diff --git a/.gitignore b/.gitignore index 272d07eaa..334874485 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,16 @@ *.zip +TestResults/ +backup/ +update/ build/ -.vscode/ +packages/ +*.exe +*.exe.config +package-lock.json +Web.Backup.config +Web.Restore.config +Web.RestoreUpdate.config +/SiteFiles/ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. @@ -216,7 +226,6 @@ Generated_Code/ # to a newer Visual Studio version. Backup files are not needed, # because we have git ;-) _UpgradeReport_Files/ -Backup*/ UpgradeLog*.XML UpgradeLog*.htm diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 000000000..4bfd587b3 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,40 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + "version": "2.0.0", + "tasks": [ + { + "label": "Build Web", + "type": "shell", + "command": "MSBuild.exe siteserver-web.sln", + "group": { + "kind": "build", + "isDefault": true + }, + "presentation": { + "reveal": "always", + "panel": "new" + } + }, + { + "label": "Build Cli", + "type": "shell", + "command": "MSBuild.exe siteserver-cli.sln", + "group": "build", + "presentation": { + "reveal": "always", + "panel": "new" + } + }, + { + "label": "Build All", + "type": "shell", + "command": "MSBuild.exe siteserver-all.sln", + "group": "build", + "presentation": { + "reveal": "always", + "panel": "new" + } + } + ] +} \ No newline at end of file diff --git a/NuGet.config b/NuGet.config deleted file mode 100644 index 9335e9610..000000000 --- a/NuGet.config +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/README.md b/README.md index d01642dfe..5abbea2ed 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,66 @@ # SiteServer CMS -SiteServer CMS 是.NET平台CMS系统的创始者,能够以最低的成本、最少的人力投入在最短的时间内架设一个功能齐全、性能优异、规模庞大并易于维护的网站平台。 +SiteServer CMS 基于.NET 平台,能够以最低的成本、最少的人力投入在最短的时间内架设一个功能齐全、性能优异、规模庞大并易于维护的网站平台。 -![SiteServer CMS](http://www.siteserver.cn/assets/github-banner.png) +![SiteServer CMS](https://www.siteserver.cn/assets/images/github-banner.png) -[官网](http://www.siteserver.cn/) | [文档中心](http://docs.siteserver.cn/) | [STL 语言](http://stl.siteserver.cn/) | [博客](http://blog.siteserver.cn/) +## 版本 + +项目发布的正式版本存放在 `master` 分支,当前的开发版本存放在 `dev` 分支 + +| 版本 | 编译状态 | 版本号 | 发布日期 | +| ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | +| 正式版 | [![Build status](https://ci.appveyor.com/api/projects/status/plx37i94y9gsqkru/branch/master?svg=true)](https://ci.appveyor.com/project/starlying/cms/branch/master) | ![Nuget version](https://img.shields.io/nuget/v/SS.CMS.svg) | ![master last commit](https://img.shields.io/github/last-commit/siteserver/cms/master.svg) | +| 开发版 | [![Build status](https://ci.appveyor.com/api/projects/status/plx37i94y9gsqkru/branch/staging?svg=true)](https://ci.appveyor.com/project/starlying/cms/branch/staging) | ![Nuget version](https://img.shields.io/nuget/vpre/SS.CMS.svg) | ![staging last commit](https://img.shields.io/github/last-commit/siteserver/cms/staging.svg) | + +## 迭代计划 + +[2019 年 1 月/2 月迭代计划](https://github.com/siteserver/cms/issues/1683) + +[2018 年 11 月/12 月迭代计划](https://github.com/siteserver/cms/issues/1521) + +[2018 年 9 月/10 月迭代计划](https://github.com/siteserver/cms/issues/1280) + +[2018 年 8 月迭代计划](https://github.com/siteserver/cms/issues/1138) + +[2018 年 7 月迭代计划](https://github.com/siteserver/cms/issues/956) + +[2018 年 6 月迭代计划](https://github.com/siteserver/cms/issues/719) + +[2018 年 5 月迭代计划](https://github.com/siteserver/cms/issues/518) + +[2018 年 4 月迭代计划](https://github.com/siteserver/cms/issues/412) + +[2018 年 3 月迭代计划](https://github.com/siteserver/cms/issues/300) + +[2018 年 2 月迭代计划](https://github.com/siteserver/cms/issues/239) + +[SiteServer CMS 路线图 2018](https://github.com/siteserver/cms/issues/718) + +## 开发文档 + +[《STL 语言参考手册》](https://docs.siteserver.cn/stl/) + +[《插件开发参考手册》](https://docs.siteserver.cn/plugins/) + +[《CLI 命令行参考手册》](https://docs.siteserver.cn/cli/) + +[《REST API 参考手册》](https://docs.siteserver.cn/api/) + +[《数据结构参考手册》](https://docs.siteserver.cn/model/) + +系统使用文档请点击 [SiteServer CMS 文档中心](https://www.siteserver.cn/docs/) ## SiteServer CMS 源码结构 ```code │ siteserver.sln Visual Studio 项目文件 │ -├─SiteServer.Utils 基础类库 -├─SiteServer.CMS CMS 源文件 ├─SiteServer.BackgroundPages ASP.NET 页面源文件 -└─SiteServer.Web API 源文件及aspx页面 +├─SiteServer.Cli 命令行工具 +├─SiteServer.CMS CMS 源文件 +├─SiteServer.Utils 基础类库 +└─SiteServer.API API 源文件及页面 ``` ## 生成安装包 @@ -24,15 +70,15 @@ SiteServer CMS 是.NET平台CMS系统的创始者,能够以最低的成本、 二、安装NodeJs 三、打开命令行,运行 npm install gulp -g 四、命令行,转到根目录,运行 npm install -五、命令行,运行 gulp release +五、命令行,运行 gulp build 六、命令行,运行 gulp zip ``` -结束后会在根目录看到siteserver_install.zip,这就是安装包了。 +结束后会在根目录看到 siteserver_install.zip,这就是安装包了。 以上步骤是第一次生成安装包所需要执行的操作,如果已经生成过安装包: ```code -一、命令行,转到根目录,运行 gulp release +一、命令行,转到根目录,运行 gulp build 二、命令行,运行 gulp zip ``` @@ -48,29 +94,20 @@ SiteServer CMS 是.NET平台CMS系统的创始者,能够以最低的成本、 - 4、将您的修改记录提交到远程 `git` 仓库 (`git push origin my-new-feature`) - 5、然后到 github 网站的该 `git` 远程仓库的 `my-new-feature` 分支下发起 Pull Request(请提交到 `dev` 分支,不要直接提交到 `master` 分支) -## 产品路线图 +## 系统更新 -SiteServer CMS 产品将在每个月底发布新的稳定版本,我们将在每次迭代中对核心功能、文档支持、功能插件以及网站模板四个方面进行持续改进,详情请参考 [路线图](https://github.com/siteserver/cms/wiki/%E8%B7%AF%E7%BA%BF%E5%9B%BE)。 +SiteServer CMS 产品将在每个月底发布新的正式版本,我们将在每次迭代中对核心功能、文档支持、功能插件以及网站模板四个方面进行持续改进。 ## 问题与建议 -我们的目标是系统零BUG,如果发现任何BUG请提交至[Github Issues](https://github.com/siteserver/cms/issues)。 +如果发现任何 BUG 以及对产品使用的问题与建议,请提交至 [Github Issues](https://github.com/siteserver/cms/issues)。 ## 关注最新动态 -[![qrcode](http://www.siteserver.cn/images/qrcode_for_wx.jpg)](http://www.siteserver.cn/) +[![qrcode](https://www.siteserver.cn/assets/images/qrcode_for_wx.jpg)](https://www.siteserver.cn/) ## License [GNU GENERAL PUBLIC LICENSE 3.0](LICENSE) -Copyright (C) 2003-2018 北京百容千域软件技术开发有限公司 - -## 编译状态 - -项目正式发布的稳定版本存放在 `master` 分支,当前的开发版本存放在 `dev` 分支 - -分支 | AppVeyor ------- | ------ -master | [![Build status](https://ci.appveyor.com/api/projects/status/plx37i94y9gsqkru/branch/master?svg=true)](https://ci.appveyor.com/project/starlying/cms/branch/master) -dev | [![Build status](https://ci.appveyor.com/api/projects/status/plx37i94y9gsqkru/branch/dev?svg=true)](https://ci.appveyor.com/project/starlying/cms/branch/dev) \ No newline at end of file +Copyright (C) 2003-2019 SiteServer CMS diff --git a/SS.CMS.nuspec b/SS.CMS.nuspec index 92543298e..803c7eacd 100644 --- a/SS.CMS.nuspec +++ b/SS.CMS.nuspec @@ -12,7 +12,7 @@ Copyright © SiteServer CMS 2018 SiteServer CMS - 6.1正式版,40余项BUG修复,10余项功能增强 + SiteServer CMS V6.8正式版 \ No newline at end of file diff --git a/SiteServer.BackgroundPages/Account/PagePassword.cs b/SiteServer.BackgroundPages/Account/PagePassword.cs deleted file mode 100644 index f79bfcca0..000000000 --- a/SiteServer.BackgroundPages/Account/PagePassword.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; - -namespace SiteServer.BackgroundPages.Account -{ - public class PagePassword : BasePage - { - public Literal LtlUserName; - public TextBox TbCurrentPassword; - public TextBox TbNewPassword; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (!Page.IsPostBack) - { - LtlUserName.Text = AuthRequest.AdminName; - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - var adminInfo = DataProvider.AdministratorDao.GetByUserName(AuthRequest.AdminName); - - if (DataProvider.AdministratorDao.CheckPassword(TbCurrentPassword.Text, adminInfo.Password, adminInfo.PasswordFormat, adminInfo.PasswordSalt)) - { - string errorMessage; - if (DataProvider.AdministratorDao.ChangePassword(AuthRequest.AdminName, TbNewPassword.Text, out errorMessage)) - { - SuccessMessage("密码更改成功"); - } - else - { - FailMessage(errorMessage); - } - } - else - { - FailMessage("当前帐号密码错误"); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Account/PageProfile.cs b/SiteServer.BackgroundPages/Account/PageProfile.cs deleted file mode 100644 index f91a8ba97..000000000 --- a/SiteServer.BackgroundPages/Account/PageProfile.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; - -namespace SiteServer.BackgroundPages.Account -{ - public class PageProfile : BasePage - { - public Literal LtlUserName; - public TextBox TbDisplayName; - public TextBox TbEmail; - public TextBox TbMobile; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (Page.IsPostBack) return; - - LtlUserName.Text = AuthRequest.AdminInfo.UserName; - TbDisplayName.Text = AuthRequest.AdminInfo.DisplayName; - TbEmail.Text = AuthRequest.AdminInfo.Email; - TbMobile.Text = AuthRequest.AdminInfo.Mobile; - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - AuthRequest.AdminInfo.DisplayName = TbDisplayName.Text; - AuthRequest.AdminInfo.Email = TbEmail.Text; - AuthRequest.AdminInfo.Mobile = TbMobile.Text; - - DataProvider.AdministratorDao.Update(AuthRequest.AdminInfo); - - SuccessMessage("资料更改成功"); - } - } -} diff --git a/SiteServer.BackgroundPages/BaseHandler.cs b/SiteServer.BackgroundPages/BaseHandler.cs deleted file mode 100644 index a91ea495a..000000000 --- a/SiteServer.BackgroundPages/BaseHandler.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Web; -using SiteServer.Utils; -using SiteServer.CMS.Plugin; - -namespace SiteServer.BackgroundPages -{ - public abstract class BaseHandler : IHttpHandler - { - protected AuthRequest AuthRequest { get; private set; } - - public void ProcessRequest(HttpContext context) - { - AuthRequest = new AuthRequest(context.Request); - - if (!AuthRequest.IsAdminLoggin) return; - - Finish(Process()); - } - - protected abstract object Process(); - - protected void Finish(object retval) - { - var response = HttpContext.Current.Response; - - response.ContentType = "application/json"; - response.Write(TranslateUtils.JsonSerialize(retval)); - response.End(); - } - - public bool IsReusable => false; - } -} diff --git a/SiteServer.BackgroundPages/BasePage.cs b/SiteServer.BackgroundPages/BasePage.cs deleted file mode 100644 index 5ec0fbc63..000000000 --- a/SiteServer.BackgroundPages/BasePage.cs +++ /dev/null @@ -1,255 +0,0 @@ -using System; -using System.Web.UI; -using SiteServer.CMS.Core; -using SiteServer.Utils; -using SiteServer.CMS.Plugin; - -namespace SiteServer.BackgroundPages -{ - public class BasePage : Page - { - private MessageUtils.Message.EMessageType _messageType; - private string _message = string.Empty; - private string _scripts = string.Empty; - - protected virtual bool IsAccessable => false; // 页面默认情况下是不能直接访问 - - protected virtual bool IsSinglePage => false; // 是否为单页(即是否需要放在框架页内运行,false表示需要) - - public string IsNightly => WebConfigUtils.IsNightlyUpdate.ToString().ToLower(); // 系统是否允许升级到最新的开发版本 - - public string Version => SystemManager.PluginVersion; // 系统采用的插件API版本号 - - protected bool IsForbidden { get; private set; } - - public AuthRequest AuthRequest { get; private set; } - - private void SetMessage(MessageUtils.Message.EMessageType messageType, Exception ex, string message) - { - _messageType = messageType; - _message = ex != null ? $"{message}" : message; - } - - protected override void OnInit(EventArgs e) - { - base.OnInit(e); - - AuthRequest = new AuthRequest(Request); - - if (!IsAccessable) // 如果页面不能直接访问且又没有登录则直接跳登录页 - { - if (!AuthRequest.IsAdminLoggin || AuthRequest.AdminInfo == null) // 检测管理员是否登录 - { - IsForbidden = true; - PageUtils.RedirectToLoginPage(); - return; - } - - if (AuthRequest.AdminInfo.IsLockedOut) // 检测管理员帐号是否被锁定 - { - IsForbidden = true; - PageUtils.RedirectToLoginPage("对不起,您的账号已被锁定,无法进入系统!"); - return; - } - } - - //防止csrf攻击 - Response.AddHeader("X-Frame-Options", "SAMEORIGIN"); - //tell Chrome to disable its XSS protection - Response.AddHeader("X-XSS-Protection", "0"); - } - - protected override void Render(HtmlTextWriter writer) - { - if (!string.IsNullOrEmpty(_message)) - { - MessageUtils.SaveMessage(_messageType, _message); - } - - base.Render(writer); - - if (!IsAccessable && !IsSinglePage) // 页面不能直接访问且不是单页,需要加一段框架检测代码,检测页面是否运行在框架内 - { - writer.Write($@""); - } - - if (!string.IsNullOrEmpty(_scripts)) - { - writer.Write($@""); - } - } - - public void AddScript(string script) - { - _scripts += script; - } - - public void AddWaitAndRedirectScript(string redirectUrl) - { - _scripts += $@" -setTimeout(function() {{ - location.href = '{redirectUrl}'; -}}, 1500); -"; - } - - public void AddWaitAndReloadMainPage() - { - _scripts += @" -setTimeout(function() {{ - window.top.location.reload(true); -}}, 1500); -"; - } - - public void AddWaitAndScript(string scripts) - { - _scripts += $@" -setTimeout(function() {{ - {scripts} -}}, 1500); -"; - } - - public void FailMessage(Exception ex, string message) - { - SetMessage(MessageUtils.Message.EMessageType.Error, ex, message); - } - - public void FailMessage(string message) - { - SetMessage(MessageUtils.Message.EMessageType.Error, null, message); - } - - public void SuccessMessage(string message) - { - SetMessage(MessageUtils.Message.EMessageType.Success, null, message); - } - - public void SuccessMessage() - { - SuccessMessage("操作成功!"); - } - - public void InfoMessage(string message) - { - SetMessage(MessageUtils.Message.EMessageType.Info, null, message); - } - - public void SuccessDeleteMessage() - { - SuccessMessage(MessageUtils.DeleteSuccess); - } - - public void SuccessUpdateMessage() - { - SuccessMessage(MessageUtils.UpdateSuccess); - } - - public void SuccessCheckMessage() - { - SuccessMessage(MessageUtils.CheckSuccess); - } - - public void SuccessInsertMessage() - { - SuccessMessage(MessageUtils.InsertSuccess); - } - - public void FailInsertMessage(Exception ex) - { - FailMessage(ex, MessageUtils.InsertFail); - } - - public void FailUpdateMessage(Exception ex) - { - FailMessage(ex, MessageUtils.UpdateFail); - } - - public void FailDeleteMessage(Exception ex) - { - FailMessage(ex, MessageUtils.DeleteFail); - } - - public void FailCheckMessage(Exception ex) - { - FailMessage(ex, MessageUtils.CheckFail); - } - - public string MaxLengthText(string str, int length) - { - return StringUtils.MaxLengthText(str, length); - } - - public Control FindControlBySelfAndChildren(string controlId) - { - return ControlUtils.FindControlBySelfAndChildren(controlId, this); - } - - public void VerifyAdministratorPermissions(params string[] permissionArray) - { - if (AuthRequest.AdminPermissions.HasAdministratorPermissions(permissionArray)) - { - return; - } - AuthRequest.AdminLogout(); - PageUtils.Redirect(PageUtils.GetAdminDirectoryUrl(string.Empty)); - } - - public virtual void Submit_OnClick(object sender, EventArgs e) - { - LayerUtils.Close(Page); - } - - public static string GetShowHintScript() - { - return GetShowHintScript("操作进行中"); - } - - public static string GetShowHintScript(string message) - { - return GetShowHintScript(message, 120); - } - - public static string GetShowHintScript(string message, int top) - { - return $@"hideBoxAndShowHint(this, '{message}, 请稍候...', {top});"; - } - - public void ClientScriptRegisterClientScriptBlock(string key, string script) - { - if (!ClientScript.IsStartupScriptRegistered(key)) - { - ClientScript.RegisterClientScriptBlock(GetType(), key, script); - } - } - - public void ClientScriptRegisterStartupScript(string key, string script) - { - if (!ClientScript.IsStartupScriptRegistered(key)) - { - ClientScript.RegisterStartupScript(GetType(), key, script); - } - } - - public bool ClientScriptIsStartupScriptRegistered(string key) - { - return ClientScript.IsStartupScriptRegistered(key); - } - - public static string GetShowImageScript(string imageClientId, string siteUrl) - { - return GetShowImageScript("this", imageClientId, siteUrl); - } - - public static string GetShowImageScript(string objString, string imageClientId, string siteUrl) - { - return - $"showImage({objString}, '{imageClientId}', '{PageUtils.ApplicationPath}', '{siteUrl}')"; - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalChannelEdit.cs b/SiteServer.BackgroundPages/Cms/ModalChannelEdit.cs deleted file mode 100644 index 5b725dc99..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalChannelEdit.cs +++ /dev/null @@ -1,288 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Create; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalChannelEdit : BasePageCms - { - public PlaceHolder PhFilePath; - public PlaceHolder PhLinkUrl; - public PlaceHolder PhLinkType; - public PlaceHolder PhChannelTemplateId; - - public TextBox TbNodeName; - public TextBox TbNodeIndexName; - public TextBox TbLinkUrl; - public CheckBoxList CblNodeGroupNameCollection; - public DropDownList DdlLinkType; - public DropDownList DdlTaxisType; - public DropDownList DdlChannelTemplateId; - public DropDownList DdlContentTemplateId; - public TextBox TbImageUrl; - public Literal LtlImageUrlButtonGroup; - public TextBox TbFilePath; - public TextBox TbKeywords; - public TextBox TbDescription; - - public TextEditorControl TbContent; - - public ChannelAuxiliaryControl CacAttributes; - - public Button BtnSubmit; - - private int _channelId; - private string _returnUrl; - - public static string GetOpenWindowString(int siteId, int channelId, string returnUrl) - { - return LayerUtils.GetOpenScript("快速修改栏目", PageUtils.GetCmsUrl(siteId, nameof(ModalChannelEdit), new NameValueCollection - { - {"channelId", channelId.ToString()}, - {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} - })); - } - - public static string GetRedirectUrl(int siteId, int channelId, string returnUrl) - { - return PageUtils.GetCmsUrl(siteId, nameof(ModalChannelEdit), new NameValueCollection - { - {"channelId", channelId.ToString()}, - {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "channelId", "ReturnUrl"); - _channelId = AuthRequest.GetQueryInt("channelId"); - _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); - - CacAttributes.SiteInfo = SiteInfo; - CacAttributes.ChannelId = _channelId; - - if (!IsPostBack) - { - if (!HasChannelPermissions(_channelId, ConfigManager.ChannelPermissions.ChannelEdit)) - { - PageUtils.RedirectToErrorPage("您没有修改栏目的权限!"); - return; - } - - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - if (nodeInfo == null) return; - - if (nodeInfo.ParentId == 0) - { - PhLinkUrl.Visible = false; - PhLinkType.Visible = false; - PhChannelTemplateId.Visible = false; - PhFilePath.Visible = false; - } - - BtnSubmit.Attributes.Add("onclick", "if (UE && UE.getEditor('Content', {{allowDivTransToP: false}})){ UE.getEditor('Content', {{allowDivTransToP: false}}).sync(); }"); - - CacAttributes.Attributes = nodeInfo.Additional; - - if (PhLinkType.Visible) - { - ELinkTypeUtils.AddListItems(DdlLinkType); - } - - ETaxisTypeUtils.AddListItemsForChannelEdit(DdlTaxisType); - - CblNodeGroupNameCollection.DataSource = DataProvider.ChannelGroupDao.GetDataSource(SiteId); - if (PhChannelTemplateId.Visible) - { - DdlChannelTemplateId.DataSource = DataProvider.TemplateDao.GetDataSourceByType(SiteId, TemplateType.ChannelTemplate); - } - DdlContentTemplateId.DataSource = DataProvider.TemplateDao.GetDataSourceByType(SiteId, TemplateType.ContentTemplate); - - DataBind(); - - if (PhChannelTemplateId.Visible) - { - DdlChannelTemplateId.Items.Insert(0, new ListItem("<未设置>", "0")); - ControlUtils.SelectSingleItem(DdlChannelTemplateId, nodeInfo.ChannelTemplateId.ToString()); - } - - DdlContentTemplateId.Items.Insert(0, new ListItem("<未设置>", "0")); - ControlUtils.SelectSingleItem(DdlContentTemplateId, nodeInfo.ContentTemplateId.ToString()); - - TbNodeName.Text = nodeInfo.ChannelName; - TbNodeIndexName.Text = nodeInfo.IndexName; - if (PhLinkUrl.Visible) - { - TbLinkUrl.Text = nodeInfo.LinkUrl; - } - - foreach (ListItem item in CblNodeGroupNameCollection.Items) - { - item.Selected = StringUtils.In(nodeInfo.GroupNameCollection, item.Value); - } - if (PhFilePath.Visible) - { - TbFilePath.Text = nodeInfo.FilePath; - } - - if (PhLinkType.Visible) - { - ControlUtils.SelectSingleItem(DdlLinkType, nodeInfo.LinkType); - } - ControlUtils.SelectSingleItem(DdlTaxisType, nodeInfo.Additional.DefaultTaxisType); - - TbImageUrl.Text = nodeInfo.ImageUrl; - LtlImageUrlButtonGroup.Text = WebUtils.GetImageUrlButtonGroupHtml(SiteInfo, TbImageUrl.ClientID); - TbContent.SetParameters(SiteInfo, ChannelAttribute.Content, nodeInfo.Content); - if (TbKeywords.Visible) - { - TbKeywords.Text = nodeInfo.Keywords; - } - if (TbDescription.Visible) - { - TbDescription.Text = nodeInfo.Description; - } - } - else - { - CacAttributes.Attributes = new ExtendedAttributes(Request.Form); - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - var isChanged = false; - - try - { - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - - if (!nodeInfo.IndexName.Equals(TbNodeIndexName.Text) && TbNodeIndexName.Text.Length != 0) - { - var nodeIndexNameList = DataProvider.ChannelDao.GetIndexNameList(SiteId); - if (nodeIndexNameList.IndexOf(TbNodeIndexName.Text) != -1) - { - FailMessage("栏目修改失败,栏目索引已存在!"); - return; - } - } - - if (PhFilePath.Visible) - { - TbFilePath.Text = TbFilePath.Text.Trim(); - if (!nodeInfo.FilePath.Equals(TbFilePath.Text) && TbFilePath.Text.Length != 0) - { - if (!DirectoryUtils.IsDirectoryNameCompliant(TbFilePath.Text)) - { - FailMessage("栏目页面路径不符合系统要求!"); - return; - } - - if (PathUtils.IsDirectoryPath(TbFilePath.Text)) - { - TbFilePath.Text = PageUtils.Combine(TbFilePath.Text, "index.html"); - } - - var filePathArrayList = DataProvider.ChannelDao.GetAllFilePathBySiteId(SiteId); - if (filePathArrayList.IndexOf(TbFilePath.Text) != -1) - { - FailMessage("栏目修改失败,栏目页面路径已存在!"); - return; - } - } - } - - var extendedAttributes = new ExtendedAttributes(); - var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(SiteId, _channelId); - var styleInfoList = TableStyleManager.GetTableStyleInfoList(DataProvider.ChannelDao.TableName, - relatedIdentities); - BackgroundInputTypeParser.SaveAttributes(extendedAttributes, SiteInfo, styleInfoList, Request.Form, null); - if (extendedAttributes.ToNameValueCollection().Count > 0) - { - nodeInfo.Additional.Load(extendedAttributes.ToNameValueCollection()); - } - - nodeInfo.ChannelName = TbNodeName.Text; - nodeInfo.IndexName = TbNodeIndexName.Text; - if (PhFilePath.Visible) - { - nodeInfo.FilePath = TbFilePath.Text; - } - - var list = new ArrayList(); - foreach (ListItem item in CblNodeGroupNameCollection.Items) - { - if (item.Selected) - { - list.Add(item.Value); - } - } - nodeInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(list); - nodeInfo.ImageUrl = TbImageUrl.Text; - nodeInfo.Content = ContentUtility.TextEditorContentEncode(SiteInfo, Request.Form[ChannelAttribute.Content]); - if (TbKeywords.Visible) - { - nodeInfo.Keywords = TbKeywords.Text; - } - if (TbDescription.Visible) - { - nodeInfo.Description = TbDescription.Text; - } - - if (PhLinkUrl.Visible) - { - nodeInfo.LinkUrl = TbLinkUrl.Text; - } - if (PhLinkType.Visible) - { - nodeInfo.LinkType = DdlLinkType.SelectedValue; - } - nodeInfo.Additional.DefaultTaxisType = ETaxisTypeUtils.GetValue(ETaxisTypeUtils.GetEnumType(DdlTaxisType.SelectedValue)); - if (PhChannelTemplateId.Visible) - { - nodeInfo.ChannelTemplateId = DdlChannelTemplateId.Items.Count > 0 ? TranslateUtils.ToInt(DdlChannelTemplateId.SelectedValue) : 0; - } - nodeInfo.ContentTemplateId = DdlContentTemplateId.Items.Count > 0 ? TranslateUtils.ToInt(DdlContentTemplateId.SelectedValue) : 0; - - DataProvider.ChannelDao.Update(nodeInfo); - - AuthRequest.AddSiteLog(SiteId, _channelId, 0, "修改栏目", $"栏目:{nodeInfo.ChannelName}"); - - isChanged = true; - } - catch (Exception ex) - { - FailMessage(ex, $"栏目修改失败:{ex.Message}"); - LogUtils.AddErrorLog(ex); - } - - if (isChanged) - { - CreateManager.CreateChannel(SiteId, _channelId); - - if (string.IsNullOrEmpty(_returnUrl)) - { - LayerUtils.Close(Page); - } - else - { - LayerUtils.CloseAndRedirect(Page, _returnUrl); - } - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalCheckState.cs b/SiteServer.BackgroundPages/Cms/ModalCheckState.cs deleted file mode 100644 index 5c6e536f7..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalCheckState.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalCheckState : BasePageCms - { - public Literal LtlTitle; - public Literal LtlState; - public PlaceHolder PhCheckReasons; - public Repeater RptContents; - public Button BtnCheck; - - private int _channelId; - private string _tableName; - private int _contentId; - private string _returnUrl; - - public static string GetOpenWindowString(int siteId, ContentInfo contentInfo, string returnUrl) - { - return LayerUtils.GetOpenScript("审核状态", - PageUtils.GetCmsUrl(siteId, nameof(ModalCheckState), new NameValueCollection - { - {"channelId", contentInfo.ChannelId.ToString()}, - {"contentID", contentInfo.Id.ToString()}, - {"returnUrl", StringUtils.ValueToUrl(returnUrl)} - }), 560, 500); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "channelId", "contentID", "returnUrl"); - - _channelId = AuthRequest.GetQueryInt("channelId"); - _tableName = ChannelManager.GetTableName(SiteInfo, _channelId); - _contentId = AuthRequest.GetQueryInt("contentID"); - _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("returnUrl")); - - var contentInfo = DataProvider.ContentDao.GetContentInfo(_tableName, _contentId); - - int checkedLevel; - var isChecked = CheckManager.GetUserCheckLevel(AuthRequest.AdminPermissions, SiteInfo, SiteId, out checkedLevel); - BtnCheck.Visible = CheckManager.IsCheckable(SiteInfo, _channelId, contentInfo.IsChecked, contentInfo.CheckedLevel, isChecked, checkedLevel); - - LtlTitle.Text = contentInfo.Title; - LtlState.Text = CheckManager.GetCheckState(SiteInfo, contentInfo.IsChecked, contentInfo.CheckedLevel); - - var checkInfoList = DataProvider.ContentCheckDao.GetCheckInfoList(_tableName, _contentId); - if (checkInfoList.Count > 0) - { - PhCheckReasons.Visible = true; - RptContents.DataSource = checkInfoList; - RptContents.ItemDataBound += RptContents_ItemDataBound; - RptContents.DataBind(); - } - } - - private static void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - var checkInfo = (ContentCheckInfo)e.Item.DataItem; - - var ltlUserName = (Literal)e.Item.FindControl("ltlUserName"); - var ltlCheckDate = (Literal)e.Item.FindControl("ltlCheckDate"); - var ltlReasons = (Literal)e.Item.FindControl("ltlReasons"); - - ltlUserName.Text = AdminManager.GetDisplayName(checkInfo.UserName, true); - ltlCheckDate.Text = DateUtils.GetDateAndTimeString(checkInfo.CheckDate); - ltlReasons.Text = checkInfo.Reasons; - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var redirectUrl = ModalContentCheck.GetRedirectUrl(SiteId, _channelId, _contentId, _returnUrl); - PageUtils.Redirect(redirectUrl); - } - - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalConfigurationCreateChannel.cs b/SiteServer.BackgroundPages/Cms/ModalConfigurationCreateChannel.cs deleted file mode 100644 index 17711a5d3..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalConfigurationCreateChannel.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalConfigurationCreateChannel : BasePageCms - { - public DropDownList DdlIsCreateChannelIfContentChanged; - - protected ListBox LbChannelId; - - private int _channelId; - - public static string GetOpenWindowString(int siteId, int channelId) - { - return LayerUtils.GetOpenScript("栏目生成设置", - PageUtils.GetCmsUrl(siteId, nameof(ModalConfigurationCreateChannel), new NameValueCollection - { - {"channelId", channelId.ToString()} - }), 550, 500); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "channelId"); - _channelId = AuthRequest.GetQueryInt("channelId"); - - if (!IsPostBack) - { - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - - EBooleanUtils.AddListItems(DdlIsCreateChannelIfContentChanged, "生成", "不生成"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsCreateChannelIfContentChanged, nodeInfo.Additional.IsCreateChannelIfContentChanged.ToString()); - - //NodeManager.AddListItemsForAddContent(this.channelIdCollection.Items, base.SiteInfo, false); - ChannelManager.AddListItemsForCreateChannel(LbChannelId.Items, SiteInfo, false, AuthRequest.AdminPermissions); - ControlUtils.SelectMultiItems(LbChannelId, TranslateUtils.StringCollectionToStringList(nodeInfo.Additional.CreateChannelIDsIfContentChanged)); - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var isSuccess = false; - - try - { - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - - nodeInfo.Additional.IsCreateChannelIfContentChanged = TranslateUtils.ToBool(DdlIsCreateChannelIfContentChanged.SelectedValue); - nodeInfo.Additional.CreateChannelIDsIfContentChanged = ControlUtils.GetSelectedListControlValueCollection(LbChannelId); - - DataProvider.ChannelDao.Update(nodeInfo); - - AuthRequest.AddSiteLog(SiteId, _channelId, 0, "设置栏目变动生成页面", $"栏目:{nodeInfo.ChannelName}"); - isSuccess = true; - } - catch (Exception ex) - { - FailMessage(ex, ex.Message); - } - - if (isSuccess) - { - LayerUtils.CloseAndRedirect(Page, PageConfigurationCreateTrigger.GetRedirectUrl(SiteId, _channelId)); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalContentArchive.cs b/SiteServer.BackgroundPages/Cms/ModalContentArchive.cs deleted file mode 100644 index e6ef0c513..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalContentArchive.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Create; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalContentArchive : BasePageCms - { - private int _channelId; - private string _returnUrl; - private List _contentIdList; - - public static string GetOpenWindowString(int siteId, int channelId, string returnUrl) - { - return LayerUtils.GetOpenScriptWithCheckBoxValue("内容归档", PageUtils.GetCmsUrl(siteId, nameof(ModalContentArchive), new NameValueCollection - { - {"channelId", channelId.ToString()}, - {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} - }), "contentIdCollection", "请选择需要归档的内容!", 400, 230); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "channelId", "ReturnUrl", "contentIdCollection"); - - _channelId = AuthRequest.GetQueryInt("channelId"); - _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); - _contentIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("contentIdCollection")); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var tableName = ChannelManager.GetTableName(SiteInfo, _channelId); - ArchiveManager.CreateArchiveTableIfNotExists(SiteInfo, tableName); - var tableNameOfArchive = TableMetadataManager.GetTableNameOfArchive(tableName); - - foreach (var contentId in _contentIdList) - { - var contentInfo = DataProvider.ContentDao.GetContentInfo(tableName, contentId); - contentInfo.LastEditDate = DateTime.Now; - DataProvider.ContentDao.Insert(tableNameOfArchive, SiteInfo, contentInfo); - } - - DataProvider.ContentDao.DeleteContents(SiteId, tableName, _contentIdList, _channelId); - - CreateManager.CreateContentTrigger(SiteId, _channelId); - - AuthRequest.AddSiteLog(SiteId, _channelId, 0, "归档内容", string.Empty); - - LayerUtils.CloseAndRedirect(Page, _returnUrl); - } - - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalContentAttributes.cs b/SiteServer.BackgroundPages/Cms/ModalContentAttributes.cs deleted file mode 100644 index dab97a4cd..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalContentAttributes.cs +++ /dev/null @@ -1,153 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.HtmlControls; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalContentAttributes : BasePageCms - { - protected CheckBox CbIsRecommend; - protected CheckBox CbIsHot; - protected CheckBox CbIsColor; - protected CheckBox CbIsTop; - protected HtmlInputHidden HihType; - protected TextBox TbHits; - - private int _channelId; - private string _tableName; - private List _idList; - - public static string GetOpenWindowString(int siteId, int channelId) - { - return LayerUtils.GetOpenScriptWithCheckBoxValue("设置内容属性", PageUtils.GetCmsUrl(siteId, nameof(ModalContentAttributes), new NameValueCollection - { - {"channelId", channelId.ToString()} - }), "contentIdCollection", "请选择需要设置属性的内容!", 450, 350); - } - - public static string GetOpenWindowStringWithCheckBoxValue(int siteId, int channelId) - { - return LayerUtils.GetOpenScriptWithCheckBoxValue("设置内容属性", PageUtils.GetCmsUrl(siteId, nameof(ModalContentAttributes), new NameValueCollection - { - {"channelId", channelId.ToString()} - }), "contentIdCollection", "请选择需要设置属性的内容!", 450, 350); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "channelId"); - - _channelId = AuthRequest.GetQueryInt("channelId"); - _tableName = ChannelManager.GetTableName(SiteInfo, _channelId); - _idList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("contentIdCollection")); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var isChanged = false; - - try - { - if (HihType.Value == "1") - { - if (CbIsRecommend.Checked || CbIsHot.Checked || CbIsColor.Checked || CbIsTop.Checked) - { - foreach (var contentId in _idList) - { - var contentInfo = DataProvider.ContentDao.GetContentInfo(_tableName, contentId); - if (contentInfo != null) - { - if (CbIsRecommend.Checked) - { - contentInfo.IsRecommend = true; - } - if (CbIsHot.Checked) - { - contentInfo.IsHot = true; - } - if (CbIsColor.Checked) - { - contentInfo.IsColor = true; - } - if (CbIsTop.Checked) - { - contentInfo.IsTop = true; - } - DataProvider.ContentDao.Update(_tableName, SiteInfo, contentInfo); - } - } - - AuthRequest.AddSiteLog(SiteId, "设置内容属性"); - - isChanged = true; - } - } - else if (HihType.Value == "2") - { - if (CbIsRecommend.Checked || CbIsHot.Checked || CbIsColor.Checked || CbIsTop.Checked) - { - foreach (var contentId in _idList) - { - var contentInfo = DataProvider.ContentDao.GetContentInfo(_tableName, contentId); - if (contentInfo != null) - { - if (CbIsRecommend.Checked) - { - contentInfo.IsRecommend = false; - } - if (CbIsHot.Checked) - { - contentInfo.IsHot = false; - } - if (CbIsColor.Checked) - { - contentInfo.IsColor = false; - } - if (CbIsTop.Checked) - { - contentInfo.IsTop = false; - } - DataProvider.ContentDao.Update(_tableName, SiteInfo, contentInfo); - } - } - - AuthRequest.AddSiteLog(SiteId, "取消内容属性"); - - isChanged = true; - } - } - else if (HihType.Value == "3") - { - var hits = TranslateUtils.ToInt(TbHits.Text); - - foreach (var contentId in _idList) - { - DataProvider.ContentDao.SetValue(_tableName, contentId, ContentAttribute.Hits, hits.ToString()); - } - - AuthRequest.AddSiteLog(SiteId, "设置内容点击量"); - - isChanged = true; - } - } - catch(Exception ex) - { - FailMessage(ex, ex.Message); - isChanged = false; - } - - if (isChanged) - { - LayerUtils.Close(Page); - } - } - - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalContentCheck.cs b/SiteServer.BackgroundPages/Cms/ModalContentCheck.cs deleted file mode 100644 index cbd4b0ab4..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalContentCheck.cs +++ /dev/null @@ -1,192 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Text; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Create; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalContentCheck : BasePageCms - { - public Literal LtlTitles; - public DropDownList DdlCheckType; - public DropDownList DdlTranslateChannelId; - public TextBox TbCheckReasons; - - private Dictionary> _idsDictionary = new Dictionary>(); - private string _returnUrl; - - public static string GetOpenWindowString(int siteId, int channelId, string returnUrl) - { - return LayerUtils.GetOpenScriptWithCheckBoxValue("审核内容", PageUtils.GetCmsUrl(siteId, nameof(ModalContentCheck), new NameValueCollection - { - {"channelId", channelId.ToString()}, - {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} - }), "contentIdCollection", "请选择需要审核的内容!", 560, 550); - } - - public static string GetOpenWindowStringForMultiChannels(int siteId, string returnUrl) - { - return LayerUtils.GetOpenScriptWithCheckBoxValue("审核内容", PageUtils.GetCmsUrl(siteId, nameof(ModalContentCheck), new NameValueCollection - { - {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} - }), "IDsCollection", "请选择需要审核的内容!", 560, 550); - } - - public static string GetOpenWindowString(int siteId, int channelId, int contentId, string returnUrl) - { - return LayerUtils.GetOpenScript("审核内容", PageUtils.GetCmsUrl(siteId, nameof(ModalContentCheck), new NameValueCollection - { - {"channelId", channelId.ToString()}, - {"contentIdCollection", contentId.ToString()}, - {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} - }), 560, 550); - } - - public static string GetRedirectUrl(int siteId, int channelId, int contentId, string returnUrl) - { - return PageUtils.GetCmsUrl(siteId, nameof(ModalContentCheck), new NameValueCollection - { - {"channelId", channelId.ToString()}, - {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)}, - {"contentIdCollection", contentId.ToString()} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "ReturnUrl"); - _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); - - _idsDictionary = ContentUtility.GetIDsDictionary(Request.QueryString); - - if (IsPostBack) return; - - var titles = new StringBuilder(); - foreach (var channelId in _idsDictionary.Keys) - { - var tableName = ChannelManager.GetTableName(SiteInfo, channelId); - var contentIdList = _idsDictionary[channelId]; - foreach (var contentId in contentIdList) - { - var title = DataProvider.ContentDao.GetValue(tableName, contentId, ContentAttribute.Title); - titles.Append(title + "
"); - } - } - - if (!string.IsNullOrEmpty(LtlTitles.Text)) - { - titles.Length -= 6; - } - LtlTitles.Text = titles.ToString(); - - var checkedLevel = 5; - var isChecked = true; - - foreach (var channelId in _idsDictionary.Keys) - { - int checkedLevelByChannelId; - var isCheckedByChannelId = CheckManager.GetUserCheckLevel(AuthRequest.AdminPermissions, SiteInfo, channelId, out checkedLevelByChannelId); - if (checkedLevel > checkedLevelByChannelId) - { - checkedLevel = checkedLevelByChannelId; - } - if (!isCheckedByChannelId) - { - isChecked = false; - } - } - - CheckManager.LoadContentLevelToCheck(DdlCheckType, SiteInfo, isChecked, checkedLevel); - - var listItem = new ListItem("<保持原栏目不变>", "0"); - DdlTranslateChannelId.Items.Add(listItem); - - ChannelManager.AddListItemsForAddContent(DdlTranslateChannelId.Items, SiteInfo, true, AuthRequest.AdminPermissions); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var checkedLevel = TranslateUtils.ToIntWithNagetive(DdlCheckType.SelectedValue); - - var isChecked = checkedLevel >= SiteInfo.Additional.CheckContentLevel; - - var contentInfoListToCheck = new List(); - var idsDictionaryToCheck = new Dictionary>(); - foreach (var channelId in _idsDictionary.Keys) - { - var tableName = ChannelManager.GetTableName(SiteInfo, channelId); - var contentIdList = _idsDictionary[channelId]; - var contentIdListToCheck = new List(); - - int checkedLevelOfUser; - var isCheckedOfUser = CheckManager.GetUserCheckLevel(AuthRequest.AdminPermissions, SiteInfo, channelId, out checkedLevelOfUser); - - foreach (var contentId in contentIdList) - { - var contentInfo = DataProvider.ContentDao.GetContentInfo(tableName, contentId); - if (contentInfo != null) - { - if (CheckManager.IsCheckable(SiteInfo, contentInfo.ChannelId, contentInfo.IsChecked, contentInfo.CheckedLevel, isCheckedOfUser, checkedLevelOfUser)) - { - contentInfoListToCheck.Add(contentInfo); - contentIdListToCheck.Add(contentId); - } - - DataProvider.ContentDao.Update(tableName, SiteInfo, contentInfo); - - CreateManager.CreateContentAndTrigger(SiteId, contentInfo.ChannelId, contentId); - } - } - if (contentIdListToCheck.Count > 0) - { - idsDictionaryToCheck[channelId] = contentIdListToCheck; - } - } - - if (contentInfoListToCheck.Count == 0) - { - LayerUtils.CloseWithoutRefresh(Page, "alert('您的审核权限不足,无法审核所选内容!');"); - return; - } - - var translateChannelId = TranslateUtils.ToInt(DdlTranslateChannelId.SelectedValue); - - foreach (var channelId in idsDictionaryToCheck.Keys) - { - var tableName = ChannelManager.GetTableName(SiteInfo, channelId); - var contentIdList = idsDictionaryToCheck[channelId]; - DataProvider.ContentDao.UpdateIsChecked(tableName, SiteId, channelId, contentIdList, translateChannelId, true, AuthRequest.AdminName, isChecked, checkedLevel, TbCheckReasons.Text); - - DataProvider.ChannelDao.UpdateContentNum(SiteInfo, channelId, true); - } - - if (translateChannelId > 0) - { - DataProvider.ChannelDao.UpdateContentNum(SiteInfo, translateChannelId, true); - } - - AuthRequest.AddSiteLog(SiteId, SiteId, 0, "设置内容状态为" + DdlCheckType.SelectedItem.Text, TbCheckReasons.Text); - - foreach (var channelId in idsDictionaryToCheck.Keys) - { - var contentIdList = _idsDictionary[channelId]; - if (contentIdList != null) - { - foreach (var contentId in contentIdList) - { - CreateManager.CreateContentAndTrigger(SiteId, channelId, contentId); - } - } - } - - LayerUtils.CloseAndRedirect(Page, _returnUrl); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalContentCrossSiteTrans.cs b/SiteServer.BackgroundPages/Cms/ModalContentCrossSiteTrans.cs deleted file mode 100644 index eb0042c36..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalContentCrossSiteTrans.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalContentCrossSiteTrans : BasePageCms - { - protected DropDownList DdlSiteId; - protected ListBox LbChannelId; - - private int _channelId; - private List _contentIdList; - - public static string GetOpenWindowString(int siteId, int channelId) - { - return LayerUtils.GetOpenScriptWithCheckBoxValue("跨站转发", PageUtils.GetCmsUrl(siteId, nameof(ModalContentCrossSiteTrans), new NameValueCollection - { - {"channelId", channelId.ToString()} - }), "contentIdCollection", "请选择需要转发的内容!", 400, 410); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "channelId", "contentIdCollection"); - - _channelId = AuthRequest.GetQueryInt("channelId"); - _contentIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("contentIdCollection")); - - if (IsPostBack) return; - - CrossSiteTransUtility.LoadSiteIdDropDownList(DdlSiteId, SiteInfo, _channelId); - - if (DdlSiteId.Items.Count > 0) - { - DdlSiteId_SelectedIndexChanged(null, EventArgs.Empty); - } - } - - public void DdlSiteId_SelectedIndexChanged(object sender, EventArgs e) - { - var psId = int.Parse(DdlSiteId.SelectedValue); - CrossSiteTransUtility.LoadChannelIdListBox(LbChannelId, SiteInfo, psId, ChannelManager.GetChannelInfo(SiteId, _channelId), AuthRequest.AdminPermissions); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var targetSiteId = int.Parse(DdlSiteId.SelectedValue); - var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); - try - { - foreach (ListItem listItem in LbChannelId.Items) - { - if (listItem.Selected) - { - var targetChannelId = TranslateUtils.ToInt(listItem.Value); - if (targetChannelId != 0) - { - var targetTableName = ChannelManager.GetTableName(targetSiteInfo, targetChannelId); - var tableName = ChannelManager.GetTableName(SiteInfo, _channelId); - foreach (var contentId in _contentIdList) - { - var contentInfo = DataProvider.ContentDao.GetContentInfo(tableName, contentId); - FileUtility.MoveFileByContentInfo(SiteInfo, targetSiteInfo, contentInfo); - contentInfo.SiteId = targetSiteId; - contentInfo.SourceId = contentInfo.ChannelId; - contentInfo.ChannelId = targetChannelId; - - contentInfo.IsChecked = targetSiteInfo.Additional.IsCrossSiteTransChecked; - contentInfo.CheckedLevel = 0; - - DataProvider.ContentDao.Insert(targetTableName, targetSiteInfo, contentInfo); - } - } - } - } - - AuthRequest.AddSiteLog(SiteId, _channelId, 0, "跨站转发", string.Empty); - - SuccessMessage("内容转发成功,请选择后续操作。"); - } - catch (Exception ex) - { - FailMessage(ex, "内容转发失败!"); - } - - LayerUtils.Close(Page); - } - - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalContentExport.cs b/SiteServer.BackgroundPages/Cms/ModalContentExport.cs deleted file mode 100644 index 7ff410d22..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalContentExport.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalContentExport : BasePageCms - { - public DropDownList DdlExportType; - public DropDownList DdlPeriods; - public DateTimeTextBox TbStartDate; - public DateTimeTextBox TbEndDate; - public PlaceHolder PhDisplayAttributes; - public CheckBoxList CblDisplayAttributes; - public DropDownList DdlIsChecked; - - private int _channelId; - - public static string GetOpenWindowString(int siteId, int channelId) - { - return LayerUtils.GetOpenScriptWithCheckBoxValue("导出内容", - PageUtils.GetCmsUrl(siteId, nameof(ModalContentExport), new NameValueCollection - { - {"channelId", channelId.ToString()} - }), "contentIdCollection", string.Empty); - } - - private void LoadDisplayAttributeCheckBoxList() - { - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(SiteId, _channelId); - var tableName = ChannelManager.GetTableName(SiteInfo, nodeInfo); - var styleInfoList = ContentUtility.GetAllTableStyleInfoList(TableStyleManager.GetTableStyleInfoList(tableName, relatedIdentities)); - - foreach (var styleInfo in styleInfoList) - { - var listItem = new ListItem(styleInfo.DisplayName, styleInfo.AttributeName) - { - Selected = true - }; - CblDisplayAttributes.Items.Add(listItem); - } - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - _channelId = AuthRequest.GetQueryInt("channelId", SiteId); - if (IsPostBack) return; - - LoadDisplayAttributeCheckBoxList(); - ConfigSettings(true); - } - - private void ConfigSettings(bool isLoad) - { - if (isLoad) - { - if (!string.IsNullOrEmpty(SiteInfo.Additional.ConfigExportType)) - { - DdlExportType.SelectedValue = SiteInfo.Additional.ConfigExportType; - } - if (!string.IsNullOrEmpty(SiteInfo.Additional.ConfigExportPeriods)) - { - DdlPeriods.SelectedValue = SiteInfo.Additional.ConfigExportPeriods; - } - if (!string.IsNullOrEmpty(SiteInfo.Additional.ConfigExportDisplayAttributes)) - { - var displayAttributes = TranslateUtils.StringCollectionToStringList(SiteInfo.Additional.ConfigExportDisplayAttributes); - ControlUtils.SelectMultiItems(CblDisplayAttributes, displayAttributes); - } - if (!string.IsNullOrEmpty(SiteInfo.Additional.ConfigExportIsChecked)) - { - DdlIsChecked.SelectedValue = SiteInfo.Additional.ConfigExportIsChecked; - } - } - else - { - SiteInfo.Additional.ConfigExportType = DdlExportType.SelectedValue; - SiteInfo.Additional.ConfigExportPeriods = DdlPeriods.SelectedValue; - SiteInfo.Additional.ConfigExportDisplayAttributes = ControlUtils.GetSelectedListControlValueCollection(CblDisplayAttributes); - SiteInfo.Additional.ConfigExportIsChecked = DdlIsChecked.SelectedValue; - DataProvider.SiteDao.Update(SiteInfo); - } - } - - public void DdlExportType_SelectedIndexChanged(object sender, EventArgs e) - { - PhDisplayAttributes.Visible = DdlExportType.SelectedValue != "ContentZip"; - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var displayAttributes = ControlUtils.GetSelectedListControlValueCollection(CblDisplayAttributes); - if (PhDisplayAttributes.Visible && string.IsNullOrEmpty(displayAttributes)) - { - FailMessage("必须至少选择一项!"); - return; - } - - ConfigSettings(false); - - var isPeriods = false; - var startDate = string.Empty; - var endDate = string.Empty; - if (DdlPeriods.SelectedValue != "0") - { - isPeriods = true; - if (DdlPeriods.SelectedValue == "-1") - { - startDate = TbStartDate.Text; - endDate = TbEndDate.Text; - } - else - { - var days = int.Parse(DdlPeriods.SelectedValue); - startDate = DateUtils.GetDateString(DateTime.Now.AddDays(-days)); - endDate = DateUtils.GetDateString(DateTime.Now); - } - } - var checkedState = ETriStateUtils.GetEnumType(DdlPeriods.SelectedValue); - var redirectUrl = ModalExportMessage.GetRedirectUrlStringToExportContent(SiteId, _channelId, DdlExportType.SelectedValue, AuthRequest.GetQueryString("contentIdCollection"), displayAttributes, isPeriods, startDate, endDate, checkedState); - PageUtils.Redirect(redirectUrl); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalContentGroupAdd.cs b/SiteServer.BackgroundPages/Cms/ModalContentGroupAdd.cs deleted file mode 100644 index 783ef209b..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalContentGroupAdd.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalContentGroupAdd : BasePageCms - { - protected TextBox TbContentGroupName; - public Literal LtlContentGroupName; - protected TextBox TbDescription; - - public static string GetOpenWindowString(int siteId, string groupName) - { - return LayerUtils.GetOpenScript("修改内容组", PageUtils.GetCmsUrl(siteId, nameof(ModalContentGroupAdd), new NameValueCollection - { - {"GroupName", groupName} - }), 600, 300); - } - - public static string GetOpenWindowString(int siteId) - { - return LayerUtils.GetOpenScript("添加内容组", PageUtils.GetCmsUrl(siteId, nameof(ModalContentGroupAdd), null), 600, 300); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (!IsPostBack) - { - if (AuthRequest.IsQueryExists("GroupName")) - { - var groupName = AuthRequest.GetQueryString("GroupName"); - var contentGroupInfo = DataProvider.ContentGroupDao.GetContentGroupInfo(groupName, SiteId); - if (contentGroupInfo != null) - { - TbContentGroupName.Text = contentGroupInfo.GroupName; - TbContentGroupName.Visible = false; - LtlContentGroupName.Text = $"{contentGroupInfo.GroupName}"; - TbDescription.Text = contentGroupInfo.Description; - } - } - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var isChanged = false; - - var contentGroupInfo = new ContentGroupInfo - { - GroupName = PageUtils.FilterXss(TbContentGroupName.Text), - SiteId = SiteId, - Description = TbDescription.Text - }; - - if (AuthRequest.IsQueryExists("GroupName")) - { - try - { - DataProvider.ContentGroupDao.Update(contentGroupInfo); - AuthRequest.AddSiteLog(SiteId, "修改内容组", $"内容组:{contentGroupInfo.GroupName}"); - isChanged = true; - } - catch (Exception ex) - { - FailMessage(ex, "内容组修改失败!"); - } - } - else - { - var contentGroupNameList = DataProvider.ContentGroupDao.GetGroupNameList(SiteId); - if (contentGroupNameList.IndexOf(TbContentGroupName.Text) != -1) - { - FailMessage("内容组添加失败,内容组名称已存在!"); - } - else - { - try - { - DataProvider.ContentGroupDao.Insert(contentGroupInfo); - AuthRequest.AddSiteLog(SiteId, "添加内容组", - $"内容组:{contentGroupInfo.GroupName}"); - isChanged = true; - } - catch(Exception ex) - { - FailMessage(ex, "内容组添加失败!"); - } - } - } - - if (isChanged) - { - LayerUtils.Close(Page); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalContentMultipleSelect.cs b/SiteServer.BackgroundPages/Cms/ModalContentMultipleSelect.cs deleted file mode 100644 index 07039e06d..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalContentMultipleSelect.cs +++ /dev/null @@ -1,189 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Text; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalContentMultipleSelect : BasePageCms - { - public DropDownList DdlChannelId; - public CheckBox CbIsDuplicate; - public DropDownList DdlSearchType; - public TextBox TbKeyword; - public DateTimeTextBox TbDateFrom; - public DateTimeTextBox TbDateTo; - - public Repeater RptContents; - public SqlPager SpContents; - - private ChannelInfo _channelInfo; - private string _tableName; - private List _relatedIdentities; - private List _tableStyleInfoList; - private string _jsMethod; - private readonly Hashtable _valueHashtable = new Hashtable(); - - public static string GetOpenWindowString(int siteId, string jsMethod) - { - return LayerUtils.GetOpenScript("选择内容", PageUtils.GetCmsUrl(siteId, nameof(ModalContentMultipleSelect), new NameValueCollection - { - {"jsMethod", jsMethod} - })); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - _jsMethod = AuthRequest.GetQueryString("jsMethod"); - - PageUtils.CheckRequestParameter("siteId"); - var channelId = AuthRequest.GetQueryInt("channelId"); - if (channelId == 0) - { - channelId = SiteId; - } - _channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - _tableName = ChannelManager.GetTableName(SiteInfo, _channelInfo); - _relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(SiteId, _channelInfo.Id); - _tableStyleInfoList = TableStyleManager.GetTableStyleInfoList(_tableName, _relatedIdentities); - - SpContents.ControlToPaginate = RptContents; - SpContents.SelectCommand = string.IsNullOrEmpty(AuthRequest.GetQueryString("channelId")) - ? DataProvider.ContentDao.GetSqlString(_tableName, SiteId, - _channelInfo.Id, AuthRequest.AdminPermissions.IsSystemAdministrator, - AuthRequest.AdminPermissions.OwningChannelIdList, DdlSearchType.SelectedValue, TbKeyword.Text, - TbDateFrom.Text, TbDateTo.Text, true, ETriState.True, !CbIsDuplicate.Checked, false) - : DataProvider.ContentDao.GetSqlString(_tableName, SiteId, - _channelInfo.Id, AuthRequest.AdminPermissions.IsSystemAdministrator, - AuthRequest.AdminPermissions.OwningChannelIdList, AuthRequest.GetQueryString("SearchType"), - AuthRequest.GetQueryString("Keyword"), AuthRequest.GetQueryString("DateFrom"), AuthRequest.GetQueryString("DateTo"), true, - ETriState.True, !AuthRequest.GetQueryBool("IsDuplicate"), true); - SpContents.ItemsPerPage = SiteInfo.Additional.PageSize; - SpContents.SortField = ContentAttribute.Id; - SpContents.SortMode = SortMode.DESC; - SpContents.OrderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByIdDesc); - RptContents.ItemDataBound += RptContents_ItemDataBound; - - if (IsPostBack) return; - - ChannelManager.AddListItems(DdlChannelId.Items, SiteInfo, false, true, AuthRequest.AdminPermissions); - - if (_tableStyleInfoList != null) - { - foreach (var styleInfo in _tableStyleInfoList) - { - var listitem = new ListItem(styleInfo.DisplayName, styleInfo.AttributeName); - DdlSearchType.Items.Add(listitem); - } - } - - //添加隐藏属性 - DdlSearchType.Items.Add(new ListItem("内容ID", ContentAttribute.Id)); - DdlSearchType.Items.Add(new ListItem("添加者", ContentAttribute.AddUserName)); - DdlSearchType.Items.Add(new ListItem("最后修改者", ContentAttribute.LastEditUserName)); - - if (AuthRequest.IsQueryExists("channelId")) - { - if (SiteId != _channelInfo.Id) - { - ControlUtils.SelectSingleItem(DdlChannelId, _channelInfo.Id.ToString()); - } - CbIsDuplicate.Checked = AuthRequest.GetQueryBool("IsDuplicate"); - ControlUtils.SelectSingleItem(DdlSearchType, AuthRequest.GetQueryString("SearchType")); - TbKeyword.Text = AuthRequest.GetQueryString("Keyword"); - TbDateFrom.Text = AuthRequest.GetQueryString("DateFrom"); - TbDateTo.Text = AuthRequest.GetQueryString("DateTo"); - } - - SpContents.DataBind(); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) - { - var ltlChannel = (Literal)e.Item.FindControl("ltlChannel"); - var ltlTitle = (Literal)e.Item.FindControl("ltlTitle"); - var ltlSelect = (Literal)e.Item.FindControl("ltlSelect"); - - var contentInfo = new ContentInfo(e.Item.DataItem); - - var nodeName = _valueHashtable[contentInfo.ChannelId] as string; - if (nodeName == null) - { - nodeName = ChannelManager.GetChannelNameNavigation(SiteId, contentInfo.ChannelId); - _valueHashtable[contentInfo.ChannelId] = nodeName; - } - ltlChannel.Text = nodeName; - - ltlTitle.Text = WebUtils.GetContentTitle(SiteInfo, contentInfo, PageUrl); - - ltlSelect.Text = - $@""; - } - } - - public void AddContent_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(WebUtils.GetContentAddAddUrl(SiteId, _channelInfo, PageUrl)); - } - - public void Search_OnClick(object sender, EventArgs e) - { - Response.Redirect(PageUrl, true); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!string.IsNullOrEmpty(Request.Form["IDsCollection"])) - { - var builder = new StringBuilder(); - foreach (var pair in TranslateUtils.StringCollectionToStringList(Request.Form["IDsCollection"])) - { - var channelId = TranslateUtils.ToInt(pair.Split('_')[0]); - var contentId = TranslateUtils.ToInt(pair.Split('_')[1]); - - var tableName = ChannelManager.GetTableName(SiteInfo, channelId); - var title = DataProvider.ContentDao.GetValue(tableName, contentId, ContentAttribute.Title); - builder.Append($@"parent.{_jsMethod}('{title}', '{pair}');"); - } - LayerUtils.CloseWithoutRefresh(Page, builder.ToString()); - } - else - { - LayerUtils.CloseWithoutRefresh(Page); - } - } - - private string _pageUrl; - private string PageUrl - { - get - { - if (string.IsNullOrEmpty(_pageUrl)) - { - _pageUrl = PageUtils.GetCmsUrl(SiteId, nameof(ModalContentMultipleSelect), new NameValueCollection - { - {"channelId", DdlChannelId.SelectedValue}, - {"IsDuplicate", CbIsDuplicate.Checked.ToString()}, - {"SearchType", DdlSearchType.SelectedValue}, - {"Keyword", TbKeyword.Text}, - {"DateFrom", TbDateFrom.Text}, - {"DateTo", TbDateTo.Text} - }); - } - return _pageUrl; - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalContentTagAdd.cs b/SiteServer.BackgroundPages/Cms/ModalContentTagAdd.cs deleted file mode 100644 index 3e2746440..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalContentTagAdd.cs +++ /dev/null @@ -1,127 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalContentTagAdd : BasePageCms - { - protected TextBox TbTags; - - private string _tagName; - - public static string GetOpenWindowStringToAdd(int siteId) - { - return LayerUtils.GetOpenScript("添加标签", PageUtils.GetCmsUrl(siteId, nameof(ModalContentTagAdd), null), 600, 360); - } - - public static string GetOpenWindowStringToEdit(int siteId, string tagName) - { - return LayerUtils.GetOpenScript("修改标签", PageUtils.GetCmsUrl(siteId, nameof(ModalContentTagAdd), new NameValueCollection - { - {"TagName", tagName} - }), 600, 360); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - _tagName = AuthRequest.GetQueryString("TagName"); - - if (IsPostBack) return; - - if (!string.IsNullOrEmpty(_tagName)) - { - TbTags.Text = _tagName; - - var count = DataProvider.TagDao.GetTagCount(_tagName, SiteId); - - InfoMessage($@"标签“{_tagName}”被使用 {count} 次,编辑此标签将更新所有使用此标签的内容。"); - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var isChanged = false; - - if (!string.IsNullOrEmpty(_tagName)) - { - try - { - if (!string.Equals(_tagName, TbTags.Text)) - { - var tagCollection = TagUtils.ParseTagsString(TbTags.Text); - var contentIdList = DataProvider.TagDao.GetContentIdListByTag(_tagName, SiteId); - if (contentIdList.Count > 0) - { - foreach (int contentId in contentIdList) - { - if (!tagCollection.Contains(_tagName))//删除 - { - var tagInfo = DataProvider.TagDao.GetTagInfo(SiteId, _tagName); - if (tagInfo != null) - { - var idArrayList = TranslateUtils.StringCollectionToIntList(tagInfo.ContentIdCollection); - idArrayList.Remove(contentId); - tagInfo.ContentIdCollection = TranslateUtils.ObjectCollectionToString(idArrayList); - tagInfo.UseNum = idArrayList.Count; - DataProvider.TagDao.Update(tagInfo); - } - } - - TagUtils.AddTags(tagCollection, SiteId, contentId); - - var contentTags = DataProvider.ContentDao.GetValue(SiteInfo.TableName, contentId, ContentAttribute.Tags); - var contentTagArrayList = TranslateUtils.StringCollectionToStringList(contentTags); - contentTagArrayList.Remove(_tagName); - foreach (var theTag in tagCollection) - { - if (!contentTagArrayList.Contains(theTag)) - { - contentTagArrayList.Add(theTag); - } - } - DataProvider.ContentDao.SetValue(SiteInfo.TableName, contentId, ContentAttribute.Tags, TranslateUtils.ObjectCollectionToString(contentTagArrayList)); - } - } - else - { - DataProvider.TagDao.DeleteTag(_tagName, SiteId); - } - } - - AuthRequest.AddSiteLog(SiteId, "修改内容标签", $"内容标签:{TbTags.Text}"); - - isChanged = true; - } - catch(Exception ex) - { - FailMessage(ex, "标签修改失败!"); - } - } - else - { - try - { - var tagCollection = TagUtils.ParseTagsString(TbTags.Text); - TagUtils.AddTags(tagCollection, SiteId, 0); - AuthRequest.AddSiteLog(SiteId, "添加内容标签", $"内容标签:{TbTags.Text}"); - isChanged = true; - } - catch(Exception ex) - { - FailMessage(ex, "标签添加失败!"); - } - } - - if (isChanged) - { - LayerUtils.Close(Page); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalContentTaxis.cs b/SiteServer.BackgroundPages/Cms/ModalContentTaxis.cs deleted file mode 100644 index ce720faaf..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalContentTaxis.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Create; -using SiteServer.CMS.Model; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalContentTaxis : BasePageCms - { - protected DropDownList DdlTaxisType; - protected TextBox TbTaxisNum; - - private int _channelId; - private string _returnUrl; - private List _contentIdList; - private string _tableName; - - public static string GetOpenWindowString(int siteId, int channelId, string returnUrl) - { - return LayerUtils.GetOpenScriptWithCheckBoxValue("内容排序", PageUtils.GetCmsUrl(siteId, nameof(ModalContentTaxis), new NameValueCollection - { - {"channelId", channelId.ToString()}, - {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} - }), "contentIdCollection", "请选择需要排序的内容!", 400, 280); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "channelId", "ReturnUrl", "contentIdCollection"); - - _channelId = AuthRequest.GetQueryInt("channelId"); - _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); - _contentIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("contentIdCollection")); - _tableName = ChannelManager.GetTableName(SiteInfo, _channelId); - - if (IsPostBack) return; - - DdlTaxisType.Items.Add(new ListItem("上升", "Up")); - DdlTaxisType.Items.Add(new ListItem("下降", "Down")); - ControlUtils.SelectSingleItem(DdlTaxisType, "Up"); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var isUp = DdlTaxisType.SelectedValue == "Up"; - var taxisNum = TranslateUtils.ToInt(TbTaxisNum.Text); - - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - if (ETaxisTypeUtils.Equals(nodeInfo.Additional.DefaultTaxisType, ETaxisType.OrderByTaxis)) - { - isUp = !isUp; - } - - if (isUp == false) - { - _contentIdList.Reverse(); - } - - foreach (var contentId in _contentIdList) - { - var isTop = TranslateUtils.ToBool(DataProvider.ContentDao.GetValue(_tableName, contentId, ContentAttribute.IsTop)); - for (var i = 1; i <= taxisNum; i++) - { - if (isUp) - { - if (DataProvider.ContentDao.UpdateTaxisToUp(_tableName, _channelId, contentId, isTop) == false) - { - break; - } - } - else - { - if (DataProvider.ContentDao.UpdateTaxisToDown(_tableName, _channelId, contentId, isTop) == false) - { - break; - } - } - } - } - - CreateManager.CreateContentTrigger(SiteId, _channelId); - - AuthRequest.AddSiteLog(SiteId, _channelId, 0, "对内容排序", string.Empty); - - LayerUtils.CloseAndRedirect(Page, _returnUrl); - } - - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalCrossSiteTransEdit.cs b/SiteServer.BackgroundPages/Cms/ModalCrossSiteTransEdit.cs deleted file mode 100644 index f6c5522ec..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalCrossSiteTransEdit.cs +++ /dev/null @@ -1,188 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalCrossSiteTransEdit : BasePageCms - { - public DropDownList DdlTransType; - public PlaceHolder PhSite; - public DropDownList DdlSiteId; - public ListBox LbChannelId; - public PlaceHolder PhNodeNames; - public TextBox TbNodeNames; - public PlaceHolder PhIsAutomatic; - public DropDownList DdlIsAutomatic; - public DropDownList DdlTranslateDoneType; - - private ChannelInfo _channelInfo; - - public static string GetOpenWindowString(int siteId, int channelId) - { - return LayerUtils.GetOpenScript("跨站转发设置", PageUtils.GetCmsUrl(siteId, nameof(ModalCrossSiteTransEdit), new NameValueCollection - { - {"channelId", channelId.ToString()} - })); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "channelId"); - var channelId = int.Parse(AuthRequest.GetQueryString("channelId")); - _channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - - if (IsPostBack) return; - - ECrossSiteTransTypeUtils.AddAllListItems(DdlTransType, SiteInfo.ParentId > 0); - - ControlUtils.SelectSingleItem(DdlTransType, ECrossSiteTransTypeUtils.GetValue(_channelInfo.Additional.TransType)); - - DdlTransType_OnSelectedIndexChanged(null, EventArgs.Empty); - ControlUtils.SelectSingleItem(DdlSiteId, _channelInfo.Additional.TransSiteId.ToString()); - - - DdlSiteId_OnSelectedIndexChanged(null, EventArgs.Empty); - ControlUtils.SelectMultiItems(LbChannelId, TranslateUtils.StringCollectionToStringList(_channelInfo.Additional.TransChannelIds)); - TbNodeNames.Text = _channelInfo.Additional.TransChannelNames; - - EBooleanUtils.AddListItems(DdlIsAutomatic, "系统自动转发", "需手动操作"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsAutomatic, _channelInfo.Additional.TransIsAutomatic.ToString()); - - ETranslateContentTypeUtils.AddListItems(DdlTranslateDoneType, false); - ControlUtils.SelectSingleItem(DdlTranslateDoneType, ETranslateContentTypeUtils.GetValue(_channelInfo.Additional.TransDoneType)); - } - - protected void DdlTransType_OnSelectedIndexChanged(object sender, EventArgs e) - { - DdlSiteId.Items.Clear(); - DdlSiteId.Enabled = true; - - PhIsAutomatic.Visible = false; - - var contributeType = ECrossSiteTransTypeUtils.GetEnumType(DdlTransType.SelectedValue); - if (contributeType == ECrossSiteTransType.None) - { - PhSite.Visible = PhNodeNames.Visible = false; - } - else if (contributeType == ECrossSiteTransType.SelfSite || contributeType == ECrossSiteTransType.SpecifiedSite) - { - PhSite.Visible = true; - PhNodeNames.Visible = false; - - PhIsAutomatic.Visible = true; - } - else if (contributeType == ECrossSiteTransType.ParentSite) - { - PhSite.Visible = true; - PhNodeNames.Visible = false; - DdlSiteId.Enabled = false; - - PhIsAutomatic.Visible = true; - } - else if (contributeType == ECrossSiteTransType.AllParentSite || contributeType == ECrossSiteTransType.AllSite) - { - PhSite.Visible = false; - PhNodeNames.Visible = true; - } - - if (PhSite.Visible) - { - var siteIdList = SiteManager.GetSiteIdList(); - - var allParentSiteIdList = new List(); - if (contributeType == ECrossSiteTransType.AllParentSite) - { - SiteManager.GetAllParentSiteIdList(allParentSiteIdList, siteIdList, SiteId); - } - else if (contributeType == ECrossSiteTransType.SelfSite) - { - siteIdList = new List - { - SiteId - }; - } - - foreach (var psId in siteIdList) - { - var psInfo = SiteManager.GetSiteInfo(psId); - var show = false; - if (contributeType == ECrossSiteTransType.SpecifiedSite) - { - show = true; - } - else if (contributeType == ECrossSiteTransType.SelfSite) - { - if (psId == SiteId) - { - show = true; - } - } - else if (contributeType == ECrossSiteTransType.ParentSite) - { - if (psInfo.Id == SiteInfo.ParentId || (SiteInfo.ParentId == 0 && psInfo.IsRoot)) - { - show = true; - } - } - if (!show) continue; - - var listitem = new ListItem(psInfo.SiteName, psId.ToString()); - if (psInfo.IsRoot) listitem.Selected = true; - DdlSiteId.Items.Add(listitem); - } - } - DdlSiteId_OnSelectedIndexChanged(sender, e); - } - - protected void DdlSiteId_OnSelectedIndexChanged(object sender, EventArgs e) - { - LbChannelId.Items.Clear(); - if (PhSite.Visible && DdlSiteId.Items.Count > 0) - { - ChannelManager.AddListItemsForAddContent(LbChannelId.Items, SiteManager.GetSiteInfo(int.Parse(DdlSiteId.SelectedValue)), false, AuthRequest.AdminPermissions); - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var isSuccess = false; - - try - { - _channelInfo.Additional.TransType = ECrossSiteTransTypeUtils.GetEnumType(DdlTransType.SelectedValue); - _channelInfo.Additional.TransSiteId = _channelInfo.Additional.TransType == ECrossSiteTransType.SpecifiedSite ? TranslateUtils.ToInt(DdlSiteId.SelectedValue) : 0; - _channelInfo.Additional.TransChannelIds = ControlUtils.GetSelectedListControlValueCollection(LbChannelId); - _channelInfo.Additional.TransChannelNames = TbNodeNames.Text; - - _channelInfo.Additional.TransIsAutomatic = TranslateUtils.ToBool(DdlIsAutomatic.SelectedValue); - - var translateDoneType = ETranslateContentTypeUtils.GetEnumType(DdlTranslateDoneType.SelectedValue); - _channelInfo.Additional.TransDoneType = translateDoneType; - - DataProvider.ChannelDao.Update(_channelInfo); - - AuthRequest.AddSiteLog(SiteId, "修改跨站转发设置"); - - isSuccess = true; - } - catch (Exception ex) - { - FailMessage(ex, ex.Message); - } - - if (isSuccess) - { - LayerUtils.Close(Page); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalExportMessage.cs b/SiteServer.BackgroundPages/Cms/ModalExportMessage.cs deleted file mode 100644 index c0658b6ba..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalExportMessage.cs +++ /dev/null @@ -1,212 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.CMS.Api; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Office; -using SiteServer.CMS.ImportExport; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalExportMessage : BasePageCms - { - public const int Width = 580; - public const int Height = 250; - public const string ExportTypeContentZip = "ContentZip"; - public const string ExportTypeContentAccess = "ContentAccess"; - public const string ExportTypeContentExcel = "ContentExcel"; - public const string ExportTypeContentTxtZip = "ContentTxtZip"; - public const string ExportTypeRelatedField = "RelatedField"; - public const string ExportTypeChannel = "Channel"; - public const string ExportTypeSingleTableStyle = "SingleTableStyle"; - - private string _exportType; - - public static string GetRedirectUrlStringToExportContent(int siteId, int channelId, - string exportType, string contentIdCollection, string displayAttributes, bool isPeriods, - string startDate, string endDate, ETriState checkedState) - { - return PageUtils.GetCmsUrl(siteId, nameof(ModalExportMessage), new NameValueCollection - { - {"channelId", channelId.ToString()}, - {"ExportType", exportType}, - {"contentIdCollection", contentIdCollection}, - {"DisplayAttributes", displayAttributes}, - {"isPeriods", isPeriods.ToString()}, - {"startDate", startDate}, - {"endDate", endDate}, - {"checkedState", ETriStateUtils.GetValue(checkedState)} - }); - } - - public static string GetOpenWindowStringToChannel(int siteId, string checkBoxId, string alertString) - { - return LayerUtils.GetOpenScriptWithCheckBoxValue("导出数据", - PageUtils.GetCmsUrl(siteId, nameof(ModalExportMessage), new NameValueCollection - { - {"ExportType", ExportTypeChannel} - }), checkBoxId, alertString, Width, Height); - } - - public static string GetOpenWindowStringToSingleTableStyle(string tableName, int siteId, int relatedIdentity) - { - return LayerUtils.GetOpenScript("导出数据", - PageUtils.GetCmsUrl(siteId, nameof(ModalExportMessage), new NameValueCollection - { - {"TableName", tableName}, - {"ExportType", ExportTypeSingleTableStyle}, - {"RelatedIdentity", relatedIdentity.ToString()} - }), Width, Height); - } - - public static string GetOpenWindowStringToRelatedField(int siteId, int relatedFieldId) - { - return LayerUtils.GetOpenScript("导出数据", - PageUtils.GetCmsUrl(siteId, nameof(ModalExportMessage), new NameValueCollection - { - {"RelatedFieldID", relatedFieldId.ToString()}, - {"ExportType", ExportTypeRelatedField} - }), Width, Height); - } - - public static string GetOpenWindowStringToExport(int siteId, string exportType) - { - return LayerUtils.GetOpenScript("导出数据", - PageUtils.GetCmsUrl(siteId, nameof(ModalExportMessage), new NameValueCollection - { - {"ExportType", exportType} - }), Width, Height); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - _exportType = AuthRequest.GetQueryString("ExportType"); - - if (!IsPostBack) - { - var isExport = true; - var fileName = string.Empty; - try - { - if (_exportType == ExportTypeRelatedField) - { - var relatedFieldId = AuthRequest.GetQueryInt("RelatedFieldID"); - fileName = ExportRelatedField(relatedFieldId); - } - else if (_exportType == ExportTypeContentZip) - { - var channelId = AuthRequest.GetQueryInt("channelId"); - var contentIdCollection = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("contentIdCollection")); - var isPeriods = AuthRequest.GetQueryBool("isPeriods"); - var startDate = AuthRequest.GetQueryString("startDate"); - var endDate = AuthRequest.GetQueryString("endDate"); - var checkedState = ETriStateUtils.GetEnumType(AuthRequest.GetQueryString("checkedState")); - isExport = ExportContentZip(channelId, contentIdCollection, isPeriods, startDate, endDate, checkedState, out fileName); - } - else if (_exportType == ExportTypeContentAccess) - { - var channelId = AuthRequest.GetQueryInt("channelId"); - var contentIdCollection = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("contentIdCollection")); - var displayAttributes = TranslateUtils.StringCollectionToStringList(AuthRequest.GetQueryString("DisplayAttributes")); - var isPeriods = AuthRequest.GetQueryBool("isPeriods"); - var startDate = AuthRequest.GetQueryString("startDate"); - var endDate = AuthRequest.GetQueryString("endDate"); - var checkedState = ETriStateUtils.GetEnumType(AuthRequest.GetQueryString("checkedState")); - isExport = ExportContentAccess(channelId, contentIdCollection, displayAttributes, isPeriods, startDate, endDate, checkedState, out fileName); - } - else if (_exportType == ExportTypeContentExcel) - { - var channelId = AuthRequest.GetQueryInt("channelId"); - var contentIdCollection = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("contentIdCollection")); - var displayAttributes = TranslateUtils.StringCollectionToStringList(AuthRequest.GetQueryString("DisplayAttributes")); - var isPeriods = AuthRequest.GetQueryBool("isPeriods"); - var startDate = AuthRequest.GetQueryString("startDate"); - var endDate = AuthRequest.GetQueryString("endDate"); - var checkedState = ETriStateUtils.GetEnumType(AuthRequest.GetQueryString("checkedState")); - ExportContentExcel(channelId, contentIdCollection, displayAttributes, isPeriods, startDate, endDate, checkedState, out fileName); - } - else if (_exportType == ExportTypeChannel) - { - var channelIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("ChannelIDCollection")); - fileName = ExportChannel(channelIdList); - } - else if (_exportType == ExportTypeSingleTableStyle) - { - var tableName = AuthRequest.GetQueryString("TableName"); - var relatedIdentity = AuthRequest.GetQueryInt("RelatedIdentity"); - fileName = ExportSingleTableStyle(tableName, relatedIdentity); - } - - if (isExport) - { - var link = new HyperLink(); - var filePath = PathUtils.GetTemporaryFilesPath(fileName); - link.NavigateUrl = ApiRouteActionsDownload.GetUrl(ApiManager.InnerApiUrl, filePath); - link.Text = "下载"; - var successMessage = "成功导出文件!  " + ControlUtils.GetControlRenderHtml(link); - SuccessMessage(successMessage); - } - else - { - FailMessage("导出失败,所选条件没有匹配内容,请重新选择条件导出内容"); - } - } - catch (Exception ex) - { - var failedMessage = "文件导出失败!

原因为:" + ex.Message; - FailMessage(ex, failedMessage); - } - } - } - - private string ExportRelatedField(int relatedFieldId) - { - var exportObject = new ExportObject(SiteId, AuthRequest.AdminName); - return exportObject.ExportRelatedField(relatedFieldId); - } - - private bool ExportContentZip(int channelId, List contentIdArrayList, bool isPeriods, string dateFrom, string dateTo, ETriState checkedState, out string fileName) - { - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - fileName = $"{nodeInfo.ChannelName}.zip"; - var filePath = PathUtils.GetTemporaryFilesPath(fileName); - var exportObject = new ExportObject(SiteId, AuthRequest.AdminName); - return exportObject.ExportContents(filePath, channelId, contentIdArrayList, isPeriods, dateFrom, dateTo, checkedState); - } - - private bool ExportContentAccess(int channelId, List contentIdArrayList, List displayAttributes, bool isPeriods, string dateFrom, string dateTo, ETriState checkedState, out string fileName) - { - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - fileName = $"{nodeInfo.ChannelName}.mdb"; - var filePath = PathUtils.GetTemporaryFilesPath(fileName); - return AccessObject.CreateAccessFileForContents(filePath, SiteInfo, nodeInfo, contentIdArrayList, displayAttributes, isPeriods, dateFrom, dateTo, checkedState); - } - - private void ExportContentExcel(int channelId, List contentIdList, List displayAttributes, bool isPeriods, string dateFrom, string dateTo, ETriState checkedState, out string fileName) - { - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - - fileName = $"{nodeInfo.ChannelName}.csv"; - var filePath = PathUtils.GetTemporaryFilesPath(fileName); - ExcelObject.CreateExcelFileForContents(filePath, SiteInfo, nodeInfo, contentIdList, displayAttributes, isPeriods, dateFrom, dateTo, checkedState); - } - - private string ExportChannel(List channelIdList) - { - var exportObject = new ExportObject(SiteId, AuthRequest.AdminName); - return exportObject.ExportChannels(channelIdList); - } - - private string ExportSingleTableStyle(string tableName, int relatedIdentity) - { - var exportObject = new ExportObject(SiteId, AuthRequest.AdminName); - return exportObject.ExportSingleTableStyle(tableName, relatedIdentity); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalNodeGroupAdd.cs b/SiteServer.BackgroundPages/Cms/ModalNodeGroupAdd.cs deleted file mode 100644 index e13482d6e..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalNodeGroupAdd.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalNodeGroupAdd : BasePageCms - { - public TextBox TbNodeGroupName; - public Literal LtlNodeGroupName; - public TextBox TbDescription; - - public static string GetOpenWindowString(int siteId, string groupName) - { - return LayerUtils.GetOpenScript("修改栏目组", PageUtils.GetCmsUrl(siteId, nameof(ModalNodeGroupAdd), new NameValueCollection - { - {"GroupName", groupName} - }), 600, 300); - } - - public static string GetOpenWindowString(int siteId) - { - return LayerUtils.GetOpenScript("添加栏目组", PageUtils.GetCmsUrl(siteId, nameof(ModalNodeGroupAdd), null), 600, 300); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - if (IsPostBack) return; - - if (AuthRequest.IsQueryExists("GroupName")) - { - var groupName = AuthRequest.GetQueryString("GroupName"); - var nodeGroupInfo = DataProvider.ChannelGroupDao.GetGroupInfo(SiteId, groupName); - if (nodeGroupInfo != null) - { - TbNodeGroupName.Text = nodeGroupInfo.GroupName; - TbNodeGroupName.Visible = false; - LtlNodeGroupName.Text = $"{nodeGroupInfo.GroupName}"; - TbDescription.Text = nodeGroupInfo.Description; - } - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var isChanged = false; - - var nodeGroupInfo = new ChannelGroupInfo - { - GroupName = TbNodeGroupName.Text, - SiteId = SiteId, - Description = TbDescription.Text - }; - - if (AuthRequest.IsQueryExists("GroupName")) - { - try - { - DataProvider.ChannelGroupDao.Update(nodeGroupInfo); - AuthRequest.AddSiteLog(SiteId, "修改栏目组", $"栏目组:{nodeGroupInfo.GroupName}"); - isChanged = true; - } - catch(Exception ex) - { - FailMessage(ex, "栏目组修改失败!"); - } - } - else - { - var nodeGroupNameList = DataProvider.ChannelGroupDao.GetGroupNameList(SiteId); - if (nodeGroupNameList.IndexOf(TbNodeGroupName.Text) != -1) - { - FailMessage("栏目组添加失败,栏目组名称已存在!"); - } - else - { - try - { - DataProvider.ChannelGroupDao.Insert(nodeGroupInfo); - AuthRequest.AddSiteLog(SiteId, "添加栏目组", $"栏目组:{nodeGroupInfo.GroupName}"); - isChanged = true; - } - catch (Exception ex) - { - FailMessage(ex, "栏目组添加失败!"); - } - } - } - - if (isChanged) - { - LayerUtils.Close(Page); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalSelectColumns.cs b/SiteServer.BackgroundPages/Cms/ModalSelectColumns.cs deleted file mode 100644 index af1cbb4ea..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalSelectColumns.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalSelectColumns : BasePageCms - { - public CheckBoxList CblDisplayAttributes; - - private int _relatedIdentity; - private List _relatedIdentities; - private bool _isList; - - public static string GetOpenWindowString(int siteId, int relatedIdentity, bool isList) - { - return LayerUtils.GetOpenScript("选择需要显示的项", PageUtils.GetCmsUrl(siteId, nameof(ModalSelectColumns), new NameValueCollection - { - {"RelatedIdentity", relatedIdentity.ToString()}, - {"IsList", isList.ToString()} - }), 0, 550); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - _relatedIdentity = AuthRequest.GetQueryInt("RelatedIdentity"); - _isList = AuthRequest.GetQueryBool("IsList"); - - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, _relatedIdentity); - var tableName = ChannelManager.GetTableName(SiteInfo, nodeInfo); - _relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(SiteId, _relatedIdentity); - var attributesOfDisplay = TranslateUtils.StringCollectionToStringCollection(nodeInfo.Additional.ContentAttributesOfDisplay); - - if (IsPostBack) return; - - var styleInfoList = ContentUtility.GetAllTableStyleInfoList(TableStyleManager.GetTableStyleInfoList(tableName, _relatedIdentities)); - foreach (var styleInfo in styleInfoList) - { - var listitem = new ListItem($"{styleInfo.DisplayName}({styleInfo.AttributeName})", styleInfo.AttributeName); - if (styleInfo.AttributeName == ContentAttribute.Title) - { - listitem.Selected = true; - } - else - { - if (_isList) - { - if (attributesOfDisplay.Contains(styleInfo.AttributeName)) - { - listitem.Selected = true; - } - } - else - { - listitem.Selected = true; - } - } - - CblDisplayAttributes.Items.Add(listitem); - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, _relatedIdentity); - var attributesOfDisplay = ControlUtils.SelectedItemsValueToStringCollection(CblDisplayAttributes.Items); - nodeInfo.Additional.ContentAttributesOfDisplay = attributesOfDisplay; - - DataProvider.ChannelDao.Update(nodeInfo); - - AuthRequest.AddSiteLog(SiteId, "设置内容显示项", $"显示项:{attributesOfDisplay}"); - - if (!_isList) - { - LayerUtils.CloseWithoutRefresh(Page); - } - else - { - LayerUtils.Close(Page); - } - } - - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalSiteSelect.cs b/SiteServer.BackgroundPages/Cms/ModalSiteSelect.cs deleted file mode 100644 index 7a470eaf6..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalSiteSelect.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Text; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalSiteSelect : BasePageCms - { - public Literal LtlHtml; - - public static string GetOpenLayerString(int siteId) - { - return LayerUtils.GetOpenScript("选择站点", PageUtils.GetCmsUrl(siteId, nameof(ModalSiteSelect), null)); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (IsPostBack) return; - - var builder = new StringBuilder(); - - var siteIdList = AuthRequest.AdminPermissions.SiteIdList; - foreach (var siteId in siteIdList) - { - var loadingUrl = PageUtils.GetLoadingUrl(PageMain.GetRedirectUrl(siteId)); - var siteInfo = SiteManager.GetSiteInfo(siteId); - builder.Append($@" -
-
-

- - {siteInfo.SiteName} - -

-

{siteInfo.SiteDir}

-
-
"); - } - - LtlHtml.Text = builder.ToString(); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalTableStyleAdd.cs b/SiteServer.BackgroundPages/Cms/ModalTableStyleAdd.cs deleted file mode 100644 index e26a76edb..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalTableStyleAdd.cs +++ /dev/null @@ -1,470 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.Plugin; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalTableStyleAdd : BasePageCms - { - public TextBox TbAttributeName; - public TextBox TbDisplayName; - public TextBox TbHelpText; - public TextBox TbTaxis; - public PlaceHolder PhIsFormatString; - public DropDownList DdlInputType; - public DropDownList DdlIsFormatString; - public PlaceHolder PhDefaultValue; - public TextBox TbDefaultValue; - public Control SpanDateTip; - public DropDownList DdlIsHorizontal; - public TextBox TbColumns; - public PlaceHolder PhRelatedField; - public DropDownList DdlRelatedFieldId; - public DropDownList DdlRelatedFieldStyle; - public PlaceHolder PhWidth; - public TextBox TbWidth; - public PlaceHolder PhHeight; - public TextBox TbHeight; - - public PlaceHolder PhIsSelectField; - public DropDownList DdlIsRapid; - public PlaceHolder PhRapid; - public TextBox TbRapidValues; - public PlaceHolder PhNotRapid; - public TextBox TbItemCount; - public Repeater RptItems; - public PlaceHolder PhRepeat; - - public PlaceHolder PhCustomize; - public TextBox TbCustomizeLeft; - public TextBox TbCustomizeRight; - - private int _tableStyleId; - private List _relatedIdentities; - private string _tableName; - private string _attributeName; - private string _redirectUrl; - private TableStyleInfo _styleInfo; - - public static string GetOpenWindowString(int siteId, int tableStyleId, List relatedIdentities, string tableName, string attributeName, string redirectUrl) - { - return LayerUtils.GetOpenScript("修改显示样式", PageUtils.GetCmsUrl(siteId, nameof(ModalTableStyleAdd), new NameValueCollection - { - {"TableStyleID", tableStyleId.ToString()}, - {"RelatedIdentities", TranslateUtils.ObjectCollectionToString(relatedIdentities)}, - {"TableName", tableName}, - {"AttributeName", attributeName}, - {"RedirectUrl", StringUtils.ValueToUrl(redirectUrl)} - })); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - _tableStyleId = AuthRequest.GetQueryInt("TableStyleID"); - _relatedIdentities = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("RelatedIdentities")); - if (_relatedIdentities.Count == 0) - { - _relatedIdentities.Add(0); - } - _tableName = AuthRequest.GetQueryString("TableName"); - _attributeName = AuthRequest.GetQueryString("AttributeName"); - _redirectUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("RedirectUrl")); - - _styleInfo = _tableStyleId != 0 ? DataProvider.TableStyleDao.GetTableStyleInfo(_tableStyleId) : TableStyleManager.GetTableStyleInfo(_tableName, _attributeName, _relatedIdentities); - - if (IsPostBack) return; - - InputTypeUtils.AddListItems(DdlInputType); - - var relatedFieldInfoList = DataProvider.RelatedFieldDao.GetRelatedFieldInfoList(SiteId); - foreach (var rfInfo in relatedFieldInfoList) - { - var listItem = new ListItem(rfInfo.Title, rfInfo.Id.ToString()); - DdlRelatedFieldId.Items.Add(listItem); - } - - ERelatedFieldStyleUtils.AddListItems(DdlRelatedFieldStyle); - - ControlUtils.SelectSingleItem(DdlIsRapid, _styleInfo.Id != 0 ? false.ToString() : true.ToString()); - - TbAttributeName.Text = _styleInfo.AttributeName; - TbDisplayName.Text = _styleInfo.DisplayName; - TbHelpText.Text = _styleInfo.HelpText; - ControlUtils.SelectSingleItem(DdlInputType, _styleInfo.InputType.Value); - TbTaxis.Text = _styleInfo.Taxis.ToString(); - ControlUtils.SelectSingleItem(DdlIsFormatString, _styleInfo.Additional.IsFormatString.ToString()); - TbDefaultValue.Text = _styleInfo.DefaultValue; - DdlIsHorizontal.SelectedValue = _styleInfo.IsHorizontal.ToString(); - TbColumns.Text = _styleInfo.Additional.Columns.ToString(); - - ControlUtils.SelectSingleItem(DdlRelatedFieldId, _styleInfo.Additional.RelatedFieldId.ToString()); - ControlUtils.SelectSingleItem(DdlRelatedFieldStyle, _styleInfo.Additional.RelatedFieldStyle); - - TbHeight.Text = _styleInfo.Additional.Height == 0 ? string.Empty : _styleInfo.Additional.Height.ToString(); - TbWidth.Text = _styleInfo.Additional.Width; - - var styleItems = _styleInfo.StyleItems ?? DataProvider.TableStyleItemDao.GetStyleItemInfoList(_styleInfo.Id); - TbItemCount.Text = styleItems.Count.ToString(); - RptItems.DataSource = GetDataSource(styleItems.Count, styleItems); - RptItems.ItemDataBound += RptItems_ItemDataBound; - RptItems.DataBind(); - - var isSelected = false; - var isNotEquals = false; - var list = new List(); - foreach (var item in styleItems) - { - list.Add(item.ItemValue); - if (item.IsSelected) - { - isSelected = true; - } - if (item.ItemValue != item.ItemTitle) - { - isNotEquals = true; - } - } - - DdlIsRapid.SelectedValue = (!isSelected && !isNotEquals).ToString(); - TbRapidValues.Text = string.Join(",", list); - - TbCustomizeLeft.Text = _styleInfo.Additional.CustomizeLeft; - TbCustomizeRight.Text = _styleInfo.Additional.CustomizeRight; - - ReFresh(null, EventArgs.Empty); - } - - private List GetDataSource(int count, List styleItems) - { - var items = new List(); - for (var i = 0; i < count; i++) - { - var itemInfo = styleItems != null && styleItems.Count > i ? styleItems[i] : new TableStyleItemInfo(); - items.Add(itemInfo); - } - return items; - } - - private static void RptItems_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var itemInfo = (TableStyleItemInfo) e.Item.DataItem; - - var ltlSeq = (Literal) e.Item.FindControl("ltlSeq"); - var tbTitle = (TextBox) e.Item.FindControl("tbTitle"); - var tbValue = (TextBox) e.Item.FindControl("tbValue"); - var cbIsSelected = (CheckBox) e.Item.FindControl("cbIsSelected"); - - ltlSeq.Text = (e.Item.ItemIndex + 1).ToString(); - tbTitle.Text = itemInfo.ItemTitle; - tbValue.Text = itemInfo.ItemValue; - cbIsSelected.Checked = itemInfo.IsSelected; - } - - public void ReFresh(object sender, EventArgs e) - { - PhRelatedField.Visible = PhWidth.Visible = PhHeight.Visible = SpanDateTip.Visible = PhIsSelectField.Visible = PhRapid.Visible = PhNotRapid.Visible = PhRepeat.Visible = PhIsFormatString.Visible = PhDefaultValue.Visible = PhCustomize.Visible = false; - - if (!string.IsNullOrEmpty(_attributeName)) - { - TbAttributeName.Enabled = false; - } - - var inputType = InputTypeUtils.GetEnumType(DdlInputType.SelectedValue); - if (inputType == InputType.CheckBox || inputType == InputType.Radio || inputType == InputType.SelectMultiple || inputType == InputType.SelectOne) - { - PhDefaultValue.Visible = PhIsSelectField.Visible = true; - var isRapid = TranslateUtils.ToBool(DdlIsRapid.SelectedValue); - if (isRapid) - { - PhRapid.Visible = true; - PhNotRapid.Visible = false; - } - else - { - PhRapid.Visible = false; - PhNotRapid.Visible = true; - } - if (inputType == InputType.CheckBox || inputType == InputType.Radio) - { - PhRepeat.Visible = true; - } - } - else if (inputType == InputType.TextEditor) - { - PhDefaultValue.Visible = PhWidth.Visible = PhHeight.Visible = true; - } - else if (inputType == InputType.TextArea) - { - PhDefaultValue.Visible = PhWidth.Visible = PhHeight.Visible = true; - } - else if (inputType == InputType.Text) - { - PhDefaultValue.Visible = PhIsFormatString.Visible = PhWidth.Visible = true; - } - else if (inputType == InputType.Date || inputType == InputType.DateTime) - { - PhDefaultValue.Visible = SpanDateTip.Visible = true; - } - else if (inputType == InputType.SelectCascading) - { - PhDefaultValue.Visible = PhRelatedField.Visible = true; - } - else if (inputType == InputType.Image || inputType == InputType.Video || inputType == InputType.File) - { - PhDefaultValue.Visible = true; - } - else if (inputType == InputType.Customize) - { - PhCustomize.Visible = true; - } - } - - public void SetCount_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack) return; - - var count = TranslateUtils.ToInt(TbItemCount.Text); - if (count != 0) - { - List styleItems = null; - if (_styleInfo.Id != 0) - { - styleItems = DataProvider.TableStyleItemDao.GetStyleItemInfoList(_styleInfo.Id); - } - RptItems.DataSource = GetDataSource(count, styleItems); - RptItems.DataBind(); - } - else - { - FailMessage("选项数目必须为大于0的数字!"); - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - bool isChanged; - - var inputType = InputTypeUtils.GetEnumType(DdlInputType.SelectedValue); - - if (inputType == InputType.Radio || inputType == InputType.SelectMultiple || inputType == InputType.SelectOne) - { - var isRapid = TranslateUtils.ToBool(DdlIsRapid.SelectedValue); - if (!isRapid) - { - var itemCount = TranslateUtils.ToInt(TbItemCount.Text); - if (itemCount == 0) - { - FailMessage("操作失败,选项数目不能为0!"); - return; - } - } - } - - if (_styleInfo.Id == 0 && _styleInfo.RelatedIdentity == 0)//数据库中没有此项及父项的表样式 - { - isChanged = InsertTableStyleInfo(inputType); - } - else if (_styleInfo.RelatedIdentity != _relatedIdentities[0])//数据库中没有此项的表样式,但是有父项的表样式 - { - isChanged = InsertTableStyleInfo(inputType); - } - else//数据库中有此项的表样式 - { - isChanged = UpdateTableStyleInfo(inputType); - } - - if (isChanged) - { - LayerUtils.CloseAndRedirect(Page, _redirectUrl); - } - } - - private bool UpdateTableStyleInfo(InputType inputType) - { - var isChanged = false; - _styleInfo.AttributeName =TbAttributeName.Text; - _styleInfo.DisplayName = PageUtils.FilterXss(TbDisplayName.Text); - _styleInfo.HelpText = TbHelpText.Text; - _styleInfo.Taxis = TranslateUtils.ToInt(TbTaxis.Text); - _styleInfo.InputType = inputType; - _styleInfo.DefaultValue = TbDefaultValue.Text; - _styleInfo.IsHorizontal = TranslateUtils.ToBool(DdlIsHorizontal.SelectedValue); - - _styleInfo.Additional.Columns = TranslateUtils.ToInt(TbColumns.Text); - _styleInfo.Additional.Height = TranslateUtils.ToInt(TbHeight.Text); - _styleInfo.Additional.Width = TbWidth.Text; - _styleInfo.Additional.IsFormatString = TranslateUtils.ToBool(DdlIsFormatString.SelectedValue); - _styleInfo.Additional.RelatedFieldId = TranslateUtils.ToInt(DdlRelatedFieldId.SelectedValue); - _styleInfo.Additional.RelatedFieldStyle = DdlRelatedFieldStyle.SelectedValue; - _styleInfo.Additional.CustomizeLeft = TbCustomizeLeft.Text; - _styleInfo.Additional.CustomizeRight = TbCustomizeRight.Text; - - List styleItems = null; - - if (inputType == InputType.CheckBox || inputType == InputType.Radio || inputType == InputType.SelectMultiple || inputType == InputType.SelectOne) - { - styleItems = new List(); - - var isRapid = TranslateUtils.ToBool(DdlIsRapid.SelectedValue); - if (isRapid) - { - var rapidValues = TranslateUtils.StringCollectionToStringList(TbRapidValues.Text); - foreach (var rapidValue in rapidValues) - { - var itemInfo = new TableStyleItemInfo(0, _styleInfo.Id, rapidValue, rapidValue, false); - styleItems.Add(itemInfo); - } - } - else - { - var isHasSelected = false; - foreach (RepeaterItem item in RptItems.Items) - { - var tbTitle = (TextBox)item.FindControl("tbTitle"); - var tbValue = (TextBox)item.FindControl("tbValue"); - var cbIsSelected = (CheckBox)item.FindControl("cbIsSelected"); - - if (inputType != InputType.SelectMultiple && inputType != InputType.CheckBox && isHasSelected && cbIsSelected.Checked) - { - FailMessage("操作失败,只能有一个初始化时选定项!"); - return false; - } - if (cbIsSelected.Checked) isHasSelected = true; - - var itemInfo = new TableStyleItemInfo(0, _styleInfo.Id, tbTitle.Text, tbValue.Text, cbIsSelected.Checked); - styleItems.Add(itemInfo); - } - } - } - - try - { - TableStyleManager.Update(_styleInfo); - TableStyleManager.DeleteAndInsertStyleItems(_styleInfo.Id, styleItems); - - if (SiteId > 0) - { - AuthRequest.AddSiteLog(SiteId, "修改表单显示样式", $"字段名:{_styleInfo.AttributeName}"); - } - else - { - AuthRequest.AddAdminLog("修改表单显示样式", $"字段名:{_styleInfo.AttributeName}"); - } - isChanged = true; - } - catch (Exception ex) - { - FailMessage(ex, "显示样式修改失败:" + ex.Message); - } - return isChanged; - } - - private bool InsertTableStyleInfo(InputType inputType) - { - var isChanged = false; - - var relatedIdentity = _relatedIdentities[0]; - - if (string.IsNullOrEmpty(TbAttributeName.Text)) - { - FailMessage("操作失败,字段名不能为空!"); - return false; - } - - if (TableStyleManager.IsExists(relatedIdentity, _tableName, TbAttributeName.Text)) - { - FailMessage($@"显示样式添加失败:字段名""{TbAttributeName.Text}""已存在"); - return false; - } - - _styleInfo = DataProvider.TableMetadataDao.IsExists(_tableName, TbAttributeName.Text) ? TableStyleManager.GetTableStyleInfo(_tableName, TbAttributeName.Text, _relatedIdentities) : new TableStyleInfo(); - - _styleInfo.RelatedIdentity = relatedIdentity; - _styleInfo.TableName = _tableName; - _styleInfo.AttributeName = TbAttributeName.Text; - _styleInfo.DisplayName =PageUtils.FilterXss(TbDisplayName.Text); - _styleInfo.HelpText = TbHelpText.Text; - _styleInfo.Taxis = TranslateUtils.ToInt(TbTaxis.Text); - _styleInfo.InputType = inputType; - _styleInfo.DefaultValue = TbDefaultValue.Text; - _styleInfo.IsHorizontal = TranslateUtils.ToBool(DdlIsHorizontal.SelectedValue); - - _styleInfo.Additional.Columns = TranslateUtils.ToInt(TbColumns.Text); - _styleInfo.Additional.Height = TranslateUtils.ToInt(TbHeight.Text); - _styleInfo.Additional.Width = TbWidth.Text; - _styleInfo.Additional.IsFormatString = TranslateUtils.ToBool(DdlIsFormatString.SelectedValue); - _styleInfo.Additional.RelatedFieldId = TranslateUtils.ToInt(DdlRelatedFieldId.SelectedValue); - _styleInfo.Additional.RelatedFieldStyle = DdlRelatedFieldStyle.SelectedValue; - _styleInfo.Additional.CustomizeLeft = TbCustomizeLeft.Text; - _styleInfo.Additional.CustomizeRight = TbCustomizeRight.Text; - - if (inputType == InputType.CheckBox || inputType == InputType.Radio || inputType == InputType.SelectMultiple || inputType == InputType.SelectOne) - { - _styleInfo.StyleItems = new List(); - - var isRapid = TranslateUtils.ToBool(DdlIsRapid.SelectedValue); - if (isRapid) - { - var rapidValues = TranslateUtils.StringCollectionToStringList(TbRapidValues.Text); - foreach (var rapidValue in rapidValues) - { - var itemInfo = new TableStyleItemInfo(0, _styleInfo.Id, rapidValue, rapidValue, false); - _styleInfo.StyleItems.Add(itemInfo); - } - } - else - { - var isHasSelected = false; - foreach (RepeaterItem item in RptItems.Items) - { - var tbTitle = (TextBox)item.FindControl("tbTitle"); - var tbValue = (TextBox)item.FindControl("tbValue"); - var cbIsSelected = (CheckBox)item.FindControl("cbIsSelected"); - - if (inputType != InputType.SelectMultiple && inputType != InputType.CheckBox && isHasSelected && cbIsSelected.Checked) - { - FailMessage("操作失败,只能有一个初始化时选定项!"); - return false; - } - if (cbIsSelected.Checked) isHasSelected = true; - - var itemInfo = new TableStyleItemInfo(0, 0, tbTitle.Text, tbValue.Text, cbIsSelected.Checked); - _styleInfo.StyleItems.Add(itemInfo); - } - } - } - - try - { - TableStyleManager.Insert(_styleInfo); - - if (SiteId > 0) - { - AuthRequest.AddSiteLog(SiteId, "添加表单显示样式", $"字段名:{_styleInfo.AttributeName}"); - } - else - { - AuthRequest.AddAdminLog("添加表单显示样式", $"字段名:{_styleInfo.AttributeName}"); - } - - isChanged = true; - } - catch (Exception ex) - { - FailMessage(ex, "显示样式添加失败:" + ex.Message); - } - return isChanged; - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalTableStyleValidateAdd.cs b/SiteServer.BackgroundPages/Cms/ModalTableStyleValidateAdd.cs deleted file mode 100644 index 5df4ada60..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalTableStyleValidateAdd.cs +++ /dev/null @@ -1,146 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils; -using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalTableStyleValidateAdd : BasePageCms - { - public DropDownList DdlIsValidate; - public PlaceHolder PhValidate; - public DropDownList DdlIsRequired; - public PlaceHolder PhNum; - public TextBox TbMinNum; - public TextBox TbMaxNum; - public DropDownList DdlValidateType; - public PlaceHolder PhRegExp; - public TextBox TbRegExp; - public TextBox TbErrorMessage; - - private int _tableStyleId; - private List _relatedIdentities; - private string _tableName; - private string _attributeName; - private string _redirectUrl; - private TableStyleInfo _styleInfo; - - public static string GetOpenWindowString(int siteId, int tableStyleId, List relatedIdentities, string tableName, string attributeName, string redirectUrl) - { - return LayerUtils.GetOpenScript("设置表单验证", PageUtils.GetCmsUrl(siteId, nameof(ModalTableStyleValidateAdd), new NameValueCollection - { - {"TableStyleID", tableStyleId.ToString()}, - {"RelatedIdentities", TranslateUtils.ObjectCollectionToString(relatedIdentities)}, - {"TableName", tableName}, - {"AttributeName", attributeName}, - {"RedirectUrl", StringUtils.ValueToUrl(redirectUrl)} - })); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - _tableStyleId = AuthRequest.GetQueryInt("TableStyleID"); - _relatedIdentities = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("RelatedIdentities")); - if (_relatedIdentities.Count == 0) - { - _relatedIdentities.Add(0); - } - _tableName = AuthRequest.GetQueryString("TableName"); - _attributeName = AuthRequest.GetQueryString("AttributeName"); - _redirectUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("RedirectUrl")); - - _styleInfo = _tableStyleId != 0 - ? DataProvider.TableStyleDao.GetTableStyleInfo(_tableStyleId) - : TableStyleManager.GetTableStyleInfo(_tableName, _attributeName, _relatedIdentities); - - if (IsPostBack) return; - - DdlIsValidate.Items[0].Value = true.ToString(); - DdlIsValidate.Items[1].Value = false.ToString(); - - ControlUtils.SelectSingleItem(DdlIsValidate, _styleInfo.Additional.IsValidate.ToString()); - - DdlIsRequired.Items[0].Value = true.ToString(); - DdlIsRequired.Items[1].Value = false.ToString(); - - ControlUtils.SelectSingleItem(DdlIsRequired, _styleInfo.Additional.IsRequired.ToString()); - - PhNum.Visible = InputTypeUtils.EqualsAny(_styleInfo.InputType, InputType.Text, InputType.TextArea); - - TbMinNum.Text = _styleInfo.Additional.MinNum.ToString(); - TbMaxNum.Text = _styleInfo.Additional.MaxNum.ToString(); - - ValidateTypeUtils.AddListItems(DdlValidateType); - ControlUtils.SelectSingleItem(DdlValidateType, _styleInfo.Additional.ValidateType.Value); - - TbRegExp.Text = _styleInfo.Additional.RegExp; - TbErrorMessage.Text = _styleInfo.Additional.ErrorMessage; - - DdlValidate_SelectedIndexChanged(null, EventArgs.Empty); - } - - public void DdlValidate_SelectedIndexChanged(object sender, EventArgs e) - { - PhValidate.Visible = !EBooleanUtils.Equals(EBoolean.False, DdlIsValidate.SelectedValue); - var type = ValidateTypeUtils.GetEnumType(DdlValidateType.SelectedValue); - PhRegExp.Visible = type == ValidateType.RegExp; - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var isChanged = InsertOrUpdateTableStyleInfo(); - - if (isChanged) - { - LayerUtils.CloseAndRedirect(Page, _redirectUrl); - } - } - - private bool InsertOrUpdateTableStyleInfo() - { - var isChanged = false; - - _styleInfo.Additional.IsValidate = TranslateUtils.ToBool(DdlIsValidate.SelectedValue); - _styleInfo.Additional.IsRequired = TranslateUtils.ToBool(DdlIsRequired.SelectedValue); - _styleInfo.Additional.MinNum = TranslateUtils.ToInt(TbMinNum.Text); - _styleInfo.Additional.MaxNum = TranslateUtils.ToInt(TbMaxNum.Text); - _styleInfo.Additional.ValidateType = ValidateTypeUtils.GetEnumType(DdlValidateType.SelectedValue); - _styleInfo.Additional.RegExp = TbRegExp.Text.Trim('/'); - _styleInfo.Additional.ErrorMessage = TbErrorMessage.Text; - - try - { - if (_tableStyleId == 0)//数据库中没有此项的表样式,但是有父项的表样式 - { - var relatedIdentity = _relatedIdentities[0]; - _styleInfo.RelatedIdentity = relatedIdentity; - _styleInfo.Id = TableStyleManager.Insert(_styleInfo); - } - - if (_styleInfo.Id > 0) - { - TableStyleManager.Update(_styleInfo); - AuthRequest.AddSiteLog(SiteId, "修改表单验证", $"字段:{_styleInfo.AttributeName}"); - } - else - { - TableStyleManager.Insert(_styleInfo); - AuthRequest.AddSiteLog(SiteId, "新增表单验证", $"字段:{_styleInfo.AttributeName}"); - } - isChanged = true; - } - catch (Exception ex) - { - FailMessage(ex, "设置表单验证失败:" + ex.Message); - } - return isChanged; - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalTemplateFilePathRule.cs b/SiteServer.BackgroundPages/Cms/ModalTemplateFilePathRule.cs deleted file mode 100644 index 03be76d4b..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalTemplateFilePathRule.cs +++ /dev/null @@ -1,158 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Create; -using SiteServer.CMS.Model.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalTemplateFilePathRule : BasePageCms - { - public PlaceHolder PhFilePath; - public TextBox TbFilePath; - public TextBox TbChannelFilePathRule; - public TextBox TbContentFilePathRule; - public Button BtnCreateChannelRule; - public Button BtnCreateContentRule; - - private int _channelId; - - public static string GetOpenWindowString(int siteId, int channelId) - { - return LayerUtils.GetOpenScript("页面命名规则", - PageUtils.GetCmsUrl(siteId, nameof(ModalTemplateFilePathRule), new NameValueCollection - { - {"channelId", channelId.ToString()} - })); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "channelId"); - _channelId = AuthRequest.GetQueryInt("channelId"); - - if (IsPostBack) return; - - var channelInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - var linkType = ELinkTypeUtils.GetEnumType(channelInfo.LinkType); - if (channelInfo.ParentId == 0 || linkType == ELinkType.LinkToFirstChannel || linkType == ELinkType.LinkToFirstContent || linkType == ELinkType.LinkToLastAddChannel || linkType == ELinkType.NoLink) - { - PhFilePath.Visible = false; - } - - var showPopWinString = ModalFilePathRule.GetOpenWindowString(SiteId, _channelId, true, TbChannelFilePathRule.ClientID); - BtnCreateChannelRule.Attributes.Add("onclick", showPopWinString); - - showPopWinString = ModalFilePathRule.GetOpenWindowString(SiteId, _channelId, false, TbContentFilePathRule.ClientID); - BtnCreateContentRule.Attributes.Add("onclick", showPopWinString); - - TbFilePath.Text = string.IsNullOrEmpty(channelInfo.FilePath) ? PageUtility.GetInputChannelUrl(SiteInfo, channelInfo, false) : channelInfo.FilePath; - - TbChannelFilePathRule.Text = string.IsNullOrEmpty(channelInfo.ChannelFilePathRule) ? PathUtility.GetChannelFilePathRule(SiteInfo, _channelId) : channelInfo.ChannelFilePathRule; - - TbContentFilePathRule.Text = string.IsNullOrEmpty(channelInfo.ContentFilePathRule) ? PathUtility.GetContentFilePathRule(SiteInfo, _channelId) : channelInfo.ContentFilePathRule; - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var isSuccess = false; - - try - { - var channelInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - - var filePath = channelInfo.FilePath; - - if (PhFilePath.Visible) - { - TbFilePath.Text = TbFilePath.Text.Trim(); - if (!string.IsNullOrEmpty(TbFilePath.Text) && !StringUtils.EqualsIgnoreCase(filePath, TbFilePath.Text)) - { - if (!DirectoryUtils.IsDirectoryNameCompliant(TbFilePath.Text)) - { - FailMessage("栏目页面路径不符合系统要求!"); - return; - } - - if (PathUtils.IsDirectoryPath(TbFilePath.Text)) - { - TbFilePath.Text = PageUtils.Combine(TbFilePath.Text, "index.html"); - } - - var filePathArrayList = DataProvider.ChannelDao.GetAllFilePathBySiteId(SiteId); - filePathArrayList.AddRange(DataProvider.TemplateMatchDao.GetAllFilePathBySiteId(SiteId)); - if (filePathArrayList.IndexOf(TbFilePath.Text) != -1) - { - FailMessage("栏目修改失败,栏目页面路径已存在!"); - return; - } - } - } - - if (!string.IsNullOrEmpty(TbChannelFilePathRule.Text)) - { - var filePathRule = TbChannelFilePathRule.Text.Replace("|", string.Empty); - if (!DirectoryUtils.IsDirectoryNameCompliant(filePathRule)) - { - FailMessage("栏目页面命名规则不符合系统要求!"); - return; - } - if (PathUtils.IsDirectoryPath(filePathRule)) - { - FailMessage("栏目页面命名规则必须包含生成文件的后缀!"); - return; - } - } - - if (!string.IsNullOrEmpty(TbContentFilePathRule.Text)) - { - var filePathRule = TbContentFilePathRule.Text.Replace("|", string.Empty); - if (!DirectoryUtils.IsDirectoryNameCompliant(filePathRule)) - { - FailMessage("内容页面命名规则不符合系统要求!"); - return; - } - if (PathUtils.IsDirectoryPath(filePathRule)) - { - FailMessage("内容页面命名规则必须包含生成文件的后缀!"); - return; - } - } - - if (TbFilePath.Text != PageUtility.GetInputChannelUrl(SiteInfo, channelInfo, false)) - { - channelInfo.FilePath = TbFilePath.Text; - } - if (TbChannelFilePathRule.Text != PathUtility.GetChannelFilePathRule(SiteInfo, _channelId)) - { - channelInfo.ChannelFilePathRule = TbChannelFilePathRule.Text; - } - if (TbContentFilePathRule.Text != PathUtility.GetContentFilePathRule(SiteInfo, _channelId)) - { - channelInfo.ContentFilePathRule = TbContentFilePathRule.Text; - } - - DataProvider.ChannelDao.Update(channelInfo); - - CreateManager.CreateChannel(SiteId, _channelId); - - AuthRequest.AddSiteLog(SiteId, _channelId, 0, "设置页面命名规则", $"栏目:{channelInfo.ChannelName}"); - - isSuccess = true; - } - catch (Exception ex) - { - FailMessage(ex, ex.Message); - } - - if (isSuccess) - { - LayerUtils.CloseAndRedirect(Page, PageConfigurationCreateRule.GetRedirectUrl(SiteId, _channelId)); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalTemplateView.cs b/SiteServer.BackgroundPages/Cms/ModalTemplateView.cs deleted file mode 100644 index 1a94ba309..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalTemplateView.cs +++ /dev/null @@ -1,34 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalTemplateView : BasePageCms - { - public TextBox TbContent; - - public static string GetOpenWindowString(int siteId, int templateLogId) - { - return LayerUtils.GetOpenScript("查看修订内容", PageUtils.GetCmsUrl(siteId, nameof(ModalTemplateView), new NameValueCollection - { - {"templateLogID", templateLogId.ToString()} - })); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (!IsPostBack) - { - var templateLogId = AuthRequest.GetQueryInt("templateLogID"); - TbContent.Text = DataProvider.TemplateLogDao.GetTemplateContent(templateLogId); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalTextEditorInsertImage.cs b/SiteServer.BackgroundPages/Cms/ModalTextEditorInsertImage.cs deleted file mode 100644 index 58e1df1e6..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalTextEditorInsertImage.cs +++ /dev/null @@ -1,147 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.HtmlControls; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Create; -using SiteServer.CMS.Core.Office; -using SiteServer.CMS.Model; -using SiteServer.Utils.Enumerations; -using SiteServer.Utils.Images; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalTextEditorInsertImage : BasePageCms - { - public HtmlInputHidden HihFilePaths; - public CheckBox CbIsLinkToOriginal; - public CheckBox CbIsSmallImage; - public TextBox TbSmallImageWidth; - public TextBox TbSmallImageHeight; - - private string _attributeName; - - public static string GetOpenWindowString(int siteId, string attributeName) - { - return LayerUtils.GetOpenScript("插入图片", - PageUtils.GetCmsUrl(siteId, nameof(ModalTextEditorInsertImage), new NameValueCollection - { - {"attributeName", attributeName} - }), 700, 550); - } - - public string UploadUrl => ModalTextEditorInsertImageHandler.GetRedirectUrl(SiteId); - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "attributeName"); - _attributeName = AuthRequest.GetQueryString("attributeName"); - - if (IsPostBack) return; - - ConfigSettings(true); - - CbIsSmallImage.Attributes.Add("onclick", "checkBoxChange();"); - } - - private void ConfigSettings(bool isLoad) - { - if (isLoad) - { - if (!string.IsNullOrEmpty(SiteInfo.Additional.ConfigUploadImageIsLinkToOriginal)) - { - CbIsLinkToOriginal.Checked = TranslateUtils.ToBool(SiteInfo.Additional.ConfigUploadImageIsLinkToOriginal); - } - if (!string.IsNullOrEmpty(SiteInfo.Additional.ConfigUploadImageIsSmallImage)) - { - CbIsSmallImage.Checked = TranslateUtils.ToBool(SiteInfo.Additional.ConfigUploadImageIsSmallImage); - } - if (!string.IsNullOrEmpty(SiteInfo.Additional.ConfigUploadImageSmallImageWidth)) - { - TbSmallImageWidth.Text = SiteInfo.Additional.ConfigUploadImageSmallImageWidth; - } - if (!string.IsNullOrEmpty(SiteInfo.Additional.ConfigUploadImageSmallImageHeight)) - { - TbSmallImageHeight.Text = SiteInfo.Additional.ConfigUploadImageSmallImageHeight; - } - } - else - { - if (SiteInfo.Additional.ConfigUploadImageIsLinkToOriginal != CbIsLinkToOriginal.Checked.ToString() - || SiteInfo.Additional.ConfigUploadImageIsSmallImage != CbIsSmallImage.Checked.ToString() - || SiteInfo.Additional.ConfigUploadImageSmallImageWidth != TbSmallImageWidth.Text - || SiteInfo.Additional.ConfigUploadImageSmallImageHeight != TbSmallImageHeight.Text) - { - SiteInfo.Additional.ConfigUploadImageIsLinkToOriginal = CbIsLinkToOriginal.Checked.ToString(); - SiteInfo.Additional.ConfigUploadImageIsSmallImage = CbIsSmallImage.Checked.ToString(); - SiteInfo.Additional.ConfigUploadImageSmallImageWidth = TbSmallImageWidth.Text; - SiteInfo.Additional.ConfigUploadImageSmallImageHeight = TbSmallImageHeight.Text; - - DataProvider.SiteDao.Update(SiteInfo); - } - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - if (CbIsSmallImage.Checked && string.IsNullOrEmpty(TbSmallImageWidth.Text) && string.IsNullOrEmpty(TbSmallImageHeight.Text)) - { - FailMessage("缩略图尺寸不能为空!"); - return; - } - - ConfigSettings(false); - - var scripts = string.Empty; - - var fileNames = TranslateUtils.StringCollectionToStringList(HihFilePaths.Value); - - foreach (var filePath in fileNames) - { - if (!string.IsNullOrEmpty(filePath)) - { - var fileName = PathUtils.GetFileName(filePath); - - var fileExtName = PathUtils.GetExtension(filePath).ToLower(); - var localDirectoryPath = PathUtility.GetUploadDirectoryPath(SiteInfo, fileExtName); - - var imageUrl = PageUtility.GetSiteUrlByPhysicalPath(SiteInfo, filePath, true); - - if (CbIsSmallImage.Checked) - { - var localSmallFileName = StringUtils.Constants.SmallImageAppendix + fileName; - var localSmallFilePath = PathUtils.Combine(localDirectoryPath, localSmallFileName); - - var smallImageUrl = PageUtility.GetSiteUrlByPhysicalPath(SiteInfo, localSmallFilePath, true); - - var width = TranslateUtils.ToInt(TbSmallImageWidth.Text); - var height = TranslateUtils.ToInt(TbSmallImageHeight.Text); - ImageUtils.MakeThumbnail(filePath, localSmallFilePath, width, height, true); - - var insertHtml = CbIsLinkToOriginal.Checked - ? $@"" - : $@""; - - scripts += "if(parent." + ETextEditorTypeUtils.GetEditorInstanceScript() + ") parent." + - ETextEditorTypeUtils.GetInsertHtmlScript("Content", insertHtml); - } - else - { - var insertHtml = $@""; - - scripts += "if(parent." + ETextEditorTypeUtils.GetEditorInstanceScript() + ") parent." + - ETextEditorTypeUtils.GetInsertHtmlScript("Content", insertHtml); - } - } - } - - LayerUtils.CloseWithoutRefresh(Page, scripts); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalTextEditorInsertVideo.cs b/SiteServer.BackgroundPages/Cms/ModalTextEditorInsertVideo.cs deleted file mode 100644 index 4ab5928c8..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalTextEditorInsertVideo.cs +++ /dev/null @@ -1,138 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; -using SiteServer.Utils.LitJson; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalTextEditorInsertVideo : BasePageCms - { - public TextBox TbPlayUrl; - public TextBox TbWidth; - public TextBox TbHeight; - public CheckBox CbIsAutoPlay; - - private string _attributeName; - - public static string GetOpenWindowString(int siteId, string attributeName) - { - return LayerUtils.GetOpenScript("插入视频", PageUtils.GetCmsUrl(siteId, nameof(ModalTextEditorInsertVideo), new NameValueCollection - { - {"AttributeName", attributeName} - }), 600, 460); - } - - public string UploadUrl => PageUtils.GetCmsUrl(SiteId, nameof(ModalTextEditorInsertVideo), new NameValueCollection - { - {"upload", true.ToString()} - }); - - public string TypeCollection => SiteInfo.Additional.VideoUploadTypeCollection; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (AuthRequest.IsQueryExists("upload")) - { - var json = JsonMapper.ToJson(Upload()); - Response.Write(json); - Response.End(); - return; - } - - _attributeName = AuthRequest.GetQueryString("AttributeName"); - - if (IsPostBack) return; - - TbWidth.Text = SiteInfo.Additional.ConfigVideoContentInsertWidth.ToString(); - TbHeight.Text = SiteInfo.Additional.ConfigVideoContentInsertHeight.ToString(); - } - - private Hashtable Upload() - { - var success = false; - var playUrl = string.Empty; - var message = "视频上传失败"; - - if (Request.Files["filedata"] != null) - { - var postedFile = Request.Files["filedata"]; - try - { - if (!string.IsNullOrEmpty(postedFile?.FileName)) - { - var filePath = postedFile.FileName; - var fileExtName = PathUtils.GetExtension(filePath); - - var isAllow = true; - if (!PathUtility.IsVideoExtenstionAllowed(SiteInfo, fileExtName)) - { - message = "此格式不允许上传,请选择有效的音频文件"; - isAllow = false; - } - if (!PathUtility.IsVideoSizeAllowed(SiteInfo, postedFile.ContentLength)) - { - message = "上传失败,上传文件超出规定文件大小"; - isAllow = false; - } - - if (isAllow) - { - var localDirectoryPath = PathUtility.GetUploadDirectoryPath(SiteInfo, fileExtName); - var localFileName = PathUtility.GetUploadFileName(SiteInfo, filePath); - var localFilePath = PathUtils.Combine(localDirectoryPath, localFileName); - - postedFile.SaveAs(localFilePath); - - playUrl = PageUtility.GetSiteUrlByPhysicalPath(SiteInfo, localFilePath, true); - playUrl = PageUtility.GetVirtualUrl(SiteInfo, playUrl); - - success = true; - } - } - } - catch (Exception ex) - { - message = ex.Message; - } - } - - var jsonAttributes = new Hashtable(); - if (success) - { - jsonAttributes.Add("success", "true"); - jsonAttributes.Add("playUrl", playUrl); - } - else - { - jsonAttributes.Add("success", "false"); - jsonAttributes.Add("message", message); - } - - return jsonAttributes; - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var width = TranslateUtils.ToInt(TbWidth.Text); - var height = TranslateUtils.ToInt(TbHeight.Text); - if (width > 0 && height > 0 && (width != SiteInfo.Additional.ConfigVideoContentInsertWidth || height != SiteInfo.Additional.ConfigVideoContentInsertHeight)) - { - SiteInfo.Additional.ConfigVideoContentInsertWidth = width; - SiteInfo.Additional.ConfigVideoContentInsertHeight = height; - DataProvider.SiteDao.Update(SiteInfo); - } - - var playUrl = TbPlayUrl.Text; - - var script = "parent." + ETextEditorTypeUtils.GetInsertVideoScript(_attributeName, playUrl, width, height, CbIsAutoPlay.Checked); - LayerUtils.CloseWithoutRefresh(Page, script); - } - - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalUploadImage.cs b/SiteServer.BackgroundPages/Cms/ModalUploadImage.cs deleted file mode 100644 index d2e8cb092..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalUploadImage.cs +++ /dev/null @@ -1,213 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.HtmlControls; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.Utils.Images; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalUploadImage : BasePageCms - { - public HtmlInputFile HifUpload; - - public CheckBox CbIsTitleImage; - public TextBox TbTitleImageWidth; - public TextBox TbTitleImageHeight; - - public CheckBox CbIsShowImageInTextEditor; - public CheckBox CbIsLinkToOriginal; - public CheckBox CbIsSmallImage; - public TextBox TbSmallImageWidth; - public TextBox TbSmallImageHeight; - - public Literal LtlScript; - - private string _textBoxClientId; - - public static string GetOpenWindowString(int siteId, string textBoxClientId) - { - return LayerUtils.GetOpenScript("上传图片", PageUtils.GetCmsUrl(siteId, nameof(ModalUploadImage), new NameValueCollection - { - {"textBoxClientID", textBoxClientId} - }), 600, 560); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - _textBoxClientId = AuthRequest.GetQueryString("TextBoxClientID"); - - if (IsPostBack) return; - - ConfigSettings(true); - - CbIsTitleImage.Attributes.Add("onclick", "checkBoxChange();"); - CbIsShowImageInTextEditor.Attributes.Add("onclick", "checkBoxChange();"); - CbIsSmallImage.Attributes.Add("onclick", "checkBoxChange();"); - } - - private void ConfigSettings(bool isLoad) - { - if (isLoad) - { - if (!string.IsNullOrEmpty(SiteInfo.Additional.ConfigUploadImageIsTitleImage)) - { - CbIsTitleImage.Checked = TranslateUtils.ToBool(SiteInfo.Additional.ConfigUploadImageIsTitleImage); - } - if (!string.IsNullOrEmpty(SiteInfo.Additional.ConfigUploadImageTitleImageWidth)) - { - TbTitleImageWidth.Text = SiteInfo.Additional.ConfigUploadImageTitleImageWidth; - } - if (!string.IsNullOrEmpty(SiteInfo.Additional.ConfigUploadImageTitleImageHeight)) - { - TbTitleImageHeight.Text = SiteInfo.Additional.ConfigUploadImageTitleImageHeight; - } - - if (!string.IsNullOrEmpty(SiteInfo.Additional.ConfigUploadImageIsShowImageInTextEditor)) - { - CbIsShowImageInTextEditor.Checked = TranslateUtils.ToBool(SiteInfo.Additional.ConfigUploadImageIsShowImageInTextEditor); - } - if (!string.IsNullOrEmpty(SiteInfo.Additional.ConfigUploadImageIsLinkToOriginal)) - { - CbIsLinkToOriginal.Checked = TranslateUtils.ToBool(SiteInfo.Additional.ConfigUploadImageIsLinkToOriginal); - } - if (!string.IsNullOrEmpty(SiteInfo.Additional.ConfigUploadImageIsSmallImage)) - { - CbIsSmallImage.Checked = TranslateUtils.ToBool(SiteInfo.Additional.ConfigUploadImageIsSmallImage); - } - if (!string.IsNullOrEmpty(SiteInfo.Additional.ConfigUploadImageSmallImageWidth)) - { - TbSmallImageWidth.Text = SiteInfo.Additional.ConfigUploadImageSmallImageWidth; - } - if (!string.IsNullOrEmpty(SiteInfo.Additional.ConfigUploadImageSmallImageHeight)) - { - TbSmallImageHeight.Text = SiteInfo.Additional.ConfigUploadImageSmallImageHeight; - } - } - else - { - SiteInfo.Additional.ConfigUploadImageIsTitleImage = CbIsTitleImage.Checked.ToString(); - SiteInfo.Additional.ConfigUploadImageTitleImageWidth = TbTitleImageWidth.Text; - SiteInfo.Additional.ConfigUploadImageTitleImageHeight = TbTitleImageHeight.Text; - - SiteInfo.Additional.ConfigUploadImageIsShowImageInTextEditor = CbIsShowImageInTextEditor.Checked.ToString(); - SiteInfo.Additional.ConfigUploadImageIsLinkToOriginal = CbIsLinkToOriginal.Checked.ToString(); - SiteInfo.Additional.ConfigUploadImageIsSmallImage = CbIsSmallImage.Checked.ToString(); - SiteInfo.Additional.ConfigUploadImageSmallImageWidth = TbSmallImageWidth.Text; - SiteInfo.Additional.ConfigUploadImageSmallImageHeight = TbSmallImageHeight.Text; - - DataProvider.SiteDao.Update(SiteInfo); - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (CbIsTitleImage.Checked && string.IsNullOrEmpty(TbTitleImageWidth.Text) && string.IsNullOrEmpty(TbTitleImageHeight.Text)) - { - FailMessage("缩略图尺寸不能为空!"); - return; - } - if (CbIsSmallImage.Checked && string.IsNullOrEmpty(TbSmallImageWidth.Text) && string.IsNullOrEmpty(TbSmallImageHeight.Text)) - { - FailMessage("缩略图尺寸不能为空!"); - return; - } - - ConfigSettings(false); - - if (HifUpload.PostedFile == null || "" == HifUpload.PostedFile.FileName) return; - - var filePath = HifUpload.PostedFile.FileName; - try - { - var fileExtName = PathUtils.GetExtension(filePath).ToLower(); - var localDirectoryPath = PathUtility.GetUploadDirectoryPath(SiteInfo, fileExtName); - var localFileName = PathUtility.GetUploadFileName(SiteInfo, filePath); - var localTitleFileName = StringUtils.Constants.TitleImageAppendix + localFileName; - var localSmallFileName = StringUtils.Constants.SmallImageAppendix + localFileName; - var localFilePath = PathUtils.Combine(localDirectoryPath, localFileName); - var localTitleFilePath = PathUtils.Combine(localDirectoryPath, localTitleFileName); - var localSmallFilePath = PathUtils.Combine(localDirectoryPath, localSmallFileName); - - if (!PathUtility.IsImageExtenstionAllowed(SiteInfo, fileExtName)) - { - FailMessage("上传失败,上传图片格式不正确!"); - return; - } - if (!PathUtility.IsImageSizeAllowed(SiteInfo, HifUpload.PostedFile.ContentLength)) - { - FailMessage("上传失败,上传图片超出规定文件大小!"); - return; - } - - HifUpload.PostedFile.SaveAs(localFilePath); - - var isImage = EFileSystemTypeUtils.IsImage(fileExtName); - - //处理上半部分 - if (isImage) - { - FileUtility.AddWaterMark(SiteInfo, localFilePath); - if (CbIsTitleImage.Checked) - { - var width = TranslateUtils.ToInt(TbTitleImageWidth.Text); - var height = TranslateUtils.ToInt(TbTitleImageHeight.Text); - ImageUtils.MakeThumbnail(localFilePath, localTitleFilePath, width, height, true); - } - } - - var imageUrl = PageUtility.GetSiteUrlByPhysicalPath(SiteInfo, localFilePath, true); - if (CbIsTitleImage.Checked) - { - imageUrl = PageUtility.GetSiteUrlByPhysicalPath(SiteInfo, localTitleFilePath, true); - } - - var textBoxUrl = PageUtility.GetVirtualUrl(SiteInfo, imageUrl); - - var script = $@" -if (parent.document.getElementById('{_textBoxClientId}')) -{{ - parent.document.getElementById('{_textBoxClientId}').value = '{textBoxUrl}'; -}} -"; - - //处理下半部分 - if (CbIsShowImageInTextEditor.Checked && isImage) - { - imageUrl = PageUtility.GetSiteUrlByPhysicalPath(SiteInfo, localFilePath, true); - var smallImageUrl = imageUrl; - if (CbIsSmallImage.Checked) - { - smallImageUrl = PageUtility.GetSiteUrlByPhysicalPath(SiteInfo, localSmallFilePath, true); - } - - if (CbIsSmallImage.Checked) - { - var width = TranslateUtils.ToInt(TbSmallImageWidth.Text); - var height = TranslateUtils.ToInt(TbSmallImageHeight.Text); - ImageUtils.MakeThumbnail(localFilePath, localSmallFilePath, width, height, true); - } - - var insertHtml = CbIsLinkToOriginal.Checked ? $@"" : $@""; - - script += "if(parent." + ETextEditorTypeUtils.GetEditorInstanceScript() + ") parent." + ETextEditorTypeUtils.GetInsertHtmlScript("Content", insertHtml); - } - - LtlScript.Text = $@" -"; - } - catch (Exception ex) - { - FailMessage(ex, ex.Message); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/ModalUploadWord.cs b/SiteServer.BackgroundPages/Cms/ModalUploadWord.cs deleted file mode 100644 index 4d5149928..000000000 --- a/SiteServer.BackgroundPages/Cms/ModalUploadWord.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.HtmlControls; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Create; -using SiteServer.CMS.Core.Office; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Cms -{ - public class ModalUploadWord : BasePageCms - { - public HtmlInputHidden HihFileNames; - public CheckBox CbIsFirstLineTitle; - public CheckBox CbIsFirstLineRemove; - public CheckBox CbIsClearFormat; - public CheckBox CbIsFirstLineIndent; - public CheckBox CbIsClearFontSize; - public CheckBox CbIsClearFontFamily; - public CheckBox CbIsClearImages; - public DropDownList DdlContentLevel; - - private ChannelInfo _channelInfo; - private string _returnUrl; - - public static string GetOpenWindowString(int siteId, int channelId, string returnUrl) - { - return LayerUtils.GetOpenScript("批量导入Word文件", - PageUtils.GetCmsUrl(siteId, nameof(ModalUploadWord), new NameValueCollection - { - {"channelId", channelId.ToString()}, - {"returnUrl", returnUrl} - }), 700, 550); - } - - public string UploadUrl => ModalUploadWordHandler.GetRedirectUrl(SiteId); - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "ReturnUrl"); - var channelId = int.Parse(AuthRequest.GetQueryString("channelId")); - _channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - _returnUrl = AuthRequest.GetQueryString("ReturnUrl"); - - if (IsPostBack) return; - - int checkedLevel; - var isChecked = CheckManager.GetUserCheckLevel(AuthRequest.AdminPermissions, SiteInfo, SiteId, out checkedLevel); - CheckManager.LoadContentLevelToEdit(DdlContentLevel, SiteInfo, _channelInfo.Id, null, isChecked, checkedLevel); - ControlUtils.SelectSingleItem(DdlContentLevel, CheckManager.LevelInt.CaoGao.ToString()); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - var fileNames = TranslateUtils.StringCollectionToStringList(HihFileNames.Value); - if (fileNames.Count == 1) - { - var fileName = fileNames[0]; - if (!string.IsNullOrEmpty(fileName)) - { - var redirectUrl = WebUtils.GetContentAddUploadWordUrl(SiteId, _channelInfo, CbIsFirstLineTitle.Checked, CbIsFirstLineRemove.Checked, CbIsClearFormat.Checked, CbIsFirstLineIndent.Checked, CbIsClearFontSize.Checked, CbIsClearFontFamily.Checked, CbIsClearImages.Checked, TranslateUtils.ToIntWithNagetive(DdlContentLevel.SelectedValue), fileName, _returnUrl); - LayerUtils.CloseAndRedirect(Page, redirectUrl); - } - - return; - } - - if (fileNames.Count > 1) - { - var tableName = ChannelManager.GetTableName(SiteInfo, _channelInfo); - var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(SiteId, _channelInfo.Id); - var styleInfoList = TableStyleManager.GetTableStyleInfoList(tableName, relatedIdentities); - - foreach (var fileName in fileNames) - { - if (!string.IsNullOrEmpty(fileName)) - { - var formCollection = WordUtils.GetWordNameValueCollection(SiteId, CbIsFirstLineTitle.Checked, CbIsFirstLineRemove.Checked, CbIsClearFormat.Checked, CbIsFirstLineIndent.Checked, CbIsClearFontSize.Checked, CbIsClearFontFamily.Checked, CbIsClearImages.Checked, TranslateUtils.ToInt(DdlContentLevel.SelectedValue), fileName); - - if (!string.IsNullOrEmpty(formCollection[ContentAttribute.Title])) - { - var contentInfo = new ContentInfo(); - - BackgroundInputTypeParser.SaveAttributes(contentInfo, SiteInfo, styleInfoList, formCollection, ContentAttribute.AllAttributesLowercase); - - contentInfo.ChannelId = _channelInfo.Id; - contentInfo.SiteId = SiteId; - contentInfo.AddUserName = AuthRequest.AdminName; - contentInfo.AddDate = DateTime.Now; - contentInfo.LastEditUserName = contentInfo.AddUserName; - contentInfo.LastEditDate = contentInfo.AddDate; - - contentInfo.CheckedLevel = TranslateUtils.ToIntWithNagetive(DdlContentLevel.SelectedValue); - contentInfo.IsChecked = contentInfo.CheckedLevel >= SiteInfo.Additional.CheckContentLevel; - - contentInfo.Title = formCollection[ContentAttribute.Title]; - - contentInfo.Id = DataProvider.ContentDao.Insert(tableName, SiteInfo, contentInfo); - - CreateManager.CreateContentAndTrigger(SiteId, _channelInfo.Id, contentInfo.Id); - } - } - } - } - - LayerUtils.Close(Page); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageChannel.cs b/SiteServer.BackgroundPages/Cms/PageChannel.cs deleted file mode 100644 index 21b80c752..000000000 --- a/SiteServer.BackgroundPages/Cms/PageChannel.cs +++ /dev/null @@ -1,147 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageChannel : BasePageCms - { - public Repeater RptContents; - - public PlaceHolder PhAddChannel; - public Button BtnAddChannel1; - public Button BtnAddChannel2; - public PlaceHolder PhChannelEdit; - public Button BtnAddToGroup; - public PlaceHolder PhTranslate; - public Button BtnTranslate; - public PlaceHolder PhImport; - public Button BtnImport; - public Button BtnExport; - public PlaceHolder PhDelete; - public Button BtnDelete; - public PlaceHolder PhCreate; - public Button BtnCreate; - - private int _currentChannelId; - - public static string GetRedirectUrl(int siteId, int currentChannelId) - { - if (currentChannelId > 0 && currentChannelId != siteId) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageChannel), new NameValueCollection - { - {"CurrentChannelId", currentChannelId.ToString()} - }); - } - return PageUtils.GetCmsUrl(siteId, nameof(PageChannel), null); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (AuthRequest.IsQueryExists("channelId") && (AuthRequest.IsQueryExists("Subtract") || AuthRequest.IsQueryExists("Add"))) - { - var channelId = AuthRequest.GetQueryInt("channelId"); - if (SiteId != channelId) - { - var isSubtract = AuthRequest.IsQueryExists("Subtract"); - DataProvider.ChannelDao.UpdateTaxis(SiteId, channelId, isSubtract); - - AuthRequest.AddSiteLog(SiteId, channelId, 0, "栏目排序" + (isSubtract ? "上升" : "下降"), - $"栏目:{ChannelManager.GetChannelName(SiteId, channelId)}"); - - PageUtils.Redirect(GetRedirectUrl(SiteId, channelId)); - return; - } - } - - if (IsPostBack) return; - - ClientScriptRegisterClientScriptBlock("NodeTreeScript", ChannelLoading.GetScript(SiteInfo, string.Empty, ELoadingType.Channel, null)); - - if (AuthRequest.IsQueryExists("CurrentChannelId")) - { - _currentChannelId = AuthRequest.GetQueryInt("CurrentChannelId"); - var onLoadScript = ChannelLoading.GetScriptOnLoad(SiteId, _currentChannelId); - if (!string.IsNullOrEmpty(onLoadScript)) - { - ClientScriptRegisterClientScriptBlock("NodeTreeScriptOnLoad", onLoadScript); - } - } - - PhAddChannel.Visible = HasChannelPermissionsIgnoreChannelId(ConfigManager.ChannelPermissions.ChannelAdd); - if (PhAddChannel.Visible) - { - BtnAddChannel1.Attributes.Add("onclick", ModalChannelsAdd.GetOpenWindowString(SiteId, SiteId, GetRedirectUrl(SiteId, SiteId))); - BtnAddChannel2.Attributes.Add("onclick", - $"location.href='{PageChannelAdd.GetRedirectUrl(SiteId, SiteId, GetRedirectUrl(SiteId, 0))}';return false;"); - } - - PhChannelEdit.Visible = HasChannelPermissionsIgnoreChannelId(ConfigManager.ChannelPermissions.ChannelEdit); - if (PhChannelEdit.Visible) - { - var showPopWinString = ModalAddToGroup.GetOpenWindowStringToChannel(SiteId); - BtnAddToGroup.Attributes.Add("onclick", showPopWinString); - } - - PhTranslate.Visible = HasChannelPermissionsIgnoreChannelId(ConfigManager.ChannelPermissions.ChannelTranslate); - if (PhTranslate.Visible) - { - BtnTranslate.Attributes.Add("onclick", - PageUtils.GetRedirectStringWithCheckBoxValue( - PageChannelTranslate.GetRedirectUrl(SiteId, - GetRedirectUrl(SiteId, _currentChannelId)), "ChannelIDCollection", - "ChannelIDCollection", "请选择需要转移的栏目!")); - } - - PhDelete.Visible = HasChannelPermissionsIgnoreChannelId(ConfigManager.ChannelPermissions.ChannelDelete); - if (PhDelete.Visible) - { - BtnDelete.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValue(PageChannelDelete.GetRedirectUrl(SiteId, GetRedirectUrl(SiteId, SiteId)), "ChannelIDCollection", "ChannelIDCollection", "请选择需要删除的栏目!")); - } - - PhCreate.Visible = HasSitePermissions(ConfigManager.WebSitePermissions.Create) || HasChannelPermissionsIgnoreChannelId(ConfigManager.ChannelPermissions.CreatePage); - if (PhCreate.Visible) - { - BtnCreate.Attributes.Add("onclick", ModalCreateChannels.GetOpenWindowString(SiteId)); - } - - PhImport.Visible = PhAddChannel.Visible; - if (PhImport.Visible) - { - BtnImport.Attributes.Add("onclick", ModalChannelImport.GetOpenWindowString(SiteId, SiteId)); - } - BtnExport.Attributes.Add("onclick", ModalExportMessage.GetOpenWindowStringToChannel(SiteId, "ChannelIDCollection", "请选择需要导出的栏目!")); - - var channelIdList = ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(SiteId, SiteId), EScopeType.SelfAndChildren, string.Empty, string.Empty, string.Empty); - - RptContents.DataSource = channelIdList; - RptContents.ItemDataBound += RptContents_ItemDataBound; - RptContents.DataBind(); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - var channelId = (int)e.Item.DataItem; - var enabled = IsOwningChannelId(channelId); - if (!enabled) - { - if (!IsDescendantOwningChannelId(channelId)) e.Item.Visible = false; - } - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - - var ltlHtml = (Literal)e.Item.FindControl("ltlHtml"); - - ltlHtml.Text = ChannelLoading.GetChannelRowHtml(SiteInfo, nodeInfo, enabled, ELoadingType.Channel, null, AuthRequest.AdminPermissions); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageChannelAdd.cs b/SiteServer.BackgroundPages/Cms/PageChannelAdd.cs deleted file mode 100644 index 882fae1e0..000000000 --- a/SiteServer.BackgroundPages/Cms/PageChannelAdd.cs +++ /dev/null @@ -1,320 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Create; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.Plugin; -using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageChannelAdd : BasePageCms - { - public DropDownList DdlParentChannelId; - public TextBox TbNodeName; - public TextBox TbNodeIndexName; - public DropDownList DdlContentModelPluginId; - public PlaceHolder PhContentRelatedPluginIds; - public CheckBoxList CblContentRelatedPluginIds; - public TextBox TbLinkUrl; - public CheckBoxList CblNodeGroupNameCollection; - public DropDownList DdlLinkType; - public DropDownList DdlTaxisType; - public DropDownList DdlChannelTemplateId; - public DropDownList DdlContentTemplateId; - public RadioButtonList RblIsChannelAddable; - public RadioButtonList RblIsContentAddable; - public TextBox TbImageUrl; - public TextBox TbFilePath; - public TextBox TbChannelFilePathRule; - public TextBox TbContentFilePathRule; - - public TextEditorControl TbContent; - public TextBox TbKeywords; - public TextBox TbDescription; - - public ChannelAuxiliaryControl CacAttributes; - - public Button BtnCreateChannelRule; - public Button BtnCreateContentRule; - public Button BtnSelectImage; - public Button BtnUploadImage; - - private int _channelId; - - public static string GetRedirectUrl(int siteId, int channelId, string returnUrl) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageChannelAdd), new NameValueCollection - { - {"channelId", channelId.ToString() }, - {"ReturnUrl", StringUtils.ValueToUrl(returnUrl) } - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "channelId", "ReturnUrl"); - _channelId = AuthRequest.GetQueryInt("channelId"); - ReturnUrl = StringUtils.ValueFromUrl(PageUtils.FilterSqlAndXss(AuthRequest.GetQueryString("ReturnUrl"))); - //if (!base.HasChannelPermissions(this.channelId, AppManager.CMS.Permission.Channel.ChannelAdd)) - //{ - // PageUtils.RedirectToErrorPage("您没有添加栏目的权限!"); - // return; - //} - - var parentNodeInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - if (parentNodeInfo.Additional.IsChannelAddable == false) - { - PageUtils.RedirectToErrorPage("此栏目不能添加子栏目!"); - return; - } - - CacAttributes.SiteInfo = SiteInfo; - CacAttributes.ChannelId = _channelId; - - if (!IsPostBack) - { - ChannelManager.AddListItems(DdlParentChannelId.Items, SiteInfo, true, true, AuthRequest.AdminPermissions); - ControlUtils.SelectSingleItem(DdlParentChannelId, _channelId.ToString()); - - DdlContentModelPluginId.Items.Add(new ListItem("<默认>", string.Empty)); - var contentTables = PluginContentManager.GetContentModelPlugins(); - foreach (var contentTable in contentTables) - { - DdlContentModelPluginId.Items.Add(new ListItem(contentTable.Title, contentTable.Id)); - } - ControlUtils.SelectSingleItem(DdlContentModelPluginId, parentNodeInfo.ContentModelPluginId); - - var plugins = PluginContentManager.GetAllContentRelatedPlugins(false); - if (plugins.Count > 0) - { - foreach (var pluginMetadata in plugins) - { - CblContentRelatedPluginIds.Items.Add(new ListItem(pluginMetadata.Title, pluginMetadata.Id)); - } - } - else - { - PhContentRelatedPluginIds.Visible = false; - } - - CacAttributes.Attributes = new ExtendedAttributes(); - - TbImageUrl.Attributes.Add("onchange", GetShowImageScript("preview_NavigationPicPath", SiteInfo.Additional.WebUrl)); - - var showPopWinString = ModalFilePathRule.GetOpenWindowString(SiteId, _channelId, true, TbChannelFilePathRule.ClientID); - BtnCreateChannelRule.Attributes.Add("onclick", showPopWinString); - - showPopWinString = ModalFilePathRule.GetOpenWindowString(SiteId, _channelId, false, TbContentFilePathRule.ClientID); - BtnCreateContentRule.Attributes.Add("onclick", showPopWinString); - - showPopWinString = ModalSelectImage.GetOpenWindowString(SiteInfo, TbImageUrl.ClientID); - BtnSelectImage.Attributes.Add("onclick", showPopWinString); - - showPopWinString = ModalUploadImage.GetOpenWindowString(SiteId, TbImageUrl.ClientID); - BtnUploadImage.Attributes.Add("onclick", showPopWinString); - - ELinkTypeUtils.AddListItems(DdlLinkType); - - ETaxisTypeUtils.AddListItemsForChannelEdit(DdlTaxisType); - ControlUtils.SelectSingleItem(DdlTaxisType, ETaxisTypeUtils.GetValue(ETaxisType.OrderByTaxisDesc)); - - CblNodeGroupNameCollection.DataSource = DataProvider.ChannelGroupDao.GetDataSource(SiteId); - DdlChannelTemplateId.DataSource = DataProvider.TemplateDao.GetDataSourceByType(SiteId, TemplateType.ChannelTemplate); - DdlContentTemplateId.DataSource = DataProvider.TemplateDao.GetDataSourceByType(SiteId, TemplateType.ContentTemplate); - - DataBind(); - - DdlChannelTemplateId.Items.Insert(0, new ListItem("<默认>", "0")); - DdlChannelTemplateId.Items[0].Selected = true; - - DdlContentTemplateId.Items.Insert(0, new ListItem("<默认>", "0")); - DdlContentTemplateId.Items[0].Selected = true; - TbContent.SetParameters(SiteInfo, ChannelAttribute.Content, string.Empty); - } - else - { - CacAttributes.Attributes = new ExtendedAttributes(Request.Form); - } - } - - public void DdlParentChannelId_SelectedIndexChanged(object sender, EventArgs e) - { - var theChannelId = TranslateUtils.ToInt(DdlParentChannelId.SelectedValue); - if (theChannelId == 0) - { - theChannelId = _channelId; - } - PageUtils.Redirect(GetRedirectUrl(SiteId, theChannelId, AuthRequest.GetQueryString("ReturnUrl"))); - } - - public string PreviewImageSrc - { - get - { - if (string.IsNullOrEmpty(TbImageUrl.Text)) return SiteServerAssets.GetIconUrl("empty.gif"); - - var extension = PathUtils.GetExtension(TbImageUrl.Text); - if (EFileSystemTypeUtils.IsImage(extension)) - { - return PageUtility.ParseNavigationUrl(SiteInfo, TbImageUrl.Text, true); - } - if (EFileSystemTypeUtils.IsFlash(extension)) - { - return SiteServerAssets.GetIconUrl("flash.jpg"); - } - if (EFileSystemTypeUtils.IsPlayer(extension)) - { - return SiteServerAssets.GetIconUrl("player.gif"); - } - return SiteServerAssets.GetIconUrl("empty.gif"); - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - int insertChannelId; - try - { - var channelId = AuthRequest.GetQueryInt("ChannelId"); - var nodeInfo = new ChannelInfo - { - ParentId = channelId, - ContentModelPluginId = DdlContentModelPluginId.SelectedValue, - ContentRelatedPluginIds = - ControlUtils.GetSelectedListControlValueCollection(CblContentRelatedPluginIds) - }; - - if (TbNodeIndexName.Text.Length != 0) - { - var nodeIndexNameArrayList = DataProvider.ChannelDao.GetIndexNameList(SiteId); - if (nodeIndexNameArrayList.IndexOf(TbNodeIndexName.Text) != -1) - { - FailMessage("栏目添加失败,栏目索引已存在!"); - return; - } - } - - if (TbFilePath.Text.Length != 0) - { - if (!DirectoryUtils.IsDirectoryNameCompliant(TbFilePath.Text)) - { - FailMessage("栏目页面路径不符合系统要求!"); - return; - } - - if (PathUtils.IsDirectoryPath(TbFilePath.Text)) - { - TbFilePath.Text = PageUtils.Combine(TbFilePath.Text, "index.html"); - } - - var filePathArrayList = DataProvider.ChannelDao.GetAllFilePathBySiteId(SiteId); - if (filePathArrayList.IndexOf(TbFilePath.Text) != -1) - { - FailMessage("栏目添加失败,栏目页面路径已存在!"); - return; - } - } - - if (!string.IsNullOrEmpty(TbChannelFilePathRule.Text)) - { - if (!DirectoryUtils.IsDirectoryNameCompliant(TbChannelFilePathRule.Text)) - { - FailMessage("栏目页面命名规则不符合系统要求!"); - return; - } - if (PathUtils.IsDirectoryPath(TbChannelFilePathRule.Text)) - { - FailMessage("栏目页面命名规则必须包含生成文件的后缀!"); - return; - } - } - - if (!string.IsNullOrEmpty(TbContentFilePathRule.Text)) - { - if (!DirectoryUtils.IsDirectoryNameCompliant(TbContentFilePathRule.Text)) - { - FailMessage("内容页面命名规则不符合系统要求!"); - return; - } - if (PathUtils.IsDirectoryPath(TbContentFilePathRule.Text)) - { - FailMessage("内容页面命名规则必须包含生成文件的后缀!"); - return; - } - } - - var extendedAttributes = new ExtendedAttributes(); - var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(SiteId, _channelId); - var styleInfoList = TableStyleManager.GetTableStyleInfoList(DataProvider.ChannelDao.TableName, relatedIdentities); - BackgroundInputTypeParser.SaveAttributes(extendedAttributes, SiteInfo, styleInfoList, Request.Form, null); - var attributes = extendedAttributes.ToNameValueCollection(); - nodeInfo.Additional.Load(attributes); - //foreach (string key in attributes) - //{ - // nodeInfo.Additional.SetExtendedAttribute(key, attributes[key]); - //} - - nodeInfo.ChannelName = TbNodeName.Text; - nodeInfo.IndexName = TbNodeIndexName.Text; - nodeInfo.FilePath = TbFilePath.Text; - nodeInfo.ChannelFilePathRule = TbChannelFilePathRule.Text; - nodeInfo.ContentFilePathRule = TbContentFilePathRule.Text; - - var list = new ArrayList(); - foreach (ListItem item in CblNodeGroupNameCollection.Items) - { - if (item.Selected) - { - list.Add(item.Value); - } - } - nodeInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(list); - nodeInfo.ImageUrl = TbImageUrl.Text; - nodeInfo.Content = ContentUtility.TextEditorContentEncode(SiteInfo, Request.Form[ChannelAttribute.Content]); - nodeInfo.Keywords = TbKeywords.Text; - nodeInfo.Description = TbDescription.Text; - nodeInfo.Additional.IsChannelAddable = TranslateUtils.ToBool(RblIsChannelAddable.SelectedValue); - nodeInfo.Additional.IsContentAddable = TranslateUtils.ToBool(RblIsContentAddable.SelectedValue); - - nodeInfo.LinkUrl = TbLinkUrl.Text; - nodeInfo.LinkType = DdlLinkType.SelectedValue; - - nodeInfo.Additional.DefaultTaxisType = ETaxisTypeUtils.GetValue(ETaxisTypeUtils.GetEnumType(DdlTaxisType.SelectedValue)); - - nodeInfo.ChannelTemplateId = DdlChannelTemplateId.Items.Count > 0 ? TranslateUtils.ToInt(DdlChannelTemplateId.SelectedValue) : 0; - nodeInfo.ContentTemplateId = DdlContentTemplateId.Items.Count > 0 ? TranslateUtils.ToInt(DdlContentTemplateId.SelectedValue) : 0; - - nodeInfo.AddDate = DateTime.Now; - insertChannelId = DataProvider.ChannelDao.Insert(nodeInfo); - //栏目选择投票样式后,内容 - } - catch (Exception ex) - { - LogUtils.AddErrorLog(ex); - FailMessage(ex, $"栏目添加失败:{ex.Message}"); - return; - } - - CreateManager.CreateChannel(SiteId, insertChannelId); - - AuthRequest.AddSiteLog(SiteId, "添加栏目", $"栏目:{TbNodeName.Text}"); - - SuccessMessage("栏目添加成功!"); - AddWaitAndRedirectScript(ReturnUrl); - } - - public string ReturnUrl { get; private set; } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageChannelDelete.cs b/SiteServer.BackgroundPages/Cms/PageChannelDelete.cs deleted file mode 100644 index 9a8938204..000000000 --- a/SiteServer.BackgroundPages/Cms/PageChannelDelete.cs +++ /dev/null @@ -1,158 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Text; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using System.Collections.Generic; -using SiteServer.CMS.Core.Create; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageChannelDelete : BasePageCms - { - public Literal LtlPageTitle; - public RadioButtonList RblRetainFiles; - public Button BtnDelete; - - private bool _deleteContents; - private readonly List _nodeNameList = new List(); - - public string ReturnUrl { get; private set; } - - public static string GetRedirectUrl(int siteId, string returnUrl) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageChannelDelete), new NameValueCollection - { - {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "ReturnUrl"); - ReturnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); - _deleteContents = AuthRequest.GetQueryBool("DeleteContents"); - - if (IsPostBack) return; - - var channelIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("ChannelIDCollection")); - channelIdList.Sort(); - channelIdList.Reverse(); - foreach (var channelId in channelIdList) - { - if (channelId == SiteId) continue; - if (!HasChannelPermissions(channelId, ConfigManager.ChannelPermissions.ChannelDelete)) continue; - - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - var displayName = nodeInfo.ChannelName; - if (nodeInfo.ContentNum > 0) - { - displayName += $"({nodeInfo.ContentNum})"; - } - _nodeNameList.Add(displayName); - } - - if (_nodeNameList.Count == 0) - { - BtnDelete.Enabled = false; - } - else - { - if (_deleteContents) - { - LtlPageTitle.Text = "删除内容"; - InfoMessage( - $"此操作将会删除栏目“{TranslateUtils.ObjectCollectionToString(_nodeNameList)}”下的所有内容,确认吗?"); - } - else - { - LtlPageTitle.Text = "删除栏目"; - InfoMessage( - $"此操作将会删除栏目“{TranslateUtils.ObjectCollectionToString(_nodeNameList)}”及包含的下级栏目,确认吗?"); - } - } - } - - public void Delete_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - try - { - var channelIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("ChannelIDCollection")); - channelIdList.Sort(); - channelIdList.Reverse(); - - var channelIdListToDelete = new List(); - foreach (var channelId in channelIdList) - { - if (channelId == SiteId) continue; - if (HasChannelPermissions(channelId, ConfigManager.ChannelPermissions.ChannelDelete)) - { - channelIdListToDelete.Add(channelId); - } - } - - var builder = new StringBuilder(); - foreach (var channelId in channelIdListToDelete) - { - builder.Append(ChannelManager.GetChannelName(SiteId, channelId)).Append(","); - } - - if (builder.Length > 0) - { - builder.Length -= 1; - } - - if (_deleteContents) - { - SuccessMessage(bool.Parse(RblRetainFiles.SelectedValue) == false - ? "成功删除内容以及生成页面!" - : "成功删除内容,生成页面未被删除!"); - - foreach (var channelId in channelIdListToDelete) - { - var tableName = ChannelManager.GetTableName(SiteInfo, channelId); - var contentIdList = DataProvider.ContentDao.GetContentIdList(tableName, channelId); - DeleteManager.DeleteContents(SiteInfo, channelId, contentIdList); - DataProvider.ContentDao.TrashContents(SiteId, tableName, contentIdList); - } - - AuthRequest.AddSiteLog(SiteId, "清空栏目下的内容", $"栏目:{builder}"); - } - else - { - if (bool.Parse(RblRetainFiles.SelectedValue) == false) - { - DeleteManager.DeleteChannels(SiteInfo, channelIdListToDelete); - SuccessMessage("成功删除栏目以及相关生成页面!"); - } - else - { - SuccessMessage("成功删除栏目,相关生成页面未被删除!"); - } - - foreach (var channelId in channelIdListToDelete) - { - var tableName = ChannelManager.GetTableName(SiteInfo, channelId); - DataProvider.ContentDao.TrashContentsByChannelId(SiteId, tableName, channelId); - DataProvider.ChannelDao.Delete(SiteId, channelId); - } - - AuthRequest.AddSiteLog(SiteId, "删除栏目", $"栏目:{builder}"); - } - - AddWaitAndRedirectScript(ReturnUrl); - } - catch (Exception ex) - { - FailMessage(ex, _deleteContents ? "删除内容失败!" : "删除栏目失败!"); - - LogUtils.AddErrorLog(ex); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageChannelEdit.cs b/SiteServer.BackgroundPages/Cms/PageChannelEdit.cs deleted file mode 100644 index 54a8a0f0b..000000000 --- a/SiteServer.BackgroundPages/Cms/PageChannelEdit.cs +++ /dev/null @@ -1,317 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Create; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.Plugin; -using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageChannelEdit : BasePageCms - { - public TextBox TbNodeName; - public TextBox TbNodeIndexName; - public DropDownList DdlContentModelPluginId; - public PlaceHolder PhContentRelatedPluginIds; - public CheckBoxList CblContentRelatedPluginIds; - public CheckBoxList CblNodeGroupNameCollection; - public RadioButtonList RblIsChannelAddable; - public RadioButtonList RblIsContentAddable; - public TextBox TbLinkUrl; - public DropDownList DdlLinkType; - public DropDownList DdlTaxisType; - public DropDownList DdlChannelTemplateId; - public DropDownList DdlContentTemplateId; - public TextBox TbImageUrl; - public TextBox TbFilePath; - public TextBox TbChannelFilePathRule; - public TextBox TbContentFilePathRule; - public TextEditorControl TbContent; - public TextBox TbKeywords; - public TextBox TbDescription; - public ChannelAuxiliaryControl CacAttributes; - public Button BtnCreateChannelRule; - public Button BtnCreateContentRule; - public Button BtnSelectImage; - public Button BtnUploadImage; - public Button BtnSubmit; - - private int _channelId; - - public static string GetRedirectUrl(int siteId, int channelId, string returnUrl) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageChannelEdit), new NameValueCollection - { - {"channelId", channelId.ToString()}, - {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "channelId", "ReturnUrl"); - - _channelId = AuthRequest.GetQueryInt("channelId"); - ReturnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); - - if (AuthRequest.GetQueryString("CanNotEdit") == null && AuthRequest.GetQueryString("UncheckedChannel") == null) - { - if (!HasChannelPermissions(_channelId, ConfigManager.ChannelPermissions.ChannelEdit)) - { - PageUtils.RedirectToErrorPage("您没有修改栏目的权限!"); - return; - } - } - if (AuthRequest.IsQueryExists("CanNotEdit")) - { - BtnSubmit.Visible = false; - } - - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - if (nodeInfo == null) return; - - CacAttributes.SiteInfo = SiteInfo; - CacAttributes.ChannelId = _channelId; - - if (!IsPostBack) - { - DdlContentModelPluginId.Items.Add(new ListItem("<默认>", string.Empty)); - var contentTables = PluginContentManager.GetContentModelPlugins(); - foreach (var contentTable in contentTables) - { - DdlContentModelPluginId.Items.Add(new ListItem(contentTable.Title, contentTable.Id)); - } - ControlUtils.SelectSingleItem(DdlContentModelPluginId, nodeInfo.ContentModelPluginId); - - var plugins = PluginContentManager.GetAllContentRelatedPlugins(false); - if (plugins.Count > 0) - { - var relatedPluginIds = - TranslateUtils.StringCollectionToStringList(nodeInfo.ContentRelatedPluginIds); - foreach (var pluginMetadata in plugins) - { - CblContentRelatedPluginIds.Items.Add(new ListItem(pluginMetadata.Title, pluginMetadata.Id) - { - Selected = relatedPluginIds.Contains(pluginMetadata.Id) - }); - } - } - else - { - PhContentRelatedPluginIds.Visible = false; - } - - CacAttributes.Attributes = nodeInfo.Additional; - - TbImageUrl.Attributes.Add("onchange", GetShowImageScript("preview_NavigationPicPath", SiteInfo.Additional.WebUrl)); - - var showPopWinString = ModalFilePathRule.GetOpenWindowString(SiteId, _channelId, true, TbChannelFilePathRule.ClientID); - BtnCreateChannelRule.Attributes.Add("onclick", showPopWinString); - - showPopWinString = ModalFilePathRule.GetOpenWindowString(SiteId, _channelId, false, TbContentFilePathRule.ClientID); - BtnCreateContentRule.Attributes.Add("onclick", showPopWinString); - - showPopWinString = ModalSelectImage.GetOpenWindowString(SiteInfo, TbImageUrl.ClientID); - BtnSelectImage.Attributes.Add("onclick", showPopWinString); - - showPopWinString = ModalUploadImage.GetOpenWindowString(SiteId, TbImageUrl.ClientID); - BtnUploadImage.Attributes.Add("onclick", showPopWinString); - - ELinkTypeUtils.AddListItems(DdlLinkType); - ETaxisTypeUtils.AddListItemsForChannelEdit(DdlTaxisType); - - CblNodeGroupNameCollection.DataSource = DataProvider.ChannelGroupDao.GetDataSource(SiteId); - - DdlChannelTemplateId.DataSource = DataProvider.TemplateDao.GetDataSourceByType(SiteId, TemplateType.ChannelTemplate); - - DdlContentTemplateId.DataSource = DataProvider.TemplateDao.GetDataSourceByType(SiteId, TemplateType.ContentTemplate); - - DataBind(); - - DdlChannelTemplateId.Items.Insert(0, new ListItem("<未设置>", "0")); - ControlUtils.SelectSingleItem(DdlChannelTemplateId, nodeInfo.ChannelTemplateId.ToString()); - - DdlContentTemplateId.Items.Insert(0, new ListItem("<未设置>", "0")); - ControlUtils.SelectSingleItem(DdlContentTemplateId, nodeInfo.ContentTemplateId.ToString()); - - TbNodeName.Text = nodeInfo.ChannelName; - TbNodeIndexName.Text = nodeInfo.IndexName; - TbLinkUrl.Text = nodeInfo.LinkUrl; - - foreach (ListItem item in CblNodeGroupNameCollection.Items) - { - item.Selected = StringUtils.In(nodeInfo.GroupNameCollection, item.Value); - } - TbFilePath.Text = nodeInfo.FilePath; - TbChannelFilePathRule.Text = nodeInfo.ChannelFilePathRule; - TbContentFilePathRule.Text = nodeInfo.ContentFilePathRule; - - ControlUtils.SelectSingleItem(DdlLinkType, nodeInfo.LinkType); - ControlUtils.SelectSingleItem(DdlTaxisType, nodeInfo.Additional.DefaultTaxisType); - ControlUtils.SelectSingleItem(RblIsChannelAddable, nodeInfo.Additional.IsChannelAddable.ToString()); - ControlUtils.SelectSingleItem(RblIsContentAddable, nodeInfo.Additional.IsContentAddable.ToString()); - - TbImageUrl.Text = nodeInfo.ImageUrl; - - TbContent.SetParameters(SiteInfo, ChannelAttribute.Content, nodeInfo.Content); - - TbKeywords.Text = nodeInfo.Keywords; - TbDescription.Text = nodeInfo.Description; - - //this.Content.SiteId = base.SiteId; - //this.Content.Text = StringUtility.TextEditorContentDecode(nodeInfo.Content, ConfigUtils.Instance.ApplicationPath, base.SiteInfo.SiteUrl); - } - else - { - CacAttributes.Attributes = new ExtendedAttributes(Request.Form); - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - ChannelInfo nodeInfo; - try - { - nodeInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - if (!nodeInfo.IndexName.Equals(TbNodeIndexName.Text) && TbNodeIndexName.Text.Length != 0) - { - var nodeIndexNameList = DataProvider.ChannelDao.GetIndexNameList(SiteId); - if (nodeIndexNameList.IndexOf(TbNodeIndexName.Text) != -1) - { - FailMessage("栏目属性修改失败,栏目索引已存在!"); - return; - } - } - - if (nodeInfo.ContentModelPluginId != DdlContentModelPluginId.SelectedValue) - { - nodeInfo.ContentModelPluginId = DdlContentModelPluginId.SelectedValue; - nodeInfo.ContentNum = DataProvider.ContentDao.GetCount(ChannelManager.GetTableName(SiteInfo, nodeInfo.ContentModelPluginId), nodeInfo.Id); - } - - nodeInfo.ContentRelatedPluginIds = ControlUtils.GetSelectedListControlValueCollection(CblContentRelatedPluginIds); - - TbFilePath.Text = TbFilePath.Text.Trim(); - if (!nodeInfo.FilePath.Equals(TbFilePath.Text) && TbFilePath.Text.Length != 0) - { - if (!DirectoryUtils.IsDirectoryNameCompliant(TbFilePath.Text)) - { - FailMessage("栏目页面路径不符合系统要求!"); - return; - } - - if (PathUtils.IsDirectoryPath(TbFilePath.Text)) - { - TbFilePath.Text = PageUtils.Combine(TbFilePath.Text, "index.html"); - } - - var filePathArrayList = DataProvider.ChannelDao.GetAllFilePathBySiteId(SiteId); - if (filePathArrayList.IndexOf(TbFilePath.Text) != -1) - { - FailMessage("栏目修改失败,栏目页面路径已存在!"); - return; - } - } - - if (!string.IsNullOrEmpty(TbChannelFilePathRule.Text)) - { - var filePathRule = TbChannelFilePathRule.Text.Replace("|", string.Empty); - if (!DirectoryUtils.IsDirectoryNameCompliant(filePathRule)) - { - FailMessage("栏目页面命名规则不符合系统要求!"); - return; - } - if (PathUtils.IsDirectoryPath(filePathRule)) - { - FailMessage("栏目页面命名规则必须包含生成文件的后缀!"); - return; - } - } - - if (!string.IsNullOrEmpty(TbContentFilePathRule.Text)) - { - var filePathRule = TbContentFilePathRule.Text.Replace("|", string.Empty); - if (!DirectoryUtils.IsDirectoryNameCompliant(filePathRule)) - { - FailMessage("内容页面命名规则不符合系统要求!"); - return; - } - if (PathUtils.IsDirectoryPath(filePathRule)) - { - FailMessage("内容页面命名规则必须包含生成文件的后缀!"); - return; - } - } - - var extendedAttributes = new ExtendedAttributes(); - var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(SiteId, _channelId); - var styleInfoList = TableStyleManager.GetTableStyleInfoList(DataProvider.ChannelDao.TableName, relatedIdentities); - BackgroundInputTypeParser.SaveAttributes(extendedAttributes, SiteInfo, styleInfoList, Request.Form, null); - var attributes = extendedAttributes.ToNameValueCollection(); - foreach (string key in attributes) - { - nodeInfo.Additional.Set(key, attributes[key]); - } - - nodeInfo.ChannelName = TbNodeName.Text; - nodeInfo.IndexName = TbNodeIndexName.Text; - nodeInfo.FilePath = TbFilePath.Text; - nodeInfo.ChannelFilePathRule = TbChannelFilePathRule.Text; - nodeInfo.ContentFilePathRule = TbContentFilePathRule.Text; - - var list = new ArrayList(); - foreach (ListItem item in CblNodeGroupNameCollection.Items) - { - if (item.Selected) - { - list.Add(item.Value); - } - } - nodeInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(list); - nodeInfo.ImageUrl = TbImageUrl.Text; - nodeInfo.Content = ContentUtility.TextEditorContentEncode(SiteInfo, Request.Form[ChannelAttribute.Content]); - - nodeInfo.Keywords = TbKeywords.Text; - nodeInfo.Description = TbDescription.Text; - - nodeInfo.Additional.IsChannelAddable = TranslateUtils.ToBool(RblIsChannelAddable.SelectedValue); - nodeInfo.Additional.IsContentAddable = TranslateUtils.ToBool(RblIsContentAddable.SelectedValue); - - nodeInfo.LinkUrl = TbLinkUrl.Text; - nodeInfo.LinkType = DdlLinkType.SelectedValue; - nodeInfo.Additional.DefaultTaxisType = ETaxisTypeUtils.GetValue(ETaxisTypeUtils.GetEnumType(DdlTaxisType.SelectedValue)); - nodeInfo.ChannelTemplateId = DdlChannelTemplateId.Items.Count > 0 ? TranslateUtils.ToInt(DdlChannelTemplateId.SelectedValue) : 0; - nodeInfo.ContentTemplateId = DdlContentTemplateId.Items.Count > 0 ? TranslateUtils.ToInt(DdlContentTemplateId.SelectedValue) : 0; - - DataProvider.ChannelDao.Update(nodeInfo); - } - catch (Exception ex) - { - FailMessage(ex, $"栏目修改失败:{ex.Message}"); - LogUtils.AddErrorLog(ex); - return; - } - - CreateManager.CreateChannel(SiteId, nodeInfo.Id); - - AuthRequest.AddSiteLog(SiteId, "修改栏目", $"栏目:{TbNodeName.Text}"); - - SuccessMessage("栏目修改成功!"); - PageUtils.Redirect(ReturnUrl); - } - - public string ReturnUrl { get; private set; } - } -} \ No newline at end of file diff --git a/SiteServer.BackgroundPages/Cms/PageConfigurationContent.cs b/SiteServer.BackgroundPages/Cms/PageConfigurationContent.cs deleted file mode 100644 index eb840e063..000000000 --- a/SiteServer.BackgroundPages/Cms/PageConfigurationContent.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageConfigurationContent : BasePageCms - { - public DropDownList DdlIsSaveImageInTextEditor; - public DropDownList DdlIsAutoPageInTextEditor; - public PlaceHolder PhAutoPage; - public TextBox TbAutoPageWordNum; - public DropDownList DdlIsContentTitleBreakLine; - public DropDownList DdlIsCheckContentUseLevel; - public PlaceHolder PhCheckContentLevel; - public DropDownList DdlCheckContentLevel; - public DropDownList DdlIsAutoCheckKeywords; - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageConfigurationContent), null); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); - - EBooleanUtils.AddListItems(DdlIsSaveImageInTextEditor, "保存", "不保存"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsSaveImageInTextEditor, SiteInfo.Additional.IsSaveImageInTextEditor.ToString()); - - EBooleanUtils.AddListItems(DdlIsAutoPageInTextEditor, "自动分页", "手动分页"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsAutoPageInTextEditor, SiteInfo.Additional.IsAutoPageInTextEditor.ToString()); - - PhAutoPage.Visible = SiteInfo.Additional.IsAutoPageInTextEditor; - TbAutoPageWordNum.Text = SiteInfo.Additional.AutoPageWordNum.ToString(); - - EBooleanUtils.AddListItems(DdlIsContentTitleBreakLine, "启用标题换行", "不启用"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsContentTitleBreakLine, SiteInfo.Additional.IsContentTitleBreakLine.ToString()); - - //保存时,敏感词自动检测 - EBooleanUtils.AddListItems(DdlIsAutoCheckKeywords, "启用敏感词自动检测", "不启用"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsAutoCheckKeywords, SiteInfo.Additional.IsAutoCheckKeywords.ToString()); - - DdlIsCheckContentUseLevel.Items.Add(new ListItem("默认审核机制", false.ToString())); - DdlIsCheckContentUseLevel.Items.Add(new ListItem("多级审核机制", true.ToString())); - - ControlUtils.SelectSingleItem(DdlIsCheckContentUseLevel, SiteInfo.Additional.IsCheckContentLevel.ToString()); - if (SiteInfo.Additional.IsCheckContentLevel) - { - ControlUtils.SelectSingleItem(DdlCheckContentLevel, SiteInfo.Additional.CheckContentLevel.ToString()); - PhCheckContentLevel.Visible = true; - } - else - { - PhCheckContentLevel.Visible = false; - } - } - - public void DdlIsAutoPageInTextEditor_OnSelectedIndexChanged(object sender, EventArgs e) - { - PhAutoPage.Visible = EBooleanUtils.Equals(DdlIsAutoPageInTextEditor.SelectedValue, EBoolean.True); - } - - public void DdlIsCheckContentUseLevel_OnSelectedIndexChanged(object sender, EventArgs e) - { - PhCheckContentLevel.Visible = EBooleanUtils.Equals(DdlIsCheckContentUseLevel.SelectedValue, EBoolean.True); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - SiteInfo.Additional.IsSaveImageInTextEditor = TranslateUtils.ToBool(DdlIsSaveImageInTextEditor.SelectedValue, true); - - var isReCaculate = false; - if (TranslateUtils.ToBool(DdlIsAutoPageInTextEditor.SelectedValue, false)) - { - if (SiteInfo.Additional.IsAutoPageInTextEditor == false) - { - isReCaculate = true; - } - else if (SiteInfo.Additional.AutoPageWordNum != TranslateUtils.ToInt(TbAutoPageWordNum.Text, SiteInfo.Additional.AutoPageWordNum)) - { - isReCaculate = true; - } - } - - SiteInfo.Additional.IsAutoPageInTextEditor = TranslateUtils.ToBool(DdlIsAutoPageInTextEditor.SelectedValue, false); - - SiteInfo.Additional.AutoPageWordNum = TranslateUtils.ToInt(TbAutoPageWordNum.Text, SiteInfo.Additional.AutoPageWordNum); - - SiteInfo.Additional.IsContentTitleBreakLine = TranslateUtils.ToBool(DdlIsContentTitleBreakLine.SelectedValue, true); - - SiteInfo.Additional.IsAutoCheckKeywords = TranslateUtils.ToBool(DdlIsAutoCheckKeywords.SelectedValue, true); - - SiteInfo.Additional.IsCheckContentLevel = TranslateUtils.ToBool(DdlIsCheckContentUseLevel.SelectedValue); - if (SiteInfo.Additional.IsCheckContentLevel) - { - SiteInfo.Additional.CheckContentLevel = TranslateUtils.ToInt(DdlCheckContentLevel.SelectedValue); - } - - DataProvider.SiteDao.Update(SiteInfo); - if (isReCaculate) - { - DataProvider.ContentDao.UpdateAutoPageContent(SiteInfo.TableName, SiteInfo); - } - - AuthRequest.AddSiteLog(SiteId, "修改内容设置"); - - SuccessMessage("内容设置修改成功!"); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageConfigurationCreate.cs b/SiteServer.BackgroundPages/Cms/PageConfigurationCreate.cs deleted file mode 100644 index 8e47a46ea..000000000 --- a/SiteServer.BackgroundPages/Cms/PageConfigurationCreate.cs +++ /dev/null @@ -1,109 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageConfigurationCreate : BasePageCms - { - public DropDownList DdlIsCreateContentIfContentChanged; - public DropDownList DdlIsCreateChannelIfChannelChanged; - public DropDownList DdlIsCreateShowPageInfo; - public DropDownList DdlIsCreateIe8Compatible; - public DropDownList DdlIsCreateBrowserNoCache; - public DropDownList DdlIsCreateJsIgnoreError; - public DropDownList DdlIsCreateSearchDuplicate; - public DropDownList DdlIsCreateWithJQuery; - public DropDownList DdlIsCreateDoubleClick; - public TextBox TbCreateStaticMaxPage; - public DropDownList DdlIsCreateStaticContentByAddDate; - public PlaceHolder PhIsCreateStaticContentByAddDate; - public DateTimeTextBox TbCreateStaticContentAddDate; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Create); - - EBooleanUtils.AddListItems(DdlIsCreateContentIfContentChanged, "生成", "不生成"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsCreateContentIfContentChanged, SiteInfo.Additional.IsCreateContentIfContentChanged.ToString()); - - EBooleanUtils.AddListItems(DdlIsCreateChannelIfChannelChanged, "生成", "不生成"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsCreateChannelIfChannelChanged, SiteInfo.Additional.IsCreateChannelIfChannelChanged.ToString()); - - EBooleanUtils.AddListItems(DdlIsCreateShowPageInfo, "显示", "不显示"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsCreateShowPageInfo, SiteInfo.Additional.IsCreateShowPageInfo.ToString()); - - EBooleanUtils.AddListItems(DdlIsCreateIe8Compatible, "强制兼容", "不设置"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsCreateIe8Compatible, SiteInfo.Additional.IsCreateIe8Compatible.ToString()); - - EBooleanUtils.AddListItems(DdlIsCreateBrowserNoCache, "强制清除缓存", "不设置"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsCreateBrowserNoCache, SiteInfo.Additional.IsCreateBrowserNoCache.ToString()); - - EBooleanUtils.AddListItems(DdlIsCreateJsIgnoreError, "包含JS容错代码", "不设置"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsCreateJsIgnoreError, SiteInfo.Additional.IsCreateJsIgnoreError.ToString()); - - EBooleanUtils.AddListItems(DdlIsCreateSearchDuplicate, "包含", "不包含"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsCreateSearchDuplicate, SiteInfo.Additional.IsCreateSearchDuplicate.ToString()); - - EBooleanUtils.AddListItems(DdlIsCreateWithJQuery, "是", "否"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsCreateWithJQuery, SiteInfo.Additional.IsCreateWithJQuery.ToString()); - - EBooleanUtils.AddListItems(DdlIsCreateDoubleClick, "启用双击生成", "不启用"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsCreateDoubleClick, SiteInfo.Additional.IsCreateDoubleClick.ToString()); - - TbCreateStaticMaxPage.Text = SiteInfo.Additional.CreateStaticMaxPage.ToString(); - - EBooleanUtils.AddListItems(DdlIsCreateStaticContentByAddDate, "启用", "不启用"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsCreateStaticContentByAddDate, SiteInfo.Additional.IsCreateStaticContentByAddDate.ToString()); - PhIsCreateStaticContentByAddDate.Visible = SiteInfo.Additional.IsCreateStaticContentByAddDate; - if (SiteInfo.Additional.CreateStaticContentAddDate != DateTime.MinValue) - { - TbCreateStaticContentAddDate.DateTime = SiteInfo.Additional.CreateStaticContentAddDate; - } - } - - public void DdlIsCreateStaticContentByAddDate_SelectedIndexChanged(object sender, EventArgs e) - { - PhIsCreateStaticContentByAddDate.Visible = TranslateUtils.ToBool(DdlIsCreateStaticContentByAddDate.SelectedValue); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - SiteInfo.Additional.IsCreateContentIfContentChanged = TranslateUtils.ToBool(DdlIsCreateContentIfContentChanged.SelectedValue); - SiteInfo.Additional.IsCreateChannelIfChannelChanged = TranslateUtils.ToBool(DdlIsCreateChannelIfChannelChanged.SelectedValue); - - SiteInfo.Additional.IsCreateShowPageInfo = TranslateUtils.ToBool(DdlIsCreateShowPageInfo.SelectedValue); - SiteInfo.Additional.IsCreateIe8Compatible = TranslateUtils.ToBool(DdlIsCreateIe8Compatible.SelectedValue); - SiteInfo.Additional.IsCreateBrowserNoCache = TranslateUtils.ToBool(DdlIsCreateBrowserNoCache.SelectedValue); - SiteInfo.Additional.IsCreateJsIgnoreError = TranslateUtils.ToBool(DdlIsCreateJsIgnoreError.SelectedValue); - SiteInfo.Additional.IsCreateSearchDuplicate = TranslateUtils.ToBool(DdlIsCreateSearchDuplicate.SelectedValue); - SiteInfo.Additional.IsCreateWithJQuery = TranslateUtils.ToBool(DdlIsCreateWithJQuery.SelectedValue); - - SiteInfo.Additional.IsCreateDoubleClick = TranslateUtils.ToBool(DdlIsCreateDoubleClick.SelectedValue); - SiteInfo.Additional.CreateStaticMaxPage = TranslateUtils.ToInt(TbCreateStaticMaxPage.Text); - - SiteInfo.Additional.IsCreateStaticContentByAddDate = TranslateUtils.ToBool(DdlIsCreateStaticContentByAddDate.SelectedValue); - if (SiteInfo.Additional.IsCreateStaticContentByAddDate) - { - SiteInfo.Additional.CreateStaticContentAddDate = TbCreateStaticContentAddDate.DateTime; - } - - DataProvider.SiteDao.Update(SiteInfo); - - AuthRequest.AddSiteLog(SiteId, "修改页面生成设置"); - - SuccessMessage("页面生成设置修改成功!"); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageConfigurationCrossSiteTrans.cs b/SiteServer.BackgroundPages/Cms/PageConfigurationCrossSiteTrans.cs deleted file mode 100644 index b582b9dee..000000000 --- a/SiteServer.BackgroundPages/Cms/PageConfigurationCrossSiteTrans.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageConfigurationCrossSiteTrans : BasePageCms - { - public RadioButtonList RblIsCrossSiteTransChecked; - - private int _currentChannelId; - - public static string GetRedirectUrl(int siteId, int currentChannelId) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageConfigurationCrossSiteTrans), new NameValueCollection - { - {"CurrentChannelId", currentChannelId.ToString()} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); - - ClientScriptRegisterClientScriptBlock("NodeTreeScript", ChannelLoading.GetScript(SiteInfo, string.Empty, ELoadingType.ConfigurationCrossSiteTrans, null)); - - if (AuthRequest.IsQueryExists("CurrentChannelId")) - { - _currentChannelId = AuthRequest.GetQueryInt("CurrentChannelId"); - var onLoadScript = ChannelLoading.GetScriptOnLoad(SiteId, _currentChannelId); - if (!string.IsNullOrEmpty(onLoadScript)) - { - ClientScriptRegisterClientScriptBlock("NodeTreeScriptOnLoad", onLoadScript); - } - } - - EBooleanUtils.AddListItems(RblIsCrossSiteTransChecked, "无需审核", "需要审核"); - ControlUtils.SelectSingleItem(RblIsCrossSiteTransChecked, SiteInfo.Additional.IsCrossSiteTransChecked.ToString()); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - SiteInfo.Additional.IsCrossSiteTransChecked = TranslateUtils.ToBool(RblIsCrossSiteTransChecked.SelectedValue); - - try - { - DataProvider.SiteDao.Update(SiteInfo); - - AuthRequest.AddSiteLog(SiteId, "修改默认跨站转发设置"); - - SuccessMessage("默认跨站转发设置修改成功!"); - } - catch(Exception ex) - { - FailMessage(ex, "默认跨站转发设置修改失败!"); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageConfigurationSite.cs b/SiteServer.BackgroundPages/Cms/PageConfigurationSite.cs deleted file mode 100644 index 5bacda812..000000000 --- a/SiteServer.BackgroundPages/Cms/PageConfigurationSite.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageConfigurationSite : BasePageCms - { - public DropDownList DdlCharset; - public TextBox TbPageSize; - public DropDownList DdlIsCreateDoubleClick; - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageConfigurationSite), null); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); - - ECharsetUtils.AddListItems(DdlCharset); - ControlUtils.SelectSingleItem(DdlCharset, SiteInfo.Additional.Charset); - - TbPageSize.Text = SiteInfo.Additional.PageSize.ToString(); - - EBooleanUtils.AddListItems(DdlIsCreateDoubleClick, "启用双击生成", "不启用"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsCreateDoubleClick, SiteInfo.Additional.IsCreateDoubleClick.ToString()); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - if (SiteInfo.Additional.Charset != DdlCharset.SelectedValue) - { - SiteInfo.Additional.Charset = DdlCharset.SelectedValue; - } - - SiteInfo.Additional.PageSize = TranslateUtils.ToInt(TbPageSize.Text, SiteInfo.Additional.PageSize); - SiteInfo.Additional.IsCreateDoubleClick = TranslateUtils.ToBool(DdlIsCreateDoubleClick.SelectedValue); - - //修改所有模板编码 - var templateInfoList = DataProvider.TemplateDao.GetTemplateInfoListBySiteId(SiteId); - var charset = ECharsetUtils.GetEnumType(SiteInfo.Additional.Charset); - foreach (var templateInfo in templateInfoList) - { - if (templateInfo.Charset == charset) continue; - - var templateContent = TemplateManager.GetTemplateContent(SiteInfo, templateInfo); - templateInfo.Charset = charset; - DataProvider.TemplateDao.Update(SiteInfo, templateInfo, templateContent, AuthRequest.AdminName); - } - - DataProvider.SiteDao.Update(SiteInfo); - - AuthRequest.AddSiteLog(SiteId, "修改站点设置"); - - SuccessMessage("站点设置修改成功!"); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageConfigurationSiteAttributes.cs b/SiteServer.BackgroundPages/Cms/PageConfigurationSiteAttributes.cs deleted file mode 100644 index 0b989681e..000000000 --- a/SiteServer.BackgroundPages/Cms/PageConfigurationSiteAttributes.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Text; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Model; -using SiteServer.Plugin; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageConfigurationSiteAttributes : BasePageCms - { - public TextBox TbSiteName; - public Literal LtlAttributes; - public Button BtnSubmit; - - private List _styleInfoList; - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageConfigurationSiteAttributes), null); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - var relatedIdentities = RelatedIdentities.GetRelatedIdentities(SiteId, SiteId); - _styleInfoList = TableStyleManager.GetTableStyleInfoList(DataProvider.SiteDao.TableName, relatedIdentities); - - if (!IsPostBack) - { - VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); - - TbSiteName.Text = SiteInfo.SiteName; - - LtlAttributes.Text = GetAttributesHtml(SiteInfo.Additional.ToNameValueCollection()); - - BtnSubmit.Attributes.Add("onclick", InputParserUtils.GetValidateSubmitOnClickScript("myForm")); - } - else - { - LtlAttributes.Text = GetAttributesHtml(Request.Form); - } - } - - private string GetAttributesHtml(NameValueCollection formCollection) - { - if (formCollection == null) - { - formCollection = Request.Form.Count > 0 ? Request.Form : new NameValueCollection(); - } - - var pageScripts = new NameValueCollection(); - - if (_styleInfoList == null) return string.Empty; - - var attributes = new ExtendedAttributes(formCollection); - - var builder = new StringBuilder(); - foreach (var styleInfo in _styleInfoList) - { - string extra; - var value = BackgroundInputTypeParser.Parse(SiteInfo, 0, styleInfo, attributes, pageScripts, out extra); - if (string.IsNullOrEmpty(value) && string.IsNullOrEmpty(extra)) continue; - - if (InputTypeUtils.Equals(styleInfo.InputType, InputType.TextEditor)) - { - var commands = WebUtils.GetTextEditorCommands(SiteInfo, styleInfo.AttributeName); - builder.Append($@" -
- - {commands} -
- {value} - {extra} -
"); - } - else - { - builder.Append($@" -
- - {value} - {extra} -
"); - } - } - - foreach (string key in pageScripts.Keys) - { - builder.Append(pageScripts[key]); - } - - return builder.ToString(); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - SiteInfo.SiteName = TbSiteName.Text; - - BackgroundInputTypeParser.SaveAttributes(SiteInfo.Additional, SiteInfo, _styleInfoList, Page.Request.Form, null); - - DataProvider.SiteDao.Update(SiteInfo); - - AuthRequest.AddSiteLog(SiteId, "修改站点设置"); - - SuccessMessage("站点设置修改成功!"); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageConfigurationUploadFile.cs b/SiteServer.BackgroundPages/Cms/PageConfigurationUploadFile.cs deleted file mode 100644 index f353121fe..000000000 --- a/SiteServer.BackgroundPages/Cms/PageConfigurationUploadFile.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageConfigurationUploadFile : BasePageCms - { - public TextBox TbFileUploadDirectoryName; - public DropDownList DdlFileUploadDateFormatString; - public DropDownList DdlIsFileUploadChangeFileName; - public TextBox TbFileUploadTypeCollection; - public DropDownList DdlFileUploadTypeUnit; - public TextBox TbFileUploadTypeMaxSize; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (!IsPostBack) - { - VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); - - TbFileUploadDirectoryName.Text = SiteInfo.Additional.FileUploadDirectoryName; - - DdlFileUploadDateFormatString.Items.Add(new ListItem("按年存入不同目录(不推荐)", EDateFormatTypeUtils.GetValue(EDateFormatType.Year))); - DdlFileUploadDateFormatString.Items.Add(new ListItem("按年/月存入不同目录", EDateFormatTypeUtils.GetValue(EDateFormatType.Month))); - DdlFileUploadDateFormatString.Items.Add(new ListItem("按年/月/日存入不同目录", EDateFormatTypeUtils.GetValue(EDateFormatType.Day))); - ControlUtils.SelectSingleItemIgnoreCase(DdlFileUploadDateFormatString, SiteInfo.Additional.FileUploadDateFormatString); - - EBooleanUtils.AddListItems(DdlIsFileUploadChangeFileName, "自动修改文件名", "保持文件名不变"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsFileUploadChangeFileName, SiteInfo.Additional.IsFileUploadChangeFileName.ToString()); - - TbFileUploadTypeCollection.Text = SiteInfo.Additional.FileUploadTypeCollection.Replace("|", ","); - var mbSize = GetMbSize(SiteInfo.Additional.FileUploadTypeMaxSize); - if (mbSize == 0) - { - DdlFileUploadTypeUnit.SelectedIndex = 0; - TbFileUploadTypeMaxSize.Text = SiteInfo.Additional.FileUploadTypeMaxSize.ToString(); - } - else - { - DdlFileUploadTypeUnit.SelectedIndex = 1; - TbFileUploadTypeMaxSize.Text = mbSize.ToString(); - } - } - } - - private static int GetMbSize(int kbSize) - { - var retval = 0; - if (kbSize >= 1024 && ((kbSize % 1024) == 0)) - { - retval = kbSize / 1024; - } - return retval; - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (Page.IsPostBack && Page.IsValid) - { - SiteInfo.Additional.FileUploadDirectoryName = TbFileUploadDirectoryName.Text; - - SiteInfo.Additional.FileUploadDateFormatString = EDateFormatTypeUtils.GetValue(EDateFormatTypeUtils.GetEnumType(DdlFileUploadDateFormatString.SelectedValue)); - SiteInfo.Additional.IsFileUploadChangeFileName = TranslateUtils.ToBool(DdlIsFileUploadChangeFileName.SelectedValue); - - SiteInfo.Additional.FileUploadTypeCollection = TbFileUploadTypeCollection.Text.Replace(",", "|"); - var kbSize = int.Parse(TbFileUploadTypeMaxSize.Text); - SiteInfo.Additional.FileUploadTypeMaxSize = (DdlFileUploadTypeUnit.SelectedIndex == 0) ? kbSize : 1024 * kbSize; - - try - { - DataProvider.SiteDao.Update(SiteInfo); - - AuthRequest.AddSiteLog(SiteId, "修改附件上传设置"); - - SuccessMessage("上传附件设置修改成功!"); - } - catch(Exception ex) - { - FailMessage(ex, "上传附件设置修改失败!"); - } - } - } - - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageConfigurationUploadImage.cs b/SiteServer.BackgroundPages/Cms/PageConfigurationUploadImage.cs deleted file mode 100644 index a7121eb28..000000000 --- a/SiteServer.BackgroundPages/Cms/PageConfigurationUploadImage.cs +++ /dev/null @@ -1,98 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageConfigurationUploadImage : BasePageCms - { - public TextBox TbImageUploadDirectoryName; - public DropDownList DdlImageUploadDateFormatString; - public DropDownList DdlIsImageUploadChangeFileName; - public TextBox TbImageUploadTypeCollection; - public DropDownList DdlImageUploadTypeUnit; - public TextBox TbImageUploadTypeMaxSize; - - public TextBox TbPhotoSmallWidth; - public TextBox TbPhotoMiddleWidth; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId"); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); - - TbImageUploadDirectoryName.Text = SiteInfo.Additional.ImageUploadDirectoryName; - - DdlImageUploadDateFormatString.Items.Add(new ListItem("按年存入不同目录(不推荐)", EDateFormatTypeUtils.GetValue(EDateFormatType.Year))); - DdlImageUploadDateFormatString.Items.Add(new ListItem("按年/月存入不同目录", EDateFormatTypeUtils.GetValue(EDateFormatType.Month))); - DdlImageUploadDateFormatString.Items.Add(new ListItem("按年/月/日存入不同目录", EDateFormatTypeUtils.GetValue(EDateFormatType.Day))); - ControlUtils.SelectSingleItemIgnoreCase(DdlImageUploadDateFormatString, SiteInfo.Additional.ImageUploadDateFormatString); - - EBooleanUtils.AddListItems(DdlIsImageUploadChangeFileName, "自动修改文件名", "保持文件名不变"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsImageUploadChangeFileName, SiteInfo.Additional.IsImageUploadChangeFileName.ToString()); - - TbImageUploadTypeCollection.Text = SiteInfo.Additional.ImageUploadTypeCollection.Replace("|", ","); - var mbSize = GetMbSize(SiteInfo.Additional.ImageUploadTypeMaxSize); - if (mbSize == 0) - { - DdlImageUploadTypeUnit.SelectedIndex = 0; - TbImageUploadTypeMaxSize.Text = SiteInfo.Additional.ImageUploadTypeMaxSize.ToString(); - } - else - { - DdlImageUploadTypeUnit.SelectedIndex = 1; - TbImageUploadTypeMaxSize.Text = mbSize.ToString(); - } - - TbPhotoSmallWidth.Text = SiteInfo.Additional.PhotoSmallWidth.ToString(); - TbPhotoMiddleWidth.Text = SiteInfo.Additional.PhotoMiddleWidth.ToString(); - } - - private static int GetMbSize(int kbSize) - { - var retval = 0; - if (kbSize >= 1024 && kbSize % 1024 == 0) - { - retval = kbSize / 1024; - } - return retval; - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - SiteInfo.Additional.ImageUploadDirectoryName = TbImageUploadDirectoryName.Text; - - SiteInfo.Additional.ImageUploadDateFormatString = EDateFormatTypeUtils.GetValue(EDateFormatTypeUtils.GetEnumType(DdlImageUploadDateFormatString.SelectedValue)); - SiteInfo.Additional.IsImageUploadChangeFileName = TranslateUtils.ToBool(DdlIsImageUploadChangeFileName.SelectedValue); - - SiteInfo.Additional.ImageUploadTypeCollection = TbImageUploadTypeCollection.Text.Replace(",", "|"); - var kbSize = int.Parse(TbImageUploadTypeMaxSize.Text); - SiteInfo.Additional.ImageUploadTypeMaxSize = DdlImageUploadTypeUnit.SelectedIndex == 0 ? kbSize : 1024 * kbSize; - - SiteInfo.Additional.PhotoSmallWidth = TranslateUtils.ToInt(TbPhotoSmallWidth.Text, SiteInfo.Additional.PhotoSmallWidth); - SiteInfo.Additional.PhotoMiddleWidth = TranslateUtils.ToInt(TbPhotoMiddleWidth.Text, SiteInfo.Additional.PhotoMiddleWidth); - - try - { - DataProvider.SiteDao.Update(SiteInfo); - - AuthRequest.AddSiteLog(SiteId, "修改图片上传设置"); - - SuccessMessage("上传图片设置修改成功!"); - } - catch(Exception ex) - { - FailMessage(ex, "上传图片设置修改失败!"); - } - } - - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageConfigurationUploadVideo.cs b/SiteServer.BackgroundPages/Cms/PageConfigurationUploadVideo.cs deleted file mode 100644 index fb5be26f6..000000000 --- a/SiteServer.BackgroundPages/Cms/PageConfigurationUploadVideo.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageConfigurationUploadVideo : BasePageCms - { - public TextBox TbVideoUploadDirectoryName; - public DropDownList DdlVideoUploadDateFormatString; - public DropDownList DdlIsVideoUploadChangeFileName; - public TextBox TbVideoUploadTypeCollection; - public DropDownList DdlVideoUploadTypeUnit; - public TextBox TbVideoUploadTypeMaxSize; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); - - TbVideoUploadDirectoryName.Text = SiteInfo.Additional.VideoUploadDirectoryName; - - DdlVideoUploadDateFormatString.Items.Add(new ListItem("按年存入不同目录(不推荐)", EDateFormatTypeUtils.GetValue(EDateFormatType.Year))); - DdlVideoUploadDateFormatString.Items.Add(new ListItem("按年/月存入不同目录", EDateFormatTypeUtils.GetValue(EDateFormatType.Month))); - DdlVideoUploadDateFormatString.Items.Add(new ListItem("按年/月/日存入不同目录", EDateFormatTypeUtils.GetValue(EDateFormatType.Day))); - ControlUtils.SelectSingleItemIgnoreCase(DdlVideoUploadDateFormatString, SiteInfo.Additional.VideoUploadDateFormatString); - - EBooleanUtils.AddListItems(DdlIsVideoUploadChangeFileName, "自动修改文件名", "保持文件名不变"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsVideoUploadChangeFileName, SiteInfo.Additional.IsVideoUploadChangeFileName.ToString()); - - TbVideoUploadTypeCollection.Text = SiteInfo.Additional.VideoUploadTypeCollection.Replace("|", ","); - var mbSize = GetMbSize(SiteInfo.Additional.VideoUploadTypeMaxSize); - if (mbSize == 0) - { - DdlVideoUploadTypeUnit.SelectedIndex = 0; - TbVideoUploadTypeMaxSize.Text = SiteInfo.Additional.VideoUploadTypeMaxSize.ToString(); - } - else - { - DdlVideoUploadTypeUnit.SelectedIndex = 1; - TbVideoUploadTypeMaxSize.Text = mbSize.ToString(); - } - } - - private static int GetMbSize(int kbSize) - { - var retval = 0; - if (kbSize >= 1024 && ((kbSize % 1024) == 0)) - { - retval = kbSize / 1024; - } - return retval; - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (Page.IsPostBack && Page.IsValid) - { - SiteInfo.Additional.VideoUploadDirectoryName = TbVideoUploadDirectoryName.Text; - - SiteInfo.Additional.VideoUploadDateFormatString = EDateFormatTypeUtils.GetValue(EDateFormatTypeUtils.GetEnumType(DdlVideoUploadDateFormatString.SelectedValue)); - SiteInfo.Additional.IsVideoUploadChangeFileName = TranslateUtils.ToBool(DdlIsVideoUploadChangeFileName.SelectedValue); - - SiteInfo.Additional.VideoUploadTypeCollection = TbVideoUploadTypeCollection.Text.Replace(",", "|"); - var kbSize = int.Parse(TbVideoUploadTypeMaxSize.Text); - SiteInfo.Additional.VideoUploadTypeMaxSize = (DdlVideoUploadTypeUnit.SelectedIndex == 0) ? kbSize : 1024 * kbSize; - - try - { - DataProvider.SiteDao.Update(SiteInfo); - - AuthRequest.AddSiteLog(SiteId, "修改视频上传设置"); - - SuccessMessage("上传视频设置修改成功!"); - } - catch(Exception ex) - { - FailMessage(ex, "上传视频设置修改失败!"); - } - } - } - - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageConfigurationWaterMark.cs b/SiteServer.BackgroundPages/Cms/PageConfigurationWaterMark.cs deleted file mode 100644 index c20280a31..000000000 --- a/SiteServer.BackgroundPages/Cms/PageConfigurationWaterMark.cs +++ /dev/null @@ -1,164 +0,0 @@ -using System; -using System.Drawing.Text; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageConfigurationWaterMark : BasePageCms - { - public DropDownList DdlIsWaterMark; - public Literal LtlWaterMarkPosition; - public PlaceHolder PhWaterMarkPosition; - public DropDownList DdlWaterMarkTransparency; - public PlaceHolder PhWaterMarkTransparency; - public TextBox TbWaterMarkMinWidth; - public TextBox TbWaterMarkMinHeight; - public PlaceHolder PhWaterMarkMin; - public DropDownList DdlIsImageWaterMark; - public PlaceHolder PhIsImageWaterMark; - public TextBox TbWaterMarkFormatString; - public PlaceHolder PhWaterMarkFormatString; - public DropDownList DdlWaterMarkFontName; - public PlaceHolder PhWaterMarkFontName; - public TextBox TbWaterMarkFontSize; - public PlaceHolder PhWaterMarkFontSize; - public TextBox TbWaterMarkImagePath; - public PlaceHolder PhWaterMarkImagePath; - public Button BtnImageUrlSelect; - public Button BtnImageUrlUpload; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); - - EBooleanUtils.AddListItems(DdlIsWaterMark); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsWaterMark, SiteInfo.Additional.IsWaterMark.ToString()); - - LoadWaterMarkPosition(SiteInfo.Additional.WaterMarkPosition); - - for (var i = 1; i <= 10; i++) - { - DdlWaterMarkTransparency.Items.Add(new ListItem(i + "0%", i.ToString())); - } - ControlUtils.SelectSingleItemIgnoreCase(DdlWaterMarkTransparency, SiteInfo.Additional.WaterMarkTransparency.ToString()); - - TbWaterMarkMinWidth.Text = SiteInfo.Additional.WaterMarkMinWidth.ToString(); - TbWaterMarkMinHeight.Text = SiteInfo.Additional.WaterMarkMinHeight.ToString(); - - EBooleanUtils.AddListItems(DdlIsImageWaterMark, "图片型", "文字型"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsImageWaterMark, SiteInfo.Additional.IsImageWaterMark.ToString()); - - TbWaterMarkFormatString.Text = SiteInfo.Additional.WaterMarkFormatString; - - LoadSystemFont(); - ControlUtils.SelectSingleItemIgnoreCase(DdlWaterMarkFontName, SiteInfo.Additional.WaterMarkFontName); - - TbWaterMarkFontSize.Text = SiteInfo.Additional.WaterMarkFontSize.ToString(); - - TbWaterMarkImagePath.Text = SiteInfo.Additional.WaterMarkImagePath; - - DdlIsWaterMark_SelectedIndexChanged(null, null); - TbWaterMarkImagePath.Attributes.Add("onchange", GetShowImageScript("preview_WaterMarkImagePath", SiteInfo.Additional.WebUrl)); - - var showPopWinString = ModalSelectImage.GetOpenWindowString(SiteInfo, TbWaterMarkImagePath.ClientID); - BtnImageUrlSelect.Attributes.Add("onclick", showPopWinString); - - showPopWinString = ModalUploadImageSingle.GetOpenWindowStringToTextBox(SiteId, TbWaterMarkImagePath.ClientID); - BtnImageUrlUpload.Attributes.Add("onclick", showPopWinString); - } - - private void LoadWaterMarkPosition (int selectPosition) - { - LtlWaterMarkPosition.Text = ""; - for (var i = 1;i < 10; i++) - { - if (i % 3 == 1) - { - LtlWaterMarkPosition.Text = LtlWaterMarkPosition.Text + ""; - } - if (selectPosition == i) - { - object obj1 = LtlWaterMarkPosition.Text; - LtlWaterMarkPosition.Text = string.Concat(obj1, ""); - } - else - { - object obj2 = LtlWaterMarkPosition.Text; - LtlWaterMarkPosition.Text = string.Concat(obj2, ""); - } - if (i % 3 == 0) - { - LtlWaterMarkPosition.Text = LtlWaterMarkPosition.Text + ""; - } - } - LtlWaterMarkPosition.Text = LtlWaterMarkPosition.Text + "
#", i, "#", i, "
"; - } - - private void LoadSystemFont() - { - var familyArray = new InstalledFontCollection().Families; - foreach (var family in familyArray) - { - DdlWaterMarkFontName.Items.Add(new ListItem(family.Name, family.Name)); - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - SiteInfo.Additional.IsWaterMark = TranslateUtils.ToBool(DdlIsWaterMark.SelectedValue); - SiteInfo.Additional.WaterMarkPosition = TranslateUtils.ToInt(Request.Form["WaterMarkPosition"]); - SiteInfo.Additional.WaterMarkTransparency = TranslateUtils.ToInt(DdlWaterMarkTransparency.SelectedValue); - SiteInfo.Additional.WaterMarkMinWidth = TranslateUtils.ToInt(TbWaterMarkMinWidth.Text); - SiteInfo.Additional.WaterMarkMinHeight = TranslateUtils.ToInt(TbWaterMarkMinHeight.Text); - SiteInfo.Additional.IsImageWaterMark = TranslateUtils.ToBool(DdlIsImageWaterMark.SelectedValue); - SiteInfo.Additional.WaterMarkFormatString = TbWaterMarkFormatString.Text; - SiteInfo.Additional.WaterMarkFontName = DdlWaterMarkFontName.SelectedValue; - SiteInfo.Additional.WaterMarkFontSize = TranslateUtils.ToInt(TbWaterMarkFontSize.Text); - SiteInfo.Additional.WaterMarkImagePath = TbWaterMarkImagePath.Text; - - try - { - DataProvider.SiteDao.Update(SiteInfo); - AuthRequest.AddSiteLog(SiteId, "修改图片水印设置"); - SuccessMessage("图片水印设置修改成功!"); - } - catch(Exception ex) - { - FailMessage(ex, "图片水印设置修改失败!"); - } - } - - public void DdlIsWaterMark_SelectedIndexChanged(object sender, EventArgs e) - { - if (EBooleanUtils.Equals(DdlIsWaterMark.SelectedValue, EBoolean.True)) - { - PhWaterMarkPosition.Visible = PhWaterMarkTransparency.Visible = PhWaterMarkMin.Visible = PhIsImageWaterMark.Visible = true; - if (EBooleanUtils.Equals(DdlIsImageWaterMark.SelectedValue, EBoolean.True)) - { - PhWaterMarkFormatString.Visible = PhWaterMarkFontName.Visible = PhWaterMarkFontSize.Visible = false; - PhWaterMarkImagePath.Visible = true; - } - else - { - PhWaterMarkFormatString.Visible = PhWaterMarkFontName.Visible = PhWaterMarkFontSize.Visible = true; - PhWaterMarkImagePath.Visible = false; - } - } - else - { - PhWaterMarkPosition.Visible = PhWaterMarkTransparency.Visible = PhWaterMarkMin.Visible = PhIsImageWaterMark.Visible = PhWaterMarkFormatString.Visible = PhWaterMarkFontName.Visible = PhWaterMarkFontSize.Visible = PhWaterMarkImagePath.Visible = false; - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageContent.cs b/SiteServer.BackgroundPages/Cms/PageContent.cs deleted file mode 100644 index db1fe279c..000000000 --- a/SiteServer.BackgroundPages/Cms/PageContent.cs +++ /dev/null @@ -1,199 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageContent : BasePageCms - { - public Repeater RptContents; - public SqlPager SpContents; - public Literal LtlColumnsHead; - public Literal LtlButtons; - public Literal LtlMoreButtons; - public DateTimeTextBox TbDateFrom; - public DropDownList DdlSearchType; - public TextBox TbKeyword; - - private ChannelInfo _channelInfo; - private string _tableName; - private List _relatedIdentities; - private List _styleInfoList; - private StringCollection _attributesOfDisplay; - private List _attributesOfDisplayStyleInfoList; - private Dictionary> _pluginLinks; - private bool _isEdit; - private readonly Dictionary _nameValueCacheDict = new Dictionary(); - - public static string GetRedirectUrl(int siteId, int channelId) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageContent), new NameValueCollection - { - {"channelId", channelId.ToString()} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "channelId"); - var channelId = AuthRequest.GetQueryInt("channelId"); - _relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(SiteId, channelId); - _channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - _tableName = ChannelManager.GetTableName(SiteInfo, _channelInfo); - _styleInfoList = TableStyleManager.GetTableStyleInfoList(_tableName, _relatedIdentities); - _attributesOfDisplay = TranslateUtils.StringCollectionToStringCollection(ChannelManager.GetContentAttributesOfDisplay(SiteId, channelId)); - _attributesOfDisplayStyleInfoList = ContentUtility.GetAllTableStyleInfoList(_styleInfoList); - - _pluginLinks = PluginContentManager.GetContentLinks(_channelInfo); - _isEdit = TextUtility.IsEdit(SiteInfo, channelId, AuthRequest.AdminPermissions); - - if (_channelInfo.Additional.IsPreviewContents) - { - new Action(() => - { - DataProvider.ContentDao.DeletePreviewContents(SiteId, _tableName, _channelInfo); - }).BeginInvoke(null, null); - } - - if (!HasChannelPermissions(channelId, ConfigManager.ChannelPermissions.ContentView, ConfigManager.ChannelPermissions.ContentAdd, ConfigManager.ChannelPermissions.ContentEdit, ConfigManager.ChannelPermissions.ContentDelete, ConfigManager.ChannelPermissions.ContentTranslate)) - { - if (!AuthRequest.IsAdminLoggin) - { - PageUtils.RedirectToLoginPage(); - return; - } - PageUtils.RedirectToErrorPage("您无此栏目的操作权限!"); - return; - } - - SpContents.ControlToPaginate = RptContents; - RptContents.ItemDataBound += RptContents_ItemDataBound; - SpContents.ItemsPerPage = SiteInfo.Additional.PageSize; - - var administratorName = AuthRequest.AdminPermissions.IsViewContentOnlySelf(SiteId, channelId) - ? AuthRequest.AdminName - : string.Empty; - - if (AuthRequest.IsQueryExists("searchType")) - { - var owningChannelIdList = new List - { - channelId - }; - SpContents.SelectCommand = DataProvider.ContentDao.GetSqlString(_tableName, SiteId, channelId, AuthRequest.AdminPermissions.IsSystemAdministrator, owningChannelIdList, AuthRequest.GetQueryString("searchType"), AuthRequest.GetQueryString("keyword"), AuthRequest.GetQueryString("dateFrom"), string.Empty, false, ETriState.All, false, false, false, administratorName); - } - else - { - SpContents.SelectCommand = DataProvider.ContentDao.GetSqlString(_tableName, channelId, ETriState.All, administratorName); - } - - //spContents.SortField = DataProvider.ContentDao.GetSortFieldName(); - //spContents.SortMode = SortMode.DESC; - //spContents.OrderByString = ETaxisTypeUtils.GetOrderByString(tableStyle, ETaxisType.OrderByTaxisDesc); - SpContents.OrderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisTypeUtils.GetEnumType(_channelInfo.Additional.DefaultTaxisType)); - SpContents.TotalCount = _channelInfo.ContentNum; - - if (IsPostBack) return; - - LtlButtons.Text = WebUtils.GetContentCommands(AuthRequest.AdminPermissions, SiteInfo, _channelInfo, PageUrl); - LtlMoreButtons.Text = WebUtils.GetContentMoreCommands(AuthRequest.AdminPermissions, SiteInfo, _channelInfo, PageUrl); - - SpContents.DataBind(); - - if (_styleInfoList != null) - { - foreach (var styleInfo in _styleInfoList) - { - var listitem = new ListItem(styleInfo.DisplayName, styleInfo.AttributeName); - DdlSearchType.Items.Add(listitem); - } - } - - //添加隐藏属性 - DdlSearchType.Items.Add(new ListItem("内容ID", ContentAttribute.Id)); - DdlSearchType.Items.Add(new ListItem("添加者", ContentAttribute.AddUserName)); - DdlSearchType.Items.Add(new ListItem("最后修改者", ContentAttribute.LastEditUserName)); - DdlSearchType.Items.Add(new ListItem("内容组", ContentAttribute.GroupNameCollection)); - - if (AuthRequest.IsQueryExists("searchType")) - { - TbDateFrom.Text = AuthRequest.GetQueryString("dateFrom"); - ControlUtils.SelectSingleItem(DdlSearchType, AuthRequest.GetQueryString("searchType")); - TbKeyword.Text = AuthRequest.GetQueryString("keyword"); - if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("searchType")) || !string.IsNullOrEmpty(TbDateFrom.Text) || - !string.IsNullOrEmpty(TbKeyword.Text)) - { - LtlButtons.Text += @" - -"; - } - - } - - LtlColumnsHead.Text = TextUtility.GetColumnsHeadHtml(_styleInfoList, _attributesOfDisplay, SiteInfo); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var contentInfo = new ContentInfo(e.Item.DataItem); - - var ltlTitle = (Literal)e.Item.FindControl("ltlTitle"); - var ltlColumns = (Literal)e.Item.FindControl("ltlColumns"); - var ltlStatus = (Literal)e.Item.FindControl("ltlStatus"); - var ltlCommands = (Literal)e.Item.FindControl("ltlCommands"); - var ltlSelect = (Literal)e.Item.FindControl("ltlSelect"); - - ltlTitle.Text = WebUtils.GetContentTitle(SiteInfo, contentInfo, PageUrl); - - ltlColumns.Text = TextUtility.GetColumnsHtml(_nameValueCacheDict, SiteInfo, contentInfo, _attributesOfDisplay, _attributesOfDisplayStyleInfoList); - - ltlStatus.Text = - $@"{CheckManager.GetCheckState(SiteInfo, contentInfo.IsChecked, contentInfo.CheckedLevel)}"; - - ltlCommands.Text = TextUtility.GetCommandsHtml(SiteInfo, _pluginLinks, contentInfo, PageUrl, AuthRequest.AdminName, _isEdit); - - ltlSelect.Text = $@""; - } - - public void Search_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(PageUrl); - } - - private string _pageUrl; - private string PageUrl - { - get - { - if (string.IsNullOrEmpty(_pageUrl)) - { - _pageUrl = PageUtils.GetCmsUrl(SiteId, nameof(PageContent), new NameValueCollection - { - {"channelId", _channelInfo.Id.ToString()}, - {"dateFrom", TbDateFrom.Text}, - {"searchType", DdlSearchType.SelectedValue}, - {"keyword", TbKeyword.Text}, - {"page", AuthRequest.GetQueryInt("page", 1).ToString()} - }); - } - return _pageUrl; - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageContentAdd.cs b/SiteServer.BackgroundPages/Cms/PageContentAdd.cs deleted file mode 100644 index d33f73578..000000000 --- a/SiteServer.BackgroundPages/Cms/PageContentAdd.cs +++ /dev/null @@ -1,497 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Ajax; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Create; -using SiteServer.CMS.Core.Office; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.Plugin; -using SiteServer.Plugin; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageContentAdd : BasePageCms - { - public Literal LtlPageTitle; - - public TextBox TbTitle; - public Literal LtlTitleHtml; - public AuxiliaryControl AcAttributes; - public CheckBoxList CblContentAttributes; - public CheckBoxList CblContentGroups; - public Button BtnContentGroupAdd; - public DropDownList DdlContentLevel; - public TextBox TbTags; - public Literal LtlTags; - public PlaceHolder PhTranslate; - public Button BtnTranslate; - public DropDownList DdlTranslateType; - public PlaceHolder PhStatus; - public TextBox TbLinkUrl; - public DateTimeTextBox TbAddDate; - public Button BtnSubmit; - - private ChannelInfo _nodeInfo; - private List _styleInfoList; - private string _tableName; - - protected override bool IsSinglePage => true; - - public string PageContentAddHandlerUrl => PageContentAddHandler.GetRedirectUrl(SiteId, AuthRequest.GetQueryInt("channelId"), AuthRequest.GetQueryInt("id")); - - public static string GetRedirectUrlOfAdd(int siteId, int channelId, string returnUrl) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageContentAdd), new NameValueCollection - { - {"channelId", channelId.ToString()}, - {"returnUrl", StringUtils.ValueToUrl(returnUrl)} - }); - } - - public static string GetRedirectUrlOfEdit(int siteId, int channelId, int id, string returnUrl) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageContentAdd), new NameValueCollection - { - {"channelId", channelId.ToString()}, - {"id", id.ToString()}, - {"returnUrl", StringUtils.ValueToUrl(returnUrl)} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "channelId"); - - var channelId = AuthRequest.GetQueryInt("channelId"); - var contentId = AuthRequest.GetQueryInt("id"); - ReturnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("returnUrl")); - if (string.IsNullOrEmpty(ReturnUrl)) - { - ReturnUrl = PageContent.GetRedirectUrl(SiteId, channelId); - } - - _nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(SiteId, channelId); - _tableName = ChannelManager.GetTableName(SiteInfo, _nodeInfo); - ContentInfo contentInfo = null; - _styleInfoList = TableStyleManager.GetTableStyleInfoList(_tableName, relatedIdentities); - - if (!IsPermissions(contentId)) return; - - if (contentId > 0) - { - contentInfo = DataProvider.ContentDao.GetContentInfo(_tableName, contentId); - } - - var titleFormat = IsPostBack ? Request.Form[ContentAttribute.GetFormatStringAttributeName(ContentAttribute.Title)] : contentInfo?.GetString(ContentAttribute.GetFormatStringAttributeName(ContentAttribute.Title)); - LtlTitleHtml.Text = ContentUtility.GetTitleHtml(titleFormat, AjaxCmsService.GetTitlesUrl(SiteId, _nodeInfo.Id)); - - AcAttributes.SiteInfo = SiteInfo; - AcAttributes.ChannelId = _nodeInfo.Id; - AcAttributes.StyleInfoList = _styleInfoList; - - if (!IsPostBack) - { - var pageTitle = contentId == 0 ? "添加内容" : "编辑内容"; - - LtlPageTitle.Text = pageTitle; - - if (HasChannelPermissions(_nodeInfo.Id, ConfigManager.ChannelPermissions.ContentTranslate)) - { - PhTranslate.Visible = true; - BtnTranslate.Attributes.Add("onclick", ModalChannelMultipleSelect.GetOpenWindowString(SiteId, true)); - - ETranslateContentTypeUtils.AddListItems(DdlTranslateType, true); - ControlUtils.SelectSingleItem(DdlTranslateType, ETranslateContentTypeUtils.GetValue(ETranslateContentType.Copy)); - } - else - { - PhTranslate.Visible = false; - } - - CblContentAttributes.Items.Add(new ListItem("置顶", ContentAttribute.IsTop)); - CblContentAttributes.Items.Add(new ListItem("推荐", ContentAttribute.IsRecommend)); - CblContentAttributes.Items.Add(new ListItem("热点", ContentAttribute.IsHot)); - CblContentAttributes.Items.Add(new ListItem("醒目", ContentAttribute.IsColor)); - TbAddDate.DateTime = DateTime.Now; - TbAddDate.Now = true; - - var contentGroupNameList = DataProvider.ContentGroupDao.GetGroupNameList(SiteId); - foreach (var groupName in contentGroupNameList) - { - var item = new ListItem(groupName, groupName); - CblContentGroups.Items.Add(item); - } - - BtnContentGroupAdd.Attributes.Add("onclick", ModalContentGroupAdd.GetOpenWindowString(SiteId)); - - LtlTags.Text = ContentUtility.GetTagsHtml(AjaxCmsService.GetTagsUrl(SiteId)); - - if (HasChannelPermissions(_nodeInfo.Id, ConfigManager.ChannelPermissions.ContentCheck)) - { - PhStatus.Visible = true; - int checkedLevel; - var isChecked = CheckManager.GetUserCheckLevel(AuthRequest.AdminPermissions, SiteInfo, _nodeInfo.Id, out checkedLevel); - if (AuthRequest.IsQueryExists("contentLevel")) - { - checkedLevel = TranslateUtils.ToIntWithNagetive(AuthRequest.GetQueryString("contentLevel")); - if (checkedLevel != CheckManager.LevelInt.NotChange) - { - isChecked = checkedLevel >= SiteInfo.Additional.CheckContentLevel; - } - } - - CheckManager.LoadContentLevelToEdit(DdlContentLevel, SiteInfo, _nodeInfo.Id, contentInfo, isChecked, checkedLevel); - } - else - { - PhStatus.Visible = false; - } - - BtnSubmit.Attributes.Add("onclick", InputParserUtils.GetValidateSubmitOnClickScript("myForm", true, "autoCheckKeywords()")); - //自动检测敏感词 - ClientScriptRegisterStartupScript("autoCheckKeywords", WebUtils.GetAutoCheckKeywordsScript(SiteInfo)); - - if (contentId == 0) - { - var attributes = TableStyleManager.GetDefaultAttributes(_styleInfoList); - - if (AuthRequest.IsQueryExists("isUploadWord")) - { - var isFirstLineTitle = AuthRequest.GetQueryBool("isFirstLineTitle"); - var isFirstLineRemove = AuthRequest.GetQueryBool("isFirstLineRemove"); - var isClearFormat = AuthRequest.GetQueryBool("isClearFormat"); - var isFirstLineIndent = AuthRequest.GetQueryBool("isFirstLineIndent"); - var isClearFontSize = AuthRequest.GetQueryBool("isClearFontSize"); - var isClearFontFamily = AuthRequest.GetQueryBool("isClearFontFamily"); - var isClearImages = AuthRequest.GetQueryBool("isClearImages"); - var contentLevel = AuthRequest.GetQueryInt("contentLevel"); - var fileName = AuthRequest.GetQueryString("fileName"); - - var formCollection = WordUtils.GetWordNameValueCollection(SiteId, isFirstLineTitle, isFirstLineRemove, isClearFormat, isFirstLineIndent, isClearFontSize, isClearFontFamily, isClearImages, contentLevel, fileName); - attributes.Load(formCollection); - - TbTitle.Text = formCollection[ContentAttribute.Title]; - } - - AcAttributes.Attributes = attributes; - } - else if (contentInfo != null) - { - TbTitle.Text = contentInfo.Title; - - TbTags.Text = contentInfo.Tags; - - var list = new List(); - if (contentInfo.IsTop) - { - list.Add(ContentAttribute.IsTop); - } - if (contentInfo.IsRecommend) - { - list.Add(ContentAttribute.IsRecommend); - } - if (contentInfo.IsHot) - { - list.Add(ContentAttribute.IsHot); - } - if (contentInfo.IsColor) - { - list.Add(ContentAttribute.IsColor); - } - ControlUtils.SelectMultiItems(CblContentAttributes, list); - TbLinkUrl.Text = contentInfo.LinkUrl; - TbAddDate.DateTime = contentInfo.AddDate; - ControlUtils.SelectMultiItems(CblContentGroups, TranslateUtils.StringCollectionToStringList(contentInfo.GroupNameCollection)); - - AcAttributes.Attributes = contentInfo; - } - } - else - { - AcAttributes.Attributes = new ExtendedAttributes(Request.Form); - } - //DataBind(); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - var contentId = AuthRequest.GetQueryInt("id"); - string redirectUrl; - - if (contentId == 0) - { - var contentInfo = new ContentInfo(); - try - { - contentInfo.ChannelId = _nodeInfo.Id; - contentInfo.SiteId = SiteId; - contentInfo.AddUserName = AuthRequest.AdminName; - contentInfo.LastEditUserName = contentInfo.AddUserName; - contentInfo.LastEditDate = DateTime.Now; - - BackgroundInputTypeParser.SaveAttributes(contentInfo, SiteInfo, _styleInfoList, Request.Form, ContentAttribute.AllAttributesLowercase); - - contentInfo.GroupNameCollection = ControlUtils.SelectedItemsValueToStringCollection(CblContentGroups.Items); - var tagCollection = TagUtils.ParseTagsString(TbTags.Text); - - contentInfo.Title = TbTitle.Text; - var formatString = TranslateUtils.ToBool(Request.Form[ContentAttribute.Title + "_formatStrong"]); - var formatEm = TranslateUtils.ToBool(Request.Form[ContentAttribute.Title + "_formatEM"]); - var formatU = TranslateUtils.ToBool(Request.Form[ContentAttribute.Title + "_formatU"]); - var formatColor = Request.Form[ContentAttribute.Title + "_formatColor"]; - var theFormatString = ContentUtility.GetTitleFormatString(formatString, formatEm, formatU, formatColor); - contentInfo.Set(ContentAttribute.GetFormatStringAttributeName(ContentAttribute.Title), theFormatString); - foreach (ListItem listItem in CblContentAttributes.Items) - { - var value = listItem.Selected.ToString(); - var attributeName = listItem.Value; - contentInfo.Set(attributeName, value); - } - contentInfo.LinkUrl = TbLinkUrl.Text; - contentInfo.AddDate = TbAddDate.DateTime; - if (contentInfo.AddDate.Year <= DateUtils.SqlMinValue.Year) - { - contentInfo.AddDate = DateTime.Now; - } - - contentInfo.CheckedLevel = TranslateUtils.ToIntWithNagetive(DdlContentLevel.SelectedValue); - contentInfo.IsChecked = contentInfo.CheckedLevel >= SiteInfo.Additional.CheckContentLevel; - contentInfo.Tags = TranslateUtils.ObjectCollectionToString(tagCollection, " "); - - foreach (var service in PluginManager.Services) - { - try - { - service.OnContentFormSubmit(new ContentFormSubmitEventArgs(SiteId, _nodeInfo.Id, - contentInfo, new ExtendedAttributes(Request.Form))); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(service.PluginId, ex, nameof(IService.ContentFormSubmit)); - } - } - - contentInfo.Id = DataProvider.ContentDao.Insert(_tableName, SiteInfo, contentInfo); - //判断是不是有审核权限 - int checkedLevelOfUser; - var isCheckedOfUser = CheckManager.GetUserCheckLevel(AuthRequest.AdminPermissions, SiteInfo, contentInfo.ChannelId, out checkedLevelOfUser); - if (CheckManager.IsCheckable(SiteInfo, contentInfo.ChannelId, contentInfo.IsChecked, contentInfo.CheckedLevel, isCheckedOfUser, checkedLevelOfUser)) - { - //添加审核记录 - DataProvider.ContentDao.UpdateIsChecked(_tableName, SiteId, contentInfo.ChannelId, new List { contentInfo.Id }, 0, true, AuthRequest.AdminName, contentInfo.IsChecked, contentInfo.CheckedLevel, ""); - } - - TagUtils.AddTags(tagCollection, SiteId, contentInfo.Id); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(ex); - FailMessage($"内容添加失败:{ex.Message}"); - } - - CreateManager.CreateContentAndTrigger(SiteId, _nodeInfo.Id, contentInfo.Id); - - AuthRequest.AddSiteLog(SiteId, _nodeInfo.Id, contentInfo.Id, "添加内容", - $"栏目:{ChannelManager.GetChannelNameNavigation(SiteId, contentInfo.ChannelId)},内容标题:{contentInfo.Title}"); - - ContentUtility.Translate(SiteInfo, _nodeInfo.Id, contentInfo.Id, Request.Form["translateCollection"], ETranslateContentTypeUtils.GetEnumType(DdlTranslateType.SelectedValue), AuthRequest.AdminName); - - redirectUrl = PageContentAddAfter.GetRedirectUrl(SiteId, _nodeInfo.Id, contentInfo.Id, - ReturnUrl); - } - else - { - var contentInfo = DataProvider.ContentDao.GetContentInfo(_tableName, contentId); - try - { - var tagsLast = contentInfo.Tags; - - contentInfo.LastEditUserName = AuthRequest.AdminName; - contentInfo.LastEditDate = DateTime.Now; - - BackgroundInputTypeParser.SaveAttributes(contentInfo, SiteInfo, _styleInfoList, Request.Form, ContentAttribute.AllAttributesLowercase); - - contentInfo.GroupNameCollection = ControlUtils.SelectedItemsValueToStringCollection(CblContentGroups.Items); - var tagCollection = TagUtils.ParseTagsString(TbTags.Text); - - contentInfo.Title = TbTitle.Text; - var formatString = TranslateUtils.ToBool(Request.Form[ContentAttribute.Title + "_formatStrong"]); - var formatEm = TranslateUtils.ToBool(Request.Form[ContentAttribute.Title + "_formatEM"]); - var formatU = TranslateUtils.ToBool(Request.Form[ContentAttribute.Title + "_formatU"]); - var formatColor = Request.Form[ContentAttribute.Title + "_formatColor"]; - var theFormatString = ContentUtility.GetTitleFormatString(formatString, formatEm, formatU, formatColor); - contentInfo.Set(ContentAttribute.GetFormatStringAttributeName(ContentAttribute.Title), theFormatString); - foreach (ListItem listItem in CblContentAttributes.Items) - { - var value = listItem.Selected.ToString(); - var attributeName = listItem.Value; - contentInfo.Set(attributeName, value); - } - contentInfo.LinkUrl = TbLinkUrl.Text; - contentInfo.AddDate = TbAddDate.DateTime; - - var checkedLevel = TranslateUtils.ToIntWithNagetive(DdlContentLevel.SelectedValue); - if (checkedLevel != CheckManager.LevelInt.NotChange) - { - contentInfo.IsChecked = checkedLevel >= SiteInfo.Additional.CheckContentLevel; - contentInfo.CheckedLevel = checkedLevel; - } - contentInfo.Tags = TranslateUtils.ObjectCollectionToString(tagCollection, " "); - - foreach (var service in PluginManager.Services) - { - try - { - service.OnContentFormSubmit(new ContentFormSubmitEventArgs(SiteId, _nodeInfo.Id, - contentInfo, new ExtendedAttributes(Request.Form))); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(service.PluginId, ex, nameof(IService.ContentFormSubmit)); - } - } - - DataProvider.ContentDao.Update(_tableName, SiteInfo, contentInfo); - - TagUtils.UpdateTags(tagsLast, contentInfo.Tags, tagCollection, SiteId, contentId); - - ContentUtility.Translate(SiteInfo, _nodeInfo.Id, contentInfo.Id, Request.Form["translateCollection"], ETranslateContentTypeUtils.GetEnumType(DdlTranslateType.SelectedValue), AuthRequest.AdminName); - - //更新引用该内容的信息 - //如果不是异步自动保存,那么需要将引用此内容的content修改 - //var sourceContentIdList = new List - //{ - // contentInfo.Id - //}; - //var tableList = DataProvider.TableDao.GetTableCollectionInfoListCreatedInDb(); - //foreach (var table in tableList) - //{ - // var targetContentIdList = DataProvider.ContentDao.GetReferenceIdList(table.TableName, sourceContentIdList); - // foreach (var targetContentId in targetContentIdList) - // { - // var targetContentInfo = DataProvider.ContentDao.GetContentInfo(table.TableName, targetContentId); - // if (targetContentInfo == null || targetContentInfo.GetString(ContentAttribute.TranslateContentType) != ETranslateContentType.ReferenceContent.ToString()) continue; - - // contentInfo.Id = targetContentId; - // contentInfo.SiteId = targetContentInfo.SiteId; - // contentInfo.ChannelId = targetContentInfo.ChannelId; - // contentInfo.SourceId = targetContentInfo.SourceId; - // contentInfo.ReferenceId = targetContentInfo.ReferenceId; - // contentInfo.Taxis = targetContentInfo.Taxis; - // contentInfo.Set(ContentAttribute.TranslateContentType, targetContentInfo.GetString(ContentAttribute.TranslateContentType)); - // DataProvider.ContentDao.Update(table.TableName, contentInfo); - - // //资源:图片,文件,视频 - // var targetSiteInfo = SiteManager.GetSiteInfo(targetContentInfo.SiteId); - // var bgContentInfo = contentInfo as BackgroundContentInfo; - // var bgTargetContentInfo = targetContentInfo as BackgroundContentInfo; - // if (bgTargetContentInfo != null && bgContentInfo != null) - // { - // if (bgContentInfo.ImageUrl != bgTargetContentInfo.ImageUrl) - // { - // //修改图片 - // var sourceImageUrl = PathUtility.MapPath(SiteInfo, bgContentInfo.ImageUrl); - // CopyReferenceFiles(targetSiteInfo, sourceImageUrl); - // } - // else if (bgContentInfo.GetString(ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.ImageUrl)) != bgTargetContentInfo.GetString(ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.ImageUrl))) - // { - // var sourceImageUrls = TranslateUtils.StringCollectionToStringList(bgContentInfo.GetString(ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.ImageUrl))); - - // foreach (string imageUrl in sourceImageUrls) - // { - // var sourceImageUrl = PathUtility.MapPath(SiteInfo, imageUrl); - // CopyReferenceFiles(targetSiteInfo, sourceImageUrl); - // } - // } - // if (bgContentInfo.FileUrl != bgTargetContentInfo.FileUrl) - // { - // //修改附件 - // var sourceFileUrl = PathUtility.MapPath(SiteInfo, bgContentInfo.FileUrl); - // CopyReferenceFiles(targetSiteInfo, sourceFileUrl); - - // } - // else if (bgContentInfo.GetString(ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.FileUrl)) != bgTargetContentInfo.GetString(ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.FileUrl))) - // { - // var sourceFileUrls = TranslateUtils.StringCollectionToStringList(bgContentInfo.GetString(ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.FileUrl))); - - // foreach (var fileUrl in sourceFileUrls) - // { - // var sourceFileUrl = PathUtility.MapPath(SiteInfo, fileUrl); - // CopyReferenceFiles(targetSiteInfo, sourceFileUrl); - // } - // } - // } - // } - //} - } - catch (Exception ex) - { - LogUtils.AddErrorLog(ex); - FailMessage($"内容修改失败:{ex.Message}"); - return; - } - - CreateManager.CreateContentAndTrigger(SiteId, _nodeInfo.Id, contentId); - - AuthRequest.AddSiteLog(SiteId, _nodeInfo.Id, contentId, "修改内容", - $"栏目:{ChannelManager.GetChannelNameNavigation(SiteId, contentInfo.ChannelId)},内容标题:{contentInfo.Title}"); - - redirectUrl = ReturnUrl; - } - - PageUtils.Redirect(redirectUrl); - } - - private bool IsPermissions(int contentId) - { - if (contentId == 0) - { - if (_nodeInfo == null || _nodeInfo.Additional.IsContentAddable == false) - { - PageUtils.RedirectToErrorPage("此栏目不能添加内容!"); - return false; - } - - if (!HasChannelPermissions(_nodeInfo.Id, ConfigManager.ChannelPermissions.ContentAdd)) - { - if (!AuthRequest.IsAdminLoggin) - { - PageUtils.RedirectToLoginPage(); - return false; - } - - PageUtils.RedirectToErrorPage("您无此栏目的添加内容权限!"); - return false; - } - } - else - { - if (!HasChannelPermissions(_nodeInfo.Id, ConfigManager.ChannelPermissions.ContentEdit)) - { - if (!AuthRequest.IsAdminLoggin) - { - PageUtils.RedirectToLoginPage(); - return false; - } - - PageUtils.RedirectToErrorPage("您无此栏目的修改内容权限!"); - return false; - } - } - return true; - } - - public string ReturnUrl { get; private set; } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageContentCheck.cs b/SiteServer.BackgroundPages/Cms/PageContentCheck.cs deleted file mode 100644 index 76ab0fd8d..000000000 --- a/SiteServer.BackgroundPages/Cms/PageContentCheck.cs +++ /dev/null @@ -1,203 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageContentCheck : BasePageCms - { - public DropDownList DdlChannelId; - public DropDownList DdlState; - - public Repeater RptContents; - public SqlPager SpContents; - public Literal LtlColumnsHead; - - public Button BtnCheck; - public Button BtnDelete; - - private int _channelId; - private List _styleInfoList; - private StringCollection _attributesOfDisplay; - private List _attributesOfDisplayStyleInfoList; - private List _relatedIdentities; - private ChannelInfo _nodeInfo; - private string _tableName; - private Dictionary> _pluginLinks; - private bool _isEdit; - private readonly Dictionary _nameValueCacheDict = new Dictionary(); - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageContentCheck), null); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - _channelId = AuthRequest.IsQueryExists("ChannelId") ? AuthRequest.GetQueryInt("ChannelId") : SiteId; - - _relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(SiteId, _channelId); - _nodeInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - _tableName = ChannelManager.GetTableName(SiteInfo, _nodeInfo); - _styleInfoList = TableStyleManager.GetTableStyleInfoList(_tableName, _relatedIdentities); - _attributesOfDisplay = TranslateUtils.StringCollectionToStringCollection(ChannelManager.GetContentAttributesOfDisplay(SiteId, _channelId)); - _attributesOfDisplayStyleInfoList = ContentUtility.GetAllTableStyleInfoList(_styleInfoList); - _pluginLinks = PluginContentManager.GetContentLinks(_nodeInfo); - _isEdit = TextUtility.IsEdit(SiteInfo, _channelId, AuthRequest.AdminPermissions); - - if (IsPostBack) return; - - var checkedLevel = 5; - var isChecked = true; - foreach (var owningChannelId in AuthRequest.AdminPermissions.OwningChannelIdList) - { - int checkedLevelByChannelId; - var isCheckedByChannelId = CheckManager.GetUserCheckLevel(AuthRequest.AdminPermissions, SiteInfo, owningChannelId, out checkedLevelByChannelId); - if (checkedLevel > checkedLevelByChannelId) - { - checkedLevel = checkedLevelByChannelId; - } - if (!isCheckedByChannelId) - { - isChecked = false; - } - } - - ChannelManager.AddListItems(DdlChannelId.Items, SiteInfo, true, true, AuthRequest.AdminPermissions); - CheckManager.LoadContentLevelToList(DdlState, SiteInfo, SiteId, isChecked, checkedLevel); - var checkLevelList = new List(); - - if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("channelId"))) - { - ControlUtils.SelectSingleItem(DdlChannelId, AuthRequest.GetQueryString("channelId")); - } - if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("state"))) - { - ControlUtils.SelectSingleItem(DdlState, AuthRequest.GetQueryString("state")); - checkLevelList.Add(AuthRequest.GetQueryInt("state")); - } - else - { - checkLevelList = CheckManager.LevelInt.GetCheckLevelList(SiteInfo, isChecked, checkedLevel); - } - - SpContents.ControlToPaginate = RptContents; - SpContents.ItemsPerPage = SiteInfo.Additional.PageSize; - - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - var tableName = ChannelManager.GetTableName(SiteInfo, nodeInfo); - var channelIdList = ChannelManager.GetChannelIdList(nodeInfo, EScopeType.All, string.Empty, string.Empty, nodeInfo.ContentModelPluginId); - var list = new List(); - if (AuthRequest.AdminPermissions.IsSystemAdministrator) - { - list = channelIdList; - } - else - { - var owningChannelIdList = new List(); - foreach (var owningChannelId in AuthRequest.AdminPermissions.OwningChannelIdList) - { - if (HasChannelPermissions(owningChannelId, ConfigManager.ChannelPermissions.ContentCheck)) - { - owningChannelIdList.Add(owningChannelId); - } - } - foreach (var theChannelId in channelIdList) - { - if (owningChannelIdList.Contains(theChannelId)) - { - list.Add(theChannelId); - } - } - } - - SpContents.SelectCommand = DataProvider.ContentDao.GetSelectedCommendByCheck(tableName, SiteId, list, checkLevelList); - - SpContents.SortField = ContentAttribute.LastEditDate; - SpContents.SortMode = SortMode.DESC; - RptContents.ItemDataBound += RptContents_ItemDataBound; - - SpContents.DataBind(); - - var showPopWinString = ModalContentCheck.GetOpenWindowStringForMultiChannels(SiteId, PageUrl); - BtnCheck.Attributes.Add("onclick", showPopWinString); - - LtlColumnsHead.Text = TextUtility.GetColumnsHeadHtml(_styleInfoList, _attributesOfDisplay, SiteInfo); - - if (!HasChannelPermissions(SiteId, ConfigManager.ChannelPermissions.ContentDelete)) - { - BtnDelete.Visible = false; - } - else - { - BtnDelete.Attributes.Add("onclick", PageContentDelete.GetRedirectClickStringForMultiChannels(SiteId, false, PageUrl)); - } - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var contentInfo = new ContentInfo(e.Item.DataItem); - - var ltlTitle = (Literal)e.Item.FindControl("ltlTitle"); - var ltlChannel = (Literal)e.Item.FindControl("ltlChannel"); - var ltlColumns = (Literal)e.Item.FindControl("ltlColumns"); - var ltlStatus = (Literal)e.Item.FindControl("ltlStatus"); - var ltlCommands = (Literal)e.Item.FindControl("ltlCommands"); - var ltlSelect = (Literal) e.Item.FindControl("ltlSelect"); - - ltlTitle.Text = WebUtils.GetContentTitle(SiteInfo, contentInfo, PageUrl); - - ltlColumns.Text = TextUtility.GetColumnsHtml(_nameValueCacheDict, SiteInfo, contentInfo, _attributesOfDisplay, _attributesOfDisplayStyleInfoList); - - string nodeName; - if (!_nameValueCacheDict.TryGetValue(contentInfo.ChannelId.ToString(), out nodeName)) - { - nodeName = ChannelManager.GetChannelNameNavigation(SiteId, contentInfo.ChannelId); - _nameValueCacheDict[contentInfo.ChannelId.ToString()] = nodeName; - } - ltlChannel.Text = nodeName; - - ltlStatus.Text = - $@"{CheckManager.GetCheckState(SiteInfo, contentInfo.IsChecked, contentInfo.CheckedLevel)}"; - - ltlCommands.Text = TextUtility.GetCommandsHtml(SiteInfo, _pluginLinks, contentInfo, PageUrl, AuthRequest.AdminName, _isEdit); - - ltlSelect.Text = $@""; - } - - public void Search_OnClick(object sender, EventArgs e) - { - Response.Redirect(PageUrl, true); - } - - private string _pageUrl; - private string PageUrl - { - get - { - if (string.IsNullOrEmpty(_pageUrl)) - { - _pageUrl = PageUtils.GetCmsUrl(SiteId, nameof(PageContentCheck), new NameValueCollection - { - {"channelId", DdlChannelId.SelectedValue}, - {"state", DdlState.SelectedValue} - }); - } - return _pageUrl; - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageContentDelete.cs b/SiteServer.BackgroundPages/Cms/PageContentDelete.cs deleted file mode 100644 index 92c803560..000000000 --- a/SiteServer.BackgroundPages/Cms/PageContentDelete.cs +++ /dev/null @@ -1,200 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Text; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Create; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageContentDelete : BasePageCms - { - public Literal LtlContents; - public PlaceHolder PhRetain; - public RadioButtonList RblRetainFiles; - - private Dictionary> _idsDictionary = new Dictionary>(); - private bool _isDeleteFromTrash; - private string _returnUrl; - - public static string GetRedirectClickStringForMultiChannels(int siteId, bool isDeleteFromTrash, - string returnUrl) - { - return PageUtils.GetRedirectStringWithCheckBoxValue(PageUtils.GetCmsUrl(siteId, nameof(PageContentDelete), - new NameValueCollection - { - {"IsDeleteFromTrash", isDeleteFromTrash.ToString()}, - {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} - }), "IDsCollection", "IDsCollection", "请选择需要删除的内容!"); - } - - public static string GetRedirectClickStringForSingleChannel(int siteId, int channelId, - bool isDeleteFromTrash, string returnUrl) - { - return PageUtils.GetRedirectStringWithCheckBoxValue(PageUtils.GetCmsUrl(siteId, nameof(PageContentDelete), - new NameValueCollection - { - {"channelId", channelId.ToString()}, - {"IsDeleteFromTrash", isDeleteFromTrash.ToString()}, - {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} - }), "contentIdCollection", "contentIdCollection", "请选择需要删除的内容!"); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "ReturnUrl"); - _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); - _isDeleteFromTrash = AuthRequest.GetQueryBool("IsDeleteFromTrash"); - _idsDictionary = ContentUtility.GetIDsDictionary(Request.QueryString); - - //if (this.channelId > 0) - //{ - // this.nodeInfo = NodeManager.GetChannelInfo(base.SiteId, this.channelId); - //} - //else - //{ - // this.nodeInfo = NodeManager.GetChannelInfo(base.SiteId, -this.channelId); - //} - //if (this.nodeInfo != null) - //{ - // this.tableStyle = NodeManager.GetTableStyle(base.SiteInfo, nodeInfo); - // this.tableName = NodeManager.GetTableName(base.SiteInfo, nodeInfo); - //} - - //if (this.contentID == 0) - //{ - // if (!base.HasChannelPermissions(Math.Abs(this.channelId), AppManager.CMS.Permission.Channel.ContentDelete)) - // { - // PageUtils.RedirectToErrorPage("您没有删除此栏目内容的权限!"); - // return; - // } - //} - //else - //{ - // ContentInfo contentInfo = DataProvider.ContentDAO.GetContentInfo(this.tableStyle, this.tableName, this.contentID); - - // if (contentInfo == null || !string.Equals(AuthRequest.AdminName, contentInfo.AddUserName)) - // { - // if (!base.HasChannelPermissions(Math.Abs(this.channelId), AppManager.CMS.Permission.Channel.ContentDelete)) - // { - // PageUtils.RedirectToErrorPage("您没有删除此栏目内容的权限!"); - // return; - // } - // } - //} - - if (IsPostBack) return; - - var builder = new StringBuilder(); - foreach (var channelId in _idsDictionary.Keys) - { - var tableName = ChannelManager.GetTableName(SiteInfo, channelId); - var contentIdList = _idsDictionary[channelId]; - foreach (var contentId in contentIdList) - { - var contentInfo = DataProvider.ContentDao.GetContentInfo(tableName, contentId); - if (contentInfo != null) - { - builder.Append( - $@"{WebUtils.GetContentTitle(SiteInfo, contentInfo, _returnUrl)}
"); - } - } - } - LtlContents.Text = builder.ToString(); - - if (!_isDeleteFromTrash) - { - PhRetain.Visible = true; - InfoMessage("此操作将把所选内容放入回收站,确定吗?"); - } - else - { - PhRetain.Visible = false; - InfoMessage("此操作将从回收站中彻底删除所选内容,确定吗?"); - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - try - { - foreach (var channelId in _idsDictionary.Keys) - { - var tableName = ChannelManager.GetTableName(SiteInfo, channelId); - var contentIdList = _idsDictionary[channelId]; - - if (!_isDeleteFromTrash) - { - if (bool.Parse(RblRetainFiles.SelectedValue) == false) - { - DeleteManager.DeleteContents(SiteInfo, channelId, contentIdList); - SuccessMessage("成功删除内容以及生成页面!"); - } - else - { - SuccessMessage("成功删除内容,生成页面未被删除!"); - } - - if (contentIdList.Count == 1) - { - var contentId = contentIdList[0]; - var contentTitle = DataProvider.ContentDao.GetValue(tableName, contentId, ContentAttribute.Title); - AuthRequest.AddSiteLog(SiteId, channelId, contentId, "删除内容", - $"栏目:{ChannelManager.GetChannelNameNavigation(SiteId, channelId)},内容标题:{contentTitle}"); - } - else - { - AuthRequest.AddSiteLog(SiteId, "批量删除内容", - $"栏目:{ChannelManager.GetChannelNameNavigation(SiteId, channelId)},内容条数:{contentIdList.Count}"); - } - - DataProvider.ContentDao.TrashContents(SiteId, tableName, contentIdList); - - //引用内容,需要删除 - var tableList = DataProvider.TableDao.GetTableCollectionInfoListCreatedInDb(); - foreach (var table in tableList) - { - var targetContentIdList = DataProvider.ContentDao.GetReferenceIdList(table.TableName, contentIdList); - if (targetContentIdList.Count > 0) - { - var targetContentInfo = DataProvider.ContentDao.GetContentInfo(table.TableName, TranslateUtils.ToInt(targetContentIdList[0].ToString())); - DataProvider.ContentDao.DeleteContents(targetContentInfo.SiteId, table.TableName, targetContentIdList, targetContentInfo.ChannelId); - } - } - - CreateManager.CreateContentTrigger(SiteId, channelId); - } - else - { - SuccessMessage("成功从回收站清空内容!"); - DataProvider.ContentDao.DeleteContents(SiteId, tableName, contentIdList, channelId); - - AuthRequest.AddSiteLog(SiteId, "从回收站清空内容", $"内容条数:{contentIdList.Count}"); - } - } - - - AddWaitAndRedirectScript(_returnUrl); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(ex); - FailMessage(ex, "删除内容失败!"); - } - } - - public void Return_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(_returnUrl); - } - - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageContentSearch.cs b/SiteServer.BackgroundPages/Cms/PageContentSearch.cs deleted file mode 100644 index a89ab29c5..000000000 --- a/SiteServer.BackgroundPages/Cms/PageContentSearch.cs +++ /dev/null @@ -1,236 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageContentSearch : BasePageCms - { - public DropDownList DdlChannelId; - public DropDownList DdlState; - public CheckBox CbIsDuplicate; - public DropDownList DdlSearchType; - public TextBox TbKeyword; - public DateTimeTextBox TbDateFrom; - public DateTimeTextBox TbDateTo; - - public Repeater RptContents; - public SqlPager SpContents; - public Literal LtlColumnsHead; - - public Button BtnAddContent; - public Button BtnAddToGroup; - public Button BtnDelete; - public Button BtnTranslate; - public Button BtnSelect; - public PlaceHolder PhCheck; - public Button BtnCheck; - - private bool _isWritingOnly; - private bool _isSelfOnly; - private int _channelId; - private ChannelInfo _nodeInfo; - private List _relatedIdentities; - private List _styleInfoList; - private StringCollection _attributesOfDisplay; - private List _attributesOfDisplayStyleInfoList; - private Dictionary> _pluginLinks; - private bool _isEdit; - private readonly Dictionary _nameValueCacheDict = new Dictionary(); - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageContentSearch), null); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("SiteId"); - _channelId = AuthRequest.IsQueryExists("ChannelId") ? AuthRequest.GetQueryInt("ChannelId") : SiteId; - - _isWritingOnly = AuthRequest.GetQueryBool("isWritingOnly"); - - var administratorName = string.Empty; - _isSelfOnly = AuthRequest.GetQueryBool("isSelfOnly"); - if (!_isSelfOnly) - { - administratorName = AuthRequest.AdminPermissions.IsViewContentOnlySelf(SiteId, _channelId) ? AuthRequest.AdminName : string.Empty; - } - - _nodeInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - var tableName = ChannelManager.GetTableName(SiteInfo, _nodeInfo); - _relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(SiteId, _channelId); - _styleInfoList = TableStyleManager.GetTableStyleInfoList(tableName, _relatedIdentities); - _attributesOfDisplay = TranslateUtils.StringCollectionToStringCollection(ChannelManager.GetContentAttributesOfDisplay(SiteId, _channelId)); - _attributesOfDisplayStyleInfoList = ContentUtility.GetAllTableStyleInfoList(_styleInfoList); - _pluginLinks = PluginContentManager.GetContentLinks(_nodeInfo); - _isEdit = TextUtility.IsEdit(SiteInfo, _channelId, AuthRequest.AdminPermissions); - - var stateType = AuthRequest.IsQueryExists("state") ? ETriStateUtils.GetEnumType(AuthRequest.GetQueryString("state")) : ETriState.All; - var searchType = AuthRequest.IsQueryExists("searchType") ? AuthRequest.GetQueryString("searchType") : ContentAttribute.Title; - var dateFrom = AuthRequest.IsQueryExists("dateFrom") ? AuthRequest.GetQueryString("dateFrom") : string.Empty; - var dateTo = AuthRequest.IsQueryExists("dateTo") ? AuthRequest.GetQueryString("dateTo") : string.Empty; - var isDuplicate = AuthRequest.IsQueryExists("isDuplicate") && AuthRequest.GetQueryBool("isDuplicate"); - var keyword = AuthRequest.IsQueryExists("keyword") ? AuthRequest.GetQueryString("keyword") : string.Empty; - - SpContents.ControlToPaginate = RptContents; - SpContents.SelectCommand = DataProvider.ContentDao.GetSqlString(tableName, SiteId, _channelId, AuthRequest.AdminPermissions.IsSystemAdministrator, AuthRequest.AdminPermissions.OwningChannelIdList, searchType, keyword, dateFrom, dateTo, true, stateType, !isDuplicate, false, _isWritingOnly, administratorName); - SpContents.ItemsPerPage = SiteInfo.Additional.PageSize; - SpContents.SortField = ContentAttribute.Id; - SpContents.SortMode = SortMode.DESC; - SpContents.OrderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByIdDesc); - RptContents.ItemDataBound += RptContents_ItemDataBound; - - if (!IsPostBack) - { - ChannelManager.AddListItems(DdlChannelId.Items, SiteInfo, true, true, AuthRequest.AdminPermissions); - - DdlSearchType.Items.Add(new ListItem("标题", ContentAttribute.Title)); - if (_styleInfoList != null) - { - foreach (var styleInfo in _styleInfoList) - { - if (styleInfo.AttributeName != ContentAttribute.AddDate) - { - var listitem = new ListItem(styleInfo.DisplayName, styleInfo.AttributeName); - DdlSearchType.Items.Add(listitem); - } - } - } - DdlSearchType.Items.Add(new ListItem("内容ID", ContentAttribute.Id)); - DdlSearchType.Items.Add(new ListItem("添加者", ContentAttribute.AddUserName)); - DdlSearchType.Items.Add(new ListItem("最后修改者", ContentAttribute.LastEditUserName)); - - ETriStateUtils.AddListItems(DdlState, "全部", "已审核", "待审核"); - - if (SiteId != _channelId) - { - ControlUtils.SelectSingleItem(DdlChannelId, _channelId.ToString()); - } - ControlUtils.SelectSingleItem(DdlState, AuthRequest.GetQueryString("State")); - CbIsDuplicate.Checked = isDuplicate; - ControlUtils.SelectSingleItem(DdlSearchType, searchType); - TbKeyword.Text = keyword; - TbDateFrom.Text = dateFrom; - TbDateTo.Text = dateTo; - - SpContents.DataBind(); - - var showPopWinString = ModalAddToGroup.GetOpenWindowStringToContentForMultiChannels(SiteId); - BtnAddToGroup.Attributes.Add("onclick", showPopWinString); - - showPopWinString = ModalSelectColumns.GetOpenWindowString(SiteId, _channelId, true); - BtnSelect.Attributes.Add("onclick", showPopWinString); - - if (HasChannelPermissions(SiteId, ConfigManager.ChannelPermissions.ContentCheck)) - { - showPopWinString = ModalContentCheck.GetOpenWindowStringForMultiChannels(SiteId, PageUrl); - BtnCheck.Attributes.Add("onclick", showPopWinString); - } - else - { - PhCheck.Visible = false; - } - - LtlColumnsHead.Text = TextUtility.GetColumnsHeadHtml(_styleInfoList, _attributesOfDisplay, SiteInfo); - } - - if (!HasChannelPermissions(_channelId, ConfigManager.ChannelPermissions.ContentAdd)) BtnAddContent.Visible = false; - if (!HasChannelPermissions(_channelId, ConfigManager.ChannelPermissions.ContentTranslate)) - { - BtnTranslate.Visible = false; - } - else - { - BtnTranslate.Attributes.Add("onclick", PageContentTranslate.GetRedirectClickStringForMultiChannels(SiteId, PageUrl)); - } - - if (!HasChannelPermissions(_channelId, ConfigManager.ChannelPermissions.ContentDelete)) - { - BtnDelete.Visible = false; - } - else - { - BtnDelete.Attributes.Add("onclick", PageContentDelete.GetRedirectClickStringForMultiChannels(SiteId, false, PageUrl)); - } - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var contentInfo = new ContentInfo(e.Item.DataItem); - - var ltlTitle = (Literal)e.Item.FindControl("ltlTitle"); - var ltlChannel = (Literal)e.Item.FindControl("ltlChannel"); - var ltlColumns = (Literal)e.Item.FindControl("ltlColumns"); - var ltlStatus = (Literal)e.Item.FindControl("ltlStatus"); - var ltlCommands = (Literal)e.Item.FindControl("ltlCommands"); - var ltlSelect = (Literal)e.Item.FindControl("ltlSelect"); - - ltlTitle.Text = WebUtils.GetContentTitle(SiteInfo, contentInfo, PageUrl); - - ltlColumns.Text = TextUtility.GetColumnsHtml(_nameValueCacheDict, SiteInfo, contentInfo, _attributesOfDisplay, _attributesOfDisplayStyleInfoList); - - string nodeName; - if (!_nameValueCacheDict.TryGetValue(contentInfo.ChannelId.ToString(), out nodeName)) - { - nodeName = ChannelManager.GetChannelNameNavigation(SiteId, contentInfo.ChannelId); - _nameValueCacheDict[contentInfo.ChannelId.ToString()] = nodeName; - } - - ltlChannel.Text = nodeName; - - ltlStatus.Text = - $@"{CheckManager.GetCheckState(SiteInfo, contentInfo.IsChecked, contentInfo.CheckedLevel)}"; - - ltlCommands.Text = TextUtility.GetCommandsHtml(SiteInfo, _pluginLinks, contentInfo, PageUrl, AuthRequest.AdminName, _isEdit); - - ltlSelect.Text = $@""; - } - - public void AddContent_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(WebUtils.GetContentAddAddUrl(SiteId, _nodeInfo, PageUrl)); - } - - public void Search_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(PageUrl); - } - - private string _pageUrl; - private string PageUrl - { - get - { - if (string.IsNullOrEmpty(_pageUrl)) - { - _pageUrl = PageUtils.GetCmsUrl(SiteId, nameof(PageContentSearch), new NameValueCollection - { - {"ChannelId", DdlChannelId.SelectedValue}, - {"State", DdlState.SelectedValue}, - {"IsDuplicate", CbIsDuplicate.Checked.ToString()}, - {"SearchType", DdlSearchType.SelectedValue}, - {"Keyword", TbKeyword.Text}, - {"DateFrom", TbDateFrom.Text}, - {"DateTo", TbDateTo.Text}, - {"isWritingOnly", _isWritingOnly.ToString()}, - {"isSelfOnly", _isSelfOnly.ToString()} - }); - } - return _pageUrl; - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageContentTags.cs b/SiteServer.BackgroundPages/Cms/PageContentTags.cs deleted file mode 100644 index d36842f61..000000000 --- a/SiteServer.BackgroundPages/Cms/PageContentTags.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageContentTags : BasePageCms - { - public Repeater RptContents; - public SqlPager SpContents; - - public Button BtnAddTag; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (AuthRequest.IsQueryExists("Delete")) - { - var tagName = AuthRequest.GetQueryString("TagName"); - - try - { - var contentIdList = DataProvider.TagDao.GetContentIdListByTag(tagName, SiteId); - if (contentIdList.Count > 0) - { - foreach (var contentId in contentIdList) - { - var contentTags = DataProvider.ContentDao.GetValue(SiteInfo.TableName, contentId, ContentAttribute.Tags); - var contentTagArrayList = TranslateUtils.StringCollectionToStringList(contentTags); - contentTagArrayList.Remove(tagName); - DataProvider.ContentDao.SetValue(SiteInfo.TableName, contentId, ContentAttribute.Tags, TranslateUtils.ObjectCollectionToString(contentTagArrayList)); - } - } - DataProvider.TagDao.DeleteTag(tagName, SiteId); - AuthRequest.AddSiteLog(SiteId, "删除内容标签", $"内容标签:{tagName}"); - SuccessDeleteMessage(); - } - catch (Exception ex) - { - FailDeleteMessage(ex); - } - } - - SpContents.ControlToPaginate = RptContents; - SpContents.ItemsPerPage = SiteInfo.Additional.PageSize; - - SpContents.SelectCommand = DataProvider.TagDao.GetSqlString(SiteId, 0, true, 0); - SpContents.SortField = nameof(TagInfo.UseNum); - SpContents.SortMode = SortMode.DESC; - - RptContents.ItemDataBound += RptContents_ItemDataBound; - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); - - SpContents.DataBind(); - - var showPopWinString = ModalContentTagAdd.GetOpenWindowStringToAdd(SiteId); - BtnAddTag.Attributes.Add("onclick", showPopWinString); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var tag = SqlUtils.EvalString(e.Item.DataItem, nameof(TagInfo.Tag)); - var level = SqlUtils.EvalInt(e.Item.DataItem, nameof(TagInfo.Level)); - var useNum = SqlUtils.EvalInt(e.Item.DataItem, nameof(TagInfo.UseNum)); - - var ltlTagName = (Literal)e.Item.FindControl("ltlTagName"); - var ltlCount = (Literal)e.Item.FindControl("ltlCount"); - var ltlEditUrl = (Literal)e.Item.FindControl("ltlEditUrl"); - var ltlDeleteUrl = (Literal)e.Item.FindControl("ltlDeleteUrl"); - - var cssClass = "tag_popularity_1"; - if (level == 2) - { - cssClass = "tag_popularity_2"; - } - else if (level == 3) - { - cssClass = "tag_popularity_3"; - } - - ltlTagName.Text = $@"{tag}"; - ltlCount.Text = useNum.ToString(); - - var showPopWinString = ModalContentTagAdd.GetOpenWindowStringToEdit(SiteId, tag); - ltlEditUrl.Text = $"编辑"; - - var urlDelete = PageUtils.GetCmsUrl(SiteId, nameof(PageContentTags), new NameValueCollection - { - {"TagName", tag}, - {"Delete", true.ToString()} - }); - ltlDeleteUrl.Text = - $"删除"; - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageContentTrash.cs b/SiteServer.BackgroundPages/Cms/PageContentTrash.cs deleted file mode 100644 index 0f964083c..000000000 --- a/SiteServer.BackgroundPages/Cms/PageContentTrash.cs +++ /dev/null @@ -1,214 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageContentTrash : BasePageCms - { - public DropDownList DdlChannelId; - public DropDownList DdlPageNum; - public DropDownList DdlSearchType; - public TextBox TbKeyword; - public DateTimeTextBox TbDateFrom; - public DateTimeTextBox TbDateTo; - - public Repeater RptContents; - public SqlPager SpContents; - - public Button BtnRestore; - public Button BtnRestoreAll; - public Button BtnDelete; - public Button BtnDeleteAll; - - private int _channelId; - private List _relatedIdentities; - private List _tableStyleInfoList; - private readonly Hashtable _nodeNameNavigations = new Hashtable(); - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - _channelId = AuthRequest.GetQueryInt("channelId"); - if (_channelId == 0) - { - _channelId = SiteId; - } - var channelInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - var tableName = ChannelManager.GetTableName(SiteInfo, channelInfo); - _relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(SiteId, _channelId); - _tableStyleInfoList = TableStyleManager.GetTableStyleInfoList(tableName, _relatedIdentities); - - SpContents.ControlToPaginate = RptContents; - if (string.IsNullOrEmpty(AuthRequest.GetQueryString("channelId"))) - { - SpContents.ItemsPerPage = TranslateUtils.ToInt(DdlPageNum.SelectedValue) == 0 ? SiteInfo.Additional.PageSize : TranslateUtils.ToInt(DdlPageNum.SelectedValue); - SpContents.SelectCommand = DataProvider.ContentDao.GetSqlString(tableName, SiteId, _channelId, AuthRequest.AdminPermissions.IsSystemAdministrator, AuthRequest.AdminPermissions.OwningChannelIdList, DdlSearchType.SelectedValue, TbKeyword.Text, TbDateFrom.Text, TbDateTo.Text, true, ETriState.All, false, true); - } - else - { - SpContents.ItemsPerPage = AuthRequest.GetQueryInt("PageNum") == 0 ? SiteInfo.Additional.PageSize : AuthRequest.GetQueryInt("PageNum"); - SpContents.SelectCommand = DataProvider.ContentDao.GetSqlString(tableName, SiteId, _channelId, AuthRequest.AdminPermissions.IsSystemAdministrator, AuthRequest.AdminPermissions.OwningChannelIdList, AuthRequest.GetQueryString("SearchType"), AuthRequest.GetQueryString("Keyword"), AuthRequest.GetQueryString("DateFrom"), AuthRequest.GetQueryString("DateTo"), true, ETriState.All, false, true); - } - SpContents.OrderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByIdDesc); - RptContents.ItemDataBound += RptContents_ItemDataBound; - - if(!IsPostBack) - { - VerifySitePermissions(ConfigManager.WebSitePermissions.Content); - - if (AuthRequest.IsQueryExists("IsDeleteAll")) - { - DataProvider.ContentDao.DeleteContentsByTrash(SiteId, tableName); - AuthRequest.AddSiteLog(SiteId, "清空回收站"); - SuccessMessage("成功清空回收站!"); - AddWaitAndRedirectScript(PageUrl); - return; - } - if (AuthRequest.IsQueryExists("IsRestore")) - { - var idsDictionary = ContentUtility.GetIDsDictionary(Request.QueryString); - foreach (var channelId in idsDictionary.Keys) - { - var contentIdArrayList = idsDictionary[channelId]; - DataProvider.ContentDao.TrashContents(SiteId, ChannelManager.GetTableName(SiteInfo, channelId), contentIdArrayList); - } - AuthRequest.AddSiteLog(SiteId, "从回收站还原内容"); - SuccessMessage("成功还原内容!"); - AddWaitAndRedirectScript(PageUrl); - return; - } - if (AuthRequest.IsQueryExists("IsRestoreAll")) - { - DataProvider.ContentDao.RestoreContentsByTrash(SiteId, tableName); - AuthRequest.AddSiteLog(SiteId, "从回收站还原所有内容"); - SuccessMessage("成功还原所有内容!"); - AddWaitAndRedirectScript(PageUrl); - return; - } - ChannelManager.AddListItems(DdlChannelId.Items, SiteInfo, true, false, AuthRequest.AdminPermissions); - - if (_tableStyleInfoList != null) - { - foreach (var styleInfo in _tableStyleInfoList) - { - var listitem = new ListItem(styleInfo.DisplayName, styleInfo.AttributeName); - DdlSearchType.Items.Add(listitem); - } - } - //添加隐藏属性 - DdlSearchType.Items.Add(new ListItem("内容ID", ContentAttribute.Id)); - DdlSearchType.Items.Add(new ListItem("添加者", ContentAttribute.AddUserName)); - DdlSearchType.Items.Add(new ListItem("最后修改者", ContentAttribute.LastEditUserName)); - - if (AuthRequest.IsQueryExists("channelId")) - { - if (SiteId != _channelId) - { - ControlUtils.SelectSingleItem(DdlChannelId, _channelId.ToString()); - } - ControlUtils.SelectSingleItem(DdlPageNum, AuthRequest.GetQueryString("PageNum")); - ControlUtils.SelectSingleItem(DdlSearchType, AuthRequest.GetQueryString("SearchType")); - TbKeyword.Text = AuthRequest.GetQueryString("Keyword"); - TbDateFrom.Text = AuthRequest.GetQueryString("DateFrom"); - TbDateTo.Text = AuthRequest.GetQueryString("DateTo"); - } - - SpContents.DataBind(); - } - - if (!HasChannelPermissions(_channelId, ConfigManager.ChannelPermissions.ContentDelete)) - { - BtnDelete.Visible = false; - BtnDeleteAll.Visible = false; - } - else - { - BtnDelete.Attributes.Add("onclick", PageContentDelete.GetRedirectClickStringForMultiChannels(SiteId, true, PageUrl)); - BtnDeleteAll.Attributes.Add("onclick", PageUtils.GetRedirectStringWithConfirm(PageUtils.AddQueryString(PageUrl, "IsDeleteAll", "True"), "确实要清空回收站吗?")); - } - BtnRestore.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValue(PageUtils.AddQueryString(PageUrl, "IsRestore", "True"), "IDsCollection", "IDsCollection", "请选择需要还原的内容!")); - BtnRestoreAll.Attributes.Add("onclick", PageUtils.GetRedirectStringWithConfirm(PageUtils.AddQueryString(PageUrl, "IsRestoreAll", "True"), "确实要还原所有内容吗?")); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var ltlItemTitle = (Literal)e.Item.FindControl("ltlItemTitle"); - var ltlChannel = (Literal)e.Item.FindControl("ltlChannel"); - var ltlDeleteDate = (Literal)e.Item.FindControl("ltlDeleteDate"); - var ltlItemEditUrl = (Literal)e.Item.FindControl("ltlItemEditUrl"); - var ltlSelect = (Literal)e.Item.FindControl("ltlSelect"); - - var contentInfo = new ContentInfo(e.Item.DataItem); - contentInfo.ChannelId = -contentInfo.ChannelId; - - ltlItemTitle.Text = WebUtils.GetContentTitle(SiteInfo, contentInfo, PageUrl); - string nodeNameNavigation; - if (!_nodeNameNavigations.ContainsKey(contentInfo.ChannelId)) - { - nodeNameNavigation = ChannelManager.GetChannelNameNavigation(SiteId, contentInfo.ChannelId); - _nodeNameNavigations.Add(contentInfo.ChannelId, nodeNameNavigation); - } - else - { - nodeNameNavigation = _nodeNameNavigations[contentInfo.ChannelId] as string; - } - ltlChannel.Text = nodeNameNavigation; - ltlDeleteDate.Text = DateUtils.GetDateAndTimeString(contentInfo.LastEditDate); - - if (HasChannelPermissions(contentInfo.ChannelId, ConfigManager.ChannelPermissions.ContentEdit) || AuthRequest.AdminName == contentInfo.AddUserName) - { - var channelInfo = ChannelManager.GetChannelInfo(SiteId, contentInfo.ChannelId); - ltlItemEditUrl.Text = - $"修改"; - } - - ltlSelect.Text = - $@""; - } - - public void AddContent_OnClick(object sender, EventArgs e) - { - var channelInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - PageUtils.Redirect(WebUtils.GetContentAddAddUrl(SiteId, channelInfo, PageUrl)); - } - - public void Search_OnClick(object sender, EventArgs e) - { - Response.Redirect(PageUrl, true); - } - - private string _pageUrl; - private string PageUrl - { - get - { - if (string.IsNullOrEmpty(_pageUrl)) - { - _pageUrl = PageUtils.GetCmsUrl(SiteId, nameof(PageContentTrash), new NameValueCollection - { - {"channelId", DdlChannelId.SelectedValue}, - {"PageNum", DdlPageNum.SelectedValue}, - {"SearchType", DdlSearchType.SelectedValue}, - {"Keyword", TbKeyword.Text}, - {"DateFrom", TbDateFrom.Text}, - {"DateTo", TbDateTo.Text} - }); - } - return _pageUrl; - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageContentView.cs b/SiteServer.BackgroundPages/Cms/PageContentView.cs deleted file mode 100644 index 381074426..000000000 --- a/SiteServer.BackgroundPages/Cms/PageContentView.cs +++ /dev/null @@ -1,147 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Api.Preview; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageContentView : BasePageCms - { - public Literal LtlScripts; - public Literal LtlNodeName; - public Literal LtlContentGroup; - public Literal LtlTags; - public Literal LtlLastEditDate; - public Literal LtlAddUserName; - public Literal LtlLastEditUserName; - public Literal LtlContentLevel; - public Repeater RptContents; - public PlaceHolder PhTags; - public PlaceHolder PhContentGroup; - public Button BtnSubmit; - public HyperLink HlPreview; - - private int _channelId; - private string _tableName; - private List _relatedIdentities; - private int _contentId; - private string _returnUrl; - private ContentInfo _contentInfo; - - public static string GetContentViewUrl(int siteId, int channelId, int contentId, string returnUrl) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageContentView), new NameValueCollection - { - {"channelId", channelId.ToString()}, - {"ID", contentId.ToString()}, - {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId", "channelId", "ID", "ReturnUrl"); - - _channelId = AuthRequest.GetQueryInt("channelId"); - var channelInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); - _tableName = ChannelManager.GetTableName(SiteInfo, channelInfo); - _contentId = AuthRequest.GetQueryInt("ID"); - _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); - - _relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(SiteId, _channelId); - - _contentInfo = DataProvider.ContentDao.GetContentInfo(_tableName, _contentId); - - if (IsPostBack) return; - - var styleInfoList = TableStyleManager.GetTableStyleInfoList(_tableName, _relatedIdentities); - var myStyleInfoArrayList = new ArrayList(); - if (styleInfoList != null) - { - foreach (var styleInfo in styleInfoList) - { - myStyleInfoArrayList.Add(styleInfo); - } - } - - RptContents.DataSource = myStyleInfoArrayList; - RptContents.ItemDataBound += RptContents_ItemDataBound; - RptContents.DataBind(); - - LtlNodeName.Text = ChannelManager.GetChannelName(SiteId, _channelId); - - LtlTags.Text = _contentInfo.Tags; - if (string.IsNullOrEmpty(LtlTags.Text)) - { - PhTags.Visible = false; - } - - LtlContentGroup.Text = _contentInfo.GroupNameCollection; - if (string.IsNullOrEmpty(LtlContentGroup.Text)) - { - PhContentGroup.Visible = false; - } - - LtlLastEditDate.Text = DateUtils.GetDateAndTimeString(_contentInfo.LastEditDate); - LtlAddUserName.Text = AdminManager.GetDisplayName(_contentInfo.AddUserName, true); - LtlLastEditUserName.Text = AdminManager.GetDisplayName(_contentInfo.LastEditUserName, true); - - LtlContentLevel.Text = CheckManager.GetCheckState(SiteInfo, _contentInfo.IsChecked, _contentInfo.CheckedLevel); - - if (_contentInfo.ReferenceId > 0 && _contentInfo.GetString(ContentAttribute.TranslateContentType) != ETranslateContentType.ReferenceContent.ToString()) - { - var referenceSiteId = DataProvider.ChannelDao.GetSiteId(_contentInfo.SourceId); - var referenceSiteInfo = SiteManager.GetSiteInfo(referenceSiteId); - var referenceTableName = ChannelManager.GetTableName(referenceSiteInfo, _contentInfo.SourceId); - var referenceContentInfo = DataProvider.ContentDao.GetContentInfo(referenceTableName, _contentInfo.ReferenceId); - - if (referenceContentInfo != null) - { - var pageUrl = PageUtility.GetContentUrl(referenceSiteInfo, referenceContentInfo, true); - var referenceNodeInfo = ChannelManager.GetChannelInfo(referenceContentInfo.SiteId, referenceContentInfo.ChannelId); - var addEditUrl = - WebUtils.GetContentAddEditUrl(referenceSiteInfo.Id, - referenceNodeInfo, _contentInfo.ReferenceId, AuthRequest.GetQueryString("ReturnUrl")); - - LtlScripts.Text += $@" -
此内容为对内容 (站点:{referenceSiteInfo.SiteName},栏目:{referenceNodeInfo.ChannelName})“{_contentInfo.Title}”(编辑) 的引用,内容链接将和原始内容链接一致
"; - } - } - - BtnSubmit.Attributes.Add("onclick", ModalContentCheck.GetOpenWindowString(SiteInfo.Id, _channelId, _contentId, _returnUrl)); - HlPreview.NavigateUrl = ApiRoutePreview.GetContentUrl(SiteId, _contentInfo.ChannelId, _contentInfo.Id); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var styleInfo = (TableStyleInfo)e.Item.DataItem; - - var inputHtml = InputParserUtility.GetContentByTableStyle(_contentInfo.GetString(styleInfo.AttributeName), SiteInfo, styleInfo); - - var ltlHtml = (Literal)e.Item.FindControl("ltlHtml"); - - ltlHtml.Text = $@" -
- -
- {inputHtml} -
-
-
-"; - } - - public string ReturnUrl => _returnUrl; - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageCreateAll.cs b/SiteServer.BackgroundPages/Cms/PageCreateAll.cs deleted file mode 100644 index 3a25db7aa..000000000 --- a/SiteServer.BackgroundPages/Cms/PageCreateAll.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Settings; -using SiteServer.CMS.Core.Create; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageCreateAll : BasePageCms - { - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (IsPostBack) return; - - CreateManager.CreateAll(SiteId); - PageCreateStatus.Redirect(SiteId); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageCreateChannel.cs b/SiteServer.BackgroundPages/Cms/PageCreateChannel.cs deleted file mode 100644 index c632a0031..000000000 --- a/SiteServer.BackgroundPages/Cms/PageCreateChannel.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Settings; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Create; -using SiteServer.Plugin; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageCreateChannel : BasePageCms - { - public ListBox LbChannelIdList; - public DropDownList DdlScope; - public Button BtnDeleteAll; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Create); - - var listitem = new ListItem("所有选中的栏目", "All"); - DdlScope.Items.Add(listitem); - listitem = new ListItem("一个月内更新的栏目", "Month"); - DdlScope.Items.Add(listitem); - listitem = new ListItem("一天内更新的栏目", "Day"); - DdlScope.Items.Add(listitem); - listitem = new ListItem("2小时内更新的栏目", "2Hour"); - DdlScope.Items.Add(listitem); - - ChannelManager.AddListItems(LbChannelIdList.Items, SiteInfo, false, true, AuthRequest.AdminPermissions); - BtnDeleteAll.Attributes.Add("onclick", "return confirm(\"此操作将删除所有已生成的栏目页面,确定吗?\");"); - } - - public void Create_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - var channelIdList = new List(); - var selectedChannelIdArrayList = ControlUtils.GetSelectedListControlValueArrayList(LbChannelIdList); - - var tableName = SiteInfo.TableName; - - if (DdlScope.SelectedValue == "Month") - { - var lastEditList = DataProvider.ContentDao.GetChannelIdListCheckedByLastEditDateHour(tableName, SiteId, 720); - foreach (var channelId in lastEditList) - { - if (selectedChannelIdArrayList.Contains(channelId.ToString())) - { - channelIdList.Add(channelId); - } - } - } - else if (DdlScope.SelectedValue == "Day") - { - var lastEditList = DataProvider.ContentDao.GetChannelIdListCheckedByLastEditDateHour(tableName, SiteId, 24); - foreach (var channelId in lastEditList) - { - if (selectedChannelIdArrayList.Contains(channelId.ToString())) - { - channelIdList.Add(channelId); - } - } - } - else if (DdlScope.SelectedValue == "2Hour") - { - var lastEditList = DataProvider.ContentDao.GetChannelIdListCheckedByLastEditDateHour(tableName, SiteId, 2); - foreach (var channelId in lastEditList) - { - if (selectedChannelIdArrayList.Contains(channelId.ToString())) - { - channelIdList.Add(channelId); - } - } - } - else - { - channelIdList = TranslateUtils.StringCollectionToIntList(TranslateUtils.ObjectCollectionToString(selectedChannelIdArrayList)); - } - - if (channelIdList.Count == 0) - { - FailMessage("请首先选中希望生成页面的栏目!"); - return; - } - - foreach (var channelId in channelIdList) - { - CreateManager.CreateChannel(SiteId, channelId); - } - - PageCreateStatus.Redirect(SiteId); - } - - public void BtnDeleteAll_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - var url = PageProgressBar.GetDeleteAllPageUrl(SiteId, TemplateType.ChannelTemplate); - PageUtils.RedirectToLoadingPage(url); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageCreateContent.cs b/SiteServer.BackgroundPages/Cms/PageCreateContent.cs deleted file mode 100644 index 7ef1a89af..000000000 --- a/SiteServer.BackgroundPages/Cms/PageCreateContent.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Settings; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Create; -using SiteServer.Plugin; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageCreateContent : BasePageCms - { - public ListBox LbChannelIdList; - public DropDownList DdlScope; - public Button BtnDeleteAll; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Create); - - var listitem = new ListItem("所有选中的栏目", "All"); - DdlScope.Items.Add(listitem); - listitem = new ListItem("一个月内更新的内容", "Month"); - DdlScope.Items.Add(listitem); - listitem = new ListItem("一天内更新的内容", "Day"); - DdlScope.Items.Add(listitem); - listitem = new ListItem("2小时内更新的内容", "2Hour"); - DdlScope.Items.Add(listitem); - - ChannelManager.AddListItems(LbChannelIdList.Items, SiteInfo, false, true, AuthRequest.AdminPermissions); - BtnDeleteAll.Attributes.Add("onclick", "return confirm(\"此操作将删除所有已生成的内容页面,确定吗?\");"); - } - - - public void Create_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - var channelIdList = new List(); - var selectedChannelIdArrayList = ControlUtils.GetSelectedListControlValueArrayList(LbChannelIdList); - - var tableName = SiteInfo.TableName; - - if (DdlScope.SelectedValue == "Month") - { - var lastEditList = DataProvider.ContentDao.GetChannelIdListCheckedByLastEditDateHour(tableName, SiteId, 720); - foreach (var channelId in lastEditList) - { - if (selectedChannelIdArrayList.Contains(channelId.ToString())) - { - channelIdList.Add(channelId); - } - } - } - else if (DdlScope.SelectedValue == "Day") - { - var lastEditList = DataProvider.ContentDao.GetChannelIdListCheckedByLastEditDateHour(tableName, SiteId, 24); - foreach (var channelId in lastEditList) - { - if (selectedChannelIdArrayList.Contains(channelId.ToString())) - { - channelIdList.Add(channelId); - } - } - } - else if (DdlScope.SelectedValue == "2Hour") - { - var lastEditList = DataProvider.ContentDao.GetChannelIdListCheckedByLastEditDateHour(tableName, SiteId, 2); - foreach (var channelId in lastEditList) - { - if (selectedChannelIdArrayList.Contains(channelId.ToString())) - { - channelIdList.Add(channelId); - } - } - } - else - { - channelIdList = TranslateUtils.StringCollectionToIntList(TranslateUtils.ObjectCollectionToString(selectedChannelIdArrayList)); - } - - - if (channelIdList.Count == 0) - { - FailMessage("请首先选中希望生成内容页面的栏目!"); - return; - } - - foreach (var channelId in channelIdList) - { - CreateManager.CreateAllContent(SiteId, channelId); - } - - PageCreateStatus.Redirect(SiteId); - } - - public void BtnDeleteAll_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - var url = PageProgressBar.GetDeleteAllPageUrl(SiteId, TemplateType.ContentTemplate); - PageUtils.RedirectToLoadingPage(url); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageCreateFile.cs b/SiteServer.BackgroundPages/Cms/PageCreateFile.cs deleted file mode 100644 index b479365ff..000000000 --- a/SiteServer.BackgroundPages/Cms/PageCreateFile.cs +++ /dev/null @@ -1,73 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Settings; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Create; -using SiteServer.Plugin; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageCreateFile : BasePageCms - { - public ListBox LbTemplateIdList; - public Button BtnDeleteAll; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Create); - - var templateInfoList = DataProvider.TemplateDao.GetTemplateInfoListOfFile(SiteId); - - foreach (var templateInfo in templateInfoList) - { - var listitem = new ListItem(templateInfo.CreatedFileFullName, templateInfo.Id.ToString()); - LbTemplateIdList.Items.Add(listitem); - } - - BtnDeleteAll.Attributes.Add("onclick", "return confirm(\"此操作将删除所有已生成的文件页面,确定吗?\");"); - } - - public void Create_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - var templateIdList = new List(); - foreach (ListItem item in LbTemplateIdList.Items) - { - if (!item.Selected) continue; - - var templateId = int.Parse(item.Value); - templateIdList.Add(templateId); - } - - if (templateIdList.Count == 0) - { - FailMessage("请选择需要生成的文件页!"); - return; - } - - foreach (var templateId in templateIdList) - { - CreateManager.CreateFile(SiteId, templateId); - } - - PageCreateStatus.Redirect(SiteId); - } - - public void BtnDeleteAll_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - var url = PageProgressBar.GetDeleteAllPageUrl(SiteId, TemplateType.FileTemplate); - PageUtils.RedirectToLoadingPage(url); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageCreateIndex.cs b/SiteServer.BackgroundPages/Cms/PageCreateIndex.cs deleted file mode 100644 index fcf410f49..000000000 --- a/SiteServer.BackgroundPages/Cms/PageCreateIndex.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Settings; -using SiteServer.CMS.Core.Create; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageCreateIndex : BasePageCms - { - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (!IsPostBack) - { - CreateManager.CreateChannel(SiteId, SiteId); // 创建任务 - PageCreateStatus.Redirect(SiteId); // 转到查询任务进度页面 - } - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageProgressBar.cs b/SiteServer.BackgroundPages/Cms/PageProgressBar.cs deleted file mode 100644 index 67775dc22..000000000 Binary files a/SiteServer.BackgroundPages/Cms/PageProgressBar.cs and /dev/null differ diff --git a/SiteServer.BackgroundPages/Cms/PageTableStyleContent.cs b/SiteServer.BackgroundPages/Cms/PageTableStyleContent.cs deleted file mode 100644 index d02d4ce35..000000000 --- a/SiteServer.BackgroundPages/Cms/PageTableStyleContent.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageTableStyleContent : BasePageCms - { - public DropDownList DdlChannelId; - public Repeater RptContents; - - public Button BtnAddStyle; - public Button BtnAddStyles; - public Button BtnImport; - public Button BtnExport; - - private ChannelInfo _channelInfo; - private string _tableName; - private List _relatedIdentities; - private string _redirectUrl; - - public static string GetRedirectUrl(int siteId, int channelId) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageTableStyleContent), new NameValueCollection - { - {"channelId", channelId.ToString()} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - var channelId = AuthRequest.GetQueryInt("channelId", SiteId); - _channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - _tableName = ChannelManager.GetTableName(SiteInfo, _channelInfo); - _redirectUrl = GetRedirectUrl(SiteId, channelId); - _relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(SiteId, channelId); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); - - //删除样式 - if (AuthRequest.IsQueryExists("DeleteStyle")) - { - var attributeName = AuthRequest.GetQueryString("AttributeName"); - if (TableStyleManager.IsExists(_channelInfo.Id, _tableName, attributeName)) - { - try - { - TableStyleManager.Delete(_channelInfo.Id, _tableName, attributeName); - AuthRequest.AddSiteLog(SiteId, "删除数据表单样式", $"表单:{_tableName},字段:{attributeName}"); - SuccessDeleteMessage(); - } - catch (Exception ex) - { - FailDeleteMessage(ex); - } - } - } - - InfoMessage( - $"在此编辑内容模型字段,子栏目默认继承父栏目字段设置; 辅助表:{DataProvider.TableDao.GetDisplayName(_tableName)}({_tableName})"); - ChannelManager.AddListItems(DdlChannelId.Items, SiteInfo, false, true, AuthRequest.AdminPermissions); - ControlUtils.SelectSingleItem(DdlChannelId, channelId.ToString()); - - RptContents.DataSource = TableStyleManager.GetTableStyleInfoList(_tableName, _relatedIdentities); - RptContents.ItemDataBound += RptContents_ItemDataBound; - RptContents.DataBind(); - - BtnAddStyle.Attributes.Add("onclick", ModalTableStyleAdd.GetOpenWindowString(SiteId, 0, _relatedIdentities, _tableName, string.Empty, _redirectUrl)); - BtnAddStyles.Attributes.Add("onclick", ModalTableStylesAdd.GetOpenWindowString(SiteId, _relatedIdentities, _tableName, _redirectUrl)); - BtnImport.Attributes.Add("onclick", ModalTableStyleImport.GetOpenWindowString(_tableName, SiteId, channelId)); - BtnExport.Attributes.Add("onclick", ModalExportMessage.GetOpenWindowStringToSingleTableStyle(_tableName, SiteId, channelId)); - } - - public void Redirect(object sender, EventArgs e) - { - PageUtils.Redirect(GetRedirectUrl(SiteId, TranslateUtils.ToInt(DdlChannelId.SelectedValue))); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var styleInfo = (TableStyleInfo)e.Item.DataItem; - - var ltlAttributeName = (Literal)e.Item.FindControl("ltlAttributeName"); - var ltlDisplayName = (Literal)e.Item.FindControl("ltlDisplayName"); - var ltlInputType = (Literal)e.Item.FindControl("ltlInputType"); - var ltlFieldType = (Literal)e.Item.FindControl("ltlFieldType"); - var ltlValidate = (Literal)e.Item.FindControl("ltlValidate"); - var ltlTaxis = (Literal)e.Item.FindControl("ltlTaxis"); - var ltlEditStyle = (Literal)e.Item.FindControl("ltlEditStyle"); - var ltlEditValidate = (Literal)e.Item.FindControl("ltlEditValidate"); - - ltlAttributeName.Text = styleInfo.AttributeName; - - ltlDisplayName.Text = styleInfo.DisplayName; - ltlInputType.Text = InputTypeUtils.GetText(styleInfo.InputType); - ltlFieldType.Text = TableMetadataManager.IsAttributeNameExists(_tableName, styleInfo.AttributeName) ? $"真实 {TableMetadataManager.GetTableMetadataDataType(_tableName, styleInfo.AttributeName)}" : "虚拟字段"; - - ltlValidate.Text = TableStyleManager.GetValidateInfo(styleInfo); - - var showPopWinString = ModalTableStyleAdd.GetOpenWindowString(SiteId, styleInfo.Id, _relatedIdentities, _tableName, styleInfo.AttributeName, _redirectUrl); - var editText = styleInfo.RelatedIdentity == _channelInfo.Id ? "修改" : "添加"; - ltlEditStyle.Text = $@"{editText}"; - - showPopWinString = ModalTableStyleValidateAdd.GetOpenWindowString(SiteId, styleInfo.Id, _relatedIdentities, _tableName, styleInfo.AttributeName, _redirectUrl); - ltlEditValidate.Text = $@"设置"; - - ltlTaxis.Text = styleInfo.Taxis.ToString(); - - if (styleInfo.RelatedIdentity != _channelInfo.Id) return; - - var urlStyle = PageUtils.GetCmsUrl(SiteId, nameof(PageTableStyleContent), new NameValueCollection - { - {"channelId", _channelInfo.Id.ToString()}, - {"DeleteStyle", true.ToString()}, - {"TableName", _tableName}, - {"AttributeName", styleInfo.AttributeName} - }); - ltlEditStyle.Text += - $@"  删除"; - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageTableStyleSite.cs b/SiteServer.BackgroundPages/Cms/PageTableStyleSite.cs deleted file mode 100644 index f010579ec..000000000 --- a/SiteServer.BackgroundPages/Cms/PageTableStyleSite.cs +++ /dev/null @@ -1,153 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageTableStyleSite : BasePageCms - { - public Repeater RptContents; - - public Button BtnAddStyle; - public Button BtnAddStyles; - public Button BtnImport; - public Button BtnExport; - public Button BtnReturn; - - private int _relatedIdentity; - private List _relatedIdentities; - private string _tableName; - private int _itemId; - private List _attributeNames; - private string _returnUrl; - - public static string GetRedirectUrl(int siteId, int relatedIdentity, string returnUrl) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageTableStyleSite), new NameValueCollection - { - {"RelatedIdentity", relatedIdentity.ToString()}, - {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} - }); - } - - public static string GetRedirectUrl(int siteId, int relatedIdentity, int itemId, string returnUrl) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageTableStyleSite), new NameValueCollection - { - {"RelatedIdentity", relatedIdentity.ToString()}, - {"ItemID", itemId.ToString()}, - {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - _relatedIdentity = string.IsNullOrEmpty(AuthRequest.GetQueryString("RelatedIdentity")) ? SiteId : AuthRequest.GetQueryInt("RelatedIdentity"); - _tableName = DataProvider.SiteDao.TableName; - _itemId = AuthRequest.GetQueryInt("itemID"); - _relatedIdentities = RelatedIdentities.GetRelatedIdentities(SiteId, _relatedIdentity); - _attributeNames = TableMetadataManager.GetAttributeNameList(_tableName); - _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); - - //删除样式 - if (AuthRequest.IsQueryExists("DeleteStyle")) - { - var attributeName = AuthRequest.GetQueryString("AttributeName"); - if (TableStyleManager.IsExists(_relatedIdentity, _tableName, attributeName)) - { - try - { - TableStyleManager.Delete(_relatedIdentity, _tableName, attributeName); - AuthRequest.AddSiteLog(SiteId, "删除数据表单样式", $"表单:{_tableName},字段:{attributeName}"); - SuccessDeleteMessage(); - } - catch (Exception ex) - { - FailDeleteMessage(ex); - } - } - } - - if (!string.IsNullOrEmpty(_returnUrl)) - { - BtnReturn.Attributes.Add("onclick", $"location.href='{_returnUrl}';return false;"); - } - else - { - BtnReturn.Visible = false; - } - - RptContents.DataSource = TableStyleManager.GetTableStyleInfoList(_tableName, _relatedIdentities); - RptContents.ItemDataBound += RptContents_ItemDataBound; - RptContents.DataBind(); - - var redirectUrl = GetRedirectUrl(SiteId, _relatedIdentity, _itemId, _returnUrl); - - BtnAddStyle.Attributes.Add("onclick", ModalTableStyleAdd.GetOpenWindowString(SiteId, 0, _relatedIdentities, _tableName, string.Empty, redirectUrl)); - BtnAddStyles.Attributes.Add("onclick", ModalTableStylesAdd.GetOpenWindowString(SiteId, _relatedIdentities, _tableName, redirectUrl)); - - BtnImport.Attributes.Add("onclick", ModalTableStyleImport.GetOpenWindowString(_tableName, SiteId, _relatedIdentity)); - BtnExport.Attributes.Add("onclick", ModalExportMessage.GetOpenWindowStringToSingleTableStyle(_tableName, SiteId, _relatedIdentity)); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var styleInfo = (TableStyleInfo)e.Item.DataItem; - - if (_attributeNames.Contains(styleInfo.AttributeName)) - { - e.Item.Visible = false; - return; - } - - var ltlAttributeName = (Literal)e.Item.FindControl("ltlAttributeName"); - var ltlDisplayName = (Literal)e.Item.FindControl("ltlDisplayName"); - var ltlInputType = (Literal)e.Item.FindControl("ltlInputType"); - var ltlValidate = (Literal)e.Item.FindControl("ltlValidate"); - var ltlTaxis = (Literal)e.Item.FindControl("ltlTaxis"); - var ltlEditStyle = (Literal)e.Item.FindControl("ltlEditStyle"); - var ltlEditValidate = (Literal)e.Item.FindControl("ltlEditValidate"); - - ltlAttributeName.Text = styleInfo.AttributeName; - - ltlDisplayName.Text = styleInfo.DisplayName; - ltlInputType.Text = InputTypeUtils.GetText(styleInfo.InputType); - - ltlValidate.Text = TableStyleManager.GetValidateInfo(styleInfo); - - var redirectUrl = GetRedirectUrl(SiteId, _relatedIdentity, _itemId, _returnUrl); - var showPopWinString = ModalTableStyleAdd.GetOpenWindowString(SiteId, styleInfo.Id, _relatedIdentities, _tableName, styleInfo.AttributeName, redirectUrl); - var editText = styleInfo.RelatedIdentity == _relatedIdentity ? "修改" : "设置"; - ltlEditStyle.Text = $@"{editText}"; - - showPopWinString = ModalTableStyleValidateAdd.GetOpenWindowString(SiteId, styleInfo.Id, _relatedIdentities, _tableName, styleInfo.AttributeName, redirectUrl); - ltlEditValidate.Text = $@"设置"; - - ltlTaxis.Text = styleInfo.Taxis.ToString(); - - if (styleInfo.RelatedIdentity != _relatedIdentity) return; - - var urlStyle = PageUtils.GetCmsUrl(SiteId, nameof(PageTableStyleSite), new NameValueCollection - { - {"TableName", _tableName}, - {"RelatedIdentity", _relatedIdentity.ToString()}, - {"DeleteStyle", true.ToString()}, - {"AttributeName", styleInfo.AttributeName} - }); - ltlEditStyle.Text += - $@"  删除"; - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageTemplateCss.cs b/SiteServer.BackgroundPages/Cms/PageTemplateCss.cs deleted file mode 100644 index 80054e222..000000000 --- a/SiteServer.BackgroundPages/Cms/PageTemplateCss.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageTemplateCss : BasePageCms - { - public Repeater RptContents; - public Button BtnAdd; - - private string _directoryPath; - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageTemplateCss), null); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - _directoryPath = PathUtility.MapPath(SiteInfo, "@/css"); - - if (AuthRequest.IsQueryExists("Delete")) - { - var fileName = AuthRequest.GetQueryString("FileName"); - - try - { - FileUtils.DeleteFileIfExists(PathUtils.Combine(_directoryPath, fileName)); - AuthRequest.AddSiteLog(SiteId, "删除样式文件", $"样式文件:{fileName}"); - SuccessDeleteMessage(); - } - catch (Exception ex) - { - FailDeleteMessage(ex); - } - } - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Template); - - DirectoryUtils.CreateDirectoryIfNotExists(_directoryPath); - var fileNames = DirectoryUtils.GetFileNames(_directoryPath); - var fileNameList = new List(); - foreach (var fileName in fileNames) - { - if (EFileSystemTypeUtils.IsTextEditable(EFileSystemTypeUtils.GetEnumType(PathUtils.GetExtension(fileName)))) - { - if (!fileName.Contains("_parsed")) - { - fileNameList.Add(fileName); - } - } - } - - RptContents.DataSource = fileNameList; - RptContents.ItemDataBound += RptContents_ItemDataBound; - RptContents.DataBind(); - - BtnAdd.Attributes.Add("onclick", $"location.href='{PageTemplateCssAdd.GetRedirectUrl(SiteId)}';return false"); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var fileName = (string) e.Item.DataItem; - - var ltlFileName = (Literal)e.Item.FindControl("ltlFileName"); - var ltlCharset = (Literal)e.Item.FindControl("ltlCharset"); - var ltlView = (Literal)e.Item.FindControl("ltlView"); - var ltlEdit = (Literal)e.Item.FindControl("ltlEdit"); - var ltlDelete = (Literal)e.Item.FindControl("ltlDelete"); - - ltlFileName.Text = fileName; - - var charset = FileUtils.GetFileCharset(PathUtils.Combine(_directoryPath, fileName)); - ltlCharset.Text = ECharsetUtils.GetText(charset); - - ltlView.Text = $@"查看"; - ltlEdit.Text = - $@"编辑"; - ltlDelete.Text = - $@"删除"; - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageTemplateCssAdd.cs b/SiteServer.BackgroundPages/Cms/PageTemplateCssAdd.cs deleted file mode 100644 index 66dec1718..000000000 --- a/SiteServer.BackgroundPages/Cms/PageTemplateCssAdd.cs +++ /dev/null @@ -1,160 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageTemplateCssAdd : BasePageCms - { - public Literal LtlPageTitle; - public TextBox TbRelatedFileName; - public DropDownList DdlCharset; - public TextBox TbContent; - public PlaceHolder PhCodeMirror; - public Button BtnEditorType; - - private string _fileName; - private string _directoryPath; - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageTemplateCssAdd), null); - } - - public static string GetRedirectUrl(int siteId, string fileName) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageTemplateCssAdd), new NameValueCollection - { - {"FileName", fileName} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (AuthRequest.IsQueryExists("FileName")) - { - _fileName = AuthRequest.GetQueryString("FileName"); - _fileName = PathUtils.RemoveParentPath(_fileName); - } - _directoryPath = PathUtility.MapPath(SiteInfo, "@/css"); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Template); - - LtlPageTitle.Text = string.IsNullOrEmpty(_fileName) ? "添加样式文件" : "编辑样式文件"; - - var isCodeMirror = SiteInfo.Additional.ConfigTemplateIsCodeMirror; - BtnEditorType.Text = isCodeMirror ? "采用纯文本编辑模式" : "采用代码编辑模式"; - PhCodeMirror.Visible = isCodeMirror; - - ECharsetUtils.AddListItems(DdlCharset); - - if (_fileName != null) - { - if (!EFileSystemTypeUtils.IsCss(PathUtils.GetExtension(_fileName))) - { - PageUtils.RedirectToErrorPage("对不起,此文件无法编辑!"); - } - else - { - TbRelatedFileName.Text = PathUtils.RemoveExtension(_fileName); - var fileCharset = FileUtils.GetFileCharset(PathUtils.Combine(_directoryPath, _fileName)); - ControlUtils.SelectSingleItemIgnoreCase(DdlCharset, ECharsetUtils.GetValue(fileCharset)); - TbContent.Text = FileUtils.ReadText(PathUtils.Combine(_directoryPath, _fileName), fileCharset); - } - } - else - { - ControlUtils.SelectSingleItemIgnoreCase(DdlCharset, SiteInfo.Additional.Charset); - } - } - - public void EditorType_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - var isCodeMirror = SiteInfo.Additional.ConfigTemplateIsCodeMirror; - isCodeMirror = !isCodeMirror; - SiteInfo.Additional.ConfigTemplateIsCodeMirror = isCodeMirror; - DataProvider.SiteDao.Update(SiteInfo); - - BtnEditorType.Text = isCodeMirror ? "采用纯文本编辑模式" : "采用代码编辑模式"; - PhCodeMirror.Visible = isCodeMirror; - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - if (_fileName != null) - { - var isChanged = false; - if (PathUtils.RemoveExtension(_fileName) != PathUtils.RemoveExtension(TbRelatedFileName.Text))//文件名改变 - { - var fileNames = DirectoryUtils.GetFileNames(_directoryPath); - foreach (var theFileName in fileNames) - { - var fileNameWithoutExtension = PathUtils.RemoveExtension(theFileName); - if (fileNameWithoutExtension == TbRelatedFileName.Text.ToLower()) - { - FailMessage("样式文件修改失败,样式文件已存在!"); - return; - } - } - - isChanged = true; - } - - var previousFileName = string.Empty; - if (isChanged) - { - previousFileName = _fileName; - } - - var currentFileName = TbRelatedFileName.Text + ".css"; - var charset = ECharsetUtils.GetEnumType(DdlCharset.SelectedValue); - FileUtils.WriteText(PathUtils.Combine(_directoryPath, currentFileName), charset, TbContent.Text); - if (!string.IsNullOrEmpty(previousFileName)) - { - FileUtils.DeleteFileIfExists(PathUtils.Combine(_directoryPath, previousFileName)); - } - AuthRequest.AddSiteLog(SiteId, "修改样式文件", $"样式文件:{currentFileName}"); - SuccessMessage("样式文件修改成功!"); - AddWaitAndRedirectScript(PageTemplateCss.GetRedirectUrl(SiteId)); - } - else - { - var currentFileName = TbRelatedFileName.Text + ".css"; - - var fileNames = DirectoryUtils.GetFileNames(_directoryPath); - foreach (var theFileName in fileNames) - { - if (StringUtils.EqualsIgnoreCase(theFileName, currentFileName)) - { - FailMessage("样式文件添加失败,样式文件文件已存在!"); - return; - } - } - - var charset = ECharsetUtils.GetEnumType(DdlCharset.SelectedValue); - FileUtils.WriteText(PathUtils.Combine(_directoryPath, currentFileName), charset, TbContent.Text); - AuthRequest.AddSiteLog(SiteId, "添加样式文件", $"样式文件:{currentFileName}"); - SuccessMessage("样式文件添加成功!"); - AddWaitAndRedirectScript(PageTemplateCss.GetRedirectUrl(SiteId)); - } - } - - public void Return_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(PageTemplateCss.GetRedirectUrl(SiteId)); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageTemplateInclude.cs b/SiteServer.BackgroundPages/Cms/PageTemplateInclude.cs deleted file mode 100644 index 7fb8e1623..000000000 --- a/SiteServer.BackgroundPages/Cms/PageTemplateInclude.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageTemplateInclude : BasePageCms - { - public Repeater RptContents; - public Button BtnAdd; - - private string _directoryPath; - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageTemplateInclude), null); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - _directoryPath = PathUtility.MapPath(SiteInfo, "@/include"); - - if (AuthRequest.IsQueryExists("Delete")) - { - var fileName = AuthRequest.GetQueryString("FileName"); - - try - { - FileUtils.DeleteFileIfExists(PathUtils.Combine(_directoryPath, fileName)); - AuthRequest.AddSiteLog(SiteId, "删除包含文件", $"包含文件:{fileName}"); - SuccessDeleteMessage(); - } - catch (Exception ex) - { - FailDeleteMessage(ex); - } - } - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Template); - - DirectoryUtils.CreateDirectoryIfNotExists(_directoryPath); - var fileNames = DirectoryUtils.GetFileNames(_directoryPath); - var fileNameList = new List(); - foreach (var fileName in fileNames) - { - if (EFileSystemTypeUtils.IsTextEditable(EFileSystemTypeUtils.GetEnumType(PathUtils.GetExtension(fileName)))) - { - if (!fileName.Contains("_parsed")) - { - fileNameList.Add(fileName); - } - } - } - - RptContents.DataSource = fileNameList; - RptContents.ItemDataBound += RptContents_ItemDataBound; - RptContents.DataBind(); - - BtnAdd.Attributes.Add("onclick", $"location.href='{PageTemplateIncludeAdd.GetRedirectUrl(SiteId)}';return false"); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var fileName = (string)e.Item.DataItem; - - var ltlFileName = (Literal)e.Item.FindControl("ltlFileName"); - var ltlCharset = (Literal)e.Item.FindControl("ltlCharset"); - var ltlEdit = (Literal)e.Item.FindControl("ltlEdit"); - var ltlDelete = (Literal)e.Item.FindControl("ltlDelete"); - - ltlFileName.Text = fileName; - - var charset = FileUtils.GetFileCharset(PathUtils.Combine(_directoryPath, fileName)); - ltlCharset.Text = ECharsetUtils.GetText(charset); - - ltlEdit.Text = - $@"编辑"; - ltlDelete.Text = - $@"删除"; - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageTemplateIncludeAdd.cs b/SiteServer.BackgroundPages/Cms/PageTemplateIncludeAdd.cs deleted file mode 100644 index 8400089ff..000000000 --- a/SiteServer.BackgroundPages/Cms/PageTemplateIncludeAdd.cs +++ /dev/null @@ -1,168 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageTemplateIncludeAdd : BasePageCms - { - public Literal LtlPageTitle; - public TextBox TbRelatedFileName; - public Literal LtlCreatedFileExtName; - public DropDownList DdlCharset; - public TextBox TbContent; - public PlaceHolder PhCodeMirror; - public Button BtnEditorType; - - private string _fileName; - private string _directoryPath; - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageTemplateIncludeAdd), null); - } - - public static string GetRedirectUrl(int siteId, string fileName) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageTemplateIncludeAdd), new NameValueCollection - { - {"FileName", fileName} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (AuthRequest.IsQueryExists("FileName")) - { - _fileName = AuthRequest.GetQueryString("FileName"); - _fileName = PathUtils.RemoveParentPath(_fileName); - } - _directoryPath = PathUtility.MapPath(SiteInfo, "@/include"); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Template); - - LtlPageTitle.Text = string.IsNullOrEmpty(_fileName) ? "添加包含文件" : "编辑包含文件"; - - var isCodeMirror = SiteInfo.Additional.ConfigTemplateIsCodeMirror; - BtnEditorType.Text = isCodeMirror ? "采用纯文本编辑模式" : "采用代码编辑模式"; - PhCodeMirror.Visible = isCodeMirror; - - ECharsetUtils.AddListItems(DdlCharset); - - if (_fileName != null) - { - if (!EFileSystemTypeUtils.IsHtml(PathUtils.GetExtension(_fileName))) - { - PageUtils.RedirectToErrorPage("对不起,此文件无法编辑!"); - } - else - { - TbRelatedFileName.Text = PathUtils.RemoveExtension(_fileName); - LtlCreatedFileExtName.Text = PathUtils.GetExtension(_fileName); - var fileCharset = FileUtils.GetFileCharset(PathUtils.Combine(_directoryPath, _fileName)); - ControlUtils.SelectSingleItemIgnoreCase(DdlCharset, ECharsetUtils.GetValue(fileCharset)); - TbContent.Text = FileUtils.ReadText(PathUtils.Combine(_directoryPath, _fileName), fileCharset); - } - } - else - { - LtlCreatedFileExtName.Text = ".html"; - ControlUtils.SelectSingleItemIgnoreCase(DdlCharset, SiteInfo.Additional.Charset); - } - } - - public void EditorType_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - var isCodeMirror = SiteInfo.Additional.ConfigTemplateIsCodeMirror; - isCodeMirror = !isCodeMirror; - SiteInfo.Additional.ConfigTemplateIsCodeMirror = isCodeMirror; - DataProvider.SiteDao.Update(SiteInfo); - - BtnEditorType.Text = isCodeMirror ? "采用纯文本编辑模式" : "采用代码编辑模式"; - PhCodeMirror.Visible = isCodeMirror; - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - if (_fileName != null) - { - var isChanged = false; - if (PathUtils.RemoveExtension(_fileName) != PathUtils.RemoveExtension(TbRelatedFileName.Text))//文件名改变 - { - var fileNames = DirectoryUtils.GetFileNames(_directoryPath); - foreach (var theFileName in fileNames) - { - var fileNameWithoutExtension = PathUtils.RemoveExtension(theFileName); - if (fileNameWithoutExtension == TbRelatedFileName.Text.ToLower()) - { - FailMessage("包含文件修改失败,包含文件已存在!"); - return; - } - } - - isChanged = true; - } - - if (PathUtils.GetExtension(_fileName) != LtlCreatedFileExtName.Text)//文件后缀改变 - { - isChanged = true; - } - - var previousFileName = string.Empty; - if (isChanged) - { - previousFileName = _fileName; - } - - var currentFileName = TbRelatedFileName.Text + LtlCreatedFileExtName.Text; - var charset = ECharsetUtils.GetEnumType(DdlCharset.SelectedValue); - FileUtils.WriteText(PathUtils.Combine(_directoryPath, currentFileName), charset, TbContent.Text); - if (!string.IsNullOrEmpty(previousFileName)) - { - FileUtils.DeleteFileIfExists(PathUtils.Combine(_directoryPath, previousFileName)); - } - AuthRequest.AddSiteLog(SiteId, "修改包含文件", $"包含文件:{currentFileName}"); - SuccessMessage("包含文件修改成功!"); - AddWaitAndRedirectScript(PageTemplateInclude.GetRedirectUrl(SiteId)); - } - else - { - var currentFileName = TbRelatedFileName.Text + LtlCreatedFileExtName.Text; - - var fileNames = DirectoryUtils.GetFileNames(_directoryPath); - foreach (var theFileName in fileNames) - { - if (StringUtils.EqualsIgnoreCase(theFileName, currentFileName)) - { - FailMessage("包含文件添加失败,包含文件文件已存在!"); - return; - } - } - - var charset = ECharsetUtils.GetEnumType(DdlCharset.SelectedValue); - FileUtils.WriteText(PathUtils.Combine(_directoryPath, currentFileName), charset, TbContent.Text); - AuthRequest.AddSiteLog(SiteId, "添加包含文件", $"包含文件:{currentFileName}"); - SuccessMessage("包含文件添加成功!"); - AddWaitAndRedirectScript(PageTemplateInclude.GetRedirectUrl(SiteId)); - } - } - - public void Return_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(PageTemplateInclude.GetRedirectUrl(SiteId)); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageTemplateJs.cs b/SiteServer.BackgroundPages/Cms/PageTemplateJs.cs deleted file mode 100644 index 10b418233..000000000 --- a/SiteServer.BackgroundPages/Cms/PageTemplateJs.cs +++ /dev/null @@ -1,96 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageTemplateJs : BasePageCms - { - public Repeater RptContents; - public Button BtnAdd; - - private string _directoryPath; - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageTemplateJs), null); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - _directoryPath = PathUtility.MapPath(SiteInfo, "@/js"); - - if (AuthRequest.IsQueryExists("Delete")) - { - var fileName = AuthRequest.GetQueryString("FileName"); - - try - { - FileUtils.DeleteFileIfExists(PathUtils.Combine(_directoryPath, fileName)); - AuthRequest.AddSiteLog(SiteId, "删除脚本文件", $"脚本文件:{fileName}"); - SuccessDeleteMessage(); - } - catch (Exception ex) - { - FailDeleteMessage(ex); - } - } - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Template); - - DirectoryUtils.CreateDirectoryIfNotExists(_directoryPath); - var fileNames = DirectoryUtils.GetFileNames(_directoryPath); - var fileNameList = new List(); - foreach (var fileName in fileNames) - { - if (EFileSystemTypeUtils.IsTextEditable(EFileSystemTypeUtils.GetEnumType(PathUtils.GetExtension(fileName)))) - { - if (!fileName.Contains("_parsed")) - { - fileNameList.Add(fileName); - } - } - } - - RptContents.DataSource = fileNameList; - RptContents.ItemDataBound += RptContents_ItemDataBound; - RptContents.DataBind(); - - BtnAdd.Attributes.Add("onclick", $"location.href='{PageTemplateJsAdd.GetRedirectUrl(SiteId)}';return false"); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var fileName = (string)e.Item.DataItem; - - var ltlFileName = (Literal)e.Item.FindControl("ltlFileName"); - var ltlCharset = (Literal)e.Item.FindControl("ltlCharset"); - var ltlView = (Literal)e.Item.FindControl("ltlView"); - var ltlEdit = (Literal)e.Item.FindControl("ltlEdit"); - var ltlDelete = (Literal)e.Item.FindControl("ltlDelete"); - - ltlFileName.Text = fileName; - - var charset = FileUtils.GetFileCharset(PathUtils.Combine(_directoryPath, fileName)); - ltlCharset.Text = ECharsetUtils.GetText(charset); - - ltlView.Text = $@"查看"; - ltlEdit.Text = - $@"编辑"; - ltlDelete.Text = - $@"删除"; - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageTemplateJsAdd.cs b/SiteServer.BackgroundPages/Cms/PageTemplateJsAdd.cs deleted file mode 100644 index 1e9a7b046..000000000 --- a/SiteServer.BackgroundPages/Cms/PageTemplateJsAdd.cs +++ /dev/null @@ -1,160 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageTemplateJsAdd : BasePageCms - { - public Literal LtlPageTitle; - public TextBox TbRelatedFileName; - public DropDownList DdlCharset; - public TextBox TbContent; - public PlaceHolder PhCodeMirror; - public Button BtnEditorType; - - private string _fileName; - private string _directoryPath; - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageTemplateJsAdd), null); - } - - public static string GetRedirectUrl(int siteId, string fileName) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageTemplateJsAdd), new NameValueCollection - { - {"FileName", fileName} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (AuthRequest.IsQueryExists("FileName")) - { - _fileName = AuthRequest.GetQueryString("FileName"); - _fileName = PathUtils.RemoveParentPath(_fileName); - } - _directoryPath = PathUtility.MapPath(SiteInfo, "@/js"); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Template); - - LtlPageTitle.Text = string.IsNullOrEmpty(_fileName) ? "添加脚本文件" : "编辑脚本文件"; - - var isCodeMirror = SiteInfo.Additional.ConfigTemplateIsCodeMirror; - BtnEditorType.Text = isCodeMirror ? "采用纯文本编辑模式" : "采用代码编辑模式"; - PhCodeMirror.Visible = isCodeMirror; - - ECharsetUtils.AddListItems(DdlCharset); - - if (_fileName != null) - { - if (!EFileSystemTypeUtils.IsJs(PathUtils.GetExtension(_fileName))) - { - PageUtils.RedirectToErrorPage("对不起,此文件无法编辑!"); - } - else - { - TbRelatedFileName.Text = PathUtils.RemoveExtension(_fileName); - var fileCharset = FileUtils.GetFileCharset(PathUtils.Combine(_directoryPath, _fileName)); - ControlUtils.SelectSingleItemIgnoreCase(DdlCharset, ECharsetUtils.GetValue(fileCharset)); - TbContent.Text = FileUtils.ReadText(PathUtils.Combine(_directoryPath, _fileName), fileCharset); - } - } - else - { - ControlUtils.SelectSingleItemIgnoreCase(DdlCharset, SiteInfo.Additional.Charset); - } - } - - public void EditorType_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - var isCodeMirror = SiteInfo.Additional.ConfigTemplateIsCodeMirror; - isCodeMirror = !isCodeMirror; - SiteInfo.Additional.ConfigTemplateIsCodeMirror = isCodeMirror; - DataProvider.SiteDao.Update(SiteInfo); - - BtnEditorType.Text = isCodeMirror ? "采用纯文本编辑模式" : "采用代码编辑模式"; - PhCodeMirror.Visible = isCodeMirror; - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - if (_fileName != null) - { - var isChanged = false; - if (PathUtils.RemoveExtension(_fileName) != PathUtils.RemoveExtension(TbRelatedFileName.Text))//文件名改变 - { - var fileNames = DirectoryUtils.GetFileNames(_directoryPath); - foreach (var theFileName in fileNames) - { - var fileNameWithoutExtension = PathUtils.RemoveExtension(theFileName); - if (fileNameWithoutExtension == TbRelatedFileName.Text.ToLower()) - { - FailMessage("脚本文件修改失败,脚本文件已存在!"); - return; - } - } - - isChanged = true; - } - - var previousFileName = string.Empty; - if (isChanged) - { - previousFileName = _fileName; - } - - var currentFileName = TbRelatedFileName.Text + ".js"; - var charset = ECharsetUtils.GetEnumType(DdlCharset.SelectedValue); - FileUtils.WriteText(PathUtils.Combine(_directoryPath, currentFileName), charset, TbContent.Text); - if (!string.IsNullOrEmpty(previousFileName)) - { - FileUtils.DeleteFileIfExists(PathUtils.Combine(_directoryPath, previousFileName)); - } - AuthRequest.AddSiteLog(SiteId, "修改脚本文件", $"脚本文件:{currentFileName}"); - SuccessMessage("脚本文件修改成功!"); - AddWaitAndRedirectScript(PageTemplateJs.GetRedirectUrl(SiteId)); - } - else - { - var currentFileName = TbRelatedFileName.Text + ".js"; - - var fileNames = DirectoryUtils.GetFileNames(_directoryPath); - foreach (var theFileName in fileNames) - { - if (StringUtils.EqualsIgnoreCase(theFileName, currentFileName)) - { - FailMessage("脚本文件添加失败,脚本文件文件已存在!"); - return; - } - } - - var charset = ECharsetUtils.GetEnumType(DdlCharset.SelectedValue); - FileUtils.WriteText(PathUtils.Combine(_directoryPath, currentFileName), charset, TbContent.Text); - AuthRequest.AddSiteLog(SiteId, "添加脚本文件", $"脚本文件:{currentFileName}"); - SuccessMessage("脚本文件添加成功!"); - AddWaitAndRedirectScript(PageTemplateJs.GetRedirectUrl(SiteId)); - } - } - - public void Return_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(PageTemplateJs.GetRedirectUrl(SiteId)); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageTemplateMatch.cs b/SiteServer.BackgroundPages/Cms/PageTemplateMatch.cs deleted file mode 100644 index 8f6ea0afe..000000000 --- a/SiteServer.BackgroundPages/Cms/PageTemplateMatch.cs +++ /dev/null @@ -1,483 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageTemplateMatch : BasePageCms - { - public ListBox LbChannelId; - public ListBox LbChannelTemplateId; - public ListBox LbContentTemplateId; - public Button BtnCreateChannelTemplate; - public Button BtnCreateSubChannelTemplate; - public Button BtnCreateContentTemplate; - public Button BtnCreateSubContentTemplate; - - private bool[] _isLastNodeArray; - private string _defaultChannelTemplateName; - private string _defaultContentTemplateName; - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetCmsUrl(siteId, nameof(PageTemplateMatch), null); - } - - public string GetTitle(ChannelInfo nodeInfo) - { - var str = string.Empty; - if (nodeInfo.Id == SiteId) - { - nodeInfo.IsLastNode = true; - } - if (nodeInfo.IsLastNode == false) - { - _isLastNodeArray[nodeInfo.ParentsCount] = false; - } - else - { - _isLastNodeArray[nodeInfo.ParentsCount] = true; - } - for (var i = 0; i < nodeInfo.ParentsCount; i++) - { - str = string.Concat(str, _isLastNodeArray[i] ? " " : "│"); - } - str = string.Concat(str, nodeInfo.IsLastNode ? "└" : "├"); - str = string.Concat(str, StringUtils.MaxLengthText(nodeInfo.ChannelName, 8)); - - if (nodeInfo.ParentId == 0) - { - var indexTemplateId = TemplateManager.GetDefaultTemplateId(SiteId, TemplateType.IndexPageTemplate); - var indexTemplateName = TemplateManager.GetTemplateName(SiteId, indexTemplateId); - str = string.Concat(str, $" ({indexTemplateName})"); - } - else - { - var channelTemplateId = nodeInfo.ChannelTemplateId; - var contentTemplateId = nodeInfo.ContentTemplateId; - - var channelTemplateName = string.Empty; - if (channelTemplateId != 0) - { - channelTemplateName = TemplateManager.GetTemplateName(SiteId, channelTemplateId); - } - if (string.IsNullOrEmpty(channelTemplateName)) - { - channelTemplateName = _defaultChannelTemplateName; - } - str = string.Concat(str, $" ({channelTemplateName})"); - - var contentTemplateName = string.Empty; - if (contentTemplateId != 0) - { - contentTemplateName = TemplateManager.GetTemplateName(SiteId, contentTemplateId); - } - if (string.IsNullOrEmpty(contentTemplateName)) - { - contentTemplateName = _defaultContentTemplateName; - } - str = string.Concat(str, $" ({contentTemplateName})"); - } - - return str; - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - var defaultChannelTemplateId = TemplateManager.GetDefaultTemplateId(SiteId, TemplateType.ChannelTemplate); - _defaultChannelTemplateName = TemplateManager.GetTemplateName(SiteId, defaultChannelTemplateId); - - var defaultContentTemplateId = TemplateManager.GetDefaultTemplateId(SiteId, TemplateType.ContentTemplate); - _defaultContentTemplateName = TemplateManager.GetTemplateName(SiteId, defaultContentTemplateId); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Template); - - LbChannelTemplateId.Attributes.Add("onfocus", "$('#LbContentTemplateId option:selected').removeAttr('selected')"); - LbContentTemplateId.Attributes.Add("onfocus", "$('#LbChannelTemplateId option:selected').removeAttr('selected')"); - - BindListBox(); - - BtnCreateChannelTemplate.OnClientClick = $"{AlertUtils.Confirm("创建栏目模板", "此操作将创建空的栏目模板并匹配选中栏目,确认吗?", "创 建", "$('#BtnCreateChannelTemplateReal').click()")}"; - BtnCreateSubChannelTemplate.OnClientClick = $"{AlertUtils.Confirm("创建下级栏目模版", "此操作将创建空的栏目模板并匹配选中栏目的下级栏目,确认吗?", "创 建", "$('#BtnCreateSubChannelTemplateReal').click()")}"; - BtnCreateContentTemplate.OnClientClick = $"{AlertUtils.Confirm("创建内容模版", "此操作将创建空的内容模板并匹配选中栏目,确认吗?", "创 建", "$('#BtnCreateContentTemplateReal').click()")}"; - BtnCreateSubContentTemplate.OnClientClick = $"{AlertUtils.Confirm("创建下级内容模版", "此操作将创建空的内容模板并匹配选中栏目的下级栏目,确认吗?", "创 建", "$('#BtnCreateSubContentTemplateReal').click()")}"; - } - - - public void BindListBox() - { - var selectedChannelIdList = new List(); - foreach (ListItem listitem in LbChannelId.Items) - { - if (listitem.Selected) selectedChannelIdList.Add(listitem.Value); - } - var selectedChannelTemplateId = LbChannelTemplateId.SelectedValue; - var selectedContentTemplateId = LbContentTemplateId.SelectedValue; - - LbChannelId.Items.Clear(); - LbChannelTemplateId.Items.Clear(); - LbContentTemplateId.Items.Clear(); - var channelIdList = ChannelManager.GetChannelIdList(SiteId); - var nodeCount = channelIdList.Count; - _isLastNodeArray = new bool[nodeCount]; - foreach (var theChannelId in channelIdList) - { - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, theChannelId); - var listitem = new ListItem(GetTitle(nodeInfo), nodeInfo.Id.ToString()); - LbChannelId.Items.Add(listitem); - } - - LbChannelTemplateId.DataSource = DataProvider.TemplateDao.GetDataSourceByType(SiteId, TemplateType.ChannelTemplate); - LbContentTemplateId.DataSource = DataProvider.TemplateDao.GetDataSourceByType(SiteId, TemplateType.ContentTemplate); - DataBind(); - - ControlUtils.SelectMultiItems(LbChannelId, selectedChannelIdList); - ControlUtils.SelectSingleItem(LbChannelTemplateId, selectedChannelTemplateId); - ControlUtils.SelectSingleItem(LbContentTemplateId, selectedContentTemplateId); - } - - public void MatchChannelTemplateButton_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid || !Validate(true, true)) return; - - var channelIdList = new List(); - foreach (ListItem item in LbChannelId.Items) - { - if (item.Selected) - { - var channelId = int.Parse(item.Value); - channelIdList.Add(channelId); - } - } - var channelTemplateId = int.Parse(LbChannelTemplateId.SelectedValue); - Process(channelIdList, channelTemplateId, true); - } - - public void RemoveChannelTemplateButton_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid || !Validate(false, true)) return; - - var channelIdList = new List(); - foreach (ListItem item in LbChannelId.Items) - { - if (item.Selected) - { - var channelId = int.Parse(item.Value); - channelIdList.Add(channelId); - } - } - Process(channelIdList, 0, true); - } - - public void MatchContentTemplateButton_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid || !Validate(true, false)) return; - - var channelIdList = new List(); - foreach (ListItem item in LbChannelId.Items) - { - if (item.Selected) - { - var channelId = int.Parse(item.Value); - channelIdList.Add(channelId); - } - } - var contentTemplateId = int.Parse(LbContentTemplateId.SelectedValue); - Process(channelIdList, contentTemplateId, false); - } - - public void RemoveContentTemplateButton_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid || !Validate(false, false)) return; - - var channelIdList = new List(); - foreach (ListItem item in LbChannelId.Items) - { - if (item.Selected) - { - var channelId = int.Parse(item.Value); - channelIdList.Add(channelId); - } - } - Process(channelIdList, 0, false); - } - - private bool Validate(bool isMatch, bool isChannelTemplate) - { - if (LbChannelId.SelectedIndex < 0) - { - FailMessage("请选择栏目!"); - return false; - } - if (isMatch) - { - if (isChannelTemplate) - { - if (LbChannelTemplateId.SelectedIndex < 0) - { - FailMessage("请选择栏目模板!"); - return false; - } - } - else - { - if (LbContentTemplateId.SelectedIndex < 0) - { - FailMessage("请选择内容模板!"); - return false; - } - } - } - return true; - } - - private void Process(List channelIdList, int templateId, bool isChannelTemplate) - { - if (channelIdList != null && channelIdList.Count > 0) - { - if (isChannelTemplate) - { - foreach (var channelId in channelIdList) - { - TemplateManager.UpdateChannelTemplateId(SiteId, channelId, templateId); - } - } - else - { - foreach (var channelId in channelIdList) - { - TemplateManager.UpdateContentTemplateId(SiteId, channelId, templateId); - } - } - } - - if (templateId == 0) - { - AuthRequest.AddSiteLog(SiteId, "取消模板匹配", $"栏目:{GetNodeNames()}"); - SuccessMessage("取消匹配成功!"); - } - else - { - AuthRequest.AddSiteLog(SiteId, "模板匹配", $"栏目:{GetNodeNames()}"); - SuccessMessage("模板匹配成功!"); - } - - BindListBox(); - } - - private string GetNodeNames() - { - var builder = new StringBuilder(); - foreach (ListItem listItem in LbChannelId.Items) - { - if (listItem.Selected) - { - builder.Append(listItem.Text).Append(","); - } - } - - if (builder.Length > 0) - { - builder.Length = builder.Length - 1; - } - - return RegexUtils.Replace("\\(.*?\\)|│|├| |└", builder.ToString(), string.Empty); - } - - public void CreateChannelTemplate_Click(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid || !Validate(false, false)) return; - - var defaultChannelTemplateId = TemplateManager.GetDefaultTemplateId(SiteId, TemplateType.ChannelTemplate); - var relatedFileNameList = DataProvider.TemplateDao.GetLowerRelatedFileNameList(SiteId, TemplateType.ChannelTemplate); - var templateNameList = DataProvider.TemplateDao.GetTemplateNameList(SiteId, TemplateType.ChannelTemplate); - foreach (ListItem item in LbChannelId.Items) - { - if (!item.Selected) continue; - - var channelId = int.Parse(item.Value); - var channelTemplateId = -1; - - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - if (nodeInfo.ParentId > 0) - { - channelTemplateId = nodeInfo.ChannelTemplateId; - } - - if (channelTemplateId != -1 && channelTemplateId != 0 && channelTemplateId != defaultChannelTemplateId) - { - if (TemplateManager.GetTemplateInfo(SiteId, channelTemplateId) == null) - { - channelTemplateId = -1; - } - } - - if (channelTemplateId != -1) - { - var templateInfo = new TemplateInfo(0, SiteId, nodeInfo.ChannelName, TemplateType.ChannelTemplate, "T_" + nodeInfo.ChannelName + ".html", "index.html", ".html", ECharsetUtils.GetEnumType(SiteInfo.Additional.Charset), false); - - if (relatedFileNameList.Contains(templateInfo.RelatedFileName.ToLower())) - { - continue; - } - if (templateNameList.Contains(templateInfo.TemplateName)) - { - continue; - } - var insertedTemplateId = DataProvider.TemplateDao.Insert(templateInfo, string.Empty, AuthRequest.AdminName); - if (nodeInfo.ParentId > 0) - { - TemplateManager.UpdateChannelTemplateId(SiteId, channelId, insertedTemplateId); - //DataProvider.BackgroundNodeDAO.UpdateChannelTemplateID(channelId, insertedTemplateID); - } - - } - } - - AuthRequest.AddSiteLog(SiteId, "生成并匹配栏目模版", $"栏目:{GetNodeNames()}"); - - SuccessMessage("生成栏目模版并匹配成功!"); - - BindListBox(); - } - - public void CreateSubChannelTemplate_Click(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid || !Validate(false, false)) return; - - var relatedFileNameList = DataProvider.TemplateDao.GetLowerRelatedFileNameList(SiteId, TemplateType.ChannelTemplate); - var templateNameList = DataProvider.TemplateDao.GetTemplateNameList(SiteId, TemplateType.ChannelTemplate); - foreach (ListItem item in LbChannelId.Items) - { - if (!item.Selected) continue; - - var channelId = int.Parse(item.Value); - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - - var templateInfo = new TemplateInfo(0, SiteId, nodeInfo.ChannelName + "_下级", TemplateType.ChannelTemplate, "T_" + nodeInfo.ChannelName + "_下级.html", "index.html", ".html", ECharsetUtils.GetEnumType(SiteInfo.Additional.Charset), false); - - if (relatedFileNameList.Contains(templateInfo.RelatedFileName.ToLower())) - { - continue; - } - if (templateNameList.Contains(templateInfo.TemplateName)) - { - continue; - } - var insertedTemplateId = DataProvider.TemplateDao.Insert(templateInfo, string.Empty, AuthRequest.AdminName); - var childChannelIdList = ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(SiteId, channelId), EScopeType.Descendant, string.Empty, string.Empty, string.Empty); - foreach (var childChannelId in childChannelIdList) - { - TemplateManager.UpdateChannelTemplateId(SiteId, childChannelId, insertedTemplateId); - //DataProvider.BackgroundNodeDAO.UpdateChannelTemplateID(childChannelId, insertedTemplateID); - } - } - - AuthRequest.AddSiteLog(SiteId, "生成并匹配下级栏目模版", $"栏目:{GetNodeNames()}"); - - SuccessMessage("生成下级栏目模版并匹配成功!"); - - BindListBox(); - } - - public void CreateContentTemplate_Click(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid || !Validate(false, false)) return; - - var defaultContentTemplateId = TemplateManager.GetDefaultTemplateId(SiteId, TemplateType.ContentTemplate); - var relatedFileNameList = DataProvider.TemplateDao.GetLowerRelatedFileNameList(SiteId, TemplateType.ContentTemplate); - var templateNameList = DataProvider.TemplateDao.GetTemplateNameList(SiteId, TemplateType.ContentTemplate); - foreach (ListItem item in LbChannelId.Items) - { - if (!item.Selected) continue; - - var channelId = TranslateUtils.ToInt(item.Value); - - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - - var contentTemplateId = nodeInfo.ContentTemplateId; - - if (contentTemplateId != 0 && contentTemplateId != defaultContentTemplateId) - { - if (TemplateManager.GetTemplateInfo(SiteId, contentTemplateId) == null) - { - contentTemplateId = -1; - } - } - - if (contentTemplateId != -1) - { - var templateInfo = new TemplateInfo(0, SiteId, nodeInfo.ChannelName, TemplateType.ContentTemplate, "T_" + nodeInfo.ChannelName + ".html", "index.html", ".html", ECharsetUtils.GetEnumType(SiteInfo.Additional.Charset), false); - if (relatedFileNameList.Contains(templateInfo.RelatedFileName.ToLower())) - { - continue; - } - if (templateNameList.Contains(templateInfo.TemplateName)) - { - continue; - } - var insertedTemplateId = DataProvider.TemplateDao.Insert(templateInfo, string.Empty, AuthRequest.AdminName); - TemplateManager.UpdateContentTemplateId(SiteId, channelId, insertedTemplateId); - //DataProvider.BackgroundNodeDAO.UpdateContentTemplateID(channelId, insertedTemplateID); - } - } - - AuthRequest.AddSiteLog(SiteId, "生成并匹配内容模版", $"栏目:{GetNodeNames()}"); - - SuccessMessage("生成内容模版并匹配成功!"); - - BindListBox(); - } - - public void CreateSubContentTemplate_Click(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid || !Validate(false, false)) return; - - var relatedFileNameList = DataProvider.TemplateDao.GetLowerRelatedFileNameList(SiteId, TemplateType.ContentTemplate); - var templateNameList = DataProvider.TemplateDao.GetTemplateNameList(SiteId, TemplateType.ContentTemplate); - foreach (ListItem item in LbChannelId.Items) - { - if (!item.Selected) continue; - - var channelId = int.Parse(item.Value); - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - - var templateInfo = new TemplateInfo(0, SiteId, nodeInfo.ChannelName + "_下级", TemplateType.ContentTemplate, "T_" + nodeInfo.ChannelName + "_下级.html", "index.html", ".html", ECharsetUtils.GetEnumType(SiteInfo.Additional.Charset), false); - - if (relatedFileNameList.Contains(templateInfo.RelatedFileName.ToLower())) - { - continue; - } - if (templateNameList.Contains(templateInfo.TemplateName)) - { - continue; - } - var insertedTemplateId = DataProvider.TemplateDao.Insert(templateInfo, string.Empty, AuthRequest.AdminName); - var childChannelIdList = ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(SiteId, channelId), EScopeType.Descendant, string.Empty, string.Empty, string.Empty); - foreach (var childChannelId in childChannelIdList) - { - TemplateManager.UpdateContentTemplateId(SiteId, childChannelId, insertedTemplateId); - //DataProvider.BackgroundNodeDAO.UpdateContentTemplateID(childChannelId, insertedTemplateID); - } - } - - AuthRequest.AddSiteLog(SiteId, "生成并匹配下级内容模版", $"栏目:{GetNodeNames()}"); - - SuccessMessage("生成下级内容模版并匹配成功!"); - - BindListBox(); - } - } -} diff --git a/SiteServer.BackgroundPages/Cms/PageTemplateReference.cs b/SiteServer.BackgroundPages/Cms/PageTemplateReference.cs deleted file mode 100644 index b71a2e2d5..000000000 --- a/SiteServer.BackgroundPages/Cms/PageTemplateReference.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Reflection; -using System.Text; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.Utils; -using SiteServer.CMS.StlParser.Model; - -namespace SiteServer.BackgroundPages.Cms -{ - public class PageTemplateReference : BasePageCms - { - public Literal LtlElements; - public Literal LtlAttributes; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (IsPostBack) return; - - VerifySitePermissions(ConfigManager.WebSitePermissions.Template); - - // var elementsDictionary = StlAll.StlElements.GetElementsNameDictionary(); - var elements = StlAll.Elements; - - var liBuilder = new StringBuilder(); - var contentBuilder = new StringBuilder(); - foreach (var elementName in elements.Keys) - { - var elementType = elements[elementName]; - - var htmlId = elementName.Replace(":", "-"); - liBuilder.Append($@"
  • - - {elementName} - -
  • "); - - var attrBuilder = new StringBuilder(); - - var fields = elementType.GetFields(BindingFlags.Static | BindingFlags.NonPublic); - foreach (var field in fields) - { - var attr = field.GetValue(null) as Attr; - if (attr != null) - { - attrBuilder.Append($@" - {attr.Name} - {AttrUtils.GetAttrTypeText(attr.Type, attr.GetEnums(elementType, SiteId))} - {attr.Description} - "); - } - } - - var helpUrl = StringUtils.Constants.GetStlUrl(false, elementName); - - var stlAttribute = (StlClassAttribute) Attribute.GetCustomAttribute(elementType, typeof(StlClassAttribute)); - - contentBuilder.Append($@"
    -

    - <{elementName}> {stlAttribute.Usage} -

    -

    - {stlAttribute.Description} - 详细使用说明 -

    -
    -
    -
    - - - - - - - - - - {attrBuilder} - -
    属性取值简介
    -
    -
    -
    -
    -"); - } - LtlElements.Text = liBuilder.ToString(); - LtlAttributes.Text = contentBuilder.ToString(); - } - } -} diff --git a/SiteServer.BackgroundPages/Controls/Alerts.cs b/SiteServer.BackgroundPages/Controls/Alerts.cs deleted file mode 100644 index 39a1269c4..000000000 --- a/SiteServer.BackgroundPages/Controls/Alerts.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System.Web.UI; -using SiteServer.Utils; - -namespace SiteServer.BackgroundPages.Controls -{ - public class Alerts : Control - { - public bool IsShowImmidiatary { get; set; } - - public MessageUtils.Message.EMessageType MessageType { get; set; } = MessageUtils.Message.EMessageType.None; - - public string Content { get; set; } = string.Empty; - - public string Text - { - get - { - var state = ViewState["Text"]; - if (state != null) - { - return (string)state; - } - return string.Empty; - } - set - { - ViewState["Text"] = value; - } - } - - protected override void Render(HtmlTextWriter writer) - { - writer.Write(IsShowImmidiatary - ? MessageUtils.GetAlertHtml(MessageType, Content, this) - : MessageUtils.GetAlertHtml(this, Text)); - - writer.Write(@"
    提示!  
    "); - } - } -} diff --git a/SiteServer.BackgroundPages/Controls/AuxiliaryControl.cs b/SiteServer.BackgroundPages/Controls/AuxiliaryControl.cs deleted file mode 100644 index d860827af..000000000 --- a/SiteServer.BackgroundPages/Controls/AuxiliaryControl.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Text; -using System.Web.UI; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Plugin; -using SiteServer.Plugin; - -namespace SiteServer.BackgroundPages.Controls -{ - public class AuxiliaryControl : Control - { - public IAttributes Attributes { get; set; } - - public SiteInfo SiteInfo { get; set; } - - public int ChannelId { get; set; } - - public List StyleInfoList { get; set; } - - protected override void Render(HtmlTextWriter output) - { - if (StyleInfoList == null || StyleInfoList.Count == 0 || Attributes == null) return; - - var pageScripts = new NameValueCollection(); - - var builder = new StringBuilder(); - foreach (var styleInfo in StyleInfoList) - { - string extra; - var value = BackgroundInputTypeParser.Parse(SiteInfo, ChannelId, styleInfo, Attributes, pageScripts, out extra); - - if (string.IsNullOrEmpty(value) && string.IsNullOrEmpty(extra)) continue; - - if (styleInfo.InputType == InputType.TextEditor) - { - var commands = WebUtils.GetTextEditorCommands(SiteInfo, styleInfo.AttributeName); - builder.Append($@" -
    - -
    - {commands} -
    - {value} -
    -
    -
    - {extra} -
    -
    "); - } - else - { - var html = $@" -
    - -
    - {value} -
    -
    - {extra} -
    -
    "; - - if (styleInfo.InputType == InputType.Customize) - { - var eventArgs = new ContentFormLoadEventArgs(SiteInfo.Id, ChannelId, styleInfo.AttributeName, Attributes); - foreach (var service in PluginManager.Services) - { - try - { - var serviceReturnedHtml = service.OnContentFormLoad(eventArgs); - if (!string.IsNullOrEmpty(serviceReturnedHtml)) - { - html = serviceReturnedHtml; - } - } - catch (Exception ex) - { - LogUtils.AddErrorLog(service.PluginId, ex, nameof(IService.ContentFormLoad)); - } - } - } - - builder.Append(html); - } - } - - output.Write(builder.ToString()); - - foreach (string key in pageScripts.Keys) - { - output.Write(pageScripts[key]); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Controls/Message.cs b/SiteServer.BackgroundPages/Controls/Message.cs deleted file mode 100644 index ed3f569c5..000000000 --- a/SiteServer.BackgroundPages/Controls/Message.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Web.UI; -using SiteServer.Utils; - -namespace SiteServer.BackgroundPages.Controls -{ - public class Message : Control - { - private bool isShowImmidiatary = false; - public bool IsShowImmidiatary - { - get { return isShowImmidiatary; } - set { isShowImmidiatary = value; } - } - - private MessageUtils.Message.EMessageType messageType = MessageUtils.Message.EMessageType.None; - public MessageUtils.Message.EMessageType MessageType - { - get { return messageType; } - set { messageType = value; } - } - - private string content = string.Empty; - public string Content - { - get { return content; } - set { content = value; } - } - - protected override void Render(HtmlTextWriter writer) - { - if (isShowImmidiatary) // 有直接显示的消息 - { - writer.Write(MessageUtils.GetMessageHtml(messageType, content, this)); - } - else // 没有直接显示的消息则去cookies中检查是否有消息需要显示 - { - writer.Write(MessageUtils.GetMessageHtml(this)); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Controls/NavigationTree.cs b/SiteServer.BackgroundPages/Controls/NavigationTree.cs deleted file mode 100644 index 159973049..000000000 --- a/SiteServer.BackgroundPages/Controls/NavigationTree.cs +++ /dev/null @@ -1,110 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Text; -using System.Web.UI; -using SiteServer.BackgroundPages.Plugins; -using SiteServer.Utils; -using SiteServer.CMS.Core; - -namespace SiteServer.BackgroundPages.Controls -{ - public class NavigationTree : Control - { - public int SiteId { get; set; } - - public string TopId { get; set; } - - public string Title { get; set; } - - public List PermissionList { get; set; } - - protected override void Render(HtmlTextWriter writer) - { - var builder = new StringBuilder(); - var tabList = TabManager.GetTabList(TopId, SiteId); - if (tabList != null && tabList.Count > 0) - { - var linkHtml = string.Empty; - if (string.IsNullOrEmpty(TopId) && PermissionList.Contains(ConfigManager.PluginsPermissions.Management)) - { - linkHtml = $@""; - } - builder.Append($@"
  • {Title}{linkHtml}
  • "); - BuildNavigationTree(builder, tabList, 0, true); - } - writer.Write(builder); - } - - protected void BuildNavigationTree(StringBuilder builder, List tabs, int parentsCount, bool isDisplay) - { - if (tabs == null) return; - - foreach (var parent in tabs) - { - if (!TabManager.IsValid(parent, PermissionList)) continue; - - var childBuilder = new StringBuilder(); - if (parent.Children != null && parent.Children.Length > 0) - { - var tabCollection = new TabCollection(parent.Children); - if (tabCollection.Tabs != null && tabCollection.Tabs.Length > 0) - { - foreach (var childTab in tabCollection.Tabs) - { - if (!TabManager.IsValid(childTab, PermissionList)) continue; - - var href = childTab.Href; - if (!PageUtils.IsAbsoluteUrl(href)) - { - href = PageUtils.AddQueryString(href, - new NameValueCollection { { "siteId", SiteId.ToString() } }); - } - href = childTab.HasHref ? PageUtils.GetLoadingUrl(href) : "javascript:;"; - - childBuilder.Append($@" -
  • - - - {childTab.Text} - -
  • "); - } - } - } - - if (childBuilder.Length > 0) - { - builder.Append($@" -
  • - - - {parent.Text} - - -
      - {childBuilder} -
    -
  • -"); - } - else - { - var href = parent.Href; - if (!PageUtils.IsAbsoluteUrl(href)) - { - href = PageUtils.AddQueryString(href, - new NameValueCollection {{"siteId", SiteId.ToString()}}); - } - href = parent.HasHref ? PageUtils.GetLoadingUrl(href) : "javascript:;"; - builder.Append($@" -
  • - - - {parent.Text} - -
  • "); - } - } - } - } -} diff --git a/SiteServer.BackgroundPages/Controls/SqlCountPager.cs b/SiteServer.BackgroundPages/Controls/SqlCountPager.cs deleted file mode 100644 index e4b1b003e..000000000 --- a/SiteServer.BackgroundPages/Controls/SqlCountPager.cs +++ /dev/null @@ -1,864 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.ComponentModel; -using System.Data; -using System.Web.UI; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; - -namespace SiteServer.BackgroundPages.Controls -{ - [DefaultProperty("SelectCommand")] - [DefaultEvent("PageIndexChanged")] - [ToolboxData("<{0}:SqlCountPager runat=\"server\" />")] - public class SqlCountPager : Table, INamingContainer - { - private PagedDataSource _dataSource; - private Control _controlToPaginate; - private string CacheKeyName => Page.Request.FilePath + "_" + UniqueID + "_Data"; - public const string ParmPage = "page"; - -// private string GetQueryPageCommandText(int recsToRetrieve) -// { -// if (!string.IsNullOrEmpty(OrderByString)) -// { -// var orderByString2 = OrderByString.Replace(" DESC", " DESC2"); -// orderByString2 = orderByString2.Replace(" ASC", " DESC"); -// orderByString2 = orderByString2.Replace(" DESC2", " ASC"); - -// if (WebConfigUtils.DatabaseType == EDatabaseType.MySql) -// { -// return $@" -//SELECT * FROM ( -// SELECT * FROM ( -// SELECT * FROM ({SelectCommand}) AS t0 {OrderByString} LIMIT {ItemsPerPage * (CurrentPageIndex + 1)} -// ) AS t1 {orderByString2} LIMIT {recsToRetrieve} -//) AS t2 {OrderByString}"; -// } -// else -// { -// return $@" -//SELECT * FROM ( -// SELECT TOP {recsToRetrieve} * FROM ( -// SELECT TOP {ItemsPerPage * (CurrentPageIndex + 1)} * FROM ({SelectCommand}) AS t0 {OrderByString} -// ) AS t1 {orderByString2} -//) AS t2 {OrderByString}"; -// } -// } -// else -// { -// if (WebConfigUtils.DatabaseType == EDatabaseType.MySql) -// { -// return $@" -//SELECT * FROM ( -// SELECT * FROM ( -// SELECT * FROM ({SelectCommand}) AS t0 ORDER BY {SortField} {SortMode} LIMIT {ItemsPerPage * (CurrentPageIndex + 1)} -// ) AS t1 ORDER BY {SortField} {AlterSortMode(SortMode)} LIMIT {recsToRetrieve} -//) AS t2 ORDER BY {SortField} {SortMode}"; -// } -// else -// { -// return $@" -//SELECT * FROM ( -// SELECT TOP {recsToRetrieve} * FROM ( -// SELECT TOP {ItemsPerPage * (CurrentPageIndex + 1)} * FROM ({SelectCommand}) AS t0 ORDER BY {SortField} {SortMode} -// ) AS t1 ORDER BY {SortField} {AlterSortMode(SortMode)} -//) AS t2 ORDER BY {SortField} {SortMode}"; -// } -// } -// } - - public SqlCountPager() - { - _dataSource = null; - _controlToPaginate = null; - - PagingMode = PagingMode.NonCached; - PagerStyle = PagerStyle.NextPrev; - CurrentPageIndex = 0; - SelectCommand = ""; - ItemsPerPage = 10; - TotalPages = -1; - CacheDuration = 60; - SortMode = SortMode.DESC; - } - - /// - /// Removes any data cached for paging - /// - public void ClearCache() - { - if (PagingMode == PagingMode.Cached) - Page.Cache.Remove(CacheKeyName); - } - - [Description("Gets and sets for how many seconds the data should stay in the cache")] - public int CacheDuration - { - get { return Convert.ToInt32(ViewState["CacheDuration"]); } - set { ViewState["CacheDuration"] = value; } - } - - [Description("Indicates whether the data are retrieved page by page or can be cached")] - public PagingMode PagingMode - { - get { return (PagingMode)ViewState["PagingMode"]; } - set { ViewState["PagingMode"] = value; } - } - - [Description("Indicates the style of the pager's navigation bar")] - public PagerStyle PagerStyle - { - get { return (PagerStyle)ViewState["PagerStyle"]; } - set { ViewState["PagerStyle"] = value; } - } - - [Description("Gets and sets the name of the control to paginate")] - public Control ControlToPaginate - { - get { return _controlToPaginate; } - set { _controlToPaginate = value; } - } - - [Description("Gets and sets the number of items to display per page")] - public int ItemsPerPage - { - get { return Convert.ToInt32(ViewState["ItemsPerPage"]); } - set { ViewState["ItemsPerPage"] = value; } - } - - [Description("Gets and sets the index of the currently displayed page")] - public int CurrentPageIndex - { - get { return Convert.ToInt32(ViewState["CurrentPageIndex"]); } - set { ViewState["CurrentPageIndex"] = value; } - } - - [Description("Gets and sets the SQL query to get data")] - public string SelectCommand - { - get { return Convert.ToString(ViewState["SelectCommand"]); } - set { ViewState["SelectCommand"] = value; } - } - - public string OrderByString - { - get { return Convert.ToString(ViewState["OrderByString"]); } - set { ViewState["OrderByString"] = value; } - } - - [Description("Gets and sets the sort-by field. It is mandatory in NonCached mode.)")] - public string SortField - { - get { return Convert.ToString(ViewState["SortKeyField"]); } - set { ViewState["SortKeyField"] = value; } - } - - [Description("Gets and sets the Unit.)")] - public string Unit - { - get { return Convert.ToString(ViewState["Unit"]); } - set { ViewState["Unit"] = value; } - } - - [Description("取得设置排序模式")] - public SortMode SortMode - { - get { return (SortMode)ViewState["SortMode"]; } - set { ViewState["SortMode"] = value; } - } - - public string FirstText - { - get - { - var text = ViewState["FirstText"] as string; - if (string.IsNullOrEmpty(text)) - { - text = "首页"; - } - return text; - } - set { ViewState["FirstText"] = value; } - } - - public string LastText - { - get - { - var text = ViewState["LastText"] as string; - if (string.IsNullOrEmpty(text)) - { - text = "末页"; - } - return text; - } - set { ViewState["LastText"] = value; } - } - - public string PrevText - { - get - { - var text = ViewState["PrevText"] as string; - if (string.IsNullOrEmpty(text)) - { - text = "上一页"; - } - return text; - } - set { ViewState["PrevText"] = value; } - } - - public string NextText - { - get - { - var text = ViewState["NextText"] as string; - if (string.IsNullOrEmpty(text)) - { - text = "下一页"; - } - return text; - } - set { ViewState["NextText"] = value; } - } - - public string CurrentPageText - { - get { return ViewState["CurrentPageText"] as string; } - set { ViewState["CurrentPageText"] = value; } - } - - public string EnabledCssClass - { - get { return ViewState["EnabledCssClass"] as string; } - set { ViewState["EnabledCssClass"] = value; } - } - - public new string DisabledCssClass - { - get { return ViewState["DisabledCssClass"] as string; } - set { ViewState["DisabledCssClass"] = value; } - } - - public string TextCssClass - { - get { return ViewState["TextCssClass"] as string; } - set { ViewState["TextCssClass"] = value; } - } - - /// - /// Gets the number of displayable pages - /// - [Browsable(false)] - public int PageCount => TotalPages; - - /// - /// Gets and sets the number of pages to display - /// - protected int TotalPages - { - get { return Convert.ToInt32(ViewState["TotalPages"]); } - set { ViewState["TotalPages"] = value; } - } - - /// - /// Gets and sets the number of pages to display - /// - public int TotalCount - { - get { return Convert.ToInt32(ViewState["TotalCount"]); } - set { ViewState["TotalCount"] = value; } - } - - /// - /// Fetches and stores the data - /// - public override void DataBind() - { - CurrentPageIndex = TranslateUtils.ToInt(Page.Request.QueryString[ParmPage], 1) - 1; - - base.DataBind(); - - // Controls must be recreated after data binding - ChildControlsCreated = false; - - // Ensures the control exists and is a list control - if (_controlToPaginate == null) - return; - if (!(_controlToPaginate is BaseDataList || _controlToPaginate is Repeater || _controlToPaginate is ListControl)) - return; - - // Ensures enough info to connect and query is specified - if (SelectCommand == "") - return; - - // Fetch data - if (PagingMode == PagingMode.Cached) - { - FetchAllData(); - } - else - { - FetchPageData(); - } - - // Bind data to the buddy control - if (_controlToPaginate is BaseDataList) - { - var baseDataListControl = (BaseDataList)_controlToPaginate; - baseDataListControl.DataSource = _dataSource; - baseDataListControl.DataBind(); - } - else if (_controlToPaginate is Repeater) - { - var baseRepeaterControl = (Repeater)_controlToPaginate; - baseRepeaterControl.DataSource = _dataSource; - baseRepeaterControl.DataBind(); - } - else if (_controlToPaginate is ListControl) - { - var listControl = (ListControl)_controlToPaginate; - listControl.Items.Clear(); - listControl.DataSource = _dataSource; - listControl.DataBind(); - } - } - - /// - /// Writes the content to be rendered on the client - /// - protected override void Render(HtmlTextWriter output) - { - // If in design-mode ensure that child controls have been created. - // Child controls are not created at this time in design-mode because - // there's no pre-render stage. Do so for composite controls like this - if (Site != null && Site.DesignMode) - CreateChildControls(); - - base.Render(output); - } - - /// - /// Outputs the HTML markup for the control - /// - protected override void CreateChildControls() - { - Controls.Clear(); - ClearChildViewState(); - - BuildControlHierarchy(); - } - - /// - /// Control the building of the control's hierarchy - /// - private void BuildControlHierarchy() - { - if (TotalPages > 1) - { - // Build the surrounding table (one row, two cells) - - // Build the table row - var row = new TableRow {Height = 25}; - Rows.Add(row); - //t.Rows.Add(row); - - // Build the cell with navigation bar - var cellNavBar = new TableCell {VerticalAlign = VerticalAlign.Middle}; - if (PagerStyle == PagerStyle.NextPrev) - { - BuildNextPrevUi(cellNavBar); - row.Cells.Add(cellNavBar); - // Build the cell with the page index - var cellPageDesc = new TableCell(); - if (!string.IsNullOrEmpty(TextCssClass)) - { - cellPageDesc.CssClass = TextCssClass; - } - cellPageDesc.HorizontalAlign = HorizontalAlign.Right; - cellPageDesc.VerticalAlign = VerticalAlign.Top; - BuildCurrentPage(cellPageDesc); - row.Cells.Add(cellPageDesc); - } - else - { - row.Cells.Add(cellNavBar); - } - } - } - - private string GetNavigationUrl(int page) - { - var queryString = new NameValueCollection(Page.Request.QueryString); - if (page > 1) - { - queryString[ParmPage] = page.ToString(); - } - else - { - queryString.Remove(ParmPage); - } - return PageUtils.AddQueryString(PageUtils.GetUrlWithoutQueryString(Page.Request.RawUrl), queryString); - } - - /// - /// Generates the HTML markup for the Next/Prev navigation bar - /// - /// - private void BuildNextPrevUi(TableCell cell) - { - var isValidPage = (CurrentPageIndex >= 0 && CurrentPageIndex <= TotalPages - 1); - var canMoveBack = (CurrentPageIndex > 0); - var canMoveForward = (CurrentPageIndex < TotalPages - 1); - - // 首页 - var enabled = isValidPage && canMoveBack; - var firstImage = new Image {ToolTip = FirstText}; - var firstText = new Label {Text = FirstText}; - - if (enabled) - { - firstImage.ImageUrl = SiteServerAssets.GetUrl(SiteServerAssets.Arrow.First); - - var link = new HyperLink(); - link.Style.Add("text-decoration", "none"); - link.NavigateUrl = GetNavigationUrl(1); - if (!string.IsNullOrEmpty(EnabledCssClass)) - { - link.CssClass = EnabledCssClass; - } - link.Controls.Add(firstImage); - link.Controls.Add(new LiteralControl(" ")); - link.Controls.Add(firstText); - cell.Controls.Add(link); - } - else - { - firstImage.ImageUrl = SiteServerAssets.GetUrl(SiteServerAssets.Arrow.FirstDisabled); - cell.Controls.Add(firstImage); - cell.Controls.Add(new LiteralControl(" ")); - if (!string.IsNullOrEmpty(DisabledCssClass)) - { - firstText.CssClass = DisabledCssClass; - } - else - { - firstText.Style.Add("color", "gray"); - } - cell.Controls.Add(firstText); - } - - cell.Controls.Add(new LiteralControl("  ")); - - // 上一页 - var prevImage = new Image {ToolTip = PrevText}; - var prevText = new Label {Text = PrevText}; - - if (enabled) - { - prevImage.ImageUrl = SiteServerAssets.GetUrl(SiteServerAssets.Arrow.Previous); - - var link = new HyperLink(); - link.Style.Add("text-decoration", "none"); - link.NavigateUrl = GetNavigationUrl(CurrentPageIndex); - if (!string.IsNullOrEmpty(EnabledCssClass)) - { - link.CssClass = EnabledCssClass; - } - link.Controls.Add(prevImage); - link.Controls.Add(new LiteralControl(" ")); - link.Controls.Add(prevText); - cell.Controls.Add(link); - } - else - { - prevImage.ImageUrl = SiteServerAssets.GetUrl(SiteServerAssets.Arrow.PreviousDisabled); - cell.Controls.Add(prevImage); - cell.Controls.Add(new LiteralControl(" ")); - if (!string.IsNullOrEmpty(DisabledCssClass)) - { - prevText.CssClass = DisabledCssClass; - } - else - { - prevText.Style.Add("color", "gray"); - } - cell.Controls.Add(prevText); - } - - cell.Controls.Add(new LiteralControl("  ")); - - // 下一页 - enabled = isValidPage && canMoveForward; - var nextImage = new Image {ToolTip = NextText}; - var nextText = new Label {Text = NextText}; - - if (enabled) - { - nextImage.ImageUrl = SiteServerAssets.GetUrl(SiteServerAssets.Arrow.Next); - - var link = new HyperLink(); - link.Style.Add("text-decoration", "none"); - link.NavigateUrl = GetNavigationUrl(CurrentPageIndex + 2); - if (!string.IsNullOrEmpty(EnabledCssClass)) - { - link.CssClass = EnabledCssClass; - } - link.Controls.Add(nextImage); - link.Controls.Add(new LiteralControl(" ")); - link.Controls.Add(nextText); - cell.Controls.Add(link); - } - else - { - nextImage.ImageUrl = SiteServerAssets.GetUrl(SiteServerAssets.Arrow.NextDisabled); - - cell.Controls.Add(nextImage); - cell.Controls.Add(new LiteralControl(" ")); - if (!string.IsNullOrEmpty(DisabledCssClass)) - { - nextText.CssClass = DisabledCssClass; - } - else - { - nextText.Style.Add("color", "gray"); - } - cell.Controls.Add(nextText); - } - - cell.Controls.Add(new LiteralControl("  ")); - - // 末页 - var lastImage = new Image {ToolTip = LastText}; - var lastText = new Label {Text = LastText}; - - if (enabled) - { - lastImage.ImageUrl = SiteServerAssets.GetUrl(SiteServerAssets.Arrow.Last); - - var link = new HyperLink(); - link.Style.Add("text-decoration", "none"); - link.NavigateUrl = GetNavigationUrl(TotalPages); - if (!string.IsNullOrEmpty(EnabledCssClass)) - { - link.CssClass = EnabledCssClass; - } - link.Controls.Add(lastImage); - link.Controls.Add(new LiteralControl(" ")); - link.Controls.Add(lastText); - cell.Controls.Add(link); - } - else - { - lastImage.ImageUrl = SiteServerAssets.GetUrl(SiteServerAssets.Arrow.LastDisabled); - - cell.Controls.Add(lastImage); - cell.Controls.Add(new LiteralControl(" ")); - if (!string.IsNullOrEmpty(DisabledCssClass)) - { - lastText.CssClass = DisabledCssClass; - } - else - { - lastText.Style.Add("color", "gray"); - } - cell.Controls.Add(lastText); - } - - //显示总记录数 - if (TotalPages > 0) - { - - cell.Controls.Add(new LiteralControl("  ")); - var totalPagesText = new Label(); - lastText.Text = $@" ( 共{TotalCount}条 )"; - cell.Controls.Add(totalPagesText); - } - } - - // *********************************************************************** - - /// - /// Generates the HTML markup to describe the current page (0-based) - /// - private void BuildCurrentPage(TableCell cell) - { - var text = new NoTagText - { - ID = "Text", - Text = CurrentPageText - }; - cell.Controls.Add(text); - // Render a drop-down list - var pageList = new DropDownList - { - ID = "PageList", - AutoPostBack = true - }; - pageList.SelectedIndexChanged += PageList_Click; - pageList.Font.Name = Font.Name; - pageList.Font.Size = Font.Size; - pageList.ForeColor = ForeColor; - pageList.CssClass = "input-medium"; - - // Embellish the list when there are no pages to list - if (TotalPages <= 0 || CurrentPageIndex == -1) - { - pageList.Items.Add("1 / 1"); - pageList.Enabled = false; - pageList.SelectedIndex = 0; - } - else // Populate the list - { - for (var i = 1; i <= TotalPages; i++) - { - var item = new ListItem($"{i} / {TotalPages}", (i - 1).ToString()); - pageList.Items.Add(item); - } - pageList.SelectedIndex = CurrentPageIndex; - } - cell.CssClass = "align-right"; - cell.Controls.Add(pageList); - } - - /// - /// Ensures the CurrentPageIndex is either valid [0,TotalPages) - /// - private void ValidatePageIndex() - { - if (CurrentPageIndex < 0) - { - CurrentPageIndex = 0; - } - else if (CurrentPageIndex > TotalPages - 1) - { - CurrentPageIndex = TotalPages - 1; - } - } - - /// - /// Runs the query for all data to be paged and caches the resulting data - /// - private void FetchAllData() - { - // Looks for data in the ASP.NET Cache - var data = (DataTable)Page.Cache[CacheKeyName]; - if (data == null) - { - // Fix SelectCommand with order-by info - AdjustSelectCommand(true); - - // If data expired or has never been fetched, go to the database - //SqlDataAdapter adapter = new SqlDataAdapter(SelectCommand, ConnectionString); - var adapter = SqlUtils.GetIDbDataAdapter(SelectCommand, WebConfigUtils.ConnectionString); - data = new DataTable(); - //adapter.Fill(data); - SqlUtils.FillDataAdapterWithDataTable(adapter, data); - Page.Cache.Insert(CacheKeyName, data, null, - DateTime.Now.AddSeconds(CacheDuration), - System.Web.Caching.Cache.NoSlidingExpiration); - } - - // Configures the paged data source component - if (_dataSource == null) - _dataSource = new PagedDataSource(); - _dataSource.DataSource = data.DefaultView; // must be IEnumerable! - _dataSource.AllowPaging = true; - _dataSource.PageSize = ItemsPerPage; - TotalPages = _dataSource.PageCount; - - // Ensures the page index is valid - ValidatePageIndex(); - if (CurrentPageIndex == -1) - { - _dataSource = null; - return; - } - - // Selects the page to view - _dataSource.CurrentPageIndex = CurrentPageIndex; - } - - /// - /// Runs the query to get only the data that fit into the current page - /// - private void FetchPageData() - { - // Need a validated page index to fetch data. - // Also need the virtual page count to validate the page index - AdjustSelectCommand(false); - var countInfo = CalculateVirtualRecordCount(); - TotalPages = countInfo.PageCount; - TotalCount = countInfo.RecordCount; - - // Validate the page number (ensures CurrentPageIndex is valid or -1) - ValidatePageIndex(); - if (CurrentPageIndex == -1) - return; - - // Prepare and run the command - var cmd = PrepareCommand(countInfo); - if (cmd == null) - return; - //SqlDataAdapter adapter = new SqlDataAdapter(cmd); - var adapter = SqlUtils.GetIDbDataAdapter(); - adapter.SelectCommand = cmd; - var data = new DataTable(); - //adapter.Fill(data); - SqlUtils.FillDataAdapterWithDataTable(adapter, data); - - // Configures the paged data source component - if (_dataSource == null) - _dataSource = new PagedDataSource(); - _dataSource.AllowCustomPaging = true; - _dataSource.AllowPaging = true; - _dataSource.CurrentPageIndex = 0; - _dataSource.PageSize = ItemsPerPage; - _dataSource.VirtualCount = countInfo.RecordCount; - _dataSource.DataSource = data.DefaultView; - } - - /// - /// Strips ORDER-BY clauses from SelectCommand and adds a new one based - /// on SortKeyField - /// - private void AdjustSelectCommand(bool addCustomSortInfo) - { - // Truncate where ORDER BY is found - var temp = SelectCommand.ToLower(); - var pos = temp.IndexOf("order by", StringComparison.Ordinal); - if (pos > -1) - SelectCommand = SelectCommand.Substring(0, pos); - - // Add new ORDER BY info if SortKeyField is specified - if (SortField != "" && addCustomSortInfo) - SelectCommand += " ORDER BY " + SortField; - } - - /// - /// Calculates record and page count for the specified query - /// - private VirtualRecordCount CalculateVirtualRecordCount() - { - var count = new VirtualRecordCount - { - RecordCount = GetQueryVirtualCount(), - RecordsInLastPage = ItemsPerPage - }; - - // Calculate the virtual number of records from the query - - // Calculate the correspondent number of pages - var lastPage = count.RecordCount / ItemsPerPage; - var remainder = count.RecordCount % ItemsPerPage; - if (remainder > 0) - lastPage++; - count.PageCount = lastPage; - - // Calculate the number of items in the last page - if (remainder > 0) - count.RecordsInLastPage = remainder; - return count; - } - - /// - /// Prepares and returns the command object for the reader-based query - /// - private IDbCommand PrepareCommand(VirtualRecordCount countInfo) - { - // Determines how many records are to be retrieved. - // The last page could require less than other pages - //var recsToRetrieve = ItemsPerPage; - //if (CurrentPageIndex == countInfo.PageCount - 1) - // recsToRetrieve = countInfo.RecordsInLastPage; - - //var cmdText = GetQueryPageCommandText(recsToRetrieve); - var orderString = OrderByString; - if (string.IsNullOrEmpty(orderString)) - { - orderString = $"ORDER BY {SortField} {SortMode}"; - } - var cmdText = SqlUtils.GetPageSqlString(SelectCommand, orderString, ItemsPerPage, CurrentPageIndex, PageCount, countInfo.RecordsInLastPage); - - var conn = SqlUtils.GetIDbConnection(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString); - var cmd = SqlUtils.GetIDbCommand(); - cmd.Connection = conn; - cmd.CommandText = cmdText; - return cmd; - } - - ///// - ///// 方法 反转排序模式 - ///// - ///// 排序模式 - ///// 相反的排序模式 - //private static SortMode AlterSortMode(SortMode mode) - //{ - // return mode == SortMode.DESC ? SortMode.ASC : SortMode.DESC; - //} - - /// - /// Run a query to get the record count - /// - private int GetQueryVirtualCount() - { - var recCount = DataProvider.DatabaseDao.GetPageTotalCount(SelectCommand); - // SqlConnection conn = new SqlConnection(ConnectionString); - // SqlCommand cmd = new SqlCommand(cmdText, conn); - //IDbConnection conn = SqlUtils.GetIDbConnection(DataProvider.ADOType, ConnectionString); - //IDbCommand cmd = SqlUtils.GetIDbCommand(DataProvider.ADOType); - //cmd.Connection = conn; - //cmd.CommandText = cmdText; - - //cmd.Connection.Open(); - //int recCount = (int)cmd.ExecuteScalar(); - //cmd.Connection.Close(); - - return recCount; - } - - /// - /// Sets the current page index - /// - //private void GoToPage(int pageIndex) - //{ - // // Prepares event data - // PageChangedEventArgs e = new PageChangedEventArgs(); - // e.OldPageIndex = CurrentPageIndex; - // e.NewPageIndex = pageIndex; - - // // Updates the current index - // CurrentPageIndex = pageIndex; - - // // Fires the page changed event - // OnPageIndexChanged(e); - - // // Binds new data - // DataBind(); - //} - - /// - /// Event handler for any page selected from the drop-down page list - /// - private void PageList_Click(object sender, EventArgs e) - { - var pageList = (DropDownList)sender; - var pageIndex = Convert.ToInt32(pageList.SelectedValue); - PageUtils.Redirect(GetNavigationUrl(pageIndex + 1)); - } - - ///// - ///// Event handler for any page selected from the drop-down page list - ///// - //private void Numeric_Click(object sender, EventArgs e) - //{ - // LinkButton linkButton = (LinkButton)sender; - // int pageIndex = Convert.ToInt32(linkButton.CommandArgument); - // GoToPage(pageIndex); - //} - } -} diff --git a/SiteServer.BackgroundPages/Core/ChannelLoading.cs b/SiteServer.BackgroundPages/Core/ChannelLoading.cs deleted file mode 100644 index 0729c7dde..000000000 --- a/SiteServer.BackgroundPages/Core/ChannelLoading.cs +++ /dev/null @@ -1,207 +0,0 @@ -using System; -using System.Text; -using SiteServer.Utils; -using System.Collections.Specialized; -using SiteServer.BackgroundPages.Cms; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Core -{ - public class ChannelLoading - { - public static string GetChannelRowHtml(SiteInfo siteInfo, ChannelInfo nodeInfo, bool enabled, ELoadingType loadingType, NameValueCollection additional, PermissionManager permissionManager) - { - var nodeTreeItem = ChannelTreeItem.CreateInstance(siteInfo, nodeInfo, enabled, permissionManager); - var title = nodeTreeItem.GetItemHtml(loadingType, PageChannel.GetRedirectUrl(siteInfo.Id, nodeInfo.Id), additional); - - var rowHtml = string.Empty; - - if (loadingType == ELoadingType.ContentTree) - { - rowHtml = $@" - - {title} - -"; - } - else if (loadingType == ELoadingType.Channel) - { - var upLink = string.Empty; - var downLink = string.Empty; - var editUrl = string.Empty; - var checkBoxHtml = string.Empty; - - if (enabled) - { - if (permissionManager.HasChannelPermissions(nodeInfo.SiteId, nodeInfo.Id, ConfigManager.ChannelPermissions.ChannelEdit)) - { - var urlEdit = PageChannelEdit.GetRedirectUrl(nodeInfo.SiteId, nodeInfo.Id, PageChannel.GetRedirectUrl(nodeInfo.SiteId, nodeInfo.Id)); - editUrl = $"编辑"; - var urlSubtract = PageUtils.GetCmsUrl(nodeInfo.SiteId, nameof(PageChannel), new NameValueCollection - { - {"Subtract", true.ToString()}, - {"channelId", nodeInfo.Id.ToString()} - }); - upLink = - $@""; - var urlAdd = PageUtils.GetCmsUrl(nodeInfo.SiteId, nameof(PageChannel), new NameValueCollection - { - {"Add", true.ToString()}, - {"channelId", nodeInfo.Id.ToString()} - }); - downLink = - $@""; - } - checkBoxHtml = $""; - } - - rowHtml = $@" - - {title} - {nodeInfo.GroupNameCollection} - {nodeInfo.IndexName} - {upLink} - {downLink} - {editUrl} - {checkBoxHtml} - -"; - } - else if (loadingType == ELoadingType.SiteAnalysis) - { - var startDate = TranslateUtils.ToDateTime(additional["StartDate"]); - var endDate = TranslateUtils.ToDateTime(additional["EndDate"]); - - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - var num = DataProvider.ContentDao.GetCountOfContentAdd(tableName, siteInfo.Id, nodeInfo.Id, EScopeType.All, startDate, endDate, string.Empty, ETriState.All); - var contentAddNum = num == 0 ? "0" : $"{num}"; - - num = DataProvider.ContentDao.GetCountOfContentUpdate(tableName, siteInfo.Id, nodeInfo.Id, EScopeType.All, startDate, endDate, string.Empty); - var contentUpdateNum = num == 0 ? "0" : $"{num}"; - - rowHtml = $@" - - {title} - {contentAddNum} - {contentUpdateNum} - -"; - } - else if (loadingType == ELoadingType.TemplateFilePathRule) - { - var editLink = string.Empty; - - if (enabled) - { - var showPopWinString = ModalTemplateFilePathRule.GetOpenWindowString(nodeInfo.SiteId, nodeInfo.Id); - editLink = $"更改"; - } - var filePath = PageUtility.GetInputChannelUrl(siteInfo, nodeInfo, false); - - rowHtml = $@" - - {title} - {filePath} - {editLink} - -"; - } - else if (loadingType == ELoadingType.ConfigurationCreateDetails) - { - var editChannelLink = string.Empty; - - var nodeNames = string.Empty; - - if (enabled) - { - var showPopWinString = ModalConfigurationCreateChannel.GetOpenWindowString(nodeInfo.SiteId, nodeInfo.Id); - editChannelLink = $"触发栏目"; - } - - if (nodeInfo.Additional.ToNameValueCollection().Count > 0) - { - var nodeNameBuilder = new StringBuilder(); - var channelIdList = TranslateUtils.StringCollectionToIntList(nodeInfo.Additional.CreateChannelIDsIfContentChanged); - foreach (var theChannelId in channelIdList) - { - var theNodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, theChannelId); - if (theNodeInfo != null) - { - nodeNameBuilder.Append(theNodeInfo.ChannelName).Append(","); - } - } - if (nodeNameBuilder.Length > 0) - { - nodeNameBuilder.Length--; - nodeNames = nodeNameBuilder.ToString(); - } - } - - rowHtml = $@" - - {title} - {nodeNames} - {editChannelLink} - -"; - } - else if (loadingType == ELoadingType.ConfigurationCrossSiteTrans) - { - var editLink = string.Empty; - - if (enabled) - { - var showPopWinString = ModalCrossSiteTransEdit.GetOpenWindowString(nodeInfo.SiteId, nodeInfo.Id); - editLink = $"更改"; - } - - var contribute = CrossSiteTransUtility.GetDescription(nodeInfo.SiteId, nodeInfo); - - rowHtml = $@" - - {title} - {contribute} - {editLink} - -"; - } - else if (loadingType == ELoadingType.ChannelSelect) - { - rowHtml = $@" - - {title} - -"; - } - - return rowHtml; - } - - public static string GetScript(SiteInfo siteInfo, string contentModelPluginId, ELoadingType loadingType, NameValueCollection additional) - { - return ChannelTreeItem.GetScript(siteInfo, loadingType, contentModelPluginId, additional); - } - - public static string GetScriptOnLoad(int siteId, int currentChannelId) - { - if (currentChannelId == 0 || currentChannelId == siteId) return string.Empty; - - var nodeInfo = ChannelManager.GetChannelInfo(siteId, currentChannelId); - if (nodeInfo == null) return string.Empty; - - string path; - if (nodeInfo.ParentId == siteId) - { - path = currentChannelId.ToString(); - } - else - { - path = nodeInfo.ParentsPath.Substring(nodeInfo.ParentsPath.IndexOf(",", StringComparison.Ordinal) + 1) + "," + currentChannelId; - } - return ChannelTreeItem.GetScriptOnLoad(path); - } - } -} diff --git a/SiteServer.BackgroundPages/Core/PagingMode.cs b/SiteServer.BackgroundPages/Core/PagingMode.cs deleted file mode 100644 index 91b9f73fc..000000000 --- a/SiteServer.BackgroundPages/Core/PagingMode.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace SiteServer.BackgroundPages.Core -{ - public enum PagingMode - { - Cached, - NonCached - } -} diff --git a/SiteServer.BackgroundPages/Core/TextUtility.cs b/SiteServer.BackgroundPages/Core/TextUtility.cs deleted file mode 100644 index 2544663ca..000000000 --- a/SiteServer.BackgroundPages/Core/TextUtility.cs +++ /dev/null @@ -1,255 +0,0 @@ -using SiteServer.CMS.Model; -using System.Text; -using SiteServer.Utils; -using System.Collections.Generic; -using System.Collections.Specialized; -using SiteServer.BackgroundPages.Cms; -using SiteServer.CMS.Core; -using SiteServer.CMS.Plugin; -using System.Web.UI.WebControls; - -namespace SiteServer.BackgroundPages.Core -{ - public class TextUtility - { - private TextUtility() - { - } - - private static string GetColumnValue(Dictionary nameValueCacheDict, SiteInfo siteInfo, ContentInfo contentInfo, TableStyleInfo styleInfo) - { - var value = string.Empty; - if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.AddUserName)) - { - if (!string.IsNullOrEmpty(contentInfo.AddUserName)) - { - var key = ContentAttribute.AddUserName + ":" + contentInfo.AddUserName; - if (!nameValueCacheDict.TryGetValue(key, out value)) - { - value = AdminManager.GetDisplayName(contentInfo.AddUserName, false); - nameValueCacheDict[key] = value; - } - } - } - else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.LastEditUserName)) - { - if (!string.IsNullOrEmpty(contentInfo.LastEditUserName)) - { - var key = ContentAttribute.LastEditUserName + ":" + contentInfo.LastEditUserName; - if (!nameValueCacheDict.TryGetValue(key, out value)) - { - value = AdminManager.GetDisplayName(contentInfo.LastEditUserName, false); - nameValueCacheDict[key] = value; - } - } - } - else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.CheckUserName)) - { - var checkUserName = contentInfo.GetString(ContentAttribute.CheckUserName); - if (!string.IsNullOrEmpty(checkUserName)) - { - var key = ContentAttribute.CheckUserName + ":" + checkUserName; - if (!nameValueCacheDict.TryGetValue(key, out value)) - { - value = AdminManager.GetDisplayName(checkUserName, false); - nameValueCacheDict[key] = value; - } - } - } - else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.CheckCheckDate)) - { - var checkDate = contentInfo.GetString(ContentAttribute.CheckCheckDate); - if (!string.IsNullOrEmpty(checkDate)) - { - value = DateUtils.GetDateAndTimeString(TranslateUtils.ToDateTime(checkDate)); - } - } - else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.CheckReasons)) - { - value = contentInfo.GetString(ContentAttribute.CheckReasons); - } - else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.AddDate)) - { - value = DateUtils.GetDateAndTimeString(contentInfo.AddDate); - } - else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.LastEditDate)) - { - value = DateUtils.GetDateAndTimeString(contentInfo.LastEditDate); - } - else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.SourceId)) - { - value = SourceManager.GetSourceName(contentInfo.SourceId); - } - else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.Tags)) - { - value = contentInfo.Tags; - } - else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.GroupNameCollection)) - { - value = contentInfo.GroupNameCollection; - } - else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.Hits)) - { - value = contentInfo.Hits.ToString(); - } - else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.HitsByDay)) - { - value = contentInfo.HitsByDay.ToString(); - } - else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.HitsByWeek)) - { - value = contentInfo.HitsByWeek.ToString(); - } - else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.HitsByMonth)) - { - value = contentInfo.HitsByMonth.ToString(); - } - else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.LastHitsDate)) - { - value = DateUtils.GetDateAndTimeString(contentInfo.LastHitsDate); - } - else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.IsTop) || StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.IsColor) || StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.IsHot) || StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.IsRecommend)) - { - value = StringUtils.GetTrueImageHtml(contentInfo.GetString(styleInfo.AttributeName)); - } - else - { - value = InputParserUtility.GetContentByTableStyle(contentInfo.GetString(styleInfo.AttributeName), siteInfo, styleInfo); - } - return value; - } - - public static bool IsEdit(SiteInfo siteInfo, int channelId, PermissionManager permissionManager) - { - return permissionManager.HasChannelPermissions(siteInfo.Id, channelId, ConfigManager.ChannelPermissions.ContentEdit); - } - - //public static bool IsComment(SiteInfo siteInfo, int channelId, string administratorName) - //{ - // return siteInfo.Additional.IsCommentable && AdminUtility.HasChannelPermissions(administratorName, siteInfo.Id, channelId, ConfigManager.Permissions.Channel.CommentCheck, ConfigManager.Permissions.Channel.CommentDelete); - //} - - public static string GetColumnsHeadHtml(List tableStyleInfoList, StringCollection attributesOfDisplay, SiteInfo siteInfo) - { - var builder = new StringBuilder(); - - var styleInfoList = ContentUtility.GetAllTableStyleInfoList(tableStyleInfoList); - - foreach (var styleInfo in styleInfoList) - { - if (!attributesOfDisplay.Contains(styleInfo.AttributeName) || styleInfo.AttributeName == ContentAttribute.Title) continue; - builder.Append($@"{styleInfo.DisplayName}"); - } - - return builder.ToString(); - } - - public static string GetColumnsHtml(Dictionary nameValueCacheDict, SiteInfo siteInfo, ContentInfo contentInfo, StringCollection attributesOfDisplay, List displayStyleInfoList) - { - var builder = new StringBuilder(); - - foreach (var styleInfo in displayStyleInfoList) - { - if (!attributesOfDisplay.Contains(styleInfo.AttributeName) || styleInfo.AttributeName == ContentAttribute.Title) continue; - - var value = GetColumnValue(nameValueCacheDict, siteInfo, contentInfo, styleInfo); - builder.Append($@"{value}"); - } - - return builder.ToString(); - } - - public static string GetCommandsHtml(SiteInfo siteInfo, Dictionary> pluginLinks, ContentInfo contentInfo, string pageUrl, string administratorName, bool isEdit) - { - var builder = new StringBuilder(); - - if (isEdit || administratorName == contentInfo.AddUserName) - { - builder.Append($@"编辑"); - } - - //if (isComment) - //{ - // //var urlComment = PageComment.GetRedirectUrl(siteInfo.SiteId, contentInfo.ChannelId, contentInfo.Id, pageUrl); - // var urlComment = PageComments.GetRedirectUrl(siteInfo.Id, contentInfo.ChannelId, contentInfo.Id, pageUrl); - // builder.Append( - // $@"评论({contentInfo - // .Comments})"); - //} - - if (pluginLinks != null) - { - foreach (var pluginId in pluginLinks.Keys) - { - var contentLinks = pluginLinks[pluginId]; - if (contentLinks != null && contentLinks.Count > 0) - { - foreach (var link in contentLinks) - { - var originalUrl = link.NavigateUrl; - link.NavigateUrl = PluginMenuManager.GetMenuContentHref(pluginId, originalUrl, siteInfo.Id, contentInfo.ChannelId, contentInfo.Id, pageUrl); - - builder.Append("  ").Append(ControlUtils.GetControlRenderHtml(link)); - - link.NavigateUrl = originalUrl; - - //builder.Append( - // $@"{link.Text}"); - } - } - } - } - - return builder.ToString(); - } - - //public static string GetCommandItemRowsHtml(SiteInfo siteInfo, Dictionary pluginChannels, ContentInfo contentInfo, string pageUrl, string administratorName) - //{ - // var builder = new StringBuilder(); - - // foreach (var pluginId in pluginChannels.Keys) - // { - // var pluginChannel = pluginChannels[pluginId]; - // if (pluginChannel?.ContentLinks != null && pluginChannel.ContentLinks.Count > 0) - // { - // foreach (var link in pluginChannel.ContentLinks) - // { - // var href = PluginUtils.GetMenuContentHref(pluginId, link.Href, - // siteInfo.Id, contentInfo.ChannelId, contentInfo.Id, pageUrl); - // builder.Append( - // $@"{link.Text}"); - // } - // } - // } - - // //if (modelType == EContentModelType.Photo) - // //{ - // // var contentPhotoUploadUrl = PageContentPhotoUpload.GetRedirectUrl(siteInfo.Id, contentInfo.ChannelId, contentInfo.Id, pageUrl); - // // builder.Append( - // // $@"图片({contentInfo - // // .Photos})"); - // //} - // //else if (modelType == EContentModelType.Job) - // //{ - // // var resumeNum = DataProvider.ResumeContentDao.GetCount(siteInfo.Id, contentInfo.Id); - // // var urlResume = PageResumeContent.GetRedirectUrl(siteInfo.Id, contentInfo.Id, StringUtils.ValueToUrl(pageUrl));; - // // builder.Append( - // // $@"简历({resumeNum})"); - // //} - - // if (siteInfo.Additional.IsCommentable) - // { - // if (AdminUtility.HasChannelPermissions(administratorName, siteInfo.Id, contentInfo.ChannelId, ConfigManager.Permissions.Channel.CommentCheck, ConfigManager.Permissions.Channel.CommentDelete)) - // { - // //var urlComment = PageComment.GetRedirectUrl(siteInfo.SiteId, contentInfo.ChannelId, contentInfo.Id, pageUrl); - // var urlComment = PageComments.GetRedirectUrl(siteInfo.Id, contentInfo.ChannelId, contentInfo.Id, pageUrl); - // builder.Append( - // $@"评论({contentInfo - // .Comments})"); - // } - // } - - // return builder.ToString(); - //} - } -} diff --git a/SiteServer.BackgroundPages/Core/WebUtils.cs b/SiteServer.BackgroundPages/Core/WebUtils.cs deleted file mode 100644 index c677ce4b4..000000000 --- a/SiteServer.BackgroundPages/Core/WebUtils.cs +++ /dev/null @@ -1,503 +0,0 @@ -using System.Text; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Ajax; -using SiteServer.BackgroundPages.Cms; -using SiteServer.BackgroundPages.Settings; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Core -{ - public class WebUtils - { - public static string GetContentTitle(SiteInfo siteInfo, ContentInfo contentInfo, string pageUrl) - { - string url; - var title = ContentUtility.FormatTitle(contentInfo.GetString(BackgroundContentAttribute.TitleFormatString), contentInfo.Title); - - var displayString = contentInfo.IsColor ? $"{title}" : title; - - if (contentInfo.ChannelId < 0) - { - url = displayString; - } - else if (contentInfo.IsChecked) - { - url = - $"{displayString}"; - } - else - { - url = - $"{displayString}"; - } - - var image = string.Empty; - if (contentInfo.IsRecommend) - { - image += " "; - } - if (contentInfo.IsHot) - { - image += " "; - } - if (contentInfo.IsTop) - { - image += " "; - } - if (contentInfo.ReferenceId > 0) - { - if (contentInfo.GetString(ContentAttribute.TranslateContentType) == ETranslateContentType.ReferenceContent.ToString()) - { - image += " (引用内容)"; - } - else if (contentInfo.GetString(ContentAttribute.TranslateContentType) != ETranslateContentType.ReferenceContent.ToString()) - { - image += " (引用地址)"; - } - } - if (!string.IsNullOrEmpty(contentInfo.GetString(ContentAttribute.LinkUrl))) - { - image += " "; - } - if (!string.IsNullOrEmpty(contentInfo.GetString(BackgroundContentAttribute.ImageUrl))) - { - var imageUrl = PageUtility.ParseNavigationUrl(siteInfo, contentInfo.GetString(BackgroundContentAttribute.ImageUrl), true); - var openWindowString = ModalMessage.GetOpenWindowString(siteInfo.Id, "预览图片", $"", 500, 500); - image += - $@" "; - } - if (!string.IsNullOrEmpty(contentInfo.GetString(BackgroundContentAttribute.VideoUrl))) - { - var openWindowString = ModalMessage.GetOpenWindowStringToPreviewVideoByUrl(siteInfo.Id, contentInfo.GetString(BackgroundContentAttribute.VideoUrl)); - image += - $@" "; - } - if (!string.IsNullOrEmpty(contentInfo.GetString(BackgroundContentAttribute.FileUrl))) - { - image += " "; - if (siteInfo.Additional.IsCountDownload) - { - var count = CountManager.GetCount(siteInfo.TableName, contentInfo.Id.ToString(), ECountType.Download); - image += $"下载次数:{count}"; - } - } - if (!string.IsNullOrEmpty(contentInfo.WritingUserName)) - { - var openWindowString = ModalUserView.GetOpenWindowString(contentInfo.WritingUserName); - image += - $@" (投稿用户:{contentInfo.WritingUserName})"; - } - return url + image; - } - - public static string GetChannelListBoxTitle(int siteId, int channelId, string nodeName, int parentsCount, bool isLastNode, bool[] isLastNodeArray) - { - var str = string.Empty; - if (channelId == siteId) - { - isLastNode = true; - } - if (isLastNode == false) - { - isLastNodeArray[parentsCount] = false; - } - else - { - isLastNodeArray[parentsCount] = true; - } - for (var i = 0; i < parentsCount; i++) - { - str = string.Concat(str, isLastNodeArray[i] ? " " : "│"); - } - str = string.Concat(str, isLastNode ? "└" : "├"); - str = string.Concat(str, StringUtils.MaxLengthText(nodeName, 8)); - - return str; - } - - public static string GetContentAddUploadWordUrl(int siteId, ChannelInfo nodeInfo, bool isFirstLineTitle, bool isFirstLineRemove, bool isClearFormat, bool isFirstLineIndent, bool isClearFontSize, bool isClearFontFamily, bool isClearImages, int contentLevel, string fileName, string returnUrl) - { - return - $"{PageContentAdd.GetRedirectUrlOfAdd(siteId, nodeInfo.Id, returnUrl)}&isUploadWord=True&isFirstLineTitle={isFirstLineTitle}&isFirstLineRemove={isFirstLineRemove}&isClearFormat={isClearFormat}&isFirstLineIndent={isFirstLineIndent}&isClearFontSize={isClearFontSize}&isClearFontFamily={isClearFontFamily}&isClearImages={isClearImages}&contentLevel={contentLevel}&fileName={fileName}"; - } - - public static string GetContentAddAddUrl(int siteId, ChannelInfo nodeInfo, string returnUrl) - { - return PageContentAdd.GetRedirectUrlOfAdd(siteId, nodeInfo.Id, returnUrl); - } - - public static string GetContentAddEditUrl(int siteId, ChannelInfo nodeInfo, int id, string returnUrl) - { - return PageContentAdd.GetRedirectUrlOfEdit(siteId, nodeInfo.Id, id, returnUrl); - } - - public static string GetContentCommands(PermissionManager permissionManager, SiteInfo siteInfo, ChannelInfo nodeInfo, string pageUrl) - { - var builder = new StringBuilder(); - - if (permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ContentAdd) && nodeInfo.Additional.IsContentAddable) - { - builder.Append($@" - - - 添加 -"); - - builder.Append($@" - - 导入Word -"); - } - - if (nodeInfo.ContentNum > 0 && permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ContentDelete)) - { - builder.Append($@" - - - 删 除 -"); - } - - if (nodeInfo.ContentNum > 0) - { - if (permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ContentEdit)) - { - builder.Append($@" - - - 属性 -"); - builder.Append($@" - - 内容组 -"); - } - if (permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ContentTranslate)) - { - var redirectUrl = PageContentTranslate.GetRedirectUrl(siteInfo.Id, nodeInfo.Id, pageUrl); - var clickString = PageUtils.GetRedirectStringWithCheckBoxValue(redirectUrl, "contentIdCollection", "contentIdCollection", "请选择需要转移的内容!"); - builder.Append($@" - - 转 移 -"); - } - if (permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ContentEdit)) - { - builder.Append($@" - - 排 序 -"); - } - if (permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ContentCheck)) - { - builder.Append($@" - - 审 核 -"); - } - if (permissionManager.HasSitePermissions(siteInfo.Id, ConfigManager.WebSitePermissions.Create) || permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.CreatePage)) - { - builder.Append($@" - - - 生 成 -"); - } - } - - if (permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ChannelEdit)) - { - builder.Append($@" - - - 显示项 -"); - } - - if (nodeInfo.ContentNum > 0) - { - builder.Append(@" - - - 查找 -"); - } - - return builder.ToString(); - } - - public static string GetContentMoreCommands(PermissionManager permissionManager, SiteInfo siteInfo, ChannelInfo nodeInfo, string pageUrl) - { - var builder = new StringBuilder(); - - if (permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ContentAdd) && nodeInfo.Additional.IsContentAddable) - { - builder.Append($@" - - 导 入 -"); - } - - if (nodeInfo.ContentNum > 0) - { - builder.Append($@" - - 导 出 -"); - if (permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ContentOrder)) - { - builder.Append($@" - - 整 理 -"); - } - if (permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ContentArchive)) - { - builder.Append($@" - - 归 档 -"); - } - if (CrossSiteTransUtility.IsCrossSiteTrans(siteInfo, nodeInfo) && !CrossSiteTransUtility.IsAutomatic(nodeInfo)) - { - builder.Append($@" - - 跨站转发 -"); - } - } - - return builder.ToString(); - } - - public static string GetChannelCommands(PermissionManager permissionManager, SiteInfo siteInfo, ChannelInfo nodeInfo, string pageUrl, string currentFileName) - { - var iconUrl = SiteServerAssets.GetIconUrl(string.Empty); - var builder = new StringBuilder(); - //添加栏目 - if (permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ChannelAdd) && nodeInfo.Additional.IsChannelAddable) - { - builder.Append( - $@"添加栏目  |  "); - builder.Append( - $@"快速添加  |  "); - } - if (nodeInfo.ChildrenCount > 0) - { - //删除栏目 - if (permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ChannelDelete)) - { - builder.Append( - $@"删除栏目  |  "); - } - //清空内容 - if (permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ContentDelete)) - { - builder.Append( - $@"清空内容  |  "); - } - - if (permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ChannelAdd)) - { - //导 入 - if (nodeInfo.Additional.IsChannelAddable) - { - builder.Append( - $@"导 入  |  "); - } - //导 出 - builder.Append( - $@"导 出  |  "); - } - - //设置栏目组 - if (permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ChannelEdit)) - { - builder.Append( - $@"设置栏目组  |  "); - } - //转 移 - if (permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ChannelTranslate)) - { - builder.Append( - $@"转 移  |  "); - } - - //生 成 - if (permissionManager.HasSitePermissions(siteInfo.Id, ConfigManager.WebSitePermissions.Create) || permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.CreatePage)) - { - builder.Append( - $@"生 成  |  "); - } - } - else - { - //导 入 - if (permissionManager.HasChannelPermissions(siteInfo.Id, nodeInfo.Id, ConfigManager.ChannelPermissions.ChannelAdd) && nodeInfo.Additional.IsChannelAddable) - { - builder.Append( - $@"导 入  |  "); - } - } - if (siteInfo.Id != nodeInfo.Id) - { - builder.Append( - $@"向 上  |  "); - } - if (builder.Length > 0) - { - builder.Length = builder.Length - 15; - } - return builder.ToString(); - } - - public static string GetTextEditorCommands(SiteInfo siteInfo, string attributeName) - { - return $@" - -
    - - - - - - -
    -"; - } - - public static string GetAutoCheckKeywordsScript(SiteInfo siteInfo) - { - var isAutoCheckKeywords = siteInfo.Additional.IsAutoCheckKeywords.ToString().ToLower(); - var url = AjaxCmsService.GetDetectionReplaceUrl(siteInfo.Id); - var getPureText = ETextEditorTypeUtils.GetPureTextScript(BackgroundContentAttribute.Content); - var getContent = ETextEditorTypeUtils.GetContentScript(BackgroundContentAttribute.Content); - var setContent = ETextEditorTypeUtils.GetSetContentScript(BackgroundContentAttribute.Content, "htmlContent"); - var tipsWarn = AlertUtils.Warning("敏感词检测", "内容中共检测到' + i + '个敏感词,已用黄色背景标明", "取 消", "自动替换并保存", - "autoReplaceKeywords"); - - var command = $@" - -"; - - - - return command; - } - - public static string GetImageUrlButtonGroupHtml(SiteInfo siteInfo, string attributeName) - { - return $@" -
    - - - - -
    -"; - } - } -} diff --git a/SiteServer.BackgroundPages/PageFindPwd.cs b/SiteServer.BackgroundPages/PageFindPwd.cs deleted file mode 100644 index 1d632a7e8..000000000 --- a/SiteServer.BackgroundPages/PageFindPwd.cs +++ /dev/null @@ -1,159 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; - -namespace SiteServer.BackgroundPages -{ - public class PageFindPwd : BasePage - { - protected Literal LtlPageTitle; - protected Literal LtlMessage; - - protected PlaceHolder PhStepAccount; - protected TextBox TbAccount; - protected TextBox TbValidateCode; - protected Literal LtlValidateCodeImage; - - protected PlaceHolder PhStepSmsCode; - protected TextBox TbSmsCode; - - protected PlaceHolder PhStepChangePassword; - protected TextBox TbPassword; - protected TextBox TbConfirmPassword; - - private VcManager _vcManager; - - protected override bool IsAccessable => true; - - private string GetMessageHtml(string message, bool isError) => $@"
    {message}
    "; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - _vcManager = VcManager.GetInstance(); - if (Page.IsPostBack) return; - - if (!ConfigManager.SystemConfigInfo.IsAdminFindPassword) - { - PageUtils.RedirectToErrorPage("基于安全考虑,找回密码功能已关闭,如需使用请与管理员联系!"); - } - else if (!SmsManager.IsReady() || string.IsNullOrEmpty(ConfigManager.SystemConfigInfo.AdminFindPasswordSmsTplId)) - { - PageUtils.RedirectToErrorPage("短信验证码发送功能未开启或配置不正确,找回密码功能无法使用,如需使用请与管理员联系!"); - } - - LtlValidateCodeImage.Text = - $@""; - - LtlPageTitle.Text = "找回密码"; - } - - public void Account_OnClick(object sender, EventArgs e) - { - var account = TbAccount.Text; - - if (!_vcManager.IsCodeValid(TbValidateCode.Text)) - { - LtlMessage.Text = GetMessageHtml("验证码不正确,请重新输入!", true); - return; - } - - string userName = null; - if (StringUtils.IsMobile(account)) - { - userName = DataProvider.AdministratorDao.GetUserNameByMobile(account); - } - else if (StringUtils.IsEmail(account)) - { - userName = DataProvider.AdministratorDao.GetUserNameByEmail(account); - } - else - { - if (DataProvider.AdministratorDao.IsAdminNameExists(account)) - { - userName = account; - } - } - - if (string.IsNullOrEmpty(userName)) - { - LtlMessage.Text = GetMessageHtml("找回密码错误,输入的账号不存在", true); - return; - } - - var mobile = DataProvider.AdministratorDao.GetMobileByUserName(account); - if (string.IsNullOrEmpty(mobile) || !StringUtils.IsMobile(mobile)) - { - LtlMessage.Text = GetMessageHtml("找回密码错误,账号对应的管理员未设置手机号码", true); - return; - } - - string errorMessage; - var code = StringUtils.GetRandomInt(1111, 9999); - CacheDbUtils.RemoveAndInsert($"BaiRong.BackgroundPages.FrameworkFindPwd.{userName}.Code", code.ToString()); - var isSend = SmsManager.SendCode(mobile, code, ConfigManager.SystemConfigInfo.AdminFindPasswordSmsTplId, out errorMessage); - if (!isSend) - { - LtlMessage.Text = GetMessageHtml($"找回密码错误:{errorMessage}", true); - return; - } - - ViewState["UserName"] = userName; - LtlPageTitle.Text = "验证手机"; - LtlMessage.Text = GetMessageHtml($"短信验证码已发送至:{mobile.Substring(0, 3) + "*****" + mobile.Substring(8)}", true); - PhStepAccount.Visible = false; - PhStepSmsCode.Visible = true; - PhStepChangePassword.Visible = false; - } - - public void SmsCode_OnClick(object sender, EventArgs e) - { - var smsCode = TbSmsCode.Text; - var userName = ViewState["UserName"]; - var code = CacheDbUtils.GetValueAndRemove($"BaiRong.BackgroundPages.FrameworkFindPwd.{userName}.Code"); - - if (smsCode != code) - { - LtlMessage.Text = GetMessageHtml("找回密码错误:短信验证码不正确", true); - return; - } - - LtlPageTitle.Text = "重设密码"; - LtlMessage.Text = string.Empty; - PhStepAccount.Visible = false; - PhStepSmsCode.Visible = false; - PhStepChangePassword.Visible = true; - } - - public void ChangePassword_OnClick(object sender, EventArgs e) - { - var userName = ViewState["UserName"] as string; - - var password = TbPassword.Text; - var confirmPassword = TbConfirmPassword.Text; - - if (password != confirmPassword) - { - LtlMessage.Text = GetMessageHtml("重设密码错误:新密码与确认密码不一致", true); - return; - } - - string errorMessage; - if (!DataProvider.AdministratorDao.ChangePassword(userName, password, out errorMessage)) - { - LtlMessage.Text = GetMessageHtml($"重设密码错误:{errorMessage}", true); - return; - } - - LtlPageTitle.Text = "密码设置成功"; - LtlMessage.Text = GetMessageHtml("密码设置成功,系统将跳转至登录页面", false); - AddWaitAndRedirectScript("login.aspx"); - PhStepAccount.Visible = false; - PhStepSmsCode.Visible = false; - PhStepChangePassword.Visible = false; - } - } -} diff --git a/SiteServer.BackgroundPages/PageLogin.cs b/SiteServer.BackgroundPages/PageLogin.cs deleted file mode 100644 index 8a482b2d3..000000000 --- a/SiteServer.BackgroundPages/PageLogin.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; - -namespace SiteServer.BackgroundPages -{ - public class PageLogin : BasePage - { - public Literal LtlMessage; - public TextBox TbAccount; - public TextBox TbPassword; - public TextBox TbValidateCode; - public Literal LtlValidateCodeImage; - public CheckBox CbRememberMe; - public PlaceHolder PhFindPassword; - - private VcManager _vcManager; // 验证码类 - - protected override bool IsAccessable => true; // 设置本页面是否能直接访问 如果为false,则必须管理员登录后才能访问 - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; // 如果无权访问页面,则返回空白页 - - try - { - _vcManager = VcManager.GetInstance(); // 构建验证码实例 - if (Page.IsPostBack) return; - - PhFindPassword.Visible = ConfigManager.SystemConfigInfo.IsAdminFindPassword; - - if (AuthRequest.IsQueryExists("error")) // 如果url参数error不为空,则把错误信息显示到页面上 - { - LtlMessage.Text = GetMessageHtml(AuthRequest.GetQueryString("error")); - } - - SystemManager.DetermineRedirectToInstaller(); // 判断是否需要安装,如果需要则转到安装页面。 - - LtlValidateCodeImage.Text = - $@""; - } - catch - { - // 再次探测是否需要安装或升级 - if (SystemManager.IsNeedInstall()) - { - PageUtils.Redirect(PageInstaller.GetRedirectUrl()); - } - else if (SystemManager.IsNeedUpdate()) - { - PageUtils.Redirect(PageSyncDatabase.GetRedirectUrl()); - } - else - { - throw; - } - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var account = TbAccount.Text; - var password = TbPassword.Text; - - if (!_vcManager.IsCodeValid(TbValidateCode.Text)) // 检测验证码是否正确 - { - LtlMessage.Text = GetMessageHtml("验证码不正确,请重新输入!"); - return; - } - - string userName; - string errorMessage; - if (!DataProvider.AdministratorDao.ValidateAccount(account, password, out userName, out errorMessage)) // 检测密码是否正确 - { - LogUtils.AddAdminLog(userName, "后台管理员登录失败"); - DataProvider.AdministratorDao.UpdateLastActivityDateAndCountOfFailedLogin(userName); // 记录最后登录时间、失败次数+1 - LtlMessage.Text = GetMessageHtml(errorMessage); // 把错误信息显示在页面上 - return; - } - - DataProvider.AdministratorDao.UpdateLastActivityDateAndCountOfLogin(userName); // 记录最后登录时间、失败次数清零 - AuthRequest.AdminLogin(userName); // 写Cookie并记录管理员操作日志 - PageUtils.Redirect(PageUtils.GetAdminDirectoryUrl(string.Empty)); // 跳转到登录成功的后台页 - } - - private string GetMessageHtml(string message) => $@"
    {message}
    "; - } -} diff --git a/SiteServer.BackgroundPages/PageLogout.cs b/SiteServer.BackgroundPages/PageLogout.cs deleted file mode 100644 index e313108e0..000000000 --- a/SiteServer.BackgroundPages/PageLogout.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using SiteServer.Utils; - -namespace SiteServer.BackgroundPages -{ - public class PageLogout : BasePage - { - protected override bool IsAccessable => true; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - var redirectUrl = PageUtils.GetAdminDirectoryUrl("login.aspx"); - - AuthRequest.AdminLogout(); - PageUtils.Redirect(PageUtils.ParseNavigationUrl(redirectUrl)); - } - } -} diff --git a/SiteServer.BackgroundPages/PageMain.cs b/SiteServer.BackgroundPages/PageMain.cs deleted file mode 100644 index 428f8c4be..000000000 --- a/SiteServer.BackgroundPages/PageMain.cs +++ /dev/null @@ -1,454 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Text; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Cms; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.BackgroundPages.Settings; -using SiteServer.CMS.Api; -using SiteServer.CMS.Api.Preview; -using SiteServer.CMS.Api.Sys.Packaging; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Packaging; -using SiteServer.CMS.Plugin; - -namespace SiteServer.BackgroundPages -{ - public class PageMain : BasePageCms - { - public Literal LtlTopMenus; - public PlaceHolder PhSite; - public Literal LtlCreateStatus; - public NavigationTree NtLeftManagement; - public NavigationTree NtLeftFunctions; - - private SiteInfo _siteInfo = new SiteInfo(); - private SiteInfo _hqSiteInfo; - private readonly List _addedSiteIdList = new List(); - - protected override bool IsSinglePage => true; - - public string SignalrHubsUrl = ApiManager.SignalrHubsUrl; - - public string PackageIdSsCms = PackageUtils.PackageIdSsCms; - - public string PackageList - { - get - { - var list = new List(); - var dict = PluginManager.GetPluginIdAndVersionDict(); - foreach (var id in dict.Keys) - { - var version = dict[id]; - list.Add(new - { - id, - version - }); - } - return TranslateUtils.JsonSerialize(list); - } - } - - public string DownloadApiUrl => ApiRouteDownload.GetUrl(ApiManager.InnerApiUrl); - - public string CurrentVersion => SystemManager.Version; - - public string UpdateSystemUrl => PageUpdateSystem.GetRedirectUrl(); - - public static string GetRedirectUrl() - { - return PageUtils.GetSiteServerUrl(nameof(PageMain), null); - } - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetSiteServerUrl(nameof(PageMain), new NameValueCollection - { - {"siteId", siteId.ToString()} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - var siteId = SiteId; - - if (siteId == 0) - { - siteId = AuthRequest.AdminInfo.SiteId; - } - - var siteIdList = AuthRequest.AdminPermissions.SiteIdList; - - //站点要判断是否存在,是否有权限 - if (siteId == 0 || !SiteManager.IsExists(siteId) || !siteIdList.Contains(siteId)) - { - if (siteIdList != null && siteIdList.Count > 0) - { - siteId = siteIdList[0]; - } - } - - _siteInfo = SiteManager.GetSiteInfo(siteId); - - if (_siteInfo != null && _siteInfo.Id > 0) - { - if (SiteId == 0) - { - PageUtils.Redirect(GetRedirectUrl(_siteInfo.Id)); - return; - } - - var showSite = false; - - var permissionList = new List(AuthRequest.AdminPermissions.PermissionList); - - if (AuthRequest.AdminPermissions.HasSitePermissions(_siteInfo.Id)) - { - var websitePermissionList = AuthRequest.AdminPermissions.GetSitePermissions(_siteInfo.Id); - if (websitePermissionList != null) - { - showSite = true; - permissionList.AddRange(websitePermissionList); - } - } - - var channelPermissions = AuthRequest.AdminPermissions.GetChannelPermissions(_siteInfo.Id); - if (channelPermissions.Count > 0) - { - showSite = true; - permissionList.AddRange(channelPermissions); - } - - var siteIdHashtable = new Hashtable(); - if (siteIdList != null) - { - foreach (var theSiteId in siteIdList) - { - siteIdHashtable.Add(theSiteId, theSiteId); - } - } - - if (!siteIdHashtable.Contains(SiteId)) - { - showSite = false; - } - - if (!showSite) - { - PageUtils.RedirectToErrorPage("您没有此发布系统的操作权限!"); - return; - } - - LtlTopMenus.Text = GetTopMenuSitesHtml() + GetTopMenuLinksHtml() + GetTopMenusHtml(); - - PhSite.Visible = true; - - LtlCreateStatus.Text = $@" - - - - 0 - -"; - - NtLeftManagement.TopId = ConfigManager.TopMenu.IdSite; - NtLeftManagement.SiteId = _siteInfo.Id; - NtLeftManagement.PermissionList = permissionList; - - NtLeftFunctions.TopId = string.Empty; - NtLeftFunctions.SiteId = _siteInfo.Id; - NtLeftFunctions.PermissionList = permissionList; - - ClientScriptRegisterClientScriptBlock("NodeTreeScript", NodeNaviTreeItem.GetNavigationBarScript()); - } - else - { - if (AuthRequest.AdminPermissions.IsSystemAdministrator) - { - PageUtils.Redirect(PageSiteAdd.GetRedirectUrl()); - return; - } - } - - if (_siteInfo != null && _siteInfo.Id > 0 && AuthRequest.AdminInfo.SiteId != _siteInfo.Id) - { - DataProvider.AdministratorDao.UpdateSiteId(AuthRequest.AdminName, _siteInfo.Id); - } - } - - private void AddSite(StringBuilder builder, SiteInfo siteInfo, Dictionary> parentWithChildren, int level) - { - if (_addedSiteIdList.Contains(siteInfo.Id)) return; - - var loadingUrl = PageUtils.GetLoadingUrl(GetRedirectUrl(siteInfo.Id)); - - if (parentWithChildren.ContainsKey(siteInfo.Id)) - { - var children = parentWithChildren[siteInfo.Id]; - - builder.Append($@" -
  • - {siteInfo.SiteName} -
      -"); - - level++; - foreach (var subSiteInfo in children) - { - AddSite(builder, subSiteInfo, parentWithChildren, level); - } - - builder.Append(@" -
    -
  • "); - } - else - { - builder.Append( - $@"
  • {siteInfo.SiteName}
  • "); - } - - _addedSiteIdList.Add(siteInfo.Id); - } - - private string GetTopMenuSitesHtml() - { - var siteIdList = AuthRequest.AdminPermissions.SiteIdList; - - if (!AuthRequest.AdminPermissions.IsSystemAdministrator && siteIdList.Count == 0) - { - return string.Empty; - } - - //操作者拥有的站点列表 - var mySystemInfoList = new List(); - - var parentWithChildren = new Dictionary>(); - - if (AuthRequest.AdminPermissions.IsSystemAdministrator) - { - foreach (var siteId in siteIdList) - { - AddToMySystemInfoList(mySystemInfoList, parentWithChildren, siteId); - } - } - else - { - var permissionSiteIdList = AuthRequest.AdminPermissions.SiteIdList; - var permissionChannelIdList = AuthRequest.AdminPermissions.ChannelPermissionChannelIdList; - foreach (var siteId in siteIdList) - { - var showSite = IsShowSite(siteId, permissionSiteIdList, permissionChannelIdList); - if (showSite) - { - AddToMySystemInfoList(mySystemInfoList, parentWithChildren, siteId); - } - } - } - - var builder = new StringBuilder(); - - if (_hqSiteInfo != null || mySystemInfoList.Count > 0) - { - if (_hqSiteInfo != null) - { - AddSite(builder, _hqSiteInfo, parentWithChildren, 0); - } - - if (mySystemInfoList.Count > 0) - { - var count = 0; - foreach (var siteInfo in mySystemInfoList) - { - if (siteInfo.IsRoot == false) - { - count++; - AddSite(builder, siteInfo, parentWithChildren, 0); - } - if (count == 13) - { - builder.Append( - $@"
  • 列出全部站点...
  • "); - break; - } - } - } - } - - var clazz = "has-submenu"; - var menuText = "站点管理"; - if (_siteInfo != null && _siteInfo.Id > 0) - { - clazz = "has-submenu active"; - menuText = _siteInfo.SiteName; - if (_siteInfo.ParentId > 0) - { - menuText += $" ({SiteManager.GetSiteLevel(_siteInfo.Id) + 1}级)"; - } - } - - return $@"
  • - {menuText} -
      - {builder} -
    -
  • "; - } - - private string GetTopMenuLinksHtml() - { - if (_siteInfo == null || _siteInfo.Id <= 0) - { - return string.Empty; - } - - var builder = new StringBuilder(); - - builder.Append( - $@"
  • 访问站点
  • "); - builder.Append( - $@"
  • 预览站点
  • "); - - return $@"
  • - 站点链接 -
      - {builder} -
    -
  • "; - } - - private string GetTopMenusHtml() - { - var topMenuTabs = TabManager.GetTopMenuTabs(); - - if (topMenuTabs == null || topMenuTabs.Count == 0) - { - return string.Empty; - } - - var permissionList = new List(); - if (AuthRequest.AdminPermissions.HasSitePermissions(SiteId)) - { - var websitePermissionList = AuthRequest.AdminPermissions.GetSitePermissions(SiteId); - if (websitePermissionList != null) - { - permissionList.AddRange(websitePermissionList); - } - } - - permissionList.AddRange(AuthRequest.AdminPermissions.PermissionList); - - var builder = new StringBuilder(); - foreach (var tab in topMenuTabs) - { - if (!AuthRequest.AdminPermissions.IsConsoleAdministrator && !TabManager.IsValid(tab, permissionList)) continue; - - var tabs = TabManager.GetTabList(tab.Id, 0); - var tabsBuilder = new StringBuilder(); - foreach (var parent in tabs) - { - if (!AuthRequest.AdminPermissions.IsConsoleAdministrator && !TabManager.IsValid(parent, permissionList)) continue; - - var hasChildren = parent.Children != null && parent.Children.Length > 0; - - var parentUrl = !string.IsNullOrEmpty(parent.Href) ? PageUtils.GetLoadingUrl(parent.Href) : "javascript:;"; - var parentTarget = !string.IsNullOrEmpty(parent.Target) ? parent.Target : "right"; - - if (hasChildren) - { - tabsBuilder.Append($@" -
  • - {parent.Text} -
      -"); - - if (parent.Children != null && parent.Children.Length > 0) - { - foreach (var childTab in parent.Children) - { - var childTarget = !string.IsNullOrEmpty(childTab.Target) ? childTab.Target : "right"; - tabsBuilder.Append($@"
    • {childTab.Text}
    • "); - } - } - - tabsBuilder.Append(@" -
    -
  • "); - } - else - { - tabsBuilder.Append( - $@"
  • {parent.Text}
  • "); - } - } - - var url = !string.IsNullOrEmpty(tab.Href) ? PageUtils.ParseNavigationUrl(tab.Href) : "javascript:;"; - var target = !string.IsNullOrEmpty(tab.Target) ? tab.Target : "right"; - - builder.Append( - $@"
  • - {tab.Text} -
      - {tabsBuilder} -
    -
  • "); - } - - return builder.ToString(); - } - - private static bool IsShowSite(int siteId, List permissionSiteIdList, List permissionChannelIdList) - { - foreach (var permissionSiteId in permissionSiteIdList) - { - if (permissionSiteId == siteId) - { - return true; - } - } - foreach (var permissionChannelId in permissionChannelIdList) - { - if (ChannelManager.IsAncestorOrSelf(siteId, siteId, permissionChannelId)) - { - return true; - } - } - return false; - } - - private void AddToMySystemInfoList(List mySystemInfoList, Dictionary> parentWithChildren, int siteId) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - if (siteInfo == null) return; - - if (siteInfo.IsRoot) - { - _hqSiteInfo = siteInfo; - } - else if (siteInfo.ParentId > 0) - { - var children = new List(); - if (parentWithChildren.ContainsKey(siteInfo.ParentId)) - { - children = parentWithChildren[siteInfo.ParentId]; - } - children.Add(siteInfo); - parentWithChildren[siteInfo.ParentId] = children; - } - mySystemInfoList.Add(siteInfo); - } - } -} diff --git a/SiteServer.BackgroundPages/PageRight.cs b/SiteServer.BackgroundPages/PageRight.cs deleted file mode 100644 index 4554c8bbc..000000000 --- a/SiteServer.BackgroundPages/PageRight.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.CMS.Api; -using SiteServer.CMS.Api.Sys.Administrators; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Packaging; - -namespace SiteServer.BackgroundPages -{ - public class PageRight : BasePage - { - public Literal LtlVersionInfo; - public Literal LtlUpdateDate; - public Literal LtlLastLoginDate; - - public string SiteCheckListApiUrl => ApiRouteSiteCheckList.GetUrl(ApiManager.InnerApiUrl, AuthRequest.AdminName); - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - LtlVersionInfo.Text = SystemManager.Version == PackageUtils.VersionDev ? "dev" : SystemManager.Version; - - if (AuthRequest.AdminInfo.LastActivityDate != DateTime.MinValue) - { - LtlLastLoginDate.Text = DateUtils.GetDateAndTimeString(AuthRequest.AdminInfo.LastActivityDate); - } - - LtlUpdateDate.Text = DateUtils.GetDateAndTimeString(ConfigManager.Instance.UpdateDate); - } - } -} diff --git a/SiteServer.BackgroundPages/PageTest.cs b/SiteServer.BackgroundPages/PageTest.cs deleted file mode 100644 index 7a2fa5a0a..000000000 --- a/SiteServer.BackgroundPages/PageTest.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.IO; -using System.Reflection; -using System.Text; -using System.Text.RegularExpressions; -using System.Web.UI; -using System.Web.UI.WebControls; -using SiteServer.CMS.Model; -using SiteServer.CMS.Plugin.Apis; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.StlElement; -using SiteServer.Utils; - -namespace SiteServer.BackgroundPages -{ - public class PageTest : Page - { - public Literal LtlContent; - - public void Page_Load(object sender, EventArgs e) - { - FieldInfo[] fields = typeof(ChannelAttribute).GetFields(BindingFlags.Static | BindingFlags.Public); - - - LtlContent.Text = DisplayPropertyInfo(fields); - } - - public static string DisplayPropertyInfo(FieldInfo[] propInfos) - { - var builder = new StringBuilder(); - // Display information for all properties. - foreach (var propInfo in propInfos) - { - - builder.AppendFormat(" Property name: {0}", propInfo.Name); - builder.AppendFormat(" Property value: {0}", propInfo.GetValue(null)); - } - - return builder.ToString(); - } - } -} diff --git a/SiteServer.BackgroundPages/Plugins/ModalManualInstall.cs b/SiteServer.BackgroundPages/Plugins/ModalManualInstall.cs deleted file mode 100644 index 5ce32f3f1..000000000 --- a/SiteServer.BackgroundPages/Plugins/ModalManualInstall.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.IO; -using System.Web.UI.HtmlControls; -using System.Web.UI.WebControls; -using SiteServer.CMS.Packaging; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Plugins -{ - public class ModalManualInstall : BasePage - { - public RadioButtonList RblInstallType; - - public PlaceHolder PhFile; - public HtmlInputFile HifFile; - - public PlaceHolder PhIdAndVersion; - public TextBox TbPluginId; - public TextBox TbVersion; - - public static string GetOpenWindowString() - { - return LayerUtils.GetOpenScript("手动安装插件", PageUtils.GetPluginsUrl(nameof(ModalManualInstall), null), 560, 430); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (IsPostBack) return; - - EBooleanUtils.AddListItems(RblInstallType, "上传插件包", "指定插件Id与版本号"); - ControlUtils.SelectSingleItem(RblInstallType, true.ToString()); - } - - public void RblInstallType_SelectedIndexChanged(object sender, EventArgs e) - { - PhFile.Visible = TranslateUtils.ToBool(RblInstallType.SelectedValue); - PhIdAndVersion.Visible = !PhFile.Visible; - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (TranslateUtils.ToBool(RblInstallType.SelectedValue)) - { - if (HifFile.PostedFile == null || HifFile.PostedFile.FileName == "") return; - - var filePath = HifFile.PostedFile.FileName; - if (!StringUtils.EqualsIgnoreCase(Path.GetExtension(filePath), ".nupkg")) - { - FailMessage("必须上传后缀为.nupkg的文件"); - return; - } - - var idAndVersion = Path.GetFileNameWithoutExtension(filePath); - var directoryPath = PathUtils.GetPackagesPath(idAndVersion); - var localFilePath = PathUtils.Combine(directoryPath, idAndVersion + ".nupkg"); - - if (!Directory.Exists(directoryPath)) - { - Directory.CreateDirectory(directoryPath); - } - - HifFile.PostedFile.SaveAs(localFilePath); - - ZipUtils.UnpackFiles(localFilePath, directoryPath); - - string errorMessage; - if (!PackageUtils.UpdatePackage(idAndVersion, PackageType.Plugin, out errorMessage)) - { - FailMessage($"手动安装插件失败:{errorMessage}"); - return; - } - - AuthRequest.AddAdminLog("手动安装插件:" + idAndVersion); - - LayerUtils.CloseAndRedirect(Page, PageManagement.GetRedirectUrl()); - } - else - { - string errorMessage; - try - { - PackageUtils.DownloadPackage(TbPluginId.Text, TbVersion.Text); - } - catch (Exception ex) - { - FailMessage($"手动安装插件失败:{ex.Message}"); - return; - } - - var idWithVersion = $"{TbPluginId.Text}.{TbVersion.Text}"; - if (!PackageUtils.UpdatePackage(idWithVersion, PackageType.Plugin, out errorMessage)) - { - FailMessage($"手动安装插件失败:{errorMessage}"); - return; - } - - AuthRequest.AddAdminLog($"手动安装插件:{TbPluginId.Text} {TbVersion.Text}"); - - LayerUtils.CloseAndRedirect(Page, PageManagement.GetRedirectUrl()); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Plugins/PageAdd.cs b/SiteServer.BackgroundPages/Plugins/PageAdd.cs deleted file mode 100644 index abd6f7bc3..000000000 --- a/SiteServer.BackgroundPages/Plugins/PageAdd.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.Utils; - -namespace SiteServer.BackgroundPages.Plugins -{ - public class PageAdd : BasePage - { - public Button BtnUpload; - - public static string GetRedirectUrl() - { - return PageUtils.GetPluginsUrl(nameof(PageAdd), null); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (Page.IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.PluginsPermissions.Add); - - BtnUpload.OnClientClick = ModalManualInstall.GetOpenWindowString(); - } - } -} diff --git a/SiteServer.BackgroundPages/Plugins/PageInstall.cs b/SiteServer.BackgroundPages/Plugins/PageInstall.cs deleted file mode 100644 index 1a17f1d72..000000000 --- a/SiteServer.BackgroundPages/Plugins/PageInstall.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System; -using System.Collections.Specialized; -using SiteServer.CMS.Api; -using SiteServer.CMS.Api.Sys.Packaging; -using SiteServer.CMS.Core; -using SiteServer.CMS.Plugin; -using SiteServer.Utils; - -namespace SiteServer.BackgroundPages.Plugins -{ - public class PageInstall : BasePage - { - public static string GetRedirectUrl(bool isUpdate, string packageId) - { - return PageUtils.GetPluginsUrl(nameof(PageInstall), new NameValueCollection - { - { "type", isUpdate ? "update" : "install" }, - { "packageId", packageId } - }); - } - - public string Type => AuthRequest.GetQueryString("type") == "update" ? "升级" : "安装"; - - public string AdminUrl => PageUtils.GetAdminDirectoryUrl(string.Empty); - - public string PackagesIdAndVersionList => TranslateUtils.JsonSerialize(PluginManager.PackagesIdAndVersionList); - - public string PackageId { get; set; } - - public string DownloadApiUrl => ApiRouteDownload.GetUrl(ApiManager.InnerApiUrl); - - public string UpdateApiUrl => ApiRouteUpdate.GetUrl(ApiManager.InnerApiUrl); - - public string ClearCacheApiUrl => ApiRouteClearCache.GetUrl(ApiManager.InnerApiUrl); - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PackageId = AuthRequest.GetQueryString("packageId"); - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.PluginsPermissions.Add, ConfigManager.PluginsPermissions.Management); - } - } -} diff --git a/SiteServer.BackgroundPages/Properties/AssemblyInfo.cs b/SiteServer.BackgroundPages/Properties/AssemblyInfo.cs deleted file mode 100644 index def7b6441..000000000 --- a/SiteServer.BackgroundPages/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// 有关程序集的一般信息由以下 -// 控制。更改这些特性值可修改 -// 与程序集关联的信息。 -[assembly: AssemblyTitle("SiteServer.BackgroundPages")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("SiteServer.BackgroundPages")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// 将 ComVisible 设置为 false 会使此程序集中的类型 -//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 -//请将此类型的 ComVisible 特性设置为 true。 -[assembly: ComVisible(false)] - -// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID -[assembly: Guid("aab355c2-8dd2-43d3-880c-eb9b51a59971")] - -// 程序集的版本信息由下列四个值组成: -// -// 主版本 -// 次版本 -// 生成号 -// 修订号 -// -// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 -//通过使用 "*",如下所示: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.0.0")] -[assembly: AssemblyFileVersion("0.0.0")] -[assembly: AssemblyInformationalVersion("0.0.0")] diff --git a/SiteServer.BackgroundPages/Settings/ModalAdminPassword.cs b/SiteServer.BackgroundPages/Settings/ModalAdminPassword.cs deleted file mode 100644 index c7d34a5d1..000000000 --- a/SiteServer.BackgroundPages/Settings/ModalAdminPassword.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.Utils; - -namespace SiteServer.BackgroundPages.Settings -{ - public class ModalAdminPassword : BasePage - { - public Label LbUserName; - public TextBox TbPassword; - - private string _userName; - - public static string GetOpenWindowString(string userName) - { - return LayerUtils.GetOpenScript("重设密码", PageUtils.GetSettingsUrl(nameof(ModalAdminPassword), new NameValueCollection - { - {"userName", userName} - }), 520, 300); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - _userName = AuthRequest.GetQueryString("userName"); - - if (IsPostBack) return; - - if (!string.IsNullOrEmpty(_userName) && DataProvider.AdministratorDao.IsAdminNameExists(_userName)) - { - LbUserName.Text = _userName; - } - else - { - FailMessage("此帐户不存在!"); - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!IsPostBack || !IsValid) return; - - try - { - string errorMessage; - if (!DataProvider.AdministratorDao.ChangePassword(_userName, TbPassword.Text, out errorMessage)) - { - FailMessage(errorMessage); - return; - } - - AuthRequest.AddAdminLog("重设管理员密码", $"管理员:{_userName}"); - - SuccessMessage("重设密码成功!"); - - LayerUtils.Close(Page); - } - catch(Exception ex) - { - FailMessage(ex, "重设密码失败!"); - } - } - - } -} diff --git a/SiteServer.BackgroundPages/Settings/ModalAdminView.cs b/SiteServer.BackgroundPages/Settings/ModalAdminView.cs deleted file mode 100644 index e3ba97e49..000000000 --- a/SiteServer.BackgroundPages/Settings/ModalAdminView.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.Utils; - -namespace SiteServer.BackgroundPages.Settings -{ - public class ModalAdminView : BasePage - { - protected Literal LtlUserName; - protected Literal LtlDisplayName; - protected Literal LtlCreationDate; - protected Literal LtlLastActivityDate; - protected Literal LtlEmail; - protected Literal LtlMobile; - protected Literal LtlRoles; - - public static string GetOpenWindowString(string userName) - { - return LayerUtils.GetOpenScript("查看管理员资料", PageUtils.GetSettingsUrl(nameof(ModalAdminView), new NameValueCollection - { - {"UserName", userName} - }), 500, 500); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - var userName = AuthRequest.GetQueryString("UserName"); - var adminInfo = DataProvider.AdministratorDao.GetByUserName(userName); - LtlUserName.Text = adminInfo.UserName; - LtlDisplayName.Text = adminInfo.DisplayName; - LtlCreationDate.Text = DateUtils.GetDateAndTimeString(adminInfo.CreationDate); - LtlLastActivityDate.Text = DateUtils.GetDateAndTimeString(adminInfo.LastActivityDate); - LtlEmail.Text = adminInfo.Email; - LtlMobile.Text = adminInfo.Mobile; - LtlRoles.Text = AdminManager.GetRolesHtml(userName); - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/ModalAuxiliaryTableAdd.cs b/SiteServer.BackgroundPages/Settings/ModalAuxiliaryTableAdd.cs deleted file mode 100644 index 9a2ba859b..000000000 --- a/SiteServer.BackgroundPages/Settings/ModalAuxiliaryTableAdd.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils; - -namespace SiteServer.BackgroundPages.Settings -{ - public class ModalAuxiliaryTableAdd : BasePageCms - { - public TextBox TbTableName; - public TextBox TbDisplayName; - public TextBox TbDescription; - - private string _tableName; - - public static string GetOpenWindowString() - { - return LayerUtils.GetOpenScript("添加辅助表", PageUtils.GetSettingsUrl(nameof(ModalAuxiliaryTableAdd), null), 580, 450); - } - - public static string GetOpenWindowString(string tableName) - { - return LayerUtils.GetOpenScript("编辑辅助表", PageUtils.GetSettingsUrl(nameof(ModalAuxiliaryTableAdd), new NameValueCollection - { - {"tableName", tableName} - }), 580, 450); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - _tableName = AuthRequest.GetQueryString("tableName"); - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Site); - - if (!string.IsNullOrEmpty(_tableName)) - { - var info = DataProvider.TableDao.GetTableCollectionInfo(_tableName); - if (info != null) - { - TbTableName.Text = info.TableName; - TbTableName.Enabled = false; - TbDisplayName.Text = info.DisplayName; - TbDescription.Text = info.Description; - } - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - if (!string.IsNullOrEmpty(_tableName)) - { - var info = DataProvider.TableDao.GetTableCollectionInfo(_tableName); - info.DisplayName = TbDisplayName.Text; - info.Description = TbDescription.Text; - - DataProvider.TableDao.Update(info); - - AuthRequest.AddAdminLog("修改辅助表", $"辅助表:{_tableName}"); - - SuccessMessage("辅助表修改成功!"); - LayerUtils.Close(Page); - } - else - { - var tableNameList = DataProvider.TableDao.GetTableNameList(); - if (tableNameList.IndexOf(TbTableName.Text) != -1) - { - FailMessage("辅助表添加失败,辅助表标识已存在!"); - } - else if (DataProvider.DatabaseDao.IsTableExists(TbTableName.Text)) - { - FailMessage("辅助表添加失败,数据库中已存在此表!"); - } - else - { - var info = new TableInfo - { - TableName = TbTableName.Text, - DisplayName = TbDisplayName.Text, - Description = TbDescription.Text - }; - - DataProvider.TableDao.Insert(info, DataProvider.TableMetadataDao.GetDefaultTableMetadataInfoList(info.TableName)); - - AuthRequest.AddAdminLog("添加辅助表", $"辅助表:{TbTableName.Text}"); - - SuccessMessage("辅助表添加成功!"); - LayerUtils.Close(Page); - } - } - } - - } -} diff --git a/SiteServer.BackgroundPages/Settings/ModalExportMessage.cs b/SiteServer.BackgroundPages/Settings/ModalExportMessage.cs deleted file mode 100644 index 7abeaacc2..000000000 --- a/SiteServer.BackgroundPages/Settings/ModalExportMessage.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.CMS.Api; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.ImportExport; - -namespace SiteServer.BackgroundPages.Settings -{ - public class ModalExportMessage : BasePage - { - private string _exportType; - public const string ExportTypeSingleTableStyle = "SingleTableStyle"; - - public static string GetOpenWindowStringToSingleTableStyle(string tableName) - { - return LayerUtils.GetOpenScript("导出数据", - PageUtils.GetSettingsUrl(nameof(ModalExportMessage), new NameValueCollection - { - {"TableName", tableName}, - {"ExportType", ExportTypeSingleTableStyle} - }), 380, 250); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - _exportType = AuthRequest.GetQueryString("ExportType"); - - if (!IsPostBack) - { - var fileName = string.Empty; - try - { - if (_exportType == ExportTypeSingleTableStyle) - { - var tableName = AuthRequest.GetQueryString("TableName"); - fileName = ExportSingleTableStyle(tableName); - } - - var link = new HyperLink(); - var filePath = PathUtils.GetTemporaryFilesPath(fileName); - link.NavigateUrl = ApiRouteActionsDownload.GetUrl(ApiManager.InnerApiUrl, filePath); - link.Text = "下载"; - var successMessage = "成功导出文件!  " + ControlUtils.GetControlRenderHtml(link); - SuccessMessage(successMessage); - } - catch (Exception ex) - { - var failedMessage = "文件导出失败!

    原因为:" + ex.Message; - FailMessage(ex, failedMessage); - } - } - } - - private static string ExportSingleTableStyle(string tableName) - { - return ExportObject.ExportRootSingleTableStyle(tableName); - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/ModalKeywordAdd.cs b/SiteServer.BackgroundPages/Settings/ModalKeywordAdd.cs deleted file mode 100644 index 4e588e7b8..000000000 --- a/SiteServer.BackgroundPages/Settings/ModalKeywordAdd.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class ModalKeywordAdd : BasePageCms - { - protected TextBox TbKeyword; - protected TextBox TbAlternative; - protected DropDownList DdlGrade; - - private int _keywordId; - - public static string GetOpenWindowStringToAdd() - { - return LayerUtils.GetOpenScript("添加敏感词", PageUtils.GetSettingsUrl(nameof(ModalKeywordAdd), null), 460, 300); - } - - public static string GetOpenWindowStringToEdit(int keywordId) - { - return LayerUtils.GetOpenScript("修改敏感词", - PageUtils.GetSettingsUrl(nameof(ModalKeywordAdd), new NameValueCollection - { - {"KeywordID", keywordId.ToString()} - }), 460, 300); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - _keywordId = AuthRequest.GetQueryInt("KeywordID"); - - if (IsPostBack) return; - - EKeywordGradeUtils.AddListItems(DdlGrade); - if (_keywordId <= 0) return; - - var keywordInfo = DataProvider.KeywordDao.GetKeywordInfo(_keywordId); - TbKeyword.Text = keywordInfo.Keyword; - TbAlternative.Text = keywordInfo.Alternative; - ControlUtils.SelectSingleItem(DdlGrade, EKeywordGradeUtils.GetValue(keywordInfo.Grade)); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var isChanged = false; - - if (_keywordId > 0) - { - try - { - var keywordInfo = DataProvider.KeywordDao.GetKeywordInfo(_keywordId); - keywordInfo.Keyword = TbKeyword.Text.Trim(); - keywordInfo.Alternative = TbAlternative.Text.Trim(); - keywordInfo.Grade = EKeywordGradeUtils.GetEnumType(DdlGrade.SelectedValue); - DataProvider.KeywordDao.Update(keywordInfo); - - isChanged = true; - } - catch (Exception ex) - { - FailMessage(ex, "修改敏感词失败!"); - } - } - else - { - if (DataProvider.KeywordDao.IsExists(TbKeyword.Text)) - { - FailMessage("敏感词添加失败,敏感词名称已存在!"); - } - else - { - try - { - var keywordInfo = new KeywordInfo - { - Keyword = TbKeyword.Text.Trim(), - Alternative = TbAlternative.Text.Trim(), - Grade = EKeywordGradeUtils.GetEnumType(DdlGrade.SelectedValue) - }; - DataProvider.KeywordDao.Insert(keywordInfo); - isChanged = true; - } - catch (Exception ex) - { - FailMessage(ex, "添加敏感词失败!"); - } - } - } - - if (isChanged) - { - LayerUtils.Close(Page); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/ModalKeywordImport.cs b/SiteServer.BackgroundPages/Settings/ModalKeywordImport.cs deleted file mode 100644 index 56207840b..000000000 --- a/SiteServer.BackgroundPages/Settings/ModalKeywordImport.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class ModalKeywordImport : BasePageCms - { - public DropDownList DdlGrade; - public TextBox TbKeywords; - - public static string GetOpenWindowString() - { - return LayerUtils.GetOpenScript("导入敏感词", - PageUtils.GetSettingsUrl(nameof(ModalKeywordImport), null), 500, 530); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - if (!IsPostBack) - { - EKeywordGradeUtils.AddListItems(DdlGrade); - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var isChanged = false; - - try - { - var grade = EKeywordGradeUtils.GetEnumType(DdlGrade.SelectedValue); - - var keywordArray = TbKeywords.Text.Split(','); - foreach (var item in keywordArray) - { - if (!string.IsNullOrEmpty(item)) - { - var value = item.Trim(); - string keyword; - var alternative = string.Empty; - - if (value.IndexOf('|') != -1) - { - keyword = value.Split('|')[0]; - alternative = value.Split('|')[1]; - } - else - { - keyword = value; - } - - if (!string.IsNullOrEmpty(keyword) && !DataProvider.KeywordDao.IsExists(keyword)) - { - var keywordInfo = new KeywordInfo(0, keyword, alternative, grade); - DataProvider.KeywordDao.Insert(keywordInfo); - } - } - } - - isChanged = true; - } - catch (Exception ex) - { - FailMessage(ex, "导入敏感词失败"); - } - - if (isChanged) - { - LayerUtils.Close(Page); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/ModalPermissionsSet.cs b/SiteServer.BackgroundPages/Settings/ModalPermissionsSet.cs deleted file mode 100644 index 3b26cb0d3..000000000 --- a/SiteServer.BackgroundPages/Settings/ModalPermissionsSet.cs +++ /dev/null @@ -1,213 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class ModalPermissionsSet : BasePageCms - { - public DropDownList DdlPredefinedRole; - public PlaceHolder PhSiteId; - public CheckBoxList CblSiteId; - public PlaceHolder PhRoles; - public ListBox LbAvailableRoles; - public ListBox LbAssignedRoles; - - private string _userName = string.Empty; - - public static string GetOpenWindowString(string userName) - { - return LayerUtils.GetOpenScript("权限设置", - PageUtils.GetSettingsUrl(nameof(ModalPermissionsSet), new NameValueCollection - { - {"UserName", userName} - })); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - _userName = AuthRequest.GetQueryString("UserName"); - - if (IsPostBack) return; - - var roles = DataProvider.AdministratorsInRolesDao.GetRolesForUser(_userName); - if (AuthRequest.AdminPermissions.IsConsoleAdministrator) - { - DdlPredefinedRole.Items.Add(EPredefinedRoleUtils.GetListItem(EPredefinedRole.ConsoleAdministrator, false)); - DdlPredefinedRole.Items.Add(EPredefinedRoleUtils.GetListItem(EPredefinedRole.SystemAdministrator, false)); - } - DdlPredefinedRole.Items.Add(EPredefinedRoleUtils.GetListItem(EPredefinedRole.Administrator, false)); - - var type = EPredefinedRoleUtils.GetEnumTypeByRoles(roles); - ControlUtils.SelectSingleItem(DdlPredefinedRole, EPredefinedRoleUtils.GetValue(type)); - - SiteManager.AddListItems(CblSiteId); - ControlUtils.SelectMultiItems(CblSiteId, DataProvider.AdministratorDao.GetSiteIdList(_userName)); - - ListBoxDataBind(); - - DdlPredefinedRole_SelectedIndexChanged(null, EventArgs.Empty); - } - - public void DdlPredefinedRole_SelectedIndexChanged(object sender, EventArgs e) - { - if (EPredefinedRoleUtils.Equals(EPredefinedRole.ConsoleAdministrator, DdlPredefinedRole.SelectedValue)) - { - PhRoles.Visible = PhSiteId.Visible = false; - } - else if (EPredefinedRoleUtils.Equals(EPredefinedRole.SystemAdministrator, DdlPredefinedRole.SelectedValue)) - { - PhRoles.Visible = false; - PhSiteId.Visible = true; - } - else - { - PhRoles.Visible = true; - PhSiteId.Visible = false; - } - } - - private void ListBoxDataBind() - { - LbAvailableRoles.Items.Clear(); - LbAssignedRoles.Items.Clear(); - var allRoles = AuthRequest.AdminPermissions.IsConsoleAdministrator ? DataProvider.RoleDao.GetAllRoles() : DataProvider.RoleDao.GetAllRolesByCreatorUserName(AuthRequest.AdminName); - var userRoles = DataProvider.AdministratorsInRolesDao.GetRolesForUser(_userName); - var userRoleNameArrayList = new ArrayList(userRoles); - foreach (var roleName in allRoles) - { - if (!EPredefinedRoleUtils.IsPredefinedRole(roleName) && !userRoleNameArrayList.Contains(roleName)) - { - LbAvailableRoles.Items.Add(new ListItem(roleName, roleName)); - } - } - foreach (var roleName in userRoles) - { - if (!EPredefinedRoleUtils.IsPredefinedRole(roleName)) - { - LbAssignedRoles.Items.Add(new ListItem(roleName, roleName)); - } - } - } - - public void AddRole_OnClick(object sender, EventArgs e) - { - if (!IsPostBack || !IsValid) return; - - try - { - if (LbAvailableRoles.SelectedIndex != -1) - { - var selectedRoles = ControlUtils.GetSelectedListControlValueArray(LbAvailableRoles); - if (selectedRoles.Length > 0) - { - DataProvider.AdministratorsInRolesDao.AddUserToRoles(_userName, selectedRoles); - } - } - ListBoxDataBind(); - } - catch (Exception ex) - { - FailMessage(ex, "用户角色分配失败"); - } - } - - public void AddRoles_OnClick(object sender, EventArgs e) - { - if (!IsPostBack || !IsValid) return; - - try - { - var roles = ControlUtils.GetListControlValues(LbAvailableRoles); - if (roles.Length > 0) - { - DataProvider.AdministratorsInRolesDao.AddUserToRoles(_userName, roles); - } - ListBoxDataBind(); - } - catch (Exception ex) - { - FailMessage(ex, "用户角色分配失败"); - } - } - - public void DeleteRole_OnClick(object sender, EventArgs e) - { - if (!IsPostBack || !IsValid) return; - - try - { - if (LbAssignedRoles.SelectedIndex != -1) - { - var selectedRoles = ControlUtils.GetSelectedListControlValueArray(LbAssignedRoles); - DataProvider.AdministratorsInRolesDao.RemoveUserFromRoles(_userName, selectedRoles); - } - ListBoxDataBind(); - } - catch (Exception ex) - { - FailMessage(ex, "用户角色分配失败"); - } - } - - public void DeleteRoles_OnClick(object sender, EventArgs e) - { - if (!IsPostBack || !IsValid) return; - - try - { - var roles = ControlUtils.GetListControlValues(LbAssignedRoles); - if (roles.Length > 0) - { - DataProvider.AdministratorsInRolesDao.RemoveUserFromRoles(_userName, roles); - } - ListBoxDataBind(); - } - catch (Exception ex) - { - FailMessage(ex, "用户角色分配失败"); - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var isChanged = false; - - try - { - var allRoles = EPredefinedRoleUtils.GetAllPredefinedRoleName(); - foreach (var roleName in allRoles) - { - DataProvider.AdministratorsInRolesDao.RemoveUserFromRole(_userName, roleName); - } - DataProvider.AdministratorsInRolesDao.AddUserToRole(_userName, DdlPredefinedRole.SelectedValue); - - DataProvider.AdministratorDao.UpdateSiteIdCollection(_userName, - EPredefinedRoleUtils.Equals(EPredefinedRole.SystemAdministrator, DdlPredefinedRole.SelectedValue) - ? ControlUtils.SelectedItemsValueToStringCollection(CblSiteId.Items) - : string.Empty); - - AuthRequest.AddAdminLog("设置管理员权限", $"管理员:{_userName}"); - - SuccessMessage("权限设置成功!"); - isChanged = true; - } - catch (Exception ex) - { - FailMessage(ex, "权限设置失败!"); - } - - if (isChanged) - { - var redirectUrl = PageAdministrator.GetRedirectUrl(); - LayerUtils.CloseAndRedirect(Page, redirectUrl); - } - } - } -} \ No newline at end of file diff --git a/SiteServer.BackgroundPages/Settings/ModalTableMetadataAdd.cs b/SiteServer.BackgroundPages/Settings/ModalTableMetadataAdd.cs deleted file mode 100644 index 0c015c542..000000000 --- a/SiteServer.BackgroundPages/Settings/ModalTableMetadataAdd.cs +++ /dev/null @@ -1,163 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils; -using SiteServer.Plugin; - -namespace SiteServer.BackgroundPages.Settings -{ - public class ModalTableMetadataAdd : BasePageCms - { - public TextBox TbAttributeName; - public DropDownList DdlDataType; - public PlaceHolder PhDataLength; - public TextBox TbDataLength; - - private string _tableName; - - public static string GetOpenWindowStringToAdd(string tableName) - { - return LayerUtils.GetOpenScript("添加辅助表字段", PageUtils.GetSettingsUrl(nameof(ModalTableMetadataAdd), new NameValueCollection - { - {"TableName", tableName} - }), 600, 320); - } - - public static string GetOpenWindowStringToEdit(string tableName, int tableMetadataId) - { - return LayerUtils.GetOpenScript("修改辅助表字段", PageUtils.GetSettingsUrl(nameof(ModalTableMetadataAdd), new NameValueCollection - { - {"TableName", tableName}, - {"TableMetadataID", tableMetadataId.ToString()} - }), 600, 320); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("TableName"); - - _tableName = AuthRequest.GetQueryString("TableName"); - - if (IsPostBack) return; - - DataTypeUtils.AddListItems(DdlDataType); - - if (AuthRequest.IsQueryExists("TableMetadataID")) - { - var tableMetadataId = AuthRequest.GetQueryInt("TableMetadataID"); - var info = DataProvider.TableMetadataDao.GetTableMetadataInfo(tableMetadataId); - if (info != null) - { - TbAttributeName.Text = info.AttributeName; - TbAttributeName.Enabled = false; - ControlUtils.SelectSingleItemIgnoreCase(DdlDataType, info.DataType.ToString()); - TbDataLength.Text = info.DataLength.ToString(); - } - } - } - - public void DdlDataType_SelectedIndexChanged(object sender, EventArgs e) - { - PhDataLength.Visible = DataTypeUtils.GetEnumType(DdlDataType.SelectedValue) == DataType.VarChar; - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - var isChanged = false; - - if (AuthRequest.IsQueryExists("TableMetadataID")) - { - var tableMetadataId = AuthRequest.GetQueryInt("TableMetadataID"); - - var info = DataProvider.TableMetadataDao.GetTableMetadataInfo(tableMetadataId); - info.TableName = _tableName; - info.AttributeName = TbAttributeName.Text; - info.DataType = DataTypeUtils.GetEnumType(DdlDataType.SelectedValue); - - if (info.DataType == DataType.VarChar) - { - info.DataLength = TranslateUtils.ToInt(TbDataLength.Text); - var maxLength = SqlUtils.GetMaxLengthForNVarChar(); - if (info.DataLength <= 0 || info.DataLength > maxLength) - { - FailMessage($"字段修改失败,数据长度的值必须位于 1 和 {maxLength} 之间"); - return; - } - } - - try - { - DataProvider.TableMetadataDao.Update(info); - - AuthRequest.AddAdminLog("修改辅助表字段", - $"辅助表:{_tableName},字段名:{info.AttributeName}"); - - isChanged = true; - } - catch (Exception ex) - { - FailMessage(ex, ex.Message); - } - } - else - { - var attributeNameList = TableMetadataManager.GetAttributeNameList(_tableName, true); - - var attributeNameLowercase = TbAttributeName.Text.Trim().ToLower(); - if (attributeNameList.Contains(attributeNameLowercase) || ContentAttribute.AllAttributesLowercase.Contains(attributeNameLowercase)) - { - FailMessage("字段添加失败,字段名已存在!"); - } - else if (!SqlUtils.IsAttributeNameCompliant(TbAttributeName.Text)) - { - FailMessage("字段名不符合系统要求!"); - } - else - { - var info = new TableMetadataInfo - { - TableName = _tableName, - AttributeName = TbAttributeName.Text, - DataType = DataTypeUtils.GetEnumType(DdlDataType.SelectedValue) - }; - - if (info.DataType == DataType.VarChar) - { - info.DataLength = TranslateUtils.ToInt(TbDataLength.Text); - var maxLength = SqlUtils.GetMaxLengthForNVarChar(); - if (info.DataLength <= 0 || info.DataLength > maxLength) - { - FailMessage($"字段修改失败,数据长度的值必须位于 1 和 {maxLength} 之间"); - return; - } - } - info.IsSystem = false; - - try - { - DataProvider.TableMetadataDao.Insert(info); - - AuthRequest.AddAdminLog("添加辅助表字段", - $"辅助表:{_tableName},字段名:{info.AttributeName}"); - - isChanged = true; - } - catch (Exception ex) - { - FailMessage(ex, ex.Message); - } - } - } - - if (isChanged) - { - LayerUtils.Close(Page); - } - } - - } -} diff --git a/SiteServer.BackgroundPages/Settings/ModalUserView.cs b/SiteServer.BackgroundPages/Settings/ModalUserView.cs deleted file mode 100644 index 225f3584e..000000000 --- a/SiteServer.BackgroundPages/Settings/ModalUserView.cs +++ /dev/null @@ -1,76 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils; - -namespace SiteServer.BackgroundPages.Settings -{ - public class ModalUserView : BasePage - { - protected Literal LtlUserName; - protected Literal LtlDisplayName; - protected Literal LtlCreateDate; - protected Literal LtlLastResetPasswordDate; - protected Literal LtlLastActivityDate; - protected Literal LtlEmail; - protected Literal LtlMobile; - protected Literal LtlLoginCount; - protected Literal LtlWritingCount; - protected Literal LtlOrganization; - protected Literal LtlDepartment; - protected Literal LtlPosition; - protected Literal LtlGender; - protected Literal LtlBirthday; - protected Literal LtlEducation; - protected Literal LtlGraduation; - protected Literal LtlAddress; - protected Literal LtlWeiXin; - protected Literal LtlQq; - protected Literal LtlWeiBo; - protected Literal LtlInterests; - protected Literal LtlSignature; - - private UserInfo _userInfo; - - public static string GetOpenWindowString(string userName) - { - return LayerUtils.GetOpenScript("查看用户信息", PageUtils.GetSettingsUrl(nameof(ModalUserView), new NameValueCollection - { - {"UserName", userName} - }), 700, 560); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - var userName = Request.QueryString["UserName"]; - _userInfo = DataProvider.UserDao.GetUserInfoByAccount(userName); - - LtlUserName.Text = _userInfo.UserName; - LtlDisplayName.Text = _userInfo.DisplayName; - LtlCreateDate.Text = DateUtils.GetDateAndTimeString(_userInfo.CreateDate); - LtlLastActivityDate.Text = DateUtils.GetDateAndTimeString(_userInfo.LastActivityDate); - LtlLastResetPasswordDate.Text = DateUtils.GetDateAndTimeString(_userInfo.LastResetPasswordDate); - LtlEmail.Text = _userInfo.Email; - LtlMobile.Text = _userInfo.Mobile; - LtlLoginCount.Text = _userInfo.CountOfLogin.ToString(); - LtlWritingCount.Text = _userInfo.CountOfWriting.ToString(); - LtlOrganization.Text = _userInfo.Organization; - LtlDepartment.Text = _userInfo.Department; - LtlPosition.Text = _userInfo.Position; - LtlGender.Text = _userInfo.Gender; - LtlBirthday.Text = _userInfo.Birthday; - LtlEducation.Text = _userInfo.Education; - LtlGraduation.Text = _userInfo.Graduation; - LtlAddress.Text = _userInfo.Address; - LtlWeiXin.Text = _userInfo.WeiXin; - LtlQq.Text = _userInfo.Qq; - LtlWeiBo.Text = _userInfo.WeiBo; - LtlInterests.Text = _userInfo.Interests; - LtlSignature.Text = _userInfo.Signature; - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageAdminConfiguration.cs b/SiteServer.BackgroundPages/Settings/PageAdminConfiguration.cs deleted file mode 100644 index 89a05168f..000000000 --- a/SiteServer.BackgroundPages/Settings/PageAdminConfiguration.cs +++ /dev/null @@ -1,111 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageAdminConfiguration : BasePage - { - public TextBox TbLoginUserNameMinLength; - public TextBox TbLoginPasswordMinLength; - public DropDownList DdlLoginPasswordRestriction; - - public RadioButtonList RblIsLoginFailToLock; - public PlaceHolder PhFailToLock; - public TextBox TbLoginFailToLockCount; - public DropDownList DdlLoginLockingType; - public PlaceHolder PhLoginLockingHours; - public TextBox TbLoginLockingHours; - - public RadioButtonList RblIsFindPassword; - public PlaceHolder PhFindPassword; - public TextBox TbFindPasswordSmsTplId; - - public RadioButtonList RblIsViewContentOnlySelf; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Admin); - - TbLoginUserNameMinLength.Text = ConfigManager.SystemConfigInfo.AdminUserNameMinLength.ToString(); - TbLoginPasswordMinLength.Text = ConfigManager.SystemConfigInfo.AdminPasswordMinLength.ToString(); - EUserPasswordRestrictionUtils.AddListItems(DdlLoginPasswordRestriction); - ControlUtils.SelectSingleItemIgnoreCase(DdlLoginPasswordRestriction, ConfigManager.SystemConfigInfo.AdminPasswordRestriction); - - EBooleanUtils.AddListItems(RblIsLoginFailToLock, "是", "否"); - ControlUtils.SelectSingleItemIgnoreCase(RblIsLoginFailToLock, ConfigManager.SystemConfigInfo.IsAdminLockLogin.ToString()); - - PhFailToLock.Visible = ConfigManager.SystemConfigInfo.IsAdminLockLogin; - - TbLoginFailToLockCount.Text = ConfigManager.SystemConfigInfo.AdminLockLoginCount.ToString(); - - DdlLoginLockingType.Items.Add(new ListItem("按小时锁定", EUserLockTypeUtils.GetValue(EUserLockType.Hours))); - DdlLoginLockingType.Items.Add(new ListItem("永久锁定", EUserLockTypeUtils.GetValue(EUserLockType.Forever))); - ControlUtils.SelectSingleItemIgnoreCase(DdlLoginLockingType, ConfigManager.SystemConfigInfo.AdminLockLoginType); - - PhLoginLockingHours.Visible = false; - if (!EUserLockTypeUtils.Equals(ConfigManager.SystemConfigInfo.AdminLockLoginType, EUserLockType.Forever)) - { - PhLoginLockingHours.Visible = true; - TbLoginLockingHours.Text = ConfigManager.SystemConfigInfo.AdminLockLoginHours.ToString(); - } - - EBooleanUtils.AddListItems(RblIsFindPassword, "启用", "禁用"); - ControlUtils.SelectSingleItemIgnoreCase(RblIsFindPassword, ConfigManager.SystemConfigInfo.IsAdminFindPassword.ToString()); - PhFindPassword.Visible = ConfigManager.SystemConfigInfo.IsAdminFindPassword; - TbFindPasswordSmsTplId.Text = ConfigManager.SystemConfigInfo.AdminFindPasswordSmsTplId; - - EBooleanUtils.AddListItems(RblIsViewContentOnlySelf, "不可以", "可以"); - ControlUtils.SelectSingleItemIgnoreCase(RblIsViewContentOnlySelf, ConfigManager.SystemConfigInfo.IsViewContentOnlySelf.ToString()); - } - - public void RblIsLoginFailToLock_SelectedIndexChanged(object sender, EventArgs e) - { - PhFailToLock.Visible = TranslateUtils.ToBool(RblIsLoginFailToLock.SelectedValue); - } - - public void DdlLoginLockingType_SelectedIndexChanged(object sender, EventArgs e) - { - PhLoginLockingHours.Visible = !EUserLockTypeUtils.Equals(EUserLockType.Forever, DdlLoginLockingType.SelectedValue); - } - - public void RblIsFindPassword_SelectedIndexChanged(object sender, EventArgs e) - { - PhFindPassword.Visible = TranslateUtils.ToBool(RblIsFindPassword.SelectedValue); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - try - { - ConfigManager.SystemConfigInfo.AdminUserNameMinLength = TranslateUtils.ToInt(TbLoginUserNameMinLength.Text); - ConfigManager.SystemConfigInfo.AdminPasswordMinLength = TranslateUtils.ToInt(TbLoginPasswordMinLength.Text); - ConfigManager.SystemConfigInfo.AdminPasswordRestriction = DdlLoginPasswordRestriction.SelectedValue; - - ConfigManager.SystemConfigInfo.IsAdminLockLogin = TranslateUtils.ToBool(RblIsLoginFailToLock.SelectedValue); - ConfigManager.SystemConfigInfo.AdminLockLoginCount = TranslateUtils.ToInt(TbLoginFailToLockCount.Text, 3); - ConfigManager.SystemConfigInfo.AdminLockLoginType = DdlLoginLockingType.SelectedValue; - ConfigManager.SystemConfigInfo.AdminLockLoginHours = TranslateUtils.ToInt(TbLoginLockingHours.Text); - - ConfigManager.SystemConfigInfo.IsAdminFindPassword = TranslateUtils.ToBool(RblIsFindPassword.SelectedValue); - ConfigManager.SystemConfigInfo.AdminFindPasswordSmsTplId = TbFindPasswordSmsTplId.Text; - - ConfigManager.SystemConfigInfo.IsViewContentOnlySelf = TranslateUtils.ToBool(RblIsViewContentOnlySelf.SelectedValue); - - DataProvider.ConfigDao.Update(ConfigManager.Instance); - - AuthRequest.AddAdminLog("管理员设置"); - SuccessMessage("管理员设置成功"); - } - catch (Exception ex) - { - FailMessage(ex, ex.Message); - } - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageAdminPermissionAdd.cs b/SiteServer.BackgroundPages/Settings/PageAdminPermissionAdd.cs deleted file mode 100644 index 76ee71f11..000000000 Binary files a/SiteServer.BackgroundPages/Settings/PageAdminPermissionAdd.cs and /dev/null differ diff --git a/SiteServer.BackgroundPages/Settings/PageAdminRole.cs b/SiteServer.BackgroundPages/Settings/PageAdminRole.cs deleted file mode 100644 index 08634c913..000000000 --- a/SiteServer.BackgroundPages/Settings/PageAdminRole.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageAdminRole : BasePage - { - public Repeater RptContents; - public Button BtnAdd; - - public static string GetRedirectUrl() - { - return PageUtils.GetSettingsUrl(nameof(PageAdminRole), null); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (AuthRequest.IsQueryExists("Delete")) - { - var roleName = AuthRequest.GetQueryString("RoleName"); - try - { - DataProvider.PermissionsInRolesDao.Delete(roleName); - DataProvider.RoleDao.DeleteRole(roleName); - - AuthRequest.AddAdminLog("删除管理员角色", $"角色名称:{roleName}"); - - SuccessDeleteMessage(); - } - catch(Exception ex) - { - FailDeleteMessage(ex); - } - } - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Admin); - - RptContents.DataSource = AuthRequest.AdminPermissions.IsConsoleAdministrator - ? DataProvider.RoleDao.GetAllRoles() - : DataProvider.RoleDao.GetAllRolesByCreatorUserName(AuthRequest.AdminName); - RptContents.ItemDataBound += RptContents_ItemDataBound; - RptContents.DataBind(); - - BtnAdd.Attributes.Add("onclick", $"location.href = '{PageAdminRoleAdd.GetRedirectUrl()}';return false;"); - } - - private static void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var roleName = (string)e.Item.DataItem; - e.Item.Visible = !EPredefinedRoleUtils.IsPredefinedRole(roleName); - - var ltlRoleName = (Literal) e.Item.FindControl("ltlRoleName"); - var ltlDescription = (Literal)e.Item.FindControl("ltlDescription"); - var ltlEdit = (Literal)e.Item.FindControl("ltlEdit"); - var ltlDelete = (Literal)e.Item.FindControl("ltlDelete"); - - ltlRoleName.Text = roleName; - ltlDescription.Text = DataProvider.RoleDao.GetRoleDescription(roleName); - ltlEdit.Text = $@"修改"; - ltlDelete.Text = $@"删除"; - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageAdministrator.cs b/SiteServer.BackgroundPages/Settings/PageAdministrator.cs deleted file mode 100644 index 08eed7618..000000000 --- a/SiteServer.BackgroundPages/Settings/PageAdministrator.cs +++ /dev/null @@ -1,329 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageAdministrator : BasePage - { - public DropDownList DdlRoleName; - public DropDownList DdlPageNum; - public DropDownList DdlOrder; - public DropDownList DdlLastActivityDate; - public DropDownList DdlDepartmentId; - public DropDownList DdlAreaId; - public TextBox TbKeyword; - - public Repeater RptContents; - public SqlPager SpContents; - - public Button BtnAdd; - public Button BtnLock; - public Button BtnUnLock; - public Button BtnDelete; - - private bool[] _isLastNodeArrayOfDepartment; - private bool[] _isLastNodeArrayOfArea; - private EUserLockType _lockType = EUserLockType.Forever; - - public static string GetRedirectUrl() - { - return PageUtils.GetSettingsUrl(nameof(PageAdministrator), null); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - var departmentId = AuthRequest.GetQueryInt("departmentId"); - var areaId = AuthRequest.GetQueryInt("areaId"); - - if (AuthRequest.IsQueryExists("Delete")) - { - var userNameCollection = AuthRequest.GetQueryString("UserNameCollection"); - try - { - var userNameArrayList = TranslateUtils.StringCollectionToStringList(userNameCollection); - foreach (var userName in userNameArrayList) - { - DataProvider.AdministratorDao.Delete(userName); - } - - AuthRequest.AddAdminLog("删除管理员", $"管理员:{userNameCollection}"); - - SuccessDeleteMessage(); - } - catch (Exception ex) - { - FailDeleteMessage(ex); - } - } - else if (AuthRequest.IsQueryExists("Lock")) - { - var userNameCollection = AuthRequest.GetQueryString("UserNameCollection"); - try - { - var userNameList = TranslateUtils.StringCollectionToStringList(userNameCollection); - DataProvider.AdministratorDao.Lock(userNameList); - - AuthRequest.AddAdminLog("锁定管理员", $"管理员:{userNameCollection}"); - - SuccessMessage("成功锁定所选管理员!"); - } - catch (Exception ex) - { - FailMessage(ex, "锁定所选管理员失败!"); - } - } - else if (AuthRequest.IsQueryExists("UnLock")) - { - var userNameCollection = AuthRequest.GetQueryString("UserNameCollection"); - try - { - var userNameList = TranslateUtils.StringCollectionToStringList(userNameCollection); - DataProvider.AdministratorDao.UnLock(userNameList); - - AuthRequest.AddAdminLog("解除锁定管理员", $"管理员:{userNameCollection}"); - - SuccessMessage("成功解除锁定所选管理员!"); - } - catch (Exception ex) - { - FailMessage(ex, "解除锁定所选管理员失败!"); - } - } - - SpContents.ControlToPaginate = RptContents; - SpContents.ItemsPerPage = StringUtils.Constants.PageSize; - - if (string.IsNullOrEmpty(AuthRequest.GetQueryString("pageNum"))) - { - SpContents.ItemsPerPage = TranslateUtils.ToInt(DdlPageNum.SelectedValue) == 0 ? StringUtils.Constants.PageSize : TranslateUtils.ToInt(DdlPageNum.SelectedValue); - - SpContents.SelectCommand = DataProvider.AdministratorDao.GetSelectCommand(AuthRequest.AdminPermissions.IsConsoleAdministrator, AuthRequest.AdminName); - SpContents.SortField = DataProvider.AdministratorDao.GetSortFieldName(); - SpContents.SortMode = SortMode.ASC; - } - else - { - SpContents.ItemsPerPage = AuthRequest.GetQueryInt("pageNum") == 0 ? StringUtils.Constants.PageSize : AuthRequest.GetQueryInt("pageNum"); - SpContents.SelectCommand = DataProvider.AdministratorDao.GetSelectCommand(AuthRequest.GetQueryString("keyword"), AuthRequest.GetQueryString("roleName"), AuthRequest.GetQueryInt("lastActivityDate"), AuthRequest.AdminPermissions.IsConsoleAdministrator, AuthRequest.AdminName, AuthRequest.GetQueryInt("departmentId"), AuthRequest.GetQueryInt("areaId")); - SpContents.SortField = AuthRequest.GetQueryString("order"); - SpContents.SortMode = StringUtils.EqualsIgnoreCase(SpContents.SortField, nameof(AdministratorInfo.UserName)) ? SortMode.ASC : SortMode.DESC; - } - - RptContents.ItemDataBound += RptContents_ItemDataBound; - - _lockType = EUserLockTypeUtils.GetEnumType(ConfigManager.SystemConfigInfo.AdminLockLoginType); - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Admin); - - var theListItem = new ListItem("全部", string.Empty) - { - Selected = true - }; - DdlRoleName.Items.Add(theListItem); - - var allRoles = AuthRequest.AdminPermissions.IsConsoleAdministrator ? DataProvider.RoleDao.GetAllRoles() : DataProvider.RoleDao.GetAllRolesByCreatorUserName(AuthRequest.AdminName); - - var allPredefinedRoles = EPredefinedRoleUtils.GetAllPredefinedRoleName(); - foreach (var roleName in allRoles) - { - if (allPredefinedRoles.Contains(roleName)) - { - var listitem = new ListItem(EPredefinedRoleUtils.GetText(EPredefinedRoleUtils.GetEnumType(roleName)), roleName); - DdlRoleName.Items.Add(listitem); - } - } - foreach (var roleName in allRoles) - { - if (!allPredefinedRoles.Contains(roleName)) - { - var listitem = new ListItem(roleName, roleName); - DdlRoleName.Items.Add(listitem); - } - } - - DdlDepartmentId.Items.Add(new ListItem("<所有部门>", "0")); - var departmentIdList = DepartmentManager.GetDepartmentIdList(); - var count = departmentIdList.Count; - _isLastNodeArrayOfDepartment = new bool[count]; - foreach (var theDepartmentId in departmentIdList) - { - var departmentInfo = DepartmentManager.GetDepartmentInfo(theDepartmentId); - DdlDepartmentId.Items.Add(new ListItem(GetTreeItem(departmentInfo.Id, departmentInfo.DepartmentName, departmentInfo.ParentsCount, departmentInfo.IsLastNode, _isLastNodeArrayOfDepartment), theDepartmentId.ToString())); - } - ControlUtils.SelectSingleItem(DdlDepartmentId, departmentId.ToString()); - - DdlAreaId.Items.Add(new ListItem("<全部区域>", "0")); - var areaIdList = AreaManager.GetAreaIdList(); - count = areaIdList.Count; - _isLastNodeArrayOfArea = new bool[count]; - foreach (var theAreaId in areaIdList) - { - var areaInfo = AreaManager.GetAreaInfo(theAreaId); - DdlAreaId.Items.Add(new ListItem(GetTreeItem(areaInfo.Id, areaInfo.AreaName, areaInfo.ParentsCount, areaInfo.IsLastNode, _isLastNodeArrayOfArea), theAreaId.ToString())); - } - ControlUtils.SelectSingleItem(DdlAreaId, areaId.ToString()); - - if (AuthRequest.IsQueryExists("pageNum")) - { - ControlUtils.SelectSingleItem(DdlRoleName, AuthRequest.GetQueryString("roleName")); - ControlUtils.SelectSingleItem(DdlPageNum, AuthRequest.GetQueryString("pageNum")); - TbKeyword.Text = AuthRequest.GetQueryString("keyword"); - ControlUtils.SelectSingleItem(DdlDepartmentId, AuthRequest.GetQueryString("departmentId")); - ControlUtils.SelectSingleItem(DdlAreaId, AuthRequest.GetQueryString("areaId")); - ControlUtils.SelectSingleItem(DdlLastActivityDate, AuthRequest.GetQueryString("lastActivityDate")); - ControlUtils.SelectSingleItem(DdlOrder, AuthRequest.GetQueryString("order")); - } - - BtnAdd.Attributes.Add("onclick", $@"location.href='{PageAdministratorAdd.GetRedirectUrlToAdd(departmentId)}';return false;"); - - var urlAdministrator = GetRedirectUrl(); - - BtnLock.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert(urlAdministrator + "?Lock=True", "UserNameCollection", "UserNameCollection", "请选择需要锁定的管理员!", "此操作将锁定所选管理员,确认吗?")); - - BtnUnLock.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert(urlAdministrator + "?UnLock=True", "UserNameCollection", "UserNameCollection", "请选择需要解除锁定的管理员!", "此操作将解除锁定所选管理员,确认吗?")); - - BtnDelete.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert(urlAdministrator + "?Delete=True", "UserNameCollection", "UserNameCollection", "请选择需要删除的管理员!", "此操作将删除所选管理员,确认吗?")); - - SpContents.DataBind(); - } - - public string GetTreeItem(int areaId, string areaName, int parentsCount, bool isLastNode, bool[] array) - { - var str = ""; - if (isLastNode == false) - { - array[parentsCount] = false; - } - else - { - array[parentsCount] = true; - } - for (var i = 0; i < parentsCount; i++) - { - str = string.Concat(str, array[i] ? " " : "│"); - } - str = string.Concat(str, isLastNode ? "└" : "├"); - str = string.Concat(str, areaName); - return str; - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var userName = SqlUtils.EvalString(e.Item.DataItem, nameof(AdministratorInfo.UserName)); - var displayName = SqlUtils.EvalString(e.Item.DataItem, nameof(AdministratorInfo.DisplayName)); - var mobile = SqlUtils.EvalString(e.Item.DataItem, nameof(AdministratorInfo.Mobile)); - var departmentId = SqlUtils.EvalInt(e.Item.DataItem, nameof(AdministratorInfo.DepartmentId)); - var areaId = SqlUtils.EvalInt(e.Item.DataItem, nameof(AdministratorInfo.AreaId)); - if (string.IsNullOrEmpty(displayName)) - { - displayName = userName; - } - var countOfFailedLogin = SqlUtils.EvalInt(e.Item.DataItem, nameof(AdministratorInfo.CountOfFailedLogin)); - var countOfLogin = SqlUtils.EvalInt(e.Item.DataItem, nameof(AdministratorInfo.CountOfLogin)); - var isLockedOut = SqlUtils.EvalBool(e.Item.DataItem, nameof(AdministratorInfo.IsLockedOut)); - var lastActivityDate = SqlUtils.EvalDateTime(e.Item.DataItem, nameof(AdministratorInfo.LastActivityDate)); - - var ltlUserName = (Literal)e.Item.FindControl("ltlUserName"); - var ltlDisplayName = (Literal)e.Item.FindControl("ltlDisplayName"); - var ltlMobile = (Literal)e.Item.FindControl("ltlMobile"); - var ltlDepartment = (Literal)e.Item.FindControl("ltlDepartment"); - var ltlArea = (Literal)e.Item.FindControl("ltlArea"); - var ltlLastActivityDate = (Literal)e.Item.FindControl("ltlLastActivityDate"); - var ltlCountOfLogin = (Literal)e.Item.FindControl("ltlCountOfLogin"); - var ltlRoles = (Literal)e.Item.FindControl("ltlRoles"); - var ltlEdit = (Literal)e.Item.FindControl("ltlEdit"); - var hlChangePassword = (HyperLink)e.Item.FindControl("hlChangePassword"); - var ltlRole = (Literal)e.Item.FindControl("ltlRole"); - var ltlSelect = (Literal)e.Item.FindControl("ltlSelect"); - - ltlUserName.Text = GetUserNameHtml(userName, countOfFailedLogin, isLockedOut, lastActivityDate); - ltlDisplayName.Text = displayName; - ltlMobile.Text = mobile; - ltlDepartment.Text = DepartmentManager.GetDepartmentName(departmentId); - ltlArea.Text = AreaManager.GetAreaName(areaId); - - ltlLastActivityDate.Text = GetDateTime(lastActivityDate); - ltlCountOfLogin.Text = countOfLogin.ToString(); - ltlRoles.Text = AdminManager.GetRolesHtml(userName); - - var urlEdit = PageAdministratorAdd.GetRedirectUrlToEdit(departmentId, userName); - ltlEdit.Text = $@"修改属性"; - hlChangePassword.Attributes.Add("onclick", ModalAdminPassword.GetOpenWindowString(userName)); - - if (AuthRequest.AdminName != userName) - { - var openWindowString = ModalPermissionsSet.GetOpenWindowString(userName); - ltlRole.Text = $@"权限设置"; - ltlSelect.Text = $@""; - } - } - - private static string GetDateTime(DateTime datetime) - { - var retval = string.Empty; - if (datetime > DateUtils.SqlMinValue) - { - retval = DateUtils.GetDateString(datetime); - } - return retval; - } - - private string GetUserNameHtml(string userName, int countOfFailedLogin, bool isLockedOut, DateTime lastActivityDate) - { - var showPopWinString = ModalAdminView.GetOpenWindowString(userName); - var state = string.Empty; - if (isLockedOut) - { - state = @"[已被锁定]"; - } - else if (ConfigManager.SystemConfigInfo.IsAdminLockLogin && - ConfigManager.SystemConfigInfo.AdminLockLoginCount <= countOfFailedLogin) - { - if (_lockType == EUserLockType.Forever) - { - state = @"[已被锁定]"; - } - else - { - var ts = new TimeSpan(DateTime.Now.Ticks - lastActivityDate.Ticks); - var hours = Convert.ToInt32(ConfigManager.SystemConfigInfo.AdminLockLoginHours - ts.TotalHours); - if (hours > 0) - { - state = $@"[错误登录次数过多,已被锁定{hours}小时]"; - } - } - } - return $@"{userName} {state}"; - } - - public void Search_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(PageUrl); - } - - private string _pageUrl; - private string PageUrl - { - get - { - if (string.IsNullOrEmpty(_pageUrl)) - { - _pageUrl = $"{GetRedirectUrl()}?roleName={DdlRoleName.SelectedValue}&pageNum={DdlPageNum.SelectedValue}&keyword={TbKeyword.Text}&departmentId={DdlDepartmentId.SelectedValue}&areaId={DdlAreaId.SelectedValue}&lastActivityDate={DdlLastActivityDate.SelectedValue}&order={DdlOrder.SelectedValue}"; - } - return _pageUrl; - } - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageAnalysisSiteDownloads.cs b/SiteServer.BackgroundPages/Settings/PageAnalysisSiteDownloads.cs deleted file mode 100644 index 80677d587..000000000 --- a/SiteServer.BackgroundPages/Settings/PageAnalysisSiteDownloads.cs +++ /dev/null @@ -1,170 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageAnalysisSiteDownloads : BasePageCms - { - public DropDownList DdlSiteId; - public Repeater RptContents; - public Literal LtlTotalNum; - - public string StrArray { get; set; } - - private readonly Hashtable _horizentalHashtable = new Hashtable(); - private readonly Hashtable _verticalHashtable = new Hashtable(); - private readonly List _siteIdList = new List(); - private readonly Hashtable _xHashtable = new Hashtable(); - private readonly Hashtable _yHashtableDownload = new Hashtable(); - private const string YTypeDownload = "YType_Download"; - - public static string GetRedirectUrl() - { - return PageUtils.GetSettingsUrl(nameof(PageAnalysisSiteDownloads), null); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Chart); - - DdlSiteId.Items.Add(new ListItem("<<全部站点>>", "0")); - var siteIdList = SiteManager.GetSiteIdListOrderByLevel(); - foreach (var siteId in siteIdList) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - DdlSiteId.Items.Add(new ListItem(siteInfo.SiteName, siteId.ToString())); - - var key = siteInfo.Id; - //x轴信息 - SetXHashtable(key, siteInfo.SiteName); - //y轴信息 - SetYHashtable(key, CountManager.GetCount(siteInfo.TableName, siteInfo.Id, ECountType.Download)); - } - - RptContents.DataSource = siteIdList; - RptContents.ItemDataBound += RptContents_ItemDataBound; - RptContents.DataBind(); - - foreach (var key in _siteIdList) - { - var yValueDownload = GetYHashtable(key); - if (yValueDownload != "0") - { - StrArray += $@" -xArrayDownload.push('{GetXHashtable(key)}'); - yArrayDownload.push('{yValueDownload}');"; - } - } - LtlTotalNum.Text = GetVerticalTotalNum(); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var siteId = (int) e.Item.DataItem; - - var siteInfo = SiteManager.GetSiteInfo(siteId); - var ltlSiteName = (Literal)e.Item.FindControl("ltlSiteName"); - var ltlDownloadNum = (Literal)e.Item.FindControl("ltlDownloadNum"); - - ltlSiteName.Text = $@"{siteInfo.SiteName}"; - ltlDownloadNum.Text = GetYHashtable(siteId); - } - - public void Analysis_OnClick(object sender, EventArgs e) - { - var siteId = TranslateUtils.ToInt(DdlSiteId.SelectedValue); - PageUtils.Redirect(siteId > 0 - ? PageAnalysisSiteDownloadsChannels.GetRedirectUrl(siteId) - : GetRedirectUrl()); - } - - private void SetXHashtable(int siteId, string siteName) - { - if (!_xHashtable.ContainsKey(siteId)) - { - _xHashtable.Add(siteId, siteName); - } - if (!_siteIdList.Contains(siteId)) - { - _siteIdList.Add(siteId); - } - _siteIdList.Sort(); - _siteIdList.Reverse(); - } - - private string GetXHashtable(int siteId) - { - return _xHashtable.ContainsKey(siteId) ? _xHashtable[siteId].ToString() : string.Empty; - } - - private void SetYHashtable(int publishemtSystemId, int value) - { - - if (!_yHashtableDownload.ContainsKey(publishemtSystemId)) - { - _yHashtableDownload.Add(publishemtSystemId, value); - } - else - { - var num = TranslateUtils.ToInt(_yHashtableDownload[publishemtSystemId].ToString()); - _yHashtableDownload[publishemtSystemId] = num + value; - } - SetVertical(YTypeDownload, value); - - SetHorizental(publishemtSystemId, value); - } - - private string GetYHashtable(int publishemtSystemId) - { - if (!_yHashtableDownload.ContainsKey(publishemtSystemId)) return "0"; - var num = TranslateUtils.ToInt(_yHashtableDownload[publishemtSystemId].ToString()); - return num.ToString(); - } - - private void SetHorizental(int siteId, int num) - { - if (_horizentalHashtable[siteId] == null) - { - _horizentalHashtable[siteId] = num; - } - else - { - var totalNum = (int)_horizentalHashtable[siteId]; - _horizentalHashtable[siteId] = totalNum + num; - } - } - - private void SetVertical(string type, int num) - { - if (_verticalHashtable[type] == null) - { - _verticalHashtable[type] = num; - } - else - { - var totalNum = (int)_verticalHashtable[type]; - _verticalHashtable[type] = totalNum + num; - } - } - - private string GetVerticalTotalNum() - { - var totalNum = 0; - foreach (int num in _verticalHashtable.Values) - { - totalNum += num; - } - return totalNum == 0 ? "0" : $"{totalNum}"; - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageAnalysisSiteDownloadsChannels.cs b/SiteServer.BackgroundPages/Settings/PageAnalysisSiteDownloadsChannels.cs deleted file mode 100644 index 0a84cc3db..000000000 --- a/SiteServer.BackgroundPages/Settings/PageAnalysisSiteDownloadsChannels.cs +++ /dev/null @@ -1,210 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Provider; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageAnalysisSiteDownloadsChannels : BasePageCms - { - public DropDownList DdlSiteId; - public Repeater RptContents; - public SqlPager SpContents; - - public string StrArray { get; set; } - - private readonly Hashtable _nodeNameNavigations = new Hashtable(); - private readonly Hashtable _horizentalHashtable = new Hashtable(); - private readonly Hashtable _verticalHashtable = new Hashtable(); - private readonly List _contentIdList = new List(); - private readonly Hashtable _xHashtable = new Hashtable(); - private readonly Hashtable _yHashtableDownload = new Hashtable(); - private const string YTypeDownload = "YType_Download"; - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetSettingsUrl(nameof(PageAnalysisSiteDownloadsChannels), new NameValueCollection - { - {"siteID", siteId.ToString()} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - SpContents.ControlToPaginate = RptContents; - RptContents.ItemDataBound += RptContents_ItemDataBound; - SpContents.ItemsPerPage = SiteInfo.Additional.PageSize; - - SpContents.SelectCommand = DataProvider.ContentDao.GetSqlStringByDownloads(SiteInfo.TableName, SiteId); - - SpContents.SortField = ContentDao.SortFieldName; - SpContents.SortMode = SortMode.DESC; - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Chart); - - DdlSiteId.Items.Add(new ListItem("<<全部站点>>", "0")); - var siteIdList = SiteManager.GetSiteIdListOrderByLevel(); - foreach (var siteId in siteIdList) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - DdlSiteId.Items.Add(new ListItem(siteInfo.SiteName, siteId.ToString())); - } - ControlUtils.SelectSingleItem(DdlSiteId, SiteId.ToString()); - - SpContents.DataBind(); - - foreach (var contentId in _contentIdList) - { - var yValueDownload = GetYHashtable(contentId); - var xValue = GetXHashtable(contentId); - if (xValue.Length > 10) xValue = xValue.Substring(0, 10); - - StrArray += $@" -xArrayDownload.push('{xValue}'); - yArrayDownload.push('{yValueDownload}');"; - } - } - - public void Analysis_OnClick(object sender, EventArgs e) - { - var siteId = TranslateUtils.ToInt(DdlSiteId.SelectedValue); - PageUtils.Redirect(siteId > 0 - ? GetRedirectUrl(siteId) - : PageAnalysisSiteDownloads.GetRedirectUrl()); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var ltlItemTitle = (Literal)e.Item.FindControl("ltlItemTitle"); - var ltlChannel = (Literal)e.Item.FindControl("ltlChannel"); - var ltlFileUrl = (Literal)e.Item.FindControl("ltlFileUrl"); - - var contentInfo = new ContentInfo(e.Item.DataItem); - - ltlItemTitle.Text = WebUtils.GetContentTitle(SiteInfo, contentInfo, PageUrl); - - string nodeNameNavigation; - if (!_nodeNameNavigations.ContainsKey(contentInfo.ChannelId)) - { - nodeNameNavigation = ChannelManager.GetChannelNameNavigation(SiteId, contentInfo.ChannelId); - _nodeNameNavigations.Add(contentInfo.ChannelId, nodeNameNavigation); - } - else - { - nodeNameNavigation = _nodeNameNavigations[contentInfo.ChannelId] as string; - } - ltlChannel.Text = nodeNameNavigation; - - var fileUrl = contentInfo.GetString(BackgroundContentAttribute.FileUrl); - if (!string.IsNullOrEmpty(fileUrl)) - { - ltlFileUrl.Text = - $@"{fileUrl}"; - } - - //x轴信息 - SetXHashtable(contentInfo.Id, contentInfo.Title); - //y轴信息 - SetYHashtable(contentInfo.Id, CountManager.GetCount(SiteInfo.TableName, contentInfo.Id.ToString(), ECountType.Download)); - } - - private string _pageUrl; - private string PageUrl - { - get - { - if (string.IsNullOrEmpty(_pageUrl)) - { - _pageUrl = PageUtils.GetSettingsUrl(nameof(PageAnalysisSiteDownloadsChannels), new NameValueCollection - { - {"SiteId", SiteId.ToString()} - }); - } - return _pageUrl; - } - } - - private void SetXHashtable(int contentId, string title) - { - if (!_xHashtable.ContainsKey(contentId)) - { - _xHashtable.Add(contentId, title); - } - if (!_contentIdList.Contains(contentId)) - { - _contentIdList.Add(contentId); - } - } - - private string GetXHashtable(int contentId) - { - return _xHashtable.ContainsKey(contentId) ? _xHashtable[contentId].ToString() : string.Empty; - } - - private void SetYHashtable(int contentId, int value) - { - - if (!_yHashtableDownload.ContainsKey(contentId)) - { - _yHashtableDownload.Add(contentId, value); - } - else - { - var num = TranslateUtils.ToInt(_yHashtableDownload[contentId].ToString()); - _yHashtableDownload[contentId] = num + value; - } - SetVertical(YTypeDownload, value); - - SetHorizental(contentId, value); - } - - private string GetYHashtable(int contentId) - { - if (!_yHashtableDownload.ContainsKey(contentId)) return "0"; - var num = TranslateUtils.ToInt(_yHashtableDownload[contentId].ToString()); - return num.ToString(); - } - - private void SetHorizental(int contentId, int num) - { - if (_horizentalHashtable[contentId] == null) - { - _horizentalHashtable[contentId] = num; - } - else - { - var totalNum = (int)_horizentalHashtable[contentId]; - _horizentalHashtable[contentId] = totalNum + num; - } - } - - private void SetVertical(string type, int num) - { - if (_verticalHashtable[type] == null) - { - _verticalHashtable[type] = num; - } - else - { - var totalNum = (int)_verticalHashtable[type]; - _verticalHashtable[type] = totalNum + num; - } - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageCreateStatus.cs b/SiteServer.BackgroundPages/Settings/PageCreateStatus.cs deleted file mode 100644 index a21cf528a..000000000 --- a/SiteServer.BackgroundPages/Settings/PageCreateStatus.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Collections.Specialized; -using SiteServer.CMS.Api; -using SiteServer.Utils; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageCreateStatus : BasePageCms - { - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetSettingsUrl(nameof(PageCreateStatus), new NameValueCollection - { - {"siteID", siteId.ToString()} - }); - } - - public static string GetOpenLayerString(int siteId) - { - return LayerUtils.GetOpenScript("页面生成进度", - PageUtils.GetSettingsUrl(nameof(PageCreateStatus), new NameValueCollection - { - {"siteID", siteId.ToString()} - })); - } - - public static void Redirect(int siteId) - { - var pageUrl = PageUtils.GetSettingsUrl(nameof(PageCreateStatus), new NameValueCollection - { - {"siteID", siteId.ToString()} - }); - PageUtils.Redirect(pageUrl); - } - - public string SiteUrl => PageRedirect.GetRedirectUrl(SiteId); - - public string SignalrHubsUrl = ApiManager.SignalrHubsUrl; - - //public void Page_Load(object sender, EventArgs e) - //{ - // if (IsForbidden) return; - - // if (!IsPostBack) - // { - // base.BreadCrumb(AppManager.LeftMenu.ID_Utility, "生成队列", AppManager.Permission.Platform_Utility); - // } - - // if (!string.IsNullOrEmpty(base.AuthRequest.GetQueryString("Cancel"))) - // { - // DataProvider.CreateTaskDAO.DeleteAll(base.SiteId); - // } - //} - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageLogAdmin.cs b/SiteServer.BackgroundPages/Settings/PageLogAdmin.cs deleted file mode 100644 index 8851a1b1b..000000000 --- a/SiteServer.BackgroundPages/Settings/PageLogAdmin.cs +++ /dev/null @@ -1,140 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageLogAdmin : BasePage - { - public DateTimeTextBox TbDateFrom; - public DateTimeTextBox TbDateTo; - public TextBox TbUserName; - public TextBox TbKeyword; - public Repeater RptContents; - public SqlPager SpContents; - public Literal LtlState; - public Button BtnDelete; - public Button BtnDeleteAll; - public Button BtnSetting; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - SpContents.ControlToPaginate = RptContents; - SpContents.ItemsPerPage = StringUtils.Constants.PageSize; - - SpContents.SelectCommand = !AuthRequest.IsQueryExists("Keyword") ? DataProvider.LogDao.GetSelectCommend() : DataProvider.LogDao.GetSelectCommend(AuthRequest.GetQueryString("UserName"), AuthRequest.GetQueryString("Keyword"), AuthRequest.GetQueryString("DateFrom"), AuthRequest.GetQueryString("DateTo")); - - SpContents.SortField = nameof(LogInfo.Id); - SpContents.SortMode = SortMode.DESC; - RptContents.ItemDataBound += RptContents_ItemDataBound; - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Log); - - if (AuthRequest.IsQueryExists("Keyword")) - { - TbUserName.Text = AuthRequest.GetQueryString("UserName"); - TbKeyword.Text = AuthRequest.GetQueryString("Keyword"); - TbDateFrom.Text = AuthRequest.GetQueryString("DateFrom"); - TbDateTo.Text = AuthRequest.GetQueryString("DateTo"); - } - - if (AuthRequest.IsQueryExists("Delete")) - { - var arraylist = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("IDCollection")); - try - { - DataProvider.LogDao.Delete(arraylist); - SuccessDeleteMessage(); - } - catch (Exception ex) - { - FailDeleteMessage(ex); - } - } - else if (AuthRequest.IsQueryExists("DeleteAll")) - { - DataProvider.LogDao.DeleteAll(); - SuccessDeleteMessage(); - } - else if (AuthRequest.IsQueryExists("Setting")) - { - ConfigManager.SystemConfigInfo.IsLogAdmin = !ConfigManager.SystemConfigInfo.IsLogAdmin; - DataProvider.ConfigDao.Update(ConfigManager.Instance); - SuccessMessage($"成功{(ConfigManager.SystemConfigInfo.IsLogAdmin ? "启用" : "禁用")}日志记录"); - } - - BtnDelete.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert(PageUtils.GetSettingsUrl(nameof(PageLogAdmin), new NameValueCollection - { - {"Delete", "True" } - }), "IDCollection", "IDCollection", "请选择需要删除的日志!", "此操作将删除所选日志,确认吗?")); - - BtnDeleteAll.Attributes.Add("onclick", - AlertUtils.ConfirmRedirect("删除所有日志", "此操作将删除所有日志信息,确定吗?", "删除全部", - PageUtils.GetSettingsUrl(nameof(PageLogAdmin), new NameValueCollection - { - {"DeleteAll", "True"} - }))); - - if (ConfigManager.SystemConfigInfo.IsLogAdmin) - { - BtnSetting.Text = "禁用记录日志"; - BtnSetting.Attributes.Add("onclick", - AlertUtils.ConfirmRedirect("禁用记录日志", "此操作将禁用管理员日志记录功能,确定吗?", "禁 用", - PageUtils.GetSettingsUrl(nameof(PageLogAdmin), new NameValueCollection - { - {"Setting", "True"} - }))); - } - else - { - LtlState.Text = @"
    管理员日志当前处于禁用状态,系统将不会记录管理员操作日志!
    "; - BtnSetting.Text = "启用记录日志"; - BtnSetting.Attributes.Add("onclick", - AlertUtils.ConfirmRedirect("启用记录日志", "此操作将启用管理员日志记录功能,确定吗?", "启 用", - PageUtils.GetSettingsUrl(nameof(PageLogAdmin), new NameValueCollection - { - {"Setting", "True"} - }))); - } - - SpContents.DataBind(); - } - - private static void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var ltlUserName = (Literal)e.Item.FindControl("ltlUserName"); - var ltlAddDate = (Literal)e.Item.FindControl("ltlAddDate"); - var ltlIpAddress = (Literal)e.Item.FindControl("ltlIpAddress"); - var ltlAction = (Literal)e.Item.FindControl("ltlAction"); - var ltlSummary = (Literal)e.Item.FindControl("ltlSummary"); - - ltlUserName.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(LogInfo.UserName)); - ltlAddDate.Text = DateUtils.GetDateAndTimeString(SqlUtils.EvalDateTime(e.Item.DataItem, nameof(LogInfo.AddDate))); - ltlIpAddress.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(LogInfo.IpAddress)); - ltlAction.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(LogInfo.Action)); - ltlSummary.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(LogInfo.Summary)); - } - - public void Search_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(PageUtils.GetSettingsUrl(nameof(PageLogAdmin), new NameValueCollection - { - {"UserName", TbUserName.Text}, - {"Keyword", TbKeyword.Text}, - {"DateFrom", TbDateFrom.Text}, - {"DateTo", TbDateTo.Text} - })); - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageLogConfiguration.cs b/SiteServer.BackgroundPages/Settings/PageLogConfiguration.cs deleted file mode 100644 index 75013e08a..000000000 --- a/SiteServer.BackgroundPages/Settings/PageLogConfiguration.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageLogConfiguration : BasePage - { - protected RadioButtonList RblIsTimeThreshold; - public PlaceHolder PhTimeThreshold; - protected TextBox TbTime; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Log); - - EBooleanUtils.AddListItems(RblIsTimeThreshold, "启用", "不启用"); - ControlUtils.SelectSingleItem(RblIsTimeThreshold, ConfigManager.SystemConfigInfo.IsTimeThreshold.ToString()); - TbTime.Text = ConfigManager.SystemConfigInfo.TimeThreshold.ToString(); - - PhTimeThreshold.Visible = TranslateUtils.ToBool(RblIsTimeThreshold.SelectedValue); - } - - public void RblIsTimeThreshold_SelectedIndexChanged(object sender, EventArgs e) - { - PhTimeThreshold.Visible = TranslateUtils.ToBool(RblIsTimeThreshold.SelectedValue); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - ConfigManager.SystemConfigInfo.IsTimeThreshold = TranslateUtils.ToBool(RblIsTimeThreshold.SelectedValue); - if (ConfigManager.SystemConfigInfo.IsTimeThreshold) - { - ConfigManager.SystemConfigInfo.TimeThreshold = TranslateUtils.ToInt(TbTime.Text); - } - - DataProvider.ConfigDao.Update(ConfigManager.Instance); - - AuthRequest.AddAdminLog("设置日志阈值参数"); - SuccessMessage("日志设置成功"); - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageLogError.cs b/SiteServer.BackgroundPages/Settings/PageLogError.cs deleted file mode 100644 index 65775525e..000000000 --- a/SiteServer.BackgroundPages/Settings/PageLogError.cs +++ /dev/null @@ -1,162 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Plugin; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageLogError : BasePage - { - public DropDownList DdlPluginId; - public DateTimeTextBox TbDateFrom; - public DateTimeTextBox TbDateTo; - public TextBox TbKeyword; - public Repeater RptContents; - public SqlPager SpContents; - public Button BtnDelete; - public Button BtnDeleteAll; - public Literal LtlState; - public Button BtnSetting; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (AuthRequest.IsQueryExists("Delete")) - { - var list = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("IDCollection")); - try - { - DataProvider.ErrorLogDao.Delete(list); - SuccessDeleteMessage(); - } - catch (Exception ex) - { - FailDeleteMessage(ex); - } - } - else if (AuthRequest.IsQueryExists("DeleteAll")) - { - try - { - DataProvider.ErrorLogDao.DeleteAll(); - SuccessDeleteMessage(); - } - catch (Exception ex) - { - FailDeleteMessage(ex); - } - } - else if (AuthRequest.IsQueryExists("Setting")) - { - ConfigManager.SystemConfigInfo.IsLogError = !ConfigManager.SystemConfigInfo.IsLogError; - DataProvider.ConfigDao.Update(ConfigManager.Instance); - SuccessMessage($"成功{(ConfigManager.SystemConfigInfo.IsLogError ? "启用" : "禁用")}日志记录"); - } - - SpContents.ControlToPaginate = RptContents; - SpContents.ItemsPerPage = StringUtils.Constants.PageSize; - - SpContents.SelectCommand = DataProvider.ErrorLogDao.GetSelectCommend(AuthRequest.GetQueryString("PluginId"), AuthRequest.GetQueryString("Keyword"), - AuthRequest.GetQueryString("DateFrom"), AuthRequest.GetQueryString("DateTo")); - - SpContents.SortField = nameof(ErrorLogInfo.Id); - SpContents.SortMode = SortMode.DESC; - RptContents.ItemDataBound += RptContents_ItemDataBound; - - if (IsPostBack) return; - - DdlPluginId.Items.Add(new ListItem("全部错误", string.Empty)); - foreach (var pluginInfo in PluginManager.AllPluginInfoList) - { - DdlPluginId.Items.Add(new ListItem(pluginInfo.Id, pluginInfo.Id)); - } - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Log); - - if (AuthRequest.IsQueryExists("Keyword")) - { - ControlUtils.SelectSingleItem(DdlPluginId, AuthRequest.GetQueryString("PluginId")); - TbKeyword.Text = AuthRequest.GetQueryString("Keyword"); - TbDateFrom.Text = AuthRequest.GetQueryString("DateFrom"); - TbDateTo.Text = AuthRequest.GetQueryString("DateTo"); - } - - BtnDelete.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert(PageUtils.GetSettingsUrl(nameof(PageLogError), new NameValueCollection - { - {"Delete", "True" } - }), "IDCollection", "IDCollection", "请选择需要删除的日志!", "此操作将删除所选日志,确认吗?")); - - BtnDeleteAll.Attributes.Add("onclick", - AlertUtils.ConfirmRedirect("删除所有日志", "此操作将删除所有日志信息,确定吗?", "删除全部", - PageUtils.GetSettingsUrl(nameof(PageLogError), new NameValueCollection - { - {"DeleteAll", "True"} - }))); - - if (ConfigManager.SystemConfigInfo.IsLogError) - { - BtnSetting.Text = "禁用系统错误日志"; - BtnSetting.Attributes.Add("onclick", - AlertUtils.ConfirmRedirect("禁用系统错误日志", "此操作将禁用系统错误日志记录功能,确定吗?", "禁 用", - PageUtils.GetSettingsUrl(nameof(PageLogError), new NameValueCollection - { - {"Setting", "True"} - }))); - } - else - { - LtlState.Text = @"
    系统错误日志当前处于禁用状态,系统将不会记录系统错误日志!
    "; - BtnSetting.Text = "启用记录日志"; - BtnSetting.Attributes.Add("onclick", - AlertUtils.ConfirmRedirect("启用系统错误日志", "此操作将启用系统错误日志记录功能,确定吗?", "启 用", - PageUtils.GetSettingsUrl(nameof(PageLogError), new NameValueCollection - { - {"Setting", "True"} - }))); - } - - SpContents.DataBind(); - } - - private static void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var id = SqlUtils.EvalInt(e.Item.DataItem, nameof(ErrorLogInfo.Id)); - var addDate = SqlUtils.EvalDateTime(e.Item.DataItem, nameof(ErrorLogInfo.AddDate)); - var message = SqlUtils.EvalString(e.Item.DataItem, nameof(ErrorLogInfo.Message)); - var summary = SqlUtils.EvalString(e.Item.DataItem, nameof(ErrorLogInfo.Summary)); - - var ltlId = (Literal)e.Item.FindControl("ltlId"); - var ltlAddDate = (Literal)e.Item.FindControl("ltlAddDate"); - var ltlMessage = (Literal)e.Item.FindControl("ltlMessage"); - var ltlSummary = (Literal)e.Item.FindControl("ltlSummary"); - - ltlId.Text = $@"{id}"; - ltlAddDate.Text = DateUtils.GetDateAndTimeString(addDate); - ltlMessage.Text = message; - ltlSummary.Text = summary; - if (!string.IsNullOrEmpty(ltlSummary.Text)) - { - ltlSummary.Text += "
    "; - } - } - - public void Search_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(PageUtils.GetSettingsUrl(nameof(PageLogError), new NameValueCollection - { - {"PluginId", DdlPluginId.SelectedValue}, - {"Keyword", TbKeyword.Text}, - {"DateFrom", TbDateFrom.Text}, - {"DateTo", TbDateTo.Text} - })); - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageLogSite.cs b/SiteServer.BackgroundPages/Settings/PageLogSite.cs deleted file mode 100644 index bc3239e79..000000000 --- a/SiteServer.BackgroundPages/Settings/PageLogSite.cs +++ /dev/null @@ -1,161 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageLogSite : BasePageCms - { - public DropDownList DdlSiteId; - public DropDownList DdlLogType; - public TextBox TbUserName; - public TextBox TbKeyword; - public DateTimeTextBox TbDateFrom; - public DateTimeTextBox TbDateTo; - - public Repeater RptContents; - public SqlPager SpContents; - public Literal LtlSite; - - public Button BtnDelete; - public Button BtnDeleteAll; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - SpContents.ControlToPaginate = RptContents; - SpContents.ItemsPerPage = StringUtils.Constants.PageSize; - - SpContents.SelectCommand = !AuthRequest.IsQueryExists("LogType") - ? DataProvider.SiteLogDao.GetSelectCommend() - : DataProvider.SiteLogDao.GetSelectCommend(SiteId, AuthRequest.GetQueryString("LogType"), - AuthRequest.GetQueryString("UserName"), AuthRequest.GetQueryString("Keyword"), AuthRequest.GetQueryString("DateFrom"), - AuthRequest.GetQueryString("DateTo")); - - SpContents.SortField = nameof(SiteLogInfo.Id); - SpContents.SortMode = SortMode.DESC; - RptContents.ItemDataBound += RptContents_ItemDataBound; - - if (AuthRequest.IsQueryExists("Delete")) - { - var arraylist = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("IDCollection")); - try - { - DataProvider.SiteLogDao.Delete(arraylist); - SuccessDeleteMessage(); - } - catch (Exception ex) - { - FailDeleteMessage(ex); - } - } - else if (AuthRequest.IsQueryExists("DeleteAll")) - { - try - { - DataProvider.SiteLogDao.DeleteAll(); - SuccessDeleteMessage(); - } - catch (Exception ex) - { - FailDeleteMessage(ex); - } - } - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Log); - - if (SiteId == 0) - { - LtlSite.Text = @"站点名称"; - } - - DdlSiteId.Items.Add(new ListItem("<<全部站点>>", "0")); - - var siteIdList = SiteManager.GetSiteIdListOrderByLevel(); - foreach (var psId in siteIdList) - { - DdlSiteId.Items.Add(new ListItem(SiteManager.GetSiteInfo(psId).SiteName, psId.ToString())); - } - - DdlLogType.Items.Add(new ListItem("全部记录", "All")); - DdlLogType.Items.Add(new ListItem("栏目相关记录", "Channel")); - DdlLogType.Items.Add(new ListItem("内容相关记录", "Content")); - - if (AuthRequest.IsQueryExists("LogType")) - { - ControlUtils.SelectSingleItem(DdlSiteId, SiteId.ToString()); - ControlUtils.SelectSingleItem(DdlLogType, AuthRequest.GetQueryString("LogType")); - TbUserName.Text = AuthRequest.GetQueryString("UserName"); - TbKeyword.Text = AuthRequest.GetQueryString("Keyword"); - TbDateFrom.Text = AuthRequest.GetQueryString("DateFrom"); - TbDateTo.Text = AuthRequest.GetQueryString("DateTo"); - } - - BtnDelete.Attributes.Add("onclick", - PageUtils.GetRedirectStringWithCheckBoxValueAndAlert( - PageUtils.GetSettingsUrl(nameof(PageLogSite), new NameValueCollection - { - {"Delete", "True"} - }), "IDCollection", "IDCollection", "请选择需要删除的日志!", "此操作将删除所选日志,确认吗?")); - - BtnDeleteAll.Attributes.Add("onclick", - AlertUtils.ConfirmRedirect("删除所有日志", "此操作将删除所有日志信息,确定吗?", "删除全部", - PageUtils.GetSettingsUrl(nameof(PageLogSite), new NameValueCollection - { - {"DeleteAll", "True"} - }))); - - SpContents.DataBind(); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var ltlSite = (Literal)e.Item.FindControl("ltlSite"); - var ltlUserName = (Literal)e.Item.FindControl("ltlUserName"); - var ltlAddDate = (Literal)e.Item.FindControl("ltlAddDate"); - var ltlIpAddress = (Literal)e.Item.FindControl("ltlIpAddress"); - var ltlAction = (Literal)e.Item.FindControl("ltlAction"); - var ltlSummary = (Literal)e.Item.FindControl("ltlSummary"); - - if (SiteId == 0) - { - var siteInfo = SiteManager.GetSiteInfo(SqlUtils.EvalInt(e.Item.DataItem, nameof(SiteLogInfo.SiteId))); - var siteName = string.Empty; - if (siteInfo != null) - { - siteName = - $"{siteInfo.SiteName}"; - } - ltlSite.Text = $@"{siteName}"; - } - ltlUserName.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(SiteLogInfo.UserName)); - ltlAddDate.Text = DateUtils.GetDateAndTimeString(SqlUtils.EvalDateTime(e.Item.DataItem, nameof(SiteLogInfo.AddDate))); - ltlIpAddress.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(SiteLogInfo.IpAddress)); - ltlAction.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(SiteLogInfo.Action)); - ltlSummary.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(SiteLogInfo.Summary)); - } - - public void Search_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(PageUtils.GetSettingsUrl(nameof(PageLogSite), new NameValueCollection - { - {"UserName", TbUserName.Text}, - {"Keyword", TbKeyword.Text}, - {"DateFrom", TbDateFrom.Text}, - {"DateTo", TbDateTo.Text}, - {"SiteId", DdlSiteId.SelectedValue}, - {"LogType", DdlLogType.SelectedValue} - })); - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageLogUser.cs b/SiteServer.BackgroundPages/Settings/PageLogUser.cs deleted file mode 100644 index ef5e8e8d6..000000000 --- a/SiteServer.BackgroundPages/Settings/PageLogUser.cs +++ /dev/null @@ -1,133 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageLogUser : BasePage - { - public DateTimeTextBox TbDateFrom; - public DateTimeTextBox TbDateTo; - public TextBox TbUserName; - public TextBox TbKeyword; - public Repeater RptContents; - public SqlPager SpContents; - public Literal LtlState; - public Button BtnDelete; - public Button BtnDeleteAll; - public Button BtnSetting; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - SpContents.ControlToPaginate = RptContents; - SpContents.ItemsPerPage = StringUtils.Constants.PageSize; - - SpContents.SelectCommand = !AuthRequest.IsQueryExists("Keyword") ? DataProvider.UserLogDao.GetSelectCommend() : DataProvider.UserLogDao.GetSelectCommend(AuthRequest.GetQueryString("UserName"), AuthRequest.GetQueryString("Keyword"), AuthRequest.GetQueryString("DateFrom"), AuthRequest.GetQueryString("DateTo")); - - SpContents.SortField = nameof(UserLogInfo.Id); - SpContents.SortMode = SortMode.DESC; - RptContents.ItemDataBound += RptContents_ItemDataBound; - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Log); - - if (AuthRequest.IsQueryExists("Keyword")) - { - TbUserName.Text = AuthRequest.GetQueryString("UserName"); - TbKeyword.Text = AuthRequest.GetQueryString("Keyword"); - TbDateFrom.Text = AuthRequest.GetQueryString("DateFrom"); - TbDateTo.Text = AuthRequest.GetQueryString("DateTo"); - } - - if (AuthRequest.IsQueryExists("Delete")) - { - var list = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("IDCollection")); - DataProvider.UserLogDao.Delete(list); - SuccessDeleteMessage(); - } - else if (AuthRequest.IsQueryExists("DeleteAll")) - { - DataProvider.UserLogDao.DeleteAll(); - SuccessDeleteMessage(); - } - else if (AuthRequest.IsQueryExists("Setting")) - { - ConfigManager.SystemConfigInfo.IsLogUser = !ConfigManager.SystemConfigInfo.IsLogUser; - DataProvider.ConfigDao.Update(ConfigManager.Instance); - SuccessMessage($"成功{(ConfigManager.SystemConfigInfo.IsLogUser ? "启用" : "禁用")}日志记录"); - } - - BtnDelete.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert(PageUtils.GetSettingsUrl(nameof(PageLogUser), new NameValueCollection - { - {"Delete", "True" } - }), "IDCollection", "IDCollection", "请选择需要删除的日志!", "此操作将删除所选日志,确认吗?")); - - BtnDeleteAll.Attributes.Add("onclick", - AlertUtils.ConfirmRedirect("删除所有日志", "此操作将删除所有日志信息,确定吗?", "删除全部", - PageUtils.GetSettingsUrl(nameof(PageLogUser), new NameValueCollection - { - {"DeleteAll", "True"} - }))); - - if (ConfigManager.SystemConfigInfo.IsLogUser) - { - BtnSetting.Text = "禁用记录日志"; - BtnSetting.Attributes.Add("onclick", - AlertUtils.ConfirmRedirect("禁用记录日志", "此操作将禁用用户日志记录功能,确定吗?", "禁 用", - PageUtils.GetSettingsUrl(nameof(PageLogUser), new NameValueCollection - { - {"Setting", "True"} - }))); - } - else - { - LtlState.Text = @"
    用户日志当前处于禁用状态,系统将不会记录用户操作日志!
    "; - BtnSetting.Text = "启用记录日志"; - BtnSetting.Attributes.Add("onclick", - AlertUtils.ConfirmRedirect("启用记录日志", "此操作将启用用户日志记录功能,确定吗?", "启 用", - PageUtils.GetSettingsUrl(nameof(PageLogUser), new NameValueCollection - { - {"Setting", "True"} - }))); - } - - SpContents.DataBind(); - } - - private static void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var ltlUserName = (Literal)e.Item.FindControl("ltlUserName"); - var ltlAddDate = (Literal)e.Item.FindControl("ltlAddDate"); - var ltlIpAddress = (Literal)e.Item.FindControl("ltlIpAddress"); - var ltlAction = (Literal)e.Item.FindControl("ltlAction"); - var ltlSummary = (Literal)e.Item.FindControl("ltlSummary"); - - ltlUserName.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(UserLogInfo.UserName)); - ltlAddDate.Text = DateUtils.GetDateAndTimeString(SqlUtils.EvalDateTime(e.Item.DataItem, nameof(UserLogInfo.AddDate))); - ltlIpAddress.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(UserLogInfo.IpAddress)); - ltlAction.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(UserLogInfo.Action)); - ltlSummary.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(UserLogInfo.Summary)); - } - - public void Search_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(PageUtils.GetSettingsUrl(nameof(PageLogUser), new NameValueCollection - { - {"UserName", TbUserName.Text}, - {"Keyword", TbKeyword.Text}, - {"DateFrom", TbDateFrom.Text}, - {"DateTo", TbDateTo.Text} - })); - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageRecord.cs b/SiteServer.BackgroundPages/Settings/PageRecord.cs deleted file mode 100644 index 1ae08013e..000000000 --- a/SiteServer.BackgroundPages/Settings/PageRecord.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageRecord : Page - { - public TextBox TbKeyword; - public DateTimeTextBox TbDateFrom; - public DateTimeTextBox TbDateTo; - public Repeater RptContents; - public SqlPager SpContents; - public Button BtnDelete; - public Button BtnDeleteAll; - - public void Page_Load(object sender, EventArgs e) - { - if (!DataProvider.RecordDao.IsRecord()) return; - - if (!string.IsNullOrEmpty(Request.QueryString["Delete"])) - { - var list = TranslateUtils.StringCollectionToIntList(Request.QueryString["IdCollection"]); - DataProvider.RecordDao.Delete(list); - } - else if (!string.IsNullOrEmpty(Request.QueryString["DeleteAll"])) - { - DataProvider.RecordDao.DeleteAll(); - } - - SpContents.ControlToPaginate = RptContents; - SpContents.ItemsPerPage = 100; - - SpContents.SelectCommand = string.IsNullOrEmpty(Request.QueryString["Keyword"]) ? DataProvider.RecordDao.GetSqlString() : DataProvider.RecordDao.GetSqlString(Request.QueryString["Keyword"], Request.QueryString["DateFrom"], Request.QueryString["DateTo"]); - - SpContents.SortField = "Id"; - SpContents.SortMode = SortMode.DESC; - RptContents.ItemDataBound += RptContents_ItemDataBound; - - if (IsPostBack) return; - - if (!string.IsNullOrEmpty(Request.QueryString["Keyword"])) - { - TbKeyword.Text = Request.QueryString["Keyword"]; - TbDateFrom.Text = Request.QueryString["DateFrom"]; - TbDateTo.Text = Request.QueryString["DateTo"]; - } - - BtnDelete.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert(PageUtils.GetSettingsUrl(nameof(PageRecord), new NameValueCollection - { - {"Delete", "True" } - }), "IDCollection", "IDCollection", "请选择需要删除的记录!", "此操作将删除所选记录,确认吗?")); - - BtnDeleteAll.Attributes.Add("onclick", PageUtils.GetRedirectStringWithConfirm(PageUtils.GetSettingsUrl(nameof(PageRecord), new NameValueCollection - { - {"DeleteAll", "True" } - }), "此操作将删除所有记录信息,确定吗?")); - - SpContents.DataBind(); - } - - private static void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var ltlText = (Literal)e.Item.FindControl("ltlText"); - var ltlSummary = (Literal)e.Item.FindControl("ltlSummary"); - var ltlSource = (Literal)e.Item.FindControl("ltlSource"); - var ltlAddDate = (Literal)e.Item.FindControl("ltlAddDate"); - - ltlText.Text = SqlUtils.EvalString(e.Item.DataItem, "Text"); - ltlSummary.Text = SqlUtils.EvalString(e.Item.DataItem, "Summary"); - ltlSource.Text = SqlUtils.EvalString(e.Item.DataItem, "Source"); - ltlAddDate.Text = DateUtils.GetDateAndTimeString(SqlUtils.EvalDateTime(e.Item.DataItem, "AddDate"), EDateFormatType.Day, ETimeFormatType.LongTime); - } - - public void Search_OnClick(object sender, EventArgs e) - { - Response.Redirect(PageUrl, true); - } - - private string PageUrl => PageUtils.GetSettingsUrl(nameof(PageRecord), new NameValueCollection - { - {"Keyword", TbKeyword.Text}, - {"DateFrom", TbDateFrom.Text}, - {"DateTo", TbDateTo.Text} - }); - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageSite.cs b/SiteServer.BackgroundPages/Settings/PageSite.cs deleted file mode 100644 index e1fc28280..000000000 --- a/SiteServer.BackgroundPages/Settings/PageSite.cs +++ /dev/null @@ -1,146 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageSite : BasePageCms - { - public Repeater RptContents; - - private int _hqSiteId; - - public static string GetRedirectUrl() - { - return PageUtils.GetSettingsUrl(nameof(PageSite), null); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (AuthRequest.IsQueryExists("SiteId") && (AuthRequest.IsQueryExists("Up") || AuthRequest.IsQueryExists("Down"))) - { - var siteId = AuthRequest.GetQueryInt("SiteId"); - - if (AuthRequest.IsQueryExists("Up") && AuthRequest.GetQueryBool("Up")) - { - DataProvider.SiteDao.UpdateTaxisToUp(siteId); - } - else - { - DataProvider.SiteDao.UpdateTaxisToDown(siteId); - } - - } - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Site); - - _hqSiteId = DataProvider.SiteDao.GetIdByIsRoot(); - - RptContents.DataSource = SiteManager.GetSiteIdList(); - RptContents.ItemDataBound += RptContents_ItemDataBound; - RptContents.DataBind(); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var siteId = (int)e.Item.DataItem; - var siteInfo = SiteManager.GetSiteInfo(siteId); - if (siteInfo == null) return; - - var ltlSiteName = (Literal)e.Item.FindControl("ltlSiteName"); - var ltlSiteDir = (Literal)e.Item.FindControl("ltlSiteDir"); - var ltlAddDate = (Literal)e.Item.FindControl("ltlAddDate"); - var ltlSave = (Literal)e.Item.FindControl("ltlSave"); - var ltlEdit = (Literal)e.Item.FindControl("ltlEdit"); - var ltlChangeType = (Literal)e.Item.FindControl("ltlChangeType"); - var ltlReplace = (Literal)e.Item.FindControl("ltlReplace"); - var ltlDelete = (Literal)e.Item.FindControl("ltlDelete"); - var ltlUpLink = (Literal)e.Item.FindControl("ltlUpLink"); - var ltlDownLink = (Literal)e.Item.FindControl("ltlDownLink"); - - ltlSiteName.Text = GetSiteNameHtml(siteInfo); - ltlSiteDir.Text = siteInfo.SiteDir; - ltlAddDate.Text = DateUtils.GetDateString(ChannelManager.GetAddDate(siteId, siteId)); - - ltlSave.Text = $@"保存"; - - ltlEdit.Text = $@"修改"; - - ltlReplace.Text = $@"替换"; - - var upUrl = PageUtils.GetSettingsUrl(nameof(PageSite), new NameValueCollection - { - {"Up", "True" }, - {"SiteId", siteId.ToString() } - }); - ltlUpLink.Text = $@""; - - var downUrl = PageUtils.GetSettingsUrl(nameof(PageSite), new NameValueCollection - { - {"Down", "True" }, - {"SiteId", siteId.ToString() } - }); - ltlDownLink.Text = $@""; - - if (siteInfo.ParentId == 0 && (_hqSiteId == 0 || siteId == _hqSiteId)) - { - ltlChangeType.Text = GetChangeHtml(siteId, siteInfo.IsRoot); - } - - if (siteInfo.IsRoot == false) - { - ltlDelete.Text = $@"删除"; - } - } - - private static string GetSiteNameHtml(SiteInfo siteInfo) - { - var level = SiteManager.GetSiteLevel(siteInfo.Id); - string psLogo; - if (siteInfo.IsRoot) - { - psLogo = "siteHQ.gif"; - } - else - { - psLogo = "site.gif"; - if (level > 0 && level < 10) - { - psLogo = $"subsite{level + 1}.gif"; - } - } - psLogo = SiteServerAssets.GetIconUrl("tree/" + psLogo); - - var padding = string.Empty; - for (var i = 0; i < level; i++) - { - padding += " "; - } - if (level > 0) - { - padding += "└ "; - } - - return - $"{padding} {siteInfo.SiteName}"; - } - - private static string GetChangeHtml(int siteId, bool isHeadquarters) - { - var showPopWinString = ModalChangeSiteType.GetOpenWindowString(siteId); - - return isHeadquarters == false - ? $"转移到根目录" - : $"转移到子目录"; - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageSiteAdd.cs b/SiteServer.BackgroundPages/Settings/PageSiteAdd.cs deleted file mode 100644 index 213ecb605..000000000 --- a/SiteServer.BackgroundPages/Settings/PageSiteAdd.cs +++ /dev/null @@ -1,541 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.IO; -using System.Web.UI.HtmlControls; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Cms; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageSiteAdd : BasePageCms - { - protected override bool IsSinglePage => true; - - public PlaceHolder PhSource; - public RadioButtonList RblSource; - public HtmlInputHidden HihSiteTemplateDir; - public HtmlInputHidden HihOnlineTemplateName; - - public PlaceHolder PhSiteTemplates; - public Repeater RptSiteTemplates; - - public PlaceHolder PhOnlineTemplates; - public Repeater RptOnlineTemplates; - - public PlaceHolder PhSubmit; - public Literal LtlSource; - public TextBox TbSiteName; - public RadioButtonList RblIsRoot; - public PlaceHolder PhIsNotRoot; - public DropDownList DdlParentId; - public TextBox TbSiteDir; - public DropDownList DdlCharset; - public PlaceHolder PhIsImportContents; - public CheckBox CbIsImportContents; - public PlaceHolder PhIsImportTableStyles; - public CheckBox CbIsImportTableStyles; - public PlaceHolder PhIsSiteTemplateTable; - public RadioButtonList RblIsSiteTemplateTable; - public PlaceHolder PhTableName; - public DropDownList DdlTableName; - public RadioButtonList RblIsCheckContentUseLevel; - public PlaceHolder PhCheckContentLevel; - public DropDownList DdlCheckContentLevel; - - public Button BtnPrevious; - public Button BtnNext; - public Button BtnSubmit; - - public static string GetRedirectUrl() - { - return PageUtils.GetSettingsUrl(nameof(PageSiteAdd), null); - } - - public static string GetRedirectUrl(string siteTemplateDir, string onlineTemplateName) - { - return PageUtils.GetSettingsUrl(nameof(PageSiteAdd), new NameValueCollection - { - {"siteTemplateDir", siteTemplateDir}, - {"onlineTemplateName", onlineTemplateName} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.SiteAdd); - - DataProvider.TableDao.CreateAllTableCollectionInfoIfNotExists(); - - var hqSiteId = DataProvider.SiteDao.GetIdByIsRoot(); - if (hqSiteId == 0) - { - ControlUtils.SelectSingleItem(RblIsRoot, true.ToString()); - PhIsNotRoot.Visible = false; - } - else - { - RblIsRoot.Enabled = false; - } - - DdlParentId.Items.Add(new ListItem("<无上级站点>", "0")); - var siteIdArrayList = SiteManager.GetSiteIdList(); - var mySystemInfoArrayList = new ArrayList(); - var parentWithChildren = new Hashtable(); - foreach (var siteId in siteIdArrayList) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - if (siteInfo.IsRoot == false) - { - if (siteInfo.ParentId == 0) - { - mySystemInfoArrayList.Add(siteInfo); - } - else - { - var children = new ArrayList(); - if (parentWithChildren.Contains(siteInfo.ParentId)) - { - children = (ArrayList)parentWithChildren[siteInfo.ParentId]; - } - children.Add(siteInfo); - parentWithChildren[siteInfo.ParentId] = children; - } - } - } - foreach (SiteInfo siteInfo in mySystemInfoArrayList) - { - AddSite(DdlParentId, siteInfo, parentWithChildren, 0); - } - ControlUtils.SelectSingleItem(DdlParentId, "0"); - - ECharsetUtils.AddListItems(DdlCharset); - ControlUtils.SelectSingleItem(DdlCharset, ECharsetUtils.GetValue(ECharset.utf_8)); - - var tableList = DataProvider.TableDao.GetTableCollectionInfoListCreatedInDb(); - foreach (var tableInfo in tableList) - { - if (tableInfo.DisplayName.StartsWith("插件内容表:")) continue; - - var li = new ListItem($"{tableInfo.DisplayName}({tableInfo.TableName})", tableInfo.TableName); - DdlTableName.Items.Add(li); - } - - RblIsCheckContentUseLevel.Items.Add(new ListItem("默认审核机制", false.ToString())); - RblIsCheckContentUseLevel.Items.Add(new ListItem("多级审核机制", true.ToString())); - ControlUtils.SelectSingleItem(RblIsCheckContentUseLevel, false.ToString()); - - if (SiteTemplateManager.Instance.IsSiteTemplateExists) - { - RblSource.Items.Add(new ListItem("创建空站点(不使用站点模板)", ETriStateUtils.GetValue(ETriState.True))); - RblSource.Items.Add(new ListItem("使用本地站点模板创建站点", ETriStateUtils.GetValue(ETriState.False))); - RblSource.Items.Add(new ListItem("使用在线站点模板创建站点", ETriStateUtils.GetValue(ETriState.All))); - } - else - { - RblSource.Items.Add(new ListItem("创建空站点(不使用站点模板)", ETriStateUtils.GetValue(ETriState.True))); - RblSource.Items.Add(new ListItem("使用在线站点模板创建站点", ETriStateUtils.GetValue(ETriState.All))); - } - ControlUtils.SelectSingleItem(RblSource, ETriStateUtils.GetValue(ETriState.True)); - - var siteTemplateDir = AuthRequest.GetQueryString("siteTemplateDir"); - var onlineTemplateName = AuthRequest.GetQueryString("onlineTemplateName"); - - if (!string.IsNullOrEmpty(siteTemplateDir)) - { - HihSiteTemplateDir.Value = siteTemplateDir; - ControlUtils.SelectSingleItem(RblSource, ETriStateUtils.GetValue(ETriState.False)); - BtnNext_Click(null, EventArgs.Empty); - } - else if (!string.IsNullOrEmpty(onlineTemplateName)) - { - HihOnlineTemplateName.Value = onlineTemplateName; - ControlUtils.SelectSingleItem(RblSource, ETriStateUtils.GetValue(ETriState.All)); - BtnNext_Click(null, EventArgs.Empty); - } - } - - private bool IsSiteTemplate => ETriStateUtils.GetEnumType(RblSource.SelectedValue) == ETriState.False; - - private bool IsOnlineTemplate => ETriStateUtils.GetEnumType(RblSource.SelectedValue) == ETriState.All; - - public void RblIsRoot_SelectedIndexChanged(object sender, EventArgs e) - { - PhIsNotRoot.Visible = !TranslateUtils.ToBool(RblIsRoot.SelectedValue); - } - - public void RblIsSiteTemplateTable_SelectedIndexChanged(object sender, EventArgs e) - { - PhTableName.Visible = !TranslateUtils.ToBool(RblIsSiteTemplateTable.SelectedValue); - } - - public void RblIsCheckContentUseLevel_OnSelectedIndexChanged(object sender, EventArgs e) - { - PhCheckContentLevel.Visible = EBooleanUtils.Equals(RblIsCheckContentUseLevel.SelectedValue, EBoolean.True); - } - - public void BtnNext_Click(object sender, EventArgs e) - { - if (PhSource.Visible) - { - HideAll(); - - if (IsSiteTemplate) - { - var siteTemplates = SiteTemplateManager.Instance.GetSiteTemplateSortedList(); - - RptSiteTemplates.DataSource = siteTemplates.Values; - RptSiteTemplates.ItemDataBound += RptSiteTemplates_ItemDataBound; - RptSiteTemplates.DataBind(); - - ShowSiteTemplates(); - } - else if (IsOnlineTemplate) - { - List> list; - if (OnlineTemplateManager.TryGetOnlineTemplates(out list)) - { - RptOnlineTemplates.DataSource = list; - RptOnlineTemplates.ItemDataBound += RptOnlineTemplates_ItemDataBound; - RptOnlineTemplates.DataBind(); - - ShowOnlineTemplates(); - } - else - { - FailMessage($"在线模板获取失败:页面地址{OnlineTemplateManager.UrlHome}无法访问!"); - - ShowSource(); - } - } - else - { - LtlSource.Text = "创建空站点(不使用站点模板)"; - - ShowSubmit(); - } - } - else if (PhSiteTemplates.Visible) - { - HideAll(); - - var siteTemplateDir = HihSiteTemplateDir.Value; - - if (string.IsNullOrEmpty(siteTemplateDir)) - { - FailMessage("请选择需要使用的站点模板"); - ShowSiteTemplates(); - return; - } - - LtlSource.Text = $"使用本地站点模板创建站点({siteTemplateDir})"; - - ShowSubmit(); - } - else if (PhOnlineTemplates.Visible) - { - HideAll(); - - var onlineTemplateName = HihOnlineTemplateName.Value; - - if (string.IsNullOrEmpty(onlineTemplateName)) - { - FailMessage("请选择需要使用的在线站点模板"); - ShowOnlineTemplates(); - return; - } - - LtlSource.Text = $@"使用在线站点模板创建站点({onlineTemplateName})"; - - ShowSubmit(); - } - } - - public void BtnSubmit_Click(object sender, EventArgs e) - { - HideAll(); - - string errorMessage; - var theSiteId = Validate_SiteInfo(out errorMessage); - if (theSiteId > 0) - { - var siteTemplateDir = IsSiteTemplate ? HihSiteTemplateDir.Value : string.Empty; - var onlineTemplateName = IsOnlineTemplate ? HihOnlineTemplateName.Value : string.Empty; - PageUtils.Redirect(PageProgressBar.GetCreateSiteUrl(theSiteId, - CbIsImportContents.Checked, CbIsImportTableStyles.Checked, siteTemplateDir, onlineTemplateName, - TranslateUtils.ToBool(RblIsSiteTemplateTable.SelectedValue), StringUtils.Guid())); - } - else - { - FailMessage(errorMessage); - - ShowSubmit(); - } - } - - public void BtnPrevious_Click(object sender, EventArgs e) - { - if (PhSiteTemplates.Visible || PhOnlineTemplates.Visible) - { - HideAll(); - ShowSource(); - } - else if (PhSubmit.Visible) - { - HideAll(); - - if (IsSiteTemplate) - { - ShowSiteTemplates(); - } - else if (IsOnlineTemplate) - { - ShowOnlineTemplates(); - } - else - { - ShowSource(); - } - } - } - - private void RptSiteTemplates_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.AlternatingItem && e.Item.ItemType != ListItemType.Item) return; - - var templateInfo = (SiteTemplateInfo)e.Item.DataItem; - if (templateInfo == null) return; - - var directoryPath = PathUtility.GetSiteTemplatesPath(templateInfo.DirectoryName); - var directoryInfo = new DirectoryInfo(directoryPath); - - var ltlChoose = (Literal)e.Item.FindControl("ltlChoose"); - var ltlTemplateName = (Literal)e.Item.FindControl("ltlTemplateName"); - var ltlName = (Literal)e.Item.FindControl("ltlName"); - var ltlDescription = (Literal)e.Item.FindControl("ltlDescription"); - var ltlSamplePic = (Literal)e.Item.FindControl("ltlSamplePic"); - - ltlChoose.Text = $@""; - - if (!string.IsNullOrEmpty(templateInfo.SiteTemplateName)) - { - ltlTemplateName.Text = !string.IsNullOrEmpty(templateInfo.WebSiteUrl) ? $@"{templateInfo.SiteTemplateName}" : templateInfo.SiteTemplateName; - } - - ltlName.Text = directoryInfo.Name; - - if (!string.IsNullOrEmpty(templateInfo.Description)) - { - ltlDescription.Text = templateInfo.Description; - } - - if (!string.IsNullOrEmpty(templateInfo.PicFileName)) - { - var siteTemplateUrl = PageUtils.GetSiteTemplatesUrl(directoryInfo.Name); - var picFileName = PageUtils.GetSiteTemplateMetadataUrl(siteTemplateUrl, templateInfo.PicFileName); - ltlSamplePic.Text = $@"样图"; - } - } - - private void RptOnlineTemplates_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.AlternatingItem && e.Item.ItemType != ListItemType.Item) return; - - var dict = (Dictionary)e.Item.DataItem; - var title = dict["title"]; - var description = dict["description"]; - var author = dict["author"]; - var source = dict["source"]; - var lastEditDate = dict["lastEditDate"]; - - var ltlChoose = (Literal)e.Item.FindControl("ltlChoose"); - var ltlTitle = (Literal)e.Item.FindControl("ltlTitle"); - var ltlDescription = (Literal)e.Item.FindControl("ltlDescription"); - var ltlAuthor = (Literal)e.Item.FindControl("ltlAuthor"); - var ltlLastEditDate = (Literal)e.Item.FindControl("ltlLastEditDate"); - var ltlPreviewUrl = (Literal)e.Item.FindControl("ltlPreviewUrl"); - - ltlChoose.Text = $@""; - - var templateUrl = OnlineTemplateManager.GetTemplateUrl(title); - - ltlTitle.Text = $@"{title}"; - - ltlDescription.Text = description; - ltlAuthor.Text = author; - if (!string.IsNullOrEmpty(source) && PageUtils.IsProtocolUrl(source)) - { - ltlAuthor.Text = $@"{ltlAuthor.Text}"; - } - ltlLastEditDate.Text = lastEditDate; - - ltlPreviewUrl.Text = $@"模板详情"; - } - - private int Validate_SiteInfo(out string errorMessage) - { - try - { - var isHq = TranslateUtils.ToBool(RblIsRoot.SelectedValue); // 是否主站 - var parentSiteId = 0; - var siteDir = string.Empty; - - if (isHq == false) - { - if (DirectoryUtils.IsSystemDirectory(TbSiteDir.Text)) - { - errorMessage = "文件夹名称不能为系统文件夹名称!"; - return 0; - } - - parentSiteId = TranslateUtils.ToInt(DdlParentId.SelectedValue); - siteDir = TbSiteDir.Text; - - var list = DataProvider.SiteDao.GetLowerSiteDirList(parentSiteId); - if (list.IndexOf(siteDir.ToLower()) != -1) - { - errorMessage = "已存在相同的发布路径!"; - return 0; - } - - if (!DirectoryUtils.IsDirectoryNameCompliant(siteDir)) - { - errorMessage = "文件夹名称不符合系统要求!"; - return 0; - } - } - - var nodeInfo = new ChannelInfo(); - - nodeInfo.ChannelName = nodeInfo.IndexName = "首页"; - nodeInfo.ParentId = 0; - nodeInfo.ContentModelPluginId = string.Empty; - - var psInfo = new SiteInfo - { - SiteName = PageUtils.FilterXss(TbSiteName.Text), - SiteDir = siteDir, - TableName = DdlTableName.SelectedValue, - ParentId = parentSiteId, - IsRoot = isHq - }; - - psInfo.Additional.IsCheckContentLevel = TranslateUtils.ToBool(RblIsCheckContentUseLevel.SelectedValue); - - if (psInfo.Additional.IsCheckContentLevel) - { - psInfo.Additional.CheckContentLevel = TranslateUtils.ToInt(DdlCheckContentLevel.SelectedValue); - } - psInfo.Additional.Charset = DdlCharset.SelectedValue; - - var theSiteId = DataProvider.ChannelDao.InsertSiteInfo(nodeInfo, psInfo, AuthRequest.AdminName); - - if (AuthRequest.AdminPermissions.IsSystemAdministrator && !AuthRequest.AdminPermissions.IsConsoleAdministrator) - { - var siteIdList = AuthRequest.AdminPermissions.SiteIdList ?? new List(); - siteIdList.Add(theSiteId); - DataProvider.AdministratorDao.UpdateSiteIdCollection(AuthRequest.AdminName, TranslateUtils.ObjectCollectionToString(siteIdList)); - } - - AuthRequest.AddAdminLog("创建新站点", $"站点名称:{PageUtils.FilterXss(TbSiteName.Text)}"); - - errorMessage = string.Empty; - return theSiteId; - } - catch (Exception e) - { - errorMessage = e.Message; - return 0; - } - } - - private static void AddSite(ListControl listControl, SiteInfo siteInfo, Hashtable parentWithChildren, int level) - { - if (level > 1) return; - var padding = string.Empty; - for (var i = 0; i < level; i++) - { - padding += " "; - } - if (level > 0) - { - padding += "└ "; - } - - if (parentWithChildren[siteInfo.Id] != null) - { - var children = (ArrayList)parentWithChildren[siteInfo.Id]; - listControl.Items.Add(new ListItem(padding + siteInfo.SiteName + $"({children.Count})", siteInfo.Id.ToString())); - level++; - foreach (SiteInfo subSiteInfo in children) - { - AddSite(listControl, subSiteInfo, parentWithChildren, level); - } - } - else - { - listControl.Items.Add(new ListItem(padding + siteInfo.SiteName, siteInfo.Id.ToString())); - } - } - - private void HideAll() - { - PhSource.Visible = - PhSiteTemplates.Visible = - PhOnlineTemplates.Visible = - PhSubmit.Visible = PhIsImportContents.Visible = - PhIsImportTableStyles.Visible = - PhIsSiteTemplateTable.Visible = - PhTableName.Visible = - BtnPrevious.Enabled = BtnNext.Visible = BtnSubmit.Visible = false; - } - - private void ShowSource() - { - PhSource.Visible = BtnNext.Visible = true; - } - - private void ShowSiteTemplates() - { - PhSiteTemplates.Visible = BtnPrevious.Enabled = BtnNext.Visible = true; - } - - private void ShowOnlineTemplates() - { - PhOnlineTemplates.Visible = BtnPrevious.Enabled = BtnNext.Visible = true; - } - - private void ShowSubmit() - { - if (IsSiteTemplate) - { - PhSubmit.Visible = - PhIsImportContents.Visible = - PhIsImportTableStyles.Visible = - PhIsSiteTemplateTable.Visible = - PhTableName.Visible = BtnPrevious.Enabled = BtnSubmit.Visible = true; - } - else if (IsOnlineTemplate) - { - PhSubmit.Visible = - PhIsImportContents.Visible = - PhIsImportTableStyles.Visible = - PhIsSiteTemplateTable.Visible = - PhTableName.Visible = BtnPrevious.Enabled = BtnSubmit.Visible = true; - } - else - { - PhSubmit.Visible = PhTableName.Visible = BtnPrevious.Enabled = BtnSubmit.Visible = true; - } - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageSiteAuxiliaryTable.cs b/SiteServer.BackgroundPages/Settings/PageSiteAuxiliaryTable.cs deleted file mode 100644 index fdc7a8300..000000000 --- a/SiteServer.BackgroundPages/Settings/PageSiteAuxiliaryTable.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageSiteAuxiliaryTable : BasePageCms - { - public Repeater RptContents; - public Button BtnAdd; - - public static string GetRedirectUrl() - { - return PageUtils.GetSettingsUrl(nameof(PageSiteAuxiliaryTable), null); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (AuthRequest.IsQueryExists("Delete")) - { - var enName = AuthRequest.GetQueryString("ENName");//辅助表 - var enNameArchive = enName + "_Archive";//辅助表归档 - - try - { - DataProvider.TableDao.DeleteCollectionTableInfoAndDbTable(enName);//删除辅助表 - DataProvider.TableDao.DeleteCollectionTableInfoAndDbTable(enNameArchive);//删除辅助表归档 - - AuthRequest.AddAdminLog("删除辅助表", $"辅助表:{enName}"); - - SuccessDeleteMessage(); - } - catch(Exception ex) - { - FailDeleteMessage(ex); - } - } - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Site); - - RptContents.DataSource = DataProvider.TableDao.GetTableCollectionInfoList(); - RptContents.ItemDataBound += RptContents_ItemDataBound; - RptContents.DataBind(); - - BtnAdd.OnClientClick = ModalAuxiliaryTableAdd.GetOpenWindowString(); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var collectionInfo = (TableInfo)e.Item.DataItem; - var tableName = collectionInfo.TableName; - //var isHighlight = !collectionInfo.IsCreatedInDb || collectionInfo.IsChangedAfterCreatedInDb; - var isTableUsed = DataProvider.SiteDao.IsTableUsed(tableName); - - //if (isHighlight) e.Item.Attributes.Add("style", "color: red"); - - var ltlTableName = (Literal)e.Item.FindControl("ltlTableName"); - var ltlDisplayName = (Literal)e.Item.FindControl("ltlDisplayName"); - var ltlIsUsed = (Literal)e.Item.FindControl("ltlIsUsed"); - var ltlIsCreatedInDb = (Literal)e.Item.FindControl("ltlIsCreatedInDB"); - var ltlIsChangedAfterCreatedInDb = (Literal)e.Item.FindControl("ltlIsChangedAfterCreatedInDb"); - var ltlMetadataEdit = (Literal)e.Item.FindControl("ltlMetadataEdit"); - var ltlStyleEdit = (Literal)e.Item.FindControl("ltlStyleEdit"); - var ltlEdit = (Literal)e.Item.FindControl("ltlEdit"); - var ltlDelete = (Literal)e.Item.FindControl("ltlDelete"); - - ltlTableName.Text = tableName; - ltlDisplayName.Text = collectionInfo.DisplayName; - ltlIsUsed.Text = StringUtils.GetBoolText(isTableUsed); - ltlIsCreatedInDb.Text = StringUtils.GetBoolText(collectionInfo.IsCreatedInDb); - ltlIsChangedAfterCreatedInDb.Text = collectionInfo.IsCreatedInDb == false - ? "----" - : StringUtils.GetBoolText(collectionInfo.IsChangedAfterCreatedInDb); - - ltlMetadataEdit.Text = - $@"管理真实字段"; - - ltlStyleEdit.Text = $@"管理虚拟字段"; - - ltlEdit.Text = $@"编辑"; - - if (!isTableUsed) - { - var script = AlertUtils.Warning("删除辅助表", $"此操作将删除辅助表“{tableName}”,如果辅助表已在数据库中建立,将同时删除建立的辅助表,确认吗?", "取 消", - "确认删除", $"location.href = '{GetRedirectUrl()}?Delete=True&ENName={tableName}';"); - ltlDelete.Text = - $@"删除"; - } - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageSiteEdit.cs b/SiteServer.BackgroundPages/Settings/PageSiteEdit.cs deleted file mode 100644 index aa1416bed..000000000 --- a/SiteServer.BackgroundPages/Settings/PageSiteEdit.cs +++ /dev/null @@ -1,239 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageSiteEdit : BasePageCms - { - public TextBox TbSiteName; - public PlaceHolder PhSiteDir; - public TextBox TbSiteDir; - public PlaceHolder PhParentId; - public DropDownList DdlParentId; - public DropDownList DdlTableName; - public TextBox TbTaxis; - public RadioButtonList RblIsCheckContentUseLevel; - public PlaceHolder PhCheckContentLevel; - public DropDownList DdlCheckContentLevel; - public Button BtnSubmit; - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetSettingsUrl(nameof(PageSiteEdit), new NameValueCollection - { - {"siteId", siteId.ToString()} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("siteId"); - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Site); - - if (SiteInfo.IsRoot) - { - PhParentId.Visible = false; - } - else - { - PhParentId.Visible = true; - - DdlParentId.Items.Add(new ListItem("<无上级站点>", "0")); - var siteIdList = SiteManager.GetSiteIdList(); - var mySystemInfoArrayList = new ArrayList(); - var parentWithChildren = new Hashtable(); - foreach (var siteId in siteIdList) - { - if (siteId == SiteId) continue; - var siteInfo = SiteManager.GetSiteInfo(siteId); - if (siteInfo.IsRoot == false) - { - if (siteInfo.ParentId == 0) - { - mySystemInfoArrayList.Add(siteInfo); - } - else - { - var children = new ArrayList(); - if (parentWithChildren.Contains(siteInfo.ParentId)) - { - children = (ArrayList)parentWithChildren[siteInfo.ParentId]; - } - children.Add(siteInfo); - parentWithChildren[siteInfo.ParentId] = children; - } - } - } - foreach (SiteInfo siteInfo in mySystemInfoArrayList) - { - AddSite(DdlParentId, siteInfo, parentWithChildren, 0); - } - ControlUtils.SelectSingleItem(DdlParentId, SiteInfo.ParentId.ToString()); - } - - var tableList = DataProvider.TableDao.GetTableCollectionInfoListCreatedInDb(); - foreach (var tableInfo in tableList) - { - if (tableInfo.DisplayName.StartsWith("插件内容表:")) continue; - - var li = new ListItem($"{tableInfo.DisplayName}({tableInfo.TableName})", tableInfo.TableName); - DdlTableName.Items.Add(li); - } - - TbTaxis.Text = SiteInfo.Taxis.ToString(); - - RblIsCheckContentUseLevel.Items.Add(new ListItem("默认审核机制",false.ToString())); - RblIsCheckContentUseLevel.Items.Add(new ListItem("多级审核机制", true.ToString())); - - if (SiteInfo == null) - { - PageUtils.RedirectToErrorPage("站点不存在,请确认后再试!"); - return; - } - TbSiteName.Text = SiteInfo.SiteName; - ControlUtils.SelectSingleItem(RblIsCheckContentUseLevel, SiteInfo.Additional.IsCheckContentLevel.ToString()); - if (SiteInfo.Additional.IsCheckContentLevel) - { - ControlUtils.SelectSingleItem(DdlCheckContentLevel, SiteInfo.Additional.CheckContentLevel.ToString()); - PhCheckContentLevel.Visible = true; - } - else - { - PhCheckContentLevel.Visible = false; - } - if (!string.IsNullOrEmpty(SiteInfo.SiteDir)) - { - TbSiteDir.Text = PathUtils.GetDirectoryName(SiteInfo.SiteDir, false); - } - if (SiteInfo.IsRoot) - { - PhSiteDir.Visible = false; - } - foreach (ListItem item in DdlTableName.Items) - { - item.Selected = item.Value.Equals(SiteInfo.TableName); - } - - BtnSubmit.Attributes.Add("onclick", GetShowHintScript()); - } - - private static void AddSite(ListControl listControl, SiteInfo siteInfo, Hashtable parentWithChildren, int level) - { - var padding = string.Empty; - for (var i = 0; i < level; i++) - { - padding += " "; - } - if (level > 0) - { - padding += "└ "; - } - - if (parentWithChildren[siteInfo.Id] != null) - { - var children = (ArrayList)parentWithChildren[siteInfo.Id]; - listControl.Items.Add(new ListItem(padding + siteInfo.SiteName + - $"({children.Count})", siteInfo.Id.ToString())); - level++; - foreach (SiteInfo subSiteInfo in children) - { - AddSite(listControl, subSiteInfo, parentWithChildren, level); - } - } - else - { - listControl.Items.Add(new ListItem(padding + siteInfo.SiteName, siteInfo.Id.ToString())); - } - } - - public void RblIsCheckContentUseLevel_OnSelectedIndexChanged(object sender, EventArgs e) - { - PhCheckContentLevel.Visible = EBooleanUtils.Equals(RblIsCheckContentUseLevel.SelectedValue, EBoolean.True); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - SiteInfo.SiteName = TbSiteName.Text; - SiteInfo.Taxis = TranslateUtils.ToInt(TbTaxis.Text); - SiteInfo.Additional.IsCheckContentLevel = TranslateUtils.ToBool(RblIsCheckContentUseLevel.SelectedValue); - if (SiteInfo.Additional.IsCheckContentLevel) - { - SiteInfo.Additional.CheckContentLevel = TranslateUtils.ToInt(DdlCheckContentLevel.SelectedValue); - } - - var isTableChanged = false; - - if (SiteInfo.TableName != DdlTableName.SelectedValue) - { - isTableChanged = true; - SiteInfo.TableName = DdlTableName.SelectedValue; - } - - if (SiteInfo.IsRoot == false) - { - if (!StringUtils.EqualsIgnoreCase(PathUtils.GetDirectoryName(SiteInfo.SiteDir, false), TbSiteDir.Text)) - { - var list = DataProvider.SiteDao.GetLowerSiteDirList(SiteInfo.ParentId); - if (list.IndexOf(TbSiteDir.Text.ToLower()) != -1) - { - FailMessage("站点修改失败,已存在相同的发布路径!"); - return; - } - - var parentPsPath = WebConfigUtils.PhysicalApplicationPath; - if (SiteInfo.ParentId > 0) - { - var parentSiteInfo = SiteManager.GetSiteInfo(SiteInfo.ParentId); - parentPsPath = PathUtility.GetSitePath(parentSiteInfo); - } - DirectoryUtility.ChangeSiteDir(parentPsPath, SiteInfo.SiteDir, TbSiteDir.Text); - } - - if (PhParentId.Visible && SiteInfo.ParentId != TranslateUtils.ToInt(DdlParentId.SelectedValue)) - { - var newParentId = TranslateUtils.ToInt(DdlParentId.SelectedValue); - var list = DataProvider.SiteDao.GetLowerSiteDirList(newParentId); - if (list.IndexOf(TbSiteDir.Text.ToLower()) != -1) - { - FailMessage("站点修改失败,已存在相同的发布路径!"); - return; - } - - DirectoryUtility.ChangeParentSite(SiteInfo.ParentId, TranslateUtils.ToInt(DdlParentId.SelectedValue), SiteId, TbSiteDir.Text); - SiteInfo.ParentId = newParentId; - } - - SiteInfo.SiteDir = TbSiteDir.Text; - } - - DataProvider.SiteDao.Update(SiteInfo); - if (isTableChanged) - { - DataProvider.ChannelDao.UpdateContentNum(SiteInfo); - } - - AuthRequest.AddAdminLog("修改站点属性", $"站点:{SiteInfo.SiteName}"); - - SuccessMessage("站点修改成功!"); - AddWaitAndRedirectScript(PageSite.GetRedirectUrl()); - } - - public void Return_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(PageSite.GetRedirectUrl()); - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageSiteReplace.cs b/SiteServer.BackgroundPages/Settings/PageSiteReplace.cs deleted file mode 100644 index a6914fd88..000000000 --- a/SiteServer.BackgroundPages/Settings/PageSiteReplace.cs +++ /dev/null @@ -1,145 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.IO; -using System.Web.UI.HtmlControls; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Cms; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageSiteReplace : BasePageCms - { - public Literal LtlSiteName; - public PlaceHolder PhChooseSiteTemplate; - public Repeater RptContents; - public HtmlInputHidden HihSiteTemplateDir; - - public PlaceHolder PhCreateSiteParameters; - public Literal LtlSiteTemplateName; - public RadioButtonList RblIsDeleteChannels; - public RadioButtonList RblIsDeleteTemplates; - public RadioButtonList RblIsDeleteFiles; - public RadioButtonList RblIsOverride; - - public Button BtnNext; - public Button BtnSubmit; - - private SortedList _sortedlist = new SortedList(); - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetSettingsUrl(nameof(PageSiteReplace), new NameValueCollection - { - {"siteId", siteId.ToString()} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - _sortedlist = SiteTemplateManager.Instance.GetSiteTemplateSortedList(); - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Site); - - LtlSiteName.Text = SiteInfo.SiteName; - - var directoryList = new List(); - foreach (string directoryName in _sortedlist.Keys) - { - var directoryPath = PathUtility.GetSiteTemplatesPath(directoryName); - var dirInfo = new DirectoryInfo(directoryPath); - directoryList.Add(dirInfo); - } - - RptContents.DataSource = directoryList; - RptContents.ItemDataBound += RptContents_ItemDataBound; - RptContents.DataBind(); - - if (SiteTemplateManager.Instance.GetSiteTemplateCount() == 0) - { - PageUtils.RedirectToErrorPage("无站点模板!"); - } - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.AlternatingItem && e.Item.ItemType != ListItemType.Item) return; - - var directoryInfo = (DirectoryInfo)e.Item.DataItem; - var siteTemplateInfo = _sortedlist[directoryInfo.Name] as SiteTemplateInfo; - - if (siteTemplateInfo == null) return; - - var ltlChoose = (Literal)e.Item.FindControl("ltlChoose"); - var ltlTemplateName = (Literal)e.Item.FindControl("ltlTemplateName"); - var ltlName = (Literal)e.Item.FindControl("ltlName"); - var ltlDescription = (Literal)e.Item.FindControl("ltlDescription"); - var ltlSamplePic = (Literal)e.Item.FindControl("ltlSamplePic"); - - ltlChoose.Text = $@""; - - if (!string.IsNullOrEmpty(siteTemplateInfo.SiteTemplateName)) - { - ltlTemplateName.Text = !string.IsNullOrEmpty(siteTemplateInfo.WebSiteUrl) ? $"{siteTemplateInfo.SiteTemplateName}" : siteTemplateInfo.SiteTemplateName; - } - - ltlName.Text = directoryInfo.Name; - - if (!string.IsNullOrEmpty(siteTemplateInfo.Description)) - { - ltlDescription.Text = siteTemplateInfo.Description; - } - - if (!string.IsNullOrEmpty(siteTemplateInfo.PicFileName)) - { - var siteTemplateUrl = PageUtils.GetSiteTemplatesUrl(directoryInfo.Name); - var picFileName = PageUtils.GetSiteTemplateMetadataUrl(siteTemplateUrl, siteTemplateInfo.PicFileName); - ltlSamplePic.Text = $@"样图"; - } - } - - public void BtnNext_Click(object sender, EventArgs e) - { - var siteTemplateDir = HihSiteTemplateDir.Value; - var siteTemplateInfo = _sortedlist[siteTemplateDir] as SiteTemplateInfo; - - if (siteTemplateInfo == null) - { - FailMessage("请选择需要替换的站点模板"); - return; - } - - LtlSiteTemplateName.Text = !string.IsNullOrEmpty(siteTemplateInfo.WebSiteUrl) ? $"{siteTemplateInfo.SiteTemplateName}" : siteTemplateInfo.SiteTemplateName; - - PhChooseSiteTemplate.Visible = false; - PhCreateSiteParameters.Visible = true; - BtnNext.Visible = false; - BtnSubmit.Visible = true; - } - - public void BtnSubmit_Click(object sender, EventArgs e) - { - var siteTemplateDir = HihSiteTemplateDir.Value; - - var userKeyPrefix = StringUtils.Guid(); - var siteTemplatePath = PathUtility.GetSiteTemplatesPath(siteTemplateDir); - - AuthRequest.AddAdminLog("整站替换", $"站点:{SiteInfo.SiteName}"); - - PageUtils.Redirect(PageProgressBar.GetRecoveryUrl(SiteId, RblIsDeleteChannels.SelectedValue, RblIsDeleteTemplates.SelectedValue, RblIsDeleteFiles.SelectedValue, false, siteTemplatePath, RblIsOverride.SelectedValue, RblIsOverride.SelectedValue, userKeyPrefix)); - } - - public void Return_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(PageSite.GetRedirectUrl()); - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageSiteTableMetadata.cs b/SiteServer.BackgroundPages/Settings/PageSiteTableMetadata.cs deleted file mode 100644 index 74449ac01..000000000 --- a/SiteServer.BackgroundPages/Settings/PageSiteTableMetadata.cs +++ /dev/null @@ -1,315 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageSiteTableMetadata : BasePageCms - { - public Repeater RptContents; - public PlaceHolder PhSyncTable; - public PlaceHolder PhSqlString; - public Literal LtlSqlString; - public Button BtnAdd; - public Button BtnCreateDb; - public Button BtnDelete; - public Button BtnReCreateDb; - public Button BtnSqlString; - - private bool _showSqlTable = true; - private string _tableName; - private bool _tableIsRealCreated; - private bool _isTableUsed; - private string _redirectUrl; - - public static string GetRedirectUrl(string tableName) - { - return PageUtils.GetSettingsUrl(nameof(PageSiteTableMetadata), new NameValueCollection - { - {"ENName", tableName} - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - PageUtils.CheckRequestParameter("ENName"); - _showSqlTable = AuthRequest.IsQueryExists("ShowCrateDBCommand"); - - _tableName = AuthRequest.GetQueryString("ENName").Trim(); - _redirectUrl = GetRedirectUrl(_tableName); - - var tableInfo = DataProvider.TableDao.GetTableCollectionInfo(_tableName); - - if (AuthRequest.IsQueryExists("Delete")) - { - var tableMetadataId = AuthRequest.GetQueryInt("TableMetadataID"); - - try - { - var tableMetadataInfo = DataProvider.TableMetadataDao.GetTableMetadataInfo(tableMetadataId); - DataProvider.TableMetadataDao.Delete(tableMetadataId); - - AuthRequest.AddAdminLog("删除辅助表字段", $"辅助表:{_tableName},字段名:{tableMetadataInfo.AttributeName}"); - - SuccessDeleteMessage(); - PageUtils.Redirect(_redirectUrl); - } - catch (Exception ex) - { - FailDeleteMessage(ex); - } - } - else if (AuthRequest.IsQueryExists("DeleteStyle"))//删除样式 - { - var attributeName = AuthRequest.GetQueryString("AttributeName"); - if (TableStyleManager.IsExists(0, _tableName, attributeName)) - { - try - { - TableStyleManager.Delete(0, _tableName, attributeName); - - AuthRequest.AddAdminLog("删除辅助表字段样式", $"辅助表:{_tableName},字段名:{attributeName}"); - - SuccessDeleteMessage(); - PageUtils.Redirect(_redirectUrl); - } - catch (Exception ex) - { - FailDeleteMessage(ex); - } - } - } - else if (AuthRequest.IsQueryExists("CreateDB")) - { - try - { - DataProvider.TableDao.CreateDbTable(_tableName); - tableInfo.IsChangedAfterCreatedInDb = false; - - AuthRequest.AddAdminLog("创建辅助表", $"辅助表:{_tableName}"); - - SuccessMessage("辅助表创建成功!"); - PageUtils.Redirect(_redirectUrl); - } - catch (Exception ex) - { - FailMessage(ex, "
    辅助表创建失败,失败原因为:" + ex.Message + "
    请检查创建表SQL命令"); - var sqlString = DataProvider.ContentDao.GetCreateTableCollectionInfoSqlString(_tableName); - LtlSqlString.Text = sqlString.Replace("\r\n", "
    ").Replace("\t", "    "); - _showSqlTable = true; - } - } - else if (AuthRequest.IsQueryExists("DeleteDB")) - { - try - { - DataProvider.TableDao.DeleteDbTable(_tableName); - tableInfo.IsChangedAfterCreatedInDb = false; - - AuthRequest.AddAdminLog("删除辅助表", $"辅助表:{_tableName}"); - - SuccessMessage("辅助表删除成功!"); - PageUtils.Redirect(_redirectUrl); - } - catch (Exception ex) - { - - FailMessage(ex, "
    辅助表删除失败,失败原因为:" + ex.Message + "
    "); - } - } - else if (AuthRequest.IsQueryExists("ReCreateDB")) - { - try - { - DataProvider.TableDao.ReCreateDbTable(_tableName); - DataProvider.ChannelDao.UpdateContentNumToZero(_tableName); - tableInfo.IsChangedAfterCreatedInDb = false; - - AuthRequest.AddAdminLog("重建辅助表", $"辅助表:{_tableName}"); - - SuccessMessage("辅助表重建成功!"); - PageUtils.Redirect(_redirectUrl); - } - catch (Exception ex) - { - - FailMessage(ex, "
    辅助表重建失败,失败原因为:" + ex.Message + "
    请检查创建表SQL命令"); - var sqlString = DataProvider.ContentDao.GetCreateTableCollectionInfoSqlString(_tableName); - LtlSqlString.Text = sqlString.Replace("\r\n", "
    ").Replace("\t", "    "); - _showSqlTable = true; - } - } - else if (AuthRequest.IsQueryExists("ShowCrateDBCommand")) - { - var sqlString = DataProvider.ContentDao.GetCreateTableCollectionInfoSqlString(_tableName); - LtlSqlString.Text = sqlString.Replace("\r\n", "
    ").Replace("\t", "    "); - } - else if (AuthRequest.IsQueryExists("SetTaxis")) - { - var direction = AuthRequest.GetQueryString("Direction"); - var tableMetadataId = AuthRequest.GetQueryInt("TableMetadataId"); - switch (direction.ToUpper()) - { - case "UP": - DataProvider.TableMetadataDao.TaxisDown(tableMetadataId, _tableName); - break; - case "DOWN": - DataProvider.TableMetadataDao.TaxisUp(tableMetadataId, _tableName); - break; - } - SuccessMessage("排序成功!"); - } - - _tableIsRealCreated = DataProvider.DatabaseDao.IsTableExists(_tableName); - - _isTableUsed = DataProvider.SiteDao.IsTableUsed(_tableName); - - PhSyncTable.Visible = _tableIsRealCreated && tableInfo.IsChangedAfterCreatedInDb; - PhSqlString.Visible = _showSqlTable; - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Site); - - RptContents.DataSource = DataProvider.TableMetadataDao.GetDataSource(_tableName); - RptContents.ItemDataBound += RptContents_ItemDataBound; - RptContents.DataBind(); - - BtnAdd.Attributes.Add("onclick", ModalTableMetadataAdd.GetOpenWindowStringToAdd(_tableName)); - - var redirectUrl = GetRedirectUrl(_tableName); - - bool isBtnCreateDb; - if (string.IsNullOrEmpty(_tableName)) - { - isBtnCreateDb = false; - } - else - { - isBtnCreateDb = !_tableIsRealCreated; - } - if (isBtnCreateDb) - { - BtnCreateDb.Attributes.Add("onclick", $"location.href='{redirectUrl}&CreateDB={true}';return false;"); - } - else - { - BtnCreateDb.Visible = false; - } - - bool isBtnDelete; - if (_tableName == null) - { - isBtnDelete = false; - } - else - { - isBtnDelete = !_isTableUsed; - } - if (isBtnDelete) - { - BtnDelete.Attributes.Add("onclick", $"if (confirm('此操作将删除辅助表“{_tableName}”,确认吗?'))location.href='{redirectUrl}&DeleteDB={true}';return false;"); - } - else - { - BtnDelete.Visible = false; - } - - if (isBtnCreateDb) - { - BtnReCreateDb.Attributes.Add("onclick", $"if (confirm('此操作将覆盖已建立的辅助表,表中已存数据将丢失,确认吗?'))location.href='{redirectUrl}&ReCreateDB={true}';return false;"); - } - else - { - BtnReCreateDb.Visible = false; - } - - var isSqlString = !string.IsNullOrEmpty(_tableName); - if (isSqlString) - { - BtnSqlString.Attributes.Add("onclick", $"location.href='{redirectUrl}&ShowCrateDBCommand={true}';return false;"); - } - else - { - BtnSqlString.Visible = false; - } - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var tableMetadataId = SqlUtils.EvalInt(e.Item.DataItem, nameof(TableMetadataInfo.Id)); - var attributeName = SqlUtils.EvalString(e.Item.DataItem, nameof(TableMetadataInfo.AttributeName)); - var dataType = SqlUtils.EvalString(e.Item.DataItem, nameof(TableMetadataInfo.DataType)); - var isSystem = SqlUtils.EvalString(e.Item.DataItem, nameof(TableMetadataInfo.IsSystem)); - - var ltlAttributeName = (Literal)e.Item.FindControl("ltlAttributeName"); - var ltlDataType = (Literal)e.Item.FindControl("ltlDataType"); - var hlUp = (HyperLink)e.Item.FindControl("hlUp"); - var hlDown = (HyperLink)e.Item.FindControl("hlDown"); - var ltlEditUrl = (Literal)e.Item.FindControl("ltlEditUrl"); - var ltlDeleteUrl = (Literal)e.Item.FindControl("ltlDeleteUrl"); - - ltlAttributeName.Text = attributeName; - - ltlDataType.Text = DataTypeUtils.GetText(DataTypeUtils.GetEnumType(dataType)); - - if (TranslateUtils.ToBool(isSystem)) - { - hlUp.Visible = hlDown.Visible = false; - return; - } - - hlUp.NavigateUrl = PageUtils.GetSettingsUrl(nameof(PageSiteTableMetadata), - new NameValueCollection - { - {"SiteId", SiteId.ToString()}, - {"SetTaxis", "True"}, - {"Direction", "UP"}, - {"TableMetadataId", tableMetadataId.ToString()}, - {"ENName", _tableName} - }); - - hlDown.NavigateUrl = PageUtils.GetSettingsUrl(nameof(PageSiteTableMetadata), - new NameValueCollection - { - {"SiteId", SiteId.ToString()}, - {"SetTaxis", "True"}, - {"Direction", "DOWN"}, - {"TableMetadataId", tableMetadataId.ToString()}, - {"ENName", _tableName} - }); - - ltlEditUrl.Text = - $@"修改字段"; - - ltlDeleteUrl.Text = - $@"删除字段"; - } - - public void SyncTableButton_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - DataProvider.TableDao.SyncDbTable(_tableName); - PhSyncTable.Visible = false; - SuccessMessage("同步辅助表成功!"); - PageUtils.Redirect(_redirectUrl); - } - - public void Return_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(PageSiteAuxiliaryTable.GetRedirectUrl()); - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageSiteUrlApi.cs b/SiteServer.BackgroundPages/Settings/PageSiteUrlApi.cs deleted file mode 100644 index 7ae24cc6b..000000000 --- a/SiteServer.BackgroundPages/Settings/PageSiteUrlApi.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageSiteUrlApi : BasePage - { - public RadioButtonList RblIsSeparatedApi; - public PlaceHolder PhSeparatedApi; - public TextBox TbSeparatedApiUrl; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Site); - - EBooleanUtils.AddListItems(RblIsSeparatedApi, "API独立部署", "API与CMS部署在一起"); - ControlUtils.SelectSingleItem(RblIsSeparatedApi, ConfigManager.SystemConfigInfo.IsSeparatedApi.ToString()); - PhSeparatedApi.Visible = ConfigManager.SystemConfigInfo.IsSeparatedApi; - TbSeparatedApiUrl.Text = ConfigManager.SystemConfigInfo.SeparatedApiUrl; - } - - public void RblIsSeparatedApi_SelectedIndexChanged(object sender, EventArgs e) - { - PhSeparatedApi.Visible = TranslateUtils.ToBool(RblIsSeparatedApi.SelectedValue); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - ConfigManager.SystemConfigInfo.IsSeparatedApi = TranslateUtils.ToBool(RblIsSeparatedApi.SelectedValue); - ConfigManager.SystemConfigInfo.SeparatedApiUrl = TbSeparatedApiUrl.Text; - - DataProvider.ConfigDao.Update(ConfigManager.Instance); - - AuthRequest.AddAdminLog("修改API访问地址"); - SuccessUpdateMessage(); - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageSiteUrlAssetsConfig.cs b/SiteServer.BackgroundPages/Settings/PageSiteUrlAssetsConfig.cs deleted file mode 100644 index f12f89901..000000000 --- a/SiteServer.BackgroundPages/Settings/PageSiteUrlAssetsConfig.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageSiteUrlAssetsConfig : BasePageCms - { - public Literal LtlSiteName; - - public RadioButtonList RblIsSeparatedAssets; - public PlaceHolder PhSeparatedAssets; - public TextBox TbSeparatedAssetsUrl; - public TextBox TbAssetsDir; - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetSettingsUrl(nameof(PageSiteUrlAssetsConfig), new NameValueCollection - { - { - "SiteId", siteId.ToString() - } - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Site); - - LtlSiteName.Text = SiteInfo.SiteName; - - EBooleanUtils.AddListItems(RblIsSeparatedAssets, "资源文件独立部署", "资源文件与Web部署在一起"); - ControlUtils.SelectSingleItem(RblIsSeparatedAssets, SiteInfo.Additional.IsSeparatedAssets.ToString()); - PhSeparatedAssets.Visible = SiteInfo.Additional.IsSeparatedAssets; - TbSeparatedAssetsUrl.Text = SiteInfo.Additional.SeparatedAssetsUrl; - TbAssetsDir.Text = SiteInfo.Additional.AssetsDir; - } - - public void RblIsSeparatedAssets_SelectedIndexChanged(object sender, EventArgs e) - { - PhSeparatedAssets.Visible = TranslateUtils.ToBool(RblIsSeparatedAssets.SelectedValue); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - SiteInfo.Additional.IsSeparatedAssets = TranslateUtils.ToBool(RblIsSeparatedAssets.SelectedValue); - SiteInfo.Additional.SeparatedAssetsUrl = TbSeparatedAssetsUrl.Text; - SiteInfo.Additional.AssetsDir = TbAssetsDir.Text; - - DataProvider.SiteDao.Update(SiteInfo); - AuthRequest.AddSiteLog(SiteId, "修改资源文件访问地址"); - - SuccessMessage("资源文件访问地址修改成功!"); - AddWaitAndRedirectScript(PageSiteUrlAssets.GetRedirectUrl()); - } - - public void Return_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(PageSiteUrlAssets.GetRedirectUrl()); - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageSiteUrlWebConfig.cs b/SiteServer.BackgroundPages/Settings/PageSiteUrlWebConfig.cs deleted file mode 100644 index 0e40cf254..000000000 --- a/SiteServer.BackgroundPages/Settings/PageSiteUrlWebConfig.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageSiteUrlWebConfig : BasePageCms - { - public Literal LtlSiteName; - - public RadioButtonList RblIsSeparatedWeb; - public PlaceHolder PhSeparatedWeb; - public TextBox TbSeparatedWebUrl; - - public static string GetRedirectUrl(int siteId) - { - return PageUtils.GetSettingsUrl(nameof(PageSiteUrlWebConfig), new NameValueCollection - { - { - "SiteId", siteId.ToString() - } - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Site); - - LtlSiteName.Text = SiteInfo.SiteName; - - EBooleanUtils.AddListItems(RblIsSeparatedWeb, "Web独立部署", "Web与CMS部署在一起"); - ControlUtils.SelectSingleItem(RblIsSeparatedWeb, SiteInfo.Additional.IsSeparatedWeb.ToString()); - PhSeparatedWeb.Visible = SiteInfo.Additional.IsSeparatedWeb; - TbSeparatedWebUrl.Text = SiteInfo.Additional.SeparatedWebUrl; - } - - public void RblIsSeparatedWeb_SelectedIndexChanged(object sender, EventArgs e) - { - PhSeparatedWeb.Visible = TranslateUtils.ToBool(RblIsSeparatedWeb.SelectedValue); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - SiteInfo.Additional.IsSeparatedWeb = TranslateUtils.ToBool(RblIsSeparatedWeb.SelectedValue); - SiteInfo.Additional.SeparatedWebUrl = TbSeparatedWebUrl.Text; - - DataProvider.SiteDao.Update(SiteInfo); - AuthRequest.AddSiteLog(SiteId, "修改Web访问地址"); - - SuccessMessage("Web访问地址修改成功!"); - AddWaitAndRedirectScript(PageSiteUrlWeb.GetRedirectUrl()); - } - - public void Return_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(PageSiteUrlWeb.GetRedirectUrl()); - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageUser.cs b/SiteServer.BackgroundPages/Settings/PageUser.cs deleted file mode 100644 index fe78d720c..000000000 --- a/SiteServer.BackgroundPages/Settings/PageUser.cs +++ /dev/null @@ -1,261 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageUser : BasePage - { - public DropDownList DdlPageNum; - public DropDownList DdlLoginCount; - - public DropDownList DdlSearchType; - public TextBox TbKeyword; - public DropDownList DdlCreationDate; - public DropDownList DdlLastActivityDate; - - public Repeater RptContents; - public SqlPager SpContents; - - public Button BtnAdd; - public Button BtnLock; - public Button BtnUnLock; - public Button BtnDelete; - public Button BtnExport; - - private EUserLockType _lockType = EUserLockType.Forever; - - public static string GetRedirectUrl() - { - return PageUtils.GetSettingsUrl(nameof(PageUser), null); - } - - public string GetDateTime(DateTime datetime) - { - var retval = string.Empty; - if (datetime > DateUtils.SqlMinValue) - { - retval = DateUtils.GetDateString(datetime); - } - return retval; - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (AuthRequest.IsQueryExists("Delete")) - { - var userIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("UserIDCollection")); - try - { - foreach (var userId in userIdList) - { - DataProvider.UserDao.Delete(userId); - } - - AuthRequest.AddAdminLog("删除用户", string.Empty); - - SuccessDeleteMessage(); - } - catch (Exception ex) - { - FailDeleteMessage(ex); - } - } - else if (AuthRequest.IsQueryExists("Lock")) - { - var userIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("UserIDCollection")); - try - { - DataProvider.UserDao.Lock(userIdList); - - AuthRequest.AddAdminLog("锁定用户", string.Empty); - - SuccessMessage("成功锁定所选会员!"); - } - catch (Exception ex) - { - FailMessage(ex, "锁定所选会员失败!"); - } - } - else if (AuthRequest.IsQueryExists("UnLock")) - { - var userIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("UserIDCollection")); - try - { - DataProvider.UserDao.UnLock(userIdList); - - AuthRequest.AddAdminLog("解除锁定用户", string.Empty); - - SuccessMessage("成功解除锁定所选会员!"); - } - catch (Exception ex) - { - FailMessage(ex, "解除锁定所选会员失败!"); - } - } - - SpContents.ControlToPaginate = RptContents; - - if (string.IsNullOrEmpty(AuthRequest.GetQueryString("PageNum"))) - { - SpContents.ItemsPerPage = TranslateUtils.ToInt(DdlPageNum.SelectedValue) == 0 ? 25 : TranslateUtils.ToInt(DdlPageNum.SelectedValue); - - SpContents.SelectCommand = DataProvider.UserDao.GetSelectCommand(true); - } - else - { - SpContents.ItemsPerPage = AuthRequest.GetQueryInt("PageNum") == 0 ? StringUtils.Constants.PageSize : AuthRequest.GetQueryInt("PageNum"); - SpContents.SelectCommand = DataProvider.UserDao.GetSelectCommand(AuthRequest.GetQueryString("Keyword"), AuthRequest.GetQueryInt("CreationDate"), AuthRequest.GetQueryInt("LastActivityDate"), true, AuthRequest.GetQueryInt("LoginCount"), AuthRequest.GetQueryString("SearchType")); - } - - RptContents.ItemDataBound += rptContents_ItemDataBound; - SpContents.SortField = DataProvider.UserDao.GetSortFieldName(); - SpContents.SortMode = SortMode.DESC; - - _lockType = EUserLockTypeUtils.GetEnumType(ConfigManager.SystemConfigInfo.UserLockLoginType); - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.User); - - //添加隐藏属性 - DdlSearchType.Items.Add(new ListItem("用户ID", "userID")); - DdlSearchType.Items.Add(new ListItem("用户名", "userName")); - DdlSearchType.Items.Add(new ListItem("邮箱", "email")); - DdlSearchType.Items.Add(new ListItem("手机", "mobile")); - - //默认选择用户名 - DdlSearchType.SelectedValue = "userName"; - - if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("SearchType"))) - { - ControlUtils.SelectSingleItem(DdlSearchType, AuthRequest.GetQueryString("SearchType")); - } - if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("PageNum"))) - { - ControlUtils.SelectSingleItem(DdlPageNum, AuthRequest.GetQueryString("PageNum")); - } - if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("LoginCount"))) - { - ControlUtils.SelectSingleItem(DdlLoginCount, AuthRequest.GetQueryString("LoginCount")); - } - if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("Keyword"))) - { - TbKeyword.Text = AuthRequest.GetQueryString("Keyword"); - } - if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("CreationDate"))) - { - ControlUtils.SelectSingleItem(DdlCreationDate, AuthRequest.GetQueryString("CreationDate")); - } - if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("LastActivityDate"))) - { - ControlUtils.SelectSingleItem(DdlLastActivityDate, AuthRequest.GetQueryString("LastActivityDate")); - } - - var backgroundUrl = GetRedirectUrl(); - - BtnAdd.Attributes.Add("onclick", - $"location.href='{PageUserAdd.GetRedirectUrlToAdd(PageUrl)}';return false;"); - - BtnLock.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert( - $"{backgroundUrl}?Lock=True", "UserIDCollection", "UserIDCollection", "请选择需要锁定的会员!", "此操作将锁定所选会员,确认吗?")); - - BtnUnLock.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert( - $"{backgroundUrl}?UnLock=True", "UserIDCollection", "UserIDCollection", "请选择需要解除锁定的会员!", "此操作将解除锁定所选会员,确认吗?")); - - BtnDelete.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert( - $"{backgroundUrl}?Delete=True", "UserIDCollection", "UserIDCollection", "请选择需要删除的会员!", "此操作将删除所选会员,确认吗?")); - - BtnExport.Attributes.Add("onclick", ModalUserExport.GetOpenWindowString()); - - SpContents.DataBind(); - } - - public void rptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var userInfo = new UserInfo(e.Item.DataItem); - - var ltlUserName = (Literal)e.Item.FindControl("ltlUserName"); - var ltlDisplayName = (Literal)e.Item.FindControl("ltlDisplayName"); - var ltlEmail = (Literal)e.Item.FindControl("ltlEmail"); - var ltlMobile = (Literal)e.Item.FindControl("ltlMobile"); - var ltlLastActivityDate = (Literal)e.Item.FindControl("ltlLastActivityDate"); - var ltlLoginCount = (Literal)e.Item.FindControl("ltlLoginCount"); - var ltlCreationDate = (Literal)e.Item.FindControl("ltlCreationDate"); - var ltlWritingCount = (Literal)e.Item.FindControl("ltlWritingCount"); - var ltlSelect = (Literal)e.Item.FindControl("ltlSelect"); - var hlChangePassword = (HyperLink)e.Item.FindControl("hlChangePassword"); - var hlEditLink = (HyperLink)e.Item.FindControl("hlEditLink"); - - ltlUserName.Text = GetUserNameHtml(userInfo); - ltlDisplayName.Text = userInfo.DisplayName; - ltlEmail.Text = userInfo.Email; - ltlMobile.Text = userInfo.Mobile; - ltlLastActivityDate.Text = DateUtils.GetDateAndTimeString(userInfo.LastActivityDate); - ltlLoginCount.Text = userInfo.CountOfLogin.ToString(); - ltlCreationDate.Text = DateUtils.GetDateAndTimeString(userInfo.CreateDate); - - hlEditLink.NavigateUrl = PageUserAdd.GetRedirectUrlToEdit(userInfo.Id, GetRedirectUrl()); - hlChangePassword.Attributes.Add("onclick", ModalUserPassword.GetOpenWindowString(userInfo.UserName)); - ltlSelect.Text = $@""; - - ltlWritingCount.Text = userInfo.CountOfWriting.ToString(); - } - - private string GetUserNameHtml(UserInfo userInfo) - { - var showPopWinString = ModalUserView.GetOpenWindowString(userInfo.UserName); - var state = string.Empty; - if (userInfo.IsLockedOut) - { - state = @"[已被锁定]"; - } - else if (ConfigManager.SystemConfigInfo.IsUserLockLogin && - ConfigManager.SystemConfigInfo.UserLockLoginCount <= userInfo.CountOfFailedLogin) - { - if (_lockType == EUserLockType.Forever) - { - state = @"[已被锁定]"; - } - else - { - var ts = new TimeSpan(DateTime.Now.Ticks - userInfo.LastActivityDate.Ticks); - var hours = Convert.ToInt32(ConfigManager.SystemConfigInfo.UserLockLoginHours - ts.TotalHours); - if (hours > 0) - { - state = $@"[错误登录次数过多,已被锁定{hours}小时]"; - } - } - } - return $@"{userInfo.UserName} {state}"; - } - - public void Search_OnClick(object sender, EventArgs e) - { - PageUtils.Redirect(PageUrl); - } - - private string _pageUrl; - private string PageUrl - { - get - { - if (string.IsNullOrEmpty(_pageUrl)) - { - _pageUrl = - $"{GetRedirectUrl()}?PageNum={DdlPageNum.SelectedValue}&Keyword={TbKeyword.Text}&CreationDate={DdlCreationDate.SelectedValue}&LastActivityDate={DdlLastActivityDate.SelectedValue}&loginCount={DdlLoginCount.SelectedValue}&SearchType={DdlSearchType.SelectedValue}"; - } - return _pageUrl; - } - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageUserAdd.cs b/SiteServer.BackgroundPages/Settings/PageUserAdd.cs deleted file mode 100644 index 081e35ff9..000000000 --- a/SiteServer.BackgroundPages/Settings/PageUserAdd.cs +++ /dev/null @@ -1,138 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageUserAdd : BasePage - { - public Literal LtlPageTitle; - public TextBox TbUserName; - public TextBox TbDisplayName; - public PlaceHolder PhPassword; - public TextBox TbPassword; - public Literal LtlPasswordTips; - public TextBox TbEmail; - public TextBox TbMobile; - public Button BtnReturn; - - private int _userId; - private string _returnUrl; - - public static string GetRedirectUrlToAdd(string returnUrl) - { - return PageUtils.GetSettingsUrl(nameof(PageUserAdd), new NameValueCollection - { - {"returnUrl", StringUtils.ValueToUrl(returnUrl) } - }); - } - - public static string GetRedirectUrlToEdit(int userId, string returnUrl) - { - return PageUtils.GetSettingsUrl(nameof(PageUserAdd), new NameValueCollection - { - {"userID", userId.ToString() }, - {"returnUrl", StringUtils.ValueToUrl(returnUrl) } - }); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - _userId = AuthRequest.GetQueryInt("userID"); - _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("returnUrl")); - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.User); - - LtlPageTitle.Text = _userId == 0 ? "添加用户" : "编辑用户"; - - if (_userId > 0) - { - var userInfo = DataProvider.UserDao.GetUserInfo(_userId); - if (userInfo != null) - { - TbUserName.Text = userInfo.UserName; - TbUserName.Enabled = false; - TbDisplayName.Text = userInfo.DisplayName; - PhPassword.Visible = false; - TbEmail.Text = userInfo.Email; - TbMobile.Text = userInfo.Mobile; - } - } - - if (!EUserPasswordRestrictionUtils.Equals(ConfigManager.SystemConfigInfo.UserPasswordRestriction, EUserPasswordRestriction.None)) - { - LtlPasswordTips.Text = $"请包含{EUserPasswordRestrictionUtils.GetText(EUserPasswordRestrictionUtils.GetEnumType(ConfigManager.SystemConfigInfo.UserPasswordRestriction))}"; - } - - if (!string.IsNullOrEmpty(_returnUrl)) - { - BtnReturn.Attributes.Add("onclick", $"window.location.href='{_returnUrl}';return false;"); - } - else - { - BtnReturn.Visible = false; - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - if (_userId == 0) - { - var userInfo = new UserInfo - { - UserName = TbUserName.Text, - Password = TbPassword.Text, - CreateDate = DateTime.Now, - LastActivityDate = DateUtils.SqlMinValue, - IsChecked = true, - IsLockedOut = false, - DisplayName = TbDisplayName.Text, - Email = TbEmail.Text, - Mobile = TbMobile.Text - }; - - string errorMessage; - var isCreated = DataProvider.UserDao.Insert(userInfo, userInfo.Password, string.Empty, out errorMessage); - - if (isCreated) - { - AuthRequest.AddAdminLog("添加用户", - $"用户:{TbUserName.Text}"); - - SuccessMessage("用户添加成功,可以继续添加!"); - AddWaitAndRedirectScript(GetRedirectUrlToAdd(_returnUrl)); - } - else - { - FailMessage($"用户添加失败:
    {errorMessage}"); - } - } - else - { - var userInfo = DataProvider.UserDao.GetUserInfo(_userId); - - userInfo.DisplayName = TbDisplayName.Text; - userInfo.Email = TbEmail.Text; - userInfo.Mobile = TbMobile.Text; - - DataProvider.UserDao.Update(userInfo); - - AuthRequest.AddAdminLog("修改用户", - $"用户:{TbUserName.Text}"); - - SuccessMessage("用户修改成功!"); - AddWaitAndRedirectScript(_returnUrl); - } - } - } -} \ No newline at end of file diff --git a/SiteServer.BackgroundPages/Settings/PageUserCheck.cs b/SiteServer.BackgroundPages/Settings/PageUserCheck.cs deleted file mode 100644 index f87584215..000000000 --- a/SiteServer.BackgroundPages/Settings/PageUserCheck.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.BackgroundPages.Controls; -using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageUserCheck : BasePage - { - public Repeater RptContents; - public SqlPager SpContents; - - public Button BtnCheck; - public Button BtnDelete; - - public static string GetRedirectUrl() - { - return PageUtils.GetSettingsUrl(nameof(PageUserCheck), null); - } - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (AuthRequest.IsQueryExists("Delete")) - { - var userIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("UserIDCollection")); - foreach (var userId in userIdList) - { - DataProvider.UserDao.Delete(userId); - } - - AuthRequest.AddAdminLog("删除用户", string.Empty); - - SuccessDeleteMessage(); - } - else if (AuthRequest.IsQueryExists("Check")) - { - var userIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("UserIDCollection")); - DataProvider.UserDao.Check(userIdList); - - SuccessCheckMessage(); - } - - SpContents.ControlToPaginate = RptContents; - SpContents.ItemsPerPage = 25; - SpContents.SelectCommand = DataProvider.UserDao.GetSelectCommand(false); - RptContents.ItemDataBound += RptContents_ItemDataBound; - SpContents.SortField = DataProvider.UserDao.GetSortFieldName(); - SpContents.SortMode = SortMode.DESC; - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.User); - - SpContents.DataBind(); - - BtnCheck.Attributes.Add("onclick", - PageUtils.GetRedirectStringWithCheckBoxValueAndAlert( - PageUtils.GetSettingsUrl(nameof(PageUserCheck), new NameValueCollection - { - {"Check", "True"} - }), "UserIDCollection", "UserIDCollection", "请选择需要审核的会员!", "此操作将审核通过所选会员,确认吗?")); - - BtnDelete.Attributes.Add("onclick", - PageUtils.GetRedirectStringWithCheckBoxValueAndAlert( - PageUtils.GetSettingsUrl(nameof(PageUserCheck), new NameValueCollection - { - {"Delete", "True"} - }), "UserIDCollection", "UserIDCollection", "请选择需要删除的会员!", "此操作将删除所选会员,确认吗?")); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var userInfo = new UserInfo(e.Item.DataItem); - - var ltlUserName = (Literal)e.Item.FindControl("ltlUserName"); - var ltlDisplayName = (Literal)e.Item.FindControl("ltlDisplayName"); - var ltlCreateDate = (Literal)e.Item.FindControl("ltlCreateDate"); - var ltlSelect = (Literal)e.Item.FindControl("ltlSelect"); - var hlEditLink = (HyperLink)e.Item.FindControl("hlEditLink"); - - var state = string.Empty; - if (userInfo.IsLockedOut) - { - state = @"[已被锁定]"; - } - ltlUserName.Text = $@"{userInfo.UserName}{state}"; - - ltlDisplayName.Text = userInfo.DisplayName; - - ltlCreateDate.Text = DateUtils.GetDateAndTimeString(userInfo.CreateDate); - - var userAddUrl = PageUserAdd.GetRedirectUrlToEdit(userInfo.Id, GetRedirectUrl()); - hlEditLink.NavigateUrl = userAddUrl; - - ltlSelect.Text = $@""; - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageUserConfiguration.cs b/SiteServer.BackgroundPages/Settings/PageUserConfiguration.cs deleted file mode 100644 index 64ff1d68b..000000000 --- a/SiteServer.BackgroundPages/Settings/PageUserConfiguration.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageUserConfiguration : BasePage - { - public RadioButtonList RblIsRegisterAllowed; - public TextBox TbRegisterPasswordMinLength; - public DropDownList DdlRegisterPasswordRestriction; - public TextBox TbRegisterMinMinutesOfIpAddress; - - public RadioButtonList RblIsFailToLock; - public PlaceHolder PhFailToLock; - public DropDownList DdlLockType; - public TextBox TbLoginFailCount; - public PlaceHolder PhLockingTime; - public TextBox TbLockingTime; - public RadioButtonList RblIsFindPassword; - public PlaceHolder PhFindPassword; - public TextBox TbFindPasswordSmsTplId; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.User); - - EBooleanUtils.AddListItems(RblIsRegisterAllowed); - - TbRegisterPasswordMinLength.Text = ConfigManager.SystemConfigInfo.UserPasswordMinLength.ToString(); - - EUserPasswordRestrictionUtils.AddListItems(DdlRegisterPasswordRestriction); - ControlUtils.SelectSingleItemIgnoreCase(DdlRegisterPasswordRestriction, ConfigManager.SystemConfigInfo.UserPasswordRestriction); - - ControlUtils.SelectSingleItemIgnoreCase(RblIsRegisterAllowed, ConfigManager.SystemConfigInfo.IsUserRegistrationAllowed.ToString()); - - TbRegisterMinMinutesOfIpAddress.Text = ConfigManager.SystemConfigInfo.UserRegistrationMinMinutes.ToString(); - - EBooleanUtils.AddListItems(RblIsFailToLock, "是", "否"); - ControlUtils.SelectSingleItemIgnoreCase(RblIsFailToLock, ConfigManager.SystemConfigInfo.IsUserLockLogin.ToString()); - - PhFailToLock.Visible = ConfigManager.SystemConfigInfo.IsUserLockLogin; - - TbLoginFailCount.Text = ConfigManager.SystemConfigInfo.UserLockLoginCount.ToString(); - - DdlLockType.Items.Add(new ListItem("按小时锁定", EUserLockTypeUtils.GetValue(EUserLockType.Hours))); - DdlLockType.Items.Add(new ListItem("永久锁定", EUserLockTypeUtils.GetValue(EUserLockType.Forever))); - ControlUtils.SelectSingleItemIgnoreCase(DdlLockType, ConfigManager.SystemConfigInfo.UserLockLoginType); - TbLockingTime.Text = ConfigManager.SystemConfigInfo.UserLockLoginHours.ToString(); - - PhLockingTime.Visible = false; - PhLockingTime.Visible = EUserLockTypeUtils.Equals(ConfigManager.SystemConfigInfo.UserLockLoginType, EUserLockType.Hours); - - EBooleanUtils.AddListItems(RblIsFindPassword, "启用", "禁用"); - ControlUtils.SelectSingleItemIgnoreCase(RblIsFindPassword, ConfigManager.SystemConfigInfo.IsUserFindPassword.ToString()); - PhFindPassword.Visible = ConfigManager.SystemConfigInfo.IsUserFindPassword; - TbFindPasswordSmsTplId.Text = ConfigManager.SystemConfigInfo.UserFindPasswordSmsTplId; - } - - public void RblIsFailToLock_SelectedIndexChanged(object sender, EventArgs e) - { - PhFailToLock.Visible = TranslateUtils.ToBool(RblIsFailToLock.SelectedValue); - } - - public void DdlLockType_SelectedIndexChanged(object sender, EventArgs e) - { - PhLockingTime.Visible = !EUserLockTypeUtils.Equals(EUserLockType.Forever, DdlLockType.SelectedValue); - } - - public void RblIsFindPassword_SelectedIndexChanged(object sender, EventArgs e) - { - PhFindPassword.Visible = TranslateUtils.ToBool(RblIsFindPassword.SelectedValue); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - ConfigManager.SystemConfigInfo.IsUserRegistrationAllowed = TranslateUtils.ToBool(RblIsRegisterAllowed.SelectedValue); - ConfigManager.SystemConfigInfo.UserPasswordMinLength = TranslateUtils.ToInt(TbRegisterPasswordMinLength.Text); - ConfigManager.SystemConfigInfo.UserPasswordRestriction = DdlRegisterPasswordRestriction.SelectedValue; - ConfigManager.SystemConfigInfo.UserRegistrationMinMinutes = TranslateUtils.ToInt(TbRegisterMinMinutesOfIpAddress.Text); - - ConfigManager.SystemConfigInfo.IsUserLockLogin = TranslateUtils.ToBool(RblIsFailToLock.SelectedValue); - ConfigManager.SystemConfigInfo.UserLockLoginCount = TranslateUtils.ToInt(TbLoginFailCount.Text, 3); - ConfigManager.SystemConfigInfo.UserLockLoginType = DdlLockType.SelectedValue; - ConfigManager.SystemConfigInfo.UserLockLoginHours = TranslateUtils.ToInt(TbLockingTime.Text); - ConfigManager.SystemConfigInfo.IsUserFindPassword = TranslateUtils.ToBool(RblIsFindPassword.SelectedValue); - ConfigManager.SystemConfigInfo.UserFindPasswordSmsTplId = TbFindPasswordSmsTplId.Text; - - DataProvider.ConfigDao.Update(ConfigManager.Instance); - - AuthRequest.AddAdminLog("修改用户设置"); - - SuccessMessage("设置修改成功!"); - } - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageUtilityCache.cs b/SiteServer.BackgroundPages/Settings/PageUtilityCache.cs deleted file mode 100644 index d9be447d6..000000000 --- a/SiteServer.BackgroundPages/Settings/PageUtilityCache.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.Utils; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageUtilityCache : BasePage - { - public Literal LtlCount; - public Literal LtlPercentage; - public Repeater RptContents; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Utility); - - LtlCount.Text = CacheUtils.Count.ToString(); - - RptContents.DataSource = CacheUtils.AllKeys; - RptContents.ItemDataBound += RptContents_ItemDataBound; - RptContents.DataBind(); - } - - private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) - { - if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; - - var key = (string) e.Item.DataItem; - var value = CacheUtils.Get(key); - - if (value == null) return; - var valueType = value.GetType().FullName; - - var ltlKey = (Literal)e.Item.FindControl("ltlKey"); - var ltlValue = (Literal)e.Item.FindControl("ltlValue"); - - ltlKey.Text = key; - - if (valueType == "System.String") - { - ltlValue.Text = $"string, length:{value.ToString().Length}"; - } else if (valueType == "System.Int32") - { - ltlValue.Text = value.ToString(); - } - else - { - ltlValue.Text = valueType; - } - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - CacheUtils.ClearAll(); - CacheDbUtils.Clear(); - PageUtils.Redirect(PageUtils.GetSettingsUrl(nameof(PageUtilityCache), null)); - } - - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageUtilityDbLogDelete.cs b/SiteServer.BackgroundPages/Settings/PageUtilityDbLogDelete.cs deleted file mode 100644 index ef30d7fc6..000000000 --- a/SiteServer.BackgroundPages/Settings/PageUtilityDbLogDelete.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.Utils; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageUtilityDbLogDelete : BasePage - { - public Literal LtlLastExecuteDate; - - protected override bool IsAccessable => true; - - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (IsPostBack) return; - - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Utility); - var dt = DataProvider.LogDao.GetLastRemoveLogDate(AuthRequest.AdminName); - LtlLastExecuteDate.Text = dt == DateTime.MinValue ? "无记录" : DateUtils.GetDateAndTimeString(dt); - } - - public override void Submit_OnClick(object sender, EventArgs e) - { - if (!Page.IsPostBack || !Page.IsValid) return; - - DataProvider.DatabaseDao.DeleteDbLog(); - - AuthRequest.AddAdminLog("清空数据库日志"); - - SuccessMessage("清空日志成功!"); - } - - } -} diff --git a/SiteServer.BackgroundPages/Settings/PageUtilityJsMin.cs b/SiteServer.BackgroundPages/Settings/PageUtilityJsMin.cs deleted file mode 100644 index 9c52d6305..000000000 --- a/SiteServer.BackgroundPages/Settings/PageUtilityJsMin.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using SiteServer.CMS.Core; - -namespace SiteServer.BackgroundPages.Settings -{ - public class PageUtilityJsMin : BasePage - { - public void Page_Load(object sender, EventArgs e) - { - if (IsForbidden) return; - - if (!IsPostBack) - { - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Utility); - } - } - } -} diff --git a/SiteServer.BackgroundPages/app.config b/SiteServer.BackgroundPages/app.config deleted file mode 100644 index 455df6f80..000000000 --- a/SiteServer.BackgroundPages/app.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/SiteServer.BackgroundPages/packages.config b/SiteServer.BackgroundPages/packages.config deleted file mode 100644 index a36a5149f..000000000 --- a/SiteServer.BackgroundPages/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/SiteServer.CMS.sln b/SiteServer.CMS.sln new file mode 100644 index 000000000..1c45d2c31 --- /dev/null +++ b/SiteServer.CMS.sln @@ -0,0 +1,85 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 15 +VisualStudioVersion = 15.0.28307.572 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SiteServer.Utils", "src\SiteServer.Utils\SiteServer.Utils.csproj", "{059E3927-37E1-4F6F-B525-FEF40C54906B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SiteServer.Utils.Tests", "tests\SiteServer.Utils.Tests\SiteServer.Utils.Tests.csproj", "{05A848DE-A9E4-42A0-9A56-8C049A43F56A}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SiteServer.CMS", "net452\SiteServer.CMS\SiteServer.CMS.csproj", "{944127C3-915D-4F02-A534-64EC668C46EC}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SiteServer.CMS.Tests", "net452\SiteServer.CMS.Tests\SiteServer.CMS.Tests.csproj", "{9CD127C6-08E2-406D-9630-463DA1431EA4}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SiteServer.BackgroundPages", "net452\SiteServer.BackgroundPages\SiteServer.BackgroundPages.csproj", "{6AA1713A-3B77-4B20-B8C7-FCB6DE556F64}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SiteServer.API", "net452\SiteServer.Web\SiteServer.API.csproj", "{69C00F60-F28A-4CBC-B1A4-2DB73BB97471}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SiteServer.API.Tests", "net452\SiteServer.API.Tests\SiteServer.API.Tests.csproj", "{5597BC9B-1E09-4EE4-9EA4-AC71CEA645F3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SiteServer.Cli", "net452\SiteServer.Cli\SiteServer.Cli.csproj", "{A7E4D925-AACF-4782-8B9A-C10B9F527A0C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SiteServer.API.Core", "src\SiteServer.API.Core\SiteServer.API.Core.csproj", "{B7040189-5546-441E-85AC-019215CE2C5C}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SiteServer.Cli.Core", "src\SiteServer.Cli.Core\SiteServer.Cli.Core.csproj", "{8BA77BE2-8BE0-4588-A101-A10049578790}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SiteServer.API.Core.Tests", "tests\SiteServer.API.Core.Tests\SiteServer.API.Core.Tests.csproj", "{1C123D87-E7FC-4CB8-887A-964CD5577DC6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {059E3927-37E1-4F6F-B525-FEF40C54906B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {059E3927-37E1-4F6F-B525-FEF40C54906B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {059E3927-37E1-4F6F-B525-FEF40C54906B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {059E3927-37E1-4F6F-B525-FEF40C54906B}.Release|Any CPU.Build.0 = Release|Any CPU + {05A848DE-A9E4-42A0-9A56-8C049A43F56A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {05A848DE-A9E4-42A0-9A56-8C049A43F56A}.Debug|Any CPU.Build.0 = Debug|Any CPU + {05A848DE-A9E4-42A0-9A56-8C049A43F56A}.Release|Any CPU.ActiveCfg = Release|Any CPU + {05A848DE-A9E4-42A0-9A56-8C049A43F56A}.Release|Any CPU.Build.0 = Release|Any CPU + {944127C3-915D-4F02-A534-64EC668C46EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {944127C3-915D-4F02-A534-64EC668C46EC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {944127C3-915D-4F02-A534-64EC668C46EC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {944127C3-915D-4F02-A534-64EC668C46EC}.Release|Any CPU.Build.0 = Release|Any CPU + {9CD127C6-08E2-406D-9630-463DA1431EA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9CD127C6-08E2-406D-9630-463DA1431EA4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9CD127C6-08E2-406D-9630-463DA1431EA4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9CD127C6-08E2-406D-9630-463DA1431EA4}.Release|Any CPU.Build.0 = Release|Any CPU + {6AA1713A-3B77-4B20-B8C7-FCB6DE556F64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6AA1713A-3B77-4B20-B8C7-FCB6DE556F64}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6AA1713A-3B77-4B20-B8C7-FCB6DE556F64}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6AA1713A-3B77-4B20-B8C7-FCB6DE556F64}.Release|Any CPU.Build.0 = Release|Any CPU + {69C00F60-F28A-4CBC-B1A4-2DB73BB97471}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {69C00F60-F28A-4CBC-B1A4-2DB73BB97471}.Debug|Any CPU.Build.0 = Debug|Any CPU + {69C00F60-F28A-4CBC-B1A4-2DB73BB97471}.Release|Any CPU.ActiveCfg = Release|Any CPU + {69C00F60-F28A-4CBC-B1A4-2DB73BB97471}.Release|Any CPU.Build.0 = Release|Any CPU + {5597BC9B-1E09-4EE4-9EA4-AC71CEA645F3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {5597BC9B-1E09-4EE4-9EA4-AC71CEA645F3}.Debug|Any CPU.Build.0 = Debug|Any CPU + {5597BC9B-1E09-4EE4-9EA4-AC71CEA645F3}.Release|Any CPU.ActiveCfg = Release|Any CPU + {5597BC9B-1E09-4EE4-9EA4-AC71CEA645F3}.Release|Any CPU.Build.0 = Release|Any CPU + {A7E4D925-AACF-4782-8B9A-C10B9F527A0C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A7E4D925-AACF-4782-8B9A-C10B9F527A0C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {A7E4D925-AACF-4782-8B9A-C10B9F527A0C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {A7E4D925-AACF-4782-8B9A-C10B9F527A0C}.Release|Any CPU.Build.0 = Release|Any CPU + {B7040189-5546-441E-85AC-019215CE2C5C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {B7040189-5546-441E-85AC-019215CE2C5C}.Debug|Any CPU.Build.0 = Debug|Any CPU + {B7040189-5546-441E-85AC-019215CE2C5C}.Release|Any CPU.ActiveCfg = Release|Any CPU + {B7040189-5546-441E-85AC-019215CE2C5C}.Release|Any CPU.Build.0 = Release|Any CPU + {8BA77BE2-8BE0-4588-A101-A10049578790}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8BA77BE2-8BE0-4588-A101-A10049578790}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8BA77BE2-8BE0-4588-A101-A10049578790}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8BA77BE2-8BE0-4588-A101-A10049578790}.Release|Any CPU.Build.0 = Release|Any CPU + {1C123D87-E7FC-4CB8-887A-964CD5577DC6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1C123D87-E7FC-4CB8-887A-964CD5577DC6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1C123D87-E7FC-4CB8-887A-964CD5577DC6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1C123D87-E7FC-4CB8-887A-964CD5577DC6}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {5E5FD939-BED0-452A-B29F-1F8B0E14AFCC} + EndGlobalSection +EndGlobal diff --git a/SiteServer.CMS/Api/ApiManager.cs b/SiteServer.CMS/Api/ApiManager.cs deleted file mode 100644 index 4e0dffcb6..000000000 --- a/SiteServer.CMS/Api/ApiManager.cs +++ /dev/null @@ -1,36 +0,0 @@ -using SiteServer.CMS.Core; -using SiteServer.Utils; - -namespace SiteServer.CMS.Api -{ - public static class ApiManager - { - private static string _innerApiUrl; - - public static string InnerApiUrl - { - get - { - if (string.IsNullOrEmpty(_innerApiUrl)) - { - _innerApiUrl = PageUtils.ParseNavigationUrl("~/api"); - } - return _innerApiUrl; - } - } - - public static string GetInnerApiUrl(string route) - { - return PageUtils.Combine(InnerApiUrl, route); - } - - public static string OuterApiUrl => ConfigManager.SystemConfigInfo.ApiUrl; - - public static string GetOuterApiUrl(string route) - { - return PageUtils.Combine(OuterApiUrl, route); - } - - public static string SignalrHubsUrl => PageUtils.ParseNavigationUrl("~/signalr/hubs"); - } -} diff --git a/SiteServer.CMS/Api/ApiRoutePlugin.cs b/SiteServer.CMS/Api/ApiRoutePlugin.cs deleted file mode 100644 index 0a1bf9981..000000000 --- a/SiteServer.CMS/Api/ApiRoutePlugin.cs +++ /dev/null @@ -1,26 +0,0 @@ -using SiteServer.Utils; - -namespace SiteServer.CMS.Api -{ - public class ApiRoutePlugin - { - public const string Route = "plugins/{pluginId}"; - public const string RouteAction = "plugins/{pluginId}/{name}"; - public const string RouteActionAndId = "plugins/{pluginId}/{name}/{id}"; - - public static string GetUrl(string pluginId, string name = "", string id = "") - { - var apiUrl = ApiManager.GetOuterApiUrl(Route); - apiUrl = apiUrl.Replace("{pluginId}", pluginId); - if (!string.IsNullOrEmpty(name)) - { - apiUrl = PageUtils.Combine(apiUrl, name); - if (!string.IsNullOrEmpty(id)) - { - apiUrl = PageUtils.Combine(apiUrl, id); - } - } - return apiUrl; - } - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Api/Http/ApiRoutePluginHttp.cs b/SiteServer.CMS/Api/Http/ApiRoutePluginHttp.cs deleted file mode 100644 index 0d91b9b3d..000000000 --- a/SiteServer.CMS/Api/Http/ApiRoutePluginHttp.cs +++ /dev/null @@ -1,26 +0,0 @@ -using SiteServer.Utils; - -namespace SiteServer.CMS.Controllers.Http -{ - public class ApiRoutePluginHttp - { - public const string Route = "http/{pluginId}"; - public const string RouteName = "http/{pluginId}/{name}"; - public const string RouteNameAndId = "http/{pluginId}/{name}/{id}"; - - public static string GetUrl(string apiUrl, string pluginId, string name = "", string id = "") - { - apiUrl = PageUtils.Combine(apiUrl, Route); - apiUrl = apiUrl.Replace("{pluginId}", pluginId); - if (!string.IsNullOrEmpty(name)) - { - apiUrl = PageUtils.Combine(apiUrl, name); - if (!string.IsNullOrEmpty(id)) - { - apiUrl = PageUtils.Combine(apiUrl, id); - } - } - return apiUrl; - } - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Api/Json/ApiRoutePluginJson.cs b/SiteServer.CMS/Api/Json/ApiRoutePluginJson.cs deleted file mode 100644 index 5eb77f98e..000000000 --- a/SiteServer.CMS/Api/Json/ApiRoutePluginJson.cs +++ /dev/null @@ -1,26 +0,0 @@ -using SiteServer.Utils; - -namespace SiteServer.CMS.Controllers.Json -{ - public class ApiRoutePluginJson - { - public const string Route = "json/{pluginId}"; - public const string RouteName = "json/{pluginId}/{name}"; - public const string RouteNameAndId = "json/{pluginId}/{name}/{id}"; - - public static string GetUrl(string apiUrl, string pluginId, string name = "", string id = "") - { - apiUrl = PageUtils.Combine(apiUrl, Route); - apiUrl = apiUrl.Replace("{pluginId}", pluginId); - if (!string.IsNullOrEmpty(name)) - { - apiUrl = PageUtils.Combine(apiUrl, name); - if (!string.IsNullOrEmpty(id)) - { - apiUrl = PageUtils.Combine(apiUrl, id); - } - } - return apiUrl; - } - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Api/Preview/ApiRoutePreview.cs b/SiteServer.CMS/Api/Preview/ApiRoutePreview.cs deleted file mode 100644 index e4e877b99..000000000 --- a/SiteServer.CMS/Api/Preview/ApiRoutePreview.cs +++ /dev/null @@ -1,60 +0,0 @@ -using SiteServer.Utils; - -namespace SiteServer.CMS.Api.Preview -{ - public class ApiRoutePreview - { - public const string Route = "preview/{siteId}"; - public const string RouteChannel = "preview/{siteId}/{channelId}"; - public const string RouteContent = "preview/{siteId}/{channelId}/{contentId}"; - public const string RouteFile = "preview/{siteId}/file/{fileTemplateId}"; - - public static string GetSiteUrl(int siteId) - { - return GetUrl(siteId, 0, 0, 0); - } - - public static string GetChannelUrl(int siteId, int channelId) - { - return GetUrl(siteId, channelId, 0, 0); - } - - public static string GetContentUrl(int siteId, int channelId, int contentId) - { - return GetUrl(siteId, channelId, contentId, 0); - } - - public static string GetContentPreviewUrl(int siteId, int channelId, int contentId, int previewId) - { - if (contentId == 0) - { - contentId = previewId; - } - return $"{GetUrl(siteId, channelId, contentId, 0)}?isPreview=true&previewId={previewId}"; - } - - public static string GetFileUrl(int siteId, int fileTemplateId) - { - return GetUrl(siteId, 0, 0, fileTemplateId); - } - - private static string GetUrl(int siteId, int channelId, int contentId, int fileTemplateId) - { - var apiUrl = ApiManager.GetInnerApiUrl(Route); - apiUrl = apiUrl.Replace("{siteId}", siteId.ToString()); - if (channelId > 0) - { - apiUrl = PageUtils.Combine(apiUrl, channelId.ToString()); - if (contentId > 0) - { - apiUrl = PageUtils.Combine(apiUrl, contentId.ToString()); - } - } - else if (fileTemplateId > 0) - { - apiUrl = PageUtils.Combine(apiUrl, fileTemplateId.ToString()); - } - return apiUrl; - } - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Api/Sys/Administrators/ApiRouteActionsLogin.cs b/SiteServer.CMS/Api/Sys/Administrators/ApiRouteActionsLogin.cs deleted file mode 100644 index ba2618096..000000000 --- a/SiteServer.CMS/Api/Sys/Administrators/ApiRouteActionsLogin.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace SiteServer.CMS.Api.Sys.Administrators -{ - public class ApiRouteActionsLogin - { - public const string Route = "sys/administrators/actions/login"; - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Api/Sys/Administrators/ApiRouteSiteCheckList.cs b/SiteServer.CMS/Api/Sys/Administrators/ApiRouteSiteCheckList.cs deleted file mode 100644 index 271b6d278..000000000 --- a/SiteServer.CMS/Api/Sys/Administrators/ApiRouteSiteCheckList.cs +++ /dev/null @@ -1,16 +0,0 @@ -using SiteServer.Utils; - -namespace SiteServer.CMS.Api.Sys.Administrators -{ - public class ApiRouteSiteCheckList - { - public const string Route = "sys/administrators/{userName}/site_check_list"; - - public static string GetUrl(string apiUrl, string userName) - { - apiUrl = PageUtils.Combine(apiUrl, Route); - apiUrl = apiUrl.Replace("{userName}", userName); - return apiUrl; - } - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Api/Sys/Errors/ApiRouteError.cs b/SiteServer.CMS/Api/Sys/Errors/ApiRouteError.cs deleted file mode 100644 index f70bf9d6b..000000000 --- a/SiteServer.CMS/Api/Sys/Errors/ApiRouteError.cs +++ /dev/null @@ -1,16 +0,0 @@ -using SiteServer.Utils; - -namespace SiteServer.CMS.Api.Sys.Errors -{ - public class ApiRouteError - { - public const string Route = "sys/errors/{id}"; - - public static string GetUrl(string apiUrl, int id) - { - apiUrl = PageUtils.Combine(apiUrl, Route); - apiUrl = apiUrl.Replace("{id}", id.ToString()); - return apiUrl; - } - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsAddContentHits.cs b/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsAddContentHits.cs deleted file mode 100644 index fd8115ac2..000000000 --- a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsAddContentHits.cs +++ /dev/null @@ -1,18 +0,0 @@ -using SiteServer.Utils; - -namespace SiteServer.CMS.Api.Sys.Stl -{ - public class ApiRouteActionsAddContentHits - { - public const string Route = "sys/stl/actions/add_content_hits/{siteId}/{channelId}/{contentId}"; - - public static string GetUrl(string apiUrl, int siteId, int channelId, int contentId) - { - apiUrl = PageUtils.Combine(apiUrl, Route); - apiUrl = apiUrl.Replace("{siteId}", siteId.ToString()); - apiUrl = apiUrl.Replace("{channelId}", channelId.ToString()); - apiUrl = apiUrl.Replace("{contentId}", contentId.ToString()); - return apiUrl; - } - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsSearch.cs b/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsSearch.cs deleted file mode 100644 index b234d110b..000000000 --- a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsSearch.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Collections.Generic; -using SiteServer.CMS.StlParser.StlElement; -using SiteServer.Utils; - -namespace SiteServer.CMS.Api.Sys.Stl -{ - public static class ApiRouteActionsSearch - { - public const string Route = "sys/stl/actions/search"; - - public static string GetUrl(string apiUrl) - { - return PageUtils.Combine(apiUrl, Route); - } - - public static string GetParameters(bool isAllSites, string siteName, string siteDir, string siteIds, string channelIndex, string channelName, string channelIds, string type, string word, string dateAttribute, string dateFrom, string dateTo, string since, int pageNum, bool isHighlight, bool isDefaultDisplay, int siteId, string ajaxDivId, string template) - { - return $@" -{{ - {StlSearch.IsAllSites.Name.ToLower()}: {isAllSites.ToString().ToLower()}, - {StlSearch.SiteName.Name.ToLower()}: '{siteName}', - {StlSearch.SiteDir.Name.ToLower()}: '{siteDir}', - {StlSearch.SiteIds.Name.ToLower()}: '{siteIds}', - {StlSearch.ChannelIndex.Name.ToLower()}: '{channelIndex}', - {StlSearch.ChannelName.Name.ToLower()}: '{channelName}', - {StlSearch.ChannelIds.Name.ToLower()}: '{channelIds}', - {StlSearch.Type.Name.ToLower()}: '{type}', - {StlSearch.Word.Name.ToLower()}: '{word}', - {StlSearch.DateAttribute.Name.ToLower()}: '{dateAttribute}', - {StlSearch.DateFrom.Name.ToLower()}: '{dateFrom}', - {StlSearch.DateTo.Name.ToLower()}: '{dateTo}', - {StlSearch.Since.Name.ToLower()}: '{since}', - {StlSearch.PageNum.Name.ToLower()}: {pageNum}, - {StlSearch.IsHighlight.Name.ToLower()}: {isHighlight.ToString().ToLower()}, - {StlSearch.IsDefaultDisplay.Name.ToLower()}: {isDefaultDisplay.ToString().ToLower()}, - siteid: '{siteId}', - ajaxdivid: '{ajaxDivId}', - template: '{TranslateUtils.EncryptStringBySecretKey(template)}', -}}"; - } - - public static List ExlcudeAttributeNames => new List - { - StlSearch.IsAllSites.Name.ToLower(), - StlSearch.SiteName.Name.ToLower(), - StlSearch.SiteDir.Name.ToLower(), - StlSearch.SiteIds.Name.ToLower(), - StlSearch.ChannelIndex.Name.ToLower(), - StlSearch.ChannelName.Name.ToLower(), - StlSearch.ChannelIds.Name.ToLower(), - StlSearch.Type.Name.ToLower(), - StlSearch.Word.Name.ToLower(), - StlSearch.DateAttribute.Name.ToLower(), - StlSearch.DateFrom.Name.ToLower(), - StlSearch.DateTo.Name.ToLower(), - StlSearch.Since.Name.ToLower(), - StlSearch.PageNum.Name.ToLower(), - StlSearch.IsHighlight.Name.ToLower(), - StlSearch.IsDefaultDisplay.Name.ToLower(), - "siteid", - "ajaxdivid", - "template", - }; - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Core/AdminManager.cs b/SiteServer.CMS/Core/AdminManager.cs deleted file mode 100644 index a613aab20..000000000 --- a/SiteServer.CMS/Core/AdminManager.cs +++ /dev/null @@ -1,185 +0,0 @@ -using System; -using System.Collections; -using SiteServer.CMS.Model; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Core -{ - public class AdminManager - { - private static readonly object LockObject = new object(); - - private AdminManager() - { - } - - public static AdministratorInfo GetAdminInfo(string userName) - { - var ht = GetActiveAdminInfo(); - - var adminInfo = ht[userName] as AdministratorInfo; - if (adminInfo != null) return adminInfo; - - lock (LockObject) - { - adminInfo = ht[userName] as AdministratorInfo; - - if (adminInfo == null) - { - adminInfo = DataProvider.AdministratorDao.GetByUserName(userName); - ht[userName] = adminInfo; - } - } - - return adminInfo; - } - - public static string GetDisplayName(string userName, bool isDepartment) - { - var adminInfo = GetAdminInfo(userName); - if (adminInfo == null) return userName; - - if (!isDepartment) return adminInfo.DisplayName; - var departmentName = DepartmentManager.GetDepartmentName(adminInfo.DepartmentId); - return !string.IsNullOrEmpty(departmentName) ? $"{adminInfo.DisplayName}({departmentName})" : adminInfo.DisplayName; - } - - public static string GetFullName(string userName) - { - if (!string.IsNullOrEmpty(userName)) - { - var adminInfo = GetAdminInfo(userName); - if (adminInfo != null) - { - string retval = $"账号:{userName}
    姓名:{adminInfo.DisplayName}"; - var departmentName = DepartmentManager.GetDepartmentName(adminInfo.DepartmentId); - if (!string.IsNullOrEmpty(departmentName)) - { - retval += $"
    部门:{departmentName}"; - } - return retval; - } - return userName; - } - return string.Empty; - } - - public static void RemoveCache(string userName) - { - var ht = GetActiveAdminInfo(); - - lock (ht.SyncRoot) - { - ht.Remove(userName); - } - } - - public const string CacheKey = "BaiRong.Core.AdminManager"; - - public static void Clear() - { - CacheUtils.Remove(CacheKey); - } - - public static Hashtable GetActiveAdminInfo() - { - var retval = CacheUtils.Get(CacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = CacheUtils.Get(CacheKey); - if (retval == null) - { - retval = new Hashtable(); - CacheUtils.Insert(CacheKey, retval); - } - } - - return retval; - } - - public static bool CreateAdministrator(AdministratorInfo administratorInfo, out string errorMessage) - { - try - { - administratorInfo.LastActivityDate = DateUtils.SqlMinValue; - administratorInfo.CreationDate = DateTime.Now; - administratorInfo.PasswordFormat = EPasswordFormat.Encrypted; - var isCreated = DataProvider.AdministratorDao.Insert(administratorInfo, out errorMessage); - if (isCreated == false) return false; - - var roles = new[] { EPredefinedRoleUtils.GetValue(EPredefinedRole.Administrator) }; - DataProvider.AdministratorsInRolesDao.AddUserToRoles(administratorInfo.UserName, roles); - - return true; - } - catch (Exception ex) - { - errorMessage = ex.Message; - return false; - } - } - - public const string AnonymousUserName = "Anonymous"; - - public static string GetRolesHtml(string userName) - { - var isConsoleAdministrator = false; - var isSystemAdministrator = false; - var arraylist = new ArrayList(); - var roles = DataProvider.AdministratorsInRolesDao.GetRolesForUser(userName); - foreach (var role in roles) - { - if (!EPredefinedRoleUtils.IsPredefinedRole(role)) - { - arraylist.Add(role); - } - else - { - if (EPredefinedRoleUtils.Equals(EPredefinedRole.ConsoleAdministrator, role)) - { - isConsoleAdministrator = true; - break; - } - if (EPredefinedRoleUtils.Equals(EPredefinedRole.SystemAdministrator, role)) - { - isSystemAdministrator = true; - break; - } - } - } - - var retval = string.Empty; - - if (isConsoleAdministrator) - { - retval += EPredefinedRoleUtils.GetText(EPredefinedRole.ConsoleAdministrator); - } - else if (isSystemAdministrator) - { - retval += EPredefinedRoleUtils.GetText(EPredefinedRole.SystemAdministrator); - } - else - { - retval += TranslateUtils.ObjectCollectionToString(arraylist); - } - return retval; - } - - //public static bool HasChannelPermissionIsConsoleAdministrator(string userName) - //{ - // var roles = DataProvider.AdministratorsInRolesDao.GetRolesForUser(userName); - - // return EPredefinedRoleUtils.IsConsoleAdministrator(roles); - //} - - //public static bool HasChannelPermissionIsSystemAdministrator(string userName) - //{ - // var roles = DataProvider.AdministratorsInRolesDao.GetRolesForUser(userName); - - // return EPredefinedRoleUtils.IsSystemAdministrator(roles); - //} - } -} diff --git a/SiteServer.CMS/Core/ArchiveManager.cs b/SiteServer.CMS/Core/ArchiveManager.cs deleted file mode 100644 index 60e3a1e6d..000000000 --- a/SiteServer.CMS/Core/ArchiveManager.cs +++ /dev/null @@ -1,22 +0,0 @@ -using SiteServer.CMS.Model; - -namespace SiteServer.CMS.Core -{ - public class ArchiveManager - { - public static void CreateArchiveTableIfNotExists(SiteInfo siteInfo, string tableName) - { - if (!DataProvider.DatabaseDao.IsTableExists(TableMetadataManager.GetTableNameOfArchive(tableName))) - { - try - { - DataProvider.TableDao.CreateDbTableOfArchive(tableName); - } - catch - { - // ignored - } - } - } - } -} diff --git a/SiteServer.CMS/Core/AreaManager.cs b/SiteServer.CMS/Core/AreaManager.cs deleted file mode 100644 index cd95300c3..000000000 --- a/SiteServer.CMS/Core/AreaManager.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System.Collections.Generic; -using SiteServer.CMS.Model; -using SiteServer.Utils; - -namespace SiteServer.CMS.Core -{ - public class AreaManager - { - public static AreaInfo GetAreaInfo(int areaId) - { - var pairList = GetAreaInfoPairList(); - - foreach (var pair in pairList) - { - var theAreaId = pair.Key; - if (theAreaId == areaId) - { - var areaInfo = pair.Value; - return areaInfo; - } - } - return null; - } - - public static string GetThisAreaName(int areaId) - { - var areaInfo = GetAreaInfo(areaId); - if (areaInfo != null) - { - return areaInfo.AreaName; - } - return string.Empty; - } - - public static string GetAreaName(int areaId) - { - if (areaId > 0) - { - var areaNameList = new List(); - - var parentsPath = GetParentsPath(areaId); - var areaIdList = new List(); - if (!string.IsNullOrEmpty(parentsPath)) - { - areaIdList = TranslateUtils.StringCollectionToIntList(parentsPath); - } - areaIdList.Add(areaId); - - foreach (var theAreaId in areaIdList) - { - var areaInfo = GetAreaInfo(theAreaId); - if (areaInfo != null) - { - areaNameList.Add(areaInfo.AreaName); - } - } - - return TranslateUtils.ObjectCollectionToString(areaNameList, " > "); - } - return string.Empty; - } - - public static string GetParentsPath(int areaId) - { - var retval = string.Empty; - var areaInfo = GetAreaInfo(areaId); - if (areaInfo != null) - { - retval = areaInfo.ParentsPath; - } - return retval; - } - - public static List GetAreaIdList() - { - var pairList = GetAreaInfoPairList(); - var list = new List(); - foreach (var pair in pairList) - { - list.Add(pair.Key); - } - return list; - } - - public static void ClearCache() - { - CacheUtils.Remove(CacheKey); - } - - public static List> GetAreaInfoPairList() - { - lock (LockObject) - { - if (CacheUtils.Get(CacheKey) == null) - { - var pairListFormDb = DataProvider.AreaDao.GetAreaInfoPairList(); - var sl = new List>(); - foreach (var pair in pairListFormDb) - { - var areaInfo = pair.Value; - if (areaInfo != null) - { - sl.Add(pair); - } - } - CacheUtils.Insert(CacheKey, sl); - return sl; - } - return CacheUtils.Get(CacheKey) as List>; - } - } - - /****************** Cache *********************/ - - private static readonly object LockObject = new object(); - private const string CacheKey = "BaiRong.Core.AreaManager"; - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Core/CacheDbUtils.cs b/SiteServer.CMS/Core/CacheDbUtils.cs deleted file mode 100644 index e9744d342..000000000 --- a/SiteServer.CMS/Core/CacheDbUtils.cs +++ /dev/null @@ -1,43 +0,0 @@ -namespace SiteServer.CMS.Core -{ - public class CacheDbUtils - { - private CacheDbUtils() - { - } - - public static void RemoveAndInsert(string cacheKey, string cacheValue) - { - if (!string.IsNullOrEmpty(cacheKey)) - { - DataProvider.DbCacheDao.RemoveAndInsert(cacheKey, cacheValue); - } - } - - public static void Clear() - { - DataProvider.DbCacheDao.Clear(); - } - - public static bool IsExists(string cacheKey) - { - return DataProvider.DbCacheDao.IsExists(cacheKey); - } - - public static string GetValue(string cacheKey) - { - return DataProvider.DbCacheDao.GetValue(cacheKey); - } - - public static string GetValueAndRemove(string cacheKey) - { - return DataProvider.DbCacheDao.GetValueAndRemove(cacheKey); - } - - public static int GetCount() - { - return DataProvider.DbCacheDao.GetCount(); - } - - } -} diff --git a/SiteServer.CMS/Core/ChannelManager.cs b/SiteServer.CMS/Core/ChannelManager.cs deleted file mode 100644 index 46a4e0612..000000000 --- a/SiteServer.CMS/Core/ChannelManager.cs +++ /dev/null @@ -1,575 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.Utils.IO; -using SiteServer.CMS.Model; -using SiteServer.CMS.Plugin; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Core -{ - public static class ChannelManager - { - private static class ChannelManagerCache - { - private static readonly object LockObject = new object(); - private const string CacheKey = "SiteServer.CMS.Core.ChannelManager"; - private static readonly FileWatcherClass FileWatcher; - - static ChannelManagerCache() - { - FileWatcher = new FileWatcherClass(FileWatcherClass.Node); - FileWatcher.OnFileChange += FileWatcher_OnFileChange; - } - - private static void FileWatcher_OnFileChange(object sender, EventArgs e) - { - CacheUtils.Remove(CacheKey); - } - - private static void Update(Dictionary> allDict, Dictionary dic, int siteId) - { - lock (LockObject) - { - allDict[siteId] = dic; - } - } - - private static Dictionary> GetAllDictionary() - { - var allDict = CacheUtils.Get(CacheKey) as Dictionary>; - if (allDict != null) return allDict; - - allDict = new Dictionary>(); - CacheUtils.InsertHours(CacheKey, allDict, 24); - return allDict; - } - - public static void Remove(int siteId) - { - var allDict = GetAllDictionary(); - - lock (LockObject) - { - allDict.Remove(siteId); - } - - FileWatcher.UpdateCacheFile(); - } - - public static Dictionary GetChannelInfoDictionaryBySiteId(int siteId) - { - var allDict = GetAllDictionary(); - - Dictionary dict; - allDict.TryGetValue(siteId, out dict); - - if (dict != null) return dict; - - dict = DataProvider.ChannelDao.GetChannelInfoDictionaryBySiteId(siteId); - Update(allDict, dict, siteId); - return dict; - } - } - - public static void RemoveCache(int siteId) - { - ChannelManagerCache.Remove(siteId); - Node.ClearCache(); - } - - public static ChannelInfo GetChannelInfo(int siteId, int channelId) - { - ChannelInfo nodeInfo = null; - var dict = ChannelManagerCache.GetChannelInfoDictionaryBySiteId(siteId); - dict?.TryGetValue(channelId, out nodeInfo); - return nodeInfo; - } - - public static List GetChannelInfoList(int siteId) - { - var dic = ChannelManagerCache.GetChannelInfoDictionaryBySiteId(siteId); - return dic.Values.Where(nodeInfo => nodeInfo != null).ToList(); - } - - public static List GetChannelIdList(int siteId) - { - var dic = ChannelManagerCache.GetChannelInfoDictionaryBySiteId(siteId); - return dic.Values.OrderBy(c => c.Taxis).Select(channelInfo => channelInfo.Id).ToList(); - } - - public static List GetChannelIdList(ChannelInfo channelInfo, EScopeType scopeType, string group, string groupNot, string contentModelPluginId) - { - if (channelInfo == null) return new List(); - - var dic = ChannelManagerCache.GetChannelInfoDictionaryBySiteId(channelInfo.SiteId); - var channelInfoList = new List(); - - if (channelInfo.ChildrenCount == 0) - { - if (scopeType != EScopeType.Children && scopeType != EScopeType.Descendant) - { - channelInfoList.Add(channelInfo); - } - } - else if (scopeType == EScopeType.Self) - { - channelInfoList.Add(channelInfo); - } - else if (scopeType == EScopeType.All) - { - foreach (var nodeInfo in dic.Values) - { - if (nodeInfo.Id == channelInfo.Id || nodeInfo.ParentId == channelInfo.Id || StringUtils.In(nodeInfo.ParentsPath, channelInfo.Id)) - { - channelInfoList.Add(nodeInfo); - } - } - } - else if (scopeType == EScopeType.Children) - { - foreach (var nodeInfo in dic.Values) - { - if (nodeInfo.ParentId == channelInfo.Id) - { - channelInfoList.Add(nodeInfo); - } - } - } - else if (scopeType == EScopeType.Descendant) - { - foreach (var nodeInfo in dic.Values) - { - if (nodeInfo.ParentId == channelInfo.Id || StringUtils.In(nodeInfo.ParentsPath, channelInfo.Id)) - { - channelInfoList.Add(nodeInfo); - } - } - } - else if (scopeType == EScopeType.SelfAndChildren) - { - foreach (var nodeInfo in dic.Values) - { - if (nodeInfo.Id == channelInfo.Id || nodeInfo.ParentId == channelInfo.Id) - { - channelInfoList.Add(nodeInfo); - } - } - } - - var filteredChannelInfoList = new List(); - foreach (var nodeInfo in channelInfoList) - { - if (!string.IsNullOrEmpty(group)) - { - if (!StringUtils.In(nodeInfo.GroupNameCollection, group)) - { - continue; - } - } - if (!string.IsNullOrEmpty(groupNot)) - { - if (StringUtils.In(nodeInfo.GroupNameCollection, groupNot)) - { - continue; - } - } - if (!string.IsNullOrEmpty(contentModelPluginId)) - { - if (!StringUtils.EqualsIgnoreCase(nodeInfo.ContentModelPluginId, contentModelPluginId)) - { - continue; - } - } - filteredChannelInfoList.Add(nodeInfo); - } - - return filteredChannelInfoList.OrderBy(c => c.Taxis).Select(channelInfoInList => channelInfoInList.Id).ToList(); - } - - public static bool IsExists(int siteId, int channelId) - { - var nodeInfo = GetChannelInfo(siteId, channelId); - return nodeInfo != null; - } - - public static bool IsExists(int channelId) - { - var list = SiteManager.GetSiteIdList(); - foreach (var siteId in list) - { - var nodeInfo = GetChannelInfo(siteId, channelId); - if (nodeInfo != null) return true; - } - - return false; - } - - public static int GetChannelIdByParentsCount(int siteId, int channelId, int parentsCount) - { - if (parentsCount == 0) return siteId; - if (channelId == 0 || channelId == siteId) return siteId; - - var nodeInfo = GetChannelInfo(siteId, channelId); - if (nodeInfo != null) - { - return nodeInfo.ParentsCount == parentsCount ? nodeInfo.Id : GetChannelIdByParentsCount(siteId, nodeInfo.ParentId, parentsCount); - } - return siteId; - } - - public static string GetTableName(SiteInfo siteInfo, int channelId) - { - return GetTableName(siteInfo, GetChannelInfo(siteInfo.Id, channelId)); - } - - public static string GetTableName(SiteInfo siteInfo, ChannelInfo nodeInfo) - { - return nodeInfo != null ? GetTableName(siteInfo, nodeInfo.ContentModelPluginId) : string.Empty; - } - - public static string GetTableName(SiteInfo siteInfo, string pluginId) - { - var tableName = siteInfo.TableName; - - if (string.IsNullOrEmpty(pluginId)) return tableName; - - var contentTable = PluginContentTableManager.GetTableName(pluginId); - if (!string.IsNullOrEmpty(contentTable)) - { - tableName = contentTable; - } - - return tableName; - } - - //public static ETableStyle GetTableStyle(SiteInfo siteInfo, int channelId) - //{ - // return GetTableStyle(siteInfo, GetChannelInfo(siteInfo.Id, channelId)); - //} - - //public static ETableStyle GetTableStyle(SiteInfo siteInfo, NodeInfo nodeInfo) - //{ - // var tableStyle = ETableStyle.BackgroundContent; - - // if (string.IsNullOrEmpty(nodeInfo.ContentModelPluginId)) return tableStyle; - - // var contentTable = PluginCache.GetEnabledPluginMetadata(nodeInfo.ContentModelPluginId); - // if (contentTable != null) - // { - // tableStyle = ETableStyle.Custom; - // } - - // return tableStyle; - //} - - public static bool IsContentModelPlugin(SiteInfo siteInfo, ChannelInfo nodeInfo) - { - if (string.IsNullOrEmpty(nodeInfo.ContentModelPluginId)) return false; - - var contentTable = PluginContentTableManager.GetTableName(nodeInfo.ContentModelPluginId); - return !string.IsNullOrEmpty(contentTable); - } - - public static string GetNodeTreeLastImageHtml(SiteInfo siteInfo, ChannelInfo nodeInfo) - { - var imageHtml = string.Empty; - if (nodeInfo.ParentId == 0) - { - var treeDirectoryUrl = SiteServerAssets.GetIconUrl("tree"); - if (siteInfo.IsRoot == false) - { - imageHtml = - $@" "; - } - else - { - imageHtml = - $@" "; - } - } - if (!string.IsNullOrEmpty(nodeInfo.ContentRelatedPluginIds)) - { - foreach (var service in PluginContentManager.GetContentPlugins(nodeInfo, false)) - { - var iconClass = PluginMenuManager.GetPluginIconClass(service.PluginId); - if (!string.IsNullOrEmpty(iconClass)) - { - imageHtml += - $@""; - } - else - { - imageHtml += - $@""; - } - } - } - return imageHtml; - } - - public static DateTime GetAddDate(int siteId, int channelId) - { - var retval = DateTime.MinValue; - var nodeInfo = GetChannelInfo(siteId, channelId); - if (nodeInfo != null) - { - retval = nodeInfo.AddDate; - } - return retval; - } - - public static int GetParentId(int siteId, int channelId) - { - var retval = 0; - var nodeInfo = GetChannelInfo(siteId, channelId); - if (nodeInfo != null) - { - retval = nodeInfo.ParentId; - } - return retval; - } - - public static string GetParentsPath(int siteId, int channelId) - { - var retval = string.Empty; - var nodeInfo = GetChannelInfo(siteId, channelId); - if (nodeInfo != null) - { - retval = nodeInfo.ParentsPath; - } - return retval; - } - - public static int GetTopLevel(int siteId, int channelId) - { - var parentsPath = GetParentsPath(siteId, channelId); - return string.IsNullOrEmpty(parentsPath) ? 0 : parentsPath.Split(',').Length; - } - - public static string GetChannelName(int siteId, int channelId) - { - var retval = string.Empty; - var nodeInfo = GetChannelInfo(siteId, channelId); - if (nodeInfo != null) - { - retval = nodeInfo.ChannelName; - } - return retval; - } - - public static string GetChannelNameNavigation(int siteId, int channelId) - { - var nodeNameList = new List(); - - if (channelId == 0) channelId = siteId; - - if (channelId == siteId) - { - var nodeInfo = GetChannelInfo(siteId, siteId); - return nodeInfo.ChannelName; - } - var parentsPath = GetParentsPath(siteId, channelId); - var channelIdList = new List(); - if (!string.IsNullOrEmpty(parentsPath)) - { - channelIdList = TranslateUtils.StringCollectionToIntList(parentsPath); - } - channelIdList.Add(channelId); - channelIdList.Remove(siteId); - - foreach (var theChannelId in channelIdList) - { - var nodeInfo = GetChannelInfo(siteId, theChannelId); - if (nodeInfo != null) - { - nodeNameList.Add(nodeInfo.ChannelName); - } - } - - return TranslateUtils.ObjectCollectionToString(nodeNameList, " > "); - } - - public static void AddListItems(ListItemCollection listItemCollection, SiteInfo siteInfo, bool isSeeOwning, bool isShowContentNum, PermissionManager permissionManager) - { - var list = GetChannelIdList(siteInfo.Id); - var nodeCount = list.Count; - var isLastNodeArray = new bool[nodeCount]; - foreach (var channelId in list) - { - var enabled = true; - if (isSeeOwning) - { - enabled = permissionManager.IsOwningChannelId(channelId); - if (!enabled) - { - if (!permissionManager.IsDescendantOwningChannelId(siteInfo.Id, channelId)) continue; - } - } - var nodeInfo = GetChannelInfo(siteInfo.Id, channelId); - - var listitem = new ListItem(GetSelectText(siteInfo, nodeInfo, isLastNodeArray, isShowContentNum), nodeInfo.Id.ToString()); - if (!enabled) - { - listitem.Attributes.Add("style", "color:gray;"); - } - listItemCollection.Add(listitem); - } - } - - public static void AddListItems(ListItemCollection listItemCollection, SiteInfo siteInfo, bool isSeeOwning, bool isShowContentNum, string contentModelId, PermissionManager permissionManager) - { - var list = GetChannelIdList(siteInfo.Id); - var nodeCount = list.Count; - var isLastNodeArray = new bool[nodeCount]; - foreach (var channelId in list) - { - var enabled = true; - if (isSeeOwning) - { - enabled = permissionManager.IsOwningChannelId(channelId); - if (!enabled) - { - if (!permissionManager.IsDescendantOwningChannelId(siteInfo.Id, channelId)) continue; - } - } - var nodeInfo = GetChannelInfo(siteInfo.Id, channelId); - - var listitem = new ListItem(GetSelectText(siteInfo, nodeInfo, isLastNodeArray, isShowContentNum), nodeInfo.Id.ToString()); - if (!enabled) - { - listitem.Attributes.Add("style", "color:gray;"); - } - if (!StringUtils.EqualsIgnoreCase(nodeInfo.ContentModelPluginId, contentModelId)) - { - listitem.Attributes.Add("disabled", "disabled"); - } - listItemCollection.Add(listitem); - } - } - - public static void AddListItemsForAddContent(ListItemCollection listItemCollection, SiteInfo siteInfo, bool isSeeOwning, PermissionManager permissionManager) - { - var list = GetChannelIdList(siteInfo.Id); - var nodeCount = list.Count; - var isLastNodeArray = new bool[nodeCount]; - foreach (var channelId in list) - { - var enabled = true; - if (isSeeOwning) - { - enabled = permissionManager.IsOwningChannelId(channelId); - } - - var nodeInfo = GetChannelInfo(siteInfo.Id, channelId); - if (enabled) - { - if (nodeInfo.Additional.IsContentAddable == false) enabled = false; - } - - if (!enabled) - { - continue; - } - - var listitem = new ListItem(GetSelectText(siteInfo, nodeInfo, isLastNodeArray, true), nodeInfo.Id.ToString()); - listItemCollection.Add(listitem); - } - } - - /// - /// 得到栏目,并且不对(栏目是否可添加内容)进行判断 - /// 提供给触发器页面使用 - /// 使用场景:其他栏目的内容变动之后,设置某个栏目(此栏目不能添加内容)触发生成 - /// - public static void AddListItemsForCreateChannel(ListItemCollection listItemCollection, SiteInfo siteInfo, bool isSeeOwning, PermissionManager permissionManager) - { - var list = GetChannelIdList(siteInfo.Id); - var nodeCount = list.Count; - var isLastNodeArray = new bool[nodeCount]; - foreach (var channelId in list) - { - var enabled = true; - if (isSeeOwning) - { - enabled = permissionManager.IsOwningChannelId(channelId); - } - - var nodeInfo = GetChannelInfo(siteInfo.Id, channelId); - - if (!enabled) - { - continue; - } - - var listitem = new ListItem(GetSelectText(siteInfo, nodeInfo, isLastNodeArray, true), nodeInfo.Id.ToString()); - listItemCollection.Add(listitem); - } - } - - public static string GetSelectText(SiteInfo siteInfo, ChannelInfo nodeInfo, bool[] isLastNodeArray, bool isShowContentNum) - { - var retval = string.Empty; - if (nodeInfo.Id == nodeInfo.SiteId) - { - nodeInfo.IsLastNode = true; - } - if (nodeInfo.IsLastNode == false) - { - isLastNodeArray[nodeInfo.ParentsCount] = false; - } - else - { - isLastNodeArray[nodeInfo.ParentsCount] = true; - } - for (var i = 0; i < nodeInfo.ParentsCount; i++) - { - retval = string.Concat(retval, isLastNodeArray[i] ? " " : "│"); - } - retval = string.Concat(retval, nodeInfo.IsLastNode ? "└" : "├"); - retval = string.Concat(retval, nodeInfo.ChannelName); - - if (isShowContentNum) - { - retval = string.Concat(retval, " (", nodeInfo.ContentNum, ")"); - } - - return retval; - } - - public static string GetContentAttributesOfDisplay(int siteId, int channelId) - { - var nodeInfo = GetChannelInfo(siteId, channelId); - if (nodeInfo == null) return string.Empty; - if (siteId != channelId && string.IsNullOrEmpty(nodeInfo.Additional.ContentAttributesOfDisplay)) - { - return GetContentAttributesOfDisplay(siteId, nodeInfo.ParentId); - } - return nodeInfo.Additional.ContentAttributesOfDisplay; - } - - public static bool IsAncestorOrSelf(int siteId, int parentId, int childId) - { - if (parentId == childId) - { - return true; - } - var nodeInfo = GetChannelInfo(siteId, childId); - if (nodeInfo == null) - { - return false; - } - if (StringUtils.In(nodeInfo.ParentsPath, parentId.ToString())) - { - return true; - } - return false; - } - } - -} \ No newline at end of file diff --git a/SiteServer.CMS/Core/CheckManager.cs b/SiteServer.CMS/Core/CheckManager.cs deleted file mode 100644 index 550419bb3..000000000 --- a/SiteServer.CMS/Core/CheckManager.cs +++ /dev/null @@ -1,1158 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Model; - -namespace SiteServer.CMS.Core -{ - public class CheckManager - { - public class LevelInt - { - public const int CaoGao = -99;//草稿 - public const int DaiShen = 0;//待审 - - public const int Pass1 = 1;//初审通过 - public const int Pass2 = 2;//二审通过 - public const int Pass3 = 3;//三审通过 - public const int Pass4 = 4;//四审通过 - public const int Pass5 = 5;//终审通过 - - public const int Fail1 = -1;//初审退稿 - public const int Fail2 = -2;//二审退稿 - public const int Fail3 = -3;//三审退稿 - public const int Fail4 = -4;//四审退稿 - public const int Fail5 = -5;//终审退稿 - - public const int NotChange = -100;//保持不变 - - public static List GetFailLevelList() - { - return new List - { - Fail1, - Fail2, - Fail3, - Fail4, - Fail5 - }; - } - - public static List GetUnCheckedLevelList() - { - return new List - { - DaiShen, - Pass1, - Pass2, - Pass3, - Pass4 - }; - } - - public static List GetCheckLevelList(SiteInfo siteInfo, bool isChecked, int checkedLevel) - { - if (isChecked) - { - checkedLevel = 5; - } - - var list = new List - { - DaiShen - }; - - if (checkedLevel >= 1) - { - list.Add(Fail1); - } - - if (checkedLevel >= 2) - { - list.Add(Pass1); - list.Add(Fail2); - } - - if (checkedLevel >= 3) - { - list.Add(Pass2); - list.Add(Fail3); - } - - if (checkedLevel >= 4) - { - list.Add(Pass3); - list.Add(Fail4); - } - - if (checkedLevel >= 5) - { - list.Add(Pass4); - list.Add(Fail5); - } - - return list; - } - - public static List GetCheckLevelListOfNeedCheck(SiteInfo siteInfo, bool isChecked, int checkedLevel) - { - if (isChecked) - { - checkedLevel = 5; - } - - var list = new List - { - DaiShen - }; - - if (checkedLevel >= 2) - { - list.Add(Pass1); - } - - if (checkedLevel >= 3) - { - list.Add(Pass2); - } - - if (checkedLevel >= 4) - { - list.Add(Pass3); - } - - if (checkedLevel >= 5) - { - list.Add(Pass4); - } - - return list; - } - - public static string GetLevelName(int level, SiteInfo siteInfo) - { - var retval = string.Empty; - if (level == CaoGao) - { - retval = "草稿"; - } - else if (level == DaiShen) - { - retval = "待审核"; - } - else if (level == Pass1) - { - retval = "初审通过"; - } - else if (level == Pass2) - { - retval = "二审通过"; - } - else if (level == Pass3) - { - retval = "三审通过"; - } - else if (level == Pass4) - { - retval = "四审通过"; - } - else if (level == Pass5) - { - retval = "终审通过"; - } - else if (level == Fail1) - { - retval = "初审退稿"; - } - else if (level == Fail2) - { - retval = "二审退稿"; - } - else if (level == Fail3) - { - retval = "三审退稿"; - } - else if (level == Fail4) - { - retval = "四审退稿"; - } - else if (level == Fail5) - { - retval = "终审退稿"; - } - else if (level == NotChange) - { - retval = "保持不变"; - } - - if (siteInfo.Additional.IsCheckContentLevel) - { - if (siteInfo.Additional.CheckContentLevel <= level) - { - retval = "终审通过"; - } - } - else - { - if (level > 1) - { - retval = "终审通过"; - } - } - - return retval; - } - } - - public class Level - { - public const string CaoGao = "草稿";//草稿 - public const string DaiShen = "待审核";//待审 - public const string YiShenHe = "已审核";//已审核 - - public const string NotChange = "保持不变";//保持不变 - } - - public class Level5 - { - public const string Pass1 = "初审通过,等待二审"; - public const string Pass2 = "二审通过,等待三审"; - public const string Pass3 = "三审通过,等待四审"; - public const string Pass4 = "四审通过,等待终审"; - public const string Pass5 = "终审通过"; - - public const string Fail1 = "初审退稿"; - public const string Fail2 = "二审退稿"; - public const string Fail3 = "三审退稿"; - public const string Fail4 = "四审退稿"; - public const string Fail5 = "终审退稿"; - } - - public class Level4 - { - public const string Pass1 = "初审通过,等待二审"; - public const string Pass2 = "二审通过,等待三审"; - public const string Pass3 = "三审通过,等待终审"; - public const string Pass4 = "终审通过"; - - public const string Fail1 = "初审退稿"; - public const string Fail2 = "二审退稿"; - public const string Fail3 = "三审退稿"; - public const string Fail4 = "终审退稿"; - } - - public class Level3 - { - public const string Pass1 = "初审通过,等待二审"; - public const string Pass2 = "二审通过,等待终审"; - public const string Pass3 = "终审通过"; - - public const string Fail1 = "初审退稿"; - public const string Fail2 = "二审退稿"; - public const string Fail3 = "终审退稿"; - } - - public class Level2 - { - public const string Pass1 = "初审通过,等待终审"; - public const string Pass2 = "终审通过"; - - public const string Fail1 = "初审退稿"; - public const string Fail2 = "终审退稿"; - } - - public class Level1 - { - public const string Pass1 = "终审通过"; - - public const string Fail1 = "终审退稿"; - } - - public static void LoadContentLevelToEdit(ListControl listControl, SiteInfo siteInfo, int channelId, ContentInfo contentInfo, bool isChecked, int checkedLevel) - { - var checkContentLevel = siteInfo.Additional.CheckContentLevel; - if (isChecked) - { - checkedLevel = checkContentLevel; - } - - ListItem listItem; - - var isCheckable = false; - if (contentInfo != null) - { - isCheckable = IsCheckable(siteInfo, channelId, contentInfo.IsChecked, contentInfo.CheckedLevel, isChecked, checkedLevel); - if (isCheckable) - { - listItem = new ListItem(Level.NotChange, LevelInt.NotChange.ToString()); - listControl.Items.Add(listItem); - } - } - - listItem = new ListItem(Level.CaoGao, LevelInt.CaoGao.ToString()); - listControl.Items.Add(listItem); - listItem = new ListItem(Level.DaiShen, LevelInt.DaiShen.ToString()); - listControl.Items.Add(listItem); - - if (checkContentLevel == 0 || checkContentLevel == 1) - { - listItem = new ListItem(Level1.Pass1, LevelInt.Pass1.ToString()) - { - Enabled = isChecked - }; - listControl.Items.Add(listItem); - } - else if (checkContentLevel == 2) - { - listItem = new ListItem(Level2.Pass1, LevelInt.Pass1.ToString()) - { - Enabled = checkedLevel >= 1 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level2.Pass2, LevelInt.Pass2.ToString()) - { - Enabled = isChecked - }; - listControl.Items.Add(listItem); - } - else if (checkContentLevel == 3) - { - listItem = new ListItem(Level3.Pass1, LevelInt.Pass1.ToString()) - { - Enabled = checkedLevel >= 1 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level3.Pass2, LevelInt.Pass2.ToString()) - { - Enabled = checkedLevel >= 2 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level3.Pass3, LevelInt.Pass3.ToString()) - { - Enabled = isChecked - }; - listControl.Items.Add(listItem); - } - else if (checkContentLevel == 4) - { - listItem = new ListItem(Level4.Pass1, LevelInt.Pass1.ToString()) - { - Enabled = checkedLevel >= 1 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level4.Pass2, LevelInt.Pass2.ToString()) - { - Enabled = checkedLevel >= 2 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level4.Pass3, LevelInt.Pass3.ToString()) - { - Enabled = checkedLevel >= 3 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level4.Pass4, LevelInt.Pass4.ToString()) - { - Enabled = isChecked - }; - listControl.Items.Add(listItem); - } - else if (checkContentLevel == 5) - { - listItem = new ListItem(Level5.Pass1, LevelInt.Pass1.ToString()) - { - Enabled = checkedLevel >= 1 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level5.Pass2, LevelInt.Pass2.ToString()) - { - Enabled = checkedLevel >= 2 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level5.Pass3, LevelInt.Pass3.ToString()) - { - Enabled = checkedLevel >= 3 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level5.Pass4, LevelInt.Pass4.ToString()) - { - Enabled = checkedLevel >= 4 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level5.Pass5, LevelInt.Pass5.ToString()) - { - Enabled = isChecked - }; - listControl.Items.Add(listItem); - } - - if (contentInfo == null) - { - ControlUtils.SelectSingleItem(listControl, checkedLevel.ToString()); - } - else - { - ControlUtils.SelectSingleItem(listControl, - isCheckable ? LevelInt.NotChange.ToString() : checkedLevel.ToString()); - } - } - - public static void LoadContentLevelToList(ListControl listControl, SiteInfo siteInfo, int siteId, bool isChecked, int checkedLevel) - { - var checkContentLevel = siteInfo.Additional.CheckContentLevel; - - if (isChecked) - { - checkedLevel = checkContentLevel; - } - - var listItem = new ListItem("全部", String.Empty); - listControl.Items.Add(listItem); - - listItem = new ListItem(Level.DaiShen, LevelInt.DaiShen.ToString()); - listControl.Items.Add(listItem); - - if (checkContentLevel == 1) - { - if (isChecked) - { - listItem = new ListItem(Level1.Fail1, LevelInt.Fail1.ToString()); - listControl.Items.Add(listItem); - } - } - else if (checkContentLevel == 2) - { - if (checkedLevel >= 1) - { - listItem = new ListItem(Level2.Fail1, LevelInt.Fail1.ToString()); - listControl.Items.Add(listItem); - } - - if (isChecked) - { - listItem = new ListItem(Level2.Fail2, LevelInt.Fail2.ToString()); - listControl.Items.Add(listItem); - } - } - else if (checkContentLevel == 3) - { - if (checkedLevel >= 1) - { - listItem = new ListItem(Level3.Fail1, LevelInt.Fail1.ToString()); - listControl.Items.Add(listItem); - } - - if (checkedLevel >= 2) - { - listItem = new ListItem(Level3.Fail2, LevelInt.Fail2.ToString()); - listControl.Items.Add(listItem); - } - - if (isChecked) - { - listItem = new ListItem(Level3.Fail3, LevelInt.Fail3.ToString()); - listControl.Items.Add(listItem); - } - } - else if (checkContentLevel == 4) - { - if (checkedLevel >= 1) - { - listItem = new ListItem(Level4.Fail1, LevelInt.Fail1.ToString()); - listControl.Items.Add(listItem); - } - - if (checkedLevel >= 2) - { - listItem = new ListItem(Level4.Fail2, LevelInt.Fail2.ToString()); - listControl.Items.Add(listItem); - } - - if (checkedLevel >= 3) - { - listItem = new ListItem(Level4.Fail3, LevelInt.Fail3.ToString()); - listControl.Items.Add(listItem); - } - - if (isChecked) - { - listItem = new ListItem(Level4.Fail4, LevelInt.Fail4.ToString()); - listControl.Items.Add(listItem); - } - } - else if (checkContentLevel == 5) - { - if (checkedLevel >= 1) - { - listItem = new ListItem(Level5.Fail1, LevelInt.Fail1.ToString()); - listControl.Items.Add(listItem); - } - - if (checkedLevel >= 2) - { - listItem = new ListItem(Level5.Fail2, LevelInt.Fail2.ToString()); - listControl.Items.Add(listItem); - } - - if (checkedLevel >= 3) - { - listItem = new ListItem(Level5.Fail3, LevelInt.Fail3.ToString()); - listControl.Items.Add(listItem); - } - - if (checkedLevel >= 4) - { - listItem = new ListItem(Level5.Fail4, LevelInt.Fail4.ToString()); - listControl.Items.Add(listItem); - } - - if (isChecked) - { - listItem = new ListItem(Level5.Fail5, LevelInt.Fail5.ToString()); - listControl.Items.Add(listItem); - } - } - - if (checkContentLevel == 2) - { - if (checkedLevel >= 1) - { - listItem = new ListItem(Level2.Pass1, LevelInt.Pass1.ToString()); - listControl.Items.Add(listItem); - } - } - else if (checkContentLevel == 3) - { - if (checkedLevel >= 1) - { - listItem = new ListItem(Level3.Pass1, LevelInt.Pass1.ToString()); - listControl.Items.Add(listItem); - } - - if (checkedLevel >= 2) - { - listItem = new ListItem(Level3.Pass2, LevelInt.Pass2.ToString()); - listControl.Items.Add(listItem); - } - } - else if (checkContentLevel == 4) - { - if (checkedLevel >= 1) - { - listItem = new ListItem(Level4.Pass1, LevelInt.Pass1.ToString()); - listControl.Items.Add(listItem); - } - - if (checkedLevel >= 2) - { - listItem = new ListItem(Level4.Pass2, LevelInt.Pass2.ToString()); - listControl.Items.Add(listItem); - } - - if (checkedLevel >= 3) - { - listItem = new ListItem(Level4.Pass3, LevelInt.Pass3.ToString()); - listControl.Items.Add(listItem); - } - } - else if (checkContentLevel == 5) - { - if (checkedLevel >= 2) - { - listItem = new ListItem(Level5.Pass1, LevelInt.Pass1.ToString()); - listControl.Items.Add(listItem); - } - - if (checkedLevel >= 3) - { - listItem = new ListItem(Level5.Pass2, LevelInt.Pass2.ToString()); - listControl.Items.Add(listItem); - } - - if (checkedLevel >= 4) - { - listItem = new ListItem(Level5.Pass3, LevelInt.Pass3.ToString()); - listControl.Items.Add(listItem); - } - - if (checkedLevel >= 5) - { - listItem = new ListItem(Level5.Pass4, LevelInt.Pass4.ToString()); - listControl.Items.Add(listItem); - } - } - - ControlUtils.SelectSingleItem(listControl, string.Empty); - } - - public static void LoadContentLevelToCheck(ListControl listControl, SiteInfo siteInfo, bool isChecked, int checkedLevel) - { - var checkContentLevel = siteInfo.Additional.CheckContentLevel; - if (isChecked) - { - checkedLevel = checkContentLevel; - } - - var listItem = new ListItem(Level.CaoGao, LevelInt.CaoGao.ToString()); - listControl.Items.Add(listItem); - - listItem = new ListItem(Level.DaiShen, LevelInt.DaiShen.ToString()); - listControl.Items.Add(listItem); - - if (checkContentLevel == 1) - { - listItem = new ListItem(Level1.Fail1, LevelInt.Fail1.ToString()) - { - Enabled = isChecked - }; - listControl.Items.Add(listItem); - } - else if (checkContentLevel == 2) - { - listItem = new ListItem(Level2.Fail1, LevelInt.Fail1.ToString()) - { - Enabled = checkedLevel >= 1 - }; - listControl.Items.Add(listItem); - - listItem = new ListItem(Level2.Fail2, LevelInt.Fail2.ToString()) - { - Enabled = isChecked - }; - listControl.Items.Add(listItem); - } - else if (checkContentLevel == 3) - { - listItem = new ListItem(Level3.Fail1, LevelInt.Fail1.ToString()) - { - Enabled = checkedLevel >= 1 - }; - listControl.Items.Add(listItem); - - listItem = new ListItem(Level3.Fail2, LevelInt.Fail2.ToString()) - { - Enabled = checkedLevel >= 2 - }; - listControl.Items.Add(listItem); - - listItem = new ListItem(Level3.Fail3, LevelInt.Fail3.ToString()) - { - Enabled = isChecked - }; - listControl.Items.Add(listItem); - } - else if (checkContentLevel == 4) - { - listItem = new ListItem(Level4.Fail1, LevelInt.Fail1.ToString()) - { - Enabled = checkedLevel >= 1 - }; - listControl.Items.Add(listItem); - - listItem = new ListItem(Level4.Fail2, LevelInt.Fail2.ToString()) - { - Enabled = checkedLevel >= 2 - }; - listControl.Items.Add(listItem); - - listItem = new ListItem(Level4.Fail3, LevelInt.Fail3.ToString()) - { - Enabled = checkedLevel >= 3 - }; - listControl.Items.Add(listItem); - - listItem = new ListItem(Level4.Fail4, LevelInt.Fail4.ToString()) - { - Enabled = isChecked - }; - listControl.Items.Add(listItem); - } - else if (checkContentLevel == 5) - { - listItem = new ListItem(Level5.Fail1, LevelInt.Fail1.ToString()) - { - Enabled = checkedLevel >= 1 - }; - listControl.Items.Add(listItem); - - listItem = new ListItem(Level5.Fail2, LevelInt.Fail2.ToString()) - { - Enabled = checkedLevel >= 2 - }; - listControl.Items.Add(listItem); - - listItem = new ListItem(Level5.Fail3, LevelInt.Fail3.ToString()) - { - Enabled = checkedLevel >= 3 - }; - listControl.Items.Add(listItem); - - listItem = new ListItem(Level5.Fail4, LevelInt.Fail4.ToString()) - { - Enabled = checkedLevel >= 4 - }; - listControl.Items.Add(listItem); - - listItem = new ListItem(Level5.Fail5, LevelInt.Fail5.ToString()) - { - Enabled = isChecked - }; - listControl.Items.Add(listItem); - } - - if (checkContentLevel == 0 || checkContentLevel == 1) - { - listItem = new ListItem(Level1.Pass1, LevelInt.Pass1.ToString()) - { - Enabled = isChecked - }; - listControl.Items.Add(listItem); - } - else if (checkContentLevel == 2) - { - listItem = new ListItem(Level2.Pass1, LevelInt.Pass1.ToString()) - { - Enabled = checkedLevel >= 1 - }; - listControl.Items.Add(listItem); - - listItem = new ListItem(Level2.Pass2, LevelInt.Pass2.ToString()) - { - Enabled = isChecked - }; - listControl.Items.Add(listItem); - } - else if (checkContentLevel == 3) - { - listItem = new ListItem(Level3.Pass1, LevelInt.Pass1.ToString()) - { - Enabled = checkedLevel >= 1 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level3.Pass2, LevelInt.Pass2.ToString()) - { - Enabled = checkedLevel >= 2 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level3.Pass3, LevelInt.Pass3.ToString()) - { - Enabled = isChecked - }; - listControl.Items.Add(listItem); - } - else if (checkContentLevel == 4) - { - listItem = new ListItem(Level4.Pass1, LevelInt.Pass1.ToString()) - { - Enabled = checkedLevel >= 1 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level4.Pass2, LevelInt.Pass2.ToString()) - { - Enabled = checkedLevel >= 2 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level4.Pass3, LevelInt.Pass3.ToString()) - { - Enabled = checkedLevel >= 3 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level4.Pass4, LevelInt.Pass4.ToString()) - { - Enabled = isChecked - }; - listControl.Items.Add(listItem); - } - else if (checkContentLevel == 5) - { - listItem = new ListItem(Level5.Pass1, LevelInt.Pass1.ToString()) - { - Enabled = checkedLevel >= 1 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level5.Pass2, LevelInt.Pass2.ToString()) - { - Enabled = checkedLevel >= 2 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level5.Pass3, LevelInt.Pass3.ToString()) - { - Enabled = checkedLevel >= 3 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level5.Pass4, LevelInt.Pass4.ToString()) - { - Enabled = checkedLevel >= 4 - }; - listControl.Items.Add(listItem); - listItem = new ListItem(Level5.Pass5, LevelInt.Pass5.ToString()) - { - Enabled = isChecked - }; - listControl.Items.Add(listItem); - } - - ControlUtils.SelectSingleItem(listControl, checkedLevel.ToString()); - } - - public static List GetCheckLevelToPassList(SiteInfo siteInfo) - { - var list = new List(); - var checkContentLevel = siteInfo.Additional.CheckContentLevel; - - list.Add(LevelInt.DaiShen); - - if (checkContentLevel == 0 || checkContentLevel == 1) - { - list.Add(LevelInt.Pass1); - } - else if (checkContentLevel == 2) - { - list.Add(LevelInt.Pass1); - list.Add(LevelInt.Pass2); - } - else if (checkContentLevel == 3) - { - list.Add(LevelInt.Pass1); - list.Add(LevelInt.Pass2); - list.Add(LevelInt.Pass3); - } - else if (checkContentLevel == 4) - { - list.Add(LevelInt.Pass1); - list.Add(LevelInt.Pass2); - list.Add(LevelInt.Pass3); - list.Add(LevelInt.Pass4); - } - else if (checkContentLevel == 5) - { - list.Add(LevelInt.Pass1); - list.Add(LevelInt.Pass2); - list.Add(LevelInt.Pass3); - list.Add(LevelInt.Pass4); - list.Add(LevelInt.Pass5); - } - - return list; - } - - public static string GetCheckState(SiteInfo siteInfo, bool isChecked, int level) - { - if (isChecked) - { - return Level.YiShenHe; - } - - var retval = String.Empty; - - if (level == LevelInt.CaoGao) - { - retval = Level.CaoGao; - } - else if (level == LevelInt.DaiShen) - { - retval = Level.DaiShen; - } - else - { - var checkContentLevel = siteInfo.Additional.CheckContentLevel; - - if (checkContentLevel == 1) - { - if (level == LevelInt.Fail1) - { - retval = Level1.Fail1; - } - } - else if (checkContentLevel == 2) - { - if (level == LevelInt.Pass1) - { - retval = Level2.Pass1; - } - else if (level == LevelInt.Fail1) - { - retval = Level2.Fail1; - } - else if (level == LevelInt.Fail2) - { - retval = Level2.Fail2; - } - } - else if (checkContentLevel == 3) - { - if (level == LevelInt.Pass1) - { - retval = Level3.Pass1; - } - else if (level == LevelInt.Pass2) - { - retval = Level3.Pass2; - } - else if (level == LevelInt.Fail1) - { - retval = Level3.Fail1; - } - else if (level == LevelInt.Fail2) - { - retval = Level3.Fail2; - } - else if (level == LevelInt.Fail3) - { - retval = Level3.Fail3; - } - } - else if (checkContentLevel == 4) - { - if (level == LevelInt.Pass1) - { - retval = Level4.Pass1; - } - else if (level == LevelInt.Pass2) - { - retval = Level4.Pass2; - } - else if (level == LevelInt.Pass3) - { - retval = Level4.Pass3; - } - else if (level == LevelInt.Fail1) - { - retval = Level4.Fail1; - } - else if (level == LevelInt.Fail2) - { - retval = Level4.Fail2; - } - else if (level == LevelInt.Fail3) - { - retval = Level4.Fail3; - } - else if (level == LevelInt.Fail4) - { - retval = Level4.Fail4; - } - } - else if (checkContentLevel == 5) - { - if (level == LevelInt.Pass1) - { - retval = Level5.Pass1; - } - else if (level == LevelInt.Pass2) - { - retval = Level5.Pass2; - } - else if (level == LevelInt.Pass3) - { - retval = Level5.Pass3; - } - else if (level == LevelInt.Pass4) - { - retval = Level5.Pass4; - } - else if (level == LevelInt.Fail1) - { - retval = Level5.Fail1; - } - else if (level == LevelInt.Fail2) - { - retval = Level5.Fail2; - } - else if (level == LevelInt.Fail3) - { - retval = Level5.Fail3; - } - else if (level == LevelInt.Fail4) - { - retval = Level5.Fail4; - } - else if (level == LevelInt.Fail5) - { - retval = Level5.Fail5; - } - } - - if (String.IsNullOrEmpty(retval)) - { - if (checkContentLevel == 1) - { - retval = Level.DaiShen; - } - else if (checkContentLevel == 2) - { - retval = Level2.Pass1; - } - else if (checkContentLevel == 3) - { - retval = Level3.Pass2; - } - else if (checkContentLevel == 4) - { - retval = Level4.Pass3; - } - } - } - - return $"{retval}"; - } - - public static bool IsCheckable(SiteInfo siteInfo, int channelId, bool contentIsChecked, int contentCheckLevel, bool isChecked, int checkedLevel) - { - if (isChecked || checkedLevel >= 5) - { - return true; - } - if (contentIsChecked) - { - return false; - } - if (checkedLevel == 0) - { - return false; - } - if (checkedLevel == 1) - { - if (contentCheckLevel == LevelInt.CaoGao || contentCheckLevel == LevelInt.DaiShen || contentCheckLevel == LevelInt.Pass1 || contentCheckLevel == LevelInt.Fail1) - { - return true; - } - return false; - } - if (checkedLevel == 2) - { - if (contentCheckLevel == LevelInt.CaoGao || contentCheckLevel == LevelInt.DaiShen || contentCheckLevel == LevelInt.Pass1 || contentCheckLevel == LevelInt.Pass2 || contentCheckLevel == LevelInt.Fail1 || contentCheckLevel == LevelInt.Fail2) - { - return true; - } - return false; - } - if (checkedLevel == 3) - { - if (contentCheckLevel == LevelInt.CaoGao || contentCheckLevel == LevelInt.DaiShen || contentCheckLevel == LevelInt.Pass1 || contentCheckLevel == LevelInt.Pass2 || contentCheckLevel == LevelInt.Pass3 || contentCheckLevel == LevelInt.Fail1 || contentCheckLevel == LevelInt.Fail2 || contentCheckLevel == LevelInt.Fail3) - { - return true; - } - return false; - } - if (checkedLevel == 4) - { - if (contentCheckLevel == LevelInt.CaoGao || contentCheckLevel == LevelInt.DaiShen || contentCheckLevel == LevelInt.Pass1 || contentCheckLevel == LevelInt.Pass2 || contentCheckLevel == LevelInt.Pass3 || contentCheckLevel == LevelInt.Pass4 || contentCheckLevel == LevelInt.Fail1 || contentCheckLevel == LevelInt.Fail2 || contentCheckLevel == LevelInt.Fail3 || contentCheckLevel == LevelInt.Fail4) - { - return true; - } - return false; - } - - return false; - } - - public static KeyValuePair GetUserCheckLevel(PermissionManager permissionManager, SiteInfo siteInfo, int channelId) - { - if (permissionManager.IsSystemAdministrator) - { - return new KeyValuePair(true, siteInfo.Additional.CheckContentLevel); - } - - var isChecked = false; - var checkedLevel = 0; - if (siteInfo.Additional.IsCheckContentLevel == false) - { - if (permissionManager.HasChannelPermissions(siteInfo.Id, channelId, ConfigManager.ChannelPermissions.ContentCheck)) - { - isChecked = true; - } - } - else - { - if (permissionManager.HasChannelPermissions(siteInfo.Id, channelId, ConfigManager.ChannelPermissions.ContentCheckLevel5)) - { - isChecked = true; - } - else if (permissionManager.HasChannelPermissions(siteInfo.Id, channelId, ConfigManager.ChannelPermissions.ContentCheckLevel4)) - { - if (siteInfo.Additional.CheckContentLevel <= 4) - { - isChecked = true; - } - else - { - checkedLevel = 4; - } - } - else if (permissionManager.HasChannelPermissions(siteInfo.Id, channelId, ConfigManager.ChannelPermissions.ContentCheckLevel3)) - { - if (siteInfo.Additional.CheckContentLevel <= 3) - { - isChecked = true; - } - else - { - checkedLevel = 3; - } - } - else if (permissionManager.HasChannelPermissions(siteInfo.Id, channelId, ConfigManager.ChannelPermissions.ContentCheckLevel2)) - { - if (siteInfo.Additional.CheckContentLevel <= 2) - { - isChecked = true; - } - else - { - checkedLevel = 2; - } - } - else if (permissionManager.HasChannelPermissions(siteInfo.Id, channelId, ConfigManager.ChannelPermissions.ContentCheckLevel1)) - { - if (siteInfo.Additional.CheckContentLevel <= 1) - { - isChecked = true; - } - else - { - checkedLevel = 1; - } - } - else - { - checkedLevel = 0; - } - } - return new KeyValuePair(isChecked, checkedLevel); - } - - public static bool GetUserCheckLevel(PermissionManager permissionManager, SiteInfo siteInfo, int channelId, out int userCheckedLevel) - { - var checkContentLevel = siteInfo.Additional.CheckContentLevel; - - var pair = GetUserCheckLevel(permissionManager, siteInfo, channelId); - var isChecked = pair.Key; - var checkedLevel = pair.Value; - if (isChecked) - { - checkedLevel = checkContentLevel; - } - userCheckedLevel = checkedLevel; - return isChecked; - } - - public static List> GetUserCountListUnChecked(PermissionManager permissionManager) - { - var list = new List>(); - - var tableNameList = DataProvider.TableDao.GetTableNameListCreatedInDb(); - - foreach (var tableName in tableNameList) - { - list.AddRange(GetUserCountListUnChecked(permissionManager, tableName)); - } - - return list; - } - - private static List> GetUserCountListUnChecked(PermissionManager permissionManager, string tableName) - { - return DataProvider.ContentDao.GetCountListUnChecked(permissionManager, tableName); - } - } -} diff --git a/SiteServer.CMS/Core/ContentUtility.cs b/SiteServer.CMS/Core/ContentUtility.cs deleted file mode 100644 index 84899c33b..000000000 --- a/SiteServer.CMS/Core/ContentUtility.cs +++ /dev/null @@ -1,804 +0,0 @@ -using System; -using SiteServer.CMS.Model; -using System.Text; -using SiteServer.Utils; -using System.Web.UI.WebControls; -using System.Collections.Generic; -using System.Collections.Specialized; -using SiteServer.CMS.Core.Create; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.Plugin; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Core -{ - public class ContentUtility - { - private ContentUtility() - { - } - - public static string PagePlaceHolder = "[SITESERVER_PAGE]";//内容翻页展位符 - - public static string TextEditorContentEncode(SiteInfo siteInfo, string content) - { - if (siteInfo == null) return content; - - var url = siteInfo.Additional.WebUrl; - if (siteInfo.Additional.IsSaveImageInTextEditor && !string.IsNullOrEmpty(content)) - { - content = PathUtility.SaveImage(siteInfo, content); - } - - if (string.IsNullOrEmpty(url) || url == "/") - { - return content; - } - - var builder = new StringBuilder(content); - - StringUtils.ReplaceHrefOrSrc(builder, url, "@"); - - builder.Replace("@'@", "'@"); - builder.Replace("@\"@", "\"@"); - - return builder.ToString(); - } - - public static string TextEditorContentDecode(SiteInfo siteInfo, string content, bool isLocal) - { - if (siteInfo == null) return content; - - var builder = new StringBuilder(content); - - var virtualAssetsUrl = $"@/{siteInfo.Additional.AssetsDir}"; - string assetsUrl; - if (isLocal) - { - assetsUrl = PageUtility.GetLocalSiteUrl(siteInfo, - siteInfo.Additional.AssetsDir); - } - else - { - assetsUrl = siteInfo.Additional.AssetsUrl; - } - StringUtils.ReplaceHrefOrSrc(builder, virtualAssetsUrl, assetsUrl); - StringUtils.ReplaceHrefOrSrc(builder, "@", siteInfo.Additional.WebUrl); - - builder.Replace(" ", " "); - - return builder.ToString(); - } - - public static string GetTitleFormatString(bool isStrong, bool isEm, bool isU, string color) - { - return $"{isStrong}_{isEm}_{isU}_{color}"; - } - - public static bool SetTitleFormatControls(string titleFormatString, CheckBox formatStrong, CheckBox formatEm, CheckBox formatU, TextBox formatColor) - { - var isTitleFormatted = false; - if (!string.IsNullOrEmpty(titleFormatString)) - { - var formats = titleFormatString.Split('_'); - if (formats.Length == 4) - { - formatStrong.Checked = TranslateUtils.ToBool(formats[0]); - formatEm.Checked = TranslateUtils.ToBool(formats[1]); - formatU.Checked = TranslateUtils.ToBool(formats[2]); - formatColor.Text = formats[3]; - if (formatStrong.Checked || formatEm.Checked || formatU.Checked || !string.IsNullOrEmpty(formatColor.Text)) - { - isTitleFormatted = true; - } - } - } - return isTitleFormatted; - } - - public static void SetTitleFormatControls(string titleFormatString, out bool formatStrong, out bool formatEm, out bool formatU, out string formatColor) - { - formatStrong = formatEm = formatU = false; - formatColor = string.Empty; - - if (!string.IsNullOrEmpty(titleFormatString)) - { - var formats = titleFormatString.Split('_'); - if (formats.Length == 4) - { - formatStrong = TranslateUtils.ToBool(formats[0]); - formatEm = TranslateUtils.ToBool(formats[1]); - formatU = TranslateUtils.ToBool(formats[2]); - formatColor = formats[3]; - } - } - } - - public static string FormatTitle(string titleFormatString, string title) - { - var formattedTitle = title; - if (!string.IsNullOrEmpty(titleFormatString)) - { - var formats = titleFormatString.Split('_'); - if (formats.Length == 4) - { - var isStrong = TranslateUtils.ToBool(formats[0]); - var isEm = TranslateUtils.ToBool(formats[1]); - var isU = TranslateUtils.ToBool(formats[2]); - var color = formats[3]; - - if (!string.IsNullOrEmpty(color)) - { - if (!color.StartsWith("#")) - { - color = "#" + color; - } - formattedTitle = $@"{formattedTitle}"; - } - if (isStrong) - { - formattedTitle = $"{formattedTitle}"; - } - if (isEm) - { - formattedTitle = $"{formattedTitle}"; - } - if (isU) - { - formattedTitle = $"{formattedTitle}"; - } - } - } - return formattedTitle; - } - - public static void PutImagePaths(SiteInfo siteInfo, ContentInfo contentInfo, NameValueCollection collection) - { - if (contentInfo == null) return; - - var imageUrl = contentInfo.GetString(BackgroundContentAttribute.ImageUrl); - var videoUrl = contentInfo.GetString(BackgroundContentAttribute.VideoUrl); - var fileUrl = contentInfo.GetString(BackgroundContentAttribute.FileUrl); - var content = contentInfo.GetString(BackgroundContentAttribute.Content); - - if (!string.IsNullOrEmpty(imageUrl) && PageUtility.IsVirtualUrl(imageUrl)) - { - collection[imageUrl] = PathUtility.MapPath(siteInfo, imageUrl); - } - if (!string.IsNullOrEmpty(videoUrl) && PageUtility.IsVirtualUrl(videoUrl)) - { - collection[videoUrl] = PathUtility.MapPath(siteInfo, videoUrl); - } - if (!string.IsNullOrEmpty(fileUrl) && PageUtility.IsVirtualUrl(fileUrl)) - { - collection[fileUrl] = PathUtility.MapPath(siteInfo, fileUrl); - } - - var srcList = RegexUtils.GetOriginalImageSrcs(content); - foreach (var src in srcList) - { - if (PageUtility.IsVirtualUrl(src)) - { - collection[src] = PathUtility.MapPath(siteInfo, src); - } - } - } - - public static string GetAutoPageContent(string content, int pageWordNum) - { - var builder = new StringBuilder(); - if (!string.IsNullOrEmpty(content)) - { - content = content.Replace(PagePlaceHolder, string.Empty); - AutoPage(builder, content, pageWordNum); - } - return builder.ToString(); - } - - private static void AutoPage(StringBuilder builder, string content, int pageWordNum) - { - if (content.Length > pageWordNum) - { - var i = content.IndexOf("

    ", pageWordNum, StringComparison.Ordinal); - if (i == -1) - { - i = content.IndexOf("

    ", pageWordNum, StringComparison.Ordinal); - } - - if (i != -1) - { - var start = i + 4; - builder.Append(content.Substring(0, start)); - content = content.Substring(start); - if (!string.IsNullOrEmpty(content)) - { - builder.Append(PagePlaceHolder); - AutoPage(builder, content, pageWordNum); - } - } - else - { - builder.Append(content); - } - } - else - { - builder.Append(content); - } - } - - public static int GetRealContentId(string tableName, int contentId) - { - string linkUrl; - var referenceId = DataProvider.ContentDao.GetReferenceId(tableName, contentId, out linkUrl); - return referenceId > 0 ? referenceId : contentId; - } - - public static List GetAllTableStyleInfoList(List tableStyleInfoList) - { - var list = new List - { - new TableStyleInfo - { - AttributeName = ContentAttribute.Id, - DisplayName = "编号" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.Title, - DisplayName = "标题" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.LinkUrl, - DisplayName = "外部链接" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.AddDate, - DisplayName = "添加时间" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.LastEditDate, - DisplayName = "修改时间" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.GroupNameCollection, - DisplayName = "内容组" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.Tags, - DisplayName = "标签" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.AddUserName, - DisplayName = "添加人" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.LastEditUserName, - DisplayName = "修改人" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.CheckUserName, - DisplayName = "审核人" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.CheckCheckDate, - DisplayName = "审核时间" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.CheckReasons, - DisplayName = "审核原因" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.SourceId, - DisplayName = "来源标识" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.Hits, - DisplayName = "点击量" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.HitsByDay, - DisplayName = "日点击" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.HitsByWeek, - DisplayName = "周点击" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.HitsByMonth, - DisplayName = "月点击" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.LastHitsDate, - DisplayName = "最后点击时间" - } - }; - - if (tableStyleInfoList != null) - { - list.InsertRange(2, tableStyleInfoList); - } - - return list; - } - - public static List GetEditableTableStyleInfoList(List tableStyleInfoList) - { - var list = new List - { - new TableStyleInfo - { - AttributeName = ContentAttribute.Title, - InputType = InputType.Text, - DisplayName = "标题" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.LinkUrl, - InputType = InputType.Text, - DisplayName = "外部链接" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.AddDate, - InputType = InputType.DateTime, - DisplayName = "添加时间" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.GroupNameCollection, - InputType = InputType.CheckBox, - DisplayName = "内容组" - }, - new TableStyleInfo - { - AttributeName = ContentAttribute.Tags, - InputType = InputType.CheckBox, - DisplayName = "标签" - } - }; - - if (tableStyleInfoList != null) - { - list.InsertRange(2, tableStyleInfoList); - } - - return list; - } - - public static bool AfterContentAdded(SiteInfo siteInfo, ChannelInfo channelInfo, int contentId, bool isCrossSiteTrans, bool isAutomatic) - { - var isTranslated = false; - if (isCrossSiteTrans && isAutomatic) - { - var targetSiteId = 0; - - if (channelInfo.Additional.TransType == ECrossSiteTransType.SpecifiedSite) - { - targetSiteId = channelInfo.Additional.TransSiteId; - } - else if (channelInfo.Additional.TransType == ECrossSiteTransType.SelfSite) - { - targetSiteId = siteInfo.Id; - } - else if (channelInfo.Additional.TransType == ECrossSiteTransType.ParentSite) - { - targetSiteId = SiteManager.GetParentSiteId(siteInfo.Id); - } - - if (targetSiteId > 0) - { - var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); - if (targetSiteInfo != null) - { - var targetChannelIdArrayList = TranslateUtils.StringCollectionToIntList(channelInfo.Additional.TransChannelIds); - if (targetChannelIdArrayList.Count > 0) - { - foreach (var targetChannelId in targetChannelIdArrayList) - { - CrossSiteTransUtility.TransContentInfo(siteInfo, channelInfo, contentId, targetSiteInfo, targetChannelId); - isTranslated = true; - } - } - } - } - } - - foreach (var service in PluginManager.Services) - { - try - { - service.OnContentAddCompleted(new ContentEventArgs(siteInfo.Id, channelInfo.Id, contentId)); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(service.PluginId, ex, nameof(service.OnContentAddCompleted)); - } - } - - return isTranslated; - } - - public static void Translate(SiteInfo siteInfo, int channelId, int contentId, string translateCollection, ETranslateContentType translateType, string administratorName) - { - var translateList = TranslateUtils.StringCollectionToStringList(translateCollection); - foreach (var translate in translateList) - { - if (string.IsNullOrEmpty(translate)) continue; - - var translates = translate.Split('_'); - if (translates.Length != 2) continue; - - var targetSiteId = TranslateUtils.ToInt(translates[0]); - var targetChannelId = TranslateUtils.ToInt(translates[1]); - - Translate(siteInfo, channelId, contentId, targetSiteId, targetChannelId, translateType, administratorName); - } - } - - public static void Translate(SiteInfo siteInfo, int channelId, int contentId, int targetSiteId, int targetChannelId, ETranslateContentType translateType, string administratorName) - { - if (siteInfo == null || channelId <= 0 || contentId <= 0 || targetSiteId <= 0 || targetChannelId <= 0) return; - - var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); - - var targetTableName = ChannelManager.GetTableName(targetSiteInfo, targetChannelId); - - var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); - - var contentInfo = DataProvider.ContentDao.GetContentInfo(tableName, contentId); - - if (contentInfo == null) return; - - if (translateType == ETranslateContentType.Copy) - { - FileUtility.MoveFileByContentInfo(siteInfo, targetSiteInfo, contentInfo); - - contentInfo.SiteId = targetSiteId; - contentInfo.SourceId = contentInfo.ChannelId; - contentInfo.ChannelId = targetChannelId; - contentInfo.Set(ContentAttribute.TranslateContentType, ETranslateContentType.Copy.ToString()); - //contentInfo.Attributes.Add(ContentAttribute.TranslateContentType, ETranslateContentType.Copy.ToString()); - var theContentId = DataProvider.ContentDao.Insert(targetTableName, targetSiteInfo, contentInfo); - - foreach (var service in PluginManager.Services) - { - try - { - service.OnContentTranslateCompleted(new ContentTranslateEventArgs(siteInfo.Id, channelInfo.Id, contentId, targetSiteId, targetChannelId, theContentId)); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(service.PluginId, ex, nameof(service.OnContentTranslateCompleted)); - } - } - - CreateManager.CreateContentAndTrigger(targetSiteInfo.Id, contentInfo.ChannelId, theContentId); - } - else if (translateType == ETranslateContentType.Cut) - { - FileUtility.MoveFileByContentInfo(siteInfo, targetSiteInfo, contentInfo); - - contentInfo.SiteId = targetSiteId; - contentInfo.SourceId = contentInfo.ChannelId; - contentInfo.ChannelId = targetChannelId; - contentInfo.Set(ContentAttribute.TranslateContentType, ETranslateContentType.Cut.ToString()); - //contentInfo.Attributes.Add(ContentAttribute.TranslateContentType, ETranslateContentType.Cut.ToString()); - - var newContentId = DataProvider.ContentDao.Insert(targetTableName, targetSiteInfo, contentInfo); - DataProvider.ContentDao.DeleteContents(siteInfo.Id, tableName, TranslateUtils.ToIntList(contentId), channelId); - - DataProvider.ChannelDao.UpdateContentNum(siteInfo, channelId, true); - DataProvider.ChannelDao.UpdateContentNum(targetSiteInfo, targetChannelId, true); - - foreach (var service in PluginManager.Services) - { - try - { - service.OnContentTranslateCompleted(new ContentTranslateEventArgs(siteInfo.Id, channelInfo.Id, contentId, targetSiteId, targetChannelId, newContentId)); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(service.PluginId, ex, nameof(service.OnContentTranslateCompleted)); - } - - try - { - service.OnContentDeleteCompleted(new ContentEventArgs(siteInfo.Id, channelInfo.Id, contentId)); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(service.PluginId, ex, nameof(service.OnContentDeleteCompleted)); - } - } - - CreateManager.CreateContentAndTrigger(targetSiteInfo.Id, contentInfo.ChannelId, newContentId); - } - else if (translateType == ETranslateContentType.Reference) - { - if (contentInfo.ReferenceId != 0) return; - - contentInfo.SiteId = targetSiteId; - contentInfo.SourceId = contentInfo.ChannelId; - contentInfo.ChannelId = targetChannelId; - contentInfo.ReferenceId = contentId; - contentInfo.Set(ContentAttribute.TranslateContentType, ETranslateContentType.Reference.ToString()); - //contentInfo.Attributes.Add(ContentAttribute.TranslateContentType, ETranslateContentType.Reference.ToString()); - DataProvider.ContentDao.Insert(targetTableName, targetSiteInfo, contentInfo); - } - else if (translateType == ETranslateContentType.ReferenceContent) - { - if (contentInfo.ReferenceId != 0) return; - - FileUtility.MoveFileByContentInfo(siteInfo, targetSiteInfo, contentInfo); - - contentInfo.SiteId = targetSiteId; - contentInfo.SourceId = contentInfo.ChannelId; - contentInfo.ChannelId = targetChannelId; - contentInfo.ReferenceId = contentId; - contentInfo.Set(ContentAttribute.TranslateContentType, ETranslateContentType.ReferenceContent.ToString()); - var theContentId = DataProvider.ContentDao.Insert(targetTableName, targetSiteInfo, contentInfo); - - foreach (var service in PluginManager.Services) - { - try - { - service.OnContentTranslateCompleted(new ContentTranslateEventArgs(siteInfo.Id, channelInfo.Id, contentId, targetSiteId, targetChannelId, theContentId)); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(service.PluginId, ex, nameof(service.OnContentTranslateCompleted)); - } - } - - CreateManager.CreateContentAndTrigger(targetSiteInfo.Id, contentInfo.ChannelId, theContentId); - } - } - - public static Dictionary> GetIDsDictionary(NameValueCollection queryString) - { - var dic = new Dictionary>(); - - if (!string.IsNullOrEmpty(queryString["IDsCollection"])) - { - foreach (var ids in TranslateUtils.StringCollectionToStringList(queryString["IDsCollection"])) - { - var channelId = TranslateUtils.ToInt(ids.Split('_')[0]); - var contentId = TranslateUtils.ToInt(ids.Split('_')[1]); - var contentIdList = new List(); - if (dic.ContainsKey(channelId)) - { - contentIdList = dic[channelId]; - } - if (!contentIdList.Contains(contentId)) - { - contentIdList.Add(contentId); - } - - dic[channelId] = contentIdList; - } - } - else - { - var channelId = TranslateUtils.ToInt(queryString["channelId"]); - dic[channelId] = TranslateUtils.StringCollectionToIntList(queryString["contentIdCollection"]); - } - - return dic; - } - - public static Dictionary ContentToDictionary(ContentInfo contentInfo, string tableName, List relatedIdentities) - { - var dict = TranslateUtils.ObjectToDictionary(contentInfo); - dict.Remove("Attributes"); - - var styleInfoList = TableStyleManager.GetTableStyleInfoList(tableName, relatedIdentities); - foreach (var styleInfo in styleInfoList) - { - if (!dict.ContainsKey(styleInfo.AttributeName)) - { - dict[styleInfo.AttributeName] = contentInfo.GetString(styleInfo.AttributeName); - } - if (styleInfo.InputType == InputType.Image) - { - var extendName = ContentAttribute.GetExtendAttributeName(styleInfo.AttributeName); - var extendValue = contentInfo.GetString(extendName); - if (!string.IsNullOrEmpty(extendValue)) - { - dict[extendName] = extendValue; - } - } - } - - return dict; - } - - public static string GetTitleHtml(string titleFormat, string titleAjaxUrl) - { - var builder = new StringBuilder(); - var formatStrong = false; - var formatEm = false; - var formatU = false; - var formatColor = string.Empty; - if (titleFormat != null) - { - SetTitleFormatControls(titleFormat, out formatStrong, out formatEm, out formatU, out formatColor); - } - - builder.Append( - $@" - -"); - - builder.Append($@" -
    - - - - -
    -
    - - -
    - - - -"); - - builder.Append(@" - -
    "); - builder.Replace("[url]", titleAjaxUrl); - - return builder.ToString(); - } - - public static string GetTagsHtml(string tagsAjaxUrl) - { - const string tagScript = @" - -
    -"; - return tagScript.Replace("[url]", tagsAjaxUrl); - } - } -} diff --git a/SiteServer.CMS/Core/Converter.cs b/SiteServer.CMS/Core/Converter.cs deleted file mode 100644 index 1787472bf..000000000 --- a/SiteServer.CMS/Core/Converter.cs +++ /dev/null @@ -1,119 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web.UI.WebControls; -using SiteServer.CMS.Model; -using SiteServer.Utils; - -namespace SiteServer.CMS.Core -{ - /// - /// Convert ժҪ˵ - /// - public static class Converter - { - /// - /// 2004-1-202005-9-3 12:12:32ΪʽַתΪ - /// - public static DateTime ToDateTime(string dateTimeString) - { - if (string.IsNullOrEmpty(dateTimeString)) - { - return DateTime.Now; - } - var dateTimeStr = dateTimeString.Trim(); - - var year = DateTime.Now.Year; - var month = DateTime.Now.Month; - var day = DateTime.Now.Day; - var hour = DateTime.Now.Hour; - var minute = DateTime.Now.Minute; - var second = DateTime.Now.Second; - - if (dateTimeStr.IndexOf(" ", StringComparison.Ordinal) != -1) - { - var dateAndTimeArray = dateTimeStr.Split(' '); - if (dateAndTimeArray.Length == 2) - { - try - { - var arrayDate = dateAndTimeArray[0].Split('-'); - year = int.Parse(arrayDate[0]); - month = int.Parse(arrayDate[1]); - day = int.Parse(arrayDate[2]); - - var arrayTime = dateAndTimeArray[1].Split(':'); - hour = int.Parse(arrayTime[0]); - minute = int.Parse(arrayTime[1]); - second = int.Parse(arrayTime[2]); - } - catch - { - // ignored - } - } - } - else - { - var array = dateTimeStr.Split('-'); - if (array.Length == 3) - { - try - { - year = int.Parse(array[0]); - month = int.Parse(array[1]); - day = int.Parse(array[2]); - } - catch - { - // ignored - } - } - } - - var dateTime = new DateTime(year, month, day, hour, minute, second); - return dateTime; - } - - public static HorizontalAlign ToHorizontalAlign(string typeStr) - { - return (HorizontalAlign)TranslateUtils.ToEnum(typeof(HorizontalAlign), typeStr, HorizontalAlign.Left); - } - - public static VerticalAlign ToVerticalAlign(string typeStr) - { - return (VerticalAlign)TranslateUtils.ToEnum(typeof(VerticalAlign), typeStr, VerticalAlign.Middle); - } - - public static GridLines ToGridLines(string typeStr) - { - return (GridLines)TranslateUtils.ToEnum(typeof(GridLines), typeStr, GridLines.None); - } - - public static RepeatDirection ToRepeatDirection(string typeStr) - { - return (RepeatDirection)TranslateUtils.ToEnum(typeof(RepeatDirection), typeStr, RepeatDirection.Vertical); - } - - public static RepeatLayout ToRepeatLayout(string typeStr) - { - return (RepeatLayout)TranslateUtils.ToEnum(typeof(RepeatLayout), typeStr, RepeatLayout.Table); - } - - public static ContentInfo ToContentInfo(NameValueCollection collection, NameValueCollection columnsMap) - { - if (collection == null || columnsMap == null) return null; - - var contentInfo = new ContentInfo(); - foreach (string attributeName in collection.Keys) - { - if (columnsMap[attributeName] != null) - { - var columnsToMatch = columnsMap[attributeName]; - contentInfo.Set(columnsToMatch, collection[attributeName]); - } - } - return contentInfo; - } - - } -} diff --git a/SiteServer.CMS/Core/CountManager.cs b/SiteServer.CMS/Core/CountManager.cs deleted file mode 100644 index 1f91e1a21..000000000 --- a/SiteServer.CMS/Core/CountManager.cs +++ /dev/null @@ -1,43 +0,0 @@ -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Core -{ - public class CountManager - { - private CountManager() - { - } - - public static void AddCount(string relatedTableName, string relatedIdentity, ECountType countType) - { - if (DataProvider.CountDao.IsExists(relatedTableName, relatedIdentity, countType)) - { - DataProvider.CountDao.AddCountNum(relatedTableName, relatedIdentity, countType); - } - else - { - DataProvider.CountDao.Insert(relatedTableName, relatedIdentity, countType, 1); - } - } - - public static void DeleteByRelatedTableName(string relatedTableName) - { - DataProvider.CountDao.DeleteByRelatedTableName(relatedTableName); - } - - public static void DeleteByIdentity(string relatedTableName, string relatedIdentity) - { - DataProvider.CountDao.DeleteByIdentity(relatedTableName, relatedIdentity); - } - - public static int GetCount(string relatedTableName, string relatedIdentity, ECountType countType) - { - return DataProvider.CountDao.GetCountNum(relatedTableName, relatedIdentity, countType); - } - - public static int GetCount(string relatedTableName, int siteId, ECountType countType) - { - return DataProvider.CountDao.GetCountNum(relatedTableName, siteId, countType); - } - } -} diff --git a/SiteServer.CMS/Core/Create/CreateManager.cs b/SiteServer.CMS/Core/Create/CreateManager.cs deleted file mode 100644 index c0cca4550..000000000 --- a/SiteServer.CMS/Core/Create/CreateManager.cs +++ /dev/null @@ -1,152 +0,0 @@ -using SiteServer.Utils; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; - -namespace SiteServer.CMS.Core.Create -{ - public class CreateManager - { - public static string GetTaskName(ECreateType createType, int siteId, int channelId, int contentId, - int templateId, out int pageCount) - { - pageCount = 0; - var name = string.Empty; - if (createType == ECreateType.Channel) - { - name = channelId == siteId ? "首页" : ChannelManager.GetChannelName(siteId, channelId); - if (!string.IsNullOrEmpty(name)) - { - pageCount = 1; - } - } - else if (createType == ECreateType.AllContent) - { - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - if (nodeInfo != null && nodeInfo.ContentNum > 0) - { - pageCount = nodeInfo.ContentNum; - name = $"{nodeInfo.ChannelName}下所有内容页,共{pageCount}项"; - } - } - else if (createType == ECreateType.Content) - { - name = - DataProvider.ContentDao.GetValue( - ChannelManager.GetTableName( - SiteManager.GetSiteInfo(siteId), channelId), - contentId, ContentAttribute.Title); - if (!string.IsNullOrEmpty(name)) - { - pageCount = 1; - } - } - else if (createType == ECreateType.File) - { - name = TemplateManager.GetTemplateName(siteId, templateId); - if (!string.IsNullOrEmpty(name)) - { - pageCount = 1; - } - } - return name; - } - - public static void CreateChannel(int siteId, int channelId) - { - if (siteId <= 0 || channelId <= 0) return; - - int pageCount; - var taskName = GetTaskName(ECreateType.Channel, siteId, channelId, 0, 0, out pageCount); - if (pageCount == 0) return; - - var taskInfo = new CreateTaskInfo(0, taskName, ECreateType.Channel, siteId, channelId, 0, 0, pageCount); - CreateTaskManager.Instance.AddPendingTask(taskInfo); - } - - public static void CreateContent(int siteId, int channelId, int contentId) - { - if (siteId <= 0 || channelId <= 0 || contentId <= 0) return; - - int pageCount; - var taskName = GetTaskName(ECreateType.Content, siteId, channelId, contentId, 0, out pageCount); - if (pageCount == 0) return; - - var taskInfo = new CreateTaskInfo(0, taskName, ECreateType.Content, siteId, channelId, contentId, 0, pageCount); - CreateTaskManager.Instance.AddPendingTask(taskInfo); - } - - public static void CreateAllContent(int siteId, int channelId) - { - if (siteId <= 0 || channelId <= 0) return; - - int pageCount; - var taskName = GetTaskName(ECreateType.AllContent, siteId, channelId, 0, 0, out pageCount); - if (pageCount == 0) return; - - var taskInfo = new CreateTaskInfo(0, taskName, ECreateType.AllContent, siteId, channelId, 0, 0, pageCount); - CreateTaskManager.Instance.AddPendingTask(taskInfo); - } - - public static void CreateFile(int siteId, int templateId) - { - if (siteId <= 0 || templateId <= 0) return; - - int pageCount; - var taskName = GetTaskName(ECreateType.File, siteId, 0, 0, templateId, out pageCount); - if (pageCount == 0) return; - - var taskInfo = new CreateTaskInfo(0, taskName, ECreateType.File, siteId, 0, 0, templateId, pageCount); - CreateTaskManager.Instance.AddPendingTask(taskInfo); - } - - public static void CreateAll(int siteId) - { - CreateTaskManager.Instance.ClearAllTask(siteId); - - var nodeInfoList = ChannelManager.GetChannelInfoList(siteId); - foreach (var nodeInfo in nodeInfoList) - { - CreateChannel(siteId, nodeInfo.Id); - CreateAllContent(siteId, nodeInfo.Id); - } - - foreach (var templateId in TemplateManager.GetAllFileTemplateIdList(siteId)) - { - CreateFile(siteId, templateId); - } - } - - public static void CreateContentTrigger(int siteId, int channelId) - { - if (channelId > 0) - { - ContentTrigger(siteId, channelId); - } - } - - public static void CreateContentAndTrigger(int siteId, int channelId, int contentId) - { - if (siteId <= 0 || channelId <= 0 || contentId <= 0) return; - - CreateContent(siteId, channelId, contentId); - - ContentTrigger(siteId, channelId); - } - - private static void ContentTrigger(int siteId, int channelId) - { - if (siteId <= 0 || channelId <= 0) return; - - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var channelIdList = TranslateUtils.StringCollectionToIntList(nodeInfo.Additional.CreateChannelIDsIfContentChanged); - if (nodeInfo.Additional.IsCreateChannelIfContentChanged && !channelIdList.Contains(channelId)) - { - channelIdList.Add(channelId); - } - foreach (var theChannelId in channelIdList) - { - CreateChannel(siteId, theChannelId); - } - } - } -} diff --git a/SiteServer.CMS/Core/Create/CreateTaskManager.cs b/SiteServer.CMS/Core/Create/CreateTaskManager.cs deleted file mode 100644 index 28e847dc6..000000000 --- a/SiteServer.CMS/Core/Create/CreateTaskManager.cs +++ /dev/null @@ -1,207 +0,0 @@ -using System; -using System.Collections.Concurrent; -using System.Collections.Generic; -using System.Linq; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; - -namespace SiteServer.CMS.Core.Create -{ - public class CreateTaskManager : ICreateTaskManager - { - private static readonly ConcurrentDictionary> PendingTaskDict = new ConcurrentDictionary>(); - private static readonly ConcurrentDictionary> ExecutingTaskDict = new ConcurrentDictionary>(); - private static readonly ConcurrentDictionary> TaskLogDict = new ConcurrentDictionary>(); - private static readonly object LockObject = new object(); - - public static CreateTaskManager Instance { get; } = new CreateTaskManager(); - - /// - /// 获取某个站点的所有任务 - /// - /// - /// - private static ConcurrentQueue GetPendingTasks(int siteId) - { - lock (LockObject) - { - if (!PendingTaskDict.ContainsKey(siteId)) - { - PendingTaskDict.TryAdd(siteId, new ConcurrentQueue()); - } - return PendingTaskDict[siteId]; - } - } - - private static List GetExecutingTasks(int siteId) - { - lock (LockObject) - { - if (!ExecutingTaskDict.ContainsKey(siteId)) - { - ExecutingTaskDict.TryAdd(siteId, new List()); - } - return ExecutingTaskDict[siteId]; - } - } - - private static List GetTaskLogs(int siteId) - { - lock (LockObject) - { - if (!TaskLogDict.ContainsKey(siteId)) - { - TaskLogDict.TryAdd(siteId, new List()); - } - return TaskLogDict[siteId]; - } - } - - /// - /// 添加一个任务 - /// - /// - public void AddPendingTask(CreateTaskInfo task) - { - var pendingTasks = GetPendingTasks(task.SiteId); // 查找某站点所有任务 - foreach (var taskInfo in pendingTasks) - { - if (task.Equals(taskInfo)) - { - return; - } - } - pendingTasks.Enqueue(task); - } - - public int GetPendingTaskCount(int siteId) - { - var pendingTasks = GetPendingTasks(siteId); - return pendingTasks.Count == 0 ? 0 : pendingTasks.Sum(taskInfo => taskInfo.PageCount); - } - - public CreateTaskInfo GetAndRemoveLastPendingTask(int siteId) - { - lock (LockObject) - { - var pendingTasks = GetPendingTasks(siteId); - CreateTaskInfo taskInfo; - pendingTasks.TryDequeue(out taskInfo); - - if (taskInfo != null) - { - var executingTasks = GetExecutingTasks(siteId); - executingTasks.Add(taskInfo); - } - - return taskInfo; - } - } - - public void RemoveCurrent(int siteId, CreateTaskInfo taskInfo) - { - lock (LockObject) - { - var executingTasks = GetExecutingTasks(siteId); - executingTasks.Remove(taskInfo); - } - } - - public void AddSuccessLog(CreateTaskInfo taskInfo, string timeSpan) - { - var taskLogs = GetTaskLogs(taskInfo.SiteId); - var taskLog = new CreateTaskLogInfo(0, taskInfo.CreateType, taskInfo.SiteId, taskInfo.ChannelId, taskInfo.ContentId, taskInfo.TemplateId, taskInfo.Name, timeSpan, true, string.Empty, DateTime.Now); - if (taskLogs.Count > 20) - { - taskLogs.RemoveAt(20); - } - taskLogs.Add(taskLog); - } - - public void AddFailureLog(CreateTaskInfo taskInfo, Exception ex) - { - var taskLogs = GetTaskLogs(taskInfo.SiteId); - var taskLog = new CreateTaskLogInfo(0, taskInfo.CreateType, taskInfo.SiteId, taskInfo.ChannelId, taskInfo.ContentId, taskInfo.TemplateId, taskInfo.Name, string.Empty, false, ex.Message, DateTime.Now); - if (taskLogs.Count > 20) - { - taskLogs.RemoveAt(20); - } - taskLogs.Add(taskLog); - } - - public void ClearAllTask() - { - foreach (var siteId in PendingTaskDict.Keys) - { - PendingTaskDict[siteId] = new ConcurrentQueue(); - } - } - - public void ClearAllTask(int siteId) - { - PendingTaskDict[siteId] = new ConcurrentQueue(); - } - - public CreateTaskSummary GetTaskSummary(int siteId) - { - var executingTasks = GetExecutingTasks(siteId); - var pendingTasks = GetPendingTasks(siteId); - var taskLogs = GetTaskLogs(siteId); - - var list = new List(); - - var channelsCount = 0; - var contentsCount = 0; - var filesCount = 0; - - foreach (var taskInfo in pendingTasks) - { - if (taskInfo.CreateType == ECreateType.Channel) - { - channelsCount += taskInfo.PageCount; - } - else if (taskInfo.CreateType == ECreateType.Content || taskInfo.CreateType == ECreateType.AllContent) - { - contentsCount += taskInfo.PageCount; - } - else if (taskInfo.CreateType == ECreateType.File) - { - filesCount += taskInfo.PageCount; - } - } - - if (executingTasks.Count > 0) - { - foreach (var taskInfo in executingTasks) - { - var summaryItem = new CreateTaskSummaryItem(taskInfo, string.Empty, true, false, false, string.Empty); - list.Add(summaryItem); - } - } - - var count = pendingTasks.Count >= 10 ? 10 : pendingTasks.Count; - if (count > 0) - { - var pendingTaskList = pendingTasks.ToList(); - for (var i = 0; i < count; i++) - { - var taskInfo = pendingTaskList[i]; - var summaryItem = new CreateTaskSummaryItem(taskInfo, string.Empty, false, true, false, string.Empty); - list.Add(summaryItem); - } - } - - count = taskLogs.Count >= 20 ? 20 : taskLogs.Count; - for (var i = 1; i <= count; i++) - { - var logInfo = taskLogs[taskLogs.Count - i]; - var summaryItem = new CreateTaskSummaryItem(logInfo); - list.Add(summaryItem); - } - - var summary = new CreateTaskSummary(list, channelsCount, contentsCount, filesCount); - - return summary; - } - } -} diff --git a/SiteServer.CMS/Core/Create/ICreateTaskManager.cs b/SiteServer.CMS/Core/Create/ICreateTaskManager.cs deleted file mode 100644 index 46dc5374b..000000000 --- a/SiteServer.CMS/Core/Create/ICreateTaskManager.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using SiteServer.CMS.Model; - -namespace SiteServer.CMS.Core.Create -{ - public interface ICreateTaskManager - { - void AddPendingTask(CreateTaskInfo task); - - int GetPendingTaskCount(int siteId); - - CreateTaskInfo GetAndRemoveLastPendingTask(int siteId); - - void RemoveCurrent(int siteId, CreateTaskInfo taskInfo); - - void AddSuccessLog(CreateTaskInfo taskInfo, string timeSpan); - - void AddFailureLog(CreateTaskInfo taskInfo, Exception ex); - - void ClearAllTask(); - - void ClearAllTask(int siteId); - - CreateTaskSummary GetTaskSummary(int siteId); - } -} diff --git a/SiteServer.CMS/Core/CrossSiteTransUtility.cs b/SiteServer.CMS/Core/CrossSiteTransUtility.cs deleted file mode 100644 index caf50d154..000000000 --- a/SiteServer.CMS/Core/CrossSiteTransUtility.cs +++ /dev/null @@ -1,340 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; - -namespace SiteServer.CMS.Core -{ - public class CrossSiteTransUtility - { - private CrossSiteTransUtility() - { - } - - public static bool IsCrossSiteTrans(SiteInfo siteInfo, ChannelInfo channelInfo) - { - var isCrossSiteTrans = false; - - if (channelInfo != null && channelInfo.Additional.TransType != ECrossSiteTransType.None) - { - var transType = channelInfo.Additional.TransType; - if (transType != ECrossSiteTransType.None) - { - if (transType == ECrossSiteTransType.AllParentSite) - { - var parentSiteId = SiteManager.GetParentSiteId(siteInfo.Id); - if (parentSiteId != 0) - { - isCrossSiteTrans = true; - } - } - else if (transType == ECrossSiteTransType.SelfSite) - { - isCrossSiteTrans = true; - } - else if (transType == ECrossSiteTransType.AllSite) - { - isCrossSiteTrans = true; - } - else if (transType == ECrossSiteTransType.SpecifiedSite) - { - if (channelInfo.Additional.TransSiteId > 0) - { - var theSiteInfo = SiteManager.GetSiteInfo(channelInfo.Additional.TransSiteId); - if (theSiteInfo != null) - { - isCrossSiteTrans = true; - } - } - } - else if (transType == ECrossSiteTransType.ParentSite) - { - var parentSiteId = SiteManager.GetParentSiteId(siteInfo.Id); - if (parentSiteId != 0) - { - isCrossSiteTrans = true; - } - } - } - } - - return isCrossSiteTrans; - } - - public static bool IsAutomatic(ChannelInfo channelInfo) - { - var isAutomatic = false; - - if (channelInfo != null) - { - if (channelInfo.Additional.TransType == ECrossSiteTransType.SelfSite || channelInfo.Additional.TransType == ECrossSiteTransType.ParentSite || channelInfo.Additional.TransType == ECrossSiteTransType.SpecifiedSite) - { - isAutomatic = channelInfo.Additional.TransIsAutomatic; - } - } - - return isAutomatic; - } - - public static void LoadSiteIdDropDownList(DropDownList siteIdDropDownList, SiteInfo siteInfo, int channelId) - { - siteIdDropDownList.Items.Clear(); - - var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - if (channelInfo.Additional.TransType == ECrossSiteTransType.SelfSite || channelInfo.Additional.TransType == ECrossSiteTransType.SpecifiedSite || channelInfo.Additional.TransType == ECrossSiteTransType.ParentSite) - { - int theSiteId; - if (channelInfo.Additional.TransType == ECrossSiteTransType.SelfSite) - { - theSiteId = siteInfo.Id; - } - else if (channelInfo.Additional.TransType == ECrossSiteTransType.SpecifiedSite) - { - theSiteId = channelInfo.Additional.TransSiteId; - } - else - { - theSiteId = SiteManager.GetParentSiteId(siteInfo.Id); - } - if (theSiteId > 0) - { - var theSiteInfo = SiteManager.GetSiteInfo(theSiteId); - if (theSiteInfo != null) - { - var listitem = new ListItem(theSiteInfo.SiteName, theSiteInfo.Id.ToString()); - siteIdDropDownList.Items.Add(listitem); - } - } - } - else if (channelInfo.Additional.TransType == ECrossSiteTransType.AllParentSite) - { - var siteIdList = SiteManager.GetSiteIdList(); - - var allParentSiteIdList = new List(); - SiteManager.GetAllParentSiteIdList(allParentSiteIdList, siteIdList, siteInfo.Id); - - foreach (var psId in siteIdList) - { - if (psId == siteInfo.Id) continue; - var psInfo = SiteManager.GetSiteInfo(psId); - var show = psInfo.IsRoot || allParentSiteIdList.Contains(psInfo.Id); - if (show) - { - var listitem = new ListItem(psInfo.SiteName, psId.ToString()); - if (psInfo.IsRoot) listitem.Selected = true; - siteIdDropDownList.Items.Add(listitem); - } - } - } - else if (channelInfo.Additional.TransType == ECrossSiteTransType.AllSite) - { - var siteIdList = SiteManager.GetSiteIdList(); - - foreach (var psId in siteIdList) - { - var psInfo = SiteManager.GetSiteInfo(psId); - var listitem = new ListItem(psInfo.SiteName, psId.ToString()); - if (psInfo.IsRoot) listitem.Selected = true; - siteIdDropDownList.Items.Add(listitem); - } - } - } - - public static void LoadChannelIdListBox(ListBox channelIdListBox, SiteInfo siteInfo, int psId, ChannelInfo channelInfo, PermissionManager permissionManager) - { - channelIdListBox.Items.Clear(); - - var isUseNodeNames = channelInfo.Additional.TransType == ECrossSiteTransType.AllParentSite || channelInfo.Additional.TransType == ECrossSiteTransType.AllSite; - - if (!isUseNodeNames) - { - var channelIdList = TranslateUtils.StringCollectionToIntList(channelInfo.Additional.TransChannelIds); - foreach (var theChannelId in channelIdList) - { - var theNodeInfo = ChannelManager.GetChannelInfo(psId, theChannelId); - if (theNodeInfo != null) - { - var listitem = new ListItem(theNodeInfo.ChannelName, theNodeInfo.Id.ToString()); - channelIdListBox.Items.Add(listitem); - } - } - } - else - { - if (!string.IsNullOrEmpty(channelInfo.Additional.TransChannelNames)) - { - var nodeNameArrayList = TranslateUtils.StringCollectionToStringList(channelInfo.Additional.TransChannelNames); - var channelIdList = ChannelManager.GetChannelIdList(psId); - foreach (var nodeName in nodeNameArrayList) - { - foreach (var theChannelId in channelIdList) - { - var theNodeInfo = ChannelManager.GetChannelInfo(psId, theChannelId); - if (theNodeInfo.ChannelName == nodeName) - { - var listitem = new ListItem(theNodeInfo.ChannelName, theNodeInfo.Id.ToString()); - channelIdListBox.Items.Add(listitem); - break; - } - } - } - } - else - { - ChannelManager.AddListItemsForAddContent(channelIdListBox.Items, SiteManager.GetSiteInfo(psId), false, permissionManager); - } - } - } - - public static string GetDescription(int siteId, ChannelInfo channelInfo) - { - var results = string.Empty; - - if (channelInfo != null) - { - results = ECrossSiteTransTypeUtils.GetText(channelInfo.Additional.TransType); - - if (channelInfo.Additional.TransType == ECrossSiteTransType.AllParentSite || channelInfo.Additional.TransType == ECrossSiteTransType.AllSite) - { - if (!string.IsNullOrEmpty(channelInfo.Additional.TransChannelNames)) - { - results += $"({channelInfo.Additional.TransChannelNames})"; - } - } - else if (channelInfo.Additional.TransType == ECrossSiteTransType.SelfSite || channelInfo.Additional.TransType == ECrossSiteTransType.SpecifiedSite || channelInfo.Additional.TransType == ECrossSiteTransType.ParentSite) - { - SiteInfo siteInfo = null; - - if (channelInfo.Additional.TransType == ECrossSiteTransType.SelfSite) - { - siteInfo = SiteManager.GetSiteInfo(siteId); - } - else if (channelInfo.Additional.TransType == ECrossSiteTransType.SpecifiedSite) - { - siteInfo = SiteManager.GetSiteInfo(channelInfo.Additional.TransSiteId); - } - else - { - var parentSiteId = SiteManager.GetParentSiteId(siteId); - if (parentSiteId != 0) - { - siteInfo = SiteManager.GetSiteInfo(parentSiteId); - } - } - - if (siteInfo != null && !string.IsNullOrEmpty(channelInfo.Additional.TransChannelIds)) - { - var nodeNameBuilder = new StringBuilder(); - var channelIdArrayList = TranslateUtils.StringCollectionToIntList(channelInfo.Additional.TransChannelIds); - foreach (int channelId in channelIdArrayList) - { - var theNodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - if (theNodeInfo != null) - { - nodeNameBuilder.Append(theNodeInfo.ChannelName).Append(","); - } - } - if (nodeNameBuilder.Length > 0) - { - nodeNameBuilder.Length--; - results += $"({siteInfo.SiteName}:{nodeNameBuilder})"; - } - } - } - } - return results; - } - - public static void TransContentInfo(SiteInfo siteInfo, ChannelInfo channelInfo, int contentId, SiteInfo targetSiteInfo, int targetChannelId) - { - var targetTableName = ChannelManager.GetTableName(targetSiteInfo, targetChannelId); - - var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); - var contentInfo = DataProvider.ContentDao.GetContentInfo(tableName, contentId); - FileUtility.MoveFileByContentInfo(siteInfo, targetSiteInfo, contentInfo); - contentInfo.SiteId = targetSiteInfo.Id; - contentInfo.SourceId = channelInfo.Id; - contentInfo.ChannelId = targetChannelId; - contentInfo.IsChecked = targetSiteInfo.Additional.IsCrossSiteTransChecked; - contentInfo.CheckedLevel = 0; - - //复制 - if (Equals(channelInfo.Additional.TransDoneType, ETranslateContentType.Copy)) - { - contentInfo.Set(ContentAttribute.TranslateContentType, ETranslateContentType.Copy.ToString()); - } - //引用地址 - else if (Equals(channelInfo.Additional.TransDoneType, ETranslateContentType.Reference)) - { - contentInfo.SiteId = targetSiteInfo.Id; - contentInfo.SourceId = channelInfo.Id; - contentInfo.ChannelId = targetChannelId; - contentInfo.ReferenceId = contentId; - contentInfo.Set(ContentAttribute.TranslateContentType, ETranslateContentType.Reference.ToString()); - } - //引用内容 - else if (Equals(channelInfo.Additional.TransDoneType, ETranslateContentType.ReferenceContent)) - { - contentInfo.SiteId = targetSiteInfo.Id; - contentInfo.SourceId = channelInfo.Id; - contentInfo.ChannelId = targetChannelId; - contentInfo.ReferenceId = contentId; - contentInfo.Set(ContentAttribute.TranslateContentType, ETranslateContentType.ReferenceContent.ToString()); - } - - if (!string.IsNullOrEmpty(targetTableName)) - { - DataProvider.ContentDao.Insert(targetTableName, targetSiteInfo, contentInfo); - - #region 复制资源 - //资源:图片,文件,视频 - if (!string.IsNullOrEmpty(contentInfo.GetString(BackgroundContentAttribute.ImageUrl))) - { - //修改图片 - var sourceImageUrl = PathUtility.MapPath(siteInfo, contentInfo.GetString(BackgroundContentAttribute.ImageUrl)); - CopyReferenceFiles(targetSiteInfo, sourceImageUrl, siteInfo); - - } - else if (!string.IsNullOrEmpty(contentInfo.GetString(ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.ImageUrl)))) - { - var sourceImageUrls = TranslateUtils.StringCollectionToStringList(contentInfo.GetString(ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.ImageUrl))); - - foreach (string imageUrl in sourceImageUrls) - { - var sourceImageUrl = PathUtility.MapPath(siteInfo, imageUrl); - CopyReferenceFiles(targetSiteInfo, sourceImageUrl, siteInfo); - } - } - if (!string.IsNullOrEmpty(contentInfo.GetString(BackgroundContentAttribute.FileUrl))) - { - //修改附件 - var sourceFileUrl = PathUtility.MapPath(siteInfo, contentInfo.GetString(BackgroundContentAttribute.FileUrl)); - CopyReferenceFiles(targetSiteInfo, sourceFileUrl, siteInfo); - - } - else if (!string.IsNullOrEmpty(contentInfo.GetString(ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.FileUrl)))) - { - var sourceFileUrls = TranslateUtils.StringCollectionToStringList(contentInfo.GetString(ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.FileUrl))); - - foreach (string fileUrl in sourceFileUrls) - { - var sourceFileUrl = PathUtility.MapPath(siteInfo, fileUrl); - CopyReferenceFiles(targetSiteInfo, sourceFileUrl, siteInfo); - } - } - #endregion - } - } - - private static void CopyReferenceFiles(SiteInfo targetSiteInfo, string sourceUrl, SiteInfo sourceSiteInfo) - { - var targetUrl = StringUtils.ReplaceFirst(sourceSiteInfo.SiteDir, sourceUrl, targetSiteInfo.SiteDir); - if (!FileUtils.IsFileExists(targetUrl)) - { - FileUtils.CopyFile(sourceUrl, targetUrl, true); - } - } - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Core/DataProvider.cs b/SiteServer.CMS/Core/DataProvider.cs deleted file mode 100644 index b585c66ed..000000000 --- a/SiteServer.CMS/Core/DataProvider.cs +++ /dev/null @@ -1,191 +0,0 @@ -using System.Collections.Generic; -using SiteServer.CMS.Data; -using SiteServer.CMS.Provider; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Core -{ - public class DataProvider - { - private static IDataApi _dataApi; - public static IDataApi DataApi - { - get - { - if (_dataApi != null) return _dataApi; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - _dataApi = new Data.MySql(); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - _dataApi = new SqlServer(); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - _dataApi = new PostgreSql(); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - _dataApi = new Data.Oracle(); - } - - return _dataApi; - } - } - - private static AdministratorDao _administratorDao; - public static AdministratorDao AdministratorDao => _administratorDao ?? (_administratorDao = new AdministratorDao()); - - private static AdministratorsInRolesDao _administratorsInRolesDao; - public static AdministratorsInRolesDao AdministratorsInRolesDao => _administratorsInRolesDao ?? (_administratorsInRolesDao = new AdministratorsInRolesDao()); - - private static AreaDao _areaDao; - public static AreaDao AreaDao => _areaDao ?? (_areaDao = new AreaDao()); - - private static ChannelDao _channelDao; - public static ChannelDao ChannelDao => _channelDao ?? (_channelDao = new ChannelDao()); - - private static ChannelGroupDao _channelGroupDao; - public static ChannelGroupDao ChannelGroupDao => _channelGroupDao ?? (_channelGroupDao = new ChannelGroupDao()); - - private static ConfigDao _configDao; - public static ConfigDao ConfigDao => _configDao ?? (_configDao = new ConfigDao()); - - private static ContentCheckDao _contentCheckDao; - public static ContentCheckDao ContentCheckDao => _contentCheckDao ?? (_contentCheckDao = new ContentCheckDao()); - - private static ContentDao _contentDao; - public static ContentDao ContentDao => _contentDao ?? (_contentDao = new ContentDao()); - - private static ContentGroupDao _contentGroupDao; - public static ContentGroupDao ContentGroupDao => _contentGroupDao ?? (_contentGroupDao = new ContentGroupDao()); - - private static CountDao _countDao; - internal static CountDao CountDao => _countDao ?? (_countDao = new CountDao()); - - private static DatabaseDao _databaseDao; - public static DatabaseDao DatabaseDao => _databaseDao ?? (_databaseDao = new DatabaseDao()); - - private static DbCacheDao _dbCacheDao; - internal static DbCacheDao DbCacheDao => _dbCacheDao ?? (_dbCacheDao = new DbCacheDao()); - - private static DepartmentDao _departmentDao; - public static DepartmentDao DepartmentDao => _departmentDao ?? (_departmentDao = new DepartmentDao()); - - private static ErrorLogDao _errorLogDao; - public static ErrorLogDao ErrorLogDao => _errorLogDao ?? (_errorLogDao = new ErrorLogDao()); - - private static KeywordDao _keywordDao; - public static KeywordDao KeywordDao => _keywordDao ?? (_keywordDao = new KeywordDao()); - - private static LogDao _logDao; - public static LogDao LogDao => _logDao ?? (_logDao = new LogDao()); - - private static PermissionsInRolesDao _permissionsInRolesDao; - public static PermissionsInRolesDao PermissionsInRolesDao => _permissionsInRolesDao ?? (_permissionsInRolesDao = new PermissionsInRolesDao()); - - private static PluginConfigDao _pluginConfigDao; - public static PluginConfigDao PluginConfigDao => _pluginConfigDao ?? (_pluginConfigDao = new PluginConfigDao()); - - private static PluginDao _pluginDao; - public static PluginDao PluginDao => _pluginDao ?? (_pluginDao = new PluginDao()); - - private static SiteDao _siteDao; - public static SiteDao SiteDao => _siteDao ?? (_siteDao = new SiteDao()); - - private static SiteLogDao _siteLogDao; - public static SiteLogDao SiteLogDao => _siteLogDao ?? (_siteLogDao = new SiteLogDao()); - - private static RecordDao _recordDao; - public static RecordDao RecordDao => _recordDao ?? (_recordDao = new RecordDao()); - - private static RelatedFieldDao _relatedFieldDao; - public static RelatedFieldDao RelatedFieldDao => _relatedFieldDao ?? (_relatedFieldDao = new RelatedFieldDao()); - - private static RelatedFieldItemDao _relatedFieldItemDao; - public static RelatedFieldItemDao RelatedFieldItemDao => _relatedFieldItemDao ?? (_relatedFieldItemDao = new RelatedFieldItemDao()); - - private static RoleDao _roleDao; - public static RoleDao RoleDao => _roleDao ?? (_roleDao = new RoleDao()); - - private static SitePermissionsDao _sitePermissionsDao; - public static SitePermissionsDao SitePermissionsDao => _sitePermissionsDao ?? (_sitePermissionsDao = new SitePermissionsDao()); - - private static TableDao _tableDao; - public static TableDao TableDao => _tableDao ?? (_tableDao = new TableDao()); - - private static TableMatchDao _tableMatchDao; - public static TableMatchDao TableMatchDao => _tableMatchDao ?? (_tableMatchDao = new TableMatchDao()); - - private static TableMetadataDao _tableMetadataDao; - public static TableMetadataDao TableMetadataDao => _tableMetadataDao ?? (_tableMetadataDao = new TableMetadataDao()); - - private static TableStyleDao _tableStyleDao; - public static TableStyleDao TableStyleDao => _tableStyleDao ?? (_tableStyleDao = new TableStyleDao()); - - private static TableStyleItemDao _tableStyleItemDao; - public static TableStyleItemDao TableStyleItemDao => _tableStyleItemDao ?? (_tableStyleItemDao = new TableStyleItemDao()); - - private static TagDao _tagDao; - public static TagDao TagDao => _tagDao ?? (_tagDao = new TagDao()); - - private static TemplateDao _templateDao; - public static TemplateDao TemplateDao => _templateDao ?? (_templateDao = new TemplateDao()); - - private static TemplateLogDao _templateLogDao; - public static TemplateLogDao TemplateLogDao => _templateLogDao ?? (_templateLogDao = new TemplateLogDao()); - - private static TemplateMatchDao _templateMatchDao; - public static TemplateMatchDao TemplateMatchDao => _templateMatchDao ?? (_templateMatchDao = new TemplateMatchDao()); - - private static UserDao _userDao; - public static UserDao UserDao => _userDao ?? (_userDao = new UserDao()); - - private static UserLogDao _userLogDao; - public static UserLogDao UserLogDao => _userLogDao ?? (_userLogDao = new UserLogDao()); - - public static List AllProviders => new List - { - AdministratorDao, - AdministratorsInRolesDao, - AreaDao, - ChannelDao, - ChannelGroupDao, - ConfigDao, - ContentCheckDao, - ContentDao, - ContentGroupDao, - CountDao, - DatabaseDao, - DbCacheDao, - DepartmentDao, - ErrorLogDao, - KeywordDao, - LogDao, - PermissionsInRolesDao, - PluginConfigDao, - PluginDao, - SiteDao, - SiteLogDao, - RecordDao, - RelatedFieldDao, - RelatedFieldItemDao, - RoleDao, - SitePermissionsDao, - TableDao, - TableMatchDao, - TableMetadataDao, - TableStyleDao, - TableStyleItemDao, - TagDao, - TemplateDao, - TemplateLogDao, - TemplateMatchDao, - UserDao, - UserLogDao - }; - } -} diff --git a/SiteServer.CMS/Core/DepartmentManager.cs b/SiteServer.CMS/Core/DepartmentManager.cs deleted file mode 100644 index 508cae658..000000000 --- a/SiteServer.CMS/Core/DepartmentManager.cs +++ /dev/null @@ -1,118 +0,0 @@ -using System.Collections.Generic; -using SiteServer.CMS.Model; -using SiteServer.Utils; - -namespace SiteServer.CMS.Core -{ - public class DepartmentManager - { - public static DepartmentInfo GetDepartmentInfo(int departmentId) - { - var pairList = GetDepartmentInfoKeyValuePair(); - - foreach (var pair in pairList) - { - if (pair.Key == departmentId) - { - return pair.Value; - } - } - return null; - } - - public static string GetThisDepartmentName(int departmentId) - { - var departmentInfo = GetDepartmentInfo(departmentId); - if (departmentInfo != null) - { - return departmentInfo.DepartmentName; - } - return string.Empty; - } - - public static string GetDepartmentName(int departmentId) - { - if (departmentId <= 0) return string.Empty; - - var departmentNameList = new List(); - - var parentsPath = GetParentsPath(departmentId); - var departmentIdList = new List(); - if (!string.IsNullOrEmpty(parentsPath)) - { - departmentIdList = TranslateUtils.StringCollectionToIntList(parentsPath); - } - departmentIdList.Add(departmentId); - - foreach (var theDepartmentId in departmentIdList) - { - var departmentInfo = GetDepartmentInfo(theDepartmentId); - if (departmentInfo != null) - { - departmentNameList.Add(departmentInfo.DepartmentName); - } - } - - return TranslateUtils.ObjectCollectionToString(departmentNameList, " > "); - } - - public static string GetDepartmentCode(int departmentId) - { - if (departmentId > 0) - { - var departmentInfo = GetDepartmentInfo(departmentId); - if (departmentInfo != null) - { - return departmentInfo.Code; - } - } - return string.Empty; - } - - public static string GetParentsPath(int departmentId) - { - var retval = string.Empty; - var departmentInfo = GetDepartmentInfo(departmentId); - if (departmentInfo != null) - { - retval = departmentInfo.ParentsPath; - } - return retval; - } - - public static List GetDepartmentIdList() - { - var pairList = GetDepartmentInfoKeyValuePair(); - var list = new List(); - foreach (var pair in pairList) - { - list.Add(pair.Key); - } - return list; - } - - public static void ClearCache() - { - CacheUtils.Remove(CacheKey); - } - - public static List> GetDepartmentInfoKeyValuePair() - { - lock (LockObject) - { - if (CacheUtils.Get(CacheKey) == null) - { - var list = DataProvider.DepartmentDao.GetDepartmentInfoKeyValuePair(); - CacheUtils.Insert(CacheKey, list); - return list; - } - return CacheUtils.Get(CacheKey) as List>; - } - } - - /****************** Cache *********************/ - - private static readonly object LockObject = new object(); - private const string CacheKey = "BaiRong.Core.DepartmentManager"; - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Core/FileUtility.cs b/SiteServer.CMS/Core/FileUtility.cs deleted file mode 100644 index 38ae88c17..000000000 --- a/SiteServer.CMS/Core/FileUtility.cs +++ /dev/null @@ -1,142 +0,0 @@ -using System; -using SiteServer.Utils; -using SiteServer.CMS.Model; -using System.Collections.Generic; -using SiteServer.Utils.Enumerations; -using SiteServer.Utils.Images; - -namespace SiteServer.CMS.Core -{ - public class FileUtility - { - private FileUtility() - { - } - - public static void AddWaterMark(SiteInfo siteInfo, string imagePath) - { - try - { - var fileExtName = PathUtils.GetExtension(imagePath); - if (EFileSystemTypeUtils.IsImage(fileExtName)) - { - if (siteInfo.Additional.IsWaterMark) - { - if (siteInfo.Additional.IsImageWaterMark) - { - if (!string.IsNullOrEmpty(siteInfo.Additional.WaterMarkImagePath)) - { - ImageUtils.AddImageWaterMark(imagePath, PathUtility.MapPath(siteInfo, siteInfo.Additional.WaterMarkImagePath), siteInfo.Additional.WaterMarkPosition, siteInfo.Additional.WaterMarkTransparency, siteInfo.Additional.WaterMarkMinWidth, siteInfo.Additional.WaterMarkMinHeight); - } - } - else - { - if (!string.IsNullOrEmpty(siteInfo.Additional.WaterMarkFormatString)) - { - var now = DateTime.Now; - ImageUtils.AddTextWaterMark(imagePath, string.Format(siteInfo.Additional.WaterMarkFormatString, DateUtils.GetDateString(now), DateUtils.GetTimeString(now)), siteInfo.Additional.WaterMarkFontName, siteInfo.Additional.WaterMarkFontSize, siteInfo.Additional.WaterMarkPosition, siteInfo.Additional.WaterMarkTransparency, siteInfo.Additional.WaterMarkMinWidth, siteInfo.Additional.WaterMarkMinHeight); - } - } - } - } - } - catch - { - // ignored - } - } - - public static void MoveFile(SiteInfo sourceSiteInfo, SiteInfo destSiteInfo, string relatedUrl) - { - if (!string.IsNullOrEmpty(relatedUrl)) - { - var sourceFilePath = PathUtility.MapPath(sourceSiteInfo, relatedUrl); - var descFilePath = PathUtility.MapPath(destSiteInfo, relatedUrl); - if (FileUtils.IsFileExists(sourceFilePath)) - { - FileUtils.MoveFile(sourceFilePath, descFilePath, false); - } - } - } - - public static void MoveFileByContentInfo(SiteInfo sourceSiteInfo, SiteInfo destSiteInfo, ContentInfo contentInfo) - { - if (contentInfo == null || sourceSiteInfo.Id == destSiteInfo.Id) return; - - try - { - var fileUrls = new List - { - contentInfo.GetString(BackgroundContentAttribute.ImageUrl), - contentInfo.GetString(BackgroundContentAttribute.VideoUrl), - contentInfo.GetString(BackgroundContentAttribute.FileUrl) - }; - - foreach (var url in TranslateUtils.StringCollectionToStringList(contentInfo.GetString(ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.ImageUrl)))) - { - if (!fileUrls.Contains(url)) - { - fileUrls.Add(url); - } - } - foreach (var url in TranslateUtils.StringCollectionToStringList(contentInfo.GetString(ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.VideoUrl)))) - { - if (!fileUrls.Contains(url)) - { - fileUrls.Add(url); - } - } - foreach (var url in TranslateUtils.StringCollectionToStringList(contentInfo.GetString(ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.FileUrl)))) - { - if (!fileUrls.Contains(url)) - { - fileUrls.Add(url); - } - } - foreach (var url in RegexUtils.GetOriginalImageSrcs(contentInfo.GetString(BackgroundContentAttribute.Content))) - { - if (!fileUrls.Contains(url)) - { - fileUrls.Add(url); - } - } - foreach (var url in RegexUtils.GetOriginalLinkHrefs(contentInfo.GetString(BackgroundContentAttribute.Content))) - { - if (!fileUrls.Contains(url) && PageUtils.IsVirtualUrl(url)) - { - fileUrls.Add(url); - } - } - - foreach (var fileUrl in fileUrls) - { - if (!string.IsNullOrEmpty(fileUrl) && PageUtility.IsVirtualUrl(fileUrl)) - { - MoveFile(sourceSiteInfo, destSiteInfo, fileUrl); - } - } - } - catch - { - // ignored - } - } - - public static void MoveFileByVirtaulUrl(SiteInfo sourceSiteInfo, SiteInfo destSiteInfo, string fileVirtaulUrl) - { - if (string.IsNullOrEmpty(fileVirtaulUrl) || sourceSiteInfo.Id == destSiteInfo.Id) return; - - try - { - if (PageUtility.IsVirtualUrl(fileVirtaulUrl)) - { - MoveFile(sourceSiteInfo, destSiteInfo, fileVirtaulUrl); - } - } - catch - { - // ignored - } - } - } -} diff --git a/SiteServer.CMS/Core/InputParserUtility.cs b/SiteServer.CMS/Core/InputParserUtility.cs deleted file mode 100644 index c41fc89ac..000000000 --- a/SiteServer.CMS/Core/InputParserUtility.cs +++ /dev/null @@ -1,369 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using System.Web.UI.HtmlControls; -using SiteServer.CMS.Api; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Core -{ - public class InputParserUtility - { - private InputParserUtility() - { - } - - public static string GetContentByTableStyle(string content, SiteInfo siteInfo, TableStyleInfo styleInfo) - { - if (!string.IsNullOrEmpty(content)) - { - return GetContentByTableStyle(content, ",", siteInfo, styleInfo, string.Empty, null, string.Empty, false); - } - return string.Empty; - } - - public static string GetContentByTableStyle(string content, string separator, SiteInfo siteInfo, TableStyleInfo styleInfo, string formatString, Dictionary attributes, string innerXml, bool isStlEntity) - { - var parsedContent = content; - - var inputType = styleInfo.InputType; - - if (inputType == InputType.Date) - { - var dateTime = TranslateUtils.ToDateTime(content); - if (dateTime != DateUtils.SqlMinValue) - { - if (string.IsNullOrEmpty(formatString)) - { - formatString = DateUtils.FormatStringDateOnly; - } - parsedContent = DateUtils.Format(dateTime, formatString); - } - else - { - parsedContent = string.Empty; - } - } - else if (inputType == InputType.DateTime) - { - var dateTime = TranslateUtils.ToDateTime(content); - if (dateTime != DateUtils.SqlMinValue) - { - if (string.IsNullOrEmpty(formatString)) - { - formatString = DateUtils.FormatStringDateTime; - } - parsedContent = DateUtils.Format(dateTime, formatString); - } - else - { - parsedContent = string.Empty; - } - } - else if (inputType == InputType.CheckBox || inputType == InputType.Radio || inputType == InputType.SelectMultiple || inputType == InputType.SelectOne)//选择类型 - { - var selectedTexts = new ArrayList(); - var selectedValues = TranslateUtils.StringCollectionToStringList(content); - var styleItems = styleInfo.StyleItems ?? - DataProvider.TableStyleItemDao.GetStyleItemInfoList(styleInfo.Id); - foreach (var itemInfo in styleItems) - { - if (selectedValues.Contains(itemInfo.ItemValue)) - { - selectedTexts.Add(isStlEntity ? itemInfo.ItemValue : itemInfo.ItemTitle); - } - } - parsedContent = separator == null ? TranslateUtils.ObjectCollectionToString(selectedTexts) : TranslateUtils.ObjectCollectionToString(selectedTexts, separator); - } - //else if (styleInfo.InputType == InputType.TextArea) - //{ - // parsedContent = StringUtils.ReplaceNewlineToBR(parsedContent); - //} - else if (inputType == InputType.TextEditor) - { - parsedContent = ContentUtility.TextEditorContentDecode(siteInfo, parsedContent, true); - } - else if (inputType == InputType.Image) - { - parsedContent = GetImageOrFlashHtml(siteInfo, parsedContent, attributes, isStlEntity); - } - else if (inputType == InputType.Video) - { - parsedContent = GetVideoHtml(siteInfo, parsedContent, attributes, isStlEntity); - } - else if (inputType == InputType.File) - { - parsedContent = GetFileHtmlWithoutCount(siteInfo, parsedContent, attributes, innerXml, isStlEntity); - } - - return parsedContent; - } - - public static string GetContentByTableStyle(ContentInfo contentInfo, string separator, SiteInfo siteInfo, TableStyleInfo styleInfo, string formatString, int no, Dictionary attributes, string innerXml, bool isStlEntity) - { - var value = contentInfo.GetString(styleInfo.AttributeName); - var parsedContent = string.Empty; - - var inputType = styleInfo.InputType; - - if (inputType == InputType.Date) - { - var dateTime = TranslateUtils.ToDateTime(value); - if (dateTime != DateUtils.SqlMinValue) - { - if (string.IsNullOrEmpty(formatString)) - { - formatString = DateUtils.FormatStringDateOnly; - } - parsedContent = DateUtils.Format(dateTime, formatString); - } - } - else if (inputType == InputType.DateTime) - { - var dateTime = TranslateUtils.ToDateTime(value); - if (dateTime != DateUtils.SqlMinValue) - { - if (string.IsNullOrEmpty(formatString)) - { - formatString = DateUtils.FormatStringDateTime; - } - parsedContent = DateUtils.Format(dateTime, formatString); - } - } - else if (inputType == InputType.CheckBox || inputType == InputType.Radio || inputType == InputType.SelectMultiple || inputType == InputType.SelectOne)//选择类型 - { - var selectedTexts = new ArrayList(); - var selectedValues = TranslateUtils.StringCollectionToStringList(value); - var styleItems = styleInfo.StyleItems ?? - DataProvider.TableStyleItemDao.GetStyleItemInfoList(styleInfo.Id); - foreach (var itemInfo in styleItems) - { - if (selectedValues.Contains(itemInfo.ItemValue)) - { - selectedTexts.Add(isStlEntity ? itemInfo.ItemValue : itemInfo.ItemTitle); - } - } - parsedContent = separator == null ? TranslateUtils.ObjectCollectionToString(selectedTexts) : TranslateUtils.ObjectCollectionToString(selectedTexts, separator); - } - else if (inputType == InputType.TextEditor) - { - parsedContent = ContentUtility.TextEditorContentDecode(siteInfo, value, true); - } - else if (inputType == InputType.Image) - { - if (no <= 1) - { - parsedContent = GetImageOrFlashHtml(siteInfo, value, attributes, isStlEntity); - } - else - { - var extendAttributeName = ContentAttribute.GetExtendAttributeName(styleInfo.AttributeName); - var extendValues = contentInfo.GetString(extendAttributeName); - if (!string.IsNullOrEmpty(extendValues)) - { - var index = 2; - foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) - { - if (index == no) - { - parsedContent = GetImageOrFlashHtml(siteInfo, extendValue, attributes, isStlEntity); - break; - } - index++; - } - } - } - } - else if (inputType == InputType.Video) - { - if (no <= 1) - { - parsedContent = GetVideoHtml(siteInfo, value, attributes, isStlEntity); - } - else - { - var extendAttributeName = ContentAttribute.GetExtendAttributeName(styleInfo.AttributeName); - var extendValues = contentInfo.GetString(extendAttributeName); - if (!string.IsNullOrEmpty(extendValues)) - { - var index = 2; - foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) - { - if (index == no) - { - parsedContent = GetVideoHtml(siteInfo, extendValue, attributes, isStlEntity); - break; - } - index++; - } - } - } - } - else if (inputType == InputType.File) - { - if (no <= 1) - { - parsedContent = GetFileHtmlWithoutCount(siteInfo, value, attributes, innerXml, isStlEntity); - } - else - { - var extendAttributeName = ContentAttribute.GetExtendAttributeName(styleInfo.AttributeName); - var extendValues = contentInfo.GetString(extendAttributeName); - if (!string.IsNullOrEmpty(extendValues)) - { - var index = 2; - foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) - { - if (index == no) - { - parsedContent = GetFileHtmlWithoutCount(siteInfo, extendValue, attributes, innerXml, isStlEntity); - break; - } - index++; - } - } - } - } - else - { - parsedContent = value; - } - - return parsedContent; - } - - public static string GetImageOrFlashHtml(SiteInfo siteInfo, string imageUrl, Dictionary attributes, bool isStlEntity) - { - var retval = string.Empty; - if (!string.IsNullOrEmpty(imageUrl)) - { - imageUrl = PageUtility.ParseNavigationUrl(siteInfo, imageUrl, false); - if (isStlEntity) - { - retval = imageUrl; - } - else - { - if (!imageUrl.ToUpper().Trim().EndsWith(".SWF")) - { - var htmlImage = new HtmlImage(); - ControlUtils.AddAttributesIfNotExists(htmlImage, attributes); - htmlImage.Src = imageUrl; - retval = ControlUtils.GetControlRenderHtml(htmlImage); - } - else - { - var width = 100; - var height = 100; - if (attributes != null) - { - if (!string.IsNullOrEmpty(attributes["width"])) - { - try - { - width = int.Parse(attributes["width"]); - } - catch - { - // ignored - } - } - if (!string.IsNullOrEmpty(attributes["height"])) - { - try - { - height = int.Parse(attributes["height"]); - } - catch - { - // ignored - } - } - } - retval = $@" - - - - - -"; - } - } - } - return retval; - } - - public static string GetVideoHtml(SiteInfo siteInfo, string videoUrl, Dictionary attributes, bool isStlEntity) - { - var retval = string.Empty; - if (!string.IsNullOrEmpty(videoUrl)) - { - videoUrl = PageUtility.ParseNavigationUrl(siteInfo, videoUrl, false); - if (isStlEntity) - { - retval = videoUrl; - } - else - { - retval = $@" - -"; - } - } - return retval; - } - - public static string GetFileHtmlWithCount(SiteInfo siteInfo, int channelId, int contentId, string fileUrl, Dictionary attributes, string innerXml, bool isStlEntity) - { - var retval = string.Empty; - if (!string.IsNullOrEmpty(fileUrl)) - { - if (isStlEntity) - { - retval = ApiRouteActionsDownload.GetUrl(ApiManager.OuterApiUrl, siteInfo.Id, channelId, contentId, fileUrl); - } - else - { - var stlAnchor = new HtmlAnchor(); - ControlUtils.AddAttributesIfNotExists(stlAnchor, attributes); - stlAnchor.HRef = ApiRouteActionsDownload.GetUrl(ApiManager.OuterApiUrl, siteInfo.Id, channelId, contentId, fileUrl); - stlAnchor.InnerHtml = string.IsNullOrEmpty(innerXml) ? PageUtils.GetFileNameFromUrl(fileUrl) : innerXml; - - retval = ControlUtils.GetControlRenderHtml(stlAnchor); - } - } - return retval; - } - - public static string GetFileHtmlWithoutCount(SiteInfo siteInfo, string fileUrl, Dictionary attributes, string innerXml, bool isStlEntity) - { - if (siteInfo != null) - { - var retval = string.Empty; - if (!string.IsNullOrEmpty(fileUrl)) - { - if (isStlEntity) - { - retval = ApiRouteActionsDownload.GetUrl(ApiManager.OuterApiUrl, siteInfo.Id, fileUrl); - } - else - { - var stlAnchor = new HtmlAnchor(); - ControlUtils.AddAttributesIfNotExists(stlAnchor, attributes); - stlAnchor.HRef = ApiRouteActionsDownload.GetUrl(ApiManager.OuterApiUrl, siteInfo.Id, fileUrl); - stlAnchor.InnerHtml = string.IsNullOrEmpty(innerXml) ? PageUtils.GetFileNameFromUrl(fileUrl) : innerXml; - - retval = ControlUtils.GetControlRenderHtml(stlAnchor); - } - } - return retval; - } - return string.Empty; - } - - - } -} diff --git a/SiteServer.CMS/Core/LogUtils.cs b/SiteServer.CMS/Core/LogUtils.cs deleted file mode 100644 index b6057558c..000000000 --- a/SiteServer.CMS/Core/LogUtils.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; -using SiteServer.CMS.Model; -using SiteServer.Utils; - -namespace SiteServer.CMS.Core -{ - public class LogUtils - { - private static int AddErrorLog(ErrorLogInfo logInfo) - { - if (!ConfigManager.SystemConfigInfo.IsLogError) return 0; - - try - { - if (ConfigManager.SystemConfigInfo.IsTimeThreshold) - { - DataProvider.ErrorLogDao.Delete(ConfigManager.SystemConfigInfo.TimeThreshold); - } - - return DataProvider.ErrorLogDao.Insert(logInfo); - } - catch - { - // ignored - } - - return 0; - } - - public static void AddErrorLogAndRedirect(Exception ex, string summary = "") - { - if (ex.HResult == -2147467259) // 文件名不存在 - { - PageUtils.RedirectToErrorPage(ex.Message); - } - else - { - var logId = AddErrorLog(ex, summary); - if (logId > 0) - { - PageUtils.RedirectToErrorPage(logId); - } - else - { - PageUtils.RedirectToErrorPage(ex.Message); - } - } - } - - public static int AddErrorLog(Exception ex, string summary = "") - { - return AddErrorLog(new ErrorLogInfo(0, string.Empty, ex.Message, ex.StackTrace, summary, DateTime.Now)); - } - - public static int AddErrorLog(string pluginId, Exception ex, string summary = "") - { - return AddErrorLog(new ErrorLogInfo(0, pluginId, ex.Message, ex.StackTrace, summary, DateTime.Now)); - } - - public static void AddAdminLog(string userName, string action, string summary = "") - { - if (!ConfigManager.SystemConfigInfo.IsLogAdmin) return; - - try - { - if (ConfigManager.SystemConfigInfo.IsTimeThreshold) - { - DataProvider.LogDao.Delete(ConfigManager.SystemConfigInfo.TimeThreshold); - } - - if (!string.IsNullOrEmpty(action)) - { - action = StringUtils.MaxLengthText(action, 250); - } - if (!string.IsNullOrEmpty(summary)) - { - summary = StringUtils.MaxLengthText(summary, 250); - } - var logInfo = new LogInfo(0, userName, PageUtils.GetIpAddress(), DateTime.Now, action, summary); - - DataProvider.LogDao.Insert(logInfo); - } - catch (Exception ex) - { - AddErrorLog(ex); - } - } - - public static void AddUserLoginLog(string userName) - { - AddUserLog(userName, "用户登录", string.Empty); - } - - public static void AddUserLog(string userName, string actionType, string summary) - { - if (!ConfigManager.SystemConfigInfo.IsLogUser) return; - - try - { - if (ConfigManager.SystemConfigInfo.IsTimeThreshold) - { - DataProvider.UserLogDao.Delete(ConfigManager.SystemConfigInfo.TimeThreshold); - } - - if (!string.IsNullOrEmpty(summary)) - { - summary = StringUtils.MaxLengthText(summary, 250); - } - DataProvider.UserLogDao.Insert(new UserLogInfo(0, userName, PageUtils.GetIpAddress(), DateTime.Now, actionType, summary)); - } - catch (Exception ex) - { - AddErrorLog(ex); - } - } - } -} diff --git a/SiteServer.CMS/Core/Office/AccessDao.cs b/SiteServer.CMS/Core/Office/AccessDao.cs deleted file mode 100644 index 9d0b869a0..000000000 --- a/SiteServer.CMS/Core/Office/AccessDao.cs +++ /dev/null @@ -1,160 +0,0 @@ -using System.Data; -using System.Data.OleDb; -using System.Collections; -using System.Collections.Generic; -using System.Text; -using SiteServer.CMS.Model; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Core.Office -{ - public class AccessDao - { - private readonly OleDbConnection _connection; - - public AccessDao(string filePath) - { - ConnectionString = $"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={filePath};User Id=;Password=;"; - _connection = new OleDbConnection(ConnectionString); - } - - public string ConnectionString { get; } - - public string GetCreateTableSqlString(string nodeName, List tableStyleInfoList, List displayAttributes) - { - var createBuilder = new StringBuilder(); - createBuilder.Append($"CREATE TABLE {nodeName} ( "); - - foreach (var tableStyleInfo in tableStyleInfoList) - { - if (displayAttributes.Contains(tableStyleInfo.AttributeName)) - { - createBuilder.Append($" [{tableStyleInfo.DisplayName}] memo, "); - } - } - - createBuilder.Length = createBuilder.Length - 2; - createBuilder.Append(" )"); - - return createBuilder.ToString(); - } - - public ArrayList GetInsertSqlStringArrayList(string nodeName, int siteId, int channelId, string tableName, List styleInfoList, List displayAttributes, List contentIdList, bool isPeriods, string dateFrom, string dateTo, ETriState checkedState, out bool isExport) - { - var insertSqlArrayList = new ArrayList(); - - var preInsertBuilder = new StringBuilder(); - preInsertBuilder.Append($"INSERT INTO {nodeName} ("); - - foreach (var tableStyleInfo in styleInfoList) - { - if (displayAttributes.Contains(tableStyleInfo.AttributeName)) - { - preInsertBuilder.Append($"[{tableStyleInfo.DisplayName}], "); - } - } - - preInsertBuilder.Length = preInsertBuilder.Length - 2; - preInsertBuilder.Append(") VALUES ("); - - if (contentIdList == null || contentIdList.Count == 0) - { - contentIdList = DataProvider.ContentDao.GetContentIdList(tableName, channelId, isPeriods, dateFrom, dateTo, checkedState); - } - - isExport = contentIdList.Count > 0; - - foreach (var contentId in contentIdList) - { - var contentInfo = DataProvider.ContentDao.GetContentInfo(tableName, contentId); - if (contentInfo != null) - { - var insertBuilder = new StringBuilder(); - insertBuilder.Append(preInsertBuilder); - - foreach (var tableStyleInfo in styleInfoList) - { - if (displayAttributes.Contains(tableStyleInfo.AttributeName)) - { - var value = contentInfo.GetString(tableStyleInfo.AttributeName); - insertBuilder.Append($"'{SqlUtils.ToSqlString(StringUtils.StripTags(value))}', "); - } - } - - insertBuilder.Length = insertBuilder.Length - 2; - insertBuilder.Append(") "); - - insertSqlArrayList.Add(insertBuilder.ToString()); - } - } - return insertSqlArrayList; - } - - public bool ExecuteSqlString(string sqlString) - { - bool resultState; - OleDbTransaction myTrans = null; - - try - { - _connection.Open(); - myTrans = _connection.BeginTransaction(); - var command = new OleDbCommand(sqlString, _connection, myTrans); - command.ExecuteNonQuery(); - myTrans.Commit(); - resultState = true; - } - catch - { - myTrans?.Rollback(); - resultState = false; - } - finally - { - _connection.Close(); - } - - return resultState; - } - - public DataSet ReturnDataSet(string strSql) - { - var dataSet = new DataSet(); - try - { - _connection.Open(); - var oleDbDa = new OleDbDataAdapter(strSql, _connection); - oleDbDa.Fill(dataSet, "objDataSet"); - } - finally - { - _connection.Close(); - } - return dataSet; - } - - public string[] GetTableNames() - { - try - { - _connection.Open(); - var shemaTable = _connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" }); - var n = shemaTable.Rows.Count; - var strTable = new string[n]; - var m = shemaTable.Columns.IndexOf("TABLE_NAME"); - for (var i = 0; i < n; i++) - { - var m_DataRow = shemaTable.Rows[i]; - strTable[i] = m_DataRow.ItemArray.GetValue(m).ToString(); - } - return strTable; - } - finally - { - _connection.Close(); - } - } - } - -} diff --git a/SiteServer.CMS/Core/Office/AccessObject.cs b/SiteServer.CMS/Core/Office/AccessObject.cs deleted file mode 100644 index ad6e684fd..000000000 --- a/SiteServer.CMS/Core/Office/AccessObject.cs +++ /dev/null @@ -1,114 +0,0 @@ -using System.Collections; -using SiteServer.Utils; -using SiteServer.CMS.Model; -using System; -using System.Collections.Generic; -using System.Data; -using System.Collections.Specialized; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Core.Office -{ - public class AccessObject - { - public static bool CreateAccessFileForContents(string filePath, SiteInfo siteInfo, ChannelInfo nodeInfo, List contentIdList, List displayAttributes, bool isPeriods, string dateFrom, string dateTo, ETriState checkedState) - { - DirectoryUtils.CreateDirectoryIfNotExists(DirectoryUtils.GetDirectoryPath(filePath)); - FileUtils.DeleteFileIfExists(filePath); - - var sourceFilePath = SiteServerAssets.GetPath(SiteServerAssets.Default.AccessMdb); - FileUtils.CopyFile(sourceFilePath, filePath); - - var relatedidentityes = RelatedIdentities.GetChannelRelatedIdentities(siteInfo.Id, nodeInfo.Id); - - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - var styleInfoList = TableStyleManager.GetTableStyleInfoList(tableName, relatedidentityes); - styleInfoList = ContentUtility.GetAllTableStyleInfoList(styleInfoList); - - var accessDao = new AccessDao(filePath); - - var createTableSqlString = accessDao.GetCreateTableSqlString(nodeInfo.ChannelName, styleInfoList, displayAttributes); - accessDao.ExecuteSqlString(createTableSqlString); - - bool isExport; - - var insertSqlArrayList = accessDao.GetInsertSqlStringArrayList(nodeInfo.ChannelName, siteInfo.Id, nodeInfo.Id, tableName, styleInfoList, displayAttributes, contentIdList, isPeriods, dateFrom, dateTo, checkedState, out isExport); - - foreach (string insertSql in insertSqlArrayList) - { - accessDao.ExecuteSqlString(insertSql); - } - - return isExport; - } - - public static List GetContentsByAccessFile(string filePath, SiteInfo siteInfo, ChannelInfo nodeInfo) - { - var contentInfoList = new List(); - - var accessDao = new AccessDao(filePath); - var tableNames = accessDao.GetTableNames(); - if (tableNames != null && tableNames.Length > 0) - { - foreach (var tableName in tableNames) - { - string sqlString = $"SELECT * FROM [{tableName}]"; - var dataset = accessDao.ReturnDataSet(sqlString); - - var oleDt = dataset.Tables[0]; - - if (oleDt.Rows.Count > 0) - { - var relatedidentityes = RelatedIdentities.GetChannelRelatedIdentities(siteInfo.Id, nodeInfo.Id); - - var theTableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - - var tableStyleInfoList = TableStyleManager.GetTableStyleInfoList(theTableName, relatedidentityes); - - var nameValueCollection = new NameValueCollection(); - - foreach (var styleInfo in tableStyleInfoList) - { - nameValueCollection[styleInfo.DisplayName] = styleInfo.AttributeName.ToLower(); - } - - var attributeNames = new ArrayList(); - for (var i = 0; i < oleDt.Columns.Count; i++) - { - var columnName = oleDt.Columns[i].ColumnName; - attributeNames.Add(!string.IsNullOrEmpty(nameValueCollection[columnName]) - ? nameValueCollection[columnName] - : columnName); - } - - foreach (DataRow row in oleDt.Rows) - { - var contentInfo = new ContentInfo(); - - for (var i = 0; i < oleDt.Columns.Count; i++) - { - var attributeName = attributeNames[i] as string; - if (!string.IsNullOrEmpty(attributeName)) - { - var value = row[i].ToString(); - contentInfo.Set(attributeName, value); - } - } - - if (!string.IsNullOrEmpty(contentInfo.Title)) - { - contentInfo.SiteId = siteInfo.Id; - contentInfo.ChannelId = nodeInfo.Id; - contentInfo.LastEditDate = DateTime.Now; - - contentInfoList.Add(contentInfo); - } - } - } - } - } - - return contentInfoList; - } - } -} diff --git a/SiteServer.CMS/Core/Office/ExcelObject.cs b/SiteServer.CMS/Core/Office/ExcelObject.cs deleted file mode 100644 index f6b86fddf..000000000 --- a/SiteServer.CMS/Core/Office/ExcelObject.cs +++ /dev/null @@ -1,164 +0,0 @@ -using SiteServer.Utils; -using SiteServer.CMS.Model; -using System; -using System.Collections.Specialized; -using System.Collections.Generic; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Core.Office -{ - public class ExcelObject - { - public static void CreateExcelFileForContents(string filePath, SiteInfo siteInfo, - ChannelInfo nodeInfo, List contentIdList, List displayAttributes, bool isPeriods, string startDate, - string endDate, ETriState checkedState) - { - DirectoryUtils.CreateDirectoryIfNotExists(DirectoryUtils.GetDirectoryPath(filePath)); - FileUtils.DeleteFileIfExists(filePath); - - var head = new List(); - var rows = new List>(); - - var relatedidentityes = - RelatedIdentities.GetChannelRelatedIdentities(siteInfo.Id, nodeInfo.Id); - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - var styleInfoList = ContentUtility.GetAllTableStyleInfoList(TableStyleManager.GetTableStyleInfoList(tableName, relatedidentityes)); - - foreach (var styleInfo in styleInfoList) - { - if (displayAttributes.Contains(styleInfo.AttributeName)) - { - head.Add(styleInfo.DisplayName); - } - } - - if (contentIdList == null || contentIdList.Count == 0) - { - contentIdList = DataProvider.ContentDao.GetContentIdList(tableName, nodeInfo.Id, isPeriods, - startDate, endDate, checkedState); - } - - foreach (var contentId in contentIdList) - { - var contentInfo = DataProvider.ContentDao.GetContentInfo(tableName, contentId); - if (contentInfo != null) - { - var row = new List(); - - foreach (var styleInfo in styleInfoList) - { - if (displayAttributes.Contains(styleInfo.AttributeName)) - { - var value = contentInfo.GetString(styleInfo.AttributeName); - row.Add(StringUtils.StripTags(value)); - } - } - - rows.Add(row); - } - } - - CsvUtils.Export(filePath, head, rows); - } - - public static void CreateExcelFileForUsers(string filePath, ETriState checkedState) - { - DirectoryUtils.CreateDirectoryIfNotExists(DirectoryUtils.GetDirectoryPath(filePath)); - FileUtils.DeleteFileIfExists(filePath); - - var head = new List - { - "用户名", - "姓名", - "邮箱", - "手机", - "注册时间", - "最后一次活动时间" - }; - var rows = new List>(); - - List userIdList = DataProvider.UserDao.GetIdList(checkedState != ETriState.False); - if (checkedState == ETriState.All) - { - userIdList.AddRange(DataProvider.UserDao.GetIdList(false)); - } - - foreach (var userId in userIdList) - { - var userInfo = DataProvider.UserDao.GetUserInfo(userId); - - rows.Add(new List - { - userInfo.UserName, - userInfo.DisplayName, - userInfo.Email, - userInfo.Mobile, - DateUtils.GetDateAndTimeString(userInfo.CreateDate), - DateUtils.GetDateAndTimeString(userInfo.LastActivityDate) - }); - } - - CsvUtils.Export(filePath, head, rows); - } - - public static List GetContentsByCsvFile(string filePath, SiteInfo siteInfo, - ChannelInfo nodeInfo) - { - var contentInfoList = new List(); - - List head; - List> rows; - CsvUtils.Import(filePath, out head, out rows); - - if (rows.Count <= 0) return contentInfoList; - - var relatedidentityes = - RelatedIdentities.GetChannelRelatedIdentities( - siteInfo.Id, nodeInfo.Id); - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - // ArrayList tableStyleInfoArrayList = TableStyleManager.GetTableStyleInfoArrayList(ETableStyle.BackgroundContent, siteInfo.AuxiliaryTableForContent, relatedidentityes); - - var styleInfoList = ContentUtility.GetAllTableStyleInfoList(TableStyleManager.GetTableStyleInfoList(tableName, relatedidentityes)); - var nameValueCollection = new NameValueCollection(); - foreach (var styleInfo in styleInfoList) - { - nameValueCollection[styleInfo.DisplayName] = styleInfo.AttributeName.ToLower(); - } - - var attributeNames = new List(); - foreach (var columnName in head) - { - attributeNames.Add(!string.IsNullOrEmpty(nameValueCollection[columnName]) - ? nameValueCollection[columnName] - : columnName); - } - - foreach (var row in rows) - { - var contentInfo = new ContentInfo(); - if (row.Count != attributeNames.Count) continue; - - for (var i = 0; i < attributeNames.Count; i++) - { - var attributeName = attributeNames[i]; - if (!string.IsNullOrEmpty(attributeName)) - { - var value = row[i]; - contentInfo.Set(attributeName, value); - } - } - - if (!string.IsNullOrEmpty(contentInfo.Title)) - { - contentInfo.SiteId = siteInfo.Id; - contentInfo.ChannelId = nodeInfo.Id; - contentInfo.LastEditDate = DateTime.Now; - - contentInfoList.Add(contentInfo); - } - } - - return contentInfoList; - } - } -} diff --git a/SiteServer.CMS/Core/Office/TxtObject.cs b/SiteServer.CMS/Core/Office/TxtObject.cs deleted file mode 100644 index 1386d08b7..000000000 --- a/SiteServer.CMS/Core/Office/TxtObject.cs +++ /dev/null @@ -1,51 +0,0 @@ -using SiteServer.Utils; -using SiteServer.CMS.Model; -using System; -using System.Collections.Generic; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Core.Office -{ - public class TxtObject - { - public static List GetContentListByTxtFile(string directoryPath, SiteInfo siteInfo, ChannelInfo nodeInfo) - { - var contentInfoList = new List(); - - var filePaths = DirectoryUtils.GetFilePaths(directoryPath); - foreach (var filePath in filePaths) - { - if (!EFileSystemTypeUtils.Equals(EFileSystemType.Txt, PathUtils.GetExtension(filePath))) continue; - - try - { - var content = FileUtils.ReadText(filePath, ECharset.gb2312); - if (!string.IsNullOrEmpty(content)) - { - content = content.Trim(); - var title = StringUtils.GetFirstOfStringCollection(content, '\r'); - if (!string.IsNullOrEmpty(title)) - { - var contentInfo = new ContentInfo - { - Title = title.Trim(), - SiteId = siteInfo.Id, - ChannelId = nodeInfo.Id, - LastEditDate = DateTime.Now - }; - contentInfo.Set(BackgroundContentAttribute.Content, StringUtils.ReplaceNewlineToBr(content.Replace(title, string.Empty).Trim())); - - contentInfoList.Add(contentInfo); - } - } - } - catch - { - // ignored - } - } - - return contentInfoList; - } - } -} diff --git a/SiteServer.CMS/Core/PageUtility.cs b/SiteServer.CMS/Core/PageUtility.cs deleted file mode 100644 index 13ab0643b..000000000 --- a/SiteServer.CMS/Core/PageUtility.cs +++ /dev/null @@ -1,531 +0,0 @@ -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using System; -using SiteServer.CMS.Api.Preview; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.Plugin; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Core -{ - public class PageUtility - { - private PageUtility() - { - } - - public static string GetSiteUrl(SiteInfo siteInfo, bool isLocal) - { - return GetSiteUrl(siteInfo, string.Empty, isLocal); - } - - public static string GetSiteUrl(SiteInfo siteInfo, string requestPath, bool isLocal) - { - return isLocal - ? GetLocalSiteUrl(siteInfo, requestPath) - : GetRemoteSiteUrl(siteInfo, requestPath); - } - - public static string GetRemoteSiteUrl(SiteInfo siteInfo) - { - return GetRemoteSiteUrl(siteInfo, string.Empty); - } - - public static string GetRemoteSiteUrl(SiteInfo siteInfo, string requestPath) - { - var url = siteInfo.Additional.WebUrl; - - if (string.IsNullOrEmpty(url)) - { - url = "/"; - } - else - { - if (url != "/" && url.EndsWith("/")) - { - url = url.Substring(0, url.Length - 1); - } - } - - if (string.IsNullOrEmpty(requestPath)) return url; - - requestPath = requestPath.Replace(PathUtils.SeparatorChar, PageUtils.SeparatorChar); - requestPath = PathUtils.RemovePathInvalidChar(requestPath); - if (requestPath.StartsWith("/")) - { - requestPath = requestPath.Substring(1); - } - - url = PageUtils.Combine(url, requestPath); - - if (!siteInfo.Additional.IsSeparatedAssets) return url; - - var assetsUrl = PageUtils.Combine(siteInfo.Additional.WebUrl, - siteInfo.Additional.AssetsDir); - if (StringUtils.StartsWithIgnoreCase(url, assetsUrl)) - { - url = StringUtils.ReplaceStartsWithIgnoreCase(url, assetsUrl, siteInfo.Additional.AssetsUrl); - } - - return url; - } - - public static string GetLocalSiteUrl(SiteInfo siteInfo) - { - return GetLocalSiteUrl(siteInfo, string.Empty); - } - - public static string GetLocalSiteUrl(SiteInfo siteInfo, string requestPath) - { - var url = PageUtils.ParseNavigationUrl($"~/{siteInfo.SiteDir}"); - - if (string.IsNullOrEmpty(url)) - { - url = "/"; - } - else - { - if (url != "/" && url.EndsWith("/")) - { - url = url.Substring(0, url.Length - 1); - } - } - - if (string.IsNullOrEmpty(requestPath)) return url; - - requestPath = requestPath.Replace(PathUtils.SeparatorChar, PageUtils.SeparatorChar); - requestPath = PathUtils.RemovePathInvalidChar(requestPath); - if (requestPath.StartsWith("/")) - { - requestPath = requestPath.Substring(1); - } - - url = PageUtils.Combine(url, requestPath); - - return url; - } - - public static string GetSiteUrlByPhysicalPath(SiteInfo siteInfo, string physicalPath, bool isLocal) - { - if (siteInfo == null) - { - var publishmentSystemId = PathUtility.GetCurrentSiteId(); - siteInfo = SiteManager.GetSiteInfo(publishmentSystemId); - } - if (string.IsNullOrEmpty(physicalPath)) return siteInfo.Additional.WebUrl; - - var publishmentSystemPath = PathUtility.GetSitePath(siteInfo); - var requestPath = StringUtils.StartsWithIgnoreCase(physicalPath, publishmentSystemPath) - ? StringUtils.ReplaceStartsWithIgnoreCase(physicalPath, publishmentSystemPath, string.Empty) - : string.Empty; - - return GetSiteUrl(siteInfo, requestPath, isLocal); - } - - // 得到发布系统首页地址 - public static string GetIndexPageUrl(SiteInfo siteInfo, bool isLocal) - { - var indexTemplateId = TemplateManager.GetIndexTempalteId(siteInfo.Id); - var createdFileFullName = TemplateManager.GetCreatedFileFullName(siteInfo.Id, indexTemplateId); - - return isLocal - ? ApiRoutePreview.GetSiteUrl(siteInfo.Id) - : ParseNavigationUrl(siteInfo, createdFileFullName, false); - } - - public static string GetFileUrl(SiteInfo siteInfo, int fileTemplateId, bool isLocal) - { - var createdFileFullName = TemplateManager.GetCreatedFileFullName(siteInfo.Id, fileTemplateId); - - return isLocal - ? ApiRoutePreview.GetFileUrl(siteInfo.Id, fileTemplateId) - : ParseNavigationUrl(siteInfo, createdFileFullName, false); - } - - public static string GetContentUrl(SiteInfo siteInfo, IContentInfo contentInfo, bool isLocal) - { - return GetContentUrlById(siteInfo, contentInfo, isLocal); - } - - public static string GetContentUrl(SiteInfo siteInfo, ChannelInfo nodeInfo, int contentId, bool isLocal) - { - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - var contentInfo = Content.GetContentInfo(tableName, contentId); - return GetContentUrlById(siteInfo, contentInfo, isLocal); - } - - /// - /// 对GetContentUrlByID的优化 - /// 通过传入参数contentInfoCurrent,避免对ContentInfo查询太多 - /// - private static string GetContentUrlById(SiteInfo siteInfo, IContentInfo contentInfoCurrent, bool isLocal) - { - if (contentInfoCurrent == null) return PageUtils.UnclickedUrl; - - if (isLocal) - { - return ApiRoutePreview.GetContentUrl(siteInfo.Id, contentInfoCurrent.ChannelId, - contentInfoCurrent.Id); - } - - var sourceId = contentInfoCurrent.SourceId; - var referenceId = contentInfoCurrent.ReferenceId; - var linkUrl = contentInfoCurrent.GetString(ContentAttribute.LinkUrl); - var channelId = contentInfoCurrent.ChannelId; - if (referenceId > 0 && contentInfoCurrent.GetString(ContentAttribute.TranslateContentType) != ETranslateContentType.ReferenceContent.ToString()) - { - if (sourceId > 0 && (ChannelManager.IsExists(siteInfo.Id, sourceId) || ChannelManager.IsExists(sourceId))) - { - var targetChannelId = sourceId; - var targetSiteId = Node.GetSiteId(targetChannelId); - var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); - var targetChannelInfo = ChannelManager.GetChannelInfo(targetSiteId, targetChannelId); - - var tableName = ChannelManager.GetTableName(targetSiteInfo, targetChannelInfo); - var contentInfo = Content.GetContentInfo(tableName, referenceId); - if (contentInfo == null || contentInfo.ChannelId <= 0) - { - return PageUtils.UnclickedUrl; - } - if (contentInfo.SiteId == targetSiteInfo.Id) - { - return GetContentUrlById(targetSiteInfo, contentInfo, false); - } - var siteInfoTmp = SiteManager.GetSiteInfo(contentInfo.SiteId); - return GetContentUrlById(siteInfoTmp, contentInfo, false); - } - else - { - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - channelId = Content.GetChannelId(tableName, referenceId); - linkUrl = Content.GetValue(tableName, referenceId, ContentAttribute.LinkUrl); - if (ChannelManager.IsExists(siteInfo.Id, channelId)) - { - return GetContentUrlById(siteInfo, channelId, referenceId, 0, 0, linkUrl, false); - } - var targetSiteId = Node.GetSiteId(channelId); - var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); - return GetContentUrlById(targetSiteInfo, channelId, referenceId, 0, 0, linkUrl, false); - } - } - - if (!string.IsNullOrEmpty(linkUrl)) - { - return ParseNavigationUrl(siteInfo, linkUrl, false); - } - var contentUrl = PathUtility.ContentFilePathRules.Parse(siteInfo, channelId, contentInfoCurrent); - return GetSiteUrl(siteInfo, contentUrl, false); - } - - private static string GetContentUrlById(SiteInfo siteInfo, int channelId, int contentId, int sourceId, int referenceId, string linkUrl, bool isLocal) - { - if (isLocal) - { - return ApiRoutePreview.GetContentUrl(siteInfo.Id, channelId, contentId); - } - - var tableNameCurrent = ChannelManager.GetTableName(siteInfo, channelId); - var contentInfoCurrent = Content.GetContentInfo(tableNameCurrent, contentId); - - if (referenceId > 0 && contentInfoCurrent.GetString(ContentAttribute.TranslateContentType) != ETranslateContentType.ReferenceContent.ToString()) - { - if (sourceId > 0 && (ChannelManager.IsExists(siteInfo.Id, sourceId) || ChannelManager.IsExists(sourceId))) - { - var targetChannelId = sourceId; - var targetSiteId = Node.GetSiteId(targetChannelId); - var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); - var targetChannelInfo = ChannelManager.GetChannelInfo(targetSiteId, targetChannelId); - - var tableName = ChannelManager.GetTableName(targetSiteInfo, targetChannelInfo); - var contentInfo = Content.GetContentInfo(tableName, referenceId); - if (contentInfo == null || contentInfo.ChannelId <= 0) - { - return PageUtils.UnclickedUrl; - } - if (contentInfo.SiteId == targetSiteInfo.Id) - { - return GetContentUrlById(targetSiteInfo, contentInfo.ChannelId, contentInfo.Id, contentInfo.SourceId, contentInfo.ReferenceId, contentInfo.GetString(ContentAttribute.LinkUrl), false); - } - var siteInfoTmp = SiteManager.GetSiteInfo(contentInfo.SiteId); - return GetContentUrlById(siteInfoTmp, contentInfo.ChannelId, contentInfo.Id, contentInfo.SourceId, contentInfo.ReferenceId, contentInfo.GetString(ContentAttribute.LinkUrl), false); - } - else - { - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - channelId = Content.GetChannelId(tableName, referenceId); - linkUrl = Content.GetValue(tableName, referenceId, ContentAttribute.LinkUrl); - return GetContentUrlById(siteInfo, channelId, referenceId, 0, 0, linkUrl, false); - } - } - if (!string.IsNullOrEmpty(linkUrl)) - { - return ParseNavigationUrl(siteInfo, linkUrl, false); - } - var contentUrl = PathUtility.ContentFilePathRules.Parse(siteInfo, channelId, contentId); - return GetSiteUrl(siteInfo, contentUrl, false); - } - - private static string GetChannelUrlNotComputed(SiteInfo siteInfo, int channelId, bool isLocal) - { - if (channelId == siteInfo.Id) - { - return GetIndexPageUrl(siteInfo, isLocal); - } - var linkUrl = string.Empty; - var nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - if (nodeInfo != null) - { - linkUrl = nodeInfo.LinkUrl; - } - - if (string.IsNullOrEmpty(linkUrl)) - { - if (nodeInfo != null) - { - var filePath = nodeInfo.FilePath; - - if (string.IsNullOrEmpty(filePath)) - { - var channelUrl = PathUtility.ChannelFilePathRules.Parse(siteInfo, channelId); - return GetSiteUrl(siteInfo, channelUrl, isLocal); - } - return ParseNavigationUrl(siteInfo, PathUtility.AddVirtualToPath(filePath), isLocal); - } - } - - return ParseNavigationUrl(siteInfo, linkUrl, isLocal); - } - - //得到栏目经过计算后的连接地址 - public static string GetChannelUrl(SiteInfo siteInfo, ChannelInfo nodeInfo, bool isLocal) - { - if (isLocal) - { - return ApiRoutePreview.GetChannelUrl(siteInfo.Id, nodeInfo.Id); - } - var url = string.Empty; - if (nodeInfo != null) - { - if (nodeInfo.ParentId == 0) - { - url = GetChannelUrlNotComputed(siteInfo, nodeInfo.Id, false); - } - else - { - var linkType = ELinkTypeUtils.GetEnumType(nodeInfo.LinkType); - if (linkType == ELinkType.None) - { - url = GetChannelUrlNotComputed(siteInfo, nodeInfo.Id, false); - } - else if (linkType == ELinkType.NoLink) - { - url = PageUtils.UnclickedUrl; - } - else - { - if (linkType == ELinkType.NoLinkIfContentNotExists) - { - url = nodeInfo.ContentNum == 0 ? PageUtils.UnclickedUrl : GetChannelUrlNotComputed(siteInfo, nodeInfo.Id, false); - } - else if (linkType == ELinkType.LinkToOnlyOneContent) - { - if (nodeInfo.ContentNum == 1) - { - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - //var contentId = StlCacheManager.FirstContentId.GetValue(siteInfo, nodeInfo); - var contentId = Content.GetContentId(tableName, nodeInfo.Id, ETaxisTypeUtils.GetContentOrderByString(ETaxisTypeUtils.GetEnumType(nodeInfo.Additional.DefaultTaxisType))); - url = GetContentUrl(siteInfo, nodeInfo, contentId, false); - } - else - { - url = GetChannelUrlNotComputed(siteInfo, nodeInfo.Id, false); - } - } - else if (linkType == ELinkType.NoLinkIfContentNotExistsAndLinkToOnlyOneContent) - { - if (nodeInfo.ContentNum == 0) - { - url = PageUtils.UnclickedUrl; - } - else if (nodeInfo.ContentNum == 1) - { - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - var contentId = Content.GetContentId(tableName, nodeInfo.Id, ETaxisTypeUtils.GetContentOrderByString(ETaxisTypeUtils.GetEnumType(nodeInfo.Additional.DefaultTaxisType))); - //var contentId = StlCacheManager.FirstContentId.GetValue(siteInfo, nodeInfo); - url = GetContentUrl(siteInfo, nodeInfo, contentId, false); - } - else - { - url = GetChannelUrlNotComputed(siteInfo, nodeInfo.Id, false); - } - } - else if (linkType == ELinkType.LinkToFirstContent) - { - if (nodeInfo.ContentNum >= 1) - { - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - var contentId = Content.GetContentId(tableName, nodeInfo.Id, ETaxisTypeUtils.GetContentOrderByString(ETaxisTypeUtils.GetEnumType(nodeInfo.Additional.DefaultTaxisType))); - //var contentId = StlCacheManager.FirstContentId.GetValue(siteInfo, nodeInfo); - url = GetContentUrl(siteInfo, nodeInfo, contentId, false); - } - else - { - url = GetChannelUrlNotComputed(siteInfo, nodeInfo.Id, false); - } - } - else if (linkType == ELinkType.NoLinkIfContentNotExistsAndLinkToFirstContent) - { - if (nodeInfo.ContentNum >= 1) - { - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - var contentId = Content.GetContentId(tableName, nodeInfo.Id, ETaxisTypeUtils.GetContentOrderByString(ETaxisTypeUtils.GetEnumType(nodeInfo.Additional.DefaultTaxisType))); - //var contentId = StlCacheManager.FirstContentId.GetValue(siteInfo, nodeInfo); - url = GetContentUrl(siteInfo, nodeInfo, contentId, false); - } - else - { - url = PageUtils.UnclickedUrl; - } - } - else if (linkType == ELinkType.NoLinkIfChannelNotExists) - { - url = nodeInfo.ChildrenCount == 0 ? PageUtils.UnclickedUrl : GetChannelUrlNotComputed(siteInfo, nodeInfo.Id, false); - } - else if (linkType == ELinkType.LinkToLastAddChannel) - { - var lastAddChannelInfo = Node.GetChannelInfoByLastAddDate(nodeInfo.Id); - url = lastAddChannelInfo != null ? GetChannelUrl(siteInfo, lastAddChannelInfo, false) : GetChannelUrlNotComputed(siteInfo, nodeInfo.Id, false); - } - else if (linkType == ELinkType.LinkToFirstChannel) - { - var firstChannelInfo = Node.GetChannelInfoByTaxis(nodeInfo.Id); - url = firstChannelInfo != null ? GetChannelUrl(siteInfo, firstChannelInfo, false) : GetChannelUrlNotComputed(siteInfo, nodeInfo.Id, false); - } - else if (linkType == ELinkType.NoLinkIfChannelNotExistsAndLinkToLastAddChannel) - { - var lastAddChannelInfo = Node.GetChannelInfoByLastAddDate(nodeInfo.Id); - url = lastAddChannelInfo != null ? GetChannelUrl(siteInfo, lastAddChannelInfo, false) : PageUtils.UnclickedUrl; - } - else if (linkType == ELinkType.NoLinkIfChannelNotExistsAndLinkToFirstChannel) - { - var firstChannelInfo = Node.GetChannelInfoByTaxis(nodeInfo.Id); - url = firstChannelInfo != null ? GetChannelUrl(siteInfo, firstChannelInfo, false) : PageUtils.UnclickedUrl; - } - } - } - } - return url; - } - - public static string GetInputChannelUrl(SiteInfo siteInfo, ChannelInfo nodeInfo, bool isLocal) - { - var channelUrl = GetChannelUrl(siteInfo, nodeInfo, isLocal); - if (string.IsNullOrEmpty(channelUrl)) return channelUrl; - - channelUrl = StringUtils.ReplaceStartsWith(channelUrl, siteInfo.Additional.WebUrl, string.Empty); - channelUrl = channelUrl.Trim('/'); - channelUrl = "/" + channelUrl; - return channelUrl; - } - - public static string AddVirtualToUrl(string url) - { - var resolvedUrl = url; - if (string.IsNullOrEmpty(url) || PageUtils.IsProtocolUrl(url)) return resolvedUrl; - - if (!url.StartsWith("@") && !url.StartsWith("~")) - { - resolvedUrl = PageUtils.Combine("@/", url); - } - return resolvedUrl; - } - - public static string ParseNavigationUrlAddPrefix(SiteInfo siteInfo, string url, bool isLocal) - { - if (string.IsNullOrEmpty(url)) return ParseNavigationUrl(siteInfo, url, isLocal); - - if (!url.StartsWith("~/") && !url.StartsWith("@/")) - { - url = "@/" + url; - } - return ParseNavigationUrl(siteInfo, url, isLocal); - } - - public static string ParseNavigationUrl(int publishmentSystemId, string url, bool isLocal) - { - var siteInfo = SiteManager.GetSiteInfo(publishmentSystemId); - return ParseNavigationUrl(siteInfo, url, isLocal); - } - - //根据发布系统属性判断是否为相对路径并返回解析后路径 - public static string ParseNavigationUrl(SiteInfo siteInfo, string url, bool isLocal) - { - if (siteInfo != null) - { - if (!string.IsNullOrEmpty(url) && url.StartsWith("@")) - { - return GetSiteUrl(siteInfo, url.Substring(1), isLocal); - } - return PageUtils.ParseNavigationUrl(url); - } - return PageUtils.ParseNavigationUrl(url); - } - - public static string GetVirtualUrl(SiteInfo siteInfo, string url) - { - var virtualUrl = StringUtils.ReplaceStartsWith(url, siteInfo.Additional.WebUrl, "@/"); - return StringUtils.ReplaceStartsWith(virtualUrl, "@//", "@/"); - } - - public static bool IsVirtualUrl(string url) - { - if (string.IsNullOrEmpty(url)) return false; - - return url.StartsWith("~") || url.StartsWith("@"); - } - - public static string GetSiteFilesUrl(string apiUrl, string relatedUrl) - { - if (string.IsNullOrEmpty(apiUrl)) - { - apiUrl = "/api"; - } - apiUrl = apiUrl.Trim().ToLower(); - if (apiUrl == "/api") - { - apiUrl = "/"; - } - else if (apiUrl.EndsWith("/api")) - { - apiUrl = apiUrl.Substring(0, apiUrl.LastIndexOf("/api", StringComparison.Ordinal)); - } - else if (apiUrl.EndsWith("/api/")) - { - apiUrl = apiUrl.Substring(0, apiUrl.LastIndexOf("/api/", StringComparison.Ordinal)); - } - if (string.IsNullOrEmpty(apiUrl)) - { - apiUrl = "/"; - } - return PageUtils.Combine(apiUrl, DirectoryUtils.SiteFiles.DirectoryName, relatedUrl); - } - - public static string GetUserFilesUrl(string apiUrl, string relatedUrl) - { - return GetSiteFilesUrl(apiUrl, PageUtils.Combine(DirectoryUtils.SiteFiles.UserFiles, relatedUrl)); - } - - public static string GetUserAvatarUrl(string apiUrl, IUserInfo userInfo) - { - var imageUrl = userInfo?.AvatarUrl; - - if (!string.IsNullOrEmpty(imageUrl)) - { - return PageUtils.IsProtocolUrl(imageUrl) ? imageUrl : GetUserFilesUrl(apiUrl, PageUtils.Combine(userInfo.UserName, imageUrl)); - } - - return SiteFilesAssets.GetUrl(apiUrl, "default_avatar.png"); - } - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Core/PermissionConfigManager.cs b/SiteServer.CMS/Core/PermissionConfigManager.cs deleted file mode 100644 index c0d3bfc87..000000000 --- a/SiteServer.CMS/Core/PermissionConfigManager.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System.Collections.Generic; -using System.Xml; -using SiteServer.CMS.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Core -{ - public class PermissionConfigManager - { - public class PermissionConfig - { - public PermissionConfig(string name, string text) - { - Name = name; - Text = text; - } - - public string Name { get; set; } - - public string Text { get; set; } - } - - public const string CacheKey = "SiteServer.CMS.Core.PermissionConfigManager"; - - public List GeneralPermissions { get; } = new List(); - - public List WebsitePermissions { get; } = new List(); - - public List ChannelPermissions { get; } = new List(); - - private PermissionConfigManager() - { - } - - public static PermissionConfigManager Instance - { - get - { - var permissionManager = CacheUtils.Get(CacheKey) as PermissionConfigManager; - if (permissionManager != null) return permissionManager; - - permissionManager = new PermissionConfigManager(); - - var path = PathUtils.GetMenusPath("Permissions.config"); - if (FileUtils.IsFileExists(path)) - { - var doc = new XmlDocument(); - doc.Load(path); - permissionManager.LoadValuesFromConfigurationXml(doc); - } - - CacheUtils.Insert(CacheKey, permissionManager, path); - return permissionManager; - } - } - - private void LoadValuesFromConfigurationXml(XmlDocument doc) - { - var coreNode = doc.SelectSingleNode("Config"); - if (coreNode != null) - { - var isMultiple = true; - foreach (XmlNode child in coreNode.ChildNodes) - { - if (child.NodeType == XmlNodeType.Comment) continue; - if (child.Name == "generalPermissions") - { - GetPermissions(child, GeneralPermissions); - } - else if (child.Name == "websitePermissions") - { - GetPermissions(child, WebsitePermissions); - } - else if (child.Name == "channelPermissions") - { - GetPermissions(child, ChannelPermissions); - } - else - { - isMultiple = false; - break; - } - } - if (!isMultiple) - { - GetPermissions(coreNode, GeneralPermissions); - } - } - - GeneralPermissions.AddRange(PluginMenuManager.GetTopPermissions()); - WebsitePermissions.AddRange(PluginMenuManager.GetSitePermissions(0)); - } - - private static void GetPermissions(XmlNode node, List list) - { - foreach (XmlNode permission in node.ChildNodes) - { - if (permission.Name == "add" && permission.Attributes != null) - { - list.Add(new PermissionConfig(permission.Attributes["name"].Value, permission.Attributes["text"].Value)); - } - } - } - } -} diff --git a/SiteServer.CMS/Core/PermissionManager.cs b/SiteServer.CMS/Core/PermissionManager.cs deleted file mode 100644 index d6904ba87..000000000 --- a/SiteServer.CMS/Core/PermissionManager.cs +++ /dev/null @@ -1,598 +0,0 @@ -using System; -using System.Collections.Generic; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Core -{ - public class PermissionManager - { - public const string CacheKeyPrefix = "SiteServer.CMS.Core.PermissionManager"; - - private string[] _roles; - private List _permissionList; - private readonly string _rolesKey; - private readonly string _permissionListKey; - - private Dictionary> _websitePermissionDict; - private Dictionary> _channelPermissionDict; - private List _channelPermissionListIgnoreChannelId; - private List _siteIdList; - private List _owningChannelIdList; - - private readonly string _websitePermissionDictKey; - private readonly string _channelPermissionDictKey; - private readonly string _channelPermissionListIgnoreChannelIdKey; - private readonly string _siteIdListKey; - private readonly string _owningChannelIdListKey; - - public static PermissionManager GetInstance(string administratorName) - { - return new PermissionManager(administratorName); - } - - private PermissionManager(string userName) - { - UserName = string.IsNullOrEmpty(userName) ? AdminManager.AnonymousUserName : userName; - - _rolesKey = GetRolesCacheKey(userName); - _permissionListKey = GetPermissionListCacheKey(userName); - _websitePermissionDictKey = GetWebsitePermissionDictCacheKey(userName); - _channelPermissionDictKey = GetChannelPermissionDictCacheKey(userName); - _channelPermissionListIgnoreChannelIdKey = GetChannelPermissionListIgnoreChannelIdCacheKey(userName); - _siteIdListKey = GetSiteIdListCacheKey(userName); - _owningChannelIdListKey = GetOwningChannelIdListCacheKey(userName); - } - - public string UserName { get; } - - public bool IsConsoleAdministrator => EPredefinedRoleUtils.IsConsoleAdministrator(Roles); - - public bool IsSystemAdministrator => EPredefinedRoleUtils.IsSystemAdministrator(Roles); - - public bool IsAdministrator => EPredefinedRoleUtils.IsAdministrator(Roles); - - public List PermissionList - { - get - { - if (_permissionList == null) - { - if (!string.IsNullOrEmpty(UserName) && !string.Equals(UserName, AdminManager.AnonymousUserName)) - { - if (CacheUtils.Get(_permissionListKey) != null) - { - _permissionList = CacheUtils.Get(_permissionListKey) as List; - } - else - { - if (EPredefinedRoleUtils.IsConsoleAdministrator(Roles)) - { - _permissionList = new List(); - foreach (var permission in PermissionConfigManager.Instance.GeneralPermissions) - { - _permissionList.Add(permission.Name); - } - } - else if (EPredefinedRoleUtils.IsSystemAdministrator(Roles)) - { - _permissionList = new List - { - ConfigManager.SettingsPermissions.Admin - }; - } - else - { - _permissionList = DataProvider.PermissionsInRolesDao.GetGeneralPermissionList(Roles); - } - - CacheUtils.InsertMinutes(_permissionListKey, _permissionList, 30); - } - } - } - return _permissionList ?? (_permissionList = new List()); - } - } - - public string[] Roles - { - get - { - if (_roles == null) - { - if (!string.IsNullOrEmpty(UserName) && !string.Equals(UserName, AdminManager.AnonymousUserName)) - { - if (CacheUtils.Get(_rolesKey) != null) - { - _roles = (string[])CacheUtils.Get(_rolesKey); - } - else - { - _roles = DataProvider.AdministratorsInRolesDao.GetRolesForUser(UserName); - CacheUtils.InsertMinutes(_rolesKey, _roles, 30); - } - } - } - if (_roles != null && _roles.Length > 0) - { - return _roles; - } - return new[] { EPredefinedRoleUtils.GetValue(EPredefinedRole.Administrator) }; - } - } - - public bool IsInRole(string role) - { - foreach (var r in Roles) - { - if (role == r) return true; - } - return false; - } - - private Dictionary> WebsitePermissionDict - { - get - { - if (_websitePermissionDict == null) - { - if (!string.IsNullOrEmpty(UserName) && !string.Equals(UserName, AdminManager.AnonymousUserName)) - { - if (CacheUtils.Get(_websitePermissionDictKey) != null) - { - _websitePermissionDict = CacheUtils.Get(_websitePermissionDictKey) as Dictionary>; - } - else - { - if (EPredefinedRoleUtils.IsSystemAdministrator(Roles)) - { - var allWebsitePermissionList = new List(); - foreach (var permission in PermissionConfigManager.Instance.WebsitePermissions) - { - allWebsitePermissionList.Add(permission.Name); - } - - _websitePermissionDict = new Dictionary>(); - if (SiteIdList.Count > 0) - { - foreach (var siteId in SiteIdList) - { - _websitePermissionDict[siteId] = allWebsitePermissionList; - } - } - } - else - { - _websitePermissionDict = DataProvider.SitePermissionsDao.GetWebsitePermissionSortedList(Roles); - } - CacheUtils.InsertMinutes(_websitePermissionDictKey, _websitePermissionDict, 30); - } - } - } - return _websitePermissionDict ?? (_websitePermissionDict = new Dictionary>()); - } - } - - public List ChannelPermissionChannelIdList - { - get - { - var list = new List(); - foreach (var dictKey in ChannelPermissionDict.Keys) - { - var kvp = ParseChannelPermissionDictKey(dictKey); - if (!list.Contains(kvp.Value)) - { - list.Add(kvp.Value); - } - } - return list; - } - } - - private Dictionary> ChannelPermissionDict - { - get - { - if (_channelPermissionDict == null) - { - if (!string.IsNullOrEmpty(UserName) && !string.Equals(UserName, AdminManager.AnonymousUserName)) - { - if (CacheUtils.Get(_channelPermissionDictKey) != null) - { - _channelPermissionDict = CacheUtils.Get(_channelPermissionDictKey) as Dictionary>; - } - else - { - if (EPredefinedRoleUtils.IsSystemAdministrator(Roles)) - { - var allChannelPermissionList = new List(); - foreach (var permission in PermissionConfigManager.Instance.ChannelPermissions) - { - allChannelPermissionList.Add(permission.Name); - } - - _channelPermissionDict = new Dictionary>(); - - if (SiteIdList.Count > 0) - { - foreach (var siteId in SiteIdList) - { - _channelPermissionDict[GetChannelPermissionDictKey(siteId, siteId)] = allChannelPermissionList; - } - } - } - else - { - _channelPermissionDict = DataProvider.SitePermissionsDao.GetChannelPermissionSortedList(Roles); - } - CacheUtils.InsertMinutes(_channelPermissionDictKey, _channelPermissionDict, 30); - } - } - } - return _channelPermissionDict ?? (_channelPermissionDict = new Dictionary>()); - } - } - - public List ChannelPermissionListIgnoreChannelId - { - get - { - if (_channelPermissionListIgnoreChannelId == null) - { - if (!string.IsNullOrEmpty(UserName) && !string.Equals(UserName, AdminManager.AnonymousUserName)) - { - if (CacheUtils.Get(_channelPermissionListIgnoreChannelIdKey) != null) - { - _channelPermissionListIgnoreChannelId = CacheUtils.Get(_channelPermissionListIgnoreChannelIdKey) as List; - } - else - { - if (EPredefinedRoleUtils.IsSystemAdministrator(Roles)) - { - _channelPermissionListIgnoreChannelId = new List(); - foreach (var permission in PermissionConfigManager.Instance.ChannelPermissions) - { - _channelPermissionListIgnoreChannelId.Add(permission.Name); - } - } - else - { - _channelPermissionListIgnoreChannelId = DataProvider.SitePermissionsDao.GetChannelPermissionListIgnoreChannelId(Roles); - } - CacheUtils.InsertMinutes(_channelPermissionListIgnoreChannelIdKey, _channelPermissionListIgnoreChannelId, 30); - } - } - } - return _channelPermissionListIgnoreChannelId ?? (_channelPermissionListIgnoreChannelId = new List()); - } - } - - public List SiteIdList - { - get - { - if (_siteIdList != null) return _siteIdList; - - if (CacheUtils.Get(_siteIdListKey) != null) - { - _siteIdList = (List)CacheUtils.Get(_siteIdListKey); - } - else - { - if (EPredefinedRoleUtils.IsConsoleAdministrator(Roles)) - { - _siteIdList = SiteManager.GetSiteIdList(); - } - else if (EPredefinedRoleUtils.IsSystemAdministrator(Roles)) - { - var theSiteIdList = DataProvider.AdministratorDao.GetSiteIdList(UserName); - _siteIdList = new List(); - foreach (var siteId in SiteManager.GetSiteIdList()) - { - if (theSiteIdList != null && theSiteIdList.Contains(siteId)) - { - _siteIdList.Add(siteId); - } - } - } - else - { - _siteIdList = new List(); - foreach (var siteId in WebsitePermissionDict.Keys) - { - _siteIdList.Add(siteId); - } - } - - if (_siteIdList == null) - { - _siteIdList = new List(); - } - - CacheUtils.InsertMinutes(_siteIdListKey, _siteIdList, 30); - } - return _siteIdList; - } - } - - public List OwningChannelIdList - { - get - { - if (_owningChannelIdList == null) - { - if (!string.IsNullOrEmpty(UserName) && !string.Equals(UserName, AdminManager.AnonymousUserName)) - { - if (CacheUtils.Get(_owningChannelIdListKey) != null) - { - _owningChannelIdList = CacheUtils.Get(_owningChannelIdListKey) as List; - } - else - { - _owningChannelIdList = new List(); - - if (!IsSystemAdministrator) - { - foreach (var dictKey in ChannelPermissionDict.Keys) - { - var kvp = ParseChannelPermissionDictKey(dictKey); - var channelInfo = ChannelManager.GetChannelInfo(kvp.Key, kvp.Value); - _owningChannelIdList.AddRange(ChannelManager.GetChannelIdList(channelInfo, EScopeType.All, string.Empty, string.Empty, string.Empty)); - } - } - - CacheUtils.InsertMinutes(_owningChannelIdListKey, _owningChannelIdList, 30); - } - } - } - return _owningChannelIdList ?? (_owningChannelIdList = new List()); - } - } - - public bool HasAdministratorPermissions(params string[] permissionArray) - { - if (IsSystemAdministrator) - { - return true; - } - var permissionList = PermissionList; - foreach (var permission in permissionArray) - { - if (permissionList.Contains(permission)) - { - return true; - } - } - - return false; - } - - public bool HasSitePermissions(int siteId) - { - return IsSystemAdministrator || WebsitePermissionDict.ContainsKey(siteId); - } - - public List GetSitePermissions(int siteId) - { - List list; - if (WebsitePermissionDict.TryGetValue(siteId, out list)) - { - return list; - } - return new List(); - } - - public bool HasSitePermissions(int siteId, params string[] sitePermissions) - { - if (IsSystemAdministrator) - { - return true; - } - if (WebsitePermissionDict.ContainsKey(siteId)) - { - var websitePermissionList = WebsitePermissionDict[siteId]; - if (websitePermissionList != null && websitePermissionList.Count > 0) - { - foreach (var sitePermission in sitePermissions) - { - if (websitePermissionList.Contains(sitePermission)) - { - return true; - } - } - } - } - - return false; - } - - public bool HasChannelPermissions(List channelPermissionList, params string[] channelPermissions) - { - if (IsSystemAdministrator) - { - return true; - } - foreach (var channelPermission in channelPermissions) - { - if (channelPermissionList.Contains(channelPermission)) - { - return true; - } - } - return false; - } - - public bool HasChannelPermissions(int siteId, int channelId) - { - if (channelId == 0) return false; - if (IsSystemAdministrator) - { - return true; - } - var dictKey = GetChannelPermissionDictKey(siteId, channelId); - if (ChannelPermissionDict.ContainsKey(dictKey)) - { - return true; - } - - var parentChannelId = ChannelManager.GetParentId(siteId, channelId); - return HasChannelPermissions(siteId, parentChannelId); - } - - public List GetChannelPermissions(int siteId, int channelId) - { - var dictKey = GetChannelPermissionDictKey(siteId, channelId); - List list; - if (ChannelPermissionDict.TryGetValue(dictKey, out list)) - { - return list; - } - return new List(); - } - - public List GetChannelPermissions(int siteId) - { - var list = new List(); - foreach (var dictKey in ChannelPermissionDict.Keys) - { - var kvp = ParseChannelPermissionDictKey(dictKey); - if (kvp.Key == siteId) - { - foreach (var permission in ChannelPermissionDict[dictKey]) - { - if (!list.Contains(permission)) - { - list.Add(permission); - } - } - } - } - - return list; - } - - public bool HasChannelPermissions(int siteId, int channelId, params string[] channelPermissions) - { - if (channelId == 0) return false; - if (IsSystemAdministrator) - { - return true; - } - var dictKey = GetChannelPermissionDictKey(siteId, channelId); - if (ChannelPermissionDict.ContainsKey(dictKey) && HasChannelPermissions(ChannelPermissionDict[dictKey], channelPermissions)) - { - return true; - } - - var parentChannelId = ChannelManager.GetParentId(siteId, channelId); - return HasChannelPermissions(siteId, parentChannelId, channelPermissions); - } - - public bool HasChannelPermissionsIgnoreChannelId(params string[] channelPermissions) - { - if (IsSystemAdministrator) - { - return true; - } - if (HasChannelPermissions(ChannelPermissionListIgnoreChannelId, channelPermissions)) - { - return true; - } - return false; - } - - public bool IsOwningChannelId(int channelId) - { - if (IsSystemAdministrator) - { - return true; - } - if (OwningChannelIdList.Contains(channelId)) - { - return true; - } - return false; - } - - public bool IsDescendantOwningChannelId(int siteId, int channelId) - { - if (IsSystemAdministrator) - { - return true; - } - - var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var channelIdList = ChannelManager.GetChannelIdList(channelInfo, EScopeType.Descendant, string.Empty, string.Empty, string.Empty); - foreach (var theChannelId in channelIdList) - { - if (IsOwningChannelId(theChannelId)) - { - return true; - } - } - return false; - } - - public bool IsViewContentOnlySelf(int siteId, int channelId) - { - if (IsConsoleAdministrator || IsSystemAdministrator) - return false; - if (HasChannelPermissions(siteId, channelId, ConfigManager.ChannelPermissions.ContentCheck)) - return false; - return ConfigManager.SystemConfigInfo.IsViewContentOnlySelf; - } - - public static string GetChannelPermissionDictKey(int siteId, int channelId) - { - return $"{siteId}_{channelId}"; - } - - private static KeyValuePair ParseChannelPermissionDictKey(string dictKey) - { - if (string.IsNullOrEmpty(dictKey) || dictKey.IndexOf("_", StringComparison.Ordinal) == -1) return new KeyValuePair(0, 0); - - return new KeyValuePair(TranslateUtils.ToInt(dictKey.Split('_')[0]), TranslateUtils.ToInt(dictKey.Split('_')[1])); - } - - private static string GetRolesCacheKey(string userName) - { - return $"{CacheKeyPrefix}.{nameof(GetRolesCacheKey)}.{userName}"; - } - - private static string GetPermissionListCacheKey(string userName) - { - return $"{CacheKeyPrefix}.{nameof(GetPermissionListCacheKey)}.{userName}"; - } - - private static string GetWebsitePermissionDictCacheKey(string userName) - { - return $"{CacheKeyPrefix}.{nameof(GetWebsitePermissionDictCacheKey)}.{userName}"; - } - - private static string GetChannelPermissionDictCacheKey(string userName) - { - return $"{CacheKeyPrefix}.{nameof(GetChannelPermissionDictCacheKey)}.{userName}"; - } - - private static string GetChannelPermissionListIgnoreChannelIdCacheKey(string userName) - { - return $"{CacheKeyPrefix}.{nameof(GetChannelPermissionListIgnoreChannelIdCacheKey)}.{userName}"; - } - - private static string GetSiteIdListCacheKey(string userName) - { - return $"{CacheKeyPrefix}.{nameof(GetSiteIdListCacheKey)}.{userName}"; - } - - private static string GetOwningChannelIdListCacheKey(string userName) - { - return $"{CacheKeyPrefix}.{nameof(GetOwningChannelIdListCacheKey)}.{userName}"; - } - - public static void ClearAllCache() - { - CacheUtils.RemoveByStartString(CacheKeyPrefix); - } - } -} diff --git a/SiteServer.CMS/Core/RelatedIdentities.cs b/SiteServer.CMS/Core/RelatedIdentities.cs deleted file mode 100644 index c2f8f4d0c..000000000 --- a/SiteServer.CMS/Core/RelatedIdentities.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System.Collections.Generic; -using SiteServer.Utils; -using SiteServer.CMS.Model; - -namespace SiteServer.CMS.Core -{ - public class RelatedIdentities - { - private RelatedIdentities() - { - } - - public static List GetRelatedIdentities(int siteId, int relatedIdentity) - { - List relatedIdentities = GetChannelRelatedIdentities(siteId, relatedIdentity); - - return relatedIdentities; - } - - public static List GetChannelRelatedIdentities(int siteId, int channelId) - { - var arraylist = new List(); - var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); - if (channelInfo != null) - { - var channelIdCollection = "0," + channelInfo.Id; - if (channelInfo.ParentsCount > 0) - { - channelIdCollection = "0," + channelInfo.ParentsPath + "," + channelInfo.Id; - } - - arraylist = TranslateUtils.StringCollectionToIntList(channelIdCollection); - arraylist.Reverse(); - } - else - { - arraylist.Add(0); - } - return arraylist; - } - - public static List GetTableStyleInfoList(SiteInfo siteInfo, int channelId) - { - List relatedIdentities = GetChannelRelatedIdentities(siteInfo.Id, channelId); - - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - - return TableStyleManager.GetTableStyleInfoList(tableName, relatedIdentities); - } - } -} diff --git a/SiteServer.CMS/Core/RoleManager.cs b/SiteServer.CMS/Core/RoleManager.cs deleted file mode 100644 index e0741649a..000000000 --- a/SiteServer.CMS/Core/RoleManager.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Web; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Core -{ - public class RoleManager - { - private RoleManager() { } - - public static void CreatePredefinedRolesIfNotExists() - { - var allPredefinedRoles = EPredefinedRoleUtils.GetAllPredefinedRole(); - foreach (var enumRole in allPredefinedRoles) - { - if (!DataProvider.RoleDao.IsRoleExists(EPredefinedRoleUtils.GetValue(enumRole))) - { - DataProvider.RoleDao.InsertRole(EPredefinedRoleUtils.GetValue(enumRole), string.Empty, EPredefinedRoleUtils.GetText(enumRole)); - } - } - } - - public static void DeleteCookie() - { - var current = HttpContext.Current; - if ((current != null) && current.Request.Browser.Cookies) - { - var text = string.Empty; - if (current.Request.Browser["supportsEmptyStringInCookieValue"] == "false") - { - text = "NoCookie"; - } - var cookie = new HttpCookie(CookieName, text) - { - Path = "/", - Domain = string.Empty, - Expires = new DateTime(0x7cf, 10, 12), - Secure = false - }; - current.Response.Cookies.Remove(CookieName); - current.Response.Cookies.Add(cookie); - } - } - - public const string CookieName = "BAIRONG.ROLES"; - public const int CookieTimeout = 90; - public const string CookiePath = "/"; - public const bool CookieSlidingExpiration = true; - public const int MaxCachedResults = 1000; - public const string Domain = ""; - public const bool CreatePersistentCookie = true; - public const bool CookieRequireSsl = false; - public const bool CacheRolesInCookie = true; - } -} diff --git a/SiteServer.CMS/Core/SiteManager.cs b/SiteServer.CMS/Core/SiteManager.cs deleted file mode 100644 index bd65db3c8..000000000 --- a/SiteServer.CMS/Core/SiteManager.cs +++ /dev/null @@ -1,439 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.Utils.IO; -using SiteServer.CMS.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Core -{ - public static class SiteManager - { - private static class SiteManagerCache - { - private static readonly object LockObject = new object(); - private const string CacheKey = "SiteServer.CMS.Core.SiteManager"; - private static readonly FileWatcherClass FileWatcher; - - static SiteManagerCache() - { - FileWatcher = new FileWatcherClass(FileWatcherClass.Site); - FileWatcher.OnFileChange += FileWatcher_OnFileChange; - } - - private static void FileWatcher_OnFileChange(object sender, EventArgs e) - { - CacheUtils.Remove(CacheKey); - } - - public static void Clear() - { - CacheUtils.Remove(CacheKey); - FileWatcher.UpdateCacheFile(); - } - - public static List> GetSiteInfoKeyValuePairList() - { - var retval = CacheUtils.Get>>(CacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = CacheUtils.Get>>(CacheKey); - if (retval == null) - { - var list = DataProvider.SiteDao.GetSiteInfoKeyValuePairList(); - retval = new List>(); - foreach (var pair in list) - { - var siteInfo = pair.Value; - if (siteInfo == null) continue; - - siteInfo.SiteDir = GetSiteDir(list, siteInfo); - retval.Add(pair); - } - - CacheUtils.Insert(CacheKey, retval); - } - } - - return retval; - } - } - - public static void ClearCache() - { - SiteManagerCache.Clear(); - } - - public static List GetSiteInfoList() - { - var pairList = SiteManagerCache.GetSiteInfoKeyValuePairList(); - return pairList.Select(pair => pair.Value).ToList(); - } - - public static SiteInfo GetSiteInfo(int siteId) - { - if (siteId <= 0) return null; - - var list = SiteManagerCache.GetSiteInfoKeyValuePairList(); - - foreach (var pair in list) - { - var theSiteId = pair.Key; - if (theSiteId != siteId) continue; - var siteInfo = pair.Value; - return siteInfo; - } - return null; - } - - public static SiteInfo GetSiteInfoBySiteName(string siteName) - { - var list = SiteManagerCache.GetSiteInfoKeyValuePairList(); - - foreach (var pair in list) - { - var siteInfo = pair.Value; - if (siteInfo == null) continue; - - if (StringUtils.EqualsIgnoreCase(siteInfo.SiteName, siteName)) - { - return siteInfo; - } - } - return null; - } - - public static SiteInfo GetSiteInfoByDirectory(string siteDir) - { - var list = SiteManagerCache.GetSiteInfoKeyValuePairList(); - - foreach (var pair in list) - { - var siteInfo = pair.Value; - if (siteInfo == null) continue; - - if (StringUtils.EqualsIgnoreCase(siteInfo.SiteDir, siteDir)) - { - return siteInfo; - } - } - return null; - } - - public static List GetSiteIdList() - { - var pairList = SiteManagerCache.GetSiteInfoKeyValuePairList(); - var list = new List(); - foreach (var pair in pairList) - { - list.Add(pair.Key); - } - return list; - } - - public static List GetSiteIdListOrderByLevel() - { - var retval = new List(); - - var siteIdList = GetSiteIdList(); - var siteInfoList = new List(); - var parentWithChildren = new Hashtable(); - var hqSiteId = 0; - foreach (var siteId in siteIdList) - { - var siteInfo = GetSiteInfo(siteId); - if (siteInfo.IsRoot) - { - hqSiteId = siteInfo.Id; - } - else - { - if (siteInfo.ParentId == 0) - { - siteInfoList.Add(siteInfo); - } - else - { - var children = new List(); - if (parentWithChildren.Contains(siteInfo.ParentId)) - { - children = (List)parentWithChildren[siteInfo.ParentId]; - } - children.Add(siteInfo); - parentWithChildren[siteInfo.ParentId] = children; - } - } - } - - if (hqSiteId > 0) - { - retval.Add(hqSiteId); - } - foreach (var siteInfo in siteInfoList) - { - AddSiteIdList(retval, siteInfo, parentWithChildren, 0); - } - return retval; - } - - private static void AddSiteIdList(List dataSource, SiteInfo siteInfo, Hashtable parentWithChildren, int level) - { - dataSource.Add(siteInfo.Id); - - if (parentWithChildren[siteInfo.Id] != null) - { - var children = (List)parentWithChildren[siteInfo.Id]; - level++; - foreach (var subSiteInfo in children) - { - AddSiteIdList(dataSource, subSiteInfo, parentWithChildren, level); - } - } - } - - public static void GetAllParentSiteIdList(List parentSiteIds, List siteIdCollection, int siteId) - { - var siteInfo = GetSiteInfo(siteId); - var parentSiteId = -1; - foreach (var psId in siteIdCollection) - { - if (psId != siteInfo.ParentId) continue; - parentSiteId = psId; - break; - } - if (parentSiteId == -1) return; - - parentSiteIds.Add(parentSiteId); - GetAllParentSiteIdList(parentSiteIds, siteIdCollection, parentSiteId); - } - - public static bool IsExists(int siteId) - { - if (siteId == 0) return false; - return GetSiteInfo(siteId) != null; - } - - public static List GetTableNameList(SiteInfo siteInfo) - { - return new List - { - siteInfo.TableName - }; - } - - //public static ETableStyle GetTableStyle(SiteInfo siteInfo, string tableName) - //{ - // var tableStyle = ETableStyle.Custom; - - // if (StringUtils.EqualsIgnoreCase(tableName, siteInfo.AuxiliaryTableForContent)) - // { - // tableStyle = ETableStyle.BackgroundContent; - // } - // else if (StringUtils.EqualsIgnoreCase(tableName, DataProvider.SiteDao.TableName)) - // { - // tableStyle = ETableStyle.Site; - // } - // else if (StringUtils.EqualsIgnoreCase(tableName, DataProvider.ChannelDao.TableName)) - // { - // tableStyle = ETableStyle.Channel; - // } - // //else if (StringUtils.EqualsIgnoreCase(tableName, DataProvider.InputContentDao.TableName)) - // //{ - // // tableStyle = ETableStyle.InputContent; - // //} - // return tableStyle; - //} - - public static int GetSiteLevel(int siteId) - { - var level = 0; - var siteInfo = GetSiteInfo(siteId); - if (siteInfo.ParentId != 0) - { - level++; - level += GetSiteLevel(siteInfo.ParentId); - } - return level; - } - - public static void AddListItems(ListControl listControl) - { - var siteIdList = GetSiteIdList(); - var mySystemInfoList = new List(); - var parentWithChildren = new Hashtable(); - SiteInfo hqSiteInfo = null; - foreach (var siteId in siteIdList) - { - var siteInfo = GetSiteInfo(siteId); - if (siteInfo.IsRoot) - { - hqSiteInfo = siteInfo; - } - else - { - if (siteInfo.ParentId == 0) - { - mySystemInfoList.Add(siteInfo); - } - else - { - var children = new List(); - if (parentWithChildren.Contains(siteInfo.ParentId)) - { - children = (List)parentWithChildren[siteInfo.ParentId]; - } - children.Add(siteInfo); - parentWithChildren[siteInfo.ParentId] = children; - } - } - } - if (hqSiteInfo != null) - { - AddListItem(listControl, hqSiteInfo, parentWithChildren, 0); - } - foreach (var siteInfo in mySystemInfoList) - { - AddListItem(listControl, siteInfo, parentWithChildren, 0); - } - } - - private static void AddListItem(ListControl listControl, SiteInfo siteInfo, Hashtable parentWithChildren, int level) - { - var padding = string.Empty; - for (var i = 0; i < level; i++) - { - padding += " "; - } - if (level > 0) - { - padding += "└ "; - } - - if (parentWithChildren[siteInfo.Id] != null) - { - var children = (List)parentWithChildren[siteInfo.Id]; - listControl.Items.Add(new ListItem(padding + siteInfo.SiteName + $"({children.Count})", siteInfo.Id.ToString())); - level++; - foreach (SiteInfo subSiteInfo in children) - { - AddListItem(listControl, subSiteInfo, parentWithChildren, level); - } - } - else - { - listControl.Items.Add(new ListItem(padding + siteInfo.SiteName, siteInfo.Id.ToString())); - } - } - - public static int GetParentSiteId(int siteId) - { - var parentSiteId = 0; - var siteInfo = GetSiteInfo(siteId); - if (siteInfo != null && siteInfo.IsRoot == false) - { - parentSiteId = siteInfo.ParentId; - if (parentSiteId == 0) - { - parentSiteId = DataProvider.SiteDao.GetIdByIsRoot(); - } - } - return parentSiteId; - } - - private static string GetSiteDir(List> listFromDb, SiteInfo siteInfo) - { - if (siteInfo == null || siteInfo.IsRoot) return string.Empty; - if (siteInfo.ParentId != 0) - { - SiteInfo parent = null; - foreach (var pair in listFromDb) - { - var theSiteId = pair.Key; - if (theSiteId != siteInfo.ParentId) continue; - parent = pair.Value; - break; - } - return PathUtils.Combine(GetSiteDir(listFromDb, parent), PathUtils.GetDirectoryName(siteInfo.SiteDir, false)); - } - return PathUtils.GetDirectoryName(siteInfo.SiteDir, false); - } - - public static List GetWritingSiteInfoList(PermissionManager permissionManager) - { - var siteInfoList = new List(); - - if (!string.IsNullOrEmpty(permissionManager.UserName)) - { - var siteIdList = new List(); - - if (permissionManager.IsConsoleAdministrator || permissionManager.IsSystemAdministrator)//如果是超级管理员或站点管理员 - { - foreach (var itemForPsid in permissionManager.SiteIdList) - { - if (!siteIdList.Contains(itemForPsid)) - { - var siteInfo = GetSiteInfo(itemForPsid); - siteInfoList.Add(siteInfo); - siteIdList.Add(itemForPsid); - } - } - } - else - { - foreach (var itemForPsid in permissionManager.SiteIdList) - { - if (!siteIdList.Contains(itemForPsid)) - { - var channelIdCollection = DataProvider.SitePermissionsDao.GetAllPermissionList(permissionManager.Roles, itemForPsid, true); - var siteInfo = GetSiteInfo(itemForPsid); - if (channelIdCollection.Count > 0) - { - siteInfoList.Add(siteInfo); - siteIdList.Add(itemForPsid); - } - } - } - } - } - - return siteInfoList; - } - - public static string GetSiteName(SiteInfo siteInfo) - { - var padding = string.Empty; - - var level = GetSiteLevel(siteInfo.Id); - string psLogo; - if (siteInfo.IsRoot) - { - psLogo = "siteHQ.gif"; - } - else - { - psLogo = "site.gif"; - if (level > 0 && level < 10) - { - psLogo = $"subsite{level + 1}.gif"; - } - } - psLogo = SiteServerAssets.GetIconUrl("tree/" + psLogo); - - for (var i = 0; i < level; i++) - { - padding += " "; - } - if (level > 0) - { - padding += "└ "; - } - - return $"{padding} {siteInfo.SiteName}"; - } - } -} diff --git a/SiteServer.CMS/Core/SmsManager.cs b/SiteServer.CMS/Core/SmsManager.cs deleted file mode 100644 index 9c173ee2d..000000000 --- a/SiteServer.CMS/Core/SmsManager.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Net; -using System.Text; -using System.Web; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Core -{ - public class SmsManager - { - public static bool IsReady() - { - return ConfigManager.SystemConfigInfo.SmsProviderType == ESmsProviderType.Yunpian && !string.IsNullOrEmpty(ConfigManager.SystemConfigInfo.SmsAppKey); - } - - public static bool Send(string mobile, string tplId, Dictionary parameters, out string errorMessage) - { - if (string.IsNullOrEmpty(mobile) || !StringUtils.IsMobile(mobile)) - { - errorMessage = "手机号码格式不正确"; - return false; - } - - errorMessage = string.Empty; - var isSuccess = false; - - if (ConfigManager.SystemConfigInfo.SmsProviderType == ESmsProviderType.Yunpian) - { - isSuccess = SendByYunpian(mobile, tplId, parameters, out errorMessage); - } - - if (!isSuccess && string.IsNullOrEmpty(errorMessage)) - { - errorMessage = "后台短信发送功能暂时无法使用,请联系管理员或稍后再试"; - } - - return isSuccess; - } - - public static bool SendCode(string mobile, int code, string tplId, out string errorMessage) - { - var parameters = new Dictionary { { "code", code.ToString() } }; - return Send(mobile, tplId, parameters, out errorMessage); - } - - private static bool SendByYunpian(string mobile, string tplId, Dictionary parameters, out string errorMessage) - { - var param = new StringBuilder(); - if (parameters != null) - { - foreach (var key in parameters.Keys) - { - var value = parameters[key] ?? string.Empty; - - param.Append(HttpUtility.UrlEncode("#" + key + "#", Encoding.UTF8) + "=" + - HttpUtility.UrlEncode(value, Encoding.UTF8)).Append("&"); - } - } - - param.Length--; - - mobile = HttpUtility.UrlEncode(mobile, Encoding.UTF8); - //var tplValue = HttpUtility.UrlEncode( - // HttpUtility.UrlEncode("#code#", Encoding.UTF8) + "=" + - // HttpUtility.UrlEncode(code.ToString(), Encoding.UTF8) - //, Encoding.UTF8); - var tplValue = HttpUtility.UrlEncode(param.ToString(), Encoding.UTF8); - - return HttpPostToYunpian("https://sms.yunpian.com/v1/sms/tpl_send.json", "apikey=" + ConfigManager.SystemConfigInfo.SmsAppKey + "&mobile=" + mobile + "&tpl_id=" + tplId + "&tpl_value=" + tplValue, out errorMessage); - } - - private static bool HttpPostToYunpian(string url, string data, out string errorMessage) - { - errorMessage = null; - try - { - var dataArray = Encoding.UTF8.GetBytes(data); - - var request = (HttpWebRequest)WebRequest.Create(url); - request.Method = "POST"; - request.ContentType = "application/x-www-form-urlencoded"; - request.ContentLength = dataArray.Length; - var dataStream = request.GetRequestStream(); - dataStream.Write(dataArray, 0, dataArray.Length); - dataStream.Close(); - - var response = (HttpWebResponse)request.GetResponse(); - // ReSharper disable once AssignNullToNotNullAttribute - var reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8); - reader.ReadToEnd(); - reader.Close(); - return true; - } - catch (Exception e) - { - errorMessage = e.Message; - } - return false; - } - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Core/SourceManager.cs b/SiteServer.CMS/Core/SourceManager.cs deleted file mode 100644 index ebc990f85..000000000 --- a/SiteServer.CMS/Core/SourceManager.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace SiteServer.CMS.Core -{ - public class SourceManager - { - public const int CaiJi = -2; //采集 - public const int Preview = -99; //预览 - public const int Default = 0; //正常录入 - - public static string GetSourceName(int sourceId) - { - if (sourceId == Default) - { - return "正常录入"; - } - if (sourceId == CaiJi) - { - return "系统采集"; - } - if (sourceId == Preview) - { - return "预览插入"; - } - if (sourceId <= 0) return string.Empty; - - var siteId = DataProvider.ChannelDao.GetSiteId(sourceId); - var siteInfo = SiteManager.GetSiteInfo(siteId); - if (siteInfo == null) return "内容转移"; - - var nodeNames = ChannelManager.GetChannelNameNavigation(siteId, sourceId); - if (!string.IsNullOrEmpty(nodeNames)) - { - return siteInfo.SiteName + ":" + nodeNames; - } - return siteInfo.SiteName; - } - } -} diff --git a/SiteServer.CMS/Core/SystemManager.cs b/SiteServer.CMS/Core/SystemManager.cs deleted file mode 100644 index 0561ed61a..000000000 --- a/SiteServer.CMS/Core/SystemManager.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Diagnostics; -using System.Reflection; -using SiteServer.CMS.Model; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Core -{ - public class SystemManager - { - static SystemManager() - { - Version = FileVersionInfo.GetVersionInfo(PathUtils.GetBinDirectoryPath("SiteServer.CMS.dll")).ProductVersion; - PluginVersion = FileVersionInfo.GetVersionInfo(PathUtils.GetBinDirectoryPath("SiteServer.Plugin.dll")).ProductVersion; - - //var ssemblyName = assembly.GetName(); - //var assemblyVersion = ssemblyName.Version; - //var version = assemblyVersion.ToString(); - //if (StringUtils.EndsWith(version, ".0")) - //{ - // version = version.Substring(0, version.Length - 2); - //} - //Version = version; - } - - public static string Version { get; } - - public static string PluginVersion { get; } - - public static void InstallDatabase(string adminName, string adminPassword) - { - SyncDatabase(); - - if (!string.IsNullOrEmpty(adminName) && !string.IsNullOrEmpty(adminPassword)) - { - RoleManager.CreatePredefinedRolesIfNotExists(); - - var administratorInfo = new AdministratorInfo - { - UserName = adminName, - Password = adminPassword - }; - - string errorMessage; - AdminManager.CreateAdministrator(administratorInfo, out errorMessage); - DataProvider.AdministratorsInRolesDao.AddUserToRole(adminName, EPredefinedRoleUtils.GetValue(EPredefinedRole.ConsoleAdministrator)); - } - } - - public static void SyncDatabase() - { - CacheUtils.ClearAll(); - - foreach (var provider in DataProvider.AllProviders) - { - if (string.IsNullOrEmpty(provider.TableName) || provider.TableColumns == null || provider.TableColumns.Count <= 0) continue; - - if (!DataProvider.DatabaseDao.IsTableExists(provider.TableName)) - { - DataProvider.DatabaseDao.CreateSystemTable(provider.TableName, provider.TableColumns); - } - else - { - DataProvider.DatabaseDao.AlterSystemTable(provider.TableName, provider.TableColumns); - } - } - - var configInfo = DataProvider.ConfigDao.GetConfigInfo(); - if (configInfo == null) - { - configInfo = new ConfigInfo(true, Version, DateTime.Now, string.Empty); - DataProvider.ConfigDao.Insert(configInfo); - } - else - { - configInfo.DatabaseVersion = Version; - configInfo.IsInitialized = true; - configInfo.UpdateDate = DateTime.Now; - DataProvider.ConfigDao.Update(configInfo); - } - - DataProvider.TableDao.CreateAllTableCollectionInfoIfNotExists(); - } - - public static bool IsNeedUpdate() - { - return !StringUtils.EqualsIgnoreCase(Version, DataProvider.ConfigDao.GetDatabaseVersion()); - } - - public static bool IsNeedInstall() - { - var isNeedInstall = !DataProvider.ConfigDao.IsInitialized(); - if (isNeedInstall) - { - isNeedInstall = !DataProvider.ConfigDao.IsInitialized(); - } - return isNeedInstall; - } - - public static bool DetermineRedirectToInstaller() - { - if (!IsNeedInstall()) return false; - PageUtils.Redirect(PageUtils.GetAdminDirectoryUrl("Installer")); - return true; - } - } -} diff --git a/SiteServer.CMS/Core/TabManager.cs b/SiteServer.CMS/Core/TabManager.cs deleted file mode 100644 index 19dba6a11..000000000 --- a/SiteServer.CMS/Core/TabManager.cs +++ /dev/null @@ -1,176 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using SiteServer.Utils; -using SiteServer.CMS.Plugin; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Core -{ - public class TabManager - { - public static List GetTopMenuTabs() - { - var list = new List(); - - var menuPath = PathUtils.GetMenusPath("Top.config"); - if (!FileUtils.IsFileExists(menuPath)) return list; - - var tabs = TabCollection.GetTabs(menuPath); - foreach (var parent in tabs.Tabs) - { - list.Add(parent); - } - - return list; - } - - public static bool IsValid(Tab tab, IList permissionList) - { - if (tab.HasPermissions) - { - if (permissionList != null && permissionList.Count > 0) - { - var tabPermissions = tab.Permissions.Split(','); - foreach (var tabPermission in tabPermissions) - { - if (permissionList.Contains(tabPermission)) - return true; - } - } - - //ITab valid, but invalid role set - return false; - } - - //ITab valid, but no roles - return true; - } - - private static Tab GetPluginTab(Menu menu, string permission) - { - var tab = new Tab - { - Id = menu.Id, - Text = menu.Text, - IconClass = menu.IconClass, - Selected = false, - Href = menu.Href, - Target = menu.Target, - Permissions = permission - }; - if (menu.Menus != null && menu.Menus.Count > 0) - { - tab.Children = new Tab[menu.Menus.Count]; - for (var i = 0; i < menu.Menus.Count; i++) - { - tab.Children[i] = GetPluginTab(menu.Menus[i], permission); - } - } - return tab; - } - - public static List GetTabList(string topId, int siteId) - { - var tabs = new List(); - - if (!string.IsNullOrEmpty(topId)) - { - var filePath = PathUtils.GetMenusPath($"{topId}.config"); - var tabCollection = TabCollection.GetTabs(filePath); - if (tabCollection?.Tabs != null) - { - foreach (var tabCollectionTab in tabCollection.Tabs) - { - tabs.Add(tabCollectionTab.Clone()); - } - } - } - - var menus = new Dictionary(); - if (siteId > 0 && topId == string.Empty) - { - var siteMenus = PluginMenuManager.GetSiteMenus(siteId); - if (siteMenus != null) - { - foreach (var siteMenu in siteMenus) - { - menus.Add(siteMenu.Key, siteMenu.Value); - } - } - } - else if (topId == "Plugins") - { - var topMenus = PluginMenuManager.GetTopMenus(); - if (topMenus != null) - { - foreach (var topMenu in topMenus) - { - menus.Add(topMenu.Key, topMenu.Value); - } - } - } - - foreach (var pluginId in menus.Keys) - { - var menu = menus[pluginId]; - - var isExists = false; - foreach (var childTab in tabs) - { - if (childTab.Id == menu.Id) - { - isExists = true; - } - } - - if (isExists) continue; - - tabs.Add(GetPluginTab(menu, pluginId)); - - //if (string.IsNullOrEmpty(menu.ParentId)) - //{ - // var isExists = false; - // foreach (var childTab in tabs) - // { - // if (childTab.Id == menu.Id) - // { - // isExists = true; - // } - // } - - // if (isExists) continue; - - // tabs.Add(GetPluginTab(menu)); - //} - //else - //{ - // foreach (var tab in tabs) - // { - // if (!StringUtils.EqualsIgnoreCase(menu.ParentId, tab.Id)) continue; - - // var isExists = false; - // foreach (var childTab in tab.Children) - // { - // if (childTab.Id == menu.Id) - // { - // isExists = true; - // } - // } - - // if (isExists) continue; - - // var list = new List(); - // if (tab.Children != null) - // { - // list = tab.Children.ToList(); - // } - // list.Add(GetPluginTab(menu)); - // tab.Children = list.ToArray(); - // } - //} - } - - return tabs; - } - } -} diff --git a/SiteServer.CMS/Core/TableColumnManager.cs b/SiteServer.CMS/Core/TableColumnManager.cs deleted file mode 100644 index 92265b7b6..000000000 --- a/SiteServer.CMS/Core/TableColumnManager.cs +++ /dev/null @@ -1,105 +0,0 @@ -using System; -using System.Collections.Generic; -using SiteServer.CMS.Model; -using SiteServer.Utils; -using SiteServer.Utils.IO; - -namespace SiteServer.CMS.Core -{ - public sealed class TableColumnManager - { - private static class TableColumnManagerCache - { - private static readonly object LockObject = new object(); - private const string CacheKey = "BaiRong.Core.Table.TableColumnManager"; - private static readonly FileWatcherClass FileWatcher; - - static TableColumnManagerCache() - { - FileWatcher = new FileWatcherClass(FileWatcherClass.TableColumn); - FileWatcher.OnFileChange += FileWatcher_OnFileChange; - } - - private static void FileWatcher_OnFileChange(object sender, EventArgs e) - { - CacheUtils.Remove(CacheKey); - } - - public static void Clear() - { - CacheUtils.Remove(CacheKey); - FileWatcher.UpdateCacheFile(); - } - - private static void Update(Dictionary> allDict, List list, - string key) - { - lock (LockObject) - { - allDict[key] = list; - } - } - - private static Dictionary> GetAllDictionary() - { - var allDict = CacheUtils.Get(CacheKey) as Dictionary>; - if (allDict != null) return allDict; - - allDict = new Dictionary>(); - CacheUtils.InsertHours(CacheKey, allDict, 24); - return allDict; - } - - public static List GetTableColumnInfoListLowercase(string tableName) - { - var allDict = GetAllDictionary(); - - List list; - allDict.TryGetValue(tableName, out list); - - if (list != null) return list; - - list = DataProvider.DatabaseDao.GetTableColumnInfoListLowercase(WebConfigUtils.ConnectionString, tableName); - Update(allDict, list, tableName); - return list; - } - } - - public static List GetTableColumnInfoListLowercase(string tableName, List excludeAttributeNameListLowercase = null) - { - var list = TableColumnManagerCache.GetTableColumnInfoListLowercase(tableName); - if (excludeAttributeNameListLowercase == null || excludeAttributeNameListLowercase.Count == 0) return list; - - var retval = new List(); - foreach (var tableColumnInfo in list) - { - if (!excludeAttributeNameListLowercase.Contains(tableColumnInfo.ColumnName.ToLower())) - { - retval.Add(tableColumnInfo); - } - } - - return retval; - } - - public static List GetTableColumnNameListLowercase(string tableName, List excludeAttributeNameListLowercase = null) - { - var allTableColumnInfoList = GetTableColumnInfoListLowercase(tableName, excludeAttributeNameListLowercase); - - var columnNameList = new List(); - - foreach (var tableColumnInfo in allTableColumnInfoList) - { - columnNameList.Add(tableColumnInfo.ColumnName); - } - - return columnNameList; - } - - public static void ClearCache() - { - TableColumnManagerCache.Clear(); - } - } - -} diff --git a/SiteServer.CMS/Core/TableMetadataManager.cs b/SiteServer.CMS/Core/TableMetadataManager.cs deleted file mode 100644 index 11a4b90f6..000000000 --- a/SiteServer.CMS/Core/TableMetadataManager.cs +++ /dev/null @@ -1,189 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using SiteServer.CMS.Model; -using SiteServer.Utils; -using SiteServer.Utils.IO; - -namespace SiteServer.CMS.Core -{ - public sealed class TableMetadataManager - { - private static class TableMetadataManagerCache - { - private static readonly object LockObject = new object(); - private const string CacheKey = "BaiRong.Core.Table.TableMetadataManager"; - private static readonly FileWatcherClass FileWatcher; - - static TableMetadataManagerCache() - { - FileWatcher = new FileWatcherClass(FileWatcherClass.TableMetadata); - FileWatcher.OnFileChange += FileWatcher_OnFileChange; - } - - private static void FileWatcher_OnFileChange(object sender, EventArgs e) - { - CacheUtils.Remove(CacheKey); - } - - public static void Clear() - { - CacheUtils.Remove(CacheKey); - FileWatcher.UpdateCacheFile(); - } - - public static Dictionary> GetTableNameWithTableMetadataInfoDictionary() - { - var retval = CacheUtils.Get>>(CacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = CacheUtils.Get>>(CacheKey); - if (retval == null) - { - retval = DataProvider.TableMetadataDao.GetTableNameWithTableMetadataInfoList(); - CacheUtils.InsertHours(CacheKey, retval, 24); - } - } - - return retval; - } - } - - public static void ClearCache() - { - TableMetadataManagerCache.Clear(); - } - - public static List GetAllLowerAttributeNameList(string tableName) - { - var list = new List(); - list.AddRange(ContentAttribute.AllAttributesLowercase); - list.AddRange(GetAttributeNameList(tableName, true)); - return list; - } - - /// - /// 得到辅助表tableName数据库中的字段名称的集合 - /// - public static List GetAttributeNameList(string tableName, bool toLower) - { - var tableMetadataInfoList = GetTableMetadataInfoList(tableName); - return tableMetadataInfoList.Select(tableMetadataInfo => toLower ? tableMetadataInfo.AttributeName.ToLower() : tableMetadataInfo.AttributeName).ToList(); - } - - /// - /// 得到辅助表的所有字段名称的集合 - /// - public static List GetAttributeNameList(string tableName) - { - return GetAttributeNameList(tableName, false); - } - - public static bool IsAttributeNameExists(string tableName, string attributeName) - { - var list = GetAttributeNameList(tableName, true); - return list.Contains(attributeName.ToLower()); - } - - public static List GetTableMetadataInfoList(string tableName) - { - var dict = TableMetadataManagerCache.GetTableNameWithTableMetadataInfoDictionary(); - List additionMetadataList; - if (!dict.TryGetValue(tableName, out additionMetadataList)) return new List(); - - if (additionMetadataList == null || additionMetadataList.Count <= 0) return new List(); - - var metadataList = new List(); - var attributeNames = new List(); - foreach (var metadataInfo in additionMetadataList) - { - if (attributeNames.Contains(metadataInfo.AttributeName.ToLower()) || - ContentAttribute.AllAttributesLowercase.Contains(metadataInfo.AttributeName.ToLower())) - continue; - - attributeNames.Add(metadataInfo.AttributeName.ToLower()); - metadataList.Add(metadataInfo); - } - - return metadataList; - } - - public static TableMetadataInfo GetTableMetadataInfo(string tableName, string attributeName) - { - var list = GetTableMetadataInfoList(tableName); - foreach (var tableMetadataInfo in list) - { - if (StringUtils.EqualsIgnoreCase(tableMetadataInfo.AttributeName, attributeName)) - { - return tableMetadataInfo; - } - } - return null; - } - - public static string GetTableMetadataDataType(string tableName, string attributeName) - { - var metadataInfo = GetTableMetadataInfo(tableName, attributeName); - if (metadataInfo != null) - { - return DataTypeUtils.GetText(metadataInfo.DataType); - } - return string.Empty; - } - - public static int GetTableMetadataId(string tableName, string attributeName) - { - var metadataId = 0; - var list = GetTableMetadataInfoList(tableName); - foreach (var tableMetadataInfo in list) - { - if (StringUtils.EqualsIgnoreCase(tableMetadataInfo.AttributeName, attributeName)) - { - metadataId = tableMetadataInfo.Id; - break; - } - } - return metadataId; - } - - public static string GetSerializedString(string tableName) - { - var builder = new StringBuilder(); - var list = GetTableMetadataInfoList(tableName); - var sortedlist = new SortedList(); - foreach (var metadataInfo in list) - { - if (metadataInfo.IsSystem == false) - { - /* - * AttributeName, - * DataType, - * DataLength, - * CanBeNull, - * DBDefaultValue - * */ - string serialize = - $"AttributeName:{metadataInfo.AttributeName};DataType:{metadataInfo.DataType.Value};DataLength={metadataInfo.DataLength}"; - sortedlist.Add(metadataInfo.AttributeName, serialize); - } - } - - foreach (string attributeName in sortedlist.Keys) - { - builder.Append(sortedlist[attributeName]); - } - - return builder.ToString(); - } - - public static string GetTableNameOfArchive(string tableName) - { - return tableName + "_Archive"; - } - } - -} diff --git a/SiteServer.CMS/Core/TableStyleManager.cs b/SiteServer.CMS/Core/TableStyleManager.cs deleted file mode 100644 index e5b29ac14..000000000 --- a/SiteServer.CMS/Core/TableStyleManager.cs +++ /dev/null @@ -1,401 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Core -{ - public sealed class TableStyleManager - { - private static readonly object LockObject = new object(); - private static bool _async = true;//缓存与数据库不同步 - private const string CacheKey = "BaiRong.Core.Table.TableStyleManager"; - - public static PairList GetAllTableStyleInfoPairs() - { - lock (LockObject) - { - if (!_async && CacheUtils.Get(CacheKey) != null) return (PairList) CacheUtils.Get(CacheKey); - - var entries = DataProvider.TableStyleDao.GetAllTableStyleInfoPairs(); - CacheUtils.Insert(CacheKey, entries); - _async = false; - return entries; - } - } - - public static List GetTableStyleInfoList(string tableName, List relatedIdentities) - { - var allAttributeNames = new List(); - var styleInfoList = new List(); - - var entries = GetAllTableStyleInfoPairs(); - relatedIdentities = GetRelatedIdentities(relatedIdentities); - foreach (var relatedIdentity in relatedIdentities) - { - var startKey = GetCacheKeyStart(relatedIdentity, tableName); - var keyList = entries.GetKeys(startKey); - foreach (var key in keyList) - { - var styleInfo = entries.GetValue(key) as TableStyleInfo; - if (styleInfo == null) continue; - - if (!allAttributeNames.Contains(styleInfo.AttributeName.ToLower())) - { - allAttributeNames.Add(styleInfo.AttributeName.ToLower()); - styleInfoList.Add(styleInfo); - } - } - } - - var attributeNames = TableMetadataManager.GetAttributeNameList(tableName); - foreach (var attributeName in attributeNames) - { - if (!allAttributeNames.Contains(attributeName.ToLower())) - { - allAttributeNames.Add(attributeName.ToLower()); - - styleInfoList.Add(GetDefaultTableStyleInfo(tableName, attributeName)); - } - } - - styleInfoList.Sort(); - - return styleInfoList; - } - - public static IAttributes GetDefaultAttributes(List styleInfoList) - { - var attributes = new ExtendedAttributes(); - - foreach (var styleInfo in styleInfoList) - { - var defaultValue = string.Empty; - if (!string.IsNullOrEmpty(styleInfo.DefaultValue)) - { - defaultValue = styleInfo.DefaultValue; - } - else if (styleInfo.StyleItems != null) - { - var defaultValues = new List(); - foreach (var styleItem in styleInfo.StyleItems) - { - if (styleItem.IsSelected) - { - defaultValues.Add(styleItem.ItemValue); - } - } - if (defaultValues.Count > 0) - { - defaultValue = TranslateUtils.ObjectCollectionToString(defaultValues); - } - } - - if (!string.IsNullOrEmpty(defaultValue)) - { - attributes.Set(styleInfo.AttributeName, defaultValue); - } - } - - return attributes; - } - - public static bool IsExistsInParents(List relatedIdentities, string tableName, string attributeName) - { - var entries = GetAllTableStyleInfoPairs(); - for (var i = 1; i < relatedIdentities.Count - 1; i++) - { - var relatedIdentity = relatedIdentities[i]; - var startKey = GetCacheKeyStart(relatedIdentity, tableName); - var keyArrayList = entries.GetKeys(startKey); - foreach (string key in keyArrayList) - { - var styleInfo = entries.GetValue(key) as TableStyleInfo; - if (styleInfo != null && styleInfo.AttributeName == attributeName) - { - return true; - } - } - } - return false; - } - - public static bool IsChanged - { - set - { - lock (LockObject) - { - if (value) - { - CacheUtils.Remove(CacheKey); - } - _async = value; - } - } - } - - public static string GetCacheKey(int relatedIdentity, string tableName, string attributeName) - { - return $"{relatedIdentity}${tableName}${attributeName}".ToLower(); - } - - public static string GetCacheKeyStart(int relatedIdentity, string tableName) - { - return $"{relatedIdentity}${tableName}$".ToLower(); - } - - //relatedIdentities从大到小,最后是0 - public static TableStyleInfo GetTableStyleInfo(string tableName, string attributeName, List relatedIdentities) - { - TableStyleInfo styleInfo = null; - if (attributeName == null) attributeName = string.Empty; - - relatedIdentities = GetRelatedIdentities(relatedIdentities); - - var entries = GetAllTableStyleInfoPairs(); - - foreach (var relatedIdentity in relatedIdentities) - { - var key = GetCacheKey(relatedIdentity, tableName, attributeName); - if (entries.ContainsKey(key)) - { - styleInfo = entries.GetValue(key) as TableStyleInfo; - if (styleInfo != null) - { - break; - } - } - } - - return styleInfo ?? GetDefaultTableStyleInfo(tableName, attributeName); - } - - private static List GetRelatedIdentities(IReadOnlyCollection list) - { - var relatedIdentities = new List(); - - if (list != null && list.Count > 0) - { - foreach (var i in list) - { - if (!relatedIdentities.Contains(i)) - { - relatedIdentities.Add(i); - } - } - } - - relatedIdentities.Sort(); - relatedIdentities.Reverse(); - - if (!relatedIdentities.Contains(0)) - { - relatedIdentities.Add(0); - } - - return relatedIdentities; - } - - public static int Insert(TableStyleInfo styleInfo) - { - var tableStyleId = DataProvider.TableStyleDao.Insert(styleInfo); - IsChanged = true; - return tableStyleId; - } - - public static void Update(TableStyleInfo info) - { - DataProvider.TableStyleDao.Update(info); - IsChanged = true; - } - - public static void DeleteAndInsertStyleItems(int tableStyleId, List styleItems) - { - if (styleItems == null || styleItems.Count <= 0) return; - - DataProvider.TableStyleItemDao.DeleteStyleItems(tableStyleId); - DataProvider.TableStyleItemDao.InsertStyleItems(styleItems); - } - - public static void Delete(int relatedIdentity, string tableName, string attributeName) - { - DataProvider.TableStyleDao.Delete(relatedIdentity, tableName, attributeName); - IsChanged = true; - } - - public static bool IsExists(int relatedIdentity, string tableName, string attributeName) - { - var key = GetCacheKey(relatedIdentity, tableName, attributeName); - var entries = GetAllTableStyleInfoPairs(); - return entries.Keys.Contains(key); - } - - //public static DataSet GetStyleItemDataSet(int styleItemCount, List styleItemInfoList) - //{ - // var dataset = new DataSet(); - - // var dataTable = new DataTable("StyleItems"); - - // dataTable.Columns.Add(new DataColumn - // { - // DataType = System.Type.GetType("System.Int32"), - // ColumnName = "TableStyleItemID" - // }); - - // dataTable.Columns.Add(new DataColumn - // { - // DataType = System.Type.GetType("System.Int32"), - // ColumnName = "TableStyleID" - // }); - - // dataTable.Columns.Add(new DataColumn - // { - // DataType = System.Type.GetType("System.String"), - // ColumnName = "ItemTitle" - // }); - - // dataTable.Columns.Add(new DataColumn - // { - // DataType = System.Type.GetType("System.String"), - // ColumnName = "ItemValue" - // }); - - // dataTable.Columns.Add(new DataColumn - // { - // DataType = System.Type.GetType("System.String"), - // ColumnName = "IsSelected" - // }); - - // for (var i = 0; i < styleItemCount; i++) - // { - // var dataRow = dataTable.NewRow(); - - // var itemInfo = styleItemInfoList != null && styleItemInfoList.Count > i ? styleItemInfoList[i] : new TableStyleItemInfo(); - - // dataRow["TableStyleItemID"] = itemInfo.TableStyleItemId; - // dataRow["TableStyleID"] = itemInfo.TableStyleId; - // dataRow["ItemTitle"] = itemInfo.ItemTitle; - // dataRow["ItemValue"] = itemInfo.ItemValue; - // dataRow["IsSelected"] = itemInfo.IsSelected.ToString(); - - // dataTable.Rows.Add(dataRow); - // } - - // dataset.Tables.Add(dataTable); - // return dataset; - //} - - public static Dictionary> GetTableStyleInfoWithItemsDictinary(string tableName, List allRelatedIdentities) - { - var dict = new Dictionary>(); - - var entries = GetAllTableStyleInfoPairs(); - foreach (var key in entries.Keys) - { - var identityFromKey = TranslateUtils.ToInt(key.Split('$')[0]); - var tableNameFromKey = key.Split('$')[1]; - if (!StringUtils.EqualsIgnoreCase(tableNameFromKey, tableName) || - !allRelatedIdentities.Contains(identityFromKey)) continue; - - var styleInfo = (TableStyleInfo)entries.GetValue(key); - if (InputTypeUtils.IsWithStyleItems(styleInfo.InputType)) - { - styleInfo.StyleItems = DataProvider.TableStyleItemDao.GetStyleItemInfoList(styleInfo.Id); - } - var tableStyleInfoWithItemList = dict.ContainsKey(styleInfo.AttributeName) ? dict[styleInfo.AttributeName] : new List(); - tableStyleInfoWithItemList.Add(styleInfo); - dict[styleInfo.AttributeName] = tableStyleInfoWithItemList; - } - - return dict; - } - - public static string GetValidateInfo(TableStyleInfo styleInfo) - { - var builder = new StringBuilder(); - if (styleInfo.Additional.IsRequired) - { - builder.Append("必填项;"); - } - if (styleInfo.Additional.MinNum > 0) - { - builder.Append($"最少{styleInfo.Additional.MinNum}个字符;"); - } - if (styleInfo.Additional.MaxNum > 0) - { - builder.Append($"最多{styleInfo.Additional.MaxNum}个字符;"); - } - if (styleInfo.Additional.ValidateType != ValidateType.None) - { - builder.Append($"验证:{ValidateTypeUtils.GetText(styleInfo.Additional.ValidateType)};"); - } - - if (builder.Length > 0) - { - builder.Length = builder.Length - 1; - } - else - { - builder.Append("无验证"); - } - return builder.ToString(); - } - - public static TableStyleInfo GetDefaultTableStyleInfo(string tableName, string attributeName) - { - var lowerAttributeName = attributeName.ToLower(); - var styleInfo = new TableStyleInfo(0, 0, tableName, attributeName, 0, attributeName, string.Empty, false, InputType.Text, string.Empty, true, string.Empty); - - if (lowerAttributeName == BackgroundContentAttribute.SubTitle.ToLower()) - { - styleInfo.DisplayName = "副标题"; - styleInfo.Taxis = 1; - } - else if (lowerAttributeName == BackgroundContentAttribute.ImageUrl.ToLower()) - { - styleInfo.DisplayName = "图片"; - styleInfo.InputType = InputType.Image; - styleInfo.Taxis = 2; - } - else if (lowerAttributeName == BackgroundContentAttribute.VideoUrl.ToLower()) - { - styleInfo.DisplayName = "视频"; - styleInfo.InputType = InputType.Video; - styleInfo.Taxis = 3; - } - else if (lowerAttributeName == BackgroundContentAttribute.FileUrl.ToLower()) - { - styleInfo.DisplayName = "附件"; - styleInfo.InputType = InputType.File; - styleInfo.Taxis = 4; - } - else if (lowerAttributeName == BackgroundContentAttribute.Content.ToLower()) - { - styleInfo.DisplayName = "内容"; - styleInfo.InputType = InputType.TextEditor; - styleInfo.Taxis = 5; - } - else if (lowerAttributeName == BackgroundContentAttribute.Summary.ToLower()) - { - styleInfo.DisplayName = "内容摘要"; - styleInfo.InputType = InputType.TextArea; - styleInfo.Taxis = 6; - } - else if (lowerAttributeName == BackgroundContentAttribute.Author.ToLower()) - { - styleInfo.DisplayName = "作者"; - styleInfo.Taxis = 7; - } - else if (lowerAttributeName == BackgroundContentAttribute.Source.ToLower()) - { - styleInfo.DisplayName = "来源"; - styleInfo.Taxis = 8; - } - - return styleInfo; - } - } - -} diff --git a/SiteServer.CMS/Core/TemplateTypeUtils.cs b/SiteServer.CMS/Core/TemplateTypeUtils.cs deleted file mode 100644 index f85f797a2..000000000 --- a/SiteServer.CMS/Core/TemplateTypeUtils.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Core -{ - public class TemplateTypeUtils - { - public static TemplateType GetEnumType(string typeStr) - { - var retval = TemplateType.IndexPageTemplate; - - if (Equals(TemplateType.ChannelTemplate, typeStr)) - { - retval = TemplateType.ChannelTemplate; - } - else if (Equals(TemplateType.IndexPageTemplate, typeStr)) - { - retval = TemplateType.IndexPageTemplate; - } - else if (Equals(TemplateType.ContentTemplate, typeStr)) - { - retval = TemplateType.ContentTemplate; - } - else if (Equals(TemplateType.FileTemplate, typeStr)) - { - retval = TemplateType.FileTemplate; - } - return retval; - } - - public static bool Equals(TemplateType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(type.Value.ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, TemplateType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(TemplateType type, bool selected) - { - var item = new ListItem(GetText(type), type.Value); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(TemplateType.IndexPageTemplate, false)); - listControl.Items.Add(GetListItem(TemplateType.ChannelTemplate, false)); - listControl.Items.Add(GetListItem(TemplateType.ContentTemplate, false)); - listControl.Items.Add(GetListItem(TemplateType.FileTemplate, false)); - } - } - - public static string GetText(TemplateType templateType) - { - if (templateType == TemplateType.IndexPageTemplate) - { - return "首页模板"; - } - if (templateType == TemplateType.ChannelTemplate) - { - return "栏目模板"; - } - if (templateType == TemplateType.ContentTemplate) - { - return "内容模板"; - } - if (templateType == TemplateType.FileTemplate) - { - return "单页模板"; - } - - throw new Exception(); - } - } -} diff --git a/SiteServer.CMS/Data/DataProviderBase.cs b/SiteServer.CMS/Data/DataProviderBase.cs deleted file mode 100644 index d5149624d..000000000 --- a/SiteServer.CMS/Data/DataProviderBase.cs +++ /dev/null @@ -1,280 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Data; -using System.Text; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Data -{ - public class DataProviderBase - { - protected virtual string ConnectionString => WebConfigUtils.ConnectionString; - - public virtual string TableName => string.Empty; - - public virtual List TableColumns => null; - - protected IDbConnection GetConnection() - { - return SqlUtils.GetIDbConnection(WebConfigUtils.DatabaseType, ConnectionString); - } - - protected IDbConnection GetConnection(string connectionString) - { - return SqlUtils.GetIDbConnection(WebConfigUtils.DatabaseType, connectionString); - } - - protected IDbConnection GetConnection(DatabaseType databaseType, string connectionString) - { - return SqlUtils.GetIDbConnection(databaseType, connectionString); - } - - protected IDbDataParameter GetParameter(string parameterName, DataType dataType, int value) - { - return SqlUtils.GetIDbDataParameter(parameterName, dataType, 0, value); - } - - protected IDbDataParameter GetParameter(string parameterName, DataType dataType, bool value) - { - return SqlUtils.GetIDbDataParameter(parameterName, dataType, 0, value); - } - - protected IDbDataParameter GetParameter(string parameterName, DataType dataType, decimal value) - { - return SqlUtils.GetIDbDataParameter(parameterName, dataType, 0, value); - } - - protected IDbDataParameter GetParameter(string parameterName, DataType dataType, DateTime value) - { - return SqlUtils.GetIDbDataParameter(parameterName, dataType, 0, value); - } - - protected IDbDataParameter GetParameter(string parameterName, DataType dataType, string value) - { - return SqlUtils.GetIDbDataParameter(parameterName, dataType, 0, value); - } - - protected IDbDataParameter GetParameter(string parameterName, DataType dataType, int size, string value) - { - return SqlUtils.GetIDbDataParameter(parameterName, dataType, size, value); - } - - protected IDbDataParameter GetParameter(string parameterName, DataType dataType, int size, decimal value) - { - return SqlUtils.GetIDbDataParameter(parameterName, dataType, size, value); - } - - protected List GetInParameterList(string parameterName, DataType dataType, int dataLength, ICollection valueCollection, out string parameterNameList) - { - parameterNameList = string.Empty; - if (valueCollection == null || valueCollection.Count <= 0) return new List(); - - var parameterList = new List(); - - var sbCondition = new StringBuilder(); - var i = 0; - foreach (var obj in valueCollection) - { - i++; - - var value = obj.ToString(); - var parmName = parameterName + "_" + i; - - sbCondition.Append(parmName + ","); - - parameterList.Add(dataType == DataType.Integer - ? GetParameter(parmName, dataType, value) - : GetParameter(parmName, dataType, dataLength, value)); - } - - parameterNameList = sbCondition.ToString().TrimEnd(','); - - return parameterList; - } - - protected IDataReader ExecuteReader(string commandText, params IDataParameter[] commandParameters) - { - return DataProvider.DataApi.ExecuteReader(ConnectionString, commandText, commandParameters); - } - - - protected IDataReader ExecuteReader(string commandText) - { - return DataProvider.DataApi.ExecuteReader(ConnectionString, commandText); - } - - - protected IDataReader ExecuteReader(IDbConnection conn, string commandText, params IDataParameter[] commandParameters) - { - return DataProvider.DataApi.ExecuteReader(conn, commandText, commandParameters); - } - - - protected IDataReader ExecuteReader(IDbConnection conn, string commandText) - { - return DataProvider.DataApi.ExecuteReader(conn, commandText); - } - - - protected IDataReader ExecuteReader(IDbTransaction trans, string commandText, params IDataParameter[] commandParameters) - { - return DataProvider.DataApi.ExecuteReader(trans, commandText, commandParameters); - } - - - protected IDataReader ExecuteReader(IDbTransaction trans, string commandText) - { - return DataProvider.DataApi.ExecuteReader(trans, commandText); - } - - - protected IDataReader ExecuteReader(string connectionString, string commandText) - { - return DataProvider.DataApi.ExecuteReader(connectionString, commandText); - } - - protected IDataReader ExecuteReader(string connectionString, string commandText, params IDataParameter[] commandParameters) - { - return DataProvider.DataApi.ExecuteReader(connectionString, commandText, commandParameters); - } - - - protected DataSet ExecuteDataset(string commandText, params IDataParameter[] commandParameters) - { - return DataProvider.DataApi.ExecuteDataset(ConnectionString, commandText, commandParameters); - } - - - protected DataSet ExecuteDataset(string commandText) - { - return DataProvider.DataApi.ExecuteDataset(ConnectionString, commandText); - } - - protected DataSet ExecuteDataset(string connectionString, string commandText) - { - return DataProvider.DataApi.ExecuteDataset(connectionString, commandText); - } - - protected int ExecuteNonQuery(IDbConnection conn, string commandText, params IDataParameter[] commandParameters) - { - return DataProvider.DataApi.ExecuteNonQuery(conn, commandText, commandParameters); - } - - - protected int ExecuteNonQuery(IDbConnection conn, string commandText) - { - return DataProvider.DataApi.ExecuteNonQuery(conn, commandText); - } - - - protected int ExecuteNonQuery(IDbTransaction trans, string commandText, params IDataParameter[] commandParameters) - { - return DataProvider.DataApi.ExecuteNonQuery(trans, commandText, commandParameters); - } - - - protected int ExecuteNonQuery(IDbTransaction trans, string commandText) - { - return DataProvider.DataApi.ExecuteNonQuery(trans, commandText); - } - - protected int ExecuteNonQuery(string connectionString, string commandText, params IDataParameter[] commandParameters) - { - return DataProvider.DataApi.ExecuteNonQuery(connectionString, commandText, commandParameters); - } - - protected int ExecuteNonQuery(string commandText, params IDataParameter[] commandParameters) - { - return DataProvider.DataApi.ExecuteNonQuery(ConnectionString, commandText, commandParameters); - } - - protected int ExecuteNonQuery(string commandText) - { - return DataProvider.DataApi.ExecuteNonQuery(ConnectionString, commandText); - } - - protected int ExecuteNonQueryAndReturnId(string tableName, string idColumnName, string commandText, params IDataParameter[] commandParameters) - { - return DataProvider.DataApi.ExecuteNonQueryAndReturnId(tableName, idColumnName, ConnectionString, commandText, commandParameters); - } - - protected int ExecuteNonQueryAndReturnId(string tableName, string idColumnName, IDbTransaction trans, string commandText, params IDataParameter[] commandParameters) - { - return DataProvider.DataApi.ExecuteNonQueryAndReturnId(tableName, idColumnName, trans, commandText, commandParameters); - } - - - protected object ExecuteScalar(IDbConnection conn, string commandText, params IDataParameter[] commandParameters) - { - return DataProvider.DataApi.ExecuteScalar(conn, commandText, commandParameters); - } - - protected object ExecuteScalar(IDbConnection conn, string commandText) - { - return DataProvider.DataApi.ExecuteScalar(conn, commandText); - } - - protected object ExecuteScalar(IDbTransaction trans, string commandText, params IDataParameter[] commandParameters) - { - return DataProvider.DataApi.ExecuteScalar(trans, commandText, commandParameters); - } - - protected object ExecuteScalar(IDbTransaction trans, string commandText) - { - return DataProvider.DataApi.ExecuteScalar(trans, commandText); - } - - protected object ExecuteScalar(string commandText, params IDataParameter[] commandParameters) - { - return DataProvider.DataApi.ExecuteScalar(ConnectionString, commandText, commandParameters); - } - - protected object ExecuteScalar(string commandText) - { - return DataProvider.DataApi.ExecuteScalar(ConnectionString, commandText); - } - - protected string GetString(IDataReader rdr, int i) - { - var value = rdr.IsDBNull(i) ? string.Empty : rdr.GetValue(i).ToString(); - if (!string.IsNullOrEmpty(value)) - { - value = PageUtils.UnFilterSql(value); - } - if (WebConfigUtils.DatabaseType == DatabaseType.Oracle && value == SqlUtils.OracleEmptyValue) - { - value = string.Empty; - } - return value; - } - - protected bool GetBool(IDataReader rdr, int i) - { - return !rdr.IsDBNull(i) && TranslateUtils.ToBool(rdr.GetValue(i).ToString()); - } - - protected int GetInt(IDataReader rdr, int i) - { - return rdr.IsDBNull(i) ? 0 : rdr.GetInt32(i); - } - - protected decimal GetDecimal(IDataReader rdr, int i) - { - return rdr.IsDBNull(i) ? 0 : rdr.GetDecimal(i); - } - - protected double GetDouble(IDataReader rdr, int i) - { - return rdr.IsDBNull(i) ? 0 : rdr.GetDouble(i); - } - - protected DateTime GetDateTime(IDataReader rdr, int i) - { - return rdr.IsDBNull(i) ? DateTime.Now : rdr.GetDateTime(i); - } - } -} diff --git a/SiteServer.CMS/Data/DbHelper.cs b/SiteServer.CMS/Data/DbHelper.cs deleted file mode 100644 index 6023faff7..000000000 --- a/SiteServer.CMS/Data/DbHelper.cs +++ /dev/null @@ -1,2575 +0,0 @@ -// =============================================================================== -// Microsoft Data Access Application Block for .NET 3.0 -// -// AdoHelper.cs -// -// This file contains an abstract implementations of the AdoHelper class. -// -// For more information see the Documentation. -// =============================================================================== -// Release history -// VERSION DESCRIPTION -// 2.0 Added support for FillDataset, UpdateDataset and "Param" helper methods -// 3.0 New abstract class supporting the same methods using ADO.NET interfaces -// -// =============================================================================== -// Copyright (C) 2000-2001 Microsoft Corporation -// All rights reserved. -// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY -// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT -// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR -// FITNESS FOR A PARTICULAR PURPOSE. -// ============================================================================== - -using System; -using System.Collections; -using System.Data; -using System.Data.Common; -using System.Reflection; -using System.Xml; -using SiteServer.CMS.Core; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Data -{ - /// - /// The AdoHelper class is intended to encapsulate high performance, scalable best practices for - /// common data access uses. It uses the Abstract Factory pattern to be easily extensible - /// to any ADO.NET provider. The current implementation provides helpers for SQL Server, ODBC, - /// OLEDB, and Oracle. - /// - public abstract class DbHelper - { - /// - /// This enum is used to indicate whether the connection was provided by the caller, or created by AdoHelper, so that - /// we can set the appropriate CommandBehavior when calling ExecuteReader() - /// - protected enum AdoConnectionOwnership - { - /// Connection is owned and managed by ADOHelper - Internal, - - /// Connection is owned and managed by the caller - External - } - - #region Declare members - - // necessary for handling the general case of needing event handlers for RowUpdating/ed events - /// - /// Internal handler used for bubbling up the event to the user - /// - protected RowUpdatingHandler MRowUpdating; - - /// - /// Internal handler used for bubbling up the event to the user - /// - protected RowUpdatedHandler MRowUpdated; - - #endregion - - #region Provider specific abstract methods - - /// - /// Returns an IDbConnection object for the given connection string - /// - /// The connection string to be used to create the connection - /// An IDbConnection object - /// Thrown if connectionString is null - public abstract IDbConnection GetConnection(string connectionString); - - /// - /// Returns an IDbDataAdapter object - /// - /// The IDbDataAdapter - public abstract IDbDataAdapter GetDataAdapter(); - - /// - /// Calls the CommandBuilder.DeriveParameters method for the specified provider, doing any setup and cleanup necessary - /// - /// The IDbCommand referencing the stored procedure from which the parameter information is to be derived. The derived parameters are added to the Parameters collection of the IDbCommand. - public abstract void DeriveParameters(IDbCommand cmd); - - /// - /// Returns an IDataParameter object - /// - /// The IDataParameter object - public abstract IDataParameter GetParameter(); - - /// - /// Execute an IDbCommand (that returns a resultset) against the provided IDbConnection. - /// - /// - /// - /// XmlReader r = helper.ExecuteXmlReader(command); - /// - /// The IDbCommand to execute - /// An XmlReader containing the resultset generated by the command - /// Thrown if command is null. - public abstract XmlReader ExecuteXmlReader(IDbCommand cmd); - - /// - /// Provider specific code to set up the updating/ed event handlers used by UpdateDataset - /// - /// DataAdapter to attach the event handlers to - /// The handler to be called when a row is updating - /// The handler to be called when a row is updated - protected abstract void AddUpdateEventHandlers(IDbDataAdapter dataAdapter, RowUpdatingHandler rowUpdatingHandler, - RowUpdatedHandler rowUpdatedHandler); - - /// - /// Returns an array of IDataParameters of the specified size - /// - /// size of the array - /// The array of IDataParameters - protected abstract IDataParameter[] GetDataParameters(int size); - - /// - /// Handle any provider-specific issues with BLOBs here by "washing" the IDataParameter and returning a new one that is set up appropriately for the provider. - /// - /// The IDbConnection to use in cleansing the parameter - /// The parameter before cleansing - /// The parameter after it's been cleansed. - protected abstract IDataParameter GetBlobParameter(IDbConnection connection, IDataParameter p); - - #endregion - - #region Delegates - - // also used in our general case of RowUpdating/ed events - /// - /// Delegate for creating a RowUpdatingEvent handler - /// - /// The object that published the event - /// The RowUpdatingEventArgs for the event - public delegate void RowUpdatingHandler(object obj, RowUpdatingEventArgs e); - - /// - /// Delegate for creating a RowUpdatedEvent handler - /// - /// The object that published the event - /// The RowUpdatedEventArgs for the event - public delegate void RowUpdatedHandler(object obj, RowUpdatedEventArgs e); - - #endregion - - #region Factory - - /// - /// Create an AdoHelper for working with a specific provider (i.e. Sql, Odbc, OleDb, Oracle) - /// - /// Assembly containing the specified helper subclass - /// Specific type of the provider - /// An AdoHelper instance of the specified type - /// - /// AdoHelper helper = AdoHelper.CreateHelper("GotDotNet.ApplicationBlocks.Data", "GotDotNet.ApplicationBlocks.Data.OleDb"); - /// - public static DbHelper CreateHelper(string providerAssembly, string providerType) - { - var assembly = Assembly.Load(providerAssembly); - var provider = assembly.CreateInstance(providerType); - if (provider is DbHelper) - { - return provider as DbHelper; - } - else - { - throw new InvalidOperationException( - "The provider specified does not extend the AdoHelper abstract class."); - } - } - - #endregion - - #region GetParameter - - /// - /// Get an IDataParameter for use in a SQL command - /// - /// The name of the parameter to create - /// The value of the specified parameter - /// An IDataParameter object - public virtual IDataParameter GetParameter(string name, object value) - { - var parameter = GetParameter(); - parameter.ParameterName = name; - if (value is DateTime && (DateTime) value < DateUtils.SqlMinValue) - { - value = DateUtils.SqlMinValue; - } - parameter.Value = value; - - return parameter; - } - - /// - /// Get an IDataParameter for use in a SQL command - /// - /// The name of the parameter to create - /// The System.Data.DbType of the parameter - /// The size of the parameter - /// The System.Data.ParameterDirection of the parameter - /// An IDataParameter object - public virtual IDataParameter GetParameter(string name, DbType dbType, int size, ParameterDirection direction) - { - var dataParameter = GetParameter(); - dataParameter.DbType = dbType; - dataParameter.Direction = direction; - dataParameter.ParameterName = name; - - if (size > 0 && dataParameter is IDbDataParameter) - { - var dbDataParameter = (IDbDataParameter) dataParameter; - dbDataParameter.Size = size; - } - return dataParameter; - } - - /// - /// Get an IDataParameter for use in a SQL command - /// - /// The name of the parameter to create - /// The System.Data.DbType of the parameter - /// The size of the parameter - /// The source column of the parameter - /// The System.Data.DataRowVersion of the parameter - /// An IDataParameter object - public virtual IDataParameter GetParameter(string name, DbType dbType, int size, string sourceColumn, - DataRowVersion sourceVersion) - { - var dataParameter = GetParameter(); - dataParameter.DbType = dbType; - dataParameter.ParameterName = name; - dataParameter.SourceColumn = sourceColumn; - dataParameter.SourceVersion = sourceVersion; - - if (size > 0 && dataParameter is IDbDataParameter) - { - var dbDataParameter = (IDbDataParameter) dataParameter; - dbDataParameter.Size = size; - } - return dataParameter; - } - - #endregion - - #region private utility methods - - /// - /// This method is used to attach array of IDataParameters to an IDbCommand. - /// - /// This method will assign a value of DbNull to any parameter with a direction of - /// InputOutput and a value of null. - /// - /// This behavior will prevent default values from being used, but - /// this will be the less common case than an intended pure output parameter (derived as InputOutput) - /// where the user provided no input value. - /// - /// The command to which the parameters will be added - /// An array of IDataParameterParameters to be added to command - /// Thrown if command is null. - protected virtual void AttachParameters(IDbCommand command, IDataParameter[] commandParameters) - { - if (command == null) throw new ArgumentNullException(nameof(command)); - if (commandParameters != null) - { - foreach (var p in commandParameters) - { - if (p != null) - { - // Check for derived output value with no value assigned - if ((p.Direction == ParameterDirection.InputOutput || - p.Direction == ParameterDirection.Input) && - p.Value == null) - { - p.Value = DBNull.Value; - } - command.Parameters.Add(p.DbType == DbType.Binary ? GetBlobParameter(command.Connection, p) : p); - } - } - } - } - - /// - /// This method assigns dataRow column values to an IDataParameterCollection - /// - /// The IDataParameterCollection to be assigned values - /// The dataRow used to hold the stored procedure's parameter values - /// Thrown if any of the parameter names are invalid. - protected internal void AssignParameterValues(IDataParameterCollection commandParameters, DataRow dataRow) - { - if (commandParameters == null || dataRow == null) - { - // Do nothing if we get no data - return; - } - - var columns = dataRow.Table.Columns; - - var i = 0; - // Set the parameters values - foreach (IDataParameter commandParameter in commandParameters) - { - // Check the parameter name - if (commandParameter.ParameterName == null || - commandParameter.ParameterName.Length <= 1) - throw new InvalidOperationException( - $"Please provide a valid parameter name on the parameter #{i}, the ParameterName property has the following value: '{commandParameter.ParameterName}'."); - - if (columns.Contains(commandParameter.ParameterName)) - commandParameter.Value = dataRow[commandParameter.ParameterName]; - else if (columns.Contains(commandParameter.ParameterName.Substring(1))) - commandParameter.Value = dataRow[commandParameter.ParameterName.Substring(1)]; - - i++; - } - } - - /// - /// This method assigns dataRow column values to an array of IDataParameters - /// - /// Array of IDataParameters to be assigned values - /// The dataRow used to hold the stored procedure's parameter values - /// Thrown if any of the parameter names are invalid. - protected void AssignParameterValues(IDataParameter[] commandParameters, DataRow dataRow) - { - if ((commandParameters == null) || (dataRow == null)) - { - // Do nothing if we get no data - return; - } - - var columns = dataRow.Table.Columns; - - var i = 0; - // Set the parameters values - foreach (var commandParameter in commandParameters) - { - // Check the parameter name - if (commandParameter.ParameterName == null || - commandParameter.ParameterName.Length <= 1) - throw new InvalidOperationException( - $"Please provide a valid parameter name on the parameter #{i}, the ParameterName property has the following value: '{commandParameter.ParameterName}'."); - - if (columns.Contains(commandParameter.ParameterName)) - commandParameter.Value = dataRow[commandParameter.ParameterName]; - else if (columns.Contains(commandParameter.ParameterName.Substring(1))) - commandParameter.Value = dataRow[commandParameter.ParameterName.Substring(1)]; - - i++; - } - } - - /// - /// This method assigns an array of values to an array of IDataParameters - /// - /// Array of IDataParameters to be assigned values - /// Array of objects holding the values to be assigned - /// Thrown if an incorrect number of parameters are passed. - protected void AssignParameterValues(IDataParameter[] commandParameters, object[] parameterValues) - { - if ((commandParameters == null) || (parameterValues == null)) - { - // Do nothing if we get no data - return; - } - - // We must have the same number of values as we pave parameters to put them in - if (commandParameters.Length != parameterValues.Length) - { - throw new ArgumentException("Parameter count does not match Parameter Value count."); - } - - // Iterate through the IDataParameters, assigning the values from the corresponding position in the - // value array - for (int i = 0, j = commandParameters.Length, k = 0; i < j; i++) - { - if (commandParameters[i].Direction != ParameterDirection.ReturnValue) - { - // If the current array value derives from IDataParameter, then assign its Value property - if (parameterValues[k] is IDataParameter) - { - var paramInstance = (IDataParameter) parameterValues[k]; - if (paramInstance.Direction == ParameterDirection.ReturnValue) - { - paramInstance = (IDataParameter) parameterValues[++k]; - } - commandParameters[i].Value = paramInstance.Value ?? DBNull.Value; - } - else if (parameterValues[k] == null) - { - commandParameters[i].Value = DBNull.Value; - } - else - { - commandParameters[i].Value = parameterValues[k]; - } - k++; - } - } - } - - /// - /// This method cleans up the parameter syntax for the provider - /// - /// The IDbCommand containing the parameters to clean up. - public virtual void CleanParameterSyntax(IDbCommand command) - { - // do nothing by default - } - - /// - /// This method opens (if necessary) and assigns a connection, transaction, command type and parameters - /// to the provided command - /// - /// The IDbCommand to be prepared - /// A valid IDbConnection, on which to execute this command - /// A valid IDbTransaction, or 'null' - /// SQL command - /// An array of IDataParameters to be associated with the command or 'null' if no parameters are required - /// true if the connection was opened by the method, otherwose is false. - /// Thrown if command is null. - /// Thrown if commandText is null. - protected virtual void PrepareCommand(IDbCommand command, IDbConnection connection, IDbTransaction transaction, - string commandText, IDataParameter[] commandParameters, out bool mustCloseConnection) - { - if (command == null) throw new ArgumentNullException(nameof(command)); - if (string.IsNullOrEmpty(commandText)) throw new ArgumentNullException(nameof(commandText)); - if (WebConfigUtils.DatabaseType != DatabaseType.SqlServer) - { - commandText = commandText.Replace("[", string.Empty).Replace("]", string.Empty); - if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - commandText = commandText.Replace("@", ":"); - } - } - - // If the provided connection is not open, we will open it - if (connection.State != ConnectionState.Open) - { - mustCloseConnection = true; - connection.Open(); - } - else - { - mustCloseConnection = false; - } - - // Associate the connection with the command - command.Connection = connection; - - // Set the command text (stored procedure name or SQL statement) - command.CommandText = commandText; - - // If we were provided a transaction, assign it - if (transaction != null) - { - if (transaction.Connection == null) - throw new ArgumentException( - "The transaction was rolled back or commited, please provide an open transaction.", - nameof(transaction)); - command.Transaction = transaction; - } - - // Set the command type - command.CommandType = CommandType.Text; - - // Attach the command parameters if they are provided - if (commandParameters != null) - { - AttachParameters(command, commandParameters); - } - } - - /// - /// This method clears (if necessary) the connection, transaction, command type and parameters - /// from the provided command - /// - /// - /// Not implemented here because the behavior of this method differs on each data provider. - /// - /// The IDbCommand to be cleared - protected virtual void ClearCommand(IDbCommand command) - { - // do nothing by default - } - - #endregion private utility methods - - #region ExecuteDataset - - /// - /// Execute an IDbCommand (that returns a resultset) against the database specified in - /// the connection string. - /// - /// The IDbCommand object to use - /// A DataSet containing the resultset generated by the command - /// Thrown if command is null. - public virtual DataSet ExecuteDataset(IDbCommand command) - { - var mustCloseConnection = false; - - // Clean Up Parameter Syntax - CleanParameterSyntax(command); - - if (command.Connection.State != ConnectionState.Open) - { - command.Connection.Open(); - mustCloseConnection = true; - } - - // Create the DataAdapter & DataSet - IDbDataAdapter da = null; - try - { - da = GetDataAdapter(); - da.SelectCommand = command; - - var ds = new DataSet(); - - // Fill the DataSet using default values for DataTable names, etc - da.Fill(ds); - - // Detach the IDataParameters from the command object, so they can be used again - // Don't do this...screws up output params -- cjb - //command.Parameters.Clear(); - - // Return the DataSet - return ds; - } - finally - { - if (mustCloseConnection) - { - command.Connection.Close(); - } - if (da != null) - { - var id = da as IDisposable; - if (id != null) - id.Dispose(); - } - } - } - - /// - /// Execute an IDbCommand (that returns a resultset and takes no parameters) against the database specified in - /// the connection string. - /// - /// - /// - /// DataSet ds = helper.ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders"); - /// - /// A valid connection string for an IDbConnection - /// SQL command - /// A DataSet containing the resultset generated by the command - /// Thrown if connectionString is null - /// Thrown if commandText is null - /// A DataSet containing the resultset generated by the command - public virtual DataSet ExecuteDataset(string connectionString, string commandText) - { - // Pass through the call providing null for the set of IDataParameters - return ExecuteDataset(connectionString, commandText, null); - } - - /// - /// Execute an IDbCommand (that returns a resultset) against the database specified in the connection string - /// using the provided parameters. - /// - /// - /// - /// DataSet ds = helper.ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders", new IDbParameter("@prodid", 24)); - /// - /// A valid connection string for an IDbConnection - /// SQL command - /// An array of IDbParamters used to execute the command - /// A DataSet containing the resultset generated by the command - /// Thrown if connectionString is null - /// Thrown if any of the IDataParameters.ParameterNames are null, or if the parameter count does not match the number of values supplied - /// Thrown if commandText is null - /// Thrown if the parameter count does not match the number of values supplied - public virtual DataSet ExecuteDataset(string connectionString, string commandText, - params IDataParameter[] commandParameters) - { - if (string.IsNullOrEmpty(connectionString)) throw new ArgumentNullException(nameof(connectionString)); - - // Create & open an IDbConnection, and dispose of it after we are done - using (var connection = GetConnection(connectionString)) - { - connection.Open(); - - // Call the overload that takes a connection in place of the connection string - return ExecuteDataset(connection, commandText, commandParameters); - } - } - - /// - /// Execute an IDbCommand (that returns a resultset and takes no parameters) against the provided IDbConnection. - /// - /// - /// - /// DataSet ds = helper.ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders"); - /// - /// A valid IDbConnection - /// SQL command - /// A DataSet containing the resultset generated by the command - /// Thrown if commandText is null - /// Thrown if connection is null - public virtual DataSet ExecuteDataset(IDbConnection connection, string commandText) - { - // Pass through the call providing null for the set of IDataParameters - return ExecuteDataset(connection, commandText, null); - } - - /// - /// Execute an IDbCommand (that returns a resultset) against the specified IDbConnection - /// using the provided parameters. - /// - /// - /// - /// DataSet ds = helper.ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders", new IDataParameter("@prodid", 24)); - /// - /// A valid IDbConnection - /// SQL command - /// An array of IDataParameters used to execute the command - /// A DataSet containing the resultset generated by the command - /// Thrown if any of the IDataParameters.ParameterNames are null, or if the parameter count does not match the number of values supplied - /// Thrown if commandText is null - /// Thrown if the parameter count does not match the number of values supplied - /// Thrown if connection is null - public virtual DataSet ExecuteDataset(IDbConnection connection, string commandText, - params IDataParameter[] commandParameters) - { - if (connection == null) throw new ArgumentNullException(nameof(connection)); - - // Create a command and prepare it for execution - var cmd = connection.CreateCommand(); - bool mustCloseConnection; - PrepareCommand(cmd, connection, null, commandText, commandParameters, out mustCloseConnection); - CleanParameterSyntax(cmd); - - var ds = ExecuteDataset(cmd); - - if (mustCloseConnection) - connection.Close(); - - // Return the DataSet - return ds; - } - - - - /// - /// Execute an IDbCommand (that returns a resultset and takes no parameters) against the provided IDbTransaction. - /// - /// - /// DataSet ds = helper.ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders"); - /// - /// A valid IDbTransaction - /// SQL command - /// A DataSet containing the resultset generated by the command - /// Thrown if commandText is null - /// Thrown if transaction is null - /// Thrown if transaction.Connection is null - public virtual DataSet ExecuteDataset(IDbTransaction transaction, string commandText) - { - // Pass through the call providing null for the set of IDataParameters - return ExecuteDataset(transaction, commandText, null); - } - - /// - /// Execute an IDbCommand (that returns a resultset) against the specified IDbTransaction - /// using the provided parameters. - /// - /// - /// - /// DataSet ds = helper.ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders", new IDataParameter("@prodid", 24)); - /// - /// A valid IDbTransaction - /// SQL command - /// An array of IDataParameters used to execute the command - /// A DataSet containing the resultset generated by the command - /// Thrown if any of the IDataParameters.ParameterNames are null, or if the parameter count does not match the number of values supplied - /// Thrown if commandText is null - /// Thrown if the parameter count does not match the number of values supplied - /// Thrown if transaction is null - /// Thrown if transaction.Connection is null - public virtual DataSet ExecuteDataset(IDbTransaction transaction, string commandText, - params IDataParameter[] commandParameters) - { - if (transaction == null) throw new ArgumentNullException(nameof(transaction)); - if (transaction != null && transaction.Connection == null) - throw new ArgumentException( - "The transaction was rolled back or commited, please provide an open transaction.", - nameof(transaction)); - - // Create a command and prepare it for execution - var cmd = transaction.Connection.CreateCommand(); - bool mustCloseConnection; - PrepareCommand(cmd, transaction.Connection, transaction, commandText, commandParameters, - out mustCloseConnection); - CleanParameterSyntax(cmd); - - return ExecuteDataset(cmd); - - } - - #endregion ExecuteDataset - - #region ExecuteNonQuery - - /// - /// Execute an IDbCommand (that returns no resultset) against the database - /// - /// The IDbCommand to execute - /// An int representing the number of rows affected by the command - /// Thrown if command is null. - public virtual int ExecuteNonQuery(IDbCommand command) - { - var mustCloseConnection = false; - - // Clean Up Parameter Syntax - CleanParameterSyntax(command); - - if (command.Connection.State != ConnectionState.Open) - { - command.Connection.Open(); - mustCloseConnection = true; - } - - if (command == null) throw new ArgumentNullException(nameof(command)); - -#if (DEBUG) - DataProvider.RecordDao.RecordCommandExecute(command, nameof(ExecuteNonQuery)); -#endif - - int returnVal = command.ExecuteNonQuery(); - - if (mustCloseConnection) - { - command.Connection.Close(); - } - - return returnVal; - } - - /// - /// Execute an IDbCommand (that returns no resultset and takes no parameters) against the database specified in - /// the connection string - /// - /// A valid connection string for an IDbConnection - /// SQL command - /// An int representing the number of rows affected by the command - /// Thrown if connectionString is null - /// Thrown if commandText is null - public virtual int ExecuteNonQuery(string connectionString, string commandText) - { - // Pass through the call providing null for the set of IDataParameters - return ExecuteNonQuery(connectionString, commandText, null); - } - - /// - /// Execute an IDbCommand (that returns no resultset) against the database specified in the connection string - /// using the provided parameters - /// - /// A valid connection string for an IDbConnection - /// SQL command - /// An array of IDataParameters used to execute the command - /// An int representing the number of rows affected by the command - /// Thrown if connectionString is null - /// Thrown if any of the IDataParameters.ParameterNames are null, or if the parameter count does not match the number of values supplied - /// Thrown if commandText is null - /// Thrown if the parameter count does not match the number of values supplied - public virtual int ExecuteNonQuery(string connectionString, string commandText, - params IDataParameter[] commandParameters) - { - if (string.IsNullOrEmpty(connectionString)) throw new ArgumentNullException(nameof(connectionString)); - - // Create & open an IDbConnection, and dispose of it after we are done - using (var connection = GetConnection(connectionString)) - { - connection.Open(); - - // Call the overload that takes a connection in place of the connection string - return ExecuteNonQuery(connection, commandText, commandParameters); - } - } - - public virtual int ExecuteNonQueryAndReturnId(string tableName, string idColumnName, string connectionString, - string commandText, - params IDataParameter[] commandParameters) - { - if (string.IsNullOrEmpty(connectionString)) throw new ArgumentNullException(nameof(connectionString)); - - int id; - - using (var conn = GetConnection(connectionString)) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - id = ExecuteNonQueryAndReturnId(tableName, idColumnName, trans, commandText, commandParameters); - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - - return id; - } - - public virtual int ExecuteNonQueryAndReturnId(string tableName, string idColumnName, IDbTransaction trans, - string commandText, params IDataParameter[] commandParameters) - { - if (string.IsNullOrEmpty(commandText)) return 0; - - var id = 0; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - ExecuteNonQuery(trans, commandText, commandParameters); - - using (var rdr = ExecuteReader(trans, $"SELECT @@IDENTITY AS '{idColumnName}'")) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - id = rdr.GetInt32(0); - } - rdr.Close(); - } - - if (id == 0) - { - trans.Rollback(); - } - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - ExecuteNonQuery(trans, commandText, commandParameters); - - using (var rdr = ExecuteReader(trans, $"SELECT @@IDENTITY AS '{idColumnName}'")) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - id = Convert.ToInt32(rdr[0]); - } - rdr.Close(); - } - - if (id == 0) - { - trans.Rollback(); - } - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - commandText += " RETURNING " + idColumnName; - - using (var rdr = ExecuteReader(trans, commandText, commandParameters)) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - id = rdr.GetInt32(0); - } - rdr.Close(); - } - - if (id == 0) - { - trans.Rollback(); - } - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - ExecuteNonQuery(trans, commandText, commandParameters); - - var sequence = DataProvider.DatabaseDao.GetOracleSequence(tableName, idColumnName); - - if (!string.IsNullOrEmpty(sequence)) - { - using (var rdr = ExecuteReader(trans, $"SELECT {sequence}.currval from dual")) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - id = Convert.ToInt32(rdr[0]); - } - rdr.Close(); - } - } - - if (id == 0) - { - trans.Rollback(); - } - } - - return id; - } - - /// - /// Execute an IDbCommand (that returns no resultset and takes no parameters) against the provided IDbConnection. - /// - /// A valid IDbConnection - /// SQL command - /// An int representing the number of rows affected by the command - /// Thrown if commandText is null - /// Thrown if connection is null - public virtual int ExecuteNonQuery(IDbConnection connection, string commandText) - { - // Pass through the call providing null for the set of IDataParameters - return ExecuteNonQuery(connection, commandText, null); - } - - /// - /// Execute an IDbCommand (that returns no resultset) against the specified IDbConnection - /// using the provided parameters. - /// - /// - /// - /// A valid IDbConnection - /// SQL command - /// An array of IDbParamters used to execute the command - /// An int representing the number of rows affected by the command - /// Thrown if any of the IDataParameters.ParameterNames are null, or if the parameter count does not match the number of values supplied - /// Thrown if commandText is null - /// Thrown if the parameter count does not match the number of values supplied - /// Thrown if connection is null - public virtual int ExecuteNonQuery(IDbConnection connection, string commandText, - params IDataParameter[] commandParameters) - { - if (connection == null) throw new ArgumentNullException(nameof(connection)); - - // Create a command and prepare it for execution - var cmd = connection.CreateCommand(); - bool mustCloseConnection; - PrepareCommand(cmd, connection, null, commandText, commandParameters, out mustCloseConnection); - CleanParameterSyntax(cmd); - - // Finally, execute the command - var retval = ExecuteNonQuery(cmd); - - // Detach the IDataParameters from the command object, so they can be used again - // don't do this...screws up output parameters -- cjbreisch - // cmd.Parameters.Clear(); - if (mustCloseConnection) - connection.Close(); - return retval; - } - - /// - /// Execute an IDbCommand (that returns no resultset and takes no parameters) against the provided IDbTransaction. - /// - /// A valid IDbTransaction - /// SQL command - /// An int representing the number of rows affected by the command - /// Thrown if commandText is null - /// Thrown if transaction is null - /// Thrown if transaction.Connection is null - public virtual int ExecuteNonQuery(IDbTransaction transaction, string commandText) - { - // Pass through the call providing null for the set of IDataParameters - return ExecuteNonQuery(transaction, commandText, null); - } - - /// - /// Execute an IDbCommand (that returns no resultset) against the specified IDbTransaction - /// using the provided parameters. - /// - /// A valid IDbTransaction - /// SQL command - /// An array of IDataParameters used to execute the command - /// An int representing the number of rows affected by the command - /// Thrown if any of the IDataParameters.ParameterNames are null, or if the parameter count does not match the number of values supplied - /// Thrown if commandText is null - /// Thrown if the parameter count does not match the number of values supplied - /// Thrown if transaction is null - /// Thrown if transaction.Connection is null - public virtual int ExecuteNonQuery(IDbTransaction transaction, string commandText, - params IDataParameter[] commandParameters) - { - if (transaction == null) throw new ArgumentNullException(nameof(transaction)); - if (transaction != null && transaction.Connection == null) - throw new ArgumentException( - "The transaction was rolled back or commited, please provide an open transaction.", - nameof(transaction)); - - // Create a command and prepare it for execution - var cmd = transaction.Connection.CreateCommand(); - bool mustCloseConnection; - PrepareCommand(cmd, transaction.Connection, transaction, commandText, commandParameters, - out mustCloseConnection); - CleanParameterSyntax(cmd); - - // Finally, execute the command - var retval = ExecuteNonQuery(cmd); - - // Detach the IDataParameters from the command object, so they can be used again - // don't do this...screws up output parameters -- cjbreisch - // cmd.Parameters.Clear(); - return retval; - } - - #endregion ExecuteNonQuery - - #region ExecuteReader - - /// - /// Execute an IDbCommand (that returns a resultset) against the database specified in - /// the connection string. - /// - /// The IDbCommand object to use - /// A IDataReader containing the resultset generated by the command - /// Thrown if command is null. - public virtual IDataReader ExecuteReader(IDbCommand command) - { - return ExecuteReader(command, AdoConnectionOwnership.External); - } - - /// - /// Execute an IDbCommand (that returns a resultset) against the database specified in - /// the connection string. - /// - /// The IDbCommand object to use - /// Enum indicating whether the connection was created internally or externally. - /// A IDataReader containing the resultset generated by the command - /// Thrown if command is null. - protected virtual IDataReader ExecuteReader(IDbCommand command, AdoConnectionOwnership connectionOwnership) - { - // Clean Up Parameter Syntax - CleanParameterSyntax(command); - - if (command.Connection.State != ConnectionState.Open) - { - command.Connection.Open(); - connectionOwnership = AdoConnectionOwnership.Internal; - } - - // Create a reader - -#if (DEBUG) - DataProvider.RecordDao.RecordCommandExecute(command, nameof(ExecuteReader)); -#endif - - // Call ExecuteReader with the appropriate CommandBehavior - var dataReader = connectionOwnership == AdoConnectionOwnership.External - ? command.ExecuteReader() - : command.ExecuteReader(CommandBehavior.CloseConnection); - - ClearCommand(command); - - return dataReader; - } - - /// - /// Create and prepare an IDbCommand, and call ExecuteReader with the appropriate CommandBehavior. - /// - /// - /// If we created and opened the connection, we want the connection to be closed when the DataReader is closed. - /// - /// If the caller provided the connection, we want to leave it to them to manage. - /// - /// A valid IDbConnection, on which to execute this command - /// A valid IDbTransaction, or 'null' - /// SQL command - /// An array of IDataParameters to be associated with the command or 'null' if no parameters are required - /// Indicates whether the connection parameter was provided by the caller, or created by AdoHelper - /// IDataReader containing the results of the command - /// Thrown if any of the IDataParameters.ParameterNames are null, or if the parameter count does not match the number of values supplied - /// Thrown if commandText is null - /// Thrown if the parameter count does not match the number of values supplied - /// Thrown if connection is null - private IDataReader ExecuteReader(IDbConnection connection, IDbTransaction transaction, string commandText, - IDataParameter[] commandParameters, AdoConnectionOwnership connectionOwnership) - { - if (connection == null) throw new ArgumentNullException(nameof(connection)); - - var mustCloseConnection = false; - // Create a command and prepare it for execution - var cmd = connection.CreateCommand(); - try - { - PrepareCommand(cmd, connection, transaction, commandText, commandParameters, out mustCloseConnection); - CleanParameterSyntax(cmd); - - // override conenctionOwnership if we created the connection in PrepareCommand -- cjbreisch - if (mustCloseConnection) - { - connectionOwnership = AdoConnectionOwnership.Internal; - } - - // Create a reader - - var dataReader = ExecuteReader(cmd, connectionOwnership); - - ClearCommand(cmd); - - return dataReader; - } - catch - { - if (mustCloseConnection) - connection.Close(); - throw; - } - } - - /// - /// Execute an IDbCommand (that returns a resultset and takes no parameters) against the database specified in - /// the connection string. - /// - /// A valid connection string for an IDbConnection - /// SQL command - /// A IDataReader containing the resultset generated by the command - /// Thrown if connectionString is null - /// Thrown if commandText is null - public virtual IDataReader ExecuteReader(string connectionString, string commandText) - { - // Pass through the call providing null for the set of IDataParameters - return ExecuteReader(connectionString, commandText, null); - } - - /// - /// Execute an IDbCommand (that returns a resultset) against the database specified in the connection string - /// using the provided parameters. - /// - /// A valid connection string for an IDbConnection - /// SQL command - /// An array of IDataParameters used to execute the command - /// A IDataReader containing the resultset generated by the command - /// Thrown if connectionString is null - /// Thrown if any of the IDataParameters.ParameterNames are null, or if the parameter count does not match the number of values supplied - /// Thrown if commandText is null - /// Thrown if the parameter count does not match the number of values supplied - public virtual IDataReader ExecuteReader(string connectionString, string commandText, - params IDataParameter[] commandParameters) - { - if (string.IsNullOrEmpty(connectionString)) throw new ArgumentNullException(nameof(connectionString)); - IDbConnection connection = null; - try - { - connection = GetConnection(connectionString); - connection.Open(); - - // Call the private overload that takes an internally owned connection in place of the connection string - return ExecuteReader(connection, null, commandText, commandParameters, AdoConnectionOwnership.Internal); - } - catch - { - // If we fail to return the IDataReader, we need to close the connection ourselves - connection?.Close(); - throw; - } - - } - - /// - /// Execute an IDbCommand (that returns a resultset and takes no parameters) against the provided IDbConnection. - /// - /// - /// - /// IDataReader dr = helper.ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders"); - /// - /// A valid IDbConnection - /// SQL command - /// an IDataReader containing the resultset generated by the command - /// Thrown if commandText is null - public virtual IDataReader ExecuteReader(IDbConnection connection, string commandText) - { - // Pass through the call providing null for the set of IDataParameters - return ExecuteReader(connection, commandText, null); - } - - /// - /// Execute an IDbCommand (that returns a resultset) against the specified IDbConnection - /// using the provided parameters. - /// - /// - /// - /// IDataReader dr = helper.ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders", new IDataParameter("@prodid", 24)); - /// - /// A valid IDbConnection - /// SQL command - /// An array of IDataParameters used to execute the command - /// an IDataReader containing the resultset generated by the command - /// Thrown if any of the IDataParameters.ParameterNames are null, or if the parameter count does not match the number of values supplied - /// Thrown if commandText is null - /// Thrown if the parameter count does not match the number of values supplied - /// Thrown if connection is null - public virtual IDataReader ExecuteReader(IDbConnection connection, string commandText, - params IDataParameter[] commandParameters) - { - // Pass through the call to the private overload using a null transaction value and an externally owned connection - return ExecuteReader(connection, null, commandText, commandParameters, AdoConnectionOwnership.External); - } - - /// - /// Execute an IDbCommand (that returns a resultset and takes no parameters) against the provided IDbTransaction. - /// - /// - /// IDataReader dr = helper.ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders"); - /// - /// A valid IDbTransaction - /// SQL command - /// A IDataReader containing the resultset generated by the command - /// Thrown if commandText is null - public virtual IDataReader ExecuteReader(IDbTransaction transaction, string commandText) - { - // Pass through the call providing null for the set of IDataParameters - return ExecuteReader(transaction, commandText, null); - } - - /// - /// Execute an IDbCommand (that returns a resultset) against the specified IDbTransaction - /// using the provided parameters. - /// - /// - /// - /// IDataReader dr = helper.ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders", new IDataParameter("@prodid", 24)); - /// - /// A valid IDbTransaction - /// SQL command - /// An array of IDataParameters used to execute the command - /// A IDataReader containing the resultset generated by the command - public virtual IDataReader ExecuteReader(IDbTransaction transaction, string commandText, - params IDataParameter[] commandParameters) - { - if (transaction == null) throw new ArgumentNullException(nameof(transaction)); - if (transaction != null && transaction.Connection == null) - throw new ArgumentException( - "The transaction was rolled back or commited, please provide an open transaction.", - nameof(transaction)); - - // Pass through to private overload, indicating that the connection is owned by the caller - return ExecuteReader(transaction.Connection, transaction, commandText, commandParameters, - AdoConnectionOwnership.External); - } - - #endregion ExecuteReader - - #region ExecuteScalar - - /// - /// Execute an IDbCommand (that returns a 1x1 resultset) against the database specified in - /// the connection string. - /// - /// The IDbCommand to execute - /// An object containing the value in the 1x1 resultset generated by the command - /// Thrown if command is null. - public virtual object ExecuteScalar(IDbCommand command) - { - var mustCloseConnection = false; - - // Clean Up Parameter Syntax - CleanParameterSyntax(command); - - if (command.Connection.State != ConnectionState.Open) - { - command.Connection.Open(); - mustCloseConnection = true; - } - -#if (DEBUG) - DataProvider.RecordDao.RecordCommandExecute(command, nameof(ExecuteScalar)); -#endif - - // Execute the command & return the results - var retval = command.ExecuteScalar(); - - // Detach the IDataParameters from the command object, so they can be used again - // don't do this...screws up output params -- cjbreisch - // command.Parameters.Clear(); - - if (mustCloseConnection) - { - command.Connection.Close(); - } - - return retval; - } - - /// - /// Execute an IDbCommand (that returns a 1x1 resultset and takes no parameters) against the database specified in - /// the connection string. - /// - /// - /// - /// int orderCount = (int)helper.ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount"); - /// - /// A valid connection string for an IDbConnection - /// SQL command - /// An object containing the value in the 1x1 resultset generated by the command - /// Thrown if connectionString is null - /// Thrown if commandText is null - public virtual object ExecuteScalar(string connectionString, string commandText) - { - // Pass through the call providing null for the set of IDataParameters - return ExecuteScalar(connectionString, commandText, null); - } - - /// - /// Execute an IDbCommand (that returns a 1x1 resultset) against the database specified in the connection string - /// using the provided parameters. - /// - /// A valid connection string for an IDbConnection - /// SQL command - /// An array of IDataParameters used to execute the command - /// An object containing the value in the 1x1 resultset generated by the command - /// Thrown if connectionString is null - /// Thrown if any of the IDataParameters.ParameterNames are null, or if the parameter count does not match the number of values supplied - /// Thrown if commandText is null - /// Thrown if the parameter count does not match the number of values supplied - public virtual object ExecuteScalar(string connectionString, string commandText, - params IDataParameter[] commandParameters) - { - if (string.IsNullOrEmpty(connectionString)) throw new ArgumentNullException(nameof(connectionString)); - // Create & open an IDbConnection, and dispose of it after we are done - IDbConnection connection = null; - try - { - connection = GetConnection(connectionString); - connection.Open(); - - // Call the overload that takes a connection in place of the connection string - return ExecuteScalar(connection, commandText, commandParameters); - } - finally - { - var id = connection as IDisposable; - if (id != null) id.Dispose(); - } - } - - /// - /// Execute an IDbCommand (that returns a 1x1 resultset and takes no parameters) against the provided IDbConnection. - /// - /// - /// - /// int orderCount = (int)helper.ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount"); - /// - /// A valid IDbConnection - /// SQL command - /// An object containing the value in the 1x1 resultset generated by the command - /// Thrown if commandText is null - public virtual object ExecuteScalar(IDbConnection connection, string commandText) - { - // Pass through the call providing null for the set of IDbParameters - return ExecuteScalar(connection, commandText, null); - } - - /// - /// Execute an IDbCommand (that returns a 1x1 resultset) against the specified IDbConnection - /// using the provided parameters. - /// - /// A valid IDbConnection - /// SQL command - /// An array of IDataParameters used to execute the command - /// An object containing the value in the 1x1 resultset generated by the command - /// Thrown if any of the IDataParameters.ParameterNames are null, or if the parameter count does not match the number of values supplied - /// Thrown if commandText is null - /// Thrown if the parameter count does not match the number of values supplied - /// Thrown if connection is null - public virtual object ExecuteScalar(IDbConnection connection, string commandText, - params IDataParameter[] commandParameters) - { - if (connection == null) throw new ArgumentNullException(nameof(connection)); - - // Create a command and prepare it for execution - var cmd = connection.CreateCommand(); - - bool mustCloseConnection; - PrepareCommand(cmd, connection, null, commandText, commandParameters, out mustCloseConnection); - CleanParameterSyntax(cmd); - - // Execute the command & return the results - var retval = ExecuteScalar(cmd); - - // Detach the IDataParameters from the command object, so they can be used again - // don't do this...screws up output parameters -- cjbreisch - // cmd.Parameters.Clear(); - - if (mustCloseConnection) - connection.Close(); - - return retval; - } - - /// - /// Execute an IDbCommand (that returns a 1x1 resultset and takes no parameters) against the provided IDbTransaction. - /// - /// - /// - /// int orderCount = (int)helper.ExecuteScalar(tran, CommandType.StoredProcedure, "GetOrderCount"); - /// - /// A valid IDbTransaction - /// SQL command - /// An object containing the value in the 1x1 resultset generated by the command - /// Thrown if commandText is null - public virtual object ExecuteScalar(IDbTransaction transaction, string commandText) - { - // Pass through the call providing null for the set of IDataParameters - return ExecuteScalar(transaction, commandText, null); - } - - /// - /// Execute an IDbCommand (that returns a 1x1 resultset) against the specified IDbTransaction - /// using the provided parameters. - /// - /// A valid IDbTransaction - /// SQL command - /// An array of IDbParamters used to execute the command - /// An object containing the value in the 1x1 resultset generated by the command - /// Thrown if any of the IDataParameters.ParameterNames are null, or if the parameter count does not match the number of values supplied - /// Thrown if commandText is null - /// Thrown if the parameter count does not match the number of values supplied - /// Thrown if transaction is null - /// Thrown if transaction.Connection is null - public virtual object ExecuteScalar(IDbTransaction transaction, string commandText, - params IDataParameter[] commandParameters) - { - if (transaction == null) throw new ArgumentNullException(nameof(transaction)); - if (transaction != null && transaction.Connection == null) - throw new ArgumentException( - "The transaction was rolled back or commited, please provide an open transaction.", - nameof(transaction)); - - // Create a command and prepare it for execution - var cmd = transaction.Connection.CreateCommand(); - bool mustCloseConnection; - PrepareCommand(cmd, transaction.Connection, transaction, commandText, commandParameters, - out mustCloseConnection); - CleanParameterSyntax(cmd); - - // Execute the command & return the results - var retval = ExecuteScalar(cmd); - - // Detach the IDataParameters from the command object, so they can be used again - // don't do this...screws up output parameters -- cjbreisch - // cmd.Parameters.Clear(); - return retval; - } - - #endregion ExecuteScalar - - #region ExecuteInt - - public int ExecuteInt(string connectionString, string commandText) - { - var count = 0; - - using (var conn = GetConnection(connectionString)) - { - conn.Open(); - using (var rdr = ExecuteReader(conn, commandText)) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - count = rdr.GetInt32(0); - } - rdr.Close(); - } - } - return count; - } - - public int ExecuteInt(string connectionString, string commandText, IDataParameter[] commandParameters) - { - var count = 0; - - using (var conn = GetConnection(connectionString)) - { - conn.Open(); - using (var rdr = ExecuteReader(conn, commandText, commandParameters)) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - count = rdr.GetInt32(0); - } - rdr.Close(); - } - } - return count; - } - - #endregion ExecuteInt - - #region FillDataset - - /// - /// Execute an IDbCommand (that returns a resultset) against the database specified in - /// the connection string. - /// - /// The IDbCommand to execute - /// A DataSet wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// Thrown if command is null. - public virtual void FillDataset(IDbCommand command, DataSet dataSet, string[] tableNames) - { - var mustCloseConnection = false; - - // Clean Up Parameter Syntax - CleanParameterSyntax(command); - - if (command.Connection.State != ConnectionState.Open) - { - command.Connection.Open(); - mustCloseConnection = true; - } - - // Create the DataAdapter & DataSet - IDbDataAdapter dataAdapter = null; - try - { - dataAdapter = GetDataAdapter(); - dataAdapter.SelectCommand = command; - - // Add the table mappings specified by the user - if (tableNames != null && tableNames.Length > 0) - { - var tableName = "Table"; - for (var index = 0; index < tableNames.Length; index++) - { - if (tableNames[index] == null || tableNames[index].Length == 0) - throw new ArgumentException( - "The tableNames parameter must contain a list of tables, a value was provided as null or empty string.", - nameof(tableNames)); - dataAdapter.TableMappings.Add( - tableName + (index == 0 ? "" : index.ToString()), - tableNames[index]); - } - } - - // Fill the DataSet using default values for DataTable names, etc - dataAdapter.Fill(dataSet); - - if (mustCloseConnection) - { - command.Connection.Close(); - } - - // Detach the IDataParameters from the command object, so they can be used again - // don't do this...screws up output params --cjb - // command.Parameters.Clear(); - } - finally - { - var id = dataAdapter as IDisposable; - if (id != null) id.Dispose(); - } - - } - - /// - /// Execute an IDbCommand (that returns a resultset and takes no parameters) against the database specified in - /// the connection string. - /// - /// - /// - /// helper.FillDataset(connString, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}); - /// - /// A valid connection string for an IDbConnection - /// SQL command - /// A DataSet wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// Thrown if connectionString is null - /// Thrown if commandText is null - public virtual void FillDataset(string connectionString, string commandText, DataSet dataSet, - string[] tableNames) - { - if (string.IsNullOrEmpty(connectionString)) throw new ArgumentNullException(nameof(connectionString)); - if (dataSet == null) throw new ArgumentNullException(nameof(dataSet)); - - // Create & open an IDbConnection, and dispose of it after we are done - IDbConnection connection = null; - try - { - connection = GetConnection(connectionString); - connection.Open(); - - // Call the overload that takes a connection in place of the connection string - FillDataset(connection, commandText, dataSet, tableNames); - } - finally - { - var id = connection as IDisposable; - if (id != null) id.Dispose(); - } - } - - /// - /// Execute an IDbCommand (that returns a resultset) against the database specified in the connection string - /// using the provided parameters. - /// - /// A valid connection string for an IDbConnection - /// SQL command - /// An array of IDataParameters used to execute the command - /// A DataSet wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// - /// Thrown if connectionString is null - /// Thrown if any of the IDataParameters.ParameterNames are null, or if the parameter count does not match the number of values supplied - /// Thrown if commandText is null - /// Thrown if the parameter count does not match the number of values supplied - public virtual void FillDataset(string connectionString, - string commandText, DataSet dataSet, string[] tableNames, - params IDataParameter[] commandParameters) - { - if (string.IsNullOrEmpty(connectionString)) throw new ArgumentNullException(nameof(connectionString)); - if (dataSet == null) throw new ArgumentNullException(nameof(dataSet)); - // Create & open an IDbConnection, and dispose of it after we are done - IDbConnection connection = null; - try - { - connection = GetConnection(connectionString); - connection.Open(); - - // Call the overload that takes a connection in place of the connection string - FillDataset(connection, commandText, dataSet, tableNames, commandParameters); - } - finally - { - var id = connection as IDisposable; - if (id != null) id.Dispose(); - } - } - - /// - /// Execute an IDbCommand (that returns a resultset and takes no parameters) against the provided IDbConnection. - /// - /// - /// - /// helper.FillDataset(conn, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}); - /// - /// A valid IDbConnection - /// SQL command - /// A dataset wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// - /// Thrown if commandText is null - /// Thrown if connection is null - public virtual void FillDataset(IDbConnection connection, - string commandText, DataSet dataSet, string[] tableNames) - { - FillDataset(connection, commandText, dataSet, tableNames, null); - } - - /// - /// Execute an IDbCommand (that returns a resultset) against the specified IDbConnection - /// using the provided parameters. - /// - /// A valid IDbConnection - /// SQL command - /// A DataSet wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// - /// An array of IDataParameters used to execute the command - /// Thrown if commandText is null - /// Thrown if connection is null - public virtual void FillDataset(IDbConnection connection, - string commandText, DataSet dataSet, string[] tableNames, - params IDataParameter[] commandParameters) - { - FillDataset(connection, null, commandText, dataSet, tableNames, commandParameters); - } - - /// - /// Execute an IDbCommand (that returns a resultset and takes no parameters) against the provided IDbTransaction. - /// - /// - /// - /// helper.FillDataset(tran, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}); - /// - /// A valid IDbTransaction - /// SQL command - /// A dataset wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// - /// Thrown if commandText is null - /// Thrown if transaction is null - /// Thrown if transaction.Connection is null - public virtual void FillDataset(IDbTransaction transaction, - string commandText, - DataSet dataSet, string[] tableNames) - { - FillDataset(transaction, commandText, dataSet, tableNames, null); - } - - /// - /// Execute an IDbCommand (that returns a resultset) against the specified IDbTransaction - /// using the provided parameters. - /// - /// A valid IDbTransaction - /// SQL command - /// A DataSet wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// - /// An array of IDataParameters used to execute the command - /// Thrown if commandText is null - /// Thrown if transaction is null - /// Thrown if transaction.Connection is null - public virtual void FillDataset(IDbTransaction transaction, - string commandText, DataSet dataSet, string[] tableNames, - params IDataParameter[] commandParameters) - { - FillDataset(transaction.Connection, transaction, commandText, dataSet, tableNames, commandParameters); - } - - /// - /// Private helper method that execute an IDbCommand (that returns a resultset) against the specified IDbTransaction and IDbConnection - /// using the provided parameters. - /// - /// A valid IDbConnection - /// A valid IDbTransaction - /// SQL command - /// A DataSet wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// - /// An array of IDataParameters used to execute the command - private void FillDataset(IDbConnection connection, IDbTransaction transaction, - string commandText, DataSet dataSet, string[] tableNames, - params IDataParameter[] commandParameters) - { - if (connection == null) throw new ArgumentNullException(nameof(connection)); - if (dataSet == null) throw new ArgumentNullException(nameof(dataSet)); - - // Create a command and prepare it for execution - var command = connection.CreateCommand(); - bool mustCloseConnection; - PrepareCommand(command, connection, transaction, commandText, commandParameters, out mustCloseConnection); - CleanParameterSyntax(command); - - FillDataset(command, dataSet, tableNames); - - if (mustCloseConnection) - connection.Close(); - } - - #endregion - - #region UpdateDataset - - /// - /// This method consumes the RowUpdatingEvent and passes it on to the consumer specifed in the call to UpdateDataset - /// - /// The object that generated the event - /// The System.Data.Common.RowUpdatingEventArgs - protected void RowUpdating(object obj, RowUpdatingEventArgs e) - { - if (MRowUpdating != null) - MRowUpdating(obj, e); - } - - /// - /// This method consumes the RowUpdatedEvent and passes it on to the consumer specifed in the call to UpdateDataset - /// - /// The object that generated the event - /// The System.Data.Common.RowUpdatingEventArgs - protected void RowUpdated(object obj, RowUpdatedEventArgs e) - { - if (MRowUpdated != null) - MRowUpdated(obj, e); - } - - /// - /// Set up a command for updating a DataSet. - /// - /// command object to prepare - /// output parameter specifying whether the connection used should be closed by the DAAB - /// An IDbCommand object - protected virtual IDbCommand SetCommand(IDbCommand command, out bool mustCloseConnection) - { - mustCloseConnection = false; - if (command != null) - { - var commandParameters = new IDataParameter[command.Parameters.Count]; - command.Parameters.CopyTo(commandParameters, 0); - command.Parameters.Clear(); - PrepareCommand(command, command.Connection, null, command.CommandText, commandParameters, - out mustCloseConnection); - CleanParameterSyntax(command); - } - - return command; - } - - /// - /// Executes the respective command for each inserted, updated, or deleted row in the DataSet. - /// - /// - /// - /// helper.UpdateDataset(conn, insertCommand, deleteCommand, updateCommand, dataSet, "Order"); - /// - /// A valid SQL statement or stored procedure to insert new records into the data source - /// A valid SQL statement or stored procedure to delete records from the data source - /// A valid SQL statement or stored procedure used to update records in the data source - /// The DataSet used to update the data source - /// The DataTable used to update the data source. - public virtual void UpdateDataset(IDbCommand insertCommand, IDbCommand deleteCommand, IDbCommand updateCommand, - DataSet dataSet, string tableName) - { - UpdateDataset(insertCommand, deleteCommand, updateCommand, dataSet, tableName, null, null); - } - - /// - /// Executes the IDbCommand for each inserted, updated, or deleted row in the DataSet also implementing RowUpdating and RowUpdated Event Handlers - /// - /// - /// - /// RowUpdatingEventHandler rowUpdatingHandler = new RowUpdatingEventHandler( OnRowUpdating ); - /// RowUpdatedEventHandler rowUpdatedHandler = new RowUpdatedEventHandler( OnRowUpdated ); - /// helper.UpdateDataSet(sqlInsertCommand, sqlDeleteCommand, sqlUpdateCommand, dataSet, "Order", rowUpdatingHandler, rowUpdatedHandler); - /// - /// A valid SQL statement or stored procedure to insert new records into the data source - /// A valid SQL statement or stored procedure to delete records from the data source - /// A valid SQL statement or stored procedure used to update records in the data source - /// The DataSet used to update the data source - /// The DataTable used to update the data source. - /// RowUpdatingEventHandler - /// RowUpdatedEventHandler - public void UpdateDataset(IDbCommand insertCommand, IDbCommand deleteCommand, IDbCommand updateCommand, - DataSet dataSet, string tableName, RowUpdatingHandler rowUpdatingHandler, - RowUpdatedHandler rowUpdatedHandler) - { - if (string.IsNullOrEmpty(tableName)) throw new ArgumentNullException(nameof(tableName)); - - // Create an IDbDataAdapter, and dispose of it after we are done - IDbDataAdapter dataAdapter = null; - try - { - bool mustCloseUpdateConnection; - bool mustCloseInsertConnection; - bool mustCloseDeleteConnection; - - dataAdapter = GetDataAdapter(); - - // Set the data adapter commands - dataAdapter.UpdateCommand = SetCommand(updateCommand, out mustCloseUpdateConnection); - dataAdapter.InsertCommand = SetCommand(insertCommand, out mustCloseInsertConnection); - dataAdapter.DeleteCommand = SetCommand(deleteCommand, out mustCloseDeleteConnection); - - AddUpdateEventHandlers(dataAdapter, rowUpdatingHandler, rowUpdatedHandler); - - if (dataAdapter is DbDataAdapter) - { - // Update the DataSet changes in the data source - ((DbDataAdapter) dataAdapter).Update(dataSet, tableName); - } - else - { - dataAdapter.TableMappings.Add(tableName, "Table"); - - // Update the DataSet changes in the data source - dataAdapter.Update(dataSet); - } - - // Commit all the changes made to the DataSet - dataSet.Tables[tableName].AcceptChanges(); - - if (mustCloseUpdateConnection) - { - updateCommand.Connection.Close(); - } - if (mustCloseInsertConnection) - { - insertCommand.Connection.Close(); - } - if (mustCloseDeleteConnection) - { - deleteCommand.Connection.Close(); - } - } - finally - { - var id = dataAdapter as IDisposable; - id?.Dispose(); - } - } - - #endregion - - #region CreateCommand - - /// - /// Simplify the creation of an IDbCommand object by allowing - /// a stored procedure and optional parameters to be provided - /// - /// - /// - /// IDbCommand command = helper.CreateCommand(conn, "AddCustomer", "CustomerID", "CustomerName"); - /// - /// A valid connection string for an IDbConnection - /// The name of the stored procedure - /// An array of string to be assigned as the source columns of the stored procedure parameters - /// A valid IDbCommand object - /// Thrown if connectionString is null - /// Thrown if any of the IDataParameters.ParameterNames are null, or if the parameter count does not match the number of values supplied - /// Thrown if spName is null - /// Thrown if the parameter count does not match the number of values supplied - public virtual IDbCommand CreateSpCommand(string connectionString, string spName, params string[] sourceColumns) - { - return CreateSpCommand(GetConnection(connectionString), spName, sourceColumns); - } - - /// - /// Simplify the creation of an IDbCommand object by allowing - /// a stored procedure and optional parameters to be provided - /// - /// - /// - /// IDbCommand command = helper.CreateCommand(conn, "AddCustomer", "CustomerID", "CustomerName"); - /// - /// A valid IDbConnection object - /// The name of the stored procedure - /// An array of string to be assigned as the source columns of the stored procedure parameters - /// A valid IDbCommand object - /// Thrown if spName is null - /// Thrown if connection is null - public virtual IDbCommand CreateSpCommand(IDbConnection connection, string spName, params string[] sourceColumns) - { - if (connection == null) throw new ArgumentNullException(nameof(connection)); - if (string.IsNullOrEmpty(spName)) throw new ArgumentNullException(nameof(spName)); - - // Create an IDbCommand - var cmd = connection.CreateCommand(); - cmd.CommandText = spName; - cmd.CommandType = CommandType.StoredProcedure; - - // If we receive parameter values, we need to figure out where they go - if ((sourceColumns != null) && (sourceColumns.Length > 0)) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = GetSpParameterSet(connection, spName); - - // Assign the provided source columns to these parameters based on parameter order - for (var index = 0; index < sourceColumns.Length; index++) - if (commandParameters[index].SourceColumn == String.Empty) - commandParameters[index].SourceColumn = sourceColumns[index]; - - // Attach the discovered parameters to the IDbCommand object - AttachParameters(cmd, commandParameters); - } - - return cmd; - } - - /// - /// Simplify the creation of an IDbCommand object by allowing - /// a stored procedure and optional parameters to be provided - /// - /// A valid connection string for an IDbConnection - /// A valid SQL statement - /// The parameters for the SQL statement - /// A valid IDbCommand object - public virtual IDbCommand CreateCommand(string connectionString, string commandText, - params IDataParameter[] commandParameters) - { - return CreateCommand(GetConnection(connectionString), commandText, commandParameters); - } - - /// - /// Simplify the creation of an IDbCommand object by allowing - /// a stored procedure and optional parameters to be provided - /// - /// - /// IDbCommand command = helper.CreateCommand(conn, "AddCustomer", "CustomerID", "CustomerName"); - /// - /// A valid IDbConnection object - /// A valid SQL statement - /// The parameters for the SQL statement - /// A valid IDbCommand object - public virtual IDbCommand CreateCommand(IDbConnection connection, string commandText, - params IDataParameter[] commandParameters) - { - if (connection == null) throw new ArgumentNullException(nameof(connection)); - if (string.IsNullOrEmpty(commandText)) throw new ArgumentNullException(nameof(commandText)); - - // Create an IDbCommand - var cmd = connection.CreateCommand(); - cmd.CommandText = commandText; - cmd.CommandType = CommandType.Text; - - // If we receive parameter values, we need to figure out where they go - if (commandParameters != null && commandParameters.Length > 0) - { - // Assign the provided source columns to these parameters based on parameter order - for (var index = 0; index < commandParameters.Length; index++) - commandParameters[index].SourceColumn = - commandParameters[index].ParameterName.TrimStart(new char[] {'@'}); - - // Attach the discovered parameters to the IDbCommand object - AttachParameters(cmd, commandParameters); - } - - return cmd; - } - - #endregion - - #region ExecuteNonQueryTypedParams - - /// - /// Execute a stored procedure via an IDbCommand (that returns no resultset) - /// against the database specified in the connection string using the - /// dataRow column values as the stored procedure's parameters values. - /// This method will assign the parameter values based on row values. - /// - /// The IDbCommand to execute - /// The dataRow used to hold the stored procedure's parameter values. - /// An int representing the number of rows affected by the command - /// Thrown if command is null. - public virtual int ExecuteNonQueryTypedParams(IDbCommand command, DataRow dataRow) - { - int retVal; - - // Clean Up Parameter Syntax - CleanParameterSyntax(command); - - // If the row has values, the store procedure parameters must be initialized - if (dataRow != null && dataRow.ItemArray.Length > 0) - { - // Set the parameters values - AssignParameterValues(command.Parameters, dataRow); - - retVal = ExecuteNonQuery(command); - } - else - { - retVal = ExecuteNonQuery(command); - } - - return retVal; - } - - #endregion - - #region ExecuteDatasetTypedParams - - /// - /// Execute a stored procedure via an IDbCommand (that returns a resultset) against the database specified in - /// the connection string using the dataRow column values as the stored procedure's parameters values. - /// This method will assign the paraemter values based on row values. - /// - /// The IDbCommand to execute - /// The dataRow used to hold the stored procedure's parameter values. - /// A DataSet containing the resultset generated by the command - /// Thrown if command is null. - public virtual DataSet ExecuteDatasetTypedParams(IDbCommand command, DataRow dataRow) - { - DataSet ds; - - // Clean Up Parameter Syntax - CleanParameterSyntax(command); - - // If the row has values, the store procedure parameters must be initialized - if (dataRow != null && dataRow.ItemArray.Length > 0) - { - // Set the parameters values - AssignParameterValues(command.Parameters, dataRow); - - - ds = ExecuteDataset(command); - } - else - { - ds = ExecuteDataset(command); - } - - return ds; - } - - #endregion - - #region ExecuteReaderTypedParams - - /// - /// Execute a stored procedure via an IDbCommand (that returns a resultset) against the database specified in - /// the connection string using the dataRow column values as the stored procedure's parameters values. - /// This method will assign the parameter values based on parameter order. - /// - /// The IDbCommand to execute - /// The dataRow used to hold the stored procedure's parameter values. - /// A IDataReader containing the resultset generated by the command - /// Thrown if command is null. - public virtual IDataReader ExecuteReaderTypedParams(IDbCommand command, DataRow dataRow) - { - IDataReader reader; - - // Clean Up Parameter Syntax - CleanParameterSyntax(command); - - // If the row has values, the store procedure parameters must be initialized - if (dataRow != null && dataRow.ItemArray.Length > 0) - { - // Set the parameters values - AssignParameterValues(command.Parameters, dataRow); - - reader = ExecuteReader(command); - } - else - { - reader = ExecuteReader(command); - } - - return reader; - } - - #endregion - - #region ExecuteScalarTypedParams - - /// - /// Execute a stored procedure via an IDbCommand (that returns a 1x1 resultset) against the database specified in - /// the connection string using the dataRow column values as the stored procedure's parameters values. - /// This method will assign the parameter values based on parameter order. - /// - /// The IDbCommand to execute - /// The dataRow used to hold the stored procedure's parameter values. - /// An object containing the value in the 1x1 resultset generated by the command - /// Thrown if command is null. - public virtual object ExecuteScalarTypedParams(IDbCommand command, DataRow dataRow) - { - object retVal; - - // Clean Up Parameter Syntax - CleanParameterSyntax(command); - - // If the row has values, the store procedure parameters must be initialized - if (dataRow != null && dataRow.ItemArray.Length > 0) - { - // Set the parameters values - AssignParameterValues(command.Parameters, dataRow); - - retVal = ExecuteScalar(command); - } - else - { - retVal = ExecuteScalar(command); - } - - return retVal; - } - - #endregion - - #region Parameter Discovery Functions - - /// - /// Retrieves the set of IDataParameters appropriate for the stored procedure - /// - /// - /// This method will query the database for this information, and then store it in a cache for future requests. - /// - /// A valid connection string for an IDbConnection - /// The name of the stored procedure - /// An array of IDataParameterParameters - /// Thrown if connectionString is null - /// Thrown if spName is null - public virtual IDataParameter[] GetSpParameterSet(string connectionString, string spName) - { - return GetSpParameterSet(connectionString, spName, false); - } - - /// - /// Retrieves the set of IDataParameters appropriate for the stored procedure - /// - /// - /// This method will query the database for this information, and then store it in a cache for future requests. - /// - /// A valid connection string for an IDbConnection - /// The name of the stored procedure - /// A bool value indicating whether the return value parameter should be included in the results - /// An array of IDataParameters - /// Thrown if connectionString is null - /// Thrown if spName is null - public virtual IDataParameter[] GetSpParameterSet(string connectionString, string spName, - bool includeReturnValueParameter) - { - if (string.IsNullOrEmpty(connectionString)) throw new ArgumentNullException(nameof(connectionString)); - if (string.IsNullOrEmpty(spName)) throw new ArgumentNullException(nameof(spName)); - - using (var connection = GetConnection(connectionString)) - { - return GetSpParameterSetInternal(connection, spName, includeReturnValueParameter); - } - } - - /// - /// Retrieves the set of IDataParameters appropriate for the stored procedure - /// - /// - /// This method will query the database for this information, and then store it in a cache for future requests. - /// - /// A valid IDataConnection object - /// The name of the stored procedure - /// An array of IDataParameters - /// Thrown if spName is null - /// Thrown if connection is null - public virtual IDataParameter[] GetSpParameterSet(IDbConnection connection, string spName) - { - return GetSpParameterSet(connection, spName, false); - } - - /// - /// Retrieves the set of IDataParameters appropriate for the stored procedure - /// - /// - /// This method will query the database for this information, and then store it in a cache for future requests. - /// - /// A valid IDbConnection object - /// The name of the stored procedure - /// A bool value indicating whether the return value parameter should be included in the results - /// An array of IDataParameters - /// Thrown if spName is null - /// Thrown if connection is null - public virtual IDataParameter[] GetSpParameterSet(IDbConnection connection, string spName, - bool includeReturnValueParameter) - { - if (connection == null) throw new ArgumentNullException(nameof(connection)); - if (!(connection is ICloneable)) - throw new ArgumentException( - "can't discover parameters if the connection doesn't implement the ICloneable interface", - nameof(connection)); - - var clonedConnection = (IDbConnection) ((ICloneable) connection).Clone(); - return GetSpParameterSetInternal(clonedConnection, spName, includeReturnValueParameter); - } - - /// - /// Retrieves the set of IDataParameters appropriate for the stored procedure - /// - /// A valid IDbConnection object - /// The name of the stored procedure - /// A bool value indicating whether the return value parameter should be included in the results - /// An array of IDataParameters - /// Thrown if spName is null - /// Thrown if connection is null - private IDataParameter[] GetSpParameterSetInternal(IDbConnection connection, string spName, - bool includeReturnValueParameter) - { - if (connection == null) throw new ArgumentNullException(nameof(connection)); - if (string.IsNullOrEmpty(spName)) throw new ArgumentNullException(nameof(spName)); - - // string hashKey = connection.ConnectionString + ":" + spName + (includeReturnValueParameter ? ":include ReturnValue Parameter":""); - - var cachedParameters = GetCachedParameterSet(connection, - spName + (includeReturnValueParameter ? ":include ReturnValue Parameter" : "")); - - if (cachedParameters == null) - { - var spParameters = DiscoverSpParameterSet(connection, spName, includeReturnValueParameter); - CacheParameterSet(connection, - spName + (includeReturnValueParameter ? ":include ReturnValue Parameter" : ""), spParameters); - - cachedParameters = AdoHelperParameterCache.CloneParameters(spParameters); - } - - return cachedParameters; - } - - /// - /// Retrieve a parameter array from the cache - /// - /// A valid connection string for an IDbConnection - /// SQL command - /// An array of IDataParameters - /// Thrown if connectionString is null - /// Thrown if commandText is null - public IDataParameter[] GetCachedParameterSet(string connectionString, string commandText) - { - using (var connection = GetConnection(connectionString)) - { - return GetCachedParameterSetInternal(connection, commandText); - } - } - - /// - /// Retrieve a parameter array from the cache - /// - /// A valid IDbConnection object - /// SQL command - /// An array of IDataParameters - /// Thrown if commandText is null - /// Thrown if connection is null - public IDataParameter[] GetCachedParameterSet(IDbConnection connection, string commandText) - { - return GetCachedParameterSetInternal(connection, commandText); - } - - /// - /// Retrieve a parameter array from the cache - /// - /// A valid IDbConnection object - /// SQL command - /// An array of IDataParameters - private IDataParameter[] GetCachedParameterSetInternal(IDbConnection connection, string commandText) - { - var mustCloseConnection = false; - // this way we control the connection, and therefore the connection string that gets saved as a hash key - if (connection.State != ConnectionState.Open) - { - connection.Open(); - mustCloseConnection = true; - } - - var parameters = AdoHelperParameterCache.GetCachedParameterSet(connection.ConnectionString, commandText); - - if (mustCloseConnection) - { - connection.Close(); - } - - return parameters; - } - - /// - /// Add parameter array to the cache - /// - /// A valid connection string for an IDbConnection - /// SQL command - /// An array of IDataParameters to be cached - public void CacheParameterSet(string connectionString, string commandText, - params IDataParameter[] commandParameters) - { - using (var connection = GetConnection(connectionString)) - { - CacheParameterSetInternal(connection, commandText, commandParameters); - } - } - - /// - /// Add parameter array to the cache - /// - /// A valid IDbConnection - /// SQL command - /// An array of IDataParameters to be cached - public void CacheParameterSet(IDbConnection connection, string commandText, - params IDataParameter[] commandParameters) - { - if (connection is ICloneable) - { - using (var clonedConnection = (IDbConnection) ((ICloneable) connection).Clone()) - { - CacheParameterSetInternal(clonedConnection, commandText, commandParameters); - } - } - else - { - throw new InvalidCastException(); - } - } - - /// - /// Add parameter array to the cache - /// - /// A valid IDbConnection - /// SQL command - /// An array of IDataParameters to be cached - private void CacheParameterSetInternal(IDbConnection connection, string commandText, - params IDataParameter[] commandParameters) - { - // this way we control the connection, and therefore the connection string that gets saved as a hask key - connection.Open(); - AdoHelperParameterCache.CacheParameterSet(connection.ConnectionString, commandText, commandParameters); - connection.Close(); - } - - /// - /// Resolve at run time the appropriate set of IDataParameters for a stored procedure - /// - /// A valid IDbConnection object - /// The name of the stored procedure - /// Whether or not to include their return value parameter - /// The parameter array discovered. - /// Thrown if spName is null - /// Thrown if connection is null - private IDataParameter[] DiscoverSpParameterSet(IDbConnection connection, string spName, - bool includeReturnValueParameter) - { - if (connection == null) throw new ArgumentNullException(nameof(connection)); - if (string.IsNullOrEmpty(spName)) throw new ArgumentNullException(nameof(spName)); - - var cmd = connection.CreateCommand(); - cmd.CommandText = spName; - cmd.CommandType = CommandType.StoredProcedure; - - connection.Open(); - DeriveParameters(cmd); - connection.Close(); - - if (!includeReturnValueParameter) - { - // not all providers have return value parameters...don't just remove this parameter indiscriminately - if (cmd.Parameters.Count > 0 && - ((IDataParameter) cmd.Parameters[0]).Direction == ParameterDirection.ReturnValue) - { - cmd.Parameters.RemoveAt(0); - } - } - - var discoveredParameters = new IDataParameter[cmd.Parameters.Count]; - - cmd.Parameters.CopyTo(discoveredParameters, 0); - - // Init the parameters with a DBNull value - foreach (var discoveredParameter in discoveredParameters) - { - discoveredParameter.Value = DBNull.Value; - } - return discoveredParameters; - } - - #endregion Parameter Discovery Functions - - #region Utility Functions - - public string ToTopSqlString(string connectionString, string tableName, string columns, string whereString, string orderString, int startIndex, int count) - { - return DataProvider.DatabaseDao.GetSelectSqlString(connectionString, tableName, startIndex + 1, count, - columns, whereString, orderString); - } - - public string ToTopSqlString(string tableName, string columns, string whereString, string orderString, int count) - { - return SqlUtils.ToTopSqlString(tableName, columns, whereString, orderString, count); - } - - public string ToPlusSqlString(string fieldName, int plusNum) - { - return SqlUtils.ToPlusSqlString(fieldName, plusNum); - } - - public string ToMinusSqlString(string fieldName, int minusNum) - { - return SqlUtils.ToMinusSqlString(fieldName, minusNum); - } - - public string ToNowSqlString() - { - return SqlUtils.GetComparableNow(); - } - - public string ToDateSqlString(DateTime date) - { - return SqlUtils.GetComparableDate(date); - } - - public string ToDateTimeSqlString(DateTime dateTime) - { - return SqlUtils.GetComparableDate(dateTime); - } - - public string Encrypt(string inputString) - { - return TranslateUtils.EncryptStringBySecretKey(inputString); - } - - public string Decrypt(string inputString) - { - return TranslateUtils.DecryptStringBySecretKey(inputString); - } - - public string FilterXss(string html) - { - return PageUtils.FilterXss(html); - } - - public string FilterSql(string sql) - { - return PageUtils.FilterSql(sql); - } - - #endregion Utility Functions - - } - - #region ParameterCache - /// - /// ADOHelperParameterCache provides functions to leverage a static cache of procedure parameters, and the - /// ability to discover parameters for stored procedures at run-time. - /// - public sealed class AdoHelperParameterCache - { - private static Hashtable paramCache = Hashtable.Synchronized(new Hashtable()); - - /// - /// Deep copy of cached IDataParameter array - /// - /// - /// - internal static IDataParameter[] CloneParameters(IDataParameter[] originalParameters) - { - var clonedParameters = new IDataParameter[originalParameters.Length]; - - for (int i = 0, j = originalParameters.Length; i < j; i++) - { - clonedParameters[i] = (IDataParameter)((ICloneable)originalParameters[i]).Clone(); - } - - return clonedParameters; - } - -#region caching functions - - /// - /// Add parameter array to the cache - /// - /// A valid connection string for an IDbConnection - /// SQL command - /// An array of IDataParameters to be cached - /// Thrown if commandText is null - /// Thrown if connectionString is null - internal static void CacheParameterSet(string connectionString, string commandText, params IDataParameter[] commandParameters) - { - if( string.IsNullOrEmpty(connectionString) ) throw new ArgumentNullException( nameof(connectionString) ); - if( string.IsNullOrEmpty(commandText) ) throw new ArgumentNullException( nameof(commandText) ); - - var hashKey = connectionString + ":" + commandText; - - paramCache[hashKey] = commandParameters; - } - - /// - /// Retrieve a parameter array from the cache - /// - /// A valid connection string for an IDbConnection - /// SQL command - /// An array of IDataParameters - /// Thrown if commandText is null - /// Thrown if connectionString is null - internal static IDataParameter[] GetCachedParameterSet(string connectionString, string commandText) - { - if( string.IsNullOrEmpty(connectionString) ) throw new ArgumentNullException( nameof(connectionString) ); - if( string.IsNullOrEmpty(commandText) ) throw new ArgumentNullException( nameof(commandText) ); - - var hashKey = connectionString + ":" + commandText; - - var cachedParameters = paramCache[hashKey] as IDataParameter[]; - if (cachedParameters == null) - { - return null; - } - else - { - return CloneParameters(cachedParameters); - } - } - -#endregion caching functions - } -#endregion -} diff --git a/SiteServer.CMS/Data/MySql.cs b/SiteServer.CMS/Data/MySql.cs deleted file mode 100644 index ad0e0335d..000000000 --- a/SiteServer.CMS/Data/MySql.cs +++ /dev/null @@ -1,287 +0,0 @@ -using System; -using System.Data; -using System.IO; -using System.Xml; -using MySql.Data.MySqlClient; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Data -{ - public class MySql : DbHelper, IDataApi - { - #region Overrides - /// - /// Returns an array of SqlParameters of the specified size - /// - /// size of the array - /// The array of SqlParameters - protected override IDataParameter[] GetDataParameters(int size) - { - return new MySqlParameter[size]; - } - - - /// - /// Returns a SqlConnection object for the given connection string - /// - /// The connection string to be used to create the connection - /// A SqlConnection object - public override IDbConnection GetConnection(string connectionString) - { - return new MySqlConnection(connectionString); - } - - public IDbCommand GetCommand() - { - return new MySqlCommand(); - } - - - /// - /// Returns a SqlDataAdapter object - /// - /// The SqlDataAdapter - public override IDbDataAdapter GetDataAdapter() - { - return new MySqlDataAdapter(); - } - - - /// - /// Calls the CommandBuilder.DeriveParameters method for the specified provider, doing any setup and cleanup necessary - /// - /// The IDbCommand referencing the stored procedure from which the parameter information is to be derived. The derived parameters are added to the Parameters collection of the IDbCommand. - public override void DeriveParameters(IDbCommand cmd) - { - bool mustCloseConnection = false; - - - if (!(cmd is MySqlCommand)) - throw new ArgumentException("The command provided is not a SqlCommand instance.", "cmd"); - - - if (cmd.Connection.State != ConnectionState.Open) - { - cmd.Connection.Open(); - mustCloseConnection = true; - } - - - MySqlCommandBuilder.DeriveParameters((MySqlCommand)cmd); - - - if (mustCloseConnection) - { - cmd.Connection.Close(); - } - } - - - /// - /// Returns a SqlParameter object - /// - /// The SqlParameter object - public override IDataParameter GetParameter() - { - return new MySqlParameter(); - } - - - /// - /// Detach the IDataParameters from the command object, so they can be used again. - /// - /// command object to clear - protected override void ClearCommand(IDbCommand command) - { - // HACK: There is a problem here, the output parameter values are fletched - // when the reader is closed, so if the parameters are detached from the command - // then the IDataReader can磘 set its values. - // When this happen, the parameters can磘 be used again in other command. - bool canClear = true; - - - foreach (IDataParameter commandParameter in command.Parameters) - { - if (commandParameter.Direction != ParameterDirection.Input) - canClear = false; - - - } - if (canClear) - { - command.Parameters.Clear(); - } - } - - - /// - /// This cleans up the parameter syntax for an SQL Server call. This was split out from PrepareCommand so that it could be called independently. - /// - /// An IDbCommand object containing the CommandText to clean. - public override void CleanParameterSyntax(IDbCommand command) - { - // do nothing for SQL - } - - - /// - /// Execute a SqlCommand (that returns a resultset) against the provided SqlConnection. - /// - /// - /// - /// XmlReader r = helper.ExecuteXmlReader(command); - /// - /// The IDbCommand to execute - /// An XmlReader containing the resultset generated by the command - public override XmlReader ExecuteXmlReader(IDbCommand command) - { - bool mustCloseConnection = false; - - - if (command.Connection.State != ConnectionState.Open) - { - command.Connection.Open(); - mustCloseConnection = true; - } - - - CleanParameterSyntax(command); - MySqlDataAdapter da = new MySqlDataAdapter((MySqlCommand)command); - DataSet ds = new DataSet(); - - - da.MissingSchemaAction = MissingSchemaAction.AddWithKey; - da.Fill(ds); - - - StringReader stream = new StringReader(ds.GetXml()); - if (mustCloseConnection) - { - command.Connection.Close(); - } - - - return new XmlTextReader(stream); - } - - - /// - /// Provider specific code to set up the updating/ed event handlers used by UpdateDataset - /// - /// DataAdapter to attach the event handlers to - /// The handler to be called when a row is updating - /// The handler to be called when a row is updated - protected override void AddUpdateEventHandlers(IDbDataAdapter dataAdapter, RowUpdatingHandler rowUpdatingHandler, RowUpdatedHandler rowUpdatedHandler) - { - if (rowUpdatingHandler != null) - { - MRowUpdating = rowUpdatingHandler; - ((MySqlDataAdapter)dataAdapter).RowUpdating += RowUpdating; - } - - - if (rowUpdatedHandler != null) - { - MRowUpdated = rowUpdatedHandler; - ((MySqlDataAdapter)dataAdapter).RowUpdated += RowUpdated; - } - } - - - /// - /// Handles the RowUpdating event - /// - /// The object that published the event - /// The SqlRowUpdatingEventArgs - protected void RowUpdating(object obj, MySqlRowUpdatingEventArgs e) - { - base.RowUpdating(obj, e); - } - - - /// - /// Handles the RowUpdated event - /// - /// The object that published the event - /// The SqlRowUpdatedEventArgs - protected void RowUpdated(object obj, MySqlRowUpdatedEventArgs e) - { - base.RowUpdated(obj, e); - } - - - /// - /// Handle any provider-specific issues with BLOBs here by "washing" the IDataParameter and returning a new one that is set up appropriately for the provider. - /// - /// The IDbConnection to use in cleansing the parameter - /// The parameter before cleansing - /// The parameter after it's been cleansed. - protected override IDataParameter GetBlobParameter(IDbConnection connection, IDataParameter p) - { - // do nothing special for BLOBs...as far as we know now. - return p; - } - - #endregion - - public string GetString(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return string.Empty; - return rdr.IsDBNull(i) ? string.Empty : rdr.GetString(i); - } - - public bool GetBoolean(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return false; - return !rdr.IsDBNull(i) && rdr.GetBoolean(i); - } - - public int GetInt(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return 0; - return rdr.IsDBNull(i) ? 0 : rdr.GetInt32(i); - } - - public decimal GetDecimal(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return 0; - return rdr.IsDBNull(i) ? 0 : rdr.GetDecimal(i); - } - - public DateTime GetDateTime(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return DateTime.MinValue; - return rdr.IsDBNull(i) ? DateTime.MinValue : rdr.GetDateTime(i); - } - - public string GetString(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetString(rdr, i); - } - - public bool GetBoolean(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetBoolean(rdr, i); - } - - public int GetInt(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetInt(rdr, i); - } - - public decimal GetDecimal(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetDecimal(rdr, i); - } - - public DateTime GetDateTime(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetDateTime(rdr, i); - } - } -} diff --git a/SiteServer.CMS/Data/Oracle.cs b/SiteServer.CMS/Data/Oracle.cs deleted file mode 100644 index 09c6a3d6b..000000000 --- a/SiteServer.CMS/Data/Oracle.cs +++ /dev/null @@ -1,343 +0,0 @@ -using System; -using System.Data; -using System.IO; -using System.Xml; -using Oracle.ManagedDataAccess.Client; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Data -{ - public class Oracle : DbHelper, IDataApi - { - #region Overrides - /// - /// Returns an array of SqlParameters of the specified size - /// - /// size of the array - /// The array of SqlParameters - protected override IDataParameter[] GetDataParameters(int size) - { - return new OracleParameter[size]; - } - - - /// - /// Returns a SqlConnection object for the given connection string - /// - /// The connection string to be used to create the connection - /// A SqlConnection object - public override IDbConnection GetConnection(string connectionString) - { - return new OracleConnection(connectionString); - } - - public IDbCommand GetCommand() - { - return new OracleCommand(); - } - - - /// - /// Returns a SqlDataAdapter object - /// - /// The SqlDataAdapter - public override IDbDataAdapter GetDataAdapter() - { - return new OracleDataAdapter(); - } - - - /// - /// Calls the CommandBuilder.DeriveParameters method for the specified provider, doing any setup and cleanup necessary - /// - /// The IDbCommand referencing the stored procedure from which the parameter information is to be derived. The derived parameters are added to the Parameters collection of the IDbCommand. - public override void DeriveParameters(IDbCommand cmd) - { - bool mustCloseConnection = false; - - - if (!(cmd is OracleCommand)) - throw new ArgumentException("The command provided is not a SqlCommand instance.", "cmd"); - - - if (cmd.Connection.State != ConnectionState.Open) - { - cmd.Connection.Open(); - mustCloseConnection = true; - } - - - OracleCommandBuilder.DeriveParameters((OracleCommand)cmd); - - - if (mustCloseConnection) - { - cmd.Connection.Close(); - } - } - - - /// - /// Returns a SqlParameter object - /// - /// The SqlParameter object - public override IDataParameter GetParameter() - { - return new OracleParameter(); - } - - public override IDataParameter GetParameter(string name, object value) - { - var parameter = new OracleParameter - { - ParameterName = name - }; - if (value == null) - { - parameter.DbType = DbType.String; - parameter.Value = null; - } - else if (value is DateTime) - { - parameter.DbType = DbType.DateTime; - var dbValue = (DateTime) value; - if (dbValue < DateUtils.SqlMinValue) - { - dbValue = DateUtils.SqlMinValue; - } - parameter.Value = dbValue; - } - else if (value is int) - { - parameter.DbType = DbType.Int32; - parameter.Value = (int)value; - } - else if (value is decimal) - { - parameter.DbType = DbType.Decimal; - parameter.Value = (decimal)value; - } - else if (value is string) - { - parameter.DbType = DbType.String; - parameter.Value = SqlUtils.ToOracleDbValue(DataType.VarChar, value); - //parameter.Value = (string)value; - } - else if (value is bool) - { - parameter.DbType = DbType.Int32; - parameter.Value = (bool) value ? 1 : 0; - } - else - { - parameter.DbType = DbType.String; - parameter.Value = SqlUtils.ToOracleDbValue(DataType.VarChar, value.ToString()); - //parameter.Value = value.ToString(); - } - - return parameter; - } - - /// - /// Detach the IDataParameters from the command object, so they can be used again. - /// - /// command object to clear - protected override void ClearCommand(IDbCommand command) - { - // HACK: There is a problem here, the output parameter values are fletched - // when the reader is closed, so if the parameters are detached from the command - // then the IDataReader can磘 set its values. - // When this happen, the parameters can磘 be used again in other command. - bool canClear = true; - - - foreach (IDataParameter commandParameter in command.Parameters) - { - if (commandParameter.Direction != ParameterDirection.Input) - canClear = false; - - - } - if (canClear) - { - command.Parameters.Clear(); - } - } - - - /// - /// This cleans up the parameter syntax for an SQL Server call. This was split out from PrepareCommand so that it could be called independently. - /// - /// An IDbCommand object containing the CommandText to clean. - public override void CleanParameterSyntax(IDbCommand command) - { - // do nothing for SQL - } - - - /// - /// Execute a SqlCommand (that returns a resultset) against the provided SqlConnection. - /// - /// - /// - /// XmlReader r = helper.ExecuteXmlReader(command); - /// - /// The IDbCommand to execute - /// An XmlReader containing the resultset generated by the command - public override XmlReader ExecuteXmlReader(IDbCommand command) - { - bool mustCloseConnection = false; - - - if (command.Connection.State != ConnectionState.Open) - { - command.Connection.Open(); - mustCloseConnection = true; - } - - - CleanParameterSyntax(command); - OracleDataAdapter da = new OracleDataAdapter((OracleCommand)command); - DataSet ds = new DataSet(); - - - da.MissingSchemaAction = MissingSchemaAction.AddWithKey; - da.Fill(ds); - - - StringReader stream = new StringReader(ds.GetXml()); - if (mustCloseConnection) - { - command.Connection.Close(); - } - - - return new XmlTextReader(stream); - } - - - /// - /// Provider specific code to set up the updating/ed event handlers used by UpdateDataset - /// - /// DataAdapter to attach the event handlers to - /// The handler to be called when a row is updating - /// The handler to be called when a row is updated - protected override void AddUpdateEventHandlers(IDbDataAdapter dataAdapter, RowUpdatingHandler rowUpdatingHandler, RowUpdatedHandler rowUpdatedHandler) - { - if (rowUpdatingHandler != null) - { - this.MRowUpdating = rowUpdatingHandler; - ((OracleDataAdapter)dataAdapter).RowUpdating += new OracleRowUpdatingEventHandler(RowUpdating); - } - - - if (rowUpdatedHandler != null) - { - this.MRowUpdated = rowUpdatedHandler; - ((OracleDataAdapter)dataAdapter).RowUpdated += new OracleRowUpdatedEventHandler(RowUpdated); - } - } - - - /// - /// Handles the RowUpdating event - /// - /// The object that published the event - /// The SqlRowUpdatingEventArgs - protected void RowUpdating(object obj, OracleRowUpdatingEventArgs e) - { - base.RowUpdating(obj, e); - } - - - /// - /// Handles the RowUpdated event - /// - /// The object that published the event - /// The SqlRowUpdatedEventArgs - protected void RowUpdated(object obj, OracleRowUpdatedEventArgs e) - { - base.RowUpdated(obj, e); - } - - - /// - /// Handle any provider-specific issues with BLOBs here by "washing" the IDataParameter and returning a new one that is set up appropriately for the provider. - /// - /// The IDbConnection to use in cleansing the parameter - /// The parameter before cleansing - /// The parameter after it's been cleansed. - protected override IDataParameter GetBlobParameter(IDbConnection connection, IDataParameter p) - { - // do nothing special for BLOBs...as far as we know now. - return p; - } - #endregion - - public string GetString(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return string.Empty; - var retval = rdr.IsDBNull(i) ? string.Empty : rdr.GetString(i); - if (retval == SqlUtils.OracleEmptyValue) - { - retval = string.Empty; - } - return retval; - } - - public bool GetBoolean(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return false; - return GetInt(rdr, i) == 1; - } - - public int GetInt(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return 0; - return rdr.IsDBNull(i) ? 0 : rdr.GetInt32(i); - } - - public decimal GetDecimal(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return 0; - return rdr.IsDBNull(i) ? 0 : rdr.GetDecimal(i); - } - - public DateTime GetDateTime(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return DateTime.MinValue; - return rdr.IsDBNull(i) ? DateTime.MinValue : rdr.GetDateTime(i); - } - - public string GetString(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetString(rdr, i); - } - - public bool GetBoolean(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetBoolean(rdr, i); - } - - public int GetInt(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetInt(rdr, i); - } - - public decimal GetDecimal(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetDecimal(rdr, i); - } - - public DateTime GetDateTime(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetDateTime(rdr, i); - } - } -} diff --git a/SiteServer.CMS/Data/PostgreSql.cs b/SiteServer.CMS/Data/PostgreSql.cs deleted file mode 100644 index 6c577235a..000000000 --- a/SiteServer.CMS/Data/PostgreSql.cs +++ /dev/null @@ -1,284 +0,0 @@ -using System; -using System.Data; -using System.IO; -using System.Xml; -using Npgsql; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Data -{ - public class PostgreSql : DbHelper, IDataApi - { - /// - /// Returns an array of SqlParameters of the specified size - /// - /// size of the array - /// The array of SqlParameters - protected override IDataParameter[] GetDataParameters(int size) - { - return new NpgsqlParameter[size]; - } - - - /// - /// Returns a SqlConnection object for the given connection string - /// - /// The connection string to be used to create the connection - /// A SqlConnection object - public override IDbConnection GetConnection(string connectionString) - { - return new NpgsqlConnection(connectionString); - } - - public IDbCommand GetCommand() - { - return new NpgsqlCommand(); - } - - - /// - /// Returns a SqlDataAdapter object - /// - /// The SqlDataAdapter - public override IDbDataAdapter GetDataAdapter() - { - return new NpgsqlDataAdapter(); - } - - - /// - /// Calls the CommandBuilder.DeriveParameters method for the specified provider, doing any setup and cleanup necessary - /// - /// The IDbCommand referencing the stored procedure from which the parameter information is to be derived. The derived parameters are added to the Parameters collection of the IDbCommand. - public override void DeriveParameters(IDbCommand cmd) - { - bool mustCloseConnection = false; - - - if (!(cmd is NpgsqlCommand)) - throw new ArgumentException("The command provided is not a SqlCommand instance.", "cmd"); - - - if (cmd.Connection.State != ConnectionState.Open) - { - cmd.Connection.Open(); - mustCloseConnection = true; - } - - - NpgsqlCommandBuilder.DeriveParameters((NpgsqlCommand)cmd); - - - if (mustCloseConnection) - { - cmd.Connection.Close(); - } - } - - - /// - /// Returns a SqlParameter object - /// - /// The SqlParameter object - public override IDataParameter GetParameter() - { - return new NpgsqlParameter(); - } - - - /// - /// Detach the IDataParameters from the command object, so they can be used again. - /// - /// command object to clear - protected override void ClearCommand(IDbCommand command) - { - // HACK: There is a problem here, the output parameter values are fletched - // when the reader is closed, so if the parameters are detached from the command - // then the IDataReader can磘 set its values. - // When this happen, the parameters can磘 be used again in other command. - bool canClear = true; - - - foreach (IDataParameter commandParameter in command.Parameters) - { - if (commandParameter.Direction != ParameterDirection.Input) - canClear = false; - - - } - if (canClear) - { - command.Parameters.Clear(); - } - } - - - /// - /// This cleans up the parameter syntax for an SQL Server call. This was split out from PrepareCommand so that it could be called independently. - /// - /// An IDbCommand object containing the CommandText to clean. - public override void CleanParameterSyntax(IDbCommand command) - { - // do nothing for SQL - } - - - /// - /// Execute a SqlCommand (that returns a resultset) against the provided SqlConnection. - /// - /// - /// - /// XmlReader r = helper.ExecuteXmlReader(command); - /// - /// The IDbCommand to execute - /// An XmlReader containing the resultset generated by the command - public override XmlReader ExecuteXmlReader(IDbCommand command) - { - bool mustCloseConnection = false; - - - if (command.Connection.State != ConnectionState.Open) - { - command.Connection.Open(); - mustCloseConnection = true; - } - - - CleanParameterSyntax(command); - NpgsqlDataAdapter da = new NpgsqlDataAdapter((NpgsqlCommand)command); - DataSet ds = new DataSet(); - - - da.MissingSchemaAction = MissingSchemaAction.AddWithKey; - da.Fill(ds); - - - StringReader stream = new StringReader(ds.GetXml()); - if (mustCloseConnection) - { - command.Connection.Close(); - } - - - return new XmlTextReader(stream); - } - - - /// - /// Provider specific code to set up the updating/ed event handlers used by UpdateDataset - /// - /// DataAdapter to attach the event handlers to - /// The handler to be called when a row is updating - /// The handler to be called when a row is updated - protected override void AddUpdateEventHandlers(IDbDataAdapter dataAdapter, RowUpdatingHandler rowUpdatingHandler, RowUpdatedHandler rowUpdatedHandler) - { - if (rowUpdatingHandler != null) - { - this.MRowUpdating = rowUpdatingHandler; - ((NpgsqlDataAdapter)dataAdapter).RowUpdating += new NpgsqlRowUpdatingEventHandler(RowUpdating); - } - - - if (rowUpdatedHandler != null) - { - this.MRowUpdated = rowUpdatedHandler; - ((NpgsqlDataAdapter)dataAdapter).RowUpdated += new NpgsqlRowUpdatedEventHandler(RowUpdated); - } - } - - - /// - /// Handles the RowUpdating event - /// - /// The object that published the event - /// The SqlRowUpdatingEventArgs - protected void RowUpdating(object obj, NpgsqlRowUpdatingEventArgs e) - { - base.RowUpdating(obj, e); - } - - - /// - /// Handles the RowUpdated event - /// - /// The object that published the event - /// The SqlRowUpdatedEventArgs - protected void RowUpdated(object obj, NpgsqlRowUpdatedEventArgs e) - { - base.RowUpdated(obj, e); - } - - - /// - /// Handle any provider-specific issues with BLOBs here by "washing" the IDataParameter and returning a new one that is set up appropriately for the provider. - /// - /// The IDbConnection to use in cleansing the parameter - /// The parameter before cleansing - /// The parameter after it's been cleansed. - protected override IDataParameter GetBlobParameter(IDbConnection connection, IDataParameter p) - { - // do nothing special for BLOBs...as far as we know now. - return p; - } - - public string GetString(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return string.Empty; - return rdr.IsDBNull(i) ? string.Empty : rdr.GetString(i); - } - - public bool GetBoolean(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return false; - return !rdr.IsDBNull(i) && rdr.GetBoolean(i); - } - - public int GetInt(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return 0; - return rdr.IsDBNull(i) ? 0 : rdr.GetInt32(i); - } - - public decimal GetDecimal(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return 0; - return rdr.IsDBNull(i) ? 0 : rdr.GetDecimal(i); - } - - public DateTime GetDateTime(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return DateTime.MinValue; - return rdr.IsDBNull(i) ? DateTime.MinValue : rdr.GetDateTime(i); - } - - public string GetString(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetString(rdr, i); - } - - public bool GetBoolean(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetBoolean(rdr, i); - } - - public int GetInt(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetInt(rdr, i); - } - - public decimal GetDecimal(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetDecimal(rdr, i); - } - - public DateTime GetDateTime(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetDateTime(rdr, i); - } - } -} diff --git a/SiteServer.CMS/Data/SqlHelper.cs b/SiteServer.CMS/Data/SqlHelper.cs deleted file mode 100644 index 63fd81bae..000000000 --- a/SiteServer.CMS/Data/SqlHelper.cs +++ /dev/null @@ -1,2613 +0,0 @@ -// =============================================================================== -// Microsoft Data Access Application Block for .NET -// http://msdn.microsoft.com/library/en-us/dnbda/html/daab-rm.asp -// -// SQLHelper.cs -// -// This file contains the implementations of the SqlHelper and SqlHelperParameterCache -// classes. -// -// For more information see the Data Access Application Block Implementation Overview. -// =============================================================================== -// Release history -// VERSION DESCRIPTION -// 2.0 Added support for FillDataset, UpdateDataset and "Param" helper methods -// -// =============================================================================== -// Copyright (C) 2000-2001 Microsoft Corporation -// All rights reserved. -// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY -// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT -// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR -// FITNESS FOR A PARTICULAR PURPOSE. -// ============================================================================== - -using System; -using System.Data; -using System.Xml; -using System.Data.SqlClient; -using System.Collections; - -namespace SiteServer.CMS.Data -{ - /// - /// The SqlHelper class is intended to encapsulate high performance, scalable best practices for - /// common uses of SqlClient - /// - public sealed class SqlHelper - { - //Database connection strings - - #region private utility methods & constructors - - // Since this class provides only static methods, make the default constructor private to prevent - // instances from being created with "new SqlHelper()" - private SqlHelper() {} - - /// - /// This method is used to attach array of SqlParameters to a SqlCommand. - /// - /// This method will assign a value of DbNull to any parameter with a direction of - /// InputOutput and a value of null. - /// - /// This behavior will prevent default values from being used, but - /// this will be the less common case than an intended pure output parameter (derived as InputOutput) - /// where the user provided no input value. - /// - /// The command to which the parameters will be added - /// An array of SqlParameters to be added to command - private static void AttachParameters(SqlCommand command, SqlParameter[] commandParameters) - { - if( command == null ) throw new ArgumentNullException( "command" ); - if( commandParameters != null ) - { - foreach (var p in commandParameters) - { - if( p != null ) - { - // Check for derived output value with no value assigned - if ( ( p.Direction == ParameterDirection.InputOutput || - p.Direction == ParameterDirection.Input ) && - (p.Value == null)) - { - p.Value = DBNull.Value; - } - command.Parameters.Add(p); - } - } - } - } - - /// - /// This method assigns dataRow column values to an array of SqlParameters - /// - /// Array of SqlParameters to be assigned values - /// The dataRow used to hold the stored procedure's parameter values - private static void AssignParameterValues(SqlParameter[] commandParameters, DataRow dataRow) - { - if ((commandParameters == null) || (dataRow == null)) - { - // Do nothing if we get no data - return; - } - - var i = 0; - // Set the parameters values - foreach(var commandParameter in commandParameters) - { - // Check the parameter name - if( commandParameter.ParameterName == null || - commandParameter.ParameterName.Length <= 1 ) - throw new Exception( - $"Please provide a valid parameter name on the parameter #{i}, the ParameterName property has the following value: '{commandParameter.ParameterName}'."); - if (dataRow.Table.Columns.IndexOf(commandParameter.ParameterName.Substring(1)) != -1) - commandParameter.Value = dataRow[commandParameter.ParameterName.Substring(1)]; - i++; - } - } - - /// - /// This method assigns an array of values to an array of SqlParameters - /// - /// Array of SqlParameters to be assigned values - /// Array of objects holding the values to be assigned - private static void AssignParameterValues(SqlParameter[] commandParameters, object[] parameterValues) - { - if ((commandParameters == null) || (parameterValues == null)) - { - // Do nothing if we get no data - return; - } - - // We must have the same number of values as we pave parameters to put them in - if (commandParameters.Length != parameterValues.Length) - { - throw new ArgumentException("Parameter count does not match Parameter Value count."); - } - - // Iterate through the SqlParameters, assigning the values from the corresponding position in the - // value array - for (int i = 0, j = commandParameters.Length; i < j; i++) - { - // If the current array value derives from IDbDataParameter, then assign its Value property - if (parameterValues[i] is IDbDataParameter) - { - var paramInstance = (IDbDataParameter)parameterValues[i]; - if( paramInstance.Value == null ) - { - commandParameters[i].Value = DBNull.Value; - } - else - { - commandParameters[i].Value = paramInstance.Value; - } - } - else if (parameterValues[i] == null) - { - commandParameters[i].Value = DBNull.Value; - } - else - { - commandParameters[i].Value = parameterValues[i]; - } - } - } - - /// - /// This method opens (if necessary) and assigns a connection, transaction, command type and parameters - /// to the provided command - /// - /// The SqlCommand to be prepared - /// A valid SqlConnection, on which to execute this command - /// A valid SqlTransaction, or 'null' - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An array of SqlParameters to be associated with the command or 'null' if no parameters are required - /// true if the connection was opened by the method, otherwose is false. - private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, out bool mustCloseConnection ) - { - if( command == null ) throw new ArgumentNullException( "command" ); - if( commandText == null || commandText.Length == 0 ) throw new ArgumentNullException( "commandText" ); - - // If the provided connection is not open, we will open it - if (connection.State != ConnectionState.Open) - { - mustCloseConnection = true; - connection.Open(); - } - else - { - mustCloseConnection = false; - } - - // Associate the connection with the command - command.Connection = connection; - - // Set the command text (stored procedure name or SQL statement) - command.CommandText = commandText; - - // If we were provided a transaction, assign it - if (transaction != null) - { - if( transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - command.Transaction = transaction; - } - - // Set the command type - command.CommandType = commandType; - - // Attach the command parameters if they are provided - if (commandParameters != null) - { - AttachParameters(command, commandParameters); - } - return; - } - - #endregion private utility methods & constructors - - #region ExecuteNonQuery - - /// - /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the database specified in - /// the connection string - /// - /// - /// e.g.: - /// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders"); - /// - /// A valid connection string for a SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An int representing the number of rows affected by the command - public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText) - { - // Pass through the call providing null for the set of SqlParameters - return ExecuteNonQuery(connectionString, commandType, commandText, (SqlParameter[])null); - } - - /// - /// Execute a SqlCommand (that returns no resultset) against the database specified in the connection string - /// using the provided parameters - /// - /// - /// e.g.: - /// int result = ExecuteNonQuery(connString, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24)); - /// - /// A valid connection string for a SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An array of SqlParamters used to execute the command - /// An int representing the number of rows affected by the command - public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - - // Create & open a SqlConnection, and dispose of it after we are done - using (var connection = new SqlConnection(connectionString)) - { - connection.Open(); - - // Call the overload that takes a connection in place of the connection string - return ExecuteNonQuery(connection, commandType, commandText, commandParameters); - } - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the database specified in - /// the connection string using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// int result = ExecuteNonQuery(connString, "PublishOrders", 24, 36); - /// - /// A valid connection string for a SqlConnection - /// The name of the stored prcedure - /// An array of objects to be assigned as the input values of the stored procedure - /// An int representing the number of rows affected by the command - public static int ExecuteNonQuery(string connectionString, string spName, params object[] parameterValues) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If we receive parameter values, we need to figure out where they go - if ((parameterValues != null) && (parameterValues.Length > 0)) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName); - - // Assign the provided values to these parameters based on parameter order - AssignParameterValues(commandParameters, parameterValues); - - // Call the overload that takes an array of SqlParameters - return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - // Backgroundwise we can just call the SP without params - return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the provided SqlConnection. - /// - /// - /// e.g.: - /// int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders"); - /// - /// A valid SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An int representing the number of rows affected by the command - public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText) - { - // Pass through the call providing null for the set of SqlParameters - return ExecuteNonQuery(connection, commandType, commandText, (SqlParameter[])null); - } - - /// - /// Execute a SqlCommand (that returns no resultset) against the specified SqlConnection - /// using the provided parameters. - /// - /// - /// e.g.: - /// int result = ExecuteNonQuery(conn, CommandType.StoredProcedure, "PublishOrders", new SqlParameter("@prodid", 24)); - /// - /// A valid SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An array of SqlParamters used to execute the command - /// An int representing the number of rows affected by the command - public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - - // Create a command and prepare it for execution - var cmd = new SqlCommand(); - var mustCloseConnection = false; - PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection ); - - // Finally, execute the command - var retval = cmd.ExecuteNonQuery(); - - // Detach the SqlParameters from the command object, so they can be used again - cmd.Parameters.Clear(); - if( mustCloseConnection ) - connection.Close(); - return retval; - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified SqlConnection - /// using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// int result = ExecuteNonQuery(conn, "PublishOrders", 24, 36); - /// - /// A valid SqlConnection - /// The name of the stored procedure - /// An array of objects to be assigned as the input values of the stored procedure - /// An int representing the number of rows affected by the command - public static int ExecuteNonQuery(SqlConnection connection, string spName, params object[] parameterValues) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If we receive parameter values, we need to figure out where they go - if ((parameterValues != null) && (parameterValues.Length > 0)) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName); - - // Assign the provided values to these parameters based on parameter order - AssignParameterValues(commandParameters, parameterValues); - - // Call the overload that takes an array of SqlParameters - return ExecuteNonQuery(connection, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - // Backgroundwise we can just call the SP without params - return ExecuteNonQuery(connection, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a SqlCommand (that returns no resultset and takes no parameters) against the provided SqlTransaction. - /// - /// - /// e.g.: - /// int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "PublishOrders"); - /// - /// A valid SqlTransaction - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An int representing the number of rows affected by the command - public static int ExecuteNonQuery(SqlTransaction transaction, CommandType commandType, string commandText) - { - // Pass through the call providing null for the set of SqlParameters - return ExecuteNonQuery(transaction, commandType, commandText, (SqlParameter[])null); - } - - /// - /// Execute a SqlCommand (that returns no resultset) against the specified SqlTransaction - /// using the provided parameters. - /// - /// - /// e.g.: - /// int result = ExecuteNonQuery(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); - /// - /// A valid SqlTransaction - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An array of SqlParamters used to execute the command - /// An int representing the number of rows affected by the command - public static int ExecuteNonQuery(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters) - { - if( transaction == null ) throw new ArgumentNullException( "transaction" ); - if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - - // Create a command and prepare it for execution - var cmd = new SqlCommand(); - var mustCloseConnection = false; - PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection ); - - // Finally, execute the command - var retval = cmd.ExecuteNonQuery(); - - // Detach the SqlParameters from the command object, so they can be used again - cmd.Parameters.Clear(); - return retval; - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified - /// SqlTransaction using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// int result = ExecuteNonQuery(conn, trans, "PublishOrders", 24, 36); - /// - /// A valid SqlTransaction - /// The name of the stored procedure - /// An array of objects to be assigned as the input values of the stored procedure - /// An int representing the number of rows affected by the command - public static int ExecuteNonQuery(SqlTransaction transaction, string spName, params object[] parameterValues) - { - if( transaction == null ) throw new ArgumentNullException( "transaction" ); - if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If we receive parameter values, we need to figure out where they go - if ((parameterValues != null) && (parameterValues.Length > 0)) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName); - - // Assign the provided values to these parameters based on parameter order - AssignParameterValues(commandParameters, parameterValues); - - // Call the overload that takes an array of SqlParameters - return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - // Backgroundwise we can just call the SP without params - return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName); - } - } - - #endregion ExecuteNonQuery - - #region ExecuteDataset - - /// - /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the database specified in - /// the connection string. - /// - /// - /// e.g.: - /// DataSet ds = ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders"); - /// - /// A valid connection string for a SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// A dataset containing the resultset generated by the command - public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText) - { - // Pass through the call providing null for the set of SqlParameters - return ExecuteDataset(connectionString, commandType, commandText, (SqlParameter[])null); - } - - /// - /// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string - /// using the provided parameters. - /// - /// - /// e.g.: - /// DataSet ds = ExecuteDataset(connString, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); - /// - /// A valid connection string for a SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An array of SqlParamters used to execute the command - /// A dataset containing the resultset generated by the command - public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - - // Create & open a SqlConnection, and dispose of it after we are done - using (var connection = new SqlConnection(connectionString)) - { - connection.Open(); - - // Call the overload that takes a connection in place of the connection string - return ExecuteDataset(connection, commandType, commandText, commandParameters); - } - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in - /// the connection string using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// DataSet ds = ExecuteDataset(connString, "GetOrders", 24, 36); - /// - /// A valid connection string for a SqlConnection - /// The name of the stored procedure - /// An array of objects to be assigned as the input values of the stored procedure - /// A dataset containing the resultset generated by the command - public static DataSet ExecuteDataset(string connectionString, string spName, params object[] parameterValues) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If we receive parameter values, we need to figure out where they go - if ((parameterValues != null) && (parameterValues.Length > 0)) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName); - - // Assign the provided values to these parameters based on parameter order - AssignParameterValues(commandParameters, parameterValues); - - // Call the overload that takes an array of SqlParameters - return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - // Backgroundwise we can just call the SP without params - return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. - /// - /// - /// e.g.: - /// DataSet ds = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders"); - /// - /// A valid SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// A dataset containing the resultset generated by the command - public static DataSet ExecuteDataset(SqlConnection connection, CommandType commandType, string commandText) - { - // Pass through the call providing null for the set of SqlParameters - return ExecuteDataset(connection, commandType, commandText, (SqlParameter[])null); - } - - /// - /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection - /// using the provided parameters. - /// - /// - /// e.g.: - /// DataSet ds = ExecuteDataset(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); - /// - /// A valid SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An array of SqlParamters used to execute the command - /// A dataset containing the resultset generated by the command - public static DataSet ExecuteDataset(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - - // Create a command and prepare it for execution - var cmd = new SqlCommand(); - var mustCloseConnection = false; - PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection ); - - // Create the DataAdapter & DataSet - using( var da = new SqlDataAdapter(cmd) ) - { - var ds = new DataSet(); - - // Fill the DataSet using default values for DataTable names, etc - da.Fill(ds); - - // Detach the SqlParameters from the command object, so they can be used again - cmd.Parameters.Clear(); - - if( mustCloseConnection ) - connection.Close(); - - // Return the dataset - return ds; - } - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection - /// using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// DataSet ds = ExecuteDataset(conn, "GetOrders", 24, 36); - /// - /// A valid SqlConnection - /// The name of the stored procedure - /// An array of objects to be assigned as the input values of the stored procedure - /// A dataset containing the resultset generated by the command - public static DataSet ExecuteDataset(SqlConnection connection, string spName, params object[] parameterValues) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If we receive parameter values, we need to figure out where they go - if ((parameterValues != null) && (parameterValues.Length > 0)) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName); - - // Assign the provided values to these parameters based on parameter order - AssignParameterValues(commandParameters, parameterValues); - - // Call the overload that takes an array of SqlParameters - return ExecuteDataset(connection, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - // Backgroundwise we can just call the SP without params - return ExecuteDataset(connection, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. - /// - /// - /// e.g.: - /// DataSet ds = ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders"); - /// - /// A valid SqlTransaction - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// A dataset containing the resultset generated by the command - public static DataSet ExecuteDataset(SqlTransaction transaction, CommandType commandType, string commandText) - { - // Pass through the call providing null for the set of SqlParameters - return ExecuteDataset(transaction, commandType, commandText, (SqlParameter[])null); - } - - /// - /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction - /// using the provided parameters. - /// - /// - /// e.g.: - /// DataSet ds = ExecuteDataset(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); - /// - /// A valid SqlTransaction - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An array of SqlParamters used to execute the command - /// A dataset containing the resultset generated by the command - public static DataSet ExecuteDataset(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters) - { - if( transaction == null ) throw new ArgumentNullException( "transaction" ); - if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - - // Create a command and prepare it for execution - var cmd = new SqlCommand(); - var mustCloseConnection = false; - PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection ); - - // Create the DataAdapter & DataSet - using( var da = new SqlDataAdapter(cmd) ) - { - var ds = new DataSet(); - - // Fill the DataSet using default values for DataTable names, etc - da.Fill(ds); - - // Detach the SqlParameters from the command object, so they can be used again - cmd.Parameters.Clear(); - - // Return the dataset - return ds; - } - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified - /// SqlTransaction using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// DataSet ds = ExecuteDataset(trans, "GetOrders", 24, 36); - /// - /// A valid SqlTransaction - /// The name of the stored procedure - /// An array of objects to be assigned as the input values of the stored procedure - /// A dataset containing the resultset generated by the command - public static DataSet ExecuteDataset(SqlTransaction transaction, string spName, params object[] parameterValues) - { - if( transaction == null ) throw new ArgumentNullException( "transaction" ); - if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If we receive parameter values, we need to figure out where they go - if ((parameterValues != null) && (parameterValues.Length > 0)) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName); - - // Assign the provided values to these parameters based on parameter order - AssignParameterValues(commandParameters, parameterValues); - - // Call the overload that takes an array of SqlParameters - return ExecuteDataset(transaction, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - // Backgroundwise we can just call the SP without params - return ExecuteDataset(transaction, CommandType.StoredProcedure, spName); - } - } - - #endregion ExecuteDataset - - #region ExecuteReader - - /// - /// This enum is used to indicate whether the connection was provided by the caller, or created by SqlHelper, so that - /// we can set the appropriate CommandBehavior when calling ExecuteReader() - /// - private enum SqlConnectionOwnership - { - /// Connection is owned and managed by SqlHelper - Internal, - /// Connection is owned and managed by the caller - External - } - - /// - /// Create and prepare a SqlCommand, and call ExecuteReader with the appropriate CommandBehavior. - /// - /// - /// If we created and opened the connection, we want the connection to be closed when the DataReader is closed. - /// - /// If the caller provided the connection, we want to leave it to them to manage. - /// - /// A valid SqlConnection, on which to execute this command - /// A valid SqlTransaction, or 'null' - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An array of SqlParameters to be associated with the command or 'null' if no parameters are required - /// Indicates whether the connection parameter was provided by the caller, or created by SqlHelper - /// SqlDataReader containing the results of the command - private static SqlDataReader ExecuteReader(SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, SqlConnectionOwnership connectionOwnership) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - - var mustCloseConnection = false; - // Create a command and prepare it for execution - var cmd = new SqlCommand(); - try - { - PrepareCommand(cmd, connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection ); - - // Create a reader - SqlDataReader dataReader; - - // Call ExecuteReader with the appropriate CommandBehavior - if (connectionOwnership == SqlConnectionOwnership.External) - { - dataReader = cmd.ExecuteReader(); - } - else - { - dataReader = cmd.ExecuteReader(CommandBehavior.CloseConnection); - } - - // Detach the SqlParameters from the command object, so they can be used again. - // HACK: There is a problem here, the output parameter values are fletched - // when the reader is closed, so if the parameters are detached from the command - // then the SqlReader can磘 set its values. - // When this happen, the parameters can磘 be used again in other command. - var canClear = true; - foreach(SqlParameter commandParameter in cmd.Parameters) - { - if (commandParameter.Direction != ParameterDirection.Input) - canClear = false; - } - - if (canClear) - { - cmd.Parameters.Clear(); - } - - return dataReader; - } - catch - { - if( mustCloseConnection ) - connection.Close(); - throw; - } - } - - /// - /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the database specified in - /// the connection string. - /// - /// - /// e.g.: - /// SqlDataReader dr = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders"); - /// - /// A valid connection string for a SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// A SqlDataReader containing the resultset generated by the command - public static SqlDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText) - { - // Pass through the call providing null for the set of SqlParameters - return ExecuteReader(connectionString, commandType, commandText, (SqlParameter[])null); - } - - /// - /// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string - /// using the provided parameters. - /// - /// - /// e.g.: - /// SqlDataReader dr = ExecuteReader(connString, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); - /// - /// A valid connection string for a SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An array of SqlParamters used to execute the command - /// A SqlDataReader containing the resultset generated by the command - public static SqlDataReader ExecuteReader(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - SqlConnection connection = null; - try - { - connection = new SqlConnection(connectionString); - connection.Open(); - - // Call the private overload that takes an internally owned connection in place of the connection string - return ExecuteReader(connection, null, commandType, commandText, commandParameters,SqlConnectionOwnership.Internal); - } - catch - { - // If we fail to return the SqlDatReader, we need to close the connection ourselves - if( connection != null ) connection.Close(); - throw; - } - - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in - /// the connection string using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// SqlDataReader dr = ExecuteReader(connString, "GetOrders", 24, 36); - /// - /// A valid connection string for a SqlConnection - /// The name of the stored procedure - /// An array of objects to be assigned as the input values of the stored procedure - /// A SqlDataReader containing the resultset generated by the command - public static SqlDataReader ExecuteReader(string connectionString, string spName, params object[] parameterValues) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If we receive parameter values, we need to figure out where they go - if ((parameterValues != null) && (parameterValues.Length > 0)) - { - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName); - - AssignParameterValues(commandParameters, parameterValues); - - return ExecuteReader(connectionString, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - // Backgroundwise we can just call the SP without params - return ExecuteReader(connectionString, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. - /// - /// - /// e.g.: - /// SqlDataReader dr = ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders"); - /// - /// A valid SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// A SqlDataReader containing the resultset generated by the command - public static SqlDataReader ExecuteReader(SqlConnection connection, CommandType commandType, string commandText) - { - // Pass through the call providing null for the set of SqlParameters - return ExecuteReader(connection, commandType, commandText, (SqlParameter[])null); - } - - /// - /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection - /// using the provided parameters. - /// - /// - /// e.g.: - /// SqlDataReader dr = ExecuteReader(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); - /// - /// A valid SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An array of SqlParamters used to execute the command - /// A SqlDataReader containing the resultset generated by the command - public static SqlDataReader ExecuteReader(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters) - { - // Pass through the call to the private overload using a null transaction value and an externally owned connection - return ExecuteReader(connection, (SqlTransaction)null, commandType, commandText, commandParameters, SqlConnectionOwnership.External); - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection - /// using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// SqlDataReader dr = ExecuteReader(conn, "GetOrders", 24, 36); - /// - /// A valid SqlConnection - /// The name of the stored procedure - /// An array of objects to be assigned as the input values of the stored procedure - /// A SqlDataReader containing the resultset generated by the command - public static SqlDataReader ExecuteReader(SqlConnection connection, string spName, params object[] parameterValues) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If we receive parameter values, we need to figure out where they go - if ((parameterValues != null) && (parameterValues.Length > 0)) - { - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName); - - AssignParameterValues(commandParameters, parameterValues); - - return ExecuteReader(connection, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - // Backgroundwise we can just call the SP without params - return ExecuteReader(connection, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. - /// - /// - /// e.g.: - /// SqlDataReader dr = ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders"); - /// - /// A valid SqlTransaction - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// A SqlDataReader containing the resultset generated by the command - public static SqlDataReader ExecuteReader(SqlTransaction transaction, CommandType commandType, string commandText) - { - // Pass through the call providing null for the set of SqlParameters - return ExecuteReader(transaction, commandType, commandText, (SqlParameter[])null); - } - - /// - /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction - /// using the provided parameters. - /// - /// - /// e.g.: - /// SqlDataReader dr = ExecuteReader(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); - /// - /// A valid SqlTransaction - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An array of SqlParamters used to execute the command - /// A SqlDataReader containing the resultset generated by the command - public static SqlDataReader ExecuteReader(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters) - { - if( transaction == null ) throw new ArgumentNullException( "transaction" ); - if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - - // Pass through to private overload, indicating that the connection is owned by the caller - return ExecuteReader(transaction.Connection, transaction, commandType, commandText, commandParameters, SqlConnectionOwnership.External); - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified - /// SqlTransaction using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// SqlDataReader dr = ExecuteReader(trans, "GetOrders", 24, 36); - /// - /// A valid SqlTransaction - /// The name of the stored procedure - /// An array of objects to be assigned as the input values of the stored procedure - /// A SqlDataReader containing the resultset generated by the command - public static SqlDataReader ExecuteReader(SqlTransaction transaction, string spName, params object[] parameterValues) - { - if( transaction == null ) throw new ArgumentNullException( "transaction" ); - if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If we receive parameter values, we need to figure out where they go - if ((parameterValues != null) && (parameterValues.Length > 0)) - { - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName); - - AssignParameterValues(commandParameters, parameterValues); - - return ExecuteReader(transaction, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - // Backgroundwise we can just call the SP without params - return ExecuteReader(transaction, CommandType.StoredProcedure, spName); - } - } - - #endregion ExecuteReader - - #region ExecuteScalar - - /// - /// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the database specified in - /// the connection string. - /// - /// - /// e.g.: - /// int orderCount = (int)ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount"); - /// - /// A valid connection string for a SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An object containing the value in the 1x1 resultset generated by the command - public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText) - { - // Pass through the call providing null for the set of SqlParameters - return ExecuteScalar(connectionString, commandType, commandText, (SqlParameter[])null); - } - - /// - /// Execute a SqlCommand (that returns a 1x1 resultset) against the database specified in the connection string - /// using the provided parameters. - /// - /// - /// e.g.: - /// int orderCount = (int)ExecuteScalar(connString, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24)); - /// - /// A valid connection string for a SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An array of SqlParamters used to execute the command - /// An object containing the value in the 1x1 resultset generated by the command - public static object ExecuteScalar(string connectionString, CommandType commandType, string commandText, params SqlParameter[] commandParameters) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - // Create & open a SqlConnection, and dispose of it after we are done - using (var connection = new SqlConnection(connectionString)) - { - connection.Open(); - - // Call the overload that takes a connection in place of the connection string - return ExecuteScalar(connection, commandType, commandText, commandParameters); - } - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the database specified in - /// the connection string using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// int orderCount = (int)ExecuteScalar(connString, "GetOrderCount", 24, 36); - /// - /// A valid connection string for a SqlConnection - /// The name of the stored procedure - /// An array of objects to be assigned as the input values of the stored procedure - /// An object containing the value in the 1x1 resultset generated by the command - public static object ExecuteScalar(string connectionString, string spName, params object[] parameterValues) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If we receive parameter values, we need to figure out where they go - if ((parameterValues != null) && (parameterValues.Length > 0)) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName); - - // Assign the provided values to these parameters based on parameter order - AssignParameterValues(commandParameters, parameterValues); - - // Call the overload that takes an array of SqlParameters - return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - // Backgroundwise we can just call the SP without params - return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the provided SqlConnection. - /// - /// - /// e.g.: - /// int orderCount = (int)ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount"); - /// - /// A valid SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An object containing the value in the 1x1 resultset generated by the command - public static object ExecuteScalar(SqlConnection connection, CommandType commandType, string commandText) - { - // Pass through the call providing null for the set of SqlParameters - return ExecuteScalar(connection, commandType, commandText, (SqlParameter[])null); - } - - /// - /// Execute a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection - /// using the provided parameters. - /// - /// - /// e.g.: - /// int orderCount = (int)ExecuteScalar(conn, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24)); - /// - /// A valid SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An array of SqlParamters used to execute the command - /// An object containing the value in the 1x1 resultset generated by the command - public static object ExecuteScalar(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - - // Create a command and prepare it for execution - var cmd = new SqlCommand(); - - var mustCloseConnection = false; - PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection ); - - // Execute the command & return the results - var retval = cmd.ExecuteScalar(); - - // Detach the SqlParameters from the command object, so they can be used again - cmd.Parameters.Clear(); - - if( mustCloseConnection ) - connection.Close(); - - return retval; - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection - /// using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// int orderCount = (int)ExecuteScalar(conn, "GetOrderCount", 24, 36); - /// - /// A valid SqlConnection - /// The name of the stored procedure - /// An array of objects to be assigned as the input values of the stored procedure - /// An object containing the value in the 1x1 resultset generated by the command - public static object ExecuteScalar(SqlConnection connection, string spName, params object[] parameterValues) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If we receive parameter values, we need to figure out where they go - if ((parameterValues != null) && (parameterValues.Length > 0)) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName); - - // Assign the provided values to these parameters based on parameter order - AssignParameterValues(commandParameters, parameterValues); - - // Call the overload that takes an array of SqlParameters - return ExecuteScalar(connection, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - // Backgroundwise we can just call the SP without params - return ExecuteScalar(connection, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a SqlCommand (that returns a 1x1 resultset and takes no parameters) against the provided SqlTransaction. - /// - /// - /// e.g.: - /// int orderCount = (int)ExecuteScalar(trans, CommandType.StoredProcedure, "GetOrderCount"); - /// - /// A valid SqlTransaction - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An object containing the value in the 1x1 resultset generated by the command - public static object ExecuteScalar(SqlTransaction transaction, CommandType commandType, string commandText) - { - // Pass through the call providing null for the set of SqlParameters - return ExecuteScalar(transaction, commandType, commandText, (SqlParameter[])null); - } - - /// - /// Execute a SqlCommand (that returns a 1x1 resultset) against the specified SqlTransaction - /// using the provided parameters. - /// - /// - /// e.g.: - /// int orderCount = (int)ExecuteScalar(trans, CommandType.StoredProcedure, "GetOrderCount", new SqlParameter("@prodid", 24)); - /// - /// A valid SqlTransaction - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An array of SqlParamters used to execute the command - /// An object containing the value in the 1x1 resultset generated by the command - public static object ExecuteScalar(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters) - { - if( transaction == null ) throw new ArgumentNullException( "transaction" ); - if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - - // Create a command and prepare it for execution - var cmd = new SqlCommand(); - var mustCloseConnection = false; - PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection ); - - // Execute the command & return the results - var retval = cmd.ExecuteScalar(); - - // Detach the SqlParameters from the command object, so they can be used again - cmd.Parameters.Clear(); - return retval; - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified - /// SqlTransaction using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// int orderCount = (int)ExecuteScalar(trans, "GetOrderCount", 24, 36); - /// - /// A valid SqlTransaction - /// The name of the stored procedure - /// An array of objects to be assigned as the input values of the stored procedure - /// An object containing the value in the 1x1 resultset generated by the command - public static object ExecuteScalar(SqlTransaction transaction, string spName, params object[] parameterValues) - { - if( transaction == null ) throw new ArgumentNullException( "transaction" ); - if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If we receive parameter values, we need to figure out where they go - if ((parameterValues != null) && (parameterValues.Length > 0)) - { - // PPull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName); - - // Assign the provided values to these parameters based on parameter order - AssignParameterValues(commandParameters, parameterValues); - - // Call the overload that takes an array of SqlParameters - return ExecuteScalar(transaction, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - // Backgroundwise we can just call the SP without params - return ExecuteScalar(transaction, CommandType.StoredProcedure, spName); - } - } - - #endregion ExecuteScalar - - #region ExecuteXmlReader - /// - /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. - /// - /// - /// e.g.: - /// XmlReader r = ExecuteXmlReader(conn, CommandType.StoredProcedure, "GetOrders"); - /// - /// A valid SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command using "FOR XML AUTO" - /// An XmlReader containing the resultset generated by the command - public static XmlReader ExecuteXmlReader(SqlConnection connection, CommandType commandType, string commandText) - { - // Pass through the call providing null for the set of SqlParameters - return ExecuteXmlReader(connection, commandType, commandText, (SqlParameter[])null); - } - - /// - /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection - /// using the provided parameters. - /// - /// - /// e.g.: - /// XmlReader r = ExecuteXmlReader(conn, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); - /// - /// A valid SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command using "FOR XML AUTO" - /// An array of SqlParamters used to execute the command - /// An XmlReader containing the resultset generated by the command - public static XmlReader ExecuteXmlReader(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - - var mustCloseConnection = false; - // Create a command and prepare it for execution - var cmd = new SqlCommand(); - try - { - PrepareCommand(cmd, connection, (SqlTransaction)null, commandType, commandText, commandParameters, out mustCloseConnection ); - - // Create the DataAdapter & DataSet - var retval = cmd.ExecuteXmlReader(); - - // Detach the SqlParameters from the command object, so they can be used again - cmd.Parameters.Clear(); - - return retval; - } - catch - { - if( mustCloseConnection ) - connection.Close(); - throw; - } - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection - /// using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// XmlReader r = ExecuteXmlReader(conn, "GetOrders", 24, 36); - /// - /// A valid SqlConnection - /// The name of the stored procedure using "FOR XML AUTO" - /// An array of objects to be assigned as the input values of the stored procedure - /// An XmlReader containing the resultset generated by the command - public static XmlReader ExecuteXmlReader(SqlConnection connection, string spName, params object[] parameterValues) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If we receive parameter values, we need to figure out where they go - if ((parameterValues != null) && (parameterValues.Length > 0)) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName); - - // Assign the provided values to these parameters based on parameter order - AssignParameterValues(commandParameters, parameterValues); - - // Call the overload that takes an array of SqlParameters - return ExecuteXmlReader(connection, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - // Backgroundwise we can just call the SP without params - return ExecuteXmlReader(connection, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. - /// - /// - /// e.g.: - /// XmlReader r = ExecuteXmlReader(trans, CommandType.StoredProcedure, "GetOrders"); - /// - /// A valid SqlTransaction - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command using "FOR XML AUTO" - /// An XmlReader containing the resultset generated by the command - public static XmlReader ExecuteXmlReader(SqlTransaction transaction, CommandType commandType, string commandText) - { - // Pass through the call providing null for the set of SqlParameters - return ExecuteXmlReader(transaction, commandType, commandText, (SqlParameter[])null); - } - - /// - /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction - /// using the provided parameters. - /// - /// - /// e.g.: - /// XmlReader r = ExecuteXmlReader(trans, CommandType.StoredProcedure, "GetOrders", new SqlParameter("@prodid", 24)); - /// - /// A valid SqlTransaction - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command using "FOR XML AUTO" - /// An array of SqlParamters used to execute the command - /// An XmlReader containing the resultset generated by the command - public static XmlReader ExecuteXmlReader(SqlTransaction transaction, CommandType commandType, string commandText, params SqlParameter[] commandParameters) - { - if( transaction == null ) throw new ArgumentNullException( "transaction" ); - if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - - // Create a command and prepare it for execution - var cmd = new SqlCommand(); - var mustCloseConnection = false; - PrepareCommand(cmd, transaction.Connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection ); - - // Create the DataAdapter & DataSet - var retval = cmd.ExecuteXmlReader(); - - // Detach the SqlParameters from the command object, so they can be used again - cmd.Parameters.Clear(); - return retval; - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified - /// SqlTransaction using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// XmlReader r = ExecuteXmlReader(trans, "GetOrders", 24, 36); - /// - /// A valid SqlTransaction - /// The name of the stored procedure - /// An array of objects to be assigned as the input values of the stored procedure - /// A dataset containing the resultset generated by the command - public static XmlReader ExecuteXmlReader(SqlTransaction transaction, string spName, params object[] parameterValues) - { - if( transaction == null ) throw new ArgumentNullException( "transaction" ); - if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If we receive parameter values, we need to figure out where they go - if ((parameterValues != null) && (parameterValues.Length > 0)) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName); - - // Assign the provided values to these parameters based on parameter order - AssignParameterValues(commandParameters, parameterValues); - - // Call the overload that takes an array of SqlParameters - return ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - // Backgroundwise we can just call the SP without params - return ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName); - } - } - - #endregion ExecuteXmlReader - - #region FillDataset - /// - /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the database specified in - /// the connection string. - /// - /// - /// e.g.: - /// FillDataset(connString, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}); - /// - /// A valid connection string for a SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// A dataset wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - public static void FillDataset(string connectionString, CommandType commandType, string commandText, DataSet dataSet, string[] tableNames) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - if( dataSet == null ) throw new ArgumentNullException( "dataSet" ); - - // Create & open a SqlConnection, and dispose of it after we are done - using (var connection = new SqlConnection(connectionString)) - { - connection.Open(); - - // Call the overload that takes a connection in place of the connection string - FillDataset(connection, commandType, commandText, dataSet, tableNames); - } - } - - /// - /// Execute a SqlCommand (that returns a resultset) against the database specified in the connection string - /// using the provided parameters. - /// - /// - /// e.g.: - /// FillDataset(connString, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24)); - /// - /// A valid connection string for a SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// An array of SqlParamters used to execute the command - /// A dataset wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// - public static void FillDataset(string connectionString, CommandType commandType, - string commandText, DataSet dataSet, string[] tableNames, - params SqlParameter[] commandParameters) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - if( dataSet == null ) throw new ArgumentNullException( "dataSet" ); - // Create & open a SqlConnection, and dispose of it after we are done - using (var connection = new SqlConnection(connectionString)) - { - connection.Open(); - - // Call the overload that takes a connection in place of the connection string - FillDataset(connection, commandType, commandText, dataSet, tableNames, commandParameters); - } - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in - /// the connection string using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// FillDataset(connString, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, 24); - /// - /// A valid connection string for a SqlConnection - /// The name of the stored procedure - /// A dataset wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// - /// An array of objects to be assigned as the input values of the stored procedure - public static void FillDataset(string connectionString, string spName, - DataSet dataSet, string[] tableNames, - params object[] parameterValues) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - if( dataSet == null ) throw new ArgumentNullException( "dataSet" ); - // Create & open a SqlConnection, and dispose of it after we are done - using (var connection = new SqlConnection(connectionString)) - { - connection.Open(); - - // Call the overload that takes a connection in place of the connection string - FillDataset (connection, spName, dataSet, tableNames, parameterValues); - } - } - - /// - /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlConnection. - /// - /// - /// e.g.: - /// FillDataset(conn, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}); - /// - /// A valid SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// A dataset wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// - public static void FillDataset(SqlConnection connection, CommandType commandType, - string commandText, DataSet dataSet, string[] tableNames) - { - FillDataset(connection, commandType, commandText, dataSet, tableNames, null); - } - - /// - /// Execute a SqlCommand (that returns a resultset) against the specified SqlConnection - /// using the provided parameters. - /// - /// - /// e.g.: - /// FillDataset(conn, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24)); - /// - /// A valid SqlConnection - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// A dataset wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// - /// An array of SqlParamters used to execute the command - public static void FillDataset(SqlConnection connection, CommandType commandType, - string commandText, DataSet dataSet, string[] tableNames, - params SqlParameter[] commandParameters) - { - FillDataset(connection, null, commandType, commandText, dataSet, tableNames, commandParameters); - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection - /// using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// FillDataset(conn, "GetOrders", ds, new string[] {"orders"}, 24, 36); - /// - /// A valid SqlConnection - /// The name of the stored procedure - /// A dataset wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// - /// An array of objects to be assigned as the input values of the stored procedure - public static void FillDataset(SqlConnection connection, string spName, - DataSet dataSet, string[] tableNames, - params object[] parameterValues) - { - if ( connection == null ) throw new ArgumentNullException( "connection" ); - if (dataSet == null ) throw new ArgumentNullException( "dataSet" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If we receive parameter values, we need to figure out where they go - if ((parameterValues != null) && (parameterValues.Length > 0)) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName); - - // Assign the provided values to these parameters based on parameter order - AssignParameterValues(commandParameters, parameterValues); - - // Call the overload that takes an array of SqlParameters - FillDataset(connection, CommandType.StoredProcedure, spName, dataSet, tableNames, commandParameters); - } - else - { - // Backgroundwise we can just call the SP without params - FillDataset(connection, CommandType.StoredProcedure, spName, dataSet, tableNames); - } - } - - /// - /// Execute a SqlCommand (that returns a resultset and takes no parameters) against the provided SqlTransaction. - /// - /// - /// e.g.: - /// FillDataset(trans, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}); - /// - /// A valid SqlTransaction - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// A dataset wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// - public static void FillDataset(SqlTransaction transaction, CommandType commandType, - string commandText, - DataSet dataSet, string[] tableNames) - { - FillDataset (transaction, commandType, commandText, dataSet, tableNames, null); - } - - /// - /// Execute a SqlCommand (that returns a resultset) against the specified SqlTransaction - /// using the provided parameters. - /// - /// - /// e.g.: - /// FillDataset(trans, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24)); - /// - /// A valid SqlTransaction - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// A dataset wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// - /// An array of SqlParamters used to execute the command - public static void FillDataset(SqlTransaction transaction, CommandType commandType, - string commandText, DataSet dataSet, string[] tableNames, - params SqlParameter[] commandParameters) - { - FillDataset(transaction.Connection, transaction, commandType, commandText, dataSet, tableNames, commandParameters); - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified - /// SqlTransaction using the provided parameter values. This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// - /// This method provides no access to output parameters or the stored procedure's return value parameter. - /// - /// e.g.: - /// FillDataset(trans, "GetOrders", ds, new string[]{"orders"}, 24, 36); - /// - /// A valid SqlTransaction - /// The name of the stored procedure - /// A dataset wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// - /// An array of objects to be assigned as the input values of the stored procedure - public static void FillDataset(SqlTransaction transaction, string spName, - DataSet dataSet, string[] tableNames, - params object[] parameterValues) - { - if( transaction == null ) throw new ArgumentNullException( "transaction" ); - if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - if( dataSet == null ) throw new ArgumentNullException( "dataSet" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If we receive parameter values, we need to figure out where they go - if ((parameterValues != null) && (parameterValues.Length > 0)) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName); - - // Assign the provided values to these parameters based on parameter order - AssignParameterValues(commandParameters, parameterValues); - - // Call the overload that takes an array of SqlParameters - FillDataset(transaction, CommandType.StoredProcedure, spName, dataSet, tableNames, commandParameters); - } - else - { - // Backgroundwise we can just call the SP without params - FillDataset(transaction, CommandType.StoredProcedure, spName, dataSet, tableNames); - } - } - - /// - /// Private helper method that execute a SqlCommand (that returns a resultset) against the specified SqlTransaction and SqlConnection - /// using the provided parameters. - /// - /// - /// e.g.: - /// FillDataset(conn, trans, CommandType.StoredProcedure, "GetOrders", ds, new string[] {"orders"}, new SqlParameter("@prodid", 24)); - /// - /// A valid SqlConnection - /// A valid SqlTransaction - /// The CommandType (stored procedure, text, etc.) - /// The stored procedure name or T-SQL command - /// A dataset wich will contain the resultset generated by the command - /// This array will be used to create table mappings allowing the DataTables to be referenced - /// by a user defined name (probably the actual table name) - /// - /// An array of SqlParamters used to execute the command - private static void FillDataset(SqlConnection connection, SqlTransaction transaction, CommandType commandType, - string commandText, DataSet dataSet, string[] tableNames, - params SqlParameter[] commandParameters) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - if( dataSet == null ) throw new ArgumentNullException( "dataSet" ); - - // Create a command and prepare it for execution - var command = new SqlCommand(); - var mustCloseConnection = false; - PrepareCommand(command, connection, transaction, commandType, commandText, commandParameters, out mustCloseConnection ); - - // Create the DataAdapter & DataSet - using( var dataAdapter = new SqlDataAdapter(command) ) - { - - // Add the table mappings specified by the user - if (tableNames != null && tableNames.Length > 0) - { - var tableName = "Table"; - for (var index=0; index < tableNames.Length; index++) - { - if( tableNames[index] == null || tableNames[index].Length == 0 ) throw new ArgumentException( "The tableNames parameter must contain a list of tables, a value was provided as null or empty string.", "tableNames" ); - dataAdapter.TableMappings.Add(tableName, tableNames[index]); - tableName += (index + 1).ToString(); - } - } - - // Fill the DataSet using default values for DataTable names, etc - dataAdapter.Fill(dataSet); - - // Detach the SqlParameters from the command object, so they can be used again - command.Parameters.Clear(); - } - - if( mustCloseConnection ) - connection.Close(); - } - #endregion - - #region UpdateDataset - /// - /// Executes the respective command for each inserted, updated, or deleted row in the DataSet. - /// - /// - /// e.g.: - /// UpdateDataset(conn, insertCommand, deleteCommand, updateCommand, dataSet, "Order"); - /// - /// A valid transact-SQL statement or stored procedure to insert new records into the data source - /// A valid transact-SQL statement or stored procedure to delete records from the data source - /// A valid transact-SQL statement or stored procedure used to update records in the data source - /// The DataSet used to update the data source - /// The DataTable used to update the data source. - public static void UpdateDataset(SqlCommand insertCommand, SqlCommand deleteCommand, SqlCommand updateCommand, DataSet dataSet, string tableName) - { - if( insertCommand == null ) throw new ArgumentNullException( "insertCommand" ); - if( deleteCommand == null ) throw new ArgumentNullException( "deleteCommand" ); - if( updateCommand == null ) throw new ArgumentNullException( "updateCommand" ); - if( tableName == null || tableName.Length == 0 ) throw new ArgumentNullException( "tableName" ); - - // Create a SqlDataAdapter, and dispose of it after we are done - using (var dataAdapter = new SqlDataAdapter()) - { - // Set the data adapter commands - dataAdapter.UpdateCommand = updateCommand; - dataAdapter.InsertCommand = insertCommand; - dataAdapter.DeleteCommand = deleteCommand; - - // Update the dataset changes in the data source - dataAdapter.Update (dataSet, tableName); - - // Commit all the changes made to the DataSet - dataSet.AcceptChanges(); - } - } - #endregion - - #region CreateCommand - /// - /// Simplify the creation of a Sql command object by allowing - /// a stored procedure and optional parameters to be provided - /// - /// - /// e.g.: - /// SqlCommand command = CreateCommand(conn, "AddCustomer", "CustomerID", "CustomerName"); - /// - /// A valid SqlConnection object - /// The name of the stored procedure - /// An array of string to be assigned as the source columns of the stored procedure parameters - /// A valid SqlCommand object - public static SqlCommand CreateCommand(SqlConnection connection, string spName, params string[] sourceColumns) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // Create a SqlCommand - var cmd = new SqlCommand( spName, connection ); - cmd.CommandType = CommandType.StoredProcedure; - - // If we receive parameter values, we need to figure out where they go - if ((sourceColumns != null) && (sourceColumns.Length > 0)) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName); - - // Assign the provided source columns to these parameters based on parameter order - for (var index=0; index < sourceColumns.Length; index++) - commandParameters[index].SourceColumn = sourceColumns[index]; - - // Attach the discovered parameters to the SqlCommand object - AttachParameters (cmd, commandParameters); - } - - return cmd; - } - #endregion - - #region ExecuteNonQueryTypedParams - /// - /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the database specified in - /// the connection string using the dataRow column values as the stored procedure's parameters values. - /// This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on row values. - /// - /// A valid connection string for a SqlConnection - /// The name of the stored procedure - /// The dataRow used to hold the stored procedure's parameter values. - /// An int representing the number of rows affected by the command - public static int ExecuteNonQueryTypedParams(String connectionString, String spName, DataRow dataRow) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If the row has values, the store procedure parameters must be initialized - if (dataRow != null && dataRow.ItemArray.Length > 0) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName); - - // Set the parameters values - AssignParameterValues(commandParameters, dataRow); - - return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - return ExecuteNonQuery(connectionString, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified SqlConnection - /// using the dataRow column values as the stored procedure's parameters values. - /// This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on row values. - /// - /// A valid SqlConnection object - /// The name of the stored procedure - /// The dataRow used to hold the stored procedure's parameter values. - /// An int representing the number of rows affected by the command - public static int ExecuteNonQueryTypedParams(SqlConnection connection, String spName, DataRow dataRow) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If the row has values, the store procedure parameters must be initialized - if (dataRow != null && dataRow.ItemArray.Length > 0) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName); - - // Set the parameters values - AssignParameterValues(commandParameters, dataRow); - - return ExecuteNonQuery(connection, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - return ExecuteNonQuery(connection, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns no resultset) against the specified - /// SqlTransaction using the dataRow column values as the stored procedure's parameters values. - /// This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on row values. - /// - /// A valid SqlTransaction object - /// The name of the stored procedure - /// The dataRow used to hold the stored procedure's parameter values. - /// An int representing the number of rows affected by the command - public static int ExecuteNonQueryTypedParams(SqlTransaction transaction, String spName, DataRow dataRow) - { - if( transaction == null ) throw new ArgumentNullException( "transaction" ); - if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // Sf the row has values, the store procedure parameters must be initialized - if (dataRow != null && dataRow.ItemArray.Length > 0) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName); - - // Set the parameters values - AssignParameterValues(commandParameters, dataRow); - - return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - return ExecuteNonQuery(transaction, CommandType.StoredProcedure, spName); - } - } - #endregion - - #region ExecuteDatasetTypedParams - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in - /// the connection string using the dataRow column values as the stored procedure's parameters values. - /// This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on row values. - /// - /// A valid connection string for a SqlConnection - /// The name of the stored procedure - /// The dataRow used to hold the stored procedure's parameter values. - /// A dataset containing the resultset generated by the command - public static DataSet ExecuteDatasetTypedParams(string connectionString, String spName, DataRow dataRow) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - //If the row has values, the store procedure parameters must be initialized - if ( dataRow != null && dataRow.ItemArray.Length > 0) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName); - - // Set the parameters values - AssignParameterValues(commandParameters, dataRow); - - return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - return ExecuteDataset(connectionString, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection - /// using the dataRow column values as the store procedure's parameters values. - /// This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on row values. - /// - /// A valid SqlConnection object - /// The name of the stored procedure - /// The dataRow used to hold the stored procedure's parameter values. - /// A dataset containing the resultset generated by the command - public static DataSet ExecuteDatasetTypedParams(SqlConnection connection, String spName, DataRow dataRow) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If the row has values, the store procedure parameters must be initialized - if( dataRow != null && dataRow.ItemArray.Length > 0) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName); - - // Set the parameters values - AssignParameterValues(commandParameters, dataRow); - - return ExecuteDataset(connection, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - return ExecuteDataset(connection, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlTransaction - /// using the dataRow column values as the stored procedure's parameters values. - /// This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on row values. - /// - /// A valid SqlTransaction object - /// The name of the stored procedure - /// The dataRow used to hold the stored procedure's parameter values. - /// A dataset containing the resultset generated by the command - public static DataSet ExecuteDatasetTypedParams(SqlTransaction transaction, String spName, DataRow dataRow) - { - if( transaction == null ) throw new ArgumentNullException( "transaction" ); - if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If the row has values, the store procedure parameters must be initialized - if( dataRow != null && dataRow.ItemArray.Length > 0) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName); - - // Set the parameters values - AssignParameterValues(commandParameters, dataRow); - - return ExecuteDataset(transaction, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - return ExecuteDataset(transaction, CommandType.StoredProcedure, spName); - } - } - - #endregion - - #region ExecuteReaderTypedParams - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the database specified in - /// the connection string using the dataRow column values as the stored procedure's parameters values. - /// This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// A valid connection string for a SqlConnection - /// The name of the stored procedure - /// The dataRow used to hold the stored procedure's parameter values. - /// A SqlDataReader containing the resultset generated by the command - public static SqlDataReader ExecuteReaderTypedParams(String connectionString, String spName, DataRow dataRow) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If the row has values, the store procedure parameters must be initialized - if ( dataRow != null && dataRow.ItemArray.Length > 0 ) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName); - - // Set the parameters values - AssignParameterValues(commandParameters, dataRow); - - return ExecuteReader(connectionString, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - return ExecuteReader(connectionString, CommandType.StoredProcedure, spName); - } - } - - - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection - /// using the dataRow column values as the stored procedure's parameters values. - /// This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// A valid SqlConnection object - /// The name of the stored procedure - /// The dataRow used to hold the stored procedure's parameter values. - /// A SqlDataReader containing the resultset generated by the command - public static SqlDataReader ExecuteReaderTypedParams(SqlConnection connection, String spName, DataRow dataRow) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If the row has values, the store procedure parameters must be initialized - if( dataRow != null && dataRow.ItemArray.Length > 0) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName); - - // Set the parameters values - AssignParameterValues(commandParameters, dataRow); - - return ExecuteReader(connection, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - return ExecuteReader(connection, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlTransaction - /// using the dataRow column values as the stored procedure's parameters values. - /// This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// A valid SqlTransaction object - /// The name of the stored procedure - /// The dataRow used to hold the stored procedure's parameter values. - /// A SqlDataReader containing the resultset generated by the command - public static SqlDataReader ExecuteReaderTypedParams(SqlTransaction transaction, String spName, DataRow dataRow) - { - if( transaction == null ) throw new ArgumentNullException( "transaction" ); - if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If the row has values, the store procedure parameters must be initialized - if( dataRow != null && dataRow.ItemArray.Length > 0 ) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName); - - // Set the parameters values - AssignParameterValues(commandParameters, dataRow); - - return ExecuteReader(transaction, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - return ExecuteReader(transaction, CommandType.StoredProcedure, spName); - } - } - #endregion - - #region ExecuteScalarTypedParams - /// - /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the database specified in - /// the connection string using the dataRow column values as the stored procedure's parameters values. - /// This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// A valid connection string for a SqlConnection - /// The name of the stored procedure - /// The dataRow used to hold the stored procedure's parameter values. - /// An object containing the value in the 1x1 resultset generated by the command - public static object ExecuteScalarTypedParams(String connectionString, String spName, DataRow dataRow) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If the row has values, the store procedure parameters must be initialized - if( dataRow != null && dataRow.ItemArray.Length > 0) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connectionString, spName); - - // Set the parameters values - AssignParameterValues(commandParameters, dataRow); - - return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - return ExecuteScalar(connectionString, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified SqlConnection - /// using the dataRow column values as the stored procedure's parameters values. - /// This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// A valid SqlConnection object - /// The name of the stored procedure - /// The dataRow used to hold the stored procedure's parameter values. - /// An object containing the value in the 1x1 resultset generated by the command - public static object ExecuteScalarTypedParams(SqlConnection connection, String spName, DataRow dataRow) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If the row has values, the store procedure parameters must be initialized - if( dataRow != null && dataRow.ItemArray.Length > 0) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName); - - // Set the parameters values - AssignParameterValues(commandParameters, dataRow); - - return ExecuteScalar(connection, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - return ExecuteScalar(connection, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a 1x1 resultset) against the specified SqlTransaction - /// using the dataRow column values as the stored procedure's parameters values. - /// This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// A valid SqlTransaction object - /// The name of the stored procedure - /// The dataRow used to hold the stored procedure's parameter values. - /// An object containing the value in the 1x1 resultset generated by the command - public static object ExecuteScalarTypedParams(SqlTransaction transaction, String spName, DataRow dataRow) - { - if( transaction == null ) throw new ArgumentNullException( "transaction" ); - if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If the row has values, the store procedure parameters must be initialized - if( dataRow != null && dataRow.ItemArray.Length > 0) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName); - - // Set the parameters values - AssignParameterValues(commandParameters, dataRow); - - return ExecuteScalar(transaction, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - return ExecuteScalar(transaction, CommandType.StoredProcedure, spName); - } - } - #endregion - - #region ExecuteXmlReaderTypedParams - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlConnection - /// using the dataRow column values as the stored procedure's parameters values. - /// This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// A valid SqlConnection object - /// The name of the stored procedure - /// The dataRow used to hold the stored procedure's parameter values. - /// An XmlReader containing the resultset generated by the command - public static XmlReader ExecuteXmlReaderTypedParams(SqlConnection connection, String spName, DataRow dataRow) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If the row has values, the store procedure parameters must be initialized - if( dataRow != null && dataRow.ItemArray.Length > 0) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName); - - // Set the parameters values - AssignParameterValues(commandParameters, dataRow); - - return ExecuteXmlReader(connection, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - return ExecuteXmlReader(connection, CommandType.StoredProcedure, spName); - } - } - - /// - /// Execute a stored procedure via a SqlCommand (that returns a resultset) against the specified SqlTransaction - /// using the dataRow column values as the stored procedure's parameters values. - /// This method will query the database to discover the parameters for the - /// stored procedure (the first time each stored procedure is called), and assign the values based on parameter order. - /// - /// A valid SqlTransaction object - /// The name of the stored procedure - /// The dataRow used to hold the stored procedure's parameter values. - /// An XmlReader containing the resultset generated by the command - public static XmlReader ExecuteXmlReaderTypedParams(SqlTransaction transaction, String spName, DataRow dataRow) - { - if( transaction == null ) throw new ArgumentNullException( "transaction" ); - if( transaction != null && transaction.Connection == null ) throw new ArgumentException( "The transaction was rollbacked or commited, please provide an open transaction.", "transaction" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - // If the row has values, the store procedure parameters must be initialized - if( dataRow != null && dataRow.ItemArray.Length > 0) - { - // Pull the parameters for this stored procedure from the parameter cache (or discover them & populate the cache) - var commandParameters = SqlHelperParameterCache.GetSpParameterSet(transaction.Connection, spName); - - // Set the parameters values - AssignParameterValues(commandParameters, dataRow); - - return ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName, commandParameters); - } - else - { - return ExecuteXmlReader(transaction, CommandType.StoredProcedure, spName); - } - } - #endregion - - } - - /// - /// SqlHelperParameterCache provides functions to leverage a static cache of procedure parameters, and the - /// ability to discover parameters for stored procedures at run-time. - /// - public sealed class SqlHelperParameterCache - { - #region private methods, variables, and constructors - - //Since this class provides only static methods, make the default constructor private to prevent - //instances from being created with "new SqlHelperParameterCache()" - private SqlHelperParameterCache() {} - - private static Hashtable paramCache = Hashtable.Synchronized(new Hashtable()); - - /// - /// Resolve at run time the appropriate set of SqlParameters for a stored procedure - /// - /// A valid SqlConnection object - /// The name of the stored procedure - /// Whether or not to include their return value parameter - /// The parameter array discovered. - private static SqlParameter[] DiscoverSpParameterSet(SqlConnection connection, string spName, bool includeReturnValueParameter) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - var cmd = new SqlCommand(spName, connection); - cmd.CommandType = CommandType.StoredProcedure; - - connection.Open(); - SqlCommandBuilder.DeriveParameters(cmd); - connection.Close(); - - if (!includeReturnValueParameter) - { - cmd.Parameters.RemoveAt(0); - } - - var discoveredParameters = new SqlParameter[cmd.Parameters.Count]; - - cmd.Parameters.CopyTo(discoveredParameters, 0); - - // Init the parameters with a DBNull value - foreach (var discoveredParameter in discoveredParameters) - { - discoveredParameter.Value = DBNull.Value; - } - return discoveredParameters; - } - - /// - /// Deep copy of cached SqlParameter array - /// - /// - /// - private static SqlParameter[] CloneParameters(SqlParameter[] originalParameters) - { - var clonedParameters = new SqlParameter[originalParameters.Length]; - - for (int i = 0, j = originalParameters.Length; i < j; i++) - { - clonedParameters[i] = (SqlParameter)((ICloneable)originalParameters[i]).Clone(); - } - - return clonedParameters; - } - - #endregion private methods, variables, and constructors - - #region caching functions - - /// - /// Add parameter array to the cache - /// - /// A valid connection string for a SqlConnection - /// The stored procedure name or T-SQL command - /// An array of SqlParamters to be cached - public static void CacheParameterSet(string connectionString, string commandText, params SqlParameter[] commandParameters) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - if( commandText == null || commandText.Length == 0 ) throw new ArgumentNullException( "commandText" ); - - var hashKey = connectionString + ":" + commandText; - - paramCache[hashKey] = commandParameters; - } - - /// - /// Retrieve a parameter array from the cache - /// - /// A valid connection string for a SqlConnection - /// The stored procedure name or T-SQL command - /// An array of SqlParamters - public static SqlParameter[] GetCachedParameterSet(string connectionString, string commandText) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - if( commandText == null || commandText.Length == 0 ) throw new ArgumentNullException( "commandText" ); - - var hashKey = connectionString + ":" + commandText; - - var cachedParameters = paramCache[hashKey] as SqlParameter[]; - if (cachedParameters == null) - { - return null; - } - else - { - return CloneParameters(cachedParameters); - } - } - - #endregion caching functions - - #region Parameter Discovery Functions - - /// - /// Retrieves the set of SqlParameters appropriate for the stored procedure - /// - /// - /// This method will query the database for this information, and then store it in a cache for future requests. - /// - /// A valid connection string for a SqlConnection - /// The name of the stored procedure - /// An array of SqlParameters - public static SqlParameter[] GetSpParameterSet(string connectionString, string spName) - { - return GetSpParameterSet(connectionString, spName, false); - } - - /// - /// Retrieves the set of SqlParameters appropriate for the stored procedure - /// - /// - /// This method will query the database for this information, and then store it in a cache for future requests. - /// - /// A valid connection string for a SqlConnection - /// The name of the stored procedure - /// A bool value indicating whether the return value parameter should be included in the results - /// An array of SqlParameters - public static SqlParameter[] GetSpParameterSet(string connectionString, string spName, bool includeReturnValueParameter) - { - if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - using(var connection = new SqlConnection(connectionString)) - { - return GetSpParameterSetInternal(connection, spName, includeReturnValueParameter); - } - } - - /// - /// Retrieves the set of SqlParameters appropriate for the stored procedure - /// - /// - /// This method will query the database for this information, and then store it in a cache for future requests. - /// - /// A valid SqlConnection object - /// The name of the stored procedure - /// An array of SqlParameters - internal static SqlParameter[] GetSpParameterSet(SqlConnection connection, string spName) - { - return GetSpParameterSet(connection, spName, false); - } - - /// - /// Retrieves the set of SqlParameters appropriate for the stored procedure - /// - /// - /// This method will query the database for this information, and then store it in a cache for future requests. - /// - /// A valid SqlConnection object - /// The name of the stored procedure - /// A bool value indicating whether the return value parameter should be included in the results - /// An array of SqlParameters - internal static SqlParameter[] GetSpParameterSet(SqlConnection connection, string spName, bool includeReturnValueParameter) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - using (var clonedConnection = (SqlConnection)((ICloneable)connection).Clone()) - { - return GetSpParameterSetInternal(clonedConnection, spName, includeReturnValueParameter); - } - } - - /// - /// Retrieves the set of SqlParameters appropriate for the stored procedure - /// - /// A valid SqlConnection object - /// The name of the stored procedure - /// A bool value indicating whether the return value parameter should be included in the results - /// An array of SqlParameters - private static SqlParameter[] GetSpParameterSetInternal(SqlConnection connection, string spName, bool includeReturnValueParameter) - { - if( connection == null ) throw new ArgumentNullException( "connection" ); - if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); - - var hashKey = connection.ConnectionString + ":" + spName + (includeReturnValueParameter ? ":include ReturnValue Parameter":""); - - SqlParameter[] cachedParameters; - - cachedParameters = paramCache[hashKey] as SqlParameter[]; - if (cachedParameters == null) - { - var spParameters = DiscoverSpParameterSet(connection, spName, includeReturnValueParameter); - paramCache[hashKey] = spParameters; - cachedParameters = spParameters; - } - - return CloneParameters(cachedParameters); - } - - #endregion Parameter Discovery Functions - - } -} diff --git a/SiteServer.CMS/Data/SqlServer.cs b/SiteServer.CMS/Data/SqlServer.cs deleted file mode 100644 index 984433a7b..000000000 --- a/SiteServer.CMS/Data/SqlServer.cs +++ /dev/null @@ -1,695 +0,0 @@ - -// =============================================================================== -// Microsoft Data Access Application Block for .NET 3.0 -// -// SqlServer.cs -// -// This file contains the implementations of the AdoHelper supporting SqlServer. -// -// For more information see the Documentation. -// =============================================================================== -// Release history -// VERSION DESCRIPTION -// 2.0 Added support for FillDataset, UpdateDataset and "Param" helper methods -// 3.0 New abstract class supporting the same methods using ADO.NET interfaces -// -// =============================================================================== -// Copyright (C) 2000-2001 Microsoft Corporation -// All rights reserved. -// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY -// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT -// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR -// FITNESS FOR A PARTICULAR PURPOSE. -// ============================================================================== - -using System; -using System.Collections; -using System.Data; -using System.Data.SqlClient; -using System.Data.OleDb; -using System.Xml; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Data -{ - /// - /// The SqlServer class is intended to encapsulate high performance, scalable best practices for - /// common uses of the SqlClient ADO.NET provider. It is created using the abstract factory in AdoHelper. - /// - public class SqlServer : DbHelper, IDataApi - { - #region Overrides - /// - /// Returns an array of SqlParameters of the specified size - /// - /// size of the array - /// The array of SqlParameters - protected override IDataParameter[] GetDataParameters(int size) - { - return new SqlParameter[size]; - } - - /// - /// Returns a SqlConnection object for the given connection string - /// - /// The connection string to be used to create the connection - /// A SqlConnection object - public override IDbConnection GetConnection( string connectionString ) - { - return new SqlConnection( connectionString ); - } - - public IDbCommand GetCommand() - { - return new SqlCommand(); - } - - /// - /// Returns a SqlDataAdapter object - /// - /// The SqlDataAdapter - public override IDbDataAdapter GetDataAdapter() - { - return new SqlDataAdapter(); - } - - /// - /// Calls the CommandBuilder.DeriveParameters method for the specified provider, doing any setup and cleanup necessary - /// - /// The IDbCommand referencing the stored procedure from which the parameter information is to be derived. The derived parameters are added to the Parameters collection of the IDbCommand. - public override void DeriveParameters( IDbCommand cmd ) - { - var mustCloseConnection = false; - - if( !( cmd is SqlCommand ) ) - throw new ArgumentException( "The command provided is not a SqlCommand instance.", "cmd" ); - - if (cmd.Connection.State != ConnectionState.Open) - { - cmd.Connection.Open(); - mustCloseConnection = true; - } - - SqlDeriveParameters.DeriveParameters((SqlCommand)cmd ); - - if (mustCloseConnection) - { - cmd.Connection.Close(); - } - } - - /// - /// Returns a SqlParameter object - /// - /// The SqlParameter object - public override IDataParameter GetParameter() - { - return new SqlParameter(); - } - - /// - /// Detach the IDataParameters from the command object, so they can be used again. - /// - /// command object to clear - protected override void ClearCommand( IDbCommand command ) - { - // HACK: There is a problem here, the output parameter values are fletched - // when the reader is closed, so if the parameters are detached from the command - // then the IDataReader can磘 set its values. - // When this happen, the parameters can磘 be used again in other command. - var canClear = true; - - foreach(IDataParameter commandParameter in command.Parameters) - { - if (commandParameter.Direction != ParameterDirection.Input) - canClear = false; - - } - if (canClear) - { - command.Parameters.Clear(); - } - } - - /// - /// This cleans up the parameter syntax for an SQL Server call. This was split out from PrepareCommand so that it could be called independently. - /// - /// An IDbCommand object containing the CommandText to clean. - public override void CleanParameterSyntax(IDbCommand command) - { - // do nothing for SQL - } - - /// - /// Execute a SqlCommand (that returns a resultset) against the provided SqlConnection. - /// - /// - /// - /// XmlReader r = helper.ExecuteXmlReader(command); - /// - /// The IDbCommand to execute - /// An XmlReader containing the resultset generated by the command - public override XmlReader ExecuteXmlReader(IDbCommand command) - { - var mustCloseConnection = false; - - if (command.Connection.State != ConnectionState.Open) - { - command.Connection.Open(); - mustCloseConnection = true; - } - - CleanParameterSyntax(command); - // Create the DataAdapter & DataSet - var retval = ((SqlCommand)command).ExecuteXmlReader(); - - // Detach the SqlParameters from the command object, so they can be used again - // don't do this...screws up output parameters -- cjbreisch - // cmd.Parameters.Clear(); - - if (mustCloseConnection) - { - command.Connection.Close(); - } - - return retval; - } - - /// - /// Provider specific code to set up the updating/ed event handlers used by UpdateDataset - /// - /// DataAdapter to attach the event handlers to - /// The handler to be called when a row is updating - /// The handler to be called when a row is updated - protected override void AddUpdateEventHandlers(IDbDataAdapter dataAdapter, RowUpdatingHandler rowUpdatingHandler, RowUpdatedHandler rowUpdatedHandler) - { - if (rowUpdatingHandler != null) - { - MRowUpdating = rowUpdatingHandler; - ((SqlDataAdapter)dataAdapter).RowUpdating += RowUpdating; - } - - if (rowUpdatedHandler != null) - { - MRowUpdated = rowUpdatedHandler; - ((SqlDataAdapter)dataAdapter).RowUpdated += RowUpdated; - } - } - - /// - /// Handles the RowUpdating event - /// - /// The object that published the event - /// The SqlRowUpdatingEventArgs - protected void RowUpdating(object obj, SqlRowUpdatingEventArgs e) - { - base.RowUpdating(obj, e); - } - - /// - /// Handles the RowUpdated event - /// - /// The object that published the event - /// The SqlRowUpdatedEventArgs - protected void RowUpdated(object obj, SqlRowUpdatedEventArgs e) - { - base.RowUpdated(obj, e); - } - - /// - /// Handle any provider-specific issues with BLOBs here by "washing" the IDataParameter and returning a new one that is set up appropriately for the provider. - /// - /// The IDbConnection to use in cleansing the parameter - /// The parameter before cleansing - /// The parameter after it's been cleansed. - protected override IDataParameter GetBlobParameter(IDbConnection connection, IDataParameter p) - { - // do nothing special for BLOBs...as far as we know now. - return p; - } - #endregion - - public string GetString(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return string.Empty; - return rdr.IsDBNull(i) ? string.Empty : rdr.GetString(i); - } - - public bool GetBoolean(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return false; - return !rdr.IsDBNull(i) && rdr.GetBoolean(i); - } - - public int GetInt(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return 0; - return rdr.IsDBNull(i) ? 0 : rdr.GetInt32(i); - } - - public decimal GetDecimal(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return 0; - return rdr.IsDBNull(i) ? 0 : rdr.GetDecimal(i); - } - - public DateTime GetDateTime(IDataReader rdr, int i) - { - if (i < 0 || i >= rdr.FieldCount) return DateTime.MinValue; - return rdr.IsDBNull(i) ? DateTime.MinValue : rdr.GetDateTime(i); - } - - public string GetString(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetString(rdr, i); - } - - public bool GetBoolean(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetBoolean(rdr, i); - } - - public int GetInt(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetInt(rdr, i); - } - - public decimal GetDecimal(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetDecimal(rdr, i); - } - - public DateTime GetDateTime(IDataReader rdr, string name) - { - var i = rdr.GetOrdinal(name); - return GetDateTime(rdr, i); - } - } - -#region Derive Parameters -// We create our own class to do this because the existing ADO.NET 1.1 implementation is broken. - internal class SqlDeriveParameters - { - internal static void DeriveParameters(SqlCommand cmd) - { - string cmdText; - SqlCommand newCommand; - SqlDataReader reader; - ArrayList parameterList; - SqlParameter sqlParam; - CommandType cmdType; - string procedureSchema; - string procedureName; - int groupNumber; - var trnSql = cmd.Transaction; - - cmdType = cmd.CommandType; - - if ((cmdType == CommandType.Text) ) - { - throw new InvalidOperationException(); - } - else if ((cmdType == CommandType.TableDirect) ) - { - throw new InvalidOperationException(); - } - else if ((cmdType != CommandType.StoredProcedure) ) - { - throw new InvalidOperationException(); - } - - procedureName = cmd.CommandText; - string server = null; - string database = null; - procedureSchema = null; - - // split out the procedure name to get the server, database, etc. - GetProcedureTokens(ref procedureName, ref server, ref database, ref procedureSchema); - - // look for group numbers - groupNumber = ParseGroupNumber(ref procedureName); - - newCommand = null; - - // set up the command string. We use sp_procuedure_params_rowset to get the parameters - if (database != null) - { - cmdText = string.Concat("[", database, "]..sp_procedure_params_rowset"); - if (server != null ) - { - cmdText = string.Concat(server, ".", cmdText); - } - - // be careful of transactions - if (trnSql != null ) - { - newCommand = new SqlCommand(cmdText, cmd.Connection, trnSql); - } - else - { - newCommand = new SqlCommand(cmdText, cmd.Connection); - } - } - else - { - // be careful of transactions - if (trnSql != null ) - { - newCommand = new SqlCommand("sp_procedure_params_rowset", cmd.Connection, trnSql); - } - else - { - newCommand = new SqlCommand("sp_procedure_params_rowset", cmd.Connection); - } - } - - newCommand.CommandType = CommandType.StoredProcedure; - newCommand.Parameters.Add(new SqlParameter("@procedure_name", SqlDbType.NVarChar, 255)); - newCommand.Parameters[0].Value = procedureName; - - // make sure we specify - if (! IsEmptyString(procedureSchema) ) - { - newCommand.Parameters.Add(new SqlParameter("@procedure_schema", SqlDbType.NVarChar, 255)); - newCommand.Parameters[1].Value = procedureSchema; - } - - // make sure we specify the groupNumber if we were given one - if ( groupNumber != 0 ) - { - newCommand.Parameters.Add(new SqlParameter("@group_number", groupNumber)); - } - - reader = null; - parameterList = new ArrayList(); - - try - { - // get a reader full of our params - reader = newCommand.ExecuteReader(); - sqlParam = null; - - while ( reader.Read()) - { - // get all the parameter properties that we can get, Name, type, length, direction, precision - sqlParam = new SqlParameter(); - sqlParam.ParameterName = (string)(reader["PARAMETER_NAME"]); - sqlParam.SqlDbType = GetSqlDbType((short)(reader["DATA_TYPE"]), (string)(reader["TYPE_NAME"])); - - if (reader["CHARACTER_MAXIMUM_LENGTH"] != DBNull.Value ) - { - sqlParam.Size = (int)(reader["CHARACTER_MAXIMUM_LENGTH"]); - } - - sqlParam.Direction = GetParameterDirection((short)(reader["PARAMETER_TYPE"])); - - if ((sqlParam.SqlDbType == SqlDbType.Decimal) ) - { - sqlParam.Scale = (byte)(((short)(reader["NUMERIC_SCALE"]) & 255)); - sqlParam.Precision = (byte)(((short)(reader["NUMERIC_PRECISION"]) & 255)); - } - parameterList.Add(sqlParam); - } - } - finally - { - // close our reader and connection when we're done - if (reader != null) - { - reader.Close(); - } - newCommand.Connection = null; - } - - // we didn't get any parameters - if ((parameterList.Count == 0) ) - { - throw new InvalidOperationException(); - } - - cmd.Parameters.Clear(); - - // add the parameters to the command object - - foreach ( var parameter in parameterList ) - { - cmd.Parameters.Add(parameter); - } - } - - /// - /// Checks to see if the stored procedure being called is part of a group, then gets the group number if necessary - /// - /// Stored procedure being called. This method may change this parameter by removing the group number if it exists. - /// the group number - private static int ParseGroupNumber(ref string procedure) - { - string newProcName; - var groupPos = procedure.IndexOf(';'); - var groupIndex = 0; - - if ( groupPos > 0 ) - { - newProcName = procedure.Substring(0, groupPos); - try - { - groupIndex = int.Parse(procedure.Substring(groupPos + 1)); - } - catch - { - throw new InvalidOperationException(); - } - } - else - { - newProcName = procedure; - groupIndex = 0; - } - - procedure = newProcName; - return groupIndex; - } - - /// - /// Tokenize the procedure string - /// - /// The procedure name - /// The server name - /// The database name - /// The owner name - private static void GetProcedureTokens( ref string procedure, ref string server, ref string database, ref string owner) - { - string [] spNameTokens; - int arrIndex; - int nextPos; - int currPos; - int tokenCount; - - server = null; - database = null; - owner = null; - - spNameTokens = new string [4]; - - if ( ! IsEmptyString(procedure) ) - { - arrIndex = 0; - nextPos = 0; - currPos = 0; - - while ((arrIndex < 4)) - { - currPos = procedure.IndexOf('.', nextPos); - if ((-1 == currPos) ) - { - spNameTokens[arrIndex] = procedure.Substring(nextPos); - break; - } - spNameTokens[arrIndex] = procedure.Substring(nextPos, (currPos - nextPos)); - nextPos = (currPos + 1); - if ((procedure.Length <= nextPos) ) - { - break; - } - arrIndex = (arrIndex + 1); - } - - tokenCount = arrIndex + 1; - - // based on how many '.' we found, we know what tokens we found - switch (tokenCount) - { - case 1: - procedure = spNameTokens[0]; - break; - case 2: - procedure = spNameTokens[1]; - owner = spNameTokens[0]; - break; - case 3: - procedure = spNameTokens[2]; - owner = spNameTokens[1]; - database = spNameTokens[0]; - break; - case 4: - procedure = spNameTokens[3]; - owner = spNameTokens[2]; - database = spNameTokens[1]; - server = spNameTokens[0]; - break; - } - } - } - - /// - /// Checks for an empty string - /// - /// String to check - /// boolean value indicating whether string is empty - private static bool IsEmptyString( string str) - { - if (str != null ) - { - return (0 == str.Length); - } - return true; - } - - /// - /// Convert OleDbType to SQlDbType - /// - /// The OleDbType to convert - /// The typeName to convert for items such as Money and SmallMoney which both map to OleDbType.Currency - /// The converted SqlDbType - private static SqlDbType GetSqlDbType( short paramType, string typeName) - { - SqlDbType cmdType; - OleDbType oleDbType; - cmdType = SqlDbType.Variant; - oleDbType = (OleDbType)(paramType); - - switch (oleDbType) - { - case OleDbType.SmallInt: - cmdType = SqlDbType.SmallInt; - break; - case OleDbType.Integer: - cmdType = SqlDbType.Int; - break; - case OleDbType.Single: - cmdType = SqlDbType.Real; - break; - case OleDbType.Double: - cmdType = SqlDbType.Float; - break; - case OleDbType.Currency: - cmdType = (typeName == "money") ? SqlDbType.Money : SqlDbType.SmallMoney; - break; - case OleDbType.Date: - cmdType = (typeName == "datetime") ? SqlDbType.DateTime : SqlDbType.SmallDateTime; - break; - case OleDbType.BSTR: - cmdType = (typeName == "nchar") ? SqlDbType.NChar : SqlDbType.NVarChar; - break; - case OleDbType.Boolean: - cmdType = SqlDbType.Bit; - break; - case OleDbType.Variant: - cmdType = SqlDbType.Variant; - break; - case OleDbType.Decimal: - cmdType = SqlDbType.Decimal; - break; - case OleDbType.TinyInt: - cmdType = SqlDbType.TinyInt; - break; - case OleDbType.UnsignedTinyInt: - cmdType = SqlDbType.TinyInt; - break; - case OleDbType.UnsignedSmallInt: - cmdType = SqlDbType.SmallInt; - break; - case OleDbType.BigInt: - cmdType = SqlDbType.BigInt; - break; - case OleDbType.Filetime: - cmdType = (typeName == "datetime") ? SqlDbType.DateTime : SqlDbType.SmallDateTime; - break; - case OleDbType.Guid: - cmdType = SqlDbType.UniqueIdentifier; - break; - case OleDbType.Binary: - cmdType = (typeName == "binary") ? SqlDbType.Binary : SqlDbType.VarBinary; - break; - case OleDbType.Char: - cmdType = (typeName == "char") ? SqlDbType.Char : SqlDbType.VarChar; - break; - case OleDbType.WChar: - cmdType = (typeName == "nchar") ? SqlDbType.NChar : SqlDbType.NVarChar; - break; - case OleDbType.Numeric: - cmdType = SqlDbType.Decimal; - break; - case OleDbType.DBDate: - cmdType = (typeName == "datetime") ? SqlDbType.DateTime : SqlDbType.SmallDateTime; - break; - case OleDbType.DBTime: - cmdType = (typeName == "datetime") ? SqlDbType.DateTime : SqlDbType.SmallDateTime; - break; - case OleDbType.DBTimeStamp: - cmdType = (typeName == "datetime") ? SqlDbType.DateTime : SqlDbType.SmallDateTime; - break; - case OleDbType.VarChar: - cmdType = (typeName == "char") ? SqlDbType.Char : SqlDbType.VarChar; - break; - case OleDbType.LongVarChar: - cmdType = SqlDbType.Text; - break; - case OleDbType.VarWChar: - cmdType = (typeName == "nchar") ? SqlDbType.NChar : SqlDbType.NVarChar; - break; - case OleDbType.LongVarWChar: - cmdType = SqlDbType.NText; - break; - case OleDbType.VarBinary: - cmdType = (typeName == "binary") ? SqlDbType.Binary : SqlDbType.VarBinary; - break; - case OleDbType.LongVarBinary: - cmdType = SqlDbType.Image; - break; - } - return cmdType; - } - - /// - /// Converts the OleDb parameter direction - /// - /// The integer parameter direction - /// A ParameterDirection - private static ParameterDirection GetParameterDirection( short oledbDirection) - { - ParameterDirection pd; - switch (oledbDirection) - { - case 1: - pd = ParameterDirection.Input; - break; - case 2: - pd = ParameterDirection.Output; - break; - case 4: - pd = ParameterDirection.ReturnValue; - break; - default: - pd = ParameterDirection.InputOutput; - break; - } - return pd; - } - } -#endregion -} diff --git a/SiteServer.CMS/ImportExport/Components/ChannelIe.cs b/SiteServer.CMS/ImportExport/Components/ChannelIe.cs deleted file mode 100644 index 34be6f112..000000000 --- a/SiteServer.CMS/ImportExport/Components/ChannelIe.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using Atom.AdditionalElements; -using Atom.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.ImportExport.Components -{ - internal class ChannelIe - { - private readonly SiteInfo _siteInfo; - - //保存除内容表本身字段外的属性 - private const string ChannelTemplateName = "ChannelTemplateName"; - private const string ContentTemplateName = "ContentTemplateName"; - - public ChannelIe(SiteInfo siteInfo) - { - _siteInfo = siteInfo; - } - - public void ImportNodeInfo(ChannelInfo nodeInfo, ScopedElementCollection additionalElements, int parentId, IList indexNameList) - { - nodeInfo.ChannelName = AtomUtility.GetDcElementContent(additionalElements, new List{ ChannelAttribute.ChannelName, "NodeName" }); - nodeInfo.SiteId = _siteInfo.Id; - var contentModelPluginId = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.ContentModelPluginId); - if (!string.IsNullOrEmpty(contentModelPluginId)) - { - nodeInfo.ContentModelPluginId = contentModelPluginId; - } - var contentRelatedPluginIds = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.ContentRelatedPluginIds); - if (!string.IsNullOrEmpty(contentRelatedPluginIds)) - { - nodeInfo.ContentRelatedPluginIds = contentRelatedPluginIds; - } - nodeInfo.ParentId = parentId; - var indexName = AtomUtility.GetDcElementContent(additionalElements, new List { ChannelAttribute.IndexName, "NodeIndexName" }); - if (!string.IsNullOrEmpty(indexName) && indexNameList.IndexOf(indexName) == -1) - { - nodeInfo.IndexName = indexName; - indexNameList.Add(indexName); - } - nodeInfo.GroupNameCollection = AtomUtility.GetDcElementContent(additionalElements, new List { ChannelAttribute.GroupNameCollection, "NodeGroupNameCollection" }); - nodeInfo.AddDate = DateTime.Now; - nodeInfo.ImageUrl = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.ImageUrl); - nodeInfo.Content = AtomUtility.Decrypt(AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.Content)); - nodeInfo.FilePath = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.FilePath); - nodeInfo.ChannelFilePathRule = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.ChannelFilePathRule); - nodeInfo.ContentFilePathRule = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.ContentFilePathRule); - - nodeInfo.LinkUrl = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.LinkUrl); - nodeInfo.LinkType = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.LinkType); - - var channelTemplateName = AtomUtility.GetDcElementContent(additionalElements, ChannelTemplateName); - if (!string.IsNullOrEmpty(channelTemplateName)) - { - nodeInfo.ChannelTemplateId = TemplateManager.GetTemplateIdByTemplateName(_siteInfo.Id, TemplateType.ChannelTemplate, channelTemplateName); - } - var contentTemplateName = AtomUtility.GetDcElementContent(additionalElements, ContentTemplateName); - if (!string.IsNullOrEmpty(contentTemplateName)) - { - nodeInfo.ContentTemplateId = TemplateManager.GetTemplateIdByTemplateName(_siteInfo.Id, TemplateType.ContentTemplate, contentTemplateName); - } - - nodeInfo.Keywords = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.Keywords); - nodeInfo.Description = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.Description); - - nodeInfo.SetExtendValues(AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.ExtendValues)); - } - - public AtomFeed ExportNodeInfo(ChannelInfo nodeInfo) - { - var feed = AtomUtility.GetEmptyFeed(); - - AtomUtility.AddDcElement(feed.AdditionalElements, new List{ ChannelAttribute.Id, "NodeId" }, nodeInfo.Id.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, new List { ChannelAttribute.ChannelName, "NodeName" }, nodeInfo.ChannelName); - AtomUtility.AddDcElement(feed.AdditionalElements, new List { ChannelAttribute.SiteId, "PublishmentSystemId" }, nodeInfo.SiteId.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ContentModelPluginId, nodeInfo.ContentModelPluginId); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ContentRelatedPluginIds, nodeInfo.ContentRelatedPluginIds); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ParentId, nodeInfo.ParentId.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ParentsPath, nodeInfo.ParentsPath); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ParentsCount, nodeInfo.ParentsCount.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ChildrenCount, nodeInfo.ChildrenCount.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.IsLastNode, nodeInfo.IsLastNode.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, new List { ChannelAttribute.IndexName, "NodeIndexName" }, nodeInfo.IndexName); - AtomUtility.AddDcElement(feed.AdditionalElements, new List { ChannelAttribute.GroupNameCollection, "NodeGroupNameCollection" }, nodeInfo.GroupNameCollection); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.Taxis, nodeInfo.Taxis.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.AddDate, nodeInfo.AddDate.ToLongDateString()); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ImageUrl, nodeInfo.ImageUrl); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.Content, AtomUtility.Encrypt(nodeInfo.Content)); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ContentNum, nodeInfo.ContentNum.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.FilePath, nodeInfo.FilePath); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ChannelFilePathRule, nodeInfo.ChannelFilePathRule); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ContentFilePathRule, nodeInfo.ContentFilePathRule); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.LinkUrl, nodeInfo.LinkUrl); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.LinkType, nodeInfo.LinkType); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ChannelTemplateId, nodeInfo.ChannelTemplateId.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ContentTemplateId, nodeInfo.ContentTemplateId.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.Keywords, nodeInfo.Keywords); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.Description, nodeInfo.Description); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ExtendValues, nodeInfo.Additional.ToString()); - - if (nodeInfo.ChannelTemplateId != 0) - { - var channelTemplateName = TemplateManager.GetTemplateName(nodeInfo.SiteId, nodeInfo.ChannelTemplateId); - AtomUtility.AddDcElement(feed.AdditionalElements, ChannelTemplateName, channelTemplateName); - } - - if (nodeInfo.ContentTemplateId != 0) - { - var contentTemplateName = TemplateManager.GetTemplateName(nodeInfo.SiteId, nodeInfo.ContentTemplateId); - AtomUtility.AddDcElement(feed.AdditionalElements, ContentTemplateName, contentTemplateName); - } - - return feed; - } - } -} diff --git a/SiteServer.CMS/ImportExport/Components/ConfigurationIe.cs b/SiteServer.CMS/ImportExport/Components/ConfigurationIe.cs deleted file mode 100644 index 7339f0c62..000000000 --- a/SiteServer.CMS/ImportExport/Components/ConfigurationIe.cs +++ /dev/null @@ -1,174 +0,0 @@ -using System; -using System.Collections.Generic; -using Atom.Core; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.ImportExport.Components -{ - public class ConfigurationIe - { - private readonly int _siteId; - private readonly string _filePath; - - private const string DefaultIndexTemplateName = "DefaultIndexTemplateName"; - private const string DefaultChannelTemplateName = "DefaultChannelTemplateName"; - private const string DefaultContentTemplateName = "DefaultContentTemplateName"; - private const string DefaultFileTemplateName = "DefaultFileTemplateName"; - - public ConfigurationIe(int siteId, string filePath) - { - _siteId = siteId; - _filePath = filePath; - } - - public void Export() - { - var psInfo = SiteManager.GetSiteInfo(_siteId); - - var feed = AtomUtility.GetEmptyFeed(); - - AtomUtility.AddDcElement(feed.AdditionalElements, new List { SiteAttribute.Id, "PublishmentSystemId" }, psInfo.Id.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, new List { SiteAttribute.SiteName, "PublishmentSystemName" }, psInfo.SiteName); - AtomUtility.AddDcElement(feed.AdditionalElements, new List { SiteAttribute.SiteDir, "PublishmentSystemDir" }, psInfo.SiteDir); - AtomUtility.AddDcElement(feed.AdditionalElements, new List { SiteAttribute.TableName, "AuxiliaryTableForContent" }, psInfo.TableName); - AtomUtility.AddDcElement(feed.AdditionalElements, new List { SiteAttribute.IsRoot, "IsHeadquarters" }, psInfo.IsRoot.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, new List { SiteAttribute.ParentId, "ParentPublishmentSystemId" }, psInfo.ParentId.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, SiteAttribute.Taxis, psInfo.Taxis.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, SiteAttribute.SettingsXml, psInfo.Additional.ToString()); - - var indexTemplateId = TemplateManager.GetDefaultTemplateId(psInfo.Id, TemplateType.IndexPageTemplate); - if (indexTemplateId != 0) - { - var indexTemplateName = TemplateManager.GetTemplateName(_siteId, indexTemplateId); - AtomUtility.AddDcElement(feed.AdditionalElements, DefaultIndexTemplateName, indexTemplateName); - } - - var channelTemplateId = TemplateManager.GetDefaultTemplateId(psInfo.Id, TemplateType.ChannelTemplate); - if (channelTemplateId != 0) - { - var channelTemplateName = TemplateManager.GetTemplateName(_siteId, channelTemplateId); - AtomUtility.AddDcElement(feed.AdditionalElements, DefaultChannelTemplateName, channelTemplateName); - } - - var contentTemplateId = TemplateManager.GetDefaultTemplateId(psInfo.Id, TemplateType.ContentTemplate); - if (contentTemplateId != 0) - { - var contentTemplateName = TemplateManager.GetTemplateName(_siteId, contentTemplateId); - AtomUtility.AddDcElement(feed.AdditionalElements, DefaultContentTemplateName, contentTemplateName); - } - - var fileTemplateId = TemplateManager.GetDefaultTemplateId(psInfo.Id, TemplateType.FileTemplate); - if (fileTemplateId != 0) - { - var fileTemplateName = TemplateManager.GetTemplateName(psInfo.Id, fileTemplateId); - AtomUtility.AddDcElement(feed.AdditionalElements, DefaultFileTemplateName, fileTemplateName); - } - - var channelGroupInfoList = DataProvider.ChannelGroupDao.GetGroupInfoList(psInfo.Id); - channelGroupInfoList.Reverse(); - - foreach (var channelGroupInfo in channelGroupInfoList) - { - var entry = ChannelGroupIe.Export(channelGroupInfo); - feed.Entries.Add(entry); - } - - var contentGroupInfoList = DataProvider.ContentGroupDao.GetContentGroupInfoList(psInfo.Id); - contentGroupInfoList.Reverse(); - - foreach (var contentGroupInfo in contentGroupInfoList) - { - var entry = ContentGroupIe.Export(contentGroupInfo); - feed.Entries.Add(entry); - } - - feed.Save(_filePath); - } - - public static SiteInfo GetSiteInfo(string filePath) - { - var siteInfo = new SiteInfo(); - if (!FileUtils.IsFileExists(filePath)) return siteInfo; - - var feed = AtomFeed.Load(FileUtils.GetFileStreamReadOnly(filePath)); - - siteInfo.SiteName = AtomUtility.GetDcElementContent(feed.AdditionalElements, new List { SiteAttribute.SiteName, "PublishmentSystemName" }); - siteInfo.SiteDir = AtomUtility.GetDcElementContent(feed.AdditionalElements, new List { SiteAttribute.SiteDir, "PublishmentSystemDir" }); - if (siteInfo.SiteDir != null && siteInfo.SiteDir.IndexOf("\\", StringComparison.Ordinal) != -1) - { - siteInfo.SiteDir = siteInfo.SiteDir.Substring(siteInfo.SiteDir.LastIndexOf("\\", StringComparison.Ordinal) + 1); - } - siteInfo.SettingsXml = AtomUtility.GetDcElementContent(feed.AdditionalElements, SiteAttribute.SettingsXml); - siteInfo.Additional.IsCreateDoubleClick = false; - return siteInfo; - } - - public void Import() - { - if (!FileUtils.IsFileExists(_filePath)) return; - - var feed = AtomFeed.Load(FileUtils.GetFileStreamReadOnly(_filePath)); - - var siteInfo = SiteManager.GetSiteInfo(_siteId); - - siteInfo.SettingsXml = AtomUtility.GetDcElementContent(feed.AdditionalElements, SiteAttribute.SettingsXml, siteInfo.SettingsXml); - - siteInfo.Additional.IsSeparatedWeb = false; - siteInfo.Additional.IsCreateDoubleClick = false; - - DataProvider.SiteDao.Update(siteInfo); - - var indexTemplateName = AtomUtility.GetDcElementContent(feed.AdditionalElements, DefaultIndexTemplateName); - if (!string.IsNullOrEmpty(indexTemplateName)) - { - var indexTemplateId = TemplateManager.GetTemplateIdByTemplateName(siteInfo.Id, TemplateType.IndexPageTemplate, indexTemplateName); - if (indexTemplateId != 0) - { - DataProvider.TemplateDao.SetDefault(siteInfo.Id, indexTemplateId); - } - } - - var channelTemplateName = AtomUtility.GetDcElementContent(feed.AdditionalElements, DefaultChannelTemplateName); - if (!string.IsNullOrEmpty(channelTemplateName)) - { - var channelTemplateId = TemplateManager.GetTemplateIdByTemplateName(siteInfo.Id, TemplateType.ChannelTemplate, channelTemplateName); - if (channelTemplateId != 0) - { - DataProvider.TemplateDao.SetDefault(siteInfo.Id, channelTemplateId); - } - } - - var contentTemplateName = AtomUtility.GetDcElementContent(feed.AdditionalElements, DefaultContentTemplateName); - if (!string.IsNullOrEmpty(contentTemplateName)) - { - var contentTemplateId = TemplateManager.GetTemplateIdByTemplateName(siteInfo.Id, TemplateType.ContentTemplate, contentTemplateName); - if (contentTemplateId != 0) - { - DataProvider.TemplateDao.SetDefault(siteInfo.Id, contentTemplateId); - } - } - - var fileTemplateName = AtomUtility.GetDcElementContent(feed.AdditionalElements, DefaultFileTemplateName); - if (!string.IsNullOrEmpty(fileTemplateName)) - { - var fileTemplateId = TemplateManager.GetTemplateIdByTemplateName(siteInfo.Id, TemplateType.FileTemplate, fileTemplateName); - if (fileTemplateId != 0) - { - DataProvider.TemplateDao.SetDefault(siteInfo.Id, fileTemplateId); - } - } - - foreach (AtomEntry entry in feed.Entries) - { - if (!ChannelGroupIe.Import(entry, siteInfo.Id)) - { - ContentGroupIe.Import(entry, siteInfo.Id); - } - } - } - - } -} diff --git a/SiteServer.CMS/ImportExport/Components/ContentIe.cs b/SiteServer.CMS/ImportExport/Components/ContentIe.cs deleted file mode 100644 index 690b09520..000000000 --- a/SiteServer.CMS/ImportExport/Components/ContentIe.cs +++ /dev/null @@ -1,270 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Globalization; -using Atom.Core; -using Atom.Core.Collections; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.ImportExport.Components -{ - internal class ContentIe - { - private readonly SiteInfo _siteInfo; - private readonly string _siteContentDirectoryPath; - - public ContentIe(SiteInfo siteInfo, string siteContentDirectoryPath) - { - _siteContentDirectoryPath = siteContentDirectoryPath; - _siteInfo = siteInfo; - } - - public void ImportContents(string filePath, bool isOverride, ChannelInfo nodeInfo, int taxis, int importStart, int importCount, bool isChecked, int checkedLevel, string adminName) - { - if (!FileUtils.IsFileExists(filePath)) return; - var feed = AtomFeed.Load(FileUtils.GetFileStreamReadOnly(filePath)); - - ImportContents(feed.Entries, nodeInfo, taxis, importStart, importCount, false, isChecked, checkedLevel, isOverride, adminName); - } - - public void ImportContents(AtomEntryCollection entries, ChannelInfo nodeInfo, int taxis, bool isOverride, string adminName) - { - ImportContents(entries, nodeInfo, taxis, 0, 0, true, true, 0, isOverride, adminName); - } - - // 内部消化掉错误 - public void ImportContents(AtomEntryCollection entries, ChannelInfo nodeInfo, int taxis, int importStart, int importCount, bool isCheckedBySettings, bool isChecked, int checkedLevel, bool isOverride, string adminName) - { - if (importStart > 1 || importCount > 0) - { - var theEntries = new AtomEntryCollection(); - - if (importStart == 0) - { - importStart = 1; - } - if (importCount == 0) - { - importCount = entries.Count; - } - - var firstIndex = entries.Count - importStart - importCount + 1; - if (firstIndex <= 0) - { - firstIndex = 0; - } - - var addCount = 0; - for (var i = 0; i < entries.Count; i++) - { - if (addCount >= importCount) break; - if (i >= firstIndex) - { - theEntries.Add(entries[i]); - addCount++; - } - } - - entries = theEntries; - } - - var tableName = ChannelManager.GetTableName(_siteInfo, nodeInfo); - - foreach (AtomEntry entry in entries) - { - try - { - taxis++; - var lastEditDate = AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.LastEditDate); - var groupNameCollection = AtomUtility.GetDcElementContent(entry.AdditionalElements, new List{ ContentAttribute.GroupNameCollection , "ContentGroupNameCollection" }); - if (isCheckedBySettings) - { - isChecked = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.IsChecked)); - checkedLevel = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.CheckedLevel)); - } - var hits = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.Hits)); - var hitsByDay = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.HitsByDay)); - var hitsByWeek = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.HitsByWeek)); - var hitsByMonth = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.HitsByMonth)); - var lastHitsDate = AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.LastHitsDate); - var title = AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.Title); - var isTop = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.IsTop)); - var isRecommend = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.IsRecommend)); - var isHot = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.IsHot)); - var isColor = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.IsColor)); - var linkUrl = AtomUtility.Decrypt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.LinkUrl)); - var addDate = AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.AddDate); - - var topTaxis = 0; - if (isTop) - { - topTaxis = taxis - 1; - taxis = DataProvider.ContentDao.GetMaxTaxis(tableName, nodeInfo.Id, true) + 1; - } - var tags = AtomUtility.Decrypt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.Tags)); - - var contentInfo = new ContentInfo - { - ChannelId= nodeInfo.Id, - SiteId = _siteInfo.Id, - AddUserName = adminName, - AddDate = TranslateUtils.ToDateTime(addDate) - }; - contentInfo.LastEditUserName = contentInfo.AddUserName; - contentInfo.LastEditDate = TranslateUtils.ToDateTime(lastEditDate); - contentInfo.GroupNameCollection = groupNameCollection; - contentInfo.Tags = tags; - contentInfo.IsChecked = isChecked; - contentInfo.CheckedLevel = checkedLevel; - contentInfo.Hits = hits; - contentInfo.HitsByDay = hitsByDay; - contentInfo.HitsByWeek = hitsByWeek; - contentInfo.HitsByMonth = hitsByMonth; - contentInfo.LastHitsDate = TranslateUtils.ToDateTime(lastHitsDate); - contentInfo.Title = AtomUtility.Decrypt(title); - contentInfo.IsTop = isTop; - contentInfo.IsRecommend = isRecommend; - contentInfo.IsHot = isHot; - contentInfo.IsColor = isColor; - contentInfo.LinkUrl = linkUrl; - - var attributes = AtomUtility.GetDcElementNameValueCollection(entry.AdditionalElements); - foreach (string attributeName in attributes.Keys) - { - if (!contentInfo.ContainsKey(attributeName.ToLower())) - { - contentInfo.Set(attributeName, AtomUtility.Decrypt(attributes[attributeName])); - } - } - - var isInsert = false; - if (isOverride) - { - var existsIDs = DataProvider.ContentDao.GetIdListBySameTitle(tableName, contentInfo.ChannelId, contentInfo.Title); - if (existsIDs.Count > 0) - { - foreach (int id in existsIDs) - { - contentInfo.Id = id; - DataProvider.ContentDao.Update(tableName, _siteInfo, contentInfo); - } - } - else - { - isInsert = true; - } - } - else - { - isInsert = true; - } - - if (isInsert) - { - var contentId = DataProvider.ContentDao.Insert(tableName, _siteInfo, contentInfo, false, taxis); - - if (!string.IsNullOrEmpty(tags)) - { - var tagCollection = TagUtils.ParseTagsString(tags); - TagUtils.AddTags(tagCollection, _siteInfo.Id, contentId); - } - } - - if (isTop) - { - taxis = topTaxis; - } - } - catch - { - // ignored - } - } - } - - public bool ExportContents(SiteInfo siteInfo, int channelId, List contentIdList, bool isPeriods, string dateFrom, string dateTo, ETriState checkedState) - { - var filePath = _siteContentDirectoryPath + PathUtils.SeparatorChar + "contents.xml"; - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - var feed = AtomUtility.GetEmptyFeed(); - - if (contentIdList == null || contentIdList.Count == 0) - { - contentIdList = DataProvider.ContentDao.GetContentIdList(tableName, channelId, isPeriods, dateFrom, dateTo, checkedState); - } - if (contentIdList.Count == 0) return false; - - var collection = new NameValueCollection(); - - foreach (var contentId in contentIdList) - { - var contentInfo = DataProvider.ContentDao.GetContentInfo(tableName, contentId); - try - { - ContentUtility.PutImagePaths(siteInfo, contentInfo, collection); - } - catch - { - // ignored - } - var entry = ExportContentInfo(contentInfo); - feed.Entries.Add(entry); - } - feed.Save(filePath); - - foreach (string imageUrl in collection.Keys) - { - var sourceFilePath = collection[imageUrl]; - var destFilePath = PathUtility.MapPath(_siteContentDirectoryPath, imageUrl); - DirectoryUtils.CreateDirectoryIfNotExists(destFilePath); - FileUtils.MoveFile(sourceFilePath, destFilePath, true); - } - - return true; - } - - public AtomEntry ExportContentInfo(ContentInfo contentInfo) - { - var entry = AtomUtility.GetEmptyEntry(); - - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.Id, contentInfo.Id.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, new List{ ContentAttribute.ChannelId, "NodeId" }, contentInfo.ChannelId.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, new List { ContentAttribute.SiteId, "PublishmentSystemId" }, contentInfo.SiteId.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.AddUserName, contentInfo.AddUserName); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.LastEditUserName, contentInfo.LastEditUserName); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.WritingUserName, contentInfo.WritingUserName); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.LastEditDate, contentInfo.LastEditDate.ToString(CultureInfo.InvariantCulture)); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.Taxis, contentInfo.Taxis.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, new List{ ContentAttribute.GroupNameCollection, "ContentGroupNameCollection" }, contentInfo.GroupNameCollection); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.Tags, AtomUtility.Encrypt(contentInfo.Tags)); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.SourceId, contentInfo.SourceId.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.ReferenceId, contentInfo.ReferenceId.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.IsChecked, contentInfo.IsChecked.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.CheckedLevel, contentInfo.CheckedLevel.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.Hits, contentInfo.Hits.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.HitsByDay, contentInfo.HitsByDay.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.HitsByWeek, contentInfo.HitsByWeek.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.HitsByMonth, contentInfo.HitsByMonth.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.LastHitsDate, contentInfo.LastHitsDate.ToString(CultureInfo.InvariantCulture)); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.Title, AtomUtility.Encrypt(contentInfo.Title)); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.IsTop, contentInfo.IsTop.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.IsRecommend, contentInfo.IsRecommend.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.IsHot, contentInfo.IsHot.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.IsColor, contentInfo.IsColor.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.LinkUrl, AtomUtility.Encrypt(contentInfo.LinkUrl)); - AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.AddDate, contentInfo.AddDate.ToString(CultureInfo.InvariantCulture)); - - foreach (string attributeName in contentInfo.ToNameValueCollection().Keys) - { - if (!ContentAttribute.AllAttributesLowercase.Contains(attributeName.ToLower())) - { - AtomUtility.AddDcElement(entry.AdditionalElements, attributeName, AtomUtility.Encrypt(contentInfo.GetString(attributeName))); - } - } - - return entry; - } - } -} diff --git a/SiteServer.CMS/ImportExport/Components/TableIe.cs b/SiteServer.CMS/ImportExport/Components/TableIe.cs deleted file mode 100644 index 9fb2edf74..000000000 --- a/SiteServer.CMS/ImportExport/Components/TableIe.cs +++ /dev/null @@ -1,157 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Specialized; -using Atom.Core; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.CMS.ImportExport.Components -{ - internal class TableIe - { - private readonly string _directoryPath; - - public TableIe(string directoryPath) - { - _directoryPath = directoryPath; - } - - public void ExportAuxiliaryTable(string tableName) - { - var tableInfo = DataProvider.TableDao.GetTableCollectionInfo(tableName); - if (tableInfo == null) return; - - var metaInfoList = TableMetadataManager.GetTableMetadataInfoList(tableInfo.TableName); - var filePath = _directoryPath + PathUtils.SeparatorChar + tableInfo.TableName + ".xml"; - - var feed = AtomUtility.GetEmptyFeed(); - - AtomUtility.AddDcElement(feed.AdditionalElements, new List { nameof(TableInfo.TableName), "TableENName" }, tableInfo.TableName); - AtomUtility.AddDcElement(feed.AdditionalElements, new List { nameof(TableInfo.DisplayName), "TableCNName" }, tableInfo.DisplayName); - AtomUtility.AddDcElement(feed.AdditionalElements, nameof(TableInfo.AttributeNum), tableInfo.AttributeNum.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, new List { nameof(TableInfo.IsCreatedInDb), "IsCreatedInDB" }, tableInfo.IsCreatedInDb.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, new List { nameof(TableInfo.IsChangedAfterCreatedInDb), "IsChangedAfterCreatedInDB" }, tableInfo.IsChangedAfterCreatedInDb.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, nameof(TableInfo.Description), tableInfo.Description); - AtomUtility.AddDcElement(feed.AdditionalElements, "SerializedString", TableMetadataManager.GetSerializedString(tableInfo.TableName)); //表唯一序列号 - - foreach (var metaInfo in metaInfoList) - { - var entry = AtomUtility.GetEmptyEntry(); - - AtomUtility.AddDcElement(entry.AdditionalElements, new List { nameof(TableMetadataInfo.Id), "TableMetadataID" }, metaInfo.Id.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, new List { nameof(TableMetadataInfo.TableName), "AuxiliaryTableENName" }, metaInfo.TableName); - AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TableMetadataInfo.AttributeName), metaInfo.AttributeName); - AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TableMetadataInfo.DataType), metaInfo.DataType.Value); - AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TableMetadataInfo.DataLength), metaInfo.DataLength.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TableMetadataInfo.Taxis), metaInfo.Taxis.ToString()); - AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TableMetadataInfo.IsSystem), metaInfo.IsSystem.ToString()); - - feed.Entries.Add(entry); - } - feed.Save(filePath); - } - - /// - /// 将频道模板中的辅助表导入发布系统中,返回修改了的表名对照 - /// 在导入辅助表的同时检查发布系统辅助表并替换对应表 - /// - public NameValueCollection ImportAuxiliaryTables(int siteId, bool isUserTables) - { - if (!DirectoryUtils.IsDirectoryExists(_directoryPath)) return null; - - var siteInfo = SiteManager.GetSiteInfo(siteId); - - var nameValueCollection = new NameValueCollection(); - var tableNamePrefix = siteInfo.SiteDir + "_"; - - var filePaths = DirectoryUtils.GetFilePaths(_directoryPath); - - foreach (var filePath in filePaths) - { - var feed = AtomFeed.Load(FileUtils.GetFileStreamReadOnly(filePath)); - - var tableName = AtomUtility.GetDcElementContent(feed.AdditionalElements, new List { nameof(TableInfo.TableName), "TableENName" }); - - if (!isUserTables) - { - nameValueCollection[tableName] = siteInfo.TableName; - continue; - } - - var displayName = AtomUtility.GetDcElementContent(feed.AdditionalElements, new List { nameof(TableInfo.DisplayName), "TableCNName" }); - - var serializedString = AtomUtility.GetDcElementContent(feed.AdditionalElements, "SerializedString"); - - var tableNameToInsert = string.Empty;//需要增加的表名,空代表不需要添加辅助表 - - var tableInfo = DataProvider.TableDao.GetTableCollectionInfo(tableName); - if (tableInfo == null)//如果当前系统无此表名 - { - tableNameToInsert = tableName; - } - else - { - var serializedStringForExistTable = TableMetadataManager.GetSerializedString(tableName); - - if (!string.IsNullOrEmpty(serializedString)) - { - if (serializedString != serializedStringForExistTable)//仅有此时,导入表需要修改表名 - { - tableNameToInsert = tableNamePrefix + tableName; - displayName = tableNamePrefix + displayName; - nameValueCollection[tableName] = tableNameToInsert; - } - } - } - - if (!string.IsNullOrEmpty(tableNameToInsert))//需要添加 - { - if (!DataProvider.DatabaseDao.IsTableExists(tableNameToInsert)) - { - tableInfo = new TableInfo - { - TableName = tableNameToInsert, - DisplayName = displayName, - AttributeNum = 0, - IsCreatedInDb = false, - IsChangedAfterCreatedInDb = false, - Description = AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableInfo.Description)) - }; - - var metadataInfoList = new List(); - foreach (AtomEntry entry in feed.Entries) - { - var metaInfo = new TableMetadataInfo - { - TableName = tableNameToInsert, - AttributeName = AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TableMetadataInfo.AttributeName)), - DataType = DataTypeUtils.GetEnumType(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TableMetadataInfo.DataType))), - DataLength = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TableMetadataInfo.DataLength))), - Taxis = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TableMetadataInfo.Taxis))), - IsSystem = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TableMetadataInfo.IsSystem))) - }; - - if (string.IsNullOrEmpty(metaInfo.AttributeName) || - ContentAttribute.AllAttributesLowercase.Contains(metaInfo.AttributeName.ToLower())) - continue; - - metadataInfoList.Add(metaInfo); - } - - DataProvider.TableDao.Insert(tableInfo, metadataInfoList); - - DataProvider.TableDao.CreateDbTable(tableNameToInsert); - } - } - - var tableNameToChange = !string.IsNullOrEmpty(tableNameToInsert) ? tableNameToInsert : tableName; - //更新发布系统后台内容表及栏目表 - siteInfo.TableName = tableNameToChange; - DataProvider.SiteDao.Update(siteInfo); - } - - return nameValueCollection; - } - - } -} diff --git a/SiteServer.CMS/ImportExport/ImportObject.cs b/SiteServer.CMS/ImportExport/ImportObject.cs deleted file mode 100644 index d12501ca7..000000000 --- a/SiteServer.CMS/ImportExport/ImportObject.cs +++ /dev/null @@ -1,581 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Text; -using Atom.Core; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Office; -using SiteServer.CMS.ImportExport.Components; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; - -namespace SiteServer.CMS.ImportExport -{ - public class ImportObject - { - private readonly SiteInfo _siteInfo; - private readonly string _sitePath; - private readonly string _adminName; - - public ImportObject(int siteId, string adminName) - { - _siteInfo = SiteManager.GetSiteInfo(siteId); - _sitePath = PathUtils.Combine(WebConfigUtils.PhysicalApplicationPath, _siteInfo.SiteDir); - _adminName = adminName; - } - - //获取保存辅助表名称对应集合数据库缓存键 - private string GetTableNameNameValueCollectionDbCacheKey() - { - return "SiteServer.CMS.Core.ImportObject.TableNameNameValueCollection_" + _siteInfo.Id; - } - - public NameValueCollection GetTableNameCache() - { - NameValueCollection nameValueCollection = null; - var cacheValue = CacheDbUtils.GetValue(GetTableNameNameValueCollectionDbCacheKey()); - if (!string.IsNullOrEmpty(cacheValue)) - { - nameValueCollection = TranslateUtils.ToNameValueCollection(cacheValue); - } - return nameValueCollection; - } - - public void SaveTableNameCache(NameValueCollection nameValueCollection) - { - if (nameValueCollection != null && nameValueCollection.Count > 0) - { - var cacheKey = GetTableNameNameValueCollectionDbCacheKey(); - var cacheValue = TranslateUtils.NameValueCollectionToString(nameValueCollection); - CacheDbUtils.RemoveAndInsert(cacheKey, cacheValue); - } - } - - public void RemoveDbCache() - { - var cacheKey = GetTableNameNameValueCollectionDbCacheKey(); - CacheDbUtils.GetValueAndRemove(cacheKey); - } - - public void ImportFiles(string siteTemplatePath, bool isOverride) - { - //if (this.FSO.IsRoot) - //{ - // string[] filePaths = DirectoryUtils.GetFilePaths(siteTemplatePath); - // foreach (string filePath in filePaths) - // { - // string fileName = PathUtils.GetFileName(filePath); - // if (!PathUtility.IsSystemFile(fileName)) - // { - // string destFilePath = PathUtils.Combine(FSO.SitePath, fileName); - // FileUtils.MoveFile(filePath, destFilePath, isOverride); - // } - // } - - // ArrayList siteDirArrayList = DataProvider.SiteDAO.GetLowerSiteDirArrayListThatNotIsRoot(); - - // string[] directoryPaths = DirectoryUtils.GetDirectoryPaths(siteTemplatePath); - // foreach (string subDirectoryPath in directoryPaths) - // { - // string directoryName = PathUtils.GetDirectoryName(subDirectoryPath); - // if (!PathUtility.IsSystemDirectory(directoryName) && !siteDirArrayList.Contains(directoryName.ToLower())) - // { - // string destDirectoryPath = PathUtils.Combine(FSO.SitePath, directoryName); - // DirectoryUtils.MoveDirectory(subDirectoryPath, destDirectoryPath, isOverride); - // } - // } - //} - //else - //{ - // DirectoryUtils.MoveDirectory(siteTemplatePath, FSO.SitePath, isOverride); - //} - //string siteTemplateMetadataPath = PathUtils.Combine(FSO.SitePath, DirectoryUtility.SiteTemplates.SiteTemplateMetadata); - //DirectoryUtils.DeleteDirectoryIfExists(siteTemplateMetadataPath); - DirectoryUtility.ImportSiteFiles(_siteInfo, siteTemplatePath, isOverride); - } - - public void ImportSiteContent(string siteContentDirectoryPath, string filePath, bool isImportContents) - { - var siteIe = new SiteIe(_siteInfo, siteContentDirectoryPath); - siteIe.ImportChannelsAndContents(filePath, isImportContents, false, 0, _adminName); - } - - - /// - /// 从指定的地址导入网站模板至站点中 - /// - public void ImportTemplates(string filePath, bool overwrite, string administratorName) - { - var templateIe = new TemplateIe(_siteInfo.Id, filePath); - templateIe.ImportTemplates(overwrite, administratorName); - } - - public void ImportRelatedFieldByZipFile(string zipFilePath, bool overwrite) - { - var directoryPath = PathUtils.GetTemporaryFilesPath("RelatedField"); - DirectoryUtils.DeleteDirectoryIfExists(directoryPath); - DirectoryUtils.CreateDirectoryIfNotExists(directoryPath); - - ZipUtils.UnpackFiles(zipFilePath, directoryPath); - - var relatedFieldIe = new RelatedFieldIe(_siteInfo.Id, directoryPath); - relatedFieldIe.ImportRelatedField(overwrite); - } - - public void ImportAuxiliaryTables(string tableDirectoryPath, bool isUseTables) - { - NameValueCollection nameValueCollection = null; - if (DirectoryUtils.IsDirectoryExists(tableDirectoryPath)) - { - var tableIe = new TableIe(tableDirectoryPath); - nameValueCollection = tableIe.ImportAuxiliaryTables(_siteInfo.Id, isUseTables); - } - SaveTableNameCache(nameValueCollection); - } - - - public void ImportTableStyles(string tableDirectoryPath) - { - if (DirectoryUtils.IsDirectoryExists(tableDirectoryPath)) - { - var tableStyleIe = new TableStyleIe(tableDirectoryPath, _adminName); - tableStyleIe.ImportTableStyles(_siteInfo.Id); - } - } - - public static void ImportTableStyleByZipFile(string tableName, int channelId, string zipFilePath) - { - var styleDirectoryPath = PathUtils.GetTemporaryFilesPath("TableStyle"); - DirectoryUtils.DeleteDirectoryIfExists(styleDirectoryPath); - DirectoryUtils.CreateDirectoryIfNotExists(styleDirectoryPath); - - ZipUtils.UnpackFiles(zipFilePath, styleDirectoryPath); - - TableStyleIe.SingleImportTableStyle(tableName, styleDirectoryPath, channelId); - } - - public void ImportConfiguration(string configurationFilePath) - { - var configIe = new ConfigurationIe(_siteInfo.Id, configurationFilePath); - configIe.Import(); - } - - - public void ImportChannelsAndContentsByZipFile(int parentId, string zipFilePath, bool isOverride) - { - var siteContentDirectoryPath = PathUtils.GetTemporaryFilesPath(EBackupTypeUtils.GetValue(EBackupType.ChannelsAndContents)); - DirectoryUtils.DeleteDirectoryIfExists(siteContentDirectoryPath); - DirectoryUtils.CreateDirectoryIfNotExists(siteContentDirectoryPath); - - ZipUtils.UnpackFiles(zipFilePath, siteContentDirectoryPath); - - ImportChannelsAndContentsFromZip(parentId, siteContentDirectoryPath, isOverride); - - DataProvider.ChannelDao.UpdateContentNum(_siteInfo); - - var uploadFolderPath = PathUtils.Combine(siteContentDirectoryPath, BackupUtility.UploadFolderName); - var uploadFilePath = PathUtils.Combine(uploadFolderPath, BackupUtility.UploadFileName); - if (!FileUtils.IsFileExists(uploadFilePath)) - { - return; - } - var feed = AtomFeed.Load(FileUtils.GetFileStreamReadOnly(uploadFilePath)); - if (feed != null) - { - AtomEntry entry = feed.Entries[0]; - string imageUploadDirectoryPath = AtomUtility.GetDcElementContent(entry.AdditionalElements, "ImageUploadDirectoryName"); - if(imageUploadDirectoryPath != null) - { - DirectoryUtils.MoveDirectory(PathUtils.Combine(siteContentDirectoryPath, imageUploadDirectoryPath), PathUtils.Combine(_sitePath, _siteInfo.Additional.ImageUploadDirectoryName), isOverride); - } - string videoUploadDirectoryPath = AtomUtility.GetDcElementContent(entry.AdditionalElements, "VideoUploadDirectoryName"); - if (videoUploadDirectoryPath != null) - { - DirectoryUtils.MoveDirectory(PathUtils.Combine(siteContentDirectoryPath, videoUploadDirectoryPath), PathUtils.Combine(_sitePath, _siteInfo.Additional.VideoUploadDirectoryName), isOverride); - } - string fileUploadDirectoryPath = AtomUtility.GetDcElementContent(entry.AdditionalElements, "FileUploadDirectoryName"); - if (fileUploadDirectoryPath != null) - { - DirectoryUtils.MoveDirectory(PathUtils.Combine(siteContentDirectoryPath, fileUploadDirectoryPath), PathUtils.Combine(_sitePath, _siteInfo.Additional.FileUploadDirectoryName), isOverride); - } - } - } - - public void ImportChannelsAndContentsFromZip(int parentId, string siteContentDirectoryPath, bool isOverride) - { - var filePathList = GetSiteContentFilePathList(siteContentDirectoryPath); - - var siteIe = new SiteIe(_siteInfo, siteContentDirectoryPath); - - Hashtable levelHashtable = null; - foreach (var filePath in filePathList) - { - var firstIndex = filePath.LastIndexOf(PathUtils.SeparatorChar) + 1; - var lastIndex = filePath.LastIndexOf(".", StringComparison.Ordinal); - var orderString = filePath.Substring(firstIndex, lastIndex - firstIndex); - - var level = StringUtils.GetCount("_", orderString); - - if (levelHashtable == null) - { - levelHashtable = new Hashtable - { - [level] = parentId - }; - } - - var insertChannelId = siteIe.ImportChannelsAndContents(filePath, true, isOverride, (int)levelHashtable[level], _adminName); - levelHashtable[level + 1] = insertChannelId; - } - } - - public void ImportChannelsAndContents(int parentId, string siteContentDirectoryPath, bool isOverride) - { - var filePathList = GetSiteContentFilePathList(siteContentDirectoryPath); - - var siteIe = new SiteIe(_siteInfo, siteContentDirectoryPath); - - var parentOrderString = "none"; - //int parentID = 0; - foreach (var filePath in filePathList) - { - var firstIndex = filePath.LastIndexOf(PathUtils.SeparatorChar) + 1; - var lastIndex = filePath.LastIndexOf(".", StringComparison.Ordinal); - var orderString = filePath.Substring(firstIndex, lastIndex - firstIndex); - - if (StringUtils.StartsWithIgnoreCase(orderString, parentOrderString)) - { - parentId = siteIe.ImportChannelsAndContents(filePath, true, isOverride, parentId, _adminName); - parentOrderString = orderString; - } - else - { - siteIe.ImportChannelsAndContents(filePath, true, isOverride, parentId, _adminName); - } - } - } - - public void ImportContentsByZipFile(ChannelInfo nodeInfo, string zipFilePath, bool isOverride, int importStart, int importCount, bool isChecked, int checkedLevel) - { - var siteContentDirectoryPath = PathUtils.GetTemporaryFilesPath("contents"); - DirectoryUtils.DeleteDirectoryIfExists(siteContentDirectoryPath); - DirectoryUtils.CreateDirectoryIfNotExists(siteContentDirectoryPath); - - ZipUtils.UnpackFiles(zipFilePath, siteContentDirectoryPath); - - var tableName = ChannelManager.GetTableName(_siteInfo, nodeInfo); - - var taxis = DataProvider.ContentDao.GetMaxTaxis(tableName, nodeInfo.Id, false); - - ImportContents(nodeInfo, siteContentDirectoryPath, isOverride, taxis, importStart, importCount, isChecked, checkedLevel); - - DataProvider.ChannelDao.UpdateContentNum(_siteInfo); - } - - public void ImportContentsByAccessFile(int channelId, string excelFilePath, bool isOverride, int importStart, int importCount, bool isChecked, int checkedLevel) - { - var nodeInfo = ChannelManager.GetChannelInfo(_siteInfo.Id, channelId); - var contentInfoList = AccessObject.GetContentsByAccessFile(excelFilePath, _siteInfo, nodeInfo); - - if (importStart > 1 || importCount > 0) - { - var theList = new List(); - - if (importStart == 0) - { - importStart = 1; - } - if (importCount == 0) - { - importCount = contentInfoList.Count; - } - - var firstIndex = contentInfoList.Count - importStart - importCount + 1; - if (firstIndex <= 0) - { - firstIndex = 0; - } - - var addCount = 0; - for (var i = 0; i < contentInfoList.Count; i++) - { - if (addCount >= importCount) break; - if (i >= firstIndex) - { - theList.Add(contentInfoList[i]); - addCount++; - } - } - - contentInfoList = theList; - } - - var tableName = ChannelManager.GetTableName(_siteInfo, nodeInfo); - - foreach (var contentInfo in contentInfoList) - { - contentInfo.IsChecked = isChecked; - contentInfo.CheckedLevel = checkedLevel; - - //contentInfo.ID = DataProvider.ContentDAO.Insert(tableName, this.FSO.SiteInfo, contentInfo); - if (isOverride) - { - var existsIDs = DataProvider.ContentDao.GetIdListBySameTitle(tableName, contentInfo.ChannelId, contentInfo.Title); - if (existsIDs.Count > 0) - { - foreach (int id in existsIDs) - { - contentInfo.Id = id; - DataProvider.ContentDao.Update(tableName, _siteInfo, contentInfo); - } - } - else - { - contentInfo.Id = DataProvider.ContentDao.Insert(tableName, _siteInfo, contentInfo); - } - } - else - { - contentInfo.Id = DataProvider.ContentDao.Insert(tableName, _siteInfo, contentInfo); - } - } - } - - public void ImportContentsByCsvFile(int channelId, string csvFilePath, bool isOverride, int importStart, int importCount, bool isChecked, int checkedLevel) - { - var channelInfo = ChannelManager.GetChannelInfo(_siteInfo.Id, channelId); - var contentInfoList = ExcelObject.GetContentsByCsvFile(csvFilePath, _siteInfo, channelInfo); - contentInfoList.Reverse(); - - if (importStart > 1 || importCount > 0) - { - var theList = new List(); - - if (importStart == 0) - { - importStart = 1; - } - if (importCount == 0) - { - importCount = contentInfoList.Count; - } - - var firstIndex = contentInfoList.Count - importStart - importCount + 1; - if (firstIndex <= 0) - { - firstIndex = 0; - } - - var addCount = 0; - for (var i = 0; i < contentInfoList.Count; i++) - { - if (addCount >= importCount) break; - if (i >= firstIndex) - { - theList.Add(contentInfoList[i]); - addCount++; - } - } - - contentInfoList = theList; - } - - var tableName = ChannelManager.GetTableName(_siteInfo, channelInfo); - - foreach (var contentInfo in contentInfoList) - { - contentInfo.IsChecked = isChecked; - contentInfo.CheckedLevel = checkedLevel; - if (isOverride) - { - var existsIds = DataProvider.ContentDao.GetIdListBySameTitle(tableName, contentInfo.ChannelId, contentInfo.Title); - if (existsIds.Count > 0) - { - foreach (var id in existsIds) - { - contentInfo.Id = id; - DataProvider.ContentDao.Update(tableName, _siteInfo, contentInfo); - } - } - else - { - contentInfo.Id = DataProvider.ContentDao.Insert(tableName, _siteInfo, contentInfo); - } - } - else - { - contentInfo.Id = DataProvider.ContentDao.Insert(tableName, _siteInfo, contentInfo); - } - //this.FSO.AddContentToWaitingCreate(contentInfo.ChannelId, contentID); - } - } - - public void ImportContentsByTxtZipFile(int channelId, string zipFilePath, bool isOverride, int importStart, int importCount, bool isChecked, int checkedLevel) - { - var directoryPath = PathUtils.GetTemporaryFilesPath("contents"); - DirectoryUtils.DeleteDirectoryIfExists(directoryPath); - DirectoryUtils.CreateDirectoryIfNotExists(directoryPath); - - ZipUtils.UnpackFiles(zipFilePath, directoryPath); - - var nodeInfo = ChannelManager.GetChannelInfo(_siteInfo.Id, channelId); - - var contentInfoList = TxtObject.GetContentListByTxtFile(directoryPath, _siteInfo, nodeInfo); - - if (importStart > 1 || importCount > 0) - { - var theList = new List(); - - if (importStart == 0) - { - importStart = 1; - } - if (importCount == 0) - { - importCount = contentInfoList.Count; - } - - var firstIndex = contentInfoList.Count - importStart - importCount + 1; - if (firstIndex <= 0) - { - firstIndex = 0; - } - - var addCount = 0; - for (var i = 0; i < contentInfoList.Count; i++) - { - if (addCount >= importCount) break; - if (i >= firstIndex) - { - theList.Add(contentInfoList[i]); - addCount++; - } - } - - contentInfoList = theList; - } - - var tableName = ChannelManager.GetTableName(_siteInfo, nodeInfo); - - foreach (var contentInfo in contentInfoList) - { - contentInfo.IsChecked = isChecked; - contentInfo.CheckedLevel = checkedLevel; - - //int contentID = DataProvider.ContentDAO.Insert(tableName, this.FSO.SiteInfo, contentInfo); - - if (isOverride) - { - var existsIDs = DataProvider.ContentDao.GetIdListBySameTitle(tableName, contentInfo.ChannelId, contentInfo.Title); - if (existsIDs.Count > 0) - { - foreach (int id in existsIDs) - { - contentInfo.Id = id; - DataProvider.ContentDao.Update(tableName, _siteInfo, contentInfo); - } - } - else - { - contentInfo.Id = DataProvider.ContentDao.Insert(tableName, _siteInfo, contentInfo); - } - } - else - { - contentInfo.Id = DataProvider.ContentDao.Insert(tableName, _siteInfo, contentInfo); - } - - //this.FSO.AddContentToWaitingCreate(contentInfo.ChannelId, contentID); - } - } - - public void ImportContents(ChannelInfo nodeInfo, string siteContentDirectoryPath, bool isOverride, int taxis, int importStart, int importCount, bool isChecked, int checkedLevel) - { - var filePath = PathUtils.Combine(siteContentDirectoryPath, "contents.xml"); - - var contentIe = new ContentIe(_siteInfo, siteContentDirectoryPath); - - contentIe.ImportContents(filePath, isOverride, nodeInfo, taxis, importStart, importCount, isChecked, checkedLevel, _adminName); - - FileUtils.DeleteFileIfExists(filePath); - - DirectoryUtils.MoveDirectory(siteContentDirectoryPath, _sitePath, isOverride); - } - - //public void ImportInputContentsByCsvFile(InputInfo inputInfo, string excelFilePath, int importStart, int importCount, bool isChecked) - //{ - // var contentInfoList = ExcelObject.GetInputContentsByCsvFile(excelFilePath, _siteInfo, inputInfo); - // contentInfoList.Reverse(); - - // if (importStart > 1 || importCount > 0) - // { - // var theList = new List(); - - // if (importStart == 0) - // { - // importStart = 1; - // } - // if (importCount == 0) - // { - // importCount = contentInfoList.Count; - // } - - // var firstIndex = contentInfoList.Count - importStart - importCount + 1; - // if (firstIndex <= 0) - // { - // firstIndex = 0; - // } - - // var addCount = 0; - // for (var i = 0; i < contentInfoList.Count; i++) - // { - // if (addCount >= importCount) break; - // if (i >= firstIndex) - // { - // theList.Add(contentInfoList[i]); - // addCount++; - // } - // } - - // contentInfoList = theList; - // } - - // foreach (var contentInfo in contentInfoList) - // { - // contentInfo.IsChecked = isChecked; - // DataProvider.InputContentDao.Insert(contentInfo); - // } - //} - - public static IList GetSiteContentFilePathList(string siteContentDirectoryPath) - { - var filePaths = DirectoryUtils.GetFilePaths(siteContentDirectoryPath); - var filePathSortedList = new SortedList(); - foreach (var filePath in filePaths) - { - var keyBuilder = new StringBuilder(); - var fileName = PathUtils.GetFileName(filePath).ToLower().Replace(".xml", ""); - var nums = fileName.Split('_'); - foreach (var numStr in nums) - { - var count = 7 - numStr.Length; - if (count > 0) - { - for (var i = 0; i < count; i++) - { - keyBuilder.Append("0"); - } - } - keyBuilder.Append(numStr); - keyBuilder.Append("_"); - } - if (keyBuilder.Length > 0) keyBuilder.Remove(keyBuilder.Length - 1, 1); - filePathSortedList.Add(keyBuilder.ToString(), filePath); - } - return filePathSortedList.Values; - } - - } -} diff --git a/SiteServer.CMS/Model/AdministratorInfo.cs b/SiteServer.CMS/Model/AdministratorInfo.cs deleted file mode 100644 index 6820d0e15..000000000 --- a/SiteServer.CMS/Model/AdministratorInfo.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using SiteServer.Plugin; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Model -{ - public class AdministratorInfo: IAdministratorInfo - { - private string _displayName; - - public AdministratorInfo() - { - Id = 0; - UserName = string.Empty; - Password = string.Empty; - PasswordFormat = EPasswordFormat.Encrypted; - PasswordSalt = string.Empty; - CreationDate = DateUtils.SqlMinValue; - LastActivityDate = DateUtils.SqlMinValue; - CountOfLogin = 0; - CountOfFailedLogin = 0; - CreatorUserName = string.Empty; - IsLockedOut = false; - SiteIdCollection = string.Empty; - SiteId = 0; - DepartmentId = 0; - AreaId = 0; - _displayName = string.Empty; - Email = string.Empty; - Mobile = string.Empty; - } - - public AdministratorInfo(int id, string userName, string password, EPasswordFormat passwordFormat, string passwordSalt, DateTime creationDate, DateTime lastActivityDate, int countOfLogin, int countOfFailedLogin, string creatorUserName, bool isLockedOut, string siteIdCollection, int siteId, int departmentId, int areaId, string displayName, string email, string mobile) - { - Id = id; - UserName = userName; - Password = password; - PasswordFormat = passwordFormat; - PasswordSalt = passwordSalt; - CreationDate = creationDate; - LastActivityDate = lastActivityDate; - CountOfLogin = countOfLogin; - CountOfFailedLogin = countOfFailedLogin; - CreatorUserName = creatorUserName; - IsLockedOut = isLockedOut; - SiteIdCollection = siteIdCollection; - SiteId = siteId; - DepartmentId = departmentId; - AreaId = areaId; - _displayName = displayName; - Email = email; - Mobile = mobile; - } - - public int Id { get; set; } - - public string UserName { get; set; } - - public string Password { get; set; } - - public EPasswordFormat PasswordFormat { get; set; } - - public string PasswordSalt { get; set; } - - public DateTime CreationDate { get; set; } - - public DateTime LastActivityDate { get; set; } - - public int CountOfLogin { get; set; } - - public int CountOfFailedLogin { get; set; } - - public string CreatorUserName { get; set; } - - public bool IsLockedOut { get; set; } - - public string SiteIdCollection { get; set; } - - public int SiteId { get; set; } - - public int DepartmentId { get; set; } - - public int AreaId { get; set; } - - public string DisplayName - { - get - { - if (string.IsNullOrEmpty(_displayName)) - { - _displayName = UserName; - } - return _displayName; - } - set { _displayName = value; } - } - - public string Email { get; set; } - - public string Mobile { get; set; } - } -} diff --git a/SiteServer.CMS/Model/AreaInfo.cs b/SiteServer.CMS/Model/AreaInfo.cs deleted file mode 100644 index d34cfb51d..000000000 --- a/SiteServer.CMS/Model/AreaInfo.cs +++ /dev/null @@ -1,49 +0,0 @@ -namespace SiteServer.CMS.Model -{ - public class AreaInfo - { - public AreaInfo() - { - Id = 0; - AreaName = string.Empty; - ParentId = 0; - ParentsPath = string.Empty; - ParentsCount = 0; - ChildrenCount = 0; - IsLastNode = false; - Taxis = 0; - CountOfAdmin = 0; - } - - public AreaInfo(int id, string areaName, int parentId, string parentsPath, int parentsCount, int childrenCount, bool isLastNode, int taxis, int countOfAdmin) - { - Id = id; - AreaName = areaName; - ParentId = parentId; - ParentsPath = parentsPath; - ParentsCount = parentsCount; - ChildrenCount = childrenCount; - IsLastNode = isLastNode; - Taxis = taxis; - CountOfAdmin = countOfAdmin; - } - - public int Id { get; set; } - - public string AreaName { get; set; } - - public int ParentId { get; set; } - - public string ParentsPath { get; set; } - - public int ParentsCount { get; set; } - - public int ChildrenCount { get; set; } - - public bool IsLastNode { get; set; } - - public int Taxis { get; set; } - - public int CountOfAdmin { get; set; } - } -} diff --git a/SiteServer.CMS/Model/BackgroundContentAttribute.cs b/SiteServer.CMS/Model/BackgroundContentAttribute.cs deleted file mode 100644 index 3761be93d..000000000 --- a/SiteServer.CMS/Model/BackgroundContentAttribute.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Collections.Generic; - -namespace SiteServer.CMS.Model -{ - public class BackgroundContentAttribute - { - protected BackgroundContentAttribute() - { - } - - //system - public const string SubTitle = "SubTitle"; - public const string ImageUrl = "ImageUrl"; - public const string VideoUrl = "VideoUrl"; - public const string FileUrl = "FileUrl"; - public const string Author = "Author"; - public const string Source = "Source"; - public const string Summary = "Summary"; - public const string Content = "Content"; - //not exists - public const string TitleFormatString = "TitleFormatString"; - public const string PageContent = "PageContent"; - public const string NavigationUrl = "NavigationUrl"; - public const string CountOfPhotos = "CountOfPhotos"; - - public static List AllAttributes - { - get - { - var list = new List(ContentAttribute.AllAttributesLowercase); - list.AddRange(SystemAttributes); - return list; - } - } - - private static List _systemAttributes; - public static List SystemAttributes => _systemAttributes ?? (_systemAttributes = new List - { - SubTitle.ToLower(), - ImageUrl.ToLower(), - VideoUrl.ToLower(), - FileUrl.ToLower(), - Content.ToLower(), - Author.ToLower(), - Source.ToLower(), - Summary.ToLower() - }); - } -} diff --git a/SiteServer.CMS/Model/ChannelAttribute.cs b/SiteServer.CMS/Model/ChannelAttribute.cs deleted file mode 100644 index 0f3364c80..000000000 --- a/SiteServer.CMS/Model/ChannelAttribute.cs +++ /dev/null @@ -1,106 +0,0 @@ -using SiteServer.CMS.StlParser.Model; - -namespace SiteServer.CMS.Model -{ - public static class ChannelAttribute - { - [StlField(Description = "栏目Id")] - public const string Id = nameof(ChannelInfo.Id); - - [StlField(Description = "栏目名称")] - public const string ChannelName = nameof(ChannelInfo.ChannelName); - - [StlField(Description = "站点Id")] - public const string SiteId = nameof(ChannelInfo.SiteId); - - [StlField(Description = "内容模型插件Id")] - public const string ContentModelPluginId = nameof(ChannelInfo.ContentModelPluginId); - - [StlField(Description = "内容关联插件Id列表")] - public const string ContentRelatedPluginIds = nameof(ChannelInfo.ContentRelatedPluginIds); - - [StlField(Description = "父栏目Id")] - public const string ParentId = nameof(ChannelInfo.ParentId); - - [StlField(Description = "上级栏目路径")] - public const string ParentsPath = nameof(ChannelInfo.ParentsPath); - - [StlField(Description = "上级栏目数量")] - public const string ParentsCount = nameof(ChannelInfo.ParentsCount); - - [StlField(Description = "下级栏目数量")] - public const string ChildrenCount = nameof(ChannelInfo.ChildrenCount); - - [StlField(Description = "是否最后一级栏目")] - public const string IsLastNode = nameof(ChannelInfo.IsLastNode); - - [StlField(Description = "栏目索引")] - public const string IndexName = nameof(ChannelInfo.IndexName); - - [StlField(Description = "栏目组")] - public const string GroupNameCollection = nameof(ChannelInfo.GroupNameCollection); - - [StlField(Description = "栏目排序")] - public const string Taxis = nameof(ChannelInfo.Taxis); - - [StlField(Description = "栏目添加时间")] - public const string AddDate = nameof(ChannelInfo.AddDate); - - [StlField(Description = "栏目图片")] - public const string ImageUrl = nameof(ChannelInfo.ImageUrl); - - [StlField(Description = "栏目正文")] - public const string Content = nameof(ChannelInfo.Content); - - [StlField(Description = "包含内容数")] - public const string ContentNum = nameof(ChannelInfo.ContentNum); - - [StlField(Description = "页面路径")] - public const string FilePath = nameof(ChannelInfo.FilePath); - - [StlField(Description = "下级栏目页面命名规则")] - public const string ChannelFilePathRule = nameof(ChannelInfo.ChannelFilePathRule); - - [StlField(Description = "下级内容页面命名规则")] - public const string ContentFilePathRule = nameof(ChannelInfo.ContentFilePathRule); - - [StlField(Description = "外部链接")] - public const string LinkUrl = nameof(ChannelInfo.LinkUrl); - - [StlField(Description = "链接类型")] - public const string LinkType = nameof(ChannelInfo.LinkType); - - [StlField(Description = "栏目模板Id")] - public const string ChannelTemplateId = nameof(ChannelInfo.ChannelTemplateId); - - [StlField(Description = "内容模板Id")] - public const string ContentTemplateId = nameof(ChannelInfo.ContentTemplateId); - - [StlField(Description = "关键字列表")] - public const string Keywords = nameof(ChannelInfo.Keywords); - - [StlField(Description = "页面描述")] - public const string Description = nameof(ChannelInfo.Description); - - [StlField(Description = "栏目扩展值")] - public const string ExtendValues = nameof(ExtendValues); - - [StlField(Description = "栏目名称")] - public const string Title = nameof(Title); - - [StlField(Description = "栏目索引")] - public const string ChannelIndex = nameof(ChannelIndex); - - [StlField(Description = "栏目正文(翻页)")] - public const string PageContent = nameof(PageContent); - - [StlField(Description = "下级栏目数")] - public const string CountOfChannels = nameof(CountOfChannels); - - [StlField(Description = "包含内容数")] - public const string CountOfContents = nameof(CountOfContents); - - [StlField(Description = "包含图片内容数")] - public const string CountOfImageContents = nameof(CountOfImageContents); - } -} diff --git a/SiteServer.CMS/Model/ChannelGroupInfo.cs b/SiteServer.CMS/Model/ChannelGroupInfo.cs deleted file mode 100644 index 8c529aa3d..000000000 --- a/SiteServer.CMS/Model/ChannelGroupInfo.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace SiteServer.CMS.Model -{ - public class ChannelGroupInfo - { - public ChannelGroupInfo() - { - GroupName = string.Empty; - SiteId = 0; - Taxis = 0; - Description = string.Empty; - } - - public ChannelGroupInfo(string groupName, int siteId, int taxis, string description) - { - GroupName = groupName; - SiteId = siteId; - Taxis = taxis; - Description = description; - } - - public int Id { get; set; } - - public string GroupName { get; set; } - - public int SiteId { get; set; } - - public int Taxis { get; set; } - - public string Description { get; set; } - } -} diff --git a/SiteServer.CMS/Model/ChannelInfo.cs b/SiteServer.CMS/Model/ChannelInfo.cs deleted file mode 100644 index 179b32331..000000000 --- a/SiteServer.CMS/Model/ChannelInfo.cs +++ /dev/null @@ -1,166 +0,0 @@ -using System; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Model -{ - public class ChannelInfo : IChannelInfo - { - private string _extendValues; - - public ChannelInfo() - { - Id = 0; - ChannelName = string.Empty; - SiteId = 0; - ContentModelPluginId = string.Empty; - ContentRelatedPluginIds = string.Empty; - ParentId = 0; - ParentsPath = string.Empty; - ParentsCount = 0; - ChildrenCount = 0; - IsLastNode = false; - IndexName = string.Empty; - GroupNameCollection = string.Empty; - Taxis = 0; - AddDate = DateTime.Now; - ImageUrl = string.Empty; - Content = string.Empty; - ContentNum = 0; - FilePath = string.Empty; - ChannelFilePathRule = string.Empty; - ContentFilePathRule = string.Empty; - LinkUrl = string.Empty; - LinkType = string.Empty; - ChannelTemplateId = 0; - ContentTemplateId = 0; - Keywords = string.Empty; - Description = string.Empty; - _extendValues = string.Empty; - } - - public ChannelInfo(int id, string channelName, int siteId, string contentModelPluginId, string contentRelatedPluginIds, int parentId, string parentsPath, int parentsCount, int childrenCount, bool isLastNode, string indexName, string groupNameCollection, int taxis, DateTime addDate, string imageUrl, string content, int contentNum, string filePath, string channelFilePathRule, string contentFilePathRule, string linkUrl, ELinkType linkType, int channelTemplateId, int contentTemplateId, string keywords, string description, string extendValues) - { - Id = id; - ChannelName = channelName; - SiteId = siteId; - ContentModelPluginId = contentModelPluginId; - ContentRelatedPluginIds = contentRelatedPluginIds; - ParentId = parentId; - ParentsPath = parentsPath; - ParentsCount = parentsCount; - ChildrenCount = childrenCount; - IsLastNode = isLastNode; - IndexName = indexName; - GroupNameCollection = groupNameCollection; - Taxis = taxis; - AddDate = addDate; - ImageUrl = imageUrl; - Content = content; - ContentNum = contentNum; - FilePath = filePath; - ChannelFilePathRule = channelFilePathRule; - ContentFilePathRule = contentFilePathRule; - LinkUrl = linkUrl; - LinkType = ELinkTypeUtils.GetValue(linkType); - ChannelTemplateId = channelTemplateId; - ContentTemplateId = contentTemplateId; - Keywords = keywords; - Description = description; - _extendValues = extendValues; - } - - public ChannelInfo(ChannelInfo channelInfo) - { - Id = channelInfo.Id; - ChannelName = channelInfo.ChannelName; - SiteId = channelInfo.SiteId; - ContentModelPluginId = channelInfo.ContentModelPluginId; - ContentRelatedPluginIds = channelInfo.ContentRelatedPluginIds; - ParentId = channelInfo.ParentId; - ParentsPath = channelInfo.ParentsPath; - ParentsCount = channelInfo.ParentsCount; - ChildrenCount = channelInfo.ChildrenCount; - IsLastNode = channelInfo.IsLastNode; - IndexName = channelInfo.IndexName; - GroupNameCollection = channelInfo.GroupNameCollection; - Taxis = channelInfo.Taxis; - AddDate = channelInfo.AddDate; - ImageUrl = channelInfo.ImageUrl; - Content = channelInfo.Content; - ContentNum = channelInfo.ContentNum; - FilePath = channelInfo.FilePath; - ChannelFilePathRule = channelInfo.ChannelFilePathRule; - ContentFilePathRule = channelInfo.ContentFilePathRule; - LinkUrl = channelInfo.LinkUrl; - LinkType = channelInfo.LinkType; - ChannelTemplateId = channelInfo.ChannelTemplateId; - ContentTemplateId = channelInfo.ContentTemplateId; - Keywords = channelInfo.Keywords; - Description = channelInfo.Description; - _extendValues = channelInfo._extendValues; - } - - public int Id { get; set; } - - public string ChannelName { get; set; } - - public int SiteId { get; set; } - - public string ContentModelPluginId { get; set; } - - public string ContentRelatedPluginIds { get; set; } - - public int ParentId { get; set; } - - public string ParentsPath { get; set; } - - public int ParentsCount { get; set; } - - public int ChildrenCount { get; set; } - - public bool IsLastNode { get; set; } - - public string IndexName { get; set; } - - public string GroupNameCollection { get; set; } - - public int Taxis { get; set; } - - public DateTime AddDate { get; set; } - - public string ImageUrl { get; set; } - - public string Content { get; set; } - - public int ContentNum { get; set; } - - public string FilePath { get; set; } - - public string ChannelFilePathRule { get; set; } - - public string ContentFilePathRule { get; set; } - - public string LinkUrl { get; set; } - - public string LinkType { get; set; } - - public int ChannelTemplateId { get; set; } - - public int ContentTemplateId { get; set; } - - public string Keywords { get; set; } - - public string Description { get; set; } - - public void SetExtendValues(string extendValues) - { - _extendValues = extendValues; - } - - private ChannelInfoExtend _additional; - public ChannelInfoExtend Additional => _additional ?? (_additional = new ChannelInfoExtend(_extendValues)); - - public IAttributes Attributes => Additional; - } -} diff --git a/SiteServer.CMS/Model/ChannelInfoExtend.cs b/SiteServer.CMS/Model/ChannelInfoExtend.cs deleted file mode 100644 index 412891e23..000000000 --- a/SiteServer.CMS/Model/ChannelInfoExtend.cs +++ /dev/null @@ -1,107 +0,0 @@ -using SiteServer.Utils; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Model -{ - public class ChannelInfoExtend : ExtendedAttributes - { - public ChannelInfoExtend(string settings) : base(settings) - { - - } - - //是否可以添加栏目 - public bool IsChannelAddable - { - get { return GetBool("IsChannelAddable", true); } - set { Set("IsChannelAddable", value.ToString()); } - } - - //是否可以添加内容 - public bool IsContentAddable - { - get { return GetBool("IsContentAddable", true); } - set { Set("IsContentAddable", value.ToString()); } - } - - public bool IsChannelCreatable - { - get { return GetBool("IsChannelCreatable", true); } - set { Set("IsChannelCreatable", value.ToString()); } - } - - public bool IsContentCreatable - { - get { return GetBool("IsContentCreatable", true); } - set { Set("IsContentCreatable", value.ToString()); } - } - - public bool IsCreateChannelIfContentChanged - { - get { return GetBool("IsCreateChannelIfContentChanged", true); } - set { Set("IsCreateChannelIfContentChanged", value.ToString()); } - } - - public string CreateChannelIDsIfContentChanged - { - get { return GetString("CreateChannelIDsIfContentChanged"); } - set { Set("CreateChannelIDsIfContentChanged", value); } - } - - public string ContentAttributesOfDisplay - { - get { return GetString("ContentAttributesOfDisplay"); } - set { Set("ContentAttributesOfDisplay", value); } - } - - public ECrossSiteTransType TransType - { - get { return ECrossSiteTransTypeUtils.GetEnumType(GetString("TransType")); } - set { Set("TransType", ECrossSiteTransTypeUtils.GetValue(value)); } - } - - public int TransSiteId - { - get { return TranslateUtils.ToInt(GetString("TransSiteId")); } - set { Set("TransSiteId", value.ToString()); } - } - - public string TransChannelIds - { - get { return GetString("TransChannelIds"); } - set { Set("TransChannelIds", value); } - } - - public string TransChannelNames - { - get { return GetString("TransChannelNames"); } - set { Set("TransChannelNames", value); } - } - - public bool TransIsAutomatic - { - get { return GetBool("TransIsAutomatic"); } - set { Set("TransIsAutomatic", value.ToString()); } - } - - //跨站转发操作类型:复制 引用地址 引用内容 - public ETranslateContentType TransDoneType - { - get { return ETranslateContentTypeUtils.GetEnumType(GetString("TransDoneType")); } - set { Set("TransDoneType", ETranslateContentTypeUtils.GetValue(value)); } - } - - public bool IsPreviewContents - { - get { return GetBool("IsPreviewContents"); } - set { Set("IsPreviewContents", value.ToString()); } - } - - public string DefaultTaxisType - { - get { return GetString("DefaultTaxisType", ETaxisTypeUtils.GetValue(ETaxisType.OrderByTaxisDesc)); } - set { Set("DefaultTaxisType", value); } - } - } -} diff --git a/SiteServer.CMS/Model/ConfigInfo.cs b/SiteServer.CMS/Model/ConfigInfo.cs deleted file mode 100644 index 4f3480c41..000000000 --- a/SiteServer.CMS/Model/ConfigInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System; - -namespace SiteServer.CMS.Model -{ - public class ConfigInfo - { - public ConfigInfo() - { - Id = 0; - IsInitialized = false; - DatabaseVersion = string.Empty; - UpdateDate = DateTime.Now; - SystemConfig = string.Empty; - } - - public ConfigInfo(bool isInitialized, string databaseVersion, DateTime updateDate, string systemConfig) - { - IsInitialized = isInitialized; - DatabaseVersion = databaseVersion; - UpdateDate = updateDate; - SystemConfig = systemConfig; - } - - public int Id { get; set; } - - public bool IsInitialized { get; set; } - - public string DatabaseVersion { get; set; } - - public DateTime UpdateDate { get; set; } - - public string SystemConfig { get; set; } - - private SystemConfigInfo _systemConfigInfo; - public SystemConfigInfo SystemConfigInfo => _systemConfigInfo ?? (_systemConfigInfo = new SystemConfigInfo(SystemConfig)); - } -} diff --git a/SiteServer.CMS/Model/ContentAttribute.cs b/SiteServer.CMS/Model/ContentAttribute.cs deleted file mode 100644 index cae775141..000000000 --- a/SiteServer.CMS/Model/ContentAttribute.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System.Collections.Generic; - -namespace SiteServer.CMS.Model -{ - public class ContentAttribute - { - protected ContentAttribute() - { - } - - public const string Id = nameof(Id); - public const string ChannelId = nameof(ChannelId); - public const string SiteId = nameof(SiteId); - public const string AddUserName = nameof(AddUserName); - public const string LastEditUserName = nameof(LastEditUserName); - public const string WritingUserName = nameof(WritingUserName); - public const string LastEditDate = nameof(LastEditDate); - public const string Taxis = nameof(Taxis); - public const string GroupNameCollection = nameof(GroupNameCollection); - public const string Tags = nameof(Tags); - public const string SourceId = nameof(SourceId); - public const string ReferenceId = nameof(ReferenceId); - public const string IsChecked = nameof(IsChecked); - public const string CheckedLevel = nameof(CheckedLevel); - public const string Hits = nameof(Hits); - public const string HitsByDay = nameof(HitsByDay); - public const string HitsByWeek = nameof(HitsByWeek); - public const string HitsByMonth = nameof(HitsByMonth); - public const string LastHitsDate = nameof(LastHitsDate); - public const string SettingsXml = nameof(SettingsXml); - public const string Title = nameof(Title); - public const string IsTop = nameof(IsTop); - public const string IsRecommend = nameof(IsRecommend); - public const string IsHot = nameof(IsHot); - public const string IsColor = nameof(IsColor); - public const string LinkUrl = nameof(LinkUrl); - public const string AddDate = nameof(AddDate); - - public static string GetFormatStringAttributeName(string attributeName) - { - return attributeName + "FormatString"; - } - - public static string GetExtendAttributeName(string attributeName) - { - return attributeName + "_Extend"; - } - - public const string CheckIsAdmin = "Check_IsAdmin"; //审核者是否为管理员 - public const string CheckUserName = "Check_UserName"; //审核者 - public const string CheckCheckDate = "Check_CheckDate"; //审核时间 - public const string CheckReasons = "Check_Reasons"; //审核原因 - public const string TranslateContentType = "TranslateContentType"; //转移内容类型 - - private static List _allAttributesLowercase; - - public static List AllAttributesLowercase => _allAttributesLowercase ?? (_allAttributesLowercase = new List - { - Id.ToLower(), - ChannelId.ToLower(), - SiteId.ToLower(), - AddUserName.ToLower(), - LastEditUserName.ToLower(), - WritingUserName.ToLower(), - LastEditDate.ToLower(), - Taxis.ToLower(), - GroupNameCollection.ToLower(), - Tags.ToLower(), - SourceId.ToLower(), - ReferenceId.ToLower(), - IsChecked.ToLower(), - CheckedLevel.ToLower(), - Hits.ToLower(), - HitsByDay.ToLower(), - HitsByWeek.ToLower(), - HitsByMonth.ToLower(), - LastHitsDate.ToLower(), - SettingsXml.ToLower(), - Title.ToLower(), - IsTop.ToLower(), - IsRecommend.ToLower(), - IsHot.ToLower(), - IsColor.ToLower(), - LinkUrl.ToLower(), - AddDate.ToLower() - }); - } -} diff --git a/SiteServer.CMS/Model/ContentCheckInfo.cs b/SiteServer.CMS/Model/ContentCheckInfo.cs deleted file mode 100644 index a1988dfd6..000000000 --- a/SiteServer.CMS/Model/ContentCheckInfo.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System; - -namespace SiteServer.CMS.Model -{ - public class ContentCheckInfo - { - public ContentCheckInfo() - { - Id = 0; - TableName = string.Empty; - SiteId = 0; - ChannelId = 0; - ContentId = 0; - IsAdmin = false; - UserName = string.Empty; - IsChecked = false; - CheckedLevel = 0; - CheckDate = DateTime.Now; - Reasons = string.Empty; - } - - public ContentCheckInfo(int id, string tableName, int siteId, int channelId, int contentId, bool isAdmin, string userName, bool isChecked, int checkedLevel, DateTime checkDate, string reasons) - { - Id = id; - TableName = tableName; - SiteId = siteId; - ChannelId = channelId; - ContentId = contentId; - IsAdmin = isAdmin; - UserName = userName; - IsChecked = isChecked; - CheckedLevel = checkedLevel; - CheckDate = checkDate; - Reasons = reasons; - } - - public int Id { get; set; } - - public string TableName { get; set; } - - public int SiteId { get; set; } - - public int ChannelId { get; set; } - - public int ContentId { get; set; } - - public bool IsAdmin { get; set; } - - public string UserName { get; set; } - - public bool IsChecked { get; set; } - - public int CheckedLevel { get; set; } - - public DateTime CheckDate { get; set; } - - public string Reasons { get; set; } - } -} diff --git a/SiteServer.CMS/Model/ContentGroupInfo.cs b/SiteServer.CMS/Model/ContentGroupInfo.cs deleted file mode 100644 index 65718479f..000000000 --- a/SiteServer.CMS/Model/ContentGroupInfo.cs +++ /dev/null @@ -1,31 +0,0 @@ -namespace SiteServer.CMS.Model -{ - public class ContentGroupInfo - { - public ContentGroupInfo() - { - GroupName = string.Empty; - SiteId = 0; - Taxis = 0; - Description = string.Empty; - } - - public ContentGroupInfo(string groupName, int siteId, int taxis, string description) - { - GroupName = groupName; - SiteId = siteId; - Taxis = taxis; - Description = description; - } - - public int Id { get; set; } - - public string GroupName { get; set; } - - public int SiteId { get; set; } - - public int Taxis { get; set; } - - public string Description { get; set; } - } -} diff --git a/SiteServer.CMS/Model/ContentInfo.cs b/SiteServer.CMS/Model/ContentInfo.cs deleted file mode 100644 index 51f63ca5a..000000000 --- a/SiteServer.CMS/Model/ContentInfo.cs +++ /dev/null @@ -1,187 +0,0 @@ -using System; -using System.Data; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Model -{ - public class ContentInfo : ExtendedAttributes, IContentInfo - { - public ContentInfo() - { - - } - - public ContentInfo(object dataItem) : base(dataItem) - { - Load(SettingsXml); - } - - public ContentInfo(IDataReader rdr) : base(rdr) - { - Load(SettingsXml); - } - - public int Id - { - get { return GetInt(ContentAttribute.Id); } - set { Set(ContentAttribute.Id, value.ToString()); } - } - - public int ChannelId - { - get { return GetInt(ContentAttribute.ChannelId); } - set { Set(ContentAttribute.ChannelId, value.ToString()); } - } - - public int SiteId - { - get { return GetInt(ContentAttribute.SiteId); } - set { Set(ContentAttribute.SiteId, value.ToString()); } - } - - public string AddUserName - { - get { return GetString(ContentAttribute.AddUserName); } - set { Set(ContentAttribute.AddUserName, value); } - } - - public string LastEditUserName - { - get { return GetString(ContentAttribute.LastEditUserName); } - set { Set(ContentAttribute.LastEditUserName, value); } - } - - public string WritingUserName - { - get { return GetString(ContentAttribute.WritingUserName); } - set { Set(ContentAttribute.WritingUserName, value); } - } - - public DateTime LastEditDate - { - get { return GetDateTime(ContentAttribute.LastEditDate, DateTime.Now); } - set { Set(ContentAttribute.LastEditDate, DateUtils.GetDateAndTimeString(value)); } - } - - public int Taxis - { - get { return GetInt(ContentAttribute.Taxis); } - set { Set(ContentAttribute.Taxis, value.ToString()); } - } - - public string GroupNameCollection - { - get { return GetString(ContentAttribute.GroupNameCollection); } - set { Set(ContentAttribute.GroupNameCollection, value); } - } - - public string Tags - { - get { return GetString(ContentAttribute.Tags); } - set { Set(ContentAttribute.Tags, value); } - } - - public int SourceId - { - get { return GetInt(ContentAttribute.SourceId); } - set { Set(ContentAttribute.SourceId, value.ToString()); } - } - - public int ReferenceId - { - get { return GetInt(ContentAttribute.ReferenceId); } - set { Set(ContentAttribute.ReferenceId, value.ToString()); } - } - - public bool IsChecked - { - get { return GetBool(ContentAttribute.IsChecked); } - set { Set(ContentAttribute.IsChecked, value.ToString()); } - } - - public int CheckedLevel - { - get { return GetInt(ContentAttribute.CheckedLevel); } - set { Set(ContentAttribute.CheckedLevel, value.ToString()); } - } - - public int Hits - { - get { return GetInt(ContentAttribute.Hits); } - set { Set(ContentAttribute.Hits, value.ToString()); } - } - - public int HitsByDay - { - get { return GetInt(ContentAttribute.HitsByDay); } - set { Set(ContentAttribute.HitsByDay, value.ToString()); } - } - - public int HitsByWeek - { - get { return GetInt(ContentAttribute.HitsByWeek); } - set { Set(ContentAttribute.HitsByWeek, value.ToString()); } - } - - public int HitsByMonth - { - get { return GetInt(ContentAttribute.HitsByMonth); } - set { Set(ContentAttribute.HitsByMonth, value.ToString()); } - } - - public DateTime LastHitsDate - { - get { return GetDateTime(ContentAttribute.LastHitsDate, DateTime.Now); } - set { Set(ContentAttribute.LastHitsDate, DateUtils.GetDateAndTimeString(value)); } - } - - public string Title - { - get { return GetString(ContentAttribute.Title); } - set { Set(ContentAttribute.Title, value); } - } - - public bool IsTop - { - get { return GetBool(ContentAttribute.IsTop); } - set { Set(ContentAttribute.IsTop, value.ToString()); } - } - - public bool IsRecommend - { - get { return GetBool(ContentAttribute.IsRecommend); } - set { Set(ContentAttribute.IsRecommend, value.ToString()); } - } - - public bool IsHot - { - get { return GetBool(ContentAttribute.IsHot); } - set { Set(ContentAttribute.IsHot, value.ToString()); } - } - - public bool IsColor - { - get { return GetBool(ContentAttribute.IsColor); } - set { Set(ContentAttribute.IsColor, value.ToString()); } - } - - public DateTime AddDate - { - get { return GetDateTime(ContentAttribute.AddDate, DateTime.Now); } - set { Set(ContentAttribute.AddDate, DateUtils.GetDateAndTimeString(value)); } - } - - public string LinkUrl - { - get { return GetString(ContentAttribute.LinkUrl); } - set { Set(ContentAttribute.LinkUrl, value); } - } - - public string SettingsXml - { - get { return GetString(ContentAttribute.SettingsXml); } - set { Set(ContentAttribute.SettingsXml, value); } - } - } -} diff --git a/SiteServer.CMS/Model/CountInfo.cs b/SiteServer.CMS/Model/CountInfo.cs deleted file mode 100644 index dc486af94..000000000 --- a/SiteServer.CMS/Model/CountInfo.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace SiteServer.CMS.Model -{ - public class CountInfo - { - public int Id { get; set; } - - public string RelatedTableName { get; set; } - - public string RelatedIdentity { get; set; } - - public string CountType { get; set; } - - public int CountNum { get; set; } - } -} diff --git a/SiteServer.CMS/Model/CreateTaskInfo.cs b/SiteServer.CMS/Model/CreateTaskInfo.cs deleted file mode 100644 index ddea89df7..000000000 --- a/SiteServer.CMS/Model/CreateTaskInfo.cs +++ /dev/null @@ -1,33 +0,0 @@ -using SiteServer.CMS.Model.Enumerations; - -namespace SiteServer.CMS.Model -{ - public class CreateTaskInfo - { - public CreateTaskInfo(int id, string name, ECreateType createType, int siteId, int channelId, int contentId, int templateId, int pageCount) - { - Id = id; - Name = name; - CreateType = createType; - SiteId = siteId; - ChannelId = channelId; - ContentId = contentId; - TemplateId = templateId; - PageCount = pageCount; - } - - public int Id { get; set; } - public string Name { get; set; } - public ECreateType CreateType { get; set; } - public int SiteId { get; set; } - public int ChannelId { get; set; } - public int ContentId { get; set; } - public int TemplateId { get; set; } - public int PageCount { get; set; } - - public bool Equals(CreateTaskInfo taskInfo) - { - return CreateType == taskInfo?.CreateType && SiteId == taskInfo.SiteId && ChannelId == taskInfo.ChannelId && ContentId == taskInfo.ContentId && TemplateId == taskInfo.TemplateId; - } - } -} diff --git a/SiteServer.CMS/Model/CreateTaskLogInfo.cs b/SiteServer.CMS/Model/CreateTaskLogInfo.cs deleted file mode 100644 index 2162e6452..000000000 --- a/SiteServer.CMS/Model/CreateTaskLogInfo.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System; -using SiteServer.CMS.Model.Enumerations; - -namespace SiteServer.CMS.Model -{ - public class CreateTaskLogInfo - { - public CreateTaskLogInfo(int id, ECreateType createType, int siteId, int channelId, int contentId, int templateId, string taskName, string timeSpan, bool isSuccess, string errorMessage, DateTime addDate) - { - Id = id; - CreateType = createType; - SiteId = siteId; - ChannelId = channelId; - ContentId = contentId; - TemplateId = templateId; - TaskName = taskName; - TimeSpan = timeSpan; - IsSuccess = isSuccess; - ErrorMessage = errorMessage; - AddDate = addDate; - } - - public int Id { get; set; } - - public ECreateType CreateType { get; set; } - - public int SiteId { get; set; } - - public int ChannelId { get; set; } - - public int ContentId { get; set; } - - public int TemplateId { get; set; } - - public string TaskName { get; set; } - - public string TimeSpan { get; set; } - - public bool IsSuccess { get; set; } - - public string ErrorMessage { get; set; } - - public DateTime AddDate { get; set; } - } -} diff --git a/SiteServer.CMS/Model/CreateTaskSummary.cs b/SiteServer.CMS/Model/CreateTaskSummary.cs deleted file mode 100644 index 76cbbe7e8..000000000 --- a/SiteServer.CMS/Model/CreateTaskSummary.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System.Collections.Generic; - -namespace SiteServer.CMS.Model -{ - public class CreateTaskSummary - { - public CreateTaskSummary(List tasks, int channelsCount, int contentsCount, int filesCount) - { - Tasks = tasks; - ChannelsCount = channelsCount; - ContentsCount = contentsCount; - FilesCount = filesCount; - } - - public List Tasks { get; set; } - - public int ChannelsCount { get; set; } - - public int ContentsCount { get; set; } - - public int FilesCount { get; set; } - } -} diff --git a/SiteServer.CMS/Model/DepartmentInfo.cs b/SiteServer.CMS/Model/DepartmentInfo.cs deleted file mode 100644 index d6bd4ea24..000000000 --- a/SiteServer.CMS/Model/DepartmentInfo.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System; - -namespace SiteServer.CMS.Model -{ - public class DepartmentInfo - { - public DepartmentInfo() - { - Id = 0; - DepartmentName = string.Empty; - Code = string.Empty; - ParentId = 0; - ParentsPath = string.Empty; - ParentsCount = 0; - ChildrenCount = 0; - IsLastNode = false; - Taxis = 0; - AddDate = DateTime.Now; - Summary = string.Empty; - CountOfAdmin = 0; - } - - public DepartmentInfo(int id, string departmentName, string code, int parentId, string parentsPath, int parentsCount, int childrenCount, bool isLastNode, int taxis, DateTime addDate, string summary, int countOfAdmin) - { - Id = id; - DepartmentName = departmentName; - Code = code; - ParentId = parentId; - ParentsPath = parentsPath; - ParentsCount = parentsCount; - ChildrenCount = childrenCount; - IsLastNode = isLastNode; - Taxis = taxis; - AddDate = addDate; - Summary = summary; - CountOfAdmin = countOfAdmin; - } - - public int Id { get; set; } - - public string DepartmentName { get; set; } - - public string Code { get; set; } - - public int ParentId { get; set; } - - public string ParentsPath { get; set; } - - public int ParentsCount { get; set; } - - public int ChildrenCount { get; set; } - - public bool IsLastNode { get; set; } - - public int Taxis { get; set; } - - public DateTime AddDate { get; set; } - - public string Summary { get; set; } - - public int CountOfAdmin { get; set; } - } -} diff --git a/SiteServer.CMS/Model/Enumerations/EAccessControlEntry.cs b/SiteServer.CMS/Model/Enumerations/EAccessControlEntry.cs deleted file mode 100644 index 757965bb5..000000000 --- a/SiteServer.CMS/Model/Enumerations/EAccessControlEntry.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace SiteServer.CMS.Model.Enumerations -{ - public enum AccessControlEntry - { - NotSet = 0x00, - Allow = 0x01, - Deny = 0x02 - } -} diff --git a/SiteServer.CMS/Model/Enumerations/EBackupType.cs b/SiteServer.CMS/Model/Enumerations/EBackupType.cs deleted file mode 100644 index 04e0bc4f8..000000000 --- a/SiteServer.CMS/Model/Enumerations/EBackupType.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - public enum EBackupType - { - Undefined, - Templates, //模板页 - ChannelsAndContents, //栏目及内容 - Files, //文件 - Site, //整站 - } - - public class EBackupTypeUtils - { - public static string GetValue(EBackupType type) - { - if (type == EBackupType.Templates) - { - return "Templates"; - } - if (type == EBackupType.ChannelsAndContents) - { - return "ChannelsAndContents"; - } - if (type == EBackupType.Files) - { - return "Files"; - } - if (type == EBackupType.Site) - { - return "Site"; - } - return "Undefined"; - } - - public static string GetText(EBackupType type) - { - if (type == EBackupType.Templates) - { - return "显示模板"; - } - if (type == EBackupType.ChannelsAndContents) - { - return "栏目及内容"; - } - if (type == EBackupType.Files) - { - return "文件"; - } - if (type == EBackupType.Site) - { - return "整站"; - } - - return "Undefined"; - } - - public static EBackupType GetEnumType(string typeStr) - { - var retval = EBackupType.Undefined; - - if (Equals(EBackupType.Templates, typeStr)) - { - retval = EBackupType.Templates; - } - else if (Equals(EBackupType.ChannelsAndContents, typeStr)) - { - retval = EBackupType.ChannelsAndContents; - } - else if (Equals(EBackupType.Files, typeStr)) - { - retval = EBackupType.Files; - } - else if (Equals(EBackupType.Site, typeStr)) - { - retval = EBackupType.Site; - } - - return retval; - } - - public static bool Equals(EBackupType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EBackupType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(EBackupType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EBackupType.Templates, false)); - listControl.Items.Add(GetListItem(EBackupType.ChannelsAndContents, false)); - listControl.Items.Add(GetListItem(EBackupType.Files, false)); - listControl.Items.Add(GetListItem(EBackupType.Site, false)); - } - } - - } -} diff --git a/SiteServer.CMS/Model/Enumerations/ECreateType.cs b/SiteServer.CMS/Model/Enumerations/ECreateType.cs deleted file mode 100644 index 575f7ffbd..000000000 --- a/SiteServer.CMS/Model/Enumerations/ECreateType.cs +++ /dev/null @@ -1,119 +0,0 @@ -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - public enum ECreateType - { - None, - Channel, - Content, - File, - AllContent - } - - public class ECreateTypeUtils - { - public static string GetValue(ECreateType type) - { - if (type == ECreateType.Channel) - { - return "Channel"; - } - if (type == ECreateType.Content) - { - return "Content"; - } - if (type == ECreateType.File) - { - return "File"; - } - if (type == ECreateType.AllContent) - { - return "AllContent"; - } - return string.Empty; - } - - public static ECreateType GetEnumType(string typeStr) - { - var retval = ECreateType.None; - - if (Equals(ECreateType.Channel, typeStr)) - { - retval = ECreateType.Channel; - } - else if (Equals(ECreateType.Content, typeStr)) - { - retval = ECreateType.Content; - } - else if (Equals(ECreateType.File, typeStr)) - { - retval = ECreateType.File; - } - else if (Equals(ECreateType.AllContent, typeStr)) - { - retval = ECreateType.AllContent; - } - - return retval; - } - - public static string GetText(ECreateType createType) - { - if (createType == ECreateType.Channel) - { - return "栏目页"; - } - if (createType == ECreateType.Content) - { - return "内容页"; - } - if (createType == ECreateType.File) - { - return "文件页"; - } - if (createType == ECreateType.AllContent) - { - return "栏目下所有内容页"; - } - - return string.Empty; - } - - public static bool Equals(ECreateType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, ECreateType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(ECreateType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(ECreateType.Channel, false)); - listControl.Items.Add(GetListItem(ECreateType.Content, false)); - listControl.Items.Add(GetListItem(ECreateType.File, false)); - } - } - - } -} diff --git a/SiteServer.CMS/Model/Enumerations/ECrossSiteTransType.cs b/SiteServer.CMS/Model/Enumerations/ECrossSiteTransType.cs deleted file mode 100644 index f6f987131..000000000 --- a/SiteServer.CMS/Model/Enumerations/ECrossSiteTransType.cs +++ /dev/null @@ -1,159 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - public enum ECrossSiteTransType - { - None, - SelfSite, - SpecifiedSite, - ParentSite, - AllParentSite, - AllSite - } - - public class ECrossSiteTransTypeUtils - { - public static string GetValue(ECrossSiteTransType type) - { - if (type == ECrossSiteTransType.None) - { - return "None"; - } - if (type == ECrossSiteTransType.SelfSite) - { - return "SelfSite"; - } - if (type == ECrossSiteTransType.SpecifiedSite) - { - return "SpecifiedSite"; - } - if (type == ECrossSiteTransType.ParentSite) - { - return "ParentSite"; - } - if (type == ECrossSiteTransType.AllParentSite) - { - return "AllParentSite"; - } - if (type == ECrossSiteTransType.AllSite) - { - return "AllSite"; - } - throw new Exception(); - } - - public static string GetText(ECrossSiteTransType type) - { - if (type == ECrossSiteTransType.None) - { - return "不转发"; - } - if (type == ECrossSiteTransType.SelfSite) - { - return "可向本站转发"; - } - if (type == ECrossSiteTransType.SpecifiedSite) - { - return "可向指定站点转发"; - } - if (type == ECrossSiteTransType.ParentSite) - { - return "可向上一级站点转发"; - } - if (type == ECrossSiteTransType.AllParentSite) - { - return "可向所有上级站点转发"; - } - if (type == ECrossSiteTransType.AllSite) - { - return "可向所有站点转发"; - } - throw new Exception(); - } - - public static ECrossSiteTransType GetEnumType(string typeStr) - { - var retval = ECrossSiteTransType.AllSite; - - if (Equals(ECrossSiteTransType.None, typeStr)) - { - retval = ECrossSiteTransType.None; - } - else if (Equals(ECrossSiteTransType.SelfSite, typeStr)) - { - retval = ECrossSiteTransType.SelfSite; - } - else if (Equals(ECrossSiteTransType.SpecifiedSite, typeStr)) - { - retval = ECrossSiteTransType.SpecifiedSite; - } - else if (Equals(ECrossSiteTransType.ParentSite, typeStr)) - { - retval = ECrossSiteTransType.ParentSite; - } - else if (Equals(ECrossSiteTransType.AllParentSite, typeStr)) - { - retval = ECrossSiteTransType.AllParentSite; - } - else if (Equals(ECrossSiteTransType.AllSite, typeStr)) - { - retval = ECrossSiteTransType.AllSite; - } - - return retval; - } - - public static bool Equals(ECrossSiteTransType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, ECrossSiteTransType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(ECrossSiteTransType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl == null) return; - - listControl.Items.Add(GetListItem(ECrossSiteTransType.None, false)); - listControl.Items.Add(GetListItem(ECrossSiteTransType.SelfSite, false)); - listControl.Items.Add(GetListItem(ECrossSiteTransType.ParentSite, false)); - listControl.Items.Add(GetListItem(ECrossSiteTransType.AllParentSite, false)); - listControl.Items.Add(GetListItem(ECrossSiteTransType.AllSite, false)); - } - - public static void AddAllListItems(ListControl listControl, bool isParentSite) - { - if (listControl == null) return; - - listControl.Items.Add(GetListItem(ECrossSiteTransType.None, false)); - listControl.Items.Add(GetListItem(ECrossSiteTransType.SelfSite, false)); - listControl.Items.Add(GetListItem(ECrossSiteTransType.SpecifiedSite, false)); - if (isParentSite) - { - listControl.Items.Add(GetListItem(ECrossSiteTransType.ParentSite, false)); - listControl.Items.Add(GetListItem(ECrossSiteTransType.AllParentSite, false)); - } - listControl.Items.Add(GetListItem(ECrossSiteTransType.AllSite, false)); - } - } -} diff --git a/SiteServer.CMS/Model/Enumerations/EExceptionType.cs b/SiteServer.CMS/Model/Enumerations/EExceptionType.cs deleted file mode 100644 index f11c99df9..000000000 --- a/SiteServer.CMS/Model/Enumerations/EExceptionType.cs +++ /dev/null @@ -1,89 +0,0 @@ -namespace SiteServer.CMS.Model.Enumerations -{ - - public enum EExceptionType - { - DataProvider = 0, - AdministrationAccessDenied = 1, - PostEditAccessDenied = 2, - ModerateAccessDenied = 3, - PostDuplicate = 4, - FileNotFound = 5, - SectionNotFound = 6, - PostPendingModeration = 8, - PostNotFound = 9, - PostIDParameterNotSpecified = 10, - PostProblem = 11, - CreateUser = 36, - UserAccountCreated = 7, - UserAccountPending = 23, - UserAccountCreatedAuto = 24, - UserAccountDisapproved = 25, - UserAccountBanned = 26, - UserProfileUpdated = 13, - UserAccountInvalid = 74, - UserNotFound = 14, - UserPasswordChangeSuccess = 15, - UserPasswordChangeFailed = 16, - UserInvalidCredentials = 17, - ForumNoUnansweredPosts = 18, - PrivateMessagesDisabledByUser = 19, - UserSearchNotFound = 20, - ForumNoActivePosts = 21, - PrivateMessageToSelfNotAllowd = 22, - UserUnknownLoginError = 27, - EmailUnableToSend = 28, - UserAccountRegistrationDisabled = 29, - UserLoginDisabled = 30, - AccessDenied = 31, - PostAccessDenied = 32, - GroupNotFound = 33, - EmailTemplateNotFound = 34, - SearchUnknownError = 35, - PostReplyAccessDenied = 36, - PostAnnounceAccessDenied = 37, - PostEditPermissionExpired = 38, - PostLocked = 39, - PostDeletePermissionExpired = 40, - PostDeleteAccessDenied = 41, - SkinNotSet = 42, - SkinNotFound = 43, - ReturnURLRequired = 44, - SearchNoResults = 45, - PostInvalidAttachmentType = 46, - GeneralAccessDenied = 47, - EmailSentToUser = 48, - PostAttachmentTooLarge = 49, - PostAttachmentsNotAllowed = 50, - UserPasswordAnswerChangeSuccess = 51, - UserPasswordAnswerChangeFailed = 52, - RoleNotFound = 53, - RoleUpdated = 54, - RoleDeleted = 55, - RoleOperationUnavailable = 56, - ResourceNotFound = 57, - PostCategoryNotFound = 58, - WeblogNotFound = 59, - WeblogPostNotFound = 60, - PermissionApplicationUnknown = 61, - RedirectFailure = 62, - UnRegisteredSite = 63, - SiteUrlDataProvider = 64, - FloodDenied = 65, - SiteSettingsInvalidXML = 66, - PostDeleteAccessDeniedHasReplies = 67, - ForumNoUnreadPosts = 68, - UserPasswordResetSuccess = 69, - UserPasswordLinkSentSuccess = 72, - UnKnownProvider = 70, - UserAlreadyLoggedIn = 73, - InvalidLicense = 75, - LicenseAccessError = 76, - - ApplicationStart = 997, - ApplicationStop = 998, - - UnknownError = 999 - } - -} diff --git a/SiteServer.CMS/Model/Enumerations/EFrequencyType.cs b/SiteServer.CMS/Model/Enumerations/EFrequencyType.cs deleted file mode 100644 index dcccbb8ba..000000000 --- a/SiteServer.CMS/Model/Enumerations/EFrequencyType.cs +++ /dev/null @@ -1,164 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - public enum EFrequencyType - { - Month, //每月一次 - Week, //每周一次 - Day, //每天一次 - Hour, //每小时一次 - Period, //每周期一次 - JustInTime, //实时监控 - OnlyOnce //只做一次 - } - - public class EFrequencyTypeUtils - { - public static string GetValue(EFrequencyType type) - { - if (type == EFrequencyType.Month) - { - return "Month"; - } - if (type == EFrequencyType.Week) - { - return "Week"; - } - if (type == EFrequencyType.Day) - { - return "Day"; - } - if (type == EFrequencyType.Hour) - { - return "Hour"; - } - if (type == EFrequencyType.Period) - { - return "Period"; - } - if (type == EFrequencyType.JustInTime) - { - return "JustInTime"; - } - if (type == EFrequencyType.OnlyOnce) - { - return "OnlyOnce"; - } - throw new Exception(); - } - - public static string GetText(EFrequencyType type) - { - if (type == EFrequencyType.Month) - { - return "每月一次"; - } - if (type == EFrequencyType.Week) - { - return "每周一次"; - } - if (type == EFrequencyType.Day) - { - return "每天一次"; - } - if (type == EFrequencyType.Hour) - { - return "每小时一次"; - } - if (type == EFrequencyType.Period) - { - return "每周期一次"; - } - if (type == EFrequencyType.JustInTime) - { - return "实时监控"; - } - if (type == EFrequencyType.OnlyOnce) - { - return "只执行一次"; - } - throw new Exception(); - } - - public static EFrequencyType GetEnumType(string typeStr) - { - var retval = EFrequencyType.Month; - - if (Equals(EFrequencyType.Month, typeStr)) - { - retval = EFrequencyType.Month; - } - else if (Equals(EFrequencyType.Week, typeStr)) - { - retval = EFrequencyType.Week; - } - else if (Equals(EFrequencyType.Day, typeStr)) - { - retval = EFrequencyType.Day; - } - else if (Equals(EFrequencyType.Hour, typeStr)) - { - retval = EFrequencyType.Hour; - } - else if (Equals(EFrequencyType.Period, typeStr)) - { - retval = EFrequencyType.Period; - } - else if (Equals(EFrequencyType.JustInTime, typeStr)) - { - retval = EFrequencyType.JustInTime; - } - else if (Equals(EFrequencyType.OnlyOnce, typeStr)) - { - retval = EFrequencyType.OnlyOnce; - } - - return retval; - } - - public static bool Equals(EFrequencyType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EFrequencyType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(EFrequencyType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl, bool withJustInTime) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EFrequencyType.Month, false)); - listControl.Items.Add(GetListItem(EFrequencyType.Week, false)); - listControl.Items.Add(GetListItem(EFrequencyType.Day, false)); - listControl.Items.Add(GetListItem(EFrequencyType.Hour, false)); - listControl.Items.Add(GetListItem(EFrequencyType.Period, false)); - //listControl.Items.Add(GetListItem(EFrequencyType.OnlyOnce, false)); - if (withJustInTime) - { - listControl.Items.Add(GetListItem(EFrequencyType.JustInTime, false)); - } - } - } - - } -} diff --git a/SiteServer.CMS/Model/Enumerations/EGatherType.cs b/SiteServer.CMS/Model/Enumerations/EGatherType.cs deleted file mode 100644 index e51edac54..000000000 --- a/SiteServer.CMS/Model/Enumerations/EGatherType.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - public enum EGatherType - { - Undefined, - Web, //Web页面 - Database, //数据库 - File //单文件页 - } - - public class EGatherTypeUtils - { - public static string GetValue(EGatherType type) - { - if (type == EGatherType.Web) - { - return "Web"; - } - if (type == EGatherType.Database) - { - return "Database"; - } - if (type == EGatherType.File) - { - return "File"; - } - return "Undefined"; - } - - public static string GetText(EGatherType type) - { - if (type == EGatherType.Web) - { - return "Web页面"; - } - if (type == EGatherType.Database) - { - return "数据库"; - } - if (type == EGatherType.File) - { - return "单文件页"; - } - - return "Undefined"; - } - - public static EGatherType GetEnumType(string typeStr) - { - var retval = EGatherType.Undefined; - - if (Equals(EGatherType.Web, typeStr)) - { - retval = EGatherType.Web; - } - else if (Equals(EGatherType.Database, typeStr)) - { - retval = EGatherType.Database; - } - else if (Equals(EGatherType.File, typeStr)) - { - retval = EGatherType.File; - } - - return retval; - } - - public static bool Equals(EGatherType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EGatherType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(EGatherType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EGatherType.Web, false)); - listControl.Items.Add(GetListItem(EGatherType.Database, false)); - listControl.Items.Add(GetListItem(EGatherType.File, false)); - } - } - - } -} diff --git a/SiteServer.CMS/Model/Enumerations/EImportExportType.cs b/SiteServer.CMS/Model/Enumerations/EImportExportType.cs deleted file mode 100644 index 5974d2ede..000000000 --- a/SiteServer.CMS/Model/Enumerations/EImportExportType.cs +++ /dev/null @@ -1,124 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - /// - /// 导入导出元素类型 - /// - public enum EImportExportType - { - Template, - DisplayMode, - MenuDisplay, - Vote, - //DataList, - //SiteContent, - } - - public class EImportExportTypeUtils - { - public static string GetValue(EImportExportType type) - { - if (type == EImportExportType.Template) - { - return "Template"; - } - if (type == EImportExportType.DisplayMode) - { - return "DisplayMode"; - } - if (type == EImportExportType.MenuDisplay) - { - return "MenuDisplay"; - } - if (type == EImportExportType.Vote) - { - return "Vote"; - } - throw new Exception(); - } - - public static string GetText(EImportExportType type) - { - if (type == EImportExportType.Template) - { - return "网站模板"; - } - if (type == EImportExportType.DisplayMode) - { - return "列表显示方式"; - } - if (type == EImportExportType.MenuDisplay) - { - return "菜单显示方式"; - } - if (type == EImportExportType.Vote) - { - return "投票项数据"; - } - throw new Exception(); - } - - public static EImportExportType GetEnumType(string typeStr) - { - var retval = EImportExportType.Template; - - if (Equals(EImportExportType.Template, typeStr)) - { - retval = EImportExportType.Template; - } - else if (Equals(EImportExportType.DisplayMode, typeStr)) - { - retval = EImportExportType.DisplayMode; - } - else if (Equals(EImportExportType.MenuDisplay, typeStr)) - { - retval = EImportExportType.MenuDisplay; - } - else if (Equals(EImportExportType.Vote, typeStr)) - { - retval = EImportExportType.Vote; - } - - return retval; - } - - public static bool Equals(EImportExportType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EImportExportType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(EImportExportType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EImportExportType.Template, false)); - listControl.Items.Add(GetListItem(EImportExportType.DisplayMode, false)); - listControl.Items.Add(GetListItem(EImportExportType.MenuDisplay, false)); - listControl.Items.Add(GetListItem(EImportExportType.Vote, false)); - } - } - - } -} diff --git a/SiteServer.CMS/Model/Enumerations/EKeywordGrade.cs b/SiteServer.CMS/Model/Enumerations/EKeywordGrade.cs deleted file mode 100644 index 83ec10fed..000000000 --- a/SiteServer.CMS/Model/Enumerations/EKeywordGrade.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - public enum EKeywordGrade - { - Normal, //一般 - Sensitive, //比较敏感 - Dangerous //危险 - } - - public class EKeywordGradeUtils - { - public static string GetValue(EKeywordGrade type) - { - if (type == EKeywordGrade.Normal) - { - return "Normal"; - } - if (type == EKeywordGrade.Sensitive) - { - return "Sensitive"; - } - if (type == EKeywordGrade.Dangerous) - { - return "Dangerous"; - } - throw new Exception(); - } - - public static string GetText(EKeywordGrade type) - { - if (type == EKeywordGrade.Normal) - { - return "一般"; - } - if (type == EKeywordGrade.Sensitive) - { - return "比较敏感"; - } - if (type == EKeywordGrade.Dangerous) - { - return "危险"; - } - throw new Exception(); - } - - public static EKeywordGrade GetEnumType(string typeStr) - { - var retval = EKeywordGrade.Normal; - - if (Equals(EKeywordGrade.Normal, typeStr)) - { - retval = EKeywordGrade.Normal; - } - else if (Equals(EKeywordGrade.Sensitive, typeStr)) - { - retval = EKeywordGrade.Sensitive; - } - else if (Equals(EKeywordGrade.Dangerous, typeStr)) - { - retval = EKeywordGrade.Dangerous; - } - - return retval; - } - - public static bool Equals(EKeywordGrade type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EKeywordGrade type) - { - return Equals(type, typeStr); - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - var item = new ListItem(GetText(EKeywordGrade.Normal), GetValue(EKeywordGrade.Normal)); - listControl.Items.Add(item); - item = new ListItem(GetText(EKeywordGrade.Sensitive), GetValue(EKeywordGrade.Sensitive)); - listControl.Items.Add(item); - item = new ListItem(GetText(EKeywordGrade.Dangerous), GetValue(EKeywordGrade.Dangerous)); - listControl.Items.Add(item); - } - } - } -} diff --git a/SiteServer.CMS/Model/Enumerations/ELayout.cs b/SiteServer.CMS/Model/Enumerations/ELayout.cs deleted file mode 100644 index 6e9707e5b..000000000 --- a/SiteServer.CMS/Model/Enumerations/ELayout.cs +++ /dev/null @@ -1,106 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - - public enum ELayout - { - Table, //表格 - Flow, //流 - None, //无布局 - } - - public class ELayoutUtils - { - public static string GetValue(ELayout type) - { - if (type == ELayout.Table) - { - return "Table"; - } - if (type == ELayout.Flow) - { - return "Flow"; - } - if (type == ELayout.None) - { - return "None"; - } - throw new Exception(); - } - - public static string GetText(ELayout type) - { - if (type == ELayout.Table) - { - return "表格"; - } - if (type == ELayout.Flow) - { - return "流"; - } - if (type == ELayout.None) - { - return "无布局"; - } - throw new Exception(); - } - - public static ELayout GetEnumType(string typeStr) - { - var retval = ELayout.None; - - if (Equals(ELayout.Table, typeStr)) - { - retval = ELayout.Table; - } - else if (Equals(ELayout.Flow, typeStr)) - { - retval = ELayout.Flow; - } - else if (Equals(ELayout.None, typeStr)) - { - retval = ELayout.None; - } - - return retval; - } - - public static bool Equals(ELayout type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, ELayout type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(ELayout type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(ELayout.Table, false)); - listControl.Items.Add(GetListItem(ELayout.Flow, false)); - listControl.Items.Add(GetListItem(ELayout.None, false)); - } - } - - } -} diff --git a/SiteServer.CMS/Model/Enumerations/ELinkType.cs b/SiteServer.CMS/Model/Enumerations/ELinkType.cs deleted file mode 100644 index e824e0873..000000000 --- a/SiteServer.CMS/Model/Enumerations/ELinkType.cs +++ /dev/null @@ -1,267 +0,0 @@ -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - - public enum ELinkType - { - None, //默认 - NoLinkIfContentNotExists, //无内容时不可链接 - LinkToOnlyOneContent, //仅一条内容时链接到此内容 - NoLinkIfContentNotExistsAndLinkToOnlyOneContent, //无内容时不可链接,仅一条内容时链接到此内容 - LinkToFirstContent, //链接到第一条内容 - NoLinkIfContentNotExistsAndLinkToFirstContent, //无内容时不可链接,有内容时链接到第一条内容 - NoLinkIfChannelNotExists, //无栏目时不可链接 - LinkToLastAddChannel, //链接到最近增加的子栏目 - LinkToFirstChannel, //链接到第一个子栏目 - NoLinkIfChannelNotExistsAndLinkToLastAddChannel, //无栏目时不可链接,有栏目时链接到最近增加的子栏目 - NoLinkIfChannelNotExistsAndLinkToFirstChannel, //无栏目时不可链接,有栏目时链接到第一个子栏目 - NoLink //不可链接 - } - - public class ELinkTypeUtils - { - public static string GetValue(ELinkType type) - { - if (type == ELinkType.NoLinkIfContentNotExists) - { - return "NoLinkIfContentNotExists"; - } - if (type == ELinkType.LinkToOnlyOneContent) - { - return "LinkToOnlyOneContent"; - } - if (type == ELinkType.NoLinkIfContentNotExistsAndLinkToOnlyOneContent) - { - return "NoLinkIfContentNotExistsAndLinkToOnlyOneContent"; - } - if (type == ELinkType.LinkToFirstContent) - { - return "LinkToFirstContent"; - } - if (type == ELinkType.NoLinkIfContentNotExistsAndLinkToFirstContent) - { - return "NoLinkIfContentNotExistsAndLinkToFirstContent"; - } - if (type == ELinkType.NoLinkIfChannelNotExists) - { - return "NoLinkIfChannelNotExists"; - } - if (type == ELinkType.LinkToLastAddChannel) - { - return "LinkToLastAddChannel"; - } - if (type == ELinkType.LinkToFirstChannel) - { - return "LinkToFirstChannel"; - } - if (type == ELinkType.NoLinkIfChannelNotExistsAndLinkToLastAddChannel) - { - return "NoLinkIfChannelNotExistsAndLinkToLastAddChannel"; - } - if (type == ELinkType.NoLinkIfChannelNotExistsAndLinkToFirstChannel) - { - return "NoLinkIfChannelNotExistsAndLinkToFirstChannel"; - } - if (type == ELinkType.NoLink) - { - return "NoLink"; - } - - return "None"; - } - - public static string GetText(ELinkType type) - { - if (type == ELinkType.NoLinkIfContentNotExists) - { - return "无内容时不可链接"; - } - if (type == ELinkType.LinkToOnlyOneContent) - { - return "仅一条内容时链接到此内容"; - } - if (type == ELinkType.NoLinkIfContentNotExistsAndLinkToOnlyOneContent) - { - return "无内容时不可链接,仅一条内容时链接到此内容"; - } - if (type == ELinkType.LinkToFirstContent) - { - return "链接到第一条内容"; - } - if (type == ELinkType.NoLinkIfContentNotExistsAndLinkToFirstContent) - { - return "无内容时不可链接,有内容时链接到第一条内容"; - } - if (type == ELinkType.NoLinkIfChannelNotExists) - { - return "无栏目时不可链接"; - } - if (type == ELinkType.LinkToLastAddChannel) - { - return "链接到最近增加的子栏目"; - } - if (type == ELinkType.LinkToFirstChannel) - { - return "链接到第一个子栏目"; - } - if (type == ELinkType.NoLinkIfChannelNotExistsAndLinkToLastAddChannel) - { - return "无栏目时不可链接,有栏目时链接到最近增加的子栏目"; - } - if (type == ELinkType.NoLinkIfChannelNotExistsAndLinkToFirstChannel) - { - return "无栏目时不可链接,有栏目时链接到第一个子栏目"; - } - if (type == ELinkType.NoLink) - { - return "不可链接"; - } - - return "默认"; - } - - public static ELinkType GetEnumType(string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return ELinkType.None; - - var retval = ELinkType.None; - - if (Equals(ELinkType.NoLinkIfContentNotExists, typeStr)) - { - retval = ELinkType.NoLinkIfContentNotExists; - } - else if (Equals(ELinkType.LinkToOnlyOneContent, typeStr)) - { - retval = ELinkType.LinkToOnlyOneContent; - } - else if (Equals(ELinkType.NoLinkIfContentNotExistsAndLinkToOnlyOneContent, typeStr)) - { - retval = ELinkType.NoLinkIfContentNotExistsAndLinkToOnlyOneContent; - } - else if (Equals(ELinkType.LinkToFirstContent, typeStr)) - { - retval = ELinkType.LinkToFirstContent; - } - else if (Equals(ELinkType.NoLinkIfContentNotExistsAndLinkToFirstContent, typeStr)) - { - retval = ELinkType.NoLinkIfContentNotExistsAndLinkToFirstContent; - } - else if (Equals(ELinkType.NoLinkIfChannelNotExists, typeStr)) - { - retval = ELinkType.NoLinkIfChannelNotExists; - } - else if (Equals(ELinkType.LinkToLastAddChannel, typeStr)) - { - retval = ELinkType.LinkToLastAddChannel; - } - else if (Equals(ELinkType.LinkToFirstChannel, typeStr)) - { - retval = ELinkType.LinkToFirstChannel; - } - else if (Equals(ELinkType.NoLinkIfChannelNotExistsAndLinkToLastAddChannel, typeStr)) - { - retval = ELinkType.NoLinkIfChannelNotExistsAndLinkToLastAddChannel; - } - else if (Equals(ELinkType.NoLinkIfChannelNotExistsAndLinkToFirstChannel, typeStr)) - { - retval = ELinkType.NoLinkIfChannelNotExistsAndLinkToFirstChannel; - } - else if (Equals(ELinkType.NoLink, typeStr)) - { - retval = ELinkType.NoLink; - } - - return retval; - } - - public static bool Equals(ELinkType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, ELinkType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(ELinkType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl == null) return; - - listControl.Items.Add(GetListItem(ELinkType.None, false)); - listControl.Items.Add(GetListItem(ELinkType.NoLinkIfContentNotExists, false)); - listControl.Items.Add(GetListItem(ELinkType.LinkToOnlyOneContent, false)); - listControl.Items.Add(GetListItem(ELinkType.NoLinkIfContentNotExistsAndLinkToOnlyOneContent, false)); - listControl.Items.Add(GetListItem(ELinkType.LinkToFirstContent, false)); - listControl.Items.Add(GetListItem(ELinkType.NoLinkIfContentNotExistsAndLinkToFirstContent, false)); - listControl.Items.Add(GetListItem(ELinkType.NoLinkIfChannelNotExists, false)); - listControl.Items.Add(GetListItem(ELinkType.LinkToLastAddChannel, false)); - listControl.Items.Add(GetListItem(ELinkType.LinkToFirstChannel, false)); - listControl.Items.Add(GetListItem(ELinkType.NoLinkIfChannelNotExistsAndLinkToLastAddChannel, false)); - listControl.Items.Add(GetListItem(ELinkType.NoLinkIfChannelNotExistsAndLinkToFirstChannel, false)); - listControl.Items.Add(GetListItem(ELinkType.NoLink, false)); - } - - public static bool IsCreatable(ChannelInfo channelInfo) - { - var isCreatable = false; - - var linkType = GetEnumType(channelInfo.LinkType); - - if (linkType == ELinkType.None) - { - isCreatable = true; - } - else if (linkType == ELinkType.NoLinkIfContentNotExists) - { - isCreatable = channelInfo.ContentNum != 0; - } - else if (linkType == ELinkType.LinkToOnlyOneContent) - { - isCreatable = channelInfo.ContentNum != 1; - } - else if (linkType == ELinkType.NoLinkIfContentNotExistsAndLinkToOnlyOneContent) - { - if (channelInfo.ContentNum != 0 && channelInfo.ContentNum != 1) - { - isCreatable = true; - } - } - else if (linkType == ELinkType.LinkToFirstContent) - { - isCreatable = channelInfo.ContentNum < 1; - } - else if (linkType == ELinkType.NoLinkIfChannelNotExists) - { - isCreatable = channelInfo.ChildrenCount != 0; - } - else if (linkType == ELinkType.LinkToLastAddChannel) - { - isCreatable = channelInfo.ChildrenCount <= 0; - } - else if (linkType == ELinkType.LinkToFirstChannel) - { - isCreatable = channelInfo.ChildrenCount <= 0; - } - - return isCreatable; - } - - } -} diff --git a/SiteServer.CMS/Model/Enumerations/EPositionType.cs b/SiteServer.CMS/Model/Enumerations/EPositionType.cs deleted file mode 100644 index 0f562b887..000000000 --- a/SiteServer.CMS/Model/Enumerations/EPositionType.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - public enum EPositionType - { - LeftTop, //左上 - LeftBottom, //左下 - RightTop, //右上 - RightBottom //右下 - } - - public class EPositionTypeUtils - { - public static string GetValue(EPositionType type) - { - if (type == EPositionType.LeftTop) - { - return "LeftTop"; - } - if (type == EPositionType.LeftBottom) - { - return "LeftBottom"; - } - if (type == EPositionType.RightTop) - { - return "RightTop"; - } - if (type == EPositionType.RightBottom) - { - return "RightBottom"; - } - throw new Exception(); - } - - public static string GetText(EPositionType type) - { - if (type == EPositionType.LeftTop) - { - return "左上"; - } - if (type == EPositionType.LeftBottom) - { - return "左下"; - } - if (type == EPositionType.RightTop) - { - return "右上"; - } - if (type == EPositionType.RightBottom) - { - return "右下"; - } - throw new Exception(); - } - - public static EPositionType GetEnumType(string typeStr) - { - var retval = EPositionType.LeftTop; - - if (Equals(EPositionType.LeftTop, typeStr)) - { - retval = EPositionType.LeftTop; - } - else if (Equals(EPositionType.LeftBottom, typeStr)) - { - retval = EPositionType.LeftBottom; - } - else if (Equals(EPositionType.RightTop, typeStr)) - { - retval = EPositionType.RightTop; - } - else if (Equals(EPositionType.RightBottom, typeStr)) - { - retval = EPositionType.RightBottom; - } - - return retval; - } - - public static bool Equals(EPositionType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EPositionType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(EPositionType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl, ERollingType rollingType) - { - if (listControl != null) - { - if (rollingType == ERollingType.Static) - { - listControl.Items.Add(GetListItem(EPositionType.LeftTop, false)); - listControl.Items.Add(GetListItem(EPositionType.LeftBottom, false)); - listControl.Items.Add(GetListItem(EPositionType.RightTop, false)); - listControl.Items.Add(GetListItem(EPositionType.RightBottom, false)); - } - else if (rollingType == ERollingType.FollowingScreen) - { - listControl.Items.Add(GetListItem(EPositionType.LeftBottom, false)); - listControl.Items.Add(GetListItem(EPositionType.RightBottom, false)); - } - else if (rollingType == ERollingType.FloatingInWindow) - { - listControl.Items.Add(GetListItem(EPositionType.LeftTop, false)); - } - } - } - - } -} diff --git a/SiteServer.CMS/Model/Enumerations/EProgressType.cs b/SiteServer.CMS/Model/Enumerations/EProgressType.cs deleted file mode 100644 index 90d353be3..000000000 --- a/SiteServer.CMS/Model/Enumerations/EProgressType.cs +++ /dev/null @@ -1,61 +0,0 @@ -using System; - -namespace SiteServer.CMS.Model.Enumerations -{ - public enum EProgressType - { - CreateChannels, - CreateContents, - } - - public class EProgressTypeUtils - { - public static string GetValue(EProgressType type) - { - if (type == EProgressType.CreateChannels) - { - return "CreateChannels"; - } - if (type == EProgressType.CreateContents) - { - return "CreateContents"; - } - throw new Exception(); - } - - public static EProgressType GetEnumType(string typeStr) - { - var retval = EProgressType.CreateChannels; - - if (Equals(EProgressType.CreateChannels, typeStr)) - { - retval = EProgressType.CreateChannels; - } - else if (Equals(EProgressType.CreateContents, typeStr)) - { - retval = EProgressType.CreateContents; - } - - return retval; - } - - public static bool Equals(EProgressType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EProgressType type) - { - return Equals(type, typeStr); - } - - public const string CACHE_TOTAL_COUNT = "_TotalCount"; - public const string CACHE_CURRENT_COUNT = "_CurrentCount"; - public const string CACHE_MESSAGE = "_Message"; - } -} diff --git a/SiteServer.CMS/Model/Enumerations/ERelatedFieldStyle.cs b/SiteServer.CMS/Model/Enumerations/ERelatedFieldStyle.cs deleted file mode 100644 index 968f169c6..000000000 --- a/SiteServer.CMS/Model/Enumerations/ERelatedFieldStyle.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - - public enum ERelatedFieldStyle - { - Horizontal, //水平显示 - Virtical, //垂直显示 - } - - public class ERelatedFieldStyleUtils - { - public static string GetValue(ERelatedFieldStyle type) - { - if (type == ERelatedFieldStyle.Horizontal) - { - return "Horizontal"; - } - if (type == ERelatedFieldStyle.Virtical) - { - return "Virtical"; - } - throw new Exception(); - } - - public static string GetText(ERelatedFieldStyle type) - { - if (type == ERelatedFieldStyle.Horizontal) - { - return "水平显示"; - } - if (type == ERelatedFieldStyle.Virtical) - { - return "垂直显示"; - } - throw new Exception(); - } - - public static ERelatedFieldStyle GetEnumType(string typeStr) - { - var retval = ERelatedFieldStyle.Horizontal; - - if (Equals(ERelatedFieldStyle.Horizontal, typeStr)) - { - retval = ERelatedFieldStyle.Horizontal; - } - else if (Equals(ERelatedFieldStyle.Virtical, typeStr)) - { - retval = ERelatedFieldStyle.Virtical; - } - - return retval; - } - - public static bool Equals(ERelatedFieldStyle type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, ERelatedFieldStyle type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(ERelatedFieldStyle type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(ERelatedFieldStyle.Horizontal, false)); - listControl.Items.Add(GetListItem(ERelatedFieldStyle.Virtical, false)); - } - } - - } -} diff --git a/SiteServer.CMS/Model/Enumerations/ERollingType.cs b/SiteServer.CMS/Model/Enumerations/ERollingType.cs deleted file mode 100644 index 5c7d2445f..000000000 --- a/SiteServer.CMS/Model/Enumerations/ERollingType.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - /// - /// FloatDivInfo 滚动方式 - /// - public enum ERollingType - { - Static, //静止不动 - FollowingScreen, //跟随窗体滚动 - FloatingInWindow //在窗体中不断移动 - } - - public class ERollingTypeUtils - { - public static string GetValue(ERollingType type) - { - if (type == ERollingType.Static) - { - return "Static"; - } - if (type == ERollingType.FollowingScreen) - { - return "FollowingScreen"; - } - if (type == ERollingType.FloatingInWindow) - { - return "FloatingInWindow"; - } - throw new Exception(); - } - - public static string GetText(ERollingType type) - { - if (type == ERollingType.Static) - { - return "静止不动"; - } - if (type == ERollingType.FollowingScreen) - { - return "跟随窗体滚动"; - } - if (type == ERollingType.FloatingInWindow) - { - return "在窗体中不断移动"; - } - throw new Exception(); - } - - public static ERollingType GetEnumType(string typeStr) - { - var retval = ERollingType.Static; - - if (Equals(ERollingType.Static, typeStr)) - { - retval = ERollingType.Static; - } - else if (Equals(ERollingType.FollowingScreen, typeStr)) - { - retval = ERollingType.FollowingScreen; - } - else if (Equals(ERollingType.FloatingInWindow, typeStr)) - { - retval = ERollingType.FloatingInWindow; - } - - return retval; - } - - public static bool Equals(ERollingType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, ERollingType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(ERollingType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(ERollingType.Static, false)); - listControl.Items.Add(GetListItem(ERollingType.FollowingScreen, false)); - listControl.Items.Add(GetListItem(ERollingType.FloatingInWindow, false)); - } - } - - } -} diff --git a/SiteServer.CMS/Model/Enumerations/ESearchEngineType.cs b/SiteServer.CMS/Model/Enumerations/ESearchEngineType.cs deleted file mode 100644 index 1758e90a7..000000000 --- a/SiteServer.CMS/Model/Enumerations/ESearchEngineType.cs +++ /dev/null @@ -1,161 +0,0 @@ -using System; -using System.Collections; -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - - public enum ESearchEngineType - { - Baidu, //百度 - Google_CN, //Google(简体中文) - Google, //Google - Yahoo, //Yahoo - Live, //Live - Sogou, //搜狗 - } - - public class ESearchEngineTypeUtils - { - public static string GetValue(ESearchEngineType type) - { - if (type == ESearchEngineType.Baidu) - { - return "Baidu"; - } - if (type == ESearchEngineType.Google) - { - return "Google"; - } - if (type == ESearchEngineType.Google_CN) - { - return "Google_CN"; - } - if (type == ESearchEngineType.Live) - { - return "Live"; - } - if (type == ESearchEngineType.Sogou) - { - return "Sogou"; - } - if (type == ESearchEngineType.Yahoo) - { - return "Yahoo"; - } - throw new Exception(); - } - - public static string GetText(ESearchEngineType type) - { - if (type == ESearchEngineType.Baidu) - { - return "百度"; - } - if (type == ESearchEngineType.Google_CN) - { - return "Google(简体中文)"; - } - if (type == ESearchEngineType.Google) - { - return "Google(全部语言)"; - } - if (type == ESearchEngineType.Yahoo) - { - return "Yahoo"; - } - if (type == ESearchEngineType.Live) - { - return "Live 搜索"; - } - if (type == ESearchEngineType.Sogou) - { - return "搜狗"; - } - throw new Exception(); - } - - public static ESearchEngineType GetEnumType(string typeStr) - { - var retval = ESearchEngineType.Baidu; - - if (Equals(ESearchEngineType.Baidu, typeStr)) - { - retval = ESearchEngineType.Baidu; - } - else if (Equals(ESearchEngineType.Google, typeStr)) - { - retval = ESearchEngineType.Google; - } - else if (Equals(ESearchEngineType.Google_CN, typeStr)) - { - retval = ESearchEngineType.Google_CN; - } - else if (Equals(ESearchEngineType.Live, typeStr)) - { - retval = ESearchEngineType.Live; - } - else if (Equals(ESearchEngineType.Sogou, typeStr)) - { - retval = ESearchEngineType.Sogou; - } - else if (Equals(ESearchEngineType.Yahoo, typeStr)) - { - retval = ESearchEngineType.Yahoo; - } - - return retval; - } - - public static bool Equals(ESearchEngineType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, ESearchEngineType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(ESearchEngineType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(ESearchEngineType.Baidu, false)); - listControl.Items.Add(GetListItem(ESearchEngineType.Google_CN, false)); - listControl.Items.Add(GetListItem(ESearchEngineType.Google, false)); - listControl.Items.Add(GetListItem(ESearchEngineType.Yahoo, false)); - listControl.Items.Add(GetListItem(ESearchEngineType.Live, false)); - listControl.Items.Add(GetListItem(ESearchEngineType.Sogou, false)); - } - } - - public static ArrayList GetSearchEngineTypeArrayList() - { - var arraylist = new ArrayList(); - arraylist.Add(ESearchEngineType.Baidu); - arraylist.Add(ESearchEngineType.Google_CN); - arraylist.Add(ESearchEngineType.Google); - arraylist.Add(ESearchEngineType.Yahoo); - arraylist.Add(ESearchEngineType.Live); - arraylist.Add(ESearchEngineType.Sogou); - return arraylist; - } - - } -} diff --git a/SiteServer.CMS/Model/Enumerations/ESigninPriority.cs b/SiteServer.CMS/Model/Enumerations/ESigninPriority.cs deleted file mode 100644 index 7f553404f..000000000 --- a/SiteServer.CMS/Model/Enumerations/ESigninPriority.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - public enum ESigninPriority - { - Lower, //低 - Normal, //普通 - High //高 - } - - public class ESigninPriorityUtils - { - public static string GetValue(ESigninPriority type) - { - if (type == ESigninPriority.Lower) - { - return "1"; - } - if (type == ESigninPriority.Normal) - { - return "2"; - } - if (type == ESigninPriority.High) - { - return "3"; - } - throw new Exception(); - } - - public static string GetText(ESigninPriority type) - { - if (type == ESigninPriority.Lower) - { - return "低"; - } - if (type == ESigninPriority.Normal) - { - return "普通"; - } - if (type == ESigninPriority.High) - { - return "高"; - } - throw new Exception(); - } - - public static ESigninPriority GetEnumType(string typeStr) - { - var retval = ESigninPriority.Lower; - - if (Equals(ESigninPriority.Lower, typeStr)) - { - retval = ESigninPriority.Lower; - } - else if (Equals(ESigninPriority.Normal, typeStr)) - { - retval = ESigninPriority.Normal; - } - else if (Equals(ESigninPriority.High, typeStr)) - { - retval = ESigninPriority.High; - } - - return retval; - } - - public static bool Equals(ESigninPriority type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - var item = new ListItem(GetText(ESigninPriority.Lower), GetValue(ESigninPriority.Lower)); - listControl.Items.Add(item); - item = new ListItem(GetText(ESigninPriority.Normal), GetValue(ESigninPriority.Normal)); - listControl.Items.Add(item); - item = new ListItem(GetText(ESigninPriority.High), GetValue(ESigninPriority.High)); - listControl.Items.Add(item); - } - } - } -} diff --git a/SiteServer.CMS/Model/Enumerations/EStatisticsInputType.cs b/SiteServer.CMS/Model/Enumerations/EStatisticsInputType.cs deleted file mode 100644 index d3a32bea8..000000000 --- a/SiteServer.CMS/Model/Enumerations/EStatisticsInputType.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - /// - /// by 20160225 sofuny 可统计分析的表单类型 - /// - public enum EStatisticsInputType - { - Text, - CheckBox, - Radio, - SelectOne, - } - - public class EStatisticsInputTypeUtils - { - public static string GetValue(EStatisticsInputType type) - { - if (type == EStatisticsInputType.Text) - { - return "Text"; - } - if (type == EStatisticsInputType.CheckBox) - { - return "CheckBox"; - } - if (type == EStatisticsInputType.Radio) - { - return "Radio"; - } - if (type == EStatisticsInputType.SelectOne) - { - return "SelectOne"; - } - throw new Exception(); - } - - public static string GetText(EStatisticsInputType type) - { - if (type == EStatisticsInputType.Text) - { - return "文本框(单行)"; - } - if (type == EStatisticsInputType.CheckBox) - { - return "复选列表(checkbox)"; - } - if (type == EStatisticsInputType.Radio) - { - return "单选列表(radio)"; - } - if (type == EStatisticsInputType.SelectOne) - { - return "下拉列表(select单选)"; - } - throw new Exception(); - } - - public static EStatisticsInputType GetEnumType(string typeStr) - { - var retval = EStatisticsInputType.Text; - - if (Equals(EStatisticsInputType.Text, typeStr)) - { - retval = EStatisticsInputType.Text; - } - else if (Equals(EStatisticsInputType.CheckBox, typeStr)) - { - retval = EStatisticsInputType.CheckBox; - } - else if (Equals(EStatisticsInputType.Radio, typeStr)) - { - retval = EStatisticsInputType.Radio; - } - else if (Equals(EStatisticsInputType.SelectOne, typeStr)) - { - retval = EStatisticsInputType.SelectOne; - } - - return retval; - } - - public static bool Equals(EStatisticsInputType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EStatisticsInputType type) - { - return Equals(type, typeStr); - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EStatisticsInputType.Text, false)); - listControl.Items.Add(GetListItem(EStatisticsInputType.CheckBox, false)); - listControl.Items.Add(GetListItem(EStatisticsInputType.Radio, false)); - listControl.Items.Add(GetListItem(EStatisticsInputType.SelectOne, false)); - } - } - - public static ListItem GetListItem(EStatisticsInputType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - } -} diff --git a/SiteServer.CMS/Model/Enumerations/ETranslateContentType.cs b/SiteServer.CMS/Model/Enumerations/ETranslateContentType.cs deleted file mode 100644 index 910cf490f..000000000 --- a/SiteServer.CMS/Model/Enumerations/ETranslateContentType.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - public enum ETranslateContentType - { - Copy, //复制 - Cut, //剪切 - Reference, //引用地址 - ReferenceContent, //引用内容 - } - - public class ETranslateContentTypeUtils - { - public static string GetValue(ETranslateContentType type) - { - if (type == ETranslateContentType.Copy) - { - return "Copy"; - } - if (type == ETranslateContentType.Cut) - { - return "Cut"; - } - if (type == ETranslateContentType.Reference) - { - return "Reference"; - } - if (type == ETranslateContentType.ReferenceContent) - { - return "ReferenceContent"; - } - throw new Exception(); - } - - public static string GetText(ETranslateContentType type) - { - if (type == ETranslateContentType.Copy) - { - return "复制"; - } - if (type == ETranslateContentType.Cut) - { - return "剪切"; - } - if (type == ETranslateContentType.Reference) - { - return "引用地址"; - } - if (type == ETranslateContentType.ReferenceContent) - { - return "引用内容"; - } - throw new Exception(); - } - - public static ETranslateContentType GetEnumType(string typeStr) - { - var retval = ETranslateContentType.Copy; - - if (Equals(ETranslateContentType.Copy, typeStr)) - { - retval = ETranslateContentType.Copy; - } - else if (Equals(ETranslateContentType.Cut, typeStr)) - { - retval = ETranslateContentType.Cut; - } - else if (Equals(ETranslateContentType.Reference, typeStr)) - { - retval = ETranslateContentType.Reference; - } - else if (Equals(ETranslateContentType.ReferenceContent, typeStr)) - { - retval = ETranslateContentType.ReferenceContent; - } - - return retval; - } - - public static bool Equals(ETranslateContentType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, ETranslateContentType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(ETranslateContentType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl, bool isCut) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(ETranslateContentType.Copy, false)); - if (isCut) - { - listControl.Items.Add(GetListItem(ETranslateContentType.Cut, false)); - } - listControl.Items.Add(GetListItem(ETranslateContentType.Reference, false)); - listControl.Items.Add(GetListItem(ETranslateContentType.ReferenceContent, false)); - } - } - } -} diff --git a/SiteServer.CMS/Model/Enumerations/ETranslateType.cs b/SiteServer.CMS/Model/Enumerations/ETranslateType.cs deleted file mode 100644 index 87428c584..000000000 --- a/SiteServer.CMS/Model/Enumerations/ETranslateType.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - /// - /// 批量转移类型 - /// - public enum ETranslateType - { - Content, //仅转移内容 - Channel, //仅转移栏目 - All //转移栏目及内容 - } - - public class ETranslateTypeUtils - { - public static string GetValue(ETranslateType type) - { - if (type == ETranslateType.Content) - { - return "Content"; - } - if (type == ETranslateType.Channel) - { - return "Channel"; - } - if (type == ETranslateType.All) - { - return "All"; - } - throw new Exception(); - } - - public static string GetText(ETranslateType type) - { - if (type == ETranslateType.Content) - { - return "仅转移内容"; - } - if (type == ETranslateType.Channel) - { - return "仅转移栏目"; - } - if (type == ETranslateType.All) - { - return "转移栏目及内容"; - } - throw new Exception(); - } - - public static ETranslateType GetEnumType(string typeStr) - { - var retval = ETranslateType.Content; - - if (Equals(ETranslateType.Content, typeStr)) - { - retval = ETranslateType.Content; - } - else if (Equals(ETranslateType.Channel, typeStr)) - { - retval = ETranslateType.Channel; - } - else if (Equals(ETranslateType.All, typeStr)) - { - retval = ETranslateType.All; - } - - return retval; - } - - public static bool Equals(ETranslateType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, ETranslateType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(ETranslateType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(ETranslateType.Content, false)); - listControl.Items.Add(GetListItem(ETranslateType.Channel, false)); - listControl.Items.Add(GetListItem(ETranslateType.All, false)); - } - } - - } -} diff --git a/SiteServer.CMS/Model/Enumerations/EWriteBackMethod.cs b/SiteServer.CMS/Model/Enumerations/EWriteBackMethod.cs deleted file mode 100644 index 1d5a63f15..000000000 --- a/SiteServer.CMS/Model/Enumerations/EWriteBackMethod.cs +++ /dev/null @@ -1,120 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.Model.Enumerations -{ - - public enum EWriteBackMethod - { - None, //不需要回复 - ByWriteBackField, //使用前台表字段回复 - ByEmail, //使用电子邮件回复 - All //两种回复方式均可 - } - - public class EWriteBackMethodUtils - { - public static string GetValue(EWriteBackMethod type) - { - if (type == EWriteBackMethod.None) - { - return "None"; - } - if (type == EWriteBackMethod.ByWriteBackField) - { - return "ByWriteBackField"; - } - if (type == EWriteBackMethod.ByEmail) - { - return "ByEmail"; - } - if (type == EWriteBackMethod.All) - { - return "All"; - } - throw new Exception(); - } - - public static string GetText(EWriteBackMethod type) - { - if (type == EWriteBackMethod.None) - { - return "不回复信息"; - } - if (type == EWriteBackMethod.ByWriteBackField) - { - return "直接回复信息"; - } - if (type == EWriteBackMethod.ByEmail) - { - return "通过邮件回复信息"; - } - if (type == EWriteBackMethod.All) - { - return "同时使用两种回复方式"; - } - throw new Exception(); - } - - public static EWriteBackMethod GetEnumType(string typeStr) - { - EWriteBackMethod retval = EWriteBackMethod.None; - - if (Equals(EWriteBackMethod.None, typeStr)) - { - retval = EWriteBackMethod.None; - } - else if (Equals(EWriteBackMethod.ByWriteBackField, typeStr)) - { - retval = EWriteBackMethod.ByWriteBackField; - } - else if (Equals(EWriteBackMethod.ByEmail, typeStr)) - { - retval = EWriteBackMethod.ByEmail; - } - else if (Equals(EWriteBackMethod.All, typeStr)) - { - retval = EWriteBackMethod.All; - } - - return retval; - } - - public static bool Equals(EWriteBackMethod type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EWriteBackMethod type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(EWriteBackMethod type, bool selected) - { - ListItem item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EWriteBackMethod.None, false)); - listControl.Items.Add(GetListItem(EWriteBackMethod.ByWriteBackField, false)); - listControl.Items.Add(GetListItem(EWriteBackMethod.ByEmail, false)); - listControl.Items.Add(GetListItem(EWriteBackMethod.All, false)); - } - } - - } -} diff --git a/SiteServer.CMS/Model/ErrorLogInfo.cs b/SiteServer.CMS/Model/ErrorLogInfo.cs deleted file mode 100644 index 930ca625b..000000000 --- a/SiteServer.CMS/Model/ErrorLogInfo.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; - -namespace SiteServer.CMS.Model -{ - public class ErrorLogInfo - { - public ErrorLogInfo() - { - Id = 0; - PluginId = string.Empty; - Message = string.Empty; - Stacktrace = string.Empty; - Summary = string.Empty; - AddDate = DateTime.Now; - } - - public ErrorLogInfo(int id, string pluginId, string message, string stacktrace, string summary, DateTime addDate) - { - Id = id; - PluginId = pluginId; - Message = message; - Stacktrace = stacktrace; - Summary = summary; - AddDate = addDate; - } - - public int Id { get; set; } - - public string PluginId { get; set; } - - public string Message { get; set; } - - public string Stacktrace { get; set; } - - public string Summary { get; set; } - - public DateTime AddDate { get; set; } - } -} diff --git a/SiteServer.CMS/Model/ExtendedAttributes.cs b/SiteServer.CMS/Model/ExtendedAttributes.cs deleted file mode 100644 index 5bcf6b992..000000000 --- a/SiteServer.CMS/Model/ExtendedAttributes.cs +++ /dev/null @@ -1,326 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Data; -using System.Text; -using System.Web.UI; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Model -{ - /// - /// Provides standard implementation for simple extendent data storage - /// - [Serializable] - public class ExtendedAttributes : IAttributes - { - private object _dataObj; - private readonly NameValueCollection _dataNvc = new NameValueCollection(); - - public ExtendedAttributes() - { - } - - public ExtendedAttributes(object dataItem) - { - Load(dataItem); - } - - public ExtendedAttributes(IDataReader rdr) - { - Load(rdr); - } - - public ExtendedAttributes(NameValueCollection attributes) - { - Load(attributes); - } - - public ExtendedAttributes(string str) - { - Load(str); - } - - public void Load(object dataItem) - { - _dataObj = dataItem; - } - - public void Load(IDataReader rdr) - { - if (rdr == null) return; - - for (var i = 0; i < rdr.FieldCount; i++) - { - var name = rdr.GetName(i); - var value = Convert.ToString(rdr.GetValue(i)); - if (WebConfigUtils.DatabaseType == DatabaseType.Oracle && value == SqlUtils.OracleEmptyValue) - { - value = string.Empty; - } - Set(name, value); - } - } - - public void Load(NameValueCollection attributes) - { - if (attributes == null) return; - - foreach (string name in attributes) - { - var value = attributes[name]; - Set(name, value); - } - } - - public void Load(string str) - { - if (string.IsNullOrEmpty(str)) return; - - var nameValues = Utils.ToNameValueCollection(str); - foreach (string key in nameValues.Keys) - { - Set(key, nameValues[key]); - } - } - - public string Get(string name) - { - name = name.ToLower(); - var returnValue = _dataNvc[name]; - - if (string.IsNullOrEmpty(returnValue) && _dataObj != null) - { - var obj = Utils.Eval(_dataObj, name); - if (obj != null) - { - if (obj is string) - { - returnValue = _dataNvc[name] = obj as string; - if (WebConfigUtils.DatabaseType == DatabaseType.Oracle && returnValue == SqlUtils.OracleEmptyValue) - { - returnValue = string.Empty; - } - } - else - { - returnValue = _dataNvc[name] = obj.ToString(); - } - } - } - - return returnValue; - } - - public string GetString(string name, string defaultValue = "") - { - var value = Get(name); - if (!string.IsNullOrEmpty(value)) - { - value = Utils.UnFilterSql(value); - } - return string.IsNullOrEmpty(value) ? defaultValue : value; - } - - public bool GetBool(string name, bool defaultValue = false) - { - name = name.ToLower(); - var value = Get(name); - return string.IsNullOrWhiteSpace(value) ? defaultValue : TranslateUtils.ToBool(value, defaultValue); - } - - public int GetInt(string name, int defaultValue = 0) - { - name = name.ToLower(); - var value = Get(name); - return string.IsNullOrWhiteSpace(value) ? defaultValue : TranslateUtils.ToIntWithNagetive(value, defaultValue); - } - - public decimal GetDecimal(string name, decimal defaultValue = 0) - { - name = name.ToLower(); - var value = Get(name); - return string.IsNullOrWhiteSpace(value) ? defaultValue : TranslateUtils.ToDecimalWithNagetive(value, defaultValue); - } - - public DateTime GetDateTime(string name, DateTime defaultValue) - { - name = name.ToLower(); - var value = Get(name); - return string.IsNullOrWhiteSpace(value) ? defaultValue : TranslateUtils.ToDateTime(value, defaultValue); - } - - public void Remove(string name) - { - name = name.ToLower(); - _dataNvc.Remove(name); - } - - public void Set(string name, object value) - { - name = name.ToLower(); - - if (value == null) - { - _dataNvc.Remove(name); - } - else - { - _dataNvc[name] = value.ToString(); - } - } - - public bool ContainsKey(string name) - { - name = name.ToLower(); - var returnValue = _dataNvc[name]; - - if (returnValue == null && _dataObj != null) - { - var obj = Utils.Eval(_dataObj, name); - if (obj != null) - { - if (obj is string) - { - returnValue = _dataNvc[name] = obj as string; - if (WebConfigUtils.DatabaseType == DatabaseType.Oracle && returnValue == SqlUtils.OracleEmptyValue) - { - returnValue = string.Empty; - } - } - else - { - returnValue = _dataNvc[name] = obj.ToString(); - } - } - } - - return returnValue != null; - } - - public override string ToString() - { - if (_dataNvc != null && _dataNvc.Count > 0) - { - return Utils.NameValueCollectionToString(_dataNvc); - } - return string.Empty; - } - - public string ToString(List lowerCaseExcludeAttributeNames) - { - if (_dataNvc == null || _dataNvc.Count <= 0 || lowerCaseExcludeAttributeNames == null) - return string.Empty; - - var nvc = new NameValueCollection(); - foreach (string key in _dataNvc.Keys) - { - if (!lowerCaseExcludeAttributeNames.Contains(key)) - { - nvc[key] = _dataNvc[key]; - } - } - return Utils.NameValueCollectionToString(nvc); - } - - public NameValueCollection ToNameValueCollection() - { - return new NameValueCollection(_dataNvc); - } - - #region private utils - - private static class Utils - { - public static object Eval(object dataItem, string name) - { - object o = null; - try - { - o = DataBinder.Eval(dataItem, name); - } - catch - { - // ignored - } - if (o == DBNull.Value) - { - o = null; - } - return o; - } - - public static string UnFilterSql(string objStr) - { - if (string.IsNullOrEmpty(objStr)) return string.Empty; - - return objStr.Replace("_sqlquote_", "'").Replace("_sqldoulbeline_", "--").Replace("_sqlleftparenthesis_", "\\(").Replace("_sqlrightparenthesis_", "\\)"); - } - - public static string NameValueCollectionToString(NameValueCollection attributes, char seperator = '&') - { - if (attributes == null || attributes.Count <= 0) return string.Empty; - - var builder = new StringBuilder(); - foreach (string key in attributes.Keys) - { - builder.Append( - $@"{ValueToUrl(key)}={ValueToUrl(attributes[key])}{seperator}"); - } - builder.Length--; - return builder.ToString(); - } - - private static string ValueToUrl(string value) - { - var retval = string.Empty; - if (!string.IsNullOrEmpty(value)) - { - retval = value.Replace("=", "_equals_").Replace("&", "_and_").Replace("?", "_question_").Replace("'", "_quote_").Replace("+", "_add_").Replace("\r", "_return_").Replace("\n", "_newline_"); - } - return retval; - } - - private static string ValueFromUrl(string value) - { - var retval = string.Empty; - if (!string.IsNullOrEmpty(value)) - { - retval = value.Replace("_equals_", "=").Replace("_and_", "&").Replace("_question_", "?").Replace("_quote_", "'").Replace("_add_", "+").Replace("_return_", "\r").Replace("_newline_", "\n"); - } - return retval; - } - - public static NameValueCollection ToNameValueCollection(string separateString) - { - if (!string.IsNullOrEmpty(separateString)) - { - separateString = separateString.Replace("/u0026", "&"); - } - return ToNameValueCollection(separateString, '&'); - } - - private static NameValueCollection ToNameValueCollection(string separateString, char seperator) - { - var attributes = new NameValueCollection(); - if (!string.IsNullOrEmpty(separateString)) - { - var pairs = separateString.Split(seperator); - foreach (var pair in pairs) - { - if (pair.IndexOf("=", StringComparison.Ordinal) != -1) - { - var name = ValueFromUrl(pair.Split('=')[0]); - var value = ValueFromUrl(pair.Split('=')[1]); - attributes.Add(name.ToLower(), value); - } - } - } - return attributes; - } - } - - #endregion private utils - } -} diff --git a/SiteServer.CMS/Model/IntegrationPayConfig.cs b/SiteServer.CMS/Model/IntegrationPayConfig.cs deleted file mode 100644 index 3912db984..000000000 --- a/SiteServer.CMS/Model/IntegrationPayConfig.cs +++ /dev/null @@ -1,38 +0,0 @@ -using Newtonsoft.Json; - -namespace SiteServer.CMS.Model -{ - [JsonObject(MemberSerialization.OptOut)] - public class IntegrationPayConfig - { - public bool IsAlipayPc { get; set; } - public bool AlipayPcIsMApi { get; set; } - public string AlipayPcAppId { get; set; } - public string AlipayPcPid { get; set; } - public string AlipayPcMd5 { get; set; } - public string AlipayPcPublicKey { get; set; } - public string AlipayPcPrivateKey { get; set; } - - public bool IsAlipayMobi { get; set; } - public bool AlipayMobiIsMApi { get; set; } - public string AlipayMobiAppId { get; set; } - public string AlipayMobiPid { get; set; } - public string AlipayMobiMd5 { get; set; } - public string AlipayMobiPublicKey { get; set; } - public string AlipayMobiPrivateKey { get; set; } - - public bool IsWeixin { get; set; } - public string WeixinAppId { get; set; } - public string WeixinAppSecret { get; set; } - public string WeixinMchId { get; set; } - public string WeixinKey { get; set; } - - public bool IsJdpay { get; set; } - public string JdpayMerchant { get; set; } - public string JdpayUserId { get; set; } - public string JdpayMd5Key { get; set; } - public string JdpayDesKey { get; set; } - public string JdpayPublicKey { get; set; } - public string JdpayPrivateKey { get; set; } - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Model/KeywordInfo.cs b/SiteServer.CMS/Model/KeywordInfo.cs deleted file mode 100644 index f8ac440d8..000000000 --- a/SiteServer.CMS/Model/KeywordInfo.cs +++ /dev/null @@ -1,31 +0,0 @@ -using SiteServer.CMS.Model.Enumerations; - -namespace SiteServer.CMS.Model -{ - public class KeywordInfo - { - public KeywordInfo() - { - Id = 0; - Keyword = string.Empty; - Alternative = string.Empty; - Grade = EKeywordGrade.Normal; - } - - public KeywordInfo(int id, string keyword, string alternative, EKeywordGrade grade) - { - Id = id; - Keyword = keyword; - Alternative = alternative; - Grade = grade; - } - - public int Id { get; set; } - - public string Keyword { get; set; } - - public string Alternative { get; set; } - - public EKeywordGrade Grade { get; set; } - } -} diff --git a/SiteServer.CMS/Model/LogInfo.cs b/SiteServer.CMS/Model/LogInfo.cs deleted file mode 100644 index 5cb1ade90..000000000 --- a/SiteServer.CMS/Model/LogInfo.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Model -{ - public class LogInfo: ILogInfo - { - public const string AdminLogin = "后台管理员登录"; - - public LogInfo() - { - Id = 0; - UserName = string.Empty; - IpAddress = string.Empty; - AddDate = DateTime.Now; - Action = string.Empty; - Summary = string.Empty; - } - - public LogInfo(int id, string userName, string ipAddress, DateTime addDate, string action, string summary) - { - Id = id; - UserName = userName; - IpAddress = ipAddress; - AddDate = addDate; - Action = action; - Summary = summary; - } - - public int Id { get; set; } - - public string UserName { get; set; } - - public string IpAddress { get; set; } - - public DateTime AddDate { get; set; } - - public string Action { get; set; } - - public string Summary { get; set; } - } -} diff --git a/SiteServer.CMS/Model/PermissionsInRolesInfo.cs b/SiteServer.CMS/Model/PermissionsInRolesInfo.cs deleted file mode 100644 index b559887e2..000000000 --- a/SiteServer.CMS/Model/PermissionsInRolesInfo.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; - -namespace SiteServer.CMS.Model -{ - [Serializable] - public class PermissionsInRolesInfo - { - private int _id; - private string _roleName; - private string _generalPermissions; - - public PermissionsInRolesInfo() - { - _id = 0; - _roleName = string.Empty; - _generalPermissions = string.Empty; - } - - public PermissionsInRolesInfo(int id, string roleName, string generalPermissions) - { - _id = id; - _roleName = roleName; - _generalPermissions = generalPermissions; - } - - public int Id - { - get { return _id; } - set { _id = value; } - } - - public string RoleName - { - get{ return _roleName; } - set{ _roleName = value; } - } - - public string GeneralPermissions - { - get{ return _generalPermissions; } - set{ _generalPermissions = value; } - } - } -} diff --git a/SiteServer.CMS/Model/PluginConfigInfo.cs b/SiteServer.CMS/Model/PluginConfigInfo.cs deleted file mode 100644 index 669b0dfcb..000000000 --- a/SiteServer.CMS/Model/PluginConfigInfo.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace SiteServer.CMS.Model -{ - public class PluginConfigInfo - { - public PluginConfigInfo() - { - Id = 0; - PluginId = string.Empty; - SiteId = 0; - ConfigName = string.Empty; - ConfigValue = string.Empty; - } - - public PluginConfigInfo(int id, string pluginId, int siteId, string configName, string configValue) - { - Id = id; - PluginId = pluginId; - SiteId = siteId; - ConfigName = configName; - ConfigValue = configValue; - } - - public int Id { get; set; } - - public string PluginId { get; set; } - - public int SiteId { get; set; } - - public string ConfigName { get; set; } - - public string ConfigValue { get; set; } - } -} diff --git a/SiteServer.CMS/Model/RelatedFieldlInfo.cs b/SiteServer.CMS/Model/RelatedFieldlInfo.cs deleted file mode 100644 index a2bbb4b26..000000000 --- a/SiteServer.CMS/Model/RelatedFieldlInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace SiteServer.CMS.Model -{ - public class RelatedFieldInfo - { - public RelatedFieldInfo() - { - Id = 0; - Title = string.Empty; - SiteId = 0; - TotalLevel = 0; - Prefixes = string.Empty; - Suffixes = string.Empty; - } - - public RelatedFieldInfo(int id, string title, int siteId, int totalLevel, string prefixes, string suffixes) - { - Id = id; - Title = title; - SiteId = siteId; - TotalLevel = totalLevel; - Prefixes = prefixes; - Suffixes = suffixes; - } - - public int Id { get; set; } - - public string Title { get; set; } - - public int SiteId { get; set; } - - public int TotalLevel { get; set; } - - public string Prefixes { get; set; } - - public string Suffixes { get; set; } - } -} diff --git a/SiteServer.CMS/Model/RelatedFieldlItemInfo.cs b/SiteServer.CMS/Model/RelatedFieldlItemInfo.cs deleted file mode 100644 index 313899b3b..000000000 --- a/SiteServer.CMS/Model/RelatedFieldlItemInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -namespace SiteServer.CMS.Model -{ - public class RelatedFieldItemInfo - { - public RelatedFieldItemInfo() - { - Id = 0; - RelatedFieldId = 0; - ItemName = string.Empty; - ItemValue = string.Empty; - ParentId = 0; - Taxis = 0; - } - - public RelatedFieldItemInfo(int id, int relatedFieldId, string itemName, string itemValue, int parentId, int taxis) - { - Id = id; - RelatedFieldId = relatedFieldId; - ItemName = itemName; - ItemValue = itemValue; - ParentId = parentId; - Taxis = taxis; - } - - public int Id { get; set; } - - public int RelatedFieldId { get; set; } - - public string ItemName { get; set; } - - public string ItemValue { get; set; } - - public int ParentId { get; set; } - - public int Taxis { get; set; } - } -} diff --git a/SiteServer.CMS/Model/SiteAttribute.cs b/SiteServer.CMS/Model/SiteAttribute.cs deleted file mode 100644 index d1d45823d..000000000 --- a/SiteServer.CMS/Model/SiteAttribute.cs +++ /dev/null @@ -1,20 +0,0 @@ -using SiteServer.Plugin; - -namespace SiteServer.CMS.Model -{ - public class SiteAttribute - { - protected SiteAttribute() - { - } - - public const string Id = nameof(ISiteInfo.Id); - public const string SiteName = nameof(ISiteInfo.SiteName); - public const string SiteDir = nameof(ISiteInfo.SiteDir); - public const string TableName = nameof(ISiteInfo.TableName); - public const string IsRoot = nameof(ISiteInfo.IsRoot); - public const string ParentId = nameof(ISiteInfo.ParentId); - public const string Taxis = nameof(ISiteInfo.Taxis); - public const string SettingsXml = nameof(SettingsXml); - } -} diff --git a/SiteServer.CMS/Model/SiteInfo.cs b/SiteServer.CMS/Model/SiteInfo.cs deleted file mode 100644 index daeea6bda..000000000 --- a/SiteServer.CMS/Model/SiteInfo.cs +++ /dev/null @@ -1,99 +0,0 @@ -using System; -using System.Xml.Serialization; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Model -{ - [Serializable] - public class SiteInfo: ISiteInfo - { - private int _id; - private string _siteName = string.Empty; - private string _siteDir = string.Empty; - private string _tableName = string.Empty; - private bool _isRoot; - private int _parentId; - private int _taxis; - private string _settingsXml = string.Empty; - private SiteInfoExtend _additional; - - public SiteInfo() - { - } - - public SiteInfo(int id, string siteName, string siteDir, string tableName, bool isRoot, int parentId, int taxis, string settingsXml) - { - _id = id; - _siteName = siteName; - _siteDir = siteDir; - _tableName = tableName; - _isRoot = isRoot; - _parentId = parentId; - _taxis = taxis; - _settingsXml = settingsXml; - } - - [XmlIgnore] - public int Id - { - get{ return _id; } - set{ _id = value; } - } - - [XmlIgnore] - public string SiteDir - { - get { return _siteDir; } - set { _siteDir = value; } - } - - [XmlIgnore] - public string SiteName - { - get{ return _siteName; } - set{ _siteName = value; } - } - - [XmlIgnore] - public string TableName - { - get{ return _tableName; } - set{ _tableName = value; } - } - - [XmlIgnore] - public bool IsRoot - { - get{ return _isRoot; } - set{ _isRoot = value; } - } - - [XmlIgnore] - public int ParentId - { - get { return _parentId; } - set { _parentId = value; } - } - - [XmlIgnore] - public int Taxis - { - get { return _taxis; } - set { _taxis = value; } - } - - public string SettingsXml - { - get { return _settingsXml; } - set - { - _additional = null; - _settingsXml = value; - } - } - - public SiteInfoExtend Additional => _additional ?? (_additional = new SiteInfoExtend(SiteDir, _settingsXml)); - - public IAttributes Attributes => Additional; - } -} diff --git a/SiteServer.CMS/Model/SiteInfoExtend.cs b/SiteServer.CMS/Model/SiteInfoExtend.cs deleted file mode 100644 index c9044c007..000000000 --- a/SiteServer.CMS/Model/SiteInfoExtend.cs +++ /dev/null @@ -1,511 +0,0 @@ -using System; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Model -{ - [Serializable] - public class SiteInfoExtend : ExtendedAttributes - { - public const string DefaultApiUrl = "/api"; - public const string DefaultHomeUrl = "/home"; - - private readonly string _siteDir; - - public SiteInfoExtend(string siteDir, string settingsXml) - { - _siteDir = siteDir; - Load(settingsXml); - } - - /****************站点设置********************/ - - public string Charset - { - get { return GetString("Charset", ECharsetUtils.GetValue(ECharset.utf_8)); } - set { Set("Charset", value); } - } - - public int PageSize - { - get { return GetInt("PageSize", 30); } - set { Set("PageSize", value.ToString()); } - } - - public bool IsCheckContentLevel - { - get { return GetBool("IsCheckContentLevel"); } - set { Set("IsCheckContentLevel", value.ToString()); } - } - - public int CheckContentLevel { - get - { - return IsCheckContentLevel ? GetInt("CheckContentLevel") : 1; - } - set { Set("CheckContentLevel", value.ToString()); } - } - - public bool IsCountDownload - { - get { return GetBool("IsCountDownload", true); } - set { Set("IsCountDownload", value.ToString()); } - } - - public bool IsCountHits - { - get { return GetBool("IsCountHits"); } - set { Set("IsCountHits", value.ToString()); } - } - - public bool IsCountHitsByDay - { - get { return GetBool("IsCountHitsByDay"); } - set { Set("IsCountHitsByDay", value.ToString()); } - } - - public bool IsSaveImageInTextEditor - { - get { return GetBool("IsSaveImageInTextEditor", true); } - set { Set("IsSaveImageInTextEditor", value.ToString()); } - } - - public bool IsAutoPageInTextEditor - { - get { return GetBool("IsAutoPageInTextEditor"); } - set { Set("IsAutoPageInTextEditor", value.ToString()); } - } - - public int AutoPageWordNum - { - get { return GetInt("AutoPageWordNum", 1500); } - set { Set("AutoPageWordNum", value.ToString()); } - } - - public bool IsContentTitleBreakLine - { - get { return GetBool("IsContentTitleBreakLine"); } - set { Set("IsContentTitleBreakLine", value.ToString()); } - } - - /// - /// 敏感词自动检测 - /// - public bool IsAutoCheckKeywords - { - get { return GetBool("lIsAutoCheckKeywords"); } - set { Set("lIsAutoCheckKeywords", value.ToString()); } - } - - public int PhotoSmallWidth - { - get { return GetInt("PhotoSmallWidth", 70); } - set { Set("PhotoSmallWidth", value.ToString()); } - } - - public int PhotoMiddleWidth - { - get { return GetInt("PhotoMiddleWidth", 400); } - set { Set("PhotoMiddleWidth", value.ToString()); } - } - - /****************图片水印设置********************/ - - public bool IsWaterMark - { - get { return GetBool("IsWaterMark"); } - set { Set("IsWaterMark", value.ToString()); } - } - - public bool IsImageWaterMark - { - get { return GetBool("IsImageWaterMark"); } - set { Set("IsImageWaterMark", value.ToString()); } - } - - public int WaterMarkPosition - { - get { return GetInt("WaterMarkPosition", 9); } - set { Set("WaterMarkPosition", value.ToString()); } - } - - public int WaterMarkTransparency - { - get { return GetInt("WaterMarkTransparency", 5); } - set { Set("WaterMarkTransparency", value.ToString()); } - } - - public int WaterMarkMinWidth - { - get { return GetInt("WaterMarkMinWidth", 200); } - set { Set("WaterMarkMinWidth", value.ToString()); } - } - - public int WaterMarkMinHeight - { - get { return GetInt("WaterMarkMinHeight", 200); } - set { Set("WaterMarkMinHeight", value.ToString()); } - } - - public string WaterMarkFormatString - { - get { return GetString("WaterMarkFormatString", string.Empty); } - set { Set("WaterMarkFormatString", value); } - } - - public string WaterMarkFontName - { - get { return GetString("WaterMarkFontName", string.Empty); } - set { Set("WaterMarkFontName", value); } - } - - public int WaterMarkFontSize - { - get { return GetInt("WaterMarkFontSize", 12); } - set { Set("WaterMarkFontSize", value.ToString()); } - } - - public string WaterMarkImagePath - { - get { return GetString("WaterMarkImagePath", string.Empty); } - set { Set("WaterMarkImagePath", value); } - } - - /****************生成页面设置********************/ - - public bool IsSeparatedWeb - { - get { return GetBool("IsSeparatedWeb"); } - set { Set("IsSeparatedWeb", value.ToString()); } - } - - public string SeparatedWebUrl - { - get { return GetString("SeparatedWebUrl"); } - set { Set("SeparatedWebUrl", value); } - } - - public string WebUrl => IsSeparatedWeb ? SeparatedWebUrl : PageUtils.ParseNavigationUrl($"~/{_siteDir}"); - - public bool IsSeparatedAssets - { - get { return GetBool("IsSeparatedAssets"); } - set { Set("IsSeparatedAssets", value.ToString()); } - } - - public string SeparatedAssetsUrl - { - get { return GetString("SeparatedAssetsUrl"); } - set { Set("SeparatedAssetsUrl", value); } - } - - public string AssetsDir - { - get { return GetString("AssetsDir", "upload"); } - set { Set("AssetsDir", value); } - } - - public string AssetsUrl => IsSeparatedAssets ? SeparatedAssetsUrl : PageUtils.ParseNavigationUrl($"~/{_siteDir}/{AssetsDir}/"); - - public string ChannelFilePathRule - { - get { return GetString("ChannelFilePathRule", "/channels/{@ChannelID}.html"); } - set { Set("ChannelFilePathRule", value); } - } - - public string ContentFilePathRule - { - get { return GetString("ContentFilePathRule", "/contents/{@ChannelID}/{@ContentID}.html"); } - set { Set("ContentFilePathRule", value); } - } - - public bool IsCreateContentIfContentChanged - { - get { return GetBool("IsCreateContentIfContentChanged", true); } - set { Set("IsCreateContentIfContentChanged", value.ToString()); } - } - - public bool IsCreateChannelIfChannelChanged - { - get { return GetBool("IsCreateChannelIfChannelChanged", true); } - set { Set("IsCreateChannelIfChannelChanged", value.ToString()); } - } - - public bool IsCreateShowPageInfo - { - get { return GetBool("IsCreateShowPageInfo"); } - set { Set("IsCreateShowPageInfo", value.ToString()); } - } - - public bool IsCreateIe8Compatible - { - get { return GetBool("IsCreateIe8Compatible"); } - set { Set("IsCreateIe8Compatible", value.ToString()); } - } - - public bool IsCreateBrowserNoCache - { - get { return GetBool("IsCreateBrowserNoCache"); } - set { Set("IsCreateBrowserNoCache", value.ToString()); } - } - - public bool IsCreateJsIgnoreError - { - get { return GetBool("IsCreateJsIgnoreError"); } - set { Set("IsCreateJsIgnoreError", value.ToString()); } - } - - public bool IsCreateSearchDuplicate - { - get { return GetBool("IsCreateSearchDuplicate", true); } - set { Set("IsCreateSearchDuplicate", value.ToString()); } - } - - public bool IsCreateWithJQuery - { - get { return GetBool("IsCreateWithJQuery", true); } - set { Set("IsCreateWithJQuery", value.ToString()); } - } - - public bool IsCreateDoubleClick - { - get { return GetBool("IsCreateDoubleClick"); } - set { Set("IsCreateDoubleClick", value.ToString()); } - } - - public int CreateStaticMaxPage - { - get { return GetInt("CreateStaticMaxPage", 10); } - set { Set("CreateStaticMaxPage", value.ToString()); } - } - - public bool IsCreateStaticContentByAddDate - { - get { return GetBool("IsCreateStaticContentByAddDate"); } - set { Set("IsCreateStaticContentByAddDate", value.ToString()); } - } - - public DateTime CreateStaticContentAddDate - { - get { return GetDateTime("CreateStaticContentAddDate", DateTime.MinValue); } - set { Set("CreateStaticContentAddDate", DateUtils.GetDateString(value)); } - } - - /****************跨站转发设置********************/ - - public bool IsCrossSiteTransChecked - { - get { return GetBool("IsCrossSiteTransChecked"); } - set { Set("IsCrossSiteTransChecked", value.ToString()); } - } - - /****************记录系统操作设置********************/ - - public bool ConfigTemplateIsCodeMirror - { - get { return GetBool("ConfigTemplateIsCodeMirror", true); } - set { Set("ConfigTemplateIsCodeMirror", value.ToString()); } - } - - public int ConfigVideoContentInsertWidth - { - get { return GetInt("ConfigVideoContentInsertWidth", 420); } - set { Set("ConfigVideoContentInsertWidth", value.ToString()); } - } - - public int ConfigVideoContentInsertHeight - { - get { return GetInt("ConfigVideoContentInsertHeight", 280); } - set { Set("ConfigVideoContentInsertHeight", value.ToString()); } - } - - public string ConfigExportType - { - get { return GetString("ConfigExportType", string.Empty); } - set { Set("ConfigExportType", value); } - } - - public string ConfigExportPeriods - { - get { return GetString("ConfigExportPeriods", string.Empty); } - set { Set("ConfigExportPeriods", value); } - } - - public string ConfigExportDisplayAttributes - { - get { return GetString("ConfigExportDisplayAttributes", string.Empty); } - set { Set("ConfigExportDisplayAttributes", value); } - } - - public string ConfigExportIsChecked - { - get { return GetString("ConfigExportIsChecked", string.Empty); } - set { Set("ConfigExportIsChecked", value); } - } - - public string ConfigSelectImageCurrentUrl - { - get { return GetString("ConfigSelectImageCurrentUrl", "@/" + ImageUploadDirectoryName); } - set { Set("ConfigSelectImageCurrentUrl", value); } - } - - public string ConfigSelectVideoCurrentUrl - { - get { return GetString("ConfigSelectVideoCurrentUrl", "@/" + VideoUploadDirectoryName); } - set { Set("ConfigSelectVideoCurrentUrl", value); } - } - - public string ConfigSelectFileCurrentUrl - { - get { return GetString("ConfigSelectFileCurrentUrl", "@/" + FileUploadDirectoryName); } - set { Set("ConfigSelectFileCurrentUrl", value); } - } - - public string ConfigUploadImageIsTitleImage - { - get { return GetString("ConfigUploadImageIsTitleImage", "True"); } - set { Set("ConfigUploadImageIsTitleImage", value); } - } - - public string ConfigUploadImageTitleImageWidth - { - get { return GetString("ConfigUploadImageTitleImageWidth", "300"); } - set { Set("ConfigUploadImageTitleImageWidth", value); } - } - - public string ConfigUploadImageTitleImageHeight - { - get { return GetString("ConfigUploadImageTitleImageHeight", string.Empty); } - set { Set("ConfigUploadImageTitleImageHeight", value); } - } - - public string ConfigUploadImageIsShowImageInTextEditor - { - get { return GetString("ConfigUploadImageIsShowImageInTextEditor", "True"); } - set { Set("ConfigUploadImageIsShowImageInTextEditor", value); } - } - - public string ConfigUploadImageIsLinkToOriginal - { - get { return GetString("ConfigUploadImageIsLinkToOriginal", string.Empty); } - set { Set("ConfigUploadImageIsLinkToOriginal", value); } - } - - public string ConfigUploadImageIsSmallImage - { - get { return GetString("ConfigUploadImageIsSmallImage", "True"); } - set { Set("ConfigUploadImageIsSmallImage", value); } - } - - public string ConfigUploadImageSmallImageWidth - { - get { return GetString("ConfigUploadImageSmallImageWidth", "500"); } - set { Set("ConfigUploadImageSmallImageWidth", value); } - } - - public string ConfigUploadImageSmallImageHeight - { - get { return GetString("ConfigUploadImageSmallImageHeight", string.Empty); } - set { Set("ConfigUploadImageSmallImageHeight", value); } - } - - /****************站点基本设置********************/ - public string SiteSettingsCollection - { - get { return GetString("SiteSettingsCollection", string.Empty); } - set { Set("SiteSettingsCollection", value); } - } - - /****************上传设置*************************/ - - public string ImageUploadDirectoryName - { - get { return GetString("ImageUploadDirectoryName", "upload/images"); } - set { Set("ImageUploadDirectoryName", value); } - } - - public string ImageUploadDateFormatString - { - get { return GetString("ImageUploadDateFormatString", EDateFormatTypeUtils.GetValue(EDateFormatType.Month)); } - set { Set("ImageUploadDateFormatString", value); } - } - - public bool IsImageUploadChangeFileName - { - get { return GetBool("IsImageUploadChangeFileName", true); } - set { Set("IsImageUploadChangeFileName", value.ToString()); } - } - - public string ImageUploadTypeCollection - { - get { return GetString("ImageUploadTypeCollection", "gif|jpg|jpeg|bmp|png|pneg|swf"); } - set { Set("ImageUploadTypeCollection", value); } - } - - public int ImageUploadTypeMaxSize - { - get { return GetInt("ImageUploadTypeMaxSize", 15360); } - set { Set("ImageUploadTypeMaxSize", value.ToString()); } - } - - public string VideoUploadDirectoryName - { - get { return GetString("VideoUploadDirectoryName", "upload/videos"); } - set { Set("VideoUploadDirectoryName", value); } - } - - public string VideoUploadDateFormatString - { - get { return GetString("VideoUploadDateFormatString", EDateFormatTypeUtils.GetValue(EDateFormatType.Month)); } - set { Set("VideoUploadDateFormatString", value); } - } - - public bool IsVideoUploadChangeFileName - { - get { return GetBool("IsVideoUploadChangeFileName", true); } - set { Set("IsVideoUploadChangeFileName", value.ToString()); } - } - - public string VideoUploadTypeCollection - { - get { return GetString("VideoUploadTypeCollection", "asf|asx|avi|flv|mid|midi|mov|mp3|mp4|mpg|mpeg|ogg|ra|rm|rmb|rmvb|rp|rt|smi|swf|wav|webm|wma|wmv|viv"); } - set { Set("VideoUploadTypeCollection", value); } - } - - public int VideoUploadTypeMaxSize - { - get { return GetInt("VideoUploadTypeMaxSize", 307200); } - set { Set("VideoUploadTypeMaxSize", value.ToString()); } - } - - public string FileUploadDirectoryName - { - get { return GetString("FileUploadDirectoryName", "upload/files"); } - set { Set("FileUploadDirectoryName", value); } - } - - public string FileUploadDateFormatString - { - get { return GetString("FileUploadDateFormatString", EDateFormatTypeUtils.GetValue(EDateFormatType.Month)); } - set { Set("FileUploadDateFormatString", value); } - } - - public bool IsFileUploadChangeFileName - { - get { return GetBool("IsFileUploadChangeFileName", true); } - set { Set("IsFileUploadChangeFileName", value.ToString()); } - } - - public string FileUploadTypeCollection - { - get { return GetString("FileUploadTypeCollection", "zip,rar,7z,js,css,txt,doc,docx,ppt,pptx,xls,xlsx,pdf"); } - set { Set("FileUploadTypeCollection", value); } - } - - public int FileUploadTypeMaxSize - { - get { return GetInt("FileUploadTypeMaxSize", 307200); } - set { Set("FileUploadTypeMaxSize", value.ToString()); } - } - } -} diff --git a/SiteServer.CMS/Model/SiteLogInfo.cs b/SiteServer.CMS/Model/SiteLogInfo.cs deleted file mode 100644 index 1f2db7191..000000000 --- a/SiteServer.CMS/Model/SiteLogInfo.cs +++ /dev/null @@ -1,51 +0,0 @@ -using System; - -namespace SiteServer.CMS.Model -{ - public class SiteLogInfo - { - public SiteLogInfo() - { - Id = 0; - SiteId = 0; - ChannelId = 0; - ContentId = 0; - UserName = string.Empty; - IpAddress = string.Empty; - AddDate = DateTime.Now; - Action = string.Empty; - Summary = string.Empty; - } - - public SiteLogInfo(int id, int site, int channelId, int contentId, string userName, string ipAddress, DateTime addDate, string action, string summary) - { - Id = id; - SiteId = site; - ChannelId = channelId; - ContentId = contentId; - UserName = userName; - IpAddress = ipAddress; - AddDate = addDate; - Action = action; - Summary = summary; - } - - public int Id { get; set; } - - public int SiteId { get; set; } - - public int ChannelId { get; set; } - - public int ContentId { get; set; } - - public string UserName { get; set; } - - public string IpAddress { get; set; } - - public DateTime AddDate { get; set; } - - public string Action { get; set; } - - public string Summary { get; set; } - } -} diff --git a/SiteServer.CMS/Model/SitePageInfo.cs b/SiteServer.CMS/Model/SitePageInfo.cs deleted file mode 100644 index 4e0c3314b..000000000 --- a/SiteServer.CMS/Model/SitePageInfo.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System.Web; - -using SiteServer.Utils; -using SiteServer.CMS.Core; - -namespace SiteServer.CMS.Model -{ - public class SitePageInfo - { - private SitePageInfo() - { - SiteId = ChannelId = ContentId = PageIndex = 0; - } - - public static SitePageInfo GetInstance() - { - var pageInfo = new SitePageInfo(); - - if (!string.IsNullOrEmpty(HttpContext.Current.Request.QueryString["SiteID"])) - { - pageInfo.SiteId = TranslateUtils.ToInt(HttpContext.Current.Request.QueryString["SiteID"]); - } - if (pageInfo.SiteId == 0) - { - pageInfo.SiteId = PathUtility.GetCurrentSiteId(); - } - if (!string.IsNullOrEmpty(HttpContext.Current.Request.QueryString["ChannelID"])) - { - pageInfo.ChannelId = TranslateUtils.ToInt(HttpContext.Current.Request.QueryString["ChannelID"]); - } - if (!string.IsNullOrEmpty(HttpContext.Current.Request.QueryString["ContentID"])) - { - pageInfo.ContentId = TranslateUtils.ToInt(HttpContext.Current.Request.QueryString["ContentID"]); - } - - if (pageInfo.ChannelId == 0) - { - var path = HttpContext.Current.Request.Path.Substring(0, HttpContext.Current.Request.Path.LastIndexOf(".aspx")); - if (StringUtils.Contains(path, PathUtility.ChannelFilePathRules.DefaultDirectoryName)) - { - pageInfo.ChannelId = TranslateUtils.ToInt(RegexUtils.GetContent("channelID", PathUtility.ChannelFilePathRules.DefaultRegexString, path)); - pageInfo.PageIndex = TranslateUtils.ToInt(RegexUtils.GetContent("pageIndex", PathUtility.ChannelFilePathRules.DefaultRegexString, path)); - if (pageInfo.PageIndex > 0) - { - pageInfo.PageIndex--; - } - } - else if (StringUtils.Contains(path, PathUtility.ContentFilePathRules.DefaultDirectoryName)) - { - pageInfo.ChannelId = TranslateUtils.ToInt(RegexUtils.GetContent("channelID", PathUtility.ContentFilePathRules.DefaultRegexString, path)); - pageInfo.ContentId = TranslateUtils.ToInt(RegexUtils.GetContent("contentID", PathUtility.ContentFilePathRules.DefaultRegexString, path)); - pageInfo.PageIndex = TranslateUtils.ToInt(RegexUtils.GetContent("pageIndex", PathUtility.ContentFilePathRules.DefaultRegexString, path)); - if (pageInfo.PageIndex > 0) - { - pageInfo.PageIndex--; - } - } - } - return pageInfo; - } - - public int SiteId { get; private set; } - - public int ChannelId { get; private set; } - - public int ContentId { get; private set; } - - public int PageIndex { get; private set; } - } -} diff --git a/SiteServer.CMS/Model/SitePermissionsInfo.cs b/SiteServer.CMS/Model/SitePermissionsInfo.cs deleted file mode 100644 index 9c4090a93..000000000 --- a/SiteServer.CMS/Model/SitePermissionsInfo.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; - -namespace SiteServer.CMS.Model -{ - [Serializable] - public class SitePermissionsInfo - { - private int _id; - private string _roleName; - private int _siteId; - private string _channelIdCollection; - private string _channelPermissions; - private string _websitePermissions; - - public SitePermissionsInfo() - { - _id = 0; - _roleName = string.Empty; - _siteId = 0; - _channelIdCollection = string.Empty; - _channelPermissions = string.Empty; - _websitePermissions = string.Empty; - } - - public SitePermissionsInfo(string roleName, int siteId, string channelIdCollection, string channelPermissions, string websitePermissions) - { - _roleName = roleName; - _siteId = siteId; - _channelIdCollection = channelIdCollection; - _channelPermissions = channelPermissions; - _websitePermissions = websitePermissions; - } - - public int Id - { - get { return _id; } - set { _id = value; } - } - - public string RoleName - { - get{ return _roleName; } - set{ _roleName = value; } - } - - public int SiteId - { - get{ return _siteId; } - set{ _siteId = value; } - } - - public string ChannelIdCollection - { - get{ return _channelIdCollection; } - set{ _channelIdCollection = value; } - } - - public string ChannelPermissions - { - get{ return _channelPermissions; } - set{ _channelPermissions = value; } - } - - public string WebsitePermissions - { - get{ return _websitePermissions; } - set{ _websitePermissions = value; } - } - } -} diff --git a/SiteServer.CMS/Model/SiteTemplateInfo.cs b/SiteServer.CMS/Model/SiteTemplateInfo.cs deleted file mode 100644 index 491de765c..000000000 --- a/SiteServer.CMS/Model/SiteTemplateInfo.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System; -using System.Xml.Serialization; - -namespace SiteServer.CMS.Model -{ - [Serializable] - [XmlRoot("SiteTemplate")] - public class SiteTemplateInfo - { - private string _siteTemplateName; - private string _webSiteUrl; - private string _picFileName; - private string _description; - - public SiteTemplateInfo() - { - _siteTemplateName = string.Empty; - _webSiteUrl = string.Empty; - _picFileName = string.Empty; - _description = string.Empty; - } - - public SiteTemplateInfo(string siteTemplateName, string webSiteUrl, string picFileName, string description) - { - _siteTemplateName = siteTemplateName; - _webSiteUrl = webSiteUrl; - _picFileName = picFileName; - _description = description; - } - - [XmlElement(ElementName = "SiteTemplateName")] - public string SiteTemplateName - { - get { return _siteTemplateName; } - set { _siteTemplateName = value; } - } - - [XmlElement(ElementName = "WebSiteUrl")] - public string WebSiteUrl - { - get { return _webSiteUrl; } - set { _webSiteUrl = value; } - } - - [XmlElement(ElementName = "PicFileName")] - public string PicFileName - { - get { return _picFileName; } - set { _picFileName = value; } - } - - [XmlElement(ElementName = "Description")] - public string Description - { - get { return _description; } - set { _description = value; } - } - - public string DirectoryName { get; set; } - - } -} diff --git a/SiteServer.CMS/Model/SystemConfigInfo.cs b/SiteServer.CMS/Model/SystemConfigInfo.cs deleted file mode 100644 index 941e704ef..000000000 --- a/SiteServer.CMS/Model/SystemConfigInfo.cs +++ /dev/null @@ -1,207 +0,0 @@ -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Model -{ - public class SystemConfigInfo : ExtendedAttributes - { - public SystemConfigInfo(string settings) : base(settings) - { - - } - - public bool IsSeparatedApi - { - get { return GetBool("IsSeparatedApi"); } - set { Set("IsSeparatedApi", value.ToString()); } - } - - public string SeparatedApiUrl - { - get { return GetString("SeparatedApiUrl"); } - set { Set("SeparatedApiUrl", value); } - } - - public string ApiUrl => IsSeparatedApi ? SeparatedApiUrl : PageUtils.ParseNavigationUrl("~/api"); - - public bool IsLogAdmin - { - get { return GetBool("IsLogAdmin", true); } - set { Set("IsLogAdmin", value.ToString()); } - } - - public bool IsLogUser - { - get { return GetBool("IsLogUser", true); } - set { Set("IsLogUser", value.ToString()); } - } - - public bool IsLogError - { - get { return GetBool("IsLogError", true); } - set { Set("IsLogError", value.ToString()); } - } - - /// - /// 是否只查看自己添加的内容 - /// 如果是,那么管理员只能查看自己添加的内容 - /// 如果不是,那么管理员可以查看其他管理员天机的内容,默认false - /// 注意:超级管理与,站点管理员,审核管理员,此设置无效 - /// add by sessionliang at 20151217 - /// - public bool IsViewContentOnlySelf - { - get { return GetBool("IsViewContentOnlySelf"); } - set { Set("IsViewContentOnlySelf", value.ToString()); } - } - - // 是否开启时间阈值 - public bool IsTimeThreshold - { - get { return GetBool("IsTimeThreshold"); } - set { Set("IsTimeThreshold", value.ToString()); } - } - - public int TimeThreshold - { - get { return GetInt("TimeThreshold", 60); } - set { Set("TimeThreshold", value.ToString()); } - } - - public ESmsProviderType SmsProviderType - { - get { return ESmsProviderTypeUtils.GetEnumType(GetString("SmsProviderType", ESmsProviderTypeUtils.GetValue(ESmsProviderType.None))); } - set { Set("SmsProviderType", ESmsProviderTypeUtils.GetValue(value)); } - } - - public string SmsAppKey - { - get { return GetString("SmsAppKey", string.Empty); } - set { Set("SmsAppKey", value); } - } - - public string IntegrationPayConfigJson - { - get { return GetString("IntegrationPayConfigJson", string.Empty); } - set { Set("IntegrationPayConfigJson", value); } - } - - /****************管理员设置********************/ - - public int AdminUserNameMinLength - { - get { return GetInt("AdminUserNameMinLength"); } - set { Set("AdminUserNameMinLength", value.ToString()); } - } - - public int AdminPasswordMinLength - { - get { return GetInt("AdminPasswordMinLength", 6); } - set { Set("AdminPasswordMinLength", value.ToString()); } - } - - public string AdminPasswordRestriction - { - get { return GetString("AdminPasswordRestriction", EUserPasswordRestrictionUtils.GetValue(EUserPasswordRestriction.LetterAndDigit)); } - set { Set("AdminPasswordRestriction", value); } - } - - public bool IsAdminLockLogin - { - get { return GetBool("IsAdminLockLogin"); } - set { Set("IsAdminLockLogin", value.ToString()); } - } - - public int AdminLockLoginCount - { - get { return GetInt("AdminLockLoginCount", 3); } - set { Set("AdminLockLoginCount", value.ToString()); } - } - - public string AdminLockLoginType - { - get { return GetString("AdminLockLoginType", EUserLockTypeUtils.GetValue(EUserLockType.Hours)); } - set { Set("AdminLockLoginType", value); } - } - - public int AdminLockLoginHours - { - get { return GetInt("AdminLockLoginHours", 3); } - set { Set("AdminLockLoginHours", value.ToString()); } - } - - public bool IsAdminFindPassword - { - get { return GetBool("IsAdminFindPassword"); } - set { Set("IsAdminFindPassword", value.ToString()); } - } - - public string AdminFindPasswordSmsTplId - { - get { return GetString("AdminFindPasswordSmsTplId", string.Empty); } - set { Set("AdminFindPasswordSmsTplId", value); } - } - - /****************用户设置********************/ - - public bool IsUserRegistrationAllowed - { - get { return GetBool("IsUserRegistrationAllowed", true); } - set { Set("IsUserRegistrationAllowed", value.ToString()); } - } - - public int UserPasswordMinLength - { - get { return GetInt("UserPasswordMinLength", 6); } - set { Set("UserPasswordMinLength", value.ToString()); } - } - - public string UserPasswordRestriction - { - get { return GetString("UserPasswordRestriction", EUserPasswordRestrictionUtils.GetValue(EUserPasswordRestriction.LetterAndDigit)); } - set { Set("UserPasswordRestriction", value); } - } - - public int UserRegistrationMinMinutes - { - get { return GetInt("UserRegistrationMinMinutes"); } - set { Set("UserRegistrationMinMinutes", value.ToString()); } - } - - public bool IsUserFindPassword - { - get { return GetBool("IsUserFindPassword"); } - set { Set("IsUserFindPassword", value.ToString()); } - } - - public string UserFindPasswordSmsTplId - { - get { return GetString("UserFindPasswordSmsTplId", string.Empty); } - set { Set("UserFindPasswordSmsTplId", value); } - } - - public bool IsUserLockLogin - { - get { return GetBool("IsUserLockLogin"); } - set { Set("IsUserLockLogin", value.ToString()); } - } - - public int UserLockLoginCount - { - get { return GetInt("UserLockLoginCount", 3); } - set { Set("UserLockLoginCount", value.ToString()); } - } - - public string UserLockLoginType - { - get { return GetString("UserLockLoginType", "Hours"); } - set { Set("UserLockLoginType", value); } - } - - public int UserLockLoginHours - { - get { return GetInt("UserLockLoginHours", 3); } - set { Set("UserLockLoginHours", value.ToString()); } - } - } -} diff --git a/SiteServer.CMS/Model/TableColumnInfo.cs b/SiteServer.CMS/Model/TableColumnInfo.cs deleted file mode 100644 index 946293b99..000000000 --- a/SiteServer.CMS/Model/TableColumnInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using SiteServer.Plugin; - -namespace SiteServer.CMS.Model -{ - public class TableColumnInfo - { - public TableColumnInfo() - { - ColumnName = string.Empty; - DataType = DataType.VarChar; - Length = 0; - IsPrimaryKey = false; - IsIdentity = false; - } - - public TableColumnInfo(string columnName, DataType dataType, int length, bool isPrimaryKey, bool isIdentity) - { - ColumnName = columnName; - DataType = dataType; - Length = length; - IsPrimaryKey = isPrimaryKey; - IsIdentity = isIdentity; - } - - public string ColumnName { get; set; } - - public DataType DataType { get; set; } - - public int Length { get; set; } - - public bool IsPrimaryKey { get; set; } - - public bool IsIdentity { get; set; } - } -} diff --git a/SiteServer.CMS/Model/TableInfo.cs b/SiteServer.CMS/Model/TableInfo.cs deleted file mode 100644 index 088bbe0e8..000000000 --- a/SiteServer.CMS/Model/TableInfo.cs +++ /dev/null @@ -1,45 +0,0 @@ -namespace SiteServer.CMS.Model -{ - public class TableInfo - { - public TableInfo() - { - Id = 0; - TableName = string.Empty; - DisplayName = string.Empty; - AttributeNum = 0; - IsCreatedInDb = false; - IsChangedAfterCreatedInDb = false; - IsDefault = false; - Description = string.Empty; - } - - public TableInfo(int id, string tableName, string displayName, int attributeNum, bool isCreatedInDb, bool isChangedAfterCreatedInDb, bool isDefault, string description) - { - Id = id; - TableName = tableName; - DisplayName = displayName; - AttributeNum = attributeNum; - IsCreatedInDb = isCreatedInDb; - IsChangedAfterCreatedInDb = isChangedAfterCreatedInDb; - IsDefault = isDefault; - Description = description; - } - - public int Id { get; set; } - - public string TableName { get; set; } - - public string DisplayName { get; set; } - - public int AttributeNum { get; set; } - - public bool IsCreatedInDb { get; set; } - - public bool IsChangedAfterCreatedInDb { get; set; } - - public bool IsDefault { get; set; } - - public string Description { get; set; } - } -} diff --git a/SiteServer.CMS/Model/TableMatchInfo.cs b/SiteServer.CMS/Model/TableMatchInfo.cs deleted file mode 100644 index 260bc4b64..000000000 --- a/SiteServer.CMS/Model/TableMatchInfo.cs +++ /dev/null @@ -1,72 +0,0 @@ -using System; -using System.Collections.Specialized; - -namespace SiteServer.CMS.Model -{ - [Serializable] - public class TableMatchInfo - { - private int _id; - private string _connectionString; - private string _tableName; - private string _connectionStringToMatch; - private string _tableNameToMatch; - private NameValueCollection _columnsMap; - - public TableMatchInfo() - { - _id = 0; - _connectionString = string.Empty; - _tableName = string.Empty; - _connectionStringToMatch = string.Empty; - _tableNameToMatch = string.Empty; - _columnsMap = new NameValueCollection(); - } - - public TableMatchInfo(int id, string connectionString, string tableName, string connectionStringToMatch, string tableNameToMatch, NameValueCollection columnsMap) - { - _id = id; - _connectionString = connectionString; - _tableName = tableName; - _connectionStringToMatch = connectionStringToMatch; - _tableNameToMatch = tableNameToMatch; - _columnsMap = columnsMap; - } - - public int Id - { - get{ return _id; } - set{ _id = value; } - } - - public string ConnectionString - { - get{ return _connectionString; } - set{ _connectionString = value; } - } - - public string TableName - { - get{ return _tableName; } - set{ _tableName = value; } - } - - public string ConnectionStringToMatch - { - get{ return _connectionStringToMatch; } - set{ _connectionStringToMatch = value; } - } - - public string TableNameToMatch - { - get{ return _tableNameToMatch; } - set{ _tableNameToMatch = value; } - } - - public NameValueCollection ColumnsMap - { - get{ return _columnsMap; } - set{ _columnsMap = value; } - } - } -} diff --git a/SiteServer.CMS/Model/TableStyleInfo.cs b/SiteServer.CMS/Model/TableStyleInfo.cs deleted file mode 100644 index 428bfe6a2..000000000 --- a/SiteServer.CMS/Model/TableStyleInfo.cs +++ /dev/null @@ -1,81 +0,0 @@ -using System; -using System.Collections.Generic; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Model -{ - [Serializable] - public class TableStyleInfo: IComparable - { - public TableStyleInfo() - { - Id = 0; - RelatedIdentity = 0; - TableName = string.Empty; - AttributeName = string.Empty; - Taxis = 0; - DisplayName = string.Empty; - HelpText = string.Empty; - IsVisibleInList = false; - InputType = InputType.Text; - DefaultValue = string.Empty; - IsHorizontal = true; - ExtendValues = string.Empty; - } - - public TableStyleInfo(int id, int relatedIdentity, string tableName, string attributeName, int taxis, string displayName, string helpText, bool isVisibleInList, InputType inputType, string defaultValue, bool isHorizontal, string extendValues) - { - Id = id; - RelatedIdentity = relatedIdentity; - TableName = tableName; - AttributeName = attributeName; - Taxis = taxis; - DisplayName = displayName; - HelpText = helpText; - IsVisibleInList = isVisibleInList; - InputType = inputType; - DefaultValue = defaultValue; - IsHorizontal = isHorizontal; - ExtendValues = extendValues; - } - - public int Id { get; set; } - - public int RelatedIdentity { get; set; } - - public string TableName { get; set; } - - public string AttributeName { get; set; } - - public int Taxis { get; set; } - - public string DisplayName { get; set; } - - public string HelpText { get; set; } - - public bool IsVisibleInList { get; set; } - - public InputType InputType { get; set; } - - public string DefaultValue { get; set; } - - public bool IsHorizontal { get; set; } - - public string ExtendValues { get; set; } - - private TableStyleInfoExtend _additional; - public TableStyleInfoExtend Additional => _additional ?? (_additional = new TableStyleInfoExtend(ExtendValues)); - - public List StyleItems { get; set; } - - public int CompareTo(TableStyleInfo other) - { - if (other == null) return 1; - - var x = Taxis.CompareTo(other.Taxis); - if (x != 0) return x; - - return string.Compare(AttributeName, other.AttributeName, StringComparison.Ordinal); - } - } -} diff --git a/SiteServer.CMS/Model/TableStyleInfoExtend.cs b/SiteServer.CMS/Model/TableStyleInfoExtend.cs deleted file mode 100644 index 6a1f0d920..000000000 --- a/SiteServer.CMS/Model/TableStyleInfoExtend.cs +++ /dev/null @@ -1,107 +0,0 @@ -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Model -{ - public class TableStyleInfoExtend : ExtendedAttributes - { - public TableStyleInfoExtend(string settings) : base(settings) - { - - } - - public int Height - { - get { return GetInt("Height"); } - set { Set("Height", value.ToString()); } - } - - public string Width - { - get - { - var width = GetString("Width"); - return width == "0" ? string.Empty : width; - } - set { Set("Width", value); } - } - - public int Columns - { - get { return GetInt("Columns"); } - set { Set("Columns", value.ToString()); } - } - - public bool IsFormatString - { - get { return GetBool("IsFormatString"); } - set { Set("IsFormatString", value.ToString()); } - } - - public int RelatedFieldId - { - get { return GetInt("RelatedFieldID"); } - set { Set("RelatedFieldID", value.ToString()); } - } - - public string RelatedFieldStyle - { - get { return GetString("RelatedFieldStyle"); } - set { Set("RelatedFieldStyle", value); } - } - - public string CustomizeLeft - { - get { return GetString("CustomizeLeft"); } - set { Set("CustomizeLeft", value); } - } - - public string CustomizeRight - { - get { return GetString("CustomizeRight"); } - set { Set("CustomizeRight", value); } - } - - public bool IsValidate - { - get { return GetBool("IsValidate"); } - set { Set("IsValidate", value.ToString()); } - } - - public bool IsRequired - { - get { return GetBool("IsRequired"); } - set { Set("IsRequired", value.ToString()); } - } - - public int MinNum - { - get { return GetInt("MinNum"); } - set { Set("MinNum", value.ToString()); } - } - - public int MaxNum - { - get { return GetInt("MaxNum"); } - set { Set("MaxNum", value.ToString()); } - } - - public ValidateType ValidateType - { - get { return ValidateTypeUtils.GetEnumType(GetString("ValidateType")); } - set { Set("ValidateType", value != null ? value.Value : ValidateType.None.Value); } - } - - public string RegExp - { - get { return GetString("RegExp"); } - set { Set("RegExp", value); } - } - - public string ErrorMessage - { - get { return GetString("ErrorMessage"); } - set { Set("ErrorMessage", value); } - } - } -} diff --git a/SiteServer.CMS/Model/TableStyleItemInfo.cs b/SiteServer.CMS/Model/TableStyleItemInfo.cs deleted file mode 100644 index 2b2709e4f..000000000 --- a/SiteServer.CMS/Model/TableStyleItemInfo.cs +++ /dev/null @@ -1,33 +0,0 @@ -namespace SiteServer.CMS.Model -{ - public class TableStyleItemInfo - { - public TableStyleItemInfo() - { - Id = 0; - TableStyleId = 0; - ItemTitle = string.Empty; - ItemValue = string.Empty; - IsSelected = false; - } - - public TableStyleItemInfo(int id, int tableStyleId, string itemTitle, string itemValue, bool isSelected) - { - Id = id; - TableStyleId = tableStyleId; - ItemTitle = itemTitle; - ItemValue = itemValue; - IsSelected = isSelected; - } - - public int Id { get; set; } - - public int TableStyleId { get; set; } - - public string ItemTitle { get; set; } - - public string ItemValue { get; set; } - - public bool IsSelected { get; set; } - } -} diff --git a/SiteServer.CMS/Model/TagInfo.cs b/SiteServer.CMS/Model/TagInfo.cs deleted file mode 100644 index 0a911be81..000000000 --- a/SiteServer.CMS/Model/TagInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -namespace SiteServer.CMS.Model -{ - public class TagInfo - { - public TagInfo() - { - Id = 0; - SiteId = 0; - ContentIdCollection = string.Empty; - Tag = string.Empty; - UseNum = 0; - } - - public TagInfo(int id, int siteId, string contentIdCollection, string tag, int useNum) - { - Id = id; - SiteId = siteId; - ContentIdCollection = contentIdCollection; - Tag = tag; - UseNum = useNum; - } - - public int Id { get; set; } - - public int SiteId { get; set; } - - public string ContentIdCollection { get; set; } - - public string Tag { get; set; } - - public int UseNum { get; set; } - - public int Level { get; set; } = 0; - } -} diff --git a/SiteServer.CMS/Model/TemplateInfo.cs b/SiteServer.CMS/Model/TemplateInfo.cs deleted file mode 100644 index 831bc6e32..000000000 --- a/SiteServer.CMS/Model/TemplateInfo.cs +++ /dev/null @@ -1,107 +0,0 @@ -using System; -using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Model -{ - [Serializable] - public class TemplateInfo - { - private int _id; - private int _siteId; - private string _templateName; - private TemplateType _templateType; - private string _relatedFileName; - private string _createdFileFullName; - private string _createdFileExtName; - private ECharset _charset; - private bool _isDefault; - - public TemplateInfo() - { - _id = 0; - _siteId = 0; - _templateName = string.Empty; - _templateType = TemplateType.ContentTemplate; - _relatedFileName = string.Empty; - _createdFileFullName = string.Empty; - _createdFileExtName = string.Empty; - _charset = ECharset.utf_8; - _isDefault = false; - } - - public TemplateInfo(int id, int siteId, string templateName, TemplateType templateType, string relatedFileName, string createdFileFullName, string createdFileExtName, ECharset charset, bool isDefault) - { - _id = id; - _siteId = siteId; - _templateName = templateName; - _templateType = templateType; - _relatedFileName = relatedFileName; - _createdFileFullName = createdFileFullName; - _createdFileExtName = createdFileExtName; - _charset = charset; - _isDefault = isDefault; - } - - public int Id - { - get{ return _id; } - set{ _id = value; } - } - - public int SiteId - { - get{ return _siteId; } - set{ _siteId = value; } - } - - public string TemplateName - { - get{ return _templateName; } - set{ _templateName = value; } - } - - public TemplateType TemplateType - { - get{ return _templateType; } - set{ _templateType = value; } - } - - public string RelatedFileName - { - get { return _relatedFileName; } - set { _relatedFileName = value; } - } - - public string CreatedFileFullName - { - get { return _createdFileFullName; } - set { _createdFileFullName = value; } - } - - public string CreatedFileExtName - { - get { return _createdFileExtName; } - set { _createdFileExtName = value; } - } - - public ECharset Charset - { - get { return _charset; } - set { _charset = value; } - } - - public bool IsDefault - { - get{ return _isDefault; } - set{ _isDefault = value; } - } - - private string _content; - public string Content - { - get { return _content; } - set { _content = value; } - } - } -} diff --git a/SiteServer.CMS/Model/TemplateLogInfo.cs b/SiteServer.CMS/Model/TemplateLogInfo.cs deleted file mode 100644 index 75713971d..000000000 --- a/SiteServer.CMS/Model/TemplateLogInfo.cs +++ /dev/null @@ -1,43 +0,0 @@ -using System; - -namespace SiteServer.CMS.Model -{ - public class TemplateLogInfo - { - public TemplateLogInfo() - { - Id = 0; - TemplateId = 0; - SiteId = 0; - AddDate = DateTime.Now; - AddUserName = string.Empty; - ContentLength = 0; - TemplateContent = string.Empty; - } - - public TemplateLogInfo(int id, int templateId, int siteId, DateTime addDate, string addUserName, int contentLength, string templateContent) - { - Id = id; - TemplateId = templateId; - SiteId = siteId; - AddDate = addDate; - AddUserName = addUserName; - ContentLength = contentLength; - TemplateContent = templateContent; - } - - public int Id { get; set; } - - public int TemplateId { get; set; } - - public int SiteId { get; set; } - - public DateTime AddDate { get; set; } - - public string AddUserName { get; set; } - - public int ContentLength { get; set; } - - public string TemplateContent { get; set; } - } -} diff --git a/SiteServer.CMS/Model/TemplateMatchInfo.cs b/SiteServer.CMS/Model/TemplateMatchInfo.cs deleted file mode 100644 index eec15d04d..000000000 --- a/SiteServer.CMS/Model/TemplateMatchInfo.cs +++ /dev/null @@ -1,45 +0,0 @@ -namespace SiteServer.CMS.Model -{ - public class TemplateMatchInfo - { - public TemplateMatchInfo() - { - Id = 0; - ChannelId = 0; - SiteId = 0; - ChannelTemplateId = 0; - ContentTemplateId = 0; - FilePath = string.Empty; - ChannelFilePathRule = string.Empty; - ContentFilePathRule = string.Empty; - } - - public TemplateMatchInfo(int id, int channelId, int siteId, int channelTemplateId, int contentTemplateId, string filePath, string channelFilePathRule, string contentFilePathRule) - { - Id = id; - ChannelId = channelId; - SiteId = siteId; - ChannelTemplateId = channelTemplateId; - ContentTemplateId = contentTemplateId; - FilePath = filePath; - ChannelFilePathRule = channelFilePathRule; - ContentFilePathRule = contentFilePathRule; - } - - public int Id { get; set; } - - public int ChannelId { get; set; } - - public int SiteId { get; set; } - - public int ChannelTemplateId { get; set; } - - public int ContentTemplateId { get; set; } - - public string FilePath { get; set; } - - public string ChannelFilePathRule { get; set; } - - public string ContentFilePathRule { get; set; } - } -} diff --git a/SiteServer.CMS/Model/UserInfo.cs b/SiteServer.CMS/Model/UserInfo.cs deleted file mode 100644 index b58a57d97..000000000 --- a/SiteServer.CMS/Model/UserInfo.cs +++ /dev/null @@ -1,138 +0,0 @@ -using System; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Model -{ - public class UserInfo: IUserInfo - { - public UserInfo() - { - Id = 0; - UserName = string.Empty; - Password = string.Empty; - PasswordFormat = string.Empty; - PasswordSalt = string.Empty; - CreateDate = DateUtils.SqlMinValue; - LastResetPasswordDate = DateUtils.SqlMinValue; - LastActivityDate = DateUtils.SqlMinValue; - CountOfLogin = 0; - CountOfFailedLogin = 0; - CountOfWriting = 0; - IsChecked = true; - IsLockedOut = false; - DisplayName = string.Empty; - Email = string.Empty; - Mobile = string.Empty; - AvatarUrl = string.Empty; - Organization = string.Empty; - Department = string.Empty; - Position = string.Empty; - Gender = string.Empty; - Birthday = string.Empty; - Education = string.Empty; - Graduation = string.Empty; - Address = string.Empty; - WeiXin = string.Empty; - Qq = string.Empty; - WeiBo = string.Empty; - Interests = string.Empty; - Signature = string.Empty; - } - - public UserInfo(object dataItem) - { - if (dataItem == null) return; - Id = SqlUtils.EvalInt(dataItem, nameof(Id)); - UserName = SqlUtils.EvalString(dataItem, nameof(UserName)); - Password = SqlUtils.EvalString(dataItem, nameof(Password)); - PasswordFormat = SqlUtils.EvalString(dataItem, nameof(PasswordFormat)); - PasswordSalt = SqlUtils.EvalString(dataItem, nameof(PasswordSalt)); - CreateDate = SqlUtils.EvalDateTime(dataItem, nameof(CreateDate)); - LastResetPasswordDate = SqlUtils.EvalDateTime(dataItem, nameof(LastResetPasswordDate)); - LastActivityDate = SqlUtils.EvalDateTime(dataItem, nameof(LastActivityDate)); - CountOfLogin = SqlUtils.EvalInt(dataItem, nameof(CountOfLogin)); - CountOfFailedLogin = SqlUtils.EvalInt(dataItem, nameof(CountOfFailedLogin)); - CountOfWriting = SqlUtils.EvalInt(dataItem, nameof(CountOfWriting)); - IsChecked = SqlUtils.EvalBool(dataItem, nameof(IsChecked)); - IsLockedOut = SqlUtils.EvalBool(dataItem, nameof(IsLockedOut)); - DisplayName = SqlUtils.EvalString(dataItem, nameof(DisplayName)); - Email = SqlUtils.EvalString(dataItem, nameof(Email)); - Mobile = SqlUtils.EvalString(dataItem, nameof(Mobile)); - AvatarUrl = SqlUtils.EvalString(dataItem, nameof(AvatarUrl)); - Organization = SqlUtils.EvalString(dataItem, nameof(Organization)); - Department = SqlUtils.EvalString(dataItem, nameof(Department)); - Position = SqlUtils.EvalString(dataItem, nameof(Position)); - Gender = SqlUtils.EvalString(dataItem, nameof(Gender)); - Birthday = SqlUtils.EvalString(dataItem, nameof(Birthday)); - Education = SqlUtils.EvalString(dataItem, nameof(Education)); - Graduation = SqlUtils.EvalString(dataItem, nameof(Graduation)); - Address = SqlUtils.EvalString(dataItem, nameof(Address)); - WeiXin = SqlUtils.EvalString(dataItem, nameof(WeiXin)); - Qq = SqlUtils.EvalString(dataItem, nameof(Qq)); - WeiBo = SqlUtils.EvalString(dataItem, nameof(WeiBo)); - Interests = SqlUtils.EvalString(dataItem, nameof(Interests)); - Signature = SqlUtils.EvalString(dataItem, nameof(Signature)); - } - - public int Id { get; set; } - - public string UserName { get; set; } - - public string Password { get; set; } - - public string PasswordFormat { get; set; } - - public string PasswordSalt { get; set; } - - public DateTime CreateDate { get; set; } - - public DateTime LastResetPasswordDate { get; set; } - - public DateTime LastActivityDate { get; set; } - - public int CountOfLogin { get; set; } - - public int CountOfFailedLogin { get; set; } - - public int CountOfWriting { get; set; } - - public bool IsChecked { get; set; } - - public bool IsLockedOut { get; set; } - - public string DisplayName { get; set; } - - public string Email { get; set; } - - public string Mobile { get; set; } - - public string AvatarUrl { get; set; } - - public string Organization { get; set; } - - public string Department { get; set; } - - public string Position { get; set; } - - public string Gender { get; set; } - - public string Birthday { get; set; } - - public string Education { get; set; } - - public string Graduation { get; set; } - - public string Address { get; set; } - - public string WeiXin { get; set; } - - public string Qq { get; set; } - - public string WeiBo { get; set; } - - public string Interests { get; set; } - - public string Signature { get; set; } - } -} diff --git a/SiteServer.CMS/Model/UserLogInfo.cs b/SiteServer.CMS/Model/UserLogInfo.cs deleted file mode 100644 index ccd413392..000000000 --- a/SiteServer.CMS/Model/UserLogInfo.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Model -{ - public class UserLogInfo: ILogInfo - { - public UserLogInfo() - { - Id = 0; - UserName = string.Empty; - IpAddress = string.Empty; - AddDate = DateTime.Now; - Action = string.Empty; - Summary = string.Empty; - } - - public UserLogInfo(int id, string userName, string ipAddress, DateTime addDate, string action, string summary) - { - Id = id; - UserName = userName; - IpAddress = ipAddress; - AddDate = addDate; - Action = action; - Summary = summary; - } - - public int Id { get; set; } - - public string UserName { get; set; } - - public string IpAddress { get; set; } - - public DateTime AddDate { get; set; } - - public string Action { get; set; } - - public string Summary { get; set; } - } -} diff --git a/SiteServer.CMS/Plugin/Apis/AdminApi.cs b/SiteServer.CMS/Plugin/Apis/AdminApi.cs deleted file mode 100644 index 5121cc423..000000000 --- a/SiteServer.CMS/Plugin/Apis/AdminApi.cs +++ /dev/null @@ -1,56 +0,0 @@ -using SiteServer.CMS.Core; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Plugin.Apis -{ - public class AdminApi : IAdminApi - { - private readonly IMetadata _metadata; - - public AdminApi(IMetadata metadata) - { - _metadata = metadata; - } - - public bool IsAdminNameExists(string adminName) - { - return DataProvider.AdministratorDao.IsAdminNameExists(adminName); - } - - public string AdminName - { - get - { - var request = new AuthRequest(); - return request.AdminName; - } - } - - public bool IsPluginAuthorized - { - get - { - var request = new AuthRequest(); - return request.AdminPermissions.HasAdministratorPermissions(_metadata.Id); - } - } - - public bool IsSiteAuthorized(int siteId) - { - var request = new AuthRequest(); - return request.AdminPermissions.HasAdministratorPermissions(_metadata.Id + siteId); - } - - public bool HasSitePermissions(int siteId, params string[] sitePermissions) - { - var request = new AuthRequest(); - return request.AdminPermissions.HasSitePermissions(siteId, sitePermissions); - } - - public bool HasChannelPermissions(int siteId, int channelId, params string[] channelPermissions) - { - var request = new AuthRequest(); - return request.AdminPermissions.HasChannelPermissions(siteId, channelId, channelPermissions); - } - } -} diff --git a/SiteServer.CMS/Plugin/Apis/ChannelApi.cs b/SiteServer.CMS/Plugin/Apis/ChannelApi.cs deleted file mode 100644 index 5031d7fa7..000000000 --- a/SiteServer.CMS/Plugin/Apis/ChannelApi.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Collections.Generic; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Plugin.Apis -{ - public class ChannelApi : IChannelApi - { - private ChannelApi() { } - - private static ChannelApi _instance; - public static ChannelApi Instance => _instance ?? (_instance = new ChannelApi()); - - public IChannelInfo GetChannelInfo(int siteId, int channelId) - { - return ChannelManager.GetChannelInfo(siteId, channelId); - } - - public IChannelInfo NewInstance(int siteId) - { - return new ChannelInfo - { - ParentId = siteId, - SiteId = siteId, - AddDate = DateTime.Now - }; - } - - public int Insert(int siteId, IChannelInfo nodeInfo) - { - return DataProvider.ChannelDao.Insert(nodeInfo); - } - - public List GetChannelIdList(int siteId) - { - return ChannelManager.GetChannelIdList(siteId); - } - - public List GetChannelIdList(int siteId, int parentId) - { - return ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(siteId, parentId == 0 ? siteId : parentId), EScopeType.Children, string.Empty, string.Empty, string.Empty); - } - - public List GetChannelIdList(int siteId, string adminName) - { - var channelIdList = new List(); - if (string.IsNullOrEmpty(adminName)) return channelIdList; - - var permissionManager = PermissionManager.GetInstance(adminName); - - if (permissionManager.IsConsoleAdministrator || permissionManager.IsSystemAdministrator)//如果是超级管理员或站点管理员 - { - channelIdList = ChannelManager.GetChannelIdList(siteId); - } - else - { - foreach (var channelId in permissionManager.ChannelPermissionChannelIdList) - { - var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var allChannelIdList = ChannelManager.GetChannelIdList(channelInfo, EScopeType.Descendant, string.Empty, string.Empty, string.Empty); - allChannelIdList.Insert(0, channelId); - - foreach (var ownChannelId in allChannelIdList) - { - var nodeInfo = ChannelManager.GetChannelInfo(siteId, ownChannelId); - if (nodeInfo != null) - { - channelIdList.Add(nodeInfo.Id); - } - } - } - } - return channelIdList; - } - - public string GetChannelName(int siteId, int channelId) - { - return ChannelManager.GetChannelName(siteId, channelId); - } - - public void Update(int siteId, IChannelInfo channelInfo) - { - DataProvider.ChannelDao.Update(channelInfo); - } - - public void Delete(int siteId, int channelId) - { - DataProvider.ChannelDao.Delete(siteId, channelId); - } - } -} diff --git a/SiteServer.CMS/Plugin/Apis/ConfigApi.cs b/SiteServer.CMS/Plugin/Apis/ConfigApi.cs deleted file mode 100644 index 110cb6ffa..000000000 --- a/SiteServer.CMS/Plugin/Apis/ConfigApi.cs +++ /dev/null @@ -1,97 +0,0 @@ -using System; -using Newtonsoft.Json; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Plugin.Apis -{ - public class ConfigApi : IConfigApi - { - private readonly IMetadata _metadata; - - public ConfigApi(IMetadata metadata) - { - _metadata = metadata; - } - - public bool SetConfig(int siteId, object config) - { - return SetConfig(siteId, string.Empty, config); - } - - public bool SetConfig(int siteId, string name, object config) - { - if (name == null) name = string.Empty; - - try - { - if (config == null) - { - DataProvider.PluginConfigDao.Delete(_metadata.Id, siteId, name); - } - else - { - var settings = new JsonSerializerSettings - { - NullValueHandling = NullValueHandling.Ignore - }; - var json = JsonConvert.SerializeObject(config, Formatting.Indented, settings); - if (DataProvider.PluginConfigDao.IsExists(_metadata.Id, siteId, name)) - { - var configInfo = new PluginConfigInfo(0, _metadata.Id, siteId, name, json); - DataProvider.PluginConfigDao.Update(configInfo); - } - else - { - var configInfo = new PluginConfigInfo(0, _metadata.Id, siteId, name, json); - DataProvider.PluginConfigDao.Insert(configInfo); - } - } - } - catch (Exception ex) - { - LogUtils.AddErrorLog(_metadata.Id, ex); - return false; - } - return true; - } - - public T GetConfig(int siteId, string name = "") - { - if (name == null) name = string.Empty; - - try - { - var value = DataProvider.PluginConfigDao.GetValue(_metadata.Id, siteId, name); - if (!string.IsNullOrEmpty(value)) - { - return JsonConvert.DeserializeObject(value); - } - } - catch (Exception ex) - { - LogUtils.AddErrorLog(_metadata.Id, ex); - } - return default(T); - } - - public bool RemoveConfig(int siteId, string name = "") - { - if (name == null) name = string.Empty; - - try - { - DataProvider.PluginConfigDao.Delete(_metadata.Id, siteId, name); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(_metadata.Id, ex); - return false; - } - return true; - } - - public IAttributes SystemConfig => ConfigManager.SystemConfigInfo; - } -} diff --git a/SiteServer.CMS/Plugin/Apis/ContentApi.cs b/SiteServer.CMS/Plugin/Apis/ContentApi.cs deleted file mode 100644 index 6dfbbba06..000000000 --- a/SiteServer.CMS/Plugin/Apis/ContentApi.cs +++ /dev/null @@ -1,257 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Data; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Plugin.Apis -{ - public class ContentApi : IContentApi - { - private ContentApi() { } - - private static ContentApi _instance; - public static ContentApi Instance => _instance ?? (_instance = new ContentApi()); - - public IContentInfo GetContentInfo(int siteId, int channelId, int contentId) - { - if (siteId <= 0 || channelId <= 0 || contentId <= 0) return null; - - var siteInfo = SiteManager.GetSiteInfo(siteId); - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - - return DataProvider.ContentDao.GetContentInfo(tableName, contentId); - } - - public List GetContentInfoList(int siteId, int channelId, string whereString, string orderString, int limit, int offset) - { - if (siteId <= 0 || channelId <= 0) return null; - - var siteInfo = SiteManager.GetSiteInfo(siteId); - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - - return DataProvider.ContentDao.GetListByLimitAndOffset(tableName, channelId, whereString, orderString, limit, offset); - } - - public int GetCount(int siteId, int channelId, string whereString) - { - if (siteId <= 0 || channelId <= 0) return 0; - - var siteInfo = SiteManager.GetSiteInfo(siteId); - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - - return DataProvider.ContentDao.GetCount(tableName, channelId, whereString); - } - - public string GetTableName(int siteId, int channelId) - { - if (siteId <= 0 || channelId <= 0) return string.Empty; - - var siteInfo = SiteManager.GetSiteInfo(siteId); - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - return ChannelManager.GetTableName(siteInfo, nodeInfo); - } - - public List GetTableColumns(int siteId, int channelId) - { - if (siteId <= 0 || channelId <= 0) return null; - - var siteInfo = SiteManager.GetSiteInfo(siteId); - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(siteId, channelId); - - var tableStyleInfoList = TableStyleManager.GetTableStyleInfoList(tableName, relatedIdentities); - var tableColumnList = new List - { - new TableColumn - { - AttributeName = ContentAttribute.Title, - DataType = DataType.VarChar, - DataLength = 255, - InputStyle = new InputStyle - { - InputType = InputType.Text, - DisplayName = "标题", - IsRequired = true, - ValidateType = ValidateType.None - } - } - }; - - foreach (var styleInfo in tableStyleInfoList) - { - tableColumnList.Add(new TableColumn - { - AttributeName = styleInfo.AttributeName, - DataType = DataType.VarChar, - DataLength = 50, - InputStyle = new InputStyle - { - InputType = styleInfo.InputType, - DisplayName = styleInfo.DisplayName, - DefaultValue = styleInfo.DefaultValue, - IsRequired = styleInfo.Additional.IsRequired, - ValidateType = styleInfo.Additional.ValidateType, - MinNum = styleInfo.Additional.MinNum, - MaxNum = styleInfo.Additional.MaxNum, - RegExp = styleInfo.Additional.RegExp, - Width = styleInfo.Additional.Width, - } - }); - } - - tableColumnList.Add(new TableColumn - { - AttributeName = ContentAttribute.IsTop, - DataType = DataType.VarChar, - DataLength = 18, - InputStyle = new InputStyle - { - InputType = InputType.CheckBox, - DisplayName = "置顶" - } - }); - tableColumnList.Add(new TableColumn - { - AttributeName = ContentAttribute.IsRecommend, - DataType = DataType.VarChar, - DataLength = 18, - InputStyle = new InputStyle - { - InputType = InputType.CheckBox, - DisplayName = "推荐" - } - }); - tableColumnList.Add(new TableColumn - { - AttributeName = ContentAttribute.IsHot, - DataType = DataType.VarChar, - DataLength = 18, - InputStyle = new InputStyle - { - InputType = InputType.CheckBox, - DisplayName = "热点" - } - }); - tableColumnList.Add(new TableColumn - { - AttributeName = ContentAttribute.IsColor, - DataType = DataType.VarChar, - DataLength = 18, - InputStyle = new InputStyle - { - InputType = InputType.CheckBox, - DisplayName = "醒目" - } - }); - tableColumnList.Add(new TableColumn - { - AttributeName = ContentAttribute.AddDate, - DataType = DataType.DateTime, - InputStyle = new InputStyle - { - InputType = InputType.DateTime, - DisplayName = "添加时间" - } - }); - - return tableColumnList; - } - - public string GetContentValue(int siteId, int channelId, int contentId, string attributeName) - { - if (siteId <= 0 || channelId <= 0 || contentId <= 0) return null; - - var siteInfo = SiteManager.GetSiteInfo(siteId); - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - - return DataProvider.ContentDao.GetValue(tableName, contentId, attributeName); - } - - public IContentInfo NewInstance() - { - return new ContentInfo(); - } - - public IContentInfo Parse(object dataItem) - { - var contentInfo = NewInstance(); - contentInfo.Load(dataItem); - return contentInfo; - } - - public IContentInfo Parse(IDataReader rdr) - { - var contentInfo = NewInstance(); - contentInfo.Load(rdr); - return contentInfo; - } - - public IContentInfo Parse(NameValueCollection attributes) - { - var contentInfo = NewInstance(); - contentInfo.Load(attributes); - return contentInfo; - } - - public IContentInfo Parse(string str) - { - var contentInfo = NewInstance(); - contentInfo.Load(str); - return contentInfo; - } - - //public void SetValuesToContentInfo(int siteId, int channelId, NameValueCollection form, IContentInfo contentInfo) - //{ - // var siteInfo = SiteManager.GetSiteInfo(siteId); - // var nodeInfo = NodeManager.GetChannelInfo(siteId, channelId); - // var tableName = NodeManager.GetTableName(siteInfo, nodeInfo); - // var tableStyle = NodeManager.GetTableStyle(siteInfo, nodeInfo); - // var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(siteId, channelId); - - // var extendImageUrl = ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.ImageUrl); - // if (form.AllKeys.Contains(StringUtils.LowerFirst(extendImageUrl))) - // { - // form[extendImageUrl] = form[StringUtils.LowerFirst(extendImageUrl)]; - // } - - // InputTypeParser.AddValuesToAttributes(tableStyle, tableName, siteInfo, relatedIdentities, form, contentInfo.ToNameValueCollection(), ContentAttribute.HiddenAttributes); - //} - - public int Insert(int siteId, int channelId, IContentInfo contentInfo) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - - return DataProvider.ContentDao.Insert(tableName, siteInfo, contentInfo); - } - - public void Update(int siteId, int channelId, IContentInfo contentInfo) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - - DataProvider.ContentDao.Update(tableName, siteInfo, contentInfo); - } - - public void Delete(int siteId, int channelId, int contentId) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - var contentIdList = new List { contentId }; - DataProvider.ContentDao.TrashContents(siteId, tableName, contentIdList); - } - - public List GetContentIdList(int siteId, int channelId) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - return DataProvider.ContentDao.GetContentIdListCheckedByChannelId(tableName, siteId, channelId); - } - } -} diff --git a/SiteServer.CMS/Plugin/Apis/FilesApi.cs b/SiteServer.CMS/Plugin/Apis/FilesApi.cs deleted file mode 100644 index 789babc6f..000000000 --- a/SiteServer.CMS/Plugin/Apis/FilesApi.cs +++ /dev/null @@ -1,92 +0,0 @@ -using System.Collections.Generic; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Plugin.Apis -{ - public class FilesApi : IFilesApi - { - private FilesApi() { } - - private static FilesApi _instance; - public static FilesApi Instance => _instance ?? (_instance = new FilesApi()); - - public void MoveFiles(int sourceSiteId, int targetSiteId, List relatedUrls) - { - if (sourceSiteId == targetSiteId) return; - - var siteInfo = SiteManager.GetSiteInfo(sourceSiteId); - var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); - if (siteInfo == null || targetSiteInfo == null) return; - - foreach (var relatedUrl in relatedUrls) - { - if (!string.IsNullOrEmpty(relatedUrl) && !PageUtils.IsProtocolUrl(relatedUrl)) - { - FileUtility.MoveFile(siteInfo, targetSiteInfo, relatedUrl); - } - } - } - - public void AddWaterMark(int siteId, string filePath) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - FileUtility.AddWaterMark(siteInfo, filePath); - } - - public string GetUploadFilePath(int siteId, string fileName) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - var localDirectoryPath = PathUtility.GetUploadDirectoryPath(siteInfo, PathUtils.GetExtension(fileName)); - var localFileName = PathUtility.GetUploadFileName(siteInfo, fileName); - return PathUtils.Combine(localDirectoryPath, localFileName); - } - - public string GetTemporaryFilesPath(string relatedPath) - { - return PathUtils.GetTemporaryFilesPath(relatedPath); - } - - public string GetSiteUrl(int siteId) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - return PageUtility.GetSiteUrl(siteInfo, false); - } - - public string GetSiteUrl(int siteId, string relatedUrl) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - return PageUtility.GetSiteUrl(siteInfo, relatedUrl, false); - } - - public string GetSiteUrlByFilePath(string filePath) - { - var siteId = SiteApi.Instance.GetSiteIdByFilePath(filePath); - var siteInfo = SiteManager.GetSiteInfo(siteId); - return PageUtility.GetSiteUrlByPhysicalPath(siteInfo, filePath, false); - } - - public string GetRootUrl(string relatedUrl) - { - return PageUtils.GetRootUrl(relatedUrl); - } - - public string GetAdminDirectoryUrl(string relatedUrl) - { - return PageUtils.GetAdminDirectoryUrl(relatedUrl); - } - - public string GetChannelUrl(int siteId, int channelId) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - return PageUtility.GetChannelUrl(siteInfo, ChannelManager.GetChannelInfo(siteId, channelId), false); - } - - public string GetContentUrl(int siteId, int channelId, int contentId) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - return PageUtility.GetContentUrl(siteInfo, ChannelManager.GetChannelInfo(siteId, channelId), contentId, false); - } - } -} diff --git a/SiteServer.CMS/Plugin/Apis/ParseApi.cs b/SiteServer.CMS/Plugin/Apis/ParseApi.cs deleted file mode 100644 index 3dfdd48ea..000000000 --- a/SiteServer.CMS/Plugin/Apis/ParseApi.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System.Collections.Generic; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Parsers; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Plugin.Apis -{ - public class ParseApi : IParseApi - { - private ParseApi() { } - - private static ParseApi _instance; - public static ParseApi Instance => _instance ?? (_instance = new ParseApi()); - - public Dictionary GetStlElements(string innerXml, List stlElementNames) - { - return StlInnerUtility.GetStlElements(innerXml, stlElementNames); - } - - public string ParseInnerXml(string innerXml, IParseContext context) - { - return StlParserManager.ParseInnerContent(innerXml, context); - } - - public string ParseAttributeValue(string attributeValue, IParseContext context) - { - var siteInfo = SiteManager.GetSiteInfo(context.SiteId); - var templateInfo = new TemplateInfo - { - Id = context.TemplateId, - TemplateType = context.TemplateType - }; - var pageInfo = new PageInfo(context.ChannelId, context.ContentId, siteInfo, templateInfo, new Dictionary()); - var contextInfo = new ContextInfo(pageInfo); - return StlEntityParser.ReplaceStlEntitiesForAttributeValue(attributeValue, pageInfo, contextInfo); - } - - public string HtmlToXml(string html) - { - return StlParserUtility.HtmlToXml(html); - } - - public string XmlToHtml(string xml) - { - return StlParserUtility.XmlToHtml(xml); - } - - public string GetCurrentUrl(IParseContext context) - { - var siteInfo = SiteManager.GetSiteInfo(context.SiteId); - return StlParserUtility.GetStlCurrentUrl(siteInfo, context.ChannelId, context.ContentId, - context.ContentInfo, context.TemplateType, context.TemplateId, false); - } - } -} diff --git a/SiteServer.CMS/Plugin/Apis/PluginApi.cs b/SiteServer.CMS/Plugin/Apis/PluginApi.cs deleted file mode 100644 index a0ced4a29..000000000 --- a/SiteServer.CMS/Plugin/Apis/PluginApi.cs +++ /dev/null @@ -1,46 +0,0 @@ -using System.Web; -using SiteServer.CMS.Api; -using SiteServer.CMS.Core; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Plugin.Apis -{ - public class PluginApi : IPluginApi - { - private readonly IMetadata _metadata; - - public PluginApi(IMetadata metadata) - { - _metadata = metadata; - } - - public IRequest AuthRequest(HttpRequest httpRequest) - { - return new AuthRequest(httpRequest); - } - - public string GetPluginUrl(string relatedUrl = "") - { - return PageUtility.GetSiteFilesUrl(ApiManager.OuterApiUrl, PageUtils.Combine(DirectoryUtils.SiteFiles.Plugins, _metadata.Id, relatedUrl)); - } - - public string GetPluginApiUrl(string action = "", string id = "") - { - return ApiRoutePlugin.GetUrl(_metadata.Id, action, id); - } - - public string GetPluginPath(string relatedPath = "") - { - var path = PathUtils.Combine(PathUtils.GetPluginPath(_metadata.Id), relatedPath); - DirectoryUtils.CreateDirectoryIfNotExists(path); - return path; - } - - public T GetPlugin(string pluginId) where T : PluginBase - { - var pluginInfo = PluginManager.GetPluginInfo(pluginId); - return pluginInfo?.Plugin as T; - } - } -} diff --git a/SiteServer.CMS/Plugin/Apis/SiteApi.cs b/SiteServer.CMS/Plugin/Apis/SiteApi.cs deleted file mode 100644 index c531a7c33..000000000 --- a/SiteServer.CMS/Plugin/Apis/SiteApi.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System.Collections.Generic; -using SiteServer.CMS.Core; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Plugin.Apis -{ - public class SiteApi : ISiteApi - { - private SiteApi() { } - - private static SiteApi _instance; - public static SiteApi Instance => _instance ?? (_instance = new SiteApi()); - - public int GetSiteIdByFilePath(string path) - { - var siteInfo = PathUtility.GetSiteInfo(path); - return siteInfo?.Id ?? 0; - } - - public string GetSitePath(int siteId) - { - if (siteId <= 0) return null; - - var siteInfo = SiteManager.GetSiteInfo(siteId); - return siteInfo == null ? null : PathUtility.GetSitePath(siteInfo); - } - - public List GetSiteIdList() - { - return SiteManager.GetSiteIdList(); - } - - public ISiteInfo GetSiteInfo(int siteId) - { - return SiteManager.GetSiteInfo(siteId); - } - - public List GetSiteInfoList(string adminName) - { - var permissionManager = PermissionManager.GetInstance(adminName); - return SiteManager.GetWritingSiteInfoList(permissionManager); - } - } -} diff --git a/SiteServer.CMS/Plugin/Apis/UserApi.cs b/SiteServer.CMS/Plugin/Apis/UserApi.cs deleted file mode 100644 index 8c2238d60..000000000 --- a/SiteServer.CMS/Plugin/Apis/UserApi.cs +++ /dev/null @@ -1,134 +0,0 @@ -using System.Collections.Generic; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Plugin.Apis -{ - public class UserApi : IUserApi - { - private UserApi() { } - - private static UserApi _instance; - public static UserApi Instance => _instance ?? (_instance = new UserApi()); - - public IUserInfo GetUserInfoByUserId(int userId) - { - var userInfo = DataProvider.UserDao.GetUserInfo(userId); - if (userInfo != null) - { - userInfo.Password = string.Empty; - userInfo.PasswordFormat = string.Empty; - userInfo.PasswordSalt = string.Empty; - } - return userInfo; - } - - public IUserInfo GetUserInfoByUserName(string userName) - { - var userInfo = DataProvider.UserDao.GetUserInfoByUserName(userName); - if (userInfo != null) - { - userInfo.Password = string.Empty; - userInfo.PasswordFormat = string.Empty; - userInfo.PasswordSalt = string.Empty; - } - return userInfo; - } - - public IUserInfo GetUserInfoByEmail(string email) - { - var userInfo = DataProvider.UserDao.GetUserInfoByEmail(email); - if (userInfo != null) - { - userInfo.Password = string.Empty; - userInfo.PasswordFormat = string.Empty; - userInfo.PasswordSalt = string.Empty; - } - return userInfo; - } - - public IUserInfo GetUserInfoByMobile(string mobile) - { - var userInfo = DataProvider.UserDao.GetUserInfoByMobile(mobile); - if (userInfo != null) - { - userInfo.Password = string.Empty; - userInfo.PasswordFormat = string.Empty; - userInfo.PasswordSalt = string.Empty; - } - return userInfo; - } - - public string GetMobileByAccount(string account) - { - return DataProvider.UserDao.GetMobileByAccount(account); - } - - public bool IsUserNameExists(string userName) - { - return DataProvider.UserDao.IsUserNameExists(userName); - } - - public bool IsEmailExists(string email) - { - return DataProvider.UserDao.IsEmailExists(email); - } - - public bool IsMobileExists(string mobile) - { - return DataProvider.UserDao.IsMobileExists(mobile); - } - - public IUserInfo NewInstance() - { - return new UserInfo(); - } - - public bool Insert(IUserInfo userInfo, string password, out string errorMessage) - { - return DataProvider.UserDao.Insert(userInfo, password, PageUtils.GetIpAddress(), out errorMessage); - } - - public bool Validate(string account, string password, out string userName, out string errorMessage) - { - return DataProvider.UserDao.Validate(account, password, out userName, out errorMessage); - } - - public void UpdateLastActivityDateAndCountOfFailedLogin(string userName) - { - DataProvider.UserDao.UpdateLastActivityDateAndCountOfFailedLogin(userName); - } - - public void UpdateLastActivityDateAndCountOfLogin(string userName) - { - DataProvider.UserDao.UpdateLastActivityDateAndCountOfLogin(userName); - } - - public bool ChangePassword(string userName, string password, out string errorMessage) - { - return DataProvider.UserDao.ChangePassword(userName, password, out errorMessage); - } - - public void Update(IUserInfo userInfo) - { - DataProvider.UserDao.Update(userInfo); - } - - public bool IsPasswordCorrect(string password, out string errorMessage) - { - return DataProvider.UserDao.IsPasswordCorrect(password, out errorMessage); - } - - public void AddLog(string userName, string action, string summary) - { - LogUtils.AddUserLog(userName, action, summary); - } - - public List GetLogs(string userName, int totalNum, string action = "") - { - return DataProvider.UserLogDao.List(userName, totalNum, action); - } - } -} diff --git a/SiteServer.CMS/Plugin/AuthRequest.cs b/SiteServer.CMS/Plugin/AuthRequest.cs deleted file mode 100644 index 2063dec6d..000000000 --- a/SiteServer.CMS/Plugin/AuthRequest.cs +++ /dev/null @@ -1,422 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.IO; -using System.Web; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; -using Newtonsoft.Json.Linq; -using Newtonsoft.Json.Serialization; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; -using SiteServer.Utils.Auth; - -namespace SiteServer.CMS.Plugin -{ - public class AuthRequest : IRequest - { - private const string UserAccessToken = "ss_user_access_token"; - private const string AdministratorAccessToken = "ss_administrator_access_token"; - private const int AccessTokenExpireDays = 7; - - public AuthRequest(): this(HttpContext.Current.Request) - { - } - - public AuthRequest(HttpRequest request) - { - HttpRequest = request; - - UserAuthentication(); - AdministratorAuthentication(); - } - - private JObject _postData; - public JObject PostData - { - get - { - if (_postData != null) return _postData; - var bodyStream = new StreamReader(HttpRequest.InputStream); - bodyStream.BaseStream.Seek(0, SeekOrigin.Begin); - var raw = bodyStream.ReadToEnd(); - _postData = !string.IsNullOrEmpty(raw) ? JObject.Parse(raw) : new JObject(); - return _postData; - } - } - - public HttpRequest HttpRequest { get; } - - public NameValueCollection QueryString => HttpRequest.QueryString; - - public NameValueCollection Form => HttpRequest.Form; - - public int SiteId => GetQueryInt("siteId"); - - public int ChannelId => GetQueryInt("channelId"); - - public int ContentId => GetQueryInt("contentId"); - - public string ReturnUrl => GetQueryString("ReturnUrl"); - - public bool IsQueryExists(string name) - { - return HttpRequest.QueryString[name] != null; - } - - public string GetQueryString(string name) - { - return !string.IsNullOrEmpty(HttpRequest.QueryString[name]) ? PageUtils.FilterSql(HttpRequest.QueryString[name]) : null; - } - - public int GetQueryInt(string name, int defaultValue = 0) - { - return !string.IsNullOrEmpty(HttpRequest.QueryString[name]) ? TranslateUtils.ToInt(HttpRequest.QueryString[name]) : defaultValue; - } - - public decimal GetQueryDecimal(string name, decimal defaultValue = 0) - { - return !string.IsNullOrEmpty(HttpRequest.QueryString[name]) ? TranslateUtils.ToDecimal(HttpRequest.QueryString[name]) : defaultValue; - } - - public bool GetQueryBool(string name, bool defaultValue = false) - { - var str = HttpRequest.QueryString[name]; - var retval = !string.IsNullOrEmpty(str) ? TranslateUtils.ToBool(str) : defaultValue; - return retval; - } - - public bool IsPostExists(string name) - { - JToken value; - return PostData.TryGetValue(name, out value); - } - - public T GetPostObject(string name = "") - { - string json; - if (string.IsNullOrEmpty(name)) - { - var bodyStream = new StreamReader(HttpRequest.InputStream); - bodyStream.BaseStream.Seek(0, SeekOrigin.Begin); - json = bodyStream.ReadToEnd(); - } - else - { - json = GetPostString(name); - } - var settings = new JsonSerializerSettings - { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }; - var timeFormat = new IsoDateTimeConverter - { - DateTimeFormat = "yyyy-MM-dd HH:mm:ss" - }; - settings.Converters.Add(timeFormat); - return JsonConvert.DeserializeObject(json, settings); - } - - public string GetPostString(string name) - { - return PostData[name]?.ToString(); - } - - public int GetPostInt(string name, int defaultValue = 0) - { - return TranslateUtils.ToInt(PostData[name]?.ToString(), defaultValue); - } - - public decimal GetPostDecimal(string name, decimal defaultValue = 0) - { - return TranslateUtils.ToDecimal(PostData[name]?.ToString(), defaultValue); - } - - public bool GetPostBool(string name, bool defaultValue = false) - { - return TranslateUtils.ToBool(PostData[name]?.ToString(), defaultValue); - } - - public NameValueCollection GetPostCollection() - { - var formCollection = new NameValueCollection(); - foreach (var item in PostData) - { - formCollection[item.Key] = item.Value.ToString(); - } - return formCollection; - } - - #region Log - - public void AddSiteLog(int siteId, string action) - { - AddSiteLog(siteId, 0, 0, action, string.Empty); - } - - public void AddSiteLog(int siteId, string action, string summary) - { - AddSiteLog(siteId, 0, 0, action, summary); - } - - public void AddSiteLog(int siteId, int channelId, int contentId, string action, string summary) - { - if (siteId <= 0) - { - LogUtils.AddAdminLog(AdminName, action, summary); - } - else - { - try - { - if (!string.IsNullOrEmpty(action)) - { - action = StringUtils.MaxLengthText(action, 250); - } - if (!string.IsNullOrEmpty(summary)) - { - summary = StringUtils.MaxLengthText(summary, 250); - } - if (channelId < 0) - { - channelId = -channelId; - } - var logInfo = new SiteLogInfo(0, siteId, channelId, contentId, AdminName, PageUtils.GetIpAddress(), DateTime.Now, action, summary); - DataProvider.SiteLogDao.Insert(logInfo); - } - catch - { - // ignored - } - } - } - - public void AddAdminLog(string action, string summary) - { - LogUtils.AddAdminLog(AdminName, action, summary); - } - - public void AddAdminLog(string action) - { - LogUtils.AddAdminLog(AdminName, action); - } - - #endregion - - #region Cookie - - public void SetCookie(string name, string value, DateTime expires) - { - CookieUtils.SetCookie(name, value, expires); - } - - public string GetCookie(string name) - { - return CookieUtils.GetCookie(name); - } - - public bool IsCookieExists(string name) - { - return CookieUtils.IsExists(name); - } - - #endregion - - #region Administrator - - public string AdminName { get; private set; } - - public PermissionManager AdminPermissions { get; private set; } - - public bool IsAdminLoggin => !string.IsNullOrEmpty(AdminName) && AdminName != AdminManager.AnonymousUserName; - - private AdministratorInfo _adminInfo; - public IAdministratorInfo AdminInfo - { - get - { - if (_adminInfo != null) return _adminInfo; - - if (!string.IsNullOrEmpty(AdminName)) - { - _adminInfo = AdminManager.GetAdminInfo(AdminName); - } - return _adminInfo ?? (_adminInfo = new AdministratorInfo()); - } - } - - protected void AdministratorAuthentication() - { - var administratorTokenStr = string.Empty; - if (!string.IsNullOrEmpty(CookieUtils.GetCookie(AdministratorAccessToken))) - { - administratorTokenStr = CookieUtils.GetCookie(AdministratorAccessToken); - } - else if (!string.IsNullOrEmpty(HttpRequest.Headers.Get(AdministratorAccessToken))) - { - administratorTokenStr = HttpRequest.Headers.Get(AdministratorAccessToken); - } - else if (!string.IsNullOrEmpty(HttpRequest.QueryString[AdministratorAccessToken])) - { - administratorTokenStr = HttpRequest.QueryString[AdministratorAccessToken]; - } - - AdminName = string.IsNullOrEmpty(administratorTokenStr) ? AdminManager.AnonymousUserName : GetAdministratorToken(administratorTokenStr).AdministratorName; - AdminPermissions = PermissionManager.GetInstance(AdminName); - } - - public string GetAdminNameByToken(string token) - { - var userToken = GetAdministratorToken(token); - return userToken?.AdministratorName; - } - - public static AdministratorToken GetAdministratorToken(string tokenStr) - { - if (string.IsNullOrEmpty(tokenStr)) return new AdministratorToken(); - - try - { - var userToken = JsonWebToken.DecodeToObject(tokenStr, WebConfigUtils.SecretKey); - - if (userToken.AddDate.AddDays(AccessTokenExpireDays) > DateTime.Now) - { - return userToken; - } - } - catch - { - // ignored - } - return new AdministratorToken(); - } - - public string GetAdminTokenByAdminName(string administratorName) - { - if (string.IsNullOrEmpty(administratorName)) return null; - - var administratorToken = new AdministratorToken() - { - AdministratorName = administratorName, - AddDate = DateTime.Now - }; - - return JsonWebToken.Encode(administratorToken, WebConfigUtils.SecretKey, JwtHashAlgorithm.HS256); - } - - public void AdminLogin(string administratorName) - { - if (string.IsNullOrEmpty(administratorName)) return; - - AdminName = administratorName; - LogUtils.AddAdminLog(administratorName, "管理员登录"); - CookieUtils.SetCookie(AdministratorAccessToken, GetAdminTokenByAdminName(administratorName), DateTime.Now.AddDays(AccessTokenExpireDays)); - } - - public void AdminLogout() - { - CookieUtils.Erase(AdministratorAccessToken); - } - - #endregion - - #region User - - protected void UserAuthentication() - { - var userTokenStr = string.Empty; - if (!string.IsNullOrEmpty(CookieUtils.GetCookie(UserAccessToken))) - { - userTokenStr = CookieUtils.GetCookie(UserAccessToken); - } - else if (!string.IsNullOrEmpty(HttpRequest.Headers.Get(UserAccessToken))) - { - userTokenStr = HttpRequest.Headers.Get(UserAccessToken); - } - else if (!string.IsNullOrEmpty(HttpRequest.QueryString[UserAccessToken])) - { - userTokenStr = HttpRequest.QueryString[UserAccessToken]; - } - - if (string.IsNullOrEmpty(userTokenStr)) return; - - UserName = GetUserToken(userTokenStr).UserName; - } - - public bool IsUserLoggin => !string.IsNullOrEmpty(UserName); - - public string UserName { get; private set; } - - private UserInfo _userInfo; - public IUserInfo UserInfo - { - get - { - if (_userInfo != null) return _userInfo; - - if (!string.IsNullOrEmpty(UserName)) - { - _userInfo = DataProvider.UserDao.GetUserInfoByUserName(UserName); - } - return _userInfo ?? (_userInfo = new UserInfo()); - } - } - - public string GetUserNameByToken(string token) - { - var userToken = GetUserToken(token); - return userToken?.UserName; - } - - public static UserToken GetUserToken(string tokenStr) - { - if (string.IsNullOrEmpty(tokenStr)) return new UserToken(); - - try - { - var userToken = JsonWebToken.DecodeToObject(tokenStr, WebConfigUtils.SecretKey); - - if (userToken.AddDate.AddDays(AccessTokenExpireDays) > DateTime.Now) - { - return userToken; - } - } - catch - { - // ignored - } - return new UserToken(); - } - - public string GetUserTokenByUserName(string userName) - { - if (string.IsNullOrEmpty(userName)) return null; - - var userToken = new UserToken - { - UserName = userName, - AddDate = DateTime.Now - }; - - return JsonWebToken.Encode(userToken, WebConfigUtils.SecretKey, JwtHashAlgorithm.HS256); - } - - public void UserLogin(string userName) - { - if (string.IsNullOrEmpty(userName)) return; - - UserName = userName; - LogUtils.AddUserLoginLog(userName); - CookieUtils.SetCookie(UserAccessToken, GetUserTokenByUserName(userName), DateTime.Now.AddDays(AccessTokenExpireDays)); - } - - public void UserLogout() - { - UserName = null; - CookieUtils.Erase(UserAccessToken); - } - - #endregion - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Plugin/Model/PluginApiCollection.cs b/SiteServer.CMS/Plugin/Model/PluginApiCollection.cs deleted file mode 100644 index 2f0cbe86e..000000000 --- a/SiteServer.CMS/Plugin/Model/PluginApiCollection.cs +++ /dev/null @@ -1,27 +0,0 @@ -using SiteServer.Plugin; - -namespace SiteServer.CMS.Plugin.Model -{ - public class PluginApiCollection: IApiCollection - { - public IAdminApi AdminApi { get; set; } - - public IConfigApi ConfigApi { get; set; } - - public IContentApi ContentApi { get; set; } - - public IDataApi DataApi { get; set; } - - public IFilesApi FilesApi { get; set; } - - public IChannelApi ChannelApi { get; set; } - - public IParseApi ParseApi { get; set; } - - public IPluginApi PluginApi { get; set; } - - public ISiteApi SiteApi { get; set; } - - public IUserApi UserApi { get; set; } - } -} diff --git a/SiteServer.CMS/Plugin/Model/PluginEnvironment.cs b/SiteServer.CMS/Plugin/Model/PluginEnvironment.cs deleted file mode 100644 index 76c809f74..000000000 --- a/SiteServer.CMS/Plugin/Model/PluginEnvironment.cs +++ /dev/null @@ -1,23 +0,0 @@ -using SiteServer.Plugin; - -namespace SiteServer.CMS.Plugin.Model -{ - public class PluginEnvironment: IEnvironment - { - public PluginEnvironment(DatabaseType databaseType, string connectionString, string adminDirectory, string physicalApplicationPath) - { - DatabaseType = databaseType; - ConnectionString = connectionString; - AdminDirectory = adminDirectory; - PhysicalApplicationPath = physicalApplicationPath; - } - - public DatabaseType DatabaseType { get; } - - public string ConnectionString { get; } - - public string AdminDirectory { get; } - - public string PhysicalApplicationPath { get; } - } -} diff --git a/SiteServer.CMS/Plugin/Model/PluginInfo.cs b/SiteServer.CMS/Plugin/Model/PluginInfo.cs deleted file mode 100644 index d101a34ac..000000000 --- a/SiteServer.CMS/Plugin/Model/PluginInfo.cs +++ /dev/null @@ -1,62 +0,0 @@ -using Newtonsoft.Json; -using SiteServer.CMS.Core; -using SiteServer.CMS.Packaging; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Plugin.Model -{ - public class PluginInfo - { - public PluginInfo(string directoryName, PackageMetadata metadata, string errorMessage) - { - if (metadata != null) - { - Id = metadata.Id; - Metadata = metadata; - } - else - { - Id = directoryName; - } - IsRunnable = false; - ErrorMessage = errorMessage; - } - - public PluginInfo(PackageMetadata metadata, PluginService service, PluginBase plugin, long initTime) - { - Id = plugin.Id; - Metadata = metadata; - Plugin = plugin; - Service = service; - InitTime = initTime; - - bool isDisabled; - int taxis; - DataProvider.PluginDao.SetIsDisabledAndTaxis(Id, out isDisabled, out taxis); - - IsRunnable = plugin != null; - IsDisabled = isDisabled; - Taxis = taxis; - } - - public string Id { get; } - - public PackageMetadata Metadata { get; } - - [JsonIgnore] - public PluginBase Plugin { get; } - - [JsonIgnore] - public PluginService Service { get; } - - public long InitTime { get; } - - public string ErrorMessage { get; } - - public bool IsRunnable { get; set; } - - public bool IsDisabled { get; set; } - - public int Taxis { get; set; } - } -} diff --git a/SiteServer.CMS/Plugin/Model/PluginParseContext.cs b/SiteServer.CMS/Plugin/Model/PluginParseContext.cs deleted file mode 100644 index b45142479..000000000 --- a/SiteServer.CMS/Plugin/Model/PluginParseContext.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Collections.Generic; -using SiteServer.CMS.StlParser.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Plugin.Model -{ - public class PluginParseContext: IParseContext - { - public PluginParseContext(Dictionary stlAttributes, string stlInnerXml, PageInfo pageInfo, ContextInfo contextInfo) - { - SiteId = contextInfo.SiteInfo.Id; - ChannelId = contextInfo.ChannelId; - ContentId = contextInfo.ContentId; - ContentInfo = contextInfo.ContentInfo; - TemplateType = pageInfo.TemplateInfo.TemplateType; - TemplateId = pageInfo.TemplateInfo.Id; - - StlPageHead = pageInfo.HeadCodes; - StlPageBody = pageInfo.BodyCodes; - StlPageFoot = pageInfo.FootCodes; - StlAttributes = stlAttributes; - StlInnerXml = stlInnerXml; - StlItems = pageInfo.PluginItems; - IsStlEntity = contextInfo.IsStlEntity; - } - - public int SiteId { get; set; } - - public int ChannelId { get; set; } - - public int ContentId { get; set; } - - public IContentInfo ContentInfo { get; set; } - - public TemplateType TemplateType { get; set; } - - public int TemplateId { get; set; } - - public SortedDictionary StlPageHead { get; } - - public SortedDictionary StlPageBody { get; } - - public SortedDictionary StlPageFoot { get; } - - public Dictionary StlAttributes { get; set; } - - public string StlInnerXml { get; set; } - - public Dictionary StlItems { get; } - - public bool IsStlEntity { get; } - } -} diff --git a/SiteServer.CMS/Plugin/Model/PluginService.cs b/SiteServer.CMS/Plugin/Model/PluginService.cs deleted file mode 100644 index 1ad6fd132..000000000 --- a/SiteServer.CMS/Plugin/Model/PluginService.cs +++ /dev/null @@ -1,374 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Web.UI.WebControls; -using SiteServer.Plugin; -using Menu = SiteServer.Plugin.Menu; - -namespace SiteServer.CMS.Plugin.Model -{ - public class PluginService: IService - { - public string PluginId { get; private set; } - - public IMetadata Metadata { get; private set; } - - public Menu PluginMenu { get; private set; } - public Func SiteMenuFunc { get; private set; } - public string ContentTableName { get; private set; } - - public List ContentTableColumns { get; private set; } - public Dictionary> DatabaseTables { get; private set; } - public List ContentLinks { get; private set; } - - public event EventHandler ContentAddCompleted; - - public void OnContentAddCompleted(ContentEventArgs e) - { - ContentAddCompleted?.Invoke(this, e); - } - - public event EventHandler ContentDeleteCompleted; - - public void OnContentDeleteCompleted(ContentEventArgs e) - { - ContentDeleteCompleted?.Invoke(this, e); - } - - public event EventHandler ContentTranslateCompleted; - - public void OnContentTranslateCompleted(ContentTranslateEventArgs e) - { - ContentTranslateCompleted?.Invoke(this, e); - } - - //public Dictionary> ContentFormCustomized { get; private set; } - - //public IService AddCustomizedContentForm(string attributeName, Func customized) - //{ - // if (ContentFormCustomized == null) - // { - // ContentFormCustomized = new Dictionary>(); - // } - - // ContentFormCustomized[attributeName] = customized; - - // return this; - //} - - public event ContentFormLoadEventHandler ContentFormLoad; - - public string OnContentFormLoad(ContentFormLoadEventArgs e) - { - return ContentFormLoad?.Invoke(this, e); - } - - public event EventHandler ContentFormSubmit; - - public void OnContentFormSubmit(ContentFormSubmitEventArgs e) - { - ContentFormSubmit?.Invoke(this, e); - } - - public Dictionary> StlElementsToParse { get; private set; } - - //public Func JsonGet { get; private set; } - //public Func JsonGetWithName { get; private set; } - //public Func JsonGetWithNameAndId { get; private set; } - - //public Func JsonPost { get; private set; } - //public Func JsonPostWithName { get; private set; } - //public Func JsonPostWithNameAndId { get; private set; } - - //public Func JsonPut { get; private set; } - //public Func JsonPutWithName { get; private set; } - //public Func JsonPutWithNameAndId { get; private set; } - - //public Func JsonDelete { get; private set; } - //public Func JsonDeleteWithName { get; private set; } - //public Func JsonDeleteWithNameAndId { get; private set; } - - //public Func HttpGet { get; private set; } - //public Func HttpGetWithName { get; private set; } - //public Func HttpGetWithNameAndId { get; private set; } - - //public Func HttpPost { get; private set; } - //public Func HttpPostWithName { get; private set; } - //public Func HttpPostWithNameAndId { get; private set; } - - //public Func HttpPut { get; private set; } - //public Func HttpPutWithName { get; private set; } - //public Func HttpPutWithNameAndId { get; private set; } - - //public Func HttpDelete { get; private set; } - //public Func HttpDeleteWithName { get; private set; } - //public Func HttpDeleteWithNameAndId { get; private set; } - - public PluginService(IMetadata metadata) - { - PluginId = metadata.Id; - Metadata = metadata; - } - - public IService AddPluginMenu(Menu menu) - { - PluginMenu = menu; - return this; - } - - public IService AddSiteMenu(Func siteMenuFunc) - { - SiteMenuFunc = siteMenuFunc; - return this; - } - - public IService AddContentModel(string tableName, List tableColumns) - { - ContentTableName = tableName; - ContentTableColumns = tableColumns; - - return this; - } - - public IService AddDatabaseTable(string tableName, List tableColumns) - { - if (DatabaseTables == null) - { - DatabaseTables = new Dictionary>(); - } - - DatabaseTables[tableName] = tableColumns; - - return this; - } - - public IService AddContentLink(HyperLink link) - { - if (ContentLinks == null) - { - ContentLinks = new List(); - } - - ContentLinks.Add(link); - - return this; - } - - public IService AddStlElementParser(string elementName, Func parse) - { - if (StlElementsToParse == null) - { - StlElementsToParse = new Dictionary>(); - } - - StlElementsToParse[elementName] = parse; - - return this; - } - - public event ApiEventHandler ApiGet; - public event ApiEventHandler ApiPost; - public event ApiEventHandler ApiPut; - public event ApiEventHandler ApiDelete; - - public object OnApiGet(ApiEventArgs e) - { - return ApiGet?.Invoke(this, e); - } - - public object OnApiPost(ApiEventArgs e) - { - return ApiPost?.Invoke(this, e); - } - - public object OnApiPut(ApiEventArgs e) - { - return ApiPut?.Invoke(this, e); - } - - public object OnApiDelete(ApiEventArgs e) - { - return ApiDelete?.Invoke(this, e); - } - - //public IService AddJsonGet(Func jsonGet) - //{ - // JsonGet = jsonGet; - - // return this; - //} - - //public IService AddJsonGet(Func jsonGetWithName) - //{ - // JsonGetWithName = jsonGetWithName; - - // return this; - //} - - //public IService AddJsonGet(Func jsonGetWithNameAndId) - //{ - // JsonGetWithNameAndId = jsonGetWithNameAndId; - - // return this; - //} - - //public IService AddJsonPost(Func jsonPost) - //{ - // JsonPost = jsonPost; - - // return this; - //} - - //public IService AddJsonPost(Func jsonPostWithName) - //{ - // JsonPostWithName = jsonPostWithName; - - // return this; - //} - - //public IService AddJsonPost(Func jsonPostWithNameAndId) - //{ - // JsonPostWithNameAndId = jsonPostWithNameAndId; - - // return this; - //} - - //public IService AddJsonPut(Func jsonPut) - //{ - // JsonPut = jsonPut; - - // return this; - //} - - //public IService AddJsonPut(Func jsonPutWithName) - //{ - // JsonPutWithName = jsonPutWithName; - - // return this; - //} - - //public IService AddJsonPut(Func jsonPutWithNameAndId) - //{ - // JsonPutWithNameAndId = jsonPutWithNameAndId; - - // return this; - //} - - //public IService AddJsonDelete(Func jsonDelete) - //{ - // JsonDelete = jsonDelete; - - // return this; - //} - - //public IService AddJsonDelete(Func jsonDeleteWithName) - //{ - // JsonDeleteWithName = jsonDeleteWithName; - - // return this; - //} - - //public IService AddJsonDelete(Func jsonDeleteWithNameAndId) - //{ - // JsonDeleteWithNameAndId = jsonDeleteWithNameAndId; - - // return this; - //} - - //public IService AddHttpGet(Func httpGet) - //{ - // HttpGet = httpGet; - - // return this; - //} - - //public IService AddHttpGet(Func httpGetWithName) - //{ - // HttpGetWithName = httpGetWithName; - - // return this; - //} - - //public IService AddHttpGet(Func httpGetWithNameAndId) - //{ - // HttpGetWithNameAndId = httpGetWithNameAndId; - - // return this; - //} - - //public IService AddHttpPost(Func httpPost) - //{ - // HttpPost = httpPost; - - // return this; - //} - - //public IService AddHttpPost(Func httpPostWithName) - //{ - // HttpPostWithName = httpPostWithName; - - // return this; - //} - - //public IService AddHttpPost(Func httpPostWithNameAndId) - //{ - // HttpPostWithNameAndId = httpPostWithNameAndId; - - // return this; - //} - - //public IService AddHttpPut(Func httpPut) - //{ - // HttpPut = httpPut; - - // return this; - //} - - //public IService AddHttpPut(Func httpPutWithName) - //{ - // HttpPutWithName = httpPutWithName; - - // return this; - //} - - //public IService AddHttpPut(Func httpPutWithNameAndId) - //{ - // HttpPutWithNameAndId = httpPutWithNameAndId; - - // return this; - //} - - //public IService AddHttpDelete(Func httpDelete) - //{ - // HttpDelete = httpDelete; - - // return this; - //} - - //public IService AddHttpDelete(Func httpDeleteWithName) - //{ - // HttpDeleteWithName = httpDeleteWithName; - - // return this; - //} - - //public IService AddHttpDelete(Func httpDeleteWithNameAndId) - //{ - // HttpDeleteWithNameAndId = httpDeleteWithNameAndId; - - // return this; - //} - - public event EventHandler BeforeStlParse; - public event EventHandler AfterStlParse; - - public void OnBeforeStlParse(ParseEventArgs e) - { - BeforeStlParse?.Invoke(this, e); - } - - public void OnAfterStlParse(ParseEventArgs e) - { - AfterStlParse?.Invoke(this, e); - } - } -} diff --git a/SiteServer.CMS/Plugin/PluginContentManager.cs b/SiteServer.CMS/Plugin/PluginContentManager.cs deleted file mode 100644 index 039c9630d..000000000 --- a/SiteServer.CMS/Plugin/PluginContentManager.cs +++ /dev/null @@ -1,122 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Web.UI.WebControls; -using SiteServer.CMS.Model; -using SiteServer.CMS.Plugin.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Plugin -{ - public class PluginContentManager - { - public static List GetContentModelPlugins() - { - var list = new List(); - - foreach (var service in PluginManager.Services) - { - if (string.IsNullOrEmpty(service.ContentTableName) || service.ContentTableColumns == null || service.ContentTableColumns.Count == 0) continue; - - list.Add(service.Metadata); - } - - return list; - } - - public static List GetAllContentRelatedPlugins(bool includeContentTable) - { - var list = new List(); - - foreach (var service in PluginManager.Services) - { - var isContentModel = PluginContentTableManager.IsContentTable(service); - - if (!includeContentTable && isContentModel) continue; - - if (isContentModel) - { - list.Add(service.Metadata); - } - else if (service.ContentLinks != null && service.ContentLinks.Count > 0) - { - list.Add(service.Metadata); - } - } - - return list; - } - - public static List GetContentPlugins(ChannelInfo channelInfo, bool includeContentTable) - { - var list = new List(); - var pluginIds = TranslateUtils.StringCollectionToStringList(channelInfo.ContentRelatedPluginIds); - if (!string.IsNullOrEmpty(channelInfo.ContentModelPluginId)) - { - pluginIds.Add(channelInfo.ContentModelPluginId); - } - - foreach (var service in PluginManager.Services) - { - if (!pluginIds.Contains(service.PluginId)) continue; - - if (!includeContentTable && PluginContentTableManager.IsContentTable(service)) continue; - - list.Add(service); - } - - return list; - } - - public static Dictionary> GetContentLinks(ChannelInfo nodeInfo) - { - if (string.IsNullOrEmpty(nodeInfo.ContentRelatedPluginIds) && - string.IsNullOrEmpty(nodeInfo.ContentModelPluginId)) - { - return null; - } - - var dict = new Dictionary>(); - var pluginIds = TranslateUtils.StringCollectionToStringList(nodeInfo.ContentRelatedPluginIds); - if (!string.IsNullOrEmpty(nodeInfo.ContentModelPluginId)) - { - pluginIds.Add(nodeInfo.ContentModelPluginId); - } - - foreach (var service in PluginManager.Services) - { - if (!pluginIds.Contains(service.PluginId) || service.ContentLinks == null || service.ContentLinks.Count == 0) continue; - - dict[service.PluginId] = service.ContentLinks; - } - - return dict; - } - - //public static Dictionary>> GetContentFormCustomized(ChannelInfo nodeInfo) - //{ - // if (string.IsNullOrEmpty(nodeInfo.ContentRelatedPluginIds) && - // string.IsNullOrEmpty(nodeInfo.ContentModelPluginId)) - // { - // return null; - // } - - // var dict = new Dictionary>>(); - - // var pluginIds = TranslateUtils.StringCollectionToStringList(nodeInfo.ContentRelatedPluginIds); - // if (!string.IsNullOrEmpty(nodeInfo.ContentModelPluginId)) - // { - // pluginIds.Add(nodeInfo.ContentModelPluginId); - // } - - // foreach (var service in PluginManager.Services) - // { - // if (!pluginIds.Contains(service.PluginId) || service.ContentFormCustomized == null || service.ContentFormCustomized.Count == 0) continue; - - // dict[service.PluginId] = service.ContentFormCustomized; - // } - - // return dict; - //} - } -} diff --git a/SiteServer.CMS/Plugin/PluginContentTableManager.cs b/SiteServer.CMS/Plugin/PluginContentTableManager.cs deleted file mode 100644 index 892ae7556..000000000 --- a/SiteServer.CMS/Plugin/PluginContentTableManager.cs +++ /dev/null @@ -1,293 +0,0 @@ -using System.Collections.Generic; -using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Plugin.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Plugin -{ - public class PluginContentTableManager - { - public static bool IsContentTable(PluginService service) - { - return !string.IsNullOrEmpty(service.ContentTableName) && - service.ContentTableColumns != null && service.ContentTableColumns.Count > 0; - } - - public static string GetTableName(string pluginId) - { - foreach (var service in PluginManager.Services) - { - if (service.PluginId == pluginId && IsContentTable(service)) - { - return service.ContentTableName; - } - } - - return string.Empty; - } - - public static void SyncContentTable(PluginService service) - { - if (!IsContentTable(service)) return; - - var tableName = service.ContentTableName; - - if (!DataProvider.TableDao.IsExists(tableName)) - { - ContentTableCreateMetadatas(service.Metadata, tableName, service.ContentTableColumns); - } - else - { - ContentTableUpdateMetadatas(tableName, service.ContentTableColumns); - } - - if (!DataProvider.DatabaseDao.IsTableExists(tableName)) - { - DataProvider.TableDao.CreateDbTable(tableName); - } - else - { - DataProvider.TableDao.SyncDbTable(tableName); - } - - ContentTableCreateOrUpdateStyles(tableName, service.ContentTableColumns); - } - - private static void ContentTableCreateMetadatas(IMetadata metadata, string tableName, List tableColumns) - { - DataProvider.TableDao.DeleteCollectionTableInfoAndDbTable(tableName); - DataProvider.TableMetadataDao.Delete(tableName); - DataProvider.TableStyleDao.Delete(tableName); - - var metadataInfoList = new List(); - foreach (var tableColumn in tableColumns) - { - if (string.IsNullOrEmpty(tableColumn.AttributeName) || - ContentAttribute.AllAttributesLowercase.Contains(tableColumn.AttributeName.ToLower())) - continue; - - metadataInfoList.Add(new TableMetadataInfo(0, tableName, - tableColumn.AttributeName, tableColumn.DataType, tableColumn.DataLength, - 0, true)); - } - - DataProvider.TableDao.Insert( - new TableInfo(0, tableName, $"插件内容表:{metadata.Title}", 0, false, false, false, string.Empty), - metadataInfoList); - } - - private static void ContentTableUpdateMetadatas(string tableName, List tableColumns) - { - var metadataInfoListToInsert = new List(); - var metadataInfoListToUpdate = new List(); - - foreach (var tableColumn in tableColumns) - { - if (string.IsNullOrEmpty(tableColumn.AttributeName) || - ContentAttribute.AllAttributesLowercase.Contains(tableColumn.AttributeName.ToLower())) - continue; - - if (!TableMetadataManager.IsAttributeNameExists(tableName, tableColumn.AttributeName)) - { - var metadataInfo = new TableMetadataInfo(0, tableName, - tableColumn.AttributeName, tableColumn.DataType, - tableColumn.DataLength, 0, true); - metadataInfoListToInsert.Add(metadataInfo); - } - else - { - var isEquals = true; - - var metadataInfo = TableMetadataManager.GetTableMetadataInfo(tableName, tableColumn.AttributeName); - - if (metadataInfo.DataType != tableColumn.DataType) - { - isEquals = false; - metadataInfo.DataType = tableColumn.DataType; - } - - if (metadataInfo.DataLength != tableColumn.DataLength) - { - isEquals = false; - metadataInfo.DataLength = tableColumn.DataLength; - } - - if (isEquals) continue; - - metadataInfoListToUpdate.Add(metadataInfo); - } - } - - foreach (var metadataInfo in metadataInfoListToInsert) - { - DataProvider.TableMetadataDao.Insert(metadataInfo); - } - foreach (var metadataInfo in metadataInfoListToUpdate) - { - DataProvider.TableMetadataDao.Update(metadataInfo); - } - } - - private static void ContentTableCreateOrUpdateStyles(string tableName, List tableColumns) - { - var styleInfoList = new List(); - var columnTaxis = 0; - foreach (var tableColumn in tableColumns) - { - var inputStyle = tableColumn.InputStyle ?? new InputStyle - { - InputType = InputType.Hidden - }; - - columnTaxis++; - var styleInfo = TableStyleManager.GetTableStyleInfo(tableName, tableColumn.AttributeName, new List { 0 }); - - var isEquals = true; - - if (styleInfo.InputType != inputStyle.InputType) - { - isEquals = false; - styleInfo.InputType = inputStyle.InputType; - } - - if (!StringUtils.EqualsIgnoreNull(styleInfo.DisplayName, inputStyle.DisplayName)) - { - isEquals = false; - styleInfo.DisplayName = inputStyle.DisplayName; - } - - if (!StringUtils.EqualsIgnoreNull(styleInfo.HelpText, inputStyle.HelpText)) - { - isEquals = false; - styleInfo.HelpText = inputStyle.HelpText; - } - - if (!StringUtils.EqualsIgnoreNull(styleInfo.DefaultValue, inputStyle.DefaultValue)) - { - isEquals = false; - styleInfo.DefaultValue = inputStyle.DefaultValue; - } - - if (styleInfo.Taxis != columnTaxis) - { - isEquals = false; - styleInfo.Taxis = columnTaxis; - } - - if (styleInfo.Additional.IsRequired != inputStyle.IsRequired) - { - isEquals = false; - styleInfo.Additional.IsRequired = inputStyle.IsRequired; - } - - if (styleInfo.Additional.ValidateType != inputStyle.ValidateType) - { - isEquals = false; - styleInfo.Additional.ValidateType = inputStyle.ValidateType; - } - - if (styleInfo.Additional.MinNum != inputStyle.MinNum) - { - isEquals = false; - styleInfo.Additional.MinNum = inputStyle.MinNum; - } - - if (styleInfo.Additional.MaxNum != inputStyle.MaxNum) - { - isEquals = false; - styleInfo.Additional.MaxNum = inputStyle.MaxNum; - } - - if (!StringUtils.EqualsIgnoreNull(styleInfo.Additional.RegExp, inputStyle.RegExp)) - { - isEquals = false; - styleInfo.Additional.RegExp = inputStyle.RegExp; - } - - if (!StringUtils.EqualsIgnoreNull(styleInfo.Additional.Width, inputStyle.Width)) - { - isEquals = false; - styleInfo.Additional.Width = inputStyle.Width; - } - - if (!(styleInfo.Additional.Height == 0 && string.IsNullOrEmpty(inputStyle.Height)) && styleInfo.Additional.Height != TranslateUtils.ToInt(inputStyle.Height)) - { - isEquals = false; - styleInfo.Additional.Height = TranslateUtils.ToInt(inputStyle.Height); - } - - if (!(styleInfo.StyleItems == null && inputStyle.ListItems == null)) - { - var styleItems = styleInfo.StyleItems ?? new List(); - var listItems = inputStyle.ListItems ?? new List(); - - if (styleItems.Count > listItems.Count) - { - isEquals = false; - styleItems.RemoveRange(listItems.Count, styleItems.Count - listItems.Count); - } - - for (var i = 0; i < listItems.Count; i++) - { - var listItem = listItems[i]; - if (styleItems.Count < i + 1) - { - isEquals = false; - styleItems.Add(new TableStyleItemInfo - { - TableStyleId = styleInfo.Id, - ItemTitle = listItem.Text, - ItemValue = listItem.Value, - IsSelected = listItem.Selected - }); - } - else - { - var styleItem = styleItems[i]; - - if (!StringUtils.EqualsIgnoreNull(styleItem.ItemTitle, listItem.Text)) - { - isEquals = false; - styleItem.ItemTitle = listItem.Text; - } - - if (!StringUtils.EqualsIgnoreNull(styleItem.ItemValue, listItem.Value)) - { - isEquals = false; - styleItem.ItemValue = listItem.Value; - } - - if (styleItem.IsSelected != listItem.Selected) - { - isEquals = false; - styleItem.IsSelected = listItem.Selected; - } - } - } - } - - if (isEquals) continue; - - styleInfo.IsVisibleInList = false; - styleInfo.Additional.IsValidate = true; - styleInfoList.Add(styleInfo); - } - - foreach (var styleInfo in styleInfoList) - { - if (styleInfo.Id == 0) - { - TableStyleManager.Insert(styleInfo); - } - else - { - TableStyleManager.Update(styleInfo); - TableStyleManager.DeleteAndInsertStyleItems(styleInfo.Id, styleInfo.StyleItems); - } - } - } - } -} diff --git a/SiteServer.CMS/Plugin/PluginDatabaseTableManager.cs b/SiteServer.CMS/Plugin/PluginDatabaseTableManager.cs deleted file mode 100644 index 8bd0682ea..000000000 --- a/SiteServer.CMS/Plugin/PluginDatabaseTableManager.cs +++ /dev/null @@ -1,28 +0,0 @@ -using SiteServer.CMS.Core; -using SiteServer.CMS.Plugin.Model; - -namespace SiteServer.CMS.Plugin -{ - public class PluginDatabaseTableManager - { - public static void SyncTable(PluginService service) - { - if (service.DatabaseTables == null || service.DatabaseTables.Count <= 0) return; - - foreach (var tableName in service.DatabaseTables.Keys) - { - var tableColumns = service.DatabaseTables[tableName]; - if (tableColumns == null || tableColumns.Count == 0) continue; - - if (!DataProvider.DatabaseDao.IsTableExists(tableName)) - { - DataProvider.DatabaseDao.CreatePluginTable(service.PluginId, tableName, tableColumns); - } - else - { - DataProvider.DatabaseDao.AlterPluginTable(service.PluginId, tableName, tableColumns); - } - } - } - } -} diff --git a/SiteServer.CMS/Plugin/PluginMenuManager.cs b/SiteServer.CMS/Plugin/PluginMenuManager.cs deleted file mode 100644 index 8eb1eafad..000000000 --- a/SiteServer.CMS/Plugin/PluginMenuManager.cs +++ /dev/null @@ -1,193 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Web.UI; -using SiteServer.CMS.Core; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Plugin -{ - public class PluginMenuManager - { - private static readonly Dictionary PluginIconClassDict = new Dictionary(); - - public static string GetPluginIconClass(string pluginId) - { - string iconClass; - if (PluginIconClassDict.TryGetValue(pluginId, out iconClass)) - { - return iconClass; - } - return string.Empty; - } - - public static Dictionary GetTopMenus() - { - var menus = new Dictionary(); - - foreach (var service in PluginManager.Services) - { - if (service.PluginMenu == null) continue; - - try - { - var pluginMenu = GetMenu(service.PluginId, 0, service.PluginMenu, 0); - - if (!string.IsNullOrEmpty(pluginMenu.IconClass)) - { - PluginIconClassDict[service.PluginId] = pluginMenu.IconClass; - } - - menus.Add(service.PluginId, pluginMenu); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(service.PluginId, ex); - } - } - - return menus; - } - - public static Dictionary GetSiteMenus(int siteId) - { - var menus = new Dictionary(); - - foreach (var service in PluginManager.Services) - { - if (service.SiteMenuFunc == null) continue; - - Menu metadataMenu = null; - try - { - metadataMenu = service.SiteMenuFunc.Invoke(siteId); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(service.PluginId, ex); - } - - if (metadataMenu == null) continue; - - var pluginMenu = GetMenu(service.PluginId, siteId, metadataMenu, 0); - - if (!string.IsNullOrEmpty(pluginMenu.IconClass)) - { - PluginIconClassDict[service.PluginId] = pluginMenu.IconClass; - } - - menus.Add(service.PluginId, pluginMenu); - } - - return menus; - } - - public static string GetMenuHref(string pluginId, string href, int siteId) - { - if (PageUtils.IsAbsoluteUrl(href)) - { - return href; - } - - var url = PageUtils.AddQueryStringIfNotExists(PageUtils.GetPluginDirectoryUrl(pluginId, href), new NameValueCollection - { - {"v", StringUtils.GetRandomInt(1, 1000).ToString()} - }); - if (siteId > 0) - { - url = PageUtils.AddQueryStringIfNotExists(url, new NameValueCollection - { - {"siteId", siteId.ToString()} - }); - } - return url; - } - - public static string GetMenuContentHref(string pluginId, string href, int siteId, int channelId, int contentId, string returnUrl) - { - if (PageUtils.IsAbsoluteUrl(href)) - { - return href; - } - return PageUtils.AddQueryStringIfNotExists(PageUtils.GetPluginDirectoryUrl(pluginId, href), new NameValueCollection - { - {"siteId", siteId.ToString()}, - {"channelId", channelId.ToString()}, - {"contentId", contentId.ToString()}, - {"returnUrl", returnUrl}, - {"v", StringUtils.GetRandomInt(1, 1000).ToString()} - }); - } - - internal static Menu GetMenu(string pluginId, int siteId, Menu metadataMenu, int i) - { - var menu = new Menu - { - Id = metadataMenu.Id, - Text = metadataMenu.Text, - Href = metadataMenu.Href, - Target = metadataMenu.Target, - IconClass = metadataMenu.IconClass - }; - - if (string.IsNullOrEmpty(menu.Id)) - { - menu.Id = pluginId + i; - } - if (!string.IsNullOrEmpty(menu.Href)) - { - menu.Href = GetMenuHref(pluginId, menu.Href, siteId); - } - if (string.IsNullOrEmpty(menu.Target)) - { - menu.Target = "right"; - } - - if (metadataMenu.Menus != null && metadataMenu.Menus.Count > 0) - { - var chlildren = new List(); - var x = 1; - foreach (var childMetadataMenu in metadataMenu.Menus) - { - var child = GetMenu(pluginId, siteId, childMetadataMenu, x++); - - chlildren.Add(child); - } - menu.Menus = chlildren; - } - - return menu; - } - - public static List GetTopPermissions() - { - var permissions = new List(); - - foreach (var service in PluginManager.Services) - { - if (service.PluginMenu != null) - { - permissions.Add(new PermissionConfigManager.PermissionConfig(service.PluginId, $"系统管理 -> {service.Metadata.Title}(插件)")); - } - } - - return permissions; - } - - public static List GetSitePermissions(int siteId) - { - var permissions = new List(); - - foreach (var service in PluginManager.Services) - { - if (service.SiteMenuFunc != null) - { - permissions.Add(new PermissionConfigManager.PermissionConfig(service.PluginId, $"{service.Metadata.Title}(插件)")); - } - } - - return permissions; - } - } -} diff --git a/SiteServer.CMS/Plugin/PluginStlParserManager.cs b/SiteServer.CMS/Plugin/PluginStlParserManager.cs deleted file mode 100644 index 06e6dbd28..000000000 --- a/SiteServer.CMS/Plugin/PluginStlParserManager.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.Collections.Generic; -using SiteServer.CMS.Plugin.Model; - -namespace SiteServer.CMS.Plugin -{ - public class PluginStlParserContentManager - { - public static Dictionary> GetParses() - { - var elementsToParse = new Dictionary>(); - - foreach (var service in PluginManager.Services) - { - if (service.StlElementsToParse != null && service.StlElementsToParse.Count > 0) - { - foreach (var elementName in service.StlElementsToParse.Keys) - { - elementsToParse[elementName.ToLower()] = service.StlElementsToParse[elementName]; - } - } - } - - return elementsToParse; - } - } -} diff --git a/SiteServer.CMS/Properties/AssemblyInfo.cs b/SiteServer.CMS/Properties/AssemblyInfo.cs deleted file mode 100644 index 4ec162e38..000000000 --- a/SiteServer.CMS/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// 有关程序集的一般信息由以下 -// 控制。更改这些特性值可修改 -// 与程序集关联的信息。 -[assembly: AssemblyTitle("SiteServer.CMS")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("SiteServer.CMS")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// 将 ComVisible 设置为 false 会使此程序集中的类型 -//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 -//请将此类型的 ComVisible 特性设置为 true。 -[assembly: ComVisible(false)] - -// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID -[assembly: Guid("55efd315-e628-4293-9505-d1f919ade339")] - -// 程序集的版本信息由下列四个值组成: -// -// 主版本 -// 次版本 -// 生成号 -// 修订号 -// -// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 -//通过使用 "*",如下所示: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.0.0")] -[assembly: AssemblyFileVersion("0.0.0")] -[assembly: AssemblyInformationalVersion("0.0.0-dev")] diff --git a/SiteServer.CMS/Provider/AdministratorDao.cs b/SiteServer.CMS/Provider/AdministratorDao.cs deleted file mode 100644 index 039013d31..000000000 --- a/SiteServer.CMS/Provider/AdministratorDao.cs +++ /dev/null @@ -1,1133 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Security.Cryptography; -using System.Text; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Utils.Auth; -using SiteServer.Plugin; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Provider -{ - public class AdministratorDao : DataProviderBase - { - public override string TableName => "siteserver_Administrator"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.Id), - DataType = DataType.Integer, - IsPrimaryKey = true, - IsIdentity = true - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.UserName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.Password), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.PasswordFormat), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.PasswordSalt), - DataType = DataType.VarChar, - Length = 128 - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.CreationDate), - DataType = DataType.DateTime - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.LastActivityDate), - DataType = DataType.DateTime - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.CountOfLogin), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.CountOfFailedLogin), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.CreatorUserName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.IsLockedOut), - DataType = DataType.VarChar, - Length = 18 - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.SiteIdCollection), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.SiteId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.DepartmentId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.AreaId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.DisplayName), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.Email), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(AdministratorInfo.Mobile), - DataType = DataType.VarChar, - Length = 20 - } - }; - - private const string SqlSelectUser = - "SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreationDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, CreatorUserName, IsLockedOut, SiteIdCollection, SiteId, DepartmentId, AreaId, DisplayName, Email, Mobile FROM siteserver_Administrator WHERE UserName = @UserName"; - - private const string SqlSelectUserByEmail = - "SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreationDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, CreatorUserName, IsLockedOut, SiteIdCollection, SiteId, DepartmentId, AreaId, DisplayName, Email, Mobile FROM siteserver_Administrator WHERE Email = @Email"; - - private const string SqlSelectUserByMobile = - "SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreationDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, CreatorUserName, IsLockedOut, SiteIdCollection, SiteId, DepartmentId, AreaId, DisplayName, Email, Mobile FROM siteserver_Administrator WHERE Mobile = @Mobile"; - - private const string SqlSelectUsername = "SELECT UserName FROM siteserver_Administrator WHERE UserName = @UserName"; - - private const string SqlSelectUsernameByEmail = - "SELECT UserName FROM siteserver_Administrator WHERE Email = @Email"; - - private const string SqlSelectUsernameByMobile = - "SELECT UserName FROM siteserver_Administrator WHERE Mobile = @Mobile"; - - private const string SqlSelectMobileByUsername = - "SELECT Mobile FROM siteserver_Administrator WHERE UserName = @UserName"; - - private const string SqlSelectCreatorUserName = - "SELECT CreatorUserName FROM siteserver_Administrator WHERE UserName = @UserName"; - - private const string SqlSelectDisplayName = - "SELECT DisplayName FROM siteserver_Administrator WHERE UserName = @UserName"; - - private const string SqlSelectDepartmentId = - "SELECT DepartmentId FROM siteserver_Administrator WHERE UserName = @UserName"; - - private const string SqlSelectAreaId = "SELECT AreaId FROM siteserver_Administrator WHERE UserName = @UserName"; - - private const string SqlSelectSiteIdCollection = - "SELECT SiteIdCollection FROM siteserver_Administrator WHERE UserName = @UserName"; - - private const string SqlSelectSiteId = - "SELECT SiteId FROM siteserver_Administrator WHERE UserName = @UserName"; - - private const string SqlInsertUser = - "INSERT INTO siteserver_Administrator (UserName, Password, PasswordFormat, PasswordSalt, CreationDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, CreatorUserName, IsLockedOut, SiteIdCollection, SiteId, DepartmentId, AreaId, DisplayName, Email, Mobile) VALUES (@UserName, @Password, @PasswordFormat, @PasswordSalt, @CreationDate, @LastActivityDate, @CountOfLogin, @CountOfFailedLogin, @CreatorUserName, @IsLockedOut, @SiteIdCollection, @SiteId, @DepartmentId, @AreaId, @DisplayName, @Email, @Mobile)"; - - private const string SqlUpdateUser = - "UPDATE siteserver_Administrator SET LastActivityDate = @LastActivityDate, CountOfLogin = @CountOfLogin, CountOfFailedLogin = @CountOfFailedLogin, IsLockedOut = @IsLockedOut, SiteIdCollection = @SiteIdCollection, SiteId = @SiteId, DepartmentId = @DepartmentId, AreaId = @AreaId, DisplayName = @DisplayName, Email = @Email, Mobile = @Mobile WHERE UserName = @UserName"; - - private const string SqlUpdateSiteId = - "UPDATE siteserver_Administrator SET SiteId = @SiteId WHERE UserName = @UserName"; - - private const string SqlUpdateSiteIdCollection = - "UPDATE siteserver_Administrator SET SiteIdCollection = @SiteIdCollection WHERE UserName = @UserName"; - - private const string SqlUpdatePassword = - "UPDATE siteserver_Administrator SET Password = @Password, PasswordFormat = @PasswordFormat, PasswordSalt = @PasswordSalt WHERE UserName = @UserName"; - - private const string SqlDeleteUser = "DELETE FROM siteserver_Administrator WHERE UserName = @UserName"; - - private const string ParmUsername = "@UserName"; - private const string ParmPassword = "@Password"; - private const string ParmPasswordFormat = "@PasswordFormat"; - private const string ParmPasswordSalt = "@PasswordSalt"; - private const string ParmCreationDate = "@CreationDate"; - private const string ParmLastActivityDate = "@LastActivityDate"; - private const string ParmCountOfLogin = "@CountOfLogin"; - private const string ParmCountOfFailedLogin = "@CountOfFailedLogin"; - private const string ParmCreatorUsername = "@CreatorUserName"; - private const string ParmIsLockedOut = "@IsLockedOut"; - private const string ParmSiteIdCollection = "@SiteIdCollection"; - private const string ParmSiteId = "@SiteId"; - private const string ParmDepartmentId = "@DepartmentId"; - private const string ParmAreaId = "@AreaId"; - private const string ParmDisplayname = "@DisplayName"; - private const string ParmEmail = "@Email"; - private const string ParmMobile = "@Mobile"; - - private void Insert(AdministratorInfo info) - { - IDataParameter[] insertParms = - { - GetParameter(ParmUsername, DataType.VarChar, 255, info.UserName), - GetParameter(ParmPassword, DataType.VarChar, 255, info.Password), - GetParameter(ParmPasswordFormat, DataType.VarChar, 50, - EPasswordFormatUtils.GetValue(info.PasswordFormat)), - GetParameter(ParmPasswordSalt, DataType.VarChar, 128, info.PasswordSalt), - GetParameter(ParmCreationDate, DataType.DateTime, info.CreationDate), - GetParameter(ParmLastActivityDate, DataType.DateTime, info.LastActivityDate), - GetParameter(ParmCountOfLogin, DataType.Integer, info.CountOfLogin), - GetParameter(ParmCountOfFailedLogin, DataType.Integer, info.CountOfFailedLogin), - GetParameter(ParmCreatorUsername, DataType.VarChar, 255, info.CreatorUserName), - GetParameter(ParmIsLockedOut, DataType.VarChar, 18, info.IsLockedOut.ToString()), - GetParameter(ParmSiteIdCollection, DataType.VarChar, 50, info.SiteIdCollection), - GetParameter(ParmSiteId, DataType.Integer, info.SiteId), - GetParameter(ParmDepartmentId, DataType.Integer, info.DepartmentId), - GetParameter(ParmAreaId, DataType.Integer, info.AreaId), - GetParameter(ParmDisplayname, DataType.VarChar, 255, info.DisplayName), - GetParameter(ParmEmail, DataType.VarChar, 255, info.Email), - GetParameter(ParmMobile, DataType.VarChar, 20, info.Mobile) - }; - - ExecuteNonQuery(SqlInsertUser, insertParms); - - DataProvider.DepartmentDao.UpdateCountOfAdmin(); - DataProvider.AreaDao.UpdateCountOfAdmin(); - } - - public void Update(IAdministratorInfo info) - { - IDataParameter[] parms = - { - GetParameter(ParmLastActivityDate, DataType.DateTime, info.LastActivityDate), - GetParameter(ParmCountOfLogin, DataType.Integer, info.CountOfLogin), - GetParameter(ParmCountOfFailedLogin, DataType.Integer, info.CountOfFailedLogin), - GetParameter(ParmIsLockedOut, DataType.VarChar, 18, info.IsLockedOut.ToString()), - GetParameter(ParmSiteIdCollection, DataType.VarChar, 50, info.SiteIdCollection), - GetParameter(ParmSiteId, DataType.Integer, info.SiteId), - GetParameter(ParmDepartmentId, DataType.Integer, info.DepartmentId), - GetParameter(ParmAreaId, DataType.Integer, info.AreaId), - GetParameter(ParmDisplayname, DataType.VarChar, 255, info.DisplayName), - GetParameter(ParmEmail, DataType.VarChar, 255, info.Email), - GetParameter(ParmMobile, DataType.VarChar, 20, info.Mobile), - GetParameter(ParmUsername, DataType.VarChar, 255, info.UserName) - }; - - ExecuteNonQuery(SqlUpdateUser, parms); - - DataProvider.DepartmentDao.UpdateCountOfAdmin(); - DataProvider.AreaDao.UpdateCountOfAdmin(); - - AdminManager.RemoveCache(info.UserName); - } - - public void UpdateLastActivityDateAndCountOfFailedLogin(string userName) - { - if (string.IsNullOrEmpty(userName)) return; - - var sqlString = - $"UPDATE siteserver_Administrator SET LastActivityDate = @LastActivityDate, {SqlUtils.ToPlusSqlString("CountOfFailedLogin")} WHERE UserName = @UserName"; - - IDataParameter[] updateParms = - { - GetParameter(ParmLastActivityDate, DataType.DateTime, DateTime.Now), - GetParameter(ParmUsername, DataType.VarChar, 255, userName) - }; - - ExecuteNonQuery(sqlString, updateParms); - - AdminManager.RemoveCache(userName); - } - - public void UpdateLastActivityDateAndCountOfLogin(string userName) - { - if (string.IsNullOrEmpty(userName)) return; - - var sqlString = - $"UPDATE siteserver_Administrator SET LastActivityDate = @LastActivityDate, {SqlUtils.ToPlusSqlString("CountOfLogin")}, CountOfFailedLogin = 0 WHERE UserName = @UserName"; - - IDataParameter[] updateParms = - { - GetParameter(ParmLastActivityDate, DataType.DateTime, DateTime.Now), - GetParameter(ParmUsername, DataType.VarChar, 255, userName) - }; - - ExecuteNonQuery(sqlString, updateParms); - - AdminManager.RemoveCache(userName); - } - - public void UpdateSiteIdCollection(string userName, string siteIdCollection) - { - if (string.IsNullOrEmpty(userName)) return; - - IDataParameter[] updateParms = - { - GetParameter(ParmSiteIdCollection, DataType.VarChar, 50, siteIdCollection), - GetParameter(ParmUsername, DataType.VarChar, 255, userName) - }; - - ExecuteNonQuery(SqlUpdateSiteIdCollection, updateParms); - - AdminManager.RemoveCache(userName); - } - - public void UpdateSiteId(string userName, int siteId) - { - if (string.IsNullOrEmpty(userName)) return; - - IDataParameter[] updateParms = - { - GetParameter(ParmSiteId, DataType.Integer, siteId), - GetParameter(ParmUsername, DataType.VarChar, 255, userName) - }; - - ExecuteNonQuery(SqlUpdateSiteId, updateParms); - - AdminManager.RemoveCache(userName); - } - - private bool ChangePassword(string userName, EPasswordFormat passwordFormat, string passwordSalt, - string password) - { - var isSuccess = false; - IDataParameter[] updateParms = - { - GetParameter(ParmPassword, DataType.VarChar, 255, password), - GetParameter(ParmPasswordFormat, DataType.VarChar, 50, EPasswordFormatUtils.GetValue(passwordFormat)), - GetParameter(ParmPasswordSalt, DataType.VarChar, 128, passwordSalt), - GetParameter(ParmUsername, DataType.VarChar, 255, userName) - }; - - try - { - ExecuteNonQuery(SqlUpdatePassword, updateParms); - - AdminManager.RemoveCache(userName); - isSuccess = true; - } - catch - { - // ignored - } - return isSuccess; - } - - public void Delete(string userName) - { - IDataParameter[] deleteParms = - { - GetParameter(ParmUsername, DataType.VarChar, 255, userName) - }; - - ExecuteNonQuery(SqlDeleteUser, deleteParms); - - AdminManager.RemoveCache(userName); - - DataProvider.DepartmentDao.UpdateCountOfAdmin(); - DataProvider.AreaDao.UpdateCountOfAdmin(); - } - - public void Lock(List userNameList) - { - string sqlString = - $"UPDATE siteserver_Administrator SET IsLockedOut = '{true}' WHERE UserName IN ({TranslateUtils.ToSqlInStringWithQuote(userNameList)})"; - - ExecuteNonQuery(sqlString); - - AdminManager.Clear(); - } - - public void UnLock(List userNameList) - { - string sqlString = - $"UPDATE siteserver_Administrator SET IsLockedOut = '{false}', CountOfFailedLogin = 0 WHERE UserName IN ({TranslateUtils.ToSqlInStringWithQuote(userNameList)})"; - - ExecuteNonQuery(sqlString); - - AdminManager.Clear(); - } - - public AdministratorInfo GetByAccount(string account) - { - AdministratorInfo info = null; - - string sqlString; - IDataParameter[] parms; - if (StringUtils.IsMobile(account)) - { - sqlString = SqlSelectUserByMobile; - parms = new IDataParameter[] - { - GetParameter(ParmMobile, DataType.VarChar, 50, account) - }; - } - else if (StringUtils.IsEmail(account)) - { - sqlString = SqlSelectUserByEmail; - parms = new IDataParameter[] - { - GetParameter(ParmEmail, DataType.VarChar, 50, account) - }; - } - else - { - sqlString = SqlSelectUser; - parms = new IDataParameter[] - { - GetParameter(ParmUsername, DataType.VarChar, 255, account) - }; - } - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - var i = 0; - info = new AdministratorInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), - EPasswordFormatUtils.GetEnumType(GetString(rdr, i++)), GetString(rdr, i++), - GetDateTime(rdr, i++), GetDateTime(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), - GetString(rdr, i++), TranslateUtils.ToBool(GetString(rdr, i++)), GetString(rdr, i++), - GetInt(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), - GetString(rdr, i)); - } - rdr.Close(); - } - - return info; - } - - public AdministratorInfo GetByUserName(string userName) - { - AdministratorInfo info = null; - - IDataParameter[] parms = - { - GetParameter(ParmUsername, DataType.VarChar, 255, userName) - }; - - using (var rdr = ExecuteReader(SqlSelectUser, parms)) - { - if (rdr.Read()) - { - var i = 0; - info = new AdministratorInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), - EPasswordFormatUtils.GetEnumType(GetString(rdr, i++)), GetString(rdr, i++), - GetDateTime(rdr, i++), GetDateTime(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), - GetString(rdr, i++), TranslateUtils.ToBool(GetString(rdr, i++)), GetString(rdr, i++), - GetInt(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), - GetString(rdr, i)); - } - rdr.Close(); - } - - return info; - } - - public int GetDepartmentId(string userName) - { - var departmentId = 0; - - IDataParameter[] parms = - { - GetParameter(ParmUsername, DataType.VarChar, 255, userName) - }; - - using (var rdr = ExecuteReader(SqlSelectDepartmentId, parms)) - { - if (rdr.Read()) - { - departmentId = GetInt(rdr, 0); - } - rdr.Close(); - } - - return departmentId; - } - - public int GetAreaId(string userName) - { - var areaId = 0; - - IDataParameter[] parms = - { - GetParameter(ParmUsername, DataType.VarChar, 255, userName) - }; - - using (var rdr = ExecuteReader(SqlSelectAreaId, parms)) - { - if (rdr.Read()) - { - areaId = GetInt(rdr, 0); - } - rdr.Close(); - } - - return areaId; - } - - public string GetSelectCommand(bool isConsoleAdministrator, string creatorUserName) - { - var sqlString = - "SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreationDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, CreatorUserName, IsLockedOut, SiteIdCollection, SiteId, DepartmentId, AreaId, DisplayName, Email, Mobile FROM siteserver_Administrator"; - if (!isConsoleAdministrator) - { - sqlString = - $"SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreationDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, CreatorUserName, IsLockedOut, SiteIdCollection, SiteId, DepartmentId, AreaId, DisplayName, Email, Mobile FROM siteserver_Administrator WHERE CreatorUserName = '{PageUtils.FilterSql(creatorUserName)}'"; - } - - return sqlString; - } - - public string GetSelectCommand(string searchWord, string roleName, int dayOfLastActivity, - bool isConsoleAdministrator, string creatorUserName, int departmentId, int areaId) - { - var whereBuilder = new StringBuilder(); - - if (dayOfLastActivity > 0) - { - var dateTime = DateTime.Now.AddDays(-dayOfLastActivity); - whereBuilder.Append($"(LastActivityDate >= {SqlUtils.GetComparableDate(dateTime)}) "); - } - if (!string.IsNullOrEmpty(searchWord)) - { - if (whereBuilder.Length > 0) - { - whereBuilder.Append(" AND "); - } - whereBuilder.Append( - $"(UserName LIKE '%{PageUtils.FilterSql(searchWord)}%' OR EMAIL LIKE '%{PageUtils.FilterSql(searchWord)}%' OR DisplayName LIKE '%{PageUtils.FilterSql(searchWord)}%')"); - } - - if (!isConsoleAdministrator) - { - if (whereBuilder.Length > 0) - { - whereBuilder.Append(" AND "); - } - whereBuilder.Append($"CreatorUserName = '{PageUtils.FilterSql(creatorUserName)}'"); - } - - if (departmentId != 0) - { - if (whereBuilder.Length > 0) - { - whereBuilder.Append(" AND "); - } - whereBuilder.Append($"DepartmentId = {departmentId}"); - } - - if (areaId != 0) - { - if (whereBuilder.Length > 0) - { - whereBuilder.Append(" AND "); - } - whereBuilder.Append($"AreaId = {areaId}"); - } - - var whereString = string.Empty; - if (!string.IsNullOrEmpty(roleName)) - { - if (whereBuilder.Length > 0) - { - whereString = $"AND {whereBuilder}"; - } - whereString = - $"WHERE (UserName IN (SELECT UserName FROM {DataProvider.AdministratorsInRolesDao.TableName} WHERE RoleName = '{PageUtils.FilterSql(roleName)}')) {whereString}"; - } - else - { - if (whereBuilder.Length > 0) - { - whereString = $"WHERE {whereBuilder}"; - } - } - - var sqlString = - "SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreationDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, CreatorUserName, IsLockedOut, SiteIdCollection, SiteId, DepartmentId, AreaId, DisplayName, Email, Mobile FROM siteserver_Administrator " + - whereString; - - return sqlString; - } - - public string GetSortFieldName() - { - return "UserName"; - } - - public bool IsAdminNameExists(string adminName) - { - if (string.IsNullOrEmpty(adminName)) - { - return false; - } - - var exists = false; - - IDataParameter[] parms = - { - GetParameter(ParmUsername, DataType.VarChar, 255, adminName) - }; - - using (var rdr = ExecuteReader(SqlSelectUsername, parms)) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - exists = true; - } - rdr.Close(); - } - return exists; - } - - public string GetUserNameByEmail(string email) - { - if (string.IsNullOrEmpty(email)) - { - return string.Empty; - } - - var userName = string.Empty; - - IDataParameter[] parms = - { - GetParameter(ParmEmail, DataType.VarChar, 50, email) - }; - - using (var rdr = ExecuteReader(SqlSelectUsernameByEmail, parms)) - { - if (rdr.Read()) - { - userName = GetString(rdr, 0); - } - rdr.Close(); - } - return userName; - } - - public string GetUserNameByMobile(string mobile) - { - if (string.IsNullOrEmpty(mobile)) - { - return string.Empty; - } - - var userName = string.Empty; - - IDataParameter[] parms = - { - GetParameter(ParmMobile, DataType.VarChar, 50, mobile) - }; - - using (var rdr = ExecuteReader(SqlSelectUsernameByMobile, parms)) - { - if (rdr.Read()) - { - userName = GetString(rdr, 0); - } - rdr.Close(); - } - return userName; - } - - public string GetMobileByUserName(string userName) - { - if (string.IsNullOrEmpty(userName)) - { - return string.Empty; - } - - var mobile = string.Empty; - - IDataParameter[] parms = - { - GetParameter(ParmUsername, DataType.VarChar, 50, userName) - }; - - using (var rdr = ExecuteReader(SqlSelectMobileByUsername, parms)) - { - if (rdr.Read()) - { - mobile = GetString(rdr, 0); - } - rdr.Close(); - } - return mobile; - } - - public string GetCreatorUserName(string userName) - { - var creatorUserName = string.Empty; - - IDataParameter[] parms = - { - GetParameter(ParmUsername, DataType.VarChar, 255, userName) - }; - - using (var rdr = ExecuteReader(SqlSelectCreatorUserName, parms)) - { - if (rdr.Read()) - { - creatorUserName = GetString(rdr, 0); - } - rdr.Close(); - } - return creatorUserName; - } - - public string GetDisplayName(string userName) - { - var displayName = string.Empty; - - IDataParameter[] parms = - { - GetParameter(ParmUsername, DataType.VarChar, 255, userName) - }; - - using (var rdr = ExecuteReader(SqlSelectDisplayName, parms)) - { - if (rdr.Read()) - { - displayName = GetString(rdr, 0); - } - rdr.Close(); - } - - return (!string.IsNullOrEmpty(displayName)) ? displayName : userName; - } - - public List GetSiteIdList(string userName) - { - var siteIdList = new List(); - - IDataParameter[] parms = - { - GetParameter(ParmUsername, DataType.VarChar, 255, userName) - }; - - using (var rdr = ExecuteReader(SqlSelectSiteIdCollection, parms)) - { - if (rdr.Read()) - { - var collection = GetString(rdr, 0); - if (!string.IsNullOrEmpty(collection)) - { - siteIdList = TranslateUtils.StringCollectionToIntList(collection); - } - } - rdr.Close(); - } - return siteIdList; - } - - public int GetSiteId(string userName) - { - var siteId = 0; - - IDataParameter[] parms = - { - GetParameter(ParmUsername, DataType.VarChar, 255, userName) - }; - - using (var rdr = ExecuteReader(SqlSelectSiteId, parms)) - { - if (rdr.Read()) - { - siteId = GetInt(rdr, 0); - } - rdr.Close(); - } - return siteId; - } - - public int GetCountByAreaId(int areaId) - { - var sqlString = $"SELECT COUNT(*) FROM {TableName} WHERE {nameof(AdministratorInfo.AreaId)} = {areaId}"; - - return DataProvider.DatabaseDao.GetIntResult(sqlString); - } - - public int GetCountByDepartmentId(int departmentId) - { - var sqlString = $"SELECT COUNT(*) FROM {TableName} WHERE {nameof(AdministratorInfo.DepartmentId)} = {departmentId}"; - - return DataProvider.DatabaseDao.GetIntResult(sqlString); - } - - public List GetUserNameListByCreatorUserName(string creatorUserName) - { - var list = new List(); - if (creatorUserName != null) - { - const string sqlString = - "SELECT UserName FROM siteserver_Administrator WHERE CreatorUserName = @CreatorUserName"; - - IDataParameter[] parms = - { - GetParameter(ParmCreatorUsername, DataType.VarChar, 255, creatorUserName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - } - return list; - } - - public List GetUserNameList() - { - var list = new List(); - const string sqlSelect = "SELECT UserName FROM siteserver_Administrator"; - - using (var rdr = ExecuteReader(sqlSelect)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - return list; - } - - public List GetUserNameList(List departmentIdList) - { - var list = new List(); - string sqlSelect = - $"SELECT UserName FROM siteserver_Administrator WHERE DepartmentId IN ({TranslateUtils.ToSqlInStringWithoutQuote(departmentIdList)}) ORDER BY DepartmentId"; - - using (var rdr = ExecuteReader(sqlSelect)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - return list; - } - - public List GetUserNameList(int departmentId, bool isAll) - { - var list = new List(); - string sqlSelect = $"SELECT UserName FROM siteserver_Administrator WHERE DepartmentId = {departmentId}"; - if (isAll) - { - var departmentIdList = DataProvider.DepartmentDao.GetIdListForDescendant(departmentId); - departmentIdList.Add(departmentId); - sqlSelect = - $"SELECT UserName FROM siteserver_Administrator WHERE DepartmentId IN ({TranslateUtils.ObjectCollectionToString(departmentIdList)})"; - } - - using (var rdr = ExecuteReader(sqlSelect)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - return list; - } - - public List GetUserNameList(string searchWord, int dayOfCreation, int dayOfLastActivity, bool isChecked) - { - var arraylist = new List(); - - var whereString = string.Empty; - if (dayOfCreation > 0) - { - var dateTime = DateTime.Now.AddDays(-dayOfCreation); - whereString += $" AND (CreationDate >= {SqlUtils.GetComparableDate(dateTime)}) "; - } - if (dayOfLastActivity > 0) - { - var dateTime = DateTime.Now.AddDays(-dayOfLastActivity); - whereString += $" AND (LastActivityDate >= {SqlUtils.GetComparableDate(dateTime)}) "; - } - if (!string.IsNullOrEmpty(searchWord)) - { - var word = PageUtils.FilterSql(searchWord); - whereString += $" AND (UserName LIKE '%{word}%' OR EMAIL LIKE '%{word}%') "; - } - - string sqlString = - $"SELECT * FROM siteserver_Administrator WHERE IsChecked = '{isChecked}' {whereString}"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - arraylist.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - return arraylist; - } - - public static string EncodePassword(string password, EPasswordFormat passwordFormat, out string passwordSalt) - { - var retval = string.Empty; - passwordSalt = string.Empty; - - if (passwordFormat == EPasswordFormat.Clear) - { - retval = password; - } - else if (passwordFormat == EPasswordFormat.Hashed) - { - passwordSalt = GenerateSalt(); - - var src = Encoding.Unicode.GetBytes(password); - var buffer2 = Convert.FromBase64String(passwordSalt); - var dst = new byte[buffer2.Length + src.Length]; - Buffer.BlockCopy(buffer2, 0, dst, 0, buffer2.Length); - Buffer.BlockCopy(src, 0, dst, buffer2.Length, src.Length); - var algorithm = HashAlgorithm.Create("SHA1"); - if (algorithm == null) return retval; - var inArray = algorithm.ComputeHash(dst); - - retval = Convert.ToBase64String(inArray); - } - else if (passwordFormat == EPasswordFormat.Encrypted) - { - passwordSalt = GenerateSalt(); - - var encryptor = new DesEncryptor - { - InputString = password, - EncryptKey = passwordSalt - }; - encryptor.DesEncrypt(); - - retval = encryptor.OutString; - } - return retval; - } - - public static string GenerateSalt() - { - var data = new byte[0x10]; - new RNGCryptoServiceProvider().GetBytes(data); - return Convert.ToBase64String(data); - } - - public bool Insert(AdministratorInfo userInfo, out string errorMessage) - { - errorMessage = string.Empty; - if (string.IsNullOrEmpty(userInfo.UserName)) - { - errorMessage = "用户名不能为空"; - return false; - } - if (userInfo.UserName.Length < ConfigManager.SystemConfigInfo.AdminUserNameMinLength) - { - errorMessage = $"用户名长度必须大于等于{ConfigManager.SystemConfigInfo.AdminUserNameMinLength}"; - return false; - } - if (IsAdminNameExists(userInfo.UserName)) - { - errorMessage = "用户名已存在,请更换用户名"; - return false; - } - - if (string.IsNullOrEmpty(userInfo.Password)) - { - errorMessage = "密码不能为空"; - return false; - } - if (userInfo.Password.Length < ConfigManager.SystemConfigInfo.AdminPasswordMinLength) - { - errorMessage = $"密码长度必须大于等于{ConfigManager.SystemConfigInfo.AdminPasswordMinLength}"; - return false; - } - if ( - !EUserPasswordRestrictionUtils.IsValid(userInfo.Password, - ConfigManager.SystemConfigInfo.AdminPasswordRestriction)) - { - errorMessage = - $"密码不符合规则,请包含{EUserPasswordRestrictionUtils.GetText(EUserPasswordRestrictionUtils.GetEnumType(ConfigManager.SystemConfigInfo.AdminPasswordRestriction))}"; - return false; - } - - try - { - string passwordSalt; - userInfo.Password = EncodePassword(userInfo.Password, userInfo.PasswordFormat, out passwordSalt); - userInfo.PasswordSalt = passwordSalt; - Insert(userInfo); - return true; - } - catch (Exception ex) - { - errorMessage = ex.Message; - return false; - } - } - - public bool ChangePassword(string userName, string password, out string errorMessage) - { - errorMessage = string.Empty; - - if (string.IsNullOrEmpty(password)) - { - errorMessage = "密码不能为空"; - return false; - } - if (password.Length < ConfigManager.SystemConfigInfo.AdminPasswordMinLength) - { - errorMessage = $"密码长度必须大于等于{ConfigManager.SystemConfigInfo.AdminPasswordMinLength}"; - return false; - } - if ( - !EUserPasswordRestrictionUtils.IsValid(password, ConfigManager.SystemConfigInfo.AdminPasswordRestriction)) - { - errorMessage = - $"密码不符合规则,请包含{EUserPasswordRestrictionUtils.GetText(EUserPasswordRestrictionUtils.GetEnumType(ConfigManager.SystemConfigInfo.AdminPasswordRestriction))}"; - return false; - } - - string passwordSalt; - password = EncodePassword(password, EPasswordFormat.Encrypted, out passwordSalt); - return ChangePassword(userName, EPasswordFormat.Encrypted, passwordSalt, password); - } - - public bool ValidateAccount(string account, string password, out string userName, out string errorMessage) - { - userName = string.Empty; - errorMessage = string.Empty; - - if (string.IsNullOrEmpty(account)) - { - errorMessage = "账号不能为空"; - return false; - } - if (string.IsNullOrEmpty(password)) - { - errorMessage = "密码不能为空"; - return false; - } - - var adminInfo = GetByAccount(account); - if (string.IsNullOrEmpty(adminInfo?.UserName)) - { - errorMessage = "帐号或密码错误"; - return false; - } - - userName = adminInfo.UserName; - - if (adminInfo.IsLockedOut) - { - errorMessage = "此账号被锁定,无法登录"; - return false; - } - - if (ConfigManager.SystemConfigInfo.IsAdminLockLogin) - { - if (adminInfo.CountOfFailedLogin > 0 && - adminInfo.CountOfFailedLogin >= ConfigManager.SystemConfigInfo.AdminLockLoginCount) - { - var lockType = EUserLockTypeUtils.GetEnumType(ConfigManager.SystemConfigInfo.AdminLockLoginType); - if (lockType == EUserLockType.Forever) - { - errorMessage = "此账号错误登录次数过多,已被永久锁定"; - return false; - } - if (lockType == EUserLockType.Hours) - { - var ts = new TimeSpan(DateTime.Now.Ticks - adminInfo.LastActivityDate.Ticks); - var hours = Convert.ToInt32(ConfigManager.SystemConfigInfo.AdminLockLoginHours - ts.TotalHours); - if (hours > 0) - { - errorMessage = - $"此账号错误登录次数过多,已被锁定,请等待{hours}小时后重试"; - return false; - } - } - } - } - - if (CheckPassword(password, adminInfo.Password, adminInfo.PasswordFormat, adminInfo.PasswordSalt)) - return true; - - errorMessage = "账号或密码不正确"; - return false; - } - - public static string DecodePassword(string password, EPasswordFormat passwordFormat, string passwordSalt) - { - var retval = string.Empty; - if (passwordFormat == EPasswordFormat.Clear) - { - retval = password; - } - else if (passwordFormat == EPasswordFormat.Hashed) - { - throw new Exception("can not decode hashed password"); - } - else if (passwordFormat == EPasswordFormat.Encrypted) - { - var encryptor = new DesEncryptor - { - InputString = password, - DecryptKey = passwordSalt - }; - encryptor.DesDecrypt(); - - retval = encryptor.OutString; - } - return retval; - } - - public bool CheckPassword(string password, string dbpassword, EPasswordFormat passwordFormat, - string passwordSalt) - { - var pass1 = password; - var pass2 = DecodePassword(dbpassword, passwordFormat, passwordSalt); - - return pass1 == pass2; - } - - public string GetPassword(string password, EPasswordFormat passwordFormat, string passwordSalt) - { - return DecodePassword(password, passwordFormat, passwordSalt); - } - } -} diff --git a/SiteServer.CMS/Provider/AdministratorsInRolesDao.cs b/SiteServer.CMS/Provider/AdministratorsInRolesDao.cs deleted file mode 100644 index 94130173e..000000000 --- a/SiteServer.CMS/Provider/AdministratorsInRolesDao.cs +++ /dev/null @@ -1,196 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Provider -{ - public class AdministratorsInRolesDao : DataProviderBase - { - public override string TableName => "siteserver_AdministratorsInRoles"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = "Id", - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = "RoleName", - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = "UserName", - DataType = DataType.VarChar, - Length = 255 - } - }; - - public string[] GetRolesForUser(string userName) - { - var tmpRoleNames = string.Empty; - var sqlString = "SELECT RoleName FROM siteserver_AdministratorsInRoles WHERE UserName = @UserName ORDER BY RoleName"; - var parms = new IDataParameter[] - { - GetParameter("@UserName", DataType.VarChar, 255, userName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - while (rdr.Read()) - { - tmpRoleNames += GetString(rdr, 0) + ","; - } - rdr.Close(); - } - - if (tmpRoleNames.Length > 0) - { - tmpRoleNames = tmpRoleNames.Substring(0, tmpRoleNames.Length - 1); - return tmpRoleNames.Split(','); - } - - return new string[0]; - } - - public string[] GetUsersInRole(string roleName) - { - var tmpUserNames = string.Empty; - var sqlString = "SELECT UserName FROM siteserver_AdministratorsInRoles WHERE RoleName = @RoleName ORDER BY userName"; - var parms = new IDataParameter[] - { - GetParameter("@RoleName", DataType.VarChar, 255, roleName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - while (rdr.Read()) - { - tmpUserNames += GetString(rdr, 0) + ","; - } - rdr.Close(); - } - - if (tmpUserNames.Length > 0) - { - tmpUserNames = tmpUserNames.Substring(0, tmpUserNames.Length - 1); - return tmpUserNames.Split(','); - } - - return new string[0]; - } - - public void RemoveUserFromRoles(string userName, string[] roleNames) - { - var sqlString = "DELETE FROM siteserver_AdministratorsInRoles WHERE UserName = @UserName AND RoleName = @RoleName"; - foreach (var roleName in roleNames) - { - var parms = new IDataParameter[] - { - GetParameter("@UserName", DataType.VarChar, 255, userName), - GetParameter("@RoleName", DataType.VarChar, 255, roleName) - }; - ExecuteNonQuery(sqlString, parms); - } - } - - public void RemoveUserFromRole(string userName, string roleName) - { - var sqlString = "DELETE FROM siteserver_AdministratorsInRoles WHERE UserName = @UserName AND RoleName = @RoleName"; - var parms = new IDataParameter[] - { - GetParameter("@UserName", DataType.VarChar, 255, userName), - GetParameter("@RoleName", DataType.VarChar, 255, roleName) - }; - - ExecuteNonQuery(sqlString, parms); - } - - public string[] FindUsersInRole(string roleName, string userNameToMatch) - { - var tmpUserNames = string.Empty; - string sqlString = - $"SELECT UserName FROM siteserver_AdministratorsInRoles WHERE RoleName = @RoleName AND UserName LIKE '%{PageUtils.FilterSql(userNameToMatch)}%'"; - - var parms = new IDataParameter[] - { - GetParameter("@RoleName", DataType.VarChar, 255, roleName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - while (rdr.Read()) - { - tmpUserNames += GetString(rdr, 0) + ","; - } - rdr.Close(); - } - - if (tmpUserNames.Length > 0) - { - tmpUserNames = tmpUserNames.Substring(0, tmpUserNames.Length - 1); - return tmpUserNames.Split(','); - } - - return new string[0]; - } - - public bool IsUserInRole(string userName, string roleName) - { - var isUserInRole = false; - const string sqlString = "SELECT * FROM siteserver_AdministratorsInRoles WHERE UserName = @UserName AND RoleName = @RoleName"; - var parms = new IDataParameter[] - { - GetParameter("@UserName", DataType.VarChar, 255, userName), - GetParameter("@RoleName", DataType.VarChar, 255, roleName) - }; - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - if (!rdr.IsDBNull(0)) - { - isUserInRole = true; - } - } - rdr.Close(); - } - return isUserInRole; - } - - public void AddUserToRoles(string userName, string[] roleNames) - { - foreach (var roleName in roleNames) - { - AddUserToRole(userName, roleName); - } - } - - public void AddUserToRole(string userName, string roleName) - { - if (!DataProvider.RoleDao.IsRoleExists(roleName)) return; - if (!DataProvider.AdministratorDao.IsAdminNameExists(userName)) return; - if (!IsUserInRole(userName, roleName)) - { - var sqlString = "INSERT INTO siteserver_AdministratorsInRoles (UserName, RoleName) VALUES (@UserName, @RoleName)"; - - var parms = new IDataParameter[] - { - GetParameter("@UserName", DataType.VarChar, 255, userName), - GetParameter("@RoleName", DataType.VarChar, 255, roleName) - }; - - ExecuteNonQuery(sqlString, parms); - } - } - } -} diff --git a/SiteServer.CMS/Provider/AreaDao.cs b/SiteServer.CMS/Provider/AreaDao.cs deleted file mode 100644 index f7a5bcf47..000000000 --- a/SiteServer.CMS/Provider/AreaDao.cs +++ /dev/null @@ -1,586 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using System.Text; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Provider -{ - public class AreaDao : DataProviderBase - { - public override string TableName => "siteserver_Area"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(AreaInfo.Id), - DataType = DataType.Integer, - IsPrimaryKey = true, - IsIdentity = true - }, - new TableColumnInfo - { - ColumnName = nameof(AreaInfo.AreaName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(AreaInfo.ParentId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(AreaInfo.ParentsPath), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(AreaInfo.ParentsCount), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(AreaInfo.ChildrenCount), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(AreaInfo.IsLastNode), - DataType = DataType.VarChar, - Length = 18 - }, - new TableColumnInfo - { - ColumnName = nameof(AreaInfo.Taxis), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(AreaInfo.CountOfAdmin), - DataType = DataType.Integer - } - }; - - private const string SqlSelect = "SELECT Id, AreaName, ParentID, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, Taxis, CountOfAdmin FROM siteserver_Area WHERE Id = @Id"; - private const string SqlSelectAll = "SELECT Id, AreaName, ParentID, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, Taxis, CountOfAdmin FROM siteserver_Area ORDER BY TAXIS"; - private const string SqlSelectCount = "SELECT COUNT(*) FROM siteserver_Area WHERE ParentID = @ParentID"; - private const string SqlUpdate = "UPDATE siteserver_Area SET AreaName = @AreaName, ParentsPath = @ParentsPath, ParentsCount = @ParentsCount, ChildrenCount = @ChildrenCount, IsLastNode = @IsLastNode, CountOfAdmin = @CountOfAdmin WHERE Id = @Id"; - - private const string ParmId = "@Id"; - private const string ParmName = "@AreaName"; - private const string ParmParentId = "@ParentID"; - private const string ParmParentsPath = "@ParentsPath"; - private const string ParmParentsCount = "@ParentsCount"; - private const string ParmChildrenCount = "@ChildrenCount"; - private const string ParmIsLastNode = "@IsLastNode"; - private const string ParmTaxis = "@Taxis"; - private const string ParmCountOfAdmin = "@CountOfAdmin"; - - private void InsertWithTrans(AreaInfo parentInfo, AreaInfo areaInfo, IDbTransaction trans) - { - if (parentInfo != null) - { - areaInfo.ParentsPath = parentInfo.ParentsPath + "," + parentInfo.Id; - areaInfo.ParentsCount = parentInfo.ParentsCount + 1; - - var maxTaxis = GetMaxTaxisByParentPath(areaInfo.ParentsPath); - if (maxTaxis == 0) - { - maxTaxis = parentInfo.Taxis; - } - areaInfo.Taxis = maxTaxis + 1; - } - else - { - areaInfo.ParentsPath = "0"; - areaInfo.ParentsCount = 0; - var maxTaxis = GetMaxTaxisByParentPath("0"); - areaInfo.Taxis = maxTaxis + 1; - } - - var sqlInsert = "INSERT INTO siteserver_Area (AreaName, ParentID, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, Taxis, CountOfAdmin) VALUES (@AreaName, @ParentID, @ParentsPath, @ParentsCount, @ChildrenCount, @IsLastNode, @Taxis, @CountOfAdmin)"; - - IDataParameter[] insertParms = { - GetParameter(ParmName, DataType.VarChar, 255, areaInfo.AreaName), - GetParameter(ParmParentId, DataType.Integer, areaInfo.ParentId), - GetParameter(ParmParentsPath, DataType.VarChar, 255, areaInfo.ParentsPath), - GetParameter(ParmParentsCount, DataType.Integer, areaInfo.ParentsCount), - GetParameter(ParmChildrenCount, DataType.Integer, 0), - GetParameter(ParmIsLastNode, DataType.VarChar, 18, true.ToString()), - GetParameter(ParmTaxis, DataType.Integer, areaInfo.Taxis), - GetParameter(ParmCountOfAdmin, DataType.Integer, areaInfo.CountOfAdmin) - }; - - string sqlString = $"UPDATE siteserver_Area SET {SqlUtils.ToPlusSqlString("Taxis")} WHERE (Taxis >= {areaInfo.Taxis})"; - ExecuteNonQuery(trans, sqlString); - - areaInfo.Id = ExecuteNonQueryAndReturnId(TableName, nameof(AreaInfo.Id), trans, sqlInsert, insertParms); - - if (!string.IsNullOrEmpty(areaInfo.ParentsPath) && areaInfo.ParentsPath != "0") - { - sqlString = $"UPDATE siteserver_Area SET {SqlUtils.ToPlusSqlString("ChildrenCount")} WHERE Id IN ({PageUtils.FilterSql(areaInfo.ParentsPath)})"; - - ExecuteNonQuery(trans, sqlString); - } - - sqlString = $"UPDATE siteserver_Area SET IsLastNode = '{false}' WHERE ParentID = {areaInfo.ParentId}"; - - ExecuteNonQuery(trans, sqlString); - - //sqlString = - // $"UPDATE siteserver_Area SET IsLastNode = 'True' WHERE (Id IN (SELECT TOP 1 Id FROM siteserver_Area WHERE ParentID = {areaInfo.ParentId} ORDER BY Taxis DESC))"; - sqlString = - $"UPDATE siteserver_Area SET IsLastNode = '{true}' WHERE Id IN ({SqlUtils.ToInTopSqlString(TableName, "Id", $"WHERE ParentID = {areaInfo.ParentId}", "ORDER BY Taxis DESC", 1)})"; - - ExecuteNonQuery(trans, sqlString); - - AreaManager.ClearCache(); - } - - private void UpdateSubtractChildrenCount(string parentsPath, int subtractNum) - { - if (!string.IsNullOrEmpty(parentsPath)) - { - var sqlString = string.Concat("UPDATE siteserver_Area SET ChildrenCount = ChildrenCount - ", subtractNum, " WHERE Id IN (", PageUtils.FilterSql(parentsPath), ")"); - ExecuteNonQuery(sqlString); - - AreaManager.ClearCache(); - } - } - - private void TaxisSubtract(int selectedId) - { - var areaInfo = GetAreaInfo(selectedId); - if (areaInfo == null) return; - //Get Lower Taxis and Id - int lowerId; - int lowerChildrenCount; - string lowerParentsPath; - // const string sqlString = @"SELECT TOP 1 Id, ChildrenCount, ParentsPath - //FROM siteserver_Area - //WHERE (ParentID = @ParentID) AND (Id <> @Id) AND (Taxis < @Taxis) - //ORDER BY Taxis DESC"; - var sqlString = SqlUtils.ToTopSqlString(TableName, "Id, ChildrenCount, ParentsPath", - "WHERE (ParentID = @ParentID) AND (Id <> @Id) AND (Taxis < @Taxis)", "ORDER BY Taxis DESC", 1); - - IDataParameter[] parms = { - GetParameter(ParmParentId, DataType.Integer, areaInfo.ParentId), - GetParameter(ParmId, DataType.Integer, areaInfo.Id), - GetParameter(ParmTaxis, DataType.Integer, areaInfo.Taxis), - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - lowerId = GetInt(rdr, 0); - lowerChildrenCount = GetInt(rdr, 1); - lowerParentsPath = GetString(rdr, 2); - } - else - { - return; - } - rdr.Close(); - } - - - var lowerNodePath = string.Concat(lowerParentsPath, ",", lowerId); - var selectedNodePath = string.Concat(areaInfo.ParentsPath, ",", areaInfo.Id); - - SetTaxisSubtract(selectedId, selectedNodePath, lowerChildrenCount + 1); - SetTaxisAdd(lowerId, lowerNodePath, areaInfo.ChildrenCount + 1); - - UpdateIsLastNode(areaInfo.ParentId); - } - - private void TaxisAdd(int selectedId) - { - var areaInfo = GetAreaInfo(selectedId); - if (areaInfo == null) return; - //Get Higher Taxis and Id - int higherId; - int higherChildrenCount; - string higherParentsPath; - // var sqlString = @"SELECT TOP 1 Id, ChildrenCount, ParentsPath - //FROM siteserver_Area - //WHERE (ParentID = @ParentID) AND (Id <> @Id) AND (Taxis > @Taxis) - //ORDER BY Taxis"; - var sqlString = SqlUtils.ToTopSqlString(TableName, "Id, ChildrenCount, ParentsPath", - "WHERE (ParentID = @ParentID) AND (Id <> @Id) AND (Taxis > @Taxis)", "ORDER BY Taxis", 1); - - IDataParameter[] parms = { - GetParameter(ParmParentId, DataType.Integer, areaInfo.ParentId), - GetParameter(ParmId, DataType.Integer, areaInfo.Id), - GetParameter(ParmTaxis, DataType.Integer, areaInfo.Taxis) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - higherId = GetInt(rdr, 0); - higherChildrenCount = GetInt(rdr, 1); - higherParentsPath = GetString(rdr, 2); - } - else - { - return; - } - rdr.Close(); - } - - - var higherNodePath = string.Concat(higherParentsPath, ",", higherId); - var selectedNodePath = string.Concat(areaInfo.ParentsPath, ",", areaInfo.Id); - - SetTaxisAdd(selectedId, selectedNodePath, higherChildrenCount + 1); - SetTaxisSubtract(higherId, higherNodePath, areaInfo.ChildrenCount + 1); - - UpdateIsLastNode(areaInfo.ParentId); - } - - private void SetTaxisAdd(int areaId, string parentsPath, int addNum) - { - var path = PageUtils.FilterSql(parentsPath); - string sqlString = - $"UPDATE siteserver_Area SET Taxis = Taxis + {addNum} WHERE Id = {areaId} OR ParentsPath = '{path}' OR ParentsPath LIKE '{path},%'"; - - ExecuteNonQuery(sqlString); - - AreaManager.ClearCache(); - } - - private void SetTaxisSubtract(int areaId, string parentsPath, int subtractNum) - { - var path = PageUtils.FilterSql(parentsPath); - string sqlString = - $"UPDATE siteserver_Area SET Taxis = Taxis - {subtractNum} WHERE Id = {areaId} OR ParentsPath = '{path}' OR ParentsPath LIKE '{path},%'"; - - ExecuteNonQuery(sqlString); - - AreaManager.ClearCache(); - } - - private void UpdateIsLastNode(int parentId) - { - if (parentId > 0) - { - var sqlString = "UPDATE siteserver_Area SET IsLastNode = @IsLastNode WHERE ParentID = @ParentID"; - - IDataParameter[] parms = { - GetParameter(ParmIsLastNode, DataType.VarChar, 18, false.ToString()), - GetParameter(ParmParentId, DataType.Integer, parentId) - }; - - ExecuteNonQuery(sqlString, parms); - - //sqlString = - // $"UPDATE siteserver_Area SET IsLastNode = '{true}' WHERE (Id IN (SELECT TOP 1 Id FROM siteserver_Area WHERE ParentID = {parentId} ORDER BY Taxis DESC))"; - sqlString = - $"UPDATE siteserver_Area SET IsLastNode = '{true}' WHERE Id IN ({SqlUtils.ToInTopSqlString(TableName, "Id", $"WHERE ParentID = {parentId}", "ORDER BY Taxis DESC", 1)})"; - - ExecuteNonQuery(sqlString); - } - } - - private int GetMaxTaxisByParentPath(string parentPath) - { - var sqlString = string.Concat("SELECT MAX(Taxis) AS MaxTaxis FROM siteserver_Area WHERE (ParentsPath = '", PageUtils.FilterSql(parentPath), "') OR (ParentsPath LIKE '", PageUtils.FilterSql(parentPath), ",%')"); - var maxTaxis = 0; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - maxTaxis = GetInt(rdr, 0); - } - rdr.Close(); - } - return maxTaxis; - } - - public int Insert(AreaInfo areaInfo) - { - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - var parentAreaInfo = GetAreaInfo(areaInfo.ParentId); - - InsertWithTrans(parentAreaInfo, areaInfo, trans); - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - - AreaManager.ClearCache(); - - return areaInfo.Id; - } - - public void Update(AreaInfo areaInfo) - { - IDataParameter[] updateParms = { - GetParameter(ParmName, DataType.VarChar, 255, areaInfo.AreaName), - GetParameter(ParmParentsPath, DataType.VarChar, 255, areaInfo.ParentsPath), - GetParameter(ParmParentsCount, DataType.Integer, areaInfo.ParentsCount), - GetParameter(ParmChildrenCount, DataType.Integer, areaInfo.ChildrenCount), - GetParameter(ParmIsLastNode, DataType.VarChar, 18, areaInfo.IsLastNode.ToString()), - GetParameter(ParmCountOfAdmin, DataType.Integer, areaInfo.CountOfAdmin), - GetParameter(ParmId, DataType.Integer, areaInfo.Id) - }; - - ExecuteNonQuery(SqlUpdate, updateParms); - - AreaManager.ClearCache(); - } - - public void UpdateTaxis(int selectedId, bool isSubtract) - { - if (isSubtract) - { - TaxisSubtract(selectedId); - } - else - { - TaxisAdd(selectedId); - } - } - - public void UpdateCountOfAdmin() - { - var areaIdList = AreaManager.GetAreaIdList(); - foreach (var areaId in areaIdList) - { - var count = DataProvider.AdministratorDao.GetCountByAreaId(areaId); - string sqlString = $"UPDATE {TableName} SET CountOfAdmin = {count} WHERE Id = {areaId}"; - ExecuteNonQuery(sqlString); - } - AreaManager.ClearCache(); - } - - public void Delete(int areaId) - { - var areaInfo = GetAreaInfo(areaId); - if (areaInfo != null) - { - var areaIdList = new List(); - if (areaInfo.ChildrenCount > 0) - { - areaIdList = GetIdListForDescendant(areaId); - } - areaIdList.Add(areaId); - - string sqlString = - $"DELETE FROM siteserver_Area WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(areaIdList)})"; - - int deletedNum; - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - deletedNum = ExecuteNonQuery(trans, sqlString); - - if (deletedNum > 0) - { - string sqlStringTaxis = - $"UPDATE siteserver_Area SET Taxis = Taxis - {deletedNum} WHERE (Taxis > {areaInfo.Taxis})"; - ExecuteNonQuery(trans, sqlStringTaxis); - } - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - UpdateIsLastNode(areaInfo.ParentId); - UpdateSubtractChildrenCount(areaInfo.ParentsPath, deletedNum); - } - - AreaManager.ClearCache(); - } - - private AreaInfo GetAreaInfo(int areaId) - { - AreaInfo areaInfo = null; - - IDataParameter[] parms = { - GetParameter(ParmId, DataType.Integer, areaId) - }; - - using (var rdr = ExecuteReader(SqlSelect, parms)) - { - if (rdr.Read()) - { - var i = 0; - areaInfo = new AreaInfo(GetInt(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetBool(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i)); - } - rdr.Close(); - } - return areaInfo; - } - - private List GetAreaInfoList() - { - var list = new List(); - - using (var rdr = ExecuteReader(SqlSelectAll)) - { - while (rdr.Read()) - { - var i = 0; - var areaInfo = new AreaInfo(GetInt(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetBool(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i)); - list.Add(areaInfo); - } - rdr.Close(); - } - return list; - } - - public int GetNodeCount(int areaId) - { - var nodeCount = 0; - - IDataParameter[] nodeParms = { - GetParameter(ParmParentId, DataType.Integer, areaId) - }; - - using (var rdr = ExecuteReader(SqlSelectCount, nodeParms)) - { - if (rdr.Read()) - { - nodeCount = GetInt(rdr, 0); - } - rdr.Close(); - } - return nodeCount; - } - - public List GetIdListByParentId(int parentId) - { - string sqlString = $@"SELECT Id FROM siteserver_Area WHERE ParentID = '{parentId}' ORDER BY Taxis"; - var list = new List(); - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetInt(rdr, 0)); - } - rdr.Close(); - } - - return list; - } - - public List GetIdListForDescendant(int areaId) - { - string sqlString = $@"SELECT Id -FROM siteserver_Area -WHERE (ParentsPath LIKE '{areaId},%') OR - (ParentsPath LIKE '%,{areaId},%') OR - (ParentsPath LIKE '%,{areaId}') OR - (ParentID = {areaId}) -"; - var list = new List(); - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var theId = GetInt(rdr, 0); - list.Add(theId); - } - rdr.Close(); - } - - return list; - } - - public List GetIdListByIdCollection(string areaIdCollection) - { - var list = new List(); - - if (string.IsNullOrEmpty(areaIdCollection)) return list; - - string sqlString = $@"SELECT Id FROM siteserver_Area WHERE Id IN ({areaIdCollection})"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetInt(rdr, 0)); - } - rdr.Close(); - } - - return list; - } - - public List GetIdListByFirstIdList(List firstIdList) - { - var list = new List(); - - if (firstIdList.Count > 0) - { - var builder = new StringBuilder(); - foreach (var areaId in firstIdList) - { - builder.Append($"Id = {areaId} OR ParentID = {areaId} OR ParentsPath LIKE '{areaId},%' OR "); - } - builder.Length -= 3; - - string sqlString = $"SELECT Id FROM siteserver_Area WHERE {builder} ORDER BY Taxis"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetInt(rdr, 0)); - } - rdr.Close(); - } - } - - return list; - } - - public List> GetAreaInfoPairList() - { - var pairList = new List>(); - - var areaInfoList = GetAreaInfoList(); - foreach (var areaInfo in areaInfoList) - { - var pair = new KeyValuePair(areaInfo.Id, areaInfo); - pairList.Add(pair); - } - - return pairList; - } - } -} diff --git a/SiteServer.CMS/Provider/ChannelDao.cs b/SiteServer.CMS/Provider/ChannelDao.cs deleted file mode 100644 index 96bddfcf9..000000000 --- a/SiteServer.CMS/Provider/ChannelDao.cs +++ /dev/null @@ -1,2028 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Text; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Provider -{ - public class ChannelDao : DataProviderBase - { - public override string TableName => "siteserver_Channel"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.ChannelName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.SiteId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.ContentModelPluginId), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.ContentRelatedPluginIds), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.ParentId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.ParentsPath), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.ParentsCount), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.ChildrenCount), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.IsLastNode), - DataType = DataType.VarChar, - Length = 18 - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.IndexName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.GroupNameCollection), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.Taxis), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.AddDate), - DataType = DataType.DateTime - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.ImageUrl), - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.Content), - DataType = DataType.Text - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.ContentNum), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.FilePath), - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.ChannelFilePathRule), - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.ContentFilePathRule), - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.LinkUrl), - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.LinkType), - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.ChannelTemplateId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.ContentTemplateId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.Keywords), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelInfo.Description), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = "ExtendValues", - DataType = DataType.Text - } - }; - - private const string SqlSelect = "SELECT Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, ContentNum, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues FROM siteserver_Channel WHERE Id = @Id"; - - private const string SqlSelectByLastAddDate = "SELECT Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, ContentNum, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues FROM siteserver_Channel WHERE ParentId = @ParentId ORDER BY AddDate Desc"; - - private const string SqlSelectId = "SELECT Id FROM siteserver_Channel WHERE Id = @Id"; - - private const string SqlSelectByTaxis = "SELECT Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, ContentNum, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues FROM siteserver_Channel WHERE ParentId = @ParentId ORDER BY Taxis"; - - //private const string SqlSelectByParentIdAndContentModelPluginId = "SELECT Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, ContentNum, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues FROM siteserver_Channel WHERE (SiteId = @SiteId OR Id = @SiteId) AND ContentModelPluginId = @ContentModelPluginId"; - - private const string SqlSelectGroupNameCollection = "SELECT GroupNameCollection FROM siteserver_Channel WHERE Id = @Id"; - - private const string SqlSelectParentId = "SELECT ParentId FROM siteserver_Channel WHERE Id = @Id"; - - private const string SqlSelectCount = "SELECT COUNT(*) FROM siteserver_Channel WHERE ParentId = @ParentId"; - - private const string SqlSelectSiteIdById = "SELECT SiteId FROM siteserver_Channel WHERE Id = @Id"; - - private const string SqlSelectIndexNameCollection = "SELECT DISTINCT IndexName FROM siteserver_Channel WHERE SiteId = @SiteId"; - - private const string SqlSelectIdByIndex = "SELECT Id FROM siteserver_Channel WHERE (SiteId = @SiteId OR Id = @SiteId) AND IndexName = @IndexName"; - - private const string SqlSelectIdByContentModelPluginId = "SELECT Id FROM siteserver_Channel WHERE (SiteId = @SiteId OR Id = @SiteId) AND ContentModelPluginId = @ContentModelPluginId"; - - private const string SqlUpdate = "UPDATE siteserver_Channel SET ChannelName = @ChannelName, ContentModelPluginId = @ContentModelPluginId, ContentRelatedPluginIds = @ContentRelatedPluginIds, ParentsPath = @ParentsPath, ParentsCount = @ParentsCount, ChildrenCount = @ChildrenCount, IsLastNode = @IsLastNode, IndexName = @IndexName, GroupNameCollection = @GroupNameCollection, ImageUrl = @ImageUrl, Content = @Content, ContentNum = @ContentNum, FilePath = @FilePath, ChannelFilePathRule = @ChannelFilePathRule, ContentFilePathRule = @ContentFilePathRule, LinkUrl = @LinkUrl,LinkType = @LinkType, ChannelTemplateId = @ChannelTemplateId, ContentTemplateId = @ContentTemplateId, Keywords = @Keywords, Description = @Description, ExtendValues = @ExtendValues WHERE Id = @Id"; - - private const string SqlUpdateExtendValues = "UPDATE siteserver_Channel SET ExtendValues = @ExtendValues WHERE Id = @Id"; - - private const string SqlUpdateGroupNameCollection = "UPDATE siteserver_Channel SET GroupNameCollection = @GroupNameCollection WHERE Id = @Id"; - - private const string ParmId = "@Id"; - private const string ParmChannelName = "@ChannelName"; - private const string ParmSiteId = "@SiteId"; - private const string ParmContentModelPluginId = "@ContentModelPluginId"; - private const string ParmContentRelatedPluginIds = "@ContentRelatedPluginIds"; - private const string ParmParentId = "@ParentId"; - private const string ParmParentsPath = "@ParentsPath"; - private const string ParmParentsCount = "@ParentsCount"; - private const string ParmChildrenCount = "@ChildrenCount"; - private const string ParmIsLastNode = "@IsLastNode"; - private const string ParmIndexName = "@IndexName"; - private const string ParmGroupNameCollection = "@GroupNameCollection"; - private const string ParmTaxis = "@Taxis"; - private const string ParmAddDate = "@AddDate"; - private const string ParmImageUrl = "@ImageUrl"; - private const string ParmContent = "@Content"; - private const string ParmContentNum = "@ContentNum"; - private const string ParmFilePath = "@FilePath"; - private const string ParmChannelFilePathRule = "@ChannelFilePathRule"; - private const string ParmContentFilePathRule = "@ContentFilePathRule"; - private const string ParmLinkUrl = "@LinkUrl"; - private const string ParmLinkType = "@LinkType"; - private const string ParmChannelTemplateId = "@ChannelTemplateId"; - private const string ParmContentTemplateId = "@ContentTemplateId"; - private const string ParmKeywords = "@Keywords"; - private const string ParmDescription = "@Description"; - private const string ParmExtendValues = "@ExtendValues"; - - private void InsertChannelInfoWithTrans(IChannelInfo parentChannelInfo, IChannelInfo channelInfo, IDbTransaction trans) - { - if (parentChannelInfo != null) - { - channelInfo.SiteId = parentChannelInfo.SiteId; - if (parentChannelInfo.ParentsPath.Length == 0) - { - channelInfo.ParentsPath = parentChannelInfo.Id.ToString(); - } - else - { - channelInfo.ParentsPath = parentChannelInfo.ParentsPath + "," + parentChannelInfo.Id; - } - channelInfo.ParentsCount = parentChannelInfo.ParentsCount + 1; - - var maxTaxis = GetMaxTaxisByParentPath(channelInfo.ParentsPath); - if (maxTaxis == 0) - { - maxTaxis = parentChannelInfo.Taxis; - } - channelInfo.Taxis = maxTaxis + 1; - } - else - { - channelInfo.Taxis = 1; - } - - const string sqlInsertNode = "INSERT INTO siteserver_Channel (ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, ContentNum, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues) VALUES (@ChannelName, @SiteId, @ContentModelPluginId, @ContentRelatedPluginIds, @ParentId, @ParentsPath, @ParentsCount, @ChildrenCount, @IsLastNode, @IndexName, @GroupNameCollection, @Taxis, @AddDate, @ImageUrl, @Content, @ContentNum, @FilePath, @ChannelFilePathRule, @ContentFilePathRule, @LinkUrl, @LinkType, @ChannelTemplateId, @ContentTemplateId, @Keywords, @Description, @ExtendValues)"; - - var insertParms = new IDataParameter[] - { - GetParameter(ParmChannelName, DataType.VarChar, 255, channelInfo.ChannelName), - GetParameter(ParmSiteId, DataType.Integer, channelInfo.SiteId), - GetParameter(ParmContentModelPluginId, DataType.VarChar, 50, channelInfo.ContentModelPluginId), - GetParameter(ParmContentRelatedPluginIds, DataType.VarChar, 255, channelInfo.ContentRelatedPluginIds), - GetParameter(ParmParentId, DataType.Integer, channelInfo.ParentId), - GetParameter(ParmParentsPath, DataType.VarChar, 255, channelInfo.ParentsPath), - GetParameter(ParmParentsCount, DataType.Integer, channelInfo.ParentsCount), - GetParameter(ParmChildrenCount, DataType.Integer, 0), - GetParameter(ParmIsLastNode, DataType.VarChar, 18, true.ToString()), - GetParameter(ParmIndexName, DataType.VarChar, 255, channelInfo.IndexName), - GetParameter(ParmGroupNameCollection, DataType.VarChar, 255, channelInfo.GroupNameCollection), - GetParameter(ParmTaxis, DataType.Integer, channelInfo.Taxis), - GetParameter(ParmAddDate, DataType.DateTime, channelInfo.AddDate), - GetParameter(ParmImageUrl, DataType.VarChar, 200, channelInfo.ImageUrl), - GetParameter(ParmContent, DataType.Text, channelInfo.Content), - GetParameter(ParmContentNum, DataType.Integer, channelInfo.ContentNum), - GetParameter(ParmFilePath, DataType.VarChar, 200, channelInfo.FilePath), - GetParameter(ParmChannelFilePathRule, DataType.VarChar, 200, channelInfo.ChannelFilePathRule), - GetParameter(ParmContentFilePathRule, DataType.VarChar, 200, channelInfo.ContentFilePathRule), - GetParameter(ParmLinkUrl, DataType.VarChar, 200, channelInfo.LinkUrl), - GetParameter(ParmLinkType, DataType.VarChar, 200, channelInfo.LinkType), - GetParameter(ParmChannelTemplateId, DataType.Integer, channelInfo.ChannelTemplateId), - GetParameter(ParmContentTemplateId, DataType.Integer, channelInfo.ContentTemplateId), - GetParameter(ParmKeywords, DataType.VarChar, 255, channelInfo.Keywords), - GetParameter(ParmDescription, DataType.VarChar, 255, channelInfo.Description), - GetParameter(ParmExtendValues, DataType.Text, channelInfo.Attributes.ToString()) - }; - - if (channelInfo.SiteId != 0) - { - string sqlString = - $"UPDATE siteserver_Channel SET {SqlUtils.ToPlusSqlString("Taxis")} WHERE (Taxis >= {channelInfo.Taxis}) AND (SiteId = {channelInfo.SiteId})"; - ExecuteNonQuery(trans, sqlString); - } - channelInfo.Id = ExecuteNonQueryAndReturnId(TableName, nameof(ChannelInfo.Id), trans, sqlInsertNode, insertParms); - - if (!string.IsNullOrEmpty(channelInfo.ParentsPath)) - { - var sqlString = $"UPDATE siteserver_Channel SET {SqlUtils.ToPlusSqlString("ChildrenCount")} WHERE Id IN ({channelInfo.ParentsPath})"; - - ExecuteNonQuery(trans, sqlString); - } - - var sqlUpdateIsLastNode = "UPDATE siteserver_Channel SET IsLastNode = @IsLastNode WHERE ParentId = @ParentId"; - - var parms = new IDataParameter[] - { - GetParameter(ParmIsLastNode, DataType.VarChar, 18, false.ToString()), - GetParameter(ParmParentId, DataType.Integer, channelInfo.ParentId) - }; - - ExecuteNonQuery(trans, sqlUpdateIsLastNode, parms); - - //sqlUpdateIsLastNode = - // $"UPDATE siteserver_Channel SET IsLastNode = '{true}' WHERE (Id IN (SELECT TOP 1 Id FROM siteserver_Channel WHERE ParentId = {channelInfo.ParentId} ORDER BY Taxis DESC))"; - sqlUpdateIsLastNode = - $"UPDATE siteserver_Channel SET IsLastNode = '{true}' WHERE (Id IN ({SqlUtils.ToInTopSqlString(TableName, "Id", $"WHERE ParentId = {channelInfo.ParentId}", "ORDER BY Taxis DESC", 1)}))"; - - - ExecuteNonQuery(trans, sqlUpdateIsLastNode); - - //OwningIdCache.IsChanged = true; - ChannelManager.RemoveCache(channelInfo.SiteId); - PermissionManager.ClearAllCache(); - } - - - /// - /// 将节点数减1 - /// - /// - /// - private void UpdateSubtractChildrenCount(string parentsPath, int subtractNum) - { - if (!string.IsNullOrEmpty(parentsPath)) - { - var sqlString = string.Concat("UPDATE siteserver_Channel SET ChildrenCount = ChildrenCount - ", subtractNum, " WHERE Id in (", parentsPath, ")"); - ExecuteNonQuery(sqlString); - } - } - - - /// - /// 更新发布系统下的所有节点的排序号 - /// - /// - private void UpdateWholeTaxisBySiteId(int siteId) - { - if (siteId <= 0) return; - var idList = new List - { - siteId - }; - var level = 0; - string selectLevelCmd = - $"SELECT MAX(ParentsCount) FROM siteserver_Channel WHERE (Id = {siteId}) OR (SiteId = {siteId})"; - using (var rdr = ExecuteReader(selectLevelCmd)) - { - while (rdr.Read()) - { - var parentsCount = GetInt(rdr, 0); - level = parentsCount; - } - rdr.Close(); - } - - for (var i = 0; i < level; i++) - { - var list = new List(idList); - foreach (var savedId in list) - { - var lastChildIdOfSavedId = savedId; - var sqlString = - $"SELECT Id, ChannelName FROM siteserver_Channel WHERE ParentId = {savedId} ORDER BY Taxis, IsLastNode"; - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var channelId = GetInt(rdr, 0); - if (!idList.Contains(channelId)) - { - var index = idList.IndexOf(lastChildIdOfSavedId); - idList.Insert(index + 1, channelId); - lastChildIdOfSavedId = channelId; - } - } - rdr.Close(); - } - } - } - - for (var i = 1; i <= idList.Count; i++) - { - var channelId = idList[i - 1]; - string updateCmd = $"UPDATE siteserver_Channel SET Taxis = {i} WHERE Id = {channelId}"; - ExecuteNonQuery(updateCmd); - } - } - - - /// - /// Change The Texis To Lowerer Level - /// - private void TaxisSubtract(int siteId, int selectedId) - { - var channelInfo = ChannelManager.GetChannelInfo(siteId, selectedId); - if (channelInfo == null || channelInfo.ParentId == 0 || channelInfo.SiteId == 0) return; - UpdateWholeTaxisBySiteId(channelInfo.SiteId); - //Get Lower Taxis and Id - int lowerId; - int lowerChildrenCount; - string lowerParentsPath; - // var sqlString = @"SELECT TOP 1 Id, ChildrenCount, ParentsPath - //FROM siteserver_Channel - //WHERE (ParentId = @ParentId) AND (Id <> @Id) AND (Taxis < @Taxis) AND (SiteId = @SiteId) - //ORDER BY Taxis DESC"; - var sqlString = SqlUtils.ToTopSqlString(TableName, "Id, ChildrenCount, ParentsPath", "WHERE (ParentId = @ParentId) AND (Id <> @Id) AND (Taxis < @Taxis) AND (SiteId = @SiteId)", "ORDER BY Taxis DESC", 1); - - var parms = new IDataParameter[] - { - GetParameter(ParmParentId, DataType.Integer, channelInfo.ParentId), - GetParameter(ParmId, DataType.Integer, channelInfo.Id), - GetParameter(ParmTaxis, DataType.Integer, channelInfo.Taxis), - GetParameter(ParmSiteId, DataType.Integer, channelInfo.SiteId) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - lowerId = GetInt(rdr, 0); - lowerChildrenCount = GetInt(rdr, 1); - lowerParentsPath = GetString(rdr, 2); - } - else - { - return; - } - rdr.Close(); - } - - var lowerPath = lowerParentsPath == "" ? lowerId.ToString() : string.Concat(lowerParentsPath, ",", lowerId); - var selectedPath = channelInfo.ParentsPath == "" ? channelInfo.Id.ToString() : string.Concat(channelInfo.ParentsPath, ",", channelInfo.Id); - - SetTaxisSubtract(selectedId, selectedPath, lowerChildrenCount + 1); - SetTaxisAdd(lowerId, lowerPath, channelInfo.ChildrenCount + 1); - - UpdateIsLastNode(channelInfo.ParentId); - } - - /// - /// Change The Texis To Higher Level - /// - private void TaxisAdd(int siteId, int selectedId) - { - var channelInfo = ChannelManager.GetChannelInfo(siteId, selectedId); - if (channelInfo == null || channelInfo.ParentId == 0 || channelInfo.SiteId == 0) return; - UpdateWholeTaxisBySiteId(channelInfo.SiteId); - //Get Higher Taxis and Id - int higherId; - int higherChildrenCount; - string higherParentsPath; - //const string sqlString = @"SELECT TOP 1 Id, ChildrenCount, ParentsPath - //FROM siteserver_Channel - //WHERE (ParentId = @ParentId) AND (Id <> @Id) AND (Taxis > @Taxis) AND (SiteId = @SiteId) ORDER BY Taxis"; - var sqlString = SqlUtils.ToTopSqlString(TableName, "Id, ChildrenCount, ParentsPath", "WHERE (ParentId = @ParentId) AND (Id <> @Id) AND (Taxis > @Taxis) AND (SiteId = @SiteId)", "ORDER BY Taxis", 1); - - var parms = new IDataParameter[] - { - GetParameter(ParmParentId, DataType.Integer, channelInfo.ParentId), - GetParameter(ParmId, DataType.Integer, channelInfo.Id), - GetParameter(ParmTaxis, DataType.Integer, channelInfo.Taxis), - GetParameter(ParmSiteId, DataType.Integer, channelInfo.SiteId) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - higherId = GetInt(rdr, 0); - higherChildrenCount = GetInt(rdr, 1); - higherParentsPath = GetString(rdr, 2); - } - else - { - return; - } - rdr.Close(); - } - - - var higherPath = higherParentsPath == string.Empty ? higherId.ToString() : string.Concat(higherParentsPath, ",", higherId); - var selectedPath = channelInfo.ParentsPath == string.Empty ? channelInfo.Id.ToString() : String.Concat(channelInfo.ParentsPath, ",", channelInfo.Id); - - SetTaxisAdd(selectedId, selectedPath, higherChildrenCount + 1); - SetTaxisSubtract(higherId, higherPath, channelInfo.ChildrenCount + 1); - - UpdateIsLastNode(channelInfo.ParentId); - } - - private void SetTaxisAdd(int channelId, string parentsPath, int addNum) - { - string sqlString = - $"UPDATE siteserver_Channel SET {SqlUtils.ToPlusSqlString("Taxis", addNum)} WHERE Id = {channelId} OR ParentsPath = '{parentsPath}' OR ParentsPath like '{parentsPath},%'"; - - ExecuteNonQuery(sqlString); - } - - private void SetTaxisSubtract(int channelId, string parentsPath, int subtractNum) - { - string sqlString = - $"UPDATE siteserver_Channel SET {SqlUtils.ToMinusSqlString("Taxis", subtractNum)} WHERE Id = {channelId} OR ParentsPath = '{parentsPath}' OR ParentsPath like '{parentsPath},%'"; - - ExecuteNonQuery(sqlString); - } - - - private void UpdateIsLastNode(int parentId) - { - if (parentId <= 0) return; - - var sqlString = "UPDATE siteserver_Channel SET IsLastNode = @IsLastNode WHERE ParentId = @ParentId"; - - var parms = new IDataParameter[] - { - GetParameter(ParmIsLastNode, DataType.VarChar, 18, false.ToString()), - GetParameter(ParmParentId, DataType.Integer, parentId) - }; - - ExecuteNonQuery(sqlString, parms); - - //sqlString = - // $"UPDATE siteserver_Channel SET IsLastNode = '{true}' WHERE (Id IN (SELECT TOP 1 Id FROM siteserver_Channel WHERE ParentId = {parentId} ORDER BY Taxis DESC))"; - sqlString = - $"UPDATE siteserver_Channel SET IsLastNode = '{true}' WHERE (Id IN ({SqlUtils.ToInTopSqlString(TableName, "Id", $"WHERE ParentId = {parentId}", "ORDER BY Taxis DESC", 1)}))"; - - ExecuteNonQuery(sqlString); - } - - - private int GetMaxTaxisByParentPath(string parentPath) - { - var cmd = string.Concat("SELECT MAX(Taxis) AS MaxTaxis FROM siteserver_Channel WHERE (ParentsPath = '", parentPath, "') OR (ParentsPath like '", parentPath, ",%')"); - var maxTaxis = 0; - - using (var rdr = ExecuteReader(cmd)) - { - if (rdr.Read()) - { - maxTaxis = GetInt(rdr, 0); - } - rdr.Close(); - } - return maxTaxis; - } - - private string GetGroupNameCollection(int channelId) - { - var groupNameCollection = string.Empty; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, channelId) - }; - - using (var rdr = ExecuteReader(SqlSelectGroupNameCollection, parms)) - { - if (rdr.Read()) - { - groupNameCollection = GetString(rdr, 0); - } - rdr.Close(); - } - return groupNameCollection; - } - - private int GetParentId(int channelId) - { - var parentId = 0; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, channelId) - }; - - using (var rdr = ExecuteReader(SqlSelectParentId, parms)) - { - if (rdr.Read()) - { - parentId = GetInt(rdr, 0); - } - rdr.Close(); - } - return parentId; - } - - private int GetIdByParentIdAndOrder(int parentId, int order) - { - var channelId = parentId; - - string cmd = $"SELECT Id FROM siteserver_Channel WHERE (ParentId = {parentId}) ORDER BY Taxis"; - - using (var rdr = ExecuteReader(cmd)) - { - var index = 1; - while (rdr.Read()) - { - channelId = GetInt(rdr, 0); - if (index == order) - break; - index++; - } - rdr.Close(); - } - return channelId; - } - - public int Insert(int siteId, int parentId, string channelName, string indexName, string contentModelPluginId) - { - if (siteId > 0 && parentId == 0) return 0; - - var defaultChannelTemplateInfo = TemplateManager.GetDefaultTemplateInfo(siteId, TemplateType.ChannelTemplate); - var defaultContentTemplateInfo = TemplateManager.GetDefaultTemplateInfo(siteId, TemplateType.ContentTemplate); - - var channelInfo = new ChannelInfo - { - ParentId = parentId, - SiteId = siteId, - ChannelName = channelName, - IndexName = indexName, - ContentModelPluginId = contentModelPluginId, - AddDate = DateTime.Now, - ChannelTemplateId = defaultChannelTemplateInfo.Id, - ContentTemplateId = defaultContentTemplateInfo.Id - }; - - var parentChannelInfo = ChannelManager.GetChannelInfo(siteId, parentId); - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - InsertChannelInfoWithTrans(parentChannelInfo, channelInfo, trans); - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - - return channelInfo.Id; - } - - public int Insert(int siteId, int parentId, string channelName, string indexName, string contentModelPluginId, string contentRelatedPluginIds, int channelTemplateId, int contentTemplateId) - { - if (siteId > 0 && parentId == 0) return 0; - - var defaultChannelTemplateInfo = TemplateManager.GetDefaultTemplateInfo(siteId, TemplateType.ChannelTemplate); - var defaultContentTemplateInfo = TemplateManager.GetDefaultTemplateInfo(siteId, TemplateType.ContentTemplate); - - var channelInfo = new ChannelInfo - { - ParentId = parentId, - SiteId = siteId, - ChannelName = channelName, - IndexName = indexName, - ContentModelPluginId = contentModelPluginId, - ContentRelatedPluginIds = contentRelatedPluginIds, - AddDate = DateTime.Now, - ChannelTemplateId = channelTemplateId > 0 ? channelTemplateId : defaultChannelTemplateInfo.Id, - ContentTemplateId = contentTemplateId > 0 ? contentTemplateId : defaultContentTemplateInfo.Id - }; - - var parentChannelInfo = ChannelManager.GetChannelInfo(siteId, parentId); - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - InsertChannelInfoWithTrans(parentChannelInfo, channelInfo, trans); - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - - return channelInfo.Id; - - } - - public int Insert(IChannelInfo channelInfo) - { - if (channelInfo.SiteId > 0 && channelInfo.ParentId == 0) return 0; - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - var parentChannelInfo = GetChannelInfo(channelInfo.ParentId); - - InsertChannelInfoWithTrans(parentChannelInfo, channelInfo, trans); - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - - return channelInfo.Id; - } - - /// - /// 添加后台发布节点 - /// - public int InsertSiteInfo(ChannelInfo channelInfo, SiteInfo psInfo, string administratorName) - { - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - InsertChannelInfoWithTrans(null, channelInfo, trans); - - psInfo.Id = channelInfo.Id; - - DataProvider.SiteDao.InsertWithTrans(psInfo, trans); - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - - DataProvider.AdministratorDao.UpdateSiteId(administratorName, channelInfo.Id); - - var sqlString = - $"UPDATE siteserver_Channel SET SiteId = {channelInfo.Id} WHERE Id = {channelInfo.Id}"; - ExecuteNonQuery(sqlString); - - DataProvider.TemplateDao.CreateDefaultTemplateInfo(channelInfo.Id, administratorName); - return channelInfo.Id; - } - - public void Update(IChannelInfo channelInfo) - { - var updateParms = new IDataParameter[] - { - GetParameter(ParmChannelName, DataType.VarChar, 255, channelInfo.ChannelName), - GetParameter(ParmContentModelPluginId, DataType.VarChar, 50, channelInfo.ContentModelPluginId), - GetParameter(ParmContentRelatedPluginIds, DataType.VarChar, 255, channelInfo.ContentRelatedPluginIds), - GetParameter(ParmParentsPath, DataType.VarChar, 255, channelInfo.ParentsPath), - GetParameter(ParmParentsCount, DataType.Integer, channelInfo.ParentsCount), - GetParameter(ParmChildrenCount, DataType.Integer, channelInfo.ChildrenCount), - GetParameter(ParmIsLastNode, DataType.VarChar, 18, channelInfo.IsLastNode.ToString()), - GetParameter(ParmIndexName, DataType.VarChar, 255, channelInfo.IndexName), - GetParameter(ParmGroupNameCollection, DataType.VarChar, 255, channelInfo.GroupNameCollection), - GetParameter(ParmImageUrl, DataType.VarChar, 200, channelInfo.ImageUrl), - GetParameter(ParmContent, DataType.Text, channelInfo.Content), - GetParameter(ParmContentNum, DataType.Integer, channelInfo.ContentNum), - GetParameter(ParmFilePath, DataType.VarChar, 200, channelInfo.FilePath), - GetParameter(ParmChannelFilePathRule, DataType.VarChar, 200, channelInfo.ChannelFilePathRule), - GetParameter(ParmContentFilePathRule, DataType.VarChar, 200, channelInfo.ContentFilePathRule), - GetParameter(ParmLinkUrl, DataType.VarChar, 200, channelInfo.LinkUrl), - GetParameter(ParmLinkType, DataType.VarChar, 200, channelInfo.LinkType), - GetParameter(ParmChannelTemplateId, DataType.Integer, channelInfo.ChannelTemplateId), - GetParameter(ParmContentTemplateId, DataType.Integer, channelInfo.ContentTemplateId), - GetParameter(ParmKeywords, DataType.VarChar, 255, channelInfo.Keywords), - GetParameter(ParmDescription, DataType.VarChar, 255, channelInfo.Description), - GetParameter(ParmExtendValues, DataType.Text, channelInfo.Attributes.ToString()), - GetParameter(ParmId, DataType.Integer, channelInfo.Id) - }; - - ExecuteNonQuery(SqlUpdate, updateParms); - - ChannelManager.RemoveCache(channelInfo.ParentId == 0 - ? channelInfo.Id - : channelInfo.SiteId); - } - - public void UpdateAdditional(ChannelInfo channelInfo) - { - var updateParms = new IDataParameter[] - { - GetParameter(ParmExtendValues, DataType.Text, channelInfo.Additional.ToString()), - GetParameter(ParmId, DataType.Integer, channelInfo.Id) - }; - - ExecuteNonQuery(SqlUpdateExtendValues, updateParms); - - ChannelManager.RemoveCache(channelInfo.ParentId == 0 - ? channelInfo.Id - : channelInfo.SiteId); - } - - /// - /// 修改排序 - /// - public void UpdateTaxis(int siteId, int selectedId, bool isSubtract) - { - if (isSubtract) - { - TaxisSubtract(siteId, selectedId); - } - else - { - TaxisAdd(siteId, selectedId); - } - ChannelManager.RemoveCache(siteId); - } - - private void UpdateGroupNameCollection(int siteId, int channelId, string groupNameCollection) - { - var parms = new IDataParameter[] - { - GetParameter(ParmGroupNameCollection, DataType.VarChar, 255, groupNameCollection), - GetParameter(ParmId, DataType.Integer, channelId) - }; - - ExecuteNonQuery(SqlUpdateGroupNameCollection, parms); - ChannelManager.RemoveCache(siteId); - } - - public void AddGroupNameList(int siteId, int channelId, List groupList) - { - var list = TranslateUtils.StringCollectionToStringList(GetGroupNameCollection(channelId)); - foreach (string groupName in groupList) - { - if (!list.Contains(groupName)) list.Add(groupName); - } - UpdateGroupNameCollection(siteId, channelId, TranslateUtils.ObjectCollectionToString(list)); - } - - public void UpdateContentNum(SiteInfo siteInfo) - { - var idList = ChannelManager.GetChannelIdList(siteInfo.Id); - foreach (var channelId in idList) - { - UpdateContentNum(siteInfo, channelId, false); - } - - ChannelManager.RemoveCache(siteInfo.Id); - } - - public virtual void UpdateContentNum(SiteInfo siteInfo, int channelId, bool isRemoveCache) - { - var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - var sqlString = string.Empty; - var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); - if (!string.IsNullOrEmpty(tableName)) - { - sqlString = - $"UPDATE {TableName} SET ContentNum = ({DataProvider.ContentDao.GetCountSqlString(tableName, channelId)}) WHERE Id = {channelId}"; - } - if (!string.IsNullOrEmpty(sqlString)) - { - ExecuteNonQuery(sqlString); - } - - if (isRemoveCache) - { - ChannelManager.RemoveCache(siteInfo.Id); - } - } - - public void UpdateContentNumToZero(string tableName) - { - var siteIdList = new List(); - var psIdList = SiteManager.GetSiteIdList(); - - foreach (var siteId in psIdList) - { - var psInfo = SiteManager.GetSiteInfo(siteId); - if (psInfo.TableName == tableName) - { - siteIdList.Add(siteId); - ChannelManager.RemoveCache(siteId); - } - } - if (siteIdList.Count == 0) return; - - var inString = TranslateUtils.ToSqlInStringWithoutQuote(siteIdList); - string sqlString = - $"UPDATE siteserver_Channel SET ContentNum = 0 WHERE SiteId IN ({inString}) OR Id IN ({inString})"; - ExecuteNonQuery(sqlString); - } - - public void Delete(int siteId, int channelId) - { - var channelInfo = GetChannelInfo(channelId); - if (channelInfo == null) return; - - var idList = new List(); - if (channelInfo.ChildrenCount > 0) - { - idList = ChannelManager.GetChannelIdList(channelInfo, EScopeType.Descendant, string.Empty, string.Empty, string.Empty); - } - idList.Add(channelId); - - string deleteCmd = - $"DELETE FROM siteserver_Channel WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; - - int deletedNum; - - var siteInfo = SiteManager.GetSiteInfo(siteId); - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - DataProvider.ContentDao.DeleteContentsByDeletedChannelIdList(trans, siteInfo, idList); - - deletedNum = ExecuteNonQuery(trans, deleteCmd); - - if (channelInfo.ParentId != 0) - { - string taxisCmd = - $"UPDATE siteserver_Channel SET Taxis = Taxis - {deletedNum} WHERE (Taxis > {channelInfo.Taxis}) AND (SiteId = {channelInfo.SiteId})"; - ExecuteNonQuery(trans, taxisCmd); - } - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - UpdateIsLastNode(channelInfo.ParentId); - UpdateSubtractChildrenCount(channelInfo.ParentsPath, deletedNum); - - if (channelInfo.ParentId == 0) - { - DataProvider.SiteDao.Delete(channelInfo.Id); - } - else - { - ChannelManager.RemoveCache(channelInfo.SiteId); - } - } - - public ChannelInfo GetChannelInfo(int channelId) - { - ChannelInfo channelInfo = null; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, channelId) - }; - - using (var rdr = ExecuteReader(SqlSelect, parms)) - { - if (rdr.Read()) - { - channelInfo = GetChannelInfo(rdr); - } - rdr.Close(); - } - return channelInfo; - } - - /// - /// 得到最后一个添加的子节点 - /// - public ChannelInfo GetChannelInfoByLastAddDate(int channelId) - { - ChannelInfo channelInfo = null; - - var parms = new IDataParameter[] - { - GetParameter(ParmParentId, DataType.Integer, channelId) - }; - - using (var rdr = ExecuteReader(SqlSelectByLastAddDate, parms)) - { - if (rdr.Read()) - { - channelInfo = GetChannelInfo(rdr); - } - rdr.Close(); - } - return channelInfo; - } - - /// - /// 得到第一个子节点 - /// - public ChannelInfo GetChannelInfoByTaxis(int channelId) - { - ChannelInfo channelInfo = null; - - var parms = new IDataParameter[] - { - GetParameter(ParmParentId, DataType.Integer, channelId) - }; - - using (var rdr = ExecuteReader(SqlSelectByTaxis, parms)) - { - if (rdr.Read()) - { - channelInfo = GetChannelInfo(rdr); - } - rdr.Close(); - } - return channelInfo; - } - - //public ChannelInfo GetChannelInfoByParentId(int siteId, int parentId, string contentModelPluginId) - //{ - // ChannelInfo channelInfo = null; - // var parms = new IDataParameter[] - // { - // GetParameter(ParmSiteId, DataType.Integer, siteId), - // GetParameter(ParmParentId, DataType.Integer, parentId), - // GetParameter(ParmContentModelPluginId, DataType.VarChar, 50, contentModelPluginId) - // }; - // using (var rdr = ExecuteReader(SqlSelectByParentIdAndContentModelPluginId, parms)) - // { - // if (rdr.Read()) - // { - // channelInfo = GetChannelInfo(rdr); - // } - // rdr.Close(); - // } - // return channelInfo; - //} - - public int GetIdByParentIdAndChannelName(int siteId, int parentId, string channelName, bool recursive) - { - var channelId = 0; - string sqlString; - - if (recursive) - { - if (siteId == parentId) - { - sqlString = - $"SELECT Id FROM siteserver_Channel WHERE (SiteId = {siteId} AND ChannelName = '{PageUtils.FilterSql(channelName)}') ORDER BY Taxis"; - } - else - { - sqlString = $@"SELECT Id -FROM siteserver_Channel -WHERE ((ParentId = {parentId}) OR - (ParentsPath = '{parentId}') OR - (ParentsPath LIKE '{parentId},%') OR - (ParentsPath LIKE '%,{parentId},%') OR - (ParentsPath LIKE '%,{parentId}')) AND ChannelName = '{PageUtils.FilterSql(channelName)}' -ORDER BY Taxis"; - } - } - else - { - sqlString = - $"SELECT Id FROM siteserver_Channel WHERE (ParentId = {parentId} AND ChannelName = '{PageUtils.FilterSql(channelName)}') ORDER BY Taxis"; - } - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - channelId = GetInt(rdr, 0); - } - rdr.Close(); - } - return channelId; - } - - public int GetIdByParentIdAndTaxis(int parentId, int taxis, bool isNextChannel) - { - var channelId = 0; - - //var sqlString = isNextChannel ? $"SELECT TOP 1 Id FROM siteserver_Channel WHERE (ParentId = {parentId} AND Taxis > {taxis}) ORDER BY Taxis" : $"SELECT TOP 1 Id FROM siteserver_Channel WHERE (ParentId = {parentId} AND Taxis < {taxis}) ORDER BY Taxis DESC"; - var sqlString = isNextChannel - ? SqlUtils.ToTopSqlString(TableName, "Id", - $"WHERE (ParentId = {parentId} AND Taxis > {taxis})", "ORDER BY Taxis", 1) - : SqlUtils.ToTopSqlString(TableName, "Id", - $"WHERE (ParentId = {parentId} AND Taxis < {taxis})", "ORDER BY Taxis DESC", 1); - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - channelId = GetInt(rdr, 0); - } - rdr.Close(); - } - return channelId; - } - - public int GetId(int siteId, string orderString) - { - if (orderString == "1") - return siteId; - - var channelId = siteId; - - var orderArr = orderString.Split('_'); - for (var index = 1; index < orderArr.Length; index++) - { - var order = int.Parse(orderArr[index]); - channelId = GetIdByParentIdAndOrder(channelId, order); - } - return channelId; - } - - public int GetSiteId(int channelId) - { - var siteId = 0; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, channelId) - }; - - using (var rdr = ExecuteReader(SqlSelectSiteIdById, parms)) - { - if (rdr.Read()) - { - siteId = GetInt(rdr, 0); - if (siteId == 0) - { - siteId = channelId; - } - } - rdr.Close(); - } - return siteId; - } - - /// - /// 在节点树中得到此节点的排序号,以“1_2_5_2”的形式表示 - /// - public string GetOrderStringInSite(int channelId) - { - var retval = ""; - if (channelId != 0) - { - var parentId = GetParentId(channelId); - if (parentId != 0) - { - var orderString = GetOrderStringInSite(parentId); - retval = orderString + "_" + GetOrderInSibling(channelId, parentId); - } - else - { - retval = "1"; - } - } - return retval; - } - - //public List GetIdListByGroupName(int siteId, string groupName) - //{ - // var idList = new List(); - // string sqlString = - // $"SELECT Id FROM siteserver_Channel WHERE SiteId={siteId} AND (GroupNameCollection LIKE '{PageUtils.FilterSql(groupName)},%' OR GroupNameCollection LIKE '%,{PageUtils.FilterSql(groupName)}' OR GroupNameCollection LIKE '%,{PageUtils.FilterSql(groupName)},%' OR GroupNameCollection='{PageUtils.FilterSql(groupName)}') ORDER By Id"; - - // using (var rdr = ExecuteReader(sqlString)) - // { - // while (rdr.Read()) - // { - // idList.Add(GetInt(rdr, 0)); - // } - // rdr.Close(); - // } - - // return idList; - //} - - public int GetOrderInSibling(int channelId, int parentId) - { - string cmd = $"SELECT Id FROM siteserver_Channel WHERE (ParentId = {parentId}) ORDER BY Taxis"; - var idList = new List(); - using (var rdr = ExecuteReader(cmd)) - { - while (rdr.Read()) - { - idList.Add(GetInt(rdr, 0)); - } - rdr.Close(); - } - return idList.IndexOf(channelId) + 1; - } - - public List GetIndexNameList(int siteId) - { - var list = new List(); - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - - using (var rdr = ExecuteReader(SqlSelectIndexNameCollection, parms)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - - return list; - } - - private static string GetGroupWhereString(string group, string groupNot) - { - var whereStringBuilder = new StringBuilder(); - if (!string.IsNullOrEmpty(group)) - { - group = group.Trim().Trim(','); - var groupArr = group.Split(','); - if (groupArr.Length > 0) - { - whereStringBuilder.Append(" AND ("); - foreach (var theGroup in groupArr) - { - var trimGroup = theGroup.Trim(); - //whereStringBuilder.Append( - // $" (siteserver_Channel.GroupNameCollection = '{trimGroup}' OR CHARINDEX('{trimGroup},',siteserver_Channel.GroupNameCollection) > 0 OR CHARINDEX(',{trimGroup},', siteserver_Channel.GroupNameCollection) > 0 OR CHARINDEX(',{trimGroup}', siteserver_Channel.GroupNameCollection) > 0) OR "); - - whereStringBuilder.Append( - $" (siteserver_Channel.GroupNameCollection = '{trimGroup}' OR {SqlUtils.GetInStr("siteserver_Channel.GroupNameCollection", trimGroup + ",")} OR {SqlUtils.GetInStr("siteserver_Channel.GroupNameCollection", "," + trimGroup + ",")} OR {SqlUtils.GetInStr("siteserver_Channel.GroupNameCollection", "," + trimGroup)}) OR "); - } - if (groupArr.Length > 0) - { - whereStringBuilder.Length = whereStringBuilder.Length - 3; - } - whereStringBuilder.Append(") "); - } - } - - if (!string.IsNullOrEmpty(groupNot)) - { - groupNot = groupNot.Trim().Trim(','); - var groupNotArr = groupNot.Split(','); - if (groupNotArr.Length > 0) - { - whereStringBuilder.Append(" AND ("); - foreach (var theGroupNot in groupNotArr) - { - var trimGroupNot = theGroupNot.Trim(); - //whereStringBuilder.Append( - // $" (siteserver_Channel.GroupNameCollection <> '{trimGroupNot}' AND CHARINDEX('{trimGroupNot},',siteserver_Channel.GroupNameCollection) = 0 AND CHARINDEX(',{trimGroupNot},',siteserver_Channel.GroupNameCollection) = 0 AND CHARINDEX(',{trimGroupNot}',siteserver_Channel.GroupNameCollection) = 0) AND "); - - whereStringBuilder.Append( - $" (siteserver_Channel.GroupNameCollection <> '{trimGroupNot}' AND {SqlUtils.GetNotInStr("siteserver_Channel.GroupNameCollection", trimGroupNot + ",")} AND {SqlUtils.GetNotInStr("siteserver_Channel.GroupNameCollection", "," + trimGroupNot + ",")} AND {SqlUtils.GetNotInStr("siteserver_Channel.GroupNameCollection", "," + trimGroupNot)}) AND "); - } - if (groupNotArr.Length > 0) - { - whereStringBuilder.Length = whereStringBuilder.Length - 4; - } - whereStringBuilder.Append(") "); - } - } - return whereStringBuilder.ToString(); - } - - public string GetWhereString(int siteId, string group, string groupNot, bool isImageExists, bool isImage, string where) - { - var whereStringBuilder = new StringBuilder(); - if (isImageExists) - { - whereStringBuilder.Append(isImage - ? " AND siteserver_Channel.ImageUrl <> '' " - : " AND siteserver_Channel.ImageUrl = '' "); - } - - whereStringBuilder.Append(GetGroupWhereString(group, groupNot)); - - if (!string.IsNullOrEmpty(where)) - { - whereStringBuilder.Append($" AND {where} "); - } - - return whereStringBuilder.ToString(); - } - - public int GetCountBySiteId(int siteId) - { - var count = 0; - string cmd = - $"SELECT COUNT(*) AS TotalNum FROM siteserver_Channel WHERE (SiteId = {siteId} AND (Id = {siteId} OR ParentId > 0))"; - - using (var rdr = ExecuteReader(cmd)) - { - if (rdr.Read()) - { - count = GetInt(rdr, 0); - } - rdr.Close(); - } - - return count; - } - - public int GetCount(int channelId) - { - var count = 0; - - var parms = new IDataParameter[] - { - GetParameter(ParmParentId, DataType.Integer, channelId) - }; - - using (var rdr = ExecuteReader(SqlSelectCount, parms)) - { - if (rdr.Read()) - { - count = GetInt(rdr, 0); - } - rdr.Close(); - } - return count; - } - - public int GetSequence(int siteId, int channelId) - { - var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); - string sqlString = - $"SELECT COUNT(*) AS TotalNum FROM siteserver_Channel WHERE SiteId = {siteId} AND ParentId = {channelInfo.ParentId} AND Taxis > (SELECT Taxis FROM siteserver_Channel WHERE Id = {channelId})"; - - return DataProvider.DatabaseDao.GetIntResult(sqlString) + 1; - } - - public int GetIdByIndexName(int siteId, string indexName) - { - var channelId = 0; - if (string.IsNullOrEmpty(indexName)) return channelId; - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId), - GetParameter(ParmIndexName, DataType.VarChar, 255, indexName) - }; - - using (var rdr = ExecuteReader(SqlSelectIdByIndex, parms)) - { - if (rdr.Read()) - { - channelId = GetInt(rdr, 0); - } - rdr.Close(); - } - - return channelId; - } - - public int GetIdByContentModelType(int siteId, string contentModelPluginId) - { - var channelId = 0; - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId), - GetParameter(ParmContentModelPluginId, DataType.VarChar, 50, contentModelPluginId) - }; - - using (var rdr = ExecuteReader(SqlSelectIdByContentModelPluginId, parms)) - { - if (rdr.Read()) - { - channelId = GetInt(rdr, 0); - } - rdr.Close(); - } - - return channelId; - } - - public bool IsExists(int channelId) - { - var exists = false; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, channelId) - }; - - using (var rdr = ExecuteReader(SqlSelectId, parms)) - { - if (rdr.Read()) - { - if (!rdr.IsDBNull(0)) - { - exists = true; - } - } - rdr.Close(); - } - return exists; - } - - public void UpdateChannelTemplateId(int channelId, int channelTemplateId) - { - string sqlString = - $"UPDATE siteserver_Channel SET ChannelTemplateId = {channelTemplateId} WHERE Id = {channelId}"; - ExecuteNonQuery(sqlString); - - ChannelManager.RemoveCache(channelId); - } - - public void UpdateContentTemplateId(int channelId, int contentTemplateId) - { - string sqlString = - $"UPDATE siteserver_Channel SET ContentTemplateId = {contentTemplateId} WHERE Id = {channelId}"; - ExecuteNonQuery(sqlString); - - ChannelManager.RemoveCache(channelId); - } - - public List GetIdListByTotalNum(List channelIdList, int totalNum, string orderByString, string whereString) - { - if (channelIdList == null || channelIdList.Count == 0) - { - return channelIdList; - } - - string sqlString; - if (totalNum > 0) - { -// sqlString = $@"SELECT TOP {totalNum} Id -//FROM siteserver_Channel -//WHERE (Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) {whereString}) {orderByString} -//"; - sqlString = SqlUtils.ToTopSqlString(TableName, "Id", - $"WHERE (Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) {whereString})", - orderByString, - totalNum); - } - else - { - sqlString = $@"SELECT Id -FROM siteserver_Channel -WHERE (Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) {whereString}) {orderByString} -"; - } - - var list = new List(); - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetInt(rdr, 0)); - } - rdr.Close(); - } - return list; - } - -// public List GetIdListByScopeType(int channelId, EScopeType scopeType, string group, string groupNot) -// { -// var list = new List(); -// string sqlString = null; -// var groupWhereString = GetGroupWhereString(group, groupNot); -// if (scopeType == EScopeType.All) -// { -// sqlString = $@"SELECT Id -//FROM siteserver_Channel -//WHERE ((Id = {channelId}) OR -// (ParentId = {channelId}) OR -// (ParentsPath = '{channelId}') OR -// (ParentsPath LIKE '{channelId},%') OR -// (ParentsPath LIKE '%,{channelId},%') OR -// (ParentsPath LIKE '%,{channelId}')) {groupWhereString} -//ORDER BY Taxis"; -// } -// else if (scopeType == EScopeType.Self) -// { -// list.Add(channelId); -// return list; -// } -// else if (scopeType == EScopeType.Children) -// { -// sqlString = $@"SELECT Id -//FROM siteserver_Channel -//WHERE (ParentId = {channelId}) {groupWhereString} -//ORDER BY Taxis"; -// } -// else if (scopeType == EScopeType.Descendant) -// { -// sqlString = $@"SELECT Id -//FROM siteserver_Channel -//WHERE ((ParentId = {channelId}) OR -// (ParentsPath = '{channelId}') OR -// (ParentsPath LIKE '{channelId},%') OR -// (ParentsPath LIKE '%,{channelId},%') OR -// (ParentsPath LIKE '%,{channelId}')) {groupWhereString} -//ORDER BY Taxis"; -// } -// else if (scopeType == EScopeType.SelfAndChildren) -// { -// sqlString = $@"SELECT Id -//FROM siteserver_Channel -//WHERE ((Id = {channelId}) OR -// (ParentId = {channelId})) {groupWhereString} -//ORDER BY Taxis"; -// } - -// using (var rdr = ExecuteReader(sqlString)) -// { -// while (rdr.Read()) -// { -// list.Add(GetInt(rdr, 0)); -// } -// rdr.Close(); -// } - -// return list; -// } - -// public List GetIdListByScopeType(ChannelInfo channelInfo, EScopeType scopeType, string group, string groupNot, string contentModelPluginId) -// { -// if (channelInfo == null || channelInfo.Id <= 0) return new List(); - -// var list = new List(); - -// if (scopeType == EScopeType.Self) -// { -// list.Add(channelInfo.Id); -// return list; -// } -// if (channelInfo.ChildrenCount == 0) -// { -// if (scopeType != EScopeType.Children && scopeType != EScopeType.Descendant) -// { -// list.Add(channelInfo.Id); -// } - -// return list; -// } - -// string sqlString = null; -// var whereString = GetGroupWhereString(group, groupNot); -// if (!string.IsNullOrEmpty(contentModelPluginId)) -// { -// whereString += $" AND ContentModelPluginId = '{contentModelPluginId}'"; -// } - -// if (scopeType == EScopeType.All) -// { -// sqlString = $@"SELECT Id -//FROM siteserver_Channel -//WHERE ((Id = {channelInfo.Id}) OR -// (ParentId = {channelInfo.Id}) OR -// (ParentsPath = '{channelInfo.Id}') OR -// (ParentsPath LIKE '{channelInfo.Id},%') OR -// (ParentsPath LIKE '%,{channelInfo.Id},%') OR -// (ParentsPath LIKE '%,{channelInfo.Id}')) {whereString} -//ORDER BY Taxis"; -// } -// else if (scopeType == EScopeType.Children) -// { -// sqlString = $@"SELECT Id -//FROM siteserver_Channel -//WHERE (ParentId = {channelInfo.Id}) {whereString} -//ORDER BY Taxis"; -// } -// else if (scopeType == EScopeType.Descendant) -// { -// sqlString = $@"SELECT Id -//FROM siteserver_Channel -//WHERE ((ParentId = {channelInfo.Id}) OR -// (ParentsPath = '{channelInfo.Id}') OR -// (ParentsPath LIKE '{channelInfo.Id},%') OR -// (ParentsPath LIKE '%,{channelInfo.Id},%') OR -// (ParentsPath LIKE '%,{channelInfo.Id}')) {whereString} -//ORDER BY Taxis"; -// } -// else if (scopeType == EScopeType.SelfAndChildren) -// { -// sqlString = $@"SELECT Id -//FROM siteserver_Channel -//WHERE ((Id = {channelInfo.Id}) OR -// (ParentId = {channelInfo.Id})) {whereString} -//ORDER BY Taxis"; -// } - -// using (var rdr = ExecuteReader(sqlString)) -// { -// while (rdr.Read()) -// { -// list.Add(GetInt(rdr, 0)); -// } -// rdr.Close(); -// } - -// return list; -// } - -// public List GetIdListForDescendant(int parentId) -// { -// string sqlString = $@"SELECT Id -//FROM siteserver_Channel -//WHERE (ParentsPath LIKE '{parentId},%') OR -// (ParentsPath LIKE '%,{parentId},%') OR -// (ParentsPath LIKE '%,{parentId}') OR -// (ParentId = {parentId}) -//"; -// var list = new List(); - -// using (var rdr = ExecuteReader(sqlString)) -// { -// while (rdr.Read()) -// { -// list.Add(GetInt(rdr, 0)); -// } -// rdr.Close(); -// } - -// return list; -// } - -// public List GetIdListByParentId(int siteId, int parentId) -// { -// string sqlString; -// if (parentId == 0) -// { -// sqlString = $@"SELECT Id -//FROM siteserver_Channel -//WHERE (Id = {siteId} OR ParentId = {siteId}) -//ORDER BY Taxis"; -// } -// else -// { -// sqlString = $@"SELECT Id -//FROM siteserver_Channel -//WHERE (ParentId = {parentId}) -//ORDER BY Taxis"; -// } - -// var list = new List(); - -// using (var rdr = ExecuteReader(sqlString)) -// { -// while (rdr.Read()) -// { -// list.Add(GetInt(rdr, 0)); -// } -// rdr.Close(); -// } - -// return list; -// } - -// public List GetChannelInfoListByParentId(int siteId, int parentId) -// { -// var sqlString = $@"SELECT Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, ContentNum, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues FROM siteserver_Channel -//WHERE (SiteId={siteId} AND ParentId = {parentId}) -//ORDER BY Taxis"; - -// var list = new List(); -// using (var rdr = ExecuteReader(sqlString)) -// { -// while (rdr.Read()) -// { -// var channelInfo = GetChannelInfo(rdr); -// list.Add(channelInfo); -// } -// rdr.Close(); -// } - -// return list; -// } - -// public List GetIdListBySiteId(int siteId) -// { -// string sqlString = $@"SELECT Id -//FROM siteserver_Channel -//WHERE SiteId = {siteId} AND (Id = {siteId} OR ParentId > 0) -//ORDER BY Taxis"; -// var list = new List(); - -// using (var rdr = ExecuteReader(sqlString)) -// { -// while (rdr.Read()) -// { -// list.Add(GetInt(rdr, 0)); -// } -// rdr.Close(); -// } - -// return list; -// } - - public Dictionary GetChannelInfoDictionaryBySiteId(int siteId) - { - var dic = new Dictionary(); - string sqlString = - $@"SELECT Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, ContentNum, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues -FROM siteserver_Channel -WHERE (SiteId = {siteId} AND (Id = {siteId} OR ParentId > 0)) -ORDER BY Taxis"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var channelInfo = GetChannelInfo(rdr); - dic.Add(channelInfo.Id, channelInfo); - } - rdr.Close(); - } - - return dic; - } - - public string SqlColumns => $"{ChannelAttribute.Id}, {ChannelAttribute.AddDate}, {ChannelAttribute.Taxis}"; - - public IDataReader GetStlDataSource(List channelIdList, int startNum, int totalNum, string whereString, string orderByString) - { - if (channelIdList == null || channelIdList.Count == 0) - { - return null; - } - - string sqlWhereString = - $"WHERE (Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) {whereString})"; - - var sqlSelect = DataProvider.DatabaseDao.GetSelectSqlString(TableName, startNum, totalNum, SqlColumns, sqlWhereString, orderByString); - - return ExecuteReader(sqlSelect); - } - - public DataSet GetStlDataSourceBySiteId(int siteId, int startNum, int totalNum, string whereString, string orderByString) - { - string sqlWhereString = $"WHERE (SiteId = {siteId} {whereString})"; - - var sqlSelect = DataProvider.DatabaseDao.GetSelectSqlString(TableName, startNum, totalNum, SqlColumns, sqlWhereString, orderByString); - - return ExecuteDataset(sqlSelect); - } - - public DataSet GetStlDataSet(List channelIdList, int startNum, int totalNum, string whereString, string orderByString) - { - if (channelIdList == null || channelIdList.Count == 0) - { - return null; - } - - string sqlWhereString = - $"WHERE (Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) {whereString})"; - - var sqlSelect = DataProvider.DatabaseDao.GetSelectSqlString(TableName, startNum, totalNum, SqlColumns, sqlWhereString, orderByString); - - return ExecuteDataset(sqlSelect); - } - - public DataSet GetStlDataSetBySiteId(int siteId, int startNum, int totalNum, string whereString, string orderByString) - { - string sqlWhereString = $"WHERE (SiteId = {siteId} {whereString})"; - - var sqlSelect = DataProvider.DatabaseDao.GetSelectSqlString(TableName, startNum, totalNum, SqlColumns, sqlWhereString, orderByString); - - return ExecuteDataset(sqlSelect); - } - -// public List GetChannelInfoListBySiteId(int siteId, string whereString) -// { -// var list = new List(); -// string cmd = -// $@"SELECT Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, ContentNum, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues -//FROM siteserver_Channel -//WHERE (SiteId = {siteId} AND (Id = {siteId} OR ParentId > 0)) -//{whereString} -//ORDER BY Taxis"; - -// using (var rdr = ExecuteReader(cmd)) -// { -// while (rdr.Read()) -// { -// var channelInfo = GetChannelInfo(rdr); -// list.Add(channelInfo); -// } -// rdr.Close(); -// } -// return list; -// } - -// public List GetChannelInfoList(ChannelInfo channelInfo, int totalNum, string whereString, EScopeType scopeType, string orderByString) -// { -// var idList = ChannelManager.GetChannelIdList(channelInfo, scopeType, string.Empty, string.Empty, string.Empty); -// if (idList == null || idList.Count == 0) -// { -// return null; -// } - -// string sqlString; -// if (totalNum > 0) -// { -// // sqlString = -// // $@"SELECT TOP {totalNum} Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, ContentNum, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues -// //FROM siteserver_Channel -// //WHERE (Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) {whereString}) {orderByString} -// //"; -// sqlString = SqlUtils.ToTopSqlString(TableName, -// "Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, ContentNum, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues", -// $"WHERE (Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)}) {whereString})", -// orderByString, -// totalNum); -// } -// else -// { -// sqlString = -// $@" -//SELECT Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, ContentNum, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues -//FROM siteserver_Channel -//WHERE (Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)}) {whereString}) {orderByString} -//"; -// } - -// var list = new List(); - -// var parms = new IDataParameter[] -// { -// GetParameter(ParmId, DataType.Integer, channelInfo.Id) -// }; - -// using (var rdr = ExecuteReader(sqlString, parms)) -// { -// while (rdr.Read()) -// { -// list.Add(GetChannelInfo(rdr)); -// } -// rdr.Close(); -// } -// return list; -// } - - public int GetContentNumBySiteId(int siteId) - { - string sqlString = - $"SELECT SUM(ContentNum) FROM siteserver_Channel WHERE (SiteId = {siteId})"; - - return DataProvider.DatabaseDao.GetIntResult(sqlString); - } - - public List GetContentModelPluginIdList() - { - var list = new List(); - - const string sqlString = "SELECT DISTINCT ContentModelPluginId FROM siteserver_Channel"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - return list; - } - - public List GetAllFilePathBySiteId(int siteId) - { - var list = new List(); - - var sqlString = - $"SELECT FilePath FROM siteserver_Channel WHERE FilePath <> '' AND SiteId = {siteId}"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - return list; - } - -// public List GetIdListByChildId(int siteId, int childId, List channelIdList) -// { -// var sqlString = $@"SELECT Id,ParentId FROM siteserver_Channel -//WHERE (SiteId={siteId} AND Id={childId}) -//ORDER BY Taxis"; - -// using (var rdr = ExecuteReader(sqlString)) -// { -// while (rdr.Read()) -// { -// var channelId = GetInt(rdr, 0); -// var parentId = GetInt(rdr, 1); -// channelIdList.Add(channelId); -// GetIdListByChildId(siteId, parentId, channelIdList); - -// } -// rdr.Close(); -// } -// return channelIdList; -// } - - public int GetIdByChannelIdOrChannelIndexOrChannelName(int siteId, int channelId, string channelIndex, string channelName) - { - var retval = channelId; - - if (!string.IsNullOrEmpty(channelIndex)) - { - var theId = GetIdByIndexName(siteId, channelIndex); - if (theId != 0) - { - retval = theId; - } - } - if (!string.IsNullOrEmpty(channelName)) - { - var theId = GetIdByParentIdAndChannelName(siteId, retval, channelName, true); - if (theId == 0) - { - theId = GetIdByParentIdAndChannelName(siteId, siteId, channelName, true); - } - if (theId != 0) - { - retval = theId; - } - } - - return retval; - } - - public int GetTemplateUseCount(int siteId, int templateId, TemplateType templateType, bool isDefault) - { - var sqlString = string.Empty; - - if (templateType == TemplateType.IndexPageTemplate) - { - if (isDefault) - { - return 1; - } - return 0; - } - if (templateType == TemplateType.FileTemplate) - { - return 1; - } - if (templateType == TemplateType.ChannelTemplate) - { - sqlString = isDefault - ? $"SELECT COUNT(*) FROM {TableName} WHERE ({nameof(ChannelInfo.ChannelTemplateId)} = {templateId} OR {nameof(ChannelInfo.ChannelTemplateId)} = 0) AND {nameof(ChannelInfo.SiteId)} = {siteId}" - : $"SELECT COUNT(*) FROM {TableName} WHERE {nameof(ChannelInfo.ChannelTemplateId)} = {templateId} AND {nameof(ChannelInfo.SiteId)} = {siteId}"; - } - else if (templateType == TemplateType.ContentTemplate) - { - sqlString = isDefault - ? $"SELECT COUNT(*) FROM {TableName} WHERE ({nameof(ChannelInfo.ContentTemplateId)} = {templateId} OR {nameof(ChannelInfo.ContentTemplateId)} = 0) AND {nameof(ChannelInfo.SiteId)} = {siteId}" - : $"SELECT COUNT(*) FROM {TableName} WHERE {nameof(ChannelInfo.ContentTemplateId)} = {templateId} AND {nameof(ChannelInfo.SiteId)} = {siteId}"; - } - - return DataProvider.DatabaseDao.GetIntResult(sqlString); - } - - public List GetChannelIdList(TemplateInfo templateInfo) - { - var list = new List(); - var sqlString = string.Empty; - - if (templateInfo.TemplateType == TemplateType.ChannelTemplate) - { - sqlString = templateInfo.IsDefault - ? $"SELECT {nameof(ChannelInfo.Id)} FROM {TableName} WHERE ({nameof(ChannelInfo.ChannelTemplateId)} = {templateInfo.Id} OR {nameof(ChannelInfo.ChannelTemplateId)} = 0) AND {nameof(ChannelInfo.SiteId)} = {templateInfo.SiteId}" - : $"SELECT {nameof(ChannelInfo.Id)} FROM {TableName} WHERE {nameof(ChannelInfo.ChannelTemplateId)} = {templateInfo.Id} AND {nameof(ChannelInfo.SiteId)} = {templateInfo.SiteId}"; - } - else if (templateInfo.TemplateType == TemplateType.ContentTemplate) - { - sqlString = templateInfo.IsDefault - ? $"SELECT {nameof(ChannelInfo.Id)} FROM {TableName} WHERE ({nameof(ChannelInfo.ContentTemplateId)} = {templateInfo.Id} OR {nameof(ChannelInfo.ContentTemplateId)} = 0) AND {nameof(ChannelInfo.SiteId)} = {templateInfo.SiteId}" - : $"SELECT {nameof(ChannelInfo.Id)} FROM {TableName} WHERE {nameof(ChannelInfo.ContentTemplateId)} = {templateInfo.Id} AND {nameof(ChannelInfo.SiteId)} = {templateInfo.SiteId}"; - } - - if (!string.IsNullOrEmpty(sqlString)) - { - list = DataProvider.DatabaseDao.GetIntList(sqlString); - } - - return list; - } - - private ChannelInfo GetChannelInfo(IDataReader rdr) - { - var i = 0; - return new ChannelInfo(GetInt(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), - GetString(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), - GetBool(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetDateTime(rdr, i++), - GetString(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), - GetString(rdr, i++), GetString(rdr, i++), ELinkTypeUtils.GetEnumType(GetString(rdr, i++)), - GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetString(rdr, i)); - } - } -} diff --git a/SiteServer.CMS/Provider/ChannelGroupDao.cs b/SiteServer.CMS/Provider/ChannelGroupDao.cs deleted file mode 100644 index 81b72c233..000000000 --- a/SiteServer.CMS/Provider/ChannelGroupDao.cs +++ /dev/null @@ -1,323 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Provider -{ - public class ChannelGroupDao : DataProviderBase - { - public override string TableName => "siteserver_ChannelGroup"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(ChannelGroupInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelGroupInfo.GroupName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelGroupInfo.SiteId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelGroupInfo.Taxis), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(ChannelGroupInfo.Description), - DataType = DataType.Text - } - }; - - private const string ParmGroupName = "@GroupName"; - private const string ParmSiteId = "@SiteId"; - private const string ParmTaxis = "@Taxis"; - private const string ParmDescription = "@Description"; - - - public void Insert(ChannelGroupInfo groupInfo) - { - var maxTaxis = GetMaxTaxis(groupInfo.SiteId); - groupInfo.Taxis = maxTaxis + 1; - - var sqlString = $"INSERT INTO {TableName} (GroupName, SiteId, Taxis, Description) VALUES (@GroupName, @SiteId, @Taxis, @Description)"; - - var insertParms = new IDataParameter[] - { - GetParameter(ParmGroupName, DataType.VarChar, 255, groupInfo.GroupName), - GetParameter(ParmSiteId, DataType.Integer, groupInfo.SiteId), - GetParameter(ParmTaxis, DataType.Integer, groupInfo.Taxis), - GetParameter(ParmDescription, DataType.Text, groupInfo.Description) - }; - - ExecuteNonQuery(sqlString, insertParms); - } - - public void Update(ChannelGroupInfo groupInfo) - { - var sqlString = $"UPDATE {TableName} SET Description = @Description WHERE GroupName = @GroupName AND SiteId = @SiteId"; - - var updateParms = new IDataParameter[] - { - GetParameter(ParmDescription, DataType.Text, groupInfo.Description), - GetParameter(ParmGroupName, DataType.VarChar, 255, groupInfo.GroupName), - GetParameter(ParmSiteId, DataType.Integer, groupInfo.SiteId) - }; - - ExecuteNonQuery(sqlString, updateParms); - } - - public void Delete(int siteId, string groupName) - { - var sqlString = $"DELETE FROM {TableName} WHERE GroupName = @GroupName AND SiteId = @SiteId"; - - var groupParms = new IDataParameter[] - { - GetParameter(ParmGroupName, DataType.VarChar, 255, groupName), - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - - ExecuteNonQuery(sqlString, groupParms); - - var channelIdList = ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(siteId, siteId), EScopeType.All, groupName, string.Empty, string.Empty); - foreach (var channelId in channelIdList) - { - var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var groupNameList = TranslateUtils.StringCollectionToStringList(channelInfo.GroupNameCollection); - groupNameList.Remove(groupName); - channelInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(groupNameList); - DataProvider.ChannelDao.Update(channelInfo); - } - } - - public ChannelGroupInfo GetGroupInfo(int siteId, string groupName) - { - ChannelGroupInfo group = null; - - const string sqlString = "SELECT GroupName, SiteId, Taxis, Description FROM siteserver_ChannelGroup WHERE GroupName = @GroupName AND SiteId = @SiteId"; - - var parms = new IDataParameter[] - { - GetParameter(ParmGroupName, DataType.VarChar, 255, groupName), - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - var i = 0; - group = new ChannelGroupInfo(GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i)); - } - rdr.Close(); - } - - return group; - } - - public bool IsExists(int siteId, string groupName) - { - var exists = false; - - var sqlString = "SELECT GroupName FROM siteserver_ChannelGroup WHERE GroupName = @GroupName AND SiteId = @SiteId"; - - var parms = new IDataParameter[] - { - GetParameter(ParmGroupName, DataType.VarChar, 255, groupName), - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - exists = true; - } - rdr.Close(); - } - - return exists; - } - - public IDataReader GetDataSource(int siteId) - { - string sqlString = - $"SELECT GroupName, SiteId, Taxis, Description FROM siteserver_ChannelGroup WHERE SiteId = {siteId} ORDER BY Taxis DESC, GroupName"; - var enumerable = ExecuteReader(sqlString); - return enumerable; - } - - public List GetGroupInfoList(int siteId) - { - var list = new List(); - string sqlString = - $"SELECT GroupName, SiteId, Taxis, Description FROM siteserver_ChannelGroup WHERE SiteId = {siteId} ORDER BY Taxis DESC, GroupName"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var i = 0; - list.Add(new ChannelGroupInfo(GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i))); - } - rdr.Close(); - } - - return list; - } - - public List GetGroupNameList(int siteId) - { - var list = new List(); - string sqlString = - $"SELECT GroupName FROM siteserver_ChannelGroup WHERE SiteId = {siteId} ORDER BY Taxis DESC, GroupName"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - - return list; - } - - private int GetTaxis(int siteId, string groupName) - { - var sqlString = "SELECT Taxis FROM siteserver_ChannelGroup WHERE (GroupName = @GroupName AND SiteId = @SiteId)"; - var parms = new IDataParameter[] - { - GetParameter(ParmGroupName, DataType.VarChar, 255, groupName), - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - return DataProvider.DatabaseDao.GetIntResult(sqlString, parms); - } - - private void SetTaxis(int siteId, string groupName, int taxis) - { - string sqlString = - $"UPDATE siteserver_ChannelGroup SET Taxis = {taxis} WHERE (GroupName = @GroupName AND SiteId = @SiteId)"; - var parms = new IDataParameter[] - { - GetParameter(ParmGroupName, DataType.VarChar, 255, groupName), - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - ExecuteNonQuery(sqlString, parms); - } - - private int GetMaxTaxis(int siteId) - { - string sqlString = - $"SELECT MAX(Taxis) FROM siteserver_ChannelGroup WHERE (SiteId = {siteId})"; - var maxTaxis = 0; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - maxTaxis = GetInt(rdr, 0); - } - rdr.Close(); - } - return maxTaxis; - } - - public bool UpdateTaxisToUp(int siteId, string groupName) - { - //Get Higher Taxis and ID - //var sqlString = "SELECT TOP 1 GroupName, Taxis FROM siteserver_ChannelGroup WHERE (Taxis > (SELECT Taxis FROM siteserver_ChannelGroup WHERE GroupName = @GroupName AND SiteId = @SiteId) AND SiteId = @SiteId) ORDER BY Taxis"; - var sqlString = SqlUtils.ToTopSqlString("siteserver_ChannelGroup", "GroupName, Taxis", - "WHERE (Taxis > (SELECT Taxis FROM siteserver_ChannelGroup WHERE GroupName = @GroupName AND SiteId = @SiteId) AND SiteId = @SiteId)", - "ORDER BY Taxis", 1); - - var higherGroupName = string.Empty; - var higherTaxis = 0; - - var parms = new IDataParameter[] - { - GetParameter(ParmGroupName, DataType.VarChar, 255, groupName), - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - higherGroupName = GetString(rdr, 0); - higherTaxis = GetInt(rdr, 1); - } - rdr.Close(); - } - - if (!string.IsNullOrEmpty(higherGroupName)) - { - //Get Taxis Of Selected ID - var selectedTaxis = GetTaxis(siteId, groupName); - - //Set The Selected Class Taxis To Higher Level - SetTaxis(siteId, groupName, higherTaxis); - //Set The Higher Class Taxis To Lower Level - SetTaxis(siteId, higherGroupName, selectedTaxis); - return true; - } - return false; - } - - public bool UpdateTaxisToDown(int siteId, string groupName) - { - //Get Lower Taxis and ID - //var sqlString = "SELECT TOP 1 GroupName, Taxis FROM siteserver_ChannelGroup WHERE (Taxis < (SELECT Taxis FROM siteserver_ChannelGroup WHERE GroupName = @GroupName AND SiteId = @SiteId) AND SiteId = @SiteId) ORDER BY Taxis DESC"; - var sqlString = SqlUtils.ToTopSqlString("siteserver_ChannelGroup", "GroupName, Taxis", - "WHERE (Taxis < (SELECT Taxis FROM siteserver_ChannelGroup WHERE GroupName = @GroupName AND SiteId = @SiteId) AND SiteId = @SiteId)", - "ORDER BY Taxis DESC", 1); - - var lowerGroupName = string.Empty; - var lowerTaxis = 0; - var parms = new IDataParameter[] - { - GetParameter(ParmGroupName, DataType.VarChar, 255, groupName), - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - lowerGroupName = GetString(rdr, 0); - lowerTaxis = GetInt(rdr, 1); - } - rdr.Close(); - } - - if (!string.IsNullOrEmpty(lowerGroupName)) - { - //Get Taxis Of Selected Class - var selectedTaxis = GetTaxis(siteId, groupName); - - //Set The Selected Class Taxis To Lower Level - SetTaxis(siteId, groupName, lowerTaxis); - //Set The Lower Class Taxis To Higher Level - SetTaxis(siteId, lowerGroupName, selectedTaxis); - return true; - } - return false; - } - } -} diff --git a/SiteServer.CMS/Provider/ConfigDao.cs b/SiteServer.CMS/Provider/ConfigDao.cs deleted file mode 100644 index 1eedd7e19..000000000 --- a/SiteServer.CMS/Provider/ConfigDao.cs +++ /dev/null @@ -1,153 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Provider -{ - public class ConfigDao : DataProviderBase - { - public override string TableName => "siteserver_Config"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(ConfigInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(ConfigInfo.IsInitialized), - DataType = DataType.VarChar, - Length = 18 - }, - new TableColumnInfo - { - ColumnName = nameof(ConfigInfo.DatabaseVersion), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(ConfigInfo.UpdateDate), - DataType = DataType.DateTime - }, - new TableColumnInfo - { - ColumnName = nameof(ConfigInfo.SystemConfig), - DataType = DataType.Text - } - }; - - private const string SqlInsertConfig = "INSERT INTO siteserver_Config (IsInitialized, DatabaseVersion, UpdateDate, SystemConfig) VALUES (@IsInitialized, @DatabaseVersion, @UpdateDate, @SystemConfig)"; - - private const string SqlSelectConfig = "SELECT IsInitialized, DatabaseVersion, UpdateDate, SystemConfig FROM siteserver_Config"; - - private const string SqlSelectIsInitialized = "SELECT IsInitialized FROM siteserver_Config"; - - private const string SqlSelectDatabaseVersion = "SELECT DatabaseVersion FROM siteserver_Config"; - - private const string SqlUpdateConfig = "UPDATE siteserver_Config SET IsInitialized = @IsInitialized, DatabaseVersion = @DatabaseVersion, UpdateDate = @UpdateDate, SystemConfig = @SystemConfig"; - - private const string ParmIsInitialized = "@IsInitialized"; - private const string ParmDatabaseVersion = "@DatabaseVersion"; - private const string ParmUpdateDate = "@UpdateDate"; - private const string ParmSystemConfig = "@SystemConfig"; - - public void Insert(ConfigInfo info) - { - var insertParms = new IDataParameter[] - { - GetParameter(ParmIsInitialized, DataType.VarChar, 18, info.IsInitialized.ToString()), - GetParameter(ParmDatabaseVersion, DataType.VarChar, 50, info.DatabaseVersion), - GetParameter(ParmUpdateDate, DataType.DateTime, info.UpdateDate), - GetParameter(ParmSystemConfig, DataType.Text, info.SystemConfigInfo.ToString()) - }; - - ExecuteNonQuery(SqlInsertConfig, insertParms); - ConfigManager.IsChanged = true; - } - - public void Update(ConfigInfo info) - { - var updateParms = new IDataParameter[] - { - GetParameter(ParmIsInitialized, DataType.VarChar, 18, info.IsInitialized.ToString()), - GetParameter(ParmDatabaseVersion, DataType.VarChar, 50, info.DatabaseVersion), - GetParameter(ParmUpdateDate, DataType.DateTime, info.UpdateDate), - GetParameter(ParmSystemConfig, DataType.Text, info.SystemConfigInfo.ToString()) - }; - - ExecuteNonQuery(SqlUpdateConfig, updateParms); - ConfigManager.IsChanged = true; - } - - public bool IsInitialized() - { - var isInitialized = false; - - try - { - using (var rdr = ExecuteReader(SqlSelectIsInitialized)) - { - if (rdr.Read()) - { - isInitialized = GetBool(rdr, 0); - } - rdr.Close(); - } - } - catch - { - // ignored - } - - return isInitialized; - } - - public string GetDatabaseVersion() - { - var databaseVersion = string.Empty; - - try - { - using (var rdr = ExecuteReader(SqlSelectDatabaseVersion)) - { - if (rdr.Read()) - { - databaseVersion = GetString(rdr, 0); - } - rdr.Close(); - } - } - catch - { - // ignored - } - - return databaseVersion; - } - - public ConfigInfo GetConfigInfo() - { - ConfigInfo info = null; - - using (var rdr = ExecuteReader(SqlSelectConfig)) - { - if (rdr.Read()) - { - var i = 0; - info = new ConfigInfo(GetBool(rdr, i++), GetString(rdr, i++), GetDateTime(rdr, i++), GetString(rdr, i)); - } - rdr.Close(); - } - - return info; - } - } -} diff --git a/SiteServer.CMS/Provider/ContentCheckDao.cs b/SiteServer.CMS/Provider/ContentCheckDao.cs deleted file mode 100644 index bcde073ce..000000000 --- a/SiteServer.CMS/Provider/ContentCheckDao.cs +++ /dev/null @@ -1,200 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Provider -{ - public class ContentCheckDao : DataProviderBase - { - public override string TableName => "siteserver_ContentCheck"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(ContentCheckInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(ContentCheckInfo.TableName), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(ContentCheckInfo.SiteId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(ContentCheckInfo.ChannelId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(ContentCheckInfo.ContentId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(ContentCheckInfo.IsAdmin), - DataType = DataType.VarChar, - Length = 18 - }, - new TableColumnInfo - { - ColumnName = nameof(ContentCheckInfo.UserName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(ContentCheckInfo.IsChecked), - DataType = DataType.VarChar, - Length = 18 - }, - new TableColumnInfo - { - ColumnName = nameof(ContentCheckInfo.CheckedLevel), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(ContentCheckInfo.CheckDate), - DataType = DataType.DateTime - }, - new TableColumnInfo - { - ColumnName = nameof(ContentCheckInfo.Reasons), - DataType = DataType.VarChar, - Length = 255 - } - }; - - private const string SqlSelect = "SELECT Id, TableName, SiteId, ChannelId, ContentId, IsAdmin, UserName, IsChecked, CheckedLevel, CheckDate, Reasons FROM siteserver_ContentCheck WHERE Id = @Id"; - - private const string SqlSelectAll = "SELECT Id, TableName, SiteId, ChannelId, ContentId, IsAdmin, UserName, IsChecked, CheckedLevel, CheckDate, Reasons FROM siteserver_ContentCheck WHERE TableName = @TableName AND ContentId = @ContentId ORDER BY Id DESC"; - - private const string SqlDelete = "DELETE FROM siteserver_ContentCheck WHERE Id = @Id"; - - private const string ParmId = "@Id"; - private const string ParmTableName = "@TableName"; - private const string ParmSiteId = "@SiteId"; - private const string ParmChannelId = "@ChannelId"; - private const string ParmContentId = "@ContentId"; - private const string ParmIsAdmin = "@IsAdmin"; - private const string ParmUserName = "@UserName"; - private const string ParmIsChecked = "@IsChecked"; - private const string ParmCheckedLevel = "@CheckedLevel"; - private const string ParmCheckDate = "@CheckDate"; - private const string ParmReasons = "@Reasons"; - - public void Insert(ContentCheckInfo checkInfo) - { - const string sqlString = "INSERT INTO siteserver_ContentCheck (TableName, SiteId, ChannelId, ContentId, IsAdmin, UserName, IsChecked, CheckedLevel, CheckDate, Reasons) VALUES (@TableName, @SiteId, @ChannelId, @ContentId, @IsAdmin, @UserName, @IsChecked, @CheckedLevel, @CheckDate, @Reasons)"; - - var parms = new IDataParameter[] - { - GetParameter(ParmTableName, DataType.VarChar, 50, checkInfo.TableName), - GetParameter(ParmSiteId, DataType.Integer, checkInfo.SiteId), - GetParameter(ParmChannelId, DataType.Integer, checkInfo.ChannelId), - GetParameter(ParmContentId, DataType.Integer, checkInfo.ContentId), - GetParameter(ParmIsAdmin, DataType.VarChar, 18, checkInfo.IsAdmin.ToString()), - GetParameter(ParmUserName, DataType.VarChar, 255, checkInfo.UserName), - GetParameter(ParmIsChecked, DataType.VarChar, 18, checkInfo.IsChecked.ToString()), - GetParameter(ParmCheckedLevel, DataType.Integer, checkInfo.CheckedLevel), - GetParameter(ParmCheckDate, DataType.DateTime, checkInfo.CheckDate), - GetParameter(ParmReasons, DataType.VarChar, 255, checkInfo.Reasons), - }; - - ExecuteNonQuery(sqlString, parms); - } - - public void Delete(int checkId) - { - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, checkId) - }; - - ExecuteNonQuery(SqlDelete, parms); - } - - public ContentCheckInfo GetCheckInfo(int checkId) - { - ContentCheckInfo checkInfo = null; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, checkId) - }; - - using (var rdr = ExecuteReader(SqlSelect, parms)) - { - if (rdr.Read()) - { - var i = 0; - checkInfo = new ContentCheckInfo(GetInt(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetBool(rdr, i++), GetString(rdr, i++), GetBool(rdr, i++), GetInt(rdr, i++), GetDateTime(rdr, i++), GetString(rdr, i)); - } - rdr.Close(); - } - - return checkInfo; - } - - public ContentCheckInfo GetCheckInfoByLastId(string tableName, int contentId) - { - ContentCheckInfo checkInfo = null; - - //var sqlString = "SELECT TOP 1 Id, TableName, SiteId, ChannelId, ContentId, IsAdmin, UserName, IsChecked, CheckedLevel, CheckDate, Reasons FROM siteserver_ContentCheck WHERE TableName = @TableName AND ContentId = @ContentId ORDER BY Id DESC"; - var sqlString = SqlUtils.ToTopSqlString(TableName, "Id, TableName, SiteId, ChannelId, ContentId, IsAdmin, UserName, IsChecked, CheckedLevel, CheckDate, Reasons", "WHERE TableName = @TableName AND ContentId = @ContentId", "ORDER BY Id DESC", 1); - - var parms = new IDataParameter[] - { - GetParameter(ParmTableName, DataType.VarChar, 50, tableName), - GetParameter(ParmContentId, DataType.Integer, contentId) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - var i = 0; - checkInfo = new ContentCheckInfo(GetInt(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetBool(rdr, i++), GetString(rdr, i++), GetBool(rdr, i++), GetInt(rdr, i++), GetDateTime(rdr, i++), GetString(rdr, i)); - } - rdr.Close(); - } - - return checkInfo; - } - - public List GetCheckInfoList(string tableName, int contentId) - { - var list = new List(); - - var parms = new IDataParameter[] - { - GetParameter(ParmTableName, DataType.VarChar, 50, tableName), - GetParameter(ParmContentId, DataType.Integer, contentId) - }; - - using (var rdr = ExecuteReader(SqlSelectAll, parms)) - { - while (rdr.Read()) - { - var i = 0; - list.Add(new ContentCheckInfo(GetInt(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetBool(rdr, i++), GetString(rdr, i++), GetBool(rdr, i++), GetInt(rdr, i++), GetDateTime(rdr, i++), GetString(rdr, i))); - } - rdr.Close(); - } - - return list; - } - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Provider/ContentDao.cs b/SiteServer.CMS/Provider/ContentDao.cs deleted file mode 100644 index 79a3f928d..000000000 --- a/SiteServer.CMS/Provider/ContentDao.cs +++ /dev/null @@ -1,2965 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Data; -using System.Text; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Provider -{ - public class ContentDao : DataProviderBase - { - public const int TaxisMaxValue = 2147483647; - public const int TaxisIsTopStartValue = 2147480000; - public const string SortFieldName = nameof(ContentAttribute.Taxis); - - public string StlColumns => $"{ContentAttribute.Id}, {ContentAttribute.ChannelId}, {ContentAttribute.IsTop}, {ContentAttribute.AddDate}, {ContentAttribute.LastEditDate}, {ContentAttribute.Taxis}, {ContentAttribute.Hits}, {ContentAttribute.HitsByDay}, {ContentAttribute.HitsByWeek}, {ContentAttribute.HitsByMonth}"; - - public string GetCreateTableCollectionInfoSqlString(string tableName) - { - var columnSqlStringList = new List(); - - var tableMetadataInfoList = TableMetadataManager.GetTableMetadataInfoList(tableName); - if (tableMetadataInfoList.Count > 0) - { - foreach (var metadataInfo in tableMetadataInfoList) - { - var columnSql = SqlUtils.GetColumnSqlString(metadataInfo.DataType, metadataInfo.AttributeName, metadataInfo.DataLength); - if (!string.IsNullOrEmpty(columnSql)) - { - columnSqlStringList.Add(columnSql); - } - } - } - - var sqlBuilder = new StringBuilder(); - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - sqlBuilder.Append($@"CREATE TABLE `{tableName}` ("); - sqlBuilder.Append($@" -`{nameof(ContentInfo.Id)}` INT AUTO_INCREMENT, -`{nameof(ContentInfo.ChannelId)}` INT, -`{nameof(ContentInfo.SiteId)}` INT, -`{nameof(ContentInfo.AddUserName)}` VARCHAR(255), -`{nameof(ContentInfo.LastEditUserName)}` VARCHAR(255), -`{nameof(ContentInfo.WritingUserName)}` VARCHAR(255), -`{nameof(ContentInfo.LastEditDate)}` DATETIME, -`{nameof(ContentInfo.Taxis)}` INT, -`{nameof(ContentInfo.GroupNameCollection)}` VARCHAR(255), -`{nameof(ContentInfo.Tags)}` VARCHAR(255), -`{nameof(ContentInfo.SourceId)}` INT, -`{nameof(ContentInfo.ReferenceId)}` INT, -`{nameof(ContentInfo.IsChecked)}` VARCHAR(18), -`{nameof(ContentInfo.CheckedLevel)}` INT, -`{nameof(ContentInfo.Hits)}` INT, -`{nameof(ContentInfo.HitsByDay)}` INT, -`{nameof(ContentInfo.HitsByWeek)}` INT, -`{nameof(ContentInfo.HitsByMonth)}` INT, -`{nameof(ContentInfo.LastHitsDate)}` DATETIME, -`{nameof(ContentInfo.SettingsXml)}` LONGTEXT, -`{nameof(ContentInfo.Title)}` VARCHAR(255), -`{nameof(ContentInfo.IsTop)}` VARCHAR(18), -`{nameof(ContentInfo.IsRecommend)}` VARCHAR(18), -`{nameof(ContentInfo.IsHot)}` VARCHAR(18), -`{nameof(ContentInfo.IsColor)}` VARCHAR(18), -`{nameof(ContentInfo.LinkUrl)}` VARCHAR(200), -`{nameof(ContentInfo.AddDate)}` DATETIME, -"); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - sqlBuilder.Append($@"CREATE TABLE {tableName} ("); - sqlBuilder.Append($@" -{nameof(ContentInfo.Id)} int IDENTITY (1, 1), -{nameof(ContentInfo.ChannelId)} int NULL, -{nameof(ContentInfo.SiteId)} int NULL, -{nameof(ContentInfo.AddUserName)} nvarchar (255) NULL, -{nameof(ContentInfo.LastEditUserName)} nvarchar (255) NULL, -{nameof(ContentInfo.WritingUserName)} nvarchar (255) NULL, -{nameof(ContentInfo.LastEditDate)} datetime NULL, -{nameof(ContentInfo.Taxis)} int NULL, -{nameof(ContentInfo.GroupNameCollection)} nvarchar (255) NULL, -{nameof(ContentInfo.Tags)} nvarchar (255) NULL, -{nameof(ContentInfo.SourceId)} int NULL, -{nameof(ContentInfo.ReferenceId)} int NULL, -{nameof(ContentInfo.IsChecked)} nvarchar (18) NULL, -{nameof(ContentInfo.CheckedLevel)} int NULL, -{nameof(ContentInfo.Hits)} int NULL, -{nameof(ContentInfo.HitsByDay)} int NULL, -{nameof(ContentInfo.HitsByWeek)} int NULL, -{nameof(ContentInfo.HitsByMonth)} int NULL, -{nameof(ContentInfo.LastHitsDate)} datetime NULL, -{nameof(ContentInfo.SettingsXml)} ntext NULL, -{nameof(ContentInfo.Title)} nvarchar (255) NULL, -{nameof(ContentInfo.IsTop)} nvarchar (18) NULL, -{nameof(ContentInfo.IsRecommend)} nvarchar (18) NULL, -{nameof(ContentInfo.IsHot)} nvarchar (18) NULL, -{nameof(ContentInfo.IsColor)} nvarchar (18) NULL, -{nameof(ContentInfo.LinkUrl)} nvarchar (200) NULL, -{nameof(ContentInfo.AddDate)} datetime NULL, -"); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - sqlBuilder.Append($@"CREATE TABLE {tableName} ("); - sqlBuilder.Append($@" -{nameof(ContentInfo.Id)} SERIAL, -{nameof(ContentInfo.ChannelId)} int4 NULL, -{nameof(ContentInfo.SiteId)} int4 NULL, -{nameof(ContentInfo.AddUserName)} varchar (255) NULL, -{nameof(ContentInfo.LastEditUserName)} varchar (255) NULL, -{nameof(ContentInfo.WritingUserName)} varchar (255) NULL, -{nameof(ContentInfo.LastEditDate)} timestamptz NULL, -{nameof(ContentInfo.Taxis)} int4 NULL, -{nameof(ContentInfo.GroupNameCollection)} varchar (255) NULL, -{nameof(ContentInfo.Tags)} varchar (255) NULL, -{nameof(ContentInfo.SourceId)} int4 NULL, -{nameof(ContentInfo.ReferenceId)} int4 NULL, -{nameof(ContentInfo.IsChecked)} varchar (18) NULL, -{nameof(ContentInfo.CheckedLevel)} int4 NULL, -{nameof(ContentInfo.Hits)} int4 NULL, -{nameof(ContentInfo.HitsByDay)} int4 NULL, -{nameof(ContentInfo.HitsByWeek)} int4 NULL, -{nameof(ContentInfo.HitsByMonth)} int4 NULL, -{nameof(ContentInfo.LastHitsDate)} timestamptz NULL, -{nameof(ContentInfo.SettingsXml)} text NULL, -{nameof(ContentInfo.Title)} varchar (255) NULL, -{nameof(ContentInfo.IsTop)} varchar (18) NULL, -{nameof(ContentInfo.IsRecommend)} varchar (18) NULL, -{nameof(ContentInfo.IsHot)} varchar (18) NULL, -{nameof(ContentInfo.IsColor)} varchar (18) NULL, -{nameof(ContentInfo.LinkUrl)} varchar (200) NULL, -{nameof(ContentInfo.AddDate)} timestamptz NULL, -"); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - sqlBuilder.Append($@"CREATE TABLE {tableName} ("); - sqlBuilder.Append($@" -{nameof(ContentInfo.Id)} NUMBER GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1), -{nameof(ContentInfo.ChannelId)} number NULL, -{nameof(ContentInfo.SiteId)} number NULL, -{nameof(ContentInfo.AddUserName)} nvarchar2(255) NULL, -{nameof(ContentInfo.LastEditUserName)} nvarchar2(255) NULL, -{nameof(ContentInfo.WritingUserName)} nvarchar2(255) NULL, -{nameof(ContentInfo.LastEditDate)} timestamp(6) with time zone NULL, -{nameof(ContentInfo.Taxis)} number NULL, -{nameof(ContentInfo.GroupNameCollection)} nvarchar2(255) NULL, -{nameof(ContentInfo.Tags)} nvarchar2(255) NULL, -{nameof(ContentInfo.SourceId)} number NULL, -{nameof(ContentInfo.ReferenceId)} number NULL, -{nameof(ContentInfo.IsChecked)} nvarchar2(18) NULL, -{nameof(ContentInfo.CheckedLevel)} number NULL, -{nameof(ContentInfo.Hits)} number NULL, -{nameof(ContentInfo.HitsByDay)} number NULL, -{nameof(ContentInfo.HitsByWeek)} number NULL, -{nameof(ContentInfo.HitsByMonth)} number NULL, -{nameof(ContentInfo.LastHitsDate)} timestamp(6) with time zone NULL, -{nameof(ContentInfo.SettingsXml)} nclob NULL, -{nameof(ContentInfo.Title)} nvarchar2(255) NULL, -{nameof(ContentInfo.IsTop)} nvarchar2(18) NULL, -{nameof(ContentInfo.IsRecommend)} nvarchar2(18) NULL, -{nameof(ContentInfo.IsHot)} nvarchar2(18) NULL, -{nameof(ContentInfo.IsColor)} nvarchar2(18) NULL, -{nameof(ContentInfo.LinkUrl)} nvarchar2(200) NULL, -{nameof(ContentInfo.AddDate)} timestamp(6) with time zone NULL, -"); - } - - //添加后台定义字段 - foreach (var sqlString in columnSqlStringList) - { - sqlBuilder.Append(sqlString).Append(@","); - } - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - sqlBuilder.Append($@" -PRIMARY KEY ({nameof(ContentInfo.Id)}) -) -GO -CREATE INDEX `IX_{tableName}` ON `{tableName}`(`{nameof(ContentInfo.IsTop)}` DESC, `{nameof(ContentInfo.Taxis)}` DESC, `{nameof(ContentInfo.Id)}` DESC) -GO -CREATE INDEX `IX_{tableName}_Taxis` ON `{tableName}`(`{nameof(ContentInfo.Taxis)}` DESC) -GO"); - } - else - { - sqlBuilder.Append($@" -CONSTRAINT PK_{tableName} PRIMARY KEY ({nameof(ContentInfo.Id)}) -) -GO -CREATE INDEX IX_{tableName} ON {tableName}({nameof(ContentInfo.IsTop)} DESC, {nameof(ContentInfo.Taxis)} DESC, {nameof(ContentInfo.Id)} DESC) -GO -CREATE INDEX IX_{tableName}_Taxis ON {tableName}({nameof(ContentInfo.Taxis)} DESC) -GO"); - } - - return sqlBuilder.ToString(); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - public void SetValue(string tableName, int contentId, string name, string value) - { - string sqlString = $"UPDATE {tableName} SET {name} = '{value}' WHERE Id = {contentId}"; - - ExecuteNonQuery(sqlString); - - Content.ClearCache(); - } - - public void UpdateIsChecked(string tableName, int siteId, int channelId, List contentIdList, int translateChannelId, bool isAdmin, string userName, bool isChecked, int checkedLevel, string reasons) - { - if (isChecked) - { - checkedLevel = 0; - } - - var checkDate = DateTime.Now; - - foreach (var contentId in contentIdList) - { - var settingsXml = GetValue(tableName, contentId, ContentAttribute.SettingsXml); - var attributes = TranslateUtils.ToNameValueCollection(settingsXml); - attributes[ContentAttribute.CheckIsAdmin] = isAdmin.ToString(); - attributes[ContentAttribute.CheckUserName] = userName; - attributes[ContentAttribute.CheckCheckDate] = DateUtils.GetDateAndTimeString(checkDate); - attributes[ContentAttribute.CheckReasons] = reasons; - - string sqlString = - $"UPDATE {tableName} SET IsChecked = '{isChecked}', CheckedLevel = {checkedLevel}, SettingsXML = '{TranslateUtils.NameValueCollectionToString(attributes)}' WHERE Id = {contentId}"; - if (translateChannelId > 0) - { - sqlString = - $"UPDATE {tableName} SET IsChecked = '{isChecked}', CheckedLevel = {checkedLevel}, SettingsXML = '{TranslateUtils.NameValueCollectionToString(attributes)}', ChannelId = {translateChannelId} WHERE Id = {contentId}"; - } - ExecuteNonQuery(sqlString); - - var checkInfo = new ContentCheckInfo(0, tableName, siteId, channelId, contentId, isAdmin, userName, isChecked, checkedLevel, checkDate, reasons); - DataProvider.ContentCheckDao.Insert(checkInfo); - } - - Content.ClearCache(); - } - - public void AddHits(string tableName, bool isCountHits, bool isCountHitsByDay, int contentId) - { - if (contentId <= 0 || !isCountHits) return; - - if (isCountHitsByDay) - { - var referenceId = 0; - var hitsByDay = 0; - var hitsByWeek = 0; - var hitsByMonth = 0; - var lastHitsDate = DateTime.Now; - - string sqlString = - $"SELECT ReferenceId, HitsByDay, HitsByWeek, HitsByMonth, LastHitsDate FROM {tableName} WHERE (Id = {contentId})"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - var i = 0; - referenceId = GetInt(rdr, i++); - hitsByDay = GetInt(rdr, i++); - hitsByWeek = GetInt(rdr, i++); - hitsByMonth = GetInt(rdr, i++); - lastHitsDate = GetDateTime(rdr, i); - } - rdr.Close(); - } - - if (referenceId > 0) - { - contentId = referenceId; - } - - var now = DateTime.Now; - - hitsByDay = now.Day != lastHitsDate.Day || now.Month != lastHitsDate.Month || now.Year != lastHitsDate.Year ? 1 : hitsByDay + 1; - hitsByWeek = now.Month != lastHitsDate.Month || now.Year != lastHitsDate.Year || now.DayOfYear / 7 != lastHitsDate.DayOfYear / 7 ? 1 : hitsByWeek + 1; - hitsByMonth = now.Month != lastHitsDate.Month || now.Year != lastHitsDate.Year ? 1 : hitsByMonth + 1; - - sqlString = - $"UPDATE {tableName} SET {SqlUtils.ToPlusSqlString("Hits")}, HitsByDay = {hitsByDay}, HitsByWeek = {hitsByWeek}, HitsByMonth = {hitsByMonth}, LastHitsDate = '{DateUtils.GetDateAndTimeString(DateTime.Now)}' WHERE Id = {contentId} AND ReferenceId = 0"; - ExecuteNonQuery(sqlString); - } - else - { - string sqlString = - $"UPDATE {tableName} SET {SqlUtils.ToPlusSqlString("Hits")}, LastHitsDate = '{DateUtils.GetDateAndTimeString(DateTime.Now)}' WHERE Id = {contentId} AND ReferenceId = 0"; - var count = ExecuteNonQuery(sqlString); - if (count < 1) - { - var referenceId = 0; - - sqlString = $"SELECT ReferenceId FROM {tableName} WHERE (Id = {contentId})"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - referenceId = GetInt(rdr, 0); - } - rdr.Close(); - } - - if (referenceId > 0) - { - sqlString = - $"UPDATE {tableName} SET {SqlUtils.ToPlusSqlString("Hits")}, LastHitsDate = '{DateUtils.GetDateAndTimeString(DateTime.Now)}' WHERE Id = {referenceId} AND ReferenceId = 0"; - ExecuteNonQuery(sqlString); - } - } - } - - Content.ClearCache(); - } - - public void UpdateComments(string tableName, int contentId, int comments) - { - string sqlString = $"UPDATE {tableName} SET Comments = {comments} WHERE Id = {contentId}"; - ExecuteNonQuery(sqlString); - - Content.ClearCache(); - } - - public void DeleteContentsByTrash(int siteId, string tableName) - { - if (string.IsNullOrEmpty(tableName)) return; - - var contentIdList = GetContentIdListByTrash(siteId, tableName); - TagUtils.RemoveTags(siteId, contentIdList); - - string sqlString = - $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND ChannelId < 0"; - ExecuteNonQuery(sqlString); - - Content.ClearCache(); - } - - private int Insert(string tableName, IContentInfo contentInfo) - { - //var contentId = 0; - - if (string.IsNullOrEmpty(tableName) || contentInfo == null) return 0; - - contentInfo.LastEditDate = DateTime.Now; - - var metadataInfoList = TableMetadataManager.GetTableMetadataInfoList(tableName); - - var names = new StringBuilder(); - var values = new StringBuilder(); - var paras = new List(); - var lowerCaseExcludeAttributesNames = new List(ContentAttribute.AllAttributesLowercase); - foreach (var metadataInfo in metadataInfoList) - { - lowerCaseExcludeAttributesNames.Add(metadataInfo.AttributeName.ToLower()); - names.Append($",{metadataInfo.AttributeName}").AppendLine(); - values.Append($",@{metadataInfo.AttributeName}").AppendLine(); - if (metadataInfo.DataType == DataType.Integer) - { - paras.Add(GetParameter($"@{metadataInfo.AttributeName}", metadataInfo.DataType, contentInfo.GetInt(metadataInfo.AttributeName))); - } - else if (metadataInfo.DataType == DataType.Decimal) - { - paras.Add(GetParameter($"@{metadataInfo.AttributeName}", metadataInfo.DataType, contentInfo.GetDecimal(metadataInfo.AttributeName))); - } - else if (metadataInfo.DataType == DataType.Boolean) - { - paras.Add(GetParameter($"@{metadataInfo.AttributeName}", metadataInfo.DataType, contentInfo.GetBool(metadataInfo.AttributeName))); - } - else if (metadataInfo.DataType == DataType.DateTime) - { - paras.Add(GetParameter($"@{metadataInfo.AttributeName}", metadataInfo.DataType, contentInfo.GetDateTime(metadataInfo.AttributeName, DateTime.Now))); - } - else - { - paras.Add(GetParameter($"@{metadataInfo.AttributeName}", metadataInfo.DataType, contentInfo.GetString(metadataInfo.AttributeName))); - } - } - - var sqlString = $@" -INSERT INTO {tableName} ( - {nameof(ContentInfo.ChannelId)}, - {nameof(ContentInfo.SiteId)}, - {nameof(ContentInfo.AddUserName)}, - {nameof(ContentInfo.LastEditUserName)}, - {nameof(ContentInfo.WritingUserName)}, - {nameof(ContentInfo.LastEditDate)}, - {nameof(ContentInfo.Taxis)}, - {nameof(ContentInfo.GroupNameCollection)}, - {nameof(ContentInfo.Tags)}, - {nameof(ContentInfo.SourceId)}, - {nameof(ContentInfo.ReferenceId)}, - {nameof(ContentInfo.IsChecked)}, - {nameof(ContentInfo.CheckedLevel)}, - {nameof(ContentInfo.Hits)}, - {nameof(ContentInfo.HitsByDay)}, - {nameof(ContentInfo.HitsByWeek)}, - {nameof(ContentInfo.HitsByMonth)}, - {nameof(ContentInfo.LastHitsDate)}, - {nameof(ContentInfo.SettingsXml)}, - {nameof(ContentInfo.Title)}, - {nameof(ContentInfo.IsTop)}, - {nameof(ContentInfo.IsRecommend)}, - {nameof(ContentInfo.IsHot)}, - {nameof(ContentInfo.IsColor)}, - {nameof(ContentInfo.LinkUrl)}, - {nameof(ContentInfo.AddDate)} - {names} -) VALUES ( - @{nameof(ContentInfo.ChannelId)}, - @{nameof(ContentInfo.SiteId)}, - @{nameof(ContentInfo.AddUserName)}, - @{nameof(ContentInfo.LastEditUserName)}, - @{nameof(ContentInfo.WritingUserName)}, - @{nameof(ContentInfo.LastEditDate)}, - @{nameof(ContentInfo.Taxis)}, - @{nameof(ContentInfo.GroupNameCollection)}, - @{nameof(ContentInfo.Tags)}, - @{nameof(ContentInfo.SourceId)}, - @{nameof(ContentInfo.ReferenceId)}, - @{nameof(ContentInfo.IsChecked)}, - @{nameof(ContentInfo.CheckedLevel)}, - @{nameof(ContentInfo.Hits)}, - @{nameof(ContentInfo.HitsByDay)}, - @{nameof(ContentInfo.HitsByWeek)}, - @{nameof(ContentInfo.HitsByMonth)}, - @{nameof(ContentInfo.LastHitsDate)}, - @{nameof(ContentInfo.SettingsXml)}, - @{nameof(ContentInfo.Title)}, - @{nameof(ContentInfo.IsTop)}, - @{nameof(ContentInfo.IsRecommend)}, - @{nameof(ContentInfo.IsHot)}, - @{nameof(ContentInfo.IsColor)}, - @{nameof(ContentInfo.LinkUrl)}, - @{nameof(ContentInfo.AddDate)} - {values} -)"; - - var parameters = new List - { - GetParameter($"@{nameof(ContentInfo.ChannelId)}", DataType.Integer, contentInfo.ChannelId), - GetParameter($"@{nameof(ContentInfo.SiteId)}", DataType.Integer, contentInfo.SiteId), - GetParameter($"@{nameof(ContentInfo.AddUserName)}", DataType.VarChar, 255, contentInfo.AddUserName), - GetParameter($"@{nameof(ContentInfo.LastEditUserName)}", DataType.VarChar, 255, contentInfo.LastEditUserName), - GetParameter($"@{nameof(ContentInfo.WritingUserName)}", DataType.VarChar, 255, contentInfo.WritingUserName), - GetParameter($"@{nameof(ContentInfo.LastEditDate)}", DataType.DateTime, contentInfo.LastEditDate), - GetParameter($"@{nameof(ContentInfo.Taxis)}", DataType.Integer, contentInfo.Taxis), - GetParameter($"@{nameof(ContentInfo.GroupNameCollection)}", DataType.VarChar, 255, contentInfo.GroupNameCollection), - GetParameter($"@{nameof(ContentInfo.Tags)}", DataType.VarChar, 255, contentInfo.Tags), - GetParameter($"@{nameof(ContentInfo.SourceId)}", DataType.Integer, contentInfo.SourceId), - GetParameter($"@{nameof(ContentInfo.ReferenceId)}", DataType.Integer, contentInfo.ReferenceId), - GetParameter($"@{nameof(ContentInfo.IsChecked)}", DataType.VarChar, 18, contentInfo.IsChecked.ToString()), - GetParameter($"@{nameof(ContentInfo.CheckedLevel)}", DataType.Integer, contentInfo.CheckedLevel), - GetParameter($"@{nameof(ContentInfo.Hits)}", DataType.Integer, contentInfo.Hits), - GetParameter($"@{nameof(ContentInfo.HitsByDay)}", DataType.Integer, contentInfo.HitsByDay), - GetParameter($"@{nameof(ContentInfo.HitsByWeek)}", DataType.Integer, contentInfo.HitsByWeek), - GetParameter($"@{nameof(ContentInfo.HitsByMonth)}", DataType.Integer, contentInfo.HitsByMonth), - GetParameter($"@{nameof(ContentInfo.LastHitsDate)}", DataType.DateTime, contentInfo.LastHitsDate), - GetParameter($"@{nameof(ContentInfo.SettingsXml)}", DataType.Text, contentInfo.ToString(lowerCaseExcludeAttributesNames)), - GetParameter($"@{nameof(ContentInfo.Title)}", DataType.VarChar, 255, contentInfo.Title), - GetParameter($"@{nameof(ContentInfo.IsTop)}", DataType.VarChar, 18, contentInfo.IsTop.ToString()), - GetParameter($"@{nameof(ContentInfo.IsRecommend)}", DataType.VarChar, 18, contentInfo.IsRecommend.ToString()), - GetParameter($"@{nameof(ContentInfo.IsHot)}", DataType.VarChar, 18, contentInfo.IsHot.ToString()), - GetParameter($"@{nameof(ContentInfo.IsColor)}", DataType.VarChar, 18, contentInfo.IsColor.ToString()), - GetParameter($"@{nameof(ContentInfo.LinkUrl)}", DataType.VarChar, 200, contentInfo.LinkUrl), - GetParameter($"@{nameof(ContentInfo.AddDate)}", DataType.DateTime, contentInfo.AddDate) - }; - parameters.AddRange(paras); - - //IDataParameter[] parms; - //var sqlInsert = DataProvider.DatabaseDao.GetInsertSqlString(contentInfo.Attributes.GetExtendedAttributes(), tableName, out parms); - - var contentId = ExecuteNonQueryAndReturnId(tableName, nameof(ContentInfo.Id), sqlString, parameters.ToArray()); - - Content.ClearCache(); - - return contentId; - - //using (var conn = GetConnection()) - //{ - // conn.Open(); - // using (var trans = conn.BeginTransaction()) - // { - // try - // { - // //contentId = ExecuteNonQueryAndReturnId(trans, sqlInsert, parms); - // contentId = ExecuteNonQueryAndReturningId(trans, sqlString, nameof(ContentInfo.Id), parameters.ToArray()); - - // trans.Commit(); - // } - // catch - // { - // trans.Rollback(); - // throw; - // } - // } - //} - - //return contentId; - } - - private void Update(string tableName, IContentInfo contentInfo) - { - if (string.IsNullOrEmpty(tableName) || contentInfo == null) return; - - //出现IsTop与Taxis不同步情况 - if (contentInfo.IsTop == false && contentInfo.Taxis >= TaxisIsTopStartValue) - { - contentInfo.Taxis = GetMaxTaxis(tableName, contentInfo.ChannelId, false) + 1; - } - else if (contentInfo.IsTop && contentInfo.Taxis < TaxisIsTopStartValue) - { - contentInfo.Taxis = GetMaxTaxis(tableName, contentInfo.ChannelId, true) + 1; - } - - contentInfo.LastEditDate = DateTime.Now; - - //if (!string.IsNullOrEmpty(tableName)) - //{ - // contentInfo.Attributes.BeforeExecuteNonQuery(); - // sqlString = DataProvider.DatabaseDao.GetUpdateSqlString(contentInfo.Attributes.GetExtendedAttributes(), tableName, out parms); - //} - - var metadataInfoList = TableMetadataManager.GetTableMetadataInfoList(tableName); - - var sets = new StringBuilder(); - var paras = new List(); - var lowerCaseExcludeAttributesNames = new List(ContentAttribute.AllAttributesLowercase); - foreach (var metadataInfo in metadataInfoList) - { - lowerCaseExcludeAttributesNames.Add(metadataInfo.AttributeName.ToLower()); - sets.Append($",{metadataInfo.AttributeName} = @{metadataInfo.AttributeName}").AppendLine(); - if (metadataInfo.DataType == DataType.Integer) - { - paras.Add(GetParameter($"@{metadataInfo.AttributeName}", metadataInfo.DataType, contentInfo.GetInt(metadataInfo.AttributeName))); - } - else if (metadataInfo.DataType == DataType.Decimal) - { - paras.Add(GetParameter($"@{metadataInfo.AttributeName}", metadataInfo.DataType, contentInfo.GetDecimal(metadataInfo.AttributeName))); - } - else if (metadataInfo.DataType == DataType.Boolean) - { - paras.Add(GetParameter($"@{metadataInfo.AttributeName}", metadataInfo.DataType, contentInfo.GetBool(metadataInfo.AttributeName))); - } - else if (metadataInfo.DataType == DataType.DateTime) - { - paras.Add(GetParameter($"@{metadataInfo.AttributeName}", metadataInfo.DataType, contentInfo.GetDateTime(metadataInfo.AttributeName, DateTime.Now))); - } - else - { - paras.Add(GetParameter($"@{metadataInfo.AttributeName}", metadataInfo.DataType, contentInfo.GetString(metadataInfo.AttributeName))); - } - } - - var sqlString = $@" -UPDATE {tableName} SET - {nameof(ContentInfo.ChannelId)} = @{nameof(ContentInfo.ChannelId)}, - {nameof(ContentInfo.SiteId)} = @{nameof(ContentInfo.SiteId)}, - {nameof(ContentInfo.AddUserName)} = @{nameof(ContentInfo.AddUserName)}, - {nameof(ContentInfo.LastEditUserName)} = @{nameof(ContentInfo.LastEditUserName)}, - {nameof(ContentInfo.WritingUserName)} = @{nameof(ContentInfo.WritingUserName)}, - {nameof(ContentInfo.LastEditDate)} = @{nameof(ContentInfo.LastEditDate)}, - {nameof(ContentInfo.Taxis)} = @{nameof(ContentInfo.Taxis)}, - {nameof(ContentInfo.GroupNameCollection)} = @{nameof(ContentInfo.GroupNameCollection)}, - {nameof(ContentInfo.Tags)} = @{nameof(ContentInfo.Tags)}, - {nameof(ContentInfo.SourceId)} = @{nameof(ContentInfo.SourceId)}, - {nameof(ContentInfo.ReferenceId)} = @{nameof(ContentInfo.ReferenceId)}, - {nameof(ContentInfo.IsChecked)} = @{nameof(ContentInfo.IsChecked)}, - {nameof(ContentInfo.CheckedLevel)} = @{nameof(ContentInfo.CheckedLevel)}, - {nameof(ContentInfo.Hits)} = @{nameof(ContentInfo.Hits)}, - {nameof(ContentInfo.HitsByDay)} = @{nameof(ContentInfo.HitsByDay)}, - {nameof(ContentInfo.HitsByWeek)} = @{nameof(ContentInfo.HitsByWeek)}, - {nameof(ContentInfo.HitsByMonth)} = @{nameof(ContentInfo.HitsByMonth)}, - {nameof(ContentInfo.LastHitsDate)} = @{nameof(ContentInfo.LastHitsDate)}, - {nameof(ContentInfo.SettingsXml)} = @{nameof(ContentInfo.SettingsXml)}, - {nameof(ContentInfo.Title)} = @{nameof(ContentInfo.Title)}, - {nameof(ContentInfo.IsTop)} = @{nameof(ContentInfo.IsTop)}, - {nameof(ContentInfo.IsRecommend)} = @{nameof(ContentInfo.IsRecommend)}, - {nameof(ContentInfo.IsHot)} = @{nameof(ContentInfo.IsHot)}, - {nameof(ContentInfo.IsColor)} = @{nameof(ContentInfo.IsColor)}, - {nameof(ContentInfo.LinkUrl)} = @{nameof(ContentInfo.LinkUrl)}, - {nameof(ContentInfo.AddDate)} = @{nameof(ContentInfo.AddDate)} - {sets} -WHERE {nameof(ContentInfo.Id)} = @{nameof(ContentInfo.Id)}"; - - var parameters = new List - { - GetParameter($"@{nameof(ContentInfo.ChannelId)}", DataType.Integer, contentInfo.ChannelId), - GetParameter($"@{nameof(ContentInfo.SiteId)}", DataType.Integer, contentInfo.SiteId), - GetParameter($"@{nameof(ContentInfo.AddUserName)}", DataType.VarChar, 255, contentInfo.AddUserName), - GetParameter($"@{nameof(ContentInfo.LastEditUserName)}", DataType.VarChar, 255, contentInfo.LastEditUserName), - GetParameter($"@{nameof(ContentInfo.WritingUserName)}", DataType.VarChar, 255, contentInfo.WritingUserName), - GetParameter($"@{nameof(ContentInfo.LastEditDate)}", DataType.DateTime, contentInfo.LastEditDate), - GetParameter($"@{nameof(ContentInfo.Taxis)}", DataType.Integer, contentInfo.Taxis), - GetParameter($"@{nameof(ContentInfo.GroupNameCollection)}", DataType.VarChar, 255, contentInfo.GroupNameCollection), - GetParameter($"@{nameof(ContentInfo.Tags)}", DataType.VarChar, 255, contentInfo.Tags), - GetParameter($"@{nameof(ContentInfo.SourceId)}", DataType.Integer, contentInfo.SourceId), - GetParameter($"@{nameof(ContentInfo.ReferenceId)}", DataType.Integer, contentInfo.ReferenceId), - GetParameter($"@{nameof(ContentInfo.IsChecked)}", DataType.VarChar, 18, contentInfo.IsChecked.ToString()), - GetParameter($"@{nameof(ContentInfo.CheckedLevel)}", DataType.Integer, contentInfo.CheckedLevel), - GetParameter($"@{nameof(ContentInfo.Hits)}", DataType.Integer, contentInfo.Hits), - GetParameter($"@{nameof(ContentInfo.HitsByDay)}", DataType.Integer, contentInfo.HitsByDay), - GetParameter($"@{nameof(ContentInfo.HitsByWeek)}", DataType.Integer, contentInfo.HitsByWeek), - GetParameter($"@{nameof(ContentInfo.HitsByMonth)}", DataType.Integer, contentInfo.HitsByMonth), - GetParameter($"@{nameof(ContentInfo.LastHitsDate)}", DataType.DateTime, contentInfo.LastHitsDate), - GetParameter($"@{nameof(ContentInfo.SettingsXml)}", DataType.Text, contentInfo.ToString(lowerCaseExcludeAttributesNames)), - GetParameter($"@{nameof(ContentInfo.Title)}", DataType.VarChar, 255, contentInfo.Title), - GetParameter($"@{nameof(ContentInfo.IsTop)}", DataType.VarChar, 18, contentInfo.IsTop.ToString()), - GetParameter($"@{nameof(ContentInfo.IsRecommend)}", DataType.VarChar, 18, contentInfo.IsRecommend.ToString()), - GetParameter($"@{nameof(ContentInfo.IsHot)}", DataType.VarChar, 18, contentInfo.IsHot.ToString()), - GetParameter($"@{nameof(ContentInfo.IsColor)}", DataType.VarChar, 18, contentInfo.IsColor.ToString()), - GetParameter($"@{nameof(ContentInfo.LinkUrl)}", DataType.VarChar, 200, contentInfo.LinkUrl), - GetParameter($"@{nameof(ContentInfo.AddDate)}", DataType.DateTime, contentInfo.AddDate) - }; - parameters.AddRange(paras); - parameters.Add(GetParameter($"@{nameof(ContentInfo.Id)}", DataType.Integer, contentInfo.Id)); - - ExecuteNonQuery(sqlString, parameters.ToArray()); - - Content.ClearCache(); - } - - public void UpdateAutoPageContent(string tableName, SiteInfo siteInfo) - { - if (!siteInfo.Additional.IsAutoPageInTextEditor) return; - - string sqlString = - $"SELECT Id, {BackgroundContentAttribute.Content} FROM {tableName} WHERE (SiteId = {siteInfo.Id})"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var contentId = GetInt(rdr, 0); - var content = GetString(rdr, 1); - if (!string.IsNullOrEmpty(content)) - { - content = ContentUtility.GetAutoPageContent(content, siteInfo.Additional.AutoPageWordNum); - string updateString = - $"UPDATE {tableName} SET {BackgroundContentAttribute.Content} = '{content}' WHERE Id = {contentId}"; - try - { - ExecuteNonQuery(updateString); - } - catch - { - // ignored - } - } - } - - rdr.Close(); - } - - Content.ClearCache(); - } - - public void TrashContents(int siteId, string tableName, List contentIdList, int channelId) - { - if (string.IsNullOrEmpty(tableName)) return; - - var referenceIdList = GetReferenceIdList(tableName, contentIdList); - if (referenceIdList.Count > 0) - { - DeleteContents(siteId, tableName, referenceIdList); - } - var updateNum = 0; - - if (!string.IsNullOrEmpty(tableName) && contentIdList != null && contentIdList.Count > 0) - { - string sqlString = - $"UPDATE {tableName} SET ChannelId = -ChannelId, LastEditDate = {SqlUtils.GetComparableNow()} WHERE SiteId = {siteId} AND Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; - updateNum = ExecuteNonQuery(sqlString); - } - - if (updateNum <= 0) return; - - new Action(() => - { - DataProvider.ChannelDao.UpdateContentNum(SiteManager.GetSiteInfo(siteId), channelId, true); - }).BeginInvoke(null, null); - - Content.ClearCache(); - } - - public void TrashContents(int siteId, string tableName, List contentIdList) - { - if (string.IsNullOrEmpty(tableName)) return; - - var referenceIdList = GetReferenceIdList(tableName, contentIdList); - if (referenceIdList.Count > 0) - { - DeleteContents(siteId, tableName, referenceIdList); - } - - var updateNum = 0; - - if (!string.IsNullOrEmpty(tableName) && contentIdList != null && contentIdList.Count > 0) - { - string sqlString = - $"UPDATE {tableName} SET ChannelId = -ChannelId, LastEditDate = {SqlUtils.GetComparableNow()} WHERE SiteId = {siteId} AND Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; - updateNum = ExecuteNonQuery(sqlString); - } - - if (updateNum <= 0) return; - - new Action(() => - { - DataProvider.ChannelDao.UpdateContentNum(SiteManager.GetSiteInfo(siteId)); - }).BeginInvoke(null, null); - - Content.ClearCache(); - } - - public void TrashContentsByChannelId(int siteId, string tableName, int channelId) - { - if (string.IsNullOrEmpty(tableName)) return; - - var contentIdList = GetContentIdList(tableName, channelId); - var referenceIdList = GetReferenceIdList(tableName, contentIdList); - if (referenceIdList.Count > 0) - { - DeleteContents(siteId, tableName, referenceIdList); - } - var updateNum = 0; - - if (!string.IsNullOrEmpty(tableName)) - { - string sqlString = - $"UPDATE {tableName} SET ChannelId = -ChannelId, LastEditDate = {SqlUtils.GetComparableNow()} WHERE SiteId = {siteId} AND ChannelId = {siteId}"; - updateNum = ExecuteNonQuery(sqlString); - } - - if (updateNum <= 0) return; - - new Action(() => - { - DataProvider.ChannelDao.UpdateContentNum(SiteManager.GetSiteInfo(siteId), channelId, true); - }).BeginInvoke(null, null); - - Content.ClearCache(); - } - - public void DeleteContents(int siteId, string tableName, List contentIdList, int channelId) - { - if (string.IsNullOrEmpty(tableName)) return; - - var deleteNum = 0; - - if (!string.IsNullOrEmpty(tableName) && contentIdList != null && contentIdList.Count > 0) - { - TagUtils.RemoveTags(siteId, contentIdList); - - string sqlString = - $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; - deleteNum = ExecuteNonQuery(sqlString); - } - - if (channelId <= 0 || deleteNum <= 0) return; - - new Action(() => - { - DataProvider.ChannelDao.UpdateContentNum(SiteManager.GetSiteInfo(siteId), channelId, true); - }).BeginInvoke(null, null); - - Content.ClearCache(); - } - - public void DeleteContentsByChannelId(int siteId, string tableName, int channelId) - { - if (string.IsNullOrEmpty(tableName)) return; - - var contentIdList = GetContentIdListChecked(tableName, channelId, string.Empty); - - TagUtils.RemoveTags(siteId, contentIdList); - - string sqlString = - $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelId}"; - var deleteNum = ExecuteNonQuery(sqlString); - - if (channelId <= 0 || deleteNum <= 0) return; - - new Action(() => - { - DataProvider.ChannelDao.UpdateContentNum(SiteManager.GetSiteInfo(siteId), channelId, true); - }).BeginInvoke(null, null); - - Content.ClearCache(); - } - - public void DeleteContentsByDeletedChannelIdList(IDbTransaction trans, SiteInfo siteInfo, List channelIdList) - { - foreach (var channelId in channelIdList) - { - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - if (!string.IsNullOrEmpty(tableName)) - { - ExecuteNonQuery(trans, $"DELETE FROM {tableName} WHERE SiteId = {siteInfo.Id} AND {nameof(ContentInfo.ChannelId)} = {channelId}"); - } - } - - Content.ClearCache(); - } - - public string GetCountSqlString(string tableName, int channelId) - { - return $"SELECT COUNT(*) AS ContentNum FROM {tableName} WHERE {ContentAttribute.ChannelId} = {channelId}"; - } - - public void RestoreContentsByTrash(int siteId, string tableName) - { - var updateNum = 0; - - if (!string.IsNullOrEmpty(tableName)) - { - string sqlString = - $"UPDATE {tableName} SET ChannelId = -ChannelId, LastEditDate = {SqlUtils.GetComparableNow()} WHERE SiteId = {siteId} AND ChannelId < 0"; - updateNum = ExecuteNonQuery(sqlString); - } - - if (updateNum <= 0) return; - - new Action(() => - { - DataProvider.ChannelDao.UpdateContentNum(SiteManager.GetSiteInfo(siteId)); - }).BeginInvoke(null, null); - - Content.ClearCache(); - } - - private void SetTaxis(int id, int taxis, string tableName) - { - string sqlString = $"UPDATE {tableName} SET Taxis = {taxis} WHERE Id = {id}"; - ExecuteNonQuery(sqlString); - - Content.ClearCache(); - } - - private void DeleteContents(int siteId, string tableName, List contentIdList) - { - if (string.IsNullOrEmpty(tableName)) return; - - var deleteNum = 0; - - if (!string.IsNullOrEmpty(tableName) && contentIdList != null && contentIdList.Count > 0) - { - TagUtils.RemoveTags(siteId, contentIdList); - - string sqlString = - $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; - deleteNum = ExecuteNonQuery(sqlString); - } - - if (deleteNum <= 0) return; - - new Action(() => - { - DataProvider.ChannelDao.UpdateContentNum(SiteManager.GetSiteInfo(siteId)); - }).BeginInvoke(null, null); - - Content.ClearCache(); - } - - public void DeletePreviewContents(int siteId, string tableName, ChannelInfo channelInfo) - { - if (!string.IsNullOrEmpty(tableName)) - { - channelInfo.Additional.IsPreviewContents = false; - DataProvider.ChannelDao.UpdateAdditional(channelInfo); - - string sqlString = - $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelInfo.Id} AND SourceId = {SourceManager.Preview}"; - DataProvider.DatabaseDao.ExecuteSql(sqlString); - } - } - - public void TidyUp(string tableName, int channelId, string attributeName, bool isDesc) - { - var taxisDirection = isDesc ? "ASC" : "DESC";//升序,但由于页面排序是按Taxis的Desc排序的,所以这里sql里面的ASC/DESC取反 - - string sqlString = - $"SELECT Id, IsTop FROM {tableName} WHERE ChannelId = {channelId} OR ChannelId = -{channelId} ORDER BY {attributeName} {taxisDirection}"; - var sqlList = new List(); - - using (var rdr = ExecuteReader(sqlString)) - { - var taxis = 1; - while (rdr.Read()) - { - var id = GetInt(rdr, 0); - var isTop = GetBool(rdr, 1); - - sqlList.Add( - $"UPDATE {tableName} SET Taxis = {taxis++}, IsTop = '{isTop}' WHERE Id = {id}"); - } - rdr.Close(); - } - - DataProvider.DatabaseDao.ExecuteSql(sqlList); - - Content.ClearCache(); - } - - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - - public bool UpdateTaxisToUp(string tableName, int channelId, int contentId, bool isTop) - { - //Get Higher Taxis and Id - var sqlString = SqlUtils.ToTopSqlString(tableName, "Id, Taxis", - isTop - ? $"WHERE (Taxis > (SELECT Taxis FROM {tableName} WHERE Id = {contentId}) AND Taxis >= {TaxisIsTopStartValue} AND ChannelId = {channelId})" - : $"WHERE (Taxis > (SELECT Taxis FROM {tableName} WHERE Id = {contentId}) AND Taxis < {TaxisIsTopStartValue} AND ChannelId = {channelId})", - "ORDER BY Taxis", 1); - var higherId = 0; - var higherTaxis = 0; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - higherId = GetInt(rdr, 0); - higherTaxis = GetInt(rdr, 1); - } - rdr.Close(); - } - - if (higherId != 0) - { - //Get Taxis Of Selected Id - var selectedTaxis = GetTaxis(contentId, tableName); - - //Set The Selected Class Taxis To Higher Level - SetTaxis(contentId, higherTaxis, tableName); - //Set The Higher Class Taxis To Lower Level - SetTaxis(higherId, selectedTaxis, tableName); - return true; - } - return false; - } - - public bool UpdateTaxisToDown(string tableName, int channelId, int contentId, bool isTop) - { - //Get Lower Taxis and Id - var sqlString = SqlUtils.ToTopSqlString(tableName, "Id, Taxis", - isTop - ? $"WHERE (Taxis < (SELECT Taxis FROM {tableName} WHERE Id = {contentId}) AND Taxis >= {TaxisIsTopStartValue} AND ChannelId = {channelId})" - : $"WHERE (Taxis < (SELECT Taxis FROM {tableName} WHERE Id = {contentId}) AND Taxis < {TaxisIsTopStartValue} AND ChannelId = {channelId})", - "ORDER BY Taxis DESC", 1); - var lowerId = 0; - var lowerTaxis = 0; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - lowerId = GetInt(rdr, 0); - lowerTaxis = GetInt(rdr, 1); - } - rdr.Close(); - } - - if (lowerId != 0) - { - //Get Taxis Of Selected Class - var selectedTaxis = GetTaxis(contentId, tableName); - - //Set The Selected Class Taxis To Lower Level - SetTaxis(contentId, lowerTaxis, tableName); - //Set The Lower Class Taxis To Higher Level - SetTaxis(lowerId, selectedTaxis, tableName); - return true; - } - return false; - } - - public int GetMaxTaxis(string tableName, int channelId, bool isTop) - { - var maxTaxis = 0; - if (isTop) - { - maxTaxis = TaxisIsTopStartValue; - - string sqlString = - $"SELECT MAX(Taxis) FROM {tableName} WHERE ChannelId = {channelId} AND Taxis >= {TaxisIsTopStartValue}"; - - using (var conn = GetConnection()) - { - conn.Open(); - using (var rdr = ExecuteReader(conn, sqlString)) - { - if (rdr.Read()) - { - maxTaxis = GetInt(rdr, 0); - } - rdr.Close(); - } - } - if (maxTaxis == TaxisMaxValue) - { - maxTaxis = TaxisMaxValue - 1; - } - } - else - { - string sqlString = - $"SELECT MAX(Taxis) FROM {tableName} WHERE ChannelId = {channelId} AND Taxis < {TaxisIsTopStartValue}"; - using (var conn = GetConnection()) - { - conn.Open(); - using (var rdr = ExecuteReader(conn, sqlString)) - { - if (rdr.Read()) - { - maxTaxis = GetInt(rdr, 0); - } - rdr.Close(); - } - } - } - return maxTaxis; - } - - public string GetValue(string tableName, int contentId, string name) - { - string sqlString = $"SELECT {name} FROM {tableName} WHERE (Id = {contentId})"; - return DataProvider.DatabaseDao.GetString(sqlString); - } - - public void AddContentGroupList(string tableName, int contentId, List contentGroupList) - { - var list = TranslateUtils.StringCollectionToStringList(GetValue(tableName, contentId, ContentAttribute.GroupNameCollection)); - foreach (var groupName in contentGroupList) - { - if (!list.Contains(groupName)) list.Add(groupName); - } - SetValue(tableName, contentId, ContentAttribute.GroupNameCollection, TranslateUtils.ObjectCollectionToString(list)); - } - - public int GetReferenceId(string tableName, int contentId, out string linkUrl) - { - var referenceId = 0; - linkUrl = string.Empty; - try - { - string sqlString = $"SELECT ReferenceId, LinkUrl FROM {tableName} WHERE Id = {contentId}"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - referenceId = GetInt(rdr, 0); - linkUrl = GetString(rdr, 1); - } - rdr.Close(); - } - } - catch - { - // ignored - } - return referenceId; - } - - public List GetReferenceIdList(string tableName, List contentIdList) - { - var list = new List(); - string sqlString = - $"SELECT Id FROM {tableName} WHERE ChannelId > 0 AND ReferenceId IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetInt(rdr, 0)); - } - rdr.Close(); - } - - return list; - } - - public string GetSqlString(string tableName, int channelId, ETriState checkedState, string userNameOnly) - { - var orderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByTaxisDesc); - - var whereString = new StringBuilder(); - whereString.Append($"WHERE {nameof(ContentAttribute.ChannelId)} = {channelId} AND {nameof(ContentAttribute.SourceId)} != {SourceManager.Preview} "); - - if (checkedState == ETriState.True) - { - whereString.Append($"AND IsChecked='{true}' "); - } - else if (checkedState == ETriState.False) - { - whereString.Append($"AND IsChecked='{false}'"); - } - - if (!string.IsNullOrEmpty(userNameOnly)) - { - whereString.Append($" AND AddUserName = '{userNameOnly}' "); - } - - return DataProvider.DatabaseDao.GetSelectSqlString(tableName, SqlUtils.Asterisk, whereString.ToString(), orderByString); - } - - public string GetSelectCommandByHitsAnalysis(string tableName, int siteId) - { - var orderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByTaxisDesc); - - var whereString = new StringBuilder(); - whereString.Append($"AND IsChecked='{true}' AND SiteId = {siteId} AND Hits > 0"); - whereString.Append(orderByString); - - return DataProvider.DatabaseDao.GetSelectSqlString(tableName, SqlUtils.Asterisk, whereString.ToString()); - } - - public int GetTotalHits(string tableName, int siteId) - { - return DataProvider.DatabaseDao.GetIntResult($"SELECT SUM(Hits) FROM {tableName} WHERE IsChecked='{true}' AND SiteId = {siteId} AND Hits > 0"); - } - - public int GetFirstContentId(string tableName, int channelId) - { - string sqlString = $"SELECT Id FROM {tableName} WHERE ChannelId = {channelId} ORDER BY Taxis DESC, Id DESC"; - return DataProvider.DatabaseDao.GetIntResult(sqlString); - } - - public List GetContentIdList(string tableName, int channelId) - { - var list = new List(); - - string sqlString = $"SELECT Id FROM {tableName} WHERE ChannelId = {channelId}"; - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var contentId = GetInt(rdr, 0); - list.Add(contentId); - } - rdr.Close(); - } - return list; - } - - public List GetContentIdList(string tableName, int channelId, bool isPeriods, string dateFrom, string dateTo, ETriState checkedState) - { - var list = new List(); - - string sqlString = $"SELECT Id FROM {tableName} WHERE ChannelId = {channelId}"; - if (isPeriods) - { - var dateString = string.Empty; - if (!string.IsNullOrEmpty(dateFrom)) - { - dateString = $" AND AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))} "; - } - if (!string.IsNullOrEmpty(dateTo)) - { - dateString += $" AND AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo).AddDays(1))} "; - } - sqlString += dateString; - } - - if (checkedState != ETriState.All) - { - sqlString += $" AND IsChecked = '{ETriStateUtils.GetValue(checkedState)}'"; - } - - sqlString += " ORDER BY Taxis DESC, Id DESC"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var contentId = GetInt(rdr, 0); - list.Add(contentId); - } - rdr.Close(); - } - return list; - } - - public List GetContentIdListCheckedByChannelId(string tableName, int siteId, int channelId) - { - var list = new List(); - - string sqlString = $"SELECT Id FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelId} AND IsChecked = '{true}'"; - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetInt(rdr, 0)); - } - rdr.Close(); - } - return list; - } - - public int GetContentId(string tableName, int channelId, int taxis, bool isNextContent) - { - var contentId = 0; - var sqlString = SqlUtils.ToTopSqlString(tableName, "Id", $"WHERE (ChannelId = {channelId} AND Taxis > {taxis} AND IsChecked = 'True')", "ORDER BY Taxis", 1); - if (isNextContent) - { - sqlString = SqlUtils.ToTopSqlString(tableName, "Id", - $"WHERE (ChannelId = {channelId} AND Taxis < {taxis} AND IsChecked = 'True')", "ORDER BY Taxis DESC", 1); - } - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - contentId = GetInt(rdr, 0); - } - rdr.Close(); - } - return contentId; - } - - public int GetContentId(string tableName, int channelId, string orderByString) - { - var contentId = 0; - var sqlString = SqlUtils.ToTopSqlString(tableName, "Id", $"WHERE (ChannelId = {channelId})", orderByString, 1); - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - contentId = GetInt(rdr, 0); - } - rdr.Close(); - } - return contentId; - } - - public List GetValueList(string tableName, int channelId, string name) - { - string sqlString = $"SELECT {name} FROM {tableName} WHERE ChannelId = {channelId}"; - return DataProvider.DatabaseDao.GetStringList(sqlString); - } - - public List GetValueListByStartString(string tableName, int channelId, string name, string startString, int totalNum) - { - var inStr = SqlUtils.GetInStr(name, startString); - var sqlString = SqlUtils.GetDistinctTopSqlString(tableName, name, $"WHERE ChannelId = {channelId} AND {inStr}", string.Empty, totalNum); - return DataProvider.DatabaseDao.GetStringList(sqlString); - } - - public int GetChannelId(string tableName, int contentId) - { - var channelId = 0; - string sqlString = $"SELECT {ContentAttribute.ChannelId} FROM {tableName} WHERE (Id = {contentId})"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - channelId = GetInt(rdr, 0); - } - rdr.Close(); - } - return channelId; - } - - public DateTime GetAddDate(string tableName, int contentId) - { - var addDate = DateTime.Now; - string sqlString = $"SELECT {ContentAttribute.AddDate} FROM {tableName} WHERE (Id = {contentId})"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - addDate = GetDateTime(rdr, 0); - } - rdr.Close(); - } - return addDate; - } - - public DateTime GetLastEditDate(string tableName, int contentId) - { - var lastEditDate = DateTime.Now; - string sqlString = $"SELECT {ContentAttribute.LastEditDate} FROM {tableName} WHERE (Id = {contentId})"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - lastEditDate = GetDateTime(rdr, 0); - } - rdr.Close(); - } - return lastEditDate; - } - - public int GetCount(string tableName, int channelId) - { - string sqlString = $"SELECT COUNT(*) AS TotalNum FROM {tableName} WHERE (ChannelId = {channelId})"; - - return DataProvider.DatabaseDao.GetIntResult(sqlString); - } - - public int GetSequence(string tableName, int channelId, int contentId) - { - string sqlString = - $"SELECT COUNT(*) AS TotalNum FROM {tableName} WHERE ChannelId = {channelId} AND IsChecked = '{true}' AND Taxis < (SELECT Taxis FROM {tableName} WHERE (Id = {contentId}))"; - - return DataProvider.DatabaseDao.GetIntResult(sqlString) + 1; - } - - public string GetSqlStringOfAdminExcludeRecycle(string tableName, int siteId, DateTime begin, DateTime end) - { - string sqlString = $@"select userName,SUM(addCount) as addCount, SUM(updateCount) as updateCount from( -SELECT AddUserName as userName, Count(AddUserName) as addCount, 0 as updateCount FROM {tableName} -INNER JOIN {DataProvider.AdministratorDao.TableName} ON AddUserName = {DataProvider.AdministratorDao.TableName}.UserName -WHERE {tableName}.SiteId = {siteId} AND (({tableName}.ChannelId > 0)) -AND LastEditDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))} -GROUP BY AddUserName -Union -SELECT LastEditUserName as userName,0 as addCount, Count(LastEditUserName) as updateCount FROM {tableName} -INNER JOIN {DataProvider.AdministratorDao.TableName} ON LastEditUserName = {DataProvider.AdministratorDao.TableName}.UserName -WHERE {tableName}.SiteId = {siteId} AND (({tableName}.ChannelId > 0)) -AND LastEditDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))} -AND LastEditDate != AddDate -GROUP BY LastEditUserName -) as tmp -group by tmp.userName"; - - - return sqlString; - } - - public List GetChannelIdListCheckedByLastEditDateHour(string tableName, int siteId, int hour) - { - var list = new List(); - - string sqlString = - $"SELECT DISTINCT ChannelId FROM {tableName} WHERE (SiteId = {siteId}) AND (IsChecked = '{true}') AND (LastEditDate BETWEEN {SqlUtils.GetComparableDateTime(DateTime.Now.AddHours(-hour))} AND {SqlUtils.GetComparableNow()})"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var channelId = GetInt(rdr, 0); - list.Add(channelId); - } - rdr.Close(); - } - return list; - } - - public string GetSelectedCommendByCheck(string tableName, int siteId, List channelIdList, List checkLevelList) - { - var whereString = channelIdList.Count == 1 - ? $"WHERE SiteId = {siteId} AND ChannelId = {channelIdList[0]} AND IsChecked='{false}' AND CheckedLevel IN ({TranslateUtils.ToSqlInStringWithoutQuote(checkLevelList)}) " - : $"WHERE SiteId = {siteId} AND ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND IsChecked='{false}' AND CheckedLevel IN ({TranslateUtils.ToSqlInStringWithoutQuote(checkLevelList)}) "; - - return DataProvider.DatabaseDao.GetSelectSqlString(tableName, SqlUtils.Asterisk, whereString); - } - - public string GetStlWhereString(int siteId, string group, string groupNot, string tags, bool isTopExists, bool isTop, string where) - { - var whereStringBuilder = new StringBuilder(); - - if (isTopExists) - { - whereStringBuilder.Append($" AND IsTop = '{isTop}' "); - } - - if (!string.IsNullOrEmpty(group)) - { - group = group.Trim().Trim(','); - var groupArr = group.Split(','); - if (groupArr.Length > 0) - { - whereStringBuilder.Append(" AND ("); - foreach (var theGroup in groupArr) - { - //whereStringBuilder.Append( - // $" ({ContentAttribute.GroupNameCollection} = '{theGroup.Trim()}' OR CHARINDEX('{theGroup.Trim()},',{ContentAttribute.GroupNameCollection}) > 0 OR CHARINDEX(',{theGroup.Trim()},',{ContentAttribute.GroupNameCollection}) > 0 OR CHARINDEX(',{theGroup.Trim()}',{ContentAttribute.GroupNameCollection}) > 0) OR "); - - whereStringBuilder.Append( - $" ({ContentAttribute.GroupNameCollection} = '{theGroup.Trim()}' OR {SqlUtils.GetInStr(ContentAttribute.GroupNameCollection, theGroup.Trim() + ",")} OR {SqlUtils.GetInStr(ContentAttribute.GroupNameCollection, "," + theGroup.Trim() + ",")} OR {SqlUtils.GetInStr(ContentAttribute.GroupNameCollection, "," + theGroup.Trim())}) OR "); - } - if (groupArr.Length > 0) - { - whereStringBuilder.Length = whereStringBuilder.Length - 3; - } - whereStringBuilder.Append(") "); - } - } - - if (!string.IsNullOrEmpty(groupNot)) - { - groupNot = groupNot.Trim().Trim(','); - var groupNotArr = groupNot.Split(','); - if (groupNotArr.Length > 0) - { - whereStringBuilder.Append(" AND ("); - foreach (var theGroupNot in groupNotArr) - { - //whereStringBuilder.Append( - // $" ({ContentAttribute.GroupNameCollection} <> '{theGroupNot.Trim()}' AND CHARINDEX('{theGroupNot.Trim()},',{ContentAttribute.GroupNameCollection}) = 0 AND CHARINDEX(',{theGroupNot.Trim()},',{ContentAttribute.GroupNameCollection}) = 0 AND CHARINDEX(',{theGroupNot.Trim()}',{ContentAttribute.GroupNameCollection}) = 0) AND "); - - whereStringBuilder.Append( - $" ({ContentAttribute.GroupNameCollection} <> '{theGroupNot.Trim()}' AND {SqlUtils.GetNotInStr(ContentAttribute.GroupNameCollection, theGroupNot.Trim() + ",")} AND {SqlUtils.GetNotInStr(ContentAttribute.GroupNameCollection, "," + theGroupNot.Trim() + ",")} AND {SqlUtils.GetNotInStr(ContentAttribute.GroupNameCollection, "," + theGroupNot.Trim())}) AND "); - } - if (groupNotArr.Length > 0) - { - whereStringBuilder.Length = whereStringBuilder.Length - 4; - } - whereStringBuilder.Append(") "); - } - } - - if (!string.IsNullOrEmpty(tags)) - { - var tagCollection = TagUtils.ParseTagsString(tags); - var contentIdList = DataProvider.TagDao.GetContentIdListByTagCollection(tagCollection, siteId); - if (contentIdList.Count > 0) - { - var inString = TranslateUtils.ToSqlInStringWithoutQuote(contentIdList); - whereStringBuilder.Append($" AND (Id IN ({inString}))"); - } - } - - if (!string.IsNullOrEmpty(where)) - { - whereStringBuilder.Append($" AND ({where}) "); - } - - return whereStringBuilder.ToString(); - } - - public DataSet GetDataSetOfAdminExcludeRecycle(string tableName, int siteId, DateTime begin, DateTime end) - { - var sqlString = GetSqlStringOfAdminExcludeRecycle(tableName, siteId, begin, end); - - return ExecuteDataset(sqlString); - } - - public int Insert(string tableName, SiteInfo siteInfo, IContentInfo contentInfo) - { - var taxis = GetTaxisToInsert(tableName, contentInfo.ChannelId, contentInfo.IsTop); - return Insert(tableName, siteInfo, contentInfo, true, taxis); - } - - public int InsertPreview(string tableName, SiteInfo siteInfo, ChannelInfo channelInfo, ContentInfo contentInfo) - { - channelInfo.Additional.IsPreviewContents = true; - DataProvider.ChannelDao.UpdateAdditional(channelInfo); - - contentInfo.SourceId = SourceManager.Preview; - return Insert(tableName, siteInfo, contentInfo, false, 0); - } - - public int Insert(string tableName, SiteInfo siteInfo, IContentInfo contentInfo, bool isUpdateContentNum, int taxis) - { - var contentId = 0; - - if (!string.IsNullOrEmpty(tableName)) - { - if (siteInfo.Additional.IsAutoPageInTextEditor && contentInfo.ContainsKey(BackgroundContentAttribute.Content)) - { - contentInfo.Set(BackgroundContentAttribute.Content, ContentUtility.GetAutoPageContent(contentInfo.GetString(BackgroundContentAttribute.Content), siteInfo.Additional.AutoPageWordNum)); - } - - contentInfo.Taxis = taxis; - - contentId = Insert(tableName, contentInfo); - - if (isUpdateContentNum) - { - new Action(() => - { - DataProvider.ChannelDao.UpdateContentNum(SiteManager.GetSiteInfo(contentInfo.SiteId), contentInfo.ChannelId, true); - }).BeginInvoke(null, null); - } - - Content.ClearCache(); - } - - return contentId; - } - - public void Update(string tableName, SiteInfo siteInfo, IContentInfo contentInfo) - { - if (siteInfo.Additional.IsAutoPageInTextEditor && contentInfo.ContainsKey(BackgroundContentAttribute.Content)) - { - contentInfo.Set(BackgroundContentAttribute.Content, ContentUtility.GetAutoPageContent(contentInfo.GetString(BackgroundContentAttribute.Content), siteInfo.Additional.AutoPageWordNum)); - } - - Update(tableName, contentInfo); - - Content.ClearCache(); - } - - public ContentInfo GetContentInfo(string tableName, int contentId) - { - if (string.IsNullOrEmpty(tableName) || contentId <= 0) return null; - - ContentInfo info = null; - - string sqlWhere = $"WHERE Id = {contentId}"; - var sqlSelect = DataProvider.DatabaseDao.GetSelectSqlString(tableName, SqlUtils.Asterisk, sqlWhere); - - using (var rdr = ExecuteReader(sqlSelect)) - { - if (rdr.Read()) - { - info = GetContentInfo(rdr); - } - rdr.Close(); - } - - return info; - } - - public int GetCountOfContentAdd(string tableName, int siteId, int channelId, EScopeType scope, DateTime begin, DateTime end, string userName, ETriState checkedState) - { - var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var channelIdList = ChannelManager.GetChannelIdList(channelInfo, scope, string.Empty, string.Empty, string.Empty); - return GetCountOfContentAdd(tableName, siteId, channelIdList, begin, end, userName, checkedState); - } - - public List GetContentIdListChecked(string tableName, int channelId, string orderByFormatString) - { - return GetContentIdListChecked(tableName, channelId, orderByFormatString, string.Empty); - } - - public int GetCountOfContentUpdate(string tableName, int siteId, int channelId, EScopeType scope, DateTime begin, DateTime end, string userName) - { - var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var channelIdList = ChannelManager.GetChannelIdList(channelInfo, scope, string.Empty, string.Empty, string.Empty); - return GetCountOfContentUpdate(tableName, siteId, channelIdList, begin, end, userName); - } - - public int GetCountOfContentUpdate(string tableName, int siteId, List channelIdList, DateTime begin, DateTime end, string userName) - { - string sqlString; - if (string.IsNullOrEmpty(userName)) - { - sqlString = channelIdList.Count == 1 - ? $"SELECT COUNT(Id) AS Num FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelIdList[0]} AND (LastEditDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))}) AND (LastEditDate <> AddDate)" - : $"SELECT COUNT(Id) AS Num FROM {tableName} WHERE SiteId = {siteId} AND ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND (LastEditDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))}) AND (LastEditDate <> AddDate)"; - } - else - { - sqlString = channelIdList.Count == 1 - ? $"SELECT COUNT(Id) AS Num FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelIdList[0]} AND (LastEditDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))}) AND (LastEditDate <> AddDate) AND (AddUserName = '{userName}')" - : $"SELECT COUNT(Id) AS Num FROM {tableName} WHERE SiteId = {siteId} AND ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND (LastEditDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))}) AND (LastEditDate <> AddDate) AND (AddUserName = '{userName}')"; - } - - return DataProvider.DatabaseDao.GetIntResult(sqlString); - } - - public string GetWhereStringByStlSearch(bool isAllSites, string siteName, string siteDir, string siteIds, string channelIndex, string channelName, string channelIds, string type, string word, string dateAttribute, string dateFrom, string dateTo, string since, int siteId, List excludeAttributes, NameValueCollection form, out bool isDefaultCondition) - { - isDefaultCondition = true; - var whereBuilder = new StringBuilder(); - - SiteInfo siteInfo = null; - if (!string.IsNullOrEmpty(siteName)) - { - siteInfo = SiteManager.GetSiteInfoBySiteName(siteName); - } - else if (!string.IsNullOrEmpty(siteDir)) - { - siteInfo = SiteManager.GetSiteInfoByDirectory(siteDir); - } - if (siteInfo == null) - { - siteInfo = SiteManager.GetSiteInfo(siteId); - } - - var channelId = DataProvider.ChannelDao.GetIdByChannelIdOrChannelIndexOrChannelName(siteId, siteId, channelIndex, channelName); - var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); - - if (isAllSites) - { - whereBuilder.Append("(SiteId > 0) "); - } - else if (!string.IsNullOrEmpty(siteIds)) - { - whereBuilder.Append($"(SiteId IN ({TranslateUtils.ToSqlInStringWithoutQuote(TranslateUtils.StringCollectionToIntList(siteIds))})) "); - } - else - { - whereBuilder.Append($"(SiteId = {siteInfo.Id}) "); - } - - if (!string.IsNullOrEmpty(channelIds)) - { - whereBuilder.Append(" AND "); - var channelIdList = new List(); - foreach (var theChannelId in TranslateUtils.StringCollectionToIntList(channelIds)) - { - var theSiteId = DataProvider.ChannelDao.GetSiteId(theChannelId); - channelIdList.AddRange( - ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(theSiteId, theChannelId), - EScopeType.All, string.Empty, string.Empty, string.Empty)); - } - whereBuilder.Append(channelIdList.Count == 1 - ? $"(ChannelId = {channelIdList[0]}) " - : $"(ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)})) "); - } - else if (channelId != siteId) - { - whereBuilder.Append(" AND "); - - var theSiteId = DataProvider.ChannelDao.GetSiteId(channelId); - var channelIdList = ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(theSiteId, channelId), - EScopeType.All, string.Empty, string.Empty, string.Empty); - - whereBuilder.Append(channelIdList.Count == 1 - ? $"(ChannelId = {channelIdList[0]}) " - : $"(ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)})) "); - } - - var typeList = new List(); - if (string.IsNullOrEmpty(type)) - { - typeList.Add(ContentAttribute.Title); - } - else - { - typeList = TranslateUtils.StringCollectionToStringList(type); - } - - if (!string.IsNullOrEmpty(word)) - { - whereBuilder.Append(" AND ("); - foreach (var attributeName in typeList) - { - whereBuilder.Append($"[{attributeName}] LIKE '%{PageUtils.FilterSql(word)}%' OR "); - } - whereBuilder.Length = whereBuilder.Length - 3; - whereBuilder.Append(")"); - } - - if (string.IsNullOrEmpty(dateAttribute)) - { - dateAttribute = ContentAttribute.AddDate; - } - - if (!string.IsNullOrEmpty(dateFrom)) - { - whereBuilder.Append(" AND "); - whereBuilder.Append($" {dateAttribute} >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))} "); - } - if (!string.IsNullOrEmpty(dateTo)) - { - whereBuilder.Append(" AND "); - whereBuilder.Append($" {dateAttribute} <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo))} "); - } - if (!string.IsNullOrEmpty(since)) - { - var sinceDate = DateTime.Now.AddHours(-DateUtils.GetSinceHours(since)); - whereBuilder.Append($" AND {dateAttribute} BETWEEN {SqlUtils.GetComparableDateTime(sinceDate)} AND {SqlUtils.GetComparableNow()} "); - } - - var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); - var styleInfoList = RelatedIdentities.GetTableStyleInfoList(siteInfo, channelInfo.Id); - - foreach (string key in form.Keys) - { - if (excludeAttributes.Contains(key.ToLower())) continue; - if (string.IsNullOrEmpty(form[key])) continue; - - var value = StringUtils.Trim(form[key]); - if (string.IsNullOrEmpty(value)) continue; - - if (TableMetadataManager.IsAttributeNameExists(tableName, key)) - { - whereBuilder.Append(" AND "); - whereBuilder.Append($"({key} LIKE '%{value}%')"); - } - else - { - foreach (var tableStyleInfo in styleInfoList) - { - if (StringUtils.EqualsIgnoreCase(tableStyleInfo.AttributeName, key)) - { - whereBuilder.Append(" AND "); - whereBuilder.Append($"({ContentAttribute.SettingsXml} LIKE '%{key}={value}%')"); - break; - } - } - } - } - - if (whereBuilder.ToString().Contains(" AND ")) - { - isDefaultCondition = false; - } - - return whereBuilder.ToString(); - } - - public string GetSqlString(string tableName, int siteId, int channelId, bool isSystemAdministrator, List owningChannelIdList, string searchType, string keyword, string dateFrom, string dateTo, bool isSearchChildren, ETriState checkedState, bool isNoDup, bool isTrashContent) - { - var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var channelIdList = ChannelManager.GetChannelIdList(channelInfo, - isSearchChildren ? EScopeType.All : EScopeType.Self, string.Empty, string.Empty, channelInfo.ContentModelPluginId); - - var list = new List(); - if (isSystemAdministrator) - { - list = channelIdList; - } - else - { - foreach (int theChannelId in channelIdList) - { - if (owningChannelIdList.Contains(theChannelId)) - { - list.Add(theChannelId); - } - } - } - - return GetSqlStringByCondition(tableName, siteId, list, searchType, keyword, dateFrom, dateTo, checkedState, isNoDup, isTrashContent); - } - - public string GetSqlString(string tableName, int siteId, int channelId, bool isSystemAdministrator, List owningChannelIdList, string searchType, string keyword, string dateFrom, string dateTo, bool isSearchChildren, ETriState checkedState, bool isNoDup, bool isTrashContent, bool isWritingOnly, string userNameOnly) - { - var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var channelIdList = ChannelManager.GetChannelIdList(channelInfo, isSearchChildren ? EScopeType.All : EScopeType.Self, string.Empty, string.Empty, channelInfo.ContentModelPluginId); - - var list = new List(); - if (isSystemAdministrator) - { - list = channelIdList; - } - else - { - foreach (int theChannelId in channelIdList) - { - if (owningChannelIdList.Contains(theChannelId)) - { - list.Add(theChannelId); - } - } - } - - return GetSqlStringByCondition(tableName, siteId, list, searchType, keyword, dateFrom, dateTo, checkedState, isNoDup, isTrashContent, isWritingOnly, userNameOnly); - } - - public string GetSqlStringByContentGroup(string tableName, string contentGroupName, int siteId) - { - contentGroupName = PageUtils.FilterSql(contentGroupName); - string sqlString = - $"SELECT * FROM {tableName} WHERE SiteId = {siteId} AND ChannelId > 0 AND (GroupNameCollection LIKE '{contentGroupName},%' OR GroupNameCollection LIKE '%,{contentGroupName}' OR GroupNameCollection LIKE '%,{contentGroupName},%' OR GroupNameCollection='{contentGroupName}')"; - return sqlString; - } - - public DataSet GetStlDataSourceChecked(List channelIdList, string tableName, int startNum, int totalNum, string orderByString, string whereString, bool isNoDup, LowerNameValueCollection others) - { - return GetStlDataSourceChecked(tableName, channelIdList, startNum, totalNum, orderByString, whereString, isNoDup, others); - } - - public string GetStlSqlStringChecked(List channelIdList, string tableName, int siteId, int channelId, int startNum, int totalNum, string orderByString, string whereString, EScopeType scopeType, string groupChannel, string groupChannelNot, bool isNoDup) - { - string sqlWhereString; - - if (siteId == channelId && scopeType == EScopeType.All && string.IsNullOrEmpty(groupChannel) && string.IsNullOrEmpty(groupChannelNot)) - { - sqlWhereString = - $"WHERE (SiteId = {siteId} AND ChannelId > 0 AND IsChecked = '{true}' {whereString})"; - } - else - { - if (channelIdList == null || channelIdList.Count == 0) - { - return string.Empty; - } - sqlWhereString = channelIdList.Count == 1 ? $"WHERE (ChannelId = {channelIdList[0]} AND IsChecked = '{true}' {whereString})" : $"WHERE (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND IsChecked = '{true}' {whereString})"; - } - - if (isNoDup) - { - var sqlString = DataProvider.DatabaseDao.GetSelectSqlString(tableName, "MIN(Id)", sqlWhereString + " GROUP BY Title"); - sqlWhereString += $" AND Id IN ({sqlString})"; - } - - if (!string.IsNullOrEmpty(tableName)) - { - return DataProvider.DatabaseDao.GetSelectSqlString(tableName, startNum, totalNum, StlColumns, sqlWhereString, orderByString); - } - return string.Empty; - } - - public string GetStlSqlStringCheckedBySearch(string tableName, int startNum, int totalNum, string orderByString, string whereString, bool isNoDup) - { - string sqlWhereString = - $"WHERE (ChannelId > 0 AND IsChecked = '{true}' {whereString})"; - if (isNoDup) - { - var sqlString = DataProvider.DatabaseDao.GetSelectSqlString(tableName, "MIN(Id)", sqlWhereString + " GROUP BY Title"); - sqlWhereString += $" AND Id IN ({sqlString})"; - } - - if (!string.IsNullOrEmpty(tableName)) - { - return DataProvider.DatabaseDao.GetSelectSqlString(tableName, startNum, totalNum, $"{nameof(IContentInfo.Id)}, {nameof(IContentInfo.ChannelId)}, {nameof(IContentInfo.IsTop)}, {nameof(IContentInfo.AddDate)}, {nameof(IContentInfo.LastEditDate)}, {nameof(IContentInfo.Taxis)}, {nameof(IContentInfo.Hits)}, {nameof(IContentInfo.HitsByDay)}, {nameof(IContentInfo.HitsByWeek)}, {nameof(IContentInfo.HitsByMonth)}", sqlWhereString, orderByString); - } - return string.Empty; - } - - public List GetIdListBySameTitle(string tableName, int channelId, string title) - { - var list = new List(); - string sql = $"SELECT Id FROM {tableName} WHERE ChannelId = {channelId} AND Title = '{title}'"; - using (var rdr = ExecuteReader(sql)) - { - while (rdr.Read()) - { - list.Add(GetInt(rdr, 0)); - } - rdr.Close(); - } - return list; - } - - public List GetListByLimitAndOffset(string tableName, int channelId, string whereString, string orderString, int limit, int offset) - { - var list = new List(); - if (!string.IsNullOrEmpty(whereString)) - { - whereString = whereString.Replace("WHERE ", string.Empty).Replace("where ", string.Empty); - } - if (!string.IsNullOrEmpty(orderString)) - { - orderString = orderString.Replace("ORDER BY ", string.Empty).Replace("order by ", string.Empty); - } - var firstWhere = string.IsNullOrEmpty(whereString) ? string.Empty : $"WHERE {whereString}"; - var secondWhere = string.IsNullOrEmpty(whereString) ? string.Empty : $"AND {whereString}"; - var order = string.IsNullOrEmpty(orderString) ? "IsTop DESC, Id DESC" : orderString; - - var sqlString = $"SELECT * FROM {tableName} {firstWhere} ORDER BY {order}"; - if (limit > 0 && offset > 0) - { - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - sqlString = $"SELECT * FROM {tableName} {firstWhere} ORDER BY {order} limit {limit} offset {offset}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - sqlString = $@"SELECT TOP {limit} * FROM {tableName} WHERE Id NOT IN (SELECT TOP {offset} Id FROM {tableName} {firstWhere} ORDER BY {order}) {secondWhere} ORDER BY {order}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - sqlString = $"SELECT * FROM {tableName} {firstWhere} ORDER BY {order} limit {limit} offset {offset}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - sqlString = $"SELECT * FROM {tableName} {firstWhere} ORDER BY {order} OFFSET {offset} ROWS FETCH NEXT {limit} ROWS ONLY"; - } - } - else if (limit > 0) - { - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - sqlString = $"SELECT * FROM {tableName} {firstWhere} ORDER BY {order} limit {limit}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - sqlString = $@"SELECT TOP {limit} * FROM {tableName} {firstWhere} ORDER BY {order}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - sqlString = $"SELECT * FROM {tableName} {firstWhere} ORDER BY {order} limit {limit}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - sqlString = $"SELECT * FROM {tableName} {firstWhere} ORDER BY {order} FETCH FIRST {limit} ROWS ONLY"; - } - } - else if (offset > 0) - { - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - sqlString = $"SELECT * FROM {tableName} {firstWhere} ORDER BY {order} offset {offset}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - sqlString = - $@"SELECT * FROM {tableName} WHERE Id NOT IN (SELECT TOP {offset} Id FROM {tableName} {firstWhere} ORDER BY {order}) {secondWhere} ORDER BY {order}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - sqlString = $"SELECT * FROM {tableName} {firstWhere} ORDER BY {order} offset {offset}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - sqlString = $"SELECT * FROM {tableName} {firstWhere} ORDER BY {order} OFFSET {offset} ROWS"; - } - } - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var info = GetContentInfo(rdr); - list.Add(info); - } - rdr.Close(); - } - - return list; - } - - public int GetCount(string tableName, int channelId, string whereString) - { - if (!string.IsNullOrEmpty(whereString)) - { - whereString = whereString.Replace("WHERE ", string.Empty).Replace("where ", string.Empty); - } - whereString = string.IsNullOrEmpty(whereString) ? string.Empty : $"WHERE {whereString}"; - - string sqlString = $"SELECT COUNT(*) FROM {tableName} {whereString}"; - - return DataProvider.DatabaseDao.GetIntResult(sqlString); - } - - public List> GetCountListUnChecked(PermissionManager permissionManager, string tableName) - { - var list = new List>(); - - var siteIdList = permissionManager.SiteIdList; - var owningChannelIdList = permissionManager.OwningChannelIdList; - - var siteIdArrayList = SiteManager.GetSiteIdList(); - foreach (var siteId in siteIdArrayList) - { - if (!siteIdList.Contains(siteId)) continue; - - var siteInfo = SiteManager.GetSiteInfo(siteId); - if (!permissionManager.IsSystemAdministrator) - { - //if (!owningChannelIdArrayList.Contains(psID)) continue; - //if (!AdminUtility.HasChannelPermissions(psID, psID, AppManager.CMS.Permission.Channel.ContentCheck)) continue; - - var isContentCheck = false; - foreach (var theChannelId in owningChannelIdList) - { - if (permissionManager.HasChannelPermissions(siteId, theChannelId, ConfigManager.ChannelPermissions.ContentCheck)) - { - isContentCheck = true; - } - } - if (!isContentCheck) - { - continue; - } - } - - int checkedLevel; - var isChecked = CheckManager.GetUserCheckLevel(permissionManager, siteInfo, siteInfo.Id, out checkedLevel); - var checkLevelList = CheckManager.LevelInt.GetCheckLevelListOfNeedCheck(siteInfo, isChecked, checkedLevel); - var sqlString = permissionManager.IsSystemAdministrator ? $"SELECT COUNT(*) AS TotalNum FROM {tableName} WHERE (SiteId = {siteId} AND ChannelId > 0 AND IsChecked = '{false}' AND CheckedLevel IN ({TranslateUtils.ToSqlInStringWithoutQuote(checkLevelList)}))" : $"SELECT COUNT(*) AS TotalNum FROM {tableName} WHERE (SiteId = {siteId} AND ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(owningChannelIdList)}) AND IsChecked = '{false}' AND CheckedLevel IN ({TranslateUtils.ToSqlInStringWithoutQuote(checkLevelList)}))"; - - var count = DataProvider.DatabaseDao.GetIntResult(sqlString); - if (count > 0) - { - list.Add(new KeyValuePair(siteId, count)); - } - } - return list; - } - - public int GetCountCheckedImage(int siteId, int channelId) - { - var tableName = SiteManager.GetSiteInfo(siteId).TableName; - string sqlString = - $"SELECT COUNT(*) AS TotalNum FROM {tableName} WHERE (ChannelId = {channelId} AND ImageUrl <> '' AND {ContentAttribute.IsChecked} = '{true}')"; - - return DataProvider.DatabaseDao.GetIntResult(sqlString); - } - - public string GetStlWhereString(int siteId, string tableName, string group, string groupNot, string tags, bool isImageExists, bool isImage, bool isVideoExists, bool isVideo, bool isFileExists, bool isFile, bool isTopExists, bool isTop, bool isRecommendExists, bool isRecommend, bool isHotExists, bool isHot, bool isColorExists, bool isColor, string where, bool isCreateSearchDuplicate) - { - var whereBuilder = new StringBuilder(); - whereBuilder.Append($" AND SiteId = {siteId} "); - - if (isImageExists) - { - whereBuilder.Append(isImage - ? $" AND {BackgroundContentAttribute.ImageUrl} <> '' " - : $" AND {BackgroundContentAttribute.ImageUrl} = '' "); - } - - if (isVideoExists) - { - whereBuilder.Append(isVideo - ? $" AND {BackgroundContentAttribute.VideoUrl} <> '' " - : $" AND {BackgroundContentAttribute.VideoUrl} = '' "); - } - - if (isFileExists) - { - whereBuilder.Append(isFile - ? $" AND {BackgroundContentAttribute.FileUrl} <> '' " - : $" AND {BackgroundContentAttribute.FileUrl} = '' "); - } - - if (isTopExists) - { - whereBuilder.Append($" AND {ContentAttribute.IsTop} = '{isTop}' "); - } - - if (isRecommendExists) - { - whereBuilder.Append($" AND {ContentAttribute.IsRecommend} = '{isRecommend}' "); - } - - if (isHotExists) - { - whereBuilder.Append($" AND {ContentAttribute.IsHot} = '{isHot}' "); - } - - if (isColorExists) - { - whereBuilder.Append($" AND {ContentAttribute.IsColor} = '{isColor}' "); - } - - if (!string.IsNullOrEmpty(group)) - { - group = group.Trim().Trim(','); - var groupArr = group.Split(','); - if (groupArr != null && groupArr.Length > 0) - { - whereBuilder.Append(" AND ("); - foreach (var theGroup in groupArr) - { - var trimGroup = theGroup.Trim(); - //whereBuilder.Append( - // $" ({ContentAttribute.GroupNameCollection} = '{trimGroup}' OR CHARINDEX('{trimGroup},',{ContentAttribute.GroupNameCollection}) > 0 OR CHARINDEX(',{trimGroup},',{ContentAttribute.GroupNameCollection}) > 0 OR CHARINDEX(',{trimGroup}',{ContentAttribute.GroupNameCollection}) > 0) OR "); - - whereBuilder.Append( - $" ({ContentAttribute.GroupNameCollection} = '{trimGroup}' OR {SqlUtils.GetInStr(ContentAttribute.GroupNameCollection, trimGroup + ",")} OR {SqlUtils.GetInStr(ContentAttribute.GroupNameCollection, "," + trimGroup + ",")} OR {SqlUtils.GetInStr(ContentAttribute.GroupNameCollection, "," + trimGroup)}) OR "); - } - if (groupArr.Length > 0) - { - whereBuilder.Length = whereBuilder.Length - 3; - } - whereBuilder.Append(") "); - } - } - - if (!string.IsNullOrEmpty(groupNot)) - { - groupNot = groupNot.Trim().Trim(','); - var groupNotArr = groupNot.Split(','); - if (groupNotArr != null && groupNotArr.Length > 0) - { - whereBuilder.Append(" AND ("); - foreach (var theGroupNot in groupNotArr) - { - var trimGroup = theGroupNot.Trim(); - //whereBuilder.Append( - // $" ({ContentAttribute.GroupNameCollection} <> '{trimGroup}' AND CHARINDEX('{trimGroup},',{ContentAttribute.GroupNameCollection}) = 0 AND CHARINDEX(',{trimGroup},',{ContentAttribute.GroupNameCollection}) = 0 AND CHARINDEX(',{trimGroup}',{ContentAttribute.GroupNameCollection}) = 0) AND "); - - whereBuilder.Append( - $" ({ContentAttribute.GroupNameCollection} <> '{trimGroup}' AND {SqlUtils.GetNotInStr(ContentAttribute.GroupNameCollection, trimGroup + ",")} AND {SqlUtils.GetNotInStr(ContentAttribute.GroupNameCollection, "," + trimGroup + ",")} AND {SqlUtils.GetNotInStr(ContentAttribute.GroupNameCollection, "," + trimGroup)}) AND "); - } - if (groupNotArr.Length > 0) - { - whereBuilder.Length = whereBuilder.Length - 4; - } - whereBuilder.Append(") "); - } - } - - if (!string.IsNullOrEmpty(tags)) - { - var tagCollection = TagUtils.ParseTagsString(tags); - var contentIdArrayList = DataProvider.TagDao.GetContentIdListByTagCollection(tagCollection, siteId); - if (contentIdArrayList.Count > 0) - { - whereBuilder.Append( - $" AND (ID IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdArrayList)}))"); - } - } - - if (!string.IsNullOrEmpty(where)) - { - whereBuilder.Append($" AND ({where}) "); - } - - if (!isCreateSearchDuplicate) - { - var sqlString = DataProvider.DatabaseDao.GetSelectSqlString(tableName, "MIN(ID)", whereBuilder + " GROUP BY Title"); - whereBuilder.Append($" AND ID IN ({sqlString}) "); - } - - return whereBuilder.ToString(); - } - - public string GetStlWhereStringBySearch(string tableName, string group, string groupNot, string tags, bool isImageExists, bool isImage, bool isVideoExists, bool isVideo, bool isFileExists, bool isFile, bool isTopExists, bool isTop, bool isRecommendExists, bool isRecommend, bool isHotExists, bool isHot, bool isColorExists, bool isColor, string where) - { - var whereBuilder = new StringBuilder(); - - if (isImageExists) - { - whereBuilder.Append(isImage - ? $" AND {BackgroundContentAttribute.ImageUrl} <> '' " - : $" AND {BackgroundContentAttribute.ImageUrl} = '' "); - } - - if (isVideoExists) - { - whereBuilder.Append(isVideo - ? $" AND {BackgroundContentAttribute.VideoUrl} <> '' " - : $" AND {BackgroundContentAttribute.VideoUrl} = '' "); - } - - if (isFileExists) - { - whereBuilder.Append(isFile - ? $" AND {BackgroundContentAttribute.FileUrl} <> '' " - : $" AND {BackgroundContentAttribute.FileUrl} = '' "); - } - - if (isTopExists) - { - whereBuilder.Append($" AND {ContentAttribute.IsTop} = '{isTop}' "); - } - - if (isRecommendExists) - { - whereBuilder.Append($" AND {ContentAttribute.IsRecommend} = '{isRecommend}' "); - } - - if (isHotExists) - { - whereBuilder.Append($" AND {ContentAttribute.IsHot} = '{isHot}' "); - } - - if (isColorExists) - { - whereBuilder.Append($" AND {ContentAttribute.IsColor} = '{isColor}' "); - } - - if (!string.IsNullOrEmpty(group)) - { - group = group.Trim().Trim(','); - var groupArr = group.Split(','); - if (groupArr != null && groupArr.Length > 0) - { - whereBuilder.Append(" AND ("); - foreach (var theGroup in groupArr) - { - var trimGroup = theGroup.Trim(); - //whereBuilder.Append( - // $" ({ContentAttribute.GroupNameCollection} = '{trimGroup}' OR CHARINDEX('{trimGroup},',{ContentAttribute.GroupNameCollection}) > 0 OR CHARINDEX(',{trimGroup},',{ContentAttribute.GroupNameCollection}) > 0 OR CHARINDEX(',{trimGroup}',{ContentAttribute.GroupNameCollection}) > 0) OR "); - - whereBuilder.Append( - $" ({ContentAttribute.GroupNameCollection} = '{trimGroup}' OR {SqlUtils.GetInStr(ContentAttribute.GroupNameCollection, trimGroup + ",")} OR {SqlUtils.GetInStr(ContentAttribute.GroupNameCollection, "," + trimGroup + ",")} OR {SqlUtils.GetInStr(ContentAttribute.GroupNameCollection, "," + trimGroup)}) OR "); - } - if (groupArr.Length > 0) - { - whereBuilder.Length = whereBuilder.Length - 3; - } - whereBuilder.Append(") "); - } - } - - if (!string.IsNullOrEmpty(groupNot)) - { - groupNot = groupNot.Trim().Trim(','); - var groupNotArr = groupNot.Split(','); - if (groupNotArr != null && groupNotArr.Length > 0) - { - whereBuilder.Append(" AND ("); - foreach (var theGroupNot in groupNotArr) - { - var trimGroup = theGroupNot.Trim(); - //whereBuilder.Append( - // $" ({ContentAttribute.GroupNameCollection} <> '{trimGroup}' AND CHARINDEX('{trimGroup},',{ContentAttribute.GroupNameCollection}) = 0 AND CHARINDEX(',{trimGroup},',{ContentAttribute.GroupNameCollection}) = 0 AND CHARINDEX(',{trimGroup}',{ContentAttribute.GroupNameCollection}) = 0) AND "); - - whereBuilder.Append( - $" ({ContentAttribute.GroupNameCollection} <> '{trimGroup}' AND {SqlUtils.GetNotInStr(ContentAttribute.GroupNameCollection, trimGroup + ",")} AND {SqlUtils.GetNotInStr(ContentAttribute.GroupNameCollection, "," + trimGroup + ",")} AND {SqlUtils.GetNotInStr(ContentAttribute.GroupNameCollection, "," + trimGroup)}) AND "); - } - if (groupNotArr.Length > 0) - { - whereBuilder.Length = whereBuilder.Length - 4; - } - whereBuilder.Append(") "); - } - } - - if (!string.IsNullOrEmpty(where)) - { - whereBuilder.Append($" AND ({where}) "); - } - - return whereBuilder.ToString(); - } - - public string GetSqlStringByDownloads(string tableName, int siteId) - { - var whereString = new StringBuilder(); - whereString.Append( - $"WHERE (SiteId = {siteId} AND IsChecked='True' AND FileUrl <> '') "); - - return DataProvider.DatabaseDao.GetSelectSqlString(tableName, SqlUtils.Asterisk, whereString.ToString()); - } - - private int GetTaxis(int selectedId, string tableName) - { - string sqlString = $"SELECT Taxis FROM {tableName} WHERE (Id = {selectedId})"; - - return DataProvider.DatabaseDao.GetIntResult(sqlString); - } - - private string GetSqlStringByCondition(string tableName, int siteId, List channelIdList, string searchType, string keyword, string dateFrom, string dateTo, ETriState checkedState, bool isNoDup, bool isTrashContent) - { - return GetSqlStringByCondition(tableName, siteId, channelIdList, searchType, keyword, dateFrom, dateTo, checkedState, isNoDup, isTrashContent, false, string.Empty); - } - - private string GetSqlStringByCondition(string tableName, int siteId, List channelIdList, string searchType, string keyword, string dateFrom, string dateTo, ETriState checkedState, bool isNoDup, bool isTrashContent, bool isWritingOnly, string userNameOnly) - { - if (channelIdList == null || channelIdList.Count == 0) - { - return null; - } - - var orderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByTaxisDesc); - - var dateString = string.Empty; - if (!string.IsNullOrEmpty(dateFrom)) - { - dateString = $" AND AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))} "; - } - if (!string.IsNullOrEmpty(dateTo)) - { - dateString += $" AND AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo).AddDays(1))} "; - } - var whereString = new StringBuilder($"WHERE {nameof(ContentAttribute.SourceId)} != {SourceManager.Preview} AND "); - - if (isTrashContent) - { - for (var i = 0; i < channelIdList.Count; i++) - { - var theChannelId = channelIdList[i]; - channelIdList[i] = -theChannelId; - } - } - - whereString.Append(channelIdList.Count == 1 - ? $"SiteId = {siteId} AND (ChannelId = {channelIdList[0]}) " - : $"SiteId = {siteId} AND (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)})) "); - - if (StringUtils.EqualsIgnoreCase(searchType, ContentAttribute.IsTop) || StringUtils.EqualsIgnoreCase(searchType, ContentAttribute.IsRecommend) || StringUtils.EqualsIgnoreCase(searchType, ContentAttribute.IsColor) || StringUtils.EqualsIgnoreCase(searchType, ContentAttribute.IsHot)) - { - if (!string.IsNullOrEmpty(keyword)) - { - whereString.Append($"AND ({ContentAttribute.Title} LIKE '%{keyword}%') "); - } - whereString.Append($" AND {searchType} = '{true}'"); - } - else if (!string.IsNullOrEmpty(keyword)) - { - var list = TableMetadataManager.GetAllLowerAttributeNameList(tableName); - whereString.Append(list.Contains(searchType.ToLower()) - ? $"AND ({searchType} LIKE '%{keyword}%') " - : $"AND (SettingsXML LIKE '%{searchType}={keyword}%') "); - } - - whereString.Append(dateString); - - if (checkedState == ETriState.True) - { - whereString.Append("AND IsChecked='True' "); - } - else if (checkedState == ETriState.False) - { - whereString.Append("AND IsChecked='False' "); - } - - if (isNoDup) - { - var sqlString = DataProvider.DatabaseDao.GetSelectSqlString(tableName, "MIN(Id)", whereString + " GROUP BY Title"); - whereString.Append($"AND Id IN ({sqlString})"); - } - - if (!string.IsNullOrEmpty(userNameOnly)) - { - whereString.Append($" AND AddUserName = '{userNameOnly}' "); - } - if (isWritingOnly) - { - whereString.Append(" AND WritingUserName <> '' "); - } - - whereString.Append(" ").Append(orderByString); - - return DataProvider.DatabaseDao.GetSelectSqlString(tableName, SqlUtils.Asterisk, whereString.ToString()); - } - - private List GetContentIdListByTrash(int siteId, string tableName) - { - string sqlString = - $"SELECT Id FROM {tableName} WHERE SiteId = {siteId} AND ChannelId < 0"; - return DataProvider.DatabaseDao.GetIntList(sqlString); - } - - private DataSet GetStlDataSourceChecked(string tableName, List channelIdList, int startNum, int totalNum, string orderByString, string whereString, bool isNoDup, LowerNameValueCollection others) - { - if (channelIdList == null || channelIdList.Count == 0) - { - return null; - } - var sqlWhereString = channelIdList.Count == 1 ? $"WHERE (ChannelId = {channelIdList[0]} AND IsChecked = '{true}' {whereString})" : $"WHERE (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND IsChecked = '{true}' {whereString})"; - - if (isNoDup) - { - var sqlString = DataProvider.DatabaseDao.GetSelectSqlString(tableName, "MIN(Id)", sqlWhereString + " GROUP BY Title"); - sqlWhereString += $" AND Id IN ({sqlString})"; - } - - if (others != null && others.Count > 0) - { - var lowerColumnNameList = TableMetadataManager.GetAllLowerAttributeNameList(tableName); - foreach (var attributeName in others.Keys) - { - if (lowerColumnNameList.Contains(attributeName.ToLower())) - { - var value = others.Get(attributeName); - if (!string.IsNullOrEmpty(value)) - { - value = value.Trim(); - if (StringUtils.StartsWithIgnoreCase(value, "not:")) - { - value = value.Substring("not:".Length); - if (value.IndexOf(',') == -1) - { - sqlWhereString += $" AND ({attributeName} <> '{value}')"; - } - else - { - var collection = TranslateUtils.StringCollectionToStringList(value); - foreach (var val in collection) - { - sqlWhereString += $" AND ({attributeName} <> '{val}')"; - } - } - } - else if (StringUtils.StartsWithIgnoreCase(value, "contains:")) - { - value = value.Substring("contains:".Length); - if (value.IndexOf(',') == -1) - { - sqlWhereString += $" AND ({attributeName} LIKE '%{value}%')"; - } - else - { - var builder = new StringBuilder(" AND ("); - var collection = TranslateUtils.StringCollectionToStringList(value); - foreach (var val in collection) - { - builder.Append($" {attributeName} LIKE '%{val}%' OR "); - } - builder.Length -= 3; - - builder.Append(")"); - - sqlWhereString += builder.ToString(); - } - } - else if (StringUtils.StartsWithIgnoreCase(value, "start:")) - { - value = value.Substring("start:".Length); - if (value.IndexOf(',') == -1) - { - sqlWhereString += $" AND ({attributeName} LIKE '{value}%')"; - } - else - { - var builder = new StringBuilder(" AND ("); - var collection = TranslateUtils.StringCollectionToStringList(value); - foreach (var val in collection) - { - builder.Append($" {attributeName} LIKE '{val}%' OR "); - } - builder.Length -= 3; - - builder.Append(")"); - - sqlWhereString += builder.ToString(); - } - } - else if (StringUtils.StartsWithIgnoreCase(value, "end:")) - { - value = value.Substring("end:".Length); - if (value.IndexOf(',') == -1) - { - sqlWhereString += $" AND ({attributeName} LIKE '%{value}')"; - } - else - { - var builder = new StringBuilder(" AND ("); - var collection = TranslateUtils.StringCollectionToStringList(value); - foreach (var val in collection) - { - builder.Append($" {attributeName} LIKE '%{val}' OR "); - } - builder.Length -= 3; - - builder.Append(")"); - - sqlWhereString += builder.ToString(); - } - } - else - { - if (value.IndexOf(',') == -1) - { - sqlWhereString += $" AND ({attributeName} = '{value}')"; - } - else - { - var builder = new StringBuilder(" AND ("); - var collection = TranslateUtils.StringCollectionToStringList(value); - foreach (var val in collection) - { - builder.Append($" {attributeName} = '{val}' OR "); - } - builder.Length -= 3; - - builder.Append(")"); - - sqlWhereString += builder.ToString(); - } - } - } - } - } - } - - return startNum <= 1 ? GetStlDataSourceByContentNumAndWhereString(tableName, totalNum, sqlWhereString, orderByString) : GetStlDataSourceByStartNum(tableName, startNum, totalNum, sqlWhereString, orderByString); - } - - private DataSet GetStlDataSourceByContentNumAndWhereString(string tableName, int totalNum, string whereString, string orderByString) - { - DataSet dataset = null; - if (!string.IsNullOrEmpty(tableName)) - { - var sqlSelect = DataProvider.DatabaseDao.GetSelectSqlString(tableName, totalNum, StlColumns, whereString, orderByString); - dataset = ExecuteDataset(sqlSelect); - } - return dataset; - } - - private DataSet GetStlDataSourceByStartNum(string tableName, int startNum, int totalNum, string whereString, string orderByString) - { - DataSet dataset = null; - if (!string.IsNullOrEmpty(tableName)) - { - var sqlSelect = DataProvider.DatabaseDao.GetSelectSqlString(tableName, startNum, totalNum, StlColumns, whereString, orderByString); - dataset = ExecuteDataset(sqlSelect); - } - return dataset; - } - - private int GetTaxisToInsert(string tableName, int channelId, bool isTop) - { - int taxis; - - if (isTop) - { - taxis = GetMaxTaxis(tableName, channelId, true) + 1; - } - else - { - taxis = GetMaxTaxis(tableName, channelId, false) + 1; - } - - return taxis; - } - - private ContentInfo GetContentInfo(IDataReader rdr) - { - var contentInfo = new ContentInfo(); - contentInfo.Load(rdr); - contentInfo.Load(contentInfo.SettingsXml); - - return contentInfo; - } - - private int GetCountOfContentAdd(string tableName, int siteId, List channelIdList, DateTime begin, DateTime end, string userName, ETriState checkedState) - { - string sqlString; - if (string.IsNullOrEmpty(userName)) - { - sqlString = channelIdList.Count == 1 - ? $"SELECT COUNT(Id) AS Num FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelIdList[0]} AND (AddDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))})" - : $"SELECT COUNT(Id) AS Num FROM {tableName} WHERE SiteId = {siteId} AND ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND (AddDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))})"; - } - else - { - sqlString = channelIdList.Count == 1 - ? $"SELECT COUNT(Id) AS Num FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelIdList[0]} AND (AddDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))}) AND (AddUserName = '{userName}')" - : $"SELECT COUNT(Id) AS Num FROM {tableName} WHERE SiteId = {siteId} AND ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND (AddDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))}) AND (AddUserName = '{userName}')"; - } - - if (checkedState != ETriState.All) - { - sqlString += $" AND {ContentAttribute.IsChecked} = '{ETriStateUtils.GetValue(checkedState)}'"; - } - - return DataProvider.DatabaseDao.GetIntResult(sqlString); - } - - private List GetContentIdListChecked(string tableName, int channelId, int totalNum, string orderByFormatString, string whereString) - { - var channelIdList = new List - { - channelId - }; - return GetContentIdListChecked(tableName, channelIdList, totalNum, orderByFormatString, whereString); - } - - private List GetContentIdListChecked(string tableName, List channelIdList, int totalNum, string orderString, string whereString) - { - var list = new List(); - - if (channelIdList == null || channelIdList.Count == 0) - { - return list; - } - - string sqlString; - - if (totalNum > 0) - { - sqlString = SqlUtils.ToTopSqlString(tableName, "Id", - channelIdList.Count == 1 - ? $"WHERE (ChannelId = {channelIdList[0]} AND IsChecked = '{true}' {whereString})" - : $"WHERE (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND IsChecked = '{true}' {whereString})", orderString, - totalNum); - } - else - { - sqlString = channelIdList.Count == 1 - ? $"SELECT Id FROM {tableName} WHERE (ChannelId = {channelIdList[0]} AND IsChecked = '{true}' {whereString}) {orderString}" - : $"SELECT Id FROM {tableName} WHERE (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND IsChecked = '{true}' {whereString}) {orderString}"; - } - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var contentId = GetInt(rdr, 0); - list.Add(contentId); - } - rdr.Close(); - } - return list; - } - - private List GetContentIdListChecked(string tableName, int channelId, string orderByFormatString, string whereString) - { - return GetContentIdListChecked(tableName, channelId, 0, orderByFormatString, whereString); - } - //private void UpdateIsChecked(string tableName, int siteId, int channelId, List contentIdList, int translateChannelId, bool isAdmin, string userName, bool isChecked, int checkedLevel, string reasons, bool isCheck) - //{ - // if (isChecked) - // { - // checkedLevel = 0; - // } - - // var checkDate = DateTime.Now; - - // foreach (var contentId in contentIdList) - // { - // var settingsXml = GetValue(tableName, contentId, ContentAttribute.SettingsXml); - // var attributes = TranslateUtils.ToNameValueCollection(settingsXml); - // attributes[ContentAttribute.CheckIsAdmin] = isAdmin.ToString(); - // attributes[ContentAttribute.CheckUserName] = userName; - // attributes[ContentAttribute.CheckCheckDate] = DateUtils.GetDateAndTimeString(checkDate); - // attributes[ContentAttribute.CheckReasons] = reasons; - - // string sqlString = - // $"UPDATE {tableName} SET IsChecked = '{isChecked}', CheckedLevel = {checkedLevel}, SettingsXML = '{TranslateUtils.NameValueCollectionToString(attributes)}' WHERE Id = {contentId}"; - // if (translateChannelId > 0) - // { - // sqlString = - // $"UPDATE {tableName} SET IsChecked = '{isChecked}', CheckedLevel = {checkedLevel}, SettingsXML = '{TranslateUtils.NameValueCollectionToString(attributes)}', ChannelId = {translateChannelId} WHERE Id = {contentId}"; - // } - // ExecuteNonQuery(sqlString); - - // var checkInfo = new ContentCheckInfo(0, tableName, siteId, channelId, contentId, isAdmin, userName, isChecked, checkedLevel, checkDate, reasons); - // DataProvider.ContentCheckDao.Insert(checkInfo); - // } - //} - - //private void UpdatePhotos(string tableName, int contentId, int photos) - //{ - // string sqlString = $"UPDATE {tableName} SET Photos = {photos} WHERE Id = {contentId}"; - // ExecuteNonQuery(sqlString); - //} - - //private int GetReferenceId(string tableName, int contentId, out string linkUrl, out int channelId) - //{ - // var referenceId = 0; - // channelId = 0; - // linkUrl = string.Empty; - // try - // { - // string sqlString = $"SELECT ReferenceId, ChannelId, LinkUrl FROM {tableName} WHERE Id = {contentId}"; - - // using (var rdr = ExecuteReader(sqlString)) - // { - // if (rdr.Read()) - // { - // referenceId = GetInt(rdr, 0); - // channelId = GetInt(rdr, 1); - // linkUrl = GetString(rdr, 2); - // } - // rdr.Close(); - // } - // } - // catch - // { - // // ignored - // } - // return referenceId; - //} - - //private string GetSqlStringByWhere(string tableName, int siteId, List channelIdList, string where, ETriState checkedState) - //{ - // if (channelIdList == null || channelIdList.Count == 0) - // { - // return null; - // } - - // var orderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByTaxisDesc); - - // var whereString = new StringBuilder("WHERE "); - - // whereString.Append( - // channelIdList.Count == 1 - // ? $"SiteId = {siteId} AND (ChannelId = {channelIdList[0]}) AND ({where}) " - // : $"SiteId = {siteId} AND (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)})) AND ({where}) "); - - // if (checkedState == ETriState.True) - // { - // whereString.Append("AND IsChecked='True' "); - // } - // else if (checkedState == ETriState.False) - // { - // whereString.Append("AND IsChecked='False' "); - // } - - // whereString.Append(orderByString); - - // return DataProvider.DatabaseDao.GetSelectSqlString(tableName, SqlUtils.Asterisk, whereString.ToString()); - //} - - //private string GetSqlString(string tableName, int channelId, ETriState checkedState) - //{ - // var orderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByTaxisDesc); - - // var whereString = new StringBuilder(); - // whereString.Append($"WHERE (ChannelId = {channelId}) "); - - // if (checkedState == ETriState.True) - // { - // whereString.Append("AND IsChecked='True' "); - // } - // else if (checkedState == ETriState.False) - // { - // whereString.Append("AND IsChecked='False'"); - // } - - // //whereString.Append(orderByString); - - // return DataProvider.DatabaseDao.GetSelectSqlString(tableName, SqlUtils.Asterisk, whereString.ToString(), orderByString); - //} - - //private string GetSqlString(string tableName, List channelIdList, ETriState checkedState) - //{ - // var orderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByTaxisDesc); - - // var whereString = new StringBuilder(); - - // whereString.Append(channelIdList.Count == 1 - // ? $"WHERE (ChannelId = {channelIdList[0]}) " - // : $"WHERE (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)})) "); - - // if (checkedState == ETriState.True) - // { - // whereString.Append("AND IsChecked='True' "); - // } - // else if (checkedState == ETriState.False) - // { - // whereString.Append("AND IsChecked='False'"); - // } - - // whereString.Append(orderByString); - - // return DataProvider.DatabaseDao.GetSelectSqlString(tableName, SqlUtils.Asterisk, whereString.ToString()); - //} - - //private List GetContentIdListBySiteId(string tableName, int siteId) - //{ - // var list = new List(); - - // string sqlString = $"SELECT Id FROM {tableName} WHERE SiteId = {siteId}"; - // using (var rdr = ExecuteReader(sqlString)) - // { - // while (rdr.Read()) - // { - // var contentId = GetInt(rdr, 0); - // list.Add(contentId); - // } - // rdr.Close(); - // } - // return list; - //} - - //private void DeleteContentsArchive(int siteId, string tableName, List contentIdList) - //{ - // if (!string.IsNullOrEmpty(tableName) && contentIdList != null && contentIdList.Count > 0) - // { - // string sqlString = - // $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; - // ExecuteNonQuery(sqlString); - // } - //} - - //private int GetContentId(string tableName, int channelId, string attributeName, string value) - //{ - // var contentId = 0; - // string sqlString = $"SELECT Id FROM {tableName} WHERE (ChannelId = {channelId} AND {attributeName} = '{value}')"; - - // using (var rdr = ExecuteReader(sqlString)) - // { - // if (rdr.Read()) - // { - // contentId = GetInt(rdr, 0); - // } - // rdr.Close(); - // } - // return contentId; - //} - - //private int GetCountChecked(string tableName, int channelId, int days) - //{ - // var whereString = string.Empty; - // if (days > 0) - // { - // whereString = "AND " + SqlUtils.GetDateDiffLessThanDays("AddDate", days.ToString()); - // } - // return GetCountChecked(tableName, channelId, whereString); - //} - - //private int GetCountChecked(string tableName, int channelId, string whereString) - //{ - // string sqlString = - // $"SELECT COUNT(*) AS TotalNum FROM {tableName} WHERE (ChannelId = {channelId} AND IsChecked = '{true}' {whereString})"; - - // return DataProvider.DatabaseDao.GetIntResult(sqlString); - //} - - //private int GetStlCountChecked(string tableName, List channelIdList, string whereString) - //{ - // if (channelIdList == null || channelIdList.Count == 0) - // { - // return 0; - // } - // var sqlWhereString = channelIdList.Count == 1 ? $"WHERE (ChannelId ={channelIdList[0]} AND IsChecked = '{true}' {whereString})" : $"WHERE (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND IsChecked = '{true}' {whereString})"; - - // string sqlString = $"SELECT COUNT(*) FROM {tableName} {sqlWhereString}"; - - // return DataProvider.DatabaseDao.GetIntResult(sqlString); - //} - - //private List GetContentIdListCheck(int siteId, int channelId, string tableName) - //{ - // var list = new List(); - - // string sqlString = - // $"SELECT Id FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelId} AND IsChecked = '{false}'"; - // using (var rdr = ExecuteReader(sqlString)) - // { - // while (rdr.Read()) - // { - // var contentId = GetInt(rdr, 0); - // list.Add(contentId); - // } - // rdr.Close(); - // } - // return list; - //} - - //private List GetContentIdListUnCheck(int siteId, int channelId, string tableName) - //{ - // var list = new List(); - - // string sqlString = - // $"SELECT Id FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelId} AND IsChecked = '{true}'"; - // using (var rdr = ExecuteReader(sqlString)) - // { - // while (rdr.Read()) - // { - // var contentId = GetInt(rdr, 0); - // list.Add(contentId); - // } - // rdr.Close(); - // } - // return list; - //} - - //private ContentInfo GetContentInfoNotTrash(string tableName, int contentId) - //{ - // ContentInfo info = null; - // if (contentId > 0) - // { - // if (!string.IsNullOrEmpty(tableName)) - // { - // string sqlWhere = $"WHERE ChannelId > 0 AND Id = {contentId}"; - // var sqlSelect = DataProvider.DatabaseDao.GetSelectSqlString(tableName, SqlUtils.Asterisk, sqlWhere); - - // using (var rdr = ExecuteReader(sqlSelect)) - // { - // if (rdr.Read()) - // { - // info = GetContentInfo(rdr); - // } - // rdr.Close(); - // } - // } - // } - - // return info; - //} - //private List GetContentIdListChecked(string tableName, int channelId, int totalNum, string orderByFormatString) - //{ - // return GetContentIdListChecked(tableName, channelId, totalNum, orderByFormatString, string.Empty); - //} - - //public int TrashContents(int siteId, string tableName, List contentIdList) - //{ - // if (!string.IsNullOrEmpty(tableName) && contentIdList != null && contentIdList.Count > 0) - // { - // string sqlString = - // $"UPDATE {tableName} SET ChannelId = -ChannelId, LastEditDate = {SqlUtils.GetComparableNow()} WHERE SiteId = {siteId} AND Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; - // return ExecuteNonQuery(sqlString); - // } - // return 0; - //} - - //public int TrashContentsByChannelId(int siteId, string tableName, int channelId) - //{ - // if (!string.IsNullOrEmpty(tableName)) - // { - // string sqlString = - // $"UPDATE {tableName} SET ChannelId = -ChannelId, LastEditDate = {SqlUtils.GetComparableNow()} WHERE SiteId = {siteId} AND ChannelId = {siteId}"; - // return ExecuteNonQuery(sqlString); - // } - // return 0; - //} - - //public int DeleteContents(int siteId, string tableName, List contentIdList) - //{ - // if (!string.IsNullOrEmpty(tableName) && contentIdList != null && contentIdList.Count > 0) - // { - // TagUtils.RemoveTags(siteId, contentIdList); - - // string sqlString = - // $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; - // return ExecuteNonQuery(sqlString); - // } - // return 0; - //} - - //public int DeleteContentsByChannelId(int siteId, string tableName, int channelId, List contentIdList) - //{ - // if (!string.IsNullOrEmpty(tableName)) - // { - // TagUtils.RemoveTags(siteId, contentIdList); - - // string sqlString = - // $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelId}"; - // return ExecuteNonQuery(sqlString); - // } - // return 0; - //} - - //public int RestoreContentsByTrash(int siteId, string tableName) - //{ - // if (!string.IsNullOrEmpty(tableName)) - // { - // string sqlString = - // $"UPDATE {tableName} SET ChannelId = -ChannelId, LastEditDate = {SqlUtils.GetComparableNow()} WHERE SiteId = {siteId} AND ChannelId < 0"; - // return ExecuteNonQuery(sqlString); - // } - // return 0; - //} - - //public string GetSqlString(string tableName, int siteId, int channelId, bool isSystemAdministrator, List owningChannelIdList, string searchType, string keyword, string dateFrom, string dateTo, bool isSearchChildren, ETriState checkedState) - //{ - // return GetSqlString(tableName, siteId, channelId, isSystemAdministrator, owningChannelIdList, searchType, keyword, dateFrom, dateTo, isSearchChildren, checkedState, false, false); - //} - //public string GetWritingSqlString(string writingUserName, string tableName, int siteId, List channelIdList, string searchType, string keyword, string dateFrom, string dateTo) - //{ - // if (channelIdList == null || channelIdList.Count == 0) - // { - // return null; - // } - - // var whereString = new StringBuilder($"WHERE WritingUserName = '{writingUserName}' "); - - // if (channelIdList.Count == 1) - // { - // whereString.AppendFormat("AND SiteId = {0} AND ChannelId = {1} ", siteId, channelIdList[0]); - // } - // else - // { - // whereString.AppendFormat("AND SiteId = {0} AND ChannelId IN ({1}) ", siteId, TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)); - // } - - // var dateString = string.Empty; - // if (!string.IsNullOrEmpty(dateFrom)) - // { - // dateString = $" AND AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))} "; - // } - // if (!string.IsNullOrEmpty(dateTo)) - // { - // dateString += $" AND AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo).AddDays(1))} "; - // } - - // if (string.IsNullOrEmpty(keyword)) - // { - // whereString.Append(dateString); - // } - // else - // { - // var list = TableMetadataManager.GetAllLowerAttributeNameList(tableName); - // if (list.Contains(searchType.ToLower())) - // { - // whereString.AppendFormat("AND ([{0}] LIKE '%{1}%') {2} ", searchType, keyword, dateString); - // } - // } - - // return DataProvider.DatabaseDao.GetSelectSqlString(tableName, SqlUtils.Asterisk, whereString.ToString()); - //} - } -} diff --git a/SiteServer.CMS/Provider/ContentGroupDao.cs b/SiteServer.CMS/Provider/ContentGroupDao.cs deleted file mode 100644 index ee8e47c97..000000000 --- a/SiteServer.CMS/Provider/ContentGroupDao.cs +++ /dev/null @@ -1,303 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.Utils; -using SiteServer.CMS.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Provider -{ - public class ContentGroupDao : DataProviderBase - { - public override string TableName => "siteserver_ContentGroup"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(ContentGroupInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(ContentGroupInfo.GroupName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(ContentGroupInfo.SiteId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(ContentGroupInfo.Taxis), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(ContentGroupInfo.Description), - DataType = DataType.Text - } - }; - - private const string SqlInsert = "INSERT INTO siteserver_ContentGroup (GroupName, SiteId, Taxis, Description) VALUES (@GroupName, @SiteId, @Taxis, @Description)"; - private const string SqlUpdate = "UPDATE siteserver_ContentGroup SET Description = @Description WHERE GroupName = @GroupName AND SiteId = @SiteId"; - private const string SqlDelete = "DELETE FROM siteserver_ContentGroup WHERE GroupName = @GroupName AND SiteId = @SiteId"; - - private const string ParmGroupName = "@GroupName"; - private const string ParmSiteId = "@SiteId"; - private const string ParmTaxis = "@Taxis"; - private const string ParmDescription = "@Description"; - - public void Insert(ContentGroupInfo contentGroup) - { - var maxTaxis = GetMaxTaxis(contentGroup.SiteId); - contentGroup.Taxis = maxTaxis + 1; - - var insertParms = new IDataParameter[] - { - GetParameter(ParmGroupName, DataType.VarChar, 255, contentGroup.GroupName), - GetParameter(ParmSiteId, DataType.Integer, contentGroup.SiteId), - GetParameter(ParmTaxis, DataType.Integer, contentGroup.Taxis), - GetParameter(ParmDescription, DataType.Text, contentGroup.Description) - }; - - ExecuteNonQuery(SqlInsert, insertParms); - } - - public void Update(ContentGroupInfo contentGroup) - { - var updateParms = new IDataParameter[] - { - GetParameter(ParmDescription, DataType.Text, contentGroup.Description), - GetParameter(ParmGroupName, DataType.VarChar, 255, contentGroup.GroupName), - GetParameter(ParmSiteId, DataType.Integer, contentGroup.SiteId) - }; - - ExecuteNonQuery(SqlUpdate, updateParms); - } - - public void Delete(string groupName, int siteId) - { - var contentGroupParms = new IDataParameter[] - { - GetParameter(ParmGroupName, DataType.VarChar, 255, groupName), - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - - ExecuteNonQuery(SqlDelete, contentGroupParms); - } - - public ContentGroupInfo GetContentGroupInfo(string groupName, int siteId) - { - ContentGroupInfo contentGroup = null; - - string sqlString = - $"SELECT GroupName, SiteId, Taxis, Description FROM siteserver_ContentGroup WHERE GroupName = @GroupName AND SiteId = {siteId}"; - - var selectParms = new IDataParameter[] - { - GetParameter(ParmGroupName, DataType.VarChar, 255, groupName) - }; - - using (var rdr = ExecuteReader(sqlString, selectParms)) - { - if (rdr.Read()) - { - var i = 0; - contentGroup = new ContentGroupInfo(GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i)); - } - rdr.Close(); - } - - return contentGroup; - } - - public bool IsExists(string groupName, int siteId) - { - var exists = false; - - string sqlString = - $"SELECT GroupName FROM siteserver_ContentGroup WHERE GroupName = @GroupName AND SiteId = {siteId}"; - - var selectParms = new IDataParameter[] - { - GetParameter(ParmGroupName, DataType.VarChar, 255, groupName) - }; - - using (var rdr = ExecuteReader(sqlString, selectParms)) - { - if (rdr.Read()) - { - exists = true; - } - rdr.Close(); - } - - return exists; - } - - public List GetContentGroupInfoList(int siteId) - { - var list = new List(); - string sqlString = - $"SELECT GroupName, SiteId, Taxis, Description FROM siteserver_ContentGroup WHERE SiteId = {siteId} ORDER BY Taxis DESC, GroupName"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var i = 0; - list.Add(new ContentGroupInfo(GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i))); - } - rdr.Close(); - } - - return list; - } - - public List GetGroupNameList(int siteId) - { - var list = new List(); - string sqlString = - $"SELECT GroupName FROM siteserver_ContentGroup WHERE SiteId = {siteId} ORDER BY Taxis DESC, GroupName"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - - return list; - } - - private int GetTaxis(int siteId, string groupName) - { - string sqlString = - $"SELECT Taxis FROM siteserver_ContentGroup WHERE (GroupName = @GroupName AND SiteId = {siteId})"; - - var selectParms = new IDataParameter[] - { - GetParameter(ParmGroupName, DataType.VarChar, 255, groupName) - }; - - return DataProvider.DatabaseDao.GetIntResult(sqlString, selectParms); - } - - private void SetTaxis(int siteId, string groupName, int taxis) - { - string sqlString = - $"UPDATE siteserver_ContentGroup SET Taxis = {taxis} WHERE (GroupName = @GroupName AND SiteId = {siteId})"; - var updateParms = new IDataParameter[] - { - GetParameter(ParmGroupName, DataType.VarChar, 255, groupName) - }; - ExecuteNonQuery(sqlString, updateParms); - } - - private int GetMaxTaxis(int siteId) - { - string sqlString = - $"SELECT MAX(Taxis) FROM siteserver_ContentGroup WHERE (SiteId = {siteId})"; - var maxTaxis = 0; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - maxTaxis = GetInt(rdr, 0); - } - rdr.Close(); - } - return maxTaxis; - } - - public bool UpdateTaxisToUp(int siteId, string groupName) - { - //Get Higher Taxis and ID - //string sqlString = - // $"SELECT TOP 1 GroupName, Taxis FROM siteserver_ContentGroup WHERE (Taxis > (SELECT Taxis FROM siteserver_ContentGroup WHERE GroupName = @GroupName AND SiteId = {siteId}) AND SiteId = {siteId}) ORDER BY Taxis"; - var sqlString = SqlUtils.ToTopSqlString("siteserver_ContentGroup", "GroupName, Taxis", - $"WHERE (Taxis > (SELECT Taxis FROM siteserver_ContentGroup WHERE GroupName = @GroupName AND SiteId = {siteId}) AND SiteId = {siteId})", - "ORDER BY Taxis", 1); - - var selectParms = new IDataParameter[] - { - GetParameter(ParmGroupName, DataType.VarChar, 255, groupName) - }; - var higherGroupName = string.Empty; - var higherTaxis = 0; - - using (var rdr = ExecuteReader(sqlString, selectParms)) - { - if (rdr.Read()) - { - higherGroupName = GetString(rdr, 0); - higherTaxis = GetInt(rdr, 1); - } - rdr.Close(); - } - - if (!string.IsNullOrEmpty(higherGroupName)) - { - //Get Taxis Of Selected ID - var selectedTaxis = GetTaxis(siteId, groupName); - - //Set The Selected Class Taxis To Higher Level - SetTaxis(siteId, groupName, higherTaxis); - //Set The Higher Class Taxis To Lower Level - SetTaxis(siteId, higherGroupName, selectedTaxis); - return true; - } - return false; - } - - public bool UpdateTaxisToDown(int siteId, string groupName) - { - //Get Lower Taxis and ID - //string sqlString = - // $"SELECT TOP 1 GroupName, Taxis FROM siteserver_ContentGroup WHERE (Taxis < (SELECT Taxis FROM siteserver_ContentGroup WHERE GroupName = @GroupName AND SiteId = {siteId}) AND SiteId = {siteId}) ORDER BY Taxis DESC"; - var sqlString = SqlUtils.ToTopSqlString("siteserver_ContentGroup", "GroupName, Taxis", - $"WHERE (Taxis < (SELECT Taxis FROM siteserver_ContentGroup WHERE GroupName = @GroupName AND SiteId = {siteId}) AND SiteId = {siteId})", - "ORDER BY Taxis DESC", 1); - - var selectParms = new IDataParameter[] - { - GetParameter(ParmGroupName, DataType.VarChar, 255, groupName) - }; - var lowerGroupName = string.Empty; - var lowerTaxis = 0; - - using (var rdr = ExecuteReader(sqlString, selectParms)) - { - if (rdr.Read()) - { - lowerGroupName = GetString(rdr, 0); - lowerTaxis = GetInt(rdr, 1); - } - rdr.Close(); - } - - if (!string.IsNullOrEmpty(lowerGroupName)) - { - //Get Taxis Of Selected Class - var selectedTaxis = GetTaxis(siteId, groupName); - - //Set The Selected Class Taxis To Lower Level - SetTaxis(siteId, groupName, lowerTaxis); - //Set The Lower Class Taxis To Higher Level - SetTaxis(siteId, lowerGroupName, selectedTaxis); - return true; - } - return false; - } - - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Provider/CountDao.cs b/SiteServer.CMS/Provider/CountDao.cs deleted file mode 100644 index 377c7391f..000000000 --- a/SiteServer.CMS/Provider/CountDao.cs +++ /dev/null @@ -1,170 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Provider -{ - public class CountDao : DataProviderBase - { - public override string TableName => "siteserver_Count"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(CountInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(CountInfo.RelatedTableName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(CountInfo.RelatedIdentity), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(CountInfo.CountType), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(CountInfo.CountNum), - DataType = DataType.Integer - } - }; - - private const string SqlSelectCountNum = "SELECT CountNum FROM siteserver_Count WHERE RelatedTableName = @RelatedTableName AND RelatedIdentity = @RelatedIdentity AND CountType = @CountType"; - - private const string SqlDeleteByRelatedTableName = "DELETE FROM siteserver_Count WHERE RelatedTableName = @RelatedTableName"; - - private const string SqlDeleteByIdentity = "DELETE FROM siteserver_Count WHERE RelatedTableName = @RelatedTableName AND RelatedIdentity = @RelatedIdentity"; - - private const string ParmRelatedTableName = "@RelatedTableName"; - private const string ParmRelatedIdentity = "@RelatedIdentity"; - private const string ParmCountType = "@CountType"; - private const string ParmCountNum = "@CountNum"; - - public void Insert(string relatedTableName, string relatedIdentity, ECountType countType, int countNum) - { - const string sqlString = "INSERT INTO siteserver_Count (RelatedTableName, RelatedIdentity, CountType, CountNum) VALUES (@RelatedTableName, @RelatedIdentity, @CountType, @CountNum)"; - - var insertParms = new IDataParameter[] - { - GetParameter(ParmRelatedTableName, DataType.VarChar, 255, relatedTableName), - GetParameter(ParmRelatedIdentity, DataType.VarChar, 255, relatedIdentity), - GetParameter(ParmCountType, DataType.VarChar, 50, ECountTypeUtils.GetValue(countType)), - GetParameter(ParmCountNum, DataType.Integer, countNum) - }; - - ExecuteNonQuery(sqlString, insertParms); - } - - public void AddCountNum(string relatedTableName, string relatedIdentity, ECountType countType) - { - var sqlString = $"UPDATE siteserver_Count SET {SqlUtils.ToPlusSqlString("CountNum")} WHERE RelatedTableName = @RelatedTableName AND RelatedIdentity = @RelatedIdentity AND CountType = @CountType"; - - var insertParms = new IDataParameter[] - { - GetParameter(ParmRelatedTableName, DataType.VarChar, 255, relatedTableName), - GetParameter(ParmRelatedIdentity, DataType.VarChar, 255, relatedIdentity), - GetParameter(ParmCountType, DataType.VarChar, 50, ECountTypeUtils.GetValue(countType)), - }; - - ExecuteNonQuery(sqlString, insertParms); - } - - public void DeleteByRelatedTableName(string relatedTableName) - { - var parms = new IDataParameter[] - { - GetParameter(ParmRelatedTableName, DataType.VarChar, 255, relatedTableName) - }; - - ExecuteNonQuery(SqlDeleteByRelatedTableName, parms); - } - - public void DeleteByIdentity(string relatedTableName, string relatedIdentity) - { - var parms = new IDataParameter[] - { - GetParameter(ParmRelatedTableName, DataType.VarChar, 255, relatedTableName), - GetParameter(ParmRelatedIdentity, DataType.VarChar, 255, relatedIdentity), - }; - - ExecuteNonQuery(SqlDeleteByIdentity, parms); - } - - public bool IsExists(string relatedTableName, string relatedIdentity, ECountType countType) - { - if (GetCountNum(relatedTableName, relatedIdentity, countType) == 0) - { - return false; - } - return true; - } - - public int GetCountNum(string relatedTableName, string relatedIdentity, ECountType countType) - { - var countNum = 0; - - var parms = new IDataParameter[] - { - GetParameter(ParmRelatedTableName, DataType.VarChar, 255, relatedTableName), - GetParameter(ParmRelatedIdentity, DataType.VarChar, 255, relatedIdentity), - GetParameter(ParmCountType, DataType.VarChar, 50, ECountTypeUtils.GetValue(countType)) - }; - - using (var rdr = ExecuteReader(SqlSelectCountNum, parms)) - { - if (rdr.Read()) - { - countNum = GetInt(rdr, 0); - } - rdr.Close(); - } - - return countNum; - } - - /// - /// 获取站点的统计数据 - /// - /// - /// - /// - /// - public int GetCountNum(string relatedTableName, int siteId, ECountType countType) - { - var countNum = 0; - - string sqlString = - $@"select sum(cou.CountNum) from siteserver_Count cou left join {relatedTableName} con on cou.RelatedIdentity = con.ID -where cou.RelatedTableName = '{relatedTableName}' -and con.SiteId = {siteId} -and cou.CountType = '{ECountTypeUtils.GetValue(countType)}'"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - countNum = GetInt(rdr, 0); - } - rdr.Close(); - } - return countNum; - } - } -} diff --git a/SiteServer.CMS/Provider/DatabaseDao.cs b/SiteServer.CMS/Provider/DatabaseDao.cs deleted file mode 100644 index 918c31f8f..000000000 --- a/SiteServer.CMS/Provider/DatabaseDao.cs +++ /dev/null @@ -1,1594 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Data; -using System.Data.SqlClient; -using System.IO; -using System.Text; -using MySql.Data.MySqlClient; -using Npgsql; -using Oracle.ManagedDataAccess.Client; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Provider -{ - public class DatabaseDao : DataProviderBase - { - public virtual void DeleteDbLog() - { - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - ExecuteSql("PURGE MASTER LOGS BEFORE DATE_SUB( NOW( ), INTERVAL 3 DAY)"); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - var databaseName = SqlUtils.GetDatabaseNameFormConnectionString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString); - //检测数据库版本 - const string sqlCheck = "SELECT SERVERPROPERTY('productversion')"; - var versions = ExecuteScalar(sqlCheck).ToString(); - //MM.nn.bbbb.rr - //8 -- 2000 - //9 -- 2005 - //10 -- 2008 - var version = 8; - var arr = versions.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); - if (arr.Length > 0) - { - version = TranslateUtils.ToInt(arr[0], 8); - } - if (version < 10) - { - //2000,2005 - string sql = $"BACKUP LOG [{databaseName}] WITH NO_LOG"; - ExecuteNonQuery(sql); - } - else - { - //2008+ - string sql = - $@"ALTER DATABASE [{databaseName}] SET RECOVERY SIMPLE;DBCC shrinkfile ([{databaseName}_log], 1); ALTER DATABASE [{databaseName}] SET RECOVERY FULL; "; - ExecuteNonQuery(sql); - } - } - } - - public void ExecuteSql(string sqlString) - { - if (string.IsNullOrEmpty(sqlString)) return; - - ExecuteNonQuery(sqlString); - } - - public void ExecuteSql(List sqlList) - { - if (sqlList == null || sqlList.Count <= 0) return; - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - foreach (var sql in sqlList) - { - ExecuteNonQuery(trans, sql); - } - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - } - - public void ExecuteSqlInFile(string pathToScriptFile, StringBuilder errorBuilder) - { - IDbConnection connection; - - if (false == File.Exists(pathToScriptFile)) - { - throw new Exception("File " + pathToScriptFile + " does not exists"); - } - using (Stream stream = File.OpenRead(pathToScriptFile)) - { - var reader = new StreamReader(stream, Encoding.UTF8); - - connection = GetConnection(); - - var command = SqlUtils.GetIDbCommand(); - - connection.Open(); - command.Connection = connection; - command.CommandType = CommandType.Text; - - string sqlString; - while (null != (sqlString = SqlUtils.ReadNextSqlString(reader))) - { - command.CommandText = sqlString; - try - { - command.ExecuteNonQuery(); - } - catch (Exception ex) - { - errorBuilder.Append($@" - sql:{sqlString} - message:{ex.Message} - "); - } - } - - reader.Close(); - } - connection.Close(); - } - - public void ExecuteSqlInFile(string pathToScriptFile, string tableName, StringBuilder errorBuilder) - { - IDbConnection connection; - - if (false == File.Exists(pathToScriptFile)) - { - throw new Exception("File " + pathToScriptFile + " does not exists"); - } - using (Stream stream = File.OpenRead(pathToScriptFile)) - { - var reader = new StreamReader(stream, Encoding.Default); - - connection = GetConnection(); - - var command = SqlUtils.GetIDbCommand(); - - connection.Open(); - command.Connection = connection; - command.CommandType = CommandType.Text; - - string sqlString; - while (null != (sqlString = SqlUtils.ReadNextSqlString(reader))) - { - sqlString = string.Format(sqlString, tableName); - command.CommandText = sqlString; - try - { - command.ExecuteNonQuery(); - } - catch (Exception ex) - { - errorBuilder.Append($@" - sql:{sqlString} - message:{ex.Message} - "); - } - } - - reader.Close(); - } - connection.Close(); - } - - public int GetIntResult(string connectionString, string sqlString) - { - if (string.IsNullOrEmpty(connectionString)) - { - connectionString = ConnectionString; - } - - var count = 0; - - using (var conn = GetConnection(connectionString)) - { - conn.Open(); - using (var rdr = ExecuteReader(conn, sqlString)) - { - if (rdr.Read()) - { - count = GetInt(rdr, 0); - } - rdr.Close(); - } - } - return count; - } - - public int GetIntResult(string sqlString) - { - var count = 0; - - using (var conn = GetConnection()) - { - conn.Open(); - using (var rdr = ExecuteReader(conn, sqlString)) - { - if (rdr.Read()) - { - count = GetInt(rdr, 0); - } - rdr.Close(); - } - } - return count; - } - - public int GetIntResult(string sqlString, IDataParameter[] parms) - { - var count = 0; - - using (var conn = GetConnection()) - { - conn.Open(); - using (var rdr = ExecuteReader(conn, sqlString, parms)) - { - if (rdr.Read()) - { - count = GetInt(rdr, 0); - } - rdr.Close(); - } - } - return count; - } - - public List GetIntList(string sqlString) - { - var list = new List(); - - using (var conn = GetConnection()) - { - conn.Open(); - using (var rdr = ExecuteReader(conn, sqlString)) - { - while (rdr.Read()) - { - list.Add(GetInt(rdr, 0)); - } - rdr.Close(); - } - } - return list; - } - - public List GetIntList(string connectionString, string sqlString) - { - if (string.IsNullOrEmpty(connectionString)) - { - connectionString = ConnectionString; - } - - var list = new List(); - - using (var conn = GetConnection(connectionString)) - { - conn.Open(); - using (var rdr = ExecuteReader(conn, sqlString)) - { - while (rdr.Read()) - { - list.Add(GetInt(rdr, 0)); - } - rdr.Close(); - } - } - return list; - } - - public string GetString(string connectionString, string sqlString) - { - if (string.IsNullOrEmpty(connectionString)) - { - connectionString = ConnectionString; - } - - var retval = string.Empty; - - using (var conn = GetConnection(connectionString)) - { - conn.Open(); - using (var rdr = ExecuteReader(conn, sqlString)) - { - if (rdr.Read()) - { - retval = GetString(rdr, 0); - } - rdr.Close(); - } - } - return retval; - } - - public string GetString(string sqlString) - { - var value = string.Empty; - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - value = GetString(rdr, 0); - } - rdr.Close(); - } - - return value; - } - - public List GetStringList(string sqlString) - { - var list = new List(); - - using (var conn = GetConnection()) - { - conn.Open(); - using (var rdr = ExecuteReader(conn, sqlString)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - } - return list; - } - - public DateTime GetDateTime(string sqlString) - { - var datetime = DateTime.MinValue; - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - datetime = GetDateTime(rdr, 0); - } - rdr.Close(); - } - - return datetime; - } - - public DateTime GetDateTime(string sqlString, IDataParameter[] parms) - { - var datetime = DateTime.MinValue; - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - datetime = GetDateTime(rdr, 0); - } - rdr.Close(); - } - - return datetime; - } - - public DataSet GetDataSetByWhereString(string tableName, string whereString) - { - var sqlSelect = GetSelectSqlString(tableName, SqlUtils.Asterisk, whereString); - var dataset = ExecuteDataset(sqlSelect); - return dataset; - } - - public IDataReader GetDataReader(string connectionString, string sqlString) - { - if (string.IsNullOrEmpty(connectionString)) - { - connectionString = ConnectionString; - } - - return string.IsNullOrEmpty(sqlString) ? null : ExecuteReader(connectionString, sqlString); - } - - public IDataReader GetDataSource(string sqlString) - { - if (string.IsNullOrEmpty(sqlString)) return null; - var enumerable = ExecuteReader(sqlString); - return enumerable; - } - - public IDataReader GetDataSource(string connectionString, string sqlString) - { - if (string.IsNullOrEmpty(connectionString)) - { - connectionString = ConnectionString; - } - - if (string.IsNullOrEmpty(sqlString)) return null; - var enumerable = ExecuteReader(connectionString, sqlString); - return enumerable; - } - - public DataSet GetDataSet(string connectionString, string sqlString) - { - if (string.IsNullOrEmpty(connectionString)) - { - connectionString = ConnectionString; - } - - if (string.IsNullOrEmpty(sqlString)) return null; - var dataset = ExecuteDataset(connectionString, sqlString); - return dataset; - } - - public DataSet GetDataSet(string sqlString) - { - if (string.IsNullOrEmpty(sqlString)) return null; - var dataset = ExecuteDataset(sqlString); - return dataset; - } - - public void ReadResultsToNameValueCollection(IDataReader rdr, NameValueCollection attributes) - { - for (var i = 0; i < rdr.FieldCount; i++) - { - var columnName = rdr.GetName(i); - var value = Convert.ToString(rdr.GetValue(i)); - if (!string.IsNullOrEmpty(value)) - { - value = PageUtils.UnFilterSql(value); - } - attributes.Set(columnName, value); - } - } - - public int GetPageTotalCount(string sqlString) - { - var temp = sqlString.ToLower(); - var pos = temp.LastIndexOf("order by", StringComparison.Ordinal); - if (pos > -1) - sqlString = sqlString.Substring(0, pos); - - // Add new ORDER BY info if SortKeyField is specified - //if (!string.IsNullOrEmpty(sortField) && addCustomSortInfo) - // SelectCommand += " ORDER BY " + SortField; - - var cmdText = WebConfigUtils.DatabaseType == DatabaseType.Oracle - ? $"SELECT COUNT(*) FROM ({sqlString})" - : $"SELECT COUNT(*) FROM ({sqlString}) AS T0"; - return GetIntResult(cmdText); - } - - public string GetStlPageSqlString(string sqlString, string orderString, int totalCount, int itemsPerPage, int currentPageIndex) - { - var retval = string.Empty; - - var temp = sqlString.ToLower(); - var pos = temp.LastIndexOf("order by", StringComparison.Ordinal); - if (pos > -1) - sqlString = sqlString.Substring(0, pos); - - var recordsInLastPage = itemsPerPage; - - // Calculate the correspondent number of pages - var lastPage = totalCount / itemsPerPage; - var remainder = totalCount % itemsPerPage; - if (remainder > 0) - lastPage++; - var pageCount = lastPage; - - if (remainder > 0) - recordsInLastPage = remainder; - - var recsToRetrieve = itemsPerPage; - if (currentPageIndex == pageCount - 1) - recsToRetrieve = recordsInLastPage; - - orderString = orderString.ToUpper(); - var orderStringReverse = orderString.Replace(" DESC", " DESC2"); - orderStringReverse = orderStringReverse.Replace(" ASC", " DESC"); - orderStringReverse = orderStringReverse.Replace(" DESC2", " ASC"); - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $@" -SELECT * FROM ( - SELECT * FROM ( - SELECT * FROM ({sqlString}) AS t0 {orderString} LIMIT {itemsPerPage * (currentPageIndex + 1)} - ) AS t1 {orderStringReverse} LIMIT {recsToRetrieve} -) AS t2 {orderString}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $@" -SELECT * FROM ( - SELECT TOP {recsToRetrieve} * FROM ( - SELECT TOP {itemsPerPage * (currentPageIndex + 1)} * FROM ({sqlString}) AS t0 {orderString} - ) AS t1 {orderStringReverse} -) AS t2 {orderString}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $@" -SELECT * FROM ( - SELECT * FROM ( - SELECT * FROM ({sqlString}) AS t0 {orderString} LIMIT {itemsPerPage * (currentPageIndex + 1)} - ) AS t1 {orderStringReverse} LIMIT {recsToRetrieve} -) AS t2 {orderString}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $@" -SELECT * FROM ( - SELECT * FROM ( - SELECT * FROM ({sqlString}) WHERE ROWNUM <= {itemsPerPage * (currentPageIndex + 1)} {orderString} - ) WHERE ROWNUM <= {recsToRetrieve} {orderStringReverse} -) {orderString}"; - } - - // if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - // { - // return $@" - //SELECT * FROM ( - // SELECT * FROM ( - // SELECT * FROM ({sqlString}) AS t0 {orderString} LIMIT {itemsPerPage * (currentPageIndex + 1)} - // ) AS t1 {orderStringReverse} LIMIT {recsToRetrieve} - //) AS t2 {orderString}"; - // } - // else - // { - // return $@" - //SELECT * FROM ( - // SELECT TOP {recsToRetrieve} * FROM ( - // SELECT TOP {itemsPerPage * (currentPageIndex + 1)} * FROM ({sqlString}) AS t0 {orderString} - // ) AS t1 {orderStringReverse} - //) AS t2 {orderString}"; - // } - - return retval; - } - - //public void Install(StringBuilder errorBuilder) - //{ - // var sqlPath = PathUtils.GetInstallSqlFilePath(WebConfigUtils.DatabaseType); - // DataProvider.DatabaseDao.ExecuteSqlInFile(sqlPath, errorBuilder); - // DataProvider.TableDao.CreateAllAuxiliaryTableIfNotExists(); - //} - - //public void Upgrade(DatabaseType databaseType, StringBuilder errorBuilder) - //{ - // var filePathUpgrade = PathUtils.GetUpgradeSqlFilePath(databaseType, false); - // var filePathUpgradeTable = PathUtils.GetUpgradeSqlFilePath(databaseType, true); - - // DataProvider.DatabaseDao.ExecuteSqlInFile(filePathUpgrade, errorBuilder); - - // if (FileUtils.IsFileExists(filePathUpgradeTable)) - // { - // try - // { - // var tableList = DataProvider.TableDao.GetAuxiliaryTableListCreatedInDb(); - // foreach (var table in tableList) - // { - // DataProvider.DatabaseDao.ExecuteSqlInFile(filePathUpgradeTable, table.TableName, errorBuilder); - // } - // } - // catch - // { - // // ignored - // } - // } - - // DataProvider.TableDao.CreateAllAuxiliaryTableIfNotExists(); - //} - - public bool ConnectToServer(DatabaseType databaseType, string connectionStringWithoutDatabaseName, out List databaseNameList, out string errorMessage) - { - errorMessage = string.Empty; - databaseNameList = new List(); - try - { - databaseNameList = GetDatabaseNameList(databaseType, connectionStringWithoutDatabaseName); - return true; - } - catch (Exception e) - { - errorMessage = e.Message; - } - - return false; - } - - public bool IsTableExists(string tableName) - { - bool exists; - - if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - tableName = tableName.ToUpper(); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.MySql || WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - tableName = tableName.ToLower(); - } - - try - { - // ANSI SQL way. Works in PostgreSQL, MSSQL, MySQL. - if (WebConfigUtils.DatabaseType != DatabaseType.Oracle) - { - exists = (int)ExecuteScalar($"select case when exists((select * from information_schema.tables where table_name = '{tableName}')) then 1 else 0 end") == 1; - } - else - { - exists = GetIntResult($"SELECT COUNT(*) FROM ALL_OBJECTS WHERE OBJECT_TYPE = 'TABLE' AND OWNER = '{WebConfigUtils.ConnectionStringUserId.ToUpper()}' and OBJECT_NAME = '{tableName}'") == 1; - } - } - catch - { - try - { - // Other RDBMS. Graceful degradation - exists = true; - ExecuteNonQuery($"select 1 from {tableName} where 1 = 0"); - } - catch - { - exists = false; - } - } - - return exists; - } - - public void CreatePluginTable(string pluginId, string tableName, List tableColumns) - { - var sqlBuilder = new StringBuilder(); - - try - { - sqlBuilder.Append($@"CREATE TABLE {tableName} (").AppendLine(); - - sqlBuilder.Append($"Id {SqlUtils.GetAutoIncrementDataType()},").AppendLine(); - - foreach (var tableColumn in tableColumns) - { - if (string.IsNullOrEmpty(tableColumn.AttributeName) || - StringUtils.EqualsIgnoreCase(tableColumn.AttributeName, "Id")) continue; - - var columnSql = SqlUtils.GetColumnSqlString(tableColumn.DataType, tableColumn.AttributeName, - tableColumn.DataLength); - if (!string.IsNullOrEmpty(columnSql)) - { - sqlBuilder.Append(columnSql).Append(",").AppendLine(); - } - } - - //添加主键及索引 - sqlBuilder.Append(WebConfigUtils.DatabaseType == DatabaseType.MySql - ? @"PRIMARY KEY (Id)" - : $@"CONSTRAINT PK_{tableName} PRIMARY KEY (Id)").AppendLine(); - - sqlBuilder.Append(WebConfigUtils.DatabaseType == DatabaseType.MySql - ? ") ENGINE=InnoDB DEFAULT CHARSET=utf8" - : ")"); - - ExecuteNonQuery(sqlBuilder.ToString()); - - TableColumnManager.ClearCache(); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(pluginId, ex, sqlBuilder.ToString()); - } - } - - public void AlterPluginTable(string pluginId, string tableName, List tableColumns) - { - var isAltered = false; - var columnNameList = TableColumnManager.GetTableColumnNameListLowercase(tableName); - foreach (var tableColumn in tableColumns) - { - if (columnNameList.Contains(tableColumn.AttributeName.ToLower())) continue; - - var columnSqlString = SqlUtils.GetColumnSqlString(tableColumn.DataType, tableColumn.AttributeName, tableColumn.DataLength); - var sqlString = SqlUtils.GetAddColumnsSqlString(tableName, columnSqlString); - - try - { - DataProvider.DatabaseDao.ExecuteSql(sqlString); - isAltered = true; - } - catch (Exception ex) - { - LogUtils.AddErrorLog(pluginId, ex, sqlString); - } - } - - if (isAltered) - { - TableColumnManager.ClearCache(); - } - } - - public void CreateSystemTable(string tableName, List tableColumns) - { - try - { - var sqlBuilder = new StringBuilder(); - - sqlBuilder.Append($@"CREATE TABLE {tableName} (").AppendLine(); - - var primaryKeyColumns = new List(); - foreach (var tableColumn in tableColumns) - { - if (string.IsNullOrEmpty(tableColumn.ColumnName)) continue; - - if (tableColumn.IsIdentity) - { - primaryKeyColumns.Add(tableColumn); - sqlBuilder.Append($@"{tableColumn.ColumnName} {SqlUtils.GetAutoIncrementDataType()},").AppendLine(); - } - else - { - if (tableColumn.IsPrimaryKey) - { - primaryKeyColumns.Add(tableColumn); - } - - var columnSql = SqlUtils.GetColumnSqlString(tableColumn.DataType, tableColumn.ColumnName, - tableColumn.Length); - if (!string.IsNullOrEmpty(columnSql)) - { - sqlBuilder.Append(columnSql).Append(",").AppendLine(); - } - } - } - - foreach (var tableColumn in primaryKeyColumns) - { - sqlBuilder.Append(WebConfigUtils.DatabaseType == DatabaseType.MySql - ? $@"PRIMARY KEY ({tableColumn.ColumnName})," - : $@"CONSTRAINT PK_{tableName}_{tableColumn.ColumnName} PRIMARY KEY ({tableColumn.ColumnName}),"); - } - if (primaryKeyColumns.Count > 0) - { - sqlBuilder.Length--; - } - - sqlBuilder.AppendLine().Append(WebConfigUtils.DatabaseType == DatabaseType.MySql - ? ") ENGINE=InnoDB DEFAULT CHARSET=utf8" - : ")"); - - ExecuteNonQuery(sqlBuilder.ToString()); - - TableColumnManager.ClearCache(); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(ex, tableName); - } - } - - public void AlterSystemTable(string tableName, List tableColumns) - { - var list = new List(); - - var columnNameList = TableColumnManager.GetTableColumnNameListLowercase(tableName); - foreach (var tableColumn in tableColumns) - { - if (columnNameList.Contains(tableColumn.ColumnName.ToLower())) continue; - - list.Add(SqlUtils.GetAddColumnsSqlString(tableName, SqlUtils.GetColumnSqlString(tableColumn.DataType, tableColumn.ColumnName, tableColumn.Length))); - } - - if (list.Count > 0) - { - foreach (var sqlString in list) - { - try - { - DataProvider.DatabaseDao.ExecuteSql(sqlString); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(ex, sqlString); - } - } - - TableColumnManager.ClearCache(); - } - } - - public List GetDatabaseNameList(DatabaseType databaseType, string connectionStringWithoutDatabaseName) - { - if (string.IsNullOrEmpty(connectionStringWithoutDatabaseName)) - { - connectionStringWithoutDatabaseName = ConnectionString; - } - - var list = new List(); - - if (databaseType == DatabaseType.MySql) - { - var connection = new MySqlConnection(connectionStringWithoutDatabaseName); - var command = new MySqlCommand("show databases", connection); - - connection.Open(); - - var rdr = command.ExecuteReader(); - - while (rdr.Read()) - { - var dbName = rdr.GetString(0); - if (dbName == null) continue; - if (dbName != "information_schema" && - dbName != "mysql" && - dbName != "performance_schema" && - dbName != "sakila" && - dbName != "sys" && - dbName != "world") - { - list.Add(dbName); - } - } - - connection.Close(); - } - else if (databaseType == DatabaseType.SqlServer) - { - var connection = new SqlConnection(connectionStringWithoutDatabaseName); - var command = new SqlCommand("select name from master..sysdatabases order by name asc", connection); - - connection.Open(); - - connection.ChangeDatabase("master"); - - var dr = command.ExecuteReader(); - - while (dr.Read()) - { - var dbName = dr["name"] as string; - if (dbName == null) continue; - if (dbName != "master" && - dbName != "msdb" && - dbName != "tempdb" && - dbName != "model") - { - list.Add(dbName); - } - } - - connection.Close(); - } - else if (databaseType == DatabaseType.PostgreSql) - { - var connection = new NpgsqlConnection(connectionStringWithoutDatabaseName); - var command = - new NpgsqlCommand( - "select datname from pg_database where datistemplate = false order by datname asc", - connection); - - connection.Open(); - - var dr = command.ExecuteReader(); - - while (dr.Read()) - { - var dbName = dr["datname"] as string; - if (dbName == null) continue; - - list.Add(dbName); - } - - connection.Close(); - } - else if (databaseType == DatabaseType.Oracle) - { - var connection = new OracleConnection(connectionStringWithoutDatabaseName); - connection.Open(); - connection.Close(); - } - - return list; - } - - public Dictionary GetTablesAndViewsDictionary(string connectionString, string databaseName) - { - if (string.IsNullOrEmpty(connectionString)) - { - connectionString = ConnectionString; - } - - string sqlString = - $"select name, id from [{databaseName}].dbo.sysobjects where type in ('U','V') and category<>2 Order By Name"; - - var dict = new Dictionary(); - - using (var rdr = ExecuteReader(connectionString, sqlString)) - { - while (rdr.Read()) - { - var name = GetString(rdr, 0); - var id = GetInt(rdr, 1); - if (!string.IsNullOrEmpty(name)) - { - dict[name] = id; - } - } - rdr.Close(); - } - - return dict; - } - - //public string GetTableId(string connectionString, string databaseName, string tableName) - //{ - // if (WebConfigUtils.DatabaseType == DatabaseType.MySql) return tableName; - - // if (string.IsNullOrEmpty(connectionString)) - // { - // connectionString = ConnectionString; - // } - - // var tableId = SqlUtils.Cache_GetTableIDCache(databaseName, tableName); - - // if (string.IsNullOrEmpty(tableId)) - // { - // string sqlString = - // $"select id from [{databaseName}].dbo.sysobjects where type in ('U','V') and category<>2 and name='{tableName}'"; - - // using (var rdr = ExecuteReader(connectionString, sqlString)) - // { - // if (rdr.Read()) - // { - // tableId = GetString(rdr, 0); - // SqlUtils.Cache_CacheTableID(databaseName, tableName, tableId); - // } - // rdr.Close(); - // } - // } - - // return tableId; - //} - - //public string GetTableName(string databaseName, string tableId) - //{ - // if (WebConfigUtils.DatabaseType == DatabaseType.MySql) return tableId; - - // var tableName = string.Empty; - // string cmd = - // $"select O.name from [{databaseName}].dbo.sysobjects O, [{databaseName}].dbo.sysusers U where O.id={tableId} and U.uid=O.uid"; - - // using (var rdr = ExecuteReader(cmd)) - // { - // if (rdr.Read()) - // { - // tableName = GetString(rdr, 0); - // } - // rdr.Close(); - // } - // return tableName; - //} - - //public string GetTableName(string connectionString, string databaseName, string tableId) - //{ - // if (WebConfigUtils.DatabaseType == DatabaseType.MySql) return tableId; - - // if (string.IsNullOrEmpty(connectionString)) - // { - // connectionString = ConnectionString; - // } - - // var tableName = string.Empty; - // string sqlString = - // $"select O.name from [{databaseName}].dbo.sysobjects O, [{databaseName}].dbo.sysusers U where O.id={tableId} and U.uid=O.uid"; - - // using (var rdr = ExecuteReader(connectionString, sqlString)) - // { - // if (rdr.Read()) - // { - // tableName = GetString(rdr, 0); - // } - // rdr.Close(); - // } - // return tableName; - //} - - public string GetSqlServerDefaultConstraintName(string tableName, string columnName) - { - var defaultConstraintName = string.Empty; - string sqlString = - $"select b.name from syscolumns a,sysobjects b where a.id=object_id('{tableName}') and b.id=a.cdefault and a.name='{columnName}' and b.name like 'DF%'"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - defaultConstraintName = GetString(rdr, 0); - } - rdr.Close(); - } - return defaultConstraintName; - } - - public List GetTableColumnInfoListLowercase(string connectionString, string tableName) - { - if (string.IsNullOrEmpty(connectionString)) - { - connectionString = ConnectionString; - } - - var databaseName = SqlUtils.GetDatabaseNameFormConnectionString(WebConfigUtils.DatabaseType, connectionString); - - List list = null; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - list = GetMySqlColumnsLowercase(connectionString, databaseName, tableName); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - list = GetSqlServerColumnsLowercase(connectionString, databaseName, tableName); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - list = GetPostgreSqlColumnsLowercase(connectionString, databaseName, tableName); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - list = GetOracleColumnsLowercase(connectionString, tableName); - } - - return list; - } - - public string GetOracleSequence(string tableName, string idColumnName) - { - var cacheKey = $"BaiRong.Core.Provider.{nameof(DatabaseDao)}.{nameof(GetOracleSequence)}.{tableName}.{idColumnName}"; - var sequence = CacheUtils.Get(cacheKey); - if (string.IsNullOrEmpty(sequence)) - { - using (var conn = new OracleConnection(ConnectionString)) - { - conn.Open(); - var cmd = new OracleCommand - { - CommandType = CommandType.Text, - CommandText = $"SELECT DATA_DEFAULT FROM all_tab_cols WHERE OWNER = '{WebConfigUtils.ConnectionStringUserId.ToUpper()}' and table_name = '{tableName.ToUpper()}' AND column_name = '{idColumnName.ToUpper()}'", - Connection = conn, - InitialLONGFetchSize = -1 - }; - - using (var rdr = cmd.ExecuteReader()) - { - if (rdr.Read()) - { - var dataDefault = rdr.GetValue(0).ToString(); - - if (dataDefault.Contains(".nextval")) - { - sequence = dataDefault.Replace(".nextval", string.Empty); - } - } - rdr.Close(); - } - } - - CacheUtils.Insert(cacheKey, sequence); - } - - return sequence; - } - - private List GetOracleColumnsLowercase(string connectionString, string tableName) - { - var owner = SqlUtils.GetConnectionStringUserId(connectionString).ToUpper(); - tableName = tableName.ToUpper(); - - var list = new List(); - var sqlString = - $"SELECT COLUMN_NAME, DATA_TYPE, DATA_PRECISION, DATA_SCALE, CHAR_LENGTH, DATA_DEFAULT FROM all_tab_cols WHERE OWNER = '{owner}' and table_name = '{tableName}' and user_generated = 'YES' ORDER BY COLUMN_ID"; - using (var rdr = ExecuteReader(connectionString, sqlString)) - { - while (rdr.Read()) - { - var columnName = (rdr.IsDBNull(0) ? string.Empty : rdr.GetString(0)).ToLower(); - var dataType = SqlUtils.ToDataType(DatabaseType.Oracle, rdr.IsDBNull(1) ? string.Empty : rdr.GetString(1)); - var percision = rdr.IsDBNull(2) ? 0 : rdr.GetInt32(2); - var scale = rdr.IsDBNull(3) ? 0 : rdr.GetInt32(3); - var charLength = rdr.IsDBNull(4) ? 0 : rdr.GetInt32(4); - var dataDefault = rdr.IsDBNull(5) ? string.Empty : rdr.GetString(5); - if (dataType == DataType.Integer) - { - if (scale == 2) - { - dataType = DataType.Decimal; - } - else if (percision == 1) - { - dataType = DataType.Boolean; - } - } - var isIdentity = dataDefault.Contains(".nextval"); - - var info = new TableColumnInfo(columnName, dataType, charLength, false, isIdentity); - list.Add(info); - } - rdr.Close(); - } - - sqlString = - $@"select distinct cu.column_name from all_cons_columns cu inner join all_constraints au -on cu.constraint_name = au.constraint_name -and au.constraint_type = 'P' and cu.OWNER = '{owner}' and cu.table_name = '{tableName}'"; - - using (var rdr = ExecuteReader(connectionString, sqlString)) - { - while (rdr.Read()) - { - var columnName = (rdr.IsDBNull(0) ? string.Empty : rdr.GetString(0)).ToLower(); - - foreach (var tableColumnInfo in list) - { - if (columnName == tableColumnInfo.ColumnName) - { - tableColumnInfo.IsPrimaryKey = true; - break; - } - } - } - rdr.Close(); - } - - return list; - } - - private List GetPostgreSqlColumnsLowercase(string connectionString, string databaseName, string tableName) - { - var list = new List(); - string sqlString = - $"SELECT COLUMN_NAME, UDT_NAME, CHARACTER_MAXIMUM_LENGTH, COLUMN_DEFAULT FROM information_schema.columns WHERE table_catalog = '{databaseName}' AND table_name = '{tableName.ToLower()}' ORDER BY ordinal_position"; - using (var rdr = ExecuteReader(connectionString, sqlString)) - { - while (rdr.Read()) - { - var columnName = (rdr.IsDBNull(0) ? string.Empty : rdr.GetString(0)).ToLower(); - var dataType = SqlUtils.ToDataType(DatabaseType.PostgreSql, rdr.IsDBNull(1) ? string.Empty : rdr.GetString(1)); - var length = rdr.IsDBNull(2) ? 0 : rdr.GetInt32(2); - var columnDefault = rdr.IsDBNull(3) ? string.Empty : rdr.GetString(3); - - var isIdentity = columnDefault.StartsWith("nextval("); - - var info = new TableColumnInfo(columnName, dataType, length, false, isIdentity); - list.Add(info); - } - rdr.Close(); - } - - sqlString = - $"select column_name, constraint_name from information_schema.key_column_usage where table_catalog = '{databaseName}' and table_name = '{tableName.ToLower()}';"; - using (var rdr = ExecuteReader(connectionString, sqlString)) - { - while (rdr.Read()) - { - var columnName = (rdr.IsDBNull(0) ? string.Empty : rdr.GetString(0)).ToLower(); - var constraintName = rdr.IsDBNull(1) ? string.Empty : rdr.GetString(1); - - var isPrimary = constraintName.StartsWith("pk"); - - if (isPrimary) - { - foreach (var tableColumnInfo in list) - { - if (columnName == tableColumnInfo.ColumnName) - { - tableColumnInfo.IsPrimaryKey = true; - break; - } - } - } - } - rdr.Close(); - } - - return list; - } - - private List GetSqlServerColumnsLowercase(string connectionString, string databaseName, string tableName) - { - var list = new List(); - - var isIdentityExist = false; - var tableId = string.Empty; - string sqlStringTableId = - $"select id from [{databaseName}].dbo.sysobjects where type in ('U','V') and category<>2 and name='{tableName}'"; - - using (var rdr = ExecuteReader(connectionString, sqlStringTableId)) - { - if (rdr.Read()) - { - tableId = GetString(rdr, 0); - } - rdr.Close(); - } - - string sqlString = - $"select C.name, T.name, C.length, C.colstat, case when C.autoval is null then 0 else 1 end, SC.text, (select CForgin.name from [{databaseName}].dbo.sysreferences Sr,[{databaseName}].dbo.sysobjects O,[{databaseName}].dbo.syscolumns CForgin where Sr.fkeyid={tableId} and Sr.fkey1=C.colid and Sr.rkeyid=O.id and CForgin.id=O.id and CForgin.colid=Sr.rkey1), (select O.name from [{databaseName}].dbo.sysreferences Sr,[{databaseName}].dbo.sysobjects O,[{databaseName}].dbo.syscolumns CForgin where Sr.fkeyid={tableId} and Sr.fkey1=C.colid and Sr.rkeyid=O.id and CForgin.id=O.id and CForgin.colid=Sr.rkey1), (select Sr.rkeyid from [{databaseName}].dbo.sysreferences Sr,[{databaseName}].dbo.sysobjects O,[{databaseName}].dbo.syscolumns CForgin where Sr.fkeyid={tableId} and Sr.fkey1=C.colid and Sr.rkeyid=O.id and CForgin.id=O.id and CForgin.colid=Sr.rkey1) from [{databaseName}].dbo.systypes T, [{databaseName}].dbo.syscolumns C left join [{databaseName}].dbo.syscomments SC on C.cdefault=SC.id where C.id={tableId} and C.xtype=T.xusertype order by C.colid"; - - using (var rdr = ExecuteReader(connectionString, sqlString)) - { - while (rdr.Read()) - { - var columnName = (rdr.IsDBNull(0) ? string.Empty : rdr.GetString(0)).ToLower(); - if (columnName == "msrepl_tran_version") //sqlserver 发布订阅字段,忽略 - { - continue; - } - var dataType = SqlUtils.ToDataType(DatabaseType.SqlServer, rdr.IsDBNull(1) ? string.Empty : rdr.GetString(1)); - var length = Convert.ToInt32(rdr.GetValue(2)); - if (dataType == DataType.VarChar) - { - length = Convert.ToInt32(length / 2); - } - var isPrimaryKeyInt = Convert.ToInt32(rdr.GetValue(3)); - var isIdentityInt = Convert.ToInt32(rdr.GetValue(4)); - - var isPrimaryKey = isPrimaryKeyInt == 1; - var isIdentity = isIdentityInt == 1 || StringUtils.EqualsIgnoreCase(columnName, "Id"); - //sqlserver 2005 返回isIdentity结果不正确,so 在此假设所有ID字段为Idenity字段 - if (isIdentity) - { - isIdentityExist = true; - } - - var info = new TableColumnInfo(columnName, dataType, length, isPrimaryKey, isIdentity); - list.Add(info); - } - rdr.Close(); - } - - if (!isIdentityExist) - { - var sqlIdentity = "select name from syscolumns where id = object_id(N'" + tableName + - "') and COLUMNPROPERTY(id, name,'IsIdentity')= 1"; - var clName = ""; - using (var rdr = ExecuteReader(sqlIdentity)) - { - if (rdr.Read()) - { - clName = (rdr.IsDBNull(0) ? string.Empty : rdr.GetString(0)).ToLower(); - } - rdr.Close(); - } - - foreach (var info in list) - { - if (clName == info.ColumnName) - { - info.IsIdentity = true; - } - } - } - - return list; - } - - private List GetMySqlColumnsLowercase(string connectionString, string databaseName, string tableName) - { - var list = new List(); - - string sqlString = - $"select COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, COLUMN_KEY from information_schema.columns where table_schema = '{databaseName}' and table_name = '{tableName}' order by table_name,ordinal_position; "; - using (var rdr = ExecuteReader(connectionString, sqlString)) - { - while (rdr.Read()) - { - var columnName = (rdr.IsDBNull(0) ? string.Empty : rdr.GetString(0)).ToLower(); - var dataType = SqlUtils.ToDataType(DatabaseType.MySql, rdr.IsDBNull(1) ? string.Empty : rdr.GetString(1)); - var length = rdr.IsDBNull(2) || dataType == DataType.Text ? 0 : Convert.ToInt32(rdr.GetValue(2)); - var isPrimaryKey = Convert.ToString(rdr.GetValue(3)) == "PRI"; - - var isIdentity = isPrimaryKey && StringUtils.EqualsIgnoreCase(columnName, "Id"); - - var info = new TableColumnInfo(columnName, dataType, length, isPrimaryKey, isIdentity); - list.Add(info); - } - rdr.Close(); - } - - return list; - } - - public string GetSelectSqlString(string tableName, string columns, string whereString) - { - return GetSelectSqlString(tableName, 0, columns, whereString, null); - } - - public string GetSelectSqlString(string tableName, string columns, string whereString, string orderByString) - { - return GetSelectSqlString(tableName, 0, columns, whereString, orderByString); - } - - public string GetSelectSqlString(string tableName, int totalNum, string columns, string whereString, string orderByString) - { - return GetSelectSqlString(ConnectionString, tableName, totalNum, columns, whereString, orderByString); - } - - public string GetSelectSqlString(string connectionString, string tableName, int totalNum, string columns, string whereString, string orderByString) - { - return GetSelectSqlString(ConnectionString, tableName, totalNum, columns, whereString, orderByString, string.Empty); - } - - public string GetSelectSqlString(string connectionString, string tableName, int totalNum, string columns, string whereString, string orderByString, string joinString) - { - if (!string.IsNullOrEmpty(whereString)) - { - whereString = StringUtils.ReplaceStartsWith(whereString.Trim(), "AND", string.Empty); - if (!StringUtils.StartsWithIgnoreCase(whereString, "WHERE ")) - { - whereString = "WHERE " + whereString; - } - } - - if (!string.IsNullOrEmpty(joinString)) - { - whereString = joinString + " " + whereString; - } - - return SqlUtils.ToTopSqlString(tableName, columns, whereString, orderByString, totalNum); - } - - public string GetSelectSqlString(string tableName, int startNum, int totalNum, string columns, string whereString, string orderByString) - { - return GetSelectSqlString(ConnectionString, tableName, startNum, totalNum, columns, whereString, orderByString); - } - - public string GetSelectSqlString(string connectionString, string tableName, int startNum, int totalNum, string columns, string whereString, string orderByString) - { - if (string.IsNullOrEmpty(connectionString)) - { - connectionString = ConnectionString; - } - - if (startNum <= 1) - { - return GetSelectSqlString(connectionString, tableName, totalNum, columns, whereString, orderByString); - } - - string countSqlString = $"SELECT Count(*) FROM {tableName} {whereString}"; - var allCount = DataProvider.DatabaseDao.GetIntResult(connectionString, countSqlString); - if (totalNum == 0) - { - totalNum = allCount; - } - - if (startNum > allCount) return string.Empty; - - var topNum = startNum + totalNum - 1; - - if (allCount < topNum) - { - totalNum = allCount - startNum + 1; - if (totalNum < 1) - { - return GetSelectSqlString(connectionString, tableName, totalNum, columns, whereString, orderByString); - } - } - - var orderByStringOpposite = GetOrderByStringOpposite(orderByString); - - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $@" -SELECT {columns} FROM ( - SELECT {columns} FROM ( - SELECT {columns} FROM {tableName} {whereString} {orderByString} LIMIT {topNum} - ) AS tmp {orderByStringOpposite} LIMIT {totalNum} -) AS tmp {orderByString} -"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $@" -SELECT {columns} -FROM (SELECT TOP {totalNum} {columns} - FROM (SELECT TOP {topNum} {columns} - FROM {tableName} {whereString} {orderByString}) tmp - {orderByStringOpposite}) tmp -{orderByString} -"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $@" -SELECT {columns} FROM ( - SELECT {columns} FROM ( - SELECT {columns} FROM {tableName} {whereString} {orderByString} LIMIT {topNum} - ) AS tmp {orderByStringOpposite} LIMIT {totalNum} -) AS tmp {orderByString} -"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $@" -SELECT {columns} FROM ( - SELECT {columns} FROM ( - SELECT {columns} FROM {tableName} {whereString} {orderByString} LIMIT {topNum} - ) AS tmp {orderByStringOpposite} LIMIT {totalNum} -) AS tmp {orderByString} -"; - } - - return retval; - } - - public string GetSelectSqlStringByQueryString(string connectionString, string queryString, int totalNum, string orderByString) - { - if (totalNum == 0 && string.IsNullOrEmpty(orderByString)) - { - return queryString; - } - string sqlString; - if (totalNum > 0) - { - sqlString = SqlUtils.ToTopSqlString(queryString, orderByString, totalNum); - - //sqlString = WebConfigUtils.DatabaseType == DatabaseType.MySql ? $"SELECT * FROM ({queryString}) AS tmp {orderByString} LIMIT {totalNum}" : $"SELECT TOP {totalNum} * FROM ({queryString}) tmp {orderByString}"; - } - else - { - sqlString = string.IsNullOrEmpty(orderByString) ? queryString : $"SELECT * FROM ({queryString}) {orderByString}"; - } - return sqlString; - } - - - public string GetSelectSqlStringByQueryString(string connectionString, string queryString, int startNum, int totalNum, string orderByString) - { - if (string.IsNullOrEmpty(connectionString)) - { - connectionString = ConnectionString; - } - - if (startNum == 1 && totalNum == 0 && string.IsNullOrEmpty(orderByString)) - { - return queryString; - } - //queryString = queryString.Trim().ToUpper(); - if (queryString.LastIndexOf(" ORDER ", StringComparison.Ordinal) != -1) - { - if (string.IsNullOrEmpty(orderByString)) - { - orderByString = queryString.Substring(queryString.LastIndexOf(" ORDER ", StringComparison.Ordinal) + 1); - } - queryString = queryString.Substring(0, queryString.LastIndexOf(" ORDER ", StringComparison.Ordinal)); - } - orderByString = ParseOrderByString(orderByString); - - if (startNum <= 1) - { - return GetSelectSqlStringByQueryString(connectionString, queryString, totalNum, orderByString); - } - - string countSqlString = $"SELECT Count(*) FROM ({queryString}) tmp"; - var count = DataProvider.DatabaseDao.GetIntResult(connectionString, countSqlString); - if (totalNum == 0) - { - totalNum = count; - } - - if (startNum > count) return string.Empty; - - var topNum = startNum + totalNum - 1; - - if (count < topNum) - { - totalNum = count - startNum + 1; - if (totalNum < 1) - { - return GetSelectSqlStringByQueryString(connectionString, queryString, totalNum, orderByString); - } - } - - var orderByStringOpposite = GetOrderByStringOpposite(orderByString); - - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $@" -SELECT * FROM ( - SELECT * FROM ( - SELECT * FROM ({queryString}) tmp {orderByString} LIMIT {topNum} - ) AS tmp {orderByStringOpposite} LIMIT {totalNum} -) AS tmp {orderByString}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $@" -SELECT * -FROM (SELECT TOP {totalNum} * - FROM (SELECT TOP {topNum} * - FROM ({queryString}) tmp {orderByString}) tmp - {orderByStringOpposite}) tmp -{orderByString} -"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $@" -SELECT * FROM ( - SELECT * FROM ( - SELECT * FROM ({queryString}) tmp {orderByString} LIMIT {topNum} - ) AS tmp {orderByStringOpposite} LIMIT {totalNum} -) AS tmp {orderByString}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $@" -SELECT * -FROM (SELECT TOP {totalNum} * - FROM (SELECT TOP {topNum} * - FROM ({queryString}) tmp {orderByString}) tmp - {orderByStringOpposite}) tmp -{orderByString} -"; - } - - return retval; - } - - private static string ParseOrderByString(string orderByString) - { - if (string.IsNullOrEmpty(orderByString)) return orderByString; - - orderByString = orderByString.ToUpper().Trim(); - if (!orderByString.StartsWith("ORDER BY")) - { - orderByString = "ORDER BY " + orderByString; - } - if (!orderByString.EndsWith("DESC") && !orderByString.EndsWith("ASC")) - { - orderByString = orderByString + " ASC"; - } - return orderByString; - } - - private string GetOrderByStringOpposite(string orderByString) - { - var retval = string.Empty; - if (!string.IsNullOrEmpty(orderByString)) - { - retval = orderByString.Replace(" DESC", " DESC_OPPOSITE").Replace(" ASC", " DESC").Replace(" DESC_OPPOSITE", " ASC"); - } - return retval; - } - - public List GetDropColumnsSqlString(string tableName, string attributeName) - { - var sqlList = new List(); - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - sqlList.Add($"ALTER TABLE [{tableName}] DROP COLUMN [{attributeName}]"); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - var defaultConstraintName = GetSqlServerDefaultConstraintName(tableName, attributeName); - if (!string.IsNullOrEmpty(defaultConstraintName)) - { - sqlList.Add($"ALTER TABLE [{tableName}] DROP CONSTRAINT [{defaultConstraintName}]"); - } - sqlList.Add($"ALTER TABLE [{tableName}] DROP COLUMN [{attributeName}]"); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - sqlList.Add($"ALTER TABLE [{tableName}] DROP COLUMN [{attributeName}]"); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - sqlList.Add($"ALTER TABLE {tableName} DROP COLUMN {attributeName}"); - } - - return sqlList; - } - } -} - diff --git a/SiteServer.CMS/Provider/DbCacheDao.cs b/SiteServer.CMS/Provider/DbCacheDao.cs deleted file mode 100644 index 7ce1be83f..000000000 --- a/SiteServer.CMS/Provider/DbCacheDao.cs +++ /dev/null @@ -1,206 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Provider -{ - public class DbCacheDao : DataProviderBase - { - public override string TableName => "siteserver_DbCache"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = "Id", - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = "CacheKey", - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = "CacheValue", - DataType = DataType.VarChar, - Length = 500 - }, - new TableColumnInfo - { - ColumnName = "AddDate", - DataType = DataType.DateTime - } - }; - - private const string SqlSelectValue = "SELECT CacheValue FROM siteserver_DbCache WHERE CacheKey = @CacheKey"; - - private const string SqlSelectCount = "SELECT COUNT(*) FROM siteserver_DbCache"; - - private const string SqlInsert = "INSERT INTO siteserver_DbCache (CacheKey, CacheValue, AddDate) VALUES (@CacheKey, @CacheValue, @AddDate)"; - - private const string SqlDelete = "DELETE FROM siteserver_DbCache WHERE CacheKey = @CacheKey"; - - private const string SqlDeleteAll = "DELETE FROM siteserver_DbCache"; - - private const string ParmCacheKey = "@CacheKey"; - private const string ParmCacheValue = "@CacheValue"; - private const string ParmAddDate = "@AddDate"; - - public void RemoveAndInsert(string cacheKey, string cacheValue) - { - if (string.IsNullOrEmpty(cacheKey)) return; - - DeleteExcess90Days(); - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - var removeParams = new IDataParameter[] - { - GetParameter(ParmCacheKey, DataType.VarChar, 200, cacheKey) - }; - - ExecuteNonQuery(trans, SqlDelete, removeParams); - - var insertParms = new IDataParameter[] - { - GetParameter(ParmCacheKey, DataType.VarChar, 200, cacheKey), - GetParameter(ParmCacheValue, DataType.VarChar, 500, cacheValue), - GetParameter(ParmAddDate, DataType.DateTime, DateTime.Now) - }; - - ExecuteNonQuery(trans, SqlInsert, insertParms); - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - } - - public void Clear() - { - ExecuteNonQuery(SqlDeleteAll); - } - - public bool IsExists(string cacheKey) - { - var retval = false; - - var parms = new IDataParameter[] - { - GetParameter(ParmCacheKey, DataType.VarChar, 200, cacheKey) - }; - - using (var rdr = ExecuteReader(SqlSelectValue, parms)) - { - if (rdr.Read()) - { - retval = true; - } - rdr.Close(); - } - return retval; - } - - public string GetValue(string cacheKey) - { - var retval = string.Empty; - - var parms = new IDataParameter[] - { - GetParameter(ParmCacheKey, DataType.VarChar, 200, cacheKey) - }; - - using (var rdr = ExecuteReader(SqlSelectValue, parms)) - { - if (rdr.Read()) - { - retval = GetString(rdr, 0); - } - rdr.Close(); - } - return retval; - } - - public string GetValueAndRemove(string cacheKey) - { - var retval = string.Empty; - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - var parms = new IDataParameter[] - { - GetParameter(ParmCacheKey, DataType.VarChar, 200, cacheKey) - }; - - using (var rdr = ExecuteReader(trans, SqlSelectValue, parms)) - { - if (rdr.Read()) - { - retval = GetString(rdr, 0); - } - rdr.Close(); - } - - var removeParams = new IDataParameter[] - { - GetParameter(ParmCacheKey, DataType.VarChar, 200, cacheKey) - }; - - ExecuteNonQuery(trans, SqlDelete, removeParams); - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - - return retval; - } - - public int GetCount() - { - var count = 0; - using (var rdr = ExecuteReader(SqlSelectCount)) - { - if (rdr.Read()) - { - count = GetInt(rdr, 0); - } - rdr.Close(); - } - return count; - } - - public void DeleteExcess90Days() - { - ExecuteNonQuery("DELETE FROM siteserver_DbCache WHERE " + SqlUtils.GetDateDiffGreatThanDays("AddDate", 90.ToString())); - } - } -} diff --git a/SiteServer.CMS/Provider/DepartmentDao.cs b/SiteServer.CMS/Provider/DepartmentDao.cs deleted file mode 100644 index 2af00b80e..000000000 --- a/SiteServer.CMS/Provider/DepartmentDao.cs +++ /dev/null @@ -1,633 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using System.Text; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Provider -{ - public class DepartmentDao : DataProviderBase - { - public override string TableName => "siteserver_Department"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(DepartmentInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(DepartmentInfo.DepartmentName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(DepartmentInfo.Code), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(DepartmentInfo.ParentId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(DepartmentInfo.ParentsPath), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(DepartmentInfo.ParentsCount), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(DepartmentInfo.ChildrenCount), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(DepartmentInfo.IsLastNode), - DataType = DataType.VarChar, - Length = 18 - }, - new TableColumnInfo - { - ColumnName = nameof(DepartmentInfo.Taxis), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(DepartmentInfo.AddDate), - DataType = DataType.DateTime - }, - new TableColumnInfo - { - ColumnName = nameof(DepartmentInfo.Summary), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(DepartmentInfo.CountOfAdmin), - DataType = DataType.Integer - } - }; - - private const string SqlSelect = "SELECT Id, DepartmentName, Code, ParentID, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, Taxis, AddDate, Summary, CountOfAdmin FROM siteserver_Department WHERE Id = @Id"; - - private const string SqlSelectAll = "SELECT Id, DepartmentName, Code, ParentID, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, Taxis, AddDate, Summary, CountOfAdmin FROM siteserver_Department ORDER BY TAXIS"; - - private const string SqlSelectCount = "SELECT COUNT(*) FROM siteserver_Department WHERE ParentID = @ParentID"; - - private const string SqlUpdate = "UPDATE siteserver_Department SET DepartmentName = @DepartmentName, Code = @Code, ParentsPath = @ParentsPath, ParentsCount = @ParentsCount, ChildrenCount = @ChildrenCount, IsLastNode = @IsLastNode, Summary = @Summary, CountOfAdmin = @CountOfAdmin WHERE Id = @Id"; - - private const string ParmId = "@Id"; - private const string ParmName = "@DepartmentName"; - private const string ParmCode = "@Code"; - private const string ParmParentId = "@ParentID"; - private const string ParmParentsPath = "@ParentsPath"; - private const string ParmParentsCount = "@ParentsCount"; - private const string ParmChildrenCount = "@ChildrenCount"; - private const string ParmIsLastNode = "@IsLastNode"; - private const string ParmTaxis = "@Taxis"; - private const string ParmAddDate = "@AddDate"; - private const string ParmSummary = "@Summary"; - private const string ParmCountOfAdmin = "@CountOfAdmin"; - - private void InsertWithTrans(DepartmentInfo parentInfo, DepartmentInfo departmentInfo, IDbTransaction trans) - { - if (parentInfo != null) - { - departmentInfo.ParentsPath = parentInfo.ParentsPath + "," + parentInfo.Id; - departmentInfo.ParentsCount = parentInfo.ParentsCount + 1; - - var maxTaxis = GetMaxTaxisByParentPath(departmentInfo.ParentsPath); - if (maxTaxis == 0) - { - maxTaxis = parentInfo.Taxis; - } - departmentInfo.Taxis = maxTaxis + 1; - } - else - { - departmentInfo.ParentsPath = "0"; - departmentInfo.ParentsCount = 0; - var maxTaxis = GetMaxTaxisByParentPath("0"); - departmentInfo.Taxis = maxTaxis + 1; - } - - var sqlInsert = "INSERT INTO siteserver_Department (DepartmentName, Code, ParentID, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, Taxis, AddDate, Summary, CountOfAdmin) VALUES (@DepartmentName, @Code, @ParentID, @ParentsPath, @ParentsCount, @ChildrenCount, @IsLastNode, @Taxis, @AddDate, @Summary, @CountOfAdmin)"; - - var insertParms = new IDataParameter[] - { - GetParameter(ParmName, DataType.VarChar, 255, departmentInfo.DepartmentName), - GetParameter(ParmCode, DataType.VarChar, 50, departmentInfo.Code), - GetParameter(ParmParentId, DataType.Integer, departmentInfo.ParentId), - GetParameter(ParmParentsPath, DataType.VarChar, 255, departmentInfo.ParentsPath), - GetParameter(ParmParentsCount, DataType.Integer, departmentInfo.ParentsCount), - GetParameter(ParmChildrenCount, DataType.Integer, 0), - GetParameter(ParmIsLastNode, DataType.VarChar, 18, true.ToString()), - GetParameter(ParmTaxis, DataType.Integer, departmentInfo.Taxis), - GetParameter(ParmAddDate, DataType.DateTime, departmentInfo.AddDate), - GetParameter(ParmSummary, DataType.VarChar, 255, departmentInfo.Summary), - GetParameter(ParmCountOfAdmin, DataType.Integer, departmentInfo.CountOfAdmin) - }; - - string sqlString = - $"UPDATE siteserver_Department SET {SqlUtils.ToPlusSqlString("Taxis")} WHERE (Taxis >= {departmentInfo.Taxis})"; - ExecuteNonQuery(trans, sqlString); - - departmentInfo.Id = ExecuteNonQueryAndReturnId(TableName, nameof(DepartmentInfo.Id), trans, sqlInsert, insertParms); - - if (!string.IsNullOrEmpty(departmentInfo.ParentsPath)) - { - sqlString = $"UPDATE siteserver_Department SET {SqlUtils.ToPlusSqlString("ChildrenCount")} WHERE Id IN ({PageUtils.FilterSql(departmentInfo.ParentsPath)})"; - - ExecuteNonQuery(trans, sqlString); - } - - sqlString = $"UPDATE siteserver_Department SET IsLastNode = '{false}' WHERE ParentID = {departmentInfo.ParentId}"; - - ExecuteNonQuery(trans, sqlString); - - //sqlString = - // $"UPDATE siteserver_Department SET IsLastNode = '{true}' WHERE (Id IN (SELECT TOP 1 Id FROM siteserver_Department WHERE ParentID = {departmentInfo.ParentId} ORDER BY Taxis DESC))"; - - sqlString = - $"UPDATE siteserver_Department SET IsLastNode = '{true}' WHERE (Id IN ({SqlUtils.ToInTopSqlString("siteserver_Department", "Id", $"WHERE ParentID = {departmentInfo.ParentId}", "ORDER BY Taxis DESC", 1)}))"; - - ExecuteNonQuery(trans, sqlString); - - DepartmentManager.ClearCache(); - } - - private void UpdateSubtractChildrenCount(string parentsPath, int subtractNum) - { - if (!string.IsNullOrEmpty(parentsPath)) - { - var sqlString = string.Concat("UPDATE siteserver_Department SET ChildrenCount = ChildrenCount - ", subtractNum, " WHERE Id IN (", PageUtils.FilterSql(parentsPath) , ")"); - ExecuteNonQuery(sqlString); - - DepartmentManager.ClearCache(); - } - } - - private void TaxisSubtract(int selectedId) - { - var departmentInfo = GetDepartmentInfo(selectedId); - if (departmentInfo == null) return; - //Get Lower Taxis and Id - int lowerId; - int lowerChildrenCount; - string lowerParentsPath; - // var sqlString = @"SELECT TOP 1 Id, ChildrenCount, ParentsPath - //FROM siteserver_Department - //WHERE (ParentID = @ParentID) AND (Id <> @Id) AND (Taxis < @Taxis) - //ORDER BY Taxis DESC"; - - var sqlString = SqlUtils.ToTopSqlString("siteserver_Department", "Id, ChildrenCount, ParentsPath", - "WHERE (ParentID = @ParentID) AND (Id <> @Id) AND (Taxis < @Taxis)", - "ORDER BY Taxis DESC", 1); - - var parms = new IDataParameter[] - { - GetParameter(ParmParentId, DataType.Integer, departmentInfo.ParentId), - GetParameter(ParmId, DataType.Integer, departmentInfo.Id), - GetParameter(ParmTaxis, DataType.Integer, departmentInfo.Taxis), - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - lowerId = GetInt(rdr, 0); - lowerChildrenCount = GetInt(rdr, 1); - lowerParentsPath = GetString(rdr, 2); - } - else - { - return; - } - rdr.Close(); - } - - - var lowerNodePath = string.Concat(lowerParentsPath, ",", lowerId); - var selectedNodePath = string.Concat(departmentInfo.ParentsPath, ",", departmentInfo.Id); - - SetTaxisSubtract(selectedId, selectedNodePath, lowerChildrenCount + 1); - SetTaxisAdd(lowerId, lowerNodePath, departmentInfo.ChildrenCount + 1); - - UpdateIsLastNode(departmentInfo.ParentId); - } - - private void TaxisAdd(int selectedId) - { - var departmentInfo = GetDepartmentInfo(selectedId); - if (departmentInfo == null) return; - //Get Higher Taxis and Id - int higherId; - int higherChildrenCount; - string higherParentsPath; - // var sqlString = @"SELECT TOP 1 Id, ChildrenCount, ParentsPath - //FROM siteserver_Department - //WHERE (ParentID = @ParentID) AND (Id <> @Id) AND (Taxis > @Taxis) - //ORDER BY Taxis"; - - var sqlString = SqlUtils.ToTopSqlString("siteserver_Department", "Id, ChildrenCount, ParentsPath", - "WHERE (ParentID = @ParentID) AND (Id <> @Id) AND (Taxis > @Taxis)", - "ORDER BY Taxis", 1); - - var parms = new IDataParameter[] - { - GetParameter(ParmParentId, DataType.Integer, departmentInfo.ParentId), - GetParameter(ParmId, DataType.Integer, departmentInfo.Id), - GetParameter(ParmTaxis, DataType.Integer, departmentInfo.Taxis) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - higherId = GetInt(rdr, 0); - higherChildrenCount = GetInt(rdr, 1); - higherParentsPath = GetString(rdr, 2); - } - else - { - return; - } - rdr.Close(); - } - - - var higherNodePath = string.Concat(higherParentsPath, ",", higherId); - var selectedNodePath = string.Concat(departmentInfo.ParentsPath, ",", departmentInfo.Id); - - SetTaxisAdd(selectedId, selectedNodePath, higherChildrenCount + 1); - SetTaxisSubtract(higherId, higherNodePath, departmentInfo.ChildrenCount + 1); - - UpdateIsLastNode(departmentInfo.ParentId); - } - - private void SetTaxisAdd(int id, string parentsPath, int addNum) - { - var path = PageUtils.FilterSql(parentsPath); - string sqlString = - $"UPDATE siteserver_Department SET Taxis = Taxis + {addNum} WHERE Id = {id} OR ParentsPath = '{path}' OR ParentsPath LIKE '{path},%'"; - - ExecuteNonQuery(sqlString); - - DepartmentManager.ClearCache(); - } - - private void SetTaxisSubtract(int id, string parentsPath, int subtractNum) - { - var path = PageUtils.FilterSql(parentsPath); - string sqlString = - $"UPDATE siteserver_Department SET Taxis = Taxis - {subtractNum} WHERE Id = {id} OR ParentsPath = '{path}' OR ParentsPath LIKE '{path},%'"; - - ExecuteNonQuery(sqlString); - - DepartmentManager.ClearCache(); - } - - private void UpdateIsLastNode(int parentId) - { - if (parentId > 0) - { - var sqlString = "UPDATE siteserver_Department SET IsLastNode = @IsLastNode WHERE ParentID = @ParentID"; - - var parms = new IDataParameter[] - { - GetParameter(ParmIsLastNode, DataType.VarChar, 18, false.ToString()), - GetParameter(ParmParentId, DataType.Integer, parentId) - }; - - ExecuteNonQuery(sqlString, parms); - - //sqlString = - // $"UPDATE siteserver_Department SET IsLastNode = '{true.ToString()}' WHERE (Id IN (SELECT TOP 1 Id FROM siteserver_Department WHERE ParentID = {parentId} ORDER BY Taxis DESC))"; - - sqlString = - $"UPDATE siteserver_Department SET IsLastNode = '{true}' WHERE (Id IN ({SqlUtils.ToInTopSqlString("siteserver_Department", "Id", $"WHERE ParentID = {parentId}", "ORDER BY Taxis DESC", 1)}))"; - - ExecuteNonQuery(sqlString); - } - } - - private int GetMaxTaxisByParentPath(string parentPath) - { - var sqlString = string.Concat("SELECT MAX(Taxis) AS MaxTaxis FROM siteserver_Department WHERE (ParentsPath = '", PageUtils.FilterSql(parentPath), "') OR (ParentsPath LIKE '", PageUtils.FilterSql(parentPath), ",%')"); - var maxTaxis = 0; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - maxTaxis = GetInt(rdr, 0); - } - rdr.Close(); - } - return maxTaxis; - } - - public int Insert(DepartmentInfo departmentInfo) - { - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - var parentDepartmentInfo = GetDepartmentInfo(departmentInfo.ParentId); - - InsertWithTrans(parentDepartmentInfo, departmentInfo, trans); - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - - DepartmentManager.ClearCache(); - - return departmentInfo.Id; - } - - public void Update(DepartmentInfo departmentInfo) - { - var updateParms = new IDataParameter[] - { - GetParameter(ParmName, DataType.VarChar, 255, departmentInfo.DepartmentName), - GetParameter(ParmCode, DataType.VarChar, 50, departmentInfo.Code), - GetParameter(ParmParentsPath, DataType.VarChar, 255, departmentInfo.ParentsPath), - GetParameter(ParmParentsCount, DataType.Integer, departmentInfo.ParentsCount), - GetParameter(ParmChildrenCount, DataType.Integer, departmentInfo.ChildrenCount), - GetParameter(ParmIsLastNode, DataType.VarChar, 18, departmentInfo.IsLastNode.ToString()), - GetParameter(ParmSummary, DataType.VarChar, 255, departmentInfo.Summary), - GetParameter(ParmCountOfAdmin, DataType.Integer, departmentInfo.CountOfAdmin), - GetParameter(ParmId, DataType.Integer, departmentInfo.Id) - }; - - ExecuteNonQuery(SqlUpdate, updateParms); - - DepartmentManager.ClearCache(); - } - - public void UpdateTaxis(int selectedId, bool isSubtract) - { - if (isSubtract) - { - TaxisSubtract(selectedId); - } - else - { - TaxisAdd(selectedId); - } - } - - public void UpdateCountOfAdmin() - { - var idList = DepartmentManager.GetDepartmentIdList(); - foreach (var departmentId in idList) - { - var count = DataProvider.AdministratorDao.GetCountByDepartmentId(departmentId); - string sqlString = $"UPDATE {TableName} SET CountOfAdmin = {count} WHERE Id = {departmentId}"; - ExecuteNonQuery(sqlString); - } - DepartmentManager.ClearCache(); - } - - public void Delete(int id) - { - var departmentInfo = GetDepartmentInfo(id); - if (departmentInfo != null) - { - var idList = new List(); - if (departmentInfo.ChildrenCount > 0) - { - idList = GetIdListForDescendant(id); - } - idList.Add(id); - - string sqlString = - $"DELETE FROM siteserver_Department WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; - - int deletedNum; - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - deletedNum = ExecuteNonQuery(trans, sqlString); - - if (deletedNum > 0) - { - string sqlStringTaxis = - $"UPDATE siteserver_Department SET Taxis = Taxis - {deletedNum} WHERE (Taxis > {departmentInfo.Taxis})"; - ExecuteNonQuery(trans, sqlStringTaxis); - } - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - UpdateIsLastNode(departmentInfo.ParentId); - UpdateSubtractChildrenCount(departmentInfo.ParentsPath, deletedNum); - } - - DepartmentManager.ClearCache(); - } - - private DepartmentInfo GetDepartmentInfo(int id) - { - DepartmentInfo departmentInfo = null; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, id) - }; - - using (var rdr = ExecuteReader(SqlSelect, parms)) - { - if (rdr.Read()) - { - var i = 0; - departmentInfo = new DepartmentInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetBool(rdr, i++), GetInt(rdr, i++), GetDateTime(rdr, i++), GetString(rdr, i++), GetInt(rdr, i)); - } - rdr.Close(); - } - return departmentInfo; - } - - private List GetDepartmentInfoList() - { - var list = new List(); - - using (var rdr = ExecuteReader(SqlSelectAll)) - { - while (rdr.Read()) - { - var i = 0; - var departmentInfo = new DepartmentInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetBool(rdr, i++), GetInt(rdr, i++), GetDateTime(rdr, i++), GetString(rdr, i++), GetInt(rdr, i)); - list.Add(departmentInfo); - } - rdr.Close(); - } - return list; - } - - public int GetNodeCount(int id) - { - var nodeCount = 0; - - var nodeParms = new IDataParameter[] - { - GetParameter(ParmParentId, DataType.Integer, id) - }; - - using (var rdr = ExecuteReader(SqlSelectCount, nodeParms)) - { - if (rdr.Read()) - { - nodeCount = GetInt(rdr, 0); - } - rdr.Close(); - } - return nodeCount; - } - - public List GetIdListByParentId(int parentId) - { - string sqlString = - $@"SELECT Id FROM siteserver_Department WHERE ParentID = '{parentId}' ORDER BY Taxis"; - var list = new List(); - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var theId = GetInt(rdr, 0); - list.Add(theId); - } - rdr.Close(); - } - - return list; - } - - public List GetIdListForDescendant(int id) - { - string sqlString = $@"SELECT Id -FROM siteserver_Department -WHERE (ParentsPath LIKE '{id},%') OR - (ParentsPath LIKE '%,{id},%') OR - (ParentsPath LIKE '%,{id}') OR - (ParentID = {id}) -"; - var list = new List(); - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var theId = GetInt(rdr, 0); - list.Add(theId); - } - rdr.Close(); - } - - return list; - } - - public List GetIdListByIdCollection(string idCollection) - { - var list = new List(); - - if (string.IsNullOrEmpty(idCollection)) return list; - - string sqlString = - $@"SELECT Id FROM siteserver_Department WHERE Id IN ({idCollection})"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var theId = GetInt(rdr, 0); - list.Add(theId); - } - rdr.Close(); - } - - return list; - } - - public List GetIdListByFirstIdList(List firstIdList) - { - var list = new List(); - - if (firstIdList.Count <= 0) return list; - - var builder = new StringBuilder(); - foreach (var id in firstIdList) - { - builder.Append($"Id = {id} OR ParentID = {id} OR ParentsPath LIKE '{id},%' OR "); - } - builder.Length -= 3; - - string sqlString = - $"SELECT Id FROM siteserver_Department WHERE {builder} ORDER BY Taxis"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var id = GetInt(rdr, 0); - list.Add(id); - } - rdr.Close(); - } - - return list; - } - - public List> GetDepartmentInfoKeyValuePair() - { - var list = new List>(); - - var departmentInfoList = GetDepartmentInfoList(); - foreach (var departmentInfo in departmentInfoList) - { - var pair = new KeyValuePair(departmentInfo.Id, departmentInfo); - list.Add(pair); - } - - return list; - } - } -} diff --git a/SiteServer.CMS/Provider/ErrorLogDao.cs b/SiteServer.CMS/Provider/ErrorLogDao.cs deleted file mode 100644 index b3fe2f6c6..000000000 --- a/SiteServer.CMS/Provider/ErrorLogDao.cs +++ /dev/null @@ -1,201 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Text; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Provider -{ - public class ErrorLogDao : DataProviderBase - { - public override string TableName => "siteserver_ErrorLog"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(ErrorLogInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(ErrorLogInfo.PluginId), - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = nameof(ErrorLogInfo.Message), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(ErrorLogInfo.Stacktrace), - DataType = DataType.Text - }, - new TableColumnInfo - { - ColumnName = nameof(ErrorLogInfo.Summary), - DataType = DataType.Text - }, - new TableColumnInfo - { - ColumnName = nameof(ErrorLogInfo.AddDate), - DataType = DataType.DateTime - } - }; - - private const string ParmPluginId = "@PluginId"; - private const string ParmMessage = "@Message"; - private const string ParmStacktrace = "@Stacktrace"; - private const string ParmSummary = "@Summary"; - private const string ParmAddDate = "@AddDate"; - - public int Insert(ErrorLogInfo logInfo) - { - var sqlString = $"INSERT INTO {TableName} (PluginId, Message, Stacktrace, Summary, AddDate) VALUES (@PluginId, @Message, @Stacktrace, @Summary, @AddDate)"; - - var parms = new IDataParameter[] - { - GetParameter(ParmPluginId, DataType.VarChar, 200, logInfo.PluginId), - GetParameter(ParmMessage, DataType.VarChar, 255, logInfo.Message), - GetParameter(ParmStacktrace, DataType.Text, logInfo.Stacktrace), - GetParameter(ParmSummary, DataType.Text, logInfo.Summary), - GetParameter(ParmAddDate, DataType.DateTime, logInfo.AddDate), - }; - - return ExecuteNonQueryAndReturnId(TableName, nameof(ErrorLogInfo.Id), sqlString, parms); - } - - public void Delete(List idList) - { - if (idList == null || idList.Count <= 0) return; - - var sqlString = - $"DELETE FROM {TableName} WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; - - ExecuteNonQuery(sqlString); - } - - public void Delete(int days) - { - if (days <= 0) return; - ExecuteNonQuery($@"DELETE FROM {TableName} WHERE AddDate < '{DateUtils.GetDateAndTimeString(DateTime.Now.AddDays(-days))}'"); - } - - public void DeleteAll() - { - var sqlString = $"DELETE FROM {TableName}"; - - ExecuteNonQuery(sqlString); - } - - public int GetCount() - { - var count = 0; - var sqlString = $"SELECT Count(*) FROM {TableName}"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - count = GetInt(rdr, 0); - } - rdr.Close(); - } - - return count; - } - - public ErrorLogInfo GetErrorLogInfo(int logId) - { - ErrorLogInfo logInfo = null; - - var sqlString = $"SELECT Id, PluginId, Message, Stacktrace, Summary, AddDate FROM {TableName} WHERE Id = @Id"; - - var parms = new IDataParameter[] - { - GetParameter("@Id", DataType.Integer, logId) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - var i = 0; - logInfo = new ErrorLogInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetDateTime(rdr, i)); - } - rdr.Close(); - } - - return logInfo; - } - - public KeyValuePair GetMessageAndStacktrace(int logId) - { - var pair = new KeyValuePair(); - - var sqlString = $"SELECT Message, Stacktrace FROM {TableName} WHERE Id = {logId}"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - pair = new KeyValuePair(GetString(rdr, 0), GetString(rdr, 1)); - } - rdr.Close(); - } - - return pair; - } - - public string GetSelectCommend(string pluginId, string keyword, string dateFrom, string dateTo) - { - var whereString = new StringBuilder(); - - if (!string.IsNullOrEmpty(pluginId)) - { - whereString.Append($"PluginId = '{PageUtils.FilterSql(pluginId)}'"); - } - - if (!string.IsNullOrEmpty(keyword)) - { - if (whereString.Length > 0) - { - whereString.Append(" AND "); - } - var filterKeyword = PageUtils.FilterSql(keyword); - var keywordId = TranslateUtils.ToInt(keyword); - whereString.Append(keywordId > 0 - ? $"Id = {keywordId}" - : $"(Message LIKE '%{filterKeyword}%' OR Stacktrace LIKE '%{filterKeyword}%' OR Summary LIKE '%{filterKeyword}%')"); - } - if (!string.IsNullOrEmpty(dateFrom)) - { - if (whereString.Length > 0) - { - whereString.Append(" AND "); - } - whereString.Append($"AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))}"); - } - if (!string.IsNullOrEmpty(dateTo)) - { - if (whereString.Length > 0) - { - whereString.Append(" AND "); - } - whereString.Append($"AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo))}"); - } - - return whereString.Length > 0 - ? $"SELECT Id, PluginId, Message, Stacktrace, Summary, AddDate FROM {TableName} WHERE {whereString}" - : $"SELECT Id, PluginId, Message, Stacktrace, Summary, AddDate FROM {TableName}"; - } - } -} diff --git a/SiteServer.CMS/Provider/KeywordDao.cs b/SiteServer.CMS/Provider/KeywordDao.cs deleted file mode 100644 index 8827a12d8..000000000 --- a/SiteServer.CMS/Provider/KeywordDao.cs +++ /dev/null @@ -1,197 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.Utils; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Provider -{ - public class KeywordDao : DataProviderBase - { - public override string TableName => "siteserver_Keyword"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(KeywordInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(KeywordInfo.Keyword), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(KeywordInfo.Alternative), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(KeywordInfo.Grade), - DataType = DataType.VarChar, - Length = 50 - } - }; - - private const string ParmId = "@Id"; - private const string ParmKeyword = "@Keyword"; - private const string ParmAlternative = "@Alternative"; - private const string ParmGrade = "@Grade"; - - private const string SqlUpdate = "UPDATE siteserver_Keyword SET Keyword=@Keyword, Alternative=@Alternative, Grade=@Grade WHERE Id=@Id"; - - private const string SqlDelete = "DELETE FROM siteserver_Keyword WHERE Id=@Id"; - - private const string SqlSelect = "SELECT Id, Keyword, Alternative, Grade FROM siteserver_Keyword WHERE Id=@Id"; - - private const string SqlSelectAll = "SELECT Id, Keyword, Alternative, Grade FROM siteserver_Keyword"; - - private const string SqlSelectKeyword = "SELECT Id, Keyword, Alternative, Grade FROM siteserver_Keyword WHERE Keyword = @Keyword"; - - public void Insert(KeywordInfo keywordInfo) - { - var sqlString = "INSERT INTO siteserver_Keyword(Keyword, Alternative, Grade) VALUES(@Keyword, @Alternative, @Grade)"; - - var parms = new IDataParameter[] - { - GetParameter(ParmKeyword, DataType.VarChar,50, keywordInfo.Keyword), - GetParameter(ParmAlternative, DataType.VarChar,50, keywordInfo.Alternative), - GetParameter(ParmGrade, DataType.VarChar, 50, EKeywordGradeUtils.GetValue(keywordInfo.Grade)) - }; - - ExecuteNonQuery(sqlString, parms); - } - - public int GetCount() - { - var sqlString = "SELECT COUNT(*) AS TotalNum FROM siteserver_Keyword"; - return DataProvider.DatabaseDao.GetIntResult(sqlString); - } - - public void Update(KeywordInfo keywordInfo) - { - var parms = new IDataParameter[] - { - GetParameter(ParmKeyword, DataType.VarChar,50, keywordInfo.Keyword), - GetParameter(ParmAlternative, DataType.VarChar,50, keywordInfo.Alternative), - GetParameter(ParmGrade, DataType.VarChar, 50, EKeywordGradeUtils.GetValue(keywordInfo.Grade)), - GetParameter(ParmId, DataType.Integer, keywordInfo.Id) - }; - ExecuteNonQuery(SqlUpdate, parms); - } - - public KeywordInfo GetKeywordInfo(int id) - { - var keywordInfo = new KeywordInfo(); - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, id) - }; - - using (var rdr = ExecuteReader(SqlSelect, parms)) - { - if (rdr.Read()) - { - var i = 0; - keywordInfo = new KeywordInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), EKeywordGradeUtils.GetEnumType(GetString(rdr, i))); - } - rdr.Close(); - } - return keywordInfo; - } - - public void Delete(int id) - { - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, id) - }; - ExecuteNonQuery(SqlDelete, parms); - } - - public void Delete(List idList) - { - string sqlString = - $@"DELETE FROM siteserver_Keyword WHERE Id IN ({TranslateUtils.ObjectCollectionToString(idList)})"; - ExecuteNonQuery(sqlString); - } - - public string GetSelectCommand() - { - return SqlSelectAll; - } - - public bool IsExists(string keyword) - { - var isExists = false; - - var parms = new IDataParameter[] - { - GetParameter(ParmKeyword, DataType.VarChar, 50, keyword) - }; - using (var rdr = ExecuteReader(SqlSelectKeyword, parms)) - { - if (rdr.Read()) - { - isExists = true; - } - rdr.Close(); - } - return isExists; - } - - public List GetKeywordInfoList() - { - var list = new List(); - using (var rdr = ExecuteReader(SqlSelectAll)) - { - while (rdr.Read()) - { - var i = 0; - var keywordInfo = new KeywordInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), EKeywordGradeUtils.GetEnumType(GetString(rdr, i))); - list.Add(keywordInfo); - } - rdr.Close(); - } - return list; - } - - public List GetKeywordInfoList(List keywords) - { - if (keywords == null || keywords.Count == 0) return new List(); - - var list = new List(); - string sqlSelectKeywords = - $"SELECT Id, Keyword, Alternative, Grade FROM siteserver_Keyword WHERE Keyword IN ({TranslateUtils.ToSqlInStringWithQuote(keywords)})"; - using (var rdr = ExecuteReader(sqlSelectKeywords)) - { - while (rdr.Read()) - { - var i = 0; - var keywordInfo = new KeywordInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), EKeywordGradeUtils.GetEnumType(GetString(rdr, i))); - list.Add(keywordInfo); - } - rdr.Close(); - } - return list; - } - - public List GetKeywordListByContent(string content) - { - //string sqlString = - // $"SELECT Keyword FROM siteserver_Keyword WHERE CHARINDEX(Keyword, '{PageUtils.FilterSql(content)}') > 0"; - var sqlString = $"SELECT Keyword FROM siteserver_Keyword WHERE {SqlUtils.GetInStrReverse(PageUtils.FilterSql(content), nameof(KeywordInfo.Keyword))}"; - return DataProvider.DatabaseDao.GetStringList(sqlString); - } - } -} diff --git a/SiteServer.CMS/Provider/LogDao.cs b/SiteServer.CMS/Provider/LogDao.cs deleted file mode 100644 index 16de71e10..000000000 --- a/SiteServer.CMS/Provider/LogDao.cs +++ /dev/null @@ -1,318 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Text; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Provider -{ - public class LogDao : DataProviderBase - { - public override string TableName => "siteserver_Log"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(LogInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(LogInfo.UserName), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(LogInfo.IpAddress), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(LogInfo.AddDate), - DataType = DataType.DateTime - }, - new TableColumnInfo - { - ColumnName = nameof(LogInfo.Action), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(LogInfo.Summary), - DataType = DataType.VarChar, - Length = 255 - } - }; - - private const string ParmUserName = "@UserName"; - private const string ParmIpAddress = "@IPAddress"; - private const string ParmAddDate = "@AddDate"; - private const string ParmAction = "@Action"; - private const string ParmSummary = "@Summary"; - - public void Insert(LogInfo log) - { - var sqlString = "INSERT INTO siteserver_Log(UserName, IPAddress, AddDate, Action, Summary) VALUES (@UserName, @IPAddress, @AddDate, @Action, @Summary)"; - - var parms = new IDataParameter[] - { - GetParameter(ParmUserName, DataType.VarChar, 50, log.UserName), - GetParameter(ParmIpAddress, DataType.VarChar, 50, log.IpAddress), - GetParameter(ParmAddDate, DataType.DateTime, log.AddDate), - GetParameter(ParmAction, DataType.VarChar, 255, log.Action), - GetParameter(ParmSummary, DataType.VarChar, 255, log.Summary) - }; - - ExecuteNonQuery(sqlString, parms); - } - - public void Delete(List idList) - { - if (idList != null && idList.Count > 0) - { - string sqlString = - $"DELETE FROM siteserver_Log WHERE ID IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; - - ExecuteNonQuery(sqlString); - } - } - - public void Delete(int days) - { - if (days <= 0) return; - ExecuteNonQuery($@"DELETE FROM siteserver_Log WHERE AddDate < '{DateUtils.GetDateAndTimeString(DateTime.Now.AddDays(-days))}'"); - } - - public void DeleteAll() - { - const string sqlString = "DELETE FROM siteserver_Log"; - - ExecuteNonQuery(sqlString); - } - - public int GetCount() - { - var count = 0; - const string sqlString = "SELECT Count(*) FROM siteserver_Log"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - count = GetInt(rdr, 0); - } - rdr.Close(); - } - - return count; - } - - public string GetSelectCommend() - { - return "SELECT ID, UserName, IPAddress, AddDate, Action, Summary FROM siteserver_Log"; - } - - public string GetSelectCommend(string userName, string keyword, string dateFrom, string dateTo) - { - if (string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(keyword) && string.IsNullOrEmpty(dateFrom) && string.IsNullOrEmpty(dateTo)) - { - return GetSelectCommend(); - } - - var whereString = new StringBuilder("WHERE "); - - var isWhere = false; - - if (!string.IsNullOrEmpty(userName)) - { - isWhere = true; - whereString.AppendFormat("(UserName = '{0}')", PageUtils.FilterSql(userName)); - } - - if (!string.IsNullOrEmpty(keyword)) - { - if (isWhere) - { - whereString.Append(" AND "); - } - isWhere = true; - whereString.AppendFormat("(Action LIKE '%{0}%' OR Summary LIKE '%{0}%')", PageUtils.FilterSql(keyword)); - } - - if (!string.IsNullOrEmpty(dateFrom)) - { - if (isWhere) - { - whereString.Append(" AND "); - } - isWhere = true; - whereString.Append($"(AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))})"); - } - if (!string.IsNullOrEmpty(dateTo)) - { - if (isWhere) - { - whereString.Append(" AND "); - } - whereString.Append($"(AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo))})"); - } - - return "SELECT ID, UserName, IPAddress, AddDate, Action, Summary FROM siteserver_Log " + whereString; - } - - public DateTime GetLastRemoveLogDate(string userName) - { - var retval = DateTime.MinValue; - var sqlString = SqlUtils.ToTopSqlString("siteserver_Log", "AddDate", "WHERE Action = '清空数据库日志'", "ORDER BY ID DESC", 1); - - var parms = new IDataParameter[] - { - GetParameter(ParmUserName, DataType.VarChar, 50, userName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - retval = GetDateTime(rdr, 0); - } - rdr.Close(); - } - return retval; - } - - /// - /// 统计管理员actionType的操作次数 - /// - /// - /// - /// - /// - /// - public Dictionary GetAdminLoginDictionaryByDate(DateTime dateFrom, DateTime dateTo, string xType, string actionType) - { - var dict = new Dictionary(); - if (string.IsNullOrEmpty(xType)) - { - xType = EStatictisXTypeUtils.GetValue(EStatictisXType.Day); - } - - var builder = new StringBuilder(); - if (dateFrom > DateUtils.SqlMinValue) - { - builder.Append($" AND AddDate >= {SqlUtils.GetComparableDate(dateFrom)}"); - } - if (dateTo != DateUtils.SqlMinValue) - { - builder.Append($" AND AddDate < {SqlUtils.GetComparableDate(dateTo)}"); - } - - string sqlSelectTrackingDay = $@" -SELECT COUNT(*) AS AddNum, AddYear, AddMonth, AddDay FROM ( - SELECT {SqlUtils.GetDatePartYear("AddDate")} AS AddYear, {SqlUtils.GetDatePartMonth("AddDate")} AS AddMonth, {SqlUtils.GetDatePartDay("AddDate")} AS AddDay - FROM siteserver_Log - WHERE {SqlUtils.GetDateDiffLessThanDays("AddDate", 30.ToString())} {builder} -) DERIVEDTBL GROUP BY AddYear, AddMonth, AddDay ORDER BY AddNum DESC";//添加日统计 - - if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Month)) - { - sqlSelectTrackingDay = $@" -SELECT COUNT(*) AS AddNum, AddYear, AddMonth FROM ( - SELECT {SqlUtils.GetDatePartYear("AddDate")} AS AddYear, {SqlUtils.GetDatePartMonth("AddDate")} AS AddMonth - FROM siteserver_Log - WHERE {SqlUtils.GetDateDiffLessThanMonths("AddDate", 12.ToString())} {builder} -) DERIVEDTBL GROUP BY AddYear, AddMonth ORDER BY AddNum DESC";//添加月统计 - } - else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Year)) - { - sqlSelectTrackingDay = $@" -SELECT COUNT(*) AS AddNum, AddYear FROM ( - SELECT {SqlUtils.GetDatePartYear("AddDate")} AS AddYear - FROM siteserver_Log - WHERE {SqlUtils.GetDateDiffLessThanYears("AddDate", 10.ToString())} {builder} -) DERIVEDTBL GROUP BY AddYear ORDER BY AddNum DESC -";//添加年统计 - } - - using (var rdr = ExecuteReader(sqlSelectTrackingDay)) - { - while (rdr.Read()) - { - var accessNum = GetInt(rdr, 0); - if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Day)) - { - var year = GetString(rdr, 1); - var month = GetString(rdr, 2); - var day = GetString(rdr, 3); - var dateTime = TranslateUtils.ToDateTime($"{year}-{month}-{day}"); - dict.Add(dateTime, accessNum); - } - else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Month)) - { - var year = GetString(rdr, 1); - var month = GetString(rdr, 2); - - var dateTime = TranslateUtils.ToDateTime($"{year}-{month}-1"); - dict.Add(dateTime, accessNum); - } - else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Year)) - { - var year = GetString(rdr, 1); - var dateTime = TranslateUtils.ToDateTime($"{year}-1-1"); - dict.Add(dateTime, accessNum); - } - } - rdr.Close(); - } - return dict; - } - - /// - /// 统计管理员actionType的操作次数 - /// - public Dictionary GetAdminLoginDictionaryByName(DateTime dateFrom, DateTime dateTo, string actionType) - { - var dict = new Dictionary(); - - var builder = new StringBuilder(); - if (dateFrom > DateUtils.SqlMinValue) - { - builder.Append($" AND AddDate >= {SqlUtils.GetComparableDate(dateFrom)}"); - } - if (dateTo != DateUtils.SqlMinValue) - { - builder.Append($" AND AddDate < {SqlUtils.GetComparableDate(dateTo)}"); - } - - string sqlSelectTrackingDay = $@" -SELECT COUNT(*) AS AddNum, UserName FROM ( - SELECT {SqlUtils.GetDatePartYear("AddDate")} AS AddYear, {SqlUtils.GetDatePartMonth("AddDate")} AS AddMonth, {SqlUtils.GetDatePartDay("AddDate")} AS AddDay, UserName - FROM siteserver_Log - WHERE {SqlUtils.GetDateDiffLessThanDays("AddDate", 30.ToString())} {builder} -) DERIVEDTBL GROUP BY UserName ORDER BY AddNum DESC";//添加日统计 - - - using (var rdr = ExecuteReader(sqlSelectTrackingDay)) - { - while (rdr.Read()) - { - var accessNum = GetInt(rdr, 0); - var userName = GetString(rdr, 1); - dict.Add(userName, accessNum); - } - rdr.Close(); - } - return dict; - } - } -} diff --git a/SiteServer.CMS/Provider/PermissionsInRolesDao.cs b/SiteServer.CMS/Provider/PermissionsInRolesDao.cs deleted file mode 100644 index 984d1305f..000000000 --- a/SiteServer.CMS/Provider/PermissionsInRolesDao.cs +++ /dev/null @@ -1,174 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Provider -{ - public class PermissionsInRolesDao : DataProviderBase - { - public override string TableName => "siteserver_PermissionsInRoles"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(PermissionsInRolesInfo.Id), - DataType = DataType.Integer, - IsPrimaryKey = true, - IsIdentity = true - }, - new TableColumnInfo - { - ColumnName = nameof(PermissionsInRolesInfo.RoleName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(PermissionsInRolesInfo.GeneralPermissions), - DataType = DataType.Text - } - }; - - private const string SqlSelect = "SELECT Id, RoleName, GeneralPermissions FROM siteserver_PermissionsInRoles WHERE RoleName = @RoleName"; - - private const string SqlInsert = "INSERT INTO siteserver_PermissionsInRoles (RoleName, GeneralPermissions) VALUES (@RoleName, @GeneralPermissions)"; - private const string SqlDelete = "DELETE FROM siteserver_PermissionsInRoles WHERE RoleName = @RoleName"; - - private const string ParmRoleRoleName = "@RoleName"; - private const string ParmGeneralPermissions = "@GeneralPermissions"; - - public void InsertRoleAndPermissions(string roleName, string creatorUserName, string description, List generalPermissionList) - { - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - if (generalPermissionList != null && generalPermissionList.Count > 0) - { - var permissionsInRolesInfo = new PermissionsInRolesInfo(0, roleName, TranslateUtils.ObjectCollectionToString(generalPermissionList)); - DataProvider.PermissionsInRolesDao.InsertWithTrans(permissionsInRolesInfo, trans); - } - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - DataProvider.RoleDao.InsertRole(roleName, creatorUserName, description); - } - - public void InsertWithTrans(PermissionsInRolesInfo info, IDbTransaction trans) - { - var insertParms = new IDataParameter[] - { - GetParameter(ParmRoleRoleName, DataType.VarChar, 255, info.RoleName), - GetParameter(ParmGeneralPermissions, DataType.Text, info.GeneralPermissions) - }; - - ExecuteNonQuery(trans, SqlInsert, insertParms); - } - - - public void DeleteWithTrans(string roleName, IDbTransaction trans) - { - var parms = new IDataParameter[] - { - GetParameter(ParmRoleRoleName, DataType.VarChar, 255, roleName) - }; - - ExecuteNonQuery(trans, SqlDelete, parms); - } - - public void Delete(string roleName) - { - var parms = new IDataParameter[] - { - GetParameter(ParmRoleRoleName, DataType.VarChar, 255, roleName) - }; - - ExecuteNonQuery(SqlDelete, parms); - } - - public void UpdateRoleAndGeneralPermissions(string roleName, string description, List generalPermissionList) - { - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - DataProvider.PermissionsInRolesDao.DeleteWithTrans(roleName, trans); - if (generalPermissionList != null && generalPermissionList.Count > 0) - { - var permissionsInRolesInfo = new PermissionsInRolesInfo(0, roleName, TranslateUtils.ObjectCollectionToString(generalPermissionList)); - DataProvider.PermissionsInRolesDao.InsertWithTrans(permissionsInRolesInfo, trans); - } - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - DataProvider.RoleDao.UpdateRole(roleName, description); - } - - private PermissionsInRolesInfo GetPermissionsInRolesInfo(string roleName) - { - PermissionsInRolesInfo info = null; - - var parms = new IDataParameter[] - { - GetParameter(ParmRoleRoleName, DataType.VarChar, 255, roleName) - }; - - using (var rdr = ExecuteReader(SqlSelect, parms)) - { - if (rdr.Read()) - { - var i = 0; - info = new PermissionsInRolesInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i)); - } - rdr.Close(); - } - return info; - } - - - public List GetGeneralPermissionList(string[] roles) - { - var list = new List(); - var roleNameCollection = new List(roles); - foreach (var roleName in roleNameCollection) - { - var permissionsInRolesInfo = GetPermissionsInRolesInfo(roleName); - if (permissionsInRolesInfo != null) - { - var permissionList = TranslateUtils.StringCollectionToStringList(permissionsInRolesInfo.GeneralPermissions); - foreach (var permission in permissionList) - { - if (!list.Contains(permission)) list.Add(permission); - } - } - } - - return list; - } - } -} diff --git a/SiteServer.CMS/Provider/PluginConfigDao.cs b/SiteServer.CMS/Provider/PluginConfigDao.cs deleted file mode 100644 index f7a756a42..000000000 --- a/SiteServer.CMS/Provider/PluginConfigDao.cs +++ /dev/null @@ -1,168 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Provider -{ - public class PluginConfigDao : DataProviderBase - { - public override string TableName => "siteserver_PluginConfig"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(PluginConfigInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(PluginConfigInfo.PluginId), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(PluginConfigInfo.SiteId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(PluginConfigInfo.ConfigName), - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = nameof(PluginConfigInfo.ConfigValue), - DataType = DataType.Text - } - }; - - private const string ParmPluginId = "@PluginId"; - private const string ParmSiteId = "@SiteId"; - private const string ParmConfigName = "@ConfigName"; - private const string ParmConfigValue = "@ConfigValue"; - - public void Insert(PluginConfigInfo configInfo) - { - const string sqlString = "INSERT INTO siteserver_PluginConfig(PluginId, SiteId, ConfigName, ConfigValue) VALUES (@PluginId, @SiteId, @ConfigName, @ConfigValue)"; - - var parms = new IDataParameter[] - { - GetParameter(ParmPluginId, DataType.VarChar, 50, configInfo.PluginId), - GetParameter(ParmSiteId, DataType.Integer, configInfo.SiteId), - GetParameter(ParmConfigName, DataType.VarChar, 200, configInfo.ConfigName), - GetParameter(ParmConfigValue, DataType.Text, configInfo.ConfigValue) - }; - - ExecuteNonQuery(sqlString, parms); - } - - public void Delete(string pluginId, int siteId, string configName) - { - const string sqlString = "DELETE FROM siteserver_PluginConfig WHERE PluginId = @PluginId AND SiteId = @SiteId AND ConfigName = @ConfigName"; - - var parms = new IDataParameter[] - { - GetParameter(ParmPluginId, DataType.VarChar, 50, pluginId), - GetParameter(ParmSiteId, DataType.Integer, siteId), - GetParameter(ParmConfigName, DataType.VarChar, 200, configName) - }; - - ExecuteNonQuery(sqlString, parms); - } - - public void DeleteAll(string pluginId) - { - const string sqlString = "DELETE FROM siteserver_PluginConfig WHERE PluginId = @PluginId"; - - var parms = new IDataParameter[] - { - GetParameter(ParmPluginId, DataType.VarChar, 50, pluginId) - }; - - ExecuteNonQuery(sqlString, parms); - } - - public void DeleteAll(int siteId) - { - const string sqlString = "DELETE FROM siteserver_PluginConfig WHERE SiteId = @SiteId"; - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - - ExecuteNonQuery(sqlString, parms); - } - - public void Update(PluginConfigInfo configInfo) - { - const string sqlString = "UPDATE siteserver_PluginConfig SET ConfigValue = @ConfigValue WHERE PluginId = @PluginId AND SiteId = @SiteId AND ConfigName = @ConfigName"; - - var parms = new IDataParameter[] - { - GetParameter(ParmConfigValue, DataType.Text, configInfo.ConfigValue), - GetParameter(ParmPluginId, DataType.VarChar, 50, configInfo.PluginId), - GetParameter(ParmSiteId, DataType.Integer, configInfo.SiteId), - GetParameter(ParmConfigName, DataType.VarChar, 200, configInfo.ConfigName) - }; - ExecuteNonQuery(sqlString, parms); - } - - public string GetValue(string pluginId, int siteId, string configName) - { - var value = string.Empty; - - const string sqlString = "SELECT ConfigValue FROM siteserver_PluginConfig WHERE PluginId = @PluginId AND SiteId = @SiteId AND ConfigName = @ConfigName"; - - var parms = new IDataParameter[] - { - GetParameter(ParmPluginId, DataType.VarChar, 50, pluginId), - GetParameter(ParmSiteId, DataType.Integer, siteId), - GetParameter(ParmConfigName, DataType.VarChar, 200, configName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - value = rdr.GetString(0); - } - rdr.Close(); - } - - return value; - } - - public bool IsExists(string pluginId, int siteId, string configName) - { - var exists = false; - - const string sqlString = "SELECT Id FROM siteserver_PluginConfig WHERE PluginId = @PluginId AND SiteId = @SiteId AND ConfigName = @ConfigName"; - - var parms = new IDataParameter[] - { - GetParameter(ParmPluginId, DataType.VarChar, 50, pluginId), - GetParameter(ParmSiteId, DataType.Integer, siteId), - GetParameter(ParmConfigName, DataType.VarChar, 200, configName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - exists = true; - } - rdr.Close(); - } - - return exists; - } - } -} diff --git a/SiteServer.CMS/Provider/PluginDao.cs b/SiteServer.CMS/Provider/PluginDao.cs deleted file mode 100644 index ff2b75db0..000000000 --- a/SiteServer.CMS/Provider/PluginDao.cs +++ /dev/null @@ -1,136 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Data; -using SiteServer.Utils; -using SiteServer.CMS.Model; -using SiteServer.CMS.Plugin.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Provider -{ - public class PluginDao : DataProviderBase - { - public override string TableName => "siteserver_Plugin"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(PluginConfigInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(PluginConfigInfo.PluginId), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(PluginInfo.IsDisabled), - DataType = DataType.VarChar, - Length = 18 - }, - new TableColumnInfo - { - ColumnName = nameof(PluginInfo.Taxis), - DataType = DataType.Integer - } - }; - - public void Delete(string pluginId) - { - const string sqlString = "DELETE FROM siteserver_Plugin WHERE PluginId = @PluginId"; - - var parms = new IDataParameter[] - { - GetParameter(nameof(PluginConfigInfo.PluginId), DataType.VarChar, 50, pluginId) - }; - - ExecuteNonQuery(sqlString, parms); - } - - public void UpdateIsDisabled(string pluginId, bool isDisabled) - { - const string sqlString = "UPDATE siteserver_Plugin SET IsDisabled = @IsDisabled WHERE PluginId = @PluginId"; - - var parms = new IDataParameter[] - { - GetParameter(nameof(PluginInfo.IsDisabled), DataType.VarChar, 18, isDisabled.ToString()), - GetParameter(nameof(PluginConfigInfo.PluginId), DataType.VarChar, 50, pluginId) - }; - - ExecuteNonQuery(sqlString, parms); - } - - public void UpdateTaxis(string pluginId, int taxis) - { - const string sqlString = "UPDATE siteserver_Plugin SET Taxis = @Taxis WHERE PluginId = @PluginId"; - - var parms = new IDataParameter[] - { - GetParameter(nameof(PluginInfo.Taxis), DataType.Integer, taxis), - GetParameter(nameof(PluginConfigInfo.PluginId), DataType.VarChar, 50, pluginId) - }; - - ExecuteNonQuery(sqlString, parms); - } - - public void SetIsDisabledAndTaxis(string pluginId, out bool isDisabled, out int taxis) - { - isDisabled = false; - taxis = 0; - - var exists = false; - - var sqlString = "SELECT Id FROM siteserver_Plugin WHERE PluginId = @PluginId"; - - var parameters = new IDataParameter[] - { - GetParameter(nameof(PluginConfigInfo.PluginId), DataType.VarChar, 50, pluginId) - }; - - using (var rdr = ExecuteReader(sqlString, parameters)) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - exists = true; - } - rdr.Close(); - } - - if (!exists) - { - sqlString = "INSERT INTO siteserver_Plugin(PluginId, IsDisabled, Taxis) VALUES (@PluginId, @IsDisabled, @Taxis)"; - - parameters = new IDataParameter[] - { - GetParameter(nameof(PluginConfigInfo.PluginId), DataType.VarChar, 50, pluginId), - GetParameter(nameof(PluginInfo.IsDisabled), DataType.VarChar, 18, false.ToString()), - GetParameter(nameof(PluginInfo.Taxis), DataType.Integer, 0) - }; - - ExecuteNonQuery(sqlString, parameters); - } - - sqlString = "SELECT IsDisabled, Taxis FROM siteserver_Plugin WHERE PluginId = @PluginId"; - - parameters = new IDataParameter[] - { - GetParameter(nameof(PluginConfigInfo.PluginId), DataType.VarChar, 50, pluginId) - }; - - using (var rdr = ExecuteReader(sqlString, parameters)) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - isDisabled = TranslateUtils.ToBool(rdr.GetString(0)); - taxis = rdr.GetInt32(1); - } - rdr.Close(); - } - } - } -} diff --git a/SiteServer.CMS/Provider/RecordDao.cs b/SiteServer.CMS/Provider/RecordDao.cs deleted file mode 100644 index 6b8447df0..000000000 --- a/SiteServer.CMS/Provider/RecordDao.cs +++ /dev/null @@ -1,167 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Text; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Provider -{ - public class RecordDao : DataProviderBase - { - public override string TableName => "siteserver_Record"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = "Id", - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = "Text", - DataType = DataType.VarChar, - Length = 2000 - }, - new TableColumnInfo - { - ColumnName = "Summary", - DataType = DataType.VarChar, - Length = 2000 - }, - new TableColumnInfo - { - ColumnName = "Source", - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = "AddDate", - DataType = DataType.DateTime - } - }; - - private const string ParmText = "@Text"; - private const string ParmSummary = "@Summary"; - private const string ParmSource = "@Source"; - private const string ParmAddDate = "@AddDate"; - - private void Insert(string text, string summary, string source) - { - var sqlString = $"INSERT INTO {TableName} (Text, Summary, Source, AddDate) VALUES (@Text, @Summary, @Source, @AddDate)"; - - var parms = new IDataParameter[] - { - GetParameter(ParmText, DataType.VarChar, 2000, text), - GetParameter(ParmSummary, DataType.VarChar, 2000, summary), - GetParameter(ParmSource, DataType.VarChar, 200, source), - GetParameter(ParmAddDate, DataType.DateTime, DateTime.Now) - }; - - ExecuteNonQuery(sqlString, parms); - } - - public void Delete(List idList) - { - if (idList != null && idList.Count > 0) - { - var sqlString = - $"DELETE FROM {TableName} WHERE ID IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; - - ExecuteNonQuery(sqlString); - } - } - - public void DeleteAll() - { - var sqlString = $"DELETE FROM {TableName}"; - - ExecuteNonQuery(sqlString); - } - - public string GetSqlString() - { - return $"SELECT Id, Text, Summary, Source, AddDate FROM {TableName}"; - } - - public string GetSqlString(string keyword, string dateFrom, string dateTo) - { - if (string.IsNullOrEmpty(keyword) && string.IsNullOrEmpty(dateFrom) && string.IsNullOrEmpty(dateTo)) - { - return GetSqlString(); - } - - var whereString = new StringBuilder("WHERE "); - - var isWhere = false; - - if (!string.IsNullOrEmpty(keyword)) - { - isWhere = true; - var filterKeyword = PageUtils.FilterSql(keyword); - whereString.Append( - $"(Text LIKE '%{filterKeyword}%' OR Summary LIKE '%{filterKeyword}%' OR Source LIKE '%{filterKeyword}%')"); - } - - if (!string.IsNullOrEmpty(dateFrom)) - { - if (isWhere) - { - whereString.Append(" AND "); - } - isWhere = true; - whereString.Append($"(AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))})"); - } - if (!string.IsNullOrEmpty(dateTo)) - { - if (isWhere) - { - whereString.Append(" AND "); - } - whereString.Append($"(AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo))})"); - } - - return $"SELECT Id, Text, Summary, Source, AddDate FROM {TableName} {whereString}"; - } - - public bool IsRecord() - { -#if (DEBUG) - return false; -#else - return false; -#endif - } - - public void RecordCommandExecute(IDbCommand command, string source) - { - if (!IsRecord()) return; - if (command.CommandText.Contains(TableName)) return; - - var builder = new StringBuilder(); - foreach (var parameter in command.Parameters) - { - var commandParameter = parameter as IDataParameter; - if (commandParameter != null) - { - builder.Append(commandParameter.ParameterName + "=" + commandParameter.Value + "
    ").AppendLine(); - } - } - - Insert(command.CommandText, builder.ToString(), source); - } - - public void RecordLog(string data, string source) - { - if (!IsRecord()) return; - - Insert(data, source, "Log"); - } - } -} diff --git a/SiteServer.CMS/Provider/RelatedFieldDao.cs b/SiteServer.CMS/Provider/RelatedFieldDao.cs deleted file mode 100644 index 7b6a90d45..000000000 --- a/SiteServer.CMS/Provider/RelatedFieldDao.cs +++ /dev/null @@ -1,239 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Provider -{ - public class RelatedFieldDao : DataProviderBase - { - public override string TableName => "siteserver_RelatedField"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(RelatedFieldInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(RelatedFieldInfo.Title), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(RelatedFieldInfo.SiteId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(RelatedFieldInfo.TotalLevel), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(RelatedFieldInfo.Prefixes), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(RelatedFieldInfo.Suffixes), - DataType = DataType.VarChar, - Length = 255 - } - }; - - private const string SqlUpdate = "UPDATE siteserver_RelatedField SET Title = @Title, TotalLevel = @TotalLevel, Prefixes = @Prefixes, Suffixes = @Suffixes WHERE Id = @Id"; - private const string SqlDelete = "DELETE FROM siteserver_RelatedField WHERE Id = @Id"; - - private const string ParmId = "@Id"; - private const string ParmTitle = "@Title"; - private const string ParmSiteId = "@SiteId"; - private const string ParmTotalLevel = "@TotalLevel"; - private const string ParmPrefixes = "@Prefixes"; - private const string ParmSuffixes = "@Suffixes"; - - public int Insert(RelatedFieldInfo relatedFieldInfo) - { - const string sqlString = "INSERT INTO siteserver_RelatedField (Title, SiteId, TotalLevel, Prefixes, Suffixes) VALUES (@Title, @SiteId, @TotalLevel, @Prefixes, @Suffixes)"; - - var insertParms = new IDataParameter[] - { - GetParameter(ParmTitle, DataType.VarChar, 50, relatedFieldInfo.Title), - GetParameter(ParmSiteId, DataType.Integer, relatedFieldInfo.SiteId), - GetParameter(ParmTotalLevel, DataType.Integer, relatedFieldInfo.TotalLevel), - GetParameter(ParmPrefixes, DataType.VarChar, 255, relatedFieldInfo.Prefixes), - GetParameter(ParmSuffixes, DataType.VarChar, 255, relatedFieldInfo.Suffixes), - }; - - return ExecuteNonQueryAndReturnId(TableName, nameof(RelatedFieldInfo.Id), sqlString, insertParms); - } - - public void Update(RelatedFieldInfo relatedFieldInfo) - { - var updateParms = new IDataParameter[] - { - GetParameter(ParmTitle, DataType.VarChar, 50, relatedFieldInfo.Title), - GetParameter(ParmTotalLevel, DataType.Integer, relatedFieldInfo.TotalLevel), - GetParameter(ParmPrefixes, DataType.VarChar, 255, relatedFieldInfo.Prefixes), - GetParameter(ParmSuffixes, DataType.VarChar, 255, relatedFieldInfo.Suffixes), - GetParameter(ParmId, DataType.Integer, relatedFieldInfo.Id) - }; - - ExecuteNonQuery(SqlUpdate, updateParms); - } - - public void Delete(int id) - { - var relatedFieldInfoParms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, id) - }; - - ExecuteNonQuery(SqlDelete, relatedFieldInfoParms); - } - - public RelatedFieldInfo GetRelatedFieldInfo(int id) - { - if (id <= 0) return null; - - RelatedFieldInfo relatedFieldInfo = null; - - string sqlString = - $"SELECT Id, Title, SiteId, TotalLevel, Prefixes, Suffixes FROM siteserver_RelatedField WHERE Id = {id}"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - var i = 0; - relatedFieldInfo = new RelatedFieldInfo(GetInt(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i)); - } - rdr.Close(); - } - - return relatedFieldInfo; - } - - public RelatedFieldInfo GetRelatedFieldInfo(int siteId, string relatedFieldName) - { - RelatedFieldInfo relatedFieldInfo = null; - - string sqlString = - $"SELECT Id, Title, SiteId, TotalLevel, Prefixes, Suffixes FROM siteserver_RelatedField WHERE SiteId = {siteId} AND Title = @Title"; - - var selectParms = new IDataParameter[] - { - GetParameter(ParmTitle, DataType.VarChar, 255, relatedFieldName) - }; - - using (var rdr = ExecuteReader(sqlString, selectParms)) - { - if (rdr.Read()) - { - var i = 0; - relatedFieldInfo = new RelatedFieldInfo(GetInt(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i)); - } - rdr.Close(); - } - - return relatedFieldInfo; - } - - public string GetTitle(int id) - { - var relatedFieldName = string.Empty; - - string sqlString = - $"SELECT Title FROM siteserver_RelatedField WHERE Id = {id}"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - relatedFieldName = GetString(rdr, 0); - } - rdr.Close(); - } - - return relatedFieldName; - } - - public List GetRelatedFieldInfoList(int siteId) - { - var list = new List(); - string sqlString = - $"SELECT Id, Title, SiteId, TotalLevel, Prefixes, Suffixes FROM siteserver_RelatedField WHERE SiteId = {siteId} ORDER BY Id"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var i = 0; - list.Add(new RelatedFieldInfo(GetInt(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i))); - } - rdr.Close(); - } - - return list; - } - - public List GetTitleList(int siteId) - { - var list = new List(); - string sqlString = - $"SELECT Title FROM siteserver_RelatedField WHERE SiteId = {siteId} ORDER BY Id"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - - return list; - } - - public string GetImportTitle(int siteId, string relatedFieldName) - { - string importName; - if (relatedFieldName.IndexOf("_", StringComparison.Ordinal) != -1) - { - var relatedFieldNameCount = 0; - var lastName = relatedFieldName.Substring(relatedFieldName.LastIndexOf("_", StringComparison.Ordinal) + 1); - var firstName = relatedFieldName.Substring(0, relatedFieldName.Length - lastName.Length); - try - { - relatedFieldNameCount = int.Parse(lastName); - } - catch - { - // ignored - } - relatedFieldNameCount++; - importName = firstName + relatedFieldNameCount; - } - else - { - importName = relatedFieldName + "_1"; - } - - var relatedFieldInfo = GetRelatedFieldInfo(siteId, relatedFieldName); - if (relatedFieldInfo != null) - { - importName = GetImportTitle(siteId, importName); - } - - return importName; - } - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Provider/RelatedFieldItemDao.cs b/SiteServer.CMS/Provider/RelatedFieldItemDao.cs deleted file mode 100644 index 16284f16b..000000000 --- a/SiteServer.CMS/Provider/RelatedFieldItemDao.cs +++ /dev/null @@ -1,272 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Provider -{ - public class RelatedFieldItemDao : DataProviderBase - { - public override string TableName => "siteserver_RelatedFieldItem"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(RelatedFieldItemInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(RelatedFieldItemInfo.RelatedFieldId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(RelatedFieldItemInfo.ItemName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(RelatedFieldItemInfo.ItemValue), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(RelatedFieldItemInfo.ParentId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(RelatedFieldItemInfo.Taxis), - DataType = DataType.Integer - } - }; - - private const string SqlUpdate = "UPDATE siteserver_RelatedFieldItem SET ItemName = @ItemName, ItemValue = @ItemValue WHERE ID = @ID"; - - private const string ParmId = "@ID"; - private const string ParmRelatedFieldId = "@RelatedFieldID"; - private const string ParmItemName = "@ItemName"; - private const string ParmItemValue = "@ItemValue"; - private const string ParmParentId = "@ParentID"; - private const string ParmTaxis = "@Taxis"; - - public int Insert(RelatedFieldItemInfo info) - { - info.Taxis = GetMaxTaxis(info.ParentId) + 1; - - const string sqlString = "INSERT INTO siteserver_RelatedFieldItem (RelatedFieldID, ItemName, ItemValue, ParentID, Taxis) VALUES (@RelatedFieldID, @ItemName, @ItemValue, @ParentID, @Taxis)"; - - var parms = new IDataParameter[] - { - GetParameter(ParmRelatedFieldId, DataType.Integer, info.RelatedFieldId), - GetParameter(ParmItemName, DataType.VarChar, 255, info.ItemName), - GetParameter(ParmItemValue, DataType.VarChar, 255, info.ItemValue), - GetParameter(ParmParentId, DataType.Integer, info.ParentId), - GetParameter(ParmTaxis, DataType.Integer, info.Taxis) - }; - - return ExecuteNonQueryAndReturnId(TableName, nameof(RelatedFieldItemInfo.Id), sqlString, parms); - - //RelatedFieldManager.ClearCache(); - } - - public void Update(RelatedFieldItemInfo info) - { - var parms = new IDataParameter[] - { - GetParameter(ParmItemName, DataType.VarChar, 255, info.ItemName), - GetParameter(ParmItemValue, DataType.VarChar, 255, info.ItemValue), - GetParameter(ParmId, DataType.Integer, info.Id) - }; - - ExecuteNonQuery(SqlUpdate, parms); - - //RelatedFieldManager.ClearCache(); - } - - public void Delete(int id) - { - if (id > 0) - { - string sqlString = $"DELETE FROM siteserver_RelatedFieldItem WHERE ID = {id} OR ParentID = {id}"; - ExecuteNonQuery(sqlString); - } - //RelatedFieldManager.ClearCache(); - } - - public List GetRelatedFieldItemInfoList(int relatedFieldId, int parentId) - { - var list = new List(); - - string sqlString = - $"SELECT ID, RelatedFieldID, ItemName, ItemValue, ParentID, Taxis FROM siteserver_RelatedFieldItem WHERE RelatedFieldID = {relatedFieldId} AND ParentID = {parentId} ORDER BY Taxis"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var i = 0; - var info = new RelatedFieldItemInfo(GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i)); - list.Add(info); - } - rdr.Close(); - } - - return list; - } - - public void UpdateTaxisToUp(int id, int parentId) - { - //Get Higher Taxis and ClassID - //string sqlString = - // $"SELECT TOP 1 ID, Taxis FROM siteserver_RelatedFieldItem WHERE ((Taxis > (SELECT Taxis FROM siteserver_RelatedFieldItem WHERE ID = {id})) AND ParentID = {parentId}) ORDER BY Taxis"; - var sqlString = SqlUtils.ToTopSqlString("siteserver_RelatedFieldItem", "ID, Taxis", $"WHERE ((Taxis > (SELECT Taxis FROM siteserver_RelatedFieldItem WHERE ID = {id})) AND ParentID = {parentId})", "ORDER BY Taxis", 1); - - var higherId = 0; - var higherTaxis = 0; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - higherId = GetInt(rdr, 0); - higherTaxis = GetInt(rdr, 1); - } - rdr.Close(); - } - - //Get Taxis Of Selected Class - var selectedTaxis = GetTaxis(id); - - if (higherId != 0) - { - //Set The Selected Class Taxis To Higher Level - SetTaxis(id, higherTaxis); - //Set The Higher Class Taxis To Lower Level - SetTaxis(higherId, selectedTaxis); - } - - //RelatedFieldManager.ClearCache(); - } - - public void UpdateTaxisToDown(int id, int parentId) - { - //Get Lower Taxis and ClassID - //string sqlString = - // $"SELECT TOP 1 ID, Taxis FROM siteserver_RelatedFieldItem WHERE ((Taxis < (SELECT Taxis FROM siteserver_RelatedFieldItem WHERE (ID = {id}))) AND ParentID = {parentId}) ORDER BY Taxis DESC"; - var sqlString = SqlUtils.ToTopSqlString("siteserver_RelatedFieldItem", "ID, Taxis", $"WHERE ((Taxis < (SELECT Taxis FROM siteserver_RelatedFieldItem WHERE (ID = {id}))) AND ParentID = {parentId})", "ORDER BY Taxis DESC", 1); - - var lowerId = 0; - var lowerTaxis = 0; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - lowerId = GetInt(rdr, 0); - lowerTaxis = GetInt(rdr, 1); - } - rdr.Close(); - } - - //Get Taxis Of Selected Class - var selectedTaxis = GetTaxis(id); - - if (lowerId != 0) - { - //Set The Selected Class Taxis To Lower Level - SetTaxis(id, lowerTaxis); - //Set The Lower Class Taxis To Higher Level - SetTaxis(lowerId, selectedTaxis); - } - - //RelatedFieldManager.ClearCache(); - } - - private int GetTaxis(int id) - { - string cmd = $"SELECT Taxis FROM siteserver_RelatedFieldItem WHERE (ID = {id})"; - var taxis = 0; - - using (var rdr = ExecuteReader(cmd)) - { - if (rdr.Read()) - { - taxis = GetInt(rdr, 0); - } - rdr.Close(); - } - return taxis; - } - - private void SetTaxis(int id, int taxis) - { - string cmd = $"UPDATE siteserver_RelatedFieldItem SET Taxis = {taxis} WHERE ID = {id}"; - - ExecuteNonQuery(cmd); - } - - public int GetMaxTaxis(int parentId) - { - int maxTaxis; - string cmd = - $"SELECT MAX(Taxis) FROM siteserver_RelatedFieldItem WHERE ParentID = {parentId} AND Taxis <> {int.MaxValue}"; - using (var conn = GetConnection()) - { - conn.Open(); - var o = ExecuteScalar(conn, cmd); - if (o is System.DBNull) - maxTaxis = 0; - else - maxTaxis = int.Parse(o.ToString()); - } - return maxTaxis; - } - - public int GetMinTaxis(int parentId) - { - int minTaxis; - string cmd = $"SELECT MIN(Taxis) FROM siteserver_RelatedFieldItem WHERE ParentID = {parentId}"; - using (var conn = GetConnection()) - { - conn.Open(); - var o = ExecuteScalar(conn, cmd); - if (o is System.DBNull) - minTaxis = 0; - else - minTaxis = int.Parse(o.ToString()); - } - return minTaxis; - } - - public RelatedFieldItemInfo GetRelatedFieldItemInfo(int id) - { - RelatedFieldItemInfo info = null; - - string sqlString = - $"SELECT ID, RelatedFieldID, ItemName, ItemValue, ParentID, Taxis FROM siteserver_RelatedFieldItem WHERE ID = {id}"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - var i = 0; - info = new RelatedFieldItemInfo(GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i)); - } - rdr.Close(); - } - - return info; - } - - - } -} \ No newline at end of file diff --git a/SiteServer.CMS/Provider/RoleDao.cs b/SiteServer.CMS/Provider/RoleDao.cs deleted file mode 100644 index e6853a41f..000000000 --- a/SiteServer.CMS/Provider/RoleDao.cs +++ /dev/null @@ -1,198 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Provider -{ - public class RoleDao : DataProviderBase - { - public override string TableName => "siteserver_Role"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = "Id", - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = "RoleName", - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = "CreatorUserName", - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = "Description", - DataType = DataType.VarChar, - Length = 255 - } - }; - - private const string ParmRoleName = "@RoleName"; - private const string ParmCreatorUsername= "@CreatorUserName"; - private const string ParmDescription = "@Description"; - - public string GetRoleDescription(string roleName) - { - var roleDescription = string.Empty; - var sqlString = "SELECT Description FROM siteserver_Role WHERE RoleName = @RoleName"; - var parms = new IDataParameter[] - { - GetParameter(ParmRoleName, DataType.VarChar, 255, roleName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - roleDescription = GetString(rdr, 0); - } - rdr.Close(); - } - return roleDescription; - } - - public string GetRolesCreatorUserName(string roleName) - { - var creatorUserName = string.Empty; - var sqlString = "SELECT CreatorUserName FROM siteserver_Role WHERE RoleName = @RoleName"; - var parms = new IDataParameter[] - { - GetParameter(ParmRoleName, DataType.VarChar, 255, roleName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - creatorUserName = GetString(rdr, 0); - } - rdr.Close(); - } - return creatorUserName; - } - - public List GetAllRoles() - { - var list = new List(); - const string sqlSelect = "SELECT RoleName FROM siteserver_Role ORDER BY RoleName"; - - using (var rdr = ExecuteReader(sqlSelect)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - - return list; - } - - public List GetAllRolesByCreatorUserName(string creatorUserName) - { - var list = new List(); - - if (string.IsNullOrEmpty(creatorUserName)) return list; - - const string sqlString = "SELECT RoleName FROM siteserver_Role WHERE CreatorUserName = @CreatorUserName"; - var parms = new IDataParameter[] - { - GetParameter(ParmCreatorUsername, DataType.VarChar, 255, creatorUserName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - return list; - } - - public void InsertRole(string roleName, string creatorUserName, string description) - { - var sqlString = "INSERT INTO siteserver_Role (RoleName, CreatorUserName, Description) VALUES (@RoleName, @CreatorUserName, @Description)"; - - var parms = new IDataParameter[] - { - GetParameter(ParmRoleName, DataType.VarChar, 255, roleName), - GetParameter(ParmCreatorUsername, DataType.VarChar, 255, creatorUserName), - GetParameter(ParmDescription, DataType.VarChar, 255, description) - }; - - ExecuteNonQuery(sqlString, parms); - } - - public virtual void UpdateRole(string roleName, string description) - { - var sqlString = "UPDATE siteserver_Role SET Description = @Description WHERE RoleName = @RoleName"; - - var parms = new IDataParameter[] - { - GetParameter(ParmDescription, DataType.VarChar, 255, description), - GetParameter(ParmRoleName, DataType.VarChar, 255, roleName) - }; - - ExecuteNonQuery(sqlString, parms); - } - - - public bool DeleteRole(string roleName) - { - var isSuccess = false; - try - { - var sqlString = "DELETE FROM siteserver_Role WHERE RoleName = @RoleName"; - - var parms = new IDataParameter[] - { - GetParameter(ParmRoleName, DataType.VarChar, 255, roleName) - }; - - ExecuteNonQuery(sqlString, parms); - isSuccess = true; - } - catch - { - // ignored - } - return isSuccess; - } - - public bool IsRoleExists(string roleName) - { - var exists = false; - var sqlString = "SELECT RoleName FROM siteserver_Role WHERE RoleName = @RoleName"; - var parms = new IDataParameter[] - { - GetParameter("@RoleName", DataType.VarChar, 255, roleName) - }; - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - if (!rdr.IsDBNull(0)) - { - exists = true; - } - } - rdr.Close(); - } - return exists; - } - } -} diff --git a/SiteServer.CMS/Provider/SiteDao.cs b/SiteServer.CMS/Provider/SiteDao.cs deleted file mode 100644 index 854b4d93e..000000000 --- a/SiteServer.CMS/Provider/SiteDao.cs +++ /dev/null @@ -1,513 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.CMS.Plugin; -using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Provider -{ - public class SiteDao : DataProviderBase - { - public override string TableName => "siteserver_Site"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(SiteInfo.Id), - DataType = DataType.Integer, - IsPrimaryKey = true, - IsIdentity = false - }, - new TableColumnInfo - { - ColumnName = nameof(SiteInfo.SiteName), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(SiteInfo.SiteDir), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(SiteInfo.TableName), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(SiteInfo.IsRoot), - DataType = DataType.VarChar, - Length = 18 - }, - new TableColumnInfo - { - ColumnName = nameof(SiteInfo.ParentId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(SiteInfo.Taxis), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(SiteInfo.SettingsXml), - DataType = DataType.Text - } - }; - - private const string ParmId = "@Id"; - private const string ParmSiteName = "@SiteName"; - private const string ParmSiteDir = "@SiteDir"; - private const string ParmTableName = "@TableName"; - private const string ParmIsRoot = "@IsRoot"; - private const string ParmParentId = "@ParentId"; - private const string ParmTaxis = "@Taxis"; - private const string ParmSettingsXml = "@SettingsXML"; - - public void InsertWithTrans(SiteInfo info, IDbTransaction trans) - { - var sqlString = $"INSERT INTO {TableName} (Id, SiteName, SiteDir, TableName, IsRoot, ParentId, Taxis, SettingsXML) VALUES (@Id, @SiteName, @SiteDir, @TableName, @IsRoot, @ParentId, @Taxis, @SettingsXML)"; - - //获取排序值 - var taxis = GetMaxTaxis() + 1; - var insertParms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, info.Id), - GetParameter(ParmSiteName, DataType.VarChar, 50, info.SiteName), - GetParameter(ParmSiteDir, DataType.VarChar, 50, info.SiteDir), - GetParameter(ParmTableName, DataType.VarChar, 50, info.TableName), - GetParameter(ParmIsRoot, DataType.VarChar, 18, info.IsRoot.ToString()), - GetParameter(ParmParentId, DataType.Integer, info.ParentId), - GetParameter(ParmTaxis, DataType.Integer, taxis), - GetParameter(ParmSettingsXml, DataType.Text, info.Additional.ToString()) - }; - - ExecuteNonQuery(trans, sqlString, insertParms); - SiteManager.ClearCache(); - } - - public void Delete(int siteId) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - var list = ChannelManager.GetChannelIdList(siteId); - DataProvider.TableStyleDao.Delete(list, siteInfo.TableName); - - DataProvider.TagDao.DeleteTags(siteId); - - DataProvider.ChannelDao.Delete(siteId, siteId); - - UpdateParentIdToZero(siteId); - - ExecuteNonQuery($"DELETE FROM siteserver_Site WHERE Id = {siteId}"); - - SiteManager.ClearCache(); - ChannelManager.RemoveCache(siteId); - PermissionManager.ClearAllCache(); - } - - public void Update(SiteInfo info) - { - var sqlString = $"UPDATE {TableName} SET SiteName = @SiteName, SiteDir = @SiteDir, TableName = @TableName, IsRoot = @IsRoot, ParentId = @ParentId, Taxis = @Taxis, SettingsXML = @SettingsXML WHERE Id = @Id"; - - var updateParms = new IDataParameter[] - { - GetParameter(ParmSiteName, DataType.VarChar, 50, info.SiteName), - GetParameter(ParmSiteDir, DataType.VarChar, 50, info.SiteDir), - GetParameter(ParmTableName, DataType.VarChar, 50, info.TableName), - GetParameter(ParmIsRoot, DataType.VarChar, 18, info.IsRoot.ToString()), - GetParameter(ParmParentId, DataType.Integer, info.ParentId), - GetParameter(ParmTaxis, DataType.Integer, info.Taxis), - GetParameter(ParmSettingsXml, DataType.Text, info.Additional.ToString()), - GetParameter(ParmId, DataType.Integer, info.Id) - }; - - if (info.IsRoot) - { - UpdateAllIsRoot(); - } - - ExecuteNonQuery(sqlString, updateParms); - SiteManager.ClearCache(); - } - - public void UpdateParentIdToZero(int parentId) - { - var sqlString = "UPDATE siteserver_Site SET ParentId = 0 WHERE ParentId = " + parentId; - - ExecuteNonQuery(sqlString); - SiteManager.ClearCache(); - } - - public List GetLowerSiteDirListThatNotIsRoot() - { - var list = new List(); - - var sqlString = $"SELECT SiteDir FROM {TableName} WHERE IsRoot = @IsRoot"; - - var parms = new IDataParameter[] - { - GetParameter(ParmIsRoot, DataType.VarChar, 18, false.ToString()) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0).ToLower()); - } - rdr.Close(); - } - return list; - } - - public List GetIdListByParent(int parentId) - { - var list = new List(); - - var sqlString = $"SELECT Id FROM {TableName} WHERE ParentId = @ParentId"; - - var parms = new IDataParameter[] - { - GetParameter(ParmParentId, DataType.Integer, parentId) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - while (rdr.Read()) - { - list.Add(GetInt(rdr, 0)); - } - rdr.Close(); - } - return list; - } - - private void UpdateAllIsRoot() - { - var sqlString = $"UPDATE {TableName} SET IsRoot = @IsRoot"; - - var updateParms = new IDataParameter[] - { - GetParameter(ParmIsRoot, DataType.VarChar, 18, false.ToString()) - }; - - ExecuteNonQuery(sqlString, updateParms); - SiteManager.ClearCache(); - } - - public List> GetSiteInfoKeyValuePairList() - { - var list = new List>(); - - var siteInfoList = GetSiteInfoList(); - foreach (var siteInfo in siteInfoList) - { - var entry = new KeyValuePair(siteInfo.Id, siteInfo); - list.Add(entry); - } - - return list; - } - - protected List GetIdList(DateTime sinceDate) - { - var list = new List(); - - string sqlString = - $"SELECT p.Id FROM {TableName} p INNER JOIN {DataProvider.ChannelDao.TableName} n ON (p.Id = n.{nameof(ChannelInfo.Id)} AND (n.AddDate BETWEEN {SqlUtils.GetComparableDate(sinceDate)} AND {SqlUtils.GetComparableNow()})) ORDER BY p.IsRoot DESC, p.ParentId, p.Taxis DESC, n.{nameof(ChannelInfo.Id)}"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetInt(rdr, 0)); - } - rdr.Close(); - } - return list; - } - - private List GetSiteInfoList() - { - var list = new List(); - - var sqlString = $"SELECT Id, SiteName, SiteDir, TableName, IsRoot, ParentId, Taxis, SettingsXML FROM {TableName} ORDER BY Taxis"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var i = 0; - var siteInfo = new SiteInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetBool(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i)); - list.Add(siteInfo); - } - rdr.Close(); - } - return list; - } - - public int GetSiteCount() - { - var count = 0; - - var sqlString = $"SELECT Count(*) FROM {TableName}"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - count = GetInt(rdr, 0); - } - rdr.Close(); - } - return count; - } - - public bool IsTableUsed(string tableName) - { - var parameters = new IDataParameter[] - { - GetParameter(ParmTableName, DataType.VarChar, 50, tableName) - }; - - const string sqlString = "SELECT COUNT(*) FROM siteserver_Site WHERE TableName = @TableName"; - var count = DataProvider.DatabaseDao.GetIntResult(sqlString, parameters); - - if (count > 0) return true; - - var contentModelPluginIdList = DataProvider.ChannelDao.GetContentModelPluginIdList(); - foreach (var pluginId in contentModelPluginIdList) - { - var service = PluginManager.GetService(pluginId); - if (service != null && PluginContentTableManager.IsContentTable(service) && service.ContentTableName == tableName) - { - return true; - } - } - - return false; - } - - public int GetIdByIsRoot() - { - var siteId = 0; - - var sqlString = $"SELECT Id FROM {TableName} WHERE IsRoot = @IsRoot"; - - var parms = new IDataParameter[] - { - GetParameter(ParmIsRoot, DataType.VarChar, 18, true.ToString()) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - siteId = GetInt(rdr, 0); - } - rdr.Close(); - } - return siteId; - } - - public int GetIdBySiteDir(string siteDir) - { - var siteId = 0; - - var sqlString = $"SELECT Id FROM {TableName} WHERE SiteDir = @SiteDir"; - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteDir, DataType.VarChar, 50, siteDir) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - siteId = GetInt(rdr, 0); - } - rdr.Close(); - } - return siteId; - } - - /// - /// 得到所有系统文件夹的列表,以小写表示。 - /// - public List GetLowerSiteDirList(int parentId) - { - var list = new List(); - var sqlString = "SELECT SiteDir FROM siteserver_Site WHERE ParentId = " + parentId; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0).ToLower()); - } - rdr.Close(); - } - - return list; - } - - public IDataReader GetStlDataSource(string siteName, string siteDir, int startNum, int totalNum, string whereString, EScopeType scopeType, string orderByString, string since) - { - IDataReader ie = null; - - var sqlWhereString = string.Empty; - - SiteInfo siteInfo = null; - if (!string.IsNullOrEmpty(siteName)) - { - siteInfo = SiteManager.GetSiteInfoBySiteName(siteName); - } - else if (!string.IsNullOrEmpty(siteDir)) - { - siteInfo = SiteManager.GetSiteInfoByDirectory(siteDir); - } - - if (siteInfo != null) - { - sqlWhereString = $"WHERE (ParentId = {siteInfo.Id})"; - } - else - { - if (scopeType == EScopeType.Children) - { - sqlWhereString = "WHERE (ParentId = 0 AND IsRoot = 'False')"; - } - else if (scopeType == EScopeType.Descendant) - { - sqlWhereString = "WHERE (IsRoot = 'False')"; - } - } - - if (!string.IsNullOrEmpty(whereString)) - { - sqlWhereString = string.IsNullOrEmpty(sqlWhereString) ? $"WHERE ({whereString})" : $"{sqlWhereString} AND ({whereString})"; - } - - if (string.IsNullOrEmpty(orderByString) || StringUtils.EqualsIgnoreCase(orderByString, "default")) - { - orderByString = "ORDER BY IsRoot DESC, ParentId, Taxis DESC, Id"; - - var sqlSelect = DataProvider.DatabaseDao.GetSelectSqlString(TableName, startNum, totalNum, SqlUtils.Asterisk, sqlWhereString, orderByString); - - ie = ExecuteReader(sqlSelect); - } - - return ie; - } - - public bool UpdateTaxisToDown(int siteId) - { - SetTaxisNotZero(); - //var sbSql = new StringBuilder(); - //sbSql.AppendFormat("SELECT TOP 1 Id, Taxis FROM siteserver_Site "); - //sbSql.AppendFormat(" WHERE Taxis > (SELECT Taxis FROM siteserver_Site WHERE Id = {0}) ", siteId); - //sbSql.AppendFormat(" ORDER BY Taxis "); - - var sqlString = SqlUtils.ToTopSqlString("siteserver_Site", "Id, Taxis", $"WHERE Taxis > (SELECT Taxis FROM siteserver_Site WHERE Id = {siteId})", "ORDER BY Taxis", 1); - - var lowerId = 0; - var lowerTaxis = 0; - - using (var reader = ExecuteReader(sqlString)) - { - if (reader.Read()) - { - lowerId = Convert.ToInt32(reader[0]); - lowerTaxis = Convert.ToInt32(reader[1]); - } - reader.Close(); - } - - var selectedTaxis = GetTaxis(siteId); - if (lowerId == 0) return false; - - SetTaxis(siteId, lowerTaxis); - SetTaxis(lowerId, selectedTaxis); - - SiteManager.ClearCache(); - - return true; - } - - public bool UpdateTaxisToUp(int siteId) - { - SetTaxisNotZero(); - //var sbSql = new StringBuilder(); - //sbSql.AppendFormat("SELECT TOP 1 Id, Taxis FROM siteserver_Site "); - //sbSql.AppendFormat(" WHERE Taxis < (SELECT Taxis FROM siteserver_Site WHERE Id = {0}) ", siteId); - //sbSql.AppendFormat(" ORDER BY Taxis DESC"); - - var sqlString = SqlUtils.ToTopSqlString("siteserver_Site", "Id, Taxis", $"WHERE Taxis < (SELECT Taxis FROM siteserver_Site WHERE Id = {siteId})", "ORDER BY Taxis DESC", 1); - - var higherId = 0; - var higherTaxis = 0; - - using (var reader = ExecuteReader(sqlString)) - { - if (reader.Read()) - { - higherId = Convert.ToInt32(reader[0]); - higherTaxis = Convert.ToInt32(reader[1]); - } - reader.Close(); - } - - var selectedTaxis = GetTaxis(siteId); - if (higherId == 0) return false; - - SetTaxis(siteId, higherTaxis); - SetTaxis(higherId, selectedTaxis); - - SiteManager.ClearCache(); - - return true; - } - - private void SetTaxis(int siteId, int taxis) - { - ExecuteNonQuery($"UPDATE siteserver_Site SET Taxis = {taxis} WHERE Id = {siteId}"); - } - - private int GetTaxis(int siteId) - { - var taxis = 0; - using (var reader = ExecuteReader($"SELECT Taxis FROM siteserver_Site WHERE Id = {siteId}")) - { - if (reader.Read()) - { - taxis = Convert.ToInt32(reader[0]); - } - reader.Close(); - } - return taxis; - } - - private static int GetMaxTaxis() - { - const string sqlString = "SELECT MAX(Taxis) FROM siteserver_Site"; - return DataProvider.DatabaseDao.GetIntResult(sqlString); - } - - private void SetTaxisNotZero() - { - const string sqlString = @"UPDATE siteserver_Site SET Taxis = Id where Taxis = 0"; - ExecuteNonQuery(sqlString); - } - } -} diff --git a/SiteServer.CMS/Provider/SiteLogDao.cs b/SiteServer.CMS/Provider/SiteLogDao.cs deleted file mode 100644 index 072dc8cbc..000000000 --- a/SiteServer.CMS/Provider/SiteLogDao.cs +++ /dev/null @@ -1,197 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using System.Text; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Utils; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Provider -{ - public class SiteLogDao : DataProviderBase - { - public override string TableName => "siteserver_SiteLog"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(SiteLogInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(SiteLogInfo.SiteId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(SiteLogInfo.ChannelId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(SiteLogInfo.ContentId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(SiteLogInfo.UserName), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(SiteLogInfo.IpAddress), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(SiteLogInfo.AddDate), - DataType = DataType.DateTime - }, - new TableColumnInfo - { - ColumnName = nameof(SiteLogInfo.Action), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(SiteLogInfo.Summary), - DataType = DataType.VarChar, - Length = 255 - } - }; - - private const string ParmSiteId = "@SiteId"; - private const string ParmChannelId = "@ChannelId"; - private const string ParmContentId = "@ContentId"; - private const string ParmUserName = "@UserName"; - private const string ParmIpAddress = "@IpAddress"; - private const string ParmAddDate = "@AddDate"; - private const string ParmAction = "@Action"; - private const string ParmSummary = "@Summary"; - - public void Insert(SiteLogInfo log) - { - var sqlString = "INSERT INTO siteserver_SiteLog(SiteId, ChannelId, ContentId, UserName, IpAddress, AddDate, Action, Summary) VALUES (@SiteId, @ChannelId, @ContentId, @UserName, @IpAddress, @AddDate, @Action, @Summary)"; - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, log.SiteId), - GetParameter(ParmChannelId, DataType.Integer, log.ChannelId), - GetParameter(ParmContentId, DataType.Integer, log.ContentId), - GetParameter(ParmUserName, DataType.VarChar, 50, log.UserName), - GetParameter(ParmIpAddress, DataType.VarChar, 50, log.IpAddress), - GetParameter(ParmAddDate, DataType.DateTime, log.AddDate), - GetParameter(ParmAction, DataType.VarChar, 255, log.Action), - GetParameter(ParmSummary, DataType.VarChar, 255, log.Summary) - }; - - ExecuteNonQuery(sqlString, parms); - } - - public void Delete(List idList) - { - if (idList != null && idList.Count > 0) - { - string sqlString = - $"DELETE FROM siteserver_SiteLog WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; - - ExecuteNonQuery(sqlString); - } - } - - public void DeleteAll() - { - var sqlString = "DELETE FROM siteserver_SiteLog"; - - ExecuteNonQuery(sqlString); - } - - public string GetSelectCommend() - { - return "SELECT Id, SiteId, ChannelId, ContentId, UserName, IpAddress, AddDate, Action, Summary FROM siteserver_SiteLog"; - } - - public string GetSelectCommend(int siteId, string logType, string userName, string keyword, string dateFrom, string dateTo) - { - if (siteId == 0 && (string.IsNullOrEmpty(logType) || StringUtils.EqualsIgnoreCase(logType, "All")) && string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(keyword) && string.IsNullOrEmpty(dateFrom) && string.IsNullOrEmpty(dateTo)) - { - return GetSelectCommend(); - } - - var whereString = new StringBuilder("WHERE "); - - var isWhere = false; - - if (siteId > 0) - { - isWhere = true; - whereString.AppendFormat("(SiteId = {0})", siteId); - } - - if (!string.IsNullOrEmpty(logType) && !StringUtils.EqualsIgnoreCase(logType, "All")) - { - if (isWhere) - { - whereString.Append(" AND "); - } - isWhere = true; - - if (StringUtils.EqualsIgnoreCase(logType, "Channel")) - { - whereString.Append("(ChannelId > 0 AND ContentId = 0)"); - } - else if (StringUtils.EqualsIgnoreCase(logType, "Content")) - { - whereString.Append("(ChannelId > 0 AND ContentId > 0)"); - } - } - - if (!string.IsNullOrEmpty(userName)) - { - if (isWhere) - { - whereString.Append(" AND "); - } - isWhere = true; - whereString.AppendFormat("(UserName = '{0}')", userName); - } - - if (!string.IsNullOrEmpty(keyword)) - { - if (isWhere) - { - whereString.Append(" AND "); - } - isWhere = true; - whereString.AppendFormat("(Action LIKE '%{0}%' OR Summary LIKE '%{0}%')",PageUtils.FilterSql(keyword)); - } - - if (!string.IsNullOrEmpty(dateFrom)) - { - if (isWhere) - { - whereString.Append(" AND "); - } - isWhere = true; - whereString.Append($"(AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))})"); - } - if (!string.IsNullOrEmpty(dateTo)) - { - if (isWhere) - { - whereString.Append(" AND "); - } - whereString.Append($"(AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo))})"); - } - - return "SELECT Id, SiteId, ChannelId, ContentId, UserName, IpAddress, AddDate, Action, Summary FROM siteserver_SiteLog " + whereString; - } - } -} diff --git a/SiteServer.CMS/Provider/SitePermissionsDao.cs b/SiteServer.CMS/Provider/SitePermissionsDao.cs deleted file mode 100644 index 5f5e1f87d..000000000 --- a/SiteServer.CMS/Provider/SitePermissionsDao.cs +++ /dev/null @@ -1,455 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.Utils; -using SiteServer.CMS.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Provider -{ - public class SitePermissionsDao : DataProviderBase - { - public override string TableName => "siteserver_SitePermissions"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(SitePermissionsInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(SitePermissionsInfo.RoleName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(SitePermissionsInfo.SiteId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(SitePermissionsInfo.ChannelIdCollection), - DataType = DataType.Text - }, - new TableColumnInfo - { - ColumnName = nameof(SitePermissionsInfo.ChannelPermissions), - DataType = DataType.Text - }, - new TableColumnInfo - { - ColumnName = nameof(SitePermissionsInfo.WebsitePermissions), - DataType = DataType.Text - } - }; - - private const string SqlSelectAllByRoleName = "SELECT RoleName, SiteId, ChannelIdCollection, ChannelPermissions, WebsitePermissions FROM siteserver_SitePermissions WHERE RoleName = @RoleName ORDER BY SiteId DESC"; - - private const string SqlInsert = "INSERT INTO siteserver_SitePermissions (RoleName, SiteId, ChannelIdCollection, ChannelPermissions, WebsitePermissions) VALUES (@RoleName, @SiteId, @ChannelIdCollection, @ChannelPermissions, @WebsitePermissions)"; - private const string SqlDelete = "DELETE FROM siteserver_SitePermissions WHERE RoleName = @RoleName"; - - private const string ParmRoleRoleName = "@RoleName"; - private const string ParmSiteId = "@SiteId"; - private const string ParmChannelIdCollection = "@ChannelIdCollection"; - private const string ParmChannelPermissions = "@ChannelPermissions"; - private const string ParmWebsitePermissions = "@WebsitePermissions"; - - public void InsertWithTrans(SitePermissionsInfo info, IDbTransaction trans) - { - if (IsExists(info.RoleName, info.SiteId, trans)) - { - DeleteWithTrans(info.RoleName, info.SiteId, trans); - } - - var insertParms = new IDataParameter[] - { - GetParameter(ParmRoleRoleName, DataType.VarChar, 255, info.RoleName), - GetParameter(ParmSiteId, DataType.Integer, info.SiteId), - GetParameter(ParmChannelIdCollection, DataType.Text, info.ChannelIdCollection), - GetParameter(ParmChannelPermissions, DataType.Text, info.ChannelPermissions), - GetParameter(ParmWebsitePermissions, DataType.Text, info.WebsitePermissions) - }; - - ExecuteNonQuery(trans, SqlInsert, insertParms); - } - - - public void DeleteWithTrans(string roleName, IDbTransaction trans) - { - var parms = new IDataParameter[] - { - GetParameter(ParmRoleRoleName, DataType.VarChar, 255, roleName) - }; - - ExecuteNonQuery(trans, SqlDelete, parms); - } - - private void DeleteWithTrans(string roleName, int siteId, IDbTransaction trans) - { - var sqlString = "DELETE FROM siteserver_SitePermissions WHERE RoleName = @RoleName AND SiteId = @SiteId"; - - var parms = new IDataParameter[] - { - GetParameter(ParmRoleRoleName, DataType.VarChar, 255, roleName), - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - - ExecuteNonQuery(trans, sqlString, parms); - } - - private bool IsExists(string roleName, int siteId, IDbTransaction trans) - { - var isExists = false; - - var sqlString = "SELECT RoleName FROM siteserver_SitePermissions WHERE RoleName = @RoleName AND SiteId = @SiteId"; - - var parms = new IDataParameter[] - { - GetParameter(ParmRoleRoleName, DataType.VarChar, 255, roleName), - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - - using (var rdr = ExecuteReader(trans, sqlString, parms)) - { - if (rdr.Read()) - { - isExists = true; - } - rdr.Close(); - } - - return isExists; - } - - public List GetSystemPermissionsInfoList(string roleName) - { - var list = new List(); - - var parms = new IDataParameter[] - { - GetParameter(ParmRoleRoleName, DataType.VarChar, 255, roleName) - }; - - using (var rdr = ExecuteReader(SqlSelectAllByRoleName, parms)) - { - while (rdr.Read()) - { - var i = 0; - var info = new SitePermissionsInfo(GetString(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetString(rdr, i)); - list.Add(info); - } - rdr.Close(); - } - - return list; - } - - public Dictionary> GetWebsitePermissionSortedList(string[] roles) - { - var sortedlist = new Dictionary>(); - foreach (var roleName in roles) - { - var systemPermissionsList = GetSystemPermissionsInfoList(roleName); - foreach (var systemPermissionsInfo in systemPermissionsList) - { - var list = new List(); - var websitePermissionList = TranslateUtils.StringCollectionToStringList(systemPermissionsInfo.WebsitePermissions); - foreach (var websitePermission in websitePermissionList) - { - if (!list.Contains(websitePermission)) list.Add(websitePermission); - } - sortedlist[systemPermissionsInfo.SiteId] = list; - } - } - - return sortedlist; - } - - public Dictionary> GetChannelPermissionSortedList(string[] roles) - { - var dict = new Dictionary>(); - - foreach (var roleName in roles) - { - var systemPermissionsInfoList = GetSystemPermissionsInfoList(roleName); - foreach (var systemPermissionsInfo in systemPermissionsInfoList) - { - var channelIdStrList = TranslateUtils.StringCollectionToStringList(systemPermissionsInfo.ChannelIdCollection); - foreach (var channelIdStr in channelIdStrList) - { - var channelId = TranslateUtils.ToInt(channelIdStr); - List list = null; - - foreach (var dictKey in dict.Keys) - { - if (dictKey == PermissionManager.GetChannelPermissionDictKey(systemPermissionsInfo.SiteId, channelId)) - { - list = dict[dictKey]; - break; - } - } - if (list == null) - { - list = new List(); - dict.Add(PermissionManager.GetChannelPermissionDictKey(systemPermissionsInfo.SiteId, channelId), list); - } - - var channelPermissionList = TranslateUtils.StringCollectionToStringList(systemPermissionsInfo.ChannelPermissions); - foreach (var channelPermission in channelPermissionList) - { - if (!list.Contains(channelPermission)) list.Add(channelPermission); - } - } - } - } - - return dict; - } - - public List GetChannelPermissionListIgnoreChannelId(string[] roles) - { - var list = new List(); - var roleNameCollection = new List(roles); - - foreach (var roleName in roleNameCollection) - { - var systemPermissionsInfoList = GetSystemPermissionsInfoList(roleName); - foreach (SitePermissionsInfo systemPermissionsInfo in systemPermissionsInfoList) - { - var channelPermissionList = TranslateUtils.StringCollectionToStringList(systemPermissionsInfo.ChannelPermissions); - foreach (var channelPermission in channelPermissionList) - { - if (!list.Contains(channelPermission)) - { - list.Add(channelPermission); - } - } - } - } - - return list; - } - - - - public List GetSystemPermissionsInfoListBySiteId(int siteId, string whereStr) - { - var list = new List(); - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - - using (var rdr = ExecuteReader( - $"SELECT RoleName, SiteId, ChannelIdCollection, ChannelPermissions, WebsitePermissions FROM siteserver_SitePermissions WHERE SiteId = @SiteId {whereStr} ", parms)) - { - while (rdr.Read()) - { - var i = 0; - var info = new SitePermissionsInfo(GetString(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetString(rdr, i)); - list.Add(info); - } - rdr.Close(); - } - - return list; - } - - - private const string SqlSelectAllByRp = "SELECT RoleName, SiteId, ChannelIdCollection, ChannelPermissions, WebsitePermissions FROM siteserver_SitePermissions WHERE RoleName = @RoleName AND SiteId=@SiteId ORDER BY SiteId DESC"; - /// - /// 根据角色名和站点ID获取角色权限信息 - /// - /// - /// - /// - public SitePermissionsInfo GetSystemPermissionsInfoByRp(string roleName, int siteId) - { - SitePermissionsInfo info = null; - - var parms = new IDataParameter[] - { - GetParameter(ParmRoleRoleName, DataType.VarChar, 255, roleName), - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - - using (var rdr = ExecuteReader(SqlSelectAllByRp, parms)) - { - if (rdr.Read()) - { - var i = 0; - info = new SitePermissionsInfo(GetString(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetString(rdr, i)); - } - rdr.Close(); - } - - return info; - } - - /// - /// 根据角色名和站点ID获取角色的站点权限信息 - /// - /// - /// - /// - public List GetWebsitePermissionListByRp(string roleName, int siteId) - { - var systemPermissionsInfo = GetSystemPermissionsInfoByRp(roleName, siteId); - - return TranslateUtils.StringCollectionToStringList(systemPermissionsInfo.WebsitePermissions); - } - - string _sqlUpdate = "update siteserver_SitePermissions set ChannelIdCollection=@ChannelIdCollection, ChannelPermissions=@ChannelPermissions, WebsitePermissions=@WebsitePermissions where RoleName =@RoleName and SiteId = @SiteId"; - - public void Update(SitePermissionsInfo info) - { - var updateParms = new IDataParameter[] - { - GetParameter(ParmRoleRoleName, DataType.VarChar, 255, info.RoleName), - GetParameter(ParmSiteId, DataType.Integer, info.SiteId), - GetParameter(ParmChannelIdCollection, DataType.Text, info.ChannelIdCollection), - GetParameter(ParmChannelPermissions, DataType.Text, info.ChannelPermissions), - GetParameter(ParmWebsitePermissions, DataType.Text, info.WebsitePermissions) - }; - - ExecuteNonQuery(_sqlUpdate, updateParms); - } - - public List GetAllPermissionList(string[] roles, int siteId, bool iscc) - { - var permissionList = new List(); - var roleNameCollection = new List(roles); - foreach (var roleName in roleNameCollection) - { - var systemPermissionsInfoList = GetSystemPermissionsInfoList(roleName); - foreach (var systemPermissionsInfo in systemPermissionsInfoList) - { - if (siteId != 0) - { - if (iscc) - { - if (systemPermissionsInfo.SiteId == siteId && - !string.IsNullOrEmpty(systemPermissionsInfo.ChannelIdCollection)) - { - permissionList.Add(systemPermissionsInfo); - } - } - else - { - if (systemPermissionsInfo.SiteId == siteId) - { - permissionList.Add(systemPermissionsInfo); - } - } - } - else - { - if (!string.IsNullOrEmpty(systemPermissionsInfo.ChannelIdCollection)) - { - permissionList.Add(systemPermissionsInfo); - } - else - { - permissionList.Add(systemPermissionsInfo); - } - } - } - } - - return permissionList; - } - - public void InsertRoleAndPermissions(string roleName, string creatorUserName, string description, List generalPermissionList, List systemPermissionsInfoList) - { - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - if (generalPermissionList != null && generalPermissionList.Count > 0) - { - var permissionsInRolesInfo = new PermissionsInRolesInfo(0, roleName, TranslateUtils.ObjectCollectionToString(generalPermissionList)); - DataProvider.PermissionsInRolesDao.InsertWithTrans(permissionsInRolesInfo, trans); - } - - foreach (var systemPermissionsInfo in systemPermissionsInfoList) - { - systemPermissionsInfo.RoleName = roleName; - InsertWithTrans(systemPermissionsInfo, trans); - } - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - DataProvider.RoleDao.InsertRole(roleName, creatorUserName, description); - } - - public void UpdateSitePermissions(string roleName, List sitePermissionsInfoList) - { - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - DeleteWithTrans(roleName, trans); - foreach (var sitePermissionsInfo in sitePermissionsInfoList) - { - sitePermissionsInfo.RoleName = roleName; - InsertWithTrans(sitePermissionsInfo, trans); - } - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - } - - public void DeleteRoleAndPermissions(string roleName) - { - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - DeleteWithTrans(roleName, trans); - - DataProvider.PermissionsInRolesDao.DeleteWithTrans(roleName, trans); - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - - DataProvider.RoleDao.DeleteRole(roleName); - } - } -} diff --git a/SiteServer.CMS/Provider/TableDao.cs b/SiteServer.CMS/Provider/TableDao.cs deleted file mode 100644 index a945ea1d6..000000000 --- a/SiteServer.CMS/Provider/TableDao.cs +++ /dev/null @@ -1,687 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Provider -{ - public class TableDao : DataProviderBase - { - public override string TableName => "siteserver_Table"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(TableInfo.Id), - DataType = DataType.Integer, - IsPrimaryKey = true, - IsIdentity = true - }, - new TableColumnInfo - { - ColumnName = nameof(TableInfo.TableName), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(TableInfo.DisplayName), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(TableInfo.AttributeNum), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(TableInfo.IsCreatedInDb), - DataType = DataType.VarChar, - Length = 18 - }, - new TableColumnInfo - { - ColumnName = nameof(TableInfo.IsChangedAfterCreatedInDb), - DataType = DataType.VarChar, - Length = 18 - }, - new TableColumnInfo - { - ColumnName = nameof(TableInfo.IsDefault), - DataType = DataType.VarChar, - Length = 18 - }, - new TableColumnInfo - { - ColumnName = nameof(TableInfo.Description), - DataType = DataType.Text - } - }; - - private const string SqlSelectTable = "SELECT Id, TableName, DisplayName, AttributeNum, IsCreatedInDB, IsChangedAfterCreatedInDB, IsDefault, Description FROM siteserver_Table WHERE TableName = @TableName"; - private const string SqlSelectDisplayName = "SELECT DisplayName FROM siteserver_Table WHERE TableName = @TableName"; - private const string SqlSelectAllTableCreatedInDb = "SELECT Id, TableName, DisplayName, AttributeNum, IsCreatedInDB, IsChangedAfterCreatedInDB, IsDefault, Description FROM siteserver_Table WHERE IsCreatedInDB = @IsCreatedInDB ORDER BY IsCreatedInDB DESC, TableName"; - private const string SqlSelectTableCount = "SELECT COUNT(*) FROM siteserver_Table"; - private const string SqlSelectTableName = "SELECT TableName FROM siteserver_Table"; - - private const string SqlInsertTable = "INSERT INTO siteserver_Table (TableName, DisplayName, AttributeNum, IsCreatedInDB, IsChangedAfterCreatedInDB, IsDefault, Description) VALUES (@TableName, @DisplayName, @AttributeNum, @IsCreatedInDB, @IsChangedAfterCreatedInDB, @IsDefault, @Description)"; - private const string SqlUpdateTable = "UPDATE siteserver_Table SET DisplayName = @DisplayName, AttributeNum = @AttributeNum, IsCreatedInDB = @IsCreatedInDB, IsChangedAfterCreatedInDB = @IsChangedAfterCreatedInDB, IsDefault = @IsDefault, Description = @Description WHERE TableName = @TableName"; - private const string SqlUpdateTableAttributeNum = "UPDATE siteserver_Table SET AttributeNum = @AttributeNum WHERE TableName = @TableName"; - private const string SqlUpdateTableIsCreatedInDb = "UPDATE siteserver_Table SET IsCreatedInDB = @IsCreatedInDB WHERE TableName = @TableName"; - private const string SqlUpdateTableIsChangedAfterCreatedInDb = "UPDATE siteserver_Table SET IsChangedAfterCreatedInDB = @IsChangedAfterCreatedInDB WHERE TableName = @TableName"; - private const string SqlDeleteTable = "DELETE FROM siteserver_Table WHERE TableName = @TableName"; - - private const string ParmTableName = "@TableName"; - private const string ParmDisplayName = "@DisplayName"; - private const string ParmAttributeNum = "@AttributeNum"; - private const string ParmIsCreatedInDb = "@IsCreatedInDB"; - private const string ParmIsChangedAfterCreatedInDb = "@IsChangedAfterCreatedInDB"; - private const string ParmIsDefault = "@IsDefault"; - private const string ParmDescription = "@Description"; - - public void Insert(TableInfo tableInfo, List metadataInfoList) - { - var insertParms = new IDataParameter[] - { - GetParameter(ParmTableName, DataType.VarChar, 50, tableInfo.TableName), - GetParameter(ParmDisplayName, DataType.VarChar, 50, tableInfo.DisplayName), - GetParameter(ParmAttributeNum, DataType.Integer, tableInfo.AttributeNum), - GetParameter(ParmIsCreatedInDb, DataType.VarChar, 18, false.ToString()), - GetParameter(ParmIsChangedAfterCreatedInDb, DataType.VarChar, 18, false.ToString()), - GetParameter(ParmIsDefault, DataType.VarChar, 18, tableInfo.IsDefault.ToString()), - GetParameter(ParmDescription, DataType.Text, tableInfo.Description) - }; - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - ExecuteNonQuery(trans, SqlInsertTable, insertParms); - //DataProvider.TableMetadataDao.InsertSystemItems(tableInfo.TableName, trans); - - if (metadataInfoList != null && metadataInfoList.Count > 0) - { - var taxis = 1; - foreach (var metadataInfo in metadataInfoList) - { - DataProvider.TableMetadataDao.InsertWithTransaction(metadataInfo, taxis++, trans); - } - } - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - } - - public void Update(TableInfo info) - { - var updateParms = new IDataParameter[] - { - GetParameter(ParmDisplayName, DataType.VarChar, 50, info.DisplayName), - GetParameter(ParmAttributeNum, DataType.Integer, info.AttributeNum), - GetParameter(ParmIsCreatedInDb, DataType.VarChar, 18, info.IsCreatedInDb.ToString()), - GetParameter(ParmIsChangedAfterCreatedInDb, DataType.VarChar, 18, info.IsChangedAfterCreatedInDb.ToString()), - GetParameter(ParmIsDefault, DataType.VarChar, 18, info.IsDefault.ToString()), - GetParameter(ParmDescription, DataType.Text, info.Description), - GetParameter(ParmTableName, DataType.VarChar, 50, info.TableName) - }; - - ExecuteNonQuery(SqlUpdateTable, updateParms); - } - - public void UpdateAttributeNum(string tableName) - { - var fieldNum = DataProvider.TableMetadataDao.GetTableMetadataCountByEnName(tableName); - UpdateAttributeNum(fieldNum, tableName); - } - - private void UpdateAttributeNum(int attributeNum, string tableName) - { - var updateParms = new IDataParameter[] - { - GetParameter(ParmAttributeNum, DataType.Integer, attributeNum), - GetParameter(ParmTableName, DataType.VarChar, 50, tableName) - }; - - ExecuteNonQuery(SqlUpdateTableAttributeNum, updateParms); - } - - public void UpdateIsCreatedInDb(bool isCreatedInDb, string tableName) - { - var updateParms = new IDataParameter[] - { - GetParameter(ParmIsCreatedInDb, DataType.VarChar, 18, isCreatedInDb.ToString()), - GetParameter(ParmTableName, DataType.VarChar, 50, tableName) - }; - - ExecuteNonQuery(SqlUpdateTableIsCreatedInDb, updateParms); - } - - public void UpdateIsChangedAfterCreatedInDbToTrue(string tableName) - { - var updateParms = new IDataParameter[] - { - GetParameter(ParmIsChangedAfterCreatedInDb, DataType.VarChar, 18, true.ToString()), - GetParameter(ParmTableName, DataType.VarChar, 50, tableName) - }; - - ExecuteNonQuery(SqlUpdateTableIsChangedAfterCreatedInDb, updateParms); - } - - public void UpdateIsChangedAfterCreatedInDbToFalse(string tableName) - { - var updateParms = new IDataParameter[] - { - GetParameter(ParmIsChangedAfterCreatedInDb, DataType.VarChar, 18, false.ToString()), - GetParameter(ParmTableName, DataType.VarChar, 50, tableName) - }; - - ExecuteNonQuery(SqlUpdateTableIsChangedAfterCreatedInDb, updateParms); - } - - public void DeleteCollectionTableInfoAndDbTable(string tableName) - { - var isDbExists = DataProvider.DatabaseDao.IsTableExists(tableName); - var parms = new IDataParameter[] - { - GetParameter(ParmTableName, DataType.VarChar, 50, tableName), - }; - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - if (isDbExists) - { - ExecuteNonQuery(trans, SqlUtils.GetDropTableSqlString(tableName)); - TableColumnManager.ClearCache(); - } - - ExecuteNonQuery(trans, SqlDeleteTable, parms); - DataProvider.TableMetadataDao.Delete(tableName, trans); - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - } - - public void DeleteDbTable(string tableName) - { - if (!DataProvider.DatabaseDao.IsTableExists(tableName)) return; - - var dropTableSqlString = SqlUtils.GetDropTableSqlString(tableName); - - var updateParms = new IDataParameter[] - { - GetParameter("@IsCreatedInDB", DataType.VarChar, 18, false.ToString()), - GetParameter("@IsChangedAfterCreatedInDB", DataType.VarChar, 18, false.ToString()), - GetParameter("@TableName", DataType.VarChar, 50, tableName) - }; - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - ExecuteNonQuery(trans, dropTableSqlString); - TableColumnManager.ClearCache(); - - ExecuteNonQuery(trans, "UPDATE siteserver_Table SET IsCreatedInDB = @IsCreatedInDB, IsChangedAfterCreatedInDB = @IsChangedAfterCreatedInDB WHERE TableName = @TableName", updateParms); - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - } - - public void ReCreateDbTable(string tableName) - { - var isTableExists = DataProvider.DatabaseDao.IsTableExists(tableName); - - var updateParms = new IDataParameter[] - { - GetParameter("@IsCreatedInDB", DataType.VarChar, 18, true.ToString()), - GetParameter("@IsChangedAfterCreatedInDB", DataType.VarChar, 18, false.ToString()), - GetParameter("@TableName", DataType.VarChar, 50, tableName) - }; - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - if (isTableExists) - { - var dropTableSqlString = SqlUtils.GetDropTableSqlString(tableName); - ExecuteNonQuery(trans, dropTableSqlString); - } - - var createTableSqlString = DataProvider.ContentDao.GetCreateTableCollectionInfoSqlString(tableName); - var reader = new System.IO.StringReader(createTableSqlString); - string sql; - while (null != (sql = SqlUtils.ReadNextStatementFromStream(reader))) - { - ExecuteNonQuery(trans, sql.Trim()); - } - - TableColumnManager.ClearCache(); - - ExecuteNonQuery(trans, "UPDATE siteserver_Table SET IsCreatedInDB = @IsCreatedInDB, IsChangedAfterCreatedInDB = @IsChangedAfterCreatedInDB WHERE TableName = @TableName", updateParms); - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - } - - public void CreateDbTable(string tableName) - { - var isDbExists = DataProvider.DatabaseDao.IsTableExists(tableName); - if (isDbExists) return; - - var createTableSqlString = DataProvider.ContentDao.GetCreateTableCollectionInfoSqlString(tableName); - - var updateParms = new IDataParameter[] - { - GetParameter("@IsCreatedInDB", DataType.VarChar, 18, true.ToString()), - GetParameter("@IsChangedAfterCreatedInDB", DataType.VarChar, 18, false.ToString()), - GetParameter("@TableName", DataType.VarChar, 50, tableName) - }; - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - var reader = new System.IO.StringReader(createTableSqlString); - string sql; - while (null != (sql = SqlUtils.ReadNextStatementFromStream(reader))) - { - ExecuteNonQuery(trans, sql.Trim()); - } - - TableColumnManager.ClearCache(); - - ExecuteNonQuery(trans, "UPDATE siteserver_Table SET IsCreatedInDB = @IsCreatedInDB, IsChangedAfterCreatedInDB = @IsChangedAfterCreatedInDB WHERE TableName = @TableName", updateParms); - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - } - - public void SyncDbTable(string tableName) - { - var metadataInfoList = TableMetadataManager.GetTableMetadataInfoList(tableName); - var columnInfolist = TableColumnManager.GetTableColumnInfoListLowercase(tableName, ContentAttribute.AllAttributesLowercase); - - var sqlList = new List(); - - //添加新增/修改字段SQL语句 - foreach (var metadataInfo in metadataInfoList) - { - var columnExists = false; - foreach (var columnInfo in columnInfolist) - { - if (!StringUtils.EqualsIgnoreCase(columnInfo.ColumnName, metadataInfo.AttributeName)) continue; - - columnExists = true; - - if (metadataInfo.DataType != columnInfo.DataType || metadataInfo.DataType == DataType.VarChar && metadataInfo.DataLength != columnInfo.Length) - { - var dropColumnsSqlList = DataProvider.DatabaseDao.GetDropColumnsSqlString(tableName, metadataInfo.AttributeName); - foreach (var sql in dropColumnsSqlList) - { - sqlList.Add(sql); - } - var addColumnsSqlList1 = DataProvider.TableMetadataDao.GetAddColumnsSqlString(tableName, metadataInfo); - foreach (var sql in addColumnsSqlList1) - { - sqlList.Add(sql); - } - } - - break; - } - if (columnExists) continue; - - var addColumnsSqlList2 = DataProvider.TableMetadataDao.GetAddColumnsSqlString(tableName, metadataInfo); - foreach (var sql in addColumnsSqlList2) - { - sqlList.Add(sql); - } - } - - //添加删除字段SQL语句 - foreach (var columnInfo in columnInfolist) - { - var isNeedDelete = true; - foreach (var metadataInfo in metadataInfoList) - { - if (StringUtils.EqualsIgnoreCase(columnInfo.ColumnName, metadataInfo.AttributeName)) - { - isNeedDelete = false; - break; - } - } - if (isNeedDelete) - { - var dropColumnsSqlList = DataProvider.DatabaseDao.GetDropColumnsSqlString(tableName, columnInfo.ColumnName); - foreach (var sql in dropColumnsSqlList) - { - sqlList.Add(sql); - } - } - } - - if (sqlList.Count <= 0) return; - - DataProvider.DatabaseDao.ExecuteSql(sqlList); - DataProvider.TableDao.UpdateIsChangedAfterCreatedInDbToFalse(tableName); - TableColumnManager.ClearCache(); - } - - public void CreateDbTableOfArchive(string tableName) - { - var createTableSqlString = DataProvider.ContentDao.GetCreateTableCollectionInfoSqlString(tableName); - - var archiveTableName = TableMetadataManager.GetTableNameOfArchive(tableName); - - createTableSqlString = createTableSqlString.Replace(tableName, archiveTableName); - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - var reader = new System.IO.StringReader(createTableSqlString); - string sql; - - while (null != (sql = SqlUtils.ReadNextStatementFromStream(reader))) - { - ExecuteNonQuery(trans, sql.Trim()); - } - - TableColumnManager.ClearCache(); - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - } - - public TableInfo GetTableCollectionInfo(string tableName) - { - TableInfo info = null; - - var parms = new IDataParameter[] - { - GetParameter(ParmTableName, DataType.VarChar, 50, tableName) - }; - - using (var rdr = ExecuteReader(SqlSelectTable, parms)) - { - if (rdr.Read()) - { - var i = 0; - info = new TableInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetBool(rdr, i++), GetBool(rdr, i++), GetBool(rdr, i++), GetString(rdr, i)); - } - rdr.Close(); - } - - return info; - } - - public string GetDisplayName(string tableName) - { - var displayName = string.Empty; - - var parms = new IDataParameter[] - { - GetParameter(ParmTableName, DataType.VarChar, 50, tableName) - }; - - using (var rdr = ExecuteReader(SqlSelectDisplayName, parms)) - { - if (rdr.Read()) - { - displayName = GetString(rdr, 0); - } - rdr.Close(); - } - - return displayName; - } - - public IDataReader GetDataSourceCreatedInDb() - { - var parms = new IDataParameter[] - { - GetParameter(ParmIsCreatedInDb, DataType.VarChar, 18, true.ToString()) - }; - - var enumerable = ExecuteReader(SqlSelectAllTableCreatedInDb, parms); - return enumerable; - } - - /// - /// Get Total AuxiliaryTable Count - /// - public int GetAuxiliaryTableCount() - { - return Convert.ToInt32(ExecuteScalar(SqlSelectTableCount)); - } - - public List GetTableNameList() - { - var list = new List(); - using (var rdr = ExecuteReader(SqlSelectTableName)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - - return list; - } - - public List GetTableCollectionInfoListCreatedInDb() - { - var list = new List(); - - string sqlString = - $"SELECT Id, TableName, DisplayName, AttributeNum, IsCreatedInDB, IsChangedAfterCreatedInDB, IsDefault, Description FROM siteserver_Table WHERE IsCreatedInDB = '{true}' ORDER BY IsCreatedInDB DESC, TableName"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var i = 0; - var info = new TableInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetBool(rdr, i++), GetBool(rdr, i++), GetBool(rdr, i++), GetString(rdr, i)); - list.Add(info); - } - rdr.Close(); - } - - return list; - } - - public List GetTableCollectionInfoList() - { - var list = new List(); - - const string sqlString = "SELECT Id, TableName, DisplayName, AttributeNum, IsCreatedInDB, IsChangedAfterCreatedInDB, IsDefault, Description FROM siteserver_Table ORDER BY IsCreatedInDB DESC, TableName"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var i = 0; - var info = new TableInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetInt(rdr, i++), GetBool(rdr, i++), GetBool(rdr, i++), GetBool(rdr, i++), GetString(rdr, i)); - list.Add(info); - } - rdr.Close(); - } - - return list; - } - - public List GetTableNameListCreatedInDb() - { - var list = new List(); - - string sqlString = - $"SELECT TableName FROM siteserver_Table WHERE IsCreatedInDB = '{true}'"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - - return list; - } - - public bool IsTableExistsAndCreated() - { - var isExists = false; - - const string sqlString = "SELECT TableName FROM siteserver_Table WHERE IsCreatedInDB = 'True'"; - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - isExists = true; - } - rdr.Close(); - } - - return isExists; - } - - public bool IsExistsAndCreated(string tableName) - { - var isExists = false; - - string sqlString = - $"SELECT TableName FROM siteserver_Table WHERE TableName = '{PageUtils.FilterSql(tableName)}' AND IsCreatedInDB = 'True'"; - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - isExists = true; - } - rdr.Close(); - } - - return isExists; - } - - public bool IsExists(string tableName) - { - var isExists = false; - - string sqlString = - $"SELECT TableName FROM siteserver_Table WHERE TableName = '{PageUtils.FilterSql(tableName)}'"; - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - isExists = true; - } - rdr.Close(); - } - - return isExists; - } - - public string GetFirstTableName() - { - var tableName = string.Empty; - - const string sqlString = "SELECT TableName FROM siteserver_Table WHERE IsCreatedInDB = 'True'"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - tableName = GetString(rdr, 0); - } - rdr.Close(); - } - - return tableName; - } - - public void CreateAllTableCollectionInfoIfNotExists() - { - //添加后台内容表 - if (!IsTableExistsAndCreated()) - { - var tableName = DefaultTableName; - if (!IsExists(tableName)) - { - var tableInfo = new TableInfo(0, tableName, "后台内容表", 0, false, false, true, string.Empty); - var metadataInfoList = DataProvider.TableMetadataDao.GetDefaultTableMetadataInfoList(tableName); - Insert(tableInfo, metadataInfoList); - } - CreateDbTable(tableName); - } - } - - private const string DefaultTableName = "model_Content"; - } -} diff --git a/SiteServer.CMS/Provider/TableMatchDao.cs b/SiteServer.CMS/Provider/TableMatchDao.cs deleted file mode 100644 index 8a75b87de..000000000 --- a/SiteServer.CMS/Provider/TableMatchDao.cs +++ /dev/null @@ -1,138 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Provider -{ - public class TableMatchDao : DataProviderBase - { - public override string TableName => "siteserver_TableMatch"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(TableMatchInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(TableMatchInfo.ConnectionString), - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = nameof(TableMatchInfo.TableName), - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = nameof(TableMatchInfo.ConnectionStringToMatch), - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = nameof(TableMatchInfo.TableNameToMatch), - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = nameof(TableMatchInfo.ColumnsMap), - DataType = DataType.Text - } - }; - - private const string SqlSelectTableMatch = "SELECT Id, ConnectionString, TableName, ConnectionStringToMatch, TableNameToMatch, ColumnsMap FROM siteserver_TableMatch WHERE Id = @Id"; - - private const string SqlUpdateTableMatch = "UPDATE siteserver_TableMatch SET ConnectionString = @ConnectionString, TableName = @TableName, ConnectionStringToMatch = @ConnectionStringToMatch, TableNameToMatch = @TableNameToMatch, ColumnsMap = @ColumnsMap WHERE Id = @Id"; - - private const string SqlDeleteTableMatch = "DELETE FROM siteserver_TableMatch WHERE Id = @Id"; - - private const string ParmId = "@Id"; - private const string ParmConnectionString = "@ConnectionString"; - private const string ParmTableName = "@TableName"; - private const string ParmConnectionStringToMatch = "@ConnectionStringToMatch"; - private const string ParmTableNameToMatch = "@TableNameToMatch"; - private const string ParmColumnsMap = "@ColumnsMap"; - - public int Insert(TableMatchInfo tableMatchInfo) - { - const string sqlString = "INSERT INTO siteserver_TableMatch (ConnectionString, TableName, ConnectionStringToMatch, TableNameToMatch, ColumnsMap) VALUES (@ConnectionString, @TableName, @ConnectionStringToMatch, @TableNameToMatch, @ColumnsMap)"; - - var insertParms = new IDataParameter[] - { - GetParameter(ParmConnectionString, DataType.VarChar, 200, tableMatchInfo.ConnectionString), - GetParameter(ParmTableName, DataType.VarChar, 200, tableMatchInfo.TableName), - GetParameter(ParmConnectionStringToMatch, DataType.VarChar, 200, tableMatchInfo.ConnectionStringToMatch), - GetParameter(ParmTableNameToMatch, DataType.VarChar, 200, tableMatchInfo.TableNameToMatch), - GetParameter(ParmColumnsMap, DataType.Text, TranslateUtils.NameValueCollectionToString(tableMatchInfo.ColumnsMap)) - }; - - return ExecuteNonQueryAndReturnId(TableName, nameof(TableMatchInfo.Id), sqlString, insertParms); - } - - public void Update(TableMatchInfo tableMatchInfo) - { - var updateParms = new IDataParameter[] - { - GetParameter(ParmConnectionString, DataType.VarChar, 200, tableMatchInfo.ConnectionString), - GetParameter(ParmTableName, DataType.VarChar, 200, tableMatchInfo.TableName), - GetParameter(ParmConnectionStringToMatch, DataType.VarChar, 200, tableMatchInfo.ConnectionStringToMatch), - GetParameter(ParmTableNameToMatch, DataType.VarChar, 200, tableMatchInfo.TableNameToMatch), - GetParameter(ParmColumnsMap, DataType.Text, TranslateUtils.NameValueCollectionToString(tableMatchInfo.ColumnsMap)), - GetParameter(ParmId, DataType.Integer, tableMatchInfo.Id) - }; - - using (var conn = GetConnection()) - { - conn.Open(); - ExecuteNonQuery(conn, SqlUpdateTableMatch, updateParms); - } - } - - public void Delete(int id) - { - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, id) - }; - - using (var conn = GetConnection()) - { - conn.Open(); - ExecuteNonQuery(conn, SqlDeleteTableMatch, parms); - } - } - - public TableMatchInfo GetTableMatchInfo(int id) - { - TableMatchInfo tableMatchInfo = null; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, id) - }; - - using (var rdr = ExecuteReader(SqlSelectTableMatch, parms)) - { - if (rdr.Read()) - { - var i = 0; - tableMatchInfo = new TableMatchInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), TranslateUtils.ToNameValueCollection(GetString(rdr, i))); - } - rdr.Close(); - } - - return tableMatchInfo; - } - } -} diff --git a/SiteServer.CMS/Provider/TableMetadataDao.cs b/SiteServer.CMS/Provider/TableMetadataDao.cs deleted file mode 100644 index b9d6d59d9..000000000 --- a/SiteServer.CMS/Provider/TableMetadataDao.cs +++ /dev/null @@ -1,597 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Provider -{ - public class TableMetadataDao : DataProviderBase - { - public override string TableName => "siteserver_TableMetadata"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(TableMetadataInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(TableMetadataInfo.TableName), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(TableMetadataInfo.AttributeName), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(TableMetadataInfo.DataType), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(TableMetadataInfo.DataLength), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(TableMetadataInfo.Taxis), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(TableMetadataInfo.IsSystem), - DataType = DataType.VarChar, - Length = 18 - } - }; - - private const string SqlSelectTableMetadata = "SELECT Id, TableName, AttributeName, DataType, DataLength, Taxis, IsSystem FROM siteserver_TableMetadata WHERE Id = @Id"; - - private const string SqlSelectAllTableMetadataByEnname = "SELECT Id, TableName, AttributeName, DataType, DataLength, Taxis, IsSystem FROM siteserver_TableMetadata WHERE TableName = @TableName ORDER BY IsSystem DESC, Taxis"; - - private const string SqlSelectTableMetadataCountByEnname = "SELECT COUNT(*) FROM siteserver_TableMetadata WHERE TableName = @TableName"; - - private const string SqlSelectTableMetadataByTableNameAndAttributeName = "SELECT Id, TableName, AttributeName, DataType, DataLength, Taxis, IsSystem FROM siteserver_TableMetadata WHERE TableName = @TableName AND AttributeName = @AttributeName"; - - private const string SqlSelectIdByTableNameAndAttributeName = "SELECT Id FROM siteserver_TableMetadata WHERE TableName = @TableName AND AttributeName = @AttributeName"; - - private const string SqlSelectTableMetadataAllAttributeName = "SELECT AttributeName FROM siteserver_TableMetadata WHERE TableName = @TableName ORDER BY Taxis"; - - private const string SqlUpdateTableMetadata = "UPDATE siteserver_TableMetadata SET TableName = @TableName, AttributeName = @AttributeName, DataType = @DataType, DataLength = @DataLength, IsSystem = @IsSystem WHERE Id = @Id"; - - private const string SqlDeleteTableMetadata = "DELETE FROM siteserver_TableMetadata WHERE Id = @Id"; - - private const string SqlDeleteTableMetadataByTableName = "DELETE FROM siteserver_TableMetadata WHERE TableName = @TableName"; - - private const string SqlUpdateTableMetadataTaxis = "UPDATE siteserver_TableMetadata SET Taxis = @Taxis WHERE Id = @Id"; - - private const string ParmId = "@Id"; - private const string ParmTableCollectionInfoEnname = "@TableName"; - private const string ParmAttributeName = "@AttributeName"; - private const string ParmDataType = "@DataType"; - private const string ParmDataLength = "@DataLength"; - private const string ParmTaxis = "@Taxis"; - private const string ParmIsSystem = "@IsSystem"; - - public void Insert(TableMetadataInfo info) - { - if (IsExists(info.TableName, info.AttributeName)) return; - - const string sqlString = "INSERT INTO siteserver_TableMetadata (TableName, AttributeName, DataType, DataLength, Taxis, IsSystem) VALUES (@TableName, @AttributeName, @DataType, @DataLength, @Taxis, @IsSystem)"; - - var parameters = new IDataParameter[] - { - GetParameter(ParmTableCollectionInfoEnname, DataType.VarChar, 50, info.TableName), - GetParameter(ParmAttributeName, DataType.VarChar, 50, info.AttributeName), - GetParameter(ParmDataType, DataType.VarChar, 50, info.DataType.Value), - GetParameter(ParmDataLength, DataType.Integer, info.DataLength), - GetParameter(ParmTaxis, DataType.Integer, GetMaxTaxis(info.TableName) + 1), - GetParameter(ParmIsSystem, DataType.VarChar, 18, info.IsSystem.ToString()) - }; - - ExecuteNonQuery(sqlString, parameters); - - DataProvider.TableDao.UpdateAttributeNum(info.TableName); - DataProvider.TableDao.UpdateIsChangedAfterCreatedInDbToTrue(info.TableName); - - TableMetadataManager.ClearCache(); - } - - - internal void InsertWithTransaction(TableMetadataInfo info, int taxis, IDbTransaction trans) - { - if (IsExistsWithTransaction(info.TableName, info.AttributeName, trans)) return; - - const string sqlString = "INSERT INTO siteserver_TableMetadata (TableName, AttributeName, DataType, DataLength, Taxis, IsSystem) VALUES (@TableName, @AttributeName, @DataType, @DataLength, @Taxis, @IsSystem)"; - - var insertParms = new IDataParameter[] - { - GetParameter(ParmTableCollectionInfoEnname, DataType.VarChar, 50, info.TableName), - GetParameter(ParmAttributeName, DataType.VarChar, 50, info.AttributeName), - GetParameter(ParmDataType, DataType.VarChar, 50, info.DataType.Value), - GetParameter(ParmDataLength, DataType.Integer, info.DataLength), - GetParameter(ParmTaxis, DataType.Integer, taxis), - GetParameter(ParmIsSystem, DataType.VarChar, 18, info.IsSystem.ToString()) - }; - - ExecuteNonQuery(trans, sqlString, insertParms); - if (info.StyleInfo != null) - { - info.StyleInfo.TableName = info.TableName; - info.StyleInfo.AttributeName = info.AttributeName; - DataProvider.TableStyleDao.InsertWithTransaction(info.StyleInfo, trans); - TableStyleManager.IsChanged = true; - } - - TableMetadataManager.ClearCache(); - } - - public void Update(TableMetadataInfo info) - { - var isSqlChanged = true; - var originalInfo = GetTableMetadataInfo(info.Id); - if (originalInfo != null) - { - if (StringUtils.EqualsIgnoreCase(info.TableName, originalInfo.TableName) - && StringUtils.EqualsIgnoreCase(info.AttributeName, originalInfo.AttributeName) - && info.DataType == originalInfo.DataType - && info.DataLength == originalInfo.DataLength - && info.IsSystem == originalInfo.IsSystem) - { - isSqlChanged = false; - } - } - - if (!isSqlChanged) return; - - var updateParms = new IDataParameter[] - { - GetParameter(ParmTableCollectionInfoEnname, DataType.VarChar, 50, info.TableName), - GetParameter(ParmAttributeName, DataType.VarChar, 50, info.AttributeName), - GetParameter(ParmDataType, DataType.VarChar, 50, info.DataType.Value), - GetParameter(ParmDataLength, DataType.Integer, info.DataLength), - GetParameter(ParmIsSystem, DataType.VarChar, 18, info.IsSystem.ToString()), - GetParameter(ParmId, DataType.Integer, info.Id) - }; - - ExecuteNonQuery(SqlUpdateTableMetadata, updateParms); - - DataProvider.TableDao.UpdateIsChangedAfterCreatedInDbToTrue(info.TableName); - TableMetadataManager.ClearCache(); - } - - public void Delete(int id) - { - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, id) - }; - - var metadataInfo = GetTableMetadataInfo(id); - - ExecuteNonQuery(SqlDeleteTableMetadata, parms); - - DataProvider.TableDao.UpdateAttributeNum(metadataInfo.TableName); - DataProvider.TableDao.UpdateIsChangedAfterCreatedInDbToTrue(metadataInfo.TableName); - TableMetadataManager.ClearCache(); - } - - public void Delete(string tableName) - { - Delete(tableName, null); - } - - public void Delete(string tableName, IDbTransaction trans) - { - var parms = new IDataParameter[] - { - GetParameter(ParmTableCollectionInfoEnname, DataType.VarChar,50, tableName) - }; - if (trans == null) - { - ExecuteNonQuery(SqlDeleteTableMetadataByTableName, parms); - TableMetadataManager.ClearCache(); - } - else - { - ExecuteNonQuery(trans, SqlDeleteTableMetadataByTableName, parms); - TableMetadataManager.ClearCache(); - } - } - - public TableMetadataInfo GetTableMetadataInfo(int id) - { - TableMetadataInfo info = null; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, id) - }; - - using (var rdr = ExecuteReader(SqlSelectTableMetadata, parms)) - { - if (rdr.Read()) - { - var i = 0; - info = new TableMetadataInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), DataTypeUtils.GetEnumType(GetString(rdr, i++)), GetInt(rdr, i++), GetInt(rdr, i++), GetBool(rdr, i)); - } - rdr.Close(); - } - - return info; - } - - public TableMetadataInfo GetTableMetadataInfo(string tableName, string attributeName) - { - TableMetadataInfo info = null; - - var parms = new IDataParameter[] - { - GetParameter(ParmTableCollectionInfoEnname, DataType.VarChar, 50, tableName), - GetParameter(ParmAttributeName, DataType.VarChar, 50, attributeName) - }; - - using (var rdr = ExecuteReader(SqlSelectTableMetadataByTableNameAndAttributeName, parms)) - { - if (rdr.Read()) - { - var i = 0; - info = new TableMetadataInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), DataTypeUtils.GetEnumType(GetString(rdr, i++)), GetInt(rdr, i++), GetInt(rdr, i++), GetBool(rdr, i)); - } - rdr.Close(); - } - - return info; - } - - public int GetId(string tableName, string attributeName) - { - var id = 0; - - var parms = new IDataParameter[] - { - GetParameter(ParmTableCollectionInfoEnname, DataType.VarChar, 50, tableName), - GetParameter(ParmAttributeName, DataType.VarChar, 50, attributeName) - }; - - using (var conn = GetConnection()) - { - conn.Open(); - using (var rdr = ExecuteReader(conn, SqlSelectIdByTableNameAndAttributeName, parms)) - { - if (rdr.Read()) - { - id = GetInt(rdr, 0); - } - rdr.Close(); - } - } - - return id; - } - - public IDataReader GetDataSource(string tableName) - { - var parms = new IDataParameter[] - { - GetParameter(ParmTableCollectionInfoEnname, DataType.VarChar, 50, tableName) - }; - - var enumerable = ExecuteReader(SqlSelectAllTableMetadataByEnname, parms); - return enumerable; - } - - public List GetTableMetadataInfoList(string tableName) - { - var list = new List(); - - var parms = new IDataParameter[] - { - GetParameter(ParmTableCollectionInfoEnname, DataType.VarChar, 50, tableName) - }; - - using (var rdr = ExecuteReader(SqlSelectAllTableMetadataByEnname, parms)) - { - while (rdr.Read()) - { - var i = 0; - var info = new TableMetadataInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), DataTypeUtils.GetEnumType(GetString(rdr, i++)), GetInt(rdr, i++), GetInt(rdr, i++), GetBool(rdr, i)); - list.Add(info); - } - rdr.Close(); - } - return list; - } - - public Dictionary> GetTableNameWithTableMetadataInfoList() - { - var dict = new Dictionary>(); - var tableNameList = DataProvider.TableDao.GetTableNameList(); - foreach (var tableName in tableNameList) - { - var list = GetTableMetadataInfoList(tableName); - if (list != null && list.Count > 0) - { - dict.Add(tableName, list); - } - } - return dict; - } - - /// - /// Get Total TableCollectionInfo Count - /// - public int GetTableMetadataCountByEnName(string tableName) - { - var count = 0; - - var parms = new IDataParameter[] - { - GetParameter(ParmTableCollectionInfoEnname, DataType.VarChar, 50, tableName) - }; - - using (var rdr = ExecuteReader(SqlSelectTableMetadataCountByEnname, parms)) - { - if (rdr.Read()) - { - count = GetInt(rdr, 0); - } - rdr.Close(); - } - - return count; - } - - public bool IsExists(string tableName, string attributeName) - { - var exists = false; - - const string sqlString = "SELECT Id FROM siteserver_TableMetadata WHERE TableName = @TableName AND AttributeName = @AttributeName"; - var parms = new IDataParameter[] - { - GetParameter(ParmTableCollectionInfoEnname, DataType.VarChar, 50, tableName), - GetParameter(ParmAttributeName, DataType.VarChar, 50, attributeName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - if (!rdr.IsDBNull(0)) - { - exists = true; - } - } - rdr.Close(); - } - return exists; - } - - public bool IsExistsWithTransaction(string tableName, string attributeName, IDbTransaction trans) - { - var exists = false; - - const string sqlString = "SELECT Id FROM siteserver_TableMetadata WHERE TableName = @TableName AND AttributeName = @AttributeName"; - var parms = new IDataParameter[] - { - GetParameter(ParmTableCollectionInfoEnname, DataType.VarChar, 50, tableName), - GetParameter(ParmAttributeName, DataType.VarChar, 50, attributeName) - }; - - using (var rdr = ExecuteReader(trans, sqlString, parms)) - { - if (rdr.Read()) - { - if (!rdr.IsDBNull(0)) - { - exists = true; - } - } - rdr.Close(); - } - return exists; - } - - public List GetAttributeNameList(string tableName) - { - var parms = new IDataParameter[] - { - GetParameter(ParmTableCollectionInfoEnname, DataType.VarChar, 50, tableName) - }; - - var list = new List(); - using (var rdr = ExecuteReader(SqlSelectTableMetadataAllAttributeName, parms)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - - return list; - } - - /// - /// Get max Taxis in the database - /// - public int GetMaxTaxis(string tableName) - { - const string sqlString = "SELECT MAX(Taxis) FROM siteserver_TableMetadata WHERE TableName = @TableName"; - - var parms = new IDataParameter[] - { - GetParameter(ParmTableCollectionInfoEnname, DataType.VarChar, 50, tableName) - }; - - return DataProvider.DatabaseDao.GetIntResult(sqlString, parms); - } - - - /// - /// Change The Texis To Higher Level - /// - public void TaxisUp(int selectedId, string tableName) - { - //Get Higher Taxis and ClassID - //var sqlString = "SELECT TOP 1 Id, Taxis FROM siteserver_TableMetadata WHERE ((Taxis > (SELECT Taxis FROM siteserver_TableMetadata WHERE (Id = @Id AND TableName = @TableName1))) AND TableName=@TableName2) ORDER BY Taxis"; - var sqlString = SqlUtils.ToTopSqlString("siteserver_TableMetadata", "Id, Taxis", - "WHERE ((Taxis > (SELECT Taxis FROM siteserver_TableMetadata WHERE (Id = @Id AND TableName = @TableName1))) AND TableName=@TableName2)", - "ORDER BY Taxis", - 1); - var higherId = 0; - var higherTaxis = 0; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, selectedId), - GetParameter("@TableName1", DataType.VarChar, 50, tableName), - GetParameter("@TableName2", DataType.VarChar, 50, tableName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - higherId = GetInt(rdr, 0); - higherTaxis = GetInt(rdr, 1); - } - rdr.Close(); - } - - //Get Taxis Of Selected Class - var selectedTaxis = GetTaxis(selectedId); - - if (higherId != 0) - { - //Set The Selected Class Taxis To Higher Level - SetTaxis(selectedId, higherTaxis); - //Set The Higher Class Taxis To Lower Level - SetTaxis(higherId, selectedTaxis); - //DataProvider.CreateTableCollectionInfoDAO().UpdateIsChangedAfterCreatedInDB(EBoolean.True, tableName); - } - } - - /// - /// Change The Texis To Lower Level - /// - public void TaxisDown(int selectedId, string tableName) - { - //Get Lower Taxis and ClassID - //var sqlString = "SELECT TOP 1 Id, Taxis FROM siteserver_TableMetadata WHERE ((Taxis < (SELECT Taxis FROM siteserver_TableMetadata WHERE (Id = @Id AND TableName = @TableName1))) AND TableName = @TableName2) ORDER BY Taxis DESC"; - var sqlString = SqlUtils.ToTopSqlString("siteserver_TableMetadata", "Id, Taxis", - "WHERE ((Taxis < (SELECT Taxis FROM siteserver_TableMetadata WHERE (Id = @Id AND TableName = @TableName1))) AND TableName = @TableName2)", - "ORDER BY Taxis DESC", 1); - - var lowerId = 0; - var lowerTaxis = 0; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, selectedId), - GetParameter("@TableName1", DataType.VarChar, 50, tableName), - GetParameter("@TableName2", DataType.VarChar, 50, tableName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - lowerId = GetInt(rdr, 0); - lowerTaxis = GetInt(rdr, 1); - } - rdr.Close(); - } - - //Get Taxis Of Selected Class - var selectedTaxis = GetTaxis(selectedId); - - if (lowerId != 0) - { - //Set The Selected Class Taxis To Lower Level - SetTaxis(selectedId, lowerTaxis); - //Set The Lower Class Taxis To Higher Level - SetTaxis(lowerId, selectedTaxis); - //DataProvider.CreateTableCollectionInfoDAO().UpdateIsChangedAfterCreatedInDB(EBoolean.True, tableName); - } - } - - private int GetTaxis(int selectedId) - { - const string sqlString = "SELECT Taxis FROM siteserver_TableMetadata WHERE (Id = @Id)"; - var taxis = 0; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, selectedId) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - taxis = GetInt(rdr, 0); - } - rdr.Close(); - } - - return taxis; - } - - private void SetTaxis(int id, int taxis) - { - var parms = new IDataParameter[] - { - GetParameter(ParmTaxis, DataType.Integer, taxis), - GetParameter(ParmId, DataType.Integer, id) - }; - - ExecuteNonQuery(SqlUpdateTableMetadataTaxis, parms); - TableMetadataManager.ClearCache(); - } - - public List GetAddColumnsSqlString(string tableName, TableMetadataInfo metadataInfo) - { - var sqlList = new List(); - var columnSqlString = SqlUtils.GetColumnSqlString(metadataInfo.DataType, metadataInfo.AttributeName, metadataInfo.DataLength); - var alterSqlString = SqlUtils.GetAddColumnsSqlString(tableName, columnSqlString); - sqlList.Add(alterSqlString); - return sqlList; - } - - public List GetDefaultTableMetadataInfoList(string tableName) - { - var list = new List(); - - var metadataInfo = new TableMetadataInfo(0, tableName, BackgroundContentAttribute.SubTitle, DataType.VarChar, 255, 0, true); - list.Add(metadataInfo); - metadataInfo = new TableMetadataInfo(0, tableName, BackgroundContentAttribute.ImageUrl, DataType.VarChar, 200, 0, true); - list.Add(metadataInfo); - metadataInfo = new TableMetadataInfo(0, tableName, BackgroundContentAttribute.VideoUrl, DataType.VarChar, 200, 0, true); - list.Add(metadataInfo); - metadataInfo = new TableMetadataInfo(0, tableName, BackgroundContentAttribute.FileUrl, DataType.VarChar, 200, 0, true); - list.Add(metadataInfo); - metadataInfo = new TableMetadataInfo(0, tableName, BackgroundContentAttribute.Content, DataType.Text, 16, 0, true); - list.Add(metadataInfo); - metadataInfo = new TableMetadataInfo(0, tableName, BackgroundContentAttribute.Summary, DataType.Text, 16, 0, true); - list.Add(metadataInfo); - metadataInfo = new TableMetadataInfo(0, tableName, BackgroundContentAttribute.Author, DataType.VarChar, 255, 0, true); - list.Add(metadataInfo); - metadataInfo = new TableMetadataInfo(0, tableName, BackgroundContentAttribute.Source, DataType.VarChar, 255, 0, true); - list.Add(metadataInfo); - return list; - } - } -} diff --git a/SiteServer.CMS/Provider/TableStyleDao.cs b/SiteServer.CMS/Provider/TableStyleDao.cs deleted file mode 100644 index 3db0d671d..000000000 --- a/SiteServer.CMS/Provider/TableStyleDao.cs +++ /dev/null @@ -1,414 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Provider -{ - public class TableStyleDao : DataProviderBase - { - public override string TableName => "siteserver_TableStyle"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(TableStyleInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(TableStyleInfo.RelatedIdentity), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(TableStyleInfo.TableName), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(TableStyleInfo.AttributeName), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(TableStyleInfo.Taxis), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(TableStyleInfo.DisplayName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(TableStyleInfo.HelpText), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(TableStyleInfo.IsVisibleInList), - DataType = DataType.VarChar, - Length = 18 - }, - new TableColumnInfo - { - ColumnName = nameof(TableStyleInfo.InputType), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(TableStyleInfo.DefaultValue), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(TableStyleInfo.IsHorizontal), - DataType = DataType.VarChar, - Length = 18 - }, - new TableColumnInfo - { - ColumnName = nameof(TableStyleInfo.ExtendValues), - DataType = DataType.Text - } - }; - - private const string SqlSelectTableStyle = "SELECT Id, RelatedIdentity, TableName, AttributeName, Taxis, DisplayName, HelpText, IsVisibleInList, InputType, DefaultValue, IsHorizontal, ExtendValues FROM siteserver_TableStyle WHERE RelatedIdentity = @RelatedIdentity AND TableName = @TableName AND AttributeName = @AttributeName"; - - private const string SqlSelectId = "SELECT Id FROM siteserver_TableStyle WHERE RelatedIdentity = @RelatedIdentity AND TableName = @TableName AND AttributeName = @AttributeName"; - - private const string SqlSelectTableStyleById = "SELECT Id, RelatedIdentity, TableName, AttributeName, Taxis, DisplayName, HelpText, IsVisibleInList, InputType, DefaultValue, IsHorizontal, ExtendValues FROM siteserver_TableStyle WHERE Id = @Id"; - - //private const string SqlSelectTableStyles = "SELECT Id, RelatedIdentity, TableName, AttributeName, Taxis, DisplayName, HelpText, IsVisibleInList, InputType, DefaultValue, IsHorizontal, ExtendValues FROM siteserver_TableStyle WHERE TableName = @TableName AND AttributeName = @AttributeName ORDER BY RelatedIdentity"; - - private const string SqlSelectAllTableStyle = "SELECT Id, RelatedIdentity, TableName, AttributeName, Taxis, DisplayName, HelpText, IsVisibleInList, InputType, DefaultValue, IsHorizontal, ExtendValues FROM siteserver_TableStyle ORDER BY Taxis DESC, Id DESC"; - - private const string SqlUpdateTableStyle = "UPDATE siteserver_TableStyle SET AttributeName = @AttributeName, Taxis = @Taxis, DisplayName = @DisplayName, HelpText = @HelpText, IsVisibleInList = @IsVisibleInList, InputType = @InputType, DefaultValue = @DefaultValue, IsHorizontal = @IsHorizontal, ExtendValues = @ExtendValues WHERE Id = @Id"; - - private const string SqlDeleteTableStyle = "DELETE FROM siteserver_TableStyle WHERE RelatedIdentity = @RelatedIdentity AND TableName = @TableName AND AttributeName = @AttributeName"; - - private const string SqlInsertTableStyle = "INSERT INTO siteserver_TableStyle (RelatedIdentity, TableName, AttributeName, Taxis, DisplayName, HelpText, IsVisibleInList, InputType, DefaultValue, IsHorizontal, ExtendValues) VALUES (@RelatedIdentity, @TableName, @AttributeName, @Taxis, @DisplayName, @HelpText, @IsVisibleInList, @InputType, @DefaultValue, @IsHorizontal, @ExtendValues)"; - - private const string ParmId = "@Id"; - private const string ParmRelatedIdentity = "@RelatedIdentity"; - private const string ParmTableName = "@TableName"; - private const string ParmAttributeName = "@AttributeName"; - private const string ParmTaxis = "@Taxis"; - private const string ParmDisplayName = "@DisplayName"; - private const string ParmHelpText = "@HelpText"; - private const string ParmIsVisibleInList = "@IsVisibleInList"; - private const string ParmInputType = "@InputType"; - private const string ParmDefaultValue = "@DefaultValue"; - private const string ParmIsHorizontal = "@IsHorizontal"; - private const string ParmExtendValues = "@ExtendValues"; - - public int Insert(TableStyleInfo styleInfo) - { - int id; - - var insertParms = new IDataParameter[] - { - GetParameter(ParmRelatedIdentity, DataType.Integer, styleInfo.RelatedIdentity), - GetParameter(ParmTableName, DataType.VarChar, 50, styleInfo.TableName), - GetParameter(ParmAttributeName, DataType.VarChar, 50, styleInfo.AttributeName), - GetParameter(ParmTaxis, DataType.Integer, styleInfo.Taxis), - GetParameter(ParmDisplayName, DataType.VarChar, 255, styleInfo.DisplayName), - GetParameter(ParmHelpText, DataType.VarChar, 255, styleInfo.HelpText), - GetParameter(ParmIsVisibleInList, DataType.VarChar, 18, styleInfo.IsVisibleInList.ToString()), - GetParameter(ParmInputType, DataType.VarChar, 50, styleInfo.InputType.Value), - GetParameter(ParmDefaultValue, DataType.VarChar, 255, styleInfo.DefaultValue), - GetParameter(ParmIsHorizontal, DataType.VarChar, 18, styleInfo.IsHorizontal.ToString()), - GetParameter(ParmExtendValues, DataType.Text, styleInfo.Additional.ToString()) - }; - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - id = ExecuteNonQueryAndReturnId(TableName, nameof(TableStyleInfo.Id), trans, SqlInsertTableStyle, insertParms); - - DataProvider.TableStyleItemDao.Insert(trans, id, styleInfo.StyleItems); - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - - return id; - } - - public void InsertWithTransaction(TableStyleInfo styleInfo, IDbTransaction trans) - { - var insertParms = new IDataParameter[] - { - GetParameter(ParmRelatedIdentity, DataType.Integer, styleInfo.RelatedIdentity), - GetParameter(ParmTableName, DataType.VarChar, 50, styleInfo.TableName), - GetParameter(ParmAttributeName, DataType.VarChar, 50, styleInfo.AttributeName), - GetParameter(ParmTaxis, DataType.Integer, styleInfo.Taxis), - GetParameter(ParmDisplayName, DataType.VarChar, 255, styleInfo.DisplayName), - GetParameter(ParmHelpText, DataType.VarChar, 255, styleInfo.HelpText), - GetParameter(ParmIsVisibleInList, DataType.VarChar, 18, styleInfo.IsVisibleInList.ToString()), - GetParameter(ParmInputType, DataType.VarChar, 50, styleInfo.InputType.Value), - GetParameter(ParmDefaultValue, DataType.VarChar, 255, styleInfo.DefaultValue), - GetParameter(ParmIsHorizontal, DataType.VarChar, 18, styleInfo.IsHorizontal.ToString()), - GetParameter(ParmExtendValues, DataType.Text, styleInfo.Additional.ToString()) - }; - - if (styleInfo.StyleItems == null || styleInfo.StyleItems.Count == 0) - { - ExecuteNonQuery(trans, SqlInsertTableStyle, insertParms); - } - else - { - var id = ExecuteNonQueryAndReturnId(TableName, nameof(TableStyleInfo.Id), trans, SqlInsertTableStyle, insertParms); - - DataProvider.TableStyleItemDao.Insert(trans, id, styleInfo.StyleItems); - } - } - - public void Update(TableStyleInfo info) - { - var updateParms = new IDataParameter[] - { - GetParameter(ParmAttributeName, DataType.VarChar, 50, info.AttributeName), - GetParameter(ParmTaxis, DataType.Integer, info.Taxis), - GetParameter(ParmDisplayName, DataType.VarChar, 255, info.DisplayName), - GetParameter(ParmHelpText, DataType.VarChar, 255, info.HelpText), - GetParameter(ParmIsVisibleInList, DataType.VarChar, 18, info.IsVisibleInList.ToString()), - GetParameter(ParmInputType, DataType.VarChar, 50, info.InputType.Value), - GetParameter(ParmDefaultValue, DataType.VarChar, 255, info.DefaultValue), - GetParameter(ParmIsHorizontal, DataType.VarChar, 18, info.IsHorizontal.ToString()), - GetParameter(ParmExtendValues, DataType.Text, info.Additional.ToString()), - GetParameter(ParmId, DataType.Integer, info.Id) - }; - - ExecuteNonQuery(SqlUpdateTableStyle, updateParms); - } - - public void Delete(string tableName) - { - if (string.IsNullOrEmpty(tableName)) return; - - const string sqlString = "DELETE FROM siteserver_TableStyle WHERE TableName = @TableName"; - - var parameters = new IDataParameter[] - { - GetParameter(ParmTableName, DataType.VarChar, 50, tableName) - }; - - ExecuteNonQuery(sqlString, parameters); - - TableStyleManager.IsChanged = true; - } - - public void Delete(int relatedIdentity, string tableName, string attributeName) - { - var parms = new IDataParameter[] - { - GetParameter(ParmRelatedIdentity, DataType.Integer, relatedIdentity), - GetParameter(ParmTableName, DataType.VarChar, 50, tableName), - GetParameter(ParmAttributeName, DataType.VarChar, 50, attributeName) - }; - - ExecuteNonQuery(SqlDeleteTableStyle, parms); - TableStyleManager.IsChanged = true; - } - - public void Delete(List relatedIdentities, string tableName) - { - if (relatedIdentities == null || relatedIdentities.Count <= 0) return; - - string sqlString = - $"DELETE FROM siteserver_TableStyle WHERE RelatedIdentity IN ({TranslateUtils.ToSqlInStringWithoutQuote(relatedIdentities)}) AND TableName = '{PageUtils.FilterSql(tableName)}'"; - ExecuteNonQuery(sqlString); - TableStyleManager.IsChanged = true; - } - - public List GetTableStyleInfoList(List relatedIdentities, string tableName) - { - var list = new List(); - - string sqlString = - $"SELECT Id, RelatedIdentity, TableName, AttributeName, Taxis, DisplayName, HelpText, IsVisibleInList, InputType, DefaultValue, IsHorizontal, ExtendValues FROM siteserver_TableStyle WHERE RelatedIdentity IN ({TranslateUtils.ToSqlInStringWithoutQuote(relatedIdentities)}) AND TableName = '{PageUtils.FilterSql(tableName)}' ORDER BY Id DESC"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetTableStyleInfoByReader(rdr)); - } - rdr.Close(); - } - - return list; - } - - public bool IsExists(int relatedIdentity, string tableName, string attributeName) - { - var exists = false; - - var parms = new IDataParameter[] - { - GetParameter(ParmRelatedIdentity, DataType.Integer, relatedIdentity), - GetParameter(ParmTableName, DataType.VarChar, 50, tableName), - GetParameter(ParmAttributeName, DataType.VarChar, 50, attributeName) - }; - - using (var rdr = ExecuteReader(SqlSelectId, parms)) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - exists = true; - } - rdr.Close(); - } - - return exists; - } - - public TableStyleInfo GetTableStyleInfo(int id) - { - TableStyleInfo styleInfo = null; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, id) - }; - - using (var rdr = ExecuteReader(SqlSelectTableStyleById, parms)) - { - if (rdr.Read()) - { - styleInfo = GetTableStyleInfoByReader(rdr); - } - rdr.Close(); - } - - return styleInfo; - } - - public TableStyleInfo GetTableStyleInfo(int relatedIdentity, string tableName, string attributeName) - { - TableStyleInfo styleInfo = null; - - var parms = new IDataParameter[] - { - GetParameter(ParmRelatedIdentity, DataType.Integer, relatedIdentity), - GetParameter(ParmTableName, DataType.VarChar, 50, tableName), - GetParameter(ParmAttributeName, DataType.VarChar, 50, attributeName) - }; - - using (var rdr = ExecuteReader(SqlSelectTableStyle, parms)) - { - if (rdr.Read()) - { - styleInfo = GetTableStyleInfoByReader(rdr); - } - rdr.Close(); - } - - return styleInfo; - } - - private TableStyleInfo GetTableStyleInfoByReader(IDataReader rdr) - { - var i = 0; - var id = GetInt(rdr, i++); - var relatedIdentity = GetInt(rdr, i++); - var tableName = GetString(rdr, i++); - var attributeName = GetString(rdr, i++); - var taxis = GetInt(rdr, i++); - var displayName = GetString(rdr, i++); - var helpText = GetString(rdr, i++); - var isVisibleInList = GetBool(rdr, i++); - var inputType = GetString(rdr, i++); - var defaultValue = GetString(rdr, i++); - var isHorizontal = GetBool(rdr, i++); - var extendValues = GetString(rdr, i); - - var styleInfo = new TableStyleInfo(id, relatedIdentity, tableName, attributeName, taxis, displayName, helpText, isVisibleInList, InputTypeUtils.GetEnumType(inputType), defaultValue, isHorizontal, extendValues); - - return styleInfo; - } - - public PairList GetAllTableStyleInfoPairs() - { - var pairs = new PairList(); - - using (var rdr = ExecuteReader(SqlSelectAllTableStyle)) - { - while (rdr.Read()) - { - var styleInfo = GetTableStyleInfoByReader(rdr); - var inputType = styleInfo.InputType; - if (InputTypeUtils.IsWithStyleItems(inputType)) - { - styleInfo.StyleItems = DataProvider.TableStyleItemDao.GetStyleItemInfoList(styleInfo.Id); - } - - var key = TableStyleManager.GetCacheKey(styleInfo.RelatedIdentity, styleInfo.TableName, styleInfo.AttributeName); - if (!pairs.ContainsKey(key)) - { - var pair = new Pair(key, styleInfo); - pairs.Add(pair); - } - } - rdr.Close(); - } - - return pairs; - } - - // public List GetTableStyleInfoWithItemsList(string tableName, string attributeName) - // { - // var list = new List(); - - // var parms = new IDataParameter[] - //{ - // GetParameter(ParmTableName, DataType.VarChar, 50, tableName), - // GetParameter(ParmAttributeName, DataType.VarChar, 50, attributeName) - //}; - - // using (var rdr = ExecuteReader(SqlSelectTableStyles, parms)) - // { - // while (rdr.Read()) - // { - // var styleInfo = GetTableStyleInfoByReader(rdr); - // if (InputTypeUtils.Equals(styleInfo.InputType, InputType.CheckBox) || InputTypeUtils.Equals(styleInfo.InputType, InputType.Radio) || InputTypeUtils.Equals(styleInfo.InputType, InputType.SelectMultiple) || InputTypeUtils.Equals(styleInfo.InputType, InputType.SelectOne)) - // { - // var styleItems = DataProvider.TableStyleItemDao.GetStyleItemInfoList(styleInfo.Id); - // if (styleItems != null && styleItems.Count > 0) - // { - // styleInfo.StyleItems = styleItems; - // } - // } - // list.Add(styleInfo); - // } - // rdr.Close(); - // } - - // return list; - // } - } -} diff --git a/SiteServer.CMS/Provider/TableStyleItemDao.cs b/SiteServer.CMS/Provider/TableStyleItemDao.cs deleted file mode 100644 index 307df18c4..000000000 --- a/SiteServer.CMS/Provider/TableStyleItemDao.cs +++ /dev/null @@ -1,144 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Provider -{ - public class TableStyleItemDao : DataProviderBase - { - public override string TableName => "siteserver_TableStyleItem"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(TableStyleItemInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(TableStyleItemInfo.TableStyleId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(TableStyleItemInfo.ItemTitle), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(TableStyleItemInfo.ItemValue), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(TableStyleItemInfo.IsSelected), - DataType = DataType.VarChar, - Length = 18 - } - }; - - private const string SqlSelectAllStyleItem = "SELECT Id, TableStyleID, ItemTitle, ItemValue, IsSelected FROM siteserver_TableStyleItem WHERE (TableStyleID = @TableStyleID)"; - - private const string SqlDeleteStyleItems = "DELETE FROM siteserver_TableStyleItem WHERE TableStyleID = @TableStyleID"; - - private const string SqlInsertStyleItem = "INSERT INTO siteserver_TableStyleItem (TableStyleID, ItemTitle, ItemValue, IsSelected) VALUES (@TableStyleID, @ItemTitle, @ItemValue, @IsSelected)"; - - private const string ParmTableStyleId = "@TableStyleID"; - private const string ParmItemTitle = "@ItemTitle"; - private const string ParmItemValue = "@ItemValue"; - private const string ParmIsSelected = "@IsSelected"; - - public void Insert(IDbTransaction trans, int tableStyleId, List styleItems) - { - if (styleItems == null || styleItems.Count <= 0) return; - - foreach (var itemInfo in styleItems) - { - var insertItemParms = new IDataParameter[] - { - GetParameter(ParmTableStyleId, DataType.Integer, tableStyleId), - GetParameter(ParmItemTitle, DataType.VarChar, 255, itemInfo.ItemTitle), - GetParameter(ParmItemValue, DataType.VarChar, 255, itemInfo.ItemValue), - GetParameter(ParmIsSelected, DataType.VarChar, 18, itemInfo.IsSelected.ToString()) - }; - - ExecuteNonQuery(trans, SqlInsertStyleItem, insertItemParms); - } - } - - public void InsertStyleItems(List styleItems) - { - if (styleItems == null || styleItems.Count == 0) return; - - using (var conn = GetConnection()) - { - conn.Open(); - using (var trans = conn.BeginTransaction()) - { - try - { - foreach (var itemInfo in styleItems) - { - var insertItemParms = new IDataParameter[] - { - GetParameter(ParmTableStyleId, DataType.Integer, itemInfo.TableStyleId), - GetParameter(ParmItemTitle, DataType.VarChar, 255, itemInfo.ItemTitle), - GetParameter(ParmItemValue, DataType.VarChar, 255, itemInfo.ItemValue), - GetParameter(ParmIsSelected, DataType.VarChar, 18, itemInfo.IsSelected.ToString()) - }; - - ExecuteNonQuery(trans, SqlInsertStyleItem, insertItemParms); - - } - - trans.Commit(); - } - catch - { - trans.Rollback(); - throw; - } - } - } - } - - public void DeleteStyleItems(int tableStyleId) - { - var parms = new IDataParameter[] - { - GetParameter(ParmTableStyleId, DataType.Integer, tableStyleId) - }; - - ExecuteNonQuery(SqlDeleteStyleItems, parms); - } - - public List GetStyleItemInfoList(int tableStyleId) - { - var styleItems = new List(); - - var parms = new IDataParameter[] - { - GetParameter(ParmTableStyleId, DataType.Integer, tableStyleId) - }; - - using (var rdr = ExecuteReader(SqlSelectAllStyleItem, parms)) - { - while (rdr.Read()) - { - var i = 0; - var info = new TableStyleItemInfo(GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetBool(rdr, i)); - styleItems.Add(info); - } - rdr.Close(); - } - return styleItems; - } - } -} diff --git a/SiteServer.CMS/Provider/TagDao.cs b/SiteServer.CMS/Provider/TagDao.cs deleted file mode 100644 index a5fb03771..000000000 --- a/SiteServer.CMS/Provider/TagDao.cs +++ /dev/null @@ -1,282 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Data; -using System.Text; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Provider -{ - public class TagDao : DataProviderBase - { - public override string TableName => "siteserver_Tag"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(TagInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(TagInfo.SiteId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(TagInfo.ContentIdCollection), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(TagInfo.Tag), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(TagInfo.UseNum), - DataType = DataType.Integer - } - }; - - private const string ParmId = "@Id"; - private const string ParmSiteId = "@SiteId"; - private const string ParmContentIdCollection = "@ContentIdCollection"; - private const string ParmTag = "@Tag"; - private const string ParmUseNum = "@UseNum"; - - public int Insert(TagInfo tagInfo) - { - const string sqlString = "INSERT INTO siteserver_Tag (SiteId, ContentIdCollection, Tag, UseNum) VALUES (@SiteId, @ContentIdCollection, @Tag, @UseNum)"; - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, tagInfo.SiteId), - GetParameter(ParmContentIdCollection, DataType.VarChar, 255, tagInfo.ContentIdCollection), - GetParameter(ParmTag, DataType.VarChar, 255, tagInfo.Tag), - GetParameter(ParmUseNum, DataType.Integer, tagInfo.UseNum) - }; - - return ExecuteNonQueryAndReturnId(TableName, nameof(TagInfo.Id), sqlString, parms); - } - - public void Update(TagInfo tagInfo) - { - var sqlString = "UPDATE siteserver_Tag SET ContentIdCollection = @ContentIdCollection, UseNum = @UseNum WHERE Id = @Id"; - - var parms = new IDataParameter[] - { - GetParameter(ParmContentIdCollection, DataType.VarChar, 255, tagInfo.ContentIdCollection), - GetParameter(ParmUseNum, DataType.Integer, tagInfo.UseNum), - GetParameter(ParmId, DataType.Integer, tagInfo.Id) - }; - - ExecuteNonQuery(sqlString, parms); - } - - public TagInfo GetTagInfo(int siteId, string tag) - { - TagInfo tagInfo = null; - - var sqlString = "SELECT Id, SiteId, ContentIdCollection, Tag, UseNum FROM siteserver_Tag WHERE SiteId = @SiteId AND Tag = @Tag"; - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId), - GetParameter(ParmTag, DataType.VarChar, 255, tag) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - var i = 0; - tagInfo = new TagInfo(GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetInt(rdr, i)); - } - rdr.Close(); - } - return tagInfo; - } - - public List GetTagInfoList(int siteId, int contentId) - { - var list = new List(); - - var whereString = GetWhereString(null, siteId, contentId); - string sqlString = - $"SELECT Id, SiteId, ContentIdCollection, Tag, UseNum FROM siteserver_Tag {whereString}"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var i = 0; - var tagInfo = new TagInfo(GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetInt(rdr, i)); - list.Add(tagInfo); - } - rdr.Close(); - } - return list; - } - - public string GetSqlString(int siteId, int contentId, bool isOrderByCount, int totalNum) - { - var whereString = GetWhereString(null, siteId, contentId); - var orderString = string.Empty; - if (isOrderByCount) - { - orderString = "ORDER BY UseNum DESC"; - } - - return SqlUtils.ToTopSqlString("siteserver_Tag", "Id, SiteId, ContentIdCollection, Tag, UseNum", whereString, orderString, totalNum); - } - - public List GetTagInfoList(int siteId, int contentId, bool isOrderByCount, int totalNum) - { - var list = new List(); - - var whereString = GetWhereString(null, siteId, contentId); - var orderString = string.Empty; - if (isOrderByCount) - { - orderString = "ORDER BY UseNum DESC"; - } - - var sqlString = SqlUtils.ToTopSqlString("siteserver_Tag", "Id, SiteId, ContentIdCollection, Tag, UseNum", whereString, orderString, totalNum); - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var i = 0; - var tagInfo = new TagInfo(GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetInt(rdr, i)); - list.Add(tagInfo); - } - rdr.Close(); - } - return list; - } - - public List GetTagListByStartString(int siteId, string startString, int totalNum) - { - var sqlString = SqlUtils.GetDistinctTopSqlString("siteserver_Tag", "Tag, UseNum", - $"WHERE SiteId = {siteId} AND {SqlUtils.GetInStr("Tag", PageUtils.FilterSql(startString))}", - "ORDER BY UseNum DESC", totalNum); - return DataProvider.DatabaseDao.GetStringList(sqlString); - } - - public List GetTagList(int siteId) - { - string sqlString = - $"SELECT Tag FROM siteserver_Tag WHERE SiteId = {siteId} ORDER BY UseNum DESC"; - return DataProvider.DatabaseDao.GetStringList(sqlString); - } - - public void DeleteTags(int siteId) - { - var whereString = GetWhereString(null, siteId, 0); - string sqlString = $"DELETE FROM siteserver_Tag {whereString}"; - ExecuteNonQuery(sqlString); - } - - public void DeleteTag(string tag, int siteId) - { - var whereString = GetWhereString(tag, siteId, 0); - string sqlString = $"DELETE FROM siteserver_Tag {whereString}"; - ExecuteNonQuery(sqlString); - } - - public int GetTagCount(string tag, int siteId) - { - var contentIdList = GetContentIdListByTag(tag, siteId); - return contentIdList.Count; - } - - private string GetWhereString(string tag, int siteId, int contentId) - { - var builder = new StringBuilder(); - builder.Append($" WHERE SiteId = {siteId} "); - if (!string.IsNullOrEmpty(tag)) - { - builder.Append($"AND Tag = '{PageUtils.FilterSql(tag)}' "); - } - if (contentId > 0) - { - builder.Append( - $"AND (ContentIdCollection = '{contentId}' OR ContentIdCollection LIKE '{contentId},%' OR ContentIdCollection LIKE '%,{contentId},%' OR ContentIdCollection LIKE '%,{contentId}')"); - } - - return builder.ToString(); - } - - public List GetContentIdListByTag(string tag, int siteId) - { - var idList = new List(); - if (string.IsNullOrEmpty(tag)) return idList; - - var whereString = GetWhereString(tag, siteId, 0); - var sqlString = "SELECT ContentIdCollection FROM siteserver_Tag" + whereString; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - var contentIdCollection = GetString(rdr, 0); - var contentIdList = TranslateUtils.StringCollectionToIntList(contentIdCollection); - foreach (var contentId in contentIdList) - { - if (contentId > 0 && !idList.Contains(contentId)) - { - idList.Add(contentId); - } - } - } - rdr.Close(); - } - return idList; - } - - public List GetContentIdListByTagCollection(StringCollection tagCollection, int siteId) - { - var contentIdList = new List(); - if (tagCollection.Count > 0) - { - string parameterNameList; - var parameterList = GetInParameterList(ParmTag, DataType.VarChar, 255, tagCollection, out parameterNameList); - - string sqlString = - $"SELECT ContentIdCollection FROM siteserver_Tag WHERE Tag IN ({parameterNameList}) AND SiteId = @SiteId"; - - var paramList = new List(); - paramList.AddRange(parameterList); - paramList.Add(GetParameter(ParmSiteId, DataType.Integer, siteId)); - - using (var rdr = ExecuteReader(sqlString, paramList.ToArray())) - { - while (rdr.Read()) - { - var contentIdCollection = GetString(rdr, 0); - var list = TranslateUtils.StringCollectionToIntList(contentIdCollection); - foreach (var contentId in list) - { - if (contentId > 0 && !contentIdList.Contains(contentId)) - { - contentIdList.Add(contentId); - } - } - } - rdr.Close(); - } - } - return contentIdList; - } - } -} diff --git a/SiteServer.CMS/Provider/TemplateDao.cs b/SiteServer.CMS/Provider/TemplateDao.cs deleted file mode 100644 index 721a36ef1..000000000 --- a/SiteServer.CMS/Provider/TemplateDao.cs +++ /dev/null @@ -1,543 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Provider -{ - public class TemplateDao : DataProviderBase - { - public override string TableName => "siteserver_Template"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(TemplateInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateInfo.SiteId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateInfo.TemplateName), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateInfo.TemplateType), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateInfo.RelatedFileName), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateInfo.CreatedFileFullName), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateInfo.CreatedFileExtName), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateInfo.Charset), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateInfo.IsDefault), - DataType = DataType.VarChar, - Length = 18 - } - }; - - private const string SqlSelectTemplateByTemplateName = "SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = @SiteId AND TemplateType = @TemplateType AND TemplateName = @TemplateName"; - - private const string SqlSelectAllTemplateByType = "SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = @SiteId AND TemplateType = @TemplateType ORDER BY RelatedFileName"; - - private const string SqlSelectAllIdByType = "SELECT Id FROM siteserver_Template WHERE SiteId = @SiteId AND TemplateType = @TemplateType ORDER BY RelatedFileName"; - - private const string SqlSelectAllTemplateBySiteId = "SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = @SiteId ORDER BY TemplateType, RelatedFileName"; - - private const string SqlSelectTemplateNames = "SELECT TemplateName FROM siteserver_Template WHERE SiteId = @SiteId AND TemplateType = @TemplateType"; - - private const string SqlSelectTemplateCount = "SELECT TemplateType, COUNT(*) FROM siteserver_Template WHERE SiteId = @SiteId GROUP BY TemplateType"; - - private const string SqlSelectRelatedFileNameByTemplateType = "SELECT RelatedFileName FROM siteserver_Template WHERE SiteId = @SiteId AND TemplateType = @TemplateType"; - - private const string SqlUpdateTemplate = "UPDATE siteserver_Template SET TemplateName = @TemplateName, TemplateType = @TemplateType, RelatedFileName = @RelatedFileName, CreatedFileFullName = @CreatedFileFullName, CreatedFileExtName = @CreatedFileExtName, Charset = @Charset, IsDefault = @IsDefault WHERE Id = @Id"; - - private const string SqlDeleteTemplate = "DELETE FROM siteserver_Template WHERE Id = @Id"; - - //by 20151106 sofuny - private const string SqlSelectTemplateByUrlType = "SELECT * FROM siteserver_Template WHERE SiteId = @SiteId AND TemplateType = @TemplateType and CreatedFileFullName=@CreatedFileFullName "; - private const string SqlSelectTemplateById = "SELECT * FROM siteserver_Template WHERE SiteId = @SiteId AND TemplateType = @TemplateType and Id = @Id "; - - private const string ParmId = "@Id"; - private const string ParmSiteId = "@SiteId"; - private const string ParmTemplateName = "@TemplateName"; - private const string ParmTemplateType = "@TemplateType"; - private const string ParmRelatedFileName = "@RelatedFileName"; - private const string ParmCreatedFileFullName = "@CreatedFileFullName"; - private const string ParmCreatedFileExtName = "@CreatedFileExtName"; - private const string ParmCharset = "@Charset"; - private const string ParmIsDefault = "@IsDefault"; - - public int Insert(TemplateInfo templateInfo, string templateContent, string administratorName) - { - if (templateInfo.IsDefault) - { - SetAllTemplateDefaultToFalse(templateInfo.SiteId, templateInfo.TemplateType); - } - - var sqlInsertTemplate = "INSERT INTO siteserver_Template (SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault) VALUES (@SiteId, @TemplateName, @TemplateType, @RelatedFileName, @CreatedFileFullName, @CreatedFileExtName, @Charset, @IsDefault)"; - - var insertParms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, templateInfo.SiteId), - GetParameter(ParmTemplateName, DataType.VarChar, 50, templateInfo.TemplateName), - GetParameter(ParmTemplateType, DataType.VarChar, 50, templateInfo.TemplateType.Value), - GetParameter(ParmRelatedFileName, DataType.VarChar, 50, templateInfo.RelatedFileName), - GetParameter(ParmCreatedFileFullName, DataType.VarChar, 50, templateInfo.CreatedFileFullName), - GetParameter(ParmCreatedFileExtName, DataType.VarChar, 50, templateInfo.CreatedFileExtName), - GetParameter(ParmCharset, DataType.VarChar, 50, ECharsetUtils.GetValue(templateInfo.Charset)), - GetParameter(ParmIsDefault, DataType.VarChar, 18, templateInfo.IsDefault.ToString()) - }; - - var id = ExecuteNonQueryAndReturnId(TableName, nameof(TemplateInfo.Id), sqlInsertTemplate, insertParms); - - var siteInfo = SiteManager.GetSiteInfo(templateInfo.SiteId); - TemplateManager.WriteContentToTemplateFile(siteInfo, templateInfo, templateContent, administratorName); - - TemplateManager.RemoveCache(templateInfo.SiteId); - - return id; - } - - public void Update(SiteInfo siteInfo, TemplateInfo templateInfo, string templateContent, string administratorName) - { - if (templateInfo.IsDefault) - { - SetAllTemplateDefaultToFalse(siteInfo.Id, templateInfo.TemplateType); - } - - var updateParms = new IDataParameter[] - { - GetParameter(ParmTemplateName, DataType.VarChar, 50, templateInfo.TemplateName), - GetParameter(ParmTemplateType, DataType.VarChar, 50, templateInfo.TemplateType.Value), - GetParameter(ParmRelatedFileName, DataType.VarChar, 50, templateInfo.RelatedFileName), - GetParameter(ParmCreatedFileFullName, DataType.VarChar, 50, templateInfo.CreatedFileFullName), - GetParameter(ParmCreatedFileExtName, DataType.VarChar, 50, templateInfo.CreatedFileExtName), - GetParameter(ParmCharset, DataType.VarChar, 50, ECharsetUtils.GetValue(templateInfo.Charset)), - GetParameter(ParmIsDefault, DataType.VarChar, 18, templateInfo.IsDefault.ToString()), - GetParameter(ParmId, DataType.Integer, templateInfo.Id) - }; - - ExecuteNonQuery(SqlUpdateTemplate, updateParms); - - TemplateManager.WriteContentToTemplateFile(siteInfo, templateInfo, templateContent, administratorName); - - TemplateManager.RemoveCache(templateInfo.SiteId); - } - - private void SetAllTemplateDefaultToFalse(int siteId, TemplateType templateType) - { - var sqlString = "UPDATE siteserver_Template SET IsDefault = @IsDefault WHERE SiteId = @SiteId AND TemplateType = @TemplateType"; - - var updateParms = new IDataParameter[] - { - GetParameter(ParmIsDefault, DataType.VarChar, 18, false.ToString()), - GetParameter(ParmSiteId, DataType.Integer, siteId), - GetParameter(ParmTemplateType, DataType.VarChar, 50, templateType.Value) - }; - - ExecuteNonQuery(sqlString, updateParms); - - } - - public void SetDefault(int siteId, int id) - { - var info = TemplateManager.GetTemplateInfo(siteId, id); - SetAllTemplateDefaultToFalse(info.SiteId, info.TemplateType); - - var sqlString = "UPDATE siteserver_Template SET IsDefault = @IsDefault WHERE Id = @Id"; - - var updateParms = new IDataParameter[] - { - GetParameter(ParmIsDefault, DataType.VarChar, 18, true.ToString()), - GetParameter(ParmId, DataType.Integer, id) - }; - - ExecuteNonQuery(sqlString, updateParms); - - TemplateManager.RemoveCache(siteId); - } - - public void Delete(int siteId, int id) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - var templateInfo = TemplateManager.GetTemplateInfo(siteId, id); - var filePath = TemplateManager.GetTemplateFilePath(siteInfo, templateInfo); - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, id) - }; - - ExecuteNonQuery(SqlDeleteTemplate, parms); - FileUtils.DeleteFileIfExists(filePath); - - TemplateManager.RemoveCache(siteId); - } - - public string GetImportTemplateName(int siteId, string templateName) - { - string importTemplateName; - if (templateName.IndexOf("_", StringComparison.Ordinal) != -1) - { - var templateNameCount = 0; - var lastTemplateName = templateName.Substring(templateName.LastIndexOf("_", StringComparison.Ordinal) + 1); - var firstTemplateName = templateName.Substring(0, templateName.Length - lastTemplateName.Length); - try - { - templateNameCount = int.Parse(lastTemplateName); - } - catch - { - // ignored - } - templateNameCount++; - importTemplateName = firstTemplateName + templateNameCount; - } - else - { - importTemplateName = templateName + "_1"; - } - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId), - GetParameter(ParmTemplateName, DataType.VarChar, 50, importTemplateName) - }; - - using (var rdr = ExecuteReader(SqlSelectTemplateByTemplateName, parms)) - { - if (rdr.Read()) - { - importTemplateName = GetImportTemplateName(siteId, importTemplateName); - } - rdr.Close(); - } - - return importTemplateName; - } - - public Dictionary GetCountDictionary(int siteId) - { - var dictionary = new Dictionary(); - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - - using (var rdr = ExecuteReader(SqlSelectTemplateCount, parms)) - { - while (rdr.Read()) - { - var templateType = TemplateTypeUtils.GetEnumType(GetString(rdr, 0)); - var count = GetInt(rdr, 1); - - dictionary.Add(templateType, count); - } - rdr.Close(); - } - - return dictionary; - } - - public IDataReader GetDataSourceByType(int siteId, TemplateType type) - { - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId), - GetParameter(ParmTemplateType, DataType.VarChar, 50, type.Value) - }; - - var enumerable = ExecuteReader(SqlSelectAllTemplateByType, parms); - return enumerable; - } - - public IDataReader GetDataSource(int siteId, string searchText, string templateTypeString) - { - if (string.IsNullOrEmpty(searchText) && string.IsNullOrEmpty(templateTypeString)) - { - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - - var enumerable = ExecuteReader(SqlSelectAllTemplateBySiteId, parms); - return enumerable; - } - if (!string.IsNullOrEmpty(searchText)) - { - var whereString = (string.IsNullOrEmpty(templateTypeString)) ? string.Empty : - $"AND TemplateType = '{templateTypeString}' "; - searchText = PageUtils.FilterSql(searchText); - whereString += - $"AND (TemplateName LIKE '%{searchText}%' OR RelatedFileName LIKE '%{searchText}%' OR CreatedFileFullName LIKE '%{searchText}%' OR CreatedFileExtName LIKE '%{searchText}%')"; - string sqlString = - $"SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = {siteId} {whereString} ORDER BY TemplateType, RelatedFileName"; - - var enumerable = ExecuteReader(sqlString); - return enumerable; - } - - return GetDataSourceByType(siteId, TemplateTypeUtils.GetEnumType(templateTypeString)); - } - - public List GetIdListByType(int siteId, TemplateType type) - { - var list = new List(); - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId), - GetParameter(ParmTemplateType, DataType.VarChar, 50, type.Value) - }; - - using (var rdr = ExecuteReader(SqlSelectAllIdByType, parms)) - { - while (rdr.Read()) - { - var id = GetInt(rdr, 0); - list.Add(id); - } - rdr.Close(); - } - return list; - } - - public List GetTemplateInfoListByType(int siteId, TemplateType type) - { - var list = new List(); - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId), - GetParameter(ParmTemplateType, DataType.VarChar, 50, type.Value) - }; - - using (var rdr = ExecuteReader(SqlSelectAllTemplateByType, parms)) - { - while (rdr.Read()) - { - var i = 0; - var info = new TemplateInfo(GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), TemplateTypeUtils.GetEnumType(GetString(rdr, i++)), GetString(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), ECharsetUtils.GetEnumType(GetString(rdr, i++)), GetBool(rdr, i)); - list.Add(info); - } - rdr.Close(); - } - return list; - } - - public List GetTemplateInfoListOfFile(int siteId) - { - var list = new List(); - - string sqlString = - $"SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = {siteId} AND TemplateType = '{TemplateType.FileTemplate.Value}' ORDER BY RelatedFileName"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var i = 0; - var info = new TemplateInfo(GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), TemplateTypeUtils.GetEnumType(GetString(rdr, i++)), GetString(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), ECharsetUtils.GetEnumType(GetString(rdr, i++)), GetBool(rdr, i)); - list.Add(info); - } - rdr.Close(); - } - return list; - } - - public List GetTemplateInfoListBySiteId(int siteId) - { - var list = new List(); - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - - using (var rdr = ExecuteReader(SqlSelectAllTemplateBySiteId, parms)) - { - while (rdr.Read()) - { - var i = 0; - var info = new TemplateInfo(GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), TemplateTypeUtils.GetEnumType(GetString(rdr, i++)), GetString(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), ECharsetUtils.GetEnumType(GetString(rdr, i++)), GetBool(rdr, i)); - list.Add(info); - } - rdr.Close(); - } - return list; - } - - public List GetTemplateNameList(int siteId, TemplateType templateType) - { - var list = new List(); - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId), - GetParameter(ParmTemplateType, DataType.VarChar, 50, templateType.Value) - }; - - using (var rdr = ExecuteReader(SqlSelectTemplateNames, parms)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - - return list; - } - - public List GetLowerRelatedFileNameList(int siteId, TemplateType templateType) - { - var list = new List(); - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId), - GetParameter(ParmTemplateType, DataType.VarChar, 50, templateType.Value) - }; - - using (var rdr = ExecuteReader(SqlSelectRelatedFileNameByTemplateType, parms)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0).ToLower()); - } - rdr.Close(); - } - - return list; - } - - public void CreateDefaultTemplateInfo(int siteId, string administratorName) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - - var templateInfoList = new List(); - var charset = ECharsetUtils.GetEnumType(siteInfo.Additional.Charset); - - var templateInfo = new TemplateInfo(0, siteInfo.Id, "系统首页模板", TemplateType.IndexPageTemplate, "T_系统首页模板.html", "@/index.html", ".html", charset, true); - templateInfoList.Add(templateInfo); - - templateInfo = new TemplateInfo(0, siteInfo.Id, "系统栏目模板", TemplateType.ChannelTemplate, "T_系统栏目模板.html", "index.html", ".html", charset, true); - templateInfoList.Add(templateInfo); - - templateInfo = new TemplateInfo(0, siteInfo.Id, "系统内容模板", TemplateType.ContentTemplate, "T_系统内容模板.html", "index.html", ".html", charset, true); - templateInfoList.Add(templateInfo); - - foreach (var theTemplateInfo in templateInfoList) - { - Insert(theTemplateInfo, theTemplateInfo.Content, administratorName); - } - } - - public Dictionary GetTemplateInfoDictionaryBySiteId(int siteId) - { - var dictionary = new Dictionary(); - - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId) - }; - - using (var rdr = ExecuteReader(SqlSelectAllTemplateBySiteId, parms)) - { - while (rdr.Read()) - { - var i = 0; - var info = new TemplateInfo(GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), TemplateTypeUtils.GetEnumType(GetString(rdr, i++)), GetString(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), ECharsetUtils.GetEnumType(GetString(rdr, i++)), GetBool(rdr, i)); - dictionary.Add(info.Id, info); - } - rdr.Close(); - } - - return dictionary; - } - - - public TemplateInfo GetTemplateByUrlType(int siteId, TemplateType type, string createdFileFullName) - { - TemplateInfo info = null; - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId), - GetParameter(ParmTemplateType, DataType.VarChar, 50, type.Value), - GetParameter(ParmCreatedFileFullName, DataType.VarChar, 50, createdFileFullName) - }; - - using (var rdr = ExecuteReader(SqlSelectTemplateByUrlType, parms)) - { - while (rdr.Read()) - { - var i = 0; - info = new TemplateInfo(GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), TemplateTypeUtils.GetEnumType(GetString(rdr, i++)), GetString(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), ECharsetUtils.GetEnumType(GetString(rdr, i++)), GetBool(rdr, i)); - } - rdr.Close(); - } - return info; - } - - public TemplateInfo GetTemplateById(int siteId, TemplateType type, string tId) - { - TemplateInfo info = null; - var parms = new IDataParameter[] - { - GetParameter(ParmSiteId, DataType.Integer, siteId), - GetParameter(ParmTemplateType, DataType.VarChar, 50, type.Value), - GetParameter(ParmId, DataType.Integer, tId) - }; - - using (var rdr = ExecuteReader(SqlSelectTemplateById, parms)) - { - if (rdr.Read()) - { - var i = 0; - info = new TemplateInfo(GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), TemplateTypeUtils.GetEnumType(GetString(rdr, i++)), GetString(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), ECharsetUtils.GetEnumType(GetString(rdr, i++)), GetBool(rdr, i)); - } - rdr.Close(); - } - return info; - } - - } -} diff --git a/SiteServer.CMS/Provider/TemplateLogDao.cs b/SiteServer.CMS/Provider/TemplateLogDao.cs deleted file mode 100644 index 02fad00dc..000000000 --- a/SiteServer.CMS/Provider/TemplateLogDao.cs +++ /dev/null @@ -1,142 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Data; -using SiteServer.Utils; -using SiteServer.CMS.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Provider -{ - public class TemplateLogDao : DataProviderBase - { - public override string TableName => "siteserver_TemplateLog"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(TemplateLogInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateLogInfo.TemplateId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateLogInfo.SiteId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateLogInfo.AddDate), - DataType = DataType.DateTime - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateLogInfo.AddUserName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateLogInfo.ContentLength), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateLogInfo.TemplateContent), - DataType = DataType.Text - } - }; - - private const string ParmTemplateId = "@TemplateId"; - private const string ParmSiteId = "@SiteId"; - private const string ParmAddDate = "@AddDate"; - private const string ParmAddUserName = "@AddUserName"; - private const string ParmContentLength = "@ContentLength"; - private const string ParmTemplateContent = "@TemplateContent"; - - public void Insert(TemplateLogInfo logInfo) - { - var sqlString = "INSERT INTO siteserver_TemplateLog(TemplateId, SiteId, AddDate, AddUserName, ContentLength, TemplateContent) VALUES (@TemplateId, @SiteId, @AddDate, @AddUserName, @ContentLength, @TemplateContent)"; - - var parms = new IDataParameter[] - { - GetParameter(ParmTemplateId, DataType.Integer, logInfo.TemplateId), - GetParameter(ParmSiteId, DataType.Integer, logInfo.SiteId), - GetParameter(ParmAddDate, DataType.DateTime, logInfo.AddDate), - GetParameter(ParmAddUserName, DataType.VarChar, 255, logInfo.AddUserName), - GetParameter(ParmContentLength, DataType.Integer, logInfo.ContentLength), - GetParameter(ParmTemplateContent, DataType.Text, logInfo.TemplateContent) - }; - - ExecuteNonQuery(sqlString, parms); - } - - public string GetSelectCommend(int siteId, int templateId) - { - return - $"SELECT ID, TemplateId, SiteId, AddDate, AddUserName, ContentLength, TemplateContent FROM siteserver_TemplateLog WHERE SiteId = {siteId} AND TemplateId = {templateId}"; - } - - public string GetTemplateContent(int logId) - { - var templateContent = string.Empty; - - string sqlString = $"SELECT TemplateContent FROM siteserver_TemplateLog WHERE ID = {logId}"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - templateContent = GetString(rdr, 0); - } - rdr.Close(); - } - - return templateContent; - } - - public Dictionary GetLogIdWithNameDictionary(int siteId, int templateId) - { - var dictionary = new Dictionary(); - - string sqlString = - $"SELECT ID, AddDate, AddUserName, ContentLength FROM siteserver_TemplateLog WHERE TemplateId = {templateId}"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var id = GetInt(rdr, 0); - var addDate = GetDateTime(rdr, 1); - var addUserName = GetString(rdr, 2); - var contentLength = GetInt(rdr, 3); - - string name = - $"修订时间:{DateUtils.GetDateAndTimeString(addDate)},修订人:{addUserName},字符数:{contentLength}"; - - dictionary.Add(id, name); - } - rdr.Close(); - } - - return dictionary; - } - - public void Delete(List idList) - { - if (idList != null && idList.Count > 0) - { - string sqlString = - $"DELETE FROM siteserver_TemplateLog WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; - - ExecuteNonQuery(sqlString); - } - } - } -} diff --git a/SiteServer.CMS/Provider/TemplateMatchDao.cs b/SiteServer.CMS/Provider/TemplateMatchDao.cs deleted file mode 100644 index 578f625c8..000000000 --- a/SiteServer.CMS/Provider/TemplateMatchDao.cs +++ /dev/null @@ -1,306 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.Provider -{ - public class TemplateMatchDao : DataProviderBase - { - public override string TableName => "siteserver_TemplateMatch"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(TemplateMatchInfo.Id), - DataType = DataType.Integer, - IsPrimaryKey = true, - IsIdentity = true - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateMatchInfo.ChannelId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateMatchInfo.SiteId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateMatchInfo.ChannelTemplateId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateMatchInfo.ContentTemplateId), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateMatchInfo.FilePath), - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateMatchInfo.ChannelFilePathRule), - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = nameof(TemplateMatchInfo.ContentFilePathRule), - DataType = DataType.VarChar, - Length = 200 - } - }; - - private const string SqlSelect = "SELECT Id, ChannelId, SiteId, ChannelTemplateId, ContentTemplateId, FilePath, ChannelFilePathRule, ContentFilePathRule FROM siteserver_TemplateMatch WHERE ChannelId = @ChannelId"; - - private const string SqlInsert = "INSERT INTO siteserver_TemplateMatch (ChannelId, SiteId, ChannelTemplateId, ContentTemplateId, FilePath, ChannelFilePathRule, ContentFilePathRule) VALUES (@ChannelId, @SiteId, @ChannelTemplateId, @ContentTemplateId, @FilePath, @ChannelFilePathRule, @ContentFilePathRule)"; - - private const string SqlUpdate = "UPDATE siteserver_TemplateMatch SET ChannelTemplateId = @ChannelTemplateId, ContentTemplateId = @ContentTemplateId, FilePath = @FilePath, ChannelFilePathRule = @ChannelFilePathRule, ContentFilePathRule = @ContentFilePathRule WHERE ChannelId = @ChannelId"; - - private const string SqlDelete = "DELETE FROM siteserver_TemplateMatch WHERE ChannelId = @ChannelId"; - - private const string ParmChannelId = "@ChannelId"; - private const string ParmSiteId = "@SiteId"; - private const string ParmChannelTemplateId = "@ChannelTemplateId"; - private const string ParmContentTemplateId = "@ContentTemplateId"; - private const string ParmFilepath = "@FilePath"; - private const string ParmChannelFilepathRule = "@ChannelFilePathRule"; - private const string ParmContentFilepathRule = "@ContentFilePathRule"; - - public void Insert(TemplateMatchInfo info) - { - var insertParms = new IDataParameter[] - { - GetParameter(ParmChannelId, DataType.Integer, info.ChannelId), - GetParameter(ParmSiteId, DataType.Integer, info.SiteId), - GetParameter(ParmChannelTemplateId, DataType.Integer, info.ChannelTemplateId), - GetParameter(ParmContentTemplateId, DataType.Integer, info.ContentTemplateId), - GetParameter(ParmFilepath, DataType.VarChar, 200, info.FilePath), - GetParameter(ParmChannelFilepathRule, DataType.VarChar, 200, info.ChannelFilePathRule), - GetParameter(ParmContentFilepathRule, DataType.VarChar, 200, info.ContentFilePathRule) - }; - - ExecuteNonQuery(SqlInsert, insertParms); - } - - public void Update(TemplateMatchInfo info) - { - var updateParms = new IDataParameter[] - { - GetParameter(ParmChannelTemplateId, DataType.Integer, info.ChannelTemplateId), - GetParameter(ParmContentTemplateId, DataType.Integer, info.ContentTemplateId), - GetParameter(ParmFilepath, DataType.VarChar, 200, info.FilePath), - GetParameter(ParmChannelFilepathRule, DataType.VarChar, 200, info.ChannelFilePathRule), - GetParameter(ParmContentFilepathRule, DataType.VarChar, 200, info.ContentFilePathRule), - GetParameter(ParmChannelId, DataType.Integer, info.ChannelId) - }; - - ExecuteNonQuery(SqlUpdate, updateParms); - } - - public void Delete(int channelId) - { - - var parms = new IDataParameter[] - { - GetParameter(ParmChannelId, DataType.Integer, channelId) - }; - - ExecuteNonQuery(SqlDelete, parms); - } - - public TemplateMatchInfo GetTemplateMatchInfo(int channelId) - { - TemplateMatchInfo info = null; - - var parms = new IDataParameter[] - { - GetParameter(ParmChannelId, DataType.Integer, channelId) - }; - - using (var rdr = ExecuteReader(SqlSelect, parms)) - { - if (rdr.Read()) - { - var i = 0; - info = new TemplateMatchInfo(GetInt(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetString(rdr, i)); - } - rdr.Close(); - } - - return info; - } - - public bool IsExists(int channelId) - { - var isExists = false; - - string sqlString = $"SELECT ChannelId FROM siteserver_TemplateMatch WHERE ChannelId = {channelId}"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - isExists = true; - } - rdr.Close(); - } - - return isExists; - } - - public Dictionary GetChannelTemplateIdDict(int siteId) - { - var dict = new Dictionary(); - - string sqlString = - $"SELECT ChannelId, ChannelTemplateId FROM siteserver_TemplateMatch WHERE SiteId = {siteId}"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - dict[GetInt(rdr, 0)] = GetInt(rdr, 1); - } - rdr.Close(); - } - - return dict; - } - - public Dictionary GetContentTemplateIdDict(int siteId) - { - var dict = new Dictionary(); - - string sqlString = - $"SELECT ChannelId, ContentTemplateId FROM siteserver_TemplateMatch WHERE SiteId = {siteId}"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - dict[GetInt(rdr, 0)] = GetInt(rdr, 1); - } - rdr.Close(); - } - - return dict; - } - - public int GetChannelTemplateId(int channelId) - { - var templateId = 0; - - string sqlString = $"SELECT ChannelTemplateId FROM siteserver_TemplateMatch WHERE ChannelId = {channelId}"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - templateId = GetInt(rdr, 0); - } - rdr.Close(); - } - - return templateId; - } - - public int GetContentTemplateId(int channelId) - { - var templateId = 0; - - string sqlString = $"SELECT ContentTemplateId FROM siteserver_TemplateMatch WHERE ChannelId = {channelId}"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - templateId = GetInt(rdr, 0); - } - rdr.Close(); - } - - return templateId; - } - - public string GetFilePath(int channelId) - { - var filePath = string.Empty; - - string sqlString = $"SELECT FilePath FROM siteserver_TemplateMatch WHERE ChannelId = {channelId}"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - filePath = GetString(rdr, 0); - } - rdr.Close(); - } - - return filePath; - } - - public string GetChannelFilePathRule(int channelId) - { - var filePathRule = string.Empty; - - string sqlString = $"SELECT ChannelFilePathRule FROM siteserver_TemplateMatch WHERE ChannelId = {channelId}"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - filePathRule = GetString(rdr, 0); - } - rdr.Close(); - } - - return filePathRule; - } - - public string GetContentFilePathRule(int channelId) - { - var filePathRule = string.Empty; - - string sqlString = $"SELECT ContentFilePathRule FROM siteserver_TemplateMatch WHERE ChannelId = {channelId}"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - filePathRule = GetString(rdr, 0); - } - rdr.Close(); - } - - return filePathRule; - } - - public List GetAllFilePathBySiteId(int siteId) - { - var list = new List(); - - string sqlString = - $"SELECT FilePath FROM siteserver_TemplateMatch WHERE FilePath <> '' AND SiteId = {siteId}"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - return list; - } - } -} diff --git a/SiteServer.CMS/Provider/UserDao.cs b/SiteServer.CMS/Provider/UserDao.cs deleted file mode 100644 index 9fc69b4a6..000000000 --- a/SiteServer.CMS/Provider/UserDao.cs +++ /dev/null @@ -1,1431 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Security.Cryptography; -using System.Text; -using SiteServer.CMS.Core; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Utils.Auth; -using SiteServer.Plugin; -using SiteServer.Utils; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.Provider -{ - public class UserDao : DataProviderBase - { - public override string TableName => "siteserver_User"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(UserInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.UserName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.Password), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.PasswordFormat), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.PasswordSalt), - DataType = DataType.VarChar, - Length = 128 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.CreateDate), - DataType = DataType.DateTime - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.LastResetPasswordDate), - DataType = DataType.DateTime - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.LastActivityDate), - DataType = DataType.DateTime - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.CountOfLogin), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.CountOfFailedLogin), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.CountOfWriting), - DataType = DataType.Integer - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.IsChecked), - DataType = DataType.VarChar, - Length = 18 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.IsLockedOut), - DataType = DataType.VarChar, - Length = 18 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.DisplayName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.Email), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.Mobile), - DataType = DataType.VarChar, - Length = 20 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.AvatarUrl), - DataType = DataType.VarChar, - Length = 200 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.Organization), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.Department), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.Position), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.Gender), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.Birthday), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.Education), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.Graduation), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.Address), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.WeiXin), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.Qq), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.WeiBo), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.Interests), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(UserInfo.Signature), - DataType = DataType.VarChar, - Length = 255 - } - }; - - private const string ParmId = "@Id"; - private const string ParmUserName = "@UserName"; - private const string ParmPassword = "@Password"; - private const string ParmPasswordFormat = "@PasswordFormat"; - private const string ParmPasswordSalt = "@PasswordSalt"; - private const string ParmCreateDate = "@CreateDate"; - private const string ParmLastResetPasswordDate = "@LastResetPasswordDate"; - private const string ParmLastActivityDate = "@LastActivityDate"; - private const string ParmCountOfLogin = "@CountOfLogin"; - private const string ParmCountOfFailedLogin = "@CountOfFailedLogin"; - private const string ParmCountOfWriting = "@CountOfWriting"; - private const string ParmIsChecked = "@IsChecked"; - private const string ParmIsLockedOut = "@IsLockedOut"; - private const string ParmDisplayname = "@DisplayName"; - private const string ParmEmail = "@Email"; - private const string ParmMobile = "@Mobile"; - private const string ParmAvatarUrl = "@AvatarUrl"; - - private const string ParmOrganization = "@Organization"; - private const string ParmDepartment = "@Department"; - private const string ParmPosition = "@Position"; - private const string ParmGender = "@Gender"; - private const string ParmBirthday = "@Birthday"; - private const string ParmEducation = "@Education"; - private const string ParmGraduation = "@Graduation"; - private const string ParmAddress = "@Address"; - private const string ParmWeixin = "@WeiXin"; - private const string ParmQq = "@QQ"; - private const string ParmWeibo = "@WeiBo"; - private const string ParmInterests = "@Interests"; - private const string ParmSignature = "@Signature"; - - private bool IpAddressIsRegisterAllowed(string ipAddress) - { - if (ConfigManager.SystemConfigInfo.UserRegistrationMinMinutes == 0 || string.IsNullOrEmpty(ipAddress)) - { - return true; - } - var obj = CacheUtils.Get($"BaiRong.Core.Provider.UserDao.Insert.IpAddress.{ipAddress}"); - return obj == null; - } - - private void IpAddressCache(string ipAddress) - { - if (ConfigManager.SystemConfigInfo.UserRegistrationMinMinutes > 0 && !string.IsNullOrEmpty(ipAddress)) - { - CacheUtils.InsertMinutes($"BaiRong.Core.Provider.UserDao.Insert.IpAddress.{ipAddress}", ipAddress, ConfigManager.SystemConfigInfo.UserRegistrationMinMinutes); - } - } - - public bool Insert(IUserInfo userInfo, string password, string ipAddress, out string errorMessage) - { - errorMessage = string.Empty; - if (!IpAddressIsRegisterAllowed(ipAddress)) - { - errorMessage = $"同一IP在{ConfigManager.SystemConfigInfo.UserRegistrationMinMinutes}分钟内只能注册一次"; - return false; - } - if (string.IsNullOrEmpty(password)) - { - errorMessage = "密码不能为空"; - return false; - } - if (password.Length < ConfigManager.SystemConfigInfo.UserPasswordMinLength) - { - errorMessage = $"密码长度必须大于等于{ConfigManager.SystemConfigInfo.UserPasswordMinLength}"; - return false; - } - if (!EUserPasswordRestrictionUtils.IsValid(password, ConfigManager.SystemConfigInfo.UserPasswordRestriction)) - { - errorMessage = - $"密码不符合规则,请包含{EUserPasswordRestrictionUtils.GetText(EUserPasswordRestrictionUtils.GetEnumType(ConfigManager.SystemConfigInfo.UserPasswordRestriction))}"; - return false; - } - if (!IsUserNameCompliant(userInfo.UserName.Replace("@", string.Empty).Replace(".", string.Empty))) - { - errorMessage = "用户名包含不规则字符,请更换用户名"; - return false; - } - if (!string.IsNullOrEmpty(userInfo.Email) && IsEmailExists(userInfo.Email)) - { - errorMessage = "电子邮件地址已被注册,请更换邮箱"; - return false; - } - if (!string.IsNullOrEmpty(userInfo.Mobile) && IsMobileExists(userInfo.Mobile)) - { - errorMessage = "手机号码已被注册,请更换手机号码"; - return false; - } - if (!string.IsNullOrEmpty(userInfo.UserName) && IsUserNameExists(userInfo.UserName)) - { - errorMessage = "用户名已被注册,请更换用户名"; - return false; - } - - try - { - var passwordSalt = GenerateSalt(); - password = EncodePassword(password, EPasswordFormat.Encrypted, passwordSalt); - - InsertWithoutValidation(userInfo, password, EPasswordFormat.Encrypted, passwordSalt); - - IpAddressCache(ipAddress); - - return true; - } - catch (Exception ex) - { - errorMessage = ex.Message; - return false; - } - } - - private void InsertWithoutValidation(IUserInfo userInfo, string password, EPasswordFormat passwordFormat, string passwordSalt) - { - const string sqlString = "INSERT INTO siteserver_User (UserName, Password, PasswordFormat, PasswordSalt, CreateDate, LastResetPasswordDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, CountOfWriting, IsChecked, IsLockedOut, DisplayName, Email, Mobile, AvatarUrl, Organization, Department, Position, Gender, Birthday, Education, Graduation, Address, WeiXin, QQ, WeiBo, Interests, Signature) VALUES (@UserName, @Password, @PasswordFormat, @PasswordSalt, @CreateDate, @LastResetPasswordDate, @LastActivityDate, @CountOfLogin, @CountOfFailedLogin, @CountOfWriting, @IsChecked, @IsLockedOut, @DisplayName, @Email, @Mobile, @AvatarUrl, @Organization, @Department, @Position, @Gender, @Birthday, @Education, @Graduation, @Address, @WeiXin, @QQ, @WeiBo, @Interests, @Signature)"; - - userInfo.CreateDate = DateTime.Now; - userInfo.LastActivityDate = DateTime.Now; - userInfo.LastResetPasswordDate = DateUtils.SqlMinValue; - - var parameters = new IDataParameter[] - { - GetParameter(ParmUserName, DataType.VarChar, 255, userInfo.UserName), - GetParameter(ParmPassword, DataType.VarChar, 255, password), - GetParameter(ParmPasswordFormat, DataType.VarChar, 50, EPasswordFormatUtils.GetValue(passwordFormat)), - GetParameter(ParmPasswordSalt, DataType.VarChar, 128, passwordSalt), - GetParameter(ParmCreateDate, DataType.DateTime, userInfo.CreateDate), - GetParameter(ParmLastResetPasswordDate, DataType.DateTime, userInfo.LastResetPasswordDate), - GetParameter(ParmLastActivityDate, DataType.DateTime, userInfo.LastActivityDate), - GetParameter(ParmCountOfLogin, DataType.Integer, userInfo.CountOfLogin), - GetParameter(ParmCountOfFailedLogin, DataType.Integer, userInfo.CountOfFailedLogin), - GetParameter(ParmCountOfWriting, DataType.Integer, userInfo.CountOfWriting), - GetParameter(ParmIsChecked, DataType.VarChar, 18, userInfo.IsChecked.ToString()), - GetParameter(ParmIsLockedOut, DataType.VarChar, 18, userInfo.IsLockedOut.ToString()), - GetParameter(ParmDisplayname, DataType.VarChar, 255, userInfo.DisplayName), - GetParameter(ParmEmail, DataType.VarChar, 255, userInfo.Email), - GetParameter(ParmMobile, DataType.VarChar, 20, userInfo.Mobile), - GetParameter(ParmAvatarUrl, DataType.VarChar, 200, userInfo.AvatarUrl), - GetParameter(ParmOrganization, DataType.VarChar, 255, userInfo.Organization), - GetParameter(ParmDepartment, DataType.VarChar, 255, userInfo.Department), - GetParameter(ParmPosition, DataType.VarChar, 255, userInfo.Position), - GetParameter(ParmGender, DataType.VarChar, 255, userInfo.Gender), - GetParameter(ParmBirthday, DataType.VarChar, 50, userInfo.Birthday), - GetParameter(ParmEducation, DataType.VarChar, 255, userInfo.Education), - GetParameter(ParmGraduation, DataType.VarChar, 255, userInfo.Graduation), - GetParameter(ParmAddress, DataType.VarChar, 255, userInfo.Address), - GetParameter(ParmWeixin, DataType.VarChar, 255, userInfo.WeiXin), - GetParameter(ParmQq, DataType.VarChar, 255, userInfo.Qq), - GetParameter(ParmWeibo, DataType.VarChar, 255, userInfo.WeiBo), - GetParameter(ParmInterests, DataType.VarChar, 255, userInfo.Interests), - GetParameter(ParmSignature, DataType.VarChar, 255, userInfo.Signature) - }; - - ExecuteNonQuery(sqlString, parameters); - } - - public bool IsPasswordCorrect(string password, out string errorMessage) - { - errorMessage = null; - if (string.IsNullOrEmpty(password)) - { - errorMessage = "密码不能为空"; - return false; - } - if (password.Length < ConfigManager.SystemConfigInfo.UserPasswordMinLength) - { - errorMessage = $"密码长度必须大于等于{ConfigManager.SystemConfigInfo.UserPasswordMinLength}"; - return false; - } - if (!EUserPasswordRestrictionUtils.IsValid(password, ConfigManager.SystemConfigInfo.UserPasswordRestriction)) - { - errorMessage = - $"密码不符合规则,请包含{EUserPasswordRestrictionUtils.GetText(EUserPasswordRestrictionUtils.GetEnumType(ConfigManager.SystemConfigInfo.UserPasswordRestriction))}"; - return false; - } - return true; - } - - public void Update(IUserInfo userInfo) - { - const string sqlString = "UPDATE siteserver_User SET UserName = @UserName, CreateDate = @CreateDate, LastResetPasswordDate = @LastResetPasswordDate, LastActivityDate = @LastActivityDate, CountOfLogin = @CountOfLogin, CountOfFailedLogin = @CountOfFailedLogin, CountOfWriting = @CountOfWriting, IsChecked = @IsChecked, IsLockedOut = @IsLockedOut, DisplayName = @DisplayName, Email = @Email, Mobile = @Mobile, AvatarUrl = @AvatarUrl, Organization = @Organization, Department = @Department, Position = @Position, Gender = @Gender, Birthday = @Birthday, Education = @Education, Graduation = @Graduation, Address = @Address, WeiXin = @WeiXin, QQ = @QQ, WeiBo = @WeiBo, Interests = @Interests, Signature = @Signature WHERE Id = @Id"; - - var updateParms = new IDataParameter[] - { - GetParameter(ParmUserName, DataType.VarChar, 255, userInfo.UserName), - GetParameter(ParmCreateDate, DataType.DateTime, userInfo.CreateDate), - GetParameter(ParmLastResetPasswordDate, DataType.DateTime, userInfo.LastResetPasswordDate), - GetParameter(ParmLastActivityDate, DataType.DateTime, userInfo.LastActivityDate), - GetParameter(ParmCountOfLogin, DataType.Integer, userInfo.CountOfLogin), - GetParameter(ParmCountOfFailedLogin, DataType.Integer, userInfo.CountOfFailedLogin), - GetParameter(ParmCountOfWriting, DataType.Integer, userInfo.CountOfWriting), - GetParameter(ParmIsChecked, DataType.VarChar, 18, userInfo.IsChecked.ToString()), - GetParameter(ParmIsLockedOut, DataType.VarChar, 18, userInfo.IsLockedOut.ToString()), - GetParameter(ParmDisplayname, DataType.VarChar, 255, userInfo.DisplayName), - GetParameter(ParmEmail, DataType.VarChar, 255, userInfo.Email), - GetParameter(ParmMobile, DataType.VarChar, 20, userInfo.Mobile), - GetParameter(ParmAvatarUrl, DataType.VarChar, 200, userInfo.AvatarUrl), - GetParameter(ParmOrganization, DataType.VarChar, 255, userInfo.Organization), - GetParameter(ParmDepartment, DataType.VarChar, 255, userInfo.Department), - GetParameter(ParmPosition, DataType.VarChar, 255, userInfo.Position), - GetParameter(ParmGender, DataType.VarChar, 255, userInfo.Gender), - GetParameter(ParmBirthday, DataType.VarChar, 50, userInfo.Birthday), - GetParameter(ParmEducation, DataType.VarChar, 255, userInfo.Education), - GetParameter(ParmGraduation, DataType.VarChar, 255, userInfo.Graduation), - GetParameter(ParmAddress, DataType.VarChar, 255, userInfo.Address), - GetParameter(ParmWeixin, DataType.VarChar, 255, userInfo.WeiXin), - GetParameter(ParmQq, DataType.VarChar, 255, userInfo.Qq), - GetParameter(ParmWeibo, DataType.VarChar, 255, userInfo.WeiBo), - GetParameter(ParmInterests, DataType.VarChar, 255, userInfo.Interests), - GetParameter(ParmSignature, DataType.VarChar, 255, userInfo.Signature), - GetParameter(ParmId, DataType.Integer, userInfo.Id) - }; - - ExecuteNonQuery(sqlString, updateParms); - } - - public void UpdateLastActivityDate(string userName) - { - const string sqlString = "UPDATE siteserver_User SET LastActivityDate = @LastActivityDate WHERE UserName = @UserName"; - - var updateParms = new IDataParameter[] - { - GetParameter(ParmLastActivityDate, DataType.DateTime, DateTime.Now), - GetParameter(ParmUserName, DataType.VarChar, 255, userName) - }; - - ExecuteNonQuery(sqlString, updateParms); - } - - public string EncodePassword(string password, EPasswordFormat passwordFormat, string passwordSalt) - { - var retval = string.Empty; - - if (passwordFormat == EPasswordFormat.Clear) - { - retval = password; - } - else if (passwordFormat == EPasswordFormat.Hashed) - { - var src = Encoding.Unicode.GetBytes(password); - var buffer2 = Convert.FromBase64String(passwordSalt); - var dst = new byte[buffer2.Length + src.Length]; - byte[] inArray = null; - Buffer.BlockCopy(buffer2, 0, dst, 0, buffer2.Length); - Buffer.BlockCopy(src, 0, dst, buffer2.Length, src.Length); - var algorithm = HashAlgorithm.Create("SHA1"); - if (algorithm != null) inArray = algorithm.ComputeHash(dst); - - if (inArray != null) retval = Convert.ToBase64String(inArray); - } - else if (passwordFormat == EPasswordFormat.Encrypted) - { - var encryptor = new DesEncryptor - { - InputString = password, - EncryptKey = passwordSalt - }; - encryptor.DesEncrypt(); - - retval = encryptor.OutString; - } - return retval; - } - - public string DecodePassword(string password, EPasswordFormat passwordFormat, string passwordSalt) - { - var retval = string.Empty; - if (passwordFormat == EPasswordFormat.Clear) - { - retval = password; - } - else if (passwordFormat == EPasswordFormat.Hashed) - { - throw new Exception("can not decode hashed password"); - } - else if (passwordFormat == EPasswordFormat.Encrypted) - { - var encryptor = new DesEncryptor - { - InputString = password, - DecryptKey = passwordSalt - }; - encryptor.DesDecrypt(); - - retval = encryptor.OutString; - } - return retval; - } - - private static string GenerateSalt() - { - var data = new byte[0x10]; - new RNGCryptoServiceProvider().GetBytes(data); - return Convert.ToBase64String(data); - } - - public bool ChangePassword(string userName, string password, out string errorMessage) - { - errorMessage = null; - if (password.Length < ConfigManager.SystemConfigInfo.UserPasswordMinLength) - { - errorMessage = $"密码长度必须大于等于{ConfigManager.SystemConfigInfo.UserPasswordMinLength}"; - return false; - } - if (!EUserPasswordRestrictionUtils.IsValid(password, ConfigManager.SystemConfigInfo.UserPasswordRestriction)) - { - errorMessage = - $"密码不符合规则,请包含{EUserPasswordRestrictionUtils.GetText(EUserPasswordRestrictionUtils.GetEnumType(ConfigManager.SystemConfigInfo.UserPasswordRestriction))}"; - return false; - } - - var passwordFormat = EPasswordFormat.Encrypted; - var passwordSalt = GenerateSalt(); - password = EncodePassword(password, passwordFormat, passwordSalt); - return ChangePassword(userName, passwordFormat, passwordSalt, password); - } - - private bool ChangePassword(string userName, EPasswordFormat passwordFormat, string passwordSalt, string password) - { - var isSuccess = false; - - const string sqlString = "UPDATE siteserver_User SET Password = @Password, PasswordFormat = @PasswordFormat, PasswordSalt = @PasswordSalt, LastResetPasswordDate = @LastResetPasswordDate WHERE UserName = @UserName"; - - var updateParms = new IDataParameter[] - { - GetParameter(ParmPassword, DataType.VarChar, 255, password), - GetParameter(ParmPasswordFormat, DataType.VarChar, 50, EPasswordFormatUtils.GetValue(passwordFormat)), - GetParameter(ParmPasswordSalt, DataType.VarChar, 128, passwordSalt), - GetParameter(ParmLastResetPasswordDate, DataType.DateTime, DateTime.Now), - GetParameter(ParmUserName, DataType.VarChar, 255, userName) - }; - - try - { - ExecuteNonQuery(sqlString, updateParms); - LogUtils.AddUserLog(userName, "修改密码", string.Empty); - isSuccess = true; - } - catch - { - // ignored - } - return isSuccess; - } - - public void Delete(int id) - { - const string sqlString = "DELETE FROM siteserver_User WHERE Id = @Id"; - - var deleteParms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, id) - }; - - ExecuteNonQuery(sqlString, deleteParms); - } - - public void Check(List idList) - { - string sqlString = - $"UPDATE siteserver_User SET IsChecked = '{true}' WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; - - ExecuteNonQuery(sqlString); - } - - public void Check(int id) - { - string sqlString = $"UPDATE siteserver_User SET IsChecked = '{true}' WHERE Id = {id}"; - - ExecuteNonQuery(sqlString); - } - - public void Lock(List idList) - { - string sqlString = - $"UPDATE siteserver_User SET IsLockedOut = '{true}' WHERE Id IN ({TranslateUtils.ToSqlInStringWithQuote(idList)})"; - - ExecuteNonQuery(sqlString); - } - - public void UnLock(List idList) - { - string sqlString = - $"UPDATE siteserver_User SET IsLockedOut = '{false}', CountOfFailedLogin = 0 WHERE Id IN ({TranslateUtils.ToSqlInStringWithQuote(idList)})"; - - ExecuteNonQuery(sqlString); - } - - public UserInfo GetUserInfoByAccount(string account) - { - if (string.IsNullOrEmpty(account)) return null; - - UserInfo userInfo = null; - - if (StringUtils.IsMobile(account)) - { - userInfo = GetUserInfoByMobile(account); - } - else if (StringUtils.IsEmail(account)) - { - userInfo = GetUserInfoByEmail(account); - } - - return userInfo ?? GetUserInfoByUserName(account); - } - - private UserInfo GetUserInfo(IDataReader rdr) - { - var i = 0; - var userInfo = new UserInfo - { - Id = GetInt(rdr, i++), - UserName = GetString(rdr, i++), - Password = GetString(rdr, i++), - PasswordFormat = GetString(rdr, i++), - PasswordSalt = GetString(rdr, i++), - CreateDate = GetDateTime(rdr, i++), - LastResetPasswordDate = GetDateTime(rdr, i++), - LastActivityDate = GetDateTime(rdr, i++), - CountOfLogin = GetInt(rdr, i++), - CountOfFailedLogin = GetInt(rdr, i++), - CountOfWriting = GetInt(rdr, i++), - IsChecked = GetBool(rdr, i++), - IsLockedOut = GetBool(rdr, i++), - DisplayName = GetString(rdr, i++), - Email = GetString(rdr, i++), - Mobile = GetString(rdr, i++), - AvatarUrl = GetString(rdr, i++), - Organization = GetString(rdr, i++), - Department = GetString(rdr, i++), - Position = GetString(rdr, i++), - Gender = GetString(rdr, i++), - Birthday = GetString(rdr, i++), - Education = GetString(rdr, i++), - Graduation = GetString(rdr, i++), - Address = GetString(rdr, i++), - WeiXin = GetString(rdr, i++), - Qq = GetString(rdr, i++), - WeiBo = GetString(rdr, i++), - Interests = GetString(rdr, i++), - Signature = GetString(rdr, i) - }; - if (string.IsNullOrEmpty(userInfo.DisplayName)) - { - userInfo.DisplayName = userInfo.UserName; - } - return userInfo; - } - - public UserInfo GetUserInfoByUserName(string userName) - { - if (string.IsNullOrEmpty(userName)) return null; - - UserInfo userInfo = null; - const string sqlString = "SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreateDate, LastResetPasswordDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, CountOfWriting, IsChecked, IsLockedOut, DisplayName, Email, Mobile, AvatarUrl, Organization, Department, Position, Gender, Birthday, Education, Graduation, Address, WeiXin, QQ, WeiBo, Interests, Signature FROM siteserver_User WHERE UserName = @UserName"; - - var parms = new IDataParameter[] - { - GetParameter(ParmUserName, DataType.VarChar, 255, userName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - userInfo = GetUserInfo(rdr); - } - rdr.Close(); - } - return userInfo; - } - - public UserInfo GetUserInfoByEmail(string email) - { - if (string.IsNullOrEmpty(email)) return null; - - UserInfo userInfo = null; - const string sqlString = "SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreateDate, LastResetPasswordDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, CountOfWriting, IsChecked, IsLockedOut, DisplayName, Email, Mobile, AvatarUrl, Organization, Department, Position, Gender, Birthday, Education, Graduation, Address, WeiXin, QQ, WeiBo, Interests, Signature FROM siteserver_User WHERE Email = @Email"; - - var parms = new IDataParameter[] - { - GetParameter(ParmEmail, DataType.VarChar, 255, email) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - userInfo = GetUserInfo(rdr); - } - rdr.Close(); - } - return userInfo; - } - - public UserInfo GetUserInfoByMobile(string mobile) - { - if (string.IsNullOrEmpty(mobile)) return null; - - UserInfo userInfo = null; - const string sqlString = "SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreateDate, LastResetPasswordDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, CountOfWriting, IsChecked, IsLockedOut, DisplayName, Email, Mobile, AvatarUrl, Organization, Department, Position, Gender, Birthday, Education, Graduation, Address, WeiXin, QQ, WeiBo, Interests, Signature FROM siteserver_User WHERE Mobile = @Mobile"; - - var parms = new IDataParameter[] - { - GetParameter(ParmMobile, DataType.VarChar, 20, mobile) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - userInfo = GetUserInfo(rdr); - } - rdr.Close(); - } - return userInfo; - } - - public string GetUserNameByMobile(string mobile) - { - if (string.IsNullOrEmpty(mobile)) return string.Empty; - - var userName = string.Empty; - const string sqlString = "SELECT UserName FROM siteserver_User WHERE Mobile = @Mobile"; - - var parms = new IDataParameter[] - { - GetParameter(ParmMobile, DataType.VarChar, 20, mobile) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - userName = GetString(rdr, 0); - } - rdr.Close(); - } - return userName; - } - - public UserInfo GetUserInfo(int id) - { - if (id <= 0) return null; - - UserInfo userInfo = null; - const string sqlString = "SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreateDate, LastResetPasswordDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, CountOfWriting, IsChecked, IsLockedOut, DisplayName, Email, Mobile, AvatarUrl, Organization, Department, Position, Gender, Birthday, Education, Graduation, Address, WeiXin, QQ, WeiBo, Interests, Signature FROM siteserver_User WHERE Id = @Id"; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, id) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - userInfo = GetUserInfo(rdr); - } - rdr.Close(); - } - return userInfo; - } - - public bool IsUserNameExists(string userName) - { - if (string.IsNullOrEmpty(userName)) return false; - - var exists = false; - - const string sqlString = "SELECT Id FROM siteserver_User WHERE UserName = @UserName"; - - var parms = new IDataParameter[] - { - GetParameter(ParmUserName, DataType.VarChar, 255, userName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read() && !rdr.IsDBNull(0)) - { - exists = true; - } - rdr.Close(); - } - - return exists; - } - - public bool IsUserNameCompliant(string userName) - { - if (userName.IndexOf(" ", StringComparison.Ordinal) != -1 || userName.IndexOf(" ", StringComparison.Ordinal) != -1 || userName.IndexOf("'", StringComparison.Ordinal) != -1 || userName.IndexOf(":", StringComparison.Ordinal) != -1 || userName.IndexOf(".", StringComparison.Ordinal) != -1) - { - return false; - } - return DirectoryUtils.IsDirectoryNameCompliant(userName); - } - - public bool IsEmailExists(string email) - { - if (string.IsNullOrEmpty(email)) return false; - - var exists = false; - - const string sqlSelect = "SELECT Email FROM siteserver_User WHERE Email = @Email"; - - var parms = new IDataParameter[] - { - GetParameter(ParmEmail, DataType.VarChar, 200, email) - }; - - using (var rdr = ExecuteReader(sqlSelect, parms)) - { - if (rdr.Read()) - { - exists = true; - } - rdr.Close(); - } - - return exists; - } - - public bool IsMobileExists(string mobile) - { - if (string.IsNullOrEmpty(mobile)) return false; - - var exists = false; - const string sqlString = "SELECT Mobile FROM siteserver_User WHERE Mobile = @Mobile"; - - var parms = new IDataParameter[] - { - GetParameter(ParmMobile, DataType.VarChar, 20, mobile) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - exists = true; - } - rdr.Close(); - } - - return exists; - } - - public string GetUserName(int id) - { - var userName = string.Empty; - - const string sqlString = "SELECT UserName FROM siteserver_User WHERE Id = @Id"; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, id) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - userName = GetString(rdr, 0); - } - rdr.Close(); - } - return userName; - } - - public string GetEmail(int id) - { - var email = string.Empty; - - const string sqlString = "SELECT Email FROM siteserver_User WHERE Id = @Id"; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, id) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - email = GetString(rdr, 0); - } - rdr.Close(); - } - return email; - } - - public int GetId(string userName) - { - var id = 0; - - const string sqlString = "SELECT Id FROM siteserver_User WHERE UserName = @UserName"; - - var parms = new IDataParameter[] - { - GetParameter(ParmUserName, DataType.VarChar, 255, userName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - id = GetInt(rdr, 0); - } - rdr.Close(); - } - return id; - } - - public string GetDisplayName(string userName) - { - if (string.IsNullOrEmpty(userName)) return string.Empty; - var displayName = string.Empty; - - const string sqlString = "SELECT DisplayName FROM siteserver_User WHERE UserName = @UserName"; - - var parms = new IDataParameter[] - { - GetParameter(ParmUserName, DataType.VarChar, 255, userName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - displayName = GetString(rdr, 0); - } - rdr.Close(); - } - - if (string.IsNullOrEmpty(displayName)) - { - displayName = userName; - } - - return displayName; - } - - public int GetIdByEmailOrMobile(string email, string mobile) - { - var id = 0; - - if (!string.IsNullOrEmpty(email)) - { - const string sqlString = @"SELECT Id FROM siteserver_User WHERE Email = @Email"; - - var parms = new IDataParameter[] - { - GetParameter(ParmEmail, DataType.VarChar, 200, email) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - id = GetInt(rdr, 0); - } - rdr.Close(); - } - } - else if (!string.IsNullOrEmpty(mobile)) - { - const string sqlString = "SELECT Id FROM siteserver_User WHERE Mobile = @Mobile"; - - var parms = new IDataParameter[] - { - GetParameter(ParmMobile, DataType.VarChar, 20, mobile) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - id = GetInt(rdr, 0); - } - rdr.Close(); - } - } - - return id; - } - - public string GetMobile(int id) - { - var mobile = string.Empty; - - const string sqlString = "SELECT Mobile FROM siteserver_User WHERE Id = @Id"; - - var parms = new IDataParameter[] - { - GetParameter(ParmId, DataType.Integer, id) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - mobile = GetString(rdr, 0); - } - rdr.Close(); - } - return mobile; - } - - public string GetMobileByAccount(string account) - { - if (string.IsNullOrEmpty(account)) return string.Empty; - - var mobile = string.Empty; - - string sqlString; - IDataParameter[] parms; - - if (StringUtils.IsMobile(account)) - { - sqlString = "SELECT Mobile FROM siteserver_User WHERE Mobile = @Mobile"; - parms = new IDataParameter[] - { - GetParameter(ParmMobile, DataType.VarChar, 20, account) - }; - } - else if (StringUtils.IsEmail(account)) - { - sqlString = "SELECT Mobile FROM siteserver_User WHERE Email = @Email"; - parms = new IDataParameter[] - { - GetParameter(ParmEmail, DataType.VarChar, 200, account) - }; - } - else - { - sqlString = "SELECT Mobile FROM siteserver_User WHERE UserName = @UserName"; - parms = new IDataParameter[] - { - GetParameter(ParmUserName, DataType.VarChar, 255, account) - }; - } - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - mobile = GetString(rdr, 0); - } - rdr.Close(); - } - - return mobile; - } - - public int GetTotalCount() - { - var count = 0; - - using (var rdr = ExecuteReader("SELECT COUNT(*) AS TotalNum FROM siteserver_User")) - { - if (rdr.Read()) - { - count = GetInt(rdr, 0); - } - rdr.Close(); - } - return count; - } - - public List GetUserNameList(bool isChecked) - { - var userNameList = new List(); - string sqlSelect = - $"SELECT UserName FROM siteserver_User WHERE IsChecked = '{isChecked}' ORDER BY Id DESC"; - - using (var rdr = ExecuteReader(sqlSelect)) - { - while (rdr.Read()) - { - userNameList.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - return userNameList; - } - - public List GetIdList(bool isChecked) - { - var idList = new List(); - - string sqlSelect = - $"SELECT Id FROM siteserver_User WHERE IsChecked = '{isChecked}' ORDER BY Id DESC"; - - using (var rdr = ExecuteReader(sqlSelect)) - { - while (rdr.Read()) - { - idList.Add(GetInt(rdr, 0)); - } - rdr.Close(); - } - - return idList; - } - - public List GetUserNameList(string searchWord, int dayOfCreate, int dayOfLastActivity, bool isChecked) - { - var list = new List(); - - var whereString = string.Empty; - - if (dayOfCreate > 0) - { - var dateTime = DateTime.Now.AddDays(-dayOfCreate); - whereString += $" AND (CreateDate >= {SqlUtils.GetComparableDate(dateTime)}) "; - } - if (dayOfLastActivity > 0) - { - var dateTime = DateTime.Now.AddDays(-dayOfLastActivity); - whereString += $" AND (LastActivityDate >= {SqlUtils.GetComparableDate(dateTime)}) "; - } - if (!string.IsNullOrEmpty(searchWord)) - { - var word = PageUtils.FilterSql(searchWord); - whereString += $" AND (UserName LIKE '%{word}%' OR EMAIL LIKE '%{word}%' OR MOBILE = '{word}') "; - } - string sqlString = - $"SELECT UserName FROM siteserver_User WHERE IsChecked = '{isChecked}' {whereString} ORDER BY Id DESC"; - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - list.Add(GetString(rdr, 0)); - } - rdr.Close(); - } - return list; - } - - public string GetSelectCommand(bool isChecked) - { - string whereString = $"WHERE IsChecked = '{isChecked}'"; - return DataProvider.DatabaseDao.GetSelectSqlString(TableName, SqlUtils.Asterisk, whereString); - } - - public string GetSelectCommand(string searchWord, int dayOfCreate, int dayOfLastActivity, bool isChecked, int loginCount, string searchType) - { - var whereBuilder = new StringBuilder(); - - if (dayOfCreate > 0) - { - whereBuilder.Append(" AND "); - - var dateTime = DateTime.Now.AddDays(-dayOfCreate); - whereBuilder.Append($"(CreateDate >= {SqlUtils.GetComparableDate(dateTime)})"); - } - - if (dayOfLastActivity > 0) - { - whereBuilder.Append(" AND "); - - var dateTime = DateTime.Now.AddDays(-dayOfLastActivity); - whereBuilder.Append($"(LastActivityDate >= {SqlUtils.GetComparableDate(dateTime)}) "); - } - - if (string.IsNullOrEmpty(searchType)) - { - whereBuilder.Append(" AND "); - whereBuilder.Append( - $"(UserName LIKE '%{PageUtils.FilterSql(searchWord)}%' OR EMAIL LIKE '%{PageUtils.FilterSql(searchWord)}%')"); - } - else - { - whereBuilder.Append(" AND "); - whereBuilder.Append($"({searchType} LIKE '%{searchWord}%') "); - } - - if (loginCount > 0) - { - whereBuilder.Append(" AND "); - whereBuilder.Append($"(CountOfLogin > {loginCount})"); - } - - var whereString = string.Empty; - if (whereBuilder.Length > 0) - { - whereString = $"WHERE IsChecked = '{isChecked}' {whereBuilder}"; - } - - return DataProvider.DatabaseDao.GetSelectSqlString(TableName, SqlUtils.Asterisk, whereString); - } - - public string GetSortFieldName() - { - return "Id"; - } - - public IDataReader GetStlDataSource(int startNum, int totalNum, string orderByString, string whereString) - { - string sqlWhereString = $"WHERE IsChecked = '{true}' {whereString}"; - if (string.IsNullOrEmpty(orderByString)) - { - orderByString = "ORDER BY Id DESC"; - } - - IDataReader enumerable; - - if (startNum <= 1) - { - var sqlString = DataProvider.DatabaseDao.GetSelectSqlString(TableName, totalNum, SqlUtils.Asterisk, sqlWhereString, orderByString); - enumerable = ExecuteReader(sqlString); - } - else - { - var sqlSelect = DataProvider.DatabaseDao.GetSelectSqlString(TableName, startNum, totalNum, SqlUtils.Asterisk, sqlWhereString, orderByString); - enumerable = ExecuteReader(sqlSelect); - } - - return enumerable; - } - - public bool CheckPassword(string password, string dbpassword, EPasswordFormat passwordFormat, string passwordSalt) - { - var decodePassword = DecodePassword(dbpassword, passwordFormat, passwordSalt); - return password == decodePassword; - } - - public bool Import(UserInfo userInfo) - { - if (string.IsNullOrEmpty(userInfo.UserName)) - { - return false; - } - if (string.IsNullOrEmpty(userInfo.Password)) - { - return false; - } - if (IsUserNameExists(userInfo.UserName)) - { - return false; - } - try - { - InsertWithoutValidation(userInfo, userInfo.Password, EPasswordFormatUtils.GetEnumType(userInfo.PasswordFormat), userInfo.PasswordSalt); - - return true; - } - catch - { - return false; - } - } - - public void UpdateLastActivityDateAndCountOfFailedLogin(string userName) - { - if (string.IsNullOrEmpty(userName)) return; - - var sqlString = $"UPDATE siteserver_User SET LastActivityDate = @LastActivityDate, {SqlUtils.ToPlusSqlString("CountOfFailedLogin")} WHERE UserName = @UserName"; - - IDataParameter[] updateParms = { - GetParameter(ParmLastActivityDate, DataType.DateTime, DateTime.Now), - GetParameter(ParmUserName, DataType.VarChar, 255, userName) - }; - - ExecuteNonQuery(sqlString, updateParms); - } - - public void UpdateLastActivityDateAndCountOfLogin(string userName) - { - if (string.IsNullOrEmpty(userName)) return; - - var sqlString = $"UPDATE siteserver_User SET LastActivityDate = @LastActivityDate, {SqlUtils.ToPlusSqlString("CountOfLogin")}, CountOfFailedLogin = 0 WHERE UserName = @UserName"; - - IDataParameter[] updateParms = { - GetParameter(ParmLastActivityDate, DataType.DateTime, DateTime.Now), - GetParameter(ParmUserName, DataType.VarChar, 255, userName) - }; - - ExecuteNonQuery(sqlString, updateParms); - } - - public bool Validate(string account, string password, out string userName, out string errorMessage) - { - userName = string.Empty; - errorMessage = string.Empty; - - if (string.IsNullOrEmpty(account)) - { - errorMessage = "账号不能为空"; - return false; - } - if (string.IsNullOrEmpty(password)) - { - errorMessage = "密码不能为空"; - return false; - } - - var userInfo = GetUserInfoByAccount(account); - - if (string.IsNullOrEmpty(userInfo?.UserName)) - { - errorMessage = "帐号或密码错误"; - return false; - } - - userName = userInfo.UserName; - - if (!userInfo.IsChecked) - { - errorMessage = "此账号未审核,无法登录"; - return false; - } - - if (userInfo.IsLockedOut) - { - errorMessage = "此账号被锁定,无法登录"; - return false; - } - - if (ConfigManager.SystemConfigInfo.IsUserLockLogin) - { - if (userInfo.CountOfFailedLogin > 0 && userInfo.CountOfFailedLogin >= ConfigManager.SystemConfigInfo.UserLockLoginCount) - { - var lockType = EUserLockTypeUtils.GetEnumType(ConfigManager.SystemConfigInfo.UserLockLoginType); - if (lockType == EUserLockType.Forever) - { - errorMessage = "此账号错误登录次数过多,已被永久锁定"; - return false; - } - if (lockType == EUserLockType.Hours) - { - var ts = new TimeSpan(DateTime.Now.Ticks - userInfo.LastActivityDate.Ticks); - var hours = Convert.ToInt32(ConfigManager.SystemConfigInfo.UserLockLoginHours - ts.TotalHours); - if (hours > 0) - { - errorMessage = - $"此账号错误登录次数过多,已被锁定,请等待{hours}小时后重试"; - return false; - } - } - } - } - - if (!CheckPassword(password, userInfo.Password, EPasswordFormatUtils.GetEnumType(userInfo.PasswordFormat), userInfo.PasswordSalt)) - { - LogUtils.AddUserLog(userInfo.UserName, "用户登录失败", "帐号或密码错误"); - errorMessage = "帐号或密码错误"; - return false; - } - - UpdateLastActivityDate(userInfo.UserName); - - return true; - } - - public Dictionary GetTrackingDictionary(DateTime dateFrom, DateTime dateTo, string xType) - { - var dict = new Dictionary(); - if (string.IsNullOrEmpty(xType)) - { - xType = EStatictisXTypeUtils.GetValue(EStatictisXType.Day); - } - - var builder = new StringBuilder(); - builder.Append($" AND CreateDate >= {SqlUtils.GetComparableDate(dateFrom)}"); - builder.Append($" AND CreateDate < {SqlUtils.GetComparableDate(dateTo)}"); - - string sqlString = $@" -SELECT COUNT(*) AS AddNum, AddYear, AddMonth, AddDay FROM ( - SELECT {SqlUtils.GetDatePartYear("CreateDate")} AS AddYear, {SqlUtils.GetDatePartMonth("CreateDate")} AS AddMonth, {SqlUtils.GetDatePartDay("CreateDate")} AS AddDay - FROM siteserver_User - WHERE {SqlUtils.GetDateDiffLessThanDays("CreateDate", 30.ToString())} {builder} -) DERIVEDTBL GROUP BY AddYear, AddMonth, AddDay ORDER BY AddYear, AddMonth, AddDay -";//添加日统计 - - if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Month)) - { - sqlString = $@" -SELECT COUNT(*) AS AddNum, AddYear, AddMonth FROM ( - SELECT {SqlUtils.GetDatePartYear("CreateDate")} AS AddYear, {SqlUtils.GetDatePartMonth("CreateDate")} AS AddMonth - FROM siteserver_User - WHERE {SqlUtils.GetDateDiffLessThanMonths("CreateDate", 12.ToString())} {builder} -) DERIVEDTBL GROUP BY AddYear, AddMonth ORDER BY AddYear, AddMonth -";//添加月统计 - } - else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Year)) - { - sqlString = $@" -SELECT COUNT(*) AS AddNum, AddYear FROM ( - SELECT {SqlUtils.GetDatePartYear("CreateDate")} AS AddYear - FROM siteserver_User - WHERE {SqlUtils.GetDateDiffLessThanYears("CreateDate", 10.ToString())} {builder} -) DERIVEDTBL GROUP BY AddYear ORDER BY AddYear -";//添加年统计 - } - - using (var rdr = ExecuteReader(sqlString)) - { - while (rdr.Read()) - { - var accessNum = GetInt(rdr, 0); - if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Day)) - { - var year = GetString(rdr, 1); - var month = GetString(rdr, 2); - var day = GetString(rdr, 3); - var dateTime = TranslateUtils.ToDateTime($"{year}-{month}-{day}"); - dict.Add(dateTime, accessNum); - } - else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Month)) - { - var year = GetString(rdr, 1); - var month = GetString(rdr, 2); - - var dateTime = TranslateUtils.ToDateTime($"{year}-{month}-1"); - dict.Add(dateTime, accessNum); - } - else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Year)) - { - var year = GetString(rdr, 1); - var dateTime = TranslateUtils.ToDateTime($"{year}-1-1"); - dict.Add(dateTime, accessNum); - } - } - rdr.Close(); - } - return dict; - } - } -} - diff --git a/SiteServer.CMS/Provider/UserLogDao.cs b/SiteServer.CMS/Provider/UserLogDao.cs deleted file mode 100644 index 2c8a3165c..000000000 --- a/SiteServer.CMS/Provider/UserLogDao.cs +++ /dev/null @@ -1,270 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Text; -using SiteServer.CMS.Data; -using SiteServer.CMS.Model; -using SiteServer.Plugin; -using SiteServer.Utils; - -namespace SiteServer.CMS.Provider -{ - public class UserLogDao : DataProviderBase - { - public override string TableName => "siteserver_UserLog"; - - public override List TableColumns => new List - { - new TableColumnInfo - { - ColumnName = nameof(UserLogInfo.Id), - DataType = DataType.Integer, - IsIdentity = true, - IsPrimaryKey = true - }, - new TableColumnInfo - { - ColumnName = nameof(UserLogInfo.UserName), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(UserLogInfo.IpAddress), - DataType = DataType.VarChar, - Length = 50 - }, - new TableColumnInfo - { - ColumnName = nameof(UserLogInfo.AddDate), - DataType = DataType.DateTime - }, - new TableColumnInfo - { - ColumnName = nameof(UserLogInfo.Action), - DataType = DataType.VarChar, - Length = 255 - }, - new TableColumnInfo - { - ColumnName = nameof(UserLogInfo.Summary), - DataType = DataType.VarChar, - Length = 255 - } - }; - - private const string ParmUserName = "@UserName"; - private const string ParmIpAddress = "@IPAddress"; - private const string ParmAddDate = "@AddDate"; - private const string ParmAction = "@Action"; - private const string ParmSummary = "@Summary"; - - public void Insert(UserLogInfo userLog) - { - var sqlString = "INSERT INTO siteserver_UserLog(UserName, IPAddress, AddDate, Action, Summary) VALUES (@UserName, @IPAddress, @AddDate, @Action, @Summary)"; - - var parms = new IDataParameter[] - { - GetParameter(ParmUserName, DataType.VarChar, 50, userLog.UserName), - GetParameter(ParmIpAddress, DataType.VarChar, 50, userLog.IpAddress), - GetParameter(ParmAddDate, DataType.DateTime, userLog.AddDate), - GetParameter(ParmAction, DataType.VarChar, 255, userLog.Action), - GetParameter(ParmSummary, DataType.VarChar, 255, userLog.Summary) - }; - - ExecuteNonQuery(sqlString, parms); - } - - public void Delete(int days) - { - if (days <= 0) return; - ExecuteNonQuery($@"DELETE FROM siteserver_UserLog WHERE AddDate < '{DateUtils.GetDateAndTimeString(DateTime.Now.AddDays(-days))}'"); - } - - public void Delete(List idList) - { - if (idList != null && idList.Count > 0) - { - string sqlString = - $"DELETE FROM siteserver_UserLog WHERE ID IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; - - ExecuteNonQuery(sqlString); - } - } - - public void DeleteAll() - { - var sqlString = "DELETE FROM siteserver_UserLog"; - - ExecuteNonQuery(sqlString); - } - - public int GetCount() - { - var count = 0; - var sqlString = "SELECT Count(ID) FROM siteserver_UserLog"; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - count = GetInt(rdr, 0); - } - rdr.Close(); - } - - return count; - } - - public int GetCount(string where) - { - var count = 0; - var sqlString = "SELECT Count(ID) FROM siteserver_UserLog"; - if (!string.IsNullOrEmpty(where)) - sqlString += " WHERE " + where; - - using (var rdr = ExecuteReader(sqlString)) - { - if (rdr.Read()) - { - count = GetInt(rdr, 0); - } - rdr.Close(); - } - - return count; - } - - public string GetSelectCommend() - { - return "SELECT ID, UserName, IPAddress, AddDate, Action, Summary FROM siteserver_UserLog"; - } - - public string GetSelectCommend(string userName, string keyword, string dateFrom, string dateTo) - { - if (string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(keyword) && string.IsNullOrEmpty(dateFrom) && string.IsNullOrEmpty(dateTo)) - { - return GetSelectCommend(); - } - - var whereString = new StringBuilder("WHERE "); - - var isWhere = false; - - if (!string.IsNullOrEmpty(userName)) - { - isWhere = true; - whereString.AppendFormat("(UserName = '{0}')", PageUtils.FilterSql(userName)); - } - - if (!string.IsNullOrEmpty(keyword)) - { - if (isWhere) - { - whereString.Append(" AND "); - } - isWhere = true; - whereString.AppendFormat("(Action LIKE '%{0}%' OR Summary LIKE '%{0}%')", PageUtils.FilterSql(keyword)); - } - - if (!string.IsNullOrEmpty(dateFrom)) - { - if (isWhere) - { - whereString.Append(" AND "); - } - isWhere = true; - whereString.Append($"(AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))})"); - } - if (!string.IsNullOrEmpty(dateTo)) - { - if (isWhere) - { - whereString.Append(" AND "); - } - whereString.Append($"(AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo))})"); - } - - return "SELECT ID, UserName, IPAddress, AddDate, Action, Summary FROM siteserver_UserLog " + whereString; - } - - public DateTime GetLastUserLoginDate(string userName) - { - var retval = DateTime.MinValue; - //const string sqlString = "SELECT TOP 1 AddDate FROM siteserver_UserLog WHERE UserName = @UserName ORDER BY ID DESC"; - var sqlString = SqlUtils.ToTopSqlString("siteserver_UserLog", "AddDate", "WHERE UserName = @UserName", - "ORDER BY ID DESC", 1); - - var parms = new IDataParameter[] - { - GetParameter(ParmUserName, DataType.VarChar, 50, userName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - retval = GetDateTime(rdr, 0); - } - rdr.Close(); - } - return retval; - } - - public DateTime GetLastRemoveUserLogDate(string userName) - { - var retval = DateTime.MinValue; - //const string sqlString = "SELECT TOP 1 AddDate FROM siteserver_UserLog WHERE UserName = @UserName AND Action = '清空数据库日志' ORDER BY ID DESC"; - var sqlString = SqlUtils.ToTopSqlString("siteserver_UserLog", "AddDate", - "WHERE UserName = @UserName AND Action = '清空数据库日志'", "ORDER BY ID DESC", 1); - - var parms = new IDataParameter[] - { - GetParameter(ParmUserName, DataType.VarChar, 50, userName) - }; - - using (var rdr = ExecuteReader(sqlString, parms)) - { - if (rdr.Read()) - { - retval = GetDateTime(rdr, 0); - } - rdr.Close(); - } - return retval; - } - - public List List(string userName, int totalNum, string action) - { - var list = new List(); - var sqlString = "SELECT * FROM siteserver_UserLog WHERE UserName = @UserName"; - - if (!string.IsNullOrEmpty(action)) - { - sqlString += " And Action = @Action"; - } - sqlString += " ORDER BY ID DESC"; - - var parameters = new List - { - GetParameter(ParmUserName, DataType.VarChar, 50, userName) - }; - if (!string.IsNullOrEmpty(action)) - { - parameters.Add(GetParameter(ParmAction, DataType.VarChar, 255, action)); - } - - using (var rdr = ExecuteReader(sqlString, parameters.ToArray())) - { - while (rdr.Read()) - { - var i = 0; - var info = new UserLogInfo(GetInt(rdr, i++), GetString(rdr, i++), GetString(rdr, i++), GetDateTime(rdr, i++), GetString(rdr, i++), GetString(rdr, i)); - list.Add(info); - } - } - - return list; - } - } -} diff --git a/SiteServer.CMS/SiteServer.CMS.csproj b/SiteServer.CMS/SiteServer.CMS.csproj deleted file mode 100644 index f26bb5bcd..000000000 --- a/SiteServer.CMS/SiteServer.CMS.csproj +++ /dev/null @@ -1,456 +0,0 @@ - - - - - - Debug - AnyCPU - {944127C3-915D-4F02-A534-64EC668C46EC} - Library - Properties - SiteServer.CMS - SiteServer.CMS - v4.5.2 - 512 - - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\Microsoft.Web.Xdt.2.1.1\lib\net40\Microsoft.Web.XmlTransform.dll - - - ..\packages\MySql.Data.6.10.6\lib\net452\MySql.Data.dll - - - ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll - - - ..\packages\Npgsql.3.2.7\lib\net451\Npgsql.dll - - - ..\packages\NuGet.Common.4.5.0\lib\net45\NuGet.Common.dll - - - ..\packages\NuGet.Core.2.14.0\lib\net40-Client\NuGet.Core.dll - - - ..\packages\NuGet.Frameworks.4.5.0\lib\net45\NuGet.Frameworks.dll - - - ..\packages\NuGet.Packaging.4.5.0\lib\net45\NuGet.Packaging.dll - - - ..\packages\NuGet.Packaging.Core.4.5.0\lib\net45\NuGet.Packaging.Core.dll - - - ..\packages\NuGet.Versioning.4.5.0\lib\net45\NuGet.Versioning.dll - - - ..\packages\Oracle.ManagedDataAccess.12.2.1100\lib\net40\Oracle.ManagedDataAccess.dll - True - - - ..\packages\SiteServer.Plugin.1.5.0\lib\net45\SiteServer.Plugin.dll - - - - - - - - - - - - - - ..\packages\System.Threading.Tasks.Extensions.4.3.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll - - - - - - - - - - - ..\ref\WordPlugin.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {2176d8ba-5f57-4c56-8e21-a09011517ae2} - SiteServer.Utils - - - - - - 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - - - \ No newline at end of file diff --git a/SiteServer.CMS/StlControls/CommentInput.cs b/SiteServer.CMS/StlControls/CommentInput.cs deleted file mode 100644 index cbe90807e..000000000 --- a/SiteServer.CMS/StlControls/CommentInput.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System.Web.UI; -using SiteServer.Utils; -using SiteServer.CMS.Core; - -namespace SiteServer.CMS.StlControls -{ - public class CommentInput : LiteralControl - { - public bool IsAnonymous - { - get { return ViewState["IsAnonymous"] == null || TranslateUtils.ToBool(ViewState["IsAnonymous"].ToString()); } - set { ViewState["IsAnonymous"] = value; } - } - - public int PageNum - { - get { return ViewState["PageNum"] != null ? TranslateUtils.ToInt(ViewState["PageNum"].ToString()) : 20; } - set { ViewState["PageNum"] = value; } - } - - public string ApiUrl - { - get { return ViewState["ApiUrl"] as string; } - set { ViewState["ApiUrl"] = value; } - } - - public string ApiGetUrl - { - get { return ViewState["ApiGetUrl"] as string; } - set { ViewState["ApiGetUrl"] = value; } - } - - public string ApiActionsAddUrl - { - get { return ViewState["ApiActionsAddUrl"] as string; } - set { ViewState["ApiActionsAddUrl"] = value; } - } - - public string ApiActionsGoodUrl - { - get { return ViewState["ApiActionsGoodUrl"] as string; } - set { ViewState["ApiActionsGoodUrl"] = value; } - } - - public string ApiActionsDeleteUrl - { - get { return ViewState["ApiActionsDeleteUrl"] as string; } - set { ViewState["ApiActionsDeleteUrl"] = value; } - } - - public string ApiActionsLogoutUrl - { - get { return ViewState["ApiActionsLogoutUrl"] as string; } - set { ViewState["ApiActionsLogoutUrl"] = value; } - } - - public bool IsDelete - { - get { return (bool)ViewState["IsDelete"]; } - set { ViewState["IsDelete"] = value; } - } - - protected override void Render(HtmlTextWriter writer) - { - writer.Write($@" - - -
    - {TemplateManager.GetContentByFilePath(SiteFilesAssets.CommentInput.CommentsTemplatePath)} -
    - -"); - } - } -} diff --git a/SiteServer.CMS/StlParser/Cache/Administrator.cs b/SiteServer.CMS/StlParser/Cache/Administrator.cs deleted file mode 100644 index b98667678..000000000 --- a/SiteServer.CMS/StlParser/Cache/Administrator.cs +++ /dev/null @@ -1,29 +0,0 @@ -using SiteServer.CMS.Core; - -namespace SiteServer.CMS.StlParser.Cache -{ - public class Administrator - { - private static readonly object LockObject = new object(); - - public static string GetDisplayName(string userName) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Administrator), nameof(GetDisplayName), - userName); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.AdministratorDao.GetDisplayName(userName); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - } -} diff --git a/SiteServer.CMS/StlParser/Cache/Content.cs b/SiteServer.CMS/StlParser/Cache/Content.cs deleted file mode 100644 index fc1643b0f..000000000 --- a/SiteServer.CMS/StlParser/Cache/Content.cs +++ /dev/null @@ -1,395 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.StlParser.Cache -{ - public class Content - { - private static readonly object LockObject = new object(); - - public static void ClearCache() - { - StlCacheUtils.ClearCache(nameof(Content)); - } - - public static List GetContentIdListChecked(string tableName, int channelId, string orderByFormatString) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), nameof(GetContentIdListChecked), - tableName, channelId.ToString(), orderByFormatString); - var retval = StlCacheUtils.GetCache>(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache>(cacheKey); - if (retval == null) - { - retval = DataProvider.ContentDao.GetContentIdListChecked(tableName, channelId, orderByFormatString); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static DataSet GetStlDataSourceChecked(List channelIdList, string tableName, int startNum, int totalNum, string orderByString, string whereString, bool isNoDup, LowerNameValueCollection others) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), nameof(GetStlDataSourceChecked), - TranslateUtils.ObjectCollectionToString(channelIdList), tableName, startNum.ToString(), totalNum.ToString(), orderByString, whereString, isNoDup.ToString(), TranslateUtils.NameValueCollectionToString(others)); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.ContentDao.GetStlDataSourceChecked(channelIdList, tableName, startNum, totalNum, orderByString, whereString, isNoDup, others); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static ContentInfo GetContentInfo(string tableName, int contentId) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), nameof(GetContentInfo), tableName, contentId.ToString()); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.ContentDao.GetContentInfo(tableName, contentId); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static ContentInfo GetContentInfo(int siteId, int channelId, int contentId) - { - if (siteId <= 0 || channelId <= 0 || contentId <= 0) return null; - - var siteInfo = SiteManager.GetSiteInfo(siteId); - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - - return GetContentInfo(tableName, contentId); - } - - public static string GetValue(string tableName, int contentId, string type) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), nameof(GetValue), tableName, - contentId.ToString(), type); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.ContentDao.GetValue(tableName, contentId, type); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static int GetSequence(string tableName, int channelId, int contentId) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), nameof(GetSequence), - tableName, channelId.ToString(), contentId.ToString()); - var retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval != -1) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval == -1) - { - retval = DataProvider.ContentDao.GetSequence(tableName, channelId, contentId); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static int GetCountCheckedImage(int siteId, int channelId) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), nameof(GetCountCheckedImage), - siteId.ToString(), channelId.ToString()); - var retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval != -1) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval == -1) - { - retval = DataProvider.ContentDao.GetCountCheckedImage(siteId, channelId); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static int GetCountOfContentAdd(string tableName, int siteId, int channelId, EScopeType scope, - DateTime begin, DateTime end, string userName, ETriState checkedState) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), nameof(GetCountOfContentAdd), - siteId.ToString(), channelId.ToString(), EScopeTypeUtils.GetValue(scope), - DateUtils.GetDateString(begin), DateUtils.GetDateString(end), userName, ETriStateUtils.GetValue(checkedState)); - var retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval != -1) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval == -1) - { - retval = DataProvider.ContentDao.GetCountOfContentAdd(tableName, siteId, channelId, scope, - begin, end, userName, checkedState); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static DateTime GetAddDate(string tableName, int contentId) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), nameof(GetAddDate), tableName, - contentId.ToString()); - var retval = StlCacheUtils.GetDateTimeCache(cacheKey); - if (retval != DateTime.MinValue) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetDateTimeCache(cacheKey); - if (retval == DateTime.MinValue) - { - retval = DataProvider.ContentDao.GetAddDate(tableName, contentId); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static DateTime GetLastEditDate(string tableName, int contentId) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), nameof(GetLastEditDate), tableName, - contentId.ToString()); - var retval = StlCacheUtils.GetDateTimeCache(cacheKey); - if (retval != DateTime.MinValue) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetDateTimeCache(cacheKey); - if (retval == DateTime.MinValue) - { - retval = DataProvider.ContentDao.GetLastEditDate(tableName, contentId); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static int GetContentId(string tableName, int channelId, int taxis, bool isNextContent) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), nameof(GetContentId), tableName, - channelId.ToString(), taxis.ToString(), isNextContent.ToString()); - var retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval != -1) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval == -1) - { - retval = DataProvider.ContentDao.GetContentId(tableName, channelId, taxis, isNextContent); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static int GetContentId(string tableName, int channelId, string orderByString) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), nameof(GetContentId), tableName, - channelId.ToString(), orderByString); - var retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval != -1) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval == -1) - { - retval = DataProvider.ContentDao.GetContentId(tableName, channelId, orderByString); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static int GetChannelId(string tableName, int contentId) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), nameof(GetChannelId), tableName, - contentId.ToString()); - var retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval != -1) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval == -1) - { - retval = DataProvider.ContentDao.GetChannelId(tableName, contentId); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static string GetStlWhereString(int siteId, string tableName, string group, string groupNot, string tags, bool isImageExists, bool isImage, bool isVideoExists, bool isVideo, bool isFileExists, bool isFile, bool isTopExists, bool isTop, bool isRecommendExists, bool isRecommend, bool isHotExists, bool isHot, bool isColorExists, bool isColor, string where, bool isCreateSearchDuplicate) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), nameof(GetStlWhereString), - siteId.ToString(), tableName, group, groupNot, - tags, isImageExists.ToString(), isImage.ToString(), isVideoExists.ToString(), isVideo.ToString(), - isFileExists.ToString(), isFile.ToString(), isTopExists.ToString(), isTop.ToString(), - isRecommendExists.ToString(), isRecommend.ToString(), isHotExists.ToString(), isHot.ToString(), - isColorExists.ToString(), isColor.ToString(), where, - isCreateSearchDuplicate.ToString()); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.ContentDao.GetStlWhereString(siteId, tableName, group, - groupNot, - tags, isImageExists, isImage, isVideoExists, isVideo, isFileExists, isFile, isTopExists, isTop, - isRecommendExists, isRecommend, isHotExists, isHot, isColorExists, isColor, where, - isCreateSearchDuplicate); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static string GetStlWhereString(int siteId, string group, string groupNot, string tags, bool isTopExists, bool isTop, string where) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), nameof(GetStlWhereString), - siteId.ToString(), group, groupNot, tags, isTopExists.ToString(), isTop.ToString(), - where); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.ContentDao.GetStlWhereString(siteId, group, groupNot, tags, - isTopExists, isTop, where); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static string GetStlSqlStringChecked(string tableName, int siteId, int channelId, int startNum, int totalNum, string orderByString, string whereString, EScopeType scopeType, string groupChannel, string groupChannelNot, bool isNoDup) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), nameof(GetStlSqlStringChecked), - tableName, siteId.ToString(), channelId.ToString(), startNum.ToString(), - totalNum.ToString(), orderByString, whereString, EScopeTypeUtils.GetValue(scopeType), groupChannel, - groupChannelNot, isNoDup.ToString()); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var channelIdList = ChannelManager.GetChannelIdList(channelInfo, scopeType, groupChannel, groupChannelNot, string.Empty); - retval = DataProvider.ContentDao.GetStlSqlStringChecked(channelIdList, tableName, siteId, channelId, startNum, - totalNum, orderByString, whereString, scopeType, groupChannel, groupChannelNot, isNoDup); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static string GetStlWhereStringBySearch(string tableName, string group, string groupNot, string tags, bool isImageExists, bool isImage, bool isVideoExists, bool isVideo, bool isFileExists, bool isFile, bool isTopExists, bool isTop, bool isRecommendExists, bool isRecommend, bool isHotExists, bool isHot, bool isColorExists, bool isColor, string where) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), nameof(GetStlWhereStringBySearch), - tableName, group, groupNot, tags, isImageExists.ToString(), isImage.ToString(), - isVideoExists.ToString(), isVideo.ToString(), isFileExists.ToString(), isFile.ToString(), - isTopExists.ToString(), isTop.ToString(), isRecommendExists.ToString(), isRecommend.ToString(), - isHotExists.ToString(), isHot.ToString(), isColorExists.ToString(), isColor.ToString(), where); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.ContentDao.GetStlWhereStringBySearch(tableName, group, groupNot, tags, - isImageExists, isImage, isVideoExists, isVideo, isFileExists, isFile, isTopExists, isTop, - isRecommendExists, isRecommend, isHotExists, isHot, isColorExists, isColor, where); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static string GetStlSqlStringCheckedBySearch(string tableName, int startNum, int totalNum, string orderByString, string whereString, bool isNoDup) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Content), - nameof(GetStlSqlStringCheckedBySearch), - tableName, startNum.ToString(), totalNum.ToString(), orderByString, whereString, isNoDup.ToString()); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.ContentDao.GetStlSqlStringCheckedBySearch(tableName, startNum, totalNum, - orderByString, whereString, isNoDup); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - } -} diff --git a/SiteServer.CMS/StlParser/Cache/Database.cs b/SiteServer.CMS/StlParser/Cache/Database.cs deleted file mode 100644 index 6034d65f5..000000000 --- a/SiteServer.CMS/StlParser/Cache/Database.cs +++ /dev/null @@ -1,70 +0,0 @@ -using SiteServer.CMS.Core; - -namespace SiteServer.CMS.StlParser.Cache -{ - public class Database - { - private static readonly object LockObject = new object(); - - public static int GetPageTotalCount(string sqlString) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Database), nameof(GetPageTotalCount), - sqlString); - var retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval != -1) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval == -1) - { - retval = DataProvider.DatabaseDao.GetPageTotalCount(sqlString); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static string GetStlPageSqlString(string sqlString, string orderByString, int totalNum, int pageNum, int currentPageIndex) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Database), nameof(GetStlPageSqlString), - sqlString, orderByString, totalNum.ToString(), pageNum.ToString(), currentPageIndex.ToString()); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.DatabaseDao.GetStlPageSqlString(sqlString, orderByString, totalNum, pageNum, - currentPageIndex); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static string GetString(string connectionString, string queryString) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Database), nameof(GetString), - connectionString, queryString); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.DatabaseDao.GetString(connectionString, queryString); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - } -} diff --git a/SiteServer.CMS/StlParser/Cache/Node.cs b/SiteServer.CMS/StlParser/Cache/Node.cs deleted file mode 100644 index 4a445cf6d..000000000 --- a/SiteServer.CMS/StlParser/Cache/Node.cs +++ /dev/null @@ -1,243 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.StlParser.Cache -{ - public class Node - { - private static readonly object LockObject = new object(); - - public static void ClearCache() - { - StlCacheUtils.ClearCache(nameof(Node)); - } - - public static int GetSiteId(int channelId) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Node), nameof(GetSiteId), - channelId.ToString()); - var retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval != -1) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval == -1) - { - retval = DataProvider.ChannelDao.GetSiteId(channelId); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static int GetSequence(int siteId, int channelId) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Node), nameof(GetSequence), - siteId.ToString(), channelId.ToString()); - var retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval != -1) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval == -1) - { - retval = DataProvider.ChannelDao.GetSequence(siteId, channelId); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static DataSet GetStlDataSourceBySiteId(int siteId, int startNum, int totalNum, string whereString, string orderByString) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Node), nameof(GetStlDataSourceBySiteId), - siteId.ToString(), startNum.ToString(), totalNum.ToString(), whereString, orderByString); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.ChannelDao.GetStlDataSourceBySiteId(siteId, startNum, totalNum, whereString, orderByString); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static DataSet GetStlDataSet(List channelIdList, int startNum, int totalNum, string whereString, string orderByString) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Node), nameof(GetStlDataSet), - TranslateUtils.ObjectCollectionToString(channelIdList), startNum.ToString(), totalNum.ToString(), whereString, orderByString); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.ChannelDao.GetStlDataSet(channelIdList, startNum, totalNum, whereString, orderByString); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static int GetIdByIndexName(int siteId, string channelIndex) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Node), nameof(GetIdByIndexName), - siteId.ToString(), channelIndex); - var retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval != -1) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval == -1) - { - retval = DataProvider.ChannelDao.GetIdByIndexName(siteId, channelIndex); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static int GetIdByParentIdAndTaxis(int parentId, int taxis, bool isNextChannel) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Node), nameof(GetIdByParentIdAndTaxis), - parentId.ToString(), taxis.ToString(), isNextChannel.ToString()); - var retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval != -1) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval == -1) - { - retval = DataProvider.ChannelDao.GetIdByParentIdAndTaxis(parentId, taxis, isNextChannel); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static int GetIdByParentIdAndChannelName(int siteId, int parentId, string nodeName, bool recursive) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Node), - nameof(GetIdByParentIdAndChannelName), siteId.ToString(), - parentId.ToString(), nodeName, recursive.ToString()); - var retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval != -1) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval == -1) - { - retval = DataProvider.ChannelDao.GetIdByParentIdAndChannelName(siteId, - parentId, nodeName, recursive); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static string GetWhereString(int siteId, string groupContent, string groupContentNot, bool isImageExists, bool isImage, string where) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Node), nameof(GetWhereString), - siteId.ToString(), groupContent, groupContentNot, isImageExists.ToString(), - isImage.ToString(), where); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.ChannelDao.GetWhereString(siteId, groupContent, groupContentNot, - isImageExists, isImage, where); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static List GetIdListByTotalNum(List channelIdList, int totalNum, string orderByString, string whereString) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Node), nameof(GetIdListByTotalNum), - TranslateUtils.ObjectCollectionToString(channelIdList), totalNum.ToString(), orderByString, whereString); - var retval = StlCacheUtils.GetCache>(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache>(cacheKey); - if (retval == null) - { - retval = DataProvider.ChannelDao.GetIdListByTotalNum(channelIdList, totalNum, orderByString, whereString); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static ChannelInfo GetChannelInfoByLastAddDate(int channelId) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Node), nameof(GetChannelInfoByLastAddDate), - channelId.ToString()); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.ChannelDao.GetChannelInfoByLastAddDate(channelId); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static ChannelInfo GetChannelInfoByTaxis(int channelId) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Node), nameof(GetChannelInfoByTaxis), - channelId.ToString()); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.ChannelDao.GetChannelInfoByTaxis(channelId); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - } -} diff --git a/SiteServer.CMS/StlParser/Cache/PublishmentSystem.cs b/SiteServer.CMS/StlParser/Cache/PublishmentSystem.cs deleted file mode 100644 index 6279d373c..000000000 --- a/SiteServer.CMS/StlParser/Cache/PublishmentSystem.cs +++ /dev/null @@ -1,53 +0,0 @@ -using SiteServer.CMS.Core; - -namespace SiteServer.CMS.StlParser.Cache -{ - public class Site - { - private static readonly object LockObject = new object(); - - public static int GetSiteIdByIsRoot() - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Site), - nameof(GetSiteIdByIsRoot)); - var retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval != -1) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval == -1) - { - retval = DataProvider.SiteDao.GetIdByIsRoot(); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static int GetSiteIdBySiteDir(string siteDir) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Site), - nameof(GetSiteIdBySiteDir), siteDir); - var retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval != -1) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetIntCache(cacheKey); - if (retval == -1) - { - retval = - DataProvider.SiteDao.GetIdBySiteDir( - siteDir); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - - } -} diff --git a/SiteServer.CMS/StlParser/Cache/StlCacheUtils.cs b/SiteServer.CMS/StlParser/Cache/StlCacheUtils.cs deleted file mode 100644 index ccba252db..000000000 --- a/SiteServer.CMS/StlParser/Cache/StlCacheUtils.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using SiteServer.Utils; - -namespace SiteServer.CMS.StlParser.Cache -{ - public class StlCacheUtils - { - private StlCacheUtils() - { - } - - public static string GetCacheKey(string nameofClass, string nameofMethod, params string[] values) - { - var key = $"SiteServer.CMS.StlParser.Cache.{nameofClass}.{nameofMethod}"; - if (values == null || values.Length <= 0) return key; - foreach (var t in values) - { - key += "." + t; - } - return key; - } - - public static T GetCache(string cacheKey) where T : class - { - return CacheUtils.Get(cacheKey); - } - - public static int GetIntCache(string cacheKey) - { - return CacheUtils.GetInt(cacheKey, -1); - } - - public static DateTime GetDateTimeCache(string cacheKey) - { - return CacheUtils.GetDateTime(cacheKey, DateTime.MinValue); - } - - public static void SetCache(string cacheKey, object value) - { - CacheUtils.InsertMinutes(cacheKey, value, 2); - } - - public static void ClearCache(string nameofClass) - { - CacheUtils.RemoveByStartString(GetCacheKey(nameofClass, string.Empty)); - } - } -} diff --git a/SiteServer.CMS/StlParser/Cache/TableStructure.cs b/SiteServer.CMS/StlParser/Cache/TableStructure.cs deleted file mode 100644 index 8423c9503..000000000 --- a/SiteServer.CMS/StlParser/Cache/TableStructure.cs +++ /dev/null @@ -1,32 +0,0 @@ -using SiteServer.CMS.Core; - -namespace SiteServer.CMS.StlParser.Cache -{ - public class TableStructure - { - private static readonly object LockObject = new object(); - - public static string GetSelectSqlStringByQueryString(string connectionString, string queryString, int startNum, - int totalNum, string orderByString) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(TableStructure), - nameof(GetSelectSqlStringByQueryString), connectionString, queryString, startNum.ToString(), - totalNum.ToString(), orderByString); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.DatabaseDao.GetSelectSqlStringByQueryString(connectionString, - queryString, startNum, totalNum, orderByString); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - } -} diff --git a/SiteServer.CMS/StlParser/Cache/Tag.cs b/SiteServer.CMS/StlParser/Cache/Tag.cs deleted file mode 100644 index 15a3ab013..000000000 --- a/SiteServer.CMS/StlParser/Cache/Tag.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Specialized; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils; - -namespace SiteServer.CMS.StlParser.Cache -{ - public class Tag - { - private static readonly object LockObject = new object(); - - public static List GetContentIdListByTagCollection(StringCollection tagCollection, int siteId) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Tag), - nameof(GetContentIdListByTagCollection), TranslateUtils.ObjectCollectionToString(tagCollection), - siteId.ToString()); - var retval = StlCacheUtils.GetCache>(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache>(cacheKey); - if (retval == null) - { - retval = DataProvider.TagDao.GetContentIdListByTagCollection(tagCollection, siteId); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - - public static List GetTagInfoList(int siteId, int contentId, bool isOrderByCount, int totalNum) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(Tag), - nameof(GetTagInfoList), siteId.ToString(), contentId.ToString(), isOrderByCount.ToString(), totalNum.ToString()); - var retval = StlCacheUtils.GetCache>(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache>(cacheKey); - if (retval == null) - { - retval = DataProvider.TagDao.GetTagInfoList(siteId, contentId, isOrderByCount, totalNum); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - } -} diff --git a/SiteServer.CMS/StlParser/Cache/User.cs b/SiteServer.CMS/StlParser/Cache/User.cs deleted file mode 100644 index 0729b1a84..000000000 --- a/SiteServer.CMS/StlParser/Cache/User.cs +++ /dev/null @@ -1,28 +0,0 @@ -using SiteServer.CMS.Core; - -namespace SiteServer.CMS.StlParser.Cache -{ - public class User - { - private static readonly object LockObject = new object(); - - public static string GetDisplayName(string userName) - { - var cacheKey = StlCacheUtils.GetCacheKey(nameof(User), nameof(GetDisplayName), userName); - var retval = StlCacheUtils.GetCache(cacheKey); - if (retval != null) return retval; - - lock (LockObject) - { - retval = StlCacheUtils.GetCache(cacheKey); - if (retval == null) - { - retval = DataProvider.UserDao.GetDisplayName(userName); - StlCacheUtils.SetCache(cacheKey, retval); - } - } - - return retval; - } - } -} diff --git a/SiteServer.CMS/StlParser/FileSystemObjectAsync.cs b/SiteServer.CMS/StlParser/FileSystemObjectAsync.cs deleted file mode 100644 index ba493b026..000000000 --- a/SiteServer.CMS/StlParser/FileSystemObjectAsync.cs +++ /dev/null @@ -1,469 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Threading.Tasks; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Create; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.StlElement; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.StlParser -{ - public class FileSystemObjectAsync - { - //public FileSystemObject(int siteId) - //{ - // SiteInfo = SiteManager.GetSiteInfo(siteId); - // if (SiteInfo == null) - // { - // throw new ArgumentException(siteId + " 不是正确的发布系统ID!"); - // } - // SiteId = siteInfo.Id; - // SiteDir = SiteInfo.SiteDir; - // SitePath = PathUtils.Combine(WebConfigUtils.PhysicalApplicationPath, SiteInfo.SiteDir); - // IsRoot = SiteInfo.IsRoot; - // DirectoryUtils.CreateDirectoryIfNotExists(SitePath); - //} - - public static async Task ExecuteAsync(int siteId, ECreateType createType, int channelId, int contentId, int templateId) - { - if (createType == ECreateType.Channel) - { - await CreateChannelAsync(siteId, channelId); - } - else if (createType == ECreateType.Content) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - await CreateContentAsync(siteInfo, tableName, channelId, contentId); - } - else if (createType == ECreateType.AllContent) - { - await CreateContentsAsync(siteId, channelId); - } - else if (createType == ECreateType.File) - { - await CreateFileAsync(siteId, templateId); - } - } - - private static async Task CreateContentsAsync(int siteId, int channelId) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - var orderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByTaxisDesc); - var contentIdList = Content.GetContentIdListChecked(tableName, channelId, orderByString); - - foreach (var contentId in contentIdList) - { - try - { - await CreateContentAsync(siteInfo, tableName, channelId, contentId); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(ex, "CreateContent"); - } - } - } - - private static async Task CreateChannelAsync(int siteId, int channelId) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - if (nodeInfo == null) return; - - if (!string.IsNullOrEmpty(nodeInfo.LinkUrl)) - { - return; - } - if (!ELinkTypeUtils.IsCreatable(nodeInfo)) - { - return; - } - - var templateInfo = channelId == siteId - ? TemplateManager.GetIndexPageTemplateInfo(siteId) - : TemplateManager.GetChannelTemplateInfo(siteId, channelId); - var filePath = PathUtility.GetChannelPageFilePath(siteInfo, channelId, 0); - var pageInfo = new PageInfo(channelId, 0, siteInfo, templateInfo, new Dictionary()); - var contextInfo = new ContextInfo(pageInfo) - { - ContextType = EContextType.Channel - }; - var contentBuilder = new StringBuilder(TemplateManager.GetTemplateContent(siteInfo, templateInfo)); - - var stlLabelList = StlParserUtility.GetStlLabelList(contentBuilder.ToString()); - var stlPageContentElement = string.Empty; - foreach (var label in stlLabelList) - { - if (!StlParserUtility.IsStlChannelElement(label, ChannelAttribute.PageContent)) continue; - stlPageContentElement = label; - break; - } - - //如果标签中存在 - if (!string.IsNullOrEmpty(stlPageContentElement))//内容存在 - { - var innerBuilder = new StringBuilder(stlPageContentElement); - StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); - var contentAttributeHtml = innerBuilder.ToString(); - var pageCount = StringUtils.GetCount(ContentUtility.PagePlaceHolder, contentAttributeHtml) + 1;//一共需要的页数 - - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, filePath, false); - - for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) - { - var thePageInfo = pageInfo.Clone(); - var index = contentAttributeHtml.IndexOf(ContentUtility.PagePlaceHolder, StringComparison.Ordinal); - var length = index == -1 ? contentAttributeHtml.Length : index; - var pagedContentAttributeHtml = contentAttributeHtml.Substring(0, length); - var pagedBuilder = new StringBuilder(contentBuilder.ToString().Replace(stlPageContentElement, pagedContentAttributeHtml)); - StlParserManager.ReplacePageElementsInChannelPage(pagedBuilder, thePageInfo, stlLabelList, thePageInfo.PageChannelId, currentPageIndex, pageCount, 0); - - filePath = PathUtility.GetChannelPageFilePath(siteInfo, thePageInfo.PageChannelId, currentPageIndex); - - await GenerateFileAsync(filePath, pageInfo.TemplateInfo.Charset, pagedBuilder); - - if (index != -1) - { - contentAttributeHtml = contentAttributeHtml.Substring(length + ContentUtility.PagePlaceHolder.Length); - } - } - } - //如果标签中存在 - else if (StlParserUtility.IsStlElementExists(StlPageContents.ElementName, stlLabelList)) - { - var stlElement = StlParserUtility.GetStlElement(StlPageContents.ElementName, stlLabelList); - var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); - - var pageContentsElementParser = new StlPageContents(stlElement, pageInfo, contextInfo, false); - int totalNum; - var pageCount = pageContentsElementParser.GetPageCount(out totalNum); - - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, filePath, false); - - for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) - { - var thePageInfo = pageInfo.Clone(); - var pageHtml = pageContentsElementParser.Parse(totalNum, currentPageIndex, pageCount, true); - var pagedBuilder = - new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); - - StlParserManager.ReplacePageElementsInChannelPage(pagedBuilder, thePageInfo, stlLabelList, - thePageInfo.PageChannelId, currentPageIndex, pageCount, totalNum); - - filePath = PathUtility.GetChannelPageFilePath(siteInfo, thePageInfo.PageChannelId, - currentPageIndex); - thePageInfo.AddLastPageScript(pageInfo); - - await GenerateFileAsync(filePath, pageInfo.TemplateInfo.Charset, pagedBuilder); - - thePageInfo.ClearLastPageScript(pageInfo); - pageInfo.ClearLastPageScript(); - } - } - //如果标签中存在 - else if (StlParserUtility.IsStlElementExists(StlPageChannels.ElementName, stlLabelList)) - { - var stlElement = StlParserUtility.GetStlElement(StlPageChannels.ElementName, stlLabelList); - var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); - - var pageChannelsElementParser = new StlPageChannels(stlElement, pageInfo, contextInfo, false); - int totalNum; - var pageCount = pageChannelsElementParser.GetPageCount(out totalNum); - - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, filePath, false); - - for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) - { - var thePageInfo = pageInfo.Clone(); - var pageHtml = pageChannelsElementParser.Parse(currentPageIndex, pageCount); - var pagedBuilder = new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); - - StlParserManager.ReplacePageElementsInChannelPage(pagedBuilder, thePageInfo, stlLabelList, thePageInfo.PageChannelId, currentPageIndex, pageCount, totalNum); - - filePath = PathUtility.GetChannelPageFilePath(siteInfo, thePageInfo.PageChannelId, currentPageIndex); - await GenerateFileAsync(filePath, pageInfo.TemplateInfo.Charset, pagedBuilder); - } - } - //如果标签中存在 - else if (StlParserUtility.IsStlElementExists(StlPageSqlContents.ElementName, stlLabelList)) - { - var stlElement = StlParserUtility.GetStlElement(StlPageSqlContents.ElementName, stlLabelList); - var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); - - var pageSqlContentsElementParser = new StlPageSqlContents(stlElement, pageInfo, contextInfo, false); - int totalNum; - var pageCount = pageSqlContentsElementParser.GetPageCount(out totalNum); - - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, filePath, false); - - for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) - { - var thePageInfo = pageInfo.Clone(); - var pageHtml = pageSqlContentsElementParser.Parse(currentPageIndex, pageCount); - var pagedBuilder = new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); - - StlParserManager.ReplacePageElementsInChannelPage(pagedBuilder, thePageInfo, stlLabelList, thePageInfo.PageChannelId, currentPageIndex, pageCount, totalNum); - - filePath = PathUtility.GetChannelPageFilePath(siteInfo, thePageInfo.PageChannelId, currentPageIndex); - await GenerateFileAsync(filePath, pageInfo.TemplateInfo.Charset, pagedBuilder); - } - } - //如果标签中存在 - //else if (StlParserUtility.IsStlElementExists(StlPageInputContents.ElementName, stlLabelList)) - //{ - // var stlElement = StlParserUtility.GetStlElement(StlPageInputContents.ElementName, stlLabelList); - // var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); - - // var pageInputContentsElementParser = new StlPageInputContents(stlElement, pageInfo, contextInfo, true); - // int totalNum; - // var pageCount = pageInputContentsElementParser.GetPageCount(out totalNum); - - // Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, filePath, false); - - // for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) - // { - // var thePageInfo = new PageInfo(pageInfo.PageChannelId, pageInfo.PageContentId, pageInfo.SiteInfo, pageInfo.TemplateInfo, null); - // var pageHtml = pageInputContentsElementParser.Parse(currentPageIndex, pageCount); - // var pagedBuilder = new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); - - // StlParserManager.ReplacePageElementsInChannelPage(pagedBuilder, thePageInfo, stlLabelList, thePageInfo.PageChannelId, currentPageIndex, pageCount, totalNum); - - // filePath = PathUtility.GetChannelPageFilePath(siteInfo, thePageInfo.PageChannelId, currentPageIndex); - // GenerateFile(filePath, pageInfo.TemplateInfo.Charset, pagedBuilder); - // } - //} - else - { - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, filePath, false); - await GenerateFileAsync(filePath, pageInfo.TemplateInfo.Charset, contentBuilder); - } - } - - private static async Task CreateContentAsync(SiteInfo siteInfo, string tableName, int channelId, int contentId) - { - var contentInfo = Content.GetContentInfo(tableName, contentId); - - if (contentInfo == null) - { - return; - } - if (!contentInfo.IsChecked) - { - DeleteManager.DeleteContent(siteInfo, channelId, contentId); - return; - } - //引用链接,不需要生成内容页;引用内容,需要生成内容页; - if (contentInfo.ReferenceId > 0 && ETranslateContentTypeUtils.GetEnumType(contentInfo.GetString(ContentAttribute.TranslateContentType)) != ETranslateContentType.ReferenceContent) - { - return; - } - if (!string.IsNullOrEmpty(contentInfo.GetString(ContentAttribute.LinkUrl))) - { - return; - } - if (siteInfo.Additional.IsCreateStaticContentByAddDate && contentInfo.AddDate < siteInfo.Additional.CreateStaticContentAddDate) - { - return; - } - - var templateInfo = TemplateManager.GetContentTemplateInfo(siteInfo.Id, channelId); - var pageInfo = new PageInfo(channelId, contentId, siteInfo, templateInfo, new Dictionary()); - var contextInfo = new ContextInfo(pageInfo) - { - ContextType = EContextType.Content, - ContentInfo = contentInfo - }; - var filePath = PathUtility.GetContentPageFilePath(siteInfo, pageInfo.PageChannelId, contentInfo, 0); - var contentBuilder = new StringBuilder(TemplateManager.GetTemplateContent(siteInfo, templateInfo)); - - var stlLabelList = StlParserUtility.GetStlLabelList(contentBuilder.ToString()); - - //如果标签中存在 - if (StlParserUtility.IsStlContentElementWithTypePageContent(stlLabelList))//内容存在 - { - var stlElement = StlParserUtility.GetStlContentElementWithTypePageContent(stlLabelList); - var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); - contentBuilder.Replace(stlElement, stlElementTranslated); - - var innerBuilder = new StringBuilder(stlElement); - StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); - var pageContentHtml = innerBuilder.ToString(); - var pageCount = StringUtils.GetCount(ContentUtility.PagePlaceHolder, pageContentHtml) + 1;//一共需要的页数 - - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, filePath, false); - - for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) - { - var thePageInfo = pageInfo.Clone(); - - var index = pageContentHtml.IndexOf(ContentUtility.PagePlaceHolder, StringComparison.Ordinal); - var length = index == -1 ? pageContentHtml.Length : index; - - var pageHtml = pageContentHtml.Substring(0, length); - var pagedBuilder = new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); - StlParserManager.ReplacePageElementsInContentPage(pagedBuilder, thePageInfo, stlLabelList, channelId, contentId, currentPageIndex, pageCount); - - filePath = PathUtility.GetContentPageFilePath(siteInfo, thePageInfo.PageChannelId, contentInfo, currentPageIndex); - await GenerateFileAsync(filePath, pageInfo.TemplateInfo.Charset, pagedBuilder); - - if (index != -1) - { - pageContentHtml = pageContentHtml.Substring(length + ContentUtility.PagePlaceHolder.Length); - } - } - } - //如果标签中存在 - else if (StlParserUtility.IsStlElementExists(StlPageContents.ElementName, stlLabelList)) - { - var stlElement = StlParserUtility.GetStlElement(StlPageContents.ElementName, stlLabelList); - var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); - - var pageContentsElementParser = new StlPageContents(stlElement, pageInfo, contextInfo, false); - int totalNum; - var pageCount = pageContentsElementParser.GetPageCount(out totalNum); - - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, filePath, false); - - for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) - { - var thePageInfo = pageInfo.Clone(); - var pageHtml = pageContentsElementParser.Parse(totalNum, currentPageIndex, pageCount, true); - var pagedBuilder = new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); - - StlParserManager.ReplacePageElementsInContentPage(pagedBuilder, thePageInfo, stlLabelList, channelId, contentId, currentPageIndex, pageCount); - - filePath = PathUtility.GetContentPageFilePath(siteInfo, thePageInfo.PageChannelId, contentInfo, currentPageIndex); - await GenerateFileAsync(filePath, pageInfo.TemplateInfo.Charset, pagedBuilder); - } - } - //如果标签中存在 - else if (StlParserUtility.IsStlElementExists(StlPageChannels.ElementName, stlLabelList)) - { - var stlElement = StlParserUtility.GetStlElement(StlPageChannels.ElementName, stlLabelList); - var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); - - var pageChannelsElementParser = new StlPageChannels(stlElement, pageInfo, contextInfo, false); - int totalNum; - var pageCount = pageChannelsElementParser.GetPageCount(out totalNum); - - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, filePath, false); - - for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) - { - var thePageInfo = pageInfo.Clone(); - var pageHtml = pageChannelsElementParser.Parse(currentPageIndex, pageCount); - var pagedBuilder = new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); - - StlParserManager.ReplacePageElementsInContentPage(pagedBuilder, thePageInfo, stlLabelList, channelId, contentId, currentPageIndex, pageCount); - - filePath = PathUtility.GetContentPageFilePath(siteInfo, thePageInfo.PageChannelId, contentInfo, currentPageIndex); - await GenerateFileAsync(filePath, pageInfo.TemplateInfo.Charset, pagedBuilder); - } - } - //如果标签中存在 - else if (StlParserUtility.IsStlElementExists(StlPageSqlContents.ElementName, stlLabelList)) - { - var stlElement = StlParserUtility.GetStlElement(StlPageSqlContents.ElementName, stlLabelList); - var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); - - var pageSqlContentsElementParser = new StlPageSqlContents(stlElement, pageInfo, contextInfo, false); - int totalNum; - var pageCount = pageSqlContentsElementParser.GetPageCount(out totalNum); - - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, filePath, false); - - for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) - { - var thePageInfo = pageInfo.Clone(); - var pageHtml = pageSqlContentsElementParser.Parse(currentPageIndex, pageCount); - var pagedBuilder = new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); - - StlParserManager.ReplacePageElementsInContentPage(pagedBuilder, thePageInfo, stlLabelList, channelId, contentId, currentPageIndex, pageCount); - - filePath = PathUtility.GetContentPageFilePath(siteInfo, thePageInfo.PageChannelId, contentInfo, currentPageIndex); - await GenerateFileAsync(filePath, pageInfo.TemplateInfo.Charset, pagedBuilder); - } - } - else//无翻页 - { - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, filePath, false); - await GenerateFileAsync(filePath, pageInfo.TemplateInfo.Charset, contentBuilder); - } - } - - private static async Task CreateFileAsync(int siteId, int templateId) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - var templateInfo = TemplateManager.GetTemplateInfo(siteId, templateId); - if (templateInfo == null || templateInfo.TemplateType != TemplateType.FileTemplate) - { - return; - } - var pageInfo = new PageInfo(siteId, 0, siteInfo, templateInfo, new Dictionary()); - var contextInfo = new ContextInfo(pageInfo); - var filePath = PathUtility.MapPath(siteInfo, templateInfo.CreatedFileFullName); - - //if (siteInfo.Additional.VisualType == EVisualType.Dynamic) - //{ - // string pageUrl = PageUtility.GetFileUrl(siteInfo, templateID, EVisualType.Dynamic); - // string content = StringUtility.GetRedirectPageHtml(pageUrl); - // this.GenerateFile(filePath, pageInfo.TemplateInfo.Charset, content); - // return; - //} - - var contentBuilder = new StringBuilder(TemplateManager.GetTemplateContent(siteInfo, templateInfo)); - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, filePath, false); - await GenerateFileAsync(filePath, pageInfo.TemplateInfo.Charset, contentBuilder); - } - - //private string CreateIncludeFile(string virtualUrl, bool isCreateIfExists) - //{ - // var templateInfo = new TemplateInfo(0, SiteId, string.Empty, TemplateType.FileTemplate, string.Empty, string.Empty, string.Empty, ECharsetUtils.GetEnumType(SiteInfo.Additional.Charset), false); - // var pageInfo = new PageInfo(SiteId, 0, SiteInfo, templateInfo, null); - // var contextInfo = new ContextInfo(pageInfo); - - // var parsedVirtualUrl = virtualUrl.Substring(0, virtualUrl.LastIndexOf('.')) + "_parsed" + virtualUrl.Substring(virtualUrl.LastIndexOf('.')); - // var filePath = PathUtility.MapPath(SiteInfo, parsedVirtualUrl); - // if (!isCreateIfExists && FileUtils.IsFileExists(filePath)) return parsedVirtualUrl; - - // var contentBuilder = new StringBuilder(StlCacheManager.FileContent.GetIncludeContent(SiteInfo, virtualUrl, pageInfo.TemplateInfo.Charset)); - // StlParserManager.ParseTemplateContent(contentBuilder, pageInfo, contextInfo); - // var pageAfterBodyScripts = StlParserManager.GetPageInfoScript(pageInfo, true); - // var pageBeforeBodyScripts = StlParserManager.GetPageInfoScript(pageInfo, false); - // contentBuilder.Insert(0, pageBeforeBodyScripts); - // contentBuilder.Append(pageAfterBodyScripts); - // GenerateFile(filePath, pageInfo.TemplateInfo.Charset, contentBuilder); - // return parsedVirtualUrl; - //} - - /// - /// 在操作系统中创建文件,如果文件存在,重新创建此文件 - /// - private static async Task GenerateFileAsync(string filePath, ECharset charset, StringBuilder contentBuilder) - { - if (string.IsNullOrEmpty(filePath)) return; - - try - { - await FileUtils.WriteTextAsync(filePath, ECharsetUtils.GetEncoding(charset), contentBuilder.ToString()); - } - catch - { - FileUtils.RemoveReadOnlyAndHiddenIfExists(filePath); - await FileUtils.WriteTextAsync(filePath, ECharsetUtils.GetEncoding(charset), contentBuilder.ToString()); - } - } - } -} \ No newline at end of file diff --git a/SiteServer.CMS/StlParser/Model/Attr.cs b/SiteServer.CMS/StlParser/Model/Attr.cs deleted file mode 100644 index 8d5fc98d5..000000000 --- a/SiteServer.CMS/StlParser/Model/Attr.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace SiteServer.CMS.StlParser.Model -{ - public class Attr - { - public Attr(string name, string description) - { - Name = name; - Type = AttrType.String; - Description = description; - } - - public Attr(string name, string description, AttrType type) - { - Name = name; - Type = type; - Description = description; - } - - public Attr(string name, string description, AttrType type, List enums) - { - Name = name; - Type = type; - Description = description; - _enums = enums; - } - - public string Name { get; } - public AttrType Type { get; } - public string Description { get; } - - private readonly List _enums; - - public List GetEnums(Type elementType, int siteId) - { - return _enums ?? AttrUtils.GetEnums(elementType, Name, siteId); - } - } -} diff --git a/SiteServer.CMS/StlParser/Model/AttrEnum.cs b/SiteServer.CMS/StlParser/Model/AttrEnum.cs deleted file mode 100644 index fb7bc2cb7..000000000 --- a/SiteServer.CMS/StlParser/Model/AttrEnum.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using System.Collections.Generic; - -namespace SiteServer.CMS.StlParser.Model -{ - public class AttrEnum - { - public AttrEnum(string name, string description) - { - Name = name; - Description = description; - } - - public string Name { get; } - public string Description { get; } - } -} diff --git a/SiteServer.CMS/StlParser/Model/AttrType.cs b/SiteServer.CMS/StlParser/Model/AttrType.cs deleted file mode 100644 index 02db3ed53..000000000 --- a/SiteServer.CMS/StlParser/Model/AttrType.cs +++ /dev/null @@ -1,95 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace SiteServer.CMS.StlParser.Model -{ - public class AttrType : IEquatable, IComparable - { - public static readonly AttrType Boolean = new AttrType(nameof(Boolean)); - public static readonly AttrType DateTime = new AttrType(nameof(DateTime)); - public static readonly AttrType Decimal = new AttrType(nameof(Decimal)); - public static readonly AttrType Integer = new AttrType(nameof(Integer)); - public static readonly AttrType Enum = new AttrType(nameof(Enum)); - public static readonly AttrType String = new AttrType(nameof(String)); - - private AttrType(string value) - { - if (string.IsNullOrEmpty(value)) - { - throw new ArgumentNullException(nameof(value)); - } - - Value = value; - } - - public string Value { get; } - - public override bool Equals(object obj) - { - return Equals(obj as AttrType); - } - - public static bool operator ==(AttrType a, AttrType b) - { - if (ReferenceEquals(a, b)) - { - return true; - } - - if ((object)a == null || (object)b == null) - { - return false; - } - - return a.Equals(b); - } - - public static bool operator !=(AttrType a, AttrType b) - { - return !(a == b); - } - - public bool Equals(AttrType other) - { - if (other == null) - { - return false; - } - - if (ReferenceEquals(this, other)) - { - return true; - } - - return - Value.Equals(other.Value, StringComparison.OrdinalIgnoreCase); - } - - public int CompareTo(AttrType other) - { - - if (other == null) - { - return 1; - } - - if (ReferenceEquals(this, other)) - { - return 0; - } - - return StringComparer.OrdinalIgnoreCase.Compare(Value, other.Value); - } - - public override int GetHashCode() - { - return EqualityComparer.Default.GetHashCode(Value); - } - - public override string ToString() - { - return Value; - } - } -} diff --git a/SiteServer.CMS/StlParser/Model/AttrUtils.cs b/SiteServer.CMS/StlParser/Model/AttrUtils.cs deleted file mode 100644 index af2ebc731..000000000 --- a/SiteServer.CMS/StlParser/Model/AttrUtils.cs +++ /dev/null @@ -1,142 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Text; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Provider; -using SiteServer.CMS.StlParser.StlElement; -using SiteServer.Plugin; - -namespace SiteServer.CMS.StlParser.Model -{ - public static class AttrUtils - { - public static List GetEnums(Type elementType, string name, int siteId) - { - var enums = new List(); - if (name == "channelIndex") - { - var channelInfoList = ChannelManager.GetChannelInfoList(siteId); - foreach (var channelInfo in channelInfoList) - { - if (!string.IsNullOrEmpty(channelInfo.IndexName)) - { - enums.Add(new AttrEnum(channelInfo.IndexName, string.Empty)); - } - } - } - else if (name == "channelName") - { - var channelInfoList = ChannelManager.GetChannelInfoList(siteId); - foreach (var channelInfo in channelInfoList) - { - enums.Add(new AttrEnum(channelInfo.ChannelName, string.Empty)); - } - } - else if (name == "context") - { - enums = new List - { - new AttrEnum("site", "站点"), - new AttrEnum("channel", "栏目"), - new AttrEnum("content", "内容"), - new AttrEnum("sqlContent", "SQL") - }; - } - else if (name == "type") - { - if (elementType == typeof(StlAudio)) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - var tableName = ChannelManager.GetTableName(siteInfo, siteId); - var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(siteId, siteId); - var styleInfoList = TableStyleManager.GetTableStyleInfoList(tableName, relatedIdentities); - var editableStyleInfoList = ContentUtility.GetEditableTableStyleInfoList(styleInfoList); - - foreach (var styleInfo in editableStyleInfoList) - { - if (styleInfo.InputType == InputType.Text || styleInfo.InputType == InputType.Video || styleInfo.InputType == InputType.Image || styleInfo.InputType == InputType.File) - { - enums.Add(new AttrEnum(styleInfo.AttributeName, styleInfo.DisplayName)); - } - } - } - else if (elementType == typeof(StlChannel)) - { - var fields = typeof(ChannelAttribute).GetFields(BindingFlags.Static | BindingFlags.Public); - foreach (var field in fields) - { - - var stlAttribute = (StlFieldAttribute)field.GetCustomAttribute(typeof(StlFieldAttribute)); - var desc = string.Empty; - if (stlAttribute != null) - { - desc = stlAttribute.Description; - } - enums.Add(new AttrEnum(field.Name, desc)); - } - var styleInfoList = TableStyleManager.GetTableStyleInfoList(DataProvider.ChannelDao.TableName, RelatedIdentities.GetChannelRelatedIdentities(siteId, siteId)); - foreach (var styleInfo in styleInfoList) - { - enums.Add(new AttrEnum(styleInfo.AttributeName, styleInfo.DisplayName)); - } - } - } - - return enums; - } - - public static string GetAttrTypeText(AttrType attrType, List attrEnums) - { - if (attrType == AttrType.Boolean) - { - return "布尔值"; - } - if (attrType == AttrType.DateTime) - { - return "日期"; - } - if (attrType == AttrType.Decimal) - { - return "小数"; - } - if (attrType == AttrType.Integer) - { - return "整数"; - } - if (attrType == AttrType.Enum) - { - if (attrEnums != null && attrEnums.Count > 0) - { - var builder = new StringBuilder(); - foreach (var attrEnum in attrEnums) - { - builder.Append( - $@"
    - {attrEnum.Name} - {attrEnum.Description} -
    "); - } - return $@" -
    -
    枚举
    -
    - -
    -
    -
    -
    -
    - {builder} -
    -
    -"; - } - return "枚举"; - } - - return "字符串"; - } - } -} diff --git a/SiteServer.CMS/StlParser/Model/ContextInfo.cs b/SiteServer.CMS/StlParser/Model/ContextInfo.cs deleted file mode 100644 index 9ffec3648..000000000 --- a/SiteServer.CMS/StlParser/Model/ContextInfo.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System.Collections.Generic; -using System.Xml; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Cache; - -namespace SiteServer.CMS.StlParser.Model -{ - public class ContextInfo - { - private ContentInfo _contentInfo; - - public ContextInfo(PageInfo pageInfo) - { - SiteInfo = pageInfo.SiteInfo; - ChannelId = pageInfo.PageChannelId; - ContentId = pageInfo.PageContentId; - } - - //用于clone - private ContextInfo(ContextInfo contextInfo) - { - ContextType = contextInfo.ContextType; - SiteInfo = contextInfo.SiteInfo; - ChannelId = contextInfo.ChannelId; - ContentId = contextInfo.ContentId; - _contentInfo = contextInfo._contentInfo; - - IsInnerElement = contextInfo.IsInnerElement; - IsStlEntity = contextInfo.IsStlEntity; - PageItemIndex = contextInfo.PageItemIndex; - ItemContainer = contextInfo.ItemContainer; - ContainerClientId = contextInfo.ContainerClientId; - - StlElement = contextInfo.StlElement; - Attributes = contextInfo.Attributes; - InnerXml = contextInfo.InnerXml; - ChildNodes = contextInfo.ChildNodes; - } - - public ContextInfo Clone(string stlElement, Dictionary attributes, string innerXml, XmlNodeList childNodes) - { - var contextInfo = new ContextInfo(this) - { - StlElement = stlElement, - Attributes = attributes, - InnerXml = innerXml, - ChildNodes = childNodes - }; - return contextInfo; - } - - public ContextInfo Clone() - { - var contextInfo = new ContextInfo(this); - return contextInfo; - } - - public EContextType ContextType { get; set; } = EContextType.Undefined; - - public SiteInfo SiteInfo { get; set; } - - public int ChannelId { get; set; } - - public int ContentId { get; set; } - - public string StlElement { get; set; } - - public Dictionary Attributes { get; set; } - - public string InnerXml { get; set; } - - public XmlNodeList ChildNodes { get; set; } - - public ContentInfo ContentInfo - { - get - { - if (_contentInfo != null) return _contentInfo; - if (ContentId <= 0) return _contentInfo; - var nodeInfo = ChannelManager.GetChannelInfo(SiteInfo.Id, ChannelId); - var tableName = ChannelManager.GetTableName(SiteInfo, nodeInfo); - //_contentInfo = DataProvider.ContentDao.GetContentInfo(tableStyle, tableName, ContentId); - _contentInfo = Content.GetContentInfo(tableName, ContentId); - return _contentInfo; - } - set { _contentInfo = value; } - } - - public bool IsInnerElement { get; set; } - - public bool IsStlEntity { get; set; } - - public int PageItemIndex { get; set; } - - public DbItemContainer ItemContainer { get; set; } - - public string ContainerClientId { get; set; } - } -} diff --git a/SiteServer.CMS/StlParser/Model/EStlChannelOrder.cs b/SiteServer.CMS/StlParser/Model/EStlChannelOrder.cs deleted file mode 100644 index e8d5ad527..000000000 --- a/SiteServer.CMS/StlParser/Model/EStlChannelOrder.cs +++ /dev/null @@ -1,154 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.StlParser.Model -{ - public enum EStlChannelOrder - { - Default, //Ĭ򣬼Ŀе - Back, //Ĭ෴ - AddDate, //ʱ - AddDateBack, //ʱ෴ - Hits, // - Random //ʾ - } - - - public class EStlChannelOrderUtils - { - public static string GetValue(EStlChannelOrder type) - { - if (type == EStlChannelOrder.Default) - { - return "Default"; - } - else if (type == EStlChannelOrder.Back) - { - return "Back"; - } - else if (type == EStlChannelOrder.AddDate) - { - return "AddDate"; - } - else if (type == EStlChannelOrder.AddDateBack) - { - return "AddDateBack"; - } - else if (type == EStlChannelOrder.Hits) - { - return "Hits"; - } - else if (type == EStlChannelOrder.Random) - { - return "Random"; - } - else - { - throw new Exception(); - } - } - - public static string GetText(EStlChannelOrder type) - { - if (type == EStlChannelOrder.Default) - { - return "Ĭ򣬼Ŀе"; - } - else if (type == EStlChannelOrder.Back) - { - return "Ĭ෴"; - } - else if (type == EStlChannelOrder.AddDate) - { - return "ʱ"; - } - else if (type == EStlChannelOrder.AddDateBack) - { - return "ʱ෴"; - } - else if (type == EStlChannelOrder.Hits) - { - return ""; - } - else if (type == EStlChannelOrder.Random) - { - return "ʾ"; - } - else - { - throw new Exception(); - } - } - - public static EStlChannelOrder GetEnumType(string typeStr) - { - var retval = EStlChannelOrder.Default; - - if (Equals(EStlChannelOrder.Default, typeStr)) - { - retval = EStlChannelOrder.Default; - } - else if (Equals(EStlChannelOrder.Back, typeStr)) - { - retval = EStlChannelOrder.Back; - } - else if (Equals(EStlChannelOrder.AddDate, typeStr)) - { - retval = EStlChannelOrder.AddDate; - } - else if (Equals(EStlChannelOrder.AddDateBack, typeStr)) - { - retval = EStlChannelOrder.AddDateBack; - } - else if (Equals(EStlChannelOrder.Hits, typeStr)) - { - retval = EStlChannelOrder.Hits; - } - else if (Equals(EStlChannelOrder.Random, typeStr)) - { - retval = EStlChannelOrder.Random; - } - - return retval; - } - - public static bool Equals(EStlChannelOrder type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EStlChannelOrder type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(EStlChannelOrder type, bool selected) - { - var item = new ListItem(GetValue(type) + " (" + GetText(type) + ")", GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EStlChannelOrder.Default, false)); - listControl.Items.Add(GetListItem(EStlChannelOrder.Back, false)); - listControl.Items.Add(GetListItem(EStlChannelOrder.AddDate, false)); - listControl.Items.Add(GetListItem(EStlChannelOrder.AddDateBack, false)); - listControl.Items.Add(GetListItem(EStlChannelOrder.Hits, false)); - listControl.Items.Add(GetListItem(EStlChannelOrder.Random, false)); - } - } - - } -} diff --git a/SiteServer.CMS/StlParser/Model/EStlContentOrder.cs b/SiteServer.CMS/StlParser/Model/EStlContentOrder.cs deleted file mode 100644 index cb4b6b3c5..000000000 --- a/SiteServer.CMS/StlParser/Model/EStlContentOrder.cs +++ /dev/null @@ -1,266 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.CMS.StlParser.Model -{ - public enum EStlContentOrder - { - Default, //Ĭ򣬼ݹе - Back, //Ĭ෴ - AddDate, //ʱ - AddDateBack, //ʱ෴ - LastEditDate, //ʱ - LastEditDateBack, //ʱ෴ - Hits, // - HitsByDay, //յ - HitsByWeek, //ܵ - HitsByMonth, //µ - Stars, // - Digg, // - Comments, // - Random //ʾ - } - - - public class EStlContentOrderUtils - { - public static string GetValue(EStlContentOrder type) - { - if (type == EStlContentOrder.Default) - { - return "Default"; - } - else if (type == EStlContentOrder.Back) - { - return "Back"; - } - else if (type == EStlContentOrder.AddDate) - { - return "AddDate"; - } - else if (type == EStlContentOrder.AddDateBack) - { - return "AddDateBack"; - } - else if (type == EStlContentOrder.LastEditDate) - { - return "LastEditDate"; - } - else if (type == EStlContentOrder.LastEditDateBack) - { - return "LastEditDateBack"; - } - else if (type == EStlContentOrder.Hits) - { - return "Hits"; - } - else if (type == EStlContentOrder.HitsByDay) - { - return "HitsByDay"; - } - else if (type == EStlContentOrder.HitsByWeek) - { - return "HitsByWeek"; - } - else if (type == EStlContentOrder.HitsByMonth) - { - return "HitsByMonth"; - } - else if (type == EStlContentOrder.Stars) - { - return "Stars"; - } - else if (type == EStlContentOrder.Digg) - { - return "Digg"; - } - else if (type == EStlContentOrder.Comments) - { - return "Comments"; - } - else if (type == EStlContentOrder.Random) - { - return "Random"; - } - else - { - throw new Exception(); - } - } - - public static string GetText(EStlContentOrder type) - { - if (type == EStlContentOrder.Default) - { - return "Ĭ򣬼ݹе"; - } - else if (type == EStlContentOrder.Back) - { - return "Ĭ෴"; - } - else if (type == EStlContentOrder.AddDate) - { - return "ʱ"; - } - else if (type == EStlContentOrder.AddDateBack) - { - return "ʱ෴"; - } - else if (type == EStlContentOrder.LastEditDate) - { - return "ʱ"; - } - else if (type == EStlContentOrder.LastEditDateBack) - { - return "ʱ෴"; - } - else if (type == EStlContentOrder.Hits) - { - return ""; - } - else if (type == EStlContentOrder.HitsByDay) - { - return "յ"; - } - else if (type == EStlContentOrder.HitsByWeek) - { - return "ܵ"; - } - else if (type == EStlContentOrder.HitsByMonth) - { - return "µ"; - } - else if (type == EStlContentOrder.Stars) - { - return ""; - } - else if (type == EStlContentOrder.Digg) - { - return ""; - } - else if (type == EStlContentOrder.Comments) - { - return ""; - } - else if (type == EStlContentOrder.Random) - { - return "ʾ"; - } - else - { - throw new Exception(); - } - } - - public static EStlContentOrder GetEnumType(string typeStr) - { - var retval = EStlContentOrder.Default; - - if (Equals(EStlContentOrder.Default, typeStr)) - { - retval = EStlContentOrder.Default; - } - else if (Equals(EStlContentOrder.Back, typeStr)) - { - retval = EStlContentOrder.Back; - } - else if (Equals(EStlContentOrder.AddDate, typeStr)) - { - retval = EStlContentOrder.AddDate; - } - else if (Equals(EStlContentOrder.AddDateBack, typeStr)) - { - retval = EStlContentOrder.AddDateBack; - } - else if (Equals(EStlContentOrder.LastEditDate, typeStr)) - { - retval = EStlContentOrder.LastEditDate; - } - else if (Equals(EStlContentOrder.LastEditDateBack, typeStr)) - { - retval = EStlContentOrder.LastEditDateBack; - } - else if (Equals(EStlContentOrder.Hits, typeStr)) - { - retval = EStlContentOrder.Hits; - } - else if (Equals(EStlContentOrder.HitsByDay, typeStr)) - { - retval = EStlContentOrder.HitsByDay; - } - else if (Equals(EStlContentOrder.HitsByWeek, typeStr)) - { - retval = EStlContentOrder.HitsByWeek; - } - else if (Equals(EStlContentOrder.HitsByMonth, typeStr)) - { - retval = EStlContentOrder.HitsByMonth; - } - else if (Equals(EStlContentOrder.Stars, typeStr)) - { - retval = EStlContentOrder.Stars; - } - else if (Equals(EStlContentOrder.Digg, typeStr)) - { - retval = EStlContentOrder.Digg; - } - else if (Equals(EStlContentOrder.Comments, typeStr)) - { - retval = EStlContentOrder.Comments; - } - else if (Equals(EStlContentOrder.Random, typeStr)) - { - retval = EStlContentOrder.Random; - } - - return retval; - } - - public static bool Equals(EStlContentOrder type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EStlContentOrder type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(EStlContentOrder type, bool selected) - { - var item = new ListItem(GetValue(type) + " (" + GetText(type) + ")", GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EStlContentOrder.Default, false)); - listControl.Items.Add(GetListItem(EStlContentOrder.Back, false)); - listControl.Items.Add(GetListItem(EStlContentOrder.AddDate, false)); - listControl.Items.Add(GetListItem(EStlContentOrder.AddDateBack, false)); - listControl.Items.Add(GetListItem(EStlContentOrder.LastEditDate, false)); - listControl.Items.Add(GetListItem(EStlContentOrder.LastEditDateBack, false)); - listControl.Items.Add(GetListItem(EStlContentOrder.Hits, false)); - listControl.Items.Add(GetListItem(EStlContentOrder.HitsByDay, false)); - listControl.Items.Add(GetListItem(EStlContentOrder.HitsByWeek, false)); - listControl.Items.Add(GetListItem(EStlContentOrder.HitsByMonth, false)); - listControl.Items.Add(GetListItem(EStlContentOrder.Stars, false)); - listControl.Items.Add(GetListItem(EStlContentOrder.Digg, false)); - listControl.Items.Add(GetListItem(EStlContentOrder.Comments, false)); - listControl.Items.Add(GetListItem(EStlContentOrder.Random, false)); - } - } - - } -} diff --git a/SiteServer.CMS/StlParser/Model/StlClassAttribute.cs b/SiteServer.CMS/StlParser/Model/StlClassAttribute.cs deleted file mode 100644 index 8383f08e0..000000000 --- a/SiteServer.CMS/StlParser/Model/StlClassAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace SiteServer.CMS.StlParser.Model -{ - [AttributeUsage(AttributeTargets.Class)] - public class StlClassAttribute : Attribute - { - public string Usage { get; set; } - public string Description { get; set; } - public bool Obsolete { get; set; } - } -} diff --git a/SiteServer.CMS/StlParser/Model/StlFieldAttribute.cs b/SiteServer.CMS/StlParser/Model/StlFieldAttribute.cs deleted file mode 100644 index 4afa5f4de..000000000 --- a/SiteServer.CMS/StlParser/Model/StlFieldAttribute.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; - -namespace SiteServer.CMS.StlParser.Model -{ - [AttributeUsage(AttributeTargets.Field)] - public class StlFieldAttribute : Attribute - { - public string Description { get; set; } - } -} diff --git a/SiteServer.CMS/StlParser/Parser.cs b/SiteServer.CMS/StlParser/Parser.cs deleted file mode 100644 index 6bb420b1e..000000000 --- a/SiteServer.CMS/StlParser/Parser.cs +++ /dev/null @@ -1,166 +0,0 @@ -using System; -using System.Text; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Plugin; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.StlParser -{ - public class Parser - { - private Parser() - { - } - - public static void Parse(SiteInfo siteInfo, PageInfo pageInfo, ContextInfo contextInfo, StringBuilder contentBuilder, string filePath, bool isDynamic) - { - foreach (var service in PluginManager.Services) - { - try - { - service.OnBeforeStlParse(new ParseEventArgs(pageInfo.SiteId, pageInfo.PageChannelId, pageInfo.PageContentId, pageInfo.TemplateInfo.TemplateType, pageInfo.TemplateInfo.Id, filePath, contentBuilder)); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(service.PluginId, ex, nameof(service.OnBeforeStlParse)); - } - } - - if (contentBuilder.Length > 0) - { - StlParserManager.ParseTemplateContent(contentBuilder, pageInfo, contextInfo); - } - - if (EFileSystemTypeUtils.IsHtml(PathUtils.GetExtension(filePath))) - { - if (isDynamic) - { - var pageUrl = PageUtils.AddProtocolToUrl(PageUtils.ParseNavigationUrl($"~/{PathUtils.GetPathDifference(WebConfigUtils.PhysicalApplicationPath, filePath)}")); - string templateString = $@" -"; - StringUtils.InsertAfter(new[] { "", "" }, contentBuilder, templateString); - } - - if (pageInfo.SiteInfo.Additional.IsCreateBrowserNoCache) - { - const string templateString = @" - -"; - StringUtils.InsertAfter(new[] { "", "" }, contentBuilder, templateString); - } - - if (pageInfo.SiteInfo.Additional.IsCreateIe8Compatible) - { - const string templateString = @" -"; - StringUtils.InsertAfter(new[] { "", "" }, contentBuilder, templateString); - } - - if (pageInfo.SiteInfo.Additional.IsCreateJsIgnoreError) - { - const string templateString = @" -"; - StringUtils.InsertAfter(new[] { "", "" }, contentBuilder, templateString); - } - - if (pageInfo.PageContentId > 0 && pageInfo.SiteInfo.Additional.IsCountHits && !pageInfo.BodyCodes.ContainsKey(PageInfo.Const.JsAdStlCountHits)) - { - if (!pageInfo.FootCodes.ContainsKey(PageInfo.Const.JsAdStlCountHits)) - { - pageInfo.FootCodes.Add(PageInfo.Const.JsAdStlCountHits, $@" -"); - } - } - - var isShowPageInfo = pageInfo.SiteInfo.Additional.IsCreateShowPageInfo; - - if (!pageInfo.IsLocal) - { - if (pageInfo.SiteInfo.Additional.IsCreateDoubleClick) - { - var fileTemplateId = 0; - if (pageInfo.TemplateInfo.TemplateType == TemplateType.FileTemplate) - { - fileTemplateId = pageInfo.TemplateInfo.Id; - } - - var apiUrl = pageInfo.ApiUrl; - var ajaxUrl = ApiRouteActionsTrigger.GetUrl(apiUrl, pageInfo.SiteId, contextInfo.ChannelId, - contextInfo.ContentId, fileTemplateId, true); - if (!pageInfo.FootCodes.ContainsKey("CreateDoubleClick")) - { - pageInfo.FootCodes.Add("CreateDoubleClick", $@" -"); - } - } - } - else - { - isShowPageInfo = true; - } - - if (isShowPageInfo) - { - contentBuilder.Append($@" -"); - } - - var headCodesHtml = pageInfo.HeadCodesHtml; - if (!string.IsNullOrEmpty(headCodesHtml)) - { - if (contentBuilder.ToString().IndexOf("", StringComparison.Ordinal) != -1 || contentBuilder.ToString().IndexOf("", StringComparison.Ordinal) != -1) - { - StringUtils.InsertBefore(new[] { "", "" }, contentBuilder, headCodesHtml); - } - else - { - contentBuilder.Insert(0, headCodesHtml); - } - } - - var bodyCodesHtml = pageInfo.BodyCodesHtml; - if (!string.IsNullOrEmpty(bodyCodesHtml)) - { - if (contentBuilder.ToString().IndexOf("", index, StringComparison.Ordinal); - contentBuilder.Insert(index + 1, StringUtils.Constants.ReturnAndNewline + bodyCodesHtml + StringUtils.Constants.ReturnAndNewline); - } - else - { - contentBuilder.Insert(0, bodyCodesHtml); - } - } - - var footCodesHtml = pageInfo.FootCodesHtml; - if (!string.IsNullOrEmpty(footCodesHtml)) - { - contentBuilder.Append(footCodesHtml + StringUtils.Constants.ReturnAndNewline); - } - } - - foreach (var service in PluginManager.Services) - { - try - { - service.OnAfterStlParse(new ParseEventArgs(pageInfo.SiteId, pageInfo.PageChannelId, pageInfo.PageContentId, pageInfo.TemplateInfo.TemplateType, pageInfo.TemplateInfo.Id, filePath, contentBuilder)); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(service.PluginId, ex, nameof(service.OnAfterStlParse)); - } - } - } - } -} diff --git a/SiteServer.CMS/StlParser/Parsers/StlElementParser.cs b/SiteServer.CMS/StlParser/Parsers/StlElementParser.cs deleted file mode 100644 index 8ad177faf..000000000 --- a/SiteServer.CMS/StlParser/Parsers/StlElementParser.cs +++ /dev/null @@ -1,255 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Xml; -using SiteServer.Utils; -using SiteServer.CMS.Plugin; -using SiteServer.CMS.Plugin.Model; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.StlElement; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.Parsers -{ - /// - /// Stl元素解析器 - /// - public class StlElementParser - { - private StlElementParser() - { - } - - /// - /// 将原始内容中的STL元素替换为实际内容 - /// - public static void ReplaceStlElements(StringBuilder parsedBuilder, PageInfo pageInfo, ContextInfo contextInfo) - { - var stlElements = StlParserUtility.GetStlElementList(parsedBuilder.ToString()); - foreach (var stlElement in stlElements) - { - try - { - var startIndex = parsedBuilder.ToString().IndexOf(stlElement, StringComparison.Ordinal); - if (startIndex == -1) continue; - - var parsedContent = ParseStlElement(stlElement, pageInfo, contextInfo); - parsedBuilder.Replace(stlElement, parsedContent, startIndex, stlElement.Length); - } - catch - { - // ignored - } - } - } - - private static readonly Dictionary> ElementsToParseDic = new Dictionary> - { - {StlA.ElementName.ToLower(), StlA.Parse}, - {StlAction.ElementName.ToLower(), StlAction.Parse}, - {StlAudio.ElementName.ToLower(), StlAudio.Parse}, - {StlChannel.ElementName.ToLower(), StlChannel.Parse}, - {StlChannels.ElementName.ToLower(), StlChannels.Parse}, - {StlCode.ElementName.ToLower(), StlCode.Parse}, - {StlContainer.ElementName.ToLower(), StlContainer.Parse}, - {StlContent.ElementName.ToLower(), StlContent.Parse}, - {StlContents.ElementName.ToLower(), StlContents.Parse}, - {StlCount.ElementName.ToLower(), StlCount.Parse}, - {StlDynamic.ElementName.ToLower(), StlDynamic.Parse}, - {StlEach.ElementName.ToLower(), StlEach.Parse}, - {StlFile.ElementName.ToLower(), StlFile.Parse}, - {StlFlash.ElementName.ToLower(), StlFlash.Parse}, - {StlFocusViewer.ElementName.ToLower(), StlFocusViewer.Parse}, - {StlIf.ElementName.ToLower(), StlIf.Parse}, - {StlImage.ElementName.ToLower(), StlImage.Parse}, - {StlInclude.ElementName.ToLower(), StlInclude.Parse}, - {StlLocation.ElementName.ToLower(), StlLocation.Parse}, - {StlMarquee.ElementName.ToLower(), StlMarquee.Parse}, - {StlNavigation.ElementName.ToLower(), StlNavigation.Parse}, - {StlPlayer.ElementName.ToLower(), StlPlayer.Parse}, - {StlPrinter.ElementName.ToLower(), StlPrinter.Parse}, - {StlRss.ElementName.ToLower(), StlRss.Parse}, - {StlSearch.ElementName.ToLower(), StlSearch.Parse}, - {StlSearch.ElementName2.ToLower(), StlSearch.Parse}, - {StlSelect.ElementName.ToLower(), StlSelect.Parse}, - {StlSite.ElementName.ToLower(), StlSite.Parse}, - {StlSites.ElementName.ToLower(), StlSites.Parse}, - {StlSqlContent.ElementName.ToLower(), StlSqlContent.Parse}, - {StlSqlContents.ElementName.ToLower(), StlSqlContents.Parse}, - {StlTabs.ElementName.ToLower(), StlTabs.Parse}, - {StlTags.ElementName.ToLower(), StlTags.Parse}, - {StlTree.ElementName.ToLower(), StlTree.Parse}, - {StlValue.ElementName.ToLower(), StlValue.Parse}, - {StlVideo.ElementName.ToLower(), StlVideo.Parse}, - {StlZoom.ElementName.ToLower(), StlZoom.Parse} - }; - - private static readonly Dictionary> ElementsToTranslateDic = new Dictionary> - { - {StlPageContents.ElementName.ToLower(), StlParserManager.StlEncrypt}, - {StlPageChannels.ElementName.ToLower(), StlParserManager.StlEncrypt}, - {StlPageSqlContents.ElementName.ToLower(), StlParserManager.StlEncrypt}, - //{StlPageInputContents.ElementName.ToLower(), StlParserManager.StlEncrypt}, - {StlPageItems.ElementName.ToLower(), StlParserManager.StlEncrypt} - }; - - internal static string ParseStlElement(string stlElement, PageInfo pageInfo, ContextInfo contextInfo) - { - string parsedContent = null; - //var parsedContent = StlCacheManager.ParsedContent.GetParsedContent(stlElement, pageInfo, contextInfo); - //if (parsedContent != null) return parsedContent; - - //if (stlElement.StartsWith(" func; - if (ElementsToTranslateDic.TryGetValue(elementName, out func)) - { - parsedContent = func(stlElement); - } - } - else if (ElementsToParseDic.ContainsKey(elementName)) - { - var isDynamic = false; - var attributes = new Dictionary(); - var innerXml = StringUtils.Trim(node.InnerXml); - var childNodes = node.ChildNodes; - - var ie = node.Attributes?.GetEnumerator(); - if (ie != null) - { - while (ie.MoveNext()) - { - var attr = (XmlAttribute) ie.Current; - - if (StringUtils.EqualsIgnoreCase(attr.Name, "isDynamic")) - { - isDynamic = TranslateUtils.ToBool(attr.Value, false); - } - else - { - var key = attr.Name; - if (!string.IsNullOrEmpty(key)) - { - var value = attr.Value; - if (string.IsNullOrEmpty(StringUtils.Trim(value))) - { - value = string.Empty; - } - attributes[key] = value; - } - } - } - } - - if (isDynamic) - { - parsedContent = StlDynamic.ParseDynamicElement(stlElement, pageInfo, contextInfo); - } - else - { - try - { - Func func; - if (ElementsToParseDic.TryGetValue(elementName, out func)) - { - parsedContent = func(pageInfo, - contextInfo.Clone(stlElement, attributes, innerXml, childNodes)); - } - } - catch (Exception ex) - { - parsedContent = StlParserUtility.GetStlErrorMessage(elementName, stlElement, ex); - } - } - } - else - { - var parsers = PluginStlParserContentManager.GetParses(); - if (parsers.ContainsKey(elementName)) - { - var isDynamic = false; - var attributes = new Dictionary(); - var innerXml = StringUtils.Trim(node.InnerXml); - - var ie = node.Attributes?.GetEnumerator(); - if (ie != null) - { - while (ie.MoveNext()) - { - var attr = (XmlAttribute)ie.Current; - - if (StringUtils.EqualsIgnoreCase(attr.Name, "isDynamic")) - { - isDynamic = TranslateUtils.ToBool(attr.Value, false); - } - else - { - var key = attr.Name; - if (!string.IsNullOrEmpty(key)) - { - var value = attr.Value; - if (string.IsNullOrEmpty(StringUtils.Trim(value))) - { - value = string.Empty; - } - attributes[key] = value; - } - } - } - } - - if (isDynamic) - { - parsedContent = StlDynamic.ParseDynamicElement(stlElement, pageInfo, contextInfo); - } - else - { - try - { - Func func; - if (parsers.TryGetValue(elementName, out func)) - { - var context = new PluginParseContext(attributes, innerXml, pageInfo, contextInfo); - parsedContent = func(context); - } - } - catch (Exception ex) - { - parsedContent = StlParserUtility.GetStlErrorMessage(elementName, stlElement, ex); - } - } - } - } - } - } - - if (parsedContent == null) - { - parsedContent = stlElement; - } - else - { - parsedContent = contextInfo.IsInnerElement ? parsedContent : StlParserUtility.GetBackHtml(parsedContent, pageInfo); - } - - //StlCacheManager.ParsedContent.SetParsedContent(stlElement, pageInfo, contextInfo, parsedContent); - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlA.cs b/SiteServer.CMS/StlParser/StlElement/StlA.cs deleted file mode 100644 index 74ff7a66d..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlA.cs +++ /dev/null @@ -1,227 +0,0 @@ -using System.Text; -using System.Web.UI.HtmlControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Parsers; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "获取链接", Description = "通过 stl:a 标签在模板中创建链接,系统将根据所处上下文计算链接地址")] - public static class StlA - { - public const string ElementName = "stl:a"; - - private static readonly Attr Id = new Attr("id", "唯一标识符"); - private static readonly Attr ChannelIndex = new Attr("channelIndex", "栏目索引", AttrType.Enum); - private static readonly Attr ChannelName = new Attr("channelName", "栏目名称", AttrType.Enum); - private static readonly Attr Parent = new Attr("parent", "显示父栏目", AttrType.Boolean); - private static readonly Attr UpLevel = new Attr("upLevel", "上级栏目的级别", AttrType.Integer); - private static readonly Attr TopLevel = new Attr("topLevel", "从首页向下的栏目级别", AttrType.Integer); - private static readonly Attr Context = new Attr("context", "所处上下文", AttrType.Enum); - private static readonly Attr Href = new Attr("href", "链接地址"); - private static readonly Attr Host = new Attr("host", "链接域名"); - private static readonly Attr QueryString = new Attr("queryString", "链接参数"); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var stlAnchor = new HtmlAnchor(); - var htmlId = string.Empty; - var channelIndex = string.Empty; - var channelName = string.Empty; - var upLevel = 0; - var topLevel = -1; - const bool removeTarget = false; - var href = string.Empty; - var queryString = string.Empty; - var host = string.Empty; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - if (StringUtils.EqualsIgnoreCase(name, Id.Name)) - { - htmlId = value; - } - else if (StringUtils.EqualsIgnoreCase(name, ChannelIndex.Name)) - { - channelIndex = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - if (!string.IsNullOrEmpty(channelIndex)) - { - contextInfo.ContextType = EContextType.Channel; - } - } - else if (StringUtils.EqualsIgnoreCase(name, ChannelName.Name)) - { - channelName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - if (!string.IsNullOrEmpty(channelName)) - { - contextInfo.ContextType = EContextType.Channel; - } - } - else if (StringUtils.EqualsIgnoreCase(name, Parent.Name)) - { - if (TranslateUtils.ToBool(value)) - { - upLevel = 1; - contextInfo.ContextType = EContextType.Channel; - } - } - else if (StringUtils.EqualsIgnoreCase(name, UpLevel.Name)) - { - upLevel = TranslateUtils.ToInt(value); - if (upLevel > 0) - { - contextInfo.ContextType = EContextType.Channel; - } - } - else if (StringUtils.EqualsIgnoreCase(name, TopLevel.Name)) - { - topLevel = TranslateUtils.ToInt(value); - if (topLevel >= 0) - { - contextInfo.ContextType = EContextType.Channel; - } - } - else if (StringUtils.EqualsIgnoreCase(name, Context.Name)) - { - contextInfo.ContextType = EContextTypeUtils.GetEnumType(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Href.Name)) - { - href = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, QueryString.Name)) - { - queryString = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, Host.Name)) - { - host = value; - } - else - { - ControlUtils.AddAttributeIfNotExists(stlAnchor, name, value); - } - } - - var parsedContent = ParseImpl(pageInfo, contextInfo, stlAnchor, htmlId, channelIndex, channelName, upLevel, topLevel, removeTarget, href, queryString, host); - - return parsedContent; - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, HtmlAnchor stlAnchor, string htmlId, string channelIndex, string channelName, int upLevel, int topLevel, bool removeTarget, string href, string queryString, string host) - { - if (!string.IsNullOrEmpty(htmlId) && !string.IsNullOrEmpty(contextInfo.ContainerClientId)) - { - htmlId = contextInfo.ContainerClientId + "_" + htmlId; - } - stlAnchor.ID = htmlId; - - var url = string.Empty; - var onclick = string.Empty; - if (!string.IsNullOrEmpty(href)) - { - url = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, href, pageInfo.IsLocal); - - var innerBuilder = new StringBuilder(contextInfo.InnerXml); - StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); - stlAnchor.InnerHtml = innerBuilder.ToString(); - } - else - { - if (contextInfo.ContextType == EContextType.Undefined) - { - contextInfo.ContextType = contextInfo.ContentId != 0 ? EContextType.Content : EContextType.Channel; - } - if (contextInfo.ContextType == EContextType.Content)//获取内容Url - { - if (contextInfo.ContentInfo != null) - { - url = PageUtility.GetContentUrl(pageInfo.SiteInfo, contextInfo.ContentInfo, pageInfo.IsLocal); - } - else - { - var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); - url = PageUtility.GetContentUrl(pageInfo.SiteInfo, nodeInfo, contextInfo.ContentId, pageInfo.IsLocal); - } - if (string.IsNullOrEmpty(contextInfo.InnerXml)) - { - var title = contextInfo.ContentInfo?.Title; - title = ContentUtility.FormatTitle(contextInfo.ContentInfo?.GetString("BackgroundContentAttribute.TitleFormatString"), title); - - if (pageInfo.SiteInfo.Additional.IsContentTitleBreakLine) - { - title = title.Replace(" ", string.Empty); - } - - stlAnchor.InnerHtml = title; - } - else - { - var innerBuilder = new StringBuilder(contextInfo.InnerXml); - StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); - stlAnchor.InnerHtml = innerBuilder.ToString(); - } - } - else if (contextInfo.ContextType == EContextType.Channel)//获取栏目Url - { - contextInfo.ChannelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); - contextInfo.ChannelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, contextInfo.ChannelId, channelIndex, channelName); - var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); - - url = PageUtility.GetChannelUrl(pageInfo.SiteInfo, channel, pageInfo.IsLocal); - if (contextInfo.InnerXml.Trim().Length == 0) - { - stlAnchor.InnerHtml = channel.ChannelName; - } - else - { - var innerBuilder = new StringBuilder(contextInfo.InnerXml); - StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); - stlAnchor.InnerHtml = innerBuilder.ToString(); - } - } - } - - if (url.Equals(PageUtils.UnclickedUrl)) - { - removeTarget = true; - } - else - { - if (!string.IsNullOrEmpty(host)) - { - url = PageUtils.AddProtocolToUrl(url, host); - } - if (!string.IsNullOrEmpty(queryString)) - { - url = PageUtils.AddQueryString(url, queryString); - } - } - - stlAnchor.HRef = url; - - if (!string.IsNullOrEmpty(onclick)) - { - stlAnchor.Attributes.Add("onclick", onclick); - } - - if (removeTarget) - { - stlAnchor.Target = string.Empty; - } - - // 如果是实体标签,则只返回url - if (contextInfo.IsStlEntity) - { - return stlAnchor.HRef; - } - else - { - return ControlUtils.GetControlRenderHtml(stlAnchor); - } - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlAudio.cs b/SiteServer.CMS/StlParser/StlElement/StlAudio.cs deleted file mode 100644 index 8ca5188ac..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlAudio.cs +++ /dev/null @@ -1,127 +0,0 @@ -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.CMS.StlParser.Model; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "播放音频", Description = "通过 stl:audio 标签在模板中显示并播放音频文件")] - public class StlAudio - { - private StlAudio() { } - public const string ElementName = "stl:audio"; - - private static readonly Attr Type = new Attr("type", "指定存储音频地址的内容字段,默认为VideoUrl", AttrType.Enum); - private static readonly Attr PlayUrl = new Attr("playUrl", "音频地址,优先级高于type属性"); - private static readonly Attr IsAutoPlay = new Attr("isAutoPlay", "是否自动播放", AttrType.Boolean); - private static readonly Attr IsPreload = new Attr("isPreload", "是否预载入", AttrType.Boolean); - private static readonly Attr IsLoop = new Attr("isLoop", "是否循环播放", AttrType.Boolean); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var type = BackgroundContentAttribute.VideoUrl; - var playUrl = string.Empty; - var isAutoPlay = false; - var isPreLoad = true; - var isLoop = false; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, Type.Name)) - { - type = value; - } - else if (StringUtils.EqualsIgnoreCase(name, PlayUrl.Name) || StringUtils.EqualsIgnoreCase(name, "src")) - { - playUrl = value; - } - else if (StringUtils.EqualsIgnoreCase(name, IsAutoPlay.Name) || StringUtils.EqualsIgnoreCase(name, "play")) - { - isAutoPlay = TranslateUtils.ToBool(value, false); - } - else if (StringUtils.EqualsIgnoreCase(name, IsPreload.Name)) - { - isPreLoad = TranslateUtils.ToBool(value, true); - } - else if (StringUtils.EqualsIgnoreCase(name, IsLoop.Name) || StringUtils.EqualsIgnoreCase(name, "loop")) - { - isLoop = TranslateUtils.ToBool(value, false); - } - } - - return ParseImpl(pageInfo, contextInfo, type, playUrl, isAutoPlay, isPreLoad, isLoop); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string type, string playUrl, bool isAutoPlay, bool isPreLoad, bool isLoop) - { - var contentId = contextInfo.ContentId; - - if (string.IsNullOrEmpty(playUrl)) - { - if (contentId != 0)//获取内容视频 - { - if (contextInfo.ContentInfo == null) - { - //playUrl = DataProvider.ContentDao.GetValue(pageInfo.SiteInfo.AuxiliaryTableForContent, contentId, type); - playUrl = Content.GetValue(pageInfo.SiteInfo.TableName, contentId, type); - if (string.IsNullOrEmpty(playUrl)) - { - if (!StringUtils.EqualsIgnoreCase(type, BackgroundContentAttribute.VideoUrl)) - { - //playUrl = DataProvider.ContentDao.GetValue(pageInfo.SiteInfo.AuxiliaryTableForContent, contentId, BackgroundContentAttribute.VideoUrl); - playUrl = Content.GetValue(pageInfo.SiteInfo.TableName, contentId, BackgroundContentAttribute.VideoUrl); - } - } - if (string.IsNullOrEmpty(playUrl)) - { - if (!StringUtils.EqualsIgnoreCase(type, BackgroundContentAttribute.FileUrl)) - { - //playUrl = DataProvider.ContentDao.GetValue(pageInfo.SiteInfo.AuxiliaryTableForContent, contentId, BackgroundContentAttribute.FileUrl); - playUrl = Content.GetValue(pageInfo.SiteInfo.TableName, contentId, BackgroundContentAttribute.FileUrl); - } - } - } - else - { - playUrl = contextInfo.ContentInfo.GetString(type); - if (string.IsNullOrEmpty(playUrl)) - { - playUrl = contextInfo.ContentInfo.GetString(BackgroundContentAttribute.VideoUrl); - } - if (string.IsNullOrEmpty(playUrl)) - { - playUrl = contextInfo.ContentInfo.GetString(BackgroundContentAttribute.FileUrl); - } - } - } - } - - if (string.IsNullOrEmpty(playUrl)) return string.Empty; - - playUrl = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, playUrl, pageInfo.IsLocal); - - // 如果是实体标签,则只返回数字 - if (contextInfo.IsStlEntity) - { - return playUrl; - } - else - { - pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.Jquery); - pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.JsAcMediaElement); - - return $@" - -"; - } - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlChannel.cs b/SiteServer.CMS/StlParser/StlElement/StlChannel.cs deleted file mode 100644 index 04a7af93b..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlChannel.cs +++ /dev/null @@ -1,339 +0,0 @@ -using System.Collections.Specialized; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Parsers; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Plugin; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "获取栏目值", Description = "通过 stl:channel 标签在模板中显示指定栏目的属性值")] - public class StlChannel - { - private StlChannel() { } - public const string ElementName = "stl:channel"; - - private static readonly Attr ChannelIndex = new Attr("channelIndex", "栏目索引", AttrType.Enum); - private static readonly Attr ChannelName = new Attr("channelName", "栏目名称", AttrType.Enum); - private static readonly Attr Parent = new Attr("parent", "显示父栏目属性", AttrType.Boolean); - private static readonly Attr UpLevel = new Attr("upLevel", "上级栏目的级别", AttrType.Integer); - private static readonly Attr TopLevel = new Attr("topLevel", "从首页向下的栏目级别", AttrType.Integer); - private static readonly Attr Type = new Attr("type", "显示的类型", AttrType.Enum); - private static readonly Attr LeftText = new Attr("leftText", "显示在信息前的文字"); - private static readonly Attr RightText = new Attr("rightText", "显示在信息后的文字"); - private static readonly Attr FormatString = new Attr("formatString", "显示的格式"); - private static readonly Attr Separator = new Attr("separator", "显示多项时的分割字符串"); - private static readonly Attr StartIndex = new Attr("startIndex", "字符开始位置", AttrType.Integer); - private static readonly Attr Length = new Attr("length", "指定字符长度", AttrType.Integer); - private static readonly Attr WordNum = new Attr("wordNum", "显示字符的数目", AttrType.Integer); - private static readonly Attr Ellipsis = new Attr("ellipsis", "文字超出部分显示的文字"); - private static readonly Attr Replace = new Attr("replace", "需要替换的文字,可以是正则表达式"); - private static readonly Attr To = new Attr("to", "替换replace的文字信息"); - private static readonly Attr IsClearTags = new Attr("isClearTags", "是否清除HTML标签", AttrType.Boolean); - private static readonly Attr IsReturnToBr = new Attr("isReturnToBr", "是否将回车替换为HTML换行标签", AttrType.Boolean); - private static readonly Attr IsLower = new Attr("isLower", "是否转换为小写", AttrType.Boolean); - private static readonly Attr IsUpper = new Attr("isUpper", "是否转换为大写", AttrType.Boolean); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var leftText = string.Empty; - var rightText = string.Empty; - var channelIndex = string.Empty; - var channelName = string.Empty; - var upLevel = 0; - var topLevel = -1; - var type = ChannelAttribute.Title; - var formatString = string.Empty; - string separator = null; - var startIndex = 0; - var length = 0; - var wordNum = 0; - var ellipsis = StringUtils.Constants.Ellipsis; - var replace = string.Empty; - var to = string.Empty; - var isClearTags = false; - var isReturnToBr = false; - var isLower = false; - var isUpper = false; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, ChannelIndex.Name)) - { - channelIndex = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, ChannelName.Name)) - { - channelName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, Parent.Name)) - { - if (TranslateUtils.ToBool(value)) - { - upLevel = 1; - } - } - else if (StringUtils.EqualsIgnoreCase(name, UpLevel.Name)) - { - upLevel = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, TopLevel.Name)) - { - topLevel = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Type.Name)) - { - type = value; - } - else if (StringUtils.EqualsIgnoreCase(name, LeftText.Name)) - { - leftText = value; - } - else if (StringUtils.EqualsIgnoreCase(name, RightText.Name)) - { - rightText = value; - } - else if (StringUtils.EqualsIgnoreCase(name, FormatString.Name)) - { - formatString = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Separator.Name)) - { - separator = value; - } - else if (StringUtils.EqualsIgnoreCase(name, StartIndex.Name)) - { - startIndex = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Length.Name)) - { - length = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, WordNum.Name)) - { - wordNum = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Ellipsis.Name)) - { - ellipsis = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Replace.Name)) - { - replace = value; - } - else if (StringUtils.EqualsIgnoreCase(name, To.Name)) - { - to = value; - } - else if (StringUtils.EqualsIgnoreCase(name, IsClearTags.Name)) - { - isClearTags = TranslateUtils.ToBool(value, false); - } - else if (StringUtils.EqualsIgnoreCase(name, IsReturnToBr.Name)) - { - isReturnToBr = TranslateUtils.ToBool(value, false); - } - else if (StringUtils.EqualsIgnoreCase(name, IsLower.Name)) - { - isLower = TranslateUtils.ToBool(value, true); - } - else if (StringUtils.EqualsIgnoreCase(name, IsUpper.Name)) - { - isUpper = TranslateUtils.ToBool(value, true); - } - } - - return ParseImpl(pageInfo, contextInfo, leftText, rightText, channelIndex, channelName, upLevel, topLevel, type, formatString, separator, startIndex, length, wordNum, ellipsis, replace, to, isClearTags, isReturnToBr, isLower, isUpper); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string leftText, string rightText, string channelIndex, string channelName, int upLevel, int topLevel, string type, string formatString, string separator, int startIndex, int length, int wordNum, string ellipsis, string replace, string to, bool isClearTags, bool isReturnToBr, bool isLower, bool isUpper) - { - if (string.IsNullOrEmpty(type)) return string.Empty; - type = type.ToLower(); - - var parsedContent = string.Empty; - - var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); - - channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, channelIndex, channelName); - var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); - - if (!string.IsNullOrEmpty(formatString)) - { - formatString = formatString.Trim(); - if (!formatString.StartsWith("{0")) - { - formatString = "{0:" + formatString; - } - if (!formatString.EndsWith("}")) - { - formatString = formatString + "}"; - } - } - var inputType = InputType.Text; - - if (type.Equals(ChannelAttribute.Title.ToLower())) - { - parsedContent = channel.ChannelName; - - if (isClearTags) - { - parsedContent = StringUtils.StripTags(parsedContent); - } - - if (!string.IsNullOrEmpty(replace)) - { - parsedContent = StringUtils.Replace(replace, parsedContent, to); - } - - if (!string.IsNullOrEmpty(parsedContent) && wordNum > 0) - { - parsedContent = StringUtils.MaxLengthText(parsedContent, wordNum, ellipsis); - } - } - else if (type.Equals(ChannelAttribute.ChannelIndex.ToLower())) - { - parsedContent = channel.IndexName; - - if (!string.IsNullOrEmpty(replace)) - { - parsedContent = StringUtils.Replace(replace, parsedContent, to); - } - - if (!string.IsNullOrEmpty(parsedContent) && wordNum > 0) - { - parsedContent = StringUtils.MaxLengthText(parsedContent, wordNum, ellipsis); - } - } - else if (type.Equals(ChannelAttribute.Content.ToLower())) - { - parsedContent = ContentUtility.TextEditorContentDecode(pageInfo.SiteInfo, channel.Content, pageInfo.IsLocal); - - if (isClearTags) - { - parsedContent = StringUtils.StripTags(parsedContent); - } - - if (!string.IsNullOrEmpty(replace)) - { - parsedContent = StringUtils.Replace(replace, parsedContent, to); - } - - if (!string.IsNullOrEmpty(parsedContent) && wordNum > 0) - { - parsedContent = StringUtils.MaxLengthText(parsedContent, wordNum, ellipsis); - } - } - else if (type.Equals(ChannelAttribute.PageContent.ToLower())) - { - if (contextInfo.IsInnerElement || pageInfo.TemplateInfo.TemplateType != TemplateType.ChannelTemplate) - { - parsedContent = ContentUtility.TextEditorContentDecode(pageInfo.SiteInfo, channel.Content, pageInfo.IsLocal); - - if (isClearTags) - { - parsedContent = StringUtils.StripTags(parsedContent); - } - - if (!string.IsNullOrEmpty(replace)) - { - parsedContent = StringUtils.Replace(replace, parsedContent, to); - } - - if (!string.IsNullOrEmpty(parsedContent) && wordNum > 0) - { - parsedContent = StringUtils.MaxLengthText(parsedContent, wordNum, ellipsis); - } - } - else - { - return contextInfo.StlElement; - } - } - else if (type.Equals(ChannelAttribute.AddDate.ToLower())) - { - inputType = InputType.DateTime; - parsedContent = DateUtils.Format(channel.AddDate, formatString); - } - else if (type.Equals(ChannelAttribute.ImageUrl.ToLower())) - { - inputType = InputType.Image; - parsedContent = InputParserUtility.GetImageOrFlashHtml(pageInfo.SiteInfo, channel.ImageUrl, contextInfo.Attributes, contextInfo.IsStlEntity); // contextInfo.IsStlEntity = true 表示实体标签 - } - else if (type.Equals(ChannelAttribute.Id.ToLower())) - { - parsedContent = channelId.ToString(); - } - else if (StringUtils.StartsWithIgnoreCase(type, StlParserUtility.ItemIndex) && contextInfo.ItemContainer?.ChannelItem != null) - { - var itemIndex = StlParserUtility.ParseItemIndex(contextInfo.ItemContainer.ChannelItem.ItemIndex, type, contextInfo); - parsedContent = !string.IsNullOrEmpty(formatString) ? string.Format(formatString, itemIndex) : itemIndex.ToString(); - } - else if (type.Equals(ChannelAttribute.CountOfChannels.ToLower())) - { - parsedContent = channel.ChildrenCount.ToString(); - } - else if (type.Equals(ChannelAttribute.CountOfContents.ToLower())) - { - parsedContent = channel.ContentNum.ToString(); - } - else if (type.Equals(ChannelAttribute.CountOfImageContents.ToLower())) - { - var count = Content.GetCountCheckedImage(pageInfo.SiteId, channel.Id); - parsedContent = count.ToString(); - } - else if (type.Equals(ChannelAttribute.Keywords.ToLower())) - { - parsedContent = channel.Keywords; - } - else if (type.Equals(ChannelAttribute.Description.ToLower())) - { - parsedContent = channel.Description; - } - else - { - var attributeName = type; - - var formCollection = channel.Additional.ToNameValueCollection(); - if (formCollection != null && formCollection.Count > 0) - { - var styleInfo = TableStyleManager.GetTableStyleInfo(DataProvider.ChannelDao.TableName, attributeName, RelatedIdentities.GetChannelRelatedIdentities(pageInfo.SiteId, channel.Id)); - // 如果 styleInfo.TableStyleId <= 0,表示此字段已经被删除了,不需要再显示值了 ekun008 - if (styleInfo.Id > 0) - { - parsedContent = GetValue(attributeName, formCollection, false, styleInfo.DefaultValue); - if (!string.IsNullOrEmpty(parsedContent)) - { - parsedContent = InputParserUtility.GetContentByTableStyle(parsedContent, separator, pageInfo.SiteInfo, styleInfo, formatString, contextInfo.Attributes, contextInfo.InnerXml, false); - inputType = styleInfo.InputType; - } - } - } - } - - if (string.IsNullOrEmpty(parsedContent)) return string.Empty; - - parsedContent = StringUtils.ParseString(inputType, parsedContent, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); - return leftText + parsedContent + rightText; - } - - private static string GetValue(string attributeName, NameValueCollection formCollection, bool isAddAndNotPostBack, string defaultValue) - { - var value = string.Empty; - if (formCollection?[attributeName] != null) - { - value = formCollection[attributeName]; - } - if (isAddAndNotPostBack && string.IsNullOrEmpty(value)) - { - value = defaultValue; - } - return value; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlChannels.cs b/SiteServer.CMS/StlParser/StlElement/StlChannels.cs deleted file mode 100644 index 33f73e3ef..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlChannels.cs +++ /dev/null @@ -1,151 +0,0 @@ -using System.Data; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "栏目列表", Description = "通过 stl:channels 标签在模板中显示栏目列表")] - public class StlChannels - { - public const string ElementName = "stl:channels"; - - public static readonly Attr ChannelIndex = new Attr("channelIndex", "栏目索引"); //栏目索引 - public static readonly Attr ChannelName = new Attr("channelName", "栏目名称"); //栏目名称 - public static readonly Attr UpLevel = new Attr("upLevel", "上级栏目的级别"); //上级栏目的级别 - public static readonly Attr TopLevel = new Attr("topLevel", "从首页向下的栏目级别"); //从首页向下的栏目级别 - protected static readonly Attr IsTotal = new Attr("isTotal", "是否从所有栏目中选择"); //是否从所有栏目中选择(包括首页) - protected static readonly Attr IsAllChildren = new Attr("isAllChildren", "是否显示所有级别的子栏目"); //是否显示所有级别的子栏目 - public static readonly Attr GroupChannel = new Attr("groupChannel", "指定显示的栏目组"); //指定显示的栏目组 - public static readonly Attr GroupChannelNot = new Attr("groupChannelNot", "指定不显示的栏目组"); //指定不显示的栏目组 - public static readonly Attr TotalNum = new Attr("totalNum", "显示栏目数目"); //显示栏目数目 - public static readonly Attr StartNum = new Attr("startNum", "从第几条信息开始显示"); //从第几条信息开始显示 - public static readonly Attr Order = new Attr("order", "排序"); //排序 - public static readonly Attr IsImage = new Attr("isImage", "仅显示图片栏目"); //仅显示图片栏目 - public static readonly Attr Where = new Attr("where", "获取栏目列表的条件判断"); //获取栏目列表的条件判断 - public static readonly Attr CellPadding = new Attr("cellPadding", "填充"); - public static readonly Attr CellSpacing = new Attr("cellSpacing", "间距"); - public static readonly Attr Class = new Attr("class", "Css类"); - public static readonly Attr Columns = new Attr("columns", "列数"); - public static readonly Attr Direction = new Attr("direction", "方向"); - public static readonly Attr Height = new Attr("height", "整体高度"); - public static readonly Attr Width = new Attr("width", "整体宽度"); - public static readonly Attr Align = new Attr("align", "整体对齐"); - public static readonly Attr Layout = new Attr("layout", "指定列表布局方式"); - public static readonly Attr ItemHeight = new Attr("itemHeight", "项高度"); - public static readonly Attr ItemWidth = new Attr("itemWidth", "项宽度"); - public static readonly Attr ItemAlign = new Attr("itemAlign", "项水平对齐"); - public static readonly Attr ItemVerticalAlign = new Attr("itemVerticalAlign", "项垂直对齐"); - public static readonly Attr ItemClass = new Attr("itemClass", "项Css类"); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - // 如果是实体标签则返回空 - if(contextInfo.IsStlEntity) - { - return string.Empty; - } - var listInfo = ListInfo.GetListInfoByXmlNode(pageInfo, contextInfo, EContextType.Channel); - - return ParseImpl(pageInfo, contextInfo, listInfo); - } - - public static DataSet GetDataSource(PageInfo pageInfo, ContextInfo contextInfo, ListInfo listInfo) - { - var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, listInfo.UpLevel, listInfo.TopLevel); - - channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, listInfo.ChannelIndex, listInfo.ChannelName); - - var isTotal = TranslateUtils.ToBool(listInfo.Others.Get(IsTotal.Name)); - - if (TranslateUtils.ToBool(listInfo.Others.Get(IsAllChildren.Name))) - { - listInfo.Scope = EScopeType.Descendant; - } - - return StlDataUtility.GetChannelsDataSource(pageInfo.SiteId, channelId, listInfo.GroupChannel, listInfo.GroupChannelNot, listInfo.IsImageExists, listInfo.IsImage, listInfo.StartNum, listInfo.TotalNum, listInfo.OrderByString, listInfo.Scope, isTotal, listInfo.Where); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, ListInfo listInfo) - { - var parsedContent = string.Empty; - - var dataSource = GetDataSource(pageInfo, contextInfo, listInfo); - - if (listInfo.Layout == ELayout.None) - { - var rptContents = new Repeater(); - - if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) - { - rptContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); - } - if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) - { - rptContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); - } - if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) - { - rptContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); - } - if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) - { - rptContents.AlternatingItemTemplate = new RepeaterTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Channel, contextInfo); - } - - rptContents.ItemTemplate = new RepeaterTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, - listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, - pageInfo, EContextType.Channel, contextInfo); - - rptContents.DataSource = dataSource; - rptContents.DataBind(); - - if (rptContents.Items.Count > 0) - { - parsedContent = ControlUtils.GetControlRenderHtml(rptContents); - } - } - else - { - var pdlContents = new ParsedDataList(); - - //设置显示属性 - TemplateUtility.PutListInfoToMyDataList(pdlContents, listInfo); - - //设置列表模板 - pdlContents.ItemTemplate = new DataListTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Channel, contextInfo); - if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) - { - pdlContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); - } - if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) - { - pdlContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); - } - if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) - { - pdlContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); - } - if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) - { - pdlContents.AlternatingItemTemplate = new DataListTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Channel, contextInfo); - } - - pdlContents.DataSource = dataSource; - pdlContents.DataKeyField = ChannelAttribute.Id; - pdlContents.DataBind(); - - if (pdlContents.Items.Count > 0) - { - parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); - } - } - - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlCode.cs b/SiteServer.CMS/StlParser/StlElement/StlCode.cs deleted file mode 100644 index 955d126ce..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlCode.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using SiteServer.Utils; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "添加代码", Description = "通过 stl:code 标签在页面中添加html代码,相同Key的代码将显示最后添加的值")] - public class StlCode - { - private StlCode() { } - public const string ElementName = "stl:code"; - - private static readonly Attr Type = new Attr("type", "代码放置的位置"); - private static readonly Attr Key = new Attr("key", "代码键"); - - public const string TypeHead = "Head"; - public const string TypeBody = "Body"; - public const string TypeFoot = "Foot"; - - public static SortedList TypeList => new SortedList - { - {TypeHead, "头部(之前)"}, - {TypeBody, "主体(之后)"}, - {TypeFoot, "底部(之后)"} - }; - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var type = string.Empty; - var key = string.Empty; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, Type.Name)) - { - type = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Key.Name)) - { - key = value; - } - } - - if (!string.IsNullOrEmpty(key)) - { - var innerBuilder = new StringBuilder(contextInfo.InnerXml); - StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); - var code = innerBuilder.ToString(); - - if (StringUtils.EqualsIgnoreCase(type, TypeHead)) - { - pageInfo.HeadCodes[key] = code; - } - else if (StringUtils.EqualsIgnoreCase(type, TypeFoot)) - { - pageInfo.FootCodes[key] = code; - } - else - { - pageInfo.BodyCodes[key] = code; - } - } - - return string.Empty; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlContainer.cs b/SiteServer.CMS/StlParser/StlElement/StlContainer.cs deleted file mode 100644 index 2d82032cb..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlContainer.cs +++ /dev/null @@ -1,47 +0,0 @@ -using System.Text; -using SiteServer.Utils; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "容器", Description = "通过 stl:container 标签在模板中定义容器,切换上下文")] - public class StlContainer - { - private StlContainer() { } - public const string ElementName = "stl:container"; - - private static readonly Attr Context = new Attr("context", "所处上下文"); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - // 如果是实体标签则返回空 - if (contextInfo.IsStlEntity) - { - return string.Empty; - } - - if (string.IsNullOrEmpty(contextInfo.InnerXml)) - { - return string.Empty; - } - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, Context.Name)) - { - contextInfo.ContextType = EContextTypeUtils.GetEnumType(value); - } - } - - var innerHtml = RegexUtils.GetInnerContent(ElementName, contextInfo.StlElement); - - var builder = new StringBuilder(innerHtml); - StlParserManager.ParseInnerContent(builder, pageInfo, contextInfo); - - return builder.ToString(); - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlContent.cs b/SiteServer.CMS/StlParser/StlElement/StlContent.cs deleted file mode 100644 index 0146e2562..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlContent.cs +++ /dev/null @@ -1,565 +0,0 @@ -using System.Text; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "获取内容值", Description = "通过 stl:content 标签在模板中显示指定内容的属性值")] - public class StlContent - { - private StlContent() { } - public const string ElementName = "stl:content"; - - private static readonly Attr Type = new Attr("type", "显示的类型"); - private static readonly Attr LeftText = new Attr("leftText", "显示在信息前的文字"); - private static readonly Attr RightText = new Attr("rightText", "显示在信息后的文字"); - private static readonly Attr FormatString = new Attr("formatString", "显示的格式"); - private static readonly Attr No = new Attr("no", "显示第几项"); - private static readonly Attr Separator = new Attr("separator", "显示多项时的分割字符串"); - private static readonly Attr StartIndex = new Attr("startIndex", "字符开始位置"); - private static readonly Attr Length = new Attr("length", "指定字符长度"); - private static readonly Attr WordNum = new Attr("wordNum", "显示字符的数目"); - private static readonly Attr Ellipsis = new Attr("ellipsis", "文字超出部分显示的文字"); - private static readonly Attr Replace = new Attr("replace", "需要替换的文字,可以是正则表达式"); - private static readonly Attr To = new Attr("to", "替换replace的文字信息"); - private static readonly Attr IsClearTags = new Attr("isClearTags", "是否清除HTML标签"); - private static readonly Attr IsReturnToBr = new Attr("isReturnToBr", "是否将回车替换为HTML换行标签"); - private static readonly Attr IsLower = new Attr("isLower", "是否转换为小写"); - private static readonly Attr IsUpper = new Attr("isUpper", "是否转换为大写"); - private static readonly Attr IsOriginal = new Attr("isOriginal", "如果是引用内容,是否获取所引用内容的值"); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var leftText = string.Empty; - var rightText = string.Empty; - var formatString = string.Empty; - var no = "0"; - string separator = null; - var startIndex = 0; - var length = 0; - var wordNum = 0; - var ellipsis = StringUtils.Constants.Ellipsis; - var replace = string.Empty; - var to = string.Empty; - var isClearTags = false; - var isReturnToBrStr = string.Empty; - var isLower = false; - var isUpper = false; - var isOriginal = true;//引用的时候,默认使用原来的数据 - var type = ContentAttribute.Title.ToLower(); - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, Type.Name)) - { - type = value.ToLower(); - } - else if (StringUtils.EqualsIgnoreCase(name, LeftText.Name)) - { - leftText = value; - } - else if (StringUtils.EqualsIgnoreCase(name, RightText.Name)) - { - rightText = value; - } - else if (StringUtils.EqualsIgnoreCase(name, FormatString.Name)) - { - formatString = value; - } - else if (StringUtils.EqualsIgnoreCase(name, No.Name)) - { - no = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Separator.Name)) - { - separator = value; - } - else if (StringUtils.EqualsIgnoreCase(name, StartIndex.Name)) - { - startIndex = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Length.Name)) - { - length = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, WordNum.Name)) - { - wordNum = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Ellipsis.Name)) - { - ellipsis = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Replace.Name)) - { - replace = value; - } - else if (StringUtils.EqualsIgnoreCase(name, To.Name)) - { - to = value; - } - else if (StringUtils.EqualsIgnoreCase(name, IsClearTags.Name)) - { - isClearTags = TranslateUtils.ToBool(value, true); - } - else if (StringUtils.EqualsIgnoreCase(name, IsReturnToBr.Name)) - { - isReturnToBrStr = value; - } - else if (StringUtils.EqualsIgnoreCase(name, IsLower.Name)) - { - isLower = TranslateUtils.ToBool(value, true); - } - else if (StringUtils.EqualsIgnoreCase(name, IsUpper.Name)) - { - isUpper = TranslateUtils.ToBool(value, true); - } - else if (StringUtils.EqualsIgnoreCase(name, IsOriginal.Name)) - { - isOriginal = TranslateUtils.ToBool(value, true); - } - } - - var parsedContent = ParseImpl(pageInfo, contextInfo, leftText, rightText, formatString, no, separator, startIndex, length, wordNum, ellipsis, replace, to, isClearTags, isReturnToBrStr, isLower, isUpper, isOriginal, type); - - var innerBuilder = new StringBuilder(parsedContent); - StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); - parsedContent = innerBuilder.ToString(); - - return parsedContent; - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string leftText, string rightText, string formatString, string no, string separator, int startIndex, int length, int wordNum, string ellipsis, string replace, string to, bool isClearTags, string isReturnToBrStr, bool isLower, bool isUpper, bool isOriginal, string type) - { - var parsedContent = string.Empty; - - var isReturnToBr = false; - if (string.IsNullOrEmpty(isReturnToBrStr)) - { - if (BackgroundContentAttribute.Summary.ToLower().Equals(type)) - { - isReturnToBr = true; - } - } - else - { - isReturnToBr = TranslateUtils.ToBool(isReturnToBrStr, true); - } - - var contentId = contextInfo.ContentId; - var contentInfo = contextInfo.ContentInfo; - if (contentInfo == null) return string.Empty; - - if (isOriginal) - { - if (contentInfo.ReferenceId > 0 && contentInfo.SourceId > 0 && contentInfo.GetString(ContentAttribute.TranslateContentType) == ETranslateContentType.Reference.ToString()) - { - var targetChannelId = contentInfo.SourceId; - //var targetSiteId = DataProvider.ChannelDao.GetSiteId(targetChannelId); - var targetSiteId = Node.GetSiteId(targetChannelId); - var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); - var targetNodeInfo = ChannelManager.GetChannelInfo(targetSiteId, targetChannelId); - - var tableName = ChannelManager.GetTableName(targetSiteInfo, targetNodeInfo); - //var targetContentInfo = DataProvider.ContentDao.GetContentInfo(tableStyle, tableName, contentInfo.ReferenceId); - var targetContentInfo = Content.GetContentInfo(tableName, contentInfo.ReferenceId); - if (targetContentInfo != null && targetContentInfo.ChannelId > 0) - { - //标题可以使用自己的 - targetContentInfo.Title = contentInfo.Title; - contentInfo = targetContentInfo; - } - } - } - - if (!string.IsNullOrEmpty(formatString)) - { - formatString = formatString.Trim(); - if (!formatString.StartsWith("{0")) - { - formatString = "{0:" + formatString; - } - if (!formatString.EndsWith("}")) - { - formatString = formatString + "}"; - } - } - - if (contentId != 0) - { - if (ContentAttribute.Title.ToLower().Equals(type)) - { - var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(pageInfo.SiteId, contentInfo.ChannelId); - var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contentInfo.ChannelId); - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, nodeInfo); - - var styleInfo = TableStyleManager.GetTableStyleInfo(tableName, type, relatedIdentities); - parsedContent = InputParserUtility.GetContentByTableStyle(contentInfo.Title, separator, pageInfo.SiteInfo, styleInfo, formatString, contextInfo.Attributes, contextInfo.InnerXml, false); - parsedContent = StringUtils.ParseString(styleInfo.InputType, parsedContent, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); - - if (!isClearTags && !string.IsNullOrEmpty(contentInfo.GetString(BackgroundContentAttribute.TitleFormatString))) - { - parsedContent = ContentUtility.FormatTitle(contentInfo.GetString(BackgroundContentAttribute.TitleFormatString), parsedContent); - } - - if (!contextInfo.IsInnerElement) - { - parsedContent = parsedContent.Replace("&", "&"); - } - - if (pageInfo.SiteInfo.Additional.IsContentTitleBreakLine) - { - parsedContent = parsedContent.Replace(" ", !contextInfo.IsInnerElement ? "
    " : string.Empty); - } - } - else if (BackgroundContentAttribute.Summary.ToLower().Equals(type)) - { - parsedContent = StringUtils.ParseString(contentInfo.GetString(BackgroundContentAttribute.Summary), replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); - if (!contextInfo.IsInnerElement) - { - parsedContent = parsedContent.Replace("&", "&"); - } - } - else if (BackgroundContentAttribute.Content.ToLower().Equals(type)) - { - parsedContent = ContentUtility.TextEditorContentDecode(pageInfo.SiteInfo, contentInfo.GetString(BackgroundContentAttribute.Content), pageInfo.IsLocal); - - if (isClearTags) - { - parsedContent = StringUtils.StripTags(parsedContent); - } - - if (!string.IsNullOrEmpty(replace)) - { - parsedContent = StringUtils.Replace(replace, parsedContent, to); - } - - if (wordNum > 0 && !string.IsNullOrEmpty(parsedContent)) - { - parsedContent = StringUtils.MaxLengthText(parsedContent, wordNum, ellipsis); - } - - if (!string.IsNullOrEmpty(formatString)) - { - parsedContent = string.Format(formatString, parsedContent); - } - - if (!contextInfo.IsInnerElement) - { - parsedContent = parsedContent.Replace("&", "&"); - } - } - else if (BackgroundContentAttribute.PageContent.ToLower().Equals(type)) - { - //if (contextInfo.IsInnerElement) - // { - parsedContent = ContentUtility.TextEditorContentDecode(pageInfo.SiteInfo, contentInfo.GetString(BackgroundContentAttribute.Content), pageInfo.IsLocal); - - if (isClearTags) - { - parsedContent = StringUtils.StripTags(parsedContent); - } - - if (!string.IsNullOrEmpty(replace)) - { - parsedContent = StringUtils.Replace(replace, parsedContent, to); - } - - if (wordNum > 0 && !string.IsNullOrEmpty(parsedContent)) - { - parsedContent = StringUtils.MaxLengthText(parsedContent, wordNum, ellipsis); - } - - if (!string.IsNullOrEmpty(formatString)) - { - parsedContent = string.Format(formatString, parsedContent); - } - } - else if (ContentAttribute.AddDate.ToLower().Equals(type)) - { - parsedContent = DateUtils.Format(contentInfo.AddDate, formatString); - } - else if (ContentAttribute.LastEditDate.ToLower().Equals(type)) - { - parsedContent = DateUtils.Format(contentInfo.LastEditDate, formatString); - } - else if (BackgroundContentAttribute.ImageUrl.ToLower().Equals(type)) - { - if (no == "all") - { - var sbParsedContent = new StringBuilder(); - //第一条 - sbParsedContent.Append(contextInfo.IsStlEntity - ? PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, - contentInfo.GetString(BackgroundContentAttribute.ImageUrl), pageInfo.IsLocal) - : InputParserUtility.GetImageOrFlashHtml(pageInfo.SiteInfo, - contentInfo.GetString(BackgroundContentAttribute.ImageUrl), - contextInfo.Attributes, false)); - //第n条 - var extendAttributeName = ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.ImageUrl); - var extendValues = contentInfo.GetString(extendAttributeName); - if (!string.IsNullOrEmpty(extendValues)) - { - foreach (var extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) - { - var newExtendValue = extendValue; - sbParsedContent.Append(contextInfo.IsStlEntity - ? PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, newExtendValue, pageInfo.IsLocal) - : InputParserUtility.GetImageOrFlashHtml(pageInfo.SiteInfo, - newExtendValue, contextInfo.Attributes, false)); - } - } - - parsedContent = sbParsedContent.ToString(); - } - else - { - var num = TranslateUtils.ToInt(no, 0); - if (num <= 1) - { - parsedContent = contextInfo.IsStlEntity ? PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, contentInfo.GetString(BackgroundContentAttribute.ImageUrl), pageInfo.IsLocal) : InputParserUtility.GetImageOrFlashHtml(pageInfo.SiteInfo, contentInfo.GetString(BackgroundContentAttribute.ImageUrl), contextInfo.Attributes, false); - } - else - { - var extendAttributeName = ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.ImageUrl); - var extendValues = contentInfo.GetString(extendAttributeName); - if (!string.IsNullOrEmpty(extendValues)) - { - var index = 2; - foreach (var extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) - { - var newExtendValue = extendValue; - if (index == num) - { - parsedContent = contextInfo.IsStlEntity ? PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, newExtendValue, pageInfo.IsLocal) : InputParserUtility.GetImageOrFlashHtml(pageInfo.SiteInfo, newExtendValue, contextInfo.Attributes, false); - break; - } - index++; - } - } - } - } - } - else if (BackgroundContentAttribute.VideoUrl.ToLower().Equals(type)) - { - if (no == "all") - { - var sbParsedContent = new StringBuilder(); - //第一条 - sbParsedContent.Append(InputParserUtility.GetVideoHtml(pageInfo.SiteInfo, contentInfo.GetString(BackgroundContentAttribute.VideoUrl), contextInfo.Attributes, contextInfo.IsStlEntity)); - - //第n条 - var extendAttributeName = ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.VideoUrl); - var extendValues = contentInfo.GetString(extendAttributeName); - if (!string.IsNullOrEmpty(extendValues)) - { - foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) - { - - sbParsedContent.Append(InputParserUtility.GetVideoHtml(pageInfo.SiteInfo, extendValue, contextInfo.Attributes, contextInfo.IsStlEntity)); - - } - } - - parsedContent = sbParsedContent.ToString(); - } - else - { - var num = TranslateUtils.ToInt(no, 0); - if (num <= 1) - { - parsedContent = InputParserUtility.GetVideoHtml(pageInfo.SiteInfo, contentInfo.GetString(BackgroundContentAttribute.VideoUrl), contextInfo.Attributes, contextInfo.IsStlEntity); - } - else - { - var extendAttributeName = ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.VideoUrl); - var extendValues = contentInfo.GetString(extendAttributeName); - if (!string.IsNullOrEmpty(extendValues)) - { - var index = 2; - foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) - { - if (index == num) - { - parsedContent = InputParserUtility.GetVideoHtml(pageInfo.SiteInfo, extendValue, contextInfo.Attributes, contextInfo.IsStlEntity); - break; - } - index++; - } - } - } - } - - } - else if (BackgroundContentAttribute.FileUrl.ToLower().Equals(type)) - { - - if (no == "all") - { - var sbParsedContent = new StringBuilder(); - if (contextInfo.IsStlEntity) - { - //第一条 - sbParsedContent.Append(contentInfo.GetString(BackgroundContentAttribute.FileUrl)); - //第n条 - var extendAttributeName = ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.FileUrl); - var extendValues = contentInfo.GetString(extendAttributeName); - if (!string.IsNullOrEmpty(extendValues)) - { - foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) - { - sbParsedContent.Append(extendValue); - } - } - } - else - { - //第一条 - sbParsedContent.Append(InputParserUtility.GetFileHtmlWithCount(pageInfo.SiteInfo, contentInfo.ChannelId, contentInfo.Id, contentInfo.GetString(BackgroundContentAttribute.FileUrl), contextInfo.Attributes, contextInfo.InnerXml, false)); - //第n条 - var extendAttributeName = ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.FileUrl); - var extendValues = contentInfo.GetString(extendAttributeName); - if (!string.IsNullOrEmpty(extendValues)) - { - foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) - { - sbParsedContent.Append(InputParserUtility.GetFileHtmlWithCount(pageInfo.SiteInfo, contentInfo.ChannelId, contentInfo.Id, extendValue, contextInfo.Attributes, contextInfo.InnerXml, false)); - } - } - - } - - parsedContent = sbParsedContent.ToString(); - - } - else - { - var num = TranslateUtils.ToInt(no, 0); - if (contextInfo.IsStlEntity) - { - if (num <= 1) - { - parsedContent = contentInfo.GetString(BackgroundContentAttribute.FileUrl); - } - else - { - var extendAttributeName = ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.FileUrl); - var extendValues = contentInfo.GetString(extendAttributeName); - if (!string.IsNullOrEmpty(extendValues)) - { - var index = 2; - foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) - { - if (index == num) - { - parsedContent = extendValue; - break; - } - index++; - } - } - } - - if (!string.IsNullOrEmpty(parsedContent)) - { - parsedContent = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); - } - } - else - { - if (num <= 1) - { - parsedContent = InputParserUtility.GetFileHtmlWithCount(pageInfo.SiteInfo, contentInfo.ChannelId, contentInfo.Id, contentInfo.GetString(BackgroundContentAttribute.FileUrl), contextInfo.Attributes, contextInfo.InnerXml, false); - } - else - { - var extendAttributeName = ContentAttribute.GetExtendAttributeName(BackgroundContentAttribute.FileUrl); - var extendValues = contentInfo.GetString(extendAttributeName); - if (!string.IsNullOrEmpty(extendValues)) - { - var index = 2; - foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) - { - if (index == num) - { - parsedContent = InputParserUtility.GetFileHtmlWithCount(pageInfo.SiteInfo, contentInfo.ChannelId, contentInfo.Id, extendValue, contextInfo.Attributes, contextInfo.InnerXml, false); - break; - } - index++; - } - } - } - } - } - - - } - else if (BackgroundContentAttribute.NavigationUrl.ToLower().Equals(type)) - { - parsedContent = PageUtility.GetContentUrl(pageInfo.SiteInfo, contentInfo, pageInfo.IsLocal); - } - else if (ContentAttribute.Tags.ToLower().Equals(type)) - { - parsedContent = contentInfo.Tags; - } - else if (StringUtils.StartsWithIgnoreCase(type, StlParserUtility.ItemIndex) && contextInfo.ItemContainer?.ContentItem != null) - { - var itemIndex = StlParserUtility.ParseItemIndex(contextInfo.ItemContainer.ContentItem.ItemIndex, type, contextInfo); - parsedContent = !string.IsNullOrEmpty(formatString) ? string.Format(formatString, itemIndex) : itemIndex.ToString(); - } - else if (ContentAttribute.AddUserName.ToLower().Equals(type)) - { - if (!string.IsNullOrEmpty(contentInfo.AddUserName)) - { - //var displayName = DataProvider.AdministratorDao.GetDisplayName(contentInfo.AddUserName); - var displayName = Administrator.GetDisplayName(contentInfo.AddUserName); - parsedContent = string.IsNullOrEmpty(displayName) ? contentInfo.AddUserName : displayName; - } - } - else - { - var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contentInfo.ChannelId); - - if (contentInfo.ContainsKey(type)) - { - if (!ContentAttribute.AllAttributesLowercase.Contains(type.ToLower())) - { - var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(pageInfo.SiteId, contentInfo.ChannelId); - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, nodeInfo); - var styleInfo = TableStyleManager.GetTableStyleInfo(tableName, type, relatedIdentities); - - //styleInfo.IsVisible = false 表示此字段不需要显示 styleInfo.TableStyleId = 0 不能排除,因为有可能是直接辅助表字段没有添加显示样式 - var num = TranslateUtils.ToInt(no); - parsedContent = InputParserUtility.GetContentByTableStyle(contentInfo, separator, pageInfo.SiteInfo, styleInfo, formatString, num, contextInfo.Attributes, contextInfo.InnerXml, false); - parsedContent = StringUtils.ParseString(styleInfo.InputType, parsedContent, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); - } - else - { - parsedContent = contentInfo.GetString(type); - parsedContent = StringUtils.ParseString(parsedContent, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); - } - } - - if (!contextInfo.IsInnerElement) - { - parsedContent = parsedContent.Replace("&", "&"); - } - } - - if (!string.IsNullOrEmpty(parsedContent)) - { - parsedContent = leftText + parsedContent + rightText; - } - } - - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlContents.cs b/SiteServer.CMS/StlParser/StlElement/StlContents.cs deleted file mode 100644 index 80304ccdd..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlContents.cs +++ /dev/null @@ -1,157 +0,0 @@ -using System.Data; -using System.Web.UI.WebControls; -using SiteServer.CMS.Model; -using SiteServer.Utils; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "内容列表", Description = "通过 stl:contents 标签在模板中显示内容列表")] - public class StlContents - { - public const string ElementName = "stl:contents"; - - public static readonly Attr ChannelIndex = new Attr("channelIndex", "栏目索引"); - public static readonly Attr ChannelName = new Attr("channelName", "栏目名称"); - public static readonly Attr UpLevel = new Attr("upLevel", "上级栏目的级别"); - public static readonly Attr TopLevel = new Attr("topLevel", "从首页向下的栏目级别"); - public static readonly Attr Scope = new Attr("scope", "内容范围"); - public static readonly Attr Group = new Attr("group", "指定显示的栏目组"); - public static readonly Attr GroupNot = new Attr("groupNot", "指定不显示的栏目组"); - public static readonly Attr GroupChannel = new Attr("groupChannel", "指定显示的内容组"); - public static readonly Attr GroupChannelNot = new Attr("groupChannelNot", "指定不显示的内容组"); - public static readonly Attr GroupContent = new Attr("groupContent", "指定显示的内容组"); - public static readonly Attr GroupContentNot = new Attr("groupContentNot", "指定不显示的内容组"); - public static readonly Attr Tags = new Attr("tags", "指定标签"); - public static readonly Attr IsTop = new Attr("isTop", "仅显示置顶内容"); - public static readonly Attr IsRecommend = new Attr("isRecommend", "仅显示推荐内容"); - public static readonly Attr IsHot = new Attr("isHot", "仅显示热点内容"); - public static readonly Attr IsColor = new Attr("isColor", "仅显示醒目内容"); - public static readonly Attr TotalNum = new Attr("totalNum", "显示内容数目"); - public static readonly Attr StartNum = new Attr("startNum", "从第几条信息开始显示"); - public static readonly Attr Order = new Attr("order", "排序"); - public static readonly Attr IsImage = new Attr("isImage", "仅显示图片内容"); - public static readonly Attr IsVideo = new Attr("isVideo", "仅显示视频内容"); - public static readonly Attr IsFile = new Attr("isFile", "仅显示附件内容"); - public static readonly Attr IsNoDup = new Attr("isNoDup", "不显示重复标题的内容"); - public static readonly Attr IsRelatedContents = new Attr("isRelatedContents", "显示相关内容列表"); - public static readonly Attr Where = new Attr("where", "获取内容列表的条件判断"); - public static readonly Attr CellPadding = new Attr("cellPadding", "填充"); - public static readonly Attr CellSpacing = new Attr("cellSpacing", "间距"); - public static readonly Attr Class = new Attr("class", "Css类"); - public static readonly Attr Columns = new Attr("columns", "列数"); - public static readonly Attr Direction = new Attr("direction", "方向"); - public static readonly Attr Height = new Attr("height", "指定列表布局方式"); - public static readonly Attr Width = new Attr("width", "整体高度"); - public static readonly Attr Align = new Attr("align", "整体宽度"); - public static readonly Attr ItemHeight = new Attr("itemHeight", "整体对齐"); - public static readonly Attr ItemWidth = new Attr("itemWidth", "项高度"); - public static readonly Attr ItemAlign = new Attr("itemAlign", "项宽度"); - public static readonly Attr ItemVerticalAlign = new Attr("itemVerticalAlign", "项水平对齐"); - public static readonly Attr ItemClass = new Attr("itemClass", "项垂直对齐"); - public static readonly Attr Layout = new Attr("layout", "项Css类"); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - // 如果是实体标签则返回空 - if (contextInfo.IsStlEntity) - { - return string.Empty; - } - - var listInfo = ListInfo.GetListInfoByXmlNode(pageInfo, contextInfo, EContextType.Content); - - return ParseImpl(pageInfo, contextInfo, listInfo); - } - - public static DataSet GetDataSource(PageInfo pageInfo, ContextInfo contextInfo, ListInfo listInfo) - { - var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, listInfo.UpLevel, listInfo.TopLevel); - - channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, listInfo.ChannelIndex, listInfo.ChannelName); - - return StlDataUtility.GetContentsDataSource(pageInfo.SiteInfo, channelId, contextInfo.ContentId, listInfo.GroupContent, listInfo.GroupContentNot, listInfo.Tags, listInfo.IsImageExists, listInfo.IsImage, listInfo.IsVideoExists, listInfo.IsVideo, listInfo.IsFileExists, listInfo.IsFile, listInfo.IsNoDup, listInfo.IsRelatedContents, listInfo.StartNum, listInfo.TotalNum, listInfo.OrderByString, listInfo.IsTopExists, listInfo.IsTop, listInfo.IsRecommendExists, listInfo.IsRecommend, listInfo.IsHotExists, listInfo.IsHot, listInfo.IsColorExists, listInfo.IsColor, listInfo.Where, listInfo.Scope, listInfo.GroupChannel, listInfo.GroupChannelNot, listInfo.Others); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, ListInfo listInfo) - { - var parsedContent = string.Empty; - - var dataSource = GetDataSource(pageInfo, contextInfo, listInfo); - - if (listInfo.Layout == ELayout.None) - { - var rptContents = new Repeater - { - ItemTemplate = - new RepeaterTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, - listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, - pageInfo, EContextType.Content, contextInfo) - }; - - if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) - { - rptContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); - } - if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) - { - rptContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); - } - if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) - { - rptContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); - } - if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) - { - rptContents.AlternatingItemTemplate = new RepeaterTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Content, contextInfo); - } - - rptContents.DataSource = dataSource; - rptContents.DataBind(); - - if (rptContents.Items.Count > 0) - { - parsedContent = ControlUtils.GetControlRenderHtml(rptContents); - } - } - else - { - var pdlContents = new ParsedDataList(); - - TemplateUtility.PutListInfoToMyDataList(pdlContents, listInfo); - - pdlContents.ItemTemplate = new DataListTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Content, contextInfo); - if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) - { - pdlContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); - } - if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) - { - pdlContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); - } - if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) - { - pdlContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); - } - if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) - { - pdlContents.AlternatingItemTemplate = new DataListTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Content, contextInfo); - } - - pdlContents.DataSource = dataSource; - pdlContents.DataKeyField = ContentAttribute.Id; - pdlContents.DataBind(); - - if (pdlContents.Items.Count > 0) - { - parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); - } - } - - return parsedContent; - } - - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlCount.cs b/SiteServer.CMS/StlParser/StlElement/StlCount.cs deleted file mode 100644 index 34cd871f7..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlCount.cs +++ /dev/null @@ -1,126 +0,0 @@ -using System; -using System.Collections.Generic; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "显示数值", Description = "通过 stl:count 标签在模板中显示统计数字")] - public class StlCount - { - private StlCount() { } - public const string ElementName = "stl:count"; - - private static readonly Attr Type = new Attr("type", "需要获取值的类型"); - private static readonly Attr ChannelIndex = new Attr("channelIndex", "栏目索引"); - private static readonly Attr ChannelName = new Attr("channelName", "栏目名称"); - private static readonly Attr UpLevel = new Attr("upLevel", "上级栏目的级别"); - private static readonly Attr TopLevel = new Attr("topLevel", "从首页向下的栏目级别"); - private static readonly Attr Scope = new Attr("scope", "内容范围"); - private static readonly Attr Since = new Attr("since", "时间段"); - - public const string TypeChannels = "Channels"; - public const string TypeContents = "Contents"; - public const string TypeDownloads = "Downloads"; - - public static SortedList TypeList => new SortedList - { - {TypeChannels, "栏目数"}, - {TypeContents, "内容数"}, - {TypeDownloads, "下载次数"} - }; - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var type = string.Empty; - var channelIndex = string.Empty; - var channelName = string.Empty; - var upLevel = 0; - var topLevel = -1; - var scope = EScopeType.Self; - var since = string.Empty; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, Type.Name)) - { - type = value; - } - else if (StringUtils.EqualsIgnoreCase(name, ChannelIndex.Name)) - { - channelIndex = value; - } - else if (StringUtils.EqualsIgnoreCase(name, ChannelName.Name)) - { - channelName = value; - } - else if (StringUtils.EqualsIgnoreCase(name, UpLevel.Name)) - { - upLevel = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, TopLevel.Name)) - { - topLevel = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Scope.Name)) - { - scope = EScopeTypeUtils.GetEnumType(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Since.Name)) - { - since = value; - } - } - - return ParseImpl(pageInfo, contextInfo, type, channelIndex, channelName, upLevel, topLevel, scope, since); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string type, string channelIndex, string channelName, int upLevel, int topLevel, EScopeType scope, string since) - { - var count = 0; - - var sinceDate = DateUtils.SqlMinValue; - if (!string.IsNullOrEmpty(since)) - { - sinceDate = DateTime.Now.AddHours(-DateUtils.GetSinceHours(since)); - } - - if (string.IsNullOrEmpty(type) || StringUtils.EqualsIgnoreCase(type, TypeContents)) - { - var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); - channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, channelIndex, channelName); - - var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); - var channelIdList = ChannelManager.GetChannelIdList(nodeInfo, scope, string.Empty, string.Empty, string.Empty); - foreach (var theChannelId in channelIdList) - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, theChannelId); - count += Content.GetCountOfContentAdd(tableName, pageInfo.SiteId, theChannelId, EScopeType.Self, sinceDate, DateTime.Now.AddDays(1), string.Empty, ETriState.True); - } - } - else if (StringUtils.EqualsIgnoreCase(type, TypeChannels)) - { - var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); - channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, channelIndex, channelName); - - var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); - count = nodeInfo.ChildrenCount; - } - else if (StringUtils.EqualsIgnoreCase(type, TypeDownloads)) - { - if (contextInfo.ContentId > 0) - { - count = CountManager.GetCount(pageInfo.SiteInfo.TableName, contextInfo.ContentId.ToString(), ECountType.Download); - } - } - - return count.ToString(); - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlDynamic.cs b/SiteServer.CMS/StlParser/StlElement/StlDynamic.cs deleted file mode 100644 index 1df34b997..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlDynamic.cs +++ /dev/null @@ -1,214 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Text; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.StlEntity; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Plugin; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "动态显示", Description = "通过 stl:dynamic 标签在模板中实现动态显示功能")] - public class StlDynamic - { - private StlDynamic() { } - public const string ElementName = "stl:dynamic"; - - private static readonly Attr Context = new Attr("context", "所处上下文"); - private static readonly Attr IsPageRefresh = new Attr("isPageRefresh", "翻页时是否刷新页面"); - - internal static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - // 如果是实体标签则返回空 - if (contextInfo.IsStlEntity) - { - return string.Empty; - } - - var isPageRefresh = false; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, Context.Name)) - { - contextInfo.ContextType = EContextTypeUtils.GetEnumType(value); - } - else if (StringUtils.EqualsIgnoreCase(name, IsPageRefresh.Name)) - { - isPageRefresh = TranslateUtils.ToBool(value); - } - } - - return ParseImpl(pageInfo, contextInfo, contextInfo.InnerXml, isPageRefresh); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string templateContent, bool isPageRefresh) - { - pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.StlClient); - - var ajaxDivId = StlParserUtility.GetAjaxDivId(pageInfo.UniqueId); - - var functionName = $"stlDynamic_{ajaxDivId}"; - - if (string.IsNullOrEmpty(templateContent)) - { - return string.Empty; - } - - StlParserManager.ParseInnerContent(new StringBuilder(templateContent), pageInfo, contextInfo); - - var apiUrl = ApiRouteActionsDynamic.GetUrl(pageInfo.ApiUrl); - var currentPageUrl = StlParserUtility.GetStlCurrentUrl(pageInfo.SiteInfo, contextInfo.ChannelId, contextInfo.ContentId, contextInfo.ContentInfo, pageInfo.TemplateInfo.TemplateType, pageInfo.TemplateInfo.Id, pageInfo.IsLocal); - currentPageUrl = PageUtils.AddQuestionOrAndToUrl(currentPageUrl); - var apiParameters = ApiRouteActionsDynamic.GetParameters(pageInfo.SiteId, contextInfo.ChannelId, contextInfo.ContentId, pageInfo.TemplateInfo.Id, currentPageUrl, ajaxDivId, isPageRefresh, templateContent); - - var builder = new StringBuilder(); - builder.Append($@""); - - builder.Append($@" - -"); - - return builder.ToString(); - } - - internal static string ParseDynamicElement(string stlElement, PageInfo pageInfo, ContextInfo contextInfo) - { - stlElement = StringUtils.ReplaceIgnoreCase(stlElement, "isdynamic=\"true\"", string.Empty); - return ParseImpl(pageInfo, contextInfo, stlElement, false); - } - - public static string ParseDynamicContent(int siteId, int channelId, int contentId, int templateId, bool isPageRefresh, string templateContent, string pageUrl, int pageIndex, string ajaxDivId, NameValueCollection queryString, IUserInfo userInfo) - { - var templateInfo = TemplateManager.GetTemplateInfo(siteId, templateId); - //TemplateManager.GetTemplateInfo(siteID, channelID, templateType); - var siteInfo = SiteManager.GetSiteInfo(siteId); - var pageInfo = new PageInfo(channelId, contentId, siteInfo, templateInfo, new Dictionary()) - { - UniqueId = 1000, - UserInfo = userInfo - }; - var contextInfo = new ContextInfo(pageInfo); - - templateContent = StlRequestEntities.ParseRequestEntities(queryString, templateContent); - var contentBuilder = new StringBuilder(templateContent); - var stlElementList = StlParserUtility.GetStlElementList(contentBuilder.ToString()); - - //如果标签中存在 - if (StlParserUtility.IsStlElementExists(StlPageContents.ElementName, stlElementList)) - { - var stlElement = StlParserUtility.GetStlElement(StlPageContents.ElementName, stlElementList); - var stlPageContentsElement = stlElement; - var stlPageContentsElementReplaceString = stlElement; - - var pageContentsElementParser = new StlPageContents(stlPageContentsElement, pageInfo, contextInfo, true); - int totalNum; - var pageCount = pageContentsElementParser.GetPageCount(out totalNum); - - for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) - { - if (currentPageIndex == pageIndex) - { - var pageHtml = pageContentsElementParser.Parse(totalNum, currentPageIndex, pageCount, false); - contentBuilder.Replace(stlPageContentsElementReplaceString, pageHtml); - - StlParserManager.ReplacePageElementsInDynamicPage(contentBuilder, pageInfo, stlElementList, pageUrl, pageInfo.PageChannelId, currentPageIndex, pageCount, totalNum, isPageRefresh, ajaxDivId); - - break; - } - } - } - //如果标签中存在 - else if (StlParserUtility.IsStlElementExists(StlPageChannels.ElementName, stlElementList)) - { - var stlElement = StlParserUtility.GetStlElement(StlPageChannels.ElementName, stlElementList); - var stlPageChannelsElement = stlElement; - var stlPageChannelsElementReplaceString = stlElement; - - var pageChannelsElementParser = new StlPageChannels(stlPageChannelsElement, pageInfo, contextInfo, true); - int totalNum; - var pageCount = pageChannelsElementParser.GetPageCount(out totalNum); - - for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) - { - if (currentPageIndex == pageIndex) - { - var pageHtml = pageChannelsElementParser.Parse(currentPageIndex, pageCount); - contentBuilder.Replace(stlPageChannelsElementReplaceString, pageHtml); - - StlParserManager.ReplacePageElementsInDynamicPage(contentBuilder, pageInfo, stlElementList, pageUrl, pageInfo.PageChannelId, currentPageIndex, pageCount, totalNum, isPageRefresh, ajaxDivId); - - break; - } - } - } - //如果标签中存在 - else if (StlParserUtility.IsStlElementExists(StlPageSqlContents.ElementName, stlElementList)) - { - var stlElement = StlParserUtility.GetStlElement(StlPageSqlContents.ElementName, stlElementList); - var stlPageSqlContentsElement = stlElement; - var stlPageSqlContentsElementReplaceString = stlElement; - - var pageSqlContentsElementParser = new StlPageSqlContents(stlPageSqlContentsElement, pageInfo, contextInfo, true); - int totalNum; - var pageCount = pageSqlContentsElementParser.GetPageCount(out totalNum); - - for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) - { - if (currentPageIndex == pageIndex) - { - var pageHtml = pageSqlContentsElementParser.Parse(currentPageIndex, pageCount); - contentBuilder.Replace(stlPageSqlContentsElementReplaceString, pageHtml); - - StlParserManager.ReplacePageElementsInDynamicPage(contentBuilder, pageInfo, stlElementList, pageUrl, pageInfo.PageChannelId, currentPageIndex, pageCount, totalNum, isPageRefresh, ajaxDivId); - - break; - } - } - } - - else if (StlParserUtility.IsStlElementExists(StlPageItems.ElementName, stlElementList)) - { - var pageCount = TranslateUtils.ToInt(queryString["pageCount"]); - var totalNum = TranslateUtils.ToInt(queryString["totalNum"]); - var pageContentsAjaxDivId = queryString["pageContentsAjaxDivId"]; - - for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) - { - if (currentPageIndex == pageIndex) - { - StlParserManager.ReplacePageElementsInDynamicPage(contentBuilder, pageInfo, stlElementList, pageUrl, pageInfo.PageChannelId, currentPageIndex, pageCount, totalNum, isPageRefresh, pageContentsAjaxDivId); - - break; - } - } - } - - StlParserManager.ParseInnerContent(contentBuilder, pageInfo, contextInfo); - - //var parsedContent = StlParserUtility.GetBackHtml(contentBuilder.ToString(), pageInfo); - //return pageInfo.HeadCodesHtml + pageInfo.BodyCodesHtml + parsedContent + pageInfo.FootCodesHtml; - return StlParserUtility.GetBackHtml(contentBuilder.ToString(), pageInfo); - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlEach.cs b/SiteServer.CMS/StlParser/StlElement/StlEach.cs deleted file mode 100644 index 305c69c98..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlEach.cs +++ /dev/null @@ -1,179 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using System.Web.UI.WebControls; -using SiteServer.CMS.Model; -using SiteServer.Utils; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "列表项循环", Description = "通过 stl:each 标签在模板中遍历指定的列表项")] - public class StlEach - { - public const string ElementName = "stl:each"; - - private static readonly Attr Type = new Attr("type", "循环类型"); - private static readonly Attr TotalNum = new Attr("totalNum", "显示信息数目"); - private static readonly Attr StartNum = new Attr("startNum", "从第几条信息开始显示"); - private static readonly Attr Order = new Attr("order", "排序"); - private static readonly Attr CellPadding = new Attr("cellPadding", "填充"); - private static readonly Attr CellSpacing = new Attr("cellSpacing", "间距"); - private static readonly Attr Class = new Attr("class", "Css类"); - private static readonly Attr Columns = new Attr("columns", "列数"); - private static readonly Attr Direction = new Attr("direction", "方向"); - private static readonly Attr Height = new Attr("height", "指定列表布局方式"); - private static readonly Attr Width = new Attr("width", "整体高度"); - private static readonly Attr Align = new Attr("align", "整体宽度"); - private static readonly Attr ItemHeight = new Attr("itemHeight", "整体对齐"); - private static readonly Attr ItemWidth = new Attr("itemWidth", "项高度"); - private static readonly Attr ItemAlign = new Attr("itemAlign", "项宽度"); - private static readonly Attr ItemVerticalAlign = new Attr("itemVerticalAlign", "项水平对齐"); - private static readonly Attr ItemClass = new Attr("itemClass", "项垂直对齐"); - private static readonly Attr Layout = new Attr("layout", "项Css类"); - - public static SortedList TypeList => new SortedList - { - {BackgroundContentAttribute.ImageUrl, "遍历内容的图片字段"}, - {BackgroundContentAttribute.VideoUrl, "遍历内容的视频字段"}, - {BackgroundContentAttribute.FileUrl, "遍历内容的附件字段"} - }; - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var listInfo = ListInfo.GetListInfoByXmlNode(pageInfo, contextInfo, EContextType.Content); - - return ParseImpl(pageInfo, contextInfo, listInfo); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, ListInfo listInfo) - { - var parsedContent = string.Empty; - - var type = listInfo.Others.Get(Type.Name); - if (string.IsNullOrEmpty(type)) - { - type = BackgroundContentAttribute.ImageUrl; - } - - var contextType = EContextType.Each; - IEnumerable dataSource = null; - var contentInfo = contextInfo.ContentInfo; - if (contentInfo != null) - { - var eachList = new List(); - - if (!string.IsNullOrEmpty(contentInfo.GetString(type))) - { - eachList.Add(contentInfo.GetString(type)); - } - - var extendAttributeName = ContentAttribute.GetExtendAttributeName(type); - var extendValues = contentInfo.GetString(extendAttributeName); - if (!string.IsNullOrEmpty(extendValues)) - { - foreach (var extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) - { - eachList.Add(extendValue); - } - } - - if (listInfo.StartNum > 1 || listInfo.TotalNum > 0) - { - if (listInfo.StartNum > 1) - { - var count = listInfo.StartNum - 1; - if (count > eachList.Count) - { - count = eachList.Count; - } - eachList.RemoveRange(0, count); - } - - if (listInfo.TotalNum > 0) - { - if (listInfo.TotalNum < eachList.Count) - { - eachList.RemoveRange(listInfo.TotalNum, eachList.Count - listInfo.TotalNum); - } - } - } - - dataSource = eachList; - } - - if (listInfo.Layout == ELayout.None) - { - var rptContents = new Repeater - { - ItemTemplate = - new RepeaterTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, - listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, - pageInfo, contextType, contextInfo) - }; - - if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) - { - rptContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); - } - if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) - { - rptContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); - } - if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) - { - rptContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); - } - if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) - { - rptContents.AlternatingItemTemplate = new RepeaterTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, contextType, contextInfo); - } - - rptContents.DataSource = dataSource; - - rptContents.DataBind(); - - if (rptContents.Items.Count > 0) - { - parsedContent = ControlUtils.GetControlRenderHtml(rptContents); - } - } - else - { - var pdlContents = new ParsedDataList(); - - TemplateUtility.PutListInfoToMyDataList(pdlContents, listInfo); - - pdlContents.ItemTemplate = new DataListTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, contextType, contextInfo); - if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) - { - pdlContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); - } - if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) - { - pdlContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); - } - if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) - { - pdlContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); - } - if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) - { - pdlContents.AlternatingItemTemplate = new DataListTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, contextType, contextInfo); - } - - pdlContents.DataSource = dataSource; - - pdlContents.DataBind(); - - if (pdlContents.Items.Count > 0) - { - parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); - } - } - - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlFile.cs b/SiteServer.CMS/StlParser/StlElement/StlFile.cs deleted file mode 100644 index 2263fda62..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlFile.cs +++ /dev/null @@ -1,159 +0,0 @@ -using System.Text; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "文件下载链接", Description = "通过 stl:file 标签在模板中显示文件下载链接")] - public class StlFile - { - private StlFile() { } - - public const string ElementName = "stl:file"; - - private static readonly Attr No = new Attr("no", "显示字段的顺序"); - private static readonly Attr Src = new Attr("src", "需要下载的文件地址"); - private static readonly Attr IsFileSize = new Attr("isFileSize", "显示文件大小"); - private static readonly Attr IsCount = new Attr("isCount", "是否记录文件下载次数"); - private static readonly Attr Type = new Attr("type", "指定存储附件的字段"); - private static readonly Attr LeftText = new Attr("leftText", "显示在信息前的文字"); - private static readonly Attr RightText = new Attr("rightText", "显示在信息后的文字"); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var no = 0; - var src = string.Empty; - var isFilesize = false; - var isCount = true; - var type = BackgroundContentAttribute.FileUrl; - var leftText = string.Empty; - var rightText = string.Empty; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, No.Name)) - { - no = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Src.Name)) - { - src = value; - } - else if (StringUtils.EqualsIgnoreCase(name, IsFileSize.Name)) - { - isFilesize = TranslateUtils.ToBool(value); - } - else if (StringUtils.EqualsIgnoreCase(name, IsCount.Name)) - { - isCount = TranslateUtils.ToBool(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Type.Name)) - { - type = value; - } - else if (StringUtils.EqualsIgnoreCase(name, LeftText.Name)) - { - leftText = value; - } - else if (StringUtils.EqualsIgnoreCase(name, RightText.Name)) - { - rightText = value; - } - } - - return ParseImpl(pageInfo, contextInfo, type, no, src, isFilesize, isCount, leftText, rightText); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string type, int no, string src, bool isFilesize, bool isCount, string leftText, string rightText) - { - if (!string.IsNullOrEmpty(contextInfo.InnerXml)) - { - var innerBuilder = new StringBuilder(contextInfo.InnerXml); - StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); - contextInfo.InnerXml = innerBuilder.ToString(); - } - - var fileUrl = string.Empty; - if (!string.IsNullOrEmpty(src)) - { - fileUrl = src; - } - else - { - if (contextInfo.ContextType == EContextType.Undefined) - { - contextInfo.ContextType = EContextType.Content; - } - if (contextInfo.ContextType == EContextType.Content) - { - if (contextInfo.ContentId != 0) - { - var contentInfo = contextInfo.ContentInfo; - - if (!string.IsNullOrEmpty(contentInfo?.GetString(type))) - { - if (no <= 1) - { - fileUrl = contentInfo.GetString(StringUtils.EqualsIgnoreCase(type, BackgroundContentAttribute.FileUrl) ? BackgroundContentAttribute.FileUrl : type); - } - else - { - var extendAttributeName = ContentAttribute.GetExtendAttributeName(type); - var extendValues = contentInfo.GetString(extendAttributeName); - if (!string.IsNullOrEmpty(extendValues)) - { - var index = 2; - foreach (var extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) - { - if (index == no) - { - fileUrl = extendValue; - - break; - } - index++; - } - } - } - } - } - } - else if (contextInfo.ContextType == EContextType.Each) - { - fileUrl = contextInfo.ItemContainer.EachItem.DataItem as string; - } - } - - var parsedContent = InputParserUtility.GetFileHtmlWithoutCount(pageInfo.SiteInfo, fileUrl, contextInfo.Attributes, contextInfo.InnerXml, contextInfo.IsStlEntity); - - if (isFilesize) - { - var filePath = PathUtility.MapPath(pageInfo.SiteInfo, fileUrl); - parsedContent += " (" + FileUtils.GetFileSizeByFilePath(filePath) + ")"; - } - else - { - if (isCount && contextInfo.ContentInfo != null) - { - parsedContent = InputParserUtility.GetFileHtmlWithCount(pageInfo.SiteInfo, contextInfo.ContentInfo.ChannelId, contextInfo.ContentInfo.Id, fileUrl, contextInfo.Attributes, contextInfo.InnerXml, contextInfo.IsStlEntity); - } - else - { - parsedContent = InputParserUtility.GetFileHtmlWithoutCount(pageInfo.SiteInfo, fileUrl, contextInfo.Attributes, contextInfo.InnerXml, contextInfo.IsStlEntity); - } - } - - if (!string.IsNullOrEmpty(parsedContent)) - { - parsedContent = leftText + parsedContent + rightText; - } - - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlFlash.cs b/SiteServer.CMS/StlParser/StlElement/StlFlash.cs deleted file mode 100644 index 740cba2ac..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlFlash.cs +++ /dev/null @@ -1,216 +0,0 @@ -using System.Text; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Parsers; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "显示Flash", Description = "通过 stl:flash 标签在模板中获取并显示栏目或内容的Flash")] - public class StlFlash - { - private StlFlash() { } - public const string ElementName = "stl:flash"; - - private static readonly Attr ChannelIndex = new Attr("channelIndex", "栏目索引"); - private static readonly Attr ChannelName = new Attr("channelName", "栏目名称"); - private static readonly Attr Parent = new Attr("parent", "显示父栏目"); - private static readonly Attr UpLevel = new Attr("upLevel", "上级栏目的级别"); - private static readonly Attr TopLevel = new Attr("topLevel", "从首页向下的栏目级别"); - private static readonly Attr Type = new Attr("type", "指定存储flash的字段"); - private static readonly Attr Src = new Attr("src", "显示的flash地址"); - private static readonly Attr AltSrc = new Attr("altSrc", "当指定的flash不存在时显示的flash地址"); - private static readonly Attr Width = new Attr("width", "宽度"); - private static readonly Attr Height = new Attr("height", "高度"); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var isGetPicUrlFromAttribute = false; - var channelIndex = string.Empty; - var channelName = string.Empty; - var upLevel = 0; - var topLevel = -1; - var type = BackgroundContentAttribute.ImageUrl; - var src = string.Empty; - var altSrc = string.Empty; - var width = "100%"; - var height = "180"; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, ChannelIndex.Name)) - { - channelIndex = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - if (!string.IsNullOrEmpty(channelIndex)) - { - isGetPicUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, ChannelName.Name)) - { - channelName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - if (!string.IsNullOrEmpty(channelName)) - { - isGetPicUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, Parent.Name)) - { - if (TranslateUtils.ToBool(value)) - { - upLevel = 1; - isGetPicUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, UpLevel.Name)) - { - upLevel = TranslateUtils.ToInt(value); - if (upLevel > 0) - { - isGetPicUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, TopLevel.Name)) - { - topLevel = TranslateUtils.ToInt(value); - if (topLevel >= 0) - { - isGetPicUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, Type.Name)) - { - type = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Src.Name)) - { - src = value; - } - else if (StringUtils.EqualsIgnoreCase(name, AltSrc.Name)) - { - altSrc = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Width.Name)) - { - width = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Height.Name)) - { - height = value; - } - } - - return ParseImpl(pageInfo, contextInfo, isGetPicUrlFromAttribute, channelIndex, channelName, upLevel, topLevel, type, src, altSrc, width, height); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, bool isGetPicUrlFromAttribute, string channelIndex, string channelName, int upLevel, int topLevel, string type, string src, string altSrc, string width, string height) - { - var parsedContent = string.Empty; - - var contentId = 0; - //判断是否图片地址由标签属性获得 - if (!isGetPicUrlFromAttribute) - { - contentId = contextInfo.ContentId; - } - var contentInfo = contextInfo.ContentInfo; - - string picUrl; - if (!string.IsNullOrEmpty(src)) - { - picUrl = src; - } - else - { - if (contentId != 0)//获取内容Flash - { - if (contentInfo == null) - { - var nodeInfo = ChannelManager.GetChannelInfo(contextInfo.SiteInfo.Id, contextInfo.ChannelId); - var tableName = ChannelManager.GetTableName(contextInfo.SiteInfo, nodeInfo); - - //picUrl = DataProvider.ContentDao.GetValue(tableName, contentId, type); - picUrl = Content.GetValue(tableName, contentId, type); - } - else - { - picUrl = contextInfo.ContentInfo.GetString(type); - } - } - else//获取栏目Flash - { - var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); - - channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, channelIndex, channelName); - var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); - - picUrl = channel.ImageUrl; - } - } - - if (string.IsNullOrEmpty(picUrl)) - { - picUrl = altSrc; - } - - // 如果是实体标签则返回空 - if (contextInfo.IsStlEntity) - { - return picUrl; - } - - if (!string.IsNullOrEmpty(picUrl)) - { - var extension = PathUtils.GetExtension(picUrl); - if (EFileSystemTypeUtils.IsImage(extension)) - { - parsedContent = StlImage.Parse(pageInfo, contextInfo); - } - else if (EFileSystemTypeUtils.IsPlayer(extension)) - { - parsedContent = StlPlayer.Parse(pageInfo, contextInfo); - } - else - { - pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.JsAcSwfObject); - - picUrl = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, picUrl, pageInfo.IsLocal); - - if (!contextInfo.Attributes.ContainsKey("quality")) - { - contextInfo.Attributes["quality"] = "high"; - } - if (!contextInfo.Attributes.ContainsKey("wmode")) - { - contextInfo.Attributes["wmode"] = "transparent"; - } - var paramBuilder = new StringBuilder(); - var uniqueId = pageInfo.UniqueId; - foreach (var key in contextInfo.Attributes.Keys) - { - paramBuilder.Append($@" so_{uniqueId}.addParam(""{key}"", ""{contextInfo.Attributes[key]}"");").Append(StringUtils.Constants.ReturnAndNewline); - } - - parsedContent = $@" -
    - -"; - } - } - - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlIf.cs b/SiteServer.CMS/StlParser/StlElement/StlIf.cs deleted file mode 100644 index ac4c4a92f..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlIf.cs +++ /dev/null @@ -1,970 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Web.UI; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "条件判断", Description = "通过 stl:if 标签在模板中根据条件判断显示内容")] - public class StlIf - { - private StlIf() { } - public const string ElementName = "stl:if"; - - private static readonly Attr Type = new Attr("type", "测试类型"); //测试类型 - private static readonly Attr Operate = new Attr("operate", "测试操作"); //测试操作 - private static readonly Attr Value = new Attr("value", "测试值"); //测试值 - private static readonly Attr Context = new Attr("context", "所处上下文"); //所处上下文 - - public const string TypeIsUserLoggin = "IsUserLoggin"; //用户是否已登录 - public const string TypeIsAdministratorLoggin = "IsAdministratorLoggin"; //管理员是否已登录 - public const string TypeIsUserOrAdministratorLoggin = "IsUserOrAdministratorLoggin"; //用户或管理员是否已登录 - public const string TypeChannelName = "ChannelName"; //栏目名称 - public const string TypeChannelIndex = "ChannelIndex"; //栏目索引 - public const string TypeTemplateName = "TemplateName"; //模板名称 - public const string TypTemplateType = "TemplateType"; //模板类型 - public const string TypeTopLevel = "TopLevel"; //栏目级别 - public const string TypeUpChannel = "UpChannel"; //上级栏目 - public const string TypeUpChannelOrSelf = "UpChannelOrSelf"; //当前栏目或上级栏目 - public const string TypeSelfChannel = "SelfChannel"; //当前栏目 - public const string TypeGroupChannel = "GroupChannel"; //栏目组名称 - public const string TypeGroupContent = "GroupContent"; //内容组名称 - public const string TypeAddDate = "AddDate"; //添加时间 - public const string TypeLastEditDate = "LastEditDate"; //最后编辑时间(仅用于判断内容) - public const string TypeItemIndex = "ItemIndex"; //当前项序号 - public const string TypeOddItem = "OddItem"; //奇数项 - - public static SortedList TypeList => new SortedList - { - {TypeIsUserLoggin, "用户是否已登录"}, - {TypeIsAdministratorLoggin, "管理员是否已登录"}, - {TypeIsUserOrAdministratorLoggin, "用户或管理员是否已登录"}, - {TypeChannelName, "栏目名称"}, - {TypeChannelIndex, "栏目索引"}, - {TypeTemplateName, "模板名称"}, - {TypTemplateType, "模板类型"}, - {TypeTopLevel, "栏目级别"}, - {TypeUpChannel, "上级栏目"}, - {TypeUpChannelOrSelf, "当前栏目或上级栏目"}, - {TypeSelfChannel, "当前栏目"}, - {TypeGroupChannel, "栏目组名称"}, - {TypeGroupContent, "内容组名称"}, - {TypeAddDate, "添加时间"}, - {TypeLastEditDate, "最后编辑时间(仅用于判断内容)"}, - {TypeItemIndex, "当前项序号"}, - {TypeOddItem, "奇数项"} - }; - - public const string OperateEmpty = "Empty"; - public const string OperateNotEmpty = "NotEmpty"; //值不为空 - public const string OperateEquals = "Equals"; //值等于 - public const string OperateNotEquals = "NotEquals"; //值不等于 - public const string OperateGreatThan = "GreatThan"; //值大于 - public const string OperateLessThan = "LessThan"; //值小于 - public const string OperateIn = "In"; //值属于 - public const string OperateNotIn = "NotIn"; //值不属于 - - public static SortedList OperateList => new SortedList - { - {OperateEmpty, "值为空"}, - {OperateNotEmpty, "值不为空"}, - {OperateEquals, "值等于"}, - {OperateNotEquals, "值不等于"}, - {OperateGreatThan, "值大于"}, - {OperateLessThan, "值小于"}, - {OperateIn, "值属于"}, - {OperateNotIn, "值不属于"} - }; - - - internal static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var testTypeStr = string.Empty; - var testOperate = OperateEquals; - var testValue = string.Empty; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, Type.Name) || StringUtils.EqualsIgnoreCase(name, "testType")) - { - testTypeStr = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Operate.Name) || StringUtils.EqualsIgnoreCase(name, "testOperate")) - { - testOperate = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Value.Name) || StringUtils.EqualsIgnoreCase(name, "testValue")) - { - testValue = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Context.Name)) - { - contextInfo.ContextType = EContextTypeUtils.GetEnumType(value); - } - } - - return ParseImpl(pageInfo, contextInfo, testTypeStr, testOperate, testValue); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string testType, string testOperate, string testValue) - { - string successTemplateString; - string failureTemplateString; - - StlInnerUtility.GetYesNo(contextInfo.InnerXml, out successTemplateString, out failureTemplateString); - - if (StringUtils.EqualsIgnoreCase(testType, TypeIsUserLoggin) || - StringUtils.EqualsIgnoreCase(testType, TypeIsAdministratorLoggin) || - StringUtils.EqualsIgnoreCase(testType, TypeIsUserOrAdministratorLoggin)) - { - StlParserManager.ParseInnerContent(new StringBuilder(successTemplateString), pageInfo, contextInfo); - StlParserManager.ParseInnerContent(new StringBuilder(failureTemplateString), pageInfo, contextInfo); - - return TestTypeDynamic(pageInfo, contextInfo, testType, testValue, testOperate, successTemplateString, - failureTemplateString); - } - - var isSuccess = false; - if (StringUtils.EqualsIgnoreCase(testType, TypeChannelName)) - { - var channelName = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId).ChannelName; - isSuccess = TestTypeValue(testOperate, testValue, channelName); - } - else if (StringUtils.EqualsIgnoreCase(testType, TypeChannelIndex)) - { - var channelIndex = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId).IndexName; - isSuccess = TestTypeValue(testOperate, testValue, channelIndex); - } - else if (StringUtils.EqualsIgnoreCase(testType, TypeTemplateName)) - { - isSuccess = TestTypeValue(testOperate, testValue, pageInfo.TemplateInfo.TemplateName); - } - else if (StringUtils.EqualsIgnoreCase(testType, TypTemplateType)) - { - isSuccess = TestTypeValue(testOperate, testValue, pageInfo.TemplateInfo.TemplateType.Value); - } - else if (StringUtils.EqualsIgnoreCase(testType, TypeTopLevel)) - { - var topLevel = ChannelManager.GetTopLevel(pageInfo.SiteId, contextInfo.ChannelId); - isSuccess = IsNumber(topLevel, testOperate, testValue); - } - else if (StringUtils.EqualsIgnoreCase(testType, TypeUpChannel)) - { - isSuccess = TestTypeUpChannel(pageInfo, contextInfo, testOperate, testValue); - } - else if (StringUtils.EqualsIgnoreCase(testType, TypeUpChannelOrSelf)) - { - isSuccess = TestTypeUpChannelOrSelf(pageInfo, contextInfo, testOperate, testValue); - } - else if (StringUtils.EqualsIgnoreCase(testType, TypeSelfChannel)) - { - isSuccess = pageInfo.PageChannelId == contextInfo.ChannelId; - } - else if (StringUtils.EqualsIgnoreCase(testType, TypeGroupChannel)) - { - var groupChannels = - TranslateUtils.StringCollectionToStringList( - ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId).GroupNameCollection); - isSuccess = TestTypeValues(testOperate, testValue, groupChannels); - } - else if (StringUtils.EqualsIgnoreCase(testType, TypeGroupContent)) - { - if (contextInfo.ContextType == EContextType.Content) - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, contextInfo.ChannelId); - //var groupContents = TranslateUtils.StringCollectionToStringList(DataProvider.ContentDao.GetValue(tableName, contextInfo.ContentId, ContentAttribute.ContentGroupNameCollection)); - var groupContents = TranslateUtils.StringCollectionToStringList(Content.GetValue(tableName, contextInfo.ContentId, ContentAttribute.GroupNameCollection)); - isSuccess = TestTypeValues(testOperate, testValue, groupContents); - } - } - else if (StringUtils.EqualsIgnoreCase(testType, TypeAddDate)) - { - var addDate = GetAddDateByContext(pageInfo, contextInfo); - isSuccess = IsDateTime(addDate, testOperate, testValue); - } - else if (StringUtils.EqualsIgnoreCase(testType, TypeLastEditDate)) - { - var lastEditDate = GetLastEditDateByContext(pageInfo, contextInfo); - isSuccess = IsDateTime(lastEditDate, testOperate, testValue); - } - else if (StringUtils.EqualsIgnoreCase(testType, TypeItemIndex)) - { - var itemIndex = StlParserUtility.GetItemIndex(contextInfo); - isSuccess = IsNumber(itemIndex, testOperate, testValue); - } - else if (StringUtils.EqualsIgnoreCase(testType, TypeOddItem)) - { - var itemIndex = StlParserUtility.GetItemIndex(contextInfo); - isSuccess = itemIndex % 2 == 1; - } - else - { - isSuccess = TestTypeDefault(pageInfo, contextInfo, testType, testOperate, testValue); - } - - var parsedContent = isSuccess ? successTemplateString : failureTemplateString; - - if (string.IsNullOrEmpty(parsedContent)) return string.Empty; - - var innerBuilder = new StringBuilder(parsedContent); - StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); - - parsedContent = innerBuilder.ToString(); - - return parsedContent; - } - - private static bool TestTypeDefault(PageInfo pageInfo, ContextInfo contextInfo, string testType, string testOperate, - string testValue) - { - var isSuccess = false; - - var theValue = GetAttributeValueByContext(pageInfo, contextInfo, testType); - - if (StringUtils.IsDateTime(theValue)) - { - var dateTime = TranslateUtils.ToDateTime(theValue); - isSuccess = IsDateTime(dateTime, testOperate, testValue); - } - else if (StringUtils.IsNumber(theValue)) - { - var number = TranslateUtils.ToInt(theValue); - isSuccess = IsNumber(number, testOperate, testValue); - } - else - { - if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotEmpty)) - { - if (!string.IsNullOrEmpty(theValue)) - { - isSuccess = true; - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateEmpty)) - { - if (string.IsNullOrEmpty(theValue)) - { - isSuccess = true; - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateEquals)) - { - if (StringUtils.EqualsIgnoreCase(theValue, testValue)) - { - isSuccess = true; - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotEquals)) - { - if (!StringUtils.EqualsIgnoreCase(theValue, testValue)) - { - isSuccess = true; - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateGreatThan)) - { - if (StringUtils.Contains(theValue, "-")) - { - if (TranslateUtils.ToDateTime(theValue) > TranslateUtils.ToDateTime(testValue)) - { - isSuccess = true; - } - } - else - { - if (TranslateUtils.ToInt(theValue) > TranslateUtils.ToInt(testValue)) - { - isSuccess = true; - } - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateLessThan)) - { - if (StringUtils.Contains(theValue, "-")) - { - if (TranslateUtils.ToDateTime(theValue) < TranslateUtils.ToDateTime(testValue)) - { - isSuccess = true; - } - } - else - { - if (TranslateUtils.ToInt(theValue) < TranslateUtils.ToInt(testValue)) - { - isSuccess = true; - } - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateIn)) - { - var stringList = TranslateUtils.StringCollectionToStringList(testValue); - - foreach (var str in stringList) - { - if (StringUtils.EndsWithIgnoreCase(str, "*")) - { - var theStr = str.Substring(0, str.Length - 1); - if (StringUtils.StartsWithIgnoreCase(theValue, theStr)) - { - isSuccess = true; - break; - } - } - else - { - if (StringUtils.EqualsIgnoreCase(theValue, str)) - { - isSuccess = true; - break; - } - } - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotIn)) - { - var stringList = TranslateUtils.StringCollectionToStringList(testValue); - - var isIn = false; - foreach (var str in stringList) - { - if (StringUtils.EndsWithIgnoreCase(str, "*")) - { - var theStr = str.Substring(0, str.Length - 1); - if (StringUtils.StartsWithIgnoreCase(theValue, theStr)) - { - isIn = true; - break; - } - } - else - { - if (StringUtils.EqualsIgnoreCase(theValue, str)) - { - isIn = true; - break; - } - } - } - if (!isIn) - { - isSuccess = true; - } - } - } - return isSuccess; - } - - private static string TestTypeDynamic(PageInfo pageInfo, ContextInfo contextInfo, string testType, string testValue, string testOperate, string successTemplateString, string failureTemplateString) - { - pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.StlClient); - - var ajaxDivId = StlParserUtility.GetAjaxDivId(pageInfo.UniqueId); - - var functionName = $"stlIf_{ajaxDivId}"; - - if (string.IsNullOrEmpty(successTemplateString) && string.IsNullOrEmpty(failureTemplateString)) - { - return string.Empty; - } - - var pageUrl = StlParserUtility.GetStlCurrentUrl(pageInfo.SiteInfo, contextInfo.ChannelId, contextInfo.ContentId, contextInfo.ContentInfo, pageInfo.TemplateInfo.TemplateType, pageInfo.TemplateInfo.Id, pageInfo.IsLocal); - - var ifApiUrl = ApiRouteActionsIf.GetUrl(pageInfo.ApiUrl); - var ifApiParms = ApiRouteActionsIf.GetParameters(pageInfo.SiteId, contextInfo.ChannelId, contextInfo.ContentId, pageInfo.TemplateInfo.Id, ajaxDivId, pageUrl, testType, testValue, testOperate, successTemplateString, failureTemplateString); - - var builder = new StringBuilder(); - builder.Append($@""); - - builder.Append($@" - -"); - - return builder.ToString(); - } - - public static bool TestTypeValues(string testOperate, string testValue, List actualValues) - { - var isSuccess = false; - - if (StringUtils.EqualsIgnoreCase(testOperate, OperateEquals) || - StringUtils.EqualsIgnoreCase(testOperate, OperateIn)) - { - var stringArrayList = TranslateUtils.StringCollectionToStringList(testValue); - - foreach (string str in stringArrayList) - { - if (actualValues.Contains(str)) - { - isSuccess = true; - break; - } - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotEquals) || - StringUtils.EqualsIgnoreCase(testOperate, OperateNotIn)) - { - var stringArrayList = TranslateUtils.StringCollectionToStringList(testValue); - - var isIn = false; - foreach (string str in stringArrayList) - { - if (actualValues.Contains(str)) - { - isIn = true; - break; - } - } - if (!isIn) - { - isSuccess = true; - } - } - return isSuccess; - } - - private static bool TestTypeUpChannelOrSelf(PageInfo pageInfo, ContextInfo contextInfo, string testOperate, - string testValue) - { - var isSuccess = false; - - if (StringUtils.EqualsIgnoreCase(testOperate, OperateIn)) - { - var channelIndexes = TranslateUtils.StringCollectionToStringList(testValue); - var isIn = false; - foreach (var channelIndex in channelIndexes) - { - //var parentId = DataProvider.ChannelDao.GetIdByIndexName(pageInfo.SiteId, channelIndex); - var parentId = Node.GetIdByIndexName(pageInfo.SiteId, channelIndex); - if (ChannelManager.IsAncestorOrSelf(pageInfo.SiteId, parentId, pageInfo.PageChannelId)) - { - isIn = true; - break; - } - } - if (isIn) - { - isSuccess = true; - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotIn)) - { - var channelIndexes = TranslateUtils.StringCollectionToStringList(testValue); - var isIn = false; - foreach (var channelIndex in channelIndexes) - { - //var parentId = DataProvider.ChannelDao.GetIdByIndexName(pageInfo.SiteId, channelIndex); - var parentId = Node.GetIdByIndexName(pageInfo.SiteId, channelIndex); - if (ChannelManager.IsAncestorOrSelf(pageInfo.SiteId, parentId, pageInfo.PageChannelId)) - { - isIn = true; - break; - } - } - if (!isIn) - { - isSuccess = true; - } - } - else - { - if (string.IsNullOrEmpty(testValue)) - { - if (ChannelManager.IsAncestorOrSelf(pageInfo.SiteId, contextInfo.ChannelId, pageInfo.PageChannelId)) - { - isSuccess = true; - } - } - else - { - var channelIndexes = TranslateUtils.StringCollectionToStringList(testValue); - foreach (var channelIndex in channelIndexes) - { - //var parentId = DataProvider.ChannelDao.GetIdByIndexName(pageInfo.SiteId, channelIndex); - var parentId = Node.GetIdByIndexName(pageInfo.SiteId, channelIndex); - if (ChannelManager.IsAncestorOrSelf(pageInfo.SiteId, parentId, pageInfo.PageChannelId)) - { - isSuccess = true; - break; - } - } - } - } - return isSuccess; - } - - private static bool TestTypeUpChannel(PageInfo pageInfo, ContextInfo contextInfo, string testOperate, string testValue) - { - var isSuccess = false; - - if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotIn)) - { - var channelIndexes = TranslateUtils.StringCollectionToStringList(testValue); - var isIn = false; - foreach (var channelIndex in channelIndexes) - { - //var parentId = DataProvider.ChannelDao.GetIdByIndexName(pageInfo.SiteId, channelIndex); - var parentId = Node.GetIdByIndexName(pageInfo.SiteId, channelIndex); - if (parentId != pageInfo.PageChannelId && - ChannelManager.IsAncestorOrSelf(pageInfo.SiteId, parentId, pageInfo.PageChannelId)) - { - isIn = true; - break; - } - } - if (!isIn) - { - isSuccess = true; - } - } - else - { - if (string.IsNullOrEmpty(testValue)) - { - if (contextInfo.ChannelId != pageInfo.PageChannelId && - ChannelManager.IsAncestorOrSelf(pageInfo.SiteId, contextInfo.ChannelId, pageInfo.PageChannelId)) - { - isSuccess = true; - } - } - else - { - var channelIndexes = TranslateUtils.StringCollectionToStringList(testValue); - foreach (var channelIndex in channelIndexes) - { - //var parentId = DataProvider.ChannelDao.GetIdByIndexName(pageInfo.SiteId, channelIndex); - var parentId = Node.GetIdByIndexName(pageInfo.SiteId, channelIndex); - if (parentId != pageInfo.PageChannelId && - ChannelManager.IsAncestorOrSelf(pageInfo.SiteId, parentId, pageInfo.PageChannelId)) - { - isSuccess = true; - break; - } - } - } - } - return isSuccess; - } - - public static bool TestTypeValue(string testOperate, string testValue, string actualValue) - { - var isSuccess = false; - if (StringUtils.EqualsIgnoreCase(testOperate, OperateEquals)) - { - if (StringUtils.EndsWithIgnoreCase(testValue, "*")) - { - var theStr = testValue.Substring(0, testValue.Length - 1); - if (StringUtils.StartsWithIgnoreCase(actualValue, theStr)) - { - isSuccess = true; - } - } - else - { - if (StringUtils.EqualsIgnoreCase(actualValue, testValue)) - { - isSuccess = true; - } - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotEquals)) - { - if (!StringUtils.EqualsIgnoreCase(actualValue, testValue)) - { - isSuccess = true; - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateIn)) - { - var stringList = TranslateUtils.StringCollectionToStringList(testValue); - - foreach (var str in stringList) - { - if (StringUtils.EndsWithIgnoreCase(str, "*")) - { - var theStr = str.Substring(0, str.Length - 1); - if (StringUtils.StartsWithIgnoreCase(actualValue, theStr)) - { - isSuccess = true; - break; - } - } - else - { - if (StringUtils.EqualsIgnoreCase(actualValue, str)) - { - isSuccess = true; - break; - } - } - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotIn)) - { - var stringList = TranslateUtils.StringCollectionToStringList(testValue); - - var isIn = false; - foreach (var str in stringList) - { - if (StringUtils.EndsWithIgnoreCase(str, "*")) - { - var theStr = str.Substring(0, str.Length - 1); - if (StringUtils.StartsWithIgnoreCase(actualValue, theStr)) - { - isIn = true; - break; - } - } - else - { - if (StringUtils.EqualsIgnoreCase(actualValue, str)) - { - isIn = true; - break; - } - } - } - if (!isIn) - { - isSuccess = true; - } - } - return isSuccess; - } - - private static string GetAttributeValueByContext(PageInfo pageInfo, ContextInfo contextInfo, string testTypeStr) - { - string theValue = null; - if (contextInfo.ContextType == EContextType.Content) - { - theValue = GetValueFromContent(pageInfo, contextInfo, testTypeStr); - } - else if (contextInfo.ContextType == EContextType.Channel) - { - theValue = GetValueFromChannel(pageInfo, contextInfo, testTypeStr); - } - else if (contextInfo.ContextType == EContextType.SqlContent) - { - if (contextInfo.ItemContainer.SqlItem != null) - { - theValue = DataBinder.Eval(contextInfo.ItemContainer.SqlItem.DataItem, testTypeStr, "{0}"); - } - } - else if (contextInfo.ContextType == EContextType.Site) - { - if (contextInfo.ItemContainer.SiteItem != null) - { - theValue = DataBinder.Eval(contextInfo.ItemContainer.SiteItem.DataItem, testTypeStr, "{0}"); - } - } - else - { - if (contextInfo.ItemContainer != null) - { - //else if (contextInfo.ItemContainer.InputItem != null) - //{ - // theValue = DataBinder.Eval(contextInfo.ItemContainer.InputItem.DataItem, testTypeStr, "{0}"); - //} - //else if (contextInfo.ItemContainer.ContentItem != null) - //{ - // theValue = DataBinder.Eval(contextInfo.ItemContainer.ContentItem.DataItem, testTypeStr, "{0}"); - //} - //else if (contextInfo.ItemContainer.ChannelItem != null) - //{ - // theValue = DataBinder.Eval(contextInfo.ItemContainer.ChannelItem.DataItem, testTypeStr, "{0}"); - //} - if (contextInfo.ItemContainer.SqlItem != null) - { - theValue = DataBinder.Eval(contextInfo.ItemContainer.SqlItem.DataItem, testTypeStr, "{0}"); - } - } - else if (contextInfo.ContentId != 0)//获取内容 - { - theValue = GetValueFromContent(pageInfo, contextInfo, testTypeStr); - } - else if (contextInfo.ChannelId != 0)//获取栏目 - { - theValue = GetValueFromChannel(pageInfo, contextInfo, testTypeStr); - } - } - - return theValue ?? string.Empty; - } - - private static string GetValueFromChannel(PageInfo pageInfo, ContextInfo contextInfo, string testTypeStr) - { - string theValue; - - var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); - - if (StringUtils.EqualsIgnoreCase(ChannelAttribute.AddDate, testTypeStr)) - { - theValue = DateUtils.GetDateAndTimeString(channel.AddDate); - } - else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.Title, testTypeStr)) - { - theValue = channel.ChannelName; - } - else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.ImageUrl, testTypeStr)) - { - theValue = channel.ImageUrl; - } - else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.Content, testTypeStr)) - { - theValue = channel.Content; - } - else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.CountOfChannels, testTypeStr)) - { - theValue = channel.ChildrenCount.ToString(); - } - else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.CountOfContents, testTypeStr)) - { - theValue = channel.ContentNum.ToString(); - } - else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.CountOfImageContents, testTypeStr)) - { - //var count = DataProvider.BackgroundContentDao.GetCountCheckedImage(pageInfo.SiteId, channel.ChannelId); - var count = Content.GetCountCheckedImage(pageInfo.SiteId, channel.Id); - theValue = count.ToString(); - } - else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.LinkUrl, testTypeStr)) - { - theValue = channel.LinkUrl; - } - else - { - theValue = channel.Additional.GetString(testTypeStr); - } - return theValue; - } - - private static string GetValueFromContent(PageInfo pageInfo, ContextInfo contextInfo, string testTypeStr) - { - string theValue; - - if (contextInfo.ContentInfo == null) - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, contextInfo.ChannelId); - //theValue = DataProvider.ContentDao.GetValue(tableName, contextInfo.ContentId, testTypeStr); - theValue = Content.GetValue(tableName, contextInfo.ContentId, testTypeStr); - } - else - { - theValue = contextInfo.ContentInfo.GetString(testTypeStr); - } - - return theValue; - } - - private static DateTime GetAddDateByContext(PageInfo pageInfo, ContextInfo contextInfo) - { - var addDate = DateUtils.SqlMinValue; - - if (contextInfo.ContextType == EContextType.Content) - { - if (contextInfo.ContentInfo == null) - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, contextInfo.ChannelId); - //addDate = DataProvider.ContentDao.GetAddDate(tableName, contextInfo.ContentId); - addDate = Content.GetAddDate(tableName, contextInfo.ContentId); - } - else - { - addDate = contextInfo.ContentInfo.AddDate; - } - } - else if (contextInfo.ContextType == EContextType.Channel) - { - var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); - - addDate = channel.AddDate; - } - else - { - if (contextInfo.ItemContainer != null) - { - //else if (contextInfo.ItemContainer.InputItem != null) - //{ - // addDate = (DateTime)DataBinder.Eval(contextInfo.ItemContainer.InputItem.DataItem, InputContentAttribute.AddDate); - //} - //else if (contextInfo.ItemContainer.ContentItem != null) - //{ - // addDate = (DateTime)DataBinder.Eval(contextInfo.ItemContainer.ContentItem.DataItem, ContentAttribute.AddDate); - //} - //else if (contextInfo.ItemContainer.ChannelItem != null) - //{ - // addDate = (DateTime)DataBinder.Eval(contextInfo.ItemContainer.ChannelItem.DataItem, NodeAttribute.AddDate); - //} - if (contextInfo.ItemContainer.SqlItem != null) - { - addDate = (DateTime)DataBinder.Eval(contextInfo.ItemContainer.SqlItem.DataItem, "AddDate"); - } - } - else if (contextInfo.ContentId != 0)//获取内容 - { - if (contextInfo.ContentInfo == null) - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, contextInfo.ChannelId); - //addDate = DataProvider.ContentDao.GetAddDate(tableName, contextInfo.ContentId); - addDate = Content.GetAddDate(tableName, contextInfo.ContentId); - } - else - { - addDate = contextInfo.ContentInfo.AddDate; - } - } - else if (contextInfo.ChannelId != 0)//获取栏目 - { - var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); - addDate = channel.AddDate; - } - } - - return addDate; - } - - private static DateTime GetLastEditDateByContext(PageInfo pageInfo, ContextInfo contextInfo) - { - var lastEditDate = DateUtils.SqlMinValue; - - if (contextInfo.ContextType == EContextType.Content) - { - if (contextInfo.ContentInfo == null) - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, contextInfo.ChannelId); - //lastEditDate = DataProvider.ContentDao.GetLastEditDate(tableName, contextInfo.ContentId); - lastEditDate = Content.GetLastEditDate(tableName, contextInfo.ContentId); - } - else - { - lastEditDate = contextInfo.ContentInfo.LastEditDate; - } - } - - return lastEditDate; - } - - private static bool IsNumber(int number, string testOperate, string testValue) - { - var isSuccess = false; - if (StringUtils.EqualsIgnoreCase(testOperate, OperateEquals)) - { - if (number == TranslateUtils.ToInt(testValue)) - { - isSuccess = true; - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotEquals)) - { - if (number != TranslateUtils.ToInt(testValue)) - { - isSuccess = true; - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateGreatThan)) - { - if (number > TranslateUtils.ToInt(testValue)) - { - isSuccess = true; - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateLessThan)) - { - if (number < TranslateUtils.ToInt(testValue)) - { - isSuccess = true; - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateIn)) - { - var intArrayList = TranslateUtils.StringCollectionToIntList(testValue); - foreach (int i in intArrayList) - { - if (i == number) - { - isSuccess = true; - break; - } - } - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateIn)) - { - var intArrayList = TranslateUtils.StringCollectionToIntList(testValue); - var isIn = false; - foreach (int i in intArrayList) - { - if (i == number) - { - isIn = true; - break; - } - } - if (!isIn) - { - isSuccess = true; - } - } - return isSuccess; - } - - private static bool IsDateTime(DateTime dateTime, string testOperate, string testValue) - { - var isSuccess = false; - - DateTime dateTimeToTest; - - if (StringUtils.EqualsIgnoreCase("now", testValue)) - { - dateTimeToTest = DateTime.Now; - } - else if (DateUtils.IsSince(testValue)) - { - var hours = DateUtils.GetSinceHours(testValue); - dateTimeToTest = DateTime.Now.AddHours(-hours); - } - else - { - dateTimeToTest = TranslateUtils.ToDateTime(testValue); - } - - if (StringUtils.EqualsIgnoreCase(testOperate, OperateEquals) || StringUtils.EqualsIgnoreCase(testOperate, OperateIn)) - { - isSuccess = dateTime.Date == dateTimeToTest.Date; - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateGreatThan)) - { - isSuccess = dateTime > dateTimeToTest; - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateLessThan)) - { - isSuccess = dateTime < dateTimeToTest; - } - else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotEquals) || StringUtils.EqualsIgnoreCase(testOperate, OperateNotIn)) - { - isSuccess = dateTime.Date != dateTimeToTest.Date; - } - - return isSuccess; - } - } -} - diff --git a/SiteServer.CMS/StlParser/StlElement/StlImage.cs b/SiteServer.CMS/StlParser/StlElement/StlImage.cs deleted file mode 100644 index b5275d96b..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlImage.cs +++ /dev/null @@ -1,241 +0,0 @@ -using System.Web.UI.HtmlControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Parsers; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "显示图片", Description = "通过 stl:image 标签在模板中显示栏目或内容的图片")] - public class StlImage - { - private StlImage(){} - public const string ElementName = "stl:image"; - - private static readonly Attr ChannelIndex = new Attr("channelIndex", "栏目索引"); - private static readonly Attr ChannelName = new Attr("channelName", "栏目名称"); - private static readonly Attr No = new Attr("no", "显示字段的顺序"); - private static readonly Attr Parent = new Attr("parent", "显示父栏目"); - private static readonly Attr UpLevel = new Attr("upLevel", "上级栏目的级别"); - private static readonly Attr TopLevel = new Attr("topLevel", "从首页向下的栏目级别"); - private static readonly Attr Type = new Attr("type", "指定存储图片的字段"); - private static readonly Attr IsOriginal = new Attr("isOriginal", "如果是引用内容,是否获取所引用内容的值"); - private static readonly Attr Src = new Attr("src", "显示的图片地址"); - private static readonly Attr AltSrc = new Attr("altSrc", "当指定的图片不存在时显示的图片地址"); - private static readonly Attr Width = new Attr("width", "宽度"); - private static readonly Attr Height = new Attr("height", "高度"); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var isGetPicUrlFromAttribute = false; - var channelIndex = string.Empty; - var channelName = string.Empty; - var no = 0; - var upLevel = 0; - var topLevel = -1; - var type = BackgroundContentAttribute.ImageUrl; - var isOriginal = false; - var src = string.Empty; - var altSrc = string.Empty; - var stlImage = new HtmlImage(); - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, ChannelIndex.Name)) - { - channelIndex = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - if (!string.IsNullOrEmpty(channelIndex)) - { - isGetPicUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, ChannelName.Name)) - { - channelName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - if (!string.IsNullOrEmpty(channelName)) - { - isGetPicUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, No.Name)) - { - no = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Parent.Name)) - { - if (TranslateUtils.ToBool(value)) - { - upLevel = 1; - isGetPicUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, UpLevel.Name)) - { - upLevel = TranslateUtils.ToInt(value); - if (upLevel > 0) - { - isGetPicUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, TopLevel.Name)) - { - topLevel = TranslateUtils.ToInt(value); - if (topLevel >= 0) - { - isGetPicUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, Type.Name)) - { - type = value; - } - else if (StringUtils.EqualsIgnoreCase(name, IsOriginal.Name)) - { - isOriginal = TranslateUtils.ToBool(value, true); - } - else if (StringUtils.EqualsIgnoreCase(name, Src.Name)) - { - src = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, AltSrc.Name)) - { - altSrc = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else - { - stlImage.Attributes[name] = value; - } - } - - return ParseImpl(pageInfo, contextInfo, stlImage, isGetPicUrlFromAttribute, channelIndex, channelName, no, upLevel, topLevel, type, isOriginal, src, altSrc); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, HtmlImage stlImage, bool isGetPicUrlFromAttribute, string channelIndex, string channelName, int no, int upLevel, int topLevel, string type, bool isOriginal, string src, string altSrc) - { - var parsedContent = string.Empty; - - var contentId = 0; - //判断是否图片地址由标签属性获得 - if (!isGetPicUrlFromAttribute) - { - contentId = contextInfo.ContentId; - } - var contextType = contextInfo.ContextType; - - var picUrl = string.Empty; - if (!string.IsNullOrEmpty(src)) - { - picUrl = src; - } - else - { - if (contextType == EContextType.Undefined) - { - contextType = contentId != 0 ? EContextType.Content : EContextType.Channel; - } - - if (contextType == EContextType.Content)//获取内容图片 - { - var contentInfo = contextInfo.ContentInfo; - - if (isOriginal) - { - if (contentInfo != null && contentInfo.ReferenceId > 0 && contentInfo.SourceId > 0) - { - var targetChannelId = contentInfo.SourceId; - //var targetSiteId = DataProvider.ChannelDao.GetSiteId(targetChannelId); - var targetSiteId = Node.GetSiteId(targetChannelId); - var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); - var targetNodeInfo = ChannelManager.GetChannelInfo(targetSiteId, targetChannelId); - - var tableName = ChannelManager.GetTableName(targetSiteInfo, targetNodeInfo); - //var targetContentInfo = DataProvider.ContentDao.GetContentInfo(tableStyle, tableName, contentInfo.ReferenceId); - var targetContentInfo = Content.GetContentInfo(tableName, contentInfo.ReferenceId); - if (targetContentInfo != null && targetContentInfo.ChannelId > 0) - { - contentInfo = targetContentInfo; - } - } - } - - if (contentInfo == null) - { - //contentInfo = DataProvider.ContentDao.GetContentInfo(ETableStyle.BackgroundContent, pageInfo.SiteInfo.AuxiliaryTableForContent, contentId); - contentInfo = Content.GetContentInfo(pageInfo.SiteInfo.TableName, contentId); - } - - if (contentInfo != null) - { - if (no <= 1) - { - picUrl = contentInfo.GetString(type); - } - else - { - var extendAttributeName = ContentAttribute.GetExtendAttributeName(type); - var extendValues = contentInfo.GetString(extendAttributeName); - if (!string.IsNullOrEmpty(extendValues)) - { - var index = 2; - foreach (var extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) - { - if (index == no) - { - picUrl = extendValue; - break; - } - index++; - } - } - } - } - } - else if (contextType == EContextType.Channel)//获取栏目图片 - { - var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); - - channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, channelIndex, channelName); - - var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); - - picUrl = channel.ImageUrl; - } - else if (contextType == EContextType.Each) - { - picUrl = contextInfo.ItemContainer.EachItem.DataItem as string; - } - } - - if (string.IsNullOrEmpty(picUrl)) - { - picUrl = altSrc; - } - - if (!string.IsNullOrEmpty(picUrl)) - { - var extension = PathUtils.GetExtension(picUrl); - if (EFileSystemTypeUtils.IsFlash(extension)) - { - parsedContent = StlFlash.Parse(pageInfo, contextInfo); - } - else if (EFileSystemTypeUtils.IsPlayer(extension)) - { - parsedContent = StlPlayer.Parse(pageInfo, contextInfo); - } - else - { - stlImage.Src = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, picUrl, pageInfo.IsLocal); - parsedContent = ControlUtils.GetControlRenderHtml(stlImage); - } - } - - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlLoading.cs b/SiteServer.CMS/StlParser/StlElement/StlLoading.cs deleted file mode 100644 index 57c045b78..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlLoading.cs +++ /dev/null @@ -1,10 +0,0 @@ -using SiteServer.CMS.StlParser.Model; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "载入模板", Description = "通过 stl:loading 标签在模板中创建载入中显示的内容")] - public sealed class StlLoading - { - public const string ElementName = "stl:loading"; - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlNo.cs b/SiteServer.CMS/StlParser/StlElement/StlNo.cs deleted file mode 100644 index 00876d486..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlNo.cs +++ /dev/null @@ -1,11 +0,0 @@ -using SiteServer.CMS.StlParser.Model; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "失败模板", Description = "通过 stl:no 标签在模板中显示失败模板")] - public sealed class StlNo - { - public const string ElementName = "stl:no"; - public const string ElementName2 = "stl:failuretemplate"; - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlPageChannels.cs b/SiteServer.CMS/StlParser/StlElement/StlPageChannels.cs deleted file mode 100644 index a6c461117..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlPageChannels.cs +++ /dev/null @@ -1,204 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Web.UI.WebControls; -using System.Xml; -using SiteServer.Utils; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "翻页栏目列表", Description = "通过 stl:pageChannels 标签在模板中显示翻页栏目列表")] - public class StlPageChannels : StlChannels - { - public new const string ElementName = "stl:pageChannels"; - - private static readonly Attr PageNum = new Attr("pageNum", "每页显示的栏目数目"); - - private readonly string _stlPageChannelsElement; - private readonly XmlNode _node; - private readonly PageInfo _pageInfo; - private readonly ContextInfo _contextInfo; - private readonly DataSet _dataSet; - - public StlPageChannels(string stlPageChannelsElement, PageInfo pageInfo, ContextInfo contextInfo, bool isXmlContent) - { - _stlPageChannelsElement = stlPageChannelsElement; - _pageInfo = pageInfo; - var xmlDocument = StlParserUtility.GetXmlDocument(_stlPageChannelsElement, isXmlContent); - _node = xmlDocument.DocumentElement; - _node = _node?.FirstChild; - - var attributes = new Dictionary(); - var ie = _node?.Attributes?.GetEnumerator(); - if (ie != null) - { - while (ie.MoveNext()) - { - var attr = (XmlAttribute)ie.Current; - - var key = attr.Name; - if (!string.IsNullOrEmpty(key)) - { - var value = attr.Value; - if (string.IsNullOrEmpty(value)) - { - value = string.Empty; - } - attributes[key] = value; - } - } - } - - _contextInfo = contextInfo.Clone(stlPageChannelsElement, attributes, _node?.InnerXml, _node?.ChildNodes); - - DisplayInfo = ListInfo.GetListInfoByXmlNode(pageInfo, _contextInfo, EContextType.Channel); - - var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, _contextInfo.ChannelId, DisplayInfo.UpLevel, DisplayInfo.TopLevel); - - channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, DisplayInfo.ChannelIndex, DisplayInfo.ChannelName); - - var isTotal = TranslateUtils.ToBool(DisplayInfo.Others.Get(IsTotal.Name)); - - if (TranslateUtils.ToBool(DisplayInfo.Others.Get(IsAllChildren.Name))) - { - DisplayInfo.Scope = EScopeType.Descendant; - } - - _dataSet = StlDataUtility.GetPageChannelsDataSet(pageInfo.SiteId, channelId, DisplayInfo.GroupChannel, DisplayInfo.GroupChannelNot, DisplayInfo.IsImageExists, DisplayInfo.IsImage, DisplayInfo.StartNum, DisplayInfo.TotalNum, DisplayInfo.OrderByString, DisplayInfo.Scope, isTotal, DisplayInfo.Where); - } - - - public int GetPageCount(out int totalNum) - { - var pageCount = 1; - totalNum = 0;//数据库中实际的内容数目 - if (_dataSet == null) return pageCount; - - totalNum = _dataSet.Tables[0].DefaultView.Count; - if (DisplayInfo.PageNum != 0 && DisplayInfo.PageNum < totalNum)//需要翻页 - { - pageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(totalNum) / Convert.ToDouble(DisplayInfo.PageNum)));//需要生成的总页数 - } - return pageCount; - } - - public ListInfo DisplayInfo { get; } - - public string Parse(int currentPageIndex, int pageCount) - { - var parsedContent = string.Empty; - - _contextInfo.PageItemIndex = currentPageIndex * DisplayInfo.PageNum; - - try - { - if (_node != null) - { - if (_dataSet != null) - { - var objPage = new PagedDataSource {DataSource = _dataSet.Tables[0].DefaultView}; //分页类 - - if (pageCount > 1) - { - objPage.AllowPaging = true; - objPage.PageSize = DisplayInfo.PageNum;//每页显示的项数 - } - else - { - objPage.AllowPaging = false; - } - - objPage.CurrentPageIndex = currentPageIndex;//当前页的索引 - - - if (DisplayInfo.Layout == ELayout.None) - { - var rptContents = new Repeater - { - ItemTemplate = - new RepeaterTemplate(DisplayInfo.ItemTemplate, DisplayInfo.SelectedItems, - DisplayInfo.SelectedValues, DisplayInfo.SeparatorRepeatTemplate, - DisplayInfo.SeparatorRepeat, _pageInfo, EContextType.Channel, _contextInfo) - }; - - if (!string.IsNullOrEmpty(DisplayInfo.HeaderTemplate)) - { - rptContents.HeaderTemplate = new SeparatorTemplate(DisplayInfo.HeaderTemplate); - } - if (!string.IsNullOrEmpty(DisplayInfo.FooterTemplate)) - { - rptContents.FooterTemplate = new SeparatorTemplate(DisplayInfo.FooterTemplate); - } - if (!string.IsNullOrEmpty(DisplayInfo.SeparatorTemplate)) - { - rptContents.SeparatorTemplate = new SeparatorTemplate(DisplayInfo.SeparatorTemplate); - } - if (!string.IsNullOrEmpty(DisplayInfo.AlternatingItemTemplate)) - { - rptContents.AlternatingItemTemplate = new RepeaterTemplate(DisplayInfo.AlternatingItemTemplate, DisplayInfo.SelectedItems, DisplayInfo.SelectedValues, DisplayInfo.SeparatorRepeatTemplate, DisplayInfo.SeparatorRepeat, _pageInfo, EContextType.Channel, _contextInfo); - } - - rptContents.DataSource = objPage; - rptContents.DataBind(); - - if (rptContents.Items.Count > 0) - { - parsedContent = ControlUtils.GetControlRenderHtml(rptContents); - } - } - else - { - var pdlContents = new ParsedDataList(); - - //设置显示属性 - TemplateUtility.PutListInfoToMyDataList(pdlContents, DisplayInfo); - - //设置列表模板 - pdlContents.ItemTemplate = new DataListTemplate(DisplayInfo.ItemTemplate, DisplayInfo.SelectedItems, DisplayInfo.SelectedValues, DisplayInfo.SeparatorRepeatTemplate, DisplayInfo.SeparatorRepeat, _pageInfo, EContextType.Channel, _contextInfo); - if (!string.IsNullOrEmpty(DisplayInfo.HeaderTemplate)) - { - pdlContents.HeaderTemplate = new SeparatorTemplate(DisplayInfo.HeaderTemplate); - } - if (!string.IsNullOrEmpty(DisplayInfo.FooterTemplate)) - { - pdlContents.FooterTemplate = new SeparatorTemplate(DisplayInfo.FooterTemplate); - } - if (!string.IsNullOrEmpty(DisplayInfo.SeparatorTemplate)) - { - pdlContents.SeparatorTemplate = new SeparatorTemplate(DisplayInfo.SeparatorTemplate); - } - if (!string.IsNullOrEmpty(DisplayInfo.AlternatingItemTemplate)) - { - pdlContents.AlternatingItemTemplate = new DataListTemplate(DisplayInfo.AlternatingItemTemplate, DisplayInfo.SelectedItems, DisplayInfo.SelectedValues, DisplayInfo.SeparatorRepeatTemplate, DisplayInfo.SeparatorRepeat, _pageInfo, EContextType.Channel, _contextInfo); - } - - pdlContents.DataSource = objPage; - pdlContents.DataKeyField = ChannelAttribute.Id; - pdlContents.DataBind(); - - if (pdlContents.Items.Count > 0) - { - parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); - } - } - } - } - } - catch (Exception ex) - { - parsedContent = StlParserUtility.GetStlErrorMessage(ElementName, _stlPageChannelsElement, ex); - } - - //还原翻页为0,使得其他列表能够正确解析ItemIndex - _contextInfo.PageItemIndex = 0; - - return StlParserUtility.GetBackHtml(parsedContent, _pageInfo); - } - } - -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlPageContents.cs b/SiteServer.CMS/StlParser/StlElement/StlPageContents.cs deleted file mode 100644 index 996d5fd5b..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlPageContents.cs +++ /dev/null @@ -1,316 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Web.UI.WebControls; -using System.Xml; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "翻页内容列表", Description = "通过 stl:pageContents 标签在模板中显示翻页内容列表")] - public class StlPageContents : StlContents - { - public new const string ElementName = "stl:pageContents"; - - public static readonly Attr PageNum = new Attr("pageNum", "每页显示的内容数目"); - public static readonly Attr MaxPage = new Attr("maxPage", "翻页中生成的静态页面最大数,剩余页面将动态获取"); - - private readonly string _stlPageContentsElement; - private readonly XmlNode _node; - private readonly PageInfo _pageInfo; - private readonly ContextInfo _contextInfo; - - public StlPageContents(string stlPageContentsElement, PageInfo pageInfo, ContextInfo contextInfo, bool isXmlContent) - { - _pageInfo = pageInfo; - _contextInfo = contextInfo; - var xmlDocument = StlParserUtility.GetXmlDocument(stlPageContentsElement, isXmlContent); - _node = xmlDocument.DocumentElement; - if (_node != null) - { - _stlPageContentsElement = _node.InnerXml; - _node = _node.FirstChild; - - var attributes = new Dictionary(); - var ie = _node?.Attributes?.GetEnumerator(); - if (ie != null) - { - while (ie.MoveNext()) - { - var attr = (XmlAttribute)ie.Current; - - var key = attr.Name; - if (!string.IsNullOrEmpty(key)) - { - var value = attr.Value; - if (string.IsNullOrEmpty(value)) - { - value = string.Empty; - } - attributes[key] = value; - } - } - } - - _contextInfo = contextInfo.Clone(stlPageContentsElement, attributes, _node?.InnerXml, _node?.ChildNodes); - - ListInfo = ListInfo.GetListInfoByXmlNode(_pageInfo, _contextInfo, EContextType.Content); - } - - var channelId = StlDataUtility.GetChannelIdByLevel(_pageInfo.SiteId, _contextInfo.ChannelId, ListInfo.UpLevel, ListInfo.TopLevel); - - channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(_pageInfo.SiteId, channelId, ListInfo.ChannelIndex, ListInfo.ChannelName); - - SqlString = StlDataUtility.GetStlPageContentsSqlString(_pageInfo.SiteInfo, channelId, ListInfo.GroupContent, ListInfo.GroupContentNot, ListInfo.Tags, ListInfo.IsImageExists, ListInfo.IsImage, ListInfo.IsVideoExists, ListInfo.IsVideo, ListInfo.IsFileExists, ListInfo.IsFile, ListInfo.IsNoDup, ListInfo.StartNum, ListInfo.TotalNum, ListInfo.OrderByString, ListInfo.IsTopExists, ListInfo.IsTop, ListInfo.IsRecommendExists, ListInfo.IsRecommend, ListInfo.IsHotExists, ListInfo.IsHot, ListInfo.IsColorExists, ListInfo.IsColor, ListInfo.Where, ListInfo.Scope, ListInfo.GroupChannel, ListInfo.GroupChannelNot); - } - - //API StlActionsSearchController调用 - public StlPageContents(string stlPageContentsElement, PageInfo pageInfo, ContextInfo contextInfo, int pageNum, string tableName, string whereString) - { - _pageInfo = pageInfo; - _contextInfo = contextInfo; - var xmlDocument = StlParserUtility.GetXmlDocument(stlPageContentsElement, false); - _node = xmlDocument.DocumentElement; - if (_node != null) - { - _node = _node.FirstChild; - - var attributes = new Dictionary(); - var ie = _node?.Attributes?.GetEnumerator(); - if (ie != null) - { - while (ie.MoveNext()) - { - var attr = (XmlAttribute)ie.Current; - - var key = attr.Name; - if (!string.IsNullOrEmpty(key)) - { - var value = attr.Value; - if (string.IsNullOrEmpty(value)) - { - value = string.Empty; - } - attributes[key] = value; - } - } - } - - _contextInfo = contextInfo.Clone(stlPageContentsElement, attributes, _node?.InnerXml, _node?.ChildNodes); - - ListInfo = ListInfo.GetListInfoByXmlNode(_pageInfo, _contextInfo, EContextType.Content); - } - ListInfo.Scope = EScopeType.All; - - ListInfo.Where += whereString; - if (pageNum > 0) - { - ListInfo.PageNum = pageNum; - } - - SqlString = StlDataUtility.GetPageContentsSqlStringBySearch(tableName, ListInfo.GroupContent, ListInfo.GroupContentNot, ListInfo.Tags, ListInfo.IsImageExists, ListInfo.IsImage, ListInfo.IsVideoExists, ListInfo.IsVideo, ListInfo.IsFileExists, ListInfo.IsFile, ListInfo.IsNoDup, ListInfo.StartNum, ListInfo.TotalNum, ListInfo.OrderByString, ListInfo.IsTopExists, ListInfo.IsTop, ListInfo.IsRecommendExists, ListInfo.IsRecommend, ListInfo.IsHotExists, ListInfo.IsHot, ListInfo.IsColorExists, ListInfo.IsColor, ListInfo.Where, ListInfo.Scope, ListInfo.GroupChannel, ListInfo.GroupChannelNot); - } - - public int GetPageCount(out int totalNum) - { - totalNum = 0; - var pageCount = 1; - try - { - //totalNum = DataProvider.DatabaseDao.GetPageTotalCount(SqlString); - totalNum = Database.GetPageTotalCount(SqlString); - if (ListInfo.PageNum != 0 && ListInfo.PageNum < totalNum)//需要翻页 - { - pageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(totalNum) / Convert.ToDouble(ListInfo.PageNum)));//需要生成的总页数 - } - } - catch - { - // ignored - } - return pageCount; - } - - public string SqlString { get; } - - public ListInfo ListInfo { get; } - - public string Parse(int totalNum, int currentPageIndex, int pageCount, bool isStatic) - { - if (isStatic) - { - var maxPage = ListInfo.MaxPage; - if (maxPage == 0) - { - maxPage = _pageInfo.SiteInfo.Additional.CreateStaticMaxPage; - } - if (maxPage > 0 && currentPageIndex + 1 > maxPage) - { - return ParseDynamic(totalNum, currentPageIndex, pageCount); - } - } - - var parsedContent = string.Empty; - - _contextInfo.PageItemIndex = currentPageIndex * ListInfo.PageNum; - - try - { - if (_node != null) - { - if (!string.IsNullOrEmpty(SqlString)) - { - //var pageSqlString = DataProvider.DatabaseDao.GetPageSqlString(SqlString, ListInfo.OrderByString, totalNum, ListInfo.PageNum, currentPageIndex); - var pageSqlString = Database.GetStlPageSqlString(SqlString, ListInfo.OrderByString, totalNum, ListInfo.PageNum, currentPageIndex); - - var datasource = DataProvider.DatabaseDao.GetDataSource(pageSqlString); - - if (ListInfo.Layout == ELayout.None) - { - var rptContents = new Repeater(); - - if (!string.IsNullOrEmpty(ListInfo.HeaderTemplate)) - { - rptContents.HeaderTemplate = new SeparatorTemplate(ListInfo.HeaderTemplate); - } - if (!string.IsNullOrEmpty(ListInfo.FooterTemplate)) - { - rptContents.FooterTemplate = new SeparatorTemplate(ListInfo.FooterTemplate); - } - if (!string.IsNullOrEmpty(ListInfo.SeparatorTemplate)) - { - rptContents.SeparatorTemplate = new SeparatorTemplate(ListInfo.SeparatorTemplate); - } - if (!string.IsNullOrEmpty(ListInfo.AlternatingItemTemplate)) - { - rptContents.AlternatingItemTemplate = new RepeaterTemplate(ListInfo.AlternatingItemTemplate, ListInfo.SelectedItems, ListInfo.SelectedValues, ListInfo.SeparatorRepeatTemplate, ListInfo.SeparatorRepeat, _pageInfo, EContextType.Content, _contextInfo); - } - - rptContents.ItemTemplate = new RepeaterTemplate(ListInfo.ItemTemplate, ListInfo.SelectedItems, ListInfo.SelectedValues, ListInfo.SeparatorRepeatTemplate, ListInfo.SeparatorRepeat, _pageInfo, EContextType.Content, _contextInfo); - - rptContents.DataSource = datasource; - rptContents.DataBind(); - - if (rptContents.Items.Count > 0) - { - parsedContent = ControlUtils.GetControlRenderHtml(rptContents); - } - } - else - { - var pdlContents = new ParsedDataList(); - - //设置显示属性 - TemplateUtility.PutListInfoToMyDataList(pdlContents, ListInfo); - - pdlContents.ItemTemplate = new DataListTemplate(ListInfo.ItemTemplate, ListInfo.SelectedItems, ListInfo.SelectedValues, ListInfo.SeparatorRepeatTemplate, ListInfo.SeparatorRepeat, _pageInfo, EContextType.Content, _contextInfo); - if (!string.IsNullOrEmpty(ListInfo.HeaderTemplate)) - { - pdlContents.HeaderTemplate = new SeparatorTemplate(ListInfo.HeaderTemplate); - } - if (!string.IsNullOrEmpty(ListInfo.FooterTemplate)) - { - pdlContents.FooterTemplate = new SeparatorTemplate(ListInfo.FooterTemplate); - } - if (!string.IsNullOrEmpty(ListInfo.SeparatorTemplate)) - { - pdlContents.SeparatorTemplate = new SeparatorTemplate(ListInfo.SeparatorTemplate); - } - if (!string.IsNullOrEmpty(ListInfo.AlternatingItemTemplate)) - { - pdlContents.AlternatingItemTemplate = new DataListTemplate(ListInfo.AlternatingItemTemplate, ListInfo.SelectedItems, ListInfo.SelectedValues, ListInfo.SeparatorRepeatTemplate, ListInfo.SeparatorRepeat, _pageInfo, EContextType.Content, _contextInfo); - } - - pdlContents.DataSource = datasource; - pdlContents.DataKeyField = ContentAttribute.Id; - pdlContents.DataBind(); - - if (pdlContents.Items.Count > 0) - { - parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); - } - } - } - } - } - catch (Exception ex) - { - parsedContent = StlParserUtility.GetStlErrorMessage(ElementName, _stlPageContentsElement, ex); - } - - parsedContent = StlParserUtility.GetBackHtml(parsedContent, _pageInfo); - - //还原翻页为0,使得其他列表能够正确解析ItemIndex - _contextInfo.PageItemIndex = 0; - return parsedContent; - } - - private string ParseDynamic(int totalNum, int currentPageIndex, int pageCount) - { - var loading = ListInfo.LoadingTemplate; - if (string.IsNullOrEmpty(loading)) - { - loading = @"
    - 载入中,请稍后... -
    "; - } - - _pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.Jquery); - - var ajaxDivId = StlParserUtility.GetAjaxDivId(_pageInfo.UniqueId); - var apiUrl = ApiRouteActionsPageContents.GetUrl(_pageInfo.ApiUrl); - var apiParameters = ApiRouteActionsPageContents.GetParameters(_pageInfo.SiteId, _pageInfo.PageChannelId, _pageInfo.TemplateInfo.Id, totalNum, pageCount, currentPageIndex, _stlPageContentsElement); - - var builder = new StringBuilder(); - builder.Append($@"
    "); - builder.Append($@"
    {loading}
    "); - builder.Append($@"
    {string.Empty}
    "); - builder.Append("
    "); - - builder.Append($@" - -"); - - return builder.ToString(); - } - } -} \ No newline at end of file diff --git a/SiteServer.CMS/StlParser/StlElement/StlPageItems.cs b/SiteServer.CMS/StlParser/StlElement/StlPageItems.cs deleted file mode 100644 index 75029c594..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlPageItems.cs +++ /dev/null @@ -1,148 +0,0 @@ -using System; -using System.Xml; -using SiteServer.Utils; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Parsers; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "翻页项容器", Description = "通过 stl:pageItems 标签在模板中插入翻页项的容器,当不需要翻页时容器内的内容不显示")] - public class StlPageItems - { - private StlPageItems() { } - public const string ElementName = "stl:pageItems"; - - private static readonly Attr Context = new Attr("context", "所处上下文"); - - //对“翻页项容器”(stl:pageItems)元素进行解析,此元素在生成页面时单独解析,不包含在ParseStlElement方法中。 - public static string Parse(string stlElement, PageInfo pageInfo, int channelId, int contentId, int currentPageIndex, int pageCount, int totalNum, EContextType contextType) - { - pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.Jquery); - string parsedContent; - try - { - var xmlDocument = StlParserUtility.GetXmlDocument(stlElement, false); - XmlNode node = xmlDocument.DocumentElement; - node = node?.FirstChild; - - var ie = node?.Attributes?.GetEnumerator(); - if (ie != null) - { - while (ie.MoveNext()) - { - var attr = (XmlAttribute)ie.Current; - if (attr == null) continue; - - var name = attr.Name; - - if (StringUtils.EqualsIgnoreCase(name, Context.Name)) - { - contextType = EContextTypeUtils.GetEnumType(attr.Value); - } - } - } - - if (pageCount <= 1) - { - return string.Empty; - } - - bool isXmlContent; - var index = stlElement.IndexOf(">", StringComparison.Ordinal) + 1; - var length = stlElement.LastIndexOf("<", StringComparison.Ordinal) - index; - if (index <= 0 || length <= 0) - { - stlElement = node?.InnerXml; - isXmlContent = true; - } - else - { - stlElement = stlElement.Substring(index, length); - isXmlContent = false; - } - - parsedContent = StlPageElementParser.ParseStlPageItems(stlElement, pageInfo, channelId, contentId, currentPageIndex, pageCount, totalNum, isXmlContent, contextType); - } - catch (Exception ex) - { - parsedContent = StlParserUtility.GetStlErrorMessage(ElementName, stlElement, ex); - } - - return parsedContent; - } - - public static string ParseInSearchPage(string stlElement, PageInfo pageInfo, string ajaxDivId, int channelId, int currentPageIndex, int pageCount, int totalNum) - { - string parsedContent; - try - { - var xmlDocument = StlParserUtility.GetXmlDocument(stlElement, false); - XmlNode node = xmlDocument.DocumentElement; - node = node?.FirstChild; - - if (pageCount <= 1) - { - return string.Empty; - } - - //bool isXmlContent; - var index = stlElement.IndexOf(">", StringComparison.Ordinal) + 1; - var length = stlElement.LastIndexOf("<", StringComparison.Ordinal) - index; - if (index <= 0 || length <= 0) - { - stlElement = node?.InnerXml; - //isXmlContent = true; - } - else - { - stlElement = stlElement.Substring(index, length); - //isXmlContent = false; - } - - parsedContent = StlPageElementParser.ParseStlPageItemsInSearchPage(stlElement, pageInfo, ajaxDivId, channelId, currentPageIndex, pageCount, totalNum); - } - catch (Exception ex) - { - parsedContent = StlParserUtility.GetStlErrorMessage(ElementName, stlElement, ex); - } - - return parsedContent; - } - - public static string ParseInDynamicPage(string stlElement, PageInfo pageInfo, string pageUrl, int channelId, int currentPageIndex, int pageCount, int totalNum, bool isPageRefresh, string ajaxDivId) - { - string parsedContent; - try - { - var xmlDocument = StlParserUtility.GetXmlDocument(stlElement, false); - XmlNode node = xmlDocument.DocumentElement; - node = node?.FirstChild; - - if (pageCount <= 1) - { - return string.Empty; - } - - var index = stlElement.IndexOf(">", StringComparison.Ordinal) + 1; - var length = stlElement.LastIndexOf("<", StringComparison.Ordinal) - index; - if (index <= 0 || length <= 0) - { - stlElement = node?.InnerXml; - } - else - { - stlElement = stlElement.Substring(index, length); - } - - parsedContent = StlPageElementParser.ParseStlPageItemsInDynamicPage(stlElement, pageInfo, pageUrl, channelId, currentPageIndex, pageCount, totalNum, isPageRefresh, ajaxDivId); - } - catch (Exception ex) - { - parsedContent = StlParserUtility.GetStlErrorMessage(ElementName, stlElement, ex); - } - - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlPageSqlContents.cs b/SiteServer.CMS/StlParser/StlElement/StlPageSqlContents.cs deleted file mode 100644 index 6dec438db..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlPageSqlContents.cs +++ /dev/null @@ -1,246 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Data; -using System.Web.UI.WebControls; -using System.Xml; -using SiteServer.Utils; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "翻页数据库列表", Description = "通过 stl:pageSqlContents 标签在模板中显示能够翻页的数据库列表")] - public class StlPageSqlContents : StlSqlContents - { - public new const string ElementName = "stl:pageSqlContents"; - - private static readonly Attr PageNum = new Attr("pageNum", "每页显示的内容数目"); - - private readonly string _stlPageSqlContentsElement; - private readonly XmlNode _node; - private readonly ListInfo _listInfo; - private readonly PageInfo _pageInfo; - private readonly ContextInfo _contextInfo; - private DataSet _dataSet; - - public StlPageSqlContents(string stlPageSqlContentsElement, PageInfo pageInfo, ContextInfo contextInfo, bool isXmlContent, bool isLoadData) - { - _stlPageSqlContentsElement = stlPageSqlContentsElement; - _pageInfo = pageInfo; - try - { - var xmlDocument = StlParserUtility.GetXmlDocument(_stlPageSqlContentsElement, isXmlContent); - _node = xmlDocument.DocumentElement; - _node = _node?.FirstChild; - - var attributes = new Dictionary(); - var ie = _node?.Attributes?.GetEnumerator(); - if (ie != null) - { - while (ie.MoveNext()) - { - var attr = (XmlAttribute)ie.Current; - - var key = attr.Name; - if (!string.IsNullOrEmpty(key)) - { - var value = attr.Value; - if (string.IsNullOrEmpty(value)) - { - value = string.Empty; - } - attributes[key] = value; - } - } - } - - _contextInfo = contextInfo.Clone(stlPageSqlContentsElement, attributes, _node?.InnerXml, _node?.ChildNodes); - - _listInfo = ListInfo.GetListInfoByXmlNode(_pageInfo, _contextInfo, EContextType.SqlContent); - if (isLoadData) - { - _dataSet = StlDataUtility.GetPageSqlContentsDataSet(_listInfo.ConnectionString, _listInfo.QueryString, _listInfo.StartNum, _listInfo.TotalNum, _listInfo.OrderByString); - } - } - catch - { - _listInfo = new ListInfo(); - } - } - - public StlPageSqlContents(string stlPageSqlContentsElement, PageInfo pageInfo, ContextInfo contextInfo, bool isXmlContent) - { - _pageInfo = pageInfo; - try - { - var xmlDocument = StlParserUtility.GetXmlDocument(stlPageSqlContentsElement, isXmlContent); - _node = xmlDocument.DocumentElement; - _node = _node?.FirstChild; - - var attributes = new Dictionary(); - var ie = _node?.Attributes?.GetEnumerator(); - if (ie != null) - { - while (ie.MoveNext()) - { - var attr = (XmlAttribute)ie.Current; - - var key = attr.Name; - if (!string.IsNullOrEmpty(key)) - { - var value = attr.Value; - if (string.IsNullOrEmpty(value)) - { - value = string.Empty; - } - attributes[key] = value; - } - } - } - - _contextInfo = contextInfo.Clone(stlPageSqlContentsElement, attributes, _node?.InnerXml, _node?.ChildNodes); - - _listInfo = ListInfo.GetListInfoByXmlNode(_pageInfo, _contextInfo, EContextType.SqlContent); - _dataSet = StlDataUtility.GetPageSqlContentsDataSet(_listInfo.ConnectionString, _listInfo.QueryString, _listInfo.StartNum, _listInfo.TotalNum, _listInfo.OrderByString); - } - catch - { - _listInfo = new ListInfo(); - } - } - - public void LoadData() - { - _dataSet = StlDataUtility.GetPageSqlContentsDataSet(_listInfo.ConnectionString, _listInfo.QueryString, _listInfo.StartNum, _listInfo.TotalNum, _listInfo.OrderByString); - } - - public int GetPageCount(out int contentNum) - { - var pageCount = 1; - contentNum = 0;//数据库中实际的内容数目 - if (_dataSet == null) return pageCount; - - contentNum = _dataSet.Tables[0].DefaultView.Count; - if (_listInfo.PageNum != 0 && _listInfo.PageNum < contentNum)//需要翻页 - { - pageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(contentNum) / Convert.ToDouble(_listInfo.PageNum)));//需要生成的总页数 - } - return pageCount; - } - - public ListInfo DisplayInfo => _listInfo; - - public string Parse(int currentPageIndex, int pageCount) - { - var parsedContent = string.Empty; - - _contextInfo.PageItemIndex = currentPageIndex * _listInfo.PageNum; - - try - { - if (_node != null) - { - if (_dataSet != null) - { - var objPage = new PagedDataSource {DataSource = _dataSet.Tables[0].DefaultView}; //分页类 - - if (pageCount > 1) - { - objPage.AllowPaging = true; - objPage.PageSize = _listInfo.PageNum;//每页显示的项数 - } - else - { - objPage.AllowPaging = false; - } - - objPage.CurrentPageIndex = currentPageIndex;//当前页的索引 - - - if (_listInfo.Layout == ELayout.None) - { - var rptContents = new Repeater - { - ItemTemplate = - new RepeaterTemplate(_listInfo.ItemTemplate, _listInfo.SelectedItems, - _listInfo.SelectedValues, _listInfo.SeparatorRepeatTemplate, - _listInfo.SeparatorRepeat, _pageInfo, EContextType.SqlContent, _contextInfo) - }; - - - if (!string.IsNullOrEmpty(_listInfo.HeaderTemplate)) - { - rptContents.HeaderTemplate = new SeparatorTemplate(_listInfo.HeaderTemplate); - } - if (!string.IsNullOrEmpty(_listInfo.FooterTemplate)) - { - rptContents.FooterTemplate = new SeparatorTemplate(_listInfo.FooterTemplate); - } - if (!string.IsNullOrEmpty(_listInfo.SeparatorTemplate)) - { - rptContents.SeparatorTemplate = new SeparatorTemplate(_listInfo.SeparatorTemplate); - } - if (!string.IsNullOrEmpty(_listInfo.AlternatingItemTemplate)) - { - rptContents.AlternatingItemTemplate = new RepeaterTemplate(_listInfo.AlternatingItemTemplate, _listInfo.SelectedItems, _listInfo.SelectedValues, _listInfo.SeparatorRepeatTemplate, _listInfo.SeparatorRepeat, _pageInfo, EContextType.SqlContent, _contextInfo); - } - - rptContents.DataSource = objPage; - rptContents.DataBind(); - - if (rptContents.Items.Count > 0) - { - parsedContent = ControlUtils.GetControlRenderHtml(rptContents); - } - } - else - { - var pdlContents = new ParsedDataList(); - - //设置显示属性 - TemplateUtility.PutListInfoToMyDataList(pdlContents, _listInfo); - - pdlContents.ItemTemplate = new DataListTemplate(_listInfo.ItemTemplate, _listInfo.SelectedItems, _listInfo.SelectedValues, _listInfo.SeparatorRepeatTemplate, _listInfo.SeparatorRepeat, _pageInfo, EContextType.SqlContent, _contextInfo); - if (!string.IsNullOrEmpty(_listInfo.HeaderTemplate)) - { - pdlContents.HeaderTemplate = new SeparatorTemplate(_listInfo.HeaderTemplate); - } - if (!string.IsNullOrEmpty(_listInfo.FooterTemplate)) - { - pdlContents.FooterTemplate = new SeparatorTemplate(_listInfo.FooterTemplate); - } - if (!string.IsNullOrEmpty(_listInfo.SeparatorTemplate)) - { - pdlContents.SeparatorTemplate = new SeparatorTemplate(_listInfo.SeparatorTemplate); - } - if (!string.IsNullOrEmpty(_listInfo.AlternatingItemTemplate)) - { - pdlContents.AlternatingItemTemplate = new DataListTemplate(_listInfo.AlternatingItemTemplate, _listInfo.SelectedItems, _listInfo.SelectedValues, _listInfo.SeparatorRepeatTemplate, _listInfo.SeparatorRepeat, _pageInfo, EContextType.SqlContent, _contextInfo); - } - - pdlContents.DataSource = objPage; - pdlContents.DataBind(); - - if (pdlContents.Items.Count > 0) - { - parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); - } - } - } - } - } - catch (Exception ex) - { - parsedContent = StlParserUtility.GetStlErrorMessage(ElementName, _stlPageSqlContentsElement, ex); - } - - //还原翻页为0,使得其他列表能够正确解析ItemIndex - _contextInfo.PageItemIndex = 0; - - return StlParserUtility.GetBackHtml(parsedContent, _pageInfo); - } - - } - -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlPlayer.cs b/SiteServer.CMS/StlParser/StlElement/StlPlayer.cs deleted file mode 100644 index 3a6e957e5..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlPlayer.cs +++ /dev/null @@ -1,460 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Parsers; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "播放视频", Description = "通过 stl:player 标签在模板中播放视频")] - public class StlPlayer - { - private StlPlayer() { } - public const string ElementName = "stl:player"; - - private static readonly Attr ChannelIndex = new Attr("channelIndex", "栏目索引"); - private static readonly Attr ChannelName = new Attr("channelName", "栏目名称"); - private static readonly Attr Parent = new Attr("parent", "显示父栏目"); - private static readonly Attr UpLevel = new Attr("upLevel", "上级栏目的级别"); - private static readonly Attr TopLevel = new Attr("topLevel", "从首页向下的栏目级别"); - private static readonly Attr Type = new Attr("type", "指定存储媒体的字段"); - private static readonly Attr PlayUrl = new Attr("playUrl", "视频地址"); - private static readonly Attr ImageUrl = new Attr("imageUrl", "图片地址"); - private static readonly Attr PlayBy = new Attr("playBy", "指定播放器"); - private static readonly Attr Width = new Attr("width", "宽度"); - private static readonly Attr Height = new Attr("height", "高度"); - private static readonly Attr IsAutoPlay = new Attr("isAutoPlay", "是否自动播放"); - - public const string PlayByBrPlayer = "BRPlayer"; - public const string PlayByFlowPlayer = "FlowPlayer"; - public const string PlayByJwPlayer = "JWPlayer"; - - public static SortedList PlayByList => new SortedList - { - {PlayByBrPlayer, "BRPlayer"}, - {PlayByFlowPlayer, "FlowPlayer"}, - {PlayByJwPlayer, "JWPlayer"} - }; - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var isGetPicUrlFromAttribute = false; - var channelIndex = string.Empty; - var channelName = string.Empty; - var upLevel = 0; - var topLevel = -1; - var type = BackgroundContentAttribute.VideoUrl; - var playUrl = string.Empty; - var imageUrl = string.Empty; - var playBy = string.Empty; - var width = 450; - var height = 350; - var isAutoPlay = true; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, ChannelIndex.Name)) - { - channelIndex = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - if (!string.IsNullOrEmpty(channelIndex)) - { - isGetPicUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, ChannelName.Name)) - { - channelName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - if (!string.IsNullOrEmpty(channelName)) - { - isGetPicUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, Parent.Name)) - { - if (TranslateUtils.ToBool(value)) - { - upLevel = 1; - isGetPicUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, UpLevel.Name)) - { - upLevel = TranslateUtils.ToInt(value); - if (upLevel > 0) - { - isGetPicUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, TopLevel.Name)) - { - topLevel = TranslateUtils.ToInt(value); - if (topLevel >= 0) - { - isGetPicUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, Type.Name)) - { - type = value; - } - else if (StringUtils.EqualsIgnoreCase(name, PlayUrl.Name) || StringUtils.EqualsIgnoreCase(name, "src")) - { - playUrl = value; - } - else if (StringUtils.EqualsIgnoreCase(name, ImageUrl.Name)) - { - imageUrl = value; - } - else if (StringUtils.EqualsIgnoreCase(name, PlayBy.Name)) - { - playBy = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Width.Name)) - { - width = TranslateUtils.ToInt(value, width); - } - else if (StringUtils.EqualsIgnoreCase(name, Height.Name)) - { - height = TranslateUtils.ToInt(value, height); - } - else if (StringUtils.EqualsIgnoreCase(name, IsAutoPlay.Name) || StringUtils.EqualsIgnoreCase(name, "play")) - { - isAutoPlay = TranslateUtils.ToBool(value, true); - } - } - - return ParseImpl(pageInfo, contextInfo, isGetPicUrlFromAttribute, channelIndex, channelName, upLevel, topLevel, playUrl, imageUrl, playBy, width, height, type, isAutoPlay); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, bool isGetPicUrlFromAttribute, string channelIndex, string channelName, int upLevel, int topLevel, string playUrl, string imageUrl, string playBy, int width, int height, string type, bool isAutoPlay) - { - var parsedContent = string.Empty; - - var contentId = 0; - //判断是否图片地址由标签属性获得 - if (!isGetPicUrlFromAttribute) - { - contentId = contextInfo.ContentId; - } - - if (string.IsNullOrEmpty(playUrl)) - { - if (contentId != 0)//获取内容视频 - { - if (contextInfo.ContentInfo == null) - { - //playUrl = DataProvider.ContentDao.GetValue(pageInfo.SiteInfo.AuxiliaryTableForContent, contentId, type); - playUrl = Content.GetValue(pageInfo.SiteInfo.TableName, contentId, type); - if (string.IsNullOrEmpty(playUrl)) - { - if (!StringUtils.EqualsIgnoreCase(type, BackgroundContentAttribute.VideoUrl)) - { - //playUrl = DataProvider.ContentDao.GetValue(pageInfo.SiteInfo.AuxiliaryTableForContent, contentId, BackgroundContentAttribute.VideoUrl); - playUrl = Content.GetValue(pageInfo.SiteInfo.TableName, contentId, BackgroundContentAttribute.VideoUrl); - } - } - if (string.IsNullOrEmpty(playUrl)) - { - if (!StringUtils.EqualsIgnoreCase(type, BackgroundContentAttribute.FileUrl)) - { - //playUrl = DataProvider.ContentDao.GetValue(pageInfo.SiteInfo.AuxiliaryTableForContent, contentId, BackgroundContentAttribute.FileUrl); - playUrl = Content.GetValue(pageInfo.SiteInfo.TableName, contentId, BackgroundContentAttribute.FileUrl); - } - } - } - else - { - playUrl = contextInfo.ContentInfo.GetString(type); - if (string.IsNullOrEmpty(playUrl)) - { - playUrl = contextInfo.ContentInfo.GetString(BackgroundContentAttribute.VideoUrl); - } - if (string.IsNullOrEmpty(playUrl)) - { - playUrl = contextInfo.ContentInfo.GetString(BackgroundContentAttribute.FileUrl); - } - } - } - } - - if (string.IsNullOrEmpty(imageUrl)) - { - if (contentId != 0) - { - //imageUrl = contextInfo.ContentInfo == null ? DataProvider.ContentDao.GetValue(pageInfo.SiteInfo.AuxiliaryTableForContent, contentId, BackgroundContentAttribute.ImageUrl) : contextInfo.ContentInfo.GetString(BackgroundContentAttribute.ImageUrl); - imageUrl = contextInfo.ContentInfo == null ? Content.GetValue(pageInfo.SiteInfo.TableName, contentId, BackgroundContentAttribute.ImageUrl) : contextInfo.ContentInfo.GetString(BackgroundContentAttribute.ImageUrl); - } - } - if (string.IsNullOrEmpty(imageUrl)) - { - var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); - channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, channelIndex, channelName); - var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); - imageUrl = channel.ImageUrl; - } - - if (!string.IsNullOrEmpty(playUrl)) - { - var extension = PathUtils.GetExtension(playUrl); - if (EFileSystemTypeUtils.IsFlash(extension)) - { - parsedContent = StlFlash.Parse(pageInfo, contextInfo); - } - else if (EFileSystemTypeUtils.IsImage(extension)) - { - parsedContent = StlImage.Parse(pageInfo, contextInfo); - } - else - { - var uniqueId = pageInfo.UniqueId; - playUrl = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, playUrl, pageInfo.IsLocal); - imageUrl = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, imageUrl, pageInfo.IsLocal); - - var fileType = EFileSystemTypeUtils.GetEnumType(extension); - if (fileType == EFileSystemType.Avi) - { - parsedContent = $@" - - - - - - - - - - - - - - -"; - } - else if (fileType == EFileSystemType.Mpg) - { - parsedContent = $@" - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -"; - } - else if (fileType == EFileSystemType.Mpg) - { - parsedContent = $@" - - - - - - - - - - - - - - - - -"; - } - else if (fileType == EFileSystemType.Rm) - { - parsedContent = $@" - - - - - - - - - - - - - - - - - -"; - } - else if (fileType == EFileSystemType.Wmv) - { - parsedContent = $@" - - - - - - - - - - - - - - - - - - - - -"; - } - else if (fileType == EFileSystemType.Wma) - { - parsedContent = $@" - - - - - - - - - - - -"; - } - else if (fileType == EFileSystemType.Rm || fileType == EFileSystemType.Rmb || fileType == EFileSystemType.Rmvb) - { - if (!contextInfo.Attributes.ContainsKey("ShowDisplay")) - { - contextInfo.Attributes["ShowDisplay"] = "0"; - } - if (!contextInfo.Attributes.ContainsKey("ShowControls")) - { - contextInfo.Attributes["ShowControls"] = "1"; - } - contextInfo.Attributes["AutoStart"] = isAutoPlay ? "1" : "0"; - if (!contextInfo.Attributes.ContainsKey("AutoRewind")) - { - contextInfo.Attributes["AutoRewind"] = "0"; - } - if (!contextInfo.Attributes.ContainsKey("PlayCount")) - { - contextInfo.Attributes["PlayCount"] = "0"; - } - if (!contextInfo.Attributes.ContainsKey("Appearance")) - { - contextInfo.Attributes["Appearance"] = "0"; - } - if (!contextInfo.Attributes.ContainsKey("BorderStyle")) - { - contextInfo.Attributes["BorderStyle"] = "0"; - } - if (!contextInfo.Attributes.ContainsKey("Controls")) - { - contextInfo.Attributes["ImageWindow"] = "0"; - } - contextInfo.Attributes["moviewindowheight"] = height.ToString(); - contextInfo.Attributes["moviewindowwidth"] = width.ToString(); - contextInfo.Attributes["filename"] = playUrl; - contextInfo.Attributes["src"] = playUrl; - - var paramBuilder = new StringBuilder(); - var embedBuilder = new StringBuilder(); - foreach (string key in contextInfo.Attributes.Keys) - { - paramBuilder.Append($@"").Append(StringUtils.Constants.ReturnAndNewline); - embedBuilder.Append($@" {key}=""{contextInfo.Attributes[key]}"""); - } - - parsedContent = $@" - -{paramBuilder} - - - -"; - } - else - { - if (StringUtils.EqualsIgnoreCase(playBy, PlayByJwPlayer)) - { - pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.JsAcJwPlayer6); - var ajaxElementId = StlParserUtility.GetAjaxDivId(pageInfo.UniqueId); - parsedContent = $@" -
    - -"; - } - else - { - var ajaxElementId = StlParserUtility.GetAjaxDivId(pageInfo.UniqueId); - pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.JsAcFlowPlayer); - - var swfUrl = SiteFilesAssets.GetUrl(pageInfo.ApiUrl, SiteFilesAssets.FlowPlayer.Swf); - parsedContent = $@" - - -"; - } - } - } - } - - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlQueryString.cs b/SiteServer.CMS/StlParser/StlElement/StlQueryString.cs deleted file mode 100644 index 5c62466be..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlQueryString.cs +++ /dev/null @@ -1,10 +0,0 @@ -using SiteServer.CMS.StlParser.Model; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "SQL查询语句", Description = "通过 stl:queryString 标签在模板中定义SQL查询语句")] - public class StlQueryString - { - public const string ElementName = "stl:queryString"; - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlRss.cs b/SiteServer.CMS/StlParser/StlElement/StlRss.cs deleted file mode 100644 index 10a5c1538..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlRss.cs +++ /dev/null @@ -1,205 +0,0 @@ -using System; -using System.Text; -using SiteServer.Utils; -using SiteServer.Utils.IO; -using SiteServer.Utils.Rss; -using SiteServer.CMS.Core; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "Rss订阅", Description = "通过 stl:rss 标签在模板中生成Rss阅读器能够浏览的Rss订阅")] - public class StlRss - { - private StlRss() { } - public const string ElementName = "stl:rss"; - - private static readonly Attr ChannelIndex = new Attr("channelIndex", "栏目索引"); - private static readonly Attr ChannelName = new Attr("channelName", "栏目名称"); - private static readonly Attr Scope = new Attr("scope", "内容范围"); - private static readonly Attr GroupChannel = new Attr("groupChannel", "指定显示的栏目组"); - private static readonly Attr GroupChannelNot = new Attr("groupChannelNot", "指定不显示的栏目组"); - private static readonly Attr GroupContent = new Attr("groupContent", "指定显示的内容组"); - private static readonly Attr GroupContentNot = new Attr("groupContentNot", "指定不显示的内容组"); - private static readonly Attr Tags = new Attr("tags", "指定标签"); - private static readonly Attr Title = new Attr("title", "Rss订阅标题"); - private static readonly Attr Description = new Attr("description", "Rss订阅摘要"); - private static readonly Attr TotalNum = new Attr("totalNum", "显示内容数目"); - private static readonly Attr StartNum = new Attr("startNum", "从第几条信息开始显示"); - private static readonly Attr Order = new Attr("order", "排序"); - private static readonly Attr IsTop = new Attr("isTop", "仅显示置顶内容"); - private static readonly Attr IsRecommend = new Attr("isRecommend", "仅显示推荐内容"); - private static readonly Attr IsHot = new Attr("isHot", "仅显示热点内容"); - private static readonly Attr IsColor = new Attr("isColor", "仅显示醒目内容"); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var title = string.Empty; - var description = string.Empty; - var scopeTypeString = string.Empty; - var groupChannel = string.Empty; - var groupChannelNot = string.Empty; - var groupContent = string.Empty; - var groupContentNot = string.Empty; - var tags = string.Empty; - var channelIndex = string.Empty; - var channelName = string.Empty; - var totalNum = 0; - var startNum = 1; - var orderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByTaxisDesc); - var isTop = false; - var isTopExists = false; - var isRecommend = false; - var isRecommendExists = false; - var isHot = false; - var isHotExists = false; - var isColor = false; - var isColorExists = false; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, Title.Name)) - { - title = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Description.Name)) - { - description = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Scope.Name)) - { - scopeTypeString = value; - } - else if (StringUtils.EqualsIgnoreCase(name, ChannelIndex.Name)) - { - channelIndex = value; - } - else if (StringUtils.EqualsIgnoreCase(name, ChannelName.Name)) - { - channelName = value; - } - else if (StringUtils.EqualsIgnoreCase(name, GroupChannel.Name)) - { - groupChannel = value; - } - else if (StringUtils.EqualsIgnoreCase(name, GroupChannelNot.Name)) - { - groupChannelNot = value; - } - else if (StringUtils.EqualsIgnoreCase(name, GroupContent.Name)) - { - groupContent = value; - } - else if (StringUtils.EqualsIgnoreCase(name, GroupContentNot.Name)) - { - groupContentNot = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Tags.Name)) - { - tags = value; - } - else if (StringUtils.EqualsIgnoreCase(name, TotalNum.Name)) - { - totalNum = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, StartNum.Name)) - { - startNum = TranslateUtils.ToInt(value, 1); - } - else if (StringUtils.EqualsIgnoreCase(name, Order.Name)) - { - orderByString = StlDataUtility.GetContentOrderByString(pageInfo.SiteId, value, ETaxisType.OrderByTaxisDesc); - } - else if (StringUtils.EqualsIgnoreCase(name, IsTop.Name)) - { - isTopExists = true; - isTop = TranslateUtils.ToBool(value); - } - else if (StringUtils.EqualsIgnoreCase(name, IsRecommend.Name)) - { - isRecommendExists = true; - isRecommend = TranslateUtils.ToBool(value); - } - else if (StringUtils.EqualsIgnoreCase(name, IsHot.Name)) - { - isHotExists = true; - isHot = TranslateUtils.ToBool(value); - } - else if (StringUtils.EqualsIgnoreCase(name, IsColor.Name)) - { - isColorExists = true; - isColor = TranslateUtils.ToBool(value); - } - } - - return ParseImpl(pageInfo, contextInfo, title, description, scopeTypeString, groupChannel, groupChannelNot, groupContent, groupContentNot, tags, channelIndex, channelName, totalNum, startNum, orderByString, isTop, isTopExists, isRecommend, isRecommendExists, isHot, isHotExists, isColor, isColorExists); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string title, string description, string scopeTypeString, string groupChannel, string groupChannelNot, string groupContent, string groupContentNot, string tags, string channelIndex, string channelName, int totalNum, int startNum, string orderByString, bool isTop, bool isTopExists, bool isRecommend, bool isRecommendExists, bool isHot, bool isHotExists, bool isColor, bool isColorExists) - { - var feed = new RssFeed - { - Encoding = ECharsetUtils.GetEncoding(pageInfo.TemplateInfo.Charset), - Version = RssVersion.RSS20 - }; - - var channel = new RssChannel - { - Title = title, - Description = description - }; - - var scopeType = !string.IsNullOrEmpty(scopeTypeString) ? EScopeTypeUtils.GetEnumType(scopeTypeString) : EScopeType.All; - - var channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, contextInfo.ChannelId, channelIndex, channelName); - - var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); - if (string.IsNullOrEmpty(channel.Title)) - { - channel.Title = nodeInfo.ChannelName; - } - if (string.IsNullOrEmpty(channel.Description)) - { - channel.Description = nodeInfo.Content; - channel.Description = string.IsNullOrEmpty(channel.Description) ? nodeInfo.ChannelName : StringUtils.MaxLengthText(channel.Description, 200); - } - channel.Link = new Uri(PageUtils.AddProtocolToUrl(PageUtility.GetChannelUrl(pageInfo.SiteInfo, nodeInfo, pageInfo.IsLocal))); - - var dataSource = StlDataUtility.GetContentsDataSource(pageInfo.SiteInfo, channelId, 0, groupContent, groupContentNot, tags, false, false, false, false, false, false, false, false, startNum, totalNum, orderByString, isTopExists, isTop, isRecommendExists, isRecommend, isHotExists, isHot, isColorExists, isColor, string.Empty, scopeType, groupChannel, groupChannelNot, null); - - if (dataSource != null) - { - //foreach (var dataItem in dataSource) - //{ - // var item = new RssItem(); - - // var contentInfo = new BackgroundContentInfo(dataItem); - // item.Title = StringUtils.Replace("&", contentInfo.Title, "&"); - // item.Description = contentInfo.Summary; - // if (string.IsNullOrEmpty(item.Description)) - // { - // item.Description = StringUtils.StripTags(contentInfo.Content); - // item.Description = string.IsNullOrEmpty(item.Description) ? contentInfo.Title : StringUtils.MaxLengthText(item.Description, 200); - // } - // item.Description = StringUtils.Replace("&", item.Description, "&"); - // item.PubDate = contentInfo.AddDate; - // item.Link = new Uri(PageUtils.AddProtocolToUrl(PageUtility.GetContentUrl(pageInfo.SiteInfo, contentInfo))); - - // channel.Items.Add(item); - //} - } - - feed.Channels.Add(channel); - - var builder = new StringBuilder(); - var textWriter = new EncodedStringWriter(builder, ECharsetUtils.GetEncoding(pageInfo.TemplateInfo.Charset)); - feed.Write(textWriter); - - return builder.ToString(); - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlSearch.cs b/SiteServer.CMS/StlParser/StlElement/StlSearch.cs deleted file mode 100644 index 2c2a7c2bd..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlSearch.cs +++ /dev/null @@ -1,238 +0,0 @@ -using System.Text; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "搜索", Description = "通过 stl:search 标签在模板中显示搜索结果")] - public class StlSearch - { - private StlSearch() { } - public const string ElementName = "stl:search"; - public const string ElementName2 = "stl:searchOutput"; - - public static readonly Attr IsAllSites = new Attr("isAllSites", "是否对全部站点进行搜索"); - public static readonly Attr SiteName = new Attr("siteName", "站点名称"); - public static readonly Attr SiteDir = new Attr("siteDir", "站点文件夹"); - public static readonly Attr SiteIds = new Attr("siteIds", "站点Id列表"); - public static readonly Attr ChannelIndex = new Attr("channelIndex", "栏目索引"); - public static readonly Attr ChannelName = new Attr("channelName", "栏目名称"); - public static readonly Attr ChannelIds = new Attr("channelIds", "栏目Id列表"); - public static readonly Attr Type = new Attr("type", "搜索类型"); - public static readonly Attr Word = new Attr("word", "搜索关键词"); - public static readonly Attr DateAttribute = new Attr("dateAttribute", "搜索时间字段"); - public static readonly Attr DateFrom = new Attr("dateFrom", "搜索开始时间"); - public static readonly Attr DateTo = new Attr("dateTo", "搜索结束时间"); - public static readonly Attr Since = new Attr("since", "搜索时间段"); - public static readonly Attr PageNum = new Attr("pageNum", "每页显示的内容数目"); - public static readonly Attr IsHighlight = new Attr("isHighlight", "是否关键字高亮"); - public static readonly Attr IsDefaultDisplay = new Attr("isDefaultDisplay", "是否默认显示"); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var isAllSites = false; - var siteName = string.Empty; - var siteDir = string.Empty; - var siteIds = string.Empty; - var channelIndex = string.Empty; - var channelName = string.Empty; - var channelIds = string.Empty; - var type = ContentAttribute.Title; - var word = string.Empty; - var dateAttribute = ContentAttribute.AddDate; - var dateFrom = string.Empty; - var dateTo = string.Empty; - var since = string.Empty; - var pageNum = 0; - var isHighlight = false; - var isDefaultDisplay = false; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, IsAllSites.Name)) - { - isAllSites = TranslateUtils.ToBool(value); - } - else if (StringUtils.EqualsIgnoreCase(name, SiteName.Name)) - { - siteName = value; - } - else if (StringUtils.EqualsIgnoreCase(name, SiteDir.Name)) - { - siteDir = value; - } - else if (StringUtils.EqualsIgnoreCase(name, SiteIds.Name)) - { - siteIds = value; - } - else if (StringUtils.EqualsIgnoreCase(name, ChannelIndex.Name)) - { - channelIndex = value; - } - else if (StringUtils.EqualsIgnoreCase(name, ChannelName.Name)) - { - channelName = value; - } - else if (StringUtils.EqualsIgnoreCase(name, ChannelIds.Name)) - { - channelIds = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Type.Name)) - { - type = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Word.Name)) - { - word = value; - } - else if (StringUtils.EqualsIgnoreCase(name, DateAttribute.Name)) - { - dateAttribute = value; - } - else if (StringUtils.EqualsIgnoreCase(name, DateFrom.Name)) - { - dateFrom = value; - } - else if (StringUtils.EqualsIgnoreCase(name, DateTo.Name)) - { - dateTo = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Since.Name)) - { - since = value; - } - else if (StringUtils.EqualsIgnoreCase(name, PageNum.Name)) - { - pageNum = TranslateUtils.ToInt(value, 0); - } - else if (StringUtils.EqualsIgnoreCase(name, IsHighlight.Name)) - { - isHighlight = TranslateUtils.ToBool(value); - } - else if (StringUtils.EqualsIgnoreCase(name, IsDefaultDisplay.Name)) - { - isDefaultDisplay = TranslateUtils.ToBool(value); - } - } - - string loading; - string yes; - string no; - StlInnerUtility.GetLoadingYesNo(contextInfo.InnerXml, out loading, out yes, out no); - - if (string.IsNullOrEmpty(loading)) - { - loading = TemplateManager.GetContentByFilePath(SiteFilesAssets.Search.LoadingTemplatePath); - } - if (string.IsNullOrEmpty(yes)) - { - yes = TemplateManager.GetContentByFilePath(SiteFilesAssets.Search.YesTemplatePath); - } - if (string.IsNullOrEmpty(no)) - { - no = TemplateManager.GetContentByFilePath(SiteFilesAssets.Search.NoTemplatePath); - } - - pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.Jquery); - - var ajaxDivId = StlParserUtility.GetAjaxDivId(pageInfo.UniqueId); - var apiUrl = ApiRouteActionsSearch.GetUrl(pageInfo.ApiUrl); - var apiParameters = ApiRouteActionsSearch.GetParameters(isAllSites, siteName, siteDir, siteIds, channelIndex, channelName, channelIds, type, word, dateAttribute, dateFrom, dateTo, since, pageNum, isHighlight, isDefaultDisplay, pageInfo.SiteId, ajaxDivId, yes); - - var builder = new StringBuilder(); - builder.Append($@" -
    -
    {loading}
    -
    -
    {no}
    -
    -"); - - builder.Append($@" - -"); - - return builder.ToString(); - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlSelect.cs b/SiteServer.CMS/StlParser/StlElement/StlSelect.cs deleted file mode 100644 index ace64fb21..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlSelect.cs +++ /dev/null @@ -1,296 +0,0 @@ -using System.Web.UI.HtmlControls; -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Parsers; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "下拉列表", Description = "通过 stl:select 标签在模板中显示栏目或内容下拉列表")] - public class StlSelect - { - private StlSelect() { } - public const string ElementName = "stl:select"; - - private static readonly Attr IsChannel = new Attr("isChannel", "是否显示栏目下拉列表"); - private static readonly Attr ChannelIndex = new Attr("channelIndex", "栏目索引"); - private static readonly Attr ChannelName = new Attr("channelName", "栏目名称"); - private static readonly Attr UpLevel = new Attr("upLevel", "上级栏目的级别"); - private static readonly Attr TopLevel = new Attr("topLevel", "从首页向下的栏目级别"); - private static readonly Attr Scope = new Attr("scope", "选择的范围"); - private static readonly Attr GroupChannel = new Attr("groupChannel", "指定显示的栏目组"); - private static readonly Attr GroupChannelNot = new Attr("groupChannelNot", "指定不显示的栏目组"); - private static readonly Attr GroupContent = new Attr("groupContent", "指定显示的内容组"); - private static readonly Attr GroupContentNot = new Attr("groupContentNot", "指定不显示的内容组"); - private static readonly Attr Tags = new Attr("tags", "指定标签"); - private static readonly Attr Order = new Attr("order", "排序"); - private static readonly Attr TotalNum = new Attr("totalNum", "显示数目"); - private static readonly Attr TitleWordNum = new Attr("titleWordNum", "标题文字数量"); - private static readonly Attr Where = new Attr("where", "获取下拉列表的条件判断"); - private static readonly Attr QueryString = new Attr("queryString", "链接参数"); - private static readonly Attr IsTop = new Attr("isTop", "仅显示置顶内容"); - private static readonly Attr IsRecommend = new Attr("isRecommend", "仅显示推荐内容"); - private static readonly Attr IsHot = new Attr("isHot", "仅显示热点内容"); - private static readonly Attr IsColor = new Attr("isColor", "仅显示醒目内容"); - private static readonly Attr Title = new Attr("title", "下拉列表提示标题"); - private static readonly Attr OpenWin = new Attr("openWin", "选择是否新窗口打开链接"); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var selectControl = new HtmlSelect(); - - var isChannel = true; - var channelIndex = string.Empty; - var channelName = string.Empty; - var upLevel = 0; - var topLevel = -1; - var scopeTypeString = string.Empty; - var groupChannel = string.Empty; - var groupChannelNot = string.Empty; - var groupContent = string.Empty; - var groupContentNot = string.Empty; - var tags = string.Empty; - var order = string.Empty; - var totalNum = 0; - var titleWordNum = 0; - var where = string.Empty; - var queryString = string.Empty; - - var isTop = false; - var isTopExists = false; - var isRecommend = false; - var isRecommendExists = false; - var isHot = false; - var isHotExists = false; - var isColor = false; - var isColorExists = false; - - var displayTitle = string.Empty; - var openWin = true; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, IsChannel.Name)) - { - isChannel = TranslateUtils.ToBool(value); - } - else if (StringUtils.EqualsIgnoreCase(name, ChannelIndex.Name)) - { - channelIndex = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, ChannelName.Name)) - { - channelName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, UpLevel.Name)) - { - upLevel = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, TopLevel.Name)) - { - topLevel = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Scope.Name)) - { - scopeTypeString = value; - } - else if (StringUtils.EqualsIgnoreCase(name, GroupChannel.Name)) - { - groupChannel = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, GroupChannelNot.Name)) - { - groupChannelNot = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, GroupContent.Name)) - { - groupContent = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, GroupContentNot.Name)) - { - groupContentNot = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, Tags.Name)) - { - tags = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, Order.Name)) - { - order = value; - } - else if (StringUtils.EqualsIgnoreCase(name, TotalNum.Name)) - { - totalNum = TranslateUtils.ToInt(value, totalNum); - } - else if (StringUtils.EqualsIgnoreCase(name, Where.Name)) - { - where = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, QueryString.Name)) - { - queryString = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, IsTop.Name)) - { - isTopExists = true; - isTop = TranslateUtils.ToBool(value); - } - else if (StringUtils.EqualsIgnoreCase(name, IsRecommend.Name)) - { - isRecommendExists = true; - isRecommend = TranslateUtils.ToBool(value); - } - else if (StringUtils.EqualsIgnoreCase(name, IsHot.Name)) - { - isHotExists = true; - isHot = TranslateUtils.ToBool(value); - } - else if (StringUtils.EqualsIgnoreCase(name, IsColor.Name)) - { - isColorExists = true; - isColor = TranslateUtils.ToBool(value); - } - else if (StringUtils.EqualsIgnoreCase(name, TitleWordNum.Name)) - { - titleWordNum = TranslateUtils.ToInt(value, titleWordNum); - } - else if (StringUtils.EqualsIgnoreCase(name, Title.Name)) - { - displayTitle = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, OpenWin.Name)) - { - openWin = TranslateUtils.ToBool(value); - } - else - { - selectControl.Attributes[name] = value; - } - } - - return ParseImpl(pageInfo, contextInfo, selectControl, isChannel, channelIndex, channelName, upLevel, topLevel, scopeTypeString, groupChannel, groupChannelNot, groupContent, groupContentNot, tags, order, totalNum, titleWordNum, where, queryString, isTop, isTopExists, isRecommend, isRecommendExists, isHot, isHotExists, isColor, isColorExists, displayTitle, openWin); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, HtmlSelect selectControl, bool isChannel, string channelIndex, string channelName, int upLevel, int topLevel, string scopeTypeString, string groupChannel, string groupChannelNot, string groupContent, string groupContentNot, string tags, string order, int totalNum, int titleWordNum, string where, string queryString, bool isTop, bool isTopExists, bool isRecommend, bool isRecommendExists, bool isHot, bool isHotExists, bool isColor, bool isColorExists, string displayTitle, bool openWin) - { - EScopeType scopeType; - if (!string.IsNullOrEmpty(scopeTypeString)) - { - scopeType = EScopeTypeUtils.GetEnumType(scopeTypeString); - } - else - { - scopeType = isChannel ? EScopeType.Children : EScopeType.Self; - } - - var orderByString = isChannel ? StlDataUtility.GetChannelOrderByString(pageInfo.SiteId, order, ETaxisType.OrderByTaxis) : StlDataUtility.GetContentOrderByString(pageInfo.SiteId, order, ETaxisType.OrderByTaxisDesc); - - var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); - - channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, channelIndex, channelName); - - var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); - - var uniqueId = "Select_" + pageInfo.UniqueId; - selectControl.ID = uniqueId; - - string scriptHtml; - if (openWin) - { - scriptHtml = $@" -"; - selectControl.Attributes.Add("onChange", $"{uniqueId}_jumpMenu('parent',this)"); - } - else - { - scriptHtml = - $""; - selectControl.Attributes.Add("onChange", $"{uniqueId}_jumpMenu('self',this,0)"); - } - if (!string.IsNullOrEmpty(displayTitle)) - { - var listitem = new ListItem(displayTitle, PageUtils.UnclickedUrl) {Selected = true}; - selectControl.Items.Add(listitem); - } - - if (isChannel) - { - var channelIdList = StlDataUtility.GetChannelIdList(pageInfo.SiteId, channel.Id, orderByString, scopeType, groupChannel, groupChannelNot, false, false, totalNum, where); - - if (channelIdList != null && channelIdList.Count > 0) - { - foreach (var channelIdInSelect in channelIdList) - { - var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelIdInSelect); - - if (nodeInfo != null) - { - var title = StringUtils.MaxLengthText(nodeInfo.ChannelName, titleWordNum); - var url = PageUtility.GetChannelUrl(pageInfo.SiteInfo, nodeInfo, pageInfo.IsLocal); - if (!string.IsNullOrEmpty(queryString)) - { - url = PageUtils.AddQueryString(url, queryString); - } - var listitem = new ListItem(title, url); - selectControl.Items.Add(listitem); - } - } - } - } - else - { - var dataSource = StlDataUtility.GetContentsDataSource(pageInfo.SiteInfo, channelId, contextInfo.ContentId, groupContent, groupContentNot, tags, false, false, false, false, false, false, false, false, 1, totalNum, orderByString, isTopExists, isTop, isRecommendExists, isRecommend, isHotExists, isHot, isColorExists, isColor, where, scopeType, groupChannel, groupChannelNot, null); - - if (dataSource != null) - { - foreach (var dataItem in dataSource.Tables[0].Rows) - { - var contentInfo = new ContentInfo(dataItem); - if (contentInfo != null) - { - var title = StringUtils.MaxLengthText(contentInfo.Title, titleWordNum); - var url = PageUtility.GetContentUrl(pageInfo.SiteInfo, contentInfo, pageInfo.IsLocal); - if (!string.IsNullOrEmpty(queryString)) - { - url = PageUtils.AddQueryString(url, queryString); - } - var listitem = new ListItem(title, url); - selectControl.Items.Add(listitem); - } - } - //foreach (var dataItem in dataSource) - //{ - // var contentInfo = new BackgroundContentInfo(dataItem); - // if (contentInfo != null) - // { - // var title = StringUtils.MaxLengthText(contentInfo.Title, titleWordNum); - // var url = PageUtility.GetContentUrl(pageInfo.SiteInfo, contentInfo); - // if (!string.IsNullOrEmpty(queryString)) - // { - // url = PageUtils.AddQueryString(url, queryString); - // } - // var listitem = new ListItem(title, url); - // selectControl.Items.Add(listitem); - // } - //} - } - } - - return scriptHtml + ControlUtils.GetControlRenderHtml(selectControl); - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlSite.cs b/SiteServer.CMS/StlParser/StlElement/StlSite.cs deleted file mode 100644 index 1e740d7d2..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlSite.cs +++ /dev/null @@ -1,90 +0,0 @@ -using System.Text; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Parsers; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "获取站点值", Description = "通过 stl:site 标签在模板中显示站点值")] - public class StlSite - { - private StlSite() { } - public const string ElementName = "stl:site"; - - private static readonly Attr SiteName = new Attr("siteName", "站点名称"); - private static readonly Attr SiteDir = new Attr("siteDir", "站点文件夹"); - - //循环解析型标签 - internal static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var parsedContent = string.Empty; - - if (!string.IsNullOrEmpty(contextInfo.InnerXml)) - { - var siteName = string.Empty; - var siteDir = string.Empty; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, SiteName.Name)) - { - siteName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, SiteDir.Name)) - { - siteDir = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - } - - parsedContent = ParseImpl(pageInfo, contextInfo, siteName, siteDir); - } - - return parsedContent; - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string siteName, string siteDir) - { - SiteInfo siteInfo = null; - - if (!string.IsNullOrEmpty(siteName)) - { - siteInfo = SiteManager.GetSiteInfoBySiteName(siteName); - } - else if (!string.IsNullOrEmpty(siteDir)) - { - siteInfo = SiteManager.GetSiteInfoByDirectory(siteDir); - } - else - { - //var siteId = DataProvider.SiteDao.GetSiteIdByIsRoot(); - var siteId = Site.GetSiteIdByIsRoot(); - if (siteId > 0) - { - siteInfo = SiteManager.GetSiteInfo(siteId); - } - } - - if (siteInfo == null) return string.Empty; - - var preSiteInfo = pageInfo.SiteInfo; - var prePageChannelId = pageInfo.PageChannelId; - var prePageContentId = pageInfo.PageContentId; - - pageInfo.ChangeSite(siteInfo, siteInfo.Id, 0, contextInfo); - - var innerBuilder = new StringBuilder(contextInfo.InnerXml); - StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); - var parsedContent = innerBuilder.ToString(); - - pageInfo.ChangeSite(preSiteInfo, prePageChannelId, prePageContentId, contextInfo); - - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlSites.cs b/SiteServer.CMS/StlParser/StlElement/StlSites.cs deleted file mode 100644 index 9d1a43981..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlSites.cs +++ /dev/null @@ -1,123 +0,0 @@ -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "站点列表", Description = "通过 stl:sites 标签在模板中显示站点列表")] - public class StlSites - { - public const string ElementName = "stl:sites"; - - private static readonly Attr SiteName = new Attr("siteName", "站点名称"); - private static readonly Attr SiteDir = new Attr("siteDir", "站点文件夹"); - private static readonly Attr TotalNum = new Attr("totalNum", "填充"); - private static readonly Attr StartNum = new Attr("startNum", "间距"); - private static readonly Attr Where = new Attr("where", "Css类"); - private static readonly Attr Scope = new Attr("scope", "列数"); - private static readonly Attr Order = new Attr("order", "方向"); - private static readonly Attr Since = new Attr("since", "指定列表布局方式"); - private static readonly Attr CellPadding = new Attr("cellPadding", "整体高度"); - private static readonly Attr CellSpacing = new Attr("cellSpacing", "整体宽度"); - private static readonly Attr Class = new Attr("class", "整体对齐"); - private static readonly Attr Columns = new Attr("columns", "项高度"); - private static readonly Attr Direction = new Attr("direction", "项宽度"); - private static readonly Attr Height = new Attr("height", "项水平对齐"); - private static readonly Attr Width = new Attr("width", "项垂直对齐"); - private static readonly Attr Align = new Attr("align", "项Css类"); - private static readonly Attr ItemHeight = new Attr("itemHeight", "显示内容数目"); - private static readonly Attr ItemWidth = new Attr("itemWidth", "从第几条信息开始显示"); - private static readonly Attr ItemAlign = new Attr("itemAlign", "获取站点列表的条件判断"); - private static readonly Attr ItemVerticalAlign = new Attr("itemVerticalAlign", "范围"); - private static readonly Attr ItemClass = new Attr("itemClass", "排序"); - private static readonly Attr Layout = new Attr("layout", "时间段"); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var listInfo = ListInfo.GetListInfoByXmlNode(pageInfo, contextInfo, EContextType.Site); - - return ParseImpl(pageInfo, contextInfo, listInfo); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, ListInfo listInfo) - { - var parsedContent = string.Empty; - - var siteName = listInfo.Others.Get(SiteName.Name); - var siteDir = listInfo.Others.Get(SiteDir.Name); - var since = listInfo.Others.Get(Since.Name); - - if (listInfo.Layout == ELayout.None) - { - var rptContents = new Repeater - { - ItemTemplate = - new RepeaterTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, - listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, - pageInfo, EContextType.Site, contextInfo) - }; - - if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) - { - rptContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); - } - if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) - { - rptContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); - } - if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) - { - rptContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); - } - if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) - { - rptContents.AlternatingItemTemplate = new RepeaterTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Site, contextInfo); - } - - rptContents.DataSource = StlDataUtility.GetSitesDataSource(siteName, siteDir, listInfo.StartNum, listInfo.TotalNum, listInfo.Where, listInfo.Scope, listInfo.OrderByString, since); - rptContents.DataBind(); - - if (rptContents.Items.Count > 0) - { - parsedContent = ControlUtils.GetControlRenderHtml(rptContents); - } - } - else - { - var pdlContents = new ParsedDataList(); - - TemplateUtility.PutListInfoToMyDataList(pdlContents, listInfo); - - pdlContents.ItemTemplate = new DataListTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Site, contextInfo); - if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) - { - pdlContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); - } - if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) - { - pdlContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); - } - if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) - { - pdlContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); - } - if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) - { - pdlContents.AlternatingItemTemplate = new DataListTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Site, contextInfo); - } - - pdlContents.DataSource = StlDataUtility.GetSitesDataSource(siteName, siteDir, listInfo.StartNum, listInfo.TotalNum, listInfo.Where, listInfo.Scope, listInfo.OrderByString, since); - pdlContents.DataBind(); - - if (pdlContents.Items.Count > 0) - { - parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); - } - } - - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlSqlContent.cs b/SiteServer.CMS/StlParser/StlElement/StlSqlContent.cs deleted file mode 100644 index 71afbd708..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlSqlContent.cs +++ /dev/null @@ -1,192 +0,0 @@ -using System.Web.UI; -using SiteServer.Utils; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Parsers; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "数据库值", Description = "通过 stl:sqlContent 标签在模板中显示数据库值")] - public class StlSqlContent - { - private StlSqlContent() { } - public const string ElementName = "stl:sqlContent"; - - private static readonly Attr ConnectionStringName = new Attr("connectionStringName", "数据库链接字符串名称"); - private static readonly Attr ConnectionString = new Attr("connectionString", "数据库链接字符串"); - private static readonly Attr QueryString = new Attr("queryString", "数据库查询语句"); - private static readonly Attr Type = new Attr("type", "显示的类型"); - private static readonly Attr LeftText = new Attr("leftText", "显示在信息前的文字"); - private static readonly Attr RightText = new Attr("rightText", "显示在信息后的文字"); - private static readonly Attr FormatString = new Attr("formatString", "显示的格式"); - private static readonly Attr StartIndex = new Attr("startIndex", "字符开始位置"); - private static readonly Attr Length = new Attr("length", "指定字符长度"); - private static readonly Attr WordNum = new Attr("wordNum", "显示字符的数目"); - private static readonly Attr Ellipsis = new Attr("ellipsis", "文字超出部分显示的文字"); - private static readonly Attr Replace = new Attr("replace", "需要替换的文字,可以是正则表达式"); - private static readonly Attr To = new Attr("to", "替换replace的文字信息"); - private static readonly Attr IsClearTags = new Attr("isClearTags", "是否清除标签信息"); - private static readonly Attr IsReturnToBr = new Attr("isReturnToBr", "是否将回车替换为HTML换行标签"); - private static readonly Attr IsLower = new Attr("isLower", "是否转换为小写"); - private static readonly Attr IsUpper = new Attr("isUpper", "是否转换为大写"); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var connectionString = string.Empty; - var queryString = string.Empty; - - var leftText = string.Empty; - var rightText = string.Empty; - var formatString = string.Empty; - var startIndex = 0; - var length = 0; - var wordNum = 0; - var ellipsis = StringUtils.Constants.Ellipsis; - var replace = string.Empty; - var to = string.Empty; - var isClearTags = false; - var isReturnToBr = false; - var isLower = false; - var isUpper = false; - var type = string.Empty; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, ConnectionString.Name)) - { - connectionString = value; - } - else if (StringUtils.EqualsIgnoreCase(name, ConnectionStringName.Name)) - { - if (string.IsNullOrEmpty(connectionString)) - { - connectionString = WebConfigUtils.ConnectionString; - } - } - else if (StringUtils.EqualsIgnoreCase(name, QueryString.Name)) - { - queryString = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - } - else if (StringUtils.EqualsIgnoreCase(name, Type.Name)) - { - type = value.ToLower(); - } - else if (StringUtils.EqualsIgnoreCase(name, LeftText.Name)) - { - leftText = value; - } - else if (StringUtils.EqualsIgnoreCase(name, RightText.Name)) - { - rightText = value; - } - else if (StringUtils.EqualsIgnoreCase(name, FormatString.Name)) - { - formatString = value; - } - else if (StringUtils.EqualsIgnoreCase(name, StartIndex.Name)) - { - startIndex = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Length.Name)) - { - length = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, WordNum.Name)) - { - wordNum = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Ellipsis.Name)) - { - ellipsis = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Replace.Name)) - { - replace = value; - } - else if (StringUtils.EqualsIgnoreCase(name, To.Name)) - { - to = value; - } - else if (StringUtils.EqualsIgnoreCase(name, IsClearTags.Name)) - { - isClearTags = TranslateUtils.ToBool(value, false); - } - else if (StringUtils.EqualsIgnoreCase(name, IsReturnToBr.Name)) - { - isReturnToBr = TranslateUtils.ToBool(value, false); - } - else if (StringUtils.EqualsIgnoreCase(name, IsLower.Name)) - { - isLower = TranslateUtils.ToBool(value, true); - } - else if (StringUtils.EqualsIgnoreCase(name, IsUpper.Name)) - { - isUpper = TranslateUtils.ToBool(value, true); - } - } - - return ParseImpl(pageInfo, contextInfo, connectionString, queryString, leftText, rightText, formatString, startIndex, length, wordNum, ellipsis, replace, to, isClearTags, isReturnToBr, isLower, isUpper, type); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string connectionString, string queryString, string leftText, string rightText, string formatString, int startIndex, int length, int wordNum, string ellipsis, string replace, string to, bool isClearTags, bool isReturnToBr, bool isLower, bool isUpper, string type) - { - var parsedContent = string.Empty; - - if (!string.IsNullOrEmpty(type) && contextInfo.ItemContainer?.SqlItem != null) - { - if (!string.IsNullOrEmpty(formatString)) - { - formatString = formatString.Trim(); - if (!formatString.StartsWith("{0")) - { - formatString = "{0:" + formatString; - } - if (!formatString.EndsWith("}")) - { - formatString = formatString + "}"; - } - } - else - { - formatString = "{0}"; - } - - if (StringUtils.StartsWithIgnoreCase(type, StlParserUtility.ItemIndex)) - { - var itemIndex = StlParserUtility.ParseItemIndex(contextInfo.ItemContainer.SqlItem.ItemIndex, type, contextInfo); - - parsedContent = !string.IsNullOrEmpty(formatString) ? string.Format(formatString, itemIndex) : itemIndex.ToString(); - } - else - { - parsedContent = DataBinder.Eval(contextInfo.ItemContainer.SqlItem.DataItem, type, formatString); - } - } - else if (!string.IsNullOrEmpty(queryString)) - { - if (string.IsNullOrEmpty(connectionString)) - { - connectionString = WebConfigUtils.ConnectionString; - } - - //parsedContent = DataProvider.DatabaseDao.GetString(connectionString, queryString); - parsedContent = Database.GetString(connectionString, queryString); - } - - if (!string.IsNullOrEmpty(parsedContent)) - { - parsedContent = StringUtils.ParseString(parsedContent, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); - - if (!string.IsNullOrEmpty(parsedContent)) - { - parsedContent = leftText + parsedContent + rightText; - } - } - - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlSqlContents.cs b/SiteServer.CMS/StlParser/StlElement/StlSqlContents.cs deleted file mode 100644 index 6080a5182..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlSqlContents.cs +++ /dev/null @@ -1,116 +0,0 @@ -using System.Web.UI.WebControls; -using SiteServer.Utils; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "数据库列表", Description = "通过 stl:sqlContents 标签在模板中显示数据库列表")] - public class StlSqlContents - { - public const string ElementName = "stl:sqlContents"; - - public static readonly Attr ConnectionStringName = new Attr("connectionStringName", "数据库链接字符串名称"); - public static readonly Attr ConnectionString = new Attr("connectionString", "数据库链接字符串"); - public static readonly Attr TotalNum = new Attr("totalNum", "填充"); - public static readonly Attr StartNum = new Attr("startNum", "间距"); - public static readonly Attr Order = new Attr("order", "Css类"); - public static readonly Attr CellPadding = new Attr("cellPadding", "列数"); - public static readonly Attr CellSpacing = new Attr("cellSpacing", "方向"); - public static readonly Attr Class = new Attr("class", "指定列表布局方式"); - public static readonly Attr Columns = new Attr("columns", "整体高度"); - public static readonly Attr Direction = new Attr("direction", "整体宽度"); - public static readonly Attr Height = new Attr("height", "整体对齐"); - public static readonly Attr Width = new Attr("width", "项高度"); - public static readonly Attr Align = new Attr("align", "项宽度"); - public static readonly Attr ItemHeight = new Attr("itemHeight", "项水平对齐"); - public static readonly Attr ItemWidth = new Attr("itemWidth", "项垂直对齐"); - public static readonly Attr ItemAlign = new Attr("itemAlign", "项Css类"); - public static readonly Attr ItemVerticalAlign = new Attr("itemVerticalAlign", "显示内容数目"); - public static readonly Attr ItemClass = new Attr("itemClass", "从第几条信息开始显示"); - public static readonly Attr Layout = new Attr("layout", "排序"); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var listInfo = ListInfo.GetListInfoByXmlNode(pageInfo, contextInfo, EContextType.SqlContent); - - return ParseImpl(pageInfo, contextInfo, listInfo); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, ListInfo listInfo) - { - var parsedContent = string.Empty; - - if (listInfo.Layout == ELayout.None) - { - var rptContents = new Repeater - { - ItemTemplate = - new RepeaterTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, - listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, - EContextType.SqlContent, contextInfo) - }; - - if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) - { - rptContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); - } - if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) - { - rptContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); - } - if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) - { - rptContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); - } - if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) - { - rptContents.AlternatingItemTemplate = new RepeaterTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.SqlContent, contextInfo); - } - - rptContents.DataSource = StlDataUtility.GetSqlContentsDataSource(listInfo.ConnectionString, listInfo.QueryString, listInfo.StartNum, listInfo.TotalNum, listInfo.OrderByString); - rptContents.DataBind(); - - if (rptContents.Items.Count > 0) - { - parsedContent = ControlUtils.GetControlRenderHtml(rptContents); - } - } - else - { - var pdlContents = new ParsedDataList(); - - TemplateUtility.PutListInfoToMyDataList(pdlContents, listInfo); - - pdlContents.ItemTemplate = new DataListTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.SqlContent, contextInfo); - if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) - { - pdlContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); - } - if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) - { - pdlContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); - } - if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) - { - pdlContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); - } - if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) - { - pdlContents.AlternatingItemTemplate = new DataListTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.SqlContent, contextInfo); - } - - pdlContents.DataSource = StlDataUtility.GetSqlContentsDataSource(listInfo.ConnectionString, listInfo.QueryString, listInfo.StartNum, listInfo.TotalNum, listInfo.OrderByString); - pdlContents.DataBind(); - - if (pdlContents.Items.Count > 0) - { - parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); - } - } - - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlTabs.cs b/SiteServer.CMS/StlParser/StlElement/StlTabs.cs deleted file mode 100644 index 6e4b361b8..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlTabs.cs +++ /dev/null @@ -1,185 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Text; -using System.Xml; -using SiteServer.Utils; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "页签切换", Description = "通过 stl:tabs 标签在模板中显示页签切换")] - public class StlTabs - { - private StlTabs() { } - public const string ElementName = "stl:tabs"; - - private static readonly Attr TabName = new Attr("tabName", "页签名称"); - private static readonly Attr IsHeader = new Attr("isHeader", "是否为页签头部"); - private static readonly Attr Action = new Attr("action", "页签切换方式"); - private static readonly Attr ClassActive = new Attr("classActive", "当前显示页签头部的CSS类"); - private static readonly Attr ClassNormal = new Attr("classNormal", "当前隐藏页签头部的CSS类"); - private static readonly Attr Current = new Attr("current", "当前页签"); - - public const string ActionClick = "Click"; - public const string ActionMouseOver = "MouseOver"; - - public static SortedList ActionList => new SortedList - { - {ActionClick, "点击"}, - {ActionMouseOver, "鼠标移动"} - }; - - internal static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var tabName = string.Empty; - var isHeader = true; - var action = ActionMouseOver; - var classActive = "active"; - var classNormal = string.Empty; - var current = 0; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, TabName.Name)) - { - tabName = value; - } - else if (StringUtils.EqualsIgnoreCase(name, IsHeader.Name)) - { - isHeader = TranslateUtils.ToBool(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Action.Name)) - { - action = value; - } - else if (StringUtils.EqualsIgnoreCase(name, ClassActive.Name)) - { - classActive = value; - } - else if (StringUtils.EqualsIgnoreCase(name, ClassNormal.Name)) - { - classNormal = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Current.Name)) - { - current = TranslateUtils.ToInt(value, 1); - } - } - - return ParseImpl(pageInfo, contextInfo, tabName, isHeader, action, classActive, classNormal, current); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string tabName, bool isHeader, string action, string classActive, string classNormal, int current) - { - pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.Jquery); - - var builder = new StringBuilder(); - var uniqueId = pageInfo.UniqueId; - - if (contextInfo.ChildNodes.Count > 0) - { - if (isHeader) - { - builder.Append($@" - -"); - } - - var count = 0; - foreach (XmlNode xmlNode in contextInfo.ChildNodes) - { - if (xmlNode.NodeType != XmlNodeType.Element) continue; - var attributes = new NameValueCollection(); - if (xmlNode.Attributes != null) - { - var xmlIe = xmlNode.Attributes.GetEnumerator(); - while (xmlIe.MoveNext()) - { - var attr = (XmlAttribute)xmlIe.Current; - if (attr == null) continue; - - var attributeName = attr.Name.ToLower(); - if (!StringUtils.EqualsIgnoreCase(attr.Name, "id") && !StringUtils.EqualsIgnoreCase(attr.Name, "onmouseover") && !StringUtils.EqualsIgnoreCase(attr.Name, "onclick")) - { - attributes[attributeName] = attr.Value; - } - } - } - - count++; - if (isHeader) - { - attributes["id"] = $"{tabName}_tabHeader_{count}"; - if (StringUtils.EqualsIgnoreCase(action, ActionMouseOver)) - { - attributes["onmouseover"] = $"stl_tab_{uniqueId}('{tabName}', {count});return false;"; - } - else - { - attributes["onclick"] = $"stl_tab_{uniqueId}('{tabName}', {count});return false;"; - } - if (current != 0) - { - if (count == current) - { - attributes["class"] = classActive; - } - else - { - attributes["class"] = classNormal; - } - } - } - else - { - attributes["id"] = $"{tabName}_tabContent_{count}"; - if (current != 0) - { - if (count != current) - { - attributes["style"] = $"display:none;{attributes["style"]}"; - } - } - } - - var innerXml = string.Empty; - if (!string.IsNullOrEmpty(xmlNode.InnerXml)) - { - var innerBuilder = new StringBuilder(xmlNode.InnerXml); - StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); - StlParserUtility.XmlToHtml(innerBuilder); - innerXml = innerBuilder.ToString(); - } - - builder.Append( - $"<{xmlNode.Name} {TranslateUtils.ToAttributesString(attributes)}>{innerXml}"); - } - } - - return builder.ToString(); - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlTags.cs b/SiteServer.CMS/StlParser/StlElement/StlTags.cs deleted file mode 100644 index 218a06ed0..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlTags.cs +++ /dev/null @@ -1,147 +0,0 @@ -using System.Collections.Generic; -using System.Text; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.CMS.StlParser.Cache; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "标签", Description = "通过 stl:tags 标签在模板中显示内容标签")] - public class StlTags - { - private StlTags() { } - public const string ElementName = "stl:tags"; - - private static readonly Attr TagLevel = new Attr("tagLevel", "标签级别"); - private static readonly Attr TotalNum = new Attr("totalNum", "显示标签数目"); - private static readonly Attr IsOrderByCount = new Attr("isOrderByCount", "是否按引用次数排序"); - private static readonly Attr Theme = new Attr("theme", "主题样式"); - private static readonly Attr Context = new Attr("context", "所处上下文"); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var tagLevel = 1; - var totalNum = 0; - var isOrderByCount = false; - var theme = "default"; - var isInnerXml = !string.IsNullOrEmpty(contextInfo.InnerXml); - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, TagLevel.Name)) - { - tagLevel = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, TotalNum.Name)) - { - totalNum = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, IsOrderByCount.Name)) - { - isOrderByCount = TranslateUtils.ToBool(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Theme.Name)) - { - theme = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Context.Name)) - { - contextInfo.ContextType = EContextTypeUtils.GetEnumType(value); - } - } - - return ParseImpl(isInnerXml, pageInfo, contextInfo, tagLevel, totalNum, isOrderByCount, theme); - } - - private static string ParseImpl(bool isInnerXml, PageInfo pageInfo, ContextInfo contextInfo, int tagLevel, int totalNum, bool isOrderByCount, string theme) - { - var innerHtml = string.Empty; - if (isInnerXml) - { - innerHtml = StringUtils.StripTags(contextInfo.StlElement, ElementName); - } - - var tagsBuilder = new StringBuilder(); - if (!isInnerXml) - { - tagsBuilder.Append($@" - -"); - tagsBuilder.Append(@"
      "); - } - - if (contextInfo.ContextType == EContextType.Undefined) - { - contextInfo.ContextType = contextInfo.ContentId != 0 ? EContextType.Content : EContextType.Channel; - } - var contentId = 0; - if (contextInfo.ContextType == EContextType.Content) - { - contentId = contextInfo.ContentId; - } - - var tagInfoList = Tag.GetTagInfoList(pageInfo.SiteId, contentId, isOrderByCount, totalNum); - tagInfoList = TagUtils.GetTagInfoList(tagInfoList, totalNum, tagLevel); - if (contextInfo.ContextType == EContextType.Content && contextInfo.ContentInfo != null) - { - var tagInfoList2 = new List(); - var tagNameList = TranslateUtils.StringCollectionToStringList(contextInfo.ContentInfo.Tags.Trim().Replace(" ", ",")); - foreach (var tagName in tagNameList) - { - if (!string.IsNullOrEmpty(tagName)) - { - var isAdd = false; - foreach (var tagInfo in tagInfoList) - { - if (tagInfo.Tag == tagName) - { - isAdd = true; - tagInfoList2.Add(tagInfo); - break; - } - } - if (!isAdd) - { - var tagInfo = new TagInfo(0, pageInfo.SiteId, contentId.ToString(), tagName, 1); - tagInfoList2.Add(tagInfo); - } - } - } - tagInfoList = tagInfoList2; - } - - foreach (var tagInfo in tagInfoList) - { - if (isInnerXml) - { - var tagHtml = innerHtml; - tagHtml = StringUtils.ReplaceIgnoreCase(tagHtml, "{Tag.Name}", tagInfo.Tag); - tagHtml = StringUtils.ReplaceIgnoreCase(tagHtml, "{Tag.Count}", tagInfo.UseNum.ToString()); - tagHtml = StringUtils.ReplaceIgnoreCase(tagHtml, "{Tag.Level}", tagInfo.Level.ToString()); - var innerBuilder = new StringBuilder(tagHtml); - StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); - tagsBuilder.Append(innerBuilder); - } - else - { - var url = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, - $"@/utils/tags.html?tagName={PageUtils.UrlEncode(tagInfo.Tag)}", pageInfo.IsLocal); - tagsBuilder.Append($@" -
    • {tagInfo.Tag}
    • -"); - } - } - - if (!isInnerXml) - { - tagsBuilder.Append("
    "); - } - return tagsBuilder.ToString(); - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlValue.cs b/SiteServer.CMS/StlParser/StlElement/StlValue.cs deleted file mode 100644 index e409f32c0..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlValue.cs +++ /dev/null @@ -1,196 +0,0 @@ -using System.Collections.Generic; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.StlParser.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "获取值", Description = "通过 stl:value 标签在模板中获取值")] - public class StlValue - { - private StlValue(){} - public const string ElementName = "stl:value"; - - private static readonly Attr Type = new Attr("type", "类型"); - private static readonly Attr FormatString = new Attr("formatString", "显示的格式"); - private static readonly Attr Separator = new Attr("separator", "显示多项时的分割字符串"); - private static readonly Attr StartIndex = new Attr("startIndex", "字符开始位置"); - private static readonly Attr Length = new Attr("length", "指定字符长度"); - private static readonly Attr WordNum = new Attr("wordNum", "显示字符的数目"); - private static readonly Attr Ellipsis = new Attr("ellipsis", "文字超出部分显示的文字"); - private static readonly Attr Replace = new Attr("replace", "需要替换的文字,可以是正则表达式"); - private static readonly Attr To = new Attr("to", "替换replace的文字信息"); - private static readonly Attr IsClearTags = new Attr("isClearTags", "是否清除标签信息"); - private static readonly Attr IsReturnToBr = new Attr("isReturnToBr", "是否将回车替换为HTML换行标签"); - private static readonly Attr IsLower = new Attr("isLower", "是否转换为小写"); - private static readonly Attr IsUpper = new Attr("isUpper", "是否转换为大写"); - - public const string TypeSiteName = "SiteName"; - public const string TypeSiteUrl = "SiteUrl"; - public const string TypeDate = "Date"; - public const string TypeDateOfTraditional = "DateOfTraditional"; - - public static SortedList TypeList => new SortedList - { - {TypeSiteName, "站点名称"}, - {TypeSiteUrl, "站点的域名地址"}, - {TypeDate, "当前日期"}, - {TypeDateOfTraditional, "带农历的当前日期"} - }; - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var type = string.Empty; - var formatString = string.Empty; - string separator = null; - var startIndex = 0; - var length = 0; - var wordNum = 0; - var ellipsis = StringUtils.Constants.Ellipsis; - var replace = string.Empty; - var to = string.Empty; - var isClearTags = false; - var isReturnToBr = false; - var isLower = false; - var isUpper = false; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, Type.Name)) - { - type = value; - } - else if (StringUtils.EqualsIgnoreCase(name, FormatString.Name)) - { - formatString = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Separator.Name)) - { - separator = value; - } - else if (StringUtils.EqualsIgnoreCase(name, StartIndex.Name)) - { - startIndex = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Length.Name)) - { - length = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, WordNum.Name)) - { - wordNum = TranslateUtils.ToInt(value); - } - else if (StringUtils.EqualsIgnoreCase(name, Ellipsis.Name)) - { - ellipsis = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Replace.Name)) - { - replace = value; - } - else if (StringUtils.EqualsIgnoreCase(name, To.Name)) - { - to = value; - } - else if (StringUtils.EqualsIgnoreCase(name, IsClearTags.Name)) - { - isClearTags = TranslateUtils.ToBool(value, false); - } - else if (StringUtils.EqualsIgnoreCase(name, IsReturnToBr.Name)) - { - isReturnToBr = TranslateUtils.ToBool(value, false); - } - else if (StringUtils.EqualsIgnoreCase(name, IsLower.Name)) - { - isLower = TranslateUtils.ToBool(value, true); - } - else if (StringUtils.EqualsIgnoreCase(name, IsUpper.Name)) - { - isUpper = TranslateUtils.ToBool(value, true); - } - } - - return ParseImpl(pageInfo, contextInfo, type, formatString, separator, startIndex, length, wordNum, ellipsis, replace, to, isClearTags, isReturnToBr, isLower, isUpper); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string type, string formatString, string separator, int startIndex, int length, int wordNum, string ellipsis, string replace, string to, bool isClearTags, bool isReturnToBr, bool isLower, bool isUpper) - { - if (string.IsNullOrEmpty(type)) return string.Empty; - - var parsedContent = string.Empty; - - if (contextInfo.ContextType == EContextType.Each) - { - parsedContent = contextInfo.ItemContainer.EachItem.DataItem as string; - return parsedContent; - } - - if (type.ToLower().Equals(TypeSiteName.ToLower())) - { - parsedContent = pageInfo.SiteInfo.SiteName; - } - else if (type.ToLower().Equals(TypeSiteUrl.ToLower())) - { - parsedContent = pageInfo.SiteInfo.Additional.WebUrl; - } - else if (type.ToLower().Equals(TypeDate.ToLower())) - { - if (!pageInfo.BodyCodes.ContainsKey("datestring.js")) - { - pageInfo.BodyCodes.Add("datestring.js", $@""); - } - - parsedContent = @""; - } - else if (type.ToLower().Equals(TypeDateOfTraditional.ToLower())) - { - if (!pageInfo.BodyCodes.ContainsKey("datestring")) - { - pageInfo.BodyCodes.Add("datestring", $@""); - } - - parsedContent = @""; - } - else if (pageInfo.Parameters != null && pageInfo.Parameters.ContainsKey(type)) - { - pageInfo.Parameters.TryGetValue(type, out parsedContent); - parsedContent = StringUtils.ParseString(InputType.Text, parsedContent, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); - } - else - { - if (pageInfo.SiteInfo.Additional.GetString(type) != null) - { - parsedContent = pageInfo.SiteInfo.Additional.GetString(type); - if (!string.IsNullOrEmpty(parsedContent)) - { - var styleInfo = TableStyleManager.GetTableStyleInfo(DataProvider.SiteDao.TableName, type, RelatedIdentities.GetRelatedIdentities(pageInfo.SiteId, pageInfo.SiteId)); - - // 如果 styleInfo.TableStyleId <= 0,表示此字段已经被删除了,不需要再显示值了 ekun008 - if (styleInfo.Id > 0) - { - if (isClearTags && InputTypeUtils.EqualsAny(styleInfo.InputType, InputType.Image, InputType.File)) - { - parsedContent = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); - } - else - { - parsedContent = InputParserUtility.GetContentByTableStyle(parsedContent, separator, pageInfo.SiteInfo, styleInfo, formatString, contextInfo.Attributes, contextInfo.InnerXml, false); - parsedContent = StringUtils.ParseString(styleInfo.InputType, parsedContent, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); - } - } - else - { // 如果字段已经被删除或不再显示了,则此字段的值为空。有时虚拟字段值不会清空 - parsedContent = string.Empty; - } - } - } - } - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlVideo.cs b/SiteServer.CMS/StlParser/StlElement/StlVideo.cs deleted file mode 100644 index 8a89c0618..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlVideo.cs +++ /dev/null @@ -1,234 +0,0 @@ -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Parsers; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "播放视频", Description = "通过 stl:video 标签在模板中显示视频播放器")] - public class StlVideo - { - private StlVideo() { } - public const string ElementName = "stl:video"; - - private static readonly Attr ChannelIndex = new Attr("channelIndex", "栏目索引"); - private static readonly Attr ChannelName = new Attr("channelName", "栏目名称"); - private static readonly Attr Parent = new Attr("parent", "显示父栏目"); - private static readonly Attr UpLevel = new Attr("upLevel", "上级栏目的级别"); - private static readonly Attr TopLevel = new Attr("topLevel", "从首页向下的栏目级别"); - private static readonly Attr Type = new Attr("type", "指定视频的字段"); - private static readonly Attr PlayUrl = new Attr("playUrl", "视频地址"); - private static readonly Attr ImageUrl = new Attr("imageUrl", "图片地址"); - private static readonly Attr Width = new Attr("width", "宽度"); - private static readonly Attr Height = new Attr("height", "高度"); - private static readonly Attr IsAutoPlay = new Attr("isAutoPlay", "是否自动播放"); - private static readonly Attr IsControls = new Attr("isControls", "是否显示播放控件"); - private static readonly Attr IsPreload = new Attr("isPreload", "是否预载入"); - private static readonly Attr IsLoop = new Attr("isLoop", "是否循环播放"); - - public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) - { - var isGetUrlFromAttribute = false; - var channelIndex = string.Empty; - var channelName = string.Empty; - var upLevel = 0; - var topLevel = -1; - var type = BackgroundContentAttribute.VideoUrl; - var playUrl = string.Empty; - var imageUrl = string.Empty; - var width = pageInfo.SiteInfo.Additional.ConfigVideoContentInsertWidth; - var height = pageInfo.SiteInfo.Additional.ConfigVideoContentInsertHeight; - var isAutoPlay = true; - var isControls = true; - var isPreLoad = true; - var isLoop = false; - - foreach (var name in contextInfo.Attributes.Keys) - { - var value = contextInfo.Attributes[name]; - - if (StringUtils.EqualsIgnoreCase(name, ChannelIndex.Name)) - { - channelIndex = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - if (!string.IsNullOrEmpty(channelIndex)) - { - isGetUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, ChannelName.Name)) - { - channelName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); - if (!string.IsNullOrEmpty(channelName)) - { - isGetUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, Parent.Name)) - { - if (TranslateUtils.ToBool(value)) - { - upLevel = 1; - isGetUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, UpLevel.Name)) - { - upLevel = TranslateUtils.ToInt(value); - if (upLevel > 0) - { - isGetUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, TopLevel.Name)) - { - topLevel = TranslateUtils.ToInt(value); - if (topLevel >= 0) - { - isGetUrlFromAttribute = true; - } - } - else if (StringUtils.EqualsIgnoreCase(name, Type.Name)) - { - type = value; - } - else if (StringUtils.EqualsIgnoreCase(name, PlayUrl.Name)) - { - playUrl = value; - } - else if (StringUtils.EqualsIgnoreCase(name, ImageUrl.Name)) - { - imageUrl = value; - } - else if (StringUtils.EqualsIgnoreCase(name, Width.Name)) - { - width = TranslateUtils.ToInt(value, width); - } - else if (StringUtils.EqualsIgnoreCase(name, Height.Name)) - { - height = TranslateUtils.ToInt(value, height); - } - else if (StringUtils.EqualsIgnoreCase(name, IsAutoPlay.Name)) - { - isAutoPlay = TranslateUtils.ToBool(value, true); - } - else if (StringUtils.EqualsIgnoreCase(name, IsControls.Name)) - { - isControls = TranslateUtils.ToBool(value, true); - } - else if (StringUtils.EqualsIgnoreCase(name, IsPreload.Name)) - { - isPreLoad = TranslateUtils.ToBool(value, true); - } - else if (StringUtils.EqualsIgnoreCase(name, IsLoop.Name)) - { - isLoop = TranslateUtils.ToBool(value, false); - } - } - - return ParseImpl(pageInfo, contextInfo, isGetUrlFromAttribute, channelIndex, channelName, upLevel, topLevel, type, playUrl, imageUrl, width, height, isAutoPlay, isControls, isPreLoad, isLoop); - } - - private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, bool isGetUrlFromAttribute, string channelIndex, string channelName, int upLevel, int topLevel, string type, string playUrl, string imageUrl, int width, int height, bool isAutoPlay, bool isControls, bool isPreLoad, bool isLoop) - { - var parsedContent = string.Empty; - - var contentId = 0; - //判断是否地址由标签属性获得 - if (!isGetUrlFromAttribute) - { - contentId = contextInfo.ContentId; - } - - var videoUrl = string.Empty; - if (!string.IsNullOrEmpty(playUrl)) - { - videoUrl = playUrl; - } - else - { - if (contextInfo.ContextType == EContextType.Content) - { - if (contentId != 0)//获取内容视频 - { - if (contextInfo.ContentInfo == null) - { - //videoUrl = DataProvider.ContentDao.GetValue(pageInfo.SiteInfo.AuxiliaryTableForContent, contentId, type); - videoUrl = Content.GetValue(pageInfo.SiteInfo.TableName, contentId, type); - if (string.IsNullOrEmpty(videoUrl)) - { - if (!StringUtils.EqualsIgnoreCase(type, BackgroundContentAttribute.VideoUrl)) - { - //videoUrl = DataProvider.ContentDao.GetValue(pageInfo.SiteInfo.AuxiliaryTableForContent, contentId, BackgroundContentAttribute.VideoUrl); - videoUrl = Content.GetValue(pageInfo.SiteInfo.TableName, contentId, BackgroundContentAttribute.VideoUrl); - } - } - if (string.IsNullOrEmpty(videoUrl)) - { - if (!StringUtils.EqualsIgnoreCase(type, BackgroundContentAttribute.FileUrl)) - { - //videoUrl = DataProvider.ContentDao.GetValue(pageInfo.SiteInfo.AuxiliaryTableForContent, contentId, BackgroundContentAttribute.FileUrl); - videoUrl = Content.GetValue(pageInfo.SiteInfo.TableName, contentId, BackgroundContentAttribute.FileUrl); - } - } - } - else - { - videoUrl = contextInfo.ContentInfo.GetString(type); - if (string.IsNullOrEmpty(videoUrl)) - { - videoUrl = contextInfo.ContentInfo.GetString(BackgroundContentAttribute.VideoUrl); - } - if (string.IsNullOrEmpty(videoUrl)) - { - videoUrl = contextInfo.ContentInfo.GetString(BackgroundContentAttribute.FileUrl); - } - } - } - } - else if (contextInfo.ContextType == EContextType.Each) - { - videoUrl = contextInfo.ItemContainer.EachItem.DataItem as string; - } - } - - if (string.IsNullOrEmpty(imageUrl)) - { - if (contentId != 0) - { - //imageUrl = contextInfo.ContentInfo == null ? DataProvider.ContentDao.GetValue(pageInfo.SiteInfo.AuxiliaryTableForContent, contentId, BackgroundContentAttribute.ImageUrl) : contextInfo.ContentInfo.GetString(BackgroundContentAttribute.ImageUrl); - imageUrl = contextInfo.ContentInfo == null ? Content.GetValue(pageInfo.SiteInfo.TableName, contentId, BackgroundContentAttribute.ImageUrl) : contextInfo.ContentInfo.GetString(BackgroundContentAttribute.ImageUrl); - } - } - - if (string.IsNullOrEmpty(imageUrl)) - { - var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); - channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, channelIndex, channelName); - var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); - imageUrl = channel.ImageUrl; - } - - if (!string.IsNullOrEmpty(videoUrl)) - { - videoUrl = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, videoUrl, pageInfo.IsLocal); - imageUrl = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, imageUrl, pageInfo.IsLocal); - - pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.JsAcVideoJs); - - parsedContent = - $@""; - } - - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlElement/StlYes.cs b/SiteServer.CMS/StlParser/StlElement/StlYes.cs deleted file mode 100644 index 63b9a9fb1..000000000 --- a/SiteServer.CMS/StlParser/StlElement/StlYes.cs +++ /dev/null @@ -1,11 +0,0 @@ -using SiteServer.CMS.StlParser.Model; - -namespace SiteServer.CMS.StlParser.StlElement -{ - [StlClass(Usage = "成功模板", Description = "通过 stl:yes 标签在模板中显示成功模板")] - public sealed class StlYes - { - public const string ElementName = "stl:yes"; - public const string ElementName2 = "stl:successtemplate"; - } -} diff --git a/SiteServer.CMS/StlParser/StlEntity/StlChannelEntities.cs b/SiteServer.CMS/StlParser/StlEntity/StlChannelEntities.cs deleted file mode 100644 index a0b21756a..000000000 --- a/SiteServer.CMS/StlParser/StlEntity/StlChannelEntities.cs +++ /dev/null @@ -1,208 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Plugin; - -namespace SiteServer.CMS.StlParser.StlEntity -{ - [StlClass(Usage = "栏目实体", Description = "通过 {channel.} 实体在模板中显示栏目值")] - public class StlChannelEntities - { - private StlChannelEntities() - { - } - - public const string EntityName = "channel"; - - public const string ChannelId = "ChannelID"; - public const string ChannelName = "ChannelName"; - public const string ChannelIndex = "ChannelIndex"; - public const string Title = "Title"; - public const string Content = "Content"; - public const string NavigationUrl = "NavigationUrl"; - public const string ImageUrl = "ImageUrl"; - public const string AddDate = "AddDate"; - public const string DirectoryName = "DirectoryName"; - public const string Group = "Group"; - public const string ItemIndex = "ItemIndex"; - - public static SortedList AttributeList => new SortedList - { - {ChannelId, "栏目ID"}, - {Title, "栏目名称"}, - {ChannelName, "栏目名称"}, - {ChannelIndex, "栏目索引"}, - {Content, "栏目正文"}, - {NavigationUrl, "栏目链接地址"}, - {ImageUrl, "栏目图片地址"}, - {AddDate, "栏目添加日期"}, - {DirectoryName, "生成文件夹名称"}, - {Group, "栏目组别"}, - {ItemIndex, "栏目排序"} - }; - - internal static string Parse(string stlEntity, PageInfo pageInfo, ContextInfo contextInfo) - { - var parsedContent = string.Empty; - - try - { - var entityName = StlParserUtility.GetNameFromEntity(stlEntity); - var channelIndex = StlParserUtility.GetValueFromEntity(stlEntity); - var attributeName = entityName.Substring(9, entityName.Length - 10); - - var upLevel = 0; - var topLevel = -1; - var channelId = contextInfo.ChannelId; - if (!string.IsNullOrEmpty(channelIndex)) - { - //channelId = DataProvider.ChannelDao.GetIdByIndexName(pageInfo.SiteId, channelIndex); - channelId = Node.GetIdByIndexName(pageInfo.SiteId, channelIndex); - if (channelId == 0) - { - channelId = contextInfo.ChannelId; - } - } - - if (attributeName.ToLower().StartsWith("up") && attributeName.IndexOf(".", StringComparison.Ordinal) != -1) - { - if (attributeName.ToLower().StartsWith("up.")) - { - upLevel = 1; - } - else - { - var upLevelStr = attributeName.Substring(2, attributeName.IndexOf(".", StringComparison.Ordinal) - 2); - upLevel = TranslateUtils.ToInt(upLevelStr); - } - topLevel = -1; - attributeName = attributeName.Substring(attributeName.IndexOf(".", StringComparison.Ordinal) + 1); - } - else if (attributeName.ToLower().StartsWith("top") && attributeName.IndexOf(".", StringComparison.Ordinal) != -1) - { - if (attributeName.ToLower().StartsWith("top.")) - { - topLevel = 1; - } - else - { - var topLevelStr = attributeName.Substring(3, attributeName.IndexOf(".", StringComparison.Ordinal) - 3); - topLevel = TranslateUtils.ToInt(topLevelStr); - } - upLevel = 0; - attributeName = attributeName.Substring(attributeName.IndexOf(".", StringComparison.Ordinal) + 1); - } - - var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, channelId, upLevel, topLevel)); - - if (StringUtils.EqualsIgnoreCase(ChannelId, attributeName))//栏目ID - { - parsedContent = nodeInfo.Id.ToString(); - } - else if (StringUtils.EqualsIgnoreCase(Title, attributeName) || StringUtils.EqualsIgnoreCase(ChannelName, attributeName))//栏目名称 - { - parsedContent = nodeInfo.ChannelName; - } - else if (StringUtils.EqualsIgnoreCase(ChannelIndex, attributeName))//栏目索引 - { - parsedContent = nodeInfo.IndexName; - } - else if (StringUtils.EqualsIgnoreCase(Content, attributeName))//栏目正文 - { - parsedContent = ContentUtility.TextEditorContentDecode(pageInfo.SiteInfo, nodeInfo.Content, pageInfo.IsLocal); - } - else if (StringUtils.EqualsIgnoreCase(NavigationUrl, attributeName))//栏目链接地址 - { - parsedContent = PageUtility.GetChannelUrl(pageInfo.SiteInfo, nodeInfo, pageInfo.IsLocal); - } - else if (StringUtils.EqualsIgnoreCase(ImageUrl, attributeName))//栏目图片地址 - { - parsedContent = nodeInfo.ImageUrl; - - if (!string.IsNullOrEmpty(parsedContent)) - { - parsedContent = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); - } - } - else if (StringUtils.EqualsIgnoreCase(AddDate, attributeName))//栏目添加日期 - { - parsedContent = DateUtils.Format(nodeInfo.AddDate, string.Empty); - } - else if (StringUtils.EqualsIgnoreCase(DirectoryName, attributeName))//生成文件夹名称 - { - parsedContent = PathUtils.GetDirectoryName(nodeInfo.FilePath, true); - } - else if (StringUtils.EqualsIgnoreCase(Group, attributeName))//栏目组别 - { - parsedContent = nodeInfo.GroupNameCollection; - } - else if (StringUtils.StartsWithIgnoreCase(attributeName, StlParserUtility.ItemIndex) && contextInfo.ItemContainer?.ChannelItem != null) - { - parsedContent = StlParserUtility.ParseItemIndex(contextInfo.ItemContainer.ChannelItem.ItemIndex, attributeName, contextInfo).ToString(); - } - else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.Keywords, attributeName))//栏目组别 - { - parsedContent = nodeInfo.Keywords; - } - else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.Description, attributeName))//栏目组别 - { - parsedContent = nodeInfo.Description; - } - else - { - //var styleInfo = TableStyleManager.GetTableStyleInfo(ETableStyle.Channel, DataProvider.ChannelDao.TableName, attributeName, RelatedIdentities.GetChannelRelatedIdentities(pageInfo.SiteId, nodeInfo.ChannelId)); - //parsedContent = InputParserUtility.GetContentByTableStyle(parsedContent, ",", pageInfo.SiteInfo, ETableStyle.Channel, styleInfo, string.Empty, null, string.Empty, true); - - var formCollection = nodeInfo.Additional.ToNameValueCollection(); - if (formCollection != null && formCollection.Count > 0) - { - var styleInfo = TableStyleManager.GetTableStyleInfo(DataProvider.ChannelDao.TableName, attributeName, RelatedIdentities.GetChannelRelatedIdentities(pageInfo.SiteId, nodeInfo.Id)); - // 如果 styleInfo.TableStyleId <= 0,表示此字段已经被删除了,不需要再显示值了 ekun008 - if (styleInfo.Id > 0) - { - parsedContent = GetValue(attributeName, formCollection, false, styleInfo.DefaultValue); - if (!string.IsNullOrEmpty(parsedContent)) - { - if (InputTypeUtils.EqualsAny(styleInfo.InputType, InputType.Image, InputType.File)) - { - parsedContent = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); - } - else - { - parsedContent = InputParserUtility.GetContentByTableStyle(parsedContent, null, pageInfo.SiteInfo, styleInfo, string.Empty, null, string.Empty, true); - } - } - } - } - } - } - catch - { - // ignored - } - - return parsedContent; - } - - private static string GetValue(string attributeName, NameValueCollection formCollection, bool isAddAndNotPostBack, string defaultValue) - { - var value = string.Empty; - if (formCollection?[attributeName] != null) - { - value = formCollection[attributeName]; - } - if (isAddAndNotPostBack && string.IsNullOrEmpty(value)) - { - value = defaultValue; - } - - return value; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlEntity/StlContentEntities.cs b/SiteServer.CMS/StlParser/StlEntity/StlContentEntities.cs deleted file mode 100644 index 30daa4ca7..000000000 --- a/SiteServer.CMS/StlParser/StlEntity/StlContentEntities.cs +++ /dev/null @@ -1,341 +0,0 @@ -using System.Collections.Generic; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlEntity -{ - [StlClass(Usage = "内容实体", Description = "通过 {content.} 实体在模板中显示内容值")] - public class StlContentEntities - { - private StlContentEntities() - { - } - - public const string EntityName = "content"; - - public const string Id = "Id"; - public const string Title = "Title"; - public const string FullTitle = "FullTitle"; - public const string NavigationUrl = "NavigationUrl"; - public const string ImageUrl = "ImageUrl"; - public const string VideoUrl = "VideoUrl"; - public const string FileUrl = "FileUrl"; - public const string DownloadUrl = "DownloadUrl"; - public const string AddDate = "AddDate"; - public const string LastEditDate = "LastEditDate"; - public const string Content = "Content"; - public const string Group = "Group"; - public const string Tags = "Tags"; - public const string AddUserName = "AddUserName"; - public const string ItemIndex = "ItemIndex"; - - public static SortedList AttributeList => new SortedList - { - {Id, "内容ID"}, - {Title, "内容标题"}, - {FullTitle, "内容标题全称"}, - {Content, "内容正文"}, - {NavigationUrl, "内容链接地址"}, - {ImageUrl, "内容图片地址"}, - {VideoUrl, "内容视频地址"}, - {FileUrl, "内容附件地址"}, - {DownloadUrl, "内容附件地址(可统计下载量)"}, - {AddDate, "内容添加日期"}, - {LastEditDate, "内容最后修改日期"}, - {Group, "内容组别"}, - {Tags, "内容标签"}, - {AddUserName, "内容添加人"}, - {ItemIndex, "内容排序"} - }; - - internal static string Parse(string stlEntity, PageInfo pageInfo, ContextInfo contextInfo) - { - var parsedContent = string.Empty; - - if (contextInfo.ContentId != 0) - { - try - { - if (contextInfo.ContentInfo != null && contextInfo.ContentInfo.ReferenceId > 0 && contextInfo.ContentInfo.SourceId > 0 && contextInfo.ContentInfo.GetString(ContentAttribute.TranslateContentType) != ETranslateContentType.ReferenceContent.ToString()) - { - var targetChannelId = contextInfo.ContentInfo.SourceId; - //var targetSiteId = DataProvider.ChannelDao.GetSiteId(targetChannelId); - var targetSiteId = Node.GetSiteId(targetChannelId); - var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); - var targetNodeInfo = ChannelManager.GetChannelInfo(targetSiteId, targetChannelId); - - var tableName = ChannelManager.GetTableName(targetSiteInfo, targetNodeInfo); - //var targetContentInfo = DataProvider.ContentDao.GetContentInfo(tableStyle, tableName, contextInfo.ContentInfo.ReferenceId); - var targetContentInfo = Cache.Content.GetContentInfo(tableName, contextInfo.ContentInfo.ReferenceId); - if (targetContentInfo != null && targetContentInfo.ChannelId > 0) - { - //标题可以使用自己的 - targetContentInfo.Title = contextInfo.ContentInfo.Title; - - contextInfo.ContentInfo = targetContentInfo; - } - } - - var entityName = StlParserUtility.GetNameFromEntity(stlEntity); - var attributeName = entityName.Substring(9, entityName.Length - 10); - - if (StringUtils.EqualsIgnoreCase(ContentAttribute.Id, attributeName))//内容ID - { - if (contextInfo.ContentInfo != null) - { - parsedContent = contextInfo.ContentInfo.ReferenceId > 0 ? contextInfo.ContentInfo.ReferenceId.ToString() : contextInfo.ContentInfo.Id.ToString(); - } - else - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId)); - //parsedContent = DataProvider.ContentDao.GetValue(tableName, contextInfo.ContentId, ContentAttribute.Id); - parsedContent = Cache.Content.GetValue(tableName, contextInfo.ContentId, ContentAttribute.Id); - } - } - else if (StringUtils.EqualsIgnoreCase(Title, attributeName))//内容标题 - { - if (contextInfo.ContentInfo != null) - { - parsedContent = contextInfo.ContentInfo.Title; - } - else - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId)); - //parsedContent = DataProvider.ContentDao.GetValue(tableName, contextInfo.ContentId, ContentAttribute.Title); - parsedContent = Cache.Content.GetValue(tableName, contextInfo.ContentId, ContentAttribute.Title); - } - } - else if (StringUtils.EqualsIgnoreCase(FullTitle, attributeName))//内容标题全称 - { - if (contextInfo.ContentInfo != null) - { - parsedContent = contextInfo.ContentInfo.Title; - } - else - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId)); - //parsedContent = DataProvider.ContentDao.GetValue(tableName, contextInfo.ContentId, ContentAttribute.Title); - parsedContent = Cache.Content.GetValue(tableName, contextInfo.ContentId, ContentAttribute.Title); - } - } - else if (StringUtils.EqualsIgnoreCase(NavigationUrl, attributeName))//内容链接地址 - { - if (contextInfo.ContentInfo != null) - { - parsedContent = PageUtility.GetContentUrl(pageInfo.SiteInfo, contextInfo.ContentInfo, pageInfo.IsLocal); - } - else - { - var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); - parsedContent = PageUtility.GetContentUrl(pageInfo.SiteInfo, nodeInfo, contextInfo.ContentId, pageInfo.IsLocal); - } - } - else if (StringUtils.EqualsIgnoreCase(ImageUrl, attributeName))//内容图片地址 - { - if (contextInfo.ContentInfo != null) - { - parsedContent = contextInfo.ContentInfo.GetString(BackgroundContentAttribute.ImageUrl); - } - else - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId)); - //parsedContent = DataProvider.ContentDao.GetValue(tableName, contextInfo.ContentId, BackgroundContentAttribute.ImageUrl); - parsedContent = Cache.Content.GetValue(tableName, contextInfo.ContentId, BackgroundContentAttribute.ImageUrl); - } - - if (!string.IsNullOrEmpty(parsedContent)) - { - parsedContent = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); - } - } - else if (StringUtils.EqualsIgnoreCase(VideoUrl, attributeName))//内容视频地址 - { - if (contextInfo.ContentInfo != null) - { - parsedContent = contextInfo.ContentInfo.GetString(BackgroundContentAttribute.VideoUrl); - } - else - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId)); - //parsedContent = DataProvider.ContentDao.GetValue(tableName, contextInfo.ContentId, BackgroundContentAttribute.VideoUrl); - parsedContent = Cache.Content.GetValue(tableName, contextInfo.ContentId, BackgroundContentAttribute.VideoUrl); - } - - if (!string.IsNullOrEmpty(parsedContent)) - { - parsedContent = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); - } - } - else if (StringUtils.EqualsIgnoreCase(FileUrl, attributeName))//内容附件地址 - { - if (contextInfo.ContentInfo != null) - { - parsedContent = contextInfo.ContentInfo.GetString(BackgroundContentAttribute.FileUrl); - } - else - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId)); - //parsedContent = DataProvider.ContentDao.GetValue(tableName, contextInfo.ContentId, BackgroundContentAttribute.FileUrl); - parsedContent = Cache.Content.GetValue(tableName, contextInfo.ContentId, BackgroundContentAttribute.FileUrl); - } - - if (!string.IsNullOrEmpty(parsedContent)) - { - parsedContent = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); - } - } - else if (StringUtils.EqualsIgnoreCase(DownloadUrl, attributeName))//内容附件地址(可统计下载量) - { - if (contextInfo.ContentInfo != null) - { - parsedContent = contextInfo.ContentInfo.GetString(BackgroundContentAttribute.FileUrl); - } - else - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId)); - //parsedContent = DataProvider.ContentDao.GetValue(tableName, contextInfo.ContentId, BackgroundContentAttribute.FileUrl); - parsedContent = Cache.Content.GetValue(tableName, contextInfo.ContentId, BackgroundContentAttribute.FileUrl); - } - - if (!string.IsNullOrEmpty(parsedContent)) - { - parsedContent = ApiRouteActionsDownload.GetUrl(pageInfo.ApiUrl, pageInfo.SiteId, contextInfo.ChannelId, contextInfo.ContentId, parsedContent); - } - } - else if (StringUtils.EqualsIgnoreCase(AddDate, attributeName))//内容添加日期 - { - if (contextInfo.ContentInfo != null) - { - parsedContent = DateUtils.Format(contextInfo.ContentInfo.AddDate, string.Empty); - } - else - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, contextInfo.ChannelId); - //parsedContent = DateUtils.Format(DataProvider.ContentDao.GetAddDate(tableName, contextInfo.ContentId), string.Empty); - parsedContent = DateUtils.Format(Cache.Content.GetAddDate(tableName, contextInfo.ContentId), string.Empty); - } - } - else if (StringUtils.EqualsIgnoreCase(LastEditDate, attributeName))//替换最后修改日期 - { - if (contextInfo.ContentInfo != null) - { - parsedContent = DateUtils.Format(contextInfo.ContentInfo.LastEditDate, string.Empty); - } - else - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, contextInfo.ChannelId); - //parsedContent = DateUtils.Format(DataProvider.ContentDao.GetLastEditDate(tableName, contextInfo.ContentId), string.Empty); - parsedContent = DateUtils.Format(Cache.Content.GetLastEditDate(tableName, contextInfo.ContentId), string.Empty); - } - } - else if (StringUtils.EqualsIgnoreCase(Content, attributeName))//内容正文 - { - if (contextInfo.ContentInfo != null) - { - parsedContent = contextInfo.ContentInfo.GetString(BackgroundContentAttribute.Content); - } - else - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId)); - //parsedContent = DataProvider.ContentDao.GetValue(tableName, contextInfo.ContentId, BackgroundContentAttribute.Content); - parsedContent = Cache.Content.GetValue(tableName, contextInfo.ContentId, BackgroundContentAttribute.Content); - } - parsedContent = ContentUtility.TextEditorContentDecode(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); - } - else if (StringUtils.EqualsIgnoreCase(Group, attributeName))//内容组别 - { - if (contextInfo.ContentInfo != null) - { - parsedContent = contextInfo.ContentInfo.GroupNameCollection; - } - else - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId)); - //parsedContent = DataProvider.ContentDao.GetValue(tableName, contextInfo.ContentId, ContentAttribute.ContentGroupNameCollection); - parsedContent = Cache.Content.GetValue(tableName, contextInfo.ContentId, ContentAttribute.GroupNameCollection); - } - } - else if (StringUtils.EqualsIgnoreCase(Tags, attributeName))//标签 - { - if (contextInfo.ContentInfo != null) - { - parsedContent = contextInfo.ContentInfo.Tags; - } - else - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId)); - //parsedContent = DataProvider.ContentDao.GetValue(tableName, contextInfo.ContentId, ContentAttribute.Tags); - parsedContent = Cache.Content.GetValue(tableName, contextInfo.ContentId, ContentAttribute.Tags); - } - } - else if (StringUtils.EqualsIgnoreCase(AddUserName, attributeName)) - { - string addUserName; - if (contextInfo.ContentInfo != null) - { - addUserName = contextInfo.ContentInfo.AddUserName; - } - else - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId)); - //addUserName = DataProvider.ContentDao.GetValue(tableName, contextInfo.ContentId, ContentAttribute.AddUserName); - addUserName = Cache.Content.GetValue(tableName, contextInfo.ContentId, ContentAttribute.AddUserName); - } - if (!string.IsNullOrEmpty(addUserName)) - { - //var displayName = DataProvider.AdministratorDao.GetDisplayName(addUserName); - var displayName = Administrator.GetDisplayName(addUserName); - parsedContent = string.IsNullOrEmpty(displayName) ? addUserName : displayName; - } - } - else if (StringUtils.StartsWithIgnoreCase(attributeName, StlParserUtility.ItemIndex) && contextInfo.ItemContainer?.ContentItem != null) - { - parsedContent = StlParserUtility.ParseItemIndex(contextInfo.ItemContainer.ContentItem.ItemIndex, attributeName, contextInfo).ToString(); - } - else - { - int contentChannelId; - if (contextInfo.ContentInfo != null) - { - contentChannelId = contextInfo.ContentInfo.ChannelId; - if (contextInfo.ContentInfo.ContainsKey(attributeName)) - { - parsedContent = contextInfo.ContentInfo.GetString(attributeName); - } - } - else - { - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, contextInfo.ChannelId); - //contentChannelId = DataProvider.ContentDao.GetChannelId(tableName, contextInfo.ContentId); - contentChannelId = Cache.Content.GetChannelId(tableName, contextInfo.ContentId); - tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, ChannelManager.GetChannelInfo(pageInfo.SiteId, contentChannelId)); - //parsedContent = DataProvider.ContentDao.GetValue(tableName, contextInfo.ContentId, attributeName); - parsedContent = Cache.Content.GetValue(tableName, contextInfo.ContentId, attributeName); - } - - if (!string.IsNullOrEmpty(parsedContent)) - { - var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(pageInfo.SiteId, contentChannelId); - var styleInfo = TableStyleManager.GetTableStyleInfo(pageInfo.SiteInfo.TableName, attributeName, relatedIdentities); - - //styleInfo.IsVisible = false 表示此字段不需要显示 styleInfo.TableStyleId = 0 不能排除,因为有可能是直接辅助表字段没有添加显示样式 - parsedContent = InputParserUtility.GetContentByTableStyle(parsedContent, ",", pageInfo.SiteInfo, styleInfo, string.Empty, null, string.Empty, true); - } - - } - } - catch - { - // ignored - } - } - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlEntity/StlNavigationEntities.cs b/SiteServer.CMS/StlParser/StlEntity/StlNavigationEntities.cs deleted file mode 100644 index e4a9ef68a..000000000 --- a/SiteServer.CMS/StlParser/StlEntity/StlNavigationEntities.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System.Collections.Generic; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlEntity -{ - [StlClass(Usage = "导航实体", Description = "通过 {navigation.} 实体在模板中显示导航链接")] - public class StlNavigationEntities - { - private StlNavigationEntities() - { - } - - public const string EntityName = "navigation"; - - public static string PreviousChannel = "PreviousChannel"; - public static string NextChannel = "NextChannel"; - public static string PreviousContent = "PreviousContent"; - public static string NextContent = "NextContent"; - - public static SortedList AttributeList => new SortedList - { - {PreviousChannel, "上一栏目链接"}, - {NextChannel, "下一栏目链接"}, - {PreviousContent, "上一内容链接"}, - {NextContent, "下一内容链接"} - }; - - internal static string Parse(string stlEntity, PageInfo pageInfo, ContextInfo contextInfo) - { - var parsedContent = string.Empty; - try - { - var entityName = StlParserUtility.GetNameFromEntity(stlEntity); - var attributeName = entityName.Substring(12, entityName.Length - 13); - - var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); - - if (StringUtils.EqualsIgnoreCase(PreviousChannel, attributeName) || StringUtils.EqualsIgnoreCase(NextChannel, attributeName)) - { - var taxis = nodeInfo.Taxis; - var isNextChannel = !StringUtils.EqualsIgnoreCase(attributeName, PreviousChannel); - //var siblingChannelId = DataProvider.ChannelDao.GetIdByParentIdAndTaxis(nodeInfo.ParentId, taxis, isNextChannel); - var siblingChannelId = Node.GetIdByParentIdAndTaxis(nodeInfo.ParentId, taxis, isNextChannel); - if (siblingChannelId != 0) - { - var siblingNodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, siblingChannelId); - parsedContent = PageUtility.GetChannelUrl(pageInfo.SiteInfo, siblingNodeInfo, pageInfo.IsLocal); - } - } - else if (StringUtils.EqualsIgnoreCase(PreviousContent, attributeName) || StringUtils.EqualsIgnoreCase(NextContent, attributeName)) - { - if (contextInfo.ContentId != 0) - { - var taxis = contextInfo.ContentInfo.Taxis; - var isNextContent = !StringUtils.EqualsIgnoreCase(attributeName, PreviousContent); - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, contextInfo.ChannelId); - //var siblingContentId = DataProvider.ContentDao.GetContentId(tableName, contextInfo.ChannelId, taxis, isNextContent); - var siblingContentId = Content.GetContentId(tableName, contextInfo.ChannelId, taxis, isNextContent); - if (siblingContentId != 0) - { - //var contentInfo = DataProvider.ContentDao.GetContentInfo(tableStyle, tableName, siblingContentId); - var contentInfo = Content.GetContentInfo(tableName, siblingContentId); - parsedContent = PageUtility.GetContentUrl(pageInfo.SiteInfo, contentInfo, pageInfo.IsLocal); - } - } - } - } - catch - { - // ignored - } - - if (string.IsNullOrEmpty(parsedContent)) - { - parsedContent = PageUtils.UnclickedUrl; - } - - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlEntity/StlStlEntities.cs b/SiteServer.CMS/StlParser/StlEntity/StlStlEntities.cs deleted file mode 100644 index 72294b84c..000000000 --- a/SiteServer.CMS/StlParser/StlEntity/StlStlEntities.cs +++ /dev/null @@ -1,161 +0,0 @@ -using System.Collections.Generic; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Plugin; - -namespace SiteServer.CMS.StlParser.StlEntity -{ - [StlClass(Usage = "通用实体", Description = "通过 {stl.} 实体在模板中显示对应数据")] - public class StlStlEntities - { - private StlStlEntities() - { - } - - public const string EntityName = "stl"; - - public static string PoweredBy = "PoweredBy"; - public static string SiteName = "SiteName"; - public static string SiteId = "SiteId"; - public static string SiteDir = "SiteDir"; - public static string SiteUrl = "SiteUrl"; - public static string RootUrl = "RootUrl"; - public static string ApiUrl = "ApiUrl"; - public static string CurrentUrl = "CurrentUrl"; - public static string ChannelUrl = "ChannelUrl"; - - public static SortedList AttributeList => new SortedList - { - {PoweredBy, "PoweredBy 链接"}, - {SiteName, "站点名称"}, - {SiteId, "站点ID"}, - {SiteDir, "站点文件夹"}, - {SiteUrl, "站点根目录地址"}, - {RootUrl, "系统根目录地址"}, - {ApiUrl, "Api地址"}, - {CurrentUrl, "当前页地址"}, - {ChannelUrl, "栏目页地址"} - }; - - internal static string Parse(string stlEntity, PageInfo pageInfo, ContextInfo contextInfo) - { - var parsedContent = string.Empty; - try - { - var entityName = StlParserUtility.GetNameFromEntity(stlEntity); - var attributeName = entityName.Substring(5, entityName.Length - 6); - - if (StringUtils.EqualsIgnoreCase(PoweredBy, attributeName))//支持信息 - { - parsedContent = @"Powered by SiteServer CMS"; - } - else if (StringUtils.EqualsIgnoreCase(RootUrl, attributeName))//系统根目录地址 - { - parsedContent = PageUtils.ParseConfigRootUrl("~"); - if (!string.IsNullOrEmpty(parsedContent)) - { - parsedContent = parsedContent.TrimEnd('/'); - } - } - else if (StringUtils.EqualsIgnoreCase(ApiUrl, attributeName))//API地址 - { - parsedContent = pageInfo.ApiUrl.TrimEnd('/'); - } - else if (StringUtils.EqualsIgnoreCase(SiteId, attributeName))//ID - { - parsedContent = pageInfo.SiteId.ToString(); - } - else if (StringUtils.EqualsIgnoreCase(SiteName, attributeName))//名称 - { - parsedContent = pageInfo.SiteInfo.SiteName; - } - else if (StringUtils.EqualsIgnoreCase(SiteUrl, attributeName))//域名地址 - { - parsedContent = PageUtility.GetSiteUrl(pageInfo.SiteInfo, pageInfo.IsLocal).TrimEnd('/'); - } - else if (StringUtils.EqualsIgnoreCase(SiteDir, attributeName))//文件夹 - { - parsedContent = pageInfo.SiteInfo.SiteDir; - } - else if (StringUtils.EqualsIgnoreCase(CurrentUrl, attributeName))//当前页地址 - { - parsedContent = StlParserUtility.GetStlCurrentUrl(pageInfo.SiteInfo, contextInfo.ChannelId, contextInfo.ContentId, contextInfo.ContentInfo, pageInfo.TemplateInfo.TemplateType, pageInfo.TemplateInfo.Id, pageInfo.IsLocal); - } - else if (StringUtils.EqualsIgnoreCase(ChannelUrl, attributeName))//栏目页地址 - { - parsedContent = PageUtility.GetChannelUrl(pageInfo.SiteInfo, ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId), pageInfo.IsLocal); - } - //else if (StringUtils.EqualsIgnoreCase(HomeUrl, attributeName))//用户中心地址 - //{ - // parsedContent = pageInfo.HomeUrl.TrimEnd('/'); - //} - //else if (StringUtils.EqualsIgnoreCase(attributeName, LoginUrl)) - //{ - // var returnUrl = StlUtility.GetStlCurrentUrl(pageInfo.SiteInfo, contextInfo.ChannelId, contextInfo.ContentId, contextInfo.ContentInfo, pageInfo.TemplateInfo.TemplateType, pageInfo.TemplateInfo.TemplateId); - // parsedContent = HomeUtils.GetLoginUrl(pageInfo.HomeUrl, returnUrl); - //} - //else if (StringUtils.EqualsIgnoreCase(attributeName, LogoutUrl)) - //{ - // var returnUrl = StlUtility.GetStlCurrentUrl(pageInfo.SiteInfo, contextInfo.ChannelId, contextInfo.ContentId, contextInfo.ContentInfo, pageInfo.TemplateInfo.TemplateType, pageInfo.TemplateInfo.TemplateId); - // parsedContent = HomeUtils.GetLogoutUrl(pageInfo.HomeUrl, returnUrl); - //} - //else if (StringUtils.EqualsIgnoreCase(attributeName, RegisterUrl)) - //{ - // var returnUrl = StlUtility.GetStlCurrentUrl(pageInfo.SiteInfo, contextInfo.ChannelId, contextInfo.ContentId, contextInfo.ContentInfo, pageInfo.TemplateInfo.TemplateType, pageInfo.TemplateInfo.TemplateId); - // parsedContent = HomeUtils.GetRegisterUrl(pageInfo.HomeUrl, returnUrl); - //} - else if (StringUtils.StartsWithIgnoreCase(attributeName, "TableFor"))// - { - if (StringUtils.EqualsIgnoreCase(attributeName, "TableForContent")) - { - parsedContent = pageInfo.SiteInfo.TableName; - } - } - else if (StringUtils.StartsWithIgnoreCase(attributeName, "Site"))// - { - parsedContent = pageInfo.SiteInfo.Additional.GetString(attributeName.Substring(4)); - } - else if (pageInfo.Parameters != null && pageInfo.Parameters.ContainsKey(attributeName)) - { - pageInfo.Parameters.TryGetValue(attributeName, out parsedContent); - } - else - { - if (pageInfo.SiteInfo.Additional.ContainsKey(attributeName)) - { - parsedContent = pageInfo.SiteInfo.Additional.GetString(attributeName); - - if (!string.IsNullOrEmpty(parsedContent)) - { - var styleInfo = TableStyleManager.GetTableStyleInfo(DataProvider.SiteDao.TableName, attributeName, RelatedIdentities.GetRelatedIdentities(pageInfo.SiteId, pageInfo.SiteId)); - - // 如果 styleInfo.TableStyleId <= 0,表示此字段已经被删除了,不需要再显示值了 ekun008 - if (styleInfo.Id > 0) - { - parsedContent = InputTypeUtils.EqualsAny(styleInfo.InputType, InputType.Image, - InputType.File) - ? PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, - pageInfo.IsLocal) - : InputParserUtility.GetContentByTableStyle(parsedContent, string.Empty, - pageInfo.SiteInfo, styleInfo, string.Empty, null, string.Empty, - true); - } - else - { // 如果字段已经被删除或不再显示了,则此字段的值为空。有时虚拟字段值不会清空 - parsedContent = string.Empty; - } - } - } - } - } - catch - { - // ignored - } - - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/StlEntity/StlUserEntities.cs b/SiteServer.CMS/StlParser/StlEntity/StlUserEntities.cs deleted file mode 100644 index 2ea140394..000000000 --- a/SiteServer.CMS/StlParser/StlEntity/StlUserEntities.cs +++ /dev/null @@ -1,180 +0,0 @@ -using System.Collections.Generic; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.Utility; - -namespace SiteServer.CMS.StlParser.StlEntity -{ - [StlClass(Usage = "用户实体", Description = "通过 {user.} 实体在模板中显示用户值")] - public class StlUserEntities - { - private StlUserEntities() - { - } - - public const string EntityName = "user"; - - public static string Id = "Id"; - public static string UserName = "UserName"; - public static string CreateDate = "CreateDate"; - public static string LastActivityDate = "LastActivityDate"; - public static string CountOfLogin = "CountOfLogin"; - public static string CountOfWriting = "CountOfWriting"; - public static string DisplayName = "DisplayName"; - public static string Email = "Email"; - public static string Mobile = "Mobile"; - public static string AvatarUrl = "AvatarUrl"; - public static string Organization = "Organization"; - public static string Department = "Department"; - public static string Position = "Position"; - public static string Gender = "Gender"; - public static string Birthday = "Birthday"; - public static string Education = "Education"; - public static string Graduation = "Graduation"; - public static string Address = "Address"; - public static string WeiXin = "WeiXin"; - public static string Qq = "Qq"; - public static string WeiBo = "WeiBo"; - public static string Interests = "Interests"; - public static string Signature = "Signature"; - - public static SortedList AttributeList => new SortedList - { - {Id, "用户ID"}, - {UserName, "用户名"}, - {CreateDate, "注册日期"}, - {LastActivityDate, "最后活动日期"}, - {CountOfLogin, "登录次数"}, - {CountOfWriting, "投稿次数"}, - {DisplayName, "姓名"}, - {Email, "邮箱"}, - {Mobile, "手机"}, - {AvatarUrl, "头像地址"}, - {Organization, "单位"}, - {Department, "部门"}, - {Position, "职位"}, - {Gender, "性别"}, - {Birthday, "出生日期"}, - {Education, "教育程度"}, - {Graduation, "毕业院校"}, - {Address, "通讯地址"}, - {WeiXin, "微信"}, - {Qq, "QQ"}, - {WeiBo, "微博"}, - {Interests, "兴趣爱好"}, - {Signature, "签名"} - }; - - internal static string Parse(string stlEntity, PageInfo pageInfo) - { - var parsedContent = string.Empty; - if (pageInfo?.UserInfo == null) return string.Empty; - - try - { - var entityName = StlParserUtility.GetNameFromEntity(stlEntity); - var attributeName = entityName.Substring(6, entityName.Length - 7); - - if (StringUtils.EqualsIgnoreCase(Id, attributeName)) - { - parsedContent = pageInfo.UserInfo.Id.ToString(); - } - else if (StringUtils.EqualsIgnoreCase(UserName, attributeName)) - { - parsedContent = pageInfo.UserInfo.UserName; - } - else if (StringUtils.EqualsIgnoreCase(CreateDate, attributeName)) - { - parsedContent = DateUtils.Format(pageInfo.UserInfo.CreateDate, string.Empty); - } - else if (StringUtils.EqualsIgnoreCase(LastActivityDate, attributeName)) - { - parsedContent = DateUtils.Format(pageInfo.UserInfo.LastActivityDate, string.Empty); - } - else if (StringUtils.EqualsIgnoreCase(CountOfLogin, attributeName)) - { - parsedContent = pageInfo.UserInfo.CountOfLogin.ToString(); - } - else if (StringUtils.EqualsIgnoreCase(CountOfWriting, attributeName)) - { - parsedContent = pageInfo.UserInfo.CountOfWriting.ToString(); - } - else if (StringUtils.EqualsIgnoreCase(DisplayName, attributeName)) - { - parsedContent = pageInfo.UserInfo.DisplayName; - } - else if (StringUtils.EqualsIgnoreCase(Email, attributeName)) - { - parsedContent = pageInfo.UserInfo.Email; - } - else if (StringUtils.EqualsIgnoreCase(Mobile, attributeName)) - { - parsedContent = pageInfo.UserInfo.Mobile; - } - else if (StringUtils.EqualsIgnoreCase(AvatarUrl, attributeName)) - { - parsedContent = PageUtility.GetUserAvatarUrl(pageInfo.ApiUrl, pageInfo.UserInfo); - } - else if (StringUtils.EqualsIgnoreCase(Organization, attributeName)) - { - parsedContent = pageInfo.UserInfo.Organization; - } - else if (StringUtils.EqualsIgnoreCase(Department, attributeName)) - { - parsedContent = pageInfo.UserInfo.Department; - } - else if (StringUtils.EqualsIgnoreCase(Position, attributeName)) - { - parsedContent = pageInfo.UserInfo.Position; - } - else if (StringUtils.EqualsIgnoreCase(Gender, attributeName)) - { - parsedContent = pageInfo.UserInfo.Gender; - } - else if (StringUtils.EqualsIgnoreCase(Birthday, attributeName)) - { - parsedContent = pageInfo.UserInfo.Birthday; - } - else if (StringUtils.EqualsIgnoreCase(Education, attributeName)) - { - parsedContent = pageInfo.UserInfo.Education; - } - else if (StringUtils.EqualsIgnoreCase(Graduation, attributeName)) - { - parsedContent = pageInfo.UserInfo.Graduation; - } - else if (StringUtils.EqualsIgnoreCase(Address, attributeName)) - { - parsedContent = pageInfo.UserInfo.Address; - } - else if (StringUtils.EqualsIgnoreCase(WeiXin, attributeName)) - { - parsedContent = pageInfo.UserInfo.WeiXin; - } - else if (StringUtils.EqualsIgnoreCase(Qq, attributeName)) - { - parsedContent = pageInfo.UserInfo.Qq; - } - else if (StringUtils.EqualsIgnoreCase(WeiBo, attributeName)) - { - parsedContent = pageInfo.UserInfo.WeiBo; - } - else if (StringUtils.EqualsIgnoreCase(Interests, attributeName)) - { - parsedContent = pageInfo.UserInfo.Interests; - } - else if (StringUtils.EqualsIgnoreCase(Signature, attributeName)) - { - parsedContent = pageInfo.UserInfo.Signature; - } - } - catch - { - // ignored - } - - return parsedContent; - } - } -} diff --git a/SiteServer.CMS/StlParser/Utility/StlDataUtility.cs b/SiteServer.CMS/StlParser/Utility/StlDataUtility.cs deleted file mode 100644 index 85e140567..000000000 --- a/SiteServer.CMS/StlParser/Utility/StlDataUtility.cs +++ /dev/null @@ -1,472 +0,0 @@ -using System.Collections.Generic; -using System.Data; -using System.Xml; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.StlElement; -using SiteServer.CMS.Plugin; -using SiteServer.CMS.StlParser.Cache; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.CMS.StlParser.Utility -{ - public class StlDataUtility - { - public static int GetChannelIdByChannelIdOrChannelIndexOrChannelName(int siteId, int channelId, string channelIndex, string channelName) - { - var retval = channelId; - - if (!string.IsNullOrEmpty(channelIndex)) - { - var theChannelId = Node.GetIdByIndexName(siteId, channelIndex); - if (theChannelId != 0) - { - retval = theChannelId; - } - } - if (!string.IsNullOrEmpty(channelName)) - { - var theChannelId = Node.GetIdByParentIdAndChannelName(siteId, retval, channelName, true); - if (theChannelId == 0) - { - theChannelId = Node.GetIdByParentIdAndChannelName(siteId, siteId, channelName, true); - } - if (theChannelId != 0) - { - retval = theChannelId; - } - } - - return retval; - } - - public static int GetChannelIdByLevel(int siteId, int channelId, int upLevel, int topLevel) - { - var theChannelId = channelId; - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - if (nodeInfo != null) - { - if (topLevel >= 0) - { - if (topLevel > 0) - { - if (topLevel < nodeInfo.ParentsCount) - { - var parentIdStrList = TranslateUtils.StringCollectionToStringList(nodeInfo.ParentsPath); - if (parentIdStrList[topLevel] != null) - { - var parentIdStr = parentIdStrList[topLevel]; - theChannelId = int.Parse(parentIdStr); - } - } - } - else - { - theChannelId = siteId; - } - } - else if (upLevel > 0) - { - if (upLevel < nodeInfo.ParentsCount) - { - var parentIdStrList = TranslateUtils.StringCollectionToStringList(nodeInfo.ParentsPath); - if (parentIdStrList[upLevel] != null) - { - var parentIdStr = parentIdStrList[nodeInfo.ParentsCount - upLevel]; - theChannelId = int.Parse(parentIdStr); - } - } - else - { - theChannelId = siteId; - } - } - } - return theChannelId; - } - - public static List GetChannelIdList(int siteId, int channelId, string orderByString, EScopeType scopeType, string groupChannel, string groupChannelNot, bool isImageExists, bool isImage, int totalNum, string where) - { - var whereString = Node.GetWhereString(siteId, groupChannel, groupChannelNot, isImageExists, isImage, where); - var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var channelIdList = ChannelManager.GetChannelIdList(channelInfo, scopeType, groupChannel, groupChannelNot, string.Empty); - return Node.GetIdListByTotalNum(channelIdList, totalNum, orderByString, whereString); - } - - //public static int GetChannelIdByChannelIDOrChannelIndexOrChannelName(int siteID, int channelID, string channelIndex, string channelName) - //{ - // int retval = channelID; - // if (!string.IsNullOrEmpty(channelIndex)) - // { - // int theChannelId = DataProvider.NodeDAO.GetChannelIdByNodeIndexName(siteID, channelIndex); - // if (theChannelId != 0) - // { - // retval = theChannelId; - // } - // } - // if (!string.IsNullOrEmpty(channelName)) - // { - // int theChannelId = DataProvider.NodeDAO.GetChannelIdByParentIDAndNodeName(retval, channelName, true); - // if (theChannelId == 0) - // { - // theChannelId = DataProvider.NodeDAO.GetChannelIdByParentIDAndNodeName(siteID, channelName, true); - // } - // if (theChannelId != 0) - // { - // retval = theChannelId; - // } - // } - // return retval; - //} - - public static ETaxisType GetETaxisTypeByOrder(string order, bool isChannel, ETaxisType defaultType) - { - var taxisType = defaultType; - if (!string.IsNullOrEmpty(order)) - { - if (isChannel) - { - if (order.ToLower().Equals(StlParserUtility.OrderDefault.ToLower())) - { - taxisType = ETaxisType.OrderByTaxis; - } - else if (order.ToLower().Equals(StlParserUtility.OrderBack.ToLower())) - { - taxisType = ETaxisType.OrderByTaxisDesc; - } - else if (order.ToLower().Equals(StlParserUtility.OrderAddDate.ToLower())) - { - taxisType = ETaxisType.OrderByAddDate; - } - else if (order.ToLower().Equals(StlParserUtility.OrderAddDateBack.ToLower())) - { - taxisType = ETaxisType.OrderByAddDateDesc; - } - else if (order.ToLower().Equals(StlParserUtility.OrderHits.ToLower())) - { - taxisType = ETaxisType.OrderByHits; - } - } - else - { - if (order.ToLower().Equals(StlParserUtility.OrderDefault.ToLower())) - { - taxisType = ETaxisType.OrderByTaxisDesc; - } - else if (order.ToLower().Equals(StlParserUtility.OrderBack.ToLower())) - { - taxisType = ETaxisType.OrderByTaxis; - } - else if (order.ToLower().Equals(StlParserUtility.OrderAddDate.ToLower())) - { - taxisType = ETaxisType.OrderByAddDate; - } - else if (order.ToLower().Equals(StlParserUtility.OrderAddDateBack.ToLower())) - { - taxisType = ETaxisType.OrderByAddDateDesc; - } - else if (order.ToLower().Equals(StlParserUtility.OrderLastEditDate.ToLower())) - { - taxisType = ETaxisType.OrderByLastEditDate; - } - else if (order.ToLower().Equals(StlParserUtility.OrderAddDateBack.ToLower())) - { - taxisType = ETaxisType.OrderByLastEditDateDesc; - } - else if (order.ToLower().Equals(StlParserUtility.OrderHits.ToLower())) - { - taxisType = ETaxisType.OrderByHits; - } - else if (order.ToLower().Equals(StlParserUtility.OrderHitsByDay.ToLower())) - { - taxisType = ETaxisType.OrderByHitsByDay; - } - else if (order.ToLower().Equals(StlParserUtility.OrderHitsByWeek.ToLower())) - { - taxisType = ETaxisType.OrderByHitsByWeek; - } - else if (order.ToLower().Equals(StlParserUtility.OrderHitsByMonth.ToLower())) - { - taxisType = ETaxisType.OrderByHitsByMonth; - } - } - } - return taxisType; - } - - public static string GetChannelOrderByString(int siteId, string orderValue, ETaxisType defaultType) - { - var taxisType = defaultType; - var orderByString = string.Empty; - if (!string.IsNullOrEmpty(orderValue)) - { - if (orderValue.ToLower().Equals(StlParserUtility.OrderDefault.ToLower())) - { - taxisType = ETaxisType.OrderByTaxis; - } - else if (orderValue.ToLower().Equals(StlParserUtility.OrderBack.ToLower())) - { - taxisType = ETaxisType.OrderByTaxisDesc; - } - else if (orderValue.ToLower().Equals(StlParserUtility.OrderAddDate.ToLower())) - { - taxisType = ETaxisType.OrderByAddDateDesc; - } - else if (orderValue.ToLower().Equals(StlParserUtility.OrderAddDateBack.ToLower())) - { - taxisType = ETaxisType.OrderByAddDate; - } - else if (orderValue.ToLower().Equals(StlParserUtility.OrderHits.ToLower())) - { - taxisType = ETaxisType.OrderByHits; - } - else if (orderValue.ToLower().Equals(StlParserUtility.OrderRandom.ToLower())) - { - taxisType = ETaxisType.OrderByRandom; - } - else - { - orderByString = orderValue; - } - } - - return ETaxisTypeUtils.GetChannelOrderByString(taxisType, orderByString, null); - } - - public static string GetContentOrderByString(int siteId, string orderValue, ETaxisType defaultType) - { - var taxisType = defaultType; - var orderByString = string.Empty; - if (!string.IsNullOrEmpty(orderValue)) - { - if (orderValue.ToLower().Equals(StlParserUtility.OrderDefault.ToLower())) - { - taxisType = ETaxisType.OrderByTaxisDesc; - } - else if (orderValue.ToLower().Equals(StlParserUtility.OrderBack.ToLower())) - { - taxisType = ETaxisType.OrderByTaxis; - } - else if (orderValue.ToLower().Equals(StlParserUtility.OrderAddDate.ToLower())) - { - taxisType = ETaxisType.OrderByAddDateDesc; - } - else if (orderValue.ToLower().Equals(StlParserUtility.OrderAddDateBack.ToLower())) - { - taxisType = ETaxisType.OrderByAddDate; - } - else if (orderValue.ToLower().Equals(StlParserUtility.OrderLastEditDate.ToLower())) - { - taxisType = ETaxisType.OrderByLastEditDateDesc; - } - else if (orderValue.ToLower().Equals(StlParserUtility.OrderLastEditDateBack.ToLower())) - { - taxisType = ETaxisType.OrderByLastEditDate; - } - else if (orderValue.ToLower().Equals(StlParserUtility.OrderHits.ToLower())) - { - taxisType = ETaxisType.OrderByHits; - } - else if (orderValue.ToLower().Equals(StlParserUtility.OrderHitsByDay.ToLower())) - { - taxisType = ETaxisType.OrderByHitsByDay; - } - else if (orderValue.ToLower().Equals(StlParserUtility.OrderHitsByWeek.ToLower())) - { - taxisType = ETaxisType.OrderByHitsByWeek; - } - else if (orderValue.ToLower().Equals(StlParserUtility.OrderHitsByMonth.ToLower())) - { - taxisType = ETaxisType.OrderByHitsByMonth; - } - else if (orderValue.ToLower().Equals(StlParserUtility.OrderRandom.ToLower())) - { - taxisType = ETaxisType.OrderByRandom; - } - else - { - orderByString = orderValue; - } - } - - return ETaxisTypeUtils.GetContentOrderByString(taxisType, orderByString); - } - - public static string GetStlPageContentsSqlString(SiteInfo siteInfo, int channelId, string groupContent, string groupContentNot, string tags, bool isImageExists, bool isImage, bool isVideoExists, bool isVideo, bool isFileExists, bool isFile, bool isNoDup, int startNum, int totalNum, string orderByString, bool isTopExists, bool isTop, bool isRecommendExists, bool isRecommend, bool isHotExists, bool isHot, bool isColorExists, bool isColor, string where, EScopeType scopeType, string groupChannel, string groupChannelNot) - { - if (!ChannelManager.IsExists(siteInfo.Id, channelId)) return string.Empty; - - var nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - - - - var sqlWhereString = ChannelManager.IsContentModelPlugin(siteInfo, nodeInfo) - ? Content.GetStlWhereString(siteInfo.Id, groupContent, groupContentNot, - tags, isTopExists, isTop, where) - : Content.GetStlWhereString(siteInfo.Id, tableName, groupContent, - groupContentNot, tags, isImageExists, isImage, isVideoExists, isVideo, isFileExists, isFile, - isTopExists, isTop, isRecommendExists, isRecommend, isHotExists, isHot, isColorExists, isColor, - where, siteInfo.Additional.IsCreateSearchDuplicate); - - return Content.GetStlSqlStringChecked(tableName, siteInfo.Id, channelId, startNum, totalNum, orderByString, sqlWhereString, scopeType, groupChannel, groupChannelNot, isNoDup); - } - - public static string GetPageContentsSqlStringBySearch(string tableName, string groupContent, string groupContentNot, string tags, bool isImageExists, bool isImage, bool isVideoExists, bool isVideo, bool isFileExists, bool isFile, bool isNoDup, int startNum, int totalNum, string orderByString, bool isTopExists, bool isTop, bool isRecommendExists, bool isRecommend, bool isHotExists, bool isHot, bool isColorExists, bool isColor, string where, EScopeType scopeType, string groupChannel, string groupChannelNot) - { - var sqlWhereString = Content.GetStlWhereStringBySearch(tableName, groupContent, groupContentNot, tags, isImageExists, isImage, isVideoExists, isVideo, isFileExists, isFile, isTopExists, isTop, isRecommendExists, isRecommend, isHotExists, isHot, isColorExists, isColor, where); - var sqlString = Content.GetStlSqlStringCheckedBySearch(tableName, startNum, totalNum, orderByString, sqlWhereString, isNoDup); - - return sqlString; - } - - public static DataSet GetContentsDataSource(SiteInfo siteInfo, int channelId, int contentId, string groupContent, string groupContentNot, string tags, bool isImageExists, bool isImage, bool isVideoExists, bool isVideo, bool isFileExists, bool isFile, bool isNoDup, bool isRelatedContents, int startNum, int totalNum, string orderByString, bool isTopExists, bool isTop, bool isRecommendExists, bool isRecommend, bool isHotExists, bool isHot, bool isColorExists, bool isColor, string where, EScopeType scopeType, string groupChannel, string groupChannelNot, LowerNameValueCollection others) - { - if (!ChannelManager.IsExists(siteInfo.Id, channelId)) return null; - - var nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - - if (isRelatedContents && contentId > 0) - { - var isTags = false; - var tagCollection = Content.GetValue(tableName, contentId, ContentAttribute.Tags); - if (!string.IsNullOrEmpty(tagCollection)) - { - var contentIdList = Tag.GetContentIdListByTagCollection(TranslateUtils.StringCollectionToStringCollection(tagCollection), siteInfo.Id); - if (contentIdList.Count > 0) - { - contentIdList.Remove(contentId); - isTags = true; - if (string.IsNullOrEmpty(where)) - { - where = - $"ID IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; - } - else - { - where += - $" AND (ID IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)}))"; - } - } - } - - if (!isTags) - { - if (string.IsNullOrEmpty(where)) - { - where = $"ID <> {contentId}"; - } - else - { - where += $" AND (ID <> {contentId})"; - } - } - } - - var sqlWhereString = PluginManager.IsExists(nodeInfo.ContentModelPluginId) - ? Content.GetStlWhereString(siteInfo.Id, groupContent, groupContentNot, - tags, isTopExists, isTop, where) - : Content.GetStlWhereString(siteInfo.Id, tableName, groupContent, - groupContentNot, tags, isImageExists, isImage, isVideoExists, isVideo, isFileExists, isFile, - isTopExists, isTop, isRecommendExists, isRecommend, isHotExists, isHot, isColorExists, isColor, - where, siteInfo.Additional.IsCreateSearchDuplicate); - - var channelIdList = ChannelManager.GetChannelIdList(nodeInfo, scopeType, groupChannel, groupChannelNot, string.Empty); - return Content.GetStlDataSourceChecked(channelIdList, tableName, startNum, totalNum, orderByString, sqlWhereString, isNoDup, others); - } - - public static DataSet GetChannelsDataSource(int siteId, int channelId, string group, string groupNot, bool isImageExists, bool isImage, int startNum, int totalNum, string orderByString, EScopeType scopeType, bool isTotal, string where) - { - DataSet ie; - - if (isTotal)//从所有栏目中选择 - { - var sqlWhereString = Node.GetWhereString(siteId, group, groupNot, isImageExists, isImage, where); - ie = Node.GetStlDataSourceBySiteId(siteId, startNum, totalNum, sqlWhereString, orderByString); - } - else - { - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - if (nodeInfo == null) return null; - - var sqlWhereString = Node.GetWhereString(siteId, group, groupNot, isImageExists, isImage, where); - var channelIdList = ChannelManager.GetChannelIdList(nodeInfo, scopeType, string.Empty, string.Empty, string.Empty); - //ie = DataProvider.ChannelDao.GetStlDataSource(channelIdList, startNum, totalNum, sqlWhereString, orderByString); - ie = Node.GetStlDataSet(channelIdList, startNum, totalNum, sqlWhereString, orderByString); - } - - return ie; - } - - public static DataSet GetPageChannelsDataSet(int siteId, int channelId, string group, string groupNot, bool isImageExists, bool isImage, int startNum, int totalNum, string orderByString, EScopeType scopeType, bool isTotal, string where) - { - DataSet dataSet; - - if (isTotal)//从所有栏目中选择 - { - var sqlWhereString = Node.GetWhereString(siteId, group, groupNot, isImageExists, isImage, where); - dataSet = DataProvider.ChannelDao.GetStlDataSetBySiteId(siteId, startNum, totalNum, sqlWhereString, orderByString); - } - else - { - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - if (nodeInfo == null) return null; - - var sqlWhereString = Node.GetWhereString(siteId, group, groupNot, isImageExists, isImage, where); - var channelIdList = ChannelManager.GetChannelIdList(nodeInfo, scopeType, string.Empty, string.Empty, string.Empty); - dataSet = DataProvider.ChannelDao.GetStlDataSet(channelIdList, startNum, totalNum, sqlWhereString, orderByString); - } - return dataSet; - } - - public static IDataReader GetSqlContentsDataSource(string connectionString, string queryString, int startNum, int totalNum, string orderByString) - { - var sqlString = TableStructure.GetSelectSqlStringByQueryString(connectionString, queryString, startNum, totalNum, orderByString); - return DataProvider.DatabaseDao.GetDataSource(connectionString, sqlString); - } - - public static DataSet GetPageSqlContentsDataSet(string connectionString, string queryString, int startNum, int totalNum, string orderByString) - { - var sqlString = TableStructure.GetSelectSqlStringByQueryString(connectionString, queryString, startNum, totalNum, orderByString); - return DataProvider.DatabaseDao.GetDataSet(connectionString, sqlString); - } - - public static IDataReader GetSitesDataSource(string siteName, string siteDir, int startNum, int totalNum, string whereString, EScopeType scopeType, string orderByString, string since) - { - return DataProvider.SiteDao.GetStlDataSource(siteName, siteDir, startNum, totalNum, whereString, scopeType, orderByString, since); - } - - public static DataSet GetDataSourceByStlElement(SiteInfo siteInfo, int templateId, string elementName, string stlElement) - { - var xmlDocument = StlParserUtility.GetXmlDocument(stlElement, false); - XmlNode node = xmlDocument.DocumentElement; - if (node == null) return null; - - node = node.FirstChild; - - var templateInfo = TemplateManager.GetTemplateInfo(siteInfo.Id, templateId); - var pageInfo = new PageInfo(siteInfo.Id, 0, siteInfo, templateInfo, new Dictionary()); - var contextInfo = new ContextInfo(pageInfo); - - if (node?.Name == null) return null; - - if (elementName == StlChannels.ElementName) - { - var listInfo = ListInfo.GetListInfoByXmlNode(pageInfo, contextInfo, EContextType.Channel); - - return StlChannels.GetDataSource(pageInfo, contextInfo, listInfo); - } - if (elementName == StlContents.ElementName) - { - var listInfo = ListInfo.GetListInfoByXmlNode(pageInfo, contextInfo, EContextType.Content); - - return StlContents.GetDataSource(pageInfo, contextInfo, listInfo); - } - - return null; - } - } -} diff --git a/SiteServer.CMS/StlParser/Utility/StlHtmlUtility.cs b/SiteServer.CMS/StlParser/Utility/StlHtmlUtility.cs deleted file mode 100644 index 36e009478..000000000 --- a/SiteServer.CMS/StlParser/Utility/StlHtmlUtility.cs +++ /dev/null @@ -1,247 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Text; -using System.Text.RegularExpressions; -using System.Xml; -using SiteServer.Utils; - -namespace SiteServer.CMS.StlParser.Utility -{ - public class StlHtmlUtility - { - public static string GetHtmlElementById(string html, string id) - { - const RegexOptions options = RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline | RegexOptions.IgnoreCase; - - var regex = $"]*?id\\s*=\\s*(\"{id}\"|\'{id}\'|{id}).*?>"; - var reg = new Regex(regex, options); - var match = reg.Match(html); - if (match.Success) - { - return match.Value; - } - - regex = $"<\\w+\\s*[^>]*?id\\s*=\\s*(\"{id}\"|\'{id}\'|{id})[^>]*/\\s*>"; - reg = new Regex(regex, options); - match = reg.Match(html); - if (match.Success) - { - return match.Value; - } - - regex = $"<(\\w+?)\\s*[^>]*?id\\s*=\\s*(\"{id}\"|\'{id}\'|{id}).*?>[^>]*]*>"; - reg = new Regex(regex, options); - match = reg.Match(html); - if (match.Success) - { - return match.Value; - } - - return string.Empty; - } - - public static string GetHtmlElementBySRole(string html, string sRole) - { - const RegexOptions options = RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline | RegexOptions.IgnoreCase; - - var regex = $"]*?s-role\\s*=\\s*(\"{sRole}\"|\'{sRole}\'|{sRole}).*?>"; - var reg = new Regex(regex, options); - var match = reg.Match(html); - if (match.Success) - { - return match.Value; - } - - regex = $"<\\w+\\s*[^>]*?s-role\\s*=\\s*(\"{sRole}\"|\'{sRole}\'|{sRole})[^>]*/\\s*>"; - reg = new Regex(regex, options); - match = reg.Match(html); - if (match.Success) - { - return match.Value; - } - - regex = $"<(\\w+?)\\s*[^>]*?s-role\\s*=\\s*(\"{sRole}\"|\'{sRole}\'|{sRole}).*?>[^>]*]*>"; - reg = new Regex(regex, options); - match = reg.Match(html); - if (match.Success) - { - return match.Value; - } - - return string.Empty; - } - - public static List GetHtmlFormElements(string content) - { - var list = new List(); - - const RegexOptions options = RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline | RegexOptions.IgnoreCase; - - var regex = "]*?/>|]*?>[^>]*?"; - var reg = new Regex(regex, options); - var mc = reg.Matches(content); - for (var i = 0; i < mc.Count; i++) - { - var element = mc[i].Value; - list.Add(element); - } - - regex = "]*?/>|]*?>[^>]*?"; - reg = new Regex(regex, options); - mc = reg.Matches(content); - for (var i = 0; i < mc.Count; i++) - { - var element = mc[i].Value; - list.Add(element); - } - - regex = ""; - reg = new Regex(regex, options); - mc = reg.Matches(content); - for (var i = 0; i < mc.Count; i++) - { - var element = mc[i].Value; - list.Add(element); - } - - return list; - } - - public static void ParseHtmlElement(string htmlElement, out string tagName, out string innerXml, out NameValueCollection attributes) - { - tagName = string.Empty; - innerXml = string.Empty; - attributes = new NameValueCollection(); - - var document = StlParserUtility.GetXmlDocument(htmlElement, false); - XmlNode elementNode = document.DocumentElement; - if (elementNode == null) return; - - elementNode = elementNode.FirstChild; - tagName = elementNode.Name; - innerXml = elementNode.InnerXml; - if (elementNode.Attributes == null) return; - - var elementIe = elementNode.Attributes.GetEnumerator(); - while (elementIe.MoveNext()) - { - var attr = (XmlAttribute)elementIe.Current; - var attributeName = attr.Name; - attributes.Add(attributeName, attr.Value); - } - } - - public static void RewriteSubmitButton(StringBuilder builder, string clickString) - { - var submitElement = GetHtmlElementBySRole(builder.ToString(), "submit"); - if (string.IsNullOrEmpty(submitElement)) - { - submitElement = GetHtmlElementById(builder.ToString(), "submit"); - } - if (!string.IsNullOrEmpty(submitElement)) - { - var document = StlParserUtility.GetXmlDocument(submitElement, false); - XmlNode elementNode = document.DocumentElement; - if (elementNode != null) - { - elementNode = elementNode.FirstChild; - if (elementNode.Attributes != null) - { - var elementIe = elementNode.Attributes.GetEnumerator(); - var attributes = new StringDictionary(); - while (elementIe.MoveNext()) - { - var attr = (XmlAttribute)elementIe.Current; - var attributeName = attr.Name.ToLower(); - if (attributeName == "href") - { - attributes.Add(attr.Name, PageUtils.UnclickedUrl); - } - else if (attributeName != "onclick") - { - attributes.Add(attr.Name, attr.Value); - } - } - attributes.Add("onclick", clickString); - attributes.Remove("id"); - attributes.Remove("name"); - - //attributes.Add("id", "submit_" + styleID); - - if (StringUtils.EqualsIgnoreCase(elementNode.Name, "a")) - { - attributes.Remove("href"); - attributes.Add("href", PageUtils.UnclickedUrl); - } - - if (!string.IsNullOrEmpty(elementNode.InnerXml)) - { - builder.Replace(submitElement, - $@"<{elementNode.Name} {TranslateUtils.ToAttributesString(attributes)}>{elementNode.InnerXml}"); - } - else - { - builder.Replace(submitElement, - $@"<{elementNode.Name} {TranslateUtils.ToAttributesString(attributes)}/>"); - } - } - } - } - } - - public static string RewriteOnClick(string originalHtml, string id, string clickString) - { - var rewriteHtml = originalHtml; - var submitElement = GetHtmlElementById(rewriteHtml, id); - if (!string.IsNullOrEmpty(submitElement)) - { - var document = StlParserUtility.GetXmlDocument(submitElement, false); - XmlNode elementNode = document.DocumentElement; - if (elementNode != null) - { - elementNode = elementNode.FirstChild; - if (elementNode.Attributes != null) - { - var elementIe = elementNode.Attributes.GetEnumerator(); - var attributes = new StringDictionary(); - while (elementIe.MoveNext()) - { - var attr = (XmlAttribute)elementIe.Current; - var attributeName = attr.Name.ToLower(); - if (attributeName == "href") - { - attributes.Add(attr.Name, PageUtils.UnclickedUrl); - } - else if (attributeName != "onclick") - { - attributes.Add(attr.Name, attr.Value); - } - } - attributes.Add("onclick", clickString); - attributes.Remove("id"); - attributes.Remove("name"); - if (StringUtils.EqualsIgnoreCase(elementNode.Name, "a")) - { - attributes.Remove("href"); - attributes.Add("href", PageUtils.UnclickedUrl); - } - - if (!string.IsNullOrEmpty(elementNode.InnerXml)) - { - rewriteHtml = rewriteHtml.Replace(submitElement, - $@"<{elementNode.Name} {TranslateUtils.ToAttributesString(attributes)}>{elementNode.InnerXml}"); - } - else - { - rewriteHtml = rewriteHtml.Replace(submitElement, - $@"<{elementNode.Name} {TranslateUtils.ToAttributesString(attributes)}/>"); - } - } - } - } - return rewriteHtml; - } - } -} diff --git a/SiteServer.CMS/StlParser/Utility/StlInnerUtility.cs b/SiteServer.CMS/StlParser/Utility/StlInnerUtility.cs deleted file mode 100644 index bcec03c32..000000000 --- a/SiteServer.CMS/StlParser/Utility/StlInnerUtility.cs +++ /dev/null @@ -1,185 +0,0 @@ -using System.Collections.Generic; -using SiteServer.Utils; -using SiteServer.CMS.StlParser.StlElement; - -namespace SiteServer.CMS.StlParser.Utility -{ - public class StlInnerUtility - { - public static void GetYesNo(string innerXml, out string yes, out string no) - { - yes = string.Empty; - no = string.Empty; - if (string.IsNullOrEmpty(innerXml)) return; - - var stlElementList = StlParserUtility.GetStlElementList(innerXml); - if (stlElementList.Count > 0) - { - foreach (var theStlElement in stlElementList) - { - if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlYes.ElementName) || StlParserUtility.IsSpecifiedStlElement(theStlElement, StlYes.ElementName2)) - { - yes = StlParserUtility.GetInnerXml(theStlElement, true); - } - else if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlNo.ElementName) || StlParserUtility.IsSpecifiedStlElement(theStlElement, StlNo.ElementName2)) - { - no = StlParserUtility.GetInnerXml(theStlElement, true); - } - } - } - - if (string.IsNullOrEmpty(yes) && string.IsNullOrEmpty(no)) - { - yes = innerXml; - } - - yes = StringUtils.Trim(yes); - no = StringUtils.Trim(no); - } - - public static void GetLoadingYesNo(string innerXml, out string loading, out string yes, out string no) - { - loading = string.Empty; - yes = string.Empty; - no = string.Empty; - if (string.IsNullOrEmpty(innerXml)) return; - - var stlElementList = StlParserUtility.GetStlElementList(innerXml); - if (stlElementList.Count > 0) - { - foreach (var theStlElement in stlElementList) - { - if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlLoading.ElementName)) - { - loading = StlParserUtility.GetInnerXml(theStlElement, true); - } - else if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlYes.ElementName) || StlParserUtility.IsSpecifiedStlElement(theStlElement, StlYes.ElementName2)) - { - yes = StlParserUtility.GetInnerXml(theStlElement, true); - } - else if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlNo.ElementName) || StlParserUtility.IsSpecifiedStlElement(theStlElement, StlNo.ElementName2)) - { - no = StlParserUtility.GetInnerXml(theStlElement, true); - } - } - } - - if (string.IsNullOrEmpty(loading) && string.IsNullOrEmpty(yes) && string.IsNullOrEmpty(no)) - { - yes = innerXml; - } - - loading = StringUtils.Trim(loading); - yes = StringUtils.Trim(yes); - no = StringUtils.Trim(no); - } - - //public static void GetTemplateYesNo(string innerXml, out string template, out string yes, out string no) - //{ - // template = string.Empty; - // yes = string.Empty; - // no = string.Empty; - // if (string.IsNullOrEmpty(innerXml)) return; - - // var stlElementList = StlParserUtility.GetStlElementList(innerXml); - // if (stlElementList.Count > 0) - // { - // foreach (var theStlElement in stlElementList) - // { - // if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlTemplate.ElementName)) - // { - // template = StlParserUtility.GetInnerXml(theStlElement, true); - // } - // else if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlYes.ElementName) || StlParserUtility.IsSpecifiedStlElement(theStlElement, StlYes.ElementName2)) - // { - // yes = StlParserUtility.GetInnerXml(theStlElement, true); - // } - // else if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlNo.ElementName) || StlParserUtility.IsSpecifiedStlElement(theStlElement, StlNo.ElementName2)) - // { - // no = StlParserUtility.GetInnerXml(theStlElement, true); - // } - // } - // } - - // if (string.IsNullOrEmpty(template) && string.IsNullOrEmpty(yes) && string.IsNullOrEmpty(no)) - // { - // template = innerXml; - // } - - // template = StringUtils.Trim(template); - // yes = StringUtils.Trim(yes); - // no = StringUtils.Trim(no); - //} - - //public static void GetTemplateLoadingYesNo(string innerXml, out string template, out string loading, out string yes, out string no) - //{ - // template = string.Empty; - // loading = string.Empty; - // yes = string.Empty; - // no = string.Empty; - // if (string.IsNullOrEmpty(innerXml)) return; - - // var stlElementList = StlParserUtility.GetStlElementList(innerXml); - // if (stlElementList.Count > 0) - // { - // foreach (var theStlElement in stlElementList) - // { - // if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlTemplate.ElementName)) - // { - // template = StlParserUtility.GetInnerXml(theStlElement, true); - // } - // else if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlLoading.ElementName)) - // { - // loading = StlParserUtility.GetInnerXml(theStlElement, true); - // } - // else if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlYes.ElementName) || StlParserUtility.IsSpecifiedStlElement(theStlElement, StlYes.ElementName2)) - // { - // yes = StlParserUtility.GetInnerXml(theStlElement, true); - // } - // else if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlNo.ElementName) || StlParserUtility.IsSpecifiedStlElement(theStlElement, StlNo.ElementName2)) - // { - // no = StlParserUtility.GetInnerXml(theStlElement, true); - // } - // } - // } - - // if (string.IsNullOrEmpty(template) && string.IsNullOrEmpty(loading) && string.IsNullOrEmpty(yes) && string.IsNullOrEmpty(no)) - // { - // template = innerXml; - // } - - // template = StringUtils.Trim(template); - // loading = StringUtils.Trim(loading); - // yes = StringUtils.Trim(yes); - // no = StringUtils.Trim(no); - //} - - public static Dictionary GetStlElements(string innerXml, List stlElementNames) - { - var dic = new Dictionary(); - foreach (var stlElementName in stlElementNames) - { - dic[stlElementName] = string.Empty; - } - if (string.IsNullOrEmpty(innerXml)) return dic; - - var stlElementList = StlParserUtility.GetStlElementList(innerXml); - if (stlElementList.Count > 0) - { - foreach (var theStlElement in stlElementList) - { - foreach (var stlElementName in stlElementNames) - { - if (StlParserUtility.IsSpecifiedStlElement(theStlElement, stlElementName)) - { - var template = StlParserUtility.GetInnerXml(theStlElement, true); - dic[stlElementName] = template; - } - } - } - } - - return dic; - } - } -} diff --git a/SiteServer.CMS/StlParser/Utility/StlParserUtility.cs b/SiteServer.CMS/StlParser/Utility/StlParserUtility.cs deleted file mode 100644 index a70100b31..000000000 --- a/SiteServer.CMS/StlParser/Utility/StlParserUtility.cs +++ /dev/null @@ -1,622 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Text; -using System.Text.RegularExpressions; -using System.Xml; -using SiteServer.Utils; -using SiteServer.Utils.ThirdParty.Sgml; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.StlParser.Model; -using SiteServer.Plugin; - -namespace SiteServer.CMS.StlParser.Utility -{ - public static class StlParserUtility - { - public const string OrderDefault = "Default"; //默认排序 - public const string OrderBack = "Back"; //默认排序的相反方向 - public const string OrderAddDate = "AddDate"; //添加时间 - public const string OrderAddDateBack = "AddDateBack"; //添加时间的相反方向 - public const string OrderLastEditDate = "LastEditDate"; //最后更改时间(只可用于内容列表) - public const string OrderLastEditDateBack = "LastEditDateBack"; //最后更改时间的相反方向(只可用于内容列表) - public const string OrderHits = "Hits"; //点击量 - public const string OrderHitsByDay = "HitsByDay"; //日点击量 - public const string OrderHitsByWeek = "HitsByWeek"; //周点击量 - public const string OrderHitsByMonth = "HitsByMonth"; //月点击量 - public const string OrderRandom = "Random"; //随机 - - private const string XmlDeclaration = ""; - - private const string XmlNamespaceStart = ""; - - private const string XmlNamespaceEnd = ""; - - //http://weblogs.asp.net/whaggard/archive/2005/02/20/377025.aspx - // public static Regex REGEX_STL_ELEMENT = new Regex(@" - //]*> - // (?> - // ]*> (?) - // | - // ]*> (?<-LEVEL>) - // | - // (?! ]*> | ]*> ). - // )* - // (?(LEVEL)(?!)) - //]*> - //", ((RegexOptions.Singleline | RegexOptions.IgnoreCase) | RegexOptions.IgnorePatternWhitespace) | RegexOptions.Compiled); - public static readonly Regex RegexStlElement = new Regex(@" -]*> - (?> - ]*> (?) - | - ]*> (?<-LEVEL>) - | - (?! ]*> | ]*> ). - )* - (?(LEVEL)(?!)) -]*>|]*/> -", ((RegexOptions.Singleline | RegexOptions.IgnoreCase) | RegexOptions.IgnorePatternWhitespace) | RegexOptions.Compiled); - - public static string ReplaceXmlNamespace(string content) - { - if (!string.IsNullOrEmpty(content)) - { - return content.Replace(@" xmlns=""http://www.siteserver.cn/stl""", string.Empty).Replace(@" xmlns:stl=""http://www.siteserver.cn/stl""", string.Empty); - } - return string.Empty; - } - - public static XmlDocument GetXmlDocument(string element, bool isXmlContent) - { - var xmlDocument = new XmlDocument - { - PreserveWhitespace = true, - Prefix = "" - }; - - try - { - if (isXmlContent) - { - xmlDocument.LoadXml(XmlDeclaration + XmlNamespaceStart + element + XmlNamespaceEnd); - } - else - { - xmlDocument.LoadXml(XmlDeclaration + XmlNamespaceStart + HtmlToXml(element) + XmlNamespaceEnd); - } - } - catch - { - // ignored - } - //catch(Exception e) - //{ - // TraceUtils.Warn(e.ToString()); - // throw e; - //} - return xmlDocument; - } - - //还原Html转换为Xml时无法保留的特定字符 - public static string GetBackHtml(string content, PageInfo pageInfo) - { - if (string.IsNullOrEmpty(content)) return string.Empty; - - content = content.Replace(ContentUtility.PagePlaceHolder, string.Empty); - content = content.Replace(""", "'"); - content = content.Replace(">", ">"); - content = content.Replace("<", "<"); - content = content.Replace("&", "&"); - content = content.Replace(" xmlns=\"http://www.siteserver.cn/stl\"", string.Empty); - content = content.Replace(" xmlns:stl=\"http://www.siteserver.cn/stl\"", string.Empty); - content = content.Replace(" xmlns:asp=\"http://www.siteserver.cn/stl\"", string.Empty); - content = content.Replace("&#", "&#"); - content = content.Replace(" hexadecimal-value-0x40", " @");//vuejs shorthand @click - content = content.Replace(" hexadecimal-value-0x3a", " :");//vuejs shorthand :href - if (pageInfo?.TemplateInfo == null) return content; - - content = content.Replace("", string.Empty); - return content; - } - - public static string Amp(string content) - { - return content?.Replace("&", "&"); - } - - public static void XmlToHtml(StringBuilder builder) - { - builder?.Replace(""", "'").Replace(">", ">").Replace("<", "<").Replace("&", "&"); - } - - public static string XmlToHtml(string xml) - { - return string.IsNullOrWhiteSpace(xml) ? string.Empty : xml.Replace(""", "'").Replace(">", ">").Replace("<", "<").Replace("&", "&"); - } - - /// - /// 将html代码转换为xml代码,需要在try-catch块中调用。 - /// - public static string HtmlToXml(string html) - { - if (string.IsNullOrWhiteSpace(html)) return string.Empty; - - html = StringUtils.ReplaceIgnoreCase(html, "
    ", "
    "); - html = StringUtils.ReplaceIgnoreCase(html, "&#", "&#"); - html = html.Replace(" @", " hexadecimal-value-0x40");//vuejs shorthand @click - html = html.Replace(" :", " hexadecimal-value-0x3a");//vuejs shorthand :href - //strInputHtml = StringUtils.ReplaceNewline(strInputHtml, NEWLINE_REPLACEMENT); - var reader = new SgmlReader - { - DocType = "HTML" - }; - var sr = new System.IO.StringReader(html); - reader.InputStream = sr; - var sw = new System.IO.StringWriter(); - var w = new XmlTextWriter(sw); - reader.Read(); - while (!reader.EOF) - { - w.WriteNode(reader, true); - } - - w.Flush(); - w.Close(); - var xml = sw.ToString(); - //xml = xml.Replace(NEWLINE_REPLACEMENT, "\r\n"); - return xml; - } - - public static bool IsStlEntityExists(string stlEntityName, string insertedLabelCollection) - { - return insertedLabelCollection.IndexOf(stlEntityName.Substring(0, stlEntityName.Length - 1), StringComparison.Ordinal) != -1; - } - - public static List GetStlLabelList(string templateContent) - { - var stlElementList = GetStlElementList(templateContent); - var stlEntityList = GetStlEntityList(templateContent); - stlElementList.AddRange(stlEntityList); - return stlElementList; - } - - //需要修改 - public static bool IsStlElementExists(string stlElementName, List list) - { - var exists = false; - foreach (var label in list) - { - if (label.ToLower().StartsWith($"<{stlElementName.ToLower()} ") || label.ToLower().StartsWith( - $"<{stlElementName.ToLower()}>")) - { - exists = true; - break; - } - } - return exists; - } - - public static bool IsStlContentElementWithTypePageContent(List list) - { - foreach (var label in list) - { - if (!IsStlContentElement(label, BackgroundContentAttribute.PageContent)) continue; - return true; - } - return false; - } - - public static string GetStlEntity(string stlEntityName, string insertedLabelCollection) - { - var stlEntity = string.Empty; - var labelList = TranslateUtils.StringCollectionToStringList(insertedLabelCollection); - foreach (var labelWithDisplayModeEnNameAndChannelId in labelList) - { - if (labelWithDisplayModeEnNameAndChannelId.StartsWith(stlEntityName.Substring(0, stlEntityName.Length - 1))) - { - stlEntity = labelWithDisplayModeEnNameAndChannelId; - break; - } - } - return stlEntity; - } - - public static string GetStlElement(string stlElementName, List labelList) - { - var stlElement = string.Empty; - foreach (var labelWithDisplayModeEnNameAndChannelId in labelList) - { - if (labelWithDisplayModeEnNameAndChannelId.ToLower().StartsWith($"<{stlElementName.ToLower()} ") || labelWithDisplayModeEnNameAndChannelId.ToLower().StartsWith( - $"<{stlElementName.ToLower()}>")) - { - stlElement = labelWithDisplayModeEnNameAndChannelId; - break; - } - } - return stlElement; - } - - public static string GetStlContentElementWithTypePageContent(List labelList) - { - var stlPageContentElement = string.Empty; - foreach (var label in labelList) - { - if (!IsStlContentElement(label, BackgroundContentAttribute.PageContent)) continue; - stlPageContentElement = label; - break; - } - return stlPageContentElement; - } - - public static string GetNameFromEntity(string stlEntity) - { - var name = stlEntity; - if (stlEntity.IndexOf("_", StringComparison.Ordinal) != -1) - { - name = stlEntity.Substring(0, stlEntity.IndexOf("_", StringComparison.Ordinal)); - name = name + "}"; - } - return name; - } - - public static string GetValueFromEntity(string stlEntity) - { - if (stlEntity.IndexOf("_", StringComparison.Ordinal) == -1) return string.Empty; - - var value = string.Empty; - try - { - var length = stlEntity.LastIndexOf("}", StringComparison.Ordinal) - stlEntity.LastIndexOf("_", StringComparison.Ordinal) - 1; - value = stlEntity.Substring(stlEntity.LastIndexOf("_", StringComparison.Ordinal) + 1, length); - } - catch - { - // ignored - } - return value; - } - - /// - /// 判断此标签是否为Stl实体 - /// - /// - /// - public static bool IsStlEntity(string label) - { - if (label == null) return false; - label = label.ToLower(); - return (label.StartsWith("{stl.") || label.StartsWith("{content.") || label.StartsWith("{channel.")) && label.EndsWith("}"); - } - - public static bool IsStlEntityInclude(string content) - { - if (content == null) return false; - content = content.ToLower(); - return StringUtils.Contains(content, "}") && (StringUtils.Contains(content, "{stl.") || StringUtils.Contains(content, "{content.") || StringUtils.Contains(content, "{channel.")); - } - - public static bool IsSpecifiedStlEntity(EStlEntityType entityType, string stlEntity) - { - return stlEntity != null && stlEntity.TrimStart('{').ToLower().StartsWith(EStlEntityTypeUtils.GetValue(entityType).ToLower()); - } - - /// - /// 判断此标签是否为Stl元素 - /// - /// - /// - public static bool IsStlElement(string label) - { - if (label == null) return false; - return label.ToLower().StartsWith("", StringComparison.Ordinal) != -1; - } - - public static bool IsSpecifiedStlElement(string stlElement, string elementName) - { - if (stlElement == null) return false; - return (StringUtils.StartsWithIgnoreCase(stlElement, $"<{elementName} ") || - StringUtils.StartsWithIgnoreCase(stlElement, $"<{elementName}>")) && - (StringUtils.EndsWithIgnoreCase(stlElement, $"") || - StringUtils.EndsWithIgnoreCase(stlElement, "/>")); - } - - public static Regex GetStlEntityRegex(string entityName) - { - return new Regex($@"{{{entityName}.[^{{}}]*}}", RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled); - } - - /// - /// 得到内容中的STL元素列表 - /// - public static List GetStlElementList(string templateContent) - { - var stlElementList = new List(); - - var mc = RegexStlElement.Matches(templateContent); - for (var i = 0; i < mc.Count; i++) - { - var stlElement = mc[i].Value; - stlElementList.Add(stlElement); - } - - return stlElementList; - } - - /// - /// 得到内容中的STL实体列表 - /// - /// 需要解析的内容 - /// - public static List GetStlEntityList(string content) - { - //首先需要去除]*>.*?<\/stl:\1>", content, string.Empty); - content = RegexStlElement.Replace(content, string.Empty); - - var stlEntityList = new List(); - - //Regex regex = new Regex(@"{[^{}]*}", RegexOptions.Singleline | RegexOptions.IgnoreCase); - //Regex regex = new Regex(@"{stl\.[^{}]*}|{content\.[^{}]*}|{channel\.[^{}]*}|{comment\.[^{}]*}|{request\.[^{}]*}|{sql\.[^{}]*}|{navigation\.[^{}]*}", RegexOptions.Singleline | RegexOptions.IgnoreCase); - var regex = new Regex(EStlEntityTypeUtils.RegexStringAll, RegexOptions.Singleline | RegexOptions.IgnoreCase); - var mc = regex.Matches(content); - for (var i = 0; i < mc.Count; i++) - { - var stlEntity = mc[i].Value; - stlEntityList.Add(stlEntity); - } - - return stlEntityList; - } - - public static List GetStlSqlEntityList(string content) - { - //首先需要去除]*>.*?<\/stl:\1>", content, string.Empty); - content = RegexStlElement.Replace(content, string.Empty); - - var stlEntityList = new List(); - - //Regex regex = new Regex(@"{[^{}]*}", RegexOptions.Singleline | RegexOptions.IgnoreCase); - var regex = new Regex(EStlEntityTypeUtils.RegexStringSql, RegexOptions.Singleline | RegexOptions.IgnoreCase); - var mc = regex.Matches(content); - for (var i = 0; i < mc.Count; i++) - { - var stlEntity = mc[i].Value; - stlEntityList.Add(stlEntity); - } - - return stlEntityList; - } - - public static List GetStlUserEntityList(string content) - { - content = RegexStlElement.Replace(content, string.Empty); - - var stlEntityList = new List(); - - var regex = new Regex(EStlEntityTypeUtils.RegexStringUser, RegexOptions.Singleline | RegexOptions.IgnoreCase); - var mc = regex.Matches(content); - for (var i = 0; i < mc.Count; i++) - { - var stlEntity = mc[i].Value; - stlEntityList.Add(stlEntity); - } - - return stlEntityList; - } - - //判断属于某种类型(type)的元素是否存在 - public static bool IsStlContentElement(string labelString, string type) - { - return RegexUtils.IsMatch($@"]+type=""{type}""[^>]*>", labelString); - } - - //判断属于某种类型(type)的元素是否存在 - public static bool IsStlChannelElement(string labelString, string type) - { - return RegexUtils.IsMatch($@"]+type=""{type}""[^>]*>", labelString); - } - - public static string GetInnerXml(string stlElement, bool isInnerElement) - { - return GetInnerXml(stlElement, isInnerElement, null); - } - - public static string GetInnerXml(string stlElement, bool isInnerElement, LowerNameValueCollection attributes) - { - var retval = string.Empty; - try - { - var xmlDocument = GetXmlDocument(stlElement, isInnerElement); - XmlNode node = xmlDocument.DocumentElement; - if (node != null) - { - node = node.FirstChild; - retval = node.InnerXml; - - if (attributes != null && node.Attributes != null) - { - foreach (XmlAttribute attribute in node.Attributes) - { - attributes.Set(attribute.Name, attribute.Value); - } - } - } - } - catch - { - // ignored - } - return retval; - } - - public static string GetAttribute(string stlElement, string attributeName) - { - return RegexUtils.GetAttributeContent(attributeName, stlElement); - } - - public static LowerNameValueCollection GetAttributes(string stlElement, bool isInnerElement) - { - var attributes = new LowerNameValueCollection(); - try - { - var xmlDocument = GetXmlDocument(stlElement, isInnerElement); - XmlNode node = xmlDocument.DocumentElement; - if (node != null) - { - node = node.FirstChild; - - if (node.Attributes != null) - { - foreach (XmlAttribute attribute in node.Attributes) - { - attributes.Set(attribute.Name, attribute.Value); - } - } - } - } - catch - { - // ignored - } - return attributes; - } - - public static NameValueCollection GetStlAttributes(string stlElement) - { - var attributes = new NameValueCollection(); - try - { - var xmlDocument = GetXmlDocument(stlElement, false); - XmlNode node = xmlDocument.DocumentElement; - if (node != null) - { - node = node.FirstChild; - - if (node.Attributes != null) - { - foreach (XmlAttribute attribute in node.Attributes) - { - attributes.Set(attribute.Name, attribute.Value); - } - } - } - } - catch - { - // ignored - } - return attributes; - } - - public const string ItemIndex = "ItemIndex"; - - public static int ParseItemIndex(int dbItemIndex, string attributeName, ContextInfo contextInfo) - { - var itemIndex = contextInfo.PageItemIndex + dbItemIndex + 1; - if (attributeName.IndexOf('+') == -1 && attributeName.IndexOf('-') == -1) return itemIndex; - - var array = attributeName.Split('+'); - if (array.Length == 2) - { - var addNum = TranslateUtils.ToInt(array[1].Trim(), 1); - return itemIndex + addNum; - } - - array = attributeName.Split('-'); - if (array.Length != 2) return itemIndex; - - var substractNum = TranslateUtils.ToInt(array[1].Trim(), 1); - return itemIndex - substractNum; - } - - public static int GetItemIndex(ContextInfo contextInfo) - { - var dbItemIndex = 0; - if (contextInfo.ContextType == EContextType.Channel) - { - dbItemIndex = contextInfo.ItemContainer.ChannelItem.ItemIndex; - } - else if (contextInfo.ContextType == EContextType.Content) - { - dbItemIndex = contextInfo.ItemContainer.ContentItem.ItemIndex; - } - else if (contextInfo.ContextType == EContextType.SqlContent) - { - dbItemIndex = contextInfo.ItemContainer.SqlItem.ItemIndex; - } - else if (contextInfo.ContextType == EContextType.Site) - { - dbItemIndex = contextInfo.ItemContainer.SiteItem.ItemIndex; - } - else if (contextInfo.ContextType == EContextType.Each) - { - dbItemIndex = contextInfo.ItemContainer.EachItem.ItemIndex; - } - - return contextInfo.PageItemIndex + dbItemIndex + 1; - } - - public static string GetStlErrorMessage(string elementName, string stlContent, Exception ex) - { - LogUtils.AddErrorLog(ex, StringUtils.HtmlEncode(stlContent)); - return $@" -"; - } - - public static string GetAjaxDivId(int updaterId) - { - return "ajaxElement_" + updaterId + "_" + StringUtils.GetRandomInt(100, 1000); - } - - public static string GetStlElement(string stlElementName, NameValueCollection attributes, string innerContent) - { - if (string.IsNullOrEmpty(innerContent)) - { - return $@"<{stlElementName} {TranslateUtils.ToAttributesString(attributes)}>"; - } - return $@"<{stlElementName} {TranslateUtils.ToAttributesString(attributes)}> -{innerContent} -"; - } - - public static string GetStlCurrentUrl(SiteInfo siteInfo, int channelId, int contentId, IContentInfo contentInfo, TemplateType templateType, int templateId, bool isLocal) - { - var currentUrl = string.Empty; - if (templateType == TemplateType.IndexPageTemplate) - { - currentUrl = siteInfo.Additional.WebUrl; - } - else if (templateType == TemplateType.ContentTemplate) - { - if (contentInfo == null) - { - var nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - currentUrl = PageUtility.GetContentUrl(siteInfo, nodeInfo, contentId, isLocal); - } - else - { - currentUrl = PageUtility.GetContentUrl(siteInfo, contentInfo, isLocal); - } - } - else if (templateType == TemplateType.ChannelTemplate) - { - currentUrl = PageUtility.GetChannelUrl(siteInfo, ChannelManager.GetChannelInfo(siteInfo.Id, channelId), isLocal); - } - else if (templateType == TemplateType.FileTemplate) - { - currentUrl = PageUtility.GetFileUrl(siteInfo, templateId, isLocal); - } - //currentUrl是当前页面的地址,前后台分离的时候,不允许带上protocol - //return PageUtils.AddProtocolToUrl(currentUrl); - return currentUrl; - } - } -} diff --git a/SiteServer.CMS/app.config b/SiteServer.CMS/app.config deleted file mode 100644 index 7f48ea153..000000000 --- a/SiteServer.CMS/app.config +++ /dev/null @@ -1,34 +0,0 @@ - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SiteServer.CMS/packages.config b/SiteServer.CMS/packages.config deleted file mode 100644 index 64ff4f54a..000000000 --- a/SiteServer.CMS/packages.config +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/SiteServer.Utils/Auth/AdministratorToken.cs b/SiteServer.Utils/Auth/AdministratorToken.cs deleted file mode 100644 index c8d7f73a6..000000000 --- a/SiteServer.Utils/Auth/AdministratorToken.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace SiteServer.Utils.Auth -{ - public class AdministratorToken - { - public string AdministratorName { get; set; } - - public DateTime AddDate { get; set; } - } -} \ No newline at end of file diff --git a/SiteServer.Utils/Auth/DefaultJsonSerializer.cs b/SiteServer.Utils/Auth/DefaultJsonSerializer.cs deleted file mode 100644 index 4a8cc7ab3..000000000 --- a/SiteServer.Utils/Auth/DefaultJsonSerializer.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Web.Script.Serialization; - -namespace SiteServer.Utils.Auth -{ - /// - /// JSON Serializer using JavaScriptSerializer - /// - public class DefaultJsonSerializer : IJsonSerializer - { - private readonly JavaScriptSerializer serializer = new JavaScriptSerializer(); - - /// - /// Serialize an object to JSON string - /// - /// object - /// JSON string - public string Serialize(object obj) - { - return serializer.Serialize(obj); - } - - /// - /// Deserialize a JSON string to typed object. - /// - /// type of object - /// JSON string - /// typed object - public T Deserialize(string json) - { - return serializer.Deserialize(json); - } - } -} \ No newline at end of file diff --git a/SiteServer.Utils/Auth/UserToken.cs b/SiteServer.Utils/Auth/UserToken.cs deleted file mode 100644 index 4f230f1f3..000000000 --- a/SiteServer.Utils/Auth/UserToken.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; - -namespace SiteServer.Utils.Auth -{ - public class UserToken - { - public string UserName { get; set; } - - public DateTime AddDate { get; set; } - } -} \ No newline at end of file diff --git a/SiteServer.Utils/ControlUtils.cs b/SiteServer.Utils/ControlUtils.cs deleted file mode 100644 index 8048b6a95..000000000 --- a/SiteServer.Utils/ControlUtils.cs +++ /dev/null @@ -1,591 +0,0 @@ -using System.Text; -using System.Collections; -using System.Collections.Specialized; -using System.Web.UI; -using System.Web.UI.WebControls; -using System.Collections.Generic; - -namespace SiteServer.Utils -{ - /// - /// 对控件的帮助类 - /// - public class ControlUtils - { - private ControlUtils() - { - - } - - /// - /// 得到代表控件的HTML代码 - /// - /// 控件 - /// - public static string GetControlRenderHtml(Control control) - { - if (control == null) return string.Empty; - - var builder = new StringBuilder(); - var sw = new System.IO.StringWriter(builder); - var htw = new HtmlTextWriter(sw); - control.RenderControl(htw); - return builder.ToString(); - } - - public static string GetControlRenderHtml(Control control, Page page) - { - if (control == null) return string.Empty; - - var builder = new StringBuilder(); - control.Page = page; - control.DataBind(); - var sw = new System.IO.StringWriter(builder); - var htw = new HtmlTextWriter(sw); - control.RenderControl(htw); - return builder.ToString(); - } - - /// - /// 如果此控件不存在此属性,将属性添加到控件中 - /// - /// 控件 - /// 属性集合 - public static void AddAttributesIfNotExists(IAttributeAccessor accessor, Dictionary attributes) - { - if (accessor == null || attributes == null) return; - - foreach (var key in attributes.Keys) - { - if (accessor.GetAttribute(key) == null) - { - accessor.SetAttribute(key, attributes[key]); - } - } - } - - /// - /// 如果此控件不存在此属性,将属性添加到控件中 - /// - /// - /// - /// - public static void AddAttributeIfNotExists(IAttributeAccessor accessor, string attributeName, string attributeValue) - { - if (accessor == null || attributeName == null) return; - - if (accessor.GetAttribute(attributeName) == null) - { - accessor.SetAttribute(attributeName, attributeValue); - } - } - - - /// - /// 将属性添加到控件中 - /// - /// 控件 - /// 属性集合 - public static void AddAttributes(IAttributeAccessor accessor, StringDictionary attributes) - { - if (accessor == null || attributes == null) return; - - foreach (string key in attributes.Keys) - { - accessor.SetAttribute(key, attributes[key]); - } - } - - /// - /// 将属性添加到控件中 - /// - /// - /// - /// - public static void AddAttribute(IAttributeAccessor accessor, string attributeName, string attributeValue) - { - if (accessor != null && attributeName != null) - { - accessor.SetAttribute(attributeName, attributeValue); - } - } - - public static void AddListControlItems(ListControl listControl, List list) - { - if (listControl == null) return; - - foreach (var value in list) - { - var item = new ListItem(value, value); - listControl.Items.Add(item); - } - } - - - public static string[] GetSelectedListControlValueArray(ListControl listControl) - { - var arraylist = new ArrayList(); - if (listControl != null) - { - foreach (ListItem item in listControl.Items) - { - if (item.Selected) - { - arraylist.Add(item.Value); - } - } - } - var retval = new string[arraylist.Count]; - arraylist.CopyTo(retval); - return retval; - } - - public static string GetSelectedListControlValueCollection(ListControl listControl) - { - var list = new List(); - if (listControl != null) - { - foreach (ListItem item in listControl.Items) - { - if (item.Selected) - { - list.Add(item.Value); - } - } - } - return TranslateUtils.ObjectCollectionToString(list); - } - - public static ArrayList GetSelectedListControlValueArrayList(ListControl listControl) - { - var arraylist = new ArrayList(); - if (listControl != null) - { - foreach (ListItem item in listControl.Items) - { - if (item.Selected) - { - arraylist.Add(item.Value); - } - } - } - return arraylist; - } - - public static ArrayList GetSelectedListControlValueIntArrayList(ListControl listControl) - { - var arraylist = new ArrayList(); - if (listControl != null) - { - foreach (ListItem item in listControl.Items) - { - if (item.Selected) - { - arraylist.Add(TranslateUtils.ToInt(item.Value)); - } - } - } - return arraylist; - } - - public static List GetSelectedListControlValueStringList(ListControl listControl) - { - var list = new List(); - if (listControl != null) - { - foreach (ListItem item in listControl.Items) - { - if (item.Selected) - { - list.Add(item.Value); - } - } - } - return list; - } - - public static List GetSelectedListControlValueIntList(ListControl listControl) - { - var list = new List(); - if (listControl != null) - { - foreach (ListItem item in listControl.Items) - { - if (item.Selected) - { - list.Add(TranslateUtils.ToInt(item.Value)); - } - } - } - return list; - } - - public static string[] GetListControlValues(ListControl listControl) - { - var arraylist = new ArrayList(); - if (listControl != null) - { - foreach (ListItem item in listControl.Items) - { - arraylist.Add(item.Value); - } - } - var retval = new string[arraylist.Count]; - arraylist.CopyTo(retval); - return retval; - } - - public static void SelectSingleItem(ListControl listControl, string value) - { - if (listControl == null) return; - - listControl.ClearSelection(); - - foreach (ListItem item in listControl.Items) - { - if (string.Equals(item.Value, value)) - { - item.Selected = true; - break; - } - } - } - - public static void SelectSingleItemIgnoreCase(ListControl listControl, string value) - { - if (listControl == null) return; - - listControl.ClearSelection(); - foreach (ListItem item in listControl.Items) - { - if (StringUtils.EqualsIgnoreCase(item.Value, value)) - { - item.Selected = true; - break; - } - } - } - - public static void SelectMultiItems(ListControl listControl, params string[] values) - { - if (listControl == null) return; - - listControl.ClearSelection(); - foreach (ListItem item in listControl.Items) - { - foreach (var value in values) - { - if (string.Equals(item.Value, value)) - { - item.Selected = true; - break; - } - } - } - } - - public static void SelectMultiItems(ListControl listControl, List values) - { - if (listControl == null) return; - - listControl.ClearSelection(); - foreach (ListItem item in listControl.Items) - { - foreach (var value in values) - { - if (string.Equals(item.Value, value)) - { - item.Selected = true; - break; - } - } - } - } - - public static void SelectMultiItems(ListControl listControl, List values) - { - if (listControl == null) return; - - listControl.ClearSelection(); - foreach (ListItem item in listControl.Items) - { - foreach (var intVal in values) - { - if (string.Equals(item.Value, intVal.ToString())) - { - item.Selected = true; - break; - } - } - } - } - - public static void SelectMultiItemsIgnoreCase(ListControl listControl, params string[] values) - { - if (listControl == null) return; - - listControl.ClearSelection(); - foreach (ListItem item in listControl.Items) - { - foreach (var value in values) - { - if (StringUtils.EqualsIgnoreCase(item.Value, value)) - { - item.Selected = true; - break; - } - } - } - } - - - public static string SelectedItemsValueToStringCollection(ListItemCollection items) - { - var builder = new StringBuilder(); - if (items!= null) - { - foreach (ListItem item in items) - { - if (item.Selected) - { - builder.Append(item.Value).Append(","); - } - } - if (builder.Length != 0) - builder.Remove(builder.Length - 1, 1); - } - return builder.ToString(); - } - - public static Control FindControlBySelfAndChildren(string id, Control baseControl) - { - Control ctrl = null; - if (baseControl != null) - { - ctrl = baseControl.FindControl(id); - if (ctrl == baseControl) ctrl = null;//DropDownList中FindControl将返回自身 - if (ctrl == null && baseControl.HasControls()) - { - ctrl = FindControlByChildren(id, baseControl.Controls); - } - } - return ctrl; - } - - public static Control FindControlByChildren(string id, ControlCollection controls) - { - foreach (Control control in controls) - { - var ctrl = FindControlBySelfAndChildren(id, control); - if (ctrl != null) - { - return ctrl; - } - } - return null; - } - - //public static string GetInputValue(Control containerControl, string inputName) - //{ - // Control control; - // return GetInputValue(containerControl, inputName, out control); - //} - - ///// - ///// 返回null代表未找到控件。 - ///// - //public static string GetInputValue(Control containerControl, string inputName, out Control control) - //{ - // string value = null; - - // control = FindControlBySelfAndChildren(inputName, containerControl); - // if (control != null) - // { - // value = string.Empty; - // if (control is TextBox) - // { - // var input = (TextBox)control; - // value = input.Text; - // } - // else if (control is HtmlInputControl) - // { - // var input = (HtmlInputControl)control; - // value = input.Value; - // } - // else if (control is HtmlTextArea) - // { - // var input = (HtmlTextArea)control; - // value = input.Value; - // } - // else if (control is TextEditorBase) - // { - // var input = (TextEditorBase)control; - // value = input.Text; - // } - // else if (control is ListControl) - // { - // var select = (ListControl)control; - // var arraylist = GetSelectedListControlValueArrayList(select); - // value = TranslateUtils.ObjectCollectionToString(arraylist); - // } - // else if (control is HtmlSelect) - // { - // var select = (HtmlSelect)control; - // var arraylist = new ArrayList(); - // foreach (ListItem item in select.Items) - // { - // if (item.Selected) - // { - // arraylist.Add(item.Value); - // } - // } - // value = TranslateUtils.ObjectCollectionToString(arraylist); - // } - // else if (control is CheckBox) - // { - // var checkBox = (CheckBox)control; - // value = checkBox.Checked.ToString(); - // } - // } - // return value; - //} - - //public static void SetInputValue(Control containerControl, string inputName, TableStyleInfo styleInfo) - //{ - // var control = FindControlBySelfAndChildren(inputName, containerControl); - - // if (control != null) - // { - // if (control is TextBox) - // { - // var input = (TextBox)control; - // if (string.IsNullOrEmpty(input.Text) && !string.IsNullOrEmpty(styleInfo.DefaultValue)) - // { - // input.Text = styleInfo.DefaultValue; - // } - // } - // else if (control is HtmlInputControl) - // { - // var input = (HtmlInputControl)control; - // if (string.IsNullOrEmpty(input.Value) && !string.IsNullOrEmpty(styleInfo.DefaultValue)) - // { - // input.Value = styleInfo.DefaultValue; - // } - // } - // else if (control is HtmlTextArea) - // { - // var input = (HtmlTextArea)control; - // if (string.IsNullOrEmpty(input.Value) && !string.IsNullOrEmpty(styleInfo.DefaultValue)) - // { - // input.Value = styleInfo.DefaultValue; - // } - // } - // else if (control is TextEditorBase) - // { - // var input = (TextEditorBase)control; - // if (string.IsNullOrEmpty(input.Text) && !string.IsNullOrEmpty(styleInfo.DefaultValue)) - // { - // input.Text = styleInfo.DefaultValue; - // } - // } - // else if (control is ListControl) - // { - // var select = (ListControl)control; - // if (select.Items.Count == 0) - // { - // var tableStyleItemInfoArrayList = BaiRongDataProvider.TableStyleItemDao.GetStyleItemInfoList(styleInfo.TableStyleId); - // if (tableStyleItemInfoArrayList != null && tableStyleItemInfoArrayList.Count > 0) - // { - // foreach (var styleItemInfo in tableStyleItemInfoArrayList) - // { - // var listItem = new ListItem(styleItemInfo.ItemTitle, styleItemInfo.ItemValue); - // listItem.Selected = styleItemInfo.IsSelected; - // select.Items.Add(listItem); - // } - // } - // } - // } - // else if (control is HtmlSelect) - // { - // var select = (HtmlSelect)control; - // if (select.Items.Count == 0) - // { - // var tableStyleItemInfoArrayList = BaiRongDataProvider.TableStyleItemDao.GetStyleItemInfoList(styleInfo.TableStyleId); - // if (tableStyleItemInfoArrayList != null && tableStyleItemInfoArrayList.Count > 0) - // { - // foreach (var styleItemInfo in tableStyleItemInfoArrayList) - // { - // var listItem = new ListItem(styleItemInfo.ItemTitle, styleItemInfo.ItemValue); - // listItem.Selected = styleItemInfo.IsSelected; - // select.Items.Add(listItem); - // } - // } - // } - // } - // } - //} - - //public static void SetInputValue(Control containerControl, string inputName, string value, TableStyleInfo styleInfo) - //{ - // var control = FindControlBySelfAndChildren(inputName, containerControl); - - // if (control != null) - // { - // if (control is TextBox) - // { - // var input = (TextBox)control; - // input.Text = value; - // } - // else if (control is HtmlInputControl) - // { - // var input = (HtmlInputControl)control; - // input.Value = value; - // } - // else if (control is HtmlTextArea) - // { - // var input = (HtmlTextArea)control; - // input.Value = value; - // } - // else if (control is TextEditorBase) - // { - // var input = (TextEditorBase)control; - // input.Text = value; - // } - // else if (control is ListControl) - // { - // var select = (ListControl)control; - // if (select.Items.Count == 0) - // { - // var tableStyleItemInfoArrayList = BaiRongDataProvider.TableStyleItemDao.GetStyleItemInfoList(styleInfo.TableStyleId); - // if (tableStyleItemInfoArrayList != null && tableStyleItemInfoArrayList.Count > 0) - // { - // foreach (var styleItemInfo in tableStyleItemInfoArrayList) - // { - // var listItem = new ListItem(styleItemInfo.ItemTitle, styleItemInfo.ItemValue); - // listItem.Selected = styleItemInfo.IsSelected; - // select.Items.Add(listItem); - // } - // } - // } - // } - // else if (control is HtmlSelect) - // { - // var select = (HtmlSelect)control; - // if (select.Items.Count == 0) - // { - // var tableStyleItemInfoArrayList = BaiRongDataProvider.TableStyleItemDao.GetStyleItemInfoList(styleInfo.TableStyleId); - // if (tableStyleItemInfoArrayList != null && tableStyleItemInfoArrayList.Count > 0) - // { - // foreach (var styleItemInfo in tableStyleItemInfoArrayList) - // { - // var listItem = new ListItem(styleItemInfo.ItemTitle, styleItemInfo.ItemValue); - // listItem.Selected = styleItemInfo.IsSelected; - // select.Items.Add(listItem); - // } - // } - // } - // } - // } - //} - } -} diff --git a/SiteServer.Utils/CookieUtils.cs b/SiteServer.Utils/CookieUtils.cs deleted file mode 100644 index 3f84de8e1..000000000 --- a/SiteServer.Utils/CookieUtils.cs +++ /dev/null @@ -1,56 +0,0 @@ -using System; -using System.Web; - -namespace SiteServer.Utils -{ - public class CookieUtils - { - private CookieUtils() - { - } - - public static void SetCookie(string name, string value, DateTime expires) - { - SetCookie(new HttpCookie(name) - { - Value = value, - Expires = expires - }); - } - - public static void SetCookie(HttpCookie cookie) - { - cookie.Value = TranslateUtils.EncryptStringBySecretKey(cookie.Value); - cookie.HttpOnly = false; - - if (HttpContext.Current.Request.Url.Scheme.Equals("https")) - { - cookie.Secure = true;//通过https传递cookie - } - HttpContext.Current.Response.Cookies.Add(cookie); - } - - public static string GetCookie(string name) - { - if (HttpContext.Current.Request.Cookies[name] == null) return string.Empty; - - var value = HttpContext.Current.Request.Cookies[name].Value; - return TranslateUtils.DecryptStringBySecretKey(value); - } - - public static bool IsExists(string name) - { - return HttpContext.Current.Request.Cookies[name] != null; - } - - public static void Erase(string name) - { - var cookie = HttpContext.Current.Response.Cookies[name]; - if (cookie != null) - { - cookie.Expires = DateTime.Now.AddDays(-1); - cookie.Values.Clear(); - } - } - } -} diff --git a/SiteServer.Utils/DataTypeUtils.cs b/SiteServer.Utils/DataTypeUtils.cs deleted file mode 100644 index fd93e55e3..000000000 --- a/SiteServer.Utils/DataTypeUtils.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System.Web.UI.WebControls; -using SiteServer.Plugin; - -namespace SiteServer.Utils -{ - public class DataTypeUtils - { - public static DataType GetEnumType(string typeStr) - { - var retval = DataType.VarChar; - - if (Equals(DataType.Boolean, typeStr)) - { - retval = DataType.Boolean; - } - else if (Equals(DataType.DateTime, typeStr)) - { - retval = DataType.DateTime; - } - else if (Equals(DataType.Decimal, typeStr)) - { - retval = DataType.Decimal; - } - else if (Equals(DataType.Integer, typeStr)) - { - retval = DataType.Integer; - } - else if (Equals(DataType.Text, typeStr)) - { - retval = DataType.Text; - } - else if (Equals(DataType.VarChar, typeStr)) - { - retval = DataType.VarChar; - } - - return retval; - } - - public static bool Equals(DataType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(type.Value.ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, DataType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(DataType type, string text) - { - return new ListItem(text, type.Value); - } - - public static void AddListItems(ListControl listControl) - { - if (listControl == null) return; - - listControl.Items.Add(GetListItem(DataType.VarChar, "文本")); - listControl.Items.Add(GetListItem(DataType.Text, "备注")); - listControl.Items.Add(GetListItem(DataType.Integer, "整数")); - listControl.Items.Add(GetListItem(DataType.DateTime, "日期")); - listControl.Items.Add(GetListItem(DataType.Decimal, "小数")); - listControl.Items.Add(GetListItem(DataType.Boolean, "布尔值")); - } - - public static string GetText(DataType dataType) - { - var retval = string.Empty; - if (dataType == DataType.VarChar) - { - retval = "文本"; - } - else if (dataType == DataType.Text) - { - retval = "备注"; - } - else if (dataType == DataType.Integer) - { - retval = "整数"; - } - else if (dataType == DataType.DateTime) - { - retval = "日期"; - } - else if (dataType == DataType.Decimal) - { - retval = "小数"; - } - else if (dataType == DataType.Boolean) - { - retval = "布尔值"; - } - return retval; - } - } -} diff --git a/SiteServer.Utils/DatabaseTypeUtils.cs b/SiteServer.Utils/DatabaseTypeUtils.cs deleted file mode 100644 index 0b4fdc574..000000000 --- a/SiteServer.Utils/DatabaseTypeUtils.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System.Web.UI.WebControls; -using SiteServer.Plugin; - -namespace SiteServer.Utils -{ - public class DatabaseTypeUtils - { - public static DatabaseType GetEnumType(string typeStr) - { - var retval = DatabaseType.SqlServer; - - if (Equals(DatabaseType.MySql, typeStr)) - { - retval = DatabaseType.MySql; - } - else if (Equals(DatabaseType.SqlServer, typeStr)) - { - retval = DatabaseType.SqlServer; - } - else if (Equals(DatabaseType.PostgreSql, typeStr)) - { - retval = DatabaseType.PostgreSql; - } - else if (Equals(DatabaseType.Oracle, typeStr)) - { - retval = DatabaseType.Oracle; - } - - return retval; - } - - public static bool Equals(DatabaseType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(type.Value.ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, DatabaseType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(DatabaseType type, bool selected) - { - var item = new ListItem(type.Value, type.Value); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl == null) return; - listControl.Items.Add(GetListItem(DatabaseType.MySql, false)); - listControl.Items.Add(GetListItem(DatabaseType.SqlServer, false)); - listControl.Items.Add(GetListItem(DatabaseType.PostgreSql, false)); - listControl.Items.Add(GetListItem(DatabaseType.Oracle, false)); - } - } -} diff --git a/SiteServer.Utils/DateUtils.cs b/SiteServer.Utils/DateUtils.cs deleted file mode 100644 index 9bd59cf4b..000000000 --- a/SiteServer.Utils/DateUtils.cs +++ /dev/null @@ -1,336 +0,0 @@ -using System; -using System.Globalization; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.Utils -{ - public class DateUtils - { - private DateUtils() - { - } - - public const string FormatStringDateTime = "yyyy-MM-dd HH:mm:ss"; - public const string FormatStringDateOnly = "yyyy-MM-dd"; - - public static string GetRelatedDateTimeString(DateTime datetime) - { - string retval; - var interval = DateTime.Now - datetime; - if (interval.Days > 0) - { - if (interval.Days >= 7 && interval.Days < 35) - { - retval = $"{interval.Days/7}周"; - } - else - { - retval = $"{interval.Days}天"; - } - } - else if (interval.Hours > 0) - { - retval = $"{interval.Hours}小时"; - } - else if (interval.Minutes > 0) - { - retval = $"{interval.Minutes}分钟"; - } - else if (interval.Seconds > 0) - { - retval = $"{interval.Seconds}秒"; - } - else if (interval.Milliseconds > 0) - { - retval = $"{interval.Milliseconds}毫秒"; - } - else - { - retval = "1毫秒"; - } - return retval; - } - - public static string GetRelatedDateTimeString(DateTime datetime, string postfix) - { - return $"{GetRelatedDateTimeString(datetime)}{postfix}"; - } - - public static string GetDateAndTimeString(DateTime datetime, EDateFormatType dateFormat, ETimeFormatType timeFormat) - { - return $"{GetDateString(datetime, dateFormat)} {GetTimeString(datetime, timeFormat)}"; - } - - public static string GetDateAndTimeString(DateTime datetime) - { - if (datetime == SqlMinValue) return string.Empty; - return GetDateAndTimeString(datetime, EDateFormatType.Day, ETimeFormatType.ShortTime); - } - - public static string GetDateString(DateTime datetime) - { - if (datetime == SqlMinValue) return string.Empty; - return GetDateString(datetime, EDateFormatType.Day); - } - - public static string GetDateString(DateTime datetime, EDateFormatType dateFormat) - { - var format = string.Empty; - if (dateFormat == EDateFormatType.Year) - { - format = "yyyy年MM月"; - } - else if (dateFormat == EDateFormatType.Month) - { - format = "MM月dd日"; - } - else if (dateFormat == EDateFormatType.Day) - { - format = "yyyy-MM-dd"; - } - else if (dateFormat == EDateFormatType.Chinese) - { - format = "yyyy年M月d日"; - } - return datetime.ToString(format); - } - - public static string GetTimeString(DateTime datetime) - { - return GetTimeString(datetime, ETimeFormatType.ShortTime); - } - - public static string GetTimeString(DateTime datetime, ETimeFormatType timeFormat) - { - var retval = string.Empty; - if (timeFormat == ETimeFormatType.LongTime) - { - retval = datetime.ToLongTimeString(); - } - else if (timeFormat == ETimeFormatType.ShortTime) - { - retval = datetime.ToShortTimeString(); - } - return retval; - } - - public static int GetSeconds(string intWithUnitString) - { - var seconds = 0; - if (!string.IsNullOrEmpty(intWithUnitString)) - { - intWithUnitString = intWithUnitString.Trim().ToLower(); - if (intWithUnitString.EndsWith("h")) - { - seconds = 60 * 60 * TranslateUtils.ToInt(intWithUnitString.TrimEnd('h')); - } - else if (intWithUnitString.EndsWith("m")) - { - seconds = 60 * TranslateUtils.ToInt(intWithUnitString.TrimEnd('m')); - } - else if (intWithUnitString.EndsWith("s")) - { - seconds = TranslateUtils.ToInt(intWithUnitString.TrimEnd('s')); - } - else - { - seconds = TranslateUtils.ToInt(intWithUnitString); - } - } - return seconds; - } - - public static bool IsSince(string val) - { - if (!string.IsNullOrEmpty(val)) - { - val = val.Trim().ToLower(); - if (val.EndsWith("y") || val.EndsWith("m") || val.EndsWith("d") || val.EndsWith("h")) - { - return true; - } - } - return false; - } - - public static int GetSinceHours(string intWithUnitString) - { - var hours = 0; - if (!string.IsNullOrEmpty(intWithUnitString)) - { - intWithUnitString = intWithUnitString.Trim().ToLower(); - if (intWithUnitString.EndsWith("y")) - { - hours = 8760 * TranslateUtils.ToInt(intWithUnitString.TrimEnd('y')); - } - else if (intWithUnitString.EndsWith("m")) - { - hours = 720 * TranslateUtils.ToInt(intWithUnitString.TrimEnd('m')); - } - else if (intWithUnitString.EndsWith("d")) - { - hours = 24 * TranslateUtils.ToInt(intWithUnitString.TrimEnd('d')); - } - else if (intWithUnitString.EndsWith("h")) - { - hours = TranslateUtils.ToInt(intWithUnitString.TrimEnd('h')); - } - else - { - hours = TranslateUtils.ToInt(intWithUnitString); - } - } - return hours; - } - - public static bool IsTheSameDay(DateTime d1, DateTime d2) - { - if (d1.Year == d2.Year && d1.Month == d2.Month && d1.Day == d2.Day) - { - return true; - } - return false; - } - - public static string Format(DateTime datetime, string formatString) - { - string retval; - if (!string.IsNullOrEmpty(formatString)) - { - retval = formatString.IndexOf("{0:", StringComparison.Ordinal) != -1 ? string.Format(DateTimeFormatInfo.InvariantInfo, formatString, datetime) : datetime.ToString(formatString, DateTimeFormatInfo.InvariantInfo); - } - else - { - retval = GetDateString(datetime); - } - return retval; - } - - public static DateTime SqlMinValue => new DateTime(1754, 1, 1, 0, 0, 0, 0); - - //Task used - public static int GetDayOfWeek(DateTime dateTime) - { - switch (dateTime.DayOfWeek) - { - case DayOfWeek.Monday: - return 1; - - case DayOfWeek.Tuesday: - return 2; - - case DayOfWeek.Wednesday: - return 3; - - case DayOfWeek.Thursday: - return 4; - - case DayOfWeek.Friday: - return 5; - - case DayOfWeek.Saturday: - return 6; - - default: - return 7; - } - } - - public static string ParseThisMoment(DateTime dateTime) - { - if (dateTime != SqlMinValue) - { - return ParseThisMoment(dateTime, DateTime.Now); - } - return string.Empty; - } - - /// - /// 把两个时间差,三天内的时间用今天,昨天,前天表示,后跟时间,无日期 - /// - public static string ParseThisMoment(DateTime dateTime, DateTime currentDateTime) - { - string result; - if (currentDateTime.Year == dateTime.Year && currentDateTime.Month == dateTime.Month)//如果date和当前时间年份或者月份不一致,则直接返回"yyyy-MM-dd HH:mm"格式日期 - { - if (DateDiff("hour", dateTime, currentDateTime) <= 10)//如果date和当前时间间隔在10小时内(曾经是3小时) - { - if (DateDiff("hour", dateTime, currentDateTime) > 0) - return DateDiff("hour", dateTime, currentDateTime) + "小时前"; - - if (DateDiff("minute", dateTime, currentDateTime) > 0) - return DateDiff("minute", dateTime, currentDateTime) + "分钟前"; - - if (DateDiff("second", dateTime, currentDateTime) >= 0) - return DateDiff("second", dateTime, currentDateTime) + "秒前"; - else - return "刚才";//为了解决时间精度不够导致发帖时间问题的兼容 - } - else - { - switch (currentDateTime.Day - dateTime.Day) - { - case 0: - result = "今天 " + dateTime.ToString("HH") + ":" + dateTime.ToString("mm"); - break; - case 1: - result = "昨天 " + dateTime.ToString("HH") + ":" + dateTime.ToString("mm"); - break; - case 2: - result = "前天 " + dateTime.ToString("HH") + ":" + dateTime.ToString("mm"); - break; - default: - result = dateTime.ToString("yyyy-MM-dd HH:mm"); - break; - } - } - } - else - result = dateTime.ToString("yyyy-MM-dd HH:mm"); - return result; - } - - /// - /// 两个时间的差值,可以为秒,小时,天,分钟 - /// - /// - public static long DateDiff(string interval, DateTime startDate, DateTime endDate) - { - long retval = 0; - var ts = new TimeSpan(endDate.Ticks - startDate.Ticks); - if (interval == "second") - { - retval = (long)ts.TotalSeconds; - } - else if (interval == "minute") - { - retval = (long) ts.TotalMinutes; - } - else if (interval == "hour") - { - retval = (long) ts.TotalHours; - } - else if (interval == "day") - { - retval = ts.Days; - } - else if (interval == "week") - { - retval = ts.Days / 7; - } - else if (interval == "month") - { - retval = ts.Days / 30; - } - else if (interval == "quarter") - { - retval = ts.Days / 30 / 3; - } - else if (interval == "year") - { - retval = ts.Days / 365; - } - return retval; - } - } -} diff --git a/SiteServer.Utils/Enumerations/EBoolean.cs b/SiteServer.Utils/Enumerations/EBoolean.cs deleted file mode 100644 index 5fbbdaa18..000000000 --- a/SiteServer.Utils/Enumerations/EBoolean.cs +++ /dev/null @@ -1,102 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.Utils.Enumerations -{ - public enum EBoolean - { - True, - False - } - - public class EBooleanUtils - { - private static string GetValue(EBoolean type) - { - if (type == EBoolean.True) - { - return "True"; - } - if (type == EBoolean.False) - { - return "False"; - } - throw new Exception(); - } - - private static string GetText(EBoolean type) - { - if (type == EBoolean.True) - { - return "是"; - } - if (type == EBoolean.False) - { - return "否"; - } - throw new Exception(); - } - - public static EBoolean GetEnumType(string typeStr) - { - var retval = EBoolean.False; - - if (Equals(EBoolean.True, typeStr)) - { - retval = EBoolean.True; - } - else if (Equals(EBoolean.False, typeStr)) - { - retval = EBoolean.False; - } - - return retval; - } - - public static bool Equals(EBoolean type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EBoolean type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(EBoolean type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EBoolean.True, false)); - listControl.Items.Add(GetListItem(EBoolean.False, false)); - } - } - - public static void AddListItems(ListControl listControl, string trueText, string falseText) - { - if (listControl != null) - { - var item = new ListItem(trueText, GetValue(EBoolean.True)); - listControl.Items.Add(item); - item = new ListItem(falseText, GetValue(EBoolean.False)); - listControl.Items.Add(item); - } - } - - } -} diff --git a/SiteServer.Utils/Enumerations/ECountType.cs b/SiteServer.Utils/Enumerations/ECountType.cs deleted file mode 100644 index 1c27c5d66..000000000 --- a/SiteServer.Utils/Enumerations/ECountType.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; - -namespace SiteServer.Utils.Enumerations -{ - - public enum ECountType - { - View, - Download - } - - public class ECountTypeUtils - { - public static string GetValue(ECountType type) - { - if (type == ECountType.View) - { - return "View"; - } - if (type == ECountType.Download) - { - return "Download"; - } - throw new Exception(); - } - - public static ECountType GetEnumType(string typeStr) - { - var retval = ECountType.View; - - if (Equals(ECountType.View, typeStr)) - { - retval = ECountType.View; - } - else if (Equals(ECountType.Download, typeStr)) - { - retval = ECountType.Download; - } - - return retval; - } - - public static bool Equals(ECountType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, ECountType type) - { - return Equals(type, typeStr); - } - } -} diff --git a/SiteServer.Utils/Enumerations/EDataFormat.cs b/SiteServer.Utils/Enumerations/EDataFormat.cs deleted file mode 100644 index 310d9a3f2..000000000 --- a/SiteServer.Utils/Enumerations/EDataFormat.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.Utils.Enumerations -{ - public enum EDataFormat - { - String, - Json, - Xml - } - - public class EDataFormatUtils - { - public static string GetValue(EDataFormat type) - { - if (type == EDataFormat.String) - { - return "String"; - } - if (type == EDataFormat.Json) - { - return "Json"; - } - if (type == EDataFormat.Xml) - { - return "Xml"; - } - throw new Exception(); - } - - public static string GetText(EDataFormat type) - { - if (type == EDataFormat.String) - { - return "默认"; - } - if (type == EDataFormat.Json) - { - return "Json"; - } - if (type == EDataFormat.Xml) - { - return "Xml"; - } - throw new Exception(); - } - - public static EDataFormat GetEnumType(string typeStr) - { - var retval = EDataFormat.String; - - if (Equals(EDataFormat.Json, typeStr)) - { - retval = EDataFormat.Json; - } - else if (Equals(EDataFormat.Xml, typeStr)) - { - retval = EDataFormat.Xml; - } - - return retval; - } - - public static bool Equals(EDataFormat type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EDataFormat type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(EDataFormat type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EDataFormat.String, false)); - listControl.Items.Add(GetListItem(EDataFormat.Json, false)); - listControl.Items.Add(GetListItem(EDataFormat.Xml, false)); - } - } - } -} diff --git a/SiteServer.Utils/Enumerations/EDiggType.cs b/SiteServer.Utils/Enumerations/EDiggType.cs deleted file mode 100644 index 2c26ab458..000000000 --- a/SiteServer.Utils/Enumerations/EDiggType.cs +++ /dev/null @@ -1,108 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Web.UI.WebControls; - -namespace SiteServer.Utils.Enumerations -{ - public enum EDiggType - { - Good, - Bad, - All - } - - public class EDiggTypeUtils - { - public static string GetValue(EDiggType type) - { - if (type == EDiggType.Good) - { - return "Good"; - } - if (type == EDiggType.Bad) - { - return "Bad"; - } - if (type == EDiggType.All) - { - return "All"; - } - throw new Exception(); - } - - public static string GetText(EDiggType type) - { - if (type == EDiggType.Good) - { - return "仅显示赞同"; - } - if (type == EDiggType.Bad) - { - return "仅显示不赞同"; - } - if (type == EDiggType.All) - { - return "显示全部"; - } - throw new Exception(); - } - - public static EDiggType GetEnumType(string typeStr) - { - var retval = EDiggType.All; - - if (Equals(EDiggType.Good, typeStr)) - { - retval = EDiggType.Good; - } - else if (Equals(EDiggType.Bad, typeStr)) - { - retval = EDiggType.Bad; - } - - return retval; - } - - public static bool Equals(EDiggType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EDiggType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(EDiggType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EDiggType.All, false)); - listControl.Items.Add(GetListItem(EDiggType.Good, false)); - listControl.Items.Add(GetListItem(EDiggType.Bad, false)); - } - } - - public static SortedList TypeList => new SortedList - { - {GetValue(EDiggType.All), GetText(EDiggType.All)}, - {GetValue(EDiggType.Good), GetText(EDiggType.Good)}, - {GetValue(EDiggType.Bad), GetText(EDiggType.Bad)} - }; - } -} diff --git a/SiteServer.Utils/Enumerations/EGender.cs b/SiteServer.Utils/Enumerations/EGender.cs deleted file mode 100644 index c3bfe3e3c..000000000 --- a/SiteServer.Utils/Enumerations/EGender.cs +++ /dev/null @@ -1,100 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.Utils.Enumerations -{ - public enum EGender - { - NotSet, - Male, - Female - } - - public class EGenderUtils - { - public static string GetValue(EGender type) - { - if (type == EGender.NotSet) - { - return "NotSet"; - } - if (type == EGender.Male) - { - return "Male"; - } - if (type == EGender.Female) - { - return "Female"; - } - throw new Exception(); - } - - public static string GetText(EGender type) - { - if (type == EGender.NotSet) - { - return "未设置"; - } - if (type == EGender.Male) - { - return "男"; - } - if (type == EGender.Female) - { - return "女"; - } - throw new Exception(); - } - - public static EGender GetEnumType(string typeStr) - { - var retval = EGender.NotSet; - - if (Equals(EGender.Male, typeStr)) - { - retval = EGender.Male; - } - else if (Equals(EGender.Female, typeStr)) - { - retval = EGender.Female; - } - - return retval; - } - - public static bool Equals(EGender type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EGender type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(EGender type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EGender.NotSet, false)); - listControl.Items.Add(GetListItem(EGender.Male, false)); - listControl.Items.Add(GetListItem(EGender.Female, false)); - } - } - } -} diff --git a/SiteServer.Utils/Enumerations/EImageSizeType.cs b/SiteServer.Utils/Enumerations/EImageSizeType.cs deleted file mode 100644 index 85b2ba416..000000000 --- a/SiteServer.Utils/Enumerations/EImageSizeType.cs +++ /dev/null @@ -1,248 +0,0 @@ -using System; -using System.Collections; -using System.Drawing; - -namespace SiteServer.Utils.Enumerations -{ - public enum EImageSizeType - { - Square, - Thumbnail, - Small, - Medium, - Original - } - - public class EImageSizeTypeUtils - { - public static string GetValue(EImageSizeType type) - { - if (type == EImageSizeType.Square) - { - return "Square"; - } - if (type == EImageSizeType.Thumbnail) - { - return "Thumbnail"; - } - if (type == EImageSizeType.Small) - { - return "Small"; - } - if (type == EImageSizeType.Medium) - { - return "Medium"; - } - if (type == EImageSizeType.Original) - { - return "Original"; - } - throw new Exception(); - } - - public static string GetText(EImageSizeType type) - { - if (type == EImageSizeType.Square) - { - return "矩形"; - } - if (type == EImageSizeType.Thumbnail) - { - return "小图"; - } - if (type == EImageSizeType.Small) - { - return "较小尺寸"; - } - if (type == EImageSizeType.Medium) - { - return "中等尺寸"; - } - if (type == EImageSizeType.Original) - { - return "原始尺寸"; - } - throw new Exception(); - } - - public static EImageSizeType GetEnumType(string typeStr) - { - EImageSizeType retval = EImageSizeType.Original; - - if (Equals(EImageSizeType.Square, typeStr)) - { - retval = EImageSizeType.Square; - } - else if (Equals(EImageSizeType.Thumbnail, typeStr)) - { - retval = EImageSizeType.Thumbnail; - } - else if (Equals(EImageSizeType.Small, typeStr)) - { - retval = EImageSizeType.Small; - } - else if (Equals(EImageSizeType.Medium, typeStr)) - { - retval = EImageSizeType.Medium; - } - else if (Equals(EImageSizeType.Original, typeStr)) - { - retval = EImageSizeType.Original; - } - - return retval; - } - - public static string GetAppendix(EImageSizeType type) - { - string retval = string.Empty; - - if (type == EImageSizeType.Square) - { - retval = "_s"; - } - else if (type == EImageSizeType.Thumbnail) - { - retval = "_t"; - } - else if (type == EImageSizeType.Small) - { - retval = "_m"; - } - else if (type == EImageSizeType.Medium) - { - retval = "_e"; - } - else if (type == EImageSizeType.Original) - { - retval = "_o"; - } - - return retval; - } - - public const int Size_Max_Medium = 500; - public const int Size_Max_Small = 240; - public const int Size_Max_Thumbnail = 100; - - public const int Size_Square = 75; - - public static int GetMaxSize(EImageSizeType type) - { - int size = Size_Max_Medium; - - if (type == EImageSizeType.Square) - { - size = Size_Square; - } - else if (type == EImageSizeType.Thumbnail) - { - size = Size_Max_Thumbnail; - } - else if (type == EImageSizeType.Small) - { - size = Size_Max_Small; - } - - return size; - } - - public static ArrayList GetEImageSizeTypeArrayListByLargerInt(int largerInt) - { - ArrayList arraylist = new ArrayList(); - - arraylist.Add(EImageSizeType.Square); - - if (largerInt > Size_Max_Thumbnail) - { - arraylist.Add(EImageSizeType.Thumbnail); - } - - arraylist.Add(EImageSizeType.Small); - - if (largerInt > Size_Max_Medium) - { - arraylist.Add(EImageSizeType.Medium); - } - - arraylist.Add(EImageSizeType.Original); - - return arraylist; - } - - private static int GetSmallerInt(Size originalSize, EImageSizeType sizeType, bool isWidthLarger, int largerInt) - { - int retval = 0; - if (isWidthLarger) - { - retval = Convert.ToInt32((Convert.ToDouble(largerInt) / Convert.ToDouble(originalSize.Width)) * Convert.ToDouble(originalSize.Height)); - } - else - { - retval = Convert.ToInt32((Convert.ToDouble(largerInt) / Convert.ToDouble(originalSize.Height)) * Convert.ToDouble(originalSize.Width)); - } - return retval; - } - - public static Size GetSize(Size originalSize, EImageSizeType sizeType) - { - Size size = new Size(originalSize.Width, originalSize.Height); - bool isWidthLarger = (originalSize.Width > originalSize.Height); - int largerInt = Math.Max(originalSize.Width, originalSize.Height); - - if (sizeType == EImageSizeType.Medium) - { - largerInt = Math.Min(Size_Max_Medium, largerInt); - } - else if (sizeType == EImageSizeType.Small) - { - largerInt = Math.Min(Size_Max_Small, largerInt); - } - else if (sizeType == EImageSizeType.Thumbnail) - { - largerInt = Math.Min(Size_Max_Thumbnail, largerInt); - } - else if (sizeType == EImageSizeType.Square) - { - int squareWidth = Size_Square; - int squareHeight = Size_Square; - if (originalSize.Width < Size_Square) - { - squareWidth = originalSize.Width; - } - if (originalSize.Height < Size_Square) - { - squareHeight = originalSize.Height; - } - return new Size(squareWidth, squareHeight); - } - - if (largerInt > 0) - { - if (isWidthLarger) - { - size.Width = largerInt; - size.Height = GetSmallerInt(originalSize, sizeType, isWidthLarger, largerInt); - } - else - { - size.Height = largerInt; - size.Width = GetSmallerInt(originalSize, sizeType, isWidthLarger, largerInt); - } - } - - return size; - } - - public static bool Equals(EImageSizeType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - } -} diff --git a/SiteServer.Utils/Enumerations/EImageType.cs b/SiteServer.Utils/Enumerations/EImageType.cs deleted file mode 100644 index fcd21af78..000000000 --- a/SiteServer.Utils/Enumerations/EImageType.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; - -namespace SiteServer.Utils.Enumerations -{ - public enum EImageType - { - Jpg, - Jpeg, - Gif, - Png, - Bmp, - Unknown - } - - public class EImageTypeUtils - { - public static string GetValue(EImageType type) - { - if (type == EImageType.Jpg) - { - return "jpg"; - } - if (type == EImageType.Jpeg) - { - return "jpeg"; - } - if (type == EImageType.Gif) - { - return "gif"; - } - if (type == EImageType.Png) - { - return "png"; - } - if (type == EImageType.Bmp) - { - return "bmp"; - } - if (type == EImageType.Unknown) - { - return "unknown"; - } - throw new Exception(); - } - - public static EImageType GetEnumType(string typeStr) - { - var retval = EImageType.Unknown; - - if (Equals(EImageType.Jpg, typeStr)) - { - retval = EImageType.Jpg; - } - else if (Equals(EImageType.Jpeg, typeStr)) - { - retval = EImageType.Jpeg; - } - else if (Equals(EImageType.Gif, typeStr)) - { - retval = EImageType.Gif; - } - else if (Equals(EImageType.Png, typeStr)) - { - retval = EImageType.Png; - } - else if (Equals(EImageType.Bmp, typeStr)) - { - retval = EImageType.Bmp; - } - - return retval; - } - - public static bool Equals(EImageType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - } -} diff --git a/SiteServer.Utils/Enumerations/ELevelPeriodType.cs b/SiteServer.Utils/Enumerations/ELevelPeriodType.cs deleted file mode 100644 index 979cf7bc3..000000000 --- a/SiteServer.Utils/Enumerations/ELevelPeriodType.cs +++ /dev/null @@ -1,132 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.Utils.Enumerations -{ - public enum ELevelPeriodType - { - None, //不限 - Once, //一次 - Everyday, //每天 - Hour, //间隔小时 - Minute, //间隔分钟 - } - - public class ELevelPeriodTypeUtils - { - public static string GetValue(ELevelPeriodType type) - { - if (type == ELevelPeriodType.None) - { - return "None"; - } - if (type == ELevelPeriodType.Once) - { - return "Once"; - } - if (type == ELevelPeriodType.Everyday) - { - return "Everyday"; - } - if (type == ELevelPeriodType.Hour) - { - return "Hour"; - } - if (type == ELevelPeriodType.Minute) - { - return "Minute"; - } - throw new Exception(); - } - - public static string GetText(ELevelPeriodType type) - { - if (type == ELevelPeriodType.None) - { - return "不限"; - } - if (type == ELevelPeriodType.Once) - { - return "一次"; - } - if (type == ELevelPeriodType.Everyday) - { - return "每天"; - } - if (type == ELevelPeriodType.Hour) - { - return "间隔小时"; - } - if (type == ELevelPeriodType.Minute) - { - return "间隔分钟"; - } - throw new Exception(); - } - - public static ELevelPeriodType GetEnumType(string typeStr) - { - var retval = ELevelPeriodType.None; - - if (Equals(ELevelPeriodType.None, typeStr)) - { - retval = ELevelPeriodType.None; - } - else if (Equals(ELevelPeriodType.Once, typeStr)) - { - retval = ELevelPeriodType.Once; - } - else if (Equals(ELevelPeriodType.Everyday, typeStr)) - { - retval = ELevelPeriodType.Everyday; - } - else if (Equals(ELevelPeriodType.Hour, typeStr)) - { - retval = ELevelPeriodType.Hour; - } - else if (Equals(ELevelPeriodType.Minute, typeStr)) - { - retval = ELevelPeriodType.Minute; - } - - return retval; - } - - public static bool Equals(ELevelPeriodType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, ELevelPeriodType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(ELevelPeriodType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(ELevelPeriodType.None, false)); - listControl.Items.Add(GetListItem(ELevelPeriodType.Once, false)); - listControl.Items.Add(GetListItem(ELevelPeriodType.Everyday, false)); - listControl.Items.Add(GetListItem(ELevelPeriodType.Hour, false)); - listControl.Items.Add(GetListItem(ELevelPeriodType.Minute, false)); - } - } - } -} diff --git a/SiteServer.Utils/Enumerations/EMonth.cs b/SiteServer.Utils/Enumerations/EMonth.cs deleted file mode 100644 index ee9a56dc1..000000000 --- a/SiteServer.Utils/Enumerations/EMonth.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.Utils.Enumerations -{ - public enum EMonth - { - LastMonth, //近一个月 - MonthAgo //一个月前 - } - - public class EMonthUtils - { - public static string GetValue(EMonth type) - { - if (type == EMonth.LastMonth) - { - return "LastMonth"; - } - if (type == EMonth.MonthAgo) - { - return "MonthAgo"; - } - throw new Exception(); - } - - //public static string GetText(EMonth type, string trueText, string falseText) - //{ - // if (type == EMonth.LastMonth) - // { - // return allText; - // } - // else if (type == EMonth.LastMonth) - // { - // return falseText; - // } - // else - // { - // return trueText; - // } - //} - - public static EMonth GetEnumType(string typeStr) - { - var retval = EMonth.LastMonth; - - if (Equals(EMonth.LastMonth, typeStr)) - { - retval = EMonth.LastMonth; - } - else if (Equals(EMonth.MonthAgo, typeStr)) - { - retval = EMonth.MonthAgo; - } - - return retval; - } - - public static bool Equals(EMonth type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EMonth type) - { - return Equals(type, typeStr); - } - - public static void AddListItems(ListControl listControl, string trueText, string falseText) - { - if (listControl != null) - { - var item = new ListItem(trueText, GetValue(EMonth.LastMonth)); - listControl.Items.Add(item); - item = new ListItem(falseText, GetValue(EMonth.MonthAgo)); - listControl.Items.Add(item); - } - } - } -} diff --git a/SiteServer.Utils/Enumerations/EPasswordFormat.cs b/SiteServer.Utils/Enumerations/EPasswordFormat.cs deleted file mode 100644 index 5db5f7ba7..000000000 --- a/SiteServer.Utils/Enumerations/EPasswordFormat.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.Utils.Enumerations -{ - public enum EPasswordFormat - { - Clear, - Hashed, - Encrypted - } - - public class EPasswordFormatUtils - { - public static string GetValue(EPasswordFormat type) - { - if (type == EPasswordFormat.Clear) - { - return "Clear"; - } - if (type == EPasswordFormat.Hashed) - { - return "Hashed"; - } - if (type == EPasswordFormat.Encrypted) - { - return "Encrypted"; - } - throw new Exception(); - } - - public static string GetText(EPasswordFormat type) - { - if (type == EPasswordFormat.Clear) - { - return "不加密"; - } - if (type == EPasswordFormat.Hashed) - { - return "不可逆方式加密"; - } - if (type == EPasswordFormat.Encrypted) - { - return "可逆方式加密"; - } - throw new Exception(); - } - - public static EPasswordFormat GetEnumType(string typeStr) - { - var retval = EPasswordFormat.Clear; - - if (Equals(EPasswordFormat.Clear, typeStr)) - { - retval = EPasswordFormat.Clear; - } - else if (Equals(EPasswordFormat.Hashed, typeStr)) - { - retval = EPasswordFormat.Hashed; - } - else if (Equals(EPasswordFormat.Encrypted, typeStr)) - { - retval = EPasswordFormat.Encrypted; - } - - return retval; - } - - public static bool Equals(EPasswordFormat type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EPasswordFormat type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(EPasswordFormat type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EPasswordFormat.Clear, false)); - listControl.Items.Add(GetListItem(EPasswordFormat.Encrypted, false)); - listControl.Items.Add(GetListItem(EPasswordFormat.Hashed, false)); - } - } - } -} diff --git a/SiteServer.Utils/Enumerations/EPhotoListType.cs b/SiteServer.Utils/Enumerations/EPhotoListType.cs deleted file mode 100644 index e8ab8a39b..000000000 --- a/SiteServer.Utils/Enumerations/EPhotoListType.cs +++ /dev/null @@ -1,91 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.Utils.Enumerations -{ - public enum EPhotoListType - { - Large, //大图浏览 - Thumbnail, //小图浏览 - } - - public class EPhotoListTypeUtils - { - public static string GetValue(EPhotoListType type) - { - if (type == EPhotoListType.Large) - { - return "Large"; - } - if (type == EPhotoListType.Thumbnail) - { - return "Thumbnail"; - } - throw new Exception(); - } - - public static string GetText(EPhotoListType type) - { - if (type == EPhotoListType.Large) - { - return "大图浏览"; - } - if (type == EPhotoListType.Thumbnail) - { - return "小图浏览"; - } - throw new Exception(); - } - - public static EPhotoListType GetEnumType(string typeStr) - { - var retval = EPhotoListType.Large; - - if (Equals(EPhotoListType.Large, typeStr)) - { - retval = EPhotoListType.Large; - } - else if (Equals(EPhotoListType.Thumbnail, typeStr)) - { - retval = EPhotoListType.Thumbnail; - } - - return retval; - } - - public static bool Equals(EPhotoListType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EPhotoListType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(EPhotoListType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EPhotoListType.Large, false)); - listControl.Items.Add(GetListItem(EPhotoListType.Thumbnail, false)); - } - } - - } -} diff --git a/SiteServer.Utils/Enumerations/EPredefinedRole.cs b/SiteServer.Utils/Enumerations/EPredefinedRole.cs deleted file mode 100644 index 47c007892..000000000 --- a/SiteServer.Utils/Enumerations/EPredefinedRole.cs +++ /dev/null @@ -1,219 +0,0 @@ -using System.Collections.Generic; -using System.Web.UI.WebControls; - -namespace SiteServer.Utils.Enumerations -{ - public enum EPredefinedRole - { - ConsoleAdministrator, //超级管理员 - SystemAdministrator, //站点管理员 - Administrator, //管理员 - } - - public class EPredefinedRoleUtils - { - public static string GetValue(EPredefinedRole type) - { - if (type == EPredefinedRole.ConsoleAdministrator) - { - return "ConsoleAdministrator"; - } - if (type == EPredefinedRole.SystemAdministrator) - { - return "SystemAdministrator"; - } - if (type == EPredefinedRole.Administrator) - { - return "Administrator"; - } - return string.Empty; - } - - public static string GetText(EPredefinedRole type) - { - if (type == EPredefinedRole.ConsoleAdministrator) - { - return "超级管理员"; - } - if (type == EPredefinedRole.SystemAdministrator) - { - return "站点管理员"; - } - if (type == EPredefinedRole.Administrator) - { - return "管理员"; - } - return string.Empty; - } - - public static bool IsPredefinedRole(string roleName) - { - var retval = false; - if (Equals(EPredefinedRole.ConsoleAdministrator, roleName)) - { - retval = true; - } - else if (Equals(EPredefinedRole.SystemAdministrator, roleName)) - { - retval = true; - } - else if (Equals(EPredefinedRole.Administrator, roleName)) - { - retval = true; - } - - return retval; - } - - public static EPredefinedRole GetEnumType(string typeStr) - { - var retval = EPredefinedRole.Administrator; - - if (Equals(EPredefinedRole.ConsoleAdministrator, typeStr)) - { - retval = EPredefinedRole.ConsoleAdministrator; - } - else if (Equals(EPredefinedRole.SystemAdministrator, typeStr)) - { - retval = EPredefinedRole.SystemAdministrator; - } - - return retval; - } - - public static EPredefinedRole GetEnumTypeByRoles(string[] roles) - { - var isConsoleAdministrator = false; - var isSystemAdministrator = false; - - if (roles != null && roles.Length > 0) - { - foreach (var role in roles) - { - if (Equals(EPredefinedRole.ConsoleAdministrator, role)) - { - isConsoleAdministrator = true; - } - else if (Equals(EPredefinedRole.SystemAdministrator, role)) - { - isSystemAdministrator = true; - } - } - } - if (isConsoleAdministrator) return EPredefinedRole.ConsoleAdministrator; - if (isSystemAdministrator) return EPredefinedRole.SystemAdministrator; - return EPredefinedRole.Administrator; - } - - public static bool Equals(EPredefinedRole type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, EPredefinedRole type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(EPredefinedRole type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static bool IsConsoleAdministrator(string[] roles) - { - var retval = false; - if (roles != null && roles.Length > 0) - { - foreach (var role in roles) - { - if (Equals(EPredefinedRole.ConsoleAdministrator, role)) - { - retval = true; - break; - } - } - } - return retval; - } - - public static bool IsSystemAdministrator(string[] roles) - { - var retval = false; - if (roles != null && roles.Length > 0) - { - foreach (var role in roles) - { - if (Equals(EPredefinedRole.ConsoleAdministrator, role)) - { - retval = true; - break; - } - if (Equals(EPredefinedRole.SystemAdministrator, role)) - { - retval = true; - break; - } - } - } - return retval; - } - - public static bool IsAdministrator(string[] roles) - { - var retval = false; - if (roles != null && roles.Length > 0) - { - foreach (var role in roles) - { - if (Equals(EPredefinedRole.ConsoleAdministrator, role)) - { - retval = true; - break; - } - if (Equals(EPredefinedRole.SystemAdministrator, role)) - { - retval = true; - break; - } - if(Equals(EPredefinedRole.Administrator,role)) - { - retval = true; - break; - } - } - } - return retval; - } - - public static List GetAllPredefinedRoleName() - { - return new List - { - GetValue(EPredefinedRole.Administrator), - GetValue(EPredefinedRole.SystemAdministrator), - GetValue(EPredefinedRole.ConsoleAdministrator) - }; - } - - public static List GetAllPredefinedRole() - { - return new List - { - EPredefinedRole.Administrator, - EPredefinedRole.SystemAdministrator, - EPredefinedRole.ConsoleAdministrator - }; - } - } -} diff --git a/SiteServer.Utils/Enumerations/ESSOAppType.cs b/SiteServer.Utils/Enumerations/ESSOAppType.cs deleted file mode 100644 index 30abe43d6..000000000 --- a/SiteServer.Utils/Enumerations/ESSOAppType.cs +++ /dev/null @@ -1,85 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.Utils.Enumerations -{ - public enum ESSOAppType - { - SiteServer, //SiteServer 产品 - Others, //其他 - } - public class ESSOAppTypeUtils - { - public static string GetValue(ESSOAppType type) - { - if (type == ESSOAppType.SiteServer) - { - return "SiteServer"; - } - if (type == ESSOAppType.Others) - { - return "Others"; - } - throw new Exception(); - } - - public static string GetText(ESSOAppType type) - { - if (type == ESSOAppType.SiteServer) - { - return "SiteServer 产品"; - } - if (type == ESSOAppType.Others) - { - return "其他"; - } - throw new Exception(); - } - - public static ESSOAppType GetEnumType(string typeStr) - { - var retval = ESSOAppType.SiteServer; - - if (Equals(ESSOAppType.Others, typeStr)) - { - retval = ESSOAppType.Others; - } - - return retval; - } - - public static bool Equals(ESSOAppType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, ESSOAppType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(ESSOAppType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(ESSOAppType.SiteServer, false)); - listControl.Items.Add(GetListItem(ESSOAppType.Others, false)); - } - } - } -} diff --git a/SiteServer.Utils/Enumerations/ESecurityType.cs b/SiteServer.Utils/Enumerations/ESecurityType.cs deleted file mode 100644 index 3778e9474..000000000 --- a/SiteServer.Utils/Enumerations/ESecurityType.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.Utils.Enumerations -{ - public enum ESecurityType - { - Public, - Friends, - SelfOnly - } - - public class ESecurityTypeUtils - { - public static string GetValue(ESecurityType type) - { - if (type == ESecurityType.Public) - { - return "Public"; - } - if (type == ESecurityType.Friends) - { - return "Friends"; - } - if (type == ESecurityType.SelfOnly) - { - return "SelfOnly"; - } - throw new Exception(); - } - - public static string GetText(ESecurityType type) - { - if (type == ESecurityType.Public) - { - return "所有人"; - } - if (type == ESecurityType.Friends) - { - return "我的好友"; - } - if (type == ESecurityType.SelfOnly) - { - return "只有我自己"; - } - throw new Exception(); - } - - public static ESecurityType GetEnumType(string typeStr) - { - var retval = ESecurityType.SelfOnly; - - if (Equals(ESecurityType.Public, typeStr)) - { - retval = ESecurityType.Public; - } - else if (Equals(ESecurityType.Friends, typeStr)) - { - retval = ESecurityType.Friends; - } - else if (Equals(ESecurityType.SelfOnly, typeStr)) - { - retval = ESecurityType.SelfOnly; - } - - return retval; - } - - public static bool Equals(ESecurityType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, ESecurityType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(ESecurityType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(ESecurityType.Public, false)); - listControl.Items.Add(GetListItem(ESecurityType.Friends, false)); - listControl.Items.Add(GetListItem(ESecurityType.SelfOnly, false)); - } - } - } -} diff --git a/SiteServer.Utils/Enumerations/ESmsProviderType.cs b/SiteServer.Utils/Enumerations/ESmsProviderType.cs deleted file mode 100644 index 78a55f56d..000000000 --- a/SiteServer.Utils/Enumerations/ESmsProviderType.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System.Collections.Generic; -using System.Web.UI.WebControls; - -namespace SiteServer.Utils.Enumerations -{ - public enum ESmsProviderType - { - Yunpian, - None - } - - public class ESmsProviderTypeUtils - { - public static string GetValue(ESmsProviderType type) - { - if (type == ESmsProviderType.Yunpian) - { - return "Yunpian"; - } - return "None"; - } - - public static string GetText(ESmsProviderType type) - { - if (type == ESmsProviderType.Yunpian) - { - return "云片"; - } - return "无"; - } - - public static string GetUrl(ESmsProviderType type) - { - if (type == ESmsProviderType.Yunpian) - { - return "http://www.yunpian.com/"; - } - return string.Empty; - } - - public static ESmsProviderType GetEnumType(string typeStr) - { - var retval = ESmsProviderType.None; - if (Equals(typeStr, ESmsProviderType.Yunpian)) - { - retval = ESmsProviderType.Yunpian; - } - return retval; - } - - public static bool Equals(ESmsProviderType type, string typeStr) - { - return !string.IsNullOrEmpty(typeStr) && string.Equals(GetValue(type).ToLower(), typeStr.ToLower()); - } - - public static bool Equals(string typeStr, ESmsProviderType type) - { - return Equals(type, typeStr); - } - - public static List GetList() - { - return new List - { - ESmsProviderType.Yunpian - }; - } - - public static ListItem GetListItem(ESmsProviderType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(ESmsProviderType.None, false)); - listControl.Items.Add(GetListItem(ESmsProviderType.Yunpian, false)); - } - } - } -} diff --git a/SiteServer.Utils/Enumerations/ESubscribePushType.cs b/SiteServer.Utils/Enumerations/ESubscribePushType.cs deleted file mode 100644 index 964cf4d6e..000000000 --- a/SiteServer.Utils/Enumerations/ESubscribePushType.cs +++ /dev/null @@ -1,94 +0,0 @@ -using System; -using System.Web.UI.WebControls; - -namespace SiteServer.Utils.Enumerations -{ - /// - /// 推送类型 - /// - public enum ESubscribePushType - { - ManualPush, - TimedPush - } - - public class ESubscribePushTypeUtils - { - public static string GetValue(ESubscribePushType type) - { - if (type == ESubscribePushType.ManualPush) - { - return "ManualPush"; - } - if (type == ESubscribePushType.TimedPush) - { - return "TimedPush"; - } - throw new Exception(); - } - - public static string GetText(ESubscribePushType type) - { - if (type == ESubscribePushType.ManualPush) - { - return "手动推送"; - } - if (type == ESubscribePushType.TimedPush) - { - return "定时推送"; - } - throw new Exception(); - } - - public static ESubscribePushType GetEnumType(string typeStr) - { - var retval = ESubscribePushType.ManualPush; - - if (Equals(ESubscribePushType.ManualPush, typeStr)) - { - retval = ESubscribePushType.ManualPush; - } - else if (Equals(ESubscribePushType.TimedPush, typeStr)) - { - retval = ESubscribePushType.TimedPush; - } - - return retval; - } - - public static bool Equals(ESubscribePushType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, ESubscribePushType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(ESubscribePushType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(ESubscribePushType.ManualPush, false)); - listControl.Items.Add(GetListItem(ESubscribePushType.TimedPush, false)); - } - } - - } -} diff --git a/SiteServer.Utils/Enumerations/ETaxisType.cs b/SiteServer.Utils/Enumerations/ETaxisType.cs deleted file mode 100644 index 44365723a..000000000 --- a/SiteServer.Utils/Enumerations/ETaxisType.cs +++ /dev/null @@ -1,440 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Web.UI.WebControls; -using SiteServer.Plugin; - -namespace SiteServer.Utils.Enumerations -{ - public enum ETaxisType - { - OrderById, //内容ID(升序) - OrderByIdDesc, //内容ID(降序) - OrderByChannelId, //栏目ID(升序) - OrderByChannelIdDesc, //栏目ID(降序) - OrderByAddDate, //添加时间(升序) - OrderByAddDateDesc, //添加时间(降序) - OrderByLastEditDate, //更新时间(升序) - OrderByLastEditDateDesc, //更新时间(降序) - OrderByTaxis, //自定义排序(反方向) - OrderByTaxisDesc, //自定义排序 - OrderByHits, //按点击量排序 - OrderByHitsByDay, //按日点击量排序 - OrderByHitsByWeek, //按周点击量排序 - OrderByHitsByMonth, //按月点击量排序 - OrderByRandom //随机排序 - } - - public class ETaxisTypeUtils - { - public static string GetValue(ETaxisType type) - { - if (type == ETaxisType.OrderById) - { - return nameof(ETaxisType.OrderById); - } - if (type == ETaxisType.OrderByIdDesc) - { - return nameof(ETaxisType.OrderByIdDesc); - } - if (type == ETaxisType.OrderByChannelId) - { - return nameof(ETaxisType.OrderByChannelId); - } - if (type == ETaxisType.OrderByChannelIdDesc) - { - return nameof(ETaxisType.OrderByChannelIdDesc); - } - if (type == ETaxisType.OrderByAddDate) - { - return nameof(ETaxisType.OrderByAddDate); - } - if (type == ETaxisType.OrderByAddDateDesc) - { - return nameof(ETaxisType.OrderByAddDateDesc); - } - if (type == ETaxisType.OrderByLastEditDate) - { - return nameof(ETaxisType.OrderByLastEditDate); - } - if (type == ETaxisType.OrderByLastEditDateDesc) - { - return nameof(ETaxisType.OrderByLastEditDateDesc); - } - if (type == ETaxisType.OrderByTaxis) - { - return nameof(ETaxisType.OrderByTaxis); - } - if (type == ETaxisType.OrderByTaxisDesc) - { - return nameof(ETaxisType.OrderByTaxisDesc); - } - if (type == ETaxisType.OrderByHits) - { - return nameof(ETaxisType.OrderByHits); - } - if (type == ETaxisType.OrderByHitsByDay) - { - return nameof(ETaxisType.OrderByHitsByDay); - } - if (type == ETaxisType.OrderByHitsByWeek) - { - return nameof(ETaxisType.OrderByHitsByWeek); - } - if (type == ETaxisType.OrderByHitsByMonth) - { - return nameof(ETaxisType.OrderByHitsByMonth); - } - if (type == ETaxisType.OrderByRandom) - { - return nameof(ETaxisType.OrderByRandom); - } - - throw new Exception(); - } - - public static string GetChannelOrderByString(ETaxisType taxisType) - { - return GetChannelOrderByString(taxisType, string.Empty, null); - } - - public static string GetChannelOrderByString(ETaxisType taxisType, string orderByString, List orderedContentIdList) - { - if (!string.IsNullOrEmpty(orderByString)) - { - if (orderByString.Trim().ToUpper().StartsWith("ORDER BY ")) - { - return orderByString; - } - return "ORDER BY " + orderByString; - } - - var retval = string.Empty; - if (taxisType == ETaxisType.OrderById) - { - retval = $"ORDER BY {nameof(IChannelInfo.Id)} ASC"; - } - else if (taxisType == ETaxisType.OrderByIdDesc) - { - retval = $"ORDER BY {nameof(IChannelInfo.Id)} DESC"; - } - else if (taxisType == ETaxisType.OrderByChannelId) - { - retval = $"ORDER BY {nameof(IChannelInfo.Id)} ASC"; - } - else if (taxisType == ETaxisType.OrderByChannelIdDesc) - { - retval = $"ORDER BY {nameof(IChannelInfo.Id)} DESC"; - } - else if (taxisType == ETaxisType.OrderByAddDate) - { - retval = $"ORDER BY {nameof(IChannelInfo.AddDate)} ASC"; - } - else if (taxisType == ETaxisType.OrderByAddDateDesc) - { - retval = $"ORDER BY {nameof(IChannelInfo.AddDate)} DESC"; - } - else if (taxisType == ETaxisType.OrderByLastEditDate) - { - retval = $"ORDER BY {nameof(IChannelInfo.AddDate)} ASC"; - } - else if (taxisType == ETaxisType.OrderByLastEditDateDesc) - { - retval = $"ORDER BY {nameof(IChannelInfo.AddDate)} DESC"; - } - else if (taxisType == ETaxisType.OrderByTaxis) - { - retval = $"ORDER BY {nameof(IChannelInfo.Taxis)} ASC"; - } - else if (taxisType == ETaxisType.OrderByTaxisDesc) - { - retval = $"ORDER BY {nameof(IChannelInfo.Taxis)} DESC"; - } - else if (taxisType == ETaxisType.OrderByHits) - { - if (orderedContentIdList != null && orderedContentIdList.Count > 0) - { - orderedContentIdList.Reverse(); - retval = - $"ORDER BY CHARINDEX(CONVERT(VARCHAR, {nameof(IChannelInfo.Id)}), '{TranslateUtils.ObjectCollectionToString(orderedContentIdList)}') DESC, {nameof(IChannelInfo.Taxis)} ASC"; - } - else - { - retval = $"ORDER BY {nameof(IChannelInfo.Taxis)} ASC"; - } - } - else if (taxisType == ETaxisType.OrderByRandom) - { - retval = SqlUtils.GetOrderByRandom(); - } - - return retval; - } - - public static string GetContentOrderByString(ETaxisType taxisType) - { - return GetContentOrderByString(taxisType, string.Empty); - } - - public static string GetContentOrderByString(ETaxisType taxisType, string orderByString) - { - if (!string.IsNullOrEmpty(orderByString)) - { - if (orderByString.Trim().ToUpper().StartsWith("ORDER BY ")) - { - return orderByString; - } - return "ORDER BY " + orderByString; - } - - var retval = string.Empty; - - if (taxisType == ETaxisType.OrderById) - { - retval = $"ORDER BY {nameof(IContentInfo.IsTop)} DESC, {nameof(IContentInfo.Id)} ASC"; - } - else if (taxisType == ETaxisType.OrderByIdDesc) - { - retval = $"ORDER BY {nameof(IContentInfo.IsTop)} DESC, {nameof(IContentInfo.Id)} DESC"; - } - else if (taxisType == ETaxisType.OrderByChannelId) - { - retval = $"ORDER BY {nameof(IContentInfo.IsTop)} DESC, {nameof(IContentInfo.ChannelId)} ASC, {nameof(IContentInfo.Id)} DESC"; - } - else if (taxisType == ETaxisType.OrderByChannelIdDesc) - { - retval = $"ORDER BY {nameof(IContentInfo.IsTop)} DESC, {nameof(IContentInfo.ChannelId)} DESC, {nameof(IContentInfo.Id)} DESC"; - } - else if (taxisType == ETaxisType.OrderByAddDate) - { - retval = $"ORDER BY {nameof(IContentInfo.IsTop)} DESC, {nameof(IContentInfo.AddDate)} ASC, {nameof(IContentInfo.Id)} DESC"; - } - else if (taxisType == ETaxisType.OrderByAddDateDesc) - { - retval = $"ORDER BY {nameof(IContentInfo.IsTop)} DESC, {nameof(IContentInfo.AddDate)} DESC, {nameof(IContentInfo.Id)} DESC"; - } - else if (taxisType == ETaxisType.OrderByLastEditDate) - { - retval = $"ORDER BY {nameof(IContentInfo.IsTop)} DESC, {nameof(IContentInfo.LastEditDate)} ASC, {nameof(IContentInfo.Id)} DESC"; - } - else if (taxisType == ETaxisType.OrderByLastEditDateDesc) - { - retval = $"ORDER BY {nameof(IContentInfo.IsTop)} DESC, {nameof(IContentInfo.LastEditDate)} DESC, {nameof(IContentInfo.Id)} DESC"; - } - else if (taxisType == ETaxisType.OrderByTaxis) - { - retval = $"ORDER BY {nameof(IContentInfo.IsTop)} DESC, {nameof(IContentInfo.Taxis)} ASC, {nameof(IContentInfo.Id)} DESC"; - } - else if (taxisType == ETaxisType.OrderByTaxisDesc) - { - retval = $"ORDER BY {nameof(IContentInfo.IsTop)} DESC, {nameof(IContentInfo.Taxis)} DESC, {nameof(IContentInfo.Id)} DESC"; - } - else if (taxisType == ETaxisType.OrderByHits) - { - retval = $"ORDER BY {nameof(IContentInfo.Hits)} DESC, {nameof(IContentInfo.Id)} DESC"; - } - else if (taxisType == ETaxisType.OrderByHitsByDay) - { - retval = $"ORDER BY {nameof(IContentInfo.HitsByDay)} DESC, {nameof(IContentInfo.Id)} DESC"; - } - else if (taxisType == ETaxisType.OrderByHitsByWeek) - { - retval = $"ORDER BY {nameof(IContentInfo.HitsByWeek)} DESC, {nameof(IContentInfo.Id)} DESC"; - } - else if (taxisType == ETaxisType.OrderByHitsByMonth) - { - retval = $"ORDER BY {nameof(IContentInfo.HitsByMonth)} DESC, {nameof(IContentInfo.Id)} DESC"; - } - else if (taxisType == ETaxisType.OrderByRandom) - { - retval = SqlUtils.GetOrderByRandom(); - } - - return retval; - } - - public static string GetText(ETaxisType type) - { - if (type == ETaxisType.OrderById) - { - return "内容ID(升序)"; - } - if (type == ETaxisType.OrderByIdDesc) - { - return "内容ID(降序)"; - } - if (type == ETaxisType.OrderByChannelId) - { - return "栏目ID(升序)"; - } - if (type == ETaxisType.OrderByChannelIdDesc) - { - return "栏目ID(降序)"; - } - if (type == ETaxisType.OrderByAddDate) - { - return "添加时间(升序)"; - } - if (type == ETaxisType.OrderByAddDateDesc) - { - return "添加时间(降序)"; - } - if (type == ETaxisType.OrderByLastEditDate) - { - return "更新时间(升序)"; - } - if (type == ETaxisType.OrderByLastEditDateDesc) - { - return "更新时间(降序)"; - } - if (type == ETaxisType.OrderByTaxis) - { - return "自定义排序(升序)"; - } - if (type == ETaxisType.OrderByTaxisDesc) - { - return "自定义排序(降序)"; - } - if (type == ETaxisType.OrderByHits) - { - return "点击量排序"; - } - if (type == ETaxisType.OrderByHitsByDay) - { - return "日点击量排序"; - } - if (type == ETaxisType.OrderByHitsByWeek) - { - return "周点击量排序"; - } - if (type == ETaxisType.OrderByHitsByMonth) - { - return "月点击量排序"; - } - throw new Exception(); - } - - public static ETaxisType GetEnumType(string typeStr) - { - var retval = ETaxisType.OrderByTaxisDesc; - - if (Equals(ETaxisType.OrderById, typeStr)) - { - retval = ETaxisType.OrderById; - } - else if (Equals(ETaxisType.OrderByIdDesc, typeStr)) - { - retval = ETaxisType.OrderByIdDesc; - } - else if (Equals(ETaxisType.OrderByChannelId, typeStr)) - { - retval = ETaxisType.OrderByChannelId; - } - else if (Equals(ETaxisType.OrderByChannelIdDesc, typeStr)) - { - retval = ETaxisType.OrderByChannelIdDesc; - } - else if (Equals(ETaxisType.OrderByAddDate, typeStr)) - { - retval = ETaxisType.OrderByAddDate; - } - else if (Equals(ETaxisType.OrderByAddDateDesc, typeStr)) - { - retval = ETaxisType.OrderByAddDateDesc; - } - else if (Equals(ETaxisType.OrderByLastEditDate, typeStr)) - { - retval = ETaxisType.OrderByLastEditDate; - } - else if (Equals(ETaxisType.OrderByLastEditDateDesc, typeStr)) - { - retval = ETaxisType.OrderByLastEditDateDesc; - } - else if (Equals(ETaxisType.OrderByTaxis, typeStr)) - { - retval = ETaxisType.OrderByTaxis; - } - else if (Equals(ETaxisType.OrderByTaxisDesc, typeStr)) - { - retval = ETaxisType.OrderByTaxisDesc; - } - else if (Equals(ETaxisType.OrderByHits, typeStr)) - { - retval = ETaxisType.OrderByHits; - } - else if (Equals(ETaxisType.OrderByHitsByDay, typeStr)) - { - retval = ETaxisType.OrderByHitsByDay; - } - else if (Equals(ETaxisType.OrderByHitsByWeek, typeStr)) - { - retval = ETaxisType.OrderByHitsByWeek; - } - else if (Equals(ETaxisType.OrderByHitsByMonth, typeStr)) - { - retval = ETaxisType.OrderByHitsByMonth; - } - - return retval; - } - - public static bool Equals(ETaxisType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, ETaxisType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(ETaxisType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl == null) return; - - listControl.Items.Add(GetListItem(ETaxisType.OrderById, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByIdDesc, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByChannelId, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByChannelIdDesc, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByAddDate, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByAddDateDesc, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByLastEditDate, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByLastEditDateDesc, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByTaxis, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByTaxisDesc, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByHits, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByHitsByDay, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByHitsByWeek, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByHitsByMonth, false)); - } - - public static void AddListItemsForChannelEdit(ListControl listControl) - { - if (listControl == null) return; - - listControl.Items.Add(GetListItem(ETaxisType.OrderById, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByIdDesc, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByAddDate, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByAddDateDesc, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByLastEditDate, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByLastEditDateDesc, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByTaxis, false)); - listControl.Items.Add(GetListItem(ETaxisType.OrderByTaxisDesc, false)); - } - - } -} diff --git a/SiteServer.Utils/Enumerations/ETextEditorType.cs b/SiteServer.Utils/Enumerations/ETextEditorType.cs deleted file mode 100644 index 10c9d5301..000000000 --- a/SiteServer.Utils/Enumerations/ETextEditorType.cs +++ /dev/null @@ -1,115 +0,0 @@ -using System.Text.RegularExpressions; - -namespace SiteServer.Utils.Enumerations -{ - public class ETextEditorTypeUtils - { - public static string GetInsertHtmlScript(string attributeName, string html) - { - html = html.Replace("\"", "'"); - string script = $@"UE.getEditor(""{attributeName}"", {{allowDivTransToP: false}}).execCommand(""insertHTML"",""{html}"");"; - if (!string.IsNullOrEmpty(html)) - { - html = html.Replace(@"""", @"\"""); - script = $@"UE.getEditor(""{attributeName}"", {{allowDivTransToP: false}}).execCommand(""insertHTML"",""{html}"");"; - } - return script; - } - - public static string GetEditorInstanceScript() - { - return "UE"; - } - - public static string GetInsertVideoScript(string attributeName, string playUrl, int width, int height, bool isAutoPlay) - { - var script = string.Empty; - if (!string.IsNullOrEmpty(playUrl)) - { - if (width > 0 && height > 0) - { - script = - $@"UE.getEditor(""{attributeName}"", {{allowDivTransToP: false}}).execCommand(""insertVideo"",{{url: ""{playUrl}"",width: {width},height: {height},isAutoPlay: ""{isAutoPlay - .ToString().ToLower()}""}});"; - } - else - { - script = - $@"UE.getEditor(""{attributeName}"", {{allowDivTransToP: false}}).execCommand(""insertVideo"",{{url: ""{playUrl}"",isAutoPlay: ""{isAutoPlay - .ToString().ToLower()}""}});"; - } - } - return script; - } - - public static string GetInsertAudioScript(string attributeName, string playUrl, bool isAutoPlay) - { - var script = string.Empty; - if (!string.IsNullOrEmpty(playUrl)) - { - script = - $@"UE.getEditor(""{attributeName}"", {{allowDivTransToP: false}}).execCommand(""music"",{{url: ""{playUrl}"",isAutoPlay: ""{isAutoPlay - .ToString().ToLower()}""}});"; - } - return script; - } - - public static string GetPureTextScript(string attributeName) - { - string script = $@"UE.getEditor(""{attributeName}"", {{allowDivTransToP: false}}).getContentTxt();"; - return script; - } - - public static string GetContentScript(string attributeName) - { - string script = $@"UE.getEditor(""{attributeName}"", {{allowDivTransToP: false}}).getContent();"; - return script; - } - - public static string GetSetContentScript(string attributeName, string contentWithoutQuote) - { - string script = $@"UE.getEditor(""{attributeName}"", {{allowDivTransToP: false}}).setContent({contentWithoutQuote});"; - return script; - } - - public static string TranslateToStlElement(string html) - { - var retval = html; - if (!string.IsNullOrEmpty(retval)) - { - var regex = new Regex(@"]*class=""edui-faked-[^>]*/>", ((RegexOptions.Singleline | RegexOptions.IgnoreCase) | RegexOptions.IgnorePatternWhitespace) | RegexOptions.Compiled); - - var mc = regex.Matches(retval); - for (var i = 0; i < mc.Count; i++) - { - var original = mc[i].Value; - if (original.Contains("edui-faked-video")) - { - var replace = original.Replace("embed", "stl:player"); - retval = retval.Replace(original, replace); - } - else if (original.Contains("edui-faked-music")) - { - var replace = original.Replace("embed", "stl:audio"); - retval = retval.Replace(original, replace); - } - } - - //retval = retval.Replace(@" 255) - // // return false; - - // // // GDI+ still lies to us - the return format is BGR, NOT RGB. - // // var bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - - // // var stride = bmData.Stride; - // // var Scan0 = bmData.Scan0; - - // // var nVal = 0; - - // // unsafe - // // { - // // var p = (byte*)(void*)Scan0; - - // // var nOffset = stride - b.Width * 3; - // // var nWidth = b.Width * 3; - - // // for (var y = 0; y < b.Height; ++y) - // // { - // // for (var x = 0; x < nWidth; ++x) - // // { - // // nVal = (int)(p[0] + nBrightness); - - // // if (nVal < 0) nVal = 0; - // // if (nVal > 255) nVal = 255; - - // // p[0] = (byte)nVal; - - // // ++p; - // // } - // // p += nOffset; - // // } - // // } - - // // b.UnlockBits(bmData); - - // // return true; - // //} - - // //public static bool Contrast(Bitmap b, sbyte nContrast) - // //{ - // // if (nContrast < -100) return false; - // // if (nContrast > 100) return false; - - // // double pixel = 0, contrast = (100.0 + nContrast) / 100.0; - - // // contrast *= contrast; - - // // int red, green, blue; - - // // // GDI+ still lies to us - the return format is BGR, NOT RGB. - // // var bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - - // // var stride = bmData.Stride; - // // var Scan0 = bmData.Scan0; - - // // unsafe - // // { - // // var p = (byte*)(void*)Scan0; - - // // var nOffset = stride - b.Width * 3; - - // // for (var y = 0; y < b.Height; ++y) - // // { - // // for (var x = 0; x < b.Width; ++x) - // // { - // // blue = p[0]; - // // green = p[1]; - // // red = p[2]; - - // // pixel = red / 255.0; - // // pixel -= 0.5; - // // pixel *= contrast; - // // pixel += 0.5; - // // pixel *= 255; - // // if (pixel < 0) pixel = 0; - // // if (pixel > 255) pixel = 255; - // // p[2] = (byte)pixel; - - // // pixel = green / 255.0; - // // pixel -= 0.5; - // // pixel *= contrast; - // // pixel += 0.5; - // // pixel *= 255; - // // if (pixel < 0) pixel = 0; - // // if (pixel > 255) pixel = 255; - // // p[1] = (byte)pixel; - - // // pixel = blue / 255.0; - // // pixel -= 0.5; - // // pixel *= contrast; - // // pixel += 0.5; - // // pixel *= 255; - // // if (pixel < 0) pixel = 0; - // // if (pixel > 255) pixel = 255; - // // p[0] = (byte)pixel; - - // // p += 3; - // // } - // // p += nOffset; - // // } - // // } - - // // b.UnlockBits(bmData); - - // // return true; - // //} - - // public static bool Gamma(Bitmap b, double red, double green, double blue) - // { - // if (red < .2 || red > 5) return false; - // if (green < .2 || green > 5) return false; - // if (blue < .2 || blue > 5) return false; - - // var redGamma = new byte[256]; - // var greenGamma = new byte[256]; - // var blueGamma = new byte[256]; - - // for (var i = 0; i < 256; ++i) - // { - // redGamma[i] = (byte)Math.Min(255, (int)((255.0 * Math.Pow(i / 255.0, 1.0 / red)) + 0.5)); - // greenGamma[i] = (byte)Math.Min(255, (int)((255.0 * Math.Pow(i / 255.0, 1.0 / green)) + 0.5)); - // blueGamma[i] = (byte)Math.Min(255, (int)((255.0 * Math.Pow(i / 255.0, 1.0 / blue)) + 0.5)); - // } - - // // GDI+ still lies to us - the return format is BGR, NOT RGB. - // var bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - - // var stride = bmData.Stride; - // var Scan0 = bmData.Scan0; - - // unsafe - // { - // var p = (byte*)(void*)Scan0; - - // var nOffset = stride - b.Width * 3; - - // for (var y = 0; y < b.Height; ++y) - // { - // for (var x = 0; x < b.Width; ++x) - // { - // p[2] = redGamma[p[2]]; - // p[1] = greenGamma[p[1]]; - // p[0] = blueGamma[p[0]]; - - // p += 3; - // } - // p += nOffset; - // } - // } - - // b.UnlockBits(bmData); - - // return true; - // } - - // public static bool Color(Bitmap b, int red, int green, int blue) - // { - // if (red < -255 || red > 255) return false; - // if (green < -255 || green > 255) return false; - // if (blue < -255 || blue > 255) return false; - - // // GDI+ still lies to us - the return format is BGR, NOT RGB. - // var bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - - // var stride = bmData.Stride; - // var Scan0 = bmData.Scan0; - - // unsafe - // { - // var p = (byte*)(void*)Scan0; - - // var nOffset = stride - b.Width * 3; - // int nPixel; - - // for (var y = 0; y < b.Height; ++y) - // { - // for (var x = 0; x < b.Width; ++x) - // { - // nPixel = p[2] + red; - // nPixel = Math.Max(nPixel, 0); - // p[2] = (byte)Math.Min(255, nPixel); - - // nPixel = p[1] + green; - // nPixel = Math.Max(nPixel, 0); - // p[1] = (byte)Math.Min(255, nPixel); - - // nPixel = p[0] + blue; - // nPixel = Math.Max(nPixel, 0); - // p[0] = (byte)Math.Min(255, nPixel); - - // p += 3; - // } - // p += nOffset; - // } - // } - - // b.UnlockBits(bmData); - - // return true; - // } - - // public static bool Conv3x3(Bitmap b, ConvMatrix m) - // { - // // Avoid divide by zero errors - // if (0 == m.Factor) return false; - - // var bSrc = (Bitmap)b.Clone(); - - // // GDI+ still lies to us - the return format is BGR, NOT RGB. - // var bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - // var bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - - // var stride = bmData.Stride; - // var stride2 = stride * 2; - // var Scan0 = bmData.Scan0; - // var SrcScan0 = bmSrc.Scan0; - - // unsafe - // { - // var p = (byte*)(void*)Scan0; - // var pSrc = (byte*)(void*)SrcScan0; - - // var nOffset = stride - b.Width * 3; - // var nWidth = b.Width - 2; - // var nHeight = b.Height - 2; - - // int nPixel; - - // for (var y = 0; y < nHeight; ++y) - // { - // for (var x = 0; x < nWidth; ++x) - // { - // nPixel = ((((pSrc[2] * m.TopLeft) + (pSrc[5] * m.TopMid) + (pSrc[8] * m.TopRight) + - // (pSrc[2 + stride] * m.MidLeft) + (pSrc[5 + stride] * m.Pixel) + (pSrc[8 + stride] * m.MidRight) + - // (pSrc[2 + stride2] * m.BottomLeft) + (pSrc[5 + stride2] * m.BottomMid) + (pSrc[8 + stride2] * m.BottomRight)) / m.Factor) + m.Offset); - - // if (nPixel < 0) nPixel = 0; - // if (nPixel > 255) nPixel = 255; - - // p[5 + stride] = (byte)nPixel; - - // nPixel = ((((pSrc[1] * m.TopLeft) + (pSrc[4] * m.TopMid) + (pSrc[7] * m.TopRight) + - // (pSrc[1 + stride] * m.MidLeft) + (pSrc[4 + stride] * m.Pixel) + (pSrc[7 + stride] * m.MidRight) + - // (pSrc[1 + stride2] * m.BottomLeft) + (pSrc[4 + stride2] * m.BottomMid) + (pSrc[7 + stride2] * m.BottomRight)) / m.Factor) + m.Offset); - - // if (nPixel < 0) nPixel = 0; - // if (nPixel > 255) nPixel = 255; - - // p[4 + stride] = (byte)nPixel; - - // nPixel = ((((pSrc[0] * m.TopLeft) + (pSrc[3] * m.TopMid) + (pSrc[6] * m.TopRight) + - // (pSrc[0 + stride] * m.MidLeft) + (pSrc[3 + stride] * m.Pixel) + (pSrc[6 + stride] * m.MidRight) + - // (pSrc[0 + stride2] * m.BottomLeft) + (pSrc[3 + stride2] * m.BottomMid) + (pSrc[6 + stride2] * m.BottomRight)) / m.Factor) + m.Offset); - - // if (nPixel < 0) nPixel = 0; - // if (nPixel > 255) nPixel = 255; - - // p[3 + stride] = (byte)nPixel; - - // p += 3; - // pSrc += 3; - // } - // p += nOffset; - // pSrc += nOffset; - // } - // } - - // b.UnlockBits(bmData); - // bSrc.UnlockBits(bmSrc); - - // return true; - // } - - // public static bool Smooth(Bitmap b, int nWeight /* default to 1 */) - // { - // var m = new ConvMatrix(); - // m.SetAll(1); - // m.Pixel = nWeight; - // m.Factor = nWeight + 8; - - // return Conv3x3(b, m); - // } - - // public static bool GaussianBlur(Bitmap b, int nWeight /* default to 4*/) - // { - // var m = new ConvMatrix(); - // m.SetAll(1); - // m.Pixel = nWeight; - // m.TopMid = m.MidLeft = m.MidRight = m.BottomMid = 2; - // m.Factor = nWeight + 12; - - // return Conv3x3(b, m); - // } - // public static bool MeanRemoval(Bitmap b, int nWeight /* default to 9*/ ) - // { - // var m = new ConvMatrix(); - // m.SetAll(-1); - // m.Pixel = nWeight; - // m.Factor = nWeight - 8; - - // return Conv3x3(b, m); - // } - // public static bool Sharpen(Bitmap b, int nWeight /* default to 11*/ ) - // { - // var m = new ConvMatrix(); - // m.SetAll(0); - // m.Pixel = nWeight; - // m.TopMid = m.MidLeft = m.MidRight = m.BottomMid = -2; - // m.Factor = nWeight - 8; - - // return Conv3x3(b, m); - // } - // public static bool EmbossLaplacian(Bitmap b) - // { - // var m = new ConvMatrix(); - // m.SetAll(-1); - // m.TopMid = m.MidLeft = m.MidRight = m.BottomMid = 0; - // m.Pixel = 4; - // m.Offset = 127; - - // return Conv3x3(b, m); - // } - // public static bool EdgeDetectQuick(Bitmap b) - // { - // var m = new ConvMatrix(); - // m.TopLeft = m.TopMid = m.TopRight = -1; - // m.MidLeft = m.Pixel = m.MidRight = 0; - // m.BottomLeft = m.BottomMid = m.BottomRight = 1; - - // m.Offset = 127; - - // return Conv3x3(b, m); - // } - - // public static bool EdgeDetectConvolution(Bitmap b, short nType, byte nThreshold) - // { - // var m = new ConvMatrix(); - - // // I need to make a copy of this bitmap BEFORE I alter it 80) - // var bTemp = (Bitmap)b.Clone(); - - // switch (nType) - // { - // case EDGE_DETECT_SOBEL: - // m.SetAll(0); - // m.TopLeft = m.BottomLeft = 1; - // m.TopRight = m.BottomRight = -1; - // m.MidLeft = 2; - // m.MidRight = -2; - // m.Offset = 0; - // break; - // case EDGE_DETECT_PREWITT: - // m.SetAll(0); - // m.TopLeft = m.MidLeft = m.BottomLeft = -1; - // m.TopRight = m.MidRight = m.BottomRight = 1; - // m.Offset = 0; - // break; - // case EDGE_DETECT_KIRSH: - // m.SetAll(-3); - // m.Pixel = 0; - // m.TopLeft = m.MidLeft = m.BottomLeft = 5; - // m.Offset = 0; - // break; - // } - - // Conv3x3(b, m); - - // switch (nType) - // { - // case EDGE_DETECT_SOBEL: - // m.SetAll(0); - // m.TopLeft = m.TopRight = 1; - // m.BottomLeft = m.BottomRight = -1; - // m.TopMid = 2; - // m.BottomMid = -2; - // m.Offset = 0; - // break; - // case EDGE_DETECT_PREWITT: - // m.SetAll(0); - // m.BottomLeft = m.BottomMid = m.BottomRight = -1; - // m.TopLeft = m.TopMid = m.TopRight = 1; - // m.Offset = 0; - // break; - // case EDGE_DETECT_KIRSH: - // m.SetAll(-3); - // m.Pixel = 0; - // m.BottomLeft = m.BottomMid = m.BottomRight = 5; - // m.Offset = 0; - // break; - // } - - // Conv3x3(bTemp, m); - - // // GDI+ still lies to us - the return format is BGR, NOT RGB. - // var bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - // var bmData2 = bTemp.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - - // var stride = bmData.Stride; - // var Scan0 = bmData.Scan0; - // var Scan02 = bmData2.Scan0; - - // unsafe - // { - // var p = (byte*)(void*)Scan0; - // var p2 = (byte*)(void*)Scan02; - - // var nOffset = stride - b.Width * 3; - // var nWidth = b.Width * 3; - - // var nPixel = 0; - - // for (var y = 0; y < b.Height; ++y) - // { - // for (var x = 0; x < nWidth; ++x) - // { - // nPixel = (int)Math.Sqrt((p[0] * p[0]) + (p2[0] * p2[0])); - // if (nPixel < nThreshold) nPixel = nThreshold; - // if (nPixel > 255) nPixel = 255; - // p[0] = (byte)nPixel; - // ++p; - // ++p2; - // } - // p += nOffset; - // p2 += nOffset; - // } - // } - - // b.UnlockBits(bmData); - // bTemp.UnlockBits(bmData2); - - // return true; - // } - - // public static bool EdgeDetectHorizontal(Bitmap b) - // { - // var bmTemp = (Bitmap)b.Clone(); - - // // GDI+ still lies to us - the return format is BGR, NOT RGB. - // var bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - // var bmData2 = bmTemp.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - - // var stride = bmData.Stride; - // var Scan0 = bmData.Scan0; - // var Scan02 = bmData2.Scan0; - - // unsafe - // { - // var p = (byte*)(void*)Scan0; - // var p2 = (byte*)(void*)Scan02; - - // var nOffset = stride - b.Width * 3; - // var nWidth = b.Width * 3; - - // var nPixel = 0; - - // p += stride; - // p2 += stride; - - // for (var y = 1; y < b.Height - 1; ++y) - // { - // p += 9; - // p2 += 9; - - // for (var x = 9; x < nWidth - 9; ++x) - // { - // nPixel = ((p2 + stride - 9)[0] + - // (p2 + stride - 6)[0] + - // (p2 + stride - 3)[0] + - // (p2 + stride)[0] + - // (p2 + stride + 3)[0] + - // (p2 + stride + 6)[0] + - // (p2 + stride + 9)[0] - - // (p2 - stride - 9)[0] - - // (p2 - stride - 6)[0] - - // (p2 - stride - 3)[0] - - // (p2 - stride)[0] - - // (p2 - stride + 3)[0] - - // (p2 - stride + 6)[0] - - // (p2 - stride + 9)[0]); - - // if (nPixel < 0) nPixel = 0; - // if (nPixel > 255) nPixel = 255; - - // (p + stride)[0] = (byte)nPixel; - - // ++p; - // ++p2; - // } - - // p += 9 + nOffset; - // p2 += 9 + nOffset; - // } - // } - - // b.UnlockBits(bmData); - // bmTemp.UnlockBits(bmData2); - - // return true; - // } - - // public static bool EdgeDetectVertical(Bitmap b) - // { - // var bmTemp = (Bitmap)b.Clone(); - - // // GDI+ still lies to us - the return format is BGR, NOT RGB. - // var bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - // var bmData2 = bmTemp.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - - // var stride = bmData.Stride; - // var Scan0 = bmData.Scan0; - // var Scan02 = bmData2.Scan0; - - // unsafe - // { - // var p = (byte*)(void*)Scan0; - // var p2 = (byte*)(void*)Scan02; - - // var nOffset = stride - b.Width * 3; - // var nWidth = b.Width * 3; - - // var nPixel = 0; - - // var nStride2 = stride * 2; - // var nStride3 = stride * 3; - - // p += nStride3; - // p2 += nStride3; - - // for (var y = 3; y < b.Height - 3; ++y) - // { - // p += 3; - // p2 += 3; - - // for (var x = 3; x < nWidth - 3; ++x) - // { - // nPixel = ((p2 + nStride3 + 3)[0] + - // (p2 + nStride2 + 3)[0] + - // (p2 + stride + 3)[0] + - // (p2 + 3)[0] + - // (p2 - stride + 3)[0] + - // (p2 - nStride2 + 3)[0] + - // (p2 - nStride3 + 3)[0] - - // (p2 + nStride3 - 3)[0] - - // (p2 + nStride2 - 3)[0] - - // (p2 + stride - 3)[0] - - // (p2 - 3)[0] - - // (p2 - stride - 3)[0] - - // (p2 - nStride2 - 3)[0] - - // (p2 - nStride3 - 3)[0]); - - // if (nPixel < 0) nPixel = 0; - // if (nPixel > 255) nPixel = 255; - - // p[0] = (byte)nPixel; - - // ++p; - // ++p2; - // } - - // p += 3 + nOffset; - // p2 += 3 + nOffset; - // } - // } - - // b.UnlockBits(bmData); - // bmTemp.UnlockBits(bmData2); - - // return true; - // } - - // public static bool EdgeDetectHomogenity(Bitmap b, byte nThreshold) - // { - // // This one works by working out the greatest difference between a pixel and it's eight neighbours. - // // The threshold allows softer edges to be forced down to black, use 0 to negate it's effect. - // var b2 = (Bitmap)b.Clone(); - - // // GDI+ still lies to us - the return format is BGR, NOT RGB. - // var bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - // var bmData2 = b2.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - - // var stride = bmData.Stride; - // var Scan0 = bmData.Scan0; - // var Scan02 = bmData2.Scan0; - - // unsafe - // { - // var p = (byte*)(void*)Scan0; - // var p2 = (byte*)(void*)Scan02; - - // var nOffset = stride - b.Width * 3; - // var nWidth = b.Width * 3; - - // int nPixel = 0, nPixelMax = 0; - - // p += stride; - // p2 += stride; - - // for (var y = 1; y < b.Height - 1; ++y) - // { - // p += 3; - // p2 += 3; - - // for (var x = 3; x < nWidth - 3; ++x) - // { - // nPixelMax = Math.Abs(p2[0] - (p2 + stride - 3)[0]); - // nPixel = Math.Abs(p2[0] - (p2 + stride)[0]); - // if (nPixel > nPixelMax) nPixelMax = nPixel; - - // nPixel = Math.Abs(p2[0] - (p2 + stride + 3)[0]); - // if (nPixel > nPixelMax) nPixelMax = nPixel; - - // nPixel = Math.Abs(p2[0] - (p2 - stride)[0]); - // if (nPixel > nPixelMax) nPixelMax = nPixel; - - // nPixel = Math.Abs(p2[0] - (p2 + stride)[0]); - // if (nPixel > nPixelMax) nPixelMax = nPixel; - - // nPixel = Math.Abs(p2[0] - (p2 - stride - 3)[0]); - // if (nPixel > nPixelMax) nPixelMax = nPixel; - - // nPixel = Math.Abs(p2[0] - (p2 - stride)[0]); - // if (nPixel > nPixelMax) nPixelMax = nPixel; - - // nPixel = Math.Abs(p2[0] - (p2 - stride + 3)[0]); - // if (nPixel > nPixelMax) nPixelMax = nPixel; - - // if (nPixelMax < nThreshold) nPixelMax = 0; - - // p[0] = (byte)nPixelMax; - - // ++p; - // ++p2; - // } - - // p += 3 + nOffset; - // p2 += 3 + nOffset; - // } - // } - - // b.UnlockBits(bmData); - // b2.UnlockBits(bmData2); - - // return true; - - // } - // public static bool EdgeDetectDifference(Bitmap b, byte nThreshold) - // { - // // This one works by working out the greatest difference between a pixel and it's eight neighbours. - // // The threshold allows softer edges to be forced down to black, use 0 to negate it's effect. - // var b2 = (Bitmap)b.Clone(); - - // // GDI+ still lies to us - the return format is BGR, NOT RGB. - // var bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - // var bmData2 = b2.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - - // var stride = bmData.Stride; - // var Scan0 = bmData.Scan0; - // var Scan02 = bmData2.Scan0; - - // unsafe - // { - // var p = (byte*)(void*)Scan0; - // var p2 = (byte*)(void*)Scan02; - - // var nOffset = stride - b.Width * 3; - // var nWidth = b.Width * 3; - - // int nPixel = 0, nPixelMax = 0; - - // p += stride; - // p2 += stride; - - // for (var y = 1; y < b.Height - 1; ++y) - // { - // p += 3; - // p2 += 3; - - // for (var x = 3; x < nWidth - 3; ++x) - // { - // nPixelMax = Math.Abs((p2 - stride + 3)[0] - (p2 + stride - 3)[0]); - // nPixel = Math.Abs((p2 + stride + 3)[0] - (p2 - stride - 3)[0]); - // if (nPixel > nPixelMax) nPixelMax = nPixel; - - // nPixel = Math.Abs((p2 - stride)[0] - (p2 + stride)[0]); - // if (nPixel > nPixelMax) nPixelMax = nPixel; - - // nPixel = Math.Abs((p2 + 3)[0] - (p2 - 3)[0]); - // if (nPixel > nPixelMax) nPixelMax = nPixel; - - // if (nPixelMax < nThreshold) nPixelMax = 0; - - // p[0] = (byte)nPixelMax; - - // ++p; - // ++p2; - // } - - // p += 3 + nOffset; - // p2 += 3 + nOffset; - // } - // } - - // b.UnlockBits(bmData); - // b2.UnlockBits(bmData2); - - // return true; - - // } - - // public static bool EdgeEnhance(Bitmap b, byte nThreshold) - // { - // // This one works by working out the greatest difference between a nPixel and it's eight neighbours. - // // The threshold allows softer edges to be forced down to black, use 0 to negate it's effect. - // var b2 = (Bitmap)b.Clone(); - - // // GDI+ still lies to us - the return format is BGR, NOT RGB. - // var bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - // var bmData2 = b2.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - - // var stride = bmData.Stride; - // var Scan0 = bmData.Scan0; - // var Scan02 = bmData2.Scan0; - - // unsafe - // { - // var p = (byte*)(void*)Scan0; - // var p2 = (byte*)(void*)Scan02; - - // var nOffset = stride - b.Width * 3; - // var nWidth = b.Width * 3; - - // int nPixel = 0, nPixelMax = 0; - - // p += stride; - // p2 += stride; - - // for (var y = 1; y < b.Height - 1; ++y) - // { - // p += 3; - // p2 += 3; - - // for (var x = 3; x < nWidth - 3; ++x) - // { - // nPixelMax = Math.Abs((p2 - stride + 3)[0] - (p2 + stride - 3)[0]); - - // nPixel = Math.Abs((p2 + stride + 3)[0] - (p2 - stride - 3)[0]); - - // if (nPixel > nPixelMax) nPixelMax = nPixel; - - // nPixel = Math.Abs((p2 - stride)[0] - (p2 + stride)[0]); - - // if (nPixel > nPixelMax) nPixelMax = nPixel; - - // nPixel = Math.Abs((p2 + 3)[0] - (p2 - 3)[0]); - - // if (nPixel > nPixelMax) nPixelMax = nPixel; - - // if (nPixelMax > nThreshold && nPixelMax > p[0]) - // p[0] = (byte)Math.Max(p[0], nPixelMax); - - // ++p; - // ++p2; - // } - - // p += nOffset + 3; - // p2 += nOffset + 3; - // } - // } - - // b.UnlockBits(bmData); - // b2.UnlockBits(bmData2); - - // return true; - // } - // public static Bitmap Resize(Bitmap b, int nWidth, int nHeight, bool bBilinear) - // { - // var bTemp = (Bitmap)b.Clone(); - // b = new Bitmap(nWidth, nHeight, bTemp.PixelFormat); - - // var nXFactor = (double)bTemp.Width / (double)nWidth; - // var nYFactor = (double)bTemp.Height / (double)nHeight; - - // if (bBilinear) - // { - // double fraction_x, fraction_y, one_minus_x, one_minus_y; - // int ceil_x, ceil_y, floor_x, floor_y; - // var c1 = new Color(); - // var c2 = new Color(); - // var c3 = new Color(); - // var c4 = new Color(); - // byte red, green, blue; - - // byte b1, b2; - - // for (var x = 0; x < b.Width; ++x) - // for (var y = 0; y < b.Height; ++y) - // { - // // Setup - - // floor_x = (int)Math.Floor(x * nXFactor); - // floor_y = (int)Math.Floor(y * nYFactor); - // ceil_x = floor_x + 1; - // if (ceil_x >= bTemp.Width) ceil_x = floor_x; - // ceil_y = floor_y + 1; - // if (ceil_y >= bTemp.Height) ceil_y = floor_y; - // fraction_x = x * nXFactor - floor_x; - // fraction_y = y * nYFactor - floor_y; - // one_minus_x = 1.0 - fraction_x; - // one_minus_y = 1.0 - fraction_y; - - // c1 = bTemp.GetPixel(floor_x, floor_y); - // c2 = bTemp.GetPixel(ceil_x, floor_y); - // c3 = bTemp.GetPixel(floor_x, ceil_y); - // c4 = bTemp.GetPixel(ceil_x, ceil_y); - - // // Blue - // b1 = (byte)(one_minus_x * c1.B + fraction_x * c2.B); - - // b2 = (byte)(one_minus_x * c3.B + fraction_x * c4.B); - - // blue = (byte)(one_minus_y * (double)(b1) + fraction_y * (double)(b2)); - - // // Green - // b1 = (byte)(one_minus_x * c1.G + fraction_x * c2.G); - - // b2 = (byte)(one_minus_x * c3.G + fraction_x * c4.G); - - // green = (byte)(one_minus_y * (double)(b1) + fraction_y * (double)(b2)); - - // // Red - // b1 = (byte)(one_minus_x * c1.R + fraction_x * c2.R); - - // b2 = (byte)(one_minus_x * c3.R + fraction_x * c4.R); - - // red = (byte)(one_minus_y * (double)(b1) + fraction_y * (double)(b2)); - - // b.SetPixel(x, y, System.Drawing.Color.FromArgb(255, red, green, blue)); - // } - // } - // else - // { - // for (var x = 0; x < b.Width; ++x) - // for (var y = 0; y < b.Height; ++y) - // b.SetPixel(x, y, bTemp.GetPixel((int)(Math.Floor(x * nXFactor)), (int)(Math.Floor(y * nYFactor)))); - // } - - // return b; - // } - - // public static bool OffsetFilterAbs(Bitmap b, Point[,] offset) - // { - // var bSrc = (Bitmap)b.Clone(); - - // // GDI+ still lies to us - the return format is BGR, NOT RGB. - // var bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - // var bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - - // var scanline = bmData.Stride; - - // var Scan0 = bmData.Scan0; - // var SrcScan0 = bmSrc.Scan0; - - // unsafe - // { - // var p = (byte*)(void*)Scan0; - // var pSrc = (byte*)(void*)SrcScan0; - - // var nOffset = bmData.Stride - b.Width * 3; - // var nWidth = b.Width; - // var nHeight = b.Height; - - // int xOffset, yOffset; - - // for (var y = 0; y < nHeight; ++y) - // { - // for (var x = 0; x < nWidth; ++x) - // { - // xOffset = offset[x, y].X; - // yOffset = offset[x, y].Y; - - // if (yOffset >= 0 && yOffset < nHeight && xOffset >= 0 && xOffset < nWidth) - // { - // p[0] = pSrc[(yOffset * scanline) + (xOffset * 3)]; - // p[1] = pSrc[(yOffset * scanline) + (xOffset * 3) + 1]; - // p[2] = pSrc[(yOffset * scanline) + (xOffset * 3) + 2]; - // } - - // p += 3; - // } - // p += nOffset; - // } - // } - - // b.UnlockBits(bmData); - // bSrc.UnlockBits(bmSrc); - - // return true; - // } - - // public static bool OffsetFilter(Bitmap b, Point[,] offset) - // { - // var bSrc = (Bitmap)b.Clone(); - - // // GDI+ still lies to us - the return format is BGR, NOT RGB. - // var bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - // var bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - - // var scanline = bmData.Stride; - - // var Scan0 = bmData.Scan0; - // var SrcScan0 = bmSrc.Scan0; - - // unsafe - // { - // var p = (byte*)(void*)Scan0; - // var pSrc = (byte*)(void*)SrcScan0; - - // var nOffset = bmData.Stride - b.Width * 3; - // var nWidth = b.Width; - // var nHeight = b.Height; - - // int xOffset, yOffset; - - // for (var y = 0; y < nHeight; ++y) - // { - // for (var x = 0; x < nWidth; ++x) - // { - // xOffset = offset[x, y].X; - // yOffset = offset[x, y].Y; - - // if (y + yOffset >= 0 && y + yOffset < nHeight && x + xOffset >= 0 && x + xOffset < nWidth) - // { - // p[0] = pSrc[((y + yOffset) * scanline) + ((x + xOffset) * 3)]; - // p[1] = pSrc[((y + yOffset) * scanline) + ((x + xOffset) * 3) + 1]; - // p[2] = pSrc[((y + yOffset) * scanline) + ((x + xOffset) * 3) + 2]; - // } - - // p += 3; - // } - // p += nOffset; - // } - // } - - // b.UnlockBits(bmData); - // bSrc.UnlockBits(bmSrc); - - // return true; - // } - - // public static bool OffsetFilterAntiAlias(Bitmap b, FloatPoint[,] fp) - // { - // var bSrc = (Bitmap)b.Clone(); - - // // GDI+ still lies to us - the return format is BGR, NOT RGB. - // var bmData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - // var bmSrc = bSrc.LockBits(new Rectangle(0, 0, bSrc.Width, bSrc.Height), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); - - // var scanline = bmData.Stride; - - // var Scan0 = bmData.Scan0; - // var SrcScan0 = bmSrc.Scan0; - - // unsafe - // { - // var p = (byte*)(void*)Scan0; - // var pSrc = (byte*)(void*)SrcScan0; - - // var nOffset = bmData.Stride - b.Width * 3; - // var nWidth = b.Width; - // var nHeight = b.Height; - - // double xOffset, yOffset; - - // double fraction_x, fraction_y, one_minus_x, one_minus_y; - // int ceil_x, ceil_y, floor_x, floor_y; - // Byte p1, p2; - - // for (var y = 0; y < nHeight; ++y) - // { - // for (var x = 0; x < nWidth; ++x) - // { - // xOffset = fp[x, y].X; - // yOffset = fp[x, y].Y; - - // // Setup - - // floor_x = (int)Math.Floor(xOffset); - // floor_y = (int)Math.Floor(yOffset); - // ceil_x = floor_x + 1; - // ceil_y = floor_y + 1; - // fraction_x = xOffset - floor_x; - // fraction_y = yOffset - floor_y; - // one_minus_x = 1.0 - fraction_x; - // one_minus_y = 1.0 - fraction_y; - - // if (floor_y >= 0 && ceil_y < nHeight && floor_x >= 0 && ceil_x < nWidth) - // { - // // Blue - - // p1 = (Byte)(one_minus_x * (double)(pSrc[floor_y * scanline + floor_x * 3]) + - // fraction_x * (double)(pSrc[floor_y * scanline + ceil_x * 3])); - - // p2 = (Byte)(one_minus_x * (double)(pSrc[ceil_y * scanline + floor_x * 3]) + - // fraction_x * (double)(pSrc[ceil_y * scanline + 3 * ceil_x])); - - // p[x * 3 + y * scanline] = (Byte)(one_minus_y * (double)(p1) + fraction_y * (double)(p2)); - - // // Green - - // p1 = (Byte)(one_minus_x * (double)(pSrc[floor_y * scanline + floor_x * 3 + 1]) + - // fraction_x * (double)(pSrc[floor_y * scanline + ceil_x * 3 + 1])); - - // p2 = (Byte)(one_minus_x * (double)(pSrc[ceil_y * scanline + floor_x * 3 + 1]) + - // fraction_x * (double)(pSrc[ceil_y * scanline + 3 * ceil_x + 1])); - - // p[x * 3 + y * scanline + 1] = (Byte)(one_minus_y * (double)(p1) + fraction_y * (double)(p2)); - - // // Red - - // p1 = (Byte)(one_minus_x * (double)(pSrc[floor_y * scanline + floor_x * 3 + 2]) + - // fraction_x * (double)(pSrc[floor_y * scanline + ceil_x * 3 + 2])); - - // p2 = (Byte)(one_minus_x * (double)(pSrc[ceil_y * scanline + floor_x * 3 + 2]) + - // fraction_x * (double)(pSrc[ceil_y * scanline + 3 * ceil_x + 2])); - - // p[x * 3 + y * scanline + 2] = (Byte)(one_minus_y * (double)(p1) + fraction_y * (double)(p2)); - // } - // } - // } - // } - - // b.UnlockBits(bmData); - // bSrc.UnlockBits(bmSrc); - - // return true; - // } - - // public static Bitmap Flip(Bitmap b, bool bHorz, bool bVert) - // { - // var ptFlip = new Point[b.Width, b.Height]; - - // var nWidth = b.Width; - // var nHeight = b.Height; - - // for (var x = 0; x < nWidth; ++x) - // for (var y = 0; y < nHeight; ++y) - // { - // ptFlip[x, y].X = (bHorz) ? nWidth - (x + 1) : x; - // ptFlip[x, y].Y = (bVert) ? nHeight - (y + 1) : y; - // } - - // OffsetFilterAbs(b, ptFlip); - - // return b; - // } - - // public static Bitmap RotateLeftAndFlipVert(Bitmap b) - // { - // var bTemp = (Bitmap)b.Clone(); - // b = new Bitmap(bTemp.Height, bTemp.Width, bTemp.PixelFormat); - - // for (var x = 0; x < b.Width; ++x) - // for (var y = 0; y < b.Height; ++y) - // b.SetPixel(x, y, bTemp.GetPixel(y, x)); - - // return b; - // } - - // public static Bitmap RotateLeft(Bitmap b) - // { - // b = RotateLeftAndFlipVert(b); - // Flip(b, false, true); - // return b; - // } - - // public static Bitmap RotateRight(Bitmap b) - // { - // b = RotateLeftAndFlipVert(b); - // Flip(b, true, false); - // return b; - // } - - // public static Bitmap RotateLeftAndFlipHorz(Bitmap b) - // { - // b = RotateLeft(b); - // Flip(b, true, false); - // return b; - // } - - // public static bool RandomJitter(Bitmap b, short nDegree) - // { - // var ptRandJitter = new Point[b.Width, b.Height]; - - // var nWidth = b.Width; - // var nHeight = b.Height; - - // int newX, newY; - - // var nHalf = (short)Math.Floor(Convert.ToDouble(nDegree / 2)); - // var rnd = new Random(); - - // for (var x = 0; x < nWidth; ++x) - // for (var y = 0; y < nHeight; ++y) - // { - // newX = rnd.Next(nDegree) - nHalf; - - // if (x + newX > 0 && x + newX < nWidth) - // ptRandJitter[x, y].X = newX; - // else - // ptRandJitter[x, y].X = 0; - - // newY = rnd.Next(nDegree) - nHalf; - - // if (y + newY > 0 && y + newY < nWidth) - // ptRandJitter[x, y].Y = newY; - // else - // ptRandJitter[x, y].Y = 0; - // } - - // OffsetFilter(b, ptRandJitter); - - // return true; - // } - // public static bool Swirl(Bitmap b, double fDegree, bool bSmoothing /* default fDegree to .05 */) - // { - // var nWidth = b.Width; - // var nHeight = b.Height; - - // var fp = new FloatPoint[nWidth, nHeight]; - // var pt = new Point[nWidth, nHeight]; - - // var mid = new Point(); - // mid.X = nWidth / 2; - // mid.Y = nHeight / 2; - - // double theta, radius; - // double newX, newY; - - // for (var x = 0; x < nWidth; ++x) - // for (var y = 0; y < nHeight; ++y) - // { - // var trueX = x - mid.X; - // var trueY = y - mid.Y; - // theta = Math.Atan2((trueY), (trueX)); - - // radius = Math.Sqrt(trueX * trueX + trueY * trueY); - - // newX = mid.X + (radius * Math.Cos(theta + fDegree * radius)); - // if (newX > 0 && newX < nWidth) - // { - // fp[x, y].X = newX; - // pt[x, y].X = (int)newX; - // } - // else - // fp[x, y].X = pt[x, y].X = x; - - // newY = mid.Y + (radius * Math.Sin(theta + fDegree * radius)); - // if (newY > 0 && newY < nHeight) - // { - // fp[x, y].Y = newY; - // pt[x, y].Y = (int)newY; - // } - // else - // fp[x, y].Y = pt[x, y].Y = y; - // } - - // if (bSmoothing) - // OffsetFilterAntiAlias(b, fp); - // else - // OffsetFilterAbs(b, pt); - - // return true; - // } - - // public static bool Sphere(Bitmap b, bool bSmoothing) - // { - // var nWidth = b.Width; - // var nHeight = b.Height; - - // var fp = new FloatPoint[nWidth, nHeight]; - // var pt = new Point[nWidth, nHeight]; - - // var mid = new Point(); - // mid.X = nWidth / 2; - // mid.Y = nHeight / 2; - - // double theta, radius; - // double newX, newY; - - // for (var x = 0; x < nWidth; ++x) - // for (var y = 0; y < nHeight; ++y) - // { - // var trueX = x - mid.X; - // var trueY = y - mid.Y; - // theta = Math.Atan2((trueY), (trueX)); - - // radius = Math.Sqrt(trueX * trueX + trueY * trueY); - - // var newRadius = radius * radius / (Math.Max(mid.X, mid.Y)); - - // newX = mid.X + (newRadius * Math.Cos(theta)); - - // if (newX > 0 && newX < nWidth) - // { - // fp[x, y].X = newX; - // pt[x, y].X = (int)newX; - // } - // else - // { - // fp[x, y].X = fp[x, y].Y = 0.0; - // pt[x, y].X = pt[x, y].Y = 0; - // } - - // newY = mid.Y + (newRadius * Math.Sin(theta)); - - // if (newY > 0 && newY < nHeight && newX > 0 && newX < nWidth) - // { - // fp[x, y].Y = newY; - // pt[x, y].Y = (int)newY; - // } - // else - // { - // fp[x, y].X = fp[x, y].Y = 0.0; - // pt[x, y].X = pt[x, y].Y = 0; - // } - // } - - // if (bSmoothing) - // OffsetFilterAbs(b, pt); - // else - // OffsetFilterAntiAlias(b, fp); - - // return true; - // } - - // public static bool TimeWarp(Bitmap b, Byte factor, bool bSmoothing) - // { - // var nWidth = b.Width; - // var nHeight = b.Height; - - // var fp = new FloatPoint[nWidth, nHeight]; - // var pt = new Point[nWidth, nHeight]; - - // var mid = new Point(); - // mid.X = nWidth / 2; - // mid.Y = nHeight / 2; - - // double theta, radius; - // double newX, newY; - - // for (var x = 0; x < nWidth; ++x) - // for (var y = 0; y < nHeight; ++y) - // { - // var trueX = x - mid.X; - // var trueY = y - mid.Y; - // theta = Math.Atan2((trueY), (trueX)); - - // radius = Math.Sqrt(trueX * trueX + trueY * trueY); - - // var newRadius = Math.Sqrt(radius) * factor; - - // newX = mid.X + (newRadius * Math.Cos(theta)); - // if (newX > 0 && newX < nWidth) - // { - // fp[x, y].X = newX; - // pt[x, y].X = (int)newX; - // } - // else - // { - // fp[x, y].X = 0.0; - // pt[x, y].X = 0; - // } - - // newY = mid.Y + (newRadius * Math.Sin(theta)); - // if (newY > 0 && newY < nHeight) - // { - // fp[x, y].Y = newY; - // pt[x, y].Y = (int)newY; - // } - // else - // { - // fp[x, y].Y = 0.0; - // pt[x, y].Y = 0; - // } - // } - - // if (bSmoothing) - // OffsetFilterAbs(b, pt); - // else - // OffsetFilterAntiAlias(b, fp); - - // return true; - // } - - // public static bool Moire(Bitmap b, double fDegree) - // { - // var nWidth = b.Width; - // var nHeight = b.Height; - - // var pt = new Point[nWidth, nHeight]; - - // var mid = new Point(); - // mid.X = nWidth / 2; - // mid.Y = nHeight / 2; - - // double theta, radius; - // int newX, newY; - - // for (var x = 0; x < nWidth; ++x) - // for (var y = 0; y < nHeight; ++y) - // { - // var trueX = x - mid.X; - // var trueY = y - mid.Y; - // theta = Math.Atan2((trueX), (trueY)); - - // radius = Math.Sqrt(trueX * trueX + trueY * trueY); - - // newX = (int)(radius * Math.Sin(theta + fDegree * radius)); - // if (newX > 0 && newX < nWidth) - // { - // pt[x, y].X = (int)newX; - // } - // else - // { - // pt[x, y].X = 0; - // } - - // newY = (int)(radius * Math.Sin(theta + fDegree * radius)); - // if (newY > 0 && newY < nHeight) - // { - // pt[x, y].Y = (int)newY; - // } - // else - // { - // pt[x, y].Y = 0; - // } - // } - - // OffsetFilterAbs(b, pt); - - // return true; - // } - - // public static bool Water(Bitmap b, short nWave, bool bSmoothing) - // { - // var nWidth = b.Width; - // var nHeight = b.Height; - - // var fp = new FloatPoint[nWidth, nHeight]; - // var pt = new Point[nWidth, nHeight]; - - // var mid = new Point(); - // mid.X = nWidth / 2; - // mid.Y = nHeight / 2; - - // double newX, newY; - // double xo, yo; - - // for (var x = 0; x < nWidth; ++x) - // for (var y = 0; y < nHeight; ++y) - // { - // xo = ((double)nWave * Math.Sin(2.0 * 3.1415 * (float)y / 128.0)); - // yo = ((double)nWave * Math.Cos(2.0 * 3.1415 * (float)x / 128.0)); - - // newX = (x + xo); - // newY = (y + yo); - - // if (newX > 0 && newX < nWidth) - // { - // fp[x, y].X = newX; - // pt[x, y].X = (int)newX; - // } - // else - // { - // fp[x, y].X = 0.0; - // pt[x, y].X = 0; - // } - - - // if (newY > 0 && newY < nHeight) - // { - // fp[x, y].Y = newY; - // pt[x, y].Y = (int)newY; - // } - // else - // { - // fp[x, y].Y = 0.0; - // pt[x, y].Y = 0; - // } - // } - - // if (bSmoothing) - // OffsetFilterAbs(b, pt); - // else - // OffsetFilterAntiAlias(b, fp); - - // return true; - // } - - // public static bool Pixelate(Bitmap b, short pixel, bool bGrid) - // { - // var nWidth = b.Width; - // var nHeight = b.Height; - - // var pt = new Point[nWidth, nHeight]; - - // int newX, newY; - - // for (var x = 0; x < nWidth; ++x) - // for (var y = 0; y < nHeight; ++y) - // { - // newX = pixel - x % pixel; - - // if (bGrid && newX == pixel) - // pt[x, y].X = -x; - // else if (x + newX > 0 && x + newX < nWidth) - // pt[x, y].X = newX; - // else - // pt[x, y].X = 0; - - // newY = pixel - y % pixel; - - // if (bGrid && newY == pixel) - // pt[x, y].Y = -y; - // else if (y + newY > 0 && y + newY < nHeight) - // pt[x, y].Y = newY; - // else - // pt[x, y].Y = 0; - // } - - // OffsetFilter(b, pt); - - // return true; - // } - //} -} diff --git a/SiteServer.Utils/Images/ConvMatrix.cs b/SiteServer.Utils/Images/ConvMatrix.cs deleted file mode 100644 index 9df596365..000000000 --- a/SiteServer.Utils/Images/ConvMatrix.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace SiteServer.Utils.Images -{ - public class ConvMatrix - { - public int TopLeft = 0, TopMid = 0, TopRight = 0; - public int MidLeft = 0, Pixel = 1, MidRight = 0; - public int BottomLeft = 0, BottomMid = 0, BottomRight = 0; - public int Factor = 1; - public int Offset = 0; - public void SetAll(int nVal) - { - TopLeft = TopMid = TopRight = MidLeft = Pixel = MidRight = BottomLeft = BottomMid = BottomRight = nVal; - } - } -} diff --git a/SiteServer.Utils/Images/FloatPoint.cs b/SiteServer.Utils/Images/FloatPoint.cs deleted file mode 100644 index 137818766..000000000 --- a/SiteServer.Utils/Images/FloatPoint.cs +++ /dev/null @@ -1,8 +0,0 @@ -namespace SiteServer.Utils.Images -{ - public struct FloatPoint - { - public double X; - public double Y; - } -} diff --git a/SiteServer.Utils/Images/ImageUtils.cs b/SiteServer.Utils/Images/ImageUtils.cs deleted file mode 100644 index 634a8628c..000000000 --- a/SiteServer.Utils/Images/ImageUtils.cs +++ /dev/null @@ -1,633 +0,0 @@ -using SiteServer.Utils.Enumerations; -using System; -using System.Drawing; -using System.Drawing.Drawing2D; -using System.Drawing.Imaging; -using System.IO; - -namespace SiteServer.Utils.Images -{ - public class ImageUtils - { - private ImageUtils() { } - - public static Bitmap GetBitmap(string imageFilePath) - { - var fs = new FileStream(imageFilePath, FileMode.Open); - var br = new BinaryReader(fs); - var bytes = br.ReadBytes((int)fs.Length); - br.Close(); - fs.Close(); - var ms = new MemoryStream(bytes); - - var bitmap = (Bitmap)Image.FromStream(ms, false); - - return bitmap; - } - - public static Image GetImage(string imageFilePath) - { - var fs = new FileStream(imageFilePath, FileMode.Open); - var br = new BinaryReader(fs); - var bytes = br.ReadBytes((int)fs.Length); - br.Close(); - fs.Close(); - var ms = new MemoryStream(bytes); - - var image = Image.FromStream(ms, false); - - return image; - } - - public static ImageFormat GetImageFormat(string imagePath) - { - var extName = PathUtils.GetExtension(imagePath).ToLower(); - switch (extName) - { - case ".bmp": - return ImageFormat.Bmp; - case ".emf": - return ImageFormat.Emf; - case ".exif": - return ImageFormat.Exif; - case ".gif": - return ImageFormat.Gif; - case ".ico": - return ImageFormat.Icon; - case ".jpg": - case ".jpeg": - return ImageFormat.Jpeg; - case ".png": - return ImageFormat.Png; - case ".tiff": - return ImageFormat.Tiff; - case ".wmf": - return ImageFormat.Wmf; - } - return ImageFormat.Png; - } - - private static PointF GetWaterMarkPointF(Image image, int waterMarkPosition, float waterMarkWidth, float waterMarkHeight, bool textMark) - { - float x; - float y; - switch(waterMarkPosition) - { - case 1: - if (textMark) - { - x = waterMarkWidth / 2; - } - else - { - x = 0; - } - y = 0; - break; - case 2 : - if (textMark) - { - x = (image.Width / 2); - } - else - { - x = (image.Width / 2) - (waterMarkWidth / 2); - } - y = 0; - break; - case 3 : - if (textMark) - { - x = image.Width - waterMarkWidth / 2; - } - else - { - x = image.Width - waterMarkWidth; - } - y = 0; - break; - case 4 : - if (textMark) - { - x = waterMarkWidth / 2; - } - else - { - x = 0; - } - y = (image.Height / 2) - (waterMarkHeight / 2); - break; - case 5 : - if (textMark) - { - x = (image.Width / 2); - } - else - { - x= (image.Width / 2) - (waterMarkWidth / 2); - } - y = (image.Height / 2) - (waterMarkHeight / 2); - break; - case 6 : - if (textMark) - { - x = image.Width - waterMarkWidth / 2; - } - else - { - x = image.Width - waterMarkWidth; - } - y = (image.Height / 2) - (waterMarkHeight / 2); - break; - case 7 : - if (textMark) - { - x = waterMarkWidth / 2; - } - else - { - x = 0; - } - y = image.Height - waterMarkHeight; - break; - case 8 : - if (textMark) - { - x = (image.Width / 2); - } - else - { - x = (image.Width / 2) - (waterMarkWidth / 2); - } - y = image.Height - waterMarkHeight; - break; - default : - - if (textMark) - { - x = image.Width - waterMarkWidth / 2; - } - else - { - x = image.Width - waterMarkWidth; - } - y = image.Height - waterMarkHeight; - break; - } - return new PointF(x, y); - } - - public static void AddTextWaterMark(string imagePath, string waterMarkText, string fontName, int fontSize, int waterMarkPosition, int waterMarkTransparency, int minWidth, int minHeight) - { - try - { - var image = GetImage(imagePath); - - if (minWidth > 0) - { - if (image.Width < minWidth) - { - image.Dispose(); - return; - } - } - if (minHeight > 0) - { - if (image.Height < minHeight) - { - image.Dispose(); - return; - } - } - - var b = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb); - var picture = Graphics.FromImage(b); - picture.Clear(Color.White); - picture.SmoothingMode = SmoothingMode.Default; - picture.InterpolationMode = InterpolationMode.Default; - - picture.DrawImage(image, 0, 0, image.Width, image.Height); - - var sizes = new[] { fontSize, 16, 14, 12, 10, 8, 6, 4 }; - Font crFont = null; - var crSize = new SizeF(); - for (var i = 0; i < 8; i++) - { - crFont = new Font(fontName, sizes[i], FontStyle.Bold); - crSize = picture.MeasureString(waterMarkText, crFont); - - if ((ushort)crSize.Width < (ushort)image.Width && (ushort)crSize.Height < (ushort)image.Height) break; - } - - if (image.Width <= Convert.ToInt32(crSize.Width) || image.Height <= Convert.ToInt32(crSize.Height)) return; - var pointF = GetWaterMarkPointF(image, waterMarkPosition, crSize.Width, crSize.Height,true); - - if (pointF.X < 0 || pointF.X >= image.Width || pointF.Y < 0 || pointF.Y >= image.Height) return; - - var strFormat = new StringFormat {Alignment = StringAlignment.Center}; - - var alphaRate = (255 * waterMarkTransparency) / 10; - if (alphaRate <= 0 || alphaRate > 255) alphaRate = 153; - - var semiTransBrush2 = new SolidBrush(Color.FromArgb(alphaRate, 0, 0, 0)); - picture.DrawString(waterMarkText, crFont, semiTransBrush2, pointF.X + 1, pointF.Y + 1, strFormat); - - var semiTransBrush = new SolidBrush(Color.FromArgb(alphaRate, 255, 255, 255)); - // - picture.DrawString(waterMarkText, crFont, semiTransBrush, pointF.X, pointF.Y, strFormat); - - semiTransBrush2.Dispose(); - semiTransBrush.Dispose(); - - var fileType = EFileSystemTypeUtils.GetEnumType(PathUtils.GetExtension(imagePath)); - var imageFormat = ImageFormat.Jpeg; - if (fileType == EFileSystemType.Bmp) - { - imageFormat = ImageFormat.Bmp; - } - else if (fileType == EFileSystemType.Gif) - { - imageFormat = ImageFormat.Gif; - } - else if (fileType == EFileSystemType.Png) - { - imageFormat = ImageFormat.Png; - } - - b.Save(imagePath, imageFormat); - b.Dispose(); - image.Dispose(); - - } - catch - { - // ignored - } - } - - public static void AddImageWaterMark(string imagePath, string waterMarkImagePath, int waterMarkPosition, int waterMarkTransparency, int minWidth, int minHeight) - { - try - { - var image = GetImage(imagePath); - - if (minWidth > 0) - { - if (image.Width < minWidth) - { - image.Dispose(); - return; - } - } - if (minHeight > 0) - { - if (image.Height < minHeight) - { - image.Dispose(); - return; - } - } - - var b = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb); - var picture = Graphics.FromImage(b); - picture.Clear(Color.White); - picture.SmoothingMode = SmoothingMode.Default; - picture.InterpolationMode = InterpolationMode.Default; - - picture.DrawImage(image, 0, 0, image.Width, image.Height); - - var waterMark = GetImage(waterMarkImagePath); - - if (image.Width <= waterMark.Width || image.Height <= waterMark.Height) return; - var pointF = GetWaterMarkPointF(image, waterMarkPosition, waterMark.Width, waterMark.Height, false); - var xpos = Convert.ToInt32(pointF.X); - var ypos = Convert.ToInt32(pointF.Y); - - if (xpos < 0 || xpos >= image.Width || ypos < 0 || ypos >= image.Height) return; - - var alphaRate = (255 * waterMarkTransparency) / 10; - if (alphaRate <= 0 || alphaRate > 255) alphaRate = 153; - - var bmWaterMark = new Bitmap(waterMark); - for (var ix = 0; ix < waterMark.Width; ix++) - { - for (var iy = 0; iy < waterMark.Height; iy++) - { - int ir = bmWaterMark.GetPixel(ix, iy).R; - int ig = bmWaterMark.GetPixel(ix, iy).G; - int ib = bmWaterMark.GetPixel(ix, iy).B; - - if (!(ir == 0 && ig == 0 && ib == 0)) - { - picture.DrawEllipse(new Pen(new SolidBrush(Color.FromArgb(alphaRate, ir, ig, ib))), xpos + ix, ypos + iy, 1, 1); - } - } - } - - waterMark.Dispose(); - - b.Save(imagePath); - b.Dispose(); - image.Dispose(); - - } - catch - { - // ignored - } - } - - public static bool MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, bool isLessSizeNotThumb, out Size originalSize) - { - originalSize = new Size(); - - if (width == 0 && height == 0) - { - FileUtils.CopyFile(originalImagePath, thumbnailPath); - return true; - } - DirectoryUtils.CreateDirectoryIfNotExists(thumbnailPath); - if (!FileUtils.IsFileExists(originalImagePath)) return false; - - var originalImage = Image.FromFile(originalImagePath); - originalSize = originalImage.Size; - - if (width == 0) - { - if (isLessSizeNotThumb && originalImage.Height < height) - { - FileUtils.CopyFile(originalImagePath, thumbnailPath); - return true; - } - return MakeThumbnail(originalImage, originalImagePath, thumbnailPath, width, height, "H"); - } - if (height == 0) - { - if (isLessSizeNotThumb && originalImage.Width < width) - { - FileUtils.CopyFile(originalImagePath, thumbnailPath); - return true; - } - return MakeThumbnail(originalImage, originalImagePath, thumbnailPath, width, height, "W"); - } - if (isLessSizeNotThumb && originalImage.Height < height && originalImage.Width < width) - { - FileUtils.CopyFile(originalImagePath, thumbnailPath); - return true; - } - return MakeThumbnail(originalImage, originalImagePath, thumbnailPath, width, height, "HW"); - } - - public static bool MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, bool isLessSizeNotThumb) - { - Size originalSize; - return MakeThumbnail(originalImagePath, thumbnailPath, width, height, isLessSizeNotThumb, out originalSize); - } - - private static bool MakeThumbnail(Image originalImage, string originalImagePath, string thumbnailPath, int width, int height, string mode) - { - var created = false; - - if (FileUtils.IsFileExists(originalImagePath)) - { - var towidth = width; - var toheight = height; - var x = 0; - var y = 0; - var ow = originalImage.Width; - var oh = originalImage.Height; - switch (mode) - { - case "HW": - break; - case "W": - toheight = originalImage.Height * width / originalImage.Width; - break; - case "H": - towidth = originalImage.Width * height / originalImage.Height; - break; - case "Cut": - if ((double)originalImage.Width / originalImage.Height > towidth / (double)toheight) - { - oh = originalImage.Height; - ow = originalImage.Height * towidth / toheight; - y = 0; - x = (originalImage.Width - ow) / 2; - } - else - { - ow = originalImage.Width; - oh = originalImage.Width * height / towidth; - x = 0; - y = (originalImage.Height - oh) / 2; - } - break; - } - Image bitmap = new Bitmap(towidth, toheight); - var g = Graphics.FromImage(bitmap); - g.InterpolationMode = InterpolationMode.Default; - g.SmoothingMode = SmoothingMode.Default; - g.Clear(Color.Transparent); - g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight), - new Rectangle(x, y, ow, oh), GraphicsUnit.Pixel); - try - { - bitmap.Save(thumbnailPath, GetImageFormat(originalImagePath)); - created = true; - } - catch - { - FileUtils.CopyFile(originalImagePath, thumbnailPath); - created = true; - } - finally - { - originalImage.Dispose(); bitmap.Dispose(); g.Dispose(); - } - } - - return created; - } - - public static bool MakeThumbnailIfExceedWidth(string originalImagePath, string thumbnailPath, int width) - { - Size originalSize; - Size thumbSize; - return MakeThumbnailIfExceedWidth(originalImagePath, thumbnailPath, width, out originalSize, out thumbSize); - } - - public static bool MakeThumbnailIfExceedWidth(string originalImagePath, string thumbnailPath, int width, out Size originalSize, out Size thumbSize) - { - originalSize = new Size(); - thumbSize = new Size(); - - var created = false; - - DirectoryUtils.CreateDirectoryIfNotExists(thumbnailPath); - if (FileUtils.IsFileExists(originalImagePath)) - { - var originalImage = Image.FromFile(originalImagePath); - - originalSize = originalImage.Size; - thumbSize = originalImage.Size; - - if (originalImage.Width < width) - { - return false; - } - - var towidth = width; - int toheight = originalImage.Height * width / originalImage.Width; - var x = 0; - var y = 0; - var ow = originalImage.Width; - var oh = originalImage.Height; - Image bitmap = new Bitmap(towidth, toheight); - var g = Graphics.FromImage(bitmap); - g.InterpolationMode = InterpolationMode.Default; - g.SmoothingMode = SmoothingMode.Default; - g.Clear(Color.Transparent); - g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight), - new Rectangle(x, y, ow, oh), GraphicsUnit.Pixel); - try - { - bitmap.Save(thumbnailPath, GetImageFormat(originalImagePath)); - thumbSize = bitmap.Size; - created = true; - } - catch - { - FileUtils.CopyFile(originalImagePath, thumbnailPath); - created = true; - } - finally - { - originalImage.Dispose(); bitmap.Dispose(); g.Dispose(); - } - } - - return created; - } - - public static bool CropImage(string originalImagePath, string thumbnailPath, int xPosition, int yPosition, int width, int height) - { - DirectoryUtils.CreateDirectoryIfNotExists(thumbnailPath); - if (!FileUtils.IsFileExists(originalImagePath)) return false; - - var originalImage = Image.FromFile(originalImagePath); - - var towidth = width; - var toheight = height; - var x = xPosition; - var y = yPosition; - Image bitmap = new Bitmap(towidth, toheight); - var g = Graphics.FromImage(bitmap); - g.InterpolationMode = InterpolationMode.Default; - g.SmoothingMode = SmoothingMode.Default; - g.Clear(Color.Transparent); - - var section = new Rectangle(new Point(x, y), new Size(width, height)); - g.DrawImage(originalImage, 0, 0, section, GraphicsUnit.Pixel); - try - { - bitmap.Save(thumbnailPath, GetImageFormat(originalImagePath)); - } - catch - { - FileUtils.CopyFile(originalImagePath, thumbnailPath); - } - finally - { - originalImage.Dispose(); bitmap.Dispose(); g.Dispose(); - } - - return true; - } - - public static bool RotateFlipImage(string originalImagePath, string thumbnailPath, RotateFlipType rotateFlipType) - { - DirectoryUtils.CreateDirectoryIfNotExists(thumbnailPath); - if (!FileUtils.IsFileExists(originalImagePath)) return false; - - var originalImage = Image.FromFile(originalImagePath); - - originalImage.RotateFlip(rotateFlipType); - - try - { - originalImage.Save(thumbnailPath, GetImageFormat(originalImagePath)); - } - catch - { - FileUtils.CopyFile(originalImagePath, thumbnailPath); - } - finally - { - originalImage.Dispose(); - } - - return true; - } - - public static Image GetImageFromBytes(byte[] data) - { - using (var ms = new MemoryStream(data)) - { - var image = Image.FromStream(ms); - ms.Flush(); - return image; - } - } - - public static bool AddText(Image image, string imagePath, string topText, string middleText, string bottomText, int thumbImageHeight, int thumbFontSize) - { - var isText = false; - try - { - if (!string.IsNullOrEmpty(topText) || !string.IsNullOrEmpty(middleText) || !string.IsNullOrEmpty(bottomText)) - { - var fontSize = Convert.ToInt32(Convert.ToDouble(image.Height / thumbImageHeight) * thumbFontSize); - var lineHeight = fontSize + 20; - var font = new Font("Microsoft YaHei", fontSize, FontStyle.Bold, GraphicsUnit.Pixel); - - //http://tech.pro/tutorial/654/csharp-snippet-tutorial-how-to-draw-text-on-an-image - - var g = Graphics.FromImage(image); - g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; - - if (!string.IsNullOrEmpty(topText)) - { - var strFormat = new StringFormat {Alignment = StringAlignment.Center}; - var rectangleF = new RectangleF(0, 20, image.Width, lineHeight); - g.DrawString(topText, font, Brushes.White, rectangleF, strFormat); - } - if (!string.IsNullOrEmpty(middleText)) - { - var strFormat = new StringFormat {Alignment = StringAlignment.Center}; - var rectangleF = new RectangleF(0, Convert.ToInt64((image.Height - lineHeight) / 2), image.Width, lineHeight); - g.DrawString(middleText, font, Brushes.White, rectangleF, strFormat); - } - if (!string.IsNullOrEmpty(bottomText)) - { - var strFormat = new StringFormat {Alignment = StringAlignment.Center}; - var rectangleF = new RectangleF(0, image.Height - lineHeight - 30, image.Width, lineHeight); - g.DrawString(bottomText, font, Brushes.White, rectangleF, strFormat); - } - - g.Dispose(); - - image.Save(imagePath); - image.Dispose(); - - isText = true; - } - } - catch - { - // ignored - } - - return isText; - } - } -} diff --git a/SiteServer.Utils/InputTypeUtils.cs b/SiteServer.Utils/InputTypeUtils.cs deleted file mode 100644 index e7a6ca971..000000000 --- a/SiteServer.Utils/InputTypeUtils.cs +++ /dev/null @@ -1,255 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.Plugin; - -namespace SiteServer.Utils -{ - public class InputTypeUtils - { - public static string GetText(InputType type) - { - if (type == InputType.CheckBox) - { - return "复选框"; - } - if (type == InputType.Radio) - { - return "单选框"; - } - if (type == InputType.SelectOne) - { - return "下拉列表(单选)"; - } - if (type == InputType.SelectMultiple) - { - return "下拉列表(多选)"; - } - if (type == InputType.SelectCascading) - { - return "下拉列表(级联)"; - } - if (type == InputType.Date) - { - return "日期选择框"; - } - if (type == InputType.DateTime) - { - return "日期时间选择框"; - } - if (type == InputType.Image) - { - return "图片"; - } - if (type == InputType.Video) - { - return "视频"; - } - if (type == InputType.File) - { - return "附件"; - } - if (type == InputType.Text) - { - return "文本框(单行)"; - } - if (type == InputType.TextArea) - { - return "文本框(多行)"; - } - if (type == InputType.TextEditor) - { - return "内容编辑器"; - } - if (type == InputType.Customize) - { - return "自定义"; - } - if (type == InputType.Hidden) - { - return "隐藏"; - } - - throw new Exception(); - } - - public static InputType GetEnumType(string typeStr) - { - var retval = InputType.Text; - - if (Equals(InputType.CheckBox, typeStr)) - { - retval = InputType.CheckBox; - } - else if (Equals(InputType.Radio, typeStr)) - { - retval = InputType.Radio; - } - else if (Equals(InputType.SelectOne, typeStr)) - { - retval = InputType.SelectOne; - } - else if (Equals(InputType.SelectMultiple, typeStr)) - { - retval = InputType.SelectMultiple; - } - else if (Equals(InputType.SelectCascading, typeStr)) - { - retval = InputType.SelectCascading; - } - else if (Equals(InputType.Date, typeStr)) - { - retval = InputType.Date; - } - else if (Equals(InputType.DateTime, typeStr)) - { - retval = InputType.DateTime; - } - else if (Equals(InputType.Image, typeStr)) - { - retval = InputType.Image; - } - else if (Equals(InputType.Video, typeStr)) - { - retval = InputType.Video; - } - else if (Equals(InputType.File, typeStr)) - { - retval = InputType.File; - } - else if (Equals(InputType.Text, typeStr)) - { - retval = InputType.Text; - } - else if (Equals(InputType.TextArea, typeStr)) - { - retval = InputType.TextArea; - } - else if (Equals(InputType.TextEditor, typeStr)) - { - retval = InputType.TextEditor; - } - else if (Equals(InputType.Customize, typeStr)) - { - retval = InputType.Customize; - } - else if (Equals(InputType.Hidden, typeStr)) - { - retval = InputType.Hidden; - } - - return retval; - } - - public static bool Equals(InputType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(type.Value.ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, InputType type) - { - return Equals(type, typeStr); - } - - public static bool EqualsAny(InputType type, params InputType[] types) - { - foreach (var theType in types) - { - if (type == theType) - { - return true; - } - } - return false; - } - - public static ListItem GetListItem(InputType type, bool selected) - { - var item = new ListItem(GetText(type), type.Value); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(InputType.Text, false)); - listControl.Items.Add(GetListItem(InputType.TextArea, false)); - listControl.Items.Add(GetListItem(InputType.TextEditor, false)); - listControl.Items.Add(GetListItem(InputType.CheckBox, false)); - listControl.Items.Add(GetListItem(InputType.Radio, false)); - listControl.Items.Add(GetListItem(InputType.SelectOne, false)); - listControl.Items.Add(GetListItem(InputType.SelectMultiple, false)); - listControl.Items.Add(GetListItem(InputType.SelectCascading, false)); - listControl.Items.Add(GetListItem(InputType.Date, false)); - listControl.Items.Add(GetListItem(InputType.DateTime, false)); - listControl.Items.Add(GetListItem(InputType.Image, false)); - listControl.Items.Add(GetListItem(InputType.Video, false)); - listControl.Items.Add(GetListItem(InputType.File, false)); - listControl.Items.Add(GetListItem(InputType.Customize, false)); - listControl.Items.Add(GetListItem(InputType.Hidden, false)); - } - } - - public static void AddListItems(ListControl listControl, DataType dataType) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(InputType.Text, false)); - listControl.Items.Add(GetListItem(InputType.TextArea, false)); - if (dataType == DataType.Text) - { - listControl.Items.Add(GetListItem(InputType.TextEditor, false)); - } - listControl.Items.Add(GetListItem(InputType.CheckBox, false)); - listControl.Items.Add(GetListItem(InputType.Radio, false)); - listControl.Items.Add(GetListItem(InputType.SelectOne, false)); - listControl.Items.Add(GetListItem(InputType.SelectMultiple, false)); - listControl.Items.Add(GetListItem(InputType.SelectCascading, false)); - listControl.Items.Add(GetListItem(InputType.Date, false)); - listControl.Items.Add(GetListItem(InputType.DateTime, false)); - listControl.Items.Add(GetListItem(InputType.Image, false)); - listControl.Items.Add(GetListItem(InputType.Video, false)); - listControl.Items.Add(GetListItem(InputType.File, false)); - listControl.Items.Add(GetListItem(InputType.Customize, false)); - listControl.Items.Add(GetListItem(InputType.Hidden, false)); - } - } - - public static void AddListItemsToText(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(InputType.Text, false)); - listControl.Items.Add(GetListItem(InputType.TextArea, false)); - listControl.Items.Add(GetListItem(InputType.TextEditor, false)); - } - } - - public static bool IsWithStyleItems(InputType type) - { - if (type == InputType.CheckBox || type == InputType.Radio || type == InputType.SelectMultiple || type == InputType.SelectOne || type == InputType.SelectCascading) - { - return true; - } - return false; - } - - public static bool IsPureString(InputType type) - { - if (type == InputType.Date || type == InputType.DateTime || type == InputType.CheckBox || type == InputType.Radio || type == InputType.SelectMultiple || type == InputType.SelectOne || type == InputType.Image || type == InputType.Video || type == InputType.File || type == InputType.SelectCascading) - { - return false; - } - return true; - } - } -} diff --git a/SiteServer.Utils/LowerNameValueCollection.cs b/SiteServer.Utils/LowerNameValueCollection.cs deleted file mode 100644 index 31b69191e..000000000 --- a/SiteServer.Utils/LowerNameValueCollection.cs +++ /dev/null @@ -1,45 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Specialized; - -namespace SiteServer.Utils -{ - public class LowerNameValueCollection - { - private readonly NameValueCollection _nvcLower; - - public LowerNameValueCollection() - { - Keys = new List(); - _nvcLower = new NameValueCollection(); - } - - public void Set(string name, string value) - { - if (string.IsNullOrEmpty(name)) return; - - _nvcLower.Set(name.ToLower(), value); - if (!Keys.Contains(name)) - { - Keys.Add(name); - } - } - - public string Get(string name) - { - return string.IsNullOrEmpty(name) ? null : _nvcLower.Get(name.ToLower()); - } - - public void Remove(string name) - { - if (string.IsNullOrEmpty(name)) return; - - _nvcLower.Remove(name.ToLower()); - - Keys.Remove(name); - } - - public List Keys { get; } - - public int Count => Keys.Count; - } -} diff --git a/SiteServer.Utils/MessageUtils.cs b/SiteServer.Utils/MessageUtils.cs deleted file mode 100644 index 383d6e202..000000000 --- a/SiteServer.Utils/MessageUtils.cs +++ /dev/null @@ -1,214 +0,0 @@ -using System; -using System.Web.UI; - -namespace SiteServer.Utils -{ - public class MessageUtils - { - private MessageUtils() - { - } - - public static void SaveMessage(Message.EMessageType messageType, string message) - { - CookieUtils.SetCookie(Message.GetCookieName(messageType), message, DateTime.MaxValue); - } - - private static string DecodeMessage(string message) - { - if (!string.IsNullOrEmpty(message)) - { - //message = StringUtils.HtmlDecode(message); - message = message.Replace("''", "\""); - } - return message; - } - - public static string GetMessageHtml(Message.EMessageType messageType, string message, Control control) - { - var messageHtml = string.Empty; - message = DecodeMessage(message); - if (!string.IsNullOrEmpty(message)) - { - if (messageType == Message.EMessageType.Success) - { - messageHtml = $@"
    {message}
    "; - } - else if (messageType == Message.EMessageType.Error) - { - messageHtml = $@"
    {message}
    "; - } - else if (messageType == Message.EMessageType.Info) - { - messageHtml = $@"
    {message}
    "; - } - } - return messageHtml; - } - - public static string GetMessageHtml(Control control) - { - var messageType = Message.EMessageType.None; - var message = string.Empty; - if (CookieUtils.IsExists(Message.GetCookieName(Message.EMessageType.Success))) - { - messageType = Message.EMessageType.Success; - message = CookieUtils.GetCookie(Message.GetCookieName(Message.EMessageType.Success)); - CookieUtils.Erase(Message.GetCookieName(Message.EMessageType.Success)); - } - else if (CookieUtils.IsExists(Message.GetCookieName(Message.EMessageType.Error))) - { - messageType = Message.EMessageType.Error; - message = CookieUtils.GetCookie(Message.GetCookieName(Message.EMessageType.Error)); - CookieUtils.Erase(Message.GetCookieName(Message.EMessageType.Error)); - } - else if (CookieUtils.IsExists(Message.GetCookieName(Message.EMessageType.Info))) - { - messageType = Message.EMessageType.Info; - message = CookieUtils.GetCookie(Message.GetCookieName(Message.EMessageType.Info)); - CookieUtils.Erase(Message.GetCookieName(Message.EMessageType.Info)); - } - return GetMessageHtml(messageType, message, control); - } - - public static string GetAlertHtml(Message.EMessageType messageType, string message, Control control) - { - var messageHtml = string.Empty; - message = DecodeMessage(message); - if (messageType == Message.EMessageType.Success) - { - if (!string.IsNullOrEmpty(message)) - { - messageHtml = $@" -
    - - 成功!   {message}
    "; - } - } - else if (messageType == Message.EMessageType.Error) - { - if (!string.IsNullOrEmpty(message)) - { - messageHtml = $@" -
    - - 错误!   {message}
    "; - } - } - else if (messageType == Message.EMessageType.Info) - { - if (!string.IsNullOrEmpty(message)) - { - messageHtml = $@" -
    - - 提示!   {message}
    "; - } - } - return messageHtml; - } - - public static string GetAlertHtml(Control control, string text) - { - var messageType = Message.EMessageType.None; - var message = string.Empty; - if (CookieUtils.IsExists(Message.GetCookieName(Message.EMessageType.Success))) - { - messageType = Message.EMessageType.Success; - message = CookieUtils.GetCookie(Message.GetCookieName(Message.EMessageType.Success)); - CookieUtils.Erase(Message.GetCookieName(Message.EMessageType.Success)); - } - else if (CookieUtils.IsExists(Message.GetCookieName(Message.EMessageType.Error))) - { - messageType = Message.EMessageType.Error; - message = CookieUtils.GetCookie(Message.GetCookieName(Message.EMessageType.Error)); - CookieUtils.Erase(Message.GetCookieName(Message.EMessageType.Error)); - } - else if (CookieUtils.IsExists(Message.GetCookieName(Message.EMessageType.Info))) - { - messageType = Message.EMessageType.Info; - message = CookieUtils.GetCookie(Message.GetCookieName(Message.EMessageType.Info)); - CookieUtils.Erase(Message.GetCookieName(Message.EMessageType.Info)); - } - else if (!string.IsNullOrEmpty(text)) - { - messageType = Message.EMessageType.Info; - message = text; - } - return GetAlertHtml(messageType, message, control); - } - - #region Message - public class Message - { - private const string CookieName = "BaiRong_Message"; - public static string GetCookieName(EMessageType messageType) - { - return $"{CookieName}_{EMessageTypeUtils.GetValue(messageType)}"; - } - - public enum EMessageType - { - Success, - Error, - Info, - None - } - - public class EMessageTypeUtils - { - public static string GetValue(EMessageType type) - { - if (type == EMessageType.Success) - { - return "Success"; - } - if (type == EMessageType.Error) - { - return "Error"; - } - if (type == EMessageType.Info) - { - return "Info"; - } - if (type == EMessageType.None) - { - return "None"; - } - throw new Exception(); - } - } - } - #endregion - - #region Constants - - public const string InsertSuccess = "添加成功!"; - public const string UpdateSuccess = "更新成功!"; - public const string DeleteSuccess = "删除成功!"; - public const string CheckSuccess = "审核成功!"; - public const string InsertFail = "添加失败!"; - public const string UpdateFail = "更新失败!"; - public const string DeleteFail = "删除失败!"; - public const string CheckFail = "审核失败!"; - - public const string AccountLocked = "登录失败,您的帐户已经被锁定!"; - public const string AccountUnchecked = "登录失败,您的帐户还未被审核!"; - public const string AccountError = "登录失败,请重试!"; - - //public const string CheckDenied = "审核不通过"; - //public const string Unchecked = "未审核"; - //public const string CheckedLevel1 = "一级审核通过"; - //public const string CheckedLevel2 = "二级审核通过"; - //public const string CheckedLevel3 = "三级审核通过"; - //public const string CheckedLevel4 = "四级审核通过"; - //public const string CheckedLevel5 = "五级审核通过"; - - - public const string PageErrorParameterIsNotCorrect = "此页需要正确的参数传输进入!"; - - public const string PermissionNotVisible = "对不起,您没有权限浏览此页!"; - - #endregion - } -} \ No newline at end of file diff --git a/SiteServer.Utils/PageUtils.cs b/SiteServer.Utils/PageUtils.cs deleted file mode 100644 index b0dee1fba..000000000 --- a/SiteServer.Utils/PageUtils.cs +++ /dev/null @@ -1,1208 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Globalization; -using System.Text; -using System.Text.RegularExpressions; -using System.Web; -using System.Web.UI; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.Utils -{ - public class PageUtils - { - public const char SeparatorChar = '/'; - - public const string UnclickedUrl = "javascript:;"; - - public static string ParseNavigationUrl(string url) - { - if (string.IsNullOrEmpty(url)) return string.Empty; - - url = url.StartsWith("~") ? Combine(ApplicationPath, url.Substring(1)) : url; - url = url.Replace(PathUtils.SeparatorChar, SeparatorChar); - return url; - } - - public static string AddProtocolToUrl(string url) - { - return AddProtocolToUrl(url, string.Empty); - } - - /// - /// 按照给定的host,添加Protocol - /// Demo: 发送的邮件中,需要内容标题的链接为全连接,那么需要指定他的host - /// - /// - /// - /// - public static string AddProtocolToUrl(string url, string host) - { - if (url == UnclickedUrl) - { - return url; - } - var retval = string.Empty; - - if (!string.IsNullOrEmpty(url)) - { - url = url.Trim(); - if (IsProtocolUrl(url)) - { - retval = url; - } - else - { - if (string.IsNullOrEmpty(host)) - { - retval = url.StartsWith("/") ? GetScheme() + "://" + GetHost() + url : GetScheme() + "://" + url; - } - else - { - retval = url.StartsWith("/") ? host.TrimEnd('/') + url : host + url; - } - } - } - return retval; - } - - public static string AddQuestionOrAndToUrl(string pageUrl) - { - var url = pageUrl; - if (string.IsNullOrEmpty(url)) - { - url = "?"; - } - else - { - if (url.IndexOf('?') == -1) - { - url = url + "?"; - } - else if (!url.EndsWith("?")) - { - url = url + "&"; - } - } - return url; - } - - public static string RemovePortFromUrl(string url) - { - var retval = string.Empty; - - if (!string.IsNullOrEmpty(url)) - { - var regex = new Regex(@":\d+"); - retval = regex.Replace(url, ""); - } - return retval; - } - - public static string RemoveFileNameFromUrl(string url) - { - if (string.IsNullOrEmpty(url)) return string.Empty; - - url = url.Trim(); - if (url.Contains("/")) - { - var fileName = url.Substring(url.LastIndexOf("/", StringComparison.Ordinal)); - if (fileName.Contains(".")) - { - return url.Substring(0, url.LastIndexOf("/", StringComparison.Ordinal)); - } - } - - return url; - } - - public static string RemoveProtocolFromUrl(string url) - { - if (string.IsNullOrEmpty(url)) return string.Empty; - - url = url.Trim(); - return IsProtocolUrl(url) ? url.Substring(url.IndexOf("://", StringComparison.Ordinal) + 3) : url; - } - - public static bool IsProtocolUrl(string url) - { - if (string.IsNullOrEmpty(url)) return false; - - url = url.Trim(); - return url.IndexOf("://", StringComparison.Ordinal) != -1 || url.StartsWith("javascript:"); - } - - public static bool IsAbsoluteUrl(string url) - { - if (string.IsNullOrEmpty(url)) return false; - - url = url.Trim(); - return url.StartsWith("/") || url.IndexOf("://", StringComparison.Ordinal) != -1 || url.StartsWith("javascript:"); - } - - public static string GetAbsoluteUrl() - { - return HttpContext.Current.Request.Url.AbsoluteUri; - } - - public static string PathDifference(string path1, string path2, bool compareCase) - { - var num2 = -1; - var num1 = 0; - while ((num1 < path1.Length) && (num1 < path2.Length)) - { - if ((path1[num1] != path2[num1]) && (compareCase || (char.ToLower(path1[num1], CultureInfo.InvariantCulture) != char.ToLower(path2[num1], CultureInfo.InvariantCulture)))) - { - break; - } - if (path1[num1] == '/') - { - num2 = num1; - } - num1++; - } - if (num1 == 0) - { - return path2; - } - if ((num1 == path1.Length) && (num1 == path2.Length)) - { - return string.Empty; - } - var builder1 = new StringBuilder(); - while (num1 < path1.Length) - { - if (path1[num1] == '/') - { - builder1.Append("../"); - } - num1++; - } - return (builder1 + path2.Substring(num2 + 1)); - } - - /// - /// 获取服务器根域名 - /// - /// - public static string GetMainDomain(string url) - { - if (string.IsNullOrEmpty(url)) return url; - - url = RemoveProtocolFromUrl(url.ToLower()); - if (url.IndexOf('/') != -1) - { - url = url.Substring(0, url.IndexOf('/')); - } - - if (url.IndexOf('.') <= 0) return url; - - var strArr = url.Split('.'); - var lastStr = strArr.GetValue(strArr.Length - 1).ToString(); - if (StringUtils.IsNumber(lastStr)) //如果最后一位是数字,那么说明是IP地址 - { - return url; - } - var domainRules = ".com.cn|.net.cn|.org.cn|.gov.cn|.com|.net|.cn|.org|.cc|.me|.tel|.mobi|.asia|.biz|.info|.name|.tv|.hk|.公司|.中国|.网络".Split('|'); - var returnStr = string.Empty; - foreach (var t in domainRules) - { - if (url.EndsWith(t.ToLower())) //如果最后有找到匹配项 - { - var findStr = t; - var replaceStr = url.Replace(findStr, ""); - if (replaceStr.IndexOf('.') > 0) //存在二级域名或者三级,比如:www.px915 - { - var replaceArr = replaceStr.Split('.'); // www px915 - returnStr = replaceArr.GetValue(replaceArr.Length - 1) + findStr; - return returnStr; - } - returnStr = replaceStr + findStr; //连接起来输出为:px915.com - return returnStr; - } - returnStr = url; - } - return returnStr; - } - - public static string GetHost() - { - var host = string.Empty; - if (HttpContext.Current == null) return string.IsNullOrEmpty(host) ? string.Empty : host.Trim().ToLower(); - host = HttpContext.Current.Request.Headers["HOST"]; - if (string.IsNullOrEmpty(host)) - { - host = HttpContext.Current.Request.Url.Host; - } - - return string.IsNullOrEmpty(host) ? string.Empty : host.Trim().ToLower(); - } - - public static string GetScheme() - { - var scheme = string.Empty; - if (HttpContext.Current != null) - { - scheme = HttpContext.Current.Request.Headers["SCHEME"]; - if (string.IsNullOrEmpty(scheme)) - { - scheme = HttpContext.Current.Request.Url.Scheme; - } - } - - return string.IsNullOrEmpty(scheme) ? "http" : scheme.Trim().ToLower(); - } - - public static string ApplicationPath => HttpContext.Current != null && !string.IsNullOrEmpty(HttpContext.Current.Request.ApplicationPath) ? HttpContext.Current.Request.ApplicationPath : "/"; - - // 系统根目录访问地址 - public static string GetRootUrl(string relatedUrl) - { - return Combine(ApplicationPath, relatedUrl); - } - - public static string GetTemporaryFilesUrl(string relatedUrl) - { - return Combine(ApplicationPath, DirectoryUtils.SiteFiles.DirectoryName, DirectoryUtils.SiteFiles.TemporaryFiles, relatedUrl); - } - - public static NameValueCollection GetQueryString(string url) - { - if (string.IsNullOrEmpty(url) || url.IndexOf("?", StringComparison.Ordinal) == -1) return new NameValueCollection(); - - var querystring = url.Substring(url.IndexOf("?", StringComparison.Ordinal) + 1); - return TranslateUtils.ToNameValueCollection(querystring); - } - - public static NameValueCollection GetQueryStringFilterXss(string url) - { - if (string.IsNullOrEmpty(url) || url.IndexOf("?", StringComparison.Ordinal) == -1) return new NameValueCollection(); - - var attributes = new NameValueCollection(); - - var querystring = url.Substring(url.IndexOf("?", StringComparison.Ordinal) + 1); - var originals = TranslateUtils.ToNameValueCollection(querystring); - foreach (string key in originals.Keys) - { - attributes[key] = FilterXss(originals[key]); - } - return attributes; - } - - public static string Combine(params string[] urls) - { - if (urls == null || urls.Length <= 0) return string.Empty; - - var retval = urls[0]?.Replace(PathUtils.SeparatorChar, SeparatorChar) ?? string.Empty; - for (var i = 1; i < urls.Length; i++) - { - var url = (urls[i] != null) ? urls[i].Replace(PathUtils.SeparatorChar, SeparatorChar) : string.Empty; - retval = Combine(retval, url); - } - return retval; - } - - private static string Combine(string url1, string url2) - { - if (url1 == null || url2 == null) - { - throw new ArgumentNullException(url1 == null ? "url1" : "url2"); - } - if (url2.Length == 0) - { - return url1; - } - if (url1.Length == 0) - { - return url2; - } - - return url1.TrimEnd(SeparatorChar) + SeparatorChar + url2.TrimStart(SeparatorChar); - } - - public static string AddQueryString(string url, string queryStringKey, string queryStringValue) - { - var queryString = new NameValueCollection - { - {queryStringKey, queryStringValue} - }; - return AddQueryString(url, queryString); - } - - public static string AddQueryString(string url, string queryString) - { - if (queryString == null || url == null) return url; - - queryString = queryString.TrimStart('?', '&'); - - if (url.IndexOf("?", StringComparison.Ordinal) == -1) - { - return string.Concat(url, "?", queryString); - } - return url.EndsWith("?") ? string.Concat(url, queryString) : string.Concat(url, "&", queryString); - } - - public static string AddQueryString(string url, NameValueCollection queryString) - { - if (queryString == null || url == null || queryString.Count == 0) - return url; - - var builder = new StringBuilder(); - foreach (string key in queryString.Keys) - { - builder.Append($"&{key}={HttpUtility.UrlEncode(queryString[key])}"); - } - if (url.IndexOf("?", StringComparison.Ordinal) == -1) - { - if (builder.Length > 0) builder.Remove(0, 1); - return string.Concat(url, "?", builder.ToString()); - } - if (url.EndsWith("?")) - { - if (builder.Length > 0) builder.Remove(0, 1); - } - return string.Concat(url, builder.ToString()); - } - - public static string AddQueryStringIfNotExists(string url, NameValueCollection queryString) - { - if (queryString == null || url == null || queryString.Count == 0) - return url; - - var index = url.IndexOf("?", StringComparison.Ordinal); - if (index != -1) - { - var query = TranslateUtils.ToNameValueCollection(url.Substring(index).Trim('?', '&'), '&'); - - foreach (string key in query.Keys) - { - if (queryString[key] != null) - { - queryString.Remove(key); - } - } - } - - return AddQueryString(url, queryString); - } - - public static string RemoveQueryString(string url, string queryString) - { - if (queryString == null || url == null) return url; - - if (url.IndexOf("?", StringComparison.Ordinal) == -1 || url.EndsWith("?")) - { - return url; - } - var attributes = GetQueryString(url); - attributes.Remove(queryString); - url = url.Substring(0, url.IndexOf("?", StringComparison.Ordinal)); - return AddQueryString(url, attributes); - } - - public static string GetIpAddress() - { - var result = string.Empty; - - try - { - //取CDN用户真实IP的方法 - //当用户使用代理时,取到的是代理IP - result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; - if (!string.IsNullOrEmpty(result)) - { - //可能有代理 - if (result.IndexOf(".", StringComparison.Ordinal) == -1) - result = null; - else - { - if (result.IndexOf(",", StringComparison.Ordinal) != -1) - { - result = result.Replace(" ", "").Replace("'", ""); - var temparyip = result.Split(",;".ToCharArray()); - foreach (var t in temparyip) - { - if (IsIpAddress(t) && t.Substring(0, 3) != "10." && t.Substring(0, 7) != "192.168" && t.Substring(0, 7) != "172.16.") - { - result = t; - } - } - var str = result.Split(','); - if (str.Length > 0) - result = str[0].Trim(); - } - else if (IsIpAddress(result)) - return result; - } - } - - if (string.IsNullOrEmpty(result)) - result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; - if (string.IsNullOrEmpty(result)) - result = HttpContext.Current.Request.UserHostAddress; - if (string.IsNullOrEmpty(result)) - result = "localhost"; - - if (result == "::1" || result == "127.0.0.1") - { - result = "localhost"; - } - } - catch - { - // ignored - } - - return result; - } - - public static bool IsIpAddress(string ip) - { - return Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$"); - } - - public static string SessionId - { - get - { - var sessionId = CookieUtils.GetCookie("SiteServer.SessionID"); - if (!string.IsNullOrEmpty(sessionId)) return sessionId; - long i = 1; - foreach (var b in Guid.NewGuid().ToByteArray()) - { - i *= b + 1; - } - sessionId = $"{i - DateTime.Now.Ticks:x}"; - CookieUtils.SetCookie("SiteServer.SessionID", sessionId, DateTime.Now.AddDays(100)); - return sessionId; - } - } - - public static string GetRefererUrl() - { - var url = HttpContext.Current.Request.ServerVariables["HTTP_REFERER"]; - return url; - } - - public static string GetUrlWithReturnUrl(string pageUrl, string returnUrl) - { - var retval = pageUrl; - returnUrl = $"ReturnUrl={returnUrl}"; - if (pageUrl.IndexOf("?", StringComparison.Ordinal) != -1) - { - if (pageUrl.EndsWith("&")) - { - retval += returnUrl; - } - else - { - retval += "&" + returnUrl; - } - } - else - { - retval += "?" + returnUrl; - } - return ParseNavigationUrl(retval); - } - - public static string GetReturnUrl() - { - return GetReturnUrl(true); - } - - public static string GetReturnUrl(bool toReferer) - { - var redirectUrl = string.Empty; - if (!string.IsNullOrEmpty(HttpContext.Current.Request.QueryString["ReturnUrl"])) - { - redirectUrl = ParseNavigationUrl(HttpContext.Current.Request.QueryString["ReturnUrl"]); - } - else if (toReferer) - { - var referer = GetRefererUrl(); - redirectUrl = !string.IsNullOrEmpty(referer) ? referer : GetHost(); - } - return redirectUrl; - } - - public static string GetUrlByBaseUrl(string rawUrl, string baseUrl) - { - var url = string.Empty; - if (!string.IsNullOrEmpty(rawUrl)) - { - rawUrl = rawUrl.Trim().TrimEnd('#'); - } - if (!string.IsNullOrEmpty(baseUrl)) - { - baseUrl = baseUrl.Trim(); - } - if (!string.IsNullOrEmpty(rawUrl)) - { - rawUrl = rawUrl.Trim(); - if (IsProtocolUrl(rawUrl)) - { - url = rawUrl; - } - else if (rawUrl.StartsWith("/")) - { - var domain = GetUrlWithoutPathInfo(baseUrl); - url = domain + rawUrl; - } - else if (rawUrl.StartsWith("../")) - { - var count = StringUtils.GetStartCount("../", rawUrl); - rawUrl = rawUrl.Remove(0, 3 * count); - baseUrl = GetUrlWithoutFileName(baseUrl).TrimEnd('/'); - baseUrl = RemoveProtocolFromUrl(baseUrl); - for (var i = 0; i < count; i++) - { - var j = baseUrl.LastIndexOf('/'); - if (j != -1) - { - baseUrl = StringUtils.Remove(baseUrl, j); - } - else - { - break; - } - } - url = Combine(AddProtocolToUrl(baseUrl), rawUrl); - } - else - { - if (baseUrl != null && baseUrl.EndsWith("/")) - { - url = baseUrl + rawUrl; - } - else - { - var urlWithoutFileName = GetUrlWithoutFileName(baseUrl); - if (!urlWithoutFileName.EndsWith("/")) - { - urlWithoutFileName += "/"; - } - url = urlWithoutFileName + rawUrl; - } - } - } - return url; - } - - /// - /// 将Url地址的查询字符串去掉 - /// - /// - /// - public static string GetUrlWithoutQueryString(string rawUrl) - { - string urlWithoutQueryString; - if (rawUrl != null && rawUrl.IndexOf("?", StringComparison.Ordinal) != -1) - { - var queryString = rawUrl.Substring(rawUrl.IndexOf("?", StringComparison.Ordinal)); - urlWithoutQueryString = rawUrl.Replace(queryString, ""); - } - else - { - urlWithoutQueryString = rawUrl; - } - return urlWithoutQueryString; - } - - /// - /// 将Url地址域名后的字符去掉 - /// - /// - /// - public static string GetUrlWithoutPathInfo(string rawUrl) - { - var urlWithoutPathInfo = string.Empty; - if (rawUrl != null && rawUrl.Trim().Length > 0) - { - if (rawUrl.ToLower().StartsWith("http://")) - { - urlWithoutPathInfo = rawUrl.Substring("http://".Length); - } - if (urlWithoutPathInfo.IndexOf("/", StringComparison.Ordinal) != -1) - { - urlWithoutPathInfo = urlWithoutPathInfo.Substring(0, urlWithoutPathInfo.IndexOf("/", StringComparison.Ordinal)); - } - if (string.IsNullOrEmpty(urlWithoutPathInfo)) - { - urlWithoutPathInfo = rawUrl; - } - urlWithoutPathInfo = "http://" + urlWithoutPathInfo; - } - return urlWithoutPathInfo; - } - - /// - /// 将Url地址后的文件名称去掉 - /// - /// - /// - public static string GetUrlWithoutFileName(string rawUrl) - { - if (string.IsNullOrEmpty(rawUrl)) return string.Empty; - - var urlWithoutFileName = string.Empty; - if (rawUrl.ToLower().StartsWith("http://")) - { - urlWithoutFileName = rawUrl.Substring("http://".Length); - } - if (urlWithoutFileName.IndexOf("/", StringComparison.Ordinal) != -1 && !urlWithoutFileName.EndsWith("/")) - { - const string regex = "/(?[^/]*\\.[^/]*)[^/]*$"; - const RegexOptions options = RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline | RegexOptions.IgnoreCase; - var reg = new Regex(regex, options); - var match = reg.Match(urlWithoutFileName); - if (match.Success) - { - var fileName = match.Groups["filename"].Value; - urlWithoutFileName = urlWithoutFileName.Substring(0, urlWithoutFileName.LastIndexOf(fileName, StringComparison.Ordinal)); - } - } - urlWithoutFileName = "http://" + urlWithoutFileName; - return urlWithoutFileName; - } - - public static string GetUrlQueryString(string url) - { - var queryString = string.Empty; - if (!string.IsNullOrEmpty(url) && url.IndexOf("?", StringComparison.Ordinal) != -1) - { - queryString = url.Substring(url.IndexOf("?", StringComparison.Ordinal) + 1); - } - return queryString; - } - - public static string GetFileNameFromUrl(string rawUrl) - { - if (string.IsNullOrEmpty(rawUrl)) return string.Empty; - - var fileName = string.Empty; - //if (rawUrl.ToLower().StartsWith("http://")) - //{ - // rawUrl = rawUrl.Substring("http://".Length); - //} - //if (rawUrl.IndexOf("?") != -1) - //{ - // int index = rawUrl.IndexOf("?"); - // rawUrl = rawUrl.Remove(index, rawUrl.Length - index); - //} - rawUrl = RemoveProtocolFromUrl(rawUrl); - rawUrl = GetUrlWithoutQueryString(rawUrl); - if (rawUrl.IndexOf("/", StringComparison.Ordinal) != -1 && !rawUrl.EndsWith("/")) - { - const string regex = "/(?[^/]*\\.[^/]*)[^/]*$"; - const RegexOptions options = RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline | RegexOptions.IgnoreCase; - var reg = new Regex(regex, options); - var match = reg.Match(rawUrl); - if (match.Success) - { - fileName = match.Groups["filename"].Value; - } - } - else - { - fileName = rawUrl; - } - return fileName; - } - - public static string GetExtensionFromUrl(string rawUrl) - { - var extension = string.Empty; - if (!string.IsNullOrEmpty(rawUrl)) - { - rawUrl = RemoveProtocolFromUrl(rawUrl); - rawUrl = GetUrlWithoutQueryString(rawUrl); - rawUrl = rawUrl.TrimEnd('/'); - if (rawUrl.IndexOf('/') != -1) - { - rawUrl = rawUrl.Substring(rawUrl.LastIndexOf('/')); - if (rawUrl.IndexOf('.') != -1) - { - extension = rawUrl.Substring(rawUrl.LastIndexOf('.')); - } - } - } - return extension; - } - - public static string UrlEncode(string urlString) - { - if (urlString == null || urlString == "$4") - { - return string.Empty; - } - - var newValue = urlString.Replace("\"", "'"); - newValue = HttpUtility.UrlEncode(newValue); - newValue = newValue.Replace("%2f", "/"); - return newValue; - } - - public static string UrlEncode(string urlString, string encoding) - { - if (urlString == null || urlString == "$4") - { - return string.Empty; - } - - var newValue = urlString.Replace("\"", "'"); - newValue = HttpUtility.UrlEncode(newValue, Encoding.GetEncoding(encoding)); - newValue = newValue.Replace("%2f", "/"); - return newValue; - } - - public static string UrlEncode(string urlString, ECharset charset) - { - if (urlString == null || urlString == "$4") - { - return string.Empty; - } - - var newValue = urlString.Replace("\"", "'"); - newValue = HttpUtility.UrlEncode(newValue, ECharsetUtils.GetEncoding(charset)); - newValue = newValue.Replace("%2f", "/"); - return newValue; - } - - public static string UrlDecode(string urlString, string encoding) - { - return HttpUtility.UrlDecode(urlString, Encoding.GetEncoding(encoding)); - } - - public static string UrlDecode(string urlString, ECharset charset) - { - return HttpUtility.UrlDecode(urlString, ECharsetUtils.GetEncoding(charset)); - } - - public static string UrlDecode(string urlString) - { - return HttpContext.Current.Server.UrlDecode(urlString); - } - - public static void Redirect(string url) - { - var response = HttpContext.Current.Response; - response.Clear();//这里是关键,清除在返回前已经设置好的标头信息,这样后面的跳转才不会报错 - response.BufferOutput = true;//设置输出缓冲 - if (!response.IsRequestBeingRedirected) //在跳转之前做判断,防止重复 - { - response.Redirect(url, true); - } - } - - public static void Download(HttpResponse response, string filePath, string fileName) - { - var fileType = PathUtils.GetExtension(filePath); - var fileSystemType = EFileSystemTypeUtils.GetEnumType(fileType); - response.Buffer = true; - response.Clear(); - response.ContentType = EFileSystemTypeUtils.GetResponseContentType(fileSystemType); - response.AddHeader("Content-Disposition", "attachment; filename=" + UrlEncode(fileName)); - response.WriteFile(filePath); - response.Flush(); - response.End(); - } - - public static void Download(HttpResponse response, string filePath) - { - var fileName = PathUtils.GetFileName(filePath); - Download(response, filePath, fileName); - } - - public static string GetAdminDirectoryUrl(string relatedUrl) - { - return Combine(ApplicationPath, WebConfigUtils.AdminDirectory, relatedUrl); - } - - public static string GetSiteFilesUrl(string relatedUrl) - { - return Combine(ApplicationPath, DirectoryUtils.SiteFiles.DirectoryName, relatedUrl); - } - - public static string GetSiteTemplatesUrl(string relatedUrl) - { - return Combine(ApplicationPath, DirectoryUtils.SiteFiles.DirectoryName, DirectoryUtils.SiteTemplates.DirectoryName, relatedUrl); - } - - public static string GetSiteTemplateMetadataUrl(string siteTemplateUrl, string relatedUrl) - { - return Combine(siteTemplateUrl, DirectoryUtils.SiteTemplates.SiteTemplateMetadata, relatedUrl); - } - - public static string GetPluginDirectoryUrl(string pluginId, string url) - { - if (string.IsNullOrEmpty(url)) return string.Empty; - - if (!IsProtocolUrl(url)) - { - return StringUtils.StartsWith(url, "@/") ? GetAdminDirectoryUrl(url.Substring(1)) : GetSiteFilesUrl(Combine(DirectoryUtils.SiteFiles.Plugins, pluginId, url)); - } - return url; - } - - public static string GetSiteServerUrl(string className, NameValueCollection queryString) - { - return AddQueryString(GetAdminDirectoryUrl(className.ToLower() + ".aspx"), queryString); - } - - public static string GetPluginsUrl(string className, NameValueCollection queryString) - { - return AddQueryString(GetAdminDirectoryUrl(Combine("plugins", className.ToLower() + ".aspx")), queryString); - } - - public static string GetSettingsUrl(string className, NameValueCollection queryString) - { - return AddQueryString(GetAdminDirectoryUrl(Combine("settings", className.ToLower() + ".aspx")), queryString); - } - - public static string GetCmsUrl(int siteId, string className, NameValueCollection queryString) - { - queryString = queryString ?? new NameValueCollection(); - queryString.Remove("siteId"); - return AddQueryString(GetAdminDirectoryUrl($"cms/{className.ToLower()}.aspx?siteId={siteId}"), queryString); - } - - public static string GetCmsWebHandlerUrl(int siteId, string className, NameValueCollection queryString) - { - queryString = queryString ?? new NameValueCollection(); - queryString.Remove("siteId"); - return AddQueryString(GetAdminDirectoryUrl($"cms/{className.ToLower()}.ashx?siteId={siteId}"), queryString); - } - - public static string GetAjaxUrl(string className, NameValueCollection queryString) - { - return AddQueryString(GetAdminDirectoryUrl(Combine("ajax", className.ToLower() + ".aspx")), queryString); - } - - public static string GetUserFilesUrl(string userName, string relatedUrl) - { - if (IsVirtualUrl(relatedUrl)) - { - return ParseNavigationUrl(relatedUrl); - } - return Combine(ApplicationPath, DirectoryUtils.SiteFiles.DirectoryName, DirectoryUtils.SiteFiles.UserFiles, userName, relatedUrl); - } - - public static string GetUserFileSystemManagementDirectoryUrl(string userName, string currentRootPath) - { - var directoryUrl = string.Empty; - if (string.IsNullOrEmpty(currentRootPath) || !(currentRootPath.StartsWith("~/"))) - { - currentRootPath = "~/" + currentRootPath; - } - var directoryNames = currentRootPath.Split('/'); - foreach (var directoryName in directoryNames) - { - if (!string.IsNullOrEmpty(directoryName)) - { - directoryUrl = directoryName.Equals("~") ? GetUserFilesUrl(string.Empty, userName) : Combine(directoryUrl, directoryName); - } - - } - return directoryUrl; - } - - public static void RedirectToErrorPage(int logId) - { - Redirect(GetErrorPageUrl(logId)); - } - - public static void RedirectToErrorPage(string message) - { - Redirect(GetErrorPageUrl(message)); - } - - public static string GetErrorPageUrl(int logId) - { - return GetAdminDirectoryUrl($"pageError.html?logId={logId}"); - } - - public static string GetErrorPageUrl(string message) - { - return GetAdminDirectoryUrl($"pageError.html?message={HttpUtility.UrlEncode(message)}"); - } - - public static void CheckRequestParameter(params string[] parameters) - { - foreach (var parameter in parameters) - { - if (!string.IsNullOrEmpty(parameter) && HttpContext.Current.Request.QueryString[parameter] == null) - { - Redirect(GetErrorPageUrl(MessageUtils.PageErrorParameterIsNotCorrect)); - return; - } - } - } - - public static void RedirectToLoginPage() - { - RedirectToLoginPage(string.Empty); - } - - public static void RedirectToLoginPage(string error) - { - var pageUrl = GetAdminDirectoryUrl("login.aspx"); - - if (!string.IsNullOrEmpty(error)) - { - pageUrl = pageUrl + "?error=" + error; - } - Redirect(pageUrl); - } - - public static void RedirectToLoadingPage(string pageUrl) - { - Redirect(GetLoadingUrl(pageUrl)); - } - - public static string AddReturnUrl(string url, string returnUrl) - { - return AddQueryString(url, "ReturnUrl", returnUrl); - } - - public static string GetRootUrlByPhysicalPath(string physicalPath) - { - var requestPath = PathUtils.GetPathDifference(WebConfigUtils.PhysicalApplicationPath, physicalPath); - requestPath = requestPath.Replace(PathUtils.SeparatorChar, SeparatorChar); - return GetRootUrl(requestPath); - } - - public static string ParseConfigRootUrl(string url) - { - return ParseNavigationUrl(url); - } - - public static string GetFileSystemManagementDirectoryUrl(string currentRootPath, string publishementSystemDir) - { - var directoryUrl = string.Empty; - if (string.IsNullOrEmpty(currentRootPath) || !(currentRootPath.StartsWith("~/") || currentRootPath.StartsWith("@/"))) - { - currentRootPath = "@/" + currentRootPath; - } - var directoryNames = currentRootPath.Split('/'); - foreach (var directoryName in directoryNames) - { - if (!string.IsNullOrEmpty(directoryName)) - { - if (directoryName.Equals("~")) - { - directoryUrl = ApplicationPath; - } - else if (directoryName.Equals("@")) - { - directoryUrl = Combine(ApplicationPath, publishementSystemDir); - } - else - { - directoryUrl = Combine(directoryUrl, directoryName); - } - } - } - return directoryUrl; - } - - public static bool IsVirtualUrl(string url) - { - if (!string.IsNullOrEmpty(url)) - { - if (url.StartsWith("~") || url.StartsWith("@")) - { - return true; - } - } - return false; - } - - public static string GetLoadingUrl(string url) - { - return GetAdminDirectoryUrl($"loading.aspx?redirectUrl={TranslateUtils.EncryptStringBySecretKey(url)}"); - } - - public static string GetSafeHtmlFragment(string content) - { - return Microsoft.Security.Application.AntiXss.GetSafeHtmlFragment(content); - } - - /// - ///sql和xss脚本过滤 - /// - public static string FilterSqlAndXss(string objStr) - { - return FilterXss(FilterSql(objStr)); - } - - /// - /// 过滤xss攻击脚本 - /// - public static string FilterXss(string html) - { - var retval = html; - if (!string.IsNullOrEmpty(retval)) - { - retval = retval.Replace("@", "_at_"); - retval = retval.Replace("&", "_and_"); - retval = retval.Replace("#", "_sharp_"); - retval = retval.Replace(";", "_semicolon_"); - retval = retval.Replace(":", "_colon_"); - retval = retval.Replace("=", "_equal_"); - retval = retval.Replace(",", "_cn_comma_"); - retval = retval.Replace("“", "_quotel_"); - retval = retval.Replace("”", "_quoter_"); - retval = retval.Replace("/", "_slash_"); - retval = retval.Replace("|", "_or_"); - retval = retval.Replace("-", "_shortOne_"); - retval = retval.Replace(",", "_comma_"); - retval = retval.Replace("\r", "_return_"); - retval = retval.Replace("\n", "_newline_"); - - //中文标点符号 - retval = retval.Replace(";", "_cn_semicolon_"); - retval = retval.Replace(":", "_cn_colon_"); - retval = retval.Replace("。", "_cn_stop_"); - retval = retval.Replace("、", "_cn_tempstop_"); - retval = retval.Replace("?", "_cn_question_"); - retval = retval.Replace("《", "_cn_lbracket_"); - retval = retval.Replace("》", "_cn_rbracket_"); - retval = retval.Replace("‘", "_cn_rmark_"); - retval = retval.Replace("’", "_cn_lmark_"); - retval = retval.Replace("【", "_cn_slbracket_"); - retval = retval.Replace("】", "_cn_srbracket_"); - retval = retval.Replace("——", "_cn_extension_"); - retval = Microsoft.Security.Application.AntiXss.HtmlEncode(retval); - //中文标点符号 - retval = retval.Replace("_cn_semicolon_", ";"); - retval = retval.Replace("_cn_colon_", ":"); - retval = retval.Replace("_cn_stop_", "。"); - retval = retval.Replace("_cn_tempstop_", "、"); - retval = retval.Replace("_cn_question_", "?"); - retval = retval.Replace("_cn_lbracket_", "《"); - retval = retval.Replace("_cn_rbracket_", "》"); - retval = retval.Replace("_cn_rmark_", "‘"); - retval = retval.Replace("_cn_lmark_", "’"); - retval = retval.Replace("_cn_slbracket_", "【"); - retval = retval.Replace("_cn_srbracket_", "】"); - retval = retval.Replace("_cn_extension_", "——"); - - retval = retval.Replace("_at_", "@"); - retval = retval.Replace("_and_", "&"); - retval = retval.Replace("_sharp_", "#"); - retval = retval.Replace("_semicolon_", ";"); - retval = retval.Replace("_colon_", ":"); - retval = retval.Replace("_equal_", "="); - retval = retval.Replace("_cn_comma_", ","); - retval = retval.Replace("_quotel_", "“"); - retval = retval.Replace("_quoter_", "”"); - retval = retval.Replace("_slash_", "/"); - retval = retval.Replace("_or_", "|"); - retval = retval.Replace("_shortOne_", "-"); - retval = retval.Replace("_comma_", ","); - retval = retval.Replace("_return_", "\r"); - retval = retval.Replace("_newline_", "\n"); - } - return retval; - } - - /// - /// 过滤sql攻击脚本 - /// - public static string FilterSql(string objStr) - { - if (string.IsNullOrEmpty(objStr)) return string.Empty; - - var isSqlExists = false; - const string strSql = "',--,\\(,\\)"; - var strSqls = strSql.Split(','); - foreach (var sql in strSqls) - { - if (objStr.IndexOf(sql, StringComparison.Ordinal) != -1) - { - isSqlExists = true; - break; - } - } - if (isSqlExists) - { - return objStr.Replace("'", "_sqlquote_").Replace("--", "_sqldoulbeline_").Replace("\\(", "_sqlleftparenthesis_").Replace("\\)", "_sqlrightparenthesis_"); - } - return objStr; - } - - public static string UnFilterSql(string objStr) - { - if (string.IsNullOrEmpty(objStr)) return string.Empty; - - return objStr.Replace("_sqlquote_", "'").Replace("_sqldoulbeline_", "--").Replace("_sqlleftparenthesis_", "\\(").Replace("_sqlrightparenthesis_", "\\)"); - } - - public static void ResponseToJson(string jsonString) - { - HttpContext.Current.Response.Clear(); - HttpContext.Current.Response.ContentType = "text/html"; - HttpContext.Current.Response.Write(jsonString); - HttpContext.Current.Response.End(); - } - - public class Api - { - private static string GetUrl(string relatedPath, string proco) - { - return Combine(string.IsNullOrEmpty(proco) ? GetRootUrl("api") : proco, relatedPath); - } - - public static string GetSiteClearCacheUrl() - { - return GetUrl("cache/clearSiteCache", string.Empty); - } - - public static string GetUserClearCacheUrl() - { - return GetUrl("cache/removeUserCache", string.Empty); - } - - public static string GetTableStyleClearCacheUrl() - { - return GetUrl("cache/RemoveTableManagerCache", string.Empty); - } - - public static string GetUserConfigClearCacheUrl() - { - return GetUrl("cache/RemoveUserConfigCache", string.Empty); - } - } - - public static void ResponseScripts(Page page, string scripts) - { - page.Response.Clear(); - page.Response.Write($""); - //page.Response.End(); - } - - - public static string GetRedirectStringWithCheckBoxValue(string redirectUrl, string checkBoxServerId, string checkBoxClientId, string emptyAlertText) - { - return - $@"if (!_alertCheckBoxCollection(document.getElementsByName('{checkBoxClientId}'), '{emptyAlertText}')){{_goto('{redirectUrl}' + '&{checkBoxServerId}=' + _getCheckBoxCollectionValue(document.getElementsByName('{checkBoxClientId}')));}};return false;"; - } - - public static string GetRedirectStringWithCheckBoxValueAndAlert(string redirectUrl, string checkBoxServerId, string checkBoxClientId, string emptyAlertText, string confirmAlertText) - { - return - $@"_confirmCheckBoxCollection(document.getElementsByName('{checkBoxClientId}'), '{emptyAlertText}', '{confirmAlertText}', '{redirectUrl}' + '&{checkBoxServerId}=' + _getCheckBoxCollectionValue(document.getElementsByName('{checkBoxClientId}')));return false;"; - } - - public static string GetRedirectStringWithConfirm(string redirectUrl, string confirmString) - { - return $@"_confirm('{confirmString}', '{redirectUrl}');return false;"; - } - - public static string GetRedirectString(string redirectUrl) - { - return $@"window.location.href='{redirectUrl}';return false;"; - } - } -} diff --git a/SiteServer.Utils/Pair.cs b/SiteServer.Utils/Pair.cs deleted file mode 100644 index 07480e1d3..000000000 --- a/SiteServer.Utils/Pair.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace SiteServer.Utils -{ - public class Pair - { - public Pair(string key, object value) - { - Key = key; - Value = value; - } - - public string Key { get; } - - public object Value { get; } - } -} diff --git a/SiteServer.Utils/PairList.cs b/SiteServer.Utils/PairList.cs deleted file mode 100644 index 9e7dec9cb..000000000 --- a/SiteServer.Utils/PairList.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace SiteServer.Utils -{ - public class PairList - { - private readonly List _list = new List(); - - public Pair GetPair(string key) - { - return _list.FirstOrDefault(pair => pair != null && pair.Key == key); - } - - public object GetValue(string key) - { - object value = null; - var pair = GetPair(key); - if (pair != null) - { - value = pair.Value; - } - return value; - } - - public void Add(Pair pair) - { - _list.Add(pair); - } - - public void Insert(int index, Pair pair) - { - _list.Insert(index, pair); - } - - public List Keys - { - get - { - return _list.Select(pair => pair.Key).ToList(); - } - } - - public bool ContainsKey(string key) - { - return _list.Any(pair => pair.Key == key); - } - - public List GetKeys(string startKey) - { - return (from pair in _list where pair.Key.StartsWith(startKey) select pair.Key).ToList(); - } - } -} \ No newline at end of file diff --git a/SiteServer.Utils/PathUtils.cs b/SiteServer.Utils/PathUtils.cs deleted file mode 100644 index 2cda95231..000000000 --- a/SiteServer.Utils/PathUtils.cs +++ /dev/null @@ -1,363 +0,0 @@ -using System.IO; -using System.Web; -using System.Text.RegularExpressions; -using System; -using System.Linq; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.Utils -{ - public class PathUtils - { - public const char SeparatorChar = '\\'; - public static readonly char[] InvalidPathChars = Path.GetInvalidPathChars(); - - public static string Combine(params string[] paths) - { - var retval = string.Empty; - if (paths != null && paths.Length > 0) - { - retval = paths[0]?.Replace(PageUtils.SeparatorChar, SeparatorChar).TrimEnd(SeparatorChar) ?? string.Empty; - for (var i = 1; i < paths.Length; i++) - { - var path = paths[i] != null ? paths[i].Replace(PageUtils.SeparatorChar, SeparatorChar).Trim(SeparatorChar) : string.Empty; - retval = Path.Combine(retval, path); - } - } - return retval; - } - - public static string GetCurrentFileNameWithoutExtension() - { - if (HttpContext.Current != null) - { - return Path.GetFileNameWithoutExtension(HttpContext.Current.Request.PhysicalPath); - } - return string.Empty; - } - - /// - /// 根据路径扩展名判断是否为文件夹路径 - /// - /// - /// - public static bool IsDirectoryPath(string path) - { - var retval = false; - if (!string.IsNullOrEmpty(path)) - { - var ext = Path.GetExtension(path); - if (string.IsNullOrEmpty(ext)) //path为文件路径 - { - retval = true; - } - } - return retval; - } - - public static bool IsEquals(string path1, string path2) - { - if (string.IsNullOrEmpty(path1) || string.IsNullOrEmpty(path2)) return false; - return string.Equals(Path.GetFullPath(path1), Path.GetFullPath(path2), StringComparison.OrdinalIgnoreCase); - } - - public static bool IsSystemPath(string path) - { - return DirectoryUtils.IsInDirectory(Combine(WebConfigUtils.PhysicalApplicationPath, DirectoryUtils.AspnetClient.DirectoryName), path) - || DirectoryUtils.IsInDirectory(Combine(WebConfigUtils.PhysicalApplicationPath, DirectoryUtils.Bin.DirectoryName), path) - || DirectoryUtils.IsInDirectory(Combine(WebConfigUtils.PhysicalApplicationPath, DirectoryUtils.SiteFiles.DirectoryName), path) - || DirectoryUtils.IsInDirectory(Combine(WebConfigUtils.PhysicalApplicationPath, WebConfigUtils.AdminDirectory), path) - || IsEquals(Combine(WebConfigUtils.PhysicalApplicationPath, "web.config"), path) - || IsEquals(Combine(WebConfigUtils.PhysicalApplicationPath, "Global.asax"), path); - } - - public static string GetExtension(string path) - { - var retval = string.Empty; - if (!string.IsNullOrEmpty(path)) - { - path = path.Trim('/', '\\').Trim(); - try - { - retval = Path.GetExtension(path); - } - catch - { - // ignored - } - } - return retval; - } - - public static string RemoveExtension(string fileName) - { - var retval = string.Empty; - if (!string.IsNullOrEmpty(fileName)) - { - var index = fileName.LastIndexOf('.'); - retval = index != -1 ? fileName.Substring(0, index) : fileName; - } - return retval; - } - - public static string RemoveParentPath(string path) - { - var retval = string.Empty; - if (!string.IsNullOrEmpty(path)) - { - retval = path.Replace("../", string.Empty); - retval = retval.Replace("./", string.Empty); - } - return retval; - } - - public static string GetFileName(string filePath) - { - return Path.GetFileName(filePath); - } - - public static string GetFileNameWithoutExtension(string filePath) - { - return Path.GetFileNameWithoutExtension(filePath); - } - - public static string GetDirectoryName(string path, bool isFile) - { - if (string.IsNullOrWhiteSpace(path)) return string.Empty; - - if (isFile) - { - path = Path.GetDirectoryName(path); - } - if (!string.IsNullOrEmpty(path)) - { - var directoryInfo = new DirectoryInfo(path); - return directoryInfo.Name; - } - return string.Empty; - } - - public static string GetDirectoryDifference(string rootDirectoryPath, string path) - { - var directoryPath = DirectoryUtils.GetDirectoryPath(path); - if (!string.IsNullOrEmpty(directoryPath) && StringUtils.StartsWithIgnoreCase(directoryPath, rootDirectoryPath)) - { - var retval = directoryPath.Substring(rootDirectoryPath.Length, directoryPath.Length - rootDirectoryPath.Length); - return retval.Trim('/', '\\'); - } - return string.Empty; - } - - public static string GetPathDifference(string rootPath, string path) - { - if (!string.IsNullOrEmpty(path) && StringUtils.StartsWithIgnoreCase(path, rootPath)) - { - var retval = path.Substring(rootPath.Length, path.Length - rootPath.Length); - return retval.Trim('/', '\\'); - } - return string.Empty; - } - - public static string AddVirtualToPath(string path) - { - var resolvedPath = path; - if (!string.IsNullOrEmpty(path)) - { - path = path.Replace("../", string.Empty); - if (!path.StartsWith("~")) - { - resolvedPath = "~" + path; - } - } - return resolvedPath; - } - - public static string GetCurrentPagePath() - { - if (HttpContext.Current != null) - { - return HttpContext.Current.Request.PhysicalPath; - } - return string.Empty; - } - - public static string GetSiteFilesPath(params string[] paths) - { - return MapPath(Combine("~/" + DirectoryUtils.SiteFiles.DirectoryName, Combine(paths))); - } - - public static string GetBinDirectoryPath(string relatedPath) - { - relatedPath = RemoveParentPath(relatedPath); - return Combine(WebConfigUtils.PhysicalApplicationPath, DirectoryUtils.Bin.DirectoryName, relatedPath); - } - - public static string GetAdminDirectoryPath(string relatedPath) - { - relatedPath = RemoveParentPath(relatedPath); - return Combine(WebConfigUtils.PhysicalApplicationPath, WebConfigUtils.AdminDirectory, relatedPath); - } - - public static string PluginsPath => GetSiteFilesPath(DirectoryUtils.SiteFiles.Plugins); - - public static string GetPluginPath(string pluginId, params string[] paths) - { - return GetSiteFilesPath(DirectoryUtils.SiteFiles.Plugins, pluginId, Combine(paths)); - } - - public static string GetPluginNuspecPath(string pluginId) - { - return GetPluginPath(pluginId, pluginId + ".nuspec"); - } - - public static string GetPluginDllDirectoryPath(string pluginId) - { - var fileName = pluginId + ".dll"; - - if (FileUtils.IsFileExists(GetPluginPath(pluginId, "Bin", fileName))) - { - return GetPluginPath(pluginId, "Bin"); - } - if (FileUtils.IsFileExists(GetPluginPath(pluginId, "Bin", "Debug", fileName))) - { - return GetPluginPath(pluginId, "Bin", "Debug"); - } - if (FileUtils.IsFileExists(GetPluginPath(pluginId, "Bin", "Release", fileName))) - { - return GetPluginPath(pluginId, "Bin", "Release"); - } - - return string.Empty; - } - - public static string GetPackagesPath(params string[] paths) - { - return GetSiteFilesPath(DirectoryUtils.SiteFiles.Packages, Combine(paths)); - } - - public static string RemovePathInvalidChar(string filePath) - { - if (string.IsNullOrEmpty(filePath)) - return filePath; - var invalidChars = new string(Path.GetInvalidPathChars()); - string invalidReStr = $"[{Regex.Escape(invalidChars)}]"; - return Regex.Replace(filePath, invalidReStr, ""); - } - - public static string MapPath(string virtualPath) - { - virtualPath = RemovePathInvalidChar(virtualPath); - string retval; - if (!string.IsNullOrEmpty(virtualPath)) - { - if (virtualPath.StartsWith("~")) - { - virtualPath = virtualPath.Substring(1); - } - virtualPath = PageUtils.Combine("~", virtualPath); - } - else - { - virtualPath = "~/"; - } - if (HttpContext.Current != null) - { - retval = HttpContext.Current.Server.MapPath(virtualPath); - } - else - { - var rootPath = WebConfigUtils.PhysicalApplicationPath; - - virtualPath = !string.IsNullOrEmpty(virtualPath) ? virtualPath.Substring(2) : string.Empty; - retval = Combine(rootPath, virtualPath); - } - - if (retval == null) retval = string.Empty; - return retval.Replace("/", "\\"); - } - - public static bool IsFileExtenstionAllowed(string sAllowedExt, string sExt) - { - if (sExt != null && sExt.StartsWith(".")) - { - sExt = sExt.Substring(1, sExt.Length - 1); - } - sAllowedExt = sAllowedExt.Replace("|", ","); - var aExt = sAllowedExt.Split(','); - return aExt.Any(t => StringUtils.EqualsIgnoreCase(sExt, t)); - } - - public static bool IsFileExtenstionNotAllowed(string sNotAllowedExt, string sExt) - { - if (sExt != null && sExt.StartsWith(".")) - { - sExt = sExt.Substring(1, sExt.Length - 1); - } - sNotAllowedExt = sNotAllowedExt.Replace("|", ","); - var aExt = sNotAllowedExt.Split(','); - return aExt.All(t => !StringUtils.EqualsIgnoreCase(sExt, t)); - } - - public static string GetClientUserPath(string applicationName, string userName, string relatedPath) - { - string systemName; - if (!string.IsNullOrEmpty(applicationName) && applicationName.IndexOf("_", StringComparison.Ordinal) != -1) - { - systemName = applicationName.Split('_')[1]; - } - else - { - systemName = applicationName; - } - return GetSiteFilesPath($"{DirectoryUtils.SiteFiles.UserFiles}/{userName}/{systemName}/{relatedPath}"); - } - - public static string GetTemporaryFilesPath(string relatedPath) - { - return Combine(WebConfigUtils.PhysicalApplicationPath, DirectoryUtils.SiteFiles.DirectoryName, DirectoryUtils.SiteFiles.TemporaryFiles, relatedPath); - } - - public static string GetMenusPath(params string[] paths) - { - return Combine(SiteServerAssets.GetPath("menus"), Combine(paths)); - } - - public static string GetUserFilesPath(string userName, string relatedPath) - { - return Combine(WebConfigUtils.PhysicalApplicationPath, DirectoryUtils.SiteFiles.DirectoryName, DirectoryUtils.SiteFiles.UserFiles, userName, relatedPath); - } - - public static string GetUserUploadDirectoryPath(string userName) - { - string directoryPath; - var dateFormatType = EDateFormatType.Month; - var datetime = DateTime.Now; - var userFilesPath = GetUserFilesPath(userName, string.Empty); - if (dateFormatType == EDateFormatType.Year) - { - directoryPath = Combine(userFilesPath, datetime.Year.ToString()); - } - else if (dateFormatType == EDateFormatType.Day) - { - directoryPath = Combine(userFilesPath, datetime.Year.ToString(), datetime.Month.ToString(), datetime.Day.ToString()); - } - else - { - directoryPath = Combine(userFilesPath, datetime.Year.ToString(), datetime.Month.ToString()); - } - DirectoryUtils.CreateDirectoryIfNotExists(directoryPath); - return directoryPath; - } - - public static string GetUserUploadFileName(string filePath) - { - var dt = DateTime.Now; - string strDateTime = $"{dt.Day}{dt.Hour}{dt.Minute}{dt.Second}{dt.Millisecond}"; - return $"{strDateTime}{GetExtension(filePath)}"; - } - - public static string PhysicalSiteServerPath => Combine(WebConfigUtils.PhysicalApplicationPath, WebConfigUtils.AdminDirectory); - - public static string PhysicalSiteFilesPath => Combine(WebConfigUtils.PhysicalApplicationPath, DirectoryUtils.SiteFiles.DirectoryName); - } -} diff --git a/SiteServer.Utils/Properties/AssemblyInfo.cs b/SiteServer.Utils/Properties/AssemblyInfo.cs deleted file mode 100644 index 3c0664485..000000000 --- a/SiteServer.Utils/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,37 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// 有关程序集的一般信息由以下 -// 控制。更改这些特性值可修改 -// 与程序集关联的信息。 -[assembly: AssemblyTitle("SiteServer.Utils")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("SiteServer.Utils")] -[assembly: AssemblyCopyright("Copyright © 2018")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// 将 ComVisible 设置为 false 会使此程序集中的类型 -//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 -//请将此类型的 ComVisible 特性设置为 true。 -[assembly: ComVisible(false)] - -// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID -[assembly: Guid("f19a6f6d-d96a-415e-b1d0-f3ad6f6067a3")] - -// 程序集的版本信息由下列四个值组成: -// -// 主版本 -// 次版本 -// 生成号 -// 修订号 -// -// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 -//通过使用 "*",如下所示: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.0.0")] -[assembly: AssemblyFileVersion("0.0.0")] -[assembly: AssemblyInformationalVersion("0.0.0")] diff --git a/SiteServer.Utils/RegexUtils.cs b/SiteServer.Utils/RegexUtils.cs deleted file mode 100644 index bd80c0cf4..000000000 --- a/SiteServer.Utils/RegexUtils.cs +++ /dev/null @@ -1,263 +0,0 @@ -using System; -using System.Text.RegularExpressions; -using System.Collections.Generic; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.Utils -{ - public class RegexUtils - { - - /* - * 通用:.*? - * 所有链接:[^"]*)"|'(?[^']*)'|(?\S+)).*?> - * */ - - public static RegexOptions Options = ((RegexOptions.Singleline | RegexOptions.IgnoreCase) | RegexOptions.IgnorePatternWhitespace); - - public static List GetImageSrcs(string baseUrl, string html) - { - const string regex = "(img|input)[^><]*\\s+src\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*))"; - return GetUrls(regex, html, baseUrl); - } - - public static List GetOriginalImageSrcs(string html) - { - const string regex = "(img|input)[^><]*\\s+src\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*))"; - return GetContents("url", regex, html); - } - - public static List GetOriginalLinkHrefs(string html) - { - const string regex = "a[^><]*\\s+href\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*))"; - return GetContents("url", regex, html); - } - - public static List GetFlashSrcs(string baseUrl, string html) - { - const string regex = "embed\\s+[^><]*src\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*))|param\\s+[^><]*value\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*))"; - return GetUrls(regex, html, baseUrl); - } - - public static List GetOriginalFlashSrcs(string html) - { - const string regex = "embed\\s+[^><]*src\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*))|param\\s+[^><]*value\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*))"; - return GetContents("url", regex, html); - } - - public static List GetStyleImageUrls(string baseUrl, string html) - { - const string regex = "url\\((?[^\\(\\)]*)\\)"; - var arraylist = GetUrls(regex, html, baseUrl); - var list = new List(); - foreach (var url in arraylist) - { - if (!list.Contains(url) && EFileSystemTypeUtils.IsImage(PathUtils.GetExtension(url))) - { - list.Add(url); - } - } - return list; - } - - public static List GetOriginalStyleImageUrls(string html) - { - //background-image: url(../images/leftline.gif); - const string regex = "url\\((?[^\\(\\)]*)\\)"; - var arraylist = GetContents("url", regex, html); - var list = new List(); - foreach (var url in arraylist) - { - if (!list.Contains(url) && EFileSystemTypeUtils.IsImage(PathUtils.GetExtension(url))) - { - list.Add(url); - } - } - return list; - } - - public static List GetBackgroundImageSrcs(string baseUrl, string html) - { - const string regex = "background\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*))"; - return GetUrls(regex, html, baseUrl); - } - - public static List GetOriginalBackgroundImageSrcs(string html) - { - const string regex = "background\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*))"; - return GetContents("url", regex, html); - } - - public static List GetCssHrefs(string baseUrl, string html) - { - //string regex = "link\\s+[^><]*href\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?\\S+))|@import\\s*url\\((?:\"(?[^\"]*)\"|'(?[^']*)'|(?\\S+))\\)"; - const string regex = "link\\s+[^><]*href\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*))|\\@import\\s*url\\s*\\(\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?.*?))\\s*\\)"; - return GetUrls(regex, html, baseUrl); - } - - public static List GetOriginalCssHrefs(string html) - { - const string regex = "link\\s+[^><]*href\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*))|\\@import\\s*url\\s*\\(\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?.*?))\\s*\\)"; - return GetContents("url", regex, html); - } - - public static List GetScriptSrcs(string baseUrl, string html) - { - const string regex = "script\\s+[^><]*src\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*))"; - return GetUrls(regex, html, baseUrl); - } - - public static List GetOriginalScriptSrcs(string html) - { - const string regex = "script\\s+[^><]*src\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*))"; - return GetContents("url", regex, html); - } - - public static List GetTagInnerContents(string tagName, string html) - { - string regex = $"<{tagName}\\s+[^><]*>\\s*(?[\\s\\S]+?)\\s*"; - return GetContents("content", regex, html); - } - - public static List GetTagContents(string tagName, string html) - { - var list = new List(); - - string regex = $@"<({tagName})[^>]*>(.*?)|<{tagName}[^><]*/>"; - - var matches = Regex.Matches(html, regex, RegexOptions.IgnoreCase); - foreach (Match match in matches) - { - if (match.Success) - { - list.Add(match.Result("$0")); - } - } - - return list; - } - - public static string GetTagName(string html) - { - var match = Regex.Match(html, "<([^>\\s]+)[\\s\\SS]*>", RegexOptions.IgnoreCase); - return match.Success ? match.Result("$1") : string.Empty; - } - - public static string GetInnerContent(string tagName, string html) - { - string regex = $"<{tagName}[^><]*>(?[\\s\\S]+?)"; - return GetContent("content", regex, html); - } - - public static string GetAttributeContent(string attributeName, string html) - { - string regex = - $"<[^><]+\\s*{attributeName}\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*)).*?>"; - return GetContent("value", regex, html); - } - - public static List GetUrls(string html, string baseUrl) - { - const string regex = "[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*)).*?>"; - return GetUrls(regex, html, baseUrl); - } - - public static List GetUrls(string regex, string html, string baseUrl) - { - var list = new List(); - if (string.IsNullOrEmpty(regex)) - { - regex = "[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*)).*?>"; - } - var groupName = "url"; - var arraylist = GetContents(groupName, regex, html); - foreach (var rawUrl in arraylist) - { - var url = PageUtils.GetUrlByBaseUrl(rawUrl, baseUrl); - if (!string.IsNullOrEmpty(url) && !list.Contains(url)) - { - list.Add(url); - } - } - return list; - } - - public static string GetUrl(string regex, string html, string baseUrl) - { - return PageUtils.GetUrlByBaseUrl(GetContent("url", regex, html), baseUrl); - } - - public static string GetContent(string groupName, string regex, string html) - { - var content = string.Empty; - if (string.IsNullOrEmpty(regex)) return content; - if (regex.IndexOf("<" + groupName + ">", StringComparison.Ordinal) == -1) - { - return regex; - } - - var reg = new Regex(regex, Options); - var match = reg.Match(html); - if (match.Success) - { - content = match.Groups[groupName].Value; - } - - return content; - } - - public static string Replace(string regex, string input, string replacement) - { - if (string.IsNullOrEmpty(input)) return input; - var reg = new Regex(regex, Options); - return reg.Replace(input, replacement); - } - - public static string Replace(string regex, string input, string replacement, int count) - { - if (count == 0) - { - return Replace(regex, input, replacement); - } - if (string.IsNullOrEmpty(input)) return input; - var reg = new Regex(regex, Options); - return reg.Replace(input, replacement, count); - } - - public static bool IsMatch(string regex, string input) - { - var reg = new Regex(regex, Options); - return reg.IsMatch(input); - } - - public static List GetContents(string groupName, string regex, string html) - { - if (string.IsNullOrEmpty(regex)) return new List(); - - var list = new List(); - var reg = new Regex(regex, Options); - - for (var match = reg.Match(html); match.Success; match = match.NextMatch()) - { - var theValue = match.Groups[groupName].Value; - if (!list.Contains(theValue)) - { - list.Add(theValue); - } - } - return list; - } - - public static string RemoveScripts(string html) - { - const string regex = "<]*>.*?<\\/script>"; - return Replace(regex, html, string.Empty); - } - - public static string RemoveImages(string html) - { - const string regex = "<]*>"; - return Replace(regex, html, string.Empty); - } - } -} diff --git a/SiteServer.Utils/Rss/Collections/ExceptionCollection.cs b/SiteServer.Utils/Rss/Collections/ExceptionCollection.cs deleted file mode 100644 index 779035921..000000000 --- a/SiteServer.Utils/Rss/Collections/ExceptionCollection.cs +++ /dev/null @@ -1,103 +0,0 @@ -/* ExceptionCollection.cs - * ====================== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; -using System.Collections; - -namespace SiteServer.Utils.Rss -{ - /// A strongly typed collection of objects - [SerializableAttribute()] - public class ExceptionCollection : CollectionBase - { - private Exception lastException = null; - - /// Gets or sets the exception at a specified index.In C#, this property is the indexer for the class. - /// The index of the collection to access. - /// A exception at each valid index. - /// This method is an indexer that can be used to access the collection. - public Exception this[int index] - { - get { return ((Exception)(List[index])); } - set { List[index] = value; } - } - /// Adds a specified exception to this collection. - /// The exception to add. - /// The zero-based index of the added exception -or- -1 if the exception already exists. - public int Add(Exception exception) - { - foreach(Exception e in List) - if (e.Message == exception.Message) - return -1; - lastException = exception; - return List.Add(exception); - } - /// Determines whether the ExceptionCollection contains a specific element. - /// The Exception to locate in the ExceptionCollection. - /// true if the ExceptionCollection contains the specified value; otherwise, false. - public bool Contains(Exception exception) - { - return List.Contains(exception); - } - /// Copies the entire ExceptionCollection to a compatible one-dimensional , starting at the specified index of the target array. - /// The one-dimensional Exception Array that is the destination of the elements copied from ExceptionCollection. The Array must have zero-based indexing. - /// The zero-based index in array at which copying begins. - /// array is a null reference (Nothing in Visual Basic). - /// index is less than zero. - /// array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source ExceptionCollection is greater than the available space from index to the end of the destination array. - public void CopyTo(Exception[] array, int index) - { - List.CopyTo(array, index); - } - /// Searches for the specified Exception and returns the zero-based index of the first occurrence within the entire ExceptionCollection. - /// The Exception to locate in the ExceptionCollection. - /// The zero-based index of the first occurrence of RssChannel within the entire ExceptionCollection, if found; otherwise, -1. - public int IndexOf(Exception exception) - { - return List.IndexOf(exception); - } - /// Inserts an Exception into this collection at a specified index. - /// The zero-based index of the collection at which to insert the Exception. - /// The Exception to insert into this collection. - public void Insert(int index, Exception exception) - { - List.Insert(index, exception); - } - - /// Removes a specified Exception from this collection. - /// The Exception to remove. - public void Remove(Exception exception) - { - List.Remove(exception); - } - /// Returns the last exception added through the Add method. - /// The last exception -or- null if no exceptions exist - public Exception LastException => lastException; - } -} diff --git a/SiteServer.Utils/Rss/Collections/RssCategoryCollection.cs b/SiteServer.Utils/Rss/Collections/RssCategoryCollection.cs deleted file mode 100644 index 5c38fe2f1..000000000 --- a/SiteServer.Utils/Rss/Collections/RssCategoryCollection.cs +++ /dev/null @@ -1,95 +0,0 @@ -/* RssCategoryCollection.cs - * ======================== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; -using System.Collections; - -namespace SiteServer.Utils.Rss -{ - /// A strongly typed collection of objects - [SerializableAttribute()] - public class RssCategoryCollection : CollectionBase - { - /// Gets or sets the category at a specified index.In C#, this property is the indexer for the class. - /// The index of the collection to access. - /// A category at each valid index. - /// This method is an indexer that can be used to access the collection. - /// index is not a valid index. - public RssCategory this[int index] - { - get { return ((RssCategory)(List[index])); } - set { List[index] = value; } - } - /// Adds a specified category to this collection. - /// The category to add. - /// The zero-based index of the added category. - public int Add(RssCategory rssCategory) - { - return List.Add(rssCategory); - } - /// Determines whether the RssCategoryCollection contains a specific element. - /// The RssCategory to locate in the RssCategoryCollection. - /// true if the RssCategoryCollection contains the specified value; otherwise, false. - public bool Contains(RssCategory rssCategory) - { - return List.Contains(rssCategory); - } - /// Copies the entire RssCategoryCollection to a compatible one-dimensional , starting at the specified index of the target array. - /// The one-dimensional RssCategory Array that is the destination of the elements copied from RssCategoryCollection. The Array must have zero-based indexing. - /// The zero-based index in array at which copying begins. - /// array is a null reference (Nothing in Visual Basic). - /// index is less than zero. - /// array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssCategoryCollection is greater than the available space from index to the end of the destination array. - public void CopyTo(RssCategory[] array, int index) - { - List.CopyTo(array, index); - } - /// Searches for the specified RssCategory and returns the zero-based index of the first occurrence within the entire RssCategoryCollection. - /// The RssCategory to locate in the RssCategoryCollection. - /// The zero-based index of the first occurrence of RssCategory within the entire RssCategoryCollection, if found; otherwise, -1. - public int IndexOf(RssCategory rssCategory) - { - return List.IndexOf(rssCategory); - } - /// Inserts an category into this collection at a specified index. - /// The zero-based index of the collection at which to insert the category. - /// The category to insert into this collection. - public void Insert(int index, RssCategory rssCategory) - { - List.Insert(index, rssCategory); - } - - /// Removes a specified category from this collection. - /// The category to remove. - public void Remove(RssCategory rssCategory) - { - List.Remove(rssCategory); - } - } -} diff --git a/SiteServer.Utils/Rss/Collections/RssChannelCollection.cs b/SiteServer.Utils/Rss/Collections/RssChannelCollection.cs deleted file mode 100644 index 8999cdab8..000000000 --- a/SiteServer.Utils/Rss/Collections/RssChannelCollection.cs +++ /dev/null @@ -1,94 +0,0 @@ -/* RssChannelCollection.cs - * ======================= - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; -using System.Collections; - -namespace SiteServer.Utils.Rss -{ - /// A strongly typed collection of objects - [SerializableAttribute()] - public class RssChannelCollection : CollectionBase - { - /// Gets or sets the channel at a specified index.In C#, this property is the indexer for the class. - /// The index of the collection to access. - /// A channel at each valid index. - /// This method is an indexer that can be used to access the collection. - /// index is not a valid index. - public RssChannel this[int index] - { - get { return ((RssChannel)(List[index])); } - set { List[index] = value; } - } - /// Adds a specified channel to this collection. - /// The channel to add. - /// The zero-based index of the added channel. - public int Add(RssChannel channel) - { - return List.Add(channel); - } - /// Determines whether the RssChannelCollection contains a specific element. - /// The RssChannel to locate in the RssChannelCollection. - /// true if the RssChannelCollection contains the specified value; otherwise, false. - public bool Contains(RssChannel rssChannel) - { - return List.Contains(rssChannel); - } - /// Copies the entire RssChannelCollection to a compatible one-dimensional , starting at the specified index of the target array. - /// The one-dimensional RssChannel Array that is the destination of the elements copied from RssChannelCollection. The Array must have zero-based indexing. - /// The zero-based index in array at which copying begins. - /// array is a null reference (Nothing in Visual Basic). - /// index is less than zero. - /// array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssChannelCollection is greater than the available space from index to the end of the destination array. - public void CopyTo(RssChannel[] array, int index) - { - List.CopyTo(array, index); - } - /// Searches for the specified RssChannel and returns the zero-based index of the first occurrence within the entire RssChannelCollection. - /// The RssChannel to locate in the RssChannelCollection. - /// The zero-based index of the first occurrence of RssChannel within the entire RssChannelCollection, if found; otherwise, -1. - public int IndexOf(RssChannel rssChannel) - { - return List.IndexOf(rssChannel); - } - /// Inserts a channel into this collection at a specified index. - /// The zero-based index of the collection at which to insert the channel. - /// The channel to insert into this collection. - public void Insert(int index, RssChannel channel) - { - List.Insert(index, channel); - } - /// Removes a specified channel from this collection. - /// The channel to remove. - public void Remove(RssChannel channel) - { - List.Remove(channel); - } - } -} diff --git a/SiteServer.Utils/Rss/Collections/RssFeedCollection.cs b/SiteServer.Utils/Rss/Collections/RssFeedCollection.cs deleted file mode 100644 index 0c667e371..000000000 --- a/SiteServer.Utils/Rss/Collections/RssFeedCollection.cs +++ /dev/null @@ -1,113 +0,0 @@ -/* RssFeedCollection.cs - * ==================== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; -using System.Collections; - -namespace SiteServer.Utils.Rss -{ - /// A strongly typed collection of objects - [SerializableAttribute()] - public class RssFeedCollection : CollectionBase - { - /// Gets or sets the feed at a specified index.In C#, this property is the indexer for the class. - /// The index of the collection to access. - /// A feed at each valid index. - /// This method is an indexer that can be used to access the collection. - /// index is not a valid index. - public RssFeed this[int index] - { - get { return ((RssFeed)(List[index])); } - set { List[index] = value; } - } - /// Gets or sets the feed with the given name.In C#, this property is the indexer for the class. - /// The url of the feed to access. - /// A feed at each valid url. If the feed does not exist, null. - /// This method is an indexer that can be used to access the collection. - public RssFeed this[string url] - { - get - { - for (var i=0; iAdds a specified feed to this collection. - /// The feed to add. - /// The zero-based index of the added feed. - public int Add(RssFeed feed) - { - return List.Add(feed); - } - /// Determines whether the RssFeedCollection contains a specific element. - /// The RssFeed to locate in the RssFeedCollection. - /// true if the RssFeedCollection contains the specified value; otherwise, false. - public bool Contains(RssFeed rssFeed) - { - return List.Contains(rssFeed); - } - /// Copies the entire RssFeedCollection to a compatible one-dimensional , starting at the specified index of the target array. - /// The one-dimensional RssFeed Array that is the destination of the elements copied from RssFeedCollection. The Array must have zero-based indexing. - /// The zero-based index in array at which copying begins. - /// array is a null reference (Nothing in Visual Basic). - /// index is less than zero. - /// array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssFeedCollection is greater than the available space from index to the end of the destination array. - public void CopyTo(RssFeed[] array, int index) - { - List.CopyTo(array, index); - } - /// Searches for the specified RssFeed and returns the zero-based index of the first occurrence within the entire RssFeedCollection. - /// The RssFeed to locate in the RssFeedCollection. - /// The zero-based index of the first occurrence of RssFeed within the entire RssFeedCollection, if found; otherwise, -1. - public int IndexOf(RssFeed rssFeed) - { - return List.IndexOf(rssFeed); - } - /// Inserts a feed into this collection at a specified index. - /// The zero-based index of the collection at which to insert the feed. - /// The feed to insert into this collection. - public void Insert(int index, RssFeed feed) - { - List.Insert(index, feed); - } - - /// Removes a specified category from this collection. - /// The category to remove. - public void Remove(RssFeed feed) - { - List.Remove(feed); - } - } -} diff --git a/SiteServer.Utils/Rss/Collections/RssItemCollection.cs b/SiteServer.Utils/Rss/Collections/RssItemCollection.cs deleted file mode 100644 index 91b319b86..000000000 --- a/SiteServer.Utils/Rss/Collections/RssItemCollection.cs +++ /dev/null @@ -1,138 +0,0 @@ -/* RssItemCollection.cs - * ==================== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// A strongly typed collection of objects - public class RssItemCollection : System.Collections.CollectionBase - { - private DateTime latestPubDate = RssDefault.DateTime; - private DateTime oldestPubDate = RssDefault.DateTime; - private bool pubDateChanged = true; - /// Gets or sets the item at a specified index.In C#, this property is the indexer for the class. - /// The index of the collection to access. - /// An item at each valid index. - /// This method is an indexer that can be used to access the collection. - /// index is not a valid index. - public RssItem this[int index] - { - get { return ((RssItem)(List[index])); } - set - { - pubDateChanged = true; - List[index] = value; - } - } - /// Adds a specified item to this collection. - /// The item to add. - /// The zero-based index of the added item. - public int Add(RssItem item) - { - pubDateChanged = true; - return List.Add(item); - } - /// Determines whether the RssItemCollection contains a specific element. - /// The RssItem to locate in the RssItemCollection. - /// true if the RssItemCollection contains the specified value; otherwise, false. - public bool Contains(RssItem rssItem) - { - return List.Contains(rssItem); - } - /// Copies the entire RssItemCollection to a compatible one-dimensional , starting at the specified index of the target array. - /// The one-dimensional RssItem Array that is the destination of the elements copied from RssItemCollection. The Array must have zero-based indexing. - /// The zero-based index in array at which copying begins. - /// array is a null reference (Nothing in Visual Basic). - /// index is less than zero. - /// array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssItemCollection is greater than the available space from index to the end of the destination array. - public void CopyTo(RssItem[] array, int index) - { - List.CopyTo(array, index); - } - /// Searches for the specified RssItem and returns the zero-based index of the first occurrence within the entire RssItemCollection. - /// The RssItem to locate in the RssItemCollection. - /// The zero-based index of the first occurrence of RssItem within the entire RssItemCollection, if found; otherwise, -1. - public int IndexOf(RssItem rssItem) - { - return List.IndexOf(rssItem); - } - /// Inserts an item into this collection at a specified index. - /// The zero-based index of the collection at which to insert the item. - /// The item to insert into this collection. - public void Insert(int index, RssItem item) - { - pubDateChanged = true; - List.Insert(index, item); - } - /// Removes a specified item from this collection. - /// The item to remove. - public void Remove(RssItem item) - { - pubDateChanged = true; - List.Remove(item); - } - /// The latest pubDate in the items collection - /// The latest pubDate -or- RssDefault.DateTime if all item pubDates are not defined - public DateTime LatestPubDate() - { - CalculatePubDates(); - return latestPubDate; - } - /// The oldest pubDate in the items collection - /// The oldest pubDate -or- RssDefault.DateTime if all item pubDates are not defined - public DateTime OldestPubDate() - { - CalculatePubDates(); - return oldestPubDate; - } - /// Calculates the oldest and latest pubdates - private void CalculatePubDates() - { - if (pubDateChanged) - { - pubDateChanged = false; - latestPubDate = DateTime.MinValue; - oldestPubDate = DateTime.MaxValue; - - foreach(RssItem item in List) - if ((item.PubDate != RssDefault.DateTime) & (item.PubDate > latestPubDate)) - latestPubDate = item.PubDate; - if (latestPubDate == DateTime.MinValue) - latestPubDate = RssDefault.DateTime; - - foreach(RssItem item in List) - if ((item.PubDate != RssDefault.DateTime) & (item.PubDate < oldestPubDate)) - oldestPubDate = item.PubDate; - if (oldestPubDate == DateTime.MaxValue) - oldestPubDate = RssDefault.DateTime; - } - } - } -} diff --git a/SiteServer.Utils/Rss/Collections/RssModuleCollection.cs b/SiteServer.Utils/Rss/Collections/RssModuleCollection.cs deleted file mode 100644 index bfb8cb2ae..000000000 --- a/SiteServer.Utils/Rss/Collections/RssModuleCollection.cs +++ /dev/null @@ -1,98 +0,0 @@ -/* RssModuleCollection.cs - * ====================== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// A strongly typed collection of objects - public class RssModuleCollection : System.Collections.CollectionBase - { - /// Gets or sets the item at a specified index.In C#, this property is the indexer for the class. - /// The index of the collection to access. - /// An item at each valid index. - /// This method is an indexer that can be used to access the collection. - /// index is not a valid index. - public RssModule this[int index] - { - get { return ((RssModule)(List[index])); } - set { List[index] = value; } - } - - /// Adds a specified item to this collection. - /// The item to add. - /// The zero-based index of the added item. - public int Add(RssModule rssModule) - { - return List.Add(rssModule); - } - - /// Determines whether the RssModuleCollection contains a specific element. - /// The RssModule to locate in the RssModuleCollection. - /// true if the RssModuleCollection contains the specified value; otherwise, false. - public bool Contains(RssModule rssModule) - { - return List.Contains(rssModule); - } - - /// Copies the entire RssModuleCollection to a compatible one-dimensional , starting at the specified index of the target array. - /// The one-dimensional RssModule Array that is the destination of the elements copied from RssModuleCollection. The Array must have zero-based indexing. - /// The zero-based index in array at which copying begins. - /// array is a null reference (Nothing in Visual Basic). - /// index is less than zero. - /// array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssModuleCollection is greater than the available space from index to the end of the destination array. - public void CopyTo(RssModule[] array, int index) - { - List.CopyTo(array, index); - } - - /// Searches for the specified RssModule and returns the zero-based index of the first occurrence within the entire RssModuleCollection. - /// The RssModule to locate in the RssModuleCollection. - /// The zero-based index of the first occurrence of RssModule within the entire RssModuleCollection, if found; otherwise, -1. - public int IndexOf(RssModule rssModule) - { - return List.IndexOf(rssModule); - } - - /// Inserts an item into this collection at a specified index. - /// The zero-based index of the collection at which to insert the item. - /// The item to insert into this collection. - public void Insert(int index, RssModule rssModule) - { - List.Insert(index, rssModule); - } - - /// Removes a specified item from this collection. - /// The item to remove. - public void Remove(RssModule rssModule) - { - List.Remove(rssModule); - } - } -} diff --git a/SiteServer.Utils/Rss/Collections/RssModuleItemCollection.cs b/SiteServer.Utils/Rss/Collections/RssModuleItemCollection.cs deleted file mode 100644 index 8b4f67f6a..000000000 --- a/SiteServer.Utils/Rss/Collections/RssModuleItemCollection.cs +++ /dev/null @@ -1,116 +0,0 @@ -/* RssModuleItemCollection.cs - * ========================== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; -using System.Collections; - -namespace SiteServer.Utils.Rss -{ - /// A strongly typed collection of objects - public class RssModuleItemCollection : CollectionBase - { - private ArrayList _alBindTo = new ArrayList(); - - /// Gets or sets the item at a specified index.In C#, this property is the indexer for the class. - /// The index of the collection to access. - /// An item at each valid index. - /// This method is an indexer that can be used to access the collection. - /// index is not a valid index. - public RssModuleItem this[int index] - { - get { return ((RssModuleItem)(List[index])); } - set { List[index] = value; } - } - - /// Adds a specified item to this collection. - /// The item to add. - /// The zero-based index of the added item. - public int Add(RssModuleItem rssModuleItem) - { - return List.Add(rssModuleItem); - } - - /// Determines whether the RssModuleItemCollection contains a specific element. - /// The RssModuleItem to locate in the RssModuleItemCollection. - /// true if the RssModuleItemCollection contains the specified value; otherwise, false. - public bool Contains(RssModuleItem rssModuleItem) - { - return List.Contains(rssModuleItem); - } - - /// Copies the entire RssModuleItemCollection to a compatible one-dimensional , starting at the specified index of the target array. - /// The one-dimensional RssModuleItem Array that is the destination of the elements copied from RssModuleItemCollection. The Array must have zero-based indexing. - /// The zero-based index in array at which copying begins. - /// array is a null reference (Nothing in Visual Basic). - /// index is less than zero. - /// array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssModuleItemCollection is greater than the available space from index to the end of the destination array. - public void CopyTo(RssModuleItem[] array, int index) - { - List.CopyTo(array, index); - } - - /// Searches for the specified RssModuleItem and returns the zero-based index of the first occurrence within the entire RssModuleItemCollection. - /// The RssModuleItem to locate in the RssModuleItemCollection. - /// The zero-based index of the first occurrence of RssModuleItem within the entire RssModuleItemCollection, if found; otherwise, -1. - public int IndexOf(RssModuleItem rssModuleItem) - { - return List.IndexOf(rssModuleItem); - } - - /// Inserts an item into this collection at a specified index. - /// The zero-based index of the collection at which to insert the item. - /// The item to insert into this collection. - public void Insert(int index, RssModuleItem rssModuleItem) - { - List.Insert(index, rssModuleItem); - } - - /// Removes a specified item from this collection. - /// The item to remove. - public void Remove(RssModuleItem rssModuleItem) - { - List.Remove(rssModuleItem); - } - - /// Bind a particular item to this module - /// Hash code of the item - public void BindTo(int itemHashCode) - { - _alBindTo.Add(itemHashCode); - } - - /// Check if a particular item is bound to this module - /// Hash code of the item - /// true if this item is bound to this module, otherwise false - public bool IsBoundTo(int itemHashCode) - { - return (_alBindTo.BinarySearch(0, _alBindTo.Count, itemHashCode, null) >= 0); - } - } -} diff --git a/SiteServer.Utils/Rss/Collections/RssModuleItemCollectionCollection.cs b/SiteServer.Utils/Rss/Collections/RssModuleItemCollectionCollection.cs deleted file mode 100644 index 9096dd318..000000000 --- a/SiteServer.Utils/Rss/Collections/RssModuleItemCollectionCollection.cs +++ /dev/null @@ -1,98 +0,0 @@ -/* RssModuleItemCollectionCollection.cs - * ==================================== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// A strongly typed collection of objects - public class RssModuleItemCollectionCollection : System.Collections.CollectionBase - { - /// Gets or sets the item at a specified index.In C#, this property is the indexer for the class. - /// The index of the collection to access. - /// An item at each valid index. - /// This method is an indexer that can be used to access the collection. - /// index is not a valid index. - public RssModuleItemCollection this[int index] - { - get { return ((RssModuleItemCollection)(List[index])); } - set { List[index] = value; } - } - - /// Adds a specified item to this collection. - /// The item to add. - /// The zero-based index of the added item. - public int Add(RssModuleItemCollection rssModuleItemCollection) - { - return List.Add(rssModuleItemCollection); - } - - /// Determines whether the RssModuleItemCollectionCollection contains a specific element. - /// The RssModuleItemCollection to locate in the RssModuleItemCollectionCollection. - /// true if the RssModuleItemCollectionCollection contains the specified value; otherwise, false. - public bool Contains(RssModuleItemCollection rssModuleItemCollection) - { - return List.Contains(rssModuleItemCollection); - } - - /// Copies the entire RssModuleItemCollectionCollection to a compatible one-dimensional , starting at the specified index of the target array. - /// The one-dimensional RssModuleItemCollection Array that is the destination of the elements copied from RssModuleItemCollectionCollection. The Array must have zero-based indexing. - /// The zero-based index in array at which copying begins. - /// array is a null reference (Nothing in Visual Basic). - /// index is less than zero. - /// array is multidimensional. -or- index is equal to or greater than the length of array.-or-The number of elements in the source RssModuleItemCollectionCollection is greater than the available space from index to the end of the destination array. - public void CopyTo(RssModuleItemCollection[] array, int index) - { - List.CopyTo(array, index); - } - - /// Searches for the specified RssModuleItemCollection and returns the zero-based index of the first occurrence within the entire RssModuleItemCollectionCollection. - /// The RssModuleItemCollection to locate in the RssModuleItemCollectionCollection. - /// The zero-based index of the first occurrence of RssModuleItemCollection within the entire RssModuleItemCollectionCollection, if found; otherwise, -1. - public int IndexOf(RssModuleItemCollection rssModuleItemCollection) - { - return List.IndexOf(rssModuleItemCollection); - } - - /// Inserts an item into this collection at a specified index. - /// The zero-based index of the collection at which to insert the item. - /// The item to insert into this collection. - public void Insert(int index, RssModuleItemCollection rssModuleItemCollection) - { - List.Insert(index, rssModuleItemCollection); - } - - /// Removes a specified item from this collection. - /// The item to remove. - public void Remove(RssModuleItemCollection rssModuleItemCollection) - { - List.Remove(rssModuleItemCollection); - } - } -} diff --git a/SiteServer.Utils/Rss/RssChannel/RssChannel.cs b/SiteServer.Utils/Rss/RssChannel/RssChannel.cs deleted file mode 100644 index 07eccf79b..000000000 --- a/SiteServer.Utils/Rss/RssChannel/RssChannel.cs +++ /dev/null @@ -1,214 +0,0 @@ -/* RssChannel.cs - * ============= - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// Grouping of related content items on a site - [SerializableAttribute()] - public class RssChannel : RssElement - { - private string title = RssDefault.String; - private Uri link = RssDefault.Uri; - private string description = RssDefault.String; - private string language = RssDefault.String; - private string copyright = RssDefault.String; - private string managingEditor = RssDefault.String; - private string webMaster = RssDefault.String; - private DateTime pubDate = RssDefault.DateTime; - private DateTime lastBuildDate = RssDefault.DateTime; - private RssCategoryCollection categories = new RssCategoryCollection(); - private string generator = RssDefault.String; - private string docs = RssDefault.String; - private RssCloud cloud = null; - private int timeToLive = RssDefault.Int; - private RssImage image = null; - private RssTextInput textInput = null; - private bool[] skipHours = new bool[24]; - private bool[] skipDays = new bool[7]; - private string rating = RssDefault.String; - private RssItemCollection items = new RssItemCollection(); - /// Initialize a new instance of the RssChannel class. - public RssChannel() {} - /// Returns a string representation of the current Object. - /// The channel's title, description, or "RssChannel" if the title and description are blank. - public override string ToString() - { - if (title != null) - return title; - else - if (description != null) - return description; - else - return "RssChannel"; - } - /// The name of the channel - /// Maximum length is 100 characters (For RSS 0.91) - public string Title - { - get { return title; } - set { title = RssDefault.Check(value); } - } - /// URL of the website named in the title - /// Maximum length is 500 characters (For RSS 0.91) - public Uri Link - { - get { return link; } - set { link = RssDefault.Check(value); } - } - /// Description of the channel - /// Maximum length is 500 characters (For RSS 0.91) - public string Description - { - get { return description; } - set { description = RssDefault.Check(value); } - } - /// Language the channel is written in - public string Language - { - get { return language; } - set { language = RssDefault.Check(value); } - } - /// A link and description for a graphic icon that represent a channel - public RssImage Image - { - get { return image; } - set { image = value; } - } - /// Copyright notice for content in the channel - /// Maximum length is 100 (For RSS 0.91) - public string Copyright - { - get { return copyright; } - set { copyright = RssDefault.Check(value); } - } - /// The email address of the managing editor of the channel, the person to contact for editorial inquiries - /// - /// Maximum length is 100 (For RSS 0.91) - /// The suggested format for email addresses in RSS elements is - /// bull@mancuso.com (Bull Mancuso) - /// - public string ManagingEditor - { - get { return managingEditor; } - set { managingEditor = RssDefault.Check(value); } - } - /// The email address of the webmaster for the channel - /// - /// Person to contact if there are technical problems - /// Maximum length is 100 (For RSS 0.91) - /// The suggested format for email addresses in RSS elements is - /// bull@mancuso.com (Bull Mancuso) - /// - public string WebMaster - { - get { return webMaster; } - set { webMaster = RssDefault.Check(value); } - } - /// The PICS rating for the channel - /// Maximum length is 500 (For RSS 0.91) - public string Rating - { - get { return rating; } - set { rating = RssDefault.Check(value); } - } - /// The publication date for the content in the channel, expressed as the coordinated universal time (UTC) - public DateTime PubDate - { - get { return pubDate; } - set { pubDate = value; } - } - /// The date-time the last time the content of the channel changed, expressed as the coordinated universal time (UTC) - public DateTime LastBuildDate - { - get { return lastBuildDate; } - set { lastBuildDate = value; } - } - /// One or more categories the channel belongs to. - public RssCategoryCollection Categories => categories; - - /// A string indicating the program used to generate the channel - public string Generator - { - get { return generator; } - set { generator = RssDefault.Check(value); } - } - /// A URL, points to the documentation for the format used in the RSS file - /// Maximum length is 500 (For RSS 0.91). - public string Docs - { - get { return docs; } - set { docs = RssDefault.Check(value); } - } - /// Provides information about an HTTP GET feature, typically for a search or subscription - public RssTextInput TextInput - { - get { return textInput; } - set { textInput = value; } - } - /// Readers should not read the channel during days listed. (UTC) - /// Days are listed in the array in the following order: - /// Monday - /// Tuesday - /// Wednesday - /// Thursday - /// Friday - /// Saturday - /// Sunday - /// Monday - /// - public bool[] SkipDays - { - get { return skipDays; } - set { skipDays = value; } - } - /// Readers should not read the channel during hours listed (UTC) - /// Represents a time in UTC - 1. - public bool[] SkipHours - { - get { return skipHours; } - set { skipHours = value; } - } - /// Allow processes to register with a cloud to be notified of updates to the channel - public RssCloud Cloud - { - get { return cloud; } - set { cloud = value; } - } - /// The number of minutes that a channel can be cached. - public int TimeToLive - { - get { return timeToLive; } - set { timeToLive = RssDefault.Check(value); } - } - /// All items within the channel - public RssItemCollection Items => items; - } -} diff --git a/SiteServer.Utils/Rss/RssChannel/RssCloud.cs b/SiteServer.Utils/Rss/RssChannel/RssCloud.cs deleted file mode 100644 index fa7353b68..000000000 --- a/SiteServer.Utils/Rss/RssChannel/RssCloud.cs +++ /dev/null @@ -1,77 +0,0 @@ -/* RssCloud.cs - * =========== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// Allow processes to register with a cloud to be notified of updates to the channel. - [SerializableAttribute()] - public class RssCloud : RssElement - { - private RssCloudProtocol protocol = RssCloudProtocol.Empty; - private string domain = RssDefault.String; - private string path = RssDefault.String; - private string registerProcedure = RssDefault.String; - private int port = RssDefault.Int; - /// Initialize a new instance of the RssCloud class. - public RssCloud() {} - /// Domain name or IP address of the cloud - public string Domain - { - get { return domain; } - set { domain = RssDefault.Check(value); } - } - /// TCP port that the cloud is running on - public int Port - { - get { return port; } - set { port = RssDefault.Check(value); } - } - /// Location of its responder - public string Path - { - get { return path; } - set { path = RssDefault.Check(value); } - } - - /// Name of the procedure to call to request notification - public string RegisterProcedure - { - get { return registerProcedure; } - set { registerProcedure = RssDefault.Check(value); } - } - /// Protocol used - public RssCloudProtocol Protocol - { - get { return protocol; } - set { protocol = value; } - } - } -} diff --git a/SiteServer.Utils/Rss/RssChannel/RssImage.cs b/SiteServer.Utils/Rss/RssChannel/RssImage.cs deleted file mode 100644 index 7f7b430a9..000000000 --- a/SiteServer.Utils/Rss/RssChannel/RssImage.cs +++ /dev/null @@ -1,90 +0,0 @@ -/* RssImage.cs - * =========== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// A link and description for a graphic that represent a channel - [SerializableAttribute()] - public class RssImage : RssElement - { - private string title = RssDefault.String; - private string description = RssDefault.String; - private Uri uri = RssDefault.Uri; - private Uri link = RssDefault.Uri; - private int width = RssDefault.Int; - private int height = RssDefault.Int; - - /// Initialize a new instance of the RssImage class. - public RssImage() {} - - /// The URL of a GIF, JPEG or PNG image that represents the channel. - /// Maximum length is 500 (For RSS 0.91). - public Uri Url - { - get { return uri; } - set { uri = RssDefault.Check(value); } - } - /// Describes the image, it's used in the ALT attribute of the HTML img tag when the channel is rendered in HTML. - /// Maximum length is 100 (For RSS 0.91). - public string Title - { - get { return title; } - set { title = RssDefault.Check(value); } - } - /// The URL of the site, when the channel is rendered, the image is a link to the site. - /// Maximum length is 500 (For RSS 0.91). - public Uri Link - { - get { return link; } - set { link = RssDefault.Check(value); } - } - /// Contains text that is included in the TITLE attribute of the link formed around the image in the HTML rendering. - public string Description - { - get { return description; } - set { description = RssDefault.Check(value); } - } - /// Width of image in pixels - /// Maximum value for height is 400 (For RSS 0.91) - public int Width - { - get { return width; } - set { width = RssDefault.Check(value); } - } - /// Height of image in pixels - /// Maximum value for width is 144 (For RSS 0.91) - public int Height - { - get { return height; } - set { height = RssDefault.Check(value); } - } - } -} diff --git a/SiteServer.Utils/Rss/RssChannel/RssTextInput.cs b/SiteServer.Utils/Rss/RssChannel/RssTextInput.cs deleted file mode 100644 index a9d9797f5..000000000 --- a/SiteServer.Utils/Rss/RssChannel/RssTextInput.cs +++ /dev/null @@ -1,76 +0,0 @@ -/* RssTextInput.cs - * =============== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// Multi-purpose channel element for the purpose of allowing users to submit queries back to the publisher's site - /// Typically for a search or subscription - [SerializableAttribute()] - public class RssTextInput : RssElement - { - private string title = RssDefault.String; - private string description = RssDefault.String; - private string name = RssDefault.String; - private Uri link = RssDefault.Uri; - - /// Initialize a new instance of the RssTextInput class - public RssTextInput() {} - - /// The label of the submit button in the text input area - /// Maximum length is 100 (For RSS 0.91) - public string Title - { - get { return title; } - set { title = RssDefault.Check(value); } - } - /// Explains the text input area - /// Maximum length is 500 (For RSS 0.91) - public string Description - { - get { return description; } - set { description = RssDefault.Check(value); } - } - /// The name of the text object in the text input area - /// Maximum length is 20 (For RSS 0.91). - public string Name - { - get { return name; } - set { name = RssDefault.Check(value); } - } - /// The URL of the script that processes text input requests - /// Maximum length is 500 (For RSS 0.91) - public Uri Link - { - get { return link; } - set { link = RssDefault.Check(value); } - } - } -} diff --git a/SiteServer.Utils/Rss/RssFeed.cs b/SiteServer.Utils/Rss/RssFeed.cs deleted file mode 100644 index e92ab51a4..000000000 --- a/SiteServer.Utils/Rss/RssFeed.cs +++ /dev/null @@ -1,275 +0,0 @@ -/* RssFeed.cs - * ========== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; -using System.IO; -using System.Net; -using System.Text; - -namespace SiteServer.Utils.Rss -{ - /// The contents of a RssFeed - [SerializableAttribute()] - public class RssFeed - { - private RssChannelCollection channels = new RssChannelCollection(); - private RssModuleCollection modules = new RssModuleCollection(); - private ExceptionCollection exceptions = null; - private DateTime lastModified = RssDefault.DateTime; - private RssVersion rssVersion = RssVersion.Empty; - private bool cached = false; - private string etag = RssDefault.String; - private string url = RssDefault.String; - private Encoding encoding = null; - /// Initialize a new instance of the RssFeed class. - public RssFeed() {} - /// Initialize a new instance of the RssFeed class with a specified encoding. - public RssFeed(Encoding encoding) - { - this.encoding = encoding; - } - /// Returns a string representation of the current Object. - /// The Url of the feed - public override string ToString() - { - return url; - } - /// The channels that are contained in the feed. - public RssChannelCollection Channels => channels; - - /// The modules that the feed adhears to. - public RssModuleCollection Modules => modules; - - /// A collection of all exceptions encountered during the reading of the feed. - public ExceptionCollection Exceptions => exceptions == null ? new ExceptionCollection() : exceptions; - - /// The Version of the feed. - public RssVersion Version - { - get { return rssVersion; } - set { rssVersion = value; } - } - /// The server generated hash of the feed. - public string ETag => etag; - - /// The server generated last modfified date and time of the feed. - public DateTime LastModified => lastModified; - - /// Indicates this feed has not been changed on the server, and the local copy was returned. - public bool Cached => cached; - - /// Location of the feed - public string Url => url; - - /// Encoding of the feed - public Encoding Encoding - { - get { return encoding; } - set { encoding = value; } - } - /// Reads the specified RSS feed - /// The url or filename of the RSS feed - /// The contents of the feed - public static RssFeed Read(string url) - { - return read(url, null, null); - } - /// Reads the specified RSS feed - /// The specified way to connect to the web server - /// The contents of the feed - public static RssFeed Read(HttpWebRequest Request) - { - return read(Request.RequestUri.ToString(), Request, null); - } - /// Reads the specified RSS feed - /// The cached version of the feed - /// The current contents of the feed - /// Will not download the feed if it has not been modified - public static RssFeed Read(RssFeed oldFeed) - { - return read(oldFeed.url, null, oldFeed); - } - /// Reads the specified RSS feed - /// The specified way to connect to the web server - /// The cached version of the feed - /// The current contents of the feed - /// Will not download the feed if it has not been modified - public static RssFeed Read(HttpWebRequest Request, RssFeed oldFeed) - { - return read(oldFeed.url, Request, oldFeed); - } - private static RssFeed read(string url, HttpWebRequest request, RssFeed oldFeed) - { - // ***** Marked for substantial improvement - var feed = new RssFeed(); - RssElement element = null; - Stream stream = null; - var uri = new Uri(url); - feed.url = url; - - switch (uri.Scheme) - { - case "file": - feed.lastModified = File.GetLastWriteTime(url); - if ((oldFeed != null) && (feed.LastModified == oldFeed.LastModified)) - { - oldFeed.cached = true; - return oldFeed; - } - stream = new FileStream(url, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); - break; - case "https": - goto case "http"; - case "http": - if (request == null) - request = (HttpWebRequest)WebRequest.Create(uri); - if (oldFeed != null) - { - request.IfModifiedSince = oldFeed.LastModified; - request.Headers.Add("If-None-Match", oldFeed.ETag); - } - try - { - var response = (HttpWebResponse)request.GetResponse(); - feed.lastModified = response.LastModified; - feed.etag = response.Headers["ETag"]; - try - { - if (response.ContentEncoding != "") - feed.encoding = Encoding.GetEncoding(response.ContentEncoding); - } - catch {} - stream = response.GetResponseStream(); - } - catch (WebException we) - { - if (oldFeed != null) - { - oldFeed.cached = true; - return oldFeed; - } - else throw we; // bad - } - break; - } - - if (stream != null) - { - RssReader reader = null; - try - { - reader = new RssReader(stream); - do - { - element = reader.Read(); - if (element is RssChannel) - feed.Channels.Add((RssChannel)element); - } - while (element != null); - feed.rssVersion = reader.Version; - } - finally - { - feed.exceptions = reader.Exceptions; - reader.Close(); - } - } - else - throw new ApplicationException("Not a valid Url"); - - return feed; - } - /// Writes the RSS feed to the specified stream. - /// specified Stream - /// The Stream cannot be written to. - /// Feed must contain at least one channel. - /// Channel must contain at least one item. - public void Write(Stream stream) - { - RssWriter writer; - - if (encoding == null) - writer = new RssWriter(stream); - else - writer = new RssWriter(stream, encoding); - write(writer); - } - - /// - /// add by lxx - /// - public void Write(TextWriter textWriter) - { - var writer = new RssWriter(textWriter); - write(writer); - } - - /// Writes the RSS feed to the specified file. - /// The encoding is ISO-8859-1. - /// The filename is empty, contains only white space, or contains one or more invalid characters. - /// Access is denied. - /// The filename is a (null c#, Nothing vb) reference. - /// The directory to write to is not found. - /// The filename includes an incorrect or invalid syntax for file name, directory name, or volume label syntax. - /// The caller does not have the required permission. - /// specified file (including path) If the file exists, it will be truncated with the new content. - /// Feed must contain at least one channel. - /// Channel must contain at least one item. - public void Write(string fileName) - { - var writer = new RssWriter(fileName); - write(writer); - } - private void write(RssWriter writer) - { - try - { - if (channels.Count == 0) - throw new InvalidOperationException("Feed must contain at least one channel."); - - writer.Version = rssVersion; - - writer.Modules = modules; - - foreach(RssChannel channel in channels) - { - if (channel.Items.Count == 0) - throw new InvalidOperationException("Channel must contain at least one item."); - - writer.Write(channel); - } - } - finally - { - if (writer != null) - writer.Close(); - } - } - } -} diff --git a/SiteServer.Utils/Rss/RssItem/RssEnclosure.cs b/SiteServer.Utils/Rss/RssItem/RssEnclosure.cs deleted file mode 100644 index 5da3fad0c..000000000 --- a/SiteServer.Utils/Rss/RssItem/RssEnclosure.cs +++ /dev/null @@ -1,63 +0,0 @@ -/* RssEnclosure.cs - * =============== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// A reference to an attachment to the item - [SerializableAttribute()] - public class RssEnclosure : RssElement - { - private Uri uri = RssDefault.Uri; - private int length = RssDefault.Int; - private string type = RssDefault.String; - /// Initialize a new instance of the RssEnclosure class. - public RssEnclosure() {} - /// Where the enclosure is located - public Uri Url - { - get { return uri; } - set { uri= RssDefault.Check(value); } - } - /// The size of the enclosure, in bytes - /// -1 represents a null. - public int Length - { - get { return length; } - set { length = RssDefault.Check(value); } - } - /// A standard Multipurpose Internet Mail Extensions (MIME) type - public string Type - { - get { return type; } - set { type = RssDefault.Check(value); } - } - } -} diff --git a/SiteServer.Utils/Rss/RssItem/RssGuid.cs b/SiteServer.Utils/Rss/RssItem/RssGuid.cs deleted file mode 100644 index 751b52d3c..000000000 --- a/SiteServer.Utils/Rss/RssItem/RssGuid.cs +++ /dev/null @@ -1,55 +0,0 @@ -/* RssGuid.cs - * ========== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// Globally unique identifier - [SerializableAttribute()] - public class RssGuid : RssElement - { - private DBBool permaLink = DBBool.Null; - private string name = RssDefault.String; - /// Initialize a new instance of the RssGuid class. - public RssGuid() {} - /// If true, a url that can be opened in a web browser that points to the item - public DBBool PermaLink - { - get { return permaLink; } - set { permaLink = value; } - } - /// Globally unique identifier value - public string Name - { - get { return name; } - set { name = RssDefault.Check(value); } - } - } -} diff --git a/SiteServer.Utils/Rss/RssItem/RssItem.cs b/SiteServer.Utils/Rss/RssItem/RssItem.cs deleted file mode 100644 index dc51dd45e..000000000 --- a/SiteServer.Utils/Rss/RssItem/RssItem.cs +++ /dev/null @@ -1,123 +0,0 @@ -/* RssItem.cs - * ========== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// A channel may contain any number of items, each of which links to more information about the item, with an optional description - [SerializableAttribute()] - public class RssItem : RssElement - { - private string title = RssDefault.String; - private Uri link = RssDefault.Uri; - private string description = RssDefault.String; - private string author = RssDefault.String; - private RssCategoryCollection categories = new RssCategoryCollection(); - private string comments = RssDefault.String; - private RssEnclosure enclosure = null; - private RssGuid guid = null; - private DateTime pubDate = RssDefault.DateTime; - private RssSource source = null; - /// Initialize a new instance of the RssItem class - public RssItem() {} - /// Returns a string representation of the current Object. - /// The item's title, description, or "RssItem" if the title and description are blank. - public override string ToString() - { - if (title != null) - return title; - else - if (description != null) - return description; - else - return "RssItem"; - } - /// Title of the item - /// Maximum length is 100 (For RSS 0.91) - public string Title - { - get { return title; } - set { title = RssDefault.Check(value); } - } - /// URL of the item - /// Maximum length is 500 (For RSS 0.91) - public Uri Link - { - get { return link; } - set { link = RssDefault.Check(value); } - } - /// Item synopsis - /// Maximum length is 500 (For RSS 0.91) - public string Description - { - get { return description; } - set { description = RssDefault.Check(value); } - } - /// Email address of the author of the item - public string Author - { - get { return author; } - set { author = RssDefault.Check(value); } - } - /// Provide information regarding the location of the subject matter of the channel in a taxonomy - public RssCategoryCollection Categories => categories; - - /// URL of a page for comments relating to the item - public string Comments - { - get { return comments; } - set { comments = RssDefault.Check(value); } - } - /// Describes an items source - public RssSource Source - { - get { return source; } - set { source = value; } - } - /// A reference to an attachment to the item - public RssEnclosure Enclosure - { - get { return enclosure; } - set { enclosure = value; } - } - /// A string that uniquely identifies the item - public RssGuid Guid - { - get { return guid; } - set { guid = value; } - } - /// Indicates when the item was published - public DateTime PubDate - { - get { return pubDate; } - set { pubDate = value; } - } - } -} diff --git a/SiteServer.Utils/Rss/RssItem/RssSource.cs b/SiteServer.Utils/Rss/RssItem/RssSource.cs deleted file mode 100644 index 03c56cff4..000000000 --- a/SiteServer.Utils/Rss/RssItem/RssSource.cs +++ /dev/null @@ -1,55 +0,0 @@ -/* RssSource.cs - * ============ - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// Describes an items source - [SerializableAttribute()] - public class RssSource : RssElement - { - private string name = RssDefault.String; - private Uri uri = RssDefault.Uri; - /// Initialize a new instance of the RssSource class - public RssSource() {} - /// Name of the RSS channel that the item came from - public string Name - { - get { return name; } - set { name = RssDefault.Check(value); } - } - /// URL of the original RSS feed from which the item was republished - public Uri Url - { - get { return uri; } - set { uri = RssDefault.Check(value); } - } - } -} diff --git a/SiteServer.Utils/Rss/RssModule.cs b/SiteServer.Utils/Rss/RssModule.cs deleted file mode 100644 index e52c6ff4b..000000000 --- a/SiteServer.Utils/Rss/RssModule.cs +++ /dev/null @@ -1,91 +0,0 @@ -/* RssModule.cs - * ============ - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; -using System.Collections; - -namespace SiteServer.Utils.Rss -{ - /// Base class for all RSS modules - [SerializableAttribute()] - public abstract class RssModule - { - private ArrayList _alBindTo = new ArrayList(); - private RssModuleItemCollection _rssChannelExtensions = new RssModuleItemCollection(); - private RssModuleItemCollectionCollection _rssItemExtensions = new RssModuleItemCollectionCollection(); - private string _sNamespacePrefix = RssDefault.String; - private Uri _uriNamespaceURL = RssDefault.Uri; - - /// Initialize a new instance of the RssModule class - public RssModule() {} - - /// Collection of RSSModuleItem that are to be placed in the channel - internal RssModuleItemCollection ChannelExtensions - { - get { return _rssChannelExtensions; } - set { _rssChannelExtensions = value; } - } - - /// Collection of RSSModuleItemCollection that are to be placed in the channel item - internal RssModuleItemCollectionCollection ItemExtensions - { - get { return _rssItemExtensions; } - set { _rssItemExtensions = value; } - } - - /// Prefix for the given module namespace - public string NamespacePrefix - { - get { return _sNamespacePrefix; } - set { _sNamespacePrefix = RssDefault.Check(value); } - } - - /// URL for the given module namespace - public Uri NamespaceURL - { - get { return _uriNamespaceURL; } - set { _uriNamespaceURL = RssDefault.Check(value); } - } - - /// Bind a particular channel to this module - /// Hash code of the channel - public void BindTo(int channelHashCode) - { - _alBindTo.Add(channelHashCode); - } - - /// Check if a particular channel is bound to this module - /// Hash code of the channel - /// true if this channel is bound to this module, otherwise false - public bool IsBoundTo(int channelHashCode) - { - return (_alBindTo.BinarySearch(0, _alBindTo.Count, channelHashCode, null) >= 0); - } - } -} diff --git a/SiteServer.Utils/Rss/RssModuleItem.cs b/SiteServer.Utils/Rss/RssModuleItem.cs deleted file mode 100644 index cee2c0019..000000000 --- a/SiteServer.Utils/Rss/RssModuleItem.cs +++ /dev/null @@ -1,143 +0,0 @@ -/* RssModuleItem.cs - * ================ - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// A module may contain any number of items (either channel-based or item-based). - [SerializableAttribute()] - public class RssModuleItem : RssElement - { - private bool _bRequired = false; - private string _sElementName = RssDefault.String; - private string _sElementText = RssDefault.String; - private RssModuleItemCollection _rssSubElements = new RssModuleItemCollection(); - - /// Initialize a new instance of the RssModuleItem class - public RssModuleItem() - { - } - - /// Initialize a new instance of the RssModuleItem class - /// The name of this RssModuleItem. - public RssModuleItem(string name) - { - _sElementName = RssDefault.Check(name); - } - - /// Initialize a new instance of the RssModuleItem class - /// The name of this RssModuleItem. - /// Is text required for this RssModuleItem? - public RssModuleItem(string name, bool required) : this(name) - { - _bRequired = required; - } - - /// Initialize a new instance of the RssModuleItem class - /// The name of this RssModuleItem. - /// The text contained within this RssModuleItem. - public RssModuleItem(string name, string text) : this(name) - { - _sElementText = RssDefault.Check(text); - } - - /// Initialize a new instance of the RssModuleItem class - /// The name of this RssModuleItem. - /// Is text required for this RssModuleItem? - /// The text contained within this RssModuleItem. - public RssModuleItem(string name, bool required, string text) : this(name, required) - { - _sElementText = RssDefault.Check(text); - } - - /// Initialize a new instance of the RssModuleItem class - /// The name of this RssModuleItem. - /// The text contained within this RssModuleItem. - /// The sub-elements of this RssModuleItem (if any exist). - public RssModuleItem(string name, string text, RssModuleItemCollection subElements) : this(name, text) - { - _rssSubElements = subElements; - } - - /// Initialize a new instance of the RssModuleItem class - /// The name of this RssModuleItem. - /// Is text required for this RssModuleItem? - /// The text contained within this RssModuleItem. - /// The sub-elements of this RssModuleItem (if any exist). - public RssModuleItem(string name, bool required, string text, RssModuleItemCollection subElements) : this(name, required, text) - { - _rssSubElements = subElements; - } - - /// Returns a string representation of the current Object. - /// The item's title, description, or "RssModuleItem" if the title and description are blank. - public override string ToString() - { - if (_sElementName != null) - return _sElementName; - else if (_sElementText != null) - return _sElementText; - else - return "RssModuleItem"; - } - - /// - /// The name of this RssModuleItem. - /// - public string Name - { - get { return _sElementName; } - set { _sElementName = RssDefault.Check(value); } - } - - /// - /// The text contained within this RssModuleItem. - /// - public string Text - { - get { return _sElementText; } - set { _sElementText = RssDefault.Check(value); } - } - - /// - /// The sub-elements of this RssModuleItem (if any exist). - /// - public RssModuleItemCollection SubElements - { - get { return _rssSubElements; } - set { _rssSubElements = value;} - } - - /// - /// Is text for this element required? - /// - public bool IsRequired => _bRequired; - } -} diff --git a/SiteServer.Utils/Rss/RssModules/RssBlogChannel.cs b/SiteServer.Utils/Rss/RssModules/RssBlogChannel.cs deleted file mode 100644 index 1181fab8d..000000000 --- a/SiteServer.Utils/Rss/RssModules/RssBlogChannel.cs +++ /dev/null @@ -1,61 +0,0 @@ -/* RssBlogChannel.cs - * ================= - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * blogChannel RSS Module (http://backend.userland.com/blogChannelModule) - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// A RSS module that adds elements at the channel level that are common to weblogs. - public sealed class RssBlogChannel : RssModule - { - /// Initialize a new instance of the - /// The URL of an OPML file containing the blogroll for the site. - /// The URL of an OPML file containing the author's RSS subscriptions. - /// - /// The URL of a weblog that the author of the weblog is promoting per Mark Pilgrim's description. - /// "http://diveintomark.org/archives/2002/09/17.html#blink_and_youll_miss_it" - /// - /// - /// The URL of a changes.xml file. When the feed that contains this element updates, it pings a server that updates this file. The presence of this element says to aggregators that they only have to read the changes file to see if this feed has updated. If several feeds point to the same changes file, the aggregator has to do less polling, resulting in better use of server bandwidth, and the Internet as a whole; and resulting in faster scans. Everyone wins. For more technical information, see the howto on the XML-RPC site. - /// "http://www.xmlrpc.com/weblogsComForRss" - /// - public RssBlogChannel(Uri blogRoll, Uri mySubscriptions, Uri blink, Uri changes) - { - NamespacePrefix = "blogChannel"; - NamespaceURL = new Uri("http://backend.userland.com/blogChannelModule"); - - ChannelExtensions.Add(new RssModuleItem("blogRoll", true, RssDefault.Check(blogRoll.ToString()))); - ChannelExtensions.Add(new RssModuleItem("mySubscriptions", true, RssDefault.Check(mySubscriptions.ToString()))); - ChannelExtensions.Add(new RssModuleItem("blink", true, RssDefault.Check(blink.ToString()))); - ChannelExtensions.Add(new RssModuleItem("changes", true, RssDefault.Check(changes.ToString()))); - } - } -} \ No newline at end of file diff --git a/SiteServer.Utils/Rss/RssModules/RssCreativeCommon.cs b/SiteServer.Utils/Rss/RssModules/RssCreativeCommon.cs deleted file mode 100644 index e4241ee03..000000000 --- a/SiteServer.Utils/Rss/RssModules/RssCreativeCommon.cs +++ /dev/null @@ -1,66 +0,0 @@ -/* RssCreativeCommons.cs - * ===================== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * creativeCommons RSS Module (http://backend.userland.com/creativeCommonsRssModule) - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// A RSS module that adds elements at the channel or item level that specifies which Creative Commons license applies. - public sealed class RssCreativeCommons : RssModule - { - /// Initialize a new instance of the - /// - /// If present as a sub-element of channel, indicates that the content of the RSS file is available under a license, indicated by a URL, which is the value of the license element. A list of some licenses that may be used in this context is on the Creative Commons website on this page, however the license element may point to licenses not authored by Creative Commons. - /// You may also use the license element as a sub-element of item. When used this way it applies only to the content of that item. If an item has a license, and the channel does too, the license on the item applies, i.e. the inner license overrides the outer one. - /// Multiple license elements are allowed, in either context, indicating that the content is available under multiple licenses. - /// "http://www.creativecommons.org/licenses/" - /// - /// If present as a sub-element of channel then true, otherwise false - public RssCreativeCommons(Uri license, bool isChannelSubElement) - { - NamespacePrefix = "creativeCommons"; - NamespaceURL = new Uri("http://backend.userland.com/creativeCommonsRssModule"); - - if(isChannelSubElement) - { - ChannelExtensions.Add(new RssModuleItem("license", true, RssDefault.Check(license.ToString()))); - } - else - { - var rssItems = new RssModuleItemCollection(); - - rssItems.Add(new RssModuleItem("license", true, RssDefault.Check(license.ToString()))); - - ItemExtensions.Add(rssItems); - } - } - } -} \ No newline at end of file diff --git a/SiteServer.Utils/Rss/RssModules/RssPhotoAlbum.cs b/SiteServer.Utils/Rss/RssModules/RssPhotoAlbum.cs deleted file mode 100644 index c850cdd26..000000000 --- a/SiteServer.Utils/Rss/RssModules/RssPhotoAlbum.cs +++ /dev/null @@ -1,367 +0,0 @@ -/* RssPhotoAlbum.cs - * ================ - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Photo Album 1.0 (http://www.innothinx.com) - * Copyright ?2001-2003 Robert A. Wlodarczyk and Inno Thinx, LLC. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// People in a photo - public sealed class RssPhotoAlbumCategoryPhotoPeople : RssModuleItemCollection - { - /// Initialize a new instance of the RssPhotoAlbumItemPhotoPeople class - public RssPhotoAlbumCategoryPhotoPeople() - { - } - - /// Initialize a new instance of the RssPhotoAlbumItemPhotoPeople class - /// Name of person - public RssPhotoAlbumCategoryPhotoPeople(string value) - { - Add(value); - } - - /// Add a person to the photo - /// Name of person - /// The zero-based index of the added item - public int Add(string value) - { - return base.Add(new RssModuleItem("person", true, value)); - } - } - - - /// A collection of photos in a category - public sealed class RssPhotoAlbumCategoryPhotos : RssModuleItemCollectionCollection - { - /// Initialize a new instance of the RssPhotoAlbumItemPhoto class - public RssPhotoAlbumCategoryPhotos() - { - } - - /// Adds a sepecified photo to this collection. - /// The photo to add. - /// The zero-based index of the added item. - public int Add(RssPhotoAlbumCategoryPhoto photo) - { - return base.Add(photo); - } - } - - - /// A photo in the category - public sealed class RssPhotoAlbumCategoryPhoto : RssModuleItemCollection - { - /// Initialize a new instance of the RssPhotoAlbumItemPhoto class - /// Date of the Photo - /// Description of the photo. - /// Direct link of the photo. - public RssPhotoAlbumCategoryPhoto(DateTime photoDate, string photoDescription, Uri photoLink) - { - Add(photoDate, photoDescription, photoLink); - } - - /// Initialize a new instance of the RssPhotoAlbumItemPhoto class - /// Date of the Photo - /// Description of the photo. - /// People to add to the photo. - /// Direct link of the photo. - public RssPhotoAlbumCategoryPhoto(DateTime photoDate, string photoDescription, Uri photoLink, RssPhotoAlbumCategoryPhotoPeople photoPeople) - { - Add(photoDate, photoDescription, photoLink, photoPeople); - } - - /// Adds a specified item to this collection. - /// Date of the Photo - /// Description of the photo. - /// People to add to the photo. - /// Direct link of the photo. - /// The zero-based index of the added item. - private int Add(DateTime photoDate, string photoDescription, Uri photoLink, RssPhotoAlbumCategoryPhotoPeople photoPeople) - { - Add(photoDate, photoDescription, photoLink); - base.Add(new RssModuleItem("photoPeople", true, "", photoPeople)); - return -1; - } - - /// Adds a specified item to this collection. - /// Date of the Photo - /// Description of the photo. - /// Direct link of the photo. - /// The zero-based index of the added item. - private int Add(DateTime photoDate, string photoDescription, Uri photoLink) - { - base.Add(new RssModuleItem("photoDate", true, RssDefault.Check(photoDate.ToUniversalTime().ToString("r")))); - base.Add(new RssModuleItem("photoDescription", false, RssDefault.Check(photoDescription))); - base.Add(new RssModuleItem("photoLink", true, RssDefault.Check(photoLink).ToString())); - return -1; - } - - /// Initialize a new instance of the RssPhotoAlbumItemPhoto class - /// Date of the Photo - /// Description of the photo. - /// Direct link of the photo. - public RssPhotoAlbumCategoryPhoto(string photoDate, string photoDescription, Uri photoLink) - { - Add(photoDate, photoDescription, photoLink); - } - - /// Initialize a new instance of the RssPhotoAlbumItemPhoto class - /// Date of the Photo - /// Description of the photo. - /// People to add to the photo. - /// Direct link of the photo. - public RssPhotoAlbumCategoryPhoto(string photoDate, string photoDescription, Uri photoLink, RssPhotoAlbumCategoryPhotoPeople photoPeople) - { - Add(photoDate, photoDescription, photoLink, photoPeople); - } - - /// Adds a specified item to this collection. - /// Date of the Photo - /// Description of the photo. - /// People to add to the photo. - /// Direct link of the photo. - /// The zero-based index of the added item. - private int Add(string photoDate, string photoDescription, Uri photoLink, RssPhotoAlbumCategoryPhotoPeople photoPeople) - { - Add(photoDate, photoDescription, photoLink); - base.Add(new RssModuleItem("photoPeople", true, "", photoPeople)); - return -1; - } - - /// Adds a specified item to this collection. - /// Date of the Photo - /// Description of the photo. - /// Direct link of the photo. - /// The zero-based index of the added item. - private int Add(string photoDate, string photoDescription, Uri photoLink) - { - base.Add(new RssModuleItem("photoDate", true, RssDefault.Check(photoDate))); - base.Add(new RssModuleItem("photoDescription", false, RssDefault.Check(photoDescription))); - base.Add(new RssModuleItem("photoLink", true, RssDefault.Check(photoLink).ToString())); - return -1; - } - } - - - /// A collection of categories in a photo album - public sealed class RssPhotoAlbumCategories : RssModuleItemCollectionCollection - { - /// Initialize a new instance of the RssPhotoAlbumItemPhoto class - public RssPhotoAlbumCategories() - { - } - - /// Adds a sepecified category to this collection. - /// The category to add. - /// The zero-based index of the added item. - public int Add(RssPhotoAlbumCategory category) - { - return base.Add(category); - } - } - - - /// A Photo Album category - public sealed class RssPhotoAlbumCategory : RssModuleItemCollection - { - /// Initialize a new instance of the RssPhotoAlbumItem class - /// Name of the category. - /// Description of the category. - /// From date of the category. - /// To date of the category. - /// Photos of the category. - public RssPhotoAlbumCategory(string categoryName, string categoryDescription, DateTime categoryDateFrom, DateTime categoryDateTo, RssPhotoAlbumCategoryPhoto categoryPhoto) - { - Add(categoryName, categoryDescription, categoryDateFrom, categoryDateTo, categoryPhoto); - } - - /// Adds a specified category to this collection. - /// Name of the category. - /// Description of the category. - /// From date of the category. - /// To date of the category. - /// Photos of the category. - /// The zero-based index of the added item. - private int Add(string categoryName, string categoryDescription, DateTime categoryDateFrom, DateTime categoryDateTo, RssPhotoAlbumCategoryPhoto categoryPhoto) - { - var categoryDataRange = new RssModuleItemCollection(); - categoryDataRange.Add(new RssModuleItem("from", true, RssDefault.Check(categoryDateFrom.ToUniversalTime().ToString("r")))); - categoryDataRange.Add(new RssModuleItem("to", true, RssDefault.Check(categoryDateTo.ToUniversalTime().ToString("r")))); - - base.Add(new RssModuleItem("categoryName", true, RssDefault.Check(categoryName))); - base.Add(new RssModuleItem("categoryDescription", true, RssDefault.Check(categoryDescription))); - base.Add(new RssModuleItem("categoryDateRange", true, "", categoryDataRange)); - base.Add(new RssModuleItem("categoryPhoto", true, "", categoryPhoto)); - - return -1; - } - - /// Initialize a new instance of the RssPhotoAlbumItem class - /// Name of the category. - /// Description of the category. - /// From date of the category. - /// To date of the category. - /// Photos of the category. - public RssPhotoAlbumCategory(string categoryName, string categoryDescription, string categoryDateFrom, string categoryDateTo, RssPhotoAlbumCategoryPhoto categoryPhoto) - { - Add(categoryName, categoryDescription, categoryDateFrom, categoryDateTo, categoryPhoto); - } - - /// Adds a specified category to this collection. - /// Name of the category. - /// Description of the category. - /// From date of the category. - /// To date of the category. - /// Photos of the category. - /// The zero-based index of the added item. - private int Add(string categoryName, string categoryDescription, string categoryDateFrom, string categoryDateTo, RssPhotoAlbumCategoryPhoto categoryPhoto) - { - var categoryDataRange = new RssModuleItemCollection(); - categoryDataRange.Add(new RssModuleItem("from", true, RssDefault.Check(categoryDateFrom))); - categoryDataRange.Add(new RssModuleItem("to", true, RssDefault.Check(categoryDateTo))); - - base.Add(new RssModuleItem("categoryName", true, RssDefault.Check(categoryName))); - base.Add(new RssModuleItem("categoryDescription", true, RssDefault.Check(categoryDescription))); - base.Add(new RssModuleItem("categoryDateRange", true, "", categoryDataRange)); - base.Add(new RssModuleItem("categoryPhoto", true, "", categoryPhoto)); - - return -1; - } - - /// Initialize a new instance of the RssPhotoAlbumItem class - /// Name of the category. - /// Description of the category. - /// From date of the category. - /// To date of the category. - /// Photos of the category. - public RssPhotoAlbumCategory(string categoryName, string categoryDescription, DateTime categoryDateFrom, DateTime categoryDateTo, RssPhotoAlbumCategoryPhotos categoryPhotos) - { - Add(categoryName, categoryDescription, categoryDateFrom, categoryDateTo, categoryPhotos); - } - - /// Adds a specified category to this collection. - /// Name of the category. - /// Description of the category. - /// From date of the category. - /// To date of the category. - /// Photos of the category. - /// The zero-based index of the added item. - private int Add(string categoryName, string categoryDescription, DateTime categoryDateFrom, DateTime categoryDateTo, RssPhotoAlbumCategoryPhotos categoryPhotos) - { - var categoryDataRange = new RssModuleItemCollection(); - categoryDataRange.Add(new RssModuleItem("from", true, RssDefault.Check(categoryDateFrom.ToUniversalTime().ToString("r")))); - categoryDataRange.Add(new RssModuleItem("to", true, RssDefault.Check(categoryDateTo.ToUniversalTime().ToString("r")))); - - base.Add(new RssModuleItem("categoryName", true, RssDefault.Check(categoryName))); - base.Add(new RssModuleItem("categoryDescription", true, RssDefault.Check(categoryDescription))); - base.Add(new RssModuleItem("categoryDateRange", true, "", categoryDataRange)); - foreach(RssPhotoAlbumCategoryPhoto categoryPhoto in categoryPhotos) - base.Add(new RssModuleItem("categoryPhoto", true, "", categoryPhoto)); - - return -1; - } - - /// Initialize a new instance of the RssPhotoAlbumItem class - /// Name of the category. - /// Description of the category. - /// From date of the category. - /// To date of the category. - /// Photos of the category. - public RssPhotoAlbumCategory(string categoryName, string categoryDescription, string categoryDateFrom, string categoryDateTo, RssPhotoAlbumCategoryPhotos categoryPhotos) - { - Add(categoryName, categoryDescription, categoryDateFrom, categoryDateTo, categoryPhotos); - } - - /// Adds a specified category to this collection. - /// Name of the category. - /// Description of the category. - /// From date of the category. - /// To date of the category. - /// Photos of the category. - /// The zero-based index of the added item. - private int Add(string categoryName, string categoryDescription, string categoryDateFrom, string categoryDateTo, RssPhotoAlbumCategoryPhotos categoryPhotos) - { - var categoryDataRange = new RssModuleItemCollection(); - categoryDataRange.Add(new RssModuleItem("from", true, RssDefault.Check(categoryDateFrom))); - categoryDataRange.Add(new RssModuleItem("to", true, RssDefault.Check(categoryDateTo))); - - base.Add(new RssModuleItem("categoryName", true, RssDefault.Check(categoryName))); - base.Add(new RssModuleItem("categoryDescription", true, RssDefault.Check(categoryDescription))); - base.Add(new RssModuleItem("categoryDateRange", true, "", categoryDataRange)); - foreach(RssPhotoAlbumCategoryPhoto categoryPhoto in categoryPhotos) - base.Add(new RssModuleItem("categoryPhoto", true, "", categoryPhoto)); - - return -1; - } - } - - - /// RSS syndication for Robert A. Wlodarczyk's Photo Album application (to be sold by Inno Thinx LLC) - public sealed class RssPhotoAlbum : RssModule - { - /// Initialize a new instance of the RssPhotoAlbum class - /// Link to the Photo Album - /// The category of the Photo Album to add - public RssPhotoAlbum(Uri link, RssPhotoAlbumCategory photoAlbumCategory) - { - NamespacePrefix = "photoAlbum"; - NamespaceURL = new Uri("http://xml.innothinx.com/photoAlbum"); - - ChannelExtensions.Add(new RssModuleItem("link", true, RssDefault.Check(link).ToString())); - - ItemExtensions.Add(photoAlbumCategory); - } - - /// Initialize a new instance of the RssPhotoAlbum class - /// Link to the Photo Album - /// A collection of categories in the Photo Album to add - public RssPhotoAlbum(Uri link, RssPhotoAlbumCategories photoAlbumCategories) - { - NamespacePrefix = "photoAlbum"; - NamespaceURL = new Uri("http://xml.innothinx.com/photoAlbum"); - - ChannelExtensions.Add(new RssModuleItem("link", true, RssDefault.Check(link).ToString())); - - foreach(RssModuleItemCollection photoAlbumCategory in photoAlbumCategories) - { - ItemExtensions.Add(photoAlbumCategory); - } - } - - /// Link element for channel - public Uri Link - { - get { return (RssDefault.Check(ChannelExtensions[0].Text) == RssDefault.String) ? null : new Uri(ChannelExtensions[0].Text); } - set { ChannelExtensions[0].Text = (RssDefault.Check(value) == RssDefault.Uri) ? "" : value.ToString(); } - } - } -} diff --git a/SiteServer.Utils/Rss/RssReader.cs b/SiteServer.Utils/Rss/RssReader.cs deleted file mode 100644 index 05165bfab..000000000 --- a/SiteServer.Utils/Rss/RssReader.cs +++ /dev/null @@ -1,708 +0,0 @@ -/* RssReader.cs - * ============ - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; -using System.Collections; -using System.Xml; -using System.Text; -using System.IO; - -namespace SiteServer.Utils.Rss -{ - /// Reads an RSS file. - /// Provides fast, non-cached, forward-only access to RSS data. - public class RssReader - { - // TODO: Add support for modules - - private Stack xmlNodeStack = new Stack(); - private StringBuilder elementText = new StringBuilder(); - private XmlTextReader reader = null; - private bool wroteChannel = false; - private RssVersion rssVersion = RssVersion.Empty; - private ExceptionCollection exceptions = new ExceptionCollection(); - - private RssTextInput textInput = null; - private RssImage image = null; - private RssCloud cloud = null; - private RssChannel channel = null; - private RssSource source = null; - private RssEnclosure enclosure = null; - private RssGuid guid = null; - private RssCategory category = null; - private RssItem item = null; - - private void InitReader() - { - reader.WhitespaceHandling = WhitespaceHandling.None; - reader.XmlResolver = null; - } - - #region Constructors - - /// Initializes a new instance of the RssReader class with the specified URL or filename. - /// The URL or filename for the file containing the RSS data. - /// Occures when unable to retrieve file containing the RSS data. - public RssReader(string url) - { - try - { - reader = new XmlTextReader(url); - InitReader(); - } - catch (Exception e) - { - throw new ArgumentException("Unable to retrieve file containing the RSS data.", e); - } - } - - /// Creates an instance of the RssReader class using the specified TextReader. - /// specified TextReader - /// Occures when unable to retrieve file containing the RSS data. - public RssReader(TextReader textReader) - { - try - { - reader = new XmlTextReader(textReader); - InitReader(); - } - catch (Exception e) - { - throw new ArgumentException("Unable to retrieve file containing the RSS data.", e); - } - } - - /// Creates an instance of the RssReader class using the specified Stream. - /// Occures when unable to retrieve file containing the RSS data. - /// Stream to read from - public RssReader(Stream stream) - { - try - { - reader = new XmlTextReader(stream); - InitReader(); - } - catch (Exception e) - { - throw new ArgumentException("Unable to retrieve file containing the RSS data.", e); - } - } - - #endregion - - /// Reads the next RssElement from the stream. - /// An RSS Element - /// RssReader has been closed, and can not be read. - /// RSS file not found. - /// Invalid XML syntax in RSS file. - /// Unable to read an RssElement. Reached the end of the stream. - public RssElement Read() - { - var readData = false; - var pushElement = true; - RssElement rssElement = null; - var lineNumber = -1; - var linePosition = -1; - - if (reader == null) - throw new InvalidOperationException("RssReader has been closed, and can not be read."); - - do - { - pushElement = true; - try - { - readData = reader.Read(); - } - catch (EndOfStreamException e) - { - throw new EndOfStreamException("Unable to read an RssElement. Reached the end of the stream.", e); - } - catch (XmlException e) - { - if (lineNumber != -1 || linePosition != -1) - if (reader.LineNumber == lineNumber && reader.LinePosition == linePosition) - throw exceptions.LastException; - - lineNumber = reader.LineNumber; - linePosition = reader.LinePosition; - - exceptions.Add(e); // just add to list of exceptions and continue :) - } - if (readData) - { - var readerName = reader.Name.ToLower(); - switch (reader.NodeType) - { - case XmlNodeType.Element: - { - if (reader.IsEmptyElement) - break; - elementText = new StringBuilder(); - - switch (readerName) - { - case "item": - // is this the end of the channel element? (absence of before ) - if (!wroteChannel) - { - wroteChannel = true; - rssElement = channel; // return RssChannel - readData = false; - } - item = new RssItem(); // create new RssItem - channel.Items.Add(item); - break; - case "source": - source = new RssSource(); - item.Source = source; - for (var i=0; i < reader.AttributeCount; i++) - { - reader.MoveToAttribute(i); - switch (reader.Name.ToLower()) - { - case "url": - try - { - source.Url = new Uri(reader.Value); - } - catch (Exception e) - { - exceptions.Add(e); - } - break; - } - } - break; - case "enclosure": - enclosure = new RssEnclosure(); - item.Enclosure = enclosure; - for (var i=0; i < reader.AttributeCount; i++) - { - reader.MoveToAttribute(i); - switch (reader.Name.ToLower()) - { - case "url": - try - { - enclosure.Url = new Uri(reader.Value); - } - catch (Exception e) - { - exceptions.Add(e); - } - break; - case "length": - try - { - enclosure.Length = int.Parse(reader.Value); - } - catch (Exception e) - { - exceptions.Add(e); - } - break; - case "type": - enclosure.Type = reader.Value; - break; - } - } - break; - case "guid": - guid = new RssGuid(); - item.Guid = guid; - for (var i=0; i < reader.AttributeCount; i++) - { - reader.MoveToAttribute(i); - switch (reader.Name.ToLower()) - { - case "ispermalink": - try - { - guid.PermaLink = bool.Parse(reader.Value); - } - catch (Exception e) - { - exceptions.Add(e); - } - break; - } - } - break; - case "category": - category = new RssCategory(); - if ((string)xmlNodeStack.Peek() == "channel") - channel.Categories.Add(category); - else - item.Categories.Add(category); - for (var i=0; i < reader.AttributeCount; i++) - { - reader.MoveToAttribute(i); - switch (reader.Name.ToLower()) - { - case "url": - goto case "domain"; - case "domain": - category.Domain = reader.Value; - break; - } - } - break; - case "channel": - channel = new RssChannel(); - textInput = null; - image = null; - cloud = null; - source = null; - enclosure = null; - category = null; - item = null; - break; - case "image": - image = new RssImage(); - channel.Image = image; - break; - case "textinput": - textInput = new RssTextInput(); - channel.TextInput = textInput; - break; - case "cloud": - pushElement = false; - cloud = new RssCloud(); - channel.Cloud = cloud; - for (var i=0; i < reader.AttributeCount; i++) - { - reader.MoveToAttribute(i); - switch (reader.Name.ToLower()) - { - case "domain": - cloud.Domain = reader.Value; - break; - case "port": - try - { - cloud.Port = ushort.Parse(reader.Value); - } - catch (Exception e) - { - exceptions.Add(e); - } - break; - case "path": - cloud.Path = reader.Value; - break; - case "registerprocedure": - cloud.RegisterProcedure = reader.Value; - break; - case "protocol": - switch (reader.Value.ToLower()) - { - case "xml-rpc": - cloud.Protocol = RssCloudProtocol.XmlRpc; - break; - case "soap": - cloud.Protocol = RssCloudProtocol.Soap; - break; - case "http-post": - cloud.Protocol = RssCloudProtocol.HttpPost; - break; - default: - cloud.Protocol = RssCloudProtocol.Empty; - break; - } - break; - } - } - break; - case "rss": - for (var i=0; i < reader.AttributeCount; i++) - { - reader.MoveToAttribute(i); - if (reader.Name.ToLower() == "version") - switch (reader.Value) - { - case "0.91": - rssVersion = RssVersion.RSS091; - break; - case "0.92": - rssVersion = RssVersion.RSS092; - break; - case "2.0": - rssVersion = RssVersion.RSS20; - break; - default: - rssVersion = RssVersion.NotSupported; - break; - } - } - break; - case "rdf": - for (var i=0; i < reader.AttributeCount; i++) - { - reader.MoveToAttribute(i); - if (reader.Name.ToLower() == "version") - switch (reader.Value) - { - case "0.90": - rssVersion = RssVersion.RSS090; - break; - case "1.0": - rssVersion = RssVersion.RSS10; - break; - default: - rssVersion = RssVersion.NotSupported; - break; - } - } - break; - - } - if (pushElement) - xmlNodeStack.Push(readerName); - break; - } - case XmlNodeType.EndElement: - { - if (xmlNodeStack.Count == 1) - break; - var childElementName = (string)xmlNodeStack.Pop(); - var parentElementName = (string)xmlNodeStack.Peek(); - switch (childElementName) // current element - { - // item classes - case "item": - rssElement = item; - readData = false; - break; - case "source": - source.Name = elementText.ToString(); - rssElement = source; - readData = false; - break; - case "enclosure": - rssElement = enclosure; - readData = false; - break; - case "guid": - guid.Name = elementText.ToString(); - rssElement = guid; - readData = false; - break; - case "category": // parent is either item or channel - category.Name = elementText.ToString(); - rssElement = category; - readData = false; - break; - // channel classes - case "channel": - if (wroteChannel) - wroteChannel = false; - else - { - wroteChannel = true; - rssElement = channel; - readData = false; - } - break; - case "textinput": - rssElement = textInput; - readData = false; - break; - case "image": - rssElement = image; - readData = false; - break; - case "cloud": - rssElement = cloud; - readData = false; - break; - } - switch (parentElementName) // parent element - { - case "item": - switch (childElementName) - { - case "title": - item.Title = elementText.ToString(); - break; - case "link": - item.Link = new Uri(elementText.ToString()); - break; - case "description": - item.Description = elementText.ToString(); - break; - case "author": - item.Author = elementText.ToString(); - break; - case "comments": - item.Comments = elementText.ToString(); - break; - case "pubdate": - try - { - item.PubDate = DateTime.Parse(elementText.ToString()); - } - catch (Exception e) - { - try { - var tmp = elementText.ToString (); - tmp = tmp.Substring (0, tmp.Length - 5); - tmp += "GMT"; - item.PubDate = DateTime.Parse (tmp); - } - catch - { - exceptions.Add(e); - } - } - break; - } - break; - case "channel": - switch (childElementName) - { - case "title": - channel.Title = elementText.ToString(); - break; - case "link": - try - { - channel.Link = new Uri(elementText.ToString()); - } - catch (Exception e) - { - exceptions.Add(e); - } - break; - case "description": - channel.Description = elementText.ToString(); - break; - case "language": - channel.Language = elementText.ToString(); - break; - case "copyright": - channel.Copyright = elementText.ToString(); - break; - case "managingeditor": - channel.ManagingEditor = elementText.ToString(); - break; - case "webmaster": - channel.WebMaster = elementText.ToString(); - break; - case "rating": - channel.Rating = elementText.ToString(); - break; - case "pubdate": - try - { - channel.PubDate = DateTime.Parse(elementText.ToString()); - } - catch (Exception e) - { - exceptions.Add(e); - } - break; - case "lastbuilddate": - try - { - channel.LastBuildDate = DateTime.Parse(elementText.ToString()); - } - catch (Exception e) - { - exceptions.Add(e); - } - break; - case "generator": - channel.Generator = elementText.ToString(); - break; - case "docs": - channel.Docs = elementText.ToString(); - break; - case "ttl": - try - { - channel.TimeToLive = int.Parse(elementText.ToString()); - } - catch (Exception e) - { - exceptions.Add(e); - } - break; - } - break; - case "image": - switch (childElementName) - { - case "url": - try - { - image.Url = new Uri(elementText.ToString()); - } - catch (Exception e) - { - exceptions.Add(e); - } - break; - case "title": - image.Title = elementText.ToString(); - break; - case "link": - try - { - image.Link = new Uri(elementText.ToString()); - } - catch (Exception e) - { - exceptions.Add(e); - } - break; - case "description": - image.Description = elementText.ToString(); - break; - case "width": - try - { - image.Width = Byte.Parse(elementText.ToString()); - } - catch (Exception e) - { - exceptions.Add(e); - } - break; - case "height": - try - { - image.Height = Byte.Parse(elementText.ToString()); - } - catch (Exception e) - { - exceptions.Add(e); - } - break; - } - break; - case "textinput": - switch (childElementName) - { - case "title": - textInput.Title = elementText.ToString(); - break; - case "description": - textInput.Description = elementText.ToString(); - break; - case "name": - textInput.Name = elementText.ToString(); - break; - case "link": - try - { - textInput.Link = new Uri(elementText.ToString()); - } - catch (Exception e) - { - exceptions.Add(e); - } - break; - } - break; - case "skipdays": - if (childElementName == "day") - switch (elementText.ToString().ToLower()) - { - case "monday": - channel.SkipDays[0] = true; - break; - case "tuesday": - channel.SkipDays[1] = true; - break; - case "wednesday": - channel.SkipDays[2] = true; - break; - case "thursday": - channel.SkipDays[3] = true; - break; - case "friday": - channel.SkipDays[4] = true; - break; - case "saturday": - channel.SkipDays[5] = true; - break; - case "sunday": - channel.SkipDays[6] = true; - break; - } - break; - case "skiphours": - if (childElementName == "hour") - channel.SkipHours[Byte.Parse(elementText.ToString().ToLower())] = true; - break; - } - break; - } - case XmlNodeType.Text: - elementText.Append(reader.Value); - break; - case XmlNodeType.CDATA: - elementText.Append(reader.Value); - break; - } - } - } - while (readData); - return rssElement; - } - /// A collection of all exceptions the RssReader class has encountered. - public ExceptionCollection Exceptions => exceptions; - - /// Gets the RSS version of the stream. - /// One of the values. - public RssVersion Version => rssVersion; - - /// Closes connection to file. - /// This method also releases any resources held while reading. - public void Close() - { - textInput = null; - image = null; - cloud = null; - channel = null; - source = null; - enclosure = null; - category = null; - item = null; - if (reader!=null) - { - reader.Close(); - reader = null; - } - elementText = null; - xmlNodeStack = null; - } - } -} diff --git a/SiteServer.Utils/Rss/RssWriter.cs b/SiteServer.Utils/Rss/RssWriter.cs deleted file mode 100644 index 19a991201..000000000 --- a/SiteServer.Utils/Rss/RssWriter.cs +++ /dev/null @@ -1,609 +0,0 @@ -/* RssWriter.cs - * ============ - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; -using System.Xml; -using System.Text; -using System.IO; - -namespace SiteServer.Utils.Rss -{ - /// Writes an RSS XML file. - /// Represents a writer that provides a fast, non-cached, forward-only way of generating streams or files containing RSS XML data that conforms to the W3C Extensible Markup Language (XML) 1.0 and the Namespaces in XML recommendations. - public class RssWriter - { - private XmlTextWriter writer = null; - - // functional var - private bool wroteStartDocument = false; - private bool wroteChannel = false; - - // prefrences - private RssVersion rssVersion = RssVersion.RSS20; - private Formatting xmlFormat = Formatting.Indented; - private int xmlIndentation = 2; - - // constants - private const string DateTimeFormatString = "ddd, dd MMM yyyy HH':'mm':'ss 'GMT'"; - - // modules - private RssModuleCollection _rssModules = new RssModuleCollection(); - - #region Constructors - - /// Creates an instance of the RssWriter class using the specified TextWriter. - /// specified TextWriter - public RssWriter(TextWriter textWriter) - { - writer = new XmlTextWriter(textWriter); - } - - /// Creates an instance of the RssWriter class using the specified Stream and Encoding. - /// The encoding is not supported or the stream cannot be written to. - /// Stream to output to - /// The encoding to use. If encoding is (null c#, Nothing vb) it writes out the stream as UTF-8. - public RssWriter(Stream stream, Encoding encoding) - { - writer = new XmlTextWriter(stream, encoding); - } - - /// Creates an instance of the RssWriter class using the specified Stream. - /// The encoding is ISO-8859-1. - /// The Stream cannot be written to. - /// specified Stream - public RssWriter(Stream stream) - { - writer = new XmlTextWriter(stream, Encoding.GetEncoding("ISO-8859-1")); - } - - /// Creates an instance of the RssWriter class using the specified file and Encoding. - /// The encoding is not supported; the filename is empty, contains only white space, or contains one or more invalid characters. - /// Access is denied. - /// The filename is a (null c#, Nothing vb) reference. - /// The directory to write to is not found. - /// The filename includes an incorrect or invalid syntax for file name, directory name, or volume label syntax. - /// The caller does not have the required permission. - /// specified file (including path) If the file exists, it will be truncated with the new content. - /// specified Encoding - public RssWriter(string fileName, Encoding encoding) - { - writer = new XmlTextWriter(fileName, encoding); - } - - /// Creates an instance of the RssWriter class using the specified file. - /// The encoding is ISO-8859-1. - /// The filename is empty, contains only white space, or contains one or more invalid characters. - /// Access is denied. - /// The filename is a (null c#, Nothing vb) reference. - /// The directory to write to is not found. - /// The filename includes an incorrect or invalid syntax for file name, directory name, or volume label syntax. - /// The caller does not have the required permission. - /// specified file (including path) If the file exists, it will be truncated with the new content. - public RssWriter(string fileName) - { - writer = new XmlTextWriter(fileName, Encoding.GetEncoding("ISO-8859-1")); - } - #endregion - - /// Writes the begining data to the RSS file - /// This routine is called from the WriteChannel and WriteItem subs - /// RDF Site Summary (RSS) 1.0 is not currently supported. - private void BeginDocument() - { - if (!wroteStartDocument) - { - if (rssVersion == RssVersion.Empty) - rssVersion = RssVersion.RSS20; - writer.Formatting = xmlFormat; - writer.Indentation = xmlIndentation; - writer.WriteStartDocument(); - if (rssVersion != RssVersion.RSS20) - writer.WriteComment("Generated by RSS.NET: http://rss-net.sf.net"); - - //exc: The xml:space or xml:lang attribute value is invalid. - switch (rssVersion) - { - case RssVersion.RSS090: - // - writer.WriteStartElement("RDF", "rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#"); - break; - case RssVersion.RSS091: - writer.WriteStartElement("rss"); - writer.WriteDocType("rss", "-//Netscape Communications//DTD RSS 0.91//EN", "http://my.netscape.com/publish/formats/rss-0.91.dtd", null); - writer.WriteAttributeString("version", "0.91"); - break; - case RssVersion.RSS092: - writer.WriteStartElement("rss"); - writer.WriteAttributeString("version", "0.92"); - break; - case RssVersion.RSS10: - throw new NotSupportedException("RDF Site Summary (RSS) 1.0 is not currently supported."); - case RssVersion.RSS20: - writer.WriteStartElement("rss"); - writer.WriteAttributeString("version", "2.0"); - // RSS Modules - foreach(RssModule rssModule in _rssModules) - { - WriteAttribute("xmlns:" + rssModule.NamespacePrefix, rssModule.NamespaceURL.ToString(), true); - } - break; - } - wroteStartDocument = true; - } - } - private void writeChannel(RssChannel channel) - { - if (writer == null) - throw new InvalidOperationException("RssWriter has been closed, and can not be written to."); - if (channel == null) - throw new ArgumentNullException("Channel must be instanciated with data to be written."); - - if (wroteChannel) - writer.WriteEndElement(); - else - wroteChannel = true; - - BeginDocument(); - - writer.WriteStartElement("channel"); - WriteElement("title", channel.Title, true); - WriteElement("description", channel.Description, true); - WriteElement("link", channel.Link, true); - if (channel.Image != null) - { - writer.WriteStartElement("image"); - WriteElement("title", channel.Image.Title, true); - WriteElement("url", channel.Image.Url, true); - WriteElement("link", channel.Image.Link, true); - switch (rssVersion) - { - case RssVersion.RSS091: - case RssVersion.RSS092: - case RssVersion.RSS20: - WriteElement("description", channel.Image.Description, false); - WriteElement("width", channel.Image.Width, false); - WriteElement("height", channel.Image.Height, false); - break; - } - writer.WriteEndElement(); - } - switch (rssVersion) - { - case RssVersion.RSS091: - case RssVersion.RSS092: - case RssVersion.RSS20: - WriteElement("language", channel.Language, rssVersion == RssVersion.RSS091); - WriteElement("copyright", channel.Copyright, false); - WriteElement("managingEditor", channel.ManagingEditor, false); - WriteElement("webMaster", channel.WebMaster, false); - WriteElement("pubDate", channel.PubDate, false); - WriteElement("lastBuildDate", channel.LastBuildDate, false); - if (channel.Docs != RssDefault.String) - WriteElement("docs", channel.Docs, false); - else - switch (rssVersion) - { - case RssVersion.RSS091: - WriteElement("docs", "http://my.netscape.com/publish/formats/rss-spec-0.91.html", false); - break; - case RssVersion.RSS092: - WriteElement("docs", "http://backend.userland.com/rss092", false); - break; - case RssVersion.RSS20: - WriteElement("docs", "http://backend.userland.com/rss", false); - break; - } - WriteElement("rating", channel.Rating, false); - string[] Days = {"monday","tuesday","wednesday","thursday","friday","saturday","sunday"}; - for (var i = 0; i <= 6; i++) - if (channel.SkipDays[i]) - { - writer.WriteStartElement("skipDays"); - for (var i2 = 0; i2 <= 6; i2++) - if (channel.SkipDays[i2]) - WriteElement("day", Days[i2], false); - writer.WriteEndElement(); - break; - } - for (var i = 0; i <= 23; i++) - if (channel.SkipHours[i]) - { - writer.WriteStartElement("skipHours"); - for (var i2 = 0; i2<= 23; i2++) - if (channel.SkipHours[i2]) - WriteElement("hour", i2+1, false); - writer.WriteEndElement(); - break; - } - break; - } - switch (rssVersion) - { - case RssVersion.RSS092: - case RssVersion.RSS20: - if (channel.Categories != null) - foreach(RssCategory category in channel.Categories) - if (category.Name != RssDefault.String) - { - writer.WriteStartElement("category"); - WriteAttribute("domain", category.Domain, false); - writer.WriteString(category.Name); - writer.WriteEndElement(); - } - if (channel.Cloud != null) - { - writer.WriteStartElement("cloud"); - WriteElement("domain", channel.Cloud.Domain, false); - WriteElement("port", channel.Cloud.Port, false); - WriteElement("path", channel.Cloud.Path, false); - WriteElement("registerProcedure", channel.Cloud.RegisterProcedure, false); - if (channel.Cloud.Protocol != RssCloudProtocol.Empty) - WriteElement("Protocol", channel.Cloud.Protocol, false); - writer.WriteEndElement(); - } - break; - } - if (rssVersion == RssVersion.RSS20) - { - if (channel.Generator != RssDefault.String) - WriteElement("generator", channel.Generator, false); - else - WriteElement("generator", "RSS.NET: http://www.rssdotnet.com/", false); - WriteElement("ttl", channel.TimeToLive, false); - - // RSS Modules - foreach(RssModule rssModule in _rssModules) - { - if(rssModule.IsBoundTo(channel.GetHashCode())) - { - foreach(RssModuleItem rssModuleItem in rssModule.ChannelExtensions) - { - if(rssModuleItem.SubElements.Count == 0) - WriteElement(rssModule.NamespacePrefix + ":" + rssModuleItem.Name, rssModuleItem.Text, rssModuleItem.IsRequired); - else - writeSubElements(rssModuleItem.SubElements, rssModule.NamespacePrefix); - } - } - } - } - if (channel.TextInput != null) - { - writer.WriteStartElement("textinput"); - WriteElement("title", channel.TextInput.Title, true); - WriteElement("description", channel.TextInput.Description, true); - WriteElement("name", channel.TextInput.Name, true); - WriteElement("link", channel.TextInput.Link, true); - writer.WriteEndElement(); - } - foreach (RssItem item in channel.Items) - { - writeItem(item, channel.GetHashCode()); - } - writer.Flush(); - } - private void writeItem(RssItem item, int channelHashCode) - { - if (writer == null) - throw new InvalidOperationException("RssWriter has been closed, and can not be written to."); - if (item == null) - throw new ArgumentNullException("Item must be instanciated with data to be written."); - if (!wroteChannel) - throw new InvalidOperationException("Channel must be written first, before writing an item."); - - BeginDocument(); - - writer.WriteStartElement("item"); - switch (rssVersion) - { - case RssVersion.RSS090: - case RssVersion.RSS10: - case RssVersion.RSS091: - WriteElement("title", item.Title, true); - WriteElement("description", item.Description, false); - WriteElement("link", item.Link, true); - break; - case RssVersion.RSS20: - if ((item.Title == RssDefault.String) && (item.Description == RssDefault.String)) - throw new ArgumentException("item title and description cannot be null"); - goto case RssVersion.RSS092; - case RssVersion.RSS092: - WriteElement("title", item.Title, false); - WriteElement("description", item.Description, false); - WriteElement("link", item.Link, false); - if (item.Source != null) - { - writer.WriteStartElement("source"); - WriteAttribute("url", item.Source.Url, true); - writer.WriteString(item.Source.Name); - writer.WriteEndElement(); - } - if (item.Enclosure != null) - { - writer.WriteStartElement("enclosure"); - WriteAttribute("url", item.Enclosure.Url, true); - WriteAttribute("length", item.Enclosure.Length, true); - WriteAttribute("type", item.Enclosure.Type, true); - writer.WriteEndElement(); - } - foreach(RssCategory category in item.Categories) - if (category.Name != RssDefault.String) - { - writer.WriteStartElement("category"); - WriteAttribute("domain", category.Domain, false); - writer.WriteString(category.Name); - writer.WriteEndElement(); - } - break; - } - if (rssVersion == RssVersion.RSS20) - { - WriteElement("author", item.Author, false); - WriteElement("comments", item.Comments, false); - if ((item.Guid != null) && (item.Guid.Name != RssDefault.String)) - { - writer.WriteStartElement("guid"); - try { - WriteAttribute("isPermaLink", (bool)item.Guid.PermaLink, false); - } catch {} - writer.WriteString(item.Guid.Name); - writer.WriteEndElement(); - } - WriteElement("pubDate", item.PubDate, false); - - foreach(RssModule rssModule in _rssModules) - { - if(rssModule.IsBoundTo(channelHashCode)) - { - foreach(RssModuleItemCollection rssModuleItemCollection in rssModule.ItemExtensions) - { - if(rssModuleItemCollection.IsBoundTo(item.GetHashCode())) - writeSubElements(rssModuleItemCollection, rssModule.NamespacePrefix); - } - } - } - } - writer.WriteEndElement(); - writer.Flush(); - } - /// Closes instance of RssWriter. - /// Writes end elements, and releases connections - /// Occurs if the RssWriter is already closed or the caller is attempting to close before writing a channel. - public void Close() - { - if (writer == null) - throw new InvalidOperationException("RssWriter has been closed, and can not be closed again."); - - if (!wroteChannel) - throw new InvalidOperationException("Can't close RssWriter without first writing a channel."); - else - writer.WriteEndElement(); // - - writer.WriteEndElement(); // or - writer.Close(); - writer = null; - } - /// Gets or sets the RSS version to write. - /// Can't change version number after data has been written. - public RssVersion Version - { - get { return rssVersion; } - set - { - if(wroteStartDocument) - throw new InvalidOperationException("Can't change version number after data has been written."); - else - rssVersion = value; - } - } - /// Gets or sets the of the XML output. - /// Can't change XML formatting after data has been written. - public Formatting XmlFormat - { - get { return xmlFormat; } - set - { - if(wroteStartDocument) - throw new InvalidOperationException("Can't change XML formatting after data has been written."); - else - xmlFormat = value; - } - } - /// Gets or sets how indentation to write for each level in the hierarchy when XmlFormat is set to - /// Can't change XML formatting after data has been written. - /// Setting this property to a negative value. - public int XmlIndentation - { - get { return xmlIndentation; } - set - { - if(wroteStartDocument) - throw new InvalidOperationException("Can't change XML indentation after data has been written."); - else - if (value < 0) - throw new ArgumentException("Setting this property to a negative value."); - else - xmlIndentation = value; - } - } - /// Writes an RSS channel - /// RssWriter has been closed, and can not be written to. - /// Channel must be instanciated with data, before calling Write. - /// RSS channel to write - public void Write(RssChannel channel) - { - writeChannel(channel); - } - /// Writes an RSS item - /// Either the RssWriter has already been closed, or the caller is attempting to write an RSS item before an RSS channel. - /// Item must be instanciated with data, before calling Write. - /// RSS item to write - public void Write(RssItem item) - { - // NOTE: Standalone items cannot adhere to modules, hence -1 is passed. This may not be the case, however, no examples have been seen where this is legal. - writeItem(item, -1); - } - - /// RSS modules - public RssModuleCollection Modules - { - get { return _rssModules; } - set { _rssModules = value; } - } - #region WriteElement - /// Writes an element with the specified local name and value - /// the localname of the element - /// the value of the element - /// boolean that determines if input cannot be null - private void WriteElement(string localName, DateTime input, bool required) - { - if (input != RssDefault.DateTime) - writer.WriteElementString(localName, XmlConvert.ToString(input,DateTimeFormatString)); - else if (required) - throw new ArgumentException(localName + " can not be null."); - } - /// Writes an element with the specified local name and value - /// the localname of the element - /// the value of the element - /// boolean that determines if input cannot be null - private void WriteElement(string localName, int input, bool required) - { - if (input != RssDefault.Int) - writer.WriteElementString(localName, XmlConvert.ToString(input)); - else if (required) - throw new ArgumentException(localName + " can not be null."); - } - /// Writes an element with the specified local name and value - /// the localname of the element - /// the value of the element - /// boolean that determines if input cannot be null - private void WriteElement(string localName, string input, bool required) - { - if (input != RssDefault.String) - writer.WriteElementString(localName, input); - else if (required) - throw new ArgumentException(localName + " can not be null."); - } - /// Writes an element with the specified local name and value - /// the localname of the element - /// the value of the element - /// boolean that determines if input cannot be null - private void WriteElement(string localName, Uri input, bool required) - { - if (input != RssDefault.Uri) - writer.WriteElementString(localName, input.ToString()); - else if (required) - throw new ArgumentException(localName + " can not be null."); - } - /// Writes an element with the specified local name and value - /// the localname of the element - /// the value of the element - /// boolean that determines if input cannot be null - private void WriteElement(string localName, object input, bool required) - { - if (input != null) - writer.WriteElementString(localName, input.ToString()); - else if (required) - throw new ArgumentException(localName + " can not be null."); - } - #endregion - #region WriteAttribute - /// Writes an attribute with the specified local name and value - /// the localname of the element - /// the value of the element - /// boolean that determines if input cannot be null - private void WriteAttribute(string localName, DateTime input, bool required) - { - if (input != RssDefault.DateTime) - writer.WriteAttributeString(localName, XmlConvert.ToString(input,DateTimeFormatString)); - else if (required) - throw new ArgumentException(localName + " can not be null."); - } - /// Writes an attribute with the specified local name and value - /// the localname of the element - /// the value of the element - /// boolean that determines if input cannot be null - private void WriteAttribute(string localName, int input, bool required) - { - if (input != RssDefault.Int) - writer.WriteAttributeString(localName, XmlConvert.ToString(input)); - else if (required) - throw new ArgumentException(localName + " can not be null."); - } - /// Writes an attribute with the specified local name and value - /// the localname of the element - /// the value of the element - /// boolean that determines if input cannot be null - private void WriteAttribute(string localName, string input, bool required) - { - if (input != RssDefault.String) - writer.WriteAttributeString(localName, input); - else if (required) - throw new ArgumentException(localName + " can not be null."); - } - /// Writes an attribute with the specified local name and value - /// the localname of the element - /// the value of the element - /// boolean that determines if input cannot be null - private void WriteAttribute(string localName, Uri input, bool required) - { - if (input != RssDefault.Uri) - writer.WriteAttributeString(localName, input.ToString()); - else if (required) - throw new ArgumentException(localName + " can not be null."); - } - /// Writes an attribute with the specified local name and value - /// the localname of the element - /// the value of the element - /// boolean that determines if input cannot be null - private void WriteAttribute(string localName, object input, bool required) - { - if (input != null) - writer.WriteAttributeString(localName, input.ToString()); - else if (required) - throw new ArgumentException(localName + " can not be null."); - } - #endregion - #region WriteSubElements - private void writeSubElements(RssModuleItemCollection items, string NamespacePrefix) - { - foreach(RssModuleItem rssModuleItem in items) - { - if(rssModuleItem.SubElements.Count == 0) - WriteElement(NamespacePrefix + ":" + rssModuleItem.Name, rssModuleItem.Text, rssModuleItem.IsRequired); - else - { - writer.WriteStartElement(NamespacePrefix + ":" + rssModuleItem.Name); - writeSubElements(rssModuleItem.SubElements, NamespacePrefix); - writer.WriteEndElement(); - } - } - } - #endregion - } -} diff --git a/SiteServer.Utils/Rss/Shared/DBBool.cs b/SiteServer.Utils/Rss/Shared/DBBool.cs deleted file mode 100644 index 2c2c0e866..000000000 --- a/SiteServer.Utils/Rss/Shared/DBBool.cs +++ /dev/null @@ -1,175 +0,0 @@ -/* DBBool.cs - * ========= - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// Represents Null, False, and True - /// Source: Microsoft c# example - [SerializableAttribute()] - public struct DBBool - { - /// A DBBool containing 'Null'. - /// One of three possible DBBool values. - public static readonly DBBool Null = new DBBool(0); - /// A DBBool containing 'False'. - /// One of three possible DBBool values. - public static readonly DBBool False = new DBBool(-1); - /// A DBBool containing 'True'. - /// One of three possible DBBool values. - public static readonly DBBool True = new DBBool(1); - /// Private field that stores ?, 0, 1 for False, Null, True. - sbyte value; - /// Private instance constructor. The value parameter must be ?, 0, or 1. - DBBool(int value) - { - this.value = (sbyte)value; - } - /// Properties to examine the value of a DBBool. - /// Return true if this DBBool has the given value, false otherwise. - public bool IsNull => value == 0; - - /// Properties to examine the value of a DBBool. - /// Return true if this DBBool has the given value, false otherwise. - public bool IsFalse => value < 0; - - /// Properties to examine the value of a DBBool. - /// Return true if this DBBool has the given value, false otherwise. - public bool IsTrue => value > 0; - - /// Implicit conversion from bool to DBBool. Maps true to DBBool.True and false to DBBool.False. - /// a DBBool - public static implicit operator DBBool(bool x) - { - return x? True: False; - } - /// Explicit conversion from DBBool to bool. - /// The given DBBool is Null - /// a DBBool - /// true or false - public static explicit operator bool(DBBool x) - { - if (x.value == 0) throw new InvalidOperationException(); - return x.value > 0; - } - /// Equality operator. - /// a DBBool - /// a DBBool - /// Returns Null if either operand is Null, otherwise returns True or False. - public static DBBool operator ==(DBBool x, DBBool y) - { - if (x.value == 0 || y.value == 0) return Null; - return x.value == y.value? True: False; - } - /// Inequality operator. - /// a DBBool - /// a DBBool - /// Returns Null if either operand is Null, otherwise returns True or False. - public static DBBool operator !=(DBBool x, DBBool y) - { - if (x.value == 0 || y.value == 0) return Null; - return x.value != y.value? True: False; - } - /// Logical negation operator. - /// a DBBool - /// Returns True if the operand is False, Null if the operand is Null, or False if the operand is True. - public static DBBool operator !(DBBool x) - { - return new DBBool(-x.value); - } - /// Logical AND operator. - /// a DBBool - /// a DBBool - /// Returns False if either operand is False, otherwise Null if either operand is Null, otherwise True. - public static DBBool operator &(DBBool x, DBBool y) - { - return new DBBool(x.value < y.value? x.value: y.value); - } - /// Logical OR operator. - /// a DBBool - /// a DBBool - /// Returns True if either operand is True, otherwise Null if either operand is Null, otherwise False. - public static DBBool operator |(DBBool x, DBBool y) - { - return new DBBool(x.value > y.value? x.value: y.value); - } - /// Definitely true operator. - /// a DBBool - /// Returns true if the operand is True, false otherwise. - public static bool operator true(DBBool x) - { - return x.value > 0; - } - /// Definitely false operator. - /// a DBBool - /// Returns true if the operand is False, false otherwise. - public static bool operator false(DBBool x) - { - return x.value < 0; - } - /// Determines whether two DBBool instances are equal. - /// The object to check. - /// True if the two DBBools are equal. - public override bool Equals(object o) - { - try - { - return (bool) (this == (DBBool) o); - } - catch - { - return false; - } - } - /// Serves as a hash function for a particular type, suitable for use in hashing algorithms and data structures like a hash table. - /// A hash code for the current DBBool. - public override int GetHashCode() - { - return value; - } - /// Returns a string representation of the current Object. - /// Object has not been initialized. - /// A string containing DBBool.False, DBBool.Null, or DBBool.True - public override string ToString() - { - switch (value) - { - case -1: - return "false"; - case 0: - return "DBBool.Null"; - case 1: - return "true"; - default: - throw new InvalidOperationException(); - } - } - } -} diff --git a/SiteServer.Utils/Rss/Shared/RssCategory.cs b/SiteServer.Utils/Rss/Shared/RssCategory.cs deleted file mode 100644 index dc28760d2..000000000 --- a/SiteServer.Utils/Rss/Shared/RssCategory.cs +++ /dev/null @@ -1,58 +0,0 @@ -/* RssCategory.cs - * ============== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// Provide information regarding the location of the subject matter of the channel in a taxonomy - [SerializableAttribute()] - public class RssCategory : RssElement - { - private string name = RssDefault.String; - private string domain = RssDefault.String; - - /// Initialize a new instance of the RssCategory class - public RssCategory() {} - - /// Actual categorization given for this item, within the chosen taxonomy - public string Name - { - get { return name; } - set { name = RssDefault.Check(value); } - } - /// URL of external taxonomy - public string Domain - { - get { return domain; } - set { domain = RssDefault.Check(value); } - } - } - -} diff --git a/SiteServer.Utils/Rss/Shared/RssCompact.cs b/SiteServer.Utils/Rss/Shared/RssCompact.cs deleted file mode 100644 index 4ae420fe7..000000000 --- a/SiteServer.Utils/Rss/Shared/RssCompact.cs +++ /dev/null @@ -1,45 +0,0 @@ -/* RssCompact.cs - * ============= - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -// This file is required to build the RSS library on the .NET Compact Framework. - -namespace SiteServer.Utils.Rss -{ - /// Class does not exist on the .NET Compact Framework - class Serializable : Attribute {} - /// Class does not exist on the .NET Compact Framework - class SecurityPermissionAttribute : Attribute - { - public SecurityPermissionAttribute(SecurityAction securityAction) {} - } - /// Enumerator does not exist on the .NET Compact Framework - enum SecurityAction { RequestMinimum } -} \ No newline at end of file diff --git a/SiteServer.Utils/Rss/Shared/RssDefault.cs b/SiteServer.Utils/Rss/Shared/RssDefault.cs deleted file mode 100644 index 3496a32b6..000000000 --- a/SiteServer.Utils/Rss/Shared/RssDefault.cs +++ /dev/null @@ -1,79 +0,0 @@ -/* RssDefault.cs - * ============= - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// Contains default values and methods for maintaining data consistency - [SerializableAttribute()] - public class RssDefault - { - /// Default value for a string in all RSS classes - /// empty string - /// If an element in the RSS class library has the value of RssDefault.String, consider the element as "not entered", "null", or empty. - public const string String = ""; - /// Default value for an int in all RSS classes - /// -1 - /// If an element in the RSS class library has the value of RssDefault.Int, consider the element as "not entered", "null", or empty. - public const int Int = -1; - /// Default value for a DateTime in all RSS classes - /// DateTime.MinValue - /// If an element in the RSS class library has the value of RssDefault.DateTime, consider the element as "not entered", "null", or empty. - public static readonly DateTime DateTime = DateTime.MinValue; - /// Default value for a Uri in all RSS classes - /// gopher://rss-net.sf.net - /// If an element in the RSS class library has the value of RssDefault.Uri, consider the element as "not entered", "null", or empty. - public static readonly Uri Uri = new Uri("gopher://rss-net.sf.net"); - /// Verifies the string passed is not null - /// string to verify - /// RssDefault.String if input is null, otherwise input - /// Method is used in properties to prevent a null value - public static string Check(string input) - { - return input == null ? String : input; - } - /// Verifies the int passed is greater than or equal to -1 - /// int to verify - /// RssDefault.Int if int is less than -1, else input - /// Method is used in properties to prevent values less than -1 - public static int Check(int input) - { - return input < -1 ? Int : input; - } - /// Verifies the Uri passed is not null - /// Uri to verify - /// RssDefault.Uri if input is null, otherwise input - /// Method is used in all properties to prevent a null value - public static Uri Check(Uri input) - { - return input == null ? Uri : input; - } - } -} diff --git a/SiteServer.Utils/Rss/Shared/RssElement.cs b/SiteServer.Utils/Rss/Shared/RssElement.cs deleted file mode 100644 index 58834b57d..000000000 --- a/SiteServer.Utils/Rss/Shared/RssElement.cs +++ /dev/null @@ -1,41 +0,0 @@ -/* RssElement.cs - * ============= - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// Base class for all RSS elements - [SerializableAttribute()] - public abstract class RssElement - { - /// Initialize a new instance of the RssElement class - protected RssElement() {} - } -} \ No newline at end of file diff --git a/SiteServer.Utils/Rss/Shared/RssEnumerators.cs b/SiteServer.Utils/Rss/Shared/RssEnumerators.cs deleted file mode 100644 index c74f0b028..000000000 --- a/SiteServer.Utils/Rss/Shared/RssEnumerators.cs +++ /dev/null @@ -1,68 +0,0 @@ -/* Enumerators.cs - * ============== - * - * RSS.NET (http://rss-net.sf.net/) - * Copyright ?2002, 2003 George Tsiokos. All Rights Reserved. - * - * RSS 2.0 (http://blogs.law.harvard.edu/tech/rss) - * RSS 2.0 is offered by the Berkman Center for Internet & Society at - * Harvard Law School under the terms of the Attribution/Share Alike - * Creative Commons license. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in all - * copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. -*/ -using System; - -namespace SiteServer.Utils.Rss -{ - /// All valid Rss Cloud protocols, including Null - [SerializableAttribute()] - public enum RssCloudProtocol - { - /// Not defined - Empty, - /// Protocol is not supported - NotSupported, - /// xml-rpc - XmlRpc, - /// soap - Soap, - /// http-post - HttpPost - } - /// All RSS versions - [SerializableAttribute()] - public enum RssVersion - { - /// Not defined - Empty, - /// Version is not directly supported - NotSupported, - /// RDF Site Summary (RSS) 0.9 - RSS090, - /// Rich Site Summary (RSS) 0.91 - RSS091, - /// Rich Site Summary (RSS) 0.92 - RSS092, - /// RDF Site Summary (RSS) 1.0 - RSS10, - /// Really Simple Syndication (RSS) 2.0 - RSS20 - } -} diff --git a/SiteServer.Utils/SiteServer.Utils.csproj b/SiteServer.Utils/SiteServer.Utils.csproj deleted file mode 100644 index 40a3bd3bb..000000000 --- a/SiteServer.Utils/SiteServer.Utils.csproj +++ /dev/null @@ -1,345 +0,0 @@ - - - - - - Debug - AnyCPU - {2176D8BA-5F57-4C56-8E21-A09011517AE2} - Library - Properties - SiteServer.Utils - SiteServer.Utils - v4.5.2 - 512 - - - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - ..\packages\ICSharpCode.SharpZipLib.dll.0.85.4.369\lib\net20\ICSharpCode.SharpZipLib.dll - - - ..\packages\MySql.Data.6.10.6\lib\net452\MySql.Data.dll - - - ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll - - - ..\packages\Npgsql.3.2.7\lib\net451\Npgsql.dll - - - ..\packages\Oracle.ManagedDataAccess.12.2.1100\lib\net40\Oracle.ManagedDataAccess.dll - True - - - ..\packages\SiteServer.Plugin.1.5.0\lib\net45\SiteServer.Plugin.dll - - - - - - - - - - - - - - ..\packages\System.Threading.Tasks.Extensions.4.3.0\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Microsoft.Exchange.CtsResources.GlobalizationStrings.cs - - - Microsoft.Exchange.CtsResources.SharedStrings.cs - - - Microsoft.Exchange.CtsResources.TextConvertersStrings.cs - - - - - - - - - - - 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - - - \ No newline at end of file diff --git a/SiteServer.Utils/SqlUtils.cs b/SiteServer.Utils/SqlUtils.cs deleted file mode 100644 index aa85e4385..000000000 --- a/SiteServer.Utils/SqlUtils.cs +++ /dev/null @@ -1,1566 +0,0 @@ -using System; -using System.Text; -using System.Data; -using System.Data.SqlClient; -using System.IO; -using System.Web.UI; -using MySql.Data.MySqlClient; -using Npgsql; -using NpgsqlTypes; -using Oracle.ManagedDataAccess.Client; -using SiteServer.Plugin; - -namespace SiteServer.Utils -{ - public static class SqlUtils - { - public const string Asterisk = "*"; - public const string OracleEmptyValue = "_EMPTY_"; - - public static string GetConnectionString(DatabaseType databaseType, string server, bool isDefaultPort, int port, string userName, string password, string database) - { - var connectionString = string.Empty; - - if (databaseType == DatabaseType.MySql) - { - connectionString = $"Server={server};"; - if (!isDefaultPort && port > 0) - { - connectionString += $"Port={port};"; - } - connectionString += $"Uid={userName};Pwd={password};"; - if (!string.IsNullOrEmpty(database)) - { - connectionString += $"Database={database};"; - } - } - else if (databaseType == DatabaseType.SqlServer) - { - connectionString = $"Server={server};"; - if (!isDefaultPort && port > 0) - { - connectionString += $"Port={port};"; - } - connectionString += $"Uid={userName};Pwd={password};"; - if (!string.IsNullOrEmpty(database)) - { - connectionString += $"Database={database};"; - } - } - else if (databaseType == DatabaseType.PostgreSql) - { - connectionString = $"Host={server};"; - if (!isDefaultPort && port > 0) - { - connectionString += $"Port={port};"; - } - connectionString += $"Username={userName};Password={password};"; - if (!string.IsNullOrEmpty(database)) - { - connectionString += $"Database={database};"; - } - } - else if (databaseType == DatabaseType.Oracle) - { - port = !isDefaultPort && port > 0 ? port : 1521; - database = string.IsNullOrEmpty(database) - ? string.Empty - : $"(CONNECT_DATA=(SERVICE_NAME={database}))"; - connectionString = $"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST={server})(PORT={port})){database});User ID={userName};Password={password};"; - } - - return connectionString; - } - - public static IDbConnection GetIDbConnection(DatabaseType databaseType, string connectionString) - { - IDbConnection conn = null; - - if (databaseType == DatabaseType.MySql) - { - conn = new MySqlConnection(connectionString); - } - else if (databaseType == DatabaseType.SqlServer) - { - conn = new SqlConnection(connectionString); - } - else if (databaseType == DatabaseType.PostgreSql) - { - conn = new NpgsqlConnection(connectionString); - } - else if (databaseType == DatabaseType.Oracle) - { - conn = new OracleConnection(connectionString); - } - - return conn; - } - - public static IDbCommand GetIDbCommand() - { - IDbCommand command = null; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - command = new MySqlCommand(); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - command = new SqlCommand(); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - command = new NpgsqlCommand(); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - command = new OracleCommand(); - } - - return command; - } - - public static IDbDataAdapter GetIDbDataAdapter(string text, string connectionString) - { - IDbDataAdapter adapter = null; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - adapter = new MySqlDataAdapter(text, connectionString); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - adapter = new SqlDataAdapter(text, connectionString); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - adapter = new NpgsqlDataAdapter(text, connectionString); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - adapter = new OracleDataAdapter(text, connectionString); - } - - return adapter; - } - - public static IDbDataAdapter GetIDbDataAdapter() - { - IDbDataAdapter adapter = null; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - adapter = new MySqlDataAdapter(); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - adapter = new SqlDataAdapter(); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - adapter = new NpgsqlDataAdapter(); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - adapter = new OracleDataAdapter(); - } - - return adapter; - } - - public static void FillDataAdapterWithDataTable(IDbDataAdapter adapter, DataTable table) - { - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - ((MySqlDataAdapter)adapter).Fill(table); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - ((SqlDataAdapter)adapter).Fill(table); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - ((NpgsqlDataAdapter)adapter).Fill(table); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - ((OracleDataAdapter)adapter).Fill(table); - } - } - - public static IDbDataParameter GetIDbDataParameter(string parameterName, DataType dataType, int size, object value) - { - IDbDataParameter parameter = null; - - if (size == 0) - { - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - parameter = new MySqlParameter(parameterName, ToMySqlDbType(dataType)) - { - Value = value - }; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - parameter = new SqlParameter(parameterName, ToSqlServerDbType(dataType)) - { - Value = value - }; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - parameter = new NpgsqlParameter(parameterName, ToNpgsqlDbType(dataType)) - { - Value = value - }; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - parameter = new OracleParameter(parameterName, ToOracleDbType(dataType)) - { - Value = ToOracleDbValue(dataType, value) - }; - } - } - else - { - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - parameter = new MySqlParameter(parameterName, ToMySqlDbType(dataType), size) - { - Value = value - }; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - parameter = new SqlParameter(parameterName, ToSqlServerDbType(dataType), size) - { - Value = value - }; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - parameter = new NpgsqlParameter(parameterName, ToNpgsqlDbType(dataType), size) - { - Value = value - }; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - parameter = new OracleParameter(parameterName, ToOracleDbType(dataType), size) - { - Value = ToOracleDbValue(dataType, value) - }; - } - } - - return parameter; - } - - public static string GetInStr(string columnName, string inStr) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"INSTR({columnName}, '{inStr}') > 0"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"CHARINDEX('{inStr}', {columnName}) > 0"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"POSITION('{inStr}' IN {columnName}) > 0"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"INSTR({columnName}, '{inStr}') > 0"; - } - - return retval; - } - - public static string GetInStrReverse(string inStr, string columnName) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"INSTR('{inStr}', {columnName}) > 0"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"CHARINDEX({columnName}, '{inStr}') > 0"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"POSITION({columnName} IN '{inStr}') > 0"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"INSTR('{inStr}', {columnName}) > 0"; - } - - return retval; - } - - public static string GetNotInStr(string columnName, string inStr) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"INSTR({columnName}, '{inStr}') = 0"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"CHARINDEX('{inStr}', {columnName}) = 0"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"POSITION('{inStr}' IN {columnName}) = 0"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"INSTR({columnName}, '{inStr}') = 0"; - } - - return retval; - } - - public static string GetNotNullAndEmpty(string columnName) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"LENGTH(IFNULL({columnName},'')) > 0"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"DATALENGTH({columnName}) > 0"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"LENGTH(COALESCE({columnName}, '')) > 0"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"LENGTH(COALESCE({columnName}, '')) > 0"; - } - - return retval; - } - - public static string GetNullOrEmpty(string columnName) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"LENGTH(IFNULL({columnName},'')) = 0"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"DATALENGTH({columnName}) = 0"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"LENGTH(COALESCE({columnName}, '')) = 0"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"LENGTH(COALESCE({columnName}, '')) = 0"; - } - - return retval; - } - - public static string ToTopSqlString(string tableName, string columns, string whereString, string orderString, int topN) - { - string retval = $"SELECT {columns} FROM {tableName} {whereString} {orderString}"; - if (topN <= 0) return retval; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"SELECT {columns} FROM {tableName} {whereString} {orderString} LIMIT {topN}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"SELECT TOP {topN} {columns} FROM {tableName} {whereString} {orderString}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"SELECT {columns} FROM {tableName} {whereString} {orderString} LIMIT {topN}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $@"SELECT {columns} FROM {tableName} {whereString} {orderString} FETCH FIRST {topN} ROWS ONLY"; - } - - return retval; - } - - public static string ToTopSqlString(string sqlString, string orderString, int topN) - { - string retval = $"SELECT * FROM ({sqlString}) {orderString}"; - if (topN <= 0) return retval; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"SELECT * FROM ({sqlString}) {orderString} LIMIT {topN}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"SELECT TOP {topN} * FROM ({sqlString}) {orderString}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"SELECT * FROM ({sqlString}) {orderString} LIMIT {topN}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $@"SELECT * FROM ({sqlString}) {orderString} FETCH FIRST {topN} ROWS ONLY"; - } - - return retval; - } - - public static string GetPageSqlString(string sqlString, string orderString, int itemsPerPage, int currentPageIndex, int pageCount, int recordsInLastPage) - { - var retval = string.Empty; - - var recsToRetrieve = itemsPerPage; - if (currentPageIndex == pageCount - 1) - { - recsToRetrieve = recordsInLastPage; - } - - orderString = orderString.ToUpper(); - var orderStringReverse = orderString.Replace(" DESC", " DESC2"); - orderStringReverse = orderStringReverse.Replace(" ASC", " DESC"); - orderStringReverse = orderStringReverse.Replace(" DESC2", " ASC"); - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $@" -SELECT * FROM ( - SELECT * FROM ( - SELECT * FROM ({sqlString}) AS t0 {orderString} LIMIT {itemsPerPage * (currentPageIndex + 1)} - ) AS t1 {orderStringReverse} LIMIT {recsToRetrieve} -) AS t2 {orderString}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $@" -SELECT * FROM ( - SELECT TOP {recsToRetrieve} * FROM ( - SELECT TOP {itemsPerPage * (currentPageIndex + 1)} * FROM ({sqlString}) AS t0 {orderString} - ) AS t1 {orderStringReverse} -) AS t2 {orderString}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $@" -SELECT * FROM ( - SELECT * FROM ( - SELECT * FROM ({sqlString}) AS t0 {orderString} LIMIT {itemsPerPage * (currentPageIndex + 1)} - ) AS t1 {orderStringReverse} LIMIT {recsToRetrieve} -) AS t2 {orderString}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $@" -SELECT * FROM ( - SELECT * FROM ( - SELECT * FROM ({sqlString}) {orderString} FETCH FIRST {itemsPerPage * (currentPageIndex + 1)} ROWS ONLY - ) {orderStringReverse} FETCH FIRST {recsToRetrieve} ROWS ONLY -) {orderString}"; - } - - return retval; - } - - public static string GetDistinctTopSqlString(string tableName, string columns, string whereString, string orderString, int topN) - { - var retval = $"SELECT DISTINCT {columns} FROM {tableName} {whereString} {orderString}"; - if (topN <= 0) return retval; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"SELECT DISTINCT {columns} FROM {tableName} {whereString} {orderString} LIMIT {topN}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"SELECT DISTINCT TOP {topN} {columns} FROM {tableName} {whereString} {orderString}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"SELECT DISTINCT {columns} FROM {tableName} {whereString} {orderString} LIMIT {topN}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"SELECT DISTINCT {columns} FROM {tableName} {whereString} {orderString} FETCH FIRST {topN} ROWS ONLY"; - } - - return retval; - } - - public static string ToInTopSqlString(string tableName, string columns, string whereString, string orderString, int topN) - { - var builder = new StringBuilder(); - if (WebConfigUtils.DatabaseType != DatabaseType.Oracle) - { - foreach (var column in TranslateUtils.StringCollectionToStringList(columns)) - { - builder.Append($"T.{column}, "); - } - builder.Length = builder.Length - 2; - return - $"SELECT {builder} FROM ({ToTopSqlString(tableName, columns, whereString, orderString, topN)}) AS T"; - } - - foreach (var column in TranslateUtils.StringCollectionToStringList(columns)) - { - builder.Append($"{column}, "); - } - builder.Length = builder.Length - 2; - return - $"SELECT {builder} FROM ({ToTopSqlString(tableName, columns, whereString, orderString, topN)})"; - } - - public static string GetColumnSqlString(DataType dataType, string attributeName, int length) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = ToMySqlColumnString(dataType, attributeName, length); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = ToSqlServerColumnString(dataType, attributeName, length); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = ToPostgreColumnString(dataType, attributeName, length); - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = ToOracleColumnString(dataType, attributeName, length); - } - - return retval; - } - - public static string GetAddColumnsSqlString(string tableName, string columnsSqlString) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"ALTER TABLE `{tableName}` ADD ({columnsSqlString})"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"ALTER TABLE [{tableName}] ADD {columnsSqlString}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"ALTER TABLE {tableName} ADD {columnsSqlString}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"ALTER TABLE {tableName} ADD {columnsSqlString}"; - } - - return retval; - } - - public static string GetDropTableSqlString(string tableName) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"DROP TABLE `{tableName}`"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"DROP TABLE [{tableName}]"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"DROP TABLE {tableName}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"DROP TABLE {tableName}"; - } - - return retval; - } - - public static string GetAutoIncrementDataType() - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = "INT AUTO_INCREMENT"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = "int IDENTITY (1, 1)"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = "SERIAL"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = "NUMBER GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1)"; - } - - return retval; - } - - public static DataType ToDataType(DatabaseType databaseType, string dataTypeStr) - { - if (string.IsNullOrEmpty(dataTypeStr)) return DataType.VarChar; - - var dataType = DataType.VarChar; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - dataTypeStr = dataTypeStr.ToLower().Trim(); - switch (dataTypeStr) - { - case "bit": - dataType = DataType.Boolean; - break; - case "datetime": - dataType = DataType.DateTime; - break; - case "decimal": - dataType = DataType.Decimal; - break; - case "int": - dataType = DataType.Integer; - break; - case "longtext": - dataType = DataType.Text; - break; - case "nvarchar": - dataType = DataType.VarChar; - break; - case "text": - dataType = DataType.Text; - break; - case "varchar": - dataType = DataType.VarChar; - break; - } - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - dataTypeStr = dataTypeStr.ToLower().Trim(); - switch (dataTypeStr) - { - case "bit": - dataType = DataType.Boolean; - break; - case "datetime": - dataType = DataType.DateTime; - break; - case "decimal": - dataType = DataType.Decimal; - break; - case "int": - dataType = DataType.Integer; - break; - case "ntext": - dataType = DataType.Text; - break; - case "nvarchar": - dataType = DataType.VarChar; - break; - case "text": - dataType = DataType.Text; - break; - case "varchar": - dataType = DataType.VarChar; - break; - } - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - dataTypeStr = dataTypeStr.ToLower().Trim(); - switch (dataTypeStr) - { - case "varchar": - dataType = DataType.VarChar; - break; - case "bool": - dataType = DataType.Boolean; - break; - case "timestamptz": - dataType = DataType.DateTime; - break; - case "numeric": - dataType = DataType.Decimal; - break; - case "int4": - dataType = DataType.Integer; - break; - case "text": - dataType = DataType.Text; - break; - } - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - dataTypeStr = dataTypeStr.ToUpper().Trim(); - if (dataTypeStr.StartsWith("TIMESTAMP(")) - { - dataType = DataType.DateTime; - } - else if (dataTypeStr == "NUMBER") - { - dataType = DataType.Integer; - } - else if (dataTypeStr == "NCLOB") - { - dataType = DataType.Text; - } - else if (dataTypeStr == "NVARCHAR2") - { - dataType = DataType.VarChar; - } - else if (dataTypeStr == "CLOB") - { - dataType = DataType.Text; - } - else if (dataTypeStr == "VARCHAR2") - { - dataType = DataType.VarChar; - } - } - - return dataType; - } - - public static SqlDbType ToSqlServerDbType(DataType type) - { - if (type == DataType.Boolean) - { - return SqlDbType.Bit; - } - if (type == DataType.DateTime) - { - return SqlDbType.DateTime; - } - if (type == DataType.Decimal) - { - return SqlDbType.Decimal; - } - if (type == DataType.Integer) - { - return SqlDbType.Int; - } - if (type == DataType.Text) - { - return SqlDbType.NText; - } - if (type == DataType.VarChar) - { - return SqlDbType.NVarChar; - } - return SqlDbType.VarChar; - } - - public static MySqlDbType ToMySqlDbType(DataType type) - { - if (type == DataType.Boolean) - { - return MySqlDbType.Bit; - } - if (type == DataType.DateTime) - { - return MySqlDbType.DateTime; - } - if (type == DataType.Decimal) - { - return MySqlDbType.Decimal; - } - if (type == DataType.Integer) - { - return MySqlDbType.Int32; - } - if (type == DataType.Text) - { - return MySqlDbType.LongText; - } - if (type == DataType.VarChar) - { - return MySqlDbType.VarString; - } - - return MySqlDbType.VarString; - } - - public static NpgsqlDbType ToNpgsqlDbType(DataType type) - { - if (type == DataType.Boolean) - { - return NpgsqlDbType.Boolean; - } - if (type == DataType.DateTime) - { - return NpgsqlDbType.TimestampTZ; - } - if (type == DataType.Decimal) - { - return NpgsqlDbType.Numeric; - } - if (type == DataType.Integer) - { - return NpgsqlDbType.Integer; - } - if (type == DataType.Text) - { - return NpgsqlDbType.Text; - } - return NpgsqlDbType.Varchar; - } - - public static object ToOracleDbValue(DataType dataType, object value) - { - // Oracle internally changes empty string to NULL values. Oracle simply won't let insert an empty string. So we replace string.Empty value to placeholder _EMPTY_ - if ((dataType == DataType.Text || dataType == DataType.VarChar) && value != null && value.ToString() == string.Empty) - { - return OracleEmptyValue; - } - return value; - } - - public static OracleDbType ToOracleDbType(DataType type) - { - if (type == DataType.Boolean) - { - return OracleDbType.Int32; - } - if (type == DataType.DateTime) - { - return OracleDbType.TimeStampTZ; - } - if (type == DataType.Decimal) - { - return OracleDbType.Decimal; - } - if (type == DataType.Integer) - { - return OracleDbType.Int32; - } - if (type == DataType.Text) - { - return OracleDbType.NClob; - } - return OracleDbType.NVarchar2; - } - - public static string ToMySqlColumnString(DataType type, string attributeName, int length) - { - if (type == DataType.Boolean) - { - return $"`{attributeName}` tinyint(1)"; - } - if (type == DataType.DateTime) - { - return $"`{attributeName}` datetime"; - } - if (type == DataType.Decimal) - { - return $"`{attributeName}` decimal(18, 2)"; - } - if (type == DataType.Integer) - { - return $"`{attributeName}` int"; - } - if (type == DataType.Text) - { - return $"`{attributeName}` longtext"; - } - return $"`{attributeName}` varchar({length})"; - } - - public static string ToSqlServerColumnString(DataType type, string attributeName, int length) - { - if (type == DataType.Boolean) - { - return $"[{attributeName}] [bit]"; - } - if (type == DataType.DateTime) - { - return $"[{attributeName}] [datetime]"; - } - if (type == DataType.Decimal) - { - return $"[{attributeName}] [decimal] (18, 2)"; - } - if (type == DataType.Integer) - { - return $"[{attributeName}] [int]"; - } - if (type == DataType.Text) - { - return $"[{attributeName}] [ntext]"; - } - return $"[{attributeName}] [nvarchar] ({length})"; - } - - public static string ToPostgreColumnString(DataType type, string attributeName, int length) - { - if (type == DataType.Boolean) - { - return $"{attributeName} bool"; - } - if (type == DataType.DateTime) - { - return $"{attributeName} timestamptz"; - } - if (type == DataType.Decimal) - { - return $"{attributeName} numeric(18, 2)"; - } - if (type == DataType.Integer) - { - return $"{attributeName} int4"; - } - if (type == DataType.Text) - { - return $"{attributeName} text"; - } - return $"{attributeName} varchar({length})"; - } - - public static string GetConnectionStringUserId(string connectionString) - { - try - { - var csb = new SqlConnectionStringBuilder(connectionString); - return csb.UserID; - } - catch - { - return string.Empty; - } - } - - public static string ToOracleColumnString(DataType type, string attributeName, int length) - { - if (type == DataType.Boolean) - { - return $"{attributeName} number(1)"; - } - if (type == DataType.DateTime) - { - return $"{attributeName} timestamp(6) with time zone"; - } - if (type == DataType.Decimal) - { - return $"{attributeName} number(38, 2)"; - } - if (type == DataType.Integer) - { - return $"{attributeName} number"; - } - if (type == DataType.Text) - { - return $"{attributeName} nclob"; - } - return $"{attributeName} nvarchar2({length})"; - } - - public static string GetDateDiffLessThanYears(string fieldName, string years) - { - return GetDateDiffLessThan(fieldName, years, "YEAR"); - } - - public static string GetDateDiffLessThanMonths(string fieldName, string months) - { - return GetDateDiffLessThan(fieldName, months, "MONTH"); - } - - public static string GetDateDiffLessThanDays(string fieldName, string days) - { - return GetDateDiffLessThan(fieldName, days, "DAY"); - } - - public static string GetDateDiffLessThanHours(string fieldName, string hours) - { - return GetDateDiffLessThan(fieldName, hours, "HOUR"); - } - - public static string GetDateDiffLessThanMinutes(string fieldName, string minutes) - { - return GetDateDiffLessThan(fieldName, minutes, "MINUTE"); - } - - private static int GetSecondsByUnit(string unit) - { - var seconds = 1; - if (unit == "MINUTE") - { - seconds = 60; - } - else if (unit == "HOUR") - { - seconds = 3600; - } - else if (unit == "DAY") - { - seconds = 86400; - } - else if (unit == "MONTH") - { - seconds = 2592000; - } - else if (unit == "YEAR") - { - seconds = 31536000; - } - return seconds; - } - - private static string GetDateDiffLessThan(string fieldName, string fieldValue, string unit) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"TIMESTAMPDIFF({unit}, {fieldName}, now()) < {fieldValue}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"DATEDIFF({unit}, {fieldName}, getdate()) < {fieldValue}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"EXTRACT(EPOCH FROM current_timestamp - {fieldName})/{GetSecondsByUnit(unit)} < {fieldValue}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"EXTRACT({unit} FROM CURRENT_TIMESTAMP - {fieldName}) < {fieldValue}"; - } - - return retval; - } - - public static string GetDateDiffGreatThanYears(string fieldName, string years) - { - return GetDateDiffGreatThan(fieldName, years, "YEAR"); - } - - public static string GetDateDiffGreatThanMonths(string fieldName, string months) - { - return GetDateDiffGreatThan(fieldName, months, "MONTH"); - } - - public static string GetDateDiffGreatThanDays(string fieldName, string days) - { - return GetDateDiffGreatThan(fieldName, days, "DAY"); - } - - public static string GetDateDiffGreatThanHours(string fieldName, string hours) - { - return GetDateDiffGreatThan(fieldName, hours, "HOUR"); - } - - public static string GetDateDiffGreatThanMinutes(string fieldName, string minutes) - { - return GetDateDiffGreatThan(fieldName, minutes, "MINUTE"); - } - - private static string GetDateDiffGreatThan(string fieldName, string fieldValue, string unit) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"TIMESTAMPDIFF({unit}, {fieldName}, now()) > {fieldValue}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"DATEDIFF({unit}, {fieldName}, getdate()) > {fieldValue}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"EXTRACT(EPOCH FROM current_timestamp - {fieldName})/{GetSecondsByUnit(unit)} > {fieldValue}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"EXTRACT({unit} FROM CURRENT_TIMESTAMP - {fieldName}) > {fieldValue}"; - } - - return retval; - } - - public static string GetDatePartYear(string fieldName) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"DATE_FORMAT({fieldName}, '%Y')"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"DATEPART([YEAR], {fieldName})"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"date_part('year', {fieldName})"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"EXTRACT(year from {fieldName})"; - } - - return retval; - } - - public static string GetDatePartMonth(string fieldName) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"DATE_FORMAT({fieldName}, '%c')"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"DATEPART([MONTH], {fieldName})"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"date_part('month', {fieldName})"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"EXTRACT(month from {fieldName})"; - } - - return retval; - } - - public static string GetDatePartDay(string fieldName) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"DATE_FORMAT({fieldName}, '%e')"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"DATEPART([DAY], {fieldName})"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"date_part('day', {fieldName})"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"EXTRACT(day from {fieldName})"; - } - - return retval; - } - - public static string GetDatePartHour(string fieldName) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"DATE_FORMAT({fieldName}, '%k')"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"DATEPART([HOUR], {fieldName})"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"date_part('hour', {fieldName})"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"EXTRACT(hour from {fieldName})"; - } - - return retval; - } - - public static string GetDatePartDayOfYear(string fieldName) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"DATE_FORMAT({fieldName}, '%j')"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"DATEPART([DAYOFYEAR], {fieldName})"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"date_part('doy', {fieldName})"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"TO_CHAR({fieldName}, 'DDD')"; - } - - return retval; - } - - public static string GetComparableNow() - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = "now()"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = "getdate()"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = "current_timestamp"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = "sysdate"; - } - - return retval; - } - - public static string GetComparableDate(DateTime dateTime) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"'{dateTime:yyyy-MM-dd}'"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"'{dateTime:yyyy-MM-dd}'"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"'{dateTime:yyyy-MM-dd}'"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"to_date('{dateTime:yyyy-MM-dd}', 'yyyy-mm-dd')"; - } - - return retval; - } - - public static string GetComparableDateTime(DateTime dateTime) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"'{dateTime:yyyy-MM-dd HH:mm:ss}'"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"'{dateTime:yyyy-MM-dd HH:mm:ss}'"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"'{dateTime:yyyy-MM-dd HH:mm:ss}'"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"to_date('{dateTime:yyyy-MM-dd HH:mm:ss}', 'yyyy-mm-dd hh24:mi:ss')"; - } - - return retval; - } - - public static string ToPlusSqlString(string fieldName, int plusNum = 1) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"{fieldName} = IFNULL({fieldName}, 0) + {plusNum}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"{fieldName} = ISNULL({fieldName}, 0) + {plusNum}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"{fieldName} = COALESCE({fieldName}, 0) + {plusNum}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"{fieldName} = COALESCE({fieldName}, 0) + {plusNum}"; - } - - return retval; - } - - public static string ToMinusSqlString(string fieldName, int minusNum = 1) - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = $"{fieldName} = IFNULL({fieldName}, 0) - {minusNum}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = $"{fieldName} = ISNULL({fieldName}, 0) - {minusNum}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = $"{fieldName} = COALESCE({fieldName}, 0) - {minusNum}"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = $"{fieldName} = COALESCE({fieldName}, 0) - {minusNum}"; - } - - return retval; - } - - public static string GetOrderByRandom() - { - var retval = string.Empty; - - if (WebConfigUtils.DatabaseType == DatabaseType.MySql) - { - retval = "ORDER BY RAND()"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) - { - retval = "ORDER BY NEWID() DESC"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) - { - retval = "ORDER BY random()"; - } - else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) - { - retval = "ORDER BY dbms_random.value()"; - } - - return retval; - } - - public static int GetMaxLengthForNVarChar() - { - return 4000; - } - - public static string ToSqlString(string inputString) - { - return !string.IsNullOrEmpty(inputString) ? inputString.Replace("'", "''") : string.Empty; - } - - public static string ToSqlString(string inputString, int maxLength) - { - if (string.IsNullOrEmpty(inputString)) return string.Empty; - - if (maxLength > 0 && inputString.Length > maxLength) - { - inputString = inputString.Substring(0, maxLength); - } - return inputString.Replace("'", "''"); - } - - /// - /// 验证此字符串是否合作作为字段名称 - /// - public static bool IsAttributeNameCompliant(string attributeName) - { - if (string.IsNullOrEmpty(attributeName) || attributeName.IndexOf(" ", StringComparison.Ordinal) != -1) return false; - if (-1 != attributeName.IndexOfAny(PathUtils.InvalidPathChars)) - { - return false; - } - foreach (var t in attributeName) - { - if (StringUtils.IsTwoBytesChar(t)) - { - return false; - } - } - return true; - } - - public static string ReadNextSqlString(StreamReader reader) - { - try - { - var sb = new StringBuilder(); - - while (true) - { - var lineOfText = reader.ReadLine(); - - if (lineOfText == null) - { - return sb.Length > 0 ? sb.ToString() : null; - } - - if (lineOfText.StartsWith("--")) continue; - lineOfText = lineOfText.Replace(")ENGINE=INNODB", ") ENGINE=InnoDB DEFAULT CHARSET=utf8"); - - if (lineOfText.TrimEnd().ToUpper() == "GO") - { - break; - } - - sb.Append(lineOfText + Environment.NewLine); - } - - return sb.ToString(); - } - catch - { - return null; - } - } - - public static string ReadNextStatementFromStream(StringReader reader) - { - try - { - var sb = new StringBuilder(); - - while (true) - { - var lineOfText = reader.ReadLine(); - if (lineOfText == null) - { - return sb.Length > 0 ? sb.ToString() : null; - } - - if (lineOfText.TrimEnd().ToUpper() == "GO") - { - break; - } - - sb.Append(lineOfText + Environment.NewLine); - } - - return sb.ToString(); - } - catch - { - return null; - } - } - - public static object Eval(object dataItem, string name) - { - object o = null; - try - { - o = DataBinder.Eval(dataItem, name); - } - catch - { - // ignored - } - if (o == DBNull.Value) - { - o = null; - } - return o; - } - - public static int EvalInt(object dataItem, string name) - { - var o = Eval(dataItem, name); - return o == null ? 0 : Convert.ToInt32(o); - } - - public static decimal EvalDecimal(object dataItem, string name) - { - var o = Eval(dataItem, name); - return o == null ? 0 : Convert.ToDecimal(o); - } - - public static string EvalString(object dataItem, string name) - { - var o = Eval(dataItem, name); - return o?.ToString() ?? string.Empty; - } - - public static DateTime EvalDateTime(object dataItem, string name) - { - var o = Eval(dataItem, name); - if (o == null) - { - return DateUtils.SqlMinValue; - } - return (DateTime)o; - } - - public static bool EvalBool(object dataItem, string name) - { - var o = Eval(dataItem, name); - return o != null && TranslateUtils.ToBool(o.ToString()); - } - - public static string GetDatabaseNameFormConnectionString(DatabaseType databaseType, string connectionString) - { - if (databaseType == DatabaseType.Oracle) - { - var index1 = connectionString.IndexOf("SERVICE_NAME=", StringComparison.Ordinal); - var index2 = connectionString.IndexOf(")));", StringComparison.Ordinal); - return connectionString.Substring(index1 + 13, index2 - index1 - 13); - } - return GetValueFromConnectionString(databaseType, connectionString, "Database"); - } - - public static string GetValueFromConnectionString(DatabaseType databaseType, string connectionString, string attribute) - { - var retval = string.Empty; - if (!string.IsNullOrEmpty(connectionString) && !string.IsNullOrEmpty(attribute)) - { - var pairs = connectionString.Split(';'); - foreach (var pair in pairs) - { - if (pair.IndexOf("=", StringComparison.Ordinal) != -1) - { - if (StringUtils.EqualsIgnoreCase(attribute, pair.Trim().Split('=')[0])) - { - retval = pair.Trim().Split('=')[1]; - break; - } - } - } - } - return retval; - } - - - } -} diff --git a/SiteServer.Utils/StringUtils.cs b/SiteServer.Utils/StringUtils.cs deleted file mode 100644 index f011e9fe9..000000000 --- a/SiteServer.Utils/StringUtils.cs +++ /dev/null @@ -1,1253 +0,0 @@ -using System; -using System.Text; -using System.Web; -using System.Text.RegularExpressions; -using System.Collections.Generic; -using System.Linq; -using System.Web.Script.Serialization; -using SiteServer.Utils.Enumerations; -using SiteServer.Plugin; - -namespace SiteServer.Utils -{ - public class StringUtils - { - public sealed class Constants - { - public const string ReturnAndNewline = "\r\n";//回车换行 - public const string Html5Empty = @""; - - public const string Ellipsis = "..."; - - //分钟基数 - public static readonly int MinuteFactorWeek = 5040; - public static readonly int MinuteFactorDay = 720; - public static readonly int MinuteFactorHour = 60; - - public const int PageSize = 25;//后台分页数 - public const string HideElementStyle = "display:none"; - public const string ShowElementStyle = "display:"; - - public const string TitleImageAppendix = "t_"; - public const string SmallImageAppendix = "s_"; - - public const string CompanyName = "北京百容千域软件技术开发有限责任公司"; - public const string CompanyUrl = "http://www.siteserver.cn"; - public const string ProductName = "SITESERVER"; - public const string ProductUrl = "http://www.siteserver.cn"; - - public static string GetStlUrl(bool isEntity, string label) - { - return isEntity ? $"http://stl.siteserver.cn/e-{label}/index.html" : $"http://stl.siteserver.cn/{label.Substring("stl:".Length)}/index.html"; - } - } - - public static bool IsMobile(string val) - { - return Regex.IsMatch(val, @"^1[3456789]\d{9}$", RegexOptions.IgnoreCase); - } - - public static bool IsEmail(string val) - { - return Regex.IsMatch(val, @"^\w+([-_+.]\w+)*@\w+([-_.]\w+)*\.\w+([-_.]\w+)*$", RegexOptions.IgnoreCase); - } - - public static bool IsIpAddress(string ip) - { - return Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$"); - } - - public static bool IsNumber(string val) - { - const string formatNumber = "^[0-9]+$"; - return Regex.IsMatch(val, formatNumber); - } - - public static bool IsDateTime(string val) - { - const string formatDate = @"^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$"; - const string formatDateTime = @"^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23|[0-1]?\d):[0-5]?\d:[0-5]?\d$"; - - return Regex.IsMatch(val, formatDate) || Regex.IsMatch(val, formatDateTime); - } - - public static bool In(string strCollection, int inInt) - { - return In(strCollection, inInt.ToString()); - } - - public static bool In(string strCollection, string inStr) - { - if (string.IsNullOrEmpty(strCollection)) return false; - return strCollection == inStr || strCollection.StartsWith(inStr + ",") || strCollection.EndsWith("," + inStr) || strCollection.IndexOf("," + inStr + ",", StringComparison.Ordinal) != -1; - } - - public static bool Contains(string text, string inner) - { - return text?.IndexOf(inner, StringComparison.Ordinal) >= 0; - } - - public static bool ContainsIgnoreCase(string text, string inner) - { - if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(inner)) return false; - return text.ToLower().IndexOf(inner.ToLower(), StringComparison.Ordinal) >= 0; - } - - public static string Trim(string text) - { - return string.IsNullOrEmpty(text) ? string.Empty : text.Trim(); - } - - public static string TrimAndToLower(string text) - { - return string.IsNullOrEmpty(text) ? string.Empty : text.ToLower().Trim(); - } - - public static string Remove(string text, int startIndex) - { - if (string.IsNullOrEmpty(text)) return string.Empty; - if (startIndex < 0) - { - throw new ArgumentOutOfRangeException(nameof(startIndex)); - } - if (startIndex >= text.Length) - { - throw new ArgumentOutOfRangeException(nameof(startIndex)); - } - return text.Substring(0, startIndex); - } - - public static string RemoveAttribute(string content, string attributeName) - { - string regex = $@"\s{attributeName}=\""[^\""]*\"""; - return RegexUtils.Replace(regex, content, string.Empty); - } - - public static string RemoveNewline(string inputString) - { - if (string.IsNullOrEmpty(inputString)) return string.Empty; - var retVal = new StringBuilder(); - inputString = inputString.Trim(); - for (var i = 0; i < inputString.Length; i++) - { - switch (i) - { - case '\n': - break; - case '\r': - break; - default: - retVal.Append(i); - break; - } - } - return retVal.ToString(); - } - - public static string Guid() - { - return System.Guid.NewGuid().ToString(); - } - - public static string GetShortGuid() - { - long i = 1; - foreach (var b in System.Guid.NewGuid().ToByteArray()) - { - i *= b + 1; - } - return $"{i - DateTime.Now.Ticks:x}"; - } - - public static string GetShortGuid(bool isUppercase) - { - long i = 1; - foreach (var b in System.Guid.NewGuid().ToByteArray()) - { - i *= b + 1; - } - string retval = $"{i - DateTime.Now.Ticks:x}"; - return isUppercase ? retval.ToUpper() : retval.ToLower(); - } - - /// - /// 获取json对象值 - /// - public static string GetJsonValue(string attributeName, string jsonContent) - { - var serializer = new JavaScriptSerializer(); - var json = (Dictionary)serializer.DeserializeObject(jsonContent); - object value; - if (json.TryGetValue(attributeName, out value)) - { - return Convert.ToString(value); - } - return string.Empty; - } - - public static string GetBoolText(bool type) - { - return type ? "是" : "否"; - } - - public static bool EqualsIgnoreCase(string a, string b) - { - if (a == b) return true; - if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(b)) return false; - return string.Equals(a.Trim().ToLower(), b.Trim().ToLower()); - } - - public static bool EqualsIgnoreNull(string a, string b) - { - return string.IsNullOrEmpty(a) ? string.IsNullOrEmpty(b) : string.Equals(a, b); - } - - public static bool EqualsIgnoreOrder(List idList, string idCollection) - { - if (idList == null || idList.Count == 0) - { - return string.IsNullOrEmpty(idCollection); - } - if (idList.Count > 0 && string.IsNullOrEmpty(idCollection)) return false; - - var idList2 = TranslateUtils.StringCollectionToIntList(idCollection); - - if (idList.Count != idList2.Count) return false; - - idList.Sort(); - idList2.Sort(); - - for (var i = 0; i < idList.Count; i++) - { - if (idList[i] != idList2[i]) - { - return false; - } - } - - return true; - } - - public static bool StartsWithIgnoreCase(string text, string startString) - { - if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(startString)) return false; - return text.Trim().ToLower().StartsWith(startString.Trim().ToLower()) || string.Equals(text.Trim(), startString.Trim(), StringComparison.CurrentCultureIgnoreCase); - } - - public static bool EndsWithIgnoreCase(string text, string endString) - { - if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(endString)) return false; - return text.Trim().ToLower().EndsWith(endString.Trim().ToLower()); - } - - public static bool StartsWith(string text, string startString) - { - if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(startString)) return false; - return text.StartsWith(startString); - } - - public static bool EndsWith(string text, string endString) - { - if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(endString)) return false; - return text.EndsWith(endString); - } - - public static bool StringEndsWith(string s, char c) - { - var num1 = s.Length; - if (num1 != 0) - { - return s[num1 - 1] == c; - } - return false; - } - - public static bool StringStartsWith(string s, char c) - { - if (s.Length != 0) - { - return s[0] == c; - } - return false; - } - - public static string InsertBefore(string[] insertBeforeArray, string content, string insertContent) - { - if (content == null) return string.Empty; - foreach (var insertBefore in insertBeforeArray) - { - if (content.IndexOf(insertBefore, StringComparison.Ordinal) != -1) - { - return InsertBefore(insertBefore, content, insertContent); - } - } - return content; - } - - public static string InsertBefore(string insertBefore, string content, string insertContent) - { - var retval = content; - if (insertBefore != null && content != null) - { - var startIndex = content.IndexOf(insertBefore, StringComparison.Ordinal); - if (startIndex != -1) - { - retval = content.Substring(0, startIndex) + insertContent + insertBefore + content.Substring(startIndex + insertBefore.Length); - } - } - return retval; - } - - public static bool InsertBefore(string[] insertBeforeArray, StringBuilder contentBuilder, string insertContent) - { - if (contentBuilder == null) return false; - foreach (var insertBefore in insertBeforeArray) - { - if (contentBuilder.ToString().IndexOf(insertBefore, StringComparison.Ordinal) != -1) - { - InsertBefore(insertBefore, contentBuilder, insertContent); - return true; - } - } - return false; - } - - public static void InsertBefore(string insertBefore, StringBuilder contentBuilder, string insertContent) - { - if (string.IsNullOrEmpty(insertBefore) || contentBuilder == null) return; - var startIndex = contentBuilder.ToString().IndexOf(insertBefore, StringComparison.Ordinal); - if (startIndex != -1) - { - contentBuilder.Insert(startIndex, insertContent); - } - } - - public static void InsertBeforeOrAppend(string[] insertBeforeArray, StringBuilder contentBuilder, string insertContent) - { - if (!InsertBefore(insertBeforeArray, contentBuilder, insertContent)) - { - contentBuilder.Append(insertContent); - } - } - - public static void InsertAfterOrAppend(string[] insertAfterArray, StringBuilder contentBuilder, string insertContent) - { - if (!InsertAfter(insertAfterArray, contentBuilder, insertContent)) - { - contentBuilder.Append(insertContent); - } - } - - public static bool InsertAfter(string[] insertAfterArray, StringBuilder contentBuilder, string insertContent) - { - if (contentBuilder != null) - { - foreach (var insertAfter in insertAfterArray) - { - if (contentBuilder.ToString().IndexOf(insertAfter, StringComparison.Ordinal) != -1) - { - InsertAfter(insertAfter, contentBuilder, insertContent); - return true; - } - } - } - return false; - } - - public static void InsertAfter(string insertAfter, StringBuilder contentBuilder, string insertContent) - { - if (string.IsNullOrEmpty(insertAfter) || contentBuilder == null) return; - var startIndex = contentBuilder.ToString().IndexOf(insertAfter, StringComparison.Ordinal); - if (startIndex == -1) return; - if (startIndex != -1) - { - contentBuilder.Insert(startIndex + insertAfter.Length, insertContent); - } - } - - public static string HtmlDecode(string inputString) - { - return HttpUtility.HtmlDecode(inputString); - } - - public static string HtmlEncode(string inputString) - { - return HttpUtility.HtmlEncode(inputString); - } - - public static string ToXmlContent(string inputString) - { - var contentBuilder = new StringBuilder(inputString); - contentBuilder.Replace("", string.Empty); - contentBuilder.Insert(0, ""); - return contentBuilder.ToString(); - } - - public static string StripTags(string inputString) - { - var retval = RegexUtils.Replace("]*>.*?<\\/script>", inputString, string.Empty); - retval = RegexUtils.Replace("<[\\/]?[^>]*>|<[\\S]+", retval, string.Empty); - return retval; - } - - public static string StripTagsExcludeBr(string inputString) - { - var content = RegexUtils.Replace("<[\\/]?br[^>]*>", inputString, "[_LineBreak_]"); - content = StripTags(content); - content = content.Replace("[_LineBreak_]", "
    "); - return content; - } - - public static string StripTags(string inputString, params string[] tagNames) - { - var retval = inputString; - foreach (var tagName in tagNames) - { - retval = RegexUtils.Replace($"<[\\/]?{tagName}[^>]*>|<{tagName}", retval, string.Empty); - } - return retval; - } - - public static string StripEntities(string inputString) - { - var retval = RegexUtils.Replace("&[^;]*;", inputString, string.Empty); - return retval; - } - - public static string CleanText(string text) - { - return StripTags(text); - } - - public static string CleanTextArea(string text) - { - text = StripTags(text); - text = ReplaceNewlineToBr(text); - return text; - } - - public static string ParseWordString(string wordString) - { - var parsedContent = RegexUtils.GetInnerContent("body", wordString); - parsedContent = parsedContent.Replace(@" -

     

    -", string.Empty); - return CleanTextArea(parsedContent.Trim()); - } - - public static string ReplaceIgnoreCase(string original, string pattern, string replacement) - { - if (original == null) return string.Empty; - if (replacement == null) replacement = string.Empty; - var count = 0; - var position0 = 0; - int position1; - var upperString = original.ToUpper(); - var upperPattern = pattern.ToUpper(); - var inc = (original.Length / pattern.Length) * (replacement.Length - pattern.Length); - var chars = new char[original.Length + Math.Max(0, inc)]; - while ((position1 = upperString.IndexOf(upperPattern, position0, StringComparison.Ordinal)) != -1) - { - for (var i = position0; i < position1; ++i) chars[count++] = original[i]; - foreach (var t in replacement) - { - chars[count++] = t; - } - position0 = position1 + pattern.Length; - } - if (position0 == 0) return original; - for (var i = position0; i < original.Length; ++i) chars[count++] = original[i]; - return new string(chars, 0, count); - } - - public static string Replace(string replace, string input, string to) - { - var retval = RegexUtils.Replace(replace, input, to); - if (string.IsNullOrEmpty(replace)) return retval; - if (replace.StartsWith("/") && replace.EndsWith("/")) - { - retval = RegexUtils.Replace(replace.Trim('/'), input, to); - } - else - { - retval = input.Replace(replace, to); - } - return retval; - } - - public static void ReplaceHrefOrSrc(StringBuilder builder, string replace, string to) - { - builder.Replace("href=\"" + replace, "href=\"" + to); - builder.Replace("href='" + replace, "href='" + to); - builder.Replace("href=" + replace, "href=" + to); - builder.Replace("href="" + replace, "href="" + to); - builder.Replace("src=\"" + replace, "src=\"" + to); - builder.Replace("src='" + replace, "src='" + to); - builder.Replace("src=" + replace, "src=" + to); - builder.Replace("src="" + replace, "src="" + to); - } - - public static string ReplaceFirst(string replace, string input, string to) - { - var pos = input.IndexOf(replace, StringComparison.Ordinal); - if (pos > 0) - { - //取位置前部分+替换字符串+位置(加上查找字符长度)后部分 - return input.Substring(0, pos) + to + input.Substring(pos + replace.Length); - } - if (pos == 0) - { - return to + input.Substring(replace.Length); - } - return input; - } - - public static string ReplaceSpecified(string replace, string input, string to, int specified) - { - if (specified <= 1) - { - return ReplaceFirst(replace, input, to); - } - var pos = 0; - for (var i = 1; i <= specified; i++) - { - pos = input.IndexOf(replace, pos + 1, StringComparison.Ordinal); - } - - if (pos > 0) - { - //取位置前部分+替换字符串+位置(加上查找字符长度)后部分 - return input.Substring(0, pos) + to + input.Substring(pos + replace.Length); - } - if (pos == 0) - { - return to + input.Substring(replace.Length); - } - return input; - } - - public static string ReplaceAfterIndex(string replace, string input, string to, int index) - { - index = input.IndexOf(replace, index + 1, StringComparison.Ordinal); - if (index > 0) - { - //取位置前部分+替换字符串+位置(加上查找字符长度)后部分 - return input.Substring(0, index) + to + input.Substring(index + replace.Length); - } - if (index == 0) - { - return to + input.Substring(replace.Length); - } - return input; - } - - public static string ReplaceStartsWith(string input, string replace, string to) - { - var retval = input; - if (!string.IsNullOrEmpty(input) && !string.IsNullOrEmpty(replace) && input.StartsWith(replace)) - { - retval = to + input.Substring(replace.Length); - } - return retval; - } - - public static string ReplaceStartsWithIgnoreCase(string input, string replace, string to) - { - var retval = input; - if (!string.IsNullOrEmpty(input) && !string.IsNullOrEmpty(replace) && input.ToLower().StartsWith(replace.ToLower())) - { - retval = to + input.Substring(replace.Length); - } - return retval; - } - - public static string ReplaceEndsWith(string input, string replace, string to) - { - var retval = input; - if (!string.IsNullOrEmpty(input) && !string.IsNullOrEmpty(replace) && input.EndsWith(replace)) - { - retval = input.Substring(0, input.LastIndexOf(replace, StringComparison.Ordinal)) + to; - } - return retval; - } - - public static string ReplaceNewlineToBr(string inputString) - { - if (string.IsNullOrEmpty(inputString)) return string.Empty; - var retVal = new StringBuilder(); - inputString = inputString.Trim(); - foreach (var t in inputString) - { - switch (t) - { - case '\n': - retVal.Append("
    "); - break; - case '\r': - break; - default: - retVal.Append(t); - break; - } - } - return retVal.ToString(); - } - - public static string ReplaceBrToNewline(string inputString) - { - return RegexUtils.Replace("]*>", inputString, "\n"); - } - - /// - /// 将回车换行符替换为Tab符 - /// - /// - /// - public static string ReplaceNewlineToTab(string inputString) - { - if (string.IsNullOrEmpty(inputString)) return string.Empty; - var retVal = new StringBuilder(); - inputString = inputString.Trim(); - foreach (var t in inputString) - { - switch (t) - { - case '\r': - retVal.Append("\t"); - break; - case '\n': - break; - default: - retVal.Append(t); - break; - } - } - return retVal.ToString(); - } - - public static string ReplaceNewline(string inputString, string replacement) - { - if (string.IsNullOrEmpty(inputString)) return string.Empty; - var retVal = new StringBuilder(); - inputString = inputString.Trim(); - foreach (var t in inputString) - { - switch (t) - { - case '\n': - retVal.Append(replacement); - break; - case '\r': - break; - default: - retVal.Append(t); - break; - } - } - return retVal.ToString(); - } - - public static string CutLengthText(string inputString, int length) - { - var retval = inputString; - if (string.IsNullOrEmpty(retval)) return retval; - retval = retval.Substring(0, length); - if (retval.Length != inputString.Length) - { - retval += Constants.Ellipsis; - } - return retval; - } - - public static string CutString(string str, int startIndex) - { - return CutString(str, startIndex, str.Length); - } - - public static string CutString(string str, int startIndex, int length) - { - if (startIndex >= 0) - { - if (length < 0) - { - length = length * -1; - if (startIndex - length < 0) - { - length = startIndex; - startIndex = 0; - } - else - { - startIndex = startIndex - length; - } - } - - if (startIndex > str.Length) - { - return string.Empty; - } - } - else - { - if (length < 0) - { - return string.Empty; - } - if (length + startIndex > 0) - { - length = length + startIndex; - startIndex = 0; - } - else - { - return string.Empty; - } - } - - if (str.Length - startIndex < length) - { - length = str.Length - startIndex; - } - - return str.Substring(startIndex, length); - } - - public static string MaxLengthText(string inputString, int maxLength) - { - return MaxLengthText(inputString, maxLength, Constants.Ellipsis); - } - - public static string MaxLengthText(string inputString, int maxLength, string endString) - { - var retval = inputString; - try - { - if (maxLength > 0) - { - var decodedInputString = HttpUtility.HtmlDecode(retval); - retval = decodedInputString; - - var totalLength = maxLength * 2; - var length = 0; - var builder = new StringBuilder(); - - var isOneBytesChar = false; - var lastChar = ' '; - - if (!string.IsNullOrEmpty(retval)) - { - foreach (var singleChar in retval.ToCharArray()) - { - builder.Append(singleChar); - - if (IsTwoBytesChar(singleChar)) - { - length += 2; - if (length >= totalLength) - { - lastChar = singleChar; - break; - } - } - else - { - length += 1; - if (length == totalLength) - { - isOneBytesChar = true;//已经截取到需要的字数,再多截取一位 - } - else if (length > totalLength) - { - lastChar = singleChar; - break; - } - else - { - isOneBytesChar = !isOneBytesChar; - } - } - } - } - if (isOneBytesChar && length > totalLength) - { - builder.Length--; - var theStr = builder.ToString(); - retval = builder.ToString(); - if (char.IsLetter(lastChar)) - { - for (var i = theStr.Length - 1; i > 0; i--) - { - var theChar = theStr[i]; - if (!IsTwoBytesChar(theChar) && char.IsLetter(theChar)) - { - retval = retval.Substring(0, i - 1); - } - else - { - break; - } - } - //int index = retval.LastIndexOfAny(new char[] { ' ', '\t', '\n', '\v', '\f', '\r', '\x0085' }); - //if (index != -1) - //{ - // retval = retval.Substring(0, index); - //} - } - } - else - { - retval = builder.ToString(); - } - - var isCut = decodedInputString != retval; - retval = HttpUtility.HtmlEncode(retval); - - if (isCut && endString != null) - { - retval += endString; - } - } - } - catch - { - // ignored - } - - return retval; - } - - /// - /// 分割字符串 - /// - public static string[] SplitStringIgnoreCase(string strContent, string strSplit) - { - if (!string.IsNullOrEmpty(strContent)) - { - if (strContent.ToLower().IndexOf(strSplit.ToLower(), StringComparison.Ordinal) < 0) - { - return new[] { strContent }; - } - - return Regex.Split(strContent, Regex.Escape(strSplit), RegexOptions.IgnoreCase); - } - return new string[] { }; - } - - /// - /// 分割字符串 - /// - /// - public static string[] SplitStringIgnoreCase(string strContent, string strSplit, int count) - { - var result = new string[count]; - var splited = SplitStringIgnoreCase(strContent, strSplit); - - for (var i = 0; i < count; i++) - { - if (i < splited.Length) - result[i] = splited[i]; - else - result[i] = string.Empty; - } - - return result; - } - - public static bool IsTwoBytesChar(char chr) - { - // 使用中文支持编码 - return ECharsetUtils.GB2312.GetByteCount(new[] { chr }) == 2; - } - - public static bool IsContainTwoBytesChar(string str) - { - if (!string.IsNullOrEmpty(str)) - { - foreach (var c in str) - { - if (IsTwoBytesChar(c)) - { - return true; - } - } - } - return false; - } - - public static int GetByteCount(string content) - { - return string.IsNullOrEmpty(content) ? 0 : Encoding.GetEncoding("gb2312").GetByteCount(content); - } - - - /// - /// 得到innerText在content中的数目 - /// - /// - /// - /// - public static int GetCount(string innerText, string content) - { - if (innerText == null || content == null) - { - return 0; - } - var count = 0; - for (var index = content.IndexOf(innerText, StringComparison.Ordinal); index != -1; index = content.IndexOf(innerText, index + innerText.Length, StringComparison.Ordinal)) - { - count++; - } - return count; - } - - public static int GetStartCount(char startChar, string content) - { - if (content == null) - { - return 0; - } - var count = 0; - - foreach (var theChar in content) - { - if (theChar == startChar) - { - count++; - } - else - { - break; - } - } - return count; - } - - public static int GetStartCount(string startString, string content) - { - if (content == null) - { - return 0; - } - var count = 0; - - while (true) - { - if (content.StartsWith(startString)) - { - count++; - content = content.Remove(0, startString.Length); - } - else - { - break; - } - } - - return count; - } - - public static string GetFirstOfStringCollection(string collection) - { - return GetFirstOfStringCollection(collection, ','); - } - - public static string GetFirstOfStringCollection(string collection, char separator) - { - if (!string.IsNullOrEmpty(collection)) - { - var index = collection.IndexOf(separator); - return index == -1 ? collection : collection.Substring(0, index); - } - return string.Empty; - } - - - private static int _randomSeq; - public static int GetRandomInt(int minValue, int maxValue) - { - var ro = new Random(unchecked((int)DateTime.Now.Ticks)); - var retval = ro.Next(minValue, maxValue); - retval += _randomSeq++; - if (retval >= maxValue) - { - _randomSeq = 0; - retval = minValue; - } - return retval; - } - - public static string ValueToUrl(string value) - { - var retval = string.Empty; - if (!string.IsNullOrEmpty(value)) - { - //替换url中的换行符,update by sessionliang at 20151211 - retval = value.Replace("=", "_equals_").Replace("&", "_and_").Replace("?", "_question_").Replace("'", "_quote_").Replace("+", "_add_").Replace("\r", "").Replace("\n", ""); - } - return retval; - } - - public static string ValueToUrl(string value, bool replaceSlash) - { - - var retval = string.Empty; - if (replaceSlash) - { - if (!string.IsNullOrEmpty(value)) - { - retval = value.Replace("=", "_equals_").Replace("&", "_and_").Replace("?", "_question_").Replace("'", "_quote_").Replace("+", "_add_").Replace("/", "_slash_"); - } - } - else - { - retval = ValueToUrl(value); - } - return retval; - } - - public static string ValueFromUrl(string value) - { - var retval = string.Empty; - if (!string.IsNullOrEmpty(value)) - { - retval = value.Replace("_equals_", "=").Replace("_and_", "&").Replace("_question_", "?").Replace("_quote_", "'").Replace("_add_", "+"); - } - return retval; - } - - public static string ValueFromUrl(string value, bool replaceSlash) - { - var retval = string.Empty; - if (replaceSlash) - { - if (!string.IsNullOrEmpty(value)) - { - retval = value.Replace("_equals_", "=").Replace("_and_", "&").Replace("_question_", "?").Replace("_quote_", "'").Replace("_add_", "+").Replace("_slash_", "/"); - } - } - else - { - retval = ValueFromUrl(value); - } - return retval; - } - - public static string ToJsString(string value) - { - var retval = string.Empty; - if (!string.IsNullOrEmpty(value)) - { - retval = value.Replace("'", @"\'").Replace("\r", "\\r").Replace("\n", "\\n"); - } - return retval; - } - - public static int GetDotNetVersion() - { - return Environment.Version.Major; - } - - public static string ParseString(InputType inputType, string content, string replace, string to, int startIndex, int length, int wordNum, string ellipsis, bool isClearTags, bool isReturnToBr, bool isLower, bool isUpper, string formatString) - { - return InputTypeUtils.IsPureString(inputType) ? ParseString(content, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString) : content; - } - - public static string ParseString(string content, string replace, string to, int startIndex, int length, int wordNum, string ellipsis, bool isClearTags, bool isReturnToBr, bool isLower, bool isUpper, string formatString) - { - var parsedContent = content; - - if (!string.IsNullOrEmpty(replace)) - { - parsedContent = Replace(replace, parsedContent, to); - } - - if (isClearTags) - { - parsedContent = StripTags(parsedContent); - } - - if (!string.IsNullOrEmpty(parsedContent)) - { - if (startIndex > 0 || length > 0) - { - try - { - parsedContent = length > 0 ? parsedContent.Substring(startIndex, length) : parsedContent.Substring(startIndex); - } - catch - { - // ignored - } - } - - if (wordNum > 0) - { - parsedContent = MaxLengthText(parsedContent, wordNum, ellipsis); - } - - if (isReturnToBr) - { - parsedContent = ReplaceNewlineToBr(parsedContent); - } - - if (!string.IsNullOrEmpty(formatString)) - { - parsedContent = string.Format(formatString, parsedContent); - } - - if (isLower) - { - parsedContent = parsedContent.ToLower(); - } - if (isUpper) - { - parsedContent = parsedContent.ToUpper(); - } - } - - return parsedContent; - } - - public static string IntToSignString(int i) - { - var retval = "0"; - if (i != 0) - { - retval = i > 0 ? "+" + i : i.ToString(); - } - return retval; - } - - public static string GetPercentage(int num, int totalNum) - { - return Convert.ToDouble(num / (double)totalNum).ToString("0.00%"); - } - - /// - /// 去除HTML标记 - /// - /// 包括HTML的源码 - /// 已经去除后的文字 - public static string NoHtml(string htmlstring) - { - //删除脚本 - htmlstring = htmlstring.Replace("\r\n", ""); - htmlstring = Regex.Replace(htmlstring, @"", "", RegexOptions.IgnoreCase); - htmlstring = Regex.Replace(htmlstring, @"", "", RegexOptions.IgnoreCase); - htmlstring = Regex.Replace(htmlstring, @"<.*?>", "", RegexOptions.IgnoreCase); - //删除HTML - htmlstring = Regex.Replace(htmlstring, @"<(.[^>]*)>", "", RegexOptions.IgnoreCase); - htmlstring = Regex.Replace(htmlstring, @"([\r\n])[\s]+", "", RegexOptions.IgnoreCase); - htmlstring = Regex.Replace(htmlstring, @"-->", "", RegexOptions.IgnoreCase); - htmlstring = Regex.Replace(htmlstring, @""); - writer.WriteNewLine(true); - } - - writer.WriteStartTag(HtmlNameIndex.Style); - - - writer.WriteMarkupText(""); - writer.WriteEndTag(HtmlNameIndex.Style); - } - - if (endTagCallbackRequested) - { - callbackContext.InitializeTag(true, HtmlNameIndex.Head, dropEndTag); - - callbackContext.InitializeFragment(false); - - callback(callbackContext, writer); - - callbackContext.UninitializeFragment(); - } - else if (!dropEndTag) - { - writer.WriteEndTag(HtmlNameIndex.Head); - writer.WriteNewLine(true); - } - - writer.WriteStartTag(HtmlNameIndex.Body); - writer.WriteNewLine(true); - } - else - { - writer.WriteStartTag(HtmlNameIndex.Div); - writer.WriteAttribute(HtmlNameIndex.Class, "BodyFragment"); - writer.WriteNewLine(true); - } - - if (injection != null && injection.HaveHead) - { - InternalDebug.Assert(!injection.HeadDone); - injection.Inject(true, writer); - } - - ApplyCharFormat(); - return true; - } - - - - protected override void EndDocument() - { - RevertCharFormat(); - - if (injection != null && injection.HaveTail) - { - InternalDebug.Assert(!injection.TailDone); - injection.Inject(false, writer); - } - - if (!outputFragment) - { - writer.WriteNewLine(true); - writer.WriteEndTag(HtmlNameIndex.Body); - writer.WriteNewLine(true); - writer.WriteEndTag(HtmlNameIndex.Html); - } - else - { - writer.WriteNewLine(true); - writer.WriteEndTag(HtmlNameIndex.Div); - } - - writer.WriteNewLine(true); - } - - - - protected override void StartEndBaseFont() - { - } - - - - protected override bool StartTable() - { - var fontFaceValue = GetDistinctProperty(PropertyId.FontFace); - if (!fontFaceValue.IsNull) - { - writer.WriteStartTag(HtmlNameIndex.Font); - - writer.WriteAttributeName(HtmlNameIndex.Face); - - string name; - - StringValue sv; - MultiValue mv; - - if (fontFaceValue.IsMultiValue) - { - mv = FormatStore.GetMultiValue(fontFaceValue); - - for (var i = 0; i < mv.Length; i++) - { - sv = mv.GetStringValue(i); - name = sv.GetString(); - if (i != 0) - { - writer.WriteAttributeValue(","); - } - writer.WriteAttributeValue(name); - } - } - else - { - sv = FormatStore.GetStringValue(fontFaceValue); - name = sv.GetString(); - writer.WriteAttributeValue(name); - } - } - - writer.WriteNewLine(true); - writer.WriteStartTag(HtmlNameIndex.Table); - - OutputTableTagAttributes(); - - var styleAttributeOpen = false; - - OutputTableCssProperties(ref styleAttributeOpen); - - OutputBlockCssProperties(ref styleAttributeOpen); - - writer.WriteNewLine(true); - - return true; - } - - - - protected override void EndTable() - { - writer.WriteNewLine(true); - writer.WriteEndTag(HtmlNameIndex.Table); - writer.WriteNewLine(true); - - var fontFaceValue = GetDistinctProperty(PropertyId.FontFace); - if (!fontFaceValue.IsNull) - { - writer.WriteEndTag(HtmlNameIndex.Font); - } - } - - - - protected override bool StartTableColumnGroup() - { - writer.WriteNewLine(true); - writer.WriteStartTag(HtmlNameIndex.ColGroup); - - - var width = GetDistinctProperty(PropertyId.Width); - if (!width.IsNull && width.IsAbsRelLength) - { - writer.WriteAttribute(HtmlNameIndex.Width, width.PixelsInteger.ToString()); - } - - var span = GetDistinctProperty(PropertyId.NumColumns); - if (!span.IsNull && span.IsAbsRelLength) - { - writer.WriteAttribute(HtmlNameIndex.Span, span.Integer.ToString()); - } - - var styleAttributeOpen = false; - - OutputTableColumnCssProperties(ref styleAttributeOpen); - - return true; - } - - - - protected override void EndTableColumnGroup() - { - writer.WriteEndTag(HtmlNameIndex.ColGroup); - writer.WriteNewLine(true); - } - - - - protected override void StartEndTableColumn() - { - writer.WriteStartTag(HtmlNameIndex.Col); - - - var width = GetDistinctProperty(PropertyId.Width); - if (!width.IsNull && width.IsAbsRelLength) - { - writer.WriteAttribute(HtmlNameIndex.Width, width.PixelsInteger.ToString()); - } - - var span = GetDistinctProperty(PropertyId.NumColumns); - if (!span.IsNull && span.IsAbsRelLength) - { - writer.WriteAttribute(HtmlNameIndex.Span, span.Integer.ToString()); - } - - var styleAttributeOpen = false; - - OutputTableColumnCssProperties(ref styleAttributeOpen); - - writer.WriteNewLine(true); - } - - - - protected override bool StartTableCaption() - { - writer.WriteNewLine(true); - - if (!CurrentNode.Parent.IsNull && CurrentNode.Parent.NodeType == FormatContainerType.Table) - { - writer.WriteStartTag(HtmlNameIndex.Caption); - - var defaultStyle = FormatStore.GetStyle(HtmlConverterData.DefaultStyle.Caption); - SubtractDefaultContainerPropertiesFromDistinct(defaultStyle.FlagProperties, defaultStyle.PropertyList); - - - var pv = GetDistinctProperty(PropertyId.BlockAlignment); - if (!pv.IsNull) - { - var val = HtmlSupport.GetBlockAlignmentString(pv); - if (val != null) - { - writer.WriteAttribute(HtmlNameIndex.Align, val); - } - } - - writer.WriteNewLine(true); - } - - ApplyCharFormat(); - - return true; - } - - - - protected override void EndTableCaption() - { - RevertCharFormat(); - - if (!CurrentNode.Parent.IsNull && CurrentNode.Parent.NodeType == FormatContainerType.Table) - { - writer.WriteNewLine(true); - writer.WriteEndTag(HtmlNameIndex.Caption); - } - - writer.WriteNewLine(true); - } - - protected override bool StartTableExtraContent() - { - return StartBlockContainer(); - } - - protected override void EndTableExtraContent() - { - EndBlockContainer(); - } - - - - protected override bool StartTableRow() - { - writer.WriteNewLine(true); - writer.WriteStartTag(HtmlNameIndex.TR); - - - var height = GetDistinctProperty(PropertyId.Height); - if (!height.IsNull && height.IsAbsRelLength) - { - writer.WriteAttribute(HtmlNameIndex.Height, height.PixelsInteger.ToString()); - } - - var styleAttributeOpen = false; - - OutputBlockCssProperties(ref styleAttributeOpen); - - writer.WriteNewLine(true); - - return true; - } - - - - protected override void EndTableRow() - { - writer.WriteNewLine(true); - writer.WriteEndTag(HtmlNameIndex.TR); - writer.WriteNewLine(true); - } - - - - protected override bool StartTableCell() - { - var mergeCell = GetDistinctProperty(PropertyId.MergedCell); - - - if (mergeCell.IsNull || !mergeCell.Bool) - { - writer.WriteNewLine(true); - writer.WriteStartTag(HtmlNameIndex.TD); - - OutputTableCellTagAttributes(); - - var styleAttributeOpen = false; - - OutputBlockCssProperties(ref styleAttributeOpen); - - ApplyCharFormat(); - } - - return true; - } - - - - protected override void EndTableCell() - { - var mergeCell = GetDistinctProperty(PropertyId.MergedCell); - - if (mergeCell.IsNull || !mergeCell.Bool) - { - RevertCharFormat(); - - writer.WriteEndTag(HtmlNameIndex.TD); - writer.WriteNewLine(true); - } - } - - - - private static string[] listType = - { - null, - null, - "1", - "a", - "A", - "i", - "I", - }; - - protected override bool StartList() - { - writer.WriteNewLine(true); - - var listStyle = GetEffectiveProperty(PropertyId.ListStyle); - - var bulletedList = true; - - if (listStyle.IsNull || (ListStyle)listStyle.Enum == ListStyle.Bullet) - { - writer.WriteStartTag(HtmlNameIndex.UL); - } - else - { - writer.WriteStartTag(HtmlNameIndex.OL); - bulletedList = false; - } - - - var rtl = GetDistinctProperty(PropertyId.RightToLeft); - if (!rtl.IsNull) - { - writer.WriteAttribute(HtmlNameIndex.Dir, rtl.Bool ? "rtl" : "ltr"); - } - - - if (!bulletedList && (ListStyle)listStyle.Enum != ListStyle.Decimal) - { - writer.WriteAttribute(HtmlNameIndex.Type, listType[listStyle.Enum]); - } - - - var listStart = GetDistinctProperty(PropertyId.ListStart); - if (!bulletedList && listStart.IsInteger && listStart.Integer != 1) - { - writer.WriteAttribute(HtmlNameIndex.Start, listStart.Integer.ToString()); - } - - var styleAttributeOpen = false; - - OutputBlockCssProperties(ref styleAttributeOpen); - - writer.WriteNewLine(true); - - ApplyCharFormat(); - - return true; - } - - - - protected override void EndList() - { - RevertCharFormat(); - - var listStyle = GetEffectiveProperty(PropertyId.ListStyle); - - writer.WriteNewLine(true); - - if (listStyle.IsNull || (ListStyle)listStyle.Enum == ListStyle.Bullet) - { - writer.WriteEndTag(HtmlNameIndex.UL); - } - else - { - writer.WriteEndTag(HtmlNameIndex.OL); - } - - writer.WriteNewLine(true); - } - - - - protected override bool StartListItem() - { - writer.WriteNewLine(true); - writer.WriteStartTag(HtmlNameIndex.LI); - - var styleAttributeOpen = false; - - OutputBlockCssProperties(ref styleAttributeOpen); - - ApplyCharFormat(); - - return true; - } - - - - protected override void EndListItem() - { - RevertCharFormat(); - - writer.WriteEndTag(HtmlNameIndex.LI); - writer.WriteNewLine(true); - } - - - - private static Property[] DefaultHyperlinkProperties = new Property[] - { - new Property(PropertyId.FontColor, new PropertyValue(new RGBT(0,0,255))), - }; - - protected override bool StartHyperLink() - { - var dropEndTag = false; - var dropInnerContent = false; - var endTagCallbackRequested = false; - - var defaultFlags = new FlagProperties(); - defaultFlags.Set(PropertyId.Underline, true); - SubtractDefaultContainerPropertiesFromDistinct(defaultFlags, DefaultHyperlinkProperties); - - if (callback != null) - { - if (callbackContext == null) - { - callbackContext = new HtmlFormatOutputCallbackContext(this); - } - - - callbackContext.InitializeTag(false, HtmlNameIndex.A, false); - } - else - { - writer.WriteStartTag(HtmlNameIndex.A); - } - - var pv = GetDistinctProperty(PropertyId.HyperlinkUrl); - if (!pv.IsNull) - { - var sv = FormatStore.GetStringValue(pv); - var url = sv.GetString(); - - if (filterHtml && !HtmlToHtmlConverter.IsUrlSafe(url, callback != null)) - { - url = string.Empty; - } - - if (callback != null) - { - callbackContext.AddAttribute(HtmlNameIndex.Href, url); - } - else - { - writer.WriteAttributeName(HtmlNameIndex.Href); - writer.WriteAttributeValue(url); - } - - pv = GetDistinctProperty(PropertyId.HyperlinkTarget); - if (!pv.IsNull) - { - var target = HtmlSupport.GetTargetString(pv); - - if (callback != null) - { - callbackContext.AddAttribute(HtmlNameIndex.Target, target); - } - else - { - writer.WriteAttributeName(HtmlNameIndex.Target); - writer.WriteAttributeValue(target); - } - } - } - - - - if (callback != null) - { - callbackContext.InitializeFragment(false); - - callback(callbackContext, writer); - - callbackContext.UninitializeFragment(); - - if (callbackContext.IsInvokeCallbackForEndTag) - { - - - - endTagCallbackRequested = true; - } - - if (callbackContext.IsDeleteInnerContent) - { - dropInnerContent = true; - } - - if (callbackContext.IsDeleteEndTag) - { - dropEndTag = true; - } - - if (dropEndTag || endTagCallbackRequested) - { - if (endTagActionStack == null) - { - endTagActionStack = new EndTagActionEntry[4]; - } - else if (endTagActionStack.Length == endTagActionStackTop) - { - var newEndTagActionStack = new EndTagActionEntry[endTagActionStack.Length * 2]; - Array.Copy(endTagActionStack, 0, newEndTagActionStack, 0, endTagActionStackTop); - endTagActionStack = newEndTagActionStack; - } - - endTagActionStack[endTagActionStackTop].tagLevel = hyperlinkLevel; - endTagActionStack[endTagActionStackTop].drop = dropEndTag; - endTagActionStack[endTagActionStackTop].callback = endTagCallbackRequested; - - endTagActionStackTop++; - } - } - - hyperlinkLevel ++; - - if (!dropInnerContent) - { - ApplyCharFormat(); - } - else - { - - CloseHyperLink(); - } - - if (writer.IsTagOpen) - { - writer.WriteTagEnd(); - } - - return !dropInnerContent; - } - - - - protected override void EndHyperLink() - { - hyperlinkLevel --; - - RevertCharFormat(); - - CloseHyperLink(); - - if (writer.IsTagOpen) - { - writer.WriteTagEnd(); - } - } - - - - private void CloseHyperLink() - { - var dropTag = false; - var endTagCallbackRequested = false; - - if (endTagActionStackTop != 0) - { - InternalDebug.Assert(callback != null && callbackContext != null); - InternalDebug.Assert(endTagActionStack[endTagActionStackTop - 1].tagLevel <= hyperlinkLevel); - - - - - - if (endTagActionStack[endTagActionStackTop - 1].tagLevel == hyperlinkLevel) - { - endTagActionStackTop --; - - dropTag = endTagActionStack[endTagActionStackTop].drop; - endTagCallbackRequested = endTagActionStack[endTagActionStackTop].callback; - } - } - - if (endTagCallbackRequested) - { - InternalDebug.Assert(callback != null && callbackContext != null); - - callbackContext.InitializeTag(true, HtmlNameIndex.A, dropTag); - callbackContext.InitializeFragment(false); - - callback(callbackContext, writer); - - callbackContext.UninitializeFragment(); - } - else if (!dropTag) - { - writer.WriteEndTag(HtmlNameIndex.A); - } - } - - - - protected override bool StartBookmark() - { - var pv = GetDistinctProperty(PropertyId.BookmarkName); - if (!pv.IsNull) - { - - - writer.WriteStartTag(HtmlNameIndex.A); - - var sv = FormatStore.GetStringValue(pv); - var name = sv.GetString(); - - writer.WriteAttributeName(HtmlNameIndex.Name); - writer.WriteAttributeValue(name); - } - - ApplyCharFormat(); - - if (writer.IsTagOpen) - { - writer.WriteTagEnd(); - } - - return true; - } - - - - protected override void EndBookmark() - { - RevertCharFormat(); - - var pv = GetDistinctProperty(PropertyId.BookmarkName); - if (!pv.IsNull) - { - writer.WriteEndTag(HtmlNameIndex.A); - } - - if (writer.IsTagOpen) - { - writer.WriteTagEnd(); - } - } - - - - protected override void StartEndImage() - { - if (callback != null) - { - if (callbackContext == null) - { - callbackContext = new HtmlFormatOutputCallbackContext(this); - } - - - callbackContext.InitializeTag(false, HtmlNameIndex.Img, false); - } - else - { - writer.WriteStartTag(HtmlNameIndex.Img); - } - - var pv = GetDistinctProperty(PropertyId.Width); - if (!pv.IsNull) - { - var val = HtmlSupport.FormatPixelOrPercentageLength(ref scratchBuffer, pv); - if (val.Length != 0) - { - if (callback != null) - { - callbackContext.AddAttribute(HtmlNameIndex.Width, val.ToString()); - } - else - { - writer.WriteAttribute(HtmlNameIndex.Width, val); - } - } - } - - pv = GetDistinctProperty(PropertyId.Height); - if (!pv.IsNull) - { - var val = HtmlSupport.FormatPixelOrPercentageLength(ref scratchBuffer, pv); - if (val.Length != 0) - { - if (callback != null) - { - callbackContext.AddAttribute(HtmlNameIndex.Height, val.ToString()); - } - else - { - writer.WriteAttribute(HtmlNameIndex.Height, val); - } - } - } - - pv = GetDistinctProperty(PropertyId.BlockAlignment); - if (!pv.IsNull) - { - var val = HtmlSupport.GetBlockAlignmentString(pv); - if (val != null) - { - if (callback != null) - { - callbackContext.AddAttribute(HtmlNameIndex.Align, val); - } - else - { - writer.WriteAttribute(HtmlNameIndex.Align, val); - } - } - } - - pv = GetDistinctProperty(PropertyId.ImageBorder); - if (!pv.IsNull) - { - var val = HtmlSupport.FormatPixelOrPercentageLength(ref scratchBuffer, pv); - if (val.Length != 0) - { - if (callback != null) - { - callbackContext.AddAttribute(HtmlNameIndex.Border, val.ToString()); - } - else - { - writer.WriteAttribute(HtmlNameIndex.Border, val); - } - } - } - - pv = GetDistinctProperty(PropertyId.ImageUrl); - if (!pv.IsNull) - { - - - var sv = FormatStore.GetStringValue(pv); - var url = sv.GetString(); - - if (filterHtml && !HtmlToHtmlConverter.IsUrlSafe(url, callback != null)) - { - url = string.Empty; - } - - if (callback != null) - { - callbackContext.AddAttribute(HtmlNameIndex.Src, url); - } - else - { - writer.WriteAttributeName(HtmlNameIndex.Src); - writer.WriteAttributeValue(url); - } - } - - pv = GetDistinctProperty(PropertyId.RightToLeft); - if (pv.IsBool) - { - if (callback != null) - { - callbackContext.AddAttribute(HtmlNameIndex.Dir, pv.Bool ? "rtl" : "ltr"); - } - else - { - writer.WriteAttributeName(HtmlNameIndex.Dir); - writer.WriteAttributeValue(pv.Bool ? "rtl" : "ltr"); - } - } - - pv = GetDistinctProperty(PropertyId.Language); - if (pv.IsInteger) - { - Culture culture; - - if (Culture.TryGetCulture(pv.Integer, out culture) || String.IsNullOrEmpty(culture.Name)) - { - if (callback != null) - { - callbackContext.AddAttribute(HtmlNameIndex.Lang, culture.Name); - } - else - { - writer.WriteAttributeName(HtmlNameIndex.Lang); - writer.WriteAttributeValue(culture.Name); - } - } - } - - pv = GetDistinctProperty(PropertyId.ImageAltText); - if (!pv.IsNull) - { - - - var sv = FormatStore.GetStringValue(pv); - var altText = sv.GetString(); - - if (callback != null) - { - callbackContext.AddAttribute(HtmlNameIndex.Alt, altText); - } - else - { - writer.WriteAttributeName(HtmlNameIndex.Alt); - writer.WriteAttributeValue(altText); - } - } - - - - if (callback != null) - { - callbackContext.InitializeFragment(true); - - callback(callbackContext, writer); - - callbackContext.UninitializeFragment(); - - - } - - if (writer.IsTagOpen) - { - writer.WriteTagEnd(); - } - } - - - - protected override void StartEndHorizontalLine() - { - writer.WriteNewLine(true); - - writer.WriteStartTag(HtmlNameIndex.HR); - - - var width = GetDistinctProperty(PropertyId.Width); - if (!width.IsNull) - { - var val = HtmlSupport.FormatPixelOrPercentageLength(ref scratchBuffer, width); - if (val.Length != 0) - { - writer.WriteAttribute(HtmlNameIndex.Width, val); - } - } - - - var size = GetDistinctProperty(PropertyId.Height); - if (!size.IsNull && size.IsAbsRelLength) - { - writer.WriteAttribute(HtmlNameIndex.Size, size.PixelsInteger.ToString()); - } - - - var align = GetDistinctProperty(PropertyId.HorizontalAlignment); - if (!align.IsNull) - { - var val = HtmlSupport.GetHorizontalAlignmentString(align); - if (val != null) - { - writer.WriteAttribute(HtmlNameIndex.Align, val); - } - } - - - var color = GetDistinctProperty(PropertyId.FontColor); - if (!color.IsNull) - { - var val = HtmlSupport.FormatColor(ref scratchBuffer, color); - if (val.Length != 0) - { - writer.WriteAttribute(HtmlNameIndex.Color, val); - } - } - - - if (!width.IsNull) - { - writer.WriteAttributeName(HtmlNameIndex.Style); - - if (!width.IsNull) - { - var val = HtmlSupport.FormatLength(ref scratchBuffer, width); - if (val.Length != 0) - { - writer.WriteAttributeValue("width:"); - writer.WriteAttributeValue(val); - writer.WriteAttributeValue(";"); - } - } - } - - if (writer.LiteralWhitespaceNesting == 0) - { - writer.WriteNewLine(true); - } - } - - - - protected override bool StartInline() - { - ApplyCharFormat(); - return true; - } - - - - protected override void EndInline() - { - RevertCharFormat(); - } - - - - protected override bool StartMap() - { - return StartBlockContainer(); - } - - - - protected override void EndMap() - { - EndBlockContainer(); - } - - - - protected override void StartEndArea() - { - } - - - - protected override bool StartForm() - { - return StartInlineContainer(); - } - - - - protected override void EndForm() - { - EndInlineContainer(); - } - - - - protected override bool StartFieldSet() - { - return StartBlockContainer(); - } - - - - protected override void EndFieldSet() - { - EndBlockContainer(); - } - - - - protected override bool StartSelect() - { - return true; - } - - - - protected override void EndSelect() - { - } - - - - protected override bool StartOptionGroup() - { - return true; - } - - - - protected override void EndOptionGroup() - { - } - - - - protected override bool StartOption() - { - return true; - } - - - - protected override void EndOption() - { - } - - - - protected override bool StartText() - { - ApplyCharFormat(); - writer.StartTextChunk(); - return true; - } - - - - protected override bool ContinueText(uint beginTextPosition, uint endTextPosition) - { - InternalDebug.Assert(CurrentNode.IsText); - InternalDebug.Assert(CurrentNode.BeginTextPosition <= beginTextPosition && - beginTextPosition <= endTextPosition && - endTextPosition <= CurrentNode.EndTextPosition); - - if (beginTextPosition != endTextPosition) - { - var run = FormatStore.GetTextRun(beginTextPosition); - - do - { - var effectiveLength = run.EffectiveLength; - InternalDebug.Assert(effectiveLength > 0 || run.Type == TextRunType.Invalid); - - switch (run.Type) - { - case TextRunType.NewLine: - - while (0 != effectiveLength--) - { - if (writer.LiteralWhitespaceNesting == 0) - { - writer.WriteStartTag(HtmlNameIndex.BR); - } - writer.WriteNewLine(false); - } - break; - - case TextRunType.Tabulation: - - writer.WriteTabulation(effectiveLength); - break; - - case TextRunType.Space: - - writer.WriteSpace(effectiveLength); - break; - - case TextRunType.NbSp: - - writer.WriteNbsp(effectiveLength); - break; - - case TextRunType.NonSpace: - - var start = 0; - - if (recognizeHyperlinks && hyperlinkLevel == 0 && effectiveLength > 10 && effectiveLength < MaxRecognizedHyperlinkLength) - { - - - bool addHttpPrefix; - bool addFilePrefix; - int offset; - int length; - - var link = RecognizeHyperLink(run, out offset, out length, out addFilePrefix, out addHttpPrefix); - - if (link) - { - if (offset != 0) - { - - writer.WriteTextInternal(scratchBuffer.Buffer, 0, offset); - } - - if (callback != null) - { - if (callbackContext == null) - { - callbackContext = new HtmlFormatOutputCallbackContext(this); - } - - - callbackContext.InitializeTag(false, HtmlNameIndex.A, false); - - - var href = new string(scratchBuffer.Buffer, offset, length); - if (addHttpPrefix) - { - href = "http://" + href; - } - else if (addFilePrefix) - { - href = "file://" + href; - } - - callbackContext.AddAttribute(HtmlNameIndex.Href, href); - - callbackContext.InitializeFragment(false); - - callback(callbackContext, writer); - - callbackContext.UninitializeFragment(); - - if (writer.IsTagOpen) - { - writer.WriteTagEnd(); - } - - if (!callbackContext.IsDeleteInnerContent) - { - writer.WriteTextInternal(scratchBuffer.Buffer, offset, length); - } - - if (callbackContext.IsInvokeCallbackForEndTag) - { - - - - - callbackContext.InitializeTag(true, HtmlNameIndex.A, callbackContext.IsDeleteEndTag); - - callbackContext.InitializeFragment(false); - - callback(callbackContext, writer); - - callbackContext.UninitializeFragment(); - } - else if (!callbackContext.IsDeleteEndTag) - { - writer.WriteEndTag(HtmlNameIndex.A); - } - - if (writer.IsTagOpen) - { - writer.WriteTagEnd(); - } - } - else - { - writer.WriteStartTag(HtmlNameIndex.A); - - - writer.WriteAttributeName(HtmlNameIndex.Href); - if (addHttpPrefix) - { - writer.WriteAttributeValue("http://"); - } - else if (addFilePrefix) - { - writer.WriteAttributeValue("file://"); - } - - writer.WriteAttributeValue(scratchBuffer.Buffer, offset, length); - writer.WriteTagEnd(); - - writer.WriteTextInternal(scratchBuffer.Buffer, offset, length); - - writer.WriteEndTag(HtmlNameIndex.A); - } - - start += offset + length; - - if (start == effectiveLength) - { - - run.MoveNext(); - continue; - } - - - } - - - } - - - - do - { - char[] buffer; - int offset; - int count; - - run.GetChunk(start, out buffer, out offset, out count); - writer.WriteTextInternal(buffer, offset, count); - start += count; - } - while (start != effectiveLength); - - break; - } - - run.MoveNext(); - } - while (run.Position < endTextPosition); - } - - return true; - } - - - - protected override void EndText() - { - writer.EndTextChunk(); - - RevertCharFormat(); - } - - - - protected override bool StartBlockContainer() - { - writer.WriteNewLine(true); - - var preformatted = GetDistinctProperty(PropertyId.Preformatted); - var quotingLevel = GetDistinctProperty(PropertyId.QuotingLevelDelta); - - if (!preformatted.IsNull && preformatted.Bool) - { - var defaultStyle = FormatStore.GetStyle(HtmlConverterData.DefaultStyle.Pre); - - SubtractDefaultContainerPropertiesFromDistinct(FlagProperties.AllOff, defaultStyle.PropertyList); - - writer.WriteStartTag(HtmlNameIndex.Pre); - } - else if (!quotingLevel.IsNull && quotingLevel.Integer != 0) - { - for (var i = 0; i < quotingLevel.Integer; i++) - { - writer.WriteStartTag(HtmlNameIndex.Div); - - - writer.WriteAttribute(HtmlNameIndex.Class, "EmailQuote"); - } - } - else - { - - - if (SourceFormat == SourceFormat.Text) - { - ApplyCharFormat(); - } - - writer.WriteStartTag(HtmlNameIndex.Div); - - if (SourceFormat == SourceFormat.Text) - { - - writer.WriteAttribute(HtmlNameIndex.Class, "PlainText"); - } - } - - OutputBlockTagAttributes(); - - var styleAttributeOpen = false; - - OutputBlockCssProperties(ref styleAttributeOpen); - - if (SourceFormat != SourceFormat.Text) - { - ApplyCharFormat(); - } - - if (CurrentNode.FirstChild.IsNull) - { - - writer.WriteText('\xA0'); - } - else if (CurrentNode.FirstChild == CurrentNode.LastChild && CurrentNode.FirstChild.NodeType == FormatContainerType.Text) - { - var child = CurrentNode.FirstChild; - if (child.BeginTextPosition + 1 == child.EndTextPosition) - { - var run = FormatStore.GetTextRun(child.BeginTextPosition); - - InternalDebug.Assert(run.Length == 1); - - if (run.Type == TextRunType.Space) - { - - writer.WriteText('\xA0'); - EndBlockContainer(); - return false; - } - } - } - - return true; - } - - - - protected override void EndBlockContainer() - { - var preformatted = GetDistinctProperty(PropertyId.Preformatted); - var quotingLevel = GetDistinctProperty(PropertyId.QuotingLevelDelta); - - if (SourceFormat != SourceFormat.Text) - { - RevertCharFormat(); - } - - if (!preformatted.IsNull && preformatted.Bool) - { - writer.WriteEndTag(HtmlNameIndex.Pre); - } - else if (!quotingLevel.IsNull && quotingLevel.Integer != 0) - { - for (var i = 0; i < quotingLevel.Integer; i++) - { - writer.WriteEndTag(HtmlNameIndex.Div); - } - } - else - { - writer.WriteEndTag(HtmlNameIndex.Div); - - if (SourceFormat == SourceFormat.Text) - { - RevertCharFormat(); - } - } - - writer.WriteNewLine(true); - } - - - - protected override bool StartInlineContainer() - { - return true; - } - - - - protected override void EndInlineContainer() - { - } - - - - private void ApplyCharFormat() - { - BufferString val; - - scratchBuffer.Reset(); - - var flags = GetDistinctFlags(); - - var fontSizeValue = GetDistinctProperty(PropertyId.FontSize); - if (!fontSizeValue.IsNull && !fontSizeValue.IsHtmlFontUnits && !fontSizeValue.IsRelativeHtmlFontUnits) - { - scratchBuffer.Append("font-size:"); - HtmlSupport.AppendCssFontSize(ref scratchBuffer, fontSizeValue); - scratchBuffer.Append(';'); - } - - var backColorValue = GetDistinctProperty(PropertyId.BackColor); - if (backColorValue.IsColor) - { - scratchBuffer.Append("background-color:"); - HtmlSupport.AppendColor(ref scratchBuffer, backColorValue); - scratchBuffer.Append(';'); - } - - Culture culture = null; - - var languageValue = GetDistinctProperty(PropertyId.Language); - if (languageValue.IsInteger) - { - if (!Culture.TryGetCulture(languageValue.Integer, out culture) || String.IsNullOrEmpty(culture.Name)) - { - culture = null; - } - } - - if (0 == (CurrentNode.NodeType & FormatContainerType.BlockFlag)) - { - var displayValue = GetDistinctProperty(PropertyId.Display); - var unicodeBiDiValue = GetDistinctProperty(PropertyId.UnicodeBiDi); - - if (!displayValue.IsNull) - { - var str = HtmlSupport.GetDisplayString(displayValue); - if (str != null) - { - scratchBuffer.Append("display:"); - scratchBuffer.Append(str); - scratchBuffer.Append(";"); - } - } - - if (flags.IsDefined(PropertyId.Visible)) - { - scratchBuffer.Append(flags.IsOn(PropertyId.Visible) ? "visibility:visible;" : "visibility:hidden;"); - } - - if (!unicodeBiDiValue.IsNull) - { - var str = HtmlSupport.GetUnicodeBiDiString(unicodeBiDiValue); - if (str != null) - { - scratchBuffer.Append("unicode-bidi:"); - scratchBuffer.Append(str); - scratchBuffer.Append(";"); - } - } - } - - if (flags.IsDefinedAndOff(PropertyId.Bold)) - { - - scratchBuffer.Append("font-weight:normal;"); - } - - if (flags.IsDefined(PropertyId.SmallCaps)) - { - scratchBuffer.Append(flags.IsOn(PropertyId.SmallCaps) ? "font-variant:small-caps;" : "font-variant:normal;"); - } - - if (flags.IsDefined(PropertyId.Capitalize)) - { - scratchBuffer.Append(flags.IsOn(PropertyId.Capitalize) ? "text-transform:uppercase;" : "text-transform:none;"); - } - - - - - var fontFaceValue = GetDistinctProperty(PropertyId.FontFace); - var fontColorValue = GetDistinctProperty(PropertyId.FontColor); - - if (!fontFaceValue.IsNull || !fontSizeValue.IsNull || !fontColorValue.IsNull) - { - writer.WriteStartTag(HtmlNameIndex.Font); - - if (!fontFaceValue.IsNull) - { - writer.WriteAttributeName(HtmlNameIndex.Face); - - string name; - - StringValue sv; - MultiValue mv; - - if (fontFaceValue.IsMultiValue) - { - mv = FormatStore.GetMultiValue(fontFaceValue); - - for (var i = 0; i < mv.Length; i++) - { - sv = mv.GetStringValue(i); - name = sv.GetString(); - if (i != 0) - { - writer.WriteAttributeValue(","); - } - writer.WriteAttributeValue(name); - } - } - else - { - sv = FormatStore.GetStringValue(fontFaceValue); - name = sv.GetString(); - writer.WriteAttributeValue(name); - } - } - - if (!fontSizeValue.IsNull) - { - val = HtmlSupport.FormatFontSize(ref scratchValueBuffer, fontSizeValue); - if (val.Length != 0) - { - writer.WriteAttribute(HtmlNameIndex.Size, val); - } - } - - if (!fontColorValue.IsNull) - { - val = HtmlSupport.FormatColor(ref scratchValueBuffer, fontColorValue); - if (val.Length != 0) - { - writer.WriteAttribute(HtmlNameIndex.Color, val); - } - } - } - - if (scratchBuffer.Length != 0 || flags.IsDefined(PropertyId.RightToLeft) || culture != null) - { - writer.WriteStartTag(HtmlNameIndex.Span); - - if (scratchBuffer.Length != 0) - { - writer.WriteAttributeName(HtmlNameIndex.Style); - writer.WriteAttributeValue(scratchBuffer.BufferString); - } - - if (flags.IsDefined(PropertyId.RightToLeft)) - { - writer.WriteAttributeName(HtmlNameIndex.Dir); - writer.WriteAttributeValue(flags.IsOn(PropertyId.RightToLeft) ? "rtl" : "ltr"); - } - - if (culture != null) - { - writer.WriteAttributeName(HtmlNameIndex.Lang); - writer.WriteAttributeValue(culture.Name); - } - } - - if (flags.IsDefinedAndOn(PropertyId.Bold)) - { - writer.WriteStartTag(HtmlNameIndex.B); - } - - if (flags.IsDefinedAndOn(PropertyId.Italic)) - { - writer.WriteStartTag(HtmlNameIndex.I); - } - - if (flags.IsDefinedAndOn(PropertyId.Underline)) - { - writer.WriteStartTag(HtmlNameIndex.U); - } - - if (flags.IsDefinedAndOn(PropertyId.Subscript)) - { - writer.WriteStartTag(HtmlNameIndex.Sub); - } - - if (flags.IsDefinedAndOn(PropertyId.Superscript)) - { - writer.WriteStartTag(HtmlNameIndex.Sup); - } - - if (flags.IsDefinedAndOn(PropertyId.Strikethrough)) - { - writer.WriteStartTag(HtmlNameIndex.Strike); - } - } - - - - private void RevertCharFormat() - { - var flags = GetDistinctFlags(); - - var closeFontTag = false; - var closeSpanTag = false; - - var fontSizeValue = GetDistinctProperty(PropertyId.FontSize); - if (!fontSizeValue.IsNull && !fontSizeValue.IsHtmlFontUnits && !fontSizeValue.IsRelativeHtmlFontUnits) - { - closeSpanTag = true; - } - - var backColorValue = GetDistinctProperty(PropertyId.BackColor); - if (backColorValue.IsColor) - { - closeSpanTag = true; - } - - Culture culture = null; - - var languageValue = GetDistinctProperty(PropertyId.Language); - if (languageValue.IsInteger) - { - if (Culture.TryGetCulture(languageValue.Integer, out culture) && !String.IsNullOrEmpty(culture.Name)) - { - closeSpanTag = true; - } - } - - if (0 == (CurrentNode.NodeType & FormatContainerType.BlockFlag)) - { - var displayValue = GetDistinctProperty(PropertyId.Display); - var unicodeBiDiValue = GetDistinctProperty(PropertyId.UnicodeBiDi); - - if (!displayValue.IsNull) - { - var str = HtmlSupport.GetDisplayString(displayValue); - if (str != null) - { - closeSpanTag = true; - } - } - - if (flags.IsDefined(PropertyId.Visible)) - { - closeSpanTag = true; - } - - if (!unicodeBiDiValue.IsNull) - { - var str = HtmlSupport.GetUnicodeBiDiString(unicodeBiDiValue); - if (str != null) - { - closeSpanTag = true; - } - } - } - - if (flags.IsDefinedAndOff(PropertyId.Bold)) - { - - closeSpanTag = true; - } - - if (flags.IsDefined(PropertyId.SmallCaps)) - { - closeSpanTag = true; - } - - if (flags.IsDefined(PropertyId.Capitalize)) - { - closeSpanTag = true; - } - - if (flags.IsDefined(PropertyId.RightToLeft)) - { - closeSpanTag = true; - } - - var fontFaceValue = GetDistinctProperty(PropertyId.FontFace); - var fontColorValue = GetDistinctProperty(PropertyId.FontColor); - - if (!fontFaceValue.IsNull || !fontSizeValue.IsNull || !fontColorValue.IsNull) - { - closeFontTag = true; - } - - - - - if (flags.IsDefinedAndOn(PropertyId.Strikethrough)) - { - writer.WriteEndTag(HtmlNameIndex.Strike); - } - - if (flags.IsDefinedAndOn(PropertyId.Superscript)) - { - writer.WriteEndTag(HtmlNameIndex.Sup); - } - - if (flags.IsDefinedAndOn(PropertyId.Subscript)) - { - writer.WriteEndTag(HtmlNameIndex.Sub); - } - - if (flags.IsDefinedAndOn(PropertyId.Underline)) - { - writer.WriteEndTag(HtmlNameIndex.U); - } - - if (flags.IsDefinedAndOn(PropertyId.Italic)) - { - writer.WriteEndTag(HtmlNameIndex.I); - } - - if (flags.IsDefinedAndOn(PropertyId.Bold)) - { - writer.WriteEndTag(HtmlNameIndex.B); - } - - if (closeSpanTag) - { - writer.WriteEndTag(HtmlNameIndex.Span); - } - - if (closeFontTag) - { - writer.WriteEndTag(HtmlNameIndex.Font); - } - } - - - - private void OutputBlockCssProperties(ref bool styleAttributeOpen) - { - var display = GetDistinctProperty(PropertyId.Display); - var visible = GetDistinctProperty(PropertyId.Visible); - - var height = GetDistinctProperty(PropertyId.Height); - var width = GetDistinctProperty(PropertyId.Width); - - var unicodeBiDiValue = GetDistinctProperty(PropertyId.UnicodeBiDi); - - var firstLineIndent = GetDistinctProperty(PropertyId.FirstLineIndent); - var textAlignment = GetDistinctProperty(PropertyId.TextAlignment); - var backColor = GetDistinctProperty(PropertyId.BackColor); - - var topMargin = GetDistinctProperty(PropertyId.TopMargin); - var rightMargin = GetDistinctProperty(PropertyId.RightMargin); - var bottomMargin = GetDistinctProperty(PropertyId.BottomMargin); - var leftMargin = GetDistinctProperty(PropertyId.LeftMargin); - var topPadding = GetDistinctProperty(PropertyId.TopPadding); - var rightPadding = GetDistinctProperty(PropertyId.RightPadding); - var bottomPadding = GetDistinctProperty(PropertyId.BottomPadding); - var leftPadding = GetDistinctProperty(PropertyId.LeftPadding); - - var topBorderWidth = GetDistinctProperty(PropertyId.TopBorderWidth); - var rightBorderWidth = GetDistinctProperty(PropertyId.RightBorderWidth); - var bottomBorderWidth = GetDistinctProperty(PropertyId.BottomBorderWidth); - var leftBorderWidth = GetDistinctProperty(PropertyId.LeftBorderWidth); - var topBorderStyle = GetDistinctProperty(PropertyId.TopBorderStyle); - var rightBorderStyle = GetDistinctProperty(PropertyId.RightBorderStyle); - var bottomBorderStyle = GetDistinctProperty(PropertyId.BottomBorderStyle); - var leftBorderStyle = GetDistinctProperty(PropertyId.LeftBorderStyle); - var topBorderColor = GetDistinctProperty(PropertyId.TopBorderColor); - var rightBorderColor = GetDistinctProperty(PropertyId.RightBorderColor); - var bottomBorderColor = GetDistinctProperty(PropertyId.BottomBorderColor); - var leftBorderColor = GetDistinctProperty(PropertyId.LeftBorderColor); - - if (!visible.IsNull || - !display.IsNull || - !unicodeBiDiValue.IsNull || - !width.IsNull || - !height.IsNull) - { - if (!styleAttributeOpen) - { - writer.WriteAttributeName(HtmlNameIndex.Style); - styleAttributeOpen = true; - } - - if (!display.IsNull) - { - var val = HtmlSupport.GetDisplayString(display); - if (val != null) - { - scratchBuffer.Append("display:"); - scratchBuffer.Append(val); - scratchBuffer.Append(";"); - } - } - - if (!visible.IsNull) - { - scratchBuffer.Append(visible.Bool ? "visibility:visible;" : "visibility:hidden;"); - } - - if (!width.IsNull) - { - var val = HtmlSupport.FormatLength(ref scratchBuffer, width); - if (val.Length != 0) - { - writer.WriteAttributeValue("width:"); - writer.WriteAttributeValue(val); - writer.WriteAttributeValue(";"); - } - } - - if (!height.IsNull) - { - var val = HtmlSupport.FormatLength(ref scratchBuffer, height); - if (val.Length != 0) - { - writer.WriteAttributeValue("height:"); - writer.WriteAttributeValue(val); - writer.WriteAttributeValue(";"); - } - } - - if (!unicodeBiDiValue.IsNull) - { - var str = HtmlSupport.GetUnicodeBiDiString(unicodeBiDiValue); - if (str != null) - { - writer.WriteAttributeValue("unicode-bidi:"); - writer.WriteAttributeValue(str); - writer.WriteAttributeValue(";"); - } - } - } - - if (!firstLineIndent.IsNull || - !textAlignment.IsNull || - !backColor.IsNull) - { - if (!styleAttributeOpen) - { - writer.WriteAttributeName(HtmlNameIndex.Style); - styleAttributeOpen = true; - } - - if (!firstLineIndent.IsNull) - { - var val = HtmlSupport.FormatLength(ref scratchBuffer, firstLineIndent); - if (val.Length != 0) - { - writer.WriteAttributeValue("text-indent:"); - writer.WriteAttributeValue(val); - writer.WriteAttributeValue(";"); - } - } - - if (!textAlignment.IsNull) - { - if (textAlignment.IsEnum && textAlignment.Enum < HtmlSupport.TextAlignmentEnumeration.Length) - { - writer.WriteAttributeValue("text-align:"); - writer.WriteAttributeValue(HtmlSupport.TextAlignmentEnumeration[textAlignment.Enum].name); - writer.WriteAttributeValue(";"); - } - } - - if (!backColor.IsNull) - { - var val = HtmlSupport.FormatColor(ref scratchBuffer, backColor); - if (val.Length != 0) - { - writer.WriteAttributeValue("background-color:"); - writer.WriteAttributeValue(val); - writer.WriteAttributeValue(";"); - } - } - } - - if (!topMargin.IsNull || - !rightMargin.IsNull || - !bottomMargin.IsNull || - !leftMargin.IsNull) - { - if (!styleAttributeOpen) - { - writer.WriteAttributeName(HtmlNameIndex.Style); - styleAttributeOpen = true; - } - - OutputMarginAndPaddingProperties( - "margin", - topMargin, rightMargin, bottomMargin, leftMargin); - } - - if (!topPadding.IsNull || - !rightPadding.IsNull || - !bottomPadding.IsNull || - !leftPadding.IsNull) - { - if (!styleAttributeOpen) - { - writer.WriteAttributeName(HtmlNameIndex.Style); - styleAttributeOpen = true; - } - - OutputMarginAndPaddingProperties( - "padding", - topPadding, rightPadding, bottomPadding, leftPadding); - } - - if (!topBorderWidth.IsNull || - !rightBorderWidth.IsNull || - !bottomBorderWidth.IsNull || - !leftBorderWidth.IsNull || - !topBorderStyle.IsNull || - !rightBorderStyle.IsNull || - !bottomBorderStyle.IsNull || - !leftBorderStyle.IsNull || - !topBorderColor.IsNull || - !rightBorderColor.IsNull || - !bottomBorderColor.IsNull || - !leftBorderColor.IsNull) - { - if (!styleAttributeOpen) - { - writer.WriteAttributeName(HtmlNameIndex.Style); - styleAttributeOpen = true; - } - - OutputBorderProperties( - topBorderWidth, rightBorderWidth, bottomBorderWidth, leftBorderWidth, - topBorderStyle, rightBorderStyle, bottomBorderStyle, leftBorderStyle, - topBorderColor, rightBorderColor, bottomBorderColor, leftBorderColor); - } - } - - - - private void OutputMarginAndPaddingProperties( - string name, - PropertyValue topValue, PropertyValue rightValue, PropertyValue bottomValue, PropertyValue leftValue) - { - var numSidesDefined = 0; - - if (!topValue.IsNull) - { - numSidesDefined ++; - } - - if (!rightValue.IsNull) - { - numSidesDefined ++; - } - - if (!bottomValue.IsNull) - { - numSidesDefined ++; - } - - if (!leftValue.IsNull) - { - numSidesDefined ++; - } - - if (numSidesDefined == 4) - { - - writer.WriteAttributeValue(name); - writer.WriteAttributeValue(":"); - - if (topValue == rightValue && topValue == bottomValue && topValue == leftValue) - { - - OutputLengthPropertyValue(topValue); - } - else - { - if (topValue == bottomValue && rightValue == leftValue) - { - - OutputCompositeLengthPropertyValue(topValue, rightValue); - } - else - { - - OutputCompositeLengthPropertyValue(topValue, rightValue, bottomValue, leftValue); - } - } - - writer.WriteAttributeValue(";"); - } - else - { - - - if (!topValue.IsNull) - { - - writer.WriteAttributeValue(name); - writer.WriteAttributeValue("-top:"); - OutputLengthPropertyValue(topValue); - writer.WriteAttributeValue(";"); - } - - if (!rightValue.IsNull) - { - - writer.WriteAttributeValue(name); - writer.WriteAttributeValue("-right:"); - OutputLengthPropertyValue(rightValue); - writer.WriteAttributeValue(";"); - } - - if (!bottomValue.IsNull) - { - - writer.WriteAttributeValue(name); - writer.WriteAttributeValue("-bottom:"); - OutputLengthPropertyValue(bottomValue); - writer.WriteAttributeValue(";"); - } - - if (!leftValue.IsNull) - { - - writer.WriteAttributeValue(name); - writer.WriteAttributeValue("-left:"); - OutputLengthPropertyValue(leftValue); - writer.WriteAttributeValue(";"); - } - } - } - - - - private void OutputBorderProperties( - PropertyValue topBorderWidth, PropertyValue rightBorderWidth, PropertyValue bottomBorderWidth, PropertyValue leftBorderWidth, - PropertyValue topBorderStyle, PropertyValue rightBorderStyle, PropertyValue bottomBorderStyle, PropertyValue leftBorderStyle, - PropertyValue topBorderColor, PropertyValue rightBorderColor, PropertyValue bottomBorderColor, PropertyValue leftBorderColor) - { - var numSidesDefinedWidth = 0; - var numSidesDefinedStyle = 0; - var numSidesDefinedColor = 0; - - var numPropsDefinedTop = 0; - var numPropsDefinedRight = 0; - var numPropsDefinedBottom = 0; - var numPropsDefinedLeft = 0; - - if (!topBorderWidth.IsNull) - { - numSidesDefinedWidth ++; - numPropsDefinedTop ++; - } - - if (!rightBorderWidth.IsNull) - { - numSidesDefinedWidth ++; - numPropsDefinedRight ++; - } - - if (!bottomBorderWidth.IsNull) - { - numSidesDefinedWidth ++; - numPropsDefinedBottom ++; - } - - if (!leftBorderWidth.IsNull) - { - numSidesDefinedWidth ++; - numPropsDefinedLeft ++; - } - - if (!topBorderStyle.IsNull) - { - numSidesDefinedStyle ++; - numPropsDefinedTop ++; - } - - if (!rightBorderStyle.IsNull) - { - numSidesDefinedStyle ++; - numPropsDefinedRight ++; - } - - if (!bottomBorderStyle.IsNull) - { - numSidesDefinedStyle ++; - numPropsDefinedBottom ++; - } - - if (!leftBorderStyle.IsNull) - { - numSidesDefinedStyle ++; - numPropsDefinedLeft ++; - } - - if (!topBorderColor.IsNull) - { - numSidesDefinedColor ++; - numPropsDefinedTop ++; - } - - if (!rightBorderColor.IsNull) - { - numSidesDefinedColor ++; - numPropsDefinedRight ++; - } - - if (!bottomBorderColor.IsNull) - { - numSidesDefinedColor ++; - numPropsDefinedBottom ++; - } - - if (!leftBorderColor.IsNull) - { - numSidesDefinedColor ++; - numPropsDefinedLeft ++; - } - - var allSidesEqualWidth = false; - var hvSidesEqualWidth = false; - var allSidesEqualStyle = false; - var hvSidesEqualStyle = false; - var allSidesEqualColor = false; - var hvSidesEqualColor = false; - - if (numSidesDefinedWidth == 4) - { - if (topBorderWidth == bottomBorderWidth && rightBorderWidth == leftBorderWidth) - { - hvSidesEqualWidth = true; - allSidesEqualWidth = (topBorderWidth == rightBorderWidth); - } - } - - if (numSidesDefinedStyle == 4) - { - if (topBorderStyle == bottomBorderStyle && rightBorderStyle == leftBorderStyle) - { - hvSidesEqualStyle = true; - allSidesEqualStyle = (topBorderStyle == rightBorderStyle); - } - } - - if (numSidesDefinedColor == 4) - { - if (topBorderColor == bottomBorderColor && rightBorderColor == leftBorderColor) - { - hvSidesEqualColor = true; - allSidesEqualColor = (topBorderColor == rightBorderColor); - } - } - - if (numSidesDefinedWidth == 4 && numSidesDefinedStyle == 4 && numSidesDefinedColor == 4) - { - - if (allSidesEqualWidth && allSidesEqualStyle && allSidesEqualColor) - { - - - writer.WriteAttributeValue("border:"); - OutputCompositeBorderSidePropertyValue(topBorderWidth, topBorderStyle, topBorderColor); - writer.WriteAttributeValue(";"); - } - else - { - - - - writer.WriteAttributeValue("border-width:"); - if (allSidesEqualWidth) - { - OutputBorderWidthPropertyValue(topBorderWidth); - } - else if (hvSidesEqualWidth) - { - OutputCompositeBorderWidthPropertyValue(topBorderWidth, rightBorderWidth); - } - else - { - OutputCompositeBorderWidthPropertyValue(topBorderWidth, rightBorderWidth, bottomBorderWidth, leftBorderWidth); - } - - writer.WriteAttributeValue(";"); - - writer.WriteAttributeValue("border-style:"); - if (allSidesEqualStyle) - { - OutputBorderStylePropertyValue(topBorderStyle); - } - else if (hvSidesEqualStyle) - { - OutputCompositeBorderStylePropertyValue(topBorderStyle, rightBorderStyle); - } - else - { - OutputCompositeBorderStylePropertyValue(topBorderStyle, rightBorderStyle, bottomBorderStyle, leftBorderStyle); - } - writer.WriteAttributeValue(";"); - - writer.WriteAttributeValue("border-color:"); - if (allSidesEqualColor) - { - OutputBorderColorPropertyValue(topBorderColor); - } - else if (hvSidesEqualColor) - { - OutputCompositeBorderColorPropertyValue(topBorderColor, rightBorderColor); - } - else - { - OutputCompositeBorderColorPropertyValue(topBorderColor, rightBorderColor, bottomBorderColor, leftBorderColor); - } - writer.WriteAttributeValue(";"); - } - } - else - { - - - bool topWidthOutput = false, rightWidthOutput = false, bottomWidthOutput = false, leftWidthOutput = false; - bool topStyleOutput = false, rightStyleOutput = false, bottomStyleOutput = false, leftStyleOutput = false; - bool topColorOutput = false, rightColorOutput = false, bottomColorOutput = false, leftColorOutput = false; - - if (numSidesDefinedWidth == 4 || numSidesDefinedStyle == 4 || numSidesDefinedColor == 4) - { - - - if (numSidesDefinedWidth == 4) - { - writer.WriteAttributeValue("border-width:"); - if (allSidesEqualWidth) - { - OutputBorderWidthPropertyValue(topBorderWidth); - } - else if (hvSidesEqualWidth) - { - OutputCompositeBorderWidthPropertyValue(topBorderWidth, rightBorderWidth); - } - else - { - OutputCompositeBorderWidthPropertyValue(topBorderWidth, rightBorderWidth, bottomBorderWidth, leftBorderWidth); - } - writer.WriteAttributeValue(";"); - - topWidthOutput = true; - rightWidthOutput = true; - bottomWidthOutput = true; - leftWidthOutput = true; - } - - if (numSidesDefinedStyle == 4) - { - writer.WriteAttributeValue("border-style:"); - if (allSidesEqualStyle) - { - OutputBorderStylePropertyValue(topBorderStyle); - } - else if (hvSidesEqualStyle) - { - OutputCompositeBorderStylePropertyValue(topBorderStyle, rightBorderStyle); - } - else - { - OutputCompositeBorderStylePropertyValue(topBorderStyle, rightBorderStyle, bottomBorderStyle, leftBorderStyle); - } - writer.WriteAttributeValue(";"); - - topStyleOutput = true; - rightStyleOutput = true; - bottomStyleOutput = true; - leftStyleOutput = true; - } - - if (numSidesDefinedColor == 4) - { - writer.WriteAttributeValue("border-color:"); - if (allSidesEqualColor) - { - OutputBorderColorPropertyValue(topBorderColor); - } - else if (hvSidesEqualColor) - { - OutputCompositeBorderColorPropertyValue(topBorderColor, rightBorderColor); - } - else - { - OutputCompositeBorderColorPropertyValue(topBorderColor, rightBorderColor, bottomBorderColor, leftBorderColor); - } - writer.WriteAttributeValue(";"); - - topColorOutput = true; - rightColorOutput = true; - bottomColorOutput = true; - leftColorOutput = true; - } - } - else if (numPropsDefinedTop == 3 || numPropsDefinedRight == 3 || numPropsDefinedBottom == 3 || numPropsDefinedLeft == 3) - { - - - if (numPropsDefinedTop == 3) - { - writer.WriteAttributeValue("border-top:"); - OutputCompositeBorderSidePropertyValue(topBorderWidth, topBorderStyle, topBorderColor); - writer.WriteAttributeValue(";"); - - topWidthOutput = true; - topStyleOutput = true; - topColorOutput = true; - } - - if (numPropsDefinedRight == 3) - { - writer.WriteAttributeValue("border-right:"); - OutputCompositeBorderSidePropertyValue(rightBorderWidth, rightBorderStyle, rightBorderColor); - writer.WriteAttributeValue(";"); - - rightWidthOutput = true; - rightStyleOutput = true; - rightColorOutput = true; - } - - if (numPropsDefinedBottom == 3) - { - writer.WriteAttributeValue("border-bottom:"); - OutputCompositeBorderSidePropertyValue(bottomBorderWidth, bottomBorderStyle, bottomBorderColor); - writer.WriteAttributeValue(";"); - - bottomWidthOutput = true; - bottomStyleOutput = true; - bottomColorOutput = true; - } - - if (numPropsDefinedLeft == 3) - { - writer.WriteAttributeValue("border-left:"); - OutputCompositeBorderSidePropertyValue(leftBorderWidth, leftBorderStyle, leftBorderColor); - writer.WriteAttributeValue(";"); - - leftWidthOutput = true; - leftStyleOutput = true; - leftColorOutput = true; - } - } - - - - if (!topWidthOutput && !topBorderWidth.IsNull) - { - writer.WriteAttributeValue("border-top-width:"); - OutputBorderWidthPropertyValue(topBorderWidth); - writer.WriteAttributeValue(";"); - } - - if (!rightWidthOutput && !rightBorderWidth.IsNull) - { - writer.WriteAttributeValue("border-right-width:"); - OutputBorderWidthPropertyValue(rightBorderWidth); - writer.WriteAttributeValue(";"); - } - - if (!bottomWidthOutput && !bottomBorderWidth.IsNull) - { - writer.WriteAttributeValue("border-bottom-width:"); - OutputBorderWidthPropertyValue(bottomBorderWidth); - writer.WriteAttributeValue(";"); - } - - if (!leftWidthOutput && !leftBorderWidth.IsNull) - { - writer.WriteAttributeValue("border-left-width:"); - OutputBorderWidthPropertyValue(leftBorderWidth); - writer.WriteAttributeValue(";"); - } - - if (!topStyleOutput && !topBorderStyle.IsNull) - { - writer.WriteAttributeValue("border-top-style:"); - OutputBorderStylePropertyValue(topBorderStyle); - writer.WriteAttributeValue(";"); - } - - if (!rightStyleOutput && !rightBorderStyle.IsNull) - { - writer.WriteAttributeValue("border-right-style:"); - OutputBorderStylePropertyValue(rightBorderStyle); - writer.WriteAttributeValue(";"); - } - - if (!bottomStyleOutput && !bottomBorderStyle.IsNull) - { - writer.WriteAttributeValue("border-bottom-style:"); - OutputBorderStylePropertyValue(bottomBorderStyle); - writer.WriteAttributeValue(";"); - } - - if (!leftStyleOutput && !leftBorderStyle.IsNull) - { - writer.WriteAttributeValue("border-left-style:"); - OutputBorderStylePropertyValue(leftBorderStyle); - writer.WriteAttributeValue(";"); - } - - if (!topColorOutput && !topBorderColor.IsNull) - { - writer.WriteAttributeValue("border-top-color:"); - OutputBorderColorPropertyValue(topBorderColor); - writer.WriteAttributeValue(";"); - } - - if (!rightColorOutput && !rightBorderColor.IsNull) - { - writer.WriteAttributeValue("border-right-color:"); - OutputBorderColorPropertyValue(rightBorderColor); - writer.WriteAttributeValue(";"); - } - - if (!bottomColorOutput && !bottomBorderColor.IsNull) - { - writer.WriteAttributeValue("border-bottom-color:"); - OutputBorderColorPropertyValue(bottomBorderColor); - writer.WriteAttributeValue(";"); - } - - if (!leftColorOutput && !leftBorderColor.IsNull) - { - writer.WriteAttributeValue("border-left-color:"); - OutputBorderColorPropertyValue(leftBorderColor); - writer.WriteAttributeValue(";"); - } - } - } - - private void OutputCompositeBorderSidePropertyValue(PropertyValue width, PropertyValue style, PropertyValue color) - { - OutputBorderWidthPropertyValue(width); - writer.WriteAttributeValue(" "); - OutputBorderStylePropertyValue(style); - writer.WriteAttributeValue(" "); - OutputBorderColorPropertyValue(color); - } - - private void OutputCompositeLengthPropertyValue(PropertyValue topBottom, PropertyValue rightLeft) - { - OutputLengthPropertyValue(topBottom); - writer.WriteAttributeValue(" "); - OutputLengthPropertyValue(rightLeft); - } - - private void OutputCompositeLengthPropertyValue(PropertyValue top, PropertyValue right, PropertyValue bottom, PropertyValue left) - { - OutputLengthPropertyValue(top); - writer.WriteAttributeValue(" "); - OutputLengthPropertyValue(right); - writer.WriteAttributeValue(" "); - OutputLengthPropertyValue(bottom); - writer.WriteAttributeValue(" "); - OutputLengthPropertyValue(left); - } - - private void OutputCompositeBorderWidthPropertyValue(PropertyValue topBottom, PropertyValue rightLeft) - { - OutputBorderWidthPropertyValue(topBottom); - writer.WriteAttributeValue(" "); - OutputBorderWidthPropertyValue(rightLeft); - } - - private void OutputCompositeBorderWidthPropertyValue(PropertyValue top, PropertyValue right, PropertyValue bottom, PropertyValue left) - { - OutputBorderWidthPropertyValue(top); - writer.WriteAttributeValue(" "); - OutputBorderWidthPropertyValue(right); - writer.WriteAttributeValue(" "); - OutputBorderWidthPropertyValue(bottom); - writer.WriteAttributeValue(" "); - OutputBorderWidthPropertyValue(left); - } - - private void OutputCompositeBorderStylePropertyValue(PropertyValue topBottom, PropertyValue rightLeft) - { - OutputBorderStylePropertyValue(topBottom); - writer.WriteAttributeValue(" "); - OutputBorderStylePropertyValue(rightLeft); - } - - private void OutputCompositeBorderStylePropertyValue(PropertyValue top, PropertyValue right, PropertyValue bottom, PropertyValue left) - { - OutputBorderStylePropertyValue(top); - writer.WriteAttributeValue(" "); - OutputBorderStylePropertyValue(right); - writer.WriteAttributeValue(" "); - OutputBorderStylePropertyValue(bottom); - writer.WriteAttributeValue(" "); - OutputBorderStylePropertyValue(left); - } - - private void OutputCompositeBorderColorPropertyValue(PropertyValue topBottom, PropertyValue rightLeft) - { - OutputBorderColorPropertyValue(topBottom); - writer.WriteAttributeValue(" "); - OutputBorderColorPropertyValue(rightLeft); - } - - private void OutputCompositeBorderColorPropertyValue(PropertyValue top, PropertyValue right, PropertyValue bottom, PropertyValue left) - { - OutputBorderColorPropertyValue(top); - writer.WriteAttributeValue(" "); - OutputBorderColorPropertyValue(right); - writer.WriteAttributeValue(" "); - OutputBorderColorPropertyValue(bottom); - writer.WriteAttributeValue(" "); - OutputBorderColorPropertyValue(left); - } - - private void OutputLengthPropertyValue(PropertyValue width) - { - var val = HtmlSupport.FormatLength(ref scratchBuffer, width); - InternalDebug.Assert(val.Length != 0); - if (val.Length != 0) - { - writer.WriteAttributeValue(val); - } - else - { - writer.WriteAttributeValue("0"); - } - } - - private void OutputBorderWidthPropertyValue(PropertyValue width) - { - var val = HtmlSupport.FormatLength(ref scratchBuffer, width); - InternalDebug.Assert(val.Length != 0); - if (val.Length != 0) - { - writer.WriteAttributeValue(val); - } - else - { - writer.WriteAttributeValue("medium"); - } - } - - private void OutputBorderStylePropertyValue(PropertyValue style) - { - InternalDebug.Assert(!style.IsNull); - - var str = HtmlSupport.GetBorderStyleString(style); - InternalDebug.Assert(str != null); - if (str != null) - { - writer.WriteAttributeValue(str); - } - else - { - writer.WriteAttributeValue("solid"); - } - } - - private void OutputBorderColorPropertyValue(PropertyValue color) - { - InternalDebug.Assert(!color.IsNull); - - var val = HtmlSupport.FormatColor(ref scratchBuffer, color); - InternalDebug.Assert(val.Length != 0); - if (val.Length != 0) - { - writer.WriteAttributeValue(val); - } - else - { - writer.WriteAttributeValue("black"); - } - } - - - - private void OutputTableCssProperties(ref bool styleAttributeOpen) - { - var layoutFixed = GetDistinctProperty(PropertyId.TableLayoutFixed); - var borderCollapse = GetDistinctProperty(PropertyId.TableBorderCollapse); - var showEmptyCells = GetDistinctProperty(PropertyId.TableShowEmptyCells); - var captionSideTop = GetDistinctProperty(PropertyId.TableCaptionSideTop); - var spacingVertical = GetDistinctProperty(PropertyId.TableBorderSpacingVertical); - var spacingHorizontal = GetDistinctProperty(PropertyId.TableBorderSpacingHorizontal); - - if (!layoutFixed.IsNull || - !borderCollapse.IsNull || - !showEmptyCells.IsNull || - !captionSideTop.IsNull || - !spacingVertical.IsNull || - !spacingHorizontal.IsNull) - { - if (!styleAttributeOpen) - { - writer.WriteAttributeName(HtmlNameIndex.Style); - styleAttributeOpen = true; - } - - if (!layoutFixed.IsNull) - { - writer.WriteAttributeValue("table-layout:"); - writer.WriteAttributeValue(layoutFixed.Bool ? "fixed" : "auto"); - writer.WriteAttributeValue(";"); - } - - if (!borderCollapse.IsNull) - { - writer.WriteAttributeValue("border-collapse:"); - writer.WriteAttributeValue(borderCollapse.Bool ? "collapse" : "separate"); - writer.WriteAttributeValue(";"); - } - - if (!showEmptyCells.IsNull) - { - writer.WriteAttributeValue("empty-cells:"); - writer.WriteAttributeValue(showEmptyCells.Bool ? "show" : "hide"); - writer.WriteAttributeValue(";"); - } - - if (!captionSideTop.IsNull) - { - writer.WriteAttributeValue("caption-side:"); - writer.WriteAttributeValue(captionSideTop.Bool ? "top" : "bottom"); - writer.WriteAttributeValue(";"); - } - - if (!spacingVertical.IsNull && !spacingVertical.IsNull) - { - var val = HtmlSupport.FormatLength(ref scratchBuffer, spacingVertical); - if (val.Length != 0) - { - writer.WriteAttributeValue("border-spacing:"); - writer.WriteAttributeValue(val); - - if (spacingVertical != spacingHorizontal) - { - val = HtmlSupport.FormatLength(ref scratchBuffer, spacingHorizontal); - if (val.Length != 0) - { - writer.WriteAttributeValue(" "); - writer.WriteAttributeValue(val); - } - } - writer.WriteAttributeValue(";"); - } - } - } - } - - - - private void OutputTableColumnCssProperties(ref bool styleAttributeOpen) - { - var width = GetDistinctProperty(PropertyId.Width); - var backColor = GetDistinctProperty(PropertyId.BackColor); - - if (!backColor.IsNull || - !width.IsNull) - { - if (!styleAttributeOpen) - { - writer.WriteAttributeName(HtmlNameIndex.Style); - styleAttributeOpen = true; - } - - if (!width.IsNull) - { - var val = HtmlSupport.FormatLength(ref scratchBuffer, width); - if (val.Length != 0) - { - writer.WriteAttributeValue("width:"); - writer.WriteAttributeValue(val); - writer.WriteAttributeValue(";"); - } - } - - if (!backColor.IsNull) - { - var val = HtmlSupport.FormatColor(ref scratchBuffer, backColor); - if (val.Length != 0) - { - writer.WriteAttributeValue("background-color:"); - writer.WriteAttributeValue(val); - } - } - } - } - - - - private void OutputBlockTagAttributes() - { - var rtl = GetDistinctProperty(PropertyId.RightToLeft); - if (!rtl.IsNull) - { - writer.WriteAttribute(HtmlNameIndex.Dir, rtl.Bool ? "rtl" : "ltr"); - } - - var textAlignment = GetDistinctProperty(PropertyId.TextAlignment); - if (!textAlignment.IsNull) - { - var val = HtmlSupport.GetTextAlignmentString(textAlignment); - if (val != null) - { - writer.WriteAttribute(HtmlNameIndex.Align, val); - } - } - } - - - - private void OutputTableTagAttributes() - { - var width = GetDistinctProperty(PropertyId.Width); - if (!width.IsNull) - { - var val = HtmlSupport.FormatPixelOrPercentageLength(ref scratchBuffer, width); - if (val.Length != 0) - { - writer.WriteAttribute(HtmlNameIndex.Width, val); - } - } - - var align = GetDistinctProperty(PropertyId.HorizontalAlignment); - if (!align.IsNull) - { - var val = HtmlSupport.GetHorizontalAlignmentString(align); - if (val != null) - { - writer.WriteAttribute(HtmlNameIndex.Align, val); - } - } - - var rtl = GetDistinctProperty(PropertyId.RightToLeft); - if (!rtl.IsNull) - { - writer.WriteAttribute(HtmlNameIndex.Dir, rtl.Bool ? "rtl" : "ltr"); - } - - var border = GetDistinctProperty(PropertyId.TableBorder); - if (!border.IsNull) - { - var val = HtmlSupport.FormatPixelOrPercentageLength(ref scratchBuffer, border); - if (val.Length != 0) - { - writer.WriteAttribute(HtmlNameIndex.Border, val); - } - } - - var frame = GetDistinctProperty(PropertyId.TableFrame); - if (!frame.IsNull) - { - var val = HtmlSupport.GetTableFrameString(frame); - if (val != null) - { - writer.WriteAttribute(HtmlNameIndex.Frame, val); - } - } - - var rules = GetDistinctProperty(PropertyId.TableRules); - if (!rules.IsNull) - { - var val = HtmlSupport.GetTableRulesString(rules); - if (val != null) - { - writer.WriteAttribute(HtmlNameIndex.Rules, val); - } - } - - var cellSpacing = GetDistinctProperty(PropertyId.TableCellSpacing); - if (!cellSpacing.IsNull) - { - var val = HtmlSupport.FormatPixelOrPercentageLength(ref scratchBuffer, cellSpacing); - if (val.Length != 0) - { - writer.WriteAttribute(HtmlNameIndex.CellSpacing, val); - } - } - - var cellPadding = GetDistinctProperty(PropertyId.TableCellPadding); - if (!cellPadding.IsNull) - { - var val = HtmlSupport.FormatPixelOrPercentageLength(ref scratchBuffer, cellPadding); - if (val.Length != 0) - { - writer.WriteAttribute(HtmlNameIndex.CellPadding, val); - } - } - - } - - - - private void OutputTableCellTagAttributes() - { - var colSpan = GetDistinctProperty(PropertyId.NumColumns); - if (colSpan.IsInteger && colSpan.Integer != 1) - { - writer.WriteAttribute(HtmlNameIndex.ColSpan, colSpan.Integer.ToString()); - } - - var rowSpan = GetDistinctProperty(PropertyId.NumRows); - if (rowSpan.IsInteger && rowSpan.Integer != 1) - { - writer.WriteAttribute(HtmlNameIndex.RowSpan, rowSpan.Integer.ToString()); - } - - var width = GetDistinctProperty(PropertyId.Width); - if (!width.IsNull && width.IsAbsRelLength) - { - writer.WriteAttribute(HtmlNameIndex.Width, width.PixelsInteger.ToString()); - } - - var textAlignment = GetDistinctProperty(PropertyId.TextAlignment); - if (!textAlignment.IsNull) - { - var val = HtmlSupport.GetTextAlignmentString(textAlignment); - if (val != null) - { - writer.WriteAttribute(HtmlNameIndex.Align, val); - } - } - - var verticalAlignment = GetDistinctProperty(PropertyId.VerticalAlignment); - if (!verticalAlignment.IsNull) - { - var val = HtmlSupport.GetVerticalAlignmentString(verticalAlignment); - if (val != null) - { - writer.WriteAttribute(HtmlNameIndex.Valign, val); - } - } - - var noWrap = GetDistinctProperty(PropertyId.TableCellNoWrap); - if (!noWrap.IsNull && noWrap.Bool) - { - writer.WriteAttribute(HtmlNameIndex.NoWrap, ""); - } - } - - - - private bool RecognizeHyperLink(TextRun run, out int offset, out int length, out bool addFilePrefix, out bool addHttpPrefix) - { - - - - - - - - - scratchBuffer.Reset(); - - run.AppendFragment(0, ref scratchBuffer, 10); - - offset = 0; - length = 0; - - - while (offset < 3 && (scratchBuffer[offset] == '<' || scratchBuffer[offset] == '\"' || scratchBuffer[offset] == '\'' || - scratchBuffer[offset] == '(' || scratchBuffer[offset] == '[')) - { - offset ++; - } - - - - - - - - - var link = false; - addHttpPrefix = false; - addFilePrefix = false; - - if (scratchBuffer[offset] == '\\') - { - if (scratchBuffer[offset + 1] == '\\' && - Char.IsLetterOrDigit(scratchBuffer[offset + 2])) - { - - link = true; - addFilePrefix = true; - } - } - else if (scratchBuffer[offset] == 'h') - { - if (scratchBuffer[offset + 1] == 't' && - scratchBuffer[offset + 2] == 't' && - scratchBuffer[offset + 3] == 'p' && - (scratchBuffer[offset + 4] == ':' || - (scratchBuffer[offset + 4] == 's' && scratchBuffer[offset + 5] == ':'))) - { - - link = true; - } - } - else if (scratchBuffer[offset] == 'f') - { - if (scratchBuffer[offset + 1] == 't' && - scratchBuffer[offset + 2] == 'p' && - scratchBuffer[offset + 3] == ':') - { - - link = true; - } - else if (scratchBuffer[offset + 1] == 'i' && - scratchBuffer[offset + 2] == 'l' && - scratchBuffer[offset + 3] == 'e' && - scratchBuffer[offset + 4] == ':' && - scratchBuffer[offset + 5] == '/' && - scratchBuffer[offset + 6] == '/') - { - - - - link = true; - } - } - else if (scratchBuffer[offset] == 'm') - { - if (scratchBuffer[offset + 1] == 'a' && - scratchBuffer[offset + 2] == 'i' && - scratchBuffer[offset + 3] == 'l' && - scratchBuffer[offset + 4] == 't' && - scratchBuffer[offset + 5] == 'o' && - scratchBuffer[offset + 6] == ':') - { - - link = true; - } - } - else if (scratchBuffer[offset] == 'w') - { - if (scratchBuffer[offset + 1] == 'w' && - scratchBuffer[offset + 2] == 'w' && - scratchBuffer[offset + 3] == '.') - { - - link = true; - addHttpPrefix = true; - } - } - - if (link) - { - var end = 10 + run.AppendFragment(10, ref scratchBuffer, MaxRecognizedHyperlinkLength - 10); - - - while (scratchBuffer[end - 1] == '>' || scratchBuffer[end - 1] == '\"' || scratchBuffer[end - 1] == '\'' || - scratchBuffer[end - 1] == ')' || scratchBuffer[end - 1] == ']' || - scratchBuffer[end - 1] == '.' || scratchBuffer[end - 1] == ',' || scratchBuffer[end - 1] == ';') - { - end --; - } - - length = end - offset; - } - - return link; - } - - - - protected override void Dispose(bool disposing) - { - if (writer != null && writer is IDisposable) - { - ((IDisposable)writer).Dispose(); - } - - writer = null; - - base.Dispose(disposing); - } - } - - - - internal class HtmlFormatOutputCallbackContext : HtmlTagContext - { - private const int MaxCallbackAttributes = 10; - - private HtmlFormatOutput formatOutput; - private int countAttributes; - private AttributeDescriptor[] attributes = new AttributeDescriptor[MaxCallbackAttributes]; - - private static readonly HtmlAttributeParts CompleteAttributeParts = new HtmlAttributeParts(HtmlToken.AttrPartMajor.Complete, HtmlToken.AttrPartMinor.CompleteName | HtmlToken.AttrPartMinor.CompleteValue); - private static readonly HtmlTagParts CompleteTagWithAttributesParts = new HtmlTagParts(HtmlToken.TagPartMajor.Complete, HtmlToken.TagPartMinor.CompleteName | HtmlToken.TagPartMinor.Attributes); - private static readonly HtmlTagParts CompleteTagWithoutAttributesParts = new HtmlTagParts(HtmlToken.TagPartMajor.Complete, HtmlToken.TagPartMinor.CompleteName); - - private struct AttributeDescriptor - { - public HtmlNameIndex nameIndex; - public string value; - public int readIndex; - } - - public HtmlFormatOutputCallbackContext(HtmlFormatOutput formatOutput) - { - this.formatOutput = formatOutput; - } - - public new void InitializeTag(bool isEndTag, HtmlNameIndex tagNameIndex, bool tagDropped) - { - base.InitializeTag(isEndTag, tagNameIndex, tagDropped); - countAttributes = 0; - } - - internal void Reset() - { - countAttributes = 0; - } - - internal void AddAttribute(HtmlNameIndex nameIndex, string value) - { - InternalDebug.Assert(countAttributes < MaxCallbackAttributes); - - attributes[countAttributes].nameIndex = nameIndex; - attributes[countAttributes].value = value; - attributes[countAttributes].readIndex = 0; - countAttributes ++; - } - - public void InitializeFragment(bool isEmptyElementTag) - { - base.InitializeFragment(isEmptyElementTag, countAttributes, countAttributes == 0 ? CompleteTagWithoutAttributesParts : CompleteTagWithAttributesParts); - } - - - - - internal override string GetTagNameImpl() - { - InternalDebug.Assert(TagNameIndex > HtmlNameIndex.Unknown); - return HtmlNameData.names[(int)TagNameIndex].name; - } - - internal override HtmlAttributeId GetAttributeNameIdImpl(int attributeIndex) - { - return HtmlNameData.names[(int)attributes[attributeIndex].nameIndex].publicAttributeId; - } - - internal override HtmlAttributeParts GetAttributePartsImpl(int attributeIndex) - { - return CompleteAttributeParts; - } - - internal override string GetAttributeNameImpl(int attributeIndex) - { - InternalDebug.Assert(attributes[attributeIndex].nameIndex > HtmlNameIndex.Unknown); - return HtmlNameData.names[(int)attributes[attributeIndex].nameIndex].name; - } - - - - internal override string GetAttributeValueImpl(int attributeIndex) - { - return attributes[attributeIndex].value; - } - - internal override int ReadAttributeValueImpl(int attributeIndex, char[] buffer, int offset, int count) - { - var countToCopy = Math.Min(count, attributes[attributeIndex].value.Length - attributes[attributeIndex].readIndex); - - if (countToCopy != 0) - { - attributes[attributeIndex].value.CopyTo(attributes[attributeIndex].readIndex, buffer, offset, countToCopy); - attributes[attributeIndex].readIndex += countToCopy; - } - - return countToCopy; - } - - internal override void WriteTagImpl(bool copyTagAttributes) - { - formatOutput.writer.WriteTagBegin(TagNameIndex, null, IsEndTag, false, false); - - if (copyTagAttributes) - { - for (var i = 0; i < countAttributes; i++) - { - WriteAttributeImpl(i, true, true); - } - } - } - - internal override void WriteAttributeImpl(int attributeIndex, bool writeName, bool writeValue) - { - if (writeName) - { - formatOutput.writer.WriteAttributeName(attributes[attributeIndex].nameIndex); - } - - if (writeValue) - { - formatOutput.writer.WriteAttributeValue(attributes[attributeIndex].value); - } - } - } -} - diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlNameData.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlNameData.cs deleted file mode 100644 index be740efc2..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlNameData.cs +++ /dev/null @@ -1,2625 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters.Internal.Html -{ - internal enum HtmlNameIndex : byte - { - _NOTANAME = 0, - _COMMENT = 1, - _CONDITIONAL = 2, - _BANG = 3, - _ASP = 4, - _DTD = 5, - Unknown = 6, - Nofill = 7, - Comment = 8, - LI = 9, - Version = 10, - CellSpacing = 11, - Kbd = 12, - Scheme = 13, - Multiple = 14, - Ruby = 15, - Code = 16, - NoResize = 17, - Alt = 18, - HrefLang = 19, - FlushRight = 20, - Accept = 21, - FrameBorder = 22, - Shape = 23, - Param = 24, - Acronym = 25, - Bdo = 26, - For = 27, - Text = 28, - Color = 29, - A = 30, - _Pxml = 31, - Face = 32, - RowSpan = 33, - NoWrap = 34, - Ins = 35, - RP = 36, - Script = 37, - Char = 38, - BGColor = 39, - Style = 40, - Width = 41, - Headers = 42, - Map = 43, - Listing = 44, - Data = 45, - Sub = 46, - H2 = 47, - Image = 48, - StandBy = 49, - Select = 50, - Profile = 51, - NoHref = 52, - Button = 53, - Meta = 54, - Rules = 55, - Class = 56, - Src = 57, - Legend = 58, - Scrolling = 59, - Vlink = 60, - Del = 61, - Hspace = 62, - Charset = 63, - RT = 64, - Italic = 65, - Div = 66, - Dir = 67, - TT = 68, - LowSrc = 69, - H6 = 70, - ValueType = 71, - Declare = 72, - Size = 73, - FrameSet = 74, - ReadOnly = 75, - Language = 76, - Area = 77, - BlockQuote = 78, - TopMargin = 79, - NoEmbed = 80, - BaseFont = 81, - NoFrames = 82, - Border = 83, - Center = 84, - Height = 85, - Underline = 86, - FlushBoth = 87, - BGSound = 88, - Var = 89, - Start = 90, - TD = 91, - Id = 92, - Rows = 93, - H4 = 94, - Abbr = 95, - HttpEquiv = 96, - Span = 97, - DD = 98, - Address = 99, - Applet = 100, - Rel = 101, - TextArea = 102, - Tbody = 103, - ParaIndent = 104, - DT = 105, - Checked = 106, - NextId = 107, - Head = 108, - Rev = 109, - Small = 110, - Cite = 111, - Cols = 112, - LongDesc = 113, - Sup = 114, - Fixed = 115, - Prompt = 116, - Disabled = 117, - Name = 118, - Coords = 119, - Summary = 120, - Object = 121, - Label = 122, - Content = 123, - Target = 124, - EM = 125, - Clear = 126, - Scope = 127, - Compact = 128, - Blink = 129, - Selected = 130, - MaxLength = 131, - Frame = 132, - Thead = 133, - TabIndex = 134, - _Import = 135, - Marquee = 136, - Embed = 137, - TH = 138, - Caption = 139, - Value = 140, - Smaller = 141, - DateTime = 142, - ClassId = 143, - Bold = 144, - Strike = 145, - FlushLeft = 146, - NoShade = 147, - LeftMargin = 148, - Title = 149, - Excerpt = 150, - CellPadding = 151, - Doofn = 152, - CharOff = 153, - IsIndex = 154, - Tfoot = 155, - NoBR = 156, - Lang = 157, - OptGroup = 158, - AcceptCharset = 159, - Option = 160, - Big = 161, - Font = 162, - Type = 163, - Href = 164, - Img = 165, - Vspace = 166, - H3 = 167, - Align = 168, - Wbr = 169, - AccessKey = 170, - Col = 171, - Menu = 172, - Bigger = 173, - CodeBase = 174, - Strong = 175, - BR = 176, - Archive = 177, - UL = 178, - NoScript = 179, - PlainText = 180, - Base = 181, - IsMap = 182, - Defer = 183, - Body = 184, - OL = 185, - H1 = 186, - Valign = 187, - Media = 188, - Iframe = 189, - DL = 190, - ColSpan = 191, - Axis = 192, - MarginHeight = 193, - Alink = 194, - _Xml_Namespace = 195, - Method = 196, - FontFamily = 197, - FieldSet = 198, - Pre = 199, - Table = 200, - TR = 201, - Samp = 202, - Link = 203, - HR = 204, - Form = 205, - Input = 206, - Xml = 207, - UseMap = 208, - Xmp = 209, - Html = 210, - CodeType = 211, - MarginWidth = 212, - Q = 213, - ColGroup = 214, - DynSrc = 215, - S = 216, - P = 217, - U = 218, - Action = 219, - EncType = 220, - I = 221, - B = 222, - H5 = 223, - Background = 224, - } - - - - internal enum HtmlEntityIndex : ushort - { - omega = 1, - emsp = 2, - rle = 3, - Oacute = 4, - fnof = 5, - Oslash = 6, - Ntilde = 7, - larr = 8, - psi = 9, - QUOT = 10, - Pi = 11, - micro = 12, - piv = 13, - upsih = 14, - Xi = 15, - lceil = 16, - aring = 17, - ni = 18, - macr = 19, - cap = 20, - iuml = 21, - chi = 22, - frac14 = 23, - frac34 = 24, - ordm = 25, - nbsp = 26, - and = 27, - brvbar = 28, - zwsp = 29, - forall = 30, - pi = 31, - otimes = 32, - uacute = 33, - ang = 34, - iexcl = 35, - lrm = 36, - upsilon = 37, - xi = 38, - lre = 39, - zwj = 40, - Nu = 41, - Mu = 42, - lro = 43, - COPY = 44, - nsub = 45, - sub = 46, - thorn = 47, - sum = 48, - rsquo = 49, - middot = 50, - Ecirc = 51, - permil = 52, - thinsp = 53, - times = 54, - nu = 55, - mu = 56, - yen = 57, - prod = 58, - dArr = 59, - euml = 60, - acirc = 61, - Beta = 62, - radic = 63, - frac12 = 64, - hearts = 65, - TRADE = 66, - rsaquo = 67, - Auml = 68, - ugrave = 69, - ccedil = 70, - OElig = 71, - sect = 72, - Eacute = 73, - there4 = 74, - REG = 75, - plusmn = 76, - lang = 77, - thetasym = 78, - rArr = 79, - iota = 80, - rceil = 81, - empty = 82, - AMP = 83, - gt = 84, - Phi = 85, - Gamma = 86, - bass = 87, - lt = 88, - Zeta = 89, - Ograve = 90, - deg = 91, - spades = 92, - zwnj = 93, - exist = 94, - delta = 95, - reg = 96, - isin = 97, - Alpha = 98, - Yuml = 99, - cedil = 100, - sup2 = 101, - rfloor = 102, - divide = 103, - Omicron = 104, - ordf = 105, - clubs = 106, - Uuml = 107, - Eta = 108, - Acirc = 109, - Atilde = 110, - Rho = 111, - alefsym = 112, - AElig = 113, - lfloor = 114, - hArr = 115, - oline = 116, - Aacute = 117, - Ccedil = 118, - theta = 119, - or = 120, - Egrave = 121, - trade = 122, - Int = 123, - sup1 = 124, - phi = 125, - cup = 126, - equiv = 127, - sim = 128, - Yacute = 129, - Prime = 130, - uarr = 131, - mdash = 132, - amp = 133, - acute = 134, - ETH = 135, - eacute = 136, - weierp = 137, - Kappa = 138, - Theta = 139, - pound = 140, - rarr = 141, - Omega = 142, - oelig = 143, - sup = 144, - igrave = 145, - cent = 146, - agrave = 147, - dagger = 148, - bull = 149, - Ouml = 150, - Aring = 151, - loz = 152, - lowast = 153, - otilde = 154, - euro = 155, - uml = 156, - sigma = 157, - Epsilon = 158, - lsaquo = 159, - image = 160, - lArr = 161, - Iuml = 162, - Chi = 163, - eta = 164, - harr = 165, - aacute = 166, - nads = 167, - eth = 168, - GT = 169, - Sigma = 170, - THORN = 171, - oslash = 172, - aelig = 173, - LT = 174, - notin = 175, - aafs = 176, - yacute = 177, - laquo = 178, - prime = 179, - iss = 180, - Agrave = 181, - lambda = 182, - oplus = 183, - real = 184, - Ugrave = 185, - supe = 186, - para = 187, - darr = 188, - sube = 189, - asymp = 190, - Euml = 191, - ocirc = 192, - Lambda = 193, - beta = 194, - sup3 = 195, - infin = 196, - Upsilon = 197, - ucirc = 198, - Delta = 199, - auml = 200, - Iacute = 201, - circ = 202, - Iota = 203, - tilde = 204, - bdquo = 205, - scaron = 206, - Tau = 207, - zeta = 208, - pdf = 209, - perp = 210, - shy = 211, - icirc = 212, - yuml = 213, - gamma = 214, - sigmaf = 215, - rang = 216, - crarr = 217, - raquo = 218, - minus = 219, - ograve = 220, - uuml = 221, - Ocirc = 222, - nods = 223, - ldquo = 224, - rho = 225, - szlig = 226, - Ucirc = 227, - alpha = 228, - quot = 229, - Dagger = 230, - Uacute = 231, - Igrave = 232, - Psi = 233, - tau = 234, - lsquo = 235, - ge = 236, - atilde = 237, - nabla = 238, - Scaron = 239, - cong = 240, - frasl = 241, - ne = 242, - curren = 243, - le = 244, - uArr = 245, - epsilon = 246, - iacute = 247, - rlm = 248, - Otilde = 249, - sdot = 250, - rlo = 251, - ndash = 252, - egrave = 253, - Icirc = 254, - oacute = 255, - part = 256, - diams = 257, - copy = 258, - ntilde = 259, - rdquo = 260, - iquest = 261, - sbquo = 262, - not = 263, - iafs = 264, - ouml = 265, - ecirc = 266, - kappa = 267, - ensp = 268, - prop = 269, - omicron = 270, - hellip = 271, - } - - internal static class HtmlNameData - { - - public const short MAX_NAME = 14; - public const short MAX_TAG_NAME = 14; - - - public const short MAX_ENTITY_NAME = 8; - - - public struct NameDef - { - public short hash; - public bool literalTag; - public bool literalEnt; - public string name; - public HtmlTagIndex tagIndex; - public HtmlTagId publicTagId; - public HtmlAttributeId publicAttributeId; - - public NameDef(short hash, string name, HtmlTagId publicTagId, HtmlAttributeId publicAttributeId) : - this(hash, name, HtmlTagIndex.Unknown, false, false, publicTagId, publicAttributeId) - { - } - - public NameDef(short hash, string name, HtmlTagIndex tagIndex, bool literalTag, bool literalEnt, HtmlTagId publicTagId, HtmlAttributeId publicAttributeId) - { - this.hash = hash; - this.literalTag = literalTag; - this.literalEnt = literalEnt; - this.name = name; - this.tagIndex = tagIndex; - this.publicTagId = publicTagId; - this.publicAttributeId = publicAttributeId; - } - } - - public struct EntityDef - { - public short hash; - public short value; - public string name; - - public EntityDef(short hash, short value, string name) - { - this.hash = hash; - this.name = name; - this.value = value; - } - } - - - - public const short NAME_HASH_SIZE = 601; - public const int NAME_HASH_MODIFIER = 0xDD; - - public static HtmlNameIndex[] nameHashTable = - { - 0, - HtmlNameIndex.Nofill, - HtmlNameIndex.Comment, - HtmlNameIndex.LI, - HtmlNameIndex.Version, - 0, - 0, - 0, - HtmlNameIndex.CellSpacing, - 0, - HtmlNameIndex.Kbd, - 0, - 0, - 0, - HtmlNameIndex.Scheme, - HtmlNameIndex.Multiple, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Ruby, - 0, - HtmlNameIndex.Code, - HtmlNameIndex.NoResize, - HtmlNameIndex.Alt, - 0, - HtmlNameIndex.HrefLang, - 0, - 0, - HtmlNameIndex.FlushRight, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Accept, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.FrameBorder, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Shape, - 0, - 0, - HtmlNameIndex.Param, - HtmlNameIndex.Acronym, - 0, - HtmlNameIndex.For, - HtmlNameIndex.Color, - 0, - 0, - 0, - HtmlNameIndex.A, - 0, - 0, - HtmlNameIndex._Pxml, - 0, - HtmlNameIndex.Face, - 0, - 0, - 0, - HtmlNameIndex.RowSpan, - HtmlNameIndex.NoWrap, - HtmlNameIndex.Ins, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.RP, - HtmlNameIndex.Script, - 0, - HtmlNameIndex.Char, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.BGColor, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Style, - 0, - 0, - HtmlNameIndex.Width, - 0, - HtmlNameIndex.Headers, - 0, - HtmlNameIndex.Map, - 0, - HtmlNameIndex.Data, - 0, - 0, - HtmlNameIndex.Sub, - HtmlNameIndex.H2, - HtmlNameIndex.Image, - 0, - 0, - 0, - HtmlNameIndex.StandBy, - 0, - HtmlNameIndex.Select, - 0, - HtmlNameIndex.Profile, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Button, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Meta, - 0, - 0, - 0, - HtmlNameIndex.Rules, - HtmlNameIndex.Class, - 0, - 0, - HtmlNameIndex.Src, - HtmlNameIndex.Legend, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Scrolling, - 0, - 0, - HtmlNameIndex.Vlink, - HtmlNameIndex.Del, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Hspace, - 0, - 0, - HtmlNameIndex.Charset, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.RT, - 0, - HtmlNameIndex.Italic, - 0, - 0, - HtmlNameIndex.Div, - 0, - 0, - 0, - HtmlNameIndex.Dir, - HtmlNameIndex.TT, - 0, - HtmlNameIndex.H6, - HtmlNameIndex.ValueType, - HtmlNameIndex.Declare, - 0, - HtmlNameIndex.Size, - 0, - HtmlNameIndex.FrameSet, - 0, - HtmlNameIndex.ReadOnly, - 0, - HtmlNameIndex.Language, - 0, - HtmlNameIndex.Area, - 0, - HtmlNameIndex.TopMargin, - HtmlNameIndex.NoEmbed, - HtmlNameIndex.BaseFont, - 0, - 0, - 0, - 0, - HtmlNameIndex.NoFrames, - 0, - 0, - HtmlNameIndex.Border, - HtmlNameIndex.Center, - 0, - 0, - 0, - HtmlNameIndex.Height, - 0, - 0, - HtmlNameIndex.Underline, - 0, - HtmlNameIndex.FlushBoth, - 0, - HtmlNameIndex.BGSound, - 0, - 0, - 0, - 0, - HtmlNameIndex.Var, - 0, - 0, - HtmlNameIndex.TD, - HtmlNameIndex.Id, - HtmlNameIndex.Rows, - HtmlNameIndex.H4, - 0, - HtmlNameIndex.Abbr, - HtmlNameIndex.HttpEquiv, - HtmlNameIndex.Span, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.DD, - 0, - 0, - HtmlNameIndex.Address, - 0, - HtmlNameIndex.Applet, - HtmlNameIndex.Rel, - 0, - 0, - 0, - HtmlNameIndex.TextArea, - HtmlNameIndex.Tbody, - 0, - 0, - 0, - HtmlNameIndex.ParaIndent, - 0, - 0, - HtmlNameIndex.DT, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Checked, - HtmlNameIndex.Head, - 0, - 0, - HtmlNameIndex.Rev, - HtmlNameIndex.Small, - 0, - HtmlNameIndex.Cite, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Cols, - HtmlNameIndex.Sup, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Fixed, - HtmlNameIndex.Prompt, - 0, - 0, - 0, - 0, - HtmlNameIndex.Disabled, - 0, - HtmlNameIndex.Name, - HtmlNameIndex.Summary, - HtmlNameIndex.Object, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Label, - HtmlNameIndex.Content, - HtmlNameIndex.Target, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.EM, - 0, - 0, - 0, - HtmlNameIndex.Clear, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Scope, - 0, - HtmlNameIndex.Compact, - 0, - HtmlNameIndex.Blink, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Selected, - 0, - HtmlNameIndex.MaxLength, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Frame, - HtmlNameIndex.Thead, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.TabIndex, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex._Import, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Embed, - HtmlNameIndex.TH, - HtmlNameIndex.Caption, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Value, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Smaller, - 0, - 0, - 0, - HtmlNameIndex.DateTime, - 0, - HtmlNameIndex.ClassId, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Bold, - HtmlNameIndex.Strike, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.FlushLeft, - HtmlNameIndex.NoShade, - HtmlNameIndex.LeftMargin, - HtmlNameIndex.Title, - 0, - HtmlNameIndex.Excerpt, - 0, - HtmlNameIndex.CellPadding, - 0, - 0, - 0, - HtmlNameIndex.Doofn, - HtmlNameIndex.CharOff, - 0, - HtmlNameIndex.IsIndex, - HtmlNameIndex.Tfoot, - 0, - HtmlNameIndex.NoBR, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Lang, - 0, - HtmlNameIndex.OptGroup, - 0, - HtmlNameIndex.AcceptCharset, - 0, - HtmlNameIndex.Big, - HtmlNameIndex.Font, - 0, - HtmlNameIndex.Type, - 0, - 0, - HtmlNameIndex.Href, - 0, - HtmlNameIndex.Img, - 0, - HtmlNameIndex.Vspace, - HtmlNameIndex.H3, - 0, - 0, - 0, - 0, - 0, - HtmlNameIndex.Align, - 0, - 0, - 0, - HtmlNameIndex.Wbr, - 0, - HtmlNameIndex.AccessKey, - 0, - 0, - HtmlNameIndex.Col, - 0, - HtmlNameIndex.Menu, - 0, - HtmlNameIndex.CodeBase, - 0, - HtmlNameIndex.Strong, - 0, - HtmlNameIndex.BR, - 0, - HtmlNameIndex.Archive, - 0, - HtmlNameIndex.UL, - 0, - HtmlNameIndex.NoScript, - HtmlNameIndex.PlainText, - 0, - 0, - 0, - HtmlNameIndex.Base, - HtmlNameIndex.Defer, - HtmlNameIndex.Body, - HtmlNameIndex.OL, - 0, - HtmlNameIndex.H1, - 0, - HtmlNameIndex.Valign, - 0, - 0, - HtmlNameIndex.Media, - HtmlNameIndex.Iframe, - HtmlNameIndex.DL, - 0, - HtmlNameIndex.ColSpan, - 0, - 0, - HtmlNameIndex.Axis, - 0, - 0, - 0, - HtmlNameIndex.MarginHeight, - HtmlNameIndex.Alink, - 0, - HtmlNameIndex._Xml_Namespace, - HtmlNameIndex.Method, - 0, - 0, - HtmlNameIndex.FontFamily, - 0, - 0, - 0, - 0, - HtmlNameIndex.FieldSet, - 0, - HtmlNameIndex.Pre, - HtmlNameIndex.Table, - 0, - 0, - HtmlNameIndex.TR, - 0, - HtmlNameIndex.Samp, - HtmlNameIndex.Link, - HtmlNameIndex.HR, - 0, - 0, - 0, - HtmlNameIndex.Form, - HtmlNameIndex.Input, - HtmlNameIndex.Xml, - 0, - HtmlNameIndex.UseMap, - 0, - HtmlNameIndex.Xmp, - HtmlNameIndex.CodeType, - 0, - 0, - 0, - 0, - HtmlNameIndex.MarginWidth, - 0, - 0, - 0, - HtmlNameIndex.Q, - HtmlNameIndex.ColGroup, - HtmlNameIndex.S, - HtmlNameIndex.P, - HtmlNameIndex.U, - HtmlNameIndex.Action, - HtmlNameIndex.EncType, - 0, - HtmlNameIndex.I, - 0, - 0, - 0, - 0, - HtmlNameIndex.B, - HtmlNameIndex.H5, - HtmlNameIndex.Background, - 0, - }; - - - - public const short ENTITY_HASH_SIZE = 705; - public const int ENTITY_HASH_MODIFIER = 0xE6; - - public static HtmlEntityIndex[] entityHashTable = - { - 0, - HtmlEntityIndex.omega, - HtmlEntityIndex.rle, - 0, - 0, - HtmlEntityIndex.Oacute, - 0, - 0, - HtmlEntityIndex.fnof, - HtmlEntityIndex.Oslash, - 0, - 0, - HtmlEntityIndex.Ntilde, - 0, - HtmlEntityIndex.larr, - HtmlEntityIndex.psi, - 0, - 0, - 0, - 0, - HtmlEntityIndex.Pi, - 0, - HtmlEntityIndex.micro, - 0, - HtmlEntityIndex.piv, - 0, - HtmlEntityIndex.upsih, - 0, - HtmlEntityIndex.Xi, - HtmlEntityIndex.aring, - HtmlEntityIndex.ni, - 0, - HtmlEntityIndex.cap, - HtmlEntityIndex.iuml, - HtmlEntityIndex.chi, - 0, - 0, - 0, - HtmlEntityIndex.frac14, - 0, - HtmlEntityIndex.frac34, - HtmlEntityIndex.ordm, - 0, - 0, - HtmlEntityIndex.and, - 0, - 0, - HtmlEntityIndex.brvbar, - 0, - HtmlEntityIndex.zwsp, - HtmlEntityIndex.forall, - 0, - HtmlEntityIndex.pi, - HtmlEntityIndex.otimes, - HtmlEntityIndex.uacute, - HtmlEntityIndex.ang, - HtmlEntityIndex.iexcl, - HtmlEntityIndex.lrm, - 0, - 0, - HtmlEntityIndex.xi, - 0, - 0, - 0, - 0, - HtmlEntityIndex.lre, - HtmlEntityIndex.zwj, - 0, - HtmlEntityIndex.Nu, - HtmlEntityIndex.Mu, - 0, - HtmlEntityIndex.lro, - 0, - HtmlEntityIndex.COPY, - HtmlEntityIndex.nsub, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.thorn, - 0, - HtmlEntityIndex.sum, - 0, - HtmlEntityIndex.rsquo, - HtmlEntityIndex.middot, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.Ecirc, - HtmlEntityIndex.thinsp, - 0, - HtmlEntityIndex.times, - HtmlEntityIndex.mu, - HtmlEntityIndex.yen, - 0, - 0, - 0, - 0, - HtmlEntityIndex.prod, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.dArr, - 0, - HtmlEntityIndex.euml, - 0, - 0, - 0, - HtmlEntityIndex.Beta, - HtmlEntityIndex.radic, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.hearts, - HtmlEntityIndex.TRADE, - 0, - 0, - HtmlEntityIndex.rsaquo, - 0, - HtmlEntityIndex.Auml, - HtmlEntityIndex.ugrave, - 0, - 0, - 0, - 0, - HtmlEntityIndex.ccedil, - HtmlEntityIndex.OElig, - HtmlEntityIndex.sect, - 0, - HtmlEntityIndex.there4, - 0, - HtmlEntityIndex.REG, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.plusmn, - 0, - 0, - HtmlEntityIndex.thetasym, - 0, - 0, - HtmlEntityIndex.rArr, - HtmlEntityIndex.iota, - HtmlEntityIndex.rceil, - HtmlEntityIndex.empty, - HtmlEntityIndex.Phi, - HtmlEntityIndex.Gamma, - HtmlEntityIndex.bass, - 0, - 0, - 0, - HtmlEntityIndex.lt, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.Zeta, - 0, - HtmlEntityIndex.Ograve, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.spades, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.zwnj, - 0, - 0, - HtmlEntityIndex.delta, - 0, - 0, - 0, - HtmlEntityIndex.reg, - 0, - 0, - HtmlEntityIndex.isin, - HtmlEntityIndex.Alpha, - 0, - 0, - HtmlEntityIndex.Yuml, - 0, - 0, - 0, - HtmlEntityIndex.cedil, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.rfloor, - 0, - HtmlEntityIndex.divide, - 0, - HtmlEntityIndex.Omicron, - 0, - 0, - HtmlEntityIndex.ordf, - 0, - HtmlEntityIndex.clubs, - HtmlEntityIndex.Uuml, - HtmlEntityIndex.Eta, - 0, - HtmlEntityIndex.Acirc, - HtmlEntityIndex.Atilde, - HtmlEntityIndex.Rho, - HtmlEntityIndex.alefsym, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.AElig, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.hArr, - 0, - HtmlEntityIndex.oline, - 0, - 0, - 0, - HtmlEntityIndex.Aacute, - HtmlEntityIndex.Ccedil, - HtmlEntityIndex.theta, - HtmlEntityIndex.or, - HtmlEntityIndex.Egrave, - HtmlEntityIndex.trade, - HtmlEntityIndex.Int, - 0, - HtmlEntityIndex.sup1, - HtmlEntityIndex.phi, - 0, - HtmlEntityIndex.cup, - 0, - 0, - HtmlEntityIndex.equiv, - 0, - 0, - 0, - HtmlEntityIndex.sim, - HtmlEntityIndex.Yacute, - 0, - 0, - HtmlEntityIndex.Prime, - HtmlEntityIndex.uarr, - 0, - 0, - HtmlEntityIndex.mdash, - HtmlEntityIndex.acute, - 0, - 0, - 0, - HtmlEntityIndex.ETH, - 0, - HtmlEntityIndex.eacute, - 0, - 0, - HtmlEntityIndex.weierp, - 0, - HtmlEntityIndex.Kappa, - 0, - HtmlEntityIndex.Theta, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.pound, - 0, - 0, - HtmlEntityIndex.rarr, - 0, - 0, - 0, - 0, - HtmlEntityIndex.oelig, - HtmlEntityIndex.sup, - HtmlEntityIndex.igrave, - 0, - HtmlEntityIndex.cent, - 0, - 0, - HtmlEntityIndex.agrave, - 0, - HtmlEntityIndex.dagger, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.bull, - 0, - HtmlEntityIndex.Ouml, - 0, - 0, - 0, - 0, - HtmlEntityIndex.Aring, - 0, - 0, - HtmlEntityIndex.loz, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.lowast, - HtmlEntityIndex.otilde, - 0, - 0, - 0, - 0, - HtmlEntityIndex.euro, - HtmlEntityIndex.uml, - 0, - HtmlEntityIndex.sigma, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.Epsilon, - 0, - 0, - HtmlEntityIndex.lsaquo, - 0, - 0, - HtmlEntityIndex.image, - HtmlEntityIndex.lArr, - 0, - 0, - 0, - HtmlEntityIndex.Iuml, - HtmlEntityIndex.Chi, - 0, - 0, - 0, - 0, - HtmlEntityIndex.eta, - 0, - 0, - 0, - HtmlEntityIndex.harr, - 0, - 0, - HtmlEntityIndex.aacute, - 0, - HtmlEntityIndex.nads, - 0, - HtmlEntityIndex.eth, - HtmlEntityIndex.GT, - 0, - HtmlEntityIndex.Sigma, - 0, - 0, - 0, - HtmlEntityIndex.oslash, - HtmlEntityIndex.aelig, - 0, - HtmlEntityIndex.notin, - 0, - 0, - 0, - HtmlEntityIndex.aafs, - HtmlEntityIndex.yacute, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.laquo, - 0, - 0, - 0, - HtmlEntityIndex.prime, - HtmlEntityIndex.Agrave, - HtmlEntityIndex.lambda, - 0, - 0, - HtmlEntityIndex.oplus, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.real, - HtmlEntityIndex.Ugrave, - 0, - 0, - 0, - 0, - HtmlEntityIndex.supe, - 0, - HtmlEntityIndex.para, - 0, - 0, - 0, - 0, - HtmlEntityIndex.darr, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.sube, - 0, - HtmlEntityIndex.asymp, - HtmlEntityIndex.Euml, - HtmlEntityIndex.ocirc, - HtmlEntityIndex.Lambda, - 0, - 0, - 0, - 0, - HtmlEntityIndex.beta, - HtmlEntityIndex.sup3, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.infin, - HtmlEntityIndex.Upsilon, - HtmlEntityIndex.ucirc, - 0, - HtmlEntityIndex.Delta, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.Iacute, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.Iota, - 0, - 0, - HtmlEntityIndex.tilde, - HtmlEntityIndex.bdquo, - 0, - 0, - HtmlEntityIndex.scaron, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.Tau, - 0, - HtmlEntityIndex.zeta, - 0, - HtmlEntityIndex.pdf, - 0, - 0, - 0, - HtmlEntityIndex.perp, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.shy, - HtmlEntityIndex.icirc, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.yuml, - 0, - 0, - 0, - HtmlEntityIndex.gamma, - 0, - HtmlEntityIndex.sigmaf, - 0, - HtmlEntityIndex.rang, - 0, - 0, - HtmlEntityIndex.crarr, - 0, - 0, - HtmlEntityIndex.raquo, - 0, - HtmlEntityIndex.minus, - HtmlEntityIndex.ograve, - 0, - 0, - 0, - HtmlEntityIndex.uuml, - HtmlEntityIndex.Ocirc, - 0, - HtmlEntityIndex.nods, - HtmlEntityIndex.ldquo, - HtmlEntityIndex.rho, - HtmlEntityIndex.szlig, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.Ucirc, - 0, - HtmlEntityIndex.alpha, - 0, - 0, - HtmlEntityIndex.quot, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.Dagger, - HtmlEntityIndex.Uacute, - 0, - 0, - 0, - HtmlEntityIndex.Igrave, - 0, - HtmlEntityIndex.Psi, - 0, - 0, - 0, - 0, - HtmlEntityIndex.tau, - HtmlEntityIndex.lsquo, - HtmlEntityIndex.ge, - 0, - HtmlEntityIndex.atilde, - HtmlEntityIndex.nabla, - HtmlEntityIndex.Scaron, - HtmlEntityIndex.cong, - HtmlEntityIndex.frasl, - 0, - 0, - HtmlEntityIndex.ne, - HtmlEntityIndex.curren, - HtmlEntityIndex.le, - 0, - 0, - HtmlEntityIndex.uArr, - 0, - 0, - 0, - 0, - HtmlEntityIndex.epsilon, - HtmlEntityIndex.iacute, - 0, - HtmlEntityIndex.rlm, - HtmlEntityIndex.Otilde, - HtmlEntityIndex.sdot, - HtmlEntityIndex.ndash, - 0, - 0, - HtmlEntityIndex.egrave, - 0, - 0, - HtmlEntityIndex.Icirc, - 0, - HtmlEntityIndex.part, - HtmlEntityIndex.diams, - HtmlEntityIndex.copy, - 0, - 0, - HtmlEntityIndex.ntilde, - 0, - 0, - HtmlEntityIndex.rdquo, - HtmlEntityIndex.iquest, - HtmlEntityIndex.sbquo, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.not, - HtmlEntityIndex.iafs, - 0, - 0, - 0, - 0, - HtmlEntityIndex.ouml, - 0, - 0, - 0, - 0, - HtmlEntityIndex.ecirc, - 0, - HtmlEntityIndex.kappa, - 0, - 0, - 0, - 0, - HtmlEntityIndex.ensp, - 0, - 0, - HtmlEntityIndex.prop, - 0, - 0, - HtmlEntityIndex.omicron, - HtmlEntityIndex.hellip, - 0, - }; - - public static NameDef[] names = - { - new NameDef(0, null, HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(0, null, HtmlTagIndex._COMMENT, false, false, HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(0, null, HtmlTagIndex._CONDITIONAL, false, false, HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(0, null, HtmlTagIndex._BANG, false, false, HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(0, null, HtmlTagIndex._ASP, false, false, HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(0, null, HtmlTagIndex._DTD, false, false, HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(0, null, HtmlTagIndex.Unknown, false, false, HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(1, "nofill", HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(2, "comment", HtmlTagIndex.Comment, true, true, HtmlTagId.Comment, HtmlAttributeId.Unknown), - new NameDef(3, "li", HtmlTagIndex.LI, false, false, HtmlTagId.LI, HtmlAttributeId.Unknown), - new NameDef(4, "version", HtmlTagId.Unknown, HtmlAttributeId.Version), - new NameDef(8, "cellspacing", HtmlTagId.Unknown, HtmlAttributeId.CellSpacing), - new NameDef(10, "kbd", HtmlTagIndex.Kbd, false, false, HtmlTagId.Kbd, HtmlAttributeId.Unknown), - new NameDef(14, "scheme", HtmlTagId.Unknown, HtmlAttributeId.Scheme), - new NameDef(15, "multiple", HtmlTagId.Unknown, HtmlAttributeId.Multiple), - new NameDef(21, "ruby", HtmlTagIndex.Ruby, false, false, HtmlTagId.Ruby, HtmlAttributeId.Unknown), - new NameDef(23, "code", HtmlTagIndex.Code, false, false, HtmlTagId.Code, HtmlAttributeId.Code), - new NameDef(24, "noresize", HtmlTagId.Unknown, HtmlAttributeId.NoResize), - new NameDef(25, "alt", HtmlTagId.Unknown, HtmlAttributeId.Alt), - new NameDef(27, "hreflang", HtmlTagId.Unknown, HtmlAttributeId.HrefLang), - new NameDef(30, "flushright", HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(38, "accept", HtmlTagId.Unknown, HtmlAttributeId.Accept), - new NameDef(45, "frameborder", HtmlTagId.Unknown, HtmlAttributeId.FrameBorder), - new NameDef(52, "shape", HtmlTagId.Unknown, HtmlAttributeId.Shape), - new NameDef(55, "param", HtmlTagIndex.Param, false, false, HtmlTagId.Param, HtmlAttributeId.Unknown), - new NameDef(56, "acronym", HtmlTagIndex.Acronym, false, false, HtmlTagId.Acronym, HtmlAttributeId.Unknown), - new NameDef(56, "bdo", HtmlTagIndex.Bdo, false, false, HtmlTagId.Bdo, HtmlAttributeId.Unknown), - new NameDef(58, "for", HtmlTagId.Unknown, HtmlAttributeId.For), - new NameDef(58, "text", HtmlTagId.Unknown, HtmlAttributeId.Text), - new NameDef(59, "color", HtmlTagId.Unknown, HtmlAttributeId.Color), - new NameDef(63, "a", HtmlTagIndex.A, false, false, HtmlTagId.A, HtmlAttributeId.Unknown), - new NameDef(66, "?pxml", HtmlTagIndex._Pxml, false, false, HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(68, "face", HtmlTagId.Unknown, HtmlAttributeId.Face), - new NameDef(72, "rowspan", HtmlTagId.Unknown, HtmlAttributeId.RowSpan), - new NameDef(73, "nowrap", HtmlTagId.Unknown, HtmlAttributeId.NoWrap), - new NameDef(74, "ins", HtmlTagIndex.Ins, false, false, HtmlTagId.Ins, HtmlAttributeId.Unknown), - new NameDef(85, "rp", HtmlTagIndex.RP, false, false, HtmlTagId.RP, HtmlAttributeId.Unknown), - new NameDef(86, "script", HtmlTagIndex.Script, true, true, HtmlTagId.Script, HtmlAttributeId.Unknown), - new NameDef(88, "char", HtmlTagId.Unknown, HtmlAttributeId.Char), - new NameDef(100, "bgcolor", HtmlTagId.Unknown, HtmlAttributeId.BGColor), - new NameDef(123, "style", HtmlTagIndex.Style, true, true, HtmlTagId.Style, HtmlAttributeId.Style), - new NameDef(126, "width", HtmlTagId.Unknown, HtmlAttributeId.Width), - new NameDef(128, "headers", HtmlTagId.Unknown, HtmlAttributeId.Headers), - new NameDef(130, "map", HtmlTagIndex.Map, false, false, HtmlTagId.Map, HtmlAttributeId.Unknown), - new NameDef(130, "listing", HtmlTagIndex.Listing, false, false, HtmlTagId.Listing, HtmlAttributeId.Unknown), - new NameDef(132, "data", HtmlTagId.Unknown, HtmlAttributeId.Data), - new NameDef(135, "sub", HtmlTagIndex.Sub, false, false, HtmlTagId.Sub, HtmlAttributeId.Unknown), - new NameDef(136, "h2", HtmlTagIndex.H2, false, false, HtmlTagId.H2, HtmlAttributeId.Unknown), - new NameDef(137, "image", HtmlTagIndex.Image, false, false, HtmlTagId.Image, HtmlAttributeId.Unknown), - new NameDef(141, "standby", HtmlTagId.Unknown, HtmlAttributeId.StandBy), - new NameDef(143, "select", HtmlTagIndex.Select, false, false, HtmlTagId.Select, HtmlAttributeId.Unknown), - new NameDef(145, "profile", HtmlTagId.Unknown, HtmlAttributeId.Profile), - new NameDef(145, "nohref", HtmlTagId.Unknown, HtmlAttributeId.NoHref), - new NameDef(155, "button", HtmlTagIndex.Button, false, false, HtmlTagId.Button, HtmlAttributeId.Unknown), - new NameDef(162, "meta", HtmlTagIndex.Meta, false, false, HtmlTagId.Meta, HtmlAttributeId.Unknown), - new NameDef(166, "rules", HtmlTagId.Unknown, HtmlAttributeId.Rules), - new NameDef(167, "class", HtmlTagId.Unknown, HtmlAttributeId.Class), - new NameDef(170, "src", HtmlTagId.Unknown, HtmlAttributeId.Src), - new NameDef(171, "legend", HtmlTagIndex.Legend, false, false, HtmlTagId.Legend, HtmlAttributeId.Unknown), - new NameDef(177, "scrolling", HtmlTagId.Unknown, HtmlAttributeId.Scrolling), - new NameDef(180, "vlink", HtmlTagId.Unknown, HtmlAttributeId.Vlink), - new NameDef(181, "del", HtmlTagIndex.Del, false, false, HtmlTagId.Del, HtmlAttributeId.Unknown), - new NameDef(187, "hspace", HtmlTagId.Unknown, HtmlAttributeId.Hspace), - new NameDef(190, "charset", HtmlTagId.Unknown, HtmlAttributeId.Charset), - new NameDef(196, "rt", HtmlTagIndex.RT, false, false, HtmlTagId.RT, HtmlAttributeId.Unknown), - new NameDef(198, "italic", HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(201, "div", HtmlTagIndex.Div, false, false, HtmlTagId.Div, HtmlAttributeId.Unknown), - new NameDef(205, "dir", HtmlTagIndex.Dir, false, false, HtmlTagId.Dir, HtmlAttributeId.Dir), - new NameDef(206, "tt", HtmlTagIndex.TT, false, false, HtmlTagId.TT, HtmlAttributeId.Unknown), - new NameDef(206, "lowsrc", HtmlTagId.Unknown, HtmlAttributeId.LowSrc), - new NameDef(208, "h6", HtmlTagIndex.H6, false, false, HtmlTagId.H6, HtmlAttributeId.Unknown), - new NameDef(209, "valuetype", HtmlTagId.Unknown, HtmlAttributeId.ValueType), - new NameDef(210, "declare", HtmlTagId.Unknown, HtmlAttributeId.Declare), - new NameDef(212, "size", HtmlTagId.Unknown, HtmlAttributeId.Size), - new NameDef(214, "frameset", HtmlTagIndex.FrameSet, false, false, HtmlTagId.FrameSet, HtmlAttributeId.Unknown), - new NameDef(216, "readonly", HtmlTagId.Unknown, HtmlAttributeId.ReadOnly), - new NameDef(218, "language", HtmlTagId.Unknown, HtmlAttributeId.Language), - new NameDef(220, "area", HtmlTagIndex.Area, false, false, HtmlTagId.Area, HtmlAttributeId.Unknown), - new NameDef(220, "blockquote", HtmlTagIndex.BlockQuote, false, false, HtmlTagId.BlockQuote, HtmlAttributeId.Unknown), - new NameDef(222, "topmargin", HtmlTagId.Unknown, HtmlAttributeId.TopMargin), - new NameDef(223, "noembed", HtmlTagIndex.NoEmbed, false, false, HtmlTagId.NoEmbed, HtmlAttributeId.Unknown), - new NameDef(224, "basefont", HtmlTagIndex.BaseFont, false, false, HtmlTagId.BaseFont, HtmlAttributeId.Unknown), - new NameDef(229, "noframes", HtmlTagIndex.NoFrames, false, false, HtmlTagId.NoFrames, HtmlAttributeId.Unknown), - new NameDef(232, "border", HtmlTagId.Unknown, HtmlAttributeId.Border), - new NameDef(233, "center", HtmlTagIndex.Center, false, false, HtmlTagId.Center, HtmlAttributeId.Unknown), - new NameDef(237, "height", HtmlTagId.Unknown, HtmlAttributeId.Height), - new NameDef(240, "underline", HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(242, "flushboth", HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(244, "bgsound", HtmlTagIndex.BGSound, false, false, HtmlTagId.BGSound, HtmlAttributeId.Unknown), - new NameDef(249, "var", HtmlTagIndex.Var, false, false, HtmlTagId.Var, HtmlAttributeId.Unknown), - new NameDef(249, "start", HtmlTagId.Unknown, HtmlAttributeId.Start), - new NameDef(252, "td", HtmlTagIndex.TD, false, false, HtmlTagId.TD, HtmlAttributeId.Unknown), - new NameDef(253, "id", HtmlTagId.Unknown, HtmlAttributeId.Id), - new NameDef(254, "rows", HtmlTagId.Unknown, HtmlAttributeId.Rows), - new NameDef(255, "h4", HtmlTagIndex.H4, false, false, HtmlTagId.H4, HtmlAttributeId.Unknown), - new NameDef(257, "abbr", HtmlTagIndex.Abbr, false, false, HtmlTagId.Abbr, HtmlAttributeId.Abbr), - new NameDef(258, "http-equiv", HtmlTagId.Unknown, HtmlAttributeId.HttpEquiv), - new NameDef(259, "span", HtmlTagIndex.Span, false, false, HtmlTagId.Span, HtmlAttributeId.Span), - new NameDef(268, "dd", HtmlTagIndex.DD, false, false, HtmlTagId.DD, HtmlAttributeId.Unknown), - new NameDef(271, "address", HtmlTagIndex.Address, false, false, HtmlTagId.Address, HtmlAttributeId.Unknown), - new NameDef(273, "applet", HtmlTagIndex.Applet, false, false, HtmlTagId.Applet, HtmlAttributeId.Unknown), - new NameDef(274, "rel", HtmlTagId.Unknown, HtmlAttributeId.Rel), - new NameDef(278, "textarea", HtmlTagIndex.TextArea, true, false, HtmlTagId.TextArea, HtmlAttributeId.Unknown), - new NameDef(279, "tbody", HtmlTagIndex.Tbody, false, false, HtmlTagId.Tbody, HtmlAttributeId.Unknown), - new NameDef(283, "paraindent", HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(286, "dt", HtmlTagIndex.DT, false, false, HtmlTagId.DT, HtmlAttributeId.Unknown), - new NameDef(292, "checked", HtmlTagId.Unknown, HtmlAttributeId.Checked), - new NameDef(292, "nextid", HtmlTagIndex.NextId, false, false, HtmlTagId.NextId, HtmlAttributeId.Unknown), - new NameDef(293, "head", HtmlTagIndex.Head, false, false, HtmlTagId.Head, HtmlAttributeId.Unknown), - new NameDef(296, "rev", HtmlTagId.Unknown, HtmlAttributeId.Rev), - new NameDef(297, "small", HtmlTagIndex.Small, false, false, HtmlTagId.Small, HtmlAttributeId.Unknown), - new NameDef(299, "cite", HtmlTagIndex.Cite, false, false, HtmlTagId.Cite, HtmlAttributeId.Cite), - new NameDef(305, "cols", HtmlTagId.Unknown, HtmlAttributeId.Cols), - new NameDef(305, "longdesc", HtmlTagId.Unknown, HtmlAttributeId.LongDesc), - new NameDef(306, "sup", HtmlTagIndex.Sup, false, false, HtmlTagId.Sup, HtmlAttributeId.Unknown), - new NameDef(314, "fixed", HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(315, "prompt", HtmlTagId.Unknown, HtmlAttributeId.Prompt), - new NameDef(320, "disabled", HtmlTagId.Unknown, HtmlAttributeId.Disabled), - new NameDef(322, "name", HtmlTagId.Unknown, HtmlAttributeId.Name), - new NameDef(322, "coords", HtmlTagId.Unknown, HtmlAttributeId.Coords), - new NameDef(323, "summary", HtmlTagId.Unknown, HtmlAttributeId.Summary), - new NameDef(324, "object", HtmlTagIndex.Object, false, false, HtmlTagId.Object, HtmlAttributeId.Object), - new NameDef(331, "label", HtmlTagIndex.Label, false, false, HtmlTagId.Label, HtmlAttributeId.Label), - new NameDef(332, "content", HtmlTagId.Unknown, HtmlAttributeId.Content), - new NameDef(333, "target", HtmlTagId.Unknown, HtmlAttributeId.Target), - new NameDef(340, "em", HtmlTagIndex.EM, false, false, HtmlTagId.EM, HtmlAttributeId.Unknown), - new NameDef(344, "clear", HtmlTagId.Unknown, HtmlAttributeId.Clear), - new NameDef(354, "scope", HtmlTagId.Unknown, HtmlAttributeId.Scope), - new NameDef(356, "compact", HtmlTagId.Unknown, HtmlAttributeId.Compact), - new NameDef(358, "blink", HtmlTagIndex.Blink, false, false, HtmlTagId.Blink, HtmlAttributeId.Unknown), - new NameDef(372, "selected", HtmlTagId.Unknown, HtmlAttributeId.Selected), - new NameDef(374, "maxlength", HtmlTagId.Unknown, HtmlAttributeId.MaxLength), - new NameDef(380, "frame", HtmlTagIndex.Frame, false, false, HtmlTagId.Frame, HtmlAttributeId.Frame), - new NameDef(381, "thead", HtmlTagIndex.Thead, false, false, HtmlTagId.Thead, HtmlAttributeId.Unknown), - new NameDef(389, "tabindex", HtmlTagId.Unknown, HtmlAttributeId.TabIndex), - new NameDef(395, "?import", HtmlTagIndex._Import, false, false, HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(395, "marquee", HtmlTagIndex.Marquee, false, false, HtmlTagId.Marquee, HtmlAttributeId.Unknown), - new NameDef(405, "embed", HtmlTagIndex.Embed, false, false, HtmlTagId.Embed, HtmlAttributeId.Unknown), - new NameDef(406, "th", HtmlTagIndex.TH, false, false, HtmlTagId.TH, HtmlAttributeId.Unknown), - new NameDef(407, "caption", HtmlTagIndex.Caption, false, false, HtmlTagId.Caption, HtmlAttributeId.Unknown), - new NameDef(413, "value", HtmlTagId.Unknown, HtmlAttributeId.Value), - new NameDef(420, "smaller", HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(424, "datetime", HtmlTagId.Unknown, HtmlAttributeId.DateTime), - new NameDef(426, "classid", HtmlTagId.Unknown, HtmlAttributeId.ClassId), - new NameDef(432, "bold", HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(433, "strike", HtmlTagIndex.Strike, false, false, HtmlTagId.Strike, HtmlAttributeId.Unknown), - new NameDef(447, "flushleft", HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(448, "noshade", HtmlTagId.Unknown, HtmlAttributeId.NoShade), - new NameDef(449, "leftmargin", HtmlTagId.Unknown, HtmlAttributeId.LeftMargin), - new NameDef(450, "title", HtmlTagIndex.Title, true, false, HtmlTagId.Title, HtmlAttributeId.Title), - new NameDef(452, "excerpt", HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(454, "cellpadding", HtmlTagId.Unknown, HtmlAttributeId.CellPadding), - new NameDef(458, "dfn", HtmlTagIndex.Doofn, false, false, HtmlTagId.Doofn, HtmlAttributeId.Unknown), - new NameDef(459, "charoff", HtmlTagId.Unknown, HtmlAttributeId.CharOff), - new NameDef(461, "isindex", HtmlTagIndex.IsIndex, false, false, HtmlTagId.IsIndex, HtmlAttributeId.Unknown), - new NameDef(462, "tfoot", HtmlTagIndex.Tfoot, false, false, HtmlTagId.Tfoot, HtmlAttributeId.Unknown), - new NameDef(464, "nobr", HtmlTagIndex.NoBR, false, false, HtmlTagId.NoBR, HtmlAttributeId.Unknown), - new NameDef(470, "lang", HtmlTagId.Unknown, HtmlAttributeId.Lang), - new NameDef(472, "optgroup", HtmlTagIndex.OptGroup, false, false, HtmlTagId.OptGroup, HtmlAttributeId.Unknown), - new NameDef(474, "accept-charset", HtmlTagId.Unknown, HtmlAttributeId.AcceptCharset), - new NameDef(474, "option", HtmlTagIndex.Option, false, false, HtmlTagId.Option, HtmlAttributeId.Unknown), - new NameDef(476, "big", HtmlTagIndex.Big, false, false, HtmlTagId.Big, HtmlAttributeId.Unknown), - new NameDef(477, "font", HtmlTagIndex.Font, false, false, HtmlTagId.Font, HtmlAttributeId.Unknown), - new NameDef(479, "type", HtmlTagId.Unknown, HtmlAttributeId.Type), - new NameDef(482, "href", HtmlTagId.Unknown, HtmlAttributeId.Href), - new NameDef(484, "img", HtmlTagIndex.Img, false, false, HtmlTagId.Img, HtmlAttributeId.Unknown), - new NameDef(486, "vspace", HtmlTagId.Unknown, HtmlAttributeId.Vspace), - new NameDef(487, "h3", HtmlTagIndex.H3, false, false, HtmlTagId.H3, HtmlAttributeId.Unknown), - new NameDef(493, "align", HtmlTagId.Unknown, HtmlAttributeId.Align), - new NameDef(497, "wbr", HtmlTagIndex.Wbr, false, false, HtmlTagId.Wbr, HtmlAttributeId.Unknown), - new NameDef(499, "accesskey", HtmlTagId.Unknown, HtmlAttributeId.AccessKey), - new NameDef(502, "col", HtmlTagIndex.Col, false, false, HtmlTagId.Col, HtmlAttributeId.Unknown), - new NameDef(504, "menu", HtmlTagIndex.Menu, false, false, HtmlTagId.Menu, HtmlAttributeId.Unknown), - new NameDef(504, "bigger", HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(506, "codebase", HtmlTagId.Unknown, HtmlAttributeId.CodeBase), - new NameDef(508, "strong", HtmlTagIndex.Strong, false, false, HtmlTagId.Strong, HtmlAttributeId.Unknown), - new NameDef(510, "br", HtmlTagIndex.BR, false, false, HtmlTagId.BR, HtmlAttributeId.Unknown), - new NameDef(512, "archive", HtmlTagId.Unknown, HtmlAttributeId.Archive), - new NameDef(514, "ul", HtmlTagIndex.UL, false, false, HtmlTagId.UL, HtmlAttributeId.Unknown), - new NameDef(516, "noscript", HtmlTagIndex.NoScript, false, false, HtmlTagId.NoScript, HtmlAttributeId.Unknown), - new NameDef(517, "plaintext", HtmlTagIndex.PlainText, true, true, HtmlTagId.PlainText, HtmlAttributeId.Unknown), - new NameDef(521, "base", HtmlTagIndex.Base, false, false, HtmlTagId.Base, HtmlAttributeId.Unknown), - new NameDef(521, "ismap", HtmlTagId.Unknown, HtmlAttributeId.IsMap), - new NameDef(522, "defer", HtmlTagId.Unknown, HtmlAttributeId.Defer), - new NameDef(523, "body", HtmlTagIndex.Body, false, false, HtmlTagId.Body, HtmlAttributeId.Unknown), - new NameDef(524, "ol", HtmlTagIndex.OL, false, false, HtmlTagId.OL, HtmlAttributeId.Unknown), - new NameDef(526, "h1", HtmlTagIndex.H1, false, false, HtmlTagId.H1, HtmlAttributeId.Unknown), - new NameDef(528, "valign", HtmlTagId.Unknown, HtmlAttributeId.Valign), - new NameDef(531, "media", HtmlTagId.Unknown, HtmlAttributeId.Media), - new NameDef(532, "iframe", HtmlTagIndex.Iframe, false, false, HtmlTagId.Iframe, HtmlAttributeId.Unknown), - new NameDef(533, "dl", HtmlTagIndex.DL, false, false, HtmlTagId.DL, HtmlAttributeId.Unknown), - new NameDef(535, "colspan", HtmlTagId.Unknown, HtmlAttributeId.ColSpan), - new NameDef(538, "axis", HtmlTagId.Unknown, HtmlAttributeId.Axis), - new NameDef(542, "marginheight", HtmlTagId.Unknown, HtmlAttributeId.MarginHeight), - new NameDef(543, "alink", HtmlTagId.Unknown, HtmlAttributeId.Alink), - new NameDef(545, "?xml:namespace", HtmlTagIndex._Xml_Namespace, false, false, HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(546, "method", HtmlTagId.Unknown, HtmlAttributeId.Method), - new NameDef(549, "fontfamily", HtmlTagId.Unknown, HtmlAttributeId.Unknown), - new NameDef(554, "fieldset", HtmlTagIndex.FieldSet, false, false, HtmlTagId.FieldSet, HtmlAttributeId.Unknown), - new NameDef(556, "pre", HtmlTagIndex.Pre, false, false, HtmlTagId.Pre, HtmlAttributeId.Unknown), - new NameDef(557, "table", HtmlTagIndex.Table, false, false, HtmlTagId.Table, HtmlAttributeId.Unknown), - new NameDef(560, "tr", HtmlTagIndex.TR, false, false, HtmlTagId.TR, HtmlAttributeId.Unknown), - new NameDef(562, "samp", HtmlTagIndex.Samp, false, false, HtmlTagId.Samp, HtmlAttributeId.Unknown), - new NameDef(563, "link", HtmlTagIndex.Link, false, false, HtmlTagId.Link, HtmlAttributeId.Link), - new NameDef(564, "hr", HtmlTagIndex.HR, false, false, HtmlTagId.HR, HtmlAttributeId.Unknown), - new NameDef(568, "form", HtmlTagIndex.Form, false, false, HtmlTagId.Form, HtmlAttributeId.Unknown), - new NameDef(569, "input", HtmlTagIndex.Input, false, false, HtmlTagId.Input, HtmlAttributeId.Unknown), - new NameDef(570, "xml", HtmlTagIndex.Xml, true, true, HtmlTagId.Xml, HtmlAttributeId.Unknown), - new NameDef(572, "usemap", HtmlTagId.Unknown, HtmlAttributeId.UseMap), - new NameDef(574, "xmp", HtmlTagIndex.Xmp, true, true, HtmlTagId.Xmp, HtmlAttributeId.Unknown), - new NameDef(574, "html", HtmlTagIndex.Html, false, false, HtmlTagId.Html, HtmlAttributeId.Unknown), - new NameDef(575, "codetype", HtmlTagId.Unknown, HtmlAttributeId.CodeType), - new NameDef(580, "marginwidth", HtmlTagId.Unknown, HtmlAttributeId.MarginWidth), - new NameDef(584, "q", HtmlTagIndex.Q, false, false, HtmlTagId.Q, HtmlAttributeId.Unknown), - new NameDef(585, "colgroup", HtmlTagIndex.ColGroup, false, false, HtmlTagId.ColGroup, HtmlAttributeId.Unknown), - new NameDef(585, "dynsrc", HtmlTagId.Unknown, HtmlAttributeId.DynSrc), - new NameDef(586, "s", HtmlTagIndex.S, false, false, HtmlTagId.S, HtmlAttributeId.Unknown), - new NameDef(587, "p", HtmlTagIndex.P, false, false, HtmlTagId.P, HtmlAttributeId.Unknown), - new NameDef(588, "u", HtmlTagIndex.U, false, false, HtmlTagId.U, HtmlAttributeId.Unknown), - new NameDef(589, "action", HtmlTagId.Unknown, HtmlAttributeId.Action), - new NameDef(590, "enctype", HtmlTagId.Unknown, HtmlAttributeId.EncType), - new NameDef(592, "i", HtmlTagIndex.I, false, false, HtmlTagId.I, HtmlAttributeId.Unknown), - new NameDef(597, "b", HtmlTagIndex.B, false, false, HtmlTagId.B, HtmlAttributeId.Unknown), - new NameDef(598, "h5", HtmlTagIndex.H5, false, false, HtmlTagId.H5, HtmlAttributeId.Unknown), - new NameDef(599, "background", HtmlTagId.Unknown, HtmlAttributeId.Background), - new NameDef(600, null, HtmlTagId.Unknown, HtmlAttributeId.Unknown), - }; - - public static HtmlNameIndex[] tagIndex = - { - HtmlNameIndex.Unknown, - HtmlNameIndex.A, - HtmlNameIndex.Abbr, - HtmlNameIndex.Acronym, - HtmlNameIndex.Address, - HtmlNameIndex.Applet, - HtmlNameIndex.Area, - HtmlNameIndex.B, - HtmlNameIndex.Base, - HtmlNameIndex.BaseFont, - HtmlNameIndex.Bdo, - HtmlNameIndex.BGSound, - HtmlNameIndex.Big, - HtmlNameIndex.Blink, - HtmlNameIndex.BlockQuote, - HtmlNameIndex.Body, - HtmlNameIndex.BR, - HtmlNameIndex.Button, - HtmlNameIndex.Caption, - HtmlNameIndex.Center, - HtmlNameIndex.Cite, - HtmlNameIndex.Code, - HtmlNameIndex.Col, - HtmlNameIndex.ColGroup, - HtmlNameIndex.Comment, - HtmlNameIndex.DD, - HtmlNameIndex.Del, - HtmlNameIndex.Doofn, - HtmlNameIndex.Dir, - HtmlNameIndex.Div, - HtmlNameIndex.DL, - HtmlNameIndex.DT, - HtmlNameIndex.EM, - HtmlNameIndex.Embed, - HtmlNameIndex.FieldSet, - HtmlNameIndex.Font, - HtmlNameIndex.Form, - HtmlNameIndex.Frame, - HtmlNameIndex.FrameSet, - HtmlNameIndex.H1, - HtmlNameIndex.H2, - HtmlNameIndex.H3, - HtmlNameIndex.H4, - HtmlNameIndex.H5, - HtmlNameIndex.H6, - HtmlNameIndex.Head, - HtmlNameIndex.HR, - HtmlNameIndex.Html, - HtmlNameIndex.I, - HtmlNameIndex.Iframe, - HtmlNameIndex.Image, - HtmlNameIndex.Img, - HtmlNameIndex.Input, - HtmlNameIndex.Ins, - HtmlNameIndex.IsIndex, - HtmlNameIndex.Kbd, - HtmlNameIndex.Label, - HtmlNameIndex.Legend, - HtmlNameIndex.LI, - HtmlNameIndex.Link, - HtmlNameIndex.Listing, - HtmlNameIndex.Map, - HtmlNameIndex.Marquee, - HtmlNameIndex.Menu, - HtmlNameIndex.Meta, - HtmlNameIndex.NextId, - HtmlNameIndex.NoBR, - HtmlNameIndex.NoEmbed, - HtmlNameIndex.NoFrames, - HtmlNameIndex.NoScript, - HtmlNameIndex.Object, - HtmlNameIndex.OL, - HtmlNameIndex.OptGroup, - HtmlNameIndex.Option, - HtmlNameIndex.P, - HtmlNameIndex.Param, - HtmlNameIndex.PlainText, - HtmlNameIndex.Pre, - HtmlNameIndex.Q, - HtmlNameIndex.RP, - HtmlNameIndex.RT, - HtmlNameIndex.Ruby, - HtmlNameIndex.S, - HtmlNameIndex.Samp, - HtmlNameIndex.Script, - HtmlNameIndex.Select, - HtmlNameIndex.Small, - HtmlNameIndex.Span, - HtmlNameIndex.Strike, - HtmlNameIndex.Strong, - HtmlNameIndex.Style, - HtmlNameIndex.Sub, - HtmlNameIndex.Sup, - HtmlNameIndex.Table, - HtmlNameIndex.Tbody, - HtmlNameIndex.TD, - HtmlNameIndex.TextArea, - HtmlNameIndex.Tfoot, - HtmlNameIndex.TH, - HtmlNameIndex.Thead, - HtmlNameIndex.Title, - HtmlNameIndex.TR, - HtmlNameIndex.TT, - HtmlNameIndex.U, - HtmlNameIndex.UL, - HtmlNameIndex.Var, - HtmlNameIndex.Wbr, - HtmlNameIndex.Xml, - HtmlNameIndex.Xmp, - }; - - public static HtmlNameIndex[] attributeIndex = - { - HtmlNameIndex.Unknown, - HtmlNameIndex.Abbr, - HtmlNameIndex.Accept, - HtmlNameIndex.AcceptCharset, - HtmlNameIndex.AccessKey, - HtmlNameIndex.Action, - HtmlNameIndex.Align, - HtmlNameIndex.Alink, - HtmlNameIndex.Alt, - HtmlNameIndex.Archive, - HtmlNameIndex.Axis, - HtmlNameIndex.Background, - HtmlNameIndex.BGColor, - HtmlNameIndex.Border, - HtmlNameIndex.CellPadding, - HtmlNameIndex.CellSpacing, - HtmlNameIndex.Char, - HtmlNameIndex.CharOff, - HtmlNameIndex.Charset, - HtmlNameIndex.Checked, - HtmlNameIndex.Cite, - HtmlNameIndex.Class, - HtmlNameIndex.ClassId, - HtmlNameIndex.Clear, - HtmlNameIndex.Code, - HtmlNameIndex.CodeBase, - HtmlNameIndex.CodeType, - HtmlNameIndex.Color, - HtmlNameIndex.Cols, - HtmlNameIndex.ColSpan, - HtmlNameIndex.Compact, - HtmlNameIndex.Content, - HtmlNameIndex.Coords, - HtmlNameIndex.Data, - HtmlNameIndex.DateTime, - HtmlNameIndex.Declare, - HtmlNameIndex.Defer, - HtmlNameIndex.Dir, - HtmlNameIndex.Disabled, - HtmlNameIndex.DynSrc, - HtmlNameIndex.EncType, - HtmlNameIndex.Face, - HtmlNameIndex.For, - HtmlNameIndex.Frame, - HtmlNameIndex.FrameBorder, - HtmlNameIndex.Headers, - HtmlNameIndex.Height, - HtmlNameIndex.Href, - HtmlNameIndex.HrefLang, - HtmlNameIndex.Hspace, - HtmlNameIndex.HttpEquiv, - HtmlNameIndex.Id, - HtmlNameIndex.IsMap, - HtmlNameIndex.Label, - HtmlNameIndex.Lang, - HtmlNameIndex.Language, - HtmlNameIndex.LeftMargin, - HtmlNameIndex.Link, - HtmlNameIndex.LongDesc, - HtmlNameIndex.LowSrc, - HtmlNameIndex.MarginHeight, - HtmlNameIndex.MarginWidth, - HtmlNameIndex.MaxLength, - HtmlNameIndex.Media, - HtmlNameIndex.Method, - HtmlNameIndex.Multiple, - HtmlNameIndex.Name, - HtmlNameIndex.NoHref, - HtmlNameIndex.NoResize, - HtmlNameIndex.NoShade, - HtmlNameIndex.NoWrap, - HtmlNameIndex.Object, - HtmlNameIndex.Profile, - HtmlNameIndex.Prompt, - HtmlNameIndex.ReadOnly, - HtmlNameIndex.Rel, - HtmlNameIndex.Rev, - HtmlNameIndex.Rows, - HtmlNameIndex.RowSpan, - HtmlNameIndex.Rules, - HtmlNameIndex.Scheme, - HtmlNameIndex.Scope, - HtmlNameIndex.Scrolling, - HtmlNameIndex.Selected, - HtmlNameIndex.Shape, - HtmlNameIndex.Size, - HtmlNameIndex.Span, - HtmlNameIndex.Src, - HtmlNameIndex.StandBy, - HtmlNameIndex.Start, - HtmlNameIndex.Style, - HtmlNameIndex.Summary, - HtmlNameIndex.TabIndex, - HtmlNameIndex.Target, - HtmlNameIndex.Text, - HtmlNameIndex.Title, - HtmlNameIndex.TopMargin, - HtmlNameIndex.Type, - HtmlNameIndex.UseMap, - HtmlNameIndex.Valign, - HtmlNameIndex.Value, - HtmlNameIndex.ValueType, - HtmlNameIndex.Version, - HtmlNameIndex.Vlink, - HtmlNameIndex.Vspace, - HtmlNameIndex.Width, - }; - - public static EntityDef[] entities = - { - new EntityDef(0, 0, null), - new EntityDef(1, 969, "omega"), - new EntityDef(1, 8195, "emsp"), - new EntityDef(2, 8235, "rle"), - new EntityDef(5, 211, "Oacute"), - new EntityDef(8, 402, "fnof"), - new EntityDef(9, 216, "Oslash"), - new EntityDef(12, 209, "Ntilde"), - new EntityDef(14, 8592, "larr"), - new EntityDef(15, 968, "psi"), - new EntityDef(15, 34, "QUOT"), - new EntityDef(20, 928, "Pi"), - new EntityDef(22, 181, "micro"), - new EntityDef(24, 982, "piv"), - new EntityDef(26, 978, "upsih"), - new EntityDef(28, 926, "Xi"), - new EntityDef(28, 8968, "lceil"), - new EntityDef(29, 229, "aring"), - new EntityDef(30, 8715, "ni"), - new EntityDef(30, 175, "macr"), - new EntityDef(32, 8745, "cap"), - new EntityDef(33, 239, "iuml"), - new EntityDef(34, 967, "chi"), - new EntityDef(38, 188, "frac14"), - new EntityDef(40, 190, "frac34"), - new EntityDef(41, 186, "ordm"), - new EntityDef(41, 160, "nbsp"), - new EntityDef(44, 8743, "and"), - new EntityDef(47, 166, "brvbar"), - new EntityDef(49, 8203, "zwsp"), - new EntityDef(50, 8704, "forall"), - new EntityDef(52, 960, "pi"), - new EntityDef(53, 8855, "otimes"), - new EntityDef(54, 250, "uacute"), - new EntityDef(55, 8736, "ang"), - new EntityDef(56, 161, "iexcl"), - new EntityDef(57, 8206, "lrm"), - new EntityDef(57, 965, "upsilon"), - new EntityDef(60, 958, "xi"), - new EntityDef(65, 8234, "lre"), - new EntityDef(66, 8205, "zwj"), - new EntityDef(68, 925, "Nu"), - new EntityDef(69, 924, "Mu"), - new EntityDef(71, 8237, "lro"), - new EntityDef(73, 169, "COPY"), - new EntityDef(74, 8836, "nsub"), - new EntityDef(74, 8834, "sub"), - new EntityDef(83, 254, "thorn"), - new EntityDef(85, 8721, "sum"), - new EntityDef(87, 8217, "rsquo"), - new EntityDef(88, 183, "middot"), - new EntityDef(97, 202, "Ecirc"), - new EntityDef(97, 8240, "permil"), - new EntityDef(98, 8201, "thinsp"), - new EntityDef(100, 215, "times"), - new EntityDef(100, 957, "nu"), - new EntityDef(101, 956, "mu"), - new EntityDef(102, 165, "yen"), - new EntityDef(107, 8719, "prod"), - new EntityDef(116, 8659, "dArr"), - new EntityDef(118, 235, "euml"), - new EntityDef(118, 226, "acirc"), - new EntityDef(122, 914, "Beta"), - new EntityDef(123, 8730, "radic"), - new EntityDef(123, 189, "frac12"), - new EntityDef(130, 9829, "hearts"), - new EntityDef(131, 8482, "TRADE"), - new EntityDef(134, 8250, "rsaquo"), - new EntityDef(136, 196, "Auml"), - new EntityDef(137, 249, "ugrave"), - new EntityDef(142, 231, "ccedil"), - new EntityDef(143, 338, "OElig"), - new EntityDef(144, 167, "sect"), - new EntityDef(144, 201, "Eacute"), - new EntityDef(146, 8756, "there4"), - new EntityDef(148, 174, "REG"), - new EntityDef(155, 177, "plusmn"), - new EntityDef(155, 9001, "lang"), - new EntityDef(158, 977, "thetasym"), - new EntityDef(161, 8658, "rArr"), - new EntityDef(162, 953, "iota"), - new EntityDef(163, 8969, "rceil"), - new EntityDef(164, 8709, "empty"), - new EntityDef(164, 38, "AMP"), - new EntityDef(164, 62, "gt"), - new EntityDef(165, 934, "Phi"), - new EntityDef(166, 915, "Gamma"), - new EntityDef(167, 8299, "ass"), - new EntityDef(171, 60, "lt"), - new EntityDef(177, 918, "Zeta"), - new EntityDef(179, 210, "Ograve"), - new EntityDef(179, 176, "deg"), - new EntityDef(187, 9824, "spades"), - new EntityDef(193, 8204, "zwnj"), - new EntityDef(193, 8707, "exist"), - new EntityDef(196, 948, "delta"), - new EntityDef(200, 174, "reg"), - new EntityDef(203, 8712, "isin"), - new EntityDef(204, 913, "Alpha"), - new EntityDef(207, 376, "Yuml"), - new EntityDef(211, 184, "cedil"), - new EntityDef(211, 178, "sup2"), - new EntityDef(218, 8971, "rfloor"), - new EntityDef(220, 247, "divide"), - new EntityDef(222, 927, "Omicron"), - new EntityDef(225, 170, "ordf"), - new EntityDef(227, 9827, "clubs"), - new EntityDef(228, 220, "Uuml"), - new EntityDef(229, 919, "Eta"), - new EntityDef(231, 194, "Acirc"), - new EntityDef(232, 195, "Atilde"), - new EntityDef(233, 929, "Rho"), - new EntityDef(234, 8501, "alefsym"), - new EntityDef(240, 198, "AElig"), - new EntityDef(240, 8970, "lfloor"), - new EntityDef(248, 8660, "hArr"), - new EntityDef(250, 8254, "oline"), - new EntityDef(254, 193, "Aacute"), - new EntityDef(255, 199, "Ccedil"), - new EntityDef(256, 952, "theta"), - new EntityDef(257, 8744, "or"), - new EntityDef(258, 200, "Egrave"), - new EntityDef(259, 8482, "trade"), - new EntityDef(260, 8747, "int"), - new EntityDef(262, 185, "sup1"), - new EntityDef(263, 966, "phi"), - new EntityDef(265, 8746, "cup"), - new EntityDef(268, 8801, "equiv"), - new EntityDef(272, 8764, "sim"), - new EntityDef(273, 221, "Yacute"), - new EntityDef(276, 8243, "Prime"), - new EntityDef(277, 8593, "uarr"), - new EntityDef(280, 8212, "mdash"), - new EntityDef(280, 38, "amp"), - new EntityDef(281, 180, "acute"), - new EntityDef(285, 208, "ETH"), - new EntityDef(287, 233, "eacute"), - new EntityDef(290, 8472, "weierp"), - new EntityDef(292, 922, "Kappa"), - new EntityDef(294, 920, "Theta"), - new EntityDef(304, 163, "pound"), - new EntityDef(307, 8594, "rarr"), - new EntityDef(307, 937, "Omega"), - new EntityDef(312, 339, "oelig"), - new EntityDef(313, 8835, "sup"), - new EntityDef(314, 236, "igrave"), - new EntityDef(316, 162, "cent"), - new EntityDef(319, 224, "agrave"), - new EntityDef(321, 8224, "dagger"), - new EntityDef(328, 8226, "bull"), - new EntityDef(330, 214, "Ouml"), - new EntityDef(335, 197, "Aring"), - new EntityDef(338, 9674, "loz"), - new EntityDef(345, 8727, "lowast"), - new EntityDef(346, 245, "otilde"), - new EntityDef(351, 8364, "euro"), - new EntityDef(352, 168, "uml"), - new EntityDef(354, 963, "sigma"), - new EntityDef(373, 917, "Epsilon"), - new EntityDef(376, 8249, "lsaquo"), - new EntityDef(379, 8465, "image"), - new EntityDef(380, 8656, "lArr"), - new EntityDef(384, 207, "Iuml"), - new EntityDef(385, 935, "Chi"), - new EntityDef(390, 951, "eta"), - new EntityDef(394, 8596, "harr"), - new EntityDef(397, 225, "aacute"), - new EntityDef(399, 8302, "nads"), - new EntityDef(401, 240, "eth"), - new EntityDef(402, 62, "GT"), - new EntityDef(404, 931, "Sigma"), - new EntityDef(404, 222, "THORN"), - new EntityDef(408, 248, "oslash"), - new EntityDef(409, 230, "aelig"), - new EntityDef(409, 60, "LT"), - new EntityDef(411, 8713, "notin"), - new EntityDef(415, 8301, "aafs"), - new EntityDef(416, 253, "yacute"), - new EntityDef(427, 171, "laquo"), - new EntityDef(431, 8242, "prime"), - new EntityDef(431, 8298, "iss"), - new EntityDef(432, 192, "Agrave"), - new EntityDef(433, 955, "lambda"), - new EntityDef(436, 8853, "oplus"), - new EntityDef(442, 8476, "real"), - new EntityDef(443, 217, "Ugrave"), - new EntityDef(448, 8839, "supe"), - new EntityDef(450, 182, "para"), - new EntityDef(455, 8595, "darr"), - new EntityDef(466, 8838, "sube"), - new EntityDef(468, 8776, "asymp"), - new EntityDef(469, 203, "Euml"), - new EntityDef(470, 244, "ocirc"), - new EntityDef(471, 923, "Lambda"), - new EntityDef(476, 946, "beta"), - new EntityDef(477, 179, "sup3"), - new EntityDef(486, 8734, "infin"), - new EntityDef(487, 933, "Upsilon"), - new EntityDef(488, 251, "ucirc"), - new EntityDef(490, 916, "Delta"), - new EntityDef(490, 228, "auml"), - new EntityDef(506, 205, "Iacute"), - new EntityDef(506, 710, "circ"), - new EntityDef(513, 921, "Iota"), - new EntityDef(516, 732, "tilde"), - new EntityDef(517, 8222, "bdquo"), - new EntityDef(520, 353, "scaron"), - new EntityDef(529, 932, "Tau"), - new EntityDef(531, 950, "zeta"), - new EntityDef(533, 8236, "pdf"), - new EntityDef(537, 8869, "perp"), - new EntityDef(546, 173, "shy"), - new EntityDef(547, 238, "icirc"), - new EntityDef(561, 255, "yuml"), - new EntityDef(565, 947, "gamma"), - new EntityDef(567, 962, "sigmaf"), - new EntityDef(569, 9002, "rang"), - new EntityDef(572, 8629, "crarr"), - new EntityDef(575, 187, "raquo"), - new EntityDef(577, 8722, "minus"), - new EntityDef(578, 242, "ograve"), - new EntityDef(582, 252, "uuml"), - new EntityDef(583, 212, "Ocirc"), - new EntityDef(585, 8303, "nods"), - new EntityDef(586, 8220, "ldquo"), - new EntityDef(587, 961, "rho"), - new EntityDef(588, 223, "szlig"), - new EntityDef(601, 219, "Ucirc"), - new EntityDef(603, 945, "alpha"), - new EntityDef(606, 34, "quot"), - new EntityDef(615, 8225, "Dagger"), - new EntityDef(616, 218, "Uacute"), - new EntityDef(620, 204, "Igrave"), - new EntityDef(622, 936, "Psi"), - new EntityDef(627, 964, "tau"), - new EntityDef(628, 8216, "lsquo"), - new EntityDef(629, 8805, "ge"), - new EntityDef(631, 227, "atilde"), - new EntityDef(632, 8711, "nabla"), - new EntityDef(633, 352, "Scaron"), - new EntityDef(634, 8773, "cong"), - new EntityDef(635, 8260, "frasl"), - new EntityDef(638, 8800, "ne"), - new EntityDef(639, 164, "curren"), - new EntityDef(640, 8804, "le"), - new EntityDef(643, 8657, "uArr"), - new EntityDef(648, 949, "epsilon"), - new EntityDef(649, 237, "iacute"), - new EntityDef(651, 8207, "rlm"), - new EntityDef(652, 213, "Otilde"), - new EntityDef(653, 8901, "sdot"), - new EntityDef(653, 8238, "rlo"), - new EntityDef(654, 8211, "ndash"), - new EntityDef(657, 232, "egrave"), - new EntityDef(660, 206, "Icirc"), - new EntityDef(660, 243, "oacute"), - new EntityDef(662, 8706, "part"), - new EntityDef(663, 9830, "diams"), - new EntityDef(664, 169, "copy"), - new EntityDef(667, 241, "ntilde"), - new EntityDef(670, 8221, "rdquo"), - new EntityDef(671, 191, "iquest"), - new EntityDef(672, 8218, "sbquo"), - new EntityDef(678, 172, "not"), - new EntityDef(679, 8300, "iafs"), - new EntityDef(684, 246, "ouml"), - new EntityDef(689, 234, "ecirc"), - new EntityDef(691, 954, "kappa"), - new EntityDef(696, 8194, "ensp"), - new EntityDef(699, 8733, "prop"), - new EntityDef(702, 959, "omicron"), - new EntityDef(703, 8230, "hellip"), - new EntityDef(704, 0, null), - }; - - } - -} diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlNames.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlNames.cs deleted file mode 100644 index b502288fe..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlNames.cs +++ /dev/null @@ -1,343 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters -{ - -#pragma warning disable 1591 - - - - - - public enum HtmlTagId : byte - { - - - - - Unknown = 0, - - - A, - Abbr, - Acronym, - Address, - Applet, - Area, - B, - Base, - BaseFont, - Bdo, - BGSound, - Big, - Blink, - BlockQuote, - Body, - BR, - Button, - Caption, - Center, - Cite, - Code, - Col, - ColGroup, - Comment, - DD, - Del, - Doofn, - Dir, - Div, - DL, - DT, - EM, - Embed, - FieldSet, - Font, - Form, - Frame, - FrameSet, - H1, - H2, - H3, - H4, - H5, - H6, - Head, - HR, - Html, - I, - Iframe, - Image, - Img, - Input, - Ins, - IsIndex, - Kbd, - Label, - Legend, - LI, - Link, - Listing, - Map, - Marquee, - Menu, - Meta, - NextId, - NoBR, - NoEmbed, - NoFrames, - NoScript, - Object, - OL, - OptGroup, - Option, - P, - Param, - PlainText, - Pre, - Q, - RP, - RT, - Ruby, - S, - Samp, - Script, - Select, - Small, - Span, - Strike, - Strong, - Style, - Sub, - Sup, - Table, - Tbody, - TD, - TextArea, - Tfoot, - TH, - Thead, - Title, - TR, - TT, - U, - UL, - Var, - Wbr, - Xml, - Xmp, - - - - - - - } - - - - - - public enum HtmlAttributeId : byte - { - - - - - Unknown = 0, - - - Abbr, - Accept, - AcceptCharset, - AccessKey, - Action, - Align, - Alink, - Alt, - Archive, - Axis, - Background, - BGColor, - Border, - CellPadding, - CellSpacing, - Char, - CharOff, - Charset, - Checked, - Cite, - Class, - ClassId, - Clear, - Code, - CodeBase, - CodeType, - Color, - Cols, - ColSpan, - Compact, - Content, - Coords, - Data, - DateTime, - Declare, - Defer, - Dir, - Disabled, - DynSrc, - EncType, - Face, - For, - Frame, - FrameBorder, - Headers, - Height, - Href, - HrefLang, - Hspace, - HttpEquiv, - Id, - IsMap, - Label, - Lang, - Language, - LeftMargin, - Link, - LongDesc, - LowSrc, - MarginHeight, - MarginWidth, - MaxLength, - Media, - Method, - Multiple, - Name, - NoHref, - NoResize, - NoShade, - NoWrap, - Object, -#if false - OnAbort, - OnActivate, - OnAfterPrint, - OnAfterUpdate, - OnBeforeActivate, - OnBeforeCopy, - OnBeforeCut, - OnBeforeDeactivate, - OnBeforeEditFocus, - OnBeforePaste, - OnBeforeUnload, - OnBeforeUpdate, - OnBlur, - OnCellChange, - OnChange, - OnClick, - OnContextMenu, - OnControlSelect, - OnCopy, - OnCut, - OnDataAvailable, - OnDatasetChanged, - OnDatasetComplete, - OnDblClick, - OnDeactivate, - OnDrag, - OnDragEnd, - OnDragEnter, - OnDragLeave, - OnDragOver, - OnDragStart, - OnDrop, - OnError, - OnErrorUpdate, - OnFilterChange, - OnFocus, - OnFocusIn, - OnFocusOut, - OnHelp, - OnKeyDown, - OnKeyPress, - OnKeyUp, - OnLayoutComplete, - OnLoseCapture, - OnLoad, - OnMouseDown, - OnMouseEnter, - OnMouseLeave, - OnMouseMove, - OnMouseOut, - OnMouseOver, - OnMouseUp, - OnMouseWheel, - OnMove, - OnMoveEnd, - OnMoveStart, - OnPaste, - OnPropertyChange, - OnReadyStateChange, - OnResize, - OnResizeEnd, - OnResizeStart, - OnReset, - OnRowEnter, - OnRowExit, - OnRowsDelete, - OnRowsInserted, - OnScroll, - OnSelect, - OnSelectStart, - OnSubmit, - OnTimeError, - OnUnload, -#endif - Profile, - Prompt, - ReadOnly, - Rel, - Rev, - Rows, - RowSpan, - Rules, - Scheme, - Scope, - Scrolling, - Selected, - Shape, - Size, - Span, - Src, - StandBy, - Start, - Style, - Summary, - TabIndex, - Target, - Text, - Title, - TopMargin, - Type, - UseMap, - Valign, - Value, - ValueType, - Version, - Vlink, - Vspace, - Width, - - - } - - -#pragma warning restore 1591 -} diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlNormalizingParser.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlNormalizingParser.cs deleted file mode 100644 index ba3bb5b60..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlNormalizingParser.cs +++ /dev/null @@ -1,2217 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters.Internal.Html -{ - using System; - using System.IO; - using Data.Internal; - - using Strings = CtsResources.TextConvertersStrings; - - - internal class HtmlNormalizingParser : IHtmlParser, IRestartable, IReusable, IDisposable - { - - - private HtmlParser parser; - private IRestartable restartConsumer; - - private int maxElementStack; - - private Context context; - private Context[] contextStack; - private int contextStackTop; - - private HtmlTagIndex[] elementStack; - private int elementStackTop; - - private QueueItem[] queue; - private int queueHead; - private int queueTail; - - - private int queueStart; - - private bool ensureHead = true; - - - private int[] closeList; - private HtmlTagIndex[] openList; - - private bool validRTC; - private HtmlTagIndex tagIdRTC; - - - private HtmlToken token; - - - private HtmlToken inputToken; - private bool ignoreInputTag; - - - private int currentRun; - private int currentRunOffset; - private int numRuns; - - private bool allowWspLeft; - private bool allowWspRight; - - private SmallTokenBuilder tokenBuilder; - - - private HtmlInjection injection; - private DocumentState saveState; - - - public HtmlNormalizingParser( - HtmlParser parser, - HtmlInjection injection, - bool ensureHead, - int maxNesting, - bool testBoundaryConditions, - Stream traceStream, - bool traceShowTokenNum, - int traceStopOnTokenNum) - { - this.parser = parser; - this.parser.SetRestartConsumer(this); - - this.injection = injection; - if (injection != null) - { - saveState = new DocumentState(); - } - - this.ensureHead = ensureHead; - - var initialStackSize = testBoundaryConditions ? 1 : 32; - maxElementStack = testBoundaryConditions ? 30 : maxNesting; - - openList = new HtmlTagIndex[8]; - closeList = new int[8]; - - elementStack = new HtmlTagIndex[initialStackSize]; - - - contextStack = new Context[testBoundaryConditions ? 1 : 4]; - - - - - elementStack[elementStackTop++] = HtmlTagIndex._ROOT; - - - context.type = HtmlDtd.ContextType.Root; - context.textType = HtmlDtd.ContextTextType.Full; - - context.reject = HtmlDtd.SetId.Empty; - - - - - - - queue = new QueueItem[testBoundaryConditions ? 1 : initialStackSize / 4]; - - tokenBuilder = new SmallTokenBuilder(); - } - - - private void Reinitialize() - { - elementStackTop = 0; - - contextStackTop = 0; - - ignoreInputTag = false; - - elementStack[elementStackTop++] = HtmlTagIndex._ROOT; - - context.topElement = 0; - context.type = HtmlDtd.ContextType.Root; - context.textType = HtmlDtd.ContextTextType.Full; - context.accept = HtmlDtd.SetId.Null; - context.reject = HtmlDtd.SetId.Empty; - context.ignoreEnd = HtmlDtd.SetId.Null; - context.hasSpace = false; - context.eatSpace = false; - context.oneNL = false; - context.lastCh = '\0'; - - queueHead = 0; - queueTail = 0; - queueStart = 0; - - validRTC = false; - tagIdRTC = HtmlTagIndex._NULL; - - token = null; - - if (injection != null) - { - if (injection.Active) - { - parser = (HtmlParser) injection.Pop(); - } - - injection.Reset(); - } - } - - - private enum QueueItemKind : byte - { - Empty, - None, - Eof, - BeginElement, - EndElement, - OverlappedClose, - OverlappedReopen, - PassThrough, - Space, - Text, - Suspend, - InjectionBegin, - InjectionEnd, - - EndLastTag, - } - - - [Flags] - private enum QueueItemFlags : byte - { - AllowWspLeft = 0x01, - AllowWspRight = 0x02, - } - - - public HtmlToken Token => token; - - - public void SetRestartConsumer(IRestartable restartConsumer) - { - this.restartConsumer = restartConsumer; - } - - - public HtmlTokenId Parse() - { - while (true) - { - if (!QueueEmpty()) - { - return GetTokenFromQueue(); - } - - Process(parser.Parse()); - } - } - - - bool IRestartable.CanRestart() - { - return restartConsumer != null && restartConsumer.CanRestart(); - } - - - void IRestartable.Restart() - { - InternalDebug.Assert(((IRestartable)this).CanRestart()); - - if (restartConsumer != null) - { - restartConsumer.Restart(); - } - - Reinitialize(); - } - - - void IRestartable.DisableRestart() - { - if (restartConsumer != null) - { - restartConsumer.DisableRestart(); - } - } - - - void IReusable.Initialize(object newSourceOrDestination) - { - InternalDebug.Assert(parser is IReusable); - - ((IReusable)parser).Initialize(newSourceOrDestination); - - Reinitialize(); - - parser.SetRestartConsumer(this); - } - - - public void Initialize(string fragment, bool preformatedText) - { - parser.Initialize(fragment, preformatedText); - - Reinitialize(); - } - - - void IDisposable.Dispose() - { - if (parser != null /*&& this.parser is IDisposable*/) - { - ((IDisposable)parser).Dispose(); - } - - parser = null; - restartConsumer = null; - contextStack = null; - queue = null; - closeList = null; - openList = null; - token = null; - inputToken = null; - tokenBuilder = null; - - GC.SuppressFinalize(this); - } - - - private static HtmlDtd.TagDefinition GetTagDefinition(HtmlTagIndex tagIndex) - { - return HtmlDtd.tags[(int)tagIndex]; - } - - - private void Process(HtmlTokenId tokenId) - { - if (tokenId == HtmlTokenId.None) - { - InternalDebug.Assert(QueueEmpty()); - - EnqueueHead(QueueItemKind.None); - return; - } - - InternalDebug.Assert(queueHead == queueTail || queue[queueHead].kind != QueueItemKind.Suspend || tokenId == HtmlTokenId.Tag || tokenId == HtmlTokenId.EndOfFile); - - inputToken = parser.Token; - - switch (tokenId) - { - case HtmlTokenId.Restart: - - EnqueueTail(QueueItemKind.PassThrough); - break; - - case HtmlTokenId.EncodingChange: - - EnqueueTail(QueueItemKind.PassThrough); - break; - - case HtmlTokenId.EndOfFile: - - HandleTokenEof(); - break; - - case HtmlTokenId.Tag: - - InternalDebug.Assert(queue[queueHead].kind != QueueItemKind.Suspend || !inputToken.IsTagBegin); - - if (parser.Token.NameIndex < HtmlNameIndex.Unknown) - { - HandleTokenSpecialTag(parser.Token); - break; - } - - HandleTokenTag(parser.Token); - break; - - case HtmlTokenId.Text: - - HandleTokenText(parser.Token); - break; - - default: - - - InternalDebug.Assert(false, "unexpected HTML token"); - break; - } - } - - - private void HandleTokenEof() - { - - InternalDebug.Assert(QueueEmpty()); - - if (queueHead != queueTail && queue[queueHead].kind == QueueItemKind.Suspend) - { - - - - var qi = DoDequeueFirst(); - EnqueueHead( - QueueItemKind.EndLastTag, - qi.tagIndex, - 0 != (qi.flags & QueueItemFlags.AllowWspLeft), - 0 != (qi.flags & QueueItemFlags.AllowWspRight)); - return; - } - - if (injection != null && injection.Active) - { - - - - CloseAllContainers(saveState.SavedStackTop); - - if (queueHead != queueTail) - { - - return; - } - - - saveState.Restore(this); - EnqueueHead(QueueItemKind.InjectionEnd, injection.InjectingHead ? 1 : 0); - parser = (HtmlParser) injection.Pop(); - return; - } - - - - - - - - - - if (injection != null) - { - var bodyLevel = FindContainer(HtmlTagIndex.Body, HtmlDtd.SetId.Empty); - - if (bodyLevel == -1) - { - - - - - - - CloseAllProhibitedContainers(GetTagDefinition(HtmlTagIndex.Body)); - - OpenContainer(HtmlTagIndex.Body); - return; - } - - - CloseAllContainers(bodyLevel + 1); - - if (queueHead != queueTail) - { - - return; - } - - if (injection.HaveTail && !injection.TailDone) - { - - - parser = (HtmlParser) injection.Push(false, parser); - saveState.Save(this, elementStackTop); - EnqueueTail(QueueItemKind.InjectionBegin, 0); - if (injection.HeaderFooterFormat == HeaderFooterFormat.Text) - { - OpenContainer(HtmlTagIndex.TT); - OpenContainer(HtmlTagIndex.Pre); - } - return; - } - } - - - - CloseAllContainers(); - - - - EnqueueTail(QueueItemKind.Eof); - } - - - private void HandleTokenTag(HtmlToken tag) - { - HtmlTagIndex tagIndex; - - InternalDebug.Assert(HtmlNameIndex.Unknown <= tag.NameIndex && (int)tag.NameIndex < HtmlNameData.names.Length - 1); - - tagIndex = HtmlNameData.names[(int)tag.NameIndex].tagIndex; - - if (tag.IsTagBegin) - { - StartTagProcessing(tagIndex, tag); - } - else - { - - - if (!ignoreInputTag) - { - InternalDebug.Assert(QueueHeadKind() == QueueItemKind.Suspend); - - if (tag.IsTagEnd) - { - - - DoDequeueFirst(); - } - - if (inputToken.TagIndex != HtmlTagIndex.Unknown) - { - var emptyScope = (GetTagDefinition(tagIndex).scope == HtmlDtd.TagScope.EMPTY); - - - inputToken.Flags = emptyScope ? inputToken.Flags | HtmlToken.TagFlags.EmptyScope : inputToken.Flags & ~HtmlToken.TagFlags.EmptyScope; - } - - EnqueueHead(QueueItemKind.PassThrough); - } - else - { - if (tag.IsTagEnd) - { - ignoreInputTag = false; - } - } - } - } - - - private void HandleTokenSpecialTag(HtmlToken tag) - { - HtmlTagIndex tagIndex; - - InternalDebug.Assert(HtmlNameIndex._NOTANAME < tag.NameIndex && tag.NameIndex < HtmlNameIndex.Unknown); - - - tag.Flags = tag.Flags | HtmlToken.TagFlags.EmptyScope; - - tagIndex = HtmlNameData.names[(int)tag.NameIndex].tagIndex; - - if (tag.IsTagBegin) - { - StartSpecialTagProcessing(tagIndex, tag); - } - else - { - - - if (!ignoreInputTag) - { - InternalDebug.Assert(QueueHeadKind() == QueueItemKind.Suspend); - - if (tag.IsTagEnd) - { - - - DoDequeueFirst(); - } - - EnqueueHead(QueueItemKind.PassThrough); - } - else - { - if (tag.IsTagEnd) - { - ignoreInputTag = false; - } - } - } - } - - - private void HandleTokenText(HtmlToken token) - { - var tagIdRTC = validRTC ? this.tagIdRTC : RequiredTextContainer(); - - var cntWhitespaces = 0; - - var runs = inputToken.Runs; - - if (HtmlTagIndex._NULL != tagIdRTC) - { - - while (runs.MoveNext(true) && (runs.Current.TextType <= RunTextType.LastWhitespace)) - { - } - - if (!runs.IsValidPosition) - { - - return; - } - - CloseAllProhibitedContainers(GetTagDefinition(tagIdRTC)); - OpenContainer(tagIdRTC); - } - else if (context.textType != HtmlDtd.ContextTextType.Literal) - { - - - - while (runs.MoveNext(true) && (runs.Current.TextType <= RunTextType.LastWhitespace)) - { - - - cntWhitespaces += runs.Current.TextType == RunTextType.NewLine ? 1 : 2; - } - } - - if (context.textType == HtmlDtd.ContextTextType.Literal) - { - - - EnqueueTail(QueueItemKind.PassThrough); - } - else if (context.textType == HtmlDtd.ContextTextType.Full) - { - if (cntWhitespaces != 0) - { - - - AddSpace(cntWhitespaces == 1); - } - - currentRun = runs.CurrentIndex; - currentRunOffset = runs.CurrentOffset; - - if (runs.IsValidPosition) - { - var firstChar = runs.Current.FirstChar; - char lastChar; - do - { - lastChar = runs.Current.LastChar; - } - while (runs.MoveNext(true) && !(runs.Current.TextType <= RunTextType.LastWhitespace)); - - - AddNonspace(firstChar, lastChar); - } - - numRuns = runs.CurrentIndex - currentRun; - } - } - - - private void StartTagProcessing(HtmlTagIndex tagIndex, HtmlToken tag) - { - InternalDebug.Assert(!ignoreInputTag); - - if ((HtmlDtd.SetId.Null != context.reject && !HtmlDtd.IsTagInSet(tagIndex, context.reject)) || - (HtmlDtd.SetId.Null != context.accept && HtmlDtd.IsTagInSet(tagIndex, context.accept))) - { - if (!tag.IsEndTag) - { - if (!ProcessOpenTag(tagIndex, GetTagDefinition(tagIndex))) - { - ProcessIgnoredTag(tagIndex, tag); - } - } - else - { - if (HtmlDtd.SetId.Null == context.ignoreEnd || !HtmlDtd.IsTagInSet(tagIndex, context.ignoreEnd)) - { - if (!ProcessEndTag(tagIndex, GetTagDefinition(tagIndex))) - { - ProcessIgnoredTag(tagIndex, tag); - } - } - else - { - ProcessIgnoredTag(tagIndex, tag); - } - } - } - else if (context.type == HtmlDtd.ContextType.Select && tagIndex == HtmlTagIndex.Select) - { - if (!ProcessEndTag(tagIndex, GetTagDefinition(tagIndex))) - { - ProcessIgnoredTag(tagIndex, tag); - } - } - else - { - ProcessIgnoredTag(tagIndex, tag); - } - } - - - private void StartSpecialTagProcessing(HtmlTagIndex tagIndex, HtmlToken tag) - { - InternalDebug.Assert(!ignoreInputTag); - - EnqueueTail(QueueItemKind.PassThrough); - - if (!tag.IsTagEnd) - { - EnqueueTail(QueueItemKind.Suspend, tagIndex, allowWspLeft, allowWspRight); - } - } - - - private void ProcessIgnoredTag(HtmlTagIndex tagIndex, HtmlToken tag) - { - - - if (!tag.IsTagEnd) - { - ignoreInputTag = true; - } - } - - - private bool ProcessOpenTag(HtmlTagIndex tagIndex, HtmlDtd.TagDefinition tagDef) - { - if (!PrepareContainer(tagIndex, tagDef)) - { - return false; - } - - PushElement(tagIndex, true, tagDef); - return true; - } - - - private bool ProcessEndTag(HtmlTagIndex tagIndex, HtmlDtd.TagDefinition tagDef) - { - var elementStackPos = -1; - - - if (tagIndex == HtmlTagIndex.Unknown) - { - - - - - - - - - - PushElement(tagIndex, true, tagDef); - return true; - } - - - var useInputTag = true; - var inputTagUsed = false; - - if (HtmlDtd.SetId.Null != tagDef.match) - { - elementStackPos = FindContainer(tagDef.match, tagDef.endContainers); - - if (elementStackPos >= 0 && elementStack[elementStackPos] != tagIndex) - { - - - useInputTag = false; - } - } - else - { - elementStackPos = FindContainer(tagIndex, tagDef.endContainers); - } - - - - - - if (elementStackPos < 0) - { - - - var tagId2 = tagDef.unmatchedSubstitute; - if (tagId2 == HtmlTagIndex._NULL) - { - - return false; - } - - if (tagId2 == HtmlTagIndex._IMPLICIT_BEGIN) - { - - - if (!PrepareContainer(tagIndex, tagDef)) - { - return false; - } - - - - - - - - - inputToken.Flags &= ~HtmlToken.TagFlags.EndTag; - - elementStackPos = PushElement(tagIndex, useInputTag, tagDef); - - - inputTagUsed |= useInputTag; - - - useInputTag = false; - - - - } - else - { - - - elementStackPos = FindContainer(tagId2, GetTagDefinition(tagId2).endContainers); - if (elementStackPos < 0) - { - return false; - } - - - - useInputTag = false; - } - } - - - - if (elementStackPos >= 0 && elementStackPos < elementStackTop) - { - - useInputTag &= inputToken.IsEndTag; - - inputTagUsed |= useInputTag; - - CloseContainer(elementStackPos, useInputTag); - } - - - - return inputTagUsed; - } - - - private bool PrepareContainer(HtmlTagIndex tagIndex, HtmlDtd.TagDefinition tagDef) - { - - - if (tagIndex == HtmlTagIndex.Unknown) - { - - - - - - - return true; - } - - if (HtmlDtd.SetId.Null != tagDef.maskingContainers) - { - var elementStackPos = FindContainer(tagDef.maskingContainers, tagDef.beginContainers); - if (elementStackPos >= 0) - { - - return false; - } - } - - - - CloseAllProhibitedContainers(tagDef); - - - - var tagId2 = HtmlTagIndex._NULL; - - if (tagDef.textType == HtmlDtd.TagTextType.ALWAYS || - (tagDef.textType == HtmlDtd.TagTextType.QUERY && QueryTextlike(tagIndex))) - { - tagId2 = validRTC ? tagIdRTC : RequiredTextContainer(); - - if (HtmlTagIndex._NULL != tagId2) - { - CloseAllProhibitedContainers(GetTagDefinition(tagId2)); - if (-1 == OpenContainer(tagId2)) - { - return false; - } - } - } - - - - if (tagId2 == HtmlTagIndex._NULL) - { - if (HtmlDtd.SetId.Null != tagDef.requiredContainers) - { - var elementStackPos = FindContainer(tagDef.requiredContainers, tagDef.beginContainers); - if (elementStackPos < 0) - { - - - - - - CloseAllProhibitedContainers(GetTagDefinition(tagDef.defaultContainer)); - if (-1 == OpenContainer(tagDef.defaultContainer)) - { - return false; - } - } - } - } - - return true; - } - - - private int OpenContainer(HtmlTagIndex tagIndex) - { - var numTags = 0; - - while (HtmlTagIndex._NULL != tagIndex) - { - InternalDebug.Assert(numTags < openList.Length); - openList[numTags++] = tagIndex; - - var tagDef = GetTagDefinition(tagIndex); - - if (HtmlDtd.SetId.Null == tagDef.requiredContainers) - { - break; - } - - var elementStackPos = FindContainer(tagDef.requiredContainers, tagDef.beginContainers); - if (elementStackPos >= 0) - { - break; - } - - tagIndex = tagDef.defaultContainer; - } - - - if (HtmlTagIndex._NULL == tagIndex) - { - - return -1; - } - - var stackPos = -1; - - for (var i = numTags - 1; i >= 0; i--) - { - - - - - - tagIndex = openList[i]; - - stackPos = PushElement(tagIndex, false, GetTagDefinition(tagIndex)); - } - - return stackPos; - } - - - private void CloseContainer(int stackPos, bool useInputTag) - { - if (stackPos != elementStackTop - 1) - { - var closeNested = false; - - var numClose = 0; - - closeList[numClose++] = stackPos; - - if (GetTagDefinition(elementStack[stackPos]).scope == HtmlDtd.TagScope.NESTED) - { - closeNested = true; - } - - for (var i = stackPos + 1; i < elementStackTop; i++) - { - var tagDef = GetTagDefinition(elementStack[i]); - - if (numClose == closeList.Length) - { - - - var newCloseList = new int[closeList.Length * 2]; - Array.Copy(closeList, 0, newCloseList, 0, numClose); - closeList = newCloseList; - } - - if (closeNested && tagDef.scope == HtmlDtd.TagScope.NESTED) - { - closeList[numClose++] = i; - } - else - { - for (var j = 0; j < numClose; j++) - { - if (HtmlDtd.IsTagInSet(elementStack[closeList[j]], tagDef.endContainers)) - { - closeList[numClose++] = i; - - closeNested = closeNested || (tagDef.scope == HtmlDtd.TagScope.NESTED); - break; - } - } - } - } - - - - for (var j = numClose - 1; j > 0; j--) - { - - - PopElement(closeList[j], false); - } - } - - - - PopElement(stackPos, useInputTag); - } - - - private void CloseAllProhibitedContainers(HtmlDtd.TagDefinition tagDef) - { - var close = tagDef.prohibitedContainers; - - if (HtmlDtd.SetId.Null != close) - { - while (true) - { - var elementStackPos = FindContainer(close, tagDef.beginContainers); - if (elementStackPos < 0) - { - break; - } - - CloseContainer(elementStackPos, false); - } - } - } - - - private void CloseAllContainers() - { - for (var i = elementStackTop - 1; i > 0; i--) - { - CloseContainer(i, false); - } - } - - - private void CloseAllContainers(int level) - { - for (var i = elementStackTop - 1; i >= level; i--) - { - CloseContainer(i, false); - } - } - - - private int FindContainer(HtmlDtd.SetId matchSet, HtmlDtd.SetId stopSet) - { - - - - int i; - - for (i = elementStackTop - 1; i >= 0 && !HtmlDtd.IsTagInSet(elementStack[i], matchSet); i--) - { - if (HtmlDtd.IsTagInSet(elementStack[i], stopSet)) - { - return -1; - } - } - - return i; - } - - - private int FindContainer(HtmlTagIndex match, HtmlDtd.SetId stopSet) - { - int i; - - for (i = elementStackTop - 1; i >= 0 && elementStack[i] != match; i--) - { - if (HtmlDtd.IsTagInSet(elementStack[i], stopSet)) - { - return -1; - } - } - - return i; - } - - - private HtmlTagIndex RequiredTextContainer() - { - InternalDebug.Assert(!validRTC); - - validRTC = true; - - for (var i = elementStackTop - 1; i >= 0; i--) - { - var tagDef = GetTagDefinition(elementStack[i]); - - if (tagDef.textScope == HtmlDtd.TagTextScope.INCLUDE) - { - tagIdRTC = HtmlTagIndex._NULL; - return tagIdRTC; - } - - if (tagDef.textScope == HtmlDtd.TagTextScope.EXCLUDE) - { - tagIdRTC = tagDef.textSubcontainer; - return tagIdRTC; - } - } - - InternalDebug.Assert(false); - - tagIdRTC = HtmlTagIndex._NULL; - return tagIdRTC; - } - - - private int PushElement(HtmlTagIndex tagIndex, bool useInputTag, HtmlDtd.TagDefinition tagDef) - { - InternalDebug.Assert(!useInputTag || inputToken.IsTagBegin); - - int stackPos; - - if (ensureHead) - { - if (tagIndex == HtmlTagIndex.Body) - { - - stackPos = PushElement(HtmlTagIndex.Head, false, HtmlDtd.tags[(int)HtmlTagIndex.Head]); - PopElement(stackPos, false); - } - else if (tagIndex == HtmlTagIndex.Head) - { - - ensureHead = false; - } - } - - if (tagDef.textScope != HtmlDtd.TagTextScope.NEUTRAL) - { - validRTC = false; - } - - if (elementStackTop == elementStack.Length && !EnsureElementStackSpace()) - { - - - - throw new TextConvertersException(Strings.HtmlNestingTooDeep); - } - - var emptyScope = (tagDef.scope == HtmlDtd.TagScope.EMPTY); - - if (useInputTag) - { - if (inputToken.TagIndex != HtmlTagIndex.Unknown) - { - - inputToken.Flags = emptyScope ? inputToken.Flags | HtmlToken.TagFlags.EmptyScope : inputToken.Flags & ~HtmlToken.TagFlags.EmptyScope; - } - else - { - - - - - emptyScope = true; - } - } - - stackPos = elementStackTop ++; - - elementStack[stackPos] = tagIndex; - - LFillTagB(tagDef); - - EnqueueTail( - useInputTag ? QueueItemKind.PassThrough : QueueItemKind.BeginElement, - tagIndex, - allowWspLeft, - allowWspRight); - - if (useInputTag && !inputToken.IsTagEnd) - { - - EnqueueTail(QueueItemKind.Suspend, tagIndex, allowWspLeft, allowWspRight); - } - - RFillTagB(tagDef); - - - - - - if (!emptyScope) - { - - - if (tagDef.contextType != HtmlDtd.ContextType.None) - { - - - if (contextStackTop == contextStack.Length) - { - - - EnsureContextStackSpace(); - } - - contextStack[contextStackTop++] = context; - - - - context.topElement = stackPos; - context.type = tagDef.contextType; - context.textType = tagDef.contextTextType; - context.accept = tagDef.accept; - context.reject = tagDef.reject; - context.ignoreEnd = tagDef.ignoreEnd; - context.hasSpace = false; - context.eatSpace = false; - context.oneNL = false; - context.lastCh = '\0'; - - if (context.textType != HtmlDtd.ContextTextType.Full) - { - allowWspLeft = false; - allowWspRight = false; - } - - RFillTagB(tagDef); - } - } - else - { - - - - - - - - - - - - elementStackTop --; - } - - return stackPos; - } - - - private void PopElement(int stackPos, bool useInputTag) - { - InternalDebug.Assert(!useInputTag || inputToken.IsTagBegin); - - var tagIndex = elementStack[stackPos]; - var tagDef = GetTagDefinition(tagIndex); - - if (tagDef.textScope != HtmlDtd.TagTextScope.NEUTRAL) - { - validRTC = false; - } - - if (stackPos == context.topElement) - { - if (context.textType == HtmlDtd.ContextTextType.Full) - { - LFillTagE(tagDef); - } - - - context = contextStack[--contextStackTop]; - } - - LFillTagE(tagDef); - - if (stackPos != elementStackTop - 1) - { - - - - - InternalDebug.Assert(stackPos < elementStackTop - 1); - - EnqueueTail(QueueItemKind.OverlappedClose, elementStackTop - stackPos - 1); - } - - EnqueueTail( - useInputTag ? QueueItemKind.PassThrough : QueueItemKind.EndElement, - tagIndex, - allowWspLeft, - allowWspRight); - - if (useInputTag && !inputToken.IsTagEnd) - { - - EnqueueTail(QueueItemKind.Suspend, tagIndex, allowWspLeft, allowWspRight); - } - - RFillTagE(tagDef); - - - - if (stackPos != elementStackTop - 1) - { - - - - InternalDebug.Assert(stackPos < elementStackTop - 1); - - EnqueueTail(QueueItemKind.OverlappedReopen, elementStackTop - stackPos - 1); - - - Array.Copy(elementStack, stackPos + 1, elementStack, stackPos, elementStackTop - stackPos - 1); - - if (context.topElement > stackPos) - { - context.topElement --; - - for (var i = contextStackTop - 1; i > 0; i--) - { - InternalDebug.Assert(contextStack[i].topElement != stackPos); - - if (contextStack[i].topElement < stackPos) - { - break; - } - - contextStack[i].topElement --; - } - } - } - - elementStackTop --; - } - - - private void AddNonspace(char firstChar, char lastChar) - { - if (context.hasSpace) - { - context.hasSpace = false; - - - - if ('\0' == context.lastCh || !context.oneNL || !ParseSupport.TwoFarEastNonHanguelChars(context.lastCh, firstChar)) - { - EnqueueTail(QueueItemKind.Space); - } - } - - EnqueueTail(QueueItemKind.Text); - - context.eatSpace = false; - context.lastCh = lastChar; - context.oneNL = false; - } - - - private void AddSpace(bool oneNL) - { - InternalDebug.Assert(context.textType == HtmlDtd.ContextTextType.Full); - - if (!context.eatSpace) - { - context.hasSpace = true; - } - - if (context.lastCh != '\0') - { - if (oneNL && !context.oneNL) - { - context.oneNL = true; - } - else - { - context.lastCh = '\0'; - } - } - } - - - private bool QueryTextlike(HtmlTagIndex tagIndex) - { - - - - var contextType = context.type; - var i = contextStackTop; - - while (i != 0) - { - switch (contextType) - { - case HtmlDtd.ContextType.Head: - - if (tagIndex == HtmlTagIndex.Object) - { - return false; - } - - - break; - - case HtmlDtd.ContextType.Body: - - switch (tagIndex) - { - case HtmlTagIndex.Input: - case HtmlTagIndex.Object: - case HtmlTagIndex.Applet: - case HtmlTagIndex.A: - case HtmlTagIndex.Div: - case HtmlTagIndex.Span: - return true; - } - - return false; - } - - contextType = contextStack[--i].type; - } - - - - InternalDebug.Assert(contextType == HtmlDtd.ContextType.Root); - - if (tagIndex == HtmlTagIndex.Object || tagIndex == HtmlTagIndex.Applet) - { - return true; - } - - return false; - } - - - - - private void LFillTagB(HtmlDtd.TagDefinition tagDef) - { - if (context.textType == HtmlDtd.ContextTextType.Full) - { - LFill(FillCodeFromTag(tagDef).LB, FillCodeFromTag(tagDef).RB); - } - } - - - private void RFillTagB(HtmlDtd.TagDefinition tagDef) - { - if (context.textType == HtmlDtd.ContextTextType.Full) - { - RFill(FillCodeFromTag(tagDef).RB); - } - } - - - private void LFillTagE(HtmlDtd.TagDefinition tagDef) - { - if (context.textType == HtmlDtd.ContextTextType.Full) - { - LFill(FillCodeFromTag(tagDef).LE, FillCodeFromTag(tagDef).RE); - } - } - - - private void RFillTagE(HtmlDtd.TagDefinition tagDef) - { - if (context.textType == HtmlDtd.ContextTextType.Full) - { - RFill(FillCodeFromTag(tagDef).RE); - } - } - - - private void LFill(HtmlDtd.FillCode codeLeft, HtmlDtd.FillCode codeRight) - { - InternalDebug.Assert(context.textType == HtmlDtd.ContextTextType.Full); - - - - allowWspLeft = context.hasSpace || codeLeft == HtmlDtd.FillCode.EAT; - - context.lastCh = '\0'; - - if (context.hasSpace) - { - if (codeLeft == HtmlDtd.FillCode.PUT) - { - EnqueueTail(QueueItemKind.Space); - context.eatSpace = true; - } - - context.hasSpace = (codeLeft == HtmlDtd.FillCode.NUL); - } - - allowWspRight = context.hasSpace || codeRight == HtmlDtd.FillCode.EAT; - } - - - private void RFill(HtmlDtd.FillCode code) - { - InternalDebug.Assert(context.textType == HtmlDtd.ContextTextType.Full); - - if (code == HtmlDtd.FillCode.EAT) - { - context.hasSpace = false; - context.eatSpace = true; - } - else if (code == HtmlDtd.FillCode.PUT) - { - context.eatSpace = false; - } - } - - - private bool QueueEmpty() - { - return (queueHead == queueTail || queue[queueHead].kind == QueueItemKind.Suspend); - } - - - private QueueItemKind QueueHeadKind() - { - if (queueHead == queueTail) - { - return QueueItemKind.Empty; - } - - return queue[queueHead].kind; - } - - - private void EnqueueTail(QueueItemKind kind, HtmlTagIndex tagIndex, bool allowWspLeft, bool allowWspRight) - { - if (queueTail == queue.Length) - { - ExpandQueue(); - } - - queue[queueTail].kind = kind; - queue[queueTail].tagIndex = tagIndex; - queue[queueTail].flags = (allowWspLeft ? QueueItemFlags.AllowWspLeft : 0) | - (allowWspRight ? QueueItemFlags.AllowWspRight : 0); - queue[queueTail].argument = 0; - - queueTail ++; - } - - - private void EnqueueTail(QueueItemKind kind, int argument) - { - if (queueTail == queue.Length) - { - ExpandQueue(); - } - - queue[queueTail].kind = kind; - queue[queueTail].tagIndex = HtmlTagIndex._NULL; - queue[queueTail].flags = 0; - queue[queueTail].argument = argument; - - queueTail ++; - } - - - private void EnqueueTail(QueueItemKind kind) - { - if (queueTail == queue.Length) - { - ExpandQueue(); - } - - queue[queueTail].kind = kind; - queue[queueTail].tagIndex = HtmlTagIndex._NULL; - queue[queueTail].flags = 0; - queue[queueTail].argument = 0; - - queueTail ++; - } - - - private void EnqueueHead(QueueItemKind kind, HtmlTagIndex tagIndex, bool allowWspLeft, bool allowWspRight) - { - - - if (queueHead != queueStart) - { - queueHead --; - } - else - { - - InternalDebug.Assert(queueHead == queueTail); - queueTail ++; - } - - queue[queueHead].kind = kind; - queue[queueHead].tagIndex = tagIndex; - queue[queueHead].flags = (allowWspLeft ? QueueItemFlags.AllowWspLeft : 0) | - (allowWspRight ? QueueItemFlags.AllowWspRight : 0); - queue[queueHead].argument = 0; - } - - - private void EnqueueHead(QueueItemKind kind) - { - EnqueueHead(kind, 0); - } - - - private void EnqueueHead(QueueItemKind kind, int argument) - { - - - if (queueHead != queueStart) - { - queueHead --; - } - else - { - - InternalDebug.Assert(queueHead == queueTail); - queueTail ++; - } - - queue[queueHead].kind = kind; - queue[queueHead].tagIndex = HtmlTagIndex._NULL; - queue[queueHead].flags = 0; - queue[queueHead].argument = argument; - } - - - private HtmlTokenId GetTokenFromQueue() - { - QueueItem qi; - - switch (QueueHeadKind()) - { - case QueueItemKind.None: - - - - DoDequeueFirst(); - - token = null; - - return HtmlTokenId.None; - - case QueueItemKind.PassThrough: - - - - qi = DoDequeueFirst(); - - token = inputToken; - - if (token.TokenId == HtmlTokenId.Tag) - { - - - token.Flags |= (((qi.flags & QueueItemFlags.AllowWspLeft) == QueueItemFlags.AllowWspLeft) ? - HtmlToken.TagFlags.AllowWspLeft : 0) | - (((qi.flags & QueueItemFlags.AllowWspRight) == QueueItemFlags.AllowWspRight) ? - HtmlToken.TagFlags.AllowWspRight : 0); - - if (token.OriginalTagId == HtmlTagIndex.Body && - token.IsTagEnd && - injection != null && - injection.HaveHead && - !injection.HeadDone) - { - - InternalDebug.Assert(token.IsEndTag == false); - - - - - var bodyLevel = FindContainer(HtmlTagIndex.Body, HtmlDtd.SetId.Empty); - - parser = (HtmlParser) injection.Push(true, parser); - saveState.Save(this, bodyLevel + 1); - EnqueueTail(QueueItemKind.InjectionBegin, 1); - if (injection.HeaderFooterFormat == HeaderFooterFormat.Text) - { - OpenContainer(HtmlTagIndex.TT); - OpenContainer(HtmlTagIndex.Pre); - } - } - } - - return token.TokenId; - - case QueueItemKind.BeginElement: - case QueueItemKind.EndElement: - - - - qi = DoDequeueFirst(); - - tokenBuilder.BuildTagToken( - qi.tagIndex, - qi.kind == QueueItemKind.EndElement, - (qi.flags & QueueItemFlags.AllowWspLeft) == QueueItemFlags.AllowWspLeft, - (qi.flags & QueueItemFlags.AllowWspRight) == QueueItemFlags.AllowWspRight, - false); - - token = tokenBuilder; - - if (qi.kind == QueueItemKind.BeginElement && - token.OriginalTagId == HtmlTagIndex.Body && - injection != null && - injection.HaveHead && - !injection.HeadDone) - { - - InternalDebug.Assert(token.IsEndTag == false); - - - - - var bodyLevel = FindContainer(HtmlTagIndex.Body, HtmlDtd.SetId.Empty); - - parser = (HtmlParser) injection.Push(true, parser); - saveState.Save(this, bodyLevel + 1); - EnqueueTail(QueueItemKind.InjectionBegin, 1); - if (injection.HeaderFooterFormat == HeaderFooterFormat.Text) - { - OpenContainer(HtmlTagIndex.TT); - OpenContainer(HtmlTagIndex.Pre); - } - } - - - return token.TokenId; - - case QueueItemKind.EndLastTag: - - qi = DoDequeueFirst(); - - tokenBuilder.BuildTagToken( - qi.tagIndex, - false, - (qi.flags & QueueItemFlags.AllowWspLeft) == QueueItemFlags.AllowWspLeft, - (qi.flags & QueueItemFlags.AllowWspRight) == QueueItemFlags.AllowWspRight, - true); - - token = tokenBuilder; - - if (qi.kind == QueueItemKind.BeginElement && - token.OriginalTagId == HtmlTagIndex.Body && - injection != null && - injection.HaveHead && - !injection.HeadDone) - { - - InternalDebug.Assert(token.IsEndTag == false); - - - - - var bodyLevel = FindContainer(HtmlTagIndex.Body, HtmlDtd.SetId.Empty); - - parser = (HtmlParser) injection.Push(true, parser); - saveState.Save(this, bodyLevel + 1); - EnqueueTail(QueueItemKind.InjectionBegin, 1); - if (injection.HeaderFooterFormat == HeaderFooterFormat.Text) - { - OpenContainer(HtmlTagIndex.TT); - OpenContainer(HtmlTagIndex.Pre); - } - } - - - return token.TokenId; - - case QueueItemKind.OverlappedClose: - case QueueItemKind.OverlappedReopen: - - - - qi = DoDequeueFirst(); - - tokenBuilder.BuildOverlappedToken(qi.kind == QueueItemKind.OverlappedClose, qi.argument); - - token = tokenBuilder; - - - return token.TokenId; - - case QueueItemKind.Space: - - - - qi = DoDequeueFirst(); - - tokenBuilder.BuildSpaceToken(); - - token = tokenBuilder; - - - return token.TokenId; - - case QueueItemKind.Text: - - - - - var requeueInjectionEnd = false; - var requeueInjectionArgument = 0; - - InternalDebug.Assert(context.textType == HtmlDtd.ContextTextType.Full); - - - qi = DoDequeueFirst(); - - if (queueHead != queueTail) - { - InternalDebug.Assert(queueHead == queueTail - 1 && QueueHeadKind() == QueueItemKind.InjectionEnd); - requeueInjectionEnd = true; - requeueInjectionArgument = queue[queueHead].argument; - DoDequeueFirst(); - } - - - - - tokenBuilder.BuildTextSliceToken(inputToken, currentRun, currentRunOffset, numRuns); - - token = tokenBuilder; - - var runs = inputToken.Runs; - - if (runs.IsValidPosition) - { - var cnt = 0; - - InternalDebug.Assert(runs.Current.TextType <= RunTextType.LastWhitespace); - - - - do - { - - - cnt += runs.Current.TextType == RunTextType.NewLine ? 1 : 2; - } - while (runs.MoveNext(true) && (runs.Current.TextType <= RunTextType.LastWhitespace)); - - if (cnt != 0) - { - - - AddSpace(cnt == 1); - } - - currentRun = runs.CurrentIndex; - currentRunOffset = runs.CurrentOffset; - - if (runs.IsValidPosition) - { - var firstChar = runs.Current.FirstChar; - var lastChar = firstChar; - do - { - lastChar = runs.Current.LastChar; - } - while (runs.MoveNext(true) && !(runs.Current.TextType <= RunTextType.LastWhitespace)); - - - AddNonspace(firstChar, lastChar); - } - - numRuns = runs.CurrentIndex - currentRun; - } - else - { - currentRun = runs.CurrentIndex; - currentRunOffset = runs.CurrentOffset; - numRuns = 0; - } - - if (requeueInjectionEnd) - { - EnqueueTail(QueueItemKind.InjectionEnd, requeueInjectionArgument); - } - - - return token.TokenId; - - case QueueItemKind.Eof: - - - - - InternalDebug.Assert(queueHead + 1 == queueTail); - - tokenBuilder.BuildEofToken(); - - token = tokenBuilder; - - break; - - case QueueItemKind.InjectionBegin: - case QueueItemKind.InjectionEnd: - - - - qi = DoDequeueFirst(); - - tokenBuilder.BuildInjectionToken(qi.kind == QueueItemKind.InjectionBegin, qi.argument != 0); - - token = tokenBuilder; - - break; - - default: - - InternalDebug.Assert(false); - break; - } - - - return token.TokenId; - } - - - private void ExpandQueue() - { - - - - var newQueue = new QueueItem[queue.Length * 2]; - Array.Copy(queue, queueHead, newQueue, queueHead, queueTail - queueHead); - if (queueStart != 0) - { - Array.Copy(queue, 0, newQueue, 0, queueStart); - } - queue = newQueue; - newQueue = null; - } - - - private QueueItem DoDequeueFirst() - { - var head = queueHead; - - queueHead ++; - - if (queueHead == queueTail) - { - queueHead = queueTail = queueStart; - } - - return queue[head]; - } - - - private HtmlDtd.TagFill FillCodeFromTag(HtmlDtd.TagDefinition tagDef) - { - if (context.type == HtmlDtd.ContextType.Select && tagDef.tagIndex != HtmlTagIndex.Option) - { - return HtmlDtd.TagFill.PUT_PUT_PUT_PUT; - } - else if (context.type == HtmlDtd.ContextType.Title) - { - InternalDebug.Assert(tagDef.tagIndex == HtmlTagIndex.Title); - return HtmlDtd.TagFill.NUL_EAT_EAT_NUL; - } - - return tagDef.fill; - } - - - private bool EnsureElementStackSpace() - { - if (elementStackTop == elementStack.Length) - { - if (elementStack.Length >= maxElementStack) - { - return false; - } - - var newSize = (maxElementStack / 2 > elementStack.Length) ? elementStack.Length * 2 : maxElementStack; - - var newElementStack = new HtmlTagIndex[newSize]; - Array.Copy(elementStack, 0, newElementStack, 0, elementStackTop); - elementStack = newElementStack; - newElementStack = null; - } - - return true; - } - - - private void EnsureContextStackSpace() - { - if (contextStackTop + 1 > contextStack.Length) - { - - - var newContextStack = new Context[contextStack.Length * 2]; - Array.Copy(contextStack, 0, newContextStack, 0, contextStackTop); - contextStack = newContextStack; - newContextStack = null; - } - } - - - private struct Context - { - public int topElement; - - - public HtmlDtd.ContextType type; - public HtmlDtd.ContextTextType textType; - public HtmlDtd.SetId accept; - public HtmlDtd.SetId reject; - public HtmlDtd.SetId ignoreEnd; - - - public char lastCh; - public bool oneNL; - public bool hasSpace; - public bool eatSpace; - } - - - private struct QueueItem - { - public QueueItemKind kind; - public HtmlTagIndex tagIndex; - public QueueItemFlags flags; - public int argument; - } - - - - - private class DocumentState - { - private int queueHead; - private int queueTail; - private HtmlToken inputToken; - private int elementStackTop; - private int currentRun; - private int currentRunOffset; - private int numRuns; - private HtmlTagIndex[] savedElementStackEntries = new HtmlTagIndex[5]; - private int savedElementStackEntriesCount; - private bool hasSpace; - private bool eatSpace; - private bool validRTC; - private HtmlTagIndex tagIdRTC; - - public DocumentState() - { - } - - public int SavedStackTop => elementStackTop; - - public void Save(HtmlNormalizingParser document, int stackLevel) - { - if (stackLevel != document.elementStackTop) - { - - InternalDebug.Assert(stackLevel < document.elementStackTop && document.elementStackTop - stackLevel < 5); - - Array.Copy(document.elementStack, stackLevel, savedElementStackEntries, 0, document.elementStackTop - stackLevel); - savedElementStackEntriesCount = document.elementStackTop - stackLevel; - document.elementStackTop = stackLevel; - } - else - { - savedElementStackEntriesCount = 0; - } - - elementStackTop = document.elementStackTop; - queueHead = document.queueHead; - queueTail = document.queueTail; - inputToken = document.inputToken; - currentRun = document.currentRun; - currentRunOffset = document.currentRunOffset; - numRuns = document.numRuns; - hasSpace = document.context.hasSpace; - eatSpace = document.context.eatSpace; - validRTC = document.validRTC; - tagIdRTC = document.tagIdRTC; - - - document.queueStart = document.queueTail; - document.queueHead = document.queueTail = document.queueStart; - } - - public void Restore(HtmlNormalizingParser document) - { - InternalDebug.Assert(document.elementStackTop == elementStackTop); - - if (savedElementStackEntriesCount != 0) - { - Array.Copy(savedElementStackEntries, 0, document.elementStack, document.elementStackTop, savedElementStackEntriesCount); - document.elementStackTop += savedElementStackEntriesCount; - } - - document.queueStart = 0; - document.queueHead = queueHead; - document.queueTail = queueTail; - - document.inputToken = inputToken; - document.currentRun = currentRun; - document.currentRunOffset = currentRunOffset; - document.numRuns = numRuns; - document.context.hasSpace = hasSpace; - document.context.eatSpace = eatSpace; - document.validRTC = validRTC; - document.tagIdRTC = tagIdRTC; - } - } - - - private class SmallTokenBuilder : HtmlToken - { - private char[] spareBuffer = new char[1]; - private RunEntry[] spareRuns = new RunEntry[1]; - - public SmallTokenBuilder() - { - } - - public void BuildTagToken(HtmlTagIndex tagIndex, bool closingTag, bool allowWspLeft, bool allowWspRight, bool endOnly) - { - tokenId = (TokenId)HtmlTokenId.Tag; - argument = 1; - - buffer = spareBuffer; - runList = spareRuns; - whole.Reset(); - wholePosition.Rewind(whole); - - this.tagIndex = originalTagIndex = tagIndex; - nameIndex = HtmlDtd.tags[(int)tagIndex].nameIndex; - - if (!endOnly) - { - partMajor = TagPartMajor.Complete; - partMinor = TagPartMinor.CompleteName; - } - else - { - partMajor = TagPartMajor.End; - partMinor = TagPartMinor.Empty; - } - - flags = (closingTag ? TagFlags.EndTag : 0) | - (allowWspLeft ? TagFlags.AllowWspLeft : 0) | - (allowWspRight ? TagFlags.AllowWspRight : 0); - } - - public void BuildOverlappedToken(bool close, int argument) - { - tokenId = (TokenId)(close ? HtmlTokenId.OverlappedClose : HtmlTokenId.OverlappedReopen); - this.argument = argument; - - buffer = spareBuffer; - runList = spareRuns; - whole.Reset(); - wholePosition.Rewind(whole); - } - - public void BuildInjectionToken(bool begin, bool head) - { - tokenId = (TokenId)(begin ? HtmlTokenId.InjectionBegin : HtmlTokenId.InjectionEnd); - argument = head ? 1 : 0; - - buffer = spareBuffer; - runList = spareRuns; - whole.Reset(); - wholePosition.Rewind(whole); - } - - public void BuildSpaceToken() - { - tokenId = (TokenId)HtmlTokenId.Text; - argument = 1; - - buffer = spareBuffer; - runList = spareRuns; - - buffer[0] = ' '; - runList[0].Initialize(RunType.Normal, RunTextType.Space, (uint)HtmlRunKind.Text, 1, 0); - - whole.Reset(); - whole.tail = 1; - wholePosition.Rewind(whole); - } - - public void BuildTextSliceToken(Token source, int startRun, int startRunOffset, int numRuns) - { - InternalDebug.Assert(numRuns > 0); - InternalDebug.Assert(startRun >= source.whole.head && startRun < source.whole.tail); - InternalDebug.Assert(startRun + numRuns <= source.whole.tail); - InternalDebug.Assert(startRunOffset >= source.whole.headOffset && startRunOffset < source.buffer.Length); - - tokenId = (TokenId)HtmlTokenId.Text; - argument = 0; - - buffer = source.buffer; - runList = source.runList; - - whole.Initialize(startRun, startRunOffset); - whole.tail = whole.head + numRuns; - wholePosition.Rewind(whole); - } - - public void BuildEofToken() - { - tokenId = (TokenId)HtmlTokenId.EndOfFile; - argument = 0; - - buffer = spareBuffer; - runList = spareRuns; - whole.Reset(); - wholePosition.Rewind(whole); - } - } - } -} - diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlParser.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlParser.cs deleted file mode 100644 index d1796d37e..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlParser.cs +++ /dev/null @@ -1,3685 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters.Internal.Html -{ - using System; - using System.Text; - using Data.Internal; - using Globalization; - - - internal interface IHtmlParser - { - - - HtmlToken Token { get; } - - HtmlTokenId Parse(); - void SetRestartConsumer(IRestartable restartConsumer); - } - - - - internal class HtmlParser : IHtmlParser, IRestartable, IReusable, IDisposable - { - - - #pragma warning disable 0429 - private const int ParseThresholdMax = (HtmlNameData.MAX_ENTITY_NAME > HtmlNameData.MAX_NAME ? HtmlNameData.MAX_ENTITY_NAME : HtmlNameData.MAX_NAME) + 2; - #pragma warning restore 0429 - - private ConverterInput input; - private bool endOfFile; - - - private bool literalTags; - private HtmlNameIndex literalTagNameId; - private bool literalEntities; - private bool plaintext; - - - - - private bool parseConditionals = false; - - - private ParseState parseState = ParseState.Text; - - private char[] parseBuffer; - private int parseStart; - private int parseCurrent; - private int parseEnd; - private int parseThreshold = 1; - - private bool slowParse = true; - - private char scanQuote; - private char valueQuote; - private CharClass lastCharClass; - private int nameLength; - - - private HtmlTokenBuilder tokenBuilder; - private HtmlToken token; - - private IRestartable restartConsumer; - private bool detectEncodingFromMetaTag; - - - private short[] hashValuesTable; - - private bool rightMeta; - private Encoding newEncoding; - - private SavedParserState savedState; - - - public HtmlParser( - ConverterInput input, - bool detectEncodingFromMetaTag, - bool preformatedText, - int maxRuns, - int maxAttrs, - bool testBoundaryConditions) - { - this.input = input; - this.detectEncodingFromMetaTag = detectEncodingFromMetaTag; - input.SetRestartConsumer(this); - - tokenBuilder = new HtmlTokenBuilder(null, maxRuns, maxAttrs, testBoundaryConditions); - - token = tokenBuilder.Token; - - plaintext = preformatedText; - literalEntities = preformatedText; - } - - - protected enum ParseState : byte - { - Text, - TagStart, - TagNamePrefix, - TagName, - TagWsp, - AttrNameStart, - AttrNamePrefix, - AttrName, - AttrWsp, - AttrValueWsp, - AttrValue, - EmptyTagEnd, - TagEnd, - TagSkip, - CommentStart, - Comment, - Conditional, - CommentConditional, - Bang, - Dtd, - Asp, - } - - - public HtmlToken Token => token; - - - public void SetRestartConsumer(IRestartable restartConsumer) - { - this.restartConsumer = restartConsumer; - } - - - private void Reinitialize() - { - endOfFile = false; - - literalTags = false; - literalTagNameId = HtmlNameIndex._NOTANAME; - literalEntities = false; - plaintext = false; - - parseState = ParseState.Text; - - parseBuffer = null; - parseStart = 0; - parseCurrent = 0; - parseEnd = 0; - parseThreshold = 1; - - slowParse = true; - - scanQuote = '\0'; - valueQuote = '\0'; - lastCharClass = 0; - nameLength = 0; - - tokenBuilder.Reset(); - tokenBuilder.MakeEmptyToken(HtmlTokenId.Restart); - } - - - public bool ParsingFragment => savedState != null && savedState.StateSaved; - - - public void PushFragment(ConverterInput fragmentInput, bool literalTextInput) - { - if (savedState == null) - { - savedState = new SavedParserState(); - } - - savedState.PushState(this, fragmentInput, literalTextInput); - } - - - public void PopFragment() - { - savedState.PopState(this); - } - - - private class SavedParserState - { - private ConverterInput input; - private bool endOfFile; - private ParseState parseState; - private bool slowParse; - private bool literalTags; - private HtmlNameIndex literalTagNameId; - private bool literalEntities; - private bool plaintext; - private char[] parseBuffer; - private int parseStart; - private int parseCurrent; - private int parseEnd; - private int parseThreshold; - - public bool StateSaved => input != null; - - public void PushState(HtmlParser parser, ConverterInput newInput, bool literalTextInput) - { - InternalDebug.Assert(!StateSaved); - InternalDebug.Assert(parser.parseState == ParseState.Text || parser.parseState == ParseState.TagStart); - - input = parser.input; - endOfFile = parser.endOfFile; - parseState = parser.parseState; - slowParse = parser.slowParse; - literalTags = parser.literalTags; - literalTagNameId = parser.literalTagNameId; - literalEntities = parser.literalEntities; - plaintext = parser.plaintext; - parseBuffer = parser.parseBuffer; - parseStart = parser.parseStart; - parseCurrent = parser.parseCurrent; - parseEnd = parser.parseEnd; - parseThreshold = parser.parseThreshold; - - parser.input = newInput; - parser.endOfFile = false; - parser.parseState = ParseState.Text; - parser.slowParse = true; - parser.literalTags = literalTextInput; - parser.literalTagNameId = HtmlNameIndex.PlainText; - parser.literalEntities = literalTextInput; - parser.plaintext = literalTextInput; - parser.parseBuffer = null; - parser.parseStart = 0; - parser.parseCurrent = 0; - parser.parseEnd = 0; - parser.parseThreshold = 1; - } - - public void PopState(HtmlParser parser) - { - InternalDebug.Assert(StateSaved); - InternalDebug.Assert(parser.endOfFile); - - parser.input = input; - parser.endOfFile = endOfFile; - parser.parseState = parseState; - parser.slowParse = slowParse; - parser.literalTags = literalTags; - parser.literalTagNameId = literalTagNameId; - parser.literalEntities = literalEntities; - parser.plaintext = plaintext; - parser.parseBuffer = parseBuffer; - parser.parseStart = parseStart; - parser.parseCurrent = parseCurrent; - parser.parseEnd = parseEnd; - parser.parseThreshold = parseThreshold; - - input = null; - parseBuffer = null; - } - } - - - bool IRestartable.CanRestart() - { - return restartConsumer != null && restartConsumer.CanRestart(); - } - - - void IRestartable.Restart() - { - if (restartConsumer != null) - { - restartConsumer.Restart(); - } - - Reinitialize(); - } - - - void IRestartable.DisableRestart() - { - if (restartConsumer != null) - { - restartConsumer.DisableRestart(); - restartConsumer = null; - } - } - - - void IReusable.Initialize(object newSourceOrDestination) - { - InternalDebug.Assert(input is IReusable); - - ((IReusable)input).Initialize(newSourceOrDestination); - - Reinitialize(); - - input.SetRestartConsumer(this); - } - - - public void Initialize(string fragment, bool preformatedText) - { - InternalDebug.Assert(input is ConverterBufferInput); - - (input as ConverterBufferInput).Initialize(fragment); - - Reinitialize(); - - plaintext = preformatedText; - literalEntities = preformatedText; - } - - - void IDisposable.Dispose() - { - if (input != null /*&& this.input is IDisposable*/) - { - ((IDisposable)input).Dispose(); - } - - input = null; - restartConsumer = null; - parseBuffer = null; - token = null; - tokenBuilder = null; - hashValuesTable = null; - - GC.SuppressFinalize(this); - } - - - public HtmlTokenId Parse() - { - if (slowParse) - { - return ParseSlow(); - } - - - - - - - - InternalDebug.Assert(this.parseBuffer[this.parseCurrent] == '<' && parseState == ParseState.TagStart); - - if (tokenBuilder.Valid) - { - - - - InternalDebug.Assert(!tokenBuilder.IncompleteTag); - - input.ReportProcessed(this.parseCurrent - parseStart); - parseStart = this.parseCurrent; - - tokenBuilder.Reset(); - } - - - - - var parseBuffer = this.parseBuffer; - var parseCurrent = this.parseCurrent; - - var runStart = parseCurrent; - var endTag = false; - - var ch = parseBuffer[++parseCurrent]; - - if (ch == '/') - { - endTag = true; - ch = parseBuffer[++parseCurrent]; - } - - var charClass = ParseSupport.GetCharClass(ch); - - if (!ParseSupport.AlphaCharacter(charClass)) - { - - goto StartSlowly; - } - - tokenBuilder.StartTag(HtmlNameIndex.Unknown, runStart); - if (endTag) - { - tokenBuilder.SetEndTag(); - } - - - - tokenBuilder.DebugPrepareToAddMoreRuns(6); - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.TagPrefix, runStart, parseCurrent); - - tokenBuilder.StartTagName(); - - var nameLength = 0; - - runStart = parseCurrent; - - parseState = ParseState.TagNamePrefix; - - do - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - while (ParseSupport.HtmlSimpleTagNameCharacter(charClass)); - - if (ch == ':') - { - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.Name, runStart, parseCurrent); - - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.NamePrefixDelimiter, parseCurrent, parseCurrent + 1); - - tokenBuilder.EndTagNamePrefix(); - - nameLength = parseCurrent + 1 - runStart; - runStart = parseCurrent + 1; - - - do - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - while (ParseSupport.HtmlSimpleTagNameCharacter(charClass)); - - parseState = ParseState.TagName; - } - - if (parseCurrent != runStart) - { - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.Name, runStart, parseCurrent); - nameLength += parseCurrent - runStart; - } - - if (!ParseSupport.HtmlEndTagNameCharacter(charClass)) - { - - goto ContinueSlowly; - } - - tokenBuilder.EndTagName(nameLength); - - ScanNextAttributeOrEnd: - - tokenBuilder.AssertPreparedToAddMoreRuns(2); - - - - if (ParseSupport.WhitespaceCharacter(charClass)) - { - runStart = parseCurrent; - - do - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - while (ParseSupport.WhitespaceCharacter(charClass)); - - tokenBuilder.AddRun(RunTextType.Space, HtmlRunKind.TagWhitespace, runStart, parseCurrent); - } - - CheckEndOfTag: - - tokenBuilder.AssertPreparedToAddMoreRuns(1); - - if (ch == '>' || (ch == '/' && parseBuffer[parseCurrent + 1] == '>')) - { - - - runStart = parseCurrent; - - if (ch == '/') - { - parseCurrent ++; - tokenBuilder.SetEmptyScope(); - } - parseCurrent ++; - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.TagSuffix, runStart, parseCurrent); - tokenBuilder.EndTag(true); - - InternalDebug.Assert(scanQuote == '\0' && valueQuote == '\0'); - - if (parseBuffer[parseCurrent] == '<') - { - parseState = ParseState.TagStart; - } - else - { - parseState = ParseState.Text; - slowParse = true; - } - - this.parseCurrent = parseCurrent; - - HandleSpecialTag(); - - return token.TokenId; - } - - parseState = ParseState.TagWsp; - if (!ParseSupport.HtmlSimpleAttrNameCharacter(charClass) || - !tokenBuilder.CanAddAttribute() || - !tokenBuilder.PrepareToAddMoreRuns(11)) - { - - goto ContinueSlowly; - } - - - - - tokenBuilder.StartAttribute(); - - nameLength = 0; - - runStart = parseCurrent; - - parseState = ParseState.AttrNamePrefix; - - do - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - while (ParseSupport.HtmlSimpleAttrNameCharacter(charClass)); - - if (ch == ':') - { - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.Name, runStart, parseCurrent); - - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.NamePrefixDelimiter, parseCurrent, parseCurrent + 1); - - tokenBuilder.EndAttributeNamePrefix(); - - nameLength = parseCurrent + 1 - runStart; - runStart = parseCurrent + 1; - - - do - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - while (ParseSupport.HtmlSimpleAttrNameCharacter(charClass)); - - parseState = ParseState.AttrName; - } - - if (parseCurrent != runStart) - { - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.Name, runStart, parseCurrent); - nameLength += parseCurrent - runStart; - } - - if (!ParseSupport.HtmlEndAttrNameCharacter(charClass)) - { - - goto ContinueSlowly; - } - - tokenBuilder.EndAttributeName(nameLength); - - if (ParseSupport.WhitespaceCharacter(charClass)) - { - runStart = parseCurrent; - - do - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - while (ParseSupport.WhitespaceCharacter(charClass)); - - tokenBuilder.AddRun(RunTextType.Space, HtmlRunKind.TagWhitespace, runStart, parseCurrent); - - parseState = ParseState.AttrWsp; - if (ParseSupport.InvalidUnicodeCharacter(charClass)) - { - - goto ContinueSlowly; - } - } - - if (ch != '=') - { - - - tokenBuilder.EndAttribute(); - - goto CheckEndOfTag; - } - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.AttrEqual, parseCurrent, parseCurrent + 1); - - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - if (ParseSupport.WhitespaceCharacter(charClass)) - { - runStart = parseCurrent; - - do - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - while (ParseSupport.WhitespaceCharacter(charClass)); - - tokenBuilder.AddRun(RunTextType.Space, HtmlRunKind.TagWhitespace, runStart, parseCurrent); - - parseState = ParseState.AttrValueWsp; - if (ParseSupport.InvalidUnicodeCharacter(charClass)) - { - - goto ContinueSlowly; - } - } - - if (ParseSupport.QuoteCharacter(charClass)) - { - valueQuote = ch; - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.AttrQuote, parseCurrent, parseCurrent + 1); - - tokenBuilder.StartValue(); - tokenBuilder.SetValueQuote(valueQuote); - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - if (ParseSupport.HtmlSimpleAttrQuotedValueCharacter(charClass)) - { - runStart = parseCurrent; - - do - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - while (ParseSupport.HtmlSimpleAttrQuotedValueCharacter(charClass)); - - - tokenBuilder.AddRun(RunTextType.Unknown, HtmlRunKind.AttrValue, runStart, parseCurrent); - } - - if (ch != valueQuote) - { - scanQuote = valueQuote; - parseState = ParseState.AttrValue; - - goto ContinueSlowly; - } - - valueQuote = '\0'; - - tokenBuilder.EndValue(); - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.AttrQuote, parseCurrent, parseCurrent + 1); - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - tokenBuilder.EndAttribute(); - - goto ScanNextAttributeOrEnd; - } - else if (ParseSupport.HtmlSimpleAttrUnquotedValueCharacter(charClass)) - { - tokenBuilder.StartValue(); - - runStart = parseCurrent; - - do - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - while (ParseSupport.HtmlSimpleAttrUnquotedValueCharacter(charClass)); - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.AttrValue, runStart, parseCurrent); - - parseState = ParseState.AttrValue; - if (!ParseSupport.HtmlEndAttrUnquotedValueCharacter(charClass)) - { - - goto ContinueSlowly; - } - - tokenBuilder.EndValue(); - - tokenBuilder.EndAttribute(); - - goto ScanNextAttributeOrEnd; - } - - - - - parseState = ParseState.AttrValueWsp; - - ContinueSlowly: - - this.parseCurrent = parseCurrent; - lastCharClass = ParseSupport.GetCharClass(parseBuffer[parseCurrent - 1]); - this.nameLength = nameLength; - - StartSlowly: - - slowParse = true; - return ParseSlow(); - } - - - public HtmlTokenId ParseSlow() - { - InternalDebug.Assert(parseCurrent >= parseStart); - - if (tokenBuilder.Valid) - { - - - if (tokenBuilder.IncompleteTag) - { - var newBase = tokenBuilder.RewindTag(); - - - - - InternalDebug.Assert(parseCurrent >= newBase); - - input.ReportProcessed(newBase - parseStart); - parseStart = newBase; - } - else - { - input.ReportProcessed(parseCurrent - parseStart); - parseStart = parseCurrent; - - tokenBuilder.Reset(); - } - } - - while (true) - { - InternalDebug.Assert(parseThreshold > 0); - - - - var forceFlushToken = false; - - if (parseCurrent + parseThreshold > parseEnd) - { - - - - - - - if (!endOfFile) - { - if (!input.ReadMore(ref parseBuffer, ref parseStart, ref parseCurrent, ref parseEnd)) - { - - - - InternalDebug.Assert(!tokenBuilder.Valid); - - return HtmlTokenId.None; - } - - - - - tokenBuilder.BufferChanged(parseBuffer, parseStart); - - var decodingInput = input as ConverterDecodingInput; - - if (decodingInput != null && decodingInput.EncodingChanged) - { - - - - - - - - - - - - - - decodingInput.EncodingChanged = false; - - - - - - - return tokenBuilder.MakeEmptyToken(HtmlTokenId.EncodingChange, decodingInput.Encoding.CodePage); - } - - if (input.EndOfFile) - { - endOfFile = true; - } - - - if (!endOfFile && parseEnd - parseStart < input.MaxTokenSize) - { - - continue; - } - } - - - forceFlushToken = true; - } - - - InternalDebug.Assert(parseEnd > parseCurrent || forceFlushToken); - - - - - - var ch = parseBuffer[parseCurrent]; - var charClass = ParseSupport.GetCharClass(ch); - - if (ParseSupport.InvalidUnicodeCharacter(charClass) || parseThreshold > 1) - { - - - - - - - var aboveThreshold = SkipInvalidCharacters(ref ch, ref charClass, ref parseCurrent); - - - - if (token.IsEmpty) - { - input.ReportProcessed(parseCurrent - parseStart); - parseStart = parseCurrent; - - if (tokenBuilder.IncompleteTag) - { - - tokenBuilder.BufferChanged(parseBuffer, parseStart); - } - } - - if (!aboveThreshold) - { - - - if (!forceFlushToken) - { - - continue; - } - - - - if (parseCurrent == parseEnd && !tokenBuilder.IsStarted && endOfFile) - { - - break; - } - - - } - - - parseThreshold = 1; - } - - if (ParseStateMachine(ch, charClass, forceFlushToken)) - { - return token.TokenId; - } - } - - return tokenBuilder.MakeEmptyToken(HtmlTokenId.EndOfFile); - } - - - public bool ParseStateMachine(char ch, CharClass charClass, bool forceFlushToken) - { - char chT; - CharClass charClassT; - - var tokenBuilder = this.tokenBuilder; - var parseBuffer = this.parseBuffer; - var parseCurrent = this.parseCurrent; - var parseEnd = this.parseEnd; - - var runStart = parseCurrent; - - InternalDebug.Assert(parseBuffer[parseCurrent] == ch); - - switch (parseState) - { - - - case ParseState.Text: - - InternalDebug.Assert(!tokenBuilder.IsStarted); - - if (ch == '<' && !plaintext) - { - - parseState = ParseState.TagStart; - goto case ParseState.TagStart; - } - - ContinueText: - - tokenBuilder.StartText(runStart); - - - tokenBuilder.DebugPrepareToAddMoreRuns(3); - - ParseText(ch, charClass, ref parseCurrent); - - if (token.IsEmpty && !forceFlushToken) - { - - InternalDebug.Assert(parseCurrent == runStart); - InternalDebug.Assert(parseState != ParseState.Text || parseThreshold > 1); - - tokenBuilder.Reset(); - slowParse = true; - break; - } - - - - tokenBuilder.EndText(); - - this.parseCurrent = parseCurrent; - - return true; - - - - case ParseState.TagStart: - - InternalDebug.Assert(ch == '<'); - InternalDebug.Assert(!tokenBuilder.IsStarted); - - - tokenBuilder.DebugPrepareToAddMoreRuns(4); - - chT = parseBuffer[parseCurrent + 1]; - charClassT = ParseSupport.GetCharClass(chT); - - var endTag = false; - - if (chT == '/') - { - - - chT = parseBuffer[parseCurrent + 2]; - charClassT = ParseSupport.GetCharClass(chT); - - if (ParseSupport.InvalidUnicodeCharacter(charClassT)) - { - - - - - if (!endOfFile || parseCurrent + 2 < parseEnd) - { - - - parseThreshold = 3; - break; - } - - - } - - parseCurrent ++; - - endTag = true; - } - else if (!ParseSupport.AlphaCharacter(charClassT) || literalTags) - { - if (chT == '!') - { - - - - - - - - - - - - - - - - - - - - - parseState = ParseState.CommentStart; - goto case ParseState.CommentStart; - } - else if (chT == '?' && !literalTags) - { - parseCurrent += 2; - - tokenBuilder.StartTag(HtmlNameIndex._DTD, runStart); - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.TagPrefix, runStart, parseCurrent); - - tokenBuilder.StartTagText(); - - lastCharClass = charClassT; - - ch = parseBuffer[parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - runStart = parseCurrent; - - parseState = ParseState.Dtd; - goto case ParseState.Dtd; - } - else if (chT == '%') - { - parseCurrent += 2; - - tokenBuilder.StartTag(HtmlNameIndex._ASP, runStart); - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.TagPrefix, runStart, parseCurrent); - - tokenBuilder.StartTagText(); - - ch = parseBuffer[parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - runStart = parseCurrent; - - parseState = ParseState.Asp; - goto case ParseState.Asp; - } - else if (ParseSupport.InvalidUnicodeCharacter(charClassT)) - { - - - if (!endOfFile || parseCurrent + 1 < parseEnd) - { - - - parseThreshold = 2; - break; - } - - - } - - - - - - - - - - parseState = ParseState.Text; - goto ContinueText; - } - - - - - parseCurrent ++; - - lastCharClass = charClass; - - ch = chT; - charClass = charClassT; - - tokenBuilder.StartTag(HtmlNameIndex.Unknown, runStart); - if (endTag) - { - tokenBuilder.SetEndTag(); - } - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.TagPrefix, runStart, parseCurrent); - - nameLength = 0; - tokenBuilder.StartTagName(); - - runStart = parseCurrent; - - parseState = ParseState.TagNamePrefix; - goto case ParseState.TagNamePrefix; - - - - case ParseState.TagNamePrefix: - - if (!tokenBuilder.PrepareToAddMoreRuns(2, runStart, HtmlRunKind.Name)) - { - - - - - goto SplitTag; - } - - ch = ScanTagName(ch, ref charClass, ref parseCurrent, CharClass.HtmlTagNamePrefix); - - if (parseCurrent != runStart) - { - nameLength += (parseCurrent - runStart); - - if (literalTags && (nameLength > HtmlNameData.MAX_TAG_NAME || ch == '<')) - { - - - - - goto RejectTag; - } - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.Name, runStart, parseCurrent); - } - - if (ParseSupport.InvalidUnicodeCharacter(charClass)) - { - goto HandleTagEOB; - } - - if (ch != ':') - { - goto EndTagName; - } - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.NamePrefixDelimiter, parseCurrent, parseCurrent + 1); - nameLength ++; - - this.tokenBuilder.EndTagNamePrefix(); - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - runStart = parseCurrent; - - parseState = ParseState.TagName; - goto case ParseState.TagName; - - - - case ParseState.TagName: - - if (!tokenBuilder.PrepareToAddMoreRuns(1, runStart, HtmlRunKind.Name)) - { - - - - - goto SplitTag; - } - - ch = ScanTagName(ch, ref charClass, ref parseCurrent, CharClass.HtmlTagName); - - if (parseCurrent != runStart) - { - nameLength += (parseCurrent - runStart); - - if (literalTags && (nameLength > HtmlNameData.MAX_TAG_NAME || ch == '<')) - { - - - - - goto RejectTag; - } - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.Name, runStart, parseCurrent); - } - - if (ParseSupport.InvalidUnicodeCharacter(charClass)) - { - goto HandleTagEOB; - } - - EndTagName: - - - - tokenBuilder.EndTagName(nameLength); - - InternalDebug.Assert(!literalTags || token.IsEndTag); - - if (literalTags && token.NameIndex != literalTagNameId) - { - - - - goto RejectTag; - } - - - - runStart = parseCurrent; - - if (ch == '>') - { - parseState = ParseState.TagEnd; - goto case ParseState.TagEnd; - } - else if (ch == '/') - { - parseState = ParseState.EmptyTagEnd; - goto case ParseState.EmptyTagEnd; - } - - - - - lastCharClass = charClass; - - parseState = ParseState.TagWsp; - goto case ParseState.TagWsp; - - - - case ParseState.TagWsp: - - - if (!tokenBuilder.PrepareToAddMoreRuns(2, runStart, HtmlRunKind.TagWhitespace)) - { - goto SplitTag; - } - - ch = ScanWhitespace(ch, ref charClass, ref parseCurrent); - - if (parseCurrent != runStart) - { - tokenBuilder.AddRun(RunTextType.Space, HtmlRunKind.TagWhitespace, runStart, parseCurrent); - } - - if (ParseSupport.InvalidUnicodeCharacter(charClass)) - { - goto HandleTagEOB; - } - - runStart = parseCurrent; - - if (ch == '>') - { - parseState = ParseState.TagEnd; - goto case ParseState.TagEnd; - } - else if (ch == '/') - { - parseState = ParseState.EmptyTagEnd; - goto case ParseState.EmptyTagEnd; - } - - parseState = ParseState.AttrNameStart; - goto case ParseState.AttrNameStart; - - case ParseState.AttrNameStart: - - if (!tokenBuilder.CanAddAttribute() || !tokenBuilder.PrepareToAddMoreRuns(3, runStart, HtmlRunKind.Name)) - { - goto SplitTag; - } - - nameLength = 0; - - tokenBuilder.StartAttribute(); - - parseState = ParseState.AttrNamePrefix; - goto case ParseState.AttrNamePrefix; - - - - case ParseState.AttrNamePrefix: - - InternalDebug.Assert(valueQuote == '\0'); - - - if (!tokenBuilder.PrepareToAddMoreRuns(3, runStart, HtmlRunKind.Name)) - { - goto SplitTag; - } - - ch = ScanAttrName(ch, ref charClass, ref parseCurrent, CharClass.HtmlAttrNamePrefix); - - if (parseCurrent != runStart) - { - nameLength += (parseCurrent - runStart); - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.Name, runStart, parseCurrent); - } - - if (ParseSupport.InvalidUnicodeCharacter(charClass)) - { - goto HandleTagEOB; - } - - if (ch != ':') - { - goto EndAttributeName; - } - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.NamePrefixDelimiter, parseCurrent, parseCurrent + 1); - nameLength ++; - - this.tokenBuilder.EndAttributeNamePrefix(); - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - runStart = parseCurrent; - - parseState = ParseState.AttrName; - goto case ParseState.AttrName; - - - - case ParseState.AttrName: - - InternalDebug.Assert(valueQuote == '\0'); - - - if (!tokenBuilder.PrepareToAddMoreRuns(2, runStart, HtmlRunKind.Name)) - { - goto SplitTag; - } - - ch = ScanAttrName(ch, ref charClass, ref parseCurrent, CharClass.HtmlAttrName); - - if (parseCurrent != runStart) - { - nameLength += (parseCurrent - runStart); - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.Name, runStart, parseCurrent); - } - - if (ParseSupport.InvalidUnicodeCharacter(charClass)) - { - goto HandleTagEOB; - } - - EndAttributeName: - - tokenBuilder.EndAttributeName(nameLength); - - runStart = parseCurrent; - - if (ch == '=') - { - goto HandleAttrEqual; - } - - InternalDebug.Assert(ch == '>' || ch == '/' || ParseSupport.WhitespaceCharacter(charClass)); - - lastCharClass = charClass; - - parseState = ParseState.AttrWsp; - goto case ParseState.AttrWsp; - - - - case ParseState.AttrWsp: - - - if (!tokenBuilder.PrepareToAddMoreRuns(2, runStart, HtmlRunKind.TagWhitespace)) - { - goto SplitTag; - } - - ch = ScanWhitespace(ch, ref charClass, ref parseCurrent); - - if (parseCurrent != runStart) - { - tokenBuilder.AddRun(RunTextType.Space, HtmlRunKind.TagWhitespace, runStart, parseCurrent); - } - - if (ParseSupport.InvalidUnicodeCharacter(charClass)) - { - goto HandleTagEOB; - } - - runStart = parseCurrent; - - if (ch != '=') - { - - tokenBuilder.EndAttribute(); - - InternalDebug.Assert(valueQuote == '\0'); - - if (ch == '>') - { - parseState = ParseState.TagEnd; - goto case ParseState.TagEnd; - } - else if (ch == '/') - { - parseState = ParseState.EmptyTagEnd; - goto case ParseState.EmptyTagEnd; - } - - parseState = ParseState.AttrNameStart; - goto case ParseState.AttrNameStart; - } - - HandleAttrEqual: - - InternalDebug.Assert(ch == '='); - - lastCharClass = charClass; - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.AttrEqual, runStart, parseCurrent); - - runStart = parseCurrent; - - parseState = ParseState.AttrValueWsp; - goto case ParseState.AttrValueWsp; - - - - case ParseState.AttrValueWsp: - - - if (!tokenBuilder.PrepareToAddMoreRuns(3, runStart, HtmlRunKind.TagWhitespace)) - { - goto SplitTag; - } - - ch = ScanWhitespace(ch, ref charClass, ref parseCurrent); - - if (parseCurrent != runStart) - { - tokenBuilder.AddRun(RunTextType.Space, HtmlRunKind.TagWhitespace, runStart, parseCurrent); - } - - if (ParseSupport.InvalidUnicodeCharacter(charClass)) - { - goto HandleTagEOB; - } - - runStart = parseCurrent; - - InternalDebug.Assert(valueQuote == '\0'); - - if (ParseSupport.QuoteCharacter(charClass)) - { - if (ch == scanQuote) - { - scanQuote = '\0'; - } - else if (scanQuote == '\0') - { - InternalDebug.Assert(ParseSupport.HtmlScanQuoteSensitiveCharacter(lastCharClass)); - scanQuote = ch; - } - - valueQuote = ch; - - lastCharClass = charClass; - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.AttrQuote, runStart, parseCurrent); - - runStart = parseCurrent; - } - - tokenBuilder.StartValue(); - - if (valueQuote != '\0') - { - tokenBuilder.SetValueQuote(valueQuote); - } - - parseState = ParseState.AttrValue; - goto case ParseState.AttrValue; - - - - case ParseState.AttrValue: - - - if (!tokenBuilder.PrepareToAddMoreRuns(2, runStart, HtmlRunKind.AttrValue)) - { - goto SplitTag; - } - - if (!ParseAttributeText(ch, charClass, ref parseCurrent)) - { - goto SplitTag; - } - - ch = parseBuffer[parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - if (ParseSupport.InvalidUnicodeCharacter(charClass) || parseThreshold > 1) - { - goto HandleTagEOB; - } - - tokenBuilder.EndValue(); - - runStart = parseCurrent; - - if (ch == valueQuote) - { - lastCharClass = charClass; - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.AttrQuote, runStart, parseCurrent); - - valueQuote = '\0'; - - runStart = parseCurrent; - } - - tokenBuilder.EndAttribute(); - - InternalDebug.Assert(valueQuote == '\0'); - - if (ch == '>') - { - parseState = ParseState.TagEnd; - goto case ParseState.TagEnd; - } - else if (ch == '/') - { - parseState = ParseState.EmptyTagEnd; - goto case ParseState.EmptyTagEnd; - } - - parseState = ParseState.TagWsp; - goto case ParseState.TagWsp; - - - - case ParseState.EmptyTagEnd: - - InternalDebug.Assert(ch == '/'); - - if (!tokenBuilder.PrepareToAddMoreRuns(1, runStart, HtmlRunKind.TagWhitespace)) - { - goto SplitTag; - } - - chT = parseBuffer[parseCurrent + 1]; - charClassT = ParseSupport.GetCharClass(chT); - - if (chT == '>') - { - - - tokenBuilder.SetEmptyScope(); - - parseCurrent ++; - - lastCharClass = charClass; - - ch = chT; - charClass = charClassT; - - parseState = ParseState.TagEnd; - goto case ParseState.TagEnd; - } - - if (ParseSupport.InvalidUnicodeCharacter(charClassT) && (!endOfFile || parseCurrent + 1 < parseEnd)) - { - parseThreshold = 2; - goto HandleTagEOB; - } - - - - lastCharClass = charClass; - - parseCurrent ++; - - ch = chT; - charClass = charClassT; - - runStart = parseCurrent; - - parseState = ParseState.TagWsp; - goto case ParseState.TagWsp; - - - - case ParseState.TagEnd: - - InternalDebug.Assert(ch == '>'); - - if (!tokenBuilder.PrepareToAddMoreRuns(1, runStart, HtmlRunKind.TagSuffix)) - { - goto SplitTag; - } - - lastCharClass = charClass; - - parseCurrent ++; - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.TagSuffix, runStart, parseCurrent); - - if (scanQuote != '\0') - { - runStart = parseCurrent; - - ch = parseBuffer[parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - parseState = ParseState.TagSkip; - goto case ParseState.TagSkip; - } - - - tokenBuilder.EndTag(true); - - InternalDebug.Assert(scanQuote == '\0' && valueQuote == '\0'); - - if (parseBuffer[parseCurrent] == '<') - { - parseState = ParseState.TagStart; - slowParse = false; - } - else - { - parseState = ParseState.Text; - } - - this.parseCurrent = parseCurrent; - - HandleSpecialTag(); - - return true; - - - - case ParseState.TagSkip: - - - - if (!tokenBuilder.PrepareToAddMoreRuns(1, runStart, HtmlRunKind.TagText)) - { - goto SplitTag; - } - - ch = ScanSkipTag(ch, ref charClass, ref parseCurrent); - - if (parseCurrent != runStart) - { - tokenBuilder.AddRun(RunTextType.Unknown, HtmlRunKind.TagText, runStart, parseCurrent); - } - - if (ParseSupport.InvalidUnicodeCharacter(charClass)) - { - - goto HandleTagEOB; - } - - InternalDebug.Assert(ch == '>' && scanQuote == '\0'); - - parseCurrent ++; - - - tokenBuilder.EndTag(true); - - InternalDebug.Assert(scanQuote == '\0' && valueQuote == '\0'); - - if (parseBuffer[parseCurrent] == '<') - { - parseState = ParseState.TagStart; - slowParse = false; - } - else - { - parseState = ParseState.Text; - } - - this.parseCurrent = parseCurrent; - - HandleSpecialTag(); - - return true; - - - - - HandleTagEOB: - - if (!forceFlushToken || parseCurrent + parseThreshold < parseEnd) - { - - - break; - } - - - - if (endOfFile) - { - if (parseCurrent < parseEnd) - { - - - if (ScanForInternalInvalidCharacters(parseCurrent)) - { - - break; - } - - - - parseCurrent = parseEnd; - } - - - - if (token.IsTagBegin) - { - - - goto RejectTag; - } - - - - - tokenBuilder.EndTag(true); - - this.parseCurrent = parseCurrent; - - HandleSpecialTag(); - - parseState = ParseState.Text; - - return true; - } - - - - - SplitTag: - - if (literalTags && token.NameIndex == HtmlNameIndex.Unknown) - { - - - - InternalDebug.Assert(token.IsTagBegin); - goto RejectTag; - } - - - - tokenBuilder.EndTag(false); - - this.parseCurrent = parseCurrent; - - HandleSpecialTag(); - - return true; - - RejectTag: - - - - - - InternalDebug.Assert(token.IsTagBegin); - - parseCurrent = parseStart; - - scanQuote = valueQuote = '\0'; - - tokenBuilder.Reset(); - - runStart = parseCurrent; - - - - ch = parseBuffer[parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - InternalDebug.Assert(ch == '<'); - - parseState = ParseState.Text; - goto ContinueText; - - - - case ParseState.CommentStart: - - - - tokenBuilder.DebugPrepareToAddMoreRuns(3); - - InternalDebug.Assert(ch == '<'); - InternalDebug.Assert(parseBuffer[parseCurrent + 1] == '!'); - InternalDebug.Assert(!tokenBuilder.IsStarted); - - - - var pos = 2; - - chT = parseBuffer[parseCurrent + pos]; - - if (chT == '-') - { - pos ++; - - chT = parseBuffer[parseCurrent + pos]; - - if (chT == '-') - { - - - pos ++; - - chT = parseBuffer[parseCurrent + pos]; - - if (chT == '[' && parseConditionals) - { - - - - - - - parseCurrent += 5; - - tokenBuilder.StartTag(HtmlNameIndex._CONDITIONAL, runStart); - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.TagPrefix, runStart, parseCurrent); - - tokenBuilder.StartTagText(); - - ch = parseBuffer[parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - runStart = parseCurrent; - - parseState = ParseState.CommentConditional; - goto case ParseState.CommentConditional; - } - else if (chT == '>') - { - - - parseCurrent += 5; - - tokenBuilder.StartTag(HtmlNameIndex._COMMENT, runStart); - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.TagPrefix, runStart, parseCurrent - 1); - tokenBuilder.StartTagText(); - tokenBuilder.EndTagText(); - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.TagSuffix, parseCurrent - 1, parseCurrent); - - tokenBuilder.EndTag(true); - - InternalDebug.Assert(scanQuote == '\0' && valueQuote == '\0'); - - parseState = ParseState.Text; - - this.parseCurrent = parseCurrent; - - return true; - } - else if (chT == '-') - { - pos ++; - - chT = parseBuffer[parseCurrent + pos]; - - if (chT == '>') - { - - - parseCurrent += 6; - - tokenBuilder.StartTag(HtmlNameIndex._COMMENT, runStart); - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.TagPrefix, runStart, parseCurrent - 2); - tokenBuilder.StartTagText(); - tokenBuilder.EndTagText(); - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.TagSuffix, parseCurrent - 2, parseCurrent); - - tokenBuilder.EndTag(true); - - InternalDebug.Assert(scanQuote == '\0' && valueQuote == '\0'); - - parseState = ParseState.Text; - - this.parseCurrent = parseCurrent; - - return true; - } - } - - charClassT = ParseSupport.GetCharClass(chT); - - if (!ParseSupport.InvalidUnicodeCharacter(charClassT)) - { - parseCurrent += 4; - - tokenBuilder.StartTag(HtmlNameIndex._COMMENT, runStart); - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.TagPrefix, runStart, parseCurrent); - - tokenBuilder.StartTagText(); - - ch = parseBuffer[parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - runStart = parseCurrent; - - parseState = ParseState.Comment; - goto case ParseState.Comment; - } - } - } - else if (chT == '[' && parseConditionals) - { - - - - - - - parseCurrent += 3; - - tokenBuilder.StartTag(HtmlNameIndex._CONDITIONAL, runStart); - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.TagPrefix, runStart, parseCurrent); - - tokenBuilder.StartTagText(); - - ch = parseBuffer[parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - runStart = parseCurrent; - - parseState = ParseState.Conditional; - goto case ParseState.Conditional; - } - - - - - charClassT = ParseSupport.GetCharClass(chT); - - if (ParseSupport.InvalidUnicodeCharacter(charClassT)) - { - - - - - if (!endOfFile || parseCurrent + pos < parseEnd) - { - - - parseThreshold = pos + 1; - break; - } - - - - InternalDebug.Assert(ch == '<'); - - parseState = ParseState.Text; - goto ContinueText; - } - - - - if (literalTags) - { - - parseState = ParseState.Text; - goto ContinueText; - } - - parseCurrent += 2; - - tokenBuilder.StartTag(HtmlNameIndex._BANG, runStart); - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.TagPrefix, runStart, parseCurrent); - - tokenBuilder.StartTagText(); - - lastCharClass = ParseSupport.GetCharClass('!'); - - ch = parseBuffer[parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - runStart = parseCurrent; - - parseState = ParseState.Bang; - goto case ParseState.Bang; - - - - - - - case ParseState.CommentConditional: - case ParseState.Conditional: - case ParseState.Comment: - case ParseState.Bang: - case ParseState.Asp: - case ParseState.Dtd: - - if (!tokenBuilder.PrepareToAddMoreRuns(2, runStart, HtmlRunKind.TagText)) - { - goto SplitTag; - } - - while (!ParseSupport.InvalidUnicodeCharacter(charClass)) - { - - - if (ParseSupport.QuoteCharacter(charClass)) - { - if (ch == scanQuote) - { - scanQuote = '\0'; - } - else if (scanQuote == '\0' && ParseSupport.HtmlScanQuoteSensitiveCharacter(lastCharClass)) - { - scanQuote = ch; - } - } - else if (ParseSupport.HtmlSuffixCharacter(charClass)) - { - int addToTextCnt, tagSuffixCnt; - bool endScan; - - if (CheckSuffix(parseCurrent, ch, out addToTextCnt, out tagSuffixCnt, out endScan)) - { - if (!endScan) - { - - - InternalDebug.Assert(tagSuffixCnt == 0); - - parseCurrent += addToTextCnt; - - lastCharClass = charClass; - InternalDebug.Assert(!ParseSupport.HtmlScanQuoteSensitiveCharacter(lastCharClass)); - - ch = parseBuffer[parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - continue; - } - - scanQuote = '\0'; - - - - parseCurrent += addToTextCnt; - - if (parseCurrent != runStart) - { - tokenBuilder.AddRun(RunTextType.Unknown, HtmlRunKind.TagText, runStart, parseCurrent); - } - - tokenBuilder.EndTagText(); - - if (tagSuffixCnt != 0) - { - runStart = parseCurrent; - - parseCurrent += tagSuffixCnt; - - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.TagSuffix, runStart, parseCurrent); - } - - tokenBuilder.EndTag(true); - - InternalDebug.Assert(scanQuote == '\0' && valueQuote == '\0'); - - parseState = ParseState.Text; - - this.parseCurrent = parseCurrent; - - return true; - } - - - - - - - InternalDebug.Assert(tagSuffixCnt >= 1); - - parseCurrent += addToTextCnt; - parseThreshold = tagSuffixCnt + 1; - - break; - } - - lastCharClass = charClass; - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - - if (parseCurrent != runStart) - { - tokenBuilder.AddRun(RunTextType.Unknown, HtmlRunKind.TagText, runStart, parseCurrent); - - if (!tokenBuilder.PrepareToAddMoreRuns(2)) - { - - goto SplitTag; - } - } - - InternalDebug.Assert(ParseSupport.InvalidUnicodeCharacter(ParseSupport.GetCharClass(parseBuffer[parseCurrent + parseThreshold - 1]))); - - if (forceFlushToken && parseCurrent + parseThreshold > parseEnd) - { - - - - if (endOfFile && parseCurrent < parseEnd) - { - - - tokenBuilder.AddRun(RunTextType.Unknown, HtmlRunKind.TagText, parseCurrent, parseEnd); - - parseCurrent = parseEnd; - } - - tokenBuilder.EndTag(endOfFile); - - this.parseCurrent = parseCurrent; - - return true; - } - - - break; - - - - default: - InternalDebug.Assert(false); - this.parseCurrent = parseCurrent; - throw new TextConvertersException("internal error: invalid parse state"); - - } - - this.parseCurrent = parseCurrent; - return false; - } - - - private static void ProcessNumericEntityValue(int entityValue, out int literal) - { - if (entityValue < 0x10000) - { - if (0x80 <= entityValue && entityValue <= 0x9F) - { - literal = ParseSupport.Latin1MappingInUnicodeControlArea(entityValue); - } - else if (ParseSupport.InvalidUnicodeCharacter(ParseSupport.GetCharClass((char)entityValue))) - { - literal = '?'; - } - else - { - literal = entityValue; - } - } - else if (entityValue < 0x110000) - { - literal = entityValue; - } - else - { - literal = '?'; - } - } - - - private static bool FindEntityByHashName(short hash, char[] buffer, int nameOffset, int nameLength, out int entityValue) - { - entityValue = 0; - - var found = false; - var nameIndex = HtmlNameData.entityHashTable[hash]; - - if (nameIndex > 0) - { - do - { - if (HtmlNameData.entities[(int)nameIndex].name.Length == nameLength) - { - int i; - - - - for (i = 0; i < nameLength; i++) - { - if (HtmlNameData.entities[(int)nameIndex].name[i] != (char)buffer[nameOffset + i]) - { - break; - } - } - - if (i == nameLength) - { - entityValue = (int)HtmlNameData.entities[(int)nameIndex].value; - found = true; - break; - } - } - - - - nameIndex ++; - } - while (HtmlNameData.entities[(int)nameIndex].hash == hash); - - } - - return found; - } - - - private bool SkipInvalidCharacters(ref char ch, ref CharClass charClass, ref int parseCurrent) - { - - - var current = parseCurrent; - var end = parseEnd; - - while (ParseSupport.InvalidUnicodeCharacter(charClass) && current < end) - { - ch = parseBuffer[++current]; - charClass = ParseSupport.GetCharClass(ch); - } - - - - - if (parseThreshold > 1 && current + 1 < end) - { - InternalDebug.Assert(!ParseSupport.InvalidUnicodeCharacter(ParseSupport.GetCharClass(parseBuffer[current]))); - - var dst = current + 1; - var src = dst; - - while (src < end && dst < current + parseThreshold) - { - var chT = parseBuffer[src]; - var classT = ParseSupport.GetCharClass(chT); - - if (!ParseSupport.InvalidUnicodeCharacter(classT)) - { - if (src != dst) - { - InternalDebug.Assert(ParseSupport.InvalidUnicodeCharacter(ParseSupport.GetCharClass(parseBuffer[dst]))); - - parseBuffer[dst] = chT; - parseBuffer[src] = '\0'; - } - - dst ++; - } - - src ++; - } - - if (src == end) - { - end = parseEnd = input.RemoveGap(dst, end); - } - } - - - - parseCurrent = current; - - - return (current + parseThreshold <= end); - } - - - private char ScanTagName(char ch, ref CharClass charClass, ref int parseCurrent, CharClass acceptCharClassSet) - { - var parseBuffer = this.parseBuffer; - - while (ParseSupport.IsCharClassOneOf(charClass, acceptCharClassSet)) - { - if (ParseSupport.QuoteCharacter(charClass)) - { - if (ch == scanQuote) - { - scanQuote = '\0'; - } - else if (scanQuote == '\0' && ParseSupport.HtmlScanQuoteSensitiveCharacter(lastCharClass)) - { - scanQuote = ch; - } - } - else if (ch == '<' && literalTags) - { - - - - break; - } - - lastCharClass = charClass; - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - - return ch; - } - - - private char ScanAttrName(char ch, ref CharClass charClass, ref int parseCurrent, CharClass acceptCharClassSet) - { - var parseBuffer = this.parseBuffer; - - while (ParseSupport.IsCharClassOneOf(charClass, acceptCharClassSet)) - { - if (ParseSupport.QuoteCharacter(charClass)) - { - if (ch == scanQuote) - { - scanQuote = '\0'; - } - else if (scanQuote == '\0' && ParseSupport.HtmlScanQuoteSensitiveCharacter(lastCharClass)) - { - scanQuote = ch; - } - - if (ch != '`') - { - - - - parseBuffer[parseCurrent] = '?'; - } - } - - lastCharClass = charClass; - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - - return ch; - } - - - private char ScanWhitespace(char ch, ref CharClass charClass, ref int parseCurrent) - { - var parseBuffer = this.parseBuffer; - - while (ParseSupport.WhitespaceCharacter(charClass)) - { - lastCharClass = charClass; - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - - return ch; - } - - - private char ScanText(char ch, ref CharClass charClass, ref int parseCurrent) - { - var parseBuffer = this.parseBuffer; - - while (ParseSupport.HtmlTextCharacter(charClass)) - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - - return ch; - } - - - private char ScanAttrValue(char ch, ref CharClass charClass, ref int parseCurrent) - { - var parseBuffer = this.parseBuffer; - - while (ParseSupport.HtmlAttrValueCharacter(charClass)) - { - lastCharClass = charClass; - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - - return ch; - } - - - private char ScanSkipTag(char ch, ref CharClass charClass, ref int parseCurrent) - { - var parseBuffer = this.parseBuffer; - - while (!ParseSupport.InvalidUnicodeCharacter(charClass) && (ch != '>' || scanQuote != '\0')) - { - if (ParseSupport.QuoteCharacter(charClass)) - { - if (ch == scanQuote) - { - scanQuote = '\0'; - } - else if (scanQuote == '\0' && ParseSupport.HtmlScanQuoteSensitiveCharacter(lastCharClass)) - { - scanQuote = ch; - } - } - - lastCharClass = charClass; - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - - return ch; - } - - - private bool ScanForInternalInvalidCharacters(int parseCurrent) - { - var parseBuffer = this.parseBuffer; - char ch; - - do - { - ch = parseBuffer[parseCurrent++]; - } - while (!ParseSupport.InvalidUnicodeCharacter(ParseSupport.GetCharClass(ch))); - - parseCurrent--; - - InternalDebug.Assert(parseCurrent <= parseEnd); - - return parseCurrent < parseEnd; - } - - - private void ParseText(char ch, CharClass charClass, ref int parseCurrent) - { - var parseEnd = this.parseEnd; - var parseBuffer = this.parseBuffer; - var tokenBuilder = this.tokenBuilder; - - var firstRunStart = parseCurrent; - var runStart = firstRunStart; - - - tokenBuilder.AssertPreparedToAddMoreRuns(3); - tokenBuilder.AssertCurrentRunPosition(runStart); - - do - { - ch = ScanText(ch, ref charClass, ref parseCurrent); - - if (ParseSupport.WhitespaceCharacter(charClass)) - { - if (parseCurrent != runStart) - { - - - tokenBuilder.AddTextRun(RunTextType.NonSpace, runStart, parseCurrent); - runStart = parseCurrent; - } - - if (ch == ' ') - { - var chT = parseBuffer[parseCurrent + 1]; - var charClassT = ParseSupport.GetCharClass(chT); - - if (!ParseSupport.WhitespaceCharacter(charClassT)) - { - - - ch = chT; - charClass = charClassT; - - parseCurrent ++; - - tokenBuilder.AddTextRun(RunTextType.Space, runStart, parseCurrent); - runStart = parseCurrent; - - continue; - } - } - - - - ParseWhitespace(ch, charClass, ref parseCurrent); - - if (parseThreshold > 1) - { - - break; - } - - ch = parseBuffer[parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - else if (ch == '<') - { - - - - if (plaintext || firstRunStart == parseCurrent) - { - - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - - tokenBuilder.AssertPreparedToAddMoreRuns(3); - continue; - } - - - - if (parseCurrent != runStart) - { - - tokenBuilder.AddTextRun(RunTextType.NonSpace, runStart, parseCurrent); - } - - parseState = ParseState.TagStart; - slowParse = literalTags; - - - break; - } - else if (ch == '&') - { - if (literalEntities) - { - - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - - tokenBuilder.AssertPreparedToAddMoreRuns(3); - continue; - } - - - - int literal; - int consume; - - if (DecodeEntity(parseCurrent, false, out literal, out consume)) - { - InternalDebug.Assert(consume != 0); - - if (consume == 1) - { - - - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - - tokenBuilder.AssertPreparedToAddMoreRuns(3); - continue; - } - - - - - if (parseCurrent != runStart) - { - tokenBuilder.AddTextRun(RunTextType.NonSpace, runStart, parseCurrent); - } - - - - - if (literal <= 0xFFFF && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass((char)literal))) - { - - - switch ((char)literal) - { - case ' ': - tokenBuilder.AddLiteralTextRun(RunTextType.Space, parseCurrent, parseCurrent + consume, literal); - break; - - case '\r': - - - - tokenBuilder.AddLiteralTextRun(RunTextType.NewLine, parseCurrent, parseCurrent + consume, literal); - break; - - case '\n': - tokenBuilder.AddLiteralTextRun(RunTextType.NewLine, parseCurrent, parseCurrent + consume, literal); - break; - - case '\t': - tokenBuilder.AddLiteralTextRun(RunTextType.Tabulation, parseCurrent, parseCurrent + consume, literal); - break; - - default: - tokenBuilder.AddLiteralTextRun(RunTextType.UnusualWhitespace, parseCurrent, parseCurrent + consume, literal); - break; - } - } - else - { - if (literal == 0xA0) - { - tokenBuilder.AddLiteralTextRun(RunTextType.Nbsp, parseCurrent, parseCurrent + consume, literal); - } - else - { - tokenBuilder.AddLiteralTextRun(RunTextType.NonSpace, parseCurrent, parseCurrent + consume, literal); - } - } - - parseCurrent += consume; - - ch = parseBuffer[parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - else - { - - - - - - - if (parseCurrent != runStart) - { - tokenBuilder.AddTextRun(RunTextType.NonSpace, runStart, parseCurrent); - } - - - parseThreshold = HtmlNameData.MAX_ENTITY_NAME + 2; - - - break; - } - } - else if (ParseSupport.NbspCharacter(charClass)) - { - if (parseCurrent != runStart) - { - tokenBuilder.AddTextRun(RunTextType.NonSpace, runStart, parseCurrent); - } - - runStart = parseCurrent; - - do - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - while (ParseSupport.NbspCharacter(charClass)); - - tokenBuilder.AddTextRun(RunTextType.Nbsp, runStart, parseCurrent); - } - else - { - InternalDebug.Assert(ParseSupport.InvalidUnicodeCharacter(charClass)); - - - - if (parseCurrent != runStart) - { - tokenBuilder.AddTextRun(RunTextType.NonSpace, runStart, parseCurrent); - } - - if (parseCurrent >= parseEnd) - { - - break; - } - - - - - do - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - while (ParseSupport.InvalidUnicodeCharacter(charClass) && parseCurrent < parseEnd); - } - - - runStart = parseCurrent; - } - while (tokenBuilder.PrepareToAddMoreRuns(3, runStart, HtmlRunKind.Text)); - } - - - private bool ParseAttributeText(char ch, CharClass charClass, ref int parseCurrent) - { - var runStart = parseCurrent; - var parseBuffer = this.parseBuffer; - var tokenBuilder = this.tokenBuilder; - int consume; - - while (true) - { - tokenBuilder.AssertCurrentRunPosition(runStart); - tokenBuilder.AssertPreparedToAddMoreRuns(2); - - ch = ScanAttrValue(ch, ref charClass, ref parseCurrent); - - if (ParseSupport.QuoteCharacter(charClass)) - { - if (ch == scanQuote) - { - scanQuote = '\0'; - } - else if (scanQuote == '\0' && ParseSupport.HtmlScanQuoteSensitiveCharacter(lastCharClass)) - { - scanQuote = ch; - } - - lastCharClass = charClass; - - if (ch == valueQuote) - { - - - break; - } - - - parseCurrent ++; - } - else if (ch == '&') - { - - - lastCharClass = charClass; - - - - - int literal; - - if (DecodeEntity(parseCurrent, true, out literal, out consume)) - { - InternalDebug.Assert(consume != 0); - - if (consume == 1) - { - - - - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - continue; - } - - - - - if (parseCurrent != runStart) - { - tokenBuilder.AddRun(RunTextType.Unknown, HtmlRunKind.AttrValue, runStart, parseCurrent); - } - - tokenBuilder.AddLiteralRun(RunTextType.Unknown, HtmlRunKind.AttrValue, parseCurrent, parseCurrent + consume, literal); - - parseCurrent += consume; - - - if (!tokenBuilder.PrepareToAddMoreRuns(2)) - { - return false; - } - - runStart = parseCurrent; - } - else - { - - - - - parseThreshold = HtmlNameData.MAX_ENTITY_NAME + 2; - - break; - } - } - else if (ch == '>') - { - lastCharClass = charClass; - - if (valueQuote == '\0') - { - break; - } - - if (scanQuote == '\0') - { - - InternalDebug.Assert(valueQuote != 0); - - valueQuote = '\0'; - break; - } - - parseCurrent ++; - } - else if (ParseSupport.WhitespaceCharacter(charClass)) - { - lastCharClass = charClass; - - if (valueQuote == '\0') - { - break; - } - - -#if false - if (parseCurrent != runStart) - { - tokenBuilder.AddRun(RunTextType.NonSpace, HtmlRunKind.AttrValue, runStart, parseCurrent); - } - - - this.ParseWhitespace(ch, charClass, ref parseCurrent); - - runStart = parseCurrent; - - if (this.parseThreshold > 1) - { - - break; - } - - - if (!tokenBuilder.PrepareToAddMoreRuns(2)) - { - return false; - } -#else - parseCurrent ++; -#endif - } - else - { - InternalDebug.Assert(ParseSupport.InvalidUnicodeCharacter(charClass)); - break; - } - - ch = parseBuffer[parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - - if (parseCurrent != runStart) - { - tokenBuilder.AddRun(RunTextType.Unknown, HtmlRunKind.AttrValue, runStart, parseCurrent); - } - - return true; - } - - - private void ParseWhitespace(char ch, CharClass charClass, ref int parseCurrent) - { - CharClass charClassT; - var runStart = parseCurrent; - var parseBuffer = this.parseBuffer; - var tokenBuilder = this.tokenBuilder; - - tokenBuilder.AssertPreparedToAddMoreRuns(1); - tokenBuilder.AssertCurrentRunPosition(runStart); - - InternalDebug.Assert(ParseSupport.WhitespaceCharacter(charClass)); - - - - do - { - switch (ch) - { - case ' ': - do - { - ch = parseBuffer[++parseCurrent]; - } - while (ch == ' '); - - tokenBuilder.AddTextRun(RunTextType.Space, runStart, parseCurrent); - break; - - case '\r': - - if (parseBuffer[parseCurrent + 1] != '\n') - { - charClassT = ParseSupport.GetCharClass(parseBuffer[parseCurrent + 1]); - - if (ParseSupport.InvalidUnicodeCharacter(charClassT)) - { - if (!endOfFile || parseCurrent + 1 < parseEnd) - { - - - - - parseThreshold = 2; - break; - } - - - } - - - } - else - { - - parseCurrent ++; - } - - ch = parseBuffer[++parseCurrent]; - - tokenBuilder.AddTextRun(RunTextType.NewLine, runStart, parseCurrent); - break; - - case '\n': - - - - ch = parseBuffer[++parseCurrent]; - - tokenBuilder.AddTextRun(RunTextType.NewLine, runStart, parseCurrent); - break; - - case '\t': - - do - { - ch = parseBuffer[++parseCurrent]; - } - while (ch == '\t'); - - tokenBuilder.AddTextRun(RunTextType.Tabulation, runStart, parseCurrent); - break; - - default: - - InternalDebug.Assert(ch == '\f' || ch == '\v'); - - do - { - ch = parseBuffer[++parseCurrent]; - } - while (ch == '\f' || ch == '\v'); - - tokenBuilder.AddTextRun(RunTextType.UnusualWhitespace, runStart, parseCurrent); - break; - } - - charClass = ParseSupport.GetCharClass(ch); - - runStart = parseCurrent; - } - while (ParseSupport.WhitespaceCharacter(charClass) && tokenBuilder.PrepareToAddMoreRuns(1) && parseThreshold == 1); - } - - - private bool CheckSuffix(int parseCurrent, char ch, out int addToTextCnt, out int tagSuffixCnt, out bool endScan) - { - InternalDebug.Assert(parseBuffer[parseCurrent] == ch); - - addToTextCnt = 1; - tagSuffixCnt = 0; - endScan = false; - - char chT; - - switch (parseState) - { - case ParseState.Asp: - - if (ch != '%') - { - - return true; - } - - chT = parseBuffer[parseCurrent + 1]; - - if (chT == '>') - { - - - addToTextCnt = 0; - tagSuffixCnt = 2; - endScan = true; - - return true; - } - - if (!ParseSupport.InvalidUnicodeCharacter(ParseSupport.GetCharClass(chT))) - { - - return true; - } - - - - addToTextCnt = 0; - tagSuffixCnt = 1; - - return false; - - case ParseState.Bang: - case ParseState.Dtd: - - if (ch == '>' && scanQuote == '\0') - { - addToTextCnt = 0; - tagSuffixCnt = 1; - endScan = true; - } - - return true; - - case ParseState.Comment: - - if (ch != '-') - { - - return true; - } - - var nonDash = parseCurrent; - - do - { - chT = parseBuffer[++nonDash]; - } - while (chT == '-'); - - if (chT == '>' && nonDash - parseCurrent >= 2) - { - - - if (parseState == ParseState.CommentConditional) - { - parseState = ParseState.Comment; - - tokenBuilder.AbortConditional(true); - } - - addToTextCnt = nonDash - parseCurrent - 2; - tagSuffixCnt = 3; - endScan = true; - - return true; - } - - if (!ParseSupport.InvalidUnicodeCharacter(ParseSupport.GetCharClass(chT))) - { - - - addToTextCnt = nonDash - parseCurrent; - - return true; - } - - - - addToTextCnt = (nonDash - parseCurrent > 2) ? (nonDash - parseCurrent - 2) : 0; - tagSuffixCnt = nonDash - parseCurrent - addToTextCnt; - - return false; - - case ParseState.Conditional: - case ParseState.CommentConditional: - - if (ch == '>') - { - - - - parseState = (parseState == ParseState.CommentConditional) ? ParseState.Comment : ParseState.Bang; - - tokenBuilder.AbortConditional(parseState == ParseState.Comment); - - - return CheckSuffix(parseCurrent, ch, out addToTextCnt, out tagSuffixCnt, out endScan); - } - - if (ch == '-' && parseState == ParseState.CommentConditional) - { - - - goto case ParseState.Comment; - } - - if (ch != ']') - { - return true; - } - - - - - - - - chT = parseBuffer[parseCurrent + 1]; - - if (chT == '>') - { - - - addToTextCnt = 0; - tagSuffixCnt = 2; - endScan = true; - - return true; - } - - var numOkChars = 1; - - if (chT == '-') - { - numOkChars ++; - - chT = parseBuffer[parseCurrent + 2]; - - if (chT == '-') - { - numOkChars ++; - - chT = parseBuffer[parseCurrent + 3]; - - if (chT == '>') - { - - - addToTextCnt = 0; - tagSuffixCnt = 4; - endScan = true; - - return true; - } - } - } - - if (!ParseSupport.InvalidUnicodeCharacter(ParseSupport.GetCharClass(chT))) - { - addToTextCnt = numOkChars; - - return true; - } - - addToTextCnt = 0; - tagSuffixCnt = numOkChars; - - return false; - - default: - InternalDebug.Assert(false); - break; - } - - return true; - } - - - private bool DecodeEntity(int parseCurrent, bool inAttribute, out int literal, out int consume) - { - - - - - - - - - - - - - - - - - - - - - - - - var parseBuffer = this.parseBuffer; - - InternalDebug.Assert(parseBuffer[parseCurrent] == '&'); - - char chT; - CharClass charClassT; - var entityStart = parseCurrent + 1; - var entityCurrent = entityStart; - var charCount = 0; - var entityValue = 0; - - chT = parseBuffer[entityCurrent]; - charClassT = ParseSupport.GetCharClass(chT); - - if (chT == '#') - { - - - chT = parseBuffer[++entityCurrent]; - charClassT = ParseSupport.GetCharClass(chT); - - if (chT == 'x' || chT == 'X') - { - - - chT = parseBuffer[++entityCurrent]; - charClassT = ParseSupport.GetCharClass(chT); - - while (ParseSupport.HexCharacter(charClassT)) - { - charCount ++; - entityValue = (entityValue << 4) + ParseSupport.CharToHex(chT); - - chT = parseBuffer[++entityCurrent]; - charClassT = ParseSupport.GetCharClass(chT); - } - - - - - - - - - - - - - - if (!ParseSupport.InvalidUnicodeCharacter(charClassT) || - (endOfFile && entityCurrent >= parseEnd) || - charCount > 6) - { - if ((inAttribute || chT == ';') && entityValue != 0 && charCount <= 6) - { - ProcessNumericEntityValue(entityValue, out literal); - - consume = entityCurrent - parseCurrent; - - if (chT == ';') - { - consume ++; - } - - return true; - } - else - { - - - - - literal = 0; - consume = 1; - - return true; - } - } - - - - - } - else - { - - - while (ParseSupport.NumericCharacter(charClassT)) - { - charCount ++; - entityValue = (entityValue * 10) + ParseSupport.CharToDecimal(chT); - - entityCurrent ++; - - chT = parseBuffer[entityCurrent]; - charClassT = ParseSupport.GetCharClass(chT); - } - - - - - - if (!ParseSupport.InvalidUnicodeCharacter(charClassT) || - (endOfFile && entityCurrent >= parseEnd) || - charCount > 7) - { - if (entityValue != 0 && charCount <= 7) - { - - - ProcessNumericEntityValue(entityValue, out literal); - - consume = entityCurrent - parseCurrent; - - if (chT == ';') - { - - consume ++; - } - - return true; - } - else - { - - - literal = 0; - consume = 1; - - return true; - } - } - - - - } - } - else - { - var hashValues = hashValuesTable; - if (hashValues == null) - { - hashValues = hashValuesTable = new short[HtmlNameData.MAX_ENTITY_NAME]; - } - - var hashCode = new HashCode(true); - short hashValue; - int entityValueT; - - while (ParseSupport.HtmlEntityCharacter(charClassT) && charCount < HtmlNameData.MAX_ENTITY_NAME) - { - hashValue = (short)(((uint)hashCode.AdvanceAndFinalizeHash(chT) ^ HtmlNameData.ENTITY_HASH_MODIFIER) % HtmlNameData.ENTITY_HASH_SIZE); - hashValues[charCount++] = hashValue; - - entityCurrent ++; - - chT = parseBuffer[entityCurrent]; - charClassT = ParseSupport.GetCharClass(chT); - } - - if (!ParseSupport.InvalidUnicodeCharacter(charClassT) || (endOfFile && entityCurrent >= parseEnd)) - { - - - - - - - - - if (charCount > 1) - { - if (FindEntityByHashName(hashValues[charCount - 1], parseBuffer, entityStart, charCount, out entityValueT) && - (chT == ';' || entityValueT <= 255)) - { - - - entityValue = entityValueT; - } - else if (!inAttribute) - { - for (var i = charCount - 2; i >= 0; i--) - { - if (FindEntityByHashName(hashValues[i], parseBuffer, entityStart, i + 1, out entityValueT) && - entityValueT <= 255) - { - - - entityValue = entityValueT; - charCount = i + 1; - break; - } - } - } - - if (entityValue != 0) - { - - InternalDebug.Assert(entityValue <= 0xFFFF); - - literal = entityValue; - consume = charCount + 1; - - if (parseBuffer[entityStart + charCount] == ';') - { - consume ++; - } - - return true; - } - } - - - - literal = 0; - consume = 1; - - return true; - } - } - - literal = 0; - consume = 0; - - return false; - } - - - private void HandleSpecialTag() - { - if (HtmlNameData.names[(int)token.NameIndex].literalTag) - { - literalTags = !token.IsEndTag; - literalTagNameId = literalTags ? token.NameIndex : HtmlNameIndex.Unknown; - - if (HtmlNameData.names[(int)token.NameIndex].literalEnt) - { - - - - - - - - - - - literalEntities = !(token.IsEndTag || token.IsEmptyScope); - } - - slowParse = slowParse || literalTags; - } - - switch (token.NameIndex) - { - case HtmlNameIndex.Meta: - - if (input is ConverterDecodingInput && detectEncodingFromMetaTag && ((IRestartable)this).CanRestart()) - { - - - - - - - - - - - if (token.IsTagBegin) - { - rightMeta = false; - newEncoding = null; - } - - token.Attributes.Rewind(); - - var attrToParse = -1; - var isHttpEquivContent = false; - - foreach (var attr in token.Attributes) - { - if (attr.NameIndex == HtmlNameIndex.HttpEquiv) - { - if (attr.Value.CaseInsensitiveCompareEqual("content-type") || - attr.Value.CaseInsensitiveCompareEqual("charset")) - { - rightMeta = true; - if (attrToParse != -1) - { - break; - } - } - else - { - - break; - } - } - else if (attr.NameIndex == HtmlNameIndex.Content) - { - attrToParse = attr.Index; - isHttpEquivContent = true; - if (rightMeta) - { - break; - } - } - else if (attr.NameIndex == HtmlNameIndex.Charset) - { - attrToParse = attr.Index; - isHttpEquivContent = false; - rightMeta = true; - break; - } - } - - if (attrToParse != -1) - { - var strToParse = token.Attributes[attrToParse].Value.GetString(100); - var charset = CharsetFromString(strToParse, isHttpEquivContent); - - if (charset != null) - { - Charset.TryGetEncoding(charset, out newEncoding); - - - - - } - } - - if (rightMeta && newEncoding != null) - { - (input as ConverterDecodingInput).RestartWithNewEncoding(newEncoding); - } - - token.Attributes.Rewind(); - } - break; - - case HtmlNameIndex.PlainText: - - if (!token.IsEndTag) - { - - - - - plaintext = true; - literalEntities = true; - - if (token.IsTagEnd) - { - - - - parseState = ParseState.Text; - } - } - - break; - } - } - - - private static string CharsetFromString(string arg, bool lookForWordCharset) - { - var i = 0; - - while (i < arg.Length) - { - - while (i < arg.Length && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(arg[i]))) - { - i ++; - } - - if (i == arg.Length) - { - break; - } - - if (!lookForWordCharset || - (arg.Length - i >= 7 && string.Equals(arg.Substring(i, 7), "charset", StringComparison.OrdinalIgnoreCase))) - { - if (lookForWordCharset) - { - i = arg.IndexOf('=', i + 7); - - if (i < 0) - { - break; - } - - i ++; - - - while (i < arg.Length && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(arg[i]))) - { - i ++; - } - - if (i == arg.Length) - { - break; - } - } - - var j = i; - - while (j < arg.Length && arg[j] != ';' && !ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(arg[j]))) - { - j ++; - } - - return arg.Substring(i, j - i); - } - - i = arg.IndexOf(';', i); - - if (i < 0) - { - break; - } - - i ++; - } - - return null; - } - } -} - diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlReader.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlReader.cs deleted file mode 100644 index e4506b56a..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlReader.cs +++ /dev/null @@ -1,2054 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters -{ - using System; - using System.IO; - using System.Text; - using Data.Internal; - using Internal.Html; - - using Strings = CtsResources.TextConvertersStrings; - - - - - - - internal enum HtmlTokenKind - { - - Text, - - - StartTag, - - EndTag, - - - - - - - - - EmptyElementTag, - -#if PRIVATEBUILD - - - - - - EmptyScopeMark, -#endif - - - - - SpecialTag, - -#if PRIVATEBUILD - - - - Restart, -#endif - - - - - - - - - - - - - - - - - - - - - OverlappedClose, - - OverlappedReopen, - } - - - - - - internal class HtmlReader : IRestartable, IResultsFeedback, IDisposable - { - - - private Encoding inputEncoding; - private bool detectEncodingFromByteOrderMark; -#if PRIVATEBUILD - private bool detectEncodingFromMetaTag; - private bool detectEncodingFromXmlDeclaration; -#endif - private bool normalizeInputHtml; - - internal bool testBoundaryConditions = false; - internal int inputBufferSize = 4096; - - private Stream testTraceStream = null; - private bool testTraceShowTokenNum = true; - private int testTraceStopOnTokenNum = 0; - - private Stream testNormalizerTraceStream = null; - private bool testNormalizerTraceShowTokenNum = true; - private int testNormalizerTraceStopOnTokenNum = 0; - - private bool locked; - - - - private object input; - - private IHtmlParser parser; - - private HtmlTokenId parserTokenId; - private HtmlToken parserToken; - - private HtmlToken nextParserToken; - - private int depth; - - private StringBuildSink stringBuildSink; - - private int currentAttribute; - - private bool literalTags; - - private enum State : byte - { - Disposed, - EndOfFile, - Begin, - - Text, - EndText, - - OverlappedClose, - OverlappedReopen, - - SpecialTag, - EndSpecialTag, -#if PRIVATEBUILD - EmptyScopeMark, -#endif - BeginTag, - ReadTagName, - EndTagName, - BeginAttribute, - ReadAttributeName, - EndAttributeName, - BeginAttributeValue, - ReadAttributeValue, - EndAttribute, - ReadTag, - EndTag, - } - - private State state; - private HtmlTokenKind tokenKind; - - - - - - - - - public HtmlReader(Stream input, Encoding inputEncoding) - { - if (input == null) - { - throw new ArgumentNullException("input"); - } - - if (!input.CanRead) - { - throw new ArgumentException("input stream must support reading"); - } - - this.input = input; - this.inputEncoding = inputEncoding; - state = State.Begin; - } - - - - - - - - public HtmlReader(TextReader input) - { - if (input == null) - { - throw new ArgumentNullException("input"); - } - - this.input = input; - inputEncoding = Encoding.Unicode; - state = State.Begin; - } - - - - - - - - - - - - - - public Encoding InputEncoding - { - get { return inputEncoding; } - set { AssertNotLocked(); inputEncoding = value; } - } - - - - - - - - - - public bool DetectEncodingFromByteOrderMark - { - get { return detectEncodingFromByteOrderMark; } - set { AssertNotLocked(); detectEncodingFromByteOrderMark = value; } - } -#if PRIVATEBUILD - - - - - - - - - - - - public bool DetectEncodingFromMetaTag - { - get { return this.detectEncodingFromMetaTag; } - set { this.AssertNotLocked(); this.detectEncodingFromMetaTag = value; } - } - - - - - public bool DetectEncodingFromXmlDeclaration - { - get { return this.detectEncodingFromXmlDeclaration; } - set { this.AssertNotLocked(); this.detectEncodingFromXmlDeclaration = value; } - } -#endif - - - - - - - - - public bool NormalizeHtml - { - get { return normalizeInputHtml; } - set { AssertNotLocked(); normalizeInputHtml = value; } - } - - - - - - - - - - - public HtmlTokenKind TokenKind - { - get - { - AssertInToken(); - return tokenKind; - } - } - - - - - - - - - public bool ReadNextToken() - { - AssertNotDisposed(); - - if (state == State.EndOfFile) - { - return false; - } - - if (!locked) - { - InitializeAndLock(); - } - - if (state == State.Text) - { - InternalDebug.Assert(parserTokenId == HtmlTokenId.Text || (literalTags && parserTokenId == HtmlTokenId.Tag && parserToken.TagIndex < HtmlTagIndex.Unknown)); - - - - do - { - ParseToken(); - } - while (parserTokenId == HtmlTokenId.Text || - (literalTags && parserTokenId == HtmlTokenId.Tag && parserToken.TagIndex < HtmlTagIndex.Unknown)); - } - else if (state >= State.SpecialTag) - { - InternalDebug.Assert(parserTokenId == HtmlTokenId.Tag); - - - - - while (!parserToken.IsTagEnd) - { - ParseToken(); - } -#if PRIVATEBUILD - if (HtmlDtd.tags[(int)this.parserToken.TagIndex].scope != HtmlDtd.TagScope.EMPTY && this.parserToken.IsEmptyScope) - { - - - if (this.state != State.EmptyScopeMark) - { - - - this.state = State.EmptyScopeMark; - this.tokenKind = HtmlTokenKind.EmptyScopeMark; - return true; - } - } -#endif - if (parserToken.TagIndex <= HtmlTagIndex.Unknown || - parserToken.IsEndTag || - HtmlDtd.tags[(int)parserToken.TagIndex].scope == HtmlDtd.TagScope.EMPTY || - parserToken.IsEmptyScope) - { - - } - else - { - - depth ++; - } - - if (!parserToken.IsEndTag && - 0 != (HtmlDtd.tags[(int)parserToken.TagIndex].literal & HtmlDtd.Literal.Tags)) - { - literalTags = true; - } - - ParseToken(); - } - else - { - - - if (state == State.OverlappedClose) - { - - depth -= parserToken.Argument; - } - - ParseToken(); - } - - while (true) - { - switch (parserTokenId) - { - case HtmlTokenId.Text: - - state = State.Text; - tokenKind = HtmlTokenKind.Text; - - parserToken.Text.Rewind(); - break; - - case HtmlTokenId.Tag: - - InternalDebug.Assert(parserToken.IsTagBegin); - - if (parserToken.TagIndex < HtmlTagIndex.Unknown) - { - if (literalTags) - { - - state = State.Text; - tokenKind = HtmlTokenKind.Text; - } - else - { - state = State.SpecialTag; - tokenKind = HtmlTokenKind.SpecialTag; - } - - parserToken.Text.Rewind(); - } - else - { - if (parserToken.TagIndex == HtmlTagIndex.TC) - { - - - - - InternalDebug.Assert(parserToken.IsTagEnd); - - ParseToken(); - continue; - } - - if (parserToken.IsTagNameEmpty && parserToken.TagIndex == HtmlTagIndex.Unknown) - { - - - - InternalDebug.Assert(parserToken.IsEndTag); - - state = State.SpecialTag; - tokenKind = HtmlTokenKind.SpecialTag; - - parserToken.Text.Rewind(); - } - else - { - state = State.BeginTag; - - if (parserToken.IsEndTag) - { - tokenKind = HtmlTokenKind.EndTag; - - if (0 != (HtmlDtd.tags[(int)parserToken.TagIndex].literal & HtmlDtd.Literal.Tags)) - { - literalTags = false; - } - } - else if (parserToken.TagIndex > HtmlTagIndex.Unknown && - HtmlDtd.tags[(int)parserToken.TagIndex].scope == HtmlDtd.TagScope.EMPTY) - { - tokenKind = HtmlTokenKind.EmptyElementTag; - } - else - { - tokenKind = HtmlTokenKind.StartTag; - } - - parserToken.Text.Rewind(); - - - - - if (parserToken.IsEndTag && parserToken.TagIndex != HtmlTagIndex.Unknown) - { - depth --; - } - } - } - break; - - case HtmlTokenId.OverlappedClose: - - - - - - state = State.OverlappedClose; - tokenKind = HtmlTokenKind.OverlappedClose; - break; - - case HtmlTokenId.OverlappedReopen: - - - - - depth += parserToken.Argument; - - state = State.OverlappedReopen; - tokenKind = HtmlTokenKind.OverlappedReopen; - break; - - case HtmlTokenId.EncodingChange: - - - - ParseToken(); - continue; - - case HtmlTokenId.Restart: - -#if PRIVATEBUILD - - this.state = State.Begin; - this.tokenKind = HtmlTokenKind.Restart; - break; -#else - InternalDebug.Assert(false); - continue; -#endif - default: - - InternalDebug.Assert(parserTokenId == HtmlTokenId.EndOfFile); - - state = State.EndOfFile; - return false; - } - - break; - } - - return true; - } - - - - - - - - - - - public int Depth - { - get - { - AssertNotDisposed(); - return depth; - } - } - - - - - - - public int OverlappedDepth - { - get - { - if (state != State.OverlappedClose && state != State.OverlappedReopen) - { - AssertInToken(); - throw new InvalidOperationException("Reader must be positioned on OverlappedClose or OverlappedReopen token"); - } - - InternalDebug.Assert(parserTokenId == HtmlTokenId.OverlappedClose || parserTokenId == HtmlTokenId.OverlappedReopen); - InternalDebug.Assert(tokenKind == HtmlTokenKind.OverlappedClose || tokenKind == HtmlTokenKind.OverlappedReopen); - - return parserToken.Argument; - } - } - - - - - - - - - public HtmlTagId TagId - { - get - { - AssertInTag(); - return HtmlNameData.names[(int)parserToken.NameIndex].publicTagId; - } - } - - - - - - - - - public bool TagInjectedByNormalizer - { - get - { - AssertInTag(); - - if (state != State.BeginTag) - { - throw new InvalidOperationException("Reader must be positioned at the beginning of a StartTag, EndTag or EmptyElementTag token"); - } - - InternalDebug.Assert(parserTokenId == HtmlTokenId.Tag); - - return parserToken.Argument == 1; - } - } - - - - - - - - - - - public bool TagNameIsLong - { - get - { - AssertInTag(); - - if (state != State.BeginTag) - { - throw new InvalidOperationException("Reader must be positioned at the beginning of a StartTag, EndTag or EmptyElementTag token"); - } - - InternalDebug.Assert(parserTokenId == HtmlTokenId.Tag); - - return parserToken.NameIndex == HtmlNameIndex.Unknown && parserToken.IsTagNameBegin && !parserToken.IsTagNameEnd; - } - } - - - - - - - - - - - - - - public string ReadTagName() - { - if (state != State.BeginTag) - { - AssertInTag(); - throw new InvalidOperationException("Reader must be positioned at the beginning of a StartTag, EndTag or EmptyElementTag token"); - } - - InternalDebug.Assert(parserTokenId == HtmlTokenId.Tag && parserToken.IsTagBegin); - - string name; - - if (parserToken.NameIndex != HtmlNameIndex.Unknown) - { - - name = HtmlNameData.names[(int)parserToken.NameIndex].name; - } - else - { - InternalDebug.Assert(parserTokenId == HtmlTokenId.Tag && parserToken.IsTagBegin && parserToken.NameIndex == HtmlNameIndex.Unknown); - - if (parserToken.IsTagNameEnd) - { - return parserToken.Name.GetString(int.MaxValue); - } - - InternalDebug.Assert(!parserToken.IsTagEnd); - - var sbSink = GetStringBuildSink(); - - parserToken.Name.WriteTo(sbSink); - - do - { - ParseToken(); - - parserToken.Name.WriteTo(sbSink); - } - while (!parserToken.IsTagNameEnd); - - name = sbSink.ToString(); - } - - - state = State.EndTagName; - - - return name; - } - - - - - - - - - - - - - - - public int ReadTagName(char[] buffer, int offset, int count) - { - AssertInTag(); - if (state > State.EndTagName) - { - throw new InvalidOperationException("Reader must be positioned at the beginning of a StartTag, EndTag or EmptyElementTag token"); - } - - if (null == buffer) - { - throw new ArgumentNullException("buffer"); - } - - if (offset > buffer.Length || offset < 0) - { - throw new ArgumentOutOfRangeException("offset", Strings.OffsetOutOfRange); - } - - if (count > buffer.Length || count < 0) - { - throw new ArgumentOutOfRangeException("count", Strings.CountOutOfRange); - } - - if (count + offset > buffer.Length) - { - throw new ArgumentOutOfRangeException("count", Strings.CountTooLarge); - } - - var lengthRead = 0; - - if (state != State.EndTagName) - { - if (state == State.BeginTag) - { - state = State.ReadTagName; - parserToken.Name.Rewind(); - } - - while (count != 0) - { - var chunkLength = parserToken.Name.Read(buffer, offset, count); - - if (chunkLength == 0) - { - if (parserToken.IsTagNameEnd) - { - state = State.EndTagName; - break; - } - - ParseToken(); - parserToken.Name.Rewind(); - continue; - } - - offset += chunkLength; - count -= chunkLength; - lengthRead += chunkLength; - } - } - - return lengthRead; - } - - - internal void WriteTagNameTo(ITextSink sink) - { - if (state != State.BeginTag) - { - AssertInTag(); - throw new InvalidOperationException("Reader must be positioned at the beginning of a StartTag, EndTag or EmptyElementTag token"); - } - - while (true) - { - parserToken.Name.WriteTo(sink); - - if (parserToken.IsTagNameEnd) - { - state = State.EndTagName; - break; - } - - ParseToken(); - } - } - - - - - - - - public HtmlAttributeReader AttributeReader - { - get - { - AssertInTag(); - if (state == State.ReadTag) - { - throw new InvalidOperationException("Cannot read attributes after reading tag as a markup text"); - } - - return new HtmlAttributeReader(this); - } - } - - - - - - - - - - public int ReadText(char[] buffer, int offset, int count) - { - if (state == State.EndText) - { - return 0; - } - - if (null == buffer) - { - throw new ArgumentNullException("buffer"); - } - - if (offset > buffer.Length || offset < 0) - { - throw new ArgumentOutOfRangeException("offset", Strings.OffsetOutOfRange); - } - - if (count > buffer.Length || count < 0) - { - throw new ArgumentOutOfRangeException("count", Strings.CountOutOfRange); - } - - if (count + offset > buffer.Length) - { - throw new ArgumentOutOfRangeException("count", Strings.CountTooLarge); - } - - if (state != State.Text) - { - AssertInToken(); - throw new InvalidOperationException("Reader must be positioned on a Text token"); - } - - var lengthRead = 0; - - while (count != 0) - { - var chunkLength = parserToken.Text.Read(buffer, offset, count); - - if (chunkLength == 0) - { - var nextToken = PreviewNextToken(); - - if (nextToken != HtmlTokenId.Text && - (!literalTags || nextToken != HtmlTokenId.Tag || nextParserToken.TagIndex >= HtmlTagIndex.Unknown)) - { - state = State.EndText; - break; - } - - ParseToken(); - parserToken.Text.Rewind(); - continue; - } - - offset += chunkLength; - count -= chunkLength; - lengthRead += chunkLength; - } - - return lengthRead; - } - - - internal void WriteTextTo(ITextSink sink) - { - if (state != State.Text) - { - AssertInToken(); - throw new InvalidOperationException("Reader must be positioned on a Text token"); - } - - while (true) - { - parserToken.Text.WriteTo(sink); - - var nextToken = PreviewNextToken(); - - if (nextToken != HtmlTokenId.Text && - (!literalTags || nextToken != HtmlTokenId.Tag || nextParserToken.TagIndex >= HtmlTagIndex.Unknown)) - { - state = State.EndText; - break; - } - - ParseToken(); - } - } - - - - - - - - - - - - public int ReadMarkupText(char[] buffer, int offset, int count) - { - if (state == State.EndTag || state == State.EndSpecialTag || state == State.EndText) - { - return 0; - } - - if (null == buffer) - { - throw new ArgumentNullException("buffer"); - } - - if (offset > buffer.Length || offset < 0) - { - throw new ArgumentOutOfRangeException("offset", Strings.OffsetOutOfRange); - } - - if (count > buffer.Length || count < 0) - { - throw new ArgumentOutOfRangeException("count", Strings.CountOutOfRange); - } - - if (count + offset > buffer.Length) - { - throw new ArgumentOutOfRangeException("count", Strings.CountTooLarge); - } - - if (state == State.BeginTag) - { - state = State.ReadTag; - } - else if (state != State.SpecialTag && state != State.ReadTag && state != State.Text) - { - AssertInToken(); - - if (state > State.BeginTag) - { - throw new InvalidOperationException("Cannot read tag content as markup text after accessing tag name or attributes"); - } - - throw new InvalidOperationException("Reader must be positioned on Text, StartTag, EndTag, EmptyElementTag or SpecialTag token"); - } - - var lengthRead = 0; - - while (count != 0) - { - var chunkLength = parserToken.Text.ReadOriginal(buffer, offset, count); - - if (chunkLength == 0) - { - if (state == State.SpecialTag) - { - if (parserToken.IsTagEnd) - { - state = State.EndSpecialTag; - break; - } - } - else if (state == State.ReadTag) - { - if (parserToken.IsTagEnd) - { - state = State.EndTag; - break; - } - } - else - { - var nextToken = PreviewNextToken(); - - if (nextToken != HtmlTokenId.Text && - (!literalTags || nextToken != HtmlTokenId.Tag || nextParserToken.TagIndex >= HtmlTagIndex.Unknown)) - { - state = State.EndText; - break; - } - } - - ParseToken(); - parserToken.Text.Rewind(); - continue; - } - - offset += chunkLength; - count -= chunkLength; - lengthRead += chunkLength; - } - - return lengthRead; - } - - - internal void WriteMarkupTextTo(ITextSink sink) - { - if (state == State.BeginTag) - { - state = State.ReadTag; - } - else if (state != State.SpecialTag && state != State.ReadTag && state != State.Text) - { - AssertInToken(); - - if (state > State.BeginTag) - { - throw new InvalidOperationException("Cannot read tag content as markup text after accessing tag name or attributes"); - } - - throw new InvalidOperationException("Reader must be positioned on Text, StartTag, EndTag, EmptyElementTag or SpecialTag token"); - } - - while (true) - { - parserToken.Text.WriteOriginalTo(sink); - - if (state == State.SpecialTag) - { - if (parserToken.IsTagEnd) - { - state = State.EndSpecialTag; - break; - } - } - else if (state == State.ReadTag) - { - if (parserToken.IsTagEnd) - { - state = State.EndTag; - break; - } - } - else - { - var nextToken = PreviewNextToken(); - - if (nextToken != HtmlTokenId.Text && - (!literalTags || nextToken != HtmlTokenId.Tag || nextParserToken.TagIndex >= HtmlTagIndex.Unknown)) - { - state = State.EndText; - break; - } - } - - ParseToken(); - } - } - - - - - - - - - public void Close() - { - Dispose(true); - } - - - void IDisposable.Dispose() - { - Dispose(true); - } - - - - - - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - - if (parser != null && parser is IDisposable) - { - ((IDisposable)parser).Dispose(); - } - - if (input != null && input is IDisposable) - { - ((IDisposable)input).Dispose(); - } - - GC.SuppressFinalize(this); - } - - parser = null; - input = null; - stringBuildSink = null; - parserToken = null; - nextParserToken = null; - state = State.Disposed; - } - - - - internal HtmlReader SetInputEncoding(Encoding value) - { - InputEncoding = value; - return this; - } - - internal HtmlReader SetDetectEncodingFromByteOrderMark(bool value) - { - DetectEncodingFromByteOrderMark = value; - return this; - } - -#if PRIVATEBUILD - internal HtmlReader SetDetectEncodingFromMetaTag(bool value) - { - this.DetectEncodingFromMetaTag = value; - return this; - } -#endif - internal HtmlReader SetNormalizeHtml(bool value) - { - NormalizeHtml = value; - return this; - } - - internal HtmlReader SetTestBoundaryConditions(bool value) - { - testBoundaryConditions = value; - return this; - } - - internal HtmlReader SetTestTraceStream(Stream value) - { - testTraceStream = value; - return this; - } - - internal HtmlReader SetTestTraceShowTokenNum(bool value) - { - testTraceShowTokenNum = value; - return this; - } - - internal HtmlReader SetTestTraceStopOnTokenNum(int value) - { - testTraceStopOnTokenNum = value; - return this; - } - - internal HtmlReader SetTestNormalizerTraceStream(Stream value) - { - testNormalizerTraceStream = value; - return this; - } - - internal HtmlReader SetTestNormalizerTraceShowTokenNum(bool value) - { - testNormalizerTraceShowTokenNum = value; - return this; - } - - internal HtmlReader SetTestNormalizerTraceStopOnTokenNum(int value) - { - testNormalizerTraceStopOnTokenNum = value; - return this; - } - - - private void InitializeAndLock() - { - locked = true; - - ConverterInput converterInput; - - if (input is Stream) - { - if (inputEncoding == null) - { - throw new InvalidOperationException(Strings.InputEncodingRequired); - } - - converterInput = new ConverterDecodingInput( - (Stream)input, - false, - inputEncoding, - detectEncodingFromByteOrderMark, - - TextConvertersDefaults.MaxTokenSize(testBoundaryConditions), - TextConvertersDefaults.MaxHtmlMetaRestartOffset(testBoundaryConditions), - - inputBufferSize, - testBoundaryConditions, - this as IResultsFeedback, - null); - } - else - { - converterInput = new ConverterUnicodeInput( - input, - false, - - TextConvertersDefaults.MaxTokenSize(testBoundaryConditions), - testBoundaryConditions, - null); - - } - - var preParser = new HtmlParser( - converterInput, -#if PRIVATEBUILD - this.detectEncodingFromMetaTag, -#else - false, -#endif - false, - - TextConvertersDefaults.MaxTokenRuns(testBoundaryConditions), - - TextConvertersDefaults.MaxHtmlAttributes(testBoundaryConditions), - testBoundaryConditions); - - if (normalizeInputHtml) - { - parser = new HtmlNormalizingParser( - preParser, - null, - false, - TextConvertersDefaults.MaxHtmlNormalizerNesting(testBoundaryConditions), - testBoundaryConditions, - testNormalizerTraceStream, - testNormalizerTraceShowTokenNum, - testNormalizerTraceStopOnTokenNum); - } - else - { - parser = preParser; - } - -#if PRIVATEBUILD - if (this.detectEncodingFromMetaTag) - { - this.parser.SetRestartConsumer(this); - } -#endif - } - - - bool IRestartable.CanRestart() - { - return false; - } - - - void IRestartable.Restart() - { - } - - - void IRestartable.DisableRestart() - { - } - - - void IResultsFeedback.Set(ConfigParameter parameterId, object val) - { - switch (parameterId) - { - case ConfigParameter.InputEncoding: - inputEncoding = (Encoding) val; - break; - } - } - - - private void ParseToken() - { - if (nextParserToken != null) - { - parserToken = nextParserToken; - parserTokenId = parserToken.TokenId; - nextParserToken = null; - return; - } - - parserTokenId = parser.Parse(); - parserToken = parser.Token; - - } - - - private HtmlTokenId PreviewNextToken() - { - if (nextParserToken == null) - { - parser.Parse(); - nextParserToken = parser.Token; - - } - - return nextParserToken.TokenId; - } - - - private StringBuildSink GetStringBuildSink() - { - if (stringBuildSink == null) - { - stringBuildSink = new StringBuildSink(); - } - - stringBuildSink.Reset(int.MaxValue); - return stringBuildSink; - } - - - internal bool AttributeReader_ReadNextAttribute() - { - if (state == State.EndTag) - { - return false; - } - - AssertInTag(); - - if (state == State.ReadTag) - { - throw new InvalidOperationException("Cannot read attributes after reading tag as markup text"); - } - - do - { - if (state >= State.BeginTag && - state < State.BeginAttribute) - { - - - while (parserToken.Attributes.Count == 0 && !parserToken.IsTagEnd) - { - ParseToken(); - } - - if (parserToken.Attributes.Count == 0) - { - InternalDebug.Assert(parserToken.IsTagEnd); - - state = State.EndTag; - return false; - } - - currentAttribute = 0; - InternalDebug.Assert(parserToken.Attributes[0].IsAttrBegin); - - state = State.BeginAttribute; - } - else - { - InternalDebug.Assert(currentAttribute < parserToken.Attributes.Count); - - if (++currentAttribute == parserToken.Attributes.Count) - { - - - if (parserToken.IsTagEnd) - { - state = State.EndTag; - return false; - } - - while (true) - { - ParseToken(); - - InternalDebug.Assert(!parserToken.IsTagBegin); - - if (parserToken.Attributes.Count != 0 && (parserToken.Attributes[0].IsAttrBegin || parserToken.Attributes.Count > 1)) - { - - break; - } - - - if (parserToken.IsTagEnd) - { - state = State.EndTag; - return false; - } - } - - currentAttribute = 0; - - if (!parserToken.Attributes[0].IsAttrBegin) - { - - - currentAttribute++; - InternalDebug.Assert(currentAttribute < parserToken.Attributes.Count); - } - } - } - - - - - if (!parserToken.Attributes[currentAttribute].IsAttrEmptyName) - { - break; - } - } - while (true); - - state = State.BeginAttribute; - return true; - } - - - internal HtmlAttributeId AttributeReader_GetCurrentAttributeId() - { - AssertInAttribute(); - - return HtmlNameData.names[(int)parserToken.Attributes[currentAttribute].NameIndex].publicAttributeId; - } - - - internal bool AttributeReader_CurrentAttributeNameIsLong() - { - if (state != State.BeginAttribute) - { - AssertInAttribute(); - throw new InvalidOperationException(); - } - - return parserToken.Attributes[currentAttribute].NameIndex == HtmlNameIndex.Unknown && - parserToken.Attributes[currentAttribute].IsAttrBegin && !parserToken.Attributes[currentAttribute].IsAttrNameEnd; - } - - - internal string AttributeReader_ReadCurrentAttributeName() - { - if (state != State.BeginAttribute) - { - AssertInAttribute(); - throw new InvalidOperationException("Reader must be positioned at the beginning of attribute."); - } - - InternalDebug.Assert(parserToken.Attributes[currentAttribute].IsAttrBegin); - - string name; - - if (parserToken.Attributes[currentAttribute].NameIndex != HtmlNameIndex.Unknown) - { - - name = HtmlNameData.names[(int)parserToken.Attributes[currentAttribute].NameIndex].name; - } - else - { - InternalDebug.Assert(parserToken.Attributes[currentAttribute].IsAttrBegin && parserToken.Attributes[currentAttribute].NameIndex == HtmlNameIndex.Unknown); - - if (parserToken.Attributes[currentAttribute].IsAttrNameEnd) - { - return parserToken.Attributes[currentAttribute].Name.GetString(int.MaxValue); - } - - InternalDebug.Assert(!parserToken.IsTagEnd && !parserToken.Attributes[currentAttribute].IsAttrEnd); - - var sbSink = GetStringBuildSink(); - - parserToken.Attributes[currentAttribute].Name.WriteTo(sbSink); - - do - { - ParseToken(); - - InternalDebug.Assert(!parserToken.IsTagBegin && - parserToken.Attributes.Count != 0 && - !parserToken.Attributes[0].IsAttrBegin); - - currentAttribute = 0; - - parserToken.Attributes[currentAttribute].Name.WriteTo(sbSink); - } - while (!parserToken.Attributes[0].IsAttrNameEnd); - - name = sbSink.ToString(); - } - - - state = State.EndAttributeName; - - - return name; - } - - - internal int AttributeReader_ReadCurrentAttributeName(char[] buffer, int offset, int count) - { - if (null == buffer) - { - throw new ArgumentNullException("buffer"); - } - - if (offset > buffer.Length || offset < 0) - { - throw new ArgumentOutOfRangeException("offset", Strings.OffsetOutOfRange); - } - - if (count > buffer.Length || count < 0) - { - throw new ArgumentOutOfRangeException("count", Strings.CountOutOfRange); - } - - if (count + offset > buffer.Length) - { - throw new ArgumentOutOfRangeException("count", Strings.CountTooLarge); - } - - if (state < State.BeginAttribute || state > State.EndAttributeName) - { - AssertInAttribute(); - throw new InvalidOperationException("Reader must be positioned at the beginning of attribute."); - } - - var lengthRead = 0; - - if (state != State.EndAttributeName) - { - if (state == State.BeginAttribute) - { - state = State.ReadAttributeName; - parserToken.Attributes[currentAttribute].Name.Rewind(); - } - - while (count != 0) - { - var chunkLength = parserToken.Attributes[currentAttribute].Name.Read(buffer, offset, count); - - if (chunkLength == 0) - { - if (parserToken.Attributes[currentAttribute].IsAttrNameEnd) - { - state = State.EndAttributeName; - break; - } - - ParseToken(); - - InternalDebug.Assert(!parserToken.IsTagBegin && - parserToken.Attributes.Count != 0 && - !parserToken.Attributes[0].IsAttrBegin); - - currentAttribute = 0; - parserToken.Attributes[currentAttribute].Name.Rewind(); - continue; - } - - offset += chunkLength; - count -= chunkLength; - lengthRead += chunkLength; - } - } - - return lengthRead; - } - - - internal void AttributeReader_WriteCurrentAttributeNameTo(ITextSink sink) - { - if (state != State.BeginAttribute) - { - AssertInAttribute(); - throw new InvalidOperationException("Reader must be positioned at the beginning of attribute."); - } - - while (true) - { - parserToken.Attributes[currentAttribute].Name.WriteTo(sink); - - if (parserToken.Attributes[currentAttribute].IsAttrNameEnd) - { - state = State.EndAttributeName; - break; - } - - ParseToken(); - - InternalDebug.Assert(!parserToken.IsTagBegin && - parserToken.Attributes.Count != 0 && - !parserToken.Attributes[0].IsAttrBegin); - - currentAttribute = 0; - } - } - - - internal bool AttributeReader_CurrentAttributeHasValue() - { - if (state != State.BeginAttributeValue) - { - AssertInAttribute(); - - if (state > State.BeginAttributeValue) - { - throw new InvalidOperationException("Reader must be positioned before attribute value"); - } - - - if (!SkipToAttributeValue()) - { - state = State.EndAttributeName; - return false; - } - - state = State.BeginAttributeValue; - } - - return true; - } - - - internal bool AttributeReader_CurrentAttributeValueIsLong() - { - if (state != State.BeginAttributeValue) - { - AssertInAttribute(); - - if (state > State.BeginAttributeValue) - { - throw new InvalidOperationException("Reader must be positioned before attribute value"); - } - - - if (!SkipToAttributeValue()) - { - state = State.EndAttributeName; - return false; - } - - state = State.BeginAttributeValue; - } - - return parserToken.Attributes[currentAttribute].IsAttrValueBegin && !parserToken.Attributes[currentAttribute].IsAttrEnd; - } - - - internal string AttributeReader_ReadCurrentAttributeValue() - { - if (state != State.BeginAttributeValue) - { - AssertInAttribute(); - - if (state > State.BeginAttributeValue) - { - throw new InvalidOperationException("Reader must be positioned before attribute value"); - } - - - if (!SkipToAttributeValue()) - { - state = State.EndAttribute; - return null; - } - - - } - - InternalDebug.Assert(parserToken.Attributes[currentAttribute].IsAttrValueBegin); - - InternalDebug.Assert(parserToken.Attributes[currentAttribute].IsAttrValueBegin); - - if (parserToken.Attributes[currentAttribute].IsAttrEnd) - { - return parserToken.Attributes[currentAttribute].Value.GetString(int.MaxValue); - } - - InternalDebug.Assert(!parserToken.IsTagEnd && !parserToken.Attributes[currentAttribute].IsAttrEnd); - - var sbSink = GetStringBuildSink(); - - parserToken.Attributes[currentAttribute].Value.WriteTo(sbSink); - - do - { - ParseToken(); - - InternalDebug.Assert(!parserToken.IsTagBegin && - parserToken.Attributes.Count != 0 && - !parserToken.Attributes[0].IsAttrBegin); - - currentAttribute = 0; - - parserToken.Attributes[0].Value.WriteTo(sbSink); - } - while (!parserToken.Attributes[0].IsAttrEnd); - - - state = State.EndAttribute; - - return sbSink.ToString(); - } - - - internal int AttributeReader_ReadCurrentAttributeValue(char[] buffer, int offset, int count) - { - if (null == buffer) - { - throw new ArgumentNullException("buffer"); - } - - if (offset > buffer.Length || offset < 0) - { - throw new ArgumentOutOfRangeException("offset", Strings.OffsetOutOfRange); - } - - if (count > buffer.Length || count < 0) - { - throw new ArgumentOutOfRangeException("count", Strings.CountOutOfRange); - } - - if (count + offset > buffer.Length) - { - throw new ArgumentOutOfRangeException("count", Strings.CountTooLarge); - } - - AssertInAttribute(); - - if (state < State.BeginAttributeValue) - { - - if (!SkipToAttributeValue()) - { - state = State.EndAttribute; - return 0; - } - - state = State.BeginAttributeValue; - } - - var lengthRead = 0; - - if (state != State.EndAttribute) - { - if (state == State.BeginAttributeValue) - { - state = State.ReadAttributeValue; - parserToken.Attributes[currentAttribute].Value.Rewind(); - } - - while (count != 0) - { - var chunkLength = parserToken.Attributes[currentAttribute].Value.Read(buffer, offset, count); - - if (chunkLength == 0) - { - if (parserToken.Attributes[currentAttribute].IsAttrEnd) - { - state = State.EndAttribute; - break; - } - - ParseToken(); - - InternalDebug.Assert(!parserToken.IsTagBegin && - parserToken.Attributes.Count != 0 && - !parserToken.Attributes[0].IsAttrBegin); - - currentAttribute = 0; - parserToken.Attributes[currentAttribute].Value.Rewind(); - continue; - } - - offset += chunkLength; - count -= chunkLength; - lengthRead += chunkLength; - } - } - - return lengthRead; - } - - - internal void AttributeReader_WriteCurrentAttributeValueTo(ITextSink sink) - { - if (state != State.BeginAttributeValue) - { - AssertInAttribute(); - - if (state > State.BeginAttributeValue) - { - throw new InvalidOperationException("Reader must be positioned before attribute value"); - } - - - if (!SkipToAttributeValue()) - { - state = State.EndAttribute; - return; - } - - - } - - while (true) - { - parserToken.Attributes[currentAttribute].Value.WriteTo(sink); - - if (parserToken.Attributes[currentAttribute].IsAttrEnd) - { - state = State.EndAttribute; - break; - } - - ParseToken(); - - InternalDebug.Assert(!parserToken.IsTagBegin && - parserToken.Attributes.Count != 0 && - !parserToken.Attributes[0].IsAttrBegin); - - currentAttribute = 0; - } - } - - - private bool SkipToAttributeValue() - { - if (!parserToken.Attributes[currentAttribute].IsAttrValueBegin) - { - if (parserToken.Attributes[currentAttribute].IsAttrEnd) - { - - return false; - } - - InternalDebug.Assert(!parserToken.IsTagEnd); - - do - { - ParseToken(); - InternalDebug.Assert(!parserToken.IsTagBegin && parserToken.Attributes.Count != 0 && !parserToken.Attributes[0].IsAttrBegin); - } - while (!parserToken.Attributes[0].IsAttrValueBegin && !parserToken.Attributes[0].IsAttrEnd); - - if (parserToken.Attributes[currentAttribute].IsAttrEnd) - { - - return false; - } - } - - return true; - } - - - private void AssertNotLocked() - { - AssertNotDisposed(); - if (locked) - { - throw new InvalidOperationException("Cannot set reader properties after reading a first token"); - } - } - - - private void AssertNotDisposed() - { - if (state == State.Disposed) - { - throw new ObjectDisposedException("HtmlReader"); - } - } - - - private void AssertInToken() - { - if (state <= State.Begin) - { - AssertNotDisposed(); - throw new InvalidOperationException("Reader must be positioned inside a valid token"); - } - } - - - private void AssertInTag() - { - if (state < State.BeginTag) - { - AssertInToken(); - throw new InvalidOperationException("Reader must be positioned inside a StartTag, EndTag or EmptyElementTag token"); - } - - InternalDebug.Assert(parserTokenId == HtmlTokenId.Tag && parserToken.TagIndex >= HtmlTagIndex.Unknown); - } - - - private void AssertInAttribute() - { - if (state < State.BeginAttribute || state > State.EndAttribute) - { - AssertInTag(); - throw new InvalidOperationException("Reader must be positioned inside attribute"); - } - - InternalDebug.Assert(currentAttribute < parserToken.Attributes.Count); - } - } - - - - - - internal struct HtmlAttributeReader - { - private HtmlReader reader; - - - internal HtmlAttributeReader(HtmlReader reader) - { - this.reader = reader; - } - - - - - public bool ReadNext() - { - return reader.AttributeReader_ReadNextAttribute(); - } - - - - - - - - - public HtmlAttributeId Id => reader.AttributeReader_GetCurrentAttributeId(); - - - public bool NameIsLong => reader.AttributeReader_CurrentAttributeNameIsLong(); - - - public string ReadName() - { - return reader.AttributeReader_ReadCurrentAttributeName(); - } - - - - - - - - - - - - - - - - - public int ReadName(char[] buffer, int offset, int count) - { - return reader.AttributeReader_ReadCurrentAttributeName(buffer, offset, count); - } - - - internal void WriteNameTo(ITextSink sink) - { - reader.AttributeReader_WriteCurrentAttributeNameTo(sink); - } - - - - - - - - - - public bool HasValue => reader.AttributeReader_CurrentAttributeHasValue(); - - - public bool ValueIsLong => reader.AttributeReader_CurrentAttributeValueIsLong(); - - - public string ReadValue() - { - return reader.AttributeReader_ReadCurrentAttributeValue(); - } - - - - - - - - - - - - - - - - - - public int ReadValue(char[] buffer, int offset, int count) - { - return reader.AttributeReader_ReadCurrentAttributeValue(buffer, offset, count); - } - - - internal void WriteValueTo(ITextSink sink) - { - reader.AttributeReader_WriteCurrentAttributeValueTo(sink); - } - - - } -} diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlSupport.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlSupport.cs deleted file mode 100644 index 9851182cf..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlSupport.cs +++ /dev/null @@ -1,3462 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters.Internal.Html -{ - using System; - using System.Collections.Generic; - using Data.Internal; - using Format; - - - - internal static class HtmlSupport - { - public const int HtmlNestingLimit = 4096; - public const int MaxAttributeSize = 4096; - public const int MaxCssPropertySize = 4096; - public const int MaxNumberOfNonInlineStyles = 128; - - - - public static readonly byte[] UnsafeAsciiMap = - { - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0, - 0, - 0x02, - 0x02, - 0, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0, - 0x02, - 0x03, - 0x02, - 0x02, - 0x02, - 0x03, - 0x02, - 0x02, - 0x02, - 0x02, - 0x03, - 0, - 0, - 0, - 0x02, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0x02, - 0x02, - 0x03, - 0x02, - 0x03, - 0x02, - 0x02, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0x02, - 0x02, - 0x02, - 0x02, - 0, - 0x02, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0x02, - 0x02, - 0x02, - 0x02, - 0x03, - - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - 0x03, - - 0x03, - }; - - - - public static readonly HtmlEntityIndex[] EntityMap = - { -#if false - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.quot, - 0, - 0, - 0, - HtmlEntityIndex.amp, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - HtmlEntityIndex.lt, - 0, - HtmlEntityIndex.gt, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, -#endif - HtmlEntityIndex.nbsp, - HtmlEntityIndex.iexcl, - HtmlEntityIndex.cent, - HtmlEntityIndex.pound, - HtmlEntityIndex.curren, - HtmlEntityIndex.yen, - HtmlEntityIndex.brvbar, - HtmlEntityIndex.sect, - HtmlEntityIndex.uml, - HtmlEntityIndex.copy, - HtmlEntityIndex.ordf, - HtmlEntityIndex.laquo, - HtmlEntityIndex.not, - HtmlEntityIndex.shy, - HtmlEntityIndex.reg, - HtmlEntityIndex.macr, - HtmlEntityIndex.deg, - HtmlEntityIndex.plusmn, - HtmlEntityIndex.sup2, - HtmlEntityIndex.sup3, - HtmlEntityIndex.acute, - HtmlEntityIndex.micro, - HtmlEntityIndex.para, - HtmlEntityIndex.middot, - HtmlEntityIndex.cedil, - HtmlEntityIndex.sup1, - HtmlEntityIndex.ordm, - HtmlEntityIndex.raquo, - HtmlEntityIndex.frac14, - HtmlEntityIndex.frac12, - HtmlEntityIndex.frac34, - HtmlEntityIndex.iquest, - HtmlEntityIndex.Agrave, - HtmlEntityIndex.Aacute, - HtmlEntityIndex.Acirc, - HtmlEntityIndex.Atilde, - HtmlEntityIndex.Auml, - HtmlEntityIndex.Aring, - HtmlEntityIndex.AElig, - HtmlEntityIndex.Ccedil, - HtmlEntityIndex.Egrave, - HtmlEntityIndex.Eacute, - HtmlEntityIndex.Ecirc, - HtmlEntityIndex.Euml, - HtmlEntityIndex.Igrave, - HtmlEntityIndex.Iacute, - HtmlEntityIndex.Icirc, - HtmlEntityIndex.Iuml, - HtmlEntityIndex.ETH, - HtmlEntityIndex.Ntilde, - HtmlEntityIndex.Ograve, - HtmlEntityIndex.Oacute, - HtmlEntityIndex.Ocirc, - HtmlEntityIndex.Otilde, - HtmlEntityIndex.Ouml, - HtmlEntityIndex.times, - HtmlEntityIndex.Oslash, - HtmlEntityIndex.Ugrave, - HtmlEntityIndex.Uacute, - HtmlEntityIndex.Ucirc, - HtmlEntityIndex.Uuml, - HtmlEntityIndex.Yacute, - HtmlEntityIndex.THORN, - HtmlEntityIndex.szlig, - HtmlEntityIndex.agrave, - HtmlEntityIndex.aacute, - HtmlEntityIndex.acirc, - HtmlEntityIndex.atilde, - HtmlEntityIndex.auml, - HtmlEntityIndex.aring, - HtmlEntityIndex.aelig, - HtmlEntityIndex.ccedil, - HtmlEntityIndex.egrave, - HtmlEntityIndex.eacute, - HtmlEntityIndex.ecirc, - HtmlEntityIndex.euml, - HtmlEntityIndex.igrave, - HtmlEntityIndex.iacute, - HtmlEntityIndex.icirc, - HtmlEntityIndex.iuml, - HtmlEntityIndex.eth, - HtmlEntityIndex.ntilde, - HtmlEntityIndex.ograve, - HtmlEntityIndex.oacute, - HtmlEntityIndex.ocirc, - HtmlEntityIndex.otilde, - HtmlEntityIndex.ouml, - HtmlEntityIndex.divide, - HtmlEntityIndex.oslash, - HtmlEntityIndex.ugrave, - HtmlEntityIndex.uacute, - HtmlEntityIndex.ucirc, - HtmlEntityIndex.uuml, - HtmlEntityIndex.yacute, - HtmlEntityIndex.thorn, - HtmlEntityIndex.yuml, - }; - - - - - - - - - - - [Flags] - public enum NumberParseFlags - { - Integer = 0x0001, - Float = 0x0002, - AbsoluteLength = 0x0004, - EmExLength = 0x0008, - Percentage = 0x0010, - Multiple = 0x0020, - HtmlFontUnits = 0x0040, - - NonNegative = 0x2000, - StyleSheetProperty = 0x4000, - Strict = 0x8000, - - Length = AbsoluteLength | EmExLength | Percentage, - NonNegativeLength = AbsoluteLength | EmExLength | Percentage | NonNegative, - FontSize = AbsoluteLength | EmExLength | Percentage | HtmlFontUnits | NonNegative, - } - - public static PropertyValue ParseNumber(BufferString value, NumberParseFlags parseFlags) - { - var isValidNumber = false; - var isSigned = false; - var isNegative = false; - ulong result = 0; - var exponent = 0; - var scientificExponent = 0; - var floatNumber = false; - var offset = 0; - var end = value.Length; - - - while (offset < end && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[offset]))) - { - offset++; - } - - if (offset == end) - { - return PropertyValue.Null; - } - - if (offset < end && (value[offset] == '-' || value[offset] == '+')) - { - isSigned = true; - isNegative = (value[offset] == '-'); - offset ++; - } - - while (offset < end && ParseSupport.NumericCharacter(ParseSupport.GetCharClass(value[offset]))) - { - isValidNumber = true; - if (result < ulong.MaxValue / 10 - 9) - { - result = unchecked(result * 10u + (uint)(value[offset] - '0')); - } - else - { - - exponent++; - } - offset++; - } - - if (offset < end && value[offset] == '.') - { - floatNumber = true; - offset++; - - while (offset < end && ParseSupport.NumericCharacter(ParseSupport.GetCharClass(value[offset]))) - { - isValidNumber = true; - - - if (result < ulong.MaxValue / 10 - 9) - { - result = unchecked(result * 10u + (uint)(value[offset] - '0')); - exponent--; - } - - offset++; - } - - if (exponent >= 0 && 0 != (parseFlags & NumberParseFlags.Strict)) - { - return PropertyValue.Null; - } - } - - if (!isValidNumber) - { - return PropertyValue.Null; - } - - while (offset < end && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[offset]))) - { - offset++; - } - - if (offset < end && (value[offset] | '\x20') == 'e') - { - if (offset + 1 < end && (value[offset + 1] == '-' || value[offset + 1] == '+' || ParseSupport.NumericCharacter(ParseSupport.GetCharClass(value[offset + 1])))) - { - - - floatNumber = true; - offset ++; - - var isNegativeScientificExponent = false; - - if (value[offset] == '-' || value[offset] == '+') - { - isNegativeScientificExponent = (value[offset] == '-'); - offset ++; - } - - while (offset < end && ParseSupport.NumericCharacter(ParseSupport.GetCharClass(value[offset]))) - { - scientificExponent = unchecked(scientificExponent * 10 + (value[offset++] - '0')); - } - - if (isNegativeScientificExponent) - { - scientificExponent = -scientificExponent; - } - - while (offset < end && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[offset]))) - { - offset++; - } - } - } - - var mul = floatNumber ? 10000u : 1; - uint div = 1; - var units = floatNumber ? PropertyType.Fractional : PropertyType.Integer; - var recognized = false; - var typeLength = 0; - - if (offset + 1 < end) - { - - - if ((value[offset] | '\x20') == 'p') - { - - - if ((value[offset + 1] | '\x20') == 'c') - { - - - mul = 8 * 20 * 12; - div = 1; - recognized = true; - units = PropertyType.AbsLength; - typeLength = 2; - } - else if ((value[offset + 1] | '\x20') == 't') - { - - - mul = 8 * 20; - div = 1; - recognized = true; - units = PropertyType.AbsLength; - typeLength = 2; - } - else if ((value[offset + 1] | '\x20') == 'x') - { - - - mul = 8 * 20 * 72; - div = 120; - units = PropertyType.Pixels; - recognized = true; - typeLength = 2; - } - } - else if ((value[offset] | '\x20') == 'e') - { - - - if ((value[offset + 1] | '\x20') == 'm') - { - - - mul = 8 * 20; - div = 1; - units = PropertyType.Ems; - recognized = true; - typeLength = 2; - } - else if ((value[offset + 1] | '\x20') == 'x') - { - - - mul = 8 * 20; - div = 1; - units = PropertyType.Exs; - recognized = true; - typeLength = 2; - } - } - else if ((value[offset] | '\x20') == 'i') - { - - - if ((value[offset + 1] | '\x20') == 'n') - { - - - mul = 8 * 20 * 72; - div = 1; - recognized = true; - units = PropertyType.AbsLength; - typeLength = 2; - } - } - else if ((value[offset] | '\x20') == 'c') - { - - - if ((value[offset + 1] | '\x20') == 'm') - { - - - mul = 8 * 20 * 72 * 100; - div = 254; - recognized = true; - units = PropertyType.AbsLength; - typeLength = 2; - } - } - else if ((value[offset] | '\x20') == 'm') - { - - - if ((value[offset + 1] | '\x20') == 'm') - { - - - mul = 8 * 20 * 72 * 10; - div = 254; - recognized = true; - units = PropertyType.AbsLength; - typeLength = 2; - } - } - } - - if (!recognized && offset < end) - { - if (value[offset] == '%') - { - - - mul = 10000; - div = 1; - units = PropertyType.Percentage; - recognized = true; - typeLength = 1; - } - else if (value[offset] == '*') - { - - - mul = 1; - div = 1; - units = PropertyType.Multiple; - recognized = true; - typeLength = 1; - } - } - - offset += typeLength; - - if (offset < end) - { - while (offset < end && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[offset]))) - { - offset++; - } - - if (offset < end) - { - if (0 != (parseFlags & (NumberParseFlags.Strict | NumberParseFlags.StyleSheetProperty))) - { - return PropertyValue.Null; - } - } - } - - if (result != 0) - { - - - - var actualExponent = exponent + scientificExponent; - - - - if (actualExponent > 0) - { - if (actualExponent > 20) - { - actualExponent = 0; - result = ulong.MaxValue; - } - else - { - while (actualExponent != 0) - { - if (result > ulong.MaxValue / 10) - { - actualExponent = 0; - result = ulong.MaxValue; - break; - } - else - { - result = unchecked(result * 10); - } - actualExponent --; - } - } - } - else if (actualExponent < -10) - { - if (actualExponent < -21) - { - actualExponent = 0; - result = 0; - } - else - { - while (actualExponent != -10) - { - result /= 10; - actualExponent ++; - } - } - } - - result *= mul; - result /= div; - - while (actualExponent != 0) - { - result /= 10; - actualExponent ++; - } - - if (result > PropertyValue.ValueMax) - { - result = PropertyValue.ValueMax; - } - } - - var intValue = unchecked((int)result); - if (isNegative) - { - intValue = -intValue; - } - - if (units == PropertyType.Integer) - { - if (0 != (parseFlags & NumberParseFlags.Integer)) - { - - } - else if (0 != (parseFlags & NumberParseFlags.HtmlFontUnits)) - { - if (isSigned) - { - if (intValue < -7) - { - intValue = -7; - } - else if (intValue > 7) - { - intValue = 7; - } - units = PropertyType.RelHtmlFontUnits; - } - else - { - if (intValue < 1) - { - intValue = 1; - } - else if (intValue > 7) - { - intValue = 7; - } - units = PropertyType.HtmlFontUnits; - } - } - - else if (0 != (parseFlags & NumberParseFlags.AbsoluteLength)) - { - - - result = result * (8 * 20 * 72) / 120; - if (result > PropertyValue.ValueMax) - { - result = PropertyValue.ValueMax; - } - - intValue = unchecked((int)result); - if (isNegative) - { - intValue = -intValue; - } - - units = PropertyType.Pixels; - } - else if (0 != (parseFlags & NumberParseFlags.Float)) - { - result = result * 10000; - if (result > PropertyValue.ValueMax) - { - result = PropertyValue.ValueMax; - } - - intValue = unchecked((int)result); - if (isNegative) - { - intValue = -intValue; - } - - units = PropertyType.Fractional; - } - else - { - return PropertyValue.Null; - } - } - else if (units == PropertyType.Fractional) - { - if (0 != (parseFlags & NumberParseFlags.Float)) - { - - } - - else if (0 != (parseFlags & NumberParseFlags.AbsoluteLength)) - { - - - result = result * (8 * 20 * 72) / 120 / 10000; - if (result > PropertyValue.ValueMax) - { - result = PropertyValue.ValueMax; - } - - intValue = unchecked((int)result); - if (isNegative) - { - intValue = -intValue; - } - - units = PropertyType.Pixels; - } - else - { - return PropertyValue.Null; - } - } - else if (units == PropertyType.AbsLength || units == PropertyType.Pixels) - { - if (0 == (parseFlags & NumberParseFlags.AbsoluteLength)) - { - return PropertyValue.Null; - } - } - else if (units == PropertyType.Ems || units == PropertyType.Exs) - { - if (0 == (parseFlags & NumberParseFlags.EmExLength)) - { - return PropertyValue.Null; - } - } - else if (units == PropertyType.Percentage) - { - if (0 == (parseFlags & NumberParseFlags.Percentage)) - { - return PropertyValue.Null; - } - } - else if (units == PropertyType.Multiple) - { - if (0 == (parseFlags & NumberParseFlags.Multiple)) - { - return PropertyValue.Null; - } - } - - if (intValue < 0 && 0 != (parseFlags & NumberParseFlags.NonNegative) && units != PropertyType.RelHtmlFontUnits) - { - - return PropertyValue.Null; - } - - return new PropertyValue(units, intValue); - } - - public static BufferString FormatPixelOrPercentageLength(ref ScratchBuffer scratchBuffer, PropertyValue value) - { - scratchBuffer.Reset(); - AppendNumber(ref scratchBuffer, value, NumberParseFlags.Integer | NumberParseFlags.Percentage); - return scratchBuffer.BufferString; - } - - public static BufferString FormatPixelLength(ref ScratchBuffer scratchBuffer, PropertyValue value) - { - scratchBuffer.Reset(); - AppendNumber(ref scratchBuffer, value, NumberParseFlags.Integer); - return scratchBuffer.BufferString; - } - - public static BufferString FormatLength(ref ScratchBuffer scratchBuffer, PropertyValue value) - { - scratchBuffer.Reset(); - AppendNumber(ref scratchBuffer, value, NumberParseFlags.AbsoluteLength | NumberParseFlags.Percentage | NumberParseFlags.EmExLength); - return scratchBuffer.BufferString; - } - - public static BufferString FormatFontSize(ref ScratchBuffer scratchBuffer, PropertyValue value) - { - scratchBuffer.Reset(); - AppendNumber(ref scratchBuffer, value, NumberParseFlags.HtmlFontUnits); - return scratchBuffer.BufferString; - } - - public static void AppendPixelOrPercentageLength(ref ScratchBuffer scratchBuffer, PropertyValue value) - { - AppendNumber(ref scratchBuffer, value, NumberParseFlags.Integer | NumberParseFlags.Percentage); - } - - public static void AppendPixelLength(ref ScratchBuffer scratchBuffer, PropertyValue value) - { - AppendNumber(ref scratchBuffer, value, NumberParseFlags.Integer); - } - - public static void AppendLength(ref ScratchBuffer scratchBuffer, PropertyValue value) - { - AppendNumber(ref scratchBuffer, value, NumberParseFlags.AbsoluteLength | NumberParseFlags.Percentage | NumberParseFlags.EmExLength); - } - - public static void AppendFontSize(ref ScratchBuffer scratchBuffer, PropertyValue value) - { - AppendNumber(ref scratchBuffer, value, NumberParseFlags.HtmlFontUnits); - } - - public static void AppendCssFontSize(ref ScratchBuffer scratchBuffer, PropertyValue value) - { - AppendNumber(ref scratchBuffer, value, NumberParseFlags.FontSize); - } - - private static void AppendNumber(ref ScratchBuffer scratchBuffer, PropertyValue value, NumberParseFlags formatFlags) - { - - - if (value.IsPercentage) - { - if (0 != (formatFlags & NumberParseFlags.Percentage)) - { - scratchBuffer.AppendFractional(value.Percentage10K, 10000); - scratchBuffer.Append('%'); - } - } - else if (value.IsAbsRelLength) - { - if (0 != (formatFlags & NumberParseFlags.Integer)) - { - scratchBuffer.AppendInt(value.PixelsInteger); - } - else if (0 != (formatFlags & NumberParseFlags.AbsoluteLength)) - { - if (value.IsPixels) - { - var pixels96 = value.PixelsInteger96; - - scratchBuffer.AppendFractional(pixels96, 96); - - if (pixels96 != 0) - { - scratchBuffer.Append("px"); - } - } - else - { - var points160 = value.PointsInteger160; - - scratchBuffer.AppendFractional(points160, 160); - - if (points160 != 0) - { - scratchBuffer.Append("pt"); - } - } - } - else if (0 != (formatFlags & NumberParseFlags.HtmlFontUnits)) - { - scratchBuffer.AppendInt(PropertyValue.ConvertTwipsToHtmlFontUnits(value.TwipsInteger)); - } - } - else if (value.IsEms) - { - if (0 != (formatFlags & NumberParseFlags.EmExLength)) - { - scratchBuffer.AppendFractional(value.EmsInteger160, 160); - scratchBuffer.Append("em"); - } - } - else if (value.IsExs) - { - if (0 != (formatFlags & NumberParseFlags.EmExLength)) - { - scratchBuffer.AppendFractional(value.ExsInteger160, 160); - scratchBuffer.Append("ex"); - } - } - else if (value.IsHtmlFontUnits) - { - if (0 != (formatFlags & NumberParseFlags.HtmlFontUnits)) - { - scratchBuffer.AppendInt(value.HtmlFontUnits); - } - } - else if (value.IsRelativeHtmlFontUnits) - { - if (0 != (formatFlags & NumberParseFlags.HtmlFontUnits)) - { - if (value.RelativeHtmlFontUnits > 0) - { - scratchBuffer.Append("+"); - scratchBuffer.AppendInt(value.RelativeHtmlFontUnits); - } - else if (value.RelativeHtmlFontUnits < 0) - { - scratchBuffer.AppendInt(value.RelativeHtmlFontUnits); - } - } - } - } - - - - public struct EnumerationDef - { - public string name; - public PropertyValue value; - - public EnumerationDef(string name, PropertyValue value) - { - this.name = name; - this.value = value; - } - } - - - - public static PropertyValue ParseEnum(BufferString value, EnumerationDef[] enumerationDefs) - { - value.TrimWhitespace(); - if (value.Length == 0) - { - return PropertyValue.Null; - } - - for (var i = 0; i < enumerationDefs.Length; i++) - { - if (value.EqualsToLowerCaseStringIgnoreCase(enumerationDefs[i].name)) - { - return enumerationDefs[i].value; - } - } - - - return PropertyValue.Null; - } - - public static string GetEnumString(PropertyValue value, EnumerationDef[] enumerationDefs) - { - for (var i = 0; i < enumerationDefs.Length; i++) - { - if (value.RawValue == enumerationDefs[i].value.RawValue) - { - return enumerationDefs[i].name; - } - } - - return null; - } - - - - public static PropertyValue ParseBooleanAttribute(BufferString value, FormatConverter formatConverter) - { - - return PropertyValue.True; - } - - - - private static EnumerationDef[] DirectionEnumeration = - { - new EnumerationDef("rtl", PropertyValue.True), - new EnumerationDef("ltr", PropertyValue.False), - }; - - internal static PropertyValue ParseDirection(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, DirectionEnumeration); - } - - - - internal static EnumerationDef[] TextAlignmentEnumeration = - { - new EnumerationDef("left", new PropertyValue(TextAlign.Left)), - new EnumerationDef("center", new PropertyValue(TextAlign.Center)), - new EnumerationDef("right", new PropertyValue(TextAlign.Right)), - new EnumerationDef("justify", new PropertyValue(TextAlign.Justify)), - }; - - internal static PropertyValue ParseTextAlignment(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, TextAlignmentEnumeration); - } - - internal static string GetTextAlignmentString(PropertyValue value) - { - return GetEnumString(value, TextAlignmentEnumeration); - } - - - - internal static EnumerationDef[] HorizontalAlignmentEnumeration = - { - new EnumerationDef("left", new PropertyValue(BlockHorizontalAlign.Left)), - new EnumerationDef("center", new PropertyValue(BlockHorizontalAlign.Center)), - new EnumerationDef("right", new PropertyValue(BlockHorizontalAlign.Right)), - }; - - internal static PropertyValue ParseHorizontalAlignment(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, HorizontalAlignmentEnumeration); - } - - internal static string GetHorizontalAlignmentString(PropertyValue value) - { - return GetEnumString(value, HorizontalAlignmentEnumeration); - } - - - - private static EnumerationDef[] VerticalAlignmentEnumeration = - { - new EnumerationDef("top", new PropertyValue(BlockVerticalAlign.Top)), - new EnumerationDef("middle", new PropertyValue(BlockVerticalAlign.Middle)), - new EnumerationDef("bottom", new PropertyValue(BlockVerticalAlign.Bottom)), - new EnumerationDef("baseline", new PropertyValue(BlockVerticalAlign.Middle)), - }; - - internal static PropertyValue ParseVerticalAlignment(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, VerticalAlignmentEnumeration); - } - - internal static string GetVerticalAlignmentString(PropertyValue value) - { - return GetEnumString(value, VerticalAlignmentEnumeration); - } - - - - internal static EnumerationDef[] BlockAlignmentEnumeration = - { - new EnumerationDef("top", new PropertyValue(BlockHorizontalAlign.Left)), - new EnumerationDef("middle", new PropertyValue(BlockHorizontalAlign.Left)), - new EnumerationDef("bottom", new PropertyValue(BlockHorizontalAlign.Left)), - new EnumerationDef("left", new PropertyValue(BlockHorizontalAlign.Center)), - new EnumerationDef("right", new PropertyValue(BlockHorizontalAlign.Right)), - }; - - internal static PropertyValue ParseBlockAlignment(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, BlockAlignmentEnumeration); - } - - internal static string GetBlockAlignmentString(PropertyValue value) - { - return GetEnumString(value, BlockAlignmentEnumeration); - } - - - - internal static EnumerationDef[] BorderStyleEnumeration = - { - new EnumerationDef("none", new PropertyValue(BorderStyle.None)), - new EnumerationDef("hidden", new PropertyValue(BorderStyle.Hidden)), - new EnumerationDef("dotted", new PropertyValue(BorderStyle.Dotted)), - new EnumerationDef("dashed", new PropertyValue(BorderStyle.Dashed)), - new EnumerationDef("solid", new PropertyValue(BorderStyle.Solid)), - new EnumerationDef("double", new PropertyValue(BorderStyle.Double)), - new EnumerationDef("groove", new PropertyValue(BorderStyle.Groove)), - new EnumerationDef("ridge", new PropertyValue(BorderStyle.Ridge)), - new EnumerationDef("inset", new PropertyValue(BorderStyle.Inset)), - new EnumerationDef("outset", new PropertyValue(BorderStyle.Outset)), - }; - - internal static PropertyValue ParseBorderStyle(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, BorderStyleEnumeration); - } - - internal static string GetBorderStyleString(PropertyValue value) - { - return GetEnumString(value, BorderStyleEnumeration); - } - - - - private static EnumerationDef[] TargetEnumeration = - { - new EnumerationDef("_self", new PropertyValue(LinkTarget.Self)), - new EnumerationDef("_top", new PropertyValue(LinkTarget.Top)), - new EnumerationDef("_blank", new PropertyValue(LinkTarget.Blank)), - new EnumerationDef("_parent", new PropertyValue(LinkTarget.Parent)), - }; - - internal static PropertyValue ParseTarget(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, TargetEnumeration); - } - - internal static string GetTargetString(PropertyValue value) - { - return GetEnumString(value, TargetEnumeration); - } - - - - - private static EnumerationDef[] FontWeightEnumeration = - { - new EnumerationDef("normal", PropertyValue.False), - new EnumerationDef("bold", PropertyValue.True), - new EnumerationDef("lighter", PropertyValue.False), - new EnumerationDef("bolder", PropertyValue.True), - new EnumerationDef("100", PropertyValue.False), - new EnumerationDef("200", PropertyValue.False), - new EnumerationDef("300", PropertyValue.False), - new EnumerationDef("400", PropertyValue.False), - new EnumerationDef("500", PropertyValue.False), - new EnumerationDef("600", PropertyValue.True), - new EnumerationDef("700", PropertyValue.True), - new EnumerationDef("800", PropertyValue.True), - new EnumerationDef("900", PropertyValue.True), - }; - - internal static PropertyValue ParseFontWeight(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, FontWeightEnumeration); - } - - - - private static EnumerationDef[] FontSizeEnumeration = - { - new EnumerationDef("xx-small", new PropertyValue(LengthUnits.HtmlFontUnits, 1)), - new EnumerationDef("x-small", new PropertyValue(LengthUnits.HtmlFontUnits, 2)), - new EnumerationDef("small", new PropertyValue(LengthUnits.HtmlFontUnits, 2)), - new EnumerationDef("medium", new PropertyValue(LengthUnits.HtmlFontUnits, 3)), - new EnumerationDef("large", new PropertyValue(LengthUnits.HtmlFontUnits, 4)), - new EnumerationDef("x-large", new PropertyValue(LengthUnits.HtmlFontUnits, 5)), - new EnumerationDef("xx-large", new PropertyValue(LengthUnits.HtmlFontUnits, 6)), - }; - - internal static PropertyValue ParseCssFontSize(BufferString value, FormatConverter formatConverter) - { - var result = ParseEnum(value, FontSizeEnumeration); - if (result.IsNull) - { - result = ParseFontSize(value, formatConverter); - } - - return result; - } - - - - private static EnumerationDef[] FontStyleEnumeration = - { - - new EnumerationDef("normal", PropertyValue.False), - new EnumerationDef("italic", PropertyValue.True), - new EnumerationDef("oblique", PropertyValue.True), - }; - - internal static PropertyValue ParseFontStyle(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, FontStyleEnumeration); - } - - - - private static EnumerationDef[] FontVariantEnumeration = - { - - new EnumerationDef("normal", PropertyValue.False), - new EnumerationDef("small-caps", PropertyValue.True), - }; - - internal static PropertyValue ParseFontVariant(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, FontVariantEnumeration); - } - - - - - private static EnumerationDef[] TableLayoutEnumeration = - { - - new EnumerationDef("auto", PropertyValue.False), - new EnumerationDef("fixed", PropertyValue.True), - }; - - internal static PropertyValue ParseTableLayout(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, TableLayoutEnumeration); - } - - - - private static EnumerationDef[] BorderCollapseEnumeration = - { - - new EnumerationDef("collapse", PropertyValue.True), - new EnumerationDef("separate", PropertyValue.False), - }; - - internal static PropertyValue ParseBorderCollapse(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, BorderCollapseEnumeration); - } - - - - private static EnumerationDef[] EmptyCellsEnumeration = - { - - new EnumerationDef("show", PropertyValue.True), - new EnumerationDef("hide", PropertyValue.False), - }; - - internal static PropertyValue ParseEmptyCells(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, EmptyCellsEnumeration); - } - - - - private static EnumerationDef[] CaptionSideEnumeration = - { - - new EnumerationDef("bottom", PropertyValue.True), - new EnumerationDef("top", PropertyValue.False), - }; - - internal static PropertyValue ParseCaptionSide(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, CaptionSideEnumeration); - } - - - - private static EnumerationDef[] BorderWidthEnumeration = - { - - new EnumerationDef("thin", new PropertyValue(LengthUnits.Pixels, 2)), - new EnumerationDef("medium", new PropertyValue(LengthUnits.Pixels, 4)), - new EnumerationDef("thick", new PropertyValue(LengthUnits.Pixels, 6)), - }; - - internal static PropertyValue ParseBorderWidth(BufferString value, FormatConverter formatConverter) - { - var result = ParseEnum(value, BorderWidthEnumeration); - if (result.IsNull) - { - result = ParseNonNegativeLength(value, formatConverter); - } - - return result; - } - - - - internal enum TableFrame - { - Void, - Above, - Below, - Border, - Box, - Hsides, - Lhs, - Rhs, - Vsides, - } - - private static EnumerationDef[] TableFrameEnumeration = - { - new EnumerationDef("void", new PropertyValue(TableFrame.Void)), - new EnumerationDef("above", new PropertyValue(TableFrame.Above)), - new EnumerationDef("below", new PropertyValue(TableFrame.Below)), - new EnumerationDef("border", new PropertyValue(TableFrame.Border)), - new EnumerationDef("box", new PropertyValue(TableFrame.Box)), - new EnumerationDef("hsides", new PropertyValue(TableFrame.Hsides)), - new EnumerationDef("lhs", new PropertyValue(TableFrame.Lhs)), - new EnumerationDef("rhs", new PropertyValue(TableFrame.Rhs)), - new EnumerationDef("vsides", new PropertyValue(TableFrame.Vsides)), - }; - - internal static PropertyValue ParseTableFrame(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, TableFrameEnumeration); - } - - internal static string GetTableFrameString(PropertyValue value) - { - return GetEnumString(value, TableFrameEnumeration); - } - - - - internal enum TableRules - { - None, - Groups, - Rows, - Cells, - All, - } - - private static EnumerationDef[] TableRulesEnumeration = - { - new EnumerationDef("none", new PropertyValue(TableRules.None)), - new EnumerationDef("groups", new PropertyValue(TableRules.Groups)), - new EnumerationDef("rows", new PropertyValue(TableRules.Rows)), - new EnumerationDef("cells", new PropertyValue(TableRules.Cells)), - new EnumerationDef("all", new PropertyValue(TableRules.All)), - }; - - internal static PropertyValue ParseTableRules(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, TableRulesEnumeration); - } - - internal static string GetTableRulesString(PropertyValue value) - { - return GetEnumString(value, TableRulesEnumeration); - } - - - - private static EnumerationDef[] UnicodeBiDiEnumeration = - { - new EnumerationDef("normal", new PropertyValue(UnicodeBiDi.Normal)), - new EnumerationDef("embed", new PropertyValue(UnicodeBiDi.Embed)), - new EnumerationDef("bidi-override", new PropertyValue(UnicodeBiDi.Override)), - }; - - internal static PropertyValue ParseUnicodeBiDi(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, UnicodeBiDiEnumeration); - } - - internal static string GetUnicodeBiDiString(PropertyValue value) - { - return GetEnumString(value, UnicodeBiDiEnumeration); - } - - - - - private static EnumerationDef[] DisplayEnumeration = - { - new EnumerationDef("none", new PropertyValue(Display.None)), - new EnumerationDef("inline", new PropertyValue(Display.Inline)), - new EnumerationDef("block", new PropertyValue(Display.Block)), - new EnumerationDef("list-item", new PropertyValue(Display.ListItem)), - new EnumerationDef("run-in", new PropertyValue(Display.RunIn)), - new EnumerationDef("inline-block", new PropertyValue(Display.InlineBlock)), - new EnumerationDef("table", new PropertyValue(Display.Table)), - new EnumerationDef("inline-table", new PropertyValue(Display.InlineTable)), - new EnumerationDef("table-row-group", new PropertyValue(Display.TableRowGroup)), - new EnumerationDef("table-header-group", new PropertyValue(Display.TableHeaderGroup)), - new EnumerationDef("table-footer-group", new PropertyValue(Display.TableFooterGroup)), - new EnumerationDef("table-row", new PropertyValue(Display.TableRow)), - new EnumerationDef("table-column-group", new PropertyValue(Display.TableColumnGroup)), - new EnumerationDef("table-column", new PropertyValue(Display.TableColumn)), - new EnumerationDef("table-cell", new PropertyValue(Display.TableCell)), - new EnumerationDef("table-caption", new PropertyValue(Display.TableCaption)), - }; - - internal static PropertyValue ParseDisplay(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, DisplayEnumeration); - } - - internal static string GetDisplayString(PropertyValue value) - { - return GetEnumString(value, DisplayEnumeration); - } - - - - - private static EnumerationDef[] VisibilityEnumeration = - { - new EnumerationDef("visible", PropertyValue.True), - new EnumerationDef("hidden", PropertyValue.False), - new EnumerationDef("collapse", PropertyValue.False), - }; - - internal static PropertyValue ParseVisibility(BufferString value, FormatConverter formatConverter) - { - return ParseEnum(value, VisibilityEnumeration); - } - - - - internal static PropertyValue ParseLanguage(BufferString value, FormatConverter formatConverter) - { - value.TrimWhitespace(); - if (value.Length == 0) - { - return PropertyValue.Null; - } - - Globalization.Culture culture; - - if (Globalization.Culture.TryGetCulture(value.ToString(), out culture) && culture.LCID != 0) - { - return new PropertyValue(PropertyType.Integer, culture.LCID); - } - - return PropertyValue.Null; - } - - - - - public static PropertyValue ParseColor(BufferString value, bool enriched, bool css) - { - var offset = 0; - RGBT rgbt; - - if (value.Length == 0 || value[0] != '#' || enriched) - { - - int i; - var notAName = false; - var foundNonHex = false; - - for (i = 0; i < value.Length; i++) - { - if (!ParseSupport.AlphaCharacter(ParseSupport.GetCharClass(value[i]))) - { - notAName = true; - break; - } - if (!foundNonHex && !ParseSupport.HexCharacter(ParseSupport.GetCharClass(value[i]))) - foundNonHex = true; - } - - - if (!notAName && foundNonHex) - { - var pv = ParseNamedColor(value); - if (!pv.IsNull) - { - return pv; - } - } - - if (!enriched) - { - - var pv = ParseRgbColor(value); - if (!pv.IsNull) - { - return pv; - } - } - - - - - - } - else - { - - offset++; - } - - if (enriched) - { - if (ParseHexColorEnriched(value, offset, out rgbt)) - { - return new PropertyValue(rgbt); - } - } - else - { - - - if (ParseHexColor(value, offset, css, out rgbt)) - { - return new PropertyValue(rgbt); - } - } - - return PropertyValue.Null; - } - - internal enum SystemColors - { - - - ActiveBorder = 10, - ActiveCaption = 2, - AppWorkspace = 12, - Background = 1, - ButtonFace = 15, - ButtonHighlight = 20, - ButtonShadow = 16, - ButtonText = 18, - CaptionText = 9, - GrayText = 17, - Highlight = 13, - HighlightText = 14, - InactiveBorder = 11, - InactiveCaption = 3, - InactiveCaptionText = 19, - InfoBackground = 24, - InfoText = 23, - Menu = 4, - MenuText = 7, - Scrollbar = 0, - ThreeDDarkShadow = 21, - ThreeDFace = ButtonFace, - ThreeDHighlight = ButtonHighlight, - ThreeDLightShadow = 22, - ThreeDShadow = ButtonShadow, - Window = 5, - WindowFrame = 6, - WindowText = 8, - } - - private static readonly EnumerationDef[] colorNames = - { - - new EnumerationDef("activeborder", new PropertyValue(SystemColors.ActiveBorder)), - new EnumerationDef("activecaption", new PropertyValue(SystemColors.ActiveCaption)), - new EnumerationDef("aliceblue", new PropertyValue(new RGBT(0x00F0F8FFu))), - new EnumerationDef("antiquewhite", new PropertyValue(new RGBT(0x00FAEBD7u))), - new EnumerationDef("appworkspace", new PropertyValue(SystemColors.AppWorkspace)), - new EnumerationDef("aqua", new PropertyValue(new RGBT(0x0000FFFFu))), - new EnumerationDef("aquamarine", new PropertyValue(new RGBT(0x007FFFD4u))), - new EnumerationDef("azure", new PropertyValue(new RGBT(0x00F0FFFFu))), - new EnumerationDef("background", new PropertyValue(SystemColors.Background)), - new EnumerationDef("beige", new PropertyValue(new RGBT(0x00F5F5DCu))), - new EnumerationDef("bisque", new PropertyValue(new RGBT(0x00FFE4C4u))), - new EnumerationDef("black", new PropertyValue(new RGBT(0x00000000u))), - new EnumerationDef("blanchedalmond", new PropertyValue(new RGBT(0x00FFEBCDu))), - new EnumerationDef("blue", new PropertyValue(new RGBT(0x000000FFu))), - new EnumerationDef("blueviolet", new PropertyValue(new RGBT(0x008A2BE2u))), - new EnumerationDef("brown", new PropertyValue(new RGBT(0x00A52A2Au))), - new EnumerationDef("burlywood", new PropertyValue(new RGBT(0x00DEB887u))), - new EnumerationDef("buttonface", new PropertyValue(SystemColors.ButtonFace)), - new EnumerationDef("buttonhighlight", new PropertyValue(SystemColors.ButtonHighlight)), - new EnumerationDef("buttonshadow", new PropertyValue(SystemColors.ButtonShadow)), - new EnumerationDef("buttontext", new PropertyValue(SystemColors.ButtonText)), - new EnumerationDef("cadetblue", new PropertyValue(new RGBT(0x005F9EA0u))), - new EnumerationDef("captiontext", new PropertyValue(SystemColors.CaptionText)), - new EnumerationDef("chartreuse", new PropertyValue(new RGBT(0x007FFF00u))), - new EnumerationDef("chocolate", new PropertyValue(new RGBT(0x00D2691Eu))), - new EnumerationDef("coral", new PropertyValue(new RGBT(0x00FF7F50u))), - new EnumerationDef("cornflowerblue", new PropertyValue(new RGBT(0x006495EDu))), - new EnumerationDef("cornsilk", new PropertyValue(new RGBT(0x00FFF8DCu))), - new EnumerationDef("crimson", new PropertyValue(new RGBT(0x00DC143Cu))), - new EnumerationDef("cyan", new PropertyValue(new RGBT(0x0000FFFFu))), - new EnumerationDef("darkblue", new PropertyValue(new RGBT(0x0000008Bu))), - new EnumerationDef("darkcyan", new PropertyValue(new RGBT(0x00008B8Bu))), - new EnumerationDef("darkgoldenrod", new PropertyValue(new RGBT(0x00B8860Bu))), - new EnumerationDef("darkgray", new PropertyValue(new RGBT(0x00A9A9A9u))), - new EnumerationDef("darkgreen", new PropertyValue(new RGBT(0x00006400u))), - new EnumerationDef("darkkhaki", new PropertyValue(new RGBT(0x00BDB76Bu))), - new EnumerationDef("darkmagenta", new PropertyValue(new RGBT(0x008B008Bu))), - new EnumerationDef("darkolivegreen", new PropertyValue(new RGBT(0x00556B2Fu))), - new EnumerationDef("darkorange", new PropertyValue(new RGBT(0x00FF8C00u))), - new EnumerationDef("darkorchid", new PropertyValue(new RGBT(0x009932CCu))), - new EnumerationDef("darkred", new PropertyValue(new RGBT(0x008B0000u))), - new EnumerationDef("darksalmon", new PropertyValue(new RGBT(0x00E9967Au))), - new EnumerationDef("darkseagreen", new PropertyValue(new RGBT(0x008FBC8Fu))), - new EnumerationDef("darkslateblue", new PropertyValue(new RGBT(0x00483D8Bu))), - new EnumerationDef("darkslategray", new PropertyValue(new RGBT(0x002F4F4Fu))), - new EnumerationDef("darkturquoise", new PropertyValue(new RGBT(0x0000CED1u))), - new EnumerationDef("darkviolet", new PropertyValue(new RGBT(0x009400D3u))), - new EnumerationDef("deeppink", new PropertyValue(new RGBT(0x00FF1493u))), - new EnumerationDef("deepskyblue", new PropertyValue(new RGBT(0x0000BFFFu))), - new EnumerationDef("dimgray", new PropertyValue(new RGBT(0x00696969u))), - new EnumerationDef("dodgerblue", new PropertyValue(new RGBT(0x001E90FFu))), - new EnumerationDef("firebrick", new PropertyValue(new RGBT(0x00B22222u))), - new EnumerationDef("floralwhite", new PropertyValue(new RGBT(0x00FFFAF0u))), - new EnumerationDef("forestgreen", new PropertyValue(new RGBT(0x00228B22u))), - new EnumerationDef("fuchsia", new PropertyValue(new RGBT(0x00FF00FFu))), - new EnumerationDef("gainsboro", new PropertyValue(new RGBT(0x00DCDCDCu))), - new EnumerationDef("ghostwhite", new PropertyValue(new RGBT(0x00F8F8FFu))), - new EnumerationDef("gold", new PropertyValue(new RGBT(0x00FFD700u))), - new EnumerationDef("goldenrod", new PropertyValue(new RGBT(0x00DAA520u))), - new EnumerationDef("gray", new PropertyValue(new RGBT(0x00808080u))), - new EnumerationDef("graytext", new PropertyValue(SystemColors.GrayText)), - new EnumerationDef("green", new PropertyValue(new RGBT(0x00008000u))), - new EnumerationDef("greenyellow", new PropertyValue(new RGBT(0x00ADFF2Fu))), - new EnumerationDef("highlight", new PropertyValue(SystemColors.Highlight)), - new EnumerationDef("highlighttext", new PropertyValue(SystemColors.HighlightText)), - new EnumerationDef("honeydew", new PropertyValue(new RGBT(0x00F0FFF0u))), - new EnumerationDef("hotpink", new PropertyValue(new RGBT(0x00FF69B4u))), - new EnumerationDef("inactiveborder", new PropertyValue(SystemColors.InactiveBorder)), - new EnumerationDef("inactivecaption", new PropertyValue(SystemColors.InactiveCaption)), - new EnumerationDef("inactivecaptiontext", new PropertyValue(SystemColors.InactiveCaptionText)), - new EnumerationDef("indianred", new PropertyValue(new RGBT(0x00CD5C5Cu))), - new EnumerationDef("indigo", new PropertyValue(new RGBT(0x004B0082u))), - new EnumerationDef("infobackground", new PropertyValue(SystemColors.InfoBackground)), - new EnumerationDef("infotext", new PropertyValue(SystemColors.InfoText)), - new EnumerationDef("ivory", new PropertyValue(new RGBT(0x00FFFFF0u))), - new EnumerationDef("khaki", new PropertyValue(new RGBT(0x00F0E68Cu))), - new EnumerationDef("lavender", new PropertyValue(new RGBT(0x00E6E6FAu))), - new EnumerationDef("lavenderblush", new PropertyValue(new RGBT(0x00FFF0F5u))), - new EnumerationDef("lawngreen", new PropertyValue(new RGBT(0x007CFC00u))), - new EnumerationDef("lemonchiffon", new PropertyValue(new RGBT(0x00FFFACDu))), - new EnumerationDef("lightblue", new PropertyValue(new RGBT(0x00ADD8E6u))), - new EnumerationDef("lightcoral", new PropertyValue(new RGBT(0x00F08080u))), - new EnumerationDef("lightcyan", new PropertyValue(new RGBT(0x00E0FFFFu))), - new EnumerationDef("lightgoldenrodyellow", new PropertyValue(new RGBT(0x00FAFAD2u))), - new EnumerationDef("lightgreen", new PropertyValue(new RGBT(0x0090EE90u))), - new EnumerationDef("lightgrey", new PropertyValue(new RGBT(0x00D3D3D3u))), - new EnumerationDef("lightpink", new PropertyValue(new RGBT(0x00FFB6C1u))), - new EnumerationDef("lightsalmon", new PropertyValue(new RGBT(0x00FFA07Au))), - new EnumerationDef("lightseagreen", new PropertyValue(new RGBT(0x0020B2AAu))), - new EnumerationDef("lightskyblue", new PropertyValue(new RGBT(0x0087CEFAu))), - new EnumerationDef("lightslategray", new PropertyValue(new RGBT(0x00778899u))), - new EnumerationDef("lightsteelblue", new PropertyValue(new RGBT(0x00B0C4DEu))), - new EnumerationDef("lightyellow", new PropertyValue(new RGBT(0x00FFFFE0u))), - new EnumerationDef("lime", new PropertyValue(new RGBT(0x0000FF00u))), - new EnumerationDef("limegreen", new PropertyValue(new RGBT(0x0032CD32u))), - new EnumerationDef("linen", new PropertyValue(new RGBT(0x00FAF0E6u))), - new EnumerationDef("magenta", new PropertyValue(new RGBT(0x00FF00FFu))), - new EnumerationDef("maroon", new PropertyValue(new RGBT(0x00800000u))), - new EnumerationDef("mediumaquamarine", new PropertyValue(new RGBT(0x0066CDAAu))), - new EnumerationDef("mediumblue", new PropertyValue(new RGBT(0x000000CDu))), - new EnumerationDef("mediumorchid", new PropertyValue(new RGBT(0x00BA55D3u))), - new EnumerationDef("mediumpurple", new PropertyValue(new RGBT(0x009370DBu))), - new EnumerationDef("mediumseagreen", new PropertyValue(new RGBT(0x003CB371u))), - new EnumerationDef("mediumslateblue", new PropertyValue(new RGBT(0x007B68EEu))), - new EnumerationDef("mediumspringgreen", new PropertyValue(new RGBT(0x0000FA9Au))), - new EnumerationDef("mediumturquoise", new PropertyValue(new RGBT(0x0048D1CCu))), - new EnumerationDef("mediumvioletred", new PropertyValue(new RGBT(0x00C71585u))), - new EnumerationDef("menu", new PropertyValue(SystemColors.Menu)), - new EnumerationDef("menutext", new PropertyValue(SystemColors.MenuText)), - new EnumerationDef("midnightblue", new PropertyValue(new RGBT(0x00191970u))), - new EnumerationDef("mintcream", new PropertyValue(new RGBT(0x00F5FFFAu))), - new EnumerationDef("mistyrose", new PropertyValue(new RGBT(0x00FFE4E1u))), - new EnumerationDef("moccasin", new PropertyValue(new RGBT(0x00FFE4B5u))), - new EnumerationDef("navajowhite", new PropertyValue(new RGBT(0x00FFDEADu))), - new EnumerationDef("navy", new PropertyValue(new RGBT(0x00000080u))), - new EnumerationDef("oldlace", new PropertyValue(new RGBT(0x00FDF5E6u))), - new EnumerationDef("olive", new PropertyValue(new RGBT(0x00808000u))), - new EnumerationDef("olivedrab", new PropertyValue(new RGBT(0x006B8E23u))), - new EnumerationDef("orange", new PropertyValue(new RGBT(0x00FFA500u))), - new EnumerationDef("orangered", new PropertyValue(new RGBT(0x00FF4500u))), - new EnumerationDef("orchid", new PropertyValue(new RGBT(0x00DA70D6u))), - new EnumerationDef("palegoldenrod", new PropertyValue(new RGBT(0x00EEE8AAu))), - new EnumerationDef("palegreen", new PropertyValue(new RGBT(0x0098FB98u))), - new EnumerationDef("paleturquoise", new PropertyValue(new RGBT(0x00AFEEEEu))), - new EnumerationDef("palevioletred", new PropertyValue(new RGBT(0x00DB7093u))), - new EnumerationDef("papayawhip", new PropertyValue(new RGBT(0x00FFEFD5u))), - new EnumerationDef("peachpuff", new PropertyValue(new RGBT(0x00FFDAB9u))), - new EnumerationDef("peru", new PropertyValue(new RGBT(0x00CD853Fu))), - new EnumerationDef("pink", new PropertyValue(new RGBT(0x00FFC0CBu))), - new EnumerationDef("plum", new PropertyValue(new RGBT(0x00DDA0DDu))), - new EnumerationDef("powderblue", new PropertyValue(new RGBT(0x00B0E0E6u))), - new EnumerationDef("purple", new PropertyValue(new RGBT(0x00800080u))), - new EnumerationDef("red", new PropertyValue(new RGBT(0x00FF0000u))), - new EnumerationDef("rosybrown", new PropertyValue(new RGBT(0x00BC8F8Fu))), - new EnumerationDef("royalblue", new PropertyValue(new RGBT(0x004169E1u))), - new EnumerationDef("saddlebrown", new PropertyValue(new RGBT(0x008B4513u))), - new EnumerationDef("salmon", new PropertyValue(new RGBT(0x00FA8072u))), - new EnumerationDef("sandybrown", new PropertyValue(new RGBT(0x00F4A460u))), - new EnumerationDef("scrollbar", new PropertyValue(SystemColors.Scrollbar)), - new EnumerationDef("seagreen", new PropertyValue(new RGBT(0x002E8B57u))), - new EnumerationDef("seashell", new PropertyValue(new RGBT(0x00FFF5EEu))), - new EnumerationDef("sienna", new PropertyValue(new RGBT(0x00A0522Du))), - new EnumerationDef("silver", new PropertyValue(new RGBT(0x00C0C0C0u))), - new EnumerationDef("skyblue", new PropertyValue(new RGBT(0x0087CEEBu))), - new EnumerationDef("slateblue", new PropertyValue(new RGBT(0x006A5ACDu))), - new EnumerationDef("slategray", new PropertyValue(new RGBT(0x00708090u))), - new EnumerationDef("snow", new PropertyValue(new RGBT(0x00FFFAFAu))), - new EnumerationDef("springgreen", new PropertyValue(new RGBT(0x0000FF7Fu))), - new EnumerationDef("steelblue", new PropertyValue(new RGBT(0x004682B4u))), - new EnumerationDef("tan", new PropertyValue(new RGBT(0x00D2B48Cu))), - new EnumerationDef("teal", new PropertyValue(new RGBT(0x00008080u))), - new EnumerationDef("thistle", new PropertyValue(new RGBT(0x00D8BFD8u))), - new EnumerationDef("threeddarkshadow", new PropertyValue(SystemColors.ThreeDDarkShadow)), - new EnumerationDef("threedface", new PropertyValue(SystemColors.ThreeDFace)), - new EnumerationDef("threedhighlight", new PropertyValue(SystemColors.ThreeDHighlight)), - new EnumerationDef("threedlightshadow", new PropertyValue(SystemColors.ThreeDLightShadow)), - new EnumerationDef("threedshadow", new PropertyValue(SystemColors.ThreeDShadow)), - new EnumerationDef("tomato", new PropertyValue(new RGBT(0x00FF6347u))), - new EnumerationDef("transparent", new PropertyValue(new RGBT(0u, 0u, 0u, 7u))), - new EnumerationDef("turquoise", new PropertyValue(new RGBT(0x0040E0D0u))), - new EnumerationDef("violet", new PropertyValue(new RGBT(0x00EE82EEu))), - new EnumerationDef("wheat", new PropertyValue(new RGBT(0x00F5DEB3u))), - new EnumerationDef("white", new PropertyValue(new RGBT(0x00FFFFFFu))), - new EnumerationDef("whitesmoke", new PropertyValue(new RGBT(0x00F5F5F5u))), - new EnumerationDef("window", new PropertyValue(SystemColors.Window)), - new EnumerationDef("windowframe", new PropertyValue(SystemColors.WindowFrame)), - new EnumerationDef("windowtext", new PropertyValue(SystemColors.WindowText)), - new EnumerationDef("yellow", new PropertyValue(new RGBT(0x00FFFF00u))), - new EnumerationDef("yellowgreen", new PropertyValue(new RGBT(0x009ACD32u))), - }; - - private static Dictionary colorToNameDictionary = BuildColorToNameDictionary(); - - private static Dictionary BuildColorToNameDictionary() - { - var result = new Dictionary(); - - foreach (var def in colorNames) - { - if (!result.ContainsKey(def.value)) - { - result.Add(def.value, def.name); - } - } - - return result; - } - - private static PropertyValue ParseNamedColor(BufferString value) - { - - - var lo = 0; - var hi = colorNames.Length - 1; - - while (lo <= hi) - { - var i = lo + ((hi -lo) >> 1); - - var order = BufferString.CompareLowerCaseStringToBufferStringIgnoreCase(colorNames[i].name, value); - if (order == 0) - { - return colorNames[i].value; - } - - if (order < 0) - { - lo = i + 1; - } - else - { - hi = i - 1; - } - } - - return PropertyValue.Null; - } - - internal static PropertyValue TranslateSystemColor(PropertyValue value) - { - InternalDebug.Assert(value.IsEnum); - - switch ((SystemColors)value.Enum) - { - - case SystemColors.ActiveBorder: return new PropertyValue(new RGBT(0x00000000)); - case SystemColors.ActiveCaption: return new PropertyValue(new RGBT(0x00FFFFFF)); - case SystemColors.AppWorkspace: return new PropertyValue(new RGBT(0x00FFFFFF)); - case SystemColors.Background: return new PropertyValue(new RGBT(0x00FFFFFF)); - case SystemColors.ButtonFace: return new PropertyValue(new RGBT(0x00FFFFFF)); - case SystemColors.ButtonHighlight: return new PropertyValue(new RGBT(0x00FFFFFF)); - case SystemColors.ButtonShadow: return new PropertyValue(new RGBT(0x00FFFFFF)); - case SystemColors.ButtonText: return new PropertyValue(new RGBT(0x00000000)); - case SystemColors.CaptionText: return new PropertyValue(new RGBT(0x00000000)); - case SystemColors.GrayText: return new PropertyValue(new RGBT(0x00000000)); - case SystemColors.Highlight: return new PropertyValue(new RGBT(0x00FFFFFF)); - case SystemColors.HighlightText: return new PropertyValue(new RGBT(0x00000000)); - case SystemColors.InactiveBorder: return new PropertyValue(new RGBT(0x00000000)); - case SystemColors.InactiveCaption: return new PropertyValue(new RGBT(0x00FFFFFF)); - case SystemColors.InactiveCaptionText: return new PropertyValue(new RGBT(0x00000000)); - case SystemColors.InfoBackground: return new PropertyValue(new RGBT(0x00FFFFFF)); - case SystemColors.InfoText: return new PropertyValue(new RGBT(0x00000000)); - case SystemColors.Menu: return new PropertyValue(new RGBT(0x00FFFFFF)); - case SystemColors.MenuText: return new PropertyValue(new RGBT(0x00000000)); - case SystemColors.Scrollbar: return new PropertyValue(new RGBT(0x00FFFFFF)); - case SystemColors.ThreeDDarkShadow: return new PropertyValue(new RGBT(0x00FFFFFF)); - case SystemColors.ThreeDLightShadow: return new PropertyValue(new RGBT(0x00FFFFFF)); - case SystemColors.Window: return new PropertyValue(new RGBT(0x00FFFFFF)); - case SystemColors.WindowFrame: return new PropertyValue(new RGBT(0x00000000)); - case SystemColors.WindowText: return new PropertyValue(new RGBT(0x00000000)); - } - - InternalDebug.Assert(false); - return PropertyValue.Null; - } - - private static PropertyValue ParseRgbColor(BufferString value) - { - if (value.Length <= 4 || !value.StartsWithLowerCaseStringIgnoreCase("rgb(")) - { - return PropertyValue.Null; - } - - var offset = 4; - uint r, g, b; - - if (!ParseRgbParam(value, ref offset, out r)) - { - return PropertyValue.Null; - } - - if (!ParseRgbParam(value, ref offset, out g)) - { - return PropertyValue.Null; - } - - if (!ParseRgbParam(value, ref offset, out b)) - { - return PropertyValue.Null; - } - - if (offset != value.Length - 1 || value[offset] != ')') - { - return PropertyValue.Null; - } - - return new PropertyValue(new RGBT(r, g, b)); - } - - private static bool ParseRgbParam(BufferString str, ref int offset, out uint result) - { - uint value = 0; - uint fractionDecimal = 1; - var isNegative = false; - - while (offset < str.Length && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(str[offset]))) - { - offset++; - } - - if (offset < str.Length && str[offset] == '-') - { - isNegative = true; - offset++; - } - - if (offset == str.Length || !ParseSupport.NumericCharacter(ParseSupport.GetCharClass(str[offset]))) - { - result = 0; - return false; - } - - while (offset < str.Length && ParseSupport.NumericCharacter(ParseSupport.GetCharClass(str[offset]))) - { - value *= 10; - value += (uint)str[offset] - '0'; - offset++; - if (value > 255) - { - while (offset < str.Length && ParseSupport.NumericCharacter(ParseSupport.GetCharClass(str[offset]))) - { - offset++; - } - } - } - - if (offset < str.Length && str[offset] == '.') - { - offset++; - while (offset < str.Length && ParseSupport.NumericCharacter(ParseSupport.GetCharClass(str[offset]))) - { - value *= 10; - value += (uint)str[offset] - '0'; - fractionDecimal *= 10; - offset++; - - if (value > (Int32.MaxValue / 5100)) - { - while (offset < str.Length && ParseSupport.NumericCharacter(ParseSupport.GetCharClass(str[offset]))) - { - offset++; - } - } - } - } - - if (offset < str.Length && str[offset] == '%') - { - if (value / fractionDecimal >= 100) - result = 255; - else - result = (value * 255) / (fractionDecimal * 100); - offset++; - } - else - { - if (value / fractionDecimal > 255) - result = 255; - else - result = value / fractionDecimal; - } - - while (offset < str.Length && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(str[offset]))) - { - offset++; - } - - if (offset < str.Length && str[offset] == ',') - { - offset++; - } - - if ( isNegative ) - result = 0; - - return true; - } - - - - - - - - - - - - - - - private static bool ParseHexColor(BufferString str, int offset, bool css, out RGBT rgbt) - { - var length = str.Length - offset; - if (css && length != 3 && length != 6 && length != 9) - { - rgbt = new RGBT(); - return false; - } - - var vlen = (str.Length - offset + 3 - 1) / 3; - uint r, g, b; - uint max = 0; - - - if (!ParseHexColorPart(vlen, str, ref offset, ref max, css, out r) || - !ParseHexColorPart(vlen, str, ref offset, ref max, css, out g) || - !ParseHexColorPart(vlen, str, ref offset, ref max, css, out b)) - { - rgbt = new RGBT(); - return false; - } - - - - - int i; - for (i = 0 ; max > 255 ; i++) - { - max >>= 4; - } - - if (i > 0) - { - r >>= i * 4; - g >>= i * 4; - b >>= i * 4; - } - - - - - if (css) - { - - if (vlen == 1) - { - r += r << 4; - g += g << 4; - b += b << 4; - } - } - - rgbt = new RGBT(r, g, b); - return true; - } - - private static bool ParseHexColorPart(int vlen, BufferString str, ref int offset, ref uint max, bool css, out uint result) - { - result = 0; - - for (var j = 0; j < vlen; j++) - { - int hex; - if (offset >= str.Length) - { - if (css) - { - return false; - } - hex = 0; - } - else - { - if (ParseSupport.HexCharacter(ParseSupport.GetCharClass(str[offset]))) - { - hex = ParseSupport.CharToHex(str[offset]); - } - else - { - if (css) - { - return false; - } - hex = 0; - } - } - - result = (result << 4) + (uint)hex; - offset ++; - } - - if (result > max) - { - max = result; - } - return true; - } - - private static bool ParseHexColorEnriched(BufferString str, int offset, out RGBT rgbt) - { - uint r, g, b; - - - if (!ParseHexColorPartEnriched(str, ref offset, out r) || - !ParseHexColorPartEnriched(str, ref offset, out g) || - !ParseHexColorPartEnriched(str, ref offset, out b)) - { - rgbt = new RGBT(); - return false; - } - - - - r >>= 8; - g >>= 8; - b >>= 8; - - rgbt = new RGBT(r, g, b); - return true; - } - - private static bool ParseHexColorPartEnriched(BufferString str, ref int offset, out uint result) - { - result = 0; - - for (var j = 0; j < 4; j++) - { - int hex; - - if (offset >= str.Length) - { - hex = 0; - } - else - { - if (ParseSupport.HexCharacter(ParseSupport.GetCharClass(str[offset]))) - { - hex = ParseSupport.CharToHex(str[offset]); - } - else - { - hex = 0; - } - - offset ++; - } - - result = (result << 4) + (uint)hex; - } - - if (offset < str.Length && str[offset] == ',') - { - offset ++; - } - - return true; - } - - - - internal static PropertyValue ParseStringProperty(BufferString value, FormatConverter formatConverter) - { - value.TrimWhitespace(); - if (value.Length == 0) - { - return PropertyValue.Null; - } - - var sv = formatConverter.RegisterStringValue(false, value.ToString(), 0, value.Length); - return sv.PropertyValue; - } - - - - internal static PropertyValue ParseFontFace(BufferString value, FormatConverter formatConverter) - { - var offset = 0; - var end = value.Length; - - - while (offset < end && (value[offset] == ',' || ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[offset])))) - { - offset++; - } - - if (offset == end) - { - return PropertyValue.Null; - } - - var chStop = ','; - if (value[offset] == '\'' || value[offset] == '\"') - { - chStop = value[offset]; - offset ++; - } - - var endName = offset; - var nextName = offset; - while (endName < end && value[endName] != chStop) - { - - endName++; - nextName ++; - } - - - while (offset < endName && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[endName - 1]))) - { - endName--; - } - - var pv = formatConverter.RegisterFaceName(false, value.SubString(offset, endName - offset)); - - if (nextName < end) - { - - nextName ++; - } - - offset = nextName; - - - while (offset < end && (value[offset] == ',' || ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[offset])))) - { - offset++; - } - - if (offset == end) - { - - return pv; - } - - - - MultiValueBuilder mvBuilder; - var mv = formatConverter.RegisterMultiValue(false, out mvBuilder); - - if (!pv.IsNull) - { - mvBuilder.AddValue(pv); - } - - do - { - chStop = ','; - if (value[offset] == '\'' || value[offset] == '\"') - { - chStop = value[offset]; - offset ++; - } - - endName = offset; - nextName = offset; - while (endName < end && value[endName] != chStop) - { - - endName++; - nextName ++; - } - - nextName = endName; - - - while (offset < endName && ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[endName - 1]))) - { - endName--; - } - - pv = formatConverter.RegisterFaceName(false, value.SubString(offset, endName - offset)); - if (!pv.IsNull) - { - mvBuilder.AddValue(pv); - } - - if (nextName < end) - { - - nextName ++; - } - - offset = nextName; - - - while (offset < end && (value[offset] == ',' || ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(value[offset])))) - { - offset++; - } - } - while (offset < end); - - - if (mvBuilder.Count == 0) - { - mvBuilder.Cancel(); - mv.Release(); - return PropertyValue.Null; - } - else if (mvBuilder.Count == 1) - { - - pv = mvBuilder[0]; - if (pv.IsString) - { - formatConverter.GetStringValue(pv).AddRef(); - } - mvBuilder.Cancel(); - mv.Release(); - return pv; - } - - mvBuilder.Flush(); - return mv.PropertyValue; - } - - - - internal static PropertyValue ParseColor(BufferString value, FormatConverter formatConverter) - { - return ParseColor(value, false, false); - } - - internal static PropertyValue ParseColorCss(BufferString value, FormatConverter formatConverter) - { - return ParseColor(value, false, true); - } - - - - public static BufferString FormatColor(ref ScratchBuffer scratchBuffer, PropertyValue value) - { - scratchBuffer.Reset(); - AppendColor(ref scratchBuffer, value); - return scratchBuffer.BufferString; - } - - public static void AppendColor(ref ScratchBuffer scratchBuffer, PropertyValue value) - { - if (value.IsColor || value.IsEnum) - { - string name; - if (colorToNameDictionary.TryGetValue(value, out name)) - { - scratchBuffer.Append(name); - } - else - { - scratchBuffer.Append("#"); - scratchBuffer.AppendHex2(value.Color.Red); - scratchBuffer.AppendHex2(value.Color.Green); - scratchBuffer.AppendHex2(value.Color.Blue); - } - } - } - - - - internal static PropertyValue ParseFontSize(BufferString value, FormatConverter formatConverter) - { - return ParseNumber(value, NumberParseFlags.FontSize); - } - - - - internal static PropertyValue ParseInteger(BufferString value, FormatConverter formatConverter) - { - return ParseNumber(value, NumberParseFlags.Integer); - } - - - - internal static PropertyValue ParseNonNegativeInteger(BufferString value, FormatConverter formatConverter) - { - return ParseNumber(value, NumberParseFlags.Integer | NumberParseFlags.NonNegative); - } - - - - internal static PropertyValue ParseLength(BufferString value, FormatConverter formatConverter) - { - return ParseNumber(value, NumberParseFlags.Length); - } - - - - internal static PropertyValue ParseNonNegativeLength(BufferString value, FormatConverter formatConverter) - { - return ParseNumber(value, NumberParseFlags.NonNegativeLength); - } - - - - internal static PropertyValue ParseUrl(BufferString value, FormatConverter formatConverter) - { - return ParseStringProperty(value, formatConverter); - } - - - - public static void ScanSkipWhitespace(ref BufferString value) - { - var count = value.Length; - var offset = value.Offset; - - while (count != 0 && ParseSupport.WhitespaceCharacter(value.Buffer[offset])) - { - offset++; - count --; - } - - value.Trim(offset - value.Offset, count); - } - - - - public static void ScanRevertLastToken(ref BufferString value, BufferString token) - { - InternalDebug.Assert(value.Offset == token.Offset + token.Length && value.Buffer == token.Buffer); - - value.Set(value.Buffer, token.Offset, value.Length + token.Length); - } - - - - public static BufferString ScanNextNonWhitespaceToken(ref BufferString value) - { - - - - var count = value.Length; - var offset = value.Offset; - - while (count != 0 && !ParseSupport.WhitespaceCharacter(value.Buffer[offset])) - { - offset++; - count --; - } - - var result = new BufferString(value.Buffer, value.Offset, offset - value.Offset); - - value.Trim(offset - value.Offset, count); - - return result; - } - - - - public static BufferString ScanNextParenthesizedToken(ref BufferString value) - { - - - - var count = value.Length; - var offset = value.Offset; - - var quoteChar = '\"'; - var inQuotes = false; - var parenDepth = 0; - - while (count != 0 && (parenDepth != 0 || !ParseSupport.WhitespaceCharacter(value.Buffer[offset]))) - { - var ch = value.Buffer[offset]; - - if (!inQuotes) - { - if (ch == '\'' || ch == '\"') - { - inQuotes = true; - quoteChar = ch; - } - else if (parenDepth != 0 && ch == ')') - { - parenDepth --; - } - else if (ch == '(') - { - parenDepth ++; - } - } - else if (ch == quoteChar) - { - inQuotes = false; - } - - offset++; - count --; - } - - var result = new BufferString(value.Buffer, value.Offset, offset - value.Offset); - - value.Trim(offset - value.Offset, count); - - return result; - } - - - - public static BufferString ScanNextSize(ref BufferString value) - { - var count = value.Length; - var offset = value.Offset; - - var ch = '\0'; - - - if (count != 0) - { - ch = value.Buffer[offset]; - if (ch == '-' || ch == '+') - { - offset++; - count--; - } - - - if (count == 0 || (!ParseSupport.NumericCharacter(ch = value.Buffer[offset]) && ch != '.')) - { - - - while (count != 0 && (ParseSupport.AlphaCharacter(ch = value.Buffer[offset]) || ch == '-')) - { - offset++; - count--; - } - } - else - { - - - - while (count != 0 && (ParseSupport.NumericCharacter(ch = value.Buffer[offset]) || ch == '.')) - { - offset++; - count--; - } - - - var offsetLastSpace = offset; - while (count != 0 && ParseSupport.WhitespaceCharacter(value.Buffer[offset])) - { - offset++; - count --; - } - - - if (count >= 2 - && (((ch = ParseSupport.ToLowerCase(value.Buffer[offset])) == 'i' && ParseSupport.ToLowerCase(value.Buffer[offset + 1]) == 'n') - || (ch == 'c' && ParseSupport.ToLowerCase(value.Buffer[offset + 1]) == 'm') - || (ch == 'm' && ParseSupport.ToLowerCase(value.Buffer[offset + 1]) == 'm') - || (ch == 'e' && (ParseSupport.ToLowerCase(value.Buffer[offset + 1]) == 'm' - || ParseSupport.ToLowerCase(value.Buffer[offset + 1]) == 'x')) - || (ch == 'p' && (ParseSupport.ToLowerCase(value.Buffer[offset + 1]) == 't' - || ParseSupport.ToLowerCase(value.Buffer[offset + 1]) == 'c' - || ParseSupport.ToLowerCase(value.Buffer[offset + 1]) == 'x')))) - { - offset += 2; - count -= 2; - } - else if (count != 0 && value.Buffer[offset] == '%') - { - offset ++; - count --; - } - else - { - - - - count += offset - offsetLastSpace; - offset = offsetLastSpace; - } - } - } - - var result = new BufferString(value.Buffer, value.Offset, offset - value.Offset); - - value.Trim(offset - value.Offset, count); - - return result; - } - - - - internal static void ParseCompositeFourSidesValue(BufferString value, FormatConverter formatConverter, PropertyId groupPropertyId, Property[] outputProperties, out int parsedPropertiesCount, PropertyValueParsingMethod valueParsingMethod, bool measurements) - { - InternalDebug.Assert(outputProperties.Length >= 4); - - var word = BufferString.Null; - - ScanSkipWhitespace(ref value); - - var numValues = 0; - - if (!value.IsEmpty) - { - if (!measurements) - { - word = ScanNextParenthesizedToken(ref value); - } - else - { - word = ScanNextSize(ref value); - } - - outputProperties[numValues].Value = valueParsingMethod(word, formatConverter); - - if (!outputProperties[numValues].Value.IsNull) - { - numValues ++; - - ScanSkipWhitespace(ref value); - - if (!value.IsEmpty) - { - if (!measurements) - { - word = ScanNextParenthesizedToken(ref value); - } - else - { - word = ScanNextSize(ref value); - } - - outputProperties[numValues].Value = valueParsingMethod(word, formatConverter); - - if (!outputProperties[numValues].Value.IsNull) - { - numValues ++; - - ScanSkipWhitespace(ref value); - - if (!value.IsEmpty) - { - if (!measurements) - { - word = ScanNextParenthesizedToken(ref value); - } - else - { - word = ScanNextSize(ref value); - } - - outputProperties[numValues].Value = valueParsingMethod(word, formatConverter); - - if (!outputProperties[numValues].Value.IsNull) - { - numValues ++; - - ScanSkipWhitespace(ref value); - - if (!value.IsEmpty) - { - if (!measurements) - { - word = ScanNextParenthesizedToken(ref value); - } - else - { - word = ScanNextSize(ref value); - } - - outputProperties[numValues].Value = valueParsingMethod(word, formatConverter); - - if (!outputProperties[numValues].Value.IsNull) - { - numValues ++; - - - } - } - } - } - } - } - } - } - - if (numValues == 1) - { - outputProperties[0].Id = groupPropertyId + (int)Side.Top; - outputProperties[1].Set(groupPropertyId + (int)Side.Right, outputProperties[0].Value); - outputProperties[2].Set(groupPropertyId + (int)Side.Bottom, outputProperties[0].Value); - outputProperties[3].Set(groupPropertyId + (int)Side.Left, outputProperties[0].Value); - parsedPropertiesCount = 4; - } - else if (numValues == 2) - { - outputProperties[0].Id = groupPropertyId + (int)Side.Top; - outputProperties[1].Id = groupPropertyId + (int)Side.Right; - outputProperties[2].Set(groupPropertyId + (int)Side.Bottom, outputProperties[0].Value); - outputProperties[3].Set(groupPropertyId + (int)Side.Left, outputProperties[1].Value); - parsedPropertiesCount = 4; - } - else if (numValues == 3) - { - outputProperties[0].Id = groupPropertyId + (int)Side.Top; - outputProperties[1].Id = groupPropertyId + (int)Side.Right; - outputProperties[2].Id = groupPropertyId + (int)Side.Bottom; - outputProperties[3].Set(groupPropertyId + (int)Side.Left, outputProperties[1].Value); - parsedPropertiesCount = 4; - } - else if (numValues == 4) - { - outputProperties[0].Id = groupPropertyId + (int)Side.Top; - outputProperties[1].Id = groupPropertyId + (int)Side.Right; - outputProperties[2].Id = groupPropertyId + (int)Side.Bottom; - outputProperties[3].Id = groupPropertyId + (int)Side.Left; - parsedPropertiesCount = 4; - } - else - { - parsedPropertiesCount = 0; - } - } - - - - internal static void ParseCompositeLength(BufferString value, FormatConverter formatConverter, PropertyId groupPropertyId, Property[] outputProperties, out int parsedPropertiesCount) - { - ParseCompositeFourSidesValue(value, formatConverter, groupPropertyId, outputProperties, out parsedPropertiesCount, HtmlConverterData.PropertyValueParsingMethods.ParseLength, true); - } - - - - internal static void ParseCompositeNonNegativeLength(BufferString value, FormatConverter formatConverter, PropertyId groupPropertyId, Property[] outputProperties, out int parsedPropertiesCount) - { - ParseCompositeFourSidesValue(value, formatConverter, groupPropertyId, outputProperties, out parsedPropertiesCount, HtmlConverterData.PropertyValueParsingMethods.ParseNonNegativeLength, true); - } - - - - internal static void ParseCompositeColor(BufferString value, FormatConverter formatConverter, PropertyId groupPropertyId, Property[] outputProperties, out int parsedPropertiesCount) - { - ParseCompositeFourSidesValue(value, formatConverter, groupPropertyId, outputProperties, out parsedPropertiesCount, HtmlConverterData.PropertyValueParsingMethods.ParseColorCss, false); - } - - - - internal static void ParseCompositeBorderWidth(BufferString value, FormatConverter formatConverter, PropertyId groupPropertyId, Property[] outputProperties, out int parsedPropertiesCount) - { - ParseCompositeFourSidesValue(value, formatConverter, groupPropertyId, outputProperties, out parsedPropertiesCount, HtmlConverterData.PropertyValueParsingMethods.ParseBorderWidth, true); - } - - - - internal static void ParseCompositeBorderStyle(BufferString value, FormatConverter formatConverter, PropertyId groupPropertyId, Property[] outputProperties, out int parsedPropertiesCount) - { - ParseCompositeFourSidesValue(value, formatConverter, groupPropertyId, outputProperties, out parsedPropertiesCount, HtmlConverterData.PropertyValueParsingMethods.ParseBorderStyle, false); - } - - - - internal static void ParseCompoundBorderSpacing(BufferString value, FormatConverter formatConverter, PropertyId groupPropertyId, Property[] outputProperties, out int parsedPropertiesCount) - { - InternalDebug.Assert(outputProperties.Length >= 4); - - var word = BufferString.Null; - - ScanSkipWhitespace(ref value); - - var numValues = 0; - - if (!value.IsEmpty) - { - word = ScanNextSize(ref value); - - outputProperties[numValues].Value = HtmlConverterData.PropertyValueParsingMethods.ParseNonNegativeLength(word, formatConverter); - - if (!outputProperties[numValues].Value.IsNull) - { - numValues ++; - - ScanSkipWhitespace(ref value); - - if (!value.IsEmpty) - { - word = ScanNextSize(ref value); - - outputProperties[numValues].Value = HtmlConverterData.PropertyValueParsingMethods.ParseNonNegativeLength(word, formatConverter); - - if (!outputProperties[numValues].Value.IsNull) - { - numValues ++; - } - } - } - } - - if (numValues == 1) - { - outputProperties[0].Id = groupPropertyId; - outputProperties[1].Set(groupPropertyId + 1, outputProperties[0].Value); - parsedPropertiesCount = 2; - } - else if (numValues == 2) - { - outputProperties[0].Id = groupPropertyId; - outputProperties[1].Id = groupPropertyId + 1; - parsedPropertiesCount = 2; - } - else - { - parsedPropertiesCount = 0; - } - } - - - - internal static void ParseCompositeBorder(BufferString value, FormatConverter formatConverter, PropertyId groupPropertyId, Property[] outputProperties, out int parsedPropertiesCount) - { - InternalDebug.Assert(outputProperties.Length >= 3); - - var word = BufferString.Null; - - ScanSkipWhitespace(ref value); - - var numValues = 0; - - InternalDebug.Assert(groupPropertyId == PropertyId.TopBorderWidth || groupPropertyId == PropertyId.RightBorderWidth || groupPropertyId == PropertyId.BottomBorderWidth || groupPropertyId == PropertyId.LeftBorderWidth); - InternalDebug.Assert(PropertyId.BorderWidths + 4 == PropertyId.BorderStyles && PropertyId.BorderWidths + 8 == PropertyId.BorderColors); - - var widthIndex = -1; - var styleIndex = -1; - var colorIndex = -1; - - while (!value.IsEmpty) - { - word = ScanNextParenthesizedToken(ref value); - - - var val = ParseBorderWidth(word, formatConverter); - - if (val.IsNull) - { - - val = ParseBorderStyle(word, formatConverter); - - if (val.IsNull) - { - - val = ParseColorCss(word, formatConverter); - - if (val.IsNull) - { - break; - } - else - { - - - if (colorIndex == -1) - { - colorIndex = numValues; - outputProperties[numValues++].Set(groupPropertyId + 8, val); - } - else - { - outputProperties[colorIndex].Set(groupPropertyId + 8, val); - } - } - } - else - { - - - if (styleIndex == -1) - { - styleIndex = numValues; - outputProperties[numValues++].Set(groupPropertyId + 4, val); - } - else - { - outputProperties[styleIndex].Set(groupPropertyId + 4, val); - } - } - } - else - { - - if (widthIndex == -1) - { - widthIndex = numValues; - outputProperties[numValues++].Set(groupPropertyId, val); - } - else - { - outputProperties[widthIndex].Set(groupPropertyId, val); - } - } - - ScanSkipWhitespace(ref value); - } - - parsedPropertiesCount = numValues; - } - - - - internal static void ParseCompositeAllBorders(BufferString value, FormatConverter formatConverter, PropertyId groupPropertyId, Property[] outputProperties, out int parsedPropertiesCount) - { - InternalDebug.Assert(outputProperties.Length >= 12); - - - ParseCompositeBorder(value, formatConverter, PropertyId.TopBorderWidth, outputProperties, out parsedPropertiesCount); - - InternalDebug.Assert(parsedPropertiesCount <= 3); - - - - for (var i = 0; i < parsedPropertiesCount; i++) - { - for (var j = 1; j < 4; j++) - { - outputProperties[parsedPropertiesCount * j + i].Set((PropertyId)((int)outputProperties[i].Id + j), outputProperties[i].Value); - } - } - - parsedPropertiesCount += parsedPropertiesCount * 3; - } - - - - internal static void ParseCompositeBackground(BufferString value, FormatConverter formatConverter, PropertyId groupPropertyId, Property[] outputProperties, out int parsedPropertiesCount) - { - InternalDebug.Assert(outputProperties.Length >= 1); - - - - - var word = BufferString.Null; - - ScanSkipWhitespace(ref value); - - var numValues = 0; - - if (!value.IsEmpty) - { - word = ScanNextNonWhitespaceToken(ref value); - outputProperties[numValues].Set(PropertyId.BackColor, ParseColorCss(word, formatConverter)); - if (!outputProperties[numValues].Value.IsNull) - { - numValues++; - } - - ScanSkipWhitespace(ref value); - } - - - - parsedPropertiesCount = numValues; - } - - - - - private enum TextDecoration - { - None, - Underline, - Overline, - LineThrough, - Blink, - } - - private static EnumerationDef[] CssTextDecorationEnumeration = - { - new EnumerationDef("underline",new PropertyValue(TextDecoration.Underline)), - new EnumerationDef("overline", new PropertyValue(TextDecoration.Overline)), - new EnumerationDef("line-through", new PropertyValue(TextDecoration.LineThrough)), - new EnumerationDef("blink", new PropertyValue(TextDecoration.Blink)), - new EnumerationDef("none", new PropertyValue(TextDecoration.None)), - }; - - internal static void ParseCssTextDecoration(BufferString value, FormatConverter formatConverter, PropertyId groupPropertyId, Property[] outputProperties, out int parsedPropertiesCount) - { - InternalDebug.Assert(outputProperties.Length >= 3); - - var word = BufferString.Null; - - ScanSkipWhitespace(ref value); - - var numValues = 0; - - - - word = ScanNextNonWhitespaceToken(ref value); - - var val = ParseEnum(word, CssTextDecorationEnumeration); - if (!val.IsNull) - { - switch ((TextDecoration)val.Enum) - { - case TextDecoration.None: - case TextDecoration.Overline: - case TextDecoration.Blink: - - outputProperties[numValues++].Set(PropertyId.Underline, PropertyValue.False); - outputProperties[numValues++].Set(PropertyId.Strikethrough, PropertyValue.False); - break; - - case TextDecoration.Underline: - - outputProperties[numValues++].Set(PropertyId.Underline, PropertyValue.True); - outputProperties[numValues++].Set(PropertyId.Strikethrough, PropertyValue.False); - break; - - case TextDecoration.LineThrough: - - outputProperties[numValues++].Set(PropertyId.Underline, PropertyValue.False); - outputProperties[numValues++].Set(PropertyId.Strikethrough, PropertyValue.True); - break; - } - } - - parsedPropertiesCount = numValues; - } - - - - - private enum TextTransform - { - Capitalize, - Uppercase, - Lowercase, - None, - } - - private static EnumerationDef[] CssTextTransformEnumeration = - { - new EnumerationDef("capitalize", new PropertyValue(TextTransform.Capitalize)), - new EnumerationDef("uppercase", new PropertyValue(TextTransform.Uppercase)), - new EnumerationDef("lowercase", new PropertyValue(TextTransform.Lowercase)), - new EnumerationDef("none", new PropertyValue(TextTransform.None)), - }; - - internal static void ParseCssTextTransform(BufferString value, FormatConverter formatConverter, PropertyId groupPropertyId, Property[] outputProperties, out int parsedPropertiesCount) - { - InternalDebug.Assert(outputProperties.Length >= 3); - - var word = BufferString.Null; - - ScanSkipWhitespace(ref value); - - var numValues = 0; - - word = ScanNextNonWhitespaceToken(ref value); - - - - - var val = ParseEnum(word, CssTextTransformEnumeration); - if (!val.IsNull) - { - switch ((TextTransform)val.Enum) - { - case TextTransform.None: - case TextTransform.Uppercase: - case TextTransform.Lowercase: - - outputProperties[numValues++].Set(PropertyId.Capitalize, PropertyValue.False); - break; - - case TextTransform.Capitalize: - - outputProperties[numValues++].Set(PropertyId.Capitalize, PropertyValue.True); - break; - } - } - - parsedPropertiesCount = numValues; - } - - - - - private static EnumerationDef[] CssVerticalAlignmentEnumeration = - { - new EnumerationDef("baseline", new PropertyValue(Align.BaseLine)), - new EnumerationDef("sub", new PropertyValue(Align.Sub)), - new EnumerationDef("super", new PropertyValue(Align.Super)), - new EnumerationDef("top", new PropertyValue(Align.Top)), - new EnumerationDef("text-top", new PropertyValue(Align.TextTop)), - new EnumerationDef("middle", new PropertyValue(Align.Middle)), - new EnumerationDef("bottom", new PropertyValue(Align.Bottom)), - new EnumerationDef("text-bottom", new PropertyValue(Align.TextBottom)), - }; - - internal static void ParseCssVerticalAlignment(BufferString value, FormatConverter formatConverter, PropertyId groupPropertyId, Property[] outputProperties, out int parsedPropertiesCount) - { - InternalDebug.Assert(outputProperties.Length >= 3); - - var word = BufferString.Null; - - ScanSkipWhitespace(ref value); - - var numValues = 0; - - word = ScanNextNonWhitespaceToken(ref value); - - - - - var val = ParseEnum(word, CssVerticalAlignmentEnumeration); - if (!val.IsNull) - { - switch ((Align)val.Enum) - { - case Align.TextTop: - case Align.TextBottom: - - break; - - case Align.Top: - case Align.Middle: - case Align.Bottom: - case Align.BaseLine: - - outputProperties[numValues++].Set(PropertyId.VerticalAlignment, val); - break; - - case Align.Sub: - - outputProperties[numValues++].Set(PropertyId.Subscript, PropertyValue.True); - outputProperties[numValues++].Set(PropertyId.Superscript, PropertyValue.False); - break; - - case Align.Super: - - outputProperties[numValues++].Set(PropertyId.Superscript, PropertyValue.True); - outputProperties[numValues++].Set(PropertyId.Subscript, PropertyValue.False); - break; - } - } - else - { - - } - - parsedPropertiesCount = numValues; - } - - - - - private enum CssWhiteSpace - { - Normal, - Pre, - Nowrap, - PreWrap, - PreLine, - } - - private static EnumerationDef[] CssWhiteSpaceEnumeration = - { - new EnumerationDef("normal", new PropertyValue(CssWhiteSpace.Normal)), - new EnumerationDef("pre", new PropertyValue(CssWhiteSpace.Pre)), - new EnumerationDef("nowrap", new PropertyValue(CssWhiteSpace.Nowrap)), - new EnumerationDef("pre-wrap", new PropertyValue(CssWhiteSpace.PreWrap)), - new EnumerationDef("pre-line", new PropertyValue(CssWhiteSpace.PreLine)), - }; - - internal static void ParseCssWhiteSpace(BufferString value, FormatConverter formatConverter, PropertyId groupPropertyId, Property[] outputProperties, out int parsedPropertiesCount) - { - InternalDebug.Assert(outputProperties.Length >= 3); - - var word = BufferString.Null; - - ScanSkipWhitespace(ref value); - - var numValues = 0; - - word = ScanNextNonWhitespaceToken(ref value); - - - - - var val = ParseEnum(word, CssWhiteSpaceEnumeration); - if (!val.IsNull) - { - switch ((CssWhiteSpace)val.Enum) - { - case CssWhiteSpace.Normal: - - break; - - case CssWhiteSpace.Pre: - case CssWhiteSpace.PreWrap: - case CssWhiteSpace.PreLine: - case CssWhiteSpace.Nowrap: - - outputProperties[numValues++].Set(PropertyId.Preformatted, PropertyValue.True); - break; - } - } - - parsedPropertiesCount = numValues; - } - - - - internal static void ParseCompositeFont(BufferString value, FormatConverter formatConverter, PropertyId groupPropertyId, Property[] outputProperties, out int parsedPropertiesCount) - { - InternalDebug.Assert(outputProperties.Length >= 6); - - var word = BufferString.Null; - - ScanSkipWhitespace(ref value); - - var numValues = 0; - - var weightIndex = -1; - var variantIndex = -1; - var styleIndex = -1; - - while (!value.IsEmpty) - { - word = ScanNextNonWhitespaceToken(ref value); - - - var val = ParseFontWeight(word, formatConverter); - - - - if (val.IsNull) - { - - val = ParseFontStyle(word, formatConverter); - - if (val.IsNull) - { - - val = ParseFontVariant(word, formatConverter); - - if (val.IsNull) - { - - break; - } - else - { - - - if (variantIndex == -1) - { - variantIndex = numValues; - outputProperties[numValues++].Set(PropertyId.SmallCaps, val); - } - else - { - outputProperties[variantIndex].Set(PropertyId.SmallCaps, val); - } - } - } - else - { - - - if (styleIndex == -1) - { - styleIndex = numValues; - outputProperties[numValues++].Set(PropertyId.Italic, val); - } - else - { - outputProperties[styleIndex].Set(PropertyId.Italic, val); - } - } - } - else - { - - if (weightIndex == -1) - { - weightIndex = numValues; - outputProperties[numValues++].Set(PropertyId.Bold, val); - } - else - { - outputProperties[weightIndex].Set(PropertyId.Bold, val); - } - } - - - word = BufferString.Null; - - ScanSkipWhitespace(ref value); - } - - if (!word.IsEmpty) - { - - ScanRevertLastToken(ref value, word); - - word = ScanNextSize(ref value); - - outputProperties[numValues].Set(PropertyId.FontSize, ParseCssFontSize(word, formatConverter)); - if (!outputProperties[numValues].Value.IsNull) - { - numValues ++; - } - } - - ScanSkipWhitespace(ref value); - - if (!value.IsEmpty && value[0] == '/') - { - value.Trim(1, value.Length - 1); - - ScanSkipWhitespace(ref value); - - word = ScanNextSize(ref value); - - var lineHeight = ParseNonNegativeLength(word, formatConverter); - - - - ScanSkipWhitespace(ref value); - } - - if (!value.IsEmpty) - { - outputProperties[numValues].Set(PropertyId.FontSize, ParseFontFace(value, formatConverter)); - if (!outputProperties[numValues].Value.IsNull) - { - numValues ++; - } - } - - parsedPropertiesCount = numValues; - } - } -} - diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlTextExtractionConverter.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlTextExtractionConverter.cs deleted file mode 100644 index 2fe0150f3..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlTextExtractionConverter.cs +++ /dev/null @@ -1,349 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters.Internal.Html -{ - using System; - using System.IO; - using System.Text; - using Data.Internal; - using Globalization; - - - internal class HtmlTextExtractionConverter : IProducerConsumer, IRestartable, IDisposable - { - - - private IHtmlParser parser; - private bool endOfFile; - - private ConverterOutput output; - - private bool outputAnchorLinks = true; - - private bool insideComment; - private bool insideAnchor; - - private CollapseWhitespaceState collapseWhitespaceState; - - - - public HtmlTextExtractionConverter( - IHtmlParser parser, - ConverterOutput output, - Stream traceStream, - bool traceShowTokenNum, - int traceStopOnTokenNum) - { - - this.output = output; - - this.parser = parser; - this.parser.SetRestartConsumer(this); - } - - - - public bool CanRestart() - { - return ((IRestartable)output).CanRestart(); - } - - - - public void Restart() - { - InternalDebug.Assert(CanRestart()); - - ((IRestartable)output).Restart(); - - - - endOfFile = false; - - insideComment = false; - insideAnchor = false; - } - - - - public void DisableRestart() - { - ((IRestartable)output).DisableRestart(); - } - - - - public void Run() - { - - if (!endOfFile) - { - var tokenId = parser.Parse(); - - if (HtmlTokenId.None != tokenId) - { - Process(tokenId); - } - } - } - - - - public bool Flush() - { - if (!endOfFile) - { - Run(); - } - - return endOfFile; - } - - - - - void IDisposable.Dispose() - { - if (parser != null /*&& this.parser is IDisposable*/) - { - ((IDisposable)parser).Dispose(); - } - - if (output != null && output is IDisposable) - { - ((IDisposable)output).Dispose(); - } - - parser = null; - output = null; - - GC.SuppressFinalize(this); - } - - - - private void Process(HtmlTokenId tokenId) - { - var token = parser.Token; - - switch (tokenId) - { - - - case HtmlTokenId.Tag: - - - - - if (token.IsTagBegin) - { - - - switch (token.TagIndex) - { - case HtmlTagIndex.Title: - - - break; - - case HtmlTagIndex.Comment: - case HtmlTagIndex.Script: - case HtmlTagIndex.Style: - - insideComment = !token.IsEndTag; - break; - - case HtmlTagIndex.A: - - if (outputAnchorLinks) - { - insideAnchor = !token.IsEndTag; - if (!token.IsEndTag) - { - - } - else - { - - } - } - break; - - case HtmlTagIndex.Base: - case HtmlTagIndex.BaseFont: - case HtmlTagIndex.BGSound: - case HtmlTagIndex.Link: - case HtmlTagIndex.FrameSet: - case HtmlTagIndex.Frame: - case HtmlTagIndex.Iframe: - - - break; - - case HtmlTagIndex.Map: - case HtmlTagIndex.Div: - case HtmlTagIndex.P: - case HtmlTagIndex.H1: - case HtmlTagIndex.H2: - case HtmlTagIndex.H3: - case HtmlTagIndex.H4: - case HtmlTagIndex.H5: - case HtmlTagIndex.H6: - case HtmlTagIndex.Center: - case HtmlTagIndex.BlockQuote: - case HtmlTagIndex.Address: - case HtmlTagIndex.Marquee: - case HtmlTagIndex.BR: - - case HtmlTagIndex.HR: - - case HtmlTagIndex.Form: - case HtmlTagIndex.FieldSet: - case HtmlTagIndex.OptGroup: - case HtmlTagIndex.Select: - case HtmlTagIndex.Option: - - case HtmlTagIndex.OL: - case HtmlTagIndex.UL: - case HtmlTagIndex.Dir: - case HtmlTagIndex.Menu: - case HtmlTagIndex.LI: - case HtmlTagIndex.DL: - case HtmlTagIndex.DT: - case HtmlTagIndex.DD: - - case HtmlTagIndex.Table: - case HtmlTagIndex.Caption: - case HtmlTagIndex.ColGroup: - case HtmlTagIndex.Col: - case HtmlTagIndex.Tbody: - case HtmlTagIndex.Thead: - case HtmlTagIndex.Tfoot: - case HtmlTagIndex.TR: - case HtmlTagIndex.TC: - - case HtmlTagIndex.Pre: - case HtmlTagIndex.PlainText: - case HtmlTagIndex.Listing: - - collapseWhitespaceState = CollapseWhitespaceState.NewLine; - break; - - case HtmlTagIndex.TH: - case HtmlTagIndex.TD: - - if (!token.IsEndTag) - { - output.Write("\t"); - } - break; - - - case HtmlTagIndex.NoEmbed: - case HtmlTagIndex.NoFrames: - - insideComment = !token.IsEndTag; - break; - } - } - - - - - switch (token.TagIndex) - { - case HtmlTagIndex.A: - - if (!token.IsEndTag && outputAnchorLinks) - { - - } - break; - - case HtmlTagIndex.Area: - - if (!token.IsEndTag && outputAnchorLinks) - { - - } - break; - - case HtmlTagIndex.Img: - case HtmlTagIndex.Image: - - if (!token.IsEndTag && outputAnchorLinks) - { - - } - break; - } - - break; - - - - case HtmlTokenId.Text: - - if (!insideComment) - { - token.Text.WriteToAndCollapseWhitespace(output, ref collapseWhitespaceState); - } - break; - - - - case HtmlTokenId.OverlappedClose: - case HtmlTokenId.OverlappedReopen: - - break; - - - - case HtmlTokenId.Restart: - - break; - - - - case HtmlTokenId.EncodingChange: - - var encodingOutput = output as ConverterEncodingOutput; - if (encodingOutput != null) - { - var codePage = token.Argument; - - if (encodingOutput.CodePageSameAsInput) - { - #if DEBUG - Encoding newOutputEncoding; - - InternalDebug.Assert(Charset.TryGetEncoding(codePage, out newOutputEncoding)); - #endif - - - encodingOutput.Encoding = Charset.GetEncoding(codePage); - } - } - break; - - - - case HtmlTokenId.EndOfFile: - - output.Write("\r\n"); - output.Flush(); - - endOfFile = true; - break; - } - } - } -} - diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlToHtmlConverter.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlToHtmlConverter.cs deleted file mode 100644 index 45145d005..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlToHtmlConverter.cs +++ /dev/null @@ -1,3491 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters.Internal.Html -{ - using System; - using System.IO; - using System.Text; - using System.Collections.Generic; - using Data.Internal; - using Globalization; - using Css; - - - internal class HtmlToHtmlConverter : IProducerConsumer, IRestartable, IDisposable - { - private bool convertFragment; - private bool outputFragment; - private bool filterForFragment; - - private bool filterHtml; - private bool truncateForCallback; - - private int smallCssBlockThreshold; - private bool preserveDisplayNoneStyle; - - private bool hasTailInjection; - - private IHtmlParser parser; - private bool endOfFile; - - private bool normalizedInput; - - internal HtmlWriter writer; - - private HtmlTagCallback callback; - private HtmlToHtmlTagContext callbackContext; - - internal HtmlToken token; - - private bool headDivUnterminated; - - private int currentLevel; - private int currentLevelDelta; - - private bool insideCSS; - - private int dropLevel = Int32.MaxValue; - - private EndTagActionEntry[] endTagActionStack; - private int endTagActionStackTop; - - private bool tagDropped; - private bool justTruncated; - private bool tagCallbackRequested; - private bool attributeTriggeredCallback; - private bool endTagCallbackRequested; - private bool ignoreAttrCallback; - private bool styleIsCSS; - - private HtmlFilterData.FilterAction attrContinuationAction; - - private CopyPendingState copyPendingState; - - private HtmlTagIndex tagIndex; - - private int attributeCount; - private int attributeSkipCount; - - private bool attributeIndirect; - private AttributeIndirectEntry[] attributeIndirectIndex; - - private AttributeVirtualEntry[] attributeVirtualList; - private int attributeVirtualCount; - private ScratchBuffer attributeVirtualScratch; - - private ScratchBuffer attributeActionScratch; - private bool attributeLeadingSpaces; - - private bool metaInjected; - private bool insideHtml; - private bool insideHead; - private bool insideBody; - - private bool tagHasFilteredStyleAttribute; - - private CssParser cssParser; - private ConverterBufferInput cssParserInput; - - private VirtualScratchSink virtualScratchSink; - - private IProgressMonitor progressMonitor; - - private static readonly string NamePrefix = "x_"; - - - internal enum CopyPendingState : byte - { - NotPending, - TagCopyPending, - TagContentCopyPending, - TagNameCopyPending, - AttributeCopyPending, - AttributeNameCopyPending, - AttributeValueCopyPending, - } - - - [Flags] - private enum AvailableTagParts : byte - { - None = 0, - TagBegin = 0x01, - TagEnd = 0x02, - TagName = 0x04, - Attributes = 0x08, - UnstructuredContent = 0x10, - } - - - private enum AttributeIndirectKind - { - PassThrough, - EmptyValue, - FilteredStyle, - Virtual, - VirtualFilteredStyle, - NameOnlyFragment, - } - - - private struct AttributeIndirectEntry - { - public AttributeIndirectKind kind; - public short index; - } - - - private struct AttributeVirtualEntry - { - public short index; - public int offset; - public int length; - public int position; - } - - - private struct EndTagActionEntry - { - public int tagLevel; - public bool drop; - public bool callback; - } - - - public HtmlToHtmlConverter( - IHtmlParser parser, - HtmlWriter writer, - bool convertFragment, - bool outputFragment, - bool filterHtml, - HtmlTagCallback callback, - bool truncateForCallback, - bool hasTailInjection, - Stream traceStream, - bool traceShowTokenNum, - int traceStopOnTokenNum, - int smallCssBlockThreshold, - bool preserveDisplayNoneStyle, - IProgressMonitor progressMonitor) - { - - this.writer = writer; - - normalizedInput = parser is HtmlNormalizingParser; - - InternalDebug.Assert(progressMonitor != null); - this.progressMonitor = progressMonitor; - - - - - InternalDebug.Assert(!(outputFragment && !normalizedInput)); - - this.convertFragment = convertFragment; - this.outputFragment = outputFragment; - - filterForFragment = outputFragment || convertFragment; - - this.filterHtml = filterHtml || filterForFragment; - this.callback = callback; - - this.parser = parser; - if (!convertFragment) - { - this.parser.SetRestartConsumer(this); - } - - this.truncateForCallback = truncateForCallback; - - this.hasTailInjection = hasTailInjection; - - this.smallCssBlockThreshold = smallCssBlockThreshold; - this.preserveDisplayNoneStyle = preserveDisplayNoneStyle; - } - - - void IDisposable.Dispose() - { - if (parser != null && parser is IDisposable) - { - ((IDisposable)parser).Dispose(); - } - - if (!convertFragment && writer != null && writer is IDisposable) - { - ((IDisposable)writer).Dispose(); - } - - if (token != null && token is IDisposable) - { - ((IDisposable)token).Dispose(); - } - - parser = null; - writer = null; - - token = null; - - GC.SuppressFinalize(this); - } - - private CopyPendingState CopyPendingStateFlag - { - get - { - return copyPendingState; - } - set - { - writer.SetCopyPending(value != CopyPendingState.NotPending); - copyPendingState = value; - } - } - - - - public void Run() - { - - if (!endOfFile) - { - var tokenId = parser.Parse(); - - if (HtmlTokenId.None != tokenId) - { - Process(tokenId); - } - } - } - - - public bool Flush() - { - if (!endOfFile) - { - Run(); - } - - return endOfFile; - } - - - public void Initialize(string fragment, bool preformatedText) - { - InternalDebug.Assert(convertFragment); - - if (parser is HtmlNormalizingParser) - { - ((HtmlNormalizingParser)parser).Initialize(fragment, preformatedText); - } - else - { - ((HtmlParser)parser).Initialize(fragment, preformatedText); - } - - ((IRestartable)this).Restart(); - } - - - bool IRestartable.CanRestart() - { - if (writer is IRestartable) - { - return ((IRestartable)writer).CanRestart(); - } - - return false; - } - - - void IRestartable.Restart() - { - if (writer is IRestartable && !convertFragment) - { - ((IRestartable)writer).Restart(); - } - - - - endOfFile = false; - - token = null; - - styleIsCSS = true; - insideCSS = false; - - headDivUnterminated = false; - - tagDropped = false; - justTruncated = false; - tagCallbackRequested = false; - endTagCallbackRequested = false; - ignoreAttrCallback = false; - attrContinuationAction = HtmlFilterData.FilterAction.Unknown; - currentLevel = 0; - currentLevelDelta = 0; - dropLevel = Int32.MaxValue; - endTagActionStackTop = 0; - - copyPendingState = CopyPendingState.NotPending; - - metaInjected = false; - insideHtml = false; - insideHead = false; - insideBody = false; - } - - - void IRestartable.DisableRestart() - { - if (writer is IRestartable) - { - ((IRestartable)writer).DisableRestart(); - } - } - - - private void Process(HtmlTokenId tokenId) - { - token = parser.Token; - - if (!metaInjected) - { - if (!InjectMetaTagIfNecessary()) - { - - return; - } - } - - switch (tokenId) - { - case HtmlTokenId.Tag: - - if (!token.IsEndTag) - { - ProcessStartTag(); - } - else - { - ProcessEndTag(); - } - break; - - case HtmlTokenId.OverlappedClose: - - ProcessOverlappedClose(); - break; - - case HtmlTokenId.OverlappedReopen: - - ProcessOverlappedReopen(); - break; - - case HtmlTokenId.Text: - - ProcessText(); - break; - - case HtmlTokenId.InjectionBegin: - - ProcessInjectionBegin(); - break; - - case HtmlTokenId.InjectionEnd: - - ProcessInjectionEnd(); - break; - - case HtmlTokenId.Restart: - - break; - - case HtmlTokenId.EncodingChange: - - - - if (writer.HasEncoding && writer.CodePageSameAsInput) - { - var codePage = token.Argument; - -#if DEBUG - Encoding newOutputEncoding; - - InternalDebug.Assert(Charset.TryGetEncoding(codePage, out newOutputEncoding)); -#endif - - - - writer.Encoding = Charset.GetEncoding(codePage); - } - break; - - case HtmlTokenId.EndOfFile: - - ProcessEof(); - break; - } - } - - - private void ProcessStartTag() - { - AvailableTagParts availableParts = 0; - - if (insideCSS && - token.TagIndex == HtmlTagIndex._COMMENT && - filterHtml) - { - - AppendCssFromTokenText(); - - - return; - } - - - - if (token.IsTagBegin) - { - InternalDebug.Assert(CopyPendingStateFlag == CopyPendingState.NotPending); - - - currentLevel++; - - tagIndex = token.TagIndex; - - - - tagDropped = false; - justTruncated = false; - endTagCallbackRequested = false; - - - - - PreProcessStartTag(); - - if (currentLevel >= dropLevel) - { - - - tagDropped = true; - } - else if (!tagDropped) - { - tagCallbackRequested = false; - ignoreAttrCallback = false; - - if (filterHtml || callback != null) - { - InternalDebug.Assert(normalizedInput); - - var tagAction = filterForFragment ? - HtmlFilterData.filterInstructions[(int)token.NameIndex].tagFragmentAction : - HtmlFilterData.filterInstructions[(int)token.NameIndex].tagAction; - - if (callback != null && 0 != (tagAction & HtmlFilterData.FilterAction.Callback)) - { - - - - tagCallbackRequested = true; - } - else if (filterHtml) - { - - - ignoreAttrCallback = (0 != (tagAction & HtmlFilterData.FilterAction.IgnoreAttrCallbacks)); - - switch (tagAction & HtmlFilterData.FilterAction.ActionMask) - { - case HtmlFilterData.FilterAction.Drop: - - tagDropped = true; - dropLevel = currentLevel; - break; - - case HtmlFilterData.FilterAction.DropKeepContent: - - tagDropped = true; - break; - - case HtmlFilterData.FilterAction.KeepDropContent: - - dropLevel = currentLevel + 1; - break; - - case HtmlFilterData.FilterAction.Keep: - - break; - } - } - } - - if (!tagDropped) - { - - - attributeTriggeredCallback = false; - tagHasFilteredStyleAttribute = false; - - availableParts = AvailableTagParts.TagBegin; - } - } - } - - if (!tagDropped) - { - - - var tagMinorPart = token.MinorPart; - - if (token.IsTagEnd) - { - availableParts |= AvailableTagParts.TagEnd; - } - - if (tagIndex < HtmlTagIndex.Unknown) - { - InternalDebug.Assert(CopyPendingStateFlag == CopyPendingState.NotPending || CopyPendingStateFlag == CopyPendingState.TagCopyPending); - - availableParts |= AvailableTagParts.UnstructuredContent; - attributeCount = 0; - } - else - { - if (token.HasNameFragment || token.IsTagNameEnd) - { - availableParts |= AvailableTagParts.TagName; - } - - - - ProcessTagAttributes(); - - if (attributeCount != 0) - { - availableParts |= AvailableTagParts.Attributes; - } - } - - - - if (availableParts != 0) - { - - - if (CopyPendingStateFlag != CopyPendingState.NotPending) - { - - InternalDebug.Assert(!token.IsTagBegin); - - switch (CopyPendingStateFlag) - { - case CopyPendingState.TagCopyPending: - - CopyInputTag(true); - - if (tagCallbackRequested && 0 != (availableParts & AvailableTagParts.TagEnd)) - { - - - - - - - attributeCount = 0; - token.Name.MakeEmpty(); - - - availableParts &= ~AvailableTagParts.TagEnd; - tagMinorPart = 0; - } - else - { - - - availableParts = AvailableTagParts.None; - - - } - break; - - case CopyPendingState.TagNameCopyPending: - - InternalDebug.Assert(tagIndex == HtmlTagIndex.Unknown && !token.IsTagNameBegin); - - token.Name.WriteTo(writer.WriteTagName()); - - if (token.IsTagNameEnd) - { - CopyPendingStateFlag = CopyPendingState.NotPending; - } - - token.Name.MakeEmpty(); - - availableParts &= ~AvailableTagParts.TagName; - tagMinorPart &= ~HtmlToken.TagPartMinor.CompleteName; - break; - - case CopyPendingState.AttributeCopyPending: - - InternalDebug.Assert(GetAttribute(0).Index == 0); - InternalDebug.Assert(!token.Attributes[0].IsAttrBegin && attributeCount != 0); - - CopyInputAttribute(0); - - attributeSkipCount = 1; - attributeCount--; - - if (0 == attributeCount) - { - availableParts &= ~AvailableTagParts.Attributes; - } - - tagMinorPart &= ~HtmlToken.TagPartMinor.AttributePartMask; - break; - - case CopyPendingState.AttributeNameCopyPending: - - InternalDebug.Assert(GetAttribute(0).Index == 0); - InternalDebug.Assert(!token.Attributes[0].IsAttrBegin && - 0 != (token.Attributes[0].MinorPart & HtmlToken.AttrPartMinor.ContinueName) && - attributeCount != 0); - - CopyInputAttributeName(0); - - if (1 == attributeCount && 0 == (token.Attributes[0].MinorPart & HtmlToken.AttrPartMinor.ContinueValue)) - { - attributeSkipCount = 1; - attributeCount--; - - availableParts &= ~AvailableTagParts.Attributes; - tagMinorPart &= ~HtmlToken.TagPartMinor.AttributePartMask; - - InternalDebug.Assert(availableParts == 0 || availableParts == AvailableTagParts.TagEnd); - } - else - { - token.Attributes[0].Name.MakeEmpty(); - - token.Attributes[0].SetMinorPart(token.Attributes[0].MinorPart & ~HtmlToken.AttrPartMinor.CompleteName); - } - - break; - - case CopyPendingState.AttributeValueCopyPending: - - InternalDebug.Assert(GetAttribute(0).Index == 0); - InternalDebug.Assert(!token.Attributes[0].IsAttrBegin && - (0 != (token.Attributes[0].MinorPart & HtmlToken.AttrPartMinor.ContinueValue) || - token.Attributes[0].MinorPart == HtmlToken.AttrPartMinor.Empty || - token.Attributes[0].IsAttrEnd) && - attributeCount != 0); - - CopyInputAttributeValue(0); - - attributeSkipCount = 1; - attributeCount--; - - if (0 == attributeCount) - { - availableParts &= ~AvailableTagParts.Attributes; - } - - tagMinorPart &= ~HtmlToken.TagPartMinor.AttributePartMask; - break; - - default: - - InternalDebug.Assert(false); - break; - } - } - - - - - - - if (availableParts != 0) - { - - - if (tagCallbackRequested) - { - InternalDebug.Assert(!truncateForCallback || token.IsTagBegin); - - InternalDebug.Assert(callback != null); - - if (callbackContext == null) - { - - callbackContext = new HtmlToHtmlTagContext(this); - } - - InternalDebug.Assert(CopyPendingStateFlag == CopyPendingState.NotPending); - - if (token.IsTagBegin || attributeTriggeredCallback) - { - - callbackContext.InitializeTag(false/*this.token.IsEndTag*/, HtmlDtd.tags[(int)tagIndex].nameIndex, false); - - attributeTriggeredCallback = false; - } - - callbackContext.InitializeFragment(token.IsEmptyScope, attributeCount, new HtmlTagParts(token.MajorPart, token.MinorPart)); - - - callback(callbackContext, writer); - - - callbackContext.UninitializeFragment(); - - if (token.IsTagEnd || truncateForCallback) - { - if (callbackContext.IsInvokeCallbackForEndTag) - { - - - - endTagCallbackRequested = true; - } - - if (callbackContext.IsDeleteInnerContent) - { - dropLevel = currentLevel + 1; - } - - if (token.IsTagBegin && callbackContext.IsDeleteEndTag) - { - tagDropped = true; - } - - if (!tagDropped && !token.IsTagEnd) - { - InternalDebug.Assert(truncateForCallback); - - tagDropped = true; - - - justTruncated = true; - - CopyPendingStateFlag = CopyPendingState.NotPending; - } - } - } - else - { - - - if (token.IsTagBegin) - { - CopyInputTag(false); - } - - if (attributeCount != 0) - { - CopyInputTagAttributes(); - } - - if (token.IsTagEnd) - { - if (tagIndex == HtmlTagIndex.Unknown) - { - writer.WriteTagEnd(token.IsEmptyScope); - } - } - } - } - } - } - - - - if (token.IsTagEnd) - { - InternalDebug.Assert(CopyPendingStateFlag == CopyPendingState.NotPending); - - - - - if (writer.IsTagOpen) - { - writer.WriteTagEnd(); - } - - - - if (!token.IsEmptyScope && tagIndex > HtmlTagIndex.Unknown) - { - - - - if (normalizedInput && currentLevel < dropLevel && - ((tagDropped && !justTruncated) || endTagCallbackRequested)) - { - if (endTagActionStack == null) - { - endTagActionStack = new EndTagActionEntry[4]; - } - else if (endTagActionStack.Length == endTagActionStackTop) - { - var newEndTagActionStack = new EndTagActionEntry[endTagActionStack.Length * 2]; - Array.Copy(endTagActionStack, 0, newEndTagActionStack, 0, endTagActionStackTop); - endTagActionStack = newEndTagActionStack; - } - - endTagActionStack[endTagActionStackTop].tagLevel = currentLevel; - endTagActionStack[endTagActionStackTop].drop = tagDropped && !justTruncated; - endTagActionStack[endTagActionStackTop].callback = endTagCallbackRequested; - - endTagActionStackTop++; - } - - - - currentLevel++; - - PostProcessStartTag(); - } - else - { - - - InternalDebug.Assert(!normalizedInput || currentLevel > 0); - - currentLevel--; - - if (dropLevel != Int32.MaxValue && currentLevel < dropLevel) - { - dropLevel = Int32.MaxValue; - } - } - } - } - - - private void ProcessEndTag() - { - AvailableTagParts availableParts = 0; - - InternalDebug.Assert(token.TagIndex >= HtmlTagIndex.Unknown); - - if (token.IsTagBegin) - { - InternalDebug.Assert(CopyPendingStateFlag == CopyPendingState.NotPending); - InternalDebug.Assert(!normalizedInput || currentLevel > 0 || token.TagIndex == HtmlTagIndex.Unknown); - - - if (currentLevel > 0) - { - currentLevel--; - } - - tagIndex = token.TagIndex; - - - - tagDropped = false; - tagCallbackRequested = false; - tagHasFilteredStyleAttribute = false; - - availableParts = AvailableTagParts.TagBegin; - - - PreProcessEndTag(); - - - - - - - - InternalDebug.Assert(endTagActionStackTop == 0 || endTagActionStack[endTagActionStackTop - 1].tagLevel <= currentLevel + currentLevelDelta); - - if (currentLevel >= dropLevel) - { - - tagDropped = true; - } - else - { - if (endTagActionStackTop != 0 && tagIndex > HtmlTagIndex.Unknown) - { - - - - - if (endTagActionStack[endTagActionStackTop - 1].tagLevel >= currentLevel) - { - - - if (endTagActionStack[endTagActionStackTop - 1].tagLevel == currentLevel) - { - - - endTagActionStackTop--; - - tagDropped = endTagActionStack[endTagActionStackTop].drop; - tagCallbackRequested = endTagActionStack[endTagActionStackTop].callback; - } - else - { - - InternalDebug.Assert(currentLevelDelta != 0); - - int stackPos; - - - - for (stackPos = endTagActionStackTop; stackPos > 0 && endTagActionStack[stackPos - 1].tagLevel > currentLevel; stackPos--) - { - } - - - - - - - - - for (var j = stackPos; j < endTagActionStackTop; j++) - { - - - endTagActionStack[j].tagLevel -= 2; - } - - - - if (stackPos > 0 && endTagActionStack[stackPos - 1].tagLevel == currentLevel) - { - - tagDropped = endTagActionStack[stackPos - 1].drop; - tagCallbackRequested = endTagActionStack[stackPos - 1].callback; - - - - for (; stackPos < endTagActionStackTop; stackPos++) - { - - - endTagActionStack[stackPos - 1] = endTagActionStack[stackPos]; - } - - endTagActionStackTop--; - } - } - } - } - - if (token.Argument == 1 && tagIndex == HtmlTagIndex.Unknown) - { - - - - - tagDropped = true; - } - } - } - - HtmlToken.TagPartMinor tagMinorPart; - - if (!tagDropped) - { - tagMinorPart = token.MinorPart & ~(HtmlToken.TagPartMinor.AttributePartMask | HtmlToken.TagPartMinor.Attributes); - - if (token.IsTagEnd) - { - availableParts |= AvailableTagParts.TagEnd; - } - - if (token.HasNameFragment) - { - availableParts |= AvailableTagParts.TagName; - } - - if (CopyPendingStateFlag == CopyPendingState.TagNameCopyPending) - { - InternalDebug.Assert(!token.IsTagBegin); - - - - token.Name.WriteTo(writer.WriteTagName()); - - if (token.IsTagNameEnd) - { - CopyPendingStateFlag = CopyPendingState.NotPending; - } - - token.Name.MakeEmpty(); - - availableParts &= ~AvailableTagParts.TagName; - tagMinorPart &= ~HtmlToken.TagPartMinor.CompleteName; - } - - if (availableParts != 0) - { - if (tagCallbackRequested) - { - InternalDebug.Assert(callback != null && callbackContext != null); - - InternalDebug.Assert(CopyPendingStateFlag == CopyPendingState.NotPending); - - if (token.IsTagBegin) - { - - callbackContext.InitializeTag(true/*this.token.IsEndTag*/, HtmlDtd.tags[(int)tagIndex].nameIndex, false); - } - - - callbackContext.InitializeFragment(false, 0, new HtmlTagParts(token.MajorPart, tagMinorPart)); - - - callback(callbackContext, writer); - - - callbackContext.UninitializeFragment(); - } - else - { - - - if (token.IsTagBegin) - { - CopyInputTag(false); - } - } - } - } - else if (tagCallbackRequested) - { - - - tagMinorPart = token.MinorPart & ~(HtmlToken.TagPartMinor.AttributePartMask | HtmlToken.TagPartMinor.Attributes); - - InternalDebug.Assert(callback != null && callbackContext != null); - - InternalDebug.Assert(CopyPendingStateFlag == CopyPendingState.NotPending); - - if (token.IsTagBegin) - { - - callbackContext.InitializeTag(true/*this.token.IsEndTag*/, HtmlDtd.tags[(int)tagIndex].nameIndex, true/*droppedEndTag*/); - } - - callbackContext.InitializeFragment(false, 0, new HtmlTagParts(token.MajorPart, tagMinorPart)); - - - callback(callbackContext, writer); - - - callbackContext.UninitializeFragment(); - } - - if (token.IsTagEnd) - { - - - - if (writer.IsTagOpen) - { - writer.WriteTagEnd(); - } - - if (tagIndex > HtmlTagIndex.Unknown) - { - InternalDebug.Assert(!normalizedInput || currentLevel > 0); - - if (currentLevel > 0) - { - currentLevel--; - } - - if (dropLevel != Int32.MaxValue && currentLevel < dropLevel) - { - dropLevel = Int32.MaxValue; - } - } - else - { - - - if (currentLevel > 0) - { - currentLevel++; - } - } - } - } - - - private void ProcessOverlappedClose() - { - InternalDebug.Assert(currentLevelDelta == 0); - - - currentLevelDelta = token.Argument * 2; - currentLevel -= currentLevelDelta; - } - - - private void ProcessOverlappedReopen() - { - InternalDebug.Assert(currentLevelDelta == token.Argument * 2); - - - currentLevel += token.Argument * 2; - currentLevelDelta = 0; - } - - - private void ProcessText() - { - if (currentLevel >= dropLevel) - { - return; - } - - if (insideCSS && filterHtml) - { - - AppendCssFromTokenText(); - - - } - else if (token.Argument == 1) - { - - - InternalDebug.Assert(token.Text.Length == 1/* todo: && this.token.Text[0].IsWhitespace*/); - - writer.WriteCollapsedWhitespace(); - } - else if (token.Runs.MoveNext(true)) - { - - token.Text.WriteTo(writer.WriteText()); - } - } - - - private void ProcessInjectionBegin() - { - - - if (token.Argument == 0) - { - - - if (headDivUnterminated) - { - writer.WriteEndTag(HtmlNameIndex.Div); - writer.WriteAutoNewLine(true); - - headDivUnterminated = false; - } - } - } - - - private void ProcessInjectionEnd() - { - - - if (token.Argument != 0) - { - - - writer.WriteAutoNewLine(true); - writer.WriteStartTag(HtmlNameIndex.Div); - - - - - headDivUnterminated = true; - } - } - - - private void ProcessEof() - { - writer.SetCopyPending(false); - - if (headDivUnterminated && dropLevel != 0) - { - - - writer.WriteEndTag(HtmlNameIndex.Div); - writer.WriteAutoNewLine(true); - - headDivUnterminated = false; - } - - - - if (outputFragment && !insideBody) - { - - writer.WriteStartTag(HtmlNameIndex.Div); - writer.WriteEndTag(HtmlNameIndex.Div); - writer.WriteAutoNewLine(true); - } - - if (!convertFragment) - { - writer.Flush(); - } - - endOfFile = true; - } - - - private void PreProcessStartTag() - { - InternalDebug.Assert(token.IsTagBegin && !token.IsEndTag); - - if (tagIndex > HtmlTagIndex.Unknown) - { - - - if (tagIndex == HtmlTagIndex.Body) - { - if (outputFragment) - { - insideBody = true; - - - tagIndex = HtmlTagIndex.Div; - } - } - else if (tagIndex == HtmlTagIndex.Meta) - { - - if (!filterHtml) - { - - - - - - - - - - - - - - - - token.Attributes.Rewind(); - - foreach (var attribute in token.Attributes) - { - if (attribute.NameIndex == HtmlNameIndex.HttpEquiv) - { - if (attribute.Value.CaseInsensitiveCompareEqual("content-type") || - attribute.Value.CaseInsensitiveCompareEqual("charset")) - { - tagDropped = true; - break; - } - } - else if (attribute.NameIndex == HtmlNameIndex.Charset) - { - tagDropped = true; - break; - } - } - } - } - else if (tagIndex == HtmlTagIndex.Style) - { -#if false - - - - if (!this.outputFragment) - { -#endif - - - styleIsCSS = true; - - if (token.Attributes.Find(HtmlNameIndex.Type)) - { - var attribute = token.Attributes.Current; - - if (!attribute.Value.CaseInsensitiveCompareEqual("text/css")) - { - - styleIsCSS = false; - } - } - -#if false - - } - else - { - - - this.tagDropped = true; - this.dropLevel = this.currentLevel; - } -#endif - } - else if (tagIndex == HtmlTagIndex.TC) - { - - tagDropped = true; - } - else if (tagIndex == HtmlTagIndex.PlainText || tagIndex == HtmlTagIndex.Xmp) - { - if (filterHtml || (hasTailInjection && tagIndex == HtmlTagIndex.PlainText)) - { - - - - tagDropped = true; - - writer.WriteAutoNewLine(true); - writer.WriteStartTag(HtmlNameIndex.TT); - writer.WriteStartTag(HtmlNameIndex.Pre); - writer.WriteAutoNewLine(); - } - } - else if (tagIndex == HtmlTagIndex.Image) - { - if (filterHtml) - { - - tagIndex = HtmlTagIndex.Img; - } - } - } - } - - - private void ProcessTagAttributes() - { - attributeSkipCount = 0; - - var attributes = token.Attributes; - HtmlAttribute attribute; - HtmlFilterData.FilterAction attrAction; - - if (filterHtml) - { - attributeCount = 0; - attributeIndirect = true; - attributeVirtualCount = 0; - attributeVirtualScratch.Reset(); - - if (attributeIndirectIndex == null) - { - attributeIndirectIndex = new AttributeIndirectEntry[Math.Max(attributes.Count + 1, 32)]; - } - else if (attributeIndirectIndex.Length <= attributes.Count) - { - attributeIndirectIndex = new AttributeIndirectEntry[Math.Max(attributeIndirectIndex.Length * 2, attributes.Count + 1)]; - } - - for (var i = 0; i < attributes.Count; i++) - { - attribute = attributes[i]; - - if (attribute.IsAttrBegin) - { - - - attrAction = filterForFragment ? - HtmlFilterData.filterInstructions[(int)attribute.NameIndex].attrFragmentAction : - HtmlFilterData.filterInstructions[(int)attribute.NameIndex].attrAction; - - if (0 != (attrAction & HtmlFilterData.FilterAction.HasExceptions) && - 0 != (HtmlFilterData.filterInstructions[(int)token.NameIndex].tagAction & HtmlFilterData.FilterAction.HasExceptions)) - { - - - for (var j = 0; j < HtmlFilterData.filterExceptions.Length; j++) - { - if (HtmlFilterData.filterExceptions[j].tagNameIndex == token.NameIndex && - HtmlFilterData.filterExceptions[j].attrNameIndex == attribute.NameIndex) - { - attrAction = filterForFragment ? - HtmlFilterData.filterExceptions[j].fragmentAction : - HtmlFilterData.filterExceptions[j].action; - break; - } - } - } - - if (!outputFragment && - (attrAction == HtmlFilterData.FilterAction.PrefixName || attrAction == HtmlFilterData.FilterAction.PrefixNameList)) - { - - - attrAction = HtmlFilterData.FilterAction.Keep; - } - - if (callback != null && !ignoreAttrCallback && 0 != (attrAction & HtmlFilterData.FilterAction.Callback)) - { - - - if (token.IsTagBegin || !truncateForCallback) - { - - - attributeTriggeredCallback = attributeTriggeredCallback || !tagCallbackRequested; - tagCallbackRequested = true; - } - else - { - - - - - attrAction = HtmlFilterData.FilterAction.KeepDropContent; - } - - - - - - - - } - - - attrAction &= HtmlFilterData.FilterAction.ActionMask; - - if (!attribute.IsAttrEnd) - { - - InternalDebug.Assert(attribute.Index == attributes.Count - 1 && !token.IsTagEnd); - - - - - attrContinuationAction = attrAction; - } - } - else - { - - InternalDebug.Assert(attribute.Index == 0 && !token.IsTagBegin); - attrAction = attrContinuationAction; - } - - - - if (attrAction != HtmlFilterData.FilterAction.Drop) - { - if (attrAction == HtmlFilterData.FilterAction.Keep) - { - attributeIndirectIndex[attributeCount].index = (short)i; - attributeIndirectIndex[attributeCount].kind = AttributeIndirectKind.PassThrough; - attributeCount++; - } - else - { - if (attrAction == HtmlFilterData.FilterAction.KeepDropContent) - { - - InternalDebug.Assert(attribute.IsAttrBegin); - - - attrContinuationAction = HtmlFilterData.FilterAction.Drop; - - - attributeIndirectIndex[attributeCount].index = (short)i; - attributeIndirectIndex[attributeCount].kind = AttributeIndirectKind.EmptyValue; - attributeCount++; - } - else if (attrAction == HtmlFilterData.FilterAction.FilterStyleAttribute) - { - if (attribute.IsAttrBegin) - { - if (tagHasFilteredStyleAttribute) - { - - - - - - - - - - - - AppendCss(";"); - } - - tagHasFilteredStyleAttribute = true; - } - - AppendCssFromAttribute(attribute); - - - continue; - } - else if (attrAction == HtmlFilterData.FilterAction.ConvertBgcolorIntoStyle) - { - if (attribute.IsAttrBegin) - { - if (tagHasFilteredStyleAttribute) - { - - - AppendCss(";"); - } - - tagHasFilteredStyleAttribute = true; - } - - - - - - - - - - - - AppendCss("background-color:"); - AppendCssFromAttribute(attribute); - - - continue; - } - else - { - int vi; - int offset, length; - - - InternalDebug.Assert(attrAction == HtmlFilterData.FilterAction.SanitizeUrl || - attrAction == HtmlFilterData.FilterAction.PrefixName || - attrAction == HtmlFilterData.FilterAction.PrefixNameList); - - if (attribute.IsAttrBegin) - { - - attributeLeadingSpaces = true; - } - - if (attributeLeadingSpaces) - { - if (!attribute.Value.SkipLeadingWhitespace() && !attribute.IsAttrEnd) - { - - - if (!attribute.IsAttrBegin && !attribute.HasNameFragment) - { - - continue; - } - - - attributeIndirectIndex[attributeCount].index = (short)i; - attributeIndirectIndex[attributeCount].kind = AttributeIndirectKind.NameOnlyFragment; - attributeCount++; - continue; - } - - attributeLeadingSpaces = false; - attributeActionScratch.Reset(); - } - - var truncate = false; - - - - - - if (!attributeActionScratch.AppendHtmlAttributeValue(attribute, 4 * 1024)) - { - - truncate = true; - } - - if (!attribute.IsAttrEnd && !truncate) - { - - - if (!attribute.IsAttrBegin && !attribute.HasNameFragment) - { - - continue; - } - - - attributeIndirectIndex[attributeCount].index = (short)i; - attributeIndirectIndex[attributeCount].kind = AttributeIndirectKind.NameOnlyFragment; - attributeCount++; - continue; - } - - - - attrContinuationAction = HtmlFilterData.FilterAction.Drop; - - - - - if (attrAction == HtmlFilterData.FilterAction.SanitizeUrl) - { - switch (CheckUrl(attributeActionScratch.Buffer, attributeActionScratch.Length, tagCallbackRequested)) - { - case CheckUrlResult.LocalHyperlink: - - InternalDebug.Assert(attributeActionScratch[0] == '#'); - - if (!outputFragment) - { - goto case CheckUrlResult.Safe; - } - - var nameLength = NonWhitespaceLength(attributeActionScratch.Buffer, 1, attributeActionScratch.Length - 1); - - if (nameLength == 0) - { - - goto default; - } - - - offset = attributeVirtualScratch.Length; - length = 0; - length += attributeVirtualScratch.Append('#', int.MaxValue); - length += attributeVirtualScratch.Append(NamePrefix, int.MaxValue); - length += attributeVirtualScratch.Append(attributeActionScratch.Buffer, 1, nameLength, int.MaxValue); - - - vi = AllocateVirtualEntry(i, offset, length); - - - attributeIndirectIndex[attributeCount].index = (short)vi; - attributeIndirectIndex[attributeCount].kind = AttributeIndirectKind.Virtual; - attributeCount++; - break; - - case CheckUrlResult.Safe: - - if (attribute.IsCompleteAttr) - { - - attributeIndirectIndex[attributeCount].index = (short)i; - attributeIndirectIndex[attributeCount].kind = AttributeIndirectKind.PassThrough; - attributeCount++; - break; - } - - - - - - offset = attributeVirtualScratch.Length; - length = attributeVirtualScratch.Append(attributeActionScratch.Buffer, 0, attributeActionScratch.Length, int.MaxValue); - - - vi = AllocateVirtualEntry(i, offset, length); - - - attributeIndirectIndex[attributeCount].index = (short)vi; - attributeIndirectIndex[attributeCount].kind = AttributeIndirectKind.Virtual; - attributeCount++; - break; - - case CheckUrlResult.Inconclusive: - - if (attributeActionScratch.Length <= 256 && attribute.IsAttrEnd) - { - InternalDebug.Assert(attribute.IsAttrEnd); - - - goto case CheckUrlResult.Safe; - } - - - goto default; - - default: - - - attrContinuationAction = HtmlFilterData.FilterAction.Drop; - - - attributeIndirectIndex[attributeCount].index = (short)i; - attributeIndirectIndex[attributeCount].kind = AttributeIndirectKind.EmptyValue; - attributeCount++; - break; - } - } - else if (attrAction == HtmlFilterData.FilterAction.PrefixName) - { - InternalDebug.Assert(outputFragment); - - offset = attributeVirtualScratch.Length; - length = 0; - - var nameLength = NonWhitespaceLength(attributeActionScratch.Buffer, 0, attributeActionScratch.Length); - - if (nameLength != 0) - { - - length += attributeVirtualScratch.Append(NamePrefix, int.MaxValue); - length += attributeVirtualScratch.Append(attributeActionScratch.Buffer, 0, nameLength, int.MaxValue); - } - - - vi = AllocateVirtualEntry(i, offset, length); - - - attributeIndirectIndex[attributeCount].index = (short)vi; - attributeIndirectIndex[attributeCount].kind = AttributeIndirectKind.Virtual; - attributeCount++; - } - else if (attrAction == HtmlFilterData.FilterAction.PrefixNameList) - { - InternalDebug.Assert(outputFragment); - - - offset = attributeVirtualScratch.Length; - length = 0; - - var nameOffset = 0; - var nameLength = NonWhitespaceLength(attributeActionScratch.Buffer, nameOffset, attributeActionScratch.Length - nameOffset); - - if (nameLength != 0) - { - do - { - length += attributeVirtualScratch.Append(NamePrefix, int.MaxValue); - length += attributeVirtualScratch.Append(attributeActionScratch.Buffer, nameOffset, nameLength, int.MaxValue); - - nameOffset += nameLength; - nameOffset += WhitespaceLength(attributeActionScratch.Buffer, nameOffset, attributeActionScratch.Length - nameOffset); - - nameLength = NonWhitespaceLength(attributeActionScratch.Buffer, nameOffset, attributeActionScratch.Length - nameOffset); - - if (nameLength != 0) - { - length += attributeVirtualScratch.Append(' ', int.MaxValue); - } - } - while (nameLength != 0); - } - - - vi = AllocateVirtualEntry(i, offset, length); - - - attributeIndirectIndex[attributeCount].index = (short)vi; - attributeIndirectIndex[attributeCount].kind = AttributeIndirectKind.Virtual; - attributeCount++; - } - else - { - - InternalDebug.Assert(false); - - - InternalDebug.Assert((attribute.MinorPart & HtmlToken.AttrPartMinor.BeginValue) == HtmlToken.AttrPartMinor.BeginValue); - - - attrContinuationAction = HtmlFilterData.FilterAction.Drop; - - - attributeIndirectIndex[attributeCount].index = (short)i; - attributeIndirectIndex[attributeCount].kind = AttributeIndirectKind.EmptyValue; - attributeCount++; - } - } - } - } - } - - if (tagHasFilteredStyleAttribute && (token.IsTagEnd || (tagCallbackRequested && truncateForCallback))) - { - - attributeIndirectIndex[attributeCount].index = -1; - attributeIndirectIndex[attributeCount].kind = AttributeIndirectKind.FilteredStyle; - attributeCount++; - } - } - else - { - attributeCount = attributes.Count; - attributeIndirect = false; - - if (callback != null && !tagCallbackRequested && !ignoreAttrCallback) - { - - - - for (var i = 0; i < attributes.Count; i++) - { - attribute = attributes[i]; - - if (attribute.IsAttrBegin) - { - - - attrAction = HtmlFilterData.filterInstructions[(int)attribute.NameIndex].attrAction; - - if (0 != (attrAction & HtmlFilterData.FilterAction.HasExceptions) && - 0 != (HtmlFilterData.filterInstructions[(int)token.NameIndex].tagAction & HtmlFilterData.FilterAction.HasExceptions)) - { - - - for (var j = 0; j < HtmlFilterData.filterExceptions.Length; j++) - { - if (HtmlFilterData.filterExceptions[j].tagNameIndex == token.NameIndex && - HtmlFilterData.filterExceptions[j].attrNameIndex == attribute.NameIndex) - { - attrAction = HtmlFilterData.filterExceptions[j].action; - break; - } - } - } - - if (0 != (attrAction & HtmlFilterData.FilterAction.Callback)) - { - - - if (token.IsTagBegin || !truncateForCallback) - { - - - attributeTriggeredCallback = attributeTriggeredCallback || !tagCallbackRequested; - tagCallbackRequested = true; - - - break; - } - } - } - } - } - } - } - - private static int WhitespaceLength(char[] buffer, int offset, int remainingLength) - { - var length = 0; - - while (remainingLength != 0) - { - if (!ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(buffer[offset++]))) - { - break; - } - - length++; - remainingLength--; - } - - return length; - } - - private static int NonWhitespaceLength(char[] buffer, int offset, int remainingLength) - { - var length = 0; - - while (remainingLength != 0) - { - if (ParseSupport.WhitespaceCharacter(ParseSupport.GetCharClass(buffer[offset++]))) - { - break; - } - - length++; - remainingLength--; - } - - return length; - } - - - private void PostProcessStartTag() - { - if (tagIndex == HtmlTagIndex.Style && styleIsCSS) - { - insideCSS = true; - } - } - - - private void PreProcessEndTag() - { - InternalDebug.Assert(token.IsTagBegin && token.IsEndTag); - - if (tagIndex > HtmlTagIndex.Unknown) - { - if (0 != (HtmlDtd.tags[(int)tagIndex].literal & HtmlDtd.Literal.Entities)) - { - - - if (tagIndex == HtmlTagIndex.Style) - { - if (insideCSS && filterHtml) - { - - FlushCssInStyleTag(); - } - } - - insideCSS = false; - styleIsCSS = true; - } - - if (tagIndex == HtmlTagIndex.PlainText || tagIndex == HtmlTagIndex.Xmp) - { - - - - - - - if (filterHtml || (hasTailInjection && tagIndex == HtmlTagIndex.PlainText)) - { - - - - tagDropped = true; - writer.WriteEndTag(HtmlNameIndex.Pre); - writer.WriteEndTag(HtmlNameIndex.TT); - } - else if (tagIndex == HtmlTagIndex.PlainText) - { - if (normalizedInput) - { - - - - - tagDropped = true; - dropLevel = 0; - endTagActionStackTop = 0; - } - } - } - else if (tagIndex == HtmlTagIndex.Body) - { - if (headDivUnterminated && dropLevel != 0) - { - - - writer.WriteEndTag(HtmlNameIndex.Div); - writer.WriteAutoNewLine(true); - - headDivUnterminated = false; - } - - if (outputFragment) - { - tagIndex = HtmlTagIndex.Div; - } - } - else if (tagIndex == HtmlTagIndex.TC) - { - - tagDropped = true; - } - else if (tagIndex == HtmlTagIndex.Image) - { - if (filterHtml) - { - - tagIndex = HtmlTagIndex.Img; - } - } - } - else if (tagIndex == HtmlTagIndex.Unknown && filterHtml) - { - - tagDropped = true; - } - } - - - internal void CopyInputTag(bool copyTagAttributes) - { - if (token.IsTagBegin) - { - writer.WriteTagBegin(HtmlDtd.tags[(int)tagIndex].nameIndex, null, token.IsEndTag, token.IsAllowWspLeft, token.IsAllowWspRight); - } - - if (tagIndex <= HtmlTagIndex.Unknown) - { - if (tagIndex < HtmlTagIndex.Unknown) - { - InternalDebug.Assert(!token.HasNameFragment && attributeCount == 0); - - token.UnstructuredContent.WriteTo(writer.WriteUnstructuredTagContent()); - - if (token.IsTagEnd) - { - CopyPendingStateFlag = CopyPendingState.NotPending; - } - else - { - CopyPendingStateFlag = CopyPendingState.TagCopyPending; - } - return; - } - else - { - if (token.HasNameFragment) - { - token.Name.WriteTo(writer.WriteTagName()); - - if (!token.IsTagNameEnd) - { - InternalDebug.Assert(token.Attributes.Count == 0 && !token.IsTagEnd); - - if (!copyTagAttributes) - { - - CopyPendingStateFlag = CopyPendingState.TagNameCopyPending; - return; - } - } - } - } - } - - if (!copyTagAttributes) - { - CopyPendingStateFlag = CopyPendingState.NotPending; - return; - } - - if (attributeCount != 0) - { - CopyInputTagAttributes(); - } - - if (token.IsTagEnd) - { - CopyPendingStateFlag = CopyPendingState.NotPending; - } - else - { - CopyPendingStateFlag = CopyPendingState.TagCopyPending; - } - } - - - private void CopyInputTagAttributes() - { - - - InternalDebug.Assert(!token.IsEndTag); - - for (var i = 0; i < attributeCount; i++) - { - CopyInputAttribute(i); - } - } - - - internal void CopyInputAttribute(int index) - { - var kind = GetAttributeIndirectKind(index); - - if (kind == AttributeIndirectKind.FilteredStyle) - { - if (!tagCallbackRequested) - { - - - writer.WriteAttributeName(HtmlNameIndex.Style); - - InternalDebug.Assert(cssParserInput != null); - if (!cssParserInput.IsEmpty) - { - FlushCssInStyleAttribute(writer); - } - else - { - writer.WriteAttributeValueInternal(String.Empty); - } - return; - } - - - VirtualizeFilteredStyle(index); - kind = AttributeIndirectKind.VirtualFilteredStyle; - } - - var endAttr = true; - - if (kind == AttributeIndirectKind.VirtualFilteredStyle) - { - - writer.WriteAttributeName(HtmlNameIndex.Style); - - - var vi = GetAttributeVirtualEntryIndex(index); - - if (attributeVirtualList[vi].length != 0) - { - writer.WriteAttributeValueInternal(attributeVirtualScratch.Buffer, attributeVirtualList[vi].offset, attributeVirtualList[vi].length); - } - else - { - writer.WriteAttributeValueInternal(String.Empty); - } - - } - else - { - var attribute = GetAttribute(index); - - InternalDebug.Assert(!attribute.IsDeleted); - - if (attribute.IsAttrBegin) - { - if (attribute.NameIndex != HtmlNameIndex.Unknown) - { - writer.WriteAttributeName(attribute.NameIndex); - } - } - - if (attribute.NameIndex == HtmlNameIndex.Unknown && (attribute.HasNameFragment || attribute.IsAttrBegin)) - { - attribute.Name.WriteTo(writer.WriteAttributeName()); - } - - if (kind == AttributeIndirectKind.NameOnlyFragment) - { - InternalDebug.Assert(!attribute.IsAttrEnd); - endAttr = false; - } - else if (kind == AttributeIndirectKind.EmptyValue) - { - writer.WriteAttributeValueInternal(String.Empty); - - } - else if (kind == AttributeIndirectKind.Virtual) - { - - var vi = GetAttributeVirtualEntryIndex(index); - - if (attributeVirtualList[vi].length != 0) - { - writer.WriteAttributeValueInternal(attributeVirtualScratch.Buffer, attributeVirtualList[vi].offset, attributeVirtualList[vi].length); - } - else - { - writer.WriteAttributeValueInternal(String.Empty); - } - - } - else - { - if (attribute.HasValueFragment) - { - attribute.Value.WriteTo(writer.WriteAttributeValue()); - } - - endAttr = attribute.IsAttrEnd; - } - } - - if (endAttr) - { - CopyPendingStateFlag = CopyPendingState.NotPending; - } - else - { - CopyPendingStateFlag = CopyPendingState.AttributeCopyPending; - } - } - - - internal void CopyInputAttributeName(int index) - { - var kind = GetAttributeIndirectKind(index); - - if (kind == AttributeIndirectKind.FilteredStyle || kind == AttributeIndirectKind.VirtualFilteredStyle) - { - writer.WriteAttributeName(HtmlNameIndex.Style); - return; - } - - - - var attribute = GetAttribute(index); - - InternalDebug.Assert(!attribute.IsDeleted); - - if (attribute.IsAttrBegin) - { - if (attribute.NameIndex != HtmlNameIndex.Unknown) - { - writer.WriteAttributeName(attribute.NameIndex); - } - } - - if (attribute.NameIndex == HtmlNameIndex.Unknown && (attribute.HasNameFragment || attribute.IsAttrBegin)) - { - attribute.Name.WriteTo(writer.WriteAttributeName()); - } - - if (attribute.IsAttrNameEnd) - { - CopyPendingStateFlag = CopyPendingState.NotPending; - } - else - { - CopyPendingStateFlag = CopyPendingState.AttributeNameCopyPending; - } - } - - - internal void CopyInputAttributeValue(int index) - { - var kind = GetAttributeIndirectKind(index); - - var endAttr = true; - - if (kind != AttributeIndirectKind.PassThrough) - { - if (kind == AttributeIndirectKind.FilteredStyle) - { - if (!tagCallbackRequested) - { - - - InternalDebug.Assert(cssParserInput != null); - if (!cssParserInput.IsEmpty) - { - FlushCssInStyleAttribute(writer); - } - else - { - writer.WriteAttributeValueInternal(String.Empty); - } - return; - } - - - VirtualizeFilteredStyle(index); - kind = AttributeIndirectKind.VirtualFilteredStyle; - } - - if (kind == AttributeIndirectKind.Virtual || kind == AttributeIndirectKind.VirtualFilteredStyle) - { - - var vi = GetAttributeVirtualEntryIndex(index); - - if (attributeVirtualList[vi].length != 0) - { - writer.WriteAttributeValueInternal(attributeVirtualScratch.Buffer, attributeVirtualList[vi].offset, attributeVirtualList[vi].length); - } - else - { - writer.WriteAttributeValueInternal(String.Empty); - } - - } - else if (kind == AttributeIndirectKind.NameOnlyFragment) - { - InternalDebug.Assert(!GetAttribute(index).IsAttrEnd); - endAttr = false; - } - else if (kind == AttributeIndirectKind.EmptyValue) - { - writer.WriteAttributeValueInternal(String.Empty); - - } - } - else - { - var attribute = GetAttribute(index); - - InternalDebug.Assert(!attribute.IsDeleted); - - if (attribute.HasValueFragment) - { - attribute.Value.WriteTo(writer.WriteAttributeValue()); - } - - endAttr = attribute.IsAttrEnd; - } - - if (endAttr) - { - CopyPendingStateFlag = CopyPendingState.NotPending; - } - else - { - CopyPendingStateFlag = CopyPendingState.AttributeValueCopyPending; - } - } - - - private static object lockObject = new object(); - private static bool textConvertersConfigured; - - private static Dictionary safeUrlDictionary; - - internal static void RefreshConfiguration() - { - textConvertersConfigured = false; - } - - internal static bool TestSafeUrlSchema(string schema) - { - if (schema.Length < 2 || schema.Length > 20) - { - return false; - } - - if (!textConvertersConfigured) - { - ConfigureTextConverters(); - } - - - - if (safeUrlDictionary.ContainsKey(schema)) - { - return true; - } - - return false; - } - - private static void ConfigureTextConverters() - { - lock (lockObject) - { - if (!textConvertersConfigured) - { - /* example of the configuration: - - - - - -- or -- - - - - */ - - safeUrlDictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); - - var safeUrlSchemeListSpecified = false; - var safeUrlSchemeListAdd = true; - - if (!safeUrlSchemeListSpecified || safeUrlSchemeListAdd) - { - - - - - - safeUrlDictionary["http"] = null; - safeUrlDictionary["https"] = null; - safeUrlDictionary["ftp"] = null; - safeUrlDictionary["file"] = null; - safeUrlDictionary["mailto"] = null; - safeUrlDictionary["news"] = null; - safeUrlDictionary["gopher"] = null; - safeUrlDictionary["about"] = null; - safeUrlDictionary["wais"] = null; - safeUrlDictionary["cid"] = null; - safeUrlDictionary["mhtml"] = null; - safeUrlDictionary["ipp"] = null; - safeUrlDictionary["msdaipp"] = null; - safeUrlDictionary["meet"] = null; - safeUrlDictionary["tel"] = null; - safeUrlDictionary["sip"] = null; - safeUrlDictionary["conf"] = null; - safeUrlDictionary["im"] = null; - safeUrlDictionary["callto"] = null; - safeUrlDictionary["notes"] = null; - safeUrlDictionary["onenote"] = null; - safeUrlDictionary["groove"] = null; - safeUrlDictionary["mms"] = null; - } - - textConvertersConfigured = true; - } - } - } - - - private static bool SafeUrlSchema(char[] urlBuffer, int schemaLength) - { - if (schemaLength < 2 || schemaLength > 20) - { - return false; - } - - if (!textConvertersConfigured) - { - ConfigureTextConverters(); - } - - - - if (safeUrlDictionary.ContainsKey(new string(urlBuffer, 0, schemaLength))) - { - return true; - } - - return false; - } - - - private enum CheckUrlResult - { - Inconclusive, - Unsafe, - Safe, - LocalHyperlink, - } - - - private static CheckUrlResult CheckUrl(char[] urlBuffer, int urlLength, bool callbackRequested) - { - - - - int i; - - if (urlLength > 0 && urlBuffer[0] == '#') - { - - return CheckUrlResult.LocalHyperlink; - } - - for (i = 0; i < urlLength; i++) - { - if (urlBuffer[i] == '/' || urlBuffer[i] == '\\') - { - if (i == 0 && urlLength > 1 && (urlBuffer[1] == '/' || urlBuffer[1] == '\\')) - { - - return callbackRequested ? CheckUrlResult.Safe : CheckUrlResult.Unsafe; - } - - - return CheckUrlResult.Safe; - } - if (urlBuffer[i] == '?' || urlBuffer[i] == '#' || urlBuffer[i] == ';') - { - - return CheckUrlResult.Safe; - } - if (urlBuffer[i] == ':') - { - if (SafeUrlSchema(urlBuffer, i)) - { - return CheckUrlResult.Safe; - } - - if (callbackRequested) - { - if (i == 1 && - urlLength > 2 && - ParseSupport.AlphaCharacter(ParseSupport.GetCharClass(urlBuffer[0])) && - (urlBuffer[2] == '/' || urlBuffer[2] == '\\')) - { - - return CheckUrlResult.Safe; - } - else - { - var url = new BufferString(urlBuffer, 0, urlLength); - - if (url.EqualsToLowerCaseStringIgnoreCase("objattph://") || - url.EqualsToLowerCaseStringIgnoreCase("rtfimage://")) - { - return CheckUrlResult.Safe; - } - } - } - - - return CheckUrlResult.Unsafe; - } - } - - InternalDebug.Assert(i == urlLength); - - - - return CheckUrlResult.Inconclusive; - } - - - internal static bool IsUrlSafe(string url, bool callbackRequested) - { - - var urlBuffer = url.ToCharArray(); - - switch (CheckUrl(urlBuffer, urlBuffer.Length, callbackRequested)) - { - case CheckUrlResult.Safe: - case CheckUrlResult.Inconclusive: - case CheckUrlResult.LocalHyperlink: - - return true; - } - - return false; - } - - private int AllocateVirtualEntry(int index, int offset, int length) - { - if (attributeVirtualList == null) - { - attributeVirtualList = new AttributeVirtualEntry[4]; - } - else if (attributeVirtualList.Length == attributeVirtualCount) - { - var newVirtualList = new AttributeVirtualEntry[attributeVirtualList.Length * 2]; - Array.Copy(attributeVirtualList, 0, newVirtualList, 0, attributeVirtualCount); - attributeVirtualList = newVirtualList; - } - - var vi = attributeVirtualCount++; - - - attributeVirtualList[vi].index = (short)index; - attributeVirtualList[vi].offset = offset; - attributeVirtualList[vi].length = length; - attributeVirtualList[vi].position = 0; - - return vi; - } - - - private void VirtualizeFilteredStyle(int index) - { - - var offset = attributeVirtualScratch.Length; - FlushCssInStyleAttributeToVirtualScratch(); - var length = attributeVirtualScratch.Length - offset; - - - var vi = AllocateVirtualEntry(attributeIndirectIndex[index + attributeSkipCount].index, offset, length); - - - attributeIndirectIndex[index + attributeSkipCount].index = (short)vi; - attributeIndirectIndex[index + attributeSkipCount].kind = AttributeIndirectKind.VirtualFilteredStyle; - } - - - private bool InjectMetaTagIfNecessary() - { - - - if (filterForFragment || !writer.HasEncoding) - { - - metaInjected = true; - } - else - { - if (token.TokenId != HtmlTokenId.Restart && token.TokenId != HtmlTokenId.EncodingChange) - { - if (writer.Encoding.CodePage == 65000) - { - - - OutputMetaTag(); - metaInjected = true; - } - else if (token.TokenId == HtmlTokenId.Tag) - { - if (!insideHtml && token.TagIndex == HtmlTagIndex.Html) - { - if (token.IsTagEnd) - { - insideHtml = true; - } - } - else if (!insideHead && token.TagIndex == HtmlTagIndex.Head) - { - if (token.IsTagEnd) - { - insideHead = true; - } - } - else if (token.TagIndex <= HtmlTagIndex._ASP) - { - - } - else - { - - InternalDebug.Assert(token.IsTagBegin); - - if (insideHtml && !insideHead) - { - writer.WriteNewLine(true); - writer.WriteStartTag(HtmlNameIndex.Head); - writer.WriteNewLine(true); - - OutputMetaTag(); - - writer.WriteEndTag(HtmlNameIndex.Head); - writer.WriteNewLine(true); - } - else - { - if (insideHead) - { - writer.WriteNewLine(true); - } - OutputMetaTag(); - } - - metaInjected = true; - } - } - else if (token.TokenId == HtmlTokenId.Text) - { - if (token.IsWhitespaceOnly) - { - - return false; - } - - - - - token.Text.StripLeadingWhitespace(); - - if (insideHtml && !insideHead) - { - writer.WriteNewLine(true); - writer.WriteStartTag(HtmlNameIndex.Head); - writer.WriteNewLine(true); - - OutputMetaTag(); - - writer.WriteEndTag(HtmlNameIndex.Head); - writer.WriteNewLine(true); - } - else - { - if (insideHead) - { - writer.WriteNewLine(true); - } - - OutputMetaTag(); - } - - metaInjected = true; - } - } - } - - return true; - } - - - private void OutputMetaTag() - { - InternalDebug.Assert(CopyPendingStateFlag == CopyPendingState.NotPending); - InternalDebug.Assert(!filterForFragment); - - - - - - - InternalDebug.Assert(writer.HasEncoding); - - var encoding = writer.Encoding; - - if (encoding.CodePage == 65000) - { - - - writer.Encoding = Encoding.ASCII; - } - - writer.WriteStartTag(HtmlNameIndex.Meta); - writer.WriteAttribute(HtmlNameIndex.HttpEquiv, "Content-Type"); - writer.WriteAttributeName(HtmlNameIndex.Content); - writer.WriteAttributeValueInternal("text/html; charset="); - writer.WriteAttributeValueInternal(Charset.GetCharset(encoding.CodePage).Name); - - if (encoding.CodePage == 65000) - { - writer.WriteTagEnd(); - writer.Encoding = encoding; - } - - - } - - - private AttributeIndirectKind GetAttributeIndirectKind(int index) - { - InternalDebug.Assert(index >= 0 && index < attributeCount); - - return attributeIndirect ? attributeIndirectIndex[index + attributeSkipCount].kind : AttributeIndirectKind.PassThrough; - } - - - private int GetAttributeVirtualEntryIndex(int index) - { - InternalDebug.Assert(index >= 0 && index < attributeCount); - InternalDebug.Assert(attributeIndirect); - InternalDebug.Assert(GetAttributeIndirectKind(index) == AttributeIndirectKind.Virtual || - GetAttributeIndirectKind(index) == AttributeIndirectKind.VirtualFilteredStyle); - - return attributeIndirectIndex[index + attributeSkipCount].index; - } - - - private HtmlAttribute GetAttribute(int index) - { - InternalDebug.Assert(index >= 0 && index < attributeCount); - - InternalDebug.Assert(GetAttributeIndirectKind(index) != AttributeIndirectKind.FilteredStyle && - GetAttributeIndirectKind(index) != AttributeIndirectKind.VirtualFilteredStyle); - - if (!attributeIndirect) - { - - return token.Attributes[index + attributeSkipCount]; - } - else if (attributeIndirectIndex[index + attributeSkipCount].kind != AttributeIndirectKind.Virtual) - { - return token.Attributes[attributeIndirectIndex[index + attributeSkipCount].index]; - } - else - { - - return token.Attributes[attributeVirtualList[attributeIndirectIndex[index + attributeSkipCount].index].index]; - } - } - - - internal HtmlAttributeId GetAttributeNameId(int index) - { - var kind = GetAttributeIndirectKind(index); - - if (kind == AttributeIndirectKind.FilteredStyle || kind == AttributeIndirectKind.VirtualFilteredStyle) - { - - return HtmlAttributeId.Style; - } - - - - var attribute = GetAttribute(index); - return HtmlNameData.names[(int)attribute.NameIndex].publicAttributeId; - } - - private static readonly HtmlAttributeParts CompleteAttributeParts = new HtmlAttributeParts(HtmlToken.AttrPartMajor.Complete, HtmlToken.AttrPartMinor.CompleteNameWithCompleteValue); - - - internal HtmlAttributeParts GetAttributeParts(int index) - { - var kind = GetAttributeIndirectKind(index); - - if (kind == AttributeIndirectKind.FilteredStyle || kind == AttributeIndirectKind.VirtualFilteredStyle) - { - - return CompleteAttributeParts; - } - - var attribute = GetAttribute(index); - - if (kind == AttributeIndirectKind.NameOnlyFragment) - { - - - - InternalDebug.Assert((attribute.MajorPart & HtmlToken.AttrPartMajor.End) != HtmlToken.AttrPartMajor.End); - - - InternalDebug.Assert((attribute.MinorPart & HtmlToken.AttrPartMinor.ContinueName) != 0); - - return new HtmlAttributeParts(attribute.MajorPart, attribute.MinorPart & ~HtmlToken.AttrPartMinor.CompleteValue); - } - else if (kind == AttributeIndirectKind.EmptyValue || kind == AttributeIndirectKind.Virtual) - { - - return new HtmlAttributeParts(attribute.MajorPart | HtmlToken.AttrPartMajor.End, attribute.MinorPart | HtmlToken.AttrPartMinor.CompleteValue); - } - - return new HtmlAttributeParts(attribute.MajorPart, attribute.MinorPart); - } - - - internal string GetAttributeName(int index) - { - var kind = GetAttributeIndirectKind(index); - - if (kind == AttributeIndirectKind.FilteredStyle || kind == AttributeIndirectKind.VirtualFilteredStyle) - { - - InternalDebug.Assert(tagHasFilteredStyleAttribute); - - return HtmlNameData.names[(int)HtmlNameIndex.Style].name; - } - - - - var attribute = GetAttribute(index); - - if (attribute.NameIndex > HtmlNameIndex.Unknown) - { - return attribute.IsAttrBegin ? HtmlNameData.names[(int)attribute.NameIndex].name : String.Empty; - } - else if (attribute.HasNameFragment) - { - return attribute.Name.GetString(int.MaxValue); - } - else - { - return attribute.IsAttrBegin ? "?" : String.Empty; - } - } - - - - - internal string GetAttributeValue(int index) - { - var kind = GetAttributeIndirectKind(index); - - if (kind != AttributeIndirectKind.PassThrough) - { - if (kind == AttributeIndirectKind.FilteredStyle) - { - - VirtualizeFilteredStyle(index); - kind = AttributeIndirectKind.VirtualFilteredStyle; - } - - if (kind == AttributeIndirectKind.Virtual || kind == AttributeIndirectKind.VirtualFilteredStyle) - { - - var vi = GetAttributeVirtualEntryIndex(index); - if (attributeVirtualList[vi].length != 0) - { - return new string(attributeVirtualScratch.Buffer, attributeVirtualList[vi].offset, attributeVirtualList[vi].length); - } - - return String.Empty; - } - - InternalDebug.Assert(kind == AttributeIndirectKind.EmptyValue || kind == AttributeIndirectKind.NameOnlyFragment); - return String.Empty; - } - - var attribute = GetAttribute(index); - - if (!attribute.HasValueFragment) - { - return String.Empty; - } - - return attribute.Value.GetString(int.MaxValue); - } - - - internal int ReadAttributeValue(int index, char[] buffer, int offset, int count) - { - var kind = GetAttributeIndirectKind(index); - - if (kind != AttributeIndirectKind.PassThrough) - { - if (kind == AttributeIndirectKind.FilteredStyle) - { - - VirtualizeFilteredStyle(index); - kind = AttributeIndirectKind.VirtualFilteredStyle; - } - - if (kind == AttributeIndirectKind.Virtual || kind == AttributeIndirectKind.VirtualFilteredStyle) - { - - var vi = GetAttributeVirtualEntryIndex(index); - - InternalDebug.Assert(attributeVirtualList[vi].position < attributeVirtualList[vi].length); - - var countRead = Math.Min(attributeVirtualList[vi].length - attributeVirtualList[vi].position, count); - if (countRead != 0) - { - Buffer.BlockCopy(attributeVirtualScratch.Buffer, 2 * (attributeVirtualList[vi].offset + attributeVirtualList[vi].position), buffer, offset, 2 * countRead); - attributeVirtualList[vi].position += countRead; - } - - return countRead; - } - - InternalDebug.Assert(kind == AttributeIndirectKind.EmptyValue || kind == AttributeIndirectKind.NameOnlyFragment); - return 0; - } - - var attribute = GetAttribute(index); - - if (!attribute.HasValueFragment) - { - return 0; - } - - return attribute.Value.Read(buffer, offset, count); - } - - - internal void WriteTag(bool copyTagAttributes) - { - CopyInputTag(copyTagAttributes); - } - - - internal void WriteAttribute(int index, bool writeName, bool writeValue) - { - if (writeName) - { - if (writeValue) - { - CopyInputAttribute(index); - } - else - { - CopyInputAttributeName(index); - } - } - else if (writeValue) - { - CopyInputAttributeValue(index); - } - } - - - private void AppendCssFromTokenText() - { - if (null == cssParserInput) - { - cssParserInput = new ConverterBufferInput(CssParser.MaxCssLength, progressMonitor); - cssParser = new CssParser(cssParserInput, 4 * 1024, false); - } - - token.Text.WriteTo(cssParserInput); - } - - - private void AppendCss(string css) - { - if (null == cssParserInput) - { - cssParserInput = new ConverterBufferInput(CssParser.MaxCssLength, progressMonitor); - cssParser = new CssParser(cssParserInput, 4 * 1024, false); - } - - cssParserInput.Write(css); - } - - - private void AppendCssFromAttribute(HtmlAttribute attribute) - { - if (null == cssParserInput) - { - cssParserInput = new ConverterBufferInput(CssParser.MaxCssLength, progressMonitor); - cssParser = new CssParser(cssParserInput, 4 * 1024, false); - } - - attribute.Value.Rewind(); - attribute.Value.WriteTo(cssParserInput); - } - - - private void FlushCssInStyleTag() - { - if (null != cssParserInput) - { - writer.WriteNewLine(); - writer.WriteMarkupText(""); - writer.WriteNewLine(); - } - } - - - private void FlushCssInStyleAttributeToVirtualScratch() - { - - cssParser.SetParseMode(CssParseMode.StyleAttribute); - - if (virtualScratchSink == null) - { - virtualScratchSink = new VirtualScratchSink(this, int.MaxValue); - } - - CssTokenId tokenId; - var firstProperty = true; - do - { - tokenId = cssParser.Parse(); - - if (CssTokenId.Declarations == tokenId && cssParser.Token.Properties.ValidCount != 0) - { - CopyInputCssProperties(false, cssParser.Token.Properties, virtualScratchSink, ref firstProperty); - } - } - while (CssTokenId.EndOfFile != tokenId); - - cssParserInput.Reset(); - cssParser.Reset(); - } - - - private void FlushCssInStyleAttribute(HtmlWriter writer) - { - - cssParser.SetParseMode(CssParseMode.StyleAttribute); - - var sink = writer.WriteAttributeValue(); - - CssTokenId tokenId; - var firstProperty = true; - do - { - tokenId = cssParser.Parse(); - - if (CssTokenId.Declarations == tokenId && cssParser.Token.Properties.ValidCount != 0) - { - CopyInputCssProperties(false, cssParser.Token.Properties, sink, ref firstProperty); - } - } - while (CssTokenId.EndOfFile != tokenId); - - cssParserInput.Reset(); - cssParser.Reset(); - } - - - private bool CopyInputCssSelectors(CssToken.SelectorEnumerator selectors, ITextSinkEx sink, bool agressiveFiltering) - { - var atLeastOneOk = false; - var lastOk = false; - - - selectors.Rewind(); - - foreach (var selector in selectors) - { - if (!selector.IsDeleted) - { - if (lastOk) - { - if (selector.Combinator == CssSelectorCombinator.None) - { - sink.Write(", "); - } - else if (selector.Combinator == CssSelectorCombinator.Descendant) - { - InternalDebug.Assert(!selector.IsSimple); - sink.Write(' '); - } - else if (selector.Combinator == CssSelectorCombinator.Adjacent) - { - InternalDebug.Assert(!selector.IsSimple); - sink.Write(" + "); - } - else - { - InternalDebug.Assert(!selector.IsSimple); - InternalDebug.Assert(selector.Combinator == CssSelectorCombinator.Child); - sink.Write(" > "); - } - } - - lastOk = CopyInputCssSelector(selector, sink, agressiveFiltering); - atLeastOneOk = atLeastOneOk || lastOk; - } - } - - return atLeastOneOk; - } - - - private bool CopyInputCssSelector(CssSelector selector, ITextSinkEx sink, bool agressiveFiltering) - { - InternalDebug.Assert(!selector.IsDeleted); - - if (filterForFragment) - { - if (!selector.HasClassFragment || - (selector.ClassType != CssSelectorClassType.Regular && - selector.ClassType != CssSelectorClassType.Hash)) - { - - return false; - } -#if false - string className = selector.ClassName.GetString(256); - - if (!className.StartsWith("Mso", StringComparison.Ordinal) && - !className.StartsWith("NL", StringComparison.Ordinal) && - !className.StartsWith("email", StringComparison.OrdinalIgnoreCase) && - !className.StartsWith("outlook", StringComparison.OrdinalIgnoreCase)) - { - - return false; - } -#endif - } - - if (agressiveFiltering) - { - - - if (!selector.HasClassFragment || selector.ClassType != CssSelectorClassType.Regular) - { - - return false; - } - - - var className = selector.ClassName.GetString(256); - - - InternalDebug.Assert(className.Length > 0); - - if (!className.Equals("MsoNormal", StringComparison.Ordinal)) - { - return false; - } - } - - if (selector.NameId != HtmlNameIndex.Unknown && selector.NameId != HtmlNameIndex._NOTANAME) - { - sink.Write(HtmlNameData.names[(int)selector.NameId].name); - } - else if (selector.HasNameFragment) - { - - selector.Name.WriteOriginalTo(sink); - } - - if (selector.HasClassFragment) - { - if (selector.ClassType == CssSelectorClassType.Regular) - { - sink.Write("."); - } - else if (selector.ClassType == CssSelectorClassType.Hash) - { - sink.Write("#"); - } - else if (selector.ClassType == CssSelectorClassType.Pseudo) - { - sink.Write(":"); - } - else - { - - InternalDebug.Assert(selector.ClassType == CssSelectorClassType.Attrib); - } - - if (outputFragment) - { - InternalDebug.Assert(selector.ClassType == CssSelectorClassType.Hash || selector.ClassType == CssSelectorClassType.Regular); - - sink.Write(NamePrefix); - } - - - selector.ClassName.WriteOriginalTo(sink); - } - - return true; - } - - - private void CopyInputCssProperties(bool inTag, CssToken.PropertyEnumerator properties, ITextSinkEx sink, ref bool firstProperty) - { - - - properties.Rewind(); - - foreach (var property in properties) - { - if (property.IsPropertyBegin && !property.IsDeleted) - { - var action = CssData.filterInstructions[(int)property.NameId].propertyAction; - - if (CssData.FilterAction.CheckContent == action) - { - if (property.NameId == CssNameIndex.Display && - property.HasValueFragment && - property.Value.CaseInsensitiveContainsSubstring("none") && - !preserveDisplayNoneStyle) - { - action = CssData.FilterAction.Drop; - } - else if (property.NameId == CssNameIndex.Position && - property.HasValueFragment && - (property.Value.CaseInsensitiveContainsSubstring("absolute") || - property.Value.CaseInsensitiveContainsSubstring("relative")) && - outputFragment) - { - action = CssData.FilterAction.Drop; - } - else - { - action = CssData.FilterAction.Keep; - } - } - - if (CssData.FilterAction.Keep == action) - { - if (firstProperty) - { - firstProperty = false; - } - else - { - sink.Write(inTag ? ";\r\n\t" : "; "); - } - - CopyInputCssProperty(property, sink); - } - } - } - } - - - private static void CopyInputCssProperty(CssProperty property, ITextSinkEx sink) - { - InternalDebug.Assert(!property.IsDeleted); - - if (property.IsPropertyBegin) - { - if (property.NameId != CssNameIndex.Unknown) - { - sink.Write(CssData.names[(int)property.NameId].name); - } - } - - if (property.NameId == CssNameIndex.Unknown && property.HasNameFragment) - { - - property.Name.WriteOriginalTo(sink); - } - - if (property.IsPropertyNameEnd) - { - sink.Write(":"); - } - - if (property.HasValueFragment) - { - - property.Value.WriteEscapedOriginalTo(sink); - } - } - - - - internal class VirtualScratchSink : ITextSinkEx - { - private HtmlToHtmlConverter converter; - private int maxLength; - - public VirtualScratchSink(HtmlToHtmlConverter converter, int maxLength) - { - this.converter = converter; - this.maxLength = maxLength; - } - - public bool IsEnough => converter.attributeVirtualScratch.Length >= maxLength; - - public void Write(char[] buffer, int offset, int count) - { - InternalDebug.Assert(!IsEnough); - converter.attributeVirtualScratch.Append(buffer, offset, count, maxLength); - } - - public void Write(int ucs32Char) - { - InternalDebug.Assert(!IsEnough); - - if (Token.LiteralLength(ucs32Char) == 1) - { - converter.attributeVirtualScratch.Append((char)ucs32Char, maxLength); - } - else - { - converter.attributeVirtualScratch.Append(Token.LiteralFirstChar(ucs32Char), maxLength); - if (!IsEnough) - { - converter.attributeVirtualScratch.Append(Token.LiteralLastChar(ucs32Char), maxLength); - } - } - } - - public void Write(string value) - { - InternalDebug.Assert(!IsEnough); - - - converter.attributeVirtualScratch.Append(value, maxLength); - } - - public void WriteNewLine() - { - InternalDebug.Assert(!IsEnough); - - converter.attributeVirtualScratch.Append('\r', maxLength); - - if (!IsEnough) - { - converter.attributeVirtualScratch.Append('\n', maxLength); - } - } - } - } - - - - - - internal class HtmlToHtmlTagContext : HtmlTagContext - { - private HtmlToHtmlConverter converter; - - public HtmlToHtmlTagContext(HtmlToHtmlConverter converter) - { - this.converter = converter; - } - - - - - internal override string GetTagNameImpl() - { - if (TagNameIndex > HtmlNameIndex.Unknown) - { - return TagParts.Begin ? HtmlNameData.names[(int)TagNameIndex].name : String.Empty; - } - else if (TagParts.Name) - { - return converter.token.Name.GetString(int.MaxValue); - } - else - { - return String.Empty; - } - } - - internal override HtmlAttributeId GetAttributeNameIdImpl(int attributeIndex) - { - return converter.GetAttributeNameId(attributeIndex); - } - - internal override HtmlAttributeParts GetAttributePartsImpl(int attributeIndex) - { - return converter.GetAttributeParts(attributeIndex); - } - - internal override string GetAttributeNameImpl(int attributeIndex) - { - return converter.GetAttributeName(attributeIndex); - } - - - - internal override string GetAttributeValueImpl(int attributeIndex) - { - return converter.GetAttributeValue(attributeIndex); - } - - internal override int ReadAttributeValueImpl(int attributeIndex, char[] buffer, int offset, int count) - { - return converter.ReadAttributeValue(attributeIndex, buffer, offset, count); - } - - internal override void WriteTagImpl(bool copyTagAttributes) - { - converter.WriteTag(copyTagAttributes); - } - - internal override void WriteAttributeImpl(int attributeIndex, bool writeName, bool writeValue) - { - converter.WriteAttribute(attributeIndex, writeName, writeValue); - } - } -} diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlToTextConverter.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlToTextConverter.cs deleted file mode 100644 index 19812b29e..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlToTextConverter.cs +++ /dev/null @@ -1,1404 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters.Internal.Html -{ - using System; - using System.IO; - using System.Text; - using Data.Internal; - using Globalization; - using Text; - - using Format; - - - - internal class HtmlToTextConverter : IProducerConsumer, IRestartable, IReusable, IDisposable - { - - - private bool convertFragment; - - private IHtmlParser parser; - private bool endOfFile; - - private TextOutput output; - - private HtmlToken token; - - private bool treatNbspAsBreakable; - private bool outputImageLinks = true; - private bool outputAnchorLinks = true; - - protected bool normalizedInput; - - private NormalizerContext normalizerContext; - - private TextMapping textMapping; - - - private struct NormalizerContext - { - - public char lastCh; - public bool oneNL; - public bool hasSpace; - public bool eatSpace; - } - - private bool lineStarted; - private bool wideGap; - private bool nextParagraphCloseWideGap = true; - private bool afterFirstParagraph; - private bool ignoreNextP; - - - private int listLevel; - private int listIndex; - private bool listOrdered; - - private bool insideComment; - private bool insidePre; - private bool insideAnchor; - - private ScratchBuffer urlScratch; - private int imageHeightPixels; - private int imageWidthPixels; - private ScratchBuffer imageAltText; - - private ScratchBuffer scratch; - - private Injection injection; - - private UrlCompareSink urlCompareSink; - - - - public HtmlToTextConverter( - IHtmlParser parser, - TextOutput output, - Injection injection, - bool convertFragment, - bool preformattedText, - bool testTreatNbspAsBreakable, - Stream traceStream, - bool traceShowTokenNum, - int traceStopOnTokenNum) - { - - normalizedInput = (parser is HtmlNormalizingParser); - - treatNbspAsBreakable = testTreatNbspAsBreakable; - - this.convertFragment = convertFragment; - - this.output = output; - - this.parser = parser; - this.parser.SetRestartConsumer(this); - - if (!convertFragment) - { - this.injection = injection; - - this.output.OpenDocument(); - - if (this.injection != null && this.injection.HaveHead) - { - this.injection.Inject(true, this.output); - } - } - else - { - insidePre = preformattedText; - } - } - - - - private void Reinitialize() - { - endOfFile = false; - - normalizerContext.hasSpace = false; - normalizerContext.eatSpace = false; - normalizerContext.oneNL = false; - normalizerContext.lastCh = '\0'; - - lineStarted = false; - wideGap = false; - nextParagraphCloseWideGap = true; - afterFirstParagraph = false; - ignoreNextP = false; - - insideComment = false; - insidePre = false; - insideAnchor = false; - if (urlCompareSink != null) - { - urlCompareSink.Reset(); - } - - listLevel = 0; - listIndex= 0; - listOrdered = false; - - - - - if (!convertFragment) - { - output.OpenDocument(); - - if (injection != null) - { - injection.Reset(); - - if (injection.HaveHead) - { - injection.Inject(true, output); - } - } - } - - textMapping = TextMapping.Unicode; - - } - - - - public void Run() - { - - if (!endOfFile) - { - var tokenId = parser.Parse(); - - if (HtmlTokenId.None != tokenId) - { - Process(tokenId); - } - } - } - - - - public bool Flush() - { - if (!endOfFile) - { - Run(); - } - - return endOfFile; - } - - - - private void Process(HtmlTokenId tokenId) - { - token = parser.Token; - - switch (tokenId) - { - - - case HtmlTokenId.Tag: - - if (token.TagIndex <= HtmlTagIndex.Unknown) - { - break; - } - - var tagDef = GetTagDefinition(token.TagIndex); - - if (normalizedInput) - { - if (!token.IsEndTag) - { - if (token.IsTagBegin) - { - - PushElement(tagDef); - } - - ProcessStartTagAttributes(tagDef); - } - else - { - if (token.IsTagBegin) - { - PopElement(tagDef); - } - } - } - else - { - - - - - - - - if (!token.IsEndTag) - { - if (token.IsTagBegin) - { - LFillTagB(tagDef); - PushElement(tagDef); - RFillTagB(tagDef); - } - - ProcessStartTagAttributes(tagDef); - } - else - { - if (token.IsTagBegin) - { - LFillTagE(tagDef); - PopElement(tagDef); - RFillTagE(tagDef); - } - } - } - break; - - - - case HtmlTokenId.Text: - - if (!insideComment) - { - if (insideAnchor && urlCompareSink.IsActive) - { - token.Text.WriteTo(urlCompareSink); - } - - if (insidePre) - { - ProcessPreformatedText(); - } - else if (normalizedInput) - { - ProcessText(); - } - else - { - NormalizeProcessText(); - } - } - break; - - - - - case HtmlTokenId.OverlappedClose: - case HtmlTokenId.OverlappedReopen: - - break; - - - - case HtmlTokenId.Restart: - - break; - - - - case HtmlTokenId.EncodingChange: - - if (output.OutputCodePageSameAsInput) - { - var codePage = token.Argument; - - #if DEBUG - Encoding newOutputEncoding; - - InternalDebug.Assert(Charset.TryGetEncoding(codePage, out newOutputEncoding)); - #endif - - - - output.OutputEncoding = Charset.GetEncoding(codePage); - } - - break; - - - - case HtmlTokenId.EndOfFile: - - if (lineStarted) - { - output.OutputNewLine(); - lineStarted = false; - } - - if (!convertFragment) - { - if (injection != null && injection.HaveHead) - { - if (wideGap) - { - output.OutputNewLine(); - wideGap = false; - } - - injection.Inject(false, output); - } - - output.CloseDocument(); - output.Flush(); - } - - endOfFile = true; - break; - - } - } - - - private void PushElement(HtmlDtd.TagDefinition tagDef) - { - switch (tagDef.tagIndex) - { - case HtmlTagIndex.Title: - case HtmlTagIndex.Comment: - case HtmlTagIndex.Script: - case HtmlTagIndex.Style: - - case HtmlTagIndex.NoEmbed: - case HtmlTagIndex.NoFrames: - - insideComment = true; - break; - - case HtmlTagIndex.A: - - - if (insideAnchor) - { - - - - - EndAnchor(); - } - break; - - case HtmlTagIndex.Image: - case HtmlTagIndex.Img: - - break; - - case HtmlTagIndex.TD: - case HtmlTagIndex.TH: - - if (lineStarted) - { - output.OutputTabulation(1); - } - break; - - case HtmlTagIndex.P: - - if (!ignoreNextP) - { - EndParagraph(true); - } - nextParagraphCloseWideGap = true; - break; - - - case HtmlTagIndex.BR: - case HtmlTagIndex.Option: - - EndLine(); - break; - - - case HtmlTagIndex.HR: - - EndParagraph(false); - OutputText("________________________________"); - EndParagraph(false); - break; - - - case HtmlTagIndex.OL: - case HtmlTagIndex.UL: - case HtmlTagIndex.Dir: - case HtmlTagIndex.Menu: - - EndParagraph(listLevel == 0); - - if (listLevel < 10) - { - listLevel ++; - - if (listLevel == 1) - { - listIndex = 1; - listOrdered = (token.TagIndex == HtmlTagIndex.OL); - } - } - nextParagraphCloseWideGap = false; - break; - - case HtmlTagIndex.LI: - - EndParagraph(false); - - - OutputText(" "); - - for (var i = 0; i < listLevel - 1; i++) - { - - OutputText(" "); - } - - if (listLevel > 1 || !listOrdered) - { - OutputText("*"); - output.OutputSpace(3); - } - else - { - var num = listIndex.ToString(); - - OutputText(num); - - OutputText("."); - output.OutputSpace(num.Length == 1 ? 2 : 1); - listIndex ++; - } - break; - - - case HtmlTagIndex.DL: - - EndParagraph(true); - break; - - case HtmlTagIndex.DT: - - if (lineStarted) - { - EndLine(); - } - break; - - case HtmlTagIndex.DD: - - if (lineStarted) - { - EndLine(); - } - break; - - - case HtmlTagIndex.Pre: - case HtmlTagIndex.PlainText: - case HtmlTagIndex.Listing: - case HtmlTagIndex.Xmp: - - EndParagraph(true); - insidePre = true; - break; - - case HtmlTagIndex.Font: - case HtmlTagIndex.Span: - - break; - - default: - if (tagDef.blockElement) - { - EndParagraph(false); - } - break; - } - - ignoreNextP = false; - - if (tagDef.tagIndex == HtmlTagIndex.LI) - { - - ignoreNextP = true; - } - } - - private void ProcessStartTagAttributes(HtmlDtd.TagDefinition tagDef) - { - switch (tagDef.tagIndex) - { - case HtmlTagIndex.A: - - - if (outputAnchorLinks) - { - foreach (var attr in token.Attributes) - { - if (attr.NameIndex == HtmlNameIndex.Href) - { - if (attr.IsAttrBegin) - { - urlScratch.Reset(); - } - - urlScratch.AppendHtmlAttributeValue(attr, HtmlSupport.MaxAttributeSize); - break; - } - } - - if (token.IsTagEnd) - { - var url = urlScratch.BufferString; - - url.TrimWhitespace(); - - if (url.Length != 0 && url[0] != '#' && url[0] != '?' && url[0] != ';') - { - if (!lineStarted) - { - StartParagraphOrLine(); - } - - - - - var urlString = url.ToString(); - - if (urlString.IndexOf(' ') != -1) - { - urlString = urlString.Replace(" ", "%20"); - } - - output.OpenAnchor(urlString); - insideAnchor = true; - - if (urlCompareSink == null) - { - urlCompareSink = new UrlCompareSink(); - } - - urlCompareSink.Initialize(urlString); - } - - urlScratch.Reset(); - } - } - break; - - case HtmlTagIndex.Image: - case HtmlTagIndex.Img: - - - - if (outputImageLinks) - { - foreach (var attr in token.Attributes) - { - if (attr.NameIndex == HtmlNameIndex.Src) - { - if (attr.IsAttrBegin) - { - urlScratch.Reset(); - } - - urlScratch.AppendHtmlAttributeValue(attr, HtmlSupport.MaxAttributeSize); - } - else if (attr.NameIndex == HtmlNameIndex.Alt) - { - if (attr.IsAttrBegin) - { - imageAltText.Reset(); - } - - imageAltText.AppendHtmlAttributeValue(attr, HtmlSupport.MaxAttributeSize); - } - else if (attr.NameIndex == HtmlNameIndex.Height) - { - if (!attr.Value.IsEmpty) - { - PropertyValue value; - - if (attr.Value.IsContiguous) - { - value = HtmlSupport.ParseNumber(attr.Value.ContiguousBufferString, HtmlSupport.NumberParseFlags.Length); - } - else - { - scratch.Reset(); - scratch.AppendHtmlAttributeValue(attr, HtmlSupport.MaxAttributeSize); - value = HtmlSupport.ParseNumber(scratch.BufferString, HtmlSupport.NumberParseFlags.Length); - } - - if (value.IsAbsRelLength) - { - imageHeightPixels = value.PixelsInteger; - if (imageHeightPixels == 0) - { - imageHeightPixels = 1; - } - } - } - } - else if (attr.NameIndex == HtmlNameIndex.Width) - { - if (!attr.Value.IsEmpty) - { - PropertyValue value; - - if (attr.Value.IsContiguous) - { - value = HtmlSupport.ParseNumber(attr.Value.ContiguousBufferString, HtmlSupport.NumberParseFlags.Length); - } - else - { - scratch.Reset(); - scratch.AppendHtmlAttributeValue(attr, HtmlSupport.MaxAttributeSize); - value = HtmlSupport.ParseNumber(scratch.BufferString, HtmlSupport.NumberParseFlags.Length); - } - - if (value.IsAbsRelLength) - { - imageWidthPixels = value.PixelsInteger; - if (imageWidthPixels == 0) - { - imageWidthPixels = 1; - } - } - } - } - } - - - - if (token.IsTagEnd) - { - string urlString = null; - string altString = null; - - - - var alt = imageAltText.BufferString; - - alt.TrimWhitespace(); - - if (alt.Length != 0) - { - altString = alt.ToString(); - } - - if (altString == null || output.ImageRenderingCallbackDefined) - { - var url = urlScratch.BufferString; - - url.TrimWhitespace(); - - if (url.Length != 0) - { - urlString = url.ToString(); - } - } - - if (!lineStarted) - { - StartParagraphOrLine(); - } - - output.OutputImage(urlString, altString, imageWidthPixels, imageHeightPixels); - - urlScratch.Reset(); - imageAltText.Reset(); - imageHeightPixels = 0; - imageWidthPixels = 0; - } - } - break; - - case HtmlTagIndex.P: - - - - - if (token.Attributes.Find(HtmlNameIndex.Class) && token.Attributes.Current.Value.CaseInsensitiveCompareEqual("msonormal")) - { - - - - - wideGap = false; - nextParagraphCloseWideGap = false; - } - break; - - case HtmlTagIndex.Font: - - foreach (var attr in token.Attributes) - { - if (attr.NameIndex == HtmlNameIndex.Face) - { - scratch.Reset(); - scratch.AppendHtmlAttributeValue(attr, HtmlSupport.MaxAttributeSize); - - var fontRecognizer = new RecognizeInterestingFontName(); - - for (var i = 0; i < scratch.Length && !fontRecognizer.IsRejected; i++) - { - fontRecognizer.AddCharacter(scratch.Buffer[i]); - } - - textMapping = fontRecognizer.TextMapping; - break; - } - } - - break; - - - case HtmlTagIndex.Span: - - foreach (var attr in token.Attributes) - { - if (attr.NameIndex == HtmlNameIndex.Style) - { - scratch.Reset(); - scratch.AppendHtmlAttributeValue(attr, HtmlSupport.MaxAttributeSize); - - var fontRecognizer = new RecognizeInterestingFontNameInInlineStyle(); - - for (var i = 0; i < scratch.Length && !fontRecognizer.IsFinished; i++) - { - fontRecognizer.AddCharacter(scratch.Buffer[i]); - } - - textMapping = fontRecognizer.TextMapping; - break; - } - } - - break; - - } - } - - - private void PopElement(HtmlDtd.TagDefinition tagDef) - { - switch (tagDef.tagIndex) - { - case HtmlTagIndex.Title: - case HtmlTagIndex.Comment: - case HtmlTagIndex.Script: - case HtmlTagIndex.Style: - - case HtmlTagIndex.NoEmbed: - case HtmlTagIndex.NoFrames: - - insideComment = false; - break; - - case HtmlTagIndex.A: - - - if (insideAnchor) - { - EndAnchor(); - } - break; - - case HtmlTagIndex.Image: - case HtmlTagIndex.Img: - - break; - - case HtmlTagIndex.TD: - case HtmlTagIndex.TH: - - lineStarted = true; - break; - - case HtmlTagIndex.P: - - EndParagraph(nextParagraphCloseWideGap); - nextParagraphCloseWideGap = true; - break; - - - case HtmlTagIndex.BR: - case HtmlTagIndex.Option: - - EndLine(); - break; - - - case HtmlTagIndex.HR: - - EndParagraph(false); - OutputText("________________________________"); - EndParagraph(false); - break; - - - case HtmlTagIndex.OL: - case HtmlTagIndex.UL: - case HtmlTagIndex.Dir: - case HtmlTagIndex.Menu: - - if (listLevel != 0) - { - listLevel --; - } - - EndParagraph(listLevel == 0); - break; - - case HtmlTagIndex.DT: - - break; - - case HtmlTagIndex.DD: - - break; - - - case HtmlTagIndex.Pre: - case HtmlTagIndex.PlainText: - case HtmlTagIndex.Listing: - case HtmlTagIndex.Xmp: - - EndParagraph(true); - insidePre = false; - break; - - case HtmlTagIndex.Font: - case HtmlTagIndex.Span: - - textMapping = TextMapping.Unicode; - break; - - default: - if (tagDef.blockElement) - { - EndParagraph(false); - } - break; - } - - ignoreNextP = false; - } - - - private void ProcessText() - { - if (!lineStarted) - { - StartParagraphOrLine(); - } - - foreach (var run in token.Runs) - { - if (run.IsTextRun) - { - if (run.IsAnyWhitespace) - { - output.OutputSpace(1); - } - else if (run.TextType == RunTextType.Nbsp) - { - if (treatNbspAsBreakable) - { - output.OutputSpace(run.Length); - } - else - { - output.OutputNbsp(run.Length); - } - } - else - { - if (run.IsLiteral) - { - output.OutputNonspace(run.Literal, textMapping); - } - else - { - output.OutputNonspace(run.RawBuffer, run.RawOffset, run.RawLength, textMapping); - } - } - } - } - } - - - private void ProcessPreformatedText() - { - if (!lineStarted) - { - StartParagraphOrLine(); - } - - foreach (var run in token.Runs) - { - if (run.IsTextRun) - { - if (run.IsAnyWhitespace) - { - switch (run.TextType) - { - case RunTextType.NewLine: - - - output.OutputNewLine(); - break; - - case RunTextType.Space: - default: - - if (treatNbspAsBreakable) - { - output.OutputSpace(run.Length); - } - else - { - output.OutputNbsp(run.Length); - } - break; - - case RunTextType.Tabulation: -#if false - int tabPosition = this.output.LineLength() / 8 * 8 + 8 * run.Length; - int extraSpaces = tabPosition - this.output.LineLength(); - - this.output.OutputSpace(extraSpaces); -#endif - output.OutputTabulation(run.Length); - break; - } - } - else if (run.TextType == RunTextType.Nbsp) - { - if (treatNbspAsBreakable) - { - output.OutputSpace(run.Length); - } - else - { - output.OutputNbsp(run.Length); - } - } - else - { - if (run.IsLiteral) - { - output.OutputNonspace(run.Literal, textMapping); - } - else - { - output.OutputNonspace(run.RawBuffer, run.RawOffset, run.RawLength, textMapping); - } - } - } - } - } - - - private void NormalizeProcessText() - { - var runs = token.Runs; - - runs.MoveNext(true); - - while (runs.IsValidPosition) - { - var run = runs.Current; - - if (run.IsAnyWhitespace) - { - - - var cntWhitespaces = 0; - - do - { - - - cntWhitespaces += runs.Current.TextType == RunTextType.NewLine ? 1 : 2; - } - while (runs.MoveNext(true) && (runs.Current.TextType <= RunTextType.LastWhitespace)); - - NormalizeAddSpace(cntWhitespaces == 1); - } - else if (run.TextType == RunTextType.Nbsp) - { - NormalizeAddNbsp(run.Length); - - runs.MoveNext(true); - } - else - { - - NormalizeAddNonspace(run); - - runs.MoveNext(true); - } - } - } - - - private void NormalizeAddNonspace(TokenRun run) - { - if (!lineStarted) - { - StartParagraphOrLine(); - } - - if (normalizerContext.hasSpace) - { - normalizerContext.hasSpace = false; - - - - if ('\0' == normalizerContext.lastCh || !normalizerContext.oneNL || !ParseSupport.TwoFarEastNonHanguelChars(normalizerContext.lastCh, run.FirstChar)) - { - output.OutputSpace(1); - } - } - - if (run.IsLiteral) - { - output.OutputNonspace(run.Literal, textMapping); - } - else - { - output.OutputNonspace(run.RawBuffer, run.RawOffset, run.RawLength, textMapping); - } - - normalizerContext.eatSpace = false; - normalizerContext.lastCh = run.LastChar; - normalizerContext.oneNL = false; - } - - - private void NormalizeAddNbsp(int count) - { - if (!lineStarted) - { - StartParagraphOrLine(); - } - - if (normalizerContext.hasSpace) - { - normalizerContext.hasSpace = false; - - output.OutputSpace(1); - } - - if (treatNbspAsBreakable) - { - output.OutputSpace(count); - } - else - { - output.OutputNbsp(count); - } - - normalizerContext.eatSpace = false; - normalizerContext.lastCh = '\xA0'; - normalizerContext.oneNL = false; - } - - - private void NormalizeAddSpace(bool oneNL) - { - InternalDebug.Assert(!insidePre); - - if (!normalizerContext.eatSpace && afterFirstParagraph) - { - normalizerContext.hasSpace = true; - } - - if (normalizerContext.lastCh != '\0') - { - if (oneNL && !normalizerContext.oneNL) - { - normalizerContext.oneNL = true; - } - else - { - normalizerContext.lastCh = '\0'; - } - } - } - - - - - - - - private void LFillTagB(HtmlDtd.TagDefinition tagDef) - { - if (!insidePre) - { - LFill(tagDef.fill.LB); - } - } - - - private void RFillTagB(HtmlDtd.TagDefinition tagDef) - { - if (!insidePre) - { - RFill(tagDef.fill.RB); - } - } - - - private void LFillTagE(HtmlDtd.TagDefinition tagDef) - { - if (!insidePre) - { - LFill(tagDef.fill.LE); - } - } - - - private void RFillTagE(HtmlDtd.TagDefinition tagDef) - { - if (!insidePre) - { - RFill(tagDef.fill.RE); - } - } - - - private void LFill(HtmlDtd.FillCode codeLeft) - { - normalizerContext.lastCh = '\0'; - - if (normalizerContext.hasSpace) - { - if (codeLeft == HtmlDtd.FillCode.PUT) - { - if (!lineStarted) - { - StartParagraphOrLine(); - } - - output.OutputSpace(1); - normalizerContext.eatSpace = true; - } - - normalizerContext.hasSpace = (codeLeft == HtmlDtd.FillCode.NUL); - } - } - - - private void RFill(HtmlDtd.FillCode code) - { - if (code == HtmlDtd.FillCode.EAT) - { - normalizerContext.hasSpace = false; - normalizerContext.eatSpace = true; - } - else if (code == HtmlDtd.FillCode.PUT) - { - normalizerContext.eatSpace = false; - } - } - - - private static HtmlDtd.TagDefinition GetTagDefinition(HtmlTagIndex tagIndex) - { - return tagIndex != HtmlTagIndex._NULL ? HtmlDtd.tags[(int)tagIndex] : null; - } - - - - private void EndAnchor() - { - if (!urlCompareSink.IsMatch) - { - if (!lineStarted) - { - StartParagraphOrLine(); - } - - output.CloseAnchor(); - } - else - { - output.CancelAnchor(); - } - - insideAnchor = false; - urlCompareSink.Reset(); - } - - - - private void OutputText(string text) - { - if (!lineStarted) - { - StartParagraphOrLine(); - } - - output.OutputNonspace(text, textMapping); - } - - - - private void StartParagraphOrLine() - { - InternalDebug.Assert(!lineStarted); - - if (wideGap) - { - if (afterFirstParagraph) - { - output.OutputNewLine(); - } - - wideGap = false; - } - - lineStarted = true; - afterFirstParagraph = true; - } - - - - private void EndLine() - { - output.OutputNewLine(); - lineStarted = false; - wideGap = false; - } - - - - private void EndParagraph(bool wideGap) - { - if (insideAnchor) - { - - EndAnchor(); - } - - if (lineStarted) - { - output.OutputNewLine(); - lineStarted = false; - } - - this.wideGap = (this.wideGap || wideGap); - } - - - - void IDisposable.Dispose() - { - if (parser != null /*&& this.parser is IDisposable*/) - { - ((IDisposable)parser).Dispose(); - } - - if (!convertFragment && output != null && output is IDisposable) - { - ((IDisposable)output).Dispose(); - } - - if (token != null && token is IDisposable) - { - ((IDisposable)token).Dispose(); - } - - parser = null; - output = null; - - token = null; - - GC.SuppressFinalize(this); - } - - - - bool IRestartable.CanRestart() - { - return convertFragment || ((IRestartable)output).CanRestart(); - } - - - - void IRestartable.Restart() - { - InternalDebug.Assert(((IRestartable)this).CanRestart()); - - if (!convertFragment) - { - ((IRestartable)output).Restart(); - } - - Reinitialize(); - } - - - - void IRestartable.DisableRestart() - { - if (!convertFragment) - { - ((IRestartable)output).DisableRestart(); - } - } - - - - void IReusable.Initialize(object newSourceOrDestination) - { - InternalDebug.Assert(output is IReusable && parser is IReusable); - - ((IReusable)parser).Initialize(newSourceOrDestination); - ((IReusable)output).Initialize(newSourceOrDestination); - - Reinitialize(); - - parser.SetRestartConsumer(this); - } - - - - public void Initialize(string fragment, bool preformatedText) - { - if (normalizedInput) - { - ((HtmlNormalizingParser)parser).Initialize(fragment, preformatedText); - } - else - { - ((HtmlParser)parser).Initialize(fragment, preformatedText); - } - - if (!convertFragment) - { - ((IReusable)output).Initialize(null); - } - - Reinitialize(); - } - } -} - diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlToken.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlToken.cs deleted file mode 100644 index 5f9b8fd4f..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlToken.cs +++ /dev/null @@ -1,865 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters.Internal.Html -{ - using System; - using Data.Internal; - - - - internal enum HtmlTokenId : byte - { - None = TokenId.None, - EndOfFile = TokenId.EndOfFile, - Text = TokenId.Text, - EncodingChange = TokenId.EncodingChange, - - Tag = TokenId.EncodingChange + 1, - - Restart, - OverlappedClose, - OverlappedReopen, - - InjectionBegin, - InjectionEnd, - } - - - - internal enum HtmlLexicalUnit : uint - { - Invalid = RunKind.Invalid, - Text = RunKind.Text, - - TagPrefix = (2 << 26), - TagSuffix = (3 << 26), - Name = (4 << 26), - TagWhitespace = (5 << 26), - AttrEqual = (6 << 26), - AttrQuote = (7 << 26), - AttrValue = (8 << 26), - TagText = (9 << 26), - } - - - - internal enum HtmlRunKind : uint - { - Invalid = RunKind.Invalid, - Text = RunKind.Text, - - TagPrefix = HtmlLexicalUnit.TagPrefix, - TagSuffix = HtmlLexicalUnit.TagSuffix, - Name = HtmlLexicalUnit.Name, - NamePrefixDelimiter = HtmlLexicalUnit.Name + (1 << 24), - TagWhitespace = HtmlLexicalUnit.TagWhitespace, - AttrEqual = HtmlLexicalUnit.AttrEqual, - AttrQuote = HtmlLexicalUnit.AttrQuote, - AttrValue = HtmlLexicalUnit.AttrValue, - TagText = HtmlLexicalUnit.TagText, - } - - - - internal class HtmlToken : Token - { - protected internal HtmlTagIndex tagIndex; - protected internal HtmlTagIndex originalTagIndex; - protected internal HtmlNameIndex nameIndex; - - protected internal TagFlags flags; - protected internal TagPartMajor partMajor; - protected internal TagPartMinor partMinor; - - protected internal LexicalUnit unstructured; - protected internal FragmentPosition unstructuredPosition; - - protected internal LexicalUnit name; - protected internal LexicalUnit localName; - protected internal FragmentPosition namePosition; - - protected internal AttributeEntry[] attributeList; - protected internal int attributeTail; - - protected internal int currentAttribute; - protected internal FragmentPosition attrNamePosition; - protected internal FragmentPosition attrValuePosition; - - - - public HtmlToken() - { - Reset(); - } - - - - [Flags] - public enum TagFlags : byte - { - None = 0, - - - EmptyTagName = 0x08, - - EndTag = 0x10, - EmptyScope = 0x20, - - AllowWspLeft = 0x40, - AllowWspRight = 0x80, - } - - - - public enum TagPartMajor : byte - { - None = 0, - Begin = 0x01 | Continue, - Continue = 0x02, - End = Continue | 0x04, - Complete = Begin | End, - } - - - - public enum TagPartMinor : byte - { - Empty = 0, - - - BeginName = 0x01 | ContinueName, - ContinueName = 0x02, - EndName = ContinueName | 0x04, - EndNameWithAttributes = EndName | Attributes, - CompleteName = BeginName | EndName, - CompleteNameWithAttributes = CompleteName | Attributes, - - - BeginAttribute = 0x08 | ContinueAttribute, - ContinueAttribute = 0x10, - EndAttribute = ContinueAttribute | 0x20, - EndAttributeWithOtherAttributes = EndAttribute | Attributes, - AttributePartMask = BeginAttribute | EndAttribute, - - - Attributes = 0x80, - } - - - - public enum AttrPartMajor : byte - { - None = 0, - Begin = TagPartMinor.BeginAttribute, - Continue = TagPartMinor.ContinueAttribute, - End = TagPartMinor.EndAttribute, - Complete = Begin | End, - - - EmptyName = 0x01, - ValueQuoted = 0x40, - Deleted = 0x80, - MaskOffFlags = Complete, - } - - - - public enum AttrPartMinor : byte - { - Empty = 0, - - BeginName = 0x01 | ContinueName, - ContinueName = 0x02, - EndName = ContinueName | 0x04, - EndNameWithBeginValue = EndName | BeginValue, - EndNameWithCompleteValue = EndName | CompleteValue, - CompleteName = BeginName | EndName, - CompleteNameWithBeginValue = CompleteName | BeginValue, - CompleteNameWithCompleteValue = CompleteName | CompleteValue, - - BeginValue = 0x08 | ContinueValue, - ContinueValue = 0x10, - EndValue = ContinueValue | 0x20, - CompleteValue = BeginValue | EndValue, - } - - - - public new HtmlTokenId TokenId - { - get { return (HtmlTokenId)base.TokenId; } - set { base.TokenId = (TokenId)value; } - } - - public TagFlags Flags - { - get { return flags; } - set { flags = value; } - } - - public bool IsEndTag => 0 != (flags & TagFlags.EndTag); - - public bool IsEmptyScope => 0 != (flags & TagFlags.EmptyScope); - - public TagPartMajor MajorPart => partMajor; - - public TagPartMinor MinorPart => partMinor; - - public bool IsTagComplete => partMajor == TagPartMajor.Complete; - - public bool IsTagBegin => (partMajor & TagPartMajor.Begin) == TagPartMajor.Begin; - - public bool IsTagEnd => (partMajor & TagPartMajor.End) == TagPartMajor.End; - - public bool IsTagNameEmpty => 0 != (flags & TagFlags.EmptyTagName); - - public bool IsTagNameBegin => (partMinor & TagPartMinor.BeginName) == TagPartMinor.BeginName; - - public bool IsTagNameEnd => (partMinor & TagPartMinor.EndName) == TagPartMinor.EndName; - - public bool HasNameFragment => !IsFragmentEmpty(name); -#if false - public bool HasUnstructuredContentFragment - { - get { return !this.IsFragmentEmpty(this.unstructured); } - } -#endif - public HtmlNameIndex NameIndex => nameIndex; - - public TagNameTextReader Name => new TagNameTextReader(this); - - public TagUnstructuredContentTextReader UnstructuredContent => new TagUnstructuredContentTextReader(this); - - public HtmlTagIndex TagIndex => tagIndex; - - public HtmlTagIndex OriginalTagId => originalTagIndex; - - public bool IsAllowWspLeft => (flags & TagFlags.AllowWspLeft) == TagFlags.AllowWspLeft; - - public bool IsAllowWspRight => (flags & TagFlags.AllowWspRight) == TagFlags.AllowWspRight; - - public AttributeEnumerator Attributes => new AttributeEnumerator(this); - - internal new void Reset() - { - tagIndex = originalTagIndex = HtmlTagIndex._NULL; - nameIndex = HtmlNameIndex._NOTANAME; - flags = TagFlags.None; - partMajor = TagPartMajor.None; - partMinor = TagPartMinor.Empty; - - name.Reset(); - unstructured.Reset(); - - - namePosition.Reset(); - unstructuredPosition.Reset(); - - attributeTail = 0; - currentAttribute = -1; - - - attrNamePosition.Reset(); - attrValuePosition.Reset(); - } - - - - public struct AttributeEnumerator - { - private HtmlToken token; -#if DEBUG - private int index; -#endif - - - internal AttributeEnumerator(HtmlToken token) - { - this.token = token; -#if DEBUG - index = this.token.currentAttribute; -#endif - } - - - - public int Count => token.attributeTail; - - public HtmlAttribute Current - { - get - { - InternalDebug.Assert(token.currentAttribute >= 0 && token.currentAttribute < token.attributeTail); - AssertCurrent(); - - return new HtmlAttribute(token); - } - } - - public int CurrentIndex => token.currentAttribute; - - public HtmlAttribute this[int i] - { - get - { - InternalDebug.Assert(i >= 0 && i < token.attributeTail); - - if (i != token.currentAttribute) - { - token.attrNamePosition.Rewind(token.attributeList[i].name); - token.attrValuePosition.Rewind(token.attributeList[i].value); - } - - token.currentAttribute = i; - - return new HtmlAttribute(token); - } - } - - - - public bool MoveNext() - { - InternalDebug.Assert(token.currentAttribute >= -1 && token.currentAttribute <= token.attributeTail); - AssertCurrent(); - - if (token.currentAttribute != token.attributeTail) - { - token.currentAttribute ++; - - if (token.currentAttribute != token.attributeTail) - { - token.attrNamePosition.Rewind(token.attributeList[token.currentAttribute].name); - token.attrValuePosition.Rewind(token.attributeList[token.currentAttribute].value); - } -#if DEBUG - index = token.currentAttribute; -#endif - } - - return (token.currentAttribute != token.attributeTail); - } - - public void Rewind() - { - AssertCurrent(); - - token.currentAttribute = -1; -#if DEBUG - index = token.currentAttribute; -#endif - } - - public AttributeEnumerator GetEnumerator() - { - return this; - } - - public bool Find(HtmlNameIndex nameIndex) - { - for (var i = 0; i < token.attributeTail; i++) - { - if (token.attributeList[i].nameIndex == nameIndex) - { - token.currentAttribute = i; - - token.attrNamePosition.Rewind(token.attributeList[i].name); - token.attrValuePosition.Rewind(token.attributeList[i].value); - - return true; - } - } - - return false; - } - - - - [System.Diagnostics.Conditional("DEBUG")] - private void AssertCurrent() - { -#if DEBUG - InternalDebug.Assert(token.currentAttribute == index); -#endif - } - } - - - - public struct TagUnstructuredContentTextReader - { - private HtmlToken token; -#if DEBUG - private FragmentPosition position; -#endif - - - internal TagUnstructuredContentTextReader(HtmlToken token) - { - InternalDebug.Assert(token.TokenId == HtmlTokenId.Tag); - - this.token = token; -#if DEBUG - position = this.token.unstructuredPosition; -#endif - } -#if false - public int Length - { - get { return this.token.GetLength(this.token.unstructured); } - } - - - - public int Read(char[] buffer, int offset, int count) - { - this.AssertCurrent(); - - int countRead = this.token.Read(this.token.unstructured, ref this.token.unstructuredPosition, buffer, offset, count); -#if DEBUG - this.position = this.token.unstructuredPosition; -#endif - return countRead; - } - - public void Rewind() - { - this.token.unstructuredPosition.Rewind(this.token.unstructured); - } -#endif - public void WriteTo(ITextSink sink) - { - token.WriteTo(token.unstructured, sink); - } - - public string GetString(int maxSize) - { - return token.GetString(token.unstructured, maxSize); - } - - - - [System.Diagnostics.Conditional("DEBUG")] - private void AssertCurrent() - { -#if DEBUG - InternalDebug.Assert(position.SameAs(token.unstructuredPosition)); -#endif - } - } - - - - public struct TagNameTextReader - { - private HtmlToken token; -#if DEBUG - private FragmentPosition position; -#endif - - - internal TagNameTextReader(HtmlToken token) - { - InternalDebug.Assert(token.TokenId == HtmlTokenId.Tag); - - this.token = token; -#if DEBUG - position = this.token.namePosition; -#endif - } - - public int Length => token.GetLength(token.name); - - - public int Read(char[] buffer, int offset, int count) - { - AssertCurrent(); - - var countRead = token.Read(token.name, ref token.namePosition, buffer, offset, count); -#if DEBUG - position = token.namePosition; -#endif - return countRead; - } - - public void Rewind() - { - token.namePosition.Rewind(token.name); - } - - public void WriteTo(ITextSink sink) - { - token.WriteTo(token.name, sink); - } - - public string GetString(int maxSize) - { - return token.GetString(token.name, maxSize); - } - - public void MakeEmpty() - { - token.name.Reset(); - Rewind(); - } - - - - [System.Diagnostics.Conditional("DEBUG")] - private void AssertCurrent() - { -#if DEBUG - InternalDebug.Assert(position.SameAs(token.namePosition)); -#endif - } - } - - - - public struct AttributeNameTextReader - { - private HtmlToken token; -#if DEBUG - private FragmentPosition position; -#endif - - - internal AttributeNameTextReader(HtmlToken token) - { - InternalDebug.Assert(token.TokenId == HtmlTokenId.Tag); - - this.token = token; -#if DEBUG - position = this.token.attrNamePosition; -#endif - } - - public int Length => token.GetLength(token.attributeList[token.currentAttribute].name); - - - public int Read(char[] buffer, int offset, int count) - { - AssertCurrent(); - - var countRead = token.Read(token.attributeList[token.currentAttribute].name, ref token.attrNamePosition, buffer, offset, count); -#if DEBUG - position = token.attrNamePosition; -#endif - return countRead; - } - - public void Rewind() - { - token.attrNamePosition.Rewind(token.attributeList[token.currentAttribute].name); - } - - public void WriteTo(ITextSink sink) - { - token.WriteTo(token.attributeList[token.currentAttribute].name, sink); - } - - public string GetString(int maxSize) - { - return token.GetString(token.attributeList[token.currentAttribute].name, maxSize); - } - - public void MakeEmpty() - { - token.attributeList[token.currentAttribute].name.Reset(); - token.attrNamePosition.Rewind(token.attributeList[token.currentAttribute].name); - } - - - - [System.Diagnostics.Conditional("DEBUG")] - private void AssertCurrent() - { -#if DEBUG - InternalDebug.Assert(position.SameAs(token.attrNamePosition)); -#endif - } - } - - - - public struct AttributeValueTextReader - { - private HtmlToken token; -#if DEBUG - private FragmentPosition position; -#endif - - - internal AttributeValueTextReader(HtmlToken token) - { - InternalDebug.Assert(token.TokenId == HtmlTokenId.Tag); - - this.token = token; -#if DEBUG - position = this.token.attrValuePosition; -#endif - } - - public int Length => token.GetLength(token.attributeList[token.currentAttribute].value); - - public bool IsEmpty => token.IsFragmentEmpty(token.attributeList[token.currentAttribute].value); - - public bool IsContiguous => token.IsContiguous(token.attributeList[token.currentAttribute].value); - - public BufferString ContiguousBufferString - { - get - { - InternalDebug.Assert(!IsEmpty && IsContiguous); - return new BufferString( - token.buffer, - token.attributeList[token.currentAttribute].value.headOffset, - token.runList[token.attributeList[token.currentAttribute].value.head].Length); - } - } - - - - public int Read(char[] buffer, int offset, int count) - { - AssertCurrent(); - - var countRead = token.Read(token.attributeList[token.currentAttribute].value, ref token.attrValuePosition, buffer, offset, count); -#if DEBUG - position = token.attrValuePosition; -#endif - return countRead; - } - - public void Rewind() - { - token.attrValuePosition.Rewind(token.attributeList[token.currentAttribute].value); - } - - public void WriteTo(ITextSink sink) - { - token.WriteTo(token.attributeList[token.currentAttribute].value, sink); - } - - public string GetString(int maxSize) - { - return token.GetString(token.attributeList[token.currentAttribute].value, maxSize); - } - - - - public bool CaseInsensitiveCompareEqual(string str) - { - return token.CaseInsensitiveCompareEqual(token.attributeList[token.currentAttribute].value, str); - } - - public bool CaseInsensitiveContainsSubstring(string str) - { - return token.CaseInsensitiveContainsSubstring(token.attributeList[token.currentAttribute].value, str); - } - - - public bool SkipLeadingWhitespace() - { - return token.SkipLeadingWhitespace(token.attributeList[token.currentAttribute].value, ref token.attrValuePosition); - } - - public void MakeEmpty() - { - token.attributeList[token.currentAttribute].value.Reset(); - Rewind(); - } - - - - [System.Diagnostics.Conditional("DEBUG")] - private void AssertCurrent() - { -#if DEBUG - InternalDebug.Assert(position.SameAs(token.attrValuePosition)); -#endif - } - } - - - - protected internal struct AttributeEntry - { - public HtmlNameIndex nameIndex; - public byte quoteChar; - public AttrPartMajor partMajor; - public AttrPartMinor partMinor; - - public LexicalUnit name; - public LexicalUnit localName; - public LexicalUnit value; - - - - public bool IsCompleteAttr => MajorPart == AttrPartMajor.Complete; - - public bool IsAttrBegin => (partMajor & AttrPartMajor.Begin) == AttrPartMajor.Begin; - - public bool IsAttrEnd => (partMajor & AttrPartMajor.End) == AttrPartMajor.End; - - public bool IsAttrEmptyName => (partMajor & AttrPartMajor.EmptyName) == AttrPartMajor.EmptyName; - - public bool IsAttrNameEnd => (partMinor & AttrPartMinor.EndName) == AttrPartMinor.EndName; - - public bool IsAttrValueBegin => (partMinor & AttrPartMinor.BeginValue) == AttrPartMinor.BeginValue; - - public AttrPartMajor MajorPart => partMajor & AttrPartMajor.MaskOffFlags; - - public AttrPartMinor MinorPart - { - get { return partMinor; } - set { partMinor = value; } - } - - public bool IsAttrValueQuoted - { - get { return (partMajor & AttrPartMajor.ValueQuoted) == AttrPartMajor.ValueQuoted; } - set { partMajor = value ? (partMajor | AttrPartMajor.ValueQuoted) : (partMajor & ~AttrPartMajor.ValueQuoted); } - } - - public bool IsAttrDeleted - { - get { return (partMajor & AttrPartMajor.Deleted) == AttrPartMajor.Deleted; } - set { partMajor = value ? (partMajor | AttrPartMajor.Deleted) : (partMajor & ~AttrPartMajor.Deleted); } - } - } - } - - - - internal struct HtmlAttribute - { - private HtmlToken token; -#if DEBUG - private int index; -#endif - - - internal HtmlAttribute(HtmlToken token) - { - this.token = token; -#if DEBUG - index = this.token.currentAttribute; -#endif - } - - public bool IsNull => token == null; - - - public int Index - { - get { AssertCurrent(); return token.currentAttribute; } - } - - public HtmlToken.AttrPartMajor MajorPart - { - get { AssertCurrent(); return token.attributeList[token.currentAttribute].MajorPart; } - } - - public HtmlToken.AttrPartMinor MinorPart - { - get { AssertCurrent(); return token.attributeList[token.currentAttribute].MinorPart; } - } - - public bool IsCompleteAttr - { - get { AssertCurrent(); return token.attributeList[token.currentAttribute].IsCompleteAttr; } - } - - public bool IsAttrBegin - { - get { AssertCurrent(); return token.attributeList[token.currentAttribute].IsAttrBegin; } - } - - public bool IsAttrEmptyName - { - get { AssertCurrent(); return token.attributeList[token.currentAttribute].IsAttrEmptyName; } - } - - public bool IsAttrEnd - { - get { AssertCurrent(); return token.attributeList[token.currentAttribute].IsAttrEnd; } - } - - public bool IsAttrNameEnd - { - get { AssertCurrent(); return token.attributeList[token.currentAttribute].IsAttrNameEnd; } - } - - public bool IsDeleted - { - get { AssertCurrent(); return token.attributeList[token.currentAttribute].IsAttrDeleted; } - } - - public bool IsAttrValueBegin - { - get { AssertCurrent(); return token.attributeList[token.currentAttribute].IsAttrValueBegin; } - } - - public bool IsAttrValueQuoted - { - get { AssertCurrent(); return token.attributeList[token.currentAttribute].IsAttrValueQuoted; } - } - - public HtmlNameIndex NameIndex - { - get { AssertCurrent(); return token.attributeList[token.currentAttribute].nameIndex; } - } - - public char QuoteChar - { - get { AssertCurrent(); return (char) token.attributeList[token.currentAttribute].quoteChar; } - } - - public bool HasNameFragment - { - get { AssertCurrent(); return !token.IsFragmentEmpty(token.attributeList[token.currentAttribute].name); } - } - - public HtmlToken.AttributeNameTextReader Name - { - get { AssertCurrent(); return new HtmlToken.AttributeNameTextReader(token); } - } - - public bool HasValueFragment - { - get { AssertCurrent(); return !token.IsFragmentEmpty(token.attributeList[token.currentAttribute].value); } - } - - public HtmlToken.AttributeValueTextReader Value - { - get { AssertCurrent(); return new HtmlToken.AttributeValueTextReader(token); } - } - - public void SetMinorPart(HtmlToken.AttrPartMinor newMinorPart) - { - AssertCurrent(); - token.attributeList[token.currentAttribute].MinorPart = newMinorPart; - } - - - - [System.Diagnostics.Conditional("DEBUG")] - private void AssertCurrent() - { - - -#if DEBUG - InternalDebug.Assert(token.currentAttribute == index); -#endif - } - } -} - diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlTokenBuilder.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlTokenBuilder.cs deleted file mode 100644 index 79a6274e6..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlTokenBuilder.cs +++ /dev/null @@ -1,993 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters.Internal.Html -{ - using System; - using Data.Internal; - - - - internal class HtmlTokenBuilder : TokenBuilder - { - - - - protected const byte BuildStateEndedHtml = BuildStateEnded + 1; - protected const byte BuildStateTagStarted = 20; - protected const byte BuildStateTagText = 21; - protected const byte BuildStateTagName = 22; - protected const byte BuildStateTagBeforeAttr = 23; - - protected const byte BuildStateTagAttrName = 24; - protected const byte BuildStateTagEndAttrName = 25; - protected const byte BuildStateTagAttrValue = 26; - protected const byte BuildStateTagEndAttrValue = 27; - - protected HtmlToken htmlToken; - - protected int maxAttrs; - - protected int numCarryOverRuns; - protected int carryOverRunsHeadOffset; - protected int carryOverRunsLength; - - - - public HtmlTokenBuilder( - char[] buffer, - int maxRuns, - int maxAttrs, - bool testBoundaryConditions) : - base(new HtmlToken(), buffer, maxRuns, testBoundaryConditions) - { - htmlToken = (HtmlToken) base.Token; - - var initialAttrs = 8; - - if (maxAttrs != 0) - { - if (!testBoundaryConditions) - { - this.maxAttrs = maxAttrs; - } - else - { - initialAttrs = 1; - this.maxAttrs = 5; - } - - - - htmlToken.attributeList = new HtmlToken.AttributeEntry[initialAttrs]; - } - - htmlToken.nameIndex = HtmlNameIndex._NOTANAME; - } - - - - public new HtmlToken Token => htmlToken; - - - public bool IncompleteTag => state >= FirstStarted && state != BuildStateText; - - - public override void Reset() - { - if (state >= BuildStateEndedHtml) - { - htmlToken.Reset(); - - numCarryOverRuns = 0; - } - - base.Reset(); - } - - - - public HtmlTokenId MakeEmptyToken(HtmlTokenId tokenId) - { - return (HtmlTokenId)base.MakeEmptyToken((TokenId)tokenId); - } - - - - public HtmlTokenId MakeEmptyToken(HtmlTokenId tokenId, int argument) - { - return (HtmlTokenId)base.MakeEmptyToken((TokenId)tokenId, argument); - } - - - - public void StartTag(HtmlNameIndex nameIndex, int baseOffset) - { - InternalDebug.Assert(state == BuildStateInitialized && htmlToken.IsEmpty); - - state = BuildStateTagStarted; - - htmlToken.tokenId = (TokenId)HtmlTokenId.Tag; - htmlToken.partMajor = HtmlToken.TagPartMajor.Begin; - htmlToken.partMinor = HtmlToken.TagPartMinor.Empty; - htmlToken.nameIndex = nameIndex; - htmlToken.tagIndex = HtmlNameData.names[(int)nameIndex].tagIndex; - - htmlToken.whole.headOffset = baseOffset; - tailOffset = baseOffset; - } - - - - public void AbortConditional(bool comment) - { - InternalDebug.Assert(htmlToken.nameIndex == HtmlNameIndex._CONDITIONAL); - InternalDebug.Assert(state == BuildStateTagStarted || state == BuildStateTagText); - - - - - - - - - htmlToken.nameIndex = comment ? HtmlNameIndex._COMMENT : HtmlNameIndex._BANG; - } - - - - public void SetEndTag() - { - htmlToken.flags |= HtmlToken.TagFlags.EndTag; - } - - - - public void SetEmptyScope() - { - htmlToken.flags |= HtmlToken.TagFlags.EmptyScope; - } - - - - public void StartTagText() - { - InternalDebug.Assert(state == BuildStateTagStarted); - - state = BuildStateTagText; - - htmlToken.unstructured.Initialize(htmlToken.whole.tail, tailOffset); - htmlToken.unstructuredPosition.Rewind(htmlToken.unstructured); - } - - - - public void EndTagText() - { - if (htmlToken.unstructured.head == htmlToken.whole.tail) - { - InternalDebug.Assert(htmlToken.unstructured.headOffset == tailOffset); - - AddNullRun(HtmlRunKind.TagText); - } - - state = BuildStateTagStarted; - } - - - - public void StartTagName() - { - InternalDebug.Assert(state == BuildStateTagStarted); - - state = BuildStateTagName; - - htmlToken.partMinor |= HtmlToken.TagPartMinor.BeginName; - - htmlToken.name.Initialize(htmlToken.whole.tail, tailOffset); - htmlToken.localName.Initialize(htmlToken.whole.tail, tailOffset); - htmlToken.namePosition.Rewind(htmlToken.name); - } - - public void EndTagNamePrefix() - { - InternalDebug.Assert(state == BuildStateTagName); - - htmlToken.localName.Initialize(htmlToken.whole.tail, tailOffset); - } - - - - public void EndTagName(int nameLength) - { - InternalDebug.Assert(state == BuildStateTagName); - - InternalDebug.Assert(htmlToken.partMinor == HtmlToken.TagPartMinor.BeginName || - htmlToken.partMinor == HtmlToken.TagPartMinor.ContinueName); - - if (htmlToken.localName.head == htmlToken.whole.tail) - { - InternalDebug.Assert(htmlToken.localName.headOffset == tailOffset); - - AddNullRun(HtmlRunKind.Name); - if (htmlToken.localName.head == htmlToken.name.head) - { - htmlToken.flags |= HtmlToken.TagFlags.EmptyTagName; - } - } - - htmlToken.partMinor |= HtmlToken.TagPartMinor.EndName; - - if (htmlToken.IsTagBegin) - { - AddSentinelRun(); - htmlToken.nameIndex = LookupName(nameLength, htmlToken.name); - htmlToken.tagIndex = htmlToken.originalTagIndex = HtmlNameData.names[(int)htmlToken.nameIndex].tagIndex; - } - - state = BuildStateTagBeforeAttr; - } - - - - public void EndTagName(HtmlNameIndex resolvedNameIndex) - { - InternalDebug.Assert(state == BuildStateTagName); - - InternalDebug.Assert(htmlToken.partMinor == HtmlToken.TagPartMinor.BeginName || - htmlToken.partMinor == HtmlToken.TagPartMinor.ContinueName); - - if (htmlToken.localName.head == htmlToken.whole.tail) - { - InternalDebug.Assert(htmlToken.localName.headOffset == tailOffset); - - AddNullRun(HtmlRunKind.Name); - if (htmlToken.localName.head == htmlToken.name.head) - { - htmlToken.flags |= HtmlToken.TagFlags.EmptyTagName; - } - } - - htmlToken.partMinor |= HtmlToken.TagPartMinor.EndName; - - if (htmlToken.IsTagBegin) - { - htmlToken.nameIndex = resolvedNameIndex; - htmlToken.tagIndex = htmlToken.originalTagIndex = HtmlNameData.names[(int)resolvedNameIndex].tagIndex; - } - - state = BuildStateTagBeforeAttr; - } - - - - public bool CanAddAttribute() - { - InternalDebug.Assert(state == BuildStateTagBeforeAttr); - - return htmlToken.attributeTail < maxAttrs; - } - - - - public void StartAttribute() - { - if (htmlToken.attributeTail == htmlToken.attributeList.Length) - { - - - - InternalDebug.Assert(htmlToken.attributeList.Length < maxAttrs); - - int newSize; - - if (maxAttrs / 2 > htmlToken.attributeList.Length) - { - newSize = htmlToken.attributeList.Length * 2; - } - else - { - newSize = maxAttrs; - } - - var newAttrs = new HtmlToken.AttributeEntry[newSize]; - - Array.Copy(htmlToken.attributeList, 0, newAttrs, 0, htmlToken.attributeTail); - - htmlToken.attributeList = newAttrs; - } - - InternalDebug.Assert(htmlToken.attributeTail < htmlToken.attributeList.Length); - InternalDebug.Assert(state == BuildStateTagBeforeAttr); - - InternalDebug.Assert(htmlToken.partMinor == HtmlToken.TagPartMinor.Empty || - htmlToken.partMinor == HtmlToken.TagPartMinor.EndName || - htmlToken.partMinor == HtmlToken.TagPartMinor.EndNameWithAttributes || - htmlToken.partMinor == HtmlToken.TagPartMinor.CompleteName || - htmlToken.partMinor == HtmlToken.TagPartMinor.CompleteNameWithAttributes || - htmlToken.partMinor == HtmlToken.TagPartMinor.EndAttribute || - htmlToken.partMinor == HtmlToken.TagPartMinor.EndAttributeWithOtherAttributes || - htmlToken.partMinor == HtmlToken.TagPartMinor.Attributes); - - if (htmlToken.partMinor == HtmlToken.TagPartMinor.Empty) - { - htmlToken.partMinor = HtmlToken.TagPartMinor.BeginAttribute; - } - - htmlToken.attributeList[htmlToken.attributeTail].nameIndex = HtmlNameIndex.Unknown; - htmlToken.attributeList[htmlToken.attributeTail].partMajor = HtmlToken.AttrPartMajor.Begin; - htmlToken.attributeList[htmlToken.attributeTail].partMinor = HtmlToken.AttrPartMinor.BeginName; - htmlToken.attributeList[htmlToken.attributeTail].quoteChar = 0; - htmlToken.attributeList[htmlToken.attributeTail].name.Initialize(htmlToken.whole.tail, tailOffset); - htmlToken.attributeList[htmlToken.attributeTail].localName.Initialize(htmlToken.whole.tail, tailOffset); - htmlToken.attributeList[htmlToken.attributeTail].value.Reset(); - - state = BuildStateTagAttrName; - } - - public void EndAttributeNamePrefix() - { - InternalDebug.Assert(state == BuildStateTagAttrName); - - htmlToken.attributeList[htmlToken.attributeTail].localName.Initialize(htmlToken.whole.tail, tailOffset); - } - - - - public void EndAttributeName(int nameLength) - { - InternalDebug.Assert(state == BuildStateTagAttrName); - - htmlToken.attributeList[htmlToken.attributeTail].partMinor |= HtmlToken.AttrPartMinor.EndName; - - if (htmlToken.attributeList[htmlToken.attributeTail].localName.head == htmlToken.whole.tail) - { - InternalDebug.Assert(htmlToken.attributeList[htmlToken.attributeTail].localName.headOffset == tailOffset); - - AddNullRun(HtmlRunKind.Name); - if (htmlToken.attributeList[htmlToken.attributeTail].localName.head == htmlToken.attributeList[htmlToken.attributeTail].name.head) - { - htmlToken.attributeList[htmlToken.attributeTail].partMajor |= HtmlToken.AttrPartMajor.EmptyName; - } - } - - if (htmlToken.attributeList[htmlToken.attributeTail].IsAttrBegin) - { - AddSentinelRun(); - htmlToken.attributeList[htmlToken.attributeTail].nameIndex = LookupName(nameLength, htmlToken.attributeList[htmlToken.attributeTail].name); - } - - state = BuildStateTagEndAttrName; - } - - - - public void StartValue() - { - InternalDebug.Assert(state == BuildStateTagEndAttrName); - - htmlToken.attributeList[htmlToken.attributeTail].value.Initialize(htmlToken.whole.tail, tailOffset); - - htmlToken.attributeList[htmlToken.attributeTail].partMinor |= HtmlToken.AttrPartMinor.BeginValue; - - state = BuildStateTagAttrValue; - } - - - - public void SetValueQuote(char ch) - { - InternalDebug.Assert(state == BuildStateTagAttrValue); - InternalDebug.Assert(ParseSupport.QuoteCharacter(ParseSupport.GetCharClass(ch))); - - htmlToken.attributeList[htmlToken.attributeTail].IsAttrValueQuoted = true; - htmlToken.attributeList[htmlToken.attributeTail].quoteChar = (byte) ch; - } - - - - public void EndValue() - { - InternalDebug.Assert(state == BuildStateTagAttrValue); - - if (htmlToken.attributeList[htmlToken.attributeTail].value.head == htmlToken.whole.tail) - { - InternalDebug.Assert(htmlToken.attributeList[htmlToken.attributeTail].value.headOffset == tailOffset); - - AddNullRun(HtmlRunKind.AttrValue); - } - - htmlToken.attributeList[htmlToken.attributeTail].partMinor |= HtmlToken.AttrPartMinor.EndValue; - - state = BuildStateTagEndAttrValue; - } - - - - public void EndAttribute() - { - InternalDebug.Assert(state == BuildStateTagEndAttrName || state == BuildStateTagEndAttrValue); - - htmlToken.attributeList[htmlToken.attributeTail].partMajor |= HtmlToken.AttrPartMajor.End; - - htmlToken.attributeTail ++; - - if (htmlToken.attributeTail < htmlToken.attributeList.Length) - { - - - htmlToken.attributeList[htmlToken.attributeTail].partMajor = HtmlToken.AttrPartMajor.None; - htmlToken.attributeList[htmlToken.attributeTail].partMinor = HtmlToken.AttrPartMinor.Empty; - } - - if (htmlToken.partMinor == HtmlToken.TagPartMinor.BeginAttribute) - { - htmlToken.partMinor = HtmlToken.TagPartMinor.Attributes; - } - else if (htmlToken.partMinor == HtmlToken.TagPartMinor.ContinueAttribute) - { - htmlToken.partMinor = HtmlToken.TagPartMinor.EndAttribute; - } - else - { - InternalDebug.Assert(htmlToken.partMinor == HtmlToken.TagPartMinor.CompleteName || - htmlToken.partMinor == HtmlToken.TagPartMinor.CompleteNameWithAttributes || - htmlToken.partMinor == HtmlToken.TagPartMinor.EndName || - htmlToken.partMinor == HtmlToken.TagPartMinor.EndNameWithAttributes || - htmlToken.partMinor == HtmlToken.TagPartMinor.EndAttribute || - htmlToken.partMinor == HtmlToken.TagPartMinor.EndAttributeWithOtherAttributes || - htmlToken.partMinor == HtmlToken.TagPartMinor.Attributes); - - htmlToken.partMinor |= HtmlToken.TagPartMinor.Attributes; - } - - state = BuildStateTagBeforeAttr; - } - - - - public void EndTag(bool complete) - { - if (complete) - { - - - if (state != BuildStateTagBeforeAttr) - { - if (state == BuildStateTagText) - { - EndTagText(); - } - else if (state == BuildStateTagName) - { - EndTagName(0); - } - else - { - if (state == BuildStateTagAttrName) - { - EndAttributeName(0); - } - else if (state == BuildStateTagAttrValue) - { - EndValue(); - } - - if (state == BuildStateTagEndAttrName || state == BuildStateTagEndAttrValue) - { - EndAttribute(); - } - } - } - - - AddSentinelRun(); - - InternalDebug.Assert(state == BuildStateTagBeforeAttr || state == BuildStateTagStarted); - - state = BuildStateEndedHtml; - htmlToken.partMajor |= HtmlToken.TagPartMajor.End; - } - else - { - if (state >= BuildStateTagAttrName) - { - - - - InternalDebug.Assert(!complete); - - if (0 != htmlToken.attributeTail || - htmlToken.name.head != -1 || - htmlToken.attributeList[htmlToken.attributeTail].name.head > 0) - { - - - - InternalDebug.Assert(htmlToken.attributeList[htmlToken.attributeTail].IsAttrBegin); - - - AddSentinelRun(); - - - - - numCarryOverRuns = htmlToken.whole.tail - htmlToken.attributeList[htmlToken.attributeTail].name.head; - carryOverRunsHeadOffset = htmlToken.attributeList[htmlToken.attributeTail].name.headOffset; - carryOverRunsLength = tailOffset - carryOverRunsHeadOffset; - - htmlToken.whole.tail -= numCarryOverRuns; - - InternalDebug.Assert(numCarryOverRuns != 0); - - - } - - else - { - - - - if (state == BuildStateTagAttrName) - { - if (htmlToken.attributeList[htmlToken.attributeTail].name.head == htmlToken.whole.tail) - { - AddNullRun(HtmlRunKind.Name); - } - } - else if (state == BuildStateTagAttrValue) - { - if (htmlToken.attributeList[htmlToken.attributeTail].value.head == htmlToken.whole.tail) - { - AddNullRun(HtmlRunKind.AttrValue); - } - } - - - AddSentinelRun(); - - htmlToken.attributeTail++; - } - } - else - { - if (state == BuildStateTagName) - { - if (htmlToken.name.head == htmlToken.whole.tail) - { - - AddNullRun(HtmlRunKind.Name); - } - } - else if (state == BuildStateTagText) - { - if (htmlToken.unstructured.head == htmlToken.whole.tail) - { - AddNullRun(HtmlRunKind.TagText); - } - } - - - AddSentinelRun(); - } - } - - tokenValid = true; - } - - - - public int RewindTag() - { - InternalDebug.Assert(IncompleteTag); - InternalDebug.Assert(htmlToken.whole.head == 0); - InternalDebug.Assert(numCarryOverRuns == 0 || carryOverRunsHeadOffset + carryOverRunsLength == tailOffset); - - - - - - - - - if (state >= BuildStateTagAttrName) - { - - - if (0 == htmlToken.attributeTail || - htmlToken.attributeList[htmlToken.attributeTail - 1].IsAttrEnd) - { - - - - - InternalDebug.Assert(numCarryOverRuns != 0); - - var deltaRuns = htmlToken.whole.tail; - - Array.Copy(htmlToken.runList, deltaRuns, htmlToken.runList, 0, numCarryOverRuns); - - htmlToken.whole.head = 0; - htmlToken.whole.headOffset = carryOverRunsHeadOffset; - htmlToken.whole.tail = numCarryOverRuns; - numCarryOverRuns = 0; - - htmlToken.attributeList[0] = htmlToken.attributeList[htmlToken.attributeTail]; - - htmlToken.partMinor = (HtmlToken.TagPartMinor)htmlToken.attributeList[0].MajorPart; - - InternalDebug.Assert(htmlToken.attributeList[0].IsAttrBegin); - - - - if (htmlToken.attributeList[0].name.head != -1) - { - htmlToken.attributeList[0].name.head -= deltaRuns; - } - - if (htmlToken.attributeList[0].localName.head != -1) - { - htmlToken.attributeList[0].localName.head -= deltaRuns; - } - - if (htmlToken.attributeList[0].value.head != -1) - { - htmlToken.attributeList[0].value.head -= deltaRuns; - } - } - else - { - - - InternalDebug.Assert(numCarryOverRuns == 0); - - htmlToken.whole.Initialize(0, tailOffset); - - htmlToken.attributeList[0].nameIndex = htmlToken.attributeList[htmlToken.attributeTail - 1].nameIndex; - - htmlToken.attributeList[0].partMajor = HtmlToken.AttrPartMajor.Continue; - - var oldMinor = htmlToken.attributeList[htmlToken.attributeTail - 1].partMinor; - - if (oldMinor == HtmlToken.AttrPartMinor.BeginName || oldMinor == HtmlToken.AttrPartMinor.ContinueName) - { - htmlToken.attributeList[0].partMinor = HtmlToken.AttrPartMinor.ContinueName; - } - else if (oldMinor == HtmlToken.AttrPartMinor.EndNameWithBeginValue || - oldMinor == HtmlToken.AttrPartMinor.CompleteNameWithBeginValue || - oldMinor == HtmlToken.AttrPartMinor.BeginValue || - oldMinor == HtmlToken.AttrPartMinor.ContinueValue) - { - htmlToken.attributeList[0].partMinor = HtmlToken.AttrPartMinor.ContinueValue; - } - else - { - InternalDebug.Assert(oldMinor == HtmlToken.AttrPartMinor.EndName || oldMinor == HtmlToken.AttrPartMinor.CompleteName || oldMinor == HtmlToken.AttrPartMinor.Empty); - - htmlToken.attributeList[0].partMinor = HtmlToken.AttrPartMinor.Empty; - } - - htmlToken.attributeList[0].IsAttrDeleted = false; - htmlToken.attributeList[0].IsAttrValueQuoted = htmlToken.attributeList[htmlToken.attributeTail - 1].IsAttrValueQuoted; - htmlToken.attributeList[0].quoteChar = htmlToken.attributeList[htmlToken.attributeTail - 1].quoteChar; - - if (state == BuildStateTagAttrName) - { - htmlToken.attributeList[0].name.Initialize(0, tailOffset); - htmlToken.attributeList[0].localName.Initialize(0, tailOffset); - } - else - { - htmlToken.attributeList[0].name.Reset(); - htmlToken.attributeList[0].localName.Reset(); - } - - if (state == BuildStateTagAttrValue) - { - htmlToken.attributeList[0].value.Initialize(0, tailOffset); - } - else - { - htmlToken.attributeList[0].value.Reset(); - } - - htmlToken.partMinor = (HtmlToken.TagPartMinor)htmlToken.attributeList[0].MajorPart; - } - - InternalDebug.Assert(!htmlToken.attributeList[0].IsAttrEnd); - } - else - { - InternalDebug.Assert(numCarryOverRuns == 0); - - htmlToken.whole.Initialize(0, tailOffset); - - if (htmlToken.partMinor == HtmlToken.TagPartMinor.BeginName || htmlToken.partMinor == HtmlToken.TagPartMinor.ContinueName) - { - htmlToken.partMinor = HtmlToken.TagPartMinor.ContinueName; - } - else - { - InternalDebug.Assert(htmlToken.partMinor == HtmlToken.TagPartMinor.CompleteName || - htmlToken.partMinor == HtmlToken.TagPartMinor.CompleteNameWithAttributes || - htmlToken.partMinor == HtmlToken.TagPartMinor.EndName || - htmlToken.partMinor == HtmlToken.TagPartMinor.EndNameWithAttributes || - htmlToken.partMinor == HtmlToken.TagPartMinor.EndAttribute || - htmlToken.partMinor == HtmlToken.TagPartMinor.EndAttributeWithOtherAttributes || - htmlToken.partMinor == HtmlToken.TagPartMinor.Attributes || - htmlToken.partMinor == HtmlToken.TagPartMinor.Empty); - - htmlToken.partMinor = HtmlToken.TagPartMinor.Empty; - } - - if (htmlToken.attributeList != null) - { - htmlToken.attributeList[0].partMajor = HtmlToken.AttrPartMajor.None; - htmlToken.attributeList[0].partMinor = HtmlToken.AttrPartMinor.Empty; - } - } - - if (state == BuildStateTagText) - { - htmlToken.unstructured.Initialize(0, tailOffset); - } - else - { - htmlToken.unstructured.Reset(); - } - - if (state == BuildStateTagName) - { - htmlToken.name.Initialize(0, tailOffset); - htmlToken.localName.Initialize(0, tailOffset); - } - else - { - htmlToken.name.Reset(); - htmlToken.localName.Reset(); - } - - htmlToken.attributeTail = 0; - htmlToken.currentAttribute = -1; - - htmlToken.partMajor = HtmlToken.TagPartMajor.Continue; - - tokenValid = false; - - return htmlToken.whole.headOffset; - } - - -#if false - public HtmlNameIndex LookupName(int nameLength, ref HtmlToken.Fragment fragment) - { - if (nameLength > HtmlData.MAX_NAME || nameHashValue < 0) - { - - return HtmlNameIndex.Unknown; - } - - - - int nameIndex = (int) HtmlData.nameHashTable[nameHashValue]; - - if (nameIndex > 0) - { - do - { - - - string name = HtmlData.names[nameIndex].name; - - if (name.Length == nameLength) - { - if (fragment.tail == fragment.head + 1) - { - if (name[0] == ParseSupport.ToLowerCase(this.token.buffer[fragment.headOffset])) - { - if (nameLength == 1 || this.token.CaseInsensitiveCompareRunEqual(fragment.headOffset + 1, name, 1)) - { - return (HtmlNameIndex)nameIndex; - } - } - } - else if (this.token.CaseInsensitiveCompareEqual(ref fragment, name)) - { - return (HtmlNameIndex)nameIndex; - } - } - - nameIndex ++; - - - - } - while (HtmlData.names[nameIndex].hash == nameHashValue); - } - - return HtmlNameIndex.Unknown; - } -#endif - public HtmlNameIndex LookupName(int nameLength, Token.LexicalUnit unit) - { - InternalDebug.Assert(nameLength >= 0); - - if (nameLength != 0 && nameLength <= HtmlNameData.MAX_NAME) - { - var nameHashValue = (short)(((uint)token.CalculateHashLowerCase(unit) ^ HtmlNameData.NAME_HASH_MODIFIER) % HtmlNameData.NAME_HASH_SIZE); - - - - var nameIndex = (int)HtmlNameData.nameHashTable[nameHashValue]; - - if (nameIndex > 0) - { - do - { - - - var name = HtmlNameData.names[nameIndex].name; - - if (name.Length == nameLength) - { - if (token.IsContiguous(unit)) - { - if (name[0] == ParseSupport.ToLowerCase(token.buffer[unit.headOffset])) - { - if (nameLength == 1 || token.CaseInsensitiveCompareRunEqual(unit.headOffset + 1, name, 1)) - { - return (HtmlNameIndex)nameIndex; - } - } - } - else if (token.CaseInsensitiveCompareEqual(unit, name)) - { - return (HtmlNameIndex)nameIndex; - } - } - - nameIndex ++; - - - - } - while (HtmlNameData.names[nameIndex].hash == nameHashValue); - } - } - - return HtmlNameIndex.Unknown; - } - - - - public static HtmlNameIndex LookupName(char[] nameBuffer, int nameOffset, int nameLength) - { - InternalDebug.Assert(nameLength >= 0); - - if (nameLength != 0 && nameLength <= HtmlNameData.MAX_NAME) - { - - - var nameHashValue = (short)(((uint)HashCode.CalculateLowerCase(nameBuffer, nameOffset, nameLength) ^ HtmlNameData.NAME_HASH_MODIFIER) % HtmlNameData.NAME_HASH_SIZE); - - var nameIndex = (int)HtmlNameData.nameHashTable[nameHashValue]; - - if (nameIndex > 0) - { - do - { - - - var name = HtmlNameData.names[nameIndex].name; - - if (name.Length == nameLength && - name[0] == ParseSupport.ToLowerCase(nameBuffer[nameOffset])) - { - var i = 0; - - while (++i < name.Length) - { - InternalDebug.Assert(!ParseSupport.IsUpperCase(name[i])); - - if (ParseSupport.ToLowerCase(nameBuffer[nameOffset + i]) != name[i]) - { - break; - } - } - - if (i == name.Length) - { - return (HtmlNameIndex)nameIndex; - } - } - - nameIndex ++; - - - - } - while (HtmlNameData.names[nameIndex].hash == nameHashValue); - } - } - - return HtmlNameIndex.Unknown; - } - - - - public bool PrepareToAddMoreRuns(int numRuns, int start, HtmlRunKind skippedRunKind) - { - return base.PrepareToAddMoreRuns(numRuns, start, (uint)skippedRunKind); - } - - - - public void AddInvalidRun(int end, HtmlRunKind kind) - { - base.AddInvalidRun(end, (uint)kind); - } - - public void AddNullRun(HtmlRunKind kind) - { - base.AddNullRun((uint)kind); - } - - - - public void AddRun(RunTextType textType, HtmlRunKind kind, int start, int end) - { - base.AddRun(RunType.Normal, textType, (uint)kind, start, end, 0); - } - - - - public void AddLiteralRun(RunTextType textType, HtmlRunKind kind, int start, int end, int literal) - { - base.AddRun(RunType.Literal, textType, (uint)kind, start, end, literal); - } - - - - protected override void Rebase(int deltaOffset) - { - - - - - htmlToken.unstructured.headOffset += deltaOffset; - htmlToken.unstructuredPosition.runOffset += deltaOffset; - - htmlToken.name.headOffset += deltaOffset; - htmlToken.localName.headOffset += deltaOffset; - htmlToken.namePosition.runOffset += deltaOffset; - - for (var i = 0; i < htmlToken.attributeTail; i++) - { - htmlToken.attributeList[i].name.headOffset += deltaOffset; - htmlToken.attributeList[i].localName.headOffset += deltaOffset; - htmlToken.attributeList[i].value.headOffset += deltaOffset; - } - - if (state >= BuildStateTagAttrName) - { - htmlToken.attributeList[htmlToken.attributeTail].name.headOffset += deltaOffset; - htmlToken.attributeList[htmlToken.attributeTail].localName.headOffset += deltaOffset; - htmlToken.attributeList[htmlToken.attributeTail].value.headOffset += deltaOffset; - } - - htmlToken.attrNamePosition.runOffset += deltaOffset; - htmlToken.attrValuePosition.runOffset += deltaOffset; - - carryOverRunsHeadOffset += deltaOffset; - - base.Rebase(deltaOffset); - } - } -} - diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlWriter.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlWriter.cs deleted file mode 100644 index bd381ec32..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HTML/HtmlWriter.cs +++ /dev/null @@ -1,2342 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters -{ - using System; - using System.IO; - using System.Text; - using Data.Internal; - using Internal.Html; - using Strings = CtsResources.TextConvertersStrings; - - - - - - - internal enum HtmlWriterState - { - - Default, - - Tag, - - Attribute, - } - - - - - - - internal class HtmlWriter : IRestartable, IFallback, IDisposable, ITextSinkEx - { - private ConverterOutput output; - private OutputState outputState; - - private bool filterHtml; - - private bool autoNewLines; - - private bool allowWspBeforeFollowingTag; - private bool lastWhitespace; - - private int lineLength; - private int longestLineLength; - private int textLineLength; - - private int literalWhitespaceNesting; - private bool literalTags; - private bool literalEntities; - private bool cssEscaping; - - private IFallback fallback; - - private HtmlNameIndex tagNameIndex; - private HtmlNameIndex previousTagNameIndex; - private bool isEndTag; - private bool isEmptyScopeTag; - - private bool copyPending; - - internal enum OutputState - { - OutsideTag, - TagStarted, - WritingUnstructuredTagContent, - WritingTagName, - BeforeAttribute, - WritingAttributeName, - AfterAttributeName, - WritingAttributeValue, - } - - - - - - - - public HtmlWriter(Stream output, Encoding outputEncoding) - { - if (output == null) - { - throw new ArgumentNullException("output"); - } - - if (outputEncoding == null) - { - throw new ArgumentNullException("outputEncoding"); - } - - this.output = new ConverterEncodingOutput( - output, - true, - false, - outputEncoding, - false, - false, - null); - autoNewLines = true; - } - - - - - - - public HtmlWriter(TextWriter output) - { - if (output == null) - { - throw new ArgumentNullException("output"); - } - - this.output = new ConverterUnicodeOutput( - output, - true, - false); - autoNewLines = true; - } - - - internal HtmlWriter(ConverterOutput output, bool filterHtml, bool autoNewLines) - { - this.output = output; - this.filterHtml = filterHtml; - this.autoNewLines = autoNewLines; - } - - - internal bool HasEncoding => output is ConverterEncodingOutput; - - - internal bool CodePageSameAsInput - { - get - { - InternalDebug.Assert(output is ConverterEncodingOutput); - return (output as ConverterEncodingOutput).CodePageSameAsInput; - } - } - - - internal Encoding Encoding - { - get - { - InternalDebug.Assert(output is ConverterEncodingOutput); - return (output as ConverterEncodingOutput).Encoding; - } - - set - { - InternalDebug.Assert(output is ConverterEncodingOutput); - (output as ConverterEncodingOutput).Encoding = value; - } - } - - - internal bool CanAcceptMore => output.CanAcceptMore; - - - internal bool IsTagOpen => outputState != OutputState.OutsideTag; - - - internal int LineLength => lineLength; - - - internal int LiteralWhitespaceNesting => literalWhitespaceNesting; - - - public HtmlWriterState WriterState => outputState == OutputState.OutsideTag ? HtmlWriterState.Default : - outputState < OutputState.WritingAttributeName ? HtmlWriterState.Tag : - HtmlWriterState.Attribute; - - - internal bool IsCopyPending => copyPending; - - - public void Flush() - { - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - - if (outputState != OutputState.OutsideTag) - { - WriteTagEnd(); - } - - output.Flush(); - } - - - internal void SetCopyPending(bool copyPending) - { - this.copyPending = copyPending; - } - - - - - - - public void WriteTag(HtmlReader reader) - { - if (reader == null) - { - throw new ArgumentNullException("reader"); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - if (reader.TagId != HtmlTagId.Unknown) - { - WriteTagBegin(HtmlNameData.tagIndex[(int)reader.TagId], null, reader.TokenKind == HtmlTokenKind.EndTag, false, false); - } - else - { - WriteTagBegin(HtmlNameIndex.Unknown, null, reader.TokenKind == HtmlTokenKind.EndTag, false, false); - reader.WriteTagNameTo(WriteTagName()); - } - - isEmptyScopeTag = (reader.TokenKind == HtmlTokenKind.EmptyElementTag); - - if (reader.TokenKind == HtmlTokenKind.StartTag || - reader.TokenKind == HtmlTokenKind.EmptyElementTag) - { - var attrReader = reader.AttributeReader; - - while (attrReader.ReadNext()) - { - if (attrReader.Id != HtmlAttributeId.Unknown) - { - OutputAttributeName(HtmlNameData.names[(int)HtmlNameData.attributeIndex[(int)attrReader.Id]].name); - } - else - { - attrReader.WriteNameTo(WriteAttributeName()); - } - - if (attrReader.HasValue) - { - attrReader.WriteValueTo(WriteAttributeValue()); - } - - OutputAttributeEnd(); - - outputState = OutputState.BeforeAttribute; - } - } - } - - - - - - - public void WriteStartTag(HtmlTagId id) - { - WriteTag(id, false); - } - - - - - - - public void WriteStartTag(string name) - { - WriteTag(name, false); - } - - - - - - - public void WriteEndTag(HtmlTagId id) - { - WriteTag(id, true); - WriteTagEnd(); - } - - - - - - - public void WriteEndTag(string name) - { - WriteTag(name, true); - WriteTagEnd(); - } - - - - - - - public void WriteEmptyElementTag(HtmlTagId id) - { - WriteTag(id, false); - isEmptyScopeTag = true; - } - - - - - - - public void WriteEmptyElementTag(string name) - { - WriteTag(name, false); - isEmptyScopeTag = true; - } - - - private void WriteTag(HtmlTagId id, bool isEndTag) - { - if ((int)id < 0 || (int)id >= HtmlNameData.tagIndex.Length) - { - throw new ArgumentException(Strings.TagIdInvalid, "id"); - } - - if (id == HtmlTagId.Unknown) - { - throw new ArgumentException(Strings.TagIdIsUnknown, "id"); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - WriteTagBegin(HtmlNameData.tagIndex[(int)id], null, isEndTag, false, false); - } - - - private void WriteTag(string name, bool isEndTag) - { - if (name == null) - { - throw new ArgumentNullException("name"); - } - - if (name.Length == 0) - { - throw new ArgumentException(Strings.TagNameIsEmpty, "name"); - } - - - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - var nameIndex = LookupName(name); - - if (nameIndex != HtmlNameIndex.Unknown) - { - - name = null; - } - - WriteTagBegin(nameIndex, name, isEndTag, false, false); - } - - - internal void WriteStartTag(HtmlNameIndex nameIndex) - { - WriteTagBegin(nameIndex, null, false, false, false); - } - - - internal void WriteEndTag(HtmlNameIndex nameIndex) - { - WriteTagBegin(nameIndex, null, true, false, false); - WriteTagEnd(); - } - - - internal void WriteEmptyElementTag(HtmlNameIndex nameIndex) - { - WriteTagBegin(nameIndex, null, true, false, false); - isEmptyScopeTag = true; - } - - - internal void WriteTagBegin(HtmlNameIndex nameIndex, string name, bool isEndTag, bool allowWspLeft, bool allowWspRight) - { - - if (outputState != OutputState.OutsideTag) - { - WriteTagEnd(); - } -#if !BETTER_FUZZING - - - - - - - - - if (literalTags && nameIndex >= HtmlNameIndex.Unknown && (!isEndTag || nameIndex != tagNameIndex)) - { - throw new InvalidOperationException(Strings.CannotWriteOtherTagsInsideElement(HtmlNameData.names[(int)tagNameIndex].name)); - } -#endif - var tagIndex = HtmlNameData.names[(int)nameIndex].tagIndex; - - if (nameIndex > HtmlNameIndex.Unknown) - { - - - isEmptyScopeTag = (HtmlDtd.tags[(int)tagIndex].scope == HtmlDtd.TagScope.EMPTY); - - if (isEndTag && isEmptyScopeTag) - { - - - - - if (HtmlDtd.tags[(int)tagIndex].unmatchedSubstitute != HtmlTagIndex._IMPLICIT_BEGIN) - { - - - output.Write(""); - lineLength += 3; - } - else if (tagNameIndex == HtmlNameIndex._ASP) - { - output.Write("%>"); - lineLength += 2; - } - else if (tagNameIndex == HtmlNameIndex._CONDITIONAL) - { - output.Write("]-->"); - lineLength += 4; - } - else if (tagNameIndex == HtmlNameIndex.Unknown && emptyScopeTag) - { - output.Write(" />"); - lineLength += 3; - } - else - { - output.Write('>'); - lineLength++; - } - - - - - tagNameIndex = previousTagNameIndex; - } - - if (isEndTag && - (tagIndex == HtmlTagIndex.LI || tagIndex == HtmlTagIndex.DD || tagIndex == HtmlTagIndex.DT)) - { - - - - - - lineLength = 0; - } - - if (autoNewLines && literalWhitespaceNesting == 0) - { - - - - - var tagFmt = HtmlDtd.tags[(int)tagIndex].fmt; - var tagFill = HtmlDtd.tags[(int)tagIndex].fill; - - if ((!isEndTag && tagFmt.RB == HtmlDtd.FmtCode.BRK) || - (isEndTag && tagFmt.RE == HtmlDtd.FmtCode.BRK) || - (lineLength > 80 && - (allowWspBeforeFollowingTag || - (!isEndTag && tagFill.RB == HtmlDtd.FillCode.EAT) || - (isEndTag && tagFill.RE == HtmlDtd.FillCode.EAT)))) - { - if (lineLength > longestLineLength) - { - longestLineLength = lineLength; - } - - output.Write("\r\n"); - lineLength = 0; - } - } - - if (!isEndTag && !emptyScopeTag) - { - - - var literal = HtmlDtd.tags[(int)tagIndex].literal; - - if (0 != (literal & HtmlDtd.Literal.Tags)) - { - literalTags = true; - literalEntities = (0 != (literal & HtmlDtd.Literal.Entities)); - cssEscaping = (tagIndex == HtmlTagIndex.Style); - } - - if (HtmlDtd.tags[(int)tagIndex].contextTextType == HtmlDtd.ContextTextType.Literal) - { - literalWhitespaceNesting++; - } - } - - outputState = OutputState.OutsideTag; - } - - - - - - - - public void WriteAttribute(HtmlAttributeId id, string value) - { - if ((int)id < 0 || (int)id >= HtmlNameData.attributeIndex.Length) - { - throw new ArgumentException(Strings.AttributeIdInvalid, "id"); - } - - if (id == HtmlAttributeId.Unknown) - { - throw new ArgumentException(Strings.AttributeIdIsUnknown, "id"); - } - - if (outputState < OutputState.WritingTagName) - { - throw new InvalidOperationException(Strings.TagNotStarted); - } - - if (isEndTag) - { - throw new InvalidOperationException(Strings.EndTagCannotHaveAttributes); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - - if (outputState > OutputState.BeforeAttribute) - { - OutputAttributeEnd(); - } - - OutputAttributeName(HtmlNameData.names[(int)HtmlNameData.attributeIndex[(int)id]].name); - - if (value != null) - { - OutputAttributeValue(value); - OutputAttributeEnd(); - } - - - outputState = OutputState.BeforeAttribute; - } - - - - - - - - public void WriteAttribute(string name, string value) - { - if (name == null) - { - throw new ArgumentNullException("name"); - } - - if (name.Length == 0) - { - throw new ArgumentException(Strings.AttributeNameIsEmpty, "name"); - } - - - - - if (outputState < OutputState.WritingTagName) - { - throw new InvalidOperationException(Strings.TagNotStarted); - } - - if (isEndTag) - { - throw new InvalidOperationException(Strings.EndTagCannotHaveAttributes); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - - if (outputState > OutputState.BeforeAttribute) - { - OutputAttributeEnd(); - } - - OutputAttributeName(name); - - if (value != null) - { - OutputAttributeValue(value); - OutputAttributeEnd(); - } - - - outputState = OutputState.BeforeAttribute; - } - - - - - - - - - public void WriteAttribute(HtmlAttributeId id, char[] buffer, int index, int count) - { - if ((int)id < 0 || (int)id >= HtmlNameData.attributeIndex.Length) - { - throw new ArgumentException(Strings.AttributeIdInvalid, "id"); - } - - if (id == HtmlAttributeId.Unknown) - { - throw new ArgumentException(Strings.AttributeIdIsUnknown, "id"); - } - - if (buffer == null) - { - throw new ArgumentNullException("buffer"); - } - - if (index < 0 || index > buffer.Length) - { - throw new ArgumentOutOfRangeException("index"); - } - - if (count < 0 || count > buffer.Length - index) - { - throw new ArgumentOutOfRangeException("count"); - } - - if (outputState < OutputState.WritingTagName) - { - throw new InvalidOperationException(Strings.TagNotStarted); - } - - if (isEndTag) - { - throw new InvalidOperationException(Strings.EndTagCannotHaveAttributes); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - - if (outputState > OutputState.BeforeAttribute) - { - OutputAttributeEnd(); - } - - OutputAttributeName(HtmlNameData.names[(int)HtmlNameData.attributeIndex[(int)id]].name); - - OutputAttributeValue(buffer, index, count); - - OutputAttributeEnd(); - - - outputState = OutputState.BeforeAttribute; - } - - - - - - - - - - public void WriteAttribute(string name, char[] buffer, int index, int count) - { - if (name == null) - { - throw new ArgumentNullException("name"); - } - - if (name.Length == 0) - { - throw new ArgumentException(Strings.AttributeNameIsEmpty, "name"); - } - - if (buffer == null) - { - throw new ArgumentNullException("buffer"); - } - - if (index < 0 || index > buffer.Length) - { - throw new ArgumentOutOfRangeException("index"); - } - - if (count < 0 || count > buffer.Length - index) - { - throw new ArgumentOutOfRangeException("count"); - } - - if (outputState < OutputState.WritingTagName) - { - throw new InvalidOperationException(Strings.TagNotStarted); - } - - if (isEndTag) - { - throw new InvalidOperationException(Strings.EndTagCannotHaveAttributes); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - - if (outputState > OutputState.BeforeAttribute) - { - OutputAttributeEnd(); - } - - OutputAttributeName(name); - - OutputAttributeValue(buffer, index, count); - - OutputAttributeEnd(); - - - outputState = OutputState.BeforeAttribute; - } - - - internal void WriteAttribute(HtmlNameIndex nameIndex, string value) - { - InternalDebug.Assert(nameIndex > HtmlNameIndex.Unknown && (int)nameIndex < HtmlNameData.names.Length); - InternalDebug.Assert(outputState >= OutputState.WritingTagName); - InternalDebug.Assert(!isEndTag); - - - if (outputState > OutputState.BeforeAttribute) - { - OutputAttributeEnd(); - } - - OutputAttributeName(HtmlNameData.names[(int)nameIndex].name); - - if (value != null) - { - OutputAttributeValue(value); - OutputAttributeEnd(); - } - - outputState = OutputState.BeforeAttribute; - } - - internal void WriteAttribute(HtmlNameIndex nameIndex, BufferString value) - { - InternalDebug.Assert(nameIndex > HtmlNameIndex.Unknown && (int)nameIndex < HtmlNameData.names.Length); - InternalDebug.Assert(outputState >= OutputState.WritingTagName); - InternalDebug.Assert(!isEndTag); - - - if (outputState > OutputState.BeforeAttribute) - { - OutputAttributeEnd(); - } - - OutputAttributeName(HtmlNameData.names[(int)nameIndex].name); - OutputAttributeValue(value.Buffer, value.Offset, value.Length); - OutputAttributeEnd(); - - outputState = OutputState.BeforeAttribute; - } - - - - - - - public void WriteAttribute(HtmlAttributeReader attributeReader) - { - if (outputState < OutputState.WritingTagName) - { - throw new InvalidOperationException(Strings.TagNotStarted); - } - - if (isEndTag) - { - throw new InvalidOperationException(Strings.EndTagCannotHaveAttributes); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - attributeReader.WriteNameTo(WriteAttributeName()); - if (attributeReader.HasValue) - { - attributeReader.WriteValueTo(WriteAttributeValue()); - } - OutputAttributeEnd(); - - outputState = OutputState.BeforeAttribute; - } - - - - - - - - public void WriteAttributeName(HtmlAttributeId id) - { - if ((int)id < 0 || (int)id >= HtmlNameData.attributeIndex.Length) - { - throw new ArgumentException(Strings.AttributeIdInvalid, "id"); - } - - if (id == HtmlAttributeId.Unknown) - { - throw new ArgumentException(Strings.AttributeIdIsUnknown, "id"); - } - - if (outputState < OutputState.WritingTagName) - { - throw new InvalidOperationException(Strings.TagNotStarted); - } - - if (isEndTag) - { - throw new InvalidOperationException(Strings.EndTagCannotHaveAttributes); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - - if (outputState > OutputState.BeforeAttribute) - { - OutputAttributeEnd(); - } - - OutputAttributeName(HtmlNameData.names[(int)HtmlNameData.attributeIndex[(int)id]].name); - } - - - - - - - - public void WriteAttributeName(string name) - { - if (name == null) - { - throw new ArgumentNullException("name"); - } - - if (name.Length == 0) - { - throw new ArgumentException(Strings.AttributeNameIsEmpty, "name"); - } - - if (outputState < OutputState.WritingTagName) - { - throw new InvalidOperationException(Strings.TagNotStarted); - } - - if (isEndTag) - { - throw new InvalidOperationException(Strings.EndTagCannotHaveAttributes); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - - if (outputState > OutputState.BeforeAttribute) - { - OutputAttributeEnd(); - } - - OutputAttributeName(name); - } - - - - internal void WriteAttributeName(HtmlNameIndex nameIndex) - { - InternalDebug.Assert(nameIndex > HtmlNameIndex.Unknown && (int)nameIndex < HtmlNameData.names.Length); - InternalDebug.Assert(outputState >= OutputState.WritingTagName); - InternalDebug.Assert(!isEndTag); - - - if (outputState > OutputState.BeforeAttribute) - { - OutputAttributeEnd(); - } - - OutputAttributeName(HtmlNameData.names[(int)nameIndex].name); - } - - - - - - - public void WriteAttributeName(HtmlAttributeReader attributeReader) - { - if (outputState < OutputState.WritingTagName) - { - throw new InvalidOperationException(Strings.TagNotStarted); - } - - if (isEndTag) - { - throw new InvalidOperationException(Strings.EndTagCannotHaveAttributes); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - attributeReader.WriteNameTo(WriteAttributeName()); - } - - - - - - - - - public void WriteAttributeValue(string value) - { - if (value == null) - { - throw new ArgumentNullException("value"); - } - - if (outputState < OutputState.TagStarted) - { - throw new InvalidOperationException(Strings.TagNotStarted); - } - - if (outputState < OutputState.WritingAttributeName) - { - throw new InvalidOperationException(Strings.AttributeNotStarted); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - OutputAttributeValue(value); - } - - internal void WriteAttributeValue(BufferString value) - { - InternalDebug.Assert(!copyPending && outputState >= OutputState.WritingAttributeName); - - OutputAttributeValue(value.Buffer, value.Offset, value.Length); - } - - - - - - - - - - - public void WriteAttributeValue(char[] buffer, int index, int count) - { - if (buffer == null) - { - throw new ArgumentNullException("buffer"); - } - - if (index < 0 || index > buffer.Length) - { - throw new ArgumentOutOfRangeException("index"); - } - - if (count < 0 || count > buffer.Length - index) - { - throw new ArgumentOutOfRangeException("count"); - } - - if (outputState < OutputState.TagStarted) - { - throw new InvalidOperationException(Strings.TagNotStarted); - } - - if (outputState < OutputState.WritingAttributeName) - { - throw new InvalidOperationException(Strings.AttributeNotStarted); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - OutputAttributeValue(buffer, index, count); - } - - - - - - - public void WriteAttributeValue(HtmlAttributeReader attributeReader) - { - if (outputState < OutputState.TagStarted) - { - throw new InvalidOperationException(Strings.TagNotStarted); - } - - if (outputState < OutputState.WritingAttributeName) - { - throw new InvalidOperationException(Strings.AttributeNotStarted); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - if (attributeReader.HasValue) - { - attributeReader.WriteValueTo(WriteAttributeValue()); - } - } - - - internal void WriteAttributeValueInternal(string value) - { - InternalDebug.Assert(value != null); - InternalDebug.Assert(outputState >= OutputState.WritingAttributeName); - - OutputAttributeValue(value); - } - - - internal void WriteAttributeValueInternal(char[] buffer, int index, int count) - { - InternalDebug.Assert(buffer != null && index >= 0 && index < buffer.Length && count >= 0 && count <= buffer.Length - index); - InternalDebug.Assert(outputState >= OutputState.WritingAttributeName); - - OutputAttributeValue(buffer, index, count); - } - - - - - - - public void WriteText(string value) - { - if (value == null) - { - throw new ArgumentNullException("value"); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - - if (outputState != OutputState.OutsideTag) - { - WriteTagEnd(); - } - - if (value.Length != 0) - { - if (lastWhitespace) - { - OutputLastWhitespace(value[0]); - } - - - - output.Write(value, this); - lineLength += value.Length; - textLineLength += value.Length; - - allowWspBeforeFollowingTag = false; - } - } - - - - - - - - - public void WriteText(char[] buffer, int index, int count) - { - if (buffer == null) - { - throw new ArgumentNullException("buffer"); - } - - if (index < 0 || index > buffer.Length) - { - throw new ArgumentOutOfRangeException("index"); - } - - if (count < 0 || count > buffer.Length - index) - { - throw new ArgumentOutOfRangeException("count"); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - - if (outputState != OutputState.OutsideTag) - { - WriteTagEnd(); - } - - - - WriteTextInternal(buffer, index, count); - } - - - internal void WriteText(char ch) - { - InternalDebug.Assert(!copyPending); - - - if (outputState != OutputState.OutsideTag) - { - WriteTagEnd(); - } - - if (lastWhitespace) - { - OutputLastWhitespace(ch); - } - - output.Write(ch, this); - lineLength++; - textLineLength++; - allowWspBeforeFollowingTag = false; - } - - - - - - - public void WriteText(HtmlReader reader) - { - if (reader == null) - { - throw new ArgumentNullException("reader"); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - reader.WriteTextTo(WriteText()); - } - - - - - - - - - - - - - - - public void WriteMarkupText(string value) - { - if (value == null) - { - throw new ArgumentNullException("value"); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - - if (outputState != OutputState.OutsideTag) - { - WriteTagEnd(); - } - - if (lastWhitespace) - { - OutputLastWhitespace(value[0]); - } - - - - output.Write(value, null); - lineLength += value.Length; - - allowWspBeforeFollowingTag = false; - } - - - - - - - - - - - - - - - - - public void WriteMarkupText(char[] buffer, int index, int count) - { - if (buffer == null) - { - throw new ArgumentNullException("buffer"); - } - - if (index < 0 || index > buffer.Length) - { - throw new ArgumentOutOfRangeException("index"); - } - - if (count < 0 || count > buffer.Length - index) - { - throw new ArgumentOutOfRangeException("count"); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - - if (outputState != OutputState.OutsideTag) - { - WriteTagEnd(); - } - - if (lastWhitespace) - { - OutputLastWhitespace(buffer[index]); - } - - - - output.Write(buffer, index, count, null); - lineLength += count; - - allowWspBeforeFollowingTag = false; - } - - - - internal void WriteMarkupText(char ch) - { - - if (outputState != OutputState.OutsideTag) - { - WriteTagEnd(); - } - - if (lastWhitespace) - { - OutputLastWhitespace(ch); - } - - output.Write(ch, null); - lineLength++; - - allowWspBeforeFollowingTag = false; - } - - - - - - - - public void WriteMarkupText(HtmlReader reader) - { - if (reader == null) - { - throw new ArgumentNullException("reader"); - } - - if (copyPending) - { - throw new InvalidOperationException(Strings.CannotWriteWhileCopyPending); - } - - reader.WriteMarkupTextTo(WriteMarkupText()); - } - - - internal ITextSinkEx WriteUnstructuredTagContent() - { - InternalDebug.Assert(outputState == OutputState.WritingUnstructuredTagContent); - - fallback = null; - return this; - } - - - internal ITextSinkEx WriteTagName() - { - InternalDebug.Assert(outputState == OutputState.TagStarted || - outputState == OutputState.WritingTagName); - - outputState = OutputState.WritingTagName; - - fallback = null; - return this; - } - - - internal ITextSinkEx WriteAttributeName() - { - InternalDebug.Assert(outputState >= OutputState.WritingTagName); - - if (outputState != OutputState.WritingAttributeName) - { - if (outputState > OutputState.BeforeAttribute) - { - OutputAttributeEnd(); - } - - - - -#if false - - - - if (this.lineLength > 255 && this.autoNewLines) - { - - - - if (this.lineLength > this.longestLineLength) - { - this.longestLineLength = this.lineLength; - } - - this.output.Write("\r\n"); - this.lineLength = 0; - } -#endif - output.Write(' '); - lineLength++; - } - - outputState = OutputState.WritingAttributeName; - - fallback = null; - return this; - } - - - internal ITextSinkEx WriteAttributeValue() - { - InternalDebug.Assert(outputState >= OutputState.WritingAttributeName); - - if (outputState != OutputState.WritingAttributeValue) - { - output.Write("=\""); - lineLength += 2; - } - - outputState = OutputState.WritingAttributeValue; - - fallback = this; - return this; - } - - - internal ITextSinkEx WriteText() - { - - if (outputState != OutputState.OutsideTag) - { - WriteTagEnd(); - } - - allowWspBeforeFollowingTag = false; - - if (lastWhitespace) - { - - InternalDebug.Assert(ParseSupport.FarEastNonHanguelChar('\x3000')); - OutputLastWhitespace('\x3000'); - } - - fallback = this; - return this; - } - - - internal ITextSinkEx WriteMarkupText() - { - - if (outputState != OutputState.OutsideTag) - { - WriteTagEnd(); - } - - if (lastWhitespace) - { - output.Write(' '); - lineLength++; - lastWhitespace = false; - } - - fallback = null; - return this; - } - - - internal void WriteNewLine() - { - WriteNewLine(false); - } - - - internal void WriteNewLine(bool optional) - { - - if (outputState != OutputState.OutsideTag) - { - WriteTagEnd(); - } - - if (!optional || (lineLength != 0 && literalWhitespaceNesting == 0)) - { - if (lineLength > longestLineLength) - { - longestLineLength = lineLength; - } - - output.Write("\r\n"); - lineLength = 0; - lastWhitespace = false; - allowWspBeforeFollowingTag = false; - } - } - - - internal void WriteAutoNewLine() - { - WriteNewLine(false); - } - - - internal void WriteAutoNewLine(bool optional) - { - - if (outputState != OutputState.OutsideTag) - { - WriteTagEnd(); - } - - if (autoNewLines && (!optional || (lineLength != 0 && literalWhitespaceNesting == 0))) - { - if (lineLength > longestLineLength) - { - longestLineLength = lineLength; - } - - output.Write("\r\n"); - lineLength = 0; - lastWhitespace = false; - allowWspBeforeFollowingTag = false; - } - } - - - internal void WriteTabulation(int count) - { - WriteSpace((textLineLength / 8 * 8 + 8 * count) - textLineLength); - } - - - internal void WriteSpace(int count) - { - InternalDebug.Assert(outputState == OutputState.OutsideTag); - - if (literalWhitespaceNesting == 0) - { - if (lineLength == 0 && count == 1) - { - - - output.Write('\xA0', this); - return; - } - - if (lastWhitespace) - { - lineLength++; - output.Write('\xA0', this); - } - - lineLength += count - 1; - textLineLength += count - 1; - - while (0 != --count) - { - output.Write('\xA0', this); - } - - lastWhitespace = true; - allowWspBeforeFollowingTag = false; - } - else - { - while (0 != count--) - { - output.Write(' '); - } - - lineLength += count; - textLineLength += count; - - lastWhitespace = false; - allowWspBeforeFollowingTag = false; - } - } - - - internal void WriteNbsp(int count) - { - InternalDebug.Assert(outputState == OutputState.OutsideTag); - - if (lastWhitespace) - { - OutputLastWhitespace('\xA0'); - } - - lineLength += count; - textLineLength += count; - while (0 != count--) - { - output.Write('\xA0', this); - } - - allowWspBeforeFollowingTag = false; - } - - - internal void WriteTextInternal(char[] buffer, int index, int count) - { - InternalDebug.Assert(buffer != null); - InternalDebug.Assert(index >= 0 && index <= buffer.Length); - InternalDebug.Assert(count >= 0 && count <= buffer.Length - index); - InternalDebug.Assert(!copyPending); - - InternalDebug.Assert(outputState == OutputState.OutsideTag); - - if (count != 0) - { - if (lastWhitespace) - { - OutputLastWhitespace(buffer[index]); - } - - InternalDebug.Assert(!lastWhitespace); - - output.Write(buffer, index, count, this); - lineLength += count; - textLineLength += count; - - allowWspBeforeFollowingTag = false; - } - } - - - internal void StartTextChunk() - { - if (outputState != OutputState.OutsideTag) - { - WriteTagEnd(); - } - - lastWhitespace = false; - } - - - internal void EndTextChunk() - { - if (lastWhitespace) - { - OutputLastWhitespace('\n'); - } - } - - - internal void WriteCollapsedWhitespace() - { - if (outputState != OutputState.OutsideTag) - { - WriteTagEnd(); - } - - lastWhitespace = true; - allowWspBeforeFollowingTag = false; - } - - - private void OutputLastWhitespace(char nextChar) - { - if (lineLength > 255 && autoNewLines) - { - if (lineLength > longestLineLength) - { - longestLineLength = lineLength; - } - - output.Write("\r\n"); - lineLength = 0; - - if (ParseSupport.FarEastNonHanguelChar(nextChar)) - { - - - - output.Write(' '); - lineLength++; - } - } - else - { - output.Write(' '); - lineLength++; - } - - textLineLength++; - lastWhitespace = false; - } - - - private void OutputAttributeName(string name) - { - -#if false - - - - if (this.lineLength > 255 && this.autoNewLines) - { - - - - if (this.lineLength > this.longestLineLength) - { - this.longestLineLength = this.lineLength; - } - - this.output.Write("\r\n"); - this.lineLength = 0; - } -#endif - output.Write(' '); - output.Write(name); - lineLength += name.Length + 1; - - outputState = OutputState.AfterAttributeName; - } - - - private void OutputAttributeValue(string value) - { - InternalDebug.Assert(outputState > OutputState.BeforeAttribute); - - if (outputState < OutputState.WritingAttributeValue) - { - output.Write("=\""); - lineLength += 2; - } - - output.Write(value, this); - lineLength += value.Length; - - outputState = OutputState.WritingAttributeValue; - } - - - private void OutputAttributeValue(char[] value, int index, int count) - { - InternalDebug.Assert(outputState > OutputState.BeforeAttribute); - - if (outputState < OutputState.WritingAttributeValue) - { - output.Write("=\""); - lineLength += 2; - } - - output.Write(value, index, count, this); - lineLength += count; - - outputState = OutputState.WritingAttributeValue; - } - - - private void OutputAttributeEnd() - { - InternalDebug.Assert(outputState > OutputState.BeforeAttribute); - - if (outputState < OutputState.WritingAttributeValue) - { - output.Write("=\""); - lineLength += 2; - } - - - output.Write('\"'); - lineLength++; - } - - - internal static HtmlNameIndex LookupName(string name) - { - if (name.Length <= HtmlNameData.MAX_NAME) - { - var hash = (short)(((uint)HashCode.CalculateLowerCase(name) ^ HtmlNameData.NAME_HASH_MODIFIER) % HtmlNameData.NAME_HASH_SIZE); - - - - var nameIndex = (int)HtmlNameData.nameHashTable[hash]; - - if (nameIndex > 0) - { - do - { - - - var currentName = HtmlNameData.names[nameIndex].name; - - if (currentName.Length == name.Length) - { - if (currentName[0] == ParseSupport.ToLowerCase(name[0])) - { - if (name.Length == 1 || currentName.Equals(name, StringComparison.OrdinalIgnoreCase)) - { - return (HtmlNameIndex)nameIndex; - } - } - } - - - - } - while (HtmlNameData.names[++nameIndex].hash == hash); - } - } - - return HtmlNameIndex.Unknown; - } - - - bool IRestartable.CanRestart() - { - if (output is IRestartable) - { - return ((IRestartable)output).CanRestart(); - } - - return false; - } - - - void IRestartable.Restart() - { - if (output is IRestartable) - { - ((IRestartable)output).Restart(); - } - - - - allowWspBeforeFollowingTag = false; - lastWhitespace = false; - lineLength = 0; - longestLineLength = 0; - - literalWhitespaceNesting = 0; - literalTags = false; - literalEntities = false; - cssEscaping = false; - - tagNameIndex = HtmlNameIndex._NOTANAME; - previousTagNameIndex = HtmlNameIndex._NOTANAME; - - isEndTag = false; - isEmptyScopeTag = false; - copyPending = false; - - outputState = OutputState.OutsideTag; - } - - - void IRestartable.DisableRestart() - { - if (output is IRestartable) - { - ((IRestartable)output).DisableRestart(); - } - } - - - byte[] IFallback.GetUnsafeAsciiMap(out byte unsafeAsciiMask) - { - if (literalEntities) - { - unsafeAsciiMask = 0x00; - return null; - } - - if (filterHtml) - { - - unsafeAsciiMask = 0x01; - } - else - { - unsafeAsciiMask = 0x01; - } - - return HtmlSupport.UnsafeAsciiMap; - } - - - bool IFallback.HasUnsafeUnicode() - { - return filterHtml; - } - - bool IFallback.TreatNonAsciiAsUnsafe(string charset) - { - return filterHtml && charset.StartsWith("x-", StringComparison.OrdinalIgnoreCase); - } - - bool IFallback.IsUnsafeUnicode(char ch, bool isFirstChar) - { - return filterHtml && - ((byte)(ch & 0xFF) == (byte)'<' || - (byte)((ch >> 8) & 0xFF) == (byte)'<' || - - - (!isFirstChar && ch == '\uFEFF') || - - - - Char.GetUnicodeCategory(ch) == System.Globalization.UnicodeCategory.PrivateUse); - } - - - bool IFallback.FallBackChar(char ch, char[] outputBuffer, ref int outputBufferCount, int outputEnd) - { - if (literalEntities) - { - - - if (cssEscaping) - { - - - var value = (uint)ch; - var len = (value < 0x10) ? 1 : (value < 0x100) ? 2 : (value < 0x1000) ? 3 : 4; - if (outputEnd - outputBufferCount < len + 2) - { - return false; - } - - outputBuffer[outputBufferCount++] = '\\'; - - var offset = outputBufferCount + len; - while (value != 0) - { - var digit = value & 0xF; - outputBuffer[--offset] = (char)(digit + (digit < 10 ? '0' : 'A' - 10)); - value >>= 4; - } - outputBufferCount += len; - - outputBuffer[outputBufferCount++] = ' '; - } - else - { - - - - - - - if (outputEnd - outputBufferCount < 1) - { - return false; - } - - outputBuffer[outputBufferCount++] = filterHtml ? '?' : ch; - } - } - else - { - - - - - - - - - - HtmlEntityIndex namedEntityId = 0; - - if (ch <= '>') - { - if (ch == '>') - { - namedEntityId = HtmlEntityIndex.gt; - } - else if (ch == '<') - { - namedEntityId = HtmlEntityIndex.lt; - } - else if (ch == '&') - { - namedEntityId = HtmlEntityIndex.amp; - } - else if (ch == '\"') - { - namedEntityId = HtmlEntityIndex.quot; - } - } - else if ((char)0xA0 <= ch && ch <= (char)0xFF) - { - namedEntityId = HtmlSupport.EntityMap[(int)ch - 0xA0]; - } - - if ((int)namedEntityId != 0) - { - - - var strQuote = HtmlNameData.entities[(int)namedEntityId].name; - - if (outputEnd - outputBufferCount < strQuote.Length + 2) - { - return false; - } - - outputBuffer[outputBufferCount++] = '&'; - strQuote.CopyTo(0, outputBuffer, outputBufferCount, strQuote.Length); - outputBufferCount += strQuote.Length; - outputBuffer[outputBufferCount++] = ';'; - } - else - { - - - var value = (uint)ch; - var len = (value < 10) ? 1 : (value < 100) ? 2 : (value < 1000) ? 3 : (value < 10000) ? 4 : 5; - if (outputEnd - outputBufferCount < len + 3) - { - return false; - } - - outputBuffer[outputBufferCount++] = '&'; - outputBuffer[outputBufferCount++] = '#'; - - var offset = outputBufferCount + len; - while (value != 0) - { - var digit = value % 10; - outputBuffer[--offset] = (char)(digit + '0'); - value /= 10; - } - outputBufferCount += len; - - outputBuffer[outputBufferCount++] = ';'; - } - } - - return true; - } - - - bool ITextSink.IsEnough => false; - - void ITextSink.Write(char[] buffer, int offset, int count) - { - lineLength += count; - textLineLength += count; - output.Write(buffer, offset, count, fallback); - } - - void ITextSink.Write(int ucs32Char) - { - lineLength++; - textLineLength++; - output.Write(ucs32Char, fallback); - } - - - void ITextSinkEx.Write(string text) - { - lineLength += text.Length; - textLineLength += text.Length; - output.Write(text, fallback); - } - - void ITextSinkEx.WriteNewLine() - { - if (lineLength > longestLineLength) - { - longestLineLength = lineLength; - } - - output.Write("\r\n"); - lineLength = 0; - } - - - - - - public void Close() - { - Dispose(true); - } - - - void IDisposable.Dispose() - { - Dispose(true); - } - - - - - protected virtual void Dispose(bool disposing) - { - if (disposing) - { - if (output != null) - { - if (!copyPending) - { - Flush(); - } - - if (output is IDisposable) - { - ((IDisposable)output).Dispose(); - } - } - - GC.SuppressFinalize(this); - } - - output = null; - } - } -} diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HtmlToHtml.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HtmlToHtml.cs deleted file mode 100644 index bdf7ef528..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/HtmlToHtml.cs +++ /dev/null @@ -1,784 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters -{ - using System; - using System.IO; - using System.Text; - using Internal.Html; - using Strings = CtsResources.TextConvertersStrings; - - - - - - internal class HtmlToHtml : TextConverter - { - private Encoding inputEncoding = null; - private bool detectEncodingFromByteOrderMark = true; - private bool detectEncodingFromMetaTag = true; - - private Encoding outputEncoding = null; - private bool outputEncodingSameAsInput = true; - - private bool normalizeInputHtml = false; - - private HeaderFooterFormat injectionFormat = HeaderFooterFormat.Text; - private string injectHead = null; - private string injectTail = null; - - - - private bool filterHtml = false; - private HtmlTagCallback htmlCallback = null; - - private bool testTruncateForCallback = true; - - private bool testConvertFragment; - private bool outputFragment; - - private int testMaxTokenRuns = 512; - - private Stream testTraceStream = null; - private bool testTraceShowTokenNum = true; - private int testTraceStopOnTokenNum = 0; - - private Stream testNormalizerTraceStream = null; - private bool testNormalizerTraceShowTokenNum = true; - private int testNormalizerTraceStopOnTokenNum = 0; - - private int maxHtmlTagSize = 32768; - - private int testMaxHtmlTagAttributes = 64; - private int testMaxHtmlRestartOffset = 4096; - - - private int testMaxHtmlNormalizerNesting = HtmlSupport.HtmlNestingLimit; - - private int smallCssBlockThreshold = -1; - private bool preserveDisplayNoneStyle = false; - - private bool testNoNewLines; - - - - - - - - - - - public HtmlToHtml() - { - } - - - - - - - - - - - - - - - public Encoding InputEncoding - { - get { return inputEncoding; } - set { AssertNotLocked(); inputEncoding = value; } - } - - - - - - - - - public bool DetectEncodingFromByteOrderMark - { - get { return detectEncodingFromByteOrderMark; } - set { AssertNotLocked(); detectEncodingFromByteOrderMark = value; } - } - - - - - - - - - public bool DetectEncodingFromMetaTag - { - get { return detectEncodingFromMetaTag; } - set { AssertNotLocked(); detectEncodingFromMetaTag = value; } - } - - - - - - - - - public bool NormalizeHtml - { - get { return normalizeInputHtml; } - set { AssertNotLocked(); normalizeInputHtml = value; } - } - -#if M3STUFF - - - - - - public IHtmlParsingCallback HtmlParsingCallback - { - get { return this.parsingCallback; } - set { this.AssertNotLocked(); this.parsingCallback = value; } - } -#endif - - - - - - - - - - - - - - public Encoding OutputEncoding - { - get { return outputEncoding; } - set - { - AssertNotLocked(); - outputEncoding = value; - outputEncodingSameAsInput = (value == null); - } - } - - - - - - - - - - - - - - public HeaderFooterFormat HeaderFooterFormat - { - get { return injectionFormat; } - set { AssertNotLocked(); injectionFormat = value; } - } - - - - - - - - public string Header - { - get { return injectHead; } - set { AssertNotLocked(); injectHead = value; } - } - - - - - - - - public string Footer - { - get { return injectTail; } - set { AssertNotLocked(); injectTail = value; } - } - - - - - - - - public bool OutputHtmlFragment - { - get { return outputFragment; } - set { AssertNotLocked(); outputFragment = value; } - } - - - - - - - - public bool FilterHtml - { - get { return filterHtml; } - set { AssertNotLocked(); filterHtml = value; } - } - - - - - - - - - public HtmlTagCallback HtmlTagCallback - { - get { return htmlCallback; } - set { AssertNotLocked(); htmlCallback = value; } - } - - - - - - - - - - - public int MaxCallbackTagLength - { - get { return maxHtmlTagSize; } - set { AssertNotLocked(); maxHtmlTagSize = value; } - } - -#if M3STUFF - - - - - - - public HtmlFilterTables HtmlFilterTables - { - get { return this.filterTables; } - set { this.AssertNotLocked(); this.filterTables = value; } - } -#endif - - - - - internal HtmlToHtml SetInputEncoding(Encoding value) - { - InputEncoding = value; - return this; - } - - internal HtmlToHtml SetDetectEncodingFromByteOrderMark(bool value) - { - DetectEncodingFromByteOrderMark = value; - return this; - } - - internal HtmlToHtml SetDetectEncodingFromMetaTag(bool value) - { - DetectEncodingFromMetaTag = value; - return this; - } - - internal HtmlToHtml SetOutputEncoding(Encoding value) - { - OutputEncoding = value; - return this; - } - - internal HtmlToHtml SetNormalizeHtml(bool value) - { - NormalizeHtml = value; - return this; - } - - internal HtmlToHtml SetHeaderFooterFormat(HeaderFooterFormat value) - { - HeaderFooterFormat = value; - return this; - } - - internal HtmlToHtml SetHeader(string value) - { - Header = value; - return this; - } - - internal HtmlToHtml SetFooter(string value) - { - Footer = value; - return this; - } - - internal HtmlToHtml SetFilterHtml(bool value) - { - FilterHtml = value; - return this; - } - - internal HtmlToHtml SetHtmlTagCallback(HtmlTagCallback value) - { - HtmlTagCallback = value; - return this; - } - - internal HtmlToHtml SetTestTruncateForCallback(bool value) - { - testTruncateForCallback = value; - return this; - } - - internal HtmlToHtml SetMaxCallbackTagLength(int value) - { - maxHtmlTagSize = value; - return this; - } - - internal HtmlToHtml SetInputStreamBufferSize(int value) - { - InputStreamBufferSize = value; - return this; - } - - internal HtmlToHtml SetOutputHtmlFragment(bool value) - { - OutputHtmlFragment = value; - return this; - } - - internal HtmlToHtml SetTestConvertHtmlFragment(bool value) - { - testConvertFragment = value; - return this; - } - - internal HtmlToHtml SetTestBoundaryConditions(bool value) - { - testBoundaryConditions = value; - if (value) - { - maxHtmlTagSize = 123; - testMaxHtmlTagAttributes = 5; - testMaxHtmlNormalizerNesting = 10; - } - return this; - } - - internal HtmlToHtml SetTestMaxTokenRuns(int value) - { - testMaxTokenRuns = value; - return this; - } - - internal HtmlToHtml SetTestTraceStream(Stream value) - { - testTraceStream = value; - return this; - } - - internal HtmlToHtml SetTestTraceShowTokenNum(bool value) - { - testTraceShowTokenNum = value; - return this; - } - - internal HtmlToHtml SetTestTraceStopOnTokenNum(int value) - { - testTraceStopOnTokenNum = value; - return this; - } - - internal HtmlToHtml SetTestNormalizerTraceStream(Stream value) - { - testNormalizerTraceStream = value; - return this; - } - - internal HtmlToHtml SetTestNormalizerTraceShowTokenNum(bool value) - { - testNormalizerTraceShowTokenNum = value; - return this; - } - - internal HtmlToHtml SetTestNormalizerTraceStopOnTokenNum(int value) - { - testNormalizerTraceStopOnTokenNum = value; - return this; - } - - internal HtmlToHtml SetTestMaxHtmlTagAttributes(int value) - { - testMaxHtmlTagAttributes = value; - return this; - } - - internal HtmlToHtml SetTestMaxHtmlRestartOffset(int value) - { - testMaxHtmlRestartOffset = value; - return this; - } - - internal HtmlToHtml SetTestMaxHtmlNormalizerNesting(int value) - { - testMaxHtmlNormalizerNesting = value; - return this; - } - - internal HtmlToHtml SetTestNoNewLines(bool value) - { - testNoNewLines = value; - return this; - } - - internal HtmlToHtml SetSmallCssBlockThreshold(int value) - { - smallCssBlockThreshold = value; - return this; - } - - internal HtmlToHtml SetPreserveDisplayNoneStyle(bool value) - { - preserveDisplayNoneStyle = value; - return this; - } - - - - internal override IProducerConsumer CreatePushChain(ConverterStream converterStream, Stream output) - { - if (inputEncoding == null) - { - throw new InvalidOperationException(Strings.InputEncodingRequired); - } - - ConverterInput converterIn = new ConverterDecodingInput( - converterStream, - true, - inputEncoding, - detectEncodingFromByteOrderMark, - maxHtmlTagSize, - testMaxHtmlRestartOffset, - InputStreamBufferSize, - testBoundaryConditions, - this as IResultsFeedback, - null); - - ConverterOutput converterOut = new ConverterEncodingOutput( - output, - true, - true, - outputEncodingSameAsInput ? inputEncoding : outputEncoding, - outputEncodingSameAsInput, - testBoundaryConditions, - this as IResultsFeedback); - - return CreateChain(converterIn, converterOut, converterStream as IProgressMonitor); - } - - internal override IProducerConsumer CreatePushChain(ConverterStream converterStream, TextWriter output) - { - if (inputEncoding == null) - { - throw new InvalidOperationException(Strings.InputEncodingRequired); - } - - outputEncoding = Encoding.Unicode; - - ConverterInput converterIn = new ConverterDecodingInput( - converterStream, - true, - inputEncoding, - detectEncodingFromByteOrderMark, - maxHtmlTagSize, - testMaxHtmlRestartOffset, - InputStreamBufferSize, - testBoundaryConditions, - this as IResultsFeedback, - null); - - ConverterOutput converterOut = new ConverterUnicodeOutput( - output, - true, - true); - - return CreateChain(converterIn, converterOut, converterStream as IProgressMonitor); - } - - internal override IProducerConsumer CreatePushChain(ConverterWriter converterWriter, Stream output) - { - inputEncoding = Encoding.Unicode; - - ConverterInput converterIn = new ConverterUnicodeInput( - converterWriter, - true, - maxHtmlTagSize, - testBoundaryConditions, - null); - - ConverterOutput converterOut = new ConverterEncodingOutput( - output, - true, - false, - outputEncodingSameAsInput ? Encoding.UTF8 : outputEncoding, - outputEncodingSameAsInput, - testBoundaryConditions, - this as IResultsFeedback); - - return CreateChain(converterIn, converterOut, converterWriter as IProgressMonitor); - } - - internal override IProducerConsumer CreatePushChain(ConverterWriter converterWriter, TextWriter output) - { - inputEncoding = Encoding.Unicode; - outputEncoding = Encoding.Unicode; - - ConverterInput converterIn = new ConverterUnicodeInput( - converterWriter, - true, - maxHtmlTagSize, - testBoundaryConditions, - null); - - ConverterOutput converterOut = new ConverterUnicodeOutput( - output, - true, - false); - - return CreateChain(converterIn, converterOut, converterWriter as IProgressMonitor); - } - - internal override IProducerConsumer CreatePullChain(Stream input, ConverterStream converterStream) - { - if (inputEncoding == null) - { - throw new InvalidOperationException(Strings.InputEncodingRequired); - } - - ConverterInput converterIn = new ConverterDecodingInput( - input, - false, - inputEncoding, - detectEncodingFromByteOrderMark, - maxHtmlTagSize, - testMaxHtmlRestartOffset, - InputStreamBufferSize, - testBoundaryConditions, - this as IResultsFeedback, - converterStream as IProgressMonitor); - - ConverterOutput converterOut = new ConverterEncodingOutput( - converterStream, - false, - true, - outputEncodingSameAsInput ? inputEncoding : outputEncoding, - outputEncodingSameAsInput, - testBoundaryConditions, - this as IResultsFeedback); - - return CreateChain(converterIn, converterOut, converterStream as IProgressMonitor); - } - - internal override IProducerConsumer CreatePullChain(TextReader input, ConverterStream converterStream) - { - inputEncoding = Encoding.Unicode; - - ConverterInput converterIn = new ConverterUnicodeInput( - input, - false, - maxHtmlTagSize, - testBoundaryConditions, - converterStream as IProgressMonitor); - - ConverterOutput converterOut = new ConverterEncodingOutput( - converterStream, - false, - false, - outputEncodingSameAsInput ? Encoding.UTF8 : outputEncoding, - outputEncodingSameAsInput, - testBoundaryConditions, - this as IResultsFeedback); - - return CreateChain(converterIn, converterOut, converterStream as IProgressMonitor); - } - - internal override IProducerConsumer CreatePullChain(Stream input, ConverterReader converterReader) - { - if (inputEncoding == null) - { - throw new InvalidOperationException(Strings.InputEncodingRequired); - } - - outputEncoding = Encoding.Unicode; - - ConverterInput converterIn = new ConverterDecodingInput( - input, - false, - inputEncoding, - detectEncodingFromByteOrderMark, - maxHtmlTagSize, - testMaxHtmlRestartOffset, - InputStreamBufferSize, - testBoundaryConditions, - this as IResultsFeedback, - converterReader as IProgressMonitor); - - ConverterOutput converterOut = new ConverterUnicodeOutput( - converterReader, - false, - true); - - return CreateChain(converterIn, converterOut, converterReader as IProgressMonitor); - } - - internal override IProducerConsumer CreatePullChain(TextReader input, ConverterReader converterReader) - { - inputEncoding = Encoding.Unicode; - outputEncoding = Encoding.Unicode; - - ConverterInput converterIn = new ConverterUnicodeInput( - input, - false, - maxHtmlTagSize, - testBoundaryConditions, - converterReader as IProgressMonitor); - - ConverterOutput converterOut = new ConverterUnicodeOutput( - converterReader, - false, - false); - - return CreateChain(converterIn, converterOut, converterReader as IProgressMonitor); - } - - - - private IProducerConsumer CreateChain(ConverterInput input, ConverterOutput output, IProgressMonitor progressMonitor) - { - locked = true; - - HtmlInjection injection = null; - - if (injectHead != null || injectTail != null) - { - injection = new HtmlInjection( - injectHead, - injectTail, - injectionFormat, - filterHtml, - htmlCallback, - testBoundaryConditions, - null, - progressMonitor); - - - - normalizeInputHtml = true; - } - - if (filterHtml || outputFragment || htmlCallback != null) - { - - normalizeInputHtml = true; - } - - IHtmlParser parser; - - if (normalizeInputHtml) - { - - - - var preParser = new HtmlParser( - input, - detectEncodingFromMetaTag, - false, - testMaxTokenRuns, - testMaxHtmlTagAttributes, - testBoundaryConditions); - - parser = new HtmlNormalizingParser( - preParser, - injection, - htmlCallback != null, - testMaxHtmlNormalizerNesting, - testBoundaryConditions, - testNormalizerTraceStream, - testNormalizerTraceShowTokenNum, - testNormalizerTraceStopOnTokenNum); - } - else - { - parser = new HtmlParser( - input, - detectEncodingFromMetaTag, - false, - testMaxTokenRuns, - testMaxHtmlTagAttributes, - testBoundaryConditions); - } - - var writer = new HtmlWriter( - output, - filterHtml, - normalizeInputHtml && !testNoNewLines); - - return new HtmlToHtmlConverter( - parser, - writer, - testConvertFragment, - outputFragment, - filterHtml, - htmlCallback, - testTruncateForCallback, - injection != null && injection.HaveTail, - testTraceStream, - testTraceShowTokenNum, - testTraceStopOnTokenNum, - smallCssBlockThreshold, - preserveDisplayNoneStyle, - progressMonitor); - } - - - - internal override void SetResult(ConfigParameter parameterId, object val) - { - switch (parameterId) - { - case ConfigParameter.InputEncoding: - inputEncoding = (Encoding) val; - break; - - case ConfigParameter.OutputEncoding: - outputEncoding = (Encoding) val; - break; - } - - base.SetResult(parameterId, val); - } - } -} - diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/Microsoft.Exchange.CtsResources.TextConvertersStrings.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/Microsoft.Exchange.CtsResources.TextConvertersStrings.cs deleted file mode 100644 index cbd650742..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/Microsoft.Exchange.CtsResources.TextConvertersStrings.cs +++ /dev/null @@ -1,532 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -using System.Resources; -using static System.String; - -namespace Microsoft.Exchange.CtsResources -{ - - - - static class TextConvertersStrings - { - - - - - private static string[] stringIDs = - { - "AttributeNotStarted", - "InputEncodingRequired", - "AttributeCollectionNotInitialized", - "ConverterWriterInInconsistentStare", - "CannotUseConverterReader", - "CannotReadFromSource", - "AttributeIdIsUnknown", - "TagTooLong", - "EndTagCannotHaveAttributes", - "CannotUseConverterWriter", - "WriteAfterFlush", - "PriorityListIncludesNonDetectableCodePage", - "TagNotStarted", - "CannotSetNegativelength", - "TooManyIterationsToFlushConverter", - "IndexOutOfRange", - "TagNameIsEmpty", - "MaxCharactersCannotBeNegative", - "AttributeNotValidForThisContext", - "InputDocumentTooComplex", - "TextWriterUnsupported", - "PropertyNotValidForCodepageConversionMode", - "CountTooLarge", - "TooManyIterationsToProduceOutput", - "AttributeNotInitialized", - "AttributeIdInvalid", - "TooManyIterationsToProcessInput", - "BufferSizeValueRange", - "CannotWriteWhileCopyPending", - "AttributeNotValidInThisState", - "ParametersCannotBeChangedAfterConverterObjectIsUsed", - "CountOutOfRange", - "WriteUnsupported", - "AccessShouldBeReadOrWrite", - "ContextNotValidInThisState", - "CannotSeekBeforeBeginning", - "OffsetOutOfRange", - "ReadUnsupported", - "SeekUnsupported", - "CallbackTagAlreadyWritten", - "ConverterStreamInInconsistentStare", - "AttributeNameIsEmpty", - "HtmlNestingTooDeep", - "CannotWriteToDestination", - "ConverterReaderInInconsistentStare", - "TextReaderUnsupported", - "PropertyNotValidForTextExtractionMode", - "TagIdIsUnknown", - "TagIdInvalid", - "CallbackTagAlreadyDeleted", - }; - - - - - public enum IDs - { - - - - AttributeNotStarted, - - - - InputEncodingRequired, - - - - AttributeCollectionNotInitialized, - - - - ConverterWriterInInconsistentStare, - - - - CannotUseConverterReader, - - - - CannotReadFromSource, - - - - AttributeIdIsUnknown, - - - - TagTooLong, - - - - EndTagCannotHaveAttributes, - - - - CannotUseConverterWriter, - - - - WriteAfterFlush, - - - - PriorityListIncludesNonDetectableCodePage, - - - - TagNotStarted, - - - - CannotSetNegativelength, - - - - TooManyIterationsToFlushConverter, - - - - IndexOutOfRange, - - - - TagNameIsEmpty, - - - - MaxCharactersCannotBeNegative, - - - - AttributeNotValidForThisContext, - - - - InputDocumentTooComplex, - - - - TextWriterUnsupported, - - - - PropertyNotValidForCodepageConversionMode, - - - - CountTooLarge, - - - - TooManyIterationsToProduceOutput, - - - - AttributeNotInitialized, - - - - AttributeIdInvalid, - - - - TooManyIterationsToProcessInput, - - - - BufferSizeValueRange, - - - - CannotWriteWhileCopyPending, - - - - AttributeNotValidInThisState, - - - - ParametersCannotBeChangedAfterConverterObjectIsUsed, - - - - CountOutOfRange, - - - - WriteUnsupported, - - - - AccessShouldBeReadOrWrite, - - - - ContextNotValidInThisState, - - - - CannotSeekBeforeBeginning, - - - - OffsetOutOfRange, - - - - ReadUnsupported, - - - - SeekUnsupported, - - - - CallbackTagAlreadyWritten, - - - - ConverterStreamInInconsistentStare, - - - - AttributeNameIsEmpty, - - - - HtmlNestingTooDeep, - - - - CannotWriteToDestination, - - - - ConverterReaderInInconsistentStare, - - - - TextReaderUnsupported, - - - - PropertyNotValidForTextExtractionMode, - - - - TagIdIsUnknown, - - - - TagIdInvalid, - - - - CallbackTagAlreadyDeleted, - } - - - - - public enum ParamIDs - { - - - - CreateFileFailed, - - - - InvalidConfigurationBoolean, - - - - InvalidConfigurationStream, - - - - CannotWriteOtherTagsInsideElement, - - - - InvalidConfigurationInteger, - - - - LengthExceeded, - - - - InvalidCodePage, - } - - - - - public static string AttributeNotStarted => ResourceManager.GetString("AttributeNotStarted"); - - - public static string InputEncodingRequired => ResourceManager.GetString("InputEncodingRequired"); - - - public static string CreateFileFailed (string filePath) - { - return Format(ResourceManager.GetString("CreateFileFailed"), filePath); - } - - - - public static string AttributeCollectionNotInitialized => ResourceManager.GetString("AttributeCollectionNotInitialized"); - - - public static string ConverterWriterInInconsistentStare => ResourceManager.GetString("ConverterWriterInInconsistentStare"); - - - public static string CannotUseConverterReader => ResourceManager.GetString("CannotUseConverterReader"); - - - public static string CannotReadFromSource => ResourceManager.GetString("CannotReadFromSource"); - - - public static string AttributeIdIsUnknown => ResourceManager.GetString("AttributeIdIsUnknown"); - - - public static string TagTooLong => ResourceManager.GetString("TagTooLong"); - - - public static string EndTagCannotHaveAttributes => ResourceManager.GetString("EndTagCannotHaveAttributes"); - - - public static string CannotUseConverterWriter => ResourceManager.GetString("CannotUseConverterWriter"); - - - public static string WriteAfterFlush => ResourceManager.GetString("WriteAfterFlush"); - - - public static string PriorityListIncludesNonDetectableCodePage => ResourceManager.GetString("PriorityListIncludesNonDetectableCodePage"); - - - public static string TagNotStarted => ResourceManager.GetString("TagNotStarted"); - - - public static string CannotSetNegativelength => ResourceManager.GetString("CannotSetNegativelength"); - - - public static string TooManyIterationsToFlushConverter => ResourceManager.GetString("TooManyIterationsToFlushConverter"); - - - public static string IndexOutOfRange => ResourceManager.GetString("IndexOutOfRange"); - - - public static string TagNameIsEmpty => ResourceManager.GetString("TagNameIsEmpty"); - - - public static string MaxCharactersCannotBeNegative => ResourceManager.GetString("MaxCharactersCannotBeNegative"); - - - public static string AttributeNotValidForThisContext => ResourceManager.GetString("AttributeNotValidForThisContext"); - - - public static string InvalidConfigurationBoolean (int propertyId) - { - return Format(ResourceManager.GetString("InvalidConfigurationBoolean"), propertyId); - } - - - - public static string InputDocumentTooComplex => ResourceManager.GetString("InputDocumentTooComplex"); - - - public static string TextWriterUnsupported => ResourceManager.GetString("TextWriterUnsupported"); - - - public static string PropertyNotValidForCodepageConversionMode => ResourceManager.GetString("PropertyNotValidForCodepageConversionMode"); - - - public static string CountTooLarge => ResourceManager.GetString("CountTooLarge"); - - - public static string InvalidConfigurationStream (int propertyId) - { - return Format(ResourceManager.GetString("InvalidConfigurationStream"), propertyId); - } - - - - public static string TooManyIterationsToProduceOutput => ResourceManager.GetString("TooManyIterationsToProduceOutput"); - - - public static string AttributeNotInitialized => ResourceManager.GetString("AttributeNotInitialized"); - - - public static string CannotWriteOtherTagsInsideElement (string elementName) - { - return Format(ResourceManager.GetString("CannotWriteOtherTagsInsideElement"), elementName); - } - - - - public static string AttributeIdInvalid => ResourceManager.GetString("AttributeIdInvalid"); - - - public static string InvalidConfigurationInteger (int propertyId) - { - return Format(ResourceManager.GetString("InvalidConfigurationInteger"), propertyId); - } - - - - public static string TooManyIterationsToProcessInput => ResourceManager.GetString("TooManyIterationsToProcessInput"); - - - public static string BufferSizeValueRange => ResourceManager.GetString("BufferSizeValueRange"); - - - public static string CannotWriteWhileCopyPending => ResourceManager.GetString("CannotWriteWhileCopyPending"); - - - public static string AttributeNotValidInThisState => ResourceManager.GetString("AttributeNotValidInThisState"); - - - public static string ParametersCannotBeChangedAfterConverterObjectIsUsed => ResourceManager.GetString("ParametersCannotBeChangedAfterConverterObjectIsUsed"); - - - public static string CountOutOfRange => ResourceManager.GetString("CountOutOfRange"); - - - public static string WriteUnsupported => ResourceManager.GetString("WriteUnsupported"); - - - public static string AccessShouldBeReadOrWrite => ResourceManager.GetString("AccessShouldBeReadOrWrite"); - - - public static string ContextNotValidInThisState => ResourceManager.GetString("ContextNotValidInThisState"); - - - public static string CannotSeekBeforeBeginning => ResourceManager.GetString("CannotSeekBeforeBeginning"); - - - public static string OffsetOutOfRange => ResourceManager.GetString("OffsetOutOfRange"); - - - public static string ReadUnsupported => ResourceManager.GetString("ReadUnsupported"); - - - public static string LengthExceeded (int sum, int length) - { - return Format(ResourceManager.GetString("LengthExceeded"), sum, length); - } - - - - public static string SeekUnsupported => ResourceManager.GetString("SeekUnsupported"); - - - public static string InvalidCodePage (int codePage) - { - return Format(ResourceManager.GetString("InvalidCodePage"), codePage); - } - - - - public static string CallbackTagAlreadyWritten => ResourceManager.GetString("CallbackTagAlreadyWritten"); - - - public static string ConverterStreamInInconsistentStare => ResourceManager.GetString("ConverterStreamInInconsistentStare"); - - - public static string AttributeNameIsEmpty => ResourceManager.GetString("AttributeNameIsEmpty"); - - - public static string HtmlNestingTooDeep => ResourceManager.GetString("HtmlNestingTooDeep"); - - - public static string CannotWriteToDestination => ResourceManager.GetString("CannotWriteToDestination"); - - - public static string ConverterReaderInInconsistentStare => ResourceManager.GetString("ConverterReaderInInconsistentStare"); - - - public static string TextReaderUnsupported => ResourceManager.GetString("TextReaderUnsupported"); - - - public static string PropertyNotValidForTextExtractionMode => ResourceManager.GetString("PropertyNotValidForTextExtractionMode"); - - - public static string TagIdIsUnknown => ResourceManager.GetString("TagIdIsUnknown"); - - - public static string TagIdInvalid => ResourceManager.GetString("TagIdInvalid"); - - - public static string CallbackTagAlreadyDeleted => ResourceManager.GetString("CallbackTagAlreadyDeleted"); - - - public static string GetLocalizedString( IDs key ) - { - return ResourceManager.GetString(stringIDs[(int)key]); - } - - - - - private static ResourceManager ResourceManager = new ResourceManager("Microsoft.Exchange.CtsResources.TextConvertersStrings", typeof(TextConvertersStrings).Assembly); - } -} diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/Microsoft.Exchange.CtsResources.TextConvertersStrings.resx b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/Microsoft.Exchange.CtsResources.TextConvertersStrings.resx deleted file mode 100644 index 7f6116451..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/Microsoft.Exchange.CtsResources.TextConvertersStrings.resx +++ /dev/null @@ -1,246 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - You should write attribute name before writing attribute value - - - InputEncoding property is required for this conversion. - - - An I/O error occurred while creating the file: {0}. - . - Parameters: 0 - filePath (string) - - - Attribute collection is not properly initialized, you must retrieve one with Attributes property of HtmlTagContext before using. - - - Cannot continue using ConverterWriter after exception is thrown. - - - ConverterReader or TextWriter cannot be used as output with this converter because the converter produces byte output. Use Stream. - - - The source stream does not support reading. - - - Attribute id cannot be Unknown. - - - Tag is too long, buffer reallocation has failed. - - - End tag cannot have any attributes - - - ConverterWriter or TextReader cannot be used as input with this converter because the converter accepts byte input. Use Stream. - - - Write should not be called for ConverterStream after Flush. - - - Priority list cannot include code pages which are not detectable - - - You should write a tag with WriteTag before writing tag attributes - - - Length of the stream cannot be negative. - - - Too many iterations to flush the converter. - - - Index cannot be negative or greater than the length of the buffer. - - - Tag name cannot be empty. - - - maxCharacters cannot be negative. - - - HtmlTagContextAttribute is not valid for the current context. Do not store context attribute across callbacks. - - - Invalid configuration, expected boolean property ({0}). - . - Parameters: 0 - propertyId (int) - - - Input document is too complex. - - - ConverterReader or TextWriter cannot be used as output with this converter. This converter produces byte output (use Stream). - - - This property cannot be used in simple codepage conversion mode - - - Count cannot be greater than the number of bytes in buffer from index till the end. - - - Invalid configuration, expected stream property ({0}). - . - Parameters: 0 - propertyId (int) - - - Too many iterations to produce any output. - - - HtmlTagContextAttribute is not properly initialized, you must retrieve one through HtmlTagContext.Attributes collection. - - - Cannot write other tags inside <{0}> element. - . - Parameters: 0 - elementName (string) - - - Attribute id is invalid. - - - Invalid configuration, expected integer property ({0}). - . - Parameters: 0 - propertyId (int) - - - Too many iterations to process input chunk. - - - value cannot be smaller than 1K or bigger than 80K bytes. - - - Cannot write HTML while input tag or attribute copy is pending. - - - HtmlTagContextAttribute is not valid in this state. - - - Converter object parameters cannot be changed after object is being used - - - Count cannot be negative or greater than the length of the buffer. - - - This stream does not support writing. - - - access should be either Read or Write. - - - HtmlTagContext is not valid in this state. - - - Cannot seek before the beginning of the stream. - - - Offset cannot be negative or greater than the length of the buffer. - - - This stream does not support reading. - - - The sum of offset and count ({0}) is larger than the array length ({1}). - . - Parameters: 0 - sum (int), 1 - length (int) - - - This stream does not support seeking. - - - Text code page ({0}) is invalid or not installed. - . - Parameters: 0 - codePage (int) - - - Callback tag already has been written to output. - - - Cannot continue using ConverterStream after exception is thrown. - - - Attribute name cannot be empty - - - Html tag nesting too deep, cannot convert this document. - - - The destination stream does not support writing. - - - Cannot continue using ConverterReader after exception is thrown. - - - ConverterWriter or TextReader cannot be used as input with this converter. This converter accepts byte input (use Stream). - - - This property cannot be used in text extraction mode - - - Tag id cannot be Unknown. - - - Tag id is invalid. - - - Callback tag already has been deleted. - - - text/microsoft-resx - - - 1.0.0.0 - - - System.Resources.ResXResourceReader - - - System.Resources.ResXResourceWriter - - \ No newline at end of file diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextCodepageConverter.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextCodepageConverter.cs deleted file mode 100644 index 79e55abd3..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextCodepageConverter.cs +++ /dev/null @@ -1,132 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters.Internal.Text -{ - using System; - using System.Text; - - - internal class TextCodePageConverter : IProducerConsumer, IDisposable - { - //////////////////////////////////////////////////////////// - - protected ConverterInput input; - protected bool endOfFile; - protected bool gotAnyText; - - protected ConverterOutput output; - - - public TextCodePageConverter(ConverterInput input, ConverterOutput output) - { - this.input = input; - this.output = output; - } - - - - public void Run() - { - if (endOfFile) - { - return; - } - - char[] buffer = null; - var start = 0; - var current = 0; - var end = 0; - - if (!input.ReadMore(ref buffer, ref start, ref current, ref end)) - { - // cannot decode more data until next input chunk is available - - return; - } - - if (input.EndOfFile) - { - endOfFile = true; - } - - if (end - start != 0) - { - if (!gotAnyText) - { - if (output is ConverterEncodingOutput) - { - var encodingOutput = output as ConverterEncodingOutput; - - if (encodingOutput.CodePageSameAsInput) - { - - if (input is ConverterDecodingInput) - { - encodingOutput.Encoding = (input as ConverterDecodingInput).Encoding; - } - else - { - encodingOutput.Encoding = Encoding.UTF8; - } - - } - - } - - gotAnyText = true; - - } - - output.Write(buffer, start, end - start); - - input.ReportProcessed(end - start); - - } - - if (endOfFile) - { - output.Flush(); - } - - } - - - - public bool Flush() - { - if (!endOfFile) - { - Run(); - } - - return endOfFile; - } - - - void IDisposable.Dispose() - { - if (input != null /*&& this.input is IDisposable*/) - { - ((IDisposable)input).Dispose(); - } - - if (output != null /*&& this.output is IDisposable*/) - { - ((IDisposable)output).Dispose(); - } - - input = null; - output = null; - - GC.SuppressFinalize(this); - } - - } - -} diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextFormatConverter.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextFormatConverter.cs deleted file mode 100644 index a6bd45667..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextFormatConverter.cs +++ /dev/null @@ -1,266 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters.Internal.Text -{ - using System; - using System.IO; - using System.Text; - using Globalization; - using Data.Internal; - using Format; - - - - internal class TextFormatConverter : FormatConverter, IProducerConsumer, IDisposable - { - protected TextParser parser; - - private FormatOutput output; - protected int lineLength; - protected int newLines; - protected int spaces; - protected int nbsps; - protected bool paragraphStarted; - - protected Injection injection; - - - - public TextFormatConverter( - TextParser parser, - FormatOutput output, - Injection injection, - Stream traceStream, - bool traceShowTokenNum, - int traceStopOnTokenNum, - Stream formatConverterTraceStream) : - base(formatConverterTraceStream) - { - this.parser = parser; - - this.output = output; - - if (this.output != null) - { - this.output.Initialize( - Store, - SourceFormat.Text, - "converted from text"); - } - - this.injection = injection; - - // open the document container - InitializeDocument(); - - if (this.injection != null && this.injection.HaveHead) - { - InternalDebug.Assert(this.output != null); - // this.injection.Inject(true, this.output); - } - - - OpenContainer(FormatContainerType.Block, false); - - - Last.SetProperty(PropertyPrecedence.NonStyle, PropertyId.FontSize, new PropertyValue(LengthUnits.Points, 10)); - } - - public TextFormatConverter( - TextParser parser, - FormatStore store, - Injection injection, - Stream traceStream, - bool traceShowTokenNum, - int traceStopOnTokenNum, - Stream formatConverterTraceStream) : - base(store, formatConverterTraceStream) - { - this.parser = parser; - - this.injection = injection; - - // open the document container - InitializeDocument(); - - // open the first paragraph container - OpenContainer(FormatContainerType.Block, false); - - - Last.SetProperty(PropertyPrecedence.NonStyle, PropertyId.FontSize, new PropertyValue(LengthUnits.Points, 10)); - } - - - - public void Initialize(string fragment) - { - parser.Initialize(fragment); - - lineLength = 0; - newLines = 0; - spaces = 0; - nbsps = 0; - paragraphStarted = false; - } - - - public override void Run() - { - if (output != null && MustFlush) - { - if (CanFlush) - { - FlushOutput(); - } - } - else if (!EndOfFile) - { - var tokenId = parser.Parse(); - - if (TextTokenId.None != tokenId) - { - Process(tokenId); - } - } - } - - ///////////////////////////////////////////////////////////// - - public bool Flush() - { - Run(); - return EndOfFile && !MustFlush; - } - - void IDisposable.Dispose() - { - if (parser != null /*&& this.parser is IDisposable*/) - { - ((IDisposable)parser).Dispose(); - } - - parser = null; - - GC.SuppressFinalize(this); - } - - - private bool CanFlush => output.CanAcceptMoreOutput; - - - private bool FlushOutput() - { - InternalDebug.Assert(MustFlush); - - if (output.Flush()) - { - MustFlush = false; - return true; - } - - return false; - } - - - protected void Process(TextTokenId tokenId) - { - switch (tokenId) - { - case TextTokenId.Text: - - OutputFragmentSimple(parser.Token); - break; - - case TextTokenId.EncodingChange: - - if (output != null && output.OutputCodePageSameAsInput) - { - var codePage = parser.Token.Argument; - - #if DEBUG - Encoding newOutputEncoding; - - InternalDebug.Assert(Charset.TryGetEncoding(codePage, out newOutputEncoding)); - #endif - - - output.OutputEncoding = Charset.GetEncoding(codePage); - } - break; - - case TextTokenId.EndOfFile: - - if (injection != null && injection.HaveTail) - { - AddLineBreak(1); - InternalDebug.Assert(output != null); - - } - - // close the paragraph container - CloseContainer(); - - // close the document container - CloseAllContainersAndSetEOF(); - break; - } - } - - - private void OutputFragmentSimple(TextToken token) - { - foreach (var run in token.Runs) - { - if (run.IsTextRun) - { - switch (run.TextType) - { - case RunTextType.NewLine: - - AddLineBreak(1); - break; - - case RunTextType.Space: - case RunTextType.UnusualWhitespace: - - AddSpace(run.Length); - break; - - case RunTextType.Tabulation: - - AddTabulation(run.Length); - break; - - case RunTextType.Nbsp: - - AddNbsp(run.Length); - break; - - case RunTextType.NonSpace: - case RunTextType.Unknown: - - // InternalDebug.Assert(run.IsNormal); - AddNonSpaceText(run.RawBuffer, run.RawOffset, run.RawLength/*, TextMapping.Unicode*/); - break; - - default: - - InternalDebug.Assert(false, "unexpected run text type"); - break; - } - } - else if (run.IsSpecial && run.Kind == (uint)TextRunKind.QuotingLevel) - { - // consider: set QuotingLevelDelta property - } - } - } - } -} - diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextOutput.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextOutput.cs deleted file mode 100644 index eb79074ec..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextOutput.cs +++ /dev/null @@ -1,1278 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters.Internal.Text -{ - using System; - using System.IO; - using System.Text; - using Data.Internal; - using Html; - - using Globalization; - - internal delegate bool ImageRenderingCallbackInternal(string attachmentUrl, int approximateRenderingPosition); - - - - internal class TextOutput : IRestartable, IReusable, IFallback, IDisposable - { - - - protected ConverterOutput output; - - - protected bool lineWrapping; - protected bool rfc2646; - protected int longestNonWrappedParagraph; - protected int wrapBeforePosition; - protected bool preserveTrailingSpace; - protected bool preserveTabulation; - protected bool preserveNbsp; - - - protected int lineLength; - protected int lineLengthBeforeSoftWrap; - protected int flushedLength; - protected int tailSpace; - protected int breakOpportunity; - protected int nextBreakOpportunity; - protected int quotingLevel; - protected bool seenSpace; - protected bool wrapped; - protected char[] wrapBuffer; - protected bool signaturePossible = true; - protected bool anyNewlines; - - private bool fallbacks; - private bool htmlEscape; - - protected bool endParagraph; - - private string anchorUrl; - private int linePosition; - private ImageRenderingCallbackInternal imageRenderingCallback; - - static readonly char[] Whitespaces = { ' ', '\t', '\r', '\n', '\f' }; - - - - public TextOutput( - ConverterOutput output, - bool lineWrapping, - bool flowed, - int wrapBeforePosition, - int longestNonWrappedParagraph, - ImageRenderingCallbackInternal imageRenderingCallback, - bool fallbacks, - bool htmlEscape, - bool preserveSpace, - Stream testTraceStream) - { - - rfc2646 = flowed; - this.lineWrapping = lineWrapping; - this.wrapBeforePosition = wrapBeforePosition; - this.longestNonWrappedParagraph = longestNonWrappedParagraph; - - if (!this.lineWrapping) - { - preserveTrailingSpace = preserveSpace; - preserveTabulation = preserveSpace; - preserveNbsp = preserveSpace; - } - - this.output = output; - - this.fallbacks = fallbacks; - this.htmlEscape = htmlEscape; - - this.imageRenderingCallback = imageRenderingCallback; - - - - - - - - - - - - wrapBuffer = new char[(this.longestNonWrappedParagraph + 1) * 5]; - } - - - private void Reinitialize() - { - anchorUrl = null; - linePosition = 0; - lineLength = 0; - lineLengthBeforeSoftWrap = 0; - flushedLength = 0; - tailSpace = 0; - breakOpportunity = 0; - nextBreakOpportunity = 0; - quotingLevel = 0; - seenSpace = false; - wrapped = false; - signaturePossible = true; - anyNewlines = false; - endParagraph = false; - - } - - - - public bool OutputCodePageSameAsInput - { - get - { - if (output is ConverterEncodingOutput) - { - return (output as ConverterEncodingOutput).CodePageSameAsInput; - } - - return false; - } - } - - - - public Encoding OutputEncoding - { - set - { - if (output is ConverterEncodingOutput) - { - (output as ConverterEncodingOutput).Encoding = value; - return; - } - - InternalDebug.Assert(false, "this should never happen"); - throw new InvalidOperationException(); - } - } - - - - public bool LineEmpty => lineLength == 0 && tailSpace == 0; - - - public bool ImageRenderingCallbackDefined => imageRenderingCallback != null; - - - public void OpenDocument() - { - - } - - - - public void CloseDocument() - { - - if (!anyNewlines) - { - - output.Write("\r\n"); - } - - endParagraph = false; - } - - - - public void SetQuotingLevel(int quotingLevel) - { - - - - this.quotingLevel = Math.Min(quotingLevel, wrapBeforePosition / 2); - } - - - - public void CloseParagraph() - { - - if (lineLength != 0 || tailSpace != 0) - { - OutputNewLine(); - } - - endParagraph = true; - } - - - - public void OutputNewLine() - { - - - - - - if (lineWrapping) - { - FlushLine('\n'); - - if (signaturePossible && lineLength == 2 && tailSpace == 1) - { - - output.Write(' '); - lineLength++; - } - } - else if (preserveTrailingSpace && tailSpace != 0) - { - FlushTailSpace(); - } - - if (!endParagraph) - { - output.Write("\r\n"); - anyNewlines = true; - linePosition += 2; - } - - linePosition += lineLength; - - lineLength = 0; - lineLengthBeforeSoftWrap = 0; - flushedLength = 0; - tailSpace = 0; - breakOpportunity = 0; - nextBreakOpportunity = 0; - wrapped = false; - - seenSpace = false; - signaturePossible = true; - } - - - - public void OutputTabulation(int count) - { - - if (preserveTabulation) - { - while (count != 0) - { - OutputNonspace("\t", TextMapping.Unicode); - count--; - } - } - else - { - var tabPosition = (lineLengthBeforeSoftWrap + lineLength + tailSpace) / 8 * 8 + 8 * count; - count = tabPosition - (lineLengthBeforeSoftWrap + lineLength + tailSpace); - - OutputSpace(count); - } - } - - - - public void OutputSpace(int count) - { - - - - InternalDebug.Assert(count != 0); - - if (lineWrapping) - { - if (breakOpportunity == 0 || lineLength + tailSpace <= WrapBeforePosition()) - { - breakOpportunity = lineLength + tailSpace; - - InternalDebug.Assert(breakOpportunity >= 0); - - if (lineLength + tailSpace < WrapBeforePosition() && count > 1) - { - breakOpportunity += Math.Min(WrapBeforePosition() - (lineLength + tailSpace), count - 1); - } - - if (breakOpportunity < lineLength + tailSpace + count - 1) - { - - - nextBreakOpportunity = lineLength + tailSpace + count - 1; - } - - if (lineLength > flushedLength) - { - FlushLine(' '); - } - } - else - { - - - - - - nextBreakOpportunity = lineLength + tailSpace + count - 1; - } - } - - tailSpace += count; - - InternalDebug.Assert(breakOpportunity == 0 || breakOpportunity < lineLength + tailSpace); - InternalDebug.Assert(nextBreakOpportunity == 0 || nextBreakOpportunity < lineLength + tailSpace); - } - - - - public void OutputNbsp(int count) - { - - - - if (preserveNbsp) - { - while (count != 0) - { - OutputNonspace("\xA0", TextMapping.Unicode); - count--; - } - } - else - { - tailSpace += count; - } - } - - - - public void OutputNonspace(char[] buffer, int offset, int count, TextMapping textMapping) - { - - if (!lineWrapping && !endParagraph && textMapping == TextMapping.Unicode) - { - if (tailSpace != 0) - { - FlushTailSpace(); - } - - output.Write(buffer, offset, count, fallbacks ? this : null); - - lineLength += count; - } - else - { - OutputNonspaceImpl(buffer, offset, count, textMapping); - } - } - - - - private void OutputNonspaceImpl(char[] buffer, int offset, int count, TextMapping textMapping) - { - if (count != 0) - { - if (textMapping != TextMapping.Unicode) - { - - - - - for (var i = 0; i < count; i++) - { - MapAndOutputSymbolCharacter(buffer[offset++], textMapping); - } - return; - } - - if (endParagraph) - { - InternalDebug.Assert(lineLength == 0); - - output.Write("\r\n"); - linePosition += 2; - anyNewlines = true; - endParagraph = false; - } - - if (lineWrapping) - { - - - - - - - - WrapPrepareToAppendNonspace(count); - - if (breakOpportunity == 0) - { - FlushLine(buffer[offset]); - - output.Write(buffer, offset, count, fallbacks ? this : null); - - flushedLength += count; - } - else - { - - - - Buffer.BlockCopy(buffer, offset * 2, wrapBuffer, (lineLength - flushedLength) * 2, count * 2); - } - - lineLength += count; - - if (lineLength > 2 || buffer[offset] != '-' || (count == 2 && buffer[offset + 1] != '-')) - { - signaturePossible = false; - } - } - else - { - if (tailSpace != 0) - { - FlushTailSpace(); - } - - output.Write(buffer, offset, count, fallbacks ? this : null); - - lineLength += count; - } - } - } - - - - public void OutputNonspace(string text, TextMapping textMapping) - { - OutputNonspace(text, 0, text.Length, textMapping); - } - - - - public void OutputNonspace(string text, int offset, int length, TextMapping textMapping) - { - - if (textMapping != TextMapping.Unicode) - { - for (var i = offset; i < length; i++) - { - MapAndOutputSymbolCharacter(text[i], textMapping); - } - return; - } - - if (endParagraph) - { - InternalDebug.Assert(lineLength == 0); - - output.Write("\r\n"); - linePosition += 2; - anyNewlines = true; - endParagraph = false; - } - - if (lineWrapping) - { - if (length != 0) - { - - - - - - - - WrapPrepareToAppendNonspace(length); - - if (breakOpportunity == 0) - { - FlushLine(text[offset]); - - output.Write(text, offset, length, fallbacks ? this : null); - - flushedLength += length; - } - else - { - text.CopyTo(offset, wrapBuffer, lineLength - flushedLength, length); - } - - lineLength += length; - - if (lineLength > 2 || text[offset] != '-' || (length == 2 && text[offset + 1] != '-')) - { - signaturePossible = false; - } - } - } - else - { - if (tailSpace != 0) - { - FlushTailSpace(); - } - - output.Write(text, offset, length, fallbacks ? this : null); - - lineLength += length; - } - } - - - - public void OutputNonspace(int ucs32Literal, TextMapping textMapping) - { - - if (textMapping != TextMapping.Unicode) - { - MapAndOutputSymbolCharacter((char)ucs32Literal, textMapping); - return; - } - - if (endParagraph) - { - InternalDebug.Assert(lineLength == 0); - - output.Write("\r\n"); - linePosition += 2; - anyNewlines = true; - endParagraph = false; - } - - if (lineWrapping) - { - var count = Token.LiteralLength(ucs32Literal); - - - - - - - - - WrapPrepareToAppendNonspace(count); - - if (breakOpportunity == 0) - { - FlushLine(Token.LiteralFirstChar(ucs32Literal)); - - output.Write(ucs32Literal, fallbacks ? this : null); - - flushedLength += count; - } - else - { - wrapBuffer[lineLength - flushedLength] = Token.LiteralFirstChar(ucs32Literal); - if (count != 1) - { - wrapBuffer[lineLength - flushedLength + 1] = Token.LiteralLastChar(ucs32Literal); - } - } - - lineLength += count; - - if (lineLength > 2 || count != 1 || (char)ucs32Literal != '-') - { - signaturePossible = false; - } - } - else - { - if (tailSpace != 0) - { - FlushTailSpace(); - } - - output.Write(ucs32Literal, fallbacks ? this : null); - - lineLength += Token.LiteralLength(ucs32Literal); - } - } - - - - public void OpenAnchor(string anchorUrl) - { - - - this.anchorUrl = anchorUrl; - } - - - - public void CloseAnchor() - { - - - - if (anchorUrl != null) - { - var addSpace = (tailSpace != 0); - - var urlString = anchorUrl; - - if (urlString.IndexOf(' ') != -1) - { - urlString = urlString.Replace(" ", "%20"); - } - - OutputNonspace("<", TextMapping.Unicode); - OutputNonspace(urlString, TextMapping.Unicode); - OutputNonspace(">", TextMapping.Unicode); - - if (addSpace) - { - OutputSpace(1); - } - - anchorUrl = null; - } - } - - - - public void CancelAnchor() - { - - anchorUrl = null; - } - - - - public void OutputImage(string imageUrl, string imageAltText, int wdthPixels, int heightPixels) - { - - - - if (imageRenderingCallback != null && imageRenderingCallback(imageUrl, RenderingPosition())) - { - - OutputSpace(1); - } - else - { - if ((wdthPixels == 0 || wdthPixels >= 8) && (heightPixels == 0 || heightPixels >= 8)) - { - var addSpace = (tailSpace != 0); - - - OutputNonspace("[", TextMapping.Unicode); - - if (!string.IsNullOrEmpty(imageAltText)) - { - - - var offset = 0; - while (offset != imageAltText.Length) - { - var nextOffset = imageAltText.IndexOfAny(Whitespaces, offset); - - if (nextOffset == -1) - { - InternalDebug.Assert(imageAltText.Length - offset > 0); - OutputNonspace(imageAltText, offset, imageAltText.Length - offset, TextMapping.Unicode); - break; - } - - if (nextOffset != offset) - { - OutputNonspace(imageAltText, offset, nextOffset - offset, TextMapping.Unicode); - } - - if (imageAltText[offset] == '\t') - { - OutputTabulation(1); - } - else - { - - OutputSpace(1); - } - - offset = nextOffset + 1; - } - } - else if (!string.IsNullOrEmpty(imageUrl)) - { - - - - - if (imageUrl.Contains("/") && - !imageUrl.StartsWith("http://", StringComparison.OrdinalIgnoreCase) && - !imageUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase) ) - { - imageUrl = "X"; - } - else if (imageUrl.IndexOf(' ') != -1) - { - imageUrl = imageUrl.Replace(" ", "%20"); - } - - OutputNonspace(imageUrl, TextMapping.Unicode); - } - else - { - - OutputNonspace("X", TextMapping.Unicode); - } - OutputNonspace("]", TextMapping.Unicode); - - if (addSpace) - { - OutputSpace(1); - } - } - } - } - - - - public int RenderingPosition() - { - return linePosition + lineLength + tailSpace; - } - - - - public void Flush() - { - if (lineWrapping) - { - if (lineLength != 0) - { - FlushLine('\r'); - - OutputNewLine(); - } - } - else if (lineLength != 0) - { - OutputNewLine(); - } - - output.Flush(); - - } - - - - private int WrapBeforePosition() - { - return wrapBeforePosition - (rfc2646 ? quotingLevel + 1 : 0); - } - - - - private int LongestNonWrappedParagraph() - { - return longestNonWrappedParagraph - (rfc2646 ? quotingLevel + 1 : 0); - } - - - - private void WrapPrepareToAppendNonspace(int count) - { - InternalDebug.Assert(lineWrapping); - InternalDebug.Assert(nextBreakOpportunity == 0 || nextBreakOpportunity > breakOpportunity); - - while (breakOpportunity != 0 && - lineLength + tailSpace + count - > (wrapped ? WrapBeforePosition() : LongestNonWrappedParagraph())) - { - InternalDebug.Assert(breakOpportunity >= flushedLength); - - if (flushedLength == 0 && rfc2646) - { - for (var i = 0; i < quotingLevel; i++) - { - output.Write('>'); - } - - if (quotingLevel != 0 || wrapBuffer[0] == '>' || wrapBuffer[0] == ' ') - { - output.Write(' '); - } - } - - if (breakOpportunity >= lineLength) - { - InternalDebug.Assert(tailSpace >= breakOpportunity + 1 - lineLength); - InternalDebug.Assert(flushedLength == lineLength); - - do - { - - - - if (lineLength - flushedLength == wrapBuffer.Length) - { - output.Write(wrapBuffer, 0, wrapBuffer.Length, fallbacks ? this : null); - flushedLength += wrapBuffer.Length; - } - - wrapBuffer[lineLength - flushedLength] = ' '; - - lineLength++; - tailSpace--; - } - while (lineLength != breakOpportunity + 1); - } - - output.Write(wrapBuffer, 0, breakOpportunity + 1 - flushedLength, fallbacks ? this : null); - - anyNewlines = true; - output.Write("\r\n"); - - wrapped = true; - lineLengthBeforeSoftWrap += breakOpportunity + 1; - - linePosition += breakOpportunity + 1 + 2; - lineLength -= breakOpportunity + 1; - - InternalDebug.Assert(lineLength >= 0); - - var oldFlushedLength = flushedLength; - flushedLength = 0; - - if (lineLength != 0) - { - - - if (nextBreakOpportunity == 0 || - nextBreakOpportunity - (breakOpportunity + 1) >= lineLength || - nextBreakOpportunity - (breakOpportunity + 1) == 0) - { - - - if (rfc2646) - { - for (var i = 0; i < quotingLevel; i++) - { - output.Write('>'); - } - - if (quotingLevel != 0 || wrapBuffer[breakOpportunity + 1 - oldFlushedLength] == '>' || wrapBuffer[breakOpportunity + 1 - oldFlushedLength] == ' ') - { - output.Write(' '); - } - } - - output.Write(wrapBuffer, breakOpportunity + 1 - oldFlushedLength, lineLength, fallbacks ? this : null); - flushedLength = lineLength; - } - else - { - - - Buffer.BlockCopy(wrapBuffer, (breakOpportunity + 1 - oldFlushedLength) * 2, wrapBuffer, 0, lineLength * 2); - } - } - - if (nextBreakOpportunity != 0) - { - InternalDebug.Assert(nextBreakOpportunity > breakOpportunity); - - breakOpportunity = nextBreakOpportunity - (breakOpportunity + 1); - - InternalDebug.Assert(breakOpportunity >= 0); - InternalDebug.Assert(breakOpportunity < lineLength || tailSpace >= breakOpportunity + 1 - lineLength); - - if (breakOpportunity > WrapBeforePosition()) - { - - - - - - - - if (lineLength < WrapBeforePosition()) - { - InternalDebug.Assert(tailSpace != 0); - - nextBreakOpportunity = breakOpportunity; - breakOpportunity = WrapBeforePosition(); - } - else if (breakOpportunity > lineLength) - { - InternalDebug.Assert(tailSpace != 0); - - nextBreakOpportunity = breakOpportunity; - breakOpportunity = lineLength; - } - else - { - nextBreakOpportunity = 0; - } - - InternalDebug.Assert(breakOpportunity == 0 || breakOpportunity < lineLength + tailSpace); - InternalDebug.Assert(nextBreakOpportunity == 0 || nextBreakOpportunity < lineLength + tailSpace); - } - else - { - nextBreakOpportunity = 0; - } - } - else - { - breakOpportunity = 0; - } - - InternalDebug.Assert(breakOpportunity == 0 || breakOpportunity < lineLength + tailSpace); - InternalDebug.Assert(nextBreakOpportunity == 0 || nextBreakOpportunity < lineLength + tailSpace); - } - - if (tailSpace != 0) - { - if (breakOpportunity == 0) - { - InternalDebug.Assert(lineLength == flushedLength); - - if (flushedLength == 0 && rfc2646) - { - for (var i = 0; i < quotingLevel; i++) - { - output.Write('>'); - } - - - output.Write(' '); - } - - flushedLength += tailSpace; - FlushTailSpace(); - } - else - { - InternalDebug.Assert(lineLength + tailSpace + count - flushedLength - <= LongestNonWrappedParagraph()); - - do - { - wrapBuffer[lineLength - flushedLength] = ' '; - - lineLength++; - tailSpace--; - } - while (tailSpace != 0); - } - } - - InternalDebug.Assert(breakOpportunity == 0 || breakOpportunity < lineLength + tailSpace); - InternalDebug.Assert(nextBreakOpportunity == 0 || nextBreakOpportunity < lineLength + tailSpace); - } - - private void FlushLine(char nextChar) - { - if (flushedLength == 0 && rfc2646) - { - for (var i = 0; i < quotingLevel; i++) - { - output.Write('>'); - } - - var firstChar = lineLength != 0 ? wrapBuffer[0] : nextChar; - if (quotingLevel != 0 || firstChar == '>' || firstChar == ' ') - { - output.Write(' '); - } - } - - if (lineLength != flushedLength) - { - output.Write(wrapBuffer, 0, lineLength - flushedLength, fallbacks ? this : null); - flushedLength = lineLength; - } - } - - private void FlushTailSpace() - { - InternalDebug.Assert(tailSpace != 0); - - lineLength += tailSpace; - do - { - output.Write(' '); - tailSpace--; - } - while (tailSpace != 0); - } - - - - private void MapAndOutputSymbolCharacter(char ch, TextMapping textMapping) - { - if (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') - { - OutputNonspace((int)ch, TextMapping.Unicode); - return; - } - - string substitute = null; - - if (textMapping == TextMapping.Wingdings) - { - switch ((int)ch) - { - case 74: - substitute = "\x263A"; - break; - case 75: - substitute = ":|"; - break; - case 76: - substitute = "\x2639"; - break; - case 216: - substitute = ">"; - break; - case 223: - substitute = "<--"; - break; - case 224: - substitute = "-->"; - break; - case 231: - substitute = "<=="; - break; - case 232: - substitute = "==>"; - break; - case 239: - substitute = "<="; - break; - case 240: - substitute = "=>"; - break; - case 243: - substitute = "<=>"; - break; - } - } - - if (substitute == null) - { - substitute = "\x2022"; - } - - OutputNonspace(substitute, TextMapping.Unicode); - } - - - - byte[] IFallback.GetUnsafeAsciiMap(out byte unsafeAsciiMask) - { - if (htmlEscape) - { - - unsafeAsciiMask = 0x01; - return HtmlSupport.UnsafeAsciiMap; - } - - unsafeAsciiMask = 0; - return null; - } - - - - bool IFallback.HasUnsafeUnicode() - { - return htmlEscape; - } - - - - bool IFallback.TreatNonAsciiAsUnsafe(string charset) - { - return false; - } - - - bool IFallback.IsUnsafeUnicode(char ch, bool isFirstChar) - { - return htmlEscape && - ((byte)(ch & 0xFF) == (byte)'<' || - (byte)((ch >> 8) & 0xFF) == (byte)'<'); - } - - - - bool IFallback.FallBackChar(char ch, char[] outputBuffer, ref int outputBufferCount, int outputEnd) - { - if (htmlEscape) - { - - - - - - - - - - HtmlEntityIndex namedEntityId = 0; - - if (ch <= '>') - { - if (ch == '>') - { - namedEntityId = HtmlEntityIndex.gt; - } - else if (ch == '<') - { - namedEntityId = HtmlEntityIndex.lt; - } - else if (ch == '&') - { - namedEntityId = HtmlEntityIndex.amp; - } - else if (ch == '\"') - { - namedEntityId = HtmlEntityIndex.quot; - } - } - else if ((char)0xA0 <= ch && ch <= (char)0xFF) - { - namedEntityId = HtmlSupport.EntityMap[(int)ch - 0xA0]; - } - - if ((int)namedEntityId != 0) - { - - - var strQuote = HtmlNameData.entities[(int)namedEntityId].name; - - if (outputEnd - outputBufferCount < strQuote.Length + 2) - { - return false; - } - - outputBuffer[outputBufferCount++] = '&'; - strQuote.CopyTo(0, outputBuffer, outputBufferCount, strQuote.Length); - outputBufferCount += strQuote.Length; - outputBuffer[outputBufferCount++] = ';'; - } - else - { - - - var value = (uint)ch; - var len = (value < 0x10) ? 1 : (value < 0x100) ? 2 : (value < 0x1000) ? 3 : 4; - if (outputEnd - outputBufferCount < len + 4) - { - return false; - } - - outputBuffer[outputBufferCount++] = '&'; - outputBuffer[outputBufferCount++] = '#'; - outputBuffer[outputBufferCount++] = 'x'; - - var offset = outputBufferCount + len; - while (value != 0) - { - var digit = value & 0xF; - outputBuffer[--offset] = (char)(digit + (digit < 10 ? '0' : 'A' - 10)); - value >>= 4; - } - outputBufferCount += len; - - outputBuffer[outputBufferCount++] = ';'; - } - } - else - { - var substitute = AsciiEncoderFallback.GetCharacterFallback(ch); - - if (substitute != null) - { - if (outputEnd - outputBufferCount < substitute.Length) - { - return false; - } - - substitute.CopyTo(0, outputBuffer, outputBufferCount, substitute.Length); - outputBufferCount += substitute.Length; - } - else - { - InternalDebug.Assert(outputEnd - outputBufferCount > 0); - - - - outputBuffer[outputBufferCount++] = ch; - } - } - - return true; - } - - - - void IDisposable.Dispose() - { - if (output != null /*&& this.output is IDisposable*/) - { - ((IDisposable)output).Dispose(); - } - - output = null; - wrapBuffer = null; - - GC.SuppressFinalize(this); - } - - - - bool IRestartable.CanRestart() - { - if (output is IRestartable) - { - return ((IRestartable)output).CanRestart(); - } - - return false; - } - - - - void IRestartable.Restart() - { - InternalDebug.Assert(((IRestartable)this).CanRestart()); - - ((IRestartable)output).Restart(); - - Reinitialize(); - } - - - - void IRestartable.DisableRestart() - { - if (output is IRestartable) - { - ((IRestartable)output).DisableRestart(); - } - } - - - void IReusable.Initialize(object newSourceOrDestination) - { - InternalDebug.Assert(output is IReusable); - - ((IReusable)output).Initialize(newSourceOrDestination); - - Reinitialize(); - } - } -} - diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextParser.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextParser.cs deleted file mode 100644 index 322f676dd..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextParser.cs +++ /dev/null @@ -1,709 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters.Internal.Text -{ - using System; - using Data.Internal; - - - internal class TextParser : IDisposable - { - - protected ConverterInput input; - protected bool endOfFile; - - protected char[] parseBuffer; - protected int parseStart; - protected int parseCurrent; - protected int parseEnd; - protected int parseThreshold = 1; - - // current token - protected TextTokenBuilder tokenBuilder; - protected TextToken token; - - protected bool unwrapFlowed; - protected bool unwrapDelSpace; - - // line state - protected bool lastSpace; - protected int lineCount; - - // 2646 decoding state - protected bool quotingExpected = true; - protected int quotingLevel; - protected int lastLineQuotingLevel; - protected bool lastLineFlowed; - protected bool signaturePossible = true; - - - public TextParser( - ConverterInput input, - bool unwrapFlowed, - bool unwrapDelSp, - int maxRuns, - bool testBoundaryConditions) - { - this.input = input; - - tokenBuilder = new TextTokenBuilder(null, maxRuns, testBoundaryConditions); - - token = tokenBuilder.Token; - - this.unwrapFlowed = unwrapFlowed; - unwrapDelSpace = unwrapDelSp; - } - - - public TextToken Token - { - get - { - InternalDebug.Assert(tokenBuilder.Valid); - return token; - } - } - - - public void Initialize(string fragment) - { - InternalDebug.Assert(input is ConverterBufferInput); - - (input as ConverterBufferInput).Initialize(fragment); - - endOfFile = false; - - parseBuffer = null; - parseStart = 0; - parseCurrent = 0; - parseEnd = 0; - parseThreshold = 1; - - tokenBuilder.Reset(); - - lastSpace = false; - lineCount = 0; - - quotingExpected = true; - quotingLevel = 0; - lastLineQuotingLevel = 0; - lastLineFlowed = false; - signaturePossible = true; - } - - - public TextTokenId Parse() - { - char ch, chT; - CharClass charClass, charClassT; - bool forceFlushToken; - int runStart; - - if (tokenBuilder.Valid) - { - // start the new token - - input.ReportProcessed(parseCurrent - parseStart); - parseStart = parseCurrent; - - tokenBuilder.Reset(); - - InternalDebug.Assert(tokenBuilder.TotalLength == 0); - } - - while (true) - { - InternalDebug.Assert(parseThreshold > 0); - - // try to read and decode more input data if necessary - - forceFlushToken = false; - - if (parseCurrent + parseThreshold > parseEnd) - { - if (!endOfFile) - { - if (!input.ReadMore(ref parseBuffer, ref parseStart, ref parseCurrent, ref parseEnd)) - { - // cannot decode more data until next input chunk is available - - // we may have incomplete token at this point - InternalDebug.Assert(!tokenBuilder.Valid); - - return TextTokenId.None; - } - - // NOTE: in case of success, ReadMore can move the token in the buffer and / or - // switch to a new buffer - - tokenBuilder.BufferChanged(parseBuffer, parseStart); - - var decodingInput = input as ConverterDecodingInput; - - if (decodingInput != null && decodingInput.EncodingChanged) - { - - - // reset the flag as required by ConverterInput protocol - decodingInput.EncodingChanged = false; - - // signal encoding change to the caller - return tokenBuilder.MakeEmptyToken(TextTokenId.EncodingChange, decodingInput.Encoding.CodePage); - } - - if (input.EndOfFile) - { - endOfFile = true; - } - - if (!endOfFile && parseEnd - parseStart < input.MaxTokenSize) - { - // we have successfuly read "something", ensure this something is above threshold - continue; - } - } - - // end of file or token is too long, need to flush the token as is (split) - forceFlushToken = true; - } - - // we should have read something unless this is EOF - InternalDebug.Assert(parseEnd > parseCurrent || forceFlushToken); - - // compact, so that the next character (or parseThreshold next characters) are valid. - - // get the next input character - - ch = parseBuffer[parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - - if (ParseSupport.InvalidUnicodeCharacter(charClass) || parseThreshold > 1) - { - - - - while (ParseSupport.InvalidUnicodeCharacter(charClass) && parseCurrent < parseEnd) - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - - - if (parseThreshold > 1 && parseCurrent + 1 < parseEnd) - { - InternalDebug.Assert(parseCurrent == parseStart); - InternalDebug.Assert(!ParseSupport.InvalidUnicodeCharacter(ParseSupport.GetCharClass(parseBuffer[parseCurrent]))); - - var src = parseCurrent + 1; - var dst = parseCurrent + 1; - - while (src < parseEnd && dst < parseCurrent + parseThreshold) - { - chT = parseBuffer[src]; - charClassT = ParseSupport.GetCharClass(chT); - - if (!ParseSupport.InvalidUnicodeCharacter(charClassT)) - { - if (src != dst) - { - InternalDebug.Assert(ParseSupport.InvalidUnicodeCharacter(ParseSupport.GetCharClass(parseBuffer[dst]))); - - parseBuffer[dst] = chT; // move source character - parseBuffer[src] = '\0'; // replace source character with invalid (zero) - } - - dst ++; - } - - src ++; - } - - if (src == parseEnd && parseCurrent + parseThreshold > dst) - { - Array.Copy(parseBuffer, parseCurrent, parseBuffer, parseEnd - (dst - parseCurrent), dst - parseCurrent); - - parseCurrent = parseEnd - (dst - parseCurrent); - - // reporting all invalid characters consumed - input.ReportProcessed(parseCurrent - parseStart); - parseStart = parseCurrent; - } - } - - - if (parseCurrent + parseThreshold > parseEnd) - { - // we still below threshold... - - if (!forceFlushToken) - { - // go back and try to read more - continue; - } - - // this is the end of file - - if (parseCurrent == parseEnd && !tokenBuilder.IsStarted && endOfFile) - { - // EOF and token is empty, just return EOF token - break; - } - - // this is the end of file, we cannot make it above threshold but still have some input data. - } - - // reset the threshold to its default value - parseThreshold = 1; - } - - // now parse the buffer content - - runStart = parseCurrent; - - InternalDebug.Assert(!tokenBuilder.IsStarted); - - tokenBuilder.StartText(runStart); - - while (tokenBuilder.PrepareToAddMoreRuns(9, runStart, RunKind.Text)) - { - while (ParseSupport.TextUriCharacter(charClass)) - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - - if (ParseSupport.TextNonUriCharacter(charClass)) - { - if (parseCurrent != runStart) - { - // we have nonempty NWSP run - - AddTextRun(RunTextType.NonSpace, runStart, parseCurrent); - } - - runStart = parseCurrent; - - do - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - while (ParseSupport.NbspCharacter(charClass)); - - AddTextRun(RunTextType.NonSpace, runStart, parseCurrent); - } - else if (ParseSupport.WhitespaceCharacter(charClass)) - { - if (parseCurrent != runStart) - { - // we have nonempty NWSP run - - AddTextRun(RunTextType.NonSpace, runStart, parseCurrent); - } - - runStart = parseCurrent; - - if (ch == ' ') - { - // ordinary space - - chT = parseBuffer[parseCurrent + 1]; - charClassT = ParseSupport.GetCharClass(chT); - - if (!ParseSupport.WhitespaceCharacter(charClassT)) - { - // add single space to text run - - ch = chT; - charClass = charClassT; - - parseCurrent ++; - - AddTextRun(RunTextType.Space, runStart, parseCurrent); - - runStart = parseCurrent; - - continue; - } - } - - // this is a potentially collapsable whitespace, accumulate whitespace run(s) - - ParseWhitespace(ch, charClass); - - if (parseThreshold > 1) - { - // terminate the text parse loop to read more data - break; - } - - runStart = parseCurrent; - - ch = parseBuffer[parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - else if (ParseSupport.NbspCharacter(charClass)) - { - if (parseCurrent != runStart) - { - AddTextRun(RunTextType.NonSpace, runStart, parseCurrent); - } - - runStart = parseCurrent; - - do - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - while (ParseSupport.NbspCharacter(charClass)); - - AddTextRun(RunTextType.Nbsp, runStart, parseCurrent); - } - else - { - InternalDebug.Assert(ParseSupport.InvalidUnicodeCharacter(charClass)); - - // finish the "non-whitespace" run - - if (parseCurrent != runStart) - { - AddTextRun(RunTextType.NonSpace, runStart, parseCurrent); - } - - if (parseCurrent >= parseEnd) - { - // end of available input (EOB), flush the current text token - break; - } - - // this is just an embedded invalid character, skip any such invalid - // characters and try to continue collecting text - - do - { - ch = parseBuffer[++parseCurrent]; - charClass = ParseSupport.GetCharClass(ch); - } - while (ParseSupport.InvalidUnicodeCharacter(charClass) && parseCurrent < parseEnd); - } - - // prepare for a new run - - runStart = parseCurrent; - } - - if (token.IsEmpty) - { - // text token is empty, we need more data - - tokenBuilder.Reset(); // reset open text... - - // reporting everything below parseCurrent consumed - input.ReportProcessed(parseCurrent - parseStart); - parseStart = parseCurrent; - continue; - } - - // finish the current text token, return anything we have collected so far - - tokenBuilder.EndText(); - - return (TextTokenId)token.TokenId; - } - - return tokenBuilder.MakeEmptyToken(TextTokenId.EndOfFile); - } - - - - void IDisposable.Dispose() - { - if (input != null /*&& this.input is IDisposable*/) - { - ((IDisposable)input).Dispose(); - } - - input = null; - parseBuffer = null; - token = null; - tokenBuilder = null; - - GC.SuppressFinalize(this); - } - - - private void ParseWhitespace(char ch, CharClass charClass) - { - CharClass charClassT; - var runStart = parseCurrent; - - // parse whitespace - - do - { - switch (ch) - { - case ' ': - do - { - ch = parseBuffer[++parseCurrent]; - } - while (ch == ' '); - - AddTextRun(RunTextType.Space, runStart, parseCurrent); - break; - - case '\r': - - if (parseBuffer[parseCurrent + 1] != '\n') - { - charClassT = ParseSupport.GetCharClass(parseBuffer[parseCurrent + 1]); - - if (ParseSupport.InvalidUnicodeCharacter(charClassT)) - { - if (!endOfFile || parseCurrent + 1 < parseEnd) - { - - parseThreshold = 2; - break; - } - - // EOF - there is no LF - } - - // valid character that is not LF or EOF - no need to skip LF - } - else - { - // skip LF - parseCurrent ++; - } - - ch = parseBuffer[++parseCurrent]; - - AddTextRun(RunTextType.NewLine, runStart, parseCurrent); - break; - - case '\n': - - // this is a standalone LF, count as CRLF - - ch = parseBuffer[++parseCurrent]; - - AddTextRun(RunTextType.NewLine, runStart, parseCurrent); - break; - - case '\t': - - do - { - ch = parseBuffer[++parseCurrent]; - } - while (ch == '\t'); - - AddTextRun(RunTextType.Tabulation, runStart, parseCurrent); - break; - - default: - - InternalDebug.Assert(ch == '\v' || ch == '\f'); - - do - { - ch = parseBuffer[++parseCurrent]; - } - while (ch == '\v' || ch == '\f'); - - AddTextRun(RunTextType.UnusualWhitespace, runStart, parseCurrent); - break; - } - - charClass = ParseSupport.GetCharClass(ch); - - runStart = parseCurrent; - } - while (ParseSupport.WhitespaceCharacter(charClass) && tokenBuilder.PrepareToAddMoreRuns(4, runStart, RunKind.Text) && parseThreshold == 1); - } - - private void AddTextRun(RunTextType textType, int runStart, int runEnd) - { - if (!unwrapFlowed) - { - // just add the run - tokenBuilder.AddTextRun(textType, runStart, runEnd); - return; - } - - // do unwrapping preprocessing - AddTextRunUnwrap(textType, runStart, runEnd); - } - - - private void AddTextRunUnwrap(RunTextType textType, int runStart, int runEnd) - { - switch (textType) - { - case RunTextType.NewLine: - - if (!lastSpace || (signaturePossible && lineCount == 3)) - { - lastLineFlowed = false; - tokenBuilder.AddTextRun(textType, runStart, runEnd); - } - else - { - lastLineFlowed = true; - } - - lineCount = 0; - lastSpace = false; - signaturePossible = true; - quotingExpected = true; - - lastLineQuotingLevel = quotingLevel; - quotingLevel = 0; - break; - - case RunTextType.Space: - case RunTextType.UnusualWhitespace: - - if (quotingExpected) - { - InternalDebug.Assert(lineCount == 0); - - runStart ++; // skip first space at the beginning of line - - // need to add invalid run to keep it contigous - tokenBuilder.SkipRunIfNecessary(runStart, RunKind.Text); - - if (lastLineQuotingLevel != quotingLevel) - { - if (lastLineFlowed) - { - tokenBuilder.AddLiteralTextRun(RunTextType.NewLine, runStart, runStart, '\n'); - } - - tokenBuilder.AddSpecialRun(TextRunKind.QuotingLevel, runStart, quotingLevel); - lastLineQuotingLevel = quotingLevel; - } - - quotingExpected = false; - } - - InternalDebug.Assert(lineCount != 0 || lastLineQuotingLevel == quotingLevel); - - if (runStart != runEnd) - { - lineCount += runEnd - runStart; - lastSpace = true; - - tokenBuilder.AddTextRun(textType, runStart, runEnd); - - if (lineCount != 3 || runEnd - runStart != 1) - { - signaturePossible = false; - } - } - - break; - - case RunTextType.Tabulation: - - if (quotingExpected) - { - InternalDebug.Assert(lineCount == 0); - - if (lastLineQuotingLevel != quotingLevel) - { - if (lastLineFlowed) - { - tokenBuilder.AddLiteralTextRun(RunTextType.NewLine, runStart, runStart, '\n'); - } - - tokenBuilder.AddSpecialRun(TextRunKind.QuotingLevel, runStart, quotingLevel); - lastLineQuotingLevel = quotingLevel; - } - - quotingExpected = false; - } - - InternalDebug.Assert(lineCount != 0 || lastLineQuotingLevel == quotingLevel); - - tokenBuilder.AddTextRun(textType, runStart, runEnd); - - lineCount += runEnd - runStart; - - lastSpace = false; - signaturePossible = false; - - break; - - case RunTextType.Nbsp: - case RunTextType.NonSpace: - - if (quotingExpected) - { - InternalDebug.Assert(lineCount == 0); - - while (runStart != runEnd && parseBuffer[runStart] == '>') - { - quotingLevel ++; - runStart ++; - } - - // we may have skipped some stuff, in such case need to add invalid run to keep it contigous - tokenBuilder.SkipRunIfNecessary(runStart, RunKind.Text); - - if (runStart != runEnd) - { - // end of quotation, check the quoting level - - if (lastLineQuotingLevel != quotingLevel) - { - if (lastLineFlowed) - { - tokenBuilder.AddLiteralTextRun(RunTextType.NewLine, runStart, runStart, '\n'); - } - - tokenBuilder.AddSpecialRun(TextRunKind.QuotingLevel, runStart, quotingLevel); - lastLineQuotingLevel = quotingLevel; - } - - quotingExpected = false; - } - } - - if (runStart != runEnd) - { - InternalDebug.Assert(lineCount != 0 || lastLineQuotingLevel == quotingLevel); - - tokenBuilder.AddTextRun(textType, runStart, runEnd); - - lineCount += runEnd - runStart; - lastSpace = false; - - if (lineCount > 2 || parseBuffer[runStart] != '-' || (runEnd - runStart == 2 && parseBuffer[runStart + 1] != '-')) - { - signaturePossible = false; - } - } - - break; - - default: - - InternalDebug.Assert(false, "unexpected run textType"); - break; - } - } - } -} - diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextToTextConverter.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextToTextConverter.cs deleted file mode 100644 index e96956330..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextToTextConverter.cs +++ /dev/null @@ -1,250 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters.Internal.Text -{ - using System; - using System.IO; - using System.Text; - using Data.Internal; - using Globalization; - - - internal class TextToTextConverter : IProducerConsumer, IDisposable - { - protected TextParser parser; - protected bool endOfFile; - - protected TextOutput output; - protected bool convertFragment; - - protected int lineLength; - protected int newLines; - protected int spaces; - protected int nbsps; - protected bool paragraphStarted; - - protected bool treatNbspAsBreakable; - - private bool started; - - protected Injection injection; - - - public TextToTextConverter( - TextParser parser, - TextOutput output, - Injection injection, - bool convertFragment, - bool treatNbspAsBreakable, - Stream traceStream, - bool traceShowTokenNum, - int traceStopOnTokenNum) - { - this.treatNbspAsBreakable = treatNbspAsBreakable; - - this.convertFragment = convertFragment; - - this.output = output; - this.parser = parser; - - if (!this.convertFragment) - { - this.injection = injection; - } - } - - public void Initialize(string fragment) - { - parser.Initialize(fragment); - - endOfFile = false; - - lineLength = 0; - newLines = 0; - spaces = 0; - nbsps = 0; - paragraphStarted = false; - started = false; - } - - - public void Run() - { - if (endOfFile) - { - // nothing to do after the end of file. - return; - } - - var tokenId = parser.Parse(); - - if (TextTokenId.None == tokenId) - { - return; - } - - Process(tokenId); - } - - public bool Flush() - { - if (!endOfFile) - { - Run(); - } - - return endOfFile; - } - - - protected void Process(TextTokenId tokenId) - { - if (!started) - { - if (!convertFragment) - { - output.OpenDocument(); - - if (injection != null && injection.HaveHead) - { - injection.Inject(true, output); - } - } - - output.SetQuotingLevel(0); - started = true; - } - - switch (tokenId) - { - case TextTokenId.Text: - - OutputFragmentSimple(parser.Token); - break; - - case TextTokenId.EncodingChange: - - if (!convertFragment) - { - if (output.OutputCodePageSameAsInput) - { - var codePage = parser.Token.Argument; - - #if DEBUG - Encoding newOutputEncoding; - // we should have already checked this in parser before reporting change - InternalDebug.Assert(Charset.TryGetEncoding(codePage, out newOutputEncoding)); - #endif - - output.OutputEncoding = Charset.GetEncoding(codePage); - } - } - break; - - case TextTokenId.EndOfFile: - - if (!convertFragment) - { - if (injection != null && injection.HaveTail) - { - if (!output.LineEmpty) - { - output.OutputNewLine(); - } - - injection.Inject(false, output); - } - - output.Flush(); - } - else - { - output.CloseParagraph(); - } - - endOfFile = true; - - break; - } - } - - - private void OutputFragmentSimple(TextToken token) - { - foreach (var run in token.Runs) - { - if (run.IsTextRun) - { - switch (run.TextType) - { - case RunTextType.NewLine: - - output.OutputNewLine(); - break; - - case RunTextType.Space: - case RunTextType.UnusualWhitespace: - - output.OutputSpace(run.Length); - break; - - case RunTextType.Tabulation: - - output.OutputTabulation(run.Length); - break; - - case RunTextType.Nbsp: - - if (treatNbspAsBreakable) - { - output.OutputSpace(run.Length); - } - else - { - output.OutputNbsp(run.Length); - } - break; - - case RunTextType.NonSpace: - - // InternalDebug.Assert(run.IsNormal); - output.OutputNonspace(run.RawBuffer, run.RawOffset, run.RawLength, TextMapping.Unicode); - break; - - default: - - InternalDebug.Assert(false, "unexpected run text type"); - break; - } - } - else if (run.IsSpecial && run.Kind == (uint)TextRunKind.QuotingLevel) - { - output.SetQuotingLevel((ushort)run.Value); - } - } - } - - - void IDisposable.Dispose() - { - if (parser != null /*&& this.parser is IDisposable*/) - { - ((IDisposable)parser).Dispose(); - } - - if (!convertFragment && output != null && output is IDisposable) - { - ((IDisposable)output).Dispose(); - } - parser = null; - output = null; - GC.SuppressFinalize(this); - } - } -} diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextToken.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextToken.cs deleted file mode 100644 index 3ddae0399..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextToken.cs +++ /dev/null @@ -1,42 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters.Internal.Text -{ - internal enum TextTokenId : byte - { - None = 0, - EndOfFile = TokenId.EndOfFile, - Text = TokenId.Text, - EncodingChange = TokenId.EncodingChange, - } - - - internal enum TextRunKind : uint - { - Invalid = 0, - - Text = RunKind.Text, - QuotingLevel = (10u << 24), - } - - - internal class TextToken : Token - { - - public TextToken() - { - // this.Reset(); - } - - - public new TextTokenId TokenId => (TextTokenId)tokenId; - } -} - diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextTokenBuilder.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextTokenBuilder.cs deleted file mode 100644 index e12887b8f..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TEXT/TextTokenBuilder.cs +++ /dev/null @@ -1,59 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - - -namespace Microsoft.Exchange.Data.TextConverters.Internal.Text -{ - using Data.Internal; - - internal class TextTokenBuilder : TokenBuilder - { - public TextTokenBuilder(char[] buffer, int maxRuns, bool testBoundaryConditions) : - this(new TextToken(), buffer, maxRuns, testBoundaryConditions) - { - } - - public TextTokenBuilder(TextToken token, char[] buffer, int maxRuns, bool testBoundaryConditions) : - base(token, buffer, maxRuns, testBoundaryConditions) - { - } - - public new TextToken Token => (TextToken)base.Token; - - - public TextTokenId MakeEmptyToken(TextTokenId tokenId) - { - return (TextTokenId)base.MakeEmptyToken((TokenId)tokenId); - } - - public TextTokenId MakeEmptyToken(TextTokenId tokenId, int argument) - { - return (TextTokenId)base.MakeEmptyToken((TokenId)tokenId, argument); - } - - public void SkipRunIfNecessary(int start, RunKind skippedRunKind) - { - base.SkipRunIfNecessary(start, (uint)skippedRunKind); - } - - - public bool PrepareToAddMoreRuns(int numRuns, int start, RunKind skippedRunKind) - { - return base.PrepareToAddMoreRuns(numRuns, start, (uint)skippedRunKind); - } - - - public void AddSpecialRun(TextRunKind kind, int startEnd, int value) - { - InternalDebug.Assert(startEnd == tailOffset); - AddRun(RunType.Special, RunTextType.Unknown, (uint)kind, tailOffset, startEnd, value); - } - } -} - diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TextConverter.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TextConverter.cs deleted file mode 100644 index 6ab63c170..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TextConverter.cs +++ /dev/null @@ -1,318 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - - -namespace Microsoft.Exchange.Data.TextConverters -{ - using System; - using System.IO; - using Strings = CtsResources.TextConvertersStrings; - - - - internal interface IResultsFeedback - { - - - - void Set(ConfigParameter parameterId, object val); - } - - - - internal enum ConfigParameter : int - { - - InputEncoding, - OutputEncoding, - RtfCompressionMode, - RtfEncapsulation, - } - - - - - - - internal abstract class TextConverter : IResultsFeedback - { - internal bool testBoundaryConditions = false; - internal int inputBufferSize = 4096; - internal int outputBufferSize = 4096; - internal bool locked; - - - - - - - internal TextConverter() - { - } - - internal bool TestBoundaryConditions - { - get { return testBoundaryConditions; } - set { AssertNotLocked(); testBoundaryConditions = value; } - } - - - - - - - - - - - - - - public int InputStreamBufferSize - { - get { return inputBufferSize; } - set - { - AssertNotLocked(); - - if (value < 1024 || value > 80 * 1024) - { - throw new ArgumentOutOfRangeException("value", Strings.BufferSizeValueRange); - } - - inputBufferSize = value; - } - } - - - - - - - - - - - - - - public int OutputStreamBufferSize - { - get { return outputBufferSize; } - set - { - AssertNotLocked(); - - if (value < 1024 || value > 80 * 1024) - { - throw new ArgumentOutOfRangeException("value",Strings.BufferSizeValueRange); - } - - outputBufferSize = value; - } - } - - - - - - - - - - - - - - - - public void Convert(Stream sourceStream, Stream destinationStream) - { - if (destinationStream == null) - { - throw new ArgumentNullException("destinationStream"); - } - - - - Stream converter = new ConverterStream(sourceStream, this, ConverterStreamAccess.Read); - - var buf = new byte[outputBufferSize]; - - while (true) - { - var cnt = converter.Read(buf, 0, buf.Length); - if (0 == cnt) - { - break; - } - - destinationStream.Write(buf, 0, cnt); - } - - destinationStream.Flush(); - } - - - - - - - - - - - - - - - - public void Convert(Stream sourceStream, TextWriter destinationWriter) - { - if (destinationWriter == null) - { - throw new ArgumentNullException("destinationWriter"); - } - - - TextReader converter = new ConverterReader(sourceStream, this); - - var buf = new char[4096]; - - while (true) - { - var cnt = converter.Read(buf, 0, buf.Length); - if (0 == cnt) - { - break; - } - - destinationWriter.Write(buf, 0, cnt); - } - - destinationWriter.Flush(); - } - - - - - - - - - - - - - - - - - - public void Convert(TextReader sourceReader, Stream destinationStream) - { - if (destinationStream == null) - { - throw new ArgumentNullException("destinationStream"); - } - - - Stream converter = new ConverterStream(sourceReader, this); - - var buf = new byte[outputBufferSize]; - - while (true) - { - var cnt = converter.Read(buf, 0, buf.Length); - if (0 == cnt) - { - break; - } - - destinationStream.Write(buf, 0, cnt); - } - - destinationStream.Flush(); - } - - - - - - - - - - - - - - - - - - public void Convert(TextReader sourceReader, TextWriter destinationWriter) - { - if (destinationWriter == null) - { - throw new ArgumentNullException("destinationWriter"); - } - - - TextReader converter = new ConverterReader(sourceReader, this); - - var buf = new char[4096]; - - while (true) - { - var cnt = converter.Read(buf, 0, buf.Length); - if (0 == cnt) - { - break; - } - - destinationWriter.Write(buf, 0, cnt); - } - - destinationWriter.Flush(); - } - - - - internal abstract IProducerConsumer CreatePushChain(ConverterStream converterStream, Stream output); - internal abstract IProducerConsumer CreatePushChain(ConverterStream converterStream, TextWriter output); - internal abstract IProducerConsumer CreatePushChain(ConverterWriter converterWriter, Stream output); - internal abstract IProducerConsumer CreatePushChain(ConverterWriter converterWriter, TextWriter output); - - internal abstract IProducerConsumer CreatePullChain(Stream input, ConverterStream converterStream); - internal abstract IProducerConsumer CreatePullChain(TextReader input, ConverterStream converterStream); - internal abstract IProducerConsumer CreatePullChain(Stream input, ConverterReader converterReader); - internal abstract IProducerConsumer CreatePullChain(TextReader input, ConverterReader converterReader); - - - - internal virtual void SetResult(ConfigParameter parameterId, object val) - { - } - - void IResultsFeedback.Set(ConfigParameter parameterId, object val) - { - SetResult(parameterId, val); - } - - internal void AssertNotLocked() - { - if (locked) - { - throw new InvalidOperationException(Strings.ParametersCannotBeChangedAfterConverterObjectIsUsed); - } - } - } -} - diff --git a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TextConvertersDefaults.cs b/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TextConvertersDefaults.cs deleted file mode 100644 index b35f64ca1..000000000 --- a/SiteServer.Utils/ThirdParty/AntiXSS/TextConverters/TextConvertersDefaults.cs +++ /dev/null @@ -1,96 +0,0 @@ -// *************************************************************** -// -// Copyright (C) Microsoft Corporation. All rights reserved. -// -// -// ... -// -// *************************************************************** - -namespace Microsoft.Exchange.Data.TextConverters -{ - using Internal.Html; - - internal static class TextConvertersDefaults - { - - - private const int normalMinDecodeBytes = 64; - - private const int normalInitialTokenRuns = 64; - private const int normalMaxTokenRuns = 512; - - private const int normalInitialTokenBufferSize = 1024; - private const int normalMaxTokenSize = 4096; - - private const int normalInitialHtmlAttributes = 8; - private const int normalMaxHtmlAttributes = 128; - - private const int normalMaxHtmlNormalizerNesting = HtmlSupport.HtmlNestingLimit; - private const int normalMaxHtmlMetaRestartOffset = 4096; - - - - private const int boundaryMinDecodeBytes = 1; - - private const int boundaryInitialTokenRuns = 7; - private const int boundaryMaxTokenRuns = 16; - - private const int boundaryInitialTokenBufferSize = 32; - private const int boundaryMaxTokenSize = 128; - - private const int boundaryInitialHtmlAttributes = 1; - private const int boundaryMaxHtmlAttributes = 5; - - private const int boundaryMaxHtmlNormalizerNesting = 10; - private const int boundaryMaxHtmlMetaRestartOffset = 4096; - - - - public static int MinDecodeBytes(bool boundaryTest) - { - return boundaryTest ? boundaryMinDecodeBytes : normalMinDecodeBytes; - } - - public static int InitialTokenRuns(bool boundaryTest) - { - return boundaryTest ? boundaryInitialTokenRuns : normalInitialTokenRuns; - } - - public static int MaxTokenRuns(bool boundaryTest) - { - return boundaryTest ? boundaryMaxTokenRuns : normalMaxTokenRuns; - } - - public static int InitialTokenBufferSize(bool boundaryTest) - { - return boundaryTest ? boundaryInitialTokenBufferSize : normalInitialTokenBufferSize; - } - - public static int MaxTokenSize(bool boundaryTest) - { - return boundaryTest ? boundaryMaxTokenSize : normalMaxTokenSize; - } - - public static int InitialHtmlAttributes(bool boundaryTest) - { - return boundaryTest ? boundaryInitialHtmlAttributes : normalInitialHtmlAttributes; - } - - public static int MaxHtmlAttributes(bool boundaryTest) - { - return boundaryTest ? boundaryMaxHtmlAttributes : normalMaxHtmlAttributes; - } - - public static int MaxHtmlNormalizerNesting(bool boundaryTest) - { - return boundaryTest ? boundaryMaxHtmlNormalizerNesting : normalMaxHtmlNormalizerNesting; - } - - public static int MaxHtmlMetaRestartOffset(bool boundaryTest) - { - return boundaryTest ? boundaryMaxHtmlMetaRestartOffset : normalMaxHtmlMetaRestartOffset; - } - - } -} diff --git a/SiteServer.Utils/ThirdParty/Sgml/Html.dtd b/SiteServer.Utils/ThirdParty/Sgml/Html.dtd deleted file mode 100644 index 7c1e33a2a..000000000 --- a/SiteServer.Utils/ThirdParty/Sgml/Html.dtd +++ /dev/null @@ -1,1562 +0,0 @@ - - - - - ... - - - ... - - - - The URI used as a system identifier with the public identifier allows - the user agent to download the DTD and entity sets as needed. - - The FPI for the Strict HTML 4.01 DTD is: - - "-//W3C//DTD HTML 4.01//EN" - - This version of the strict DTD is: - - http://www.w3.org/TR/1999/REC-html401-19991224/strict.dtd - - Authors should use the Strict DTD unless they need the - presentation control for user agents that don't (adequately) - support style sheets. - - If you are writing a document that includes frames, use - the following FPI: - - "-//W3C//DTD HTML 4.01 Frameset//EN" - - This version of the frameset DTD is: - - http://www.w3.org/TR/1999/REC-html401-19991224/frameset.dtd - - ---> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]]> - - - - -]]> - - - - - -]]> - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -]]> - - - - - diff --git a/SiteServer.Utils/ThirdParty/Sgml/SgmlParser.cs b/SiteServer.Utils/ThirdParty/Sgml/SgmlParser.cs deleted file mode 100644 index fe55dfa0e..000000000 --- a/SiteServer.Utils/ThirdParty/Sgml/SgmlParser.cs +++ /dev/null @@ -1,2269 +0,0 @@ -using System; -using System.IO; -using System.Collections; -using System.Text; -using System.Net; -using System.Xml; -using System.Globalization; - -namespace SiteServer.Utils.ThirdParty.Sgml -{ - public enum LiteralType - { - CDATA, SDATA, PI - }; - - public class Entity - { - public const Char EOF = (char)65535; - public string Proxy; - public string Name; - public bool Internal; - public string PublicId; - public string Uri; - public string Literal; - public LiteralType LiteralType; - public Entity Parent; - public bool Html; - public int Line; - public char Lastchar; - public bool IsWhitespace; - - Encoding encoding; - Uri resolvedUri; - TextReader stm; - bool weOwnTheStream; - int lineStart; - int absolutePos; - - public Entity(string name, string pubid, string uri, string proxy) - { - Name = name; - PublicId = pubid; - Uri = uri; - Proxy = proxy; - Html = (name != null && StringUtilities.EqualsIgnoreCase(name, "html")); - } - - public Entity(string name, string literal) - { - Name = name; - Literal = literal; - Internal = true; - } - - public Entity(string name, Uri baseUri, TextReader stm, string proxy) - { - Name = name; - Internal = true; - this.stm = stm; - resolvedUri = baseUri; - Proxy = proxy; - Html = (string.Compare(name, "html", true, CultureInfo.InvariantCulture) == 0); - } - - public Uri ResolvedUri - { - get - { - if (resolvedUri != null) return resolvedUri; - else if (Parent != null) return Parent.ResolvedUri; - return null; - } - } - - public int LinePosition => absolutePos - lineStart + 1; - - public char ReadChar() - { - var ch = (char)stm.Read(); - if (ch == 0) - { - // convert nulls to whitespace, since they are not valid in XML anyway. - ch = ' '; - } - absolutePos++; - if (ch == 0xa) - { - IsWhitespace = true; - lineStart = absolutePos + 1; - Line++; - } - else if (ch == ' ' || ch == '\t') - { - IsWhitespace = true; - if (Lastchar == 0xd) - { - lineStart = absolutePos; - Line++; - } - } - else if (ch == 0xd) - { - IsWhitespace = true; - } - else - { - IsWhitespace = false; - if (Lastchar == 0xd) - { - Line++; - lineStart = absolutePos; - } - } - Lastchar = ch; - return ch; - } - - public void Open(Entity parent, Uri baseUri) - { - Parent = parent; - if (parent != null) Html = parent.Html; - Line = 1; - if (Internal) - { - if (Literal != null) - stm = new StringReader(Literal); - } - else if (Uri == null) - { - Error("Unresolvable entity '{0}'", Name); - } - else - { - if (baseUri != null) - { - resolvedUri = new Uri(baseUri, Uri); - } - else - { - resolvedUri = new Uri(Uri); - } - - Stream stream = null; - var e = Encoding.Default; - switch (resolvedUri.Scheme) - { - case "file": - { - var path = resolvedUri.LocalPath; - stream = new FileStream(path, FileMode.Open, FileAccess.Read); - } - break; - default: - //Console.WriteLine("Fetching:" + ResolvedUri.AbsoluteUri); - var wr = (HttpWebRequest)WebRequest.Create(ResolvedUri); - wr.UserAgent = "Mozilla/4.0 (compatible;);"; - wr.Timeout = 10000; // in case this is running in an ASPX page. - if (Proxy != null) wr.Proxy = new WebProxy(Proxy); - wr.PreAuthenticate = false; - // Pass the credentials of the process. - wr.Credentials = CredentialCache.DefaultCredentials; - - var resp = wr.GetResponse(); - var actual = resp.ResponseUri; - if (actual.AbsoluteUri != resolvedUri.AbsoluteUri) - { - resolvedUri = actual; - } - var contentType = resp.ContentType.ToLower(); - var mimeType = contentType; - var i = contentType.IndexOf(';'); - if (i >= 0) - { - mimeType = contentType.Substring(0, i); - } - if (StringUtilities.EqualsIgnoreCase(mimeType, "text/html")) - { - Html = true; - } - - i = contentType.IndexOf("charset"); - e = Encoding.Default; - if (i >= 0) - { - var j = contentType.IndexOf("=", i); - var k = contentType.IndexOf(";", j); - if (k < 0) k = contentType.Length; - if (j > 0) - { - j++; - var charset = contentType.Substring(j, k - j).Trim(); - try - { - e = Encoding.GetEncoding(charset); - } - catch (Exception) - { - } - } - } - stream = resp.GetResponseStream(); - break; - - } - weOwnTheStream = true; - var html = new HtmlStream(stream, e); - encoding = html.Encoding; - stm = html; - } - } - - public Encoding GetEncoding() - { - return encoding; - } - - public void Close() - { - if (weOwnTheStream) - stm.Close(); - } - - public char SkipWhitespace() - { - var ch = Lastchar; - while (ch != EOF && (ch == ' ' || ch == '\r' || ch == '\n' || ch == '\t')) - { - ch = ReadChar(); - } - return ch; - } - - public string ScanToken(StringBuilder sb, string term, bool nmtoken) - { - sb.Length = 0; - var ch = Lastchar; - if (nmtoken && ch != '_' && !Char.IsLetter(ch)) - { - throw new Exception( - $"Invalid name start character '{ch}'"); - } - while (ch != EOF && term.IndexOf(ch) < 0) - { - if (!nmtoken || ch == '_' || ch == '.' || ch == '-' || ch == ':' || Char.IsLetterOrDigit(ch)) - { - sb.Append(ch); - } - else - { - throw new Exception( - $"Invalid name character '{ch}'"); - } - ch = ReadChar(); - } - return sb.ToString(); - } - - public string ScanLiteral(StringBuilder sb, char quote) - { - sb.Length = 0; - var ch = ReadChar(); - while (ch != EOF && ch != quote) - { - if (ch == '&') - { - ch = ReadChar(); - if (ch == '#') - { - var charent = ExpandCharEntity(); - sb.Append(charent); - ch = Lastchar; - } - else - { - sb.Append('&'); - sb.Append(ch); - ch = ReadChar(); - } - } - else - { - sb.Append(ch); - ch = ReadChar(); - } - } - ReadChar(); // consume end quote. - return sb.ToString(); - } - - public string ScanToEnd(StringBuilder sb, string type, string terminators) - { - if (sb != null) sb.Length = 0; - var start = Line; - // This method scans over a chunk of text looking for the - // termination sequence specified by the 'terminators' parameter. - var ch = ReadChar(); - var state = 0; - var next = terminators[state]; - while (ch != EOF) - { - if (ch == next) - { - state++; - if (state >= terminators.Length) - { - // found it! - break; - } - next = terminators[state]; - } - else if (state > 0) - { - // char didn't match, so go back and see how much does still match. - var i = state - 1; - var newstate = 0; - while (i >= 0 && newstate == 0) - { - if (terminators[i] == ch) - { - // character is part of the terminators pattern, ok, so see if we can - // match all the way back to the beginning of the pattern. - var j = 1; - while (i - j >= 0) - { - if (terminators[i - j] != terminators[state - j]) - break; - j++; - } - if (j > i) - { - newstate = i + 1; - } - } - else - { - i--; - } - } - if (sb != null) - { - i = (i < 0) ? 1 : 0; - for (var k = 0; k <= state - newstate - i; k++) - { - sb.Append(terminators[k]); - } - if (i > 0) // see if we've matched this char or not - sb.Append(ch); // if not then append it to buffer. - } - state = newstate; - next = terminators[newstate]; - } - else - { - if (sb != null) sb.Append(ch); - } - ch = ReadChar(); - } - if (ch == 0) Error(type + " starting on line {0} was never closed", start); - ReadChar(); // consume last char in termination sequence. - if (sb != null) return sb.ToString(); - return ""; - } - - public string ExpandCharEntity() - { - var ch = ReadChar(); - var v = 0; - if (ch == 'x') - { - ch = ReadChar(); - for (; ch != EOF && ch != ';'; ch = ReadChar()) - { - var p = 0; - if (ch >= '0' && ch <= '9') - { - p = (int)(ch - '0'); - } - else if (ch >= 'a' && ch <= 'f') - { - p = (int)(ch - 'a') + 10; - } - else if (ch >= 'A' && ch <= 'F') - { - p = (int)(ch - 'A') + 10; - } - else - { - break;//we must be done! - //Error("Hex digit out of range '{0}'", (int)ch); - } - v = (v * 16) + p; - } - } - else - { - for (; ch != EOF && ch != ';'; ch = ReadChar()) - { - if (ch >= '0' && ch <= '9') - { - v = (v * 10) + (int)(ch - '0'); - } - else - { - break; // we must be done! - //Error("Decimal digit out of range '{0}'", (int)ch); - } - } - } - if (ch == 0) - { - Error("Premature {0} parsing entity reference", ch); - } - else if (ch == ';') - { - ReadChar(); - } - // HACK ALERT: IE and Netscape map the unicode characters - if (Html && v >= 0x80 & v <= 0x9F) - { - // This range of control characters is mapped to Windows-1252! - var size = CtrlMap.Length; - var i = v - 0x80; - var unicode = CtrlMap[i]; - return Convert.ToChar(unicode).ToString(); - } - return Convert.ToChar(v).ToString(); - } - - static int[] CtrlMap = new int[] { - // This is the windows-1252 mapping of the code points 0x80 through 0x9f. - 8364, 129, 8218, 402, 8222, 8230, 8224, 8225, 710, 8240, 352, 8249, 338, 141, - 381, 143, 144, 8216, 8217, 8220, 8221, 8226, 8211, 8212, 732, 8482, 353, 8250, - 339, 157, 382, 376 - }; - - public void Error(string msg) - { - throw new Exception(msg); - } - - public void Error(string msg, char ch) - { - var str = (ch == EOF) ? "EOF" : Char.ToString(ch); - throw new Exception(String.Format(msg, str)); - } - - public void Error(string msg, int x) - { - throw new Exception(String.Format(msg, x)); - } - - public void Error(string msg, string arg) - { - throw new Exception(String.Format(msg, arg)); - } - - public string Context() - { - var p = this; - var sb = new StringBuilder(); - while (p != null) - { - string msg; - if (p.Internal) - { - msg = $"\nReferenced on line {p.Line}, position {p.LinePosition} of internal entity '{p.Name}'"; - } - else - { - msg = - $"\nReferenced on line {p.Line}, position {p.LinePosition} of '{p.Name}' entity at [{p.ResolvedUri.AbsolutePath}]"; - } - sb.Append(msg); - p = p.Parent; - } - return sb.ToString(); - } - - public static bool IsLiteralType(string token) - { - return (token == "CDATA" || token == "SDATA" || token == "PI"); - } - - public void SetLiteralType(string token) - { - switch (token) - { - case "CDATA": - LiteralType = LiteralType.CDATA; - break; - case "SDATA": - LiteralType = LiteralType.SDATA; - break; - case "PI": - LiteralType = LiteralType.PI; - break; - } - } - } - - // This class decodes an HTML/XML stream correctly. - internal class HtmlStream : TextReader - { - Stream stm; - byte[] rawBuffer; - int rawPos; - int rawUsed; - Encoding encoding; - Decoder decoder; - char[] buffer; - int used; - int pos; - private const int BUFSIZE = 16384; - private const int EOF = -1; - - public HtmlStream(Stream stm, Encoding defaultEncoding) - { - if (defaultEncoding == null) defaultEncoding = Encoding.UTF8; // default is UTF8 - if (!stm.CanSeek) - { - // Need to be able to seek to sniff correctly. - stm = CopyToMemoryStream(stm); - } - this.stm = stm; - rawBuffer = new Byte[BUFSIZE]; - rawUsed = stm.Read(rawBuffer, 0, 4); // maximum byte order mark - buffer = new char[BUFSIZE]; - - // Check byte order marks - decoder = AutoDetectEncoding(rawBuffer, ref rawPos, rawUsed); - var bom = rawPos; - if (decoder == null) - { - decoder = defaultEncoding.GetDecoder(); - rawUsed += stm.Read(rawBuffer, 4, BUFSIZE - 4); - DecodeBlock(); - // Now sniff to see if there is an XML declaration or HTML tag. - var sd = SniffEncoding(); - if (sd != null) - { - decoder = sd; - } - } - - // Reset to get ready for Read() - this.stm.Seek(0, SeekOrigin.Begin); - pos = used = 0; - // skip bom - if (bom > 0) - { - stm.Read(rawBuffer, 0, bom); - } - rawPos = rawUsed = 0; - - } - - public Encoding Encoding => encoding; - - Stream CopyToMemoryStream(Stream s) - { - var size = 100000; // large heap is more efficient - var buffer = new byte[size]; - int len; - var r = new MemoryStream(); - while ((len = s.Read(buffer, 0, size)) > 0) - { - r.Write(buffer, 0, len); - } - r.Seek(0, SeekOrigin.Begin); - s.Close(); - return r; - } - - internal void DecodeBlock() - { - // shift current chars to beginning. - if (pos > 0) - { - if (pos < used) - { - Array.Copy(buffer, pos, buffer, 0, used - pos); - } - used -= pos; - pos = 0; - } - var len = decoder.GetCharCount(rawBuffer, rawPos, rawUsed - rawPos); - var available = buffer.Length - used; - if (available < len) - { - var newbuf = new char[buffer.Length + len]; - Array.Copy(buffer, pos, newbuf, 0, used - pos); - buffer = newbuf; - } - used = pos + decoder.GetChars(rawBuffer, rawPos, rawUsed - rawPos, buffer, pos); - rawPos = rawUsed; // consumed the whole buffer! - } - internal static Decoder AutoDetectEncoding(byte[] buffer, ref int index, int length) - { - if (4 <= (length - index)) - { - var w = (uint)buffer[index + 0] << 24 | (uint)buffer[index + 1] << 16 | (uint)buffer[index + 2] << 8 | (uint)buffer[index + 3]; - // see if it's a 4-byte encoding - switch (w) - { - case 0xfefffeff: - index += 4; - return new Ucs4DecoderBigEngian(); - - case 0xfffefffe: - index += 4; - return new Ucs4DecoderLittleEndian(); - - case 0x3c000000: - goto case 0xfefffeff; - - case 0x0000003c: - goto case 0xfffefffe; - } - w >>= 8; - if (w == 0xefbbbf) - { - index += 3; - return Encoding.UTF8.GetDecoder(); - } - w >>= 8; - switch (w) - { - case 0xfeff: - index += 2; - return Encoding.BigEndianUnicode.GetDecoder(); - - case 0xfffe: - index += 2; - return new UnicodeEncoding(false, false).GetDecoder(); - - case 0x3c00: - goto case 0xfeff; - - case 0x003c: - goto case 0xfffe; - } - } - return null; - } - private int ReadChar() - { - // Read only up to end of current buffer then stop. - if (pos < used) return buffer[pos++]; - return EOF; - } - private int PeekChar() - { - var ch = ReadChar(); - if (ch != EOF) - { - pos--; - } - return ch; - } - private bool SniffPattern(string pattern) - { - var ch = PeekChar(); - if (ch != pattern[0]) return false; - for (int i = 0, n = pattern.Length; ch != EOF && i < n; i++) - { - ch = ReadChar(); - var m = pattern[i]; - if (ch != m) - { - return false; - } - } - return true; - } - private void SniffWhitespace() - { - var ch = (char)PeekChar(); - while (ch == ' ' || ch == '\t' || ch == '\r' || ch == '\n') - { - var i = pos; - ch = (char)ReadChar(); - if (ch != ' ' && ch != '\t' && ch != '\r' && ch != '\n') - pos = i; - } - } - - private string SniffLiteral() - { - var quoteChar = PeekChar(); - if (quoteChar == '\'' || quoteChar == '"') - { - ReadChar();// consume quote char - var i = pos; - var ch = ReadChar(); - while (ch != EOF && ch != quoteChar) - { - ch = ReadChar(); - } - return (pos > i) ? new string(buffer, i, pos - i - 1) : ""; - } - return null; - } - private string SniffAttribute(string name) - { - SniffWhitespace(); - var id = SniffName(); - if (name == id) - { - SniffWhitespace(); - if (SniffPattern("=")) - { - SniffWhitespace(); - return SniffLiteral(); - } - } - return null; - } - private string SniffAttribute(out string name) - { - SniffWhitespace(); - name = SniffName(); - if (name != null) - { - SniffWhitespace(); - if (SniffPattern("=")) - { - SniffWhitespace(); - return SniffLiteral(); - } - } - return null; - } - private void SniffTerminator(string term) - { - var ch = ReadChar(); - var i = 0; - var n = term.Length; - while (i < n && ch != EOF) - { - if (term[i] == ch) - { - i++; - if (i == n) break; - } - else - { - i = 0; // reset. - } - ch = ReadChar(); - } - } - internal Decoder SniffEncoding() - { - Decoder decoder = null; - if (SniffPattern(""); - } - } - if (decoder == null) - { - return SniffMeta(); - } - return null; - } - - internal Decoder SniffMeta() - { - var i = ReadChar(); - while (i != EOF) - { - var ch = (char)i; - if (ch == '<') - { - var name = SniffName(); - if (name != null && StringUtilities.EqualsIgnoreCase(name, "meta")) - { - string httpequiv = null; - string content = null; - while (true) - { - var value = SniffAttribute(out name); - if (name == null) - { - break; - } - if (StringUtilities.EqualsIgnoreCase(name, "http-equiv")) - { - httpequiv = value; - } - else if (StringUtilities.EqualsIgnoreCase(name, "content")) - { - content = value; - } - } - if (httpequiv != null && StringUtilities.EqualsIgnoreCase(httpequiv, "content-type") && content != null) - { - var j = content.IndexOf("charset"); - if (j >= 0) - { - //charset=utf-8 - j = content.IndexOf("=", j); - if (j >= 0) - { - j++; - var k = content.IndexOf(";", j); - if (k < 0) k = content.Length; - var charset = content.Substring(j, k - j).Trim(); - try - { - var e = Encoding.GetEncoding(charset); - encoding = e; - return e.GetDecoder(); - } - catch - { - } - } - } - } - } - } - i = ReadChar(); - - } - return null; - } - - internal string SniffName() - { - var c = PeekChar(); - if (c == EOF) - return null; - var ch = (char)c; - var start = pos; - while (pos < used - 1 && (Char.IsLetterOrDigit(ch) || ch == '-' || ch == '_' || ch == ':')) - { - ch = buffer[++pos]; - } - if (start == pos) return null; - return new string(buffer, start, pos - start); - } - - internal void SkipWhitespace() - { - var ch = (char)PeekChar(); - while (pos < used - 1 && (ch == ' ' || ch == '\r' || ch == '\n')) - { - ch = buffer[++pos]; - } - } - internal void SkipTo(char what) - { - var ch = (char)PeekChar(); - while (pos < used - 1 && (ch != what)) - { - ch = buffer[++pos]; - } - } - internal string ParseAttribute() - { - SkipTo('='); - if (pos < used) - { - pos++; - SkipWhitespace(); - if (pos < used) - { - var quote = buffer[pos]; - pos++; - var start = pos; - SkipTo(quote); - if (pos < used) - { - var result = new string(buffer, start, pos - start); - pos++; - return result; - } - } - } - return null; - } - public override int Peek() - { - var result = Read(); - if (result != EOF) - { - pos--; - } - return result; - } - public override int Read() - { - if (pos == used) - { - rawUsed = stm.Read(rawBuffer, 0, rawBuffer.Length); - rawPos = 0; - if (rawUsed == 0) return EOF; - DecodeBlock(); - } - if (pos < used) return buffer[pos++]; - return -1; - } - public override int Read(char[] buffer, int start, int length) - { - if (pos == used) - { - rawUsed = stm.Read(rawBuffer, 0, rawBuffer.Length); - rawPos = 0; - if (rawUsed == 0) return -1; - DecodeBlock(); - } - if (pos < used) - { - length = Math.Min(used - pos, length); - Array.Copy(this.buffer, pos, buffer, start, length); - pos += length; - return length; - } - return 0; - } - - public override int ReadBlock(char[] buffer, int index, int count) - { - return Read(buffer, index, count); - } - // Read up to end of line, or full buffer, whichever comes first. - public int ReadLine(char[] buffer, int start, int length) - { - var i = 0; - var ch = ReadChar(); - while (ch != EOF) - { - buffer[i + start] = (char)ch; - i++; - if (i + start == length) - break; // buffer is full - - if (ch == '\r') - { - if (PeekChar() == '\n') - { - ch = ReadChar(); - buffer[i + start] = (char)ch; - i++; - } - break; - } - else if (ch == '\n') - { - break; - } - ch = ReadChar(); - } - return i; - } - - public override string ReadToEnd() - { - var buffer = new char[100000]; // large block heap is more efficient - var len = 0; - var sb = new StringBuilder(); - while ((len = Read(buffer, 0, buffer.Length)) > 0) - { - sb.Append(buffer, 0, len); - } - return sb.ToString(); - } - public override void Close() - { - stm.Close(); - } - } - internal abstract class Ucs4Decoder : Decoder - { - internal byte[] temp = new byte[4]; - internal int tempBytes = 0; - public override int GetCharCount(byte[] bytes, int index, int count) - { - return (count + tempBytes) / 4; - } - internal abstract int GetFullChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex); - public override int GetChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) - { - var i = tempBytes; - - if (tempBytes > 0) - { - for (; i < 4; i++) - { - temp[i] = bytes[byteIndex]; - byteIndex++; - byteCount--; - } - i = 1; - GetFullChars(temp, 0, 4, chars, charIndex); - charIndex++; - } - else - i = 0; - i = GetFullChars(bytes, byteIndex, byteCount, chars, charIndex) + i; - - var j = (tempBytes + byteCount) % 4; - byteCount += byteIndex; - byteIndex = byteCount - j; - tempBytes = 0; - - if (byteIndex >= 0) - for (; byteIndex < byteCount; byteIndex++) - { - temp[tempBytes] = bytes[byteIndex]; - tempBytes++; - } - return i; - } - internal char UnicodeToUTF16(UInt32 code) - { - byte lowerByte, higherByte; - lowerByte = (byte)(0xD7C0 + (code >> 10)); - higherByte = (byte)(0xDC00 | code & 0x3ff); - return ((char)((higherByte << 8) | lowerByte)); - } - } - internal class Ucs4DecoderBigEngian : Ucs4Decoder - { - internal override int GetFullChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) - { - UInt32 code; - int i, j; - byteCount += byteIndex; - for (i = byteIndex, j = charIndex; i + 3 < byteCount; ) - { - code = (UInt32)(((bytes[i + 3]) << 24) | (bytes[i + 2] << 16) | (bytes[i + 1] << 8) | (bytes[i])); - if (code > 0x10FFFF) - { - throw new Exception("Invalid character 0x" + code.ToString("x") + " in encoding"); - } - else if (code > 0xFFFF) - { - chars[j] = UnicodeToUTF16(code); - j++; - } - else - { - if (code >= 0xD800 && code <= 0xDFFF) - { - throw new Exception("Invalid character 0x" + code.ToString("x") + " in encoding"); - } - else - { - chars[j] = (char)code; - } - } - j++; - i += 4; - } - return j - charIndex; - } - }; - internal class Ucs4DecoderLittleEndian : Ucs4Decoder - { - internal override int GetFullChars(byte[] bytes, int byteIndex, int byteCount, char[] chars, int charIndex) - { - UInt32 code; - int i, j; - byteCount += byteIndex; - for (i = byteIndex, j = charIndex; i + 3 < byteCount; ) - { - code = (UInt32)(((bytes[i]) << 24) | (bytes[i + 1] << 16) | (bytes[i + 2] << 8) | (bytes[i + 3])); - if (code > 0x10FFFF) - { - throw new Exception("Invalid character 0x" + code.ToString("x") + " in encoding"); - } - else if (code > 0xFFFF) - { - chars[j] = UnicodeToUTF16(code); - j++; - } - else - { - if (code >= 0xD800 && code <= 0xDFFF) - { - throw new Exception("Invalid character 0x" + code.ToString("x") + " in encoding"); - } - else - { - chars[j] = (char)code; - } - } - j++; - i += 4; - } - return j - charIndex; - } - } - - public class ElementDecl - { - public ElementDecl(string name, bool sto, bool eto, ContentModel cm, string[] inclusions, string[] exclusions) - { - Name = name; - StartTagOptional = sto; - EndTagOptional = eto; - ContentModel = cm; - Inclusions = inclusions; - Exclusions = exclusions; - } - public string Name; - public bool StartTagOptional; - public bool EndTagOptional; - public ContentModel ContentModel; - public string[] Inclusions; - public string[] Exclusions; - public AttList AttList; - - public AttDef FindAttribute(string name) - { - return AttList[name.ToUpper()]; - } - - public void AddAttDefs(AttList list) - { - if (AttList == null) - { - AttList = list; - } - else - { - foreach (AttDef a in list) - { - if (AttList[a.Name] == null) - { - AttList.Add(a); - } - } - } - } - - public bool CanContain(string name, SgmlDtd dtd) - { - // return true if this element is allowed to contain the given element. - if (Exclusions != null) - { - foreach (var s in Exclusions) - { - if ((object)s == (object)name) // XmlNameTable optimization - return false; - } - } - if (Inclusions != null) - { - foreach (var s in Inclusions) - { - if ((object)s == (object)name) // XmlNameTable optimization - return true; - } - } - return ContentModel.CanContain(name, dtd); - } - } - - public enum DeclaredContent - { - Default, CDATA, RCDATA, EMPTY - } - - public class ContentModel - { - public DeclaredContent DeclaredContent; - public int CurrentDepth; - public Group Model; - - public ContentModel() - { - Model = new Group(null); - } - - public void PushGroup() - { - Model = new Group(Model); - CurrentDepth++; - } - - public int PopGroup() - { - if (CurrentDepth == 0) return -1; - CurrentDepth--; - Model.Parent.AddGroup(Model); - Model = Model.Parent; - return CurrentDepth; - } - - public void AddSymbol(string sym) - { - Model.AddSymbol(sym); - } - - public void AddConnector(char c) - { - Model.AddConnector(c); - } - - public void AddOccurrence(char c) - { - Model.AddOccurrence(c); - } - - public void SetDeclaredContent(string dc) - { - switch (dc) - { - case "EMPTY": - DeclaredContent = DeclaredContent.EMPTY; - break; - case "RCDATA": - DeclaredContent = DeclaredContent.RCDATA; - break; - case "CDATA": - DeclaredContent = DeclaredContent.CDATA; - break; - default: - throw new Exception( - $"Declared content type '{dc}' is not supported"); - } - } - - public bool CanContain(string name, SgmlDtd dtd) - { - if (DeclaredContent != DeclaredContent.Default) - return false; // empty or text only node. - return Model.CanContain(name, dtd); - } - } - - public enum GroupType - { - None, And, Or, Sequence - }; - - public enum Occurrence - { - Required, Optional, ZeroOrMore, OneOrMore - } - - public class Group - { - public Group Parent; - public ArrayList Members; - public GroupType GroupType; - public Occurrence Occurrence; - public bool Mixed; - - public bool TextOnly => Mixed && Members.Count == 0; - - public Group(Group parent) - { - Parent = parent; - Members = new ArrayList(); - GroupType = GroupType.None; - Occurrence = Occurrence.Required; - } - public void AddGroup(Group g) - { - Members.Add(g); - } - public void AddSymbol(string sym) - { - if (sym == "#PCDATA") - { - Mixed = true; - } - else - { - Members.Add(sym); - } - } - public void AddConnector(char c) - { - if (!Mixed && Members.Count == 0) - { - throw new Exception( - $"Missing token before connector '{c}'." - ); - } - var gt = GroupType.None; - switch (c) - { - case ',': - gt = GroupType.Sequence; - break; - case '|': - gt = GroupType.Or; - break; - case '&': - gt = GroupType.And; - break; - } - if (GroupType != GroupType.None && GroupType != gt) - { - throw new Exception( - $"Connector '{c}' is inconsistent with {GroupType.ToString()} group." - ); - } - GroupType = gt; - } - - public void AddOccurrence(char c) - { - var o = Occurrence.Required; - switch (c) - { - case '?': - o = Occurrence.Optional; - break; - case '+': - o = Occurrence.OneOrMore; - break; - case '*': - o = Occurrence.ZeroOrMore; - break; - } - Occurrence = o; - } - - // Rough approximation - this is really assuming an "Or" group - public bool CanContain(string name, SgmlDtd dtd) - { - // Do a simple search of members. - foreach (var obj in Members) - { - if (obj is String) - { - if (obj == (object)name) // XmlNameTable optimization - return true; - } - } - // didn't find it, so do a more expensive search over child elements - // that have optional start tags and over child groups. - foreach (var obj in Members) - { - if (obj is String) - { - var s = (string)obj; - var e = dtd.FindElement(s); - if (e != null) - { - if (e.StartTagOptional) - { - // tricky case, the start tag is optional so element may be - // allowed inside this guy! - if (e.CanContain(name, dtd)) - return true; - } - } - } - else - { - var m = (Group)obj; - if (m.CanContain(name, dtd)) - return true; - } - } - return false; - } - } - - public enum AttributeType - { - DEFAULT, CDATA, ENTITY, ENTITIES, ID, IDREF, IDREFS, NAME, NAMES, NMTOKEN, NMTOKENS, - NUMBER, NUMBERS, NUTOKEN, NUTOKENS, NOTATION, ENUMERATION - } - - public enum AttributePresence - { - DEFAULT, FIXED, REQUIRED, IMPLIED - } - - public class AttDef - { - public string Name; - public AttributeType Type; - public string[] EnumValues; - public string Default; - public AttributePresence Presence; - - public AttDef(string name) - { - Name = name; - } - - - public void SetType(string type) - { - switch (type) - { - case "CDATA": - Type = AttributeType.CDATA; - break; - case "ENTITY": - Type = AttributeType.ENTITY; - break; - case "ENTITIES": - Type = AttributeType.ENTITIES; - break; - case "ID": - Type = AttributeType.ID; - break; - case "IDREF": - Type = AttributeType.IDREF; - break; - case "IDREFS": - Type = AttributeType.IDREFS; - break; - case "NAME": - Type = AttributeType.NAME; - break; - case "NAMES": - Type = AttributeType.NAMES; - break; - case "NMTOKEN": - Type = AttributeType.NMTOKEN; - break; - case "NMTOKENS": - Type = AttributeType.NMTOKENS; - break; - case "NUMBER": - Type = AttributeType.NUMBER; - break; - case "NUMBERS": - Type = AttributeType.NUMBERS; - break; - case "NUTOKEN": - Type = AttributeType.NUTOKEN; - break; - case "NUTOKENS": - Type = AttributeType.NUTOKENS; - break; - default: - throw new Exception("Attribute type '" + type + "' is not supported"); - } - } - - public bool SetPresence(string token) - { - var hasDefault = true; - if (token == "FIXED") - { - Presence = AttributePresence.FIXED; - } - else if (token == "REQUIRED") - { - Presence = AttributePresence.REQUIRED; - hasDefault = false; - } - else if (token == "IMPLIED") - { - Presence = AttributePresence.IMPLIED; - hasDefault = false; - } - else - { - throw new Exception($"Attribute value '{token}' not supported"); - } - return hasDefault; - } - } - - public class AttList : IEnumerable - { - Hashtable AttDefs; - - public AttList() - { - AttDefs = new Hashtable(); - } - - public void Add(AttDef a) - { - AttDefs.Add(a.Name, a); - } - - public AttDef this[string name] => (AttDef)AttDefs[name]; - - public IEnumerator GetEnumerator() - { - return AttDefs.Values.GetEnumerator(); - } - } - - public class SgmlDtd - { - public string Name; - - Hashtable elements; - Hashtable pentities; - Hashtable entities; - StringBuilder sb; - Entity current; - XmlNameTable nameTable; - - public SgmlDtd(string name, XmlNameTable nt) - { - nameTable = nt; - Name = name; - elements = new Hashtable(); - pentities = new Hashtable(); - entities = new Hashtable(); - sb = new StringBuilder(); - } - - public XmlNameTable NameTable => nameTable; - - public static SgmlDtd Parse(Uri baseUri, string name, string pubid, string url, string subset, string proxy, XmlNameTable nt) - { - var dtd = new SgmlDtd(name, nt); - if (url != null && url != string.Empty) - { - dtd.PushEntity(baseUri, new Entity(dtd.Name, pubid, url, proxy)); - } - if (subset != null && subset != string.Empty) - { - dtd.PushEntity(baseUri, new Entity(name, subset)); - } - try - { - dtd.Parse(); - } - catch (Exception e) - { - throw new Exception(e.Message + dtd.current.Context()); - } - return dtd; - } - public static SgmlDtd Parse(Uri baseUri, string name, string pubid, TextReader input, string subset, string proxy, XmlNameTable nt) - { - var dtd = new SgmlDtd(name, nt); - dtd.PushEntity(baseUri, new Entity(dtd.Name, baseUri, input, proxy)); - if (subset != null && subset != string.Empty) - { - dtd.PushEntity(baseUri, new Entity(name, subset)); - } - try - { - dtd.Parse(); - } - catch (Exception e) - { - throw new Exception(e.Message + dtd.current.Context()); - } - return dtd; - } - - public Entity FindEntity(string name) - { - return (Entity)entities[name]; - } - - public ElementDecl FindElement(string name) - { - return (ElementDecl)elements[name.ToUpper()]; - } - - //-------------------------------- Parser ------------------------- - void PushEntity(Uri baseUri, Entity e) - { - e.Open(current, baseUri); - current = e; - current.ReadChar(); - } - - void PopEntity() - { - if (current != null) current.Close(); - if (current.Parent != null) - { - current = current.Parent; - } - else - { - current = null; - } - } - - void Parse() - { - var ch = current.Lastchar; - while (true) - { - switch (ch) - { - case Entity.EOF: - PopEntity(); - if (current == null) - return; - ch = current.Lastchar; - break; - case ' ': - case '\n': - case '\r': - case '\t': - ch = current.ReadChar(); - break; - case '<': - ParseMarkup(); - ch = current.ReadChar(); - break; - case '%': - var e = ParseParameterEntity(WhiteSpace); - try - { - PushEntity(current.ResolvedUri, e); - } - catch (Exception ex) - { - // bugbug - need an error log. - Console.WriteLine(ex.Message + current.Context()); - } - ch = current.Lastchar; - break; - default: - current.Error("Unexpected character '{0}'", ch); - break; - } - } - } - - void ParseMarkup() - { - var ch = current.ReadChar(); - if (ch != '!') - { - current.Error("Found '{0}', but expecing declaration starting with '"); - } - else if (ch == '[') - { - ParseMarkedSection(); - } - else - { - var token = current.ScanToken(sb, WhiteSpace, true); - switch (token) - { - case "ENTITY": - ParseEntity(); - break; - case "ELEMENT": - ParseElementDecl(); - break; - case "ATTLIST": - ParseAttList(); - break; - default: - current.Error("Invalid declaration ' - current.ReadChar(); // move to next char. - var name = ScanName("["); - if (name == "INCLUDE") - { - ParseIncludeSection(); - } - else if (name == "IGNORE") - { - ParseIgnoreSection(); - } - else - { - current.Error("Unsupported marked section type '{0}'", name); - } - } - - void ParseIncludeSection() - { - throw new NotImplementedException("Include Section"); - } - - void ParseIgnoreSection() - { - var start = current.Line; - // - var ch = current.SkipWhitespace(); - if (ch != '[') current.Error("Expecting '[' but found {0}", ch); - current.ScanToEnd(sb, "Conditional Section", "]]>"); - } - - string ScanName(string term) - { - // skip whitespace, scan name (which may be parameter entity reference - // which is then expanded to a name) - var ch = current.SkipWhitespace(); - if (ch == '%') - { - var e = ParseParameterEntity(term); - ch = current.Lastchar; - // bugbug - need to support external and nested parameter entities - if (!e.Internal) throw new NotSupportedException("External parameter entity resolution"); - return e.Literal.Trim(); - } - else - { - return current.ScanToken(sb, term, true); - } - } - - Entity ParseParameterEntity(string term) - { - // almost the same as this.current.ScanToken, except we also terminate on ';' - var ch = current.ReadChar(); - var name = current.ScanToken(sb, ";" + term, false); - name = nameTable.Add(name); - if (current.Lastchar == ';') - current.ReadChar(); - var e = GetParameterEntity(name); - return e; - } - - Entity GetParameterEntity(string name) - { - var e = (Entity)pentities[name]; - if (e == null) current.Error("Reference to undefined parameter entity '{0}'", name); - return e; - } - - static string WhiteSpace = " \r\n\t"; - - void ParseEntity() - { - var ch = current.SkipWhitespace(); - var pe = (ch == '%'); - if (pe) - { - // parameter entity. - current.ReadChar(); // move to next char - ch = current.SkipWhitespace(); - } - var name = current.ScanToken(sb, WhiteSpace, true); - name = nameTable.Add(name); - ch = current.SkipWhitespace(); - Entity e = null; - if (ch == '"' || ch == '\'') - { - var literal = current.ScanLiteral(sb, ch); - e = new Entity(name, literal); - } - else - { - string pubid = null; - string extid = null; - var tok = current.ScanToken(sb, WhiteSpace, true); - if (Entity.IsLiteralType(tok)) - { - ch = current.SkipWhitespace(); - var literal = current.ScanLiteral(sb, ch); - e = new Entity(name, literal); - e.SetLiteralType(tok); - } - else - { - extid = tok; - if (extid == "PUBLIC") - { - ch = current.SkipWhitespace(); - if (ch == '"' || ch == '\'') - { - pubid = current.ScanLiteral(sb, ch); - } - else - { - current.Error("Expecting public identifier literal but found '{0}'", ch); - } - } - else if (extid != "SYSTEM") - { - current.Error("Invalid external identifier '{0}'. Expecing 'PUBLIC' or 'SYSTEM'.", extid); - } - string uri = null; - ch = current.SkipWhitespace(); - if (ch == '"' || ch == '\'') - { - uri = current.ScanLiteral(sb, ch); - } - else if (ch != '>') - { - current.Error("Expecting system identifier literal but found '{0}'", ch); - } - e = new Entity(name, pubid, uri, current.Proxy); - } - } - ch = current.SkipWhitespace(); - if (ch == '-') - ch = ParseDeclComments(); - if (ch != '>') - { - current.Error("Expecting end of entity declaration '>' but found '{0}'", ch); - } - if (pe) pentities.Add(e.Name, e); - else entities.Add(e.Name, e); - } - - void ParseElementDecl() - { - var ch = current.SkipWhitespace(); - var names = ParseNameGroup(ch, true); - ch = Char.ToUpper(current.SkipWhitespace()); - var sto = false; - var eto = false; - if (ch == 'O' || ch == '-') - { - sto = (ch == 'O'); // start tag optional? - current.ReadChar(); - ch = Char.ToUpper(current.SkipWhitespace()); - if (ch == 'O' || ch == '-') - { - eto = (ch == 'O'); // end tag optional? - ch = current.ReadChar(); - } - } - ch = current.SkipWhitespace(); - var cm = ParseContentModel(ch); - ch = current.SkipWhitespace(); - - string[] exclusions = null; - string[] inclusions = null; - - if (ch == '-') - { - ch = current.ReadChar(); - if (ch == '(') - { - exclusions = ParseNameGroup(ch, true); - ch = current.SkipWhitespace(); - } - else if (ch == '-') - { - ch = ParseDeclComment(false); - } - else - { - current.Error("Invalid syntax at '{0}'", ch); - } - } - - if (ch == '-') - ch = ParseDeclComments(); - - if (ch == '+') - { - ch = current.ReadChar(); - if (ch != '(') - { - current.Error("Expecting inclusions name group", ch); - } - inclusions = ParseNameGroup(ch, true); - ch = current.SkipWhitespace(); - } - - if (ch == '-') - ch = ParseDeclComments(); - - - if (ch != '>') - { - current.Error("Expecting end of ELEMENT declaration '>' but found '{0}'", ch); - } - - foreach (var name in names) - { - var atom = name.ToUpper(); - atom = nameTable.Add(name); - elements.Add(atom, new ElementDecl(atom, sto, eto, cm, inclusions, exclusions)); - } - } - - static string ngterm = " \r\n\t|,)"; - string[] ParseNameGroup(char ch, bool nmtokens) - { - var names = new ArrayList(); - if (ch == '(') - { - ch = current.ReadChar(); - ch = current.SkipWhitespace(); - while (ch != ')') - { - // skip whitespace, scan name (which may be parameter entity reference - // which is then expanded to a name) - ch = current.SkipWhitespace(); - if (ch == '%') - { - var e = ParseParameterEntity(ngterm); - PushEntity(current.ResolvedUri, e); - ParseNameList(names, nmtokens); - PopEntity(); - ch = current.Lastchar; - } - else - { - var token = current.ScanToken(sb, ngterm, nmtokens); - token = token.ToUpper(); - var atom = nameTable.Add(token); - names.Add(atom); - } - ch = current.SkipWhitespace(); - if (ch == '|' || ch == ',') ch = current.ReadChar(); - } - current.ReadChar(); // consume ')' - } - else - { - var name = current.ScanToken(sb, WhiteSpace, nmtokens); - name = name.ToUpper(); - name = nameTable.Add(name); - names.Add(name); - } - return (string[])names.ToArray(typeof(String)); - } - - void ParseNameList(ArrayList names, bool nmtokens) - { - var ch = current.Lastchar; - ch = current.SkipWhitespace(); - while (ch != Entity.EOF) - { - string name; - if (ch == '%') - { - var e = ParseParameterEntity(ngterm); - PushEntity(current.ResolvedUri, e); - ParseNameList(names, nmtokens); - PopEntity(); - ch = current.Lastchar; - } - else - { - name = current.ScanToken(sb, ngterm, true); - name = name.ToUpper(); - name = nameTable.Add(name); - names.Add(name); - } - ch = current.SkipWhitespace(); - if (ch == '|') - { - ch = current.ReadChar(); - ch = current.SkipWhitespace(); - } - } - } - - static string dcterm = " \r\n\t>"; - ContentModel ParseContentModel(char ch) - { - var cm = new ContentModel(); - if (ch == '(') - { - current.ReadChar(); - ParseModel(')', cm); - ch = current.ReadChar(); - if (ch == '?' || ch == '+' || ch == '*') - { - cm.AddOccurrence(ch); - current.ReadChar(); - } - } - else if (ch == '%') - { - var e = ParseParameterEntity(dcterm); - PushEntity(current.ResolvedUri, e); - cm = ParseContentModel(current.Lastchar); - PopEntity(); // bugbug should be at EOF. - } - else - { - var dc = ScanName(dcterm); - cm.SetDeclaredContent(dc); - } - return cm; - } - - static string cmterm = " \r\n\t,&|()?+*"; - void ParseModel(char cmt, ContentModel cm) - { - // Called when part of the model is made up of the contents of a parameter entity - var depth = cm.CurrentDepth; - var ch = current.Lastchar; - ch = current.SkipWhitespace(); - while (ch != cmt || cm.CurrentDepth > depth) // the entity must terminate while inside the content model. - { - if (ch == Entity.EOF) - { - current.Error("Content Model was not closed"); - } - if (ch == '%') - { - var e = ParseParameterEntity(cmterm); - PushEntity(current.ResolvedUri, e); - ParseModel(Entity.EOF, cm); - PopEntity(); - ch = current.SkipWhitespace(); - } - else if (ch == '(') - { - cm.PushGroup(); - current.ReadChar();// consume '(' - ch = current.SkipWhitespace(); - } - else if (ch == ')') - { - ch = current.ReadChar();// consume ')' - if (ch == '*' || ch == '+' || ch == '?') - { - cm.AddOccurrence(ch); - ch = current.ReadChar(); - } - if (cm.PopGroup() < depth) - { - current.Error("Parameter entity cannot close a paren outside it's own scope"); - } - ch = current.SkipWhitespace(); - } - else if (ch == ',' || ch == '|' || ch == '&') - { - cm.AddConnector(ch); - current.ReadChar(); // skip connector - ch = current.SkipWhitespace(); - } - else - { - string token; - if (ch == '#') - { - ch = current.ReadChar(); - token = "#" + current.ScanToken(sb, cmterm, true); // since '#' is not a valid name character. - } - else - { - token = current.ScanToken(sb, cmterm, true); - } - token = token.ToUpper(); - token = nameTable.Add(token);// atomize it. - ch = current.Lastchar; - if (ch == '?' || ch == '+' || ch == '*') - { - cm.PushGroup(); - cm.AddSymbol(token); - cm.AddOccurrence(ch); - cm.PopGroup(); - current.ReadChar(); // skip connector - ch = current.SkipWhitespace(); - } - else - { - cm.AddSymbol(token); - ch = current.SkipWhitespace(); - } - } - } - } - - void ParseAttList() - { - var ch = current.SkipWhitespace(); - var names = ParseNameGroup(ch, true); - var attlist = new AttList(); - ParseAttList(attlist, '>'); - foreach (var name in names) - { - var e = (ElementDecl)elements[name]; - if (e == null) - { - current.Error("ATTLIST references undefined ELEMENT {0}", name); - } - e.AddAttDefs(attlist); - } - } - - static string peterm = " \t\r\n>"; - void ParseAttList(AttList list, char term) - { - var ch = current.SkipWhitespace(); - while (ch != term) - { - if (ch == '%') - { - var e = ParseParameterEntity(peterm); - PushEntity(current.ResolvedUri, e); - ParseAttList(list, Entity.EOF); - PopEntity(); - ch = current.SkipWhitespace(); - } - else if (ch == '-') - { - ch = ParseDeclComments(); - } - else - { - var a = ParseAttDef(ch); - list.Add(a); - } - ch = current.SkipWhitespace(); - } - } - - AttDef ParseAttDef(char ch) - { - ch = current.SkipWhitespace(); - var name = ScanName(WhiteSpace); - name = name.ToUpper(); - name = nameTable.Add(name); - var attdef = new AttDef(name); - - ch = current.SkipWhitespace(); - if (ch == '-') - ch = ParseDeclComments(); - - ParseAttType(ch, attdef); - - ch = current.SkipWhitespace(); - if (ch == '-') - ch = ParseDeclComments(); - - ParseAttDefault(ch, attdef); - - ch = current.SkipWhitespace(); - if (ch == '-') - ch = ParseDeclComments(); - - return attdef; - - } - - void ParseAttType(char ch, AttDef attdef) - { - if (ch == '%') - { - var e = ParseParameterEntity(WhiteSpace); - PushEntity(current.ResolvedUri, e); - ParseAttType(current.Lastchar, attdef); - PopEntity(); // bugbug - are we at the end of the entity? - ch = current.Lastchar; - return; - } - - if (ch == '(') - { - attdef.EnumValues = ParseNameGroup(ch, false); - attdef.Type = AttributeType.ENUMERATION; - } - else - { - var token = ScanName(WhiteSpace); - if (token == "NOTATION") - { - ch = current.SkipWhitespace(); - if (ch != '(') - { - current.Error("Expecting name group '(', but found '{0}'", ch); - } - attdef.Type = AttributeType.NOTATION; - attdef.EnumValues = ParseNameGroup(ch, true); - } - else - { - attdef.SetType(token); - } - } - } - - void ParseAttDefault(char ch, AttDef attdef) - { - if (ch == '%') - { - var e = ParseParameterEntity(WhiteSpace); - PushEntity(current.ResolvedUri, e); - ParseAttDefault(current.Lastchar, attdef); - PopEntity(); // bugbug - are we at the end of the entity? - ch = current.Lastchar; - return; - } - - var hasdef = true; - if (ch == '#') - { - current.ReadChar(); - var token = current.ScanToken(sb, WhiteSpace, true); - hasdef = attdef.SetPresence(token); - ch = current.SkipWhitespace(); - } - if (hasdef) - { - if (ch == '\'' || ch == '"') - { - var lit = current.ScanLiteral(sb, ch); - attdef.Default = lit; - ch = current.SkipWhitespace(); - } - else - { - var name = current.ScanToken(sb, WhiteSpace, false); - name = name.ToUpper(); - name = nameTable.Add(name); - attdef.Default = name; // bugbug - must be one of the enumerated names. - ch = current.SkipWhitespace(); - } - } - } - } - - class StringUtilities - { - public static bool EqualsIgnoreCase(string a, string b) - { - return string.Compare(a, b, true, CultureInfo.InvariantCulture) == 0; - } - } -} diff --git a/SiteServer.Utils/ThirdParty/Sgml/SgmlReader.cs b/SiteServer.Utils/ThirdParty/Sgml/SgmlReader.cs deleted file mode 100644 index 795053367..000000000 --- a/SiteServer.Utils/ThirdParty/Sgml/SgmlReader.cs +++ /dev/null @@ -1,1967 +0,0 @@ -using System; -using System.Xml; -using System.IO; -using System.Text; - -namespace SiteServer.Utils.ThirdParty.Sgml -{ - /// - /// SGML is case insensitive, so here you can choose between converting - /// to lower case or upper case tags. "None" means that the case is left - /// alone, except that end tags will be folded to match the start tags. - /// - public enum CaseFolding - { - None, - ToUpper, - ToLower - } - - /// - /// This stack maintains a high water mark for allocated objects so the client - /// can reuse the objects in the stack to reduce memory allocations, this is - /// used to maintain current state of the parser for element stack, and attributes - /// in each element. - /// - internal class HWStack - { - object[] items; - int size; - int count; - int growth; - - public HWStack(int growth) - { - this.growth = growth; - } - - public int Count - { - get { return count; } - set { count = value; } - } - public int Size => size; - // returns the item at the requested index or null if index is out of bounds - public object this[int i] - { - get { return (i >= 0 && i < size) ? items[i] : null; } - set { items[i] = value; } - } - public object Pop() - { - count--; - if (count > 0) - { - return items[count - 1]; - } - return null; - } - // This method tries to reuse a slot, if it returns null then - // the user has to call the other Push method. - public object Push() - { - if (count == size) - { - var newsize = size + growth; - var newarray = new object[newsize]; - if (items != null) - Array.Copy(items, newarray, size); - size = newsize; - items = newarray; - } - return items[count++]; - } - public void RemoveAt(int i) - { - items[i] = null; - Array.Copy(items, i + 1, items, i, count - i - 1); - count--; - - } - } - - /// - /// This class represents an attribute. The AttDef is assigned - /// from a validation process, and is used to provide default values. - /// - internal class Attribute - { - internal string Name; // the atomized name (using XmlNameTable). - internal AttDef DtdType; // the AttDef of the attribute from the SGML DTD. - internal char QuoteChar; // the quote character used for the attribute value. - internal string literalValue; // tha attribute value - - /// - /// Attribute objects are reused during parsing to reduce memory allocations, - /// hence the Reset method. - /// - public void Reset(string name, string value, char quote) - { - Name = name; - literalValue = value; - QuoteChar = quote; - DtdType = null; - } - - public string Value - { - get - { - if (literalValue != null) - return literalValue; - if (DtdType != null) - return DtdType.Default; - return null; - } - set - { - literalValue = value; - } - } - - public bool IsDefault => (literalValue == null); - } - - /// - /// This class models an XML node, an array of elements in scope is maintained while parsing - /// for validation purposes, and these Node objects are reused to reduce object allocation, - /// hence the reset method. - /// - internal class Node - { - internal XmlNodeType NodeType; - internal string Value; - internal XmlSpace Space; - internal string XmlLang; - internal bool IsEmpty; - internal string Name; - internal ElementDecl DtdType; // the DTD type found via validation - internal State CurrentState; - internal bool Simulated; // tag was injected into result stream. - HWStack attributes = new HWStack(10); - - /// - /// Attribute objects are reused during parsing to reduce memory allocations, - /// hence the Reset method. - /// - public void Reset(string name, XmlNodeType nt, string value) - { - Value = value; - Name = name; - NodeType = nt; - Space = XmlSpace.None; - XmlLang = null; - IsEmpty = true; - attributes.Count = 0; - DtdType = null; - } - - public Attribute AddAttribute(string name, string value, char quotechar, bool caseInsensitive) - { - Attribute a; - // check for duplicates! - for (int i = 0, n = attributes.Count; i < n; i++) - { - a = (Attribute)attributes[i]; - if (caseInsensitive && string.Compare(a.Name, name, true) == 0) - { - return null; - } - else if ((object)a.Name == (object)name) - { - return null; - } - } - // This code makes use of the high water mark for attribute objects, - // and reuses exisint Attribute objects to avoid memory allocation. - a = (Attribute)attributes.Push(); - if (a == null) - { - a = new Attribute(); - attributes[attributes.Count - 1] = a; - } - a.Reset(name, value, quotechar); - return a; - } - - public void RemoveAttribute(string name) - { - for (int i = 0, n = attributes.Count; i < n; i++) - { - var a = (Attribute)attributes[i]; - if (a.Name == name) - { - attributes.RemoveAt(i); - return; - } - } - } - public void CopyAttributes(Node n) - { - for (int i = 0, len = n.attributes.Count; i < len; i++) - { - var a = (Attribute)n.attributes[i]; - var na = AddAttribute(a.Name, a.Value, a.QuoteChar, false); - na.DtdType = a.DtdType; - } - } - - public int AttributeCount => attributes.Count; - - public int GetAttribute(string name) - { - for (int i = 0, n = attributes.Count; i < n; i++) - { - var a = (Attribute)attributes[i]; - if (a.Name == name) - { - return i; - } - } - return -1; - } - - public Attribute GetAttribute(int i) - { - if (i >= 0 && i < attributes.Count) - { - var a = (Attribute)attributes[i]; - return a; - } - return null; - } - } - - // This enum is used to track the current state of te SgmlReader - internal enum State - { - Initial, // The initial state (Read has not been called yet) - Markup, // Expecting text or markup - EndTag, // Positioned on an end tag - Attr, // Positioned on an attribute - AttrValue, // Positioned in an attribute value - Text, // Positioned on a Text node. - PartialTag, // Positioned on a text node, and we have hit a start tag - AutoClose, // We are auto-closing tags (this is like State.EndTag), but end tag was generated - CData, // We are on a CDATA type node, eg. where we have special parsing rules. - PartialText, - PseudoStartTag, // we pushed a pseudo-start tag, need to continue with previous start tag. - Eof - } - - - /// - /// SgmlReader is an XmlReader API over any SGML document (including built in - /// support for HTML). - /// - public class SgmlReader : XmlReader - { - SgmlDtd dtd; - Entity current; - State state; - XmlNameTable nametable; - char partial; - object endTag; - HWStack stack; - Node node; // current node (except for attributes) - // Attributes are handled separately using these members. - Attribute a; - int apos; // which attribute are we positioned on in the collection. - Uri baseUri; - StringBuilder sb; - StringBuilder name; - TextWriter log; - bool foundRoot; - - // autoclose support - Node newnode; - int poptodepth; - int rootCount; - bool isHtml; - string rootElementName; - - string href; - string errorLogFile; - Entity lastError; - string proxy; - TextReader inputStream; - string syslit; - string pubid; - string subset; - string docType; - WhitespaceHandling whitespaceHandling; - CaseFolding folding = CaseFolding.None; - bool stripDocType = true; - string startTag = null; - - public SgmlReader() - { - Init(); - nametable = new NameTable(); - } - - /// - /// Specify the SgmlDtd object directly. This allows you to cache the Dtd and share - /// it across multipl SgmlReaders. To load a DTD from a URL use the SystemLiteral property. - /// - public SgmlDtd Dtd - { - get - { - LazyLoadDtd(baseUri); - return dtd; - } - set { dtd = value; } - } - - private void LazyLoadDtd(Uri baseUri) - { - if (dtd == null) - { - if (syslit == null || syslit == string.Empty) - { - if (docType != null && StringUtilities.EqualsIgnoreCase(docType, "html")) - { - var a = typeof(SgmlReader).Assembly; - var name = a.FullName.Split(',')[0] + ".Html.dtd"; - var stm = a.GetManifestResourceStream(name); - if (stm != null) - { - var sr = new StreamReader(stm); - dtd = SgmlDtd.Parse(baseUri, "HTML", null, sr, null, proxy, nametable); - } - } - } - else - { - if (baseUri != null) - { - baseUri = new Uri(baseUri, syslit); - } - else if (this.baseUri != null) - { - baseUri = new Uri(this.baseUri, syslit); - } - else - { - baseUri = new Uri(new Uri(Directory.GetCurrentDirectory() + "\\"), syslit); - } - dtd = SgmlDtd.Parse(baseUri, docType, pubid, baseUri.AbsoluteUri, subset, proxy, nametable); - } - - if (dtd != null && dtd.Name != null) - { - switch (CaseFolding) - { - case CaseFolding.ToUpper: - rootElementName = dtd.Name.ToUpper(); - break; - case CaseFolding.ToLower: - rootElementName = dtd.Name.ToLower(); - break; - default: - rootElementName = dtd.Name; - break; - } - isHtml = StringUtilities.EqualsIgnoreCase(dtd.Name, "html"); - } - - } - } - - /// - /// The name of root element specified in the DOCTYPE tag. - /// - public string DocType - { - get { return docType; } - set { docType = value; } - } - - /// - /// The PUBLIC identifier in the DOCTYPE tag - /// - public string PublicIdentifier - { - get { return pubid; } - set { pubid = value; } - } - - /// - /// The SYSTEM literal in the DOCTYPE tag identifying the location of the DTD. - /// - public string SystemLiteral - { - get { return syslit; } - set { syslit = value; } - } - - /// - /// The DTD internal subset in the DOCTYPE tag - /// - public string InternalSubset - { - get { return subset; } - set { subset = value; } - } - - /// - /// The input stream containing SGML data to parse. - /// You must specify this property or the Href property before calling Read(). - /// - public TextReader InputStream - { - get { return inputStream; } - set { inputStream = value; Init(); } - } - - /// - /// Sometimes you need to specify a proxy server in order to load data via HTTP - /// from outside the firewall. For example: "itgproxy:80". - /// - public string WebProxy - { - get { return proxy; } - set { proxy = value; } - } - - /// - /// The base Uri is used to resolve relative Uri's like the SystemLiteral and - /// Href properties. This is a method because BaseURI is a read-only - /// property on the base XmlReader class. - /// - public void SetBaseUri(string uri) - { - baseUri = new Uri(uri); - } - - /// - /// Specify the location of the input SGML document as a URL. - /// - public string Href - { - get { return href; } - set - { - href = value; - Init(); - if (baseUri == null) - { - if (href.IndexOf("://") > 0) - { - baseUri = new Uri(href); - } - else - { - baseUri = new Uri("file:///" + Directory.GetCurrentDirectory() + "//"); - } - } - } - } - - /// - /// Whether to strip out the DOCTYPE tag from the output (default true) - /// - public bool StripDocType - { - get { return stripDocType; } - set { stripDocType = value; } - } - - public CaseFolding CaseFolding - { - get { return folding; } - set { folding = value; } - } - - /// - /// DTD validation errors are written to this stream. - /// - public TextWriter ErrorLog - { - get { return log; } - set { log = value; } - } - - /// - /// DTD validation errors are written to this log file. - /// - public string ErrorLogFile - { - get { return errorLogFile; } - set - { - errorLogFile = value; - ErrorLog = new StreamWriter(value); - } - } - - void Log(string msg, params string[] args) - { - if (ErrorLog != null) - { - var err = string.Format(msg, args); - if (lastError != current) - { - err = err + " " + current.Context(); - lastError = current; - ErrorLog.WriteLine("### Error:" + err); - } - else - { - var path = string.Empty; - if (current.ResolvedUri != null) - { - path = current.ResolvedUri.AbsolutePath; - } - ErrorLog.WriteLine("### Error in " + - path + "#" + - current.Name + - ", line " + current.Line + ", position " + current.LinePosition + ": " + - err); - } - } - } - void Log(string msg, char ch) - { - Log(msg, ch.ToString()); - } - - - void Init() - { - state = State.Initial; - stack = new HWStack(10); - node = Push(null, XmlNodeType.Document, null); - node.IsEmpty = false; - sb = new StringBuilder(); - name = new StringBuilder(); - poptodepth = 0; - current = null; - partial = '\0'; - endTag = null; - a = null; - apos = 0; - newnode = null; - rootCount = 0; - foundRoot = false; - } - - Node Push(string name, XmlNodeType nt, string value) - { - var result = (Node)stack.Push(); - if (result == null) - { - result = new Node(); - stack[stack.Count - 1] = result; - } - result.Reset(name, nt, value); - node = result; - return result; - } - - void SwapTopNodes() - { - var top = stack.Count - 1; - if (top > 0) - { - var n = (Node)stack[top - 1]; - stack[top - 1] = stack[top]; - stack[top] = n; - } - } - - Node Push(Node n) - { - // we have to do a deep clone of the Node object because - // it is reused in the stack. - var n2 = Push(n.Name, n.NodeType, n.Value); - n2.DtdType = n.DtdType; - n2.IsEmpty = n.IsEmpty; - n2.Space = n.Space; - n2.XmlLang = n.XmlLang; - n2.CurrentState = n.CurrentState; - n2.CopyAttributes(n); - node = n2; - return n2; - } - - void Pop() - { - if (stack.Count > 1) - { - node = (Node)stack.Pop(); - } - } - - Node Top() - { - var top = stack.Count - 1; - if (top > 0) - { - return (Node)stack[top]; - } - return null; - } - - public override XmlNodeType NodeType - { - get - { - if (state == State.Attr) - { - return XmlNodeType.Attribute; - } - else if (state == State.AttrValue) - { - return XmlNodeType.Text; - } - else if (state == State.EndTag || state == State.AutoClose) - { - return XmlNodeType.EndElement; - } - return node.NodeType; - } - } - - public override string Name => LocalName; - - public override string LocalName - { - get - { - string result = null; - if (state == State.Attr) - { - result = a.Name; - } - else if (state == State.AttrValue) - { - result = null; - } - else - { - result = node.Name; - } - - return result; - } - } - - public override string NamespaceURI - { - get - { - // SGML has no namespaces, unless this turned out to be an xmlns attribute. - if (state == State.Attr && StringUtilities.EqualsIgnoreCase(a.Name, "xmlns")) - { - return "http://www.w3.org/2000/xmlns/"; - } - return String.Empty; - } - } - - public override string Prefix => String.Empty; - - public override bool HasValue - { - get - { - if (state == State.Attr || state == State.AttrValue) - { - return true; - } - return (node.Value != null); - } - } - - public override string Value - { - get - { - if (state == State.Attr || state == State.AttrValue) - { - return a.Value; - } - return node.Value; - } - } - - public override int Depth - { - get - { - if (state == State.Attr) - { - return stack.Count; - } - else if (state == State.AttrValue) - { - return stack.Count + 1; - } - return stack.Count - 1; - } - } - - public override string BaseURI => baseUri == null ? "" : baseUri.AbsoluteUri; - - public override bool IsEmptyElement - { - get - { - if (state == State.Markup || state == State.Attr || state == State.AttrValue) - { - return node.IsEmpty; - } - return false; - } - } - public override bool IsDefault - { - get - { - if (state == State.Attr || state == State.AttrValue) - return a.IsDefault; - return false; - } - } - public override char QuoteChar - { - get - { - if (a != null) return a.QuoteChar; - return '\0'; - } - } - - public override XmlSpace XmlSpace - { - get - { - for (var i = stack.Count - 1; i > 1; i--) - { - var n = (Node)stack[i]; - var xs = n.Space; - if (xs != XmlSpace.None) return xs; - } - return XmlSpace.None; - } - } - - public override string XmlLang - { - get - { - for (var i = stack.Count - 1; i > 1; i--) - { - var n = (Node)stack[i]; - var xmllang = n.XmlLang; - if (xmllang != null) return xmllang; - } - return String.Empty; - } - } - - public WhitespaceHandling WhitespaceHandling - { - get - { - return whitespaceHandling; - } - set - { - whitespaceHandling = value; - } - } - - public override int AttributeCount - { - get - { - if (state == State.Attr || state == State.AttrValue) - return 0; - if (node.NodeType == XmlNodeType.Element || - node.NodeType == XmlNodeType.DocumentType) - return node.AttributeCount; - return 0; - } - } - - public override string GetAttribute(string name) - { - if (state != State.Attr && state != State.AttrValue) - { - var i = node.GetAttribute(name); - if (i >= 0) return GetAttribute(i); - } - return null; - } - - public override string GetAttribute(string name, string namespaceURI) - { - return GetAttribute(name); // SGML has no namespaces. - } - - public override string GetAttribute(int i) - { - if (state != State.Attr && state != State.AttrValue) - { - var a = node.GetAttribute(i); - if (a != null) - return a.Value; - } - throw new IndexOutOfRangeException(); - } - - public override string this[int i] => GetAttribute(i); - - public override string this[string name] => GetAttribute(name); - - public override string this[string name, string namespaceURI] => GetAttribute(name, namespaceURI); - - public override bool MoveToAttribute(string name) - { - var i = node.GetAttribute(name); - if (i >= 0) - { - MoveToAttribute(i); - return true; - } - return false; - } - - public override bool MoveToAttribute(string name, string ns) - { - return MoveToAttribute(name); - } - - public override void MoveToAttribute(int i) - { - var a = node.GetAttribute(i); - if (a != null) - { - apos = i; - this.a = a; - if (state != State.Attr) - { - node.CurrentState = state;//save current state. - } - state = State.Attr; - return; - } - throw new IndexOutOfRangeException(); - } - - public override bool MoveToFirstAttribute() - { - if (node.AttributeCount > 0) - { - MoveToAttribute(0); - return true; - } - return false; - } - - public override bool MoveToNextAttribute() - { - if (state != State.Attr && state != State.AttrValue) - { - return MoveToFirstAttribute(); - } - if (apos < node.AttributeCount - 1) - { - MoveToAttribute(apos + 1); - return true; - } - return false; - } - - public override bool MoveToElement() - { - if (state == State.Attr || state == State.AttrValue) - { - state = node.CurrentState; - a = null; - return true; - } - return (node.NodeType == XmlNodeType.Element); - } - - bool IsHtml => isHtml; - - public Encoding GetEncoding() - { - if (current == null) - { - OpenInput(); - } - return current.GetEncoding(); - } - - void OpenInput() - { - LazyLoadDtd(baseUri); - - if (Href != null) - { - current = new Entity("#document", null, href, proxy); - } - else if (inputStream != null) - { - current = new Entity("#document", null, inputStream, proxy); - } - else - { - throw new InvalidOperationException("You must specify input either via Href or InputStream properties"); - } - current.Html = IsHtml; - current.Open(null, baseUri); - if (current.ResolvedUri != null) - baseUri = current.ResolvedUri; - - if (current.Html && dtd == null) - { - docType = "HTML"; - LazyLoadDtd(baseUri); - } - } - - public override bool Read() - { - if (current == null) - { - OpenInput(); - } - var start = state; - if (node.Simulated) - { - // return the next node - node.Simulated = false; - node = Top(); - state = node.CurrentState; - return true; - } - - var foundnode = false; - while (!foundnode) - { - switch (state) - { - case State.Initial: - state = State.Markup; - current.ReadChar(); - goto case State.Markup; - case State.Eof: - if (current.Parent != null) - { - current.Close(); - current = current.Parent; - } - else - { - return false; - } - break; - case State.EndTag: - if (endTag == (object)node.Name) - { - Pop(); // we're done! - state = State.Markup; - goto case State.Markup; - } - Pop(); // close one element - foundnode = true;// return another end element. - break; - case State.Markup: - if (node.IsEmpty) - { - Pop(); - } - var n = node; - foundnode = ParseMarkup(); - break; - case State.PartialTag: - Pop(); // remove text node. - state = State.Markup; - foundnode = ParseTag(partial); - break; - case State.PseudoStartTag: - foundnode = ParseStartTag('<'); - break; - case State.AutoClose: - Pop(); // close next node. - if (stack.Count <= poptodepth) - { - state = State.Markup; - if (newnode != null) - { - Push(newnode); // now we're ready to start the new node. - newnode = null; - state = State.Markup; - } - else if (node.NodeType == XmlNodeType.Document) - { - state = State.Eof; - goto case State.Eof; - } - } - foundnode = true; - break; - case State.CData: - foundnode = ParseCData(); - break; - case State.Attr: - goto case State.AttrValue; - case State.AttrValue: - state = State.Markup; - goto case State.Markup; - case State.Text: - Pop(); - goto case State.Markup; - case State.PartialText: - if (ParseText(current.Lastchar, false)) - { - node.NodeType = XmlNodeType.Whitespace; - } - foundnode = true; - break; - } - if (foundnode && node.NodeType == XmlNodeType.Whitespace && whitespaceHandling == WhitespaceHandling.None) - { - // strip out whitespace (caller is probably pretty printing the XML). - foundnode = false; - } - if (!foundnode && state == State.Eof && stack.Count > 1) - { - poptodepth = 1; - state = State.AutoClose; - node = Top(); - return true; - } - } - if (!foundRoot && (NodeType == XmlNodeType.Element || - NodeType == XmlNodeType.Text || - NodeType == XmlNodeType.CDATA)) - { - foundRoot = true; - if (IsHtml && (NodeType != XmlNodeType.Element || - string.Compare(LocalName, "html", true, System.Globalization.CultureInfo.InvariantCulture) != 0)) - { - // Simulate an HTML root element! - node.CurrentState = state; - var root = Push("html", XmlNodeType.Element, null); - SwapTopNodes(); // make html the outer element. - node = root; - root.Simulated = true; - root.IsEmpty = false; - state = State.Markup; - //this.state = State.PseudoStartTag; - //this.startTag = name; - } - return true; - } - return true; - } - - bool ParseMarkup() - { - var ch = current.Lastchar; - if (ch == '<') - { - ch = current.ReadChar(); - return ParseTag(ch); - } - else if (ch != Entity.EOF) - { - if (node.DtdType != null && node.DtdType.ContentModel.DeclaredContent == DeclaredContent.CDATA) - { - // e.g. SCRIPT or STYLE tags which contain unparsed character data. - partial = '\0'; - state = State.CData; - return false; - } - else if (ParseText(ch, true)) - { - node.NodeType = XmlNodeType.Whitespace; - } - return true; - } - state = State.Eof; - return false; - } - - static string declterm = " \t\r\n><"; - bool ParseTag(char ch) - { - if (ch == '%') - { - return ParseAspNet(); - } - if (ch == '!') - { - ch = current.ReadChar(); - if (ch == '-') - { - return ParseComment(); - } - else if (ch == '[') - { - return ParseConditionalBlock(); - } - else if (ch != '_' && !Char.IsLetter(ch)) - { - // perhaps it's one of those nasty office document hacks like '' - var value = current.ScanToEnd(sb, "Recovering", ">"); // skip it - Log("Ignoring invalid markup '"); - return false; - } - else - { - var name = current.ScanToken(sb, declterm, false); - if (name == "DOCTYPE") - { - ParseDocType(); - // In SGML DOCTYPE SYSTEM attribute is optional, but in XML it is required, - // therefore if there is no SYSTEM literal then add an empty one. - if (GetAttribute("SYSTEM") == null && GetAttribute("PUBLIC") != null) - { - node.AddAttribute("SYSTEM", "", '"', folding == CaseFolding.None); - } - if (stripDocType) - { - return false; - } - else - { - node.NodeType = XmlNodeType.DocumentType; - return true; - } - } - else - { - Log("Invalid declaration '"); // skip it - return false; - } - } - } - else if (ch == '?') - { - current.ReadChar();// consume the '?' character. - return ParsePI(); - } - else if (ch == '/') - { - return ParseEndTag(); - } - else - { - return ParseStartTag(ch); - } - } - - string ScanName(string terminators) - { - var name = current.ScanToken(sb, terminators, false); - switch (folding) - { - case CaseFolding.ToUpper: - name = name.ToUpper(); - break; - case CaseFolding.ToLower: - name = name.ToLower(); - break; - } - return nametable.Add(name); - } - - static string tagterm = " \t\r\n=/><"; - static string aterm = " \t\r\n='\"/>"; - static string avterm = " \t\r\n>"; - bool ParseStartTag(char ch) - { - string name = null; - if (state != State.PseudoStartTag) - { - if (tagterm.IndexOf(ch) >= 0) - { - sb.Length = 0; - sb.Append('<'); - state = State.PartialText; - return false; - } - name = ScanName(tagterm); - } - else - { - name = startTag; - state = State.Markup; - } - var n = Push(name, XmlNodeType.Element, null); - n.IsEmpty = false; - Validate(n); - ch = current.SkipWhitespace(); - while (ch != Entity.EOF && ch != '>') - { - if (ch == '/') - { - n.IsEmpty = true; - ch = current.ReadChar(); - if (ch != '>') - { - Log("Expected empty start tag '/>' sequence instead of '{0}'", ch); - current.ScanToEnd(null, "Recovering", ">"); - return false; - } - break; - } - else if (ch == '<') - { - Log("Start tag '{0}' is missing '>'", name); - break; - } - var aname = ScanName(aterm); - ch = current.SkipWhitespace(); - if (aname == "," || aname == "=" || aname == ":" || aname == ";") - { - continue; - } - string value = null; - var quote = '\0'; - if (ch == '=' || ch == '"' || ch == '\'') - { - if (ch == '=') - { - current.ReadChar(); - ch = current.SkipWhitespace(); - } - if (ch == '\'' || ch == '\"') - { - quote = ch; - value = ScanLiteral(sb, ch); - } - else if (ch != '>') - { - var term = avterm; - value = current.ScanToken(sb, term, false); - } - } - if (aname.Length > 0) - { - var a = n.AddAttribute(aname, value, quote, folding == CaseFolding.None); - if (a == null) - { - Log("Duplicate attribute '{0}' ignored", aname); - } - else - { - ValidateAttribute(n, a); - } - } - ch = current.SkipWhitespace(); - } - if (ch == Entity.EOF) - { - current.Error("Unexpected EOF parsing start tag '{0}'", name); - } - else if (ch == '>') - { - current.ReadChar(); // consume '>' - } - if (Depth == 1) - { - if (rootCount == 1) - { - // Hmmm, we found another root level tag, soooo, the only - // thing we can do to keep this a valid XML document is stop - state = State.Eof; - return false; - } - rootCount++; - } - ValidateContent(n); - return true; - } - - bool ParseEndTag() - { - state = State.EndTag; - current.ReadChar(); // consume '/' char. - var name = ScanName(tagterm); - var ch = current.SkipWhitespace(); - if (ch != '>') - { - Log("Expected empty start tag '/>' sequence instead of '{0}'", ch); - current.ScanToEnd(null, "Recovering", ">"); - } - current.ReadChar(); // consume '>' - - endTag = name; - // Make sure there's a matching start tag for it. - var caseInsensitive = (folding == CaseFolding.None); - node = (Node)stack[stack.Count - 1]; - for (var i = stack.Count - 1; i > 0; i--) - { - var n = (Node)stack[i]; - if (caseInsensitive && string.Compare(n.Name, name, true) == 0) - { - endTag = n.Name; - return true; - } - else if ((object)n.Name == (object)name) - { - return true; - } - } - Log("No matching start tag for ''", name); - state = State.Markup; - return false; - } - - bool ParseAspNet() - { - var value = "<%" + current.ScanToEnd(sb, "AspNet", "%>") + "%>"; - Push(null, XmlNodeType.CDATA, value); - return true; - } - - bool ParseComment() - { - var ch = current.ReadChar(); - if (ch != '-') - { - Log("Expecting comment '"); - - // Make sure it's a valid comment! - var i = value.IndexOf("--"); - while (i >= 0) - { - var j = i + 2; - while (j < value.Length && value[j] == '-') - j++; - if (i > 0) - { - value = value.Substring(0, i - 1) + "-" + value.Substring(j); - } - else - { - value = "-" + value.Substring(j); - } - i = value.IndexOf("--"); - } - if (value.Length > 0 && value[value.Length - 1] == '-') - { - value += " "; // '-' cannot be last character - } - Push(null, XmlNodeType.Comment, value); - return true; - } - - static string cdataterm = "\t\r\n[<>"; - bool ParseConditionalBlock() - { - var ch = current.ReadChar(); // skip '[' - ch = current.SkipWhitespace(); - var name = current.ScanToken(sb, cdataterm, false); - if (name != "CDATA") - { - Log("Expecting CDATA but found '{0}'", name); - current.ScanToEnd(null, "CDATA", ">"); - return false; - } - ch = current.SkipWhitespace(); - if (ch != '[') - { - Log("Expecting '[' but found '{0}'", ch); - current.ScanToEnd(null, "CDATA", ">"); - return false; - } - var value = current.ScanToEnd(sb, "CDATA", "]]>"); - - Push(null, XmlNodeType.CDATA, value); - return true; - } - - static string dtterm = " \t\r\n>"; - void ParseDocType() - { - var ch = current.SkipWhitespace(); - var name = ScanName(dtterm); - Push(name, XmlNodeType.DocumentType, null); - ch = current.SkipWhitespace(); - if (ch != '>') - { - var subset = string.Empty; - var pubid = string.Empty; - var syslit = string.Empty; - - if (ch != '[') - { - var token = current.ScanToken(sb, dtterm, false); - if (token == "PUBLIC") - { - ch = current.SkipWhitespace(); - if (ch == '\"' || ch == '\'') - { - pubid = current.ScanLiteral(sb, ch); - node.AddAttribute(token, pubid, ch, folding == CaseFolding.None); - } - } - else if (token != "SYSTEM") - { - Log("Unexpected token in DOCTYPE '{0}'", token); - current.ScanToEnd(null, "DOCTYPE", ">"); - } - ch = current.SkipWhitespace(); - if (ch == '\"' || ch == '\'') - { - token = nametable.Add("SYSTEM"); - syslit = current.ScanLiteral(sb, ch); - node.AddAttribute(token, syslit, ch, folding == CaseFolding.None); - } - ch = current.SkipWhitespace(); - } - if (ch == '[') - { - subset = current.ScanToEnd(sb, "Internal Subset", "]"); - node.Value = subset; - } - ch = current.SkipWhitespace(); - if (ch != '>') - { - Log("Expecting end of DOCTYPE tag, but found '{0}'", ch); - current.ScanToEnd(null, "DOCTYPE", ">"); - } - - if (dtd == null) - { - docType = name; - this.pubid = pubid; - this.syslit = syslit; - this.subset = subset; - LazyLoadDtd(current.ResolvedUri); - } - } - current.ReadChar(); - } - - static string piterm = " \t\r\n?"; - bool ParsePI() - { - var name = current.ScanToken(sb, piterm, false); - string value = null; - if (current.Lastchar != '?') - { - // Notice this is not "?>". This is because Office generates bogus PI's that end with "/>". - value = current.ScanToEnd(sb, "Processing Instruction", ">"); - } - else - { - // error recovery. - value = current.ScanToEnd(sb, "Processing Instruction", ">"); - } - // skip xml declarations, since these are generated in the output instead. - if (name != "xml") - { - Push(nametable.Add(name), XmlNodeType.ProcessingInstruction, value); - return true; - } - return false; - } - - bool ParseText(char ch, bool newtext) - { - var ws = !newtext || current.IsWhitespace; - if (newtext) sb.Length = 0; - //this.sb.Append(ch); - //ch = this.current.ReadChar(); - state = State.Text; - while (ch != Entity.EOF) - { - if (ch == '<') - { - ch = current.ReadChar(); - if (ch == '/' || ch == '!' || ch == '?' || Char.IsLetter(ch)) - { - // Hit a tag, so return XmlNodeType.Text token - // and remember we partially started a new tag. - state = State.PartialTag; - partial = ch; - break; - } - else - { - // not a tag, so just proceed. - sb.Append('<'); - sb.Append(ch); - ws = false; - ch = current.ReadChar(); - } - } - else if (ch == '&') - { - ExpandEntity(sb, '<'); - ws = false; - ch = current.Lastchar; - } - else - { - if (!current.IsWhitespace) ws = false; - sb.Append(ch); - ch = current.ReadChar(); - } - } - var value = sb.ToString(); - Push(null, XmlNodeType.Text, value); - return ws; - } - - // This version is slightly different from Entity.ScanLiteral in that - // it also expands entities. - public string ScanLiteral(StringBuilder sb, char quote) - { - sb.Length = 0; - var ch = current.ReadChar(); - while (ch != Entity.EOF && ch != quote) - { - if (ch == '&') - { - ExpandEntity(this.sb, quote); - ch = current.Lastchar; - } - else - { - sb.Append(ch); - ch = current.ReadChar(); - } - } - current.ReadChar(); // consume end quote. - return sb.ToString(); - } - - bool ParseCData() - { - // Like ParseText(), only it doesn't allow elements in the content. - // It allows comments and processing instructions and text only and - // text is not returned as text but CDATA (since it may contain angle brackets). - // And initial whitespace is ignored. It terminates when we hit the - // end tag for the current CDATA node (e.g. ). - var ws = current.IsWhitespace; - sb.Length = 0; - var ch = current.Lastchar; - if (partial != '\0') - { - Pop(); // pop the CDATA - switch (partial) - { - case '!': - partial = ' '; // and pop the comment next time around - return ParseComment(); - case '?': - partial = ' '; // and pop the PI next time around - return ParsePI(); - case '/': - state = State.EndTag; - return true; // we are done! - case ' ': - break; // means we just needed to pop the Comment, PI or CDATA. - } - } - else - { - ch = current.ReadChar(); - } - - // if this.partial == '!' then parse the comment and return - // if this.partial == '?' then parse the processing instruction and return. - while (ch != Entity.EOF) - { - if (ch == '<') - { - ch = current.ReadChar(); - if (ch == '!') - { - ch = current.ReadChar(); - if (ch == '-') - { - // return what CDATA we have accumulated so far - // then parse the comment and return to here. - if (ws) - { - partial = ' '; // pop comment next time through - return ParseComment(); - } - else - { - // return what we've accumulated so far then come - // back in and parse the comment. - partial = '!'; - break; - } -#if FIX - } else if (ch == '['){ - // We are about to wrap this node as a CDATA block because of it's - // type in the DTD, but since we found a CDATA block in the input - // we have to parse it as a CDATA block, otherwise we will attempt - // to output nested CDATA blocks which of course is illegal. - if (this.ParseConditionalBlock()){ - this.partial = ' '; - return true; - } -#endif - } - else - { - // not a comment, so ignore it and continue on. - sb.Append('<'); - sb.Append('!'); - sb.Append(ch); - ws = false; - } - } - else if (ch == '?') - { - // processing instruction. - current.ReadChar();// consume the '?' character. - if (ws) - { - partial = ' '; // pop PI next time through - return ParsePI(); - } - else - { - partial = '?'; - break; - } - } - else if (ch == '/') - { - // see if this is the end tag for this CDATA node. - var temp = sb.ToString(); - if (ParseEndTag() && endTag == (object)node.Name) - { - if (ws || temp == string.Empty) - { - // we are done! - return true; - } - else - { - // return CDATA text then the end tag - partial = '/'; - sb.Length = 0; // restore buffer! - sb.Append(temp); - state = State.CData; - break; - } - } - else - { - // wrong end tag, so continue on. - sb.Length = 0; // restore buffer! - sb.Append(temp); - sb.Append(""); - ws = false; - } - } - else - { - // must be just part of the CDATA block, so proceed. - sb.Append('<'); - sb.Append(ch); - ws = false; - } - } - else - { - if (!current.IsWhitespace && ws) ws = false; - sb.Append(ch); - } - ch = current.ReadChar(); - } - var value = sb.ToString(); - Push(null, XmlNodeType.CDATA, value); - if (partial == '\0') - partial = ' ';// force it to pop this CDATA next time in. - return true; - } - - void ExpandEntity(StringBuilder sb, char terminator) - { - var ch = current.ReadChar(); - if (ch == '#') - { - var charent = current.ExpandCharEntity(); - sb.Append(charent); - ch = current.Lastchar; - } - else - { - this.name.Length = 0; - while (ch != Entity.EOF && - (Char.IsLetter(ch) || ch == '_' || ch == '-')) - { - this.name.Append(ch); - ch = current.ReadChar(); - } - var name = this.name.ToString(); - if (dtd != null && name != string.Empty) - { - var e = (Entity)dtd.FindEntity(name); - if (e != null) - { - if (e.Internal) - { - sb.Append(e.Literal); - if (ch != terminator) - ch = current.ReadChar(); - return; - } - else - { - var ex = new Entity(name, e.PublicId, e.Uri, current.Proxy); - e.Open(current, new Uri(e.Uri)); - current = ex; - current.ReadChar(); - return; - } - } - else - { - Log("Undefined entity '{0}'", name); - } - } - // Entity is not defined, so just keep it in with the rest of the - // text. - sb.Append("&"); - sb.Append(name); - if (ch != terminator) - { - sb.Append(ch); - ch = current.ReadChar(); - } - } - } - - public override bool EOF => state == State.Eof; - - public override void Close() - { - if (current != null) - { - current.Close(); - current = null; - } - if (log != null) - { - log.Close(); - log = null; - } - } - - public override ReadState ReadState - { - get - { - if (state == State.Initial) return ReadState.Initial; - else if (state == State.Eof) return ReadState.EndOfFile; - return ReadState.Interactive; - } - } - - public override string ReadString() - { - if (node.NodeType == XmlNodeType.Element) - { - sb.Length = 0; - while (Read()) - { - switch (NodeType) - { - case XmlNodeType.CDATA: - case XmlNodeType.SignificantWhitespace: - case XmlNodeType.Whitespace: - case XmlNodeType.Text: - sb.Append(node.Value); - break; - default: - return sb.ToString(); - } - } - return sb.ToString(); - } - return node.Value; - } - - - public override string ReadInnerXml() - { - var sw = new StringWriter(); - var xw = new XmlTextWriter(sw); - xw.Formatting = Formatting.Indented; - switch (NodeType) - { - case XmlNodeType.Element: - Read(); - while (!EOF && NodeType != XmlNodeType.EndElement) - { - xw.WriteNode(this, true); - } - Read(); // consume the end tag - break; - case XmlNodeType.Attribute: - sw.Write(Value); - break; - default: - // return empty string according to XmlReader spec. - break; - } - xw.Close(); - return sw.ToString(); - } - - public override string ReadOuterXml() - { - var sw = new StringWriter(); - var xw = new XmlTextWriter(sw); - xw.Formatting = Formatting.Indented; - xw.WriteNode(this, true); - xw.Close(); - return sw.ToString(); - } - - public override XmlNameTable NameTable => nametable; - - public override string LookupNamespace(string prefix) - { - return null;// there are no namespaces in SGML. - } - - public override void ResolveEntity() - { - // We never return any entity reference nodes, so this should never be called. - throw new InvalidOperationException("Not on an entity reference."); - } - - public override bool ReadAttributeValue() - { - if (state == State.Attr) - { - state = State.AttrValue; - return true; - } - else if (state == State.AttrValue) - { - return false; - } - throw new InvalidOperationException("Not on an attribute."); - } - - void Validate(Node node) - { - if (dtd != null) - { - var e = dtd.FindElement(node.Name); - if (e != null) - { - node.DtdType = e; - if (e.ContentModel.DeclaredContent == DeclaredContent.EMPTY) - node.IsEmpty = true; - } - } - } - - void ValidateAttribute(Node node, Attribute a) - { - var e = node.DtdType; - if (e != null) - { - var ad = e.FindAttribute(a.Name); - if (ad != null) - { - a.DtdType = ad; - } - } - } - - void ValidateContent(Node node) - { - if (dtd != null) - { - // See if this element is allowed inside the current element. - // If it isn't, then auto-close elements until we find one - // that it is allowed to be in. - var name = nametable.Add(node.Name.ToUpper()); // DTD is in upper case - var i = 0; - var top = stack.Count - 2; - if (node.DtdType != null) - { - // it is a known element, let's see if it's allowed in the - // current context. - for (i = top; i > 0; i--) - { - var n = (Node)stack[i]; - if (n.IsEmpty) - continue; // we'll have to pop this one - var f = n.DtdType; - if (f != null) - { - if (f.Name == dtd.Name) - break; // can't pop the root element. - if (f.CanContain(name, dtd)) - { - break; - } - else if (!f.EndTagOptional) - { - // If the end tag is not optional then we can't - // auto-close it. We'll just have to live with the - // junk we've found and move on. - break; - } - } - else - { - // Since we don't understand this tag anyway, - // we might as well allow this content! - break; - } - } - } - if (i == 0) - { - // Tag was not found or is not allowed anywhere, ignore it and - // continue on. - } - else if (i < top) - { - var n = (Node)stack[top]; - if (i == top - 1 && name == n.Name) - { - // e.g. p not allowed inside p, not an interesting error. - } - else - { - var closing = string.Empty; - for (var k = top; k >= i + 1; k--) - { - if (closing != string.Empty) closing += ","; - var n2 = (Node)stack[k]; - closing += "<" + n2.Name + ">"; - } - Log("Element '{0}' not allowed inside '{1}', closing {2}.", - name, n.Name, closing); - } - state = State.AutoClose; - newnode = node; - Pop(); // save this new node until we pop the others - poptodepth = i + 1; - } - } - } - } -} diff --git a/SiteServer.Utils/TranslateUtils.cs b/SiteServer.Utils/TranslateUtils.cs deleted file mode 100644 index ab54c509b..000000000 --- a/SiteServer.Utils/TranslateUtils.cs +++ /dev/null @@ -1,1145 +0,0 @@ -using System; -using System.Collections; -using System.Collections.Specialized; -using System.Text; -using System.Data; -using System.Web.UI.WebControls; -using System.Drawing; -using System.Collections.Generic; -using System.Linq; -using SiteServer.Utils.Auth; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; -using Newtonsoft.Json.Serialization; - -namespace SiteServer.Utils -{ - public class TranslateUtils - { - - //添加枚举:(fileAttributes | FileAttributes.ReadOnly) 判断枚举:((fileAttributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) 去除枚举:(fileAttributes ^ FileAttributes.ReadOnly) - - /// - /// 将字符串类型转换为对应的枚举类型 - /// - public static object ToEnum(Type enumType, string value, object defaultType) - { - object retval; - try - { - retval = Enum.Parse(enumType, value, true); - } - catch - { - retval = defaultType; - } - return retval; - } - - public static string EnumToString(Enum enumType) - { - return enumType.ToString(); - } - - public static SqlDbType ToSqlDbType(string typeStr) - { - return (SqlDbType)ToEnum(typeof(SqlDbType), typeStr, SqlDbType.VarChar); - } - - public static System.Data.OleDb.OleDbType ToOleDbType(string typeStr) - { - return (System.Data.OleDb.OleDbType)ToEnum(typeof(System.Data.OleDb.OleDbType), typeStr, System.Data.OleDb.OleDbType.VarChar); - } - - public static List ToIntList(int intValue) - { - return new List {intValue}; - } - - public static int ToInt(string intStr) - { - return ToInt(intStr, 0); - } - - public static int ToInt(string intStr, int defaultValue) - { - int i; - if (!int.TryParse(intStr?.Trim().TrimStart('0'), out i)) - { - i = defaultValue; - } - if (i < 0) - { - i = defaultValue; - } - return i; - } - - public static int ToIntWithNagetive(string intStr) - { - return ToIntWithNagetive(intStr, 0); - } - - public static int ToIntWithNagetive(string intStr, int defaultValue) - { - int i; - if (!int.TryParse(intStr?.Trim(), out i)) - { - i = defaultValue; - } - return i; - } - - public static decimal ToDecimal(string intStr) - { - return ToDecimal(intStr, 0); - } - - public static decimal ToDecimal(string intStr, decimal defaultValue) - { - decimal i; - if (!decimal.TryParse(intStr?.Trim(), out i)) - { - i = defaultValue; - } - if (i < 0) - { - i = defaultValue; - } - return i; - } - - public static decimal ToDecimalWithNagetive(string intStr) - { - return ToDecimalWithNagetive(intStr, 0); - } - - public static decimal ToDecimalWithNagetive(string intStr, decimal defaultValue) - { - decimal i; - if (!decimal.TryParse(intStr?.Trim(), out i)) - { - i = defaultValue; - } - return i; - } - - public static double ToDouble(string intStr) - { - return ToDouble(intStr, 0); - } - - public static double ToDouble(string intStr, double defaultValue) - { - double i; - if (!double.TryParse(intStr?.Trim(), out i)) - { - i = defaultValue; - } - if (i < 0) - { - i = defaultValue; - } - return i; - } - - public static long ToLong(string intStr) - { - return ToLong(intStr, 0); - } - - public static long ToLong(string intStr, long defaultValue) - { - long l; - if (!long.TryParse(intStr?.Trim(), out l)) - { - l = defaultValue; - } - if (l < 0) - { - l = defaultValue; - } - return l; - } - - public static bool ToBool(string boolStr) - { - bool boolean; - if (!bool.TryParse(boolStr?.Trim(), out boolean)) - { - boolean = false; - } - return boolean; - } - - public static bool ToBool(string boolStr, bool defaultValue) - { - bool boolean; - if (!bool.TryParse(boolStr?.Trim(), out boolean)) - { - boolean = defaultValue; - } - return boolean; - } - - public static DateTime ToDateTime(string dateTimeStr) - { - var datetime = DateUtils.SqlMinValue; - if (!string.IsNullOrEmpty(dateTimeStr)) - { - if (!DateTime.TryParse(dateTimeStr.Trim(), out datetime)) - { - datetime = DateUtils.SqlMinValue; - } - } - if (datetime < DateUtils.SqlMinValue) - { - datetime = DateUtils.SqlMinValue; - } - return datetime; - } - - public static DateTime ToDateTime(string dateTimeStr, DateTime defaultValue) - { - var datetime = defaultValue; - if (!string.IsNullOrEmpty(dateTimeStr)) - { - if (!DateTime.TryParse(dateTimeStr.Trim(), out datetime)) - { - datetime = defaultValue; - } - return datetime; - } - return datetime; - } - - public static Color ToColor(string colorStr) - { - var color = Color.Empty; - try - { - color = Color.FromName(colorStr.Trim()); - } - catch - { - // ignored - } - return color; - } - - public static string ToCurrency(decimal i) - { - return i.ToString("c"); - } - - public static string ToWidth(string width) - { - if (!string.IsNullOrEmpty(width) && !width.EndsWith("%") && !width.EndsWith("px")) - { - return width + "px"; - } - return width; - } - - public static Unit ToUnit(string unitStr) - { - var type = Unit.Empty; - try - { - type = Unit.Parse(unitStr.Trim()); - } - catch - { - // ignored - } - return type; - } - - - public static string ToTwoCharString(int i) - { - return i >= 0 && i <= 9 ? $"0{i}" : i.ToString(); - } - - public static string Censor(string censorRegex, string inputContent) - { - return RegexUtils.Replace(censorRegex, inputContent, "***"); - } - - public static StringCollection StringCollectionToStringCollection(string collection) - { - return StringCollectionToStringCollection(collection, ','); - } - - public static List StringCollectionToIntList(string collection) - { - var list = new List(); - if (!string.IsNullOrEmpty(collection)) - { - var array = collection.Split(','); - foreach (var s in array) - { - int i; - int.TryParse(s.Trim(), out i); - list.Add(i); - } - } - return list; - } - - public static List StringCollectionToDecimalList(string collection) - { - var list = new List(); - if (!string.IsNullOrEmpty(collection)) - { - var array = collection.Split(','); - foreach (var s in array) - { - decimal i; - decimal.TryParse(s.Trim(), out i); - list.Add(i); - } - } - return list; - } - - public static List StringCollectionToStringList(string collection) - { - return StringCollectionToStringList(collection, ','); - } - - public static List StringCollectionToStringList(string collection, char split) - { - var list = new List(); - if (!string.IsNullOrEmpty(collection)) - { - var array = collection.Split(split); - foreach (var s in array) - { - list.Add(s); - } - } - return list; - } - - public static string IntDictionaryToStringCollection(Dictionary dictionary) - { - return IntDictionaryToStringCollection(dictionary, ',', '_'); - } - - public static string IntDictionaryToStringCollection(Dictionary dictionary, char split1, char split2) - { - var builder = new StringBuilder(); - - if (dictionary != null && dictionary.Count > 0) - { - foreach (var item in dictionary) - { - builder.Append($"{item.Key}{split2}{item.Value}{split1}"); - } - } - - if (builder.Length > 0) builder.Length--; - return builder.ToString(); - } - - public static Dictionary StringCollectionToIntDictionary(string collection) - { - return StringCollectionToIntDictionary(collection, ',', '_'); - } - - public static Dictionary StringCollectionToIntDictionary(string collection, char split1, char split2) - { - var dictionary = new Dictionary(); - if (!string.IsNullOrEmpty(collection)) - { - var array1 = collection.Split(split1); - foreach (var string1 in array1) - { - if (!string.IsNullOrEmpty(string1)) - { - var array2 = string1.Split(split2); - if (array2.Length == 2) - { - var key = ToInt(array2[0]); - var value = ToInt(array2[1]); - if (key > 0) - { - dictionary[key] = value; - } - } - } - } - } - return dictionary; - } - - public static StringCollection StringCollectionToStringCollection(string collection, char separator) - { - var arraylist = new StringCollection(); - if (!string.IsNullOrEmpty(collection)) - { - var array = collection.Split(separator); - foreach (var s in array) - { - arraylist.Add(s.Trim()); - } - } - return arraylist; - } - - public static ArrayList ObjectCollectionToArrayList(ICollection collection) - { - var arraylist = new ArrayList(); - if (collection != null) - { - foreach (var obj in collection) - { - arraylist.Add(obj); - } - } - return arraylist; - } - - public static List ObjectCollectionToStringList(ICollection collection) - { - var list = new List(); - if (collection != null) - { - foreach (var obj in collection) - { - list.Add(obj.ToString()); - } - } - return list; - } - - public static string ObjectCollectionToString(ICollection collection) - { - var builder = new StringBuilder(); - if (collection != null) - { - foreach (var obj in collection) - { - builder.Append(obj.ToString().Trim()).Append(","); - } - if (builder.Length != 0) builder.Remove(builder.Length - 1, 1); - } - return builder.ToString(); - } - - public static string ObjectCollectionToString(ICollection collection, string separatorStr) - { - var builder = new StringBuilder(); - if (collection != null) - { - foreach (var obj in collection) - { - builder.Append(obj.ToString().Trim()).Append(separatorStr); - } - if (builder.Length != 0) builder.Remove(builder.Length - separatorStr.Length, separatorStr.Length); - } - return builder.ToString(); - } - - public static string ObjectCollectionToString(ICollection collection, string separatorStr, string prefixStr) - { - var builder = new StringBuilder(); - if (collection != null) - { - foreach (var obj in collection) - { - builder.Append(prefixStr + obj.ToString().Trim()).Append(separatorStr); - } - if (builder.Length != 0) builder.Remove(builder.Length - separatorStr.Length, separatorStr.Length); - } - return builder.ToString(); - } - - public static string ObjectCollectionToString(ICollection collection, string separatorStr, string prefixStr, string appendixStr) - { - var builder = new StringBuilder(); - if (collection != null) - { - foreach (var obj in collection) - { - builder.Append(prefixStr + obj.ToString().Trim() + appendixStr).Append(separatorStr); - } - if (builder.Length != 0) builder.Remove(builder.Length - separatorStr.Length, separatorStr.Length); - } - return builder.ToString(); - } - - /// - /// 将对象集合转化为可供Sql语句查询的In()条件,如将集合{'ss','xx','ww'}转化为字符串"'ss','xx','ww'"。 - /// - /// 非数字的集合 - /// 可供Sql语句查询的In()条件字符串,各元素用单引号包围 - public static string ToSqlInStringWithQuote(ICollection collection) - { - var builder = new StringBuilder(); - if (collection != null) - { - foreach (var obj in collection) - { - builder.Append("'").Append(obj).Append("'").Append(","); - } - if (builder.Length != 0) builder.Remove(builder.Length - 1, 1); - } - return builder.Length == 0 ? "null" : builder.ToString(); - } - - /// - /// 将数字集合转化为可供Sql语句查询的In()条件,如将集合{2,3,4}转化为字符串"2,3,4"。 - /// - /// 非数字的集合 - /// 可供Sql语句查询的In()条件字符串,各元素不使用单引号包围 - public static string ToSqlInStringWithoutQuote(ICollection collection) - { - var builder = new StringBuilder(); - if (collection != null) - { - foreach (var obj in collection) - { - builder.Append(obj).Append(","); - } - if (builder.Length != 0) builder.Remove(builder.Length - 1, 1); - } - return builder.Length == 0 ? "null" : builder.ToString(); - } - - public static DataView ObjectCollectionToDataView(string columnName, ICollection collection) - { - var myTable = new DataTable("myTable"); - var column = new DataColumn(columnName); - myTable.Columns.Add(column); - foreach (var value in collection) - { - var row = myTable.NewRow(); - row[columnName] = value; - myTable.Rows.Add(row); - } - var myDataView = new DataView(myTable); - return myDataView; - } - - - public static string[] ArrayListToStringArray(ArrayList arraylist) - { - return (string[])arraylist.ToArray(typeof(string)); - } - - public static ArrayList StringArrayToArrayList(string[] array) - { - return new ArrayList(array); - } - - public static List StringArrayToStringList(string[] array) - { - return new List(array); - } - - //将IDictionary转换为NameValueCollection - public static NameValueCollection ToNameValueCollection(IDictionary dictionary) - { - var nameValueMap = new NameValueCollection(); - foreach (var key in dictionary.Keys) - { - var value = dictionary[key]; - nameValueMap.Add(key.ToString(), value.ToString()); - } - return nameValueMap; - } - - public static NameValueCollection ToNameValueCollection(string separateString) - { - if (!string.IsNullOrEmpty(separateString)) - { - separateString = separateString.Replace("/u0026", "&"); - } - return ToNameValueCollection(separateString, '&'); - } - - public static NameValueCollection ToNameValueCollection(string separateString, char seperator) - { - var attributes = new NameValueCollection(); - if (!string.IsNullOrEmpty(separateString)) - { - var pairs = separateString.Split(seperator); - foreach (var pair in pairs) - { - if (pair.IndexOf("=", StringComparison.Ordinal) != -1) - { - var name = StringUtils.ValueFromUrl(pair.Split('=')[0]); - var value = StringUtils.ValueFromUrl(pair.Split('=')[1]); - attributes.Add(name, value); - } - } - } - return attributes; - } - - public static Dictionary ObjectToDictionary(object source) - { - return source.GetType().GetProperties().ToDictionary - ( - propInfo => propInfo.Name, - propInfo => propInfo.GetValue(source, null) - ); - } - - public static Dictionary ToDictionary(NameValueCollection attributes) - { - var dic = new Dictionary(); - if (attributes != null && attributes.Count > 0) - { - foreach (string key in attributes.Keys) - { - dic[key] = attributes[key]; - } - } - return dic; - } - - public static Dictionary ToDictionary(string separateString) - { - if (!string.IsNullOrEmpty(separateString)) - { - separateString = separateString.Replace("/u0026", "&"); - } - return ToDictionary(separateString, '&'); - } - - public static Dictionary ToDictionary(string separateString, char seperator) - { - var attributes = new Dictionary(); - if (!string.IsNullOrEmpty(separateString)) - { - var pairs = separateString.Split(seperator); - foreach (var pair in pairs) - { - if (pair.IndexOf("=", StringComparison.Ordinal) != -1) - { - var name = StringUtils.ValueFromUrl(pair.Split('=')[0]); - var value = StringUtils.ValueFromUrl(pair.Split('=')[1]); - attributes.Add(name, value); - } - } - } - return attributes; - } - - public static string NameValueCollectionToString(NameValueCollection attributes) - { - return NameValueCollectionToString(attributes, '&'); - } - - public static string NameValueCollectionToString(NameValueCollection attributes, char seperator) - { - if (attributes == null || attributes.Count <= 0) return string.Empty; - - var builder = new StringBuilder(); - foreach (string key in attributes.Keys) - { - builder.Append( - $@"{StringUtils.ValueToUrl(key)}={StringUtils.ValueToUrl(attributes[key])}{seperator}"); - } - builder.Length--; - return builder.ToString(); - } - - public static string NameValueCollectionToString(LowerNameValueCollection attributes) - { - return NameValueCollectionToString(attributes, '&'); - } - - public static string NameValueCollectionToString(LowerNameValueCollection attributes, char seperator) - { - if (attributes == null || attributes.Count <= 0) return string.Empty; - - var builder = new StringBuilder(); - foreach (var key in attributes.Keys) - { - builder.Append( - $@"{StringUtils.ValueToUrl(key)}={StringUtils.ValueToUrl(attributes.Get(key))}{seperator}"); - } - builder.Length--; - return builder.ToString(); - } - - public static string DictionaryToString(Dictionary attributes) - { - return DictionaryToString(attributes, '&'); - } - - public static string DictionaryToString(Dictionary attributes, char seperator) - { - var builder = new StringBuilder(); - if (attributes != null && attributes.Count > 0) - { - foreach (var key in attributes.Keys) - { - builder.Append( - $@"{StringUtils.ValueToUrl(key)}={StringUtils.ValueToUrl(attributes[key])}{seperator}"); - } - builder.Length--; - } - return builder.ToString(); - } - - public static string ToAttributesString(LowerNameValueCollection attributes) - { - var builder = new StringBuilder(); - if (attributes != null && attributes.Count > 0) - { - foreach (var key in attributes.Keys) - { - var value = attributes.Get(key); - if (!string.IsNullOrEmpty(value)) - { - value = value.Replace("\"", "'"); - } - builder.Append($@"{key}=""{value}"" "); - } - builder.Length--; - } - return builder.ToString(); - } - - public static string ToAttributesString(NameValueCollection attributes) - { - var builder = new StringBuilder(); - if (attributes != null && attributes.Count > 0) - { - foreach (string key in attributes.Keys) - { - var value = attributes[key]; - if (!string.IsNullOrEmpty(value)) - { - value = value.Replace("\"", "'"); - } - builder.Append($@"{key}=""{value}"" "); - } - builder.Length--; - } - return builder.ToString(); - } - - public static string ToAttributesString(StringDictionary attributes) - { - var builder = new StringBuilder(); - if (attributes != null && attributes.Count > 0) - { - foreach (string key in attributes.Keys) - { - var value = attributes[key]; - if (!string.IsNullOrEmpty(value)) - { - value = value.Replace("\"", "'"); - } - builder.Append($@"{key}=""{value}"" "); - } - builder.Length--; - } - return builder.ToString(); - } - - public static string ToAttributesString(Dictionary attributes) - { - var builder = new StringBuilder(); - if (attributes != null && attributes.Count > 0) - { - foreach (var key in attributes.Keys) - { - var value = attributes[key]; - if (!string.IsNullOrEmpty(value)) - { - value = value.Replace("\"", "'"); - } - builder.Append($@"{key}=""{value}"" "); - } - builder.Length--; - } - return builder.ToString(); - } - - public static NameValueCollection ParseJsonStringToNameValueCollection(string jsonString) - { - var nameValueCollection = new NameValueCollection(); - if (!string.IsNullOrEmpty(jsonString)) - { - jsonString = jsonString.Trim().TrimStart('{').TrimEnd('}'); - var array1 = jsonString.Split(','); - foreach (var s1 in array1) - { - if (s1.IndexOf(':') != -1) - { - var name = s1.Substring(0, s1.IndexOf(':')); - var value = s1.Substring(s1.IndexOf(':') + 1); - - nameValueCollection.Set(name.Trim().Trim('"', '\''), value.Trim().Trim('"', '\'')); - } - } - } - return nameValueCollection; - } - - public static NameValueCollection ParseJsonStringToNameValueCollection(string jsonString, bool isRecursive) - { - if (!isRecursive) - return ParseJsonStringToNameValueCollection(jsonString); - - var nameValueCollection = new NameValueCollection(); - if (!string.IsNullOrEmpty(jsonString)) - { - jsonString = jsonString.Trim().TrimStart('{').TrimEnd('}'); - var array1 = jsonString.Split(','); - foreach (var s1 in array1) - { - if (s1.IndexOf(':') != -1) - { - var name = s1.Substring(0, s1.IndexOf(':')); - var value = s1.Substring(s1.IndexOf(':') + 1); - if (value.IndexOf("{", StringComparison.Ordinal) != -1) - { - nameValueCollection.Add(ParseJsonStringToNameValueCollection(value, true)); - } - else - { - nameValueCollection.Set(name.Trim().Trim('"', '\''), value.Trim().Trim('"', '\'')); - } - } - } - } - return nameValueCollection; - } - - - public static string NameValueCollectionToJsonString(NameValueCollection attributes) - { - var jsonString = new StringBuilder("{"); - if (attributes != null && attributes.Count > 0) - { - foreach (string key in attributes.Keys) - { - var value = attributes[key]; - value = value?.Replace("\\", "\\\\").Replace("\"", "\\\\\\\"").Replace("\r\n", string.Empty); - jsonString.AppendFormat(@"""{0}"": ""{1}"",", key, value); - } - jsonString.Length--; - } - jsonString.Append("}"); - return jsonString.ToString(); - } - - public static string NameValueCollectionToXmlString(NameValueCollection attributes) - { - var xmlString = new StringBuilder("\r\n"); - if (attributes != null && attributes.Count > 0) - { - foreach (string key in attributes.Keys) - { - var value = attributes[key]; - value = value?.Replace("\\", "\\\\").Replace("\"", "\\\\\\\"").Replace("\r\n", string.Empty); - xmlString.AppendFormat("<{0}>{1}\r\n", key, value); - } - } - return xmlString.ToString(); - } - - public static void SetOrRemoveAttributeLowerCase(NameValueCollection attributes, string key, string value) - { - if (attributes == null || string.IsNullOrEmpty(key)) return; - - SetOrRemoveAttribute(attributes, key.ToLower(), value); - } - - public static void SetOrRemoveAttribute(NameValueCollection attributes, string key, string value) - { - if (attributes == null || string.IsNullOrEmpty(key)) return; - - if (!string.IsNullOrEmpty(value)) - { - attributes[key] = value; - } - else - { - attributes.Remove(key); - } - } - - public static int GetMbSize(int kbSize) - { - var retval = 0; - if (kbSize >= 1024 && kbSize % 1024 == 0) - { - retval = kbSize / 1024; - } - return retval; - } - - public static long GetKbSize(long byteSize) - { - long fileKbSize = Convert.ToUInt32(Math.Ceiling((double)byteSize / 1024)); - if (fileKbSize == 0) - { - fileKbSize = 1; - } - return fileKbSize; - } - - public static int GetIntFromQueryString(NameValueCollection queryString, string key) - { - var queryStringValue = queryString[key]; - - if (string.IsNullOrEmpty(queryStringValue)) return 0; - - if (queryStringValue.IndexOf("#", StringComparison.Ordinal) > 0) - { - queryStringValue = queryStringValue.Substring(0, queryStringValue.IndexOf("#", StringComparison.Ordinal)); - } - - return ToInt(queryStringValue); - } - - public static IList GetList(IList list, int startNum, int totalNum) - { - if (list == null) return null; - IList retval = new List(); - for (var i = 0; i < list.Count; i++) - { - if (i + 1 >= startNum) - { - retval.Add(list[i]); - } - if (totalNum > 0 && retval.Count >= totalNum) break; - } - return retval; - } - - public static string EscapeHtml(string content) - { - var sb = new StringBuilder(); - var ba = Encoding.Unicode.GetBytes(content); - for (var i = 0; i < ba.Length; i += 2) - { - sb.Append("%u"); - sb.Append(ba[i + 1].ToString("X2")); - sb.Append(ba[i].ToString("X2")); - } - return sb.ToString(); - } - - #region 汉字转拼音 - - private static readonly int[] Pyvalue = - { - -20319, -20317, -20304, -20295, -20292, -20283, -20265, -20257, -20242, -20230, -20051, -20036, -20032, - -20026, -20002, -19990, -19986, -19982, -19976, -19805, -19784, -19775, -19774, -19763, -19756, -19751, - -19746, -19741, -19739, -19728, - -19725, -19715, -19540, -19531, -19525, -19515, -19500, -19484, -19479, -19467, -19289, -19288, -19281, - -19275, -19270, -19263, - -19261, -19249, -19243, -19242, -19238, -19235, -19227, -19224, -19218, -19212, -19038, -19023, -19018, - -19006, -19003, -18996, - -18977, -18961, -18952, -18783, -18774, -18773, -18763, -18756, -18741, -18735, -18731, -18722, -18710, - -18697, -18696, -18526, - -18518, -18501, -18490, -18478, -18463, -18448, -18447, -18446, -18239, -18237, -18231, -18220, -18211, - -18201, -18184, -18183, - -18181, -18012, -17997, -17988, -17970, -17964, -17961, -17950, -17947, -17931, -17928, -17922, -17759, - -17752, -17733, -17730, - -17721, -17703, -17701, -17697, -17692, -17683, -17676, -17496, -17487, -17482, -17468, -17454, -17433, - -17427, -17417, -17202, - -17185, -16983, -16970, -16942, -16915, -16733, -16708, -16706, -16689, -16664, -16657, -16647, -16474, - -16470, -16465, -16459, - -16452, -16448, -16433, -16429, -16427, -16423, -16419, -16412, -16407, -16403, -16401, -16393, -16220, - -16216, -16212, -16205, - -16202, -16187, -16180, -16171, -16169, -16158, -16155, -15959, -15958, -15944, -15933, -15920, -15915, - -15903, -15889, -15878, - -15707, -15701, -15681, -15667, -15661, -15659, -15652, -15640, -15631, -15625, -15454, -15448, -15436, - -15435, -15419, -15416, - -15408, -15394, -15385, -15377, -15375, -15369, -15363, -15362, -15183, -15180, -15165, -15158, -15153, - -15150, -15149, -15144, - -15143, -15141, -15140, -15139, -15128, -15121, -15119, -15117, -15110, -15109, -14941, -14937, -14933, - -14930, -14929, -14928, - -14926, -14922, -14921, -14914, -14908, -14902, -14894, -14889, -14882, -14873, -14871, -14857, -14678, - -14674, -14670, -14668, - -14663, -14654, -14645, -14630, -14594, -14429, -14407, -14399, -14384, -14379, -14368, -14355, -14353, - -14345, -14170, -14159, - -14151, -14149, -14145, -14140, -14137, -14135, -14125, -14123, -14122, -14112, -14109, -14099, -14097, - -14094, -14092, -14090, - -14087, -14083, -13917, -13914, -13910, -13907, -13906, -13905, -13896, -13894, -13878, -13870, -13859, - -13847, -13831, -13658, - -13611, -13601, -13406, -13404, -13400, -13398, -13395, -13391, -13387, -13383, -13367, -13359, -13356, - -13343, -13340, -13329, - -13326, -13318, -13147, -13138, -13120, -13107, -13096, -13095, -13091, -13076, -13068, -13063, -13060, - -12888, -12875, -12871, - -12860, -12858, -12852, -12849, -12838, -12831, -12829, -12812, -12802, -12607, -12597, -12594, -12585, - -12556, -12359, -12346, - -12320, -12300, -12120, -12099, -12089, -12074, -12067, -12058, -12039, -11867, -11861, -11847, -11831, - -11798, -11781, -11604, - -11589, -11536, -11358, -11340, -11339, -11324, -11303, -11097, -11077, -11067, -11055, -11052, -11045, - -11041, -11038, -11024, - -11020, -11019, -11018, -11014, -10838, -10832, -10815, -10800, -10790, -10780, -10764, -10587, -10544, - -10533, -10519, -10331, - -10329, -10328, -10322, -10315, -10309, -10307, -10296, -10281, -10274, -10270, -10262, -10260, -10256, - -10254 - }; - - private static readonly string[] Pystr = - { - "a", "ai", "an", "ang", "ao", "ba", "bai", "ban", "bang", "bao", "bei", "ben", "beng", "bi", "bian", "biao", - "bie", "bin", "bing", "bo", "bu", "ca", "cai", "can", "cang", "cao", "ce", "ceng", "cha", "chai", "chan", - "chang", "chao", "che", "chen", - "cheng", "chi", "chong", "chou", "chu", "chuai", "chuan", "chuang", "chui", "chun", "chuo", "ci", "cong", - "cou", "cu", "cuan", "cui", - "cun", "cuo", "da", "dai", "dan", "dang", "dao", "de", "deng", "di", "dian", "diao", "die", "ding", "diu", - "dong", "dou", "du", "duan", - "dui", "dun", "duo", "e", "en", "er", "fa", "fan", "fang", "fei", "fen", "feng", "fo", "fou", "fu", "ga", - "gai", "gan", "gang", "gao", - "ge", "gei", "gen", "geng", "gong", "gou", "gu", "gua", "guai", "guan", "guang", "gui", "gun", "guo", "ha", - "hai", "han", "hang", - "hao", "he", "hei", "hen", "heng", "hong", "hou", "hu", "hua", "huai", "huan", "huang", "hui", "hun", "huo", - "ji", "jia", "jian", - "jiang", "jiao", "jie", "jin", "jing", "jiong", "jiu", "ju", "juan", "jue", "jun", "ka", "kai", "kan", - "kang", "kao", "ke", "ken", - "keng", "kong", "kou", "ku", "kua", "kuai", "kuan", "kuang", "kui", "kun", "kuo", "la", "lai", "lan", "lang", - "lao", "le", "lei", - "leng", "li", "lia", "lian", "liang", "liao", "lie", "lin", "ling", "liu", "long", "lou", "lu", "lv", "luan", - "lue", "lun", "luo", - "ma", "mai", "man", "mang", "mao", "me", "mei", "men", "meng", "mi", "mian", "miao", "mie", "min", "ming", - "miu", "mo", "mou", "mu", - "na", "nai", "nan", "nang", "nao", "ne", "nei", "nen", "neng", "ni", "nian", "niang", "niao", "nie", "nin", - "ning", "niu", "nong", - "nu", "nv", "nuan", "nue", "nuo", "o", "ou", "pa", "pai", "pan", "pang", "pao", "pei", "pen", "peng", "pi", - "pian", "piao", "pie", - "pin", "ping", "po", "pu", "qi", "qia", "qian", "qiang", "qiao", "qie", "qin", "qing", "qiong", "qiu", "qu", - "quan", "que", "qun", - "ran", "rang", "rao", "re", "ren", "reng", "ri", "rong", "rou", "ru", "ruan", "rui", "run", "ruo", "sa", - "sai", "san", "sang", - "sao", "se", "sen", "seng", "sha", "shai", "shan", "shang", "shao", "she", "shen", "sheng", "shi", "shou", - "shu", "shua", - "shuai", "shuan", "shuang", "shui", "shun", "shuo", "si", "song", "sou", "su", "suan", "sui", "sun", "suo", - "ta", "tai", - "tan", "tang", "tao", "te", "teng", "ti", "tian", "tiao", "tie", "ting", "tong", "tou", "tu", "tuan", "tui", - "tun", "tuo", - "wa", "wai", "wan", "wang", "wei", "wen", "weng", "wo", "wu", "xi", "xia", "xian", "xiang", "xiao", "xie", - "xin", "xing", - "xiong", "xiu", "xu", "xuan", "xue", "xun", "ya", "yan", "yang", "yao", "ye", "yi", "yin", "ying", "yo", - "yong", "you", - "yu", "yuan", "yue", "yun", "za", "zai", "zan", "zang", "zao", "ze", "zei", "zen", "zeng", "zha", "zhai", - "zhan", "zhang", - "zhao", "zhe", "zhen", "zheng", "zhi", "zhong", "zhou", "zhu", "zhua", "zhuai", "zhuan", "zhuang", "zhui", - "zhun", "zhuo", - "zi", "zong", "zou", "zu", "zuan", "zui", "zun", "zuo" - }; - - public static string ToPinYin(string chrstr) - { - var returnstr = string.Empty; - var nowchar = chrstr.ToCharArray(); - foreach (var t in nowchar) - { - var array = Encoding.Default.GetBytes(t.ToString()); - int i1 = array[0]; - int i2 = array[1]; - var chrasc = i1 * 256 + i2 - 65536; - if (chrasc > 0 && chrasc < 160) - { - returnstr += t; - } - else - { - for (var i = (Pyvalue.Length - 1); i >= 0; i--) - { - if (Pyvalue[i] <= chrasc) - { - returnstr += Pystr[i]; - break; - } - } - } - } - return returnstr; - } - - #endregion - - public static string JsonSerialize(object obj) - { - try - { - var settings = new JsonSerializerSettings - { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }; - var timeFormat = new IsoDateTimeConverter {DateTimeFormat = "yyyy-MM-dd HH:mm:ss"}; - settings.Converters.Add(timeFormat); - - return JsonConvert.SerializeObject(obj, settings); - } - catch - { - return string.Empty; - } - } - - public static T JsonDeserialize(string json) - { - try - { - var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }; - var timeFormat = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" }; - settings.Converters.Add(timeFormat); - - return JsonConvert.DeserializeObject(json, settings); - } - catch - { - return default(T); - } - } - - public static string EncryptStringBySecretKey(string inputString) - { - return EncryptStringBySecretKey(inputString, WebConfigUtils.SecretKey); - } - - public static string EncryptStringBySecretKey(string inputString, string secretKey) - { - if (string.IsNullOrEmpty(inputString)) return string.Empty; - - var encryptor = new DesEncryptor - { - InputString = inputString, - EncryptKey = secretKey - }; - encryptor.DesEncrypt(); - - var retval = encryptor.OutString; - retval = retval.Replace("+", "0add0").Replace("=", "0equals0").Replace("&", "0and0").Replace("?", "0question0").Replace("'", "0quote0").Replace("/", "0slash0"); - - return retval; - } - - public static string DecryptStringBySecretKey(string inputString) - { - return DecryptStringBySecretKey(inputString, WebConfigUtils.SecretKey); - } - - public static string DecryptStringBySecretKey(string inputString, string secretKey) - { - if (string.IsNullOrEmpty(inputString)) return string.Empty; - - inputString = inputString.Replace("0add0", "+").Replace("0equals0", "=").Replace("0and0", "&").Replace("0question0", "?").Replace("0quote0", "'").Replace("0slash0", "/"); - - var encryptor = new DesEncryptor - { - InputString = inputString, - DecryptKey = secretKey - }; - encryptor.DesDecrypt(); - - return encryptor.OutString; - } - } -} diff --git a/SiteServer.Utils/UEditorUploaderForUser.cs b/SiteServer.Utils/UEditorUploaderForUser.cs deleted file mode 100644 index 9a91c1702..000000000 --- a/SiteServer.Utils/UEditorUploaderForUser.cs +++ /dev/null @@ -1,189 +0,0 @@ -using System; -using System.Web; -using System.Collections; -using System.IO; - -namespace SiteServer.Utils -{ - public class UEditorUploaderForUser - { - string state = "SUCCESS"; - - string URL = null; - string currentType = null; - string originalName = null; - HttpPostedFile uploadFile = null; - - /** - * 上传文件的主处理方法 - * @param HttpContext - * @param string - * @param string[] - *@param int - * @return Hashtable - */ - public Hashtable upFile(HttpContext cxt) - { - try - { - uploadFile = cxt.Request.Files[0]; - originalName = uploadFile.FileName; - currentType = getFileExt(); - - var localDirectoryPath = PathUtils.GetUserUploadDirectoryPath(string.Empty); - var localFileName = PathUtils.GetUserUploadFileName(originalName); - var localFilePath = PathUtils.Combine(localDirectoryPath, localFileName); - var fileExtName = PathUtils.GetExtension(originalName); - - //string pathbase = pathbase + DateTime.Now.ToString("yyyy-MM-dd") + "/"; - //uploadpath = cxt.Server.MapPath(pathbase);//获取文件上传路径 - - //格式验证 - //if (checkType(filetype)) - //{ - // state = "不允许的文件类型"; - //} - ////大小验证 - //if (checkSize(size)) - //{ - // state = "文件大小超出网站限制"; - //} - //保存图片 - if (state == "SUCCESS") - { - uploadFile.SaveAs(localFilePath); - URL = PageUtils.GetRootUrlByPhysicalPath(localFilePath); - //URL = pathbase + filename; - } - } - catch (Exception e) - { - state = e.Message; - URL = ""; - } - return getUploadInfo(); - } - - public Hashtable upScrawl(HttpContext cxt, string base64Data) - { - FileStream fs = null; - try - { - var localDirectoryPath = PathUtils.GetUserUploadDirectoryPath(string.Empty); - var fileName = Guid.NewGuid() + ".png"; - var localFilePath = PathUtils.Combine(localDirectoryPath, fileName); - fs = File.Create(localFilePath); - var bytes = Convert.FromBase64String(base64Data); - fs.Write(bytes, 0, bytes.Length); - - URL = PageUtils.GetRootUrlByPhysicalPath(localFilePath); - } - catch - { - state = "未知错误"; - URL = ""; - } - finally - { - fs.Close(); - } - return getUploadInfo(); - } - - /** - * 获取文件信息 - * @param context - * @param string - * @return string - */ - public string getOtherInfo(HttpContext cxt, string field) - { - string info = null; - if (cxt.Request.Form[field] != null && !string.IsNullOrEmpty(cxt.Request.Form[field])) - { - info = field == "fileName" ? cxt.Request.Form[field].Split(',')[1] : cxt.Request.Form[field]; - } - return info; - } - - /** - * 获取上传信息 - * @return Hashtable - */ - private Hashtable getUploadInfo() - { - var infoList = new Hashtable(); - - infoList.Add("state", state); - infoList.Add("url", URL); - - if (currentType != null) - infoList.Add("currentType", currentType); - if (originalName != null) - infoList.Add("originalName", originalName); - return infoList; - } - - /** - * 重命名文件 - * @return string - */ - private string reName() - { - return Guid.NewGuid() + getFileExt(); - } - - /** - * 文件类型检测 - * @return bool - */ - private bool checkType(string[] filetype) - { - currentType = getFileExt(); - return Array.IndexOf(filetype, currentType) == -1; - } - - /** - * 文件大小检测 - * @param int - * @return bool - */ - private bool checkSize(int size) - { - return uploadFile.ContentLength >= (size * 1024 * 1024); - } - - /** - * 获取文件扩展名 - * @return string - */ - private string getFileExt() - { - var temp = uploadFile.FileName.Split('.'); - return "." + temp[temp.Length - 1].ToLower(); - } - - ///** - // * 按照日期自动创建存储文件夹 - // */ - //private void createFolder() - //{ - // if (!Directory.Exists(uploadpath)) - // { - // Directory.CreateDirectory(uploadpath); - // } - //} - - /** - * 删除存储文件夹 - * @param string - */ - public void deleteFolder(string path) - { - //if (Directory.Exists(path)) - //{ - // Directory.Delete(path, true); - //} - } - } -} diff --git a/SiteServer.Utils/ValidateTypeUtils.cs b/SiteServer.Utils/ValidateTypeUtils.cs deleted file mode 100644 index a1814759d..000000000 --- a/SiteServer.Utils/ValidateTypeUtils.cs +++ /dev/null @@ -1,162 +0,0 @@ -using System; -using System.Web.UI.WebControls; -using SiteServer.Plugin; - -namespace SiteServer.Utils -{ - public class ValidateTypeUtils - { - public static string GetText(ValidateType type) - { - if (type == ValidateType.None) - { - return "无"; - } - if (type == ValidateType.Chinese) - { - return "中文"; - } - if (type == ValidateType.English) - { - return "英文"; - } - if (type == ValidateType.Email) - { - return "Email格式"; - } - if (type == ValidateType.Url) - { - return "网址格式"; - } - if (type == ValidateType.Phone) - { - return "电话号码"; - } - if (type == ValidateType.Mobile) - { - return "手机号码"; - } - if (type == ValidateType.Integer) - { - return "整数"; - } - if (type == ValidateType.Currency) - { - return "货币格式"; - } - if (type == ValidateType.Zip) - { - return "邮政编码"; - } - if (type == ValidateType.IdCard) - { - return "身份证号码"; - } - if (type == ValidateType.RegExp) - { - return "正则表达式验证"; - } - throw new Exception(); - } - - public static ValidateType GetEnumType(string typeStr) - { - var retval = ValidateType.None; - - if (Equals(ValidateType.None, typeStr)) - { - retval = ValidateType.None; - } - else if (Equals(ValidateType.Chinese, typeStr)) - { - retval = ValidateType.Chinese; - } - else if (Equals(ValidateType.Currency, typeStr)) - { - retval = ValidateType.Currency; - } - else if (Equals(ValidateType.RegExp, typeStr)) - { - retval = ValidateType.RegExp; - } - else if (Equals(ValidateType.Email, typeStr)) - { - retval = ValidateType.Email; - } - else if (Equals(ValidateType.English, typeStr)) - { - retval = ValidateType.English; - } - else if (Equals(ValidateType.IdCard, typeStr)) - { - retval = ValidateType.IdCard; - } - else if (Equals(ValidateType.Integer, typeStr)) - { - retval = ValidateType.Integer; - } - else if (Equals(ValidateType.Mobile, typeStr)) - { - retval = ValidateType.Mobile; - } - else if (Equals(ValidateType.Phone, typeStr)) - { - retval = ValidateType.Phone; - } - else if (Equals(ValidateType.Url, typeStr)) - { - retval = ValidateType.Url; - } - else if (Equals(ValidateType.Zip, typeStr)) - { - retval = ValidateType.Zip; - } - - return retval; - } - - public static bool Equals(ValidateType type, string typeStr) - { - if (string.IsNullOrEmpty(typeStr)) return false; - if (string.Equals(type.Value.ToLower(), typeStr.ToLower())) - { - return true; - } - return false; - } - - public static bool Equals(string typeStr, ValidateType type) - { - return Equals(type, typeStr); - } - - public static ListItem GetListItem(ValidateType type, bool selected) - { - var item = new ListItem(GetText(type), type.Value); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(ValidateType.None, false)); - listControl.Items.Add(GetListItem(ValidateType.Chinese, false)); - listControl.Items.Add(GetListItem(ValidateType.English, false)); - listControl.Items.Add(GetListItem(ValidateType.Email, false)); - listControl.Items.Add(GetListItem(ValidateType.Url, false)); - listControl.Items.Add(GetListItem(ValidateType.Phone, false)); - listControl.Items.Add(GetListItem(ValidateType.Mobile, false)); - listControl.Items.Add(GetListItem(ValidateType.Integer, false)); - listControl.Items.Add(GetListItem(ValidateType.Currency, false)); - listControl.Items.Add(GetListItem(ValidateType.Zip, false)); - listControl.Items.Add(GetListItem(ValidateType.IdCard, false)); - listControl.Items.Add(GetListItem(ValidateType.RegExp, false)); - } - } - } -} diff --git a/SiteServer.Utils/WebConfigUtils.cs b/SiteServer.Utils/WebConfigUtils.cs deleted file mode 100644 index 9463458aa..000000000 --- a/SiteServer.Utils/WebConfigUtils.cs +++ /dev/null @@ -1,299 +0,0 @@ -using System.Runtime.CompilerServices; -using System.Text; -using System.Xml; -using SiteServer.Plugin; - -namespace SiteServer.Utils -{ - public class WebConfigUtils - { - public const string WebConfigFileName = "Web.config"; - /// - /// 获取当前正在执行的服务器应用程序的根目录的物理文件系统路径。 - /// - public static string PhysicalApplicationPath { get; private set; } - - public static bool IsProtectData { get; private set; } - public static DatabaseType DatabaseType { get; private set; } - - private static string _connectionString; - - public static string ConnectionStringUserId { get; private set; } - - public static string ConnectionString - { - get { return _connectionString; } - private set - { - _connectionString = value; - ConnectionStringUserId = SqlUtils.GetConnectionStringUserId(_connectionString); - } - } - - public static string AdminDirectory { get; private set; } - public static string SecretKey { get; private set; } - - public static bool IsNightlyUpdate { get; private set; } - - public static void Load(string physicalApplicationPath) - { - PhysicalApplicationPath = physicalApplicationPath; - - var isProtectData = false; - var databaseType = string.Empty; - var connectionString = string.Empty; - try - { - var doc = new XmlDocument(); - - var configFile = PathUtils.Combine(PhysicalApplicationPath, WebConfigFileName); - - doc.Load(configFile); - - var appSettings = doc.SelectSingleNode("configuration/appSettings"); - if (appSettings != null) - { - foreach (XmlNode setting in appSettings) - { - if (setting.Name == "add") - { - var attrKey = setting.Attributes?["key"]; - if (attrKey != null) - { - if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(IsProtectData))) - { - var attrValue = setting.Attributes["value"]; - if (attrValue != null) - { - isProtectData = TranslateUtils.ToBool(attrValue.Value); - } - } - else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(DatabaseType))) - { - var attrValue = setting.Attributes["value"]; - if (attrValue != null) - { - databaseType = attrValue.Value; - } - } - else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(ConnectionString))) - { - var attrValue = setting.Attributes["value"]; - if (attrValue != null) - { - connectionString = attrValue.Value; - } - } - else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(AdminDirectory))) - { - var attrValue = setting.Attributes["value"]; - if (attrValue != null) - { - AdminDirectory = attrValue.Value; - } - } - else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(SecretKey))) - { - var attrValue = setting.Attributes["value"]; - if (attrValue != null) - { - SecretKey = attrValue.Value; - } - } - - else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(IsNightlyUpdate))) - { - var attrValue = setting.Attributes["value"]; - if (attrValue != null) - { - IsNightlyUpdate = TranslateUtils.ToBool(attrValue.Value); - } - } - } - } - } - - if (isProtectData) - { - databaseType = TranslateUtils.DecryptStringBySecretKey(databaseType); - connectionString = TranslateUtils.DecryptStringBySecretKey(connectionString); - } - } - } - catch - { - // ignored - } - - IsProtectData = isProtectData; - DatabaseType = DatabaseTypeUtils.GetEnumType(databaseType); - ConnectionString = connectionString; - if (string.IsNullOrEmpty(AdminDirectory)) - { - AdminDirectory = "siteserver"; - } - if (string.IsNullOrEmpty(SecretKey)) - { - SecretKey = StringUtils.GetShortGuid(); - //SecretKey = "vEnfkn16t8aeaZKG3a4Gl9UUlzf4vgqU9xwh8ZV5"; - } - } - - public static void ResetWebConfig() - { - var configPath = PathUtils.Combine(PhysicalApplicationPath, WebConfigFileName); - ResetWebConfig(configPath); - } - - public static void ResetWebConfig(string configPath) - { - var content = FileUtils.ReadText(configPath, Encoding.UTF8); - FileUtils.WriteText(configPath, Encoding.UTF8, content); - } - - public static void UpdateWebConfig(bool isProtectData, DatabaseType databaseType, string connectionString, - string adminDirectory, string secretKey, bool isNightlyUpdate) - { - var configPath = PathUtils.Combine(PhysicalApplicationPath, WebConfigFileName); - UpdateWebConfig(configPath, isProtectData, databaseType, connectionString, adminDirectory, secretKey, isNightlyUpdate); - } - - public static void UpdateWebConfig(string configPath, bool isProtectData, DatabaseType databaseType, string connectionString, string adminDirectory, string secretKey, bool isNightlyUpdate) - { - var doc = new XmlDocument(); - doc.Load(configPath); - var dirty = false; - var appSettings = doc.SelectSingleNode("configuration/appSettings"); - if (appSettings != null) - { - foreach (XmlNode setting in appSettings) - { - if (setting.Name == "add") - { - var attrKey = setting.Attributes?["key"]; - if (attrKey != null) - { - if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(IsProtectData))) - { - var attrValue = setting.Attributes["value"]; - if (attrValue != null) - { - attrValue.Value = isProtectData.ToString(); - dirty = true; - } - } - else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(DatabaseType))) - { - var attrValue = setting.Attributes["value"]; - if (attrValue != null) - { - attrValue.Value = databaseType.Value; - if (isProtectData) - { - attrValue.Value = TranslateUtils.EncryptStringBySecretKey(attrValue.Value, secretKey); - } - dirty = true; - } - } - else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(ConnectionString))) - { - var attrValue = setting.Attributes["value"]; - if (attrValue != null) - { - attrValue.Value = connectionString; - if (isProtectData) - { - attrValue.Value = TranslateUtils.EncryptStringBySecretKey(attrValue.Value, secretKey); - } - dirty = true; - } - } - else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(AdminDirectory))) - { - var attrValue = setting.Attributes["value"]; - if (attrValue != null) - { - attrValue.Value = adminDirectory; - dirty = true; - } - } - else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(SecretKey))) - { - var attrValue = setting.Attributes["value"]; - if (attrValue != null) - { - attrValue.Value = secretKey; - dirty = true; - } - } - else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(IsNightlyUpdate))) - { - var attrValue = setting.Attributes["value"]; - if (attrValue != null) - { - attrValue.Value = isNightlyUpdate.ToString(); - dirty = true; - } - } - } - } - } - } - - if (dirty) - { - var writer = new XmlTextWriter(configPath, Encoding.UTF8) - { - Formatting = Formatting.Indented - }; - doc.Save(writer); - writer.Flush(); - writer.Close(); - } - - IsProtectData = isProtectData; - DatabaseType = databaseType; - ConnectionString = connectionString; - } - - public static string GetConnectionStringByName(string name) - { - var connectionString = string.Empty; - try - { - var doc = new XmlDocument(); - - var configFile = PathUtils.Combine(PhysicalApplicationPath, WebConfigFileName); - - doc.Load(configFile); - - var appSettings = doc.SelectSingleNode("configuration/appSettings"); - if (appSettings != null) - { - foreach (XmlNode setting in appSettings) - { - if (setting.Name != "add") continue; - - var attrKey = setting.Attributes?["key"]; - if (attrKey == null) continue; - - if (!StringUtils.EqualsIgnoreCase(attrKey.Value, name)) continue; - - var attrValue = setting.Attributes["value"]; - if (attrValue != null) - { - connectionString = attrValue.Value; - } - break; - } - } - } - catch - { - // ignored - } - - return connectionString; - } - } -} \ No newline at end of file diff --git a/SiteServer.Utils/XmlUtils.cs b/SiteServer.Utils/XmlUtils.cs deleted file mode 100644 index 36f316b1a..000000000 --- a/SiteServer.Utils/XmlUtils.cs +++ /dev/null @@ -1,87 +0,0 @@ -using System.Xml; - -namespace SiteServer.Utils -{ - public class XmlUtils - { - - public static XmlDocument GetXmlDocument(string xmlContent) - { - var xmlDocument = new XmlDocument(); - try - { - xmlDocument.LoadXml(xmlContent); - } - catch - { - // ignored - } - - return xmlDocument; - } - - - public static string GetXmlNodeInnerText(XmlDocument xmlDocument, string xpath) - { - var innerText = string.Empty; - try - { - var node = xmlDocument.SelectSingleNode(xpath); - if (node != null) - { - innerText = node.InnerText; - } - } - catch - { - // ignored - } - return innerText; - } - - public static XmlNode GetXmlNode(XmlDocument xmlDocument, string xpath) - { - XmlNode node = null; - try - { - node = xmlDocument.SelectSingleNode(xpath); - } - catch - { - // ignored - } - return node; - } - - public static string GetXmlNodeAttribute(XmlDocument xmlDocument, string xpath, string attributeName) - { - return GetXmlNodeAttribute(GetXmlNode(xmlDocument, xpath), attributeName); - } - - public static string GetXmlNodeAttribute(XmlNode node, string attributeName) - { - var retval = string.Empty; - try - { - if (node.Attributes != null) - { - var ie = node.Attributes.GetEnumerator(); - while (ie.MoveNext()) - { - var attr = (XmlAttribute)ie.Current; - if (attr.Name.ToLower().Equals(attributeName.ToLower())) - { - retval = attr.Value; - break; - } - } - } - } - catch - { - // ignored - } - return retval; - } - } -} diff --git a/SiteServer.Utils/ZipUtils.cs b/SiteServer.Utils/ZipUtils.cs deleted file mode 100644 index 48a4dd05d..000000000 --- a/SiteServer.Utils/ZipUtils.cs +++ /dev/null @@ -1,200 +0,0 @@ -using System; -using System.IO; -using ICSharpCode.SharpZipLib.Checksums; -using ICSharpCode.SharpZipLib.Zip; - -namespace SiteServer.Utils -{ - public class ZipUtils - { - private ZipUtils() - { - } - - public static void PackFiles(string zipFilePath, string directoryPath) - { - var fz = new FastZip {CreateEmptyDirectories = true}; - fz.CreateZip(zipFilePath, directoryPath, true, string.Empty); - } - - public static void UnpackFiles(string zipFilePath, string directoryPath) - { - var fz = new FastZip(); - fz.ExtractZip(zipFilePath, directoryPath, null); - } - - public static void UnpackFilesByExtension(string zipFilePath, string directoryPath, string extension) - { - var fz = new FastZip(); - fz.ExtractZip(zipFilePath, directoryPath, ".*\\" + extension + "$"); - } - - //public static bool UnpackFiles(string zipFilePath, string directoryPath) - //{ - // if (!Directory.Exists(directoryPath)) - // Directory.CreateDirectory(directoryPath); - - // ZipInputStream s = new ZipInputStream(File.OpenRead(zipFilePath)); - - // ZipEntry theEntry; - // while ((theEntry = s.GetNextEntry()) != null) - // { - // string directoryName = Path.GetDirectoryName(theEntry.Name); - // string fileName = Path.GetFileName(theEntry.Name); - - // if (directoryName != string.Empty) - // Directory.CreateDirectory(directoryPath + directoryName); - - // if (fileName != string.Empty) - // { - // FileStream streamWriter = File.Create(Path.Combine(directoryPath, theEntry.Name)); - - // int size = 2048; - // byte[] data = new byte[2048]; - // while (true) - // { - // size = s.Read(data, 0, data.Length); - // if (size > 0) - // { - // streamWriter.Write(data, 0, size); - // } - // else - // { - // break; - // } - // } - - // streamWriter.Close(); - // } - // } - // s.Close(); - // return true; - //} - - - public static void Zip(string directoryPath, string zipFilePath) - { - var filenames = Directory.GetFiles(directoryPath); - - var crc = new Crc32(); - var s = new ZipOutputStream(File.Create(zipFilePath)); - - s.SetLevel(6); // 0 - store only to 9 - means best compression - - foreach (var file in filenames) - { - var fs = File.OpenRead(file); - - var buffer = new byte[fs.Length]; - fs.Read(buffer, 0, buffer.Length); - var entry = new ZipEntry(file) - { - DateTime = DateTime.Now, - Size = fs.Length - }; - - // set Size and the crc, because the information - // about the size and crc should be stored in the header - // if it is not set it is automatically written in the footer. - // (in this case size == crc == -1 in the header) - // Some ZIP programs have problems with zip files that don't store - // the size and crc in the header. - fs.Close(); - - crc.Reset(); - crc.Update(buffer); - - entry.Crc = crc.Value; - - s.PutNextEntry(entry); - - s.Write(buffer, 0, buffer.Length); - - } - - s.Finish(); - s.Close(); - } - - - public static void UnZip(string directoryPath, string zipFilePath) - { - var s = new ZipInputStream(File.OpenRead(zipFilePath)); - - ZipEntry theEntry; - while ((theEntry = s.GetNextEntry()) != null) - { - var fileInfo = new FileInfo(theEntry.Name); - var fileName = fileInfo.Name; - - // create directory - DirectoryUtils.CreateDirectoryIfNotExists(directoryPath); - - if (fileName == string.Empty) continue; - - var filePath = directoryPath + Path.DirectorySeparatorChar + fileName; - var streamWriter = File.Create(filePath); - - var data = new byte[2048]; - while (true) - { - var size = s.Read(data, 0, data.Length); - if (size > 0) - { - streamWriter.Write(data, 0, size); - } - else - { - break; - } - } - - streamWriter.Close(); - } - s.Close(); - } - - - -// public static void UnZip(string zipFilePath) -// { -// ZipInputStream s = new ZipInputStream(File.OpenRead(zipFilePath)); -// -// ZipEntry theEntry; -// while ((theEntry = s.GetNextEntry()) != null) -// { -// -// Console.WriteLine(theEntry.Name); -// -// string directoryName = Path.GetDirectoryName(theEntry.Name); -// string fileName = Path.GetFileName(theEntry.Name); -// -// // create directory -// Directory.CreateDirectory(directoryName); -// -// if (fileName != string.Empty) -// { -// FileStream streamWriter = File.Create(theEntry.Name); -// -// int size = 2048; -// byte[] data = new byte[2048]; -// while (true) -// { -// size = s.Read(data, 0, data.Length); -// if (size > 0) -// { -// streamWriter.Write(data, 0, size); -// } -// else -// { -// break; -// } -// } -// -// streamWriter.Close(); -// } -// } -// s.Close(); -// } - } -} diff --git a/SiteServer.Utils/app.config b/SiteServer.Utils/app.config deleted file mode 100644 index 1711bdb0b..000000000 --- a/SiteServer.Utils/app.config +++ /dev/null @@ -1,34 +0,0 @@ - - - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SiteServer.Utils/packages.config b/SiteServer.Utils/packages.config deleted file mode 100644 index a2be04d56..000000000 --- a/SiteServer.Utils/packages.config +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/.gitignore b/SiteServer.Web/.gitignore deleted file mode 100644 index f8f6fee88..000000000 --- a/SiteServer.Web/.gitignore +++ /dev/null @@ -1,38 +0,0 @@ -bin/ -obj/ -home/ -SiteFiles/BackupFiles/ -SiteFiles/Plugins/ -SiteFiles/packages/ -SiteFiles/SiteTemplates/ -SiteFiles/TemporaryFiles/ -SiteFiles/UserFiles/test/ -test1/ -test2/ -test3/ -test4/ -test5/ -test6/ -test7/ -test8/ -test9/ -test10/ -test11/ -test12/ -test13/ -test14/ -test15/ -test16/ -test17/ -test18/ -test19/ -test20/ -test21/ -test22/ -test23/ -test24/ -test25/ -test26/ -test27/ -test28/ -test29/ \ No newline at end of file diff --git a/SiteServer.Web/Controllers/Http/PluginHttpController.cs b/SiteServer.Web/Controllers/Http/PluginHttpController.cs deleted file mode 100644 index e935620a3..000000000 --- a/SiteServer.Web/Controllers/Http/PluginHttpController.cs +++ /dev/null @@ -1,242 +0,0 @@ -using System; -using System.Net; -using System.Net.Http; -using System.Web.Http; -using SiteServer.CMS.Controllers.Http; -using SiteServer.CMS.Core; -using SiteServer.CMS.Plugin; - -namespace SiteServer.API.Controllers.Http -{ - [RoutePrefix("api")] - public class PluginHttpController : ApiController - { - [HttpGet, Route(ApiRoutePluginHttp.Route)] - public HttpResponseMessage Get(string pluginId) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - return service?.HttpGet == null - ? Request.CreateResponse(HttpStatusCode.NotFound) - : service.HttpGet.Invoke(request); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message); - } - } - - [HttpGet, Route(ApiRoutePluginHttp.RouteName)] - public HttpResponseMessage Get(string pluginId, string name) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - return service?.HttpGetWithName == null - ? Request.CreateResponse(HttpStatusCode.NotFound) - : service.HttpGetWithName.Invoke(request, name); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message); - } - } - - [HttpGet, Route(ApiRoutePluginHttp.RouteNameAndId)] - public HttpResponseMessage Get(string pluginId, string name, string id) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - return service?.HttpGetWithNameAndId == null - ? Request.CreateResponse(HttpStatusCode.NotFound) - : service.HttpGetWithNameAndId.Invoke(request, name, id); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message); - } - } - - [HttpPost, Route(ApiRoutePluginHttp.Route)] - public HttpResponseMessage Post(string pluginId) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - return service?.HttpPost == null - ? Request.CreateResponse(HttpStatusCode.NotFound) - : service.HttpPost.Invoke(request); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message); - } - } - - [HttpPost, Route(ApiRoutePluginHttp.RouteName)] - public HttpResponseMessage Post(string pluginId, string name) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - return service?.HttpPostWithName == null - ? Request.CreateResponse(HttpStatusCode.NotFound) - : service.HttpPostWithName.Invoke(request, name); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message); - } - } - - [HttpPost, Route(ApiRoutePluginHttp.RouteNameAndId)] - public HttpResponseMessage Post(string pluginId, string name, string id) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - return service?.HttpPostWithNameAndId == null - ? Request.CreateResponse(HttpStatusCode.NotFound) - : service.HttpPostWithNameAndId.Invoke(request, name, id); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message); - } - } - - [HttpPut, Route(ApiRoutePluginHttp.Route)] - public HttpResponseMessage Put(string pluginId) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - return service?.HttpPut == null - ? Request.CreateResponse(HttpStatusCode.NotFound) - : service.HttpPut.Invoke(request); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message); - } - } - - [HttpPut, Route(ApiRoutePluginHttp.RouteName)] - public HttpResponseMessage Put(string pluginId, string name) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - return service?.HttpPutWithName == null - ? Request.CreateResponse(HttpStatusCode.NotFound) - : service.HttpPutWithName.Invoke(request, name); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message); - } - } - - [HttpPut, Route(ApiRoutePluginHttp.RouteNameAndId)] - public HttpResponseMessage Put(string pluginId, string name, string id) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - return service?.HttpPutWithNameAndId == null - ? Request.CreateResponse(HttpStatusCode.NotFound) - : service.HttpPutWithNameAndId.Invoke(request, name, id); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message); - } - } - - [HttpDelete, Route(ApiRoutePluginHttp.Route)] - public HttpResponseMessage Delete(string pluginId) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - return service?.HttpDelete == null - ? Request.CreateResponse(HttpStatusCode.NotFound) - : service.HttpDelete.Invoke(request); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message); - } - } - - [HttpDelete, Route(ApiRoutePluginHttp.RouteName)] - public HttpResponseMessage Delete(string pluginId, string name) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - return service?.HttpDeleteWithName == null - ? Request.CreateResponse(HttpStatusCode.NotFound) - : service.HttpDeleteWithName.Invoke(request, name); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message); - } - } - - [HttpDelete, Route(ApiRoutePluginHttp.RouteNameAndId)] - public HttpResponseMessage Delete(string pluginId, string name, string id) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - return service?.HttpDeleteWithNameAndId == null - ? Request.CreateResponse(HttpStatusCode.NotFound) - : service.HttpDeleteWithNameAndId.Invoke(request, name, id); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return Request.CreateResponse(HttpStatusCode.BadRequest, ex.Message); - } - } - } -} diff --git a/SiteServer.Web/Controllers/Json/PluginJsonController.cs b/SiteServer.Web/Controllers/Json/PluginJsonController.cs deleted file mode 100644 index 2a7b6f8b4..000000000 --- a/SiteServer.Web/Controllers/Json/PluginJsonController.cs +++ /dev/null @@ -1,276 +0,0 @@ -using System; -using System.Web.Http; -using SiteServer.CMS.Controllers.Json; -using SiteServer.CMS.Core; -using SiteServer.CMS.Plugin; - -namespace SiteServer.API.Controllers.Json -{ - [RoutePrefix("api")] - public class PluginJsonController : ApiController - { - [HttpGet, Route(ApiRoutePluginJson.Route)] - public IHttpActionResult Get(string pluginId) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - if (service?.JsonGet == null) - { - return NotFound(); - } - - return Ok(service.JsonGet(request)); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpGet, Route(ApiRoutePluginJson.RouteName)] - public IHttpActionResult Get(string pluginId, string name) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - if (service?.JsonGetWithName == null) - { - return NotFound(); - } - - return Ok(service.JsonGetWithName(request, name)); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpGet, Route(ApiRoutePluginJson.RouteNameAndId)] - public IHttpActionResult Get(string pluginId, string name, string id) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - if (service?.JsonGetWithNameAndId == null) - { - return NotFound(); - } - - return Ok(service.JsonGetWithNameAndId(request, name, id)); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpPost, Route(ApiRoutePluginJson.Route)] - public IHttpActionResult Post(string pluginId) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - if (service?.JsonPost == null) - { - return NotFound(); - } - - return Ok(service.JsonPost(request)); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpPost, Route(ApiRoutePluginJson.RouteName)] - public IHttpActionResult Post(string pluginId, string name) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - if (service?.JsonPostWithName == null) - { - return NotFound(); - } - - return Ok(service.JsonPostWithName(request, name)); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpPost, Route(ApiRoutePluginJson.RouteNameAndId)] - public IHttpActionResult Post(string pluginId, string name, string id) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - if (service?.JsonPostWithNameAndId == null) - { - return NotFound(); - } - - return Ok(service.JsonPostWithNameAndId(request, name, id)); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpPut, Route(ApiRoutePluginJson.Route)] - public IHttpActionResult Put(string pluginId) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - if (service?.JsonPut == null) - { - return NotFound(); - } - - return Ok(service.JsonPut(request)); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpPut, Route(ApiRoutePluginJson.RouteName)] - public IHttpActionResult Put(string pluginId, string name) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - if (service?.JsonPutWithName == null) - { - return NotFound(); - } - - return Ok(service.JsonPutWithName(request, name)); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpPut, Route(ApiRoutePluginJson.RouteNameAndId)] - public IHttpActionResult Put(string pluginId, string name, string id) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - if (service?.JsonPutWithNameAndId == null) - { - return NotFound(); - } - - return Ok(service.JsonPutWithNameAndId(request, name, id)); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpDelete, Route(ApiRoutePluginJson.Route)] - public IHttpActionResult Delete(string pluginId) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - if (service?.JsonDelete == null) - { - return NotFound(); - } - - return Ok(service.JsonDelete(request)); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpDelete, Route(ApiRoutePluginJson.RouteName)] - public IHttpActionResult Delete(string pluginId, string name) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - if (service?.JsonDeleteWithName == null) - { - return NotFound(); - } - - return Ok(service.JsonDeleteWithName(request, name)); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpDelete, Route(ApiRoutePluginJson.RouteNameAndId)] - public IHttpActionResult Delete(string pluginId, string name, string id) - { - try - { - var request = new Request(); - var service = PluginManager.GetService(pluginId); - - if (service?.JsonDeleteWithNameAndId == null) - { - return NotFound(); - } - - return Ok(service.JsonDeleteWithNameAndId(request, name, id)); - } - catch (Exception ex) - { - LogUtils.AddPluginErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - } -} diff --git a/SiteServer.Web/Controllers/PluginController.cs b/SiteServer.Web/Controllers/PluginController.cs deleted file mode 100644 index 772c6b7fb..000000000 --- a/SiteServer.Web/Controllers/PluginController.cs +++ /dev/null @@ -1,239 +0,0 @@ -using System; -using System.Net; -using System.Net.Http; -using System.Web.Http; -using SiteServer.CMS.Api; -using SiteServer.CMS.Core; -using SiteServer.CMS.Plugin; -using SiteServer.Plugin; - -namespace SiteServer.API.Controllers -{ - [RoutePrefix("api")] - public class PluginController : ApiController - { - [HttpGet, Route(ApiRoutePlugin.Route)] - public IHttpActionResult Get(string pluginId) - { - try - { - var request = new AuthRequest(); - var service = PluginManager.GetService(pluginId); - - return GetHttpActionResult(service.OnApiGet(new ApiEventArgs(request, null, null))); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpGet, Route(ApiRoutePlugin.RouteAction)] - public IHttpActionResult Get(string pluginId, string name) - { - try - { - var request = new AuthRequest(); - var service = PluginManager.GetService(pluginId); - - return GetHttpActionResult(service.OnApiGet(new ApiEventArgs(request, name, null))); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpGet, Route(ApiRoutePlugin.RouteActionAndId)] - public IHttpActionResult Get(string pluginId, string name, string id) - { - try - { - var request = new AuthRequest(); - var service = PluginManager.GetService(pluginId); - - return GetHttpActionResult(service.OnApiGet(new ApiEventArgs(request, name, id))); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpPost, Route(ApiRoutePlugin.Route)] - public IHttpActionResult Post(string pluginId) - { - try - { - var request = new AuthRequest(); - var service = PluginManager.GetService(pluginId); - - return GetHttpActionResult(service.OnApiPost(new ApiEventArgs(request, null, null))); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpPost, Route(ApiRoutePlugin.RouteAction)] - public IHttpActionResult Post(string pluginId, string name) - { - try - { - var request = new AuthRequest(); - var service = PluginManager.GetService(pluginId); - - return GetHttpActionResult(service.OnApiPost(new ApiEventArgs(request, name, null))); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpPost, Route(ApiRoutePlugin.RouteActionAndId)] - public IHttpActionResult Post(string pluginId, string name, string id) - { - try - { - var request = new AuthRequest(); - var service = PluginManager.GetService(pluginId); - - return GetHttpActionResult(service.OnApiPost(new ApiEventArgs(request, name, id))); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpPut, Route(ApiRoutePlugin.Route)] - public IHttpActionResult Put(string pluginId) - { - try - { - var request = new AuthRequest(); - var service = PluginManager.GetService(pluginId); - - return GetHttpActionResult(service.OnApiPut(new ApiEventArgs(request, null, null))); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpPut, Route(ApiRoutePlugin.RouteAction)] - public IHttpActionResult Put(string pluginId, string name) - { - try - { - var request = new AuthRequest(); - var service = PluginManager.GetService(pluginId); - - return GetHttpActionResult(service.OnApiPut(new ApiEventArgs(request, name, null))); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpPut, Route(ApiRoutePlugin.RouteActionAndId)] - public IHttpActionResult Put(string pluginId, string name, string id) - { - try - { - var request = new AuthRequest(); - var service = PluginManager.GetService(pluginId); - - return GetHttpActionResult(service.OnApiPut(new ApiEventArgs(request, name, id))); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpDelete, Route(ApiRoutePlugin.Route)] - public IHttpActionResult Delete(string pluginId) - { - try - { - var request = new AuthRequest(); - var service = PluginManager.GetService(pluginId); - - return GetHttpActionResult(service.OnApiDelete(new ApiEventArgs(request, null, null))); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpDelete, Route(ApiRoutePlugin.RouteAction)] - public IHttpActionResult Delete(string pluginId, string name) - { - try - { - var request = new AuthRequest(); - var service = PluginManager.GetService(pluginId); - - return GetHttpActionResult(service.OnApiDelete(new ApiEventArgs(request, name, null))); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - [HttpDelete, Route(ApiRoutePlugin.RouteActionAndId)] - public IHttpActionResult Delete(string pluginId, string name, string id) - { - try - { - var request = new AuthRequest(); - var service = PluginManager.GetService(pluginId); - - return GetHttpActionResult(service.OnApiDelete(new ApiEventArgs(request, name, id))); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(pluginId, ex); - return BadRequest(ex.Message); - } - } - - private IHttpActionResult GetHttpActionResult(object retval) - { - if (retval == null) - { - return NotFound(); - } - - switch (retval.GetType().Name) - { - case nameof(String): - return Content(HttpStatusCode.OK, (string)retval); - case nameof(IHttpActionResult): - return (IHttpActionResult)retval; - case nameof(HttpResponseMessage): - return ResponseMessage((HttpResponseMessage)retval); - default: - return Ok(retval); - } - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Administrators/AdministratorsActionsLoginController.cs b/SiteServer.Web/Controllers/Sys/Administrators/AdministratorsActionsLoginController.cs deleted file mode 100644 index 17d7d6e68..000000000 --- a/SiteServer.Web/Controllers/Sys/Administrators/AdministratorsActionsLoginController.cs +++ /dev/null @@ -1,48 +0,0 @@ -using System; -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Administrators; -using SiteServer.CMS.Core; -using SiteServer.CMS.Plugin; - -namespace SiteServer.API.Controllers.Sys.Administrators -{ - [RoutePrefix("api")] - public class AdministratorsActionsLoginController : ApiController - { - [HttpPost, Route(ApiRouteActionsLogin.Route)] - public IHttpActionResult Main() - { - try - { - var request = new AuthRequest(); - var account = request.GetPostString("account"); - var password = request.GetPostString("password"); - if (string.IsNullOrEmpty(account) || string.IsNullOrEmpty(password)) - { - return Unauthorized(); - } - - string userName; - string errorMessage; - if (!DataProvider.AdministratorDao.ValidateAccount(account, password, out userName, out errorMessage)) - { - LogUtils.AddAdminLog(userName, "后台管理员登录失败"); - DataProvider.AdministratorDao.UpdateLastActivityDateAndCountOfFailedLogin(userName); - return Unauthorized(); - } - - DataProvider.AdministratorDao.UpdateLastActivityDateAndCountOfLogin(userName); - request.AdminLogin(userName); - - return Ok(new - { - UserName = userName - }); - } - catch (Exception ex) - { - return InternalServerError(ex); - } - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Administrators/AdministratorsSiteCheckListController.cs b/SiteServer.Web/Controllers/Sys/Administrators/AdministratorsSiteCheckListController.cs deleted file mode 100644 index eb8339d6d..000000000 --- a/SiteServer.Web/Controllers/Sys/Administrators/AdministratorsSiteCheckListController.cs +++ /dev/null @@ -1,59 +0,0 @@ -using System.Collections.Generic; -using System.Web.Http; -using SiteServer.BackgroundPages.Cms; -using SiteServer.CMS.Api.Sys.Administrators; -using SiteServer.CMS.Core; -using SiteServer.CMS.Plugin; - -namespace SiteServer.API.Controllers.Sys.Administrators -{ - [RoutePrefix("api")] - public class AdministratorsSiteCheckListController : ApiController - { - [HttpGet, Route(ApiRouteSiteCheckList.Route)] - public IHttpActionResult Main(string userName) - { - var request = new AuthRequest(); - - if (!request.IsAdminLoggin) - { - return Unauthorized(); - } - - var list = new List(); - var unCheckedList = CheckManager.GetUserCountListUnChecked(request.AdminPermissions); - if (unCheckedList.Count <= 0) return Ok(list); - - var dict = new Dictionary(); - - foreach (var pair in unCheckedList) - { - var siteId = pair.Key; - var count = pair.Value; - if (dict.ContainsKey(siteId)) - { - dict[siteId] = dict[siteId] + count; - } - else - { - dict[siteId] = count; - } - } - - foreach (var siteId in dict.Keys) - { - var count = dict[siteId]; - if (!SiteManager.IsExists(siteId)) continue; - - list.Add(new - { - Url = PageContentCheck.GetRedirectUrl(siteId), - SiteManager.GetSiteInfo(siteId).SiteName, - Count = count - }); - } - - return Ok(list); - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Editors/UEditorController.cs b/SiteServer.Web/Controllers/Sys/Editors/UEditorController.cs deleted file mode 100644 index 62201ddbb..000000000 --- a/SiteServer.Web/Controllers/Sys/Editors/UEditorController.cs +++ /dev/null @@ -1,88 +0,0 @@ -using System.Web; -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Editors; -using SiteServer.CMS.UEditor; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.API.Controllers.Sys.Editors -{ - [RoutePrefix("api")] - public class UEditorController : ApiController - { - [HttpGet, Route(ApiRouteUEditor.Route)] - public void GetMain(int siteId) - { - Main(siteId); - } - - [HttpPost, Route(ApiRouteUEditor.Route)] - public void PostMain(int siteId) - { - Main(siteId); - } - - public void Main(int siteId) - { - var queryString = HttpContext.Current.Request.QueryString; - - Handler action; - switch (queryString["action"]) - { - case "config": - action = new ConfigHandler(HttpContext.Current); - break; - case "uploadimage": - action = new UploadHandler(HttpContext.Current, new UploadConfig - { - AllowExtensions = Config.GetStringList("imageAllowFiles"), - PathFormat = Config.GetString("imagePathFormat"), - SizeLimit = Config.GetInt("imageMaxSize"), - UploadFieldName = Config.GetString("imageFieldName") - }, siteId, EUploadType.Image); - break; - case "uploadscrawl": - action = new UploadHandler(HttpContext.Current, new UploadConfig - { - AllowExtensions = new[] { ".png" }, - PathFormat = Config.GetString("scrawlPathFormat"), - SizeLimit = Config.GetInt("scrawlMaxSize"), - UploadFieldName = Config.GetString("scrawlFieldName"), - Base64 = true, - Base64Filename = "scrawl.png" - }, siteId, EUploadType.Image); - break; - case "uploadvideo": - action = new UploadHandler(HttpContext.Current, new UploadConfig - { - AllowExtensions = Config.GetStringList("videoAllowFiles"), - PathFormat = Config.GetString("videoPathFormat"), - SizeLimit = Config.GetInt("videoMaxSize"), - UploadFieldName = Config.GetString("videoFieldName") - }, siteId, EUploadType.Video); - break; - case "uploadfile": - action = new UploadHandler(HttpContext.Current, new UploadConfig - { - AllowExtensions = Config.GetStringList("fileAllowFiles"), - PathFormat = Config.GetString("filePathFormat"), - SizeLimit = Config.GetInt("fileMaxSize"), - UploadFieldName = Config.GetString("fileFieldName") - }, siteId, EUploadType.File); - break; - case "listimage": - action = new ListFileManager(HttpContext.Current, Config.GetString("imageManagerListPath"), Config.GetStringList("imageManagerAllowFiles"), siteId, EUploadType.Image); - break; - case "listfile": - action = new ListFileManager(HttpContext.Current, Config.GetString("fileManagerListPath"), Config.GetStringList("fileManagerAllowFiles"), siteId, EUploadType.File); - break; - case "catchimage": - action = new CrawlerHandler(HttpContext.Current, siteId); - break; - default: - action = new NotSupportedHandler(HttpContext.Current); - break; - } - action.Process(); - } - } -} \ No newline at end of file diff --git a/SiteServer.Web/Controllers/Sys/Errors/ErrorController.cs b/SiteServer.Web/Controllers/Sys/Errors/ErrorController.cs deleted file mode 100644 index 0f73cd45c..000000000 --- a/SiteServer.Web/Controllers/Sys/Errors/ErrorController.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Errors; -using SiteServer.CMS.Core; - -namespace SiteServer.API.Controllers.Sys.Errors -{ - [RoutePrefix("api")] - public class ErrorController : ApiController - { - [HttpGet, Route(ApiRouteError.Route)] - public IHttpActionResult Main(int id) - { - return Ok(new - { - LogInfo = DataProvider.ErrorLogDao.GetErrorLogInfo(id), - SystemManager.Version - }); - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Packaging/PackagingClearCacheController.cs b/SiteServer.Web/Controllers/Sys/Packaging/PackagingClearCacheController.cs deleted file mode 100644 index f82c05b05..000000000 --- a/SiteServer.Web/Controllers/Sys/Packaging/PackagingClearCacheController.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Packaging; -using SiteServer.CMS.Core; -using SiteServer.CMS.Plugin; -using SiteServer.Utils; - -namespace SiteServer.API.Controllers.Sys.Packaging -{ - [RoutePrefix("api")] - public class PackagesClearCacheController : ApiController - { - [HttpPost, Route(ApiRouteClearCache.Route)] - public IHttpActionResult Main() - { - var request = new AuthRequest(); - - if (!request.IsAdminLoggin) - { - return Unauthorized(); - } - - CacheUtils.ClearAll(); - CacheDbUtils.Clear(); - - return Ok(new {}); - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Packaging/PackagingDownloadController.cs b/SiteServer.Web/Controllers/Sys/Packaging/PackagingDownloadController.cs deleted file mode 100644 index 9729b2da2..000000000 --- a/SiteServer.Web/Controllers/Sys/Packaging/PackagingDownloadController.cs +++ /dev/null @@ -1,30 +0,0 @@ -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Packaging; -using SiteServer.CMS.Core; -using SiteServer.CMS.Packaging; -using SiteServer.CMS.Plugin; - -namespace SiteServer.API.Controllers.Sys.Packaging -{ - [RoutePrefix("api")] - public class PackagesDownloadController : ApiController - { - [HttpPost, Route(ApiRouteDownload.Route)] - public IHttpActionResult Main() - { - var request = new AuthRequest(); - - if (!request.IsAdminLoggin) - { - return Unauthorized(); - } - - var packageId = request.GetPostString("packageId"); - var version = request.GetPostString("version"); - - PackageUtils.DownloadPackage(packageId, version); - - return Ok(); - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Packaging/PackagingSyncDatabaseController.cs b/SiteServer.Web/Controllers/Sys/Packaging/PackagingSyncDatabaseController.cs deleted file mode 100644 index 72b739283..000000000 --- a/SiteServer.Web/Controllers/Sys/Packaging/PackagingSyncDatabaseController.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Packaging; -using SiteServer.CMS.Core; -using SiteServer.CMS.Plugin; - -namespace SiteServer.API.Controllers.Sys.Packaging -{ - [RoutePrefix("api")] - public class PackagesSyncDatabaseController : ApiController - { - [HttpPost, Route(ApiRouteSyncDatabase.Route)] - public IHttpActionResult Main() - { - var request = new AuthRequest(); - - if (!request.IsAdminLoggin) - { - return Unauthorized(); - } - - SystemManager.SyncDatabase(); - - return Ok(); - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Packaging/PackagingUpdateController.cs b/SiteServer.Web/Controllers/Sys/Packaging/PackagingUpdateController.cs deleted file mode 100644 index b26cdebf6..000000000 --- a/SiteServer.Web/Controllers/Sys/Packaging/PackagingUpdateController.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Packaging; -using SiteServer.CMS.Core; -using SiteServer.CMS.Packaging; -using SiteServer.CMS.Plugin; -using SiteServer.Utils; - -namespace SiteServer.API.Controllers.Sys.Packaging -{ - [RoutePrefix("api")] - public class PackagesUpdateController : ApiController - { - [HttpPost, Route(ApiRouteUpdate.Route)] - public IHttpActionResult Main() - { - var request = new AuthRequest(); - - if (!request.IsAdminLoggin) - { - return Unauthorized(); - } - - var packageId = request.GetPostString("packageId"); - var version = request.GetPostString("version"); - var packageType = request.GetPostString("packageType"); - if (StringUtils.EqualsIgnoreCase(packageId, PackageUtils.PackageIdSsCms)) - { - packageType = PackageType.SsCms.Value; - } - - string errorMessage; - var idWithVersion = $"{packageId}.{version}"; - if (!PackageUtils.UpdatePackage(idWithVersion, PackageType.Parse(packageType), out errorMessage)) - { - return BadRequest(errorMessage); - } - - return Ok(); - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Packaging/PackagingUpdateSsCmsController.cs b/SiteServer.Web/Controllers/Sys/Packaging/PackagingUpdateSsCmsController.cs deleted file mode 100644 index 3b5197cf6..000000000 --- a/SiteServer.Web/Controllers/Sys/Packaging/PackagingUpdateSsCmsController.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Packaging; -using SiteServer.CMS.Core; -using SiteServer.CMS.Packaging; -using SiteServer.CMS.Plugin; -using SiteServer.Utils; - -namespace SiteServer.API.Controllers.Sys.Packaging -{ - [RoutePrefix("api")] - public class PackagesUpdateSsCmsController : ApiController - { - [HttpPost, Route(ApiRouteUpdateSsCms.Route)] - public IHttpActionResult Main() - { - var request = new AuthRequest(); - - if (!request.IsAdminLoggin) - { - return Unauthorized(); - } - - var version = request.GetPostString("version"); - - var idWithVersion = $"{PackageUtils.PackageIdSsCms}.{version}"; - var packagePath = PathUtils.GetPackagesPath(idWithVersion); - var packageWebConfigPath = PathUtils.Combine(packagePath, WebConfigUtils.WebConfigFileName); - - DirectoryUtils.Copy(PathUtils.Combine(packagePath, DirectoryUtils.SiteFiles.DirectoryName), PathUtils.GetSiteFilesPath(string.Empty), true); - DirectoryUtils.Copy(PathUtils.Combine(packagePath, DirectoryUtils.SiteServer.DirectoryName), PathUtils.GetAdminDirectoryPath(string.Empty), true); - DirectoryUtils.Copy(PathUtils.Combine(packagePath, DirectoryUtils.Bin.DirectoryName), PathUtils.GetBinDirectoryPath(string.Empty), true); - FileUtils.CopyFile(packageWebConfigPath, PathUtils.Combine(WebConfigUtils.PhysicalApplicationPath, WebConfigUtils.WebConfigFileName), true); - - SystemManager.SyncDatabase(); - - return Ok(); - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Stl/StlActionsAddContentHitsController.cs b/SiteServer.Web/Controllers/Sys/Stl/StlActionsAddContentHitsController.cs deleted file mode 100644 index 2c49ca64c..000000000 --- a/SiteServer.Web/Controllers/Sys/Stl/StlActionsAddContentHitsController.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System.Web; -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.CMS.Core; - -namespace SiteServer.API.Controllers.Sys.Stl -{ - [RoutePrefix("api")] - public class StlActionsAddCountHitsController : ApiController - { - [HttpGet] - [Route(ApiRouteActionsAddContentHits.Route)] - public void Main(int siteId, int channelId, int contentId) - { - try - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - DataProvider.ContentDao.AddHits(tableName, siteInfo.Additional.IsCountHits, siteInfo.Additional.IsCountHitsByDay, contentId); - } - catch - { - // ignored - } - - HttpContext.Current.Response.End(); - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Stl/StlActionsDownloadController.cs b/SiteServer.Web/Controllers/Sys/Stl/StlActionsDownloadController.cs deleted file mode 100644 index eb112751c..000000000 --- a/SiteServer.Web/Controllers/Sys/Stl/StlActionsDownloadController.cs +++ /dev/null @@ -1,128 +0,0 @@ -using System.Web; -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.API.Controllers.Sys.Stl -{ - [RoutePrefix("api")] - public class StlActionsDownloadController : ApiController - { - [HttpGet] - [Route(ApiRouteActionsDownload.Route)] - public void Main() - { - var isSuccess = false; - try - { - var request = new AuthRequest(); - - if (!string.IsNullOrEmpty(request.GetQueryString("siteId")) && !string.IsNullOrEmpty(request.GetQueryString("fileUrl")) && string.IsNullOrEmpty(request.GetQueryString("contentId"))) - { - var siteId = request.GetQueryInt("siteId"); - var fileUrl = TranslateUtils.DecryptStringBySecretKey(request.GetQueryString("fileUrl")); - - if (PageUtils.IsProtocolUrl(fileUrl)) - { - isSuccess = true; - PageUtils.Redirect(fileUrl); - } - else - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - var filePath = PathUtility.MapPath(siteInfo, fileUrl); - var fileType = EFileSystemTypeUtils.GetEnumType(PathUtils.GetExtension(filePath)); - if (EFileSystemTypeUtils.IsDownload(fileType)) - { - if (FileUtils.IsFileExists(filePath)) - { - isSuccess = true; - PageUtils.Download(HttpContext.Current.Response, filePath); - } - } - else - { - isSuccess = true; - PageUtils.Redirect(PageUtility.ParseNavigationUrl(siteInfo, fileUrl, false)); - } - } - } - else if (!string.IsNullOrEmpty(request.GetQueryString("filePath"))) - { - var filePath = TranslateUtils.DecryptStringBySecretKey(request.GetQueryString("filePath")); - var fileType = EFileSystemTypeUtils.GetEnumType(PathUtils.GetExtension(filePath)); - if (EFileSystemTypeUtils.IsDownload(fileType)) - { - if (FileUtils.IsFileExists(filePath)) - { - isSuccess = true; - PageUtils.Download(HttpContext.Current.Response, filePath); - } - } - else - { - isSuccess = true; - var fileUrl = PageUtils.GetRootUrlByPhysicalPath(filePath); - PageUtils.Redirect(PageUtils.ParseNavigationUrl(fileUrl)); - } - } - else if (!string.IsNullOrEmpty(request.GetQueryString("siteId")) && !string.IsNullOrEmpty(request.GetQueryString("channelId")) && !string.IsNullOrEmpty(request.GetQueryString("contentId")) && !string.IsNullOrEmpty(request.GetQueryString("fileUrl"))) - { - var siteId = request.GetQueryInt("siteId"); - var channelId = request.GetQueryInt("channelId"); - var contentId = request.GetQueryInt("contentId"); - var fileUrl = TranslateUtils.DecryptStringBySecretKey(request.GetQueryString("fileUrl")); - var siteInfo = SiteManager.GetSiteInfo(siteId); - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - var contentInfo = DataProvider.ContentDao.GetContentInfo(tableName, contentId); - - if (!string.IsNullOrEmpty(contentInfo?.GetString(BackgroundContentAttribute.FileUrl))) - { - //string fileUrl = contentInfo.GetString(BackgroundContentAttribute.FileUrl); - if (siteInfo.Additional.IsCountDownload) - { - CountManager.AddCount(tableName, contentId.ToString(), ECountType.Download); - } - - if (PageUtils.IsProtocolUrl(fileUrl)) - { - isSuccess = true; - PageUtils.Redirect(fileUrl); - } - else - { - var filePath = PathUtility.MapPath(siteInfo, fileUrl, true); - var fileType = EFileSystemTypeUtils.GetEnumType(PathUtils.GetExtension(filePath)); - if (EFileSystemTypeUtils.IsDownload(fileType)) - { - if (FileUtils.IsFileExists(filePath)) - { - isSuccess = true; - PageUtils.Download(HttpContext.Current.Response, filePath); - } - } - else - { - isSuccess = true; - PageUtils.Redirect(PageUtility.ParseNavigationUrl(siteInfo, fileUrl, false)); - } - } - } - } - } - catch - { - // ignored - } - if (!isSuccess) - { - HttpContext.Current.Response.Write("下载失败,不存在此文件!"); - } - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Stl/StlActionsDynamicController.cs b/SiteServer.Web/Controllers/Sys/Stl/StlActionsDynamicController.cs deleted file mode 100644 index 3357db066..000000000 --- a/SiteServer.Web/Controllers/Sys/Stl/StlActionsDynamicController.cs +++ /dev/null @@ -1,66 +0,0 @@ -using System; -using System.Web; -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Plugin; -using SiteServer.CMS.StlParser.StlElement; - -namespace SiteServer.API.Controllers.Sys.Stl -{ - [RoutePrefix("api")] - public class StlActionsDynamicController : ApiController - { - [HttpPost, Route(ApiRouteActionsDynamic.Route)] - public IHttpActionResult Main() - { - try - { - var request = new AuthRequest(); - - var siteId = request.GetPostInt("siteId"); - var pageChannelId = request.GetPostInt("pageChannelId"); - if (pageChannelId == 0) - { - pageChannelId = siteId; - } - var pageContentId = request.GetPostInt("pageContentId"); - var pageTemplateId = request.GetPostInt("pageTemplateId"); - var isPageRefresh = request.GetPostBool("isPageRefresh"); - var templateContent = TranslateUtils.DecryptStringBySecretKey(request.GetPostString("templateContent")); - var ajaxDivId = PageUtils.FilterSqlAndXss(request.GetPostString("ajaxDivId")); - - var channelId = request.GetPostInt("channelId"); - if (channelId == 0) - { - channelId = pageChannelId; - } - var contentId = request.GetPostInt("contentId"); - if (contentId == 0) - { - contentId = pageContentId; - } - - var pageUrl = TranslateUtils.DecryptStringBySecretKey(request.GetPostString("pageUrl")); - var pageIndex = request.GetPostInt("pageNum"); - if (pageIndex > 0) - { - pageIndex--; - } - - var queryString = PageUtils.GetQueryStringFilterXss(PageUtils.UrlDecode(HttpContext.Current.Request.RawUrl)); - queryString.Remove("siteId"); - - return Ok(new - { - Html = StlDynamic.ParseDynamicContent(siteId, channelId, contentId, pageTemplateId, isPageRefresh, templateContent, pageUrl, pageIndex, ajaxDivId, queryString, request.UserInfo) - }); - } - catch(Exception ex) - { - return InternalServerError(ex); - } - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Stl/StlActionsIfController.cs b/SiteServer.Web/Controllers/Sys/Stl/StlActionsIfController.cs deleted file mode 100644 index a05f0255f..000000000 --- a/SiteServer.Web/Controllers/Sys/Stl/StlActionsIfController.cs +++ /dev/null @@ -1,58 +0,0 @@ -using System; -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Plugin; -using SiteServer.CMS.StlParser.StlElement; - -namespace SiteServer.API.Controllers.Sys.Stl -{ - [RoutePrefix("api")] - public class StlActionsIfController : ApiController - { - [HttpPost, Route(ApiRouteActionsIf.Route)] - public IHttpActionResult Main() - { - try - { - var request = new AuthRequest(); - - var siteId = request.GetPostInt("siteId"); - var channelId = request.GetPostInt("channelId"); - var contentId = request.GetPostInt("contentId"); - var templateId = request.GetPostInt("templateId"); - var ajaxDivId = PageUtils.FilterSqlAndXss(request.GetPostString("ajaxDivId")); - var pageUrl = TranslateUtils.DecryptStringBySecretKey(request.GetPostString("pageUrl")); - var testType = PageUtils.FilterSqlAndXss(request.GetPostString("testType")); - //var testValue = PageUtils.FilterSqlAndXss(request.GetPostString("testValue")); - //var testOperate = PageUtils.FilterSqlAndXss(request.GetPostString("testOperate")); - var successTemplate = TranslateUtils.DecryptStringBySecretKey(request.GetPostString("successTemplate")); - var failureTemplate = TranslateUtils.DecryptStringBySecretKey(request.GetPostString("failureTemplate")); - - var isSuccess = false; - if (StringUtils.EqualsIgnoreCase(testType, StlIf.TypeIsUserLoggin)) - { - isSuccess = request.IsUserLoggin; - } - else if (StringUtils.EqualsIgnoreCase(testType, StlIf.TypeIsAdministratorLoggin)) - { - isSuccess = request.IsAdminLoggin; - } - else if (StringUtils.EqualsIgnoreCase(testType, StlIf.TypeIsUserOrAdministratorLoggin)) - { - isSuccess = request.IsUserLoggin || request.IsAdminLoggin; - } - - return Ok(new - { - Html = StlDynamic.ParseDynamicContent(siteId, channelId, contentId, templateId, false, isSuccess ? successTemplate : failureTemplate, pageUrl, 0, ajaxDivId, null, request.UserInfo) - }); - } - catch(Exception ex) - { - return InternalServerError(ex); - } - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Stl/StlActionsLoadingChannelsController.cs b/SiteServer.Web/Controllers/Sys/Stl/StlActionsLoadingChannelsController.cs deleted file mode 100644 index e6d90f1c3..000000000 --- a/SiteServer.Web/Controllers/Sys/Stl/StlActionsLoadingChannelsController.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Text; -using System.Web; -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.StlParser.StlElement; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.API.Controllers.Sys.Stl -{ - [RoutePrefix("api")] - public class StlActionsLoadingChannelsController : ApiController - { - [HttpPost, Route(ApiRouteActionsLoadingChannels.Route)] - public void Main() - { - var builder = new StringBuilder(); - - try - { - var form = HttpContext.Current.Request.Form; - var siteId = TranslateUtils.ToInt(form["siteId"]); - var parentId = TranslateUtils.ToInt(form["parentId"]); - var target = form["target"]; - var isShowTreeLine = TranslateUtils.ToBool(form["isShowTreeLine"]); - var isShowContentNum = TranslateUtils.ToBool(form["isShowContentNum"]); - var currentFormatString = form["currentFormatString"]; - var topChannelId = TranslateUtils.ToInt(form["topChannelId"]); - var topParentsCount = TranslateUtils.ToInt(form["topParentsCount"]); - var currentChannelId = TranslateUtils.ToInt(form["currentChannelId"]); - - var siteInfo = SiteManager.GetSiteInfo(siteId); - var channelIdList = ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(siteId, parentId == 0 ? siteId : parentId), EScopeType.Children, string.Empty, string.Empty, string.Empty); - - foreach (var channelId in channelIdList) - { - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - - builder.Append(StlTree.GetChannelRowHtml(siteInfo, nodeInfo, target, isShowTreeLine, isShowContentNum, TranslateUtils.DecryptStringBySecretKey(currentFormatString), topChannelId, topParentsCount, currentChannelId, false)); - } - } - catch - { - // ignored - } - - HttpContext.Current.Response.Write(builder); - HttpContext.Current.Response.End(); - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Stl/StlActionsPageContentsController.cs b/SiteServer.Web/Controllers/Sys/Stl/StlActionsPageContentsController.cs deleted file mode 100644 index 560d5e2e3..000000000 --- a/SiteServer.Web/Controllers/Sys/Stl/StlActionsPageContentsController.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Plugin; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.StlElement; - -namespace SiteServer.API.Controllers.Sys.Stl -{ - [RoutePrefix("api")] - public class StlActionsPageContentsController : ApiController - { - [HttpPost, Route(ApiRouteActionsPageContents.Route)] - public IHttpActionResult Main() - { - try - { - var request = new AuthRequest(); - - var siteId = request.GetPostInt("siteId"); - var siteInfo = SiteManager.GetSiteInfo(siteId); - var pageChannelId = request.GetPostInt("pageChannelId"); - var templateId = request.GetPostInt("templateId"); - var totalNum = request.GetPostInt("totalNum"); - var pageCount = request.GetPostInt("pageCount"); - var currentPageIndex = request.GetPostInt("currentPageIndex"); - var stlPageContentsElement = TranslateUtils.DecryptStringBySecretKey(request.GetPostString("stlPageContentsElement")); - - var nodeInfo = ChannelManager.GetChannelInfo(siteId, pageChannelId); - var templateInfo = TemplateManager.GetTemplateInfo(siteId, templateId); - var pageInfo = new PageInfo(nodeInfo.Id, 0, siteInfo, templateInfo, new Dictionary()) - { - UserInfo = request.UserInfo - }; - var contextInfo = new ContextInfo(pageInfo); - - var stlPageContents = new StlPageContents(stlPageContentsElement, pageInfo, contextInfo, false); - - var pageHtml = stlPageContents.Parse(totalNum, currentPageIndex, pageCount, false); - - return Ok(pageHtml); - } - catch (Exception ex) - { - return InternalServerError(ex); - } - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Stl/StlActionsRelatedFieldController.cs b/SiteServer.Web/Controllers/Sys/Stl/StlActionsRelatedFieldController.cs deleted file mode 100644 index 3c91fdeeb..000000000 --- a/SiteServer.Web/Controllers/Sys/Stl/StlActionsRelatedFieldController.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System.Text; -using System.Web; -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Plugin; - -namespace SiteServer.API.Controllers.Sys.Stl -{ - [RoutePrefix("api")] - public class StlActionsRelatedFieldController : ApiController - { - [HttpPost, Route(ApiRouteActionsRelatedField.Route)] - public void Main(int siteId) - { - var request = new AuthRequest(); - - var callback = request.GetQueryString("callback"); - var relatedFieldId = request.GetQueryInt("relatedFieldId"); - var parentId = request.GetQueryInt("parentId"); - var jsonString = GetRelatedField(relatedFieldId, parentId); - var call = callback + "(" + jsonString + ")"; - - HttpContext.Current.Response.Write(call); - HttpContext.Current.Response.End(); - } - - public string GetRelatedField(int relatedFieldId, int parentId) - { - var jsonString = new StringBuilder(); - - jsonString.Append("["); - - var list = DataProvider.RelatedFieldItemDao.GetRelatedFieldItemInfoList(relatedFieldId, parentId); - if (list.Count > 0) - { - foreach (var itemInfo in list) - { - jsonString.AppendFormat(@"{{""id"":""{0}"",""name"":""{1}"",""value"":""{2}""}},", itemInfo.Id, StringUtils.ToJsString(itemInfo.ItemName), StringUtils.ToJsString(itemInfo.ItemValue)); - } - jsonString.Length -= 1; - } - - jsonString.Append("]"); - return jsonString.ToString(); - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Stl/StlActionsSearchController.cs b/SiteServer.Web/Controllers/Sys/Stl/StlActionsSearchController.cs deleted file mode 100644 index c1017a909..000000000 --- a/SiteServer.Web/Controllers/Sys/Stl/StlActionsSearchController.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using System.Web; -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Plugin; -using SiteServer.CMS.StlParser; -using SiteServer.CMS.StlParser.Model; -using SiteServer.CMS.StlParser.StlElement; -using SiteServer.CMS.StlParser.StlEntity; -using SiteServer.CMS.StlParser.Utility; -using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; - -namespace SiteServer.API.Controllers.Sys.Stl -{ - [RoutePrefix("api")] - public class StlActionsSearchController : ApiController - { - [HttpPost, Route(ApiRouteActionsSearch.Route)] - public IHttpActionResult Main() - { - try - { - var request = new AuthRequest(); - var form = HttpContext.Current.Request.Form; - - var isAllSites = request.GetPostBool(StlSearch.IsAllSites.Name.ToLower()); - var siteName = PageUtils.FilterSqlAndXss(request.GetPostString(StlSearch.SiteName.Name.ToLower())); - var siteDir = PageUtils.FilterSqlAndXss(request.GetPostString(StlSearch.SiteDir.Name.ToLower())); - var siteIds = PageUtils.FilterSqlAndXss(request.GetPostString(StlSearch.SiteIds.Name.ToLower())); - var channelIndex = PageUtils.FilterSqlAndXss(request.GetPostString(StlSearch.ChannelIndex.Name.ToLower())); - var channelName = PageUtils.FilterSqlAndXss(request.GetPostString(StlSearch.ChannelName.Name.ToLower())); - var channelIds = PageUtils.FilterSqlAndXss(request.GetPostString(StlSearch.ChannelIds.Name.ToLower())); - var type = PageUtils.FilterSqlAndXss(request.GetPostString(StlSearch.Type.Name.ToLower())); - var word = PageUtils.FilterSql(request.GetPostString(StlSearch.Word.Name.ToLower())); - var dateAttribute = PageUtils.FilterSqlAndXss(request.GetPostString(StlSearch.DateAttribute.Name.ToLower())); - var dateFrom = PageUtils.FilterSqlAndXss(request.GetPostString(StlSearch.DateFrom.Name.ToLower())); - var dateTo = PageUtils.FilterSqlAndXss(request.GetPostString(StlSearch.DateTo.Name.ToLower())); - var since = PageUtils.FilterSqlAndXss(request.GetPostString(StlSearch.Since.Name.ToLower())); - var pageNum = request.GetPostInt(StlSearch.PageNum.Name.ToLower()); - var isHighlight = request.GetPostBool(StlSearch.IsHighlight.Name.ToLower()); - var isDefaultDisplay = request.GetPostBool(StlSearch.IsDefaultDisplay.Name.ToLower()); - var siteId = request.GetPostInt("siteid"); - var ajaxDivId = PageUtils.FilterSqlAndXss(request.GetPostString("ajaxdivid")); - var template = TranslateUtils.DecryptStringBySecretKey(request.GetPostString("template")); - var pageIndex = request.GetPostInt("page", 1) - 1; - - var templateInfo = new TemplateInfo(0, siteId, string.Empty, TemplateType.FileTemplate, string.Empty, string.Empty, string.Empty, ECharset.utf_8, false); - var siteInfo = SiteManager.GetSiteInfo(siteId); - var pageInfo = new PageInfo(siteId, 0, siteInfo, templateInfo, new Dictionary()) - { - UserInfo = request.UserInfo - }; - var contextInfo = new ContextInfo(pageInfo); - var contentBuilder = new StringBuilder(StlRequestEntities.ParseRequestEntities(form, template)); - - var stlLabelList = StlParserUtility.GetStlLabelList(contentBuilder.ToString()); - - if (StlParserUtility.IsStlElementExists(StlPageContents.ElementName, stlLabelList)) - { - var stlElement = StlParserUtility.GetStlElement(StlPageContents.ElementName, stlLabelList); - var stlPageContentsElement = stlElement; - var stlPageContentsElementReplaceString = stlElement; - - bool isDefaultCondition; - var whereString = DataProvider.ContentDao.GetWhereStringByStlSearch(isAllSites, siteName, siteDir, siteIds, channelIndex, channelName, channelIds, type, word, dateAttribute, dateFrom, dateTo, since, siteId, ApiRouteActionsSearch.ExlcudeAttributeNames, form, out isDefaultCondition); - - //没搜索条件时不显示搜索结果 - if (isDefaultCondition && !isDefaultDisplay) - { - return NotFound(); - } - - var stlPageContents = new StlPageContents(stlPageContentsElement, pageInfo, contextInfo, pageNum, siteInfo.TableName, whereString); - - int totalNum; - var pageCount = stlPageContents.GetPageCount(out totalNum); - - if (totalNum == 0) - { - return NotFound(); - } - - for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) - { - if (currentPageIndex != pageIndex) continue; - - var pageHtml = stlPageContents.Parse(totalNum, currentPageIndex, pageCount, false); - var pagedBuilder = new StringBuilder(contentBuilder.ToString().Replace(stlPageContentsElementReplaceString, pageHtml)); - - StlParserManager.ReplacePageElementsInSearchPage(pagedBuilder, pageInfo, stlLabelList, ajaxDivId, pageInfo.PageChannelId, currentPageIndex, pageCount, totalNum); - - if (isHighlight && !string.IsNullOrEmpty(word)) - { - var pagedContents = pagedBuilder.ToString(); - pagedBuilder = new StringBuilder(); - pagedBuilder.Append(RegexUtils.Replace( - $"({word.Replace(" ", "\\s")})(?!)(?![^><]*>)", pagedContents, - $"{word}")); - } - - Parser.Parse(siteInfo, pageInfo, contextInfo, pagedBuilder, string.Empty, false); - return Ok(pagedBuilder.ToString()); - } - } - - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, string.Empty, false); - return Ok(contentBuilder.ToString()); - } - catch (Exception ex) - { - return InternalServerError(ex); - } - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Stl/StlActionsTriggerController.cs b/SiteServer.Web/Controllers/Sys/Stl/StlActionsTriggerController.cs deleted file mode 100644 index 29fb38838..000000000 --- a/SiteServer.Web/Controllers/Sys/Stl/StlActionsTriggerController.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System.Collections.Specialized; -using System.Threading.Tasks; -using System.Web; -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.Plugin; -using SiteServer.CMS.StlParser; - -namespace SiteServer.API.Controllers.Sys.Stl -{ - [RoutePrefix("api")] - public class StlActionsTriggerController : ApiController - { - [HttpGet] - [Route(ApiRouteActionsTrigger.Route)] - public async Task Main() - { - var request = new AuthRequest(); - - var siteId = request.GetQueryInt("siteId"); - var siteInfo = SiteManager.GetSiteInfo(siteId); - - try - { - var channelId = request.GetQueryInt("channelId"); - if (channelId == 0) - { - channelId = siteId; - } - var contentId = request.GetQueryInt("contentId"); - var fileTemplateId = request.GetQueryInt("fileTemplateId"); - var isRedirect = TranslateUtils.ToBool(request.GetQueryString("isRedirect")); - - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); - - if (fileTemplateId != 0) - { - await FileSystemObjectAsync.ExecuteAsync(siteId, ECreateType.File, 0, 0, fileTemplateId); - } - else if (contentId != 0) - { - await FileSystemObjectAsync.ExecuteAsync(siteId, ECreateType.Content, channelId, contentId, 0); - } - else if (channelId != 0) - { - await FileSystemObjectAsync.ExecuteAsync(siteId, ECreateType.Channel, channelId, 0, 0); - } - else if (siteId != 0) - { - await FileSystemObjectAsync.ExecuteAsync(siteId, ECreateType.Channel, siteId, 0, 0); - } - - if (isRedirect) - { - var redirectUrl = string.Empty; - if (fileTemplateId != 0) - { - redirectUrl = PageUtility.GetFileUrl(siteInfo, fileTemplateId, false); - } - else if (contentId != 0) - { - var contentInfo = DataProvider.ContentDao.GetContentInfo(tableName, contentId); - redirectUrl = PageUtility.GetContentUrl(siteInfo, contentInfo, false); - } - else if (channelId != 0) - { - redirectUrl = PageUtility.GetChannelUrl(siteInfo, nodeInfo, false); - } - else if (siteId != 0) - { - redirectUrl = PageUtility.GetIndexPageUrl(siteInfo, false); - } - - if (!string.IsNullOrEmpty(redirectUrl)) - { - var parameters = new NameValueCollection(); - var returnUrl = request.GetQueryString("returnUrl"); - if (!string.IsNullOrEmpty(returnUrl)) - { - if (returnUrl.StartsWith("?")) - { - parameters = TranslateUtils.ToNameValueCollection(returnUrl.Substring(1)); - } - else - { - redirectUrl = returnUrl; - } - } - - parameters["__r"] = StringUtils.GetRandomInt(1, 10000).ToString(); - - PageUtils.Redirect(PageUtils.AddQueryString(redirectUrl, parameters)); - return; - } - } - } - catch - { - var redirectUrl = PageUtility.GetIndexPageUrl(siteInfo, false); - PageUtils.Redirect(redirectUrl); - return; - } - - HttpContext.Current.Response.Write(string.Empty); - HttpContext.Current.Response.End(); - } - } -} diff --git a/SiteServer.Web/Controllers/Sys/Stl/StlActionsUploadController.cs b/SiteServer.Web/Controllers/Sys/Stl/StlActionsUploadController.cs deleted file mode 100644 index f3e41d481..000000000 --- a/SiteServer.Web/Controllers/Sys/Stl/StlActionsUploadController.cs +++ /dev/null @@ -1,112 +0,0 @@ -using System; -using System.Collections.Specialized; -using System.Web; -using System.Web.Http; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; - -namespace SiteServer.API.Controllers.Sys.Stl -{ - [RoutePrefix("api")] - public class StlActionsUploadController : ApiController - { - [HttpPost, Route(ApiRouteActionsUpload.Route)] - public IHttpActionResult Main(int siteId) - { - var siteInfo = SiteManager.GetSiteInfo(siteId); - var type = HttpContext.Current.Request.QueryString["type"]; - - var jsonAttributes = new NameValueCollection(); - - var success = false; - var message = string.Empty; - var url = string.Empty; - var value = string.Empty; - - if (type == ApiRouteActionsUpload.TypeResume) - { - success = UploadResumeImage(siteInfo, out message, out url, out value); - } - else if (type == ApiRouteActionsUpload.TypeGovPublicApply) - { - success = UploadGovPublicApply(siteInfo, out message, out url, out value); - } - - jsonAttributes.Add("success", success.ToString().ToLower()); - jsonAttributes.Add("message", message); - jsonAttributes.Add("url", url); - jsonAttributes.Add("value", value); - - return Ok(jsonAttributes); - } - - public bool UploadResumeImage(SiteInfo siteInfo, out string message, out string url, out string value) - { - message = url = value = string.Empty; - - if (HttpContext.Current.Request.Files["ImageUrl"] == null) return false; - var postedFile = HttpContext.Current.Request.Files["ImageUrl"]; - - var filePath = postedFile.FileName; - try - { - var fileExtName = PathUtils.GetExtension(filePath).ToLower(); - var localDirectoryPath = PathUtility.GetUploadDirectoryPath(siteInfo, fileExtName); - var localFileName = PathUtility.GetUploadFileName(siteInfo, filePath); - var localFilePath = PathUtils.Combine(localDirectoryPath, localFileName); - - if (!PathUtility.IsImageExtenstionAllowed(siteInfo, fileExtName)) - { - message = "上传失败,上传图片格式不正确!"; - return false; - } - if (!PathUtility.IsImageSizeAllowed(siteInfo, postedFile.ContentLength)) - { - message = "上传失败,上传图片超出规定文件大小!"; - return false; - } - - postedFile.SaveAs(localFilePath); - - url = PageUtility.GetSiteUrlByPhysicalPath(siteInfo, localFilePath, false); - value = PageUtility.GetVirtualUrl(siteInfo, url); - return true; - } - catch (Exception ex) - { - message = ex.Message; - } - return false; - } - - public bool UploadGovPublicApply(SiteInfo siteInfo, out string message, out string url, out string value) - { - message = url = value = string.Empty; - - if (HttpContext.Current.Request.Files.Count == 0) return false; - var postedFile = HttpContext.Current.Request.Files[0]; - - var filePath = postedFile.FileName; - try - { - var fileExtName = PathUtils.GetExtension(filePath).ToLower(); - var localDirectoryPath = PathUtility.GetUploadDirectoryPath(siteInfo, fileExtName); - var localFileName = PathUtility.GetUploadFileName(siteInfo, filePath); - var localFilePath = PathUtils.Combine(localDirectoryPath, localFileName); - - postedFile.SaveAs(localFilePath); - - url = PageUtility.GetSiteUrlByPhysicalPath(siteInfo, localFilePath, false); - value = PageUtility.GetVirtualUrl(siteInfo, url); - return true; - } - catch (Exception ex) - { - message = ex.Message; - } - return false; - } - } -} diff --git a/SiteServer.Web/Controllers/TestController.cs b/SiteServer.Web/Controllers/TestController.cs deleted file mode 100644 index e9ee2b9e5..000000000 --- a/SiteServer.Web/Controllers/TestController.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Net; -using System.Net.Http; -using System.Text; -using System.Web.Http; -using SiteServer.CMS.Plugin; - -namespace SiteServer.API.Controllers -{ - [RoutePrefix("api")] - public class TestController : ApiController - { - [HttpGet, Route("test")] - public IHttpActionResult Get() - { - var pluginIds = new List(); - foreach (var pluginInfo in PluginManager.PluginInfoListRunnable) - { - if (!pluginInfo.IsDisabled) - { - pluginIds.Add(pluginInfo.Id); - } - } - return Ok(new - { - DateTime = DateTime.Now, - Plugins = pluginIds - }); - } - - [HttpGet, Route("test/any")] - public HttpResponseMessage GetAny() - { - //return Content(HttpStatusCode.Created, new - //{ - // IsOk = true - //}); - - //var content = ; - - var response = Request.CreateResponse(HttpStatusCode.NotFound); - - response.Content = new StringContent("yes, yes", Encoding.UTF8); - - return response; - } - - [HttpGet, Route("test/string")] - public IHttpActionResult GetString() - { - return Ok("Hello"); - } - - //private readonly HttpClient _httpClient = new HttpClient(); - - //[HttpGet, Route("test/count")] - //public async Task GetDotNetCountAsync() - //{ - // // Suspends GetDotNetCountAsync() to allow the caller (the web server) - // // to accept another request, rather than blocking on this one. - // var html = await _httpClient.GetStringAsync("http://dotnetfoundation.org"); - - // return Ok(new - // { - // Regex.Matches(html, @"\.NET").Count - // }); - //} - } -} diff --git a/SiteServer.Web/CreateHub.cs b/SiteServer.Web/CreateHub.cs deleted file mode 100644 index b4ae6fab9..000000000 --- a/SiteServer.Web/CreateHub.cs +++ /dev/null @@ -1,77 +0,0 @@ -using System; -using System.Threading.Tasks; -using SiteServer.Utils; -using Microsoft.AspNet.SignalR; -using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Create; -using SiteServer.CMS.StlParser; - -namespace SiteServer.API -{ - public class CreateHub : Hub - { - public async Task Execute(int siteId) - { - var pendingTaskCount = 0; - try - { - pendingTaskCount = await ExecuteTaskAsync(siteId); - } - catch (Exception ex) - { - LogUtils.AddErrorLog(ex, "CreateHub"); - } - - Clients.Client(Context.ConnectionId).next(pendingTaskCount); - } - - private static async Task ExecuteTaskAsync(int siteId) - { - var instance = CreateTaskManager.Instance; - - var pendingTask = instance.GetAndRemoveLastPendingTask(siteId); - if (pendingTask == null) return 0; - - try - { - var start = DateTime.Now; - await FileSystemObjectAsync.ExecuteAsync(pendingTask.SiteId, pendingTask.CreateType, pendingTask.ChannelId, - pendingTask.ContentId, pendingTask.TemplateId); - var timeSpan = DateUtils.GetRelatedDateTimeString(start); - instance.AddSuccessLog(pendingTask, timeSpan); - } - catch (Exception ex) - { - instance.AddFailureLog(pendingTask, ex); - } - finally - { - instance.RemoveCurrent(siteId, pendingTask); - } - - return instance.GetPendingTaskCount(siteId); - } - - public async Task GetTasks(int siteId) - { - try - { - if (siteId > 0) - { - var summary = CreateTaskManager.Instance.GetTaskSummary(siteId); - Clients.Client(Context.ConnectionId).show(true, summary.Tasks, summary.ChannelsCount, summary.ContentsCount, summary.FilesCount); - - await Execute(siteId); - } - else - { - Clients.Client(Context.ConnectionId).show(false, null, 0, 0, 0, 0); - } - } - catch (Exception ex) - { - LogUtils.AddErrorLog(ex, "CreateHub"); - } - } - } -} \ No newline at end of file diff --git a/SiteServer.Web/ErrorRedirectModule.cs b/SiteServer.Web/ErrorRedirectModule.cs deleted file mode 100644 index af4e79941..000000000 --- a/SiteServer.Web/ErrorRedirectModule.cs +++ /dev/null @@ -1,40 +0,0 @@ -using System; -using System.Web; -using SiteServer.CMS.Core; - -namespace SiteServer.API -{ - public class ErrorRedirectModule : IHttpModule - { - public string ModuleName => "ErrorRedirectModule"; - - public void Init(HttpApplication app) - { - app.Error += Application_Error; - } - - private static void Application_Error(object sender, EventArgs e) - { - try - { - var ex = HttpContext.Current.Server.GetLastError(); - if (ex.InnerException != null) - { - ex = ex.InnerException; - } - HttpContext.Current.Server.ClearError(); - - LogUtils.AddErrorLogAndRedirect(ex, "ϵͳ"); - } - catch - { - // ignored - } - } - - public void Dispose() - { - } - } - -} diff --git a/SiteServer.Web/Properties/AssemblyInfo.cs b/SiteServer.Web/Properties/AssemblyInfo.cs deleted file mode 100644 index a7bff52cc..000000000 --- a/SiteServer.Web/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// 有关程序集的常规信息通过下列特性集 -// 控制。更改这些特性值可修改 -// 与程序集关联的信息。 -[assembly: AssemblyTitle("WebApplication")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("WebApplication")] -[assembly: AssemblyCopyright("Copyright © 2017")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// 将 ComVisible 设置为 false 会使此程序集中的类型 -// 对 COM 组件不可见。如果需要 -// 从 COM 访问此程序集中的某个类型,请针对该类型将 ComVisible 特性设置为 true。 -[assembly: ComVisible(false)] - -// 如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID -[assembly: Guid("10782686-b998-4e54-b2af-86233c12355d")] - -// 程序集的版本信息由下列四个值组成: -// -// 主版本 -// 次版本 -// 内部版本号 -// 修订版本 -// -// 可以指定所有值,也可以使用“修订号”和“内部版本号”的默认值, -// 方法是按如下所示使用 "*": -[assembly: AssemblyVersion("0.0.0")] -[assembly: AssemblyFileVersion("0.0.0")] -[assembly: AssemblyInformationalVersion("0.0.0")] \ No newline at end of file diff --git a/SiteServer.Web/SiteFiles/UserFiles/home_logo.png b/SiteServer.Web/SiteFiles/UserFiles/home_logo.png deleted file mode 100644 index f882f78c7..000000000 Binary files a/SiteServer.Web/SiteFiles/UserFiles/home_logo.png and /dev/null differ diff --git a/SiteServer.Web/SiteFiles/assets/resume/index.html b/SiteServer.Web/SiteFiles/assets/resume/index.html deleted file mode 100644 index 4ea29c10c..000000000 --- a/SiteServer.Web/SiteFiles/assets/resume/index.html +++ /dev/null @@ -1,1171 +0,0 @@ - - - -提交简历 - - - - - - - - - - - - - - - - - - - - -
    -
    - - -
    - -
    -

    基本信息

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    姓名* -   - 民族:
    - » 上传
    -
    - -
      -
    1. 只接受JPG或GIF文件
    2. -
    3. 尺寸为120x150
    4. -
    5. 不超过800K
    6. -
    7. 为方便面试官筛选出您的简历 , 请务必上传真实照片
    8. -
    性别* - - - Email:
    手机号码* -   - 家庭电话:
    毕业院校* -   - 学历* -   -
    证件类型:证件号码:
    出生日期:
    - -
    婚姻状况:
    工作年限:所属专业:
    期望薪水(月):到岗时间:
    - - - - - -
    当前居住地:
    - - - - - -
    个人简介:
    -
    - -
    - -

    工作经验

    -
    -
    -
    - - - - - -
    时间* - - - - - - 到 - - - (后两项不填表示至今)
    - - - - - - - - - - - - - - - - - - - -
    雇主名称* -   - 所属部门:
    联系电话:工作地点:
    职位* -   - 所属行业:
    - - - - - - - - - -
    工作描述:
    主要业绩:
    -
    - -
    » 继续添加
    -
    -
    -
    - -
    - -

    项目经验

    -
    -
    -
    - - - - - - - - - - - - - - - -
    时间* - - - - - - 到 - - - (后两项不填表示至今)
    项目名称* -   -
    项目描述:
    -
    - -
    » 继续添加
    -
    -
    -
    - -
    - -

    教育经历

    -
    -
    -
    - - - - - -
    时间* - - - - - - 到 - - - (后两项不填表示至今)
    - - - - - - - - - - - -
    学校* -   - 所获学历* -   -
    专业* -   -
    - - - - - -
    备注:
    -
    - -
    » 继续添加
    -
    -
    -
    - -
    - -

    培训信息

    -
    -
    -
    - - - - - -
    时间* - - - - - - 到 - - - (后两项不填表示至今)
    - - - - - - - - - - - - - -
    培训机构* -   - 培训地点* -   -
    课程* -   - 所获证书* -   -
    - - - - - -
    详细:
    -
    - -
    » 继续添加
    -
    -
    -
    - -
    - -

    语言能力

    -
    -
    -
    - - - - - - - -
    语种* -   - 掌握程度:
    -
    - -
    » 继续添加
    -
    -
    -
    - -
    - -

    IT技能

    -
    -
    -
    - - - - - - - - - - - - - -
    技能名称* -   - 使用时间(月):
    熟练程度:
    -
    - -
    » 继续添加
    -
    -
    -
    - -
    - -

    证书

    -
    -
    -
    - - - - - - - -
    证书名称* -   - 获得时间:
    -
    - -
    » 继续添加
    -
    -
    -
    - -
    -
    - - - - -
    提交
    - -
    - -
    - - - diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/config.js b/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/config.js deleted file mode 100644 index 417b8f787..000000000 --- a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/config.js +++ /dev/null @@ -1,42 +0,0 @@ -/** - * Created with JetBrains PhpStorm. - * User: xuheng - * Date: 12-8-8 - * Time: 下午2:00 - * To change this template use File | Settings | File Templates. - */ -var templates = [ - { - "pre":"pre0.png", - 'title':lang.blank, - 'preHtml':'

     欢迎使用UEditor!

    ', - "html":'

    欢迎使用UEditor!

    ' - - }, - { - "pre":"pre1.png", - 'title':lang.blog, - 'preHtml':'

    深入理解Range

    UEditor二次开发

    什么是Range

    对于“插入”选项卡上的库,在设计时都充分考虑了其中的项与文档整体外观的协调性。


    Range能干什么

    在“开始”选项卡上,通过从快速样式库中为所选文本选择一种外观,您可以方便地更改文档中所选文本的格式。

    ', - "html":'

    [键入文档标题]

    [键入文档副标题]

    [标题 1]

    对于“插入”选项卡上的库,在设计时都充分考虑了其中的项与文档整体外观的协调性。 您可以使用这些库来插入表格、页眉、页脚、列表、封面以及其他文档构建基块。 您创建的图片、图表或关系图也将与当前的文档外观协调一致。

    [标题 2]

    在“开始”选项卡上,通过从快速样式库中为所选文本选择一种外观,您可以方便地更改文档中所选文本的格式。 您还可以使用“开始”选项卡上的其他控件来直接设置文本格式。大多数控件都允许您选择是使用当前主题外观,还是使用某种直接指定的格式。

    [标题 3]

    对于“插入”选项卡上的库,在设计时都充分考虑了其中的项与文档整体外观的协调性。 您可以使用这些库来插入表格、页眉、页脚、列表、封面以及其他文档构建基块。 您创建的图片、图表或关系图也将与当前的文档外观协调一致。


    ' - - }, - { - "pre":"pre2.png", - 'title':lang.resume, - 'preHtml':'

    WEB前端开发简历


    联系电话:[键入您的电话]

    电子邮件:[键入您的电子邮件地址]

    家庭住址:[键入您的地址]

    目标职位

    WEB前端研发工程师

    学历

    1. [起止时间] [学校名称] [所学专业] [所获学位]

    工作经验


    ', - "html":'

    [此处键入简历标题]


    【此处插入照片】


    联系电话:[键入您的电话]


    电子邮件:[键入您的电子邮件地址]


    家庭住址:[键入您的地址]


    目标职位

    [此处键入您的期望职位]

    学历

    1. [键入起止时间] [键入学校名称] [键入所学专业] [键入所获学位]

    2. [键入起止时间] [键入学校名称] [键入所学专业] [键入所获学位]

    工作经验

    1. [键入起止时间] [键入公司名称] [键入职位名称]

      1. [键入负责项目] [键入项目简介]

      2. [键入负责项目] [键入项目简介]

    2. [键入起止时间] [键入公司名称] [键入职位名称]

      1. [键入负责项目] [键入项目简介]

    掌握技能

     [这里可以键入您所掌握的技能]

    ' - - }, - { - "pre":"pre3.png", - 'title':lang.richText, - 'preHtml':'

    [此处键入文章标题]

    图文混排方法

    图片居左,文字围绕图片排版

    方法:在文字前面插入图片,设置居左对齐,然后即可在右边输入多行文


    还有没有什么其他的环绕方式呢?这里是居右环绕


    欢迎大家多多尝试,为UEditor提供更多高质量模板!

    ', - "html":'


    [此处键入文章标题]

    图文混排方法

    1. 图片居左,文字围绕图片排版

    方法:在文字前面插入图片,设置居左对齐,然后即可在右边输入多行文本


    2. 图片居右,文字围绕图片排版

    方法:在文字前面插入图片,设置居右对齐,然后即可在左边输入多行文本


    3. 图片居中环绕排版

    方法:亲,这个真心没有办法。。。



    还有没有什么其他的环绕方式呢?这里是居右环绕


    欢迎大家多多尝试,为UEditor提供更多高质量模板!


    占位


    占位


    占位


    占位


    占位



    ' - }, - { - "pre":"pre4.png", - 'title':lang.sciPapers, - 'preHtml':'

    [键入文章标题]

    摘要:这里可以输入很长很长很长很长很长很长很长很长很差的摘要

    标题 1

    这里可以输入很多内容,可以图文混排,可以有列表等。

    标题 2

    1. 列表 1

    2. 列表 2

      1. 多级列表 1

      2. 多级列表 2

    3. 列表 3

    标题 3

    来个文字图文混排的


    ', - 'html':'

    [键入文章标题]

    摘要:这里可以输入很长很长很长很长很长很长很长很长很差的摘要

    标题 1

    这里可以输入很多内容,可以图文混排,可以有列表等。

    标题 2

    来个列表瞅瞅:

    1. 列表 1

    2. 列表 2

      1. 多级列表 1

      2. 多级列表 2

    3. 列表 3

    标题 3

    来个文字图文混排的

    这里可以多行

    右边是图片

    绝对没有问题的,不信你也可以试试看


    ' - } -]; \ No newline at end of file diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/bg.gif b/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/bg.gif deleted file mode 100644 index 8c1d10ad1..000000000 Binary files a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/bg.gif and /dev/null differ diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/pre0.png b/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/pre0.png deleted file mode 100644 index 8f3c16ab1..000000000 Binary files a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/pre0.png and /dev/null differ diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/pre1.png b/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/pre1.png deleted file mode 100644 index 5a03f9699..000000000 Binary files a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/pre1.png and /dev/null differ diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/pre2.png b/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/pre2.png deleted file mode 100644 index 5a55672c1..000000000 Binary files a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/pre2.png and /dev/null differ diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/pre3.png b/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/pre3.png deleted file mode 100644 index d852d29f1..000000000 Binary files a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/pre3.png and /dev/null differ diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/pre4.png b/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/pre4.png deleted file mode 100644 index 0d7bc72ab..000000000 Binary files a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/images/pre4.png and /dev/null differ diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/template.css b/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/template.css deleted file mode 100644 index 6c1608dfc..000000000 --- a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/template.css +++ /dev/null @@ -1,18 +0,0 @@ -.wrap{ padding: 5px;font-size: 14px;} -.left{width:425px;float: left;} -.right{width:160px;border: 1px solid #ccc;float: right;padding: 5px;margin-right: 5px;} -.right .pre{height: 332px;overflow-y: auto;} -.right .preitem{border: white 1px solid;margin: 5px 0;padding: 2px 0;} -.right .preitem:hover{background-color: lemonChiffon;cursor: pointer;border: #ccc 1px solid;} -.right .preitem img{display: block;margin: 0 auto;width:100px;} -.clear{clear: both;} -.top{height:26px;line-height: 26px;padding: 5px;} -.bottom{height:320px;width:100%;margin: 0 auto;} -.transparent{ background: url("images/bg.gif") repeat;} -.bottom table tr td{border:1px dashed #ccc;} -#colorPicker{width: 17px;height: 17px;border: 1px solid #CCC;display: inline-block;border-radius: 3px;box-shadow: 2px 2px 5px #D3D6DA;} -.border_style1{padding:2px;border: 1px solid #ccc;border-radius: 5px;box-shadow:2px 2px 5px #d3d6da;} -p{margin: 5px 0} -table{clear:both;margin-bottom:10px;border-collapse:collapse;word-break:break-all;} -li{clear:both} -ol{padding-left:40px; } \ No newline at end of file diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/template.html b/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/template.html deleted file mode 100644 index d9903a480..000000000 --- a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/template.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - -
    -
    -
    - -
    -
    -
    -
    - -
    -
    -
    -
    - - - - diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/template.js b/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/template.js deleted file mode 100644 index 80a334b36..000000000 --- a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/template/template.js +++ /dev/null @@ -1,53 +0,0 @@ -/** - * Created with JetBrains PhpStorm. - * User: xuheng - * Date: 12-8-8 - * Time: 下午2:09 - * To change this template use File | Settings | File Templates. - */ -(function () { - var me = editor, - preview = $G( "preview" ), - preitem = $G( "preitem" ), - tmps = templates, - currentTmp; - var initPre = function () { - var str = ""; - for ( var i = 0, tmp; tmp = tmps[i++]; ) { - str += '
    '; - } - preitem.innerHTML = str; - }; - var pre = function ( n ) { - var tmp = tmps[n - 1]; - currentTmp = tmp; - clearItem(); - domUtils.setStyles( preitem.childNodes[n - 1], { - "background-color":"lemonChiffon", - "border":"#ccc 1px solid" - } ); - preview.innerHTML = tmp.preHtml ? tmp.preHtml : ""; - }; - var clearItem = function () { - var items = preitem.children; - for ( var i = 0, item; item = items[i++]; ) { - domUtils.setStyles( item, { - "background-color":"", - "border":"white 1px solid" - } ); - } - }; - dialog.onok = function () { - if ( !$G( "issave" ).checked ){ - me.execCommand( "cleardoc" ); - } - var obj = { - html:currentTmp && currentTmp.html - }; - me.execCommand( "template", obj ); - }; - initPre(); - window.pre = pre; - pre(2) - -})(); \ No newline at end of file diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/editor_config.js b/SiteServer.Web/SiteFiles/assets/ueditor/editor_config.js deleted file mode 100644 index 98801023e..000000000 --- a/SiteServer.Web/SiteFiles/assets/ueditor/editor_config.js +++ /dev/null @@ -1 +0,0 @@ -!function(){function e(e,l){return t(e||self.document.URL||self.location.href,l||s())}function s(){var e=document.getElementsByTagName("script");return e[e.length-1].src}function t(e,s){var t=s;return/^(\/|\\\\)/.test(s)?t=/^.+?\w(\/|\\\\)/.exec(e)[0]+s.replace(/^(\/|\\\\)/,""):/^[a-z]+:/i.test(s)||(e=e.split("#")[0].split("?")[0].replace(/[^\\\/]+$/,""),t=e+""+s),l(t)}function l(e){var s=/^[a-z]+:\/\//.exec(e)[0],t=null,l=[];for(e=e.replace(s,"").split("?")[0].split("#")[0],e=e.replace(/\\/g,"/").split(/\//),e[e.length-1]="";e.length;)".."===(t=e.shift())?l.pop():"."!==t&&l.push(t);return s+l.join("/")}var a=window.UEDITOR_HOME_URL||e();window.UEDITOR_CONFIG={UEDITOR_HOME_URL:a,serverUrl:window.UEDITOR_CONTROLLER_URL,toolbars:[["fullscreen","source","|","undo","redo","|","bold","italic","underline","fontborder","strikethrough","superscript","subscript","removeformat","formatmatch","autotypeset","blockquote","pasteplain","|","forecolor","backcolor","insertorderedlist","insertunorderedlist","selectall","cleardoc","|","rowspacingtop","rowspacingbottom","lineheight","|","customstyle","paragraph","fontfamily","fontsize","|","directionalityltr","directionalityrtl","indent","|","justifyleft","justifycenter","justifyright","justifyjustify","|","touppercase","tolowercase","|","link","unlink","anchor","|","imagenone","imageleft","imageright","imagecenter","|","simpleupload","insertimage","emotion","scrawl","insertvideo","music","attachment","map","gmap","insertframe","insertcode","template","background","|","horizontal","date","time","spechars","wordimage","|","inserttable","deletetable","insertparagraphbeforetable","insertrow","deleterow","insertcol","deletecol","mergecells","mergeright","mergedown","splittocells","splittorows","splittocols","charts","|","print","preview","searchreplace","drafts","pagebreak"]],initialFrameHeight:320,enableAutoSave:!1,saveInterval:9999999999999,allHtmlEnabled:!1,pageBreakTag:"[SITESERVER_PAGE]",xssFilterRules:!0,inputXssFilter:!0,outputXssFilter:!0,whitList:{a:["target","href","title","class","style","name"],abbr:["title","class","style"],address:["class","style"],area:["shape","coords","href","alt"],article:[],aside:[],audio:["autoplay","controls","loop","preload","src","class","style"],b:["class","style"],bdi:["dir"],bdo:["dir"],big:[],blockquote:["cite","class","style"],br:[],caption:["class","style"],center:[],cite:[],code:["class","style"],col:["align","valign","span","width","class","style"],colgroup:["align","valign","span","width","class","style"],dd:["class","style"],del:["datetime"],details:["open"],div:["class","style"],dl:["class","style"],dt:["class","style"],em:["class","style"],font:["color","size","face"],footer:[],h1:["class","style"],h2:["class","style"],h3:["class","style"],h4:["class","style"],h5:["class","style"],h6:["class","style"],header:[],hr:[],i:["class","style"],img:["src","alt","title","width","height","id","_src", "_url","loadingclass","class","data-latex","word_img","style","anchorname"],ins:["datetime"],li:["class","style"],mark:[],nav:[],ol:["class","style"],p:["class","style"],pre:["class","style"],s:[],section:[],small:[],span:["class","style"],sub:["class","style"],sup:["class","style"],strong:["class","style"],table:["width","border","align","valign","class","style"],tbody:["align","valign","class","style"],td:["width","rowspan","colspan","align","valign","class","style"],tfoot:["align","valign","class","style"],th:["width","rowspan","colspan","align","valign","class","style"],thead:["align","valign","class","style"],tr:["rowspan","align","valign","class","style"],tt:[],u:[],ul:["class","style"],video:["autoplay","controls","loop","preload","src","height","width","class","style"],source: ["src", "type"],embed: ["type", "class", "pluginspage", "src", "width", "height", "align", "style", "wmode", "play","loop", "menu", "allowscriptaccess", "allowfullscreen"]}},window.UE={getUEBasePath:e}}(); \ No newline at end of file diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/index.html b/SiteServer.Web/SiteFiles/assets/ueditor/index.html deleted file mode 100644 index a41641825..000000000 --- a/SiteServer.Web/SiteFiles/assets/ueditor/index.html +++ /dev/null @@ -1,175 +0,0 @@ - - - - 完整demo - - - - - - - - - - -
    -

    完整demo

    - -
    -
    -
    - - - - - - - - - - - -
    -
    - - - - - - - -
    - -
    - - -
    - -
    -
    - - -
    - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/ueditor.all.js b/SiteServer.Web/SiteFiles/assets/ueditor/ueditor.all.js deleted file mode 100644 index 3fae722f0..000000000 --- a/SiteServer.Web/SiteFiles/assets/ueditor/ueditor.all.js +++ /dev/null @@ -1,29567 +0,0 @@ -/*! - * UEditor - * version: ueditor - * build: Wed Aug 10 2016 11:05:20 GMT+0800 (CST) - */ - -(function(){ - -// editor.js -UEDITOR_CONFIG = window.UEDITOR_CONFIG || {}; - -var baidu = window.baidu || {}; - -window.baidu = baidu; - -window.UE = baidu.editor = window.UE || {}; - -UE.plugins = {}; - -UE.commands = {}; - -UE.instants = {}; - -UE.I18N = {}; - -UE._customizeUI = {}; - -UE.version = "1.4.3"; - -var dom = UE.dom = {}; - -// core/browser.js -/** - * 浏览器判断模块 - * @file - * @module UE.browser - * @since 1.2.6.1 - */ - -/** - * 提供浏览器检测的模块 - * @unfile - * @module UE.browser - */ -var browser = UE.browser = function(){ - var agent = navigator.userAgent.toLowerCase(), - opera = window.opera, - browser = { - /** - * @property {boolean} ie 检测当前浏览器是否为IE - * @example - * ```javascript - * if ( UE.browser.ie ) { - * console.log( '当前浏览器是IE' ); - * } - * ``` - */ - ie : /(msie\s|trident.*rv:)([\w.]+)/.test(agent), - - /** - * @property {boolean} opera 检测当前浏览器是否为Opera - * @example - * ```javascript - * if ( UE.browser.opera ) { - * console.log( '当前浏览器是Opera' ); - * } - * ``` - */ - opera : ( !!opera && opera.version ), - - /** - * @property {boolean} webkit 检测当前浏览器是否是webkit内核的浏览器 - * @example - * ```javascript - * if ( UE.browser.webkit ) { - * console.log( '当前浏览器是webkit内核浏览器' ); - * } - * ``` - */ - webkit : ( agent.indexOf( ' applewebkit/' ) > -1 ), - - /** - * @property {boolean} mac 检测当前浏览器是否是运行在mac平台下 - * @example - * ```javascript - * if ( UE.browser.mac ) { - * console.log( '当前浏览器运行在mac平台下' ); - * } - * ``` - */ - mac : ( agent.indexOf( 'macintosh' ) > -1 ), - - /** - * @property {boolean} quirks 检测当前浏览器是否处于“怪异模式”下 - * @example - * ```javascript - * if ( UE.browser.quirks ) { - * console.log( '当前浏览器运行处于“怪异模式”' ); - * } - * ``` - */ - quirks : ( document.compatMode == 'BackCompat' ) - }; - - /** - * @property {boolean} gecko 检测当前浏览器内核是否是gecko内核 - * @example - * ```javascript - * if ( UE.browser.gecko ) { - * console.log( '当前浏览器内核是gecko内核' ); - * } - * ``` - */ - browser.gecko =( navigator.product == 'Gecko' && !browser.webkit && !browser.opera && !browser.ie); - - var version = 0; - - // Internet Explorer 6.0+ - if ( browser.ie ){ - - var v1 = agent.match(/(?:msie\s([\w.]+))/); - var v2 = agent.match(/(?:trident.*rv:([\w.]+))/); - if(v1 && v2 && v1[1] && v2[1]){ - version = Math.max(v1[1]*1,v2[1]*1); - }else if(v1 && v1[1]){ - version = v1[1]*1; - }else if(v2 && v2[1]){ - version = v2[1]*1; - }else{ - version = 0; - } - - browser.ie11Compat = document.documentMode == 11; - /** - * @property { boolean } ie9Compat 检测浏览器模式是否为 IE9 兼容模式 - * @warning 如果浏览器不是IE, 则该值为undefined - * @example - * ```javascript - * if ( UE.browser.ie9Compat ) { - * console.log( '当前浏览器运行在IE9兼容模式下' ); - * } - * ``` - */ - browser.ie9Compat = document.documentMode == 9; - - /** - * @property { boolean } ie8 检测浏览器是否是IE8浏览器 - * @warning 如果浏览器不是IE, 则该值为undefined - * @example - * ```javascript - * if ( UE.browser.ie8 ) { - * console.log( '当前浏览器是IE8浏览器' ); - * } - * ``` - */ - browser.ie8 = !!document.documentMode; - - /** - * @property { boolean } ie8Compat 检测浏览器模式是否为 IE8 兼容模式 - * @warning 如果浏览器不是IE, 则该值为undefined - * @example - * ```javascript - * if ( UE.browser.ie8Compat ) { - * console.log( '当前浏览器运行在IE8兼容模式下' ); - * } - * ``` - */ - browser.ie8Compat = document.documentMode == 8; - - /** - * @property { boolean } ie7Compat 检测浏览器模式是否为 IE7 兼容模式 - * @warning 如果浏览器不是IE, 则该值为undefined - * @example - * ```javascript - * if ( UE.browser.ie7Compat ) { - * console.log( '当前浏览器运行在IE7兼容模式下' ); - * } - * ``` - */ - browser.ie7Compat = ( ( version == 7 && !document.documentMode ) - || document.documentMode == 7 ); - - /** - * @property { boolean } ie6Compat 检测浏览器模式是否为 IE6 模式 或者怪异模式 - * @warning 如果浏览器不是IE, 则该值为undefined - * @example - * ```javascript - * if ( UE.browser.ie6Compat ) { - * console.log( '当前浏览器运行在IE6模式或者怪异模式下' ); - * } - * ``` - */ - browser.ie6Compat = ( version < 7 || browser.quirks ); - - browser.ie9above = version > 8; - - browser.ie9below = version < 9; - - browser.ie11above = version > 10; - - browser.ie11below = version < 11; - - } - - // Gecko. - if ( browser.gecko ){ - var geckoRelease = agent.match( /rv:([\d\.]+)/ ); - if ( geckoRelease ) - { - geckoRelease = geckoRelease[1].split( '.' ); - version = geckoRelease[0] * 10000 + ( geckoRelease[1] || 0 ) * 100 + ( geckoRelease[2] || 0 ) * 1; - } - } - - /** - * @property { Number } chrome 检测当前浏览器是否为Chrome, 如果是,则返回Chrome的大版本号 - * @warning 如果浏览器不是chrome, 则该值为undefined - * @example - * ```javascript - * if ( UE.browser.chrome ) { - * console.log( '当前浏览器是Chrome' ); - * } - * ``` - */ - if (/chrome\/(\d+\.\d)/i.test(agent)) { - browser.chrome = + RegExp['\x241']; - } - - /** - * @property { Number } safari 检测当前浏览器是否为Safari, 如果是,则返回Safari的大版本号 - * @warning 如果浏览器不是safari, 则该值为undefined - * @example - * ```javascript - * if ( UE.browser.safari ) { - * console.log( '当前浏览器是Safari' ); - * } - * ``` - */ - if(/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(agent) && !/chrome/i.test(agent)){ - browser.safari = + (RegExp['\x241'] || RegExp['\x242']); - } - - - // Opera 9.50+ - if ( browser.opera ) - version = parseFloat( opera.version() ); - - // WebKit 522+ (Safari 3+) - if ( browser.webkit ) - version = parseFloat( agent.match( / applewebkit\/(\d+)/ )[1] ); - - /** - * @property { Number } version 检测当前浏览器版本号 - * @remind - *
      - *
    • IE系列返回值为5,6,7,8,9,10等
    • - *
    • gecko系列会返回10900,158900等
    • - *
    • webkit系列会返回其build号 (如 522等)
    • - *
    - * @example - * ```javascript - * console.log( '当前浏览器版本号是: ' + UE.browser.version ); - * ``` - */ - browser.version = version; - - /** - * @property { boolean } isCompatible 检测当前浏览器是否能够与UEditor良好兼容 - * @example - * ```javascript - * if ( UE.browser.isCompatible ) { - * console.log( '浏览器与UEditor能够良好兼容' ); - * } - * ``` - */ - browser.isCompatible = - !browser.mobile && ( - ( browser.ie && version >= 6 ) || - ( browser.gecko && version >= 10801 ) || - ( browser.opera && version >= 9.5 ) || - ( browser.air && version >= 1 ) || - ( browser.webkit && version >= 522 ) || - false ); - return browser; -}(); -//快捷方式 -var ie = browser.ie, - webkit = browser.webkit, - gecko = browser.gecko, - opera = browser.opera; - -// core/utils.js -/** - * 工具函数包 - * @file - * @module UE.utils - * @since 1.2.6.1 - */ - -/** - * UEditor封装使用的静态工具函数 - * @module UE.utils - * @unfile - */ - -var utils = UE.utils = { - - /** - * 用给定的迭代器遍历对象 - * @method each - * @param { Object } obj 需要遍历的对象 - * @param { Function } iterator 迭代器, 该方法接受两个参数, 第一个参数是当前所处理的value, 第二个参数是当前遍历对象的key - * @example - * ```javascript - * var demoObj = { - * key1: 1, - * key2: 2 - * }; - * - * //output: key1: 1, key2: 2 - * UE.utils.each( demoObj, funciton ( value, key ) { - * - * console.log( key + ":" + value ); - * - * } ); - * ``` - */ - - /** - * 用给定的迭代器遍历数组或类数组对象 - * @method each - * @param { Array } array 需要遍历的数组或者类数组 - * @param { Function } iterator 迭代器, 该方法接受两个参数, 第一个参数是当前所处理的value, 第二个参数是当前遍历对象的key - * @example - * ```javascript - * var divs = document.getElmentByTagNames( "div" ); - * - * //output: 0: DIV, 1: DIV ... - * UE.utils.each( divs, funciton ( value, key ) { - * - * console.log( key + ":" + value.tagName ); - * - * } ); - * ``` - */ - each : function(obj, iterator, context) { - if (obj == null) return; - if (obj.length === +obj.length) { - for (var i = 0, l = obj.length; i < l; i++) { - if(iterator.call(context, obj[i], i, obj) === false) - return false; - } - } else { - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - if(iterator.call(context, obj[key], key, obj) === false) - return false; - } - } - } - }, - - /** - * 以给定对象作为原型创建一个新对象 - * @method makeInstance - * @param { Object } protoObject 该对象将作为新创建对象的原型 - * @return { Object } 新的对象, 该对象的原型是给定的protoObject对象 - * @example - * ```javascript - * - * var protoObject = { sayHello: function () { console.log('Hello UEditor!'); } }; - * - * var newObject = UE.utils.makeInstance( protoObject ); - * //output: Hello UEditor! - * newObject.sayHello(); - * ``` - */ - makeInstance:function (obj) { - var noop = new Function(); - noop.prototype = obj; - obj = new noop; - noop.prototype = null; - return obj; - }, - - /** - * 将source对象中的属性扩展到target对象上 - * @method extend - * @remind 该方法将强制把source对象上的属性复制到target对象上 - * @see UE.utils.extend(Object,Object,Boolean) - * @param { Object } target 目标对象, 新的属性将附加到该对象上 - * @param { Object } source 源对象, 该对象的属性会被附加到target对象上 - * @return { Object } 返回target对象 - * @example - * ```javascript - * - * var target = { name: 'target', sex: 1 }, - * source = { name: 'source', age: 17 }; - * - * UE.utils.extend( target, source ); - * - * //output: { name: 'source', sex: 1, age: 17 } - * console.log( target ); - * - * ``` - */ - - /** - * 将source对象中的属性扩展到target对象上, 根据指定的isKeepTarget值决定是否保留目标对象中与 - * 源对象属性名相同的属性值。 - * @method extend - * @param { Object } target 目标对象, 新的属性将附加到该对象上 - * @param { Object } source 源对象, 该对象的属性会被附加到target对象上 - * @param { Boolean } isKeepTarget 是否保留目标对象中与源对象中属性名相同的属性 - * @return { Object } 返回target对象 - * @example - * ```javascript - * - * var target = { name: 'target', sex: 1 }, - * source = { name: 'source', age: 17 }; - * - * UE.utils.extend( target, source, true ); - * - * //output: { name: 'target', sex: 1, age: 17 } - * console.log( target ); - * - * ``` - */ - extend:function (t, s, b) { - if (s) { - for (var k in s) { - if (!b || !t.hasOwnProperty(k)) { - t[k] = s[k]; - } - } - } - return t; - }, - - /** - * 将给定的多个对象的属性复制到目标对象target上 - * @method extend2 - * @remind 该方法将强制把源对象上的属性复制到target对象上 - * @remind 该方法支持两个及以上的参数, 从第二个参数开始, 其属性都会被复制到第一个参数上。 如果遇到同名的属性, - * 将会覆盖掉之前的值。 - * @param { Object } target 目标对象, 新的属性将附加到该对象上 - * @param { Object... } source 源对象, 支持多个对象, 该对象的属性会被附加到target对象上 - * @return { Object } 返回target对象 - * @example - * ```javascript - * - * var target = {}, - * source1 = { name: 'source', age: 17 }, - * source2 = { title: 'dev' }; - * - * UE.utils.extend2( target, source1, source2 ); - * - * //output: { name: 'source', age: 17, title: 'dev' } - * console.log( target ); - * - * ``` - */ - extend2:function (t) { - var a = arguments; - for (var i = 1; i < a.length; i++) { - var x = a[i]; - for (var k in x) { - if (!t.hasOwnProperty(k)) { - t[k] = x[k]; - } - } - } - return t; - }, - - /** - * 模拟继承机制, 使得subClass继承自superClass - * @method inherits - * @param { Object } subClass 子类对象 - * @param { Object } superClass 超类对象 - * @warning 该方法只能让subClass继承超类的原型, subClass对象自身的属性和方法不会被继承 - * @return { Object } 继承superClass后的子类对象 - * @example - * ```javascript - * function SuperClass(){ - * this.name = "小李"; - * } - * - * SuperClass.prototype = { - * hello:function(str){ - * console.log(this.name + str); - * } - * } - * - * function SubClass(){ - * this.name = "小张"; - * } - * - * UE.utils.inherits(SubClass,SuperClass); - * - * var sub = new SubClass(); - * //output: '小张早上好! - * sub.hello("早上好!"); - * ``` - */ - inherits:function (subClass, superClass) { - var oldP = subClass.prototype, - newP = utils.makeInstance(superClass.prototype); - utils.extend(newP, oldP, true); - subClass.prototype = newP; - return (newP.constructor = subClass); - }, - - /** - * 用指定的context对象作为函数fn的上下文 - * @method bind - * @param { Function } fn 需要绑定上下文的函数对象 - * @param { Object } content 函数fn新的上下文对象 - * @return { Function } 一个新的函数, 该函数作为原始函数fn的代理, 将完成fn的上下文调换工作。 - * @example - * ```javascript - * - * var name = 'window', - * newTest = null; - * - * function test () { - * console.log( this.name ); - * } - * - * newTest = UE.utils.bind( test, { name: 'object' } ); - * - * //output: object - * newTest(); - * - * //output: window - * test(); - * - * ``` - */ - bind:function (fn, context) { - return function () { - return fn.apply(context, arguments); - }; - }, - - /** - * 创建延迟指定时间后执行的函数fn - * @method defer - * @param { Function } fn 需要延迟执行的函数对象 - * @param { int } delay 延迟的时间, 单位是毫秒 - * @warning 该方法的时间控制是不精确的,仅仅只能保证函数的执行是在给定的时间之后, - * 而不能保证刚好到达延迟时间时执行。 - * @return { Function } 目标函数fn的代理函数, 只有执行该函数才能起到延时效果 - * @example - * ```javascript - * var start = 0; - * - * function test(){ - * console.log( new Date() - start ); - * } - * - * var testDefer = UE.utils.defer( test, 1000 ); - * // - * start = new Date(); - * //output: (大约在1000毫秒之后输出) 1000 - * testDefer(); - * ``` - */ - - /** - * 创建延迟指定时间后执行的函数fn, 如果在延迟时间内再次执行该方法, 将会根据指定的exclusion的值, - * 决定是否取消前一次函数的执行, 如果exclusion的值为true, 则取消执行,反之,将继续执行前一个方法。 - * @method defer - * @param { Function } fn 需要延迟执行的函数对象 - * @param { int } delay 延迟的时间, 单位是毫秒 - * @param { Boolean } exclusion 如果在延迟时间内再次执行该函数,该值将决定是否取消执行前一次函数的执行, - * 值为true表示取消执行, 反之则将在执行前一次函数之后才执行本次函数调用。 - * @warning 该方法的时间控制是不精确的,仅仅只能保证函数的执行是在给定的时间之后, - * 而不能保证刚好到达延迟时间时执行。 - * @return { Function } 目标函数fn的代理函数, 只有执行该函数才能起到延时效果 - * @example - * ```javascript - * - * function test(){ - * console.log(1); - * } - * - * var testDefer = UE.utils.defer( test, 1000, true ); - * - * //output: (两次调用仅有一次输出) 1 - * testDefer(); - * testDefer(); - * ``` - */ - defer:function (fn, delay, exclusion) { - var timerID; - return function () { - if (exclusion) { - clearTimeout(timerID); - } - timerID = setTimeout(fn, delay); - }; - }, - - /** - * 获取元素item在数组array中首次出现的位置, 如果未找到item, 则返回-1 - * @method indexOf - * @remind 该方法的匹配过程使用的是恒等“===” - * @param { Array } array 需要查找的数组对象 - * @param { * } item 需要在目标数组中查找的值 - * @return { int } 返回item在目标数组array中首次出现的位置, 如果在数组中未找到item, 则返回-1 - * @example - * ```javascript - * var item = 1, - * arr = [ 3, 4, 6, 8, 1, 1, 2 ]; - * - * //output: 4 - * console.log( UE.utils.indexOf( arr, item ) ); - * ``` - */ - - /** - * 获取元素item数组array中首次出现的位置, 如果未找到item, 则返回-1。通过start的值可以指定搜索的起始位置。 - * @method indexOf - * @remind 该方法的匹配过程使用的是恒等“===” - * @param { Array } array 需要查找的数组对象 - * @param { * } item 需要在目标数组中查找的值 - * @param { int } start 搜索的起始位置 - * @return { int } 返回item在目标数组array中的start位置之后首次出现的位置, 如果在数组中未找到item, 则返回-1 - * @example - * ```javascript - * var item = 1, - * arr = [ 3, 4, 6, 8, 1, 2, 8, 3, 2, 1, 1, 4 ]; - * - * //output: 9 - * console.log( UE.utils.indexOf( arr, item, 5 ) ); - * ``` - */ - indexOf:function (array, item, start) { - var index = -1; - start = this.isNumber(start) ? start : 0; - this.each(array, function (v, i) { - if (i >= start && v === item) { - index = i; - return false; - } - }); - return index; - }, - - /** - * 移除数组array中所有的元素item - * @method removeItem - * @param { Array } array 要移除元素的目标数组 - * @param { * } item 将要被移除的元素 - * @remind 该方法的匹配过程使用的是恒等“===” - * @example - * ```javascript - * var arr = [ 4, 5, 7, 1, 3, 4, 6 ]; - * - * UE.utils.removeItem( arr, 4 ); - * //output: [ 5, 7, 1, 3, 6 ] - * console.log( arr ); - * - * ``` - */ - removeItem:function (array, item) { - for (var i = 0, l = array.length; i < l; i++) { - if (array[i] === item) { - array.splice(i, 1); - i--; - } - } - }, - - /** - * 删除字符串str的首尾空格 - * @method trim - * @param { String } str 需要删除首尾空格的字符串 - * @return { String } 删除了首尾的空格后的字符串 - * @example - * ```javascript - * - * var str = " UEdtior "; - * - * //output: 9 - * console.log( str.length ); - * - * //output: 7 - * console.log( UE.utils.trim( " UEdtior " ).length ); - * - * //output: 9 - * console.log( str.length ); - * - * ``` - */ - trim:function (str) { - return str.replace(/(^[ \t\n\r]+)|([ \t\n\r]+$)/g, ''); - }, - - /** - * 将字符串str以','分隔成数组后,将该数组转换成哈希对象, 其生成的hash对象的key为数组中的元素, value为1 - * @method listToMap - * @warning 该方法在生成的hash对象中,会为每一个key同时生成一个另一个全大写的key。 - * @param { String } str 该字符串将被以','分割为数组, 然后进行转化 - * @return { Object } 转化之后的hash对象 - * @example - * ```javascript - * - * //output: Object {UEdtior: 1, UEDTIOR: 1, Hello: 1, HELLO: 1} - * console.log( UE.utils.listToMap( 'UEdtior,Hello' ) ); - * - * ``` - */ - - /** - * 将字符串数组转换成哈希对象, 其生成的hash对象的key为数组中的元素, value为1 - * @method listToMap - * @warning 该方法在生成的hash对象中,会为每一个key同时生成一个另一个全大写的key。 - * @param { Array } arr 字符串数组 - * @return { Object } 转化之后的hash对象 - * @example - * ```javascript - * - * //output: Object {UEdtior: 1, UEDTIOR: 1, Hello: 1, HELLO: 1} - * console.log( UE.utils.listToMap( [ 'UEdtior', 'Hello' ] ) ); - * - * ``` - */ - listToMap:function (list) { - if (!list)return {}; - list = utils.isArray(list) ? list : list.split(','); - for (var i = 0, ci, obj = {}; ci = list[i++];) { - obj[ci.toUpperCase()] = obj[ci] = 1; - } - return obj; - }, - - /** - * 将str中的html符号转义,将转义“',&,<,",>”五个字符 - * @method unhtml - * @param { String } str 需要转义的字符串 - * @return { String } 转义后的字符串 - * @example - * ```javascript - * var html = '&'; - * - * //output: <body>&</body> - * console.log( UE.utils.unhtml( html ) ); - * - * ``` - */ - unhtml:function (str, reg) { - return str ? str.replace(reg || /[&<">'](?:(amp|lt|quot|gt|#39|nbsp|#\d+);)?/g, function (a, b) { - if (b) { - return a; - } else { - return { - '<':'<', - '&':'&', - '"':'"', - '>':'>', - "'":''' - }[a] - } - - }) : ''; - }, - /** - * 将url中的html字符转义, 仅转义 ', ", <, > 四个字符 - * @param { String } str 需要转义的字符串 - * @param { RegExp } reg 自定义的正则 - * @return { String } 转义后的字符串 - */ - unhtmlForUrl:function (str, reg) { - return str ? str.replace(reg || /[<">']/g, function (a) { - return { - '<':'<', - '&':'&', - '"':'"', - '>':'>', - "'":''' - }[a] - - }) : ''; - }, - - /** - * 将str中的转义字符还原成html字符 - * @see UE.utils.unhtml(String); - * @method html - * @param { String } str 需要逆转义的字符串 - * @return { String } 逆转义后的字符串 - * @example - * ```javascript - * - * var str = '<body>&</body>'; - * - * //output: & - * console.log( UE.utils.html( str ) ); - * - * ``` - */ - html:function (str) { - return str ? str.replace(/&((g|l|quo)t|amp|#39|nbsp);/g, function (m) { - return { - '<':'<', - '&':'&', - '"':'"', - '>':'>', - ''':"'", - ' ':' ' - }[m] - }) : ''; - }, - - /** - * 将css样式转换为驼峰的形式 - * @method cssStyleToDomStyle - * @param { String } cssName 需要转换的css样式名 - * @return { String } 转换成驼峰形式后的css样式名 - * @example - * ```javascript - * - * var str = 'border-top'; - * - * //output: borderTop - * console.log( UE.utils.cssStyleToDomStyle( str ) ); - * - * ``` - */ - cssStyleToDomStyle:function () { - var test = document.createElement('div').style, - cache = { - 'float':test.cssFloat != undefined ? 'cssFloat' : test.styleFloat != undefined ? 'styleFloat' : 'float' - }; - - return function (cssName) { - return cache[cssName] || (cache[cssName] = cssName.toLowerCase().replace(/-./g, function (match) { - return match.charAt(1).toUpperCase(); - })); - }; - }(), - - /** - * 动态加载文件到doc中 - * @method loadFile - * @param { DomDocument } document 需要加载资源文件的文档对象 - * @param { Object } options 加载资源文件的属性集合, 取值请参考代码示例 - * @example - * ```javascript - * - * UE.utils.loadFile( document, { - * src:"test.js", - * tag:"script", - * type:"text/javascript", - * defer:"defer" - * } ); - * - * ``` - */ - - /** - * 动态加载文件到doc中,加载成功后执行的回调函数fn - * @method loadFile - * @param { DomDocument } document 需要加载资源文件的文档对象 - * @param { Object } options 加载资源文件的属性集合, 该集合支持的值是script标签和style标签支持的所有属性。 - * @param { Function } fn 资源文件加载成功之后执行的回调 - * @warning 对于在同一个文档中多次加载同一URL的文件, 该方法会在第一次加载之后缓存该请求, - * 在此之后的所有同一URL的请求, 将会直接触发回调。 - * @example - * ```javascript - * - * UE.utils.loadFile( document, { - * src:"test.js", - * tag:"script", - * type:"text/javascript", - * defer:"defer" - * }, function () { - * console.log('加载成功'); - * } ); - * - * ``` - */ - loadFile:function () { - var tmpList = []; - - function getItem(doc, obj) { - try { - for (var i = 0, ci; ci = tmpList[i++];) { - if (ci.doc === doc && ci.url == (obj.src || obj.href)) { - return ci; - } - } - } catch (e) { - return null; - } - - } - - return function (doc, obj, fn) { - var item = getItem(doc, obj); - if (item) { - if (item.ready) { - fn && fn(); - } else { - item.funs.push(fn) - } - return; - } - tmpList.push({ - doc:doc, - url:obj.src || obj.href, - funs:[fn] - }); - if (!doc.body) { - var html = []; - for (var p in obj) { - if (p == 'tag')continue; - html.push(p + '="' + obj[p] + '"') - } - doc.write('<' + obj.tag + ' ' + html.join(' ') + ' >'); - return; - } - if (obj.id && doc.getElementById(obj.id)) { - return; - } - var element = doc.createElement(obj.tag); - delete obj.tag; - for (var p in obj) { - element.setAttribute(p, obj[p]); - } - element.onload = element.onreadystatechange = function () { - if (!this.readyState || /loaded|complete/.test(this.readyState)) { - item = getItem(doc, obj); - if (item.funs.length > 0) { - item.ready = 1; - for (var fi; fi = item.funs.pop();) { - fi(); - } - } - element.onload = element.onreadystatechange = null; - } - }; - element.onerror = function () { - throw Error('The load ' + (obj.href || obj.src) + ' fails,check the url settings of file ueditor.config.js ') - }; - doc.getElementsByTagName("head")[0].appendChild(element); - } - }(), - - /** - * 判断obj对象是否为空 - * @method isEmptyObject - * @param { * } obj 需要判断的对象 - * @remind 如果判断的对象是NULL, 将直接返回true, 如果是数组且为空, 返回true, 如果是字符串, 且字符串为空, - * 返回true, 如果是普通对象, 且该对象没有任何实例属性, 返回true - * @return { Boolean } 对象是否为空 - * @example - * ```javascript - * - * //output: true - * console.log( UE.utils.isEmptyObject( {} ) ); - * - * //output: true - * console.log( UE.utils.isEmptyObject( [] ) ); - * - * //output: true - * console.log( UE.utils.isEmptyObject( "" ) ); - * - * //output: false - * console.log( UE.utils.isEmptyObject( { key: 1 } ) ); - * - * //output: false - * console.log( UE.utils.isEmptyObject( [1] ) ); - * - * //output: false - * console.log( UE.utils.isEmptyObject( "1" ) ); - * - * ``` - */ - isEmptyObject:function (obj) { - if (obj == null) return true; - if (this.isArray(obj) || this.isString(obj)) return obj.length === 0; - for (var key in obj) if (obj.hasOwnProperty(key)) return false; - return true; - }, - - /** - * 把rgb格式的颜色值转换成16进制格式 - * @method fixColor - * @param { String } rgb格式的颜色值 - * @param { String } - * @example - * rgb(255,255,255) => "#ffffff" - */ - fixColor:function (name, value) { - if (/color/i.test(name) && /rgba?/.test(value)) { - var array = value.split(","); - if (array.length > 3) - return ""; - value = "#"; - for (var i = 0, color; color = array[i++];) { - color = parseInt(color.replace(/[^\d]/gi, ''), 10).toString(16); - value += color.length == 1 ? "0" + color : color; - } - value = value.toUpperCase(); - } - return value; - }, - /** - * 只针对border,padding,margin做了处理,因为性能问题 - * @public - * @function - * @param {String} val style字符串 - */ - optCss:function (val) { - var padding, margin, border; - val = val.replace(/(padding|margin|border)\-([^:]+):([^;]+);?/gi, function (str, key, name, val) { - if (val.split(' ').length == 1) { - switch (key) { - case 'padding': - !padding && (padding = {}); - padding[name] = val; - return ''; - case 'margin': - !margin && (margin = {}); - margin[name] = val; - return ''; - case 'border': - return val == 'initial' ? '' : str; - } - } - return str; - }); - - function opt(obj, name) { - if (!obj) { - return ''; - } - var t = obj.top , b = obj.bottom, l = obj.left, r = obj.right, val = ''; - if (!t || !l || !b || !r) { - for (var p in obj) { - val += ';' + name + '-' + p + ':' + obj[p] + ';'; - } - } else { - val += ';' + name + ':' + - (t == b && b == l && l == r ? t : - t == b && l == r ? (t + ' ' + l) : - l == r ? (t + ' ' + l + ' ' + b) : (t + ' ' + r + ' ' + b + ' ' + l)) + ';' - } - return val; - } - - val += opt(padding, 'padding') + opt(margin, 'margin'); - return val.replace(/^[ \n\r\t;]*|[ \n\r\t]*$/, '').replace(/;([ \n\r\t]+)|\1;/g, ';') - .replace(/(&((l|g)t|quot|#39))?;{2,}/g, function (a, b) { - return b ? b + ";;" : ';' - }); - }, - - /** - * 克隆对象 - * @method clone - * @param { Object } source 源对象 - * @return { Object } source的一个副本 - */ - - /** - * 深度克隆对象,将source的属性克隆到target对象, 会覆盖target重名的属性。 - * @method clone - * @param { Object } source 源对象 - * @param { Object } target 目标对象 - * @return { Object } 附加了source对象所有属性的target对象 - */ - clone:function (source, target) { - var tmp; - target = target || {}; - for (var i in source) { - if (source.hasOwnProperty(i)) { - tmp = source[i]; - if (typeof tmp == 'object') { - target[i] = utils.isArray(tmp) ? [] : {}; - utils.clone(source[i], target[i]) - } else { - target[i] = tmp; - } - } - } - return target; - }, - - /** - * 把cm/pt为单位的值转换为px为单位的值 - * @method transUnitToPx - * @param { String } 待转换的带单位的字符串 - * @return { String } 转换为px为计量单位的值的字符串 - * @example - * ```javascript - * - * //output: 500px - * console.log( UE.utils.transUnitToPx( '20cm' ) ); - * - * //output: 27px - * console.log( UE.utils.transUnitToPx( '20pt' ) ); - * - * ``` - */ - transUnitToPx:function (val) { - if (!/(pt|cm)/.test(val)) { - return val - } - var unit; - val.replace(/([\d.]+)(\w+)/, function (str, v, u) { - val = v; - unit = u; - }); - switch (unit) { - case 'cm': - val = parseFloat(val) * 25; - break; - case 'pt': - val = Math.round(parseFloat(val) * 96 / 72); - } - return val + (val ? 'px' : ''); - }, - - /** - * 在dom树ready之后执行给定的回调函数 - * @method domReady - * @remind 如果在执行该方法的时候, dom树已经ready, 那么回调函数将立刻执行 - * @param { Function } fn dom树ready之后的回调函数 - * @example - * ```javascript - * - * UE.utils.domReady( function () { - * - * console.log('123'); - * - * } ); - * - * ``` - */ - domReady:function () { - - var fnArr = []; - - function doReady(doc) { - //确保onready只执行一次 - doc.isReady = true; - for (var ci; ci = fnArr.pop(); ci()) { - } - } - - return function (onready, win) { - win = win || window; - var doc = win.document; - onready && fnArr.push(onready); - if (doc.readyState === "complete") { - doReady(doc); - } else { - doc.isReady && doReady(doc); - if (browser.ie && browser.version != 11) { - (function () { - if (doc.isReady) return; - try { - doc.documentElement.doScroll("left"); - } catch (error) { - setTimeout(arguments.callee, 0); - return; - } - doReady(doc); - })(); - win.attachEvent('onload', function () { - doReady(doc) - }); - } else { - doc.addEventListener("DOMContentLoaded", function () { - doc.removeEventListener("DOMContentLoaded", arguments.callee, false); - doReady(doc); - }, false); - win.addEventListener('load', function () { - doReady(doc) - }, false); - } - } - - } - }(), - - /** - * 动态添加css样式 - * @method cssRule - * @param { String } 节点名称 - * @grammar UE.utils.cssRule('添加的样式的节点名称',['样式','放到哪个document上']) - * @grammar UE.utils.cssRule('body','body{background:#ccc}') => null //给body添加背景颜色 - * @grammar UE.utils.cssRule('body') =>样式的字符串 //取得key值为body的样式的内容,如果没有找到key值先关的样式将返回空,例如刚才那个背景颜色,将返回 body{background:#ccc} - * @grammar UE.utils.cssRule('body',document) => 返回指定key的样式,并且指定是哪个document - * @grammar UE.utils.cssRule('body','') =>null //清空给定的key值的背景颜色 - */ - cssRule:browser.ie && browser.version != 11 ? function (key, style, doc) { - var indexList, index; - if(style === undefined || style && style.nodeType && style.nodeType == 9){ - //获取样式 - doc = style && style.nodeType && style.nodeType == 9 ? style : (doc || document); - indexList = doc.indexList || (doc.indexList = {}); - index = indexList[key]; - if(index !== undefined){ - return doc.styleSheets[index].cssText - } - return undefined; - } - doc = doc || document; - indexList = doc.indexList || (doc.indexList = {}); - index = indexList[key]; - //清除样式 - if(style === ''){ - if(index!== undefined){ - doc.styleSheets[index].cssText = ''; - delete indexList[key]; - return true - } - return false; - } - - //添加样式 - if(index!== undefined){ - sheetStyle = doc.styleSheets[index]; - }else{ - sheetStyle = doc.createStyleSheet('', index = doc.styleSheets.length); - indexList[key] = index; - } - sheetStyle.cssText = style; - }: function (key, style, doc) { - var head, node; - if(style === undefined || style && style.nodeType && style.nodeType == 9){ - //获取样式 - doc = style && style.nodeType && style.nodeType == 9 ? style : (doc || document); - node = doc.getElementById(key); - return node ? node.innerHTML : undefined; - } - doc = doc || document; - node = doc.getElementById(key); - - //清除样式 - if(style === ''){ - if(node){ - node.parentNode.removeChild(node); - return true - } - return false; - } - - //添加样式 - if(node){ - node.innerHTML = style; - }else{ - node = doc.createElement('style'); - node.id = key; - node.innerHTML = style; - doc.getElementsByTagName('head')[0].appendChild(node); - } - }, - sort:function(array,compareFn){ - compareFn = compareFn || function(item1, item2){ return item1.localeCompare(item2);}; - for(var i= 0,len = array.length; i 0){ - var t = array[i]; - array[i] = array[j]; - array[j] = t; - } - } - } - return array; - }, - serializeParam:function (json) { - var strArr = []; - for (var i in json) { - //忽略默认的几个参数 - if(i=="method" || i=="timeout" || i=="async") continue; - //传递过来的对象和函数不在提交之列 - if (!((typeof json[i]).toLowerCase() == "function" || (typeof json[i]).toLowerCase() == "object")) { - strArr.push( encodeURIComponent(i) + "="+encodeURIComponent(json[i]) ); - } else if (utils.isArray(json[i])) { - //支持传数组内容 - for(var j = 0; j < json[i].length; j++) { - strArr.push( encodeURIComponent(i) + "[]="+encodeURIComponent(json[i][j]) ); - } - } - } - return strArr.join("&"); - }, - formatUrl:function (url) { - var u = url.replace(/&&/g, '&'); - u = u.replace(/\?&/g, '?'); - u = u.replace(/&$/g, ''); - u = u.replace(/&#/g, '#'); - u = u.replace(/&+/g, '&'); - return u; - }, - isCrossDomainUrl:function (url) { - var a = document.createElement('a'); - a.href = url; - if (browser.ie) { - a.href = a.href; - } - return !(a.protocol == location.protocol && a.hostname == location.hostname && - (a.port == location.port || (a.port == '80' && location.port == '') || (a.port == '' && location.port == '80'))); - }, - clearEmptyAttrs : function(obj){ - for(var p in obj){ - if(obj[p] === ''){ - delete obj[p] - } - } - return obj; - }, - str2json : function(s){ - - if (!utils.isString(s)) return null; - if (window.JSON) { - return JSON.parse(s); - } else { - return (new Function("return " + utils.trim(s || '')))(); - } - - }, - json2str : (function(){ - - if (window.JSON) { - - return JSON.stringify; - - } else { - - var escapeMap = { - "\b": '\\b', - "\t": '\\t', - "\n": '\\n', - "\f": '\\f', - "\r": '\\r', - '"' : '\\"', - "\\": '\\\\' - }; - - function encodeString(source) { - if (/["\\\x00-\x1f]/.test(source)) { - source = source.replace( - /["\\\x00-\x1f]/g, - function (match) { - var c = escapeMap[match]; - if (c) { - return c; - } - c = match.charCodeAt(); - return "\\u00" - + Math.floor(c / 16).toString(16) - + (c % 16).toString(16); - }); - } - return '"' + source + '"'; - } - - function encodeArray(source) { - var result = ["["], - l = source.length, - preComma, i, item; - - for (i = 0; i < l; i++) { - item = source[i]; - - switch (typeof item) { - case "undefined": - case "function": - case "unknown": - break; - default: - if(preComma) { - result.push(','); - } - result.push(utils.json2str(item)); - preComma = 1; - } - } - result.push("]"); - return result.join(""); - } - - function pad(source) { - return source < 10 ? '0' + source : source; - } - - function encodeDate(source){ - return '"' + source.getFullYear() + "-" - + pad(source.getMonth() + 1) + "-" - + pad(source.getDate()) + "T" - + pad(source.getHours()) + ":" - + pad(source.getMinutes()) + ":" - + pad(source.getSeconds()) + '"'; - } - - return function (value) { - switch (typeof value) { - case 'undefined': - return 'undefined'; - - case 'number': - return isFinite(value) ? String(value) : "null"; - - case 'string': - return encodeString(value); - - case 'boolean': - return String(value); - - default: - if (value === null) { - return 'null'; - } else if (utils.isArray(value)) { - return encodeArray(value); - } else if (utils.isDate(value)) { - return encodeDate(value); - } else { - var result = ['{'], - encode = utils.json2str, - preComma, - item; - - for (var key in value) { - if (Object.prototype.hasOwnProperty.call(value, key)) { - item = value[key]; - switch (typeof item) { - case 'undefined': - case 'unknown': - case 'function': - break; - default: - if (preComma) { - result.push(','); - } - preComma = 1; - result.push(encode(key) + ':' + encode(item)); - } - } - } - result.push('}'); - return result.join(''); - } - } - }; - } - - })() - -}; -/** - * 判断给定的对象是否是字符串 - * @method isString - * @param { * } object 需要判断的对象 - * @return { Boolean } 给定的对象是否是字符串 - */ - -/** - * 判断给定的对象是否是数组 - * @method isArray - * @param { * } object 需要判断的对象 - * @return { Boolean } 给定的对象是否是数组 - */ - -/** - * 判断给定的对象是否是一个Function - * @method isFunction - * @param { * } object 需要判断的对象 - * @return { Boolean } 给定的对象是否是Function - */ - -/** - * 判断给定的对象是否是Number - * @method isNumber - * @param { * } object 需要判断的对象 - * @return { Boolean } 给定的对象是否是Number - */ - -/** - * 判断给定的对象是否是一个正则表达式 - * @method isRegExp - * @param { * } object 需要判断的对象 - * @return { Boolean } 给定的对象是否是正则表达式 - */ - -/** - * 判断给定的对象是否是一个普通对象 - * @method isObject - * @param { * } object 需要判断的对象 - * @return { Boolean } 给定的对象是否是普通对象 - */ -utils.each(['String', 'Function', 'Array', 'Number', 'RegExp', 'Object', 'Date'], function (v) { - UE.utils['is' + v] = function (obj) { - return Object.prototype.toString.apply(obj) == '[object ' + v + ']'; - } -}); - - -// core/EventBase.js -/** - * UE采用的事件基类 - * @file - * @module UE - * @class EventBase - * @since 1.2.6.1 - */ - -/** - * UEditor公用空间,UEditor所有的功能都挂载在该空间下 - * @unfile - * @module UE - */ - -/** - * UE采用的事件基类,继承此类的对应类将获取addListener,removeListener,fireEvent方法。 - * 在UE中,Editor以及所有ui实例都继承了该类,故可以在对应的ui对象以及editor对象上使用上述方法。 - * @unfile - * @module UE - * @class EventBase - */ - -/** - * 通过此构造器,子类可以继承EventBase获取事件监听的方法 - * @constructor - * @example - * ```javascript - * UE.EventBase.call(editor); - * ``` - */ -var EventBase = UE.EventBase = function () {}; - -EventBase.prototype = { - - /** - * 注册事件监听器 - * @method addListener - * @param { String } types 监听的事件名称,同时监听多个事件使用空格分隔 - * @param { Function } fn 监听的事件被触发时,会执行该回调函数 - * @waining 事件被触发时,监听的函数假如返回的值恒等于true,回调函数的队列中后面的函数将不执行 - * @example - * ```javascript - * editor.addListener('selectionchange',function(){ - * console.log("选区已经变化!"); - * }) - * editor.addListener('beforegetcontent aftergetcontent',function(type){ - * if(type == 'beforegetcontent'){ - * //do something - * }else{ - * //do something - * } - * console.log(this.getContent) // this是注册的事件的编辑器实例 - * }) - * ``` - * @see UE.EventBase:fireEvent(String) - */ - addListener:function (types, listener) { - types = utils.trim(types).split(/\s+/); - for (var i = 0, ti; ti = types[i++];) { - getListener(this, ti, true).push(listener); - } - }, - - on : function(types, listener){ - return this.addListener(types,listener); - }, - off : function(types, listener){ - return this.removeListener(types, listener) - }, - trigger:function(){ - return this.fireEvent.apply(this,arguments); - }, - /** - * 移除事件监听器 - * @method removeListener - * @param { String } types 移除的事件名称,同时移除多个事件使用空格分隔 - * @param { Function } fn 移除监听事件的函数引用 - * @example - * ```javascript - * //changeCallback为方法体 - * editor.removeListener("selectionchange",changeCallback); - * ``` - */ - removeListener:function (types, listener) { - types = utils.trim(types).split(/\s+/); - for (var i = 0, ti; ti = types[i++];) { - utils.removeItem(getListener(this, ti) || [], listener); - } - }, - - /** - * 触发事件 - * @method fireEvent - * @param { String } types 触发的事件名称,同时触发多个事件使用空格分隔 - * @remind 该方法会触发addListener - * @return { * } 返回触发事件的队列中,最后执行的回调函数的返回值 - * @example - * ```javascript - * editor.fireEvent("selectionchange"); - * ``` - */ - - /** - * 触发事件 - * @method fireEvent - * @param { String } types 触发的事件名称,同时触发多个事件使用空格分隔 - * @param { *... } options 可选参数,可以传入一个或多个参数,会传给事件触发的回调函数 - * @return { * } 返回触发事件的队列中,最后执行的回调函数的返回值 - * @example - * ```javascript - * - * editor.addListener( "selectionchange", function ( type, arg1, arg2 ) { - * - * console.log( arg1 + " " + arg2 ); - * - * } ); - * - * //触发selectionchange事件, 会执行上面的事件监听器 - * //output: Hello World - * editor.fireEvent("selectionchange", "Hello", "World"); - * ``` - */ - fireEvent:function () { - var types = arguments[0]; - types = utils.trim(types).split(' '); - for (var i = 0, ti; ti = types[i++];) { - var listeners = getListener(this, ti), - r, t, k; - if (listeners) { - k = listeners.length; - while (k--) { - if(!listeners[k])continue; - t = listeners[k].apply(this, arguments); - if(t === true){ - return t; - } - if (t !== undefined) { - r = t; - } - } - } - if (t = this['on' + ti.toLowerCase()]) { - r = t.apply(this, arguments); - } - } - return r; - } -}; -/** - * 获得对象所拥有监听类型的所有监听器 - * @unfile - * @module UE - * @since 1.2.6.1 - * @method getListener - * @public - * @param { Object } obj 查询监听器的对象 - * @param { String } type 事件类型 - * @param { Boolean } force 为true且当前所有type类型的侦听器不存在时,创建一个空监听器数组 - * @return { Array } 监听器数组 - */ -function getListener(obj, type, force) { - var allListeners; - type = type.toLowerCase(); - return ( ( allListeners = ( obj.__allListeners || force && ( obj.__allListeners = {} ) ) ) - && ( allListeners[type] || force && ( allListeners[type] = [] ) ) ); -} - - - -// core/dtd.js -///import editor.js -///import core/dom/dom.js -///import core/utils.js -/** - * dtd html语义化的体现类 - * @constructor - * @namespace dtd - */ -var dtd = dom.dtd = (function() { - function _( s ) { - for (var k in s) { - s[k.toUpperCase()] = s[k]; - } - return s; - } - var X = utils.extend2; - var A = _({isindex:1,fieldset:1}), - B = _({input:1,button:1,select:1,textarea:1,label:1}), - C = X( _({a:1}), B ), - D = X( {iframe:1}, C ), - E = _({hr:1,ul:1,menu:1,div:1,blockquote:1,noscript:1,table:1,center:1,address:1,dir:1,pre:1,h5:1,dl:1,h4:1,noframes:1,h6:1,ol:1,h1:1,h3:1,h2:1}), - F = _({ins:1,del:1,script:1,style:1}), - G = X( _({b:1,acronym:1,bdo:1,'var':1,'#':1,abbr:1,code:1,br:1,i:1,cite:1,kbd:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,dfn:1,span:1}), F ), - H = X( _({sub:1,img:1,embed:1,object:1,sup:1,basefont:1,map:1,applet:1,font:1,big:1,small:1}), G ), - I = X( _({p:1}), H ), - J = X( _({iframe:1}), H, B ), - K = _({img:1,embed:1,noscript:1,br:1,kbd:1,center:1,button:1,basefont:1,h5:1,h4:1,samp:1,h6:1,ol:1,h1:1,h3:1,h2:1,form:1,font:1,'#':1,select:1,menu:1,ins:1,abbr:1,label:1,code:1,table:1,script:1,cite:1,input:1,iframe:1,strong:1,textarea:1,noframes:1,big:1,small:1,span:1,hr:1,sub:1,bdo:1,'var':1,div:1,object:1,sup:1,strike:1,dir:1,map:1,dl:1,applet:1,del:1,isindex:1,fieldset:1,ul:1,b:1,acronym:1,a:1,blockquote:1,i:1,u:1,s:1,tt:1,address:1,q:1,pre:1,p:1,em:1,dfn:1}), - - L = X( _({a:0}), J ),//a不能被切开,所以把他 - M = _({tr:1}), - N = _({'#':1}), - O = X( _({param:1}), K ), - P = X( _({form:1}), A, D, E, I ), - Q = _({li:1,ol:1,ul:1}), - R = _({style:1,script:1}), - S = _({base:1,link:1,meta:1,title:1}), - T = X( S, R ), - U = _({head:1,body:1}), - V = _({html:1}); - - var block = _({address:1,blockquote:1,center:1,dir:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,isindex:1,menu:1,noframes:1,ol:1,p:1,pre:1,table:1,ul:1}), - - empty = _({area:1,base:1,basefont:1,br:1,col:1,command:1,dialog:1,embed:1,hr:1,img:1,input:1,isindex:1,keygen:1,link:1,meta:1,param:1,source:1,track:1,wbr:1}); - - return _({ - - // $ 表示自定的属性 - - // body外的元素列表. - $nonBodyContent: X( V, U, S ), - - //块结构元素列表 - $block : block, - - //内联元素列表 - $inline : L, - - $inlineWithA : X(_({a:1}),L), - - $body : X( _({script:1,style:1}), block ), - - $cdata : _({script:1,style:1}), - - //自闭和元素 - $empty : empty, - - //不是自闭合,但不能让range选中里边 - $nonChild : _({iframe:1,textarea:1}), - //列表元素列表 - $listItem : _({dd:1,dt:1,li:1}), - - //列表根元素列表 - $list: _({ul:1,ol:1,dl:1}), - - //不能认为是空的元素 - $isNotEmpty : _({table:1,ul:1,ol:1,dl:1,iframe:1,area:1,base:1,col:1,hr:1,img:1,embed:1,input:1,link:1,meta:1,param:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1}), - - //如果没有子节点就可以删除的元素列表,像span,a - $removeEmpty : _({a:1,abbr:1,acronym:1,address:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,s:1,samp:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,tt:1,u:1,'var':1}), - - $removeEmptyBlock : _({'p':1,'div':1}), - - //在table元素里的元素列表 - $tableContent : _({caption:1,col:1,colgroup:1,tbody:1,td:1,tfoot:1,th:1,thead:1,tr:1,table:1}), - //不转换的标签 - $notTransContent : _({pre:1,script:1,style:1,textarea:1}), - html: U, - head: T, - style: N, - script: N, - body: P, - base: {}, - link: {}, - meta: {}, - title: N, - col : {}, - tr : _({td:1,th:1}), - img : {}, - embed: {}, - colgroup : _({thead:1,col:1,tbody:1,tr:1,tfoot:1}), - noscript : P, - td : P, - br : {}, - th : P, - center : P, - kbd : L, - button : X( I, E ), - basefont : {}, - h5 : L, - h4 : L, - samp : L, - h6 : L, - ol : Q, - h1 : L, - h3 : L, - option : N, - h2 : L, - form : X( A, D, E, I ), - select : _({optgroup:1,option:1}), - font : L, - ins : L, - menu : Q, - abbr : L, - label : L, - table : _({thead:1,col:1,tbody:1,tr:1,colgroup:1,caption:1,tfoot:1}), - code : L, - tfoot : M, - cite : L, - li : P, - input : {}, - iframe : P, - strong : L, - textarea : N, - noframes : P, - big : L, - small : L, - //trace: - span :_({'#':1,br:1,b:1,strong:1,u:1,i:1,em:1,sub:1,sup:1,strike:1,span:1}), - hr : L, - dt : L, - sub : L, - optgroup : _({option:1}), - param : {}, - bdo : L, - 'var' : L, - div : P, - object : O, - sup : L, - dd : P, - strike : L, - area : {}, - dir : Q, - map : X( _({area:1,form:1,p:1}), A, F, E ), - applet : O, - dl : _({dt:1,dd:1}), - del : L, - isindex : {}, - fieldset : X( _({legend:1}), K ), - thead : M, - ul : Q, - acronym : L, - b : L, - a : X( _({a:1}), J ), - blockquote :X(_({td:1,tr:1,tbody:1,li:1}),P), - caption : L, - i : L, - u : L, - tbody : M, - s : L, - address : X( D, I ), - tt : L, - legend : L, - q : L, - pre : X( G, C ), - p : X(_({'a':1}),L), - em :L, - dfn : L - }); -})(); - - -// core/domUtils.js -/** - * Dom操作工具包 - * @file - * @module UE.dom.domUtils - * @since 1.2.6.1 - */ - -/** - * Dom操作工具包 - * @unfile - * @module UE.dom.domUtils - */ -function getDomNode(node, start, ltr, startFromChild, fn, guard) { - var tmpNode = startFromChild && node[start], - parent; - !tmpNode && (tmpNode = node[ltr]); - while (!tmpNode && (parent = (parent || node).parentNode)) { - if (parent.tagName == 'BODY' || guard && !guard(parent)) { - return null; - } - tmpNode = parent[ltr]; - } - if (tmpNode && fn && !fn(tmpNode)) { - return getDomNode(tmpNode, start, ltr, false, fn); - } - return tmpNode; -} -var attrFix = ie && browser.version < 9 ? { - tabindex:"tabIndex", - readonly:"readOnly", - "for":"htmlFor", - "class":"className", - maxlength:"maxLength", - cellspacing:"cellSpacing", - cellpadding:"cellPadding", - rowspan:"rowSpan", - colspan:"colSpan", - usemap:"useMap", - frameborder:"frameBorder" - } : { - tabindex:"tabIndex", - readonly:"readOnly" - }, - styleBlock = utils.listToMap([ - '-webkit-box', '-moz-box', 'block' , - 'list-item' , 'table' , 'table-row-group' , - 'table-header-group', 'table-footer-group' , - 'table-row' , 'table-column-group' , 'table-column' , - 'table-cell' , 'table-caption' - ]); -var domUtils = dom.domUtils = { - //节点常量 - NODE_ELEMENT:1, - NODE_DOCUMENT:9, - NODE_TEXT:3, - NODE_COMMENT:8, - NODE_DOCUMENT_FRAGMENT:11, - - //位置关系 - POSITION_IDENTICAL:0, - POSITION_DISCONNECTED:1, - POSITION_FOLLOWING:2, - POSITION_PRECEDING:4, - POSITION_IS_CONTAINED:8, - POSITION_CONTAINS:16, - //ie6使用其他的会有一段空白出现 - fillChar:ie && browser.version == '6' ? '\ufeff' : '\u200B', - //-------------------------Node部分-------------------------------- - keys:{ - /*Backspace*/ 8:1, /*Delete*/ 46:1, - /*Shift*/ 16:1, /*Ctrl*/ 17:1, /*Alt*/ 18:1, - 37:1, 38:1, 39:1, 40:1, - 13:1 /*enter*/ - }, - /** - * 获取节点A相对于节点B的位置关系 - * @method getPosition - * @param { Node } nodeA 需要查询位置关系的节点A - * @param { Node } nodeB 需要查询位置关系的节点B - * @return { Number } 节点A与节点B的关系 - * @example - * ```javascript - * //output: 20 - * var position = UE.dom.domUtils.getPosition( document.documentElement, document.body ); - * - * switch ( position ) { - * - * //0 - * case UE.dom.domUtils.POSITION_IDENTICAL: - * console.log('元素相同'); - * break; - * //1 - * case UE.dom.domUtils.POSITION_DISCONNECTED: - * console.log('两个节点在不同的文档中'); - * break; - * //2 - * case UE.dom.domUtils.POSITION_FOLLOWING: - * console.log('节点A在节点B之后'); - * break; - * //4 - * case UE.dom.domUtils.POSITION_PRECEDING; - * console.log('节点A在节点B之前'); - * break; - * //8 - * case UE.dom.domUtils.POSITION_IS_CONTAINED: - * console.log('节点A被节点B包含'); - * break; - * case 10: - * console.log('节点A被节点B包含且节点A在节点B之后'); - * break; - * //16 - * case UE.dom.domUtils.POSITION_CONTAINS: - * console.log('节点A包含节点B'); - * break; - * case 20: - * console.log('节点A包含节点B且节点A在节点B之前'); - * break; - * - * } - * ``` - */ - getPosition:function (nodeA, nodeB) { - // 如果两个节点是同一个节点 - if (nodeA === nodeB) { - // domUtils.POSITION_IDENTICAL - return 0; - } - var node, - parentsA = [nodeA], - parentsB = [nodeB]; - node = nodeA; - while (node = node.parentNode) { - // 如果nodeB是nodeA的祖先节点 - if (node === nodeB) { - // domUtils.POSITION_IS_CONTAINED + domUtils.POSITION_FOLLOWING - return 10; - } - parentsA.push(node); - } - node = nodeB; - while (node = node.parentNode) { - // 如果nodeA是nodeB的祖先节点 - if (node === nodeA) { - // domUtils.POSITION_CONTAINS + domUtils.POSITION_PRECEDING - return 20; - } - parentsB.push(node); - } - parentsA.reverse(); - parentsB.reverse(); - if (parentsA[0] !== parentsB[0]) { - // domUtils.POSITION_DISCONNECTED - return 1; - } - var i = -1; - while (i++, parentsA[i] === parentsB[i]) { - } - nodeA = parentsA[i]; - nodeB = parentsB[i]; - while (nodeA = nodeA.nextSibling) { - if (nodeA === nodeB) { - // domUtils.POSITION_PRECEDING - return 4 - } - } - // domUtils.POSITION_FOLLOWING - return 2; - }, - - /** - * 检测节点node在父节点中的索引位置 - * @method getNodeIndex - * @param { Node } node 需要检测的节点对象 - * @return { Number } 该节点在父节点中的位置 - * @see UE.dom.domUtils.getNodeIndex(Node,Boolean) - */ - - /** - * 检测节点node在父节点中的索引位置, 根据给定的mergeTextNode参数决定是否要合并多个连续的文本节点为一个节点 - * @method getNodeIndex - * @param { Node } node 需要检测的节点对象 - * @param { Boolean } mergeTextNode 是否合并多个连续的文本节点为一个节点 - * @return { Number } 该节点在父节点中的位置 - * @example - * ```javascript - * - * var node = document.createElement("div"); - * - * node.appendChild( document.createTextNode( "hello" ) ); - * node.appendChild( document.createTextNode( "world" ) ); - * node.appendChild( node = document.createElement( "div" ) ); - * - * //output: 2 - * console.log( UE.dom.domUtils.getNodeIndex( node ) ); - * - * //output: 1 - * console.log( UE.dom.domUtils.getNodeIndex( node, true ) ); - * - * ``` - */ - getNodeIndex:function (node, ignoreTextNode) { - var preNode = node, - i = 0; - while (preNode = preNode.previousSibling) { - if (ignoreTextNode && preNode.nodeType == 3) { - if(preNode.nodeType != preNode.nextSibling.nodeType ){ - i++; - } - continue; - } - i++; - } - return i; - }, - - /** - * 检测节点node是否在给定的document对象上 - * @method inDoc - * @param { Node } node 需要检测的节点对象 - * @param { DomDocument } doc 需要检测的document对象 - * @return { Boolean } 该节点node是否在给定的document的dom树上 - * @example - * ```javascript - * - * var node = document.createElement("div"); - * - * //output: false - * console.log( UE.do.domUtils.inDoc( node, document ) ); - * - * document.body.appendChild( node ); - * - * //output: true - * console.log( UE.do.domUtils.inDoc( node, document ) ); - * - * ``` - */ - inDoc:function (node, doc) { - return domUtils.getPosition(node, doc) == 10; - }, - /** - * 根据给定的过滤规则filterFn, 查找符合该过滤规则的node节点的第一个祖先节点, - * 查找的起点是给定node节点的父节点。 - * @method findParent - * @param { Node } node 需要查找的节点 - * @param { Function } filterFn 自定义的过滤方法。 - * @warning 查找的终点是到body节点为止 - * @remind 自定义的过滤方法filterFn接受一个Node对象作为参数, 该对象代表当前执行检测的祖先节点。 如果该 - * 节点满足过滤条件, 则要求返回true, 这时将直接返回该节点作为findParent()的结果, 否则, 请返回false。 - * @return { Node | Null } 如果找到符合过滤条件的节点, 就返回该节点, 否则返回NULL - * @example - * ```javascript - * var filterNode = UE.dom.domUtils.findParent( document.body.firstChild, function ( node ) { - * - * //由于查找的终点是body节点, 所以永远也不会匹配当前过滤器的条件, 即这里永远会返回false - * return node.tagName === "HTML"; - * - * } ); - * - * //output: true - * console.log( filterNode === null ); - * ``` - */ - - /** - * 根据给定的过滤规则filterFn, 查找符合该过滤规则的node节点的第一个祖先节点, - * 如果includeSelf的值为true,则查找的起点是给定的节点node, 否则, 起点是node的父节点 - * @method findParent - * @param { Node } node 需要查找的节点 - * @param { Function } filterFn 自定义的过滤方法。 - * @param { Boolean } includeSelf 查找过程是否包含自身 - * @warning 查找的终点是到body节点为止 - * @remind 自定义的过滤方法filterFn接受一个Node对象作为参数, 该对象代表当前执行检测的祖先节点。 如果该 - * 节点满足过滤条件, 则要求返回true, 这时将直接返回该节点作为findParent()的结果, 否则, 请返回false。 - * @remind 如果includeSelf为true, 则过滤器第一次执行时的参数会是节点本身。 - * 反之, 过滤器第一次执行时的参数将是该节点的父节点。 - * @return { Node | Null } 如果找到符合过滤条件的节点, 就返回该节点, 否则返回NULL - * @example - * ```html - * - * - *
    - *
    - * - * - * - * ``` - */ - findParent:function (node, filterFn, includeSelf) { - if (node && !domUtils.isBody(node)) { - node = includeSelf ? node : node.parentNode; - while (node) { - if (!filterFn || filterFn(node) || domUtils.isBody(node)) { - return filterFn && !filterFn(node) && domUtils.isBody(node) ? null : node; - } - node = node.parentNode; - } - } - return null; - }, - /** - * 查找node的节点名为tagName的第一个祖先节点, 查找的起点是node节点的父节点。 - * @method findParentByTagName - * @param { Node } node 需要查找的节点对象 - * @param { Array } tagNames 需要查找的父节点的名称数组 - * @warning 查找的终点是到body节点为止 - * @return { Node | NULL } 如果找到符合条件的节点, 则返回该节点, 否则返回NULL - * @example - * ```javascript - * var node = UE.dom.domUtils.findParentByTagName( document.getElementsByTagName("div")[0], [ "BODY" ] ); - * //output: BODY - * console.log( node.tagName ); - * ``` - */ - - /** - * 查找node的节点名为tagName的祖先节点, 如果includeSelf的值为true,则查找的起点是给定的节点node, - * 否则, 起点是node的父节点。 - * @method findParentByTagName - * @param { Node } node 需要查找的节点对象 - * @param { Array } tagNames 需要查找的父节点的名称数组 - * @param { Boolean } includeSelf 查找过程是否包含node节点自身 - * @warning 查找的终点是到body节点为止 - * @return { Node | NULL } 如果找到符合条件的节点, 则返回该节点, 否则返回NULL - * @example - * ```javascript - * var queryTarget = document.getElementsByTagName("div")[0]; - * var node = UE.dom.domUtils.findParentByTagName( queryTarget, [ "DIV" ], true ); - * //output: true - * console.log( queryTarget === node ); - * ``` - */ - findParentByTagName:function (node, tagNames, includeSelf, excludeFn) { - tagNames = utils.listToMap(utils.isArray(tagNames) ? tagNames : [tagNames]); - return domUtils.findParent(node, function (node) { - return tagNames[node.tagName] && !(excludeFn && excludeFn(node)); - }, includeSelf); - }, - /** - * 查找节点node的祖先节点集合, 查找的起点是给定节点的父节点,结果集中不包含给定的节点。 - * @method findParents - * @param { Node } node 需要查找的节点对象 - * @return { Array } 给定节点的祖先节点数组 - * @grammar UE.dom.domUtils.findParents(node) => Array //返回一个祖先节点数组集合,不包含自身 - * @grammar UE.dom.domUtils.findParents(node,includeSelf) => Array //返回一个祖先节点数组集合,includeSelf指定是否包含自身 - * @grammar UE.dom.domUtils.findParents(node,includeSelf,filterFn) => Array //返回一个祖先节点数组集合,filterFn指定过滤条件,返回true的node将被选取 - * @grammar UE.dom.domUtils.findParents(node,includeSelf,filterFn,closerFirst) => Array //返回一个祖先节点数组集合,closerFirst为true的话,node的直接父亲节点是数组的第0个 - */ - - /** - * 查找节点node的祖先节点集合, 如果includeSelf的值为true, - * 则返回的结果集中允许出现当前给定的节点, 否则, 该节点不会出现在其结果集中。 - * @method findParents - * @param { Node } node 需要查找的节点对象 - * @param { Boolean } includeSelf 查找的结果中是否允许包含当前查找的节点对象 - * @return { Array } 给定节点的祖先节点数组 - */ - findParents:function (node, includeSelf, filterFn, closerFirst) { - var parents = includeSelf && ( filterFn && filterFn(node) || !filterFn ) ? [node] : []; - while (node = domUtils.findParent(node, filterFn)) { - parents.push(node); - } - return closerFirst ? parents : parents.reverse(); - }, - - /** - * 在节点node后面插入新节点newNode - * @method insertAfter - * @param { Node } node 目标节点 - * @param { Node } newNode 新插入的节点, 该节点将置于目标节点之后 - * @return { Node } 新插入的节点 - */ - insertAfter:function (node, newNode) { - return node.nextSibling ? node.parentNode.insertBefore(newNode, node.nextSibling): - node.parentNode.appendChild(newNode); - }, - - /** - * 删除节点node及其下属的所有节点 - * @method remove - * @param { Node } node 需要删除的节点对象 - * @return { Node } 返回刚删除的节点对象 - * @example - * ```html - *
    - *
    你好
    - *
    - * - * ``` - */ - - /** - * 删除节点node,并根据keepChildren的值决定是否保留子节点 - * @method remove - * @param { Node } node 需要删除的节点对象 - * @param { Boolean } keepChildren 是否需要保留子节点 - * @return { Node } 返回刚删除的节点对象 - * @example - * ```html - *
    - *
    你好
    - *
    - * - * ``` - */ - remove:function (node, keepChildren) { - var parent = node.parentNode, - child; - if (parent) { - if (keepChildren && node.hasChildNodes()) { - while (child = node.firstChild) { - parent.insertBefore(child, node); - } - } - parent.removeChild(node); - } - return node; - }, - - /** - * 取得node节点的下一个兄弟节点, 如果该节点其后没有兄弟节点, 则递归查找其父节点之后的第一个兄弟节点, - * 直到找到满足条件的节点或者递归到BODY节点之后才会结束。 - * @method getNextDomNode - * @param { Node } node 需要获取其后的兄弟节点的节点对象 - * @return { Node | NULL } 如果找满足条件的节点, 则返回该节点, 否则返回NULL - * @example - * ```html - * - *
    - * - *
    - * xxx - * - * - * ``` - * @example - * ```html - * - *
    - * - * xxx - *
    - * xxx - * - * - * ``` - */ - - /** - * 取得node节点的下一个兄弟节点, 如果startFromChild的值为ture,则先获取其子节点, - * 如果有子节点则直接返回第一个子节点;如果没有子节点或者startFromChild的值为false, - * 则执行getNextDomNode(Node node)的查找过程。 - * @method getNextDomNode - * @param { Node } node 需要获取其后的兄弟节点的节点对象 - * @param { Boolean } startFromChild 查找过程是否从其子节点开始 - * @return { Node | NULL } 如果找满足条件的节点, 则返回该节点, 否则返回NULL - * @see UE.dom.domUtils.getNextDomNode(Node) - */ - getNextDomNode:function (node, startFromChild, filterFn, guard) { - return getDomNode(node, 'firstChild', 'nextSibling', startFromChild, filterFn, guard); - }, - getPreDomNode:function (node, startFromChild, filterFn, guard) { - return getDomNode(node, 'lastChild', 'previousSibling', startFromChild, filterFn, guard); - }, - /** - * 检测节点node是否属是UEditor定义的bookmark节点 - * @method isBookmarkNode - * @private - * @param { Node } node 需要检测的节点对象 - * @return { Boolean } 是否是bookmark节点 - * @example - * ```html - * - * - * ``` - */ - isBookmarkNode:function (node) { - return node.nodeType == 1 && node.id && /^_baidu_bookmark_/i.test(node.id); - }, - /** - * 获取节点node所属的window对象 - * @method getWindow - * @param { Node } node 节点对象 - * @return { Window } 当前节点所属的window对象 - * @example - * ```javascript - * //output: true - * console.log( UE.dom.domUtils.getWindow( document.body ) === window ); - * ``` - */ - getWindow:function (node) { - var doc = node.ownerDocument || node; - return doc.defaultView || doc.parentWindow; - }, - /** - * 获取离nodeA与nodeB最近的公共的祖先节点 - * @method getCommonAncestor - * @param { Node } nodeA 第一个节点 - * @param { Node } nodeB 第二个节点 - * @remind 如果给定的两个节点是同一个节点, 将直接返回该节点。 - * @return { Node | NULL } 如果未找到公共节点, 返回NULL, 否则返回最近的公共祖先节点。 - * @example - * ```javascript - * var commonAncestor = UE.dom.domUtils.getCommonAncestor( document.body, document.body.firstChild ); - * //output: true - * console.log( commonAncestor.tagName.toLowerCase() === 'body' ); - * ``` - */ - getCommonAncestor:function (nodeA, nodeB) { - if (nodeA === nodeB) - return nodeA; - var parentsA = [nodeA] , parentsB = [nodeB], parent = nodeA, i = -1; - while (parent = parent.parentNode) { - if (parent === nodeB) { - return parent; - } - parentsA.push(parent); - } - parent = nodeB; - while (parent = parent.parentNode) { - if (parent === nodeA) - return parent; - parentsB.push(parent); - } - parentsA.reverse(); - parentsB.reverse(); - while (i++, parentsA[i] === parentsB[i]) { - } - return i == 0 ? null : parentsA[i - 1]; - - }, - /** - * 清除node节点左右连续为空的兄弟inline节点 - * @method clearEmptySibling - * @param { Node } node 执行的节点对象, 如果该节点的左右连续的兄弟节点是空的inline节点, - * 则这些兄弟节点将被删除 - * @grammar UE.dom.domUtils.clearEmptySibling(node,ignoreNext) //ignoreNext指定是否忽略右边空节点 - * @grammar UE.dom.domUtils.clearEmptySibling(node,ignoreNext,ignorePre) //ignorePre指定是否忽略左边空节点 - * @example - * ```html - * - *
    - * - * - * - * xxx - * - * - * - * ``` - */ - - /** - * 清除node节点左右连续为空的兄弟inline节点, 如果ignoreNext的值为true, - * 则忽略对右边兄弟节点的操作。 - * @method clearEmptySibling - * @param { Node } node 执行的节点对象, 如果该节点的左右连续的兄弟节点是空的inline节点, - * @param { Boolean } ignoreNext 是否忽略忽略对右边的兄弟节点的操作 - * 则这些兄弟节点将被删除 - * @see UE.dom.domUtils.clearEmptySibling(Node) - */ - - /** - * 清除node节点左右连续为空的兄弟inline节点, 如果ignoreNext的值为true, - * 则忽略对右边兄弟节点的操作, 如果ignorePre的值为true,则忽略对左边兄弟节点的操作。 - * @method clearEmptySibling - * @param { Node } node 执行的节点对象, 如果该节点的左右连续的兄弟节点是空的inline节点, - * @param { Boolean } ignoreNext 是否忽略忽略对右边的兄弟节点的操作 - * @param { Boolean } ignorePre 是否忽略忽略对左边的兄弟节点的操作 - * 则这些兄弟节点将被删除 - * @see UE.dom.domUtils.clearEmptySibling(Node) - */ - clearEmptySibling:function (node, ignoreNext, ignorePre) { - function clear(next, dir) { - var tmpNode; - while (next && !domUtils.isBookmarkNode(next) && (domUtils.isEmptyInlineElement(next) - //这里不能把空格算进来会吧空格干掉,出现文字间的空格丢掉了 - || !new RegExp('[^\t\n\r' + domUtils.fillChar + ']').test(next.nodeValue) )) { - tmpNode = next[dir]; - domUtils.remove(next); - next = tmpNode; - } - } - !ignoreNext && clear(node.nextSibling, 'nextSibling'); - !ignorePre && clear(node.previousSibling, 'previousSibling'); - }, - /** - * 将一个文本节点textNode拆分成两个文本节点,offset指定拆分位置 - * @method split - * @param { Node } textNode 需要拆分的文本节点对象 - * @param { int } offset 需要拆分的位置, 位置计算从0开始 - * @return { Node } 拆分后形成的新节点 - * @example - * ```html - *
    abcdef
    - * - * ``` - */ - split:function (node, offset) { - var doc = node.ownerDocument; - if (browser.ie && offset == node.nodeValue.length) { - var next = doc.createTextNode(''); - return domUtils.insertAfter(node, next); - } - var retval = node.splitText(offset); - //ie8下splitText不会跟新childNodes,我们手动触发他的更新 - if (browser.ie8) { - var tmpNode = doc.createTextNode(''); - domUtils.insertAfter(retval, tmpNode); - domUtils.remove(tmpNode); - } - return retval; - }, - - /** - * 检测文本节点textNode是否为空节点(包括空格、换行、占位符等字符) - * @method isWhitespace - * @param { Node } node 需要检测的节点对象 - * @return { Boolean } 检测的节点是否为空 - * @example - * ```html - *
    - * - *
    - * - * ``` - */ - isWhitespace:function (node) { - return !new RegExp('[^ \t\n\r' + domUtils.fillChar + ']').test(node.nodeValue); - }, - /** - * 获取元素element相对于viewport的位置坐标 - * @method getXY - * @param { Node } element 需要计算位置的节点对象 - * @return { Object } 返回形如{x:left,y:top}的一个key-value映射对象, 其中键x代表水平偏移距离, - * y代表垂直偏移距离。 - * - * @example - * ```javascript - * var location = UE.dom.domUtils.getXY( document.getElementById("test") ); - * //output: test的坐标为: 12, 24 - * console.log( 'test的坐标为: ', location.x, ',', location.y ); - * ``` - */ - getXY:function (element) { - var x = 0, y = 0; - while (element.offsetParent) { - y += element.offsetTop; - x += element.offsetLeft; - element = element.offsetParent; - } - return { 'x':x, 'y':y}; - }, - /** - * 为元素element绑定原生DOM事件,type为事件类型,handler为处理函数 - * @method on - * @param { Node } element 需要绑定事件的节点对象 - * @param { String } type 绑定的事件类型 - * @param { Function } handler 事件处理器 - * @example - * ```javascript - * UE.dom.domUtils.on(document.body,"click",function(e){ - * //e为事件对象,this为被点击元素对戏那个 - * }); - * ``` - */ - - /** - * 为元素element绑定原生DOM事件,type为事件类型,handler为处理函数 - * @method on - * @param { Node } element 需要绑定事件的节点对象 - * @param { Array } type 绑定的事件类型数组 - * @param { Function } handler 事件处理器 - * @example - * ```javascript - * UE.dom.domUtils.on(document.body,["click","mousedown"],function(evt){ - * //evt为事件对象,this为被点击元素对象 - * }); - * ``` - */ - on:function (element, type, handler) { - - var types = utils.isArray(type) ? type : utils.trim(type).split(/\s+/), - k = types.length; - if (k) while (k--) { - type = types[k]; - if (element.addEventListener) { - element.addEventListener(type, handler, false); - } else { - if (!handler._d) { - handler._d = { - els : [] - }; - } - var key = type + handler.toString(),index = utils.indexOf(handler._d.els,element); - if (!handler._d[key] || index == -1) { - if(index == -1){ - handler._d.els.push(element); - } - if(!handler._d[key]){ - handler._d[key] = function (evt) { - return handler.call(evt.srcElement, evt || window.event); - }; - } - - - element.attachEvent('on' + type, handler._d[key]); - } - } - } - element = null; - }, - /** - * 解除DOM事件绑定 - * @method un - * @param { Node } element 需要解除事件绑定的节点对象 - * @param { String } type 需要接触绑定的事件类型 - * @param { Function } handler 对应的事件处理器 - * @example - * ```javascript - * UE.dom.domUtils.un(document.body,"click",function(evt){ - * //evt为事件对象,this为被点击元素对象 - * }); - * ``` - */ - - /** - * 解除DOM事件绑定 - * @method un - * @param { Node } element 需要解除事件绑定的节点对象 - * @param { Array } type 需要接触绑定的事件类型数组 - * @param { Function } handler 对应的事件处理器 - * @example - * ```javascript - * UE.dom.domUtils.un(document.body, ["click","mousedown"],function(evt){ - * //evt为事件对象,this为被点击元素对象 - * }); - * ``` - */ - un:function (element, type, handler) { - var types = utils.isArray(type) ? type : utils.trim(type).split(/\s+/), - k = types.length; - if (k) while (k--) { - type = types[k]; - if (element.removeEventListener) { - element.removeEventListener(type, handler, false); - } else { - var key = type + handler.toString(); - try{ - element.detachEvent('on' + type, handler._d ? handler._d[key] : handler); - }catch(e){} - if (handler._d && handler._d[key]) { - var index = utils.indexOf(handler._d.els,element); - if(index!=-1){ - handler._d.els.splice(index,1); - } - handler._d.els.length == 0 && delete handler._d[key]; - } - } - } - }, - - /** - * 比较节点nodeA与节点nodeB是否具有相同的标签名、属性名以及属性值 - * @method isSameElement - * @param { Node } nodeA 需要比较的节点 - * @param { Node } nodeB 需要比较的节点 - * @return { Boolean } 两个节点是否具有相同的标签名、属性名以及属性值 - * @example - * ```html - * ssss - * bbbbb - * ssss - * bbbbb - * - * - * ``` - */ - isSameElement:function (nodeA, nodeB) { - if (nodeA.tagName != nodeB.tagName) { - return false; - } - var thisAttrs = nodeA.attributes, - otherAttrs = nodeB.attributes; - if (!ie && thisAttrs.length != otherAttrs.length) { - return false; - } - var attrA, attrB, al = 0, bl = 0; - for (var i = 0; attrA = thisAttrs[i++];) { - if (attrA.nodeName == 'style') { - if (attrA.specified) { - al++; - } - if (domUtils.isSameStyle(nodeA, nodeB)) { - continue; - } else { - return false; - } - } - if (ie) { - if (attrA.specified) { - al++; - attrB = otherAttrs.getNamedItem(attrA.nodeName); - } else { - continue; - } - } else { - attrB = nodeB.attributes[attrA.nodeName]; - } - if (!attrB.specified || attrA.nodeValue != attrB.nodeValue) { - return false; - } - } - // 有可能attrB的属性包含了attrA的属性之外还有自己的属性 - if (ie) { - for (i = 0; attrB = otherAttrs[i++];) { - if (attrB.specified) { - bl++; - } - } - if (al != bl) { - return false; - } - } - return true; - }, - - /** - * 判断节点nodeA与节点nodeB的元素的style属性是否一致 - * @method isSameStyle - * @param { Node } nodeA 需要比较的节点 - * @param { Node } nodeB 需要比较的节点 - * @return { Boolean } 两个节点是否具有相同的style属性值 - * @example - * ```html - * ssss - * bbbbb - * ssss - * bbbbb - * - * - * ``` - */ - isSameStyle:function (nodeA, nodeB) { - var styleA = nodeA.style.cssText.replace(/( ?; ?)/g, ';').replace(/( ?: ?)/g, ':'), - styleB = nodeB.style.cssText.replace(/( ?; ?)/g, ';').replace(/( ?: ?)/g, ':'); - if (browser.opera) { - styleA = nodeA.style; - styleB = nodeB.style; - if (styleA.length != styleB.length) - return false; - for (var p in styleA) { - if (/^(\d+|csstext)$/i.test(p)) { - continue; - } - if (styleA[p] != styleB[p]) { - return false; - } - } - return true; - } - if (!styleA || !styleB) { - return styleA == styleB; - } - styleA = styleA.split(';'); - styleB = styleB.split(';'); - if (styleA.length != styleB.length) { - return false; - } - for (var i = 0, ci; ci = styleA[i++];) { - if (utils.indexOf(styleB, ci) == -1) { - return false; - } - } - return true; - }, - /** - * 检查节点node是否为block元素 - * @method isBlockElm - * @param { Node } node 需要检测的节点对象 - * @return { Boolean } 是否是block元素节点 - * @warning 该方法的判断规则如下: 如果该元素原本是block元素, 则不论该元素当前的css样式是什么都会返回true; - * 否则,检测该元素的css样式, 如果该元素当前是block元素, 则返回true。 其余情况下都返回false。 - * @example - * ```html - * - * - *
    - * - * - * ``` - */ - isBlockElm:function (node) { - return node.nodeType == 1 && (dtd.$block[node.tagName] || styleBlock[domUtils.getComputedStyle(node, 'display')]) && !dtd.$nonChild[node.tagName]; - }, - /** - * 检测node节点是否为body节点 - * @method isBody - * @param { Element } node 需要检测的dom元素 - * @return { Boolean } 给定的元素是否是body元素 - * @example - * ```javascript - * //output: true - * console.log( UE.dom.domUtils.isBody( document.body ) ); - * ``` - */ - isBody:function (node) { - return node && node.nodeType == 1 && node.tagName.toLowerCase() == 'body'; - }, - /** - * 以node节点为分界,将该节点的指定祖先节点parent拆分成两个独立的节点, - * 拆分形成的两个节点之间是node节点 - * @method breakParent - * @param { Node } node 作为分界的节点对象 - * @param { Node } parent 该节点必须是node节点的祖先节点, 且是block节点。 - * @return { Node } 给定的node分界节点 - * @example - * ```javascript - * - * var node = document.createElement("span"), - * wrapNode = document.createElement( "div" ), - * parent = document.createElement("p"); - * - * parent.appendChild( node ); - * wrapNode.appendChild( parent ); - * - * //拆分前 - * //output:

    - * console.log( wrapNode.innerHTML ); - * - * - * UE.dom.domUtils.breakParent( node, parent ); - * //拆分后 - * //output:

    - * console.log( wrapNode.innerHTML ); - * - * ``` - */ - breakParent:function (node, parent) { - var tmpNode, - parentClone = node, - clone = node, - leftNodes, - rightNodes; - do { - parentClone = parentClone.parentNode; - if (leftNodes) { - tmpNode = parentClone.cloneNode(false); - tmpNode.appendChild(leftNodes); - leftNodes = tmpNode; - tmpNode = parentClone.cloneNode(false); - tmpNode.appendChild(rightNodes); - rightNodes = tmpNode; - } else { - leftNodes = parentClone.cloneNode(false); - rightNodes = leftNodes.cloneNode(false); - } - while (tmpNode = clone.previousSibling) { - leftNodes.insertBefore(tmpNode, leftNodes.firstChild); - } - while (tmpNode = clone.nextSibling) { - rightNodes.appendChild(tmpNode); - } - clone = parentClone; - } while (parent !== parentClone); - tmpNode = parent.parentNode; - tmpNode.insertBefore(leftNodes, parent); - tmpNode.insertBefore(rightNodes, parent); - tmpNode.insertBefore(node, rightNodes); - domUtils.remove(parent); - return node; - }, - /** - * 检查节点node是否是空inline节点 - * @method isEmptyInlineElement - * @param { Node } node 需要检测的节点对象 - * @return { Number } 如果给定的节点是空的inline节点, 则返回1, 否则返回0。 - * @example - * ```html - * => 1 - * => 1 - * => 1 - * xx => 0 - * ``` - */ - isEmptyInlineElement:function (node) { - if (node.nodeType != 1 || !dtd.$removeEmpty[ node.tagName ]) { - return 0; - } - node = node.firstChild; - while (node) { - //如果是创建的bookmark就跳过 - if (domUtils.isBookmarkNode(node)) { - return 0; - } - if (node.nodeType == 1 && !domUtils.isEmptyInlineElement(node) || - node.nodeType == 3 && !domUtils.isWhitespace(node) - ) { - return 0; - } - node = node.nextSibling; - } - return 1; - - }, - - /** - * 删除node节点下首尾两端的空白文本子节点 - * @method trimWhiteTextNode - * @param { Element } node 需要执行删除操作的元素对象 - * @example - * ```javascript - * var node = document.createElement("div"); - * - * node.appendChild( document.createTextNode( "" ) ); - * - * node.appendChild( document.createElement("div") ); - * - * node.appendChild( document.createTextNode( "" ) ); - * - * //3 - * console.log( node.childNodes.length ); - * - * UE.dom.domUtils.trimWhiteTextNode( node ); - * - * //1 - * console.log( node.childNodes.length ); - * ``` - */ - trimWhiteTextNode:function (node) { - function remove(dir) { - var child; - while ((child = node[dir]) && child.nodeType == 3 && domUtils.isWhitespace(child)) { - node.removeChild(child); - } - } - remove('firstChild'); - remove('lastChild'); - }, - - /** - * 合并node节点下相同的子节点 - * @name mergeChild - * @desc - * UE.dom.domUtils.mergeChild(node,tagName) //tagName要合并的子节点的标签 - * @example - *

    xxaaxx

    - * ==> UE.dom.domUtils.mergeChild(node,'span') - *

    xxaaxx

    - */ - mergeChild:function (node, tagName, attrs) { - var list = domUtils.getElementsByTagName(node, node.tagName.toLowerCase()); - for (var i = 0, ci; ci = list[i++];) { - if (!ci.parentNode || domUtils.isBookmarkNode(ci)) { - continue; - } - //span单独处理 - if (ci.tagName.toLowerCase() == 'span') { - if (node === ci.parentNode) { - domUtils.trimWhiteTextNode(node); - if (node.childNodes.length == 1) { - node.style.cssText = ci.style.cssText + ";" + node.style.cssText; - domUtils.remove(ci, true); - continue; - } - } - ci.style.cssText = node.style.cssText + ';' + ci.style.cssText; - if (attrs) { - var style = attrs.style; - if (style) { - style = style.split(';'); - for (var j = 0, s; s = style[j++];) { - ci.style[utils.cssStyleToDomStyle(s.split(':')[0])] = s.split(':')[1]; - } - } - } - if (domUtils.isSameStyle(ci, node)) { - domUtils.remove(ci, true); - } - continue; - } - if (domUtils.isSameElement(node, ci)) { - domUtils.remove(ci, true); - } - } - }, - - /** - * 原生方法getElementsByTagName的封装 - * @method getElementsByTagName - * @param { Node } node 目标节点对象 - * @param { String } tagName 需要查找的节点的tagName, 多个tagName以空格分割 - * @return { Array } 符合条件的节点集合 - */ - getElementsByTagName:function (node, name,filter) { - if(filter && utils.isString(filter)){ - var className = filter; - filter = function(node){return domUtils.hasClass(node,className)} - } - name = utils.trim(name).replace(/[ ]{2,}/g,' ').split(' '); - var arr = []; - for(var n = 0,ni;ni=name[n++];){ - var list = node.getElementsByTagName(ni); - for (var i = 0, ci; ci = list[i++];) { - if(!filter || filter(ci)) - arr.push(ci); - } - } - - return arr; - }, - /** - * 将节点node提取到父节点上 - * @method mergeToParent - * @param { Element } node 需要提取的元素对象 - * @example - * ```html - *
    - *
    - * - *
    - *
    - * - * - * ``` - */ - mergeToParent:function (node) { - var parent = node.parentNode; - while (parent && dtd.$removeEmpty[parent.tagName]) { - if (parent.tagName == node.tagName || parent.tagName == 'A') {//针对a标签单独处理 - domUtils.trimWhiteTextNode(parent); - //span需要特殊处理 不处理这样的情况 xxxxxxxxx - if (parent.tagName == 'SPAN' && !domUtils.isSameStyle(parent, node) - || (parent.tagName == 'A' && node.tagName == 'SPAN')) { - if (parent.childNodes.length > 1 || parent !== node.parentNode) { - node.style.cssText = parent.style.cssText + ";" + node.style.cssText; - parent = parent.parentNode; - continue; - } else { - parent.style.cssText += ";" + node.style.cssText; - //trace:952 a标签要保持下划线 - if (parent.tagName == 'A') { - parent.style.textDecoration = 'underline'; - } - } - } - if (parent.tagName != 'A') { - parent === node.parentNode && domUtils.remove(node, true); - break; - } - } - parent = parent.parentNode; - } - }, - /** - * 合并节点node的左右兄弟节点 - * @method mergeSibling - * @param { Element } node 需要合并的目标节点 - * @example - * ```html - * xxxxoooxxxx - * - * - * ``` - */ - - /** - * 合并节点node的左右兄弟节点, 可以根据给定的条件选择是否忽略合并左节点。 - * @method mergeSibling - * @param { Element } node 需要合并的目标节点 - * @param { Boolean } ignorePre 是否忽略合并左节点 - * @example - * ```html - * xxxxoooxxxx - * - * - * ``` - */ - - /** - * 合并节点node的左右兄弟节点,可以根据给定的条件选择是否忽略合并左右节点。 - * @method mergeSibling - * @param { Element } node 需要合并的目标节点 - * @param { Boolean } ignorePre 是否忽略合并左节点 - * @param { Boolean } ignoreNext 是否忽略合并右节点 - * @remind 如果同时忽略左右节点, 则该操作什么也不会做 - * @example - * ```html - * xxxxoooxxxx - * - * - * ``` - */ - mergeSibling:function (node, ignorePre, ignoreNext) { - function merge(rtl, start, node) { - var next; - if ((next = node[rtl]) && !domUtils.isBookmarkNode(next) && next.nodeType == 1 && domUtils.isSameElement(node, next)) { - while (next.firstChild) { - if (start == 'firstChild') { - node.insertBefore(next.lastChild, node.firstChild); - } else { - node.appendChild(next.firstChild); - } - } - domUtils.remove(next); - } - } - !ignorePre && merge('previousSibling', 'firstChild', node); - !ignoreNext && merge('nextSibling', 'lastChild', node); - }, - - /** - * 设置节点node及其子节点不会被选中 - * @method unSelectable - * @param { Element } node 需要执行操作的dom元素 - * @remind 执行该操作后的节点, 将不能被鼠标选中 - * @example - * ```javascript - * UE.dom.domUtils.unSelectable( document.body ); - * ``` - */ - unSelectable:ie && browser.ie9below || browser.opera ? function (node) { - //for ie9 - node.onselectstart = function () { - return false; - }; - node.onclick = node.onkeyup = node.onkeydown = function () { - return false; - }; - node.unselectable = 'on'; - node.setAttribute("unselectable", "on"); - for (var i = 0, ci; ci = node.all[i++];) { - switch (ci.tagName.toLowerCase()) { - case 'iframe' : - case 'textarea' : - case 'input' : - case 'select' : - break; - default : - ci.unselectable = 'on'; - node.setAttribute("unselectable", "on"); - } - } - } : function (node) { - node.style.MozUserSelect = - node.style.webkitUserSelect = - node.style.msUserSelect = - node.style.KhtmlUserSelect = 'none'; - }, - /** - * 删除节点node上的指定属性名称的属性 - * @method removeAttributes - * @param { Node } node 需要删除属性的节点对象 - * @param { String } attrNames 可以是空格隔开的多个属性名称,该操作将会依次删除相应的属性 - * @example - * ```html - *
    - * xxxxx - *
    - * - * - * ``` - */ - - /** - * 删除节点node上的指定属性名称的属性 - * @method removeAttributes - * @param { Node } node 需要删除属性的节点对象 - * @param { Array } attrNames 需要删除的属性名数组 - * @example - * ```html - *
    - * xxxxx - *
    - * - * - * ``` - */ - removeAttributes:function (node, attrNames) { - attrNames = utils.isArray(attrNames) ? attrNames : utils.trim(attrNames).replace(/[ ]{2,}/g,' ').split(' '); - for (var i = 0, ci; ci = attrNames[i++];) { - ci = attrFix[ci] || ci; - switch (ci) { - case 'className': - node[ci] = ''; - break; - case 'style': - node.style.cssText = ''; - var val = node.getAttributeNode('style'); - !browser.ie && val && node.removeAttributeNode(val); - } - node.removeAttribute(ci); - } - }, - /** - * 在doc下创建一个标签名为tag,属性为attrs的元素 - * @method createElement - * @param { DomDocument } doc 新创建的元素属于该document节点创建 - * @param { String } tagName 需要创建的元素的标签名 - * @param { Object } attrs 新创建的元素的属性key-value集合 - * @return { Element } 新创建的元素对象 - * @example - * ```javascript - * var ele = UE.dom.domUtils.createElement( document, 'div', { - * id: 'test' - * } ); - * - * //output: DIV - * console.log( ele.tagName ); - * - * //output: test - * console.log( ele.id ); - * - * ``` - */ - createElement:function (doc, tag, attrs) { - return domUtils.setAttributes(doc.createElement(tag), attrs) - }, - /** - * 为节点node添加属性attrs,attrs为属性键值对 - * @method setAttributes - * @param { Element } node 需要设置属性的元素对象 - * @param { Object } attrs 需要设置的属性名-值对 - * @return { Element } 设置属性的元素对象 - * @example - * ```html - * - * - * - * - */ - setAttributes:function (node, attrs) { - for (var attr in attrs) { - if(attrs.hasOwnProperty(attr)){ - var value = attrs[attr]; - switch (attr) { - case 'class': - //ie下要这样赋值,setAttribute不起作用 - node.className = value; - break; - case 'style' : - node.style.cssText = node.style.cssText + ";" + value; - break; - case 'innerHTML': - node[attr] = value; - break; - case 'value': - node.value = value; - break; - default: - node.setAttribute(attrFix[attr] || attr, value); - } - } - } - return node; - }, - - /** - * 获取元素element经过计算后的样式值 - * @method getComputedStyle - * @param { Element } element 需要获取样式的元素对象 - * @param { String } styleName 需要获取的样式名 - * @return { String } 获取到的样式值 - * @example - * ```html - * - * - * - * - * - * ``` - */ - getComputedStyle:function (element, styleName) { - //一下的属性单独处理 - var pros = 'width height top left'; - - if(pros.indexOf(styleName) > -1){ - return element['offset' + styleName.replace(/^\w/,function(s){return s.toUpperCase()})] + 'px'; - } - //忽略文本节点 - if (element.nodeType == 3) { - element = element.parentNode; - } - //ie下font-size若body下定义了font-size,则从currentStyle里会取到这个font-size. 取不到实际值,故此修改. - if (browser.ie && browser.version < 9 && styleName == 'font-size' && !element.style.fontSize && - !dtd.$empty[element.tagName] && !dtd.$nonChild[element.tagName]) { - var span = element.ownerDocument.createElement('span'); - span.style.cssText = 'padding:0;border:0;font-family:simsun;'; - span.innerHTML = '.'; - element.appendChild(span); - var result = span.offsetHeight; - element.removeChild(span); - span = null; - return result + 'px'; - } - try { - var value = domUtils.getStyle(element, styleName) || - (window.getComputedStyle ? domUtils.getWindow(element).getComputedStyle(element, '').getPropertyValue(styleName) : - ( element.currentStyle || element.style )[utils.cssStyleToDomStyle(styleName)]); - - } catch (e) { - return ""; - } - return utils.transUnitToPx(utils.fixColor(styleName, value)); - }, - /** - * 删除元素element指定的className - * @method removeClasses - * @param { Element } ele 需要删除class的元素节点 - * @param { String } classNames 需要删除的className, 多个className之间以空格分开 - * @example - * ```html - * xxx - * - * - * ``` - */ - - /** - * 删除元素element指定的className - * @method removeClasses - * @param { Element } ele 需要删除class的元素节点 - * @param { Array } classNames 需要删除的className数组 - * @example - * ```html - * xxx - * - * - * ``` - */ - removeClasses:function (elm, classNames) { - classNames = utils.isArray(classNames) ? classNames : - utils.trim(classNames).replace(/[ ]{2,}/g,' ').split(' '); - for(var i = 0,ci,cls = elm.className;ci=classNames[i++];){ - cls = cls.replace(new RegExp('\\b' + ci + '\\b'),'') - } - cls = utils.trim(cls).replace(/[ ]{2,}/g,' '); - if(cls){ - elm.className = cls; - }else{ - domUtils.removeAttributes(elm,['class']); - } - }, - /** - * 给元素element添加className - * @method addClass - * @param { Node } ele 需要增加className的元素 - * @param { String } classNames 需要添加的className, 多个className之间以空格分割 - * @remind 相同的类名不会被重复添加 - * @example - * ```html - * - * - * - * ``` - */ - - /** - * 判断元素element是否包含给定的样式类名className - * @method hasClass - * @param { Node } ele 需要检测的元素 - * @param { Array } classNames 需要检测的className数组 - * @return { Boolean } 元素是否包含所有给定的className - * @example - * ```html - * - * - * - * ``` - */ - hasClass:function (element, className) { - if(utils.isRegExp(className)){ - return className.test(element.className) - } - className = utils.trim(className).replace(/[ ]{2,}/g,' ').split(' '); - for(var i = 0,ci,cls = element.className;ci=className[i++];){ - if(!new RegExp('\\b' + ci + '\\b','i').test(cls)){ - return false; - } - } - return i - 1 == className.length; - }, - - /** - * 阻止事件默认行为 - * @method preventDefault - * @param { Event } evt 需要阻止默认行为的事件对象 - * @example - * ```javascript - * UE.dom.domUtils.preventDefault( evt ); - * ``` - */ - preventDefault:function (evt) { - evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false); - }, - /** - * 删除元素element指定的样式 - * @method removeStyle - * @param { Element } element 需要删除样式的元素 - * @param { String } styleName 需要删除的样式名 - * @example - * ```html - * - * - * - * ``` - */ - removeStyle:function (element, name) { - if(browser.ie ){ - //针对color先单独处理一下 - if(name == 'color'){ - name = '(^|;)' + name; - } - element.style.cssText = element.style.cssText.replace(new RegExp(name + '[^:]*:[^;]+;?','ig'),'') - }else{ - if (element.style.removeProperty) { - element.style.removeProperty (name); - }else { - element.style.removeAttribute (utils.cssStyleToDomStyle(name)); - } - } - - - if (!element.style.cssText) { - domUtils.removeAttributes(element, ['style']); - } - }, - /** - * 获取元素element的style属性的指定值 - * @method getStyle - * @param { Element } element 需要获取属性值的元素 - * @param { String } styleName 需要获取的style的名称 - * @warning 该方法仅获取元素style属性中所标明的值 - * @return { String } 该元素包含指定的style属性值 - * @example - * ```html - *
    - * - * - * ``` - */ - getStyle:function (element, name) { - var value = element.style[ utils.cssStyleToDomStyle(name) ]; - return utils.fixColor(name, value); - }, - /** - * 为元素element设置样式属性值 - * @method setStyle - * @param { Element } element 需要设置样式的元素 - * @param { String } styleName 样式名 - * @param { String } styleValue 样式值 - * @example - * ```html - *
    - * - * - * ``` - */ - setStyle:function (element, name, value) { - element.style[utils.cssStyleToDomStyle(name)] = value; - if(!utils.trim(element.style.cssText)){ - this.removeAttributes(element,'style') - } - }, - /** - * 为元素element设置多个样式属性值 - * @method setStyles - * @param { Element } element 需要设置样式的元素 - * @param { Object } styles 样式名值对 - * @example - * ```html - *
    - * - * - * ``` - */ - setStyles:function (element, styles) { - for (var name in styles) { - if (styles.hasOwnProperty(name)) { - domUtils.setStyle(element, name, styles[name]); - } - } - }, - /** - * 删除_moz_dirty属性 - * @private - * @method removeDirtyAttr - */ - removeDirtyAttr:function (node) { - for (var i = 0, ci, nodes = node.getElementsByTagName('*'); ci = nodes[i++];) { - ci.removeAttribute('_moz_dirty'); - } - node.removeAttribute('_moz_dirty'); - }, - /** - * 获取子节点的数量 - * @method getChildCount - * @param { Element } node 需要检测的元素 - * @return { Number } 给定的node元素的子节点数量 - * @example - * ```html - *
    - * - *
    - * - * - * ``` - */ - - /** - * 根据给定的过滤规则, 获取符合条件的子节点的数量 - * @method getChildCount - * @param { Element } node 需要检测的元素 - * @param { Function } fn 过滤器, 要求对符合条件的子节点返回true, 反之则要求返回false - * @return { Number } 符合过滤条件的node元素的子节点数量 - * @example - * ```html - *
    - * - *
    - * - * - * ``` - */ - getChildCount:function (node, fn) { - var count = 0, first = node.firstChild; - fn = fn || function () { - return 1; - }; - while (first) { - if (fn(first)) { - count++; - } - first = first.nextSibling; - } - return count; - }, - - /** - * 判断给定节点是否为空节点 - * @method isEmptyNode - * @param { Node } node 需要检测的节点对象 - * @return { Boolean } 节点是否为空 - * @example - * ```javascript - * UE.dom.domUtils.isEmptyNode( document.body ); - * ``` - */ - isEmptyNode:function (node) { - return !node.firstChild || domUtils.getChildCount(node, function (node) { - return !domUtils.isBr(node) && !domUtils.isBookmarkNode(node) && !domUtils.isWhitespace(node) - }) == 0 - }, - clearSelectedArr:function (nodes) { - var node; - while (node = nodes.pop()) { - domUtils.removeAttributes(node, ['class']); - } - }, - /** - * 将显示区域滚动到指定节点的位置 - * @method scrollToView - * @param {Node} node 节点 - * @param {window} win window对象 - * @param {Number} offsetTop 距离上方的偏移量 - */ - scrollToView:function (node, win, offsetTop) { - var getViewPaneSize = function () { - var doc = win.document, - mode = doc.compatMode == 'CSS1Compat'; - return { - width:( mode ? doc.documentElement.clientWidth : doc.body.clientWidth ) || 0, - height:( mode ? doc.documentElement.clientHeight : doc.body.clientHeight ) || 0 - }; - }, - getScrollPosition = function (win) { - if ('pageXOffset' in win) { - return { - x:win.pageXOffset || 0, - y:win.pageYOffset || 0 - }; - } - else { - var doc = win.document; - return { - x:doc.documentElement.scrollLeft || doc.body.scrollLeft || 0, - y:doc.documentElement.scrollTop || doc.body.scrollTop || 0 - }; - } - }; - var winHeight = getViewPaneSize().height, offset = winHeight * -1 + offsetTop; - offset += (node.offsetHeight || 0); - var elementPosition = domUtils.getXY(node); - offset += elementPosition.y; - var currentScroll = getScrollPosition(win).y; - // offset += 50; - if (offset > currentScroll || offset < currentScroll - winHeight) { - win.scrollTo(0, offset + (offset < 0 ? -20 : 20)); - } - }, - /** - * 判断给定节点是否为br - * @method isBr - * @param { Node } node 需要判断的节点对象 - * @return { Boolean } 给定的节点是否是br节点 - */ - isBr:function (node) { - return node.nodeType == 1 && node.tagName == 'BR'; - }, - /** - * 判断给定的节点是否是一个“填充”节点 - * @private - * @method isFillChar - * @param { Node } node 需要判断的节点 - * @param { Boolean } isInStart 是否从节点内容的开始位置匹配 - * @returns { Boolean } 节点是否是填充节点 - */ - isFillChar:function (node,isInStart) { - if(node.nodeType != 3) - return false; - var text = node.nodeValue; - if(isInStart){ - return new RegExp('^' + domUtils.fillChar).test(text) - } - return !text.replace(new RegExp(domUtils.fillChar,'g'), '').length - }, - isStartInblock:function (range) { - var tmpRange = range.cloneRange(), - flag = 0, - start = tmpRange.startContainer, - tmp; - if(start.nodeType == 1 && start.childNodes[tmpRange.startOffset]){ - start = start.childNodes[tmpRange.startOffset]; - var pre = start.previousSibling; - while(pre && domUtils.isFillChar(pre)){ - start = pre; - pre = pre.previousSibling; - } - } - if(this.isFillChar(start,true) && tmpRange.startOffset == 1){ - tmpRange.setStartBefore(start); - start = tmpRange.startContainer; - } - - while (start && domUtils.isFillChar(start)) { - tmp = start; - start = start.previousSibling - } - if (tmp) { - tmpRange.setStartBefore(tmp); - start = tmpRange.startContainer; - } - if (start.nodeType == 1 && domUtils.isEmptyNode(start) && tmpRange.startOffset == 1) { - tmpRange.setStart(start, 0).collapse(true); - } - while (!tmpRange.startOffset) { - start = tmpRange.startContainer; - if (domUtils.isBlockElm(start) || domUtils.isBody(start)) { - flag = 1; - break; - } - var pre = tmpRange.startContainer.previousSibling, - tmpNode; - if (!pre) { - tmpRange.setStartBefore(tmpRange.startContainer); - } else { - while (pre && domUtils.isFillChar(pre)) { - tmpNode = pre; - pre = pre.previousSibling; - } - if (tmpNode) { - tmpRange.setStartBefore(tmpNode); - } else { - tmpRange.setStartBefore(tmpRange.startContainer); - } - } - } - return flag && !domUtils.isBody(tmpRange.startContainer) ? 1 : 0; - }, - - /** - * 判断给定的元素是否是一个空元素 - * @method isEmptyBlock - * @param { Element } node 需要判断的元素 - * @return { Boolean } 是否是空元素 - * @example - * ```html - *
    - * - * - * ``` - */ - - /** - * 根据指定的判断规则判断给定的元素是否是一个空元素 - * @method isEmptyBlock - * @param { Element } node 需要判断的元素 - * @param { RegExp } reg 对内容执行判断的正则表达式对象 - * @return { Boolean } 是否是空元素 - */ - isEmptyBlock:function (node,reg) { - if(node.nodeType != 1) - return 0; - reg = reg || new RegExp('[ \xa0\t\r\n' + domUtils.fillChar + ']', 'g'); - - if (node[browser.ie ? 'innerText' : 'textContent'].replace(reg, '').length > 0) { - return 0; - } - for (var n in dtd.$isNotEmpty) { - if (node.getElementsByTagName(n).length) { - return 0; - } - } - return 1; - }, - - /** - * 移动元素使得该元素的位置移动指定的偏移量的距离 - * @method setViewportOffset - * @param { Element } element 需要设置偏移量的元素 - * @param { Object } offset 偏移量, 形如{ left: 100, top: 50 }的一个键值对, 表示该元素将在 - * 现有的位置上向水平方向偏移offset.left的距离, 在竖直方向上偏移 - * offset.top的距离 - * @example - * ```html - *
    - * - * - * ``` - */ - setViewportOffset:function (element, offset) { - var left = parseInt(element.style.left) | 0; - var top = parseInt(element.style.top) | 0; - var rect = element.getBoundingClientRect(); - var offsetLeft = offset.left - rect.left; - var offsetTop = offset.top - rect.top; - if (offsetLeft) { - element.style.left = left + offsetLeft + 'px'; - } - if (offsetTop) { - element.style.top = top + offsetTop + 'px'; - } - }, - - /** - * 用“填充字符”填充节点 - * @method fillNode - * @private - * @param { DomDocument } doc 填充的节点所在的docment对象 - * @param { Node } node 需要填充的节点对象 - * @example - * ```html - *
    - * - * - * ``` - */ - fillNode:function (doc, node) { - var tmpNode = browser.ie ? doc.createTextNode(domUtils.fillChar) : doc.createElement('br'); - node.innerHTML = ''; - node.appendChild(tmpNode); - }, - - /** - * 把节点src的所有子节点追加到另一个节点tag上去 - * @method moveChild - * @param { Node } src 源节点, 该节点下的所有子节点将被移除 - * @param { Node } tag 目标节点, 从源节点移除的子节点将被追加到该节点下 - * @example - * ```html - *
    - * - *
    - *
    - *
    - *
    - * - * - * ``` - */ - - /** - * 把节点src的所有子节点移动到另一个节点tag上去, 可以通过dir参数控制附加的行为是“追加”还是“插入顶部” - * @method moveChild - * @param { Node } src 源节点, 该节点下的所有子节点将被移除 - * @param { Node } tag 目标节点, 从源节点移除的子节点将被附加到该节点下 - * @param { Boolean } dir 附加方式, 如果为true, 则附加进去的节点将被放到目标节点的顶部, 反之,则放到末尾 - * @example - * ```html - *
    - * - *
    - *
    - *
    - *
    - * - * - * ``` - */ - moveChild:function (src, tag, dir) { - while (src.firstChild) { - if (dir && tag.firstChild) { - tag.insertBefore(src.lastChild, tag.firstChild); - } else { - tag.appendChild(src.firstChild); - } - } - }, - - /** - * 判断节点的标签上是否不存在任何属性 - * @method hasNoAttributes - * @private - * @param { Node } node 需要检测的节点对象 - * @return { Boolean } 节点是否不包含任何属性 - * @example - * ```html - *
    xxxx
    - * - * - * ``` - */ - hasNoAttributes:function (node) { - return browser.ie ? /^<\w+\s*?>/.test(node.outerHTML) : node.attributes.length == 0; - }, - - /** - * 检测节点是否是UEditor所使用的辅助节点 - * @method isCustomeNode - * @private - * @param { Node } node 需要检测的节点 - * @remind 辅助节点是指编辑器要完成工作临时添加的节点, 在输出的时候将会从编辑器内移除, 不会影响最终的结果。 - * @return { Boolean } 给定的节点是否是一个辅助节点 - */ - isCustomeNode:function (node) { - return node.nodeType == 1 && node.getAttribute('_ue_custom_node_'); - }, - - /** - * 检测节点的标签是否是给定的标签 - * @method isTagNode - * @param { Node } node 需要检测的节点对象 - * @param { String } tagName 标签 - * @return { Boolean } 节点的标签是否是给定的标签 - * @example - * ```html - *
    - * - * - * ``` - */ - isTagNode:function (node, tagNames) { - return node.nodeType == 1 && new RegExp('\\b' + node.tagName + '\\b','i').test(tagNames) - }, - - /** - * 给定一个节点数组,在通过指定的过滤器过滤后, 获取其中满足过滤条件的第一个节点 - * @method filterNodeList - * @param { Array } nodeList 需要过滤的节点数组 - * @param { Function } fn 过滤器, 对符合条件的节点, 执行结果返回true, 反之则返回false - * @return { Node | NULL } 如果找到符合过滤条件的节点, 则返回该节点, 否则返回NULL - * @example - * ```javascript - * var divNodes = document.getElementsByTagName("div"); - * divNodes = [].slice.call( divNodes, 0 ); - * - * //output: null - * console.log( UE.dom.domUtils.filterNodeList( divNodes, function ( node ) { - * return node.tagName.toLowerCase() !== 'div'; - * } ) ); - * ``` - */ - - /** - * 给定一个节点数组nodeList和一组标签名tagNames, 获取其中能够匹配标签名的节点集合中的第一个节点 - * @method filterNodeList - * @param { Array } nodeList 需要过滤的节点数组 - * @param { String } tagNames 需要匹配的标签名, 多个标签名之间用空格分割 - * @return { Node | NULL } 如果找到标签名匹配的节点, 则返回该节点, 否则返回NULL - * @example - * ```javascript - * var divNodes = document.getElementsByTagName("div"); - * divNodes = [].slice.call( divNodes, 0 ); - * - * //output: null - * console.log( UE.dom.domUtils.filterNodeList( divNodes, 'a span' ) ); - * ``` - */ - - /** - * 给定一个节点数组,在通过指定的过滤器过滤后, 如果参数forAll为true, 则会返回所有满足过滤 - * 条件的节点集合, 否则, 返回满足条件的节点集合中的第一个节点 - * @method filterNodeList - * @param { Array } nodeList 需要过滤的节点数组 - * @param { Function } fn 过滤器, 对符合条件的节点, 执行结果返回true, 反之则返回false - * @param { Boolean } forAll 是否返回整个节点数组, 如果该参数为false, 则返回节点集合中的第一个节点 - * @return { Array | Node | NULL } 如果找到符合过滤条件的节点, 则根据参数forAll的值决定返回满足 - * 过滤条件的节点数组或第一个节点, 否则返回NULL - * @example - * ```javascript - * var divNodes = document.getElementsByTagName("div"); - * divNodes = [].slice.call( divNodes, 0 ); - * - * //output: 3(假定有3个div) - * console.log( divNodes.length ); - * - * var nodes = UE.dom.domUtils.filterNodeList( divNodes, function ( node ) { - * return node.tagName.toLowerCase() === 'div'; - * }, true ); - * - * //output: 3 - * console.log( nodes.length ); - * - * var node = UE.dom.domUtils.filterNodeList( divNodes, function ( node ) { - * return node.tagName.toLowerCase() === 'div'; - * }, false ); - * - * //output: div - * console.log( node.nodeName ); - * ``` - */ - filterNodeList : function(nodelist,filter,forAll){ - var results = []; - if(!utils .isFunction(filter)){ - var str = filter; - filter = function(n){ - return utils.indexOf(utils.isArray(str) ? str:str.split(' '), n.tagName.toLowerCase()) != -1 - }; - } - utils.each(nodelist,function(n){ - filter(n) && results.push(n) - }); - return results.length == 0 ? null : results.length == 1 || !forAll ? results[0] : results - }, - - /** - * 查询给定的range选区是否在给定的node节点内,且在该节点的最末尾 - * @method isInNodeEndBoundary - * @param { UE.dom.Range } rng 需要判断的range对象, 该对象的startContainer不能为NULL - * @param node 需要检测的节点对象 - * @return { Number } 如果给定的选取range对象是在node内部的最末端, 则返回1, 否则返回0 - */ - isInNodeEndBoundary : function (rng,node){ - var start = rng.startContainer; - if(start.nodeType == 3 && rng.startOffset != start.nodeValue.length){ - return 0; - } - if(start.nodeType == 1 && rng.startOffset != start.childNodes.length){ - return 0; - } - while(start !== node){ - if(start.nextSibling){ - return 0 - }; - start = start.parentNode; - } - return 1; - }, - isBoundaryNode : function (node,dir){ - var tmp; - while(!domUtils.isBody(node)){ - tmp = node; - node = node.parentNode; - if(tmp !== node[dir]){ - return false; - } - } - return true; - }, - fillHtml : browser.ie11below ? ' ' : '
    ' -}; -var fillCharReg = new RegExp(domUtils.fillChar, 'g'); - -// core/Range.js -/** - * Range封装 - * @file - * @module UE.dom - * @class Range - * @since 1.2.6.1 - */ - -/** - * dom操作封装 - * @unfile - * @module UE.dom - */ - -/** - * Range实现类,本类是UEditor底层核心类,封装不同浏览器之间的Range操作。 - * @unfile - * @module UE.dom - * @class Range - */ - - -(function () { - var guid = 0, - fillChar = domUtils.fillChar, - fillData; - - /** - * 更新range的collapse状态 - * @param {Range} range range对象 - */ - function updateCollapse(range) { - range.collapsed = - range.startContainer && range.endContainer && - range.startContainer === range.endContainer && - range.startOffset == range.endOffset; - } - - function selectOneNode(rng){ - return !rng.collapsed && rng.startContainer.nodeType == 1 && rng.startContainer === rng.endContainer && rng.endOffset - rng.startOffset == 1 - } - function setEndPoint(toStart, node, offset, range) { - //如果node是自闭合标签要处理 - if (node.nodeType == 1 && (dtd.$empty[node.tagName] || dtd.$nonChild[node.tagName])) { - offset = domUtils.getNodeIndex(node) + (toStart ? 0 : 1); - node = node.parentNode; - } - if (toStart) { - range.startContainer = node; - range.startOffset = offset; - if (!range.endContainer) { - range.collapse(true); - } - } else { - range.endContainer = node; - range.endOffset = offset; - if (!range.startContainer) { - range.collapse(false); - } - } - updateCollapse(range); - return range; - } - - function execContentsAction(range, action) { - //调整边界 - //range.includeBookmark(); - var start = range.startContainer, - end = range.endContainer, - startOffset = range.startOffset, - endOffset = range.endOffset, - doc = range.document, - frag = doc.createDocumentFragment(), - tmpStart, tmpEnd; - if (start.nodeType == 1) { - start = start.childNodes[startOffset] || (tmpStart = start.appendChild(doc.createTextNode(''))); - } - if (end.nodeType == 1) { - end = end.childNodes[endOffset] || (tmpEnd = end.appendChild(doc.createTextNode(''))); - } - if (start === end && start.nodeType == 3) { - frag.appendChild(doc.createTextNode(start.substringData(startOffset, endOffset - startOffset))); - //is not clone - if (action) { - start.deleteData(startOffset, endOffset - startOffset); - range.collapse(true); - } - return frag; - } - var current, currentLevel, clone = frag, - startParents = domUtils.findParents(start, true), endParents = domUtils.findParents(end, true); - for (var i = 0; startParents[i] == endParents[i];) { - i++; - } - for (var j = i, si; si = startParents[j]; j++) { - current = si.nextSibling; - if (si == start) { - if (!tmpStart) { - if (range.startContainer.nodeType == 3) { - clone.appendChild(doc.createTextNode(start.nodeValue.slice(startOffset))); - //is not clone - if (action) { - start.deleteData(startOffset, start.nodeValue.length - startOffset); - } - } else { - clone.appendChild(!action ? start.cloneNode(true) : start); - } - } - } else { - currentLevel = si.cloneNode(false); - clone.appendChild(currentLevel); - } - while (current) { - if (current === end || current === endParents[j]) { - break; - } - si = current.nextSibling; - clone.appendChild(!action ? current.cloneNode(true) : current); - current = si; - } - clone = currentLevel; - } - clone = frag; - if (!startParents[i]) { - clone.appendChild(startParents[i - 1].cloneNode(false)); - clone = clone.firstChild; - } - for (var j = i, ei; ei = endParents[j]; j++) { - current = ei.previousSibling; - if (ei == end) { - if (!tmpEnd && range.endContainer.nodeType == 3) { - clone.appendChild(doc.createTextNode(end.substringData(0, endOffset))); - //is not clone - if (action) { - end.deleteData(0, endOffset); - } - } - } else { - currentLevel = ei.cloneNode(false); - clone.appendChild(currentLevel); - } - //如果两端同级,右边第一次已经被开始做了 - if (j != i || !startParents[i]) { - while (current) { - if (current === start) { - break; - } - ei = current.previousSibling; - clone.insertBefore(!action ? current.cloneNode(true) : current, clone.firstChild); - current = ei; - } - } - clone = currentLevel; - } - if (action) { - range.setStartBefore(!endParents[i] ? endParents[i - 1] : !startParents[i] ? startParents[i - 1] : endParents[i]).collapse(true); - } - tmpStart && domUtils.remove(tmpStart); - tmpEnd && domUtils.remove(tmpEnd); - return frag; - } - - /** - * 创建一个跟document绑定的空的Range实例 - * @constructor - * @param { Document } document 新建的选区所属的文档对象 - */ - - /** - * @property { Node } startContainer 当前Range的开始边界的容器节点, 可以是一个元素节点或者是文本节点 - */ - - /** - * @property { Node } startOffset 当前Range的开始边界容器节点的偏移量, 如果是元素节点, - * 该值就是childNodes中的第几个节点, 如果是文本节点就是文本内容的第几个字符 - */ - - /** - * @property { Node } endContainer 当前Range的结束边界的容器节点, 可以是一个元素节点或者是文本节点 - */ - - /** - * @property { Node } endOffset 当前Range的结束边界容器节点的偏移量, 如果是元素节点, - * 该值就是childNodes中的第几个节点, 如果是文本节点就是文本内容的第几个字符 - */ - - /** - * @property { Boolean } collapsed 当前Range是否闭合 - * @default true - * @remind Range是闭合的时候, startContainer === endContainer && startOffset === endOffset - */ - - /** - * @property { Document } document 当前Range所属的Document对象 - * @remind 不同range的的document属性可以是不同的 - */ - var Range = dom.Range = function (document) { - var me = this; - me.startContainer = - me.startOffset = - me.endContainer = - me.endOffset = null; - me.document = document; - me.collapsed = true; - }; - - /** - * 删除fillData - * @param doc - * @param excludeNode - */ - function removeFillData(doc, excludeNode) { - try { - if (fillData && domUtils.inDoc(fillData, doc)) { - if (!fillData.nodeValue.replace(fillCharReg, '').length) { - var tmpNode = fillData.parentNode; - domUtils.remove(fillData); - while (tmpNode && domUtils.isEmptyInlineElement(tmpNode) && - //safari的contains有bug - (browser.safari ? !(domUtils.getPosition(tmpNode,excludeNode) & domUtils.POSITION_CONTAINS) : !tmpNode.contains(excludeNode)) - ) { - fillData = tmpNode.parentNode; - domUtils.remove(tmpNode); - tmpNode = fillData; - } - } else { - fillData.nodeValue = fillData.nodeValue.replace(fillCharReg, ''); - } - } - } catch (e) { - } - } - - /** - * @param node - * @param dir - */ - function mergeSibling(node, dir) { - var tmpNode; - node = node[dir]; - while (node && domUtils.isFillChar(node)) { - tmpNode = node[dir]; - domUtils.remove(node); - node = tmpNode; - } - } - - Range.prototype = { - - /** - * 克隆选区的内容到一个DocumentFragment里 - * @method cloneContents - * @return { DocumentFragment | NULL } 如果选区是闭合的将返回null, 否则, 返回包含所clone内容的DocumentFragment元素 - * @example - * ```html - * - * - * xx[xxx]x - * - * - * - * ``` - */ - cloneContents:function () { - return this.collapsed ? null : execContentsAction(this, 0); - }, - - /** - * 删除当前选区范围中的所有内容 - * @method deleteContents - * @remind 执行完该操作后, 当前Range对象变成了闭合状态 - * @return { UE.dom.Range } 当前操作的Range对象 - * @example - * ```html - * - * - * xx[xxx]x - * - * - * - * ``` - */ - deleteContents:function () { - var txt; - if (!this.collapsed) { - execContentsAction(this, 1); - } - if (browser.webkit) { - txt = this.startContainer; - if (txt.nodeType == 3 && !txt.nodeValue.length) { - this.setStartBefore(txt).collapse(true); - domUtils.remove(txt); - } - } - return this; - }, - - /** - * 将当前选区的内容提取到一个DocumentFragment里 - * @method extractContents - * @remind 执行该操作后, 选区将变成闭合状态 - * @warning 执行该操作后, 原来选区所选中的内容将从dom树上剥离出来 - * @return { DocumentFragment } 返回包含所提取内容的DocumentFragment对象 - * @example - * ```html - * - * - * xx[xxx]x - * - * - * - */ - extractContents:function () { - return this.collapsed ? null : execContentsAction(this, 2); - }, - - /** - * 设置Range的开始容器节点和偏移量 - * @method setStart - * @remind 如果给定的节点是元素节点,那么offset指的是其子元素中索引为offset的元素, - * 如果是文本节点,那么offset指的是其文本内容的第offset个字符 - * @remind 如果提供的容器节点是一个不能包含子元素的节点, 则该选区的开始容器将被设置 - * 为该节点的父节点, 此时, 其距离开始容器的偏移量也变成了该节点在其父节点 - * 中的索引 - * @param { Node } node 将被设为当前选区开始边界容器的节点对象 - * @param { int } offset 选区的开始位置偏移量 - * @return { UE.dom.Range } 当前range对象 - * @example - * ```html - * - * xxxxxxxxxxxxx[xxx] - * - * - * ``` - * @example - * ```html - * - * xxx[xx]x - * - * - * ``` - */ - setStart:function (node, offset) { - return setEndPoint(true, node, offset, this); - }, - - /** - * 设置Range的结束容器和偏移量 - * @method setEnd - * @param { Node } node 作为当前选区结束边界容器的节点对象 - * @param { int } offset 结束边界的偏移量 - * @see UE.dom.Range:setStart(Node,int) - * @return { UE.dom.Range } 当前range对象 - */ - setEnd:function (node, offset) { - return setEndPoint(false, node, offset, this); - }, - - /** - * 将Range开始位置设置到node节点之后 - * @method setStartAfter - * @remind 该操作将会把给定节点的父节点作为range的开始容器, 且偏移量是该节点在其父节点中的位置索引+1 - * @param { Node } node 选区的开始边界将紧接着该节点之后 - * @return { UE.dom.Range } 当前range对象 - * @example - * ```html - * - * xxxxxxx[xxxx] - * - * - * ``` - */ - setStartAfter:function (node) { - return this.setStart(node.parentNode, domUtils.getNodeIndex(node) + 1); - }, - - /** - * 将Range开始位置设置到node节点之前 - * @method setStartBefore - * @remind 该操作将会把给定节点的父节点作为range的开始容器, 且偏移量是该节点在其父节点中的位置索引 - * @param { Node } node 新的选区开始位置在该节点之前 - * @see UE.dom.Range:setStartAfter(Node) - * @return { UE.dom.Range } 当前range对象 - */ - setStartBefore:function (node) { - return this.setStart(node.parentNode, domUtils.getNodeIndex(node)); - }, - - /** - * 将Range结束位置设置到node节点之后 - * @method setEndAfter - * @remind 该操作将会把给定节点的父节点作为range的结束容器, 且偏移量是该节点在其父节点中的位置索引+1 - * @param { Node } node 目标节点 - * @see UE.dom.Range:setStartAfter(Node) - * @return { UE.dom.Range } 当前range对象 - * @example - * ```html - * - * [xxxxxxx]xxxx - * - * - * ``` - */ - setEndAfter:function (node) { - return this.setEnd(node.parentNode, domUtils.getNodeIndex(node) + 1); - }, - - /** - * 将Range结束位置设置到node节点之前 - * @method setEndBefore - * @remind 该操作将会把给定节点的父节点作为range的结束容器, 且偏移量是该节点在其父节点中的位置索引 - * @param { Node } node 目标节点 - * @see UE.dom.Range:setEndAfter(Node) - * @return { UE.dom.Range } 当前range对象 - */ - setEndBefore:function (node) { - return this.setEnd(node.parentNode, domUtils.getNodeIndex(node)); - }, - - /** - * 设置Range的开始位置到node节点内的第一个子节点之前 - * @method setStartAtFirst - * @remind 选区的开始容器将变成给定的节点, 且偏移量为0 - * @remind 如果给定的节点是元素节点, 则该节点必须是允许包含子节点的元素。 - * @param { Node } node 目标节点 - * @see UE.dom.Range:setStartBefore(Node) - * @return { UE.dom.Range } 当前range对象 - * @example - * ```html - * - * xxxxx[xx]xxxx - * - * - * ``` - */ - setStartAtFirst:function (node) { - return this.setStart(node, 0); - }, - - /** - * 设置Range的开始位置到node节点内的最后一个节点之后 - * @method setStartAtLast - * @remind 选区的开始容器将变成给定的节点, 且偏移量为该节点的子节点数 - * @remind 如果给定的节点是元素节点, 则该节点必须是允许包含子节点的元素。 - * @param { Node } node 目标节点 - * @see UE.dom.Range:setStartAtFirst(Node) - * @return { UE.dom.Range } 当前range对象 - */ - setStartAtLast:function (node) { - return this.setStart(node, node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length); - }, - - /** - * 设置Range的结束位置到node节点内的第一个节点之前 - * @method setEndAtFirst - * @param { Node } node 目标节点 - * @remind 选区的结束容器将变成给定的节点, 且偏移量为0 - * @remind node必须是一个元素节点, 且必须是允许包含子节点的元素。 - * @see UE.dom.Range:setStartAtFirst(Node) - * @return { UE.dom.Range } 当前range对象 - */ - setEndAtFirst:function (node) { - return this.setEnd(node, 0); - }, - - /** - * 设置Range的结束位置到node节点内的最后一个节点之后 - * @method setEndAtLast - * @param { Node } node 目标节点 - * @remind 选区的结束容器将变成给定的节点, 且偏移量为该节点的子节点数量 - * @remind node必须是一个元素节点, 且必须是允许包含子节点的元素。 - * @see UE.dom.Range:setStartAtFirst(Node) - * @return { UE.dom.Range } 当前range对象 - */ - setEndAtLast:function (node) { - return this.setEnd(node, node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length); - }, - - /** - * 选中给定节点 - * @method selectNode - * @remind 此时, 选区的开始容器和结束容器都是该节点的父节点, 其startOffset是该节点在父节点中的位置索引, - * 而endOffset为startOffset+1 - * @param { Node } node 需要选中的节点 - * @return { UE.dom.Range } 当前range对象,此时的range仅包含当前给定的节点对象 - * @example - * ```html - * - * xxxxx[xx]xxxx - * - * - * ``` - */ - selectNode:function (node) { - return this.setStartBefore(node).setEndAfter(node); - }, - - /** - * 选中给定节点内部的所有节点 - * @method selectNodeContents - * @remind 此时, 选区的开始容器和结束容器都是该节点, 其startOffset为0, - * 而endOffset是该节点的子节点数。 - * @param { Node } node 目标节点, 当前range将包含该节点内的所有节点 - * @return { UE.dom.Range } 当前range对象, 此时range仅包含给定节点的所有子节点 - * @example - * ```html - * - * xxxxx[xx]xxxx - * - * - * ``` - */ - selectNodeContents:function (node) { - return this.setStart(node, 0).setEndAtLast(node); - }, - - /** - * clone当前Range对象 - * @method cloneRange - * @remind 返回的range是一个全新的range对象, 其内部所有属性与当前被clone的range相同。 - * @return { UE.dom.Range } 当前range对象的一个副本 - */ - cloneRange:function () { - var me = this; - return new Range(me.document).setStart(me.startContainer, me.startOffset).setEnd(me.endContainer, me.endOffset); - - }, - - /** - * 向当前选区的结束处闭合选区 - * @method collapse - * @return { UE.dom.Range } 当前range对象 - * @example - * ```html - * - * xxxxx[xx]xxxx - * - * - * ``` - */ - - /** - * 闭合当前选区,根据给定的toStart参数项决定是向当前选区开始处闭合还是向结束处闭合, - * 如果toStart的值为true,则向开始位置闭合, 反之,向结束位置闭合。 - * @method collapse - * @param { Boolean } toStart 是否向选区开始处闭合 - * @return { UE.dom.Range } 当前range对象,此时range对象处于闭合状态 - * @see UE.dom.Range:collapse() - * @example - * ```html - * - * xxxxx[xx]xxxx - * - * - * ``` - */ - collapse:function (toStart) { - var me = this; - if (toStart) { - me.endContainer = me.startContainer; - me.endOffset = me.startOffset; - } else { - me.startContainer = me.endContainer; - me.startOffset = me.endOffset; - } - me.collapsed = true; - return me; - }, - - /** - * 调整range的开始位置和结束位置,使其"收缩"到最小的位置 - * @method shrinkBoundary - * @return { UE.dom.Range } 当前range对象 - * @example - * ```html - * xxxx[xxxxx] => xxxx[xxxxx] - * ``` - * - * @example - * ```html - * - * x[xx]xxx - * - * - * ``` - * - * @example - * ```html - * [xxxxxxxxxxx] => [xxxxxxxxxxx] - * ``` - */ - - /** - * 调整range的开始位置和结束位置,使其"收缩"到最小的位置, - * 如果ignoreEnd的值为true,则忽略对结束位置的调整 - * @method shrinkBoundary - * @param { Boolean } ignoreEnd 是否忽略对结束位置的调整 - * @return { UE.dom.Range } 当前range对象 - * @see UE.dom.domUtils.Range:shrinkBoundary() - */ - shrinkBoundary:function (ignoreEnd) { - var me = this, child, - collapsed = me.collapsed; - function check(node){ - return node.nodeType == 1 && !domUtils.isBookmarkNode(node) && !dtd.$empty[node.tagName] && !dtd.$nonChild[node.tagName] - } - while (me.startContainer.nodeType == 1 //是element - && (child = me.startContainer.childNodes[me.startOffset]) //子节点也是element - && check(child)) { - me.setStart(child, 0); - } - if (collapsed) { - return me.collapse(true); - } - if (!ignoreEnd) { - while (me.endContainer.nodeType == 1//是element - && me.endOffset > 0 //如果是空元素就退出 endOffset=0那么endOffst-1为负值,childNodes[endOffset]报错 - && (child = me.endContainer.childNodes[me.endOffset - 1]) //子节点也是element - && check(child)) { - me.setEnd(child, child.childNodes.length); - } - } - return me; - }, - - /** - * 获取离当前选区内包含的所有节点最近的公共祖先节点, - * @method getCommonAncestor - * @remind 返回的公共祖先节点一定不是range自身的容器节点, 但有可能是一个文本节点 - * @return { Node } 当前range对象内所有节点的公共祖先节点 - * @example - * ```html - * //选区示例 - * xxxx[xxx]xxxxxx - * - * ``` - */ - - /** - * 获取当前选区所包含的所有节点的公共祖先节点, 可以根据给定的参数 includeSelf 决定获取到 - * 的公共祖先节点是否可以是当前选区的startContainer或endContainer节点, 如果 includeSelf - * 的取值为true, 则返回的节点可以是自身的容器节点, 否则, 则不能是容器节点 - * @method getCommonAncestor - * @param { Boolean } includeSelf 是否允许获取到的公共祖先节点是当前range对象的容器节点 - * @return { Node } 当前range对象内所有节点的公共祖先节点 - * @see UE.dom.Range:getCommonAncestor() - * @example - * ```html - * - * - * - * xxxxxxxxx[xxx]xxxxxxxx - * - * - * - * - * ``` - */ - - /** - * 获取当前选区所包含的所有节点的公共祖先节点, 可以根据给定的参数 includeSelf 决定获取到 - * 的公共祖先节点是否可以是当前选区的startContainer或endContainer节点, 如果 includeSelf - * 的取值为true, 则返回的节点可以是自身的容器节点, 否则, 则不能是容器节点; 同时可以根据 - * ignoreTextNode 参数的取值决定是否忽略类型为文本节点的祖先节点。 - * @method getCommonAncestor - * @param { Boolean } includeSelf 是否允许获取到的公共祖先节点是当前range对象的容器节点 - * @param { Boolean } ignoreTextNode 获取祖先节点的过程中是否忽略类型为文本节点的祖先节点 - * @return { Node } 当前range对象内所有节点的公共祖先节点 - * @see UE.dom.Range:getCommonAncestor() - * @see UE.dom.Range:getCommonAncestor(Boolean) - * @example - * ```html - * - * - * - * xxxxxxxx[x]xxxxxxxxxxx - * - * - * - * - * ``` - */ - getCommonAncestor:function (includeSelf, ignoreTextNode) { - var me = this, - start = me.startContainer, - end = me.endContainer; - if (start === end) { - if (includeSelf && selectOneNode(this)) { - start = start.childNodes[me.startOffset]; - if(start.nodeType == 1) - return start; - } - //只有在上来就相等的情况下才会出现是文本的情况 - return ignoreTextNode && start.nodeType == 3 ? start.parentNode : start; - } - return domUtils.getCommonAncestor(start, end); - }, - - /** - * 调整当前Range的开始和结束边界容器,如果是容器节点是文本节点,就调整到包含该文本节点的父节点上 - * @method trimBoundary - * @remind 该操作有可能会引起文本节点被切开 - * @return { UE.dom.Range } 当前range对象 - * @example - * ```html - * - * //选区示例 - * xxx[xxxxx]xxx - * - * - * ``` - */ - - /** - * 调整当前Range的开始和结束边界容器,如果是容器节点是文本节点,就调整到包含该文本节点的父节点上, - * 可以根据 ignoreEnd 参数的值决定是否调整对结束边界的调整 - * @method trimBoundary - * @param { Boolean } ignoreEnd 是否忽略对结束边界的调整 - * @return { UE.dom.Range } 当前range对象 - * @example - * ```html - * - * //选区示例 - * xxx[xxxxx]xxx - * - * - * ``` - */ - trimBoundary:function (ignoreEnd) { - this.txtToElmBoundary(); - var start = this.startContainer, - offset = this.startOffset, - collapsed = this.collapsed, - end = this.endContainer; - if (start.nodeType == 3) { - if (offset == 0) { - this.setStartBefore(start); - } else { - if (offset >= start.nodeValue.length) { - this.setStartAfter(start); - } else { - var textNode = domUtils.split(start, offset); - //跟新结束边界 - if (start === end) { - this.setEnd(textNode, this.endOffset - offset); - } else if (start.parentNode === end) { - this.endOffset += 1; - } - this.setStartBefore(textNode); - } - } - if (collapsed) { - return this.collapse(true); - } - } - if (!ignoreEnd) { - offset = this.endOffset; - end = this.endContainer; - if (end.nodeType == 3) { - if (offset == 0) { - this.setEndBefore(end); - } else { - offset < end.nodeValue.length && domUtils.split(end, offset); - this.setEndAfter(end); - } - } - } - return this; - }, - - /** - * 如果选区在文本的边界上,就扩展选区到文本的父节点上, 如果当前选区是闭合的, 则什么也不做 - * @method txtToElmBoundary - * @remind 该操作不会修改dom节点 - * @return { UE.dom.Range } 当前range对象 - */ - - /** - * 如果选区在文本的边界上,就扩展选区到文本的父节点上, 如果当前选区是闭合的, 则根据参数项 - * ignoreCollapsed 的值决定是否执行该调整 - * @method txtToElmBoundary - * @param { Boolean } ignoreCollapsed 是否忽略选区的闭合状态, 如果该参数取值为true, 则 - * 不论选区是否闭合, 都会执行该操作, 反之, 则不会对闭合的选区执行该操作 - * @return { UE.dom.Range } 当前range对象 - */ - txtToElmBoundary:function (ignoreCollapsed) { - function adjust(r, c) { - var container = r[c + 'Container'], - offset = r[c + 'Offset']; - if (container.nodeType == 3) { - if (!offset) { - r['set' + c.replace(/(\w)/, function (a) { - return a.toUpperCase(); - }) + 'Before'](container); - } else if (offset >= container.nodeValue.length) { - r['set' + c.replace(/(\w)/, function (a) { - return a.toUpperCase(); - }) + 'After' ](container); - } - } - } - - if (ignoreCollapsed || !this.collapsed) { - adjust(this, 'start'); - adjust(this, 'end'); - } - return this; - }, - - /** - * 在当前选区的开始位置前插入节点,新插入的节点会被该range包含 - * @method insertNode - * @param { Node } node 需要插入的节点 - * @remind 插入的节点可以是一个DocumentFragment依次插入多个节点 - * @return { UE.dom.Range } 当前range对象 - */ - insertNode:function (node) { - var first = node, length = 1; - if (node.nodeType == 11) { - first = node.firstChild; - length = node.childNodes.length; - } - this.trimBoundary(true); - var start = this.startContainer, - offset = this.startOffset; - var nextNode = start.childNodes[ offset ]; - if (nextNode) { - start.insertBefore(node, nextNode); - } else { - start.appendChild(node); - } - if (first.parentNode === this.endContainer) { - this.endOffset = this.endOffset + length; - } - return this.setStartBefore(first); - }, - - /** - * 闭合选区到当前选区的开始位置, 并且定位光标到闭合后的位置 - * @method setCursor - * @return { UE.dom.Range } 当前range对象 - * @see UE.dom.Range:collapse() - */ - - /** - * 闭合选区,可以根据参数toEnd的值控制选区是向前闭合还是向后闭合, 并且定位光标到闭合后的位置。 - * @method setCursor - * @param { Boolean } toEnd 是否向后闭合, 如果为true, 则闭合选区时, 将向结束容器方向闭合, - * 反之,则向开始容器方向闭合 - * @return { UE.dom.Range } 当前range对象 - * @see UE.dom.Range:collapse(Boolean) - */ - setCursor:function (toEnd, noFillData) { - return this.collapse(!toEnd).select(noFillData); - }, - - /** - * 创建当前range的一个书签,记录下当前range的位置,方便当dom树改变时,还能找回原来的选区位置 - * @method createBookmark - * @param { Boolean } serialize 控制返回的标记位置是对当前位置的引用还是ID,如果该值为true,则 - * 返回标记位置的ID, 反之则返回标记位置节点的引用 - * @return { Object } 返回一个书签记录键值对, 其包含的key有: start => 开始标记的ID或者引用, - * end => 结束标记的ID或引用, id => 当前标记的类型, 如果为true,则表示 - * 返回的记录的类型为ID, 反之则为引用 - */ - createBookmark:function (serialize, same) { - var endNode, - startNode = this.document.createElement('span'); - startNode.style.cssText = 'display:none;line-height:0px;'; - startNode.appendChild(this.document.createTextNode('\u200D')); - startNode.id = '_baidu_bookmark_start_' + (same ? '' : guid++); - - if (!this.collapsed) { - endNode = startNode.cloneNode(true); - endNode.id = '_baidu_bookmark_end_' + (same ? '' : guid++); - } - this.insertNode(startNode); - if (endNode) { - this.collapse().insertNode(endNode).setEndBefore(endNode); - } - this.setStartAfter(startNode); - return { - start:serialize ? startNode.id : startNode, - end:endNode ? serialize ? endNode.id : endNode : null, - id:serialize - } - }, - - /** - * 调整当前range的边界到书签位置,并删除该书签对象所标记的位置内的节点 - * @method moveToBookmark - * @param { BookMark } bookmark createBookmark所创建的标签对象 - * @return { UE.dom.Range } 当前range对象 - * @see UE.dom.Range:createBookmark(Boolean) - */ - moveToBookmark:function (bookmark) { - var start = bookmark.id ? this.document.getElementById(bookmark.start) : bookmark.start, - end = bookmark.end && bookmark.id ? this.document.getElementById(bookmark.end) : bookmark.end; - this.setStartBefore(start); - domUtils.remove(start); - if (end) { - this.setEndBefore(end); - domUtils.remove(end); - } else { - this.collapse(true); - } - return this; - }, - - /** - * 调整range的边界,使其"放大"到最近的父节点 - * @method enlarge - * @remind 会引起选区的变化 - * @return { UE.dom.Range } 当前range对象 - */ - - /** - * 调整range的边界,使其"放大"到最近的父节点,根据参数 toBlock 的取值, 可以 - * 要求扩大之后的父节点是block节点 - * @method enlarge - * @param { Boolean } toBlock 是否要求扩大之后的父节点必须是block节点 - * @return { UE.dom.Range } 当前range对象 - */ - enlarge:function (toBlock, stopFn) { - var isBody = domUtils.isBody, - pre, node, tmp = this.document.createTextNode(''); - if (toBlock) { - node = this.startContainer; - if (node.nodeType == 1) { - if (node.childNodes[this.startOffset]) { - pre = node = node.childNodes[this.startOffset] - } else { - node.appendChild(tmp); - pre = node = tmp; - } - } else { - pre = node; - } - while (1) { - if (domUtils.isBlockElm(node)) { - node = pre; - while ((pre = node.previousSibling) && !domUtils.isBlockElm(pre)) { - node = pre; - } - this.setStartBefore(node); - break; - } - pre = node; - node = node.parentNode; - } - node = this.endContainer; - if (node.nodeType == 1) { - if (pre = node.childNodes[this.endOffset]) { - node.insertBefore(tmp, pre); - } else { - node.appendChild(tmp); - } - pre = node = tmp; - } else { - pre = node; - } - while (1) { - if (domUtils.isBlockElm(node)) { - node = pre; - while ((pre = node.nextSibling) && !domUtils.isBlockElm(pre)) { - node = pre; - } - this.setEndAfter(node); - break; - } - pre = node; - node = node.parentNode; - } - if (tmp.parentNode === this.endContainer) { - this.endOffset--; - } - domUtils.remove(tmp); - } - - // 扩展边界到最大 - if (!this.collapsed) { - while (this.startOffset == 0) { - if (stopFn && stopFn(this.startContainer)) { - break; - } - if (isBody(this.startContainer)) { - break; - } - this.setStartBefore(this.startContainer); - } - while (this.endOffset == (this.endContainer.nodeType == 1 ? this.endContainer.childNodes.length : this.endContainer.nodeValue.length)) { - if (stopFn && stopFn(this.endContainer)) { - break; - } - if (isBody(this.endContainer)) { - break; - } - this.setEndAfter(this.endContainer); - } - } - return this; - }, - enlargeToBlockElm:function(ignoreEnd){ - while(!domUtils.isBlockElm(this.startContainer)){ - this.setStartBefore(this.startContainer); - } - if(!ignoreEnd){ - while(!domUtils.isBlockElm(this.endContainer)){ - this.setEndAfter(this.endContainer); - } - } - return this; - }, - /** - * 调整Range的边界,使其"缩小"到最合适的位置 - * @method adjustmentBoundary - * @return { UE.dom.Range } 当前range对象 - * @see UE.dom.Range:shrinkBoundary() - */ - adjustmentBoundary:function () { - if (!this.collapsed) { - while (!domUtils.isBody(this.startContainer) && - this.startOffset == this.startContainer[this.startContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length && - this.startContainer[this.startContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length - ) { - - this.setStartAfter(this.startContainer); - } - while (!domUtils.isBody(this.endContainer) && !this.endOffset && - this.endContainer[this.endContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length - ) { - this.setEndBefore(this.endContainer); - } - } - return this; - }, - - /** - * 给range选区中的内容添加给定的inline标签 - * @method applyInlineStyle - * @param { String } tagName 需要添加的标签名 - * @example - * ```html - *

    xxxx[xxxx]x

    ==> range.applyInlineStyle("strong") ==>

    xxxx[xxxx]x

    - * ``` - */ - - /** - * 给range选区中的内容添加给定的inline标签, 并且为标签附加上一些初始化属性。 - * @method applyInlineStyle - * @param { String } tagName 需要添加的标签名 - * @param { Object } attrs 跟随新添加的标签的属性 - * @return { UE.dom.Range } 当前选区 - * @example - * ```html - *

    xxxx[xxxx]x

    - * - * ==> - * - * - * range.applyInlineStyle("strong",{"style":"font-size:12px"}) - * - * ==> - * - *

    xxxx[xxxx]x

    - * ``` - */ - applyInlineStyle:function (tagName, attrs, list) { - if (this.collapsed)return this; - this.trimBoundary().enlarge(false, - function (node) { - return node.nodeType == 1 && domUtils.isBlockElm(node) - }).adjustmentBoundary(); - var bookmark = this.createBookmark(), - end = bookmark.end, - filterFn = function (node) { - return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' : !domUtils.isWhitespace(node); - }, - current = domUtils.getNextDomNode(bookmark.start, false, filterFn), - node, - pre, - range = this.cloneRange(); - while (current && (domUtils.getPosition(current, end) & domUtils.POSITION_PRECEDING)) { - if (current.nodeType == 3 || dtd[tagName][current.tagName]) { - range.setStartBefore(current); - node = current; - while (node && (node.nodeType == 3 || dtd[tagName][node.tagName]) && node !== end) { - pre = node; - node = domUtils.getNextDomNode(node, node.nodeType == 1, null, function (parent) { - return dtd[tagName][parent.tagName]; - }); - } - var frag = range.setEndAfter(pre).extractContents(), elm; - if (list && list.length > 0) { - var level, top; - top = level = list[0].cloneNode(false); - for (var i = 1, ci; ci = list[i++];) { - level.appendChild(ci.cloneNode(false)); - level = level.firstChild; - } - elm = level; - } else { - elm = range.document.createElement(tagName); - } - if (attrs) { - domUtils.setAttributes(elm, attrs); - } - elm.appendChild(frag); - range.insertNode(list ? top : elm); - //处理下滑线在a上的情况 - var aNode; - if (tagName == 'span' && attrs.style && /text\-decoration/.test(attrs.style) && (aNode = domUtils.findParentByTagName(elm, 'a', true))) { - domUtils.setAttributes(aNode, attrs); - domUtils.remove(elm, true); - elm = aNode; - } else { - domUtils.mergeSibling(elm); - domUtils.clearEmptySibling(elm); - } - //去除子节点相同的 - domUtils.mergeChild(elm, attrs); - current = domUtils.getNextDomNode(elm, false, filterFn); - domUtils.mergeToParent(elm); - if (node === end) { - break; - } - } else { - current = domUtils.getNextDomNode(current, true, filterFn); - } - } - return this.moveToBookmark(bookmark); - }, - - /** - * 移除当前选区内指定的inline标签,但保留其中的内容 - * @method removeInlineStyle - * @param { String } tagName 需要移除的标签名 - * @return { UE.dom.Range } 当前的range对象 - * @example - * ```html - * xx[xxxxyyyzz]z => range.removeInlineStyle(["em"]) => xx[xxxxyyyzz]z - * ``` - */ - - /** - * 移除当前选区内指定的一组inline标签,但保留其中的内容 - * @method removeInlineStyle - * @param { Array } tagNameArr 需要移除的标签名的数组 - * @return { UE.dom.Range } 当前的range对象 - * @see UE.dom.Range:removeInlineStyle(String) - */ - removeInlineStyle:function (tagNames) { - if (this.collapsed)return this; - tagNames = utils.isArray(tagNames) ? tagNames : [tagNames]; - this.shrinkBoundary().adjustmentBoundary(); - var start = this.startContainer, end = this.endContainer; - while (1) { - if (start.nodeType == 1) { - if (utils.indexOf(tagNames, start.tagName.toLowerCase()) > -1) { - break; - } - if (start.tagName.toLowerCase() == 'body') { - start = null; - break; - } - } - start = start.parentNode; - } - while (1) { - if (end.nodeType == 1) { - if (utils.indexOf(tagNames, end.tagName.toLowerCase()) > -1) { - break; - } - if (end.tagName.toLowerCase() == 'body') { - end = null; - break; - } - } - end = end.parentNode; - } - var bookmark = this.createBookmark(), - frag, - tmpRange; - if (start) { - tmpRange = this.cloneRange().setEndBefore(bookmark.start).setStartBefore(start); - frag = tmpRange.extractContents(); - tmpRange.insertNode(frag); - domUtils.clearEmptySibling(start, true); - start.parentNode.insertBefore(bookmark.start, start); - } - if (end) { - tmpRange = this.cloneRange().setStartAfter(bookmark.end).setEndAfter(end); - frag = tmpRange.extractContents(); - tmpRange.insertNode(frag); - domUtils.clearEmptySibling(end, false, true); - end.parentNode.insertBefore(bookmark.end, end.nextSibling); - } - var current = domUtils.getNextDomNode(bookmark.start, false, function (node) { - return node.nodeType == 1; - }), next; - while (current && current !== bookmark.end) { - next = domUtils.getNextDomNode(current, true, function (node) { - return node.nodeType == 1; - }); - if (utils.indexOf(tagNames, current.tagName.toLowerCase()) > -1) { - domUtils.remove(current, true); - } - current = next; - } - return this.moveToBookmark(bookmark); - }, - - /** - * 获取当前选中的自闭合的节点 - * @method getClosedNode - * @return { Node | NULL } 如果当前选中的是自闭合节点, 则返回该节点, 否则返回NULL - */ - getClosedNode:function () { - var node; - if (!this.collapsed) { - var range = this.cloneRange().adjustmentBoundary().shrinkBoundary(); - if (selectOneNode(range)) { - var child = range.startContainer.childNodes[range.startOffset]; - if (child && child.nodeType == 1 && (dtd.$empty[child.tagName] || dtd.$nonChild[child.tagName])) { - node = child; - } - } - } - return node; - }, - - /** - * 在页面上高亮range所表示的选区 - * @method select - * @return { UE.dom.Range } 返回当前Range对象 - */ - //这里不区分ie9以上,trace:3824 - select:browser.ie ? function (noFillData, textRange) { - var nativeRange; - if (!this.collapsed) - this.shrinkBoundary(); - var node = this.getClosedNode(); - if (node && !textRange) { - try { - nativeRange = this.document.body.createControlRange(); - nativeRange.addElement(node); - nativeRange.select(); - } catch (e) {} - return this; - } - var bookmark = this.createBookmark(), - start = bookmark.start, - end; - nativeRange = this.document.body.createTextRange(); - nativeRange.moveToElementText(start); - nativeRange.moveStart('character', 1); - if (!this.collapsed) { - var nativeRangeEnd = this.document.body.createTextRange(); - end = bookmark.end; - nativeRangeEnd.moveToElementText(end); - nativeRange.setEndPoint('EndToEnd', nativeRangeEnd); - } else { - if (!noFillData && this.startContainer.nodeType != 3) { - //使用|x固定住光标 - var tmpText = this.document.createTextNode(fillChar), - tmp = this.document.createElement('span'); - tmp.appendChild(this.document.createTextNode(fillChar)); - start.parentNode.insertBefore(tmp, start); - start.parentNode.insertBefore(tmpText, start); - //当点b,i,u时,不能清除i上边的b - removeFillData(this.document, tmpText); - fillData = tmpText; - mergeSibling(tmp, 'previousSibling'); - mergeSibling(start, 'nextSibling'); - nativeRange.moveStart('character', -1); - nativeRange.collapse(true); - } - } - this.moveToBookmark(bookmark); - tmp && domUtils.remove(tmp); - //IE在隐藏状态下不支持range操作,catch一下 - try { - nativeRange.select(); - } catch (e) { - } - return this; - } : function (notInsertFillData) { - function checkOffset(rng){ - - function check(node,offset,dir){ - if(node.nodeType == 3 && node.nodeValue.length < offset){ - rng[dir + 'Offset'] = node.nodeValue.length - } - } - check(rng.startContainer,rng.startOffset,'start'); - check(rng.endContainer,rng.endOffset,'end'); - } - var win = domUtils.getWindow(this.document), - sel = win.getSelection(), - txtNode; - //FF下关闭自动长高时滚动条在关闭dialog时会跳 - //ff下如果不body.focus将不能定位闭合光标到编辑器内 - browser.gecko ? this.document.body.focus() : win.focus(); - if (sel) { - sel.removeAllRanges(); - // trace:870 chrome/safari后边是br对于闭合得range不能定位 所以去掉了判断 - // this.startContainer.nodeType != 3 &&! ((child = this.startContainer.childNodes[this.startOffset]) && child.nodeType == 1 && child.tagName == 'BR' - if (this.collapsed && !notInsertFillData) { -// //opear如果没有节点接着,原生的不能够定位,不能在body的第一级插入空白节点 -// if (notInsertFillData && browser.opera && !domUtils.isBody(this.startContainer) && this.startContainer.nodeType == 1) { -// var tmp = this.document.createTextNode(''); -// this.insertNode(tmp).setStart(tmp, 0).collapse(true); -// } -// - //处理光标落在文本节点的情况 - //处理以下的情况 - //|xxxx - //xxxx|xxxx - //xxxx| - var start = this.startContainer,child = start; - if(start.nodeType == 1){ - child = start.childNodes[this.startOffset]; - - } - if( !(start.nodeType == 3 && this.startOffset) && - (child ? - (!child.previousSibling || child.previousSibling.nodeType != 3) - : - (!start.lastChild || start.lastChild.nodeType != 3) - ) - ){ - txtNode = this.document.createTextNode(fillChar); - //跟着前边走 - this.insertNode(txtNode); - removeFillData(this.document, txtNode); - mergeSibling(txtNode, 'previousSibling'); - mergeSibling(txtNode, 'nextSibling'); - fillData = txtNode; - this.setStart(txtNode, browser.webkit ? 1 : 0).collapse(true); - } - } - var nativeRange = this.document.createRange(); - if(this.collapsed && browser.opera && this.startContainer.nodeType == 1){ - var child = this.startContainer.childNodes[this.startOffset]; - if(!child){ - //往前靠拢 - child = this.startContainer.lastChild; - if( child && domUtils.isBr(child)){ - this.setStartBefore(child).collapse(true); - } - }else{ - //向后靠拢 - while(child && domUtils.isBlockElm(child)){ - if(child.nodeType == 1 && child.childNodes[0]){ - child = child.childNodes[0] - }else{ - break; - } - } - child && this.setStartBefore(child).collapse(true) - } - - } - //是createAddress最后一位算的不准,现在这里进行微调 - checkOffset(this); - nativeRange.setStart(this.startContainer, this.startOffset); - nativeRange.setEnd(this.endContainer, this.endOffset); - sel.addRange(nativeRange); - } - return this; - }, - - /** - * 滚动到当前range开始的位置 - * @method scrollToView - * @param { Window } win 当前range对象所属的window对象 - * @return { UE.dom.Range } 当前Range对象 - */ - - /** - * 滚动到距离当前range开始位置 offset 的位置处 - * @method scrollToView - * @param { Window } win 当前range对象所属的window对象 - * @param { Number } offset 距离range开始位置处的偏移量, 如果为正数, 则向下偏移, 反之, 则向上偏移 - * @return { UE.dom.Range } 当前Range对象 - */ - scrollToView:function (win, offset) { - win = win ? window : domUtils.getWindow(this.document); - var me = this, - span = me.document.createElement('span'); - //trace:717 - span.innerHTML = ' '; - me.cloneRange().insertNode(span); - domUtils.scrollToView(span, win, offset); - domUtils.remove(span); - return me; - }, - - /** - * 判断当前选区内容是否占位符 - * @private - * @method inFillChar - * @return { Boolean } 如果是占位符返回true,否则返回false - */ - inFillChar : function(){ - var start = this.startContainer; - if(this.collapsed && start.nodeType == 3 - && start.nodeValue.replace(new RegExp('^' + domUtils.fillChar),'').length + 1 == start.nodeValue.length - ){ - return true; - } - return false; - }, - - /** - * 保存 - * @method createAddress - * @private - * @return { Boolean } 返回开始和结束的位置 - * @example - * ```html - * - *

    - * aaaa - * - * - * bbbb - * - * - *

    - * - * - * - * ``` - */ - createAddress : function(ignoreEnd,ignoreTxt){ - var addr = {},me = this; - - function getAddress(isStart){ - var node = isStart ? me.startContainer : me.endContainer; - var parents = domUtils.findParents(node,true,function(node){return !domUtils.isBody(node)}), - addrs = []; - for(var i = 0,ci;ci = parents[i++];){ - addrs.push(domUtils.getNodeIndex(ci,ignoreTxt)); - } - var firstIndex = 0; - - if(ignoreTxt){ - if(node.nodeType == 3){ - var tmpNode = node.previousSibling; - while(tmpNode && tmpNode.nodeType == 3){ - firstIndex += tmpNode.nodeValue.replace(fillCharReg,'').length; - tmpNode = tmpNode.previousSibling; - } - firstIndex += (isStart ? me.startOffset : me.endOffset)// - (fillCharReg.test(node.nodeValue) ? 1 : 0 ) - }else{ - node = node.childNodes[ isStart ? me.startOffset : me.endOffset]; - if(node){ - firstIndex = domUtils.getNodeIndex(node,ignoreTxt); - }else{ - node = isStart ? me.startContainer : me.endContainer; - var first = node.firstChild; - while(first){ - if(domUtils.isFillChar(first)){ - first = first.nextSibling; - continue; - } - firstIndex++; - if(first.nodeType == 3){ - while( first && first.nodeType == 3){ - first = first.nextSibling; - } - }else{ - first = first.nextSibling; - } - } - } - } - - }else{ - firstIndex = isStart ? domUtils.isFillChar(node) ? 0 : me.startOffset : me.endOffset - } - if(firstIndex < 0){ - firstIndex = 0; - } - addrs.push(firstIndex); - return addrs; - } - addr.startAddress = getAddress(true); - if(!ignoreEnd){ - addr.endAddress = me.collapsed ? [].concat(addr.startAddress) : getAddress(); - } - return addr; - }, - - /** - * 保存 - * @method createAddress - * @private - * @return { Boolean } 返回开始和结束的位置 - * @example - * ```html - * - *

    - * aaaa - * - * - * bbbb - * - * - *

    - * - * - * - * ``` - */ - moveToAddress : function(addr,ignoreEnd){ - var me = this; - function getNode(address,isStart){ - var tmpNode = me.document.body, - parentNode,offset; - for(var i= 0,ci,l=address.length;i - * - * - * - * - * - * - * - * - * ``` - */ - - /** - * 遍历range内的节点。 - * 每当遍历一个节点时, 都会执行参数项 doFn 指定的函数, 该函数的接受当前遍历的节点 - * 作为其参数。 - * 可以通过参数项 filterFn 来指定一个过滤器, 只有符合该过滤器过滤规则的节点才会触 - * 发doFn函数的执行 - * @method traversal - * @param { Function } doFn 对每个遍历的节点要执行的方法, 该方法接受当前遍历的节点作为其参数 - * @param { Function } filterFn 过滤器, 该函数接受当前遍历的节点作为参数, 如果该节点满足过滤 - * 规则, 请返回true, 该节点会触发doFn, 否则, 请返回false, 则该节点不 - * 会触发doFn。 - * @return { UE.dom.Range } 当前range对象 - * @see UE.dom.Range:traversal(Function) - * @example - * ```html - * - * - * - * - * - * - * - * - * - * - * ``` - */ - traversal:function(doFn,filterFn){ - if (this.collapsed) - return this; - var bookmark = this.createBookmark(), - end = bookmark.end, - current = domUtils.getNextDomNode(bookmark.start, false, filterFn); - while (current && current !== end && (domUtils.getPosition(current, end) & domUtils.POSITION_PRECEDING)) { - var tmpNode = domUtils.getNextDomNode(current,false,filterFn); - doFn(current); - current = tmpNode; - } - return this.moveToBookmark(bookmark); - } - }; -})(); - -// core/Selection.js -/** - * 选集 - * @file - * @module UE.dom - * @class Selection - * @since 1.2.6.1 - */ - -/** - * 选区集合 - * @unfile - * @module UE.dom - * @class Selection - */ -(function () { - - function getBoundaryInformation( range, start ) { - var getIndex = domUtils.getNodeIndex; - range = range.duplicate(); - range.collapse( start ); - var parent = range.parentElement(); - //如果节点里没有子节点,直接退出 - if ( !parent.hasChildNodes() ) { - return {container:parent, offset:0}; - } - var siblings = parent.children, - child, - testRange = range.duplicate(), - startIndex = 0, endIndex = siblings.length - 1, index = -1, - distance; - while ( startIndex <= endIndex ) { - index = Math.floor( (startIndex + endIndex) / 2 ); - child = siblings[index]; - testRange.moveToElementText( child ); - var position = testRange.compareEndPoints( 'StartToStart', range ); - if ( position > 0 ) { - endIndex = index - 1; - } else if ( position < 0 ) { - startIndex = index + 1; - } else { - //trace:1043 - return {container:parent, offset:getIndex( child )}; - } - } - if ( index == -1 ) { - testRange.moveToElementText( parent ); - testRange.setEndPoint( 'StartToStart', range ); - distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length; - siblings = parent.childNodes; - if ( !distance ) { - child = siblings[siblings.length - 1]; - return {container:child, offset:child.nodeValue.length}; - } - - var i = siblings.length; - while ( distance > 0 ){ - distance -= siblings[ --i ].nodeValue.length; - } - return {container:siblings[i], offset:-distance}; - } - testRange.collapse( position > 0 ); - testRange.setEndPoint( position > 0 ? 'StartToStart' : 'EndToStart', range ); - distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length; - if ( !distance ) { - return dtd.$empty[child.tagName] || dtd.$nonChild[child.tagName] ? - {container:parent, offset:getIndex( child ) + (position > 0 ? 0 : 1)} : - {container:child, offset:position > 0 ? 0 : child.childNodes.length} - } - while ( distance > 0 ) { - try { - var pre = child; - child = child[position > 0 ? 'previousSibling' : 'nextSibling']; - distance -= child.nodeValue.length; - } catch ( e ) { - return {container:parent, offset:getIndex( pre )}; - } - } - return {container:child, offset:position > 0 ? -distance : child.nodeValue.length + distance} - } - - /** - * 将ieRange转换为Range对象 - * @param {Range} ieRange ieRange对象 - * @param {Range} range Range对象 - * @return {Range} range 返回转换后的Range对象 - */ - function transformIERangeToRange( ieRange, range ) { - if ( ieRange.item ) { - range.selectNode( ieRange.item( 0 ) ); - } else { - var bi = getBoundaryInformation( ieRange, true ); - range.setStart( bi.container, bi.offset ); - if ( ieRange.compareEndPoints( 'StartToEnd', ieRange ) != 0 ) { - bi = getBoundaryInformation( ieRange, false ); - range.setEnd( bi.container, bi.offset ); - } - } - return range; - } - - /** - * 获得ieRange - * @param {Selection} sel Selection对象 - * @return {ieRange} 得到ieRange - */ - function _getIERange( sel ) { - var ieRange; - //ie下有可能报错 - try { - ieRange = sel.getNative().createRange(); - } catch ( e ) { - return null; - } - var el = ieRange.item ? ieRange.item( 0 ) : ieRange.parentElement(); - if ( ( el.ownerDocument || el ) === sel.document ) { - return ieRange; - } - return null; - } - - var Selection = dom.Selection = function ( doc ) { - var me = this, iframe; - me.document = doc; - if ( browser.ie9below ) { - iframe = domUtils.getWindow( doc ).frameElement; - domUtils.on( iframe, 'beforedeactivate', function () { - me._bakIERange = me.getIERange(); - } ); - domUtils.on( iframe, 'activate', function () { - try { - if ( !_getIERange( me ) && me._bakIERange ) { - me._bakIERange.select(); - } - } catch ( ex ) { - } - me._bakIERange = null; - } ); - } - iframe = doc = null; - }; - - Selection.prototype = { - - rangeInBody : function(rng,txtRange){ - var node = browser.ie9below || txtRange ? rng.item ? rng.item() : rng.parentElement() : rng.startContainer; - - return node === this.document.body || domUtils.inDoc(node,this.document); - }, - - /** - * 获取原生seleciton对象 - * @method getNative - * @return { Object } 获得selection对象 - * @example - * ```javascript - * editor.selection.getNative(); - * ``` - */ - getNative:function () { - var doc = this.document; - try { - return !doc ? null : browser.ie9below ? doc.selection : domUtils.getWindow( doc ).getSelection(); - } catch ( e ) { - return null; - } - }, - - /** - * 获得ieRange - * @method getIERange - * @return { Object } 返回ie原生的Range - * @example - * ```javascript - * editor.selection.getIERange(); - * ``` - */ - getIERange:function () { - var ieRange = _getIERange( this ); - if ( !ieRange ) { - if ( this._bakIERange ) { - return this._bakIERange; - } - } - return ieRange; - }, - - /** - * 缓存当前选区的range和选区的开始节点 - * @method cache - */ - cache:function () { - this.clear(); - this._cachedRange = this.getRange(); - this._cachedStartElement = this.getStart(); - this._cachedStartElementPath = this.getStartElementPath(); - }, - - /** - * 获取选区开始位置的父节点到body - * @method getStartElementPath - * @return { Array } 返回父节点集合 - * @example - * ```javascript - * editor.selection.getStartElementPath(); - * ``` - */ - getStartElementPath:function () { - if ( this._cachedStartElementPath ) { - return this._cachedStartElementPath; - } - var start = this.getStart(); - if ( start ) { - return domUtils.findParents( start, true, null, true ) - } - return []; - }, - - /** - * 清空缓存 - * @method clear - */ - clear:function () { - this._cachedStartElementPath = this._cachedRange = this._cachedStartElement = null; - }, - - /** - * 编辑器是否得到了选区 - * @method isFocus - */ - isFocus:function () { - try { - if(browser.ie9below){ - - var nativeRange = _getIERange(this); - return !!(nativeRange && this.rangeInBody(nativeRange)); - }else{ - return !!this.getNative().rangeCount; - } - } catch ( e ) { - return false; - } - - }, - - /** - * 获取选区对应的Range - * @method getRange - * @return { Object } 得到Range对象 - * @example - * ```javascript - * editor.selection.getRange(); - * ``` - */ - getRange:function () { - var me = this; - function optimze( range ) { - var child = me.document.body.firstChild, - collapsed = range.collapsed; - while ( child && child.firstChild ) { - range.setStart( child, 0 ); - child = child.firstChild; - } - if ( !range.startContainer ) { - range.setStart( me.document.body, 0 ) - } - if ( collapsed ) { - range.collapse( true ); - } - } - - if ( me._cachedRange != null ) { - return this._cachedRange; - } - var range = new baidu.editor.dom.Range( me.document ); - - if ( browser.ie9below ) { - var nativeRange = me.getIERange(); - if ( nativeRange ) { - //备份的_bakIERange可能已经实效了,dom树发生了变化比如从源码模式切回来,所以try一下,实效就放到body开始位置 - try{ - transformIERangeToRange( nativeRange, range ); - }catch(e){ - optimze( range ); - } - - } else { - optimze( range ); - } - } else { - var sel = me.getNative(); - if ( sel && sel.rangeCount ) { - var firstRange = sel.getRangeAt( 0 ); - var lastRange = sel.getRangeAt( sel.rangeCount - 1 ); - range.setStart( firstRange.startContainer, firstRange.startOffset ).setEnd( lastRange.endContainer, lastRange.endOffset ); - if ( range.collapsed && domUtils.isBody( range.startContainer ) && !range.startOffset ) { - optimze( range ); - } - } else { - //trace:1734 有可能已经不在dom树上了,标识的节点 - if ( this._bakRange && domUtils.inDoc( this._bakRange.startContainer, this.document ) ){ - return this._bakRange; - } - optimze( range ); - } - } - return this._bakRange = range; - }, - - /** - * 获取开始元素,用于状态反射 - * @method getStart - * @return { Element } 获得开始元素 - * @example - * ```javascript - * editor.selection.getStart(); - * ``` - */ - getStart:function () { - if ( this._cachedStartElement ) { - return this._cachedStartElement; - } - var range = browser.ie9below ? this.getIERange() : this.getRange(), - tmpRange, - start, tmp, parent; - if ( browser.ie9below ) { - if ( !range ) { - //todo 给第一个值可能会有问题 - return this.document.body.firstChild; - } - //control元素 - if ( range.item ){ - return range.item( 0 ); - } - tmpRange = range.duplicate(); - //修正ie下x[xx] 闭合后 x|xx - tmpRange.text.length > 0 && tmpRange.moveStart( 'character', 1 ); - tmpRange.collapse( 1 ); - start = tmpRange.parentElement(); - parent = tmp = range.parentElement(); - while ( tmp = tmp.parentNode ) { - if ( tmp == start ) { - start = parent; - break; - } - } - } else { - range.shrinkBoundary(); - start = range.startContainer; - if ( start.nodeType == 1 && start.hasChildNodes() ){ - start = start.childNodes[Math.min( start.childNodes.length - 1, range.startOffset )]; - } - if ( start.nodeType == 3 ){ - return start.parentNode; - } - } - return start; - }, - - /** - * 得到选区中的文本 - * @method getText - * @return { String } 选区中包含的文本 - * @example - * ```javascript - * editor.selection.getText(); - * ``` - */ - getText:function () { - var nativeSel, nativeRange; - if ( this.isFocus() && (nativeSel = this.getNative()) ) { - nativeRange = browser.ie9below ? nativeSel.createRange() : nativeSel.getRangeAt( 0 ); - return browser.ie9below ? nativeRange.text : nativeRange.toString(); - } - return ''; - }, - - /** - * 清除选区 - * @method clearRange - * @example - * ```javascript - * editor.selection.clearRange(); - * ``` - */ - clearRange : function(){ - this.getNative()[browser.ie9below ? 'empty' : 'removeAllRanges'](); - } - }; -})(); - -// core/Editor.js -/** - * 编辑器主类,包含编辑器提供的大部分公用接口 - * @file - * @module UE - * @class Editor - * @since 1.2.6.1 - */ - -/** - * UEditor公用空间,UEditor所有的功能都挂载在该空间下 - * @unfile - * @module UE - */ - -/** - * UEditor的核心类,为用户提供与编辑器交互的接口。 - * @unfile - * @module UE - * @class Editor - */ - -(function () { - var uid = 0, _selectionChangeTimer; - - /** - * 获取编辑器的html内容,赋值到编辑器所在表单的textarea文本域里面 - * @private - * @method setValue - * @param { UE.Editor } editor 编辑器事例 - */ - function setValue(form, editor) { - var textarea; - if (editor.textarea) { - if (utils.isString(editor.textarea)) { - for (var i = 0, ti, tis = domUtils.getElementsByTagName(form, 'textarea'); ti = tis[i++];) { - if (ti.id == 'ueditor_textarea_' + editor.options.textarea) { - textarea = ti; - break; - } - } - } else { - textarea = editor.textarea; - } - } - if (!textarea) { - form.appendChild(textarea = domUtils.createElement(document, 'textarea', { - 'name': editor.options.textarea, - 'id': 'ueditor_textarea_' + editor.options.textarea, - 'style': "display:none" - })); - //不要产生多个textarea - editor.textarea = textarea; - } - !textarea.getAttribute('name') && textarea.setAttribute('name', editor.options.textarea ); - textarea.value = editor.hasContents() ? - (editor.options.allHtmlEnabled ? editor.getAllHtml() : editor.getContent(null, null, true)) : - '' - } - function loadPlugins(me){ - //初始化插件 - for (var pi in UE.plugins) { - UE.plugins[pi].call(me); - } - - } - function checkCurLang(I18N){ - for(var lang in I18N){ - return lang - } - } - - function langReadied(me){ - me.langIsReady = true; - - me.fireEvent("langReady"); - } - - /** - * 编辑器准备就绪后会触发该事件 - * @module UE - * @class Editor - * @event ready - * @remind render方法执行完成之后,会触发该事件 - * @remind - * @example - * ```javascript - * editor.addListener( 'ready', function( editor ) { - * editor.execCommand( 'focus' ); //编辑器家在完成后,让编辑器拿到焦点 - * } ); - * ``` - */ - /** - * 执行destroy方法,会触发该事件 - * @module UE - * @class Editor - * @event destroy - * @see UE.Editor:destroy() - */ - /** - * 执行reset方法,会触发该事件 - * @module UE - * @class Editor - * @event reset - * @see UE.Editor:reset() - */ - /** - * 执行focus方法,会触发该事件 - * @module UE - * @class Editor - * @event focus - * @see UE.Editor:focus(Boolean) - */ - /** - * 语言加载完成会触发该事件 - * @module UE - * @class Editor - * @event langReady - */ - /** - * 运行命令之后会触发该命令 - * @module UE - * @class Editor - * @event beforeExecCommand - */ - /** - * 运行命令之后会触发该命令 - * @module UE - * @class Editor - * @event afterExecCommand - */ - /** - * 运行命令之前会触发该命令 - * @module UE - * @class Editor - * @event firstBeforeExecCommand - */ - /** - * 在getContent方法执行之前会触发该事件 - * @module UE - * @class Editor - * @event beforeGetContent - * @see UE.Editor:getContent() - */ - /** - * 在getContent方法执行之后会触发该事件 - * @module UE - * @class Editor - * @event afterGetContent - * @see UE.Editor:getContent() - */ - /** - * 在getAllHtml方法执行时会触发该事件 - * @module UE - * @class Editor - * @event getAllHtml - * @see UE.Editor:getAllHtml() - */ - /** - * 在setContent方法执行之前会触发该事件 - * @module UE - * @class Editor - * @event beforeSetContent - * @see UE.Editor:setContent(String) - */ - /** - * 在setContent方法执行之后会触发该事件 - * @module UE - * @class Editor - * @event afterSetContent - * @see UE.Editor:setContent(String) - */ - /** - * 每当编辑器内部选区发生改变时,将触发该事件 - * @event selectionchange - * @warning 该事件的触发非常频繁,不建议在该事件的处理过程中做重量级的处理 - * @example - * ```javascript - * editor.addListener( 'selectionchange', function( editor ) { - * console.log('选区发生改变'); - * } - */ - /** - * 在所有selectionchange的监听函数执行之前,会触发该事件 - * @module UE - * @class Editor - * @event beforeSelectionChange - * @see UE.Editor:selectionchange - */ - /** - * 在所有selectionchange的监听函数执行完之后,会触发该事件 - * @module UE - * @class Editor - * @event afterSelectionChange - * @see UE.Editor:selectionchange - */ - /** - * 编辑器内容发生改变时会触发该事件 - * @module UE - * @class Editor - * @event contentChange - */ - - - /** - * 以默认参数构建一个编辑器实例 - * @constructor - * @remind 通过 改构造方法实例化的编辑器,不带ui层.需要render到一个容器,编辑器实例才能正常渲染到页面 - * @example - * ```javascript - * var editor = new UE.Editor(); - * editor.execCommand('blod'); - * ``` - * @see UE.Config - */ - - /** - * 以给定的参数集合创建一个编辑器实例,对于未指定的参数,将应用默认参数。 - * @constructor - * @remind 通过 改构造方法实例化的编辑器,不带ui层.需要render到一个容器,编辑器实例才能正常渲染到页面 - * @param { Object } setting 创建编辑器的参数 - * @example - * ```javascript - * var editor = new UE.Editor(); - * editor.execCommand('blod'); - * ``` - * @see UE.Config - */ - var Editor = UE.Editor = function (options) { - var me = this; - me.uid = uid++; - EventBase.call(me); - me.commands = {}; - me.options = utils.extend(utils.clone(options || {}), UEDITOR_CONFIG, true); - me.shortcutkeys = {}; - me.inputRules = []; - me.outputRules = []; - //设置默认的常用属性 - me.setOpt(Editor.defaultOptions(me)); - - /* 尝试异步加载后台配置 */ - me.loadServerConfig(); - - if(!utils.isEmptyObject(UE.I18N)){ - //修改默认的语言类型 - me.options.lang = checkCurLang(UE.I18N); - UE.plugin.load(me); - langReadied(me); - - }else{ - utils.loadFile(document, { - src: me.options.langPath + me.options.lang + "/" + me.options.lang + ".js", - tag: "script", - type: "text/javascript", - defer: "defer" - }, function () { - UE.plugin.load(me); - langReadied(me); - }); - } - - UE.instants['ueditorInstant' + me.uid] = me; - }; - Editor.prototype = { - registerCommand : function(name,obj){ - this.commands[name] = obj; - }, - /** - * 编辑器对外提供的监听ready事件的接口, 通过调用该方法,达到的效果与监听ready事件是一致的 - * @method ready - * @param { Function } fn 编辑器ready之后所执行的回调, 如果在注册事件之前编辑器已经ready,将会 - * 立即触发该回调。 - * @remind 需要等待编辑器加载完成后才能执行的代码,可以使用该方法传入 - * @example - * ```javascript - * editor.ready( function( editor ) { - * editor.setContent('初始化完毕'); - * } ); - * ``` - * @see UE.Editor.event:ready - */ - ready: function (fn) { - var me = this; - if (fn) { - me.isReady ? fn.apply(me) : me.addListener('ready', fn); - } - }, - - /** - * 该方法是提供给插件里面使用,设置配置项默认值 - * @method setOpt - * @warning 三处设置配置项的优先级: 实例化时传入参数 > setOpt()设置 > config文件里设置 - * @warning 该方法仅供编辑器插件内部和编辑器初始化时调用,其他地方不能调用。 - * @param { String } key 编辑器的可接受的选项名称 - * @param { * } val 该选项可接受的值 - * @example - * ```javascript - * editor.setOpt( 'initContent', '欢迎使用编辑器' ); - * ``` - */ - - /** - * 该方法是提供给插件里面使用,以{key:value}集合的方式设置插件内用到的配置项默认值 - * @method setOpt - * @warning 三处设置配置项的优先级: 实例化时传入参数 > setOpt()设置 > config文件里设置 - * @warning 该方法仅供编辑器插件内部和编辑器初始化时调用,其他地方不能调用。 - * @param { Object } options 将要设置的选项的键值对对象 - * @example - * ```javascript - * editor.setOpt( { - * 'initContent': '欢迎使用编辑器' - * } ); - * ``` - */ - setOpt: function (key, val) { - var obj = {}; - if (utils.isString(key)) { - obj[key] = val - } else { - obj = key; - } - utils.extend(this.options, obj, true); - }, - getOpt:function(key){ - return this.options[key] - }, - /** - * 销毁编辑器实例,使用textarea代替 - * @method destroy - * @example - * ```javascript - * editor.destroy(); - * ``` - */ - destroy: function () { - - var me = this; - me.fireEvent('destroy'); - var container = me.container.parentNode; - var textarea = me.textarea; - if (!textarea) { - textarea = document.createElement('textarea'); - container.parentNode.insertBefore(textarea, container); - } else { - textarea.style.display = '' - } - - textarea.style.width = me.iframe.offsetWidth + 'px'; - textarea.style.height = me.iframe.offsetHeight + 'px'; - textarea.value = me.getContent(); - textarea.id = me.key; - container.innerHTML = ''; - domUtils.remove(container); - var key = me.key; - //trace:2004 - for (var p in me) { - if (me.hasOwnProperty(p)) { - delete this[p]; - } - } - UE.delEditor(key); - }, - - /** - * 渲染编辑器的DOM到指定容器 - * @method render - * @param { String } containerId 指定一个容器ID - * @remind 执行该方法,会触发ready事件 - * @warning 必须且只能调用一次 - */ - - /** - * 渲染编辑器的DOM到指定容器 - * @method render - * @param { Element } containerDom 直接指定容器对象 - * @remind 执行该方法,会触发ready事件 - * @warning 必须且只能调用一次 - */ - render: function (container) { - var me = this, - options = me.options, - getStyleValue=function(attr){ - return parseInt(domUtils.getComputedStyle(container,attr)); - }; - if (utils.isString(container)) { - container = document.getElementById(container); - } - if (container) { - if(options.initialFrameWidth){ - options.minFrameWidth = options.initialFrameWidth - }else{ - options.minFrameWidth = options.initialFrameWidth = container.offsetWidth; - } - if(options.initialFrameHeight){ - options.minFrameHeight = options.initialFrameHeight - }else{ - options.initialFrameHeight = options.minFrameHeight = container.offsetHeight; - } - - container.style.width = /%$/.test(options.initialFrameWidth) ? '100%' : options.initialFrameWidth- - getStyleValue("padding-left")- getStyleValue("padding-right") +'px'; - container.style.height = /%$/.test(options.initialFrameHeight) ? '100%' : options.initialFrameHeight - - getStyleValue("padding-top")- getStyleValue("padding-bottom") +'px'; - - container.style.zIndex = options.zIndex; - - var html = ( ie && browser.version < 9 ? '' : '') + - '' + - '' + - ( options.iframeCssUrl ? '' : '' ) + - (options.initialStyle ? '' : '') + - '' + - ''; - container.appendChild(domUtils.createElement(document, 'iframe', { - id: 'ueditor_' + me.uid, - width: "100%", - height: "100%", - frameborder: "0", - //先注释掉了,加的原因忘记了,但开启会直接导致全屏模式下内容多时不会出现滚动条 -// scrolling :'no', - src: 'javascript:void(function(){document.open();' + (options.customDomain && document.domain != location.hostname ? 'document.domain="' + document.domain + '";' : '') + - 'document.write("' + html + '");document.close();}())' - })); - container.style.overflow = 'hidden'; - //解决如果是给定的百分比,会导致高度算不对的问题 - setTimeout(function(){ - if( /%$/.test(options.initialFrameWidth)){ - options.minFrameWidth = options.initialFrameWidth = container.offsetWidth; - //如果这里给定宽度,会导致ie在拖动窗口大小时,编辑区域不随着变化 -// container.style.width = options.initialFrameWidth + 'px'; - } - if(/%$/.test(options.initialFrameHeight)){ - options.minFrameHeight = options.initialFrameHeight = container.offsetHeight; - container.style.height = options.initialFrameHeight + 'px'; - } - }) - } - }, - - /** - * 编辑器初始化 - * @method _setup - * @private - * @param { Element } doc 编辑器Iframe中的文档对象 - */ - _setup: function (doc) { - - var me = this, - options = me.options; - if (ie) { - doc.body.disabled = true; - doc.body.contentEditable = true; - doc.body.disabled = false; - } else { - doc.body.contentEditable = true; - } - doc.body.spellcheck = false; - me.document = doc; - me.window = doc.defaultView || doc.parentWindow; - me.iframe = me.window.frameElement; - me.body = doc.body; - me.selection = new dom.Selection(doc); - //gecko初始化就能得到range,无法判断isFocus了 - var geckoSel; - if (browser.gecko && (geckoSel = this.selection.getNative())) { - geckoSel.removeAllRanges(); - } - this._initEvents(); - //为form提交提供一个隐藏的textarea - for (var form = this.iframe.parentNode; !domUtils.isBody(form); form = form.parentNode) { - if (form.tagName == 'FORM') { - me.form = form; - if(me.options.autoSyncData){ - domUtils.on(me.window,'blur',function(){ - setValue(form,me); - }); - }else{ - domUtils.on(form, 'submit', function () { - setValue(this, me); - }); - } - break; - } - } - if (options.initialContent) { - if (options.autoClearinitialContent) { - var oldExecCommand = me.execCommand; - me.execCommand = function () { - me.fireEvent('firstBeforeExecCommand'); - return oldExecCommand.apply(me, arguments); - }; - this._setDefaultContent(options.initialContent); - } else - this.setContent(options.initialContent, false, true); - } - - //编辑器不能为空内容 - - if (domUtils.isEmptyNode(me.body)) { - me.body.innerHTML = '

    ' + (browser.ie ? '' : '
    ') + '

    '; - } - //如果要求focus, 就把光标定位到内容开始 - if (options.focus) { - setTimeout(function () { - me.focus(me.options.focusInEnd); - //如果自动清除开着,就不需要做selectionchange; - !me.options.autoClearinitialContent && me._selectionChange(); - }, 0); - } - if (!me.container) { - me.container = this.iframe.parentNode; - } - if (options.fullscreen && me.ui) { - me.ui.setFullScreen(true); - } - - try { - me.document.execCommand('2D-position', false, false); - } catch (e) { - } - try { - me.document.execCommand('enableInlineTableEditing', false, false); - } catch (e) { - } - try { - me.document.execCommand('enableObjectResizing', false, false); - } catch (e) { - } - - //挂接快捷键 - me._bindshortcutKeys(); - me.isReady = 1; - me.fireEvent('ready'); - options.onready && options.onready.call(me); - if (!browser.ie9below) { - domUtils.on(me.window, ['blur', 'focus'], function (e) { - //chrome下会出现alt+tab切换时,导致选区位置不对 - if (e.type == 'blur') { - me._bakRange = me.selection.getRange(); - try { - me._bakNativeRange = me.selection.getNative().getRangeAt(0); - me.selection.getNative().removeAllRanges(); - } catch (e) { - me._bakNativeRange = null; - } - - } else { - try { - me._bakRange && me._bakRange.select(); - } catch (e) { - } - } - }); - } - //trace:1518 ff3.6body不够寛,会导致点击空白处无法获得焦点 - if (browser.gecko && browser.version <= 10902) { - //修复ff3.6初始化进来,不能点击获得焦点 - me.body.contentEditable = false; - setTimeout(function () { - me.body.contentEditable = true; - }, 100); - setInterval(function () { - me.body.style.height = me.iframe.offsetHeight - 20 + 'px' - }, 100) - } - - !options.isShow && me.setHide(); - options.readonly && me.setDisabled(); - }, - - /** - * 同步数据到编辑器所在的form - * 从编辑器的容器节点向上查找form元素,若找到,就同步编辑内容到找到的form里,为提交数据做准备,主要用于是手动提交的情况 - * 后台取得数据的键值,使用你容器上的name属性,如果没有就使用参数里的textarea项 - * @method sync - * @example - * ```javascript - * editor.sync(); - * form.sumbit(); //form变量已经指向了form元素 - * ``` - */ - - /** - * 根据传入的formId,在页面上查找要同步数据的表单,若找到,就同步编辑内容到找到的form里,为提交数据做准备 - * 后台取得数据的键值,该键值默认使用给定的编辑器容器的name属性,如果没有name属性则使用参数项里给定的“textarea”项 - * @method sync - * @param { String } formID 指定一个要同步数据的form的id,编辑器的数据会同步到你指定form下 - */ - sync: function (formId) { - var me = this, - form = formId ? document.getElementById(formId) : - domUtils.findParent(me.iframe.parentNode, function (node) { - return node.tagName == 'FORM' - }, true); - form && setValue(form, me); - }, - - /** - * 设置编辑器高度 - * @method setHeight - * @remind 当配置项autoHeightEnabled为真时,该方法无效 - * @param { Number } number 设置的高度值,纯数值,不带单位 - * @example - * ```javascript - * editor.setHeight(number); - * ``` - */ - setHeight: function (height,notSetHeight) { - if (height !== parseInt(this.iframe.parentNode.style.height)) { - this.iframe.parentNode.style.height = height + 'px'; - } - !notSetHeight && (this.options.minFrameHeight = this.options.initialFrameHeight = height); - this.body.style.height = height + 'px'; - !notSetHeight && this.trigger('setHeight') - }, - - /** - * 为编辑器的编辑命令提供快捷键 - * 这个接口是为插件扩展提供的接口,主要是为新添加的插件,如果需要添加快捷键,所提供的接口 - * @method addshortcutkey - * @param { Object } keyset 命令名和快捷键键值对对象,多个按钮的快捷键用“+”分隔 - * @example - * ```javascript - * editor.addshortcutkey({ - * "Bold" : "ctrl+66",//^B - * "Italic" : "ctrl+73", //^I - * }); - * ``` - */ - /** - * 这个接口是为插件扩展提供的接口,主要是为新添加的插件,如果需要添加快捷键,所提供的接口 - * @method addshortcutkey - * @param { String } cmd 触发快捷键时,响应的命令 - * @param { String } keys 快捷键的字符串,多个按钮用“+”分隔 - * @example - * ```javascript - * editor.addshortcutkey("Underline", "ctrl+85"); //^U - * ``` - */ - addshortcutkey: function (cmd, keys) { - var obj = {}; - if (keys) { - obj[cmd] = keys - } else { - obj = cmd; - } - utils.extend(this.shortcutkeys, obj) - }, - - /** - * 对编辑器设置keydown事件监听,绑定快捷键和命令,当快捷键组合触发成功,会响应对应的命令 - * @method _bindshortcutKeys - * @private - */ - _bindshortcutKeys: function () { - var me = this, shortcutkeys = this.shortcutkeys; - me.addListener('keydown', function (type, e) { - var keyCode = e.keyCode || e.which; - for (var i in shortcutkeys) { - var tmp = shortcutkeys[i].split(','); - for (var t = 0, ti; ti = tmp[t++];) { - ti = ti.split(':'); - var key = ti[0], param = ti[1]; - if (/^(ctrl)(\+shift)?\+(\d+)$/.test(key.toLowerCase()) || /^(\d+)$/.test(key)) { - if (( (RegExp.$1 == 'ctrl' ? (e.ctrlKey || e.metaKey) : 0) - && (RegExp.$2 != "" ? e[RegExp.$2.slice(1) + "Key"] : 1) - && keyCode == RegExp.$3 - ) || - keyCode == RegExp.$1 - ) { - if (me.queryCommandState(i,param) != -1) - me.execCommand(i, param); - domUtils.preventDefault(e); - } - } - } - - } - }); - }, - - /** - * 获取编辑器的内容 - * @method getContent - * @warning 该方法获取到的是经过编辑器内置的过滤规则进行过滤后得到的内容 - * @return { String } 编辑器的内容字符串, 如果编辑器的内容为空,或者是空的标签内容(如:”<p><br/></p>“), 则返回空字符串 - * @example - * ```javascript - * //编辑器html内容:

    123456

    - * var content = editor.getContent(); //返回值:

    123456

    - * ``` - */ - - /** - * 获取编辑器的内容。 可以通过参数定义编辑器内置的判空规则 - * @method getContent - * @param { Function } fn 自定的判空规则, 要求该方法返回一个boolean类型的值, - * 代表当前编辑器的内容是否空, - * 如果返回true, 则该方法将直接返回空字符串;如果返回false,则编辑器将返回 - * 经过内置过滤规则处理后的内容。 - * @remind 该方法在处理包含有初始化内容的时候能起到很好的作用。 - * @warning 该方法获取到的是经过编辑器内置的过滤规则进行过滤后得到的内容 - * @return { String } 编辑器的内容字符串 - * @example - * ```javascript - * // editor 是一个编辑器的实例 - * var content = editor.getContent( function ( editor ) { - * return editor.body.innerHTML === '欢迎使用UEditor'; //返回空字符串 - * } ); - * ``` - */ - getContent: function (cmd, fn,notSetCursor,ignoreBlank,formatter) { - var me = this; - if (cmd && utils.isFunction(cmd)) { - fn = cmd; - cmd = ''; - } - if (fn ? !fn() : !this.hasContents()) { - return ''; - } - me.fireEvent('beforegetcontent'); - var root = UE.htmlparser(me.body.innerHTML,ignoreBlank); - me.filterOutputRule(root); - me.fireEvent('aftergetcontent', cmd,root); - return root.toHtml(formatter); - }, - - /** - * 取得完整的html代码,可以直接显示成完整的html文档 - * @method getAllHtml - * @return { String } 编辑器的内容html文档字符串 - * @eaxmple - * ```javascript - * editor.getAllHtml(); //返回格式大致是: ...... - * ``` - */ - getAllHtml: function () { - var me = this, - headHtml = [], - html = ''; - me.fireEvent('getAllHtml', headHtml); - if (browser.ie && browser.version > 8) { - var headHtmlForIE9 = ''; - utils.each(me.document.styleSheets, function (si) { - headHtmlForIE9 += ( si.href ? '' : ''); - }); - utils.each(me.document.getElementsByTagName('script'), function (si) { - headHtmlForIE9 += si.outerHTML; - }); - - } - return '' + (me.options.charset ? '' : '') - + (headHtmlForIE9 || me.document.getElementsByTagName('head')[0].innerHTML) + headHtml.join('\n') + '' - + '' + me.getContent(null, null, true) + ''; - }, - - /** - * 得到编辑器的纯文本内容,但会保留段落格式 - * @method getPlainTxt - * @return { String } 编辑器带段落格式的纯文本内容字符串 - * @example - * ```javascript - * //编辑器html内容:

    1

    2

    - * console.log(editor.getPlainTxt()); //输出:"1\n2\n - * ``` - */ - getPlainTxt: function () { - var reg = new RegExp(domUtils.fillChar, 'g'), - html = this.body.innerHTML.replace(/[\n\r]/g, '');//ie要先去了\n在处理 - html = html.replace(/<(p|div)[^>]*>(| )<\/\1>/gi, '\n') - .replace(//gi, '\n') - .replace(/<[^>/]+>/g, '') - .replace(/(\n)?<\/([^>]+)>/g, function (a, b, c) { - return dtd.$block[c] ? '\n' : b ? b : ''; - }); - //取出来的空格会有c2a0会变成乱码,处理这种情况\u00a0 - return html.replace(reg, '').replace(/\u00a0/g, ' ').replace(/ /g, ' '); - }, - - /** - * 获取编辑器中的纯文本内容,没有段落格式 - * @method getContentTxt - * @return { String } 编辑器不带段落格式的纯文本内容字符串 - * @example - * ```javascript - * //编辑器html内容:

    1

    2

    - * console.log(editor.getPlainTxt()); //输出:"12 - * ``` - */ - getContentTxt: function () { - var reg = new RegExp(domUtils.fillChar, 'g'); - //取出来的空格会有c2a0会变成乱码,处理这种情况\u00a0 - return this.body[browser.ie ? 'innerText' : 'textContent'].replace(reg, '').replace(/\u00a0/g, ' '); - }, - - /** - * 设置编辑器的内容,可修改编辑器当前的html内容 - * @method setContent - * @warning 通过该方法插入的内容,是经过编辑器内置的过滤规则进行过滤后得到的内容 - * @warning 该方法会触发selectionchange事件 - * @param { String } html 要插入的html内容 - * @example - * ```javascript - * editor.getContent('

    test

    '); - * ``` - */ - - /** - * 设置编辑器的内容,可修改编辑器当前的html内容 - * @method setContent - * @warning 通过该方法插入的内容,是经过编辑器内置的过滤规则进行过滤后得到的内容 - * @warning 该方法会触发selectionchange事件 - * @param { String } html 要插入的html内容 - * @param { Boolean } isAppendTo 若传入true,不清空原来的内容,在最后插入内容,否则,清空内容再插入 - * @example - * ```javascript - * //假设设置前的编辑器内容是

    old text

    - * editor.setContent('

    new text

    ', true); //插入的结果是

    old text

    new text

    - * ``` - */ - setContent: function (html, isAppendTo, notFireSelectionchange) { - var me = this; - - me.fireEvent('beforesetcontent', html); - var root = UE.htmlparser(html); - me.filterInputRule(root); - html = root.toHtml(); - - me.body.innerHTML = (isAppendTo ? me.body.innerHTML : '') + html; - - - function isCdataDiv(node){ - return node.tagName == 'DIV' && node.getAttribute('cdata_tag'); - } - //给文本或者inline节点套p标签 - if (me.options.enterTag == 'p') { - - var child = this.body.firstChild, tmpNode; - if (!child || child.nodeType == 1 && - (dtd.$cdata[child.tagName] || isCdataDiv(child) || - domUtils.isCustomeNode(child) - ) - && child === this.body.lastChild) { - this.body.innerHTML = '

    ' + (browser.ie ? ' ' : '
    ') + '

    ' + this.body.innerHTML; - - } else { - var p = me.document.createElement('p'); - while (child) { - while (child && (child.nodeType == 3 || child.nodeType == 1 && dtd.p[child.tagName] && !dtd.$cdata[child.tagName])) { - tmpNode = child.nextSibling; - p.appendChild(child); - child = tmpNode; - } - if (p.firstChild) { - if (!child) { - me.body.appendChild(p); - break; - } else { - child.parentNode.insertBefore(p, child); - p = me.document.createElement('p'); - } - } - child = child.nextSibling; - } - } - } - me.fireEvent('aftersetcontent'); - me.fireEvent('contentchange'); - - !notFireSelectionchange && me._selectionChange(); - //清除保存的选区 - me._bakRange = me._bakIERange = me._bakNativeRange = null; - //trace:1742 setContent后gecko能得到焦点问题 - var geckoSel; - if (browser.gecko && (geckoSel = this.selection.getNative())) { - geckoSel.removeAllRanges(); - } - if(me.options.autoSyncData){ - me.form && setValue(me.form,me); - } - }, - - /** - * 让编辑器获得焦点,默认focus到编辑器头部 - * @method focus - * @example - * ```javascript - * editor.focus() - * ``` - */ - - /** - * 让编辑器获得焦点,toEnd确定focus位置 - * @method focus - * @param { Boolean } toEnd 默认focus到编辑器头部,toEnd为true时focus到内容尾部 - * @example - * ```javascript - * editor.focus(true) - * ``` - */ - focus: function (toEnd) { - try { - var me = this, - rng = me.selection.getRange(); - if (toEnd) { - var node = me.body.lastChild; - if(node && node.nodeType == 1 && !dtd.$empty[node.tagName]){ - if(domUtils.isEmptyBlock(node)){ - rng.setStartAtFirst(node) - }else{ - rng.setStartAtLast(node) - } - rng.collapse(true); - } - rng.setCursor(true); - } else { - if(!rng.collapsed && domUtils.isBody(rng.startContainer) && rng.startOffset == 0){ - - var node = me.body.firstChild; - if(node && node.nodeType == 1 && !dtd.$empty[node.tagName]){ - rng.setStartAtFirst(node).collapse(true); - } - } - - rng.select(true); - - } - this.fireEvent('focus selectionchange'); - } catch (e) { - } - - }, - isFocus:function(){ - return this.selection.isFocus(); - }, - blur:function(){ - var sel = this.selection.getNative(); - if(sel.empty && browser.ie){ - var nativeRng = document.body.createTextRange(); - nativeRng.moveToElementText(document.body); - nativeRng.collapse(true); - nativeRng.select(); - sel.empty() - }else{ - sel.removeAllRanges() - } - - //this.fireEvent('blur selectionchange'); - }, - /** - * 初始化UE事件及部分事件代理 - * @method _initEvents - * @private - */ - _initEvents: function () { - var me = this, - doc = me.document, - win = me.window; - me._proxyDomEvent = utils.bind(me._proxyDomEvent, me); - domUtils.on(doc, ['click', 'contextmenu', 'mousedown', 'keydown', 'keyup', 'keypress', 'mouseup', 'mouseover', 'mouseout', 'selectstart'], me._proxyDomEvent); - domUtils.on(win, ['focus', 'blur'], me._proxyDomEvent); - domUtils.on(me.body,'drop',function(e){ - //阻止ff下默认的弹出新页面打开图片 - if(browser.gecko && e.stopPropagation) { e.stopPropagation(); } - me.fireEvent('contentchange') - }); - domUtils.on(doc, ['mouseup', 'keydown'], function (evt) { - //特殊键不触发selectionchange - if (evt.type == 'keydown' && (evt.ctrlKey || evt.metaKey || evt.shiftKey || evt.altKey)) { - return; - } - if (evt.button == 2)return; - me._selectionChange(250, evt); - }); - }, - /** - * 触发事件代理 - * @method _proxyDomEvent - * @private - * @return { * } fireEvent的返回值 - * @see UE.EventBase:fireEvent(String) - */ - _proxyDomEvent: function (evt) { - if(this.fireEvent('before' + evt.type.replace(/^on/, '').toLowerCase()) === false){ - return false; - } - if(this.fireEvent(evt.type.replace(/^on/, ''), evt) === false){ - return false; - } - return this.fireEvent('after' + evt.type.replace(/^on/, '').toLowerCase()) - }, - /** - * 变化选区 - * @method _selectionChange - * @private - */ - _selectionChange: function (delay, evt) { - var me = this; - //有光标才做selectionchange 为了解决未focus时点击source不能触发更改工具栏状态的问题(source命令notNeedUndo=1) -// if ( !me.selection.isFocus() ){ -// return; -// } - - - var hackForMouseUp = false; - var mouseX, mouseY; - if (browser.ie && browser.version < 9 && evt && evt.type == 'mouseup') { - var range = this.selection.getRange(); - if (!range.collapsed) { - hackForMouseUp = true; - mouseX = evt.clientX; - mouseY = evt.clientY; - } - } - clearTimeout(_selectionChangeTimer); - _selectionChangeTimer = setTimeout(function () { - if (!me.selection || !me.selection.getNative()) { - return; - } - //修复一个IE下的bug: 鼠标点击一段已选择的文本中间时,可能在mouseup后的一段时间内取到的range是在selection的type为None下的错误值. - //IE下如果用户是拖拽一段已选择文本,则不会触发mouseup事件,所以这里的特殊处理不会对其有影响 - var ieRange; - if (hackForMouseUp && me.selection.getNative().type == 'None') { - ieRange = me.document.body.createTextRange(); - try { - ieRange.moveToPoint(mouseX, mouseY); - } catch (ex) { - ieRange = null; - } - } - var bakGetIERange; - if (ieRange) { - bakGetIERange = me.selection.getIERange; - me.selection.getIERange = function () { - return ieRange; - }; - } - me.selection.cache(); - if (bakGetIERange) { - me.selection.getIERange = bakGetIERange; - } - if (me.selection._cachedRange && me.selection._cachedStartElement) { - me.fireEvent('beforeselectionchange'); - // 第二个参数causeByUi为true代表由用户交互造成的selectionchange. - me.fireEvent('selectionchange', !!evt); - me.fireEvent('afterselectionchange'); - me.selection.clear(); - } - }, delay || 50); - }, - - /** - * 执行编辑命令 - * @method _callCmdFn - * @private - * @param { String } fnName 函数名称 - * @param { * } args 传给命令函数的参数 - * @return { * } 返回命令函数运行的返回值 - */ - _callCmdFn: function (fnName, args) { - var cmdName = args[0].toLowerCase(), - cmd, cmdFn; - cmd = this.commands[cmdName] || UE.commands[cmdName]; - cmdFn = cmd && cmd[fnName]; - //没有querycommandstate或者没有command的都默认返回0 - if ((!cmd || !cmdFn) && fnName == 'queryCommandState') { - return 0; - } else if (cmdFn) { - return cmdFn.apply(this, args); - } - }, - - /** - * 执行编辑命令cmdName,完成富文本编辑效果 - * @method execCommand - * @param { String } cmdName 需要执行的命令 - * @remind 具体命令的使用请参考命令列表 - * @return { * } 返回命令函数运行的返回值 - * @example - * ```javascript - * editor.execCommand(cmdName); - * ``` - */ - execCommand: function (cmdName) { - cmdName = cmdName.toLowerCase(); - var me = this, - result, - cmd = me.commands[cmdName] || UE.commands[cmdName]; - if (!cmd || !cmd.execCommand) { - return null; - } - if (!cmd.notNeedUndo && !me.__hasEnterExecCommand) { - me.__hasEnterExecCommand = true; - if (me.queryCommandState.apply(me,arguments) != -1) { - me.fireEvent('saveScene'); - me.fireEvent.apply(me, ['beforeexeccommand', cmdName].concat(arguments)); - result = this._callCmdFn('execCommand', arguments); - //保存场景时,做了内容对比,再看是否进行contentchange触发,这里多触发了一次,去掉 -// (!cmd.ignoreContentChange && !me._ignoreContentChange) && me.fireEvent('contentchange'); - me.fireEvent.apply(me, ['afterexeccommand', cmdName].concat(arguments)); - me.fireEvent('saveScene'); - } - me.__hasEnterExecCommand = false; - } else { - result = this._callCmdFn('execCommand', arguments); - (!me.__hasEnterExecCommand && !cmd.ignoreContentChange && !me._ignoreContentChange) && me.fireEvent('contentchange') - } - (!me.__hasEnterExecCommand && !cmd.ignoreContentChange && !me._ignoreContentChange) && me._selectionChange(); - return result; - }, - - /** - * 根据传入的command命令,查选编辑器当前的选区,返回命令的状态 - * @method queryCommandState - * @param { String } cmdName 需要查询的命令名称 - * @remind 具体命令的使用请参考命令列表 - * @return { Number } number 返回放前命令的状态,返回值三种情况:(-1|0|1) - * @example - * ```javascript - * editor.queryCommandState(cmdName) => (-1|0|1) - * ``` - * @see COMMAND.LIST - */ - queryCommandState: function (cmdName) { - return this._callCmdFn('queryCommandState', arguments); - }, - - /** - * 根据传入的command命令,查选编辑器当前的选区,根据命令返回相关的值 - * @method queryCommandValue - * @param { String } cmdName 需要查询的命令名称 - * @remind 具体命令的使用请参考命令列表 - * @remind 只有部分插件有此方法 - * @return { * } 返回每个命令特定的当前状态值 - * @grammar editor.queryCommandValue(cmdName) => {*} - * @see COMMAND.LIST - */ - queryCommandValue: function (cmdName) { - return this._callCmdFn('queryCommandValue', arguments); - }, - - /** - * 检查编辑区域中是否有内容 - * @method hasContents - * @remind 默认有文本内容,或者有以下节点都不认为是空 - * table,ul,ol,dl,iframe,area,base,col,hr,img,embed,input,link,meta,param - * @return { Boolean } 检查有内容返回true,否则返回false - * @example - * ```javascript - * editor.hasContents() - * ``` - */ - - /** - * 检查编辑区域中是否有内容,若包含参数tags中的节点类型,直接返回true - * @method hasContents - * @param { Array } tags 传入数组判断时用到的节点类型 - * @return { Boolean } 若文档中包含tags数组里对应的tag,返回true,否则返回false - * @example - * ```javascript - * editor.hasContents(['span']); - * ``` - */ - hasContents: function (tags) { - if (tags) { - for (var i = 0, ci; ci = tags[i++];) { - if (this.document.getElementsByTagName(ci).length > 0) { - return true; - } - } - } - if (!domUtils.isEmptyBlock(this.body)) { - return true - } - //随时添加,定义的特殊标签如果存在,不能认为是空 - tags = ['div']; - for (i = 0; ci = tags[i++];) { - var nodes = domUtils.getElementsByTagName(this.document, ci); - for (var n = 0, cn; cn = nodes[n++];) { - if (domUtils.isCustomeNode(cn)) { - return true; - } - } - } - return false; - }, - - /** - * 重置编辑器,可用来做多个tab使用同一个编辑器实例 - * @method reset - * @remind 此方法会清空编辑器内容,清空回退列表,会触发reset事件 - * @example - * ```javascript - * editor.reset() - * ``` - */ - reset: function () { - this.fireEvent('reset'); - }, - - /** - * 设置当前编辑区域可以编辑 - * @method setEnabled - * @example - * ```javascript - * editor.setEnabled() - * ``` - */ - setEnabled: function () { - var me = this, range; - if (me.body.contentEditable == 'false') { - me.body.contentEditable = true; - range = me.selection.getRange(); - //有可能内容丢失了 - try { - range.moveToBookmark(me.lastBk); - delete me.lastBk - } catch (e) { - range.setStartAtFirst(me.body).collapse(true) - } - range.select(true); - if (me.bkqueryCommandState) { - me.queryCommandState = me.bkqueryCommandState; - delete me.bkqueryCommandState; - } - if (me.bkqueryCommandValue) { - me.queryCommandValue = me.bkqueryCommandValue; - delete me.bkqueryCommandValue; - } - me.fireEvent('selectionchange'); - } - }, - enable: function () { - return this.setEnabled(); - }, - - /** 设置当前编辑区域不可编辑 - * @method setDisabled - */ - - /** 设置当前编辑区域不可编辑,except中的命令除外 - * @method setDisabled - * @param { String } except 例外命令的字符串 - * @remind 即使设置了disable,此处配置的例外命令仍然可以执行 - * @example - * ```javascript - * editor.setDisabled('bold'); //禁用工具栏中除加粗之外的所有功能 - * ``` - */ - - /** 设置当前编辑区域不可编辑,except中的命令除外 - * @method setDisabled - * @param { Array } except 例外命令的字符串数组,数组中的命令仍然可以执行 - * @remind 即使设置了disable,此处配置的例外命令仍然可以执行 - * @example - * ```javascript - * editor.setDisabled(['bold','insertimage']); //禁用工具栏中除加粗和插入图片之外的所有功能 - * ``` - */ - setDisabled: function (except) { - var me = this; - except = except ? utils.isArray(except) ? except : [except] : []; - if (me.body.contentEditable == 'true') { - if (!me.lastBk) { - me.lastBk = me.selection.getRange().createBookmark(true); - } - me.body.contentEditable = false; - me.bkqueryCommandState = me.queryCommandState; - me.bkqueryCommandValue = me.queryCommandValue; - me.queryCommandState = function (type) { - if (utils.indexOf(except, type) != -1) { - return me.bkqueryCommandState.apply(me, arguments); - } - return -1; - }; - me.queryCommandValue = function (type) { - if (utils.indexOf(except, type) != -1) { - return me.bkqueryCommandValue.apply(me, arguments); - } - return null; - }; - me.fireEvent('selectionchange'); - } - }, - disable: function (except) { - return this.setDisabled(except); - }, - - /** - * 设置默认内容 - * @method _setDefaultContent - * @private - * @param { String } cont 要存入的内容 - */ - _setDefaultContent: function () { - function clear() { - var me = this; - if (me.document.getElementById('initContent')) { - me.body.innerHTML = '

    ' + (ie ? '' : '
    ') + '

    '; - me.removeListener('firstBeforeExecCommand focus', clear); - setTimeout(function () { - me.focus(); - me._selectionChange(); - }, 0) - } - } - - return function (cont) { - var me = this; - me.body.innerHTML = '

    ' + cont + '

    '; - - me.addListener('firstBeforeExecCommand focus', clear); - } - }(), - - /** - * 显示编辑器 - * @method setShow - * @example - * ```javascript - * editor.setShow() - * ``` - */ - setShow: function () { - var me = this, range = me.selection.getRange(); - if (me.container.style.display == 'none') { - //有可能内容丢失了 - try { - range.moveToBookmark(me.lastBk); - delete me.lastBk - } catch (e) { - range.setStartAtFirst(me.body).collapse(true) - } - //ie下focus实效,所以做了个延迟 - setTimeout(function () { - range.select(true); - }, 100); - me.container.style.display = ''; - } - - }, - show: function () { - return this.setShow(); - }, - /** - * 隐藏编辑器 - * @method setHide - * @example - * ```javascript - * editor.setHide() - * ``` - */ - setHide: function () { - var me = this; - if (!me.lastBk) { - me.lastBk = me.selection.getRange().createBookmark(true); - } - me.container.style.display = 'none' - }, - hide: function () { - return this.setHide(); - }, - - /** - * 根据指定的路径,获取对应的语言资源 - * @method getLang - * @param { String } path 路径根据的是lang目录下的语言文件的路径结构 - * @return { Object | String } 根据路径返回语言资源的Json格式对象或者语言字符串 - * @example - * ```javascript - * editor.getLang('contextMenu.delete'); //如果当前是中文,那返回是的是'删除' - * ``` - */ - getLang: function (path) { - var lang = UE.I18N[this.options.lang]; - if (!lang) { - throw Error("not import language file"); - } - path = (path || "").split("."); - for (var i = 0, ci; ci = path[i++];) { - lang = lang[ci]; - if (!lang)break; - } - return lang; - }, - - /** - * 计算编辑器html内容字符串的长度 - * @method getContentLength - * @return { Number } 返回计算的长度 - * @example - * ```javascript - * //编辑器html内容

    132

    - * editor.getContentLength() //返回27 - * ``` - */ - /** - * 计算编辑器当前纯文本内容的长度 - * @method getContentLength - * @param { Boolean } ingoneHtml 传入true时,只按照纯文本来计算 - * @return { Number } 返回计算的长度,内容中有hr/img/iframe标签,长度加1 - * @example - * ```javascript - * //编辑器html内容

    132

    - * editor.getContentLength() //返回3 - * ``` - */ - getContentLength: function (ingoneHtml, tagNames) { - var count = this.getContent(false,false,true).length; - if (ingoneHtml) { - tagNames = (tagNames || []).concat([ 'hr', 'img', 'iframe']); - count = this.getContentTxt().replace(/[\t\r\n]+/g, '').length; - for (var i = 0, ci; ci = tagNames[i++];) { - count += this.document.getElementsByTagName(ci).length; - } - } - return count; - }, - - /** - * 注册输入过滤规则 - * @method addInputRule - * @param { Function } rule 要添加的过滤规则 - * @example - * ```javascript - * editor.addInputRule(function(root){ - * $.each(root.getNodesByTagName('div'),function(i,node){ - * node.tagName="p"; - * }); - * }); - * ``` - */ - addInputRule: function (rule) { - this.inputRules.push(rule); - }, - - /** - * 执行注册的过滤规则 - * @method filterInputRule - * @param { UE.uNode } root 要过滤的uNode节点 - * @remind 执行editor.setContent方法和执行'inserthtml'命令后,会运行该过滤函数 - * @example - * ```javascript - * editor.filterInputRule(editor.body); - * ``` - * @see UE.Editor:addInputRule - */ - filterInputRule: function (root) { - for (var i = 0, ci; ci = this.inputRules[i++];) { - ci.call(this, root) - } - }, - - /** - * 注册输出过滤规则 - * @method addOutputRule - * @param { Function } rule 要添加的过滤规则 - * @example - * ```javascript - * editor.addOutputRule(function(root){ - * $.each(root.getNodesByTagName('p'),function(i,node){ - * node.tagName="div"; - * }); - * }); - * ``` - */ - addOutputRule: function (rule) { - this.outputRules.push(rule) - }, - - /** - * 根据输出过滤规则,过滤编辑器内容 - * @method filterOutputRule - * @remind 执行editor.getContent方法的时候,会先运行该过滤函数 - * @param { UE.uNode } root 要过滤的uNode节点 - * @example - * ```javascript - * editor.filterOutputRule(editor.body); - * ``` - * @see UE.Editor:addOutputRule - */ - filterOutputRule: function (root) { - for (var i = 0, ci; ci = this.outputRules[i++];) { - ci.call(this, root) - } - }, - - /** - * 根据action名称获取请求的路径 - * @method getActionUrl - * @remind 假如没有设置serverUrl,会根据imageUrl设置默认的controller路径 - * @param { String } action action名称 - * @example - * ```javascript - * editor.getActionUrl('config'); //返回 "/ueditor/php/controller.php?action=config" - * editor.getActionUrl('image'); //返回 "/ueditor/php/controller.php?action=uplaodimage" - * editor.getActionUrl('scrawl'); //返回 "/ueditor/php/controller.php?action=uplaodscrawl" - * editor.getActionUrl('imageManager'); //返回 "/ueditor/php/controller.php?action=listimage" - * ``` - */ - getActionUrl: function(action){ - var actionName = this.getOpt(action) || action, - imageUrl = this.getOpt('imageUrl'), - serverUrl = this.getOpt('serverUrl'); - - if(!serverUrl && imageUrl) { - serverUrl = imageUrl.replace(/^(.*[\/]).+([\.].+)$/, '$1controller$2'); - } - - if(serverUrl) { - serverUrl = serverUrl + (serverUrl.indexOf('?') == -1 ? '?':'&') + 'action=' + (actionName || ''); - return utils.formatUrl(serverUrl); - } else { - return ''; - } - } - }; - utils.inherits(Editor, EventBase); -})(); - - -// core/Editor.defaultoptions.js -//维护编辑器一下默认的不在插件中的配置项 -UE.Editor.defaultOptions = function(editor){ - - var _url = editor.options.UEDITOR_HOME_URL; - return { - isShow: true, - initialContent: '', - initialStyle:'', - autoClearinitialContent: false, - iframeCssUrl: _url + 'themes/iframe.css', - textarea: 'editorValue', - focus: false, - focusInEnd: true, - autoClearEmptyNode: true, - fullscreen: false, - readonly: false, - zIndex: 999, - imagePopup: true, - enterTag: 'p', - customDomain: false, - lang: 'zh-cn', - langPath: _url + 'lang/', - theme: 'default', - themePath: _url + 'themes/', - allHtmlEnabled: false, - scaleEnabled: false, - tableNativeEditInFF: false, - autoSyncData : true, - fileNameFormat: '{time}{rand:6}' - } -}; - -// core/loadconfig.js -(function(){ - - UE.Editor.prototype.loadServerConfig = function(){ - var me = this; - setTimeout(function(){ - try{ - me.options.imageUrl && me.setOpt('serverUrl', me.options.imageUrl.replace(/^(.*[\/]).+([\.].+)$/, '$1controller$2')); - - var configUrl = me.getActionUrl('config'), - isJsonp = utils.isCrossDomainUrl(configUrl); - - /* 发出ajax请求 */ - me._serverConfigLoaded = false; - - configUrl && UE.ajax.request(configUrl,{ - 'method': 'GET', - 'dataType': isJsonp ? 'jsonp':'', - 'onsuccess':function(r){ - try { - var config = isJsonp ? r:eval("("+r.responseText+")"); - utils.extend(me.options, config); - me.fireEvent('serverConfigLoaded'); - me._serverConfigLoaded = true; - } catch (e) { - showErrorMsg(me.getLang('loadconfigFormatError')); - } - }, - 'onerror':function(){ - showErrorMsg(me.getLang('loadconfigHttpError')); - } - }); - } catch(e){ - showErrorMsg(me.getLang('loadconfigError')); - } - }); - - function showErrorMsg(msg) { - console && console.error(msg); - //me.fireEvent('showMessage', { - // 'title': msg, - // 'type': 'error' - //}); - } - }; - - UE.Editor.prototype.isServerConfigLoaded = function(){ - var me = this; - return me._serverConfigLoaded || false; - }; - - UE.Editor.prototype.afterConfigReady = function(handler){ - if (!handler || !utils.isFunction(handler)) return; - var me = this; - var readyHandler = function(){ - handler.apply(me, arguments); - me.removeListener('serverConfigLoaded', readyHandler); - }; - - if (me.isServerConfigLoaded()) { - handler.call(me, 'serverConfigLoaded'); - } else { - me.addListener('serverConfigLoaded', readyHandler); - } - }; - -})(); - - -// core/ajax.js -/** - * @file - * @module UE.ajax - * @since 1.2.6.1 - */ - -/** - * 提供对ajax请求的支持 - * @module UE.ajax - */ -UE.ajax = function() { - - //创建一个ajaxRequest对象 - var fnStr = 'XMLHttpRequest()'; - try { - new ActiveXObject("Msxml2.XMLHTTP"); - fnStr = 'ActiveXObject(\'Msxml2.XMLHTTP\')'; - } catch (e) { - try { - new ActiveXObject("Microsoft.XMLHTTP"); - fnStr = 'ActiveXObject(\'Microsoft.XMLHTTP\')' - } catch (e) { - } - } - var creatAjaxRequest = new Function('return new ' + fnStr); - - - /** - * 将json参数转化成适合ajax提交的参数列表 - * @param json - */ - function json2str(json) { - var strArr = []; - for (var i in json) { - //忽略默认的几个参数 - if(i=="method" || i=="timeout" || i=="async" || i=="dataType" || i=="callback") continue; - //忽略控制 - if(json[i] == undefined || json[i] == null) continue; - //传递过来的对象和函数不在提交之列 - if (!((typeof json[i]).toLowerCase() == "function" || (typeof json[i]).toLowerCase() == "object")) { - strArr.push( encodeURIComponent(i) + "="+encodeURIComponent(json[i]) ); - } else if (utils.isArray(json[i])) { - //支持传数组内容 - for(var j = 0; j < json[i].length; j++) { - strArr.push( encodeURIComponent(i) + "[]="+encodeURIComponent(json[i][j]) ); - } - } - } - return strArr.join("&"); - } - - function doAjax(url, ajaxOptions) { - var xhr = creatAjaxRequest(), - //是否超时 - timeIsOut = false, - //默认参数 - defaultAjaxOptions = { - method:"POST", - timeout:5000, - async:true, - data:{},//需要传递对象的话只能覆盖 - onsuccess:function() { - }, - onerror:function() { - } - }; - - if (typeof url === "object") { - ajaxOptions = url; - url = ajaxOptions.url; - } - if (!xhr || !url) return; - var ajaxOpts = ajaxOptions ? utils.extend(defaultAjaxOptions,ajaxOptions) : defaultAjaxOptions; - - var submitStr = json2str(ajaxOpts); // { name:"Jim",city:"Beijing" } --> "name=Jim&city=Beijing" - //如果用户直接通过data参数传递json对象过来,则也要将此json对象转化为字符串 - if (!utils.isEmptyObject(ajaxOpts.data)){ - submitStr += (submitStr? "&":"") + json2str(ajaxOpts.data); - } - //超时检测 - var timerID = setTimeout(function() { - if (xhr.readyState != 4) { - timeIsOut = true; - xhr.abort(); - clearTimeout(timerID); - } - }, ajaxOpts.timeout); - - var method = ajaxOpts.method.toUpperCase(); - var str = url + (url.indexOf("?")==-1?"?":"&") + (method=="POST"?"":submitStr+ "&noCache=" + +new Date); - xhr.open(method, str, ajaxOpts.async); - xhr.onreadystatechange = function() { - if (xhr.readyState == 4) { - if (!timeIsOut && xhr.status == 200) { - ajaxOpts.onsuccess(xhr); - } else { - ajaxOpts.onerror(xhr); - } - } - }; - if (method == "POST") { - xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); - xhr.send(submitStr); - } else { - xhr.send(null); - } - } - - function doJsonp(url, opts) { - - var successhandler = opts.onsuccess || function(){}, - scr = document.createElement('SCRIPT'), - options = opts || {}, - charset = options['charset'], - callbackField = options['jsonp'] || 'callback', - callbackFnName, - timeOut = options['timeOut'] || 0, - timer, - reg = new RegExp('(\\?|&)' + callbackField + '=([^&]*)'), - matches; - - if (utils.isFunction(successhandler)) { - callbackFnName = 'bd__editor__' + Math.floor(Math.random() * 2147483648).toString(36); - window[callbackFnName] = getCallBack(0); - } else if(utils.isString(successhandler)){ - callbackFnName = successhandler; - } else { - if (matches = reg.exec(url)) { - callbackFnName = matches[2]; - } - } - - url = url.replace(reg, '\x241' + callbackField + '=' + callbackFnName); - - if (url.search(reg) < 0) { - url += (url.indexOf('?') < 0 ? '?' : '&') + callbackField + '=' + callbackFnName; - } - - var queryStr = json2str(opts); // { name:"Jim",city:"Beijing" } --> "name=Jim&city=Beijing" - //如果用户直接通过data参数传递json对象过来,则也要将此json对象转化为字符串 - if (!utils.isEmptyObject(opts.data)){ - queryStr += (queryStr? "&":"") + json2str(opts.data); - } - if (queryStr) { - url = url.replace(/\?/, '?' + queryStr + '&'); - } - - scr.onerror = getCallBack(1); - if( timeOut ){ - timer = setTimeout(getCallBack(1), timeOut); - } - createScriptTag(scr, url, charset); - - function createScriptTag(scr, url, charset) { - scr.setAttribute('type', 'text/javascript'); - scr.setAttribute('defer', 'defer'); - charset && scr.setAttribute('charset', charset); - scr.setAttribute('src', url); - document.getElementsByTagName('head')[0].appendChild(scr); - } - - function getCallBack(onTimeOut){ - return function(){ - try { - if(onTimeOut){ - options.onerror && options.onerror(); - }else{ - try{ - clearTimeout(timer); - successhandler.apply(window, arguments); - } catch (e){} - } - } catch (exception) { - options.onerror && options.onerror.call(window, exception); - } finally { - options.oncomplete && options.oncomplete.apply(window, arguments); - scr.parentNode && scr.parentNode.removeChild(scr); - window[callbackFnName] = null; - try { - delete window[callbackFnName]; - }catch(e){} - } - } - } - } - - return { - /** - * 根据给定的参数项,向指定的url发起一个ajax请求。 ajax请求完成后,会根据请求结果调用相应回调: 如果请求 - * 成功, 则调用onsuccess回调, 失败则调用 onerror 回调 - * @method request - * @param { URLString } url ajax请求的url地址 - * @param { Object } ajaxOptions ajax请求选项的键值对,支持的选项如下: - * @example - * ```javascript - * //向sayhello.php发起一个异步的Ajax GET请求, 请求超时时间为10s, 请求完成后执行相应的回调。 - * UE.ajax.requeset( 'sayhello.php', { - * - * //请求方法。可选值: 'GET', 'POST',默认值是'POST' - * method: 'GET', - * - * //超时时间。 默认为5000, 单位是ms - * timeout: 10000, - * - * //是否是异步请求。 true为异步请求, false为同步请求 - * async: true, - * - * //请求携带的数据。如果请求为GET请求, data会经过stringify后附加到请求url之后。 - * data: { - * name: 'ueditor' - * }, - * - * //请求成功后的回调, 该回调接受当前的XMLHttpRequest对象作为参数。 - * onsuccess: function ( xhr ) { - * console.log( xhr.responseText ); - * }, - * - * //请求失败或者超时后的回调。 - * onerror: function ( xhr ) { - * alert( 'Ajax请求失败' ); - * } - * - * } ); - * ``` - */ - - /** - * 根据给定的参数项发起一个ajax请求, 参数项里必须包含一个url地址。 ajax请求完成后,会根据请求结果调用相应回调: 如果请求 - * 成功, 则调用onsuccess回调, 失败则调用 onerror 回调。 - * @method request - * @warning 如果在参数项里未提供一个key为“url”的地址值,则该请求将直接退出。 - * @param { Object } ajaxOptions ajax请求选项的键值对,支持的选项如下: - * @example - * ```javascript - * - * //向sayhello.php发起一个异步的Ajax POST请求, 请求超时时间为5s, 请求完成后不执行任何回调。 - * UE.ajax.requeset( 'sayhello.php', { - * - * //请求的地址, 该项是必须的。 - * url: 'sayhello.php' - * - * } ); - * ``` - */ - request:function(url, opts) { - if (opts && opts.dataType == 'jsonp') { - doJsonp(url, opts); - } else { - doAjax(url, opts); - } - }, - getJSONP:function(url, data, fn) { - var opts = { - 'data': data, - 'oncomplete': fn - }; - doJsonp(url, opts); - } - }; - - -}(); - - -// core/filterword.js -/** - * UE过滤word的静态方法 - * @file - */ - -/** - * UEditor公用空间,UEditor所有的功能都挂载在该空间下 - * @module UE - */ - - -/** - * 根据传入html字符串过滤word - * @module UE - * @since 1.2.6.1 - * @method filterWord - * @param { String } html html字符串 - * @return { String } 已过滤后的结果字符串 - * @example - * ```javascript - * UE.filterWord(html); - * ``` - */ -var filterWord = UE.filterWord = function () { - - //是否是word过来的内容 - function isWordDocument( str ) { - return /(class="?Mso|style="[^"]*\bmso\-|w:WordDocument|<(v|o):|lang=)/ig.test( str ); - } - //去掉小数 - function transUnit( v ) { - v = v.replace( /[\d.]+\w+/g, function ( m ) { - return utils.transUnitToPx(m); - } ); - return v; - } - - function filterPasteWord( str ) { - return str.replace(/[\t\r\n]+/g,' ') - .replace( //ig, "" ) - //转换图片 - .replace(/]*>[\s\S]*?.<\/v:shape>/gi,function(str){ - //opera能自己解析出image所这里直接返回空 - if(browser.opera){ - return ''; - } - try{ - //有可能是bitmap占为图,无用,直接过滤掉,主要体现在粘贴excel表格中 - if(/Bitmap/i.test(str)){ - return ''; - } - var width = str.match(/width:([ \d.]*p[tx])/i)[1], - height = str.match(/height:([ \d.]*p[tx])/i)[1], - src = str.match(/src=\s*"([^"]*)"/i)[1]; - return ''; - } catch(e){ - return ''; - } - }) - //针对wps添加的多余标签处理 - .replace(/<\/?div[^>]*>/g,'') - //去掉多余的属性 - .replace( /v:\w+=(["']?)[^'"]+\1/g, '' ) - .replace( /<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|xml|meta|link|style|\w+:\w+)(?=[\s\/>]))[^>]*>/gi, "" ) - .replace( /

    ]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi, "

    $1

    " ) - //去掉多余的属性 - .replace( /\s+(class|lang|align)\s*=\s*(['"]?)([\w-]+)\2/ig, function(str,name,marks,val){ - //保留list的标示 - return name == 'class' && val == 'MsoListParagraph' ? str : '' - }) - //清除多余的font/span不能匹配 有可能是空格 - .replace( /<(font|span)[^>]*>(\s*)<\/\1>/gi, function(a,b,c){ - return c.replace(/[\t\r\n ]+/g,' ') - }) - //处理style的问题 - .replace( /(<[a-z][^>]*)\sstyle=(["'])([^\2]*?)\2/gi, function( str, tag, tmp, style ) { - var n = [], - s = style.replace( /^\s+|\s+$/, '' ) - .replace(/'/g,'\'') - .replace( /"/gi, "'" ) - .replace(/[\d.]+(cm|pt)/g,function(str){ - return utils.transUnitToPx(str) - }) - .split( /;\s*/g ); - - for ( var i = 0,v; v = s[i];i++ ) { - - var name, value, - parts = v.split( ":" ); - - if ( parts.length == 2 ) { - name = parts[0].toLowerCase(); - value = parts[1].toLowerCase(); - if(/^(background)\w*/.test(name) && value.replace(/(initial|\s)/g,'').length == 0 - || - /^(margin)\w*/.test(name) && /^0\w+$/.test(value) - ){ - continue; - } - - switch ( name ) { - case "mso-padding-alt": - case "mso-padding-top-alt": - case "mso-padding-right-alt": - case "mso-padding-bottom-alt": - case "mso-padding-left-alt": - case "mso-margin-alt": - case "mso-margin-top-alt": - case "mso-margin-right-alt": - case "mso-margin-bottom-alt": - case "mso-margin-left-alt": - //ie下会出现挤到一起的情况 - //case "mso-table-layout-alt": - case "mso-height": - case "mso-width": - case "mso-vertical-align-alt": - //trace:1819 ff下会解析出padding在table上 - if(!/]/.test(html)) { - return UE.htmlparser(html).children[0] - } else { - return new uNode({ - type:'element', - children:[], - tagName:html - }) - } - }; - uNode.createText = function (data,noTrans) { - return new UE.uNode({ - type:'text', - 'data':noTrans ? data : utils.unhtml(data || '') - }) - }; - function nodeToHtml(node, arr, formatter, current) { - switch (node.type) { - case 'root': - for (var i = 0, ci; ci = node.children[i++];) { - //插入新行 - if (formatter && ci.type == 'element' && !dtd.$inlineWithA[ci.tagName] && i > 1) { - insertLine(arr, current, true); - insertIndent(arr, current) - } - nodeToHtml(ci, arr, formatter, current) - } - break; - case 'text': - isText(node, arr); - break; - case 'element': - isElement(node, arr, formatter, current); - break; - case 'comment': - isComment(node, arr, formatter); - } - return arr; - } - - function isText(node, arr) { - if(node.parentNode.tagName == 'pre'){ - //源码模式下输入html标签,不能做转换处理,直接输出 - arr.push(node.data) - }else{ - arr.push(notTransTagName[node.parentNode.tagName] ? utils.html(node.data) : node.data.replace(/[ ]{2}/g,'  ')) - } - - } - - function isElement(node, arr, formatter, current) { - var attrhtml = ''; - if (node.attrs) { - attrhtml = []; - var attrs = node.attrs; - for (var a in attrs) { - //这里就针对 - //

    '

    - //这里边的\"做转换,要不用innerHTML直接被截断了,属性src - //有可能做的不够 - attrhtml.push(a + (attrs[a] !== undefined ? '="' + (notTransAttrs[a] ? utils.html(attrs[a]).replace(/["]/g, function (a) { - return '"' - }) : utils.unhtml(attrs[a])) + '"' : '')) - } - attrhtml = attrhtml.join(' '); - } - arr.push('<' + node.tagName + - (attrhtml ? ' ' + attrhtml : '') + - (dtd.$empty[node.tagName] ? '\/' : '' ) + '>' - ); - //插入新行 - if (formatter && !dtd.$inlineWithA[node.tagName] && node.tagName != 'pre') { - if(node.children && node.children.length){ - current = insertLine(arr, current, true); - insertIndent(arr, current) - } - - } - if (node.children && node.children.length) { - for (var i = 0, ci; ci = node.children[i++];) { - if (formatter && ci.type == 'element' && !dtd.$inlineWithA[ci.tagName] && i > 1) { - insertLine(arr, current); - insertIndent(arr, current) - } - nodeToHtml(ci, arr, formatter, current) - } - } - if (!dtd.$empty[node.tagName]) { - if (formatter && !dtd.$inlineWithA[node.tagName] && node.tagName != 'pre') { - - if(node.children && node.children.length){ - current = insertLine(arr, current); - insertIndent(arr, current) - } - } - arr.push('<\/' + node.tagName + '>'); - } - - } - - function isComment(node, arr) { - arr.push(''); - } - - function getNodeById(root, id) { - var node; - if (root.type == 'element' && root.getAttr('id') == id) { - return root; - } - if (root.children && root.children.length) { - for (var i = 0, ci; ci = root.children[i++];) { - if (node = getNodeById(ci, id)) { - return node; - } - } - } - } - - function getNodesByTagName(node, tagName, arr) { - if (node.type == 'element' && node.tagName == tagName) { - arr.push(node); - } - if (node.children && node.children.length) { - for (var i = 0, ci; ci = node.children[i++];) { - getNodesByTagName(ci, tagName, arr) - } - } - } - function nodeTraversal(root,fn){ - if(root.children && root.children.length){ - for(var i= 0,ci;ci=root.children[i];){ - nodeTraversal(ci,fn); - //ci被替换的情况,这里就不再走 fn了 - if(ci.parentNode ){ - if(ci.children && ci.children.length){ - fn(ci) - } - if(ci.parentNode) i++ - } - } - }else{ - fn(root) - } - - } - uNode.prototype = { - - /** - * 当前节点对象,转换成html文本 - * @method toHtml - * @return { String } 返回转换后的html字符串 - * @example - * ```javascript - * node.toHtml(); - * ``` - */ - - /** - * 当前节点对象,转换成html文本 - * @method toHtml - * @param { Boolean } formatter 是否格式化返回值 - * @return { String } 返回转换后的html字符串 - * @example - * ```javascript - * node.toHtml( true ); - * ``` - */ - toHtml:function (formatter) { - var arr = []; - nodeToHtml(this, arr, formatter, 0); - return arr.join('') - }, - - /** - * 获取节点的html内容 - * @method innerHTML - * @warning 假如节点的type不是'element',或节点的标签名称不在dtd列表里,直接返回当前节点 - * @return { String } 返回节点的html内容 - * @example - * ```javascript - * var htmlstr = node.innerHTML(); - * ``` - */ - - /** - * 设置节点的html内容 - * @method innerHTML - * @warning 假如节点的type不是'element',或节点的标签名称不在dtd列表里,直接返回当前节点 - * @param { String } htmlstr 传入要设置的html内容 - * @return { UE.uNode } 返回节点本身 - * @example - * ```javascript - * node.innerHTML('text'); - * ``` - */ - innerHTML:function (htmlstr) { - if (this.type != 'element' || dtd.$empty[this.tagName]) { - return this; - } - if (utils.isString(htmlstr)) { - if(this.children){ - for (var i = 0, ci; ci = this.children[i++];) { - ci.parentNode = null; - } - } - this.children = []; - var tmpRoot = UE.htmlparser(htmlstr); - for (var i = 0, ci; ci = tmpRoot.children[i++];) { - this.children.push(ci); - ci.parentNode = this; - } - return this; - } else { - var tmpRoot = new UE.uNode({ - type:'root', - children:this.children - }); - return tmpRoot.toHtml(); - } - }, - - /** - * 获取节点的纯文本内容 - * @method innerText - * @warning 假如节点的type不是'element',或节点的标签名称不在dtd列表里,直接返回当前节点 - * @return { String } 返回节点的存文本内容 - * @example - * ```javascript - * var textStr = node.innerText(); - * ``` - */ - - /** - * 设置节点的纯文本内容 - * @method innerText - * @warning 假如节点的type不是'element',或节点的标签名称不在dtd列表里,直接返回当前节点 - * @param { String } textStr 传入要设置的文本内容 - * @return { UE.uNode } 返回节点本身 - * @example - * ```javascript - * node.innerText('text'); - * ``` - */ - innerText:function (textStr,noTrans) { - if (this.type != 'element' || dtd.$empty[this.tagName]) { - return this; - } - if (textStr) { - if(this.children){ - for (var i = 0, ci; ci = this.children[i++];) { - ci.parentNode = null; - } - } - this.children = []; - this.appendChild(uNode.createText(textStr,noTrans)); - return this; - } else { - return this.toHtml().replace(/<[^>]+>/g, ''); - } - }, - - /** - * 获取当前对象的data属性 - * @method getData - * @return { Object } 若节点的type值是elemenet,返回空字符串,否则返回节点的data属性 - * @example - * ```javascript - * node.getData(); - * ``` - */ - getData:function () { - if (this.type == 'element') - return ''; - return this.data - }, - - /** - * 获取当前节点下的第一个子节点 - * @method firstChild - * @return { UE.uNode } 返回第一个子节点 - * @example - * ```javascript - * node.firstChild(); //返回第一个子节点 - * ``` - */ - firstChild:function () { -// if (this.type != 'element' || dtd.$empty[this.tagName]) { -// return this; -// } - return this.children ? this.children[0] : null; - }, - - /** - * 获取当前节点下的最后一个子节点 - * @method lastChild - * @return { UE.uNode } 返回最后一个子节点 - * @example - * ```javascript - * node.lastChild(); //返回最后一个子节点 - * ``` - */ - lastChild:function () { -// if (this.type != 'element' || dtd.$empty[this.tagName] ) { -// return this; -// } - return this.children ? this.children[this.children.length - 1] : null; - }, - - /** - * 获取和当前节点有相同父亲节点的前一个节点 - * @method previousSibling - * @return { UE.uNode } 返回前一个节点 - * @example - * ```javascript - * node.children[2].previousSibling(); //返回子节点node.children[1] - * ``` - */ - previousSibling : function(){ - var parent = this.parentNode; - for (var i = 0, ci; ci = parent.children[i]; i++) { - if (ci === this) { - return i == 0 ? null : parent.children[i-1]; - } - } - - }, - - /** - * 获取和当前节点有相同父亲节点的后一个节点 - * @method nextSibling - * @return { UE.uNode } 返回后一个节点,找不到返回null - * @example - * ```javascript - * node.children[2].nextSibling(); //如果有,返回子节点node.children[3] - * ``` - */ - nextSibling : function(){ - var parent = this.parentNode; - for (var i = 0, ci; ci = parent.children[i++];) { - if (ci === this) { - return parent.children[i]; - } - } - }, - - /** - * 用新的节点替换当前节点 - * @method replaceChild - * @param { UE.uNode } target 要替换成该节点参数 - * @param { UE.uNode } source 要被替换掉的节点 - * @return { UE.uNode } 返回替换之后的节点对象 - * @example - * ```javascript - * node.replaceChild(newNode, childNode); //用newNode替换childNode,childNode是node的子节点 - * ``` - */ - replaceChild:function (target, source) { - if (this.children) { - if(target.parentNode){ - target.parentNode.removeChild(target); - } - for (var i = 0, ci; ci = this.children[i]; i++) { - if (ci === source) { - this.children.splice(i, 1, target); - source.parentNode = null; - target.parentNode = this; - return target; - } - } - } - }, - - /** - * 在节点的子节点列表最后位置插入一个节点 - * @method appendChild - * @param { UE.uNode } node 要插入的节点 - * @return { UE.uNode } 返回刚插入的子节点 - * @example - * ```javascript - * node.appendChild( newNode ); //在node内插入子节点newNode - * ``` - */ - appendChild:function (node) { - if (this.type == 'root' || (this.type == 'element' && !dtd.$empty[this.tagName])) { - if (!this.children) { - this.children = [] - } - if(node.parentNode){ - node.parentNode.removeChild(node); - } - for (var i = 0, ci; ci = this.children[i]; i++) { - if (ci === node) { - this.children.splice(i, 1); - break; - } - } - this.children.push(node); - node.parentNode = this; - return node; - } - - - }, - - /** - * 在传入节点的前面插入一个节点 - * @method insertBefore - * @param { UE.uNode } target 要插入的节点 - * @param { UE.uNode } source 在该参数节点前面插入 - * @return { UE.uNode } 返回刚插入的子节点 - * @example - * ```javascript - * node.parentNode.insertBefore(newNode, node); //在node节点后面插入newNode - * ``` - */ - insertBefore:function (target, source) { - if (this.children) { - if(target.parentNode){ - target.parentNode.removeChild(target); - } - for (var i = 0, ci; ci = this.children[i]; i++) { - if (ci === source) { - this.children.splice(i, 0, target); - target.parentNode = this; - return target; - } - } - - } - }, - - /** - * 在传入节点的后面插入一个节点 - * @method insertAfter - * @param { UE.uNode } target 要插入的节点 - * @param { UE.uNode } source 在该参数节点后面插入 - * @return { UE.uNode } 返回刚插入的子节点 - * @example - * ```javascript - * node.parentNode.insertAfter(newNode, node); //在node节点后面插入newNode - * ``` - */ - insertAfter:function (target, source) { - if (this.children) { - if(target.parentNode){ - target.parentNode.removeChild(target); - } - for (var i = 0, ci; ci = this.children[i]; i++) { - if (ci === source) { - this.children.splice(i + 1, 0, target); - target.parentNode = this; - return target; - } - - } - } - }, - - /** - * 从当前节点的子节点列表中,移除节点 - * @method removeChild - * @param { UE.uNode } node 要移除的节点引用 - * @param { Boolean } keepChildren 是否保留移除节点的子节点,若传入true,自动把移除节点的子节点插入到移除的位置 - * @return { * } 返回刚移除的子节点 - * @example - * ```javascript - * node.removeChild(childNode,true); //在node的子节点列表中移除child节点,并且吧child的子节点插入到移除的位置 - * ``` - */ - removeChild:function (node,keepChildren) { - if (this.children) { - for (var i = 0, ci; ci = this.children[i]; i++) { - if (ci === node) { - this.children.splice(i, 1); - ci.parentNode = null; - if(keepChildren && ci.children && ci.children.length){ - for(var j= 0,cj;cj=ci.children[j];j++){ - this.children.splice(i+j,0,cj); - cj.parentNode = this; - - } - } - return ci; - } - } - } - }, - - /** - * 获取当前节点所代表的元素属性,即获取attrs对象下的属性值 - * @method getAttr - * @param { String } attrName 要获取的属性名称 - * @return { * } 返回attrs对象下的属性值 - * @example - * ```javascript - * node.getAttr('title'); - * ``` - */ - getAttr:function (attrName) { - return this.attrs && this.attrs[attrName.toLowerCase()] - }, - - /** - * 设置当前节点所代表的元素属性,即设置attrs对象下的属性值 - * @method setAttr - * @param { String } attrName 要设置的属性名称 - * @param { * } attrVal 要设置的属性值,类型视设置的属性而定 - * @return { * } 返回attrs对象下的属性值 - * @example - * ```javascript - * node.setAttr('title','标题'); - * ``` - */ - setAttr:function (attrName, attrVal) { - if (!attrName) { - delete this.attrs; - return; - } - if(!this.attrs){ - this.attrs = {}; - } - if (utils.isObject(attrName)) { - for (var a in attrName) { - if (!attrName[a]) { - delete this.attrs[a] - } else { - this.attrs[a.toLowerCase()] = attrName[a]; - } - } - } else { - if (!attrVal) { - delete this.attrs[attrName] - } else { - this.attrs[attrName.toLowerCase()] = attrVal; - } - - } - }, - - /** - * 获取当前节点在父节点下的位置索引 - * @method getIndex - * @return { Number } 返回索引数值,如果没有父节点,返回-1 - * @example - * ```javascript - * node.getIndex(); - * ``` - */ - getIndex:function(){ - var parent = this.parentNode; - for(var i= 0,ci;ci=parent.children[i];i++){ - if(ci === this){ - return i; - } - } - return -1; - }, - - /** - * 在当前节点下,根据id查找节点 - * @method getNodeById - * @param { String } id 要查找的id - * @return { UE.uNode } 返回找到的节点 - * @example - * ```javascript - * node.getNodeById('textId'); - * ``` - */ - getNodeById:function (id) { - var node; - if (this.children && this.children.length) { - for (var i = 0, ci; ci = this.children[i++];) { - if (node = getNodeById(ci, id)) { - return node; - } - } - } - }, - - /** - * 在当前节点下,根据元素名称查找节点列表 - * @method getNodesByTagName - * @param { String } tagNames 要查找的元素名称 - * @return { Array } 返回找到的节点列表 - * @example - * ```javascript - * node.getNodesByTagName('span'); - * ``` - */ - getNodesByTagName:function (tagNames) { - tagNames = utils.trim(tagNames).replace(/[ ]{2,}/g, ' ').split(' '); - var arr = [], me = this; - utils.each(tagNames, function (tagName) { - if (me.children && me.children.length) { - for (var i = 0, ci; ci = me.children[i++];) { - getNodesByTagName(ci, tagName, arr) - } - } - }); - return arr; - }, - - /** - * 根据样式名称,获取节点的样式值 - * @method getStyle - * @param { String } name 要获取的样式名称 - * @return { String } 返回样式值 - * @example - * ```javascript - * node.getStyle('font-size'); - * ``` - */ - getStyle:function (name) { - var cssStyle = this.getAttr('style'); - if (!cssStyle) { - return '' - } - var reg = new RegExp('(^|;)\\s*' + name + ':([^;]+)','i'); - var match = cssStyle.match(reg); - if (match && match[0]) { - return match[2] - } - return ''; - }, - - /** - * 给节点设置样式 - * @method setStyle - * @param { String } name 要设置的的样式名称 - * @param { String } val 要设置的的样值 - * @example - * ```javascript - * node.setStyle('font-size', '12px'); - * ``` - */ - setStyle:function (name, val) { - function exec(name, val) { - var reg = new RegExp('(^|;)\\s*' + name + ':([^;]+;?)', 'gi'); - cssStyle = cssStyle.replace(reg, '$1'); - if (val) { - cssStyle = name + ':' + utils.unhtml(val) + ';' + cssStyle - } - - } - - var cssStyle = this.getAttr('style'); - if (!cssStyle) { - cssStyle = ''; - } - if (utils.isObject(name)) { - for (var a in name) { - exec(a, name[a]) - } - } else { - exec(name, val) - } - this.setAttr('style', utils.trim(cssStyle)) - }, - - /** - * 传入一个函数,递归遍历当前节点下的所有节点 - * @method traversal - * @param { Function } fn 遍历到节点的时,传入节点作为参数,运行此函数 - * @example - * ```javascript - * traversal(node, function(){ - * console.log(node.type); - * }); - * ``` - */ - traversal:function(fn){ - if(this.children && this.children.length){ - nodeTraversal(this,fn); - } - return this; - } - } -})(); - - -// core/htmlparser.js -/** - * html字符串转换成uNode节点 - * @file - * @module UE - * @since 1.2.6.1 - */ - -/** - * UEditor公用空间,UEditor所有的功能都挂载在该空间下 - * @unfile - * @module UE - */ - -/** - * html字符串转换成uNode节点的静态方法 - * @method htmlparser - * @param { String } htmlstr 要转换的html代码 - * @param { Boolean } ignoreBlank 若设置为true,转换的时候忽略\n\r\t等空白字符 - * @return { uNode } 给定的html片段转换形成的uNode对象 - * @example - * ```javascript - * var root = UE.htmlparser('

    htmlparser

    ', true); - * ``` - */ - -var htmlparser = UE.htmlparser = function (htmlstr,ignoreBlank) { - //todo 原来的方式 [^"'<>\/] 有\/就不能配对上 ') - } - html.push('') - } - //禁止指定table-width - return '
    这样的标签了 - //先去掉了,加上的原因忘了,这里先记录 - var re_tag = /<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\s\/<>]+)\s*((?:(?:"[^"]*")|(?:'[^']*')|[^"'<>])*)\/?>))/g, - re_attr = /([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g; - - //ie下取得的html可能会有\n存在,要去掉,在处理replace(/[\t\r\n]*/g,'');代码高量的\n不能去除 - var allowEmptyTags = { - b:1,code:1,i:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,span:1, - sub:1,img:1,sup:1,font:1,big:1,small:1,iframe:1,a:1,br:1,pre:1 - }; - htmlstr = htmlstr.replace(new RegExp(domUtils.fillChar, 'g'), ''); - if(!ignoreBlank){ - htmlstr = htmlstr.replace(new RegExp('[\\r\\t\\n'+(ignoreBlank?'':' ')+']*<\/?(\\w+)\\s*(?:[^>]*)>[\\r\\t\\n'+(ignoreBlank?'':' ')+']*','g'), function(a,b){ - //br暂时单独处理 - if(b && allowEmptyTags[b.toLowerCase()]){ - return a.replace(/(^[\n\r]+)|([\n\r]+$)/g,''); - } - return a.replace(new RegExp('^[\\r\\n'+(ignoreBlank?'':' ')+']+'),'').replace(new RegExp('[\\r\\n'+(ignoreBlank?'':' ')+']+$'),''); - }); - } - - var notTransAttrs = { - 'href':1, - 'src':1 - }; - - var uNode = UE.uNode, - needParentNode = { - 'td':'tr', - 'tr':['tbody','thead','tfoot'], - 'tbody':'table', - 'th':'tr', - 'thead':'table', - 'tfoot':'table', - 'caption':'table', - 'li':['ul', 'ol'], - 'dt':'dl', - 'dd':'dl', - 'option':'select' - }, - needChild = { - 'ol':'li', - 'ul':'li' - }; - - function text(parent, data) { - - if(needChild[parent.tagName]){ - var tmpNode = uNode.createElement(needChild[parent.tagName]); - parent.appendChild(tmpNode); - tmpNode.appendChild(uNode.createText(data)); - parent = tmpNode; - }else{ - - parent.appendChild(uNode.createText(data)); - } - } - - function element(parent, tagName, htmlattr) { - var needParentTag; - if (needParentTag = needParentNode[tagName]) { - var tmpParent = parent,hasParent; - while(tmpParent.type != 'root'){ - if(utils.isArray(needParentTag) ? utils.indexOf(needParentTag, tmpParent.tagName) != -1 : needParentTag == tmpParent.tagName){ - parent = tmpParent; - hasParent = true; - break; - } - tmpParent = tmpParent.parentNode; - } - if(!hasParent){ - parent = element(parent, utils.isArray(needParentTag) ? needParentTag[0] : needParentTag) - } - } - //按dtd处理嵌套 -// if(parent.type != 'root' && !dtd[parent.tagName][tagName]) -// parent = parent.parentNode; - var elm = new uNode({ - parentNode:parent, - type:'element', - tagName:tagName.toLowerCase(), - //是自闭合的处理一下 - children:dtd.$empty[tagName] ? null : [] - }); - //如果属性存在,处理属性 - if (htmlattr) { - var attrs = {}, match; - while (match = re_attr.exec(htmlattr)) { - attrs[match[1].toLowerCase()] = notTransAttrs[match[1].toLowerCase()] ? (match[2] || match[3] || match[4]) : utils.unhtml(match[2] || match[3] || match[4]) - } - elm.attrs = attrs; - } - //trace:3970 -// //如果parent下不能放elm -// if(dtd.$inline[parent.tagName] && dtd.$block[elm.tagName] && !dtd[parent.tagName][elm.tagName]){ -// parent = parent.parentNode; -// elm.parentNode = parent; -// } - parent.children.push(elm); - //如果是自闭合节点返回父亲节点 - return dtd.$empty[tagName] ? parent : elm - } - - function comment(parent, data) { - parent.children.push(new uNode({ - type:'comment', - data:data, - parentNode:parent - })); - } - - var match, currentIndex = 0, nextIndex = 0; - //设置根节点 - var root = new uNode({ - type:'root', - children:[] - }); - var currentParent = root; - - while (match = re_tag.exec(htmlstr)) { - currentIndex = match.index; - try{ - if (currentIndex > nextIndex) { - //text node - text(currentParent, htmlstr.slice(nextIndex, currentIndex)); - } - if (match[3]) { - - if(dtd.$cdata[currentParent.tagName]){ - text(currentParent, match[0]); - }else{ - //start tag - currentParent = element(currentParent, match[3].toLowerCase(), match[4]); - } - - - } else if (match[1]) { - if(currentParent.type != 'root'){ - if(dtd.$cdata[currentParent.tagName] && !dtd.$cdata[match[1]]){ - text(currentParent, match[0]); - }else{ - var tmpParent = currentParent; - while(currentParent.type == 'element' && currentParent.tagName != match[1].toLowerCase()){ - currentParent = currentParent.parentNode; - if(currentParent.type == 'root'){ - currentParent = tmpParent; - throw 'break' - } - } - //end tag - currentParent = currentParent.parentNode; - } - - } - - } else if (match[2]) { - //comment - comment(currentParent, match[2]) - } - }catch(e){} - - nextIndex = re_tag.lastIndex; - - } - //如果结束是文本,就有可能丢掉,所以这里手动判断一下 - //例如
  • sdfsdfsdf
  • sdfsdfsdfsdf - if (nextIndex < htmlstr.length) { - text(currentParent, htmlstr.slice(nextIndex)); - } - return root; -}; - - -// core/filternode.js -/** - * UE过滤节点的静态方法 - * @file - */ - -/** - * UEditor公用空间,UEditor所有的功能都挂载在该空间下 - * @module UE - */ - - -/** - * 根据传入节点和过滤规则过滤相应节点 - * @module UE - * @since 1.2.6.1 - * @method filterNode - * @param { Object } root 指定root节点 - * @param { Object } rules 过滤规则json对象 - * @example - * ```javascript - * UE.filterNode(root,editor.options.filterRules); - * ``` - */ -var filterNode = UE.filterNode = function () { - function filterNode(node,rules){ - switch (node.type) { - case 'text': - break; - case 'element': - var val; - if(val = rules[node.tagName]){ - if(val === '-'){ - node.parentNode.removeChild(node) - }else if(utils.isFunction(val)){ - var parentNode = node.parentNode, - index = node.getIndex(); - val(node); - if(node.parentNode){ - if(node.children){ - for(var i = 0,ci;ci=node.children[i];){ - filterNode(ci,rules); - if(ci.parentNode){ - i++; - } - } - } - }else{ - for(var i = index,ci;ci=parentNode.children[i];){ - filterNode(ci,rules); - if(ci.parentNode){ - i++; - } - } - } - - - }else{ - var attrs = val['$']; - if(attrs && node.attrs){ - var tmpAttrs = {},tmpVal; - for(var a in attrs){ - tmpVal = node.getAttr(a); - //todo 只先对style单独处理 - if(a == 'style' && utils.isArray(attrs[a])){ - var tmpCssStyle = []; - utils.each(attrs[a],function(v){ - var tmp; - if(tmp = node.getStyle(v)){ - tmpCssStyle.push(v + ':' + tmp); - } - }); - tmpVal = tmpCssStyle.join(';') - } - if(tmpVal){ - tmpAttrs[a] = tmpVal; - } - - } - node.attrs = tmpAttrs; - } - if(node.children){ - for(var i = 0,ci;ci=node.children[i];){ - filterNode(ci,rules); - if(ci.parentNode){ - i++; - } - } - } - } - }else{ - //如果不在名单里扣出子节点并删除该节点,cdata除外 - if(dtd.$cdata[node.tagName]){ - node.parentNode.removeChild(node) - }else{ - var parentNode = node.parentNode, - index = node.getIndex(); - node.parentNode.removeChild(node,true); - for(var i = index,ci;ci=parentNode.children[i];){ - filterNode(ci,rules); - if(ci.parentNode){ - i++; - } - } - } - } - break; - case 'comment': - node.parentNode.removeChild(node) - } - - } - return function(root,rules){ - if(utils.isEmptyObject(rules)){ - return root; - } - var val; - if(val = rules['-']){ - utils.each(val.split(' '),function(k){ - rules[k] = '-' - }) - } - for(var i= 0,ci;ci=root.children[i];){ - filterNode(ci,rules); - if(ci.parentNode){ - i++; - } - } - return root; - } -}(); - -// core/plugin.js -/** - * Created with JetBrains PhpStorm. - * User: campaign - * Date: 10/8/13 - * Time: 6:15 PM - * To change this template use File | Settings | File Templates. - */ -UE.plugin = function(){ - var _plugins = {}; - return { - register : function(pluginName,fn,oldOptionName,afterDisabled){ - if(oldOptionName && utils.isFunction(oldOptionName)){ - afterDisabled = oldOptionName; - oldOptionName = null - } - _plugins[pluginName] = { - optionName : oldOptionName || pluginName, - execFn : fn, - //当插件被禁用时执行 - afterDisabled : afterDisabled - } - }, - load : function(editor){ - utils.each(_plugins,function(plugin){ - var _export = plugin.execFn.call(editor); - if(editor.options[plugin.optionName] !== false){ - if(_export){ - //后边需要再做扩展 - utils.each(_export,function(v,k){ - switch(k.toLowerCase()){ - case 'shortcutkey': - editor.addshortcutkey(v); - break; - case 'bindevents': - utils.each(v,function(fn,eventName){ - editor.addListener(eventName,fn); - }); - break; - case 'bindmultievents': - utils.each(utils.isArray(v) ? v:[v],function(event){ - var types = utils.trim(event.type).split(/\s+/); - utils.each(types,function(eventName){ - editor.addListener(eventName, event.handler); - }); - }); - break; - case 'commands': - utils.each(v,function(execFn,execName){ - editor.commands[execName] = execFn - }); - break; - case 'outputrule': - editor.addOutputRule(v); - break; - case 'inputrule': - editor.addInputRule(v); - break; - case 'defaultoptions': - editor.setOpt(v) - } - }) - } - - }else if(plugin.afterDisabled){ - plugin.afterDisabled.call(editor) - } - - }); - //向下兼容 - utils.each(UE.plugins,function(plugin){ - plugin.call(editor); - }); - }, - run : function(pluginName,editor){ - var plugin = _plugins[pluginName]; - if(plugin){ - plugin.exeFn.call(editor) - } - } - } -}(); - -// core/keymap.js -var keymap = UE.keymap = { - 'Backspace' : 8, - 'Tab' : 9, - 'Enter' : 13, - - 'Shift':16, - 'Control':17, - 'Alt':18, - 'CapsLock':20, - - 'Esc':27, - - 'Spacebar':32, - - 'PageUp':33, - 'PageDown':34, - 'End':35, - 'Home':36, - - 'Left':37, - 'Up':38, - 'Right':39, - 'Down':40, - - 'Insert':45, - - 'Del':46, - - 'NumLock':144, - - 'Cmd':91, - - '=':187, - '-':189, - - "b":66, - 'i':73, - //回退 - 'z':90, - 'y':89, - //粘贴 - 'v' : 86, - 'x' : 88, - - 's' : 83, - - 'n' : 78 -}; - -// core/localstorage.js -//存储媒介封装 -var LocalStorage = UE.LocalStorage = (function () { - - var storage = window.localStorage || getUserData() || null, - LOCAL_FILE = 'localStorage'; - - return { - - saveLocalData: function (key, data) { - - if (storage && data) { - storage.setItem(key, data); - return true; - } - - return false; - - }, - - getLocalData: function (key) { - - if (storage) { - return storage.getItem(key); - } - - return null; - - }, - - removeItem: function (key) { - - storage && storage.removeItem(key); - - } - - }; - - function getUserData() { - - var container = document.createElement("div"); - container.style.display = "none"; - - if (!container.addBehavior) { - return null; - } - - container.addBehavior("#default#userdata"); - - return { - - getItem: function (key) { - - var result = null; - - try { - document.body.appendChild(container); - container.load(LOCAL_FILE); - result = container.getAttribute(key); - document.body.removeChild(container); - } catch (e) { - } - - return result; - - }, - - setItem: function (key, value) { - - document.body.appendChild(container); - container.setAttribute(key, value); - container.save(LOCAL_FILE); - document.body.removeChild(container); - - }, - - //// 暂时没有用到 - //clear: function () { - // - // var expiresTime = new Date(); - // expiresTime.setFullYear(expiresTime.getFullYear() - 1); - // document.body.appendChild(container); - // container.expires = expiresTime.toUTCString(); - // container.save(LOCAL_FILE); - // document.body.removeChild(container); - // - //}, - - removeItem: function (key) { - - document.body.appendChild(container); - container.removeAttribute(key); - container.save(LOCAL_FILE); - document.body.removeChild(container); - - } - - }; - - } - -})(); - -(function () { - - var ROOTKEY = 'ueditor_preference'; - - UE.Editor.prototype.setPreferences = function(key,value){ - var obj = {}; - if (utils.isString(key)) { - obj[ key ] = value; - } else { - obj = key; - } - var data = LocalStorage.getLocalData(ROOTKEY); - if (data && (data = utils.str2json(data))) { - utils.extend(data, obj); - } else { - data = obj; - } - data && LocalStorage.saveLocalData(ROOTKEY, utils.json2str(data)); - }; - - UE.Editor.prototype.getPreferences = function(key){ - var data = LocalStorage.getLocalData(ROOTKEY); - if (data && (data = utils.str2json(data))) { - return key ? data[key] : data - } - return null; - }; - - UE.Editor.prototype.removePreferences = function (key) { - var data = LocalStorage.getLocalData(ROOTKEY); - if (data && (data = utils.str2json(data))) { - data[key] = undefined; - delete data[key] - } - data && LocalStorage.saveLocalData(ROOTKEY, utils.json2str(data)); - }; - -})(); - - -// plugins/defaultfilter.js -///import core -///plugin 编辑器默认的过滤转换机制 - -UE.plugins['defaultfilter'] = function () { - var me = this; - me.setOpt({ - 'allowDivTransToP':true, - 'disabledTableInTable':true - }); - //默认的过滤处理 - //进入编辑器的内容处理 - me.addInputRule(function (root) { - var allowDivTransToP = this.options.allowDivTransToP; - var val; - function tdParent(node){ - while(node && node.type == 'element'){ - if(node.tagName == 'td'){ - return true; - } - node = node.parentNode; - } - return false; - } - //进行默认的处理 - root.traversal(function (node) { - if (node.type == 'element') { - if (!dtd.$cdata[node.tagName] && me.options.autoClearEmptyNode && dtd.$inline[node.tagName] && !dtd.$empty[node.tagName] && (!node.attrs || utils.isEmptyObject(node.attrs))) { - if (!node.firstChild()) node.parentNode.removeChild(node); - else if (node.tagName == 'span' && (!node.attrs || utils.isEmptyObject(node.attrs))) { - node.parentNode.removeChild(node, true) - } - return; - } - switch (node.tagName) { - case 'style': - case 'script': - node.setAttr({ - cdata_tag: node.tagName, - cdata_data: (node.innerHTML() || ''), - '_ue_custom_node_':'true' - }); - node.tagName = 'div'; - node.innerHTML(''); - break; - case 'a': - if (val = node.getAttr('href')) { - node.setAttr('_href', val) - } - break; - case 'img': - //todo base64暂时去掉,后边做远程图片上传后,干掉这个 - if (val = node.getAttr('src')) { - if (/^data:/.test(val)) { - node.parentNode.removeChild(node); - break; - } - } - node.setAttr('_src', node.getAttr('src')); - break; - case 'span': - if (browser.webkit && (val = node.getStyle('white-space'))) { - if (/nowrap|normal/.test(val)) { - node.setStyle('white-space', ''); - if (me.options.autoClearEmptyNode && utils.isEmptyObject(node.attrs)) { - node.parentNode.removeChild(node, true) - } - } - } - val = node.getAttr('id'); - if(val && /^_baidu_bookmark_/i.test(val)){ - node.parentNode.removeChild(node) - } - break; - case 'p': - if (val = node.getAttr('align')) { - node.setAttr('align'); - node.setStyle('text-align', val) - } - //trace:3431 -// var cssStyle = node.getAttr('style'); -// if (cssStyle) { -// cssStyle = cssStyle.replace(/(margin|padding)[^;]+/g, ''); -// node.setAttr('style', cssStyle) -// -// } - //p标签不允许嵌套 - utils.each(node.children,function(n){ - if(n.type == 'element' && n.tagName == 'p'){ - var next = n.nextSibling(); - node.parentNode.insertAfter(n,node); - var last = n; - while(next){ - var tmp = next.nextSibling(); - node.parentNode.insertAfter(next,last); - last = next; - next = tmp; - } - return false; - } - }); - if (!node.firstChild()) { - node.innerHTML(browser.ie ? ' ' : '
    ') - } - break; - case 'div': - if(node.getAttr('cdata_tag')){ - break; - } - //针对代码这里不处理插入代码的div - val = node.getAttr('class'); - if(val && /^line number\d+/.test(val)){ - break; - } - if(!allowDivTransToP){ - break; - } - var tmpNode, p = UE.uNode.createElement('p'); - while (tmpNode = node.firstChild()) { - if (tmpNode.type == 'text' || !UE.dom.dtd.$block[tmpNode.tagName]) { - p.appendChild(tmpNode); - } else { - if (p.firstChild()) { - node.parentNode.insertBefore(p, node); - p = UE.uNode.createElement('p'); - } else { - node.parentNode.insertBefore(tmpNode, node); - } - } - } - if (p.firstChild()) { - node.parentNode.insertBefore(p, node); - } - node.parentNode.removeChild(node); - break; - case 'dl': - node.tagName = 'ul'; - break; - case 'dt': - case 'dd': - node.tagName = 'li'; - break; - case 'li': - var className = node.getAttr('class'); - if (!className || !/list\-/.test(className)) { - node.setAttr() - } - var tmpNodes = node.getNodesByTagName('ol ul'); - UE.utils.each(tmpNodes, function (n) { - node.parentNode.insertAfter(n, node); - }); - break; - case 'td': - case 'th': - case 'caption': - if(!node.children || !node.children.length){ - node.appendChild(browser.ie11below ? UE.uNode.createText(' ') : UE.uNode.createElement('br')) - } - break; - case 'table': - if(me.options.disabledTableInTable && tdParent(node)){ - node.parentNode.insertBefore(UE.uNode.createText(node.innerText()),node); - node.parentNode.removeChild(node) - } - } - - } -// if(node.type == 'comment'){ -// node.parentNode.removeChild(node); -// } - }) - - }); - - //从编辑器出去的内容处理 - me.addOutputRule(function (root) { - - var val; - root.traversal(function (node) { - if (node.type == 'element') { - - if (me.options.autoClearEmptyNode && dtd.$inline[node.tagName] && !dtd.$empty[node.tagName] && (!node.attrs || utils.isEmptyObject(node.attrs))) { - - if (!node.firstChild()) node.parentNode.removeChild(node); - else if (node.tagName == 'span' && (!node.attrs || utils.isEmptyObject(node.attrs))) { - node.parentNode.removeChild(node, true) - } - return; - } - switch (node.tagName) { - case 'div': - if (val = node.getAttr('cdata_tag')) { - node.tagName = val; - node.appendChild(UE.uNode.createText(node.getAttr('cdata_data'))); - node.setAttr({cdata_tag: '', cdata_data: '','_ue_custom_node_':''}); - } - break; - case 'a': - if (val = node.getAttr('_href')) { - node.setAttr({ - 'href': utils.html(val), - '_href': '' - }) - } - break; - break; - case 'span': - val = node.getAttr('id'); - if(val && /^_baidu_bookmark_/i.test(val)){ - node.parentNode.removeChild(node) - } - break; - case 'img': - if (val = node.getAttr('_src')) { - node.setAttr({ - 'src': node.getAttr('_src'), - '_src': '' - }) - } - - - } - } - - }) - - - }); -}; - - -// plugins/inserthtml.js -/** - * 插入html字符串插件 - * @file - * @since 1.2.6.1 - */ - -/** - * 插入html代码 - * @command inserthtml - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { String } html 插入的html字符串 - * @remaind 插入的标签内容是在当前的选区位置上插入,如果当前是闭合状态,那直接插入内容, 如果当前是选中状态,将先清除当前选中内容后,再做插入 - * @warning 注意:该命令会对当前选区的位置,对插入的内容进行过滤转换处理。 过滤的规则遵循html语意化的原则。 - * @example - * ```javascript - * //xxx[BB]xxx 当前选区为非闭合选区,选中BB这两个文本 - * //执行命令,插入CC - * //插入后的效果 xxxCCxxx - * //

    xx|xxx

    当前选区为闭合状态 - * //插入

    CC

    - * //结果

    xx

    CC

    xxx

    - * //

    xxxx

    |

    xxx

    当前选区在两个p标签之间 - * //插入 xxxx - * //结果

    xxxx

    xxxx

    xxx

    - * ``` - */ - -UE.commands['inserthtml'] = { - execCommand: function (command,html,notNeedFilter){ - var me = this, - range, - div; - if(!html){ - return; - } - if(me.fireEvent('beforeinserthtml',html) === true){ - return; - } - range = me.selection.getRange(); - div = range.document.createElement( 'div' ); - div.style.display = 'inline'; - - if (!notNeedFilter) { - var root = UE.htmlparser(html); - //如果给了过滤规则就先进行过滤 - if(me.options.filterRules){ - UE.filterNode(root,me.options.filterRules); - } - //执行默认的处理 - me.filterInputRule(root); - html = root.toHtml() - } - div.innerHTML = utils.trim( html ); - - if ( !range.collapsed ) { - var tmpNode = range.startContainer; - if(domUtils.isFillChar(tmpNode)){ - range.setStartBefore(tmpNode) - } - tmpNode = range.endContainer; - if(domUtils.isFillChar(tmpNode)){ - range.setEndAfter(tmpNode) - } - range.txtToElmBoundary(); - //结束边界可能放到了br的前边,要把br包含进来 - // x[xxx]
    - if(range.endContainer && range.endContainer.nodeType == 1){ - tmpNode = range.endContainer.childNodes[range.endOffset]; - if(tmpNode && domUtils.isBr(tmpNode)){ - range.setEndAfter(tmpNode); - } - } - if(range.startOffset == 0){ - tmpNode = range.startContainer; - if(domUtils.isBoundaryNode(tmpNode,'firstChild') ){ - tmpNode = range.endContainer; - if(range.endOffset == (tmpNode.nodeType == 3 ? tmpNode.nodeValue.length : tmpNode.childNodes.length) && domUtils.isBoundaryNode(tmpNode,'lastChild')){ - me.body.innerHTML = '

    '+(browser.ie ? '' : '
    ')+'

    '; - range.setStart(me.body.firstChild,0).collapse(true) - - } - } - } - !range.collapsed && range.deleteContents(); - if(range.startContainer.nodeType == 1){ - var child = range.startContainer.childNodes[range.startOffset],pre; - if(child && domUtils.isBlockElm(child) && (pre = child.previousSibling) && domUtils.isBlockElm(pre)){ - range.setEnd(pre,pre.childNodes.length).collapse(); - while(child.firstChild){ - pre.appendChild(child.firstChild); - } - domUtils.remove(child); - } - } - - } - - - var child,parent,pre,tmp,hadBreak = 0, nextNode; - //如果当前位置选中了fillchar要干掉,要不会产生空行 - if(range.inFillChar()){ - child = range.startContainer; - if(domUtils.isFillChar(child)){ - range.setStartBefore(child).collapse(true); - domUtils.remove(child); - }else if(domUtils.isFillChar(child,true)){ - child.nodeValue = child.nodeValue.replace(fillCharReg,''); - range.startOffset--; - range.collapsed && range.collapse(true) - } - } - //列表单独处理 - var li = domUtils.findParentByTagName(range.startContainer,'li',true); - if(li){ - var next,last; - while(child = div.firstChild){ - //针对hr单独处理一下先 - while(child && (child.nodeType == 3 || !domUtils.isBlockElm(child) || child.tagName=='HR' )){ - next = child.nextSibling; - range.insertNode( child).collapse(); - last = child; - child = next; - - } - if(child){ - if(/^(ol|ul)$/i.test(child.tagName)){ - while(child.firstChild){ - last = child.firstChild; - domUtils.insertAfter(li,child.firstChild); - li = li.nextSibling; - } - domUtils.remove(child) - }else{ - var tmpLi; - next = child.nextSibling; - tmpLi = me.document.createElement('li'); - domUtils.insertAfter(li,tmpLi); - tmpLi.appendChild(child); - last = child; - child = next; - li = tmpLi; - } - } - } - li = domUtils.findParentByTagName(range.startContainer,'li',true); - if(domUtils.isEmptyBlock(li)){ - domUtils.remove(li) - } - if(last){ - - range.setStartAfter(last).collapse(true).select(true) - } - }else{ - while ( child = div.firstChild ) { - if(hadBreak){ - var p = me.document.createElement('p'); - while(child && (child.nodeType == 3 || !dtd.$block[child.tagName])){ - nextNode = child.nextSibling; - p.appendChild(child); - child = nextNode; - } - if(p.firstChild){ - - child = p - } - } - range.insertNode( child ); - nextNode = child.nextSibling; - if ( !hadBreak && child.nodeType == domUtils.NODE_ELEMENT && domUtils.isBlockElm( child ) ){ - - parent = domUtils.findParent( child,function ( node ){ return domUtils.isBlockElm( node ); } ); - if ( parent && parent.tagName.toLowerCase() != 'body' && !(dtd[parent.tagName][child.nodeName] && child.parentNode === parent)){ - if(!dtd[parent.tagName][child.nodeName]){ - pre = parent; - }else{ - tmp = child.parentNode; - while (tmp !== parent){ - pre = tmp; - tmp = tmp.parentNode; - - } - } - - - domUtils.breakParent( child, pre || tmp ); - //去掉break后前一个多余的节点

    |<[p> ==>

    |

    - var pre = child.previousSibling; - domUtils.trimWhiteTextNode(pre); - if(!pre.childNodes.length){ - domUtils.remove(pre); - } - //trace:2012,在非ie的情况,切开后剩下的节点有可能不能点入光标添加br占位 - - if(!browser.ie && - (next = child.nextSibling) && - domUtils.isBlockElm(next) && - next.lastChild && - !domUtils.isBr(next.lastChild)){ - next.appendChild(me.document.createElement('br')); - } - hadBreak = 1; - } - } - var next = child.nextSibling; - if(!div.firstChild && next && domUtils.isBlockElm(next)){ - - range.setStart(next,0).collapse(true); - break; - } - range.setEndAfter( child ).collapse(); - - } - - child = range.startContainer; - - if(nextNode && domUtils.isBr(nextNode)){ - domUtils.remove(nextNode) - } - //用chrome可能有空白展位符 - if(domUtils.isBlockElm(child) && domUtils.isEmptyNode(child)){ - if(nextNode = child.nextSibling){ - domUtils.remove(child); - if(nextNode.nodeType == 1 && dtd.$block[nextNode.tagName]){ - - range.setStart(nextNode,0).collapse(true).shrinkBoundary() - } - }else{ - - try{ - child.innerHTML = browser.ie ? domUtils.fillChar : '
    '; - }catch(e){ - range.setStartBefore(child); - domUtils.remove(child) - } - - } - - } - //加上true因为在删除表情等时会删两次,第一次是删的fillData - try{ - range.select(true); - }catch(e){} - - } - - - - setTimeout(function(){ - range = me.selection.getRange(); - range.scrollToView(me.autoHeightEnabled,me.autoHeightEnabled ? domUtils.getXY(me.iframe).y:0); - me.fireEvent('afterinserthtml', html); - },200); - } -}; - - -// plugins/autotypeset.js -/** - * 自动排版 - * @file - * @since 1.2.6.1 - */ - -/** - * 对当前编辑器的内容执行自动排版, 排版的行为根据config配置文件里的“autotypeset”选项进行控制。 - * @command autotypeset - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'autotypeset' ); - * ``` - */ - -UE.plugins['autotypeset'] = function(){ - - this.setOpt({'autotypeset': { - mergeEmptyline: true, //合并空行 - removeClass: true, //去掉冗余的class - removeEmptyline: false, //去掉空行 - textAlign:"left", //段落的排版方式,可以是 left,right,center,justify 去掉这个属性表示不执行排版 - imageBlockLine: 'center', //图片的浮动方式,独占一行剧中,左右浮动,默认: center,left,right,none 去掉这个属性表示不执行排版 - pasteFilter: false, //根据规则过滤没事粘贴进来的内容 - clearFontSize: false, //去掉所有的内嵌字号,使用编辑器默认的字号 - clearFontFamily: false, //去掉所有的内嵌字体,使用编辑器默认的字体 - removeEmptyNode: false, // 去掉空节点 - //可以去掉的标签 - removeTagNames: utils.extend({div:1},dtd.$removeEmpty), - indent: false, // 行首缩进 - indentValue : '2em', //行首缩进的大小 - bdc2sb: false, - tobdc: false - }}); - - var me = this, - opt = me.options.autotypeset, - remainClass = { - 'selectTdClass':1, - 'pagebreak':1, - 'anchorclass':1 - }, - remainTag = { - 'li':1 - }, - tags = { - div:1, - p:1, - //trace:2183 这些也认为是行 - blockquote:1,center:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1, - span:1 - }, - highlightCont; - //升级了版本,但配置项目里没有autotypeset - if(!opt){ - return; - } - - readLocalOpts(); - - function isLine(node,notEmpty){ - if(!node || node.nodeType == 3) - return 0; - if(domUtils.isBr(node)) - return 1; - if(node && node.parentNode && tags[node.tagName.toLowerCase()]){ - if(highlightCont && highlightCont.contains(node) - || - node.getAttribute('pagebreak') - ){ - return 0; - } - - return notEmpty ? !domUtils.isEmptyBlock(node) : domUtils.isEmptyBlock(node,new RegExp('[\\s'+domUtils.fillChar - +']','g')); - } - } - - function removeNotAttributeSpan(node){ - if(!node.style.cssText){ - domUtils.removeAttributes(node,['style']); - if(node.tagName.toLowerCase() == 'span' && domUtils.hasNoAttributes(node)){ - domUtils.remove(node,true); - } - } - } - function autotype(type,html){ - - var me = this,cont; - if(html){ - if(!opt.pasteFilter){ - return; - } - cont = me.document.createElement('div'); - cont.innerHTML = html.html; - }else{ - cont = me.document.body; - } - var nodes = domUtils.getElementsByTagName(cont,'*'); - - // 行首缩进,段落方向,段间距,段内间距 - for(var i=0,ci;ci=nodes[i++];){ - - if(me.fireEvent('excludeNodeinautotype',ci) === true){ - continue; - } - //font-size - if(opt.clearFontSize && ci.style.fontSize){ - domUtils.removeStyle(ci,'font-size'); - - removeNotAttributeSpan(ci); - - } - //font-family - if(opt.clearFontFamily && ci.style.fontFamily){ - domUtils.removeStyle(ci,'font-family'); - removeNotAttributeSpan(ci); - } - - if(isLine(ci)){ - //合并空行 - if(opt.mergeEmptyline ){ - var next = ci.nextSibling,tmpNode,isBr = domUtils.isBr(ci); - while(isLine(next)){ - tmpNode = next; - next = tmpNode.nextSibling; - if(isBr && (!next || next && !domUtils.isBr(next))){ - break; - } - domUtils.remove(tmpNode); - } - - } - //去掉空行,保留占位的空行 - if(opt.removeEmptyline && domUtils.inDoc(ci,cont) && !remainTag[ci.parentNode.tagName.toLowerCase()] ){ - if(domUtils.isBr(ci)){ - next = ci.nextSibling; - if(next && !domUtils.isBr(next)){ - continue; - } - } - domUtils.remove(ci); - continue; - - } - - } - if(isLine(ci,true) && ci.tagName != 'SPAN'){ - if(opt.indent){ - ci.style.textIndent = opt.indentValue; - } - if(opt.textAlign){ - ci.style.textAlign = opt.textAlign; - } - // if(opt.lineHeight) - // ci.style.lineHeight = opt.lineHeight + 'cm'; - - } - - //去掉class,保留的class不去掉 - if(opt.removeClass && ci.className && !remainClass[ci.className.toLowerCase()]){ - - if(highlightCont && highlightCont.contains(ci)){ - continue; - } - domUtils.removeAttributes(ci,['class']); - } - - //表情不处理 - if(opt.imageBlockLine && ci.tagName.toLowerCase() == 'img' && !ci.getAttribute('emotion')){ - if(html){ - var img = ci; - switch (opt.imageBlockLine){ - case 'left': - case 'right': - case 'none': - var pN = img.parentNode,tmpNode,pre,next; - while(dtd.$inline[pN.tagName] || pN.tagName == 'A'){ - pN = pN.parentNode; - } - tmpNode = pN; - if(tmpNode.tagName == 'P' && domUtils.getStyle(tmpNode,'text-align') == 'center'){ - if(!domUtils.isBody(tmpNode) && domUtils.getChildCount(tmpNode,function(node){return !domUtils.isBr(node) && !domUtils.isWhitespace(node)}) == 1){ - pre = tmpNode.previousSibling; - next = tmpNode.nextSibling; - if(pre && next && pre.nodeType == 1 && next.nodeType == 1 && pre.tagName == next.tagName && domUtils.isBlockElm(pre)){ - pre.appendChild(tmpNode.firstChild); - while(next.firstChild){ - pre.appendChild(next.firstChild); - } - domUtils.remove(tmpNode); - domUtils.remove(next); - }else{ - domUtils.setStyle(tmpNode,'text-align',''); - } - - - } - - - } - domUtils.setStyle(img,'float', opt.imageBlockLine); - break; - case 'center': - if(me.queryCommandValue('imagefloat') != 'center'){ - pN = img.parentNode; - domUtils.setStyle(img,'float','none'); - tmpNode = img; - while(pN && domUtils.getChildCount(pN,function(node){return !domUtils.isBr(node) && !domUtils.isWhitespace(node)}) == 1 - && (dtd.$inline[pN.tagName] || pN.tagName == 'A')){ - tmpNode = pN; - pN = pN.parentNode; - } - var pNode = me.document.createElement('p'); - domUtils.setAttributes(pNode,{ - - style:'text-align:center' - }); - tmpNode.parentNode.insertBefore(pNode,tmpNode); - pNode.appendChild(tmpNode); - domUtils.setStyle(tmpNode,'float',''); - - } - - - } - } else { - var range = me.selection.getRange(); - range.selectNode(ci).select(); - me.execCommand('imagefloat', opt.imageBlockLine); - } - - } - - //去掉冗余的标签 - if(opt.removeEmptyNode){ - if(opt.removeTagNames[ci.tagName.toLowerCase()] && domUtils.hasNoAttributes(ci) && domUtils.isEmptyBlock(ci)){ - domUtils.remove(ci); - } - } - } - if(opt.tobdc){ - var root = UE.htmlparser(cont.innerHTML); - root.traversal(function(node){ - if(node.type == 'text'){ - node.data = ToDBC(node.data) - } - }); - cont.innerHTML = root.toHtml() - } - if(opt.bdc2sb){ - var root = UE.htmlparser(cont.innerHTML); - root.traversal(function(node){ - if(node.type == 'text'){ - node.data = DBC2SB(node.data) - } - }); - cont.innerHTML = root.toHtml() - } - if(html){ - html.html = cont.innerHTML; - } - } - if(opt.pasteFilter){ - me.addListener('beforepaste',autotype); - } - - function DBC2SB(str) { - var result = ''; - for (var i = 0; i < str.length; i++) { - var code = str.charCodeAt(i); //获取当前字符的unicode编码 - if (code >= 65281 && code <= 65373)//在这个unicode编码范围中的是所有的英文字母已经各种字符 - { - result += String.fromCharCode(str.charCodeAt(i) - 65248); //把全角字符的unicode编码转换为对应半角字符的unicode码 - } else if (code == 12288)//空格 - { - result += String.fromCharCode(str.charCodeAt(i) - 12288 + 32); - } else { - result += str.charAt(i); - } - } - return result; - } - function ToDBC(txtstring) { - txtstring = utils.html(txtstring); - var tmp = ""; - var mark = "";/*用于判断,如果是html尖括里的标记,则不进行全角的转换*/ - for (var i = 0; i < txtstring.length; i++) { - if (txtstring.charCodeAt(i) == 32) { - tmp = tmp + String.fromCharCode(12288); - } - else if (txtstring.charCodeAt(i) < 127) { - tmp = tmp + String.fromCharCode(txtstring.charCodeAt(i) + 65248); - } - else { - tmp += txtstring.charAt(i); - } - } - return tmp; - } - - function readLocalOpts() { - var cookieOpt = me.getPreferences('autotypeset'); - utils.extend(me.options.autotypeset, cookieOpt); - } - - me.commands['autotypeset'] = { - execCommand:function () { - me.removeListener('beforepaste',autotype); - if(opt.pasteFilter){ - me.addListener('beforepaste',autotype); - } - autotype.call(me) - } - - }; - -}; - - - -// plugins/autosubmit.js -/** - * 快捷键提交 - * @file - * @since 1.2.6.1 - */ - -/** - * 提交表单 - * @command autosubmit - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'autosubmit' ); - * ``` - */ - -UE.plugin.register('autosubmit',function(){ - return { - shortcutkey:{ - "autosubmit":"ctrl+13" //手动提交 - }, - commands:{ - 'autosubmit':{ - execCommand:function () { - var me=this, - form = domUtils.findParentByTagName(me.iframe,"form", false); - if (form){ - if(me.fireEvent("beforesubmit")===false){ - return; - } - me.sync(); - form.submit(); - } - } - } - } - } -}); - -// plugins/background.js -/** - * 背景插件,为UEditor提供设置背景功能 - * @file - * @since 1.2.6.1 - */ -UE.plugin.register('background', function () { - var me = this, - cssRuleId = 'editor_background', - isSetColored, - reg = new RegExp('body[\\s]*\\{(.+)\\}', 'i'); - - function stringToObj(str) { - var obj = {}, styles = str.split(';'); - utils.each(styles, function (v) { - var index = v.indexOf(':'), - key = utils.trim(v.substr(0, index)).toLowerCase(); - key && (obj[key] = utils.trim(v.substr(index + 1) || '')); - }); - return obj; - } - - function setBackground(obj) { - if (obj) { - var styles = []; - for (var name in obj) { - if (obj.hasOwnProperty(name)) { - styles.push(name + ":" + obj[name] + '; '); - } - } - utils.cssRule(cssRuleId, styles.length ? ('body{' + styles.join("") + '}') : '', me.document); - } else { - utils.cssRule(cssRuleId, '', me.document) - } - } - //重写editor.hasContent方法 - - var orgFn = me.hasContents; - me.hasContents = function(){ - if(me.queryCommandValue('background')){ - return true - } - return orgFn.apply(me,arguments); - }; - return { - bindEvents: { - 'getAllHtml': function (type, headHtml) { - var body = this.body, - su = domUtils.getComputedStyle(body, "background-image"), - url = ""; - if (su.indexOf(me.options.imagePath) > 0) { - url = su.substring(su.indexOf(me.options.imagePath), su.length - 1).replace(/"|\(|\)/ig, ""); - } else { - url = su != "none" ? su.replace(/url\("?|"?\)/ig, "") : ""; - } - var html = ' '; - headHtml.push(html); - }, - 'aftersetcontent': function () { - if(isSetColored == false) setBackground(); - } - }, - inputRule: function (root) { - isSetColored = false; - utils.each(root.getNodesByTagName('p'), function (p) { - var styles = p.getAttr('data-background'); - if (styles) { - isSetColored = true; - setBackground(stringToObj(styles)); - p.parentNode.removeChild(p); - } - }) - }, - outputRule: function (root) { - var me = this, - styles = (utils.cssRule(cssRuleId, me.document) || '').replace(/[\n\r]+/g, '').match(reg); - if (styles) { - root.appendChild(UE.uNode.createElement('


    ')); - } - }, - commands: { - 'background': { - execCommand: function (cmd, obj) { - setBackground(obj); - }, - queryCommandValue: function () { - var me = this, - styles = (utils.cssRule(cssRuleId, me.document) || '').replace(/[\n\r]+/g, '').match(reg); - return styles ? stringToObj(styles[1]) : null; - }, - notNeedUndo: true - } - } - } -}); - -// plugins/image.js -/** - * 图片插入、排版插件 - * @file - * @since 1.2.6.1 - */ - -/** - * 图片对齐方式 - * @command imagefloat - * @method execCommand - * @remind 值center为独占一行居中 - * @param { String } cmd 命令字符串 - * @param { String } align 对齐方式,可传left、right、none、center - * @remaind center表示图片独占一行 - * @example - * ```javascript - * editor.execCommand( 'imagefloat', 'center' ); - * ``` - */ - -/** - * 如果选区所在位置是图片区域 - * @command imagefloat - * @method queryCommandValue - * @param { String } cmd 命令字符串 - * @return { String } 返回图片对齐方式 - * @example - * ```javascript - * editor.queryCommandValue( 'imagefloat' ); - * ``` - */ - -UE.commands['imagefloat'] = { - execCommand:function (cmd, align) { - var me = this, - range = me.selection.getRange(); - if (!range.collapsed) { - var img = range.getClosedNode(); - if (img && img.tagName == 'IMG') { - switch (align) { - case 'left': - case 'right': - case 'none': - var pN = img.parentNode, tmpNode, pre, next; - while (dtd.$inline[pN.tagName] || pN.tagName == 'A') { - pN = pN.parentNode; - } - tmpNode = pN; - if (tmpNode.tagName == 'P' && domUtils.getStyle(tmpNode, 'text-align') == 'center') { - if (!domUtils.isBody(tmpNode) && domUtils.getChildCount(tmpNode, function (node) { - return !domUtils.isBr(node) && !domUtils.isWhitespace(node); - }) == 1) { - pre = tmpNode.previousSibling; - next = tmpNode.nextSibling; - if (pre && next && pre.nodeType == 1 && next.nodeType == 1 && pre.tagName == next.tagName && domUtils.isBlockElm(pre)) { - pre.appendChild(tmpNode.firstChild); - while (next.firstChild) { - pre.appendChild(next.firstChild); - } - domUtils.remove(tmpNode); - domUtils.remove(next); - } else { - domUtils.setStyle(tmpNode, 'text-align', ''); - } - - - } - - range.selectNode(img).select(); - } - domUtils.setStyle(img, 'float', align == 'none' ? '' : align); - if(align == 'none'){ - domUtils.removeAttributes(img,'align'); - } - - break; - case 'center': - if (me.queryCommandValue('imagefloat') != 'center') { - pN = img.parentNode; - domUtils.setStyle(img, 'float', ''); - domUtils.removeAttributes(img,'align'); - tmpNode = img; - while (pN && domUtils.getChildCount(pN, function (node) { - return !domUtils.isBr(node) && !domUtils.isWhitespace(node); - }) == 1 - && (dtd.$inline[pN.tagName] || pN.tagName == 'A')) { - tmpNode = pN; - pN = pN.parentNode; - } - range.setStartBefore(tmpNode).setCursor(false); - pN = me.document.createElement('div'); - pN.appendChild(tmpNode); - domUtils.setStyle(tmpNode, 'float', ''); - - me.execCommand('insertHtml', '

    ' + pN.innerHTML + '

    '); - - tmpNode = me.document.getElementById('_img_parent_tmp'); - tmpNode.removeAttribute('id'); - tmpNode = tmpNode.firstChild; - range.selectNode(tmpNode).select(); - //去掉后边多余的元素 - next = tmpNode.parentNode.nextSibling; - if (next && domUtils.isEmptyNode(next)) { - domUtils.remove(next); - } - - } - - break; - } - - } - } - }, - queryCommandValue:function () { - var range = this.selection.getRange(), - startNode, floatStyle; - if (range.collapsed) { - return 'none'; - } - startNode = range.getClosedNode(); - if (startNode && startNode.nodeType == 1 && startNode.tagName == 'IMG') { - floatStyle = domUtils.getComputedStyle(startNode, 'float') || startNode.getAttribute('align'); - - if (floatStyle == 'none') { - floatStyle = domUtils.getComputedStyle(startNode.parentNode, 'text-align') == 'center' ? 'center' : floatStyle; - } - return { - left:1, - right:1, - center:1 - }[floatStyle] ? floatStyle : 'none'; - } - return 'none'; - - - }, - queryCommandState:function () { - var range = this.selection.getRange(), - startNode; - - if (range.collapsed) return -1; - - startNode = range.getClosedNode(); - if (startNode && startNode.nodeType == 1 && startNode.tagName == 'IMG') { - return 0; - } - return -1; - } -}; - - -/** - * 插入图片 - * @command insertimage - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { Object } opt 属性键值对,这些属性都将被复制到当前插入图片 - * @remind 该命令第二个参数可接受一个图片配置项对象的数组,可以插入多张图片, - * 此时数组的每一个元素都是一个Object类型的图片属性集合。 - * @example - * ```javascript - * editor.execCommand( 'insertimage', { - * src:'a/b/c.jpg', - * width:'100', - * height:'100' - * } ); - * ``` - * @example - * ```javascript - * editor.execCommand( 'insertimage', [{ - * src:'a/b/c.jpg', - * width:'100', - * height:'100' - * },{ - * src:'a/b/d.jpg', - * width:'100', - * height:'100' - * }] ); - * ``` - */ - -UE.commands['insertimage'] = { - execCommand:function (cmd, opt) { - - opt = utils.isArray(opt) ? opt : [opt]; - if (!opt.length) { - return; - } - var me = this, - range = me.selection.getRange(), - img = range.getClosedNode(); - - if(me.fireEvent('beforeinsertimage', opt) === true){ - return; - } - - function unhtmlData(imgCi) { - - utils.each('width,height,border,hspace,vspace'.split(','), function (item) { - - if (imgCi[item]) { - imgCi[item] = parseInt(imgCi[item], 10) || 0; - } - }); - - utils.each('src,_src'.split(','), function (item) { - - if (imgCi[item]) { - imgCi[item] = utils.unhtmlForUrl(imgCi[item]); - } - }); - utils.each('title,alt'.split(','), function (item) { - - if (imgCi[item]) { - imgCi[item] = utils.unhtml(imgCi[item]); - } - }); - } - - if (img && /img/i.test(img.tagName) && (img.className != "edui-faked-video" || img.className.indexOf("edui-upload-video")!=-1) && !img.getAttribute("word_img")) { - var first = opt.shift(); - var floatStyle = first['floatStyle']; - delete first['floatStyle']; -//// img.style.border = (first.border||0) +"px solid #000"; -//// img.style.margin = (first.margin||0) +"px"; -// img.style.cssText += ';margin:' + (first.margin||0) +"px;" + 'border:' + (first.border||0) +"px solid #000"; - domUtils.setAttributes(img, first); - me.execCommand('imagefloat', floatStyle); - if (opt.length > 0) { - range.setStartAfter(img).setCursor(false, true); - me.execCommand('insertimage', opt); - } - - } else { - var html = [], str = '', ci; - ci = opt[0]; - if (opt.length == 1) { - unhtmlData(ci); - - str = '' + ci.alt + ''; - if (ci['floatStyle'] == 'center') { - str = '

    ' + str + '

    '; - } - html.push(str); - - } else { - for (var i = 0; ci = opt[i++];) { - unhtmlData(ci); - str = '

    '; - html.push(str); - } - } - - me.execCommand('insertHtml', html.join('')); - } - - me.fireEvent('afterinsertimage', opt) - } -}; - - -// plugins/justify.js -/** - * 段落格式 - * @file - * @since 1.2.6.1 - */ - -/** - * 段落对齐方式 - * @command justify - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { String } align 对齐方式:left => 居左,right => 居右,center => 居中,justify => 两端对齐 - * @example - * ```javascript - * editor.execCommand( 'justify', 'center' ); - * ``` - */ -/** - * 如果选区所在位置是段落区域,返回当前段落对齐方式 - * @command justify - * @method queryCommandValue - * @param { String } cmd 命令字符串 - * @return { String } 返回段落对齐方式 - * @example - * ```javascript - * editor.queryCommandValue( 'justify' ); - * ``` - */ - -UE.plugins['justify']=function(){ - var me=this, - block = domUtils.isBlockElm, - defaultValue = { - left:1, - right:1, - center:1, - justify:1 - }, - doJustify = function (range, style) { - var bookmark = range.createBookmark(), - filterFn = function (node) { - return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' && !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace(node); - }; - - range.enlarge(true); - var bookmark2 = range.createBookmark(), - current = domUtils.getNextDomNode(bookmark2.start, false, filterFn), - tmpRange = range.cloneRange(), - tmpNode; - while (current && !(domUtils.getPosition(current, bookmark2.end) & domUtils.POSITION_FOLLOWING)) { - if (current.nodeType == 3 || !block(current)) { - tmpRange.setStartBefore(current); - while (current && current !== bookmark2.end && !block(current)) { - tmpNode = current; - current = domUtils.getNextDomNode(current, false, null, function (node) { - return !block(node); - }); - } - tmpRange.setEndAfter(tmpNode); - var common = tmpRange.getCommonAncestor(); - if (!domUtils.isBody(common) && block(common)) { - domUtils.setStyles(common, utils.isString(style) ? {'text-align':style} : style); - current = common; - } else { - var p = range.document.createElement('p'); - domUtils.setStyles(p, utils.isString(style) ? {'text-align':style} : style); - var frag = tmpRange.extractContents(); - p.appendChild(frag); - tmpRange.insertNode(p); - current = p; - } - current = domUtils.getNextDomNode(current, false, filterFn); - } else { - current = domUtils.getNextDomNode(current, true, filterFn); - } - } - return range.moveToBookmark(bookmark2).moveToBookmark(bookmark); - }; - - UE.commands['justify'] = { - execCommand:function (cmdName, align) { - var range = this.selection.getRange(), - txt; - - //闭合时单独处理 - if (range.collapsed) { - txt = this.document.createTextNode('p'); - range.insertNode(txt); - } - doJustify(range, align); - if (txt) { - range.setStartBefore(txt).collapse(true); - domUtils.remove(txt); - } - - range.select(); - - - return true; - }, - queryCommandValue:function () { - var startNode = this.selection.getStart(), - value = domUtils.getComputedStyle(startNode, 'text-align'); - return defaultValue[value] ? value : 'left'; - }, - queryCommandState:function () { - var start = this.selection.getStart(), - cell = start && domUtils.findParentByTagName(start, ["td", "th","caption"], true); - - return cell? -1:0; - } - - }; -}; - - -// plugins/font.js -/** - * 字体颜色,背景色,字号,字体,下划线,删除线 - * @file - * @since 1.2.6.1 - */ - -/** - * 字体颜色 - * @command forecolor - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { String } value 色值(必须十六进制) - * @example - * ```javascript - * editor.execCommand( 'forecolor', '#000' ); - * ``` - */ -/** - * 返回选区字体颜色 - * @command forecolor - * @method queryCommandValue - * @param { String } cmd 命令字符串 - * @return { String } 返回字体颜色 - * @example - * ```javascript - * editor.queryCommandValue( 'forecolor' ); - * ``` - */ - -/** - * 字体背景颜色 - * @command backcolor - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { String } value 色值(必须十六进制) - * @example - * ```javascript - * editor.execCommand( 'backcolor', '#000' ); - * ``` - */ -/** - * 返回选区字体颜色 - * @command backcolor - * @method queryCommandValue - * @param { String } cmd 命令字符串 - * @return { String } 返回字体背景颜色 - * @example - * ```javascript - * editor.queryCommandValue( 'backcolor' ); - * ``` - */ - -/** - * 字体大小 - * @command fontsize - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { String } value 字体大小 - * @example - * ```javascript - * editor.execCommand( 'fontsize', '14px' ); - * ``` - */ -/** - * 返回选区字体大小 - * @command fontsize - * @method queryCommandValue - * @param { String } cmd 命令字符串 - * @return { String } 返回字体大小 - * @example - * ```javascript - * editor.queryCommandValue( 'fontsize' ); - * ``` - */ - -/** - * 字体样式 - * @command fontfamily - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { String } value 字体样式 - * @example - * ```javascript - * editor.execCommand( 'fontfamily', '微软雅黑' ); - * ``` - */ -/** - * 返回选区字体样式 - * @command fontfamily - * @method queryCommandValue - * @param { String } cmd 命令字符串 - * @return { String } 返回字体样式 - * @example - * ```javascript - * editor.queryCommandValue( 'fontfamily' ); - * ``` - */ - -/** - * 字体下划线,与删除线互斥 - * @command underline - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'underline' ); - * ``` - */ - -/** - * 字体删除线,与下划线互斥 - * @command strikethrough - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'strikethrough' ); - * ``` - */ - -/** - * 字体边框 - * @command fontborder - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'fontborder' ); - * ``` - */ - -UE.plugins['font'] = function () { - var me = this, - fonts = { - 'forecolor': 'color', - 'backcolor': 'background-color', - 'fontsize': 'font-size', - 'fontfamily': 'font-family', - 'underline': 'text-decoration', - 'strikethrough': 'text-decoration', - 'fontborder': 'border' - }, - needCmd = {'underline': 1, 'strikethrough': 1, 'fontborder': 1}, - needSetChild = { - 'forecolor': 'color', - 'backcolor': 'background-color', - 'fontsize': 'font-size', - 'fontfamily': 'font-family' - - }; - me.setOpt({ - 'fontfamily': [ - { name: 'songti', val: '宋体,SimSun'}, - { name: 'yahei', val: '微软雅黑,Microsoft YaHei'}, - { name: 'kaiti', val: '楷体,楷体_GB2312, SimKai'}, - { name: 'heiti', val: '黑体, SimHei'}, - { name: 'lishu', val: '隶书, SimLi'}, - { name: 'andaleMono', val: 'andale mono'}, - { name: 'arial', val: 'arial, helvetica,sans-serif'}, - { name: 'arialBlack', val: 'arial black,avant garde'}, - { name: 'comicSansMs', val: 'comic sans ms'}, - { name: 'impact', val: 'impact,chicago'}, - { name: 'timesNewRoman', val: 'times new roman'} - ], - 'fontsize': [10, 11, 12, 14, 16, 18, 20, 24, 36] - }); - - function mergeWithParent(node){ - var parent; - while(parent = node.parentNode){ - if(parent.tagName == 'SPAN' && domUtils.getChildCount(parent,function(child){ - return !domUtils.isBookmarkNode(child) && !domUtils.isBr(child) - }) == 1) { - parent.style.cssText += node.style.cssText; - domUtils.remove(node,true); - node = parent; - - }else{ - break; - } - } - - } - function mergeChild(rng,cmdName,value){ - if(needSetChild[cmdName]){ - rng.adjustmentBoundary(); - if(!rng.collapsed && rng.startContainer.nodeType == 1){ - var start = rng.startContainer.childNodes[rng.startOffset]; - if(start && domUtils.isTagNode(start,'span')){ - var bk = rng.createBookmark(); - utils.each(domUtils.getElementsByTagName(start, 'span'), function (span) { - if (!span.parentNode || domUtils.isBookmarkNode(span))return; - if(cmdName == 'backcolor' && domUtils.getComputedStyle(span,'background-color').toLowerCase() === value){ - return; - } - domUtils.removeStyle(span,needSetChild[cmdName]); - if(span.style.cssText.replace(/^\s+$/,'').length == 0){ - domUtils.remove(span,true) - } - }); - rng.moveToBookmark(bk) - } - } - } - - } - function mergesibling(rng,cmdName,value) { - var collapsed = rng.collapsed, - bk = rng.createBookmark(), common; - if (collapsed) { - common = bk.start.parentNode; - while (dtd.$inline[common.tagName]) { - common = common.parentNode; - } - } else { - common = domUtils.getCommonAncestor(bk.start, bk.end); - } - utils.each(domUtils.getElementsByTagName(common, 'span'), function (span) { - if (!span.parentNode || domUtils.isBookmarkNode(span))return; - if (/\s*border\s*:\s*none;?\s*/i.test(span.style.cssText)) { - if(/^\s*border\s*:\s*none;?\s*$/.test(span.style.cssText)){ - domUtils.remove(span, true); - }else{ - domUtils.removeStyle(span,'border'); - } - return - } - if (/border/i.test(span.style.cssText) && span.parentNode.tagName == 'SPAN' && /border/i.test(span.parentNode.style.cssText)) { - span.style.cssText = span.style.cssText.replace(/border[^:]*:[^;]+;?/gi, ''); - } - if(!(cmdName=='fontborder' && value=='none')){ - var next = span.nextSibling; - while (next && next.nodeType == 1 && next.tagName == 'SPAN' ) { - if(domUtils.isBookmarkNode(next) && cmdName == 'fontborder') { - span.appendChild(next); - next = span.nextSibling; - continue; - } - if (next.style.cssText == span.style.cssText) { - domUtils.moveChild(next, span); - domUtils.remove(next); - } - if (span.nextSibling === next) - break; - next = span.nextSibling; - } - } - - - mergeWithParent(span); - if(browser.ie && browser.version > 8 ){ - //拷贝父亲们的特别的属性,这里只做背景颜色的处理 - var parent = domUtils.findParent(span,function(n){return n.tagName == 'SPAN' && /background-color/.test(n.style.cssText)}); - if(parent && !/background-color/.test(span.style.cssText)){ - span.style.backgroundColor = parent.style.backgroundColor; - } - } - - }); - rng.moveToBookmark(bk); - mergeChild(rng,cmdName,value) - } - - me.addInputRule(function (root) { - utils.each(root.getNodesByTagName('u s del font strike'), function (node) { - if (node.tagName == 'font') { - var cssStyle = []; - for (var p in node.attrs) { - switch (p) { - case 'size': - cssStyle.push('font-size:' + - ({ - '1':'10', - '2':'12', - '3':'16', - '4':'18', - '5':'24', - '6':'32', - '7':'48' - }[node.attrs[p]] || node.attrs[p]) + 'px'); - break; - case 'color': - cssStyle.push('color:' + node.attrs[p]); - break; - case 'face': - cssStyle.push('font-family:' + node.attrs[p]); - break; - case 'style': - cssStyle.push(node.attrs[p]); - } - } - node.attrs = { - 'style': cssStyle.join(';') - }; - } else { - var val = node.tagName == 'u' ? 'underline' : 'line-through'; - node.attrs = { - 'style': (node.getAttr('style') || '') + 'text-decoration:' + val + ';' - } - } - node.tagName = 'span'; - }); -// utils.each(root.getNodesByTagName('span'), function (node) { -// var val; -// if(val = node.getAttr('class')){ -// if(/fontstrikethrough/.test(val)){ -// node.setStyle('text-decoration','line-through'); -// if(node.attrs['class']){ -// node.attrs['class'] = node.attrs['class'].replace(/fontstrikethrough/,''); -// }else{ -// node.setAttr('class') -// } -// } -// if(/fontborder/.test(val)){ -// node.setStyle('border','1px solid #000'); -// if(node.attrs['class']){ -// node.attrs['class'] = node.attrs['class'].replace(/fontborder/,''); -// }else{ -// node.setAttr('class') -// } -// } -// } -// }); - }); -// me.addOutputRule(function(root){ -// utils.each(root.getNodesByTagName('span'), function (node) { -// var val; -// if(val = node.getStyle('text-decoration')){ -// if(/line-through/.test(val)){ -// if(node.attrs['class']){ -// node.attrs['class'] += ' fontstrikethrough'; -// }else{ -// node.setAttr('class','fontstrikethrough') -// } -// } -// -// node.setStyle('text-decoration') -// } -// if(val = node.getStyle('border')){ -// if(/1px/.test(val) && /solid/.test(val)){ -// if(node.attrs['class']){ -// node.attrs['class'] += ' fontborder'; -// -// }else{ -// node.setAttr('class','fontborder') -// } -// } -// node.setStyle('border') -// -// } -// }); -// }); - for (var p in fonts) { - (function (cmd, style) { - UE.commands[cmd] = { - execCommand: function (cmdName, value) { - value = value || (this.queryCommandState(cmdName) ? 'none' : cmdName == 'underline' ? 'underline' : - cmdName == 'fontborder' ? '1px solid #000' : - 'line-through'); - var me = this, - range = this.selection.getRange(), - text; - - if (value == 'default') { - - if (range.collapsed) { - text = me.document.createTextNode('font'); - range.insertNode(text).select(); - - } - me.execCommand('removeFormat', 'span,a', style); - if (text) { - range.setStartBefore(text).collapse(true); - domUtils.remove(text); - } - mergesibling(range,cmdName,value); - range.select() - } else { - if (!range.collapsed) { - if (needCmd[cmd] && me.queryCommandValue(cmd)) { - me.execCommand('removeFormat', 'span,a', style); - } - range = me.selection.getRange(); - - range.applyInlineStyle('span', {'style': style + ':' + value}); - mergesibling(range, cmdName,value); - range.select(); - } else { - - var span = domUtils.findParentByTagName(range.startContainer, 'span', true); - text = me.document.createTextNode('font'); - if (span && !span.children.length && !span[browser.ie ? 'innerText' : 'textContent'].replace(fillCharReg, '').length) { - //for ie hack when enter - range.insertNode(text); - if (needCmd[cmd]) { - range.selectNode(text).select(); - me.execCommand('removeFormat', 'span,a', style, null); - - span = domUtils.findParentByTagName(text, 'span', true); - range.setStartBefore(text); - - } - span && (span.style.cssText += ';' + style + ':' + value); - range.collapse(true).select(); - - - } else { - range.insertNode(text); - range.selectNode(text).select(); - span = range.document.createElement('span'); - - if (needCmd[cmd]) { - //a标签内的不处理跳过 - if (domUtils.findParentByTagName(text, 'a', true)) { - range.setStartBefore(text).setCursor(); - domUtils.remove(text); - return; - } - me.execCommand('removeFormat', 'span,a', style); - } - - span.style.cssText = style + ':' + value; - - - text.parentNode.insertBefore(span, text); - //修复,span套span 但样式不继承的问题 - if (!browser.ie || browser.ie && browser.version == 9) { - var spanParent = span.parentNode; - while (!domUtils.isBlockElm(spanParent)) { - if (spanParent.tagName == 'SPAN') { - //opera合并style不会加入";" - span.style.cssText = spanParent.style.cssText + ";" + span.style.cssText; - } - spanParent = spanParent.parentNode; - } - } - - - if (opera) { - setTimeout(function () { - range.setStart(span, 0).collapse(true); - mergesibling(range, cmdName,value); - range.select(); - }); - } else { - range.setStart(span, 0).collapse(true); - mergesibling(range,cmdName,value); - range.select(); - } - - //trace:981 - //domUtils.mergeToParent(span) - } - domUtils.remove(text); - } - - - } - return true; - }, - queryCommandValue: function (cmdName) { - var startNode = this.selection.getStart(); - - //trace:946 - if (cmdName == 'underline' || cmdName == 'strikethrough') { - var tmpNode = startNode, value; - while (tmpNode && !domUtils.isBlockElm(tmpNode) && !domUtils.isBody(tmpNode)) { - if (tmpNode.nodeType == 1) { - value = domUtils.getComputedStyle(tmpNode, style); - if (value != 'none') { - return value; - } - } - - tmpNode = tmpNode.parentNode; - } - return 'none'; - } - if (cmdName == 'fontborder') { - var tmp = startNode, val; - while (tmp && dtd.$inline[tmp.tagName]) { - if (val = domUtils.getComputedStyle(tmp, 'border')) { - - if (/1px/.test(val) && /solid/.test(val)) { - return val; - } - } - tmp = tmp.parentNode; - } - return '' - } - - if( cmdName == 'FontSize' ) { - var styleVal = domUtils.getComputedStyle(startNode, style), - tmp = /^([\d\.]+)(\w+)$/.exec( styleVal ); - - if( tmp ) { - - return Math.floor( tmp[1] ) + tmp[2]; - - } - - return styleVal; - - } - - return domUtils.getComputedStyle(startNode, style); - }, - queryCommandState: function (cmdName) { - if (!needCmd[cmdName]) - return 0; - var val = this.queryCommandValue(cmdName); - if (cmdName == 'fontborder') { - return /1px/.test(val) && /solid/.test(val) - } else { - return cmdName == 'underline' ? /underline/.test(val) : /line\-through/.test(val); - - } - - } - }; - })(p, fonts[p]); - } -}; - -// plugins/link.js -/** - * 超链接 - * @file - * @since 1.2.6.1 - */ - -/** - * 插入超链接 - * @command link - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { Object } options 设置自定义属性,例如:url、title、target - * @example - * ```javascript - * editor.execCommand( 'link', '{ - * url:'ueditor.baidu.com', - * title:'ueditor', - * target:'_blank' - * }' ); - * ``` - */ -/** - * 返回当前选中的第一个超链接节点 - * @command link - * @method queryCommandValue - * @param { String } cmd 命令字符串 - * @return { Element } 超链接节点 - * @example - * ```javascript - * editor.queryCommandValue( 'link' ); - * ``` - */ - -/** - * 取消超链接 - * @command unlink - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'unlink'); - * ``` - */ - -UE.plugins['link'] = function(){ - function optimize( range ) { - var start = range.startContainer,end = range.endContainer; - - if ( start = domUtils.findParentByTagName( start, 'a', true ) ) { - range.setStartBefore( start ); - } - if ( end = domUtils.findParentByTagName( end, 'a', true ) ) { - range.setEndAfter( end ); - } - } - - - UE.commands['unlink'] = { - execCommand : function() { - var range = this.selection.getRange(), - bookmark; - if(range.collapsed && !domUtils.findParentByTagName( range.startContainer, 'a', true )){ - return; - } - bookmark = range.createBookmark(); - optimize( range ); - range.removeInlineStyle( 'a' ).moveToBookmark( bookmark ).select(); - }, - queryCommandState : function(){ - return !this.highlight && this.queryCommandValue('link') ? 0 : -1; - } - - }; - function doLink(range,opt,me){ - var rngClone = range.cloneRange(), - link = me.queryCommandValue('link'); - optimize( range = range.adjustmentBoundary() ); - var start = range.startContainer; - if(start.nodeType == 1 && link){ - start = start.childNodes[range.startOffset]; - if(start && start.nodeType == 1 && start.tagName == 'A' && /^(?:https?|ftp|file)\s*:\s*\/\//.test(start[browser.ie?'innerText':'textContent'])){ - start[browser.ie ? 'innerText' : 'textContent'] = utils.html(opt.textValue||opt.href); - - } - } - if( !rngClone.collapsed || link){ - range.removeInlineStyle( 'a' ); - rngClone = range.cloneRange(); - } - - if ( rngClone.collapsed ) { - var a = range.document.createElement( 'a'), - text = ''; - if(opt.textValue){ - - text = utils.html(opt.textValue); - delete opt.textValue; - }else{ - text = utils.html(opt.href); - - } - domUtils.setAttributes( a, opt ); - start = domUtils.findParentByTagName( rngClone.startContainer, 'a', true ); - if(start && domUtils.isInNodeEndBoundary(rngClone,start)){ - range.setStartAfter(start).collapse(true); - - } - a[browser.ie ? 'innerText' : 'textContent'] = text; - range.insertNode(a).selectNode( a ); - } else { - range.applyInlineStyle( 'a', opt ); - - } - } - UE.commands['link'] = { - execCommand : function( cmdName, opt ) { - var range; - opt._href && (opt._href = utils.unhtml(opt._href,/[<">]/g)); - opt.href && (opt.href = utils.unhtml(opt.href,/[<">]/g)); - opt.textValue && (opt.textValue = utils.unhtml(opt.textValue,/[<">]/g)); - doLink(range=this.selection.getRange(),opt,this); - //闭合都不加占位符,如果加了会在a后边多个占位符节点,导致a是图片背景组成的列表,出现空白问题 - range.collapse().select(true); - - }, - queryCommandValue : function() { - var range = this.selection.getRange(), - node; - if ( range.collapsed ) { -// node = this.selection.getStart(); - //在ie下getstart()取值偏上了 - node = range.startContainer; - node = node.nodeType == 1 ? node : node.parentNode; - - if ( node && (node = domUtils.findParentByTagName( node, 'a', true )) && ! domUtils.isInNodeEndBoundary(range,node)) { - - return node; - } - } else { - //trace:1111 如果是

    xx

    startContainer是p就会找不到a - range.shrinkBoundary(); - var start = range.startContainer.nodeType == 3 || !range.startContainer.childNodes[range.startOffset] ? range.startContainer : range.startContainer.childNodes[range.startOffset], - end = range.endContainer.nodeType == 3 || range.endOffset == 0 ? range.endContainer : range.endContainer.childNodes[range.endOffset-1], - common = range.getCommonAncestor(); - node = domUtils.findParentByTagName( common, 'a', true ); - if ( !node && common.nodeType == 1){ - - var as = common.getElementsByTagName( 'a' ), - ps,pe; - - for ( var i = 0,ci; ci = as[i++]; ) { - ps = domUtils.getPosition( ci, start ),pe = domUtils.getPosition( ci,end); - if ( (ps & domUtils.POSITION_FOLLOWING || ps & domUtils.POSITION_CONTAINS) - && - (pe & domUtils.POSITION_PRECEDING || pe & domUtils.POSITION_CONTAINS) - ) { - node = ci; - break; - } - } - } - return node; - } - - }, - queryCommandState : function() { - //判断如果是视频的话连接不可用 - //fix 853 - var img = this.selection.getRange().getClosedNode(), - flag = img && (img.className == "edui-faked-video" || img.className.indexOf("edui-upload-video")!=-1); - return flag ? -1 : 0; - } - }; -}; - -// plugins/iframe.js -///import core -///import plugins\inserthtml.js -///commands 插入框架 -///commandsName InsertFrame -///commandsTitle 插入Iframe -///commandsDialog dialogs\insertframe - -UE.plugins['insertframe'] = function() { - var me =this; - function deleteIframe(){ - me._iframe && delete me._iframe; - } - - me.addListener("selectionchange",function(){ - deleteIframe(); - }); - -}; - - - -// plugins/scrawl.js -///import core -///commands 涂鸦 -///commandsName Scrawl -///commandsTitle 涂鸦 -///commandsDialog dialogs\scrawl -UE.commands['scrawl'] = { - queryCommandState : function(){ - return ( browser.ie && browser.version <= 8 ) ? -1 :0; - } -}; - - -// plugins/removeformat.js -/** - * 清除格式 - * @file - * @since 1.2.6.1 - */ - -/** - * 清除文字样式 - * @command removeformat - * @method execCommand - * @param { String } cmd 命令字符串 - * @param {String} tags 以逗号隔开的标签。如:strong - * @param {String} style 样式如:color - * @param {String} attrs 属性如:width - * @example - * ```javascript - * editor.execCommand( 'removeformat', 'strong','color','width' ); - * ``` - */ - -UE.plugins['removeformat'] = function(){ - var me = this; - me.setOpt({ - 'removeFormatTags': 'b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var', - 'removeFormatAttributes':'class,style,lang,width,height,align,hspace,valign' - }); - me.commands['removeformat'] = { - execCommand : function( cmdName, tags, style, attrs,notIncludeA ) { - - var tagReg = new RegExp( '^(?:' + (tags || this.options.removeFormatTags).replace( /,/g, '|' ) + ')$', 'i' ) , - removeFormatAttributes = style ? [] : (attrs || this.options.removeFormatAttributes).split( ',' ), - range = new dom.Range( this.document ), - bookmark,node,parent, - filter = function( node ) { - return node.nodeType == 1; - }; - - function isRedundantSpan (node) { - if (node.nodeType == 3 || node.tagName.toLowerCase() != 'span'){ - return 0; - } - if (browser.ie) { - //ie 下判断实效,所以只能简单用style来判断 - //return node.style.cssText == '' ? 1 : 0; - var attrs = node.attributes; - if ( attrs.length ) { - for ( var i = 0,l = attrs.length; i - var node = range.startContainer, - tmp, - collapsed = range.collapsed; - while(node.nodeType == 1 && domUtils.isEmptyNode(node) && dtd.$removeEmpty[node.tagName]){ - tmp = node.parentNode; - range.setStartBefore(node); - //trace:937 - //更新结束边界 - if(range.startContainer === range.endContainer){ - range.endOffset--; - } - domUtils.remove(node); - node = tmp; - } - - if(!collapsed){ - node = range.endContainer; - while(node.nodeType == 1 && domUtils.isEmptyNode(node) && dtd.$removeEmpty[node.tagName]){ - tmp = node.parentNode; - range.setEndBefore(node); - domUtils.remove(node); - - node = tmp; - } - - - } - } - - - - range = this.selection.getRange(); - doRemove( range ); - range.select(); - - } - - }; - -}; - - -// plugins/blockquote.js -/** - * 添加引用 - * @file - * @since 1.2.6.1 - */ - -/** - * 添加引用 - * @command blockquote - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'blockquote' ); - * ``` - */ - -/** - * 添加引用 - * @command blockquote - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { Object } attrs 节点属性 - * @example - * ```javascript - * editor.execCommand( 'blockquote',{ - * style: "color: red;" - * } ); - * ``` - */ - - -UE.plugins['blockquote'] = function(){ - var me = this; - function getObj(editor){ - return domUtils.filterNodeList(editor.selection.getStartElementPath(),'blockquote'); - } - me.commands['blockquote'] = { - execCommand : function( cmdName, attrs ) { - var range = this.selection.getRange(), - obj = getObj(this), - blockquote = dtd.blockquote, - bookmark = range.createBookmark(); - - if ( obj ) { - - var start = range.startContainer, - startBlock = domUtils.isBlockElm(start) ? start : domUtils.findParent(start,function(node){return domUtils.isBlockElm(node)}), - - end = range.endContainer, - endBlock = domUtils.isBlockElm(end) ? end : domUtils.findParent(end,function(node){return domUtils.isBlockElm(node)}); - - //处理一下li - startBlock = domUtils.findParentByTagName(startBlock,'li',true) || startBlock; - endBlock = domUtils.findParentByTagName(endBlock,'li',true) || endBlock; - - - if(startBlock.tagName == 'LI' || startBlock.tagName == 'TD' || startBlock === obj || domUtils.isBody(startBlock)){ - domUtils.remove(obj,true); - }else{ - domUtils.breakParent(startBlock,obj); - } - - if(startBlock !== endBlock){ - obj = domUtils.findParentByTagName(endBlock,'blockquote'); - if(obj){ - if(endBlock.tagName == 'LI' || endBlock.tagName == 'TD'|| domUtils.isBody(endBlock)){ - obj.parentNode && domUtils.remove(obj,true); - }else{ - domUtils.breakParent(endBlock,obj); - } - - } - } - - var blockquotes = domUtils.getElementsByTagName(this.document,'blockquote'); - for(var i=0,bi;bi=blockquotes[i++];){ - if(!bi.childNodes.length){ - domUtils.remove(bi); - }else if(domUtils.getPosition(bi,startBlock)&domUtils.POSITION_FOLLOWING && domUtils.getPosition(bi,endBlock)&domUtils.POSITION_PRECEDING){ - domUtils.remove(bi,true); - } - } - - - - - } else { - - var tmpRange = range.cloneRange(), - node = tmpRange.startContainer.nodeType == 1 ? tmpRange.startContainer : tmpRange.startContainer.parentNode, - preNode = node, - doEnd = 1; - - //调整开始 - while ( 1 ) { - if ( domUtils.isBody(node) ) { - if ( preNode !== node ) { - if ( range.collapsed ) { - tmpRange.selectNode( preNode ); - doEnd = 0; - } else { - tmpRange.setStartBefore( preNode ); - } - }else{ - tmpRange.setStart(node,0); - } - - break; - } - if ( !blockquote[node.tagName] ) { - if ( range.collapsed ) { - tmpRange.selectNode( preNode ); - } else{ - tmpRange.setStartBefore( preNode); - } - break; - } - - preNode = node; - node = node.parentNode; - } - - //调整结束 - if ( doEnd ) { - preNode = node = node = tmpRange.endContainer.nodeType == 1 ? tmpRange.endContainer : tmpRange.endContainer.parentNode; - while ( 1 ) { - - if ( domUtils.isBody( node ) ) { - if ( preNode !== node ) { - - tmpRange.setEndAfter( preNode ); - - } else { - tmpRange.setEnd( node, node.childNodes.length ); - } - - break; - } - if ( !blockquote[node.tagName] ) { - tmpRange.setEndAfter( preNode ); - break; - } - - preNode = node; - node = node.parentNode; - } - - } - - - node = range.document.createElement( 'blockquote' ); - domUtils.setAttributes( node, attrs ); - node.appendChild( tmpRange.extractContents() ); - tmpRange.insertNode( node ); - //去除重复的 - var childs = domUtils.getElementsByTagName(node,'blockquote'); - for(var i=0,ci;ci=childs[i++];){ - if(ci.parentNode){ - domUtils.remove(ci,true); - } - } - - } - range.moveToBookmark( bookmark ).select(); - }, - queryCommandState : function() { - return getObj(this) ? 1 : 0; - } - }; -}; - - - -// plugins/convertcase.js -/** - * 大小写转换 - * @file - * @since 1.2.6.1 - */ - -/** - * 把选区内文本变大写,与“tolowercase”命令互斥 - * @command touppercase - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'touppercase' ); - * ``` - */ - -/** - * 把选区内文本变小写,与“touppercase”命令互斥 - * @command tolowercase - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'tolowercase' ); - * ``` - */ -UE.commands['touppercase'] = -UE.commands['tolowercase'] = { - execCommand:function (cmd) { - var me = this; - var rng = me.selection.getRange(); - if(rng.collapsed){ - return rng; - } - var bk = rng.createBookmark(), - bkEnd = bk.end, - filterFn = function( node ) { - return !domUtils.isBr(node) && !domUtils.isWhitespace( node ); - }, - curNode = domUtils.getNextDomNode( bk.start, false, filterFn ); - while ( curNode && (domUtils.getPosition( curNode, bkEnd ) & domUtils.POSITION_PRECEDING) ) { - - if ( curNode.nodeType == 3 ) { - curNode.nodeValue = curNode.nodeValue[cmd == 'touppercase' ? 'toUpperCase' : 'toLowerCase'](); - } - curNode = domUtils.getNextDomNode( curNode, true, filterFn ); - if(curNode === bkEnd){ - break; - } - - } - rng.moveToBookmark(bk).select(); - } -}; - - - -// plugins/indent.js -/** - * 首行缩进 - * @file - * @since 1.2.6.1 - */ - -/** - * 缩进 - * @command indent - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'indent' ); - * ``` - */ -UE.commands['indent'] = { - execCommand : function() { - var me = this,value = me.queryCommandState("indent") ? "0em" : (me.options.indentValue || '2em'); - me.execCommand('Paragraph','p',{style:'text-indent:'+ value}); - }, - queryCommandState : function() { - var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),'p h1 h2 h3 h4 h5 h6'); - return pN && pN.style.textIndent && parseInt(pN.style.textIndent) ? 1 : 0; - } - -}; - - -// plugins/print.js -/** - * 打印 - * @file - * @since 1.2.6.1 - */ - -/** - * 打印 - * @command print - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'print' ); - * ``` - */ -UE.commands['print'] = { - execCommand : function(){ - this.window.print(); - }, - notNeedUndo : 1 -}; - - - -// plugins/preview.js -/** - * 预览 - * @file - * @since 1.2.6.1 - */ - -/** - * 预览 - * @command preview - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'preview' ); - * ``` - */ -UE.commands['preview'] = { - execCommand : function(){ - var w = window.open('', '_blank', ''), - d = w.document; - d.open(); - d.write('
    '+this.getContent(null,null,true)+'
    '); - d.close(); - }, - notNeedUndo : 1 -}; - - -// plugins/selectall.js -/** - * 全选 - * @file - * @since 1.2.6.1 - */ - -/** - * 选中所有内容 - * @command selectall - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'selectall' ); - * ``` - */ -UE.plugins['selectall'] = function(){ - var me = this; - me.commands['selectall'] = { - execCommand : function(){ - //去掉了原生的selectAll,因为会出现报错和当内容为空时,不能出现闭合状态的光标 - var me = this,body = me.body, - range = me.selection.getRange(); - range.selectNodeContents(body); - if(domUtils.isEmptyBlock(body)){ - //opera不能自动合并到元素的里边,要手动处理一下 - if(browser.opera && body.firstChild && body.firstChild.nodeType == 1){ - range.setStartAtFirst(body.firstChild); - } - range.collapse(true); - } - range.select(true); - }, - notNeedUndo : 1 - }; - - - //快捷键 - me.addshortcutkey({ - "selectAll" : "ctrl+65" - }); -}; - - -// plugins/paragraph.js -/** - * 段落样式 - * @file - * @since 1.2.6.1 - */ - -/** - * 段落格式 - * @command paragraph - * @method execCommand - * @param { String } cmd 命令字符串 - * @param {String} style 标签值为:'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' - * @param {Object} attrs 标签的属性 - * @example - * ```javascript - * editor.execCommand( 'Paragraph','h1','{ - * class:'test' - * }' ); - * ``` - */ - -/** - * 返回选区内节点标签名 - * @command paragraph - * @method queryCommandValue - * @param { String } cmd 命令字符串 - * @return { String } 节点标签名 - * @example - * ```javascript - * editor.queryCommandValue( 'Paragraph' ); - * ``` - */ - -UE.plugins['paragraph'] = function() { - var me = this, - block = domUtils.isBlockElm, - notExchange = ['TD','LI','PRE'], - - doParagraph = function(range,style,attrs,sourceCmdName){ - var bookmark = range.createBookmark(), - filterFn = function( node ) { - return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' && !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace( node ); - }, - para; - - range.enlarge( true ); - var bookmark2 = range.createBookmark(), - current = domUtils.getNextDomNode( bookmark2.start, false, filterFn ), - tmpRange = range.cloneRange(), - tmpNode; - while ( current && !(domUtils.getPosition( current, bookmark2.end ) & domUtils.POSITION_FOLLOWING) ) { - if ( current.nodeType == 3 || !block( current ) ) { - tmpRange.setStartBefore( current ); - while ( current && current !== bookmark2.end && !block( current ) ) { - tmpNode = current; - current = domUtils.getNextDomNode( current, false, null, function( node ) { - return !block( node ); - } ); - } - tmpRange.setEndAfter( tmpNode ); - - para = range.document.createElement( style ); - if(attrs){ - domUtils.setAttributes(para,attrs); - if(sourceCmdName && sourceCmdName == 'customstyle' && attrs.style){ - para.style.cssText = attrs.style; - } - } - para.appendChild( tmpRange.extractContents() ); - //需要内容占位 - if(domUtils.isEmptyNode(para)){ - domUtils.fillChar(range.document,para); - - } - - tmpRange.insertNode( para ); - - var parent = para.parentNode; - //如果para上一级是一个block元素且不是body,td就删除它 - if ( block( parent ) && !domUtils.isBody( para.parentNode ) && utils.indexOf(notExchange,parent.tagName)==-1) { - //存储dir,style - if(!(sourceCmdName && sourceCmdName == 'customstyle')){ - parent.getAttribute('dir') && para.setAttribute('dir',parent.getAttribute('dir')); - //trace:1070 - parent.style.cssText && (para.style.cssText = parent.style.cssText + ';' + para.style.cssText); - //trace:1030 - parent.style.textAlign && !para.style.textAlign && (para.style.textAlign = parent.style.textAlign); - parent.style.textIndent && !para.style.textIndent && (para.style.textIndent = parent.style.textIndent); - parent.style.padding && !para.style.padding && (para.style.padding = parent.style.padding); - } - - //trace:1706 选择的就是h1-6要删除 - if(attrs && /h\d/i.test(parent.tagName) && !/h\d/i.test(para.tagName) ){ - domUtils.setAttributes(parent,attrs); - if(sourceCmdName && sourceCmdName == 'customstyle' && attrs.style){ - parent.style.cssText = attrs.style; - } - domUtils.remove(para,true); - para = parent; - }else{ - domUtils.remove( para.parentNode, true ); - } - - } - if( utils.indexOf(notExchange,parent.tagName)!=-1){ - current = parent; - }else{ - current = para; - } - - - current = domUtils.getNextDomNode( current, false, filterFn ); - } else { - current = domUtils.getNextDomNode( current, true, filterFn ); - } - } - return range.moveToBookmark( bookmark2 ).moveToBookmark( bookmark ); - }; - me.setOpt('paragraph',{'p':'', 'h1':'', 'h2':'', 'h3':'', 'h4':'', 'h5':'', 'h6':''}); - me.commands['paragraph'] = { - execCommand : function( cmdName, style,attrs,sourceCmdName ) { - var range = this.selection.getRange(); - //闭合时单独处理 - if(range.collapsed){ - var txt = this.document.createTextNode('p'); - range.insertNode(txt); - //去掉冗余的fillchar - if(browser.ie){ - var node = txt.previousSibling; - if(node && domUtils.isWhitespace(node)){ - domUtils.remove(node); - } - node = txt.nextSibling; - if(node && domUtils.isWhitespace(node)){ - domUtils.remove(node); - } - } - - } - range = doParagraph(range,style,attrs,sourceCmdName); - if(txt){ - range.setStartBefore(txt).collapse(true); - pN = txt.parentNode; - - domUtils.remove(txt); - - if(domUtils.isBlockElm(pN)&&domUtils.isEmptyNode(pN)){ - domUtils.fillNode(this.document,pN); - } - - } - - if(browser.gecko && range.collapsed && range.startContainer.nodeType == 1){ - var child = range.startContainer.childNodes[range.startOffset]; - if(child && child.nodeType == 1 && child.tagName.toLowerCase() == style){ - range.setStart(child,0).collapse(true); - } - } - //trace:1097 原来有true,原因忘了,但去了就不能清除多余的占位符了 - range.select(); - - - return true; - }, - queryCommandValue : function() { - var node = domUtils.filterNodeList(this.selection.getStartElementPath(),'p h1 h2 h3 h4 h5 h6'); - return node ? node.tagName.toLowerCase() : ''; - } - }; -}; - - -// plugins/directionality.js -/** - * 设置文字输入的方向的插件 - * @file - * @since 1.2.6.1 - */ -(function() { - var block = domUtils.isBlockElm , - getObj = function(editor){ -// var startNode = editor.selection.getStart(), -// parents; -// if ( startNode ) { -// //查找所有的是block的父亲节点 -// parents = domUtils.findParents( startNode, true, block, true ); -// for ( var i = 0,ci; ci = parents[i++]; ) { -// if ( ci.getAttribute( 'dir' ) ) { -// return ci; -// } -// } -// } - return domUtils.filterNodeList(editor.selection.getStartElementPath(),function(n){return n && n.nodeType == 1 && n.getAttribute('dir')}); - - }, - doDirectionality = function(range,editor,forward){ - - var bookmark, - filterFn = function( node ) { - return node.nodeType == 1 ? !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace(node); - }, - - obj = getObj( editor ); - - if ( obj && range.collapsed ) { - obj.setAttribute( 'dir', forward ); - return range; - } - bookmark = range.createBookmark(); - range.enlarge( true ); - var bookmark2 = range.createBookmark(), - current = domUtils.getNextDomNode( bookmark2.start, false, filterFn ), - tmpRange = range.cloneRange(), - tmpNode; - while ( current && !(domUtils.getPosition( current, bookmark2.end ) & domUtils.POSITION_FOLLOWING) ) { - if ( current.nodeType == 3 || !block( current ) ) { - tmpRange.setStartBefore( current ); - while ( current && current !== bookmark2.end && !block( current ) ) { - tmpNode = current; - current = domUtils.getNextDomNode( current, false, null, function( node ) { - return !block( node ); - } ); - } - tmpRange.setEndAfter( tmpNode ); - var common = tmpRange.getCommonAncestor(); - if ( !domUtils.isBody( common ) && block( common ) ) { - //遍历到了block节点 - common.setAttribute( 'dir', forward ); - current = common; - } else { - //没有遍历到,添加一个block节点 - var p = range.document.createElement( 'p' ); - p.setAttribute( 'dir', forward ); - var frag = tmpRange.extractContents(); - p.appendChild( frag ); - tmpRange.insertNode( p ); - current = p; - } - - current = domUtils.getNextDomNode( current, false, filterFn ); - } else { - current = domUtils.getNextDomNode( current, true, filterFn ); - } - } - return range.moveToBookmark( bookmark2 ).moveToBookmark( bookmark ); - }; - - /** - * 文字输入方向 - * @command directionality - * @method execCommand - * @param { String } cmdName 命令字符串 - * @param { String } forward 传入'ltr'表示从左向右输入,传入'rtl'表示从右向左输入 - * @example - * ```javascript - * editor.execCommand( 'directionality', 'ltr'); - * ``` - */ - - /** - * 查询当前选区的文字输入方向 - * @command directionality - * @method queryCommandValue - * @param { String } cmdName 命令字符串 - * @return { String } 返回'ltr'表示从左向右输入,返回'rtl'表示从右向左输入 - * @example - * ```javascript - * editor.queryCommandValue( 'directionality'); - * ``` - */ - UE.commands['directionality'] = { - execCommand : function( cmdName,forward ) { - var range = this.selection.getRange(); - //闭合时单独处理 - if(range.collapsed){ - var txt = this.document.createTextNode('d'); - range.insertNode(txt); - } - doDirectionality(range,this,forward); - if(txt){ - range.setStartBefore(txt).collapse(true); - domUtils.remove(txt); - } - - range.select(); - return true; - }, - queryCommandValue : function() { - var node = getObj(this); - return node ? node.getAttribute('dir') : 'ltr'; - } - }; -})(); - - - -// plugins/horizontal.js -/** - * 插入分割线插件 - * @file - * @since 1.2.6.1 - */ - -/** - * 插入分割线 - * @command horizontal - * @method execCommand - * @param { String } cmdName 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'horizontal' ); - * ``` - */ -UE.plugins['horizontal'] = function(){ - var me = this; - me.commands['horizontal'] = { - execCommand : function( cmdName ) { - var me = this; - if(me.queryCommandState(cmdName)!==-1){ - me.execCommand('insertHtml','
    '); - var range = me.selection.getRange(), - start = range.startContainer; - if(start.nodeType == 1 && !start.childNodes[range.startOffset] ){ - - var tmp; - if(tmp = start.childNodes[range.startOffset - 1]){ - if(tmp.nodeType == 1 && tmp.tagName == 'HR'){ - if(me.options.enterTag == 'p'){ - tmp = me.document.createElement('p'); - range.insertNode(tmp); - range.setStart(tmp,0).setCursor(); - - }else{ - tmp = me.document.createElement('br'); - range.insertNode(tmp); - range.setStartBefore(tmp).setCursor(); - } - } - } - - } - return true; - } - - }, - //边界在table里不能加分隔线 - queryCommandState : function() { - return domUtils.filterNodeList(this.selection.getStartElementPath(),'table') ? -1 : 0; - } - }; -// me.addListener('delkeyup',function(){ -// var rng = this.selection.getRange(); -// if(browser.ie && browser.version > 8){ -// rng.txtToElmBoundary(true); -// if(domUtils.isStartInblock(rng)){ -// var tmpNode = rng.startContainer; -// var pre = tmpNode.previousSibling; -// if(pre && domUtils.isTagNode(pre,'hr')){ -// domUtils.remove(pre); -// rng.select(); -// return; -// } -// } -// } -// if(domUtils.isBody(rng.startContainer)){ -// var hr = rng.startContainer.childNodes[rng.startOffset -1]; -// if(hr && hr.nodeName == 'HR'){ -// var next = hr.nextSibling; -// if(next){ -// rng.setStart(next,0) -// }else if(hr.previousSibling){ -// rng.setStartAtLast(hr.previousSibling) -// }else{ -// var p = this.document.createElement('p'); -// hr.parentNode.insertBefore(p,hr); -// domUtils.fillNode(this.document,p); -// rng.setStart(p,0); -// } -// domUtils.remove(hr); -// rng.setCursor(false,true); -// } -// } -// }) - me.addListener('delkeydown',function(name,evt){ - var rng = this.selection.getRange(); - rng.txtToElmBoundary(true); - if(domUtils.isStartInblock(rng)){ - var tmpNode = rng.startContainer; - var pre = tmpNode.previousSibling; - if(pre && domUtils.isTagNode(pre,'hr')){ - domUtils.remove(pre); - rng.select(); - domUtils.preventDefault(evt); - return true; - - } - } - - }) -}; - - - -// plugins/time.js -/** - * 插入时间和日期 - * @file - * @since 1.2.6.1 - */ - -/** - * 插入时间,默认格式:12:59:59 - * @command time - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'time'); - * ``` - */ - -/** - * 插入日期,默认格式:2013-08-30 - * @command date - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'date'); - * ``` - */ -UE.commands['time'] = UE.commands["date"] = { - execCommand : function(cmd, format){ - var date = new Date; - - function formatTime(date, format) { - var hh = ('0' + date.getHours()).slice(-2), - ii = ('0' + date.getMinutes()).slice(-2), - ss = ('0' + date.getSeconds()).slice(-2); - format = format || 'hh:ii:ss'; - return format.replace(/hh/ig, hh).replace(/ii/ig, ii).replace(/ss/ig, ss); - } - function formatDate(date, format) { - var yyyy = ('000' + date.getFullYear()).slice(-4), - yy = yyyy.slice(-2), - mm = ('0' + (date.getMonth()+1)).slice(-2), - dd = ('0' + date.getDate()).slice(-2); - format = format || 'yyyy-mm-dd'; - return format.replace(/yyyy/ig, yyyy).replace(/yy/ig, yy).replace(/mm/ig, mm).replace(/dd/ig, dd); - } - - this.execCommand('insertHtml',cmd == "time" ? formatTime(date, format):formatDate(date, format) ); - } -}; - - -// plugins/rowspacing.js -/** - * 段前段后间距插件 - * @file - * @since 1.2.6.1 - */ - -/** - * 设置段间距 - * @command rowspacing - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { String } value 段间距的值,以px为单位 - * @param { String } dir 间距位置,top或bottom,分别表示段前和段后 - * @example - * ```javascript - * editor.execCommand( 'rowspacing', '10', 'top' ); - * ``` - */ - -UE.plugins['rowspacing'] = function(){ - var me = this; - me.setOpt({ - 'rowspacingtop':['5', '10', '15', '20', '25'], - 'rowspacingbottom':['5', '10', '15', '20', '25'] - - }); - me.commands['rowspacing'] = { - execCommand : function( cmdName,value,dir ) { - this.execCommand('paragraph','p',{style:'margin-'+dir+':'+value + 'px'}); - return true; - }, - queryCommandValue : function(cmdName,dir) { - var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),function(node){return domUtils.isBlockElm(node) }), - value; - //trace:1026 - if(pN){ - value = domUtils.getComputedStyle(pN,'margin-'+dir).replace(/[^\d]/g,''); - return !value ? 0 : value; - } - return 0; - - } - }; -}; - - - - -// plugins/lineheight.js -/** - * 设置行内间距 - * @file - * @since 1.2.6.1 - */ -UE.plugins['lineheight'] = function(){ - var me = this; - me.setOpt({'lineheight':['1', '1.5','1.75','2', '3', '4', '5']}); - - /** - * 行距 - * @command lineheight - * @method execCommand - * @param { String } cmdName 命令字符串 - * @param { String } value 传入的行高值, 该值是当前字体的倍数, 例如: 1.5, 1.75 - * @example - * ```javascript - * editor.execCommand( 'lineheight', 1.5); - * ``` - */ - /** - * 查询当前选区内容的行高大小 - * @command lineheight - * @method queryCommandValue - * @param { String } cmd 命令字符串 - * @return { String } 返回当前行高大小 - * @example - * ```javascript - * editor.queryCommandValue( 'lineheight' ); - * ``` - */ - - me.commands['lineheight'] = { - execCommand : function( cmdName,value ) { - this.execCommand('paragraph','p',{style:'line-height:'+ (value == "1" ? "normal" : value + 'em') }); - return true; - }, - queryCommandValue : function() { - var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),function(node){return domUtils.isBlockElm(node)}); - if(pN){ - var value = domUtils.getComputedStyle(pN,'line-height'); - return value == 'normal' ? 1 : value.replace(/[^\d.]*/ig,""); - } - } - }; -}; - - - - -// plugins/insertcode.js -/** - * 插入代码插件 - * @file - * @since 1.2.6.1 - */ - -UE.plugins['insertcode'] = function() { - var me = this; - me.ready(function(){ - utils.cssRule('pre','pre{margin:.5em 0;padding:.4em .6em;border-radius:8px;background:#f8f8f8;}', - me.document) - }); - me.setOpt('insertcode',{ - 'as3':'ActionScript3', - 'bash':'Bash/Shell', - 'cpp':'C/C++', - 'css':'Css', - 'cf':'CodeFunction', - 'c#':'C#', - 'delphi':'Delphi', - 'diff':'Diff', - 'erlang':'Erlang', - 'groovy':'Groovy', - 'html':'Html', - 'java':'Java', - 'jfx':'JavaFx', - 'js':'Javascript', - 'pl':'Perl', - 'php':'Php', - 'plain':'Plain Text', - 'ps':'PowerShell', - 'python':'Python', - 'ruby':'Ruby', - 'scala':'Scala', - 'sql':'Sql', - 'vb':'Vb', - 'xml':'Xml' - }); - - /** - * 插入代码 - * @command insertcode - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { String } lang 插入代码的语言 - * @example - * ```javascript - * editor.execCommand( 'insertcode', 'javascript' ); - * ``` - */ - - /** - * 如果选区所在位置是插入插入代码区域,返回代码的语言 - * @command insertcode - * @method queryCommandValue - * @param { String } cmd 命令字符串 - * @return { String } 返回代码的语言 - * @example - * ```javascript - * editor.queryCommandValue( 'insertcode' ); - * ``` - */ - - me.commands['insertcode'] = { - execCommand : function(cmd,lang){ - var me = this, - rng = me.selection.getRange(), - pre = domUtils.findParentByTagName(rng.startContainer,'pre',true); - if(pre){ - pre.className = 'brush:'+lang+';toolbar:false;'; - }else{ - var code = ''; - if(rng.collapsed){ - code = browser.ie && browser.ie11below ? (browser.version <= 8 ? ' ':''):'
    '; - }else{ - var frag = rng.extractContents(); - var div = me.document.createElement('div'); - div.appendChild(frag); - - utils.each(UE.filterNode(UE.htmlparser(div.innerHTML.replace(/[\r\t]/g,'')),me.options.filterTxtRules).children,function(node){ - if(browser.ie && browser.ie11below && browser.version > 8){ - - if(node.type =='element'){ - if(node.tagName == 'br'){ - code += '\n' - }else if(!dtd.$empty[node.tagName]){ - utils.each(node.children,function(cn){ - if(cn.type =='element'){ - if(cn.tagName == 'br'){ - code += '\n' - }else if(!dtd.$empty[node.tagName]){ - code += cn.innerText(); - } - }else{ - code += cn.data - } - }) - if(!/\n$/.test(code)){ - code += '\n'; - } - } - }else{ - code += node.data + '\n' - } - if(!node.nextSibling() && /\n$/.test(code)){ - code = code.replace(/\n$/,''); - } - }else{ - if(browser.ie && browser.ie11below){ - - if(node.type =='element'){ - if(node.tagName == 'br'){ - code += '
    ' - }else if(!dtd.$empty[node.tagName]){ - utils.each(node.children,function(cn){ - if(cn.type =='element'){ - if(cn.tagName == 'br'){ - code += '
    ' - }else if(!dtd.$empty[node.tagName]){ - code += cn.innerText(); - } - }else{ - code += cn.data - } - }); - if(!/br>$/.test(code)){ - code += '
    '; - } - } - }else{ - code += node.data + '
    ' - } - if(!node.nextSibling() && /
    $/.test(code)){ - code = code.replace(/
    $/,''); - } - - }else{ - code += (node.type == 'element' ? (dtd.$empty[node.tagName] ? '' : node.innerText()) : node.data); - if(!/br\/?\s*>$/.test(code)){ - if(!node.nextSibling()) - return; - code += '
    ' - } - } - - } - - }); - } - me.execCommand('inserthtml','
    '+code+'
    ',true); - - pre = me.document.getElementById('coder'); - domUtils.removeAttributes(pre,'id'); - var tmpNode = pre.previousSibling; - - if(tmpNode && (tmpNode.nodeType == 3 && tmpNode.nodeValue.length == 1 && browser.ie && browser.version == 6 || domUtils.isEmptyBlock(tmpNode))){ - - domUtils.remove(tmpNode) - } - var rng = me.selection.getRange(); - if(domUtils.isEmptyBlock(pre)){ - rng.setStart(pre,0).setCursor(false,true) - }else{ - rng.selectNodeContents(pre).select() - } - } - - - - }, - queryCommandValue : function(){ - var path = this.selection.getStartElementPath(); - var lang = ''; - utils.each(path,function(node){ - if(node.nodeName =='PRE'){ - var match = node.className.match(/brush:([^;]+)/); - lang = match && match[1] ? match[1] : ''; - return false; - } - }); - return lang; - } - }; - - me.addInputRule(function(root){ - utils.each(root.getNodesByTagName('pre'),function(pre){ - var brs = pre.getNodesByTagName('br'); - if(brs.length){ - browser.ie && browser.ie11below && browser.version > 8 && utils.each(brs,function(br){ - var txt = UE.uNode.createText('\n'); - br.parentNode.insertBefore(txt,br); - br.parentNode.removeChild(br); - }); - return; - } - if(browser.ie && browser.ie11below && browser.version > 8) - return; - var code = pre.innerText().split(/\n/); - pre.innerHTML(''); - utils.each(code,function(c){ - if(c.length){ - pre.appendChild(UE.uNode.createText(c)); - } - pre.appendChild(UE.uNode.createElement('br')) - }) - }) - }); - me.addOutputRule(function(root){ - utils.each(root.getNodesByTagName('pre'),function(pre){ - var code = ''; - utils.each(pre.children,function(n){ - if(n.type == 'text'){ - //在ie下文本内容有可能末尾带有\n要去掉 - //trace:3396 - code += n.data.replace(/[ ]/g,' ').replace(/\n$/,''); - }else{ - if(n.tagName == 'br'){ - code += '\n' - }else{ - code += (!dtd.$empty[n.tagName] ? '' : n.innerText()); - } - - } - - }); - - pre.innerText(code.replace(/( |\n)+$/,'')) - }) - }); - //不需要判断highlight的command列表 - me.notNeedCodeQuery ={ - help:1, - undo:1, - redo:1, - source:1, - print:1, - searchreplace:1, - fullscreen:1, - preview:1, - insertparagraph:1, - elementpath:1, - insertcode:1, - inserthtml:1, - selectall:1 - }; - //将queyCommamndState重置 - var orgQuery = me.queryCommandState; - me.queryCommandState = function(cmd){ - var me = this; - - if(!me.notNeedCodeQuery[cmd.toLowerCase()] && me.selection && me.queryCommandValue('insertcode')){ - return -1; - } - return UE.Editor.prototype.queryCommandState.apply(this,arguments) - }; - me.addListener('beforeenterkeydown',function(){ - var rng = me.selection.getRange(); - var pre = domUtils.findParentByTagName(rng.startContainer,'pre',true); - if(pre){ - me.fireEvent('saveScene'); - if(!rng.collapsed){ - rng.deleteContents(); - } - if(!browser.ie || browser.ie9above){ - var tmpNode = me.document.createElement('br'),pre; - rng.insertNode(tmpNode).setStartAfter(tmpNode).collapse(true); - var next = tmpNode.nextSibling; - if(!next && (!browser.ie || browser.version > 10)){ - rng.insertNode(tmpNode.cloneNode(false)); - }else{ - rng.setStartAfter(tmpNode); - } - pre = tmpNode.previousSibling; - var tmp; - while(pre ){ - tmp = pre; - pre = pre.previousSibling; - if(!pre || pre.nodeName == 'BR'){ - pre = tmp; - break; - } - } - if(pre){ - var str = ''; - while(pre && pre.nodeName != 'BR' && new RegExp('^[\\s'+domUtils.fillChar+']*$').test(pre.nodeValue)){ - str += pre.nodeValue; - pre = pre.nextSibling; - } - if(pre.nodeName != 'BR'){ - var match = pre.nodeValue.match(new RegExp('^([\\s'+domUtils.fillChar+']+)')); - if(match && match[1]){ - str += match[1] - } - - } - if(str){ - str = me.document.createTextNode(str); - rng.insertNode(str).setStartAfter(str); - } - } - rng.collapse(true).select(true); - }else{ - if(browser.version > 8){ - - var txt = me.document.createTextNode('\n'); - var start = rng.startContainer; - if(rng.startOffset == 0){ - var preNode = start.previousSibling; - if(preNode){ - rng.insertNode(txt); - var fillchar = me.document.createTextNode(' '); - rng.setStartAfter(txt).insertNode(fillchar).setStart(fillchar,0).collapse(true).select(true) - } - }else{ - rng.insertNode(txt).setStartAfter(txt); - var fillchar = me.document.createTextNode(' '); - start = rng.startContainer.childNodes[rng.startOffset]; - if(start && !/^\n/.test(start.nodeValue)){ - rng.setStartBefore(txt) - } - rng.insertNode(fillchar).setStart(fillchar,0).collapse(true).select(true) - } - - }else{ - var tmpNode = me.document.createElement('br'); - rng.insertNode(tmpNode); - rng.insertNode(me.document.createTextNode(domUtils.fillChar)); - rng.setStartAfter(tmpNode); - pre = tmpNode.previousSibling; - var tmp; - while(pre ){ - tmp = pre; - pre = pre.previousSibling; - if(!pre || pre.nodeName == 'BR'){ - pre = tmp; - break; - } - } - if(pre){ - var str = ''; - while(pre && pre.nodeName != 'BR' && new RegExp('^[ '+domUtils.fillChar+']*$').test(pre.nodeValue)){ - str += pre.nodeValue; - pre = pre.nextSibling; - } - if(pre.nodeName != 'BR'){ - var match = pre.nodeValue.match(new RegExp('^([ '+domUtils.fillChar+']+)')); - if(match && match[1]){ - str += match[1] - } - - } - - str = me.document.createTextNode(str); - rng.insertNode(str).setStartAfter(str); - } - rng.collapse(true).select(); - } - - - } - me.fireEvent('saveScene'); - return true; - } - - - }); - - me.addListener('tabkeydown',function(cmd,evt){ - var rng = me.selection.getRange(); - var pre = domUtils.findParentByTagName(rng.startContainer,'pre',true); - if(pre){ - me.fireEvent('saveScene'); - if(evt.shiftKey){ - - }else{ - if(!rng.collapsed){ - var bk = rng.createBookmark(); - var start = bk.start.previousSibling; - - while(start){ - if(pre.firstChild === start && !domUtils.isBr(start)){ - pre.insertBefore(me.document.createTextNode(' '),start); - - break; - } - if(domUtils.isBr(start)){ - pre.insertBefore(me.document.createTextNode(' '),start.nextSibling); - - break; - } - start = start.previousSibling; - } - var end = bk.end; - start = bk.start.nextSibling; - if(pre.firstChild === bk.start){ - pre.insertBefore(me.document.createTextNode(' '),start.nextSibling) - - } - while(start && start !== end){ - if(domUtils.isBr(start) && start.nextSibling){ - if(start.nextSibling === end){ - break; - } - pre.insertBefore(me.document.createTextNode(' '),start.nextSibling) - } - - start = start.nextSibling; - } - rng.moveToBookmark(bk).select(); - }else{ - var tmpNode = me.document.createTextNode(' '); - rng.insertNode(tmpNode).setStartAfter(tmpNode).collapse(true).select(true); - } - } - - - me.fireEvent('saveScene'); - return true; - } - - - }); - - - me.addListener('beforeinserthtml',function(evtName,html){ - var me = this, - rng = me.selection.getRange(), - pre = domUtils.findParentByTagName(rng.startContainer,'pre',true); - if(pre){ - if(!rng.collapsed){ - rng.deleteContents() - } - var htmlstr = ''; - if(browser.ie && browser.version > 8){ - - utils.each(UE.filterNode(UE.htmlparser(html),me.options.filterTxtRules).children,function(node){ - if(node.type =='element'){ - if(node.tagName == 'br'){ - htmlstr += '\n' - }else if(!dtd.$empty[node.tagName]){ - utils.each(node.children,function(cn){ - if(cn.type =='element'){ - if(cn.tagName == 'br'){ - htmlstr += '\n' - }else if(!dtd.$empty[node.tagName]){ - htmlstr += cn.innerText(); - } - }else{ - htmlstr += cn.data - } - }) - if(!/\n$/.test(htmlstr)){ - htmlstr += '\n'; - } - } - }else{ - htmlstr += node.data + '\n' - } - if(!node.nextSibling() && /\n$/.test(htmlstr)){ - htmlstr = htmlstr.replace(/\n$/,''); - } - }); - var tmpNode = me.document.createTextNode(utils.html(htmlstr.replace(/ /g,' '))); - rng.insertNode(tmpNode).selectNode(tmpNode).select(); - }else{ - var frag = me.document.createDocumentFragment(); - - utils.each(UE.filterNode(UE.htmlparser(html),me.options.filterTxtRules).children,function(node){ - if(node.type =='element'){ - if(node.tagName == 'br'){ - frag.appendChild(me.document.createElement('br')) - }else if(!dtd.$empty[node.tagName]){ - utils.each(node.children,function(cn){ - if(cn.type =='element'){ - if(cn.tagName == 'br'){ - - frag.appendChild(me.document.createElement('br')) - }else if(!dtd.$empty[node.tagName]){ - frag.appendChild(me.document.createTextNode(utils.html(cn.innerText().replace(/ /g,' ')))); - - } - }else{ - frag.appendChild(me.document.createTextNode(utils.html( cn.data.replace(/ /g,' ')))); - - } - }) - if(frag.lastChild.nodeName != 'BR'){ - frag.appendChild(me.document.createElement('br')) - } - } - }else{ - frag.appendChild(me.document.createTextNode(utils.html( node.data.replace(/ /g,' ')))); - } - if(!node.nextSibling() && frag.lastChild.nodeName == 'BR'){ - frag.removeChild(frag.lastChild) - } - - - }); - rng.insertNode(frag).select(); - - } - - return true; - } - }); - //方向键的处理 - me.addListener('keydown',function(cmd,evt){ - var me = this,keyCode = evt.keyCode || evt.which; - if(keyCode == 40){ - var rng = me.selection.getRange(),pre,start = rng.startContainer; - if(rng.collapsed && (pre = domUtils.findParentByTagName(rng.startContainer,'pre',true)) && !pre.nextSibling){ - var last = pre.lastChild - while(last && last.nodeName == 'BR'){ - last = last.previousSibling; - } - if(last === start || rng.startContainer === pre && rng.startOffset == pre.childNodes.length){ - me.execCommand('insertparagraph'); - domUtils.preventDefault(evt) - } - - } - } - }); - //trace:3395 - me.addListener('delkeydown',function(type,evt){ - var rng = this.selection.getRange(); - rng.txtToElmBoundary(true); - var start = rng.startContainer; - if(domUtils.isTagNode(start,'pre') && rng.collapsed && domUtils.isStartInblock(rng)){ - var p = me.document.createElement('p'); - domUtils.fillNode(me.document,p); - start.parentNode.insertBefore(p,start); - domUtils.remove(start); - rng.setStart(p,0).setCursor(false,true); - domUtils.preventDefault(evt); - return true; - } - }) -}; - - -// plugins/cleardoc.js -/** - * 清空文档插件 - * @file - * @since 1.2.6.1 - */ - -/** - * 清空文档 - * @command cleardoc - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * //editor 是编辑器实例 - * editor.execCommand('cleardoc'); - * ``` - */ - -UE.commands['cleardoc'] = { - execCommand : function( cmdName) { - var me = this, - enterTag = me.options.enterTag, - range = me.selection.getRange(); - if(enterTag == "br"){ - me.body.innerHTML = "
    "; - range.setStart(me.body,0).setCursor(); - }else{ - me.body.innerHTML = "

    "+(ie ? "" : "
    ")+"

    "; - range.setStart(me.body.firstChild,0).setCursor(false,true); - } - setTimeout(function(){ - me.fireEvent("clearDoc"); - },0); - - } -}; - - - -// plugins/anchor.js -/** - * 锚点插件,为UEditor提供插入锚点支持 - * @file - * @since 1.2.6.1 - */ -UE.plugin.register('anchor', function (){ - - return { - bindEvents:{ - 'ready':function(){ - utils.cssRule('anchor', - '.anchorclass{background: url(\'' - + this.options.themePath - + this.options.theme +'/images/anchor.gif\') no-repeat scroll left center transparent;cursor: auto;display: inline-block;height: 16px;width: 15px;}', - this.document); - } - }, - outputRule: function(root){ - utils.each(root.getNodesByTagName('img'),function(a){ - var val; - if(val = a.getAttr('anchorname')){ - a.tagName = 'a'; - a.setAttr({ - anchorname : '', - name : val, - 'class' : '' - }) - } - }) - }, - inputRule:function(root){ - utils.each(root.getNodesByTagName('a'),function(a){ - var val; - if((val = a.getAttr('name')) && !a.getAttr('href')){ - a.tagName = 'img'; - a.setAttr({ - anchorname :a.getAttr('name'), - 'class' : 'anchorclass' - }); - a.setAttr('name') - - } - }) - - }, - commands:{ - /** - * 插入锚点 - * @command anchor - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { String } name 锚点名称字符串 - * @example - * ```javascript - * //editor 是编辑器实例 - * editor.execCommand('anchor', 'anchor1'); - * ``` - */ - 'anchor':{ - execCommand:function (cmd, name) { - var range = this.selection.getRange(),img = range.getClosedNode(); - if (img && img.getAttribute('anchorname')) { - if (name) { - img.setAttribute('anchorname', name); - } else { - range.setStartBefore(img).setCursor(); - domUtils.remove(img); - } - } else { - if (name) { - //只在选区的开始插入 - var anchor = this.document.createElement('img'); - range.collapse(true); - domUtils.setAttributes(anchor,{ - 'anchorname':name, - 'class':'anchorclass' - }); - range.insertNode(anchor).setStartAfter(anchor).setCursor(false,true); - } - } - } - } - } - } -}); - - -// plugins/wordcount.js -///import core -///commands 字数统计 -///commandsName WordCount,wordCount -///commandsTitle 字数统计 -/* - * Created by JetBrains WebStorm. - * User: taoqili - * Date: 11-9-7 - * Time: 下午8:18 - * To change this template use File | Settings | File Templates. - */ - -UE.plugins['wordcount'] = function(){ - var me = this; - me.setOpt('wordCount',true); - me.addListener('contentchange',function(){ - me.fireEvent('wordcount'); - }); - var timer; - me.addListener('ready',function(){ - var me = this; - domUtils.on(me.body,"keyup",function(evt){ - var code = evt.keyCode||evt.which, - //忽略的按键,ctr,alt,shift,方向键 - ignores = {"16":1,"18":1,"20":1,"37":1,"38":1,"39":1,"40":1}; - if(code in ignores) return; - clearTimeout(timer); - timer = setTimeout(function(){ - me.fireEvent('wordcount'); - },200) - }) - }); -}; - - -// plugins/pagebreak.js -/** - * 分页功能插件 - * @file - * @since 1.2.6.1 - */ -UE.plugins['pagebreak'] = function () { - var me = this, - notBreakTags = ['td']; - me.setOpt('pageBreakTag','_ueditor_page_break_tag_'); - - function fillNode(node){ - if(domUtils.isEmptyBlock(node)){ - var firstChild = node.firstChild,tmpNode; - - while(firstChild && firstChild.nodeType == 1 && domUtils.isEmptyBlock(firstChild)){ - tmpNode = firstChild; - firstChild = firstChild.firstChild; - } - !tmpNode && (tmpNode = node); - domUtils.fillNode(me.document,tmpNode); - } - } - //分页符样式添加 - - me.ready(function(){ - utils.cssRule('pagebreak','.pagebreak{display:block;clear:both !important;cursor:default !important;width: 100% !important;margin:0;}',me.document); - }); - function isHr(node){ - return node && node.nodeType == 1 && node.tagName == 'HR' && node.className == 'pagebreak'; - } - me.addInputRule(function(root){ - root.traversal(function(node){ - if(node.type == 'text' && node.data == me.options.pageBreakTag){ - var hr = UE.uNode.createElement('
    '); - node.parentNode.insertBefore(hr,node); - node.parentNode.removeChild(node) - } - }) - }); - me.addOutputRule(function(node){ - utils.each(node.getNodesByTagName('hr'),function(n){ - if(n.getAttr('class') == 'pagebreak'){ - var txt = UE.uNode.createText(me.options.pageBreakTag); - n.parentNode.insertBefore(txt,n); - n.parentNode.removeChild(n); - } - }) - - }); - - /** - * 插入分页符 - * @command pagebreak - * @method execCommand - * @param { String } cmd 命令字符串 - * @remind 在表格中插入分页符会把表格切分成两部分 - * @remind 获取编辑器内的数据时, 编辑器会把分页符转换成“_ueditor_page_break_tag_”字符串, - * 以便于提交数据到服务器端后处理分页。 - * @example - * ```javascript - * editor.execCommand( 'pagebreak'); //插入一个hr标签,带有样式类名pagebreak - * ``` - */ - - me.commands['pagebreak'] = { - execCommand:function () { - var range = me.selection.getRange(),hr = me.document.createElement('hr'); - domUtils.setAttributes(hr,{ - 'class' : 'pagebreak', - noshade:"noshade", - size:"5" - }); - domUtils.unSelectable(hr); - //table单独处理 - var node = domUtils.findParentByTagName(range.startContainer, notBreakTags, true), - - parents = [], pN; - if (node) { - switch (node.tagName) { - case 'TD': - pN = node.parentNode; - if (!pN.previousSibling) { - var table = domUtils.findParentByTagName(pN, 'table'); -// var tableWrapDiv = table.parentNode; -// if(tableWrapDiv && tableWrapDiv.nodeType == 1 -// && tableWrapDiv.tagName == 'DIV' -// && tableWrapDiv.getAttribute('dropdrag') -// ){ -// domUtils.remove(tableWrapDiv,true); -// } - table.parentNode.insertBefore(hr, table); - parents = domUtils.findParents(hr, true); - - } else { - pN.parentNode.insertBefore(hr, pN); - parents = domUtils.findParents(hr); - - } - pN = parents[1]; - if (hr !== pN) { - domUtils.breakParent(hr, pN); - - } - //table要重写绑定一下拖拽 - me.fireEvent('afteradjusttable',me.document); - } - - } else { - - if (!range.collapsed) { - range.deleteContents(); - var start = range.startContainer; - while ( !domUtils.isBody(start) && domUtils.isBlockElm(start) && domUtils.isEmptyNode(start)) { - range.setStartBefore(start).collapse(true); - domUtils.remove(start); - start = range.startContainer; - } - - } - range.insertNode(hr); - - var pN = hr.parentNode, nextNode; - while (!domUtils.isBody(pN)) { - domUtils.breakParent(hr, pN); - nextNode = hr.nextSibling; - if (nextNode && domUtils.isEmptyBlock(nextNode)) { - domUtils.remove(nextNode); - } - pN = hr.parentNode; - } - nextNode = hr.nextSibling; - var pre = hr.previousSibling; - if(isHr(pre)){ - domUtils.remove(pre); - }else{ - pre && fillNode(pre); - } - - if(!nextNode){ - var p = me.document.createElement('p'); - - hr.parentNode.appendChild(p); - domUtils.fillNode(me.document,p); - range.setStart(p,0).collapse(true); - }else{ - if(isHr(nextNode)){ - domUtils.remove(nextNode); - }else{ - fillNode(nextNode); - } - range.setEndAfter(hr).collapse(false); - } - - range.select(true); - - } - - } - }; -}; - -// plugins/wordimage.js -///import core -///commands 本地图片引导上传 -///commandsName WordImage -///commandsTitle 本地图片引导上传 -///commandsDialog dialogs\wordimage - -UE.plugin.register('wordimage',function(){ - var me = this, - images = []; - return { - commands : { - 'wordimage':{ - execCommand:function () { - var images = domUtils.getElementsByTagName(me.body, "img"); - var urlList = []; - for (var i = 0, ci; ci = images[i++];) { - var url = ci.getAttribute("word_img"); - url && urlList.push(url); - } - return urlList; - }, - queryCommandState:function () { - images = domUtils.getElementsByTagName(me.body, "img"); - for (var i = 0, ci; ci = images[i++];) { - if (ci.getAttribute("word_img")) { - return 1; - } - } - return -1; - }, - notNeedUndo:true - } - }, - inputRule : function (root) { - utils.each(root.getNodesByTagName('img'), function (img) { - var attrs = img.attrs, - flag = parseInt(attrs.width) < 128 || parseInt(attrs.height) < 43, - opt = me.options, - src = opt.UEDITOR_HOME_URL + 'themes/default/images/spacer.gif'; - if (attrs['src'] && /^(?:(file:\/+))/.test(attrs['src'])) { - img.setAttr({ - width:attrs.width, - height:attrs.height, - alt:attrs.alt, - word_img: attrs.src, - src:src, - 'style':'background:url(' + ( flag ? opt.themePath + opt.theme + '/images/word.gif' : opt.langPath + opt.lang + '/images/localimage.png') + ') no-repeat center center;border:1px solid #ddd' - }) - } - }) - } - } -}); - -// plugins/dragdrop.js -UE.plugins['dragdrop'] = function (){ - - var me = this; - me.ready(function(){ - domUtils.on(this.body,'dragend',function(){ - var rng = me.selection.getRange(); - var node = rng.getClosedNode()||me.selection.getStart(); - - if(node && node.tagName == 'IMG'){ - - var pre = node.previousSibling,next; - while(next = node.nextSibling){ - if(next.nodeType == 1 && next.tagName == 'SPAN' && !next.firstChild){ - domUtils.remove(next) - }else{ - break; - } - } - - - if((pre && pre.nodeType == 1 && !domUtils.isEmptyBlock(pre) || !pre) && (!next || next && !domUtils.isEmptyBlock(next))){ - if(pre && pre.tagName == 'P' && !domUtils.isEmptyBlock(pre)){ - pre.appendChild(node); - domUtils.moveChild(next,pre); - domUtils.remove(next); - }else if(next && next.tagName == 'P' && !domUtils.isEmptyBlock(next)){ - next.insertBefore(node,next.firstChild); - } - - if(pre && pre.tagName == 'P' && domUtils.isEmptyBlock(pre)){ - domUtils.remove(pre) - } - if(next && next.tagName == 'P' && domUtils.isEmptyBlock(next)){ - domUtils.remove(next) - } - rng.selectNode(node).select(); - me.fireEvent('saveScene'); - - } - - } - - }) - }); - me.addListener('keyup', function(type, evt) { - var keyCode = evt.keyCode || evt.which; - if (keyCode == 13) { - var rng = me.selection.getRange(),node; - if(node = domUtils.findParentByTagName(rng.startContainer,'p',true)){ - if(domUtils.getComputedStyle(node,'text-align') == 'center'){ - domUtils.removeStyle(node,'text-align') - } - } - } - }) -}; - - -// plugins/undo.js -/** - * undo redo - * @file - * @since 1.2.6.1 - */ - -/** - * 撤销上一次执行的命令 - * @command undo - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'undo' ); - * ``` - */ - -/** - * 重做上一次执行的命令 - * @command redo - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'redo' ); - * ``` - */ - -UE.plugins['undo'] = function () { - var saveSceneTimer; - var me = this, - maxUndoCount = me.options.maxUndoCount || 20, - maxInputCount = me.options.maxInputCount || 20, - fillchar = new RegExp(domUtils.fillChar + '|<\/hr>', 'gi');// ie会产生多余的 - var noNeedFillCharTags = { - ol:1,ul:1,table:1,tbody:1,tr:1,body:1 - }; - var orgState = me.options.autoClearEmptyNode; - function compareAddr(indexA, indexB) { - if (indexA.length != indexB.length) - return 0; - for (var i = 0, l = indexA.length; i < l; i++) { - if (indexA[i] != indexB[i]) - return 0 - } - return 1; - } - - function compareRangeAddress(rngAddrA, rngAddrB) { - if (rngAddrA.collapsed != rngAddrB.collapsed) { - return 0; - } - if (!compareAddr(rngAddrA.startAddress, rngAddrB.startAddress) || !compareAddr(rngAddrA.endAddress, rngAddrB.endAddress)) { - return 0; - } - return 1; - } - - function UndoManager() { - this.list = []; - this.index = 0; - this.hasUndo = false; - this.hasRedo = false; - this.undo = function () { - if (this.hasUndo) { - if (!this.list[this.index - 1] && this.list.length == 1) { - this.reset(); - return; - } - while (this.list[this.index].content == this.list[this.index - 1].content) { - this.index--; - if (this.index == 0) { - return this.restore(0); - } - } - this.restore(--this.index); - } - }; - this.redo = function () { - if (this.hasRedo) { - while (this.list[this.index].content == this.list[this.index + 1].content) { - this.index++; - if (this.index == this.list.length - 1) { - return this.restore(this.index); - } - } - this.restore(++this.index); - } - }; - - this.restore = function () { - var me = this.editor; - var scene = this.list[this.index]; - var root = UE.htmlparser(scene.content.replace(fillchar, '')); - me.options.autoClearEmptyNode = false; - me.filterInputRule(root); - me.options.autoClearEmptyNode = orgState; - //trace:873 - //去掉展位符 - me.document.body.innerHTML = root.toHtml(); - me.fireEvent('afterscencerestore'); - //处理undo后空格不展位的问题 - if (browser.ie) { - utils.each(domUtils.getElementsByTagName(me.document,'td th caption p'),function(node){ - if(domUtils.isEmptyNode(node)){ - domUtils.fillNode(me.document, node); - } - }) - } - - try{ - var rng = new dom.Range(me.document).moveToAddress(scene.address); - rng.select(noNeedFillCharTags[rng.startContainer.nodeName.toLowerCase()]); - }catch(e){} - - this.update(); - this.clearKey(); - //不能把自己reset了 - me.fireEvent('reset', true); - }; - - this.getScene = function () { - var me = this.editor; - var rng = me.selection.getRange(), - rngAddress = rng.createAddress(false,true); - me.fireEvent('beforegetscene'); - var root = UE.htmlparser(me.body.innerHTML); - me.options.autoClearEmptyNode = false; - me.filterOutputRule(root); - me.options.autoClearEmptyNode = orgState; - var cont = root.toHtml(); - //trace:3461 - //这个会引起回退时导致空格丢失的情况 -// browser.ie && (cont = cont.replace(/> <').replace(/\s*\s*/g, '>')); - me.fireEvent('aftergetscene'); - - return { - address:rngAddress, - content:cont - } - }; - this.save = function (notCompareRange,notSetCursor) { - clearTimeout(saveSceneTimer); - var currentScene = this.getScene(notSetCursor), - lastScene = this.list[this.index]; - - if(lastScene && lastScene.content != currentScene.content){ - me.trigger('contentchange') - } - //内容相同位置相同不存 - if (lastScene && lastScene.content == currentScene.content && - ( notCompareRange ? 1 : compareRangeAddress(lastScene.address, currentScene.address) ) - ) { - return; - } - this.list = this.list.slice(0, this.index + 1); - this.list.push(currentScene); - //如果大于最大数量了,就把最前的剔除 - if (this.list.length > maxUndoCount) { - this.list.shift(); - } - this.index = this.list.length - 1; - this.clearKey(); - //跟新undo/redo状态 - this.update(); - - }; - this.update = function () { - this.hasRedo = !!this.list[this.index + 1]; - this.hasUndo = !!this.list[this.index - 1]; - }; - this.reset = function () { - this.list = []; - this.index = 0; - this.hasUndo = false; - this.hasRedo = false; - this.clearKey(); - }; - this.clearKey = function () { - keycont = 0; - lastKeyCode = null; - }; - } - - me.undoManger = new UndoManager(); - me.undoManger.editor = me; - function saveScene() { - this.undoManger.save(); - } - - me.addListener('saveScene', function () { - var args = Array.prototype.splice.call(arguments,1); - this.undoManger.save.apply(this.undoManger,args); - }); - -// me.addListener('beforeexeccommand', saveScene); -// me.addListener('afterexeccommand', saveScene); - - me.addListener('reset', function (type, exclude) { - if (!exclude) { - this.undoManger.reset(); - } - }); - me.commands['redo'] = me.commands['undo'] = { - execCommand:function (cmdName) { - this.undoManger[cmdName](); - }, - queryCommandState:function (cmdName) { - return this.undoManger['has' + (cmdName.toLowerCase() == 'undo' ? 'Undo' : 'Redo')] ? 0 : -1; - }, - notNeedUndo:1 - }; - - var keys = { - // /*Backspace*/ 8:1, /*Delete*/ 46:1, - /*Shift*/ 16:1, /*Ctrl*/ 17:1, /*Alt*/ 18:1, - 37:1, 38:1, 39:1, 40:1 - - }, - keycont = 0, - lastKeyCode; - //输入法状态下不计算字符数 - var inputType = false; - me.addListener('ready', function () { - domUtils.on(this.body, 'compositionstart', function () { - inputType = true; - }); - domUtils.on(this.body, 'compositionend', function () { - inputType = false; - }) - }); - //快捷键 - me.addshortcutkey({ - "Undo":"ctrl+90", //undo - "Redo":"ctrl+89" //redo - - }); - var isCollapsed = true; - me.addListener('keydown', function (type, evt) { - - var me = this; - var keyCode = evt.keyCode || evt.which; - if (!keys[keyCode] && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey) { - if (inputType) - return; - - if(!me.selection.getRange().collapsed){ - me.undoManger.save(false,true); - isCollapsed = false; - return; - } - if (me.undoManger.list.length == 0) { - me.undoManger.save(true); - } - clearTimeout(saveSceneTimer); - function save(cont){ - cont.undoManger.save(false,true); - cont.fireEvent('selectionchange'); - } - saveSceneTimer = setTimeout(function(){ - if(inputType){ - var interalTimer = setInterval(function(){ - if(!inputType){ - save(me); - clearInterval(interalTimer) - } - },300) - return; - } - save(me); - },200); - - lastKeyCode = keyCode; - keycont++; - if (keycont >= maxInputCount ) { - save(me) - } - } - }); - me.addListener('keyup', function (type, evt) { - var keyCode = evt.keyCode || evt.which; - if (!keys[keyCode] && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey) { - if (inputType) - return; - if(!isCollapsed){ - this.undoManger.save(false,true); - isCollapsed = true; - } - } - }); - //扩展实例,添加关闭和开启命令undo - me.stopCmdUndo = function(){ - me.__hasEnterExecCommand = true; - }; - me.startCmdUndo = function(){ - me.__hasEnterExecCommand = false; - } -}; - - -// plugins/copy.js -UE.plugin.register('copy', function () { - - var me = this; - - function initZeroClipboard() { - - ZeroClipboard.config({ - debug: false, - swfPath: me.options.UEDITOR_HOME_URL + 'third-party/zeroclipboard/ZeroClipboard.swf' - }); - - var client = me.zeroclipboard = new ZeroClipboard(); - - // 复制内容 - client.on('copy', function (e) { - var client = e.client, - rng = me.selection.getRange(), - div = document.createElement('div'); - - div.appendChild(rng.cloneContents()); - client.setText(div.innerText || div.textContent); - client.setHtml(div.innerHTML); - rng.select(); - }); - // hover事件传递到target - client.on('mouseover mouseout', function (e) { - var target = e.target; - if (e.type == 'mouseover') { - domUtils.addClass(target, 'edui-state-hover'); - } else if (e.type == 'mouseout') { - domUtils.removeClasses(target, 'edui-state-hover'); - } - }); - // flash加载不成功 - client.on('wrongflash noflash', function () { - ZeroClipboard.destroy(); - }); - } - - return { - bindEvents: { - 'ready': function () { - if (!browser.ie) { - if (window.ZeroClipboard) { - initZeroClipboard(); - } else { - utils.loadFile(document, { - src: me.options.UEDITOR_HOME_URL + "third-party/zeroclipboard/ZeroClipboard.js", - tag: "script", - type: "text/javascript", - defer: "defer" - }, function () { - initZeroClipboard(); - }); - } - } - } - }, - commands: { - 'copy': { - execCommand: function (cmd) { - if (!me.document.execCommand('copy')) { - alert(me.getLang('copymsg')); - } - } - } - } - } -}); - - -// plugins/paste.js -///import core -///import plugins/inserthtml.js -///import plugins/undo.js -///import plugins/serialize.js -///commands 粘贴 -///commandsName PastePlain -///commandsTitle 纯文本粘贴模式 -/** - * @description 粘贴 - * @author zhanyi - */ -UE.plugins['paste'] = function () { - function getClipboardData(callback) { - var doc = this.document; - if (doc.getElementById('baidu_pastebin')) { - return; - } - var range = this.selection.getRange(), - bk = range.createBookmark(), - //创建剪贴的容器div - pastebin = doc.createElement('div'); - pastebin.id = 'baidu_pastebin'; - // Safari 要求div必须有内容,才能粘贴内容进来 - browser.webkit && pastebin.appendChild(doc.createTextNode(domUtils.fillChar + domUtils.fillChar)); - doc.body.appendChild(pastebin); - //trace:717 隐藏的span不能得到top - //bk.start.innerHTML = ' '; - bk.start.style.display = ''; - pastebin.style.cssText = "position:absolute;width:1px;height:1px;overflow:hidden;left:-1000px;white-space:nowrap;top:" + - //要在现在光标平行的位置加入,否则会出现跳动的问题 - domUtils.getXY(bk.start).y + 'px'; - - range.selectNodeContents(pastebin).select(true); - - setTimeout(function () { - if (browser.webkit) { - for (var i = 0, pastebins = doc.querySelectorAll('#baidu_pastebin'), pi; pi = pastebins[i++];) { - if (domUtils.isEmptyNode(pi)) { - domUtils.remove(pi); - } else { - pastebin = pi; - break; - } - } - } - try { - pastebin.parentNode.removeChild(pastebin); - } catch (e) { - } - range.moveToBookmark(bk).select(true); - callback(pastebin); - }, 0); - } - - var me = this; - - me.setOpt({ - retainOnlyLabelPasted : false - }); - - var txtContent, htmlContent, address; - - function getPureHtml(html){ - return html.replace(/<(\/?)([\w\-]+)([^>]*)>/gi, function (a, b, tagName, attrs) { - tagName = tagName.toLowerCase(); - if ({img: 1}[tagName]) { - return a; - } - attrs = attrs.replace(/([\w\-]*?)\s*=\s*(("([^"]*)")|('([^']*)')|([^\s>]+))/gi, function (str, atr, val) { - if ({ - 'src': 1, - 'href': 1, - 'name': 1 - }[atr.toLowerCase()]) { - return atr + '=' + val + ' ' - } - return '' - }); - if ({ - 'span': 1, - 'div': 1 - }[tagName]) { - return '' - } else { - - return '<' + b + tagName + ' ' + utils.trim(attrs) + '>' - } - - }); - } - function filter(div) { - var html; - if (div.firstChild) { - //去掉cut中添加的边界值 - var nodes = domUtils.getElementsByTagName(div, 'span'); - for (var i = 0, ni; ni = nodes[i++];) { - if (ni.id == '_baidu_cut_start' || ni.id == '_baidu_cut_end') { - domUtils.remove(ni); - } - } - - if (browser.webkit) { - - var brs = div.querySelectorAll('div br'); - for (var i = 0, bi; bi = brs[i++];) { - var pN = bi.parentNode; - if (pN.tagName == 'DIV' && pN.childNodes.length == 1) { - pN.innerHTML = '


    '; - domUtils.remove(pN); - } - } - var divs = div.querySelectorAll('#baidu_pastebin'); - for (var i = 0, di; di = divs[i++];) { - var tmpP = me.document.createElement('p'); - di.parentNode.insertBefore(tmpP, di); - while (di.firstChild) { - tmpP.appendChild(di.firstChild); - } - domUtils.remove(di); - } - - var metas = div.querySelectorAll('meta'); - for (var i = 0, ci; ci = metas[i++];) { - domUtils.remove(ci); - } - - var brs = div.querySelectorAll('br'); - for (i = 0; ci = brs[i++];) { - if (/^apple-/i.test(ci.className)) { - domUtils.remove(ci); - } - } - } - if (browser.gecko) { - var dirtyNodes = div.querySelectorAll('[_moz_dirty]'); - for (i = 0; ci = dirtyNodes[i++];) { - ci.removeAttribute('_moz_dirty'); - } - } - if (!browser.ie) { - var spans = div.querySelectorAll('span.Apple-style-span'); - for (var i = 0, ci; ci = spans[i++];) { - domUtils.remove(ci, true); - } - } - - //ie下使用innerHTML会产生多余的\r\n字符,也会产生 这里过滤掉 - html = div.innerHTML;//.replace(/>(?:(\s| )*?)<'); - - //过滤word粘贴过来的冗余属性 - html = UE.filterWord(html); - //取消了忽略空白的第二个参数,粘贴过来的有些是有空白的,会被套上相关的标签 - var root = UE.htmlparser(html); - //如果给了过滤规则就先进行过滤 - if (me.options.filterRules) { - UE.filterNode(root, me.options.filterRules); - } - //执行默认的处理 - me.filterInputRule(root); - //针对chrome的处理 - if (browser.webkit) { - var br = root.lastChild(); - if (br && br.type == 'element' && br.tagName == 'br') { - root.removeChild(br) - } - utils.each(me.body.querySelectorAll('div'), function (node) { - if (domUtils.isEmptyBlock(node)) { - domUtils.remove(node,true) - } - }) - } - html = {'html': root.toHtml()}; - me.fireEvent('beforepaste', html, root); - //抢了默认的粘贴,那后边的内容就不执行了,比如表格粘贴 - if(!html.html){ - return; - } - root = UE.htmlparser(html.html,true); - //如果开启了纯文本模式 - if (me.queryCommandState('pasteplain') === 1) { - me.execCommand('insertHtml', UE.filterNode(root, me.options.filterTxtRules).toHtml(), true); - } else { - //文本模式 - UE.filterNode(root, me.options.filterTxtRules); - txtContent = root.toHtml(); - //完全模式 - htmlContent = html.html; - - address = me.selection.getRange().createAddress(true); - me.execCommand('insertHtml', me.getOpt('retainOnlyLabelPasted') === true ? getPureHtml(htmlContent) : htmlContent, true); - } - me.fireEvent("afterpaste", html); - } - } - - me.addListener('pasteTransfer', function (cmd, plainType) { - - if (address && txtContent && htmlContent && txtContent != htmlContent) { - var range = me.selection.getRange(); - range.moveToAddress(address, true); - - if (!range.collapsed) { - - while (!domUtils.isBody(range.startContainer) - ) { - var start = range.startContainer; - if(start.nodeType == 1){ - start = start.childNodes[range.startOffset]; - if(!start){ - range.setStartBefore(range.startContainer); - continue; - } - var pre = start.previousSibling; - - if(pre && pre.nodeType == 3 && new RegExp('^[\n\r\t '+domUtils.fillChar+']*$').test(pre.nodeValue)){ - range.setStartBefore(pre) - } - } - if(range.startOffset == 0){ - range.setStartBefore(range.startContainer); - }else{ - break; - } - - } - while (!domUtils.isBody(range.endContainer) - ) { - var end = range.endContainer; - if(end.nodeType == 1){ - end = end.childNodes[range.endOffset]; - if(!end){ - range.setEndAfter(range.endContainer); - continue; - } - var next = end.nextSibling; - if(next && next.nodeType == 3 && new RegExp('^[\n\r\t'+domUtils.fillChar+']*$').test(next.nodeValue)){ - range.setEndAfter(next) - } - } - if(range.endOffset == range.endContainer[range.endContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length){ - range.setEndAfter(range.endContainer); - }else{ - break; - } - - } - - } - - range.deleteContents(); - range.select(true); - me.__hasEnterExecCommand = true; - var html = htmlContent; - if (plainType === 2 ) { - html = getPureHtml(html); - } else if (plainType) { - html = txtContent; - } - me.execCommand('inserthtml', html, true); - me.__hasEnterExecCommand = false; - var rng = me.selection.getRange(); - while (!domUtils.isBody(rng.startContainer) && !rng.startOffset && - rng.startContainer[rng.startContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length - ) { - rng.setStartBefore(rng.startContainer); - } - var tmpAddress = rng.createAddress(true); - address.endAddress = tmpAddress.startAddress; - } - }); - - me.addListener('ready', function () { - domUtils.on(me.body, 'cut', function () { - var range = me.selection.getRange(); - if (!range.collapsed && me.undoManger) { - me.undoManger.save(); - } - }); - - //ie下beforepaste在点击右键时也会触发,所以用监控键盘才处理 - domUtils.on(me.body, browser.ie || browser.opera ? 'keydown' : 'paste', function (e) { - if ((browser.ie || browser.opera) && ((!e.ctrlKey && !e.metaKey) || e.keyCode != '86')) { - return; - } - getClipboardData.call(me, function (div) { - filter(div); - }); - }); - - }); - - me.commands['paste'] = { - execCommand: function (cmd) { - if (browser.ie) { - getClipboardData.call(me, function (div) { - filter(div); - }); - me.document.execCommand('paste'); - } else { - alert(me.getLang('pastemsg')); - } - } - } -}; - - - -// plugins/puretxtpaste.js -/** - * 纯文本粘贴插件 - * @file - * @since 1.2.6.1 - */ - -UE.plugins['pasteplain'] = function(){ - var me = this; - me.setOpt({ - 'pasteplain':false, - 'filterTxtRules' : function(){ - function transP(node){ - node.tagName = 'p'; - node.setStyle(); - } - function removeNode(node){ - node.parentNode.removeChild(node,true) - } - return { - //直接删除及其字节点内容 - '-' : 'script style object iframe embed input select', - 'p': {$:{}}, - 'br':{$:{}}, - div: function (node) { - var tmpNode, p = UE.uNode.createElement('p'); - while (tmpNode = node.firstChild()) { - if (tmpNode.type == 'text' || !UE.dom.dtd.$block[tmpNode.tagName]) { - p.appendChild(tmpNode); - } else { - if (p.firstChild()) { - node.parentNode.insertBefore(p, node); - p = UE.uNode.createElement('p'); - } else { - node.parentNode.insertBefore(tmpNode, node); - } - } - } - if (p.firstChild()) { - node.parentNode.insertBefore(p, node); - } - node.parentNode.removeChild(node); - }, - ol: removeNode, - ul: removeNode, - dl:removeNode, - dt:removeNode, - dd:removeNode, - 'li':removeNode, - 'caption':transP, - 'th':transP, - 'tr':transP, - 'h1':transP,'h2':transP,'h3':transP,'h4':transP,'h5':transP,'h6':transP, - 'td':function(node){ - //没有内容的td直接删掉 - var txt = !!node.innerText(); - if(txt){ - node.parentNode.insertAfter(UE.uNode.createText('    '),node); - } - node.parentNode.removeChild(node,node.innerText()) - } - } - }() - }); - //暂时这里支持一下老版本的属性 - var pasteplain = me.options.pasteplain; - - /** - * 启用或取消纯文本粘贴模式 - * @command pasteplain - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.queryCommandState( 'pasteplain' ); - * ``` - */ - - /** - * 查询当前是否处于纯文本粘贴模式 - * @command pasteplain - * @method queryCommandState - * @param { String } cmd 命令字符串 - * @return { int } 如果处于纯文本模式,返回1,否则,返回0 - * @example - * ```javascript - * editor.queryCommandState( 'pasteplain' ); - * ``` - */ - me.commands['pasteplain'] = { - queryCommandState: function (){ - return pasteplain ? 1 : 0; - }, - execCommand: function (){ - pasteplain = !pasteplain|0; - }, - notNeedUndo : 1 - }; -}; - -// plugins/list.js -/** - * 有序列表,无序列表插件 - * @file - * @since 1.2.6.1 - */ - -UE.plugins['list'] = function () { - var me = this, - notExchange = { - 'TD':1, - 'PRE':1, - 'BLOCKQUOTE':1 - }; - var customStyle = { - 'cn' : 'cn-1-', - 'cn1' : 'cn-2-', - 'cn2' : 'cn-3-', - 'num': 'num-1-', - 'num1' : 'num-2-', - 'num2' : 'num-3-', - 'dash' : 'dash', - 'dot':'dot' - }; - - me.setOpt( { - 'autoTransWordToList':false, - 'insertorderedlist':{ - 'num':'', - 'num1':'', - 'num2':'', - 'cn':'', - 'cn1':'', - 'cn2':'', - 'decimal':'', - 'lower-alpha':'', - 'lower-roman':'', - 'upper-alpha':'', - 'upper-roman':'' - }, - 'insertunorderedlist':{ - 'circle':'', - 'disc':'', - 'square':'', - 'dash' : '', - 'dot':'' - }, - listDefaultPaddingLeft : '30', - listiconpath : 'http://bs.baidu.com/listicon/', - maxListLevel : -1,//-1不限制 - disablePInList:false - } ); - function listToArray(list){ - var arr = []; - for(var p in list){ - arr.push(p) - } - return arr; - } - var listStyle = { - 'OL':listToArray(me.options.insertorderedlist), - 'UL':listToArray(me.options.insertunorderedlist) - }; - var liiconpath = me.options.listiconpath; - - //根据用户配置,调整customStyle - for(var s in customStyle){ - if(!me.options.insertorderedlist.hasOwnProperty(s) && !me.options.insertunorderedlist.hasOwnProperty(s)){ - delete customStyle[s]; - } - } - - me.ready(function () { - var customCss = []; - for(var p in customStyle){ - if(p == 'dash' || p == 'dot'){ - customCss.push('li.list-' + customStyle[p] + '{background-image:url(' + liiconpath +customStyle[p]+'.gif)}'); - customCss.push('ul.custom_'+p+'{list-style:none;}ul.custom_'+p+' li{background-position:0 3px;background-repeat:no-repeat}'); - }else{ - for(var i= 0;i<99;i++){ - customCss.push('li.list-' + customStyle[p] + i + '{background-image:url(' + liiconpath + 'list-'+customStyle[p] + i + '.gif)}') - } - customCss.push('ol.custom_'+p+'{list-style:none;}ol.custom_'+p+' li{background-position:0 3px;background-repeat:no-repeat}'); - } - switch(p){ - case 'cn': - customCss.push('li.list-'+p+'-paddingleft-1{padding-left:25px}'); - customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}'); - customCss.push('li.list-'+p+'-paddingleft-3{padding-left:55px}'); - break; - case 'cn1': - customCss.push('li.list-'+p+'-paddingleft-1{padding-left:30px}'); - customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}'); - customCss.push('li.list-'+p+'-paddingleft-3{padding-left:55px}'); - break; - case 'cn2': - customCss.push('li.list-'+p+'-paddingleft-1{padding-left:40px}'); - customCss.push('li.list-'+p+'-paddingleft-2{padding-left:55px}'); - customCss.push('li.list-'+p+'-paddingleft-3{padding-left:68px}'); - break; - case 'num': - case 'num1': - customCss.push('li.list-'+p+'-paddingleft-1{padding-left:25px}'); - break; - case 'num2': - customCss.push('li.list-'+p+'-paddingleft-1{padding-left:35px}'); - customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}'); - break; - case 'dash': - customCss.push('li.list-'+p+'-paddingleft{padding-left:35px}'); - break; - case 'dot': - customCss.push('li.list-'+p+'-paddingleft{padding-left:20px}'); - } - } - customCss.push('.list-paddingleft-1{padding-left:0}'); - customCss.push('.list-paddingleft-2{padding-left:'+me.options.listDefaultPaddingLeft+'px}'); - customCss.push('.list-paddingleft-3{padding-left:'+me.options.listDefaultPaddingLeft*2+'px}'); - //如果不给宽度会在自定应样式里出现滚动条 - utils.cssRule('list', 'ol,ul{margin:0;pading:0;'+(browser.ie ? '' : 'width:95%')+'}li{clear:both;}'+customCss.join('\n'), me.document); - }); - //单独处理剪切的问题 - me.ready(function(){ - domUtils.on(me.body,'cut',function(){ - setTimeout(function(){ - var rng = me.selection.getRange(),li; - //trace:3416 - if(!rng.collapsed){ - if(li = domUtils.findParentByTagName(rng.startContainer,'li',true)){ - if(!li.nextSibling && domUtils.isEmptyBlock(li)){ - var pn = li.parentNode,node; - if(node = pn.previousSibling){ - domUtils.remove(pn); - rng.setStartAtLast(node).collapse(true); - rng.select(true); - }else if(node = pn.nextSibling){ - domUtils.remove(pn); - rng.setStartAtFirst(node).collapse(true); - rng.select(true); - }else{ - var tmpNode = me.document.createElement('p'); - domUtils.fillNode(me.document,tmpNode); - pn.parentNode.insertBefore(tmpNode,pn); - domUtils.remove(pn); - rng.setStart(tmpNode,0).collapse(true); - rng.select(true); - } - } - } - } - - }) - }) - }); - - function getStyle(node){ - var cls = node.className; - if(domUtils.hasClass(node,/custom_/)){ - return cls.match(/custom_(\w+)/)[1] - } - return domUtils.getStyle(node, 'list-style-type') - - } - - me.addListener('beforepaste',function(type,html){ - var me = this, - rng = me.selection.getRange(),li; - var root = UE.htmlparser(html.html,true); - if(li = domUtils.findParentByTagName(rng.startContainer,'li',true)){ - var list = li.parentNode,tagName = list.tagName == 'OL' ? 'ul':'ol'; - utils.each(root.getNodesByTagName(tagName),function(n){ - n.tagName = list.tagName; - n.setAttr(); - if(n.parentNode === root){ - type = getStyle(list) || (list.tagName == 'OL' ? 'decimal' : 'disc') - }else{ - var className = n.parentNode.getAttr('class'); - if(className && /custom_/.test(className)){ - type = className.match(/custom_(\w+)/)[1] - }else{ - type = n.parentNode.getStyle('list-style-type'); - } - if(!type){ - type = list.tagName == 'OL' ? 'decimal' : 'disc'; - } - } - var index = utils.indexOf(listStyle[list.tagName], type); - if(n.parentNode !== root) - index = index + 1 == listStyle[list.tagName].length ? 0 : index + 1; - var currentStyle = listStyle[list.tagName][index]; - if(customStyle[currentStyle]){ - n.setAttr('class', 'custom_' + currentStyle) - - }else{ - n.setStyle('list-style-type',currentStyle) - } - }) - - } - - html.html = root.toHtml(); - }); - //导出时,去掉p标签 - me.getOpt('disablePInList') === true && me.addOutputRule(function(root){ - utils.each(root.getNodesByTagName('li'),function(li){ - var newChildrens = [],index=0; - utils.each(li.children,function(n){ - if(n.tagName == 'p'){ - var tmpNode; - while(tmpNode = n.children.pop()) { - newChildrens.splice(index,0,tmpNode); - tmpNode.parentNode = li; - lastNode = tmpNode; - } - tmpNode = newChildrens[newChildrens.length-1]; - if(!tmpNode || tmpNode.type != 'element' || tmpNode.tagName != 'br'){ - var br = UE.uNode.createElement('br'); - br.parentNode = li; - newChildrens.push(br); - } - - index = newChildrens.length; - } - }); - if(newChildrens.length){ - li.children = newChildrens; - } - }); - }); - //进入编辑器的li要套p标签 - me.addInputRule(function(root){ - utils.each(root.getNodesByTagName('li'),function(li){ - var tmpP = UE.uNode.createElement('p'); - for(var i= 0,ci;ci=li.children[i];){ - if(ci.type == 'text' || dtd.p[ci.tagName]){ - tmpP.appendChild(ci); - }else{ - if(tmpP.firstChild()){ - li.insertBefore(tmpP,ci); - tmpP = UE.uNode.createElement('p'); - i = i + 2; - }else{ - i++; - } - - } - } - if(tmpP.firstChild() && !tmpP.parentNode || !li.firstChild()){ - li.appendChild(tmpP); - } - //trace:3357 - //p不能为空 - if (!tmpP.firstChild()) { - tmpP.innerHTML(browser.ie ? ' ' : '
    ') - } - //去掉末尾的空白 - var p = li.firstChild(); - var lastChild = p.lastChild(); - if(lastChild && lastChild.type == 'text' && /^\s*$/.test(lastChild.data)){ - p.removeChild(lastChild) - } - }); - if(me.options.autoTransWordToList){ - var orderlisttype = { - 'num1':/^\d+\)/, - 'decimal':/^\d+\./, - 'lower-alpha':/^[a-z]+\)/, - 'upper-alpha':/^[A-Z]+\./, - 'cn':/^[\u4E00\u4E8C\u4E09\u56DB\u516d\u4e94\u4e03\u516b\u4e5d]+[\u3001]/, - 'cn2':/^\([\u4E00\u4E8C\u4E09\u56DB\u516d\u4e94\u4e03\u516b\u4e5d]+\)/ - }, - unorderlisttype = { - 'square':'n' - }; - function checkListType(content,container){ - var span = container.firstChild(); - if(span && span.type == 'element' && span.tagName == 'span' && /Wingdings|Symbol/.test(span.getStyle('font-family'))){ - for(var p in unorderlisttype){ - if(unorderlisttype[p] == span.data){ - return p - } - } - return 'disc' - } - for(var p in orderlisttype){ - if(orderlisttype[p].test(content)){ - return p; - } - } - - } - utils.each(root.getNodesByTagName('p'),function(node){ - if(node.getAttr('class') != 'MsoListParagraph'){ - return - } - - //word粘贴过来的会带有margin要去掉,但这样也可能会误命中一些央视 - node.setStyle('margin',''); - node.setStyle('margin-left',''); - node.setAttr('class',''); - - function appendLi(list,p,type){ - if(list.tagName == 'ol'){ - if(browser.ie){ - var first = p.firstChild(); - if(first.type =='element' && first.tagName == 'span' && orderlisttype[type].test(first.innerText())){ - p.removeChild(first); - } - }else{ - p.innerHTML(p.innerHTML().replace(orderlisttype[type],'')); - } - }else{ - p.removeChild(p.firstChild()) - } - - var li = UE.uNode.createElement('li'); - li.appendChild(p); - list.appendChild(li); - } - var tmp = node,type,cacheNode = node; - - if(node.parentNode.tagName != 'li' && (type = checkListType(node.innerText(),node))){ - - var list = UE.uNode.createElement(me.options.insertorderedlist.hasOwnProperty(type) ? 'ol' : 'ul'); - if(customStyle[type]){ - list.setAttr('class','custom_'+type) - }else{ - list.setStyle('list-style-type',type) - } - while(node && node.parentNode.tagName != 'li' && checkListType(node.innerText(),node)){ - tmp = node.nextSibling(); - if(!tmp){ - node.parentNode.insertBefore(list,node) - } - appendLi(list,node,type); - node = tmp; - } - if(!list.parentNode && node && node.parentNode){ - node.parentNode.insertBefore(list,node) - } - } - var span = cacheNode.firstChild(); - if(span && span.type == 'element' && span.tagName == 'span' && /^\s*( )+\s*$/.test(span.innerText())){ - span.parentNode.removeChild(span) - } - }) - } - - }); - - //调整索引标签 - me.addListener('contentchange',function(){ - adjustListStyle(me.document) - }); - - function adjustListStyle(doc,ignore){ - utils.each(domUtils.getElementsByTagName(doc,'ol ul'),function(node){ - - if(!domUtils.inDoc(node,doc)) - return; - - var parent = node.parentNode; - if(parent.tagName == node.tagName){ - var nodeStyleType = getStyle(node) || (node.tagName == 'OL' ? 'decimal' : 'disc'), - parentStyleType = getStyle(parent) || (parent.tagName == 'OL' ? 'decimal' : 'disc'); - if(nodeStyleType == parentStyleType){ - var styleIndex = utils.indexOf(listStyle[node.tagName], nodeStyleType); - styleIndex = styleIndex + 1 == listStyle[node.tagName].length ? 0 : styleIndex + 1; - setListStyle(node,listStyle[node.tagName][styleIndex]) - } - - } - var index = 0,type = 2; - if( domUtils.hasClass(node,/custom_/)){ - if(!(/[ou]l/i.test(parent.tagName) && domUtils.hasClass(parent,/custom_/))){ - type = 1; - } - }else{ - if(/[ou]l/i.test(parent.tagName) && domUtils.hasClass(parent,/custom_/)){ - type = 3; - } - } - - var style = domUtils.getStyle(node, 'list-style-type'); - style && (node.style.cssText = 'list-style-type:' + style); - node.className = utils.trim(node.className.replace(/list-paddingleft-\w+/,'')) + ' list-paddingleft-' + type; - utils.each(domUtils.getElementsByTagName(node,'li'),function(li){ - li.style.cssText && (li.style.cssText = ''); - if(!li.firstChild){ - domUtils.remove(li); - return; - } - if(li.parentNode !== node){ - return; - } - index++; - if(domUtils.hasClass(node,/custom_/) ){ - var paddingLeft = 1,currentStyle = getStyle(node); - if(node.tagName == 'OL'){ - if(currentStyle){ - switch(currentStyle){ - case 'cn' : - case 'cn1': - case 'cn2': - if(index > 10 && (index % 10 == 0 || index > 10 && index < 20)){ - paddingLeft = 2 - }else if(index > 20){ - paddingLeft = 3 - } - break; - case 'num2' : - if(index > 9){ - paddingLeft = 2 - } - } - } - li.className = 'list-'+customStyle[currentStyle]+ index + ' ' + 'list-'+currentStyle+'-paddingleft-' + paddingLeft; - }else{ - li.className = 'list-'+customStyle[currentStyle] + ' ' + 'list-'+currentStyle+'-paddingleft'; - } - }else{ - li.className = li.className.replace(/list-[\w\-]+/gi,''); - } - var className = li.getAttribute('class'); - if(className !== null && !className.replace(/\s/g,'')){ - domUtils.removeAttributes(li,'class') - } - }); - !ignore && adjustList(node,node.tagName.toLowerCase(),getStyle(node)||domUtils.getStyle(node, 'list-style-type'),true); - }) - } - function adjustList(list, tag, style,ignoreEmpty) { - var nextList = list.nextSibling; - if (nextList && nextList.nodeType == 1 && nextList.tagName.toLowerCase() == tag && (getStyle(nextList) || domUtils.getStyle(nextList, 'list-style-type') || (tag == 'ol' ? 'decimal' : 'disc')) == style) { - domUtils.moveChild(nextList, list); - if (nextList.childNodes.length == 0) { - domUtils.remove(nextList); - } - } - if(nextList && domUtils.isFillChar(nextList)){ - domUtils.remove(nextList); - } - var preList = list.previousSibling; - if (preList && preList.nodeType == 1 && preList.tagName.toLowerCase() == tag && (getStyle(preList) || domUtils.getStyle(preList, 'list-style-type') || (tag == 'ol' ? 'decimal' : 'disc')) == style) { - domUtils.moveChild(list, preList); - } - if(preList && domUtils.isFillChar(preList)){ - domUtils.remove(preList); - } - !ignoreEmpty && domUtils.isEmptyBlock(list) && domUtils.remove(list); - if(getStyle(list)){ - adjustListStyle(list.ownerDocument,true) - } - } - - function setListStyle(list,style){ - if(customStyle[style]){ - list.className = 'custom_' + style; - } - try{ - domUtils.setStyle(list, 'list-style-type', style); - }catch(e){} - } - function clearEmptySibling(node) { - var tmpNode = node.previousSibling; - if (tmpNode && domUtils.isEmptyBlock(tmpNode)) { - domUtils.remove(tmpNode); - } - tmpNode = node.nextSibling; - if (tmpNode && domUtils.isEmptyBlock(tmpNode)) { - domUtils.remove(tmpNode); - } - } - - me.addListener('keydown', function (type, evt) { - function preventAndSave() { - evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false); - me.fireEvent('contentchange'); - me.undoManger && me.undoManger.save(); - } - function findList(node,filterFn){ - while(node && !domUtils.isBody(node)){ - if(filterFn(node)){ - return null - } - if(node.nodeType == 1 && /[ou]l/i.test(node.tagName)){ - return node; - } - node = node.parentNode; - } - return null; - } - var keyCode = evt.keyCode || evt.which; - if (keyCode == 13 && !evt.shiftKey) {//回车 - var rng = me.selection.getRange(), - parent = domUtils.findParent(rng.startContainer,function(node){return domUtils.isBlockElm(node)},true), - li = domUtils.findParentByTagName(rng.startContainer,'li',true); - if(parent && parent.tagName != 'PRE' && !li){ - var html = parent.innerHTML.replace(new RegExp(domUtils.fillChar, 'g'),''); - if(/^\s*1\s*\.[^\d]/.test(html)){ - parent.innerHTML = html.replace(/^\s*1\s*\./,''); - rng.setStartAtLast(parent).collapse(true).select(); - me.__hasEnterExecCommand = true; - me.execCommand('insertorderedlist'); - me.__hasEnterExecCommand = false; - } - } - var range = me.selection.getRange(), - start = findList(range.startContainer,function (node) { - return node.tagName == 'TABLE'; - }), - end = range.collapsed ? start : findList(range.endContainer,function (node) { - return node.tagName == 'TABLE'; - }); - - if (start && end && start === end) { - - if (!range.collapsed) { - start = domUtils.findParentByTagName(range.startContainer, 'li', true); - end = domUtils.findParentByTagName(range.endContainer, 'li', true); - if (start && end && start === end) { - range.deleteContents(); - li = domUtils.findParentByTagName(range.startContainer, 'li', true); - if (li && domUtils.isEmptyBlock(li)) { - - pre = li.previousSibling; - next = li.nextSibling; - p = me.document.createElement('p'); - - domUtils.fillNode(me.document, p); - parentList = li.parentNode; - if (pre && next) { - range.setStart(next, 0).collapse(true).select(true); - domUtils.remove(li); - - } else { - if (!pre && !next || !pre) { - - parentList.parentNode.insertBefore(p, parentList); - - - } else { - li.parentNode.parentNode.insertBefore(p, parentList.nextSibling); - } - domUtils.remove(li); - if (!parentList.firstChild) { - domUtils.remove(parentList); - } - range.setStart(p, 0).setCursor(); - - - } - preventAndSave(); - return; - - } - } else { - var tmpRange = range.cloneRange(), - bk = tmpRange.collapse(false).createBookmark(); - - range.deleteContents(); - tmpRange.moveToBookmark(bk); - var li = domUtils.findParentByTagName(tmpRange.startContainer, 'li', true); - - clearEmptySibling(li); - tmpRange.select(); - preventAndSave(); - return; - } - } - - - li = domUtils.findParentByTagName(range.startContainer, 'li', true); - - if (li) { - if (domUtils.isEmptyBlock(li)) { - bk = range.createBookmark(); - var parentList = li.parentNode; - if (li !== parentList.lastChild) { - domUtils.breakParent(li, parentList); - clearEmptySibling(li); - } else { - - parentList.parentNode.insertBefore(li, parentList.nextSibling); - if (domUtils.isEmptyNode(parentList)) { - domUtils.remove(parentList); - } - } - //嵌套不处理 - if (!dtd.$list[li.parentNode.tagName]) { - - if (!domUtils.isBlockElm(li.firstChild)) { - p = me.document.createElement('p'); - li.parentNode.insertBefore(p, li); - while (li.firstChild) { - p.appendChild(li.firstChild); - } - domUtils.remove(li); - } else { - domUtils.remove(li, true); - } - } - range.moveToBookmark(bk).select(); - - - } else { - var first = li.firstChild; - if (!first || !domUtils.isBlockElm(first)) { - var p = me.document.createElement('p'); - - !li.firstChild && domUtils.fillNode(me.document, p); - while (li.firstChild) { - - p.appendChild(li.firstChild); - } - li.appendChild(p); - first = p; - } - - var span = me.document.createElement('span'); - - range.insertNode(span); - domUtils.breakParent(span, li); - - var nextLi = span.nextSibling; - first = nextLi.firstChild; - - if (!first) { - p = me.document.createElement('p'); - - domUtils.fillNode(me.document, p); - nextLi.appendChild(p); - first = p; - } - if (domUtils.isEmptyNode(first)) { - first.innerHTML = ''; - domUtils.fillNode(me.document, first); - } - - range.setStart(first, 0).collapse(true).shrinkBoundary().select(); - domUtils.remove(span); - var pre = nextLi.previousSibling; - if (pre && domUtils.isEmptyBlock(pre)) { - pre.innerHTML = '

    '; - domUtils.fillNode(me.document, pre.firstChild); - } - - } -// } - preventAndSave(); - } - - - } - - - } - if (keyCode == 8) { - //修中ie中li下的问题 - range = me.selection.getRange(); - if (range.collapsed && domUtils.isStartInblock(range)) { - tmpRange = range.cloneRange().trimBoundary(); - li = domUtils.findParentByTagName(range.startContainer, 'li', true); - //要在li的最左边,才能处理 - if (li && domUtils.isStartInblock(tmpRange)) { - start = domUtils.findParentByTagName(range.startContainer, 'p', true); - if (start && start !== li.firstChild) { - var parentList = domUtils.findParentByTagName(start,['ol','ul']); - domUtils.breakParent(start,parentList); - clearEmptySibling(start); - me.fireEvent('contentchange'); - range.setStart(start,0).setCursor(false,true); - me.fireEvent('saveScene'); - domUtils.preventDefault(evt); - return; - } - - if (li && (pre = li.previousSibling)) { - if (keyCode == 46 && li.childNodes.length) { - return; - } - //有可能上边的兄弟节点是个2级菜单,要追加到2级菜单的最后的li - if (dtd.$list[pre.tagName]) { - pre = pre.lastChild; - } - me.undoManger && me.undoManger.save(); - first = li.firstChild; - if (domUtils.isBlockElm(first)) { - if (domUtils.isEmptyNode(first)) { -// range.setEnd(pre, pre.childNodes.length).shrinkBoundary().collapse().select(true); - pre.appendChild(first); - range.setStart(first, 0).setCursor(false, true); - //first不是唯一的节点 - while (li.firstChild) { - pre.appendChild(li.firstChild); - } - } else { - - span = me.document.createElement('span'); - range.insertNode(span); - //判断pre是否是空的节点,如果是


    类型的空节点,干掉p标签防止它占位 - if (domUtils.isEmptyBlock(pre)) { - pre.innerHTML = ''; - } - domUtils.moveChild(li, pre); - range.setStartBefore(span).collapse(true).select(true); - - domUtils.remove(span); - - } - } else { - if (domUtils.isEmptyNode(li)) { - var p = me.document.createElement('p'); - pre.appendChild(p); - range.setStart(p, 0).setCursor(); -// range.setEnd(pre, pre.childNodes.length).shrinkBoundary().collapse().select(true); - } else { - range.setEnd(pre, pre.childNodes.length).collapse().select(true); - while (li.firstChild) { - pre.appendChild(li.firstChild); - } - } - } - domUtils.remove(li); - me.fireEvent('contentchange'); - me.fireEvent('saveScene'); - domUtils.preventDefault(evt); - return; - - } - //trace:980 - - if (li && !li.previousSibling) { - var parentList = li.parentNode; - var bk = range.createBookmark(); - if(domUtils.isTagNode(parentList.parentNode,'ol ul')){ - parentList.parentNode.insertBefore(li,parentList); - if(domUtils.isEmptyNode(parentList)){ - domUtils.remove(parentList) - } - }else{ - - while(li.firstChild){ - parentList.parentNode.insertBefore(li.firstChild,parentList); - } - - domUtils.remove(li); - if(domUtils.isEmptyNode(parentList)){ - domUtils.remove(parentList) - } - - } - range.moveToBookmark(bk).setCursor(false,true); - me.fireEvent('contentchange'); - me.fireEvent('saveScene'); - domUtils.preventDefault(evt); - return; - - } - - - } - - - } - - } - }); - - me.addListener('keyup',function(type, evt){ - var keyCode = evt.keyCode || evt.which; - if (keyCode == 8) { - var rng = me.selection.getRange(),list; - if(list = domUtils.findParentByTagName(rng.startContainer,['ol', 'ul'],true)){ - adjustList(list,list.tagName.toLowerCase(),getStyle(list)||domUtils.getComputedStyle(list,'list-style-type'),true) - } - } - }); - //处理tab键 - me.addListener('tabkeydown',function(){ - - var range = me.selection.getRange(); - - //控制级数 - function checkLevel(li){ - if(me.options.maxListLevel != -1){ - var level = li.parentNode,levelNum = 0; - while(/[ou]l/i.test(level.tagName)){ - levelNum++; - level = level.parentNode; - } - if(levelNum >= me.options.maxListLevel){ - return true; - } - } - } - //只以开始为准 - //todo 后续改进 - var li = domUtils.findParentByTagName(range.startContainer, 'li', true); - if(li){ - - var bk; - if(range.collapsed){ - if(checkLevel(li)) - return true; - var parentLi = li.parentNode, - list = me.document.createElement(parentLi.tagName), - index = utils.indexOf(listStyle[list.tagName], getStyle(parentLi)||domUtils.getComputedStyle(parentLi, 'list-style-type')); - index = index + 1 == listStyle[list.tagName].length ? 0 : index + 1; - var currentStyle = listStyle[list.tagName][index]; - setListStyle(list,currentStyle); - if(domUtils.isStartInblock(range)){ - me.fireEvent('saveScene'); - bk = range.createBookmark(); - parentLi.insertBefore(list, li); - list.appendChild(li); - adjustList(list,list.tagName.toLowerCase(),currentStyle); - me.fireEvent('contentchange'); - range.moveToBookmark(bk).select(true); - return true; - } - }else{ - me.fireEvent('saveScene'); - bk = range.createBookmark(); - for(var i= 0,closeList,parents = domUtils.findParents(li),ci;ci=parents[i++];){ - if(domUtils.isTagNode(ci,'ol ul')){ - closeList = ci; - break; - } - } - var current = li; - if(bk.end){ - while(current && !(domUtils.getPosition(current, bk.end) & domUtils.POSITION_FOLLOWING)){ - if(checkLevel(current)){ - current = domUtils.getNextDomNode(current,false,null,function(node){return node !== closeList}); - continue; - } - var parentLi = current.parentNode, - list = me.document.createElement(parentLi.tagName), - index = utils.indexOf(listStyle[list.tagName], getStyle(parentLi)||domUtils.getComputedStyle(parentLi, 'list-style-type')); - var currentIndex = index + 1 == listStyle[list.tagName].length ? 0 : index + 1; - var currentStyle = listStyle[list.tagName][currentIndex]; - setListStyle(list,currentStyle); - parentLi.insertBefore(list, current); - while(current && !(domUtils.getPosition(current, bk.end) & domUtils.POSITION_FOLLOWING)){ - li = current.nextSibling; - list.appendChild(current); - if(!li || domUtils.isTagNode(li,'ol ul')){ - if(li){ - while(li = li.firstChild){ - if(li.tagName == 'LI'){ - break; - } - } - }else{ - li = domUtils.getNextDomNode(current,false,null,function(node){return node !== closeList}); - } - break; - } - current = li; - } - adjustList(list,list.tagName.toLowerCase(),currentStyle); - current = li; - } - } - me.fireEvent('contentchange'); - range.moveToBookmark(bk).select(); - return true; - } - } - - }); - function getLi(start){ - while(start && !domUtils.isBody(start)){ - if(start.nodeName == 'TABLE'){ - return null; - } - if(start.nodeName == 'LI'){ - return start - } - start = start.parentNode; - } - } - - /** - * 有序列表,与“insertunorderedlist”命令互斥 - * @command insertorderedlist - * @method execCommand - * @param { String } command 命令字符串 - * @param { String } style 插入的有序列表类型,值为:decimal,lower-alpha,lower-roman,upper-alpha,upper-roman,cn,cn1,cn2,num,num1,num2 - * @example - * ```javascript - * editor.execCommand( 'insertorderedlist','decimal'); - * ``` - */ - /** - * 查询当前选区内容是否有序列表 - * @command insertorderedlist - * @method queryCommandState - * @param { String } cmd 命令字符串 - * @return { int } 如果当前选区是有序列表返回1,否则返回0 - * @example - * ```javascript - * editor.queryCommandState( 'insertorderedlist' ); - * ``` - */ - /** - * 查询当前选区内容是否有序列表 - * @command insertorderedlist - * @method queryCommandValue - * @param { String } cmd 命令字符串 - * @return { String } 返回当前有序列表的类型,值为null或decimal,lower-alpha,lower-roman,upper-alpha,upper-roman,cn,cn1,cn2,num,num1,num2 - * @example - * ```javascript - * editor.queryCommandValue( 'insertorderedlist' ); - * ``` - */ - - /** - * 无序列表,与“insertorderedlist”命令互斥 - * @command insertunorderedlist - * @method execCommand - * @param { String } command 命令字符串 - * @param { String } style 插入的无序列表类型,值为:circle,disc,square,dash,dot - * @example - * ```javascript - * editor.execCommand( 'insertunorderedlist','circle'); - * ``` - */ - /** - * 查询当前是否有word文档粘贴进来的图片 - * @command insertunorderedlist - * @method insertunorderedlist - * @param { String } command 命令字符串 - * @return { int } 如果当前选区是无序列表返回1,否则返回0 - * @example - * ```javascript - * editor.queryCommandState( 'insertunorderedlist' ); - * ``` - */ - /** - * 查询当前选区内容是否有序列表 - * @command insertunorderedlist - * @method queryCommandValue - * @param { String } command 命令字符串 - * @return { String } 返回当前无序列表的类型,值为null或circle,disc,square,dash,dot - * @example - * ```javascript - * editor.queryCommandValue( 'insertunorderedlist' ); - * ``` - */ - - me.commands['insertorderedlist'] = - me.commands['insertunorderedlist'] = { - execCommand:function (command, style) { - - if (!style) { - style = command.toLowerCase() == 'insertorderedlist' ? 'decimal' : 'disc'; - } - var me = this, - range = this.selection.getRange(), - filterFn = function (node) { - return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' : !domUtils.isWhitespace(node); - }, - tag = command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul', - frag = me.document.createDocumentFragment(); - //去掉是因为会出现选到末尾,导致adjustmentBoundary缩到ol/ul的位置 - //range.shrinkBoundary();//.adjustmentBoundary(); - range.adjustmentBoundary().shrinkBoundary(); - var bko = range.createBookmark(true), - start = getLi(me.document.getElementById(bko.start)), - modifyStart = 0, - end = getLi(me.document.getElementById(bko.end)), - modifyEnd = 0, - startParent, endParent, - list, tmp; - - if (start || end) { - start && (startParent = start.parentNode); - if (!bko.end) { - end = start; - } - end && (endParent = end.parentNode); - - if (startParent === endParent) { - while (start !== end) { - tmp = start; - start = start.nextSibling; - if (!domUtils.isBlockElm(tmp.firstChild)) { - var p = me.document.createElement('p'); - while (tmp.firstChild) { - p.appendChild(tmp.firstChild); - } - tmp.appendChild(p); - } - frag.appendChild(tmp); - } - tmp = me.document.createElement('span'); - startParent.insertBefore(tmp, end); - if (!domUtils.isBlockElm(end.firstChild)) { - p = me.document.createElement('p'); - while (end.firstChild) { - p.appendChild(end.firstChild); - } - end.appendChild(p); - } - frag.appendChild(end); - domUtils.breakParent(tmp, startParent); - if (domUtils.isEmptyNode(tmp.previousSibling)) { - domUtils.remove(tmp.previousSibling); - } - if (domUtils.isEmptyNode(tmp.nextSibling)) { - domUtils.remove(tmp.nextSibling) - } - var nodeStyle = getStyle(startParent) || domUtils.getComputedStyle(startParent, 'list-style-type') || (command.toLowerCase() == 'insertorderedlist' ? 'decimal' : 'disc'); - if (startParent.tagName.toLowerCase() == tag && nodeStyle == style) { - for (var i = 0, ci, tmpFrag = me.document.createDocumentFragment(); ci = frag.firstChild;) { - if(domUtils.isTagNode(ci,'ol ul')){ -// 删除时,子列表不处理 -// utils.each(domUtils.getElementsByTagName(ci,'li'),function(li){ -// while(li.firstChild){ -// tmpFrag.appendChild(li.firstChild); -// } -// -// }); - tmpFrag.appendChild(ci); - }else{ - while (ci.firstChild) { - - tmpFrag.appendChild(ci.firstChild); - domUtils.remove(ci); - } - } - - } - tmp.parentNode.insertBefore(tmpFrag, tmp); - } else { - list = me.document.createElement(tag); - setListStyle(list,style); - list.appendChild(frag); - tmp.parentNode.insertBefore(list, tmp); - } - - domUtils.remove(tmp); - list && adjustList(list, tag, style); - range.moveToBookmark(bko).select(); - return; - } - //开始 - if (start) { - while (start) { - tmp = start.nextSibling; - if (domUtils.isTagNode(start, 'ol ul')) { - frag.appendChild(start); - } else { - var tmpfrag = me.document.createDocumentFragment(), - hasBlock = 0; - while (start.firstChild) { - if (domUtils.isBlockElm(start.firstChild)) { - hasBlock = 1; - } - tmpfrag.appendChild(start.firstChild); - } - if (!hasBlock) { - var tmpP = me.document.createElement('p'); - tmpP.appendChild(tmpfrag); - frag.appendChild(tmpP); - } else { - frag.appendChild(tmpfrag); - } - domUtils.remove(start); - } - - start = tmp; - } - startParent.parentNode.insertBefore(frag, startParent.nextSibling); - if (domUtils.isEmptyNode(startParent)) { - range.setStartBefore(startParent); - domUtils.remove(startParent); - } else { - range.setStartAfter(startParent); - } - modifyStart = 1; - } - - if (end && domUtils.inDoc(endParent, me.document)) { - //结束 - start = endParent.firstChild; - while (start && start !== end) { - tmp = start.nextSibling; - if (domUtils.isTagNode(start, 'ol ul')) { - frag.appendChild(start); - } else { - tmpfrag = me.document.createDocumentFragment(); - hasBlock = 0; - while (start.firstChild) { - if (domUtils.isBlockElm(start.firstChild)) { - hasBlock = 1; - } - tmpfrag.appendChild(start.firstChild); - } - if (!hasBlock) { - tmpP = me.document.createElement('p'); - tmpP.appendChild(tmpfrag); - frag.appendChild(tmpP); - } else { - frag.appendChild(tmpfrag); - } - domUtils.remove(start); - } - start = tmp; - } - var tmpDiv = domUtils.createElement(me.document, 'div', { - 'tmpDiv':1 - }); - domUtils.moveChild(end, tmpDiv); - - frag.appendChild(tmpDiv); - domUtils.remove(end); - endParent.parentNode.insertBefore(frag, endParent); - range.setEndBefore(endParent); - if (domUtils.isEmptyNode(endParent)) { - domUtils.remove(endParent); - } - - modifyEnd = 1; - } - - - } - - if (!modifyStart) { - range.setStartBefore(me.document.getElementById(bko.start)); - } - if (bko.end && !modifyEnd) { - range.setEndAfter(me.document.getElementById(bko.end)); - } - range.enlarge(true, function (node) { - return notExchange[node.tagName]; - }); - - frag = me.document.createDocumentFragment(); - - var bk = range.createBookmark(), - current = domUtils.getNextDomNode(bk.start, false, filterFn), - tmpRange = range.cloneRange(), - tmpNode, - block = domUtils.isBlockElm; - - while (current && current !== bk.end && (domUtils.getPosition(current, bk.end) & domUtils.POSITION_PRECEDING)) { - - if (current.nodeType == 3 || dtd.li[current.tagName]) { - if (current.nodeType == 1 && dtd.$list[current.tagName]) { - while (current.firstChild) { - frag.appendChild(current.firstChild); - } - tmpNode = domUtils.getNextDomNode(current, false, filterFn); - domUtils.remove(current); - current = tmpNode; - continue; - - } - tmpNode = current; - tmpRange.setStartBefore(current); - - while (current && current !== bk.end && (!block(current) || domUtils.isBookmarkNode(current) )) { - tmpNode = current; - current = domUtils.getNextDomNode(current, false, null, function (node) { - return !notExchange[node.tagName]; - }); - } - - if (current && block(current)) { - tmp = domUtils.getNextDomNode(tmpNode, false, filterFn); - if (tmp && domUtils.isBookmarkNode(tmp)) { - current = domUtils.getNextDomNode(tmp, false, filterFn); - tmpNode = tmp; - } - } - tmpRange.setEndAfter(tmpNode); - - current = domUtils.getNextDomNode(tmpNode, false, filterFn); - - var li = range.document.createElement('li'); - - li.appendChild(tmpRange.extractContents()); - if(domUtils.isEmptyNode(li)){ - var tmpNode = range.document.createElement('p'); - while(li.firstChild){ - tmpNode.appendChild(li.firstChild) - } - li.appendChild(tmpNode); - } - frag.appendChild(li); - } else { - current = domUtils.getNextDomNode(current, true, filterFn); - } - } - range.moveToBookmark(bk).collapse(true); - list = me.document.createElement(tag); - setListStyle(list,style); - list.appendChild(frag); - range.insertNode(list); - //当前list上下看能否合并 - adjustList(list, tag, style); - //去掉冗余的tmpDiv - for (var i = 0, ci, tmpDivs = domUtils.getElementsByTagName(list, 'div'); ci = tmpDivs[i++];) { - if (ci.getAttribute('tmpDiv')) { - domUtils.remove(ci, true) - } - } - range.moveToBookmark(bko).select(); - - }, - queryCommandState:function (command) { - var tag = command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul'; - var path = this.selection.getStartElementPath(); - for(var i= 0,ci;ci = path[i++];){ - if(ci.nodeName == 'TABLE'){ - return 0 - } - if(tag == ci.nodeName.toLowerCase()){ - return 1 - }; - } - return 0; - - }, - queryCommandValue:function (command) { - var tag = command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul'; - var path = this.selection.getStartElementPath(), - node; - for(var i= 0,ci;ci = path[i++];){ - if(ci.nodeName == 'TABLE'){ - node = null; - break; - } - if(tag == ci.nodeName.toLowerCase()){ - node = ci; - break; - }; - } - return node ? getStyle(node) || domUtils.getComputedStyle(node, 'list-style-type') : null; - } - }; -}; - - - -// plugins/source.js -/** - * 源码编辑插件 - * @file - * @since 1.2.6.1 - */ - -(function (){ - var sourceEditors = { - textarea: function (editor, holder){ - var textarea = holder.ownerDocument.createElement('textarea'); - textarea.style.cssText = 'position:absolute;resize:none;width:100%;height:100%;border:0;padding:0;margin:0;overflow-y:auto;'; - // todo: IE下只有onresize属性可用... 很纠结 - if (browser.ie && browser.version < 8) { - textarea.style.width = holder.offsetWidth + 'px'; - textarea.style.height = holder.offsetHeight + 'px'; - holder.onresize = function (){ - textarea.style.width = holder.offsetWidth + 'px'; - textarea.style.height = holder.offsetHeight + 'px'; - }; - } - holder.appendChild(textarea); - return { - setContent: function (content){ - textarea.value = content; - }, - getContent: function (){ - return textarea.value; - }, - select: function (){ - var range; - if (browser.ie) { - range = textarea.createTextRange(); - range.collapse(true); - range.select(); - } else { - //todo: chrome下无法设置焦点 - textarea.setSelectionRange(0, 0); - textarea.focus(); - } - }, - dispose: function (){ - holder.removeChild(textarea); - // todo - holder.onresize = null; - textarea = null; - holder = null; - } - }; - }, - codemirror: function (editor, holder){ - - var codeEditor = window.CodeMirror(holder, { - mode: "text/html", - tabMode: "indent", - lineNumbers: true, - lineWrapping:true - }); - var dom = codeEditor.getWrapperElement(); - dom.style.cssText = 'position:absolute;left:0;top:0;width:100%;height:100%;font-family:consolas,"Courier new",monospace;font-size:13px;'; - codeEditor.getScrollerElement().style.cssText = 'position:absolute;left:0;top:0;width:100%;height:100%;'; - codeEditor.refresh(); - return { - getCodeMirror:function(){ - return codeEditor; - }, - setContent: function (content){ - codeEditor.setValue(content); - }, - getContent: function (){ - return codeEditor.getValue(); - }, - select: function (){ - codeEditor.focus(); - }, - dispose: function (){ - holder.removeChild(dom); - dom = null; - codeEditor = null; - } - }; - } - }; - - UE.plugins['source'] = function (){ - var me = this; - var opt = this.options; - var sourceMode = false; - var sourceEditor; - var orgSetContent; - opt.sourceEditor = browser.ie ? 'textarea' : (opt.sourceEditor || 'codemirror'); - - me.setOpt({ - sourceEditorFirst:false - }); - function createSourceEditor(holder){ - return sourceEditors[opt.sourceEditor == 'codemirror' && window.CodeMirror ? 'codemirror' : 'textarea'](me, holder); - } - - var bakCssText; - //解决在源码模式下getContent不能得到最新的内容问题 - var oldGetContent, - bakAddress; - - /** - * 切换源码模式和编辑模式 - * @command source - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'source'); - * ``` - */ - - /** - * 查询当前编辑区域的状态是源码模式还是可视化模式 - * @command source - * @method queryCommandState - * @param { String } cmd 命令字符串 - * @return { int } 如果当前是源码编辑模式,返回1,否则返回0 - * @example - * ```javascript - * editor.queryCommandState( 'source' ); - * ``` - */ - - me.commands['source'] = { - execCommand: function (){ - - sourceMode = !sourceMode; - if (sourceMode) { - bakAddress = me.selection.getRange().createAddress(false,true); - me.undoManger && me.undoManger.save(true); - if(browser.gecko){ - me.body.contentEditable = false; - } - - bakCssText = me.iframe.style.cssText; - me.iframe.style.cssText += 'position:absolute;left:-32768px;top:-32768px;'; - - - me.fireEvent('beforegetcontent'); - var root = UE.htmlparser(me.body.innerHTML); - me.filterOutputRule(root); - root.traversal(function (node) { - if (node.type == 'element') { - switch (node.tagName) { - case 'td': - case 'th': - case 'caption': - if(node.children && node.children.length == 1){ - if(node.firstChild().tagName == 'br' ){ - node.removeChild(node.firstChild()) - } - }; - break; - case 'pre': - node.innerText(node.innerText().replace(/ /g,' ')) - - } - } - }); - - me.fireEvent('aftergetcontent'); - - var content = root.toHtml(true); - - sourceEditor = createSourceEditor(me.iframe.parentNode); - - sourceEditor.setContent(content); - - orgSetContent = me.setContent; - - me.setContent = function(html){ - //这里暂时不触发事件,防止报错 - var root = UE.htmlparser(html); - me.filterInputRule(root); - html = root.toHtml(); - sourceEditor.setContent(html); - }; - - setTimeout(function (){ - sourceEditor.select(); - me.addListener('fullscreenchanged', function(){ - try{ - sourceEditor.getCodeMirror().refresh() - }catch(e){} - }); - }); - - //重置getContent,源码模式下取值也能是最新的数据 - oldGetContent = me.getContent; - me.getContent = function (){ - return sourceEditor.getContent() || '

    ' + (browser.ie ? '' : '
    ')+'

    '; - }; - } else { - me.iframe.style.cssText = bakCssText; - var cont = sourceEditor.getContent() || '

    ' + (browser.ie ? '' : '
    ')+'

    '; - //处理掉block节点前后的空格,有可能会误命中,暂时不考虑 - cont = cont.replace(new RegExp('[\\r\\t\\n ]*<\/?(\\w+)\\s*(?:[^>]*)>','g'), function(a,b){ - if(b && !dtd.$inlineWithA[b.toLowerCase()]){ - return a.replace(/(^[\n\r\t ]*)|([\n\r\t ]*$)/g,''); - } - return a.replace(/(^[\n\r\t]*)|([\n\r\t]*$)/g,'') - }); - me.setContent = orgSetContent; - - me.setContent(cont); - sourceEditor.dispose(); - sourceEditor = null; - //还原getContent方法 - me.getContent = oldGetContent; - var first = me.body.firstChild; - //trace:1106 都删除空了,下边会报错,所以补充一个p占位 - if(!first){ - me.body.innerHTML = '

    '+(browser.ie?'':'
    ')+'

    '; - first = me.body.firstChild; - } - - - //要在ifm为显示时ff才能取到selection,否则报错 - //这里不能比较位置了 - me.undoManger && me.undoManger.save(true); - - if(browser.gecko){ - - var input = document.createElement('input'); - input.style.cssText = 'position:absolute;left:0;top:-32768px'; - - document.body.appendChild(input); - - me.body.contentEditable = false; - setTimeout(function(){ - domUtils.setViewportOffset(input, { left: -32768, top: 0 }); - input.focus(); - setTimeout(function(){ - me.body.contentEditable = true; - me.selection.getRange().moveToAddress(bakAddress).select(true); - domUtils.remove(input); - }); - - }); - }else{ - //ie下有可能报错,比如在代码顶头的情况 - try{ - me.selection.getRange().moveToAddress(bakAddress).select(true); - }catch(e){} - - } - } - this.fireEvent('sourcemodechanged', sourceMode); - }, - queryCommandState: function (){ - return sourceMode|0; - }, - notNeedUndo : 1 - }; - var oldQueryCommandState = me.queryCommandState; - - me.queryCommandState = function (cmdName){ - cmdName = cmdName.toLowerCase(); - if (sourceMode) { - //源码模式下可以开启的命令 - return cmdName in { - 'source' : 1, - 'fullscreen' : 1 - } ? 1 : -1 - } - return oldQueryCommandState.apply(this, arguments); - }; - - if(opt.sourceEditor == "codemirror"){ - - me.addListener("ready",function(){ - utils.loadFile(document,{ - src : opt.codeMirrorJsUrl || opt.UEDITOR_HOME_URL + "third-party/codemirror/codemirror.js", - tag : "script", - type : "text/javascript", - defer : "defer" - },function(){ - if(opt.sourceEditorFirst){ - setTimeout(function(){ - me.execCommand("source"); - },0); - } - }); - utils.loadFile(document,{ - tag : "link", - rel : "stylesheet", - type : "text/css", - href : opt.codeMirrorCssUrl || opt.UEDITOR_HOME_URL + "third-party/codemirror/codemirror.css" - }); - - }); - } - - }; - -})(); - -// plugins/enterkey.js -///import core -///import plugins/undo.js -///commands 设置回车标签p或br -///commandsName EnterKey -///commandsTitle 设置回车标签p或br -/** - * @description 处理回车 - * @author zhanyi - */ -UE.plugins['enterkey'] = function() { - var hTag, - me = this, - tag = me.options.enterTag; - me.addListener('keyup', function(type, evt) { - - var keyCode = evt.keyCode || evt.which; - if (keyCode == 13) { - var range = me.selection.getRange(), - start = range.startContainer, - doSave; - - //修正在h1-h6里边回车后不能嵌套p的问题 - if (!browser.ie) { - - if (/h\d/i.test(hTag)) { - if (browser.gecko) { - var h = domUtils.findParentByTagName(start, [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6','blockquote','caption','table'], true); - if (!h) { - me.document.execCommand('formatBlock', false, '

    '); - doSave = 1; - } - } else { - //chrome remove div - if (start.nodeType == 1) { - var tmp = me.document.createTextNode(''),div; - range.insertNode(tmp); - div = domUtils.findParentByTagName(tmp, 'div', true); - if (div) { - var p = me.document.createElement('p'); - while (div.firstChild) { - p.appendChild(div.firstChild); - } - div.parentNode.insertBefore(p, div); - domUtils.remove(div); - range.setStartBefore(tmp).setCursor(); - doSave = 1; - } - domUtils.remove(tmp); - - } - } - - if (me.undoManger && doSave) { - me.undoManger.save(); - } - } - //没有站位符,会出现多行的问题 - browser.opera && range.select(); - }else{ - me.fireEvent('saveScene',true,true) - } - } - }); - - me.addListener('keydown', function(type, evt) { - var keyCode = evt.keyCode || evt.which; - if (keyCode == 13) {//回车 - if(me.fireEvent('beforeenterkeydown')){ - domUtils.preventDefault(evt); - return; - } - me.fireEvent('saveScene',true,true); - hTag = ''; - - - var range = me.selection.getRange(); - - if (!range.collapsed) { - //跨td不能删 - var start = range.startContainer, - end = range.endContainer, - startTd = domUtils.findParentByTagName(start, 'td', true), - endTd = domUtils.findParentByTagName(end, 'td', true); - if (startTd && endTd && startTd !== endTd || !startTd && endTd || startTd && !endTd) { - evt.preventDefault ? evt.preventDefault() : ( evt.returnValue = false); - return; - } - } - if (tag == 'p') { - - - if (!browser.ie) { - - start = domUtils.findParentByTagName(range.startContainer, ['ol','ul','p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6','blockquote','caption'], true); - - //opera下执行formatblock会在table的场景下有问题,回车在opera原生支持很好,所以暂时在opera去掉调用这个原生的command - //trace:2431 - if (!start && !browser.opera) { - - me.document.execCommand('formatBlock', false, '

    '); - - if (browser.gecko) { - range = me.selection.getRange(); - start = domUtils.findParentByTagName(range.startContainer, 'p', true); - start && domUtils.removeDirtyAttr(start); - } - - - } else { - hTag = start.tagName; - start.tagName.toLowerCase() == 'p' && browser.gecko && domUtils.removeDirtyAttr(start); - } - - } - - } else { - evt.preventDefault ? evt.preventDefault() : ( evt.returnValue = false); - - if (!range.collapsed) { - range.deleteContents(); - start = range.startContainer; - if (start.nodeType == 1 && (start = start.childNodes[range.startOffset])) { - while (start.nodeType == 1) { - if (dtd.$empty[start.tagName]) { - range.setStartBefore(start).setCursor(); - if (me.undoManger) { - me.undoManger.save(); - } - return false; - } - if (!start.firstChild) { - var br = range.document.createElement('br'); - start.appendChild(br); - range.setStart(start, 0).setCursor(); - if (me.undoManger) { - me.undoManger.save(); - } - return false; - } - start = start.firstChild; - } - if (start === range.startContainer.childNodes[range.startOffset]) { - br = range.document.createElement('br'); - range.insertNode(br).setCursor(); - - } else { - range.setStart(start, 0).setCursor(); - } - - - } else { - br = range.document.createElement('br'); - range.insertNode(br).setStartAfter(br).setCursor(); - } - - - } else { - br = range.document.createElement('br'); - range.insertNode(br); - var parent = br.parentNode; - if (parent.lastChild === br) { - br.parentNode.insertBefore(br.cloneNode(true), br); - range.setStartBefore(br); - } else { - range.setStartAfter(br); - } - range.setCursor(); - - } - - } - - } - }); -}; - - -// plugins/keystrokes.js -/* 处理特殊键的兼容性问题 */ -UE.plugins['keystrokes'] = function() { - var me = this; - var collapsed = true; - me.addListener('keydown', function(type, evt) { - var keyCode = evt.keyCode || evt.which, - rng = me.selection.getRange(); - - //处理全选的情况 - if(!rng.collapsed && !(evt.ctrlKey || evt.shiftKey || evt.altKey || evt.metaKey) && (keyCode >= 65 && keyCode <=90 - || keyCode >= 48 && keyCode <= 57 || - keyCode >= 96 && keyCode <= 111 || { - 13:1, - 8:1, - 46:1 - }[keyCode]) - ){ - - var tmpNode = rng.startContainer; - if(domUtils.isFillChar(tmpNode)){ - rng.setStartBefore(tmpNode) - } - tmpNode = rng.endContainer; - if(domUtils.isFillChar(tmpNode)){ - rng.setEndAfter(tmpNode) - } - rng.txtToElmBoundary(); - //结束边界可能放到了br的前边,要把br包含进来 - // x[xxx]
    - if(rng.endContainer && rng.endContainer.nodeType == 1){ - tmpNode = rng.endContainer.childNodes[rng.endOffset]; - if(tmpNode && domUtils.isBr(tmpNode)){ - rng.setEndAfter(tmpNode); - } - } - if(rng.startOffset == 0){ - tmpNode = rng.startContainer; - if(domUtils.isBoundaryNode(tmpNode,'firstChild') ){ - tmpNode = rng.endContainer; - if(rng.endOffset == (tmpNode.nodeType == 3 ? tmpNode.nodeValue.length : tmpNode.childNodes.length) && domUtils.isBoundaryNode(tmpNode,'lastChild')){ - me.fireEvent('saveScene'); - me.body.innerHTML = '

    '+(browser.ie ? '' : '
    ')+'

    '; - rng.setStart(me.body.firstChild,0).setCursor(false,true); - me._selectionChange(); - return; - } - } - } - } - - //处理backspace - if (keyCode == keymap.Backspace) { - rng = me.selection.getRange(); - collapsed = rng.collapsed; - if(me.fireEvent('delkeydown',evt)){ - return; - } - var start,end; - //避免按两次删除才能生效的问题 - if(rng.collapsed && rng.inFillChar()){ - start = rng.startContainer; - - if(domUtils.isFillChar(start)){ - rng.setStartBefore(start).shrinkBoundary(true).collapse(true); - domUtils.remove(start) - }else{ - start.nodeValue = start.nodeValue.replace(new RegExp('^' + domUtils.fillChar ),''); - rng.startOffset--; - rng.collapse(true).select(true) - } - } - - //解决选中control元素不能删除的问题 - if (start = rng.getClosedNode()) { - me.fireEvent('saveScene'); - rng.setStartBefore(start); - domUtils.remove(start); - rng.setCursor(); - me.fireEvent('saveScene'); - domUtils.preventDefault(evt); - return; - } - //阻止在table上的删除 - if (!browser.ie) { - start = domUtils.findParentByTagName(rng.startContainer, 'table', true); - end = domUtils.findParentByTagName(rng.endContainer, 'table', true); - if (start && !end || !start && end || start !== end) { - evt.preventDefault(); - return; - } - } - - } - //处理tab键的逻辑 - if (keyCode == keymap.Tab) { - //不处理以下标签 - var excludeTagNameForTabKey = { - 'ol' : 1, - 'ul' : 1, - 'table':1 - }; - //处理组件里的tab按下事件 - if(me.fireEvent('tabkeydown',evt)){ - domUtils.preventDefault(evt); - return; - } - var range = me.selection.getRange(); - me.fireEvent('saveScene'); - for (var i = 0,txt = '',tabSize = me.options.tabSize|| 4,tabNode = me.options.tabNode || ' '; i < tabSize; i++) { - txt += tabNode; - } - var span = me.document.createElement('span'); - span.innerHTML = txt + domUtils.fillChar; - if (range.collapsed) { - range.insertNode(span.cloneNode(true).firstChild).setCursor(true); - } else { - var filterFn = function(node) { - return domUtils.isBlockElm(node) && !excludeTagNameForTabKey[node.tagName.toLowerCase()] - - }; - //普通的情况 - start = domUtils.findParent(range.startContainer, filterFn,true); - end = domUtils.findParent(range.endContainer, filterFn,true); - if (start && end && start === end) { - range.deleteContents(); - range.insertNode(span.cloneNode(true).firstChild).setCursor(true); - } else { - var bookmark = range.createBookmark(); - range.enlarge(true); - var bookmark2 = range.createBookmark(), - current = domUtils.getNextDomNode(bookmark2.start, false, filterFn); - while (current && !(domUtils.getPosition(current, bookmark2.end) & domUtils.POSITION_FOLLOWING)) { - current.insertBefore(span.cloneNode(true).firstChild, current.firstChild); - current = domUtils.getNextDomNode(current, false, filterFn); - } - range.moveToBookmark(bookmark2).moveToBookmark(bookmark).select(); - } - } - domUtils.preventDefault(evt) - } - //trace:1634 - //ff的del键在容器空的时候,也会删除 - if(browser.gecko && keyCode == 46){ - range = me.selection.getRange(); - if(range.collapsed){ - start = range.startContainer; - if(domUtils.isEmptyBlock(start)){ - var parent = start.parentNode; - while(domUtils.getChildCount(parent) == 1 && !domUtils.isBody(parent)){ - start = parent; - parent = parent.parentNode; - } - if(start === parent.lastChild) - evt.preventDefault(); - return; - } - } - } - }); - me.addListener('keyup', function(type, evt) { - var keyCode = evt.keyCode || evt.which, - rng,me = this; - if(keyCode == keymap.Backspace){ - if(me.fireEvent('delkeyup')){ - return; - } - rng = me.selection.getRange(); - if(rng.collapsed){ - var tmpNode, - autoClearTagName = ['h1','h2','h3','h4','h5','h6']; - if(tmpNode = domUtils.findParentByTagName(rng.startContainer,autoClearTagName,true)){ - if(domUtils.isEmptyBlock(tmpNode)){ - var pre = tmpNode.previousSibling; - if(pre && pre.nodeName != 'TABLE'){ - domUtils.remove(tmpNode); - rng.setStartAtLast(pre).setCursor(false,true); - return; - }else{ - var next = tmpNode.nextSibling; - if(next && next.nodeName != 'TABLE'){ - domUtils.remove(tmpNode); - rng.setStartAtFirst(next).setCursor(false,true); - return; - } - } - } - } - //处理当删除到body时,要重新给p标签展位 - if(domUtils.isBody(rng.startContainer)){ - var tmpNode = domUtils.createElement(me.document,'p',{ - 'innerHTML' : browser.ie ? domUtils.fillChar : '
    ' - }); - rng.insertNode(tmpNode).setStart(tmpNode,0).setCursor(false,true); - } - } - - - //chrome下如果删除了inline标签,浏览器会有记忆,在输入文字还是会套上刚才删除的标签,所以这里再选一次就不会了 - if( !collapsed && (rng.startContainer.nodeType == 3 || rng.startContainer.nodeType == 1 && domUtils.isEmptyBlock(rng.startContainer))){ - if(browser.ie){ - var span = rng.document.createElement('span'); - rng.insertNode(span).setStartBefore(span).collapse(true); - rng.select(); - domUtils.remove(span) - }else{ - rng.select() - } - - } - } - - - }) -}; - -// plugins/fiximgclick.js -///import core -///commands 修复chrome下图片不能点击的问题,出现八个角可改变大小 -///commandsName FixImgClick -///commandsTitle 修复chrome下图片不能点击的问题,出现八个角可改变大小 -//修复chrome下图片不能点击的问题,出现八个角可改变大小 - -UE.plugins['fiximgclick'] = (function () { - - var elementUpdated = false; - function Scale() { - this.editor = null; - this.resizer = null; - this.cover = null; - this.doc = document; - this.prePos = {x: 0, y: 0}; - this.startPos = {x: 0, y: 0}; - } - - (function () { - var rect = [ - //[left, top, width, height] - [0, 0, -1, -1], - [0, 0, 0, -1], - [0, 0, 1, -1], - [0, 0, -1, 0], - [0, 0, 1, 0], - [0, 0, -1, 1], - [0, 0, 0, 1], - [0, 0, 1, 1] - ]; - - Scale.prototype = { - init: function (editor) { - var me = this; - me.editor = editor; - me.startPos = this.prePos = {x: 0, y: 0}; - me.dragId = -1; - - var hands = [], - cover = me.cover = document.createElement('div'), - resizer = me.resizer = document.createElement('div'); - - cover.id = me.editor.ui.id + '_imagescale_cover'; - cover.style.cssText = 'position:absolute;display:none;z-index:' + (me.editor.options.zIndex) + ';filter:alpha(opacity=0); opacity:0;background:#CCC;'; - domUtils.on(cover, 'mousedown click', function () { - me.hide(); - }); - - for (i = 0; i < 8; i++) { - hands.push(''); - } - resizer.id = me.editor.ui.id + '_imagescale'; - resizer.className = 'edui-editor-imagescale'; - resizer.innerHTML = hands.join(''); - resizer.style.cssText += ';display:none;border:1px solid #3b77ff;z-index:' + (me.editor.options.zIndex) + ';'; - - me.editor.ui.getDom().appendChild(cover); - me.editor.ui.getDom().appendChild(resizer); - - me.initStyle(); - me.initEvents(); - }, - initStyle: function () { - utils.cssRule('imagescale', '.edui-editor-imagescale{display:none;position:absolute;border:1px solid #38B2CE;cursor:hand;-webkit-box-sizing: content-box;-moz-box-sizing: content-box;box-sizing: content-box;}' + - '.edui-editor-imagescale span{position:absolute;width:6px;height:6px;overflow:hidden;font-size:0px;display:block;background-color:#3C9DD0;}' - + '.edui-editor-imagescale .edui-editor-imagescale-hand0{cursor:nw-resize;top:0;margin-top:-4px;left:0;margin-left:-4px;}' - + '.edui-editor-imagescale .edui-editor-imagescale-hand1{cursor:n-resize;top:0;margin-top:-4px;left:50%;margin-left:-4px;}' - + '.edui-editor-imagescale .edui-editor-imagescale-hand2{cursor:ne-resize;top:0;margin-top:-4px;left:100%;margin-left:-3px;}' - + '.edui-editor-imagescale .edui-editor-imagescale-hand3{cursor:w-resize;top:50%;margin-top:-4px;left:0;margin-left:-4px;}' - + '.edui-editor-imagescale .edui-editor-imagescale-hand4{cursor:e-resize;top:50%;margin-top:-4px;left:100%;margin-left:-3px;}' - + '.edui-editor-imagescale .edui-editor-imagescale-hand5{cursor:sw-resize;top:100%;margin-top:-3px;left:0;margin-left:-4px;}' - + '.edui-editor-imagescale .edui-editor-imagescale-hand6{cursor:s-resize;top:100%;margin-top:-3px;left:50%;margin-left:-4px;}' - + '.edui-editor-imagescale .edui-editor-imagescale-hand7{cursor:se-resize;top:100%;margin-top:-3px;left:100%;margin-left:-3px;}'); - }, - initEvents: function () { - var me = this; - - me.startPos.x = me.startPos.y = 0; - me.isDraging = false; - }, - _eventHandler: function (e) { - var me = this; - switch (e.type) { - case 'mousedown': - var hand = e.target || e.srcElement, hand; - if (hand.className.indexOf('edui-editor-imagescale-hand') != -1 && me.dragId == -1) { - me.dragId = hand.className.slice(-1); - me.startPos.x = me.prePos.x = e.clientX; - me.startPos.y = me.prePos.y = e.clientY; - domUtils.on(me.doc,'mousemove', me.proxy(me._eventHandler, me)); - } - break; - case 'mousemove': - if (me.dragId != -1) { - me.updateContainerStyle(me.dragId, {x: e.clientX - me.prePos.x, y: e.clientY - me.prePos.y}); - me.prePos.x = e.clientX; - me.prePos.y = e.clientY; - elementUpdated = true; - me.updateTargetElement(); - - } - break; - case 'mouseup': - if (me.dragId != -1) { - me.updateContainerStyle(me.dragId, {x: e.clientX - me.prePos.x, y: e.clientY - me.prePos.y}); - me.updateTargetElement(); - if (me.target.parentNode) me.attachTo(me.target); - me.dragId = -1; - } - domUtils.un(me.doc,'mousemove', me.proxy(me._eventHandler, me)); - //修复只是点击挪动点,但没有改变大小,不应该触发contentchange - if(elementUpdated){ - elementUpdated = false; - me.editor.fireEvent('contentchange'); - } - - break; - default: - break; - } - }, - updateTargetElement: function () { - var me = this; - domUtils.setStyles(me.target, { - 'width': me.resizer.style.width, - 'height': me.resizer.style.height - }); - me.target.width = parseInt(me.resizer.style.width); - me.target.height = parseInt(me.resizer.style.height); - me.attachTo(me.target); - }, - updateContainerStyle: function (dir, offset) { - var me = this, - dom = me.resizer, tmp; - - if (rect[dir][0] != 0) { - tmp = parseInt(dom.style.left) + offset.x; - dom.style.left = me._validScaledProp('left', tmp) + 'px'; - } - if (rect[dir][1] != 0) { - tmp = parseInt(dom.style.top) + offset.y; - dom.style.top = me._validScaledProp('top', tmp) + 'px'; - } - if (rect[dir][2] != 0) { - tmp = dom.clientWidth + rect[dir][2] * offset.x; - dom.style.width = me._validScaledProp('width', tmp) + 'px'; - } - if (rect[dir][3] != 0) { - tmp = dom.clientHeight + rect[dir][3] * offset.y; - dom.style.height = me._validScaledProp('height', tmp) + 'px'; - } - }, - _validScaledProp: function (prop, value) { - var ele = this.resizer, - wrap = document; - - value = isNaN(value) ? 0 : value; - switch (prop) { - case 'left': - return value < 0 ? 0 : (value + ele.clientWidth) > wrap.clientWidth ? wrap.clientWidth - ele.clientWidth : value; - case 'top': - return value < 0 ? 0 : (value + ele.clientHeight) > wrap.clientHeight ? wrap.clientHeight - ele.clientHeight : value; - case 'width': - return value <= 0 ? 1 : (value + ele.offsetLeft) > wrap.clientWidth ? wrap.clientWidth - ele.offsetLeft : value; - case 'height': - return value <= 0 ? 1 : (value + ele.offsetTop) > wrap.clientHeight ? wrap.clientHeight - ele.offsetTop : value; - } - }, - hideCover: function () { - this.cover.style.display = 'none'; - }, - showCover: function () { - var me = this, - editorPos = domUtils.getXY(me.editor.ui.getDom()), - iframePos = domUtils.getXY(me.editor.iframe); - - domUtils.setStyles(me.cover, { - 'width': me.editor.iframe.offsetWidth + 'px', - 'height': me.editor.iframe.offsetHeight + 'px', - 'top': iframePos.y - editorPos.y + 'px', - 'left': iframePos.x - editorPos.x + 'px', - 'position': 'absolute', - 'display': '' - }) - }, - show: function (targetObj) { - var me = this; - me.resizer.style.display = 'block'; - if(targetObj) me.attachTo(targetObj); - - domUtils.on(this.resizer, 'mousedown', me.proxy(me._eventHandler, me)); - domUtils.on(me.doc, 'mouseup', me.proxy(me._eventHandler, me)); - - me.showCover(); - me.editor.fireEvent('afterscaleshow', me); - me.editor.fireEvent('saveScene'); - }, - hide: function () { - var me = this; - me.hideCover(); - me.resizer.style.display = 'none'; - - domUtils.un(me.resizer, 'mousedown', me.proxy(me._eventHandler, me)); - domUtils.un(me.doc, 'mouseup', me.proxy(me._eventHandler, me)); - me.editor.fireEvent('afterscalehide', me); - }, - proxy: function( fn, context ) { - return function(e) { - return fn.apply( context || this, arguments); - }; - }, - attachTo: function (targetObj) { - var me = this, - target = me.target = targetObj, - resizer = this.resizer, - imgPos = domUtils.getXY(target), - iframePos = domUtils.getXY(me.editor.iframe), - editorPos = domUtils.getXY(resizer.parentNode); - - domUtils.setStyles(resizer, { - 'width': target.width + 'px', - 'height': target.height + 'px', - 'left': iframePos.x + imgPos.x - me.editor.document.body.scrollLeft - editorPos.x - parseInt(resizer.style.borderLeftWidth) + 'px', - 'top': iframePos.y + imgPos.y - me.editor.document.body.scrollTop - editorPos.y - parseInt(resizer.style.borderTopWidth) + 'px' - }); - } - } - })(); - - return function () { - var me = this, - imageScale; - - me.setOpt('imageScaleEnabled', true); - - if ( !browser.ie && me.options.imageScaleEnabled) { - me.addListener('click', function (type, e) { - - var range = me.selection.getRange(), - img = range.getClosedNode(); - - if (img && img.tagName == 'IMG' && me.body.contentEditable!="false") { - - if (img.className.indexOf("edui-faked-music") != -1 || - img.getAttribute("anchorname") || - domUtils.hasClass(img, 'loadingclass') || - domUtils.hasClass(img, 'loaderrorclass')) { return } - - if (!imageScale) { - imageScale = new Scale(); - imageScale.init(me); - me.ui.getDom().appendChild(imageScale.resizer); - - var _keyDownHandler = function (e) { - imageScale.hide(); - if(imageScale.target) me.selection.getRange().selectNode(imageScale.target).select(); - }, _mouseDownHandler = function (e) { - var ele = e.target || e.srcElement; - if (ele && (ele.className===undefined || ele.className.indexOf('edui-editor-imagescale') == -1)) { - _keyDownHandler(e); - } - }, timer; - - me.addListener('afterscaleshow', function (e) { - me.addListener('beforekeydown', _keyDownHandler); - me.addListener('beforemousedown', _mouseDownHandler); - domUtils.on(document, 'keydown', _keyDownHandler); - domUtils.on(document,'mousedown', _mouseDownHandler); - me.selection.getNative().removeAllRanges(); - }); - me.addListener('afterscalehide', function (e) { - me.removeListener('beforekeydown', _keyDownHandler); - me.removeListener('beforemousedown', _mouseDownHandler); - domUtils.un(document, 'keydown', _keyDownHandler); - domUtils.un(document,'mousedown', _mouseDownHandler); - var target = imageScale.target; - if (target.parentNode) { - me.selection.getRange().selectNode(target).select(); - } - }); - //TODO 有iframe的情况,mousedown不能往下传。。 - domUtils.on(imageScale.resizer, 'mousedown', function (e) { - me.selection.getNative().removeAllRanges(); - var ele = e.target || e.srcElement; - if (ele && ele.className.indexOf('edui-editor-imagescale-hand') == -1) { - timer = setTimeout(function () { - imageScale.hide(); - if(imageScale.target) me.selection.getRange().selectNode(ele).select(); - }, 200); - } - }); - domUtils.on(imageScale.resizer, 'mouseup', function (e) { - var ele = e.target || e.srcElement; - if (ele && ele.className.indexOf('edui-editor-imagescale-hand') == -1) { - clearTimeout(timer); - } - }); - } - imageScale.show(img); - } else { - if (imageScale && imageScale.resizer.style.display != 'none') imageScale.hide(); - } - }); - } - - if (browser.webkit) { - me.addListener('click', function (type, e) { - if (e.target.tagName == 'IMG' && me.body.contentEditable!="false") { - var range = new dom.Range(me.document); - range.selectNode(e.target).select(); - } - }); - } - } -})(); - -// plugins/autolink.js -///import core -///commands 为非ie浏览器自动添加a标签 -///commandsName AutoLink -///commandsTitle 自动增加链接 -/** - * @description 为非ie浏览器自动添加a标签 - * @author zhanyi - */ - -UE.plugin.register('autolink',function(){ - var cont = 0; - - return !browser.ie ? { - - bindEvents:{ - 'reset' : function(){ - cont = 0; - }, - 'keydown':function(type, evt) { - var me = this; - var keyCode = evt.keyCode || evt.which; - - if (keyCode == 32 || keyCode == 13) { - - var sel = me.selection.getNative(), - range = sel.getRangeAt(0).cloneRange(), - offset, - charCode; - - var start = range.startContainer; - while (start.nodeType == 1 && range.startOffset > 0) { - start = range.startContainer.childNodes[range.startOffset - 1]; - if (!start){ - break; - } - range.setStart(start, start.nodeType == 1 ? start.childNodes.length : start.nodeValue.length); - range.collapse(true); - start = range.startContainer; - } - - do{ - if (range.startOffset == 0) { - start = range.startContainer.previousSibling; - - while (start && start.nodeType == 1) { - start = start.lastChild; - } - if (!start || domUtils.isFillChar(start)){ - break; - } - offset = start.nodeValue.length; - } else { - start = range.startContainer; - offset = range.startOffset; - } - range.setStart(start, offset - 1); - charCode = range.toString().charCodeAt(0); - } while (charCode != 160 && charCode != 32); - - if (range.toString().replace(new RegExp(domUtils.fillChar, 'g'), '').match(/(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i)) { - while(range.toString().length){ - if(/^(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i.test(range.toString())){ - break; - } - try{ - range.setStart(range.startContainer,range.startOffset+1); - }catch(e){ - //trace:2121 - var start = range.startContainer; - while(!(next = start.nextSibling)){ - if(domUtils.isBody(start)){ - return; - } - start = start.parentNode; - - } - range.setStart(next,0); - - } - - } - //range的开始边界已经在a标签里的不再处理 - if(domUtils.findParentByTagName(range.startContainer,'a',true)){ - return; - } - var a = me.document.createElement('a'),text = me.document.createTextNode(' '),href; - - me.undoManger && me.undoManger.save(); - a.appendChild(range.extractContents()); - a.href = a.innerHTML = a.innerHTML.replace(/<[^>]+>/g,''); - href = a.getAttribute("href").replace(new RegExp(domUtils.fillChar,'g'),''); - href = /^(?:https?:\/\/)/ig.test(href) ? href : "http://"+ href; - a.setAttribute('_src',utils.html(href)); - a.href = utils.html(href); - - range.insertNode(a); - a.parentNode.insertBefore(text, a.nextSibling); - range.setStart(text, 0); - range.collapse(true); - sel.removeAllRanges(); - sel.addRange(range); - me.undoManger && me.undoManger.save(); - } - } - } - } - }:{} - },function(){ - var keyCodes = { - 37:1, 38:1, 39:1, 40:1, - 13:1,32:1 - }; - function checkIsCludeLink(node){ - if(node.nodeType == 3){ - return null - } - if(node.nodeName == 'A'){ - return node; - } - var lastChild = node.lastChild; - - while(lastChild){ - if(lastChild.nodeName == 'A'){ - return lastChild; - } - if(lastChild.nodeType == 3){ - if(domUtils.isWhitespace(lastChild)){ - lastChild = lastChild.previousSibling; - continue; - } - return null - } - lastChild = lastChild.lastChild; - } - } - browser.ie && this.addListener('keyup',function(cmd,evt){ - var me = this,keyCode = evt.keyCode; - if(keyCodes[keyCode]){ - var rng = me.selection.getRange(); - var start = rng.startContainer; - - if(keyCode == 13){ - while(start && !domUtils.isBody(start) && !domUtils.isBlockElm(start)){ - start = start.parentNode; - } - if(start && !domUtils.isBody(start) && start.nodeName == 'P'){ - var pre = start.previousSibling; - if(pre && pre.nodeType == 1){ - var pre = checkIsCludeLink(pre); - if(pre && !pre.getAttribute('_href')){ - domUtils.remove(pre,true); - } - } - } - }else if(keyCode == 32 ){ - if(start.nodeType == 3 && /^\s$/.test(start.nodeValue)){ - start = start.previousSibling; - if(start && start.nodeName == 'A' && !start.getAttribute('_href')){ - domUtils.remove(start,true); - } - } - }else { - start = domUtils.findParentByTagName(start,'a',true); - if(start && !start.getAttribute('_href')){ - var bk = rng.createBookmark(); - - domUtils.remove(start,true); - rng.moveToBookmark(bk).select(true) - } - } - - } - - - }); - } -); - -// plugins/autoheight.js -///import core -///commands 当输入内容超过编辑器高度时,编辑器自动增高 -///commandsName AutoHeight,autoHeightEnabled -///commandsTitle 自动增高 -/** - * @description 自动伸展 - * @author zhanyi - */ -UE.plugins['autoheight'] = function () { - var me = this; - //提供开关,就算加载也可以关闭 - me.autoHeightEnabled = me.options.autoHeightEnabled !== false; - if (!me.autoHeightEnabled) { - return; - } - - var bakOverflow, - lastHeight = 0, - options = me.options, - currentHeight, - timer; - - function adjustHeight() { - var me = this; - clearTimeout(timer); - if(isFullscreen)return; - if (!me.queryCommandState || me.queryCommandState && me.queryCommandState('source') != 1) { - timer = setTimeout(function(){ - - var node = me.body.lastChild; - while(node && node.nodeType != 1){ - node = node.previousSibling; - } - if(node && node.nodeType == 1){ - node.style.clear = 'both'; - currentHeight = Math.max(domUtils.getXY(node).y + node.offsetHeight + 25 ,Math.max(options.minFrameHeight, options.initialFrameHeight)) ; - if (currentHeight != lastHeight) { - if (currentHeight !== parseInt(me.iframe.parentNode.style.height)) { - me.iframe.parentNode.style.height = currentHeight + 'px'; - } - me.body.style.height = currentHeight + 'px'; - lastHeight = currentHeight; - } - domUtils.removeStyle(node,'clear'); - } - - - },50) - } - } - var isFullscreen; - me.addListener('fullscreenchanged',function(cmd,f){ - isFullscreen = f - }); - me.addListener('destroy', function () { - me.removeListener('contentchange afterinserthtml keyup mouseup',adjustHeight) - }); - me.enableAutoHeight = function () { - var me = this; - if (!me.autoHeightEnabled) { - return; - } - var doc = me.document; - me.autoHeightEnabled = true; - bakOverflow = doc.body.style.overflowY; - doc.body.style.overflowY = 'hidden'; - me.addListener('contentchange afterinserthtml keyup mouseup',adjustHeight); - //ff不给事件算得不对 - - setTimeout(function () { - adjustHeight.call(me); - }, browser.gecko ? 100 : 0); - me.fireEvent('autoheightchanged', me.autoHeightEnabled); - }; - me.disableAutoHeight = function () { - - me.body.style.overflowY = bakOverflow || ''; - - me.removeListener('contentchange', adjustHeight); - me.removeListener('keyup', adjustHeight); - me.removeListener('mouseup', adjustHeight); - me.autoHeightEnabled = false; - me.fireEvent('autoheightchanged', me.autoHeightEnabled); - }; - - me.on('setHeight',function(){ - me.disableAutoHeight() - }); - me.addListener('ready', function () { - me.enableAutoHeight(); - //trace:1764 - var timer; - domUtils.on(browser.ie ? me.body : me.document, browser.webkit ? 'dragover' : 'drop', function () { - clearTimeout(timer); - timer = setTimeout(function () { - //trace:3681 - adjustHeight.call(me); - }, 100); - - }); - //修复内容过多时,回到顶部,顶部内容被工具栏遮挡问题 - var lastScrollY; - window.onscroll = function(){ - if(lastScrollY === null){ - lastScrollY = this.scrollY - }else if(this.scrollY == 0 && lastScrollY != 0){ - me.window.scrollTo(0,0); - lastScrollY = null; - } - } - }); - - -}; - - - -// plugins/autofloat.js -///import core -///commands 悬浮工具栏 -///commandsName AutoFloat,autoFloatEnabled -///commandsTitle 悬浮工具栏 -/** - * modified by chengchao01 - * 注意: 引入此功能后,在IE6下会将body的背景图片覆盖掉! - */ -UE.plugins['autofloat'] = function() { - var me = this, - lang = me.getLang(); - me.setOpt({ - topOffset:0 - }); - var optsAutoFloatEnabled = me.options.autoFloatEnabled !== false, - topOffset = me.options.topOffset; - - - //如果不固定toolbar的位置,则直接退出 - if(!optsAutoFloatEnabled){ - return; - } - var uiUtils = UE.ui.uiUtils, - LteIE6 = browser.ie && browser.version <= 6, - quirks = browser.quirks; - - function checkHasUI(){ - if(!UE.ui){ - alert(lang.autofloatMsg); - return 0; - } - return 1; - } - function fixIE6FixedPos(){ - var docStyle = document.body.style; - docStyle.backgroundImage = 'url("about:blank")'; - docStyle.backgroundAttachment = 'fixed'; - } - var bakCssText, - placeHolder = document.createElement('div'), - toolbarBox,orgTop, - getPosition, - flag =true; //ie7模式下需要偏移 - function setFloating(){ - var toobarBoxPos = domUtils.getXY(toolbarBox), - origalFloat = domUtils.getComputedStyle(toolbarBox,'position'), - origalLeft = domUtils.getComputedStyle(toolbarBox,'left'); - toolbarBox.style.width = toolbarBox.offsetWidth + 'px'; - toolbarBox.style.zIndex = me.options.zIndex * 1 + 1; - toolbarBox.parentNode.insertBefore(placeHolder, toolbarBox); - if (LteIE6 || (quirks && browser.ie)) { - if(toolbarBox.style.position != 'absolute'){ - toolbarBox.style.position = 'absolute'; - } - toolbarBox.style.top = (document.body.scrollTop||document.documentElement.scrollTop) - orgTop + topOffset + 'px'; - } else { - if (browser.ie7Compat && flag) { - flag = false; - toolbarBox.style.left = domUtils.getXY(toolbarBox).x - document.documentElement.getBoundingClientRect().left+2 + 'px'; - } - if(toolbarBox.style.position != 'fixed'){ - toolbarBox.style.position = 'fixed'; - toolbarBox.style.top = topOffset +"px"; - ((origalFloat == 'absolute' || origalFloat == 'relative') && parseFloat(origalLeft)) && (toolbarBox.style.left = toobarBoxPos.x + 'px'); - } - } - } - function unsetFloating(){ - flag = true; - if(placeHolder.parentNode){ - placeHolder.parentNode.removeChild(placeHolder); - } - - toolbarBox.style.cssText = bakCssText; - } - - function updateFloating(){ - var rect3 = getPosition(me.container); - var offset=me.options.toolbarTopOffset||0; - if (rect3.top < 0 && rect3.bottom - toolbarBox.offsetHeight > offset) { - setFloating(); - }else{ - unsetFloating(); - } - } - var defer_updateFloating = utils.defer(function(){ - updateFloating(); - },browser.ie ? 200 : 100,true); - - me.addListener('destroy',function(){ - domUtils.un(window, ['scroll','resize'], updateFloating); - me.removeListener('keydown', defer_updateFloating); - }); - - me.addListener('ready', function(){ - if(checkHasUI(me)){ - //加载了ui组件,但在new时,没有加载ui,导致编辑器实例上没有ui类,所以这里做判断 - if(!me.ui){ - return; - } - getPosition = uiUtils.getClientRect; - toolbarBox = me.ui.getDom('toolbarbox'); - orgTop = getPosition(toolbarBox).top; - bakCssText = toolbarBox.style.cssText; - placeHolder.style.height = toolbarBox.offsetHeight + 'px'; - if(LteIE6){ - fixIE6FixedPos(); - } - domUtils.on(window, ['scroll','resize'], updateFloating); - me.addListener('keydown', defer_updateFloating); - - me.addListener('beforefullscreenchange', function (t, enabled){ - if (enabled) { - unsetFloating(); - } - }); - me.addListener('fullscreenchanged', function (t, enabled){ - if (!enabled) { - updateFloating(); - } - }); - me.addListener('sourcemodechanged', function (t, enabled){ - setTimeout(function (){ - updateFloating(); - },0); - }); - me.addListener("clearDoc",function(){ - setTimeout(function(){ - updateFloating(); - },0); - - }) - } - }); -}; - - -// plugins/video.js -/** - * video插件, 为UEditor提供视频插入支持 - * @file - * @since 1.2.6.1 - */ - -UE.plugins['video'] = function (){ - var me =this; - - /** - * 创建插入视频字符窜 - * @param url 视频地址 - * @param width 视频宽度 - * @param height 视频高度 - * @param align 视频对齐 - * @param toEmbed 是否以flash代替显示 - * @param addParagraph 是否需要添加P 标签 - */ - function creatInsertStr(url,width,height,id,align,classname,type){ - - url = utils.unhtmlForUrl(url); - align = utils.unhtml(align); - classname = utils.unhtml(classname); - - width = parseInt(width, 10) || 0; - height = parseInt(height, 10) || 0; - - var str; - switch (type){ - case 'image': - str = '' - break; - case 'embed': - str = ''; - break; - case 'video': - var ext = url.substr(url.lastIndexOf('.') + 1); - if(ext == 'ogv') ext = 'ogg'; - str = '' + - ''; - break; - } - return str; - } - - function switchImgAndVideo(root,img2video){ - utils.each(root.getNodesByTagName(img2video ? 'img' : 'embed video'),function(node){ - var className = node.getAttr('class'); - if(className && className.indexOf('edui-faked-video') != -1){ - var html = creatInsertStr( img2video ? node.getAttr('_url') : node.getAttr('src'),node.getAttr('width'),node.getAttr('height'),null,node.getStyle('float') || '',className,img2video ? 'embed':'image'); - node.parentNode.replaceChild(UE.uNode.createElement(html),node); - } - if(className && className.indexOf('edui-upload-video') != -1){ - var html = creatInsertStr( img2video ? node.getAttr('_url') : node.getAttr('src'),node.getAttr('width'),node.getAttr('height'),null,node.getStyle('float') || '',className,img2video ? 'video':'image'); - node.parentNode.replaceChild(UE.uNode.createElement(html),node); - } - }) - } - - me.addOutputRule(function(root){ - switchImgAndVideo(root,true) - }); - me.addInputRule(function(root){ - switchImgAndVideo(root) - }); - - /** - * 插入视频 - * @command insertvideo - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { Object } videoAttr 键值对对象, 描述一个视频的所有属性 - * @example - * ```javascript - * - * var videoAttr = { - * //视频地址 - * url: 'http://www.youku.com/xxx', - * //视频宽高值, 单位px - * width: 200, - * height: 100 - * }; - * - * //editor 是编辑器实例 - * //向编辑器插入单个视频 - * editor.execCommand( 'insertvideo', videoAttr ); - * ``` - */ - - /** - * 插入视频 - * @command insertvideo - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { Array } videoArr 需要插入的视频的数组, 其中的每一个元素都是一个键值对对象, 描述了一个视频的所有属性 - * @example - * ```javascript - * - * var videoAttr1 = { - * //视频地址 - * url: 'http://www.youku.com/xxx', - * //视频宽高值, 单位px - * width: 200, - * height: 100 - * }, - * videoAttr2 = { - * //视频地址 - * url: 'http://www.youku.com/xxx', - * //视频宽高值, 单位px - * width: 200, - * height: 100 - * } - * - * //editor 是编辑器实例 - * //该方法将会向编辑器内插入两个视频 - * editor.execCommand( 'insertvideo', [ videoAttr1, videoAttr2 ] ); - * ``` - */ - - /** - * 查询当前光标所在处是否是一个视频 - * @command insertvideo - * @method queryCommandState - * @param { String } cmd 需要查询的命令字符串 - * @return { int } 如果当前光标所在处的元素是一个视频对象, 则返回1,否则返回0 - * @example - * ```javascript - * - * //editor 是编辑器实例 - * editor.queryCommandState( 'insertvideo' ); - * ``` - */ - me.commands["insertvideo"] = { - execCommand: function (cmd, videoObjs, type){ - videoObjs = utils.isArray(videoObjs)?videoObjs:[videoObjs]; - var html = [],id = 'tmpVedio', cl; - for(var i=0,vi,len = videoObjs.length;i 0) { - return 0; - } - for (var i in dtd.$isNotEmpty) if (dtd.$isNotEmpty.hasOwnProperty(i)) { - if (node.getElementsByTagName(i).length) { - return 0; - } - } - return 1; - }; - UETable.getWidth = function (cell) { - if (!cell)return 0; - return parseInt(domUtils.getComputedStyle(cell, "width"), 10); - }; - - /** - * 获取单元格或者单元格组的“对齐”状态。 如果当前的检测对象是一个单元格组, 只有在满足所有单元格的 水平和竖直 对齐属性都相同的 - * 条件时才会返回其状态值,否则将返回null; 如果当前只检测了一个单元格, 则直接返回当前单元格的对齐状态; - * @param table cell or table cells , 支持单个单元格dom对象 或者 单元格dom对象数组 - * @return { align: 'left' || 'right' || 'center', valign: 'top' || 'middle' || 'bottom' } 或者 null - */ - UETable.getTableCellAlignState = function ( cells ) { - - !utils.isArray( cells ) && ( cells = [cells] ); - - var result = {}, - status = ['align', 'valign'], - tempStatus = null, - isSame = true;//状态是否相同 - - utils.each( cells, function( cellNode ){ - - utils.each( status, function( currentState ){ - - tempStatus = cellNode.getAttribute( currentState ); - - if( !result[ currentState ] && tempStatus ) { - result[ currentState ] = tempStatus; - } else if( !result[ currentState ] || ( tempStatus !== result[ currentState ] ) ) { - isSame = false; - return false; - } - - } ); - - return isSame; - - }); - - return isSame ? result : null; - - }; - - /** - * 根据当前选区获取相关的table信息 - * @return {Object} - */ - UETable.getTableItemsByRange = function (editor) { - var start = editor.selection.getStart(); - - //ff下会选中bookmark - if( start && start.id && start.id.indexOf('_baidu_bookmark_start_') === 0 && start.nextSibling) { - start = start.nextSibling; - } - - //在table或者td边缘有可能存在选中tr的情况 - var cell = start && domUtils.findParentByTagName(start, ["td", "th"], true), - tr = cell && cell.parentNode, - caption = start && domUtils.findParentByTagName(start, 'caption', true), - table = caption ? caption.parentNode : tr && tr.parentNode.parentNode; - - return { - cell:cell, - tr:tr, - table:table, - caption:caption - } - }; - UETable.getUETableBySelected = function (editor) { - var table = UETable.getTableItemsByRange(editor).table; - if (table && table.ueTable && table.ueTable.selectedTds.length) { - return table.ueTable; - } - return null; - }; - - UETable.getDefaultValue = function (editor, table) { - var borderMap = { - thin:'0px', - medium:'1px', - thick:'2px' - }, - tableBorder, tdPadding, tdBorder, tmpValue; - if (!table) { - table = editor.document.createElement('table'); - table.insertRow(0).insertCell(0).innerHTML = 'xxx'; - editor.body.appendChild(table); - var td = table.getElementsByTagName('td')[0]; - tmpValue = domUtils.getComputedStyle(table, 'border-left-width'); - tableBorder = parseInt(borderMap[tmpValue] || tmpValue, 10); - tmpValue = domUtils.getComputedStyle(td, 'padding-left'); - tdPadding = parseInt(borderMap[tmpValue] || tmpValue, 10); - tmpValue = domUtils.getComputedStyle(td, 'border-left-width'); - tdBorder = parseInt(borderMap[tmpValue] || tmpValue, 10); - domUtils.remove(table); - return { - tableBorder:tableBorder, - tdPadding:tdPadding, - tdBorder:tdBorder - }; - } else { - td = table.getElementsByTagName('td')[0]; - tmpValue = domUtils.getComputedStyle(table, 'border-left-width'); - tableBorder = parseInt(borderMap[tmpValue] || tmpValue, 10); - tmpValue = domUtils.getComputedStyle(td, 'padding-left'); - tdPadding = parseInt(borderMap[tmpValue] || tmpValue, 10); - tmpValue = domUtils.getComputedStyle(td, 'border-left-width'); - tdBorder = parseInt(borderMap[tmpValue] || tmpValue, 10); - return { - tableBorder:tableBorder, - tdPadding:tdPadding, - tdBorder:tdBorder - }; - } - }; - /** - * 根据当前点击的td或者table获取索引对象 - * @param tdOrTable - */ - UETable.getUETable = function (tdOrTable) { - var tag = tdOrTable.tagName.toLowerCase(); - tdOrTable = (tag == "td" || tag == "th" || tag == 'caption') ? domUtils.findParentByTagName(tdOrTable, "table", true) : tdOrTable; - if (!tdOrTable.ueTable) { - tdOrTable.ueTable = new UETable(tdOrTable); - } - return tdOrTable.ueTable; - }; - - UETable.cloneCell = function(cell,ignoreMerge,keepPro){ - if (!cell || utils.isString(cell)) { - return this.table.ownerDocument.createElement(cell || 'td'); - } - var flag = domUtils.hasClass(cell, "selectTdClass"); - flag && domUtils.removeClasses(cell, "selectTdClass"); - var tmpCell = cell.cloneNode(true); - if (ignoreMerge) { - tmpCell.rowSpan = tmpCell.colSpan = 1; - } - //去掉宽高 - !keepPro && domUtils.removeAttributes(tmpCell,'width height'); - !keepPro && domUtils.removeAttributes(tmpCell,'style'); - - tmpCell.style.borderLeftStyle = ""; - tmpCell.style.borderTopStyle = ""; - tmpCell.style.borderLeftColor = cell.style.borderRightColor; - tmpCell.style.borderLeftWidth = cell.style.borderRightWidth; - tmpCell.style.borderTopColor = cell.style.borderBottomColor; - tmpCell.style.borderTopWidth = cell.style.borderBottomWidth; - flag && domUtils.addClass(cell, "selectTdClass"); - return tmpCell; - } - - UETable.prototype = { - getMaxRows:function () { - var rows = this.table.rows, maxLen = 1; - for (var i = 0, row; row = rows[i]; i++) { - var currentMax = 1; - for (var j = 0, cj; cj = row.cells[j++];) { - currentMax = Math.max(cj.rowSpan || 1, currentMax); - } - maxLen = Math.max(currentMax + i, maxLen); - } - return maxLen; - }, - /** - * 获取当前表格的最大列数 - */ - getMaxCols:function () { - var rows = this.table.rows, maxLen = 0, cellRows = {}; - for (var i = 0, row; row = rows[i]; i++) { - var cellsNum = 0; - for (var j = 0, cj; cj = row.cells[j++];) { - cellsNum += (cj.colSpan || 1); - if (cj.rowSpan && cj.rowSpan > 1) { - for (var k = 1; k < cj.rowSpan; k++) { - if (!cellRows['row_' + (i + k)]) { - cellRows['row_' + (i + k)] = (cj.colSpan || 1); - } else { - cellRows['row_' + (i + k)]++ - } - } - - } - } - cellsNum += cellRows['row_' + i] || 0; - maxLen = Math.max(cellsNum, maxLen); - } - return maxLen; - }, - getCellColIndex:function (cell) { - - }, - /** - * 获取当前cell旁边的单元格, - * @param cell - * @param right - */ - getHSideCell:function (cell, right) { - try { - var cellInfo = this.getCellInfo(cell), - previewRowIndex, previewColIndex; - var len = this.selectedTds.length, - range = this.cellsRange; - //首行或者首列没有前置单元格 - if ((!right && (!len ? !cellInfo.colIndex : !range.beginColIndex)) || (right && (!len ? (cellInfo.colIndex == (this.colsNum - 1)) : (range.endColIndex == this.colsNum - 1)))) return null; - - previewRowIndex = !len ? cellInfo.rowIndex : range.beginRowIndex; - previewColIndex = !right ? ( !len ? (cellInfo.colIndex < 1 ? 0 : (cellInfo.colIndex - 1)) : range.beginColIndex - 1) - : ( !len ? cellInfo.colIndex + 1 : range.endColIndex + 1); - return this.getCell(this.indexTable[previewRowIndex][previewColIndex].rowIndex, this.indexTable[previewRowIndex][previewColIndex].cellIndex); - } catch (e) { - showError(e); - } - }, - getTabNextCell:function (cell, preRowIndex) { - var cellInfo = this.getCellInfo(cell), - rowIndex = preRowIndex || cellInfo.rowIndex, - colIndex = cellInfo.colIndex + 1 + (cellInfo.colSpan - 1), - nextCell; - try { - nextCell = this.getCell(this.indexTable[rowIndex][colIndex].rowIndex, this.indexTable[rowIndex][colIndex].cellIndex); - } catch (e) { - try { - rowIndex = rowIndex * 1 + 1; - colIndex = 0; - nextCell = this.getCell(this.indexTable[rowIndex][colIndex].rowIndex, this.indexTable[rowIndex][colIndex].cellIndex); - } catch (e) { - } - } - return nextCell; - - }, - /** - * 获取视觉上的后置单元格 - * @param cell - * @param bottom - */ - getVSideCell:function (cell, bottom, ignoreRange) { - try { - var cellInfo = this.getCellInfo(cell), - nextRowIndex, nextColIndex; - var len = this.selectedTds.length && !ignoreRange, - range = this.cellsRange; - //末行或者末列没有后置单元格 - if ((!bottom && (cellInfo.rowIndex == 0)) || (bottom && (!len ? (cellInfo.rowIndex + cellInfo.rowSpan > this.rowsNum - 1) : (range.endRowIndex == this.rowsNum - 1)))) return null; - - nextRowIndex = !bottom ? ( !len ? cellInfo.rowIndex - 1 : range.beginRowIndex - 1) - : ( !len ? (cellInfo.rowIndex + cellInfo.rowSpan) : range.endRowIndex + 1); - nextColIndex = !len ? cellInfo.colIndex : range.beginColIndex; - return this.getCell(this.indexTable[nextRowIndex][nextColIndex].rowIndex, this.indexTable[nextRowIndex][nextColIndex].cellIndex); - } catch (e) { - showError(e); - } - }, - /** - * 获取相同结束位置的单元格,xOrY指代了是获取x轴相同还是y轴相同 - */ - getSameEndPosCells:function (cell, xOrY) { - try { - var flag = (xOrY.toLowerCase() === "x"), - end = domUtils.getXY(cell)[flag ? 'x' : 'y'] + cell["offset" + (flag ? 'Width' : 'Height')], - rows = this.table.rows, - cells = null, returns = []; - for (var i = 0; i < this.rowsNum; i++) { - cells = rows[i].cells; - for (var j = 0, tmpCell; tmpCell = cells[j++];) { - var tmpEnd = domUtils.getXY(tmpCell)[flag ? 'x' : 'y'] + tmpCell["offset" + (flag ? 'Width' : 'Height')]; - //对应行的td已经被上面行rowSpan了 - if (tmpEnd > end && flag) break; - if (cell == tmpCell || end == tmpEnd) { - //只获取单一的单元格 - //todo 仅获取单一单元格在特定情况下会造成returns为空,从而影响后续的拖拽实现,修正这个。需考虑性能 - if (tmpCell[flag ? "colSpan" : "rowSpan"] == 1) { - returns.push(tmpCell); - } - if (flag) break; - } - } - } - return returns; - } catch (e) { - showError(e); - } - }, - setCellContent:function (cell, content) { - cell.innerHTML = content || (browser.ie ? domUtils.fillChar : "
    "); - }, - cloneCell:UETable.cloneCell, - /** - * 获取跟当前单元格的右边竖线为左边的所有未合并单元格 - */ - getSameStartPosXCells:function (cell) { - try { - var start = domUtils.getXY(cell).x + cell.offsetWidth, - rows = this.table.rows, cells , returns = []; - for (var i = 0; i < this.rowsNum; i++) { - cells = rows[i].cells; - for (var j = 0, tmpCell; tmpCell = cells[j++];) { - var tmpStart = domUtils.getXY(tmpCell).x; - if (tmpStart > start) break; - if (tmpStart == start && tmpCell.colSpan == 1) { - returns.push(tmpCell); - break; - } - } - } - return returns; - } catch (e) { - showError(e); - } - }, - /** - * 更新table对应的索引表 - */ - update:function (table) { - this.table = table || this.table; - this.selectedTds = []; - this.cellsRange = {}; - this.indexTable = []; - var rows = this.table.rows, - rowsNum = this.getMaxRows(), - dNum = rowsNum - rows.length, - colsNum = this.getMaxCols(); - while (dNum--) { - this.table.insertRow(rows.length); - } - this.rowsNum = rowsNum; - this.colsNum = colsNum; - for (var i = 0, len = rows.length; i < len; i++) { - this.indexTable[i] = new Array(colsNum); - } - //填充索引表 - for (var rowIndex = 0, row; row = rows[rowIndex]; rowIndex++) { - for (var cellIndex = 0, cell, cells = row.cells; cell = cells[cellIndex]; cellIndex++) { - //修正整行被rowSpan时导致的行数计算错误 - if (cell.rowSpan > rowsNum) { - cell.rowSpan = rowsNum; - } - var colIndex = cellIndex, - rowSpan = cell.rowSpan || 1, - colSpan = cell.colSpan || 1; - //当已经被上一行rowSpan或者被前一列colSpan了,则跳到下一个单元格进行 - while (this.indexTable[rowIndex][colIndex]) colIndex++; - for (var j = 0; j < rowSpan; j++) { - for (var k = 0; k < colSpan; k++) { - this.indexTable[rowIndex + j][colIndex + k] = { - rowIndex:rowIndex, - cellIndex:cellIndex, - colIndex:colIndex, - rowSpan:rowSpan, - colSpan:colSpan - } - } - } - } - } - //修复残缺td - for (j = 0; j < rowsNum; j++) { - for (k = 0; k < colsNum; k++) { - if (this.indexTable[j][k] === undefined) { - row = rows[j]; - cell = row.cells[row.cells.length - 1]; - cell = cell ? cell.cloneNode(true) : this.table.ownerDocument.createElement("td"); - this.setCellContent(cell); - if (cell.colSpan !== 1)cell.colSpan = 1; - if (cell.rowSpan !== 1)cell.rowSpan = 1; - row.appendChild(cell); - this.indexTable[j][k] = { - rowIndex:j, - cellIndex:cell.cellIndex, - colIndex:k, - rowSpan:1, - colSpan:1 - } - } - } - } - //当框选后删除行或者列后撤销,需要重建选区。 - var tds = domUtils.getElementsByTagName(this.table, "td"), - selectTds = []; - utils.each(tds, function (td) { - if (domUtils.hasClass(td, "selectTdClass")) { - selectTds.push(td); - } - }); - if (selectTds.length) { - var start = selectTds[0], - end = selectTds[selectTds.length - 1], - startInfo = this.getCellInfo(start), - endInfo = this.getCellInfo(end); - this.selectedTds = selectTds; - this.cellsRange = { - beginRowIndex:startInfo.rowIndex, - beginColIndex:startInfo.colIndex, - endRowIndex:endInfo.rowIndex + endInfo.rowSpan - 1, - endColIndex:endInfo.colIndex + endInfo.colSpan - 1 - }; - } - //给第一行设置firstRow的样式名称,在排序图标的样式上使用到 - if(!domUtils.hasClass(this.table.rows[0], "firstRow")) { - domUtils.addClass(this.table.rows[0], "firstRow"); - for(var i = 1; i< this.table.rows.length; i++) { - domUtils.removeClasses(this.table.rows[i], "firstRow"); - } - } - }, - /** - * 获取单元格的索引信息 - */ - getCellInfo:function (cell) { - if (!cell) return; - var cellIndex = cell.cellIndex, - rowIndex = cell.parentNode.rowIndex, - rowInfo = this.indexTable[rowIndex], - numCols = this.colsNum; - for (var colIndex = cellIndex; colIndex < numCols; colIndex++) { - var cellInfo = rowInfo[colIndex]; - if (cellInfo.rowIndex === rowIndex && cellInfo.cellIndex === cellIndex) { - return cellInfo; - } - } - }, - /** - * 根据行列号获取单元格 - */ - getCell:function (rowIndex, cellIndex) { - return rowIndex < this.rowsNum && this.table.rows[rowIndex].cells[cellIndex] || null; - }, - /** - * 删除单元格 - */ - deleteCell:function (cell, rowIndex) { - rowIndex = typeof rowIndex == 'number' ? rowIndex : cell.parentNode.rowIndex; - var row = this.table.rows[rowIndex]; - row.deleteCell(cell.cellIndex); - }, - /** - * 根据始末两个单元格获取被框选的所有单元格范围 - */ - getCellsRange:function (cellA, cellB) { - function checkRange(beginRowIndex, beginColIndex, endRowIndex, endColIndex) { - var tmpBeginRowIndex = beginRowIndex, - tmpBeginColIndex = beginColIndex, - tmpEndRowIndex = endRowIndex, - tmpEndColIndex = endColIndex, - cellInfo, colIndex, rowIndex; - // 通过indexTable检查是否存在超出TableRange上边界的情况 - if (beginRowIndex > 0) { - for (colIndex = beginColIndex; colIndex < endColIndex; colIndex++) { - cellInfo = me.indexTable[beginRowIndex][colIndex]; - rowIndex = cellInfo.rowIndex; - if (rowIndex < beginRowIndex) { - tmpBeginRowIndex = Math.min(rowIndex, tmpBeginRowIndex); - } - } - } - // 通过indexTable检查是否存在超出TableRange右边界的情况 - if (endColIndex < me.colsNum) { - for (rowIndex = beginRowIndex; rowIndex < endRowIndex; rowIndex++) { - cellInfo = me.indexTable[rowIndex][endColIndex]; - colIndex = cellInfo.colIndex + cellInfo.colSpan - 1; - if (colIndex > endColIndex) { - tmpEndColIndex = Math.max(colIndex, tmpEndColIndex); - } - } - } - // 检查是否有超出TableRange下边界的情况 - if (endRowIndex < me.rowsNum) { - for (colIndex = beginColIndex; colIndex < endColIndex; colIndex++) { - cellInfo = me.indexTable[endRowIndex][colIndex]; - rowIndex = cellInfo.rowIndex + cellInfo.rowSpan - 1; - if (rowIndex > endRowIndex) { - tmpEndRowIndex = Math.max(rowIndex, tmpEndRowIndex); - } - } - } - // 检查是否有超出TableRange左边界的情况 - if (beginColIndex > 0) { - for (rowIndex = beginRowIndex; rowIndex < endRowIndex; rowIndex++) { - cellInfo = me.indexTable[rowIndex][beginColIndex]; - colIndex = cellInfo.colIndex; - if (colIndex < beginColIndex) { - tmpBeginColIndex = Math.min(cellInfo.colIndex, tmpBeginColIndex); - } - } - } - //递归调用直至所有完成所有框选单元格的扩展 - if (tmpBeginRowIndex != beginRowIndex || tmpBeginColIndex != beginColIndex || tmpEndRowIndex != endRowIndex || tmpEndColIndex != endColIndex) { - return checkRange(tmpBeginRowIndex, tmpBeginColIndex, tmpEndRowIndex, tmpEndColIndex); - } else { - // 不需要扩展TableRange的情况 - return { - beginRowIndex:beginRowIndex, - beginColIndex:beginColIndex, - endRowIndex:endRowIndex, - endColIndex:endColIndex - }; - } - } - - try { - var me = this, - cellAInfo = me.getCellInfo(cellA); - if (cellA === cellB) { - return { - beginRowIndex:cellAInfo.rowIndex, - beginColIndex:cellAInfo.colIndex, - endRowIndex:cellAInfo.rowIndex + cellAInfo.rowSpan - 1, - endColIndex:cellAInfo.colIndex + cellAInfo.colSpan - 1 - }; - } - var cellBInfo = me.getCellInfo(cellB); - // 计算TableRange的四个边 - var beginRowIndex = Math.min(cellAInfo.rowIndex, cellBInfo.rowIndex), - beginColIndex = Math.min(cellAInfo.colIndex, cellBInfo.colIndex), - endRowIndex = Math.max(cellAInfo.rowIndex + cellAInfo.rowSpan - 1, cellBInfo.rowIndex + cellBInfo.rowSpan - 1), - endColIndex = Math.max(cellAInfo.colIndex + cellAInfo.colSpan - 1, cellBInfo.colIndex + cellBInfo.colSpan - 1); - - return checkRange(beginRowIndex, beginColIndex, endRowIndex, endColIndex); - } catch (e) { - //throw e; - } - }, - /** - * 依据cellsRange获取对应的单元格集合 - */ - getCells:function (range) { - //每次获取cells之前必须先清除上次的选择,否则会对后续获取操作造成影响 - this.clearSelected(); - var beginRowIndex = range.beginRowIndex, - beginColIndex = range.beginColIndex, - endRowIndex = range.endRowIndex, - endColIndex = range.endColIndex, - cellInfo, rowIndex, colIndex, tdHash = {}, returnTds = []; - for (var i = beginRowIndex; i <= endRowIndex; i++) { - for (var j = beginColIndex; j <= endColIndex; j++) { - cellInfo = this.indexTable[i][j]; - rowIndex = cellInfo.rowIndex; - colIndex = cellInfo.colIndex; - // 如果Cells里已经包含了此Cell则跳过 - var key = rowIndex + '|' + colIndex; - if (tdHash[key]) continue; - tdHash[key] = 1; - if (rowIndex < i || colIndex < j || rowIndex + cellInfo.rowSpan - 1 > endRowIndex || colIndex + cellInfo.colSpan - 1 > endColIndex) { - return null; - } - returnTds.push(this.getCell(rowIndex, cellInfo.cellIndex)); - } - } - return returnTds; - }, - /** - * 清理已经选中的单元格 - */ - clearSelected:function () { - UETable.removeSelectedClass(this.selectedTds); - this.selectedTds = []; - this.cellsRange = {}; - }, - /** - * 根据range设置已经选中的单元格 - */ - setSelected:function (range) { - var cells = this.getCells(range); - UETable.addSelectedClass(cells); - this.selectedTds = cells; - this.cellsRange = range; - }, - isFullRow:function () { - var range = this.cellsRange; - return (range.endColIndex - range.beginColIndex + 1) == this.colsNum; - }, - isFullCol:function () { - var range = this.cellsRange, - table = this.table, - ths = table.getElementsByTagName("th"), - rows = range.endRowIndex - range.beginRowIndex + 1; - return !ths.length ? rows == this.rowsNum : rows == this.rowsNum || (rows == this.rowsNum - 1); - - }, - /** - * 获取视觉上的前置单元格,默认是左边,top传入时 - * @param cell - * @param top - */ - getNextCell:function (cell, bottom, ignoreRange) { - try { - var cellInfo = this.getCellInfo(cell), - nextRowIndex, nextColIndex; - var len = this.selectedTds.length && !ignoreRange, - range = this.cellsRange; - //末行或者末列没有后置单元格 - if ((!bottom && (cellInfo.rowIndex == 0)) || (bottom && (!len ? (cellInfo.rowIndex + cellInfo.rowSpan > this.rowsNum - 1) : (range.endRowIndex == this.rowsNum - 1)))) return null; - - nextRowIndex = !bottom ? ( !len ? cellInfo.rowIndex - 1 : range.beginRowIndex - 1) - : ( !len ? (cellInfo.rowIndex + cellInfo.rowSpan) : range.endRowIndex + 1); - nextColIndex = !len ? cellInfo.colIndex : range.beginColIndex; - return this.getCell(this.indexTable[nextRowIndex][nextColIndex].rowIndex, this.indexTable[nextRowIndex][nextColIndex].cellIndex); - } catch (e) { - showError(e); - } - }, - getPreviewCell:function (cell, top) { - try { - var cellInfo = this.getCellInfo(cell), - previewRowIndex, previewColIndex; - var len = this.selectedTds.length, - range = this.cellsRange; - //首行或者首列没有前置单元格 - if ((!top && (!len ? !cellInfo.colIndex : !range.beginColIndex)) || (top && (!len ? (cellInfo.rowIndex > (this.colsNum - 1)) : (range.endColIndex == this.colsNum - 1)))) return null; - - previewRowIndex = !top ? ( !len ? cellInfo.rowIndex : range.beginRowIndex ) - : ( !len ? (cellInfo.rowIndex < 1 ? 0 : (cellInfo.rowIndex - 1)) : range.beginRowIndex); - previewColIndex = !top ? ( !len ? (cellInfo.colIndex < 1 ? 0 : (cellInfo.colIndex - 1)) : range.beginColIndex - 1) - : ( !len ? cellInfo.colIndex : range.endColIndex + 1); - return this.getCell(this.indexTable[previewRowIndex][previewColIndex].rowIndex, this.indexTable[previewRowIndex][previewColIndex].cellIndex); - } catch (e) { - showError(e); - } - }, - /** - * 移动单元格中的内容 - */ - moveContent:function (cellTo, cellFrom) { - if (UETable.isEmptyBlock(cellFrom)) return; - if (UETable.isEmptyBlock(cellTo)) { - cellTo.innerHTML = cellFrom.innerHTML; - return; - } - var child = cellTo.lastChild; - if (child.nodeType == 3 || !dtd.$block[child.tagName]) { - cellTo.appendChild(cellTo.ownerDocument.createElement('br')) - } - while (child = cellFrom.firstChild) { - cellTo.appendChild(child); - } - }, - /** - * 向右合并单元格 - */ - mergeRight:function (cell) { - var cellInfo = this.getCellInfo(cell), - rightColIndex = cellInfo.colIndex + cellInfo.colSpan, - rightCellInfo = this.indexTable[cellInfo.rowIndex][rightColIndex], - rightCell = this.getCell(rightCellInfo.rowIndex, rightCellInfo.cellIndex); - //合并 - cell.colSpan = cellInfo.colSpan + rightCellInfo.colSpan; - //被合并的单元格不应存在宽度属性 - cell.removeAttribute("width"); - //移动内容 - this.moveContent(cell, rightCell); - //删掉被合并的Cell - this.deleteCell(rightCell, rightCellInfo.rowIndex); - this.update(); - }, - /** - * 向下合并单元格 - */ - mergeDown:function (cell) { - var cellInfo = this.getCellInfo(cell), - downRowIndex = cellInfo.rowIndex + cellInfo.rowSpan, - downCellInfo = this.indexTable[downRowIndex][cellInfo.colIndex], - downCell = this.getCell(downCellInfo.rowIndex, downCellInfo.cellIndex); - cell.rowSpan = cellInfo.rowSpan + downCellInfo.rowSpan; - cell.removeAttribute("height"); - this.moveContent(cell, downCell); - this.deleteCell(downCell, downCellInfo.rowIndex); - this.update(); - }, - /** - * 合并整个range中的内容 - */ - mergeRange:function () { - //由于合并操作可以在任意时刻进行,所以无法通过鼠标位置等信息实时生成range,只能通过缓存实例中的cellsRange对象来访问 - var range = this.cellsRange, - leftTopCell = this.getCell(range.beginRowIndex, this.indexTable[range.beginRowIndex][range.beginColIndex].cellIndex); - - if (leftTopCell.tagName == "TH" && range.endRowIndex !== range.beginRowIndex) { - var index = this.indexTable, - info = this.getCellInfo(leftTopCell); - leftTopCell = this.getCell(1, index[1][info.colIndex].cellIndex); - range = this.getCellsRange(leftTopCell, this.getCell(index[this.rowsNum - 1][info.colIndex].rowIndex, index[this.rowsNum - 1][info.colIndex].cellIndex)); - } - - // 删除剩余的Cells - var cells = this.getCells(range); - for(var i= 0,ci;ci=cells[i++];){ - if (ci !== leftTopCell) { - this.moveContent(leftTopCell, ci); - this.deleteCell(ci); - } - } - // 修改左上角Cell的rowSpan和colSpan,并调整宽度属性设置 - leftTopCell.rowSpan = range.endRowIndex - range.beginRowIndex + 1; - leftTopCell.rowSpan > 1 && leftTopCell.removeAttribute("height"); - leftTopCell.colSpan = range.endColIndex - range.beginColIndex + 1; - leftTopCell.colSpan > 1 && leftTopCell.removeAttribute("width"); - if (leftTopCell.rowSpan == this.rowsNum && leftTopCell.colSpan != 1) { - leftTopCell.colSpan = 1; - } - - if (leftTopCell.colSpan == this.colsNum && leftTopCell.rowSpan != 1) { - var rowIndex = leftTopCell.parentNode.rowIndex; - //解决IE下的表格操作问题 - if( this.table.deleteRow ) { - for (var i = rowIndex+ 1, curIndex=rowIndex+ 1, len=leftTopCell.rowSpan; i < len; i++) { - this.table.deleteRow(curIndex); - } - } else { - for (var i = 0, len=leftTopCell.rowSpan - 1; i < len; i++) { - var row = this.table.rows[rowIndex + 1]; - row.parentNode.removeChild(row); - } - } - leftTopCell.rowSpan = 1; - } - this.update(); - }, - /** - * 插入一行单元格 - */ - insertRow:function (rowIndex, sourceCell) { - var numCols = this.colsNum, - table = this.table, - row = table.insertRow(rowIndex), cell, - isInsertTitle = typeof sourceCell == 'string' && sourceCell.toUpperCase() == 'TH'; - - function replaceTdToTh(colIndex, cell, tableRow) { - if (colIndex == 0) { - var tr = tableRow.nextSibling || tableRow.previousSibling, - th = tr.cells[colIndex]; - if (th.tagName == 'TH') { - th = cell.ownerDocument.createElement("th"); - th.appendChild(cell.firstChild); - tableRow.insertBefore(th, cell); - domUtils.remove(cell) - } - }else{ - if (cell.tagName == 'TH') { - var td = cell.ownerDocument.createElement("td"); - td.appendChild(cell.firstChild); - tableRow.insertBefore(td, cell); - domUtils.remove(cell) - } - } - } - - //首行直接插入,无需考虑部分单元格被rowspan的情况 - if (rowIndex == 0 || rowIndex == this.rowsNum) { - for (var colIndex = 0; colIndex < numCols; colIndex++) { - cell = this.cloneCell(sourceCell, true); - this.setCellContent(cell); - cell.getAttribute('vAlign') && cell.setAttribute('vAlign', cell.getAttribute('vAlign')); - row.appendChild(cell); - if(!isInsertTitle) replaceTdToTh(colIndex, cell, row); - } - } else { - var infoRow = this.indexTable[rowIndex], - cellIndex = 0; - for (colIndex = 0; colIndex < numCols; colIndex++) { - var cellInfo = infoRow[colIndex]; - //如果存在某个单元格的rowspan穿过待插入行的位置,则修改该单元格的rowspan即可,无需插入单元格 - if (cellInfo.rowIndex < rowIndex) { - cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex); - cell.rowSpan = cellInfo.rowSpan + 1; - } else { - cell = this.cloneCell(sourceCell, true); - this.setCellContent(cell); - row.appendChild(cell); - } - if(!isInsertTitle) replaceTdToTh(colIndex, cell, row); - } - } - //框选时插入不触发contentchange,需要手动更新索引。 - this.update(); - return row; - }, - /** - * 删除一行单元格 - * @param rowIndex - */ - deleteRow:function (rowIndex) { - var row = this.table.rows[rowIndex], - infoRow = this.indexTable[rowIndex], - colsNum = this.colsNum, - count = 0; //处理计数 - for (var colIndex = 0; colIndex < colsNum;) { - var cellInfo = infoRow[colIndex], - cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex); - if (cell.rowSpan > 1) { - if (cellInfo.rowIndex == rowIndex) { - var clone = cell.cloneNode(true); - clone.rowSpan = cell.rowSpan - 1; - clone.innerHTML = ""; - cell.rowSpan = 1; - var nextRowIndex = rowIndex + 1, - nextRow = this.table.rows[nextRowIndex], - insertCellIndex, - preMerged = this.getPreviewMergedCellsNum(nextRowIndex, colIndex) - count; - if (preMerged < colIndex) { - insertCellIndex = colIndex - preMerged - 1; - //nextRow.insertCell(insertCellIndex); - domUtils.insertAfter(nextRow.cells[insertCellIndex], clone); - } else { - if (nextRow.cells.length) nextRow.insertBefore(clone, nextRow.cells[0]) - } - count += 1; - //cell.parentNode.removeChild(cell); - } - } - colIndex += cell.colSpan || 1; - } - var deleteTds = [], cacheMap = {}; - for (colIndex = 0; colIndex < colsNum; colIndex++) { - var tmpRowIndex = infoRow[colIndex].rowIndex, - tmpCellIndex = infoRow[colIndex].cellIndex, - key = tmpRowIndex + "_" + tmpCellIndex; - if (cacheMap[key])continue; - cacheMap[key] = 1; - cell = this.getCell(tmpRowIndex, tmpCellIndex); - deleteTds.push(cell); - } - var mergeTds = []; - utils.each(deleteTds, function (td) { - if (td.rowSpan == 1) { - td.parentNode.removeChild(td); - } else { - mergeTds.push(td); - } - }); - utils.each(mergeTds, function (td) { - td.rowSpan--; - }); - row.parentNode.removeChild(row); - //浏览器方法本身存在bug,采用自定义方法删除 - //this.table.deleteRow(rowIndex); - this.update(); - }, - insertCol:function (colIndex, sourceCell, defaultValue) { - var rowsNum = this.rowsNum, - rowIndex = 0, - tableRow, cell, - backWidth = parseInt((this.table.offsetWidth - (this.colsNum + 1) * 20 - (this.colsNum + 1)) / (this.colsNum + 1), 10), - isInsertTitleCol = typeof sourceCell == 'string' && sourceCell.toUpperCase() == 'TH'; - - function replaceTdToTh(rowIndex, cell, tableRow) { - if (rowIndex == 0) { - var th = cell.nextSibling || cell.previousSibling; - if (th.tagName == 'TH') { - th = cell.ownerDocument.createElement("th"); - th.appendChild(cell.firstChild); - tableRow.insertBefore(th, cell); - domUtils.remove(cell) - } - }else{ - if (cell.tagName == 'TH') { - var td = cell.ownerDocument.createElement("td"); - td.appendChild(cell.firstChild); - tableRow.insertBefore(td, cell); - domUtils.remove(cell) - } - } - } - - var preCell; - if (colIndex == 0 || colIndex == this.colsNum) { - for (; rowIndex < rowsNum; rowIndex++) { - tableRow = this.table.rows[rowIndex]; - preCell = tableRow.cells[colIndex == 0 ? colIndex : tableRow.cells.length]; - cell = this.cloneCell(sourceCell, true); //tableRow.insertCell(colIndex == 0 ? colIndex : tableRow.cells.length); - this.setCellContent(cell); - cell.setAttribute('vAlign', cell.getAttribute('vAlign')); - preCell && cell.setAttribute('width', preCell.getAttribute('width')); - if (!colIndex) { - tableRow.insertBefore(cell, tableRow.cells[0]); - } else { - domUtils.insertAfter(tableRow.cells[tableRow.cells.length - 1], cell); - } - if(!isInsertTitleCol) replaceTdToTh(rowIndex, cell, tableRow) - } - } else { - for (; rowIndex < rowsNum; rowIndex++) { - var cellInfo = this.indexTable[rowIndex][colIndex]; - if (cellInfo.colIndex < colIndex) { - cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex); - cell.colSpan = cellInfo.colSpan + 1; - } else { - tableRow = this.table.rows[rowIndex]; - preCell = tableRow.cells[cellInfo.cellIndex]; - - cell = this.cloneCell(sourceCell, true);//tableRow.insertCell(cellInfo.cellIndex); - this.setCellContent(cell); - cell.setAttribute('vAlign', cell.getAttribute('vAlign')); - preCell && cell.setAttribute('width', preCell.getAttribute('width')); - //防止IE下报错 - preCell ? tableRow.insertBefore(cell, preCell) : tableRow.appendChild(cell); - } - if(!isInsertTitleCol) replaceTdToTh(rowIndex, cell, tableRow); - } - } - //框选时插入不触发contentchange,需要手动更新索引 - this.update(); - this.updateWidth(backWidth, defaultValue || {tdPadding:10, tdBorder:1}); - }, - updateWidth:function (width, defaultValue) { - var table = this.table, - tmpWidth = UETable.getWidth(table) - defaultValue.tdPadding * 2 - defaultValue.tdBorder + width; - if (tmpWidth < table.ownerDocument.body.offsetWidth) { - table.setAttribute("width", tmpWidth); - return; - } - var tds = domUtils.getElementsByTagName(this.table, "td th"); - utils.each(tds, function (td) { - td.setAttribute("width", width); - }) - }, - deleteCol:function (colIndex) { - var indexTable = this.indexTable, - tableRows = this.table.rows, - backTableWidth = this.table.getAttribute("width"), - backTdWidth = 0, - rowsNum = this.rowsNum, - cacheMap = {}; - for (var rowIndex = 0; rowIndex < rowsNum;) { - var infoRow = indexTable[rowIndex], - cellInfo = infoRow[colIndex], - key = cellInfo.rowIndex + '_' + cellInfo.colIndex; - // 跳过已经处理过的Cell - if (cacheMap[key])continue; - cacheMap[key] = 1; - var cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex); - if (!backTdWidth) backTdWidth = cell && parseInt(cell.offsetWidth / cell.colSpan, 10).toFixed(0); - // 如果Cell的colSpan大于1, 就修改colSpan, 否则就删掉这个Cell - if (cell.colSpan > 1) { - cell.colSpan--; - } else { - tableRows[rowIndex].deleteCell(cellInfo.cellIndex); - } - rowIndex += cellInfo.rowSpan || 1; - } - this.table.setAttribute("width", backTableWidth - backTdWidth); - this.update(); - }, - splitToCells:function (cell) { - var me = this, - cells = this.splitToRows(cell); - utils.each(cells, function (cell) { - me.splitToCols(cell); - }) - }, - splitToRows:function (cell) { - var cellInfo = this.getCellInfo(cell), - rowIndex = cellInfo.rowIndex, - colIndex = cellInfo.colIndex, - results = []; - // 修改Cell的rowSpan - cell.rowSpan = 1; - results.push(cell); - // 补齐单元格 - for (var i = rowIndex, endRow = rowIndex + cellInfo.rowSpan; i < endRow; i++) { - if (i == rowIndex)continue; - var tableRow = this.table.rows[i], - tmpCell = tableRow.insertCell(colIndex - this.getPreviewMergedCellsNum(i, colIndex)); - tmpCell.colSpan = cellInfo.colSpan; - this.setCellContent(tmpCell); - tmpCell.setAttribute('vAlign', cell.getAttribute('vAlign')); - tmpCell.setAttribute('align', cell.getAttribute('align')); - if (cell.style.cssText) { - tmpCell.style.cssText = cell.style.cssText; - } - results.push(tmpCell); - } - this.update(); - return results; - }, - getPreviewMergedCellsNum:function (rowIndex, colIndex) { - var indexRow = this.indexTable[rowIndex], - num = 0; - for (var i = 0; i < colIndex;) { - var colSpan = indexRow[i].colSpan, - tmpRowIndex = indexRow[i].rowIndex; - num += (colSpan - (tmpRowIndex == rowIndex ? 1 : 0)); - i += colSpan; - } - return num; - }, - splitToCols:function (cell) { - var backWidth = (cell.offsetWidth / cell.colSpan - 22).toFixed(0), - - cellInfo = this.getCellInfo(cell), - rowIndex = cellInfo.rowIndex, - colIndex = cellInfo.colIndex, - results = []; - // 修改Cell的rowSpan - cell.colSpan = 1; - cell.setAttribute("width", backWidth); - results.push(cell); - // 补齐单元格 - for (var j = colIndex, endCol = colIndex + cellInfo.colSpan; j < endCol; j++) { - if (j == colIndex)continue; - var tableRow = this.table.rows[rowIndex], - tmpCell = tableRow.insertCell(this.indexTable[rowIndex][j].cellIndex + 1); - tmpCell.rowSpan = cellInfo.rowSpan; - this.setCellContent(tmpCell); - tmpCell.setAttribute('vAlign', cell.getAttribute('vAlign')); - tmpCell.setAttribute('align', cell.getAttribute('align')); - tmpCell.setAttribute('width', backWidth); - if (cell.style.cssText) { - tmpCell.style.cssText = cell.style.cssText; - } - //处理th的情况 - if (cell.tagName == 'TH') { - var th = cell.ownerDocument.createElement('th'); - th.appendChild(tmpCell.firstChild); - th.setAttribute('vAlign', cell.getAttribute('vAlign')); - th.rowSpan = tmpCell.rowSpan; - tableRow.insertBefore(th, tmpCell); - domUtils.remove(tmpCell); - } - results.push(tmpCell); - } - this.update(); - return results; - }, - isLastCell:function (cell, rowsNum, colsNum) { - rowsNum = rowsNum || this.rowsNum; - colsNum = colsNum || this.colsNum; - var cellInfo = this.getCellInfo(cell); - return ((cellInfo.rowIndex + cellInfo.rowSpan) == rowsNum) && - ((cellInfo.colIndex + cellInfo.colSpan) == colsNum); - }, - getLastCell:function (cells) { - cells = cells || this.table.getElementsByTagName("td"); - var firstInfo = this.getCellInfo(cells[0]); - var me = this, last = cells[0], - tr = last.parentNode, - cellsNum = 0, cols = 0, rows; - utils.each(cells, function (cell) { - if (cell.parentNode == tr)cols += cell.colSpan || 1; - cellsNum += cell.rowSpan * cell.colSpan || 1; - }); - rows = cellsNum / cols; - utils.each(cells, function (cell) { - if (me.isLastCell(cell, rows, cols)) { - last = cell; - return false; - } - }); - return last; - - }, - selectRow:function (rowIndex) { - var indexRow = this.indexTable[rowIndex], - start = this.getCell(indexRow[0].rowIndex, indexRow[0].cellIndex), - end = this.getCell(indexRow[this.colsNum - 1].rowIndex, indexRow[this.colsNum - 1].cellIndex), - range = this.getCellsRange(start, end); - this.setSelected(range); - }, - selectTable:function () { - var tds = this.table.getElementsByTagName("td"), - range = this.getCellsRange(tds[0], tds[tds.length - 1]); - this.setSelected(range); - }, - setBackground:function (cells, value) { - if (typeof value === "string") { - utils.each(cells, function (cell) { - cell.style.backgroundColor = value; - }) - } else if (typeof value === "object") { - value = utils.extend({ - repeat:true, - colorList:["#ddd", "#fff"] - }, value); - var rowIndex = this.getCellInfo(cells[0]).rowIndex, - count = 0, - colors = value.colorList, - getColor = function (list, index, repeat) { - return list[index] ? list[index] : repeat ? list[index % list.length] : ""; - }; - for (var i = 0, cell; cell = cells[i++];) { - var cellInfo = this.getCellInfo(cell); - cell.style.backgroundColor = getColor(colors, ((rowIndex + count) == cellInfo.rowIndex) ? count : ++count, value.repeat); - } - } - }, - removeBackground:function (cells) { - utils.each(cells, function (cell) { - cell.style.backgroundColor = ""; - }) - } - - - }; - function showError(e) { - } -})(); - -// plugins/table.cmds.js -/** - * Created with JetBrains PhpStorm. - * User: taoqili - * Date: 13-2-20 - * Time: 下午6:25 - * To change this template use File | Settings | File Templates. - */ -; -(function () { - var UT = UE.UETable, - getTableItemsByRange = function (editor) { - return UT.getTableItemsByRange(editor); - }, - getUETableBySelected = function (editor) { - return UT.getUETableBySelected(editor) - }, - getDefaultValue = function (editor, table) { - return UT.getDefaultValue(editor, table); - }, - getUETable = function (tdOrTable) { - return UT.getUETable(tdOrTable); - }; - - - UE.commands['inserttable'] = { - queryCommandState: function () { - return getTableItemsByRange(this).table ? -1 : 0; - }, - execCommand: function (cmd, opt) { - function createTable(opt, tdWidth) { - var html = [], - rowsNum = opt.numRows, - colsNum = opt.numCols; - for (var r = 0; r < rowsNum; r++) { - html.push(''); - for (var c = 0; c < colsNum; c++) { - html.push('
  • ' + (browser.ie && browser.version < 11 ? domUtils.fillChar : '
    ') + '
    ' + html.join('') + '
    ' - } - - if (!opt) { - opt = utils.extend({}, { - numCols: this.options.defaultCols, - numRows: this.options.defaultRows, - tdvalign: this.options.tdvalign - }) - } - var me = this; - var range = this.selection.getRange(), - start = range.startContainer, - firstParentBlock = domUtils.findParent(start, function (node) { - return domUtils.isBlockElm(node); - }, true) || me.body; - - var defaultValue = getDefaultValue(me), - tableWidth = firstParentBlock.offsetWidth, - tdWidth = Math.floor(tableWidth / opt.numCols - defaultValue.tdPadding * 2 - defaultValue.tdBorder); - - //todo其他属性 - !opt.tdvalign && (opt.tdvalign = me.options.tdvalign); - me.execCommand("inserthtml", createTable(opt, tdWidth)); - } - }; - - UE.commands['insertparagraphbeforetable'] = { - queryCommandState: function () { - return getTableItemsByRange(this).cell ? 0 : -1; - }, - execCommand: function () { - var table = getTableItemsByRange(this).table; - if (table) { - var p = this.document.createElement("p"); - p.innerHTML = browser.ie ? ' ' : '
    '; - table.parentNode.insertBefore(p, table); - this.selection.getRange().setStart(p, 0).setCursor(); - } - } - }; - - UE.commands['deletetable'] = { - queryCommandState: function () { - var rng = this.selection.getRange(); - return domUtils.findParentByTagName(rng.startContainer, 'table', true) ? 0 : -1; - }, - execCommand: function (cmd, table) { - var rng = this.selection.getRange(); - table = table || domUtils.findParentByTagName(rng.startContainer, 'table', true); - if (table) { - var next = table.nextSibling; - if (!next) { - next = domUtils.createElement(this.document, 'p', { - 'innerHTML': browser.ie ? domUtils.fillChar : '
    ' - }); - table.parentNode.insertBefore(next, table); - } - domUtils.remove(table); - rng = this.selection.getRange(); - if (next.nodeType == 3) { - rng.setStartBefore(next) - } else { - rng.setStart(next, 0) - } - rng.setCursor(false, true) - this.fireEvent("tablehasdeleted") - - } - - } - }; - UE.commands['cellalign'] = { - queryCommandState: function () { - return getSelectedArr(this).length ? 0 : -1 - }, - execCommand: function (cmd, align) { - var selectedTds = getSelectedArr(this); - if (selectedTds.length) { - for (var i = 0, ci; ci = selectedTds[i++];) { - ci.setAttribute('align', align); - } - } - } - }; - UE.commands['cellvalign'] = { - queryCommandState: function () { - return getSelectedArr(this).length ? 0 : -1; - }, - execCommand: function (cmd, valign) { - var selectedTds = getSelectedArr(this); - if (selectedTds.length) { - for (var i = 0, ci; ci = selectedTds[i++];) { - ci.setAttribute('vAlign', valign); - } - } - } - }; - UE.commands['insertcaption'] = { - queryCommandState: function () { - var table = getTableItemsByRange(this).table; - if (table) { - return table.getElementsByTagName('caption').length == 0 ? 1 : -1; - } - return -1; - }, - execCommand: function () { - var table = getTableItemsByRange(this).table; - if (table) { - var caption = this.document.createElement('caption'); - caption.innerHTML = browser.ie ? domUtils.fillChar : '
    '; - table.insertBefore(caption, table.firstChild); - var range = this.selection.getRange(); - range.setStart(caption, 0).setCursor(); - } - - } - }; - UE.commands['deletecaption'] = { - queryCommandState: function () { - var rng = this.selection.getRange(), - table = domUtils.findParentByTagName(rng.startContainer, 'table'); - if (table) { - return table.getElementsByTagName('caption').length == 0 ? -1 : 1; - } - return -1; - }, - execCommand: function () { - var rng = this.selection.getRange(), - table = domUtils.findParentByTagName(rng.startContainer, 'table'); - if (table) { - domUtils.remove(table.getElementsByTagName('caption')[0]); - var range = this.selection.getRange(); - range.setStart(table.rows[0].cells[0], 0).setCursor(); - } - - } - }; - UE.commands['inserttitle'] = { - queryCommandState: function () { - var table = getTableItemsByRange(this).table; - if (table) { - var firstRow = table.rows[0]; - return firstRow.cells[firstRow.cells.length-1].tagName.toLowerCase() != 'th' ? 0 : -1 - } - return -1; - }, - execCommand: function () { - var table = getTableItemsByRange(this).table; - if (table) { - getUETable(table).insertRow(0, 'th'); - } - var th = table.getElementsByTagName('th')[0]; - this.selection.getRange().setStart(th, 0).setCursor(false, true); - } - }; - UE.commands['deletetitle'] = { - queryCommandState: function () { - var table = getTableItemsByRange(this).table; - if (table) { - var firstRow = table.rows[0]; - return firstRow.cells[firstRow.cells.length-1].tagName.toLowerCase() == 'th' ? 0 : -1 - } - return -1; - }, - execCommand: function () { - var table = getTableItemsByRange(this).table; - if (table) { - domUtils.remove(table.rows[0]) - } - var td = table.getElementsByTagName('td')[0]; - this.selection.getRange().setStart(td, 0).setCursor(false, true); - } - }; - UE.commands['inserttitlecol'] = { - queryCommandState: function () { - var table = getTableItemsByRange(this).table; - if (table) { - var lastRow = table.rows[table.rows.length-1]; - return lastRow.getElementsByTagName('th').length ? -1 : 0; - } - return -1; - }, - execCommand: function (cmd) { - var table = getTableItemsByRange(this).table; - if (table) { - getUETable(table).insertCol(0, 'th'); - } - resetTdWidth(table, this); - var th = table.getElementsByTagName('th')[0]; - this.selection.getRange().setStart(th, 0).setCursor(false, true); - } - }; - UE.commands['deletetitlecol'] = { - queryCommandState: function () { - var table = getTableItemsByRange(this).table; - if (table) { - var lastRow = table.rows[table.rows.length-1]; - return lastRow.getElementsByTagName('th').length ? 0 : -1; - } - return -1; - }, - execCommand: function () { - var table = getTableItemsByRange(this).table; - if (table) { - for(var i = 0; i< table.rows.length; i++ ){ - domUtils.remove(table.rows[i].children[0]) - } - } - resetTdWidth(table, this); - var td = table.getElementsByTagName('td')[0]; - this.selection.getRange().setStart(td, 0).setCursor(false, true); - } - }; - - UE.commands["mergeright"] = { - queryCommandState: function (cmd) { - var tableItems = getTableItemsByRange(this), - table = tableItems.table, - cell = tableItems.cell; - - if (!table || !cell) return -1; - var ut = getUETable(table); - if (ut.selectedTds.length) return -1; - - var cellInfo = ut.getCellInfo(cell), - rightColIndex = cellInfo.colIndex + cellInfo.colSpan; - if (rightColIndex >= ut.colsNum) return -1; // 如果处于最右边则不能向右合并 - - var rightCellInfo = ut.indexTable[cellInfo.rowIndex][rightColIndex], - rightCell = table.rows[rightCellInfo.rowIndex].cells[rightCellInfo.cellIndex]; - if (!rightCell || cell.tagName != rightCell.tagName) return -1; // TH和TD不能相互合并 - - // 当且仅当两个Cell的开始列号和结束列号一致时能进行合并 - return (rightCellInfo.rowIndex == cellInfo.rowIndex && rightCellInfo.rowSpan == cellInfo.rowSpan) ? 0 : -1; - }, - execCommand: function (cmd) { - var rng = this.selection.getRange(), - bk = rng.createBookmark(true); - var cell = getTableItemsByRange(this).cell, - ut = getUETable(cell); - ut.mergeRight(cell); - rng.moveToBookmark(bk).select(); - } - }; - UE.commands["mergedown"] = { - queryCommandState: function (cmd) { - var tableItems = getTableItemsByRange(this), - table = tableItems.table, - cell = tableItems.cell; - - if (!table || !cell) return -1; - var ut = getUETable(table); - if (ut.selectedTds.length)return -1; - - var cellInfo = ut.getCellInfo(cell), - downRowIndex = cellInfo.rowIndex + cellInfo.rowSpan; - if (downRowIndex >= ut.rowsNum) return -1; // 如果处于最下边则不能向下合并 - - var downCellInfo = ut.indexTable[downRowIndex][cellInfo.colIndex], - downCell = table.rows[downCellInfo.rowIndex].cells[downCellInfo.cellIndex]; - if (!downCell || cell.tagName != downCell.tagName) return -1; // TH和TD不能相互合并 - - // 当且仅当两个Cell的开始列号和结束列号一致时能进行合并 - return (downCellInfo.colIndex == cellInfo.colIndex && downCellInfo.colSpan == cellInfo.colSpan) ? 0 : -1; - }, - execCommand: function () { - var rng = this.selection.getRange(), - bk = rng.createBookmark(true); - var cell = getTableItemsByRange(this).cell, - ut = getUETable(cell); - ut.mergeDown(cell); - rng.moveToBookmark(bk).select(); - } - }; - UE.commands["mergecells"] = { - queryCommandState: function () { - return getUETableBySelected(this) ? 0 : -1; - }, - execCommand: function () { - var ut = getUETableBySelected(this); - if (ut && ut.selectedTds.length) { - var cell = ut.selectedTds[0]; - ut.mergeRange(); - var rng = this.selection.getRange(); - if (domUtils.isEmptyBlock(cell)) { - rng.setStart(cell, 0).collapse(true) - } else { - rng.selectNodeContents(cell) - } - rng.select(); - } - - - } - }; - UE.commands["insertrow"] = { - queryCommandState: function () { - var tableItems = getTableItemsByRange(this), - cell = tableItems.cell; - return cell && (cell.tagName == "TD" || (cell.tagName == 'TH' && tableItems.tr !== tableItems.table.rows[0])) && - getUETable(tableItems.table).rowsNum < this.options.maxRowNum ? 0 : -1; - }, - execCommand: function () { - var rng = this.selection.getRange(), - bk = rng.createBookmark(true); - var tableItems = getTableItemsByRange(this), - cell = tableItems.cell, - table = tableItems.table, - ut = getUETable(table), - cellInfo = ut.getCellInfo(cell); - //ut.insertRow(!ut.selectedTds.length ? cellInfo.rowIndex:ut.cellsRange.beginRowIndex,''); - if (!ut.selectedTds.length) { - ut.insertRow(cellInfo.rowIndex, cell); - } else { - var range = ut.cellsRange; - for (var i = 0, len = range.endRowIndex - range.beginRowIndex + 1; i < len; i++) { - ut.insertRow(range.beginRowIndex, cell); - } - } - rng.moveToBookmark(bk).select(); - if (table.getAttribute("interlaced") === "enabled")this.fireEvent("interlacetable", table); - } - }; - //后插入行 - UE.commands["insertrownext"] = { - queryCommandState: function () { - var tableItems = getTableItemsByRange(this), - cell = tableItems.cell; - return cell && (cell.tagName == "TD") && getUETable(tableItems.table).rowsNum < this.options.maxRowNum ? 0 : -1; - }, - execCommand: function () { - var rng = this.selection.getRange(), - bk = rng.createBookmark(true); - var tableItems = getTableItemsByRange(this), - cell = tableItems.cell, - table = tableItems.table, - ut = getUETable(table), - cellInfo = ut.getCellInfo(cell); - //ut.insertRow(!ut.selectedTds.length? cellInfo.rowIndex + cellInfo.rowSpan : ut.cellsRange.endRowIndex + 1,''); - if (!ut.selectedTds.length) { - ut.insertRow(cellInfo.rowIndex + cellInfo.rowSpan, cell); - } else { - var range = ut.cellsRange; - for (var i = 0, len = range.endRowIndex - range.beginRowIndex + 1; i < len; i++) { - ut.insertRow(range.endRowIndex + 1, cell); - } - } - rng.moveToBookmark(bk).select(); - if (table.getAttribute("interlaced") === "enabled")this.fireEvent("interlacetable", table); - } - }; - UE.commands["deleterow"] = { - queryCommandState: function () { - var tableItems = getTableItemsByRange(this); - return tableItems.cell ? 0 : -1; - }, - execCommand: function () { - var cell = getTableItemsByRange(this).cell, - ut = getUETable(cell), - cellsRange = ut.cellsRange, - cellInfo = ut.getCellInfo(cell), - preCell = ut.getVSideCell(cell), - nextCell = ut.getVSideCell(cell, true), - rng = this.selection.getRange(); - if (utils.isEmptyObject(cellsRange)) { - ut.deleteRow(cellInfo.rowIndex); - } else { - for (var i = cellsRange.beginRowIndex; i < cellsRange.endRowIndex + 1; i++) { - ut.deleteRow(cellsRange.beginRowIndex); - } - } - var table = ut.table; - if (!table.getElementsByTagName('td').length) { - var nextSibling = table.nextSibling; - domUtils.remove(table); - if (nextSibling) { - rng.setStart(nextSibling, 0).setCursor(false, true); - } - } else { - if (cellInfo.rowSpan == 1 || cellInfo.rowSpan == cellsRange.endRowIndex - cellsRange.beginRowIndex + 1) { - if (nextCell || preCell) rng.selectNodeContents(nextCell || preCell).setCursor(false, true); - } else { - var newCell = ut.getCell(cellInfo.rowIndex, ut.indexTable[cellInfo.rowIndex][cellInfo.colIndex].cellIndex); - if (newCell) rng.selectNodeContents(newCell).setCursor(false, true); - } - } - if (table.getAttribute("interlaced") === "enabled")this.fireEvent("interlacetable", table); - } - }; - UE.commands["insertcol"] = { - queryCommandState: function (cmd) { - var tableItems = getTableItemsByRange(this), - cell = tableItems.cell; - return cell && (cell.tagName == "TD" || (cell.tagName == 'TH' && cell !== tableItems.tr.cells[0])) && - getUETable(tableItems.table).colsNum < this.options.maxColNum ? 0 : -1; - }, - execCommand: function (cmd) { - var rng = this.selection.getRange(), - bk = rng.createBookmark(true); - if (this.queryCommandState(cmd) == -1)return; - var cell = getTableItemsByRange(this).cell, - ut = getUETable(cell), - cellInfo = ut.getCellInfo(cell); - - //ut.insertCol(!ut.selectedTds.length ? cellInfo.colIndex:ut.cellsRange.beginColIndex); - if (!ut.selectedTds.length) { - ut.insertCol(cellInfo.colIndex, cell); - } else { - var range = ut.cellsRange; - for (var i = 0, len = range.endColIndex - range.beginColIndex + 1; i < len; i++) { - ut.insertCol(range.beginColIndex, cell); - } - } - rng.moveToBookmark(bk).select(true); - } - }; - UE.commands["insertcolnext"] = { - queryCommandState: function () { - var tableItems = getTableItemsByRange(this), - cell = tableItems.cell; - return cell && getUETable(tableItems.table).colsNum < this.options.maxColNum ? 0 : -1; - }, - execCommand: function () { - var rng = this.selection.getRange(), - bk = rng.createBookmark(true); - var cell = getTableItemsByRange(this).cell, - ut = getUETable(cell), - cellInfo = ut.getCellInfo(cell); - //ut.insertCol(!ut.selectedTds.length ? cellInfo.colIndex + cellInfo.colSpan:ut.cellsRange.endColIndex +1); - if (!ut.selectedTds.length) { - ut.insertCol(cellInfo.colIndex + cellInfo.colSpan, cell); - } else { - var range = ut.cellsRange; - for (var i = 0, len = range.endColIndex - range.beginColIndex + 1; i < len; i++) { - ut.insertCol(range.endColIndex + 1, cell); - } - } - rng.moveToBookmark(bk).select(); - } - }; - - UE.commands["deletecol"] = { - queryCommandState: function () { - var tableItems = getTableItemsByRange(this); - return tableItems.cell ? 0 : -1; - }, - execCommand: function () { - var cell = getTableItemsByRange(this).cell, - ut = getUETable(cell), - range = ut.cellsRange, - cellInfo = ut.getCellInfo(cell), - preCell = ut.getHSideCell(cell), - nextCell = ut.getHSideCell(cell, true); - if (utils.isEmptyObject(range)) { - ut.deleteCol(cellInfo.colIndex); - } else { - for (var i = range.beginColIndex; i < range.endColIndex + 1; i++) { - ut.deleteCol(range.beginColIndex); - } - } - var table = ut.table, - rng = this.selection.getRange(); - - if (!table.getElementsByTagName('td').length) { - var nextSibling = table.nextSibling; - domUtils.remove(table); - if (nextSibling) { - rng.setStart(nextSibling, 0).setCursor(false, true); - } - } else { - if (domUtils.inDoc(cell, this.document)) { - rng.setStart(cell, 0).setCursor(false, true); - } else { - if (nextCell && domUtils.inDoc(nextCell, this.document)) { - rng.selectNodeContents(nextCell).setCursor(false, true); - } else { - if (preCell && domUtils.inDoc(preCell, this.document)) { - rng.selectNodeContents(preCell).setCursor(true, true); - } - } - } - } - } - }; - UE.commands["splittocells"] = { - queryCommandState: function () { - var tableItems = getTableItemsByRange(this), - cell = tableItems.cell; - if (!cell) return -1; - var ut = getUETable(tableItems.table); - if (ut.selectedTds.length > 0) return -1; - return cell && (cell.colSpan > 1 || cell.rowSpan > 1) ? 0 : -1; - }, - execCommand: function () { - var rng = this.selection.getRange(), - bk = rng.createBookmark(true); - var cell = getTableItemsByRange(this).cell, - ut = getUETable(cell); - ut.splitToCells(cell); - rng.moveToBookmark(bk).select(); - } - }; - UE.commands["splittorows"] = { - queryCommandState: function () { - var tableItems = getTableItemsByRange(this), - cell = tableItems.cell; - if (!cell) return -1; - var ut = getUETable(tableItems.table); - if (ut.selectedTds.length > 0) return -1; - return cell && cell.rowSpan > 1 ? 0 : -1; - }, - execCommand: function () { - var rng = this.selection.getRange(), - bk = rng.createBookmark(true); - var cell = getTableItemsByRange(this).cell, - ut = getUETable(cell); - ut.splitToRows(cell); - rng.moveToBookmark(bk).select(); - } - }; - UE.commands["splittocols"] = { - queryCommandState: function () { - var tableItems = getTableItemsByRange(this), - cell = tableItems.cell; - if (!cell) return -1; - var ut = getUETable(tableItems.table); - if (ut.selectedTds.length > 0) return -1; - return cell && cell.colSpan > 1 ? 0 : -1; - }, - execCommand: function () { - var rng = this.selection.getRange(), - bk = rng.createBookmark(true); - var cell = getTableItemsByRange(this).cell, - ut = getUETable(cell); - ut.splitToCols(cell); - rng.moveToBookmark(bk).select(); - - } - }; - - UE.commands["adaptbytext"] = - UE.commands["adaptbywindow"] = { - queryCommandState: function () { - return getTableItemsByRange(this).table ? 0 : -1 - }, - execCommand: function (cmd) { - var tableItems = getTableItemsByRange(this), - table = tableItems.table; - if (table) { - if (cmd == 'adaptbywindow') { - resetTdWidth(table, this); - } else { - var cells = domUtils.getElementsByTagName(table, "td th"); - utils.each(cells, function (cell) { - cell.removeAttribute("width"); - }); - table.removeAttribute("width"); - } - } - } - }; - - //平均分配各列 - UE.commands['averagedistributecol'] = { - queryCommandState: function () { - var ut = getUETableBySelected(this); - if (!ut) return -1; - return ut.isFullRow() || ut.isFullCol() ? 0 : -1; - }, - execCommand: function (cmd) { - var me = this, - ut = getUETableBySelected(me); - - function getAverageWidth() { - var tb = ut.table, - averageWidth, sumWidth = 0, colsNum = 0, - tbAttr = getDefaultValue(me, tb); - - if (ut.isFullRow()) { - sumWidth = tb.offsetWidth; - colsNum = ut.colsNum; - } else { - var begin = ut.cellsRange.beginColIndex, - end = ut.cellsRange.endColIndex, - node; - for (var i = begin; i <= end;) { - node = ut.selectedTds[i]; - sumWidth += node.offsetWidth; - i += node.colSpan; - colsNum += 1; - } - } - averageWidth = Math.ceil(sumWidth / colsNum) - tbAttr.tdBorder * 2 - tbAttr.tdPadding * 2; - return averageWidth; - } - - function setAverageWidth(averageWidth) { - utils.each(domUtils.getElementsByTagName(ut.table, "th"), function (node) { - node.setAttribute("width", ""); - }); - var cells = ut.isFullRow() ? domUtils.getElementsByTagName(ut.table, "td") : ut.selectedTds; - - utils.each(cells, function (node) { - if (node.colSpan == 1) { - node.setAttribute("width", averageWidth); - } - }); - } - - if (ut && ut.selectedTds.length) { - setAverageWidth(getAverageWidth()); - } - } - }; - //平均分配各行 - UE.commands['averagedistributerow'] = { - queryCommandState: function () { - var ut = getUETableBySelected(this); - if (!ut) return -1; - if (ut.selectedTds && /th/ig.test(ut.selectedTds[0].tagName)) return -1; - return ut.isFullRow() || ut.isFullCol() ? 0 : -1; - }, - execCommand: function (cmd) { - var me = this, - ut = getUETableBySelected(me); - - function getAverageHeight() { - var averageHeight, rowNum, sumHeight = 0, - tb = ut.table, - tbAttr = getDefaultValue(me, tb), - tdpadding = parseInt(domUtils.getComputedStyle(tb.getElementsByTagName('td')[0], "padding-top")); - - if (ut.isFullCol()) { - var captionArr = domUtils.getElementsByTagName(tb, "caption"), - thArr = domUtils.getElementsByTagName(tb, "th"), - captionHeight, thHeight; - - if (captionArr.length > 0) { - captionHeight = captionArr[0].offsetHeight; - } - if (thArr.length > 0) { - thHeight = thArr[0].offsetHeight; - } - - sumHeight = tb.offsetHeight - (captionHeight || 0) - (thHeight || 0); - rowNum = thArr.length == 0 ? ut.rowsNum : (ut.rowsNum - 1); - } else { - var begin = ut.cellsRange.beginRowIndex, - end = ut.cellsRange.endRowIndex, - count = 0, - trs = domUtils.getElementsByTagName(tb, "tr"); - for (var i = begin; i <= end; i++) { - sumHeight += trs[i].offsetHeight; - count += 1; - } - rowNum = count; - } - //ie8下是混杂模式 - if (browser.ie && browser.version < 9) { - averageHeight = Math.ceil(sumHeight / rowNum); - } else { - averageHeight = Math.ceil(sumHeight / rowNum) - tbAttr.tdBorder * 2 - tdpadding * 2; - } - return averageHeight; - } - - function setAverageHeight(averageHeight) { - var cells = ut.isFullCol() ? domUtils.getElementsByTagName(ut.table, "td") : ut.selectedTds; - utils.each(cells, function (node) { - if (node.rowSpan == 1) { - node.setAttribute("height", averageHeight); - } - }); - } - - if (ut && ut.selectedTds.length) { - setAverageHeight(getAverageHeight()); - } - } - }; - - //单元格对齐方式 - UE.commands['cellalignment'] = { - queryCommandState: function () { - return getTableItemsByRange(this).table ? 0 : -1 - }, - execCommand: function (cmd, data) { - var me = this, - ut = getUETableBySelected(me); - - if (!ut) { - var start = me.selection.getStart(), - cell = start && domUtils.findParentByTagName(start, ["td", "th", "caption"], true); - if (!/caption/ig.test(cell.tagName)) { - domUtils.setAttributes(cell, data); - } else { - cell.style.textAlign = data.align; - cell.style.verticalAlign = data.vAlign; - } - me.selection.getRange().setCursor(true); - } else { - utils.each(ut.selectedTds, function (cell) { - domUtils.setAttributes(cell, data); - }); - } - }, - /** - * 查询当前点击的单元格的对齐状态, 如果当前已经选择了多个单元格, 则会返回所有单元格经过统一协调过后的状态 - * @see UE.UETable.getTableCellAlignState - */ - queryCommandValue: function (cmd) { - - var activeMenuCell = getTableItemsByRange( this).cell; - - if( !activeMenuCell ) { - activeMenuCell = getSelectedArr(this)[0]; - } - - if (!activeMenuCell) { - - return null; - - } else { - - //获取同时选中的其他单元格 - var cells = UE.UETable.getUETable(activeMenuCell).selectedTds; - - !cells.length && ( cells = activeMenuCell ); - - return UE.UETable.getTableCellAlignState(cells); - - } - - } - }; - //表格对齐方式 - UE.commands['tablealignment'] = { - queryCommandState: function () { - if (browser.ie && browser.version < 8) { - return -1; - } - return getTableItemsByRange(this).table ? 0 : -1 - }, - execCommand: function (cmd, value) { - var me = this, - start = me.selection.getStart(), - table = start && domUtils.findParentByTagName(start, ["table"], true); - - if (table) { - table.setAttribute("align",value); - } - } - }; - - //表格属性 - UE.commands['edittable'] = { - queryCommandState: function () { - return getTableItemsByRange(this).table ? 0 : -1 - }, - execCommand: function (cmd, color) { - var rng = this.selection.getRange(), - table = domUtils.findParentByTagName(rng.startContainer, 'table'); - if (table) { - var arr = domUtils.getElementsByTagName(table, "td").concat( - domUtils.getElementsByTagName(table, "th"), - domUtils.getElementsByTagName(table, "caption") - ); - utils.each(arr, function (node) { - node.style.borderColor = color; - }); - } - } - }; - //单元格属性 - UE.commands['edittd'] = { - queryCommandState: function () { - return getTableItemsByRange(this).table ? 0 : -1 - }, - execCommand: function (cmd, bkColor) { - var me = this, - ut = getUETableBySelected(me); - - if (!ut) { - var start = me.selection.getStart(), - cell = start && domUtils.findParentByTagName(start, ["td", "th", "caption"], true); - if (cell) { - cell.style.backgroundColor = bkColor; - } - } else { - utils.each(ut.selectedTds, function (cell) { - cell.style.backgroundColor = bkColor; - }); - } - } - }; - - UE.commands["settablebackground"] = { - queryCommandState: function () { - return getSelectedArr(this).length > 1 ? 0 : -1; - }, - execCommand: function (cmd, value) { - var cells, ut; - cells = getSelectedArr(this); - ut = getUETable(cells[0]); - ut.setBackground(cells, value); - } - }; - - UE.commands["cleartablebackground"] = { - queryCommandState: function () { - var cells = getSelectedArr(this); - if (!cells.length)return -1; - for (var i = 0, cell; cell = cells[i++];) { - if (cell.style.backgroundColor !== "") return 0; - } - return -1; - }, - execCommand: function () { - var cells = getSelectedArr(this), - ut = getUETable(cells[0]); - ut.removeBackground(cells); - } - }; - - UE.commands["interlacetable"] = UE.commands["uninterlacetable"] = { - queryCommandState: function (cmd) { - var table = getTableItemsByRange(this).table; - if (!table) return -1; - var interlaced = table.getAttribute("interlaced"); - if (cmd == "interlacetable") { - //TODO 待定 - //是否需要待定,如果设置,则命令只能单次执行成功,但反射具备toggle效果;否则可以覆盖前次命令,但反射将不存在toggle效果 - return (interlaced === "enabled") ? -1 : 0; - } else { - return (!interlaced || interlaced === "disabled") ? -1 : 0; - } - }, - execCommand: function (cmd, classList) { - var table = getTableItemsByRange(this).table; - if (cmd == "interlacetable") { - table.setAttribute("interlaced", "enabled"); - this.fireEvent("interlacetable", table, classList); - } else { - table.setAttribute("interlaced", "disabled"); - this.fireEvent("uninterlacetable", table); - } - } - }; - UE.commands["setbordervisible"] = { - queryCommandState: function (cmd) { - var table = getTableItemsByRange(this).table; - if (!table) return -1; - return 0; - }, - execCommand: function () { - var table = getTableItemsByRange(this).table; - utils.each(domUtils.getElementsByTagName(table,'td'),function(td){ - td.style.borderWidth = '1px'; - td.style.borderStyle = 'solid'; - }) - } - }; - function resetTdWidth(table, editor) { - var tds = domUtils.getElementsByTagName(table,'td th'); - utils.each(tds, function (td) { - td.removeAttribute("width"); - }); - table.setAttribute('width', getTableWidth(editor, true, getDefaultValue(editor, table))); - var tdsWidths = []; - setTimeout(function () { - utils.each(tds, function (td) { - (td.colSpan == 1) && tdsWidths.push(td.offsetWidth) - }) - utils.each(tds, function (td,i) { - (td.colSpan == 1) && td.setAttribute("width", tdsWidths[i] + ""); - }) - }, 0); - } - - function getTableWidth(editor, needIEHack, defaultValue) { - var body = editor.body; - return body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (editor.options.offsetWidth || 0); - } - - function getSelectedArr(editor) { - var cell = getTableItemsByRange(editor).cell; - if (cell) { - var ut = getUETable(cell); - return ut.selectedTds.length ? ut.selectedTds : [cell]; - } else { - return []; - } - } -})(); - - -// plugins/table.action.js -/** - * Created with JetBrains PhpStorm. - * User: taoqili - * Date: 12-10-12 - * Time: 上午10:05 - * To change this template use File | Settings | File Templates. - */ -UE.plugins['table'] = function () { - var me = this, - tabTimer = null, - //拖动计时器 - tableDragTimer = null, - //双击计时器 - tableResizeTimer = null, - //单元格最小宽度 - cellMinWidth = 5, - isInResizeBuffer = false, - //单元格边框大小 - cellBorderWidth = 5, - //鼠标偏移距离 - offsetOfTableCell = 10, - //记录在有限时间内的点击状态, 共有3个取值, 0, 1, 2。 0代表未初始化, 1代表单击了1次,2代表2次 - singleClickState = 0, - userActionStatus = null, - //双击允许的时间范围 - dblclickTime = 360, - UT = UE.UETable, - getUETable = function (tdOrTable) { - return UT.getUETable(tdOrTable); - }, - getUETableBySelected = function (editor) { - return UT.getUETableBySelected(editor); - }, - getDefaultValue = function (editor, table) { - return UT.getDefaultValue(editor, table); - }, - removeSelectedClass = function (cells) { - return UT.removeSelectedClass(cells); - }; - - function showError(e) { -// throw e; - } - me.ready(function(){ - var me = this; - var orgGetText = me.selection.getText; - me.selection.getText = function(){ - var table = getUETableBySelected(me); - if(table){ - var str = ''; - utils.each(table.selectedTds,function(td){ - str += td[browser.ie?'innerText':'textContent']; - }) - return str; - }else{ - return orgGetText.call(me.selection) - } - - } - }) - - //处理拖动及框选相关方法 - var startTd = null, //鼠标按下时的锚点td - currentTd = null, //当前鼠标经过时的td - onDrag = "", //指示当前拖动状态,其值可为"","h","v" ,分别表示未拖动状态,横向拖动状态,纵向拖动状态,用于鼠标移动过程中的判断 - onBorder = false, //检测鼠标按下时是否处在单元格边缘位置 - dragButton = null, - dragOver = false, - dragLine = null, //模拟的拖动线 - dragTd = null; //发生拖动的目标td - - var mousedown = false, - //todo 判断混乱模式 - needIEHack = true; - - me.setOpt({ - 'maxColNum':20, - 'maxRowNum':100, - 'defaultCols':5, - 'defaultRows':5, - 'tdvalign':'top', - 'cursorpath':me.options.UEDITOR_HOME_URL + "themes/default/images/cursor_", - 'tableDragable':false, - 'classList':["ue-table-interlace-color-single","ue-table-interlace-color-double"] - }); - me.getUETable = getUETable; - var commands = { - 'deletetable':1, - 'inserttable':1, - 'cellvalign':1, - 'insertcaption':1, - 'deletecaption':1, - 'inserttitle':1, - 'deletetitle':1, - "mergeright":1, - "mergedown":1, - "mergecells":1, - "insertrow":1, - "insertrownext":1, - "deleterow":1, - "insertcol":1, - "insertcolnext":1, - "deletecol":1, - "splittocells":1, - "splittorows":1, - "splittocols":1, - "adaptbytext":1, - "adaptbywindow":1, - "adaptbycustomer":1, - "insertparagraph":1, - "insertparagraphbeforetable":1, - "averagedistributecol":1, - "averagedistributerow":1 - }; - me.ready(function () { - utils.cssRule('table', - //选中的td上的样式 - '.selectTdClass{background-color:#edf5fa !important}' + - 'table.noBorderTable td,table.noBorderTable th,table.noBorderTable caption{border:1px dashed #ddd !important}' + - //插入的表格的默认样式 - 'table{margin-bottom:10px;border-collapse:collapse;display:table;}' + - 'td,th{padding: 5px 10px;border: 1px solid #DDD;}' + - 'caption{border:1px dashed #DDD;border-bottom:0;padding:3px;text-align:center;}' + - 'th{border-top:1px solid #BBB;background-color:#F7F7F7;}' + - 'table tr.firstRow th{border-top-width:2px;}' + - '.ue-table-interlace-color-single{ background-color: #fcfcfc; } .ue-table-interlace-color-double{ background-color: #f7faff; }' + - 'td p{margin:0;padding:0;}', me.document); - - var tableCopyList, isFullCol, isFullRow; - //注册del/backspace事件 - me.addListener('keydown', function (cmd, evt) { - var me = this; - var keyCode = evt.keyCode || evt.which; - - if (keyCode == 8) { - - var ut = getUETableBySelected(me); - if (ut && ut.selectedTds.length) { - - if (ut.isFullCol()) { - me.execCommand('deletecol') - } else if (ut.isFullRow()) { - me.execCommand('deleterow') - } else { - me.fireEvent('delcells'); - } - domUtils.preventDefault(evt); - } - - var caption = domUtils.findParentByTagName(me.selection.getStart(), 'caption', true), - range = me.selection.getRange(); - if (range.collapsed && caption && isEmptyBlock(caption)) { - me.fireEvent('saveScene'); - var table = caption.parentNode; - domUtils.remove(caption); - if (table) { - range.setStart(table.rows[0].cells[0], 0).setCursor(false, true); - } - me.fireEvent('saveScene'); - } - - } - - if (keyCode == 46) { - - ut = getUETableBySelected(me); - if (ut) { - me.fireEvent('saveScene'); - for (var i = 0, ci; ci = ut.selectedTds[i++];) { - domUtils.fillNode(me.document, ci) - } - me.fireEvent('saveScene'); - domUtils.preventDefault(evt); - - } - - } - if (keyCode == 13) { - - var rng = me.selection.getRange(), - caption = domUtils.findParentByTagName(rng.startContainer, 'caption', true); - if (caption) { - var table = domUtils.findParentByTagName(caption, 'table'); - if (!rng.collapsed) { - - rng.deleteContents(); - me.fireEvent('saveScene'); - } else { - if (caption) { - rng.setStart(table.rows[0].cells[0], 0).setCursor(false, true); - } - } - domUtils.preventDefault(evt); - return; - } - if (rng.collapsed) { - var table = domUtils.findParentByTagName(rng.startContainer, 'table'); - if (table) { - var cell = table.rows[0].cells[0], - start = domUtils.findParentByTagName(me.selection.getStart(), ['td', 'th'], true), - preNode = table.previousSibling; - if (cell === start && (!preNode || preNode.nodeType == 1 && preNode.tagName == 'TABLE' ) && domUtils.isStartInblock(rng)) { - var first = domUtils.findParent(me.selection.getStart(), function(n){return domUtils.isBlockElm(n)}, true); - if(first && ( /t(h|d)/i.test(first.tagName) || first === start.firstChild )){ - me.execCommand('insertparagraphbeforetable'); - domUtils.preventDefault(evt); - } - - } - } - } - } - - if ((evt.ctrlKey || evt.metaKey) && evt.keyCode == '67') { - tableCopyList = null; - var ut = getUETableBySelected(me); - if (ut) { - var tds = ut.selectedTds; - isFullCol = ut.isFullCol(); - isFullRow = ut.isFullRow(); - tableCopyList = [ - [ut.cloneCell(tds[0],null,true)] - ]; - for (var i = 1, ci; ci = tds[i]; i++) { - if (ci.parentNode !== tds[i - 1].parentNode) { - tableCopyList.push([ut.cloneCell(ci,null,true)]); - } else { - tableCopyList[tableCopyList.length - 1].push(ut.cloneCell(ci,null,true)); - } - - } - } - } - }); - me.addListener("tablehasdeleted",function(){ - toggleDraggableState(this, false, "", null); - if (dragButton)domUtils.remove(dragButton); - }); - - me.addListener('beforepaste', function (cmd, html) { - var me = this; - var rng = me.selection.getRange(); - if (domUtils.findParentByTagName(rng.startContainer, 'caption', true)) { - var div = me.document.createElement("div"); - div.innerHTML = html.html; - //trace:3729 - html.html = div[browser.ie9below ? 'innerText' : 'textContent']; - return; - } - var table = getUETableBySelected(me); - if (tableCopyList) { - me.fireEvent('saveScene'); - var rng = me.selection.getRange(); - var td = domUtils.findParentByTagName(rng.startContainer, ['td', 'th'], true), tmpNode, preNode; - if (td) { - var ut = getUETable(td); - if (isFullRow) { - var rowIndex = ut.getCellInfo(td).rowIndex; - if (td.tagName == 'TH') { - rowIndex++; - } - for (var i = 0, ci; ci = tableCopyList[i++];) { - var tr = ut.insertRow(rowIndex++, "td"); - for (var j = 0, cj; cj = ci[j]; j++) { - var cell = tr.cells[j]; - if (!cell) { - cell = tr.insertCell(j) - } - cell.innerHTML = cj.innerHTML; - cj.getAttribute('width') && cell.setAttribute('width', cj.getAttribute('width')); - cj.getAttribute('vAlign') && cell.setAttribute('vAlign', cj.getAttribute('vAlign')); - cj.getAttribute('align') && cell.setAttribute('align', cj.getAttribute('align')); - cj.style.cssText && (cell.style.cssText = cj.style.cssText) - } - for (var j = 0, cj; cj = tr.cells[j]; j++) { - if (!ci[j]) - break; - cj.innerHTML = ci[j].innerHTML; - ci[j].getAttribute('width') && cj.setAttribute('width', ci[j].getAttribute('width')); - ci[j].getAttribute('vAlign') && cj.setAttribute('vAlign', ci[j].getAttribute('vAlign')); - ci[j].getAttribute('align') && cj.setAttribute('align', ci[j].getAttribute('align')); - ci[j].style.cssText && (cj.style.cssText = ci[j].style.cssText) - } - } - } else { - if (isFullCol) { - cellInfo = ut.getCellInfo(td); - var maxColNum = 0; - for (var j = 0, ci = tableCopyList[0], cj; cj = ci[j++];) { - maxColNum += cj.colSpan || 1; - } - me.__hasEnterExecCommand = true; - for (i = 0; i < maxColNum; i++) { - me.execCommand('insertcol'); - } - me.__hasEnterExecCommand = false; - td = ut.table.rows[0].cells[cellInfo.cellIndex]; - if (td.tagName == 'TH') { - td = ut.table.rows[1].cells[cellInfo.cellIndex]; - } - } - for (var i = 0, ci; ci = tableCopyList[i++];) { - tmpNode = td; - for (var j = 0, cj; cj = ci[j++];) { - if (td) { - td.innerHTML = cj.innerHTML; - //todo 定制处理 - cj.getAttribute('width') && td.setAttribute('width', cj.getAttribute('width')); - cj.getAttribute('vAlign') && td.setAttribute('vAlign', cj.getAttribute('vAlign')); - cj.getAttribute('align') && td.setAttribute('align', cj.getAttribute('align')); - cj.style.cssText && (td.style.cssText = cj.style.cssText); - preNode = td; - td = td.nextSibling; - } else { - var cloneTd = cj.cloneNode(true); - domUtils.removeAttributes(cloneTd, ['class', 'rowSpan', 'colSpan']); - - preNode.parentNode.appendChild(cloneTd) - } - } - td = ut.getNextCell(tmpNode, true, true); - if (!tableCopyList[i]) - break; - if (!td) { - var cellInfo = ut.getCellInfo(tmpNode); - ut.table.insertRow(ut.table.rows.length); - ut.update(); - td = ut.getVSideCell(tmpNode, true); - } - } - } - ut.update(); - } else { - table = me.document.createElement('table'); - for (var i = 0, ci; ci = tableCopyList[i++];) { - var tr = table.insertRow(table.rows.length); - for (var j = 0, cj; cj = ci[j++];) { - cloneTd = UT.cloneCell(cj,null,true); - domUtils.removeAttributes(cloneTd, ['class']); - tr.appendChild(cloneTd) - } - if (j == 2 && cloneTd.rowSpan > 1) { - cloneTd.rowSpan = 1; - } - } - - var defaultValue = getDefaultValue(me), - width = me.body.offsetWidth - - (needIEHack ? parseInt(domUtils.getComputedStyle(me.body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (me.options.offsetWidth || 0); - me.execCommand('insertHTML', '' + table.innerHTML.replace(/>\s*<').replace(/\bth\b/gi, "td") + '
    ') - } - me.fireEvent('contentchange'); - me.fireEvent('saveScene'); - html.html = ''; - return true; - } else { - var div = me.document.createElement("div"), tables; - div.innerHTML = html.html; - tables = div.getElementsByTagName("table"); - if (domUtils.findParentByTagName(me.selection.getStart(), 'table')) { - utils.each(tables, function (t) { - domUtils.remove(t) - }); - if (domUtils.findParentByTagName(me.selection.getStart(), 'caption', true)) { - div.innerHTML = div[browser.ie ? 'innerText' : 'textContent']; - } - } else { - utils.each(tables, function (table) { - removeStyleSize(table, true); - domUtils.removeAttributes(table, ['style', 'border']); - utils.each(domUtils.getElementsByTagName(table, "td"), function (td) { - if (isEmptyBlock(td)) { - domUtils.fillNode(me.document, td); - } - removeStyleSize(td, true); -// domUtils.removeAttributes(td, ['style']) - }); - }); - } - html.html = div.innerHTML; - } - }); - - me.addListener('afterpaste', function () { - utils.each(domUtils.getElementsByTagName(me.body, "table"), function (table) { - if (table.offsetWidth > me.body.offsetWidth) { - var defaultValue = getDefaultValue(me, table); - table.style.width = me.body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(me.body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (me.options.offsetWidth || 0) + 'px' - } - }) - }); - me.addListener('blur', function () { - tableCopyList = null; - }); - var timer; - me.addListener('keydown', function () { - clearTimeout(timer); - timer = setTimeout(function () { - var rng = me.selection.getRange(), - cell = domUtils.findParentByTagName(rng.startContainer, ['th', 'td'], true); - if (cell) { - var table = cell.parentNode.parentNode.parentNode; - if (table.offsetWidth > table.getAttribute("width")) { - cell.style.wordBreak = "break-all"; - } - } - - }, 100); - }); - me.addListener("selectionchange", function () { - toggleDraggableState(me, false, "", null); - }); - - - //内容变化时触发索引更新 - //todo 可否考虑标记检测,如果不涉及表格的变化就不进行索引重建和更新 - me.addListener("contentchange", function () { - var me = this; - //尽可能排除一些不需要更新的状况 - hideDragLine(me); - if (getUETableBySelected(me))return; - var rng = me.selection.getRange(); - var start = rng.startContainer; - start = domUtils.findParentByTagName(start, ['td', 'th'], true); - utils.each(domUtils.getElementsByTagName(me.document, 'table'), function (table) { - if (me.fireEvent("excludetable", table) === true) return; - table.ueTable = new UT(table); - //trace:3742 -// utils.each(domUtils.getElementsByTagName(me.document, 'td'), function (td) { -// -// if (domUtils.isEmptyBlock(td) && td !== start) { -// domUtils.fillNode(me.document, td); -// if (browser.ie && browser.version == 6) { -// td.innerHTML = ' ' -// } -// } -// }); -// utils.each(domUtils.getElementsByTagName(me.document, 'th'), function (th) { -// if (domUtils.isEmptyBlock(th) && th !== start) { -// domUtils.fillNode(me.document, th); -// if (browser.ie && browser.version == 6) { -// th.innerHTML = ' ' -// } -// } -// }); - table.onmouseover = function () { - me.fireEvent('tablemouseover', table); - }; - table.onmousemove = function () { - me.fireEvent('tablemousemove', table); - me.options.tableDragable && toggleDragButton(true, this, me); - utils.defer(function(){ - me.fireEvent('contentchange',50) - },true) - }; - table.onmouseout = function () { - me.fireEvent('tablemouseout', table); - toggleDraggableState(me, false, "", null); - hideDragLine(me); - }; - table.onclick = function (evt) { - evt = me.window.event || evt; - var target = getParentTdOrTh(evt.target || evt.srcElement); - if (!target)return; - var ut = getUETable(target), - table = ut.table, - cellInfo = ut.getCellInfo(target), - cellsRange, - rng = me.selection.getRange(); -// if ("topLeft" == inPosition(table, mouseCoords(evt))) { -// cellsRange = ut.getCellsRange(ut.table.rows[0].cells[0], ut.getLastCell()); -// ut.setSelected(cellsRange); -// return; -// } -// if ("bottomRight" == inPosition(table, mouseCoords(evt))) { -// -// return; -// } - if (inTableSide(table, target, evt, true)) { - var endTdCol = ut.getCell(ut.indexTable[ut.rowsNum - 1][cellInfo.colIndex].rowIndex, ut.indexTable[ut.rowsNum - 1][cellInfo.colIndex].cellIndex); - if (evt.shiftKey && ut.selectedTds.length) { - if (ut.selectedTds[0] !== endTdCol) { - cellsRange = ut.getCellsRange(ut.selectedTds[0], endTdCol); - ut.setSelected(cellsRange); - } else { - rng && rng.selectNodeContents(endTdCol).select(); - } - } else { - if (target !== endTdCol) { - cellsRange = ut.getCellsRange(target, endTdCol); - ut.setSelected(cellsRange); - } else { - rng && rng.selectNodeContents(endTdCol).select(); - } - } - return; - } - if (inTableSide(table, target, evt)) { - var endTdRow = ut.getCell(ut.indexTable[cellInfo.rowIndex][ut.colsNum - 1].rowIndex, ut.indexTable[cellInfo.rowIndex][ut.colsNum - 1].cellIndex); - if (evt.shiftKey && ut.selectedTds.length) { - if (ut.selectedTds[0] !== endTdRow) { - cellsRange = ut.getCellsRange(ut.selectedTds[0], endTdRow); - ut.setSelected(cellsRange); - } else { - rng && rng.selectNodeContents(endTdRow).select(); - } - } else { - if (target !== endTdRow) { - cellsRange = ut.getCellsRange(target, endTdRow); - ut.setSelected(cellsRange); - } else { - rng && rng.selectNodeContents(endTdRow).select(); - } - } - } - }; - }); - - switchBorderColor(me, true); - }); - - domUtils.on(me.document, "mousemove", mouseMoveEvent); - - domUtils.on(me.document, "mouseout", function (evt) { - var target = evt.target || evt.srcElement; - if (target.tagName == "TABLE") { - toggleDraggableState(me, false, "", null); - } - }); - /** - * 表格隔行变色 - */ - me.addListener("interlacetable",function(type,table,classList){ - if(!table) return; - var me = this, - rows = table.rows, - len = rows.length, - getClass = function(list,index,repeat){ - return list[index] ? list[index] : repeat ? list[index % list.length]: ""; - }; - for(var i = 0;i 1 ? currentRowIndex : ua.getCellInfo(cell).rowIndex; - var nextCell = ua.getTabNextCell(cell, currentRowIndex); - if (nextCell) { - if (isEmptyBlock(nextCell)) { - range.setStart(nextCell, 0).setCursor(false, true) - } else { - range.selectNodeContents(nextCell).select() - } - } else { - me.fireEvent('saveScene'); - me.__hasEnterExecCommand = true; - this.execCommand('insertrownext'); - me.__hasEnterExecCommand = false; - range = this.selection.getRange(); - range.setStart(table.rows[table.rows.length - 1].cells[0], 0).setCursor(); - me.fireEvent('saveScene'); - } - } - return true; - } - - }); - browser.ie && me.addListener('selectionchange', function () { - toggleDraggableState(this, false, "", null); - }); - me.addListener("keydown", function (type, evt) { - var me = this; - //处理在表格的最后一个输入tab产生新的表格 - var keyCode = evt.keyCode || evt.which; - if (keyCode == 8 || keyCode == 46) { - return; - } - var notCtrlKey = !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey; - notCtrlKey && removeSelectedClass(domUtils.getElementsByTagName(me.body, "td")); - var ut = getUETableBySelected(me); - if (!ut) return; - notCtrlKey && ut.clearSelected(); - }); - - me.addListener("beforegetcontent", function () { - switchBorderColor(this, false); - browser.ie && utils.each(this.document.getElementsByTagName('caption'), function (ci) { - if (domUtils.isEmptyNode(ci)) { - ci.innerHTML = ' ' - } - }); - }); - me.addListener("aftergetcontent", function () { - switchBorderColor(this, true); - }); - me.addListener("getAllHtml", function () { - removeSelectedClass(me.document.getElementsByTagName("td")); - }); - //修正全屏状态下插入的表格宽度在非全屏状态下撑开编辑器的情况 - me.addListener("fullscreenchanged", function (type, fullscreen) { - if (!fullscreen) { - var ratio = this.body.offsetWidth / document.body.offsetWidth, - tables = domUtils.getElementsByTagName(this.body, "table"); - utils.each(tables, function (table) { - if (table.offsetWidth < me.body.offsetWidth) return false; - var tds = domUtils.getElementsByTagName(table, "td"), - backWidths = []; - utils.each(tds, function (td) { - backWidths.push(td.offsetWidth); - }); - for (var i = 0, td; td = tds[i]; i++) { - td.setAttribute("width", Math.floor(backWidths[i] * ratio)); - } - table.setAttribute("width", Math.floor(getTableWidth(me, needIEHack, getDefaultValue(me)))) - }); - } - }); - - //重写execCommand命令,用于处理框选时的处理 - var oldExecCommand = me.execCommand; - me.execCommand = function (cmd, datatat) { - - var me = this, - args = arguments; - - cmd = cmd.toLowerCase(); - var ut = getUETableBySelected(me), tds, - range = new dom.Range(me.document), - cmdFun = me.commands[cmd] || UE.commands[cmd], - result; - if (!cmdFun) return; - if (ut && !commands[cmd] && !cmdFun.notNeedUndo && !me.__hasEnterExecCommand) { - me.__hasEnterExecCommand = true; - me.fireEvent("beforeexeccommand", cmd); - tds = ut.selectedTds; - var lastState = -2, lastValue = -2, value, state; - for (var i = 0, td; td = tds[i]; i++) { - if (isEmptyBlock(td)) { - range.setStart(td, 0).setCursor(false, true) - } else { - range.selectNode(td).select(true); - } - state = me.queryCommandState(cmd); - value = me.queryCommandValue(cmd); - if (state != -1) { - if (lastState !== state || lastValue !== value) { - me._ignoreContentChange = true; - result = oldExecCommand.apply(me, arguments); - me._ignoreContentChange = false; - - } - lastState = me.queryCommandState(cmd); - lastValue = me.queryCommandValue(cmd); - if (domUtils.isEmptyBlock(td)) { - domUtils.fillNode(me.document, td) - } - } - } - range.setStart(tds[0], 0).shrinkBoundary(true).setCursor(false, true); - me.fireEvent('contentchange'); - me.fireEvent("afterexeccommand", cmd); - me.__hasEnterExecCommand = false; - me._selectionChange(); - } else { - result = oldExecCommand.apply(me, arguments); - } - return result; - }; - - - }); - /** - * 删除obj的宽高style,改成属性宽高 - * @param obj - * @param replaceToProperty - */ - function removeStyleSize(obj, replaceToProperty) { - removeStyle(obj, "width", true); - removeStyle(obj, "height", true); - } - - function removeStyle(obj, styleName, replaceToProperty) { - if (obj.style[styleName]) { - replaceToProperty && obj.setAttribute(styleName, parseInt(obj.style[styleName], 10)); - obj.style[styleName] = ""; - } - } - - function getParentTdOrTh(ele) { - if (ele.tagName == "TD" || ele.tagName == "TH") return ele; - var td; - if (td = domUtils.findParentByTagName(ele, "td", true) || domUtils.findParentByTagName(ele, "th", true)) return td; - return null; - } - - function isEmptyBlock(node) { - var reg = new RegExp(domUtils.fillChar, 'g'); - if (node[browser.ie ? 'innerText' : 'textContent'].replace(/^\s*$/, '').replace(reg, '').length > 0) { - return 0; - } - for (var n in dtd.$isNotEmpty) { - if (node.getElementsByTagName(n).length) { - return 0; - } - } - return 1; - } - - - function mouseCoords(evt) { - if (evt.pageX || evt.pageY) { - return { x:evt.pageX, y:evt.pageY }; - } - return { - x:evt.clientX + me.document.body.scrollLeft - me.document.body.clientLeft, - y:evt.clientY + me.document.body.scrollTop - me.document.body.clientTop - }; - } - - function mouseMoveEvent(evt) { - - if( isEditorDisabled() ) { - return; - } - - try { - - //普通状态下鼠标移动 - var target = getParentTdOrTh(evt.target || evt.srcElement), - pos; - - //区分用户的行为是拖动还是双击 - if( isInResizeBuffer ) { - - me.body.style.webkitUserSelect = 'none'; - - if( Math.abs( userActionStatus.x - evt.clientX ) > offsetOfTableCell || Math.abs( userActionStatus.y - evt.clientY ) > offsetOfTableCell ) { - clearTableDragTimer(); - isInResizeBuffer = false; - singleClickState = 0; - //drag action - tableBorderDrag(evt); - } - } - - //修改单元格大小时的鼠标移动 - if (onDrag && dragTd) { - singleClickState = 0; - me.body.style.webkitUserSelect = 'none'; - me.selection.getNative()[browser.ie9below ? 'empty' : 'removeAllRanges'](); - pos = mouseCoords(evt); - toggleDraggableState(me, true, onDrag, pos, target); - if (onDrag == "h") { - dragLine.style.left = getPermissionX(dragTd, evt) + "px"; - } else if (onDrag == "v") { - dragLine.style.top = getPermissionY(dragTd, evt) + "px"; - } - return; - } - //当鼠标处于table上时,修改移动过程中的光标状态 - if (target) { - //针对使用table作为容器的组件不触发拖拽效果 - if (me.fireEvent('excludetable', target) === true) - return; - pos = mouseCoords(evt); - var state = getRelation(target, pos), - table = domUtils.findParentByTagName(target, "table", true); - - if (inTableSide(table, target, evt, true)) { - if (me.fireEvent("excludetable", table) === true) return; - me.body.style.cursor = "url(" + me.options.cursorpath + "h.png),pointer"; - } else if (inTableSide(table, target, evt)) { - if (me.fireEvent("excludetable", table) === true) return; - me.body.style.cursor = "url(" + me.options.cursorpath + "v.png),pointer"; - } else { - me.body.style.cursor = "text"; - var curCell = target; - if (/\d/.test(state)) { - state = state.replace(/\d/, ''); - target = getUETable(target).getPreviewCell(target, state == "v"); - } - //位于第一行的顶部或者第一列的左边时不可拖动 - toggleDraggableState(me, target ? !!state : false, target ? state : '', pos, target); - - } - } else { - toggleDragButton(false, table, me); - } - - } catch (e) { - showError(e); - } - } - - var dragButtonTimer; - - function toggleDragButton(show, table, editor) { - if (!show) { - if (dragOver)return; - dragButtonTimer = setTimeout(function () { - !dragOver && dragButton && dragButton.parentNode && dragButton.parentNode.removeChild(dragButton); - }, 2000); - } else { - createDragButton(table, editor); - } - } - - function createDragButton(table, editor) { - var pos = domUtils.getXY(table), - doc = table.ownerDocument; - if (dragButton && dragButton.parentNode)return dragButton; - dragButton = doc.createElement("div"); - dragButton.contentEditable = false; - dragButton.innerHTML = ""; - dragButton.style.cssText = "width:15px;height:15px;background-image:url(" + editor.options.UEDITOR_HOME_URL + "dialogs/table/dragicon.png);position: absolute;cursor:move;top:" + (pos.y - 15) + "px;left:" + (pos.x) + "px;"; - domUtils.unSelectable(dragButton); - dragButton.onmouseover = function (evt) { - dragOver = true; - }; - dragButton.onmouseout = function (evt) { - dragOver = false; - }; - domUtils.on(dragButton, 'click', function (type, evt) { - doClick(evt, this); - }); - domUtils.on(dragButton, 'dblclick', function (type, evt) { - doDblClick(evt); - }); - domUtils.on(dragButton, 'dragstart', function (type, evt) { - domUtils.preventDefault(evt); - }); - var timer; - - function doClick(evt, button) { - // 部分浏览器下需要清理 - clearTimeout(timer); - timer = setTimeout(function () { - editor.fireEvent("tableClicked", table, button); - }, 300); - } - - function doDblClick(evt) { - clearTimeout(timer); - var ut = getUETable(table), - start = table.rows[0].cells[0], - end = ut.getLastCell(), - range = ut.getCellsRange(start, end); - editor.selection.getRange().setStart(start, 0).setCursor(false, true); - ut.setSelected(range); - } - - doc.body.appendChild(dragButton); - } - - -// function inPosition(table, pos) { -// var tablePos = domUtils.getXY(table), -// width = table.offsetWidth, -// height = table.offsetHeight; -// if (pos.x - tablePos.x < 5 && pos.y - tablePos.y < 5) { -// return "topLeft"; -// } else if (tablePos.x + width - pos.x < 5 && tablePos.y + height - pos.y < 5) { -// return "bottomRight"; -// } -// } - - function inTableSide(table, cell, evt, top) { - var pos = mouseCoords(evt), - state = getRelation(cell, pos); - - if (top) { - var caption = table.getElementsByTagName("caption")[0], - capHeight = caption ? caption.offsetHeight : 0; - return (state == "v1") && ((pos.y - domUtils.getXY(table).y - capHeight) < 8); - } else { - return (state == "h1") && ((pos.x - domUtils.getXY(table).x) < 8); - } - } - - /** - * 获取拖动时允许的X轴坐标 - * @param dragTd - * @param evt - */ - function getPermissionX(dragTd, evt) { - var ut = getUETable(dragTd); - if (ut) { - var preTd = ut.getSameEndPosCells(dragTd, "x")[0], - nextTd = ut.getSameStartPosXCells(dragTd)[0], - mouseX = mouseCoords(evt).x, - left = (preTd ? domUtils.getXY(preTd).x : domUtils.getXY(ut.table).x) + 20 , - right = nextTd ? domUtils.getXY(nextTd).x + nextTd.offsetWidth - 20 : (me.body.offsetWidth + 5 || parseInt(domUtils.getComputedStyle(me.body, "width"), 10)); - - left += cellMinWidth; - right -= cellMinWidth; - - return mouseX < left ? left : mouseX > right ? right : mouseX; - } - } - - /** - * 获取拖动时允许的Y轴坐标 - */ - function getPermissionY(dragTd, evt) { - try { - var top = domUtils.getXY(dragTd).y, - mousePosY = mouseCoords(evt).y; - return mousePosY < top ? top : mousePosY; - } catch (e) { - showError(e); - } - } - - /** - * 移动状态切换 - */ - function toggleDraggableState(editor, draggable, dir, mousePos, cell) { - try { - editor.body.style.cursor = dir == "h" ? "col-resize" : dir == "v" ? "row-resize" : "text"; - if (browser.ie) { - if (dir && !mousedown && !getUETableBySelected(editor)) { - getDragLine(editor, editor.document); - showDragLineAt(dir, cell); - } else { - hideDragLine(editor) - } - } - onBorder = draggable; - } catch (e) { - showError(e); - } - } - - /** - * 获取与UETable相关的resize line - * @param uetable UETable对象 - */ - function getResizeLineByUETable() { - - var lineId = '_UETableResizeLine', - line = this.document.getElementById( lineId ); - - if( !line ) { - line = this.document.createElement("div"); - line.id = lineId; - line.contnetEditable = false; - line.setAttribute("unselectable", "on"); - - var styles = { - width: 2*cellBorderWidth + 1 + 'px', - position: 'absolute', - 'z-index': 100000, - cursor: 'col-resize', - background: 'red', - display: 'none' - }; - - //切换状态 - line.onmouseout = function(){ - this.style.display = 'none'; - }; - - utils.extend( line.style, styles ); - - this.document.body.appendChild( line ); - - } - - return line; - - } - - /** - * 更新resize-line - */ - function updateResizeLine( cell, uetable ) { - - var line = getResizeLineByUETable.call( this ), - table = uetable.table, - styles = { - top: domUtils.getXY( table ).y + 'px', - left: domUtils.getXY( cell).x + cell.offsetWidth - cellBorderWidth + 'px', - display: 'block', - height: table.offsetHeight + 'px' - }; - - utils.extend( line.style, styles ); - - } - - /** - * 显示resize-line - */ - function showResizeLine( cell ) { - - var uetable = getUETable( cell ); - - updateResizeLine.call( this, cell, uetable ); - - } - - /** - * 获取鼠标与当前单元格的相对位置 - * @param ele - * @param mousePos - */ - function getRelation(ele, mousePos) { - var elePos = domUtils.getXY(ele); - - if( !elePos ) { - return ''; - } - - if (elePos.x + ele.offsetWidth - mousePos.x < cellBorderWidth) { - return "h"; - } - if (mousePos.x - elePos.x < cellBorderWidth) { - return 'h1' - } - if (elePos.y + ele.offsetHeight - mousePos.y < cellBorderWidth) { - return "v"; - } - if (mousePos.y - elePos.y < cellBorderWidth) { - return 'v1' - } - return ''; - } - - function mouseDownEvent(type, evt) { - - if( isEditorDisabled() ) { - return ; - } - - userActionStatus = { - x: evt.clientX, - y: evt.clientY - }; - - //右键菜单单独处理 - if (evt.button == 2) { - var ut = getUETableBySelected(me), - flag = false; - - if (ut) { - var td = getTargetTd(me, evt); - utils.each(ut.selectedTds, function (ti) { - if (ti === td) { - flag = true; - } - }); - if (!flag) { - removeSelectedClass(domUtils.getElementsByTagName(me.body, "th td")); - ut.clearSelected() - } else { - td = ut.selectedTds[0]; - setTimeout(function () { - me.selection.getRange().setStart(td, 0).setCursor(false, true); - }, 0); - - } - } - } else { - tableClickHander( evt ); - } - - } - - //清除表格的计时器 - function clearTableTimer() { - tabTimer && clearTimeout( tabTimer ); - tabTimer = null; - } - - //双击收缩 - function tableDbclickHandler(evt) { - singleClickState = 0; - evt = evt || me.window.event; - var target = getParentTdOrTh(evt.target || evt.srcElement); - if (target) { - var h; - if (h = getRelation(target, mouseCoords(evt))) { - - hideDragLine( me ); - - if (h == 'h1') { - h = 'h'; - if (inTableSide(domUtils.findParentByTagName(target, "table"), target, evt)) { - me.execCommand('adaptbywindow'); - } else { - target = getUETable(target).getPreviewCell(target); - if (target) { - var rng = me.selection.getRange(); - rng.selectNodeContents(target).setCursor(true, true) - } - } - } - if (h == 'h') { - var ut = getUETable(target), - table = ut.table, - cells = getCellsByMoveBorder( target, table, true ); - - cells = extractArray( cells, 'left' ); - - ut.width = ut.offsetWidth; - - var oldWidth = [], - newWidth = []; - - utils.each( cells, function( cell ){ - - oldWidth.push( cell.offsetWidth ); - - } ); - - utils.each( cells, function( cell ){ - - cell.removeAttribute("width"); - - } ); - - window.setTimeout( function(){ - - //是否允许改变 - var changeable = true; - - utils.each( cells, function( cell, index ){ - - var width = cell.offsetWidth; - - if( width > oldWidth[index] ) { - changeable = false; - return false; - } - - newWidth.push( width ); - - } ); - - var change = changeable ? newWidth : oldWidth; - - utils.each( cells, function( cell, index ){ - - cell.width = change[index] - getTabcellSpace(); - - } ); - - - }, 0 ); - -// minWidth -= cellMinWidth; -// -// table.removeAttribute("width"); -// utils.each(cells, function (cell) { -// cell.style.width = ""; -// cell.width -= minWidth; -// }); - - } - } - } - } - - function tableClickHander( evt ) { - - removeSelectedClass(domUtils.getElementsByTagName(me.body, "td th")); - //trace:3113 - //选中单元格,点击table外部,不会清掉table上挂的ueTable,会引起getUETableBySelected方法返回值 - utils.each(me.document.getElementsByTagName('table'), function (t) { - t.ueTable = null; - }); - startTd = getTargetTd(me, evt); - if( !startTd ) return; - var table = domUtils.findParentByTagName(startTd, "table", true); - ut = getUETable(table); - ut && ut.clearSelected(); - - //判断当前鼠标状态 - if (!onBorder) { - me.document.body.style.webkitUserSelect = ''; - mousedown = true; - me.addListener('mouseover', mouseOverEvent); - } else { - //边框上的动作处理 - borderActionHandler( evt ); - } - - - } - - //处理表格边框上的动作, 这里做延时处理,避免两种动作互相影响 - function borderActionHandler( evt ) { - - if ( browser.ie ) { - evt = reconstruct(evt ); - } - - clearTableDragTimer(); - - //是否正在等待resize的缓冲中 - isInResizeBuffer = true; - - tableDragTimer = setTimeout(function(){ - tableBorderDrag( evt ); - }, dblclickTime); - - } - - function extractArray( originArr, key ) { - - var result = [], - tmp = null; - - for( var i = 0, len = originArr.length; i 0 && singleClickState--; - }, dblclickTime ); - - if( singleClickState === 2 ) { - - singleClickState = 0; - tableDbclickHandler(evt); - return; - - } - - } - - if (evt.button == 2)return; - var me = this; - //清除表格上原生跨选问题 - var range = me.selection.getRange(), - start = domUtils.findParentByTagName(range.startContainer, 'table', true), - end = domUtils.findParentByTagName(range.endContainer, 'table', true); - - if (start || end) { - if (start === end) { - start = domUtils.findParentByTagName(range.startContainer, ['td', 'th', 'caption'], true); - end = domUtils.findParentByTagName(range.endContainer, ['td', 'th', 'caption'], true); - if (start !== end) { - me.selection.clearRange() - } - } else { - me.selection.clearRange() - } - } - mousedown = false; - me.document.body.style.webkitUserSelect = ''; - //拖拽状态下的mouseUP - if ( onDrag && dragTd ) { - - me.selection.getNative()[browser.ie9below ? 'empty' : 'removeAllRanges'](); - - singleClickState = 0; - dragLine = me.document.getElementById('ue_tableDragLine'); - - // trace 3973 - if (dragLine) { - var dragTdPos = domUtils.getXY(dragTd), - dragLinePos = domUtils.getXY(dragLine); - - switch (onDrag) { - case "h": - changeColWidth(dragTd, dragLinePos.x - dragTdPos.x); - break; - case "v": - changeRowHeight(dragTd, dragLinePos.y - dragTdPos.y - dragTd.offsetHeight); - break; - default: - } - onDrag = ""; - dragTd = null; - - hideDragLine(me); - me.fireEvent('saveScene'); - return; - } - } - //正常状态下的mouseup - if (!startTd) { - var target = domUtils.findParentByTagName(evt.target || evt.srcElement, "td", true); - if (!target) target = domUtils.findParentByTagName(evt.target || evt.srcElement, "th", true); - if (target && (target.tagName == "TD" || target.tagName == "TH")) { - if (me.fireEvent("excludetable", target) === true) return; - range = new dom.Range(me.document); - range.setStart(target, 0).setCursor(false, true); - } - } else { - var ut = getUETable(startTd), - cell = ut ? ut.selectedTds[0] : null; - if (cell) { - range = new dom.Range(me.document); - if (domUtils.isEmptyBlock(cell)) { - range.setStart(cell, 0).setCursor(false, true); - } else { - range.selectNodeContents(cell).shrinkBoundary().setCursor(false, true); - } - } else { - range = me.selection.getRange().shrinkBoundary(); - if (!range.collapsed) { - var start = domUtils.findParentByTagName(range.startContainer, ['td', 'th'], true), - end = domUtils.findParentByTagName(range.endContainer, ['td', 'th'], true); - //在table里边的不能清除 - if (start && !end || !start && end || start && end && start !== end) { - range.setCursor(false, true); - } - } - } - startTd = null; - me.removeListener('mouseover', mouseOverEvent); - } - me._selectionChange(250, evt); - } - - function mouseOverEvent(type, evt) { - - if( isEditorDisabled() ) { - return; - } - - var me = this, - tar = evt.target || evt.srcElement; - currentTd = domUtils.findParentByTagName(tar, "td", true) || domUtils.findParentByTagName(tar, "th", true); - //需要判断两个TD是否位于同一个表格内 - if (startTd && currentTd && - ((startTd.tagName == "TD" && currentTd.tagName == "TD") || (startTd.tagName == "TH" && currentTd.tagName == "TH")) && - domUtils.findParentByTagName(startTd, 'table') == domUtils.findParentByTagName(currentTd, 'table')) { - var ut = getUETable(currentTd); - if (startTd != currentTd) { - me.document.body.style.webkitUserSelect = 'none'; - me.selection.getNative()[browser.ie9below ? 'empty' : 'removeAllRanges'](); - var range = ut.getCellsRange(startTd, currentTd); - ut.setSelected(range); - } else { - me.document.body.style.webkitUserSelect = ''; - ut.clearSelected(); - } - - } - evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false); - } - - function setCellHeight(cell, height, backHeight) { - var lineHight = parseInt(domUtils.getComputedStyle(cell, "line-height"), 10), - tmpHeight = backHeight + height; - height = tmpHeight < lineHight ? lineHight : tmpHeight; - if (cell.style.height) cell.style.height = ""; - cell.rowSpan == 1 ? cell.setAttribute("height", height) : (cell.removeAttribute && cell.removeAttribute("height")); - } - - function getWidth(cell) { - if (!cell)return 0; - return parseInt(domUtils.getComputedStyle(cell, "width"), 10); - } - - function changeColWidth(cell, changeValue) { - - var ut = getUETable(cell); - if (ut) { - - //根据当前移动的边框获取相关的单元格 - var table = ut.table, - cells = getCellsByMoveBorder( cell, table ); - - table.style.width = ""; - table.removeAttribute("width"); - - //修正改变量 - changeValue = correctChangeValue( changeValue, cell, cells ); - - if (cell.nextSibling) { - - var i=0; - - utils.each( cells, function( cellGroup ){ - - cellGroup.left.width = (+cellGroup.left.width)+changeValue; - cellGroup.right && ( cellGroup.right.width = (+cellGroup.right.width)-changeValue ); - - } ); - - } else { - - utils.each( cells, function( cellGroup ){ - cellGroup.left.width -= -changeValue; - } ); - - } - } - - } - - function isEditorDisabled() { - return me.body.contentEditable === "false"; - } - - function changeRowHeight(td, changeValue) { - if (Math.abs(changeValue) < 10) return; - var ut = getUETable(td); - if (ut) { - var cells = ut.getSameEndPosCells(td, "y"), - //备份需要连带变化的td的原始高度,否则后期无法获取正确的值 - backHeight = cells[0] ? cells[0].offsetHeight : 0; - for (var i = 0, cell; cell = cells[i++];) { - setCellHeight(cell, changeValue, backHeight); - } - } - - } - - /** - * 获取调整单元格大小的相关单元格 - * @isContainMergeCell 返回的结果中是否包含发生合并后的单元格 - */ - function getCellsByMoveBorder( cell, table, isContainMergeCell ) { - - if( !table ) { - table = domUtils.findParentByTagName( cell, 'table' ); - } - - if( !table ) { - return null; - } - - //获取到该单元格所在行的序列号 - var index = domUtils.getNodeIndex( cell ), - temp = cell, - rows = table.rows, - colIndex = 0; - - while( temp ) { - //获取到当前单元格在未发生单元格合并时的序列 - if( temp.nodeType === 1 ) { - colIndex += (temp.colSpan || 1); - } - temp = temp.previousSibling; - } - - temp = null; - - //记录想关的单元格 - var borderCells = []; - - utils.each(rows, function( tabRow ){ - - var cells = tabRow.cells, - currIndex = 0; - - utils.each( cells, function( tabCell ){ - - currIndex += (tabCell.colSpan || 1); - - if( currIndex === colIndex ) { - - borderCells.push({ - left: tabCell, - right: tabCell.nextSibling || null - }); - - return false; - - } else if( currIndex > colIndex ) { - - if( isContainMergeCell ) { - borderCells.push({ - left: tabCell - }); - } - - return false; - } - - - } ); - - }); - - return borderCells; - - } - - - /** - * 通过给定的单元格集合获取最小的单元格width - */ - function getMinWidthByTableCells( cells ) { - - var minWidth = Number.MAX_VALUE; - - for( var i = 0, curCell; curCell = cells[ i ] ; i++ ) { - - minWidth = Math.min( minWidth, curCell.width || getTableCellWidth( curCell ) ); - - } - - return minWidth; - - } - - function correctChangeValue( changeValue, relatedCell, cells ) { - - //为单元格的paading预留空间 - changeValue -= getTabcellSpace(); - - if( changeValue < 0 ) { - return 0; - } - - changeValue -= getTableCellWidth( relatedCell ); - - //确定方向 - var direction = changeValue < 0 ? 'left':'right'; - - changeValue = Math.abs(changeValue); - - //只关心非最后一个单元格就可以 - utils.each( cells, function( cellGroup ){ - - var curCell = cellGroup[direction]; - - //为单元格保留最小空间 - if( curCell ) { - changeValue = Math.min( changeValue, getTableCellWidth( curCell )-cellMinWidth ); - } - - - } ); - - - //修正越界 - changeValue = changeValue < 0 ? 0 : changeValue; - - return direction === 'left' ? -changeValue : changeValue; - - } - - function getTableCellWidth( cell ) { - - var width = 0, - //偏移纠正量 - offset = 0, - width = cell.offsetWidth - getTabcellSpace(); - - //最后一个节点纠正一下 - if( !cell.nextSibling ) { - - width -= getTableCellOffset( cell ); - - } - - width = width < 0 ? 0 : width; - - try { - cell.width = width; - } catch(e) { - } - - return width; - - } - - /** - * 获取单元格所在表格的最末单元格的偏移量 - */ - function getTableCellOffset( cell ) { - - tab = domUtils.findParentByTagName( cell, "table", false); - - if( tab.offsetVal === undefined ) { - - var prev = cell.previousSibling; - - if( prev ) { - - //最后一个单元格和前一个单元格的width diff结果 如果恰好为一个border width, 则条件成立 - tab.offsetVal = cell.offsetWidth - prev.offsetWidth === UT.borderWidth ? UT.borderWidth : 0; - - } else { - tab.offsetVal = 0; - } - - } - - return tab.offsetVal; - - } - - function getTabcellSpace() { - - if( UT.tabcellSpace === undefined ) { - - var cell = null, - tab = me.document.createElement("table"), - tbody = me.document.createElement("tbody"), - trow = me.document.createElement("tr"), - tabcell = me.document.createElement("td"), - mirror = null; - - tabcell.style.cssText = 'border: 0;'; - tabcell.width = 1; - - trow.appendChild( tabcell ); - trow.appendChild( mirror = tabcell.cloneNode( false ) ); - - tbody.appendChild( trow ); - - tab.appendChild( tbody ); - - tab.style.cssText = "visibility: hidden;"; - - me.body.appendChild( tab ); - - UT.paddingSpace = tabcell.offsetWidth - 1; - - var tmpTabWidth = tab.offsetWidth; - - tabcell.style.cssText = ''; - mirror.style.cssText = ''; - - UT.borderWidth = ( tab.offsetWidth - tmpTabWidth ) / 3; - - UT.tabcellSpace = UT.paddingSpace + UT.borderWidth; - - me.body.removeChild( tab ); - - } - - getTabcellSpace = function(){ return UT.tabcellSpace; }; - - return UT.tabcellSpace; - - } - - function getDragLine(editor, doc) { - if (mousedown)return; - dragLine = editor.document.createElement("div"); - domUtils.setAttributes(dragLine, { - id:"ue_tableDragLine", - unselectable:'on', - contenteditable:false, - 'onresizestart':'return false', - 'ondragstart':'return false', - 'onselectstart':'return false', - style:"background-color:blue;position:absolute;padding:0;margin:0;background-image:none;border:0px none;opacity:0;filter:alpha(opacity=0)" - }); - editor.body.appendChild(dragLine); - } - - function hideDragLine(editor) { - if (mousedown)return; - var line; - while (line = editor.document.getElementById('ue_tableDragLine')) { - domUtils.remove(line) - } - } - - /** - * 依据state(v|h)在cell位置显示横线 - * @param state - * @param cell - */ - function showDragLineAt(state, cell) { - if (!cell) return; - var table = domUtils.findParentByTagName(cell, "table"), - caption = table.getElementsByTagName('caption'), - width = table.offsetWidth, - height = table.offsetHeight - (caption.length > 0 ? caption[0].offsetHeight : 0), - tablePos = domUtils.getXY(table), - cellPos = domUtils.getXY(cell), css; - switch (state) { - case "h": - css = 'height:' + height + 'px;top:' + (tablePos.y + (caption.length > 0 ? caption[0].offsetHeight : 0)) + 'px;left:' + (cellPos.x + cell.offsetWidth); - dragLine.style.cssText = css + 'px;position: absolute;display:block;background-color:blue;width:1px;border:0; color:blue;opacity:.3;filter:alpha(opacity=30)'; - break; - case "v": - css = 'width:' + width + 'px;left:' + tablePos.x + 'px;top:' + (cellPos.y + cell.offsetHeight ); - //必须加上border:0和color:blue,否则低版ie不支持背景色显示 - dragLine.style.cssText = css + 'px;overflow:hidden;position: absolute;display:block;background-color:blue;height:1px;border:0;color:blue;opacity:.2;filter:alpha(opacity=20)'; - break; - default: - } - } - - /** - * 当表格边框颜色为白色时设置为虚线,true为添加虚线 - * @param editor - * @param flag - */ - function switchBorderColor(editor, flag) { - var tableArr = domUtils.getElementsByTagName(editor.body, "table"), color; - for (var i = 0, node; node = tableArr[i++];) { - var td = domUtils.getElementsByTagName(node, "td"); - if (td[0]) { - if (flag) { - color = (td[0].style.borderColor).replace(/\s/g, ""); - if (/(#ffffff)|(rgb\(255,255,255\))/ig.test(color)) - domUtils.addClass(node, "noBorderTable") - } else { - domUtils.removeClasses(node, "noBorderTable") - } - } - - } - } - - function getTableWidth(editor, needIEHack, defaultValue) { - var body = editor.body; - return body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (editor.options.offsetWidth || 0); - } - - /** - * 获取当前拖动的单元格 - */ - function getTargetTd(editor, evt) { - - var target = domUtils.findParentByTagName(evt.target || evt.srcElement, ["td", "th"], true), - dir = null; - - if( !target ) { - return null; - } - - dir = getRelation( target, mouseCoords( evt ) ); - - //如果有前一个节点, 需要做一个修正, 否则可能会得到一个错误的td - - if( !target ) { - return null; - } - - if( dir === 'h1' && target.previousSibling ) { - - var position = domUtils.getXY( target), - cellWidth = target.offsetWidth; - - if( Math.abs( position.x + cellWidth - evt.clientX ) > cellWidth / 3 ) { - target = target.previousSibling; - } - - } else if( dir === 'v1' && target.parentNode.previousSibling ) { - - var position = domUtils.getXY( target), - cellHeight = target.offsetHeight; - - if( Math.abs( position.y + cellHeight - evt.clientY ) > cellHeight / 3 ) { - target = target.parentNode.previousSibling.firstChild; - } - - } - - - //排除了非td内部以及用于代码高亮部分的td - return target && !(editor.fireEvent("excludetable", target) === true) ? target : null; - } - -}; - - -// plugins/table.sort.js -/** - * Created with JetBrains PhpStorm. - * User: Jinqn - * Date: 13-10-12 - * Time: 上午10:20 - * To change this template use File | Settings | File Templates. - */ - -UE.UETable.prototype.sortTable = function (sortByCellIndex, compareFn) { - var table = this.table, - rows = table.rows, - trArray = [], - flag = rows[0].cells[0].tagName === "TH", - lastRowIndex = 0; - if(this.selectedTds.length){ - var range = this.cellsRange, - len = range.endRowIndex + 1; - for (var i = range.beginRowIndex; i < len; i++) { - trArray[i] = rows[i]; - } - trArray.splice(0,range.beginRowIndex); - lastRowIndex = (range.endRowIndex +1) === this.rowsNum ? 0 : range.endRowIndex +1; - }else{ - for (var i = 0,len = rows.length; i < len; i++) { - trArray[i] = rows[i]; - } - } - - var Fn = { - 'reversecurrent': function(td1,td2){ - return 1; - }, - 'orderbyasc': function(td1,td2){ - var value1 = td1.innerText||td1.textContent, - value2 = td2.innerText||td2.textContent; - return value1.localeCompare(value2); - }, - 'reversebyasc': function(td1,td2){ - var value1 = td1.innerHTML, - value2 = td2.innerHTML; - return value2.localeCompare(value1); - }, - 'orderbynum': function(td1,td2){ - var value1 = td1[browser.ie ? 'innerText':'textContent'].match(/\d+/), - value2 = td2[browser.ie ? 'innerText':'textContent'].match(/\d+/); - if(value1) value1 = +value1[0]; - if(value2) value2 = +value2[0]; - return (value1||0) - (value2||0); - }, - 'reversebynum': function(td1,td2){ - var value1 = td1[browser.ie ? 'innerText':'textContent'].match(/\d+/), - value2 = td2[browser.ie ? 'innerText':'textContent'].match(/\d+/); - if(value1) value1 = +value1[0]; - if(value2) value2 = +value2[0]; - return (value2||0) - (value1||0); - } - }; - - //对表格设置排序的标记data-sort-type - table.setAttribute('data-sort-type', compareFn && typeof compareFn === "string" && Fn[compareFn] ? compareFn:''); - - //th不参与排序 - flag && trArray.splice(0, 1); - trArray = utils.sort(trArray,function (tr1, tr2) { - var result; - if (compareFn && typeof compareFn === "function") { - result = compareFn.call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]); - } else if (compareFn && typeof compareFn === "number") { - result = 1; - } else if (compareFn && typeof compareFn === "string" && Fn[compareFn]) { - result = Fn[compareFn].call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]); - } else { - result = Fn['orderbyasc'].call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]); - } - return result; - }); - var fragment = table.ownerDocument.createDocumentFragment(); - for (var j = 0, len = trArray.length; j < len; j++) { - fragment.appendChild(trArray[j]); - } - var tbody = table.getElementsByTagName("tbody")[0]; - if(!lastRowIndex){ - tbody.appendChild(fragment); - }else{ - tbody.insertBefore(fragment,rows[lastRowIndex- range.endRowIndex + range.beginRowIndex - 1]) - } -}; - -UE.plugins['tablesort'] = function () { - var me = this, - UT = UE.UETable, - getUETable = function (tdOrTable) { - return UT.getUETable(tdOrTable); - }, - getTableItemsByRange = function (editor) { - return UT.getTableItemsByRange(editor); - }; - - - me.ready(function () { - //添加表格可排序的样式 - utils.cssRule('tablesort', - 'table.sortEnabled tr.firstRow th,table.sortEnabled tr.firstRow td{padding-right:20px;background-repeat: no-repeat;background-position: center right;' + - ' background-image:url(' + me.options.themePath + me.options.theme + '/images/sortable.png);}', - me.document); - - //做单元格合并操作时,清除可排序标识 - me.addListener("afterexeccommand", function (type, cmd) { - if( cmd == 'mergeright' || cmd == 'mergedown' || cmd == 'mergecells') { - this.execCommand('disablesort'); - } - }); - }); - - - - //表格排序 - UE.commands['sorttable'] = { - queryCommandState: function () { - var me = this, - tableItems = getTableItemsByRange(me); - if (!tableItems.cell) return -1; - var table = tableItems.table, - cells = table.getElementsByTagName("td"); - for (var i = 0, cell; cell = cells[i++];) { - if (cell.rowSpan != 1 || cell.colSpan != 1) return -1; - } - return 0; - }, - execCommand: function (cmd, fn) { - var me = this, - range = me.selection.getRange(), - bk = range.createBookmark(true), - tableItems = getTableItemsByRange(me), - cell = tableItems.cell, - ut = getUETable(tableItems.table), - cellInfo = ut.getCellInfo(cell); - ut.sortTable(cellInfo.cellIndex, fn); - range.moveToBookmark(bk); - try{ - range.select(); - }catch(e){} - } - }; - - //设置表格可排序,清除表格可排序 - UE.commands["enablesort"] = UE.commands["disablesort"] = { - queryCommandState: function (cmd) { - var table = getTableItemsByRange(this).table; - if(table && cmd=='enablesort') { - var cells = domUtils.getElementsByTagName(table, 'th td'); - for(var i = 0; i1 || cells[i].getAttribute('rowspan')>1) return -1; - } - } - - return !table ? -1: cmd=='enablesort' ^ table.getAttribute('data-sort')!='sortEnabled' ? -1:0; - }, - execCommand: function (cmd) { - var table = getTableItemsByRange(this).table; - table.setAttribute("data-sort", cmd == "enablesort" ? "sortEnabled" : "sortDisabled"); - cmd == "enablesort" ? domUtils.addClass(table,"sortEnabled"):domUtils.removeClasses(table,"sortEnabled"); - } - }; -}; - - -// plugins/contextmenu.js -///import core -///commands 右键菜单 -///commandsName ContextMenu -///commandsTitle 右键菜单 -/** - * 右键菜单 - * @function - * @name baidu.editor.plugins.contextmenu - * @author zhanyi - */ - -UE.plugins['contextmenu'] = function () { - var me = this; - me.setOpt('enableContextMenu',true); - if(me.getOpt('enableContextMenu') === false){ - return; - } - var lang = me.getLang( "contextMenu" ), - menu, - items = me.options.contextMenu || [ - {label:lang['selectall'], cmdName:'selectall'}, - { - label:lang.cleardoc, - cmdName:'cleardoc', - exec:function () { - if ( confirm( lang.confirmclear ) ) { - this.execCommand( 'cleardoc' ); - } - } - }, - '-', - { - label:lang.unlink, - cmdName:'unlink' - }, - '-', - { - group:lang.paragraph, - icon:'justifyjustify', - subMenu:[ - { - label:lang.justifyleft, - cmdName:'justify', - value:'left' - }, - { - label:lang.justifyright, - cmdName:'justify', - value:'right' - }, - { - label:lang.justifycenter, - cmdName:'justify', - value:'center' - }, - { - label:lang.justifyjustify, - cmdName:'justify', - value:'justify' - } - ] - }, - '-', - { - group:lang.table, - icon:'table', - subMenu:[ - { - label:lang.inserttable, - cmdName:'inserttable' - }, - { - label:lang.deletetable, - cmdName:'deletetable' - }, - '-', - { - label:lang.deleterow, - cmdName:'deleterow' - }, - { - label:lang.deletecol, - cmdName:'deletecol' - }, - { - label:lang.insertcol, - cmdName:'insertcol' - }, - { - label:lang.insertcolnext, - cmdName:'insertcolnext' - }, - { - label:lang.insertrow, - cmdName:'insertrow' - }, - { - label:lang.insertrownext, - cmdName:'insertrownext' - }, - '-', - { - label:lang.insertcaption, - cmdName:'insertcaption' - }, - { - label:lang.deletecaption, - cmdName:'deletecaption' - }, - { - label:lang.inserttitle, - cmdName:'inserttitle' - }, - { - label:lang.deletetitle, - cmdName:'deletetitle' - }, - { - label:lang.inserttitlecol, - cmdName:'inserttitlecol' - }, - { - label:lang.deletetitlecol, - cmdName:'deletetitlecol' - }, - '-', - { - label:lang.mergecells, - cmdName:'mergecells' - }, - { - label:lang.mergeright, - cmdName:'mergeright' - }, - { - label:lang.mergedown, - cmdName:'mergedown' - }, - '-', - { - label:lang.splittorows, - cmdName:'splittorows' - }, - { - label:lang.splittocols, - cmdName:'splittocols' - }, - { - label:lang.splittocells, - cmdName:'splittocells' - }, - '-', - { - label:lang.averageDiseRow, - cmdName:'averagedistributerow' - }, - { - label:lang.averageDisCol, - cmdName:'averagedistributecol' - }, - '-', - { - label:lang.edittd, - cmdName:'edittd', - exec:function () { - if ( UE.ui['edittd'] ) { - new UE.ui['edittd']( this ); - } - this.getDialog('edittd').open(); - } - }, - { - label:lang.edittable, - cmdName:'edittable', - exec:function () { - if ( UE.ui['edittable'] ) { - new UE.ui['edittable']( this ); - } - this.getDialog('edittable').open(); - } - }, - { - label:lang.setbordervisible, - cmdName:'setbordervisible' - } - ] - }, - { - group:lang.tablesort, - icon:'tablesort', - subMenu:[ - { - label:lang.enablesort, - cmdName:'enablesort' - }, - { - label:lang.disablesort, - cmdName:'disablesort' - }, - '-', - { - label:lang.reversecurrent, - cmdName:'sorttable', - value:'reversecurrent' - }, - { - label:lang.orderbyasc, - cmdName:'sorttable', - value:'orderbyasc' - }, - { - label:lang.reversebyasc, - cmdName:'sorttable', - value:'reversebyasc' - }, - { - label:lang.orderbynum, - cmdName:'sorttable', - value:'orderbynum' - }, - { - label:lang.reversebynum, - cmdName:'sorttable', - value:'reversebynum' - } - ] - }, - { - group:lang.borderbk, - icon:'borderBack', - subMenu:[ - { - label:lang.setcolor, - cmdName:"interlacetable", - exec:function(){ - this.execCommand("interlacetable"); - } - }, - { - label:lang.unsetcolor, - cmdName:"uninterlacetable", - exec:function(){ - this.execCommand("uninterlacetable"); - } - }, - { - label:lang.setbackground, - cmdName:"settablebackground", - exec:function(){ - this.execCommand("settablebackground",{repeat:true,colorList:["#bbb","#ccc"]}); - } - }, - { - label:lang.unsetbackground, - cmdName:"cleartablebackground", - exec:function(){ - this.execCommand("cleartablebackground"); - } - }, - { - label:lang.redandblue, - cmdName:"settablebackground", - exec:function(){ - this.execCommand("settablebackground",{repeat:true,colorList:["red","blue"]}); - } - }, - { - label:lang.threecolorgradient, - cmdName:"settablebackground", - exec:function(){ - this.execCommand("settablebackground",{repeat:true,colorList:["#aaa","#bbb","#ccc"]}); - } - } - ] - }, - { - group:lang.aligntd, - icon:'aligntd', - subMenu:[ - { - cmdName:'cellalignment', - value:{align:'left',vAlign:'top'} - }, - { - cmdName:'cellalignment', - value:{align:'center',vAlign:'top'} - }, - { - cmdName:'cellalignment', - value:{align:'right',vAlign:'top'} - }, - { - cmdName:'cellalignment', - value:{align:'left',vAlign:'middle'} - }, - { - cmdName:'cellalignment', - value:{align:'center',vAlign:'middle'} - }, - { - cmdName:'cellalignment', - value:{align:'right',vAlign:'middle'} - }, - { - cmdName:'cellalignment', - value:{align:'left',vAlign:'bottom'} - }, - { - cmdName:'cellalignment', - value:{align:'center',vAlign:'bottom'} - }, - { - cmdName:'cellalignment', - value:{align:'right',vAlign:'bottom'} - } - ] - }, - { - group:lang.aligntable, - icon:'aligntable', - subMenu:[ - { - cmdName:'tablealignment', - className: 'left', - label:lang.tableleft, - value:"left" - }, - { - cmdName:'tablealignment', - className: 'center', - label:lang.tablecenter, - value:"center" - }, - { - cmdName:'tablealignment', - className: 'right', - label:lang.tableright, - value:"right" - } - ] - }, - '-', - { - label:lang.insertparagraphbefore, - cmdName:'insertparagraph', - value:true - }, - { - label:lang.insertparagraphafter, - cmdName:'insertparagraph' - }, - { - label:lang['copy'], - cmdName:'copy' - }, - { - label:lang['paste'], - cmdName:'paste' - } - ]; - if ( !items.length ) { - return; - } - var uiUtils = UE.ui.uiUtils; - - me.addListener( 'contextmenu', function ( type, evt ) { - - var offset = uiUtils.getViewportOffsetByEvent( evt ); - me.fireEvent( 'beforeselectionchange' ); - if ( menu ) { - menu.destroy(); - } - for ( var i = 0, ti, contextItems = []; ti = items[i]; i++ ) { - var last; - (function ( item ) { - if ( item == '-' ) { - if ( (last = contextItems[contextItems.length - 1 ] ) && last !== '-' ) { - contextItems.push( '-' ); - } - } else if ( item.hasOwnProperty( "group" ) ) { - for ( var j = 0, cj, subMenu = []; cj = item.subMenu[j]; j++ ) { - (function ( subItem ) { - if ( subItem == '-' ) { - if ( (last = subMenu[subMenu.length - 1 ] ) && last !== '-' ) { - subMenu.push( '-' ); - }else{ - subMenu.splice(subMenu.length-1); - } - } else { - if ( (me.commands[subItem.cmdName] || UE.commands[subItem.cmdName] || subItem.query) && - (subItem.query ? subItem.query() : me.queryCommandState( subItem.cmdName )) > -1 ) { - subMenu.push( { - 'label':subItem.label || me.getLang( "contextMenu." + subItem.cmdName + (subItem.value || '') )||"", - 'className':'edui-for-' +subItem.cmdName + ( subItem.className ? ( ' edui-for-' + subItem.cmdName + '-' + subItem.className ) : '' ), - onclick:subItem.exec ? function () { - subItem.exec.call( me ); - } : function () { - me.execCommand( subItem.cmdName, subItem.value ); - } - } ); - } - } - })( cj ); - } - if ( subMenu.length ) { - function getLabel(){ - switch (item.icon){ - case "table": - return me.getLang( "contextMenu.table" ); - case "justifyjustify": - return me.getLang( "contextMenu.paragraph" ); - case "aligntd": - return me.getLang("contextMenu.aligntd"); - case "aligntable": - return me.getLang("contextMenu.aligntable"); - case "tablesort": - return lang.tablesort; - case "borderBack": - return lang.borderbk; - default : - return ''; - } - } - contextItems.push( { - //todo 修正成自动获取方式 - 'label':getLabel(), - className:'edui-for-' + item.icon, - 'subMenu':{ - items:subMenu, - editor:me - } - } ); - } - - } else { - //有可能commmand没有加载右键不能出来,或者没有command也想能展示出来添加query方法 - if ( (me.commands[item.cmdName] || UE.commands[item.cmdName] || item.query) && - (item.query ? item.query.call(me) : me.queryCommandState( item.cmdName )) > -1 ) { - - contextItems.push( { - 'label':item.label || me.getLang( "contextMenu." + item.cmdName ), - className:'edui-for-' + (item.icon ? item.icon : item.cmdName + (item.value || '')), - onclick:item.exec ? function () { - item.exec.call( me ); - } : function () { - me.execCommand( item.cmdName, item.value ); - } - } ); - } - - } - - })( ti ); - } - if ( contextItems[contextItems.length - 1] == '-' ) { - contextItems.pop(); - } - - menu = new UE.ui.Menu( { - items:contextItems, - className:"edui-contextmenu", - editor:me - } ); - menu.render(); - menu.showAt( offset ); - - me.fireEvent("aftershowcontextmenu",menu); - - domUtils.preventDefault( evt ); - if ( browser.ie ) { - var ieRange; - try { - ieRange = me.selection.getNative().createRange(); - } catch ( e ) { - return; - } - if ( ieRange.item ) { - var range = new dom.Range( me.document ); - range.selectNode( ieRange.item( 0 ) ).select( true, true ); - } - } - }); - - // 添加复制的flash按钮 - me.addListener('aftershowcontextmenu', function(type, menu) { - if (me.zeroclipboard) { - var items = menu.items; - for (var key in items) { - if (items[key].className == 'edui-for-copy') { - me.zeroclipboard.clip(items[key].getDom()); - } - } - } - }); - -}; - - -// plugins/shortcutmenu.js -///import core -///commands 弹出菜单 -// commandsName popupmenu -///commandsTitle 弹出菜单 -/** - * 弹出菜单 - * @function - * @name baidu.editor.plugins.popupmenu - * @author xuheng - */ - -UE.plugins['shortcutmenu'] = function () { - var me = this, - menu, - items = me.options.shortcutMenu || []; - - if (!items.length) { - return; - } - - me.addListener ('contextmenu mouseup' , function (type , e) { - var me = this, - customEvt = { - type : type , - target : e.target || e.srcElement , - screenX : e.screenX , - screenY : e.screenY , - clientX : e.clientX , - clientY : e.clientY - }; - - setTimeout (function () { - var rng = me.selection.getRange (); - if (rng.collapsed === false || type == "contextmenu") { - - if (!menu) { - menu = new baidu.editor.ui.ShortCutMenu ({ - editor : me , - items : items , - theme : me.options.theme , - className : 'edui-shortcutmenu' - }); - - menu.render (); - me.fireEvent ("afterrendershortcutmenu" , menu); - } - - menu.show (customEvt , !!UE.plugins['contextmenu']); - } - }); - - if (type == 'contextmenu') { - domUtils.preventDefault (e); - if (browser.ie9below) { - var ieRange; - try { - ieRange = me.selection.getNative().createRange(); - } catch (e) { - return; - } - if (ieRange.item) { - var range = new dom.Range (me.document); - range.selectNode (ieRange.item (0)).select (true , true); - - } - } - } - }); - - me.addListener ('keydown' , function (type) { - if (type == "keydown") { - menu && !menu.isHidden && menu.hide (); - } - - }); - -}; - - - - -// plugins/basestyle.js -/** - * B、I、sub、super命令支持 - * @file - * @since 1.2.6.1 - */ - -UE.plugins['basestyle'] = function(){ - - /** - * 字体加粗 - * @command bold - * @param { String } cmd 命令字符串 - * @remind 对已加粗的文本内容执行该命令, 将取消加粗 - * @method execCommand - * @example - * ```javascript - * //editor是编辑器实例 - * //对当前选中的文本内容执行加粗操作 - * //第一次执行, 文本内容加粗 - * editor.execCommand( 'bold' ); - * - * //第二次执行, 文本内容取消加粗 - * editor.execCommand( 'bold' ); - * ``` - */ - - - /** - * 字体倾斜 - * @command italic - * @method execCommand - * @param { String } cmd 命令字符串 - * @remind 对已倾斜的文本内容执行该命令, 将取消倾斜 - * @example - * ```javascript - * //editor是编辑器实例 - * //对当前选中的文本内容执行斜体操作 - * //第一次操作, 文本内容将变成斜体 - * editor.execCommand( 'italic' ); - * - * //再次对同一文本内容执行, 则文本内容将恢复正常 - * editor.execCommand( 'italic' ); - * ``` - */ - - /** - * 下标文本,与“superscript”命令互斥 - * @command subscript - * @method execCommand - * @remind 把选中的文本内容切换成下标文本, 如果当前选中的文本已经是下标, 则该操作会把文本内容还原成正常文本 - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * //editor是编辑器实例 - * //对当前选中的文本内容执行下标操作 - * //第一次操作, 文本内容将变成下标文本 - * editor.execCommand( 'subscript' ); - * - * //再次对同一文本内容执行, 则文本内容将恢复正常 - * editor.execCommand( 'subscript' ); - * ``` - */ - - /** - * 上标文本,与“subscript”命令互斥 - * @command superscript - * @method execCommand - * @remind 把选中的文本内容切换成上标文本, 如果当前选中的文本已经是上标, 则该操作会把文本内容还原成正常文本 - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * //editor是编辑器实例 - * //对当前选中的文本内容执行上标操作 - * //第一次操作, 文本内容将变成上标文本 - * editor.execCommand( 'superscript' ); - * - * //再次对同一文本内容执行, 则文本内容将恢复正常 - * editor.execCommand( 'superscript' ); - * ``` - */ - var basestyles = { - 'bold':['strong','b'], - 'italic':['em','i'], - 'subscript':['sub'], - 'superscript':['sup'] - }, - getObj = function(editor,tagNames){ - return domUtils.filterNodeList(editor.selection.getStartElementPath(),tagNames); - }, - me = this; - //添加快捷键 - me.addshortcutkey({ - "Bold" : "ctrl+66",//^B - "Italic" : "ctrl+73", //^I - "Underline" : "ctrl+85"//^U - }); - me.addInputRule(function(root){ - utils.each(root.getNodesByTagName('b i'),function(node){ - switch (node.tagName){ - case 'b': - node.tagName = 'strong'; - break; - case 'i': - node.tagName = 'em'; - } - }); - }); - for ( var style in basestyles ) { - (function( cmd, tagNames ) { - me.commands[cmd] = { - execCommand : function( cmdName ) { - var range = me.selection.getRange(),obj = getObj(this,tagNames); - if ( range.collapsed ) { - if ( obj ) { - var tmpText = me.document.createTextNode(''); - range.insertNode( tmpText ).removeInlineStyle( tagNames ); - range.setStartBefore(tmpText); - domUtils.remove(tmpText); - } else { - var tmpNode = range.document.createElement( tagNames[0] ); - if(cmdName == 'superscript' || cmdName == 'subscript'){ - tmpText = me.document.createTextNode(''); - range.insertNode(tmpText) - .removeInlineStyle(['sub','sup']) - .setStartBefore(tmpText) - .collapse(true); - } - range.insertNode( tmpNode ).setStart( tmpNode, 0 ); - } - range.collapse( true ); - } else { - if(cmdName == 'superscript' || cmdName == 'subscript'){ - if(!obj || obj.tagName.toLowerCase() != cmdName){ - range.removeInlineStyle(['sub','sup']); - } - } - obj ? range.removeInlineStyle( tagNames ) : range.applyInlineStyle( tagNames[0] ); - } - range.select(); - }, - queryCommandState : function() { - return getObj(this,tagNames) ? 1 : 0; - } - }; - })( style, basestyles[style] ); - } -}; - - - -// plugins/elementpath.js -/** - * 选取路径命令 - * @file - */ -UE.plugins['elementpath'] = function(){ - var currentLevel, - tagNames, - me = this; - me.setOpt('elementPathEnabled',true); - if(!me.options.elementPathEnabled){ - return; - } - me.commands['elementpath'] = { - execCommand : function( cmdName, level ) { - var start = tagNames[level], - range = me.selection.getRange(); - currentLevel = level*1; - range.selectNode(start).select(); - }, - queryCommandValue : function() { - //产生一个副本,不能修改原来的startElementPath; - var parents = [].concat(this.selection.getStartElementPath()).reverse(), - names = []; - tagNames = parents; - for(var i=0,ci;ci=parents[i];i++){ - if(ci.nodeType == 3) { - continue; - } - var name = ci.tagName.toLowerCase(); - if(name == 'img' && ci.getAttribute('anchorname')){ - name = 'anchor'; - } - names[i] = name; - if(currentLevel == i){ - currentLevel = -1; - break; - } - } - return names; - } - }; -}; - - - -// plugins/formatmatch.js -/** - * 格式刷,只格式inline的 - * @file - * @since 1.2.6.1 - */ - -/** - * 格式刷 - * @command formatmatch - * @method execCommand - * @remind 该操作不能复制段落格式 - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * //editor是编辑器实例 - * //获取格式刷 - * editor.execCommand( 'formatmatch' ); - * ``` - */ -UE.plugins['formatmatch'] = function(){ - - var me = this, - list = [],img, - flag = 0; - - me.addListener('reset',function(){ - list = []; - flag = 0; - }); - - function addList(type,evt){ - - if(browser.webkit){ - var target = evt.target.tagName == 'IMG' ? evt.target : null; - } - - function addFormat(range){ - - if(text){ - range.selectNode(text); - } - return range.applyInlineStyle(list[list.length-1].tagName,null,list); - - } - - me.undoManger && me.undoManger.save(); - - var range = me.selection.getRange(), - imgT = target || range.getClosedNode(); - if(img && imgT && imgT.tagName == 'IMG'){ - //trace:964 - - imgT.style.cssText += ';float:' + (img.style.cssFloat || img.style.styleFloat ||'none') + ';display:' + (img.style.display||'inline'); - - img = null; - }else{ - if(!img){ - var collapsed = range.collapsed; - if(collapsed){ - var text = me.document.createTextNode('match'); - range.insertNode(text).select(); - - - } - me.__hasEnterExecCommand = true; - //不能把block上的属性干掉 - //trace:1553 - var removeFormatAttributes = me.options.removeFormatAttributes; - me.options.removeFormatAttributes = ''; - me.execCommand('removeformat'); - me.options.removeFormatAttributes = removeFormatAttributes; - me.__hasEnterExecCommand = false; - //trace:969 - range = me.selection.getRange(); - if(list.length){ - addFormat(range); - } - if(text){ - range.setStartBefore(text).collapse(true); - - } - range.select(); - text && domUtils.remove(text); - } - - } - - - - - me.undoManger && me.undoManger.save(); - me.removeListener('mouseup',addList); - flag = 0; - } - - me.commands['formatmatch'] = { - execCommand : function( cmdName ) { - - if(flag){ - flag = 0; - list = []; - me.removeListener('mouseup',addList); - return; - } - - - - var range = me.selection.getRange(); - img = range.getClosedNode(); - if(!img || img.tagName != 'IMG'){ - range.collapse(true).shrinkBoundary(); - var start = range.startContainer; - list = domUtils.findParents(start,true,function(node){ - return !domUtils.isBlockElm(node) && node.nodeType == 1; - }); - //a不能加入格式刷, 并且克隆节点 - for(var i=0,ci;ci=list[i];i++){ - if(ci.tagName == 'A'){ - list.splice(i,1); - break; - } - } - - } - - me.addListener('mouseup',addList); - flag = 1; - - - }, - queryCommandState : function() { - return flag; - }, - notNeedUndo : 1 - }; -}; - - - -// plugins/searchreplace.js -///import core -///commands 查找替换 -///commandsName SearchReplace -///commandsTitle 查询替换 -///commandsDialog dialogs\searchreplace -/** - * @description 查找替换 - * @author zhanyi - */ - -UE.plugin.register('searchreplace',function(){ - var me = this; - - var _blockElm = {'table':1,'tbody':1,'tr':1,'ol':1,'ul':1}; - - function findTextInString(textContent,opt,currentIndex){ - var str = opt.searchStr; - if(opt.dir == -1){ - textContent = textContent.split('').reverse().join(''); - str = str.split('').reverse().join(''); - currentIndex = textContent.length - currentIndex; - - } - var reg = new RegExp(str,'g' + (opt.casesensitive ? '' : 'i')),match; - - while(match = reg.exec(textContent)){ - if(match.index >= currentIndex){ - return opt.dir == -1 ? textContent.length - match.index - opt.searchStr.length : match.index; - } - } - return -1 - } - function findTextBlockElm(node,currentIndex,opt){ - var textContent,index,methodName = opt.all || opt.dir == 1 ? 'getNextDomNode' : 'getPreDomNode'; - if(domUtils.isBody(node)){ - node = node.firstChild; - } - var first = 1; - while(node){ - textContent = node.nodeType == 3 ? node.nodeValue : node[browser.ie ? 'innerText' : 'textContent']; - index = findTextInString(textContent,opt,currentIndex ); - first = 0; - if(index!=-1){ - return { - 'node':node, - 'index':index - } - } - node = domUtils[methodName](node); - while(node && _blockElm[node.nodeName.toLowerCase()]){ - node = domUtils[methodName](node,true); - } - if(node){ - currentIndex = opt.dir == -1 ? (node.nodeType == 3 ? node.nodeValue : node[browser.ie ? 'innerText' : 'textContent']).length : 0; - } - - } - } - function findNTextInBlockElm(node,index,str){ - var currentIndex = 0, - currentNode = node.firstChild, - currentNodeLength = 0, - result; - while(currentNode){ - if(currentNode.nodeType == 3){ - currentNodeLength = currentNode.nodeValue.replace(/(^[\t\r\n]+)|([\t\r\n]+$)/,'').length; - currentIndex += currentNodeLength; - if(currentIndex >= index){ - return { - 'node':currentNode, - 'index': currentNodeLength - (currentIndex - index) - } - } - }else if(!dtd.$empty[currentNode.tagName]){ - currentNodeLength = currentNode[browser.ie ? 'innerText' : 'textContent'].replace(/(^[\t\r\n]+)|([\t\r\n]+$)/,'').length - currentIndex += currentNodeLength; - if(currentIndex >= index){ - result = findNTextInBlockElm(currentNode,currentNodeLength - (currentIndex - index),str); - if(result){ - return result; - } - } - } - currentNode = domUtils.getNextDomNode(currentNode); - - } - } - - function searchReplace(me,opt){ - - var rng = me.selection.getRange(), - startBlockNode, - searchStr = opt.searchStr, - span = me.document.createElement('span'); - span.innerHTML = '$$ueditor_searchreplace_key$$'; - - rng.shrinkBoundary(true); - - //判断是不是第一次选中 - if(!rng.collapsed){ - rng.select(); - var rngText = me.selection.getText(); - if(new RegExp('^' + opt.searchStr + '$',(opt.casesensitive ? '' : 'i')).test(rngText)){ - if(opt.replaceStr != undefined){ - replaceText(rng,opt.replaceStr); - rng.select(); - return true; - }else{ - rng.collapse(opt.dir == -1) - } - - } - } - - - rng.insertNode(span); - rng.enlargeToBlockElm(true); - startBlockNode = rng.startContainer; - var currentIndex = startBlockNode[browser.ie ? 'innerText' : 'textContent'].indexOf('$$ueditor_searchreplace_key$$'); - rng.setStartBefore(span); - domUtils.remove(span); - var result = findTextBlockElm(startBlockNode,currentIndex,opt); - if(result){ - var rngStart = findNTextInBlockElm(result.node,result.index,searchStr); - var rngEnd = findNTextInBlockElm(result.node,result.index + searchStr.length,searchStr); - rng.setStart(rngStart.node,rngStart.index).setEnd(rngEnd.node,rngEnd.index); - - if(opt.replaceStr !== undefined){ - replaceText(rng,opt.replaceStr) - } - rng.select(); - return true; - }else{ - rng.setCursor() - } - - } - function replaceText(rng,str){ - - str = me.document.createTextNode(str); - rng.deleteContents().insertNode(str); - - } - return { - commands:{ - 'searchreplace':{ - execCommand:function(cmdName,opt){ - utils.extend(opt,{ - all : false, - casesensitive : false, - dir : 1 - },true); - var num = 0; - if(opt.all){ - - var rng = me.selection.getRange(), - first = me.body.firstChild; - if(first && first.nodeType == 1){ - rng.setStart(first,0); - rng.shrinkBoundary(true); - }else if(first.nodeType == 3){ - rng.setStartBefore(first) - } - rng.collapse(true).select(true); - if(opt.replaceStr !== undefined){ - me.fireEvent('saveScene'); - } - while(searchReplace(this,opt)){ - num++; - } - if(num){ - me.fireEvent('saveScene'); - } - }else{ - if(opt.replaceStr !== undefined){ - me.fireEvent('saveScene'); - } - if(searchReplace(this,opt)){ - num++ - } - if(num){ - me.fireEvent('saveScene'); - } - - } - - return num; - }, - notNeedUndo:1 - } - } - } -}); - -// plugins/customstyle.js -/** - * 自定义样式 - * @file - * @since 1.2.6.1 - */ - -/** - * 根据config配置文件里“customstyle”选项的值对匹配的标签执行样式替换。 - * @command customstyle - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand( 'customstyle' ); - * ``` - */ -UE.plugins['customstyle'] = function() { - var me = this; - me.setOpt({ 'customstyle':[ - {tag:'h1',name:'tc', style:'font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:center;margin:0 0 20px 0;'}, - {tag:'h1',name:'tl', style:'font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:left;margin:0 0 10px 0;'}, - {tag:'span',name:'im', style:'font-size:16px;font-style:italic;font-weight:bold;line-height:18px;'}, - {tag:'span',name:'hi', style:'font-size:16px;font-style:italic;font-weight:bold;color:rgb(51, 153, 204);line-height:18px;'} - ]}); - me.commands['customstyle'] = { - execCommand : function(cmdName, obj) { - var me = this, - tagName = obj.tag, - node = domUtils.findParent(me.selection.getStart(), function(node) { - return node.getAttribute('label'); - }, true), - range,bk,tmpObj = {}; - for (var p in obj) { - if(obj[p]!==undefined) - tmpObj[p] = obj[p]; - } - delete tmpObj.tag; - if (node && node.getAttribute('label') == obj.label) { - range = this.selection.getRange(); - bk = range.createBookmark(); - if (range.collapsed) { - //trace:1732 删掉自定义标签,要有p来回填站位 - if(dtd.$block[node.tagName]){ - var fillNode = me.document.createElement('p'); - domUtils.moveChild(node, fillNode); - node.parentNode.insertBefore(fillNode, node); - domUtils.remove(node); - }else{ - domUtils.remove(node,true); - } - - } else { - - var common = domUtils.getCommonAncestor(bk.start, bk.end), - nodes = domUtils.getElementsByTagName(common, tagName); - if(new RegExp(tagName,'i').test(common.tagName)){ - nodes.push(common); - } - for (var i = 0,ni; ni = nodes[i++];) { - if (ni.getAttribute('label') == obj.label) { - var ps = domUtils.getPosition(ni, bk.start),pe = domUtils.getPosition(ni, bk.end); - if ((ps & domUtils.POSITION_FOLLOWING || ps & domUtils.POSITION_CONTAINS) - && - (pe & domUtils.POSITION_PRECEDING || pe & domUtils.POSITION_CONTAINS) - ) - if (dtd.$block[tagName]) { - var fillNode = me.document.createElement('p'); - domUtils.moveChild(ni, fillNode); - ni.parentNode.insertBefore(fillNode, ni); - } - domUtils.remove(ni, true); - } - } - node = domUtils.findParent(common, function(node) { - return node.getAttribute('label') == obj.label; - }, true); - if (node) { - - domUtils.remove(node, true); - - } - - } - range.moveToBookmark(bk).select(); - } else { - if (dtd.$block[tagName]) { - this.execCommand('paragraph', tagName, tmpObj,'customstyle'); - range = me.selection.getRange(); - if (!range.collapsed) { - range.collapse(); - node = domUtils.findParent(me.selection.getStart(), function(node) { - return node.getAttribute('label') == obj.label; - }, true); - var pNode = me.document.createElement('p'); - domUtils.insertAfter(node, pNode); - domUtils.fillNode(me.document, pNode); - range.setStart(pNode, 0).setCursor(); - } - } else { - - range = me.selection.getRange(); - if (range.collapsed) { - node = me.document.createElement(tagName); - domUtils.setAttributes(node, tmpObj); - range.insertNode(node).setStart(node, 0).setCursor(); - - return; - } - - bk = range.createBookmark(); - range.applyInlineStyle(tagName, tmpObj).moveToBookmark(bk).select(); - } - } - - }, - queryCommandValue : function() { - var parent = domUtils.filterNodeList( - this.selection.getStartElementPath(), - function(node){return node.getAttribute('label')} - ); - return parent ? parent.getAttribute('label') : ''; - } - }; - //当去掉customstyle是,如果是块元素,用p代替 - me.addListener('keyup', function(type, evt) { - var keyCode = evt.keyCode || evt.which; - - if (keyCode == 32 || keyCode == 13) { - var range = me.selection.getRange(); - if (range.collapsed) { - var node = domUtils.findParent(me.selection.getStart(), function(node) { - return node.getAttribute('label'); - }, true); - if (node && dtd.$block[node.tagName] && domUtils.isEmptyNode(node)) { - var p = me.document.createElement('p'); - domUtils.insertAfter(node, p); - domUtils.fillNode(me.document, p); - domUtils.remove(node); - range.setStart(p, 0).setCursor(); - - - } - } - } - }); -}; - -// plugins/catchremoteimage.js -///import core -///commands 远程图片抓取 -///commandsName catchRemoteImage,catchremoteimageenable -///commandsTitle 远程图片抓取 -/** - * 远程图片抓取,当开启本插件时所有不符合本地域名的图片都将被抓取成为本地服务器上的图片 - */ -UE.plugins['catchremoteimage'] = function () { - var me = this, - ajax = UE.ajax; - - /* 设置默认值 */ - if (me.options.catchRemoteImageEnable === false) return; - me.setOpt({ - catchRemoteImageEnable: false - }); - - me.addListener("afterpaste", function () { - me.fireEvent("catchRemoteImage"); - }); - - me.addListener("catchRemoteImage", function () { - - var catcherLocalDomain = me.getOpt('catcherLocalDomain'), - catcherActionUrl = me.getActionUrl(me.getOpt('catcherActionName')), - catcherUrlPrefix = me.getOpt('catcherUrlPrefix'), - catcherFieldName = me.getOpt('catcherFieldName'); - - var remoteImages = [], - imgs = domUtils.getElementsByTagName(me.document, "img"), - test = function (src, urls) { - if (src.indexOf(location.host) != -1 || /(^\.)|(^\/)/.test(src)) { - return true; - } - if (urls) { - for (var j = 0, url; url = urls[j++];) { - if (src.indexOf(url) !== -1) { - return true; - } - } - } - return false; - }; - - for (var i = 0, ci; ci = imgs[i++];) { - if (ci.getAttribute("word_img")) { - continue; - } - var src = ci.getAttribute("_src") || ci.src || ""; - if (/^(https?|ftp):/i.test(src) && !test(src, catcherLocalDomain)) { - remoteImages.push(src); - } - } - - if (remoteImages.length) { - catchremoteimage(remoteImages, { - //成功抓取 - success: function (r) { - try { - var info = r.state !== undefined ? r:eval("(" + r.responseText + ")"); - } catch (e) { - return; - } - - /* 获取源路径和新路径 */ - var i, j, ci, cj, oldSrc, newSrc, list = info.list; - - for (i = 0; ci = imgs[i++];) { - oldSrc = ci.getAttribute("_src") || ci.src || ""; - for (j = 0; cj = list[j++];) { - if (oldSrc == cj.source && cj.state == "SUCCESS") { //抓取失败时不做替换处理 - newSrc = catcherUrlPrefix + cj.url; - domUtils.setAttributes(ci, { - "src": newSrc, - "_src": newSrc - }); - break; - } - } - } - me.fireEvent('catchremotesuccess') - }, - //回调失败,本次请求超时 - error: function () { - me.fireEvent("catchremoteerror"); - } - }); - } - - function catchremoteimage(imgs, callbacks) { - var params = utils.serializeParam(me.queryCommandValue('serverparam')) || '', - url = utils.formatUrl(catcherActionUrl + (catcherActionUrl.indexOf('?') == -1 ? '?':'&') + params), - isJsonp = utils.isCrossDomainUrl(url), - opt = { - 'method': 'POST', - 'dataType': isJsonp ? 'jsonp':'', - 'timeout': 60000, //单位:毫秒,回调请求超时设置。目标用户如果网速不是很快的话此处建议设置一个较大的数值 - 'onsuccess': callbacks["success"], - 'onerror': callbacks["error"] - }; - opt[catcherFieldName] = imgs; - ajax.request(url, opt); - } - - }); -}; - -// plugins/snapscreen.js -/** - * 截屏插件,为UEditor提供插入支持 - * @file - * @since 1.4.2 - */ -UE.plugin.register('snapscreen', function (){ - - var me = this; - var snapplugin; - - function getLocation(url){ - var search, - a = document.createElement('a'), - params = utils.serializeParam(me.queryCommandValue('serverparam')) || ''; - - a.href = url; - if (browser.ie) { - a.href = a.href; - } - - - search = a.search; - if (params) { - search = search + (search.indexOf('?') == -1 ? '?':'&')+ params; - search = search.replace(/[&]+/ig, '&'); - } - return { - 'port': a.port, - 'hostname': a.hostname, - 'path': a.pathname + search || + a.hash - } - } - - return { - commands:{ - /** - * 字体背景颜色 - * @command snapscreen - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand('snapscreen'); - * ``` - */ - 'snapscreen':{ - execCommand:function (cmd) { - var url, local, res; - var lang = me.getLang("snapScreen_plugin"); - - if(!snapplugin){ - var container = me.container; - var doc = me.container.ownerDocument || me.container.document; - snapplugin = doc.createElement("object"); - try{snapplugin.type = "application/x-pluginbaidusnap";}catch(e){ - return; - } - snapplugin.style.cssText = "position:absolute;left:-9999px;width:0;height:0;"; - snapplugin.setAttribute("width","0"); - snapplugin.setAttribute("height","0"); - container.appendChild(snapplugin); - } - - function onSuccess(rs){ - try{ - rs = eval("("+ rs +")"); - if(rs.state == 'SUCCESS'){ - var opt = me.options; - me.execCommand('insertimage', { - src: opt.snapscreenUrlPrefix + rs.url, - _src: opt.snapscreenUrlPrefix + rs.url, - alt: rs.title || '', - floatStyle: opt.snapscreenImgAlign - }); - } else { - alert(rs.state); - } - }catch(e){ - alert(lang.callBackErrorMsg); - } - } - url = me.getActionUrl(me.getOpt('snapscreenActionName')); - local = getLocation(url); - setTimeout(function () { - try{ - res =snapplugin.saveSnapshot(local.hostname, local.path, local.port); - }catch(e){ - me.ui._dialogs['snapscreenDialog'].open(); - return; - } - - onSuccess(res); - }, 50); - }, - queryCommandState: function(){ - return (navigator.userAgent.indexOf("Windows",0) != -1) ? 0:-1; - } - } - } - } -}); - - -// plugins/insertparagraph.js -/** - * 插入段落 - * @file - * @since 1.2.6.1 - */ - - -/** - * 插入段落 - * @command insertparagraph - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * //editor是编辑器实例 - * editor.execCommand( 'insertparagraph' ); - * ``` - */ - -UE.commands['insertparagraph'] = { - execCommand : function( cmdName,front) { - var me = this, - range = me.selection.getRange(), - start = range.startContainer,tmpNode; - while(start ){ - if(domUtils.isBody(start)){ - break; - } - tmpNode = start; - start = start.parentNode; - } - if(tmpNode){ - var p = me.document.createElement('p'); - if(front){ - tmpNode.parentNode.insertBefore(p,tmpNode) - }else{ - tmpNode.parentNode.insertBefore(p,tmpNode.nextSibling) - } - domUtils.fillNode(me.document,p); - range.setStart(p,0).setCursor(false,true); - } - } -}; - - - -// plugins/webapp.js -/** - * 百度应用 - * @file - * @since 1.2.6.1 - */ - - -/** - * 插入百度应用 - * @command webapp - * @method execCommand - * @remind 需要百度APPKey - * @remind 百度应用主页: http://app.baidu.com/ - * @param { Object } appOptions 应用所需的参数项, 支持的key有: title=>应用标题, width=>应用容器宽度, - * height=>应用容器高度,logo=>应用logo,url=>应用地址 - * @example - * ```javascript - * //editor是编辑器实例 - * //在编辑器里插入一个“植物大战僵尸”的APP - * editor.execCommand( 'webapp' , { - * title: '植物大战僵尸', - * width: 560, - * height: 465, - * logo: '应用展示的图片', - * url: '百度应用的地址' - * } ); - * ``` - */ - -//UE.plugins['webapp'] = function () { -// var me = this; -// function createInsertStr( obj, toIframe, addParagraph ) { -// return !toIframe ? -// (addParagraph ? '

    ' : '') + '' + -// (addParagraph ? '

    ' : '') -// : -// ''; -// } -// -// function switchImgAndIframe( img2frame ) { -// var tmpdiv, -// nodes = domUtils.getElementsByTagName( me.document, !img2frame ? "iframe" : "img" ); -// for ( var i = 0, node; node = nodes[i++]; ) { -// if ( node.className != "edui-faked-webapp" ){ -// continue; -// } -// tmpdiv = me.document.createElement( "div" ); -// tmpdiv.innerHTML = createInsertStr( img2frame ? {url:node.getAttribute( "_url" ), width:node.width, height:node.height,title:node.title,logo:node.style.backgroundImage.replace("url(","").replace(")","")} : {url:node.getAttribute( "src", 2 ),title:node.title, width:node.width, height:node.height,logo:node.getAttribute("logo_url")}, img2frame ? true : false,false ); -// node.parentNode.replaceChild( tmpdiv.firstChild, node ); -// } -// } -// -// me.addListener( "beforegetcontent", function () { -// switchImgAndIframe( true ); -// } ); -// me.addListener( 'aftersetcontent', function () { -// switchImgAndIframe( false ); -// } ); -// me.addListener( 'aftergetcontent', function ( cmdName ) { -// if ( cmdName == 'aftergetcontent' && me.queryCommandState( 'source' ) ){ -// return; -// } -// switchImgAndIframe( false ); -// } ); -// -// me.commands['webapp'] = { -// execCommand:function ( cmd, obj ) { -// me.execCommand( "inserthtml", createInsertStr( obj, false,true ) ); -// } -// }; -//}; - -UE.plugin.register('webapp', function (){ - var me = this; - function createInsertStr(obj,toEmbed){ - return !toEmbed ? - '' - : - '' - - } - return { - outputRule: function(root){ - utils.each(root.getNodesByTagName('img'),function(node){ - var html; - if(node.getAttr('class') == 'edui-faked-webapp'){ - html = createInsertStr({ - title:node.getAttr('title'), - 'width':node.getAttr('width'), - 'height':node.getAttr('height'), - 'align':node.getAttr('align'), - 'cssfloat':node.getStyle('float'), - 'url':node.getAttr("_url"), - 'logo':node.getAttr('_logo_url') - },true); - var embed = UE.uNode.createElement(html); - node.parentNode.replaceChild(embed,node); - } - }) - }, - inputRule:function(root){ - utils.each(root.getNodesByTagName('iframe'),function(node){ - if(node.getAttr('class') == 'edui-faked-webapp'){ - var img = UE.uNode.createElement(createInsertStr({ - title:node.getAttr('title'), - 'width':node.getAttr('width'), - 'height':node.getAttr('height'), - 'align':node.getAttr('align'), - 'cssfloat':node.getStyle('float'), - 'url':node.getAttr("src"), - 'logo':node.getAttr('logo_url') - })); - node.parentNode.replaceChild(img,node); - } - }) - - }, - commands:{ - /** - * 插入百度应用 - * @command webapp - * @method execCommand - * @remind 需要百度APPKey - * @remind 百度应用主页: http://app.baidu.com/ - * @param { Object } appOptions 应用所需的参数项, 支持的key有: title=>应用标题, width=>应用容器宽度, - * height=>应用容器高度,logo=>应用logo,url=>应用地址 - * @example - * ```javascript - * //editor是编辑器实例 - * //在编辑器里插入一个“植物大战僵尸”的APP - * editor.execCommand( 'webapp' , { - * title: '植物大战僵尸', - * width: 560, - * height: 465, - * logo: '应用展示的图片', - * url: '百度应用的地址' - * } ); - * ``` - */ - 'webapp':{ - execCommand:function (cmd, obj) { - - var me = this, - str = createInsertStr(utils.extend(obj,{ - align:'none' - }), false); - me.execCommand("inserthtml",str); - }, - queryCommandState:function () { - var me = this, - img = me.selection.getRange().getClosedNode(), - flag = img && (img.className == "edui-faked-webapp"); - return flag ? 1 : 0; - } - } - } - } -}); - -// plugins/template.js -///import core -///import plugins\inserthtml.js -///import plugins\cleardoc.js -///commands 模板 -///commandsName template -///commandsTitle 模板 -///commandsDialog dialogs\template -UE.plugins['template'] = function () { - UE.commands['template'] = { - execCommand:function (cmd, obj) { - obj.html && this.execCommand("inserthtml", obj.html); - } - }; - this.addListener("click", function (type, evt) { - var el = evt.target || evt.srcElement, - range = this.selection.getRange(); - var tnode = domUtils.findParent(el, function (node) { - if (node.className && domUtils.hasClass(node, "ue_t")) { - return node; - } - }, true); - tnode && range.selectNode(tnode).shrinkBoundary().select(); - }); - this.addListener("keydown", function (type, evt) { - var range = this.selection.getRange(); - if (!range.collapsed) { - if (!evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey) { - var tnode = domUtils.findParent(range.startContainer, function (node) { - if (node.className && domUtils.hasClass(node, "ue_t")) { - return node; - } - }, true); - if (tnode) { - domUtils.removeClasses(tnode, ["ue_t"]); - } - } - } - }); -}; - - -// plugins/music.js -/** - * 插入音乐命令 - * @file - */ -UE.plugin.register('music', function (){ - var me = this; - function creatInsertStr(url,width,height,align,cssfloat,toEmbed){ - return !toEmbed ? - '' - : - ''; - } - return { - outputRule: function(root){ - utils.each(root.getNodesByTagName('img'),function(node){ - var html; - if(node.getAttr('class') == 'edui-faked-music'){ - var cssfloat = node.getStyle('float'); - var align = node.getAttr('align'); - html = creatInsertStr(node.getAttr("_url"), node.getAttr('width'), node.getAttr('height'), align, cssfloat, true); - var embed = UE.uNode.createElement(html); - node.parentNode.replaceChild(embed,node); - } - }) - }, - inputRule:function(root){ - utils.each(root.getNodesByTagName('embed'),function(node){ - if(node.getAttr('class') == 'edui-faked-music'){ - var cssfloat = node.getStyle('float'); - var align = node.getAttr('align'); - html = creatInsertStr(node.getAttr("src"), node.getAttr('width'), node.getAttr('height'), align, cssfloat,false); - var img = UE.uNode.createElement(html); - node.parentNode.replaceChild(img,node); - } - }) - - }, - commands:{ - /** - * 插入音乐 - * @command music - * @method execCommand - * @param { Object } musicOptions 插入音乐的参数项, 支持的key有: url=>音乐地址; - * width=>音乐容器宽度;height=>音乐容器高度;align=>音乐文件的对齐方式, 可选值有: left, center, right, none - * @example - * ```javascript - * //editor是编辑器实例 - * //在编辑器里插入一个“植物大战僵尸”的APP - * editor.execCommand( 'music' , { - * width: 400, - * height: 95, - * align: "center", - * url: "音乐地址" - * } ); - * ``` - */ - 'music':{ - execCommand:function (cmd, musicObj) { - var me = this, - str = creatInsertStr(musicObj.url, musicObj.width || 400, musicObj.height || 95, "none", false); - me.execCommand("inserthtml",str); - }, - queryCommandState:function () { - var me = this, - img = me.selection.getRange().getClosedNode(), - flag = img && (img.className == "edui-faked-music"); - return flag ? 1 : 0; - } - } - } - } -}); - -// plugins/autoupload.js -/** - * @description - * 1.拖放文件到编辑区域,自动上传并插入到选区 - * 2.插入粘贴板的图片,自动上传并插入到选区 - * @author Jinqn - * @date 2013-10-14 - */ -UE.plugin.register('autoupload', function (){ - - function sendAndInsertFile(file, editor) { - var me = editor; - //模拟数据 - var fieldName, urlPrefix, maxSize, allowFiles, actionUrl, - loadingHtml, errorHandler, successHandler, - filetype = /image\/\w+/i.test(file.type) ? 'image':'file', - loadingId = 'loading_' + (+new Date()).toString(36); - - fieldName = me.getOpt(filetype + 'FieldName'); - urlPrefix = me.getOpt(filetype + 'UrlPrefix'); - maxSize = me.getOpt(filetype + 'MaxSize'); - allowFiles = me.getOpt(filetype + 'AllowFiles'); - actionUrl = me.getActionUrl(me.getOpt(filetype + 'ActionName')); - errorHandler = function(title) { - var loader = me.document.getElementById(loadingId); - loader && domUtils.remove(loader); - me.fireEvent('showmessage', { - 'id': loadingId, - 'content': title, - 'type': 'error', - 'timeout': 4000 - }); - }; - - if (filetype == 'image') { - loadingHtml = ''; - successHandler = function(data) { - var link = urlPrefix + data.url, - loader = me.document.getElementById(loadingId); - if (loader) { - loader.setAttribute('src', link); - loader.setAttribute('_src', link); - loader.setAttribute('title', data.title || ''); - loader.setAttribute('alt', data.original || ''); - loader.removeAttribute('id'); - domUtils.removeClasses(loader, 'loadingclass'); - } - }; - } else { - loadingHtml = '

    ' + - '' + - '

    '; - successHandler = function(data) { - var link = urlPrefix + data.url, - loader = me.document.getElementById(loadingId); - - var rng = me.selection.getRange(), - bk = rng.createBookmark(); - rng.selectNode(loader).select(); - me.execCommand('insertfile', {'url': link}); - rng.moveToBookmark(bk).select(); - }; - } - - /* 插入loading的占位符 */ - me.execCommand('inserthtml', loadingHtml); - - /* 判断后端配置是否没有加载成功 */ - if (!me.getOpt(filetype + 'ActionName')) { - errorHandler(me.getLang('autoupload.errorLoadConfig')); - return; - } - /* 判断文件大小是否超出限制 */ - if(file.size > maxSize) { - errorHandler(me.getLang('autoupload.exceedSizeError')); - return; - } - /* 判断文件格式是否超出允许 */ - var fileext = file.name ? file.name.substr(file.name.lastIndexOf('.')):''; - if ((fileext && filetype != 'image') || (allowFiles && (allowFiles.join('') + '.').indexOf(fileext.toLowerCase() + '.') == -1)) { - errorHandler(me.getLang('autoupload.exceedTypeError')); - return; - } - - /* 创建Ajax并提交 */ - var xhr = new XMLHttpRequest(), - fd = new FormData(), - params = utils.serializeParam(me.queryCommandValue('serverparam')) || '', - url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?':'&') + params); - - fd.append(fieldName, file, file.name || ('blob.' + file.type.substr('image/'.length))); - fd.append('type', 'ajax'); - xhr.open("post", url, true); - xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); - xhr.addEventListener('load', function (e) { - try{ - var json = (new Function("return " + utils.trim(e.target.response)))(); - if (json.state == 'SUCCESS' && json.url) { - successHandler(json); - } else { - errorHandler(json.state); - } - }catch(er){ - errorHandler(me.getLang('autoupload.loadError')); - } - }); - xhr.send(fd); - } - - function getPasteImage(e){ - return e.clipboardData && e.clipboardData.items && e.clipboardData.items.length == 1 && /^image\//.test(e.clipboardData.items[0].type) ? e.clipboardData.items:null; - } - function getDropImage(e){ - return e.dataTransfer && e.dataTransfer.files ? e.dataTransfer.files:null; - } - - return { - outputRule: function(root){ - utils.each(root.getNodesByTagName('img'),function(n){ - if (/\b(loaderrorclass)|(bloaderrorclass)\b/.test(n.getAttr('class'))) { - n.parentNode.removeChild(n); - } - }); - utils.each(root.getNodesByTagName('p'),function(n){ - if (/\bloadpara\b/.test(n.getAttr('class'))) { - n.parentNode.removeChild(n); - } - }); - }, - bindEvents:{ - //插入粘贴板的图片,拖放插入图片 - 'ready':function(e){ - var me = this; - if(window.FormData && window.FileReader) { - domUtils.on(me.body, 'paste drop', function(e){ - var hasImg = false, - items; - //获取粘贴板文件列表或者拖放文件列表 - items = e.type == 'paste' ? getPasteImage(e):getDropImage(e); - if(items){ - var len = items.length, - file; - while (len--){ - file = items[len]; - if(file.getAsFile) file = file.getAsFile(); - if(file && file.size > 0) { - sendAndInsertFile(file, me); - hasImg = true; - } - } - hasImg && e.preventDefault(); - } - - }); - //取消拖放图片时出现的文字光标位置提示 - domUtils.on(me.body, 'dragover', function (e) { - if(e.dataTransfer.types[0] == 'Files') { - e.preventDefault(); - } - }); - - //设置loading的样式 - utils.cssRule('loading', - '.loadingclass{display:inline-block;cursor:default;background: url(\'' - + this.options.themePath - + this.options.theme +'/images/loading.gif\') no-repeat center center transparent;border:1px solid #cccccc;margin-left:1px;height: 22px;width: 22px;}\n' + - '.loaderrorclass{display:inline-block;cursor:default;background: url(\'' - + this.options.themePath - + this.options.theme +'/images/loaderror.png\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;' + - '}', - this.document); - } - } - } - } -}); - -// plugins/autosave.js -UE.plugin.register('autosave', function (){ - - var me = this, - //无限循环保护 - lastSaveTime = new Date(), - //最小保存间隔时间 - MIN_TIME = 20, - //auto save key - saveKey = null; - - function save ( editor ) { - - var saveData; - - if ( new Date() - lastSaveTime < MIN_TIME ) { - return; - } - - if ( !editor.hasContents() ) { - //这里不能调用命令来删除, 会造成事件死循环 - saveKey && me.removePreferences( saveKey ); - return; - } - - lastSaveTime = new Date(); - - editor._saveFlag = null; - - saveData = me.body.innerHTML; - - if ( editor.fireEvent( "beforeautosave", { - content: saveData - } ) === false ) { - return; - } - - me.setPreferences( saveKey, saveData ); - - editor.fireEvent( "afterautosave", { - content: saveData - } ); - - } - - return { - defaultOptions: { - //默认间隔时间 - saveInterval: 500 - }, - bindEvents:{ - 'ready':function(){ - - var _suffix = "-drafts-data", - key = null; - - if ( me.key ) { - key = me.key + _suffix; - } else { - key = ( me.container.parentNode.id || 'ue-common' ) + _suffix; - } - - //页面地址+编辑器ID 保持唯一 - saveKey = ( location.protocol + location.host + location.pathname ).replace( /[.:\/]/g, '_' ) + key; - - }, - - 'contentchange': function () { - - if ( !saveKey ) { - return; - } - - if ( me._saveFlag ) { - window.clearTimeout( me._saveFlag ); - } - - if ( me.options.saveInterval > 0 ) { - - me._saveFlag = window.setTimeout( function () { - - save( me ); - - }, me.options.saveInterval ); - - } else { - - save(me); - - } - - - } - }, - commands:{ - 'clearlocaldata':{ - execCommand:function (cmd, name) { - if ( saveKey && me.getPreferences( saveKey ) ) { - me.removePreferences( saveKey ) - } - }, - notNeedUndo: true, - ignoreContentChange:true - }, - - 'getlocaldata':{ - execCommand:function (cmd, name) { - return saveKey ? me.getPreferences( saveKey ) || '' : ''; - }, - notNeedUndo: true, - ignoreContentChange:true - }, - - 'drafts':{ - execCommand:function (cmd, name) { - if ( saveKey ) { - me.body.innerHTML = me.getPreferences( saveKey ) || '

    '+domUtils.fillHtml+'

    '; - me.focus(true); - } - }, - queryCommandState: function () { - return saveKey ? ( me.getPreferences( saveKey ) === null ? -1 : 0 ) : -1; - }, - notNeedUndo: true, - ignoreContentChange:true - } - } - } - -}); - -// plugins/charts.js -UE.plugin.register('charts', function (){ - - var me = this; - - return { - bindEvents: { - 'chartserror': function () { - } - }, - commands:{ - 'charts': { - execCommand: function ( cmd, data ) { - - var tableNode = domUtils.findParentByTagName(this.selection.getRange().startContainer, 'table', true), - flagText = [], - config = {}; - - if ( !tableNode ) { - return false; - } - - if ( !validData( tableNode ) ) { - me.fireEvent( "chartserror" ); - return false; - } - - config.title = data.title || ''; - config.subTitle = data.subTitle || ''; - config.xTitle = data.xTitle || ''; - config.yTitle = data.yTitle || ''; - config.suffix = data.suffix || ''; - config.tip = data.tip || ''; - //数据对齐方式 - config.dataFormat = data.tableDataFormat || ''; - //图表类型 - config.chartType = data.chartType || 0; - - for ( var key in config ) { - - if ( !config.hasOwnProperty( key ) ) { - continue; - } - - flagText.push( key+":"+config[ key ] ); - - } - - tableNode.setAttribute( "data-chart", flagText.join( ";" ) ); - domUtils.addClass( tableNode, "edui-charts-table" ); - - - - }, - queryCommandState: function ( cmd, name ) { - - var tableNode = domUtils.findParentByTagName(this.selection.getRange().startContainer, 'table', true); - return tableNode && validData( tableNode ) ? 0 : -1; - - } - } - }, - inputRule:function(root){ - utils.each(root.getNodesByTagName('table'),function( tableNode ){ - - if ( tableNode.getAttr("data-chart") !== undefined ) { - tableNode.setAttr("style"); - } - - }) - - }, - outputRule:function(root){ - utils.each(root.getNodesByTagName('table'),function( tableNode ){ - - if ( tableNode.getAttr("data-chart") !== undefined ) { - tableNode.setAttr("style", "display: none;"); - } - - }) - - } - } - - function validData ( table ) { - - var firstRows = null, - cellCount = 0; - - //行数不够 - if ( table.rows.length < 2 ) { - return false; - } - - //列数不够 - if ( table.rows[0].cells.length < 2 ) { - return false; - } - - //第一行所有cell必须是th - firstRows = table.rows[ 0 ].cells; - cellCount = firstRows.length; - - for ( var i = 0, cell; cell = firstRows[ i ]; i++ ) { - - if ( cell.tagName.toLowerCase() !== 'th' ) { - return false; - } - - } - - for ( var i = 1, row; row = table.rows[ i ]; i++ ) { - - //每行单元格数不匹配, 返回false - if ( row.cells.length != cellCount ) { - return false; - } - - //第一列不是th也返回false - if ( row.cells[0].tagName.toLowerCase() !== 'th' ) { - return false; - } - - for ( var j = 1, cell; cell = row.cells[ j ]; j++ ) { - - var value = utils.trim( ( cell.innerText || cell.textContent || '' ) ); - - value = value.replace( new RegExp( UE.dom.domUtils.fillChar, 'g' ), '' ).replace( /^\s+|\s+$/g, '' ); - - //必须是数字 - if ( !/^\d*\.?\d+$/.test( value ) ) { - return false; - } - - } - - } - - return true; - - } - -}); - -// plugins/section.js -/** - * 目录大纲支持插件 - * @file - * @since 1.3.0 - */ -UE.plugin.register('section', function (){ - /* 目录节点对象 */ - function Section(option){ - this.tag = ''; - this.level = -1, - this.dom = null; - this.nextSection = null; - this.previousSection = null; - this.parentSection = null; - this.startAddress = []; - this.endAddress = []; - this.children = []; - } - function getSection(option) { - var section = new Section(); - return utils.extend(section, option); - } - function getNodeFromAddress(startAddress, root) { - var current = root; - for(var i = 0;i < startAddress.length; i++) { - if(!current.childNodes) return null; - current = current.childNodes[startAddress[i]]; - } - return current; - } - - var me = this; - - return { - bindMultiEvents:{ - type: 'aftersetcontent afterscencerestore', - handler: function(){ - me.fireEvent('updateSections'); - } - }, - bindEvents:{ - /* 初始化、拖拽、粘贴、执行setcontent之后 */ - 'ready': function (){ - me.fireEvent('updateSections'); - domUtils.on(me.body, 'drop paste', function(){ - me.fireEvent('updateSections'); - }); - }, - /* 执行paragraph命令之后 */ - 'afterexeccommand': function (type, cmd) { - if(cmd == 'paragraph') { - me.fireEvent('updateSections'); - } - }, - /* 部分键盘操作,触发updateSections事件 */ - 'keyup': function (type, e) { - var me = this, - range = me.selection.getRange(); - if(range.collapsed != true) { - me.fireEvent('updateSections'); - } else { - var keyCode = e.keyCode || e.which; - if(keyCode == 13 || keyCode == 8 || keyCode == 46) { - me.fireEvent('updateSections'); - } - } - } - }, - commands:{ - 'getsections': { - execCommand: function (cmd, levels) { - var levelFn = levels || ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']; - - for (var i = 0; i < levelFn.length; i++) { - if (typeof levelFn[i] == 'string') { - levelFn[i] = function(fn){ - return function(node){ - return node.tagName == fn.toUpperCase() - }; - }(levelFn[i]); - } else if (typeof levelFn[i] != 'function') { - levelFn[i] = function (node) { - return null; - } - } - } - function getSectionLevel(node) { - for (var i = 0; i < levelFn.length; i++) { - if (levelFn[i](node)) return i; - } - return -1; - } - - var me = this, - Directory = getSection({'level':-1, 'title':'root'}), - previous = Directory; - - function traversal(node, Directory) { - var level, - tmpSection = null, - parent, - child, - children = node.childNodes; - for (var i = 0, len = children.length; i < len; i++) { - child = children[i]; - level = getSectionLevel(child); - if (level >= 0) { - var address = me.selection.getRange().selectNode(child).createAddress(true).startAddress, - current = getSection({ - 'tag': child.tagName, - 'title': child.innerText || child.textContent || '', - 'level': level, - 'dom': child, - 'startAddress': utils.clone(address, []), - 'endAddress': utils.clone(address, []), - 'children': [] - }); - previous.nextSection = current; - current.previousSection = previous; - parent = previous; - while(level <= parent.level){ - parent = parent.parentSection; - } - current.parentSection = parent; - parent.children.push(current); - tmpSection = previous = current; - } else { - child.nodeType === 1 && traversal(child, Directory); - tmpSection && tmpSection.endAddress[tmpSection.endAddress.length - 1] ++; - } - } - } - traversal(me.body, Directory); - return Directory; - }, - notNeedUndo: true - }, - 'movesection': { - execCommand: function (cmd, sourceSection, targetSection, isAfter) { - - var me = this, - targetAddress, - target; - - if(!sourceSection || !targetSection || targetSection.level == -1) return; - - targetAddress = isAfter ? targetSection.endAddress:targetSection.startAddress; - target = getNodeFromAddress(targetAddress, me.body); - - /* 判断目标地址是否被源章节包含 */ - if(!targetAddress || !target || isContainsAddress(sourceSection.startAddress, sourceSection.endAddress, targetAddress)) return; - - var startNode = getNodeFromAddress(sourceSection.startAddress, me.body), - endNode = getNodeFromAddress(sourceSection.endAddress, me.body), - current, - nextNode; - - if(isAfter) { - current = endNode; - while ( current && !(domUtils.getPosition( startNode, current ) & domUtils.POSITION_FOLLOWING) ) { - nextNode = current.previousSibling; - domUtils.insertAfter(target, current); - if(current == startNode) break; - current = nextNode; - } - } else { - current = startNode; - while ( current && !(domUtils.getPosition( current, endNode ) & domUtils.POSITION_FOLLOWING) ) { - nextNode = current.nextSibling; - target.parentNode.insertBefore(current, target); - if(current == endNode) break; - current = nextNode; - } - } - - me.fireEvent('updateSections'); - - /* 获取地址的包含关系 */ - function isContainsAddress(startAddress, endAddress, addressTarget){ - var isAfterStartAddress = false, - isBeforeEndAddress = false; - for(var i = 0; i< startAddress.length; i++){ - if(i >= addressTarget.length) break; - if(addressTarget[i] > startAddress[i]) { - isAfterStartAddress = true; - break; - } else if(addressTarget[i] < startAddress[i]) { - break; - } - } - for(var i = 0; i< endAddress.length; i++){ - if(i >= addressTarget.length) break; - if(addressTarget[i] < startAddress[i]) { - isBeforeEndAddress = true; - break; - } else if(addressTarget[i] > startAddress[i]) { - break; - } - } - return isAfterStartAddress && isBeforeEndAddress; - } - } - }, - 'deletesection': { - execCommand: function (cmd, section, keepChildren) { - var me = this; - - if(!section) return; - - function getNodeFromAddress(startAddress) { - var current = me.body; - for(var i = 0;i < startAddress.length; i++) { - if(!current.childNodes) return null; - current = current.childNodes[startAddress[i]]; - } - return current; - } - - var startNode = getNodeFromAddress(section.startAddress), - endNode = getNodeFromAddress(section.endAddress), - current = startNode, - nextNode; - - if(!keepChildren) { - while ( current && domUtils.inDoc(endNode, me.document) && !(domUtils.getPosition( current, endNode ) & domUtils.POSITION_FOLLOWING) ) { - nextNode = current.nextSibling; - domUtils.remove(current); - current = nextNode; - } - } else { - domUtils.remove(current); - } - - me.fireEvent('updateSections'); - } - }, - 'selectsection': { - execCommand: function (cmd, section) { - if(!section && !section.dom) return false; - var me = this, - range = me.selection.getRange(), - address = { - 'startAddress':utils.clone(section.startAddress, []), - 'endAddress':utils.clone(section.endAddress, []) - }; - address.endAddress[address.endAddress.length - 1]++; - range.moveToAddress(address).select().scrollToView(); - return true; - }, - notNeedUndo: true - }, - 'scrolltosection': { - execCommand: function (cmd, section) { - if(!section && !section.dom) return false; - var me = this, - range = me.selection.getRange(), - address = { - 'startAddress':section.startAddress, - 'endAddress':section.endAddress - }; - address.endAddress[address.endAddress.length - 1]++; - range.moveToAddress(address).scrollToView(); - return true; - }, - notNeedUndo: true - } - } - } -}); - -// plugins/simpleupload.js -/** - * @description - * 简单上传:点击按钮,直接选择文件上传 - * @author Jinqn - * @date 2014-03-31 - */ -UE.plugin.register('simpleupload', function (){ - var me = this, - isLoaded = false, - containerBtn; - - function initUploadBtn(){ - var w = containerBtn.offsetWidth || 20, - h = containerBtn.offsetHeight || 20, - btnIframe = document.createElement('iframe'), - btnStyle = 'display:block;width:' + w + 'px;height:' + h + 'px;overflow:hidden;border:0;margin:0;padding:0;position:absolute;top:0;left:0;filter:alpha(opacity=0);-moz-opacity:0;-khtml-opacity: 0;opacity: 0;cursor:pointer;'; - - domUtils.on(btnIframe, 'load', function(){ - - var timestrap = (+new Date()).toString(36), - wrapper, - btnIframeDoc, - btnIframeBody; - - btnIframeDoc = (btnIframe.contentDocument || btnIframe.contentWindow.document); - btnIframeBody = btnIframeDoc.body; - wrapper = btnIframeDoc.createElement('div'); - - wrapper.innerHTML = '
    ' + - '' + - '
    ' + - ''; - - wrapper.className = 'edui-' + me.options.theme; - wrapper.id = me.ui.id + '_iframeupload'; - btnIframeBody.style.cssText = btnStyle; - btnIframeBody.style.width = w + 'px'; - btnIframeBody.style.height = h + 'px'; - btnIframeBody.appendChild(wrapper); - - if (btnIframeBody.parentNode) { - btnIframeBody.parentNode.style.width = w + 'px'; - btnIframeBody.parentNode.style.height = w + 'px'; - } - - var form = btnIframeDoc.getElementById('edui_form_' + timestrap); - var input = btnIframeDoc.getElementById('edui_input_' + timestrap); - var iframe = btnIframeDoc.getElementById('edui_iframe_' + timestrap); - - domUtils.on(input, 'change', function(){ - if(!input.value) return; - var loadingId = 'loading_' + (+new Date()).toString(36); - var params = utils.serializeParam(me.queryCommandValue('serverparam')) || ''; - - var imageActionUrl = me.getActionUrl(me.getOpt('imageActionName')); - var allowFiles = me.getOpt('imageAllowFiles'); - - me.focus(); - me.execCommand('inserthtml', ''); - - function callback(){ - try{ - var link, json, loader, - body = (iframe.contentDocument || iframe.contentWindow.document).body, - result = body.innerText || body.textContent || ''; - json = (new Function("return " + result))(); - link = me.options.imageUrlPrefix + json.url; - if(json.state == 'SUCCESS' && json.url) { - loader = me.document.getElementById(loadingId); - loader.setAttribute('src', link); - loader.setAttribute('_src', link); - loader.setAttribute('title', json.title || ''); - loader.setAttribute('alt', json.original || ''); - loader.removeAttribute('id'); - domUtils.removeClasses(loader, 'loadingclass'); - } else { - showErrorLoader && showErrorLoader(json.state); - } - }catch(er){ - showErrorLoader && showErrorLoader(me.getLang('simpleupload.loadError')); - } - form.reset(); - domUtils.un(iframe, 'load', callback); - } - function showErrorLoader(title){ - if(loadingId) { - var loader = me.document.getElementById(loadingId); - loader && domUtils.remove(loader); - me.fireEvent('showmessage', { - 'id': loadingId, - 'content': title, - 'type': 'error', - 'timeout': 4000 - }); - } - } - - /* 判断后端配置是否没有加载成功 */ - if (!me.getOpt('imageActionName')) { - errorHandler(me.getLang('autoupload.errorLoadConfig')); - return; - } - // 判断文件格式是否错误 - var filename = input.value, - fileext = filename ? filename.substr(filename.lastIndexOf('.')):''; - if (!fileext || (allowFiles && (allowFiles.join('') + '.').indexOf(fileext.toLowerCase() + '.') == -1)) { - showErrorLoader(me.getLang('simpleupload.exceedTypeError')); - return; - } - - domUtils.on(iframe, 'load', callback); - form.action = utils.formatUrl(imageActionUrl + (imageActionUrl.indexOf('?') == -1 ? '?':'&') + params); - form.submit(); - }); - - var stateTimer; - me.addListener('selectionchange', function () { - clearTimeout(stateTimer); - stateTimer = setTimeout(function() { - var state = me.queryCommandState('simpleupload'); - if (state == -1) { - input.disabled = 'disabled'; - } else { - input.disabled = false; - } - }, 400); - }); - isLoaded = true; - }); - - btnIframe.style.cssText = btnStyle; - containerBtn.appendChild(btnIframe); - } - - return { - bindEvents:{ - 'ready': function() { - //设置loading的样式 - utils.cssRule('loading', - '.loadingclass{display:inline-block;cursor:default;background: url(\'' - + this.options.themePath - + this.options.theme +'/images/loading.gif\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;}\n' + - '.loaderrorclass{display:inline-block;cursor:default;background: url(\'' - + this.options.themePath - + this.options.theme +'/images/loaderror.png\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;' + - '}', - this.document); - }, - /* 初始化简单上传按钮 */ - 'simpleuploadbtnready': function(type, container) { - containerBtn = container; - me.afterConfigReady(initUploadBtn); - } - }, - outputRule: function(root){ - utils.each(root.getNodesByTagName('img'),function(n){ - if (/\b(loaderrorclass)|(bloaderrorclass)\b/.test(n.getAttr('class'))) { - n.parentNode.removeChild(n); - } - }); - }, - commands: { - 'simpleupload': { - queryCommandState: function () { - return isLoaded ? 0:-1; - } - } - } - } -}); - -// plugins/serverparam.js -/** - * 服务器提交的额外参数列表设置插件 - * @file - * @since 1.2.6.1 - */ -UE.plugin.register('serverparam', function (){ - - var me = this, - serverParam = {}; - - return { - commands:{ - /** - * 修改服务器提交的额外参数列表,清除所有项 - * @command serverparam - * @method execCommand - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.execCommand('serverparam'); - * editor.queryCommandValue('serverparam'); //返回空 - * ``` - */ - /** - * 修改服务器提交的额外参数列表,删除指定项 - * @command serverparam - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { String } key 要清除的属性 - * @example - * ```javascript - * editor.execCommand('serverparam', 'name'); //删除属性name - * ``` - */ - /** - * 修改服务器提交的额外参数列表,使用键值添加项 - * @command serverparam - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { String } key 要添加的属性 - * @param { String } value 要添加属性的值 - * @example - * ```javascript - * editor.execCommand('serverparam', 'name', 'hello'); - * editor.queryCommandValue('serverparam'); //返回对象 {'name': 'hello'} - * ``` - */ - /** - * 修改服务器提交的额外参数列表,传入键值对对象添加多项 - * @command serverparam - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { Object } key 传入的键值对对象 - * @example - * ```javascript - * editor.execCommand('serverparam', {'name': 'hello'}); - * editor.queryCommandValue('serverparam'); //返回对象 {'name': 'hello'} - * ``` - */ - /** - * 修改服务器提交的额外参数列表,使用自定义函数添加多项 - * @command serverparam - * @method execCommand - * @param { String } cmd 命令字符串 - * @param { Function } key 自定义获取参数的函数 - * @example - * ```javascript - * editor.execCommand('serverparam', function(editor){ - * return {'key': 'value'}; - * }); - * editor.queryCommandValue('serverparam'); //返回对象 {'key': 'value'} - * ``` - */ - - /** - * 获取服务器提交的额外参数列表 - * @command serverparam - * @method queryCommandValue - * @param { String } cmd 命令字符串 - * @example - * ```javascript - * editor.queryCommandValue( 'serverparam' ); //返回对象 {'key': 'value'} - * ``` - */ - 'serverparam':{ - execCommand:function (cmd, key, value) { - if (key === undefined || key === null) { //不传参数,清空列表 - serverParam = {}; - } else if (utils.isString(key)) { //传入键值 - if(value === undefined || value === null) { - delete serverParam[key]; - } else { - serverParam[key] = value; - } - } else if (utils.isObject(key)) { //传入对象,覆盖列表项 - utils.extend(serverParam, key, true); - } else if (utils.isFunction(key)){ //传入函数,添加列表项 - utils.extend(serverParam, key(), true); - } - }, - queryCommandValue: function(){ - return serverParam || {}; - } - } - } - } -}); - - -// plugins/insertfile.js -/** - * 插入附件 - */ -UE.plugin.register('insertfile', function (){ - - var me = this; - - function getFileIcon(url){ - var ext = url.substr(url.lastIndexOf('.') + 1).toLowerCase(), - maps = { - "rar":"icon_rar.gif", - "zip":"icon_rar.gif", - "tar":"icon_rar.gif", - "gz":"icon_rar.gif", - "bz2":"icon_rar.gif", - "doc":"icon_doc.gif", - "docx":"icon_doc.gif", - "pdf":"icon_pdf.gif", - "mp3":"icon_mp3.gif", - "xls":"icon_xls.gif", - "chm":"icon_chm.gif", - "ppt":"icon_ppt.gif", - "pptx":"icon_ppt.gif", - "avi":"icon_mv.gif", - "rmvb":"icon_mv.gif", - "wmv":"icon_mv.gif", - "flv":"icon_mv.gif", - "swf":"icon_mv.gif", - "rm":"icon_mv.gif", - "exe":"icon_exe.gif", - "psd":"icon_psd.gif", - "txt":"icon_txt.gif", - "jpg":"icon_jpg.gif", - "png":"icon_jpg.gif", - "jpeg":"icon_jpg.gif", - "gif":"icon_jpg.gif", - "ico":"icon_jpg.gif", - "bmp":"icon_jpg.gif" - }; - return maps[ext] ? maps[ext]:maps['txt']; - } - - return { - commands:{ - 'insertfile': { - execCommand: function (command, filelist){ - filelist = utils.isArray(filelist) ? filelist : [filelist]; - - var i, item, icon, title, - html = '', - URL = me.getOpt('UEDITOR_HOME_URL'), - iconDir = URL + (URL.substr(URL.length - 1) == '/' ? '':'/') + 'dialogs/attachment/fileTypeImages/'; - for (i = 0; i < filelist.length; i++) { - item = filelist[i]; - icon = iconDir + getFileIcon(item.url); - title = item.title || item.url.substr(item.url.lastIndexOf('/') + 1); - html += '

    ' + - '' + - '' + title + '' + - '

    '; - } - me.execCommand('insertHtml', html); - } - } - } - } -}); - - - - -// plugins/xssFilter.js -/** - * @file xssFilter.js - * @desc xss过滤器 - * @author robbenmu - */ - -UE.plugins.xssFilter = function() { - - var config = UEDITOR_CONFIG; - var whitList = config.whitList; - - function filter(node) { - - var tagName = node.tagName; - var attrs = node.attrs; - - if (!whitList.hasOwnProperty(tagName)) { - node.parentNode.removeChild(node); - return false; - } - - UE.utils.each(attrs, function (val, key) { - - if (whitList[tagName].indexOf(key) === -1) { - node.setAttr(key); - } - }); - } - - // 添加inserthtml\paste等操作用的过滤规则 - if (whitList && config.xssFilterRules) { - this.options.filterRules = function () { - - var result = {}; - - UE.utils.each(whitList, function(val, key) { - result[key] = function (node) { - return filter(node); - }; - }); - - return result; - }(); - } - - var tagList = []; - - UE.utils.each(whitList, function (val, key) { - tagList.push(key); - }); - - // 添加input过滤规则 - // - if (whitList && config.inputXssFilter) { - this.addInputRule(function (root) { - - root.traversal(function(node) { - if (node.type !== 'element') { - return false; - } - filter(node); - }); - }); - } - // 添加output过滤规则 - // - if (whitList && config.outputXssFilter) { - this.addOutputRule(function (root) { - - root.traversal(function(node) { - if (node.type !== 'element') { - return false; - } - filter(node); - }); - }); - } - -}; - - -// ui/ui.js -var baidu = baidu || {}; -baidu.editor = baidu.editor || {}; -UE.ui = baidu.editor.ui = {}; - -// ui/uiutils.js -(function (){ - var browser = baidu.editor.browser, - domUtils = baidu.editor.dom.domUtils; - - var magic = '$EDITORUI'; - var root = window[magic] = {}; - var uidMagic = 'ID' + magic; - var uidCount = 0; - - var uiUtils = baidu.editor.ui.uiUtils = { - uid: function (obj){ - return (obj ? obj[uidMagic] || (obj[uidMagic] = ++ uidCount) : ++ uidCount); - }, - hook: function ( fn, callback ) { - var dg; - if (fn && fn._callbacks) { - dg = fn; - } else { - dg = function (){ - var q; - if (fn) { - q = fn.apply(this, arguments); - } - var callbacks = dg._callbacks; - var k = callbacks.length; - while (k --) { - var r = callbacks[k].apply(this, arguments); - if (q === undefined) { - q = r; - } - } - return q; - }; - dg._callbacks = []; - } - dg._callbacks.push(callback); - return dg; - }, - createElementByHtml: function (html){ - var el = document.createElement('div'); - el.innerHTML = html; - el = el.firstChild; - el.parentNode.removeChild(el); - return el; - }, - getViewportElement: function (){ - return (browser.ie && browser.quirks) ? - document.body : document.documentElement; - }, - getClientRect: function (element){ - var bcr; - //trace IE6下在控制编辑器显隐时可能会报错,catch一下 - try{ - bcr = element.getBoundingClientRect(); - }catch(e){ - bcr={left:0,top:0,height:0,width:0} - } - var rect = { - left: Math.round(bcr.left), - top: Math.round(bcr.top), - height: Math.round(bcr.bottom - bcr.top), - width: Math.round(bcr.right - bcr.left) - }; - var doc; - while ((doc = element.ownerDocument) !== document && - (element = domUtils.getWindow(doc).frameElement)) { - bcr = element.getBoundingClientRect(); - rect.left += bcr.left; - rect.top += bcr.top; - } - rect.bottom = rect.top + rect.height; - rect.right = rect.left + rect.width; - return rect; - }, - getViewportRect: function (){ - var viewportEl = uiUtils.getViewportElement(); - var width = (window.innerWidth || viewportEl.clientWidth) | 0; - var height = (window.innerHeight ||viewportEl.clientHeight) | 0; - return { - left: 0, - top: 0, - height: height, - width: width, - bottom: height, - right: width - }; - }, - setViewportOffset: function (element, offset){ - var rect; - var fixedLayer = uiUtils.getFixedLayer(); - if (element.parentNode === fixedLayer) { - element.style.left = offset.left + 'px'; - element.style.top = offset.top + 'px'; - } else { - domUtils.setViewportOffset(element, offset); - } - }, - getEventOffset: function (evt){ - var el = evt.target || evt.srcElement; - var rect = uiUtils.getClientRect(el); - var offset = uiUtils.getViewportOffsetByEvent(evt); - return { - left: offset.left - rect.left, - top: offset.top - rect.top - }; - }, - getViewportOffsetByEvent: function (evt){ - var el = evt.target || evt.srcElement; - var frameEl = domUtils.getWindow(el).frameElement; - var offset = { - left: evt.clientX, - top: evt.clientY - }; - if (frameEl && el.ownerDocument !== document) { - var rect = uiUtils.getClientRect(frameEl); - offset.left += rect.left; - offset.top += rect.top; - } - return offset; - }, - setGlobal: function (id, obj){ - root[id] = obj; - return magic + '["' + id + '"]'; - }, - unsetGlobal: function (id){ - delete root[id]; - }, - copyAttributes: function (tgt, src){ - var attributes = src.attributes; - var k = attributes.length; - while (k --) { - var attrNode = attributes[k]; - if ( attrNode.nodeName != 'style' && attrNode.nodeName != 'class' && (!browser.ie || attrNode.specified) ) { - tgt.setAttribute(attrNode.nodeName, attrNode.nodeValue); - } - } - if (src.className) { - domUtils.addClass(tgt,src.className); - } - if (src.style.cssText) { - tgt.style.cssText += ';' + src.style.cssText; - } - }, - removeStyle: function (el, styleName){ - if (el.style.removeProperty) { - el.style.removeProperty(styleName); - } else if (el.style.removeAttribute) { - el.style.removeAttribute(styleName); - } else throw ''; - }, - contains: function (elA, elB){ - return elA && elB && (elA === elB ? false : ( - elA.contains ? elA.contains(elB) : - elA.compareDocumentPosition(elB) & 16 - )); - }, - startDrag: function (evt, callbacks,doc){ - var doc = doc || document; - var startX = evt.clientX; - var startY = evt.clientY; - function handleMouseMove(evt){ - var x = evt.clientX - startX; - var y = evt.clientY - startY; - callbacks.ondragmove(x, y,evt); - if (evt.stopPropagation) { - evt.stopPropagation(); - } else { - evt.cancelBubble = true; - } - } - if (doc.addEventListener) { - function handleMouseUp(evt){ - doc.removeEventListener('mousemove', handleMouseMove, true); - doc.removeEventListener('mouseup', handleMouseUp, true); - window.removeEventListener('mouseup', handleMouseUp, true); - callbacks.ondragstop(); - } - doc.addEventListener('mousemove', handleMouseMove, true); - doc.addEventListener('mouseup', handleMouseUp, true); - window.addEventListener('mouseup', handleMouseUp, true); - - evt.preventDefault(); - } else { - var elm = evt.srcElement; - elm.setCapture(); - function releaseCaptrue(){ - elm.releaseCapture(); - elm.detachEvent('onmousemove', handleMouseMove); - elm.detachEvent('onmouseup', releaseCaptrue); - elm.detachEvent('onlosecaptrue', releaseCaptrue); - callbacks.ondragstop(); - } - elm.attachEvent('onmousemove', handleMouseMove); - elm.attachEvent('onmouseup', releaseCaptrue); - elm.attachEvent('onlosecaptrue', releaseCaptrue); - evt.returnValue = false; - } - callbacks.ondragstart(); - }, - getFixedLayer: function (){ - var layer = document.getElementById('edui_fixedlayer'); - if (layer == null) { - layer = document.createElement('div'); - layer.id = 'edui_fixedlayer'; - document.body.appendChild(layer); - if (browser.ie && browser.version <= 8) { - layer.style.position = 'absolute'; - bindFixedLayer(); - setTimeout(updateFixedOffset); - } else { - layer.style.position = 'fixed'; - } - layer.style.left = '0'; - layer.style.top = '0'; - layer.style.width = '0'; - layer.style.height = '0'; - } - return layer; - }, - makeUnselectable: function (element){ - if (browser.opera || (browser.ie && browser.version < 9)) { - element.unselectable = 'on'; - if (element.hasChildNodes()) { - for (var i=0; i'; - } - }; - utils.inherits(Separator, UIBase); - -})(); - - -// ui/mask.js -///import core -///import uicore -(function (){ - var utils = baidu.editor.utils, - domUtils = baidu.editor.dom.domUtils, - UIBase = baidu.editor.ui.UIBase, - uiUtils = baidu.editor.ui.uiUtils; - - var Mask = baidu.editor.ui.Mask = function (options){ - this.initOptions(options); - this.initUIBase(); - }; - Mask.prototype = { - getHtmlTpl: function (){ - return '
    '; - }, - postRender: function (){ - var me = this; - domUtils.on(window, 'resize', function (){ - setTimeout(function (){ - if (!me.isHidden()) { - me._fill(); - } - }); - }); - }, - show: function (zIndex){ - this._fill(); - this.getDom().style.display = ''; - this.getDom().style.zIndex = zIndex; - }, - hide: function (){ - this.getDom().style.display = 'none'; - this.getDom().style.zIndex = ''; - }, - isHidden: function (){ - return this.getDom().style.display == 'none'; - }, - _onMouseDown: function (){ - return false; - }, - _onClick: function (e, target){ - this.fireEvent('click', e, target); - }, - _fill: function (){ - var el = this.getDom(); - var vpRect = uiUtils.getViewportRect(); - el.style.width = vpRect.width + 'px'; - el.style.height = vpRect.height + 'px'; - } - }; - utils.inherits(Mask, UIBase); -})(); - - -// ui/popup.js -///import core -///import uicore -(function () { - var utils = baidu.editor.utils, - uiUtils = baidu.editor.ui.uiUtils, - domUtils = baidu.editor.dom.domUtils, - UIBase = baidu.editor.ui.UIBase, - Popup = baidu.editor.ui.Popup = function (options){ - this.initOptions(options); - this.initPopup(); - }; - - var allPopups = []; - function closeAllPopup( evt,el ){ - for ( var i = 0; i < allPopups.length; i++ ) { - var pop = allPopups[i]; - if (!pop.isHidden()) { - if (pop.queryAutoHide(el) !== false) { - if(evt&&/scroll/ig.test(evt.type)&&pop.className=="edui-wordpastepop") return; - pop.hide(); - } - } - } - - if(allPopups.length) - pop.editor.fireEvent("afterhidepop"); - } - - Popup.postHide = closeAllPopup; - - var ANCHOR_CLASSES = ['edui-anchor-topleft','edui-anchor-topright', - 'edui-anchor-bottomleft','edui-anchor-bottomright']; - Popup.prototype = { - SHADOW_RADIUS: 5, - content: null, - _hidden: false, - autoRender: true, - canSideLeft: true, - canSideUp: true, - initPopup: function (){ - this.initUIBase(); - allPopups.push( this ); - }, - getHtmlTpl: function (){ - return '
    ' + - '
    ' + - ' ' + - '
    ' + - '
    ' + - this.getContentHtmlTpl() + - '
    ' + - '
    ' + - '
    '; - }, - getContentHtmlTpl: function (){ - if(this.content){ - if (typeof this.content == 'string') { - return this.content; - } - return this.content.renderHtml(); - }else{ - return '' - } - - }, - _UIBase_postRender: UIBase.prototype.postRender, - postRender: function (){ - - - if (this.content instanceof UIBase) { - this.content.postRender(); - } - - //捕获鼠标滚轮 - if( this.captureWheel && !this.captured ) { - - this.captured = true; - - var winHeight = ( document.documentElement.clientHeight || document.body.clientHeight ) - 80, - _height = this.getDom().offsetHeight, - _top = uiUtils.getClientRect( this.combox.getDom() ).top, - content = this.getDom('content'), - ifr = this.getDom('body').getElementsByTagName('iframe'), - me = this; - - ifr.length && ( ifr = ifr[0] ); - - while( _top + _height > winHeight ) { - _height -= 30; - } - content.style.height = _height + 'px'; - //同步更改iframe高度 - ifr && ( ifr.style.height = _height + 'px' ); - - //阻止在combox上的鼠标滚轮事件, 防止用户的正常操作被误解 - if( window.XMLHttpRequest ) { - - domUtils.on( content, ( 'onmousewheel' in document.body ) ? 'mousewheel' :'DOMMouseScroll' , function(e){ - - if(e.preventDefault) { - e.preventDefault(); - } else { - e.returnValue = false; - } - - if( e.wheelDelta ) { - - content.scrollTop -= ( e.wheelDelta / 120 )*60; - - } else { - - content.scrollTop -= ( e.detail / -3 )*60; - - } - - }); - - } else { - - //ie6 - domUtils.on( this.getDom(), 'mousewheel' , function(e){ - - e.returnValue = false; - - me.getDom('content').scrollTop -= ( e.wheelDelta / 120 )*60; - - }); - - } - - } - this.fireEvent('postRenderAfter'); - this.hide(true); - this._UIBase_postRender(); - }, - _doAutoRender: function (){ - if (!this.getDom() && this.autoRender) { - this.render(); - } - }, - mesureSize: function (){ - var box = this.getDom('content'); - return uiUtils.getClientRect(box); - }, - fitSize: function (){ - if( this.captureWheel && this.sized ) { - return this.__size; - } - this.sized = true; - var popBodyEl = this.getDom('body'); - popBodyEl.style.width = ''; - popBodyEl.style.height = ''; - var size = this.mesureSize(); - if( this.captureWheel ) { - popBodyEl.style.width = -(-20 -size.width) + 'px'; - var height = parseInt( this.getDom('content').style.height, 10 ); - !window.isNaN( height ) && ( size.height = height ); - } else { - popBodyEl.style.width = size.width + 'px'; - } - popBodyEl.style.height = size.height + 'px'; - this.__size = size; - this.captureWheel && (this.getDom('content').style.overflow = 'auto'); - return size; - }, - showAnchor: function ( element, hoz ){ - this.showAnchorRect( uiUtils.getClientRect( element ), hoz ); - }, - showAnchorRect: function ( rect, hoz, adj ){ - this._doAutoRender(); - var vpRect = uiUtils.getViewportRect(); - this.getDom().style.visibility = 'hidden'; - this._show(); - var popSize = this.fitSize(); - - var sideLeft, sideUp, left, top; - if (hoz) { - sideLeft = this.canSideLeft && (rect.right + popSize.width > vpRect.right && rect.left > popSize.width); - sideUp = this.canSideUp && (rect.top + popSize.height > vpRect.bottom && rect.bottom > popSize.height); - left = (sideLeft ? rect.left - popSize.width : rect.right); - top = (sideUp ? rect.bottom - popSize.height : rect.top); - } else { - sideLeft = this.canSideLeft && (rect.right + popSize.width > vpRect.right && rect.left > popSize.width); - sideUp = this.canSideUp && (rect.top + popSize.height > vpRect.bottom && rect.bottom > popSize.height); - left = (sideLeft ? rect.right - popSize.width : rect.left); - top = (sideUp ? rect.top - popSize.height : rect.bottom); - } - - var popEl = this.getDom(); - uiUtils.setViewportOffset(popEl, { - left: left, - top: top - }); - domUtils.removeClasses(popEl, ANCHOR_CLASSES); - popEl.className += ' ' + ANCHOR_CLASSES[(sideUp ? 1 : 0) * 2 + (sideLeft ? 1 : 0)]; - if(this.editor){ - popEl.style.zIndex = this.editor.container.style.zIndex * 1 + 10; - baidu.editor.ui.uiUtils.getFixedLayer().style.zIndex = popEl.style.zIndex - 1; - } - this.getDom().style.visibility = 'visible'; - - }, - showAt: function (offset) { - var left = offset.left; - var top = offset.top; - var rect = { - left: left, - top: top, - right: left, - bottom: top, - height: 0, - width: 0 - }; - this.showAnchorRect(rect, false, true); - }, - _show: function (){ - if (this._hidden) { - var box = this.getDom(); - box.style.display = ''; - this._hidden = false; -// if (box.setActive) { -// box.setActive(); -// } - this.fireEvent('show'); - } - }, - isHidden: function (){ - return this._hidden; - }, - show: function (){ - this._doAutoRender(); - this._show(); - }, - hide: function (notNofity){ - if (!this._hidden && this.getDom()) { - this.getDom().style.display = 'none'; - this._hidden = true; - if (!notNofity) { - this.fireEvent('hide'); - } - } - }, - queryAutoHide: function (el){ - return !el || !uiUtils.contains(this.getDom(), el); - } - }; - utils.inherits(Popup, UIBase); - - domUtils.on( document, 'mousedown', function ( evt ) { - var el = evt.target || evt.srcElement; - closeAllPopup( evt,el ); - } ); - domUtils.on( window, 'scroll', function (evt,el) { - closeAllPopup( evt,el ); - } ); - -})(); - - -// ui/colorpicker.js -///import core -///import uicore -(function (){ - var utils = baidu.editor.utils, - UIBase = baidu.editor.ui.UIBase, - ColorPicker = baidu.editor.ui.ColorPicker = function (options){ - this.initOptions(options); - this.noColorText = this.noColorText || this.editor.getLang("clearColor"); - this.initUIBase(); - }; - - ColorPicker.prototype = { - getHtmlTpl: function (){ - return genColorPicker(this.noColorText,this.editor); - }, - _onTableClick: function (evt){ - var tgt = evt.target || evt.srcElement; - var color = tgt.getAttribute('data-color'); - if (color) { - this.fireEvent('pickcolor', color); - } - }, - _onTableOver: function (evt){ - var tgt = evt.target || evt.srcElement; - var color = tgt.getAttribute('data-color'); - if (color) { - this.getDom('preview').style.backgroundColor = color; - } - }, - _onTableOut: function (){ - this.getDom('preview').style.backgroundColor = ''; - }, - _onPickNoColor: function (){ - this.fireEvent('picknocolor'); - } - }; - utils.inherits(ColorPicker, UIBase); - - var COLORS = ( - 'ffffff,000000,eeece1,1f497d,4f81bd,c0504d,9bbb59,8064a2,4bacc6,f79646,' + - 'f2f2f2,7f7f7f,ddd9c3,c6d9f0,dbe5f1,f2dcdb,ebf1dd,e5e0ec,dbeef3,fdeada,' + - 'd8d8d8,595959,c4bd97,8db3e2,b8cce4,e5b9b7,d7e3bc,ccc1d9,b7dde8,fbd5b5,' + - 'bfbfbf,3f3f3f,938953,548dd4,95b3d7,d99694,c3d69b,b2a2c7,92cddc,fac08f,' + - 'a5a5a5,262626,494429,17365d,366092,953734,76923c,5f497a,31859b,e36c09,' + - '7f7f7f,0c0c0c,1d1b10,0f243e,244061,632423,4f6128,3f3151,205867,974806,' + - 'c00000,ff0000,ffc000,ffff00,92d050,00b050,00b0f0,0070c0,002060,7030a0,').split(','); - - function genColorPicker(noColorText,editor){ - var html = '
    ' + - '
    ' + - '
    ' + - '
    '+ noColorText +'
    ' + - '
    ' + - '' + - ''+ - ''; - for (var i=0; i':'')+''; - } - html += i<70 ? '':''; - } - html += '
    '+editor.getLang("themeColor")+'
    '+editor.getLang("standardColor")+'
    '; - return html; - } -})(); - - -// ui/tablepicker.js -///import core -///import uicore -(function (){ - var utils = baidu.editor.utils, - uiUtils = baidu.editor.ui.uiUtils, - UIBase = baidu.editor.ui.UIBase; - - var TablePicker = baidu.editor.ui.TablePicker = function (options){ - this.initOptions(options); - this.initTablePicker(); - }; - TablePicker.prototype = { - defaultNumRows: 10, - defaultNumCols: 10, - maxNumRows: 20, - maxNumCols: 20, - numRows: 10, - numCols: 10, - lengthOfCellSide: 22, - initTablePicker: function (){ - this.initUIBase(); - }, - getHtmlTpl: function (){ - var me = this; - return '
    ' + - '
    ' + - '
    ' + - '' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + - '
    '; - }, - _UIBase_render: UIBase.prototype.render, - render: function (holder){ - this._UIBase_render(holder); - this.getDom('label').innerHTML = '0'+this.editor.getLang("t_row")+' x 0'+this.editor.getLang("t_col"); - }, - _track: function (numCols, numRows){ - var style = this.getDom('overlay').style; - var sideLen = this.lengthOfCellSide; - style.width = numCols * sideLen + 'px'; - style.height = numRows * sideLen + 'px'; - var label = this.getDom('label'); - label.innerHTML = numCols +this.editor.getLang("t_col")+' x ' + numRows + this.editor.getLang("t_row"); - this.numCols = numCols; - this.numRows = numRows; - }, - _onMouseOver: function (evt, el){ - var rel = evt.relatedTarget || evt.fromElement; - if (!uiUtils.contains(el, rel) && el !== rel) { - this.getDom('label').innerHTML = '0'+this.editor.getLang("t_col")+' x 0'+this.editor.getLang("t_row"); - this.getDom('overlay').style.visibility = ''; - } - }, - _onMouseOut: function (evt, el){ - var rel = evt.relatedTarget || evt.toElement; - if (!uiUtils.contains(el, rel) && el !== rel) { - this.getDom('label').innerHTML = '0'+this.editor.getLang("t_col")+' x 0'+this.editor.getLang("t_row"); - this.getDom('overlay').style.visibility = 'hidden'; - } - }, - _onMouseMove: function (evt, el){ - var style = this.getDom('overlay').style; - var offset = uiUtils.getEventOffset(evt); - var sideLen = this.lengthOfCellSide; - var numCols = Math.ceil(offset.left / sideLen); - var numRows = Math.ceil(offset.top / sideLen); - this._track(numCols, numRows); - }, - _onClick: function (){ - this.fireEvent('picktable', this.numCols, this.numRows); - } - }; - utils.inherits(TablePicker, UIBase); -})(); - - -// ui/stateful.js -(function (){ - var browser = baidu.editor.browser, - domUtils = baidu.editor.dom.domUtils, - uiUtils = baidu.editor.ui.uiUtils; - - var TPL_STATEFUL = 'onmousedown="$$.Stateful_onMouseDown(event, this);"' + - ' onmouseup="$$.Stateful_onMouseUp(event, this);"' + - ( browser.ie ? ( - ' onmouseenter="$$.Stateful_onMouseEnter(event, this);"' + - ' onmouseleave="$$.Stateful_onMouseLeave(event, this);"' ) - : ( - ' onmouseover="$$.Stateful_onMouseOver(event, this);"' + - ' onmouseout="$$.Stateful_onMouseOut(event, this);"' )); - - baidu.editor.ui.Stateful = { - alwalysHoverable: false, - target:null,//目标元素和this指向dom不一样 - Stateful_init: function (){ - this._Stateful_dGetHtmlTpl = this.getHtmlTpl; - this.getHtmlTpl = this.Stateful_getHtmlTpl; - }, - Stateful_getHtmlTpl: function (){ - var tpl = this._Stateful_dGetHtmlTpl(); - // 使用function避免$转义 - return tpl.replace(/stateful/g, function (){ return TPL_STATEFUL; }); - }, - Stateful_onMouseEnter: function (evt, el){ - this.target=el; - if (!this.isDisabled() || this.alwalysHoverable) { - this.addState('hover'); - this.fireEvent('over'); - } - }, - Stateful_onMouseLeave: function (evt, el){ - if (!this.isDisabled() || this.alwalysHoverable) { - this.removeState('hover'); - this.removeState('active'); - this.fireEvent('out'); - } - }, - Stateful_onMouseOver: function (evt, el){ - var rel = evt.relatedTarget; - if (!uiUtils.contains(el, rel) && el !== rel) { - this.Stateful_onMouseEnter(evt, el); - } - }, - Stateful_onMouseOut: function (evt, el){ - var rel = evt.relatedTarget; - if (!uiUtils.contains(el, rel) && el !== rel) { - this.Stateful_onMouseLeave(evt, el); - } - }, - Stateful_onMouseDown: function (evt, el){ - if (!this.isDisabled()) { - this.addState('active'); - } - }, - Stateful_onMouseUp: function (evt, el){ - if (!this.isDisabled()) { - this.removeState('active'); - } - }, - Stateful_postRender: function (){ - if (this.disabled && !this.hasState('disabled')) { - this.addState('disabled'); - } - }, - hasState: function (state){ - return domUtils.hasClass(this.getStateDom(), 'edui-state-' + state); - }, - addState: function (state){ - if (!this.hasState(state)) { - this.getStateDom().className += ' edui-state-' + state; - } - }, - removeState: function (state){ - if (this.hasState(state)) { - domUtils.removeClasses(this.getStateDom(), ['edui-state-' + state]); - } - }, - getStateDom: function (){ - return this.getDom('state'); - }, - isChecked: function (){ - return this.hasState('checked'); - }, - setChecked: function (checked){ - if (!this.isDisabled() && checked) { - this.addState('checked'); - } else { - this.removeState('checked'); - } - }, - isDisabled: function (){ - return this.hasState('disabled'); - }, - setDisabled: function (disabled){ - if (disabled) { - this.removeState('hover'); - this.removeState('checked'); - this.removeState('active'); - this.addState('disabled'); - } else { - this.removeState('disabled'); - } - } - }; -})(); - - -// ui/button.js -///import core -///import uicore -///import ui/stateful.js -(function (){ - var utils = baidu.editor.utils, - UIBase = baidu.editor.ui.UIBase, - Stateful = baidu.editor.ui.Stateful, - Button = baidu.editor.ui.Button = function (options){ - if(options.name){ - var btnName = options.name; - var cssRules = options.cssRules; - if(!options.className){ - options.className = 'edui-for-' + btnName; - } - options.cssRules = '.edui-default .edui-for-'+ btnName +' .edui-icon {'+ cssRules +'}' - } - this.initOptions(options); - this.initButton(); - }; - Button.prototype = { - uiName: 'button', - label: '', - title: '', - showIcon: true, - showText: true, - cssRules:'', - initButton: function (){ - this.initUIBase(); - this.Stateful_init(); - if(this.cssRules){ - utils.cssRule('edui-customize-'+this.name+'-style',this.cssRules); - } - }, - getHtmlTpl: function (){ - return '
    ' + - '
    ' + - '
    ' + - (this.showIcon ? '
    ' : '') + - (this.showText ? '
    ' + this.label + '
    ' : '') + - '
    ' + - '
    ' + - '
    '; - }, - postRender: function (){ - this.Stateful_postRender(); - this.setDisabled(this.disabled) - }, - _onMouseDown: function (e){ - var target = e.target || e.srcElement, - tagName = target && target.tagName && target.tagName.toLowerCase(); - if (tagName == 'input' || tagName == 'object' || tagName == 'object') { - return false; - } - }, - _onClick: function (){ - if (!this.isDisabled()) { - this.fireEvent('click'); - } - }, - setTitle: function(text){ - var label = this.getDom('label'); - label.innerHTML = text; - } - }; - utils.inherits(Button, UIBase); - utils.extend(Button.prototype, Stateful); - -})(); - - -// ui/splitbutton.js -///import core -///import uicore -///import ui/stateful.js -(function (){ - var utils = baidu.editor.utils, - uiUtils = baidu.editor.ui.uiUtils, - domUtils = baidu.editor.dom.domUtils, - UIBase = baidu.editor.ui.UIBase, - Stateful = baidu.editor.ui.Stateful, - SplitButton = baidu.editor.ui.SplitButton = function (options){ - this.initOptions(options); - this.initSplitButton(); - }; - SplitButton.prototype = { - popup: null, - uiName: 'splitbutton', - title: '', - initSplitButton: function (){ - this.initUIBase(); - this.Stateful_init(); - var me = this; - if (this.popup != null) { - var popup = this.popup; - this.popup = null; - this.setPopup(popup); - } - }, - _UIBase_postRender: UIBase.prototype.postRender, - postRender: function (){ - this.Stateful_postRender(); - this._UIBase_postRender(); - }, - setPopup: function (popup){ - if (this.popup === popup) return; - if (this.popup != null) { - this.popup.dispose(); - } - popup.addListener('show', utils.bind(this._onPopupShow, this)); - popup.addListener('hide', utils.bind(this._onPopupHide, this)); - popup.addListener('postrender', utils.bind(function (){ - popup.getDom('body').appendChild( - uiUtils.createElementByHtml('
    ') - ); - popup.getDom().className += ' ' + this.className; - }, this)); - this.popup = popup; - }, - _onPopupShow: function (){ - this.addState('opened'); - }, - _onPopupHide: function (){ - this.removeState('opened'); - }, - getHtmlTpl: function (){ - return '
    ' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + - '
    '; - }, - showPopup: function (){ - // 当popup往上弹出的时候,做特殊处理 - var rect = uiUtils.getClientRect(this.getDom()); - rect.top -= this.popup.SHADOW_RADIUS; - rect.height += this.popup.SHADOW_RADIUS; - this.popup.showAnchorRect(rect); - }, - _onArrowClick: function (event, el){ - if (!this.isDisabled()) { - this.showPopup(); - } - }, - _onButtonClick: function (){ - if (!this.isDisabled()) { - this.fireEvent('buttonclick'); - } - } - }; - utils.inherits(SplitButton, UIBase); - utils.extend(SplitButton.prototype, Stateful, true); - -})(); - - -// ui/colorbutton.js -///import core -///import uicore -///import ui/colorpicker.js -///import ui/popup.js -///import ui/splitbutton.js -(function (){ - var utils = baidu.editor.utils, - uiUtils = baidu.editor.ui.uiUtils, - ColorPicker = baidu.editor.ui.ColorPicker, - Popup = baidu.editor.ui.Popup, - SplitButton = baidu.editor.ui.SplitButton, - ColorButton = baidu.editor.ui.ColorButton = function (options){ - this.initOptions(options); - this.initColorButton(); - }; - ColorButton.prototype = { - initColorButton: function (){ - var me = this; - this.popup = new Popup({ - content: new ColorPicker({ - noColorText: me.editor.getLang("clearColor"), - editor:me.editor, - onpickcolor: function (t, color){ - me._onPickColor(color); - }, - onpicknocolor: function (t, color){ - me._onPickNoColor(color); - } - }), - editor:me.editor - }); - this.initSplitButton(); - }, - _SplitButton_postRender: SplitButton.prototype.postRender, - postRender: function (){ - this._SplitButton_postRender(); - this.getDom('button_body').appendChild( - uiUtils.createElementByHtml('
    ') - ); - this.getDom().className += ' edui-colorbutton'; - }, - setColor: function (color){ - this.getDom('colorlump').style.backgroundColor = color; - this.color = color; - }, - _onPickColor: function (color){ - if (this.fireEvent('pickcolor', color) !== false) { - this.setColor(color); - this.popup.hide(); - } - }, - _onPickNoColor: function (color){ - if (this.fireEvent('picknocolor') !== false) { - this.popup.hide(); - } - } - }; - utils.inherits(ColorButton, SplitButton); - -})(); - - -// ui/tablebutton.js -///import core -///import uicore -///import ui/popup.js -///import ui/tablepicker.js -///import ui/splitbutton.js -(function (){ - var utils = baidu.editor.utils, - Popup = baidu.editor.ui.Popup, - TablePicker = baidu.editor.ui.TablePicker, - SplitButton = baidu.editor.ui.SplitButton, - TableButton = baidu.editor.ui.TableButton = function (options){ - this.initOptions(options); - this.initTableButton(); - }; - TableButton.prototype = { - initTableButton: function (){ - var me = this; - this.popup = new Popup({ - content: new TablePicker({ - editor:me.editor, - onpicktable: function (t, numCols, numRows){ - me._onPickTable(numCols, numRows); - } - }), - 'editor':me.editor - }); - this.initSplitButton(); - }, - _onPickTable: function (numCols, numRows){ - if (this.fireEvent('picktable', numCols, numRows) !== false) { - this.popup.hide(); - } - } - }; - utils.inherits(TableButton, SplitButton); - -})(); - - -// ui/autotypesetpicker.js -///import core -///import uicore -(function () { - var utils = baidu.editor.utils, - UIBase = baidu.editor.ui.UIBase; - - var AutoTypeSetPicker = baidu.editor.ui.AutoTypeSetPicker = function (options) { - this.initOptions(options); - this.initAutoTypeSetPicker(); - }; - AutoTypeSetPicker.prototype = { - initAutoTypeSetPicker:function () { - this.initUIBase(); - }, - getHtmlTpl:function () { - var me = this.editor, - opt = me.options.autotypeset, - lang = me.getLang("autoTypeSet"); - - var textAlignInputName = 'textAlignValue' + me.uid, - imageBlockInputName = 'imageBlockLineValue' + me.uid, - symbolConverInputName = 'symbolConverValue' + me.uid; - - return '
    ' + - '
    ' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '' + - '
    ' + lang.mergeLine + '' + lang.delLine + '
    ' + lang.removeFormat + '' + lang.indent + '
    ' + lang.alignment + '' + - '' + me.getLang("justifyleft") + - '' + me.getLang("justifycenter") + - '' + me.getLang("justifyright") + - '
    ' + lang.imageFloat + '' + - '' + me.getLang("default") + - '' + me.getLang("justifyleft") + - '' + me.getLang("justifycenter") + - '' + me.getLang("justifyright") + - '
    ' + lang.removeFontsize + '' + lang.removeFontFamily + '
    ' + lang.removeHtml + '
    ' + lang.pasteFilter + '
    ' + lang.symbol + '' + - '' + lang.bdc2sb + - '' + lang.tobdc + '' + - '
    ' + - '
    ' + - '
    '; - - - }, - _UIBase_render:UIBase.prototype.render - }; - utils.inherits(AutoTypeSetPicker, UIBase); -})(); - - -// ui/autotypesetbutton.js -///import core -///import uicore -///import ui/popup.js -///import ui/autotypesetpicker.js -///import ui/splitbutton.js -(function (){ - var utils = baidu.editor.utils, - Popup = baidu.editor.ui.Popup, - AutoTypeSetPicker = baidu.editor.ui.AutoTypeSetPicker, - SplitButton = baidu.editor.ui.SplitButton, - AutoTypeSetButton = baidu.editor.ui.AutoTypeSetButton = function (options){ - this.initOptions(options); - this.initAutoTypeSetButton(); - }; - function getPara(me){ - - var opt = {}, - cont = me.getDom(), - editorId = me.editor.uid, - inputType = null, - attrName = null, - ipts = domUtils.getElementsByTagName(cont,"input"); - for(var i=ipts.length-1,ipt;ipt=ipts[i--];){ - inputType = ipt.getAttribute("type"); - if(inputType=="checkbox"){ - attrName = ipt.getAttribute("name"); - opt[attrName] && delete opt[attrName]; - if(ipt.checked){ - var attrValue = document.getElementById( attrName + "Value" + editorId ); - if(attrValue){ - if(/input/ig.test(attrValue.tagName)){ - opt[attrName] = attrValue.value; - } else { - var iptChilds = attrValue.getElementsByTagName("input"); - for(var j=iptChilds.length-1,iptchild;iptchild=iptChilds[j--];){ - if(iptchild.checked){ - opt[attrName] = iptchild.value; - break; - } - } - } - } else { - opt[attrName] = true; - } - } else { - opt[attrName] = false; - } - } else { - opt[ipt.getAttribute("value")] = ipt.checked; - } - - } - - var selects = domUtils.getElementsByTagName(cont,"select"); - for(var i=0,si;si=selects[i++];){ - var attr = si.getAttribute('name'); - opt[attr] = opt[attr] ? si.value : ''; - } - - utils.extend(me.editor.options.autotypeset,opt); - - me.editor.setPreferences('autotypeset', opt); - } - - AutoTypeSetButton.prototype = { - initAutoTypeSetButton: function (){ - - var me = this; - this.popup = new Popup({ - //传入配置参数 - content: new AutoTypeSetPicker({editor:me.editor}), - 'editor':me.editor, - hide : function(){ - if (!this._hidden && this.getDom()) { - getPara(this); - this.getDom().style.display = 'none'; - this._hidden = true; - this.fireEvent('hide'); - } - } - }); - var flag = 0; - this.popup.addListener('postRenderAfter',function(){ - var popupUI = this; - if(flag)return; - var cont = this.getDom(), - btn = cont.getElementsByTagName('button')[0]; - - btn.onclick = function(){ - getPara(popupUI); - me.editor.execCommand('autotypeset'); - popupUI.hide() - }; - - domUtils.on(cont, 'click', function(e) { - var target = e.target || e.srcElement, - editorId = me.editor.uid; - if (target && target.tagName == 'INPUT') { - - // 点击图片浮动的checkbox,去除对应的radio - if (target.name == 'imageBlockLine' || target.name == 'textAlign' || target.name == 'symbolConver') { - var checked = target.checked, - radioTd = document.getElementById( target.name + 'Value' + editorId), - radios = radioTd.getElementsByTagName('input'), - defalutSelect = { - 'imageBlockLine': 'none', - 'textAlign': 'left', - 'symbolConver': 'tobdc' - }; - - for (var i = 0; i < radios.length; i++) { - if (checked) { - if (radios[i].value == defalutSelect[target.name]) { - radios[i].checked = 'checked'; - } - } else { - radios[i].checked = false; - } - } - } - // 点击radio,选中对应的checkbox - if (target.name == ('imageBlockLineValue' + editorId) || target.name == ('textAlignValue' + editorId) || target.name == 'bdc') { - var checkboxs = target.parentNode.previousSibling.getElementsByTagName('input'); - checkboxs && (checkboxs[0].checked = true); - } - - getPara(popupUI); - } - }); - - flag = 1; - }); - this.initSplitButton(); - } - }; - utils.inherits(AutoTypeSetButton, SplitButton); - -})(); - - -// ui/cellalignpicker.js -///import core -///import uicore -(function () { - var utils = baidu.editor.utils, - Popup = baidu.editor.ui.Popup, - Stateful = baidu.editor.ui.Stateful, - UIBase = baidu.editor.ui.UIBase; - - /** - * 该参数将新增一个参数: selected, 参数类型为一个Object, 形如{ 'align': 'center', 'valign': 'top' }, 表示单元格的初始 - * 对齐状态为: 竖直居上,水平居中; 其中 align的取值为:'center', 'left', 'right'; valign的取值为: 'top', 'middle', 'bottom' - * @update 2013/4/2 hancong03@baidu.com - */ - var CellAlignPicker = baidu.editor.ui.CellAlignPicker = function (options) { - this.initOptions(options); - this.initSelected(); - this.initCellAlignPicker(); - }; - CellAlignPicker.prototype = { - //初始化选中状态, 该方法将根据传递进来的参数获取到应该选中的对齐方式图标的索引 - initSelected: function(){ - - var status = { - - valign: { - top: 0, - middle: 1, - bottom: 2 - }, - align: { - left: 0, - center: 1, - right: 2 - }, - count: 3 - - }, - result = -1; - - if( this.selected ) { - this.selectedIndex = status.valign[ this.selected.valign ] * status.count + status.align[ this.selected.align ]; - } - - }, - initCellAlignPicker:function () { - this.initUIBase(); - this.Stateful_init(); - }, - getHtmlTpl:function () { - - var alignType = [ 'left', 'center', 'right' ], - COUNT = 9, - tempClassName = null, - tempIndex = -1, - tmpl = []; - - - for( var i= 0; i'); - - tmpl.push( '
    ' ); - - tempIndex === 2 && tmpl.push(''); - - } - - return '
    ' + - '
    ' + - '' + - tmpl.join('') + - '
    ' + - '
    ' + - '
    '; - }, - getStateDom: function (){ - return this.target; - }, - _onClick: function (evt){ - var target= evt.target || evt.srcElement; - if(/icon/.test(target.className)){ - this.items[target.parentNode.getAttribute("index")].onclick(); - Popup.postHide(evt); - } - }, - _UIBase_render:UIBase.prototype.render - }; - utils.inherits(CellAlignPicker, UIBase); - utils.extend(CellAlignPicker.prototype, Stateful,true); -})(); - - - - - -// ui/pastepicker.js -///import core -///import uicore -(function () { - var utils = baidu.editor.utils, - Stateful = baidu.editor.ui.Stateful, - uiUtils = baidu.editor.ui.uiUtils, - UIBase = baidu.editor.ui.UIBase; - - var PastePicker = baidu.editor.ui.PastePicker = function (options) { - this.initOptions(options); - this.initPastePicker(); - }; - PastePicker.prototype = { - initPastePicker:function () { - this.initUIBase(); - this.Stateful_init(); - }, - getHtmlTpl:function () { - return '
    ' + - '
    ' + - '
    ' + this.editor.getLang("pasteOpt") + '
    ' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + - '' - }, - getStateDom:function () { - return this.target; - }, - format:function (param) { - this.editor.ui._isTransfer = true; - this.editor.fireEvent('pasteTransfer', param); - }, - _onClick:function (cur) { - var node = domUtils.getNextDomNode(cur), - screenHt = uiUtils.getViewportRect().height, - subPop = uiUtils.getClientRect(node); - - if ((subPop.top + subPop.height) > screenHt) - node.style.top = (-subPop.height - cur.offsetHeight) + "px"; - else - node.style.top = ""; - - if (/hidden/ig.test(domUtils.getComputedStyle(node, "visibility"))) { - node.style.visibility = "visible"; - domUtils.addClass(cur, "edui-state-opened"); - } else { - node.style.visibility = "hidden"; - domUtils.removeClasses(cur, "edui-state-opened") - } - }, - _UIBase_render:UIBase.prototype.render - }; - utils.inherits(PastePicker, UIBase); - utils.extend(PastePicker.prototype, Stateful, true); -})(); - - - - - - -// ui/toolbar.js -(function (){ - var utils = baidu.editor.utils, - uiUtils = baidu.editor.ui.uiUtils, - UIBase = baidu.editor.ui.UIBase, - Toolbar = baidu.editor.ui.Toolbar = function (options){ - this.initOptions(options); - this.initToolbar(); - }; - Toolbar.prototype = { - items: null, - initToolbar: function (){ - this.items = this.items || []; - this.initUIBase(); - }, - add: function (item,index){ - if(index === undefined){ - this.items.push(item); - }else{ - this.items.splice(index,0,item) - } - - }, - getHtmlTpl: function (){ - var buff = []; - for (var i=0; i' + - buff.join('') + - '' - }, - postRender: function (){ - var box = this.getDom(); - for (var i=0; i
    '; - }, - postRender:function () { - }, - queryAutoHide:function () { - return true; - } - }; - Menu.prototype = { - items:null, - uiName:'menu', - initMenu:function () { - this.items = this.items || []; - this.initPopup(); - this.initItems(); - }, - initItems:function () { - for (var i = 0; i < this.items.length; i++) { - var item = this.items[i]; - if (item == '-') { - this.items[i] = this.getSeparator(); - } else if (!(item instanceof MenuItem)) { - item.editor = this.editor; - item.theme = this.editor.options.theme; - this.items[i] = this.createItem(item); - } - } - }, - getSeparator:function () { - return menuSeparator; - }, - createItem:function (item) { - //新增一个参数menu, 该参数存储了menuItem所对应的menu引用 - item.menu = this; - return new MenuItem(item); - }, - _Popup_getContentHtmlTpl:Popup.prototype.getContentHtmlTpl, - getContentHtmlTpl:function () { - if (this.items.length == 0) { - return this._Popup_getContentHtmlTpl(); - } - var buff = []; - for (var i = 0; i < this.items.length; i++) { - var item = this.items[i]; - buff[i] = item.renderHtml(); - } - return ('
    ' + buff.join('') + '
    '); - }, - _Popup_postRender:Popup.prototype.postRender, - postRender:function () { - var me = this; - for (var i = 0; i < this.items.length; i++) { - var item = this.items[i]; - item.ownerMenu = this; - item.postRender(); - } - domUtils.on(this.getDom(), 'mouseover', function (evt) { - evt = evt || event; - var rel = evt.relatedTarget || evt.fromElement; - var el = me.getDom(); - if (!uiUtils.contains(el, rel) && el !== rel) { - me.fireEvent('over'); - } - }); - this._Popup_postRender(); - }, - queryAutoHide:function (el) { - if (el) { - if (uiUtils.contains(this.getDom(), el)) { - return false; - } - for (var i = 0; i < this.items.length; i++) { - var item = this.items[i]; - if (item.queryAutoHide(el) === false) { - return false; - } - } - } - }, - clearItems:function () { - for (var i = 0; i < this.items.length; i++) { - var item = this.items[i]; - clearTimeout(item._showingTimer); - clearTimeout(item._closingTimer); - if (item.subMenu) { - item.subMenu.destroy(); - } - } - this.items = []; - }, - destroy:function () { - if (this.getDom()) { - domUtils.remove(this.getDom()); - } - this.clearItems(); - }, - dispose:function () { - this.destroy(); - } - }; - utils.inherits(Menu, Popup); - - /** - * @update 2013/04/03 hancong03 新增一个参数menu, 该参数存储了menuItem所对应的menu引用 - * @type {Function} - */ - var MenuItem = baidu.editor.ui.MenuItem = function (options) { - this.initOptions(options); - this.initUIBase(); - this.Stateful_init(); - if (this.subMenu && !(this.subMenu instanceof Menu)) { - if (options.className && options.className.indexOf("aligntd") != -1) { - var me = this; - - //获取单元格对齐初始状态 - this.subMenu.selected = this.editor.queryCommandValue( 'cellalignment' ); - - this.subMenu = new Popup({ - content:new CellAlignPicker(this.subMenu), - parentMenu:me, - editor:me.editor, - destroy:function () { - if (this.getDom()) { - domUtils.remove(this.getDom()); - } - } - }); - this.subMenu.addListener("postRenderAfter", function () { - domUtils.on(this.getDom(), "mouseover", function () { - me.addState('opened'); - }); - }); - } else { - this.subMenu = new Menu(this.subMenu); - } - } - }; - MenuItem.prototype = { - label:'', - subMenu:null, - ownerMenu:null, - uiName:'menuitem', - alwalysHoverable:true, - getHtmlTpl:function () { - return '
    ' + - '
    ' + - this.renderLabelHtml() + - '
    ' + - '
    '; - }, - postRender:function () { - var me = this; - this.addListener('over', function () { - me.ownerMenu.fireEvent('submenuover', me); - if (me.subMenu) { - me.delayShowSubMenu(); - } - }); - if (this.subMenu) { - this.getDom().className += ' edui-hassubmenu'; - this.subMenu.render(); - this.addListener('out', function () { - me.delayHideSubMenu(); - }); - this.subMenu.addListener('over', function () { - clearTimeout(me._closingTimer); - me._closingTimer = null; - me.addState('opened'); - }); - this.ownerMenu.addListener('hide', function () { - me.hideSubMenu(); - }); - this.ownerMenu.addListener('submenuover', function (t, subMenu) { - if (subMenu !== me) { - me.delayHideSubMenu(); - } - }); - this.subMenu._bakQueryAutoHide = this.subMenu.queryAutoHide; - this.subMenu.queryAutoHide = function (el) { - if (el && uiUtils.contains(me.getDom(), el)) { - return false; - } - return this._bakQueryAutoHide(el); - }; - } - this.getDom().style.tabIndex = '-1'; - uiUtils.makeUnselectable(this.getDom()); - this.Stateful_postRender(); - }, - delayShowSubMenu:function () { - var me = this; - if (!me.isDisabled()) { - me.addState('opened'); - clearTimeout(me._showingTimer); - clearTimeout(me._closingTimer); - me._closingTimer = null; - me._showingTimer = setTimeout(function () { - me.showSubMenu(); - }, 250); - } - }, - delayHideSubMenu:function () { - var me = this; - if (!me.isDisabled()) { - me.removeState('opened'); - clearTimeout(me._showingTimer); - if (!me._closingTimer) { - me._closingTimer = setTimeout(function () { - if (!me.hasState('opened')) { - me.hideSubMenu(); - } - me._closingTimer = null; - }, 400); - } - } - }, - renderLabelHtml:function () { - return '
    ' + - '
    ' + - '
    ' + (this.label || '') + '
    '; - }, - getStateDom:function () { - return this.getDom(); - }, - queryAutoHide:function (el) { - if (this.subMenu && this.hasState('opened')) { - return this.subMenu.queryAutoHide(el); - } - }, - _onClick:function (event, this_) { - if (this.hasState('disabled')) return; - if (this.fireEvent('click', event, this_) !== false) { - if (this.subMenu) { - this.showSubMenu(); - } else { - Popup.postHide(event); - } - } - }, - showSubMenu:function () { - var rect = uiUtils.getClientRect(this.getDom()); - rect.right -= 5; - rect.left += 2; - rect.width -= 7; - rect.top -= 4; - rect.bottom += 4; - rect.height += 8; - this.subMenu.showAnchorRect(rect, true, true); - }, - hideSubMenu:function () { - this.subMenu.hide(); - } - }; - utils.inherits(MenuItem, UIBase); - utils.extend(MenuItem.prototype, Stateful, true); -})(); - - -// ui/combox.js -///import core -///import uicore -///import ui/menu.js -///import ui/splitbutton.js -(function (){ - // todo: menu和item提成通用list - var utils = baidu.editor.utils, - uiUtils = baidu.editor.ui.uiUtils, - Menu = baidu.editor.ui.Menu, - SplitButton = baidu.editor.ui.SplitButton, - Combox = baidu.editor.ui.Combox = function (options){ - this.initOptions(options); - this.initCombox(); - }; - Combox.prototype = { - uiName: 'combox', - onbuttonclick:function () { - this.showPopup(); - }, - initCombox: function (){ - var me = this; - this.items = this.items || []; - for (var i=0; i vpRect.right) { - left = vpRect.right - rect.width; - } - var top = offset.top; - if (top + rect.height > vpRect.bottom) { - top = vpRect.bottom - rect.height; - } - el.style.left = Math.max(left, 0) + 'px'; - el.style.top = Math.max(top, 0) + 'px'; - }, - showAtCenter: function (){ - - var vpRect = uiUtils.getViewportRect(); - - if ( !this.fullscreen ) { - this.getDom().style.display = ''; - var popSize = this.fitSize(); - var titleHeight = this.getDom('titlebar').offsetHeight | 0; - var left = vpRect.width / 2 - popSize.width / 2; - var top = vpRect.height / 2 - (popSize.height - titleHeight) / 2 - titleHeight; - var popEl = this.getDom(); - this.safeSetOffset({ - left: Math.max(left | 0, 0), - top: Math.max(top | 0, 0) - }); - if (!domUtils.hasClass(popEl, 'edui-state-centered')) { - popEl.className += ' edui-state-centered'; - } - } else { - var dialogWrapNode = this.getDom(), - contentNode = this.getDom('content'); - - dialogWrapNode.style.display = "block"; - - var wrapRect = UE.ui.uiUtils.getClientRect( dialogWrapNode ), - contentRect = UE.ui.uiUtils.getClientRect( contentNode ); - dialogWrapNode.style.left = "-100000px"; - - contentNode.style.width = ( vpRect.width - wrapRect.width + contentRect.width ) + "px"; - contentNode.style.height = ( vpRect.height - wrapRect.height + contentRect.height ) + "px"; - - dialogWrapNode.style.width = vpRect.width + "px"; - dialogWrapNode.style.height = vpRect.height + "px"; - dialogWrapNode.style.left = 0; - - //保存环境的overflow值 - this._originalContext = { - html: { - overflowX: document.documentElement.style.overflowX, - overflowY: document.documentElement.style.overflowY - }, - body: { - overflowX: document.body.style.overflowX, - overflowY: document.body.style.overflowY - } - }; - - document.documentElement.style.overflowX = 'hidden'; - document.documentElement.style.overflowY = 'hidden'; - document.body.style.overflowX = 'hidden'; - document.body.style.overflowY = 'hidden'; - - } - - this._show(); - }, - getContentHtml: function (){ - var contentHtml = ''; - if (typeof this.content == 'string') { - contentHtml = this.content; - } else if (this.iframeUrl) { - contentHtml = ''; - } - return contentHtml; - }, - getHtmlTpl: function (){ - var footHtml = ''; - - if (this.buttons) { - var buff = []; - for (var i=0; i' + buff.join('') + '' + - ''; - } - - return '
    ' + - '
    ' + - '
    ' + - '
    ' + - '' + (this.title || '') + '' + - '
    ' + - this.closeButton.renderHtml() + - '
    ' + - '
    '+ ( this.autoReset ? '' : this.getContentHtml()) +'
    ' + - footHtml + - '
    '; - }, - postRender: function (){ - // todo: 保持居中/记住上次关闭位置选项 - if (!this.modalMask.getDom()) { - this.modalMask.render(); - this.modalMask.hide(); - } - if (!this.dragMask.getDom()) { - this.dragMask.render(); - this.dragMask.hide(); - } - var me = this; - this.addListener('show', function (){ - me.modalMask.show(this.getDom().style.zIndex - 2); - }); - this.addListener('hide', function (){ - me.modalMask.hide(); - }); - if (this.buttons) { - for (var i=0; i'; - me.editor.container.style.zIndex && (this.getDom().style.zIndex = me.editor.container.style.zIndex * 1 + 1); - } - } - // canSideUp:false, - // canSideLeft:false - }); - this.onbuttonclick = function(){ - this.showPopup(); - }; - this.initSplitButton(); - } - - }; - - utils.inherits(MultiMenuPop, SplitButton); -})(); - - -// ui/shortcutmenu.js -(function () { - var UI = baidu.editor.ui, - UIBase = UI.UIBase, - uiUtils = UI.uiUtils, - utils = baidu.editor.utils, - domUtils = baidu.editor.dom.domUtils; - - var allMenus = [],//存储所有快捷菜单 - timeID, - isSubMenuShow = false;//是否有子pop显示 - - var ShortCutMenu = UI.ShortCutMenu = function (options) { - this.initOptions (options); - this.initShortCutMenu (); - }; - - ShortCutMenu.postHide = hideAllMenu; - - ShortCutMenu.prototype = { - isHidden : true , - SPACE : 5 , - initShortCutMenu : function () { - this.items = this.items || []; - this.initUIBase (); - this.initItems (); - this.initEvent (); - allMenus.push (this); - } , - initEvent : function () { - var me = this, - doc = me.editor.document; - - domUtils.on (doc , "mousemove" , function (e) { - if (me.isHidden === false) { - //有pop显示就不隐藏快捷菜单 - if (me.getSubMenuMark () || me.eventType == "contextmenu") return; - - - var flag = true, - el = me.getDom (), - wt = el.offsetWidth, - ht = el.offsetHeight, - distanceX = wt / 2 + me.SPACE,//距离中心X标准 - distanceY = ht / 2,//距离中心Y标准 - x = Math.abs (e.screenX - me.left),//离中心距离横坐标 - y = Math.abs (e.screenY - me.top);//离中心距离纵坐标 - - clearTimeout (timeID); - timeID = setTimeout (function () { - if (y > 0 && y < distanceY) { - me.setOpacity (el , "1"); - } else if (y > distanceY && y < distanceY + 70) { - me.setOpacity (el , "0.5"); - flag = false; - } else if (y > distanceY + 70 && y < distanceY + 140) { - me.hide (); - } - - if (flag && x > 0 && x < distanceX) { - me.setOpacity (el , "1") - } else if (x > distanceX && x < distanceX + 70) { - me.setOpacity (el , "0.5") - } else if (x > distanceX + 70 && x < distanceX + 140) { - me.hide (); - } - }); - } - }); - - //ie\ff下 mouseout不准 - if (browser.chrome) { - domUtils.on (doc , "mouseout" , function (e) { - var relatedTgt = e.relatedTarget || e.toElement; - - if (relatedTgt == null || relatedTgt.tagName == "HTML") { - me.hide (); - } - }); - } - - me.editor.addListener ("afterhidepop" , function () { - if (!me.isHidden) { - isSubMenuShow = true; - } - }); - - } , - initItems : function () { - if (utils.isArray (this.items)) { - for (var i = 0, len = this.items.length ; i < len ; i++) { - var item = this.items[i].toLowerCase (); - - if (UI[item]) { - this.items[i] = new UI[item] (this.editor); - this.items[i].className += " edui-shortcutsubmenu "; - } - } - } - } , - setOpacity : function (el , value) { - if (browser.ie && browser.version < 9) { - el.style.filter = "alpha(opacity = " + parseFloat (value) * 100 + ");" - } else { - el.style.opacity = value; - } - } , - getSubMenuMark : function () { - isSubMenuShow = false; - var layerEle = uiUtils.getFixedLayer (); - var list = domUtils.getElementsByTagName (layerEle , "div" , function (node) { - return domUtils.hasClass (node , "edui-shortcutsubmenu edui-popup") - }); - - for (var i = 0, node ; node = list[i++] ;) { - if (node.style.display != "none") { - isSubMenuShow = true; - } - } - return isSubMenuShow; - } , - show : function (e , hasContextmenu) { - var me = this, - offset = {}, - el = this.getDom (), - fixedlayer = uiUtils.getFixedLayer (); - - function setPos (offset) { - if (offset.left < 0) { - offset.left = 0; - } - if (offset.top < 0) { - offset.top = 0; - } - el.style.cssText = "position:absolute;left:" + offset.left + "px;top:" + offset.top + "px;"; - } - - function setPosByCxtMenu (menu) { - if (!menu.tagName) { - menu = menu.getDom (); - } - offset.left = parseInt (menu.style.left); - offset.top = parseInt (menu.style.top); - offset.top -= el.offsetHeight + 15; - setPos (offset); - } - - - me.eventType = e.type; - el.style.cssText = "display:block;left:-9999px"; - - if (e.type == "contextmenu" && hasContextmenu) { - var menu = domUtils.getElementsByTagName (fixedlayer , "div" , "edui-contextmenu")[0]; - if (menu) { - setPosByCxtMenu (menu) - } else { - me.editor.addListener ("aftershowcontextmenu" , function (type , menu) { - setPosByCxtMenu (menu); - }); - } - } else { - offset = uiUtils.getViewportOffsetByEvent (e); - offset.top -= el.offsetHeight + me.SPACE; - offset.left += me.SPACE + 20; - setPos (offset); - me.setOpacity (el , 0.2); - } - - - me.isHidden = false; - me.left = e.screenX + el.offsetWidth / 2 - me.SPACE; - me.top = e.screenY - (el.offsetHeight / 2) - me.SPACE; - - if (me.editor) { - el.style.zIndex = me.editor.container.style.zIndex * 1 + 10; - fixedlayer.style.zIndex = el.style.zIndex - 1; - } - } , - hide : function () { - if (this.getDom ()) { - this.getDom ().style.display = "none"; - } - this.isHidden = true; - } , - postRender : function () { - if (utils.isArray (this.items)) { - for (var i = 0, item ; item = this.items[i++] ;) { - item.postRender (); - } - } - } , - getHtmlTpl : function () { - var buff; - if (utils.isArray (this.items)) { - buff = []; - for (var i = 0 ; i < this.items.length ; i++) { - buff[i] = this.items[i].renderHtml (); - } - buff = buff.join (""); - } else { - buff = this.items; - } - - return '
    ' + - buff + - '
    '; - } - }; - - utils.inherits (ShortCutMenu , UIBase); - - function hideAllMenu (e) { - var tgt = e.target || e.srcElement, - cur = domUtils.findParent (tgt , function (node) { - return domUtils.hasClass (node , "edui-shortcutmenu") || domUtils.hasClass (node , "edui-popup"); - } , true); - - if (!cur) { - for (var i = 0, menu ; menu = allMenus[i++] ;) { - menu.hide () - } - } - } - - domUtils.on (document , 'mousedown' , function (e) { - hideAllMenu (e); - }); - - domUtils.on (window , 'scroll' , function (e) { - hideAllMenu (e); - }); - -}) (); - - -// ui/breakline.js -(function (){ - var utils = baidu.editor.utils, - UIBase = baidu.editor.ui.UIBase, - Breakline = baidu.editor.ui.Breakline = function (options){ - this.initOptions(options); - this.initSeparator(); - }; - Breakline.prototype = { - uiName: 'Breakline', - initSeparator: function (){ - this.initUIBase(); - }, - getHtmlTpl: function (){ - return '
    '; - } - }; - utils.inherits(Breakline, UIBase); - -})(); - - -// ui/message.js -///import core -///import uicore -(function () { - var utils = baidu.editor.utils, - domUtils = baidu.editor.dom.domUtils, - UIBase = baidu.editor.ui.UIBase, - Message = baidu.editor.ui.Message = function (options){ - this.initOptions(options); - this.initMessage(); - }; - - Message.prototype = { - initMessage: function (){ - this.initUIBase(); - }, - getHtmlTpl: function (){ - return '
    ' + - '
    ×
    ' + - '
    ' + - ' ' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + - '
    '; - }, - reset: function(opt){ - var me = this; - if (!opt.keepshow) { - clearTimeout(this.timer); - me.timer = setTimeout(function(){ - me.hide(); - }, opt.timeout || 4000); - } - - opt.content !== undefined && me.setContent(opt.content); - opt.type !== undefined && me.setType(opt.type); - - me.show(); - }, - postRender: function(){ - var me = this, - closer = this.getDom('closer'); - closer && domUtils.on(closer, 'click', function(){ - me.hide(); - }); - }, - setContent: function(content){ - this.getDom('content').innerHTML = content; - }, - setType: function(type){ - type = type || 'info'; - var body = this.getDom('body'); - body.className = body.className.replace(/edui-message-type-[\w-]+/, 'edui-message-type-' + type); - }, - getContent: function(){ - return this.getDom('content').innerHTML; - }, - getType: function(){ - var arr = this.getDom('body').match(/edui-message-type-([\w-]+)/); - return arr ? arr[1]:''; - }, - show: function (){ - this.getDom().style.display = 'block'; - }, - hide: function (){ - var dom = this.getDom(); - if (dom) { - dom.style.display = 'none'; - dom.parentNode && dom.parentNode.removeChild(dom); - } - } - }; - - utils.inherits(Message, UIBase); - -})(); - - -// adapter/editorui.js -//ui跟编辑器的适配層 -//那个按钮弹出是dialog,是下拉筐等都是在这个js中配置 -//自己写的ui也要在这里配置,放到baidu.editor.ui下边,当编辑器实例化的时候会根据ueditor.config中的toolbars找到相应的进行实例化 -(function () { - var utils = baidu.editor.utils; - var editorui = baidu.editor.ui; - var _Dialog = editorui.Dialog; - editorui.buttons = {}; - - editorui.Dialog = function (options) { - var dialog = new _Dialog(options); - dialog.addListener('hide', function () { - - if (dialog.editor) { - var editor = dialog.editor; - try { - if (browser.gecko) { - var y = editor.window.scrollY, - x = editor.window.scrollX; - editor.body.focus(); - editor.window.scrollTo(x, y); - } else { - editor.focus(); - } - - - } catch (ex) { - } - } - }); - return dialog; - }; - - var iframeUrlMap = { - 'anchor':'~/dialogs/anchor/anchor.html', - 'insertimage':'~/dialogs/image/image.html', - 'link':'~/dialogs/link/link.html', - 'spechars':'~/dialogs/spechars/spechars.html', - 'searchreplace':'~/dialogs/searchreplace/searchreplace.html', - 'map':'~/dialogs/map/map.html', - 'gmap':'~/dialogs/gmap/gmap.html', - 'insertvideo':'~/dialogs/video/video.html', - 'help':'~/dialogs/help/help.html', - 'preview':'~/dialogs/preview/preview.html', - 'emotion':'~/dialogs/emotion/emotion.html', - 'wordimage':'~/dialogs/wordimage/wordimage.html', - 'attachment':'~/dialogs/attachment/attachment.html', - 'insertframe':'~/dialogs/insertframe/insertframe.html', - 'edittip':'~/dialogs/table/edittip.html', - 'edittable':'~/dialogs/table/edittable.html', - 'edittd':'~/dialogs/table/edittd.html', - 'webapp':'~/dialogs/webapp/webapp.html', - 'snapscreen':'~/dialogs/snapscreen/snapscreen.html', - 'scrawl':'~/dialogs/scrawl/scrawl.html', - 'music':'~/dialogs/music/music.html', - 'template':'~/dialogs/template/template.html', - 'background':'~/dialogs/background/background.html', - 'charts': '~/dialogs/charts/charts.html' - }; - //为工具栏添加按钮,以下都是统一的按钮触发命令,所以写在一起 - var btnCmds = ['undo', 'redo', 'formatmatch', - 'bold', 'italic', 'underline', 'fontborder', 'touppercase', 'tolowercase', - 'strikethrough', 'subscript', 'superscript', 'source', 'indent', 'outdent', - 'blockquote', 'pasteplain', 'pagebreak', - 'selectall', 'print','horizontal', 'removeformat', 'time', 'date', 'unlink', - 'insertparagraphbeforetable', 'insertrow', 'insertcol', 'mergeright', 'mergedown', 'deleterow', - 'deletecol', 'splittorows', 'splittocols', 'splittocells', 'mergecells', 'deletetable', 'drafts']; - - for (var i = 0, ci; ci = btnCmds[i++];) { - ci = ci.toLowerCase(); - editorui[ci] = function (cmd) { - return function (editor) { - var ui = new editorui.Button({ - className:'edui-for-' + cmd, - title:editor.options.labelMap[cmd] || editor.getLang("labelMap." + cmd) || '', - onclick:function () { - editor.execCommand(cmd); - }, - theme:editor.options.theme, - showText:false - }); - editorui.buttons[cmd] = ui; - editor.addListener('selectionchange', function (type, causeByUi, uiReady) { - var state = editor.queryCommandState(cmd); - if (state == -1) { - ui.setDisabled(true); - ui.setChecked(false); - } else { - if (!uiReady) { - ui.setDisabled(false); - ui.setChecked(state); - } - } - }); - return ui; - }; - }(ci); - } - - //清除文档 - editorui.cleardoc = function (editor) { - var ui = new editorui.Button({ - className:'edui-for-cleardoc', - title:editor.options.labelMap.cleardoc || editor.getLang("labelMap.cleardoc") || '', - theme:editor.options.theme, - onclick:function () { - if (confirm(editor.getLang("confirmClear"))) { - editor.execCommand('cleardoc'); - } - } - }); - editorui.buttons["cleardoc"] = ui; - editor.addListener('selectionchange', function () { - ui.setDisabled(editor.queryCommandState('cleardoc') == -1); - }); - return ui; - }; - - //排版,图片排版,文字方向 - var typeset = { - 'justify':['left', 'right', 'center', 'justify'], - 'imagefloat':['none', 'left', 'center', 'right'], - 'directionality':['ltr', 'rtl'] - }; - - for (var p in typeset) { - - (function (cmd, val) { - for (var i = 0, ci; ci = val[i++];) { - (function (cmd2) { - editorui[cmd.replace('float', '') + cmd2] = function (editor) { - var ui = new editorui.Button({ - className:'edui-for-' + cmd.replace('float', '') + cmd2, - title:editor.options.labelMap[cmd.replace('float', '') + cmd2] || editor.getLang("labelMap." + cmd.replace('float', '') + cmd2) || '', - theme:editor.options.theme, - onclick:function () { - editor.execCommand(cmd, cmd2); - } - }); - editorui.buttons[cmd] = ui; - editor.addListener('selectionchange', function (type, causeByUi, uiReady) { - ui.setDisabled(editor.queryCommandState(cmd) == -1); - ui.setChecked(editor.queryCommandValue(cmd) == cmd2 && !uiReady); - }); - return ui; - }; - })(ci) - } - })(p, typeset[p]) - } - - //字体颜色和背景颜色 - for (var i = 0, ci; ci = ['backcolor', 'forecolor'][i++];) { - editorui[ci] = function (cmd) { - return function (editor) { - var ui = new editorui.ColorButton({ - className:'edui-for-' + cmd, - color:'default', - title:editor.options.labelMap[cmd] || editor.getLang("labelMap." + cmd) || '', - editor:editor, - onpickcolor:function (t, color) { - editor.execCommand(cmd, color); - }, - onpicknocolor:function () { - editor.execCommand(cmd, 'default'); - this.setColor('transparent'); - this.color = 'default'; - }, - onbuttonclick:function () { - editor.execCommand(cmd, this.color); - } - }); - editorui.buttons[cmd] = ui; - editor.addListener('selectionchange', function () { - ui.setDisabled(editor.queryCommandState(cmd) == -1); - }); - return ui; - }; - }(ci); - } - - - var dialogBtns = { - noOk:['searchreplace', 'help', 'spechars', 'webapp','preview'], - ok:['attachment', 'anchor', 'link', 'insertimage', 'map', 'gmap', 'insertframe', 'wordimage', - 'insertvideo', 'insertframe', 'edittip', 'edittable', 'edittd', 'scrawl', 'template', 'music', 'background', 'charts'] - }; - - for (var p in dialogBtns) { - (function (type, vals) { - for (var i = 0, ci; ci = vals[i++];) { - //todo opera下存在问题 - if (browser.opera && ci === "searchreplace") { - continue; - } - (function (cmd) { - editorui[cmd] = function (editor, iframeUrl, title) { - iframeUrl = iframeUrl || (editor.options.iframeUrlMap || {})[cmd] || iframeUrlMap[cmd]; - title = editor.options.labelMap[cmd] || editor.getLang("labelMap." + cmd) || ''; - - var dialog; - //没有iframeUrl不创建dialog - if (iframeUrl) { - dialog = new editorui.Dialog(utils.extend({ - iframeUrl:editor.ui.mapUrl(iframeUrl), - editor:editor, - className:'edui-for-' + cmd, - title:title, - holdScroll: cmd === 'insertimage', - fullscreen: /charts|preview/.test(cmd), - closeDialog:editor.getLang("closeDialog") - }, type == 'ok' ? { - buttons:[ - { - className:'edui-okbutton', - label:editor.getLang("ok"), - editor:editor, - onclick:function () { - dialog.close(true); - } - }, - { - className:'edui-cancelbutton', - label:editor.getLang("cancel"), - editor:editor, - onclick:function () { - dialog.close(false); - } - } - ] - } : {})); - - editor.ui._dialogs[cmd + "Dialog"] = dialog; - } - - var ui = new editorui.Button({ - className:'edui-for-' + cmd, - title:title, - onclick:function () { - if (dialog) { - switch (cmd) { - case "wordimage": - var images = editor.execCommand("wordimage"); - if (images && images.length) { - dialog.render(); - dialog.open(); - } - break; - case "scrawl": - if (editor.queryCommandState("scrawl") != -1) { - dialog.render(); - dialog.open(); - } - - break; - default: - dialog.render(); - dialog.open(); - } - } - }, - theme:editor.options.theme, - disabled:(cmd == 'scrawl' && editor.queryCommandState("scrawl") == -1) || ( cmd == 'charts' ) - }); - editorui.buttons[cmd] = ui; - editor.addListener('selectionchange', function () { - //只存在于右键菜单而无工具栏按钮的ui不需要检测状态 - var unNeedCheckState = {'edittable':1}; - if (cmd in unNeedCheckState)return; - - var state = editor.queryCommandState(cmd); - if (ui.getDom()) { - ui.setDisabled(state == -1); - ui.setChecked(state); - } - - }); - - return ui; - }; - })(ci.toLowerCase()) - } - })(p, dialogBtns[p]); - } - - editorui.snapscreen = function (editor, iframeUrl, title) { - title = editor.options.labelMap['snapscreen'] || editor.getLang("labelMap.snapscreen") || ''; - var ui = new editorui.Button({ - className:'edui-for-snapscreen', - title:title, - onclick:function () { - editor.execCommand("snapscreen"); - }, - theme:editor.options.theme - - }); - editorui.buttons['snapscreen'] = ui; - iframeUrl = iframeUrl || (editor.options.iframeUrlMap || {})["snapscreen"] || iframeUrlMap["snapscreen"]; - if (iframeUrl) { - var dialog = new editorui.Dialog({ - iframeUrl:editor.ui.mapUrl(iframeUrl), - editor:editor, - className:'edui-for-snapscreen', - title:title, - buttons:[ - { - className:'edui-okbutton', - label:editor.getLang("ok"), - editor:editor, - onclick:function () { - dialog.close(true); - } - }, - { - className:'edui-cancelbutton', - label:editor.getLang("cancel"), - editor:editor, - onclick:function () { - dialog.close(false); - } - } - ] - - }); - dialog.render(); - editor.ui._dialogs["snapscreenDialog"] = dialog; - } - editor.addListener('selectionchange', function () { - ui.setDisabled(editor.queryCommandState('snapscreen') == -1); - }); - return ui; - }; - - editorui.insertcode = function (editor, list, title) { - list = editor.options['insertcode'] || []; - title = editor.options.labelMap['insertcode'] || editor.getLang("labelMap.insertcode") || ''; - // if (!list.length) return; - var items = []; - utils.each(list,function(key,val){ - items.push({ - label:key, - value:val, - theme:editor.options.theme, - renderLabelHtml:function () { - return '
    ' + (this.label || '') + '
    '; - } - }); - }); - - var ui = new editorui.Combox({ - editor:editor, - items:items, - onselect:function (t, index) { - editor.execCommand('insertcode', this.items[index].value); - }, - onbuttonclick:function () { - this.showPopup(); - }, - title:title, - initValue:title, - className:'edui-for-insertcode', - indexByValue:function (value) { - if (value) { - for (var i = 0, ci; ci = this.items[i]; i++) { - if (ci.value.indexOf(value) != -1) - return i; - } - } - - return -1; - } - }); - editorui.buttons['insertcode'] = ui; - editor.addListener('selectionchange', function (type, causeByUi, uiReady) { - if (!uiReady) { - var state = editor.queryCommandState('insertcode'); - if (state == -1) { - ui.setDisabled(true); - } else { - ui.setDisabled(false); - var value = editor.queryCommandValue('insertcode'); - if(!value){ - ui.setValue(title); - return; - } - //trace:1871 ie下从源码模式切换回来时,字体会带单引号,而且会有逗号 - value && (value = value.replace(/['"]/g, '').split(',')[0]); - ui.setValue(value); - - } - } - - }); - return ui; - }; - editorui.fontfamily = function (editor, list, title) { - - list = editor.options['fontfamily'] || []; - title = editor.options.labelMap['fontfamily'] || editor.getLang("labelMap.fontfamily") || ''; - if (!list.length) return; - for (var i = 0, ci, items = []; ci = list[i]; i++) { - var langLabel = editor.getLang('fontfamily')[ci.name] || ""; - (function (key, val) { - items.push({ - label:key, - value:val, - theme:editor.options.theme, - renderLabelHtml:function () { - return '
    ' + (this.label || '') + '
    '; - } - }); - })(ci.label || langLabel, ci.val) - } - var ui = new editorui.Combox({ - editor:editor, - items:items, - onselect:function (t, index) { - editor.execCommand('FontFamily', this.items[index].value); - }, - onbuttonclick:function () { - this.showPopup(); - }, - title:title, - initValue:title, - className:'edui-for-fontfamily', - indexByValue:function (value) { - if (value) { - for (var i = 0, ci; ci = this.items[i]; i++) { - if (ci.value.indexOf(value) != -1) - return i; - } - } - - return -1; - } - }); - editorui.buttons['fontfamily'] = ui; - editor.addListener('selectionchange', function (type, causeByUi, uiReady) { - if (!uiReady) { - var state = editor.queryCommandState('FontFamily'); - if (state == -1) { - ui.setDisabled(true); - } else { - ui.setDisabled(false); - var value = editor.queryCommandValue('FontFamily'); - //trace:1871 ie下从源码模式切换回来时,字体会带单引号,而且会有逗号 - value && (value = value.replace(/['"]/g, '').split(',')[0]); - ui.setValue(value); - - } - } - - }); - return ui; - }; - - editorui.fontsize = function (editor, list, title) { - title = editor.options.labelMap['fontsize'] || editor.getLang("labelMap.fontsize") || ''; - list = list || editor.options['fontsize'] || []; - if (!list.length) return; - var items = []; - for (var i = 0; i < list.length; i++) { - var size = list[i] + 'px'; - items.push({ - label:size, - value:size, - theme:editor.options.theme, - renderLabelHtml:function () { - return '
    ' + (this.label || '') + '
    '; - } - }); - } - var ui = new editorui.Combox({ - editor:editor, - items:items, - title:title, - initValue:title, - onselect:function (t, index) { - editor.execCommand('FontSize', this.items[index].value); - }, - onbuttonclick:function () { - this.showPopup(); - }, - className:'edui-for-fontsize' - }); - editorui.buttons['fontsize'] = ui; - editor.addListener('selectionchange', function (type, causeByUi, uiReady) { - if (!uiReady) { - var state = editor.queryCommandState('FontSize'); - if (state == -1) { - ui.setDisabled(true); - } else { - ui.setDisabled(false); - ui.setValue(editor.queryCommandValue('FontSize')); - } - } - - }); - return ui; - }; - - editorui.paragraph = function (editor, list, title) { - title = editor.options.labelMap['paragraph'] || editor.getLang("labelMap.paragraph") || ''; - list = editor.options['paragraph'] || []; - if (utils.isEmptyObject(list)) return; - var items = []; - for (var i in list) { - items.push({ - value:i, - label:list[i] || editor.getLang("paragraph")[i], - theme:editor.options.theme, - renderLabelHtml:function () { - return '
    ' + (this.label || '') + '
    '; - } - }) - } - var ui = new editorui.Combox({ - editor:editor, - items:items, - title:title, - initValue:title, - className:'edui-for-paragraph', - onselect:function (t, index) { - editor.execCommand('Paragraph', this.items[index].value); - }, - onbuttonclick:function () { - this.showPopup(); - } - }); - editorui.buttons['paragraph'] = ui; - editor.addListener('selectionchange', function (type, causeByUi, uiReady) { - if (!uiReady) { - var state = editor.queryCommandState('Paragraph'); - if (state == -1) { - ui.setDisabled(true); - } else { - ui.setDisabled(false); - var value = editor.queryCommandValue('Paragraph'); - var index = ui.indexByValue(value); - if (index != -1) { - ui.setValue(value); - } else { - ui.setValue(ui.initValue); - } - } - } - - }); - return ui; - }; - - - //自定义标题 - editorui.customstyle = function (editor) { - var list = editor.options['customstyle'] || [], - title = editor.options.labelMap['customstyle'] || editor.getLang("labelMap.customstyle") || ''; - if (!list.length)return; - var langCs = editor.getLang('customstyle'); - for (var i = 0, items = [], t; t = list[i++];) { - (function (t) { - var ck = {}; - ck.label = t.label ? t.label : langCs[t.name]; - ck.style = t.style; - ck.className = t.className; - ck.tag = t.tag; - items.push({ - label:ck.label, - value:ck, - theme:editor.options.theme, - renderLabelHtml:function () { - return '
    ' + '<' + ck.tag + ' ' + (ck.className ? ' class="' + ck.className + '"' : "") - + (ck.style ? ' style="' + ck.style + '"' : "") + '>' + ck.label + "<\/" + ck.tag + ">" - + '
    '; - } - }); - })(t); - } - - var ui = new editorui.Combox({ - editor:editor, - items:items, - title:title, - initValue:title, - className:'edui-for-customstyle', - onselect:function (t, index) { - editor.execCommand('customstyle', this.items[index].value); - }, - onbuttonclick:function () { - this.showPopup(); - }, - indexByValue:function (value) { - for (var i = 0, ti; ti = this.items[i++];) { - if (ti.label == value) { - return i - 1 - } - } - return -1; - } - }); - editorui.buttons['customstyle'] = ui; - editor.addListener('selectionchange', function (type, causeByUi, uiReady) { - if (!uiReady) { - var state = editor.queryCommandState('customstyle'); - if (state == -1) { - ui.setDisabled(true); - } else { - ui.setDisabled(false); - var value = editor.queryCommandValue('customstyle'); - var index = ui.indexByValue(value); - if (index != -1) { - ui.setValue(value); - } else { - ui.setValue(ui.initValue); - } - } - } - - }); - return ui; - }; - editorui.inserttable = function (editor, iframeUrl, title) { - title = editor.options.labelMap['inserttable'] || editor.getLang("labelMap.inserttable") || ''; - var ui = new editorui.TableButton({ - editor:editor, - title:title, - className:'edui-for-inserttable', - onpicktable:function (t, numCols, numRows) { - editor.execCommand('InsertTable', {numRows:numRows, numCols:numCols, border:1}); - }, - onbuttonclick:function () { - this.showPopup(); - } - }); - editorui.buttons['inserttable'] = ui; - editor.addListener('selectionchange', function () { - ui.setDisabled(editor.queryCommandState('inserttable') == -1); - }); - return ui; - }; - - editorui.lineheight = function (editor) { - var val = editor.options.lineheight || []; - if (!val.length)return; - for (var i = 0, ci, items = []; ci = val[i++];) { - items.push({ - //todo:写死了 - label:ci, - value:ci, - theme:editor.options.theme, - onclick:function () { - editor.execCommand("lineheight", this.value); - } - }) - } - var ui = new editorui.MenuButton({ - editor:editor, - className:'edui-for-lineheight', - title:editor.options.labelMap['lineheight'] || editor.getLang("labelMap.lineheight") || '', - items:items, - onbuttonclick:function () { - var value = editor.queryCommandValue('LineHeight') || this.value; - editor.execCommand("LineHeight", value); - } - }); - editorui.buttons['lineheight'] = ui; - editor.addListener('selectionchange', function () { - var state = editor.queryCommandState('LineHeight'); - if (state == -1) { - ui.setDisabled(true); - } else { - ui.setDisabled(false); - var value = editor.queryCommandValue('LineHeight'); - value && ui.setValue((value + '').replace(/cm/, '')); - ui.setChecked(state) - } - }); - return ui; - }; - - var rowspacings = ['top', 'bottom']; - for (var r = 0, ri; ri = rowspacings[r++];) { - (function (cmd) { - editorui['rowspacing' + cmd] = function (editor) { - var val = editor.options['rowspacing' + cmd] || []; - if (!val.length) return null; - for (var i = 0, ci, items = []; ci = val[i++];) { - items.push({ - label:ci, - value:ci, - theme:editor.options.theme, - onclick:function () { - editor.execCommand("rowspacing", this.value, cmd); - } - }) - } - var ui = new editorui.MenuButton({ - editor:editor, - className:'edui-for-rowspacing' + cmd, - title:editor.options.labelMap['rowspacing' + cmd] || editor.getLang("labelMap.rowspacing" + cmd) || '', - items:items, - onbuttonclick:function () { - var value = editor.queryCommandValue('rowspacing', cmd) || this.value; - editor.execCommand("rowspacing", value, cmd); - } - }); - editorui.buttons[cmd] = ui; - editor.addListener('selectionchange', function () { - var state = editor.queryCommandState('rowspacing', cmd); - if (state == -1) { - ui.setDisabled(true); - } else { - ui.setDisabled(false); - var value = editor.queryCommandValue('rowspacing', cmd); - value && ui.setValue((value + '').replace(/%/, '')); - ui.setChecked(state) - } - }); - return ui; - } - })(ri) - } - //有序,无序列表 - var lists = ['insertorderedlist', 'insertunorderedlist']; - for (var l = 0, cl; cl = lists[l++];) { - (function (cmd) { - editorui[cmd] = function (editor) { - var vals = editor.options[cmd], - _onMenuClick = function () { - editor.execCommand(cmd, this.value); - }, items = []; - for (var i in vals) { - items.push({ - label:vals[i] || editor.getLang()[cmd][i] || "", - value:i, - theme:editor.options.theme, - onclick:_onMenuClick - }) - } - var ui = new editorui.MenuButton({ - editor:editor, - className:'edui-for-' + cmd, - title:editor.getLang("labelMap." + cmd) || '', - 'items':items, - onbuttonclick:function () { - var value = editor.queryCommandValue(cmd) || this.value; - editor.execCommand(cmd, value); - } - }); - editorui.buttons[cmd] = ui; - editor.addListener('selectionchange', function () { - var state = editor.queryCommandState(cmd); - if (state == -1) { - ui.setDisabled(true); - } else { - ui.setDisabled(false); - var value = editor.queryCommandValue(cmd); - ui.setValue(value); - ui.setChecked(state) - } - }); - return ui; - }; - })(cl) - } - - editorui.fullscreen = function (editor, title) { - title = editor.options.labelMap['fullscreen'] || editor.getLang("labelMap.fullscreen") || ''; - var ui = new editorui.Button({ - className:'edui-for-fullscreen', - title:title, - theme:editor.options.theme, - onclick:function () { - if (editor.ui) { - editor.ui.setFullScreen(!editor.ui.isFullScreen()); - } - this.setChecked(editor.ui.isFullScreen()); - } - }); - editorui.buttons['fullscreen'] = ui; - editor.addListener('selectionchange', function () { - var state = editor.queryCommandState('fullscreen'); - ui.setDisabled(state == -1); - ui.setChecked(editor.ui.isFullScreen()); - }); - return ui; - }; - - // 表情 - editorui["emotion"] = function (editor, iframeUrl) { - var cmd = "emotion"; - var ui = new editorui.MultiMenuPop({ - title:editor.options.labelMap[cmd] || editor.getLang("labelMap." + cmd + "") || '', - editor:editor, - className:'edui-for-' + cmd, - iframeUrl:editor.ui.mapUrl(iframeUrl || (editor.options.iframeUrlMap || {})[cmd] || iframeUrlMap[cmd]) - }); - editorui.buttons[cmd] = ui; - - editor.addListener('selectionchange', function () { - ui.setDisabled(editor.queryCommandState(cmd) == -1) - }); - return ui; - }; - - editorui.autotypeset = function (editor) { - var ui = new editorui.AutoTypeSetButton({ - editor:editor, - title:editor.options.labelMap['autotypeset'] || editor.getLang("labelMap.autotypeset") || '', - className:'edui-for-autotypeset', - onbuttonclick:function () { - editor.execCommand('autotypeset') - } - }); - editorui.buttons['autotypeset'] = ui; - editor.addListener('selectionchange', function () { - ui.setDisabled(editor.queryCommandState('autotypeset') == -1); - }); - return ui; - }; - - /* 简单上传插件 */ - editorui["simpleupload"] = function (editor) { - var name = 'simpleupload', - ui = new editorui.Button({ - className:'edui-for-' + name, - title:editor.options.labelMap[name] || editor.getLang("labelMap." + name) || '', - onclick:function () {}, - theme:editor.options.theme, - showText:false - }); - editorui.buttons[name] = ui; - editor.addListener('ready', function() { - var b = ui.getDom('body'), - iconSpan = b.children[0]; - editor.fireEvent('simpleuploadbtnready', iconSpan); - }); - editor.addListener('selectionchange', function (type, causeByUi, uiReady) { - var state = editor.queryCommandState(name); - if (state == -1) { - ui.setDisabled(true); - ui.setChecked(false); - } else { - if (!uiReady) { - ui.setDisabled(false); - ui.setChecked(state); - } - } - }); - return ui; - }; - -})(); - - -// adapter/editor.js -///import core -///commands 全屏 -///commandsName FullScreen -///commandsTitle 全屏 -(function () { - var utils = baidu.editor.utils, - uiUtils = baidu.editor.ui.uiUtils, - UIBase = baidu.editor.ui.UIBase, - domUtils = baidu.editor.dom.domUtils; - var nodeStack = []; - - function EditorUI(options) { - this.initOptions(options); - this.initEditorUI(); - } - - EditorUI.prototype = { - uiName:'editor', - initEditorUI:function () { - this.editor.ui = this; - this._dialogs = {}; - this.initUIBase(); - this._initToolbars(); - var editor = this.editor, - me = this; - - editor.addListener('ready', function () { - //提供getDialog方法 - editor.getDialog = function (name) { - return editor.ui._dialogs[name + "Dialog"]; - }; - domUtils.on(editor.window, 'scroll', function (evt) { - baidu.editor.ui.Popup.postHide(evt); - }); - //提供编辑器实时宽高(全屏时宽高不变化) - editor.ui._actualFrameWidth = editor.options.initialFrameWidth; - - UE.browser.ie && UE.browser.version === 6 && editor.container.ownerDocument.execCommand("BackgroundImageCache", false, true); - - //display bottom-bar label based on config - if (editor.options.elementPathEnabled) { - editor.ui.getDom('elementpath').innerHTML = '
    ' + editor.getLang("elementPathTip") + ':
    '; - } - if (editor.options.wordCount) { - function countFn() { - setCount(editor,me); - domUtils.un(editor.document, "click", arguments.callee); - } - domUtils.on(editor.document, "click", countFn); - editor.ui.getDom('wordcount').innerHTML = editor.getLang("wordCountTip"); - } - editor.ui._scale(); - if (editor.options.scaleEnabled) { - if (editor.autoHeightEnabled) { - editor.disableAutoHeight(); - } - me.enableScale(); - } else { - me.disableScale(); - } - if (!editor.options.elementPathEnabled && !editor.options.wordCount && !editor.options.scaleEnabled) { - editor.ui.getDom('elementpath').style.display = "none"; - editor.ui.getDom('wordcount').style.display = "none"; - editor.ui.getDom('scale').style.display = "none"; - } - - if (!editor.selection.isFocus())return; - editor.fireEvent('selectionchange', false, true); - - - }); - - editor.addListener('mousedown', function (t, evt) { - var el = evt.target || evt.srcElement; - baidu.editor.ui.Popup.postHide(evt, el); - baidu.editor.ui.ShortCutMenu.postHide(evt); - - }); - editor.addListener("delcells", function () { - if (UE.ui['edittip']) { - new UE.ui['edittip'](editor); - } - editor.getDialog('edittip').open(); - }); - - var pastePop, isPaste = false, timer; - editor.addListener("afterpaste", function () { - if(editor.queryCommandState('pasteplain')) - return; - if(baidu.editor.ui.PastePicker){ - pastePop = new baidu.editor.ui.Popup({ - content:new baidu.editor.ui.PastePicker({editor:editor}), - editor:editor, - className:'edui-wordpastepop' - }); - pastePop.render(); - } - isPaste = true; - }); - - editor.addListener("afterinserthtml", function () { - clearTimeout(timer); - timer = setTimeout(function () { - if (pastePop && (isPaste || editor.ui._isTransfer)) { - if(pastePop.isHidden()){ - var span = domUtils.createElement(editor.document, 'span', { - 'style':"line-height:0px;", - 'innerHTML':'\ufeff' - }), - range = editor.selection.getRange(); - range.insertNode(span); - var tmp= getDomNode(span, 'firstChild', 'previousSibling'); - tmp && pastePop.showAnchor(tmp.nodeType == 3 ? tmp.parentNode : tmp); - domUtils.remove(span); - }else{ - pastePop.show(); - } - delete editor.ui._isTransfer; - isPaste = false; - } - }, 200) - }); - editor.addListener('contextmenu', function (t, evt) { - baidu.editor.ui.Popup.postHide(evt); - }); - editor.addListener('keydown', function (t, evt) { - if (pastePop) pastePop.dispose(evt); - var keyCode = evt.keyCode || evt.which; - if(evt.altKey&&keyCode==90){ - UE.ui.buttons['fullscreen'].onclick(); - } - }); - editor.addListener('wordcount', function (type) { - setCount(this,me); - }); - function setCount(editor,ui) { - editor.setOpt({ - wordCount:true, - maximumWords:10000, - wordCountMsg:editor.options.wordCountMsg || editor.getLang("wordCountMsg"), - wordOverFlowMsg:editor.options.wordOverFlowMsg || editor.getLang("wordOverFlowMsg") - }); - var opt = editor.options, - max = opt.maximumWords, - msg = opt.wordCountMsg , - errMsg = opt.wordOverFlowMsg, - countDom = ui.getDom('wordcount'); - if (!opt.wordCount) { - return; - } - var count = editor.getContentLength(true); - if (count > max) { - countDom.innerHTML = errMsg; - editor.fireEvent("wordcountoverflow"); - } else { - countDom.innerHTML = msg.replace("{#leave}", max - count).replace("{#count}", count); - } - } - - editor.addListener('selectionchange', function () { - if (editor.options.elementPathEnabled) { - me[(editor.queryCommandState('elementpath') == -1 ? 'dis' : 'en') + 'ableElementPath']() - } - if (editor.options.scaleEnabled) { - me[(editor.queryCommandState('scale') == -1 ? 'dis' : 'en') + 'ableScale'](); - - } - }); - var popup = new baidu.editor.ui.Popup({ - editor:editor, - content:'', - className:'edui-bubble', - _onEditButtonClick:function () { - this.hide(); - editor.ui._dialogs.linkDialog.open(); - }, - _onImgEditButtonClick:function (name) { - this.hide(); - editor.ui._dialogs[name] && editor.ui._dialogs[name].open(); - - }, - _onImgSetFloat:function (value) { - this.hide(); - editor.execCommand("imagefloat", value); - - }, - _setIframeAlign:function (value) { - var frame = popup.anchorEl; - var newFrame = frame.cloneNode(true); - switch (value) { - case -2: - newFrame.setAttribute("align", ""); - break; - case -1: - newFrame.setAttribute("align", "left"); - break; - case 1: - newFrame.setAttribute("align", "right"); - break; - } - frame.parentNode.insertBefore(newFrame, frame); - domUtils.remove(frame); - popup.anchorEl = newFrame; - popup.showAnchor(popup.anchorEl); - }, - _updateIframe:function () { - var frame = editor._iframe = popup.anchorEl; - if(domUtils.hasClass(frame, 'ueditor_baidumap')) { - editor.selection.getRange().selectNode(frame).select(); - editor.ui._dialogs.mapDialog.open(); - popup.hide(); - } else { - editor.ui._dialogs.insertframeDialog.open(); - popup.hide(); - } - }, - _onRemoveButtonClick:function (cmdName) { - editor.execCommand(cmdName); - this.hide(); - }, - queryAutoHide:function (el) { - if (el && el.ownerDocument == editor.document) { - if (el.tagName.toLowerCase() == 'img' || domUtils.findParentByTagName(el, 'a', true)) { - return el !== popup.anchorEl; - } - } - return baidu.editor.ui.Popup.prototype.queryAutoHide.call(this, el); - } - }); - popup.render(); - if (editor.options.imagePopup) { - editor.addListener('mouseover', function (t, evt) { - evt = evt || window.event; - var el = evt.target || evt.srcElement; - if (editor.ui._dialogs.insertframeDialog && /iframe/ig.test(el.tagName)) { - var html = popup.formatHtml( - '' + editor.getLang("property") + ': ' + editor.getLang("default") + '  ' + editor.getLang("justifyleft") + '  ' + editor.getLang("justifyright") + '  ' + - ' ' + editor.getLang("modify") + ''); - if (html) { - popup.getDom('content').innerHTML = html; - popup.anchorEl = el; - popup.showAnchor(popup.anchorEl); - } else { - popup.hide(); - } - } - }); - editor.addListener('selectionchange', function (t, causeByUi) { - if (!causeByUi) return; - var html = '', str = "", - img = editor.selection.getRange().getClosedNode(), - dialogs = editor.ui._dialogs; - if (img && img.tagName == 'IMG') { - var dialogName = 'insertimageDialog'; - if (img.className.indexOf("edui-faked-video") != -1 || img.className.indexOf("edui-upload-video") != -1) { - dialogName = "insertvideoDialog" - } - if (img.className.indexOf("edui-faked-webapp") != -1) { - dialogName = "webappDialog" - } - if (img.src.indexOf("http://api.map.baidu.com") != -1) { - dialogName = "mapDialog" - } - if (img.className.indexOf("edui-faked-music") != -1) { - dialogName = "musicDialog" - } - if (img.src.indexOf("http://maps.google.com/maps/api/staticmap") != -1) { - dialogName = "gmapDialog" - } - if (img.getAttribute("anchorname")) { - dialogName = "anchorDialog"; - html = popup.formatHtml( - '' + editor.getLang("property") + ': ' + editor.getLang("modify") + '  ' + - '' + editor.getLang("delete") + ''); - } - if (img.getAttribute("word_img")) { - //todo 放到dialog去做查询 - editor.word_img = [img.getAttribute("word_img")]; - dialogName = "wordimageDialog" - } - if(domUtils.hasClass(img, 'loadingclass') || domUtils.hasClass(img, 'loaderrorclass')) { - dialogName = ""; - } - if (!dialogs[dialogName]) { - return; - } - str = '' + editor.getLang("property") + ': '+ - '' + editor.getLang("default") + '  ' + - '' + editor.getLang("justifyleft") + '  ' + - '' + editor.getLang("justifyright") + '  ' + - '' + editor.getLang("justifycenter") + '  '+ - '' + editor.getLang("modify") + ''; - - !html && (html = popup.formatHtml(str)) - - } - if (editor.ui._dialogs.linkDialog) { - var link = editor.queryCommandValue('link'); - var url; - if (link && (url = (link.getAttribute('_href') || link.getAttribute('href', 2)))) { - var txt = url; - if (url.length > 30) { - txt = url.substring(0, 20) + "..."; - } - if (html) { - html += '
    ' - } - html += popup.formatHtml( - '' + editor.getLang("anthorMsg") + ': ' + txt + '' + - ' ' + editor.getLang("modify") + '' + - ' ' + editor.getLang("clear") + ''); - popup.showAnchor(link); - } - } - - if (html) { - popup.getDom('content').innerHTML = html; - popup.anchorEl = img || link; - popup.showAnchor(popup.anchorEl); - } else { - popup.hide(); - } - }); - } - - }, - _initToolbars:function () { - var editor = this.editor; - var toolbars = this.toolbars || []; - var toolbarUis = []; - for (var i = 0; i < toolbars.length; i++) { - var toolbar = toolbars[i]; - var toolbarUi = new baidu.editor.ui.Toolbar({theme:editor.options.theme}); - for (var j = 0; j < toolbar.length; j++) { - var toolbarItem = toolbar[j]; - var toolbarItemUi = null; - if (typeof toolbarItem == 'string') { - toolbarItem = toolbarItem.toLowerCase(); - if (toolbarItem == '|') { - toolbarItem = 'Separator'; - } - if(toolbarItem == '||'){ - toolbarItem = 'Breakline'; - } - if (baidu.editor.ui[toolbarItem]) { - toolbarItemUi = new baidu.editor.ui[toolbarItem](editor); - } - - //fullscreen这里单独处理一下,放到首行去 - if (toolbarItem == 'fullscreen') { - if (toolbarUis && toolbarUis[0]) { - toolbarUis[0].items.splice(0, 0, toolbarItemUi); - } else { - toolbarItemUi && toolbarUi.items.splice(0, 0, toolbarItemUi); - } - - continue; - - - } - } else { - toolbarItemUi = toolbarItem; - } - if (toolbarItemUi && toolbarItemUi.id) { - - toolbarUi.add(toolbarItemUi); - } - } - toolbarUis[i] = toolbarUi; - } - - //接受外部定制的UI - - utils.each(UE._customizeUI,function(obj,key){ - var itemUI,index; - if(obj.id && obj.id != editor.key){ - return false; - } - itemUI = obj.execFn.call(editor,editor,key); - if(itemUI){ - index = obj.index; - if(index === undefined){ - index = toolbarUi.items.length; - } - toolbarUi.add(itemUI,index) - } - }); - - this.toolbars = toolbarUis; - }, - getHtmlTpl:function () { - return '
    ' + - '
    ' + - (this.toolbars.length ? - '
    ' + - this.renderToolbarBoxHtml() + - '
    ' : '') + - '' + - '
    ' + - '
    ' + - '
    ' + - '
    ' + - //modify wdcount by matao - '
    ' + - '' + - '' + - '' + - '
    ' + - '
    ' + - '
    '; - }, - showWordImageDialog:function () { - this._dialogs['wordimageDialog'].open(); - }, - renderToolbarBoxHtml:function () { - var buff = []; - for (var i = 0; i < this.toolbars.length; i++) { - buff.push(this.toolbars[i].renderHtml()); - } - return buff.join(''); - }, - setFullScreen:function (fullscreen) { - - var editor = this.editor, - container = editor.container.parentNode.parentNode; - if (this._fullscreen != fullscreen) { - this._fullscreen = fullscreen; - this.editor.fireEvent('beforefullscreenchange', fullscreen); - if (baidu.editor.browser.gecko) { - var bk = editor.selection.getRange().createBookmark(); - } - if (fullscreen) { - while (container.tagName != "BODY") { - var position = baidu.editor.dom.domUtils.getComputedStyle(container, "position"); - nodeStack.push(position); - container.style.position = "static"; - container = container.parentNode; - } - this._bakHtmlOverflow = document.documentElement.style.overflow; - this._bakBodyOverflow = document.body.style.overflow; - this._bakAutoHeight = this.editor.autoHeightEnabled; - this._bakScrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop); - - this._bakEditorContaninerWidth = editor.iframe.parentNode.offsetWidth; - if (this._bakAutoHeight) { - //当全屏时不能执行自动长高 - editor.autoHeightEnabled = false; - this.editor.disableAutoHeight(); - } - - document.documentElement.style.overflow = 'hidden'; - //修复,滚动条不收起的问题 - - window.scrollTo(0,window.scrollY); - this._bakCssText = this.getDom().style.cssText; - this._bakCssText1 = this.getDom('iframeholder').style.cssText; - editor.iframe.parentNode.style.width = ''; - this._updateFullScreen(); - } else { - while (container.tagName != "BODY") { - container.style.position = nodeStack.shift(); - container = container.parentNode; - } - this.getDom().style.cssText = this._bakCssText; - this.getDom('iframeholder').style.cssText = this._bakCssText1; - if (this._bakAutoHeight) { - editor.autoHeightEnabled = true; - this.editor.enableAutoHeight(); - } - - document.documentElement.style.overflow = this._bakHtmlOverflow; - document.body.style.overflow = this._bakBodyOverflow; - editor.iframe.parentNode.style.width = this._bakEditorContaninerWidth + 'px'; - window.scrollTo(0, this._bakScrollTop); - } - if (browser.gecko && editor.body.contentEditable === 'true') { - var input = document.createElement('input'); - document.body.appendChild(input); - editor.body.contentEditable = false; - setTimeout(function () { - input.focus(); - setTimeout(function () { - editor.body.contentEditable = true; - editor.fireEvent('fullscreenchanged', fullscreen); - editor.selection.getRange().moveToBookmark(bk).select(true); - baidu.editor.dom.domUtils.remove(input); - fullscreen && window.scroll(0, 0); - }, 0) - }, 0) - } - - if(editor.body.contentEditable === 'true'){ - this.editor.fireEvent('fullscreenchanged', fullscreen); - this.triggerLayout(); - } - - } - }, - _updateFullScreen:function () { - if (this._fullscreen) { - var vpRect = uiUtils.getViewportRect(); - this.getDom().style.cssText = 'border:0;position:absolute;left:0;top:' + (this.editor.options.topOffset || 0) + 'px;width:' + vpRect.width + 'px;height:' + vpRect.height + 'px;z-index:' + (this.getDom().style.zIndex * 1 + 100); - uiUtils.setViewportOffset(this.getDom(), { left:0, top:this.editor.options.topOffset || 0 }); - this.editor.setHeight(vpRect.height - this.getDom('toolbarbox').offsetHeight - this.getDom('bottombar').offsetHeight - (this.editor.options.topOffset || 0),true); - //不手动调一下,会导致全屏失效 - if(browser.gecko){ - try{ - window.onresize(); - }catch(e){ - - } - - } - } - }, - _updateElementPath:function () { - var bottom = this.getDom('elementpath'), list; - if (this.elementPathEnabled && (list = this.editor.queryCommandValue('elementpath'))) { - - var buff = []; - for (var i = 0, ci; ci = list[i]; i++) { - buff[i] = this.formatHtml('' + ci + ''); - } - bottom.innerHTML = '
    ' + this.editor.getLang("elementPathTip") + ': ' + buff.join(' > ') + '
    '; - - } else { - bottom.style.display = 'none' - } - }, - disableElementPath:function () { - var bottom = this.getDom('elementpath'); - bottom.innerHTML = ''; - bottom.style.display = 'none'; - this.elementPathEnabled = false; - - }, - enableElementPath:function () { - var bottom = this.getDom('elementpath'); - bottom.style.display = ''; - this.elementPathEnabled = true; - this._updateElementPath(); - }, - _scale:function () { - var doc = document, - editor = this.editor, - editorHolder = editor.container, - editorDocument = editor.document, - toolbarBox = this.getDom("toolbarbox"), - bottombar = this.getDom("bottombar"), - scale = this.getDom("scale"), - scalelayer = this.getDom("scalelayer"); - - var isMouseMove = false, - position = null, - minEditorHeight = 0, - minEditorWidth = editor.options.minFrameWidth, - pageX = 0, - pageY = 0, - scaleWidth = 0, - scaleHeight = 0; - - function down() { - position = domUtils.getXY(editorHolder); - - if (!minEditorHeight) { - minEditorHeight = editor.options.minFrameHeight + toolbarBox.offsetHeight + bottombar.offsetHeight; - } - - scalelayer.style.cssText = "position:absolute;left:0;display:;top:0;background-color:#41ABFF;opacity:0.4;filter: Alpha(opacity=40);width:" + editorHolder.offsetWidth + "px;height:" - + editorHolder.offsetHeight + "px;z-index:" + (editor.options.zIndex + 1); - - domUtils.on(doc, "mousemove", move); - domUtils.on(editorDocument, "mouseup", up); - domUtils.on(doc, "mouseup", up); - } - - var me = this; - //by xuheng 全屏时关掉缩放 - this.editor.addListener('fullscreenchanged', function (e, fullScreen) { - if (fullScreen) { - me.disableScale(); - - } else { - if (me.editor.options.scaleEnabled) { - me.enableScale(); - var tmpNode = me.editor.document.createElement('span'); - me.editor.body.appendChild(tmpNode); - me.editor.body.style.height = Math.max(domUtils.getXY(tmpNode).y, me.editor.iframe.offsetHeight - 20) + 'px'; - domUtils.remove(tmpNode) - } - } - }); - function move(event) { - clearSelection(); - var e = event || window.event; - pageX = e.pageX || (doc.documentElement.scrollLeft + e.clientX); - pageY = e.pageY || (doc.documentElement.scrollTop + e.clientY); - scaleWidth = pageX - position.x; - scaleHeight = pageY - position.y; - - if (scaleWidth >= minEditorWidth) { - isMouseMove = true; - scalelayer.style.width = scaleWidth + 'px'; - } - if (scaleHeight >= minEditorHeight) { - isMouseMove = true; - scalelayer.style.height = scaleHeight + "px"; - } - } - - function up() { - if (isMouseMove) { - isMouseMove = false; - editor.ui._actualFrameWidth = scalelayer.offsetWidth - 2; - editorHolder.style.width = editor.ui._actualFrameWidth + 'px'; - - editor.setHeight(scalelayer.offsetHeight - bottombar.offsetHeight - toolbarBox.offsetHeight - 2,true); - } - if (scalelayer) { - scalelayer.style.display = "none"; - } - clearSelection(); - domUtils.un(doc, "mousemove", move); - domUtils.un(editorDocument, "mouseup", up); - domUtils.un(doc, "mouseup", up); - } - - function clearSelection() { - if (browser.ie) - doc.selection.clear(); - else - window.getSelection().removeAllRanges(); - } - - this.enableScale = function () { - //trace:2868 - if (editor.queryCommandState("source") == 1) return; - scale.style.display = ""; - this.scaleEnabled = true; - domUtils.on(scale, "mousedown", down); - }; - this.disableScale = function () { - scale.style.display = "none"; - this.scaleEnabled = false; - domUtils.un(scale, "mousedown", down); - }; - }, - isFullScreen:function () { - return this._fullscreen; - }, - postRender:function () { - UIBase.prototype.postRender.call(this); - for (var i = 0; i < this.toolbars.length; i++) { - this.toolbars[i].postRender(); - } - var me = this; - var timerId, - domUtils = baidu.editor.dom.domUtils, - updateFullScreenTime = function () { - clearTimeout(timerId); - timerId = setTimeout(function () { - me._updateFullScreen(); - }); - }; - domUtils.on(window, 'resize', updateFullScreenTime); - - me.addListener('destroy', function () { - domUtils.un(window, 'resize', updateFullScreenTime); - clearTimeout(timerId); - }) - }, - showToolbarMsg:function (msg, flag) { - this.getDom('toolbarmsg_label').innerHTML = msg; - this.getDom('toolbarmsg').style.display = ''; - // - if (!flag) { - var w = this.getDom('upload_dialog'); - w.style.display = 'none'; - } - }, - hideToolbarMsg:function () { - this.getDom('toolbarmsg').style.display = 'none'; - }, - mapUrl:function (url) { - return url ? url.replace('~/', this.editor.options.UEDITOR_HOME_URL || '') : '' - }, - triggerLayout:function () { - var dom = this.getDom(); - if (dom.style.zoom == '1') { - dom.style.zoom = '100%'; - } else { - dom.style.zoom = '1'; - } - } - }; - utils.inherits(EditorUI, baidu.editor.ui.UIBase); - - - var instances = {}; - - - UE.ui.Editor = function (options) { - var editor = new UE.Editor(options); - editor.options.editor = editor; - utils.loadFile(document, { - href:editor.options.themePath + editor.options.theme + "/css/ueditor.css", - tag:"link", - type:"text/css", - rel:"stylesheet" - }); - - var oldRender = editor.render; - editor.render = function (holder) { - if (holder.constructor === String) { - editor.key = holder; - instances[holder] = editor; - } - utils.domReady(function () { - editor.langIsReady ? renderUI() : editor.addListener("langReady", renderUI); - function renderUI() { - editor.setOpt({ - labelMap:editor.options.labelMap || editor.getLang('labelMap') - }); - new EditorUI(editor.options); - if (holder) { - if (holder.constructor === String) { - holder = document.getElementById(holder); - } - holder && holder.getAttribute('name') && ( editor.options.textarea = holder.getAttribute('name')); - if (holder && /script|textarea/ig.test(holder.tagName)) { - var newDiv = document.createElement('div'); - holder.parentNode.insertBefore(newDiv, holder); - var cont = holder.value || holder.innerHTML; - editor.options.initialContent = /^[\t\r\n ]*$/.test(cont) ? editor.options.initialContent : - cont.replace(/>[\n\r\t]+([ ]{4})+/g, '>') - .replace(/[\n\r\t]+([ ]{4})+[\n\r\t]+<'); - holder.className && (newDiv.className = holder.className); - holder.style.cssText && (newDiv.style.cssText = holder.style.cssText); - if (/textarea/i.test(holder.tagName)) { - editor.textarea = holder; - editor.textarea.style.display = 'none'; - - - } else { - holder.parentNode.removeChild(holder); - - - } - if(holder.id){ - newDiv.id = holder.id; - domUtils.removeAttributes(holder,'id'); - } - holder = newDiv; - holder.innerHTML = ''; - } - - } - domUtils.addClass(holder, "edui-" + editor.options.theme); - editor.ui.render(holder); - var opt = editor.options; - //给实例添加一个编辑器的容器引用 - editor.container = editor.ui.getDom(); - var parents = domUtils.findParents(holder,true); - var displays = []; - for(var i = 0 ,ci;ci=parents[i];i++){ - displays[i] = ci.style.display; - ci.style.display = 'block' - } - if (opt.initialFrameWidth) { - opt.minFrameWidth = opt.initialFrameWidth; - } else { - opt.minFrameWidth = opt.initialFrameWidth = holder.offsetWidth; - var styleWidth = holder.style.width; - if(/%$/.test(styleWidth)) { - opt.initialFrameWidth = styleWidth; - } - } - if (opt.initialFrameHeight) { - opt.minFrameHeight = opt.initialFrameHeight; - } else { - opt.initialFrameHeight = opt.minFrameHeight = holder.offsetHeight; - } - for(var i = 0 ,ci;ci=parents[i];i++){ - ci.style.display = displays[i] - } - //编辑器最外容器设置了高度,会导致,编辑器不占位 - //todo 先去掉,没有找到原因 - if(holder.style.height){ - holder.style.height = '' - } - editor.container.style.width = opt.initialFrameWidth + (/%$/.test(opt.initialFrameWidth) ? '' : 'px'); - editor.container.style.zIndex = opt.zIndex; - oldRender.call(editor, editor.ui.getDom('iframeholder')); - editor.fireEvent("afteruiready"); - } - }) - }; - return editor; - }; - - - /** - * @file - * @name UE - * @short UE - * @desc UEditor的顶部命名空间 - */ - /** - * @name getEditor - * @since 1.2.4+ - * @grammar UE.getEditor(id,[opt]) => Editor实例 - * @desc 提供一个全局的方法得到编辑器实例 - * - * * ''id'' 放置编辑器的容器id, 如果容器下的编辑器已经存在,就直接返回 - * * ''opt'' 编辑器的可选参数 - * @example - * UE.getEditor('containerId',{onready:function(){//创建一个编辑器实例 - * this.setContent('hello') - * }}); - * UE.getEditor('containerId'); //返回刚创建的实例 - * - */ - UE.getEditor = function (id, opt) { - var editor = instances[id]; - if (!editor) { - editor = instances[id] = new UE.ui.Editor(opt); - editor.render(id); - } - return editor; - }; - - - UE.delEditor = function (id) { - var editor; - if (editor = instances[id]) { - editor.key && editor.destroy(); - delete instances[id] - } - }; - - UE.registerUI = function(uiName,fn,index,editorId){ - utils.each(uiName.split(/\s+/), function (name) { - UE._customizeUI[name] = { - id : editorId, - execFn:fn, - index:index - }; - }) - - } - -})(); - -// adapter/message.js -UE.registerUI('message', function(editor) { - - var editorui = baidu.editor.ui; - var Message = editorui.Message; - var holder; - var _messageItems = []; - var me = editor; - - me.addListener('ready', function(){ - holder = document.getElementById(me.ui.id + '_message_holder'); - updateHolderPos(); - setTimeout(function(){ - updateHolderPos(); - }, 500); - }); - - me.addListener('showmessage', function(type, opt){ - opt = utils.isString(opt) ? { - 'content': opt - } : opt; - var message = new Message({ - 'timeout': opt.timeout, - 'type': opt.type, - 'content': opt.content, - 'keepshow': opt.keepshow, - 'editor': me - }), - mid = opt.id || ('msg_' + (+new Date()).toString(36)); - message.render(holder); - _messageItems[mid] = message; - message.reset(opt); - updateHolderPos(); - return mid; - }); - - me.addListener('updatemessage',function(type, id, opt){ - opt = utils.isString(opt) ? { - 'content': opt - } : opt; - var message = _messageItems[id]; - message.render(holder); - message && message.reset(opt); - }); - - me.addListener('hidemessage',function(type, id){ - var message = _messageItems[id]; - message && message.hide(); - }); - - function updateHolderPos(){ - var toolbarbox = me.ui.getDom('toolbarbox'); - if (toolbarbox) { - holder.style.top = toolbarbox.offsetHeight + 3 + 'px'; - } - holder.style.zIndex = Math.max(me.options.zIndex, me.iframe.style.zIndex) + 1; - } - -}); - - -// adapter/autosave.js -UE.registerUI('autosave', function(editor) { - var timer = null,uid = null; - editor.on('afterautosave',function(){ - clearTimeout(timer); - - timer = setTimeout(function(){ - if(uid){ - editor.trigger('hidemessage',uid); - } - uid = editor.trigger('showmessage',{ - content : editor.getLang('autosave.success'), - timeout : 2000 - }); - - },2000) - }) - -}); - - - -})(); diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/ueditor_all_min.js b/SiteServer.Web/SiteFiles/assets/ueditor/ueditor_all_min.js deleted file mode 100644 index e9f2e03de..000000000 --- a/SiteServer.Web/SiteFiles/assets/ueditor/ueditor_all_min.js +++ /dev/null @@ -1,18 +0,0 @@ -/*! - * UEditor - * version: ueditor - * build: Wed Aug 10 2016 11:05:21 GMT+0800 (CST) - */ - -!function(){function getListener(a,b,c){var d;return b=b.toLowerCase(),(d=a.__allListeners||c&&(a.__allListeners={}))&&(d[b]||c&&(d[b]=[]))}function getDomNode(a,b,c,d,e,f){var g,h=d&&a[b];for(!h&&(h=a[c]);!h&&(g=(g||a).parentNode);){if("BODY"==g.tagName||f&&!f(g))return null;h=g[c]}return h&&e&&!e(h)?getDomNode(h,b,c,!1,e):h}UEDITOR_CONFIG=window.UEDITOR_CONFIG||{};var baidu=window.baidu||{};window.baidu=baidu,window.UE=baidu.editor=window.UE||{},UE.plugins={},UE.commands={},UE.instants={},UE.I18N={},UE._customizeUI={},UE.version="1.4.3";var dom=UE.dom={},browser=UE.browser=function(){var a=navigator.userAgent.toLowerCase(),b=window.opera,c={ie:/(msie\s|trident.*rv:)([\w.]+)/.test(a),opera:!!b&&b.version,webkit:a.indexOf(" applewebkit/")>-1,mac:a.indexOf("macintosh")>-1,quirks:"BackCompat"==document.compatMode};c.gecko="Gecko"==navigator.product&&!c.webkit&&!c.opera&&!c.ie;var d=0;if(c.ie){var e=a.match(/(?:msie\s([\w.]+))/),f=a.match(/(?:trident.*rv:([\w.]+))/);d=e&&f&&e[1]&&f[1]?Math.max(1*e[1],1*f[1]):e&&e[1]?1*e[1]:f&&f[1]?1*f[1]:0,c.ie11Compat=11==document.documentMode,c.ie9Compat=9==document.documentMode,c.ie8=!!document.documentMode,c.ie8Compat=8==document.documentMode,c.ie7Compat=7==d&&!document.documentMode||7==document.documentMode,c.ie6Compat=d<7||c.quirks,c.ie9above=d>8,c.ie9below=d<9,c.ie11above=d>10,c.ie11below=d<11}if(c.gecko){var g=a.match(/rv:([\d\.]+)/);g&&(g=g[1].split("."),d=1e4*g[0]+100*(g[1]||0)+1*(g[2]||0))}return/chrome\/(\d+\.\d)/i.test(a)&&(c.chrome=+RegExp.$1),/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(a)&&!/chrome/i.test(a)&&(c.safari=+(RegExp.$1||RegExp.$2)),c.opera&&(d=parseFloat(b.version())),c.webkit&&(d=parseFloat(a.match(/ applewebkit\/(\d+)/)[1])),c.version=d,c.isCompatible=!c.mobile&&(c.ie&&d>=6||c.gecko&&d>=10801||c.opera&&d>=9.5||c.air&&d>=1||c.webkit&&d>=522||!1),c}(),ie=browser.ie,webkit=browser.webkit,gecko=browser.gecko,opera=browser.opera,utils=UE.utils={each:function(a,b,c){if(null!=a)if(a.length===+a.length){for(var d=0,e=a.length;d=c&&a===b)return d=e,!1}),d},removeItem:function(a,b){for(var c=0,d=a.length;c'](?:(amp|lt|quot|gt|#39|nbsp|#\d+);)?/g,function(a,b){return b?a:{"<":"<","&":"&",'"':""",">":">","'":"'"}[a]}):""},unhtmlForUrl:function(a,b){return a?a.replace(b||/[<">']/g,function(a){return{"<":"<","&":"&",'"':""",">":">","'":"'"}[a]}):""},html:function(a){return a?a.replace(/&((g|l|quo)t|amp|#39|nbsp);/g,function(a){return{"<":"<","&":"&",""":'"',">":">","'":"'"," ":" "}[a]}):""},cssStyleToDomStyle:function(){var a=document.createElement("div").style,b={"float":void 0!=a.cssFloat?"cssFloat":void 0!=a.styleFloat?"styleFloat":"float"};return function(a){return b[a]||(b[a]=a.toLowerCase().replace(/-./g,function(a){return a.charAt(1).toUpperCase()}))}}(),loadFile:function(){function a(a,c){try{for(var d,e=0;d=b[e++];)if(d.doc===a&&d.url==(c.src||c.href))return d}catch(f){return null}}var b=[];return function(c,d,e){var f=a(c,d);if(f)return void(f.ready?e&&e():f.funs.push(e));if(b.push({doc:c,url:d.src||d.href,funs:[e]}),!c.body){var g=[];for(var h in d)"tag"!=h&&g.push(h+'="'+d[h]+'"');return void c.write("<"+d.tag+" "+g.join(" ")+" >")}if(!d.id||!c.getElementById(d.id)){var i=c.createElement(d.tag);delete d.tag;for(var h in d)i.setAttribute(h,d[h]);i.onload=i.onreadystatechange=function(){if(!this.readyState||/loaded|complete/.test(this.readyState)){if(f=a(c,d),f.funs.length>0){f.ready=1;for(var b;b=f.funs.pop();)b()}i.onload=i.onreadystatechange=null}},i.onerror=function(){throw Error("The load "+(d.href||d.src)+" fails,check the url settings of file ueditor.config.js ")},c.getElementsByTagName("head")[0].appendChild(i)}}}(),isEmptyObject:function(a){if(null==a)return!0;if(this.isArray(a)||this.isString(a))return 0===a.length;for(var b in a)if(a.hasOwnProperty(b))return!1;return!0},fixColor:function(a,b){if(/color/i.test(a)&&/rgba?/.test(b)){var c=b.split(",");if(c.length>3)return"";b="#";for(var d,e=0;d=c[e++];)d=parseInt(d.replace(/[^\d]/gi,""),10).toString(16),b+=1==d.length?"0"+d:d;b=b.toUpperCase()}return b},optCss:function(a){function b(a,b){if(!a)return"";var c=a.top,d=a.bottom,e=a.left,f=a.right,g="";if(c&&e&&d&&f)g+=";"+b+":"+(c==d&&d==e&&e==f?c:c==d&&e==f?c+" "+e:e==f?c+" "+e+" "+d:c+" "+f+" "+d+" "+e)+";";else for(var h in a)g+=";"+b+"-"+h+":"+a[h]+";";return g}var c,d;return a=a.replace(/(padding|margin|border)\-([^:]+):([^;]+);?/gi,function(a,b,e,f){if(1==f.split(" ").length)switch(b){case"padding":return!c&&(c={}),c[e]=f,"";case"margin":return!d&&(d={}),d[e]=f,"";case"border":return"initial"==f?"":a}return a}),a+=b(c,"padding")+b(d,"margin"),a.replace(/^[ \n\r\t;]*|[ \n\r\t]*$/,"").replace(/;([ \n\r\t]+)|\1;/g,";").replace(/(&((l|g)t|quot|#39))?;{2,}/g,function(a,b){return b?b+";;":";"})},clone:function(a,b){var c;b=b||{};for(var d in a)a.hasOwnProperty(d)&&(c=a[d],"object"==typeof c?(b[d]=utils.isArray(c)?[]:{},utils.clone(a[d],b[d])):b[d]=c);return b},transUnitToPx:function(a){if(!/(pt|cm)/.test(a))return a;var b;switch(a.replace(/([\d.]+)(\w+)/,function(c,d,e){a=d,b=e}),b){case"cm":a=25*parseFloat(a);break;case"pt":a=Math.round(96*parseFloat(a)/72)}return a+(a?"px":"")},domReady:function(){function a(a){a.isReady=!0;for(var c;c=b.pop();c());}var b=[];return function(c,d){d=d||window;var e=d.document;c&&b.push(c),"complete"===e.readyState?a(e):(e.isReady&&a(e),browser.ie&&11!=browser.version?(!function(){if(!e.isReady){try{e.documentElement.doScroll("left")}catch(b){return void setTimeout(arguments.callee,0)}a(e)}}(),d.attachEvent("onload",function(){a(e)})):(e.addEventListener("DOMContentLoaded",function(){e.removeEventListener("DOMContentLoaded",arguments.callee,!1),a(e)},!1),d.addEventListener("load",function(){a(e)},!1)))}}(),cssRule:browser.ie&&11!=browser.version?function(a,b,c){var d,e;if(void 0===b||b&&b.nodeType&&9==b.nodeType){if(c=b&&b.nodeType&&9==b.nodeType?b:c||document,d=c.indexList||(c.indexList={}),e=d[a],void 0!==e)return c.styleSheets[e].cssText}else{if(c=c||document,d=c.indexList||(c.indexList={}),e=d[a],""===b)return void 0!==e&&(c.styleSheets[e].cssText="",delete d[a],!0);void 0!==e?sheetStyle=c.styleSheets[e]:(sheetStyle=c.createStyleSheet("",e=c.styleSheets.length),d[a]=e),sheetStyle.cssText=b}}:function(a,b,c){var d;return void 0===b||b&&b.nodeType&&9==b.nodeType?(c=b&&b.nodeType&&9==b.nodeType?b:c||document,d=c.getElementById(a),d?d.innerHTML:void 0):(c=c||document,d=c.getElementById(a),""===b?!!d&&(d.parentNode.removeChild(d),!0):void(d?d.innerHTML=b:(d=c.createElement("style"),d.id=a,d.innerHTML=b,c.getElementsByTagName("head")[0].appendChild(d))))},sort:function(a,b){b=b||function(a,b){return a.localeCompare(b)};for(var c=0,d=a.length;c0){var g=a[c];a[c]=a[e],a[e]=g}return a},serializeParam:function(a){var b=[];for(var c in a)if("method"!=c&&"timeout"!=c&&"async"!=c)if("function"!=(typeof a[c]).toLowerCase()&&"object"!=(typeof a[c]).toLowerCase())b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));else if(utils.isArray(a[c]))for(var d=0;d1||b!==a.parentNode){a.style.cssText=b.style.cssText+";"+a.style.cssText,b=b.parentNode;continue}b.style.cssText+=";"+a.style.cssText,"A"==b.tagName&&(b.style.textDecoration="underline")}if("A"!=b.tagName){b===a.parentNode&&domUtils.remove(a,!0);break}}b=b.parentNode}},mergeSibling:function(a,b,c){function d(a,b,c){var d;if((d=c[a])&&!domUtils.isBookmarkNode(d)&&1==d.nodeType&&domUtils.isSameElement(c,d)){for(;d.firstChild;)"firstChild"==b?c.insertBefore(d.lastChild,c.firstChild):c.appendChild(d.firstChild);domUtils.remove(d)}}!b&&d("previousSibling","firstChild",a),!c&&d("nextSibling","lastChild",a)},unSelectable:ie&&browser.ie9below||browser.opera?function(a){a.onselectstart=function(){return!1},a.onclick=a.onkeyup=a.onkeydown=function(){return!1},a.unselectable="on",a.setAttribute("unselectable","on");for(var b,c=0;b=a.all[c++];)switch(b.tagName.toLowerCase()){case"iframe":case"textarea":case"input":case"select":break;default:b.unselectable="on",a.setAttribute("unselectable","on")}}:function(a){a.style.MozUserSelect=a.style.webkitUserSelect=a.style.msUserSelect=a.style.KhtmlUserSelect="none"},removeAttributes:function(a,b){b=utils.isArray(b)?b:utils.trim(b).replace(/[ ]{2,}/g," ").split(" ");for(var c,d=0;c=b[d++];){switch(c=attrFix[c]||c){case"className":a[c]="";break;case"style":a.style.cssText="";var e=a.getAttributeNode("style");!browser.ie&&e&&a.removeAttributeNode(e)}a.removeAttribute(c)}},createElement:function(a,b,c){return domUtils.setAttributes(a.createElement(b),c)},setAttributes:function(a,b){for(var c in b)if(b.hasOwnProperty(c)){var d=b[c];switch(c){case"class":a.className=d;break;case"style":a.style.cssText=a.style.cssText+";"+d;break;case"innerHTML":a[c]=d;break;case"value":a.value=d;break;default:a.setAttribute(attrFix[c]||c,d)}}return a},getComputedStyle:function(a,b){var c="width height top left";if(c.indexOf(b)>-1)return a["offset"+b.replace(/^\w/,function(a){return a.toUpperCase()})]+"px";if(3==a.nodeType&&(a=a.parentNode),browser.ie&&browser.version<9&&"font-size"==b&&!a.style.fontSize&&!dtd.$empty[a.tagName]&&!dtd.$nonChild[a.tagName]){var d=a.ownerDocument.createElement("span");d.style.cssText="padding:0;border:0;font-family:simsun;",d.innerHTML=".",a.appendChild(d);var e=d.offsetHeight;return a.removeChild(d),d=null,e+"px"}try{var f=domUtils.getStyle(a,b)||(window.getComputedStyle?domUtils.getWindow(a).getComputedStyle(a,"").getPropertyValue(b):(a.currentStyle||a.style)[utils.cssStyleToDomStyle(b)])}catch(g){return""}return utils.transUnitToPx(utils.fixColor(b,f))},removeClasses:function(a,b){b=utils.isArray(b)?b:utils.trim(b).replace(/[ ]{2,}/g," ").split(" ");for(var c,d=0,e=a.className;c=b[d++];)e=e.replace(new RegExp("\\b"+c+"\\b"),"");e=utils.trim(e).replace(/[ ]{2,}/g," "),e?a.className=e:domUtils.removeAttributes(a,["class"])},addClass:function(a,b){if(a){b=utils.trim(b).replace(/[ ]{2,}/g," ").split(" ");for(var c,d=0,e=a.className;c=b[d++];)new RegExp("\\b"+c+"\\b").test(e)||(e+=" "+c);a.className=utils.trim(e)}},hasClass:function(a,b){if(utils.isRegExp(b))return b.test(a.className);b=utils.trim(b).replace(/[ ]{2,}/g," ").split(" ");for(var c,d=0,e=a.className;c=b[d++];)if(!new RegExp("\\b"+c+"\\b","i").test(e))return!1;return d-1==b.length},preventDefault:function(a){a.preventDefault?a.preventDefault():a.returnValue=!1},removeStyle:function(a,b){browser.ie?("color"==b&&(b="(^|;)"+b),a.style.cssText=a.style.cssText.replace(new RegExp(b+"[^:]*:[^;]+;?","ig"),"")):a.style.removeProperty?a.style.removeProperty(b):a.style.removeAttribute(utils.cssStyleToDomStyle(b)),a.style.cssText||domUtils.removeAttributes(a,["style"])},getStyle:function(a,b){var c=a.style[utils.cssStyleToDomStyle(b)];return utils.fixColor(b,c)},setStyle:function(a,b,c){a.style[utils.cssStyleToDomStyle(b)]=c,utils.trim(a.style.cssText)||this.removeAttributes(a,"style")},setStyles:function(a,b){for(var c in b)b.hasOwnProperty(c)&&domUtils.setStyle(a,c,b[c])},removeDirtyAttr:function(a){for(var b,c=0,d=a.getElementsByTagName("*");b=d[c++];)b.removeAttribute("_moz_dirty");a.removeAttribute("_moz_dirty")},getChildCount:function(a,b){var c=0,d=a.firstChild;for(b=b||function(){return 1};d;)b(d)&&c++,d=d.nextSibling;return c},isEmptyNode:function(a){return!a.firstChild||0==domUtils.getChildCount(a,function(a){return!domUtils.isBr(a)&&!domUtils.isBookmarkNode(a)&&!domUtils.isWhitespace(a)})},clearSelectedArr:function(a){for(var b;b=a.pop();)domUtils.removeAttributes(b,["class"])},scrollToView:function(a,b,c){var d=function(){var a=b.document,c="CSS1Compat"==a.compatMode;return{width:(c?a.documentElement.clientWidth:a.body.clientWidth)||0,height:(c?a.documentElement.clientHeight:a.body.clientHeight)||0}},e=function(a){if("pageXOffset"in a)return{x:a.pageXOffset||0,y:a.pageYOffset||0};var b=a.document;return{x:b.documentElement.scrollLeft||b.body.scrollLeft||0,y:b.documentElement.scrollTop||b.body.scrollTop||0}},f=d().height,g=f*-1+c;g+=a.offsetHeight||0;var h=domUtils.getXY(a);g+=h.y;var i=e(b).y;(g>i||g0)return 0;for(var c in dtd.$isNotEmpty)if(a.getElementsByTagName(c).length)return 0;return 1},setViewportOffset:function(a,b){var c=0|parseInt(a.style.left),d=0|parseInt(a.style.top),e=a.getBoundingClientRect(),f=b.left-e.left,g=b.top-e.top;f&&(a.style.left=c+f+"px"),g&&(a.style.top=d+g+"px")},fillNode:function(a,b){var c=browser.ie?a.createTextNode(domUtils.fillChar):a.createElement("br");b.innerHTML="",b.appendChild(c)},moveChild:function(a,b,c){for(;a.firstChild;)c&&b.firstChild?b.insertBefore(a.lastChild,b.firstChild):b.appendChild(a.firstChild)},hasNoAttributes:function(a){return browser.ie?/^<\w+\s*?>/.test(a.outerHTML):0==a.attributes.length},isCustomeNode:function(a){return 1==a.nodeType&&a.getAttribute("_ue_custom_node_")},isTagNode:function(a,b){return 1==a.nodeType&&new RegExp("\\b"+a.tagName+"\\b","i").test(b)},filterNodeList:function(a,b,c){var d=[];if(!utils.isFunction(b)){var e=b;b=function(a){return utils.indexOf(utils.isArray(e)?e:e.split(" "),a.tagName.toLowerCase())!=-1}}return utils.each(a,function(a){b(a)&&d.push(a)}),0==d.length?null:1!=d.length&&c?d:d[0]},isInNodeEndBoundary:function(a,b){var c=a.startContainer;if(3==c.nodeType&&a.startOffset!=c.nodeValue.length)return 0;if(1==c.nodeType&&a.startOffset!=c.childNodes.length)return 0;for(;c!==b;){if(c.nextSibling)return 0;c=c.parentNode}return 1},isBoundaryNode:function(a,b){for(var c;!domUtils.isBody(a);)if(c=a,a=a.parentNode,c!==a[b])return!1;return!0},fillHtml:browser.ie11below?" ":"
    "},fillCharReg=new RegExp(domUtils.fillChar,"g");!function(){function a(a){a.collapsed=a.startContainer&&a.endContainer&&a.startContainer===a.endContainer&&a.startOffset==a.endOffset}function b(a){return!a.collapsed&&1==a.startContainer.nodeType&&a.startContainer===a.endContainer&&a.endOffset-a.startOffset==1}function c(b,c,d,e){return 1==c.nodeType&&(dtd.$empty[c.tagName]||dtd.$nonChild[c.tagName])&&(d=domUtils.getNodeIndex(c)+(b?0:1),c=c.parentNode),b?(e.startContainer=c,e.startOffset=d,e.endContainer||e.collapse(!0)):(e.endContainer=c,e.endOffset=d,e.startContainer||e.collapse(!1)),a(e),e}function d(a,b){var c,d,e=a.startContainer,f=a.endContainer,g=a.startOffset,h=a.endOffset,i=a.document,j=i.createDocumentFragment();if(1==e.nodeType&&(e=e.childNodes[g]||(c=e.appendChild(i.createTextNode("")))),1==f.nodeType&&(f=f.childNodes[h]||(d=f.appendChild(i.createTextNode("")))),e===f&&3==e.nodeType)return j.appendChild(i.createTextNode(e.substringData(g,h-g))),b&&(e.deleteData(g,h-g),a.collapse(!0)),j;for(var k,l,m=j,n=domUtils.findParents(e,!0),o=domUtils.findParents(f,!0),p=0;n[p]==o[p];)p++;for(var q,r=p;q=n[r];r++){for(k=q.nextSibling,q==e?c||(3==a.startContainer.nodeType?(m.appendChild(i.createTextNode(e.nodeValue.slice(g))),b&&e.deleteData(g,e.nodeValue.length-g)):m.appendChild(b?e:e.cloneNode(!0))):(l=q.cloneNode(!1),m.appendChild(l));k&&k!==f&&k!==o[r];)q=k.nextSibling,m.appendChild(b?k:k.cloneNode(!0)),k=q;m=l}m=j,n[p]||(m.appendChild(n[p-1].cloneNode(!1)),m=m.firstChild);for(var s,r=p;s=o[r];r++){if(k=s.previousSibling,s==f?d||3!=a.endContainer.nodeType||(m.appendChild(i.createTextNode(f.substringData(0,h))),b&&f.deleteData(0,h)):(l=s.cloneNode(!1),m.appendChild(l)),r!=p||!n[p])for(;k&&k!==e;)s=k.previousSibling,m.insertBefore(b?k:k.cloneNode(!0),m.firstChild),k=s;m=l}return b&&a.setStartBefore(o[p]?n[p]?o[p]:n[p-1]:o[p-1]).collapse(!0),c&&domUtils.remove(c),d&&domUtils.remove(d),j}function e(a,b){try{if(g&&domUtils.inDoc(g,a))if(g.nodeValue.replace(fillCharReg,"").length)g.nodeValue=g.nodeValue.replace(fillCharReg,"");else{var c=g.parentNode;for(domUtils.remove(g);c&&domUtils.isEmptyInlineElement(c)&&(browser.safari?!(domUtils.getPosition(c,b)&domUtils.POSITION_CONTAINS):!c.contains(b));)g=c.parentNode,domUtils.remove(c),c=g}}catch(d){} -}function f(a,b){var c;for(a=a[b];a&&domUtils.isFillChar(a);)c=a[b],domUtils.remove(a),a=c}var g,h=0,i=domUtils.fillChar,j=dom.Range=function(a){var b=this;b.startContainer=b.startOffset=b.endContainer=b.endOffset=null,b.document=a,b.collapsed=!0};j.prototype={cloneContents:function(){return this.collapsed?null:d(this,0)},deleteContents:function(){var a;return this.collapsed||d(this,1),browser.webkit&&(a=this.startContainer,3!=a.nodeType||a.nodeValue.length||(this.setStartBefore(a).collapse(!0),domUtils.remove(a))),this},extractContents:function(){return this.collapsed?null:d(this,2)},setStart:function(a,b){return c(!0,a,b,this)},setEnd:function(a,b){return c(!1,a,b,this)},setStartAfter:function(a){return this.setStart(a.parentNode,domUtils.getNodeIndex(a)+1)},setStartBefore:function(a){return this.setStart(a.parentNode,domUtils.getNodeIndex(a))},setEndAfter:function(a){return this.setEnd(a.parentNode,domUtils.getNodeIndex(a)+1)},setEndBefore:function(a){return this.setEnd(a.parentNode,domUtils.getNodeIndex(a))},setStartAtFirst:function(a){return this.setStart(a,0)},setStartAtLast:function(a){return this.setStart(a,3==a.nodeType?a.nodeValue.length:a.childNodes.length)},setEndAtFirst:function(a){return this.setEnd(a,0)},setEndAtLast:function(a){return this.setEnd(a,3==a.nodeType?a.nodeValue.length:a.childNodes.length)},selectNode:function(a){return this.setStartBefore(a).setEndAfter(a)},selectNodeContents:function(a){return this.setStart(a,0).setEndAtLast(a)},cloneRange:function(){var a=this;return new j(a.document).setStart(a.startContainer,a.startOffset).setEnd(a.endContainer,a.endOffset)},collapse:function(a){var b=this;return a?(b.endContainer=b.startContainer,b.endOffset=b.startOffset):(b.startContainer=b.endContainer,b.startOffset=b.endOffset),b.collapsed=!0,b},shrinkBoundary:function(a){function b(a){return 1==a.nodeType&&!domUtils.isBookmarkNode(a)&&!dtd.$empty[a.tagName]&&!dtd.$nonChild[a.tagName]}for(var c,d=this,e=d.collapsed;1==d.startContainer.nodeType&&(c=d.startContainer.childNodes[d.startOffset])&&b(c);)d.setStart(c,0);if(e)return d.collapse(!0);if(!a)for(;1==d.endContainer.nodeType&&d.endOffset>0&&(c=d.endContainer.childNodes[d.endOffset-1])&&b(c);)d.setEnd(c,c.childNodes.length);return d},getCommonAncestor:function(a,c){var d=this,e=d.startContainer,f=d.endContainer;return e===f?a&&b(this)&&(e=e.childNodes[d.startOffset],1==e.nodeType)?e:c&&3==e.nodeType?e.parentNode:e:domUtils.getCommonAncestor(e,f)},trimBoundary:function(a){this.txtToElmBoundary();var b=this.startContainer,c=this.startOffset,d=this.collapsed,e=this.endContainer;if(3==b.nodeType){if(0==c)this.setStartBefore(b);else if(c>=b.nodeValue.length)this.setStartAfter(b);else{var f=domUtils.split(b,c);b===e?this.setEnd(f,this.endOffset-c):b.parentNode===e&&(this.endOffset+=1),this.setStartBefore(f)}if(d)return this.collapse(!0)}return a||(c=this.endOffset,e=this.endContainer,3==e.nodeType&&(0==c?this.setEndBefore(e):(c=c.nodeValue.length&&a["set"+b.replace(/(\w)/,function(a){return a.toUpperCase()})+"After"](c):a["set"+b.replace(/(\w)/,function(a){return a.toUpperCase()})+"Before"](c))}return!a&&this.collapsed||(b(this,"start"),b(this,"end")),this},insertNode:function(a){var b=a,c=1;11==a.nodeType&&(b=a.firstChild,c=a.childNodes.length),this.trimBoundary(!0);var d=this.startContainer,e=this.startOffset,f=d.childNodes[e];return f?d.insertBefore(a,f):d.appendChild(a),b.parentNode===this.endContainer&&(this.endOffset=this.endOffset+c),this.setStartBefore(b)},setCursor:function(a,b){return this.collapse(!a).select(b)},createBookmark:function(a,b){var c,d=this.document.createElement("span");return d.style.cssText="display:none;line-height:0px;",d.appendChild(this.document.createTextNode("‍")),d.id="_baidu_bookmark_start_"+(b?"":h++),this.collapsed||(c=d.cloneNode(!0),c.id="_baidu_bookmark_end_"+(b?"":h++)),this.insertNode(d),c&&this.collapse().insertNode(c).setEndBefore(c),this.setStartAfter(d),{start:a?d.id:d,end:c?a?c.id:c:null,id:a}},moveToBookmark:function(a){var b=a.id?this.document.getElementById(a.start):a.start,c=a.end&&a.id?this.document.getElementById(a.end):a.end;return this.setStartBefore(b),domUtils.remove(b),c?(this.setEndBefore(c),domUtils.remove(c)):this.collapse(!0),this},enlarge:function(a,b){var c,d,e=domUtils.isBody,f=this.document.createTextNode("");if(a){for(d=this.startContainer,1==d.nodeType?d.childNodes[this.startOffset]?c=d=d.childNodes[this.startOffset]:(d.appendChild(f),c=d=f):c=d;;){if(domUtils.isBlockElm(d)){for(d=c;(c=d.previousSibling)&&!domUtils.isBlockElm(c);)d=c;this.setStartBefore(d);break}c=d,d=d.parentNode}for(d=this.endContainer,1==d.nodeType?((c=d.childNodes[this.endOffset])?d.insertBefore(f,c):d.appendChild(f),c=d=f):c=d;;){if(domUtils.isBlockElm(d)){for(d=c;(c=d.nextSibling)&&!domUtils.isBlockElm(c);)d=c;this.setEndAfter(d);break}c=d,d=d.parentNode}f.parentNode===this.endContainer&&this.endOffset--,domUtils.remove(f)}if(!this.collapsed){for(;!(0!=this.startOffset||b&&b(this.startContainer)||e(this.startContainer));)this.setStartBefore(this.startContainer);for(;!(this.endOffset!=(1==this.endContainer.nodeType?this.endContainer.childNodes.length:this.endContainer.nodeValue.length)||b&&b(this.endContainer)||e(this.endContainer));)this.setEndAfter(this.endContainer)}return this},enlargeToBlockElm:function(a){for(;!domUtils.isBlockElm(this.startContainer);)this.setStartBefore(this.startContainer);if(!a)for(;!domUtils.isBlockElm(this.endContainer);)this.setEndAfter(this.endContainer);return this},adjustmentBoundary:function(){if(!this.collapsed){for(;!domUtils.isBody(this.startContainer)&&this.startOffset==this.startContainer[3==this.startContainer.nodeType?"nodeValue":"childNodes"].length&&this.startContainer[3==this.startContainer.nodeType?"nodeValue":"childNodes"].length;)this.setStartAfter(this.startContainer);for(;!domUtils.isBody(this.endContainer)&&!this.endOffset&&this.endContainer[3==this.endContainer.nodeType?"nodeValue":"childNodes"].length;)this.setEndBefore(this.endContainer)}return this},applyInlineStyle:function(a,b,c){if(this.collapsed)return this;this.trimBoundary().enlarge(!1,function(a){return 1==a.nodeType&&domUtils.isBlockElm(a)}).adjustmentBoundary();for(var d,e,f=this.createBookmark(),g=f.end,h=function(a){return 1==a.nodeType?"br"!=a.tagName.toLowerCase():!domUtils.isWhitespace(a)},i=domUtils.getNextDomNode(f.start,!1,h),j=this.cloneRange();i&&domUtils.getPosition(i,g)&domUtils.POSITION_PRECEDING;)if(3==i.nodeType||dtd[a][i.tagName]){for(j.setStartBefore(i),d=i;d&&(3==d.nodeType||dtd[a][d.tagName])&&d!==g;)e=d,d=domUtils.getNextDomNode(d,1==d.nodeType,null,function(b){return dtd[a][b.tagName]});var k,l=j.setEndAfter(e).extractContents();if(c&&c.length>0){var m,n;n=m=c[0].cloneNode(!1);for(var o,p=1;o=c[p++];)m.appendChild(o.cloneNode(!1)),m=m.firstChild;k=m}else k=j.document.createElement(a);b&&domUtils.setAttributes(k,b),k.appendChild(l),j.insertNode(c?n:k);var q;if("span"==a&&b.style&&/text\-decoration/.test(b.style)&&(q=domUtils.findParentByTagName(k,"a",!0))?(domUtils.setAttributes(q,b),domUtils.remove(k,!0),k=q):(domUtils.mergeSibling(k),domUtils.clearEmptySibling(k)),domUtils.mergeChild(k,b),i=domUtils.getNextDomNode(k,!1,h),domUtils.mergeToParent(k),d===g)break}else i=domUtils.getNextDomNode(i,!0,h);return this.moveToBookmark(f)},removeInlineStyle:function(a){if(this.collapsed)return this;a=utils.isArray(a)?a:[a],this.shrinkBoundary().adjustmentBoundary();for(var b=this.startContainer,c=this.endContainer;;){if(1==b.nodeType){if(utils.indexOf(a,b.tagName.toLowerCase())>-1)break;if("body"==b.tagName.toLowerCase()){b=null;break}}b=b.parentNode}for(;;){if(1==c.nodeType){if(utils.indexOf(a,c.tagName.toLowerCase())>-1)break;if("body"==c.tagName.toLowerCase()){c=null;break}}c=c.parentNode}var d,e,f=this.createBookmark();b&&(e=this.cloneRange().setEndBefore(f.start).setStartBefore(b),d=e.extractContents(),e.insertNode(d),domUtils.clearEmptySibling(b,!0),b.parentNode.insertBefore(f.start,b)),c&&(e=this.cloneRange().setStartAfter(f.end).setEndAfter(c),d=e.extractContents(),e.insertNode(d),domUtils.clearEmptySibling(c,!1,!0),c.parentNode.insertBefore(f.end,c.nextSibling));for(var g,h=domUtils.getNextDomNode(f.start,!1,function(a){return 1==a.nodeType});h&&h!==f.end;)g=domUtils.getNextDomNode(h,!0,function(a){return 1==a.nodeType}),utils.indexOf(a,h.tagName.toLowerCase())>-1&&domUtils.remove(h,!0),h=g;return this.moveToBookmark(f)},getClosedNode:function(){var a;if(!this.collapsed){var c=this.cloneRange().adjustmentBoundary().shrinkBoundary();if(b(c)){var d=c.startContainer.childNodes[c.startOffset];d&&1==d.nodeType&&(dtd.$empty[d.tagName]||dtd.$nonChild[d.tagName])&&(a=d)}}return a},select:browser.ie?function(a,b){var c;this.collapsed||this.shrinkBoundary();var d=this.getClosedNode();if(d&&!b){try{c=this.document.body.createControlRange(),c.addElement(d),c.select()}catch(h){}return this}var j,k=this.createBookmark(),l=k.start;if(c=this.document.body.createTextRange(),c.moveToElementText(l),c.moveStart("character",1),this.collapsed){if(!a&&3!=this.startContainer.nodeType){var m=this.document.createTextNode(i),n=this.document.createElement("span");n.appendChild(this.document.createTextNode(i)),l.parentNode.insertBefore(n,l),l.parentNode.insertBefore(m,l),e(this.document,m),g=m,f(n,"previousSibling"),f(l,"nextSibling"),c.moveStart("character",-1),c.collapse(!0)}}else{var o=this.document.body.createTextRange();j=k.end,o.moveToElementText(j),c.setEndPoint("EndToEnd",o)}this.moveToBookmark(k),n&&domUtils.remove(n);try{c.select()}catch(h){}return this}:function(a){function b(a){function b(b,c,d){3==b.nodeType&&b.nodeValue.length0)j=k-1;else{if(!(l<0))return{container:d,offset:c(e)};i=k+1}}if(k==-1){if(h.moveToElementText(d),h.setEndPoint("StartToStart",a),f=h.text.replace(/(\r\n|\r)/g,"\n").length,g=d.childNodes,!f)return e=g[g.length-1],{container:e,offset:e.nodeValue.length};for(var m=g.length;f>0;)f-=g[--m].nodeValue.length;return{container:g[m],offset:-f}}if(h.collapse(l>0),h.setEndPoint(l>0?"StartToStart":"EndToStart",a),f=h.text.replace(/(\r\n|\r)/g,"\n").length,!f)return dtd.$empty[e.tagName]||dtd.$nonChild[e.tagName]?{container:d,offset:c(e)+(l>0?0:1)}:{container:e,offset:l>0?0:e.childNodes.length};for(;f>0;)try{var n=e;e=e[l>0?"previousSibling":"nextSibling"],f-=e.nodeValue.length}catch(o){return{container:d,offset:c(n)}}return{container:e,offset:l>0?-f:e.nodeValue.length+f}}function b(b,c){if(b.item)c.selectNode(b.item(0));else{var d=a(b,!0);c.setStart(d.container,d.offset),0!=b.compareEndPoints("StartToEnd",b)&&(d=a(b,!1),c.setEnd(d.container,d.offset))}return c}function c(a){var b;try{b=a.getNative().createRange()}catch(c){return null}var d=b.item?b.item(0):b.parentElement();return(d.ownerDocument||d)===a.document?b:null}var d=dom.Selection=function(a){var b,d=this;d.document=a,browser.ie9below&&(b=domUtils.getWindow(a).frameElement,domUtils.on(b,"beforedeactivate",function(){d._bakIERange=d.getIERange()}),domUtils.on(b,"activate",function(){try{!c(d)&&d._bakIERange&&d._bakIERange.select()}catch(a){}d._bakIERange=null})),b=a=null};d.prototype={rangeInBody:function(a,b){var c=browser.ie9below||b?a.item?a.item():a.parentElement():a.startContainer;return c===this.document.body||domUtils.inDoc(c,this.document)},getNative:function(){var a=this.document;try{return a?browser.ie9below?a.selection:domUtils.getWindow(a).getSelection():null}catch(b){return null}},getIERange:function(){var a=c(this);return!a&&this._bakIERange?this._bakIERange:a},cache:function(){this.clear(),this._cachedRange=this.getRange(),this._cachedStartElement=this.getStart(),this._cachedStartElementPath=this.getStartElementPath()},getStartElementPath:function(){if(this._cachedStartElementPath)return this._cachedStartElementPath;var a=this.getStart();return a?domUtils.findParents(a,!0,null,!0):[]},clear:function(){this._cachedStartElementPath=this._cachedRange=this._cachedStartElement=null},isFocus:function(){try{if(browser.ie9below){var a=c(this);return!(!a||!this.rangeInBody(a))}return!!this.getNative().rangeCount}catch(b){return!1}},getRange:function(){function a(a){for(var b=c.document.body.firstChild,d=a.collapsed;b&&b.firstChild;)a.setStart(b,0),b=b.firstChild;a.startContainer||a.setStart(c.document.body,0),d&&a.collapse(!0)}var c=this;if(null!=c._cachedRange)return this._cachedRange;var d=new baidu.editor.dom.Range(c.document);if(browser.ie9below){var e=c.getIERange();if(e)try{b(e,d)}catch(f){a(d)}else a(d)}else{var g=c.getNative();if(g&&g.rangeCount){var h=g.getRangeAt(0),i=g.getRangeAt(g.rangeCount-1);d.setStart(h.startContainer,h.startOffset).setEnd(i.endContainer,i.endOffset),d.collapsed&&domUtils.isBody(d.startContainer)&&!d.startOffset&&a(d)}else{if(this._bakRange&&domUtils.inDoc(this._bakRange.startContainer,this.document))return this._bakRange;a(d)}}return this._bakRange=d},getStart:function(){if(this._cachedStartElement)return this._cachedStartElement;var a,b,c,d,e=browser.ie9below?this.getIERange():this.getRange();if(browser.ie9below){if(!e)return this.document.body.firstChild;if(e.item)return e.item(0);for(a=e.duplicate(),a.text.length>0&&a.moveStart("character",1),a.collapse(1),b=a.parentElement(),d=c=e.parentElement();c=c.parentNode;)if(c==b){b=d;break}}else if(e.shrinkBoundary(),b=e.startContainer,1==b.nodeType&&b.hasChildNodes()&&(b=b.childNodes[Math.min(b.childNodes.length-1,e.startOffset)]),3==b.nodeType)return b.parentNode;return b},getText:function(){var a,b;return this.isFocus()&&(a=this.getNative())?(b=browser.ie9below?a.createRange():a.getRangeAt(0),browser.ie9below?b.text:b.toString()):""},clearRange:function(){this.getNative()[browser.ie9below?"empty":"removeAllRanges"]()}}}(),function(){function a(a,b){var c;if(b.textarea)if(utils.isString(b.textarea)){for(var d,e=0,f=domUtils.getElementsByTagName(a,"textarea");d=f[e++];)if(d.id=="ueditor_textarea_"+b.options.textarea){c=d;break}}else c=b.textarea;c||(a.appendChild(c=domUtils.createElement(document,"textarea",{name:b.options.textarea,id:"ueditor_textarea_"+b.options.textarea,style:"display:none"})),b.textarea=c),!c.getAttribute("name")&&c.setAttribute("name",b.options.textarea),c.value=b.hasContents()?b.options.allHtmlEnabled?b.getAllHtml():b.getContent(null,null,!0):""}function b(a){for(var b in a)return b}function c(a){a.langIsReady=!0,a.fireEvent("langReady")}var d,e=0,f=UE.Editor=function(a){var d=this;d.uid=e++,EventBase.call(d),d.commands={},d.options=utils.extend(utils.clone(a||{}),UEDITOR_CONFIG,!0),d.shortcutkeys={},d.inputRules=[],d.outputRules=[],d.setOpt(f.defaultOptions(d)),d.loadServerConfig(),utils.isEmptyObject(UE.I18N)?utils.loadFile(document,{src:d.options.langPath+d.options.lang+"/"+d.options.lang+".js",tag:"script",type:"text/javascript",defer:"defer"},function(){UE.plugin.load(d),c(d)}):(d.options.lang=b(UE.I18N),UE.plugin.load(d),c(d)),UE.instants["ueditorInstant"+d.uid]=d};f.prototype={registerCommand:function(a,b){this.commands[a]=b},ready:function(a){var b=this;a&&(b.isReady?a.apply(b):b.addListener("ready",a))},setOpt:function(a,b){var c={};utils.isString(a)?c[a]=b:c=a,utils.extend(this.options,c,!0)},getOpt:function(a){return this.options[a]},destroy:function(){var a=this;a.fireEvent("destroy");var b=a.container.parentNode,c=a.textarea;c?c.style.display="":(c=document.createElement("textarea"),b.parentNode.insertBefore(c,b)),c.style.width=a.iframe.offsetWidth+"px",c.style.height=a.iframe.offsetHeight+"px",c.value=a.getContent(),c.id=a.key,b.innerHTML="",domUtils.remove(b);var d=a.key;for(var e in a)a.hasOwnProperty(e)&&delete this[e];UE.delEditor(d)},render:function(a){var b=this,c=b.options,d=function(b){return parseInt(domUtils.getComputedStyle(a,b))};if(utils.isString(a)&&(a=document.getElementById(a)),a){c.initialFrameWidth?c.minFrameWidth=c.initialFrameWidth:c.minFrameWidth=c.initialFrameWidth=a.offsetWidth,c.initialFrameHeight?c.minFrameHeight=c.initialFrameHeight:c.initialFrameHeight=c.minFrameHeight=a.offsetHeight,a.style.width=/%$/.test(c.initialFrameWidth)?"100%":c.initialFrameWidth-d("padding-left")-d("padding-right")+"px",a.style.height=/%$/.test(c.initialFrameHeight)?"100%":c.initialFrameHeight-d("padding-top")-d("padding-bottom")+"px",a.style.zIndex=c.zIndex;var e=(ie&&browser.version<9?"":"")+""+(c.iframeCssUrl?"":"")+(c.initialStyle?"":"")+"";a.appendChild(domUtils.createElement(document,"iframe",{id:"ueditor_"+b.uid,width:"100%",height:"100%",frameborder:"0",src:"javascript:void(function(){document.open();"+(c.customDomain&&document.domain!=location.hostname?'document.domain="'+document.domain+'";':"")+'document.write("'+e+'");document.close();}())'})),a.style.overflow="hidden",setTimeout(function(){/%$/.test(c.initialFrameWidth)&&(c.minFrameWidth=c.initialFrameWidth=a.offsetWidth),/%$/.test(c.initialFrameHeight)&&(c.minFrameHeight=c.initialFrameHeight=a.offsetHeight,a.style.height=c.initialFrameHeight+"px")})}},_setup:function(b){var c=this,d=c.options;ie?(b.body.disabled=!0,b.body.contentEditable=!0,b.body.disabled=!1):b.body.contentEditable=!0,b.body.spellcheck=!1,c.document=b,c.window=b.defaultView||b.parentWindow,c.iframe=c.window.frameElement,c.body=b.body,c.selection=new dom.Selection(b);var e;browser.gecko&&(e=this.selection.getNative())&&e.removeAllRanges(),this._initEvents();for(var f=this.iframe.parentNode;!domUtils.isBody(f);f=f.parentNode)if("FORM"==f.tagName){c.form=f,c.options.autoSyncData?domUtils.on(c.window,"blur",function(){a(f,c)}):domUtils.on(f,"submit",function(){a(this,c)});break}if(d.initialContent)if(d.autoClearinitialContent){var g=c.execCommand;c.execCommand=function(){return c.fireEvent("firstBeforeExecCommand"),g.apply(c,arguments)},this._setDefaultContent(d.initialContent)}else this.setContent(d.initialContent,!1,!0);domUtils.isEmptyNode(c.body)&&(c.body.innerHTML="

    "+(browser.ie?"":"
    ")+"

    "),d.focus&&setTimeout(function(){c.focus(c.options.focusInEnd),!c.options.autoClearinitialContent&&c._selectionChange()},0),c.container||(c.container=this.iframe.parentNode),d.fullscreen&&c.ui&&c.ui.setFullScreen(!0);try{c.document.execCommand("2D-position",!1,!1)}catch(h){}try{c.document.execCommand("enableInlineTableEditing",!1,!1)}catch(h){}try{c.document.execCommand("enableObjectResizing",!1,!1)}catch(h){}c._bindshortcutKeys(),c.isReady=1,c.fireEvent("ready"),d.onready&&d.onready.call(c),browser.ie9below||domUtils.on(c.window,["blur","focus"],function(a){if("blur"==a.type){c._bakRange=c.selection.getRange();try{c._bakNativeRange=c.selection.getNative().getRangeAt(0),c.selection.getNative().removeAllRanges()}catch(a){c._bakNativeRange=null}}else try{c._bakRange&&c._bakRange.select()}catch(a){}}),browser.gecko&&browser.version<=10902&&(c.body.contentEditable=!1,setTimeout(function(){c.body.contentEditable=!0},100),setInterval(function(){c.body.style.height=c.iframe.offsetHeight-20+"px"},100)),!d.isShow&&c.setHide(),d.readonly&&c.setDisabled()},sync:function(b){var c=this,d=b?document.getElementById(b):domUtils.findParent(c.iframe.parentNode,function(a){return"FORM"==a.tagName},!0);d&&a(d,c)},setHeight:function(a,b){a!==parseInt(this.iframe.parentNode.style.height)&&(this.iframe.parentNode.style.height=a+"px"),!b&&(this.options.minFrameHeight=this.options.initialFrameHeight=a),this.body.style.height=a+"px",!b&&this.trigger("setHeight")},addshortcutkey:function(a,b){var c={};b?c[a]=b:c=a,utils.extend(this.shortcutkeys,c)},_bindshortcutKeys:function(){var a=this,b=this.shortcutkeys;a.addListener("keydown",function(c,d){var e=d.keyCode||d.which;for(var f in b)for(var g,h=b[f].split(","),i=0;g=h[i++];){g=g.split(":");var j=g[0],k=g[1];(/^(ctrl)(\+shift)?\+(\d+)$/.test(j.toLowerCase())||/^(\d+)$/.test(j))&&(("ctrl"==RegExp.$1?d.ctrlKey||d.metaKey:0)&&(""!=RegExp.$2?d[RegExp.$2.slice(1)+"Key"]:1)&&e==RegExp.$3||e==RegExp.$1)&&(a.queryCommandState(f,k)!=-1&&a.execCommand(f,k),domUtils.preventDefault(d))}})},getContent:function(a,b,c,d,e){var f=this;if(a&&utils.isFunction(a)&&(b=a,a=""),b?!b():!this.hasContents())return"";f.fireEvent("beforegetcontent");var g=UE.htmlparser(f.body.innerHTML,d);return f.filterOutputRule(g),f.fireEvent("aftergetcontent",a,g),g.toHtml(e)},getAllHtml:function(){var a=this,b=[];if(a.fireEvent("getAllHtml",b),browser.ie&&browser.version>8){var c="";utils.each(a.document.styleSheets,function(a){c+=a.href?'':""}),utils.each(a.document.getElementsByTagName("script"),function(a){c+=a.outerHTML})}return""+(a.options.charset?'':"")+(c||a.document.getElementsByTagName("head")[0].innerHTML)+b.join("\n")+""+a.getContent(null,null,!0)+""},getPlainTxt:function(){var a=new RegExp(domUtils.fillChar,"g"),b=this.body.innerHTML.replace(/[\n\r]/g,"");return b=b.replace(/<(p|div)[^>]*>(| )<\/\1>/gi,"\n").replace(//gi,"\n").replace(/<[^>\/]+>/g,"").replace(/(\n)?<\/([^>]+)>/g,function(a,b,c){return dtd.$block[c]?"\n":b?b:""}),b.replace(a,"").replace(/\u00a0/g," ").replace(/ /g," ")},getContentTxt:function(){var a=new RegExp(domUtils.fillChar,"g");return this.body[browser.ie?"innerText":"textContent"].replace(a,"").replace(/\u00a0/g," ")},setContent:function(b,c,d){function e(a){return"DIV"==a.tagName&&a.getAttribute("cdata_tag")}var f=this;f.fireEvent("beforesetcontent",b);var g=UE.htmlparser(b);if(f.filterInputRule(g),b=g.toHtml(),f.body.innerHTML=(c?f.body.innerHTML:"")+b,"p"==f.options.enterTag){var h,i=this.body.firstChild;if(!i||1==i.nodeType&&(dtd.$cdata[i.tagName]||e(i)||domUtils.isCustomeNode(i))&&i===this.body.lastChild)this.body.innerHTML="

    "+(browser.ie?" ":"
    ")+"

    "+this.body.innerHTML;else for(var j=f.document.createElement("p");i;){for(;i&&(3==i.nodeType||1==i.nodeType&&dtd.p[i.tagName]&&!dtd.$cdata[i.tagName]);)h=i.nextSibling,j.appendChild(i),i=h;if(j.firstChild){if(!i){f.body.appendChild(j);break}i.parentNode.insertBefore(j,i),j=f.document.createElement("p")}i=i.nextSibling}}f.fireEvent("aftersetcontent"),f.fireEvent("contentchange"),!d&&f._selectionChange(),f._bakRange=f._bakIERange=f._bakNativeRange=null;var k;browser.gecko&&(k=this.selection.getNative())&&k.removeAllRanges(),f.options.autoSyncData&&f.form&&a(f.form,f)},focus:function(a){try{var b=this,c=b.selection.getRange();if(a){var d=b.body.lastChild;d&&1==d.nodeType&&!dtd.$empty[d.tagName]&&(domUtils.isEmptyBlock(d)?c.setStartAtFirst(d):c.setStartAtLast(d),c.collapse(!0)),c.setCursor(!0)}else{if(!c.collapsed&&domUtils.isBody(c.startContainer)&&0==c.startOffset){var d=b.body.firstChild;d&&1==d.nodeType&&!dtd.$empty[d.tagName]&&c.setStartAtFirst(d).collapse(!0)}c.select(!0)}this.fireEvent("focus selectionchange")}catch(e){}},isFocus:function(){return this.selection.isFocus()},blur:function(){var a=this.selection.getNative();if(a.empty&&browser.ie){var b=document.body.createTextRange();b.moveToElementText(document.body),b.collapse(!0),b.select(),a.empty()}else a.removeAllRanges()},_initEvents:function(){var a=this,b=a.document,c=a.window;a._proxyDomEvent=utils.bind(a._proxyDomEvent,a),domUtils.on(b,["click","contextmenu","mousedown","keydown","keyup","keypress","mouseup","mouseover","mouseout","selectstart"],a._proxyDomEvent),domUtils.on(c,["focus","blur"],a._proxyDomEvent),domUtils.on(a.body,"drop",function(b){browser.gecko&&b.stopPropagation&&b.stopPropagation(),a.fireEvent("contentchange")}),domUtils.on(b,["mouseup","keydown"],function(b){"keydown"==b.type&&(b.ctrlKey||b.metaKey||b.shiftKey||b.altKey)||2!=b.button&&a._selectionChange(250,b)})},_proxyDomEvent:function(a){return this.fireEvent("before"+a.type.replace(/^on/,"").toLowerCase())!==!1&&(this.fireEvent(a.type.replace(/^on/,""),a)!==!1&&this.fireEvent("after"+a.type.replace(/^on/,"").toLowerCase()))},_selectionChange:function(a,b){var c,e,f=this,g=!1;if(browser.ie&&browser.version<9&&b&&"mouseup"==b.type){var h=this.selection.getRange();h.collapsed||(g=!0,c=b.clientX,e=b.clientY)}clearTimeout(d),d=setTimeout(function(){if(f.selection&&f.selection.getNative()){var a;if(g&&"None"==f.selection.getNative().type){a=f.document.body.createTextRange();try{a.moveToPoint(c,e)}catch(d){a=null}}var h;a&&(h=f.selection.getIERange,f.selection.getIERange=function(){return a}),f.selection.cache(),h&&(f.selection.getIERange=h),f.selection._cachedRange&&f.selection._cachedStartElement&&(f.fireEvent("beforeselectionchange"),f.fireEvent("selectionchange",!!b),f.fireEvent("afterselectionchange"),f.selection.clear())}},a||50)},_callCmdFn:function(a,b){var c,d,e=b[0].toLowerCase();return c=this.commands[e]||UE.commands[e],d=c&&c[a],c&&d||"queryCommandState"!=a?d?d.apply(this,b):void 0:0},execCommand:function(a){a=a.toLowerCase();var b,c=this,d=c.commands[a]||UE.commands[a];return d&&d.execCommand?(d.notNeedUndo||c.__hasEnterExecCommand?(b=this._callCmdFn("execCommand",arguments),!c.__hasEnterExecCommand&&!d.ignoreContentChange&&!c._ignoreContentChange&&c.fireEvent("contentchange")):(c.__hasEnterExecCommand=!0,c.queryCommandState.apply(c,arguments)!=-1&&(c.fireEvent("saveScene"),c.fireEvent.apply(c,["beforeexeccommand",a].concat(arguments)),b=this._callCmdFn("execCommand",arguments),c.fireEvent.apply(c,["afterexeccommand",a].concat(arguments)),c.fireEvent("saveScene")),c.__hasEnterExecCommand=!1),!c.__hasEnterExecCommand&&!d.ignoreContentChange&&!c._ignoreContentChange&&c._selectionChange(),b):null},queryCommandState:function(a){return this._callCmdFn("queryCommandState",arguments)},queryCommandValue:function(a){return this._callCmdFn("queryCommandValue",arguments)},hasContents:function(a){if(a)for(var b,c=0;b=a[c++];)if(this.document.getElementsByTagName(b).length>0)return!0;if(!domUtils.isEmptyBlock(this.body))return!0;for(a=["div"],c=0;b=a[c++];)for(var d,e=domUtils.getElementsByTagName(this.document,b),f=0;d=e[f++];)if(domUtils.isCustomeNode(d))return!0;return!1},reset:function(){this.fireEvent("reset")},setEnabled:function(){var a,b=this;if("false"==b.body.contentEditable){b.body.contentEditable=!0,a=b.selection.getRange();try{a.moveToBookmark(b.lastBk),delete b.lastBk}catch(c){a.setStartAtFirst(b.body).collapse(!0)}a.select(!0),b.bkqueryCommandState&&(b.queryCommandState=b.bkqueryCommandState,delete b.bkqueryCommandState),b.bkqueryCommandValue&&(b.queryCommandValue=b.bkqueryCommandValue,delete b.bkqueryCommandValue),b.fireEvent("selectionchange")}},enable:function(){return this.setEnabled()},setDisabled:function(a){var b=this;a=a?utils.isArray(a)?a:[a]:[],"true"==b.body.contentEditable&&(b.lastBk||(b.lastBk=b.selection.getRange().createBookmark(!0)),b.body.contentEditable=!1,b.bkqueryCommandState=b.queryCommandState,b.bkqueryCommandValue=b.queryCommandValue,b.queryCommandState=function(c){return utils.indexOf(a,c)!=-1?b.bkqueryCommandState.apply(b,arguments):-1},b.queryCommandValue=function(c){return utils.indexOf(a,c)!=-1?b.bkqueryCommandValue.apply(b,arguments):null},b.fireEvent("selectionchange"))},disable:function(a){return this.setDisabled(a)},_setDefaultContent:function(){function a(){var b=this;b.document.getElementById("initContent")&&(b.body.innerHTML="

    "+(ie?"":"
    ")+"

    ",b.removeListener("firstBeforeExecCommand focus",a),setTimeout(function(){b.focus(),b._selectionChange()},0))}return function(b){var c=this;c.body.innerHTML='

    '+b+"

    ",c.addListener("firstBeforeExecCommand focus",a)}}(),setShow:function(){var a=this,b=a.selection.getRange();if("none"==a.container.style.display){try{b.moveToBookmark(a.lastBk),delete a.lastBk}catch(c){b.setStartAtFirst(a.body).collapse(!0)}setTimeout(function(){b.select(!0)},100),a.container.style.display=""}},show:function(){return this.setShow()},setHide:function(){ -var a=this;a.lastBk||(a.lastBk=a.selection.getRange().createBookmark(!0)),a.container.style.display="none"},hide:function(){return this.setHide()},getLang:function(a){var b=UE.I18N[this.options.lang];if(!b)throw Error("not import language file");a=(a||"").split(".");for(var c,d=0;(c=a[d++])&&(b=b[c],b););return b},getContentLength:function(a,b){var c=this.getContent(!1,!1,!0).length;if(a){b=(b||[]).concat(["hr","img","iframe"]),c=this.getContentTxt().replace(/[\t\r\n]+/g,"").length;for(var d,e=0;d=b[e++];)c+=this.document.getElementsByTagName(d).length}return c},addInputRule:function(a){this.inputRules.push(a)},filterInputRule:function(a){for(var b,c=0;b=this.inputRules[c++];)b.call(this,a)},addOutputRule:function(a){this.outputRules.push(a)},filterOutputRule:function(a){for(var b,c=0;b=this.outputRules[c++];)b.call(this,a)},getActionUrl:function(a){var b=this.getOpt(a)||a,c=this.getOpt("imageUrl"),d=this.getOpt("serverUrl");return!d&&c&&(d=c.replace(/^(.*[\/]).+([\.].+)$/,"$1controller$2")),d?(d=d+(d.indexOf("?")==-1?"?":"&")+"action="+(b||""),utils.formatUrl(d)):""}},utils.inherits(f,EventBase)}(),UE.Editor.defaultOptions=function(a){var b=a.options.UEDITOR_HOME_URL;return{isShow:!0,initialContent:"",initialStyle:"",autoClearinitialContent:!1,iframeCssUrl:b+"themes/iframe.css",textarea:"editorValue",focus:!1,focusInEnd:!0,autoClearEmptyNode:!0,fullscreen:!1,readonly:!1,zIndex:999,imagePopup:!0,enterTag:"p",customDomain:!1,lang:"zh-cn",langPath:b+"lang/",theme:"default",themePath:b+"themes/",allHtmlEnabled:!1,scaleEnabled:!1,tableNativeEditInFF:!1,autoSyncData:!0,fileNameFormat:"{time}{rand:6}"}},function(){UE.Editor.prototype.loadServerConfig=function(){function showErrorMsg(a){console&&console.error(a)}var me=this;setTimeout(function(){try{me.options.imageUrl&&me.setOpt("serverUrl",me.options.imageUrl.replace(/^(.*[\/]).+([\.].+)$/,"$1controller$2"));var configUrl=me.getActionUrl("config"),isJsonp=utils.isCrossDomainUrl(configUrl);me._serverConfigLoaded=!1,configUrl&&UE.ajax.request(configUrl,{method:"GET",dataType:isJsonp?"jsonp":"",onsuccess:function(r){try{var config=isJsonp?r:eval("("+r.responseText+")");utils.extend(me.options,config),me.fireEvent("serverConfigLoaded"),me._serverConfigLoaded=!0}catch(e){showErrorMsg(me.getLang("loadconfigFormatError"))}},onerror:function(){showErrorMsg(me.getLang("loadconfigHttpError"))}})}catch(e){showErrorMsg(me.getLang("loadconfigError"))}})},UE.Editor.prototype.isServerConfigLoaded=function(){var a=this;return a._serverConfigLoaded||!1},UE.Editor.prototype.afterConfigReady=function(a){if(a&&utils.isFunction(a)){var b=this,c=function(){a.apply(b,arguments),b.removeListener("serverConfigLoaded",c)};b.isServerConfigLoaded()?a.call(b,"serverConfigLoaded"):b.addListener("serverConfigLoaded",c)}}}(),UE.ajax=function(){function a(a){var b=[];for(var c in a)if("method"!=c&&"timeout"!=c&&"async"!=c&&"dataType"!=c&&"callback"!=c&&void 0!=a[c]&&null!=a[c])if("function"!=(typeof a[c]).toLowerCase()&&"object"!=(typeof a[c]).toLowerCase())b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));else if(utils.isArray(a[c]))for(var d=0;d/gi,"").replace(/]*>[\s\S]*?.<\/v:shape>/gi,function(a){if(browser.opera)return"";try{if(/Bitmap/i.test(a))return"";var c=a.match(/width:([ \d.]*p[tx])/i)[1],d=a.match(/height:([ \d.]*p[tx])/i)[1],e=a.match(/src=\s*"([^"]*)"/i)[1];return''}catch(f){return""}}).replace(/<\/?div[^>]*>/g,"").replace(/v:\w+=(["']?)[^'"]+\1/g,"").replace(/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|xml|meta|link|style|\w+:\w+)(?=[\s\/>]))[^>]*>/gi,"").replace(/

    ]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi,"

    $1

    ").replace(/\s+(class|lang|align)\s*=\s*(['"]?)([\w-]+)\2/gi,function(a,b,c,d){return"class"==b&&"MsoListParagraph"==d?a:""}).replace(/<(font|span)[^>]*>(\s*)<\/\1>/gi,function(a,b,c){return c.replace(/[\t\r\n ]+/g," ")}).replace(/(<[a-z][^>]*)\sstyle=(["'])([^\2]*?)\2/gi,function(a,c,d,e){for(var f,g=[],h=e.replace(/^\s+|\s+$/,"").replace(/'/g,"'").replace(/"/gi,"'").replace(/[\d.]+(cm|pt)/g,function(a){return utils.transUnitToPx(a)}).split(/;\s*/g),i=0;f=h[i];i++){var j,k,l=f.split(":");if(2==l.length){if(j=l[0].toLowerCase(),k=l[1].toLowerCase(),/^(background)\w*/.test(j)&&0==k.replace(/(initial|\s)/g,"").length||/^(margin)\w*/.test(j)&&/^0\w+$/.test(k))continue;switch(j){case"mso-padding-alt":case"mso-padding-top-alt":case"mso-padding-right-alt":case"mso-padding-bottom-alt":case"mso-padding-left-alt":case"mso-margin-alt":case"mso-margin-top-alt":case"mso-margin-right-alt":case"mso-margin-bottom-alt":case"mso-margin-left-alt":case"mso-height":case"mso-width":case"mso-vertical-align-alt":/1&&(a(h,j,!0),b(h,j)),c(k,h,i,j);break;case"text":d(g,h);break;case"element":e(g,h,i,j);break;case"comment":f(g,h,i)}return h}function d(a,b){"pre"==a.parentNode.tagName?b.push(a.data):b.push(l[a.parentNode.tagName]?utils.html(a.data):a.data.replace(/[ ]{2}/g,"  "))}function e(d,e,f,g){var h="";if(d.attrs){h=[];var i=d.attrs;for(var j in i)h.push(j+(void 0!==i[j]?'="'+(k[j]?utils.html(i[j]).replace(/["]/g,function(a){return"""}):utils.unhtml(i[j]))+'"':""));h=h.join(" ")}if(e.push("<"+d.tagName+(h?" "+h:"")+(dtd.$empty[d.tagName]?"/":"")+">"),f&&!dtd.$inlineWithA[d.tagName]&&"pre"!=d.tagName&&d.children&&d.children.length&&(g=a(e,g,!0),b(e,g)),d.children&&d.children.length)for(var l,m=0;l=d.children[m++];)f&&"element"==l.type&&!dtd.$inlineWithA[l.tagName]&&m>1&&(a(e,g),b(e,g)),c(l,e,f,g);dtd.$empty[d.tagName]||(f&&!dtd.$inlineWithA[d.tagName]&&"pre"!=d.tagName&&d.children&&d.children.length&&(g=a(e,g),b(e,g)),e.push(""))}function f(a,b){b.push("")}function g(a,b){var c;if("element"==a.type&&a.getAttr("id")==b)return a;if(a.children&&a.children.length)for(var d,e=0;d=a.children[e++];)if(c=g(d,b))return c}function h(a,b,c){if("element"==a.type&&a.tagName==b&&c.push(a),a.children&&a.children.length)for(var d,e=0;d=a.children[e++];)h(d,b,c)}function i(a,b){if(a.children&&a.children.length)for(var c,d=0;c=a.children[d];)i(c,b),c.parentNode&&(c.children&&c.children.length&&b(c),c.parentNode&&d++);else b(a)}var j=UE.uNode=function(a){this.type=a.type,this.data=a.data,this.tagName=a.tagName,this.parentNode=a.parentNode,this.attrs=a.attrs||{},this.children=a.children},k={href:1,src:1,_src:1,_href:1,cdata_data:1},l={style:1,script:1},m=" ",n="\n";j.createElement=function(a){return/[<>]/.test(a)?UE.htmlparser(a).children[0]:new j({type:"element",children:[],tagName:a})},j.createText=function(a,b){return new UE.uNode({type:"text",data:b?a:utils.unhtml(a||"")})},j.prototype={toHtml:function(a){var b=[];return c(this,b,a,0),b.join("")},innerHTML:function(a){if("element"!=this.type||dtd.$empty[this.tagName])return this;if(utils.isString(a)){if(this.children)for(var b,c=0;b=this.children[c++];)b.parentNode=null;this.children=[];for(var b,d=UE.htmlparser(a),c=0;b=d.children[c++];)this.children.push(b),b.parentNode=this;return this}var d=new UE.uNode({type:"root",children:this.children});return d.toHtml()},innerText:function(a,b){if("element"!=this.type||dtd.$empty[this.tagName])return this;if(a){if(this.children)for(var c,d=0;c=this.children[d++];)c.parentNode=null;return this.children=[],this.appendChild(j.createText(a,b)),this}return this.toHtml().replace(/<[^>]+>/g,"")},getData:function(){return"element"==this.type?"":this.data},firstChild:function(){return this.children?this.children[0]:null},lastChild:function(){return this.children?this.children[this.children.length-1]:null},previousSibling:function(){for(var a,b=this.parentNode,c=0;a=b.children[c];c++)if(a===this)return 0==c?null:b.children[c-1]},nextSibling:function(){for(var a,b=this.parentNode,c=0;a=b.children[c++];)if(a===this)return b.children[c]},replaceChild:function(a,b){if(this.children){a.parentNode&&a.parentNode.removeChild(a);for(var c,d=0;c=this.children[d];d++)if(c===b)return this.children.splice(d,1,a),b.parentNode=null,a.parentNode=this,a}},appendChild:function(a){if("root"==this.type||"element"==this.type&&!dtd.$empty[this.tagName]){this.children||(this.children=[]),a.parentNode&&a.parentNode.removeChild(a);for(var b,c=0;b=this.children[c];c++)if(b===a){this.children.splice(c,1);break}return this.children.push(a),a.parentNode=this,a}},insertBefore:function(a,b){if(this.children){a.parentNode&&a.parentNode.removeChild(a);for(var c,d=0;c=this.children[d];d++)if(c===b)return this.children.splice(d,0,a),a.parentNode=this,a}},insertAfter:function(a,b){if(this.children){a.parentNode&&a.parentNode.removeChild(a);for(var c,d=0;c=this.children[d];d++)if(c===b)return this.children.splice(d+1,0,a),a.parentNode=this,a}},removeChild:function(a,b){if(this.children)for(var c,d=0;c=this.children[d];d++)if(c===a){if(this.children.splice(d,1),c.parentNode=null,b&&c.children&&c.children.length)for(var e,f=0;e=c.children[f];f++)this.children.splice(d+f,0,e),e.parentNode=this;return c}},getAttr:function(a){return this.attrs&&this.attrs[a.toLowerCase()]},setAttr:function(a,b){if(!a)return void delete this.attrs;if(this.attrs||(this.attrs={}),utils.isObject(a))for(var c in a)a[c]?this.attrs[c.toLowerCase()]=a[c]:delete this.attrs[c];else b?this.attrs[a.toLowerCase()]=b:delete this.attrs[a]},getIndex:function(){for(var a,b=this.parentNode,c=0;a=b.children[c];c++)if(a===this)return c;return-1},getNodeById:function(a){var b;if(this.children&&this.children.length)for(var c,d=0;c=this.children[d++];)if(b=g(c,a))return b},getNodesByTagName:function(a){a=utils.trim(a).replace(/[ ]{2,}/g," ").split(" ");var b=[],c=this;return utils.each(a,function(a){if(c.children&&c.children.length)for(var d,e=0;d=c.children[e++];)h(d,a,b)}),b},getStyle:function(a){var b=this.getAttr("style");if(!b)return"";var c=new RegExp("(^|;)\\s*"+a+":([^;]+)","i"),d=b.match(c);return d&&d[0]?d[2]:""},setStyle:function(a,b){function c(a,b){var c=new RegExp("(^|;)\\s*"+a+":([^;]+;?)","gi");d=d.replace(c,"$1"),b&&(d=a+":"+utils.unhtml(b)+";"+d)}var d=this.getAttr("style");if(d||(d=""),utils.isObject(a))for(var e in a)c(e,a[e]);else c(a,b);this.setAttr("style",utils.trim(d))},traversal:function(a){return this.children&&this.children.length&&i(this,a),this}}}();var htmlparser=UE.htmlparser=function(a,b){function c(a,b){if(m[a.tagName]){var c=k.createElement(m[a.tagName]);a.appendChild(c),c.appendChild(k.createText(b)),a=c}else a.appendChild(k.createText(b))}function d(a,b,c){var e;if(e=l[b]){for(var f,h=a;"root"!=h.type;){if(utils.isArray(e)?utils.indexOf(e,h.tagName)!=-1:e==h.tagName){a=h,f=!0;break}h=h.parentNode}f||(a=d(a,utils.isArray(e)?e[0]:e))}var i=new k({parentNode:a,type:"element",tagName:b.toLowerCase(),children:dtd.$empty[b]?null:[]});if(c){for(var m,n={};m=g.exec(c);)n[m[1].toLowerCase()]=j[m[1].toLowerCase()]?m[2]||m[3]||m[4]:utils.unhtml(m[2]||m[3]||m[4]);i.attrs=n}return a.children.push(i),dtd.$empty[b]?a:i}function e(a,b){a.children.push(new k({type:"comment",data:b,parentNode:a}))}var f=/<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\s\/<>]+)\s*((?:(?:"[^"]*")|(?:'[^']*')|[^"'<>])*)\/?>))/g,g=/([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g,h={b:1,code:1,i:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,span:1,sub:1,img:1,sup:1,font:1,big:1,small:1,iframe:1,a:1,br:1,pre:1};a=a.replace(new RegExp(domUtils.fillChar,"g"),""),b||(a=a.replace(new RegExp("[\\r\\t\\n"+(b?"":" ")+"]*]*)>[\\r\\t\\n"+(b?"":" ")+"]*","g"),function(a,c){return c&&h[c.toLowerCase()]?a.replace(/(^[\n\r]+)|([\n\r]+$)/g,""):a.replace(new RegExp("^[\\r\\n"+(b?"":" ")+"]+"),"").replace(new RegExp("[\\r\\n"+(b?"":" ")+"]+$"),"")}));for(var i,j={href:1,src:1},k=UE.uNode,l={td:"tr",tr:["tbody","thead","tfoot"],tbody:"table",th:"tr",thead:"table",tfoot:"table",caption:"table",li:["ul","ol"],dt:"dl",dd:"dl",option:"select"},m={ol:"li",ul:"li"},n=0,o=0,p=new k({type:"root",children:[]}),q=p;i=f.exec(a);){n=i.index;try{if(n>o&&c(q,a.slice(o,n)),i[3])dtd.$cdata[q.tagName]?c(q,i[0]):q=d(q,i[3].toLowerCase(),i[4]);else if(i[1]){if("root"!=q.type)if(dtd.$cdata[q.tagName]&&!dtd.$cdata[i[1]])c(q,i[0]);else{for(var r=q;"element"==q.type&&q.tagName!=i[1].toLowerCase();)if(q=q.parentNode,"root"==q.type)throw q=r,"break";q=q.parentNode}}else i[2]&&e(q,i[2])}catch(s){}o=f.lastIndex}return o");break;case"div":if(b.getAttr("cdata_tag"))break;if(d=b.getAttr("class"),d&&/^line number\d+/.test(d))break;if(!e)break;for(var f,g=UE.uNode.createElement("p");f=b.firstChild();)"text"!=f.type&&UE.dom.dtd.$block[f.tagName]?g.firstChild()?(b.parentNode.insertBefore(g,b),g=UE.uNode.createElement("p")):b.parentNode.insertBefore(f,b):g.appendChild(f);g.firstChild()&&b.parentNode.insertBefore(g,b),b.parentNode.removeChild(b);break;case"dl":b.tagName="ul";break;case"dt":case"dd":b.tagName="li";break;case"li":var h=b.getAttr("class");h&&/list\-/.test(h)||b.setAttr();var i=b.getNodesByTagName("ol ul");UE.utils.each(i,function(a){b.parentNode.insertAfter(a,b)});break;case"td":case"th":case"caption":b.children&&b.children.length||b.appendChild(browser.ie11below?UE.uNode.createText(" "):UE.uNode.createElement("br"));break;case"table":a.options.disabledTableInTable&&c(b)&&(b.parentNode.insertBefore(UE.uNode.createText(b.innerText()),b),b.parentNode.removeChild(b))}}})}),a.addOutputRule(function(b){var c;b.traversal(function(b){if("element"==b.type){if(a.options.autoClearEmptyNode&&dtd.$inline[b.tagName]&&!dtd.$empty[b.tagName]&&(!b.attrs||utils.isEmptyObject(b.attrs)))return void(b.firstChild()?"span"!=b.tagName||b.attrs&&!utils.isEmptyObject(b.attrs)||b.parentNode.removeChild(b,!0):b.parentNode.removeChild(b));switch(b.tagName){case"div":(c=b.getAttr("cdata_tag"))&&(b.tagName=c,b.appendChild(UE.uNode.createText(b.getAttr("cdata_data"))),b.setAttr({cdata_tag:"",cdata_data:"",_ue_custom_node_:""}));break;case"a":(c=b.getAttr("_href"))&&b.setAttr({href:utils.html(c),_href:""});break;case"span":c=b.getAttr("id"),c&&/^_baidu_bookmark_/i.test(c)&&b.parentNode.removeChild(b);break;case"img":(c=b.getAttr("_src"))&&b.setAttr({src:b.getAttr("_src"),_src:""})}}})})},UE.commands.inserthtml={execCommand:function(a,b,c){var d,e,f=this;if(b&&f.fireEvent("beforeinserthtml",b)!==!0){if(d=f.selection.getRange(),e=d.document.createElement("div"),e.style.display="inline",!c){var g=UE.htmlparser(b);f.options.filterRules&&UE.filterNode(g,f.options.filterRules),f.filterInputRule(g),b=g.toHtml()}if(e.innerHTML=utils.trim(b),!d.collapsed){var h=d.startContainer;if(domUtils.isFillChar(h)&&d.setStartBefore(h),h=d.endContainer,domUtils.isFillChar(h)&&d.setEndAfter(h),d.txtToElmBoundary(),d.endContainer&&1==d.endContainer.nodeType&&(h=d.endContainer.childNodes[d.endOffset],h&&domUtils.isBr(h)&&d.setEndAfter(h)),0==d.startOffset&&(h=d.startContainer,domUtils.isBoundaryNode(h,"firstChild")&&(h=d.endContainer,d.endOffset==(3==h.nodeType?h.nodeValue.length:h.childNodes.length)&&domUtils.isBoundaryNode(h,"lastChild")&&(f.body.innerHTML="

    "+(browser.ie?"":"
    ")+"

    ",d.setStart(f.body.firstChild,0).collapse(!0)))),!d.collapsed&&d.deleteContents(),1==d.startContainer.nodeType){var i,j=d.startContainer.childNodes[d.startOffset];if(j&&domUtils.isBlockElm(j)&&(i=j.previousSibling)&&domUtils.isBlockElm(i)){for(d.setEnd(i,i.childNodes.length).collapse();j.firstChild;)i.appendChild(j.firstChild);domUtils.remove(j)}}}var j,k,i,l,m,n=0;d.inFillChar()&&(j=d.startContainer,domUtils.isFillChar(j)?(d.setStartBefore(j).collapse(!0),domUtils.remove(j)):domUtils.isFillChar(j,!0)&&(j.nodeValue=j.nodeValue.replace(fillCharReg,""),d.startOffset--,d.collapsed&&d.collapse(!0)));var o=domUtils.findParentByTagName(d.startContainer,"li",!0);if(o){for(var p,q;j=e.firstChild;){for(;j&&(3==j.nodeType||!domUtils.isBlockElm(j)||"HR"==j.tagName);)p=j.nextSibling,d.insertNode(j).collapse(),q=j,j=p;if(j)if(/^(ol|ul)$/i.test(j.tagName)){for(;j.firstChild;)q=j.firstChild,domUtils.insertAfter(o,j.firstChild),o=o.nextSibling;domUtils.remove(j)}else{var r;p=j.nextSibling,r=f.document.createElement("li"),domUtils.insertAfter(o,r),r.appendChild(j),q=j,j=p,o=r}}o=domUtils.findParentByTagName(d.startContainer,"li",!0),domUtils.isEmptyBlock(o)&&domUtils.remove(o),q&&d.setStartAfter(q).collapse(!0).select(!0)}else{for(;j=e.firstChild;){if(n){for(var s=f.document.createElement("p");j&&(3==j.nodeType||!dtd.$block[j.tagName]);)m=j.nextSibling,s.appendChild(j),j=m;s.firstChild&&(j=s)}if(d.insertNode(j),m=j.nextSibling,!n&&j.nodeType==domUtils.NODE_ELEMENT&&domUtils.isBlockElm(j)&&(k=domUtils.findParent(j,function(a){return domUtils.isBlockElm(a)}),k&&"body"!=k.tagName.toLowerCase()&&(!dtd[k.tagName][j.nodeName]||j.parentNode!==k))){if(dtd[k.tagName][j.nodeName])for(l=j.parentNode;l!==k;)i=l,l=l.parentNode;else i=k;domUtils.breakParent(j,i||l);var i=j.previousSibling;domUtils.trimWhiteTextNode(i),i.childNodes.length||domUtils.remove(i),!browser.ie&&(p=j.nextSibling)&&domUtils.isBlockElm(p)&&p.lastChild&&!domUtils.isBr(p.lastChild)&&p.appendChild(f.document.createElement("br")),n=1}var p=j.nextSibling;if(!e.firstChild&&p&&domUtils.isBlockElm(p)){d.setStart(p,0).collapse(!0);break}d.setEndAfter(j).collapse()}if(j=d.startContainer,m&&domUtils.isBr(m)&&domUtils.remove(m),domUtils.isBlockElm(j)&&domUtils.isEmptyNode(j))if(m=j.nextSibling)domUtils.remove(j),1==m.nodeType&&dtd.$block[m.tagName]&&d.setStart(m,0).collapse(!0).shrinkBoundary();else try{j.innerHTML=browser.ie?domUtils.fillChar:"
    "}catch(t){d.setStartBefore(j),domUtils.remove(j)}try{d.select(!0)}catch(t){}}setTimeout(function(){d=f.selection.getRange(),d.scrollToView(f.autoHeightEnabled,f.autoHeightEnabled?domUtils.getXY(f.iframe).y:0),f.fireEvent("afterinserthtml",b)},200)}}},UE.plugins.autotypeset=function(){function a(a,b){return a&&3!=a.nodeType?domUtils.isBr(a)?1:a&&a.parentNode&&l[a.tagName.toLowerCase()]?g&&g.contains(a)||a.getAttribute("pagebreak")?0:b?!domUtils.isEmptyBlock(a):domUtils.isEmptyBlock(a,new RegExp("[\\s"+domUtils.fillChar+"]","g")):void 0:0}function b(a){a.style.cssText||(domUtils.removeAttributes(a,["style"]),"span"==a.tagName.toLowerCase()&&domUtils.hasNoAttributes(a)&&domUtils.remove(a,!0))}function c(c,f){var h,l=this;if(f){if(!i.pasteFilter)return;h=l.document.createElement("div"),h.innerHTML=f.html}else h=l.document.body;for(var m,n=domUtils.getElementsByTagName(h,"*"),o=0;m=n[o++];)if(l.fireEvent("excludeNodeinautotype",m)!==!0){if(i.clearFontSize&&m.style.fontSize&&(domUtils.removeStyle(m,"font-size"),b(m)),i.clearFontFamily&&m.style.fontFamily&&(domUtils.removeStyle(m,"font-family"),b(m)),a(m)){if(i.mergeEmptyline)for(var p,q=m.nextSibling,r=domUtils.isBr(m);a(q)&&(p=q,q=p.nextSibling,!r||q&&(!q||domUtils.isBr(q)));)domUtils.remove(p);if(i.removeEmptyline&&domUtils.inDoc(m,h)&&!k[m.parentNode.tagName.toLowerCase()]){if(domUtils.isBr(m)&&(q=m.nextSibling,q&&!domUtils.isBr(q)))continue;domUtils.remove(m);continue}}if(a(m,!0)&&"SPAN"!=m.tagName&&(i.indent&&(m.style.textIndent=i.indentValue),i.textAlign&&(m.style.textAlign=i.textAlign)),i.removeClass&&m.className&&!j[m.className.toLowerCase()]){if(g&&g.contains(m))continue;domUtils.removeAttributes(m,["class"])}if(i.imageBlockLine&&"img"==m.tagName.toLowerCase()&&!m.getAttribute("emotion"))if(f){var s=m;switch(i.imageBlockLine){case"left":case"right":case"none":for(var p,t,q,u=s.parentNode;dtd.$inline[u.tagName]||"A"==u.tagName;)u=u.parentNode;if(p=u,"P"==p.tagName&&"center"==domUtils.getStyle(p,"text-align")&&!domUtils.isBody(p)&&1==domUtils.getChildCount(p,function(a){return!domUtils.isBr(a)&&!domUtils.isWhitespace(a)}))if(t=p.previousSibling,q=p.nextSibling,t&&q&&1==t.nodeType&&1==q.nodeType&&t.tagName==q.tagName&&domUtils.isBlockElm(t)){for(t.appendChild(p.firstChild);q.firstChild;)t.appendChild(q.firstChild);domUtils.remove(p),domUtils.remove(q)}else domUtils.setStyle(p,"text-align","");domUtils.setStyle(s,"float",i.imageBlockLine);break;case"center":if("center"!=l.queryCommandValue("imagefloat")){for(u=s.parentNode,domUtils.setStyle(s,"float","none"),p=s;u&&1==domUtils.getChildCount(u,function(a){return!domUtils.isBr(a)&&!domUtils.isWhitespace(a)})&&(dtd.$inline[u.tagName]||"A"==u.tagName);)p=u,u=u.parentNode;var v=l.document.createElement("p");domUtils.setAttributes(v,{style:"text-align:center"}),p.parentNode.insertBefore(v,p),v.appendChild(p),domUtils.setStyle(p,"float","")}}}else{var w=l.selection.getRange();w.selectNode(m).select(),l.execCommand("imagefloat",i.imageBlockLine)}i.removeEmptyNode&&i.removeTagNames[m.tagName.toLowerCase()]&&domUtils.hasNoAttributes(m)&&domUtils.isEmptyBlock(m)&&domUtils.remove(m)}if(i.tobdc){var x=UE.htmlparser(h.innerHTML);x.traversal(function(a){"text"==a.type&&(a.data=e(a.data))}),h.innerHTML=x.toHtml()}if(i.bdc2sb){var x=UE.htmlparser(h.innerHTML);x.traversal(function(a){"text"==a.type&&(a.data=d(a.data))}),h.innerHTML=x.toHtml()}f&&(f.html=h.innerHTML)}function d(a){for(var b="",c=0;c=65281&&d<=65373?String.fromCharCode(a.charCodeAt(c)-65248):12288==d?String.fromCharCode(a.charCodeAt(c)-12288+32):a.charAt(c)}return b}function e(a){a=utils.html(a);for(var b="",c=0;c0?e.substring(e.indexOf(d.options.imagePath),e.length-1).replace(/"|\(|\)/gi,""):"none"!=e?e.replace(/url\("?|"?\)/gi,""):"";var g=' ",b.push(g)},aftersetcontent:function(){0==c&&b()}},inputRule:function(d){c=!1,utils.each(d.getNodesByTagName("p"),function(d){var e=d.getAttr("data-background");e&&(c=!0,b(a(e)),d.parentNode.removeChild(d))})},outputRule:function(a){var b=this,c=(utils.cssRule(e,b.document)||"").replace(/[\n\r]+/g,"").match(f);c&&a.appendChild(UE.uNode.createElement('


    '))},commands:{background:{execCommand:function(a,c){b(c)},queryCommandValue:function(){var b=this,c=(utils.cssRule(e,b.document)||"").replace(/[\n\r]+/g,"").match(f);return c?a(c[1]):null},notNeedUndo:!0}}}}),UE.commands.imagefloat={execCommand:function(a,b){var c=this,d=c.selection.getRange();if(!d.collapsed){var e=d.getClosedNode();if(e&&"IMG"==e.tagName)switch(b){case"left":case"right":case"none":for(var f,g,h,i=e.parentNode;dtd.$inline[i.tagName]||"A"==i.tagName;)i=i.parentNode;if(f=i,"P"==f.tagName&&"center"==domUtils.getStyle(f,"text-align")){if(!domUtils.isBody(f)&&1==domUtils.getChildCount(f,function(a){return!domUtils.isBr(a)&&!domUtils.isWhitespace(a)}))if(g=f.previousSibling,h=f.nextSibling,g&&h&&1==g.nodeType&&1==h.nodeType&&g.tagName==h.tagName&&domUtils.isBlockElm(g)){for(g.appendChild(f.firstChild);h.firstChild;)g.appendChild(h.firstChild);domUtils.remove(f),domUtils.remove(h)}else domUtils.setStyle(f,"text-align","");d.selectNode(e).select()}domUtils.setStyle(e,"float","none"==b?"":b),"none"==b&&domUtils.removeAttributes(e,"align");break;case"center":if("center"!=c.queryCommandValue("imagefloat")){for(i=e.parentNode,domUtils.setStyle(e,"float",""),domUtils.removeAttributes(e,"align"),f=e;i&&1==domUtils.getChildCount(i,function(a){return!domUtils.isBr(a)&&!domUtils.isWhitespace(a)})&&(dtd.$inline[i.tagName]||"A"==i.tagName);)f=i,i=i.parentNode;d.setStartBefore(f).setCursor(!1),i=c.document.createElement("div"),i.appendChild(f),domUtils.setStyle(f,"float",""),c.execCommand("insertHtml",'

    '+i.innerHTML+"

    "),f=c.document.getElementById("_img_parent_tmp"),f.removeAttribute("id"),f=f.firstChild,d.selectNode(f).select(),h=f.parentNode.nextSibling,h&&domUtils.isEmptyNode(h)&&domUtils.remove(h)}}}},queryCommandValue:function(){var a,b,c=this.selection.getRange();return c.collapsed?"none":(a=c.getClosedNode(),a&&1==a.nodeType&&"IMG"==a.tagName?(b=domUtils.getComputedStyle(a,"float")||a.getAttribute("align"),"none"==b&&(b="center"==domUtils.getComputedStyle(a.parentNode,"text-align")?"center":b),{left:1,right:1,center:1}[b]?b:"none"):"none")},queryCommandState:function(){var a,b=this.selection.getRange();return b.collapsed?-1:(a=b.getClosedNode(),a&&1==a.nodeType&&"IMG"==a.tagName?0:-1)}},UE.commands.insertimage={execCommand:function(a,b){function c(a){utils.each("width,height,border,hspace,vspace".split(","),function(b){a[b]&&(a[b]=parseInt(a[b],10)||0)}),utils.each("src,_src".split(","),function(b){a[b]&&(a[b]=utils.unhtmlForUrl(a[b]))}),utils.each("title,alt".split(","),function(b){a[b]&&(a[b]=utils.unhtml(a[b]))})}if(b=utils.isArray(b)?b:[b],b.length){var d=this,e=d.selection.getRange(),f=e.getClosedNode();if(d.fireEvent("beforeinsertimage",b)!==!0){if(!f||!/img/i.test(f.tagName)||"edui-faked-video"==f.className&&f.className.indexOf("edui-upload-video")==-1||f.getAttribute("word_img")){var g,h=[],i="";if(g=b[0],1==b.length)c(g),i=''+g.alt+'","center"==g.floatStyle&&(i='

    '+i+"

    "),h.push(i);else for(var j=0;g=b[j++];)c(g),i="

    ",h.push(i);d.execCommand("insertHtml",h.join(""))}else{var k=b.shift(),l=k.floatStyle;delete k.floatStyle,domUtils.setAttributes(f,k),d.execCommand("imagefloat",l),b.length>0&&(e.setStartAfter(f).setCursor(!1,!0),d.execCommand("insertimage",b))}d.fireEvent("afterinsertimage",b)}}}},UE.plugins.justify=function(){var a=domUtils.isBlockElm,b={left:1,right:1,center:1,justify:1},c=function(b,c){var d=b.createBookmark(),e=function(a){return 1==a.nodeType?"br"!=a.tagName.toLowerCase()&&!domUtils.isBookmarkNode(a):!domUtils.isWhitespace(a)};b.enlarge(!0);for(var f,g=b.createBookmark(),h=domUtils.getNextDomNode(g.start,!1,e),i=b.cloneRange();h&&!(domUtils.getPosition(h,g.end)&domUtils.POSITION_FOLLOWING);)if(3!=h.nodeType&&a(h))h=domUtils.getNextDomNode(h,!0,e);else{for(i.setStartBefore(h);h&&h!==g.end&&!a(h);)f=h,h=domUtils.getNextDomNode(h,!1,null,function(b){return!a(b)});i.setEndAfter(f);var j=i.getCommonAncestor();if(!domUtils.isBody(j)&&a(j))domUtils.setStyles(j,utils.isString(c)?{"text-align":c}:c),h=j;else{var k=b.document.createElement("p");domUtils.setStyles(k,utils.isString(c)?{"text-align":c}:c);var l=i.extractContents();k.appendChild(l),i.insertNode(k),h=k}h=domUtils.getNextDomNode(h,!1,e)}return b.moveToBookmark(g).moveToBookmark(d)};UE.commands.justify={execCommand:function(a,b){var d,e=this.selection.getRange();return e.collapsed&&(d=this.document.createTextNode("p"),e.insertNode(d)),c(e,b),d&&(e.setStartBefore(d).collapse(!0),domUtils.remove(d)),e.select(),!0},queryCommandValue:function(){var a=this.selection.getStart(),c=domUtils.getComputedStyle(a,"text-align");return b[c]?c:"left"},queryCommandState:function(){var a=this.selection.getStart(),b=a&&domUtils.findParentByTagName(a,["td","th","caption"],!0);return b?-1:0}}},UE.plugins.font=function(){function a(a){for(var b;(b=a.parentNode)&&"SPAN"==b.tagName&&1==domUtils.getChildCount(b,function(a){return!domUtils.isBookmarkNode(a)&&!domUtils.isBr(a)});)b.style.cssText+=a.style.cssText,domUtils.remove(a,!0),a=b}function b(a,b,c){if(g[b]&&(a.adjustmentBoundary(),!a.collapsed&&1==a.startContainer.nodeType)){var d=a.startContainer.childNodes[a.startOffset];if(d&&domUtils.isTagNode(d,"span")){var e=a.createBookmark();utils.each(domUtils.getElementsByTagName(d,"span"),function(a){a.parentNode&&!domUtils.isBookmarkNode(a)&&("backcolor"==b&&domUtils.getComputedStyle(a,"background-color").toLowerCase()===c||(domUtils.removeStyle(a,g[b]),0==a.style.cssText.replace(/^\s+$/,"").length&&domUtils.remove(a,!0)))}),a.moveToBookmark(e)}}}function c(c,d,e){var f,g=c.collapsed,h=c.createBookmark();if(g)for(f=h.start.parentNode;dtd.$inline[f.tagName];)f=f.parentNode;else f=domUtils.getCommonAncestor(h.start,h.end);utils.each(domUtils.getElementsByTagName(f,"span"),function(b){if(b.parentNode&&!domUtils.isBookmarkNode(b)){if(/\s*border\s*:\s*none;?\s*/i.test(b.style.cssText))return void(/^\s*border\s*:\s*none;?\s*$/.test(b.style.cssText)?domUtils.remove(b,!0):domUtils.removeStyle(b,"border"));if(/border/i.test(b.style.cssText)&&"SPAN"==b.parentNode.tagName&&/border/i.test(b.parentNode.style.cssText)&&(b.style.cssText=b.style.cssText.replace(/border[^:]*:[^;]+;?/gi,"")),"fontborder"!=d||"none"!=e)for(var c=b.nextSibling;c&&1==c.nodeType&&"SPAN"==c.tagName;)if(domUtils.isBookmarkNode(c)&&"fontborder"==d)b.appendChild(c),c=b.nextSibling;else{if(c.style.cssText==b.style.cssText&&(domUtils.moveChild(c,b),domUtils.remove(c)),b.nextSibling===c)break;c=b.nextSibling}if(a(b),browser.ie&&browser.version>8){var f=domUtils.findParent(b,function(a){return"SPAN"==a.tagName&&/background-color/.test(a.style.cssText)});f&&!/background-color/.test(b.style.cssText)&&(b.style.backgroundColor=f.style.backgroundColor)}}}),c.moveToBookmark(h),b(c,d,e)}var d=this,e={forecolor:"color",backcolor:"background-color",fontsize:"font-size",fontfamily:"font-family",underline:"text-decoration",strikethrough:"text-decoration",fontborder:"border"},f={underline:1,strikethrough:1,fontborder:1},g={forecolor:"color",backcolor:"background-color",fontsize:"font-size",fontfamily:"font-family"};d.setOpt({fontfamily:[{name:"songti",val:"宋体,SimSun"},{name:"yahei",val:"微软雅黑,Microsoft YaHei"},{name:"kaiti",val:"楷体,楷体_GB2312, SimKai"},{name:"heiti",val:"黑体, SimHei"},{name:"lishu",val:"隶书, SimLi"},{name:"andaleMono",val:"andale mono"},{name:"arial",val:"arial, helvetica,sans-serif"},{name:"arialBlack",val:"arial black,avant garde"},{name:"comicSansMs",val:"comic sans ms"},{name:"impact",val:"impact,chicago"},{name:"timesNewRoman",val:"times new roman"}],fontsize:[10,11,12,14,16,18,20,24,36]}),d.addInputRule(function(a){utils.each(a.getNodesByTagName("u s del font strike"),function(a){if("font"==a.tagName){var b=[];for(var c in a.attrs)switch(c){case"size":b.push("font-size:"+({1:"10",2:"12",3:"16",4:"18",5:"24",6:"32",7:"48"}[a.attrs[c]]||a.attrs[c])+"px");break;case"color":b.push("color:"+a.attrs[c]);break;case"face":b.push("font-family:"+a.attrs[c]);break;case"style":b.push(a.attrs[c])}a.attrs={style:b.join(";")}}else{var d="u"==a.tagName?"underline":"line-through";a.attrs={style:(a.getAttr("style")||"")+"text-decoration:"+d+";"}}a.tagName="span"})});for(var h in e)!function(a,b){UE.commands[a]={execCommand:function(d,e){e=e||(this.queryCommandState(d)?"none":"underline"==d?"underline":"fontborder"==d?"1px solid #000":"line-through");var g,h=this,i=this.selection.getRange();if("default"==e)i.collapsed&&(g=h.document.createTextNode("font"),i.insertNode(g).select()),h.execCommand("removeFormat","span,a",b),g&&(i.setStartBefore(g).collapse(!0),domUtils.remove(g)),c(i,d,e),i.select();else if(i.collapsed){var j=domUtils.findParentByTagName(i.startContainer,"span",!0);if(g=h.document.createTextNode("font"),!j||j.children.length||j[browser.ie?"innerText":"textContent"].replace(fillCharReg,"").length){if(i.insertNode(g),i.selectNode(g).select(),j=i.document.createElement("span"),f[a]){if(domUtils.findParentByTagName(g,"a",!0))return i.setStartBefore(g).setCursor(),void domUtils.remove(g);h.execCommand("removeFormat","span,a",b)}if(j.style.cssText=b+":"+e,g.parentNode.insertBefore(j,g),!browser.ie||browser.ie&&9==browser.version)for(var k=j.parentNode;!domUtils.isBlockElm(k);)"SPAN"==k.tagName&&(j.style.cssText=k.style.cssText+";"+j.style.cssText),k=k.parentNode;opera?setTimeout(function(){i.setStart(j,0).collapse(!0),c(i,d,e),i.select()}):(i.setStart(j,0).collapse(!0),c(i,d,e),i.select())}else i.insertNode(g),f[a]&&(i.selectNode(g).select(),h.execCommand("removeFormat","span,a",b,null),j=domUtils.findParentByTagName(g,"span",!0),i.setStartBefore(g)),j&&(j.style.cssText+=";"+b+":"+e),i.collapse(!0).select();domUtils.remove(g)}else f[a]&&h.queryCommandValue(a)&&h.execCommand("removeFormat","span,a",b),i=h.selection.getRange(),i.applyInlineStyle("span",{style:b+":"+e}),c(i,d,e),i.select();return!0},queryCommandValue:function(a){var c=this.selection.getStart();if("underline"==a||"strikethrough"==a){for(var d,e=c;e&&!domUtils.isBlockElm(e)&&!domUtils.isBody(e);){if(1==e.nodeType&&(d=domUtils.getComputedStyle(e,b),"none"!=d))return d;e=e.parentNode}return"none"}if("fontborder"==a){for(var f,g=c;g&&dtd.$inline[g.tagName];){if((f=domUtils.getComputedStyle(g,"border"))&&/1px/.test(f)&&/solid/.test(f))return f;g=g.parentNode}return""}if("FontSize"==a){var h=domUtils.getComputedStyle(c,b),g=/^([\d\.]+)(\w+)$/.exec(h);return g?Math.floor(g[1])+g[2]:h}return domUtils.getComputedStyle(c,b)},queryCommandState:function(a){if(!f[a])return 0;var b=this.queryCommandValue(a);return"fontborder"==a?/1px/.test(b)&&/solid/.test(b):"underline"==a?/underline/.test(b):/line\-through/.test(b)}}}(h,e[h])},UE.plugins.link=function(){function a(a){var b=a.startContainer,c=a.endContainer;(b=domUtils.findParentByTagName(b,"a",!0))&&a.setStartBefore(b),(c=domUtils.findParentByTagName(c,"a",!0))&&a.setEndAfter(c)}function b(b,c,d){var e=b.cloneRange(),f=d.queryCommandValue("link");a(b=b.adjustmentBoundary());var g=b.startContainer;if(1==g.nodeType&&f&&(g=g.childNodes[b.startOffset],g&&1==g.nodeType&&"A"==g.tagName&&/^(?:https?|ftp|file)\s*:\s*\/\//.test(g[browser.ie?"innerText":"textContent"])&&(g[browser.ie?"innerText":"textContent"]=utils.html(c.textValue||c.href))),e.collapsed&&!f||(b.removeInlineStyle("a"),e=b.cloneRange()),e.collapsed){var h=b.document.createElement("a"),i="";c.textValue?(i=utils.html(c.textValue),delete c.textValue):i=utils.html(c.href),domUtils.setAttributes(h,c),g=domUtils.findParentByTagName(e.startContainer,"a",!0),g&&domUtils.isInNodeEndBoundary(e,g)&&b.setStartAfter(g).collapse(!0),h[browser.ie?"innerText":"textContent"]=i,b.insertNode(h).selectNode(h)}else b.applyInlineStyle("a",c)}UE.commands.unlink={execCommand:function(){var b,c=this.selection.getRange();c.collapsed&&!domUtils.findParentByTagName(c.startContainer,"a",!0)||(b=c.createBookmark(),a(c),c.removeInlineStyle("a").moveToBookmark(b).select())},queryCommandState:function(){return!this.highlight&&this.queryCommandValue("link")?0:-1}},UE.commands.link={execCommand:function(a,c){var d;c._href&&(c._href=utils.unhtml(c._href,/[<">]/g)),c.href&&(c.href=utils.unhtml(c.href,/[<">]/g)),c.textValue&&(c.textValue=utils.unhtml(c.textValue,/[<">]/g)),b(d=this.selection.getRange(),c,this),d.collapse().select(!0)},queryCommandValue:function(){var a,b=this.selection.getRange();if(!b.collapsed){b.shrinkBoundary();var c=3!=b.startContainer.nodeType&&b.startContainer.childNodes[b.startOffset]?b.startContainer.childNodes[b.startOffset]:b.startContainer,d=3==b.endContainer.nodeType||0==b.endOffset?b.endContainer:b.endContainer.childNodes[b.endOffset-1],e=b.getCommonAncestor();if(a=domUtils.findParentByTagName(e,"a",!0),!a&&1==e.nodeType)for(var f,g,h,i=e.getElementsByTagName("a"),j=0;h=i[j++];)if(f=domUtils.getPosition(h,c),g=domUtils.getPosition(h,d),(f&domUtils.POSITION_FOLLOWING||f&domUtils.POSITION_CONTAINS)&&(g&domUtils.POSITION_PRECEDING||g&domUtils.POSITION_CONTAINS)){a=h;break}return a}if(a=b.startContainer,a=1==a.nodeType?a:a.parentNode,a&&(a=domUtils.findParentByTagName(a,"a",!0))&&!domUtils.isInNodeEndBoundary(b,a))return a},queryCommandState:function(){var a=this.selection.getRange().getClosedNode(),b=a&&("edui-faked-video"==a.className||a.className.indexOf("edui-upload-video")!=-1);return b?-1:0}}},UE.plugins.insertframe=function(){function a(){b._iframe&&delete b._iframe}var b=this;b.addListener("selectionchange",function(){a()})},UE.commands.scrawl={queryCommandState:function(){return browser.ie&&browser.version<=8?-1:0}},UE.plugins.removeformat=function(){var a=this;a.setOpt({removeFormatTags:"b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var",removeFormatAttributes:"class,style,lang,width,height,align,hspace,valign"}),a.commands.removeformat={execCommand:function(a,b,c,d,e){function f(a){if(3==a.nodeType||"span"!=a.tagName.toLowerCase())return 0;if(browser.ie){var b=a.attributes;if(b.length){for(var c=0,d=b.length;c
    "+this.getContent(null,null,!0)+"
    "),b.close()},notNeedUndo:1},UE.plugins.selectall=function(){var a=this;a.commands.selectall={execCommand:function(){var a=this,b=a.body,c=a.selection.getRange();c.selectNodeContents(b),domUtils.isEmptyBlock(b)&&(browser.opera&&b.firstChild&&1==b.firstChild.nodeType&&c.setStartAtFirst(b.firstChild),c.collapse(!0)),c.select(!0)},notNeedUndo:1},a.addshortcutkey({selectAll:"ctrl+65"})},UE.plugins.paragraph=function(){var a=this,b=domUtils.isBlockElm,c=["TD","LI","PRE"],d=function(a,d,e,f){var g,h=a.createBookmark(),i=function(a){return 1==a.nodeType?"br"!=a.tagName.toLowerCase()&&!domUtils.isBookmarkNode(a):!domUtils.isWhitespace(a)};a.enlarge(!0);for(var j,k=a.createBookmark(),l=domUtils.getNextDomNode(k.start,!1,i),m=a.cloneRange();l&&!(domUtils.getPosition(l,k.end)&domUtils.POSITION_FOLLOWING);)if(3!=l.nodeType&&b(l))l=domUtils.getNextDomNode(l,!0,i);else{for(m.setStartBefore(l);l&&l!==k.end&&!b(l);)j=l,l=domUtils.getNextDomNode(l,!1,null,function(a){return!b(a)});m.setEndAfter(j),g=a.document.createElement(d),e&&(domUtils.setAttributes(g,e),f&&"customstyle"==f&&e.style&&(g.style.cssText=e.style)),g.appendChild(m.extractContents()),domUtils.isEmptyNode(g)&&domUtils.fillChar(a.document,g),m.insertNode(g);var n=g.parentNode;b(n)&&!domUtils.isBody(g.parentNode)&&utils.indexOf(c,n.tagName)==-1&&(f&&"customstyle"==f||(n.getAttribute("dir")&&g.setAttribute("dir",n.getAttribute("dir")),n.style.cssText&&(g.style.cssText=n.style.cssText+";"+g.style.cssText),n.style.textAlign&&!g.style.textAlign&&(g.style.textAlign=n.style.textAlign),n.style.textIndent&&!g.style.textIndent&&(g.style.textIndent=n.style.textIndent),n.style.padding&&!g.style.padding&&(g.style.padding=n.style.padding)),e&&/h\d/i.test(n.tagName)&&!/h\d/i.test(g.tagName)?(domUtils.setAttributes(n,e),f&&"customstyle"==f&&e.style&&(n.style.cssText=e.style),domUtils.remove(g,!0),g=n):domUtils.remove(g.parentNode,!0)),l=utils.indexOf(c,n.tagName)!=-1?n:g,l=domUtils.getNextDomNode(l,!1,i)}return a.moveToBookmark(k).moveToBookmark(h)};a.setOpt("paragraph",{p:"",h1:"",h2:"",h3:"",h4:"",h5:"",h6:""}),a.commands.paragraph={execCommand:function(a,b,c,e){var f=this.selection.getRange();if(f.collapsed){var g=this.document.createTextNode("p");if(f.insertNode(g),browser.ie){var h=g.previousSibling;h&&domUtils.isWhitespace(h)&&domUtils.remove(h),h=g.nextSibling,h&&domUtils.isWhitespace(h)&&domUtils.remove(h)}}if(f=d(f,b,c,e),g&&(f.setStartBefore(g).collapse(!0),pN=g.parentNode,domUtils.remove(g),domUtils.isBlockElm(pN)&&domUtils.isEmptyNode(pN)&&domUtils.fillNode(this.document,pN)),browser.gecko&&f.collapsed&&1==f.startContainer.nodeType){var i=f.startContainer.childNodes[f.startOffset];i&&1==i.nodeType&&i.tagName.toLowerCase()==b&&f.setStart(i,0).collapse(!0)}return f.select(),!0},queryCommandValue:function(){var a=domUtils.filterNodeList(this.selection.getStartElementPath(),"p h1 h2 h3 h4 h5 h6");return a?a.tagName.toLowerCase():""}}},function(){var a=domUtils.isBlockElm,b=function(a){return domUtils.filterNodeList(a.selection.getStartElementPath(),function(a){return a&&1==a.nodeType&&a.getAttribute("dir")})},c=function(c,d,e){var f,g=function(a){return 1==a.nodeType?!domUtils.isBookmarkNode(a):!domUtils.isWhitespace(a)},h=b(d);if(h&&c.collapsed)return h.setAttribute("dir",e),c;f=c.createBookmark(),c.enlarge(!0);for(var i,j=c.createBookmark(),k=domUtils.getNextDomNode(j.start,!1,g),l=c.cloneRange();k&&!(domUtils.getPosition(k,j.end)&domUtils.POSITION_FOLLOWING);)if(3!=k.nodeType&&a(k))k=domUtils.getNextDomNode(k,!0,g);else{for(l.setStartBefore(k);k&&k!==j.end&&!a(k);)i=k,k=domUtils.getNextDomNode(k,!1,null,function(b){return!a(b)});l.setEndAfter(i);var m=l.getCommonAncestor();if(!domUtils.isBody(m)&&a(m))m.setAttribute("dir",e),k=m;else{var n=c.document.createElement("p");n.setAttribute("dir",e);var o=l.extractContents();n.appendChild(o),l.insertNode(n),k=n}k=domUtils.getNextDomNode(k,!1,g)}return c.moveToBookmark(j).moveToBookmark(f)};UE.commands.directionality={execCommand:function(a,b){var d=this.selection.getRange();if(d.collapsed){var e=this.document.createTextNode("d");d.insertNode(e)}return c(d,this,b),e&&(d.setStartBefore(e).collapse(!0),domUtils.remove(e)),d.select(),!0},queryCommandValue:function(){var a=b(this);return a?a.getAttribute("dir"):"ltr"}}}(),UE.plugins.horizontal=function(){var a=this;a.commands.horizontal={execCommand:function(a){var b=this;if(b.queryCommandState(a)!==-1){b.execCommand("insertHtml","
    ");var c=b.selection.getRange(),d=c.startContainer;if(1==d.nodeType&&!d.childNodes[c.startOffset]){var e;(e=d.childNodes[c.startOffset-1])&&1==e.nodeType&&"HR"==e.tagName&&("p"==b.options.enterTag?(e=b.document.createElement("p"),c.insertNode(e),c.setStart(e,0).setCursor()):(e=b.document.createElement("br"),c.insertNode(e),c.setStartBefore(e).setCursor()))}return!0}},queryCommandState:function(){return domUtils.filterNodeList(this.selection.getStartElementPath(),"table")?-1:0}},a.addListener("delkeydown",function(a,b){var c=this.selection.getRange();if(c.txtToElmBoundary(!0),domUtils.isStartInblock(c)){var d=c.startContainer,e=d.previousSibling;if(e&&domUtils.isTagNode(e,"hr"))return domUtils.remove(e),c.select(),domUtils.preventDefault(b),!0}})},UE.commands.time=UE.commands.date={execCommand:function(a,b){function c(a,b){var c=("0"+a.getHours()).slice(-2),d=("0"+a.getMinutes()).slice(-2),e=("0"+a.getSeconds()).slice(-2);return b=b||"hh:ii:ss",b.replace(/hh/gi,c).replace(/ii/gi,d).replace(/ss/gi,e)}function d(a,b){var c=("000"+a.getFullYear()).slice(-4),d=c.slice(-2),e=("0"+(a.getMonth()+1)).slice(-2),f=("0"+a.getDate()).slice(-2);return b=b||"yyyy-mm-dd",b.replace(/yyyy/gi,c).replace(/yy/gi,d).replace(/mm/gi,e).replace(/dd/gi,f)}var e=new Date;this.execCommand("insertHtml","time"==a?c(e,b):d(e,b))}},UE.plugins.rowspacing=function(){var a=this;a.setOpt({rowspacingtop:["5","10","15","20","25"],rowspacingbottom:["5","10","15","20","25"]}),a.commands.rowspacing={execCommand:function(a,b,c){return this.execCommand("paragraph","p",{style:"margin-"+c+":"+b+"px"}),!0},queryCommandValue:function(a,b){var c,d=domUtils.filterNodeList(this.selection.getStartElementPath(),function(a){return domUtils.isBlockElm(a)});return d?(c=domUtils.getComputedStyle(d,"margin-"+b).replace(/[^\d]/g,""),c?c:0):0}}},UE.plugins.lineheight=function(){var a=this;a.setOpt({lineheight:["1","1.5","1.75","2","3","4","5"]}),a.commands.lineheight={execCommand:function(a,b){return this.execCommand("paragraph","p",{style:"line-height:"+("1"==b?"normal":b+"em")}),!0},queryCommandValue:function(){var a=domUtils.filterNodeList(this.selection.getStartElementPath(),function(a){return domUtils.isBlockElm(a)});if(a){var b=domUtils.getComputedStyle(a,"line-height");return"normal"==b?1:b.replace(/[^\d.]*/gi,"")}}}},UE.plugins.insertcode=function(){var a=this;a.ready(function(){utils.cssRule("pre","pre{margin:.5em 0;padding:.4em .6em;border-radius:8px;background:#f8f8f8;}",a.document)}),a.setOpt("insertcode",{as3:"ActionScript3",bash:"Bash/Shell",cpp:"C/C++",css:"Css",cf:"CodeFunction","c#":"C#",delphi:"Delphi",diff:"Diff",erlang:"Erlang",groovy:"Groovy",html:"Html",java:"Java",jfx:"JavaFx",js:"Javascript",pl:"Perl",php:"Php",plain:"Plain Text",ps:"PowerShell",python:"Python",ruby:"Ruby",scala:"Scala",sql:"Sql",vb:"Vb",xml:"Xml"}),a.commands.insertcode={execCommand:function(a,b){var c=this,d=c.selection.getRange(),e=domUtils.findParentByTagName(d.startContainer,"pre",!0);if(e)e.className="brush:"+b+";toolbar:false;";else{var f="";if(d.collapsed)f=browser.ie&&browser.ie11below?browser.version<=8?" ":"":"
    ";else{var g=d.extractContents(),h=c.document.createElement("div");h.appendChild(g),utils.each(UE.filterNode(UE.htmlparser(h.innerHTML.replace(/[\r\t]/g,"")),c.options.filterTxtRules).children,function(a){if(browser.ie&&browser.ie11below&&browser.version>8)"element"==a.type?"br"==a.tagName?f+="\n":dtd.$empty[a.tagName]||(utils.each(a.children,function(b){"element"==b.type?"br"==b.tagName?f+="\n":dtd.$empty[a.tagName]||(f+=b.innerText()):f+=b.data}),/\n$/.test(f)||(f+="\n")):f+=a.data+"\n",!a.nextSibling()&&/\n$/.test(f)&&(f=f.replace(/\n$/,""));else if(browser.ie&&browser.ie11below)"element"==a.type?"br"==a.tagName?f+="
    ":dtd.$empty[a.tagName]||(utils.each(a.children,function(b){"element"==b.type?"br"==b.tagName?f+="
    ":dtd.$empty[a.tagName]||(f+=b.innerText()):f+=b.data}),/br>$/.test(f)||(f+="
    ")):f+=a.data+"
    ",!a.nextSibling()&&/
    $/.test(f)&&(f=f.replace(/
    $/,""));else if(f+="element"==a.type?dtd.$empty[a.tagName]?"":a.innerText():a.data,!/br\/?\s*>$/.test(f)){if(!a.nextSibling())return;f+="
    "}})}c.execCommand("inserthtml",'
    '+f+"
    ",!0),e=c.document.getElementById("coder"),domUtils.removeAttributes(e,"id");var i=e.previousSibling;i&&(3==i.nodeType&&1==i.nodeValue.length&&browser.ie&&6==browser.version||domUtils.isEmptyBlock(i))&&domUtils.remove(i);var d=c.selection.getRange();domUtils.isEmptyBlock(e)?d.setStart(e,0).setCursor(!1,!0):d.selectNodeContents(e).select()}},queryCommandValue:function(){var a=this.selection.getStartElementPath(),b="";return utils.each(a,function(a){if("PRE"==a.nodeName){var c=a.className.match(/brush:([^;]+)/);return b=c&&c[1]?c[1]:"",!1}}),b}},a.addInputRule(function(a){utils.each(a.getNodesByTagName("pre"),function(a){var b=a.getNodesByTagName("br");if(b.length)return void(browser.ie&&browser.ie11below&&browser.version>8&&utils.each(b,function(a){var b=UE.uNode.createText("\n");a.parentNode.insertBefore(b,a),a.parentNode.removeChild(a)}));if(!(browser.ie&&browser.ie11below&&browser.version>8)){var c=a.innerText().split(/\n/);a.innerHTML(""),utils.each(c,function(b){b.length&&a.appendChild(UE.uNode.createText(b)),a.appendChild(UE.uNode.createElement("br"))})}})}),a.addOutputRule(function(a){utils.each(a.getNodesByTagName("pre"),function(a){var b="";utils.each(a.children,function(a){b+="text"==a.type?a.data.replace(/[ ]/g," ").replace(/\n$/,""):"br"==a.tagName?"\n":dtd.$empty[a.tagName]?a.innerText():""}),a.innerText(b.replace(/( |\n)+$/,""))})}),a.notNeedCodeQuery={help:1,undo:1,redo:1,source:1,print:1,searchreplace:1,fullscreen:1,preview:1,insertparagraph:1,elementpath:1,insertcode:1,inserthtml:1,selectall:1};a.queryCommandState;a.queryCommandState=function(a){var b=this;return!b.notNeedCodeQuery[a.toLowerCase()]&&b.selection&&b.queryCommandValue("insertcode")?-1:UE.Editor.prototype.queryCommandState.apply(this,arguments)},a.addListener("beforeenterkeydown",function(){var b=a.selection.getRange(),c=domUtils.findParentByTagName(b.startContainer,"pre",!0);if(c){if(a.fireEvent("saveScene"),b.collapsed||b.deleteContents(),!browser.ie||browser.ie9above){var c,d=a.document.createElement("br");b.insertNode(d).setStartAfter(d).collapse(!0);var e=d.nextSibling;e||browser.ie&&!(browser.version>10)?b.setStartAfter(d):b.insertNode(d.cloneNode(!1)), -c=d.previousSibling;for(var f;c;)if(f=c,c=c.previousSibling,!c||"BR"==c.nodeName){c=f;break}if(c){for(var g="";c&&"BR"!=c.nodeName&&new RegExp("^[\\s"+domUtils.fillChar+"]*$").test(c.nodeValue);)g+=c.nodeValue,c=c.nextSibling;if("BR"!=c.nodeName){var h=c.nodeValue.match(new RegExp("^([\\s"+domUtils.fillChar+"]+)"));h&&h[1]&&(g+=h[1])}g&&(g=a.document.createTextNode(g),b.insertNode(g).setStartAfter(g))}b.collapse(!0).select(!0)}else if(browser.version>8){var i=a.document.createTextNode("\n"),j=b.startContainer;if(0==b.startOffset){var k=j.previousSibling;if(k){b.insertNode(i);var l=a.document.createTextNode(" ");b.setStartAfter(i).insertNode(l).setStart(l,0).collapse(!0).select(!0)}}else{b.insertNode(i).setStartAfter(i);var l=a.document.createTextNode(" ");j=b.startContainer.childNodes[b.startOffset],j&&!/^\n/.test(j.nodeValue)&&b.setStartBefore(i),b.insertNode(l).setStart(l,0).collapse(!0).select(!0)}}else{var d=a.document.createElement("br");b.insertNode(d),b.insertNode(a.document.createTextNode(domUtils.fillChar)),b.setStartAfter(d),c=d.previousSibling;for(var f;c;)if(f=c,c=c.previousSibling,!c||"BR"==c.nodeName){c=f;break}if(c){for(var g="";c&&"BR"!=c.nodeName&&new RegExp("^[ "+domUtils.fillChar+"]*$").test(c.nodeValue);)g+=c.nodeValue,c=c.nextSibling;if("BR"!=c.nodeName){var h=c.nodeValue.match(new RegExp("^([ "+domUtils.fillChar+"]+)"));h&&h[1]&&(g+=h[1])}g=a.document.createTextNode(g),b.insertNode(g).setStartAfter(g)}b.collapse(!0).select()}return a.fireEvent("saveScene"),!0}}),a.addListener("tabkeydown",function(b,c){var d=a.selection.getRange(),e=domUtils.findParentByTagName(d.startContainer,"pre",!0);if(e){if(a.fireEvent("saveScene"),c.shiftKey);else if(d.collapsed){var f=a.document.createTextNode(" ");d.insertNode(f).setStartAfter(f).collapse(!0).select(!0)}else{for(var g=d.createBookmark(),h=g.start.previousSibling;h;){if(e.firstChild===h&&!domUtils.isBr(h)){e.insertBefore(a.document.createTextNode(" "),h);break}if(domUtils.isBr(h)){e.insertBefore(a.document.createTextNode(" "),h.nextSibling);break}h=h.previousSibling}var i=g.end;for(h=g.start.nextSibling,e.firstChild===g.start&&e.insertBefore(a.document.createTextNode(" "),h.nextSibling);h&&h!==i;){if(domUtils.isBr(h)&&h.nextSibling){if(h.nextSibling===i)break;e.insertBefore(a.document.createTextNode(" "),h.nextSibling)}h=h.nextSibling}d.moveToBookmark(g).select()}return a.fireEvent("saveScene"),!0}}),a.addListener("beforeinserthtml",function(a,b){var c=this,d=c.selection.getRange(),e=domUtils.findParentByTagName(d.startContainer,"pre",!0);if(e){d.collapsed||d.deleteContents();var f="";if(browser.ie&&browser.version>8){utils.each(UE.filterNode(UE.htmlparser(b),c.options.filterTxtRules).children,function(a){"element"==a.type?"br"==a.tagName?f+="\n":dtd.$empty[a.tagName]||(utils.each(a.children,function(b){"element"==b.type?"br"==b.tagName?f+="\n":dtd.$empty[a.tagName]||(f+=b.innerText()):f+=b.data}),/\n$/.test(f)||(f+="\n")):f+=a.data+"\n",!a.nextSibling()&&/\n$/.test(f)&&(f=f.replace(/\n$/,""))});var g=c.document.createTextNode(utils.html(f.replace(/ /g," ")));d.insertNode(g).selectNode(g).select()}else{var h=c.document.createDocumentFragment();utils.each(UE.filterNode(UE.htmlparser(b),c.options.filterTxtRules).children,function(a){"element"==a.type?"br"==a.tagName?h.appendChild(c.document.createElement("br")):dtd.$empty[a.tagName]||(utils.each(a.children,function(b){"element"==b.type?"br"==b.tagName?h.appendChild(c.document.createElement("br")):dtd.$empty[a.tagName]||h.appendChild(c.document.createTextNode(utils.html(b.innerText().replace(/ /g," ")))):h.appendChild(c.document.createTextNode(utils.html(b.data.replace(/ /g," "))))}),"BR"!=h.lastChild.nodeName&&h.appendChild(c.document.createElement("br"))):h.appendChild(c.document.createTextNode(utils.html(a.data.replace(/ /g," ")))),a.nextSibling()||"BR"!=h.lastChild.nodeName||h.removeChild(h.lastChild)}),d.insertNode(h).select()}return!0}}),a.addListener("keydown",function(a,b){var c=this,d=b.keyCode||b.which;if(40==d){var e,f=c.selection.getRange(),g=f.startContainer;if(f.collapsed&&(e=domUtils.findParentByTagName(f.startContainer,"pre",!0))&&!e.nextSibling){for(var h=e.lastChild;h&&"BR"==h.nodeName;)h=h.previousSibling;(h===g||f.startContainer===e&&f.startOffset==e.childNodes.length)&&(c.execCommand("insertparagraph"),domUtils.preventDefault(b))}}}),a.addListener("delkeydown",function(b,c){var d=this.selection.getRange();d.txtToElmBoundary(!0);var e=d.startContainer;if(domUtils.isTagNode(e,"pre")&&d.collapsed&&domUtils.isStartInblock(d)){var f=a.document.createElement("p");return domUtils.fillNode(a.document,f),e.parentNode.insertBefore(f,e),domUtils.remove(e),d.setStart(f,0).setCursor(!1,!0),domUtils.preventDefault(c),!0}})},UE.commands.cleardoc={execCommand:function(a){var b=this,c=b.options.enterTag,d=b.selection.getRange();"br"==c?(b.body.innerHTML="
    ",d.setStart(b.body,0).setCursor()):(b.body.innerHTML="

    "+(ie?"":"
    ")+"

    ",d.setStart(b.body.firstChild,0).setCursor(!1,!0)),setTimeout(function(){b.fireEvent("clearDoc")},0)}},UE.plugin.register("anchor",function(){return{bindEvents:{ready:function(){utils.cssRule("anchor",".anchorclass{background: url('"+this.options.themePath+this.options.theme+"/images/anchor.gif') no-repeat scroll left center transparent;cursor: auto;display: inline-block;height: 16px;width: 15px;}",this.document)}},outputRule:function(a){utils.each(a.getNodesByTagName("img"),function(a){var b;(b=a.getAttr("anchorname"))&&(a.tagName="a",a.setAttr({anchorname:"",name:b,"class":""}))})},inputRule:function(a){utils.each(a.getNodesByTagName("a"),function(a){var b;(b=a.getAttr("name"))&&!a.getAttr("href")&&(a.tagName="img",a.setAttr({anchorname:a.getAttr("name"),"class":"anchorclass"}),a.setAttr("name"))})},commands:{anchor:{execCommand:function(a,b){var c=this.selection.getRange(),d=c.getClosedNode();if(d&&d.getAttribute("anchorname"))b?d.setAttribute("anchorname",b):(c.setStartBefore(d).setCursor(),domUtils.remove(d));else if(b){var e=this.document.createElement("img");c.collapse(!0),domUtils.setAttributes(e,{anchorname:b,"class":"anchorclass"}),c.insertNode(e).setStartAfter(e).setCursor(!1,!0)}}}}}}),UE.plugins.wordcount=function(){var a=this;a.setOpt("wordCount",!0),a.addListener("contentchange",function(){a.fireEvent("wordcount")});var b;a.addListener("ready",function(){var a=this;domUtils.on(a.body,"keyup",function(c){var d=c.keyCode||c.which,e={16:1,18:1,20:1,37:1,38:1,39:1,40:1};d in e||(clearTimeout(b),b=setTimeout(function(){a.fireEvent("wordcount")},200))})})},UE.plugins.pagebreak=function(){function a(a){if(domUtils.isEmptyBlock(a)){for(var b,d=a.firstChild;d&&1==d.nodeType&&domUtils.isEmptyBlock(d);)b=d,d=d.firstChild;!b&&(b=a),domUtils.fillNode(c.document,b)}}function b(a){return a&&1==a.nodeType&&"HR"==a.tagName&&"pagebreak"==a.className}var c=this,d=["td"];c.setOpt("pageBreakTag","_ueditor_page_break_tag_"),c.ready(function(){utils.cssRule("pagebreak",".pagebreak{display:block;clear:both !important;cursor:default !important;width: 100% !important;margin:0;}",c.document)}),c.addInputRule(function(a){a.traversal(function(a){if("text"==a.type&&a.data==c.options.pageBreakTag){var b=UE.uNode.createElement('
    ');a.parentNode.insertBefore(b,a),a.parentNode.removeChild(a)}})}),c.addOutputRule(function(a){utils.each(a.getNodesByTagName("hr"),function(a){if("pagebreak"==a.getAttr("class")){var b=UE.uNode.createText(c.options.pageBreakTag);a.parentNode.insertBefore(b,a),a.parentNode.removeChild(a)}})}),c.commands.pagebreak={execCommand:function(){var e=c.selection.getRange(),f=c.document.createElement("hr");domUtils.setAttributes(f,{"class":"pagebreak",noshade:"noshade",size:"5"}),domUtils.unSelectable(f);var g,h=domUtils.findParentByTagName(e.startContainer,d,!0),i=[];if(h)switch(h.tagName){case"TD":if(g=h.parentNode,g.previousSibling)g.parentNode.insertBefore(f,g),i=domUtils.findParents(f);else{var j=domUtils.findParentByTagName(g,"table");j.parentNode.insertBefore(f,j),i=domUtils.findParents(f,!0)}g=i[1],f!==g&&domUtils.breakParent(f,g),c.fireEvent("afteradjusttable",c.document)}else{if(!e.collapsed){e.deleteContents();for(var k=e.startContainer;!domUtils.isBody(k)&&domUtils.isBlockElm(k)&&domUtils.isEmptyNode(k);)e.setStartBefore(k).collapse(!0),domUtils.remove(k),k=e.startContainer}e.insertNode(f);for(var l,g=f.parentNode;!domUtils.isBody(g);)domUtils.breakParent(f,g),l=f.nextSibling,l&&domUtils.isEmptyBlock(l)&&domUtils.remove(l),g=f.parentNode;l=f.nextSibling;var m=f.previousSibling;if(b(m)?domUtils.remove(m):m&&a(m),l)b(l)?domUtils.remove(l):a(l),e.setEndAfter(f).collapse(!1);else{var n=c.document.createElement("p");f.parentNode.appendChild(n),domUtils.fillNode(c.document,n),e.setStart(n,0).collapse(!0)}e.select(!0)}}}},UE.plugin.register("wordimage",function(){var a=this,b=[];return{commands:{wordimage:{execCommand:function(){for(var b,c=domUtils.getElementsByTagName(a.body,"img"),d=[],e=0;b=c[e++];){var f=b.getAttribute("word_img");f&&d.push(f)}return d},queryCommandState:function(){b=domUtils.getElementsByTagName(a.body,"img");for(var c,d=0;c=b[d++];)if(c.getAttribute("word_img"))return 1;return-1},notNeedUndo:!0}},inputRule:function(b){utils.each(b.getNodesByTagName("img"),function(b){var c=b.attrs,d=parseInt(c.width)<128||parseInt(c.height)<43,e=a.options,f=e.UEDITOR_HOME_URL+"themes/default/images/spacer.gif";c.src&&/^(?:(file:\/+))/.test(c.src)&&b.setAttr({width:c.width,height:c.height,alt:c.alt,word_img:c.src,src:f,style:"background:url("+(d?e.themePath+e.theme+"/images/word.gif":e.langPath+e.lang+"/images/localimage.png")+") no-repeat center center;border:1px solid #ddd"})})}}}),UE.plugins.dragdrop=function(){var a=this;a.ready(function(){domUtils.on(this.body,"dragend",function(){var b=a.selection.getRange(),c=b.getClosedNode()||a.selection.getStart();if(c&&"IMG"==c.tagName){for(var d,e=c.previousSibling;(d=c.nextSibling)&&1==d.nodeType&&"SPAN"==d.tagName&&!d.firstChild;)domUtils.remove(d);(!e||1!=e.nodeType||domUtils.isEmptyBlock(e))&&e||d&&(!d||domUtils.isEmptyBlock(d))||(e&&"P"==e.tagName&&!domUtils.isEmptyBlock(e)?(e.appendChild(c),domUtils.moveChild(d,e),domUtils.remove(d)):d&&"P"==d.tagName&&!domUtils.isEmptyBlock(d)&&d.insertBefore(c,d.firstChild),e&&"P"==e.tagName&&domUtils.isEmptyBlock(e)&&domUtils.remove(e),d&&"P"==d.tagName&&domUtils.isEmptyBlock(d)&&domUtils.remove(d),b.selectNode(c).select(),a.fireEvent("saveScene"))}})}),a.addListener("keyup",function(b,c){var d=c.keyCode||c.which;if(13==d){var e,f=a.selection.getRange();(e=domUtils.findParentByTagName(f.startContainer,"p",!0))&&"center"==domUtils.getComputedStyle(e,"text-align")&&domUtils.removeStyle(e,"text-align")}})},UE.plugins.undo=function(){function a(a,b){if(a.length!=b.length)return 0;for(var c=0,d=a.length;cf&&this.list.shift(),this.index=this.list.length-1,this.clearKey(),this.update())},this.update=function(){this.hasRedo=!!this.list[this.index+1],this.hasUndo=!!this.list[this.index-1]},this.reset=function(){this.list=[],this.index=0,this.hasUndo=!1,this.hasRedo=!1,this.clearKey()},this.clearKey=function(){m=0,k=null}}var d,e=this,f=e.options.maxUndoCount||20,g=e.options.maxInputCount||20,h=new RegExp(domUtils.fillChar+"|","gi"),i={ol:1,ul:1,table:1,tbody:1,tr:1,body:1},j=e.options.autoClearEmptyNode;e.undoManger=new c,e.undoManger.editor=e,e.addListener("saveScene",function(){var a=Array.prototype.splice.call(arguments,1);this.undoManger.save.apply(this.undoManger,a)}),e.addListener("reset",function(a,b){b||this.undoManger.reset()}),e.commands.redo=e.commands.undo={execCommand:function(a){this.undoManger[a]()},queryCommandState:function(a){return this.undoManger["has"+("undo"==a.toLowerCase()?"Undo":"Redo")]?0:-1},notNeedUndo:1};var k,l={16:1,17:1,18:1,37:1,38:1,39:1,40:1},m=0,n=!1;e.addListener("ready",function(){domUtils.on(this.body,"compositionstart",function(){n=!0}),domUtils.on(this.body,"compositionend",function(){n=!1})}),e.addshortcutkey({Undo:"ctrl+90",Redo:"ctrl+89"});var o=!0;e.addListener("keydown",function(a,b){function c(a){a.undoManger.save(!1,!0),a.fireEvent("selectionchange")}var e=this,f=b.keyCode||b.which;if(!(l[f]||b.ctrlKey||b.metaKey||b.shiftKey||b.altKey)){if(n)return;if(!e.selection.getRange().collapsed)return e.undoManger.save(!1,!0),void(o=!1);0==e.undoManger.list.length&&e.undoManger.save(!0),clearTimeout(d),d=setTimeout(function(){if(n)var a=setInterval(function(){n||(c(e),clearInterval(a))},300);else c(e)},200),k=f,m++,m>=g&&c(e)}}),e.addListener("keyup",function(a,b){var c=b.keyCode||b.which;if(!(l[c]||b.ctrlKey||b.metaKey||b.shiftKey||b.altKey)){if(n)return;o||(this.undoManger.save(!1,!0),o=!0)}}),e.stopCmdUndo=function(){e.__hasEnterExecCommand=!0},e.startCmdUndo=function(){e.__hasEnterExecCommand=!1}},UE.plugin.register("copy",function(){function a(){ZeroClipboard.config({debug:!1,swfPath:b.options.UEDITOR_HOME_URL+"third-party/zeroclipboard/ZeroClipboard.swf"});var a=b.zeroclipboard=new ZeroClipboard;a.on("copy",function(a){var c=a.client,d=b.selection.getRange(),e=document.createElement("div");e.appendChild(d.cloneContents()),c.setText(e.innerText||e.textContent),c.setHtml(e.innerHTML),d.select()}),a.on("mouseover mouseout",function(a){var b=a.target;"mouseover"==a.type?domUtils.addClass(b,"edui-state-hover"):"mouseout"==a.type&&domUtils.removeClasses(b,"edui-state-hover")}),a.on("wrongflash noflash",function(){ZeroClipboard.destroy()})}var b=this;return{bindEvents:{ready:function(){browser.ie||(window.ZeroClipboard?a():utils.loadFile(document,{src:b.options.UEDITOR_HOME_URL+"third-party/zeroclipboard/ZeroClipboard.js",tag:"script",type:"text/javascript",defer:"defer"},function(){a()}))}},commands:{copy:{execCommand:function(a){b.document.execCommand("copy")||alert(b.getLang("copymsg"))}}}}}),UE.plugins.paste=function(){function a(a){var b=this.document;if(!b.getElementById("baidu_pastebin")){var c=this.selection.getRange(),d=c.createBookmark(),e=b.createElement("div");e.id="baidu_pastebin",browser.webkit&&e.appendChild(b.createTextNode(domUtils.fillChar+domUtils.fillChar)),b.body.appendChild(e),d.start.style.display="",e.style.cssText="position:absolute;width:1px;height:1px;overflow:hidden;left:-1000px;white-space:nowrap;top:"+domUtils.getXY(d.start).y+"px",c.selectNodeContents(e).select(!0),setTimeout(function(){if(browser.webkit)for(var f,g=0,h=b.querySelectorAll("#baidu_pastebin");f=h[g++];){if(!domUtils.isEmptyNode(f)){e=f;break}domUtils.remove(f)}try{e.parentNode.removeChild(e)}catch(i){}c.moveToBookmark(d).select(!0),a(e)},0)}}function b(a){return a.replace(/<(\/?)([\w\-]+)([^>]*)>/gi,function(a,b,c,d){return c=c.toLowerCase(),{img:1}[c]?a:(d=d.replace(/([\w\-]*?)\s*=\s*(("([^"]*)")|('([^']*)')|([^\s>]+))/gi,function(a,b,c){return{src:1,href:1,name:1}[b.toLowerCase()]?b+"="+c+" ":""}),{span:1,div:1}[c]?"":"<"+b+c+" "+utils.trim(d)+">")})}function c(a){var c;if(a.firstChild){for(var h,i=domUtils.getElementsByTagName(a,"span"),j=0;h=i[j++];)"_baidu_cut_start"!=h.id&&"_baidu_cut_end"!=h.id||domUtils.remove(h);if(browser.webkit){for(var k,l=a.querySelectorAll("div br"),j=0;k=l[j++];){var m=k.parentNode;"DIV"==m.tagName&&1==m.childNodes.length&&(m.innerHTML="


    ",domUtils.remove(m))}for(var n,o=a.querySelectorAll("#baidu_pastebin"),j=0;n=o[j++];){var p=d.document.createElement("p");for(n.parentNode.insertBefore(p,n);n.firstChild;)p.appendChild(n.firstChild);domUtils.remove(n)}for(var q,r=a.querySelectorAll("meta"),j=0;q=r[j++];)domUtils.remove(q);var l=a.querySelectorAll("br");for(j=0;q=l[j++];)/^apple-/i.test(q.className)&&domUtils.remove(q)}if(browser.gecko){var s=a.querySelectorAll("[_moz_dirty]");for(j=0;q=s[j++];)q.removeAttribute("_moz_dirty")}if(!browser.ie)for(var q,t=a.querySelectorAll("span.Apple-style-span"),j=0;q=t[j++];)domUtils.remove(q,!0);c=a.innerHTML,c=UE.filterWord(c);var u=UE.htmlparser(c);if(d.options.filterRules&&UE.filterNode(u,d.options.filterRules),d.filterInputRule(u),browser.webkit){var v=u.lastChild();v&&"element"==v.type&&"br"==v.tagName&&u.removeChild(v),utils.each(d.body.querySelectorAll("div"),function(a){domUtils.isEmptyBlock(a)&&domUtils.remove(a,!0)})}if(c={html:u.toHtml()},d.fireEvent("beforepaste",c,u),!c.html)return;u=UE.htmlparser(c.html,!0),1===d.queryCommandState("pasteplain")?d.execCommand("insertHtml",UE.filterNode(u,d.options.filterTxtRules).toHtml(),!0):(UE.filterNode(u,d.options.filterTxtRules),e=u.toHtml(),f=c.html,g=d.selection.getRange().createAddress(!0),d.execCommand("insertHtml",d.getOpt("retainOnlyLabelPasted")===!0?b(f):f,!0)),d.fireEvent("afterpaste",c)}}var d=this;d.setOpt({retainOnlyLabelPasted:!1});var e,f,g;d.addListener("pasteTransfer",function(a,c){if(g&&e&&f&&e!=f){var h=d.selection.getRange();if(h.moveToAddress(g,!0),!h.collapsed){for(;!domUtils.isBody(h.startContainer);){var i=h.startContainer;if(1==i.nodeType){if(i=i.childNodes[h.startOffset],!i){h.setStartBefore(h.startContainer);continue}var j=i.previousSibling;j&&3==j.nodeType&&new RegExp("^[\n\r\t "+domUtils.fillChar+"]*$").test(j.nodeValue)&&h.setStartBefore(j)}if(0!=h.startOffset)break;h.setStartBefore(h.startContainer)}for(;!domUtils.isBody(h.endContainer);){var k=h.endContainer;if(1==k.nodeType){if(k=k.childNodes[h.endOffset],!k){h.setEndAfter(h.endContainer);continue}var l=k.nextSibling;l&&3==l.nodeType&&new RegExp("^[\n\r\t"+domUtils.fillChar+"]*$").test(l.nodeValue)&&h.setEndAfter(l)}if(h.endOffset!=h.endContainer[3==h.endContainer.nodeType?"nodeValue":"childNodes"].length)break;h.setEndAfter(h.endContainer)}}h.deleteContents(),h.select(!0),d.__hasEnterExecCommand=!0;var m=f;2===c?m=b(m):c&&(m=e),d.execCommand("inserthtml",m,!0),d.__hasEnterExecCommand=!1;for(var n=d.selection.getRange();!domUtils.isBody(n.startContainer)&&!n.startOffset&&n.startContainer[3==n.startContainer.nodeType?"nodeValue":"childNodes"].length;)n.setStartBefore(n.startContainer);var o=n.createAddress(!0);g.endAddress=o.startAddress}}),d.addListener("ready",function(){domUtils.on(d.body,"cut",function(){var a=d.selection.getRange();!a.collapsed&&d.undoManger&&d.undoManger.save()}),domUtils.on(d.body,browser.ie||browser.opera?"keydown":"paste",function(b){(!browser.ie&&!browser.opera||(b.ctrlKey||b.metaKey)&&"86"==b.keyCode)&&a.call(d,function(a){c(a)})})}),d.commands.paste={execCommand:function(b){browser.ie?(a.call(d,function(a){c(a)}),d.document.execCommand("paste")):alert(d.getLang("pastemsg"))}}},UE.plugins.pasteplain=function(){var a=this;a.setOpt({pasteplain:!1,filterTxtRules:function(){function a(a){a.tagName="p",a.setStyle()}function b(a){a.parentNode.removeChild(a,!0)}return{"-":"script style object iframe embed input select",p:{$:{}},br:{$:{}},div:function(a){for(var b,c=UE.uNode.createElement("p");b=a.firstChild();)"text"!=b.type&&UE.dom.dtd.$block[b.tagName]?c.firstChild()?(a.parentNode.insertBefore(c,a),c=UE.uNode.createElement("p")):a.parentNode.insertBefore(b,a):c.appendChild(b);c.firstChild()&&a.parentNode.insertBefore(c,a),a.parentNode.removeChild(a)},ol:b,ul:b,dl:b,dt:b,dd:b,li:b,caption:a,th:a,tr:a,h1:a,h2:a,h3:a,h4:a,h5:a,h6:a,td:function(a){var b=!!a.innerText();b&&a.parentNode.insertAfter(UE.uNode.createText("    "),a),a.parentNode.removeChild(a,a.innerText())}}}()});var b=a.options.pasteplain;a.commands.pasteplain={queryCommandState:function(){return b?1:0},execCommand:function(){b=0|!b},notNeedUndo:1}},UE.plugins.list=function(){function a(a){var b=[];for(var c in a)b.push(c);return b}function b(a){var b=a.className;return domUtils.hasClass(a,/custom_/)?b.match(/custom_(\w+)/)[1]:domUtils.getStyle(a,"list-style-type")}function c(a,c){utils.each(domUtils.getElementsByTagName(a,"ol ul"),function(f){if(domUtils.inDoc(f,a)){var g=f.parentNode;if(g.tagName==f.tagName){var h=b(f)||("OL"==f.tagName?"decimal":"disc"),i=b(g)||("OL"==g.tagName?"decimal":"disc");if(h==i){var l=utils.indexOf(k[f.tagName],h);l=l+1==k[f.tagName].length?0:l+1,e(f,k[f.tagName][l])}}var m=0,n=2;domUtils.hasClass(f,/custom_/)?/[ou]l/i.test(g.tagName)&&domUtils.hasClass(g,/custom_/)||(n=1):/[ou]l/i.test(g.tagName)&&domUtils.hasClass(g,/custom_/)&&(n=3);var o=domUtils.getStyle(f,"list-style-type");o&&(f.style.cssText="list-style-type:"+o),f.className=utils.trim(f.className.replace(/list-paddingleft-\w+/,""))+" list-paddingleft-"+n,utils.each(domUtils.getElementsByTagName(f,"li"),function(a){if(a.style.cssText&&(a.style.cssText=""),!a.firstChild)return void domUtils.remove(a);if(a.parentNode===f){if(m++,domUtils.hasClass(f,/custom_/)){var c=1,d=b(f);if("OL"==f.tagName){if(d)switch(d){case"cn":case"cn1":case"cn2":m>10&&(m%10==0||m>10&&m<20)?c=2:m>20&&(c=3);break;case"num2":m>9&&(c=2)}a.className="list-"+j[d]+m+" list-"+d+"-paddingleft-"+c}else a.className="list-"+j[d]+" list-"+d+"-paddingleft"}else a.className=a.className.replace(/list-[\w\-]+/gi,"");var e=a.getAttribute("class");null===e||e.replace(/\s/g,"")||domUtils.removeAttributes(a,"class")}}),!c&&d(f,f.tagName.toLowerCase(),b(f)||domUtils.getStyle(f,"list-style-type"),!0)}})}function d(a,d,e,f){var g=a.nextSibling;g&&1==g.nodeType&&g.tagName.toLowerCase()==d&&(b(g)||domUtils.getStyle(g,"list-style-type")||("ol"==d?"decimal":"disc"))==e&&(domUtils.moveChild(g,a),0==g.childNodes.length&&domUtils.remove(g)),g&&domUtils.isFillChar(g)&&domUtils.remove(g);var h=a.previousSibling;h&&1==h.nodeType&&h.tagName.toLowerCase()==d&&(b(h)||domUtils.getStyle(h,"list-style-type")||("ol"==d?"decimal":"disc"))==e&&domUtils.moveChild(a,h),h&&domUtils.isFillChar(h)&&domUtils.remove(h),!f&&domUtils.isEmptyBlock(a)&&domUtils.remove(a),b(a)&&c(a.ownerDocument,!0)}function e(a,b){j[b]&&(a.className="custom_"+b);try{domUtils.setStyle(a,"list-style-type",b)}catch(c){}}function f(a){var b=a.previousSibling;b&&domUtils.isEmptyBlock(b)&&domUtils.remove(b),b=a.nextSibling,b&&domUtils.isEmptyBlock(b)&&domUtils.remove(b)}function g(a){for(;a&&!domUtils.isBody(a);){if("TABLE"==a.nodeName)return null;if("LI"==a.nodeName)return a;a=a.parentNode}}var h=this,i={TD:1,PRE:1,BLOCKQUOTE:1},j={cn:"cn-1-",cn1:"cn-2-",cn2:"cn-3-",num:"num-1-",num1:"num-2-",num2:"num-3-",dash:"dash",dot:"dot"};h.setOpt({autoTransWordToList:!1,insertorderedlist:{num:"",num1:"",num2:"",cn:"",cn1:"",cn2:"",decimal:"","lower-alpha":"","lower-roman":"","upper-alpha":"","upper-roman":""},insertunorderedlist:{circle:"",disc:"",square:"",dash:"",dot:""},listDefaultPaddingLeft:"30",listiconpath:"http://bs.baidu.com/listicon/",maxListLevel:-1,disablePInList:!1});var k={OL:a(h.options.insertorderedlist),UL:a(h.options.insertunorderedlist)},l=h.options.listiconpath;for(var m in j)h.options.insertorderedlist.hasOwnProperty(m)||h.options.insertunorderedlist.hasOwnProperty(m)||delete j[m];h.ready(function(){var a=[];for(var b in j){if("dash"==b||"dot"==b)a.push("li.list-"+j[b]+"{background-image:url("+l+j[b]+".gif)}"),a.push("ul.custom_"+b+"{list-style:none;}ul.custom_"+b+" li{background-position:0 3px;background-repeat:no-repeat}");else{for(var c=0;c<99;c++)a.push("li.list-"+j[b]+c+"{background-image:url("+l+"list-"+j[b]+c+".gif)}");a.push("ol.custom_"+b+"{list-style:none;}ol.custom_"+b+" li{background-position:0 3px;background-repeat:no-repeat}")}switch(b){case"cn":a.push("li.list-"+b+"-paddingleft-1{padding-left:25px}"),a.push("li.list-"+b+"-paddingleft-2{padding-left:40px}"),a.push("li.list-"+b+"-paddingleft-3{padding-left:55px}");break;case"cn1":a.push("li.list-"+b+"-paddingleft-1{padding-left:30px}"),a.push("li.list-"+b+"-paddingleft-2{padding-left:40px}"),a.push("li.list-"+b+"-paddingleft-3{padding-left:55px}");break;case"cn2":a.push("li.list-"+b+"-paddingleft-1{padding-left:40px}"),a.push("li.list-"+b+"-paddingleft-2{padding-left:55px}"),a.push("li.list-"+b+"-paddingleft-3{padding-left:68px}");break;case"num":case"num1":a.push("li.list-"+b+"-paddingleft-1{padding-left:25px}");break;case"num2":a.push("li.list-"+b+"-paddingleft-1{padding-left:35px}"),a.push("li.list-"+b+"-paddingleft-2{padding-left:40px}");break;case"dash":a.push("li.list-"+b+"-paddingleft{padding-left:35px}");break;case"dot":a.push("li.list-"+b+"-paddingleft{padding-left:20px}")}}a.push(".list-paddingleft-1{padding-left:0}"),a.push(".list-paddingleft-2{padding-left:"+h.options.listDefaultPaddingLeft+"px}"),a.push(".list-paddingleft-3{padding-left:"+2*h.options.listDefaultPaddingLeft+"px}"),utils.cssRule("list","ol,ul{margin:0;pading:0;"+(browser.ie?"":"width:95%")+"}li{clear:both;}"+a.join("\n"),h.document)}),h.ready(function(){domUtils.on(h.body,"cut",function(){setTimeout(function(){var a,b=h.selection.getRange();if(!b.collapsed&&(a=domUtils.findParentByTagName(b.startContainer,"li",!0))&&!a.nextSibling&&domUtils.isEmptyBlock(a)){var c,d=a.parentNode;if(c=d.previousSibling)domUtils.remove(d),b.setStartAtLast(c).collapse(!0),b.select(!0);else if(c=d.nextSibling)domUtils.remove(d),b.setStartAtFirst(c).collapse(!0),b.select(!0);else{var e=h.document.createElement("p");domUtils.fillNode(h.document,e),d.parentNode.insertBefore(e,d),domUtils.remove(d),b.setStart(e,0).collapse(!0),b.select(!0)}}})})}),h.addListener("beforepaste",function(a,c){var d,e=this,f=e.selection.getRange(),g=UE.htmlparser(c.html,!0);if(d=domUtils.findParentByTagName(f.startContainer,"li",!0)){var h=d.parentNode,i="OL"==h.tagName?"ul":"ol";utils.each(g.getNodesByTagName(i),function(c){if(c.tagName=h.tagName,c.setAttr(),c.parentNode===g)a=b(h)||("OL"==h.tagName?"decimal":"disc");else{var d=c.parentNode.getAttr("class");a=d&&/custom_/.test(d)?d.match(/custom_(\w+)/)[1]:c.parentNode.getStyle("list-style-type"),a||(a="OL"==h.tagName?"decimal":"disc")}var e=utils.indexOf(k[h.tagName],a);c.parentNode!==g&&(e=e+1==k[h.tagName].length?0:e+1);var f=k[h.tagName][e];j[f]?c.setAttr("class","custom_"+f):c.setStyle("list-style-type",f)})}c.html=g.toHtml()}),h.getOpt("disablePInList")===!0&&h.addOutputRule(function(a){utils.each(a.getNodesByTagName("li"),function(a){var b=[],c=0;utils.each(a.children,function(d){if("p"==d.tagName){for(var e;e=d.children.pop();)b.splice(c,0,e),e.parentNode=a,lastNode=e;if(e=b[b.length-1],!e||"element"!=e.type||"br"!=e.tagName){var f=UE.uNode.createElement("br");f.parentNode=a,b.push(f)}c=b.length}}),b.length&&(a.children=b)})}),h.addInputRule(function(a){function b(a,b){var e=b.firstChild();if(e&&"element"==e.type&&"span"==e.tagName&&/Wingdings|Symbol/.test(e.getStyle("font-family"))){for(var f in d)if(d[f]==e.data)return f;return"disc"}for(var f in c)if(c[f].test(a))return f}if(utils.each(a.getNodesByTagName("li"),function(a){for(var b,c=UE.uNode.createElement("p"),d=0;b=a.children[d];)"text"==b.type||dtd.p[b.tagName]?c.appendChild(b):c.firstChild()?(a.insertBefore(c,b),c=UE.uNode.createElement("p"),d+=2):d++;(c.firstChild()&&!c.parentNode||!a.firstChild())&&a.appendChild(c),c.firstChild()||c.innerHTML(browser.ie?" ":"
    ");var e=a.firstChild(),f=e.lastChild();f&&"text"==f.type&&/^\s*$/.test(f.data)&&e.removeChild(f)}),h.options.autoTransWordToList){var c={num1:/^\d+\)/,decimal:/^\d+\./,"lower-alpha":/^[a-z]+\)/,"upper-alpha":/^[A-Z]+\./,cn:/^[\u4E00\u4E8C\u4E09\u56DB\u516d\u4e94\u4e03\u516b\u4e5d]+[\u3001]/,cn2:/^\([\u4E00\u4E8C\u4E09\u56DB\u516d\u4e94\u4e03\u516b\u4e5d]+\)/},d={square:"n"};utils.each(a.getNodesByTagName("p"),function(a){function d(a,b,d){if("ol"==a.tagName)if(browser.ie){var e=b.firstChild();"element"==e.type&&"span"==e.tagName&&c[d].test(e.innerText())&&b.removeChild(e)}else b.innerHTML(b.innerHTML().replace(c[d],""));else b.removeChild(b.firstChild());var f=UE.uNode.createElement("li");f.appendChild(b),a.appendChild(f)}if("MsoListParagraph"==a.getAttr("class")){a.setStyle("margin",""),a.setStyle("margin-left",""),a.setAttr("class","");var e,f=a,g=a;if("li"!=a.parentNode.tagName&&(e=b(a.innerText(),a))){var i=UE.uNode.createElement(h.options.insertorderedlist.hasOwnProperty(e)?"ol":"ul");for(j[e]?i.setAttr("class","custom_"+e):i.setStyle("list-style-type",e);a&&"li"!=a.parentNode.tagName&&b(a.innerText(),a);)f=a.nextSibling(),f||a.parentNode.insertBefore(i,a),d(i,a,e),a=f;!i.parentNode&&a&&a.parentNode&&a.parentNode.insertBefore(i,a)}var k=g.firstChild();k&&"element"==k.type&&"span"==k.tagName&&/^\s*( )+\s*$/.test(k.innerText())&&k.parentNode.removeChild(k)}})}}),h.addListener("contentchange",function(){c(h.document)}),h.addListener("keydown",function(a,b){function c(){b.preventDefault?b.preventDefault():b.returnValue=!1,h.fireEvent("contentchange"),h.undoManger&&h.undoManger.save()}function d(a,b){for(;a&&!domUtils.isBody(a);){if(b(a))return null;if(1==a.nodeType&&/[ou]l/i.test(a.tagName))return a;a=a.parentNode}return null}var e=b.keyCode||b.which;if(13==e&&!b.shiftKey){var g=h.selection.getRange(),i=domUtils.findParent(g.startContainer,function(a){return domUtils.isBlockElm(a)},!0),j=domUtils.findParentByTagName(g.startContainer,"li",!0);if(i&&"PRE"!=i.tagName&&!j){var k=i.innerHTML.replace(new RegExp(domUtils.fillChar,"g"),"");/^\s*1\s*\.[^\d]/.test(k)&&(i.innerHTML=k.replace(/^\s*1\s*\./,""),g.setStartAtLast(i).collapse(!0).select(),h.__hasEnterExecCommand=!0,h.execCommand("insertorderedlist"),h.__hasEnterExecCommand=!1)}var l=h.selection.getRange(),m=d(l.startContainer,function(a){return"TABLE"==a.tagName}),n=l.collapsed?m:d(l.endContainer,function(a){return"TABLE"==a.tagName});if(m&&n&&m===n){if(!l.collapsed){if(m=domUtils.findParentByTagName(l.startContainer,"li",!0),n=domUtils.findParentByTagName(l.endContainer,"li",!0),!m||!n||m!==n){var o=l.cloneRange(),p=o.collapse(!1).createBookmark();l.deleteContents(),o.moveToBookmark(p);var j=domUtils.findParentByTagName(o.startContainer,"li",!0);return f(j),o.select(),void c()}if(l.deleteContents(),j=domUtils.findParentByTagName(l.startContainer,"li",!0),j&&domUtils.isEmptyBlock(j))return v=j.previousSibling,next=j.nextSibling,s=h.document.createElement("p"),domUtils.fillNode(h.document,s),q=j.parentNode,v&&next?(l.setStart(next,0).collapse(!0).select(!0),domUtils.remove(j)):((v||next)&&v?j.parentNode.parentNode.insertBefore(s,q.nextSibling):q.parentNode.insertBefore(s,q),domUtils.remove(j),q.firstChild||domUtils.remove(q),l.setStart(s,0).setCursor()),void c()}if(j=domUtils.findParentByTagName(l.startContainer,"li",!0)){ -if(domUtils.isEmptyBlock(j)){p=l.createBookmark();var q=j.parentNode;if(j!==q.lastChild?(domUtils.breakParent(j,q),f(j)):(q.parentNode.insertBefore(j,q.nextSibling),domUtils.isEmptyNode(q)&&domUtils.remove(q)),!dtd.$list[j.parentNode.tagName])if(domUtils.isBlockElm(j.firstChild))domUtils.remove(j,!0);else{for(s=h.document.createElement("p"),j.parentNode.insertBefore(s,j);j.firstChild;)s.appendChild(j.firstChild);domUtils.remove(j)}l.moveToBookmark(p).select()}else{var r=j.firstChild;if(!r||!domUtils.isBlockElm(r)){var s=h.document.createElement("p");for(!j.firstChild&&domUtils.fillNode(h.document,s);j.firstChild;)s.appendChild(j.firstChild);j.appendChild(s),r=s}var t=h.document.createElement("span");l.insertNode(t),domUtils.breakParent(t,j);var u=t.nextSibling;r=u.firstChild,r||(s=h.document.createElement("p"),domUtils.fillNode(h.document,s),u.appendChild(s),r=s),domUtils.isEmptyNode(r)&&(r.innerHTML="",domUtils.fillNode(h.document,r)),l.setStart(r,0).collapse(!0).shrinkBoundary().select(),domUtils.remove(t);var v=u.previousSibling;v&&domUtils.isEmptyBlock(v)&&(v.innerHTML="

    ",domUtils.fillNode(h.document,v.firstChild))}c()}}}if(8==e&&(l=h.selection.getRange(),l.collapsed&&domUtils.isStartInblock(l)&&(o=l.cloneRange().trimBoundary(),j=domUtils.findParentByTagName(l.startContainer,"li",!0),j&&domUtils.isStartInblock(o)))){if(m=domUtils.findParentByTagName(l.startContainer,"p",!0),m&&m!==j.firstChild){var q=domUtils.findParentByTagName(m,["ol","ul"]);return domUtils.breakParent(m,q),f(m),h.fireEvent("contentchange"),l.setStart(m,0).setCursor(!1,!0),h.fireEvent("saveScene"),void domUtils.preventDefault(b)}if(j&&(v=j.previousSibling)){if(46==e&&j.childNodes.length)return;if(dtd.$list[v.tagName]&&(v=v.lastChild),h.undoManger&&h.undoManger.save(),r=j.firstChild,domUtils.isBlockElm(r))if(domUtils.isEmptyNode(r))for(v.appendChild(r),l.setStart(r,0).setCursor(!1,!0);j.firstChild;)v.appendChild(j.firstChild);else t=h.document.createElement("span"),l.insertNode(t),domUtils.isEmptyBlock(v)&&(v.innerHTML=""),domUtils.moveChild(j,v),l.setStartBefore(t).collapse(!0).select(!0),domUtils.remove(t);else if(domUtils.isEmptyNode(j)){var s=h.document.createElement("p");v.appendChild(s),l.setStart(s,0).setCursor()}else for(l.setEnd(v,v.childNodes.length).collapse().select(!0);j.firstChild;)v.appendChild(j.firstChild);return domUtils.remove(j),h.fireEvent("contentchange"),h.fireEvent("saveScene"),void domUtils.preventDefault(b)}if(j&&!j.previousSibling){var q=j.parentNode,p=l.createBookmark();if(domUtils.isTagNode(q.parentNode,"ol ul"))q.parentNode.insertBefore(j,q),domUtils.isEmptyNode(q)&&domUtils.remove(q);else{for(;j.firstChild;)q.parentNode.insertBefore(j.firstChild,q);domUtils.remove(j),domUtils.isEmptyNode(q)&&domUtils.remove(q)}return l.moveToBookmark(p).setCursor(!1,!0),h.fireEvent("contentchange"),h.fireEvent("saveScene"),void domUtils.preventDefault(b)}}}),h.addListener("keyup",function(a,c){var e=c.keyCode||c.which;if(8==e){var f,g=h.selection.getRange();(f=domUtils.findParentByTagName(g.startContainer,["ol","ul"],!0))&&d(f,f.tagName.toLowerCase(),b(f)||domUtils.getComputedStyle(f,"list-style-type"),!0)}}),h.addListener("tabkeydown",function(){function a(a){if(h.options.maxListLevel!=-1){for(var b=a.parentNode,c=0;/[ou]l/i.test(b.tagName);)c++,b=b.parentNode;if(c>=h.options.maxListLevel)return!0}}var c=h.selection.getRange(),f=domUtils.findParentByTagName(c.startContainer,"li",!0);if(f){var g;if(!c.collapsed){h.fireEvent("saveScene"),g=c.createBookmark();for(var i,j,l=0,m=domUtils.findParents(f);j=m[l++];)if(domUtils.isTagNode(j,"ol ul")){i=j;break}var n=f;if(g.end)for(;n&&!(domUtils.getPosition(n,g.end)&domUtils.POSITION_FOLLOWING);)if(a(n))n=domUtils.getNextDomNode(n,!1,null,function(a){return a!==i});else{var o=n.parentNode,p=h.document.createElement(o.tagName),q=utils.indexOf(k[p.tagName],b(o)||domUtils.getComputedStyle(o,"list-style-type")),r=q+1==k[p.tagName].length?0:q+1,s=k[p.tagName][r];for(e(p,s),o.insertBefore(p,n);n&&!(domUtils.getPosition(n,g.end)&domUtils.POSITION_FOLLOWING);){if(f=n.nextSibling,p.appendChild(n),!f||domUtils.isTagNode(f,"ol ul")){if(f)for(;(f=f.firstChild)&&"LI"!=f.tagName;);else f=domUtils.getNextDomNode(n,!1,null,function(a){return a!==i});break}n=f}d(p,p.tagName.toLowerCase(),s),n=f}return h.fireEvent("contentchange"),c.moveToBookmark(g).select(),!0}if(a(f))return!0;var o=f.parentNode,p=h.document.createElement(o.tagName),q=utils.indexOf(k[p.tagName],b(o)||domUtils.getComputedStyle(o,"list-style-type"));q=q+1==k[p.tagName].length?0:q+1;var s=k[p.tagName][q];if(e(p,s),domUtils.isStartInblock(c))return h.fireEvent("saveScene"),g=c.createBookmark(),o.insertBefore(p,f),p.appendChild(f),d(p,p.tagName.toLowerCase(),s),h.fireEvent("contentchange"),c.moveToBookmark(g).select(!0),!0}}),h.commands.insertorderedlist=h.commands.insertunorderedlist={execCommand:function(a,c){c||(c="insertorderedlist"==a.toLowerCase()?"decimal":"disc");var f=this,h=this.selection.getRange(),j=function(a){return 1==a.nodeType?"br"!=a.tagName.toLowerCase():!domUtils.isWhitespace(a)},k="insertorderedlist"==a.toLowerCase()?"ol":"ul",l=f.document.createDocumentFragment();h.adjustmentBoundary().shrinkBoundary();var m,n,o,p,q=h.createBookmark(!0),r=g(f.document.getElementById(q.start)),s=0,t=g(f.document.getElementById(q.end)),u=0;if(r||t){if(r&&(m=r.parentNode),q.end||(t=r),t&&(n=t.parentNode),m===n){for(;r!==t;){if(p=r,r=r.nextSibling,!domUtils.isBlockElm(p.firstChild)){for(var v=f.document.createElement("p");p.firstChild;)v.appendChild(p.firstChild);p.appendChild(v)}l.appendChild(p)}if(p=f.document.createElement("span"),m.insertBefore(p,t),!domUtils.isBlockElm(t.firstChild)){for(v=f.document.createElement("p");t.firstChild;)v.appendChild(t.firstChild);t.appendChild(v)}l.appendChild(t),domUtils.breakParent(p,m),domUtils.isEmptyNode(p.previousSibling)&&domUtils.remove(p.previousSibling),domUtils.isEmptyNode(p.nextSibling)&&domUtils.remove(p.nextSibling);var w=b(m)||domUtils.getComputedStyle(m,"list-style-type")||("insertorderedlist"==a.toLowerCase()?"decimal":"disc");if(m.tagName.toLowerCase()==k&&w==c){for(var x,y=0,z=f.document.createDocumentFragment();x=l.firstChild;)if(domUtils.isTagNode(x,"ol ul"))z.appendChild(x);else for(;x.firstChild;)z.appendChild(x.firstChild),domUtils.remove(x);p.parentNode.insertBefore(z,p)}else o=f.document.createElement(k),e(o,c),o.appendChild(l),p.parentNode.insertBefore(o,p);return domUtils.remove(p),o&&d(o,k,c),void h.moveToBookmark(q).select()}if(r){for(;r;){if(p=r.nextSibling,domUtils.isTagNode(r,"ol ul"))l.appendChild(r);else{for(var A=f.document.createDocumentFragment(),B=0;r.firstChild;)domUtils.isBlockElm(r.firstChild)&&(B=1),A.appendChild(r.firstChild);if(B)l.appendChild(A);else{var C=f.document.createElement("p");C.appendChild(A),l.appendChild(C)}domUtils.remove(r)}r=p}m.parentNode.insertBefore(l,m.nextSibling),domUtils.isEmptyNode(m)?(h.setStartBefore(m),domUtils.remove(m)):h.setStartAfter(m),s=1}if(t&&domUtils.inDoc(n,f.document)){for(r=n.firstChild;r&&r!==t;){if(p=r.nextSibling,domUtils.isTagNode(r,"ol ul"))l.appendChild(r);else{for(A=f.document.createDocumentFragment(),B=0;r.firstChild;)domUtils.isBlockElm(r.firstChild)&&(B=1),A.appendChild(r.firstChild);B?l.appendChild(A):(C=f.document.createElement("p"),C.appendChild(A),l.appendChild(C)),domUtils.remove(r)}r=p}var D=domUtils.createElement(f.document,"div",{tmpDiv:1});domUtils.moveChild(t,D),l.appendChild(D),domUtils.remove(t),n.parentNode.insertBefore(l,n),h.setEndBefore(n),domUtils.isEmptyNode(n)&&domUtils.remove(n),u=1}}s||h.setStartBefore(f.document.getElementById(q.start)),q.end&&!u&&h.setEndAfter(f.document.getElementById(q.end)),h.enlarge(!0,function(a){return i[a.tagName]}),l=f.document.createDocumentFragment();for(var E,F=h.createBookmark(),G=domUtils.getNextDomNode(F.start,!1,j),H=h.cloneRange(),I=domUtils.isBlockElm;G&&G!==F.end&&domUtils.getPosition(G,F.end)&domUtils.POSITION_PRECEDING;)if(3==G.nodeType||dtd.li[G.tagName]){if(1==G.nodeType&&dtd.$list[G.tagName]){for(;G.firstChild;)l.appendChild(G.firstChild);E=domUtils.getNextDomNode(G,!1,j),domUtils.remove(G),G=E;continue}for(E=G,H.setStartBefore(G);G&&G!==F.end&&(!I(G)||domUtils.isBookmarkNode(G));)E=G,G=domUtils.getNextDomNode(G,!1,null,function(a){return!i[a.tagName]});G&&I(G)&&(p=domUtils.getNextDomNode(E,!1,j),p&&domUtils.isBookmarkNode(p)&&(G=domUtils.getNextDomNode(p,!1,j),E=p)),H.setEndAfter(E),G=domUtils.getNextDomNode(E,!1,j);var J=h.document.createElement("li");if(J.appendChild(H.extractContents()),domUtils.isEmptyNode(J)){for(var E=h.document.createElement("p");J.firstChild;)E.appendChild(J.firstChild);J.appendChild(E)}l.appendChild(J)}else G=domUtils.getNextDomNode(G,!0,j);h.moveToBookmark(F).collapse(!0),o=f.document.createElement(k),e(o,c),o.appendChild(l),h.insertNode(o),d(o,k,c);for(var x,y=0,K=domUtils.getElementsByTagName(o,"div");x=K[y++];)x.getAttribute("tmpDiv")&&domUtils.remove(x,!0);h.moveToBookmark(q).select()},queryCommandState:function(a){for(var b,c="insertorderedlist"==a.toLowerCase()?"ol":"ul",d=this.selection.getStartElementPath(),e=0;b=d[e++];){if("TABLE"==b.nodeName)return 0;if(c==b.nodeName.toLowerCase())return 1}return 0},queryCommandValue:function(a){for(var c,d,e="insertorderedlist"==a.toLowerCase()?"ol":"ul",f=this.selection.getStartElementPath(),g=0;d=f[g++];){if("TABLE"==d.nodeName){c=null;break}if(e==d.nodeName.toLowerCase()){c=d;break}}return c?b(c)||domUtils.getComputedStyle(c,"list-style-type"):null}}},function(){var a={textarea:function(a,b){var c=b.ownerDocument.createElement("textarea");return c.style.cssText="position:absolute;resize:none;width:100%;height:100%;border:0;padding:0;margin:0;overflow-y:auto;",browser.ie&&browser.version<8&&(c.style.width=b.offsetWidth+"px",c.style.height=b.offsetHeight+"px",b.onresize=function(){c.style.width=b.offsetWidth+"px",c.style.height=b.offsetHeight+"px"}),b.appendChild(c),{setContent:function(a){c.value=a},getContent:function(){return c.value},select:function(){var a;browser.ie?(a=c.createTextRange(),a.collapse(!0),a.select()):(c.setSelectionRange(0,0),c.focus())},dispose:function(){b.removeChild(c),b.onresize=null,c=null,b=null}}},codemirror:function(a,b){var c=window.CodeMirror(b,{mode:"text/html",tabMode:"indent",lineNumbers:!0,lineWrapping:!0}),d=c.getWrapperElement();return d.style.cssText='position:absolute;left:0;top:0;width:100%;height:100%;font-family:consolas,"Courier new",monospace;font-size:13px;',c.getScrollerElement().style.cssText="position:absolute;left:0;top:0;width:100%;height:100%;",c.refresh(),{getCodeMirror:function(){return c},setContent:function(a){c.setValue(a)},getContent:function(){return c.getValue()},select:function(){c.focus()},dispose:function(){b.removeChild(d),d=null,c=null}}}};UE.plugins.source=function(){function b(b){return a["codemirror"==f.sourceEditor&&window.CodeMirror?"codemirror":"textarea"](e,b)}var c,d,e=this,f=this.options,g=!1;f.sourceEditor=browser.ie?"textarea":f.sourceEditor||"codemirror",e.setOpt({sourceEditorFirst:!1});var h,i,j;e.commands.source={execCommand:function(){if(g=!g){j=e.selection.getRange().createAddress(!1,!0),e.undoManger&&e.undoManger.save(!0),browser.gecko&&(e.body.contentEditable=!1),h=e.iframe.style.cssText,e.iframe.style.cssText+="position:absolute;left:-32768px;top:-32768px;",e.fireEvent("beforegetcontent");var a=UE.htmlparser(e.body.innerHTML);e.filterOutputRule(a),a.traversal(function(a){if("element"==a.type)switch(a.tagName){case"td":case"th":case"caption":a.children&&1==a.children.length&&"br"==a.firstChild().tagName&&a.removeChild(a.firstChild());break;case"pre":a.innerText(a.innerText().replace(/ /g," "))}}),e.fireEvent("aftergetcontent");var f=a.toHtml(!0);c=b(e.iframe.parentNode),c.setContent(f),d=e.setContent,e.setContent=function(a){var b=UE.htmlparser(a);e.filterInputRule(b),a=b.toHtml(),c.setContent(a)},setTimeout(function(){c.select(),e.addListener("fullscreenchanged",function(){try{c.getCodeMirror().refresh()}catch(a){}})}),i=e.getContent,e.getContent=function(){return c.getContent()||"

    "+(browser.ie?"":"
    ")+"

    "}}else{e.iframe.style.cssText=h;var k=c.getContent()||"

    "+(browser.ie?"":"
    ")+"

    ";k=k.replace(new RegExp("[\\r\\t\\n ]*]*)>","g"),function(a,b){return b&&!dtd.$inlineWithA[b.toLowerCase()]?a.replace(/(^[\n\r\t ]*)|([\n\r\t ]*$)/g,""):a.replace(/(^[\n\r\t]*)|([\n\r\t]*$)/g,"")}),e.setContent=d,e.setContent(k),c.dispose(),c=null,e.getContent=i;var l=e.body.firstChild;if(l||(e.body.innerHTML="

    "+(browser.ie?"":"
    ")+"

    ",l=e.body.firstChild),e.undoManger&&e.undoManger.save(!0),browser.gecko){var m=document.createElement("input");m.style.cssText="position:absolute;left:0;top:-32768px",document.body.appendChild(m),e.body.contentEditable=!1,setTimeout(function(){domUtils.setViewportOffset(m,{left:-32768,top:0}),m.focus(),setTimeout(function(){e.body.contentEditable=!0,e.selection.getRange().moveToAddress(j).select(!0),domUtils.remove(m)})})}else try{e.selection.getRange().moveToAddress(j).select(!0)}catch(n){}}this.fireEvent("sourcemodechanged",g)},queryCommandState:function(){return 0|g},notNeedUndo:1};var k=e.queryCommandState;e.queryCommandState=function(a){return a=a.toLowerCase(),g?a in{source:1,fullscreen:1}?1:-1:k.apply(this,arguments)},"codemirror"==f.sourceEditor&&e.addListener("ready",function(){utils.loadFile(document,{src:f.codeMirrorJsUrl||f.UEDITOR_HOME_URL+"third-party/codemirror/codemirror.js",tag:"script",type:"text/javascript",defer:"defer"},function(){f.sourceEditorFirst&&setTimeout(function(){e.execCommand("source")},0)}),utils.loadFile(document,{tag:"link",rel:"stylesheet",type:"text/css",href:f.codeMirrorCssUrl||f.UEDITOR_HOME_URL+"third-party/codemirror/codemirror.css"})})}}(),UE.plugins.enterkey=function(){var a,b=this,c=b.options.enterTag;b.addListener("keyup",function(c,d){var e=d.keyCode||d.which;if(13==e){var f,g=b.selection.getRange(),h=g.startContainer;if(browser.ie)b.fireEvent("saveScene",!0,!0);else{if(/h\d/i.test(a)){if(browser.gecko){var i=domUtils.findParentByTagName(h,["h1","h2","h3","h4","h5","h6","blockquote","caption","table"],!0);i||(b.document.execCommand("formatBlock",!1,"

    "),f=1)}else if(1==h.nodeType){var j,k=b.document.createTextNode("");if(g.insertNode(k),j=domUtils.findParentByTagName(k,"div",!0)){for(var l=b.document.createElement("p");j.firstChild;)l.appendChild(j.firstChild);j.parentNode.insertBefore(l,j),domUtils.remove(j),g.setStartBefore(k).setCursor(),f=1}domUtils.remove(k)}b.undoManger&&f&&b.undoManger.save()}browser.opera&&g.select()}}}),b.addListener("keydown",function(d,e){var f=e.keyCode||e.which;if(13==f){if(b.fireEvent("beforeenterkeydown"))return void domUtils.preventDefault(e);b.fireEvent("saveScene",!0,!0),a="";var g=b.selection.getRange();if(!g.collapsed){var h=g.startContainer,i=g.endContainer,j=domUtils.findParentByTagName(h,"td",!0),k=domUtils.findParentByTagName(i,"td",!0);if(j&&k&&j!==k||!j&&k||j&&!k)return void(e.preventDefault?e.preventDefault():e.returnValue=!1)}if("p"==c)browser.ie||(h=domUtils.findParentByTagName(g.startContainer,["ol","ul","p","h1","h2","h3","h4","h5","h6","blockquote","caption"],!0),h||browser.opera?(a=h.tagName,"p"==h.tagName.toLowerCase()&&browser.gecko&&domUtils.removeDirtyAttr(h)):(b.document.execCommand("formatBlock",!1,"

    "),browser.gecko&&(g=b.selection.getRange(),h=domUtils.findParentByTagName(g.startContainer,"p",!0),h&&domUtils.removeDirtyAttr(h))));else if(e.preventDefault?e.preventDefault():e.returnValue=!1,g.collapsed){m=g.document.createElement("br"),g.insertNode(m);var l=m.parentNode;l.lastChild===m?(m.parentNode.insertBefore(m.cloneNode(!0),m),g.setStartBefore(m)):g.setStartAfter(m),g.setCursor()}else if(g.deleteContents(),h=g.startContainer,1==h.nodeType&&(h=h.childNodes[g.startOffset])){for(;1==h.nodeType;){if(dtd.$empty[h.tagName])return g.setStartBefore(h).setCursor(),b.undoManger&&b.undoManger.save(),!1;if(!h.firstChild){var m=g.document.createElement("br");return h.appendChild(m),g.setStart(h,0).setCursor(),b.undoManger&&b.undoManger.save(),!1}h=h.firstChild}h===g.startContainer.childNodes[g.startOffset]?(m=g.document.createElement("br"),g.insertNode(m).setCursor()):g.setStart(h,0).setCursor()}else m=g.document.createElement("br"),g.insertNode(m).setStartAfter(m).setCursor()}})},UE.plugins.keystrokes=function(){var a=this,b=!0;a.addListener("keydown",function(c,d){var e=d.keyCode||d.which,f=a.selection.getRange();if(!f.collapsed&&!(d.ctrlKey||d.shiftKey||d.altKey||d.metaKey)&&(e>=65&&e<=90||e>=48&&e<=57||e>=96&&e<=111||{13:1,8:1,46:1}[e])){var g=f.startContainer;if(domUtils.isFillChar(g)&&f.setStartBefore(g),g=f.endContainer,domUtils.isFillChar(g)&&f.setEndAfter(g),f.txtToElmBoundary(),f.endContainer&&1==f.endContainer.nodeType&&(g=f.endContainer.childNodes[f.endOffset],g&&domUtils.isBr(g)&&f.setEndAfter(g)),0==f.startOffset&&(g=f.startContainer,domUtils.isBoundaryNode(g,"firstChild")&&(g=f.endContainer,f.endOffset==(3==g.nodeType?g.nodeValue.length:g.childNodes.length)&&domUtils.isBoundaryNode(g,"lastChild"))))return a.fireEvent("saveScene"),a.body.innerHTML="

    "+(browser.ie?"":"
    ")+"

    ",f.setStart(a.body.firstChild,0).setCursor(!1,!0),void a._selectionChange()}if(e==keymap.Backspace){if(f=a.selection.getRange(),b=f.collapsed,a.fireEvent("delkeydown",d))return;var h,i;if(f.collapsed&&f.inFillChar()&&(h=f.startContainer,domUtils.isFillChar(h)?(f.setStartBefore(h).shrinkBoundary(!0).collapse(!0),domUtils.remove(h)):(h.nodeValue=h.nodeValue.replace(new RegExp("^"+domUtils.fillChar),""),f.startOffset--,f.collapse(!0).select(!0))),h=f.getClosedNode())return a.fireEvent("saveScene"),f.setStartBefore(h),domUtils.remove(h),f.setCursor(),a.fireEvent("saveScene"),void domUtils.preventDefault(d);if(!browser.ie&&(h=domUtils.findParentByTagName(f.startContainer,"table",!0),i=domUtils.findParentByTagName(f.endContainer,"table",!0),h&&!i||!h&&i||h!==i))return void d.preventDefault()}if(e==keymap.Tab){var j={ol:1,ul:1,table:1};if(a.fireEvent("tabkeydown",d))return void domUtils.preventDefault(d);var k=a.selection.getRange();a.fireEvent("saveScene");for(var l=0,m="",n=a.options.tabSize||4,o=a.options.tabNode||" ";l"});d.insertNode(g).setStart(g,0).setCursor(!1,!0)}}if(!b&&(3==d.startContainer.nodeType||1==d.startContainer.nodeType&&domUtils.isEmptyBlock(d.startContainer)))if(browser.ie){var k=d.document.createElement("span");d.insertNode(k).setStartBefore(k).collapse(!0),d.select(),domUtils.remove(k)}else d.select()}})},UE.plugins.fiximgclick=function(){function a(){this.editor=null,this.resizer=null,this.cover=null,this.doc=document,this.prePos={x:0,y:0},this.startPos={x:0,y:0}}var b=!1;return function(){var c=[[0,0,-1,-1],[0,0,0,-1],[0,0,1,-1],[0,0,-1,0],[0,0,1,0],[0,0,-1,1],[0,0,0,1],[0,0,1,1]];a.prototype={init:function(a){var b=this;b.editor=a,b.startPos=this.prePos={x:0,y:0},b.dragId=-1;var c=[],d=b.cover=document.createElement("div"),e=b.resizer=document.createElement("div");for(d.id=b.editor.ui.id+"_imagescale_cover",d.style.cssText="position:absolute;display:none;z-index:"+b.editor.options.zIndex+";filter:alpha(opacity=0); opacity:0;background:#CCC;",domUtils.on(d,"mousedown click",function(){b.hide()}),i=0;i<8;i++)c.push('');e.id=b.editor.ui.id+"_imagescale",e.className="edui-editor-imagescale",e.innerHTML=c.join(""),e.style.cssText+=";display:none;border:1px solid #3b77ff;z-index:"+b.editor.options.zIndex+";",b.editor.ui.getDom().appendChild(d),b.editor.ui.getDom().appendChild(e),b.initStyle(),b.initEvents()},initStyle:function(){utils.cssRule("imagescale",".edui-editor-imagescale{display:none;position:absolute;border:1px solid #38B2CE;cursor:hand;-webkit-box-sizing: content-box;-moz-box-sizing: content-box;box-sizing: content-box;}.edui-editor-imagescale span{position:absolute;width:6px;height:6px;overflow:hidden;font-size:0px;display:block;background-color:#3C9DD0;}.edui-editor-imagescale .edui-editor-imagescale-hand0{cursor:nw-resize;top:0;margin-top:-4px;left:0;margin-left:-4px;}.edui-editor-imagescale .edui-editor-imagescale-hand1{cursor:n-resize;top:0;margin-top:-4px;left:50%;margin-left:-4px;}.edui-editor-imagescale .edui-editor-imagescale-hand2{cursor:ne-resize;top:0;margin-top:-4px;left:100%;margin-left:-3px;}.edui-editor-imagescale .edui-editor-imagescale-hand3{cursor:w-resize;top:50%;margin-top:-4px;left:0;margin-left:-4px;}.edui-editor-imagescale .edui-editor-imagescale-hand4{cursor:e-resize;top:50%;margin-top:-4px;left:100%;margin-left:-3px;}.edui-editor-imagescale .edui-editor-imagescale-hand5{cursor:sw-resize;top:100%;margin-top:-3px;left:0;margin-left:-4px;}.edui-editor-imagescale .edui-editor-imagescale-hand6{cursor:s-resize;top:100%;margin-top:-3px;left:50%;margin-left:-4px;}.edui-editor-imagescale .edui-editor-imagescale-hand7{cursor:se-resize;top:100%;margin-top:-3px;left:100%;margin-left:-3px;}")},initEvents:function(){var a=this;a.startPos.x=a.startPos.y=0,a.isDraging=!1},_eventHandler:function(a){var c=this;switch(a.type){case"mousedown":var d,d=a.target||a.srcElement;d.className.indexOf("edui-editor-imagescale-hand")!=-1&&c.dragId==-1&&(c.dragId=d.className.slice(-1),c.startPos.x=c.prePos.x=a.clientX,c.startPos.y=c.prePos.y=a.clientY,domUtils.on(c.doc,"mousemove",c.proxy(c._eventHandler,c)));break;case"mousemove":c.dragId!=-1&&(c.updateContainerStyle(c.dragId,{x:a.clientX-c.prePos.x,y:a.clientY-c.prePos.y}),c.prePos.x=a.clientX,c.prePos.y=a.clientY,b=!0,c.updateTargetElement());break;case"mouseup":c.dragId!=-1&&(c.updateContainerStyle(c.dragId,{x:a.clientX-c.prePos.x,y:a.clientY-c.prePos.y}),c.updateTargetElement(),c.target.parentNode&&c.attachTo(c.target),c.dragId=-1),domUtils.un(c.doc,"mousemove",c.proxy(c._eventHandler,c)),b&&(b=!1,c.editor.fireEvent("contentchange"))}},updateTargetElement:function(){var a=this;domUtils.setStyles(a.target,{width:a.resizer.style.width,height:a.resizer.style.height}),a.target.width=parseInt(a.resizer.style.width),a.target.height=parseInt(a.resizer.style.height),a.attachTo(a.target)},updateContainerStyle:function(a,b){var d,e=this,f=e.resizer;0!=c[a][0]&&(d=parseInt(f.style.left)+b.x,f.style.left=e._validScaledProp("left",d)+"px"),0!=c[a][1]&&(d=parseInt(f.style.top)+b.y,f.style.top=e._validScaledProp("top",d)+"px"),0!=c[a][2]&&(d=f.clientWidth+c[a][2]*b.x,f.style.width=e._validScaledProp("width",d)+"px"),0!=c[a][3]&&(d=f.clientHeight+c[a][3]*b.y,f.style.height=e._validScaledProp("height",d)+"px")},_validScaledProp:function(a,b){var c=this.resizer,d=document;switch(b=isNaN(b)?0:b,a){case"left":return b<0?0:b+c.clientWidth>d.clientWidth?d.clientWidth-c.clientWidth:b;case"top":return b<0?0:b+c.clientHeight>d.clientHeight?d.clientHeight-c.clientHeight:b;case"width":return b<=0?1:b+c.offsetLeft>d.clientWidth?d.clientWidth-c.offsetLeft:b;case"height":return b<=0?1:b+c.offsetTop>d.clientHeight?d.clientHeight-c.offsetTop:b}},hideCover:function(){this.cover.style.display="none"},showCover:function(){var a=this,b=domUtils.getXY(a.editor.ui.getDom()),c=domUtils.getXY(a.editor.iframe);domUtils.setStyles(a.cover,{width:a.editor.iframe.offsetWidth+"px",height:a.editor.iframe.offsetHeight+"px",top:c.y-b.y+"px",left:c.x-b.x+"px",position:"absolute",display:""})},show:function(a){var b=this;b.resizer.style.display="block",a&&b.attachTo(a),domUtils.on(this.resizer,"mousedown",b.proxy(b._eventHandler,b)),domUtils.on(b.doc,"mouseup",b.proxy(b._eventHandler,b)),b.showCover(),b.editor.fireEvent("afterscaleshow",b),b.editor.fireEvent("saveScene")},hide:function(){var a=this;a.hideCover(),a.resizer.style.display="none",domUtils.un(a.resizer,"mousedown",a.proxy(a._eventHandler,a)),domUtils.un(a.doc,"mouseup",a.proxy(a._eventHandler,a)),a.editor.fireEvent("afterscalehide",a)},proxy:function(a,b){return function(c){return a.apply(b||this,arguments)}},attachTo:function(a){var b=this,c=b.target=a,d=this.resizer,e=domUtils.getXY(c),f=domUtils.getXY(b.editor.iframe),g=domUtils.getXY(d.parentNode);domUtils.setStyles(d,{width:c.width+"px",height:c.height+"px",left:f.x+e.x-b.editor.document.body.scrollLeft-g.x-parseInt(d.style.borderLeftWidth)+"px",top:f.y+e.y-b.editor.document.body.scrollTop-g.y-parseInt(d.style.borderTopWidth)+"px"})}}}(),function(){var b,c=this;c.setOpt("imageScaleEnabled",!0),!browser.ie&&c.options.imageScaleEnabled&&c.addListener("click",function(d,e){var f=c.selection.getRange(),g=f.getClosedNode();if(g&&"IMG"==g.tagName&&"false"!=c.body.contentEditable){if(g.className.indexOf("edui-faked-music")!=-1||g.getAttribute("anchorname")||domUtils.hasClass(g,"loadingclass")||domUtils.hasClass(g,"loaderrorclass"))return;if(!b){b=new a,b.init(c),c.ui.getDom().appendChild(b.resizer);var h,i=function(a){b.hide(),b.target&&c.selection.getRange().selectNode(b.target).select()},j=function(a){var b=a.target||a.srcElement;!b||void 0!==b.className&&b.className.indexOf("edui-editor-imagescale")!=-1||i(a)};c.addListener("afterscaleshow",function(a){c.addListener("beforekeydown",i),c.addListener("beforemousedown",j),domUtils.on(document,"keydown",i),domUtils.on(document,"mousedown",j),c.selection.getNative().removeAllRanges()}),c.addListener("afterscalehide",function(a){c.removeListener("beforekeydown",i),c.removeListener("beforemousedown",j),domUtils.un(document,"keydown",i),domUtils.un(document,"mousedown",j);var d=b.target;d.parentNode&&c.selection.getRange().selectNode(d).select()}),domUtils.on(b.resizer,"mousedown",function(a){c.selection.getNative().removeAllRanges();var d=a.target||a.srcElement;d&&d.className.indexOf("edui-editor-imagescale-hand")==-1&&(h=setTimeout(function(){b.hide(),b.target&&c.selection.getRange().selectNode(d).select()},200))}),domUtils.on(b.resizer,"mouseup",function(a){var b=a.target||a.srcElement;b&&b.className.indexOf("edui-editor-imagescale-hand")==-1&&clearTimeout(h)})}b.show(g)}else b&&"none"!=b.resizer.style.display&&b.hide()}),browser.webkit&&c.addListener("click",function(a,b){if("IMG"==b.target.tagName&&"false"!=c.body.contentEditable){var d=new dom.Range(c.document);d.selectNode(b.target).select()}})}}(),UE.plugin.register("autolink",function(){var a=0;return browser.ie?{}:{bindEvents:{reset:function(){a=0},keydown:function(a,b){var c=this,d=b.keyCode||b.which;if(32==d||13==d){for(var e,f,g=c.selection.getNative(),h=g.getRangeAt(0).cloneRange(),i=h.startContainer;1==i.nodeType&&h.startOffset>0&&(i=h.startContainer.childNodes[h.startOffset-1]);)h.setStart(i,1==i.nodeType?i.childNodes.length:i.nodeValue.length),h.collapse(!0),i=h.startContainer;do{if(0==h.startOffset){for(i=h.startContainer.previousSibling;i&&1==i.nodeType;)i=i.lastChild;if(!i||domUtils.isFillChar(i))break;e=i.nodeValue.length}else i=h.startContainer,e=h.startOffset;h.setStart(i,e-1),f=h.toString().charCodeAt(0)}while(160!=f&&32!=f);if(h.toString().replace(new RegExp(domUtils.fillChar,"g"),"").match(/(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i)){for(;h.toString().length&&!/^(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i.test(h.toString());)try{h.setStart(h.startContainer,h.startOffset+1)}catch(j){for(var i=h.startContainer;!(next=i.nextSibling);){if(domUtils.isBody(i))return;i=i.parentNode}h.setStart(next,0)}if(domUtils.findParentByTagName(h.startContainer,"a",!0))return;var k,l=c.document.createElement("a"),m=c.document.createTextNode(" ");c.undoManger&&c.undoManger.save(),l.appendChild(h.extractContents()),l.href=l.innerHTML=l.innerHTML.replace(/<[^>]+>/g,""),k=l.getAttribute("href").replace(new RegExp(domUtils.fillChar,"g"),""),k=/^(?:https?:\/\/)/gi.test(k)?k:"http://"+k,l.setAttribute("_src",utils.html(k)),l.href=utils.html(k),h.insertNode(l),l.parentNode.insertBefore(m,l.nextSibling),h.setStart(m,0),h.collapse(!0),g.removeAllRanges(),g.addRange(h),c.undoManger&&c.undoManger.save()}}}}}},function(){function a(a){if(3==a.nodeType)return null;if("A"==a.nodeName)return a;for(var b=a.lastChild;b;){if("A"==b.nodeName)return b;if(3==b.nodeType){if(domUtils.isWhitespace(b)){b=b.previousSibling;continue}return null}b=b.lastChild}}var b={37:1,38:1,39:1,40:1,13:1,32:1};browser.ie&&this.addListener("keyup",function(c,d){var e=this,f=d.keyCode;if(b[f]){var g=e.selection.getRange(),h=g.startContainer;if(13==f){for(;h&&!domUtils.isBody(h)&&!domUtils.isBlockElm(h);)h=h.parentNode;if(h&&!domUtils.isBody(h)&&"P"==h.nodeName){var i=h.previousSibling;if(i&&1==i.nodeType){var i=a(i);i&&!i.getAttribute("_href")&&domUtils.remove(i,!0)}}}else if(32==f)3==h.nodeType&&/^\s$/.test(h.nodeValue)&&(h=h.previousSibling,h&&"A"==h.nodeName&&!h.getAttribute("_href")&&domUtils.remove(h,!0));else if(h=domUtils.findParentByTagName(h,"a",!0),h&&!h.getAttribute("_href")){var j=g.createBookmark();domUtils.remove(h,!0),g.moveToBookmark(j).select(!0)}}})}),UE.plugins.autoheight=function(){function a(){var a=this;clearTimeout(e),f||(!a.queryCommandState||a.queryCommandState&&1!=a.queryCommandState("source"))&&(e=setTimeout(function(){for(var b=a.body.lastChild;b&&1!=b.nodeType;)b=b.previousSibling;b&&1==b.nodeType&&(b.style.clear="both",d=Math.max(domUtils.getXY(b).y+b.offsetHeight+25,Math.max(h.minFrameHeight,h.initialFrameHeight)),d!=g&&(d!==parseInt(a.iframe.parentNode.style.height)&&(a.iframe.parentNode.style.height=d+"px"),a.body.style.height=d+"px",g=d),domUtils.removeStyle(b,"clear"))},50))}var b=this;if(b.autoHeightEnabled=b.options.autoHeightEnabled!==!1,b.autoHeightEnabled){var c,d,e,f,g=0,h=b.options;b.addListener("fullscreenchanged",function(a,b){f=b}),b.addListener("destroy",function(){b.removeListener("contentchange afterinserthtml keyup mouseup",a)}),b.enableAutoHeight=function(){var b=this;if(b.autoHeightEnabled){var d=b.document;b.autoHeightEnabled=!0,c=d.body.style.overflowY,d.body.style.overflowY="hidden",b.addListener("contentchange afterinserthtml keyup mouseup",a),setTimeout(function(){a.call(b)},browser.gecko?100:0),b.fireEvent("autoheightchanged",b.autoHeightEnabled)}},b.disableAutoHeight=function(){b.body.style.overflowY=c||"",b.removeListener("contentchange",a),b.removeListener("keyup",a),b.removeListener("mouseup",a),b.autoHeightEnabled=!1,b.fireEvent("autoheightchanged",b.autoHeightEnabled)},b.on("setHeight",function(){b.disableAutoHeight()}),b.addListener("ready",function(){b.enableAutoHeight();var c;domUtils.on(browser.ie?b.body:b.document,browser.webkit?"dragover":"drop",function(){clearTimeout(c),c=setTimeout(function(){a.call(b)},100)});var d;window.onscroll=function(){ -null===d?d=this.scrollY:0==this.scrollY&&0!=d&&(b.window.scrollTo(0,0),d=null)}})}},UE.plugins.autofloat=function(){function a(){return UE.ui?1:(alert(g.autofloatMsg),0)}function b(){var a=document.body.style;a.backgroundImage='url("about:blank")',a.backgroundAttachment="fixed"}function c(){var a=domUtils.getXY(k),b=domUtils.getComputedStyle(k,"position"),c=domUtils.getComputedStyle(k,"left");k.style.width=k.offsetWidth+"px",k.style.zIndex=1*f.options.zIndex+1,k.parentNode.insertBefore(q,k),o||p&&browser.ie?("absolute"!=k.style.position&&(k.style.position="absolute"),k.style.top=(document.body.scrollTop||document.documentElement.scrollTop)-l+i+"px"):(browser.ie7Compat&&r&&(r=!1,k.style.left=domUtils.getXY(k).x-document.documentElement.getBoundingClientRect().left+2+"px"),"fixed"!=k.style.position&&(k.style.position="fixed",k.style.top=i+"px",("absolute"==b||"relative"==b)&&parseFloat(c)&&(k.style.left=a.x+"px")))}function d(){r=!0,q.parentNode&&q.parentNode.removeChild(q),k.style.cssText=j}function e(){var a=m(f.container),b=f.options.toolbarTopOffset||0;a.top<0&&a.bottom-k.offsetHeight>b?c():d()}var f=this,g=f.getLang();f.setOpt({topOffset:0});var h=f.options.autoFloatEnabled!==!1,i=f.options.topOffset;if(h){var j,k,l,m,n=UE.ui.uiUtils,o=browser.ie&&browser.version<=6,p=browser.quirks,q=document.createElement("div"),r=!0,s=utils.defer(function(){e()},browser.ie?200:100,!0);f.addListener("destroy",function(){domUtils.un(window,["scroll","resize"],e),f.removeListener("keydown",s)}),f.addListener("ready",function(){if(a(f)){if(!f.ui)return;m=n.getClientRect,k=f.ui.getDom("toolbarbox"),l=m(k).top,j=k.style.cssText,q.style.height=k.offsetHeight+"px",o&&b(),domUtils.on(window,["scroll","resize"],e),f.addListener("keydown",s),f.addListener("beforefullscreenchange",function(a,b){b&&d()}),f.addListener("fullscreenchanged",function(a,b){b||e()}),f.addListener("sourcemodechanged",function(a,b){setTimeout(function(){e()},0)}),f.addListener("clearDoc",function(){setTimeout(function(){e()},0)})}})}},UE.plugins.video=function(){function a(a,b,d,e,f,g,h){a=utils.unhtmlForUrl(a),f=utils.unhtml(f),g=utils.unhtml(g),b=parseInt(b,10)||0,d=parseInt(d,10)||0;var i;switch(h){case"image":i="';break;case"embed":i='';break;case"video":var j=a.substr(a.lastIndexOf(".")+1);"ogv"==j&&(j="ogg"),i="'}return i}function b(b,c){utils.each(b.getNodesByTagName(c?"img":"embed video"),function(b){var d=b.getAttr("class");if(d&&d.indexOf("edui-faked-video")!=-1){var e=a(c?b.getAttr("_url"):b.getAttr("src"),b.getAttr("width"),b.getAttr("height"),null,b.getStyle("float")||"",d,c?"embed":"image");b.parentNode.replaceChild(UE.uNode.createElement(e),b)}if(d&&d.indexOf("edui-upload-video")!=-1){var e=a(c?b.getAttr("_url"):b.getAttr("src"),b.getAttr("width"),b.getAttr("height"),null,b.getStyle("float")||"",d,c?"video":"image");b.parentNode.replaceChild(UE.uNode.createElement(e),b)}})}var c=this;c.addOutputRule(function(a){b(a,!0)}),c.addInputRule(function(a){b(a)}),c.commands.insertvideo={execCommand:function(b,d,e){d=utils.isArray(d)?d:[d];for(var f,g,h=[],i="tmpVedio",j=0,k=d.length;j0)return 0;for(var c in dtd.$isNotEmpty)if(dtd.$isNotEmpty.hasOwnProperty(c)&&a.getElementsByTagName(c).length)return 0;return 1},b.getWidth=function(a){return a?parseInt(domUtils.getComputedStyle(a,"width"),10):0},b.getTableCellAlignState=function(a){!utils.isArray(a)&&(a=[a]);var b={},c=["align","valign"],d=null,e=!0;return utils.each(a,function(a){return utils.each(c,function(c){if(d=a.getAttribute(c),!b[c]&&d)b[c]=d;else if(!b[c]||d!==b[c])return e=!1,!1}),e}),e?b:null},b.getTableItemsByRange=function(a){var b=a.selection.getStart();b&&b.id&&0===b.id.indexOf("_baidu_bookmark_start_")&&b.nextSibling&&(b=b.nextSibling);var c=b&&domUtils.findParentByTagName(b,["td","th"],!0),d=c&&c.parentNode,e=b&&domUtils.findParentByTagName(b,"caption",!0),f=e?e.parentNode:d&&d.parentNode.parentNode;return{cell:c,tr:d,table:f,caption:e}},b.getUETableBySelected=function(a){var c=b.getTableItemsByRange(a).table;return c&&c.ueTable&&c.ueTable.selectedTds.length?c.ueTable:null},b.getDefaultValue=function(a,b){var c,d,e,f,g={thin:"0px",medium:"1px",thick:"2px"};if(b)return h=b.getElementsByTagName("td")[0],f=domUtils.getComputedStyle(b,"border-left-width"),c=parseInt(g[f]||f,10),f=domUtils.getComputedStyle(h,"padding-left"),d=parseInt(g[f]||f,10),f=domUtils.getComputedStyle(h,"border-left-width"),e=parseInt(g[f]||f,10),{tableBorder:c,tdPadding:d,tdBorder:e};b=a.document.createElement("table"),b.insertRow(0).insertCell(0).innerHTML="xxx",a.body.appendChild(b);var h=b.getElementsByTagName("td")[0];return f=domUtils.getComputedStyle(b,"border-left-width"),c=parseInt(g[f]||f,10),f=domUtils.getComputedStyle(h,"padding-left"),d=parseInt(g[f]||f,10),f=domUtils.getComputedStyle(h,"border-left-width"),e=parseInt(g[f]||f,10),domUtils.remove(b),{tableBorder:c,tdPadding:d,tdBorder:e}},b.getUETable=function(a){var c=a.tagName.toLowerCase();return a="td"==c||"th"==c||"caption"==c?domUtils.findParentByTagName(a,"table",!0):a,a.ueTable||(a.ueTable=new b(a)),a.ueTable},b.cloneCell=function(a,b,c){if(!a||utils.isString(a))return this.table.ownerDocument.createElement(a||"td");var d=domUtils.hasClass(a,"selectTdClass");d&&domUtils.removeClasses(a,"selectTdClass");var e=a.cloneNode(!0);return b&&(e.rowSpan=e.colSpan=1),!c&&domUtils.removeAttributes(e,"width height"),!c&&domUtils.removeAttributes(e,"style"),e.style.borderLeftStyle="",e.style.borderTopStyle="",e.style.borderLeftColor=a.style.borderRightColor,e.style.borderLeftWidth=a.style.borderRightWidth,e.style.borderTopColor=a.style.borderBottomColor,e.style.borderTopWidth=a.style.borderBottomWidth,d&&domUtils.addClass(a,"selectTdClass"),e},b.prototype={getMaxRows:function(){for(var a,b=this.table.rows,c=1,d=0;a=b[d];d++){for(var e,f=1,g=0;e=a.cells[g++];)f=Math.max(e.rowSpan||1,f);c=Math.max(f+d,c)}return c},getMaxCols:function(){for(var a,b=this.table.rows,c=0,d={},e=0;a=b[e];e++){for(var f,g=0,h=0;f=a.cells[h++];)if(g+=f.colSpan||1,f.rowSpan&&f.rowSpan>1)for(var i=1;ithis.rowsNum-1)?null:(e=c?h?i.endRowIndex+1:g.rowIndex+g.rowSpan:h?i.beginRowIndex-1:g.rowIndex-1,f=h?i.beginColIndex:g.colIndex,this.getCell(this.indexTable[e][f].rowIndex,this.indexTable[e][f].cellIndex))}catch(j){a(j)}},getSameEndPosCells:function(b,c){try{for(var d="x"===c.toLowerCase(),e=domUtils.getXY(b)[d?"x":"y"]+b["offset"+(d?"Width":"Height")],f=this.table.rows,g=null,h=[],i=0;ie&&d)break;if((b==j||e==l)&&(1==j[d?"colSpan":"rowSpan"]&&h.push(j),d))break}}return h}catch(m){a(m)}},setCellContent:function(a,b){a.innerHTML=b||(browser.ie?domUtils.fillChar:"
    ")},cloneCell:b.cloneCell,getSameStartPosXCells:function(b){try{for(var c,d=domUtils.getXY(b).x+b.offsetWidth,e=this.table.rows,f=[],g=0;gd)break;if(j==d&&1==h.colSpan){f.push(h);break}}}return f}catch(k){a(k)}},update:function(a){this.table=a||this.table,this.selectedTds=[],this.cellsRange={},this.indexTable=[];for(var b=this.table.rows,c=this.getMaxRows(),d=c-b.length,e=this.getMaxCols();d--;)this.table.insertRow(b.length);this.rowsNum=c,this.colsNum=e;for(var f=0,g=b.length;fc&&(j.rowSpan=c);for(var m=k,n=j.rowSpan||1,o=j.colSpan||1;this.indexTable[i][m];)m++;for(var p=0;p0)for(h=b;hf&&(m=Math.max(h,m));if(ee&&(l=Math.max(i,l));if(b>0)for(i=a;ig||d+b.colSpan-1>h)return null;j.push(this.getCell(c,b.cellIndex))}}return j},clearSelected:function(){b.removeSelectedClass(this.selectedTds),this.selectedTds=[],this.cellsRange={}},setSelected:function(a){var c=this.getCells(a);b.addSelectedClass(c),this.selectedTds=c,this.cellsRange=a},isFullRow:function(){var a=this.cellsRange;return a.endColIndex-a.beginColIndex+1==this.colsNum},isFullCol:function(){var a=this.cellsRange,b=this.table,c=b.getElementsByTagName("th"),d=a.endRowIndex-a.beginRowIndex+1;return c.length?d==this.rowsNum||d==this.rowsNum-1:d==this.rowsNum},getNextCell:function(b,c,d){try{var e,f,g=this.getCellInfo(b),h=this.selectedTds.length&&!d,i=this.cellsRange;return!c&&0==g.rowIndex||c&&(h?i.endRowIndex==this.rowsNum-1:g.rowIndex+g.rowSpan>this.rowsNum-1)?null:(e=c?h?i.endRowIndex+1:g.rowIndex+g.rowSpan:h?i.beginRowIndex-1:g.rowIndex-1,f=h?i.beginColIndex:g.colIndex,this.getCell(this.indexTable[e][f].rowIndex,this.indexTable[e][f].cellIndex))}catch(j){a(j)}},getPreviewCell:function(b,c){try{var d,e,f=this.getCellInfo(b),g=this.selectedTds.length,h=this.cellsRange;return!c&&(g?!h.beginColIndex:!f.colIndex)||c&&(g?h.endColIndex==this.colsNum-1:f.rowIndex>this.colsNum-1)?null:(d=c?g?h.beginRowIndex:f.rowIndex<1?0:f.rowIndex-1:g?h.beginRowIndex:f.rowIndex,e=c?g?h.endColIndex+1:f.colIndex:g?h.beginColIndex-1:f.colIndex<1?0:f.colIndex-1,this.getCell(this.indexTable[d][e].rowIndex,this.indexTable[d][e].cellIndex))}catch(i){a(i)}},moveContent:function(a,c){if(!b.isEmptyBlock(c)){if(b.isEmptyBlock(a))return void(a.innerHTML=c.innerHTML);var d=a.lastChild;for(3!=d.nodeType&&dtd.$block[d.tagName]||a.appendChild(a.ownerDocument.createElement("br"));d=c.firstChild;)a.appendChild(d)}},mergeRight:function(a){var b=this.getCellInfo(a),c=b.colIndex+b.colSpan,d=this.indexTable[b.rowIndex][c],e=this.getCell(d.rowIndex,d.cellIndex);a.colSpan=b.colSpan+d.colSpan,a.removeAttribute("width"),this.moveContent(a,e),this.deleteCell(e,d.rowIndex),this.update()},mergeDown:function(a){var b=this.getCellInfo(a),c=b.rowIndex+b.rowSpan,d=this.indexTable[c][b.colIndex],e=this.getCell(d.rowIndex,d.cellIndex);a.rowSpan=b.rowSpan+d.rowSpan,a.removeAttribute("height"),this.moveContent(a,e),this.deleteCell(e,d.rowIndex),this.update()},mergeRange:function(){var a=this.cellsRange,b=this.getCell(a.beginRowIndex,this.indexTable[a.beginRowIndex][a.beginColIndex].cellIndex);if("TH"==b.tagName&&a.endRowIndex!==a.beginRowIndex){var c=this.indexTable,d=this.getCellInfo(b);b=this.getCell(1,c[1][d.colIndex].cellIndex),a=this.getCellsRange(b,this.getCell(c[this.rowsNum-1][d.colIndex].rowIndex,c[this.rowsNum-1][d.colIndex].cellIndex))}for(var e,f=this.getCells(a),g=0;e=f[g++];)e!==b&&(this.moveContent(b,e),this.deleteCell(e));if(b.rowSpan=a.endRowIndex-a.beginRowIndex+1,b.rowSpan>1&&b.removeAttribute("height"),b.colSpan=a.endColIndex-a.beginColIndex+1,b.colSpan>1&&b.removeAttribute("width"),b.rowSpan==this.rowsNum&&1!=b.colSpan&&(b.colSpan=1),b.colSpan==this.colsNum&&1!=b.rowSpan){var h=b.parentNode.rowIndex;if(this.table.deleteRow)for(var g=h+1,i=h+1,j=b.rowSpan;g1&&g.rowIndex==a){var i=h.cloneNode(!0);i.rowSpan=h.rowSpan-1,i.innerHTML="",h.rowSpan=1;var j,k=a+1,l=this.table.rows[k],m=this.getPreviewMergedCellsNum(k,f)-e;m1?l.colSpan--:c[h].deleteCell(j.cellIndex),h+=j.rowSpan||1}}this.table.setAttribute("width",d-e),this.update()},splitToCells:function(a){var b=this,c=this.splitToRows(a);utils.each(c,function(a){b.splitToCols(a)})},splitToRows:function(a){var b=this.getCellInfo(a),c=b.rowIndex,d=b.colIndex,e=[];a.rowSpan=1,e.push(a);for(var f=c,g=c+b.rowSpan;f");for(var g=0;g'+(browser.ie&&browser.version<11?domUtils.fillChar:"
    ")+"");c.push("")}return"
    "+c.join("")+"
    "}b||(b=utils.extend({},{numCols:this.options.defaultCols,numRows:this.options.defaultRows,tdvalign:this.options.tdvalign}));var d=this,e=this.selection.getRange(),f=e.startContainer,h=domUtils.findParent(f,function(a){return domUtils.isBlockElm(a)},!0)||d.body,i=g(d),j=h.offsetWidth,k=Math.floor(j/b.numCols-2*i.tdPadding-i.tdBorder);!b.tdvalign&&(b.tdvalign=d.options.tdvalign),d.execCommand("inserthtml",c(b,k))}},UE.commands.insertparagraphbeforetable={queryCommandState:function(){return e(this).cell?0:-1},execCommand:function(){var a=e(this).table;if(a){var b=this.document.createElement("p");b.innerHTML=browser.ie?" ":"
    ",a.parentNode.insertBefore(b,a),this.selection.getRange().setStart(b,0).setCursor()}}},UE.commands.deletetable={queryCommandState:function(){var a=this.selection.getRange();return domUtils.findParentByTagName(a.startContainer,"table",!0)?0:-1},execCommand:function(a,b){var c=this.selection.getRange();if(b=b||domUtils.findParentByTagName(c.startContainer,"table",!0)){var d=b.nextSibling;d||(d=domUtils.createElement(this.document,"p",{innerHTML:browser.ie?domUtils.fillChar:"
    "}),b.parentNode.insertBefore(d,b)),domUtils.remove(b),c=this.selection.getRange(),3==d.nodeType?c.setStartBefore(d):c.setStart(d,0),c.setCursor(!1,!0),this.fireEvent("tablehasdeleted")}}},UE.commands.cellalign={queryCommandState:function(){return c(this).length?0:-1},execCommand:function(a,b){var d=c(this);if(d.length)for(var e,f=0;e=d[f++];)e.setAttribute("align",b)}},UE.commands.cellvalign={queryCommandState:function(){return c(this).length?0:-1},execCommand:function(a,b){var d=c(this);if(d.length)for(var e,f=0;e=d[f++];)e.setAttribute("vAlign",b)}},UE.commands.insertcaption={queryCommandState:function(){var a=e(this).table;return a&&0==a.getElementsByTagName("caption").length?1:-1},execCommand:function(){var a=e(this).table;if(a){var b=this.document.createElement("caption");b.innerHTML=browser.ie?domUtils.fillChar:"
    ",a.insertBefore(b,a.firstChild);var c=this.selection.getRange();c.setStart(b,0).setCursor()}}},UE.commands.deletecaption={queryCommandState:function(){var a=this.selection.getRange(),b=domUtils.findParentByTagName(a.startContainer,"table");return b?0==b.getElementsByTagName("caption").length?-1:1:-1},execCommand:function(){var a=this.selection.getRange(),b=domUtils.findParentByTagName(a.startContainer,"table");if(b){domUtils.remove(b.getElementsByTagName("caption")[0]);var c=this.selection.getRange();c.setStart(b.rows[0].cells[0],0).setCursor()}}},UE.commands.inserttitle={queryCommandState:function(){var a=e(this).table;if(a){var b=a.rows[0];return"th"!=b.cells[b.cells.length-1].tagName.toLowerCase()?0:-1}return-1},execCommand:function(){var a=e(this).table;a&&h(a).insertRow(0,"th");var b=a.getElementsByTagName("th")[0];this.selection.getRange().setStart(b,0).setCursor(!1,!0)}},UE.commands.deletetitle={queryCommandState:function(){var a=e(this).table;if(a){var b=a.rows[0];return"th"==b.cells[b.cells.length-1].tagName.toLowerCase()?0:-1}return-1},execCommand:function(){var a=e(this).table;a&&domUtils.remove(a.rows[0]);var b=a.getElementsByTagName("td")[0];this.selection.getRange().setStart(b,0).setCursor(!1,!0)}},UE.commands.inserttitlecol={queryCommandState:function(){var a=e(this).table;if(a){var b=a.rows[a.rows.length-1];return b.getElementsByTagName("th").length?-1:0}return-1},execCommand:function(b){var c=e(this).table;c&&h(c).insertCol(0,"th"),a(c,this);var d=c.getElementsByTagName("th")[0];this.selection.getRange().setStart(d,0).setCursor(!1,!0)}},UE.commands.deletetitlecol={queryCommandState:function(){var a=e(this).table;if(a){var b=a.rows[a.rows.length-1];return b.getElementsByTagName("th").length?0:-1}return-1},execCommand:function(){var b=e(this).table;if(b)for(var c=0;c=f.colsNum)return-1;var j=f.indexTable[g.rowIndex][i],k=c.rows[j.rowIndex].cells[j.cellIndex];return k&&d.tagName==k.tagName&&j.rowIndex==g.rowIndex&&j.rowSpan==g.rowSpan?0:-1},execCommand:function(a){var b=this.selection.getRange(),c=b.createBookmark(!0),d=e(this).cell,f=h(d);f.mergeRight(d),b.moveToBookmark(c).select()}},UE.commands.mergedown={queryCommandState:function(a){var b=e(this),c=b.table,d=b.cell;if(!c||!d)return-1;var f=h(c);if(f.selectedTds.length)return-1;var g=f.getCellInfo(d),i=g.rowIndex+g.rowSpan;if(i>=f.rowsNum)return-1;var j=f.indexTable[i][g.colIndex],k=c.rows[j.rowIndex].cells[j.cellIndex];return k&&d.tagName==k.tagName&&j.colIndex==g.colIndex&&j.colSpan==g.colSpan?0:-1},execCommand:function(){var a=this.selection.getRange(),b=a.createBookmark(!0),c=e(this).cell,d=h(c);d.mergeDown(c),a.moveToBookmark(b).select()}},UE.commands.mergecells={queryCommandState:function(){return f(this)?0:-1},execCommand:function(){var a=f(this);if(a&&a.selectedTds.length){var b=a.selectedTds[0];a.mergeRange();var c=this.selection.getRange();domUtils.isEmptyBlock(b)?c.setStart(b,0).collapse(!0):c.selectNodeContents(b),c.select()}}},UE.commands.insertrow={queryCommandState:function(){var a=e(this),b=a.cell;return b&&("TD"==b.tagName||"TH"==b.tagName&&a.tr!==a.table.rows[0])&&h(a.table).rowsNum0?-1:b&&(b.colSpan>1||b.rowSpan>1)?0:-1},execCommand:function(){var a=this.selection.getRange(),b=a.createBookmark(!0),c=e(this).cell,d=h(c);d.splitToCells(c),a.moveToBookmark(b).select()}},UE.commands.splittorows={queryCommandState:function(){var a=e(this),b=a.cell;if(!b)return-1;var c=h(a.table);return c.selectedTds.length>0?-1:b&&b.rowSpan>1?0:-1},execCommand:function(){var a=this.selection.getRange(),b=a.createBookmark(!0),c=e(this).cell,d=h(c);d.splitToRows(c),a.moveToBookmark(b).select()}},UE.commands.splittocols={queryCommandState:function(){var a=e(this),b=a.cell;if(!b)return-1;var c=h(a.table);return c.selectedTds.length>0?-1:b&&b.colSpan>1?0:-1},execCommand:function(){var a=this.selection.getRange(),b=a.createBookmark(!0),c=e(this).cell,d=h(c);d.splitToCols(c),a.moveToBookmark(b).select()}},UE.commands.adaptbytext=UE.commands.adaptbywindow={queryCommandState:function(){return e(this).table?0:-1},execCommand:function(b){var c=e(this),d=c.table;if(d)if("adaptbywindow"==b)a(d,this);else{var f=domUtils.getElementsByTagName(d,"td th");utils.each(f,function(a){a.removeAttribute("width")}),d.removeAttribute("width")}}},UE.commands.averagedistributecol={queryCommandState:function(){var a=f(this);return a&&(a.isFullRow()||a.isFullCol())?0:-1},execCommand:function(a){function b(){var a,b=e.table,c=0,f=0,h=g(d,b);if(e.isFullRow())c=b.offsetWidth,f=e.colsNum;else for(var i,j=e.cellsRange.beginColIndex,k=e.cellsRange.endColIndex,l=j;l<=k;)i=e.selectedTds[l],c+=i.offsetWidth,l+=i.colSpan,f+=1;return a=Math.ceil(c/f)-2*h.tdBorder-2*h.tdPadding}function c(a){utils.each(domUtils.getElementsByTagName(e.table,"th"),function(a){a.setAttribute("width","")});var b=e.isFullRow()?domUtils.getElementsByTagName(e.table,"td"):e.selectedTds;utils.each(b,function(b){1==b.colSpan&&b.setAttribute("width",a)})}var d=this,e=f(d);e&&e.selectedTds.length&&c(b())}},UE.commands.averagedistributerow={queryCommandState:function(){var a=f(this);return a?a.selectedTds&&/th/gi.test(a.selectedTds[0].tagName)?-1:a.isFullRow()||a.isFullCol()?0:-1:-1},execCommand:function(a){function b(){var a,b,c=0,f=e.table,h=g(d,f),i=parseInt(domUtils.getComputedStyle(f.getElementsByTagName("td")[0],"padding-top"));if(e.isFullCol()){var j,k,l=domUtils.getElementsByTagName(f,"caption"),m=domUtils.getElementsByTagName(f,"th");l.length>0&&(j=l[0].offsetHeight),m.length>0&&(k=m[0].offsetHeight),c=f.offsetHeight-(j||0)-(k||0),b=0==m.length?e.rowsNum:e.rowsNum-1}else{for(var n=e.cellsRange.beginRowIndex,o=e.cellsRange.endRowIndex,p=0,q=domUtils.getElementsByTagName(f,"tr"),r=n;r<=o;r++)c+=q[r].offsetHeight,p+=1;b=p}return a=browser.ie&&browser.version<9?Math.ceil(c/b):Math.ceil(c/b)-2*h.tdBorder-2*i}function c(a){var b=e.isFullCol()?domUtils.getElementsByTagName(e.table,"td"):e.selectedTds;utils.each(b,function(b){1==b.rowSpan&&b.setAttribute("height",a)})}var d=this,e=f(d);e&&e.selectedTds.length&&c(b())}},UE.commands.cellalignment={queryCommandState:function(){return e(this).table?0:-1},execCommand:function(a,b){var c=this,d=f(c);if(d)utils.each(d.selectedTds,function(a){domUtils.setAttributes(a,b)});else{var e=c.selection.getStart(),g=e&&domUtils.findParentByTagName(e,["td","th","caption"],!0);/caption/gi.test(g.tagName)?(g.style.textAlign=b.align,g.style.verticalAlign=b.vAlign):domUtils.setAttributes(g,b),c.selection.getRange().setCursor(!0)}},queryCommandValue:function(a){var b=e(this).cell;if(b||(b=c(this)[0]),b){var d=UE.UETable.getUETable(b).selectedTds;return!d.length&&(d=b),UE.UETable.getTableCellAlignState(d)}return null}},UE.commands.tablealignment={queryCommandState:function(){return browser.ie&&browser.version<8?-1:e(this).table?0:-1},execCommand:function(a,b){var c=this,d=c.selection.getStart(),e=d&&domUtils.findParentByTagName(d,["table"],!0);e&&e.setAttribute("align",b)}},UE.commands.edittable={queryCommandState:function(){return e(this).table?0:-1},execCommand:function(a,b){var c=this.selection.getRange(),d=domUtils.findParentByTagName(c.startContainer,"table");if(d){var e=domUtils.getElementsByTagName(d,"td").concat(domUtils.getElementsByTagName(d,"th"),domUtils.getElementsByTagName(d,"caption"));utils.each(e,function(a){a.style.borderColor=b})}}},UE.commands.edittd={queryCommandState:function(){return e(this).table?0:-1},execCommand:function(a,b){var c=this,d=f(c);if(d)utils.each(d.selectedTds,function(a){a.style.backgroundColor=b});else{var e=c.selection.getStart(),g=e&&domUtils.findParentByTagName(e,["td","th","caption"],!0);g&&(g.style.backgroundColor=b)}}},UE.commands.settablebackground={queryCommandState:function(){return c(this).length>1?0:-1},execCommand:function(a,b){var d,e;d=c(this),e=h(d[0]),e.setBackground(d,b)}},UE.commands.cleartablebackground={queryCommandState:function(){var a=c(this);if(!a.length)return-1;for(var b,d=0;b=a[d++];)if(""!==b.style.backgroundColor)return 0;return-1},execCommand:function(){var a=c(this),b=h(a[0]);b.removeBackground(a)}},UE.commands.interlacetable=UE.commands.uninterlacetable={queryCommandState:function(a){var b=e(this).table;if(!b)return-1;var c=b.getAttribute("interlaced");return"interlacetable"==a?"enabled"===c?-1:0:c&&"disabled"!==c?0:-1},execCommand:function(a,b){var c=e(this).table;"interlacetable"==a?(c.setAttribute("interlaced","enabled"),this.fireEvent("interlacetable",c,b)):(c.setAttribute("interlaced","disabled"),this.fireEvent("uninterlacetable",c))}},UE.commands.setbordervisible={queryCommandState:function(a){var b=e(this).table;return b?0:-1},execCommand:function(){var a=e(this).table;utils.each(domUtils.getElementsByTagName(a,"td"),function(a){a.style.borderWidth="1px",a.style.borderStyle="solid"})}}}(),UE.plugins.table=function(){function a(a){}function b(a,b){c(a,"width",!0),c(a,"height",!0)}function c(a,b,c){a.style[b]&&(c&&a.setAttribute(b,parseInt(a.style[b],10)),a.style[b]="")}function d(a){if("TD"==a.tagName||"TH"==a.tagName)return a;var b;return(b=domUtils.findParentByTagName(a,"td",!0)||domUtils.findParentByTagName(a,"th",!0))?b:null}function e(a){var b=new RegExp(domUtils.fillChar,"g");if(a[browser.ie?"innerText":"textContent"].replace(/^\s*$/,"").replace(b,"").length>0)return 0;for(var c in dtd.$isNotEmpty)if(a.getElementsByTagName(c).length)return 0;return 1}function f(a){return a.pageX||a.pageY?{x:a.pageX,y:a.pageY}:{x:a.clientX+N.document.body.scrollLeft-N.document.body.clientLeft,y:a.clientY+N.document.body.scrollTop-N.document.body.clientTop}}function g(b){if(!A())try{var c,e=d(b.target||b.srcElement);if(R&&(N.body.style.webkitUserSelect="none",(Math.abs(V.x-b.clientX)>T||Math.abs(V.y-b.clientY)>T)&&(t(),R=!1,U=0,v(b))),ca&&ha)return U=0,N.body.style.webkitUserSelect="none",N.selection.getNative()[browser.ie9below?"empty":"removeAllRanges"](),c=f(b),m(N,!0,ca,c,e),void("h"==ca?ga.style.left=k(ha,b)+"px":"v"==ca&&(ga.style.top=l(ha,b)+"px"));if(e){if(N.fireEvent("excludetable",e)===!0)return;c=f(b);var g=n(e,c),i=domUtils.findParentByTagName(e,"table",!0);if(j(i,e,b,!0)){if(N.fireEvent("excludetable",i)===!0)return;N.body.style.cursor="url("+N.options.cursorpath+"h.png),pointer"}else if(j(i,e,b)){if(N.fireEvent("excludetable",i)===!0)return;N.body.style.cursor="url("+N.options.cursorpath+"v.png),pointer"}else{N.body.style.cursor="text";/\d/.test(g)&&(g=g.replace(/\d/,""),e=Y(e).getPreviewCell(e,"v"==g)),m(N,!!e&&!!g,e?g:"",c,e)}}else h(!1,i,N)}catch(o){a(o)}}function h(a,b,c){if(a)i(b,c);else{if(fa)return;la=setTimeout(function(){!fa&&ea&&ea.parentNode&&ea.parentNode.removeChild(ea)},2e3)}}function i(a,b){function c(c,d){clearTimeout(g),g=setTimeout(function(){b.fireEvent("tableClicked",a,d)},300)}function d(c){clearTimeout(g);var d=Y(a),e=a.rows[0].cells[0],f=d.getLastCell(),h=d.getCellsRange(e,f);b.selection.getRange().setStart(e,0).setCursor(!1,!0),d.setSelected(h)}var e=domUtils.getXY(a),f=a.ownerDocument;if(ea&&ea.parentNode)return ea;ea=f.createElement("div"),ea.contentEditable=!1,ea.innerHTML="",ea.style.cssText="width:15px;height:15px;background-image:url("+b.options.UEDITOR_HOME_URL+"dialogs/table/dragicon.png);position: absolute;cursor:move;top:"+(e.y-15)+"px;left:"+e.x+"px;",domUtils.unSelectable(ea),ea.onmouseover=function(a){fa=!0},ea.onmouseout=function(a){fa=!1},domUtils.on(ea,"click",function(a,b){c(b,this)}),domUtils.on(ea,"dblclick",function(a,b){d(b)}),domUtils.on(ea,"dragstart",function(a,b){domUtils.preventDefault(b)});var g;f.body.appendChild(ea)}function j(a,b,c,d){var e=f(c),g=n(b,e);if(d){var h=a.getElementsByTagName("caption")[0],i=h?h.offsetHeight:0;return"v1"==g&&e.y-domUtils.getXY(a).y-i<8}return"h1"==g&&e.x-domUtils.getXY(a).x<8}function k(a,b){var c=Y(a);if(c){var d=c.getSameEndPosCells(a,"x")[0],e=c.getSameStartPosXCells(a)[0],g=f(b).x,h=(d?domUtils.getXY(d).x:domUtils.getXY(c.table).x)+20,i=e?domUtils.getXY(e).x+e.offsetWidth-20:N.body.offsetWidth+5||parseInt(domUtils.getComputedStyle(N.body,"width"),10);return h+=Q,i-=Q,gi?i:g}}function l(b,c){try{var d=domUtils.getXY(b).y,e=f(c).y;return ek[c]?(a=!1,!1):void l.push(d)});var b=a?l:k;utils.each(i,function(a,c){a.width=b[c]-G()})},0)}}}}function q(a){if(_(domUtils.getElementsByTagName(N.body,"td th")),utils.each(N.document.getElementsByTagName("table"),function(a){a.ueTable=null}),aa=M(N,a)){var b=domUtils.findParentByTagName(aa,"table",!0);ut=Y(b),ut&&ut.clearSelected(),da?r(a):(N.document.body.style.webkitUserSelect="",ia=!0,N.addListener("mouseover",x))}}function r(a){browser.ie&&(a=u(a)),t(),R=!0,O=setTimeout(function(){v(a)},W)}function s(a,b){for(var c=[],d=null,e=0,f=a.length;e0&&U--},W),2===U))return U=0,void p(b);if(2!=b.button){var c=this,d=c.selection.getRange(),e=domUtils.findParentByTagName(d.startContainer,"table",!0),f=domUtils.findParentByTagName(d.endContainer,"table",!0);if((e||f)&&(e===f?(e=domUtils.findParentByTagName(d.startContainer,["td","th","caption"],!0),f=domUtils.findParentByTagName(d.endContainer,["td","th","caption"],!0),e!==f&&c.selection.clearRange()):c.selection.clearRange()),ia=!1,c.document.body.style.webkitUserSelect="",ca&&ha&&(c.selection.getNative()[browser.ie9below?"empty":"removeAllRanges"](),U=0,ga=c.document.getElementById("ue_tableDragLine"))){var g=domUtils.getXY(ha),h=domUtils.getXY(ga);switch(ca){case"h":z(ha,h.x-g.x);break;case"v":B(ha,h.y-g.y-ha.offsetHeight)}return ca="",ha=null,I(c),void c.fireEvent("saveScene")}if(aa){var i=Y(aa),j=i?i.selectedTds[0]:null;if(j)d=new dom.Range(c.document),domUtils.isEmptyBlock(j)?d.setStart(j,0).setCursor(!1,!0):d.selectNodeContents(j).shrinkBoundary().setCursor(!1,!0);else if(d=c.selection.getRange().shrinkBoundary(),!d.collapsed){var e=domUtils.findParentByTagName(d.startContainer,["td","th"],!0),f=domUtils.findParentByTagName(d.endContainer,["td","th"],!0);(e&&!f||!e&&f||e&&f&&e!==f)&&d.setCursor(!1,!0)}aa=null,c.removeListener("mouseover",x)}else{var k=domUtils.findParentByTagName(b.target||b.srcElement,"td",!0);if(k||(k=domUtils.findParentByTagName(b.target||b.srcElement,"th",!0)),k&&("TD"==k.tagName||"TH"==k.tagName)){if(c.fireEvent("excludetable",k)===!0)return;d=new dom.Range(c.document),d.setStart(k,0).setCursor(!1,!0)}}c._selectionChange(250,b)}}}function x(a,b){if(!A()){var c=this,d=b.target||b.srcElement;if(ba=domUtils.findParentByTagName(d,"td",!0)||domUtils.findParentByTagName(d,"th",!0),aa&&ba&&("TD"==aa.tagName&&"TD"==ba.tagName||"TH"==aa.tagName&&"TH"==ba.tagName)&&domUtils.findParentByTagName(aa,"table")==domUtils.findParentByTagName(ba,"table")){var e=Y(ba);if(aa!=ba){c.document.body.style.webkitUserSelect="none",c.selection.getNative()[browser.ie9below?"empty":"removeAllRanges"]();var f=e.getCellsRange(aa,ba);e.setSelected(f)}else c.document.body.style.webkitUserSelect="",e.clearSelected()}b.preventDefault?b.preventDefault():b.returnValue=!1}}function y(a,b,c){var d=parseInt(domUtils.getComputedStyle(a,"line-height"),10),e=c+b;b=ef?(c&&g.push({left:a}),!1):void 0})}),g}function D(a,b,c){if(a-=G(),a<0)return 0;a-=E(b);var d=a<0?"left":"right";return a=Math.abs(a),utils.each(c,function(b){var c=b[d];c&&(a=Math.min(a,E(c)-Q))}),a=a<0?0:a,"left"===d?-a:a}function E(a){var b=0,b=a.offsetWidth-G();a.nextSibling||(b-=F(a)),b=b<0?0:b;try{a.width=b}catch(c){}return b}function F(a){if(tab=domUtils.findParentByTagName(a,"table",!1),void 0===tab.offsetVal){var b=a.previousSibling;b?tab.offsetVal=a.offsetWidth-b.offsetWidth===X.borderWidth?X.borderWidth:0:tab.offsetVal=0}return tab.offsetVal}function G(){if(void 0===X.tabcellSpace){var a=N.document.createElement("table"),b=N.document.createElement("tbody"),c=N.document.createElement("tr"),d=N.document.createElement("td"),e=null;d.style.cssText="border: 0;",d.width=1,c.appendChild(d),c.appendChild(e=d.cloneNode(!1)),b.appendChild(c),a.appendChild(b),a.style.cssText="visibility: hidden;",N.body.appendChild(a),X.paddingSpace=d.offsetWidth-1;var f=a.offsetWidth;d.style.cssText="",e.style.cssText="",X.borderWidth=(a.offsetWidth-f)/3,X.tabcellSpace=X.paddingSpace+X.borderWidth,N.body.removeChild(a)}return G=function(){return X.tabcellSpace},X.tabcellSpace}function H(a,b){ia||(ga=a.document.createElement("div"),domUtils.setAttributes(ga,{id:"ue_tableDragLine",unselectable:"on",contenteditable:!1,onresizestart:"return false",ondragstart:"return false",onselectstart:"return false",style:"background-color:blue;position:absolute;padding:0;margin:0;background-image:none;border:0px none;opacity:0;filter:alpha(opacity=0)"}),a.body.appendChild(ga))}function I(a){if(!ia)for(var b;b=a.document.getElementById("ue_tableDragLine");)domUtils.remove(b)}function J(a,b){if(b){var c,d=domUtils.findParentByTagName(b,"table"),e=d.getElementsByTagName("caption"),f=d.offsetWidth,g=d.offsetHeight-(e.length>0?e[0].offsetHeight:0),h=domUtils.getXY(d),i=domUtils.getXY(b);switch(a){case"h":c="height:"+g+"px;top:"+(h.y+(e.length>0?e[0].offsetHeight:0))+"px;left:"+(i.x+b.offsetWidth),ga.style.cssText=c+"px;position: absolute;display:block;background-color:blue;width:1px;border:0; color:blue;opacity:.3;filter:alpha(opacity=30)";break;case"v":c="width:"+f+"px;left:"+h.x+"px;top:"+(i.y+b.offsetHeight),ga.style.cssText=c+"px;overflow:hidden;position: absolute;display:block;background-color:blue;height:1px;border:0;color:blue;opacity:.2;filter:alpha(opacity=20)"}}}function K(a,b){for(var c,d,e=domUtils.getElementsByTagName(a.body,"table"),f=0;d=e[f++];){var g=domUtils.getElementsByTagName(d,"td");g[0]&&(b?(c=g[0].style.borderColor.replace(/\s/g,""),/(#ffffff)|(rgb\(255,255,255\))/gi.test(c)&&domUtils.addClass(d,"noBorderTable")):domUtils.removeClasses(d,"noBorderTable"))}}function L(a,b,c){var d=a.body;return d.offsetWidth-(b?2*parseInt(domUtils.getComputedStyle(d,"margin-left"),10):0)-2*c.tableBorder-(a.options.offsetWidth||0)}function M(a,b){var c=domUtils.findParentByTagName(b.target||b.srcElement,["td","th"],!0),d=null;if(!c)return null;if(d=n(c,f(b)),!c)return null;if("h1"===d&&c.previousSibling){var e=domUtils.getXY(c),g=c.offsetWidth;Math.abs(e.x+g-b.clientX)>g/3&&(c=c.previousSibling)}else if("v1"===d&&c.parentNode.previousSibling){var e=domUtils.getXY(c),h=c.offsetHeight;Math.abs(e.y+h-b.clientY)>h/3&&(c=c.parentNode.previousSibling.firstChild)}return c&&a.fireEvent("excludetable",c)!==!0?c:null}var N=this,O=null,P=null,Q=5,R=!1,S=5,T=10,U=0,V=null,W=360,X=UE.UETable,Y=function(a){return X.getUETable(a)},Z=function(a){return X.getUETableBySelected(a)},$=function(a,b){return X.getDefaultValue(a,b)},_=function(a){return X.removeSelectedClass(a)};N.ready(function(){var a=this,b=a.selection.getText;a.selection.getText=function(){var c=Z(a);if(c){var d="";return utils.each(c.selectedTds,function(a){d+=a[browser.ie?"innerText":"textContent"]}),d}return b.call(a.selection)}});var aa=null,ba=null,ca="",da=!1,ea=null,fa=!1,ga=null,ha=null,ia=!1,ja=!0;N.setOpt({maxColNum:20,maxRowNum:100,defaultCols:5,defaultRows:5,tdvalign:"top",cursorpath:N.options.UEDITOR_HOME_URL+"themes/default/images/cursor_",tableDragable:!1,classList:["ue-table-interlace-color-single","ue-table-interlace-color-double"]}),N.getUETable=Y;var ka={deletetable:1,inserttable:1,cellvalign:1,insertcaption:1,deletecaption:1,inserttitle:1,deletetitle:1,mergeright:1,mergedown:1,mergecells:1,insertrow:1,insertrownext:1,deleterow:1,insertcol:1,insertcolnext:1,deletecol:1,splittocells:1,splittorows:1,splittocols:1,adaptbytext:1,adaptbywindow:1,adaptbycustomer:1,insertparagraph:1,insertparagraphbeforetable:1,averagedistributecol:1,averagedistributerow:1};N.ready(function(){utils.cssRule("table",".selectTdClass{background-color:#edf5fa !important}table.noBorderTable td,table.noBorderTable th,table.noBorderTable caption{border:1px dashed #ddd !important}table{margin-bottom:10px;border-collapse:collapse;display:table;}td,th{padding: 5px 10px;border: 1px solid #DDD;}caption{border:1px dashed #DDD;border-bottom:0;padding:3px;text-align:center;}th{border-top:1px solid #BBB;background-color:#F7F7F7;}table tr.firstRow th{border-top-width:2px;}.ue-table-interlace-color-single{ background-color: #fcfcfc; } .ue-table-interlace-color-double{ background-color: #f7faff; }td p{margin:0;padding:0;}",N.document);var a,c,f;N.addListener("keydown",function(b,d){var g=this,h=d.keyCode||d.which;if(8==h){var i=Z(g);i&&i.selectedTds.length&&(i.isFullCol()?g.execCommand("deletecol"):i.isFullRow()?g.execCommand("deleterow"):g.fireEvent("delcells"),domUtils.preventDefault(d));var j=domUtils.findParentByTagName(g.selection.getStart(),"caption",!0),k=g.selection.getRange();if(k.collapsed&&j&&e(j)){g.fireEvent("saveScene");var l=j.parentNode;domUtils.remove(j),l&&k.setStart(l.rows[0].cells[0],0).setCursor(!1,!0),g.fireEvent("saveScene")}}if(46==h&&(i=Z(g))){g.fireEvent("saveScene");for(var m,n=0;m=i.selectedTds[n++];)domUtils.fillNode(g.document,m);g.fireEvent("saveScene"),domUtils.preventDefault(d)}if(13==h){var o=g.selection.getRange(),j=domUtils.findParentByTagName(o.startContainer,"caption",!0);if(j){var l=domUtils.findParentByTagName(j,"table");return o.collapsed?j&&o.setStart(l.rows[0].cells[0],0).setCursor(!1,!0):(o.deleteContents(),g.fireEvent("saveScene")),void domUtils.preventDefault(d)}if(o.collapsed){var l=domUtils.findParentByTagName(o.startContainer,"table");if(l){var p=l.rows[0].cells[0],q=domUtils.findParentByTagName(g.selection.getStart(),["td","th"],!0),r=l.previousSibling;if(p===q&&(!r||1==r.nodeType&&"TABLE"==r.tagName)&&domUtils.isStartInblock(o)){var s=domUtils.findParent(g.selection.getStart(),function(a){return domUtils.isBlockElm(a)},!0);s&&(/t(h|d)/i.test(s.tagName)||s===q.firstChild)&&(g.execCommand("insertparagraphbeforetable"),domUtils.preventDefault(d))}}}}if((d.ctrlKey||d.metaKey)&&"67"==d.keyCode){a=null;var i=Z(g);if(i){var t=i.selectedTds;c=i.isFullCol(),f=i.isFullRow(),a=[[i.cloneCell(t[0],null,!0)]];for(var m,n=1;m=t[n];n++)m.parentNode!==t[n-1].parentNode?a.push([i.cloneCell(m,null,!0)]):a[a.length-1].push(i.cloneCell(m,null,!0))}}}),N.addListener("tablehasdeleted",function(){m(this,!1,"",null),ea&&domUtils.remove(ea)}),N.addListener("beforepaste",function(d,g){var h=this,i=h.selection.getRange();if(domUtils.findParentByTagName(i.startContainer,"caption",!0)){var j=h.document.createElement("div");return j.innerHTML=g.html,void(g.html=j[browser.ie9below?"innerText":"textContent"])}var k=Z(h);if(a){h.fireEvent("saveScene");var l,m,i=h.selection.getRange(),n=domUtils.findParentByTagName(i.startContainer,["td","th"],!0);if(n){var o=Y(n);if(f){var p=o.getCellInfo(n).rowIndex;"TH"==n.tagName&&p++;for(var q,r=0;q=a[r++];){for(var s,t=o.insertRow(p++,"td"),u=0;s=q[u];u++){var v=t.cells[u];v||(v=t.insertCell(u)),v.innerHTML=s.innerHTML,s.getAttribute("width")&&v.setAttribute("width",s.getAttribute("width")),s.getAttribute("vAlign")&&v.setAttribute("vAlign",s.getAttribute("vAlign")),s.getAttribute("align")&&v.setAttribute("align",s.getAttribute("align")),s.style.cssText&&(v.style.cssText=s.style.cssText)}for(var s,u=0;(s=t.cells[u])&&q[u];u++)s.innerHTML=q[u].innerHTML,q[u].getAttribute("width")&&s.setAttribute("width",q[u].getAttribute("width")),q[u].getAttribute("vAlign")&&s.setAttribute("vAlign",q[u].getAttribute("vAlign")),q[u].getAttribute("align")&&s.setAttribute("align",q[u].getAttribute("align")),q[u].style.cssText&&(s.style.cssText=q[u].style.cssText)}}else{if(c){y=o.getCellInfo(n);for(var s,w=0,u=0,q=a[0];s=q[u++];)w+=s.colSpan||1;for(h.__hasEnterExecCommand=!0,r=0;r1&&(x.rowSpan=1)}var z=$(h),A=h.body.offsetWidth-(ja?2*parseInt(domUtils.getComputedStyle(h.body,"margin-left"),10):0)-2*z.tableBorder-(h.options.offsetWidth||0);h.execCommand("insertHTML",""+k.innerHTML.replace(/>\s*<").replace(/\bth\b/gi,"td")+"
    ")}return h.fireEvent("contentchange"),h.fireEvent("saveScene"),g.html="",!0}var B,j=h.document.createElement("div");j.innerHTML=g.html,B=j.getElementsByTagName("table"),domUtils.findParentByTagName(h.selection.getStart(),"table")?(utils.each(B,function(a){domUtils.remove(a)}),domUtils.findParentByTagName(h.selection.getStart(),"caption",!0)&&(j.innerHTML=j[browser.ie?"innerText":"textContent"])):utils.each(B,function(a){b(a,!0),domUtils.removeAttributes(a,["style","border"]),utils.each(domUtils.getElementsByTagName(a,"td"),function(a){e(a)&&domUtils.fillNode(h.document,a),b(a,!0)})}),g.html=j.innerHTML}),N.addListener("afterpaste",function(){utils.each(domUtils.getElementsByTagName(N.body,"table"),function(a){if(a.offsetWidth>N.body.offsetWidth){var b=$(N,a);a.style.width=N.body.offsetWidth-(ja?2*parseInt(domUtils.getComputedStyle(N.body,"margin-left"),10):0)-2*b.tableBorder-(N.options.offsetWidth||0)+"px"}})}),N.addListener("blur",function(){a=null});var i;N.addListener("keydown",function(){clearTimeout(i),i=setTimeout(function(){var a=N.selection.getRange(),b=domUtils.findParentByTagName(a.startContainer,["th","td"],!0);if(b){var c=b.parentNode.parentNode.parentNode;c.offsetWidth>c.getAttribute("width")&&(b.style.wordBreak="break-all")}},100)}),N.addListener("selectionchange",function(){m(N,!1,"",null)}),N.addListener("contentchange",function(){var a=this;if(I(a),!Z(a)){var b=a.selection.getRange(),c=b.startContainer;c=domUtils.findParentByTagName(c,["td","th"],!0),utils.each(domUtils.getElementsByTagName(a.document,"table"),function(b){a.fireEvent("excludetable",b)!==!0&&(b.ueTable=new X(b),b.onmouseover=function(){a.fireEvent("tablemouseover",b)},b.onmousemove=function(){a.fireEvent("tablemousemove",b),a.options.tableDragable&&h(!0,this,a),utils.defer(function(){a.fireEvent("contentchange",50)},!0)},b.onmouseout=function(){a.fireEvent("tablemouseout",b),m(a,!1,"",null),I(a)},b.onclick=function(b){b=a.window.event||b;var c=d(b.target||b.srcElement);if(c){var e,f=Y(c),g=f.table,h=f.getCellInfo(c),i=a.selection.getRange();if(j(g,c,b,!0)){var k=f.getCell(f.indexTable[f.rowsNum-1][h.colIndex].rowIndex,f.indexTable[f.rowsNum-1][h.colIndex].cellIndex);return void(b.shiftKey&&f.selectedTds.length?f.selectedTds[0]!==k?(e=f.getCellsRange(f.selectedTds[0],k),f.setSelected(e)):i&&i.selectNodeContents(k).select():c!==k?(e=f.getCellsRange(c,k),f.setSelected(e)):i&&i.selectNodeContents(k).select())}if(j(g,c,b)){var l=f.getCell(f.indexTable[h.rowIndex][f.colsNum-1].rowIndex,f.indexTable[h.rowIndex][f.colsNum-1].cellIndex);b.shiftKey&&f.selectedTds.length?f.selectedTds[0]!==l?(e=f.getCellsRange(f.selectedTds[0],l),f.setSelected(e)):i&&i.selectNodeContents(l).select():c!==l?(e=f.getCellsRange(c,l),f.setSelected(e)):i&&i.selectNodeContents(l).select()}}})}),K(a,!0)}}),domUtils.on(N.document,"mousemove",g),domUtils.on(N.document,"mouseout",function(a){var b=a.target||a.srcElement;"TABLE"==b.tagName&&m(N,!1,"",null)}),N.addListener("interlacetable",function(a,b,c){if(b)for(var d=this,e=b.rows,f=e.length,g=function(a,b,c){return a[b]?a[b]:c?a[b%a.length]:""},h=0;h1?k:f.getCellInfo(d).rowIndex;var g=f.getTabNextCell(d,k);g?e(g)?a.setStart(g,0).setCursor(!1,!0):a.selectNodeContents(g).select():(N.fireEvent("saveScene"),N.__hasEnterExecCommand=!0,this.execCommand("insertrownext"),N.__hasEnterExecCommand=!1,a=this.selection.getRange(),a.setStart(c.rows[c.rows.length-1].cells[0],0).setCursor(),N.fireEvent("saveScene"))}return!0}}),browser.ie&&N.addListener("selectionchange",function(){m(this,!1,"",null)}),N.addListener("keydown",function(a,b){var c=this,d=b.keyCode||b.which;if(8!=d&&46!=d){var e=!(b.ctrlKey||b.metaKey||b.shiftKey||b.altKey);e&&_(domUtils.getElementsByTagName(c.body,"td"));var f=Z(c);f&&e&&f.clearSelected()}}),N.addListener("beforegetcontent",function(){K(this,!1),browser.ie&&utils.each(this.document.getElementsByTagName("caption"),function(a){domUtils.isEmptyNode(a)&&(a.innerHTML=" ")})}),N.addListener("aftergetcontent",function(){K(this,!0)}),N.addListener("getAllHtml",function(){_(N.document.getElementsByTagName("td"))}),N.addListener("fullscreenchanged",function(a,b){if(!b){var c=this.body.offsetWidth/document.body.offsetWidth,d=domUtils.getElementsByTagName(this.body,"table");utils.each(d,function(a){if(a.offsetWidth1||c[e].getAttribute("rowspan")>1)return-1;return b?"enablesort"==a^"sortEnabled"!=b.getAttribute("data-sort")?-1:0:-1},execCommand:function(a){var b=d(this).table;b.setAttribute("data-sort","enablesort"==a?"sortEnabled":"sortDisabled"),"enablesort"==a?domUtils.addClass(b,"sortEnabled"):domUtils.removeClasses(b,"sortEnabled")}}},UE.plugins.contextmenu=function(){var a=this;if(a.setOpt("enableContextMenu",!0),a.getOpt("enableContextMenu")!==!1){var b,c=a.getLang("contextMenu"),d=a.options.contextMenu||[{label:c.selectall,cmdName:"selectall"},{label:c.cleardoc,cmdName:"cleardoc",exec:function(){confirm(c.confirmclear)&&this.execCommand("cleardoc")}},"-",{label:c.unlink,cmdName:"unlink"},"-",{group:c.paragraph,icon:"justifyjustify",subMenu:[{label:c.justifyleft,cmdName:"justify",value:"left"},{label:c.justifyright,cmdName:"justify",value:"right"},{label:c.justifycenter,cmdName:"justify",value:"center"},{label:c.justifyjustify,cmdName:"justify",value:"justify"}]},"-",{group:c.table,icon:"table",subMenu:[{label:c.inserttable,cmdName:"inserttable"},{label:c.deletetable,cmdName:"deletetable"},"-",{label:c.deleterow,cmdName:"deleterow"},{label:c.deletecol,cmdName:"deletecol"},{label:c.insertcol,cmdName:"insertcol"},{label:c.insertcolnext,cmdName:"insertcolnext"},{label:c.insertrow,cmdName:"insertrow"},{label:c.insertrownext,cmdName:"insertrownext"},"-",{label:c.insertcaption,cmdName:"insertcaption"},{label:c.deletecaption,cmdName:"deletecaption"},{label:c.inserttitle,cmdName:"inserttitle"},{label:c.deletetitle,cmdName:"deletetitle"},{label:c.inserttitlecol,cmdName:"inserttitlecol"},{label:c.deletetitlecol,cmdName:"deletetitlecol"},"-",{label:c.mergecells,cmdName:"mergecells"},{label:c.mergeright,cmdName:"mergeright"},{label:c.mergedown,cmdName:"mergedown"},"-",{label:c.splittorows,cmdName:"splittorows"},{label:c.splittocols,cmdName:"splittocols"},{label:c.splittocells,cmdName:"splittocells"},"-",{label:c.averageDiseRow,cmdName:"averagedistributerow"},{label:c.averageDisCol,cmdName:"averagedistributecol"},"-",{label:c.edittd,cmdName:"edittd",exec:function(){UE.ui.edittd&&new UE.ui.edittd(this),this.getDialog("edittd").open()}},{label:c.edittable,cmdName:"edittable",exec:function(){UE.ui.edittable&&new UE.ui.edittable(this),this.getDialog("edittable").open()}},{label:c.setbordervisible,cmdName:"setbordervisible"}]},{group:c.tablesort,icon:"tablesort",subMenu:[{label:c.enablesort,cmdName:"enablesort"},{label:c.disablesort,cmdName:"disablesort"},"-",{label:c.reversecurrent,cmdName:"sorttable",value:"reversecurrent"},{label:c.orderbyasc,cmdName:"sorttable",value:"orderbyasc"},{label:c.reversebyasc,cmdName:"sorttable",value:"reversebyasc"},{label:c.orderbynum,cmdName:"sorttable",value:"orderbynum"},{label:c.reversebynum,cmdName:"sorttable",value:"reversebynum"}]},{group:c.borderbk,icon:"borderBack",subMenu:[{label:c.setcolor,cmdName:"interlacetable",exec:function(){this.execCommand("interlacetable")}},{label:c.unsetcolor,cmdName:"uninterlacetable",exec:function(){this.execCommand("uninterlacetable")}},{label:c.setbackground,cmdName:"settablebackground",exec:function(){this.execCommand("settablebackground",{repeat:!0,colorList:["#bbb","#ccc"]})}},{label:c.unsetbackground,cmdName:"cleartablebackground",exec:function(){this.execCommand("cleartablebackground")}},{label:c.redandblue,cmdName:"settablebackground",exec:function(){this.execCommand("settablebackground",{repeat:!0,colorList:["red","blue"]})}},{label:c.threecolorgradient,cmdName:"settablebackground",exec:function(){this.execCommand("settablebackground",{repeat:!0,colorList:["#aaa","#bbb","#ccc"]})}}]},{group:c.aligntd,icon:"aligntd",subMenu:[{cmdName:"cellalignment",value:{align:"left",vAlign:"top"}},{cmdName:"cellalignment",value:{align:"center",vAlign:"top"}},{cmdName:"cellalignment",value:{align:"right",vAlign:"top"}},{cmdName:"cellalignment",value:{align:"left",vAlign:"middle"}},{cmdName:"cellalignment",value:{align:"center",vAlign:"middle"}},{cmdName:"cellalignment",value:{align:"right",vAlign:"middle"}},{cmdName:"cellalignment",value:{align:"left",vAlign:"bottom"}},{cmdName:"cellalignment",value:{align:"center",vAlign:"bottom"}},{cmdName:"cellalignment",value:{align:"right",vAlign:"bottom"}}]},{group:c.aligntable,icon:"aligntable",subMenu:[{cmdName:"tablealignment",className:"left",label:c.tableleft,value:"left"},{cmdName:"tablealignment",className:"center",label:c.tablecenter,value:"center"},{cmdName:"tablealignment",className:"right",label:c.tableright,value:"right"}]},"-",{label:c.insertparagraphbefore,cmdName:"insertparagraph",value:!0},{label:c.insertparagraphafter,cmdName:"insertparagraph"},{label:c.copy,cmdName:"copy"},{label:c.paste,cmdName:"paste"}];if(d.length){var e=UE.ui.uiUtils;a.addListener("contextmenu",function(f,g){var h=e.getViewportOffsetByEvent(g);a.fireEvent("beforeselectionchange"),b&&b.destroy();for(var i,j=0,k=[];i=d[j];j++){var l;!function(b){function d(){switch(b.icon){case"table":return a.getLang("contextMenu.table");case"justifyjustify":return a.getLang("contextMenu.paragraph");case"aligntd":return a.getLang("contextMenu.aligntd");case"aligntable":return a.getLang("contextMenu.aligntable");case"tablesort":return c.tablesort;case"borderBack":return c.borderbk;default:return""}}if("-"==b)(l=k[k.length-1])&&"-"!==l&&k.push("-");else if(b.hasOwnProperty("group")){for(var e,f=0,g=[];e=b.subMenu[f];f++)!function(b){"-"==b?(l=g[g.length-1])&&"-"!==l?g.push("-"):g.splice(g.length-1):(a.commands[b.cmdName]||UE.commands[b.cmdName]||b.query)&&(b.query?b.query():a.queryCommandState(b.cmdName))>-1&&g.push({label:b.label||a.getLang("contextMenu."+b.cmdName+(b.value||""))||"",className:"edui-for-"+b.cmdName+(b.className?" edui-for-"+b.cmdName+"-"+b.className:""),onclick:b.exec?function(){b.exec.call(a)}:function(){a.execCommand(b.cmdName,b.value)}})}(e);g.length&&k.push({label:d(),className:"edui-for-"+b.icon,subMenu:{items:g,editor:a}})}else(a.commands[b.cmdName]||UE.commands[b.cmdName]||b.query)&&(b.query?b.query.call(a):a.queryCommandState(b.cmdName))>-1&&k.push({label:b.label||a.getLang("contextMenu."+b.cmdName),className:"edui-for-"+(b.icon?b.icon:b.cmdName+(b.value||"")),onclick:b.exec?function(){b.exec.call(a)}:function(){a.execCommand(b.cmdName,b.value)}})}(i)}if("-"==k[k.length-1]&&k.pop(),b=new UE.ui.Menu({items:k,className:"edui-contextmenu",editor:a}),b.render(),b.showAt(h),a.fireEvent("aftershowcontextmenu",b),domUtils.preventDefault(g),browser.ie){var m;try{m=a.selection.getNative().createRange()}catch(n){return}if(m.item){var o=new dom.Range(a.document);o.selectNode(m.item(0)).select(!0,!0)}}}),a.addListener("aftershowcontextmenu",function(b,c){if(a.zeroclipboard){var d=c.items;for(var e in d)"edui-for-copy"==d[e].className&&a.zeroclipboard.clip(d[e].getDom())}})}}},UE.plugins.shortcutmenu=function(){var a,b=this,c=b.options.shortcutMenu||[];c.length&&(b.addListener("contextmenu mouseup",function(b,d){var e=this,f={type:b,target:d.target||d.srcElement,screenX:d.screenX,screenY:d.screenY,clientX:d.clientX,clientY:d.clientY};if(setTimeout(function(){var d=e.selection.getRange();d.collapsed!==!1&&"contextmenu"!=b||(a||(a=new baidu.editor.ui.ShortCutMenu({editor:e,items:c,theme:e.options.theme,className:"edui-shortcutmenu"}),a.render(),e.fireEvent("afterrendershortcutmenu",a)),a.show(f,!!UE.plugins.contextmenu))}),"contextmenu"==b&&(domUtils.preventDefault(d),browser.ie9below)){var g;try{g=e.selection.getNative().createRange()}catch(d){return}if(g.item){var h=new dom.Range(e.document);h.selectNode(g.item(0)).select(!0,!0)}}}),b.addListener("keydown",function(b){"keydown"==b&&a&&!a.isHidden&&a.hide()}))},UE.plugins.basestyle=function(){var a={bold:["strong","b"],italic:["em","i"],subscript:["sub"],superscript:["sup"]},b=function(a,b){return domUtils.filterNodeList(a.selection.getStartElementPath(),b)},c=this;c.addshortcutkey({Bold:"ctrl+66",Italic:"ctrl+73",Underline:"ctrl+85"}),c.addInputRule(function(a){utils.each(a.getNodesByTagName("b i"),function(a){switch(a.tagName){case"b":a.tagName="strong";break;case"i":a.tagName="em"}})});for(var d in a)!function(a,d){c.commands[a]={execCommand:function(a){var e=c.selection.getRange(),f=b(this,d);if(e.collapsed){if(f){var g=c.document.createTextNode("");e.insertNode(g).removeInlineStyle(d),e.setStartBefore(g),domUtils.remove(g)}else{var h=e.document.createElement(d[0]);"superscript"!=a&&"subscript"!=a||(g=c.document.createTextNode(""),e.insertNode(g).removeInlineStyle(["sub","sup"]).setStartBefore(g).collapse(!0)),e.insertNode(h).setStart(h,0)}e.collapse(!0)}else"superscript"!=a&&"subscript"!=a||f&&f.tagName.toLowerCase()==a||e.removeInlineStyle(["sub","sup"]),f?e.removeInlineStyle(d):e.applyInlineStyle(d[0]);e.select()},queryCommandState:function(){return b(this,d)?1:0}}}(d,a[d])},UE.plugins.elementpath=function(){var a,b,c=this;c.setOpt("elementPathEnabled",!0),c.options.elementPathEnabled&&(c.commands.elementpath={execCommand:function(d,e){var f=b[e],g=c.selection.getRange();a=1*e,g.selectNode(f).select()},queryCommandValue:function(){var c=[].concat(this.selection.getStartElementPath()).reverse(),d=[];b=c;for(var e,f=0;e=c[f];f++)if(3!=e.nodeType){var g=e.tagName.toLowerCase();if("img"==g&&e.getAttribute("anchorname")&&(g="anchor"),d[f]=g,a==f){a=-1;break}}return d}})},UE.plugins.formatmatch=function(){function a(f,g){function h(a){return m&&a.selectNode(m),a.applyInlineStyle(d[d.length-1].tagName,null,d)}if(browser.webkit)var i="IMG"==g.target.tagName?g.target:null;c.undoManger&&c.undoManger.save();var j=c.selection.getRange(),k=i||j.getClosedNode();if(b&&k&&"IMG"==k.tagName)k.style.cssText+=";float:"+(b.style.cssFloat||b.style.styleFloat||"none")+";display:"+(b.style.display||"inline"),b=null;else if(!b){var l=j.collapsed;if(l){var m=c.document.createTextNode("match");j.insertNode(m).select()}c.__hasEnterExecCommand=!0;var n=c.options.removeFormatAttributes;c.options.removeFormatAttributes="",c.execCommand("removeformat"),c.options.removeFormatAttributes=n,c.__hasEnterExecCommand=!1,j=c.selection.getRange(),d.length&&h(j),m&&j.setStartBefore(m).collapse(!0),j.select(),m&&domUtils.remove(m)}c.undoManger&&c.undoManger.save(),c.removeListener("mouseup",a),e=0}var b,c=this,d=[],e=0;c.addListener("reset",function(){d=[],e=0}),c.commands.formatmatch={execCommand:function(f){if(e)return e=0,d=[],void c.removeListener("mouseup",a);var g=c.selection.getRange();if(b=g.getClosedNode(),!b||"IMG"!=b.tagName){g.collapse(!0).shrinkBoundary();var h=g.startContainer;d=domUtils.findParents(h,!0,function(a){return!domUtils.isBlockElm(a)&&1==a.nodeType});for(var i,j=0;i=d[j];j++)if("A"==i.tagName){d.splice(j,1);break}}c.addListener("mouseup",a),e=1},queryCommandState:function(){return e},notNeedUndo:1}},UE.plugin.register("searchreplace",function(){function a(a,b,c){var d=b.searchStr;b.dir==-1&&(a=a.split("").reverse().join(""),d=d.split("").reverse().join(""),c=a.length-c);for(var e,f=new RegExp(d,"g"+(b.casesensitive?"":"i"));e=f.exec(a);)if(e.index>=c)return b.dir==-1?a.length-e.index-b.searchStr.length:e.index;return-1}function b(b,c,d){var e,f,h=d.all||1==d.dir?"getNextDomNode":"getPreDomNode";domUtils.isBody(b)&&(b=b.firstChild);for(var i=1;b;){if(e=3==b.nodeType?b.nodeValue:b[browser.ie?"innerText":"textContent"],f=a(e,d,c),i=0,f!=-1)return{node:b,index:f};for(b=domUtils[h](b);b&&g[b.nodeName.toLowerCase()];)b=domUtils[h](b,!0);b&&(c=d.dir==-1?(3==b.nodeType?b.nodeValue:b[browser.ie?"innerText":"textContent"]).length:0)}}function c(a,b,d){for(var e,f=0,g=a.firstChild,h=0;g;){if(3==g.nodeType){if(h=g.nodeValue.replace(/(^[\t\r\n]+)|([\t\r\n]+$)/,"").length,f+=h,f>=b)return{node:g,index:h-(f-b)}}else if(!dtd.$empty[g.tagName]&&(h=g[browser.ie?"innerText":"textContent"].replace(/(^[\t\r\n]+)|([\t\r\n]+$)/,"").length,f+=h,f>=b&&(e=c(g,h-(f-b),d))))return e;g=domUtils.getNextDomNode(g)}}function d(a,d){var f,g=a.selection.getRange(),h=d.searchStr,i=a.document.createElement("span");if(i.innerHTML="$$ueditor_searchreplace_key$$",g.shrinkBoundary(!0),!g.collapsed){g.select();var j=a.selection.getText();if(new RegExp("^"+d.searchStr+"$",d.casesensitive?"":"i").test(j)){if(void 0!=d.replaceStr)return e(g,d.replaceStr),g.select(),!0;g.collapse(d.dir==-1)}}g.insertNode(i),g.enlargeToBlockElm(!0),f=g.startContainer;var k=f[browser.ie?"innerText":"textContent"].indexOf("$$ueditor_searchreplace_key$$");g.setStartBefore(i),domUtils.remove(i);var l=b(f,k,d);if(l){var m=c(l.node,l.index,h),n=c(l.node,l.index+h.length,h);return g.setStart(m.node,m.index).setEnd(n.node,n.index),void 0!==d.replaceStr&&e(g,d.replaceStr),g.select(),!0}g.setCursor()}function e(a,b){b=f.document.createTextNode(b),a.deleteContents().insertNode(b)}var f=this,g={table:1,tbody:1,tr:1,ol:1,ul:1};return{commands:{searchreplace:{execCommand:function(a,b){utils.extend(b,{all:!1,casesensitive:!1,dir:1},!0);var c=0;if(b.all){var e=f.selection.getRange(),g=f.body.firstChild;for(g&&1==g.nodeType?(e.setStart(g,0),e.shrinkBoundary(!0)):3==g.nodeType&&e.setStartBefore(g),e.collapse(!0).select(!0),void 0!==b.replaceStr&&f.fireEvent("saveScene");d(this,b);)c++;c&&f.fireEvent("saveScene")}else void 0!==b.replaceStr&&f.fireEvent("saveScene"),d(this,b)&&c++,c&&f.fireEvent("saveScene");return c},notNeedUndo:1}}}}),UE.plugins.customstyle=function(){var a=this;a.setOpt({customstyle:[{tag:"h1",name:"tc",style:"font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:center;margin:0 0 20px 0;"},{tag:"h1",name:"tl",style:"font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:left;margin:0 0 10px 0;"},{tag:"span",name:"im",style:"font-size:16px;font-style:italic;font-weight:bold;line-height:18px;"},{tag:"span",name:"hi",style:"font-size:16px;font-style:italic;font-weight:bold;color:rgb(51, 153, 204);line-height:18px;"}]}),a.commands.customstyle={execCommand:function(a,b){var c,d,e=this,f=b.tag,g=domUtils.findParent(e.selection.getStart(),function(a){return a.getAttribute("label")},!0),h={};for(var i in b)void 0!==b[i]&&(h[i]=b[i]);if(delete h.tag,g&&g.getAttribute("label")==b.label){if(c=this.selection.getRange(),d=c.createBookmark(),c.collapsed)if(dtd.$block[g.tagName]){var j=e.document.createElement("p");domUtils.moveChild(g,j),g.parentNode.insertBefore(j,g),domUtils.remove(g)}else domUtils.remove(g,!0);else{var k=domUtils.getCommonAncestor(d.start,d.end),l=domUtils.getElementsByTagName(k,f);new RegExp(f,"i").test(k.tagName)&&l.push(k);for(var m,n=0;m=l[n++];)if(m.getAttribute("label")==b.label){var o=domUtils.getPosition(m,d.start),p=domUtils.getPosition(m,d.end);if((o&domUtils.POSITION_FOLLOWING||o&domUtils.POSITION_CONTAINS)&&(p&domUtils.POSITION_PRECEDING||p&domUtils.POSITION_CONTAINS)&&dtd.$block[f]){var j=e.document.createElement("p");domUtils.moveChild(m,j),m.parentNode.insertBefore(j,m)}domUtils.remove(m,!0)}g=domUtils.findParent(k,function(a){return a.getAttribute("label")==b.label},!0),g&&domUtils.remove(g,!0)}c.moveToBookmark(d).select()}else if(dtd.$block[f]){if(this.execCommand("paragraph",f,h,"customstyle"),c=e.selection.getRange(),!c.collapsed){c.collapse(),g=domUtils.findParent(e.selection.getStart(),function(a){return a.getAttribute("label")==b.label},!0);var q=e.document.createElement("p");domUtils.insertAfter(g,q),domUtils.fillNode(e.document,q),c.setStart(q,0).setCursor()}}else{if(c=e.selection.getRange(),c.collapsed)return g=e.document.createElement(f),domUtils.setAttributes(g,h),void c.insertNode(g).setStart(g,0).setCursor();d=c.createBookmark(),c.applyInlineStyle(f,h).moveToBookmark(d).select()}},queryCommandValue:function(){var a=domUtils.filterNodeList(this.selection.getStartElementPath(),function(a){return a.getAttribute("label")});return a?a.getAttribute("label"):""}},a.addListener("keyup",function(b,c){var d=c.keyCode||c.which;if(32==d||13==d){var e=a.selection.getRange();if(e.collapsed){var f=domUtils.findParent(a.selection.getStart(),function(a){return a.getAttribute("label")},!0);if(f&&dtd.$block[f.tagName]&&domUtils.isEmptyNode(f)){var g=a.document.createElement("p");domUtils.insertAfter(f,g),domUtils.fillNode(a.document,g),domUtils.remove(f),e.setStart(g,0).setCursor()}}}})},UE.plugins.catchremoteimage=function(){var me=this,ajax=UE.ajax;me.options.catchRemoteImageEnable!==!1&&(me.setOpt({catchRemoteImageEnable:!1}),me.addListener("afterpaste",function(){me.fireEvent("catchRemoteImage")}),me.addListener("catchRemoteImage",function(){function catchremoteimage(a,b){var c=utils.serializeParam(me.queryCommandValue("serverparam"))||"",d=utils.formatUrl(catcherActionUrl+(catcherActionUrl.indexOf("?")==-1?"?":"&")+c),e=utils.isCrossDomainUrl(d),f={method:"POST",dataType:e?"jsonp":"",timeout:6e4,onsuccess:b.success,onerror:b.error};f[catcherFieldName]=a,ajax.request(d,f)}for(var catcherLocalDomain=me.getOpt("catcherLocalDomain"),catcherActionUrl=me.getActionUrl(me.getOpt("catcherActionName")),catcherUrlPrefix=me.getOpt("catcherUrlPrefix"),catcherFieldName=me.getOpt("catcherFieldName"),remoteImages=[],imgs=domUtils.getElementsByTagName(me.document,"img"),test=function(a,b){if(a.indexOf(location.host)!=-1||/(^\.)|(^\/)/.test(a))return!0;if(b)for(var c,d=0;c=b[d++];)if(a.indexOf(c)!==-1)return!0;return!1},i=0,ci;ci=imgs[i++];)if(!ci.getAttribute("word_img")){var src=ci.getAttribute("_src")||ci.src||"";/^(https?|ftp):/i.test(src)&&!test(src,catcherLocalDomain)&&remoteImages.push(src)}remoteImages.length&&catchremoteimage(remoteImages,{success:function(r){try{var info=void 0!==r.state?r:eval("("+r.responseText+")")}catch(e){return}var i,j,ci,cj,oldSrc,newSrc,list=info.list;for(i=0;ci=imgs[i++];)for(oldSrc=ci.getAttribute("_src")||ci.src||"",j=0;cj=list[j++];)if(oldSrc==cj.source&&"SUCCESS"==cj.state){newSrc=catcherUrlPrefix+cj.url,domUtils.setAttributes(ci,{src:newSrc,_src:newSrc});break}me.fireEvent("catchremotesuccess")},error:function(){me.fireEvent("catchremoteerror")}})}))},UE.plugin.register("snapscreen",function(){function getLocation(a){var b,c=document.createElement("a"),d=utils.serializeParam(me.queryCommandValue("serverparam"))||"";return c.href=a,browser.ie&&(c.href=c.href),b=c.search,d&&(b=b+(b.indexOf("?")==-1?"?":"&")+d,b=b.replace(/[&]+/gi,"&")),{port:c.port,hostname:c.hostname,path:c.pathname+b||+c.hash}}var me=this,snapplugin;return{commands:{snapscreen:{execCommand:function(cmd){function onSuccess(rs){try{if(rs=eval("("+rs+")"),"SUCCESS"==rs.state){var opt=me.options;me.execCommand("insertimage",{src:opt.snapscreenUrlPrefix+rs.url,_src:opt.snapscreenUrlPrefix+rs.url,alt:rs.title||"",floatStyle:opt.snapscreenImgAlign})}else alert(rs.state)}catch(e){alert(lang.callBackErrorMsg)}}var url,local,res,lang=me.getLang("snapScreen_plugin");if(!snapplugin){var container=me.container,doc=me.container.ownerDocument||me.container.document;snapplugin=doc.createElement("object");try{snapplugin.type="application/x-pluginbaidusnap"}catch(e){return}snapplugin.style.cssText="position:absolute;left:-9999px;width:0;height:0;",snapplugin.setAttribute("width","0"),snapplugin.setAttribute("height","0"),container.appendChild(snapplugin)}url=me.getActionUrl(me.getOpt("snapscreenActionName")),local=getLocation(url),setTimeout(function(){try{res=snapplugin.saveSnapshot(local.hostname,local.path,local.port)}catch(a){return void me.ui._dialogs.snapscreenDialog.open()}onSuccess(res)},50)},queryCommandState:function(){return navigator.userAgent.indexOf("Windows",0)!=-1?0:-1}}}}}),UE.commands.insertparagraph={execCommand:function(a,b){for(var c,d=this,e=d.selection.getRange(),f=e.startContainer;f&&!domUtils.isBody(f);)c=f,f=f.parentNode;if(c){var g=d.document.createElement("p");b?c.parentNode.insertBefore(g,c):c.parentNode.insertBefore(g,c.nextSibling),domUtils.fillNode(d.document,g),e.setStart(g,0).setCursor(!1,!0)}}},UE.plugin.register("webapp",function(){function a(a,c){return c?'':'"}var b=this;return{outputRule:function(b){utils.each(b.getNodesByTagName("img"),function(b){var c;if("edui-faked-webapp"==b.getAttr("class")){c=a({title:b.getAttr("title"),width:b.getAttr("width"),height:b.getAttr("height"),align:b.getAttr("align"),cssfloat:b.getStyle("float"),url:b.getAttr("_url"),logo:b.getAttr("_logo_url")},!0);var d=UE.uNode.createElement(c);b.parentNode.replaceChild(d,b)}})},inputRule:function(b){utils.each(b.getNodesByTagName("iframe"),function(b){if("edui-faked-webapp"==b.getAttr("class")){var c=UE.uNode.createElement(a({title:b.getAttr("title"),width:b.getAttr("width"),height:b.getAttr("height"),align:b.getAttr("align"),cssfloat:b.getStyle("float"),url:b.getAttr("src"),logo:b.getAttr("logo_url")}));b.parentNode.replaceChild(c,b)}})},commands:{webapp:{execCommand:function(b,c){var d=this,e=a(utils.extend(c,{align:"none"}),!1);d.execCommand("inserthtml",e)},queryCommandState:function(){var a=this,b=a.selection.getRange().getClosedNode(),c=b&&"edui-faked-webapp"==b.className;return c?1:0}}}}}),UE.plugins.template=function(){UE.commands.template={execCommand:function(a,b){b.html&&this.execCommand("inserthtml",b.html)}},this.addListener("click",function(a,b){var c=b.target||b.srcElement,d=this.selection.getRange(),e=domUtils.findParent(c,function(a){if(a.className&&domUtils.hasClass(a,"ue_t"))return a},!0);e&&d.selectNode(e).shrinkBoundary().select()}),this.addListener("keydown",function(a,b){var c=this.selection.getRange();if(!c.collapsed&&!(b.ctrlKey||b.metaKey||b.shiftKey||b.altKey)){var d=domUtils.findParent(c.startContainer,function(a){if(a.className&&domUtils.hasClass(a,"ue_t"))return a},!0);d&&domUtils.removeClasses(d,["ue_t"])}})},UE.plugin.register("music",function(){function a(a,c,d,e,f,g){return g?'':"'}var b=this;return{outputRule:function(b){utils.each(b.getNodesByTagName("img"),function(b){var c;if("edui-faked-music"==b.getAttr("class")){var d=b.getStyle("float"),e=b.getAttr("align");c=a(b.getAttr("_url"),b.getAttr("width"),b.getAttr("height"),e,d,!0);var f=UE.uNode.createElement(c);b.parentNode.replaceChild(f,b)}})},inputRule:function(b){utils.each(b.getNodesByTagName("embed"),function(b){if("edui-faked-music"==b.getAttr("class")){var c=b.getStyle("float"),d=b.getAttr("align");html=a(b.getAttr("src"),b.getAttr("width"),b.getAttr("height"),d,c,!1);var e=UE.uNode.createElement(html);b.parentNode.replaceChild(e,b)}})},commands:{music:{execCommand:function(b,c){var d=this,e=a(c.url,c.width||400,c.height||95,"none",!1);d.execCommand("inserthtml",e)},queryCommandState:function(){var a=this,b=a.selection.getRange().getClosedNode(),c=b&&"edui-faked-music"==b.className;return c?1:0}}}}}),UE.plugin.register("autoupload",function(){function a(a,b){var c,d,e,f,g,h,i,j,k=b,l=/image\/\w+/i.test(a.type)?"image":"file",m="loading_"+(+new Date).toString(36);if(c=k.getOpt(l+"FieldName"),d=k.getOpt(l+"UrlPrefix"),e=k.getOpt(l+"MaxSize"),f=k.getOpt(l+"AllowFiles"),g=k.getActionUrl(k.getOpt(l+"ActionName")),i=function(a){var b=k.document.getElementById(m);b&&domUtils.remove(b),k.fireEvent("showmessage",{id:m,content:a,type:"error",timeout:4e3})},"image"==l?(h='',j=function(a){var b=d+a.url,c=k.document.getElementById(m);c&&(c.setAttribute("src",b),c.setAttribute("_src",b),c.setAttribute("title",a.title||""),c.setAttribute("alt",a.original||""),c.removeAttribute("id"),domUtils.removeClasses(c,"loadingclass"))}):(h='

    ',j=function(a){var b=d+a.url,c=k.document.getElementById(m),e=k.selection.getRange(),f=e.createBookmark();e.selectNode(c).select(),k.execCommand("insertfile",{url:b}),e.moveToBookmark(f).select()}),k.execCommand("inserthtml",h),!k.getOpt(l+"ActionName"))return void i(k.getLang("autoupload.errorLoadConfig"));if(a.size>e)return void i(k.getLang("autoupload.exceedSizeError"));var n=a.name?a.name.substr(a.name.lastIndexOf(".")):"";if(n&&"image"!=l||f&&(f.join("")+".").indexOf(n.toLowerCase()+".")==-1)return void i(k.getLang("autoupload.exceedTypeError"));var o=new XMLHttpRequest,p=new FormData,q=utils.serializeParam(k.queryCommandValue("serverparam"))||"",r=utils.formatUrl(g+(g.indexOf("?")==-1?"?":"&")+q);p.append(c,a,a.name||"blob."+a.type.substr("image/".length)),p.append("type","ajax"),o.open("post",r,!0),o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.addEventListener("load",function(a){try{var b=new Function("return "+utils.trim(a.target.response))();"SUCCESS"==b.state&&b.url?j(b):i(b.state)}catch(c){i(k.getLang("autoupload.loadError"))}}),o.send(p)}function b(a){return a.clipboardData&&a.clipboardData.items&&1==a.clipboardData.items.length&&/^image\//.test(a.clipboardData.items[0].type)?a.clipboardData.items:null}function c(a){return a.dataTransfer&&a.dataTransfer.files?a.dataTransfer.files:null}return{outputRule:function(a){utils.each(a.getNodesByTagName("img"),function(a){/\b(loaderrorclass)|(bloaderrorclass)\b/.test(a.getAttr("class"))&&a.parentNode.removeChild(a)}),utils.each(a.getNodesByTagName("p"),function(a){/\bloadpara\b/.test(a.getAttr("class"))&&a.parentNode.removeChild(a)})},bindEvents:{ready:function(d){var e=this;window.FormData&&window.FileReader&&(domUtils.on(e.body,"paste drop",function(d){var f,g=!1;if(f="paste"==d.type?b(d):c(d)){for(var h,i=f.length;i--;)h=f[i],h.getAsFile&&(h=h.getAsFile()),h&&h.size>0&&(a(h,e),g=!0);g&&d.preventDefault()}}),domUtils.on(e.body,"dragover",function(a){"Files"==a.dataTransfer.types[0]&&a.preventDefault()}),utils.cssRule("loading",".loadingclass{display:inline-block;cursor:default;background: url('"+this.options.themePath+this.options.theme+"/images/loading.gif') no-repeat center center transparent;border:1px solid #cccccc;margin-left:1px;height: 22px;width: 22px;}\n.loaderrorclass{display:inline-block;cursor:default;background: url('"+this.options.themePath+this.options.theme+"/images/loaderror.png') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;}",this.document))}}}}),UE.plugin.register("autosave",function(){function a(a){var f;if(!(new Date-c0?b._saveFlag=window.setTimeout(function(){a(b)},b.options.saveInterval):a(b))}},commands:{clearlocaldata:{execCommand:function(a,c){e&&b.getPreferences(e)&&b.removePreferences(e)},notNeedUndo:!0,ignoreContentChange:!0},getlocaldata:{execCommand:function(a,c){return e?b.getPreferences(e)||"":""},notNeedUndo:!0,ignoreContentChange:!0},drafts:{execCommand:function(a,c){e&&(b.body.innerHTML=b.getPreferences(e)||"

    "+domUtils.fillHtml+"

    ",b.focus(!0))},queryCommandState:function(){return e?null===b.getPreferences(e)?-1:0:-1},notNeedUndo:!0,ignoreContentChange:!0}}}}),UE.plugin.register("charts",function(){function a(a){var b=null,c=0;if(a.rows.length<2)return!1;if(a.rows[0].cells.length<2)return!1;b=a.rows[0].cells,c=b.length;for(var d,e=0;d=b[e];e++)if("th"!==d.tagName.toLowerCase())return!1;for(var f,e=1;f=a.rows[e];e++){if(f.cells.length!=c)return!1;if("th"!==f.cells[0].tagName.toLowerCase())return!1;for(var d,g=1;d=f.cells[g];g++){var h=utils.trim(d.innerText||d.textContent||"");if(h=h.replace(new RegExp(UE.dom.domUtils.fillChar,"g"),"").replace(/^\s+|\s+$/g,""),!/^\d*\.?\d+$/.test(h))return!1}}return!0}var b=this;return{bindEvents:{chartserror:function(){}},commands:{charts:{execCommand:function(c,d){var e=domUtils.findParentByTagName(this.selection.getRange().startContainer,"table",!0),f=[],g={};if(!e)return!1;if(!a(e))return b.fireEvent("chartserror"),!1;g.title=d.title||"",g.subTitle=d.subTitle||"",g.xTitle=d.xTitle||"",g.yTitle=d.yTitle||"",g.suffix=d.suffix||"",g.tip=d.tip||"",g.dataFormat=d.tableDataFormat||"",g.chartType=d.chartType||0;for(var h in g)g.hasOwnProperty(h)&&f.push(h+":"+g[h]);e.setAttribute("data-chart",f.join(";")),domUtils.addClass(e,"edui-charts-table")},queryCommandState:function(b,c){ -var d=domUtils.findParentByTagName(this.selection.getRange().startContainer,"table",!0);return d&&a(d)?0:-1}}},inputRule:function(a){utils.each(a.getNodesByTagName("table"),function(a){void 0!==a.getAttr("data-chart")&&a.setAttr("style")})},outputRule:function(a){utils.each(a.getNodesByTagName("table"),function(a){void 0!==a.getAttr("data-chart")&&a.setAttr("style","display: none;")})}}}),UE.plugin.register("section",function(){function a(a){this.tag="",this.level=-1,this.dom=null,this.nextSection=null,this.previousSection=null,this.parentSection=null,this.startAddress=[],this.endAddress=[],this.children=[]}function b(b){var c=new a;return utils.extend(c,b)}function c(a,b){for(var c=b,d=0;d=0){var o=h.selection.getRange().selectNode(i).createAddress(!0).startAddress,p=b({tag:i.tagName,title:i.innerText||i.textContent||"",level:f,dom:i,startAddress:utils.clone(o,[]),endAddress:utils.clone(o,[]),children:[]});for(j.nextSection=p,p.previousSection=j,g=j;f<=g.level;)g=g.parentSection;p.parentSection=g,g.children.push(p),k=j=p}else 1===i.nodeType&&e(i,c),k&&k.endAddress[k.endAddress.length-1]++}for(var f=c||["h1","h2","h3","h4","h5","h6"],g=0;g=c.length);f++){if(c[f]>a[f]){d=!0;break}if(c[f]=c.length);f++){if(c[f]a[f])break}return d&&e}var g,h,i=this;if(b&&d&&d.level!=-1&&(g=e?d.endAddress:d.startAddress,h=c(g,i.body),g&&h&&!f(b.startAddress,b.endAddress,g))){var j,k,l=c(b.startAddress,i.body),m=c(b.endAddress,i.body);if(e)for(j=m;j&&!(domUtils.getPosition(l,j)&domUtils.POSITION_FOLLOWING)&&(k=j.previousSibling,domUtils.insertAfter(h,j),j!=l);)j=k;else for(j=l;j&&!(domUtils.getPosition(j,m)&domUtils.POSITION_FOLLOWING)&&(k=j.nextSibling,h.parentNode.insertBefore(j,h),j!=m);)j=k;i.fireEvent("updateSections")}}},deletesection:{execCommand:function(a,b,c){function d(a){for(var b=e.body,c=0;c',b.className="edui-"+c.options.theme,b.id=c.ui.id+"_iframeupload",i.style.cssText=g,i.style.width=a+"px",i.style.height=e+"px",i.appendChild(b),i.parentNode&&(i.parentNode.style.width=a+"px",i.parentNode.style.height=a+"px");var k=h.getElementById("edui_form_"+j),l=h.getElementById("edui_input_"+j),m=h.getElementById("edui_iframe_"+j);domUtils.on(l,"change",function(){function a(){try{var e,f,g,h=(m.contentDocument||m.contentWindow.document).body,i=h.innerText||h.textContent||"";f=new Function("return "+i)(),e=c.options.imageUrlPrefix+f.url,"SUCCESS"==f.state&&f.url?(g=c.document.getElementById(d),g.setAttribute("src",e),g.setAttribute("_src",e),g.setAttribute("title",f.title||""),g.setAttribute("alt",f.original||""),g.removeAttribute("id"),domUtils.removeClasses(g,"loadingclass")):b&&b(f.state)}catch(j){b&&b(c.getLang("simpleupload.loadError"))}k.reset(),domUtils.un(m,"load",a)}function b(a){if(d){var b=c.document.getElementById(d);b&&domUtils.remove(b),c.fireEvent("showmessage",{id:d,content:a,type:"error",timeout:4e3})}}if(l.value){var d="loading_"+(+new Date).toString(36),e=utils.serializeParam(c.queryCommandValue("serverparam"))||"",f=c.getActionUrl(c.getOpt("imageActionName")),g=c.getOpt("imageAllowFiles");if(c.focus(),c.execCommand("inserthtml",''),!c.getOpt("imageActionName"))return void errorHandler(c.getLang("autoupload.errorLoadConfig"));var h=l.value,i=h?h.substr(h.lastIndexOf(".")):"";if(!i||g&&(g.join("")+".").indexOf(i.toLowerCase()+".")==-1)return void b(c.getLang("simpleupload.exceedTypeError"));domUtils.on(m,"load",a),k.action=utils.formatUrl(f+(f.indexOf("?")==-1?"?":"&")+e),k.submit()}});var n;c.addListener("selectionchange",function(){clearTimeout(n),n=setTimeout(function(){var a=c.queryCommandState("simpleupload");a==-1?l.disabled="disabled":l.disabled=!1},400)}),d=!0}),f.style.cssText=g,b.appendChild(f)}var b,c=this,d=!1;return{bindEvents:{ready:function(){utils.cssRule("loading",".loadingclass{display:inline-block;cursor:default;background: url('"+this.options.themePath+this.options.theme+"/images/loading.gif') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;}\n.loaderrorclass{display:inline-block;cursor:default;background: url('"+this.options.themePath+this.options.theme+"/images/loaderror.png') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;}",this.document)},simpleuploadbtnready:function(d,e){b=e,c.afterConfigReady(a)}},outputRule:function(a){utils.each(a.getNodesByTagName("img"),function(a){/\b(loaderrorclass)|(bloaderrorclass)\b/.test(a.getAttr("class"))&&a.parentNode.removeChild(a)})},commands:{simpleupload:{queryCommandState:function(){return d?0:-1}}}}}),UE.plugin.register("serverparam",function(){var a={};return{commands:{serverparam:{execCommand:function(b,c,d){void 0===c||null===c?a={}:utils.isString(c)?void 0===d||null===d?delete a[c]:a[c]=d:utils.isObject(c)?utils.extend(a,c,!0):utils.isFunction(c)&&utils.extend(a,c(),!0)},queryCommandValue:function(){return a||{}}}}}}),UE.plugin.register("insertfile",function(){function a(a){var b=a.substr(a.lastIndexOf(".")+1).toLowerCase(),c={rar:"icon_rar.gif",zip:"icon_rar.gif",tar:"icon_rar.gif",gz:"icon_rar.gif",bz2:"icon_rar.gif",doc:"icon_doc.gif",docx:"icon_doc.gif",pdf:"icon_pdf.gif",mp3:"icon_mp3.gif",xls:"icon_xls.gif",xlsx:"icon_xls.gif",chm:"icon_chm.gif",ppt:"icon_ppt.gif",pptx:"icon_ppt.gif",avi:"icon_mv.gif",rmvb:"icon_mv.gif",wmv:"icon_mv.gif",flv:"icon_mv.gif",swf:"icon_mv.gif",rm:"icon_mv.gif",exe:"icon_exe.gif",psd:"icon_psd.gif",txt:"icon_txt.gif",jpg:"icon_jpg.gif",png:"icon_jpg.gif",jpeg:"icon_jpg.gif",gif:"icon_jpg.gif",ico:"icon_jpg.gif",bmp:"icon_jpg.gif"};return c[b]?c[b]:c.txt}var b=this;return{commands:{insertfile:{execCommand:function(c,d){d=utils.isArray(d)?d:[d];var e,f,g,h,i="",j=b.getOpt("UEDITOR_HOME_URL"),k=j+("/"==j.substr(j.length-1)?"":"/")+"dialogs/attachment/fileTypeImages/";for(e=0;e'+h+"

    ";b.execCommand("insertHtml",i)}}}}}),UE.plugins.xssFilter=function(){function a(a){var b=a.tagName,d=a.attrs;return c.hasOwnProperty(b)?void UE.utils.each(d,function(d,e){c[b].indexOf(e)===-1&&a.setAttr(e)}):(a.parentNode.removeChild(a),!1)}var b=UEDITOR_CONFIG,c=b.whitList;c&&b.xssFilterRules&&(this.options.filterRules=function(){var b={};return UE.utils.each(c,function(c,d){b[d]=function(b){return a(b)}}),b}());var d=[];UE.utils.each(c,function(a,b){d.push(b)}),c&&b.inputXssFilter&&this.addInputRule(function(b){b.traversal(function(b){return"element"===b.type&&void a(b)})}),c&&b.outputXssFilter&&this.addOutputRule(function(b){b.traversal(function(b){return"element"===b.type&&void a(b)})})};var baidu=baidu||{};baidu.editor=baidu.editor||{},UE.ui=baidu.editor.ui={},function(){function a(){var a=document.getElementById("edui_fixedlayer");i.setViewportOffset(a,{left:0,top:0})}function b(b){d.on(window,"scroll",a),d.on(window,"resize",baidu.editor.utils.defer(a,0,!0))}var c=baidu.editor.browser,d=baidu.editor.dom.domUtils,e="$EDITORUI",f=window[e]={},g="ID"+e,h=0,i=baidu.editor.ui.uiUtils={uid:function(a){return a?a[g]||(a[g]=++h):++h},hook:function(a,b){var c;return a&&a._callbacks?c=a:(c=function(){var b;a&&(b=a.apply(this,arguments));for(var d=c._callbacks,e=d.length;e--;){var f=d[e].apply(this,arguments);void 0===b&&(b=f)}return b},c._callbacks=[]),c._callbacks.push(b),c},createElementByHtml:function(a){var b=document.createElement("div");return b.innerHTML=a,b=b.firstChild,b.parentNode.removeChild(b),b},getViewportElement:function(){return c.ie&&c.quirks?document.body:document.documentElement},getClientRect:function(a){var b;try{b=a.getBoundingClientRect()}catch(c){b={left:0,top:0,height:0,width:0}}for(var e,f={left:Math.round(b.left),top:Math.round(b.top),height:Math.round(b.bottom-b.top),width:Math.round(b.right-b.left)};(e=a.ownerDocument)!==document&&(a=d.getWindow(e).frameElement);)b=a.getBoundingClientRect(),f.left+=b.left,f.top+=b.top;return f.bottom=f.top+f.height,f.right=f.left+f.width,f},getViewportRect:function(){var a=i.getViewportElement(),b=0|(window.innerWidth||a.clientWidth),c=0|(window.innerHeight||a.clientHeight);return{left:0,top:0,height:c,width:b,bottom:c,right:b}},setViewportOffset:function(a,b){var c=i.getFixedLayer();a.parentNode===c?(a.style.left=b.left+"px",a.style.top=b.top+"px"):d.setViewportOffset(a,b)},getEventOffset:function(a){var b=a.target||a.srcElement,c=i.getClientRect(b),d=i.getViewportOffsetByEvent(a);return{left:d.left-c.left,top:d.top-c.top}},getViewportOffsetByEvent:function(a){var b=a.target||a.srcElement,c=d.getWindow(b).frameElement,e={left:a.clientX,top:a.clientY};if(c&&b.ownerDocument!==document){var f=i.getClientRect(c);e.left+=f.left,e.top+=f.top}return e},setGlobal:function(a,b){return f[a]=b,e+'["'+a+'"]'},unsetGlobal:function(a){delete f[a]},copyAttributes:function(a,b){for(var e=b.attributes,f=e.length;f--;){var g=e[f];"style"==g.nodeName||"class"==g.nodeName||c.ie&&!g.specified||a.setAttribute(g.nodeName,g.nodeValue)}b.className&&d.addClass(a,b.className),b.style.cssText&&(a.style.cssText+=";"+b.style.cssText)},removeStyle:function(a,b){if(a.style.removeProperty)a.style.removeProperty(b);else{if(!a.style.removeAttribute)throw"";a.style.removeAttribute(b)}},contains:function(a,b){return a&&b&&a!==b&&(a.contains?a.contains(b):16&a.compareDocumentPosition(b))},startDrag:function(a,b,c){function d(a){var c=a.clientX-g,d=a.clientY-h;b.ondragmove(c,d,a),a.stopPropagation?a.stopPropagation():a.cancelBubble=!0}function e(a){c.removeEventListener("mousemove",d,!0),c.removeEventListener("mouseup",e,!0),window.removeEventListener("mouseup",e,!0),b.ondragstop()}function f(){i.releaseCapture(),i.detachEvent("onmousemove",d),i.detachEvent("onmouseup",f),i.detachEvent("onlosecaptrue",f),b.ondragstop()}var c=c||document,g=a.clientX,h=a.clientY;if(c.addEventListener)c.addEventListener("mousemove",d,!0),c.addEventListener("mouseup",e,!0),window.addEventListener("mouseup",e,!0),a.preventDefault();else{var i=a.srcElement;i.setCapture(),i.attachEvent("onmousemove",d),i.attachEvent("onmouseup",f),i.attachEvent("onlosecaptrue",f),a.returnValue=!1}b.ondragstart()},getFixedLayer:function(){var d=document.getElementById("edui_fixedlayer");return null==d&&(d=document.createElement("div"),d.id="edui_fixedlayer",document.body.appendChild(d),c.ie&&c.version<=8?(d.style.position="absolute",b(),setTimeout(a)):d.style.position="fixed",d.style.left="0",d.style.top="0",d.style.width="0",d.style.height="0"),d},makeUnselectable:function(a){if(c.opera||c.ie&&c.version<9){if(a.unselectable="on",a.hasChildNodes())for(var b=0;b'}},a.inherits(c,b)}(),function(){var a=baidu.editor.utils,b=baidu.editor.dom.domUtils,c=baidu.editor.ui.UIBase,d=baidu.editor.ui.uiUtils,e=baidu.editor.ui.Mask=function(a){this.initOptions(a),this.initUIBase()};e.prototype={getHtmlTpl:function(){return'
    '},postRender:function(){var a=this;b.on(window,"resize",function(){setTimeout(function(){a.isHidden()||a._fill()})})},show:function(a){this._fill(),this.getDom().style.display="",this.getDom().style.zIndex=a},hide:function(){this.getDom().style.display="none",this.getDom().style.zIndex=""},isHidden:function(){return"none"==this.getDom().style.display},_onMouseDown:function(){return!1},_onClick:function(a,b){this.fireEvent("click",a,b)},_fill:function(){var a=this.getDom(),b=d.getViewportRect();a.style.width=b.width+"px",a.style.height=b.height+"px"}},a.inherits(e,c)}(),function(){function a(a,b){for(var c=0;c
    '+this.getContentHtmlTpl()+"
    "},getContentHtmlTpl:function(){return this.content?"string"==typeof this.content?this.content:this.content.renderHtml():""},_UIBase_postRender:e.prototype.postRender,postRender:function(){if(this.content instanceof e&&this.content.postRender(),this.captureWheel&&!this.captured){this.captured=!0;var a=(document.documentElement.clientHeight||document.body.clientHeight)-80,b=this.getDom().offsetHeight,f=c.getClientRect(this.combox.getDom()).top,g=this.getDom("content"),h=this.getDom("body").getElementsByTagName("iframe"),i=this;for(h.length&&(h=h[0]);f+b>a;)b-=30;g.style.height=b+"px",h&&(h.style.height=b+"px"),window.XMLHttpRequest?d.on(g,"onmousewheel"in document.body?"mousewheel":"DOMMouseScroll",function(a){a.preventDefault?a.preventDefault():a.returnValue=!1,a.wheelDelta?g.scrollTop-=a.wheelDelta/120*60:g.scrollTop-=a.detail/-3*60}):d.on(this.getDom(),"mousewheel",function(a){a.returnValue=!1,i.getDom("content").scrollTop-=a.wheelDelta/120*60})}this.fireEvent("postRenderAfter"),this.hide(!0),this._UIBase_postRender()},_doAutoRender:function(){!this.getDom()&&this.autoRender&&this.render()},mesureSize:function(){var a=this.getDom("content");return c.getClientRect(a)},fitSize:function(){if(this.captureWheel&&this.sized)return this.__size;this.sized=!0;var a=this.getDom("body");a.style.width="",a.style.height="";var b=this.mesureSize();if(this.captureWheel){a.style.width=-(-20-b.width)+"px";var c=parseInt(this.getDom("content").style.height,10);!window.isNaN(c)&&(b.height=c)}else a.style.width=b.width+"px";return a.style.height=b.height+"px",this.__size=b,this.captureWheel&&(this.getDom("content").style.overflow="auto"),b},showAnchor:function(a,b){this.showAnchorRect(c.getClientRect(a),b)},showAnchorRect:function(a,b,e){this._doAutoRender();var f=c.getViewportRect();this.getDom().style.visibility="hidden",this._show();var g,i,j,k,l=this.fitSize();b?(g=this.canSideLeft&&a.right+l.width>f.right&&a.left>l.width,i=this.canSideUp&&a.top+l.height>f.bottom&&a.bottom>l.height,j=g?a.left-l.width:a.right,k=i?a.bottom-l.height:a.top):(g=this.canSideLeft&&a.right+l.width>f.right&&a.left>l.width,i=this.canSideUp&&a.top+l.height>f.bottom&&a.bottom>l.height,j=g?a.right-l.width:a.left,k=i?a.top-l.height:a.bottom);var m=this.getDom();c.setViewportOffset(m,{left:j,top:k}),d.removeClasses(m,h),m.className+=" "+h[2*(i?1:0)+(g?1:0)],this.editor&&(m.style.zIndex=1*this.editor.container.style.zIndex+10,baidu.editor.ui.uiUtils.getFixedLayer().style.zIndex=m.style.zIndex-1),this.getDom().style.visibility="visible"},showAt:function(a){var b=a.left,c=a.top,d={left:b,top:c,right:b,bottom:c,height:0,width:0};this.showAnchorRect(d,!1,!0)},_show:function(){if(this._hidden){var a=this.getDom();a.style.display="",this._hidden=!1,this.fireEvent("show")}},isHidden:function(){return this._hidden},show:function(){this._doAutoRender(),this._show()},hide:function(a){!this._hidden&&this.getDom()&&(this.getDom().style.display="none",this._hidden=!0,a||this.fireEvent("hide"))},queryAutoHide:function(a){return!a||!c.contains(this.getDom(),a)}},b.inherits(f,e),d.on(document,"mousedown",function(b){var c=b.target||b.srcElement;a(b,c)}),d.on(window,"scroll",function(b,c){a(b,c)})}(),function(){function a(a,b){for(var c='
    '+a+'
    ',d=0;d"+(60==d?'":"")+""),c+=d<70?'':"";return c+="
    '+b.getLang("themeColor")+'
    '+b.getLang("standardColor")+"
    =60?"border-width:1px;":d>=10&&d<20?"border-width:1px 1px 0 1px;":"border-width:0 1px 0 1px;")+'">
    "}var b=baidu.editor.utils,c=baidu.editor.ui.UIBase,d=baidu.editor.ui.ColorPicker=function(a){this.initOptions(a),this.noColorText=this.noColorText||this.editor.getLang("clearColor"),this.initUIBase()};d.prototype={getHtmlTpl:function(){return a(this.noColorText,this.editor)},_onTableClick:function(a){var b=a.target||a.srcElement,c=b.getAttribute("data-color");c&&this.fireEvent("pickcolor",c)},_onTableOver:function(a){var b=a.target||a.srcElement,c=b.getAttribute("data-color");c&&(this.getDom("preview").style.backgroundColor=c)},_onTableOut:function(){this.getDom("preview").style.backgroundColor=""},_onPickNoColor:function(){this.fireEvent("picknocolor")}},b.inherits(d,c);var e="ffffff,000000,eeece1,1f497d,4f81bd,c0504d,9bbb59,8064a2,4bacc6,f79646,f2f2f2,7f7f7f,ddd9c3,c6d9f0,dbe5f1,f2dcdb,ebf1dd,e5e0ec,dbeef3,fdeada,d8d8d8,595959,c4bd97,8db3e2,b8cce4,e5b9b7,d7e3bc,ccc1d9,b7dde8,fbd5b5,bfbfbf,3f3f3f,938953,548dd4,95b3d7,d99694,c3d69b,b2a2c7,92cddc,fac08f,a5a5a5,262626,494429,17365d,366092,953734,76923c,5f497a,31859b,e36c09,7f7f7f,0c0c0c,1d1b10,0f243e,244061,632423,4f6128,3f3151,205867,974806,c00000,ff0000,ffc000,ffff00,92d050,00b050,00b0f0,0070c0,002060,7030a0,".split(",")}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.uiUtils,c=baidu.editor.ui.UIBase,d=baidu.editor.ui.TablePicker=function(a){this.initOptions(a),this.initTablePicker()};d.prototype={defaultNumRows:10,defaultNumCols:10,maxNumRows:20,maxNumCols:20,numRows:10,numCols:10,lengthOfCellSide:22,initTablePicker:function(){this.initUIBase()},getHtmlTpl:function(){return'
    '},_UIBase_render:c.prototype.render,render:function(a){this._UIBase_render(a),this.getDom("label").innerHTML="0"+this.editor.getLang("t_row")+" x 0"+this.editor.getLang("t_col")},_track:function(a,b){var c=this.getDom("overlay").style,d=this.lengthOfCellSide;c.width=a*d+"px",c.height=b*d+"px";var e=this.getDom("label");e.innerHTML=a+this.editor.getLang("t_col")+" x "+b+this.editor.getLang("t_row"),this.numCols=a,this.numRows=b},_onMouseOver:function(a,c){var d=a.relatedTarget||a.fromElement;b.contains(c,d)||c===d||(this.getDom("label").innerHTML="0"+this.editor.getLang("t_col")+" x 0"+this.editor.getLang("t_row"),this.getDom("overlay").style.visibility="")},_onMouseOut:function(a,c){var d=a.relatedTarget||a.toElement;b.contains(c,d)||c===d||(this.getDom("label").innerHTML="0"+this.editor.getLang("t_col")+" x 0"+this.editor.getLang("t_row"),this.getDom("overlay").style.visibility="hidden")},_onMouseMove:function(a,c){var d=(this.getDom("overlay").style,b.getEventOffset(a)),e=this.lengthOfCellSide,f=Math.ceil(d.left/e),g=Math.ceil(d.top/e);this._track(f,g)},_onClick:function(){this.fireEvent("picktable",this.numCols,this.numRows)}},a.inherits(d,c)}(),function(){var a=baidu.editor.browser,b=baidu.editor.dom.domUtils,c=baidu.editor.ui.uiUtils,d='onmousedown="$$.Stateful_onMouseDown(event, this);" onmouseup="$$.Stateful_onMouseUp(event, this);"'+(a.ie?' onmouseenter="$$.Stateful_onMouseEnter(event, this);" onmouseleave="$$.Stateful_onMouseLeave(event, this);"':' onmouseover="$$.Stateful_onMouseOver(event, this);" onmouseout="$$.Stateful_onMouseOut(event, this);"');baidu.editor.ui.Stateful={alwalysHoverable:!1,target:null,Stateful_init:function(){this._Stateful_dGetHtmlTpl=this.getHtmlTpl,this.getHtmlTpl=this.Stateful_getHtmlTpl},Stateful_getHtmlTpl:function(){var a=this._Stateful_dGetHtmlTpl();return a.replace(/stateful/g,function(){return d})},Stateful_onMouseEnter:function(a,b){this.target=b,this.isDisabled()&&!this.alwalysHoverable||(this.addState("hover"),this.fireEvent("over"))},Stateful_onMouseLeave:function(a,b){this.isDisabled()&&!this.alwalysHoverable||(this.removeState("hover"),this.removeState("active"),this.fireEvent("out"))},Stateful_onMouseOver:function(a,b){var d=a.relatedTarget;c.contains(b,d)||b===d||this.Stateful_onMouseEnter(a,b)},Stateful_onMouseOut:function(a,b){var d=a.relatedTarget;c.contains(b,d)||b===d||this.Stateful_onMouseLeave(a,b)},Stateful_onMouseDown:function(a,b){this.isDisabled()||this.addState("active")},Stateful_onMouseUp:function(a,b){this.isDisabled()||this.removeState("active")},Stateful_postRender:function(){this.disabled&&!this.hasState("disabled")&&this.addState("disabled")},hasState:function(a){return b.hasClass(this.getStateDom(),"edui-state-"+a)},addState:function(a){this.hasState(a)||(this.getStateDom().className+=" edui-state-"+a)},removeState:function(a){this.hasState(a)&&b.removeClasses(this.getStateDom(),["edui-state-"+a])},getStateDom:function(){return this.getDom("state")},isChecked:function(){return this.hasState("checked")},setChecked:function(a){!this.isDisabled()&&a?this.addState("checked"):this.removeState("checked")},isDisabled:function(){return this.hasState("disabled")},setDisabled:function(a){a?(this.removeState("hover"),this.removeState("checked"),this.removeState("active"),this.addState("disabled")):this.removeState("disabled")}}}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.UIBase,c=baidu.editor.ui.Stateful,d=baidu.editor.ui.Button=function(a){if(a.name){var b=a.name,c=a.cssRules;a.className||(a.className="edui-for-"+b),a.cssRules=".edui-default .edui-for-"+b+" .edui-icon {"+c+"}"}this.initOptions(a),this.initButton()};d.prototype={uiName:"button",label:"",title:"",showIcon:!0,showText:!0,cssRules:"",initButton:function(){this.initUIBase(),this.Stateful_init(),this.cssRules&&a.cssRule("edui-customize-"+this.name+"-style",this.cssRules)},getHtmlTpl:function(){return'
    '+(this.showIcon?'
    ':"")+(this.showText?'
    '+this.label+"
    ":"")+"
    "},postRender:function(){this.Stateful_postRender(),this.setDisabled(this.disabled)},_onMouseDown:function(a){var b=a.target||a.srcElement,c=b&&b.tagName&&b.tagName.toLowerCase();if("input"==c||"object"==c||"object"==c)return!1},_onClick:function(){this.isDisabled()||this.fireEvent("click")},setTitle:function(a){var b=this.getDom("label");b.innerHTML=a}},a.inherits(d,b),a.extend(d.prototype,c)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.uiUtils,c=(baidu.editor.dom.domUtils,baidu.editor.ui.UIBase),d=baidu.editor.ui.Stateful,e=baidu.editor.ui.SplitButton=function(a){this.initOptions(a),this.initSplitButton()};e.prototype={popup:null,uiName:"splitbutton",title:"",initSplitButton:function(){this.initUIBase(),this.Stateful_init();if(null!=this.popup){var a=this.popup;this.popup=null,this.setPopup(a)}},_UIBase_postRender:c.prototype.postRender,postRender:function(){this.Stateful_postRender(),this._UIBase_postRender()},setPopup:function(c){this.popup!==c&&(null!=this.popup&&this.popup.dispose(),c.addListener("show",a.bind(this._onPopupShow,this)),c.addListener("hide",a.bind(this._onPopupHide,this)),c.addListener("postrender",a.bind(function(){c.getDom("body").appendChild(b.createElementByHtml('
    ')),c.getDom().className+=" "+this.className},this)),this.popup=c)},_onPopupShow:function(){this.addState("opened")},_onPopupHide:function(){this.removeState("opened")},getHtmlTpl:function(){return'
    '},showPopup:function(){var a=b.getClientRect(this.getDom());a.top-=this.popup.SHADOW_RADIUS,a.height+=this.popup.SHADOW_RADIUS,this.popup.showAnchorRect(a)},_onArrowClick:function(a,b){this.isDisabled()||this.showPopup()},_onButtonClick:function(){this.isDisabled()||this.fireEvent("buttonclick")}},a.inherits(e,c),a.extend(e.prototype,d,!0)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.uiUtils,c=baidu.editor.ui.ColorPicker,d=baidu.editor.ui.Popup,e=baidu.editor.ui.SplitButton,f=baidu.editor.ui.ColorButton=function(a){this.initOptions(a),this.initColorButton()};f.prototype={initColorButton:function(){var a=this;this.popup=new d({content:new c({noColorText:a.editor.getLang("clearColor"),editor:a.editor,onpickcolor:function(b,c){a._onPickColor(c)},onpicknocolor:function(b,c){a._onPickNoColor(c)}}),editor:a.editor}),this.initSplitButton()},_SplitButton_postRender:e.prototype.postRender,postRender:function(){this._SplitButton_postRender(),this.getDom("button_body").appendChild(b.createElementByHtml('
    ')),this.getDom().className+=" edui-colorbutton"; -},setColor:function(a){this.getDom("colorlump").style.backgroundColor=a,this.color=a},_onPickColor:function(a){this.fireEvent("pickcolor",a)!==!1&&(this.setColor(a),this.popup.hide())},_onPickNoColor:function(a){this.fireEvent("picknocolor")!==!1&&this.popup.hide()}},a.inherits(f,e)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.Popup,c=baidu.editor.ui.TablePicker,d=baidu.editor.ui.SplitButton,e=baidu.editor.ui.TableButton=function(a){this.initOptions(a),this.initTableButton()};e.prototype={initTableButton:function(){var a=this;this.popup=new b({content:new c({editor:a.editor,onpicktable:function(b,c,d){a._onPickTable(c,d)}}),editor:a.editor}),this.initSplitButton()},_onPickTable:function(a,b){this.fireEvent("picktable",a,b)!==!1&&this.popup.hide()}},a.inherits(e,d)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.UIBase,c=baidu.editor.ui.AutoTypeSetPicker=function(a){this.initOptions(a),this.initAutoTypeSetPicker()};c.prototype={initAutoTypeSetPicker:function(){this.initUIBase()},getHtmlTpl:function(){var a=this.editor,b=a.options.autotypeset,c=a.getLang("autoTypeSet"),d="textAlignValue"+a.uid,e="imageBlockLineValue"+a.uid,f="symbolConverValue"+a.uid;return'
    "+c.mergeLine+'"+c.delLine+'
    "+c.removeFormat+'"+c.indent+'
    "+c.alignment+'"+a.getLang("justifyleft")+'"+a.getLang("justifycenter")+'"+a.getLang("justifyright")+'
    "+c.imageFloat+'"+a.getLang("default")+'"+a.getLang("justifyleft")+'"+a.getLang("justifycenter")+'"+a.getLang("justifyright")+'
    "+c.removeFontsize+'"+c.removeFontFamily+'
    "+c.removeHtml+'
    "+c.pasteFilter+'
    "+c.symbol+'"+c.bdc2sb+'"+c.tobdc+'
    "},_UIBase_render:b.prototype.render},a.inherits(c,b)}(),function(){function a(a){for(var c,d={},e=a.getDom(),f=a.editor.uid,g=null,h=null,i=domUtils.getElementsByTagName(e,"input"),j=i.length-1;c=i[j--];)if(g=c.getAttribute("type"),"checkbox"==g)if(h=c.getAttribute("name"),d[h]&&delete d[h],c.checked){var k=document.getElementById(h+"Value"+f);if(k){if(/input/gi.test(k.tagName))d[h]=k.value;else for(var l,m=k.getElementsByTagName("input"),n=m.length-1;l=m[n--];)if(l.checked){d[h]=l.value;break}}else d[h]=!0}else d[h]=!1;else d[c.getAttribute("value")]=c.checked;for(var o,p=domUtils.getElementsByTagName(e,"select"),j=0;o=p[j++];){var q=o.getAttribute("name");d[q]=d[q]?o.value:""}b.extend(a.editor.options.autotypeset,d),a.editor.setPreferences("autotypeset",d)}var b=baidu.editor.utils,c=baidu.editor.ui.Popup,d=baidu.editor.ui.AutoTypeSetPicker,e=baidu.editor.ui.SplitButton,f=baidu.editor.ui.AutoTypeSetButton=function(a){this.initOptions(a),this.initAutoTypeSetButton()};f.prototype={initAutoTypeSetButton:function(){var b=this;this.popup=new c({content:new d({editor:b.editor}),editor:b.editor,hide:function(){!this._hidden&&this.getDom()&&(a(this),this.getDom().style.display="none",this._hidden=!0,this.fireEvent("hide"))}});var e=0;this.popup.addListener("postRenderAfter",function(){var c=this;if(!e){var d=this.getDom(),f=d.getElementsByTagName("button")[0];f.onclick=function(){a(c),b.editor.execCommand("autotypeset"),c.hide()},domUtils.on(d,"click",function(d){var e=d.target||d.srcElement,f=b.editor.uid;if(e&&"INPUT"==e.tagName){if("imageBlockLine"==e.name||"textAlign"==e.name||"symbolConver"==e.name)for(var g=e.checked,h=document.getElementById(e.name+"Value"+f),i=h.getElementsByTagName("input"),j={imageBlockLine:"none",textAlign:"left",symbolConver:"tobdc"},k=0;k"),e.push('
    '),2===d&&e.push("");return'
    '+e.join("")+"
    "},getStateDom:function(){return this.target},_onClick:function(a){var c=a.target||a.srcElement;/icon/.test(c.className)&&(this.items[c.parentNode.getAttribute("index")].onclick(),b.postHide(a))},_UIBase_render:d.prototype.render},a.inherits(e,d),a.extend(e.prototype,c,!0)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.Stateful,c=baidu.editor.ui.uiUtils,d=baidu.editor.ui.UIBase,e=baidu.editor.ui.PastePicker=function(a){this.initOptions(a),this.initPastePicker()};e.prototype={initPastePicker:function(){this.initUIBase(),this.Stateful_init()},getHtmlTpl:function(){return'
    '+this.editor.getLang("pasteOpt")+'
    '},getStateDom:function(){return this.target},format:function(a){this.editor.ui._isTransfer=!0,this.editor.fireEvent("pasteTransfer",a)},_onClick:function(a){var b=domUtils.getNextDomNode(a),d=c.getViewportRect().height,e=c.getClientRect(b);e.top+e.height>d?b.style.top=-e.height-a.offsetHeight+"px":b.style.top="",/hidden/gi.test(domUtils.getComputedStyle(b,"visibility"))?(b.style.visibility="visible",domUtils.addClass(a,"edui-state-opened")):(b.style.visibility="hidden",domUtils.removeClasses(a,"edui-state-opened"))},_UIBase_render:d.prototype.render},a.inherits(e,d),a.extend(e.prototype,b,!0)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.uiUtils,c=baidu.editor.ui.UIBase,d=baidu.editor.ui.Toolbar=function(a){this.initOptions(a),this.initToolbar()};d.prototype={items:null,initToolbar:function(){this.items=this.items||[],this.initUIBase()},add:function(a,b){void 0===b?this.items.push(a):this.items.splice(b,0,a)},getHtmlTpl:function(){for(var a=[],b=0;b'+a.join("")+""},postRender:function(){for(var a=this.getDom(),c=0;c
    '},postRender:function(){},queryAutoHide:function(){return!0}};h.prototype={items:null,uiName:"menu",initMenu:function(){this.items=this.items||[],this.initPopup(),this.initItems()},initItems:function(){for(var a=0;a'+a.join("")+""},_Popup_postRender:e.prototype.postRender,postRender:function(){for(var a=this,d=0;d
    '+this.renderLabelHtml()+"
    "},postRender:function(){var a=this;this.addListener("over",function(){a.ownerMenu.fireEvent("submenuover",a),a.subMenu&&a.delayShowSubMenu()}),this.subMenu&&(this.getDom().className+=" edui-hassubmenu",this.subMenu.render(),this.addListener("out",function(){a.delayHideSubMenu()}),this.subMenu.addListener("over",function(){clearTimeout(a._closingTimer),a._closingTimer=null,a.addState("opened")}),this.ownerMenu.addListener("hide",function(){a.hideSubMenu()}),this.ownerMenu.addListener("submenuover",function(b,c){c!==a&&a.delayHideSubMenu()}),this.subMenu._bakQueryAutoHide=this.subMenu.queryAutoHide,this.subMenu.queryAutoHide=function(b){return(!b||!c.contains(a.getDom(),b))&&this._bakQueryAutoHide(b)}),this.getDom().style.tabIndex="-1",c.makeUnselectable(this.getDom()),this.Stateful_postRender()},delayShowSubMenu:function(){var a=this;a.isDisabled()||(a.addState("opened"),clearTimeout(a._showingTimer),clearTimeout(a._closingTimer),a._closingTimer=null,a._showingTimer=setTimeout(function(){a.showSubMenu()},250))},delayHideSubMenu:function(){var a=this;a.isDisabled()||(a.removeState("opened"),clearTimeout(a._showingTimer),a._closingTimer||(a._closingTimer=setTimeout(function(){a.hasState("opened")||a.hideSubMenu(),a._closingTimer=null},400)))},renderLabelHtml:function(){return'
    '+(this.label||"")+"
    "},getStateDom:function(){return this.getDom()},queryAutoHide:function(a){if(this.subMenu&&this.hasState("opened"))return this.subMenu.queryAutoHide(a)},_onClick:function(a,b){this.hasState("disabled")||this.fireEvent("click",a,b)!==!1&&(this.subMenu?this.showSubMenu():e.postHide(a))},showSubMenu:function(){var a=c.getClientRect(this.getDom());a.right-=5,a.left+=2,a.width-=7,a.top-=4,a.bottom+=4,a.height+=8,this.subMenu.showAnchorRect(a,!0,!0)},hideSubMenu:function(){this.subMenu.hide()}},a.inherits(j,d),a.extend(j.prototype,f,!0)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.uiUtils,c=baidu.editor.ui.Menu,d=baidu.editor.ui.SplitButton,e=baidu.editor.ui.Combox=function(a){this.initOptions(a),this.initCombox()};e.prototype={uiName:"combox",onbuttonclick:function(){this.showPopup()},initCombox:function(){var a=this;this.items=this.items||[];for(var b=0;bd.right&&(g=d.right-e.width);var h=a.top;h+e.height>d.bottom&&(h=d.bottom-e.height),c.style.left=Math.max(g,0)+"px",c.style.top=Math.max(h,0)+"px"},showAtCenter:function(){var a=f.getViewportRect();if(this.fullscreen){var b=this.getDom(),c=this.getDom("content");b.style.display="block";var d=UE.ui.uiUtils.getClientRect(b),g=UE.ui.uiUtils.getClientRect(c);b.style.left="-100000px",c.style.width=a.width-d.width+g.width+"px",c.style.height=a.height-d.height+g.height+"px",b.style.width=a.width+"px",b.style.height=a.height+"px",b.style.left=0,this._originalContext={html:{overflowX:document.documentElement.style.overflowX,overflowY:document.documentElement.style.overflowY},body:{overflowX:document.body.style.overflowX,overflowY:document.body.style.overflowY}},document.documentElement.style.overflowX="hidden",document.documentElement.style.overflowY="hidden",document.body.style.overflowX="hidden",document.body.style.overflowY="hidden"}else{this.getDom().style.display="";var h=this.fitSize(),i=0|this.getDom("titlebar").offsetHeight,j=a.width/2-h.width/2,k=a.height/2-(h.height-i)/2-i,l=this.getDom();this.safeSetOffset({left:Math.max(0|j,0),top:Math.max(0|k,0)}),e.hasClass(l,"edui-state-centered")||(l.className+=" edui-state-centered")}this._show()},getContentHtml:function(){var a="";return"string"==typeof this.content?a=this.content:this.iframeUrl&&(a=''),a},getHtmlTpl:function(){var a="";if(this.buttons){for(var b=[],c=0;c
    '+b.join("")+"
    "}return'
    '+(this.title||"")+"
    "+this.closeButton.renderHtml()+'
    '+(this.autoReset?"":this.getContentHtml())+"
    "+a+"
    "},postRender:function(){this.modalMask.getDom()||(this.modalMask.render(),this.modalMask.hide()),this.dragMask.getDom()||(this.dragMask.render(),this.dragMask.hide());var a=this;if(this.addListener("show",function(){a.modalMask.show(this.getDom().style.zIndex-2)}),this.addListener("hide",function(){a.modalMask.hide()}),this.buttons)for(var b=0;b',a.editor.container.style.zIndex&&(this.getDom().style.zIndex=1*a.editor.container.style.zIndex+1))}}),this.onbuttonclick=function(){this.showPopup()},this.initSplitButton()}},a.inherits(d,c)}(),function(){function a(a){var b=a.target||a.srcElement,c=g.findParent(b,function(a){return g.hasClass(a,"edui-shortcutmenu")||g.hasClass(a,"edui-popup")},!0);if(!c)for(var d,e=0;d=h[e++];)d.hide()}var b,c=baidu.editor.ui,d=c.UIBase,e=c.uiUtils,f=baidu.editor.utils,g=baidu.editor.dom.domUtils,h=[],i=!1,j=c.ShortCutMenu=function(a){this.initOptions(a),this.initShortCutMenu()};j.postHide=a,j.prototype={isHidden:!0,SPACE:5,initShortCutMenu:function(){this.items=this.items||[],this.initUIBase(),this.initItems(),this.initEvent(),h.push(this)},initEvent:function(){var a=this,c=a.editor.document;g.on(c,"mousemove",function(c){if(a.isHidden===!1){if(a.getSubMenuMark()||"contextmenu"==a.eventType)return;var d=!0,e=a.getDom(),f=e.offsetWidth,g=e.offsetHeight,h=f/2+a.SPACE,i=g/2,j=Math.abs(c.screenX-a.left),k=Math.abs(c.screenY-a.top);clearTimeout(b),b=setTimeout(function(){k>0&&ki&&ki+70&&k0&&jh&&jh+70&&j'+a+""}},f.inherits(j,d),g.on(document,"mousedown",function(b){a(b)}),g.on(window,"scroll",function(b){a(b)})}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.UIBase,c=baidu.editor.ui.Breakline=function(a){this.initOptions(a),this.initSeparator()};c.prototype={uiName:"Breakline",initSeparator:function(){this.initUIBase()},getHtmlTpl:function(){return"
    "}},a.inherits(c,b)}(),function(){var a=baidu.editor.utils,b=baidu.editor.dom.domUtils,c=baidu.editor.ui.UIBase,d=baidu.editor.ui.Message=function(a){this.initOptions(a),this.initMessage()};d.prototype={initMessage:function(){this.initUIBase()},getHtmlTpl:function(){return'
    ×
    '},reset:function(a){var b=this;a.keepshow||(clearTimeout(this.timer),b.timer=setTimeout(function(){b.hide()},a.timeout||4e3)),void 0!==a.content&&b.setContent(a.content),void 0!==a.type&&b.setType(a.type),b.show()},postRender:function(){var a=this,c=this.getDom("closer");c&&b.on(c,"click",function(){a.hide()})},setContent:function(a){this.getDom("content").innerHTML=a},setType:function(a){a=a||"info";var b=this.getDom("body");b.className=b.className.replace(/edui-message-type-[\w-]+/,"edui-message-type-"+a)},getContent:function(){return this.getDom("content").innerHTML},getType:function(){var a=this.getDom("body").match(/edui-message-type-([\w-]+)/);return a?a[1]:""},show:function(){this.getDom().style.display="block"},hide:function(){var a=this.getDom();a&&(a.style.display="none",a.parentNode&&a.parentNode.removeChild(a))}},a.inherits(d,c)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui,c=b.Dialog;b.buttons={},b.Dialog=function(a){var b=new c(a);return b.addListener("hide",function(){if(b.editor){var a=b.editor;try{if(browser.gecko){var c=a.window.scrollY,d=a.window.scrollX;a.body.focus(),a.window.scrollTo(d,c)}else a.focus()}catch(e){}}}),b};for(var d,e={anchor:"~/dialogs/anchor/anchor.html",insertimage:"~/dialogs/image/image.html",link:"~/dialogs/link/link.html",spechars:"~/dialogs/spechars/spechars.html",searchreplace:"~/dialogs/searchreplace/searchreplace.html",map:"~/dialogs/map/map.html",gmap:"~/dialogs/gmap/gmap.html",insertvideo:"~/dialogs/video/video.html",help:"~/dialogs/help/help.html",preview:"~/dialogs/preview/preview.html",emotion:"~/dialogs/emotion/emotion.html",wordimage:"~/dialogs/wordimage/wordimage.html",attachment:"~/dialogs/attachment/attachment.html",insertframe:"~/dialogs/insertframe/insertframe.html",edittip:"~/dialogs/table/edittip.html",edittable:"~/dialogs/table/edittable.html",edittd:"~/dialogs/table/edittd.html",webapp:"~/dialogs/webapp/webapp.html",snapscreen:"~/dialogs/snapscreen/snapscreen.html",scrawl:"~/dialogs/scrawl/scrawl.html",music:"~/dialogs/music/music.html",template:"~/dialogs/template/template.html",background:"~/dialogs/background/background.html",charts:"~/dialogs/charts/charts.html"},f=["undo","redo","formatmatch","bold","italic","underline","fontborder","touppercase","tolowercase","strikethrough","subscript","superscript","source","indent","outdent","blockquote","pasteplain","pagebreak","selectall","print","horizontal","removeformat","time","date","unlink","insertparagraphbeforetable","insertrow","insertcol","mergeright","mergedown","deleterow","deletecol","splittorows","splittocols","splittocells","mergecells","deletetable","drafts"],g=0;d=f[g++];)d=d.toLowerCase(),b[d]=function(a){return function(c){var d=new b.Button({className:"edui-for-"+a,title:c.options.labelMap[a]||c.getLang("labelMap."+a)||"",onclick:function(){c.execCommand(a)},theme:c.options.theme,showText:!1});return b.buttons[a]=d,c.addListener("selectionchange",function(b,e,f){var g=c.queryCommandState(a);g==-1?(d.setDisabled(!0),d.setChecked(!1)):f||(d.setDisabled(!1),d.setChecked(g))}),d}}(d);b.cleardoc=function(a){var c=new b.Button({className:"edui-for-cleardoc",title:a.options.labelMap.cleardoc||a.getLang("labelMap.cleardoc")||"",theme:a.options.theme,onclick:function(){confirm(a.getLang("confirmClear"))&&a.execCommand("cleardoc")}});return b.buttons.cleardoc=c,a.addListener("selectionchange",function(){c.setDisabled(a.queryCommandState("cleardoc")==-1)}),c};var h={justify:["left","right","center","justify"],imagefloat:["none","left","center","right"],directionality:["ltr","rtl"]};for(var i in h)!function(a,c){for(var d,e=0;d=c[e++];)!function(c){b[a.replace("float","")+c]=function(d){var e=new b.Button({ -className:"edui-for-"+a.replace("float","")+c,title:d.options.labelMap[a.replace("float","")+c]||d.getLang("labelMap."+a.replace("float","")+c)||"",theme:d.options.theme,onclick:function(){d.execCommand(a,c)}});return b.buttons[a]=e,d.addListener("selectionchange",function(b,f,g){e.setDisabled(d.queryCommandState(a)==-1),e.setChecked(d.queryCommandValue(a)==c&&!g)}),e}}(d)}(i,h[i]);for(var d,g=0;d=["backcolor","forecolor"][g++];)b[d]=function(a){return function(c){var d=new b.ColorButton({className:"edui-for-"+a,color:"default",title:c.options.labelMap[a]||c.getLang("labelMap."+a)||"",editor:c,onpickcolor:function(b,d){c.execCommand(a,d)},onpicknocolor:function(){c.execCommand(a,"default"),this.setColor("transparent"),this.color="default"},onbuttonclick:function(){c.execCommand(a,this.color)}});return b.buttons[a]=d,c.addListener("selectionchange",function(){d.setDisabled(c.queryCommandState(a)==-1)}),d}}(d);var j={noOk:["searchreplace","help","spechars","webapp","preview"],ok:["attachment","anchor","link","insertimage","map","gmap","insertframe","wordimage","insertvideo","insertframe","edittip","edittable","edittd","scrawl","template","music","background","charts"]};for(var i in j)!function(c,d){for(var f,g=0;f=d[g++];)browser.opera&&"searchreplace"===f||!function(d){b[d]=function(f,g,h){g=g||(f.options.iframeUrlMap||{})[d]||e[d],h=f.options.labelMap[d]||f.getLang("labelMap."+d)||"";var i;g&&(i=new b.Dialog(a.extend({iframeUrl:f.ui.mapUrl(g),editor:f,className:"edui-for-"+d,title:h,holdScroll:"insertimage"===d,fullscreen:/charts|preview/.test(d),closeDialog:f.getLang("closeDialog")},"ok"==c?{buttons:[{className:"edui-okbutton",label:f.getLang("ok"),editor:f,onclick:function(){i.close(!0)}},{className:"edui-cancelbutton",label:f.getLang("cancel"),editor:f,onclick:function(){i.close(!1)}}]}:{})),f.ui._dialogs[d+"Dialog"]=i);var j=new b.Button({className:"edui-for-"+d,title:h,onclick:function(){if(i)switch(d){case"wordimage":var a=f.execCommand("wordimage");a&&a.length&&(i.render(),i.open());break;case"scrawl":f.queryCommandState("scrawl")!=-1&&(i.render(),i.open());break;default:i.render(),i.open()}},theme:f.options.theme,disabled:"scrawl"==d&&f.queryCommandState("scrawl")==-1||"charts"==d});return b.buttons[d]=j,f.addListener("selectionchange",function(){var a={edittable:1};if(!(d in a)){var b=f.queryCommandState(d);j.getDom()&&(j.setDisabled(b==-1),j.setChecked(b))}}),j}}(f.toLowerCase())}(i,j[i]);b.snapscreen=function(a,c,d){d=a.options.labelMap.snapscreen||a.getLang("labelMap.snapscreen")||"";var f=new b.Button({className:"edui-for-snapscreen",title:d,onclick:function(){a.execCommand("snapscreen")},theme:a.options.theme});if(b.buttons.snapscreen=f,c=c||(a.options.iframeUrlMap||{}).snapscreen||e.snapscreen){var g=new b.Dialog({iframeUrl:a.ui.mapUrl(c),editor:a,className:"edui-for-snapscreen",title:d,buttons:[{className:"edui-okbutton",label:a.getLang("ok"),editor:a,onclick:function(){g.close(!0)}},{className:"edui-cancelbutton",label:a.getLang("cancel"),editor:a,onclick:function(){g.close(!1)}}]});g.render(),a.ui._dialogs.snapscreenDialog=g}return a.addListener("selectionchange",function(){f.setDisabled(a.queryCommandState("snapscreen")==-1)}),f},b.insertcode=function(c,d,e){d=c.options.insertcode||[],e=c.options.labelMap.insertcode||c.getLang("labelMap.insertcode")||"";var f=[];a.each(d,function(a,b){f.push({label:a,value:b,theme:c.options.theme,renderLabelHtml:function(){return'
    '+(this.label||"")+"
    "}})});var g=new b.Combox({editor:c,items:f,onselect:function(a,b){c.execCommand("insertcode",this.items[b].value)},onbuttonclick:function(){this.showPopup()},title:e,initValue:e,className:"edui-for-insertcode",indexByValue:function(a){if(a)for(var b,c=0;b=this.items[c];c++)if(b.value.indexOf(a)!=-1)return c;return-1}});return b.buttons.insertcode=g,c.addListener("selectionchange",function(a,b,d){if(!d){var f=c.queryCommandState("insertcode");if(f==-1)g.setDisabled(!0);else{g.setDisabled(!1);var h=c.queryCommandValue("insertcode");if(!h)return void g.setValue(e);h&&(h=h.replace(/['"]/g,"").split(",")[0]),g.setValue(h)}}}),g},b.fontfamily=function(c,d,e){if(d=c.options.fontfamily||[],e=c.options.labelMap.fontfamily||c.getLang("labelMap.fontfamily")||"",d.length){for(var f,g=0,h=[];f=d[g];g++){var i=c.getLang("fontfamily")[f.name]||"";!function(b,d){h.push({label:b,value:d,theme:c.options.theme,renderLabelHtml:function(){return'
    '+(this.label||"")+"
    "}})}(f.label||i,f.val)}var j=new b.Combox({editor:c,items:h,onselect:function(a,b){c.execCommand("FontFamily",this.items[b].value)},onbuttonclick:function(){this.showPopup()},title:e,initValue:e,className:"edui-for-fontfamily",indexByValue:function(a){if(a)for(var b,c=0;b=this.items[c];c++)if(b.value.indexOf(a)!=-1)return c;return-1}});return b.buttons.fontfamily=j,c.addListener("selectionchange",function(a,b,d){if(!d){var e=c.queryCommandState("FontFamily");if(e==-1)j.setDisabled(!0);else{j.setDisabled(!1);var f=c.queryCommandValue("FontFamily");f&&(f=f.replace(/['"]/g,"").split(",")[0]),j.setValue(f)}}}),j}},b.fontsize=function(a,c,d){if(d=a.options.labelMap.fontsize||a.getLang("labelMap.fontsize")||"",c=c||a.options.fontsize||[],c.length){for(var e=[],f=0;f'+(this.label||"")+""}})}var h=new b.Combox({editor:a,items:e,title:d,initValue:d,onselect:function(b,c){a.execCommand("FontSize",this.items[c].value)},onbuttonclick:function(){this.showPopup()},className:"edui-for-fontsize"});return b.buttons.fontsize=h,a.addListener("selectionchange",function(b,c,d){if(!d){var e=a.queryCommandState("FontSize");e==-1?h.setDisabled(!0):(h.setDisabled(!1),h.setValue(a.queryCommandValue("FontSize")))}}),h}},b.paragraph=function(c,d,e){if(e=c.options.labelMap.paragraph||c.getLang("labelMap.paragraph")||"",d=c.options.paragraph||[],!a.isEmptyObject(d)){var f=[];for(var g in d)f.push({value:g,label:d[g]||c.getLang("paragraph")[g],theme:c.options.theme,renderLabelHtml:function(){return'
    '+(this.label||"")+"
    "}});var h=new b.Combox({editor:c,items:f,title:e,initValue:e,className:"edui-for-paragraph",onselect:function(a,b){c.execCommand("Paragraph",this.items[b].value)},onbuttonclick:function(){this.showPopup()}});return b.buttons.paragraph=h,c.addListener("selectionchange",function(a,b,d){if(!d){var e=c.queryCommandState("Paragraph");if(e==-1)h.setDisabled(!0);else{h.setDisabled(!1);var f=c.queryCommandValue("Paragraph"),g=h.indexByValue(f);g!=-1?h.setValue(f):h.setValue(h.initValue)}}}),h}},b.customstyle=function(a){var c=a.options.customstyle||[],d=a.options.labelMap.customstyle||a.getLang("labelMap.customstyle")||"";if(c.length){for(var e,f=a.getLang("customstyle"),g=0,h=[];e=c[g++];)!function(b){var c={};c.label=b.label?b.label:f[b.name],c.style=b.style,c.className=b.className,c.tag=b.tag,h.push({label:c.label,value:c,theme:a.options.theme,renderLabelHtml:function(){return'
    <'+c.tag+" "+(c.className?' class="'+c.className+'"':"")+(c.style?' style="'+c.style+'"':"")+">"+c.label+"
    "}})}(e);var i=new b.Combox({editor:a,items:h,title:d,initValue:d,className:"edui-for-customstyle",onselect:function(b,c){a.execCommand("customstyle",this.items[c].value)},onbuttonclick:function(){this.showPopup()},indexByValue:function(a){for(var b,c=0;b=this.items[c++];)if(b.label==a)return c-1;return-1}});return b.buttons.customstyle=i,a.addListener("selectionchange",function(b,c,d){if(!d){var e=a.queryCommandState("customstyle");if(e==-1)i.setDisabled(!0);else{i.setDisabled(!1);var f=a.queryCommandValue("customstyle"),g=i.indexByValue(f);g!=-1?i.setValue(f):i.setValue(i.initValue)}}}),i}},b.inserttable=function(a,c,d){d=a.options.labelMap.inserttable||a.getLang("labelMap.inserttable")||"";var e=new b.TableButton({editor:a,title:d,className:"edui-for-inserttable",onpicktable:function(b,c,d){a.execCommand("InsertTable",{numRows:d,numCols:c,border:1})},onbuttonclick:function(){this.showPopup()}});return b.buttons.inserttable=e,a.addListener("selectionchange",function(){e.setDisabled(a.queryCommandState("inserttable")==-1)}),e},b.lineheight=function(a){var c=a.options.lineheight||[];if(c.length){for(var d,e=0,f=[];d=c[e++];)f.push({label:d,value:d,theme:a.options.theme,onclick:function(){a.execCommand("lineheight",this.value)}});var g=new b.MenuButton({editor:a,className:"edui-for-lineheight",title:a.options.labelMap.lineheight||a.getLang("labelMap.lineheight")||"",items:f,onbuttonclick:function(){var b=a.queryCommandValue("LineHeight")||this.value;a.execCommand("LineHeight",b)}});return b.buttons.lineheight=g,a.addListener("selectionchange",function(){var b=a.queryCommandState("LineHeight");if(b==-1)g.setDisabled(!0);else{g.setDisabled(!1);var c=a.queryCommandValue("LineHeight");c&&g.setValue((c+"").replace(/cm/,"")),g.setChecked(b)}}),g}};for(var k,l=["top","bottom"],m=0;k=l[m++];)!function(a){b["rowspacing"+a]=function(c){var d=c.options["rowspacing"+a]||[];if(!d.length)return null;for(var e,f=0,g=[];e=d[f++];)g.push({label:e,value:e,theme:c.options.theme,onclick:function(){c.execCommand("rowspacing",this.value,a)}});var h=new b.MenuButton({editor:c,className:"edui-for-rowspacing"+a,title:c.options.labelMap["rowspacing"+a]||c.getLang("labelMap.rowspacing"+a)||"",items:g,onbuttonclick:function(){var b=c.queryCommandValue("rowspacing",a)||this.value;c.execCommand("rowspacing",b,a)}});return b.buttons[a]=h,c.addListener("selectionchange",function(){var b=c.queryCommandState("rowspacing",a);if(b==-1)h.setDisabled(!0);else{h.setDisabled(!1);var d=c.queryCommandValue("rowspacing",a);d&&h.setValue((d+"").replace(/%/,"")),h.setChecked(b)}}),h}}(k);for(var n,o=["insertorderedlist","insertunorderedlist"],p=0;n=o[p++];)!function(a){b[a]=function(c){var d=c.options[a],e=function(){c.execCommand(a,this.value)},f=[];for(var g in d)f.push({label:d[g]||c.getLang()[a][g]||"",value:g,theme:c.options.theme,onclick:e});var h=new b.MenuButton({editor:c,className:"edui-for-"+a,title:c.getLang("labelMap."+a)||"",items:f,onbuttonclick:function(){var b=c.queryCommandValue(a)||this.value;c.execCommand(a,b)}});return b.buttons[a]=h,c.addListener("selectionchange",function(){var b=c.queryCommandState(a);if(b==-1)h.setDisabled(!0);else{h.setDisabled(!1);var d=c.queryCommandValue(a);h.setValue(d),h.setChecked(b)}}),h}}(n);b.fullscreen=function(a,c){c=a.options.labelMap.fullscreen||a.getLang("labelMap.fullscreen")||"";var d=new b.Button({className:"edui-for-fullscreen",title:c,theme:a.options.theme,onclick:function(){a.ui&&a.ui.setFullScreen(!a.ui.isFullScreen()),this.setChecked(a.ui.isFullScreen())}});return b.buttons.fullscreen=d,a.addListener("selectionchange",function(){var b=a.queryCommandState("fullscreen");d.setDisabled(b==-1),d.setChecked(a.ui.isFullScreen())}),d},b.emotion=function(a,c){var d="emotion",f=new b.MultiMenuPop({title:a.options.labelMap[d]||a.getLang("labelMap."+d)||"",editor:a,className:"edui-for-"+d,iframeUrl:a.ui.mapUrl(c||(a.options.iframeUrlMap||{})[d]||e[d])});return b.buttons[d]=f,a.addListener("selectionchange",function(){f.setDisabled(a.queryCommandState(d)==-1)}),f},b.autotypeset=function(a){var c=new b.AutoTypeSetButton({editor:a,title:a.options.labelMap.autotypeset||a.getLang("labelMap.autotypeset")||"",className:"edui-for-autotypeset",onbuttonclick:function(){a.execCommand("autotypeset")}});return b.buttons.autotypeset=c,a.addListener("selectionchange",function(){c.setDisabled(a.queryCommandState("autotypeset")==-1)}),c},b.simpleupload=function(a){var c="simpleupload",d=new b.Button({className:"edui-for-"+c,title:a.options.labelMap[c]||a.getLang("labelMap."+c)||"",onclick:function(){},theme:a.options.theme,showText:!1});return b.buttons[c]=d,a.addListener("ready",function(){var b=d.getDom("body"),c=b.children[0];a.fireEvent("simpleuploadbtnready",c)}),a.addListener("selectionchange",function(b,e,f){var g=a.queryCommandState(c);g==-1?(d.setDisabled(!0),d.setChecked(!1)):f||(d.setDisabled(!1),d.setChecked(g))}),d}}(),function(){function a(a){this.initOptions(a),this.initEditorUI()}var b=baidu.editor.utils,c=baidu.editor.ui.uiUtils,d=baidu.editor.ui.UIBase,e=baidu.editor.dom.domUtils,f=[];a.prototype={uiName:"editor",initEditorUI:function(){function a(a,b){a.setOpt({wordCount:!0,maximumWords:1e4,wordCountMsg:a.options.wordCountMsg||a.getLang("wordCountMsg"),wordOverFlowMsg:a.options.wordOverFlowMsg||a.getLang("wordOverFlowMsg")});var c=a.options,d=c.maximumWords,e=c.wordCountMsg,f=c.wordOverFlowMsg,g=b.getDom("wordcount");if(c.wordCount){var h=a.getContentLength(!0);h>d?(g.innerHTML=f,a.fireEvent("wordcountoverflow")):g.innerHTML=e.replace("{#leave}",d-h).replace("{#count}",h)}}this.editor.ui=this,this._dialogs={},this.initUIBase(),this._initToolbars();var b=this.editor,c=this;b.addListener("ready",function(){function d(){a(b,c),e.un(b.document,"click",arguments.callee)}b.getDialog=function(a){return b.ui._dialogs[a+"Dialog"]},e.on(b.window,"scroll",function(a){baidu.editor.ui.Popup.postHide(a)}),b.ui._actualFrameWidth=b.options.initialFrameWidth,UE.browser.ie&&6===UE.browser.version&&b.container.ownerDocument.execCommand("BackgroundImageCache",!1,!0),b.options.elementPathEnabled&&(b.ui.getDom("elementpath").innerHTML='
    '+b.getLang("elementPathTip")+":
    "),b.options.wordCount&&(e.on(b.document,"click",d),b.ui.getDom("wordcount").innerHTML=b.getLang("wordCountTip")),b.ui._scale(),b.options.scaleEnabled?(b.autoHeightEnabled&&b.disableAutoHeight(),c.enableScale()):c.disableScale(),b.options.elementPathEnabled||b.options.wordCount||b.options.scaleEnabled||(b.ui.getDom("elementpath").style.display="none",b.ui.getDom("wordcount").style.display="none",b.ui.getDom("scale").style.display="none"),b.selection.isFocus()&&b.fireEvent("selectionchange",!1,!0)}),b.addListener("mousedown",function(a,b){var c=b.target||b.srcElement;baidu.editor.ui.Popup.postHide(b,c),baidu.editor.ui.ShortCutMenu.postHide(b)}),b.addListener("delcells",function(){UE.ui.edittip&&new UE.ui.edittip(b),b.getDialog("edittip").open()});var d,f,g=!1;b.addListener("afterpaste",function(){b.queryCommandState("pasteplain")||(baidu.editor.ui.PastePicker&&(d=new baidu.editor.ui.Popup({content:new baidu.editor.ui.PastePicker({editor:b}),editor:b,className:"edui-wordpastepop"}),d.render()),g=!0)}),b.addListener("afterinserthtml",function(){clearTimeout(f),f=setTimeout(function(){if(d&&(g||b.ui._isTransfer)){if(d.isHidden()){var a=e.createElement(b.document,"span",{style:"line-height:0px;",innerHTML:"\ufeff"}),c=b.selection.getRange();c.insertNode(a);var f=getDomNode(a,"firstChild","previousSibling");f&&d.showAnchor(3==f.nodeType?f.parentNode:f),e.remove(a)}else d.show();delete b.ui._isTransfer,g=!1}},200)}),b.addListener("contextmenu",function(a,b){baidu.editor.ui.Popup.postHide(b)}),b.addListener("keydown",function(a,b){d&&d.dispose(b);var c=b.keyCode||b.which;b.altKey&&90==c&&UE.ui.buttons.fullscreen.onclick()}),b.addListener("wordcount",function(b){a(this,c)}),b.addListener("selectionchange",function(){b.options.elementPathEnabled&&c[(b.queryCommandState("elementpath")==-1?"dis":"en")+"ableElementPath"](),b.options.scaleEnabled&&c[(b.queryCommandState("scale")==-1?"dis":"en")+"ableScale"]()});var h=new baidu.editor.ui.Popup({editor:b,content:"",className:"edui-bubble",_onEditButtonClick:function(){this.hide(),b.ui._dialogs.linkDialog.open()},_onImgEditButtonClick:function(a){this.hide(),b.ui._dialogs[a]&&b.ui._dialogs[a].open()},_onImgSetFloat:function(a){this.hide(),b.execCommand("imagefloat",a)},_setIframeAlign:function(a){var b=h.anchorEl,c=b.cloneNode(!0);switch(a){case-2:c.setAttribute("align","");break;case-1:c.setAttribute("align","left");break;case 1:c.setAttribute("align","right")}b.parentNode.insertBefore(c,b),e.remove(b),h.anchorEl=c,h.showAnchor(h.anchorEl)},_updateIframe:function(){var a=b._iframe=h.anchorEl;e.hasClass(a,"ueditor_baidumap")?(b.selection.getRange().selectNode(a).select(),b.ui._dialogs.mapDialog.open(),h.hide()):(b.ui._dialogs.insertframeDialog.open(),h.hide())},_onRemoveButtonClick:function(a){b.execCommand(a),this.hide()},queryAutoHide:function(a){return a&&a.ownerDocument==b.document&&("img"==a.tagName.toLowerCase()||e.findParentByTagName(a,"a",!0))?a!==h.anchorEl:baidu.editor.ui.Popup.prototype.queryAutoHide.call(this,a)}});h.render(),b.options.imagePopup&&(b.addListener("mouseover",function(a,c){c=c||window.event;var d=c.target||c.srcElement;if(b.ui._dialogs.insertframeDialog&&/iframe/gi.test(d.tagName)){var e=h.formatHtml(""+b.getLang("property")+': '+b.getLang("default")+'  '+b.getLang("justifyleft")+'  '+b.getLang("justifyright")+'   '+b.getLang("modify")+"");e?(h.getDom("content").innerHTML=e,h.anchorEl=d,h.showAnchor(h.anchorEl)):h.hide()}}),b.addListener("selectionchange",function(a,c){if(c){var d="",f="",g=b.selection.getRange().getClosedNode(),i=b.ui._dialogs;if(g&&"IMG"==g.tagName){var j="insertimageDialog";if(g.className.indexOf("edui-faked-video")==-1&&g.className.indexOf("edui-upload-video")==-1||(j="insertvideoDialog"),g.className.indexOf("edui-faked-webapp")!=-1&&(j="webappDialog"),g.src.indexOf("http://api.map.baidu.com")!=-1&&(j="mapDialog"),g.className.indexOf("edui-faked-music")!=-1&&(j="musicDialog"),g.src.indexOf("http://maps.google.com/maps/api/staticmap")!=-1&&(j="gmapDialog"),g.getAttribute("anchorname")&&(j="anchorDialog",d=h.formatHtml(""+b.getLang("property")+': '+b.getLang("modify")+"  "+b.getLang("delete")+"")),g.getAttribute("word_img")&&(b.word_img=[g.getAttribute("word_img")],j="wordimageDialog"),(e.hasClass(g,"loadingclass")||e.hasClass(g,"loaderrorclass"))&&(j=""),!i[j])return;f=""+b.getLang("property")+': '+b.getLang("default")+'  '+b.getLang("justifyleft")+'  '+b.getLang("justifyright")+'  '+b.getLang("justifycenter")+"  '+b.getLang("modify")+"",!d&&(d=h.formatHtml(f))}if(b.ui._dialogs.linkDialog){var k,l=b.queryCommandValue("link");if(l&&(k=l.getAttribute("_href")||l.getAttribute("href",2))){var m=k;k.length>30&&(m=k.substring(0,20)+"..."),d&&(d+='
    '),d+=h.formatHtml(""+b.getLang("anthorMsg")+': '+m+' '+b.getLang("modify")+' '+b.getLang("clear")+""),h.showAnchor(l)}}d?(h.getDom("content").innerHTML=d,h.anchorEl=g||l,h.showAnchor(h.anchorEl)):h.hide()}}))},_initToolbars:function(){for(var a=this.editor,c=this.toolbars||[],d=[],e=0;e
    '+(this.toolbars.length?'
    '+this.renderToolbarBoxHtml()+"
    ":"")+'
    '},showWordImageDialog:function(){this._dialogs.wordimageDialog.open()},renderToolbarBoxHtml:function(){for(var a=[],b=0;b'+c+"
    ");b.innerHTML='
    '+this.editor.getLang("elementPathTip")+": "+d.join(" > ")+"
    "}else b.style.display="none"},disableElementPath:function(){var a=this.getDom("elementpath");a.innerHTML="",a.style.display="none",this.elementPathEnabled=!1},enableElementPath:function(){var a=this.getDom("elementpath");a.style.display="",this.elementPathEnabled=!0,this._updateElementPath()},_scale:function(){function a(){o=e.getXY(h),p||(p=g.options.minFrameHeight+j.offsetHeight+k.offsetHeight),m.style.cssText="position:absolute;left:0;display:;top:0;background-color:#41ABFF;opacity:0.4;filter: Alpha(opacity=40);width:"+h.offsetWidth+"px;height:"+h.offsetHeight+"px;z-index:"+(g.options.zIndex+1),e.on(f,"mousemove",b),e.on(i,"mouseup",c),e.on(f,"mouseup",c)}function b(a){d();var b=a||window.event;r=b.pageX||f.documentElement.scrollLeft+b.clientX,s=b.pageY||f.documentElement.scrollTop+b.clientY,t=r-o.x,u=s-o.y,t>=q&&(n=!0,m.style.width=t+"px"),u>=p&&(n=!0,m.style.height=u+"px")}function c(){n&&(n=!1,g.ui._actualFrameWidth=m.offsetWidth-2,h.style.width=g.ui._actualFrameWidth+"px",g.setHeight(m.offsetHeight-k.offsetHeight-j.offsetHeight-2,!0)),m&&(m.style.display="none"),d(),e.un(f,"mousemove",b),e.un(i,"mouseup",c),e.un(f,"mouseup",c)}function d(){browser.ie?f.selection.clear():window.getSelection().removeAllRanges()}var f=document,g=this.editor,h=g.container,i=g.document,j=this.getDom("toolbarbox"),k=this.getDom("bottombar"),l=this.getDom("scale"),m=this.getDom("scalelayer"),n=!1,o=null,p=0,q=g.options.minFrameWidth,r=0,s=0,t=0,u=0,v=this;this.editor.addListener("fullscreenchanged",function(a,b){if(b)v.disableScale();else if(v.editor.options.scaleEnabled){v.enableScale();var c=v.editor.document.createElement("span");v.editor.body.appendChild(c),v.editor.body.style.height=Math.max(e.getXY(c).y,v.editor.iframe.offsetHeight-20)+"px",e.remove(c)}}),this.enableScale=function(){1!=g.queryCommandState("source")&&(l.style.display="",this.scaleEnabled=!0,e.on(l,"mousedown",a))},this.disableScale=function(){l.style.display="none",this.scaleEnabled=!1,e.un(l,"mousedown",a)}},isFullScreen:function(){return this._fullscreen},postRender:function(){d.prototype.postRender.call(this);for(var a=0;a[\n\r\t]+([ ]{4})+/g,">").replace(/[\n\r\t]+([ ]{4})+[\n\r\t]+<"),c.className&&(b.className=c.className),c.style.cssText&&(b.style.cssText=c.style.cssText),/textarea/i.test(c.tagName)?(d.textarea=c,d.textarea.style.display="none"):c.parentNode.removeChild(c),c.id&&(b.id=c.id,e.removeAttributes(c,"id")),c=b,c.innerHTML=""}e.addClass(c,"edui-"+d.options.theme),d.ui.render(c);var h=d.options;d.container=d.ui.getDom();for(var i,j=e.findParents(c,!0),k=[],l=0;i=j[l];l++)k[l]=i.style.display,i.style.display="block";if(h.initialFrameWidth)h.minFrameWidth=h.initialFrameWidth;else{h.minFrameWidth=h.initialFrameWidth=c.offsetWidth;var m=c.style.width;/%$/.test(m)&&(h.initialFrameWidth=m)}h.initialFrameHeight?h.minFrameHeight=h.initialFrameHeight:h.initialFrameHeight=h.minFrameHeight=c.offsetHeight;for(var i,l=0;i=j[l];l++)i.style.display=k[l];c.style.height&&(c.style.height=""),d.container.style.width=h.initialFrameWidth+(/%$/.test(h.initialFrameWidth)?"":"px"),d.container.style.zIndex=h.zIndex,f.call(d,d.ui.getDom("iframeholder")),d.fireEvent("afteruiready")}d.langIsReady?b():d.addListener("langReady",b)})},d},UE.getEditor=function(a,b){var c=g[a];return c||(c=g[a]=new UE.ui.Editor(b),c.render(a)),c},UE.delEditor=function(a){var b;(b=g[a])&&(b.key&&b.destroy(),delete g[a])},UE.registerUI=function(a,c,d,e){b.each(a.split(/\s+/),function(a){UE._customizeUI[a]={id:e,execFn:c,index:d}})}}(),UE.registerUI("message",function(a){function b(){var a=g.ui.getDom("toolbarbox");a&&(c.style.top=a.offsetHeight+3+"px"),c.style.zIndex=Math.max(g.options.zIndex,g.iframe.style.zIndex)+1}var c,d=baidu.editor.ui,e=d.Message,f=[],g=a;g.addListener("ready",function(){c=document.getElementById(g.ui.id+"_message_holder"),b(),setTimeout(function(){b()},500)}),g.addListener("showmessage",function(a,d){d=utils.isString(d)?{content:d}:d;var h=new e({timeout:d.timeout,type:d.type,content:d.content,keepshow:d.keepshow,editor:g}),i=d.id||"msg_"+(+new Date).toString(36);return h.render(c),f[i]=h,h.reset(d),b(),i}),g.addListener("updatemessage",function(a,b,d){d=utils.isString(d)?{content:d}:d;var e=f[b];e.render(c),e&&e.reset(d)}),g.addListener("hidemessage",function(a,b){var c=f[b];c&&c.hide()})}),UE.registerUI("autosave",function(a){var b=null,c=null;a.on("afterautosave",function(){clearTimeout(b),b=setTimeout(function(){c&&a.trigger("hidemessage",c),c=a.trigger("showmessage",{content:a.getLang("autosave.success"),timeout:2e3})},2e3)})})}(); \ No newline at end of file diff --git a/SiteServer.Web/SiteServer.API.csproj b/SiteServer.Web/SiteServer.API.csproj deleted file mode 100644 index 7887df566..000000000 --- a/SiteServer.Web/SiteServer.API.csproj +++ /dev/null @@ -1,187 +0,0 @@ - - - - - Debug - AnyCPU - - - 2.0 - {69C00F60-F28A-4CBC-B1A4-2DB73BB97471} - {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} - Library - Properties - SiteServer.API - SiteServer.API - v4.5.2 - true - - - - - - - - - - - - true - full - false - bin\ - DEBUG;TRACE - prompt - 4 - - - true - pdbonly - true - bin\ - TRACE - prompt - 4 - - - - ..\packages\Microsoft.AspNet.SignalR.Core.2.2.2\lib\net45\Microsoft.AspNet.SignalR.Core.dll - - - ..\packages\Microsoft.AspNet.SignalR.SystemWeb.2.2.2\lib\net45\Microsoft.AspNet.SignalR.SystemWeb.dll - - - - ..\packages\Microsoft.Owin.3.1.0\lib\net45\Microsoft.Owin.dll - - - ..\packages\Microsoft.Owin.Host.SystemWeb.3.1.0\lib\net45\Microsoft.Owin.Host.SystemWeb.dll - - - ..\packages\Microsoft.Owin.Security.3.1.0\lib\net45\Microsoft.Owin.Security.dll - - - ..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll - - - ..\packages\Owin.1.0\lib\net40\Owin.dll - - - ..\packages\SiteServer.Plugin.1.5.0\lib\net45\SiteServer.Plugin.dll - - - - - ..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll - - - ..\packages\Microsoft.AspNet.Cors.5.2.3\lib\net45\System.Web.Cors.dll - - - - - - - - - - ..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll - - - ..\packages\Microsoft.AspNet.WebApi.Cors.5.2.3\lib\net45\System.Web.Http.Cors.dll - - - ..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.3\lib\net45\System.Web.Http.WebHost.dll - - - - - - - - - - - - - Web.config - - - - - Designer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {6aa1713a-3b77-4b20-b8c7-fcb6de556f64} - SiteServer.BackgroundPages - - - {944127c3-915d-4f02-a534-64ec668c46ec} - SiteServer.CMS - - - {2176d8ba-5f57-4c56-8e21-a09011517ae2} - SiteServer.Utils - - - - 10.0 - $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) - - - - - - - - - True - - - - - - - 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Account/pagePassword.aspx b/SiteServer.Web/SiteServer/Account/pagePassword.aspx deleted file mode 100644 index f2d457886..000000000 --- a/SiteServer.Web/SiteServer/Account/pagePassword.aspx +++ /dev/null @@ -1,79 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Account.PagePassword" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - -
    - -
    - - - -
    -
    - -
    - -
    -
    - -
    - - - - - -
    - -
    - - -
    - -
    - - -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Account/pageProfile.aspx b/SiteServer.Web/SiteServer/Account/pageProfile.aspx deleted file mode 100644 index 08df75b9e..000000000 --- a/SiteServer.Web/SiteServer/Account/pageProfile.aspx +++ /dev/null @@ -1,72 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Account.PageProfile" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - -
    - -
    - - - -
    -
    - -
    - -
    -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/modalContentArchive.aspx b/SiteServer.Web/SiteServer/Cms/modalContentArchive.aspx deleted file mode 100644 index b37b11e5d..000000000 --- a/SiteServer.Web/SiteServer/Cms/modalContentArchive.aspx +++ /dev/null @@ -1,30 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.ModalContentArchive" Trace="false"%> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    -
    此操作将归档所选内容,确认吗?
    -
    - -
    - -
    - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/modalSelectColumns.aspx b/SiteServer.Web/SiteServer/Cms/modalSelectColumns.aspx deleted file mode 100644 index 92292deb3..000000000 --- a/SiteServer.Web/SiteServer/Cms/modalSelectColumns.aspx +++ /dev/null @@ -1,34 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.ModalSelectColumns" Trace="false"%> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    - -
    - -
    -
    -
    - -
    - -
    - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/modalSiteSelect.aspx b/SiteServer.Web/SiteServer/Cms/modalSiteSelect.aspx deleted file mode 100644 index 6e7085e61..000000000 --- a/SiteServer.Web/SiteServer/Cms/modalSiteSelect.aspx +++ /dev/null @@ -1,23 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.ModalSiteSelect" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/modalTemplateFilePathRule.aspx b/SiteServer.Web/SiteServer/Cms/modalTemplateFilePathRule.aspx deleted file mode 100644 index f5799a429..000000000 --- a/SiteServer.Web/SiteServer/Cms/modalTemplateFilePathRule.aspx +++ /dev/null @@ -1,65 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.ModalTemplateFilePathRule" Trace="false"%> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - -
    - -
    - -
    -
    - -
    -
    -
    - -
    - -
    - -
    -
    - -
    -
    - 系统生成文件时采取的下级栏目页文件名规则 -
    -
    - -
    - -
    - -
    -
    - -
    -
    - 系统生成文件时采取的下级内容页文件名规则 -
    -
    - -
    - -
    - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertImage.aspx b/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertImage.aspx deleted file mode 100644 index c9edf59be..000000000 --- a/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertImage.aspx +++ /dev/null @@ -1,191 +0,0 @@ -<%@ Page Language="C#" Trace="false" Inherits="SiteServer.BackgroundPages.Cms.ModalTextEditorInsertImage" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - - -
    - - - - -
    - 点击批量上传图片或者将图片拖拽到此区域 -
    - -
    - -
    - -
    - -
    -

    - {{ file.fileName }} -
    大小:{{ Math.round(file.length/1024) + ' KB' }} -

    - 删 除 -
    - -
    - -
    - -
    - -
    - - - - - - - - -
    - -
    - -
    - - -
    - - - - - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertVideo.aspx b/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertVideo.aspx deleted file mode 100644 index 98c9805a8..000000000 --- a/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertVideo.aspx +++ /dev/null @@ -1,124 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.ModalTextEditorInsertVideo" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    - -
    - -
    - -
    -
    - 上 传 - -
    -
    -
    -
    - - - -
    - -
    - -
    -
    - -
    -
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    -
    - -
    -
    -
    -
    - -
    - -
    - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/modalUploadWord.aspx b/SiteServer.Web/SiteServer/Cms/modalUploadWord.aspx deleted file mode 100644 index 61501e1b4..000000000 --- a/SiteServer.Web/SiteServer/Cms/modalUploadWord.aspx +++ /dev/null @@ -1,183 +0,0 @@ -<%@ Page Language="C#" Trace="false" Inherits="SiteServer.BackgroundPages.Cms.ModalUploadWord" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - - -
    - - - - -
    - 点击批量上传Word文件或者将Word文件拖拽到此区域 -
    - -
    - -
    - -
    - -
    -

    - {{ file.fileName }} -
    大小:{{ Math.round(file.length/1024) + ' KB' }} -

    - 删 除 -
    - -
    - -
    - -
    - -
    - -
    -
    - - - -
    - - - - -
    -
    -
    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    - - -
    - - - - - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageChannel.aspx b/SiteServer.Web/SiteServer/Cms/pageChannel.aspx deleted file mode 100644 index b85c88329..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageChannel.aspx +++ /dev/null @@ -1,77 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageChannel" enableViewState="false" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    -
    - 栏目管理 -
    -

    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - -
    栏目名所属栏目组栏目索引上升下降 
    -
    -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageChannelAdd.aspx b/SiteServer.Web/SiteServer/Cms/pageChannelAdd.aspx deleted file mode 100644 index 2a240f59c..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageChannelAdd.aspx +++ /dev/null @@ -1,223 +0,0 @@ -<%@ Page Language="C#" ValidateRequest="false" Inherits="SiteServer.BackgroundPages.Cms.PageChannelAdd" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    -
    - 添加栏目 -
    -

    - -
    - -
    - -
    -
    -
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    - -
    -
    -
    - - -
    - -
    - -
    -
    -
    - -
    - -
    - -
    -
    - 设置后链接将指向此地址 - -
    -
    -
    - -
    - -
    -
    - 设置此栏目的链接与子栏目及内容的关系 -
    -
    -
    - -
    - -
    -
    - 设置内容默认排序规则后,后台内容列表将改变排序显示规则 -
    -
    -
    - -
    - -
    -
    -
    -
    - -
    - -
    -
    -
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    - - - - -
    -
    -
    -
    - -
    - - - - -
    -
    -
    -
    - -
    - -
    -
    - - -
    -
    -
    - -
    - -
    -
    -
    -
    - -
    - -
    -
    - - 注意:各关键词间用英文逗号“,”隔开。 -
    -
    -
    - -
    - -
    -
    - -
    -
    - - - -
    - -
    - -
    -
    - -
    - -
    -
    - - -
    -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageChannelEdit.aspx b/SiteServer.Web/SiteServer/Cms/pageChannelEdit.aspx deleted file mode 100644 index d3065bca3..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageChannelEdit.aspx +++ /dev/null @@ -1,215 +0,0 @@ -<%@ Page Language="C#" ValidateRequest="false" Inherits="SiteServer.BackgroundPages.Cms.PageChannelEdit" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    -
    - 编辑栏目 -
    -

    - -
    - -
    - -
    -
    - -
    -
    - -
    - -
    - -
    -
    - -
    -
    - -
    - -
    - -
    -
    -
    - - -
    - -
    - -
    -
    -
    - -
    - -
    - -
    -
    - 设置后链接将指向此地址 - -
    -
    -
    - -
    - -
    -
    - 设置此栏目的链接与子栏目及内容的关系 -
    -
    -
    - -
    - -
    -
    - 设置内容默认排序规则后,后台内容列表将改变排序显示规则 -
    -
    -
    - -
    - -
    -
    -
    -
    - -
    - -
    -
    -
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    - -
    -
    - -
    -
    -
    - -
    - - - - -
    -
    -
    -
    - -
    - - - - -
    -
    -
    -
    - -
    - -
    -
    - - -
    -
    -
    - -
    - -
    -
    -
    -
    - -
    - -
    -
    - - 注意:各关键词间用英文逗号“,”分割。 -
    -
    -
    - -
    - -
    -
    - -
    -
    - - - -
    - -
    - -
    -
    - -
    - -
    - - -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageChannelsGroup.aspx b/SiteServer.Web/SiteServer/Cms/pageChannelsGroup.aspx deleted file mode 100644 index 35e67982f..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageChannelsGroup.aspx +++ /dev/null @@ -1,79 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageChannelsGroup" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - -
    -

    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - -
    栏目名栏目索引添加日期
    - - - - - -
    -
    -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageConfigurationContent.aspx b/SiteServer.Web/SiteServer/Cms/pageConfigurationContent.aspx deleted file mode 100644 index 2d1ea2c12..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageConfigurationContent.aspx +++ /dev/null @@ -1,105 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationContent" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - -
    - -
    - - - -
    -
    - - -
    - -
    - - - - 如果修改了自动分页选项,需要将所有内容页重新生成 - -
    - - -
    - - -
    -
    - -
    - - - - 在标题中输入两连续的英文空格,内容页中标题将自动换行,列表页将忽略此空格 - -
    - -
    - - - - 当点击确定按钮保存内容的时候,会自动检测敏感词,弹框提示。 - -
    - -
    - - - - 选择内容审核的机制,需要多级审核的请选择多级审核机制,否则选择默认审核机制 - -
    - - -
    - - - - - - - - - 内容在添加后需要经多少次审核才能正式发布 - -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageConfigurationCreate.aspx b/SiteServer.Web/SiteServer/Cms/pageConfigurationCreate.aspx deleted file mode 100644 index 30584ea58..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageConfigurationCreate.aspx +++ /dev/null @@ -1,119 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationCreate" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - - - 此功能通常用于制作调试期间,网站开发期间建议启用 - -
    - -
    - - - - 设置翻页中生成的静态页面最大数,剩余页面将动态获取;设置为0代表将静态页面全部生成 - -
    - -
    - - - - 若启用此选项,系统将不再生成所选添加时间之前的内容页 - -
    - - -
    - - - - 在此设置内容添加日期,此日期之前的内容页将不再生成 - -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageConfigurationCreateRule.aspx b/SiteServer.Web/SiteServer/Cms/pageConfigurationCreateRule.aspx deleted file mode 100644 index 283d5c087..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageConfigurationCreateRule.aspx +++ /dev/null @@ -1,59 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationCreateRule" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    栏目名 页面路径
    -
    -
    -
    -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageConfigurationCreateTrigger.aspx b/SiteServer.Web/SiteServer/Cms/pageConfigurationCreateTrigger.aspx deleted file mode 100644 index b8732e374..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageConfigurationCreateTrigger.aspx +++ /dev/null @@ -1,60 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationCreateTrigger" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - -
    栏目名内容变动时需要生成的栏目 
    -
    -
    -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageConfigurationCrossSiteTrans.aspx b/SiteServer.Web/SiteServer/Cms/pageConfigurationCrossSiteTrans.aspx deleted file mode 100644 index 056f60793..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageConfigurationCrossSiteTrans.aspx +++ /dev/null @@ -1,43 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationCrossSiteTrans" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - - - -
    - -
    - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageConfigurationCrossSiteTransChannels.aspx b/SiteServer.Web/SiteServer/Cms/pageConfigurationCrossSiteTransChannels.aspx deleted file mode 100644 index cc84c225e..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageConfigurationCrossSiteTransChannels.aspx +++ /dev/null @@ -1,51 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationCrossSiteTransChannels" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    - - - - - - - - - - - - - - - -
    栏目名跨站转发设置
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageConfigurationSite.aspx b/SiteServer.Web/SiteServer/Cms/pageConfigurationSite.aspx deleted file mode 100644 index 25012c530..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageConfigurationSite.aspx +++ /dev/null @@ -1,61 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationSite" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - -
    - -
    - - - -
    -
    - - - 模板编码将同步修改 -
    - -
    - - -
    - -
    - - - 此功能通常用于制作调试期间,网站正式上线后不建议启用 -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageConfigurationSiteAttributes.aspx b/SiteServer.Web/SiteServer/Cms/pageConfigurationSiteAttributes.aspx deleted file mode 100644 index ff004f0ef..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageConfigurationSiteAttributes.aspx +++ /dev/null @@ -1,54 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationSiteAttributes" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - -
    - -
    - -
    - - - -
    -
    - - -
    - - - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadFile.aspx b/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadFile.aspx deleted file mode 100644 index 9eb104d45..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadFile.aspx +++ /dev/null @@ -1,101 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationUploadFile" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - - -
    - -
    - - - - 本设置只影响新上传的附件, 设置更改之前的附件仍存放在原来位置 - -
    - -
    - - - - 本设置只影响新上传的附件, 设置更改之前的附件名仍保持不变 - -
    - -
    - - - - 类型之间用“,”分割 - -
    - -
    - -
    -
    - -
    -
    - - - - -
    -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadImage.aspx b/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadImage.aspx deleted file mode 100644 index dbb810c20..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadImage.aspx +++ /dev/null @@ -1,123 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationUploadImage" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - - -
    - -
    - - - - 本设置只影响新上传的图片, 设置更改之前的图片仍存放在原来位置 - -
    - -
    - - - - 本设置只影响新上传的图片, 设置更改之前的图片名仍保持不变 - -
    - -
    - - - - 类型之间用“,”分割 - -
    - -
    - -
    -
    - -
    -
    - - - - -
    -
    -
    - -
    - - - 像素 -
    - -
    - - - 像素 -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadVideo.aspx b/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadVideo.aspx deleted file mode 100644 index 35c883282..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadVideo.aspx +++ /dev/null @@ -1,99 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationUploadVideo" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - - -
    - -
    - - - - 本设置只影响新上传的视频, 设置更改之前的视频仍存放在原来位置 - -
    - -
    - - - - 本设置只影响新上传的视频, 设置更改之前的视频名仍保持不变 - -
    - -
    - - - 类型之间用“,”分割 -
    - -
    - -
    -
    - -
    -
    - - - - -
    -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageConfigurationWatermark.aspx b/SiteServer.Web/SiteServer/Cms/pageConfigurationWatermark.aspx deleted file mode 100644 index c44bc87fa..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageConfigurationWatermark.aspx +++ /dev/null @@ -1,163 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationWaterMark" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - - -
    - - -
    - -
    - -
    - - 请在此选择水印添加的位置(共 9 个位置可选) - -
    -
    - - -
    - - - - 取值范围10%--100% (100%为不透明) - -
    -
    - - -
    - -
    - - - - -
    - - 需要添加水印的图片的最小尺寸,单位为像素,(0代表不限制) - -
    -
    - - -
    - - - - 选择使用的水印类型 - -
    -
    - - -
    - - - - 可以使用替换变量: {0}表示当前日期 {1}表示当前时间 例如:"上传于{0} {1}" - -
    -
    - - -
    - - -
    -
    - - -
    - - - - 像素 - -
    -
    - - -
    - - -
    - -
    -   - -   - -
    -
    -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageContentAdd.aspx b/SiteServer.Web/SiteServer/Cms/pageContentAdd.aspx deleted file mode 100644 index 4d1b69775..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageContentAdd.aspx +++ /dev/null @@ -1,223 +0,0 @@ -<%@ Page Language="C#" ValidateRequest="false" Inherits="SiteServer.BackgroundPages.Cms.PageContentAdd" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    -
    - -
    -

    - - - -
    - -
    - -
    - -
    -
    - - -
    -
    - - - -
    - - - -
    - -
    - - - - - 提示:按CTRL+回车可以快速提交 - -
    - -
    - - - - - - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageContentGroup.aspx b/SiteServer.Web/SiteServer/Cms/pageContentGroup.aspx deleted file mode 100644 index edee1fa29..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageContentGroup.aspx +++ /dev/null @@ -1,94 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageContentGroup" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    内容组名称 内容组简介
    - - - - - - - - - - - - - - - - - -
    -
    -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageContentTags.aspx b/SiteServer.Web/SiteServer/Cms/pageContentTags.aspx deleted file mode 100644 index 6df209fd2..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageContentTags.aspx +++ /dev/null @@ -1,105 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageContentTags" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - -
    标签 使用次数
    - - - - - - - -
    -
    -
    -
    - - - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageContentTree.aspx b/SiteServer.Web/SiteServer/Cms/pageContentTree.aspx deleted file mode 100644 index d1b7b71b2..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageContentTree.aspx +++ /dev/null @@ -1,57 +0,0 @@ -<%@ Page Language="C#" Trace="false" EnableViewState="false" Inherits="SiteServer.BackgroundPages.BasePageCms" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - - -
    -
    -
    - 栏目列表 -
    -
    - - - - -
    -
    - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageContentView.aspx b/SiteServer.Web/SiteServer/Cms/pageContentView.aspx deleted file mode 100644 index 01992271d..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageContentView.aspx +++ /dev/null @@ -1,101 +0,0 @@ -<%@ Page Language="C#" validateRequest="false" Inherits="SiteServer.BackgroundPages.Cms.PageContentView" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    -
    - 内容查看 -
    -

    - -
    - -
    - -
    -
    -
    - - -
    - -
    - -
    -
    -
    -
    - - -
    - -
    - -
    -
    -
    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    - -
    -
    -
    - - - - - - - -
    - -
    - - - -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageContentsGroup.aspx b/SiteServer.Web/SiteServer/Cms/pageContentsGroup.aspx deleted file mode 100644 index 3bd774e50..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageContentsGroup.aspx +++ /dev/null @@ -1,93 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageContentsGroup" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - -
    -

    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    内容标题(点击查看)所属栏目添加日期状态
    - - - - - - - - - - - -
    -
    -
    -
    - - - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageCreateAll.aspx b/SiteServer.Web/SiteServer/Cms/pageCreateAll.aspx deleted file mode 100644 index 8195e6675..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageCreateAll.aspx +++ /dev/null @@ -1 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageCreateAll" %> \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageCreateChannel.aspx b/SiteServer.Web/SiteServer/Cms/pageCreateChannel.aspx deleted file mode 100644 index 89c82490e..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageCreateChannel.aspx +++ /dev/null @@ -1,74 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageCreateChannel" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - -
    - - -
    -
    - 生成栏目页 -
    -

    - 选择需要生成页面的栏目后点击“生成选定栏目”即可生成对应得栏目页面,按住Ctrl可多选 -

    - -
    - -
    - -
    -
    - -
    -
    -
    - -
    - -
    -
    -
    - - -
    - -
    -
    - -
    - -
    - -
    - -
    -
    - -
    -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageCreateContent.aspx b/SiteServer.Web/SiteServer/Cms/pageCreateContent.aspx deleted file mode 100644 index 25bd64f62..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageCreateContent.aspx +++ /dev/null @@ -1,74 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageCreateContent" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - -
    - - -
    -
    - 生成内容页 -
    -

    - 选择需要生成内容页面的栏目后点击“生成选定内容”即可生成对应的内容页面,按住Ctrl可多选 -

    - -
    - -
    - -
    -
    - -
    -
    -
    - -
    - -
    -
    -
    - - -
    - -
    -
    - -
    - -
    - -
    - -
    -
    - -
    -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageCreateIndex.aspx b/SiteServer.Web/SiteServer/Cms/pageCreateIndex.aspx deleted file mode 100644 index debf80448..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageCreateIndex.aspx +++ /dev/null @@ -1 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageCreateIndex" %> \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageNodeGroup.aspx b/SiteServer.Web/SiteServer/Cms/pageNodeGroup.aspx deleted file mode 100644 index 2eb33cb10..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageNodeGroup.aspx +++ /dev/null @@ -1,94 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageNodeGroup" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    栏目组名称 栏目组简介
    - - - - - - - - - - - - - - - - - -
    -
    -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageRelatedField.aspx b/SiteServer.Web/SiteServer/Cms/pageRelatedField.aspx deleted file mode 100644 index ce12cde37..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageRelatedField.aspx +++ /dev/null @@ -1,90 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageRelatedField" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    联动字段名称 级数
    - - - - - - - - - - - -
    -
    -
    -
    - -
    - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageTableStyleChannel.aspx b/SiteServer.Web/SiteServer/Cms/pageTableStyleChannel.aspx deleted file mode 100644 index c397a5862..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageTableStyleChannel.aspx +++ /dev/null @@ -1,108 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageTableStyleChannel" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - 下级栏目的字段默认继承上级栏目的字段,设置字段时请先选择合适的栏目 - -
    -
    -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    字段名 显示名称 表单提交类型验证规则排序显示样式表单验证
    - - - - - - - - - - - - - -
    -
    -
    -
    - -
    - - - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageTableStyleContent.aspx b/SiteServer.Web/SiteServer/Cms/pageTableStyleContent.aspx deleted file mode 100644 index a1a8da7b0..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageTableStyleContent.aspx +++ /dev/null @@ -1,112 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageTableStyleContent" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - 下级栏目的字段默认继承上级栏目的字段,设置字段时请先选择合适的栏目 - -
    -
    -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    字段名 显示名称 表单提交类型字段类型验证规则排序显示样式表单验证
    - - - - - - - - - - - - - - - -
    -
    -
    -
    - -
    - - - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageTableStyleSite.aspx b/SiteServer.Web/SiteServer/Cms/pageTableStyleSite.aspx deleted file mode 100644 index e6cad18a7..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageTableStyleSite.aspx +++ /dev/null @@ -1,97 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageTableStyleSite" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    字段名 显示名称 表单提交类型验证规则排序显示样式表单验证
    - - - - - - - - - - - - - -
    -
    -
    -
    - -
    - - - - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageTemplateCss.aspx b/SiteServer.Web/SiteServer/Cms/pageTemplateCss.aspx deleted file mode 100644 index c58e0d773..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageTemplateCss.aspx +++ /dev/null @@ -1,73 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageTemplateCss" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    -
    - 样式文件管理 -
    -

    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - -
    文件名称 文件编码
    - - - - - - - - - -
    -
    -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageTemplateCssAdd.aspx b/SiteServer.Web/SiteServer/Cms/pageTemplateCssAdd.aspx deleted file mode 100644 index e78ee4050..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageTemplateCssAdd.aspx +++ /dev/null @@ -1,99 +0,0 @@ -<%@ Page Language="C#" validateRequest="false" Inherits="SiteServer.BackgroundPages.Cms.PageTemplateCssAdd" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - - -
    - - -
    -
    - -
    -

    - -

    - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - -
    -
    - - -
    - -
    - -
    - - - -
    - -
    - -
    - - -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageTemplateInclude.aspx b/SiteServer.Web/SiteServer/Cms/pageTemplateInclude.aspx deleted file mode 100644 index 4c866be16..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageTemplateInclude.aspx +++ /dev/null @@ -1,69 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageTemplateInclude" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    -
    - 包含文件管理 -
    -

    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - -
    文件名称 文件编码
    - - - - - - - -
    -
    -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageTemplateIncludeAdd.aspx b/SiteServer.Web/SiteServer/Cms/pageTemplateIncludeAdd.aspx deleted file mode 100644 index 530298791..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageTemplateIncludeAdd.aspx +++ /dev/null @@ -1,115 +0,0 @@ -<%@ Page Language="C#" validateRequest="false" Inherits="SiteServer.BackgroundPages.Cms.PageTemplateIncludeAdd" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - - - -
    - - -
    -
    - -
    -

    - -

    - -
    -
    - - -
    -
    - -
    - -
    -
    -
    - - -
    -
    - -
    -
    - - -
    - -
    - -
    - - - -
    - -
    - -
    - - -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageTemplateJs.aspx b/SiteServer.Web/SiteServer/Cms/pageTemplateJs.aspx deleted file mode 100644 index 29e6a5ebd..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageTemplateJs.aspx +++ /dev/null @@ -1,73 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageTemplateJs" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    -
    - 脚本文件管理 -
    -

    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - -
    文件名称 文件编码
    - - - - - - - - - -
    -
    -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageTemplateJsAdd.aspx b/SiteServer.Web/SiteServer/Cms/pageTemplateJsAdd.aspx deleted file mode 100644 index 8ecb13a71..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageTemplateJsAdd.aspx +++ /dev/null @@ -1,99 +0,0 @@ -<%@ Page Language="C#" validateRequest="false" Inherits="SiteServer.BackgroundPages.Cms.PageTemplateJsAdd" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - - -
    - - -
    -
    - -
    -

    - -

    - -
    -
    - - -
    -
    - - -
    -
    - - -
    -
    - -
    -
    - - -
    - -
    - -
    - - - -
    - -
    - -
    - - -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageTemplateLeft.aspx b/SiteServer.Web/SiteServer/Cms/pageTemplateLeft.aspx deleted file mode 100644 index f387694fe..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageTemplateLeft.aspx +++ /dev/null @@ -1,249 +0,0 @@ -<%@ Page Language="C#" Trace="false" EnableViewState="false" Inherits="SiteServer.BackgroundPages.Cms.PageTemplateLeft" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - - -
    -
    -
    - 模板列表 -
    -
    - - - - - - - - - - - - - - - - - - - - - - -
    - - - 所有模板 - - - - -
    - - - - 首页模板 - - - -
    - - - - 栏目模板 - - - -
    - - - - 内容模板 - - - -
    - - - - 单页模板 - - - -
    -
    - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageTemplateReference.aspx b/SiteServer.Web/SiteServer/Cms/pageTemplateReference.aspx deleted file mode 100644 index 7edab340d..000000000 --- a/SiteServer.Web/SiteServer/Cms/pageTemplateReference.aspx +++ /dev/null @@ -1,60 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageTemplateReference" enableviewstate="false"%> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    -
    - STL语言参考 -
    -

    - STL语言为SiteServer模板语言(SiteServer Template Language)的缩写,是一种和HTML语言类似的服务器端语言。 - STL 语言参考手册 -

    - - -
    - -
    -
    - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Inc/foot.html b/SiteServer.Web/SiteServer/Inc/foot.html deleted file mode 100644 index 6b773e134..000000000 --- a/SiteServer.Web/SiteServer/Inc/foot.html +++ /dev/null @@ -1,30 +0,0 @@ - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Installer/default.aspx b/SiteServer.Web/SiteServer/Installer/default.aspx deleted file mode 100644 index 463131706..000000000 --- a/SiteServer.Web/SiteServer/Installer/default.aspx +++ /dev/null @@ -1,447 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.PageInstaller" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - SiteServer CMS 安装向导 - - - - - - - - -
    - -
    -

    - SiteServer CMS - 安装向导 -

    -

    - 欢迎来到SiteServer CMS 安装向导!只要进行以下几步操作,你就可以开始使用强大且可扩展的CMS系统了。 -

    - - - - - - - - -
    - -
    - - - -
    - -
    - - -
    - -
    - - - - - - -
    - - 下表显示当前服务器环境 -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    参数
    服务器域名 - -
    SiteServer 版本 - -
    .NET版本 - -
    系统根目录 - -
    -
    -
    -
    - -
    - - - 系统要求必须满足下列所有的目录权限全部可读写的需求才能使用,如果没有相关权限请添加。 - -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - -
    目录名读写权限
    /* - -
    /SiteFiles/* - -
    -
    -
    -
    - -
    - -
    - - -
    - -
    - - - - - - -
    - - - - 请选择需要安装的数据库类型。 - -
    - - -
    - - - - IP地址或者服务器名 - -
    -
    - - -
    - - -
    - - - - 连接数据库的端口 - -
    -
    - -
    - - - - 连接数据库的用户名 - -
    -
    - - - - 连接数据库的密码 - -
    - - -
    - - - - 指定需要安装的Oracle数据库名称 - -
    -
    - -
    - - - -
    - - - - 选择安装的数据库 - -
    - -
    - -
    - -
    - - -
    - -
    - - - - - - -
    - - - - 在此设置总管理员的登录用户名 - -
    - -
    - - - - 密码强度: - - -
    -
    - - - - 6-16个字符,支持大小写字母、数字和符号 - -
    -
    - - - - 设置是否加密Web.Config中的数据库连接字符串 - -
    - -
    - -
    - - -
    - -
    - - - - - - - - - - -
    - -
    - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Pic/login/ynu_sico1.jpg b/SiteServer.Web/SiteServer/Pic/login/ynu_sico1.jpg deleted file mode 100644 index 62b127257..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/ynu_sico1.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/ynu_sico2.jpg b/SiteServer.Web/SiteServer/Pic/login/ynu_sico2.jpg deleted file mode 100644 index 9558293cd..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/ynu_sico2.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/ynu_sico3.jpg b/SiteServer.Web/SiteServer/Pic/login/ynu_sico3.jpg deleted file mode 100644 index 434c43682..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/ynu_sico3.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/ynu_sico4.jpg b/SiteServer.Web/SiteServer/Pic/login/ynu_sico4.jpg deleted file mode 100644 index 5d4b8382d..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/ynu_sico4.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/yunBg.jpg b/SiteServer.Web/SiteServer/Pic/login/yunBg.jpg deleted file mode 100644 index 89840c220..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/yunBg.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/yun_1.jpg b/SiteServer.Web/SiteServer/Pic/login/yun_1.jpg deleted file mode 100644 index c1ea6acd1..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/yun_1.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/yun_btn.jpg b/SiteServer.Web/SiteServer/Pic/login/yun_btn.jpg deleted file mode 100644 index 27ec5bc36..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/yun_btn.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/yun_fico1.jpg b/SiteServer.Web/SiteServer/Pic/login/yun_fico1.jpg deleted file mode 100644 index a5b640ea7..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/yun_fico1.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/yun_fico2.jpg b/SiteServer.Web/SiteServer/Pic/login/yun_fico2.jpg deleted file mode 100644 index 09ea63ce6..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/yun_fico2.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/yun_fico3.jpg b/SiteServer.Web/SiteServer/Pic/login/yun_fico3.jpg deleted file mode 100644 index 8ba2a8fb5..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/yun_fico3.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/yun_fico4.jpg b/SiteServer.Web/SiteServer/Pic/login/yun_fico4.jpg deleted file mode 100644 index 53b0862cd..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/yun_fico4.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/yun_ico1.jpg b/SiteServer.Web/SiteServer/Pic/login/yun_ico1.jpg deleted file mode 100644 index 2e63ffdcb..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/yun_ico1.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/yun_ico2.jpg b/SiteServer.Web/SiteServer/Pic/login/yun_ico2.jpg deleted file mode 100644 index 57a91a419..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/yun_ico2.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/yun_ico3.jpg b/SiteServer.Web/SiteServer/Pic/login/yun_ico3.jpg deleted file mode 100644 index 44010e718..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/yun_ico3.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/yun_serBtn.jpg b/SiteServer.Web/SiteServer/Pic/login/yun_serBtn.jpg deleted file mode 100644 index 8f48f8e22..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/yun_serBtn.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/yun_serintBg.jpg b/SiteServer.Web/SiteServer/Pic/login/yun_serintBg.jpg deleted file mode 100644 index 0e0caa878..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/yun_serintBg.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/yunregBtn.jpg b/SiteServer.Web/SiteServer/Pic/login/yunregBtn.jpg deleted file mode 100644 index 768001a1f..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/yunregBtn.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/yunsubmit.jpg b/SiteServer.Web/SiteServer/Pic/login/yunsubmit.jpg deleted file mode 100644 index e1448faa8..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/yunsubmit.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Pic/login/yunsubmit2.jpg b/SiteServer.Web/SiteServer/Pic/login/yunsubmit2.jpg deleted file mode 100644 index 72f0ed626..000000000 Binary files a/SiteServer.Web/SiteServer/Pic/login/yunsubmit2.jpg and /dev/null differ diff --git a/SiteServer.Web/SiteServer/Plugins/modalManualInstall.aspx b/SiteServer.Web/SiteServer/Plugins/modalManualInstall.aspx deleted file mode 100644 index 5221ebd76..000000000 --- a/SiteServer.Web/SiteServer/Plugins/modalManualInstall.aspx +++ /dev/null @@ -1,67 +0,0 @@ -<%@ Page Language="C#" Trace="false" Inherits="SiteServer.BackgroundPages.Plugins.ModalManualInstall" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    - - -
    - - -
    - - - 插件包是后缀为.nupkg的文件 -
    -
    - - -
    - - - 插件标识符在插件库中必须是唯一的 -
    -
    - - - 插件版本号用以确定需要安装的插件版本 -
    -
    - -
    - -
    - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Plugins/pageAdd.aspx b/SiteServer.Web/SiteServer/Plugins/pageAdd.aspx deleted file mode 100644 index 177e87e0a..000000000 --- a/SiteServer.Web/SiteServer/Plugins/pageAdd.aspx +++ /dev/null @@ -1,175 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Plugins.PageAdd" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - -
    - -

    载入中,请稍后...

    -
    - -
    -
    - -
    -
    -
    -
    - - -
    - - -
    -
    -
    - -
    -
    - -
    - -
    -
    -
    -

    搜索结果

    -
    - -

    - 0 个插件,建议更换搜索词 -

    - - -
    - - - -
    -
    - -
    - - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Plugins/pageConfig.aspx b/SiteServer.Web/SiteServer/Plugins/pageConfig.aspx deleted file mode 100644 index ded953315..000000000 --- a/SiteServer.Web/SiteServer/Plugins/pageConfig.aspx +++ /dev/null @@ -1,113 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Plugins.PageConfig" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    -
    - 插件设置 -
    -

    - -
    - -
    - -
    -
    - -
    - - -
    - - -
    - - -
    - - -
    - - - IP地址或者服务器名 -
    - -
    - - -
    - - -
    - - - 连接数据库的用户名 -
    - -
    - - - 连接数据库的密码 -
    -
    - -
    - - 点击按钮获取可用的数据库 -
    - -
    -
    - - -
    - -
    - - -
    -
    - -
    - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Plugins/pageInstall.aspx b/SiteServer.Web/SiteServer/Plugins/pageInstall.aspx deleted file mode 100644 index 5db3ca172..000000000 --- a/SiteServer.Web/SiteServer/Plugins/pageInstall.aspx +++ /dev/null @@ -1,362 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Plugins.PageInstall" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - -
    -

    - 插件{{ type }}向导 -

    -

    - 欢迎来到插件{{ type }}向导! -

    - - - - - - - - -
    - -
    -
    -

    下载{{ type }}包

    -

    系统正在下载插件{{ type }}包,可能需要几分钟,请稍后...

    -
    -
    - -
    - -
    -
    -

    正在检查{{ type }}包版本,请稍后...

    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - -
    状态Id名称版本简介发布时间
    -
    - 下载完成 -
    -
    - 下载中... -
    -
    - 等待下载 -
    -
    - {{ package.id }} - - {{ package.title }} - - {{ package.version }} - - {{ package.description }} - - {{ package.published }} -
    - -
    -
    -
    - -
    - - -
    - -
    -
    -

    {{ type }}插件

    -

    系统正在{{ type }}插件,请稍后...

    -
    -
    - -
    - - - - - - - - - - - - - - - - - - - - - - - -
    状态Id名称版本简介发布时间
    -
    - {{ type }}完成 -
    -
    - {{ type }}中... -
    -
    - 等待{{ type }} -
    -
    - {{ package.id }} - - {{ package.title }} - - {{ package.version }} - - {{ package.description }} - - {{ package.published }} -
    - -
    -
    -
    - -
    - - -
    - - - -
    - -
    - -
    - - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Plugins/pageManagement.aspx b/SiteServer.Web/SiteServer/Plugins/pageManagement.aspx deleted file mode 100644 index 4bac86add..000000000 --- a/SiteServer.Web/SiteServer/Plugins/pageManagement.aspx +++ /dev/null @@ -1,397 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Plugins.PageManagement" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    LOGO插件Id插件名称版本号作者插件介绍载入时间
    - - - {{ package.id }} - - {{ package.metadata.title }} - - {{ package.metadata.version }} - - {{ package.metadata.owners }} - - {{ package.metadata.description }} - - {{ package.initTime }}毫秒 - - {{ package.isDisabled ? '启用' : '禁用' }} -    - 删除插件 -
    - -
    -
    -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    LOGO插件Id插件名称版本号作者插件介绍载入时间
    - - - {{ package.id }} - - {{ package.metadata.title }} - - {{ package.metadata.version }} - - {{ package.metadata.owners }} - - {{ package.metadata.description }} - - {{ package.initTime }}毫秒 - - {{ package.isDisabled ? '启用' : '禁用' }} -    - 删除插件 -
    - -
    -
    -
    - -
    -
    -
    - - - - - - - - - - - - - - - -
    插件Id错误详情
    - {{ package.id }} - - {{ package.errorMessage }} - - 删除插件 -
    - -
    -
    -
    - -
    - -
    - 发现以下插件发布了新版本,请点击升级插件按钮开始升级 -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    LOGO插件Id插件名称已安装版本新版本更新说明发布时间
    - - - {{ package.id }} - - {{ package.updatePackage.title }} - - {{ package.metadata ? package.metadata.version : '' }} - - {{ package.updatePackage.version }} - - {{ package.updatePackage.releaseNotes }} - - {{ package.updatePackage.published }} - - 升级插件 -
    -
    -
    -
    - -
    - -
    - - - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Plugins/pageView.aspx b/SiteServer.Web/SiteServer/Plugins/pageView.aspx deleted file mode 100644 index 8f5d61309..000000000 --- a/SiteServer.Web/SiteServer/Plugins/pageView.aspx +++ /dev/null @@ -1,193 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Plugins.PageView" %> - - - - - - - - - - - -
    - -
    - -

    载入中,请稍后...

    -
    - -
    - -
    -
    - -
    -

    - {{ package.id }}.{{ package.version }} -

    -

    {{ package.title }}

    -
    -

    - {{ package.description }} -

    - -
    - 系统检测到插件新版本,当前版本:{{ installedVersion }},新版本:{{ package.version }} - -
    - -
    - - - - 插件主页 - -
    -
    -
    -
    - - - -
    -
    -

    插件详情

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    版本发行说明{{ package.releaseNotes }}
    更新日期{{ package.published }}
    插件Id{{ package.id }}
    版本号{{ package.version }}
    作者{{ package.authors ? package.authors.join(',') : '' }}
    标签{{ package.tags }}
    插件项目链接 - - {{ package.projectUrl }} - -
    插件许可链接 - - {{ package.licenseUrl }} - -
    版权{{ package.copyright }}
    -
    - -
    -
    -

    - 依赖项 -

    -
    - -

    - 此插件依赖的类库以及其他插件 -

    - - - - - - - - - - - - - - - - - - - - -
    依赖项版本类型
    {{ reference.id }}{{ reference.version }}插件
    {{ reference.id }}{{ reference.version }}类库
    -
    - -
    -
    - - - - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/modalAdminPassword.aspx b/SiteServer.Web/SiteServer/Settings/modalAdminPassword.aspx deleted file mode 100644 index 6119e6adc..000000000 --- a/SiteServer.Web/SiteServer/Settings/modalAdminPassword.aspx +++ /dev/null @@ -1,59 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.ModalAdminPassword" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    - -
    - -
    -
    -
    - -
    - -
    - -
    -
    - 输入需要设置的新密码 - -
    -
    - -
    - -
    - -
    -
    - - -
    -
    - -
    - -
    - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/modalAdminView.aspx b/SiteServer.Web/SiteServer/Settings/modalAdminView.aspx deleted file mode 100644 index 9a62a4677..000000000 --- a/SiteServer.Web/SiteServer/Settings/modalAdminView.aspx +++ /dev/null @@ -1,81 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.ModalAdminView" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    - -
    - -
    -
    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/modalAuxiliaryTableAdd.aspx b/SiteServer.Web/SiteServer/Settings/modalAuxiliaryTableAdd.aspx deleted file mode 100644 index b15e03a4c..000000000 --- a/SiteServer.Web/SiteServer/Settings/modalAuxiliaryTableAdd.aspx +++ /dev/null @@ -1,63 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.ModalAuxiliaryTableAdd" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    - -
    - -
    -
    - - -
    -
    - -
    - -
    - -
    -
    - - -
    -
    - -
    - -
    - -
    -
    - -
    -
    - -
    - -
    - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/modalTableMetadataAdd.aspx b/SiteServer.Web/SiteServer/Settings/modalTableMetadataAdd.aspx deleted file mode 100644 index 8f9cb9fa5..000000000 --- a/SiteServer.Web/SiteServer/Settings/modalTableMetadataAdd.aspx +++ /dev/null @@ -1,65 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.ModalTableMetadataAdd" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    - -
    - -
    -
    - - - 只允许包含字母、数字以及下划线 -
    -
    -
    - -
    - -
    -
    - -
    -
    - - -
    - -
    - -
    -
    - - -
    -
    -
    - -
    - -
    - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/modalUserView.aspx b/SiteServer.Web/SiteServer/Settings/modalUserView.aspx deleted file mode 100644 index 800b924ec..000000000 --- a/SiteServer.Web/SiteServer/Settings/modalUserView.aspx +++ /dev/null @@ -1,169 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.ModalUserView" Trace="false"%> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    -
    - -
    - -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAdminArea.aspx b/SiteServer.Web/SiteServer/Settings/pageAdminArea.aspx deleted file mode 100644 index 88508b8ae..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAdminArea.aspx +++ /dev/null @@ -1,81 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAdminArea" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - -
    区域名称管理员人数上升下降  - -
    - -
    -
    -
    - - - -
    - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAdminConfiguration.aspx b/SiteServer.Web/SiteServer/Settings/pageAdminConfiguration.aspx deleted file mode 100644 index 24bb1c091..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAdminConfiguration.aspx +++ /dev/null @@ -1,120 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAdminConfiguration" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - - - 0代表不限制 -
    - -
    - - - 0代表不限制 -
    - -
    - - -
    - -
    - - - -
    - - -
    - - - 一旦登录失败达到指定次数之后管理员就会被锁定 -
    - -
    - - -
    - - - -
    - - -
    -
    -
    - -
    - - - -
    - - -
    - - - 需进入短信供应商模板管理界面,添加验证码类短信模板并获取模板Id -
    -
    - -
    - - - 注意:超级管理员、站点管理员、具有审核权限的管理员,此设置无效。 -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAdminDepartment.aspx b/SiteServer.Web/SiteServer/Settings/pageAdminDepartment.aspx deleted file mode 100644 index 177ffbad1..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAdminDepartment.aspx +++ /dev/null @@ -1,82 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAdminDepartment" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - -
    部门名称部门编号管理员人数上升下降  - -
    - -
    -
    -
    - - - -
    - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAdminPermissionAdd.aspx b/SiteServer.Web/SiteServer/Settings/pageAdminPermissionAdd.aspx deleted file mode 100644 index 6a9df4991..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAdminPermissionAdd.aspx +++ /dev/null @@ -1,111 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAdminPermissionAdd" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - -
    - - - - - -
    - -
    - -
    - -
    -
    -
    - - - -
    - -
    - - -
    - -
    - - - 从下边选择需要管理的栏目,所选栏目下的所有子栏目都属于可管理范围 - - -
    - -
    - -
    - -
    - -
    - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAdminRole.aspx b/SiteServer.Web/SiteServer/Settings/pageAdminRole.aspx deleted file mode 100644 index 37dff8586..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAdminRole.aspx +++ /dev/null @@ -1,85 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAdminRole" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - -
    角色名称备注  
    - - - - - - - -
    - -
    -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAdminRoleAdd.aspx b/SiteServer.Web/SiteServer/Settings/pageAdminRoleAdd.aspx deleted file mode 100644 index 26f3d5a60..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAdminRoleAdd.aspx +++ /dev/null @@ -1,126 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAdminRoleAdd" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - - - 唯一标识此角色的字符串 -
    - -
    - - -
    - -
    - -
    - -
    -
    - - - -
    - - -
    - - -
    -
    - -
    - -
    - -
    - - - - -
    - - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAdministrator.aspx b/SiteServer.Web/SiteServer/Settings/pageAdministrator.aspx deleted file mode 100644 index c51808579..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAdministrator.aspx +++ /dev/null @@ -1,190 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAdministrator" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - -
    - -
    - - - - - - - - - -
    - -
    - - - - - - - -
    - -
    - - - - - - - - - - - - -
    -
    - -
    -
    - - -
    - -
    - - -
    - -
    - - -
    - - -
    -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    账号姓名手机部门区域最后登录登录次数角色    - -
    - - - - - - - - - - - - - - - - - - - - - - - -
    - -
    -
    -
    - - - -
    - - - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAdministratorAdd.aspx b/SiteServer.Web/SiteServer/Settings/pageAdministratorAdd.aspx deleted file mode 100644 index e92afd71a..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAdministratorAdd.aspx +++ /dev/null @@ -1,119 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAdministratorAdd" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - -
    -

    - -
    - - - 帐号用于登录系统,由字母、数字组成 -
    - -
    - - -
    - - -
    - - -
    -
    - - -
    -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAnalysisAdminLogin.aspx b/SiteServer.Web/SiteServer/Settings/pageAnalysisAdminLogin.aspx deleted file mode 100644 index 09a096da9..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAnalysisAdminLogin.aspx +++ /dev/null @@ -1,168 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAnalysisAdminLogin" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - -
    - - - - - -
    -
    -
    - - -
    - -
    - - -
    - -
    - - -
    - - -
    - -
    - -

    - -

    - -
    - - -
    - -

    - -

    - -
    - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAnalysisAdminWork.aspx b/SiteServer.Web/SiteServer/Settings/pageAnalysisAdminWork.aspx deleted file mode 100644 index c22e1044a..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAnalysisAdminWork.aspx +++ /dev/null @@ -1,188 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAnalysisAdminWork" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - -
    - - - - - -
    -
    -
    - - -
    - -
    - - -
    - -
    - - -
    - - -
    - - - -
    - -
    -
    - -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - -
    登录名 显示名 新增内容 更新内容
    - - - - - - - -
    -
    -
    -
    - - - -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAnalysisSite.aspx b/SiteServer.Web/SiteServer/Settings/pageAnalysisSite.aspx deleted file mode 100644 index 6c1255ddf..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAnalysisSite.aspx +++ /dev/null @@ -1,186 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAnalysisSite" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - -
    - - - - - -
    -
    -
    - - -
    - -
    - - -
    - -
    - - -
    - - -
    - -
    - -
    -
    -
    - -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    站点名称新增内容修改内容合计
    - - - - - - - -
    总计 - - - - - -
    -
    -
    -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteChannels.aspx b/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteChannels.aspx deleted file mode 100644 index 98d1514a8..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteChannels.aspx +++ /dev/null @@ -1,169 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAnalysisSiteChannels" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - -
    - - - - - -
    -
    -
    - - -
    - -
    - - -
    - -
    - - -
    - - -
    - -
    - -
    -
    - -
    - -
    -
    -
    - - - - - - - - - - - - - -
    栏目名新增内容修改内容
    -
    -
    -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteDownloads.aspx b/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteDownloads.aspx deleted file mode 100644 index 9599f794f..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteDownloads.aspx +++ /dev/null @@ -1,148 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAnalysisSiteDownloads" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - -
    - - - - - -
    -
    -
    - - -
    -
    - -
    - -
    -
    - -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - -
    站点名称文件下载量
    - - - -
    总计 - -
    -
    -
    -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteDownloadsChannels.aspx b/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteDownloadsChannels.aspx deleted file mode 100644 index e11660f0d..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteDownloadsChannels.aspx +++ /dev/null @@ -1,144 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAnalysisSiteDownloadsChannels" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - -
    - - - - - -
    -
    -
    - - -
    -
    - -
    - -
    -
    - -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - -
    内容标题(点击查看)所属栏目附件地址
    - - - - - -
    -
    -
    -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteHits.aspx b/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteHits.aspx deleted file mode 100644 index 4ced82154..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteHits.aspx +++ /dev/null @@ -1,147 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAnalysisSiteHits" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - -
    - - - - - -
    -
    -
    - - -
    -
    - -
    - -
    -
    - -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - -
    站点名称点击量
    - - - -
    总计 - -
    -
    -
    -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteHitsChannels.aspx b/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteHitsChannels.aspx deleted file mode 100644 index fdce91775..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteHitsChannels.aspx +++ /dev/null @@ -1,188 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAnalysisSiteHitsChannels" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - -
    - - - - - -
    -
    -
    - - -
    -
    - -
    - -
    -
    - -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    内容标题(点击查看)所属栏目点击量日点击量周点击量月点击量最后点击时间
    - - - - - - - - - - - - - -
    -
    -
    -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageAnalysisUser.aspx b/SiteServer.Web/SiteServer/Settings/pageAnalysisUser.aspx deleted file mode 100644 index 1ab14f26c..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageAnalysisUser.aspx +++ /dev/null @@ -1,117 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAnalysisUser" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - -
    - - - - - -
    -
    -
    - - -
    - -
    - - -
    - -
    - - -
    - - -
    - -
    - -

    - -

    - -
    - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageCreateStatus.aspx b/SiteServer.Web/SiteServer/Settings/pageCreateStatus.aspx deleted file mode 100644 index dd98eaa5e..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageCreateStatus.aspx +++ /dev/null @@ -1,148 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageCreateStatus" %> - - - - - - - - - - - - - - -
    - - -
    -
    - -
    - -
    -
    -
    -
    -

    剩余页面:

    -
    -
    - 0 - - 栏目页 - -
    -
    - 0 - - 内容页 - -
    -
    - 0 - - 文件页 - -
    -
    -
    -
    - -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    -
    - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageLogAdmin.aspx b/SiteServer.Web/SiteServer/Settings/pageLogAdmin.aspx deleted file mode 100644 index e7e660a78..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageLogAdmin.aspx +++ /dev/null @@ -1,125 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageLogAdmin" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - - -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    管理员IP地址日期动作描述 - -
    - - - - - - - - - - - -
    - -
    -
    -
    - - - -
    - - - - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageLogConfiguration.aspx b/SiteServer.Web/SiteServer/Settings/pageLogConfiguration.aspx deleted file mode 100644 index 27816ce89..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageLogConfiguration.aspx +++ /dev/null @@ -1,65 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageLogConfiguration" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - - - 启用后系统将定时自动删除日志,以节省数据库存储空间 -
    - - -
    - - - 设置为60天,则默认只保留60天的日志,60天之前的日志将被系统自动删除 -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageLogError.aspx b/SiteServer.Web/SiteServer/Settings/pageLogError.aspx deleted file mode 100644 index caa2d8d75..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageLogError.aspx +++ /dev/null @@ -1,121 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageLogError" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - - -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - -
    Id错误摘要错误消息日期 - -
    - - - - - - - - - -
    - -
    -
    -
    - - - -
    - - - - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageLogSite.aspx b/SiteServer.Web/SiteServer/Settings/pageLogSite.aspx deleted file mode 100644 index ce2a880a3..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageLogSite.aspx +++ /dev/null @@ -1,137 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageLogSite" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    -
    - -
    -
    - - -
    - -
    - - -
    - - -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    管理员IP地址日期动作描述 - -
    - - - - - - - - - - - -
    - -
    -
    -
    - - - -
    - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageLogUser.aspx b/SiteServer.Web/SiteServer/Settings/pageLogUser.aspx deleted file mode 100644 index 0c9f30973..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageLogUser.aspx +++ /dev/null @@ -1,125 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageLogUser" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    - - -
    - -
    - - -
    - -
    - - -
    - -
    - - -
    - - -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    用户IP地址日期动作描述 - -
    - - - - - - - - - - - -
    - -
    -
    -
    - - - -
    - - - - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageRecord.aspx b/SiteServer.Web/SiteServer/Settings/pageRecord.aspx deleted file mode 100644 index 011ab00b8..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageRecord.aspx +++ /dev/null @@ -1,99 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageRecord" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    -
    - 系统调试日志 -
    -

    - 此页面仅供开发人员调试系统使用 -

    - -
    -
    - - -
    - -
    - - -
    - -
    - - -
    - - -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - -
    内容描述来源日期 - -
    - - - - - - - - - -
    - -
    -
    -
    - - - -
    - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSite.aspx b/SiteServer.Web/SiteServer/Settings/pageSite.aspx deleted file mode 100644 index 9cd5d83a9..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSite.aspx +++ /dev/null @@ -1,114 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSite" EnableViewState="false" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    站点名称文件夹创建日期保存为站点模板修改属性站点路径转移整站替换整站删除上升下降
    - - - - - - - - - - - - - - - - - - - -
    - -
    -
    -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSiteAdd.aspx b/SiteServer.Web/SiteServer/Settings/pageSiteAdd.aspx deleted file mode 100644 index 267407ff2..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSiteAdd.aspx +++ /dev/null @@ -1,277 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteAdd" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    -
    - 创建新站点 - - -
    - - -

    - 欢迎使用创建新站点向导,请选择创建站点的方式 -

    - -
    - - -
    -
    - - -

    - 请选择站点模板 -

    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - -
    站点模板名称站点模板文件夹站点模板介绍样图
    - - - - - - - - - -
    - -
    -
    -
    -
    - - -

    - 请选择在线模板,本页面只显示部分免费模板,更多站点模板请访问官网: - http://templates.siteserver.cn -

    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    名称简介模板作者更新时间
    - - - - - - - - - - - -
    -
    -
    -
    -
    - - - -

    - 在此设置新建站点的名称、文件夹以及辅助表等信息 -

    - -
    - -
    - -
    -
    - -
    - - -
    - -
    - - - - - -
    - - -
    - - -
    -
    - - - 实际在服务器中保存此网站的文件夹名称,此路径必须以英文或拼音命名 -
    -
    - -
    - - -
    - - -
    - - -
    -
    - - -
    - - -
    -
    - - -
    - - - - - -
    -
    - - -
    - - -
    -
    - -
    - - -
    - - -
    - - - - - - - - 指此内容在添加后需要经多少次审核才能正式发布 -
    -
    - -
    - -
    - -
    - - - -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSiteAuxiliaryTable.aspx b/SiteServer.Web/SiteServer/Settings/pageSiteAuxiliaryTable.aspx deleted file mode 100644 index af92d5502..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSiteAuxiliaryTable.aspx +++ /dev/null @@ -1,114 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteAuxiliaryTable" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    辅助表标识辅助表名称是否被使用是否存在创建后修改
    - - - - - - - - - - - - - - - - - -
    - -
    -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSiteDelete.aspx b/SiteServer.Web/SiteServer/Settings/pageSiteDelete.aspx deleted file mode 100644 index 893ccc01b..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSiteDelete.aspx +++ /dev/null @@ -1,74 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteDelete" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - 删除站点 -
    -

    - 站点名称: - -

    - -
    - - - - - - 选择保留文件删除操作将仅在数据库中删除此站点 -
    - -
    - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSiteEdit.aspx b/SiteServer.Web/SiteServer/Settings/pageSiteEdit.aspx deleted file mode 100644 index b73cf0e1a..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSiteEdit.aspx +++ /dev/null @@ -1,129 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteEdit" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - 修改站点 -
    - -
    - - -
    - - - -
    - - - 实际在服务器中保存此网站的文件夹名称,此路径必须以英文或拼音命名。 -
    -
    - - -
    - - -
    -
    - -
    - - -
    - -
    - - - 设置站点排序,排序数字大的站点将排在其他站点之前 -
    - -
    - - -
    - - -
    - - - - - - - -
    -
    - -
    - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSiteKeyword.aspx b/SiteServer.Web/SiteServer/Settings/pageSiteKeyword.aspx deleted file mode 100644 index 8cd340373..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSiteKeyword.aspx +++ /dev/null @@ -1,102 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteKeyword" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - -
    敏感词替换为等级
    - - - - - - - - - -
    - -
    -
    -
    - - - -
    - - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSiteReplace.aspx b/SiteServer.Web/SiteServer/Settings/pageSiteReplace.aspx deleted file mode 100644 index 33d464260..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSiteReplace.aspx +++ /dev/null @@ -1,158 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteReplace" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - 整站替换 -
    - - - -
    - 整站替换将改变现有网站,请谨慎使用,您选择的站点为 - -
    - - - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - -
    站点模板名称站点模板文件夹站点模板介绍样图
    - - - - - - - - - -
    - -
    -
    -
    - -
    - - - -
    - 整站替换将改变现有网站,请谨慎使用,您选择的站点模板为 - -
    - -
    - - - - - -
    - -
    - - - - - -
    - -
    - - - - - -
    - -
    - - - - - -
    - -
    - -
    - -
    - - - -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSiteSave.aspx b/SiteServer.Web/SiteServer/Settings/pageSiteSave.aspx deleted file mode 100644 index 055052841..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSiteSave.aspx +++ /dev/null @@ -1,215 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteSave" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - 保存站点模板 -
    - - - -

    - 保存站点模板能够将此站点的文件、栏目、内容、模板、插件等保存在站点模板文件夹中 -

    - -
    - - -
    - -
    - - - 文件名必须以T_开头,且以英文或拼音取名 -
    - -
    - - -
    - -
    - - -
    - -
    - - - -

    - 保存站点文件,点击下一步将站点的文件保存到站点模板中 -

    - -
    - - -
    - - -
    - - -
    -
    - -
    - - - -

    - 保存站点内容,点击下一步将站点的栏目及内容信息保存到站点模板中 -

    - -
    - - -
    - -
    - - -
    - - -
    - - 从下边选择需要保存的栏目,所选栏目的下级栏目将自动保存到站点模板中 -
    - -
    -
    - -
    - - - -

    - 保存站点数据,点击下一步将站点数据(包括模板、辅助表、配置信息、插件等)保存到站点模板中 -

    - -
    - - - -

    - 载入样图文件,选择样图文件的名称 -

    - -
    - - -
    - -
    - - -

    - 站点模板保存成功,您已经完成保存站点模板的操作 -

    - -
    -

    保存成功,站点模版保存在"SiteFiles\SiteTemplates\ - <%=TbSiteTemplateDir.Text%>"文件夹中

    -
    - -
    - -
    - -
    - - - - - - -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSiteTableMetadata.aspx b/SiteServer.Web/SiteServer/Settings/pageSiteTableMetadata.aspx deleted file mode 100644 index 7e9b395e3..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSiteTableMetadata.aspx +++ /dev/null @@ -1,141 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteTableMetadata" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - 真实字段管理 -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    字段名数据类型上升下降
    - - - - - - - - - - - - - - - -
    - -
    -
    -
    - -
    - - - - - - - - -
    - - -
    -
    - 同步辅助表 -
    -

    - 此辅助表在创建后被修改,与数据库中的实际表结构有差别,请同步辅助表。 -

    - -
    - - -
    -
    - - -
    -
    - 创建辅助表SQL命令 -
    -

    - -

    -
    -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSiteTableStyle.aspx b/SiteServer.Web/SiteServer/Settings/pageSiteTableStyle.aspx deleted file mode 100644 index f58fe0dc4..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSiteTableStyle.aspx +++ /dev/null @@ -1,122 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteTableStyle" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - 虚拟字段管理 -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    字段名显示名称表单提交类型字段类型验证规则排序显示样式表单验证
    - - - - - - - - - - - - - - - - - - - -
    - -
    -
    -
    - -
    - - - - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSiteTemplate.aspx b/SiteServer.Web/SiteServer/Settings/pageSiteTemplate.aspx deleted file mode 100644 index 76d590d1d..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSiteTemplate.aspx +++ /dev/null @@ -1,144 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteTemplate" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    站点模板名称站点模板文件夹站点模板介绍创建日期
    - - - - - - - - - - - - - -
    -
    -
    -
    - -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - -
    未解压站点模板创建日期
    - - - - - - - -
    -
    -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSiteTemplateOnline.aspx b/SiteServer.Web/SiteServer/Settings/pageSiteTemplateOnline.aspx deleted file mode 100644 index fbddc03c7..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSiteTemplateOnline.aspx +++ /dev/null @@ -1,97 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteTemplateOnline" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    名称简介模板作者更新时间
    - - - - - - - - - - - -
    -
    -
    -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSiteUrlApi.aspx b/SiteServer.Web/SiteServer/Settings/pageSiteUrlApi.aspx deleted file mode 100644 index bd2b3296e..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSiteUrlApi.aspx +++ /dev/null @@ -1,75 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteUrlApi" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - - - 设置API服务器部署方式 -
    - - -
    - - -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSiteUrlAssets.aspx b/SiteServer.Web/SiteServer/Settings/pageSiteUrlAssets.aspx deleted file mode 100644 index 77f682490..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSiteUrlAssets.aspx +++ /dev/null @@ -1,94 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteUrlAssets" enableViewState = "false" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - -
    站点名称文件夹资源文件存储文件夹资源文件访问地址
    - - - - - - - - - -
    - -
    -
    -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSiteUrlAssetsConfig.aspx b/SiteServer.Web/SiteServer/Settings/pageSiteUrlAssetsConfig.aspx deleted file mode 100644 index 9edd6567d..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSiteUrlAssetsConfig.aspx +++ /dev/null @@ -1,92 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteUrlAssetsConfig" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - 修改资源文件访问地址 -
    -

    - 站点名称: - -

    - -
    - - - 资源文件包含图片、视频、附件等除了HTML页面之外的所有文件 -
    - - -
    - - -
    - -
    - - -
    -
    - -
    - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSiteUrlWeb.aspx b/SiteServer.Web/SiteServer/Settings/pageSiteUrlWeb.aspx deleted file mode 100644 index 01634641b..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSiteUrlWeb.aspx +++ /dev/null @@ -1,90 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteUrlWeb" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - -
    站点名称文件夹Web访问地址
    - - - - - - - -
    - -
    -
    -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageSiteUrlWebConfig.aspx b/SiteServer.Web/SiteServer/Settings/pageSiteUrlWebConfig.aspx deleted file mode 100644 index 782dc53d1..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageSiteUrlWebConfig.aspx +++ /dev/null @@ -1,84 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteUrlWebConfig" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - 修改Web访问地址 -
    -

    - 站点名称: - -

    - -
    - - - 设置网站页面部署方式 -
    - - -
    - - -
    -
    - -
    - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageUser.aspx b/SiteServer.Web/SiteServer/Settings/pageUser.aspx deleted file mode 100644 index a5cfadf80..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageUser.aspx +++ /dev/null @@ -1,188 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageUser" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - -
    - -
    - - - - - - - - - - - - -
    - -
    - - - - - - - - - - - - -
    - -
    - - - - - - - - - -
    -
    - -
    -
    - - -
    - -
    - - -
    - - -
    -
    - -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    账号显示名邮箱手机注册时间最后活动时间登录次数投稿数量   - -
    - - - - - - - - - - - - - - - - - - - - - -
    - -
    -
    -
    - - - -
    - - - - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageUserAdd.aspx b/SiteServer.Web/SiteServer/Settings/pageUserAdd.aspx deleted file mode 100644 index 9f6538b90..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageUserAdd.aspx +++ /dev/null @@ -1,101 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageUserAdd" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - -
    - -
    - -
    -
    - -
    - -
    - - - 帐号用于登录系统,由字母、数字组成 -
    - -
    - - -
    - - -
    - - - - - -
    - -
    - - -
    -
    - -
    - - -
    - -
    - - -
    - -
    - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageUserCheck.aspx b/SiteServer.Web/SiteServer/Settings/pageUserCheck.aspx deleted file mode 100644 index e5f10e39f..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageUserCheck.aspx +++ /dev/null @@ -1,88 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageUserCheck" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - -
    - -
    - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - - - - - - - -
    账号姓名注册时间  - -
    - - - - - - - - - -
    - -
    -
    -
    - - - -
    - - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageUserConfiguration.aspx b/SiteServer.Web/SiteServer/Settings/pageUserConfiguration.aspx deleted file mode 100644 index 7d59b17bd..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageUserConfiguration.aspx +++ /dev/null @@ -1,117 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageUserConfiguration" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - -
    - -
    - - - -
    -
    - - - - 选择否将禁止新用户注册, 但不影响过去已注册的会员的使用 -
    - -
    - - - 0代表不限制 -
    - -
    - - -
    - -
    - - - 同一IP在本时间间隔内将只能注册一个帐号,0 为不限制 -
    - -
    - - - -
    - - -
    - - - 一旦登录失败达到指定次数之后用户就会被锁定 -
    - -
    - - -
    - - -
    - - -
    -
    -
    - -
    - - - -
    - - -
    - - - 需进入短信供应商模板管理界面,添加验证码类短信模板并获取模板Id -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageUtilityCache.aspx b/SiteServer.Web/SiteServer/Settings/pageUtilityCache.aspx deleted file mode 100644 index 957a6e434..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageUtilityCache.aspx +++ /dev/null @@ -1,85 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageUtilityCache" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -

    - 当前缓存: - 个 - -

    - -
    -
    -
    - - - - - - - - - - - - - - - - - -
    缓存键缓存值
    - - - - - - - -
    - -
    -
    -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageUtilityDbLogDelete.aspx b/SiteServer.Web/SiteServer/Settings/pageUtilityDbLogDelete.aspx deleted file mode 100644 index b8feb7fe5..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageUtilityDbLogDelete.aspx +++ /dev/null @@ -1,52 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageUtilityDbLogDelete" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -

    - 上一次清空日志时间: - -

    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageUtilityEncrypt.aspx b/SiteServer.Web/SiteServer/Settings/pageUtilityEncrypt.aspx deleted file mode 100644 index e1428dfe1..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageUtilityEncrypt.aspx +++ /dev/null @@ -1,62 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageUtilityEncrypt" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    - - -
    - - -
    - - -
    -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageUtilityJsMin.aspx b/SiteServer.Web/SiteServer/Settings/pageUtilityJsMin.aspx deleted file mode 100644 index e4f3c3418..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageUtilityJsMin.aspx +++ /dev/null @@ -1,340 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageUtilityJsMin" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - - - - -
    - - - - - -
    -
    - - -
    - -
    - - -
    - -
    - - - - 原来大小: - - 压缩后大小: - - 压缩率: - - -
    - -
    - - - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Settings/pageUtilityParameter.aspx b/SiteServer.Web/SiteServer/Settings/pageUtilityParameter.aspx deleted file mode 100644 index ad6ecda6a..000000000 --- a/SiteServer.Web/SiteServer/Settings/pageUtilityParameter.aspx +++ /dev/null @@ -1,73 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageUtilityParameter" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - - - - -
    - - - - - -
    -
    -
    -
    - - - - - - - - - - - - - - - - - -
    参数名称
    - - - -
    - -
    -
    -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/assets/css/ionicons.min.css b/SiteServer.Web/SiteServer/assets/css/ionicons.min.css deleted file mode 100644 index baba9e930..000000000 --- a/SiteServer.Web/SiteServer/assets/css/ionicons.min.css +++ /dev/null @@ -1,11 +0,0 @@ -@charset "UTF-8";/*! - Ionicons, v2.0.0 - Created by Ben Sperry for the Ionic Framework, http://ionicons.com/ - https://twitter.com/benjsperry https://twitter.com/ionicframework - MIT License: https://github.com/driftyco/ionicons - - Android-style icons originally built by Google’s - Material Design Icons: https://github.com/google/material-design-icons - used under CC BY http://creativecommons.org/licenses/by/4.0/ - Modified icons to fit ionicon’s grid from original. -*/@font-face{font-family:"Ionicons";src:url("../fonts/ionicons.eot?v=2.0.0");src:url("../fonts/ionicons.eot?v=2.0.0#iefix") format("embedded-opentype"),url("../fonts/ionicons.ttf?v=2.0.0") format("truetype"),url("../fonts/ionicons.woff?v=2.0.0") format("woff"),url("../fonts/ionicons.svg?v=2.0.0#Ionicons") format("svg");font-weight:normal;font-style:normal}.ion,.ionicons,.ion-alert:before,.ion-alert-circled:before,.ion-android-add:before,.ion-android-add-circle:before,.ion-android-alarm-clock:before,.ion-android-alert:before,.ion-android-apps:before,.ion-android-archive:before,.ion-android-arrow-back:before,.ion-android-arrow-down:before,.ion-android-arrow-dropdown:before,.ion-android-arrow-dropdown-circle:before,.ion-android-arrow-dropleft:before,.ion-android-arrow-dropleft-circle:before,.ion-android-arrow-dropright:before,.ion-android-arrow-dropright-circle:before,.ion-android-arrow-dropup:before,.ion-android-arrow-dropup-circle:before,.ion-android-arrow-forward:before,.ion-android-arrow-up:before,.ion-android-attach:before,.ion-android-bar:before,.ion-android-bicycle:before,.ion-android-boat:before,.ion-android-bookmark:before,.ion-android-bulb:before,.ion-android-bus:before,.ion-android-calendar:before,.ion-android-call:before,.ion-android-camera:before,.ion-android-cancel:before,.ion-android-car:before,.ion-android-cart:before,.ion-android-chat:before,.ion-android-checkbox:before,.ion-android-checkbox-blank:before,.ion-android-checkbox-outline:before,.ion-android-checkbox-outline-blank:before,.ion-android-checkmark-circle:before,.ion-android-clipboard:before,.ion-android-close:before,.ion-android-cloud:before,.ion-android-cloud-circle:before,.ion-android-cloud-done:before,.ion-android-cloud-outline:before,.ion-android-color-palette:before,.ion-android-compass:before,.ion-android-contact:before,.ion-android-contacts:before,.ion-android-contract:before,.ion-android-create:before,.ion-android-delete:before,.ion-android-desktop:before,.ion-android-document:before,.ion-android-done:before,.ion-android-done-all:before,.ion-android-download:before,.ion-android-drafts:before,.ion-android-exit:before,.ion-android-expand:before,.ion-android-favorite:before,.ion-android-favorite-outline:before,.ion-android-film:before,.ion-android-folder:before,.ion-android-folder-open:before,.ion-android-funnel:before,.ion-android-globe:before,.ion-android-hand:before,.ion-android-hangout:before,.ion-android-happy:before,.ion-android-home:before,.ion-android-image:before,.ion-android-laptop:before,.ion-android-list:before,.ion-android-locate:before,.ion-android-lock:before,.ion-android-mail:before,.ion-android-map:before,.ion-android-menu:before,.ion-android-microphone:before,.ion-android-microphone-off:before,.ion-android-more-horizontal:before,.ion-android-more-vertical:before,.ion-android-navigate:before,.ion-android-notifications:before,.ion-android-notifications-none:before,.ion-android-notifications-off:before,.ion-android-open:before,.ion-android-options:before,.ion-android-people:before,.ion-android-person:before,.ion-android-person-add:before,.ion-android-phone-landscape:before,.ion-android-phone-portrait:before,.ion-android-pin:before,.ion-android-plane:before,.ion-android-playstore:before,.ion-android-print:before,.ion-android-radio-button-off:before,.ion-android-radio-button-on:before,.ion-android-refresh:before,.ion-android-remove:before,.ion-android-remove-circle:before,.ion-android-restaurant:before,.ion-android-sad:before,.ion-android-search:before,.ion-android-send:before,.ion-android-settings:before,.ion-android-share:before,.ion-android-share-alt:before,.ion-android-star:before,.ion-android-star-half:before,.ion-android-star-outline:before,.ion-android-stopwatch:before,.ion-android-subway:before,.ion-android-sunny:before,.ion-android-sync:before,.ion-android-textsms:before,.ion-android-time:before,.ion-android-train:before,.ion-android-unlock:before,.ion-android-upload:before,.ion-android-volume-down:before,.ion-android-volume-mute:before,.ion-android-volume-off:before,.ion-android-volume-up:before,.ion-android-walk:before,.ion-android-warning:before,.ion-android-watch:before,.ion-android-wifi:before,.ion-aperture:before,.ion-archive:before,.ion-arrow-down-a:before,.ion-arrow-down-b:before,.ion-arrow-down-c:before,.ion-arrow-expand:before,.ion-arrow-graph-down-left:before,.ion-arrow-graph-down-right:before,.ion-arrow-graph-up-left:before,.ion-arrow-graph-up-right:before,.ion-arrow-left-a:before,.ion-arrow-left-b:before,.ion-arrow-left-c:before,.ion-arrow-move:before,.ion-arrow-resize:before,.ion-arrow-return-left:before,.ion-arrow-return-right:before,.ion-arrow-right-a:before,.ion-arrow-right-b:before,.ion-arrow-right-c:before,.ion-arrow-shrink:before,.ion-arrow-swap:before,.ion-arrow-up-a:before,.ion-arrow-up-b:before,.ion-arrow-up-c:before,.ion-asterisk:before,.ion-at:before,.ion-backspace:before,.ion-backspace-outline:before,.ion-bag:before,.ion-battery-charging:before,.ion-battery-empty:before,.ion-battery-full:before,.ion-battery-half:before,.ion-battery-low:before,.ion-beaker:before,.ion-beer:before,.ion-bluetooth:before,.ion-bonfire:before,.ion-bookmark:before,.ion-bowtie:before,.ion-briefcase:before,.ion-bug:before,.ion-calculator:before,.ion-calendar:before,.ion-camera:before,.ion-card:before,.ion-cash:before,.ion-chatbox:before,.ion-chatbox-working:before,.ion-chatboxes:before,.ion-chatbubble:before,.ion-chatbubble-working:before,.ion-chatbubbles:before,.ion-checkmark:before,.ion-checkmark-circled:before,.ion-checkmark-round:before,.ion-chevron-down:before,.ion-chevron-left:before,.ion-chevron-right:before,.ion-chevron-up:before,.ion-clipboard:before,.ion-clock:before,.ion-close:before,.ion-close-circled:before,.ion-close-round:before,.ion-closed-captioning:before,.ion-cloud:before,.ion-code:before,.ion-code-download:before,.ion-code-working:before,.ion-coffee:before,.ion-compass:before,.ion-compose:before,.ion-connection-bars:before,.ion-contrast:before,.ion-crop:before,.ion-cube:before,.ion-disc:before,.ion-document:before,.ion-document-text:before,.ion-drag:before,.ion-earth:before,.ion-easel:before,.ion-edit:before,.ion-egg:before,.ion-eject:before,.ion-email:before,.ion-email-unread:before,.ion-erlenmeyer-flask:before,.ion-erlenmeyer-flask-bubbles:before,.ion-eye:before,.ion-eye-disabled:before,.ion-female:before,.ion-filing:before,.ion-film-marker:before,.ion-fireball:before,.ion-flag:before,.ion-flame:before,.ion-flash:before,.ion-flash-off:before,.ion-folder:before,.ion-fork:before,.ion-fork-repo:before,.ion-forward:before,.ion-funnel:before,.ion-gear-a:before,.ion-gear-b:before,.ion-grid:before,.ion-hammer:before,.ion-happy:before,.ion-happy-outline:before,.ion-headphone:before,.ion-heart:before,.ion-heart-broken:before,.ion-help:before,.ion-help-buoy:before,.ion-help-circled:before,.ion-home:before,.ion-icecream:before,.ion-image:before,.ion-images:before,.ion-information:before,.ion-information-circled:before,.ion-ionic:before,.ion-ios-alarm:before,.ion-ios-alarm-outline:before,.ion-ios-albums:before,.ion-ios-albums-outline:before,.ion-ios-americanfootball:before,.ion-ios-americanfootball-outline:before,.ion-ios-analytics:before,.ion-ios-analytics-outline:before,.ion-ios-arrow-back:before,.ion-ios-arrow-down:before,.ion-ios-arrow-forward:before,.ion-ios-arrow-left:before,.ion-ios-arrow-right:before,.ion-ios-arrow-thin-down:before,.ion-ios-arrow-thin-left:before,.ion-ios-arrow-thin-right:before,.ion-ios-arrow-thin-up:before,.ion-ios-arrow-up:before,.ion-ios-at:before,.ion-ios-at-outline:before,.ion-ios-barcode:before,.ion-ios-barcode-outline:before,.ion-ios-baseball:before,.ion-ios-baseball-outline:before,.ion-ios-basketball:before,.ion-ios-basketball-outline:before,.ion-ios-bell:before,.ion-ios-bell-outline:before,.ion-ios-body:before,.ion-ios-body-outline:before,.ion-ios-bolt:before,.ion-ios-bolt-outline:before,.ion-ios-book:before,.ion-ios-book-outline:before,.ion-ios-bookmarks:before,.ion-ios-bookmarks-outline:before,.ion-ios-box:before,.ion-ios-box-outline:before,.ion-ios-briefcase:before,.ion-ios-briefcase-outline:before,.ion-ios-browsers:before,.ion-ios-browsers-outline:before,.ion-ios-calculator:before,.ion-ios-calculator-outline:before,.ion-ios-calendar:before,.ion-ios-calendar-outline:before,.ion-ios-camera:before,.ion-ios-camera-outline:before,.ion-ios-cart:before,.ion-ios-cart-outline:before,.ion-ios-chatboxes:before,.ion-ios-chatboxes-outline:before,.ion-ios-chatbubble:before,.ion-ios-chatbubble-outline:before,.ion-ios-checkmark:before,.ion-ios-checkmark-empty:before,.ion-ios-checkmark-outline:before,.ion-ios-circle-filled:before,.ion-ios-circle-outline:before,.ion-ios-clock:before,.ion-ios-clock-outline:before,.ion-ios-close:before,.ion-ios-close-empty:before,.ion-ios-close-outline:before,.ion-ios-cloud:before,.ion-ios-cloud-download:before,.ion-ios-cloud-download-outline:before,.ion-ios-cloud-outline:before,.ion-ios-cloud-upload:before,.ion-ios-cloud-upload-outline:before,.ion-ios-cloudy:before,.ion-ios-cloudy-night:before,.ion-ios-cloudy-night-outline:before,.ion-ios-cloudy-outline:before,.ion-ios-cog:before,.ion-ios-cog-outline:before,.ion-ios-color-filter:before,.ion-ios-color-filter-outline:before,.ion-ios-color-wand:before,.ion-ios-color-wand-outline:before,.ion-ios-compose:before,.ion-ios-compose-outline:before,.ion-ios-contact:before,.ion-ios-contact-outline:before,.ion-ios-copy:before,.ion-ios-copy-outline:before,.ion-ios-crop:before,.ion-ios-crop-strong:before,.ion-ios-download:before,.ion-ios-download-outline:before,.ion-ios-drag:before,.ion-ios-email:before,.ion-ios-email-outline:before,.ion-ios-eye:before,.ion-ios-eye-outline:before,.ion-ios-fastforward:before,.ion-ios-fastforward-outline:before,.ion-ios-filing:before,.ion-ios-filing-outline:before,.ion-ios-film:before,.ion-ios-film-outline:before,.ion-ios-flag:before,.ion-ios-flag-outline:before,.ion-ios-flame:before,.ion-ios-flame-outline:before,.ion-ios-flask:before,.ion-ios-flask-outline:before,.ion-ios-flower:before,.ion-ios-flower-outline:before,.ion-ios-folder:before,.ion-ios-folder-outline:before,.ion-ios-football:before,.ion-ios-football-outline:before,.ion-ios-game-controller-a:before,.ion-ios-game-controller-a-outline:before,.ion-ios-game-controller-b:before,.ion-ios-game-controller-b-outline:before,.ion-ios-gear:before,.ion-ios-gear-outline:before,.ion-ios-glasses:before,.ion-ios-glasses-outline:before,.ion-ios-grid-view:before,.ion-ios-grid-view-outline:before,.ion-ios-heart:before,.ion-ios-heart-outline:before,.ion-ios-help:before,.ion-ios-help-empty:before,.ion-ios-help-outline:before,.ion-ios-home:before,.ion-ios-home-outline:before,.ion-ios-infinite:before,.ion-ios-infinite-outline:before,.ion-ios-information:before,.ion-ios-information-empty:before,.ion-ios-information-outline:before,.ion-ios-ionic-outline:before,.ion-ios-keypad:before,.ion-ios-keypad-outline:before,.ion-ios-lightbulb:before,.ion-ios-lightbulb-outline:before,.ion-ios-list:before,.ion-ios-list-outline:before,.ion-ios-location:before,.ion-ios-location-outline:before,.ion-ios-locked:before,.ion-ios-locked-outline:before,.ion-ios-loop:before,.ion-ios-loop-strong:before,.ion-ios-medical:before,.ion-ios-medical-outline:before,.ion-ios-medkit:before,.ion-ios-medkit-outline:before,.ion-ios-mic:before,.ion-ios-mic-off:before,.ion-ios-mic-outline:before,.ion-ios-minus:before,.ion-ios-minus-empty:before,.ion-ios-minus-outline:before,.ion-ios-monitor:before,.ion-ios-monitor-outline:before,.ion-ios-moon:before,.ion-ios-moon-outline:before,.ion-ios-more:before,.ion-ios-more-outline:before,.ion-ios-musical-note:before,.ion-ios-musical-notes:before,.ion-ios-navigate:before,.ion-ios-navigate-outline:before,.ion-ios-nutrition:before,.ion-ios-nutrition-outline:before,.ion-ios-paper:before,.ion-ios-paper-outline:before,.ion-ios-paperplane:before,.ion-ios-paperplane-outline:before,.ion-ios-partlysunny:before,.ion-ios-partlysunny-outline:before,.ion-ios-pause:before,.ion-ios-pause-outline:before,.ion-ios-paw:before,.ion-ios-paw-outline:before,.ion-ios-people:before,.ion-ios-people-outline:before,.ion-ios-person:before,.ion-ios-person-outline:before,.ion-ios-personadd:before,.ion-ios-personadd-outline:before,.ion-ios-photos:before,.ion-ios-photos-outline:before,.ion-ios-pie:before,.ion-ios-pie-outline:before,.ion-ios-pint:before,.ion-ios-pint-outline:before,.ion-ios-play:before,.ion-ios-play-outline:before,.ion-ios-plus:before,.ion-ios-plus-empty:before,.ion-ios-plus-outline:before,.ion-ios-pricetag:before,.ion-ios-pricetag-outline:before,.ion-ios-pricetags:before,.ion-ios-pricetags-outline:before,.ion-ios-printer:before,.ion-ios-printer-outline:before,.ion-ios-pulse:before,.ion-ios-pulse-strong:before,.ion-ios-rainy:before,.ion-ios-rainy-outline:before,.ion-ios-recording:before,.ion-ios-recording-outline:before,.ion-ios-redo:before,.ion-ios-redo-outline:before,.ion-ios-refresh:before,.ion-ios-refresh-empty:before,.ion-ios-refresh-outline:before,.ion-ios-reload:before,.ion-ios-reverse-camera:before,.ion-ios-reverse-camera-outline:before,.ion-ios-rewind:before,.ion-ios-rewind-outline:before,.ion-ios-rose:before,.ion-ios-rose-outline:before,.ion-ios-search:before,.ion-ios-search-strong:before,.ion-ios-settings:before,.ion-ios-settings-strong:before,.ion-ios-shuffle:before,.ion-ios-shuffle-strong:before,.ion-ios-skipbackward:before,.ion-ios-skipbackward-outline:before,.ion-ios-skipforward:before,.ion-ios-skipforward-outline:before,.ion-ios-snowy:before,.ion-ios-speedometer:before,.ion-ios-speedometer-outline:before,.ion-ios-star:before,.ion-ios-star-half:before,.ion-ios-star-outline:before,.ion-ios-stopwatch:before,.ion-ios-stopwatch-outline:before,.ion-ios-sunny:before,.ion-ios-sunny-outline:before,.ion-ios-telephone:before,.ion-ios-telephone-outline:before,.ion-ios-tennisball:before,.ion-ios-tennisball-outline:before,.ion-ios-thunderstorm:before,.ion-ios-thunderstorm-outline:before,.ion-ios-time:before,.ion-ios-time-outline:before,.ion-ios-timer:before,.ion-ios-timer-outline:before,.ion-ios-toggle:before,.ion-ios-toggle-outline:before,.ion-ios-trash:before,.ion-ios-trash-outline:before,.ion-ios-undo:before,.ion-ios-undo-outline:before,.ion-ios-unlocked:before,.ion-ios-unlocked-outline:before,.ion-ios-upload:before,.ion-ios-upload-outline:before,.ion-ios-videocam:before,.ion-ios-videocam-outline:before,.ion-ios-volume-high:before,.ion-ios-volume-low:before,.ion-ios-wineglass:before,.ion-ios-wineglass-outline:before,.ion-ios-world:before,.ion-ios-world-outline:before,.ion-ipad:before,.ion-iphone:before,.ion-ipod:before,.ion-jet:before,.ion-key:before,.ion-knife:before,.ion-laptop:before,.ion-leaf:before,.ion-levels:before,.ion-lightbulb:before,.ion-link:before,.ion-load-a:before,.ion-load-b:before,.ion-load-c:before,.ion-load-d:before,.ion-location:before,.ion-lock-combination:before,.ion-locked:before,.ion-log-in:before,.ion-log-out:before,.ion-loop:before,.ion-magnet:before,.ion-male:before,.ion-man:before,.ion-map:before,.ion-medkit:before,.ion-merge:before,.ion-mic-a:before,.ion-mic-b:before,.ion-mic-c:before,.ion-minus:before,.ion-minus-circled:before,.ion-minus-round:before,.ion-model-s:before,.ion-monitor:before,.ion-more:before,.ion-mouse:before,.ion-music-note:before,.ion-navicon:before,.ion-navicon-round:before,.ion-navigate:before,.ion-network:before,.ion-no-smoking:before,.ion-nuclear:before,.ion-outlet:before,.ion-paintbrush:before,.ion-paintbucket:before,.ion-paper-airplane:before,.ion-paperclip:before,.ion-pause:before,.ion-person:before,.ion-person-add:before,.ion-person-stalker:before,.ion-pie-graph:before,.ion-pin:before,.ion-pinpoint:before,.ion-pizza:before,.ion-plane:before,.ion-planet:before,.ion-play:before,.ion-playstation:before,.ion-plus:before,.ion-plus-circled:before,.ion-plus-round:before,.ion-podium:before,.ion-pound:before,.ion-power:before,.ion-pricetag:before,.ion-pricetags:before,.ion-printer:before,.ion-pull-request:before,.ion-qr-scanner:before,.ion-quote:before,.ion-radio-waves:before,.ion-record:before,.ion-refresh:before,.ion-reply:before,.ion-reply-all:before,.ion-ribbon-a:before,.ion-ribbon-b:before,.ion-sad:before,.ion-sad-outline:before,.ion-scissors:before,.ion-search:before,.ion-settings:before,.ion-share:before,.ion-shuffle:before,.ion-skip-backward:before,.ion-skip-forward:before,.ion-social-android:before,.ion-social-android-outline:before,.ion-social-angular:before,.ion-social-angular-outline:before,.ion-social-apple:before,.ion-social-apple-outline:before,.ion-social-bitcoin:before,.ion-social-bitcoin-outline:before,.ion-social-buffer:before,.ion-social-buffer-outline:before,.ion-social-chrome:before,.ion-social-chrome-outline:before,.ion-social-codepen:before,.ion-social-codepen-outline:before,.ion-social-css3:before,.ion-social-css3-outline:before,.ion-social-designernews:before,.ion-social-designernews-outline:before,.ion-social-dribbble:before,.ion-social-dribbble-outline:before,.ion-social-dropbox:before,.ion-social-dropbox-outline:before,.ion-social-euro:before,.ion-social-euro-outline:before,.ion-social-facebook:before,.ion-social-facebook-outline:before,.ion-social-foursquare:before,.ion-social-foursquare-outline:before,.ion-social-freebsd-devil:before,.ion-social-github:before,.ion-social-github-outline:before,.ion-social-google:before,.ion-social-google-outline:before,.ion-social-googleplus:before,.ion-social-googleplus-outline:before,.ion-social-hackernews:before,.ion-social-hackernews-outline:before,.ion-social-html5:before,.ion-social-html5-outline:before,.ion-social-instagram:before,.ion-social-instagram-outline:before,.ion-social-javascript:before,.ion-social-javascript-outline:before,.ion-social-linkedin:before,.ion-social-linkedin-outline:before,.ion-social-markdown:before,.ion-social-nodejs:before,.ion-social-octocat:before,.ion-social-pinterest:before,.ion-social-pinterest-outline:before,.ion-social-python:before,.ion-social-reddit:before,.ion-social-reddit-outline:before,.ion-social-rss:before,.ion-social-rss-outline:before,.ion-social-sass:before,.ion-social-skype:before,.ion-social-skype-outline:before,.ion-social-snapchat:before,.ion-social-snapchat-outline:before,.ion-social-tumblr:before,.ion-social-tumblr-outline:before,.ion-social-tux:before,.ion-social-twitch:before,.ion-social-twitch-outline:before,.ion-social-twitter:before,.ion-social-twitter-outline:before,.ion-social-usd:before,.ion-social-usd-outline:before,.ion-social-vimeo:before,.ion-social-vimeo-outline:before,.ion-social-whatsapp:before,.ion-social-whatsapp-outline:before,.ion-social-windows:before,.ion-social-windows-outline:before,.ion-social-wordpress:before,.ion-social-wordpress-outline:before,.ion-social-yahoo:before,.ion-social-yahoo-outline:before,.ion-social-yen:before,.ion-social-yen-outline:before,.ion-social-youtube:before,.ion-social-youtube-outline:before,.ion-soup-can:before,.ion-soup-can-outline:before,.ion-speakerphone:before,.ion-speedometer:before,.ion-spoon:before,.ion-star:before,.ion-stats-bars:before,.ion-steam:before,.ion-stop:before,.ion-thermometer:before,.ion-thumbsdown:before,.ion-thumbsup:before,.ion-toggle:before,.ion-toggle-filled:before,.ion-transgender:before,.ion-trash-a:before,.ion-trash-b:before,.ion-trophy:before,.ion-tshirt:before,.ion-tshirt-outline:before,.ion-umbrella:before,.ion-university:before,.ion-unlocked:before,.ion-upload:before,.ion-usb:before,.ion-videocamera:before,.ion-volume-high:before,.ion-volume-low:before,.ion-volume-medium:before,.ion-volume-mute:before,.ion-wand:before,.ion-waterdrop:before,.ion-wifi:before,.ion-wineglass:before,.ion-woman:before,.ion-wrench:before,.ion-xbox:before{display:inline-block;font-family:"Ionicons";speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none;text-rendering:auto;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ion-alert:before{content:"\f101"}.ion-alert-circled:before{content:"\f100"}.ion-android-add:before{content:"\f2c7"}.ion-android-add-circle:before{content:"\f359"}.ion-android-alarm-clock:before{content:"\f35a"}.ion-android-alert:before{content:"\f35b"}.ion-android-apps:before{content:"\f35c"}.ion-android-archive:before{content:"\f2c9"}.ion-android-arrow-back:before{content:"\f2ca"}.ion-android-arrow-down:before{content:"\f35d"}.ion-android-arrow-dropdown:before{content:"\f35f"}.ion-android-arrow-dropdown-circle:before{content:"\f35e"}.ion-android-arrow-dropleft:before{content:"\f361"}.ion-android-arrow-dropleft-circle:before{content:"\f360"}.ion-android-arrow-dropright:before{content:"\f363"}.ion-android-arrow-dropright-circle:before{content:"\f362"}.ion-android-arrow-dropup:before{content:"\f365"}.ion-android-arrow-dropup-circle:before{content:"\f364"}.ion-android-arrow-forward:before{content:"\f30f"}.ion-android-arrow-up:before{content:"\f366"}.ion-android-attach:before{content:"\f367"}.ion-android-bar:before{content:"\f368"}.ion-android-bicycle:before{content:"\f369"}.ion-android-boat:before{content:"\f36a"}.ion-android-bookmark:before{content:"\f36b"}.ion-android-bulb:before{content:"\f36c"}.ion-android-bus:before{content:"\f36d"}.ion-android-calendar:before{content:"\f2d1"}.ion-android-call:before{content:"\f2d2"}.ion-android-camera:before{content:"\f2d3"}.ion-android-cancel:before{content:"\f36e"}.ion-android-car:before{content:"\f36f"}.ion-android-cart:before{content:"\f370"}.ion-android-chat:before{content:"\f2d4"}.ion-android-checkbox:before{content:"\f374"}.ion-android-checkbox-blank:before{content:"\f371"}.ion-android-checkbox-outline:before{content:"\f373"}.ion-android-checkbox-outline-blank:before{content:"\f372"}.ion-android-checkmark-circle:before{content:"\f375"}.ion-android-clipboard:before{content:"\f376"}.ion-android-close:before{content:"\f2d7"}.ion-android-cloud:before{content:"\f37a"}.ion-android-cloud-circle:before{content:"\f377"}.ion-android-cloud-done:before{content:"\f378"}.ion-android-cloud-outline:before{content:"\f379"}.ion-android-color-palette:before{content:"\f37b"}.ion-android-compass:before{content:"\f37c"}.ion-android-contact:before{content:"\f2d8"}.ion-android-contacts:before{content:"\f2d9"}.ion-android-contract:before{content:"\f37d"}.ion-android-create:before{content:"\f37e"}.ion-android-delete:before{content:"\f37f"}.ion-android-desktop:before{content:"\f380"}.ion-android-document:before{content:"\f381"}.ion-android-done:before{content:"\f383"}.ion-android-done-all:before{content:"\f382"}.ion-android-download:before{content:"\f2dd"}.ion-android-drafts:before{content:"\f384"}.ion-android-exit:before{content:"\f385"}.ion-android-expand:before{content:"\f386"}.ion-android-favorite:before{content:"\f388"}.ion-android-favorite-outline:before{content:"\f387"}.ion-android-film:before{content:"\f389"}.ion-android-folder:before{content:"\f2e0"}.ion-android-folder-open:before{content:"\f38a"}.ion-android-funnel:before{content:"\f38b"}.ion-android-globe:before{content:"\f38c"}.ion-android-hand:before{content:"\f2e3"}.ion-android-hangout:before{content:"\f38d"}.ion-android-happy:before{content:"\f38e"}.ion-android-home:before{content:"\f38f"}.ion-android-image:before{content:"\f2e4"}.ion-android-laptop:before{content:"\f390"}.ion-android-list:before{content:"\f391"}.ion-android-locate:before{content:"\f2e9"}.ion-android-lock:before{content:"\f392"}.ion-android-mail:before{content:"\f2eb"}.ion-android-map:before{content:"\f393"}.ion-android-menu:before{content:"\f394"}.ion-android-microphone:before{content:"\f2ec"}.ion-android-microphone-off:before{content:"\f395"}.ion-android-more-horizontal:before{content:"\f396"}.ion-android-more-vertical:before{content:"\f397"}.ion-android-navigate:before{content:"\f398"}.ion-android-notifications:before{content:"\f39b"}.ion-android-notifications-none:before{content:"\f399"}.ion-android-notifications-off:before{content:"\f39a"}.ion-android-open:before{content:"\f39c"}.ion-android-options:before{content:"\f39d"}.ion-android-people:before{content:"\f39e"}.ion-android-person:before{content:"\f3a0"}.ion-android-person-add:before{content:"\f39f"}.ion-android-phone-landscape:before{content:"\f3a1"}.ion-android-phone-portrait:before{content:"\f3a2"}.ion-android-pin:before{content:"\f3a3"}.ion-android-plane:before{content:"\f3a4"}.ion-android-playstore:before{content:"\f2f0"}.ion-android-print:before{content:"\f3a5"}.ion-android-radio-button-off:before{content:"\f3a6"}.ion-android-radio-button-on:before{content:"\f3a7"}.ion-android-refresh:before{content:"\f3a8"}.ion-android-remove:before{content:"\f2f4"}.ion-android-remove-circle:before{content:"\f3a9"}.ion-android-restaurant:before{content:"\f3aa"}.ion-android-sad:before{content:"\f3ab"}.ion-android-search:before{content:"\f2f5"}.ion-android-send:before{content:"\f2f6"}.ion-android-settings:before{content:"\f2f7"}.ion-android-share:before{content:"\f2f8"}.ion-android-share-alt:before{content:"\f3ac"}.ion-android-star:before{content:"\f2fc"}.ion-android-star-half:before{content:"\f3ad"}.ion-android-star-outline:before{content:"\f3ae"}.ion-android-stopwatch:before{content:"\f2fd"}.ion-android-subway:before{content:"\f3af"}.ion-android-sunny:before{content:"\f3b0"}.ion-android-sync:before{content:"\f3b1"}.ion-android-textsms:before{content:"\f3b2"}.ion-android-time:before{content:"\f3b3"}.ion-android-train:before{content:"\f3b4"}.ion-android-unlock:before{content:"\f3b5"}.ion-android-upload:before{content:"\f3b6"}.ion-android-volume-down:before{content:"\f3b7"}.ion-android-volume-mute:before{content:"\f3b8"}.ion-android-volume-off:before{content:"\f3b9"}.ion-android-volume-up:before{content:"\f3ba"}.ion-android-walk:before{content:"\f3bb"}.ion-android-warning:before{content:"\f3bc"}.ion-android-watch:before{content:"\f3bd"}.ion-android-wifi:before{content:"\f305"}.ion-aperture:before{content:"\f313"}.ion-archive:before{content:"\f102"}.ion-arrow-down-a:before{content:"\f103"}.ion-arrow-down-b:before{content:"\f104"}.ion-arrow-down-c:before{content:"\f105"}.ion-arrow-expand:before{content:"\f25e"}.ion-arrow-graph-down-left:before{content:"\f25f"}.ion-arrow-graph-down-right:before{content:"\f260"}.ion-arrow-graph-up-left:before{content:"\f261"}.ion-arrow-graph-up-right:before{content:"\f262"}.ion-arrow-left-a:before{content:"\f106"}.ion-arrow-left-b:before{content:"\f107"}.ion-arrow-left-c:before{content:"\f108"}.ion-arrow-move:before{content:"\f263"}.ion-arrow-resize:before{content:"\f264"}.ion-arrow-return-left:before{content:"\f265"}.ion-arrow-return-right:before{content:"\f266"}.ion-arrow-right-a:before{content:"\f109"}.ion-arrow-right-b:before{content:"\f10a"}.ion-arrow-right-c:before{content:"\f10b"}.ion-arrow-shrink:before{content:"\f267"}.ion-arrow-swap:before{content:"\f268"}.ion-arrow-up-a:before{content:"\f10c"}.ion-arrow-up-b:before{content:"\f10d"}.ion-arrow-up-c:before{content:"\f10e"}.ion-asterisk:before{content:"\f314"}.ion-at:before{content:"\f10f"}.ion-backspace:before{content:"\f3bf"}.ion-backspace-outline:before{content:"\f3be"}.ion-bag:before{content:"\f110"}.ion-battery-charging:before{content:"\f111"}.ion-battery-empty:before{content:"\f112"}.ion-battery-full:before{content:"\f113"}.ion-battery-half:before{content:"\f114"}.ion-battery-low:before{content:"\f115"}.ion-beaker:before{content:"\f269"}.ion-beer:before{content:"\f26a"}.ion-bluetooth:before{content:"\f116"}.ion-bonfire:before{content:"\f315"}.ion-bookmark:before{content:"\f26b"}.ion-bowtie:before{content:"\f3c0"}.ion-briefcase:before{content:"\f26c"}.ion-bug:before{content:"\f2be"}.ion-calculator:before{content:"\f26d"}.ion-calendar:before{content:"\f117"}.ion-camera:before{content:"\f118"}.ion-card:before{content:"\f119"}.ion-cash:before{content:"\f316"}.ion-chatbox:before{content:"\f11b"}.ion-chatbox-working:before{content:"\f11a"}.ion-chatboxes:before{content:"\f11c"}.ion-chatbubble:before{content:"\f11e"}.ion-chatbubble-working:before{content:"\f11d"}.ion-chatbubbles:before{content:"\f11f"}.ion-checkmark:before{content:"\f122"}.ion-checkmark-circled:before{content:"\f120"}.ion-checkmark-round:before{content:"\f121"}.ion-chevron-down:before{content:"\f123"}.ion-chevron-left:before{content:"\f124"}.ion-chevron-right:before{content:"\f125"}.ion-chevron-up:before{content:"\f126"}.ion-clipboard:before{content:"\f127"}.ion-clock:before{content:"\f26e"}.ion-close:before{content:"\f12a"}.ion-close-circled:before{content:"\f128"}.ion-close-round:before{content:"\f129"}.ion-closed-captioning:before{content:"\f317"}.ion-cloud:before{content:"\f12b"}.ion-code:before{content:"\f271"}.ion-code-download:before{content:"\f26f"}.ion-code-working:before{content:"\f270"}.ion-coffee:before{content:"\f272"}.ion-compass:before{content:"\f273"}.ion-compose:before{content:"\f12c"}.ion-connection-bars:before{content:"\f274"}.ion-contrast:before{content:"\f275"}.ion-crop:before{content:"\f3c1"}.ion-cube:before{content:"\f318"}.ion-disc:before{content:"\f12d"}.ion-document:before{content:"\f12f"}.ion-document-text:before{content:"\f12e"}.ion-drag:before{content:"\f130"}.ion-earth:before{content:"\f276"}.ion-easel:before{content:"\f3c2"}.ion-edit:before{content:"\f2bf"}.ion-egg:before{content:"\f277"}.ion-eject:before{content:"\f131"}.ion-email:before{content:"\f132"}.ion-email-unread:before{content:"\f3c3"}.ion-erlenmeyer-flask:before{content:"\f3c5"}.ion-erlenmeyer-flask-bubbles:before{content:"\f3c4"}.ion-eye:before{content:"\f133"}.ion-eye-disabled:before{content:"\f306"}.ion-female:before{content:"\f278"}.ion-filing:before{content:"\f134"}.ion-film-marker:before{content:"\f135"}.ion-fireball:before{content:"\f319"}.ion-flag:before{content:"\f279"}.ion-flame:before{content:"\f31a"}.ion-flash:before{content:"\f137"}.ion-flash-off:before{content:"\f136"}.ion-folder:before{content:"\f139"}.ion-fork:before{content:"\f27a"}.ion-fork-repo:before{content:"\f2c0"}.ion-forward:before{content:"\f13a"}.ion-funnel:before{content:"\f31b"}.ion-gear-a:before{content:"\f13d"}.ion-gear-b:before{content:"\f13e"}.ion-grid:before{content:"\f13f"}.ion-hammer:before{content:"\f27b"}.ion-happy:before{content:"\f31c"}.ion-happy-outline:before{content:"\f3c6"}.ion-headphone:before{content:"\f140"}.ion-heart:before{content:"\f141"}.ion-heart-broken:before{content:"\f31d"}.ion-help:before{content:"\f143"}.ion-help-buoy:before{content:"\f27c"}.ion-help-circled:before{content:"\f142"}.ion-home:before{content:"\f144"}.ion-icecream:before{content:"\f27d"}.ion-image:before{content:"\f147"}.ion-images:before{content:"\f148"}.ion-information:before{content:"\f14a"}.ion-information-circled:before{content:"\f149"}.ion-ionic:before{content:"\f14b"}.ion-ios-alarm:before{content:"\f3c8"}.ion-ios-alarm-outline:before{content:"\f3c7"}.ion-ios-albums:before{content:"\f3ca"}.ion-ios-albums-outline:before{content:"\f3c9"}.ion-ios-americanfootball:before{content:"\f3cc"}.ion-ios-americanfootball-outline:before{content:"\f3cb"}.ion-ios-analytics:before{content:"\f3ce"}.ion-ios-analytics-outline:before{content:"\f3cd"}.ion-ios-arrow-back:before{content:"\f3cf"}.ion-ios-arrow-down:before{content:"\f3d0"}.ion-ios-arrow-forward:before{content:"\f3d1"}.ion-ios-arrow-left:before{content:"\f3d2"}.ion-ios-arrow-right:before{content:"\f3d3"}.ion-ios-arrow-thin-down:before{content:"\f3d4"}.ion-ios-arrow-thin-left:before{content:"\f3d5"}.ion-ios-arrow-thin-right:before{content:"\f3d6"}.ion-ios-arrow-thin-up:before{content:"\f3d7"}.ion-ios-arrow-up:before{content:"\f3d8"}.ion-ios-at:before{content:"\f3da"}.ion-ios-at-outline:before{content:"\f3d9"}.ion-ios-barcode:before{content:"\f3dc"}.ion-ios-barcode-outline:before{content:"\f3db"}.ion-ios-baseball:before{content:"\f3de"}.ion-ios-baseball-outline:before{content:"\f3dd"}.ion-ios-basketball:before{content:"\f3e0"}.ion-ios-basketball-outline:before{content:"\f3df"}.ion-ios-bell:before{content:"\f3e2"}.ion-ios-bell-outline:before{content:"\f3e1"}.ion-ios-body:before{content:"\f3e4"}.ion-ios-body-outline:before{content:"\f3e3"}.ion-ios-bolt:before{content:"\f3e6"}.ion-ios-bolt-outline:before{content:"\f3e5"}.ion-ios-book:before{content:"\f3e8"}.ion-ios-book-outline:before{content:"\f3e7"}.ion-ios-bookmarks:before{content:"\f3ea"}.ion-ios-bookmarks-outline:before{content:"\f3e9"}.ion-ios-box:before{content:"\f3ec"}.ion-ios-box-outline:before{content:"\f3eb"}.ion-ios-briefcase:before{content:"\f3ee"}.ion-ios-briefcase-outline:before{content:"\f3ed"}.ion-ios-browsers:before{content:"\f3f0"}.ion-ios-browsers-outline:before{content:"\f3ef"}.ion-ios-calculator:before{content:"\f3f2"}.ion-ios-calculator-outline:before{content:"\f3f1"}.ion-ios-calendar:before{content:"\f3f4"}.ion-ios-calendar-outline:before{content:"\f3f3"}.ion-ios-camera:before{content:"\f3f6"}.ion-ios-camera-outline:before{content:"\f3f5"}.ion-ios-cart:before{content:"\f3f8"}.ion-ios-cart-outline:before{content:"\f3f7"}.ion-ios-chatboxes:before{content:"\f3fa"}.ion-ios-chatboxes-outline:before{content:"\f3f9"}.ion-ios-chatbubble:before{content:"\f3fc"}.ion-ios-chatbubble-outline:before{content:"\f3fb"}.ion-ios-checkmark:before{content:"\f3ff"}.ion-ios-checkmark-empty:before{content:"\f3fd"}.ion-ios-checkmark-outline:before{content:"\f3fe"}.ion-ios-circle-filled:before{content:"\f400"}.ion-ios-circle-outline:before{content:"\f401"}.ion-ios-clock:before{content:"\f403"}.ion-ios-clock-outline:before{content:"\f402"}.ion-ios-close:before{content:"\f406"}.ion-ios-close-empty:before{content:"\f404"}.ion-ios-close-outline:before{content:"\f405"}.ion-ios-cloud:before{content:"\f40c"}.ion-ios-cloud-download:before{content:"\f408"}.ion-ios-cloud-download-outline:before{content:"\f407"}.ion-ios-cloud-outline:before{content:"\f409"}.ion-ios-cloud-upload:before{content:"\f40b"}.ion-ios-cloud-upload-outline:before{content:"\f40a"}.ion-ios-cloudy:before{content:"\f410"}.ion-ios-cloudy-night:before{content:"\f40e"}.ion-ios-cloudy-night-outline:before{content:"\f40d"}.ion-ios-cloudy-outline:before{content:"\f40f"}.ion-ios-cog:before{content:"\f412"}.ion-ios-cog-outline:before{content:"\f411"}.ion-ios-color-filter:before{content:"\f414"}.ion-ios-color-filter-outline:before{content:"\f413"}.ion-ios-color-wand:before{content:"\f416"}.ion-ios-color-wand-outline:before{content:"\f415"}.ion-ios-compose:before{content:"\f418"}.ion-ios-compose-outline:before{content:"\f417"}.ion-ios-contact:before{content:"\f41a"}.ion-ios-contact-outline:before{content:"\f419"}.ion-ios-copy:before{content:"\f41c"}.ion-ios-copy-outline:before{content:"\f41b"}.ion-ios-crop:before{content:"\f41e"}.ion-ios-crop-strong:before{content:"\f41d"}.ion-ios-download:before{content:"\f420"}.ion-ios-download-outline:before{content:"\f41f"}.ion-ios-drag:before{content:"\f421"}.ion-ios-email:before{content:"\f423"}.ion-ios-email-outline:before{content:"\f422"}.ion-ios-eye:before{content:"\f425"}.ion-ios-eye-outline:before{content:"\f424"}.ion-ios-fastforward:before{content:"\f427"}.ion-ios-fastforward-outline:before{content:"\f426"}.ion-ios-filing:before{content:"\f429"}.ion-ios-filing-outline:before{content:"\f428"}.ion-ios-film:before{content:"\f42b"}.ion-ios-film-outline:before{content:"\f42a"}.ion-ios-flag:before{content:"\f42d"}.ion-ios-flag-outline:before{content:"\f42c"}.ion-ios-flame:before{content:"\f42f"}.ion-ios-flame-outline:before{content:"\f42e"}.ion-ios-flask:before{content:"\f431"}.ion-ios-flask-outline:before{content:"\f430"}.ion-ios-flower:before{content:"\f433"}.ion-ios-flower-outline:before{content:"\f432"}.ion-ios-folder:before{content:"\f435"}.ion-ios-folder-outline:before{content:"\f434"}.ion-ios-football:before{content:"\f437"}.ion-ios-football-outline:before{content:"\f436"}.ion-ios-game-controller-a:before{content:"\f439"}.ion-ios-game-controller-a-outline:before{content:"\f438"}.ion-ios-game-controller-b:before{content:"\f43b"}.ion-ios-game-controller-b-outline:before{content:"\f43a"}.ion-ios-gear:before{content:"\f43d"}.ion-ios-gear-outline:before{content:"\f43c"}.ion-ios-glasses:before{content:"\f43f"}.ion-ios-glasses-outline:before{content:"\f43e"}.ion-ios-grid-view:before{content:"\f441"}.ion-ios-grid-view-outline:before{content:"\f440"}.ion-ios-heart:before{content:"\f443"}.ion-ios-heart-outline:before{content:"\f442"}.ion-ios-help:before{content:"\f446"}.ion-ios-help-empty:before{content:"\f444"}.ion-ios-help-outline:before{content:"\f445"}.ion-ios-home:before{content:"\f448"}.ion-ios-home-outline:before{content:"\f447"}.ion-ios-infinite:before{content:"\f44a"}.ion-ios-infinite-outline:before{content:"\f449"}.ion-ios-information:before{content:"\f44d"}.ion-ios-information-empty:before{content:"\f44b"}.ion-ios-information-outline:before{content:"\f44c"}.ion-ios-ionic-outline:before{content:"\f44e"}.ion-ios-keypad:before{content:"\f450"}.ion-ios-keypad-outline:before{content:"\f44f"}.ion-ios-lightbulb:before{content:"\f452"}.ion-ios-lightbulb-outline:before{content:"\f451"}.ion-ios-list:before{content:"\f454"}.ion-ios-list-outline:before{content:"\f453"}.ion-ios-location:before{content:"\f456"}.ion-ios-location-outline:before{content:"\f455"}.ion-ios-locked:before{content:"\f458"}.ion-ios-locked-outline:before{content:"\f457"}.ion-ios-loop:before{content:"\f45a"}.ion-ios-loop-strong:before{content:"\f459"}.ion-ios-medical:before{content:"\f45c"}.ion-ios-medical-outline:before{content:"\f45b"}.ion-ios-medkit:before{content:"\f45e"}.ion-ios-medkit-outline:before{content:"\f45d"}.ion-ios-mic:before{content:"\f461"}.ion-ios-mic-off:before{content:"\f45f"}.ion-ios-mic-outline:before{content:"\f460"}.ion-ios-minus:before{content:"\f464"}.ion-ios-minus-empty:before{content:"\f462"}.ion-ios-minus-outline:before{content:"\f463"}.ion-ios-monitor:before{content:"\f466"}.ion-ios-monitor-outline:before{content:"\f465"}.ion-ios-moon:before{content:"\f468"}.ion-ios-moon-outline:before{content:"\f467"}.ion-ios-more:before{content:"\f46a"}.ion-ios-more-outline:before{content:"\f469"}.ion-ios-musical-note:before{content:"\f46b"}.ion-ios-musical-notes:before{content:"\f46c"}.ion-ios-navigate:before{content:"\f46e"}.ion-ios-navigate-outline:before{content:"\f46d"}.ion-ios-nutrition:before{content:"\f470"}.ion-ios-nutrition-outline:before{content:"\f46f"}.ion-ios-paper:before{content:"\f472"}.ion-ios-paper-outline:before{content:"\f471"}.ion-ios-paperplane:before{content:"\f474"}.ion-ios-paperplane-outline:before{content:"\f473"}.ion-ios-partlysunny:before{content:"\f476"}.ion-ios-partlysunny-outline:before{content:"\f475"}.ion-ios-pause:before{content:"\f478"}.ion-ios-pause-outline:before{content:"\f477"}.ion-ios-paw:before{content:"\f47a"}.ion-ios-paw-outline:before{content:"\f479"}.ion-ios-people:before{content:"\f47c"}.ion-ios-people-outline:before{content:"\f47b"}.ion-ios-person:before{content:"\f47e"}.ion-ios-person-outline:before{content:"\f47d"}.ion-ios-personadd:before{content:"\f480"}.ion-ios-personadd-outline:before{content:"\f47f"}.ion-ios-photos:before{content:"\f482"}.ion-ios-photos-outline:before{content:"\f481"}.ion-ios-pie:before{content:"\f484"}.ion-ios-pie-outline:before{content:"\f483"}.ion-ios-pint:before{content:"\f486"}.ion-ios-pint-outline:before{content:"\f485"}.ion-ios-play:before{content:"\f488"}.ion-ios-play-outline:before{content:"\f487"}.ion-ios-plus:before{content:"\f48b"}.ion-ios-plus-empty:before{content:"\f489"}.ion-ios-plus-outline:before{content:"\f48a"}.ion-ios-pricetag:before{content:"\f48d"}.ion-ios-pricetag-outline:before{content:"\f48c"}.ion-ios-pricetags:before{content:"\f48f"}.ion-ios-pricetags-outline:before{content:"\f48e"}.ion-ios-printer:before{content:"\f491"}.ion-ios-printer-outline:before{content:"\f490"}.ion-ios-pulse:before{content:"\f493"}.ion-ios-pulse-strong:before{content:"\f492"}.ion-ios-rainy:before{content:"\f495"}.ion-ios-rainy-outline:before{content:"\f494"}.ion-ios-recording:before{content:"\f497"}.ion-ios-recording-outline:before{content:"\f496"}.ion-ios-redo:before{content:"\f499"}.ion-ios-redo-outline:before{content:"\f498"}.ion-ios-refresh:before{content:"\f49c"}.ion-ios-refresh-empty:before{content:"\f49a"}.ion-ios-refresh-outline:before{content:"\f49b"}.ion-ios-reload:before{content:"\f49d"}.ion-ios-reverse-camera:before{content:"\f49f"}.ion-ios-reverse-camera-outline:before{content:"\f49e"}.ion-ios-rewind:before{content:"\f4a1"}.ion-ios-rewind-outline:before{content:"\f4a0"}.ion-ios-rose:before{content:"\f4a3"}.ion-ios-rose-outline:before{content:"\f4a2"}.ion-ios-search:before{content:"\f4a5"}.ion-ios-search-strong:before{content:"\f4a4"}.ion-ios-settings:before{content:"\f4a7"}.ion-ios-settings-strong:before{content:"\f4a6"}.ion-ios-shuffle:before{content:"\f4a9"}.ion-ios-shuffle-strong:before{content:"\f4a8"}.ion-ios-skipbackward:before{content:"\f4ab"}.ion-ios-skipbackward-outline:before{content:"\f4aa"}.ion-ios-skipforward:before{content:"\f4ad"}.ion-ios-skipforward-outline:before{content:"\f4ac"}.ion-ios-snowy:before{content:"\f4ae"}.ion-ios-speedometer:before{content:"\f4b0"}.ion-ios-speedometer-outline:before{content:"\f4af"}.ion-ios-star:before{content:"\f4b3"}.ion-ios-star-half:before{content:"\f4b1"}.ion-ios-star-outline:before{content:"\f4b2"}.ion-ios-stopwatch:before{content:"\f4b5"}.ion-ios-stopwatch-outline:before{content:"\f4b4"}.ion-ios-sunny:before{content:"\f4b7"}.ion-ios-sunny-outline:before{content:"\f4b6"}.ion-ios-telephone:before{content:"\f4b9"}.ion-ios-telephone-outline:before{content:"\f4b8"}.ion-ios-tennisball:before{content:"\f4bb"}.ion-ios-tennisball-outline:before{content:"\f4ba"}.ion-ios-thunderstorm:before{content:"\f4bd"}.ion-ios-thunderstorm-outline:before{content:"\f4bc"}.ion-ios-time:before{content:"\f4bf"}.ion-ios-time-outline:before{content:"\f4be"}.ion-ios-timer:before{content:"\f4c1"}.ion-ios-timer-outline:before{content:"\f4c0"}.ion-ios-toggle:before{content:"\f4c3"}.ion-ios-toggle-outline:before{content:"\f4c2"}.ion-ios-trash:before{content:"\f4c5"}.ion-ios-trash-outline:before{content:"\f4c4"}.ion-ios-undo:before{content:"\f4c7"}.ion-ios-undo-outline:before{content:"\f4c6"}.ion-ios-unlocked:before{content:"\f4c9"}.ion-ios-unlocked-outline:before{content:"\f4c8"}.ion-ios-upload:before{content:"\f4cb"}.ion-ios-upload-outline:before{content:"\f4ca"}.ion-ios-videocam:before{content:"\f4cd"}.ion-ios-videocam-outline:before{content:"\f4cc"}.ion-ios-volume-high:before{content:"\f4ce"}.ion-ios-volume-low:before{content:"\f4cf"}.ion-ios-wineglass:before{content:"\f4d1"}.ion-ios-wineglass-outline:before{content:"\f4d0"}.ion-ios-world:before{content:"\f4d3"}.ion-ios-world-outline:before{content:"\f4d2"}.ion-ipad:before{content:"\f1f9"}.ion-iphone:before{content:"\f1fa"}.ion-ipod:before{content:"\f1fb"}.ion-jet:before{content:"\f295"}.ion-key:before{content:"\f296"}.ion-knife:before{content:"\f297"}.ion-laptop:before{content:"\f1fc"}.ion-leaf:before{content:"\f1fd"}.ion-levels:before{content:"\f298"}.ion-lightbulb:before{content:"\f299"}.ion-link:before{content:"\f1fe"}.ion-load-a:before{content:"\f29a"}.ion-load-b:before{content:"\f29b"}.ion-load-c:before{content:"\f29c"}.ion-load-d:before{content:"\f29d"}.ion-location:before{content:"\f1ff"}.ion-lock-combination:before{content:"\f4d4"}.ion-locked:before{content:"\f200"}.ion-log-in:before{content:"\f29e"}.ion-log-out:before{content:"\f29f"}.ion-loop:before{content:"\f201"}.ion-magnet:before{content:"\f2a0"}.ion-male:before{content:"\f2a1"}.ion-man:before{content:"\f202"}.ion-map:before{content:"\f203"}.ion-medkit:before{content:"\f2a2"}.ion-merge:before{content:"\f33f"}.ion-mic-a:before{content:"\f204"}.ion-mic-b:before{content:"\f205"}.ion-mic-c:before{content:"\f206"}.ion-minus:before{content:"\f209"}.ion-minus-circled:before{content:"\f207"}.ion-minus-round:before{content:"\f208"}.ion-model-s:before{content:"\f2c1"}.ion-monitor:before{content:"\f20a"}.ion-more:before{content:"\f20b"}.ion-mouse:before{content:"\f340"}.ion-music-note:before{content:"\f20c"}.ion-navicon:before{content:"\f20e"}.ion-navicon-round:before{content:"\f20d"}.ion-navigate:before{content:"\f2a3"}.ion-network:before{content:"\f341"}.ion-no-smoking:before{content:"\f2c2"}.ion-nuclear:before{content:"\f2a4"}.ion-outlet:before{content:"\f342"}.ion-paintbrush:before{content:"\f4d5"}.ion-paintbucket:before{content:"\f4d6"}.ion-paper-airplane:before{content:"\f2c3"}.ion-paperclip:before{content:"\f20f"}.ion-pause:before{content:"\f210"}.ion-person:before{content:"\f213"}.ion-person-add:before{content:"\f211"}.ion-person-stalker:before{content:"\f212"}.ion-pie-graph:before{content:"\f2a5"}.ion-pin:before{content:"\f2a6"}.ion-pinpoint:before{content:"\f2a7"}.ion-pizza:before{content:"\f2a8"}.ion-plane:before{content:"\f214"}.ion-planet:before{content:"\f343"}.ion-play:before{content:"\f215"}.ion-playstation:before{content:"\f30a"}.ion-plus:before{content:"\f218"}.ion-plus-circled:before{content:"\f216"}.ion-plus-round:before{content:"\f217"}.ion-podium:before{content:"\f344"}.ion-pound:before{content:"\f219"}.ion-power:before{content:"\f2a9"}.ion-pricetag:before{content:"\f2aa"}.ion-pricetags:before{content:"\f2ab"}.ion-printer:before{content:"\f21a"}.ion-pull-request:before{content:"\f345"}.ion-qr-scanner:before{content:"\f346"}.ion-quote:before{content:"\f347"}.ion-radio-waves:before{content:"\f2ac"}.ion-record:before{content:"\f21b"}.ion-refresh:before{content:"\f21c"}.ion-reply:before{content:"\f21e"}.ion-reply-all:before{content:"\f21d"}.ion-ribbon-a:before{content:"\f348"}.ion-ribbon-b:before{content:"\f349"}.ion-sad:before{content:"\f34a"}.ion-sad-outline:before{content:"\f4d7"}.ion-scissors:before{content:"\f34b"}.ion-search:before{content:"\f21f"}.ion-settings:before{content:"\f2ad"}.ion-share:before{content:"\f220"}.ion-shuffle:before{content:"\f221"}.ion-skip-backward:before{content:"\f222"}.ion-skip-forward:before{content:"\f223"}.ion-social-android:before{content:"\f225"}.ion-social-android-outline:before{content:"\f224"}.ion-social-angular:before{content:"\f4d9"}.ion-social-angular-outline:before{content:"\f4d8"}.ion-social-apple:before{content:"\f227"}.ion-social-apple-outline:before{content:"\f226"}.ion-social-bitcoin:before{content:"\f2af"}.ion-social-bitcoin-outline:before{content:"\f2ae"}.ion-social-buffer:before{content:"\f229"}.ion-social-buffer-outline:before{content:"\f228"}.ion-social-chrome:before{content:"\f4db"}.ion-social-chrome-outline:before{content:"\f4da"}.ion-social-codepen:before{content:"\f4dd"}.ion-social-codepen-outline:before{content:"\f4dc"}.ion-social-css3:before{content:"\f4df"}.ion-social-css3-outline:before{content:"\f4de"}.ion-social-designernews:before{content:"\f22b"}.ion-social-designernews-outline:before{content:"\f22a"}.ion-social-dribbble:before{content:"\f22d"}.ion-social-dribbble-outline:before{content:"\f22c"}.ion-social-dropbox:before{content:"\f22f"}.ion-social-dropbox-outline:before{content:"\f22e"}.ion-social-euro:before{content:"\f4e1"}.ion-social-euro-outline:before{content:"\f4e0"}.ion-social-facebook:before{content:"\f231"}.ion-social-facebook-outline:before{content:"\f230"}.ion-social-foursquare:before{content:"\f34d"}.ion-social-foursquare-outline:before{content:"\f34c"}.ion-social-freebsd-devil:before{content:"\f2c4"}.ion-social-github:before{content:"\f233"}.ion-social-github-outline:before{content:"\f232"}.ion-social-google:before{content:"\f34f"}.ion-social-google-outline:before{content:"\f34e"}.ion-social-googleplus:before{content:"\f235"}.ion-social-googleplus-outline:before{content:"\f234"}.ion-social-hackernews:before{content:"\f237"}.ion-social-hackernews-outline:before{content:"\f236"}.ion-social-html5:before{content:"\f4e3"}.ion-social-html5-outline:before{content:"\f4e2"}.ion-social-instagram:before{content:"\f351"}.ion-social-instagram-outline:before{content:"\f350"}.ion-social-javascript:before{content:"\f4e5"}.ion-social-javascript-outline:before{content:"\f4e4"}.ion-social-linkedin:before{content:"\f239"}.ion-social-linkedin-outline:before{content:"\f238"}.ion-social-markdown:before{content:"\f4e6"}.ion-social-nodejs:before{content:"\f4e7"}.ion-social-octocat:before{content:"\f4e8"}.ion-social-pinterest:before{content:"\f2b1"}.ion-social-pinterest-outline:before{content:"\f2b0"}.ion-social-python:before{content:"\f4e9"}.ion-social-reddit:before{content:"\f23b"}.ion-social-reddit-outline:before{content:"\f23a"}.ion-social-rss:before{content:"\f23d"}.ion-social-rss-outline:before{content:"\f23c"}.ion-social-sass:before{content:"\f4ea"}.ion-social-skype:before{content:"\f23f"}.ion-social-skype-outline:before{content:"\f23e"}.ion-social-snapchat:before{content:"\f4ec"}.ion-social-snapchat-outline:before{content:"\f4eb"}.ion-social-tumblr:before{content:"\f241"}.ion-social-tumblr-outline:before{content:"\f240"}.ion-social-tux:before{content:"\f2c5"}.ion-social-twitch:before{content:"\f4ee"}.ion-social-twitch-outline:before{content:"\f4ed"}.ion-social-twitter:before{content:"\f243"}.ion-social-twitter-outline:before{content:"\f242"}.ion-social-usd:before{content:"\f353"}.ion-social-usd-outline:before{content:"\f352"}.ion-social-vimeo:before{content:"\f245"}.ion-social-vimeo-outline:before{content:"\f244"}.ion-social-whatsapp:before{content:"\f4f0"}.ion-social-whatsapp-outline:before{content:"\f4ef"}.ion-social-windows:before{content:"\f247"}.ion-social-windows-outline:before{content:"\f246"}.ion-social-wordpress:before{content:"\f249"}.ion-social-wordpress-outline:before{content:"\f248"}.ion-social-yahoo:before{content:"\f24b"}.ion-social-yahoo-outline:before{content:"\f24a"}.ion-social-yen:before{content:"\f4f2"}.ion-social-yen-outline:before{content:"\f4f1"}.ion-social-youtube:before{content:"\f24d"}.ion-social-youtube-outline:before{content:"\f24c"}.ion-soup-can:before{content:"\f4f4"}.ion-soup-can-outline:before{content:"\f4f3"}.ion-speakerphone:before{content:"\f2b2"}.ion-speedometer:before{content:"\f2b3"}.ion-spoon:before{content:"\f2b4"}.ion-star:before{content:"\f24e"}.ion-stats-bars:before{content:"\f2b5"}.ion-steam:before{content:"\f30b"}.ion-stop:before{content:"\f24f"}.ion-thermometer:before{content:"\f2b6"}.ion-thumbsdown:before{content:"\f250"}.ion-thumbsup:before{content:"\f251"}.ion-toggle:before{content:"\f355"}.ion-toggle-filled:before{content:"\f354"}.ion-transgender:before{content:"\f4f5"}.ion-trash-a:before{content:"\f252"}.ion-trash-b:before{content:"\f253"}.ion-trophy:before{content:"\f356"}.ion-tshirt:before{content:"\f4f7"}.ion-tshirt-outline:before{content:"\f4f6"}.ion-umbrella:before{content:"\f2b7"}.ion-university:before{content:"\f357"}.ion-unlocked:before{content:"\f254"}.ion-upload:before{content:"\f255"}.ion-usb:before{content:"\f2b8"}.ion-videocamera:before{content:"\f256"}.ion-volume-high:before{content:"\f257"}.ion-volume-low:before{content:"\f258"}.ion-volume-medium:before{content:"\f259"}.ion-volume-mute:before{content:"\f25a"}.ion-wand:before{content:"\f358"}.ion-waterdrop:before{content:"\f25b"}.ion-wifi:before{content:"\f25c"}.ion-wineglass:before{content:"\f2b9"}.ion-woman:before{content:"\f25d"}.ion-wrench:before{content:"\f2ba"}.ion-xbox:before{content:"\f30c"} diff --git a/SiteServer.Web/SiteServer/assets/css/menu.css b/SiteServer.Web/SiteServer/assets/css/menu.css deleted file mode 100644 index f51f7b9d2..000000000 --- a/SiteServer.Web/SiteServer/assets/css/menu.css +++ /dev/null @@ -1,1151 +0,0 @@ -/* -Template Name: Minton Dashboard -Author: CoderThemes -Email: coderthemes@gmail.com -File: Topbar,Left-sidebar,Right-sidebar -*/ -.topbar { - left: 0px; - position: fixed; - right: 0; - top: 0px; - z-index: 999; -} -.topbar .topbar-left { - background: #282c37; - float: left; - height: 70px; - position: relative; - width: 240px; - z-index: 1; -} -.navbar-default { - background-color: #323944; - border-radius: 0px; - border: none; - margin-bottom: 0px; -} -.navbar-default .navbar-nav > .open > a { - background-color: rgba(0, 0, 0, 0.06); -} -.navbar-default .navbar-nav > .open > a:focus { - background-color: rgba(0, 0, 0, 0.06); -} -.navbar-default .navbar-nav > .open > a:hover { - background-color: rgba(0, 0, 0, 0.06); -} -.nav > li > a { - color: #ffffff !important; - line-height: 70px; - padding: 0px 15px; - position: relative; -} -.nav > li > a i { - font-size: 20px; -} -.profile img { - border: 2px solid #edf0f0; - height: 36px; - width: 36px; -} -.dropdown-menu-lg { - width: 300px; -} -.dropdown-menu-lg .list-group { - margin-bottom: 0px; -} -.dropdown-menu-lg .list-group-item { - border: none; - padding: 10px 20px; -} -.dropdown-menu-lg .media-heading { - margin-bottom: 0px; -} -.dropdown-menu-lg .media-body p { - color: #828282; -} -.notifi-title { - border-bottom: 1px solid rgba(0, 0, 0, 0.1); - color: #000000; - font-size: 16px; - font-weight: 400; - padding: 5px 0px 10px; -} -.notification-list em { - width: 30px; - text-align: center; - height: 30px; - line-height: 28px; - border-radius: 50%; - margin-top: 4px; -} -.notification-list .list-group-item { - padding: 12px 20px; -} -.notification-list .media-body { - display: inherit; - width: auto; - overflow: hidden; - margin-left: 50px; -} -.notification-list .media-body h5 { - text-overflow: ellipsis; - white-space: nowrap; - display: block; - width: 100%; - font-weight: normal; - overflow: hidden; -} -.noti-primary { - color: #00b19d; - border: 2px solid #00b19d; -} -.noti-success { - color: #00b19d; - border: 2px solid #00b19d; -} -.noti-info { - color: #3ddcf7; - border: 2px solid #3ddcf7; -} -.noti-warning { - color: #ffaa00; - border: 2px solid #ffaa00; -} -.noti-danger { - color: #ef5350; - border: 2px solid #ef5350; -} -.noti-purple { - color: #7266ba; - border: 2px solid #7266ba; -} -.noti-pink { - color: #f76397; - border: 2px solid #f76397; -} -.noti-inverse { - color: #4c5667; - border: 2px solid #4c5667; -} -.navbar-form { - border: none; - box-shadow: none; - padding: 0px; -} -.app-search { - position: relative; - margin: 15px 0px 15px 10px; -} -.app-search a { - position: absolute; - top: 10px; - right: 20px; - color: rgba(255, 255, 255, 0.7); -} -.app-search a:hover { - color: #ffffff; -} -.app-search .form-control, -.app-search .form-control:focus { - border: none; - font-size: 13px; - color: #ffffff; - font-weight: 600; - padding-left: 20px; - padding-right: 40px; - margin-top: 3px; - background: rgba(255, 255, 255, 0.2); - box-shadow: none; - border-radius: 30px; - width: 190px; -} -input.app-search-input::-webkit-input-placeholder { - color: rgba(255, 255, 255, 0.7); - font-weight: normal; -} -input.app-search-input:-moz-placeholder { - color: rgba(255, 255, 255, 0.7); -} -input.app-search-input::-moz-placeholder { - color: rgba(255, 255, 255, 0.7); -} -input.app-search-input:-ms-input-placeholder { - color: rgba(255, 255, 255, 0.7); -} -.navbar-nav { - margin: 0px; -} -.side-menu { - bottom: 0; - top: 0; - width: 200px; - z-index: 2; -} -.side-menu.left { - background: #eeeeee; - box-shadow: -4px 4px 40px rgba(0, 0, 0, 0.15); - position: absolute; - top: 62px; -} -body.fixed-left .side-menu.left { - bottom: 50px; - height: 100%; - margin-top: 0; - position: fixed; -} -.content-page { - margin-left: 200px; - overflow: hidden; - background: #fff; - width: 100%; - height: 100%; - margin-top: 0; - position: fixed; -} -.content-page > .content { - margin-bottom: 60px; - margin-top: 10px; - padding: 20px 5px 15px 5px; -} -.button-menu-mobile { - background: transparent; - border: none; - color: #ffffff; - font-size: 21px; - line-height: 70px; - padding: 0px 15px; -} -.button-menu-mobile:hover { - color: #eeeeee; -} -.sidebar-inner { - height: 100%; -} -#sidebar-menu, -#sidebar-menu ul, -#sidebar-menu li, -#sidebar-menu a { - border: 0; - font-family: 'Microsoft YaHei', sans-serif; - font-weight: normal; - line-height: 1; - font-size: 14px; - list-style: none; - margin: 0; - padding: 0; - position: relative; - text-decoration: none; -} -#sidebar-menu { - background-color: #eeeeee; - width: 100%; -} -#sidebar-menu a { - line-height: 1.3; -} -#sidebar-menu a.badge { - display: block; - padding: 1px 5px; - font-weight: 600; - font-size: 12px; - float: right; - border-left: 0 !important; -} -#sidebar-menu a.badge:hover { - background: #ffc107; - border-left: 0 !important; -} - -#sidebar-menu ul li .menu-arrow { - -webkit-transition: -webkit-transform 0.15s; - -o-transition: -o-transform 0.15s; - transition: transform .15s; - position: absolute; - right: 25px; - display: inline-block; - font-family: 'Ionicons'; - text-rendering: auto; - line-height: 18px; - font-size: 16px; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; - -webkit-transform: translate(0, 0); - -ms-transform: translate(0, 0); - -o-transform: translate(0, 0); - transform: translate(0, 0); - color: #98a6ad; -} -#sidebar-menu ul li .menu-arrow:before { - content: "\f3d3"; -} -#sidebar-menu ul li a.subdrop .menu-arrow { - -ms-transform: rotate(90deg); - -webkit-transform: rotate(90deg); - -o-transform: rotate(90deg); - transform: rotate(90deg); -} -#sidebar-menu ul ul { - display: none; -} -#sidebar-menu ul ul li { - border-top: 0; -} -#sidebar-menu ul ul li.active a { - background: #ddd; - color: #00b19d; -} -#sidebar-menu ul ul a { - color: #55565d; - display: block; - padding: 10px 10px 10px 45px; -} -#sidebar-menu ul ul a:hover { - color: #00b19d; -} -#sidebar-menu ul ul a i { - margin-right: 5px; -} -#sidebar-menu ul ul ul a { - padding-left: 80px; -} -#sidebar-menu > ul > li > a { - color: #565b5e; - border-left: 2px solid transparent; - display: block; - padding: 12px 10px; -} -#sidebar-menu > ul > li > a:hover { - background: #f5f5f5; - border-left: 2px solid #00b19d !important; -} -#sidebar-menu > ul > li > a:hover i { - color: #00b19d !important; -} -#sidebar-menu > ul > li > a:hover span { - color: #4c5667; -} -#sidebar-menu > ul > li > a > span { - vertical-align: middle; -} -#sidebar-menu > ul > li > a > i { - display: inline-block; - font-size: 18px; - line-height: 17px; - margin-left: 3px; - margin-right: 12px; - color: #565b5e; - text-align: center; - vertical-align: middle; - width: 20px; -} -#sidebar-menu > ul > li > a > i.i-right { - float: right; - margin: 3px 0 0 0; -} -#sidebar-menu > ul > li > a.active { - background: #f5f5f5; - border-left: 2px solid #00b19d !important; -} -#sidebar-menu > ul > li > a.active i { - color: #00b19d !important; -} -#sidebar-menu > ul > li > a.active span { - color: #4c5667; -} -.menu-title { - padding: 12px 20px!important; - letter-spacing: .035em; - font-size: 15px !important; - margin-top: 10px !important; - font-weight: 500 !important; - padding-left: 32px !important; -} -#sidebar-menu > ul > li > a.active.subdrop { - background: #f5f5f5 !important; - border-left: 2px solid #00b19d; -} -#sidebar-menu > ul > li > a.active.subdrop i { - color: #00b19d; -} -.subdrop { - background: #f5f5f5; - border-left: 2px solid #00b19d !important; -} -.subdrop i { - color: #00b19d !important; -} -.subdrop span { - color: #4c5667; -} - -#wrapper.enlarged .menu-title, -#wrapper.enlarged .menu-arrow { - display: none !important; -} -#wrapper.enlarged #sidebar-menu ul ul { - box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); -} -#wrapper.enlarged .left.side-menu { - width: 70px; - z-index: 5; -} -#wrapper.enlarged .left.side-menu #sidebar-menu > ul > li > a { - padding-left: 10px; -} -#wrapper.enlarged .left.side-menu #sidebar-menu > ul > li > a:hover { - background-color: #f5f5f5 !important; -} -#wrapper.enlarged .left.side-menu span.pull-right { - display: none !important; -} -#wrapper.enlarged .left.side-menu #sidebar-menu ul > li { - position: relative; - white-space: nowrap; -} -#wrapper.enlarged .left.side-menu #sidebar-menu ul > li:hover > a { - background: #f5f5f5; - position: relative; - width: 260px; -} -#wrapper.enlarged .left.side-menu #sidebar-menu ul > li:hover > ul { - display: block; - left: 70px; - position: absolute; - width: 190px; -} -#wrapper.enlarged .left.side-menu #sidebar-menu ul > li:hover > ul a { - background: #ffffff; - border: none; - box-shadow: none; - padding-left: 15px; - position: relative; - width: 190px; - z-index: 6; -} -#wrapper.enlarged .left.side-menu #sidebar-menu ul > li:hover a span { - display: inline; -} -#wrapper.enlarged .left.side-menu #sidebar-menu ul > li > ul { - display: none; -} -#wrapper.enlarged .left.side-menu #sidebar-menu ul ul li:hover > ul { - display: block; - left: 190px; - margin-top: -36px; - position: absolute; - width: 190px; -} -#wrapper.enlarged .left.side-menu #sidebar-menu ul ul li > a span.pull-right { - -ms-transform: rotate(270deg); - -webkit-transform: rotate(270deg); - position: absolute; - right: 20px; - top: 12px; - transform: rotate(270deg); -} -#wrapper.enlarged .left.side-menu #sidebar-menu ul > li > a span { - display: none; - padding-left: 10px; -} -#wrapper.enlarged .left.side-menu #sidebar-menu > ul > li > a > i { - margin: 0px; -} -#wrapper.enlarged .left.side-menu #sidebar-menu > ul > li > a { - padding: 15px 20px; -} -#wrapper.enlarged .left.side-menu #sidebar-menu > ul > li > a i { - margin-right: 20px !important; - font-size: 20px; - color: #a2acae; -} -#wrapper.enlarged .left.side-menu #sidebar-menu ul > li:hover > a { - position: relative; - width: 260px; - background: #f5f5f5; - color: #00b19d; - border-color: #00b19d; -} -#wrapper.enlarged .left.side-menu #sidebar-menu ul > li:hover > a i { - color: #00b19d; -} -#wrapper.enlarged .content-page { - margin-left: 70px; -} -#wrapper.enlarged .topbar .topbar-left { - width: 70px !important; -} -#wrapper.enlarged .topbar .topbar-left .logo span { - display: none; - opacity: 0; -} -#wrapper.enlarged .topbar .topbar-left .logo i { - margin-right: 0px; -} -#wrapper.enlarged #sidebar-menu > ul > li:hover > a.open :after { - display: none; -} -#wrapper.enlarged #sidebar-menu > ul > li:hover > a.active :after { - display: none; -} -#wrapper.enlarged .user-detail { - bottom: 0px; - padding: 13px 0px; - width: 70px; - text-align: center; -} -#wrapper.enlarged .user-detail .dropup { - margin: 0px auto; - margin-left: 17px; -} -#wrapper.enlarged .user-detail h5 { - display: none; -} -#wrapper.enlarged .user-detail p { - position: absolute; - right: 12px; - top: 22px; -} -#wrapper.enlarged .user-detail p span { - display: none; -} -#wrapper.enlarged #sidebar-menu ul ul li.active a { - color: #00b19d; -} -#wrapper.enlarged .footer { - left: 70px; -} -#wrapper.right-bar-enabled .right-bar { - right: 0; -} -#wrapper.right-bar-enabled .left-layout { - left: 0; -} -.right-bar-toggle:focus { - background-color: rgba(0, 0, 0, 0.06) !important; -} -.side-bar.right-bar { - float: right !important; - right: -270px; - bottom: 0px; - top: 70px; -} -.side-bar { - -moz-transition: all 200ms ease-out; - -webkit-transition: all 200ms ease-out; - background-color: #ffffff; - box-shadow: 0px 0px 8px 1px rgba(0, 0, 0, 0.1); - display: block; - overflow-y: auto; - position: fixed; - transition: all 200ms ease-out; - width: 200px; -} -.side-bar .nav.nav-tabs + .tab-content { - margin-bottom: 0px; - padding: 20px; -} -.side-bar .tabs li.tab a { - font-weight: 600; -} -.right-bar { - background: #ffffff !important; - position: fixed !important; - z-index: 99 !important; -} -.right-bar h4 { - border-bottom: 1px solid #eeeeee; - padding-bottom: 10px; -} -.right-bar .nicescroll { - height: 100%; -} - - -/*---------------------------------------------------------------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------------------------------------------------------------*/ -/*---------------------------------------------------------------------------------------------------------------------------------*/ - - - -#topnav { - right: 0; - left: 0; - top: 0; - z-index: 1030; - background-color: transparent; - border: 0; - -webkit-transition: all .5s ease; - transition: all .5s ease; - min-height: 62px; -} -#topnav .has-submenu.active a { - color: #fff; -} -#topnav .has-submenu.active a i { - color: #fff; -} -#topnav .has-submenu.active .submenu li.active a { - color: #00b19d; -} -#topnav .topbar-main { - font-family: 'Microsoft YaHei', sans-serif; - background-color: #00b19d; - height: 62px; -} -#topnav .topbar-main .logo { - color: #ffffff !important; - font-size: 18px; - font-weight: 700; - letter-spacing: .05em; - margin-top: 8px; - margin-left: 8px; - float: left; -} -#topnav .topbar-main .toggle { - color: #ffffff !important; - font-size: 18px; - font-weight: 700; - letter-spacing: .05em; - margin-top: 9px; - margin-left: 5px; - float: left; - text-decoration: none; -} -#topnav .topbar-main .logo h1 { - margin: 0px auto; - text-align: center; -} -#topnav .topbar-main .logo i { - color: #ffffff; -} -#topnav .topbar-main .badge { - position: absolute; - top: 12px; - right: -5px; -} -#topnav .topbar-main .nav > li > a { - color: #ffffff !important; - line-height: 60px; - padding: 0px 15px !important; - position: relative; - background: transparent !important; -} -#topnav .topbar-main .nav > li > a i { - font-size: 24px; -} -#topnav .topbar-main .nav > li > a { - padding: 0px 15px !important; -} -#topnav .topbar-main .navbar-nav > .open > a { - background-color: rgba(255, 255, 255, 0.1) !important; -} -#topnav .topbar-main .profile img { - border: 2px solid #edf0f0; - height: 36px; - width: 36px; -} -#topnav .topbar-main .dropdown-menu-lg { - width: 300px; -} -#topnav .topbar-main .dropdown-menu-lg .list-group { - margin-bottom: 0px; -} -#topnav .topbar-main .dropdown-menu-lg .list-group-item { - border: none; - padding: 10px 20px; -} -#topnav .topbar-main .dropdown-menu-lg .media-heading { - margin-bottom: 0px; -} -#topnav .topbar-main .dropdown-menu-lg .media-body p { - color: #828282; -} -#topnav .topbar-main .notification-list { - max-height: 230px; -} -#topnav .topbar-main .notification-list em { - width: 34px; - text-align: center; -} -#topnav .topbar-main .notification-list .media-body { - display: inherit; - width: auto; - overflow: hidden; - margin-left: 50px; -} -#topnav .topbar-main .notification-list .media-body h5 { - text-overflow: ellipsis; - white-space: nowrap; - display: block; - width: 100%; - font-weight: normal; - overflow: hidden; -} -#topnav .topbar-main .notifi-title { - border-bottom: 1px solid rgba(0, 0, 0, 0.1); - font-size: 15px; - text-transform: uppercase; - font-weight: 600; - padding: 11px 20px 15px; - color: #4c5667; - font-family: 'Microsoft YaHei', sans-serif; -} -#topnav .topbar-main .navbar-nav { - margin: 0px; -} -#topnav .app-search { - position: relative; - margin: 15px 20px 15px 10px; -} -#topnav .app-search a { - position: absolute; - top: 5px; - right: 15px; - color: rgba(255, 255, 255, 0.7); -} -#topnav .app-search a i { - font-size: 18px; -} -#topnav .app-search .form-control, -#topnav .app-search .form-control:focus { - border: none; - font-size: 13px; - color: #ffffff; - padding-left: 20px; - padding-right: 40px; - background: rgba(255, 255, 255, 0.1); - box-shadow: none; - border-radius: 30px; - height: 30px; - width: 180px; -} -#topnav .app-search input::-webkit-input-placeholder { - color: rgba(255, 255, 255, 0.7); - font-weight: normal; -} -#topnav .app-search input:-moz-placeholder { - color: rgba(255, 255, 255, 0.7); -} -#topnav .app-search input::-moz-placeholder { - color: rgba(255, 255, 255, 0.7); -} -#topnav .app-search input:-ms-input-placeholder { - color: rgba(255, 255, 255, 0.7); -} -#topnav .notifi-title { - border-bottom: 1px solid rgba(0, 0, 0, 0.1); - color: #000000; - font-size: 16px; - font-weight: 400; - padding: 5px 0px 10px; -} -#topnav .notification-list em { - width: 30px; - text-align: center; - height: 30px; - line-height: 28px; - border-radius: 50%; - margin-top: 4px; -} -#topnav .notification-list .list-group-item { - padding: 12px 20px; -} -#topnav .notification-list .media-body { - display: inherit; - width: auto; - overflow: hidden; - margin-left: 50px; -} -#topnav .notification-list .media-body h5 { - text-overflow: ellipsis; - white-space: nowrap; - display: block; - width: 100%; - font-weight: normal; - overflow: hidden; -} -#topnav .noti-primary { - color: #00b19d; - border: 2px solid #00b19d; -} -#topnav .noti-success { - color: #3bafda; - border: 2px solid #3bafda; -} -#topnav .noti-info { - color: #3ddcf7; - border: 2px solid #3ddcf7; -} -#topnav .noti-warning { - color: #ffaa00; - border: 2px solid #ffaa00; -} -#topnav .noti-danger { - color: #ef5350; - border: 2px solid #ef5350; -} -#topnav .noti-purple { - color: #7266ba; - border: 2px solid #7266ba; -} -#topnav .noti-pink { - color: #f76397; - border: 2px solid #f76397; -} -#topnav .noti-inverse { - color: #4c5667; - border: 2px solid #4c5667; -} -#topnav .navbar-custom { - background-color: #ffffff; - box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); -} -#topnav .navbar-toggle { - border: 0; - position: relative; - width: 60px; - height: 60px; - padding: 0; - margin: 0; - cursor: pointer; -} -#topnav .navbar-toggle:hover { - background-color: transparent; -} -#topnav .navbar-toggle:hover span { - background-color: #ffffff; -} -#topnav .navbar-toggle:focus { - background-color: transparent; -} -#topnav .navbar-toggle:focus span { - background-color: #00b19d; -} -#topnav .navbar-toggle .lines { - width: 25px; - display: block; - position: relative; - margin: 23px auto 17px auto; - height: 18px; -} -#topnav .navbar-toggle span { - height: 2px; - width: 100%; - background-color: #fff; - display: block; - margin-bottom: 5px; - -webkit-transition: -webkit-transform 0.5s ease; - transition: -webkit-transform 0.5s ease; - transition: transform .5s ease; -} -#topnav .navbar-toggle.open span { - position: absolute; -} -#topnav .navbar-toggle.open span:first-child { - top: 6px; - -webkit-transform: rotate(45deg); - transform: rotate(45deg); -} -#topnav .navbar-toggle.open span:nth-child(2) { - visibility: hidden; -} -#topnav .navbar-toggle.open span:last-child { - width: 100%; - top: 6px; - -webkit-transform: rotate(-45deg); - transform: rotate(-45deg); -} -#topnav .navigation-menu { - list-style: none; - margin: 0; - padding: 0; - margin-left: 245px; -} -#topnav .navigation-menu > li { - float: left; - display: block; - position: relative; -} -#topnav .navigation-menu > li > a { - display: block; - color: #fff; - font-weight: 500; - font-size: 14px; - -webkit-transition: all .3s ease; - transition: all .3s ease; - line-height: 20px; - padding-left: 15px; - padding-right: 15px; - text-decoration: none; -} -#topnav .navigation-menu > li > a:hover { - color: #fff; -} -#topnav .navigation-menu > li > a:hover i { - color: #fff; -} -#topnav .navigation-menu > li > a:focus { - color: #fff; -} -#topnav .navigation-menu > li > a:focus i { - color: #fff; -} -#topnav .navigation-menu > li > a:active { - color: #fff; -} -#topnav .navigation-menu > li > a:active i { - color: #fff; -} -#topnav .navigation-menu > li > a i { - font-size: 18px; - margin-right: 5px; - color: #fff; -} -#topnav .navigation-menu > li > a:hover, -#topnav .navigation-menu > li > a:focus { - background-color: transparent; -} -@media (min-width: 992px) { - #topnav .navigation-menu > li > a { - padding-top: 22px; - padding-bottom: 12px; - } -} -/* - Responsive Menu -*/ -@media (min-width: 992px) { - #topnav .navigation-menu > li.last-elements .submenu { - left: auto; - right: 0; - } - #topnav .navigation-menu > li.last-elements .submenu > li.has-submenu .submenu { - left: auto; - right: 100%; - margin-left: 0; - margin-right: 10px; - } - #topnav .navigation-menu > li:first-of-type a { - padding-left: 0px; - } - #topnav .navigation-menu > li:hover a { - color: #fff; - } - #topnav .navigation-menu > li:hover a i { - color: #fff; - } - #topnav .navigation-menu > li .submenu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - border: 1px solid #e7e7e7; - padding: 15px 0; - list-style: none; - min-width: 200px; - visibility: hidden; - opacity: 0; - margin-top: 10px; - -webkit-transition: all .2s ease; - transition: all .2s ease; - background-color: #ffffff; - box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.1); - } - #topnav .navigation-menu > li .submenu.megamenu { - white-space: nowrap; - width: auto; - } - #topnav .navigation-menu > li .submenu.megamenu > li { - overflow: hidden; - width: 200px; - display: inline-block; - vertical-align: top; - } - #topnav .navigation-menu > li .submenu > li.has-submenu > a:after { - content: "\f3d3"; - font-family: 'Ionicons'; - position: absolute; - right: 20px; - font-size: 16px; - top: 8px; - } - #topnav .navigation-menu > li .submenu > li .submenu { - left: 100%; - top: 0; - margin-left: 10px; - margin-top: -1px; - } - #topnav .navigation-menu > li .submenu li { - position: relative; - } - #topnav .navigation-menu > li .submenu li ul { - list-style: none; - padding-left: 0; - margin: 0; - } - #topnav .navigation-menu > li .submenu li a { - display: block; - padding: 8px 25px; - clear: both; - white-space: nowrap; - font-weight: 500; - font-size: 14px; - text-decoration: none; - color: #494e53; - } - #topnav .navigation-menu > li .submenu li a:hover { - color: #00b19d; - } - #topnav .navigation-menu > li .submenu li span { - display: block; - padding: 8px 25px; - clear: both; - line-height: 1.42857143; - white-space: nowrap; - font-size: 10px; - text-transform: uppercase; - letter-spacing: 2px; - font-weight: 500; - color: #949ba1; - } - #topnav .navbar-toggle { - display: none; - } - #topnav #navigation { - display: block !important; - } -} -@media (max-width: 991px) { - .wrapper { - margin-top: 80px; - } - .container { - width: auto; - } - #topnav .navigation-menu { - float: none; - max-height: 400px; - } - #topnav .navigation-menu > li { - float: none; - } - #topnav .navigation-menu > li > a { - color: #797979; - padding: 15px; - } - #topnav .navigation-menu > li > a i { - display: inline-block; - margin-right: 10px; - margin-bottom: 0px; - } - #topnav .navigation-menu > li > a:after { - position: absolute; - right: 15px; - } - #topnav .navigation-menu > li .submenu { - display: none; - list-style: none; - padding-left: 20px; - margin: 0; - } - #topnav .navigation-menu > li .submenu li a { - display: block; - position: relative; - padding: 7px 20px; - color: #797979; - } - #topnav .navigation-menu > li .submenu li a:hover { - color: #00b19d; - } - #topnav .navigation-menu > li .submenu li.has-submenu > a:after { - content: "\e64b"; - font-family: "themify"; - position: absolute; - right: 30px; - } - #topnav .navigation-menu > li .submenu.open { - display: block; - } - #topnav .navigation-menu > li .submenu .submenu { - display: none; - list-style: none; - } - #topnav .navigation-menu > li .submenu .submenu.open { - display: block; - } - #topnav .navigation-menu > li .submenu.megamenu > li > ul { - list-style: none; - padding-left: 0; - } - #topnav .navigation-menu > li .submenu.megamenu > li > ul > li > span { - display: block; - position: relative; - padding: 15px; - text-transform: uppercase; - font-size: 11px; - letter-spacing: 2px; - color: #79818a; - } - #topnav .navigation-menu > li.has-submenu.open > a { - color: #00b19d; - } - #topnav .navbar-header { - float: left; - } - #navigation { - position: absolute; - top: 60px; - left: 0; - width: 100%; - display: none; - height: auto; - padding-bottom: 0; - overflow: auto; - border-top: 1px solid #e7e7e7; - border-bottom: 1px solid #e7e7e7; - background-color: #fff; - } - #navigation.open { - display: block; - overflow-y: auto; - } -} -@media (min-width: 768px) { - #topnav .navigation-menu > li.has-submenu:hover > .submenu { - visibility: visible; - opacity: 1; - margin-top: 0; - } - #topnav .navigation-menu > li.has-submenu:hover > .submenu > li.has-submenu:hover > .submenu, - #topnav .navigation-menu > li.has-submenu:hover > .submenu > li.has-submenu:hover > .submenu > li.has-submenu:hover > .submenu { - visibility: visible; - opacity: 1; - margin-left: 0; - margin-right: 0; - } - .navbar-toggle { - display: block; - } -} -/* Footer */ -.footer { - border-top: 1px solid rgba(0, 0, 0, 0.1); - bottom: 0px; - color: #58666e; - text-align: left !important; - padding: 20px 0px; - position: absolute; - right: 0px; - left: 0px; -} diff --git a/SiteServer.Web/SiteServer/assets/default/machineTest.txt b/SiteServer.Web/SiteServer/assets/default/machineTest.txt deleted file mode 100644 index 5f282702b..000000000 --- a/SiteServer.Web/SiteServer/assets/default/machineTest.txt +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/assets/js/apiUtils.js b/SiteServer.Web/SiteServer/assets/js/apiUtils.js deleted file mode 100644 index a83042087..000000000 --- a/SiteServer.Web/SiteServer/assets/js/apiUtils.js +++ /dev/null @@ -1,152 +0,0 @@ -var apiUtils = { - Api: function(apiUrl) { - this.getQueryStringByName = function(name) { - var result = location.search.match(new RegExp("[\?\&]" + name + "=([^\&]+)", "i")); - if (!result || result.length < 1) { - return ""; - } - return decodeURIComponent(result[1]); - }; - - this.apiUrl = apiUrl || 'http://api.siteserver.cn/v1.1'; - // this.apiUrl = 'http://localhost:90/v1.1'; - - this._getURL = function(url, data, method) { - url += ((/\?/).test(url) ? '&' : '?'); - if ((typeof data === 'object') && method === 'GET') { - var pairs = []; - for (var prop in data) { - if (data.hasOwnProperty(prop)) { - var k = encodeURIComponent(prop), - v = encodeURIComponent(data[prop]); - pairs.push( k + "=" + v); - } - } - url += "&" + pairs.join("&"); - } - return (url + '&' + (new Date()).getTime()).replace('?&', '?'); - }; - - this.request = function(method, path, data, cb) { - var xhr = new XMLHttpRequest(); - xhr.open(method, this._getURL(path, data, method), true); - xhr.withCredentials = true; - if (cb) { - xhr.onreadystatechange = function() { - if (xhr.readyState === 4) { - if (xhr.status < 400) { - cb(null, apiUtils.parse(xhr.responseText), xhr.status); - } else { - var err = apiUtils.parse(xhr.responseText); - cb({ - status: xhr.status, - message: err.message || apiUtils.errorCode(xhr.status) - }, null, xhr.status); - } - } - }; - } - - xhr.dataType = 'json'; - xhr.setRequestHeader('Accept', 'application/vnd.siteserver+json; version=1'); - xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); - if (data) { - xhr.send(JSON.stringify(data)); - } else { - xhr.send(); - } - }; - - - this.get = function(data, cb, name, id) { - var url = this.apiUrl; - if (name) { - url += '/' + name; - if (id) { - url += '/' + id; - } - } - return this.request("GET", url, data, cb); - }; - - this.post = function(data, cb, name, id) { - var url = this.apiUrl; - if (name) { - url += '/' + name; - if (id) { - url += '/' + id; - } - } - return this.request("POST", url, data, cb); - }; - - this.put = function(data, cb, name, id) { - var url = this.apiUrl; - if (name) { - url += '/' + name; - if (id) { - url += '/' + id; - } - } - return this.request("PUT", url, data, cb); - }; - - this.delete = function(data, cb, name, id) { - var url = this.apiUrl; - if (name) { - url += '/' + name; - if (id) { - url += '/' + id; - } - } - return this.request("DELETE", url, data, cb); - }; - - this.patch = function(data, cb, name, id) { - var url = this.apiUrl; - if (name) { - url += '/' + name; - if (id) { - url += '/' + id; - } - } - return this.request("PATCH", url, data, cb); - }; - }, - - parse: function(responseText) { - return responseText ? JSON.parse(responseText) : {}; - }, - - errorCode: function(status) { - switch (status) { - case 400: - return 'Bad Request'; - case 401: - return 'Unauthorized'; - case 402: - return 'Payment Required'; - case 403: - return 'Forbidden'; - case 404: - return 'Not Found'; - case 405: - return 'Method Not Allowed'; - case 406: - return 'Not Acceptable'; - case 407: - return 'Proxy Authentication Required'; - case 408: - return 'Request Timeout'; - case 409: - return 'Conflict'; - case 410: - return 'Gone'; - case 411: - return 'Length Required'; - case 500: - return 'Internal Server Error'; - } - return 'Unknown Error'; - } -}; \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/assets/menus/Account.config b/SiteServer.Web/SiteServer/assets/menus/Account.config deleted file mode 100644 index fd1e11152..000000000 --- a/SiteServer.Web/SiteServer/assets/menus/Account.config +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/SiteServer.Web/SiteServer/assets/menus/Settings.config b/SiteServer.Web/SiteServer/assets/menus/Settings.config deleted file mode 100644 index 6dbb7d35d..000000000 --- a/SiteServer.Web/SiteServer/assets/menus/Settings.config +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SiteServer.Web/SiteServer/assets/menus/Site.config b/SiteServer.Web/SiteServer/assets/menus/Site.config deleted file mode 100644 index 5eb80add2..000000000 --- a/SiteServer.Web/SiteServer/assets/menus/Site.config +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SiteServer.Web/SiteServer/css/login.css b/SiteServer.Web/SiteServer/css/login.css deleted file mode 100644 index d6c17ba96..000000000 --- a/SiteServer.Web/SiteServer/css/login.css +++ /dev/null @@ -1,97 +0,0 @@ -@charset "utf-8"; -/* 全局样式 */ -body, ul, dl, dd, dt, ol, li, p, h1, h2, h3, h4, h5, h6, textarea, form, select, fieldset, table, td, div, input {margin:0;padding:0;-webkit-text-size-adjust: none} -h1, h2, h3, h4, h5, h6{font-size:12px;font-weight:normal} -body>div, form>div {margin:0 auto} -div {text-align:left} -a img {border:0} -table{border-collapse:collapse; border-spacing:0} -select,input,textarea{ font: 12px "Microsoft YaHei"; outline: none} -body { color:#333; text-align:center; font: 12px "Microsoft YaHei"} -ul, ol, li {list-style-type:none;vertical-align:0} -a {outline-style:none;color:#333;text-decoration:none} -a:hover { color: #CC0000; text-decoration: underline} -a, area {blr:expression(this.onFocus=this.blur())} -:focus {-moz-outline-style: none} -.clear {clear:both;height:0; overflow:hidden; visibility:hidden} -.hidden,.hide {display:none} -.block,.show {display:block} -.fl{float:left} -.fr{float:right} -.fline{float:left; display:inline} -.clearfix:after{clear:both;content:".";height:0;display:block;visibility:hidden} -.chgBtn{cursor:pointer} -.f12{font-size:12px} -.f12{font-size:13px} -.f14{font-size:14px} -.f12{font-size:15px} -.f16{font-size:16px} -.fwr{font-family:"微软雅黑"} -.far{font-family:Arial} -.fb{font-weight:bold} -.auto{margin-left:auto; margin-right:auto} -.cor_red{color:#C00} -.cor_bs,.cor_bs:hover{color:#fff} -.pr{position:relative} -.pa{position:absolute} -.mt10{margin-top:10px;} -.mb10{margin-bottom:10px;} -.yunBg { background: #C5C5C5 url(../pic/login/yunBg.jpg) no-repeat center top; } -.yunMain { width: 1003px; } -.yunTop { height: 88px; margin: 0px auto; width: 870px; } -.yunLogo { display: inline; margin: 30px 0px 0px 4px; float: left; } -.yunItmName { margin: 0px auto; height: 80px; width: 688px; padding-top: 26px; } -.yunItmName img { margin: 13px 13px 0px 0px; float: left; } -.yunItmS { font: 18px/58px "微软雅黑"; float: left; height: 58px; } -.yunBox { margin: 0px auto; height: 400px; width: 870px; } -.yun_u1 {margin-top: 30px;} -.yun_u1 ul li { line-height: 34px; height: 34px; margin-bottom: 25px; clear: both; } -.yun_s1 { font: 14px/34px "微软雅黑"; text-align: right; float: left; width: 196px; padding-right: 14px; } -.yun_int1 { line-height: 32px; padding: 0px 5px; height: 32px; width: 274px; border: 1px solid #BCBCBC; float: left; margin-right: 8px; } -.yun_int2 { width: 87px; margin-right: 12px; float: left; } -.yun_coder { float: left; margin-right: 10px; } -.yun_pwd { color: #999; } -.yun_cke { margin-right: 5px; position: relative; top: 2px; } -.yun_submit { background: url(../pic/login/yunsubmit.jpg) no-repeat; height: 36px; width: 101px; border-width: 0px; border-style: none; cursor: pointer; float: left; margin-right: 10px; } -.yun_org { font-weight: bold; color: #f78000; } -.yun_u1 ul .yun_hzbox { padding-left: 140px; } -.yun_hzbox img { margin-right: 5px; position: relative; top: 4px; } -.yunFooter { line-height: 24px; text-align: center; padding: 22px 0px 30px; border-top: 1px solid #AAAAAA; } -.yun_u1 ul .yun_alr1 { line-height: 48px; height: 48px; margin-bottom: 0px; padding-left: 210px; } -.yun_submit2 { background: url(../pic/login/yunsubmit2.jpg) no-repeat; height: 36px; width: 101px; border-width: 0px; border-style: none; cursor: pointer; float: left; margin-right: 10px; } -.yunItmName2 { width: 792px; } -.yunbxL { float: left; width: 600px; } -.yunbxR { width: 266px; float: right; } -.yunbxL .yun_s1 { width: 114px; padding-right: 6px; } -.yun_u1 ul .yun_agee { line-height: 20px; height: 20px; } -.yun_submit3 { background: url(../pic/login/yunregBtn.jpg) no-repeat; } -.yunbxr_top { line-height: 38px; height: 38px; } -.yun_alrbox { line-height: 26px; color: #D10000; background: #FFF3F3; white-space: nowrap; padding: 0px 6px; float: left; height: 26px; margin-top: 3px; border: 1px solid #FFE4E4; } -.yunbxr_dl dl dt { line-height: 40px; height: 40px; } -.yunbxr_dl dl dd { line-height: 30px; height: 30px; } -.yunbxr_dl dl dd img { position: relative; top: 3px; } -.yunTopBg { line-height: 30px; background: #707070; height: 30px; } -.yunTopCon { line-height: 30px; margin: 0px auto; height: 30px; width: 1210px; color: #FFF; text-align: right; } -.yunHeadBg { background: #FBFBFB; height: 90px; } -.yunHead { margin: 0px auto; height: 90px; width: 1210px; position: relative; } -.yun_logo2 { float: left; margin-top: 25px; } -.yun_headImg { position: absolute; left: 372px; top: 20px; } -.yunHeadR { float: right; padding-top: 21px; width: 374px; } -.yunserBox { background: url(../pic/login/yun_serintBg.jpg); height: 38px; padding-left: 9px; width: 365px; } -.yun_serInt { line-height: 28px; float: left; height: 28px; border-width: 0px; border-style: none; width: 310px; margin-top: 5px; } -.yun_serSubmit { margin: 2px 2px 0px 0px; float: right; height: 34px; width: 30px; border-width: 0px; border-style: none; cursor: pointer; background: url(../pic/login/yun_serBtn.jpg) no-repeat; } -.yun_keyword { line-height: 22px; height: 22px; padding-left: 12px; } -.yunFtLink { height: 62px; padding-top: 31px; border-top: 5px solid #E4E4E4; border-bottom: 1px solid #E4E4E4; } -.yunFtitm { margin: 0px auto; width: 1210px; } -.yunFtitm ul li { float: left; height: 28px; width: 270px; padding-left: 32px; font: 18px/28px "微软雅黑"; overflow: hidden; } -.yunFtitm ul li img { float: left; margin-right: 20px; } -.yunFotDl { height: 162px; width: 1210px; padding-top: 24px; } -.yunFotDl dl { float: left; height: 162px; width: 155px; padding-left: 66px; border-right: 1px dotted #E6E6E6; } -.yunFotDl dl dt { display: block; height: 25px; margin-bottom: 5px; font: 18px/25px "微软雅黑"; } -.yunFotDl dl dd { line-height: 22px; background: url(../pic/login/yun_1.jpg) no-repeat left center; height: 22px; padding-left: 10px; } -.yunFotDl .yun_ftvx { width: 300px; padding-left: 0px; } -.yunFotDl .yun_ftvx dt { text-align: center; } -.yunFotDl .yun_lastDl { border-right-width: 0px; border-right-style: none; } -.yunFotCenter { text-align: center; padding: 20px 0px 25px; } -.yunFtinfo { color: #9c9c9c; line-height: 24px; text-align: center; padding-bottom: 15px; } -.checkbox label { margin-left: 5px; } diff --git a/SiteServer.Web/SiteServer/default.aspx b/SiteServer.Web/SiteServer/default.aspx deleted file mode 100644 index 25f0f068b..000000000 --- a/SiteServer.Web/SiteServer/default.aspx +++ /dev/null @@ -1,15 +0,0 @@ -<%@ Page Language="C#" %> - - - - - - - <%Page.Response.Redirect("pageInitialization.aspx", false);%> - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/findPwd.aspx b/SiteServer.Web/SiteServer/findPwd.aspx deleted file mode 100644 index a24de591c..000000000 --- a/SiteServer.Web/SiteServer/findPwd.aspx +++ /dev/null @@ -1,128 +0,0 @@ -<%@ Page Language="c#" Inherits="SiteServer.BackgroundPages.PageFindPwd" %> - - - - - - 找回密码 - - - - - - - -
    -
    -
    - -
    -
    - - - - -
    -
    -
    - -
    -
    - -
      -
    • - 账号: - - - 请输入注册的手机号/邮箱/用户名 -
    • -
    • - 验证码: - - - -
    • -
    • -   - -
    • -
    • -   -   - 返回登录 -
    • -
    -
    - -
      -
    • - 短信验证码: - - -
    • -
    • -   - -
    • -
    • -   -   - 返回登录 -
    • -
    -
    - -
      -
    • - 新密码: - - - -
    • -
    • - 确认新密码: - - - -
    • -
    • -   - -
    • -
    • -   -   - 返回登录 -
    • -
    -
    -
    -
    -
    北京百容千域软件技术开发有限公司 版权所有 Copyright © 2003- - -
    -
    -
    - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/index.aspx b/SiteServer.Web/SiteServer/index.aspx deleted file mode 100644 index 25f0f068b..000000000 --- a/SiteServer.Web/SiteServer/index.aspx +++ /dev/null @@ -1,15 +0,0 @@ -<%@ Page Language="C#" %> - - - - - - - <%Page.Response.Redirect("pageInitialization.aspx", false);%> - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/loading.aspx b/SiteServer.Web/SiteServer/loading.aspx deleted file mode 100644 index 229442e44..000000000 --- a/SiteServer.Web/SiteServer/loading.aspx +++ /dev/null @@ -1,46 +0,0 @@ -<%@ Page Language="c#" Inherits="SiteServer.BackgroundPages.PageLoading" Trace="False" %> - - - - - - SiteServer 管理后台 - - - - - - - - - - - - - - -
    -
    - -

    载入中,请稍后...

    -
    -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/login.aspx b/SiteServer.Web/SiteServer/login.aspx deleted file mode 100644 index 8d9b71445..000000000 --- a/SiteServer.Web/SiteServer/login.aspx +++ /dev/null @@ -1,89 +0,0 @@ -<%@ Page Language="c#" Inherits="SiteServer.BackgroundPages.PageLogin" %> - - - - - - 管理员登录 - - - - - - - - -
    -
    -
    - -
    -
    - - 管理员登录 -
    -
    -
    - -
    -
    -
      -
    • - 账号: - - - 请输入注册的手机号/邮箱/用户名 -
    • -
    • - 密码: - - - - -
    • -
    • - 验证码: - - - -
    • -
    • -   - -
    • -
    • -   - - -   - 找回密码? - -
    • -
    -
    -
    -
    北京百容千域软件技术开发有限公司 版权所有 Copyright © 2003- - -
    -
    -
    - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/logout.aspx b/SiteServer.Web/SiteServer/logout.aspx deleted file mode 100644 index ee93b0cbe..000000000 --- a/SiteServer.Web/SiteServer/logout.aspx +++ /dev/null @@ -1 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.PageLogout"%> \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/pageError.html b/SiteServer.Web/SiteServer/pageError.html deleted file mode 100644 index b4df33c98..000000000 --- a/SiteServer.Web/SiteServer/pageError.html +++ /dev/null @@ -1,92 +0,0 @@ - - - - - - SiteServer 管理后台 - - - - - - - - - - - - - - -
    - -
    - -

    载入中,请稍后...

    -
    - - - -
    - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/pageInitialization.aspx b/SiteServer.Web/SiteServer/pageInitialization.aspx deleted file mode 100644 index 371683547..000000000 --- a/SiteServer.Web/SiteServer/pageInitialization.aspx +++ /dev/null @@ -1,46 +0,0 @@ -<%@ Page Language="c#" Inherits="SiteServer.BackgroundPages.PageInitialization" Trace="False" %> - - - - - - SiteServer 管理后台 - - - - - - - - - - - - - - - - -
    -
    - -

    载入中,请稍后...

    -
    -
    - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/pageMain.aspx b/SiteServer.Web/SiteServer/pageMain.aspx deleted file mode 100644 index 159b698d5..000000000 --- a/SiteServer.Web/SiteServer/pageMain.aspx +++ /dev/null @@ -1,301 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.PageMain" Trace="False" EnableViewState="false" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - SiteServer 管理后台 - - - - - - - - - - - - -
    -
    -
    - - - - - - - - -
    -
    -
    - -
    - -
    - -
    - -
    -
    - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/pageRedirect.aspx b/SiteServer.Web/SiteServer/pageRedirect.aspx deleted file mode 100644 index 62ac94199..000000000 --- a/SiteServer.Web/SiteServer/pageRedirect.aspx +++ /dev/null @@ -1 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.PageRedirect" Trace="False" enableViewState = "false"%> \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/pageRight.aspx b/SiteServer.Web/SiteServer/pageRight.aspx deleted file mode 100644 index 7036cc9d1..000000000 --- a/SiteServer.Web/SiteServer/pageRight.aspx +++ /dev/null @@ -1,111 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.PageRight" %> - - - - - - SiteServer 管理后台 - - - - - - - - - - - - - -
    - -
    -
    -

    - 欢迎使用 SiteServer 管理后台 -

    -
    -
    - -
    -
    - -
      -
    • -
      当前版本
      -

      - -

      -
    • -
    • -
      最近升级时间
      -

      - -

      -
    • -
    • -
      上次登录时间
      -

      - -

      -
    • -
    -
    -
    - - - -
    - - - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/pageSyncDatabase.aspx b/SiteServer.Web/SiteServer/pageSyncDatabase.aspx deleted file mode 100644 index 169319086..000000000 --- a/SiteServer.Web/SiteServer/pageSyncDatabase.aspx +++ /dev/null @@ -1,146 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.PageSyncDatabase" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - SiteServer CMS 数据库升级向导 - - - - - - - - - - - - - -
    - -
    -

    - SiteServer CMS 数据库升级向导 -

    -

    - 欢迎来到SiteServer CMS 数据库升级向导! -

    - - - - -
    - - - -
    -

    欢迎来到SiteServer CMS 数据库升级向导!

    -

    - 升级向导将逐一检查数据库字段、将数据库结构更新至最新版本。 -

    -
    - -
    - -
    - -
    - -
    - - - - - - - -
    - -
    - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/pageUpdateSystem.aspx b/SiteServer.Web/SiteServer/pageUpdateSystem.aspx deleted file mode 100644 index 71aa77590..000000000 --- a/SiteServer.Web/SiteServer/pageUpdateSystem.aspx +++ /dev/null @@ -1,270 +0,0 @@ -<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.PageUpdateSystem" %> - <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> - - - - - - SiteServer CMS 升级向导 - - - - - - - - - - - - - - - - - -
    - -
    -

    - SiteServer CMS 升级向导 -

    -

    - 欢迎来到SiteServer CMS 升级向导! -

    - - - - - - - - -
    - -
    -
    -

    检查更新

    -

    检查 SiteServer CMS 新版本

    -
    -
    - -
    - -
    -
    -

    正在检查系统更新,请稍后...

    -
    - - - - -
    -
    - -
    - - -
    - -
    - -
    -
    -

    正在升级系统,可能需要几分钟,请稍后...

    -
    - -
    - - -
    - - - -
    - -
    - -
    - - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/pageValidateCode.aspx b/SiteServer.Web/SiteServer/pageValidateCode.aspx deleted file mode 100644 index 30daadd5e..000000000 --- a/SiteServer.Web/SiteServer/pageValidateCode.aspx +++ /dev/null @@ -1 +0,0 @@ -<%@ Page language="c#" trace="false" Inherits="SiteServer.BackgroundPages.PageValidateCode" %> \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/web.config b/SiteServer.Web/SiteServer/web.config deleted file mode 100644 index bbce1d999..000000000 --- a/SiteServer.Web/SiteServer/web.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/Startup.cs b/SiteServer.Web/Startup.cs deleted file mode 100644 index 4965c86af..000000000 --- a/SiteServer.Web/Startup.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System.Web.Hosting; -using System.Web.Http; -using System.Web.Http.Cors; -using System.Web.Routing; -using Microsoft.Owin; -using Newtonsoft.Json; -using Newtonsoft.Json.Converters; -using Newtonsoft.Json.Serialization; -using Owin; -using SiteServer.API; -using SiteServer.CMS.Plugin; -using SiteServer.Utils; - -[assembly: OwinStartup(typeof(Startup))] - -namespace SiteServer.API -{ - public class Startup - { - public void Configuration(IAppBuilder app) - { - app.MapSignalR(); - - var config = GlobalConfiguration.Configuration; - - var corsAttr = new EnableCorsAttribute("*", "*", "*") - { - SupportsCredentials = true - }; - config.EnableCors(corsAttr); - config.MapHttpAttributeRoutes(); - - config.Routes.MapHttpRoute( - "DefaultApi", - "api/{controller}/{id}", - new { id = RouteParameter.Optional } - ); - - //config.Routes.Add("name", new HttpRoute()); - - RouteTable.Routes.Ignore(""); //Allow index.html to load - - var jsonFormatter = config.Formatters.JsonFormatter; - var settings = new JsonSerializerSettings - { - ContractResolver = new CamelCasePropertyNamesContractResolver() - }; - var timeFormat = new IsoDateTimeConverter - { - DateTimeFormat = "yyyy-MM-dd HH:mm:ss" - }; - settings.Converters.Add(timeFormat); - jsonFormatter.SerializerSettings = settings; - jsonFormatter.Indent = true; - - config.EnsureInitialized(); - - WebConfigUtils.Load(HostingEnvironment.ApplicationPhysicalPath); - var c = PluginManager.PluginInfoListRunnable; - } - } -} \ No newline at end of file diff --git a/SiteServer.Web/Web.Release.config b/SiteServer.Web/Web.Release.config deleted file mode 100644 index 89052d8fe..000000000 --- a/SiteServer.Web/Web.Release.config +++ /dev/null @@ -1,76 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/SiteServer.Web/Web.config b/SiteServer.Web/Web.config deleted file mode 100644 index 1f0936c26..000000000 --- a/SiteServer.Web/Web.config +++ /dev/null @@ -1,85 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/SiteServer.Web/packages.config b/SiteServer.Web/packages.config deleted file mode 100644 index a8159c8c2..000000000 --- a/SiteServer.Web/packages.config +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git "a/SiteServer.Web/\345\256\211\350\243\205\345\220\221\345\257\274.html" "b/SiteServer.Web/\345\256\211\350\243\205\345\220\221\345\257\274.html" deleted file mode 100644 index c69755c14..000000000 --- "a/SiteServer.Web/\345\256\211\350\243\205\345\220\221\345\257\274.html" +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/appveyor.yml b/appveyor.yml index 3f020b0bf..0d929859e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,10 +1,9 @@ # configuration for "master" branch -- - branches: +- branches: only: - master - version: 6.1.{build} + version: 6.8.{build} image: Visual Studio 2017 assembly_info: @@ -30,17 +29,17 @@ cache: - packages -> **\packages.config - - node_modules # local npm modules + - node_modules # local npm modules before_build: - - nuget restore siteserver.sln + - nuget restore siteserver-all.sln build: - project: siteserver.sln # path to Visual Studio solution or project + project: siteserver-all.sln # path to Visual Studio solution or project publish_nuget: true after_build: - - gulp release + - gulp build - nuget pack build/SS.CMS.nuspec - gulp zip @@ -48,27 +47,27 @@ - path: siteserver_install.zip name: siteserver_install - - path: '*.nupkg' + - path: siteserver.exe + name: siteserver.exe + + - path: "*.nupkg" deploy: - provider: GitHub release: siteserver-v$(appveyor_build_version) - description: 'SiteServer CMS' + description: "SiteServer CMS" auth_token: secure: B/TFrPxGyyTS/NKTQsf/GBLPfGI+Rz/j3e7FVLaP6yjeUDljwkfvV70C+CT34/10 - artifact: /.*\.zip/ + artifact: /.*\.[zip|exe]/ draft: false prerelease: false - on: - branch: master - appveyor_repo_tag: false - provider: NuGet - server: # remove to push to NuGet.org + server: # remove to push to NuGet.org api_key: - secure: cKpWZvlfFA7EfagAXc/mZfTGHXxfoKNOYTQd6v4ImalbNV1mtNR55M2HMJJ4jCAo + secure: B9umZPwBVx2TMfYt7G1Eppy7XX0FkqWioXxwR+lKv5XVRc6ezjOXP8D9iuisOWBF skip_symbols: false - symbol_server: # remove to push symbols to SymbolSource.org + symbol_server: # remove to push symbols to SymbolSource.org artifact: /.*\.nupkg/ notifications: @@ -76,13 +75,12 @@ on_build_success: true on_build_failure: true -# configuration for "dev" branch -- - branches: +# configuration for "staging" branch +- branches: only: - - dev + - staging - version: 6.1.{build} + version: 6.8.{build}-beta image: Visual Studio 2017 assembly_info: @@ -90,7 +88,7 @@ file: '**\AssemblyInfo.cs' assembly_version: "{version}" assembly_file_version: "{version}" - assembly_informational_version: "{version}-beta" + assembly_informational_version: "{version}" configuration: - Release @@ -98,58 +96,66 @@ environment: nodejs_version: "6" TreatWarningsAsErrors: false + DOCKER_USER: + secure: plV6NmiOZal0f3H/xNFuoA== + DOCKER_PASS: + secure: AzfvhYL4heX1Acqv5C3Oug== install: - ps: Install-Product node $env:nodejs_version - npm install gulp -g - npm install + - docker version skip_tags: true cache: - packages -> **\packages.config - - node_modules # local npm modules + - node_modules # local npm modules before_build: - - nuget restore siteserver.sln + - nuget restore siteserver-all.sln build: - project: siteserver.sln # path to Visual Studio solution or project + project: siteserver-all.sln # path to Visual Studio solution or project publish_nuget: true after_build: - - gulp preview + - gulp build - nuget pack build/SS.CMS.nuspec - gulp zip + # - docker build -t siteserver/cms:latest -t siteserver/cms:v%appveyor_build_version% . + # - docker login -u="%DOCKER_USER%" -p="%DOCKER_PASS%" + # - docker push siteserver/cms artifacts: - path: siteserver_install.zip name: siteserver_install - - path: '*.nupkg' + - path: siteserver.exe + name: siteserver.exe + + - path: "*.nupkg" deploy: - provider: GitHub - release: siteserver-v$(appveyor_build_version)-preview - description: 'SiteServer CMS' + release: siteserver-v$(appveyor_build_version) + description: "SiteServer CMS" auth_token: secure: B/TFrPxGyyTS/NKTQsf/GBLPfGI+Rz/j3e7FVLaP6yjeUDljwkfvV70C+CT34/10 - artifact: /.*\.zip/ + artifact: /.*\.[zip|exe]/ draft: false - prerelease: false - on: - branch: dev - appveyor_repo_tag: false + prerelease: true - provider: NuGet - server: https://www.myget.org/F/siteserver/api/v2/package # remove to push to NuGet.org + server: # remove to push to NuGet.org api_key: - secure: i9vISdFyCeWbRUQw+jhcF748i4oWdeatGBrx+dJ07SDTpt7Hsk9YCRp/ha3ZXfZF + secure: B9umZPwBVx2TMfYt7G1Eppy7XX0FkqWioXxwR+lKv5XVRc6ezjOXP8D9iuisOWBF skip_symbols: false - symbol_server: # remove to push symbols to SymbolSource.org + symbol_server: # remove to push symbols to SymbolSource.org artifact: /.*\.nupkg/ notifications: - provider: GitHubPullRequest on_build_success: true - on_build_failure: true \ No newline at end of file + on_build_failure: true diff --git a/azure-pipelines.yml b/azure-pipelines.yml new file mode 100644 index 000000000..f6dd7b4b5 --- /dev/null +++ b/azure-pipelines.yml @@ -0,0 +1,46 @@ +# ASP.NET +# Build and test ASP.NET projects. +# Add steps that publish symbols, save build artifacts, deploy, and more: +# https://docs.microsoft.com/azure/devops/pipelines/apps/aspnet/build-aspnet-4 + +trigger: +- dev + +pool: + vmImage: 'VS2017-Win2016' + +variables: + solution: '**/*.sln' + buildPlatform: 'Any CPU' + buildConfiguration: 'Release' + +steps: +- task: NuGetToolInstaller@0 + +- task: NuGetCommand@2 + inputs: + restoreSolution: '$(solution)' + +- task: VSBuild@1 + inputs: + solution: '$(solution)' + msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)"' + platform: '$(buildPlatform)' + configuration: '$(buildConfiguration)' + +# Visual Studio Test Platform Installer +# Acquires the test platform from nuget.org or the tools cache. Satisfies the ‘vstest’ demand and can be used for running tests and collecting diagnostic data using the Visual Studio Test task. +- task: VisualStudioTestPlatformInstaller@1 + inputs: + packageFeedSelector: 'nugetOrg' # Options: nugetOrg, customFeed, netShare + versionSelector: 'latestPreRelease' # Required when packageFeedSelector == NugetOrg || PackageFeedSelector == CustomFeed# Options: latestPreRelease, latestStable, specificVersion + #testPlatformVersion: # Required when versionSelector == SpecificVersion + #customFeed: # Required when packageFeedSelector == CustomFeed + #username: # Optional + #password: # Optional + #netShare: # Required when packageFeedSelector == NetShare + +- task: VSTest@2 + inputs: + platform: '$(buildPlatform)' + configuration: '$(buildConfiguration)' diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index 62c9a86d0..000000000 --- a/gulpfile.js +++ /dev/null @@ -1,152 +0,0 @@ -var fs = require("fs"); -var path = require("path"); -var gulp = require("gulp"); -var minify = require("gulp-minifier"); -var rimraf = require("rimraf"); -var rename = require("gulp-rename"); -var replace = require("gulp-replace"); -var zip = require("gulp-zip"); -var filter = require("gulp-filter"); -var runSequence = require("run-sequence"); - -var version = process.env.APPVEYOR_BUILD_VERSION || '0.0.0'; - -function getDependencies() { - var str = ""; - - var dirs = fs.readdirSync("./packages").filter(function(file) { - return fs.statSync("./packages/" + file).isDirectory(); - }); - for (var dir of dirs) { - var items = dir.split("."); - var index = 0; - for (var i = 0; i < items.length; i++) { - var isNumber = !isNaN(parseFloat(items[i])) && isFinite(items[i]); - if (isNumber) { - index = i; - break; - } - } - var id = items.slice(0, index).join("."); - var version = items.slice(index).join("."); - str += ''; - } - str = "" + str + ""; - return str; -} - -gulp.task("build-nuspec", function() { - var dependencies = getDependencies(); - return gulp - .src("./SS.CMS.nuspec") - .pipe(replace("$version$", version)) - .pipe(replace("", dependencies + "")) - .pipe(gulp.dest("./build")); -}); - -gulp.task("build-bin", function() { - return gulp - .src(["./SiteServer.Web/bin/*.dll"]) - .pipe(gulp.dest("./build/bin")); -}); - -gulp.task("build-sitefiles-all", function() { - return gulp - .src("./SiteServer.Web/SiteFiles/assets/**/*") - .pipe(gulp.dest("./build/SiteFiles/assets")); -}); - -gulp.task("build-sitefiles-min", function() { - return gulp - .src(["./SiteServer.Web/SiteFiles/assets/**/*.js", "./SiteServer.Web/SiteFiles/assets/**/*.css"]) - .pipe( - minify({ - minify: true, - collapseWhitespace: true, - conservativeCollapse: true, - minifyJS: true, - minifyCSS: true, - minifyHTML: false, - ignoreFiles: ['.min.css', '.min.js'] - }) - ) - .pipe(gulp.dest("./build/SiteFiles/assets")); -}); - -gulp.task("build-siteserver-all", function() { - return gulp.src("./SiteServer.Web/SiteServer/**/*").pipe(gulp.dest("./build/SiteServer")); -}); - -gulp.task("build-siteserver-aspx", function() { - return gulp - .src("./SiteServer.Web/SiteServer/**/*.aspx") - .pipe(replace('.css"', ".css?v=" + version + '"')) - .pipe(replace('.js"', ".js?v=" + version + '"')) - .pipe(gulp.dest("./build/SiteServer")); -}); - -gulp.task("build-siteserver-min", function() { - return gulp - .src(["./SiteServer.Web/SiteServer/**/*.js", "./SiteServer.Web/SiteServer/**/*.css"]) - .pipe( - minify({ - minify: true, - collapseWhitespace: true, - conservativeCollapse: true, - minifyJS: true, - minifyCSS: true, - minifyHTML: true, - ignoreFiles: ['.min.css', '.min.js'] - }) - ) - .pipe(gulp.dest("./build/SiteServer")); -}); - -gulp.task("build-docs", function() { - return gulp.src("./SiteServer.Web/安装向导.html").pipe(gulp.dest("./build")); -}); - -gulp.task("build-webconfig", function() { - return gulp - .src("./SiteServer.Web/Web.Release.config") - .pipe(rename("Web.config")) - .pipe(gulp.dest("./build")); -}); - -gulp.task("release", function(callback) { - console.log("build version: " + version); - runSequence( - "build-docs", - "build-webconfig", - "build-nuspec", - "build-bin", - "build-sitefiles-all", - "build-sitefiles-min", - "build-siteserver-all", - "build-siteserver-aspx", - "build-siteserver-min" - ); -}); - -gulp.task("preview", function(callback) { - version += "-beta"; - console.log("build version: " + version); - runSequence( - "build-docs", - "build-webconfig", - "build-nuspec", - "build-bin", - "build-sitefiles-all", - "build-sitefiles-min", - "build-siteserver-all", - "build-siteserver-aspx", - "build-siteserver-min" - ); -}); - -gulp.task("zip", function(callback) { - gulp - .src(["./build/**/*", "!./build/SS.CMS.nuspec"]) - .pipe(zip("siteserver_install.zip")) - .pipe(gulp.dest("./")); -}); diff --git a/net452/Dockerfile b/net452/Dockerfile new file mode 100644 index 000000000..be268e40c --- /dev/null +++ b/net452/Dockerfile @@ -0,0 +1,11 @@ +FROM microsoft/aspnet:4.7 + +RUN powershell -NoProfile -Command Remove-Item -Recurse C:\inetpub\wwwroot\* + +WORKDIR /inetpub/wwwroot + +COPY Dockerfile.ps1 . + +RUN powershell -executionpolicy bypass .\Dockerfile.ps1 + +COPY build/ . \ No newline at end of file diff --git a/net452/Dockerfile.ps1 b/net452/Dockerfile.ps1 new file mode 100644 index 000000000..12f803afb --- /dev/null +++ b/net452/Dockerfile.ps1 @@ -0,0 +1,8 @@ +$Acl = Get-Acl . +$Ar1 = New-Object System.Security.AccessControl.FileSystemAccessRule("NETWORK SERVICE", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow") +$Acl.SetAccessRule($Ar1) +$Ar2 = New-Object System.Security.AccessControl.FileSystemAccessRule("IIS_IUSRS", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow") +$Acl.SetAccessRule($Ar2) +$Ar3 = New-Object System.Security.AccessControl.FileSystemAccessRule("IUSR", "FullControl", "ContainerInherit,ObjectInherit", "None", "Allow") +$Acl.SetAccessRule($Ar3) +Set-Acl . $Acl \ No newline at end of file diff --git a/net452/SiteServer.API.Tests/EnvironmentFixture.cs b/net452/SiteServer.API.Tests/EnvironmentFixture.cs new file mode 100644 index 000000000..efb3ac663 --- /dev/null +++ b/net452/SiteServer.API.Tests/EnvironmentFixture.cs @@ -0,0 +1,28 @@ +using System; +using System.IO; +using System.Reflection; +using SiteServer.CMS.Fx; +using SiteServer.Utils; + +namespace SiteServer.API.Tests +{ + public class EnvironmentFixture : IDisposable + { + public string ApplicationPhysicalPath { get; } + + public EnvironmentFixture() + { + var codeBaseUrl = new Uri(Assembly.GetExecutingAssembly().CodeBase); + var codeBasePath = Uri.UnescapeDataString(codeBaseUrl.AbsolutePath); + var dirPath = Path.GetDirectoryName(codeBasePath); + ApplicationPhysicalPath = PathUtils.Combine(DirectoryUtils.GetParentPath(DirectoryUtils.GetParentPath(DirectoryUtils.GetParentPath(dirPath))), "SiteServer.Web"); + + WebConfigUtils.Load(ApplicationPhysicalPath, PathUtils.Combine(ApplicationPhysicalPath, WebConfigUtils.WebConfigFileName)); + } + + public void Dispose() + { + // ... clean up test data from the database ... + } + } +} diff --git a/net452/SiteServer.API.Tests/Pages/Settings/TestPagesAdministratorsController.cs b/net452/SiteServer.API.Tests/Pages/Settings/TestPagesAdministratorsController.cs new file mode 100644 index 000000000..473b2804c --- /dev/null +++ b/net452/SiteServer.API.Tests/Pages/Settings/TestPagesAdministratorsController.cs @@ -0,0 +1,42 @@ +using SiteServer.API.Controllers.Pages.Settings; +using SiteServer.API.Tests.Utils; +using SiteServer.Utils; +using Xunit; +using Xunit.Abstractions; + +namespace SiteServer.API.Tests.Pages.Settings +{ + public class TestPagesAdministratorsController : IClassFixture + { + public EnvironmentFixture Fixture { get; } + private readonly ITestOutputHelper _output; + + public TestPagesAdministratorsController(EnvironmentFixture fixture, ITestOutputHelper output) + { + Fixture = fixture; + _output = output; + } + + [SkippableFact] + public void GetList_ShouldReturnOkResult() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var adminInfo = AdminUtils.CreateSuperAdminIfNotExists(); + var accessToken = AdminUtils.GetAccessToken(adminInfo); + var controller = ControllerUtils.NewAdminController(accessToken); + + dynamic results = controller.GetList(); + var res = results.Content; + + Assert.NotNull(res); + Assert.NotNull(res.Value); + Assert.NotNull(res.Count); + Assert.NotNull(res.Pages); + Assert.NotNull(res.Roles); + Assert.NotNull(res.Departments); + Assert.NotNull(res.Areas); + _output.WriteLine(TranslateUtils.JsonSerialize(res)); + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.API.Tests/Properties/AssemblyInfo.cs b/net452/SiteServer.API.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..355738604 --- /dev/null +++ b/net452/SiteServer.API.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,19 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("SiteServer.API.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SiteServer.API.Tests")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +[assembly: Guid("5597bc9b-1e09-4ee4-9ea4-ac71cea645f3")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/net452/SiteServer.API.Tests/SiteServer.API.Tests.csproj b/net452/SiteServer.API.Tests/SiteServer.API.Tests.csproj new file mode 100644 index 000000000..8ae338e38 --- /dev/null +++ b/net452/SiteServer.API.Tests/SiteServer.API.Tests.csproj @@ -0,0 +1,187 @@ + + + + + + + + Debug + AnyCPU + {5597BC9B-1E09-4EE4-9EA4-AC71CEA645F3} + Library + Properties + SiteServer.API.Tests + SiteServer.API.Tests + v4.6.1 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\packages\Dapper.1.60.6\lib\net451\Dapper.dll + + + ..\..\packages\Datory.0.1.7\lib\net452\Datory.dll + + + ..\..\packages\Google.Protobuf.3.5.1\lib\net45\Google.Protobuf.dll + + + + ..\..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + ..\..\packages\MySql.Data.8.0.15\lib\net452\MySql.Data.dll + + + ..\..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll + + + ..\..\packages\Npgsql.4.0.5\lib\net451\Npgsql.dll + + + ..\..\packages\Oracle.ManagedDataAccess.18.6.0\lib\net40\Oracle.ManagedDataAccess.dll + + + ..\..\packages\SqlKata.1.1.7\lib\net45\QueryBuilder.dll + + + ..\..\packages\SiteServer.Plugin.2.2.14-beta\lib\net452\SiteServer.Plugin.dll + + + + ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll + + + + + + + + + + + + + ..\..\packages\System.Memory.4.5.2\lib\netstandard2.0\System.Memory.dll + + + + ..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll + + + + ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + + + + ..\..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll + + + ..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.7\lib\net45\System.Web.Http.dll + + + + + ..\..\packages\Validation.2.4.18\lib\net45\Validation.dll + + + ..\..\packages\xunit.abstractions.2.0.3\lib\net35\xunit.abstractions.dll + + + ..\..\packages\xunit.assert.2.4.1\lib\netstandard1.1\xunit.assert.dll + + + ..\..\packages\xunit.extensibility.core.2.4.1\lib\net452\xunit.core.dll + + + ..\..\packages\xunit.extensibility.execution.2.4.1\lib\net452\xunit.execution.desktop.dll + + + ..\..\packages\Xunit.SkippableFact.1.3.12\lib\net452\Xunit.SkippableFact.dll + + + + + + + + + + + + + + + + + + + + + + {059e3927-37e1-4f6f-b525-fef40c54906b} + SiteServer.Utils + + + {6aa1713a-3b77-4b20-b8c7-fcb6de556f64} + SiteServer.BackgroundPages + + + {944127c3-915d-4f02-a534-64ec668c46ec} + SiteServer.CMS + + + {69c00f60-f28a-4cbc-b1a4-2db73bb97471} + SiteServer.API + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.API.Tests/TestTestController.cs b/net452/SiteServer.API.Tests/TestTestController.cs new file mode 100644 index 000000000..2eb6ddad6 --- /dev/null +++ b/net452/SiteServer.API.Tests/TestTestController.cs @@ -0,0 +1,87 @@ +using System.Web.Http.Results; +using SiteServer.API.Controllers; +using SiteServer.API.Tests.Utils; +using SiteServer.Utils; +using Xunit; +using Xunit.Abstractions; + +namespace SiteServer.API.Tests +{ + public class TestTestController : IClassFixture + { + public EnvironmentFixture Fixture { get; } + private readonly ITestOutputHelper _output; + + public TestTestController(EnvironmentFixture fixture, ITestOutputHelper output) + { + Fixture = fixture; + _output = output; + } + + [SkippableFact] + public void GetAdminOnly_ShouldReturnUnauthorizedResult() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var controller = ControllerUtils.NewAnonymousController(); + var actionResult = controller.GetAdminOnly(); + + Assert.IsType(actionResult); + + var adminInfo = AdminUtils.CreateAdminIfNotExists(); + var accessToken = AdminUtils.GetAccessToken(adminInfo); + controller = ControllerUtils.NewAdminController(accessToken); + + actionResult = controller.GetAdminOnly(); + Assert.IsType(actionResult); + } + + [SkippableFact] + public void GetAdminOnly_ShouldReturnOkResult() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var adminInfo = AdminUtils.CreateSuperAdminIfNotExists(); + var accessToken = AdminUtils.GetAccessToken(adminInfo); + var controller = ControllerUtils.NewAdminController(accessToken); + + dynamic results = controller.GetAdminOnly(); + var content = results.Content; + + Assert.NotNull(content); + + _output.WriteLine(TranslateUtils.JsonSerialize(content)); + } + + //[Fact] + //public void Get_ShouldReturnList() + //{ + // var controller = new TestController + // { + // Request = new HttpRequestMessage(), + // Configuration = new HttpConfiguration() + // }; + + // dynamic results = controller.Get(); + // var content = results.Content; + + // Assert.NotNull(content); + + // _output.WriteLine(TranslateUtils.JsonSerialize(content)); + //} + + //[Fact] + //public void GetString_ShouldReturnHello() + //{ + // var controller = new TestController + // { + // Request = new HttpRequestMessage(), + // Configuration = new HttpConfiguration() + // }; + + // var response = controller.GetString() as OkNegotiatedContentResult; + // Assert.NotNull(response); + // Assert.Equal("Hello", response.Content); + //} + } +} \ No newline at end of file diff --git a/net452/SiteServer.API.Tests/Utils/AdminUtils.cs b/net452/SiteServer.API.Tests/Utils/AdminUtils.cs new file mode 100644 index 000000000..d94095b50 --- /dev/null +++ b/net452/SiteServer.API.Tests/Utils/AdminUtils.cs @@ -0,0 +1,54 @@ +using System; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.API.Tests.Utils +{ + public static class AdminUtils + { + public static AdministratorInfo CreateAdminIfNotExists() + { + var adminInfo = AdminManager.GetAdminInfoByUserName(nameof(CreateAdminIfNotExists)); + if (adminInfo != null) return adminInfo; + + adminInfo = new AdministratorInfo + { + UserName = nameof(CreateAdminIfNotExists), + Password = Guid.NewGuid().ToString() + }; + DataProvider.Administrator.Insert(adminInfo, out _); + + DataProvider.AdministratorsInRoles.AddUserToRole(adminInfo.UserName, EPredefinedRoleUtils.GetValue(EPredefinedRole.Administrator)); + + return adminInfo; + } + + public static AdministratorInfo CreateSuperAdminIfNotExists() + { + var adminInfo = AdminManager.GetAdminInfoByUserName(nameof(CreateSuperAdminIfNotExists)); + if (adminInfo != null) return adminInfo; + + adminInfo = new AdministratorInfo + { + UserName = nameof(CreateSuperAdminIfNotExists), + Password = Guid.NewGuid().ToString() + }; + DataProvider.Administrator.Insert(adminInfo, out _); + + DataProvider.AdministratorsInRoles.AddUserToRole(adminInfo.UserName, EPredefinedRoleUtils.GetValue(EPredefinedRole.ConsoleAdministrator)); + + return adminInfo; + } + + public static string GetAccessToken(AdministratorInfo adminInfo) + { + var expiresAt = TimeSpan.FromDays(7); + return AdminApi.Instance.GetAccessToken(adminInfo.Id, adminInfo.UserName, expiresAt); + } + } +} diff --git a/net452/SiteServer.API.Tests/Utils/ControllerUtils.cs b/net452/SiteServer.API.Tests/Utils/ControllerUtils.cs new file mode 100644 index 000000000..87aa46683 --- /dev/null +++ b/net452/SiteServer.API.Tests/Utils/ControllerUtils.cs @@ -0,0 +1,34 @@ +using System.Net.Http; +using System.Web.Http; +using System.Web.Http.Controllers; +using SiteServer.Utils; + +namespace SiteServer.API.Tests.Utils +{ + public static class ControllerUtils + { + public static T NewAnonymousController() where T : ApiController, new() + { + var controller = new T + { + Request = new HttpRequestMessage(), + Configuration = new HttpConfiguration() + }; + return controller; + } + + public static T NewAdminController(string accessToken) where T : ApiController, new() + { + var controller = new T(); + var controllerContext = new HttpControllerContext(); + var request = new HttpRequestMessage(); + request.Headers.Add(Constants.AuthKeyAdminHeader, accessToken); + + // Don't forget these lines, if you do then the request will be null. + controllerContext.Request = request; + controller.ControllerContext = controllerContext; + + return controller; + } + } +} diff --git a/net452/SiteServer.API.Tests/V1/TestV1AdministratorsController.cs b/net452/SiteServer.API.Tests/V1/TestV1AdministratorsController.cs new file mode 100644 index 000000000..a0bb14276 --- /dev/null +++ b/net452/SiteServer.API.Tests/V1/TestV1AdministratorsController.cs @@ -0,0 +1,82 @@ +using System.Net.Http; +using System.Web.Http; +using System.Web.Http.Controllers; +using System.Web.Http.Results; +using SiteServer.API.Controllers.V1; +using SiteServer.API.Tests.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Utils; +using Xunit; +using Xunit.Abstractions; + +namespace SiteServer.API.Tests.V1 +{ + public class TestV1AdministratorsController : IClassFixture + { + public EnvironmentFixture Fixture { get; } + private readonly ITestOutputHelper _output; + + public TestV1AdministratorsController(EnvironmentFixture fixture, ITestOutputHelper output) + { + Fixture = fixture; + _output = output; + } + + [SkippableFact] + public void List_ShouldReturnUnauthorizedResult() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var controller = new V1AdministratorsController + { + Request = new HttpRequestMessage(), + Configuration = new HttpConfiguration() + }; + + var actionResult = controller.List(); + Assert.IsType(actionResult); + } + + [SkippableFact] + public void Me_ShouldReturnUnauthorizedResult() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var controller = new V1AdministratorsController + { + Request = new HttpRequestMessage(), + Configuration = new HttpConfiguration() + }; + + var actionResult = controller.GetSelf(); + Assert.IsType(actionResult); + } + + [SkippableFact] + public void Me_ShouldReturnOkResult() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var adminInfo = AdminUtils.CreateAdminIfNotExists(); + var accessToken = AdminUtils.GetAccessToken(adminInfo); + + // Arrange + var controller = new V1AdministratorsController(); + var controllerContext = new HttpControllerContext(); + var request = new HttpRequestMessage(); + request.Headers.Add(Constants.AuthKeyAdminHeader, accessToken); + + // Don't forget these lines, if you do then the request will be null. + controllerContext.Request = request; + controller.ControllerContext = controllerContext; + + dynamic results = controller.GetSelf(); + var content = results.Content; + + Assert.NotNull(content); + + _output.WriteLine(TranslateUtils.JsonSerialize(content)); + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.API.Tests/V1/TestV1PingController.cs b/net452/SiteServer.API.Tests/V1/TestV1PingController.cs new file mode 100644 index 000000000..9545305a7 --- /dev/null +++ b/net452/SiteServer.API.Tests/V1/TestV1PingController.cs @@ -0,0 +1,41 @@ +using System.Net; +using System.Net.Http; +using System.Web.Http; +using SiteServer.API.Controllers.V1; +using Xunit; +using Xunit.Abstractions; + +namespace SiteServer.API.Tests.V1 +{ + public class TestV1PingController : IClassFixture + { + public EnvironmentFixture Fixture { get; } + private readonly ITestOutputHelper _output; + + public TestV1PingController(EnvironmentFixture fixture, ITestOutputHelper output) + { + Fixture = fixture; + _output = output; + } + + [Fact] + public void Get_ShouldReturnPong() + { + var controller = new V1PingController + { + Request = new HttpRequestMessage(), + Configuration = new HttpConfiguration() + }; + + var response = controller.Get(); + + var responseContent = response.Content as StringContent; + Assert.NotNull(responseContent); + + var result = responseContent.ReadAsStringAsync().Result; + Assert.Equal(HttpStatusCode.OK, response.StatusCode); + Assert.Equal("pong", result); + _output.WriteLine(result); + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.API.Tests/app.config b/net452/SiteServer.API.Tests/app.config new file mode 100644 index 000000000..d9d05312f --- /dev/null +++ b/net452/SiteServer.API.Tests/app.config @@ -0,0 +1,53 @@ + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/net452/SiteServer.API.Tests/packages.config b/net452/SiteServer.API.Tests/packages.config new file mode 100644 index 000000000..9aca9d1b7 --- /dev/null +++ b/net452/SiteServer.API.Tests/packages.config @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.BackgroundPages/Account/PagePassword.cs b/net452/SiteServer.BackgroundPages/Account/PagePassword.cs new file mode 100644 index 000000000..2b52f8866 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Account/PagePassword.cs @@ -0,0 +1,49 @@ +using System; +using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Account +{ + public class PagePassword : BasePage + { + public Literal LtlUserName; + public TextBox TbCurrentPassword; + public TextBox TbNewPassword; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + if (!Page.IsPostBack) + { + LtlUserName.Text = AuthRequest.AdminName; + } + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + var adminInfo = AdminManager.GetAdminInfoByUserId(AuthRequest.AdminId); + + if (DataProvider.Administrator.CheckPassword(TbCurrentPassword.Text, false, adminInfo.Password, EPasswordFormatUtils.GetEnumType(adminInfo.PasswordFormat), adminInfo.PasswordSalt)) + { + string errorMessage; + if (DataProvider.Administrator.ChangePassword(adminInfo, TbNewPassword.Text, out errorMessage)) + { + SuccessMessage("密码更改成功"); + } + else + { + FailMessage(errorMessage); + } + } + else + { + FailMessage("当前帐号密码错误"); + } + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Account/PageProfile.cs b/net452/SiteServer.BackgroundPages/Account/PageProfile.cs new file mode 100644 index 000000000..5e2ed86e4 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Account/PageProfile.cs @@ -0,0 +1,48 @@ +using System; +using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; + +namespace SiteServer.BackgroundPages.Account +{ + public class PageProfile : BasePage + { + public Literal LtlUserName; + public TextBox TbDisplayName; + public TextBox TbEmail; + public TextBox TbMobile; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + if (Page.IsPostBack) return; + + LtlUserName.Text = AuthRequest.AdminInfo.UserName; + TbDisplayName.Text = AuthRequest.AdminInfo.DisplayName; + TbEmail.Text = AuthRequest.AdminInfo.Email; + TbMobile.Text = AuthRequest.AdminInfo.Mobile; + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + var adminInfo = AdminManager.GetAdminInfoByUserId(AuthRequest.AdminId); + + adminInfo.DisplayName = TbDisplayName.Text; + adminInfo.Email = TbEmail.Text; + adminInfo.Mobile = TbMobile.Text; + + var updated = DataProvider.Administrator.Update(adminInfo, out var errorMessage); + if (updated) + { + SuccessMessage("资料更改成功"); + } + else + { + FailMessage(errorMessage); + } + } + } +} diff --git a/SiteServer.BackgroundPages/Ajax/AjaxBackupService.cs b/net452/SiteServer.BackgroundPages/Ajax/AjaxBackupService.cs similarity index 86% rename from SiteServer.BackgroundPages/Ajax/AjaxBackupService.cs rename to net452/SiteServer.BackgroundPages/Ajax/AjaxBackupService.cs index 5d2091873..e9295c866 100644 --- a/SiteServer.BackgroundPages/Ajax/AjaxBackupService.cs +++ b/net452/SiteServer.BackgroundPages/Ajax/AjaxBackupService.cs @@ -3,12 +3,15 @@ using System.Web.UI; using SiteServer.Utils; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Api; -using SiteServer.CMS.Api.Sys.Stl; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Core.RestRoutes; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Fx; using SiteServer.CMS.ImportExport; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; namespace SiteServer.BackgroundPages.Ajax { @@ -20,7 +23,7 @@ public class AjaxBackupService : Page public static string GetCountArrayUrl() { - return PageUtils.GetAjaxUrl(nameof(AjaxBackupService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxBackupService), new NameValueCollection { {"type", TypeGetCountArray } }); @@ -28,7 +31,7 @@ public static string GetCountArrayUrl() public static string GetBackupUrl() { - return PageUtils.GetAjaxUrl(nameof(AjaxBackupService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxBackupService), new NameValueCollection { {"type", TypeBackup } }); @@ -46,7 +49,7 @@ public static string GetBackupParameters(int siteId, string backupType, string u public static string GetRecoveryUrl() { - return PageUtils.GetAjaxUrl(nameof(AjaxBackupService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxBackupService), new NameValueCollection { {"type", TypeRecovery } }); @@ -73,7 +76,9 @@ public void Page_Load(object sender, EventArgs e) var type = Request.QueryString["type"]; var userKeyPrefix = Request["userKeyPrefix"]; var retval = new NameValueCollection(); - var request = new AuthRequest(); +#pragma warning disable CS0612 // '“RequestImpl”已过时 + var request = new RequestImpl(Page.Request); +#pragma warning restore CS0612 // '“RequestImpl”已过时 if (type == TypeBackup) { @@ -103,7 +108,9 @@ public NameValueCollection Backup(int siteId, string backupType, string userKeyP { //返回“运行结果”和“错误信息”的字符串数组 NameValueCollection retval; - var request = new AuthRequest(Request); +#pragma warning disable CS0612 // '“RequestImpl”已过时 + var request = new RequestImpl(Request); +#pragma warning restore CS0612 // '“RequestImpl”已过时 try { @@ -145,7 +152,9 @@ public NameValueCollection Backup(int siteId, string backupType, string userKeyP return retval; } - public NameValueCollection Recovery(int siteId, bool isDeleteChannels, bool isDeleteTemplates, bool isDeleteFiles, bool isZip, string path, bool isOverride, bool isUseTable, string userKeyPrefix, AuthRequest request) +#pragma warning disable CS0612 // '“RequestImpl”已过时 + public NameValueCollection Recovery(int siteId, bool isDeleteChannels, bool isDeleteTemplates, bool isDeleteFiles, bool isZip, string path, bool isOverride, bool isUseTable, string userKeyPrefix, RequestImpl request) +#pragma warning restore CS0612 // '“RequestImpl”已过时 { //返回“运行结果”和“错误信息”的字符串数组 NameValueCollection retval; diff --git a/SiteServer.BackgroundPages/Ajax/AjaxCmsService.cs b/net452/SiteServer.BackgroundPages/Ajax/AjaxCmsService.cs similarity index 80% rename from SiteServer.BackgroundPages/Ajax/AjaxCmsService.cs rename to net452/SiteServer.BackgroundPages/Ajax/AjaxCmsService.cs index 601176688..96033ff0c 100644 --- a/SiteServer.BackgroundPages/Ajax/AjaxCmsService.cs +++ b/net452/SiteServer.BackgroundPages/Ajax/AjaxCmsService.cs @@ -2,9 +2,12 @@ using System.Collections.Specialized; using System.Text; using System.Web.UI; +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Ajax { @@ -18,7 +21,7 @@ public class AjaxCmsService : Page public static string GetRedirectUrl(string type) { - return PageUtils.GetAjaxUrl(nameof(AjaxCmsService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxCmsService), new NameValueCollection { {"type", type} }); @@ -26,7 +29,7 @@ public static string GetRedirectUrl(string type) public static string GetTitlesUrl(int siteId, int channelId) { - return PageUtils.GetAjaxUrl(nameof(AjaxCmsService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxCmsService), new NameValueCollection { {"type", TypeGetTitles}, {"siteId", siteId.ToString()}, @@ -36,7 +39,7 @@ public static string GetTitlesUrl(int siteId, int channelId) public static string GetWordSpliterUrl(int siteId) { - return PageUtils.GetAjaxUrl(nameof(AjaxCmsService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxCmsService), new NameValueCollection { {"type", TypeGetWordSpliter}, {"siteId", siteId.ToString()} @@ -45,7 +48,7 @@ public static string GetWordSpliterUrl(int siteId) public static string GetDetectionUrl(int siteId) { - return PageUtils.GetAjaxUrl(nameof(AjaxCmsService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxCmsService), new NameValueCollection { {"type", TypeGetDetection}, {"siteId", siteId.ToString()} @@ -54,7 +57,7 @@ public static string GetDetectionUrl(int siteId) public static string GetDetectionReplaceUrl(int siteId) { - return PageUtils.GetAjaxUrl(nameof(AjaxCmsService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxCmsService), new NameValueCollection { {"type", TypeGetDetectionReplace}, {"siteId", siteId.ToString()} @@ -63,7 +66,7 @@ public static string GetDetectionReplaceUrl(int siteId) public static string GetTagsUrl(int siteId) { - return PageUtils.GetAjaxUrl(nameof(AjaxCmsService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxCmsService), new NameValueCollection { {"type", TypeGetTags}, {"siteId", siteId.ToString()} @@ -114,8 +117,8 @@ public void Page_Load(object sender, EventArgs e) if (type == TypeGetDetection) { var content = Request.Form["content"]; - var arraylist = DataProvider.KeywordDao.GetKeywordListByContent(content); - var keywords = TranslateUtils.ObjectCollectionToString(arraylist); + var list = DataProvider.Keyword.GetKeywordListByContent(content); + var keywords = string.Join(",", list); Page.Response.Write(keywords); Page.Response.End(); @@ -123,11 +126,11 @@ public void Page_Load(object sender, EventArgs e) else if (type == TypeGetDetectionReplace) { var content = Request.Form["content"]; - var keywordList = DataProvider.KeywordDao.GetKeywordListByContent(content); + var keywordList = DataProvider.Keyword.GetKeywordListByContent(content); var keywords = string.Empty; if (keywordList.Count > 0) { - var list = DataProvider.KeywordDao.GetKeywordInfoList(keywordList); + var list = DataProvider.Keyword.GetKeywordInfoList(keywordList); foreach (var keywordInfo in list) { keywords += keywordInfo.Keyword + "|" + keywordInfo.Alternative + ","; @@ -148,7 +151,7 @@ public string GetTitles(int siteId, int channelId, string title) var siteInfo = SiteManager.GetSiteInfo(siteId); var tableName = ChannelManager.GetTableName(siteInfo, channelId); - var titleList = DataProvider.ContentDao.GetValueListByStartString(tableName, channelId, ContentAttribute.Title, title, 10); + var titleList = DataProvider.ContentRepository.GetValueListByStartString(tableName, channelId, ContentAttribute.Title, title, 10); if (titleList.Count > 0) { foreach (var value in titleList) @@ -166,7 +169,7 @@ public string GetTags(int siteId, string tag) { var retval = new StringBuilder(); - var tagList = DataProvider.TagDao.GetTagListByStartString(siteId, tag, 10); + var tagList = DataProvider.Tag.GetTagListByStartString(siteId, tag, 10); if (tagList.Count > 0) { foreach (var value in tagList) diff --git a/SiteServer.BackgroundPages/Ajax/AjaxCreateService.cs b/net452/SiteServer.BackgroundPages/Ajax/AjaxCreateService.cs similarity index 86% rename from SiteServer.BackgroundPages/Ajax/AjaxCreateService.cs rename to net452/SiteServer.BackgroundPages/Ajax/AjaxCreateService.cs index 04a81356f..e47e43c5b 100644 --- a/SiteServer.BackgroundPages/Ajax/AjaxCreateService.cs +++ b/net452/SiteServer.BackgroundPages/Ajax/AjaxCreateService.cs @@ -3,9 +3,12 @@ using System.Web.UI; using SiteServer.Utils; using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; using SiteServer.CMS.Core; using SiteServer.CMS.Core.Create; -using SiteServer.CMS.Plugin; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; namespace SiteServer.BackgroundPages.Ajax { @@ -20,7 +23,7 @@ public class AjaxCreateService : Page public static string GetCountArrayUrl() { - return PageUtils.GetAjaxUrl(nameof(AjaxCreateService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxCreateService), new NameValueCollection { {"type", TypeGetCountArray } }); @@ -28,13 +31,13 @@ public static string GetCountArrayUrl() public static string GetCreateSiteUrl() { - return PageUtils.GetAjaxUrl(nameof(AjaxCreateService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxCreateService), new NameValueCollection { {"type", TypeCreateSite } }); } - public static string GetCreateSiteParameters(int siteId, bool isImportContents, bool isImportTableStyles, string siteTemplateDir, string onlineTemplateName, bool isUseTables, string userKeyPrefix) + public static string GetCreateSiteParameters(int siteId, bool isImportContents, bool isImportTableStyles, string siteTemplateDir, string onlineTemplateName, string userKeyPrefix) { return TranslateUtils.NameValueCollectionToString(new NameValueCollection { @@ -43,7 +46,6 @@ public static string GetCreateSiteParameters(int siteId, bool isImportContents, {"isImportTableStyles", isImportTableStyles.ToString()}, {"siteTemplateDir", siteTemplateDir}, {"onlineTemplateName", onlineTemplateName}, - {"isUseTables", isUseTables.ToString()}, {"userKeyPrefix", userKeyPrefix} }); } @@ -53,7 +55,9 @@ public void Page_Load(object sender, EventArgs e) var type = Request.QueryString["type"]; var userKeyPrefix = Request["userKeyPrefix"]; var retval = new NameValueCollection(); - var request = new AuthRequest(); +#pragma warning disable CS0612 // '“RequestImpl”已过时 + var request = new RequestImpl(Page.Request); +#pragma warning restore CS0612 // '“RequestImpl”已过时 if (type == TypeGetCountArray) { @@ -67,15 +71,14 @@ public void Page_Load(object sender, EventArgs e) var isImportTableStyles = TranslateUtils.ToBool(Request.Form["isImportTableStyles"]); var siteTemplateDir = Request.Form["siteTemplateDir"]; var onlineTemplateName = Request.Form["onlineTemplateName"]; - var isUseTables = TranslateUtils.ToBool(Request.Form["isUseTables"]); if (!string.IsNullOrEmpty(siteTemplateDir)) { - retval = CreateSiteBySiteTemplateDir(siteId, isImportContents, isImportTableStyles, siteTemplateDir, isUseTables, userKeyPrefix, request.AdminName); + retval = CreateSiteBySiteTemplateDir(siteId, isImportContents, isImportTableStyles, siteTemplateDir, userKeyPrefix, request.AdminName); } else if (!string.IsNullOrEmpty(onlineTemplateName)) { - retval = CreateSiteByOnlineTemplateName(siteId, isImportContents, isImportTableStyles, onlineTemplateName, isUseTables, userKeyPrefix, request.AdminName); + retval = CreateSiteByOnlineTemplateName(siteId, isImportContents, isImportTableStyles, onlineTemplateName, userKeyPrefix, request.AdminName); } else { @@ -102,7 +105,7 @@ public NameValueCollection GetCountArray(string userKeyPrefix)//进度及显示 return retval; } - public NameValueCollection CreateSiteBySiteTemplateDir(int siteId, bool isImportContents, bool isImportTableStyles, string siteTemplateDir, bool isUseTables, string userKeyPrefix, string administratorName) + public NameValueCollection CreateSiteBySiteTemplateDir(int siteId, bool isImportContents, bool isImportTableStyles, string siteTemplateDir, string userKeyPrefix, string administratorName) { var cacheTotalCountKey = userKeyPrefix + CacheTotalCount; var cacheCurrentCountKey = userKeyPrefix + CacheCurrentCount; @@ -123,14 +126,14 @@ public NameValueCollection CreateSiteBySiteTemplateDir(int siteId, bool isImport CacheUtils.Insert(cacheCurrentCountKey, "2");//存储当前的页面总数 CacheUtils.Insert(cacheMessageKey, "正在导入数据...");//存储消息 - SiteTemplateManager.Instance.ImportSiteTemplateToEmptySite(siteId, siteTemplateDir, isUseTables, isImportContents, isImportTableStyles, administratorName); - CreateManager.CreateAll(siteId); + SiteTemplateManager.Instance.ImportSiteTemplateToEmptySite(siteId, siteTemplateDir, isImportContents, isImportTableStyles, administratorName); + CreateManager.CreateByAll(siteId); CacheUtils.Insert(cacheCurrentCountKey, "3");//存储当前的页面总数 CacheUtils.Insert(cacheMessageKey, "创建成功!");//存储消息 retval = AjaxManager.GetWaitingTaskNameValueCollection( $"站点 {siteInfo.SiteName} 创建成功!", string.Empty, - $"top.location.href='{PageInitialization.GetRedirectUrl()}';"); + $"top.location.href='{FxUtils.GetMainUrl(siteId, string.Empty)}';"); } catch (Exception ex) { @@ -146,7 +149,7 @@ public NameValueCollection CreateSiteBySiteTemplateDir(int siteId, bool isImport return retval; } - public NameValueCollection CreateSiteByOnlineTemplateName(int siteId, bool isImportContents, bool isImportTableStyles, string onlineTemplateName, bool isUseTables, string userKeyPrefix, string administratorName) + public NameValueCollection CreateSiteByOnlineTemplateName(int siteId, bool isImportContents, bool isImportTableStyles, string onlineTemplateName, string userKeyPrefix, string administratorName) { var cacheTotalCountKey = userKeyPrefix + CacheTotalCount; var cacheCurrentCountKey = userKeyPrefix + CacheCurrentCount; @@ -175,20 +178,20 @@ public NameValueCollection CreateSiteByOnlineTemplateName(int siteId, bool isImp var siteTemplateDir = $"T_{onlineTemplateName}"; var directoryPath = PathUtility.GetSiteTemplatesPath(siteTemplateDir); DirectoryUtils.DeleteDirectoryIfExists(directoryPath); - ZipUtils.UnpackFiles(filePath, directoryPath); + ZipUtils.ExtractZip(filePath, directoryPath); CacheUtils.Insert(cacheCurrentCountKey, "3");//存储当前的页面总数 - CacheUtils.Insert(cacheMessageKey, "站点模板下载成功,正在导入数据...");//存储消息 + CacheUtils.Insert(cacheMessageKey, "模板压缩包解压成功,正在导入数据...");//存储消息 - SiteTemplateManager.Instance.ImportSiteTemplateToEmptySite(siteId, siteTemplateDir, isUseTables, isImportContents, isImportTableStyles, administratorName); - CreateManager.CreateAll(siteId); + SiteTemplateManager.Instance.ImportSiteTemplateToEmptySite(siteId, siteTemplateDir, isImportContents, isImportTableStyles, administratorName); + CreateManager.CreateByAll(siteId); CacheUtils.Insert(cacheCurrentCountKey, "4");//存储当前的页面总数 CacheUtils.Insert(cacheMessageKey, "创建成功!");//存储消息 var siteInfo = SiteManager.GetSiteInfo(siteId); retval = AjaxManager.GetWaitingTaskNameValueCollection($"站点 {siteInfo.SiteName} 创建成功!", string.Empty, - $"top.location.href='{PageInitialization.GetRedirectUrl()}';"); + $"top.location.href='{FxUtils.GetMainUrl(siteId, string.Empty)}';"); } catch (Exception ex) { @@ -227,7 +230,7 @@ public NameValueCollection CreateSite(int siteId, string userKeyPrefix, string a CacheUtils.Insert(cacheMessageKey, "创建成功!");//存储消息 retval = AjaxManager.GetWaitingTaskNameValueCollection( $"站点 {siteInfo.SiteName} 创建成功!", string.Empty, - $"top.location.href='{PageInitialization.GetRedirectUrl()}';"); + $"top.location.href='{FxUtils.GetMainUrl(siteId, string.Empty)}';"); } catch (Exception ex) { diff --git a/SiteServer.BackgroundPages/Ajax/AjaxOtherService.cs b/net452/SiteServer.BackgroundPages/Ajax/AjaxOtherService.cs similarity index 89% rename from SiteServer.BackgroundPages/Ajax/AjaxOtherService.cs rename to net452/SiteServer.BackgroundPages/Ajax/AjaxOtherService.cs index 1f77e5940..d0a276f59 100644 --- a/SiteServer.BackgroundPages/Ajax/AjaxOtherService.cs +++ b/net452/SiteServer.BackgroundPages/Ajax/AjaxOtherService.cs @@ -5,10 +5,13 @@ using System.Web.UI; using SiteServer.Utils; using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.Plugin; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Ajax @@ -28,7 +31,7 @@ public class AjaxOtherService : Page public static string GetCountArrayUrl() { - return PageUtils.GetAjaxUrl(nameof(AjaxOtherService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxOtherService), new NameValueCollection { {"type", TypeGetCountArray } }); @@ -36,7 +39,7 @@ public static string GetCountArrayUrl() public static string GetSiteTemplateDownloadUrl() { - return PageUtils.GetAjaxUrl(nameof(AjaxOtherService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxOtherService), new NameValueCollection { {"type", TypeSiteTemplateDownload } }); @@ -44,7 +47,7 @@ public static string GetSiteTemplateDownloadUrl() public static string GetPluginDownloadUrl() { - return PageUtils.GetAjaxUrl(nameof(AjaxOtherService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxOtherService), new NameValueCollection { {"type", TypePluginDownload } }); @@ -71,7 +74,7 @@ public static string GetPluginDownloadParameters(string downloadUrl, string user public static string GetSiteTemplateZipUrl() { - return PageUtils.GetAjaxUrl(nameof(AjaxOtherService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxOtherService), new NameValueCollection { {"type", TypeSiteTemplateZip } }); @@ -79,7 +82,7 @@ public static string GetSiteTemplateZipUrl() public static string GetSiteTemplateUnZipUrl() { - return PageUtils.GetAjaxUrl(nameof(AjaxOtherService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxOtherService), new NameValueCollection { {"type", TypeSiteTemplateUnZip } }); @@ -105,7 +108,7 @@ public static string GetSiteTemplateUnZipParameters(string fileName, string user public static string GetGetLoadingChannelsUrl() { - return PageUtils.GetAjaxUrl(nameof(AjaxOtherService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxOtherService), new NameValueCollection { {"type", TypeGetLoadingChannels } }); @@ -127,7 +130,9 @@ public void Page_Load(object sender, EventArgs e) var type = Request["type"]; var retval = new NameValueCollection(); string retString = null; - var request = new AuthRequest(); +#pragma warning disable CS0612 // '“RequestImpl”已过时 + var request = new RequestImpl(Page.Request); +#pragma warning restore CS0612 // '“RequestImpl”已过时 if (!request.IsAdminLoggin) return; if (type == TypeGetCountArray) @@ -247,7 +252,7 @@ public NameValueCollection SiteTemplateDownload(string downloadUrl, string direc var directoryPath = PathUtility.GetSiteTemplatesPath(directoryName); if (!DirectoryUtils.IsDirectoryExists(directoryPath)) { - ZipUtils.UnpackFiles(filePath, directoryPath); + ZipUtils.ExtractZip(filePath, directoryPath); } CacheUtils.Insert(cacheCurrentCountKey, "5"); @@ -287,14 +292,14 @@ public NameValueCollection PluginDownload(string downloadUrl, string userKeyPref CacheUtils.Insert(cacheMessageKey, "开始下载插件压缩包,可能需要几分钟,请耐心等待"); var fileName = PageUtils.GetFileNameFromUrl(downloadUrl); - var filePath = PathUtils.GetPluginPath(fileName); + var filePath = FxUtils.GetPluginPath(fileName); FileUtils.DeleteFileIfExists(filePath); WebClientUtils.SaveRemoteFileToLocal(downloadUrl, filePath); CacheUtils.Insert(cacheCurrentCountKey, "4"); CacheUtils.Insert(cacheMessageKey, "插件压缩包下载成功,开始安装"); - ZipUtils.UnpackFiles(filePath, PathUtils.GetPluginPath(fileName.Substring(0, fileName.IndexOf(".", StringComparison.Ordinal)))); + ZipUtils.ExtractZip(filePath, FxUtils.GetPluginPath(fileName.Substring(0, fileName.IndexOf(".", StringComparison.Ordinal)))); CacheUtils.Insert(cacheCurrentCountKey, "5"); CacheUtils.Insert(cacheMessageKey, string.Empty); @@ -336,12 +341,12 @@ public NameValueCollection SiteTemplateZip(string directoryName, string userKeyP FileUtils.DeleteFileIfExists(filePath); - ZipUtils.PackFiles(filePath, directoryPath); + ZipUtils.CreateZip(filePath, directoryPath); CacheUtils.Insert(cacheCurrentCountKey, "1");//存储当前的页面总数 retval = AjaxManager.GetProgressTaskNameValueCollection( - $"站点模板压缩成功,点击下载。", string.Empty); + $"站点模板压缩成功,点击下载。", string.Empty); } catch (Exception ex) { @@ -374,7 +379,7 @@ public NameValueCollection SiteTemplateUnZip(string fileName, string userKeyPref var directoryPath = PathUtility.GetSiteTemplatesPath(PathUtils.GetFileNameWithoutExtension(fileName)); var zipFilePath = PathUtility.GetSiteTemplatesPath(fileName); - ZipUtils.UnpackFiles(zipFilePath, directoryPath); + ZipUtils.ExtractZip(zipFilePath, directoryPath); CacheUtils.Insert(cacheCurrentCountKey, "1");//存储当前的页面总数 @@ -393,26 +398,24 @@ public NameValueCollection SiteTemplateUnZip(string fileName, string userKeyPref return retval; } - public string GetLoadingChannels(int siteId, string contentModelPluginId, int parentId, string loadingType, string additional, AuthRequest request) +#pragma warning disable CS0612 // '“RequestImpl”已过时 + public string GetLoadingChannels(int siteId, string contentModelPluginId, int parentId, string loadingType, string additional, RequestImpl request) +#pragma warning restore CS0612 // '“RequestImpl”已过时 { var list = new List(); var eLoadingType = ELoadingTypeUtils.GetEnumType(loadingType); - var channelIdList = - ChannelManager.GetChannelIdList( - ChannelManager.GetChannelInfo(siteId, parentId == 0 ? siteId : parentId), EScopeType.Children, - string.Empty, string.Empty, string.Empty); - var siteInfo = SiteManager.GetSiteInfo(siteId); - + var parentChannelInfo = ChannelManager.GetChannelInfo(siteId, parentId == 0 ? siteId : parentId); + var channelIdList = + ChannelManager.GetChannelIdList(parentChannelInfo, EScopeType.Children, string.Empty, string.Empty, string.Empty); var nameValueCollection = TranslateUtils.ToNameValueCollection(TranslateUtils.DecryptStringBySecretKey(additional)); foreach (var channelId in channelIdList) { var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); - - var enabled = request.AdminPermissions.IsOwningChannelId(channelId); + var enabled = request.AdminPermissionsImpl.IsOwningChannelId(channelId); if (!string.IsNullOrEmpty(contentModelPluginId) && !StringUtils.EqualsIgnoreCase(channelInfo.ContentModelPluginId, contentModelPluginId)) { @@ -420,11 +423,11 @@ public string GetLoadingChannels(int siteId, string contentModelPluginId, int pa } if (!enabled) { - if (!request.AdminPermissions.IsDescendantOwningChannelId(siteId, channelId)) continue; + if (!request.AdminPermissionsImpl.IsDescendantOwningChannelId(siteId, channelId)) continue; if (!IsDesendantContentModelPluginIdExists(channelInfo, contentModelPluginId)) continue; } - list.Add(ChannelLoading.GetChannelRowHtml(siteInfo, channelInfo, enabled, eLoadingType, nameValueCollection, request.AdminPermissions)); + list.Add(ChannelLoading.GetChannelRowHtml(siteInfo, channelInfo, enabled, eLoadingType, nameValueCollection, request.AdminPermissionsImpl)); } //arraylist.Reverse(); diff --git a/SiteServer.BackgroundPages/Ajax/AjaxSystemService.cs b/net452/SiteServer.BackgroundPages/Ajax/AjaxSystemService.cs similarity index 93% rename from SiteServer.BackgroundPages/Ajax/AjaxSystemService.cs rename to net452/SiteServer.BackgroundPages/Ajax/AjaxSystemService.cs index 489d1e8f5..f6bd71750 100644 --- a/SiteServer.BackgroundPages/Ajax/AjaxSystemService.cs +++ b/net452/SiteServer.BackgroundPages/Ajax/AjaxSystemService.cs @@ -6,7 +6,9 @@ using SiteServer.Utils; using SiteServer.BackgroundPages.Core; using SiteServer.BackgroundPages.Settings; -using SiteServer.CMS.Core; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Ajax { @@ -17,7 +19,7 @@ public class AjaxSystemService : Page public static string GetLoadingDepartmentsUrl() { - return PageUtils.GetAjaxUrl(nameof(AjaxSystemService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxSystemService), new NameValueCollection { {"type", TypeGetLoadingDepartments } }); @@ -34,7 +36,7 @@ public static string GetLoadingDepartmentsParameters(EDepartmentLoadingType load public static string GetLoadingAreasUrl() { - return PageUtils.GetAjaxUrl(nameof(AjaxSystemService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxSystemService), new NameValueCollection { {"type", TypeGetLoadingAreas } }); @@ -79,7 +81,7 @@ public string GetLoadingDepartments(int parentId, string loadingType, string add var eLoadingType = EDepartmentLoadingTypeUtils.GetEnumType(loadingType); - var departmentIdList = DataProvider.DepartmentDao.GetIdListByParentId(parentId); + var departmentIdList = DataProvider.Department.GetIdListByParentId(parentId); var nameValueCollection = TranslateUtils.ToNameValueCollection(TranslateUtils.DecryptStringBySecretKey(additional)); if (!string.IsNullOrEmpty(nameValueCollection["DepartmentIDCollection"])) { @@ -117,7 +119,7 @@ public string GetLoadingAreas(int parentId, string loadingType, string additiona var eLoadingType = EAreaLoadingTypeUtils.GetEnumType(loadingType); - var areaIdList = DataProvider.AreaDao.GetIdListByParentId(parentId); + var areaIdList = DataProvider.Area.GetIdListByParentId(parentId); var nameValueCollection = TranslateUtils.ToNameValueCollection(TranslateUtils.DecryptStringBySecretKey(additional)); if (!string.IsNullOrEmpty(nameValueCollection["AreaIDCollection"])) { diff --git a/SiteServer.BackgroundPages/Ajax/AjaxUploadService.cs b/net452/SiteServer.BackgroundPages/Ajax/AjaxUploadService.cs similarity index 94% rename from SiteServer.BackgroundPages/Ajax/AjaxUploadService.cs rename to net452/SiteServer.BackgroundPages/Ajax/AjaxUploadService.cs index f96258337..557082027 100644 --- a/SiteServer.BackgroundPages/Ajax/AjaxUploadService.cs +++ b/net452/SiteServer.BackgroundPages/Ajax/AjaxUploadService.cs @@ -1,9 +1,8 @@ using System; using System.Collections.Specialized; using SiteServer.Utils; -using SiteServer.Utils.Images; using SiteServer.CMS.Core; -using SiteServer.CMS.Core.Office; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Ajax @@ -12,7 +11,7 @@ public class AjaxUploadService : BasePageCms { public static string GetContentPhotoUploadSingleUrl(int siteId) { - return PageUtils.GetAjaxUrl(nameof(AjaxUploadService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxUploadService), new NameValueCollection { {"siteID", siteId.ToString()}, {"isContentPhoto", true.ToString()} @@ -21,7 +20,7 @@ public static string GetContentPhotoUploadSingleUrl(int siteId) public static string GetContentPhotoUploadMultipleUrl(int siteId) { - return PageUtils.GetAjaxUrl(nameof(AjaxUploadService), new NameValueCollection + return FxUtils.GetAjaxUrl(nameof(AjaxUploadService), new NameValueCollection { {"siteID", siteId.ToString()}, {"isContentPhotoSwfUpload", true.ToString()} @@ -112,10 +111,10 @@ public bool UploadContentPhotoImage(out string message, out string url, out stri FileUtility.AddWaterMark(SiteInfo, filePath); - var widthSmall = SiteInfo.Additional.PhotoSmallWidth; + var widthSmall = SiteInfo.PhotoSmallWidth; ImageUtils.MakeThumbnail(filePath, filePathSamll, widthSmall, 0, true); - var widthMiddle = SiteInfo.Additional.PhotoMiddleWidth; + var widthMiddle = SiteInfo.PhotoMiddleWidth; ImageUtils.MakeThumbnail(filePath, filePathMiddle, widthMiddle, 0, true); url = PageUtility.GetSiteUrlByPhysicalPath(SiteInfo, filePathSamll, true); @@ -164,10 +163,10 @@ public bool UploadContentPhotoSwfUpload(out string message, out string url, out FileUtility.AddWaterMark(SiteInfo, filePath); - var widthSmall = SiteInfo.Additional.PhotoSmallWidth; + var widthSmall = SiteInfo.PhotoSmallWidth; ImageUtils.MakeThumbnail(filePath, filePathSmall, widthSmall, 0, true); - var widthMiddle = SiteInfo.Additional.PhotoMiddleWidth; + var widthMiddle = SiteInfo.PhotoMiddleWidth; ImageUtils.MakeThumbnail(filePath, filePathMiddle, widthMiddle, 0, true); url = PageUtility.GetSiteUrlByPhysicalPath(SiteInfo, filePathSmall, true); diff --git a/net452/SiteServer.BackgroundPages/BaseHandler.cs b/net452/SiteServer.BackgroundPages/BaseHandler.cs new file mode 100644 index 000000000..c8eac1cd3 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/BaseHandler.cs @@ -0,0 +1,39 @@ +using System.Web; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.CMS.Plugin.Impl; + +namespace SiteServer.BackgroundPages +{ + public abstract class BaseHandler : IHttpHandler + { +#pragma warning disable CS0612 // '“RequestImpl”已过时 + protected RequestImpl AuthRequest { get; private set; } +#pragma warning restore CS0612 // '“RequestImpl”已过时 + + public void ProcessRequest(HttpContext context) + { +#pragma warning disable CS0612 // '“RequestImpl”已过时 + AuthRequest = new RequestImpl(context.Request); +#pragma warning restore CS0612 // '“RequestImpl”已过时 + + if (!AuthRequest.IsAdminLoggin) return; + + Finish(Process()); + } + + protected abstract object Process(); + + protected void Finish(object retval) + { + var response = HttpContext.Current.Response; + + response.ContentType = "application/json"; + response.Write(TranslateUtils.JsonSerialize(retval)); + response.End(); + } + + public bool IsReusable => false; + } +} diff --git a/net452/SiteServer.BackgroundPages/BasePage.cs b/net452/SiteServer.BackgroundPages/BasePage.cs new file mode 100644 index 000000000..54f41a3b4 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/BasePage.cs @@ -0,0 +1,240 @@ +using System; +using System.Web.UI; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.CMS.Plugin.Impl; + +namespace SiteServer.BackgroundPages +{ + public class BasePage : Page + { + private WebPageUtils.Message.EMessageType _messageType; + private string _message = string.Empty; + private string _scripts = string.Empty; + + protected virtual bool IsAccessable => false; // 页面默认情况下是不能直接访问 + + protected virtual bool IsSinglePage => false; // 是否为单页(即是否需要放在框架页内运行,false表示需要) + + public string IsNightly => WebConfigUtils.IsNightlyUpdate.ToString().ToLower(); // 系统是否允许升级到最新的开发版本 + + public string Version => SystemManager.PluginVersion; // 系统采用的插件API版本号 + + protected bool IsForbidden { get; private set; } + +#pragma warning disable CS0612 // '“RequestImpl”已过时 + public RequestImpl AuthRequest { get; private set; } +#pragma warning restore CS0612 // '“RequestImpl”已过时 + + private void SetMessage(WebPageUtils.Message.EMessageType messageType, Exception ex, string message) + { + _messageType = messageType; + _message = ex != null ? $"{message}" : message; + } + + protected override void OnInit(EventArgs e) + { + base.OnInit(e); + +#pragma warning disable CS0612 // '“RequestImpl”已过时 + AuthRequest = new RequestImpl(Request); +#pragma warning restore CS0612 // '“RequestImpl”已过时 + + if (!IsAccessable) // 如果页面不能直接访问且又没有登录则直接跳登录页 + { + if (!AuthRequest.IsAdminLoggin || AuthRequest.AdminInfo == null || AuthRequest.AdminInfo.Locked) // 检测管理员是否登录,检测管理员帐号是否被锁定 + { + IsForbidden = true; + WebPageUtils.RedirectToLoginPage(); + return; + } + } + + //防止csrf攻击 + Response.AddHeader("X-Frame-Options", "SAMEORIGIN"); + //tell Chrome to disable its XSS protection + Response.AddHeader("X-XSS-Protection", "0"); + } + + protected override void Render(HtmlTextWriter writer) + { + if (!string.IsNullOrEmpty(_message)) + { + WebPageUtils.SaveMessage(_messageType, _message); + } + + base.Render(writer); + + if (!IsAccessable && !IsSinglePage) // 页面不能直接访问且不是单页,需要加一段框架检测代码,检测页面是否运行在框架内 + { + writer.Write($@""); + } + + if (!string.IsNullOrEmpty(_scripts)) + { + writer.Write($@""); + } + } + + public void AddScript(string script) + { + _scripts += script; + } + + public void AddWaitAndRedirectScript(string redirectUrl) + { + _scripts += $@" +setTimeout(function() {{ + location.href = '{redirectUrl}'; +}}, 1500); +"; + } + + public void AddWaitAndReloadMainPage() + { + _scripts += @" +setTimeout(function() {{ + window.top.location.reload(true); +}}, 1500); +"; + } + + public void AddWaitAndScript(string scripts) + { + _scripts += $@" +setTimeout(function() {{ + {scripts} +}}, 1500); +"; + } + + public void FailMessage(Exception ex, string message) + { + SetMessage(WebPageUtils.Message.EMessageType.Error, ex, message); + } + + public void FailMessage(string message) + { + SetMessage(WebPageUtils.Message.EMessageType.Error, null, message); + } + + public void SuccessMessage(string message) + { + SetMessage(WebPageUtils.Message.EMessageType.Success, null, message); + } + + public void SuccessMessage() + { + SuccessMessage("操作成功!"); + } + + public void InfoMessage(string message) + { + SetMessage(WebPageUtils.Message.EMessageType.Info, null, message); + } + + public void SuccessDeleteMessage() + { + SuccessMessage(WebPageUtils.DeleteSuccess); + } + + public void SuccessUpdateMessage() + { + SuccessMessage(WebPageUtils.UpdateSuccess); + } + + public void SuccessCheckMessage() + { + SuccessMessage(WebPageUtils.CheckSuccess); + } + + public void SuccessInsertMessage() + { + SuccessMessage(WebPageUtils.InsertSuccess); + } + + public void FailInsertMessage(Exception ex) + { + FailMessage(ex, WebPageUtils.InsertFail); + } + + public void FailUpdateMessage(Exception ex) + { + FailMessage(ex, WebPageUtils.UpdateFail); + } + + public void FailDeleteMessage(Exception ex) + { + FailMessage(ex, WebPageUtils.DeleteFail); + } + + public void FailCheckMessage(Exception ex) + { + FailMessage(ex, WebPageUtils.CheckFail); + } + + public string MaxLengthText(string str, int length) + { + return StringUtils.MaxLengthText(str, length); + } + + public Control FindControlBySelfAndChildren(string controlId) + { + return SystemWebUtils.FindControlBySelfAndChildren(controlId, this); + } + + public void VerifySystemPermissions(params string[] permissionArray) + { + if (AuthRequest.AdminPermissionsImpl.HasSystemPermissions(permissionArray)) + { + return; + } + AuthRequest.AdminLogout(); + WebPageUtils.Redirect(FxUtils.GetAdminUrl(string.Empty)); + } + + public virtual void Submit_OnClick(object sender, EventArgs e) + { + LayerUtils.Close(Page); + } + + public void ClientScriptRegisterClientScriptBlock(string key, string script) + { + if (!ClientScript.IsStartupScriptRegistered(key)) + { + ClientScript.RegisterClientScriptBlock(GetType(), key, script); + } + } + + public void ClientScriptRegisterStartupScript(string key, string script) + { + if (!ClientScript.IsStartupScriptRegistered(key)) + { + ClientScript.RegisterStartupScript(GetType(), key, script); + } + } + + public bool ClientScriptIsStartupScriptRegistered(string key) + { + return ClientScript.IsStartupScriptRegistered(key); + } + + public static string GetShowImageScript(string imageClientId, string siteUrl) + { + return GetShowImageScript("this", imageClientId, siteUrl); + } + + public static string GetShowImageScript(string objString, string imageClientId, string siteUrl) + { + return + $"showImage({objString}, '{imageClientId}', '{FxUtils.ApplicationPath}', '{siteUrl}')"; + } + } +} diff --git a/SiteServer.BackgroundPages/BasePageCms.cs b/net452/SiteServer.BackgroundPages/BasePageCms.cs similarity index 82% rename from SiteServer.BackgroundPages/BasePageCms.cs rename to net452/SiteServer.BackgroundPages/BasePageCms.cs index a48ceb284..d014049a8 100644 --- a/SiteServer.BackgroundPages/BasePageCms.cs +++ b/net452/SiteServer.BackgroundPages/BasePageCms.cs @@ -1,6 +1,8 @@ using System.Collections.Specialized; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.Utils; namespace SiteServer.BackgroundPages @@ -9,27 +11,27 @@ public class BasePageCms : BasePage { public bool HasChannelPermissions(int channelId, params string[] channelPermissionArray) { - return AuthRequest.AdminPermissions.HasChannelPermissions(SiteId, channelId, channelPermissionArray); + return AuthRequest.AdminPermissionsImpl.HasChannelPermissions(SiteId, channelId, channelPermissionArray); } public bool HasChannelPermissionsIgnoreChannelId(params string[] channelPermissionArray) { - return AuthRequest.AdminPermissions.HasChannelPermissionsIgnoreChannelId(channelPermissionArray); + return AuthRequest.AdminPermissionsImpl.HasChannelPermissionsIgnoreChannelId(channelPermissionArray); } public bool HasSitePermissions(params string[] websitePermissionArray) { - return AuthRequest.AdminPermissions.HasSitePermissions(SiteId, websitePermissionArray); + return AuthRequest.AdminPermissionsImpl.HasSitePermissions(SiteId, websitePermissionArray); } public bool IsOwningChannelId(int channelId) { - return AuthRequest.AdminPermissions.IsOwningChannelId(channelId); + return AuthRequest.AdminPermissionsImpl.IsOwningChannelId(channelId); } public bool IsDescendantOwningChannelId(int channelId) { - return AuthRequest.AdminPermissions.IsDescendantOwningChannelId(SiteId, channelId); + return AuthRequest.AdminPermissionsImpl.IsDescendantOwningChannelId(SiteId, channelId); } private int _siteId = -1; @@ -59,12 +61,12 @@ public SiteInfo SiteInfo public void VerifySitePermissions(params string[] sitePermissions) { - if (AuthRequest.AdminPermissions.HasSitePermissions(SiteId, sitePermissions)) + if (AuthRequest.AdminPermissionsImpl.HasSitePermissions(SiteId, sitePermissions)) { return; } AuthRequest.AdminLogout(); - PageUtils.Redirect(PageUtils.GetAdminDirectoryUrl(string.Empty)); + WebPageUtils.Redirect(FxUtils.GetAdminUrl(string.Empty)); } public void VerifyChannelPermissions(int channelId, params string[] channelPermissions) @@ -74,7 +76,7 @@ public void VerifyChannelPermissions(int channelId, params string[] channelPermi return; } AuthRequest.AdminLogout(); - PageUtils.Redirect(PageUtils.GetAdminDirectoryUrl(string.Empty)); + WebPageUtils.Redirect(FxUtils.GetAdminUrl(string.Empty)); } private NameValueCollection _attributes; diff --git a/SiteServer.BackgroundPages/Cms/ModalAddToGroup.cs b/net452/SiteServer.BackgroundPages/Cms/ModalAddToGroup.cs similarity index 80% rename from SiteServer.BackgroundPages/Cms/ModalAddToGroup.cs rename to net452/SiteServer.BackgroundPages/Cms/ModalAddToGroup.cs index f23f7b215..c50fd1cce 100644 --- a/SiteServer.BackgroundPages/Cms/ModalAddToGroup.cs +++ b/net452/SiteServer.BackgroundPages/Cms/ModalAddToGroup.cs @@ -2,8 +2,13 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Cms { @@ -19,7 +24,7 @@ public class ModalAddToGroup : BasePageCms public static string GetOpenWindowStringToContentForMultiChannels(int siteId) { return LayerUtils.GetOpenScriptWithCheckBoxValue("添加到内容组", - PageUtils.GetCmsUrl(siteId, nameof(ModalAddToGroup), new NameValueCollection + FxUtils.GetCmsUrl(siteId, nameof(ModalAddToGroup), new NameValueCollection { {"isContent", "True"} }), "IDsCollection", "请选择需要设置组别的内容!", 650, 550); @@ -28,7 +33,7 @@ public static string GetOpenWindowStringToContentForMultiChannels(int siteId) public static string GetOpenWindowStringToContent(int siteId, int channelId) { return LayerUtils.GetOpenScriptWithCheckBoxValue("添加到内容组", - PageUtils.GetCmsUrl(siteId, nameof(ModalAddToGroup), new NameValueCollection + FxUtils.GetCmsUrl(siteId, nameof(ModalAddToGroup), new NameValueCollection { {"channelId", channelId.ToString()}, {"isContent", "True"} @@ -38,7 +43,7 @@ public static string GetOpenWindowStringToContent(int siteId, int channelId) public static string GetOpenWindowStringToChannel(int siteId) { return LayerUtils.GetOpenScriptWithCheckBoxValue("添加到栏目组", - PageUtils.GetCmsUrl(siteId, nameof(ModalAddToGroup), new NameValueCollection + FxUtils.GetCmsUrl(siteId, nameof(ModalAddToGroup), new NameValueCollection { {"isContent", "False"} }), "ChannelIDCollection", "请选择需要设置组别的栏目!", 650, 550); @@ -48,7 +53,7 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId"); + WebPageUtils.CheckRequestParameter("siteId"); if (AuthRequest.IsQueryExists("isContent")) { @@ -68,7 +73,7 @@ public void Page_Load(object sender, EventArgs e) { if (_isContent) { - var contentGroupNameList = DataProvider.ContentGroupDao.GetGroupNameList(SiteId); + var contentGroupNameList = ContentGroupManager.GetGroupNameList(SiteId); foreach (var groupName in contentGroupNameList) { var item = new ListItem(groupName, groupName); @@ -79,7 +84,7 @@ public void Page_Load(object sender, EventArgs e) } else { - var nodeGroupNameList = DataProvider.ChannelGroupDao.GetGroupNameList(SiteId); + var nodeGroupNameList = ChannelGroupManager.GetGroupNameList(SiteId); foreach (var groupName in nodeGroupNameList) { var item = new ListItem(groupName, groupName); @@ -111,13 +116,14 @@ public override void Submit_OnClick(object sender, EventArgs e) foreach (var channelId in _idsDictionary.Keys) { - var tableName = ChannelManager.GetTableName(SiteInfo, channelId); - var contentIdArrayList = _idsDictionary[channelId]; - if (contentIdArrayList != null) + var channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + //var tableName = ChannelManager.GetTableName(SiteInfo, channelId); + var contentIdList = _idsDictionary[channelId]; + if (contentIdList != null) { - foreach (var contentId in contentIdArrayList) + foreach (var contentId in contentIdList) { - DataProvider.ContentDao.AddContentGroupList(tableName, contentId, groupNameList); + channelInfo.ContentRepository.AddContentGroupList(contentId, groupNameList); } } } @@ -137,7 +143,7 @@ public override void Submit_OnClick(object sender, EventArgs e) foreach (int channelId in _channelIdArrayList) { - DataProvider.ChannelDao.AddGroupNameList(SiteId, channelId, groupNameList); + DataProvider.Channel.AddGroupNameList(SiteId, channelId, groupNameList); } AuthRequest.AddSiteLog(SiteId, "添加栏目到栏目组", $"栏目组:{TranslateUtils.ObjectCollectionToString(groupNameList)}"); diff --git a/net452/SiteServer.BackgroundPages/Cms/ModalChannelEdit.cs b/net452/SiteServer.BackgroundPages/Cms/ModalChannelEdit.cs new file mode 100644 index 000000000..1f3622bc7 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/ModalChannelEdit.cs @@ -0,0 +1,294 @@ +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Controls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Plugin; + +namespace SiteServer.BackgroundPages.Cms +{ + public class ModalChannelEdit : BasePageCms + { + public PlaceHolder PhFilePath; + public PlaceHolder PhLinkUrl; + public PlaceHolder PhLinkType; + public PlaceHolder PhChannelTemplateId; + + public TextBox TbNodeName; + public TextBox TbNodeIndexName; + public TextBox TbLinkUrl; + public CheckBoxList CblNodeGroupNameCollection; + public DropDownList DdlLinkType; + public DropDownList DdlTaxisType; + public DropDownList DdlChannelTemplateId; + public DropDownList DdlContentTemplateId; + public TextBox TbImageUrl; + public Literal LtlImageUrlButtonGroup; + public TextBox TbFilePath; + public TextBox TbKeywords; + public TextBox TbDescription; + + public TextEditorControl TbContent; + + public ChannelAuxiliaryControl CacAttributes; + + public Button BtnSubmit; + + private int _channelId; + private string _returnUrl; + + public static string GetOpenWindowString(int siteId, int channelId, string returnUrl) + { + return LayerUtils.GetOpenScript("快速修改栏目", FxUtils.GetCmsUrl(siteId, nameof(ModalChannelEdit), new NameValueCollection + { + {"channelId", channelId.ToString()}, + {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} + })); + } + + public static string GetRedirectUrl(int siteId, int channelId, string returnUrl) + { + return FxUtils.GetCmsUrl(siteId, nameof(ModalChannelEdit), new NameValueCollection + { + {"channelId", channelId.ToString()}, + {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "channelId", "ReturnUrl"); + _channelId = AuthRequest.GetQueryInt("channelId"); + _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); + + CacAttributes.SiteInfo = SiteInfo; + CacAttributes.ChannelId = _channelId; + + if (!IsPostBack) + { + if (!HasChannelPermissions(_channelId, ConfigManager.ChannelPermissions.ChannelEdit)) + { + WebPageUtils.RedirectToErrorPage("您没有修改栏目的权限!"); + return; + } + + var channelInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); + if (channelInfo == null) return; + + if (channelInfo.ParentId == 0) + { + PhLinkUrl.Visible = false; + PhLinkType.Visible = false; + PhChannelTemplateId.Visible = false; + PhFilePath.Visible = false; + } + + BtnSubmit.Attributes.Add("onclick", $"if (UE && UE.getEditor('Content', {UEditorUtils.ConfigValues})){{ UE.getEditor('Content', {UEditorUtils.ConfigValues}).sync(); }}"); + + CacAttributes.Attributes = channelInfo.ToDictionary(); + + if (PhLinkType.Visible) + { + SystemWebUtils.AddListItemsToELinkType(DdlLinkType); + } + + SystemWebUtils.AddListItemsToETaxisTypeForChannelEdit(DdlTaxisType); + + SystemWebUtils.AddListControlItems(CblNodeGroupNameCollection, ChannelGroupManager.GetGroupNameList(SiteId)); + //CblNodeGroupNameCollection.DataSource = DataProvider.ChannelGroup.GetDataSource(SiteId); + + if (PhChannelTemplateId.Visible) + { + DdlChannelTemplateId.DataSource = DataProvider.Template.GetDataSourceByType(SiteId, TemplateType.ChannelTemplate); + } + DdlContentTemplateId.DataSource = DataProvider.Template.GetDataSourceByType(SiteId, TemplateType.ContentTemplate); + + DataBind(); + + if (PhChannelTemplateId.Visible) + { + DdlChannelTemplateId.Items.Insert(0, new ListItem("<未设置>", "0")); + SystemWebUtils.SelectSingleItem(DdlChannelTemplateId, channelInfo.ChannelTemplateId.ToString()); + } + + DdlContentTemplateId.Items.Insert(0, new ListItem("<未设置>", "0")); + SystemWebUtils.SelectSingleItem(DdlContentTemplateId, channelInfo.ContentTemplateId.ToString()); + + TbNodeName.Text = channelInfo.ChannelName; + TbNodeIndexName.Text = channelInfo.IndexName; + if (PhLinkUrl.Visible) + { + TbLinkUrl.Text = channelInfo.LinkUrl; + } + + foreach (ListItem item in CblNodeGroupNameCollection.Items) + { + item.Selected = StringUtils.In(channelInfo.GroupNameCollection, item.Value); + } + if (PhFilePath.Visible) + { + TbFilePath.Text = channelInfo.FilePath; + } + + if (PhLinkType.Visible) + { + SystemWebUtils.SelectSingleItem(DdlLinkType, channelInfo.LinkType); + } + SystemWebUtils.SelectSingleItem(DdlTaxisType, channelInfo.DefaultTaxisType); + + TbImageUrl.Text = channelInfo.ImageUrl; + LtlImageUrlButtonGroup.Text = WebUtils.GetImageUrlButtonGroupHtml(SiteInfo, TbImageUrl.ClientID); + TbContent.SetParameters(SiteInfo, ChannelAttribute.Content, channelInfo.Content); + if (TbKeywords.Visible) + { + TbKeywords.Text = channelInfo.Keywords; + } + if (TbDescription.Visible) + { + TbDescription.Text = channelInfo.Description; + } + } + else + { + CacAttributes.Attributes = TranslateUtils.ToDictionary(Request.Form); + } + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + var isChanged = false; + + try + { + var channelInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); + + if (!channelInfo.IndexName.Equals(TbNodeIndexName.Text) && TbNodeIndexName.Text.Length != 0) + { + var nodeIndexNameList = DataProvider.Channel.GetIndexNameList(SiteId); + if (nodeIndexNameList.IndexOf(TbNodeIndexName.Text) != -1) + { + FailMessage("栏目修改失败,栏目索引已存在!"); + return; + } + } + + if (PhFilePath.Visible) + { + TbFilePath.Text = TbFilePath.Text.Trim(); + if (!channelInfo.FilePath.Equals(TbFilePath.Text) && TbFilePath.Text.Length != 0) + { + if (!DirectoryUtils.IsDirectoryNameCompliant(TbFilePath.Text)) + { + FailMessage("栏目页面路径不符合系统要求!"); + return; + } + + if (PathUtils.IsDirectoryPath(TbFilePath.Text)) + { + TbFilePath.Text = PageUtils.Combine(TbFilePath.Text, "index.html"); + } + + var filePathArrayList = DataProvider.Channel.GetAllFilePathBySiteId(SiteId); + if (filePathArrayList.IndexOf(TbFilePath.Text) != -1) + { + FailMessage("栏目修改失败,栏目页面路径已存在!"); + return; + } + } + } + + var styleInfoList = TableStyleManager.GetChannelStyleInfoList(channelInfo); + + var extendedAttributes = BackgroundInputTypeParser.SaveAttributes(SiteInfo, styleInfoList, Request.Form, null); + if (extendedAttributes.Count > 0) + { + foreach (var extendedAttribute in extendedAttributes) + { + channelInfo.Set(extendedAttribute.Key, extendedAttribute.Value); + } + } + + channelInfo.ChannelName = TbNodeName.Text; + channelInfo.IndexName = TbNodeIndexName.Text; + if (PhFilePath.Visible) + { + channelInfo.FilePath = TbFilePath.Text; + } + + var list = new ArrayList(); + foreach (ListItem item in CblNodeGroupNameCollection.Items) + { + if (item.Selected) + { + list.Add(item.Value); + } + } + channelInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(list); + channelInfo.ImageUrl = TbImageUrl.Text; + channelInfo.Content = ContentUtility.TextEditorContentEncode(SiteInfo, Request.Form[ChannelAttribute.Content]); + if (TbKeywords.Visible) + { + channelInfo.Keywords = TbKeywords.Text; + } + if (TbDescription.Visible) + { + channelInfo.Description = TbDescription.Text; + } + + if (PhLinkUrl.Visible) + { + channelInfo.LinkUrl = TbLinkUrl.Text; + } + if (PhLinkType.Visible) + { + channelInfo.LinkType = DdlLinkType.SelectedValue; + } + channelInfo.DefaultTaxisType = ETaxisTypeUtils.GetValue(ETaxisTypeUtils.GetEnumType(DdlTaxisType.SelectedValue)); + if (PhChannelTemplateId.Visible) + { + channelInfo.ChannelTemplateId = DdlChannelTemplateId.Items.Count > 0 ? TranslateUtils.ToInt(DdlChannelTemplateId.SelectedValue) : 0; + } + channelInfo.ContentTemplateId = DdlContentTemplateId.Items.Count > 0 ? TranslateUtils.ToInt(DdlContentTemplateId.SelectedValue) : 0; + + DataProvider.Channel.Update(channelInfo); + + AuthRequest.AddSiteLog(SiteId, _channelId, 0, "修改栏目", $"栏目:{channelInfo.ChannelName}"); + + isChanged = true; + } + catch (Exception ex) + { + FailMessage(ex, $"栏目修改失败:{ex.Message}"); + LogUtils.AddErrorLog(ex); + } + + if (isChanged) + { + CreateManager.CreateChannel(SiteId, _channelId); + + if (string.IsNullOrEmpty(_returnUrl)) + { + LayerUtils.Close(Page); + } + else + { + LayerUtils.CloseAndRedirect(Page, _returnUrl); + } + } + } + } +} diff --git a/SiteServer.BackgroundPages/Cms/ModalChannelImport.cs b/net452/SiteServer.BackgroundPages/Cms/ModalChannelImport.cs similarity index 87% rename from SiteServer.BackgroundPages/Cms/ModalChannelImport.cs rename to net452/SiteServer.BackgroundPages/Cms/ModalChannelImport.cs index 837010f4d..585613537 100644 --- a/SiteServer.BackgroundPages/Cms/ModalChannelImport.cs +++ b/net452/SiteServer.BackgroundPages/Cms/ModalChannelImport.cs @@ -2,8 +2,10 @@ using System.Collections.Specialized; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Fx; using SiteServer.Utils; -using SiteServer.CMS.Core; using SiteServer.CMS.ImportExport; using SiteServer.Utils.Enumerations; @@ -20,7 +22,7 @@ public class ModalChannelImport : BasePageCms public static string GetOpenWindowString(int siteId, int channelId) { return LayerUtils.GetOpenScript("导入栏目", - PageUtils.GetCmsUrl(siteId, nameof(ModalChannelImport), new NameValueCollection + FxUtils.GetCmsUrl(siteId, nameof(ModalChannelImport), new NameValueCollection { {"channelId", channelId.ToString()} }), 600, 300); @@ -38,13 +40,13 @@ public void Page_Load(object sender, EventArgs e) _isLastNodeArray = new bool[nodeCount]; foreach (var theChannelId in channelIdList) { - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, theChannelId); - var itemChannelId = nodeInfo.Id; - var nodeName = nodeInfo.ChannelName; - var parentsCount = nodeInfo.ParentsCount; - var isLastNode = nodeInfo.IsLastNode; + var channelInfo = ChannelManager.GetChannelInfo(SiteId, theChannelId); + var itemChannelId = channelInfo.Id; + var nodeName = channelInfo.ChannelName; + var parentsCount = channelInfo.ParentsCount; + var isLastNode = channelInfo.LastNode; var value = IsOwningChannelId(itemChannelId) ? itemChannelId.ToString() : string.Empty; - value = (nodeInfo.Additional.IsChannelAddable) ? value : string.Empty; + value = channelInfo.IsChannelAddable ? value : string.Empty; if (!string.IsNullOrEmpty(value)) { if (!HasChannelPermissions(theChannelId, ConfigManager.ChannelPermissions.ChannelAdd)) diff --git a/SiteServer.BackgroundPages/Cms/ModalChannelMultipleSelect.cs b/net452/SiteServer.BackgroundPages/Cms/ModalChannelMultipleSelect.cs similarity index 88% rename from SiteServer.BackgroundPages/Cms/ModalChannelMultipleSelect.cs rename to net452/SiteServer.BackgroundPages/Cms/ModalChannelMultipleSelect.cs index 7460e50a4..9de960334 100644 --- a/SiteServer.BackgroundPages/Cms/ModalChannelMultipleSelect.cs +++ b/net452/SiteServer.BackgroundPages/Cms/ModalChannelMultipleSelect.cs @@ -4,9 +4,11 @@ using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Cms @@ -26,7 +28,7 @@ public static string GetOpenWindowString(int siteId, bool isSiteSelect, string jsMethod) { return LayerUtils.GetOpenScript("选择目标栏目", - PageUtils.GetCmsUrl(siteId, nameof(ModalChannelMultipleSelect), new NameValueCollection + FxUtils.GetCmsUrl(siteId, nameof(ModalChannelMultipleSelect), new NameValueCollection { {"isSiteSelect", isSiteSelect.ToString()}, {"jsMethod", jsMethod} @@ -40,7 +42,7 @@ public static string GetOpenWindowString(int siteId, bool isSiteSelect) public string GetRedirectUrl(int targetSiteId, string targetChannelId) { - return PageUtils.GetCmsUrl(targetSiteId, nameof(ModalChannelMultipleSelect), new NameValueCollection + return FxUtils.GetCmsUrl(targetSiteId, nameof(ModalChannelMultipleSelect), new NameValueCollection { {"isSiteSelect", _isSiteSelect.ToString()}, {"jsMethod", _jsMethod}, @@ -66,7 +68,7 @@ public void Page_Load(object sender, EventArgs e) PhSiteId.Visible = _isSiteSelect; - var siteIdList = AuthRequest.AdminPermissions.SiteIdList; + var siteIdList = AuthRequest.AdminPermissionsImpl.GetSiteIdList(); var mySystemInfoArrayList = new ArrayList(); var parentWithChildren = new Hashtable(); @@ -92,7 +94,7 @@ public void Page_Load(object sender, EventArgs e) { AddSite(DdlSiteId, siteInfo, parentWithChildren, 0); } - ControlUtils.SelectSingleItem(DdlSiteId, _targetSiteId.ToString()); + SystemWebUtils.SelectSingleItem(DdlSiteId, _targetSiteId.ToString()); var targetChannelId = AuthRequest.GetQueryInt("TargetChannelId"); if (targetChannelId > 0) @@ -121,7 +123,7 @@ public void Page_Load(object sender, EventArgs e) { ["linkUrl"] = GetRedirectUrl(_targetSiteId, string.Empty) }; - ClientScriptRegisterClientScriptBlock("NodeTreeScript", ChannelLoading.GetScript(SiteManager.GetSiteInfo(_targetSiteId), string.Empty, ELoadingType.ChannelSelect, additional)); + ClientScriptRegisterClientScriptBlock("NodeTreeScript", ChannelLoading.GetScript(SiteManager.GetSiteInfo(_targetSiteId), string.Empty, ELoadingType.ChannelClickSelect, additional)); var channelIdList = ChannelManager.GetChannelIdList(nodeInfo, EScopeType.Children, string.Empty, string.Empty, string.Empty); @@ -139,7 +141,7 @@ private void RptChannel_ItemDataBound(object sender, RepeaterItemEventArgs e) { if (!IsDescendantOwningChannelId(channelId)) e.Item.Visible = false; } - var nodeInfo = ChannelManager.GetChannelInfo(_targetSiteId, channelId); + var channelInfo = ChannelManager.GetChannelInfo(_targetSiteId, channelId); var ltlHtml = (Literal)e.Item.FindControl("ltlHtml"); @@ -148,13 +150,13 @@ private void RptChannel_ItemDataBound(object sender, RepeaterItemEventArgs e) ["linkUrl"] = GetRedirectUrl(_targetSiteId, string.Empty) }; - ltlHtml.Text = ChannelLoading.GetChannelRowHtml(SiteInfo, nodeInfo, enabled, ELoadingType.ChannelSelect, additional, AuthRequest.AdminPermissions); + ltlHtml.Text = ChannelLoading.GetChannelRowHtml(SiteInfo, channelInfo, enabled, ELoadingType.ChannelClickSelect, additional, AuthRequest.AdminPermissionsImpl); } public void DdlSiteId_OnSelectedIndexChanged(object sender, EventArgs e) { var redirectUrl = GetRedirectUrl(TranslateUtils.ToInt(DdlSiteId.SelectedValue), string.Empty); - PageUtils.Redirect(redirectUrl); + WebPageUtils.Redirect(redirectUrl); } private void AddSite(ListControl listControl, SiteInfo siteInfo, Hashtable parentWithChildren, int level) diff --git a/SiteServer.BackgroundPages/Cms/ModalChannelSelect.cs b/net452/SiteServer.BackgroundPages/Cms/ModalChannelSelect.cs similarity index 86% rename from SiteServer.BackgroundPages/Cms/ModalChannelSelect.cs rename to net452/SiteServer.BackgroundPages/Cms/ModalChannelSelect.cs index b79ac1bb4..e6a2a2690 100644 --- a/SiteServer.BackgroundPages/Cms/ModalChannelSelect.cs +++ b/net452/SiteServer.BackgroundPages/Cms/ModalChannelSelect.cs @@ -3,8 +3,10 @@ using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Caches; using SiteServer.CMS.Core; -using SiteServer.CMS.Model.Enumerations; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Cms @@ -27,7 +29,7 @@ public static string GetOpenWindowString(int siteId) public static string GetOpenWindowString(int siteId, bool isProtocol) { return LayerUtils.GetOpenScript("栏目选择", - PageUtils.GetCmsUrl(siteId, nameof(ModalChannelSelect), new NameValueCollection + FxUtils.GetCmsUrl(siteId, nameof(ModalChannelSelect), new NameValueCollection { {"isProtocol", isProtocol.ToString()} }), 460, 450); @@ -35,7 +37,7 @@ public static string GetOpenWindowString(int siteId, bool isProtocol) public static string GetRedirectUrl(int siteId, int channelId) { - return PageUtils.GetCmsUrl(siteId, nameof(ModalChannelSelect), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(ModalChannelSelect), new NameValueCollection { {"channelId", channelId.ToString()} }); @@ -44,7 +46,7 @@ public static string GetRedirectUrl(int siteId, int channelId) public static string GetOpenWindowStringByItemIndex(int siteId, string jsMethod, string itemIndex) { return LayerUtils.GetOpenScript("栏目选择", - PageUtils.GetCmsUrl(siteId, nameof(ModalChannelSelect), new NameValueCollection + FxUtils.GetCmsUrl(siteId, nameof(ModalChannelSelect), new NameValueCollection { {"jsMethod", jsMethod}, {"itemIndex", itemIndex} @@ -80,7 +82,7 @@ public void Page_Load(object sender, EventArgs e) var pageUrl = PageUtility.GetChannelUrl(SiteInfo, ChannelManager.GetChannelInfo(SiteId, channelId), false); if (_isProtocol) { - pageUrl = PageUtils.AddProtocolToUrl(pageUrl); + pageUrl = FxUtils.AddProtocolToUrl(pageUrl); } string scripts = $"window.parent.selectChannel('{nodeNames}', '{channelId}', '{pageUrl}');"; @@ -91,7 +93,7 @@ public void Page_Load(object sender, EventArgs e) { var nodeInfo = ChannelManager.GetChannelInfo(SiteId, SiteId); - var linkUrl = PageUtils.GetCmsUrl(SiteId, nameof(ModalChannelSelect), new NameValueCollection + var linkUrl = FxUtils.GetCmsUrl(SiteId, nameof(ModalChannelSelect), new NameValueCollection { {"channelId", nodeInfo.Id.ToString()}, {"isProtocol", _isProtocol.ToString()}, @@ -99,7 +101,7 @@ public void Page_Load(object sender, EventArgs e) {"itemIndex", _itemIndex.ToString()} }); LtlSite.Text = $"{nodeInfo.ChannelName}"; - ClientScriptRegisterClientScriptBlock("NodeTreeScript", ChannelLoading.GetScript(SiteInfo, string.Empty, ELoadingType.ChannelSelect, null)); + ClientScriptRegisterClientScriptBlock("NodeTreeScript", ChannelLoading.GetScript(SiteInfo, string.Empty, ELoadingType.ChannelClickSelect, null)); BindGrid(); } } @@ -125,7 +127,7 @@ void rptChannel_ItemDataBound(object sender, RepeaterItemEventArgs e) var ltlHtml = (Literal)e.Item.FindControl("ltlHtml"); - ltlHtml.Text = ChannelLoading.GetChannelRowHtml(SiteInfo, nodeInfo, enabled, ELoadingType.ChannelSelect, _additional, AuthRequest.AdminPermissions); + ltlHtml.Text = ChannelLoading.GetChannelRowHtml(SiteInfo, nodeInfo, enabled, ELoadingType.ChannelClickSelect, _additional, AuthRequest.AdminPermissionsImpl); } } } diff --git a/net452/SiteServer.BackgroundPages/Cms/ModalChannelTaxis.cs b/net452/SiteServer.BackgroundPages/Cms/ModalChannelTaxis.cs new file mode 100644 index 000000000..a29adf3d8 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/ModalChannelTaxis.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class ModalChannelTaxis : BasePageCms + { + protected DropDownList DdlTaxisType; + protected TextBox TbTaxisNum; + + private List _channelIdList; + + public static string GetOpenWindowString(int siteId) + { + return LayerUtils.GetOpenScriptWithCheckBoxValue("栏目排序", FxUtils.GetCmsUrl(siteId, nameof(ModalChannelTaxis), null), "ChannelIDCollection", "请选择需要排序的栏目!", 400, 280); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "ChannelIDCollection"); + + _channelIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("channelIDCollection")); + + if (IsPostBack) return; + + DdlTaxisType.Items.Add(new ListItem("上升", "Up")); + DdlTaxisType.Items.Add(new ListItem("下降", "Down")); + SystemWebUtils.SelectSingleItem(DdlTaxisType, "Up"); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + var isSubtract = DdlTaxisType.SelectedValue == "Up"; + var taxisNum = TranslateUtils.ToInt(TbTaxisNum.Text); + + foreach (var channelId in _channelIdList) + { + for (var num = 0; num < taxisNum; num++) + { + DataProvider.Channel.UpdateTaxis(SiteId, channelId, isSubtract); + } + + AuthRequest.AddSiteLog(SiteId, channelId, 0, "栏目排序" + (isSubtract ? "上升" : "下降"), $"栏目:{ChannelManager.GetChannelName(SiteId, channelId)}"); + } + LayerUtils.Close(Page); + } + + } +} diff --git a/SiteServer.BackgroundPages/Cms/ModalChannelsAdd.cs b/net452/SiteServer.BackgroundPages/Cms/ModalChannelsAdd.cs similarity index 90% rename from SiteServer.BackgroundPages/Cms/ModalChannelsAdd.cs rename to net452/SiteServer.BackgroundPages/Cms/ModalChannelsAdd.cs index ea357bfcf..d01e4c370 100644 --- a/SiteServer.BackgroundPages/Cms/ModalChannelsAdd.cs +++ b/net452/SiteServer.BackgroundPages/Cms/ModalChannelsAdd.cs @@ -3,9 +3,13 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; using SiteServer.Utils; -using SiteServer.CMS.Core; using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; using SiteServer.CMS.Plugin; using SiteServer.Plugin; @@ -29,7 +33,7 @@ public class ModalChannelsAdd : BasePageCms public static string GetOpenWindowString(int siteId, int channelId, string returnUrl) { return LayerUtils.GetOpenScript("添加栏目", - PageUtils.GetCmsUrl(siteId, nameof(ModalChannelsAdd), new NameValueCollection + FxUtils.GetCmsUrl(siteId, nameof(ModalChannelsAdd), new NameValueCollection { {"channelId", channelId.ToString()}, {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} @@ -38,7 +42,7 @@ public static string GetOpenWindowString(int siteId, int channelId, string retur public static string GetRedirectUrl(int siteId, int channelId, string returnUrl) { - return PageUtils.GetCmsUrl(siteId, nameof(ModalChannelsAdd), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(ModalChannelsAdd), new NameValueCollection { {"channelId", channelId.ToString()}, {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} @@ -49,7 +53,7 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId", "channelId", "ReturnUrl"); + WebPageUtils.CheckRequestParameter("siteId", "channelId", "ReturnUrl"); var channelId = AuthRequest.GetQueryInt("channelId"); _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); @@ -76,8 +80,8 @@ public void Page_Load(object sender, EventArgs e) PhContentRelatedPluginIds.Visible = false; } - DdlChannelTemplateId.DataSource = DataProvider.TemplateDao.GetDataSourceByType(SiteId, TemplateType.ChannelTemplate); - DdlContentTemplateId.DataSource = DataProvider.TemplateDao.GetDataSourceByType(SiteId, TemplateType.ContentTemplate); + DdlChannelTemplateId.DataSource = DataProvider.Template.GetDataSourceByType(SiteId, TemplateType.ChannelTemplate); + DdlContentTemplateId.DataSource = DataProvider.Template.GetDataSourceByType(SiteId, TemplateType.ContentTemplate); DdlChannelTemplateId.DataBind(); DdlChannelTemplateId.Items.Insert(0, new ListItem("<默认>", "0")); @@ -111,7 +115,7 @@ public override void Submit_OnClick(object sender, EventArgs e) var insertedChannelIdHashtable = new Hashtable {[1] = parentChannelId}; //key为栏目的级别,1为第一级栏目 var nodeNameArray = TbNodeNames.Text.Split('\n'); - List nodeIndexNameList = null; + IList nodeIndexNameList = null; foreach (var item in nodeNameArray) { if (string.IsNullOrEmpty(item)) continue; @@ -144,7 +148,7 @@ public override void Submit_OnClick(object sender, EventArgs e) { if (nodeIndexNameList == null) { - nodeIndexNameList = DataProvider.ChannelDao.GetIndexNameList(SiteId); + nodeIndexNameList = DataProvider.Channel.GetIndexNameList(SiteId); } if (nodeIndexNameList.IndexOf(nodeIndex) != -1) { @@ -167,7 +171,7 @@ public override void Submit_OnClick(object sender, EventArgs e) var channelTemplateId = TranslateUtils.ToInt(DdlChannelTemplateId.SelectedValue); var contentTemplateId = TranslateUtils.ToInt(DdlContentTemplateId.SelectedValue); - var insertedChannelId = DataProvider.ChannelDao.Insert(SiteId, parentId, nodeName, nodeIndex, contentModelPluginId, ControlUtils.GetSelectedListControlValueCollection(CblContentRelatedPluginIds), channelTemplateId, contentTemplateId); + var insertedChannelId = DataProvider.Channel.Insert(SiteId, parentId, nodeName, nodeIndex, contentModelPluginId, SystemWebUtils.GetSelectedListControlValueCollection(CblContentRelatedPluginIds), channelTemplateId, contentTemplateId); insertedChannelIdHashtable[count + 1] = insertedChannelId; CreateManager.CreateChannel(SiteId, insertedChannelId); diff --git a/net452/SiteServer.BackgroundPages/Cms/ModalCheckState.cs b/net452/SiteServer.BackgroundPages/Cms/ModalCheckState.cs new file mode 100644 index 000000000..cf1730773 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/ModalCheckState.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class ModalCheckState : BasePageCms + { + protected override bool IsSinglePage => true; + public Literal LtlTitle; + public Literal LtlState; + public PlaceHolder PhCheckReasons; + public Repeater RptContents; + public Button BtnCheck; + + private int _channelId; + private string _tableName; + private int _contentId; + private string _returnUrl; + + public static string GetOpenWindowString(int siteId, ContentInfo contentInfo, string returnUrl) + { + return LayerUtils.GetOpenScript("审核状态", + FxUtils.GetCmsUrl(siteId, nameof(ModalCheckState), new NameValueCollection + { + {"channelId", contentInfo.ChannelId.ToString()}, + {"contentID", contentInfo.Id.ToString()}, + {"returnUrl", StringUtils.ValueToUrl(returnUrl)} + }), 560, 500); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "channelId", "contentID", "returnUrl"); + + _channelId = AuthRequest.GetQueryInt("channelId"); + _tableName = ChannelManager.GetTableName(SiteInfo, _channelId); + _contentId = AuthRequest.GetQueryInt("contentID"); + _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("returnUrl")); + + var contentInfo = ContentManager.GetContentInfo(SiteInfo, _channelId, _contentId); + + var isChecked = CheckManager.GetUserCheckLevel(AuthRequest.AdminPermissionsImpl, SiteInfo, SiteId, out var checkedLevel); + BtnCheck.Visible = CheckManager.IsCheckable(contentInfo.Checked, contentInfo.CheckedLevel, isChecked, checkedLevel); + + LtlTitle.Text = contentInfo.Title; + LtlState.Text = CheckManager.GetCheckState(SiteInfo, contentInfo); + + var checkInfoList = DataProvider.ContentCheck.GetCheckInfoList(_tableName, _contentId); + if (checkInfoList.Count > 0) + { + PhCheckReasons.Visible = true; + RptContents.DataSource = checkInfoList; + RptContents.ItemDataBound += RptContents_ItemDataBound; + RptContents.DataBind(); + } + } + + private static void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + var checkInfo = (ContentCheckInfo)e.Item.DataItem; + + var ltlUserName = (Literal)e.Item.FindControl("ltlUserName"); + var ltlCheckDate = (Literal)e.Item.FindControl("ltlCheckDate"); + var ltlReasons = (Literal)e.Item.FindControl("ltlReasons"); + + ltlUserName.Text = AdminManager.GetDisplayName(checkInfo.UserName, true); + ltlCheckDate.Text = DateUtils.GetDateAndTimeString(checkInfo.CheckDate); + ltlReasons.Text = checkInfo.Reasons; + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + var redirectUrl = ModalContentCheck.GetRedirectUrl(SiteId, _channelId, _contentId, _returnUrl); + WebPageUtils.Redirect(redirectUrl); + } + + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/ModalConfigurationCreateChannel.cs b/net452/SiteServer.BackgroundPages/Cms/ModalConfigurationCreateChannel.cs new file mode 100644 index 000000000..6a0e3a44a --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/ModalConfigurationCreateChannel.cs @@ -0,0 +1,78 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class ModalConfigurationCreateChannel : BasePageCms + { + public DropDownList DdlIsCreateChannelIfContentChanged; + + protected ListBox LbChannelId; + + private int _channelId; + + public static string GetOpenWindowString(int siteId, int channelId) + { + return LayerUtils.GetOpenScript("栏目生成设置", + FxUtils.GetCmsUrl(siteId, nameof(ModalConfigurationCreateChannel), new NameValueCollection + { + {"channelId", channelId.ToString()} + }), 550, 500); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "channelId"); + _channelId = AuthRequest.GetQueryInt("channelId"); + + if (!IsPostBack) + { + var channelInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); + + FxUtils.AddListItems(DdlIsCreateChannelIfContentChanged, "生成", "不生成"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsCreateChannelIfContentChanged, channelInfo.IsCreateChannelIfContentChanged.ToString()); + + //NodeManager.AddListItemsForAddContent(this.channelIdCollection.Items, base.SiteInfo, false); + SystemWebUtils.AddListItemsForCreateChannel(LbChannelId.Items, SiteInfo, false, AuthRequest.AdminPermissionsImpl); + SystemWebUtils.SelectMultiItems(LbChannelId, TranslateUtils.StringCollectionToStringList(channelInfo.CreateChannelIdsIfContentChanged)); + } + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + var isSuccess = false; + + try + { + var channelInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); + + channelInfo.IsCreateChannelIfContentChanged = TranslateUtils.ToBool(DdlIsCreateChannelIfContentChanged.SelectedValue); + channelInfo.CreateChannelIdsIfContentChanged = SystemWebUtils.GetSelectedListControlValueCollection(LbChannelId); + + DataProvider.Channel.Update(channelInfo); + + AuthRequest.AddSiteLog(SiteId, _channelId, 0, "设置栏目变动生成页面", $"栏目:{channelInfo.ChannelName}"); + isSuccess = true; + } + catch (Exception ex) + { + FailMessage(ex, ex.Message); + } + + if (isSuccess) + { + LayerUtils.CloseAndRedirect(Page, PageConfigurationCreateTrigger.GetRedirectUrl(SiteId, _channelId)); + } + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/ModalContentAttributes.cs b/net452/SiteServer.BackgroundPages/Cms/ModalContentAttributes.cs new file mode 100644 index 000000000..803401788 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/ModalContentAttributes.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Web.UI.HtmlControls; +using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.BackgroundPages.Cms +{ + public class ModalContentAttributes : BasePageCms + { + protected CheckBox CbIsRecommend; + protected CheckBox CbIsHot; + protected CheckBox CbIsColor; + protected CheckBox CbIsTop; + protected HtmlInputHidden HihType; + protected TextBox TbHits; + + private ChannelInfo _channelInfo; + private List _idList; + + public static string GetOpenWindowString(int siteId, int channelId) + { + return LayerUtils.GetOpenScriptWithCheckBoxValue("设置内容属性", PageUtils.GetCmsUrl(siteId, nameof(ModalContentAttributes), new NameValueCollection + { + {"channelId", channelId.ToString()} + }), "contentIdCollection", "请选择需要设置属性的内容!", 450, 350); + } + + public static string GetOpenWindowStringWithCheckBoxValue(int siteId, int channelId) + { + return LayerUtils.GetOpenScriptWithCheckBoxValue("设置内容属性", PageUtils.GetCmsUrl(siteId, nameof(ModalContentAttributes), new NameValueCollection + { + {"channelId", channelId.ToString()} + }), "contentIdCollection", "请选择需要设置属性的内容!", 450, 350); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + PageUtils.CheckRequestParameter("siteId", "channelId"); + + var channelId = AuthRequest.GetQueryInt("channelId"); + _channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + _idList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("contentIdCollection")); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + var isChanged = false; + + switch (HihType.Value) + { + case "1": + if (CbIsRecommend.Checked || CbIsHot.Checked || CbIsColor.Checked || CbIsTop.Checked) + { + foreach (var contentId in _idList) + { + var contentInfo = ContentManager.GetContentInfo(SiteInfo, _channelInfo, contentId); + if (contentInfo != null) + { + if (CbIsRecommend.Checked) + { + contentInfo.Recommend = true; + } + if (CbIsHot.Checked) + { + contentInfo.Hot = true; + } + if (CbIsColor.Checked) + { + contentInfo.Color = true; + } + if (CbIsTop.Checked) + { + contentInfo.Top = true; + } + DataProvider.ContentRepository.Update(SiteInfo, _channelInfo, contentInfo); + } + } + + AuthRequest.AddSiteLog(SiteId, "设置内容属性"); + + isChanged = true; + } + + break; + case "2": + if (CbIsRecommend.Checked || CbIsHot.Checked || CbIsColor.Checked || CbIsTop.Checked) + { + foreach (var contentId in _idList) + { + var contentInfo = ContentManager.GetContentInfo(SiteInfo, _channelInfo, contentId); + if (contentInfo != null) + { + if (CbIsRecommend.Checked) + { + contentInfo.Recommend = false; + } + if (CbIsHot.Checked) + { + contentInfo.Hot = false; + } + if (CbIsColor.Checked) + { + contentInfo.Color = false; + } + if (CbIsTop.Checked) + { + contentInfo.Top = false; + } + DataProvider.ContentRepository.Update(SiteInfo, _channelInfo, contentInfo); + } + } + + AuthRequest.AddSiteLog(SiteId, "取消内容属性"); + + isChanged = true; + } + + break; + case "3": + var hits = TranslateUtils.ToInt(TbHits.Text); + + foreach (var contentId in _idList) + { + var contentInfo = ContentManager.GetContentInfo(SiteInfo, _channelInfo, contentId); + if (contentInfo != null) + { + contentInfo.Hits = hits; + DataProvider.ContentRepository.Update(SiteInfo, _channelInfo, contentInfo); + } + } + + AuthRequest.AddSiteLog(SiteId, "设置内容点击量"); + + isChanged = true; + break; + } + + if (isChanged) + { + LayerUtils.Close(Page); + } + } + + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/ModalContentCheck.cs b/net452/SiteServer.BackgroundPages/Cms/ModalContentCheck.cs new file mode 100644 index 000000000..0fd4b3ab8 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/ModalContentCheck.cs @@ -0,0 +1,202 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Text; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class ModalContentCheck : BasePageCms + { + protected override bool IsSinglePage => true; + public Literal LtlTitles; + public DropDownList DdlCheckType; + public DropDownList DdlTranslateChannelId; + public TextBox TbCheckReasons; + + private Dictionary> _idsDictionary = new Dictionary>(); + private string _returnUrl; + + public static string GetOpenWindowString(int siteId, int channelId, string returnUrl) + { + return LayerUtils.GetOpenScriptWithCheckBoxValue("审核内容", FxUtils.GetCmsUrl(siteId, nameof(ModalContentCheck), new NameValueCollection + { + {"channelId", channelId.ToString()}, + {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} + }), "contentIdCollection", "请选择需要审核的内容!", 560, 550); + } + + public static string GetOpenWindowStringForMultiChannels(int siteId, string returnUrl) + { + return LayerUtils.GetOpenScriptWithCheckBoxValue("审核内容", FxUtils.GetCmsUrl(siteId, nameof(ModalContentCheck), new NameValueCollection + { + {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} + }), "IDsCollection", "请选择需要审核的内容!", 560, 550); + } + + public static string GetOpenWindowString(int siteId, int channelId, int contentId, string returnUrl) + { + return LayerUtils.GetOpenScript("审核内容", FxUtils.GetCmsUrl(siteId, nameof(ModalContentCheck), new NameValueCollection + { + {"channelId", channelId.ToString()}, + {"contentIdCollection", contentId.ToString()}, + {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} + }), 560, 550); + } + + public static string GetRedirectUrl(int siteId, int channelId, int contentId, string returnUrl) + { + return FxUtils.GetCmsUrl(siteId, nameof(ModalContentCheck), new NameValueCollection + { + {"channelId", channelId.ToString()}, + {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)}, + {"contentIdCollection", contentId.ToString()} + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "ReturnUrl"); + _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); + + _idsDictionary = ContentUtility.GetIDsDictionary(Request.QueryString); + + if (IsPostBack) return; + + var titles = new StringBuilder(); + foreach (var channelId in _idsDictionary.Keys) + { + var channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + //var tableName = ChannelManager.GetTableName(SiteInfo, channelId); + var contentIdList = _idsDictionary[channelId]; + foreach (var contentId in contentIdList) + { + var title = channelInfo.ContentRepository.GetValue(contentId, ContentAttribute.Title); + titles.Append(title + "
    "); + } + } + + if (!string.IsNullOrEmpty(LtlTitles.Text)) + { + titles.Length -= 6; + } + LtlTitles.Text = titles.ToString(); + + var checkedLevel = 5; + var isChecked = true; + + foreach (var channelId in _idsDictionary.Keys) + { + int checkedLevelByChannelId; + var isCheckedByChannelId = CheckManager.GetUserCheckLevel(AuthRequest.AdminPermissionsImpl, SiteInfo, channelId, out checkedLevelByChannelId); + if (checkedLevel > checkedLevelByChannelId) + { + checkedLevel = checkedLevelByChannelId; + } + if (!isCheckedByChannelId) + { + isChecked = false; + } + } + + SystemWebUtils.LoadContentLevelToCheck(DdlCheckType, SiteInfo, isChecked, checkedLevel); + + var listItem = new ListItem("<保持原栏目不变>", "0"); + DdlTranslateChannelId.Items.Add(listItem); + + SystemWebUtils.AddListItemsForAddContent(DdlTranslateChannelId.Items, SiteInfo, true, AuthRequest.AdminPermissionsImpl); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + var checkedLevel = TranslateUtils.ToIntWithNegative(DdlCheckType.SelectedValue); + + var isChecked = checkedLevel >= SiteInfo.CheckContentLevel; + + var contentInfoListToCheck = new List(); + var idsDictionaryToCheck = new Dictionary>(); + foreach (var channelId in _idsDictionary.Keys) + { + var channelInfo = ChannelManager.GetChannelInfo(SiteInfo.Id, channelId); + var contentIdList = _idsDictionary[channelId]; + var contentIdListToCheck = new List(); + + int checkedLevelOfUser; + var isCheckedOfUser = CheckManager.GetUserCheckLevel(AuthRequest.AdminPermissionsImpl, SiteInfo, channelId, out checkedLevelOfUser); + + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(SiteInfo, channelInfo, contentId); + if (contentInfo != null) + { + if (CheckManager.IsCheckable(contentInfo.Checked, contentInfo.CheckedLevel, isCheckedOfUser, checkedLevelOfUser)) + { + contentInfoListToCheck.Add(contentInfo); + contentIdListToCheck.Add(contentId); + } + + //DataProvider.ContentRepository.UpdateObject(SiteInfo, channelInfo, contentInfo); + + //CreateManager.CreateContent(SiteId, contentInfo.ChannelId, contentId); + //CreateManager.TriggerContentChangedEvent(SiteId, contentInfo.ChannelId); + } + } + if (contentIdListToCheck.Count > 0) + { + idsDictionaryToCheck[channelId] = contentIdListToCheck; + } + } + + if (contentInfoListToCheck.Count == 0) + { + LayerUtils.CloseWithoutRefresh(Page, "alert('您的审核权限不足,无法审核所选内容!');"); + return; + } + + var translateChannelId = TranslateUtils.ToInt(DdlTranslateChannelId.SelectedValue); + + foreach (var channelId in idsDictionaryToCheck.Keys) + { + var contentIdList = idsDictionaryToCheck[channelId]; + + var channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + channelInfo.ContentRepository.UpdateIsChecked(channelId, contentIdList, translateChannelId, AuthRequest.AdminName, isChecked, checkedLevel, TbCheckReasons.Text); + } + + if (translateChannelId > 0) + { + var tableName = ChannelManager.GetTableName(SiteInfo, translateChannelId); + ContentManager.RemoveCache(tableName, translateChannelId); + } + + AuthRequest.AddSiteLog(SiteId, SiteId, 0, "设置内容状态为" + DdlCheckType.SelectedItem.Text, TbCheckReasons.Text); + + foreach (var channelId in idsDictionaryToCheck.Keys) + { + var contentIdList = _idsDictionary[channelId]; + if (contentIdList != null) + { + foreach (var contentId in contentIdList) + { + CreateManager.CreateContent(SiteId, channelId, contentId); + CreateManager.TriggerContentChangedEvent(SiteId, channelId); + } + } + } + + LayerUtils.CloseAndRedirect(Page, _returnUrl); + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/ModalContentCrossSiteTrans.cs b/net452/SiteServer.BackgroundPages/Cms/ModalContentCrossSiteTrans.cs new file mode 100644 index 000000000..3ecd79d2a --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/ModalContentCrossSiteTrans.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class ModalContentCrossSiteTrans : BasePageCms + { + protected DropDownList DdlSiteId; + protected ListBox LbChannelId; + + private int _channelId; + private List _contentIdList; + + public static string GetOpenWindowString(int siteId, int channelId) + { + return LayerUtils.GetOpenScriptWithCheckBoxValue("跨站转发", FxUtils.GetCmsUrl(siteId, nameof(ModalContentCrossSiteTrans), new NameValueCollection + { + {"channelId", channelId.ToString()} + }), "contentIdCollection", "请选择需要转发的内容!", 400, 410); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "channelId", "contentIdCollection"); + + _channelId = AuthRequest.GetQueryInt("channelId"); + _contentIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("contentIdCollection")); + + if (IsPostBack) return; + + SystemWebUtils.LoadSiteIdDropDownList(DdlSiteId, SiteInfo, _channelId); + + if (DdlSiteId.Items.Count > 0) + { + DdlSiteId_SelectedIndexChanged(null, EventArgs.Empty); + } + } + + public void DdlSiteId_SelectedIndexChanged(object sender, EventArgs e) + { + var psId = int.Parse(DdlSiteId.SelectedValue); + SystemWebUtils.LoadChannelIdListBox(LbChannelId, SiteInfo, psId, ChannelManager.GetChannelInfo(SiteId, _channelId), AuthRequest.AdminPermissionsImpl); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + var targetSiteId = int.Parse(DdlSiteId.SelectedValue); + var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); + try + { + foreach (ListItem listItem in LbChannelId.Items) + { + if (listItem.Selected) + { + var targetChannelId = TranslateUtils.ToInt(listItem.Value); + if (targetChannelId != 0) + { + var targetChannelInfo = ChannelManager.GetChannelInfo(targetSiteId, targetChannelId); + var targetTableName = ChannelManager.GetTableName(targetSiteInfo, targetChannelId); + foreach (var contentId in _contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(SiteInfo, _channelId, contentId); + FileUtility.MoveFileByContentInfo(SiteInfo, targetSiteInfo, contentInfo); + contentInfo.SiteId = targetSiteId; + contentInfo.SourceId = contentInfo.ChannelId; + contentInfo.ChannelId = targetChannelId; + + contentInfo.Checked = targetSiteInfo.IsCrossSiteTransChecked; + contentInfo.CheckedLevel = 0; + + DataProvider.ContentRepository.Insert(targetTableName, targetSiteInfo, targetChannelInfo, contentInfo); + } + } + } + } + + AuthRequest.AddSiteLog(SiteId, _channelId, 0, "跨站转发", string.Empty); + + SuccessMessage("内容转发成功,请选择后续操作。"); + } + catch (Exception ex) + { + FailMessage(ex, "内容转发失败!"); + } + + LayerUtils.Close(Page); + } + + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/ModalContentExport.cs b/net452/SiteServer.BackgroundPages/Cms/ModalContentExport.cs new file mode 100644 index 000000000..fd6a0e0d6 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/ModalContentExport.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Controls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class ModalContentExport : BasePageCms + { + public DropDownList DdlExportType; + public DropDownList DdlPeriods; + public DateTimeTextBox TbStartDate; + public DateTimeTextBox TbEndDate; + public PlaceHolder PhDisplayAttributes; + public CheckBoxList CblDisplayAttributes; + public DropDownList DdlIsChecked; + + private int _channelId; + + public static string GetOpenWindowString(int siteId, int channelId) + { + return LayerUtils.GetOpenScriptWithCheckBoxValue("导出内容", + FxUtils.GetCmsUrl(siteId, nameof(ModalContentExport), new NameValueCollection + { + {"channelId", channelId.ToString()} + }), "contentIdCollection", string.Empty); + } + + private void LoadDisplayAttributeCheckBoxList() + { + var nodeInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); + var styleInfoList = ContentUtility.GetAllTableStyleInfoList(TableStyleManager.GetContentStyleInfoList(SiteInfo, nodeInfo)); + + foreach (var styleInfo in styleInfoList) + { + var listItem = new ListItem(styleInfo.DisplayName, styleInfo.AttributeName) + { + Selected = true + }; + CblDisplayAttributes.Items.Add(listItem); + } + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + _channelId = AuthRequest.GetQueryInt("channelId", SiteId); + if (IsPostBack) return; + + LoadDisplayAttributeCheckBoxList(); + ConfigSettings(true); + } + + private void ConfigSettings(bool isLoad) + { + if (isLoad) + { + if (!string.IsNullOrEmpty(SiteInfo.ConfigExportType)) + { + DdlExportType.SelectedValue = SiteInfo.ConfigExportType; + } + if (!string.IsNullOrEmpty(SiteInfo.ConfigExportPeriods)) + { + DdlPeriods.SelectedValue = SiteInfo.ConfigExportPeriods; + } + if (!string.IsNullOrEmpty(SiteInfo.ConfigExportDisplayAttributes)) + { + var displayAttributes = TranslateUtils.StringCollectionToStringList(SiteInfo.ConfigExportDisplayAttributes); + SystemWebUtils.SelectMultiItems(CblDisplayAttributes, displayAttributes); + } + if (!string.IsNullOrEmpty(SiteInfo.ConfigExportIsChecked)) + { + DdlIsChecked.SelectedValue = SiteInfo.ConfigExportIsChecked; + } + } + else + { + SiteInfo.ConfigExportType = DdlExportType.SelectedValue; + SiteInfo.ConfigExportPeriods = DdlPeriods.SelectedValue; + SiteInfo.ConfigExportDisplayAttributes = SystemWebUtils.GetSelectedListControlValueCollection(CblDisplayAttributes); + SiteInfo.ConfigExportIsChecked = DdlIsChecked.SelectedValue; + DataProvider.Site.Update(SiteInfo); + } + } + + public void DdlExportType_SelectedIndexChanged(object sender, EventArgs e) + { + PhDisplayAttributes.Visible = DdlExportType.SelectedValue != "ContentZip"; + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + var displayAttributes = SystemWebUtils.GetSelectedListControlValueCollection(CblDisplayAttributes); + if (PhDisplayAttributes.Visible && string.IsNullOrEmpty(displayAttributes)) + { + FailMessage("必须至少选择一项!"); + return; + } + + ConfigSettings(false); + + var isPeriods = false; + var startDate = string.Empty; + var endDate = string.Empty; + if (DdlPeriods.SelectedValue != "0") + { + isPeriods = true; + if (DdlPeriods.SelectedValue == "-1") + { + startDate = TbStartDate.Text; + endDate = TbEndDate.Text; + } + else + { + var days = int.Parse(DdlPeriods.SelectedValue); + startDate = DateUtils.GetDateString(DateTime.Now.AddDays(-days)); + endDate = DateUtils.GetDateString(DateTime.Now); + } + } + var checkedState = ETriStateUtils.GetEnumType(DdlPeriods.SelectedValue); + var redirectUrl = ModalExportMessage.GetRedirectUrlStringToExportContent(SiteId, _channelId, DdlExportType.SelectedValue, AuthRequest.GetQueryString("contentIdCollection"), displayAttributes, isPeriods, startDate, endDate, checkedState); + WebPageUtils.Redirect(redirectUrl); + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/ModalContentGroupAdd.cs b/net452/SiteServer.BackgroundPages/Cms/ModalContentGroupAdd.cs new file mode 100644 index 000000000..94886fcf3 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/ModalContentGroupAdd.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class ModalContentGroupAdd : BasePageCms + { + protected TextBox TbContentGroupName; + public Literal LtlContentGroupName; + protected TextBox TbDescription; + + public static string GetOpenWindowString(int siteId, string groupName) + { + return LayerUtils.GetOpenScript("修改内容组", FxUtils.GetCmsUrl(siteId, nameof(ModalContentGroupAdd), new NameValueCollection + { + {"GroupName", groupName} + }), 600, 300); + } + + public static string GetOpenWindowString(int siteId) + { + return LayerUtils.GetOpenScript("添加内容组", FxUtils.GetCmsUrl(siteId, nameof(ModalContentGroupAdd), null), 600, 300); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + if (!IsPostBack) + { + if (AuthRequest.IsQueryExists("GroupName")) + { + var groupName = AuthRequest.GetQueryString("GroupName"); + var contentGroupInfo = ContentGroupManager.GetContentGroupInfo(SiteId, groupName); + if (contentGroupInfo != null) + { + TbContentGroupName.Text = contentGroupInfo.GroupName; + TbContentGroupName.Visible = false; + LtlContentGroupName.Text = $"{contentGroupInfo.GroupName}"; + TbDescription.Text = contentGroupInfo.Description; + } + } + } + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + var isChanged = false; + + var contentGroupInfo = new ContentGroupInfo + { + GroupName = AttackUtils.FilterXss(TbContentGroupName.Text), + SiteId = SiteId, + Description = TbDescription.Text + }; + + if (AuthRequest.IsQueryExists("GroupName")) + { + try + { + DataProvider.ContentGroup.Update(contentGroupInfo); + AuthRequest.AddSiteLog(SiteId, "修改内容组", $"内容组:{contentGroupInfo.GroupName}"); + isChanged = true; + } + catch (Exception ex) + { + FailMessage(ex, "内容组修改失败!"); + } + } + else + { + if (ContentGroupManager.IsExists(SiteId, TbContentGroupName.Text)) + { + FailMessage("内容组添加失败,内容组名称已存在!"); + } + else + { + try + { + DataProvider.ContentGroup.Insert(contentGroupInfo); + AuthRequest.AddSiteLog(SiteId, "添加内容组", + $"内容组:{contentGroupInfo.GroupName}"); + isChanged = true; + } + catch(Exception ex) + { + FailMessage(ex, "内容组添加失败!"); + } + } + } + + if (isChanged) + { + LayerUtils.Close(Page); + } + } + } +} diff --git a/SiteServer.BackgroundPages/Cms/ModalContentImport.cs b/net452/SiteServer.BackgroundPages/Cms/ModalContentImport.cs similarity index 91% rename from SiteServer.BackgroundPages/Cms/ModalContentImport.cs rename to net452/SiteServer.BackgroundPages/Cms/ModalContentImport.cs index b9696ea85..0cd513b81 100644 --- a/SiteServer.BackgroundPages/Cms/ModalContentImport.cs +++ b/net452/SiteServer.BackgroundPages/Cms/ModalContentImport.cs @@ -2,8 +2,12 @@ using System.Collections.Specialized; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; using SiteServer.CMS.ImportExport; using SiteServer.Utils.Enumerations; @@ -23,7 +27,7 @@ public class ModalContentImport : BasePageCms public static string GetOpenWindowString(int siteId, int channelId) { return LayerUtils.GetOpenScript("导入内容", - PageUtils.GetCmsUrl(siteId, nameof(ModalContentImport), new NameValueCollection + FxUtils.GetCmsUrl(siteId, nameof(ModalContentImport), new NameValueCollection { {"channelId", channelId.ToString()} }), 0, 520); @@ -37,8 +41,8 @@ public void Page_Load(object sender, EventArgs e) if (IsPostBack) return; int checkedLevel; - var isChecked = CheckManager.GetUserCheckLevel(AuthRequest.AdminPermissions, SiteInfo, SiteId, out checkedLevel); - CheckManager.LoadContentLevelToEdit(DdlContentLevel, SiteInfo, _channelId, null, isChecked, checkedLevel); + var isChecked = CheckManager.GetUserCheckLevel(AuthRequest.AdminPermissionsImpl, SiteInfo, SiteId, out checkedLevel); + SystemWebUtils.LoadContentLevelToCheckEdit(DdlContentLevel, SiteInfo, null, isChecked, checkedLevel); } public override void Submit_OnClick(object sender, EventArgs e) @@ -46,8 +50,8 @@ public override void Submit_OnClick(object sender, EventArgs e) if (HifFile.PostedFile == null || "" == HifFile.PostedFile.FileName) return; var isChecked = false; - var checkedLevel = TranslateUtils.ToIntWithNagetive(DdlContentLevel.SelectedValue); - if (checkedLevel >= SiteInfo.Additional.CheckContentLevel) + var checkedLevel = TranslateUtils.ToIntWithNegative(DdlContentLevel.SelectedValue); + if (checkedLevel >= SiteInfo.CheckContentLevel) { isChecked = true; } diff --git a/net452/SiteServer.BackgroundPages/Cms/ModalContentMultipleSelect.cs b/net452/SiteServer.BackgroundPages/Cms/ModalContentMultipleSelect.cs new file mode 100644 index 000000000..a1dbe2fa8 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/ModalContentMultipleSelect.cs @@ -0,0 +1,193 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Data; +using System.Text; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Controls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class ModalContentMultipleSelect : BasePageCms + { + public DropDownList DdlChannelId; + public DropDownList DdlSearchType; + public TextBox TbKeyword; + public DateTimeTextBox TbDateFrom; + public DateTimeTextBox TbDateTo; + + public Repeater RptContents; + public SqlPager SpContents; + + private ChannelInfo _channelInfo; + private List _tableStyleInfoList; + private string _jsMethod; + private readonly Hashtable _valueHashtable = new Hashtable(); + + public static string GetOpenWindowString(int siteId, string jsMethod) + { + return LayerUtils.GetOpenScript("选择内容", FxUtils.GetCmsUrl(siteId, nameof(ModalContentMultipleSelect), new NameValueCollection + { + {"jsMethod", jsMethod} + })); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + _jsMethod = AuthRequest.GetQueryString("jsMethod"); + + WebPageUtils.CheckRequestParameter("siteId"); + var channelId = AuthRequest.GetQueryInt("channelId"); + if (channelId == 0) + { + channelId = SiteId; + } + _channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + var tableName = ChannelManager.GetTableName(SiteInfo, _channelInfo); + _tableStyleInfoList = TableStyleManager.GetContentStyleInfoList(SiteInfo, _channelInfo); + + SpContents.ControlToPaginate = RptContents; + SpContents.SelectCommand = string.IsNullOrEmpty(AuthRequest.GetQueryString("channelId")) + ? DataProvider.ContentRepository.GetSqlString(tableName, SiteId, + _channelInfo.Id, AuthRequest.AdminPermissionsImpl.IsSystemAdministrator, + AuthRequest.AdminPermissionsImpl.ChannelIdList, DdlSearchType.SelectedValue, TbKeyword.Text, + TbDateFrom.Text, TbDateTo.Text, true, ETriState.True, false) + : DataProvider.ContentRepository.GetSqlString(tableName, SiteId, + _channelInfo.Id, AuthRequest.AdminPermissionsImpl.IsSystemAdministrator, + AuthRequest.AdminPermissionsImpl.ChannelIdList, AuthRequest.GetQueryString("SearchType"), + AuthRequest.GetQueryString("Keyword"), AuthRequest.GetQueryString("DateFrom"), AuthRequest.GetQueryString("DateTo"), true, + ETriState.True, true); + SpContents.ItemsPerPage = SiteInfo.PageSize; + SpContents.SortField = ContentAttribute.Id; + SpContents.SortMode = SortMode.DESC; + SpContents.OrderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByIdDesc); + RptContents.ItemDataBound += RptContents_ItemDataBound; + + if (IsPostBack) return; + + SystemWebUtils.AddListItemsForChannel(DdlChannelId.Items, SiteInfo, false, true, AuthRequest.AdminPermissionsImpl); + + if (_tableStyleInfoList != null) + { + foreach (var styleInfo in _tableStyleInfoList) + { + var listitem = new ListItem(styleInfo.DisplayName, styleInfo.AttributeName); + DdlSearchType.Items.Add(listitem); + } + } + + //添加隐藏属性 + DdlSearchType.Items.Add(new ListItem("内容ID", ContentAttribute.Id)); + DdlSearchType.Items.Add(new ListItem("添加者", ContentAttribute.AddUserName)); + DdlSearchType.Items.Add(new ListItem("最后修改者", ContentAttribute.LastEditUserName)); + + if (AuthRequest.IsQueryExists("channelId")) + { + if (SiteId != _channelInfo.Id) + { + SystemWebUtils.SelectSingleItem(DdlChannelId, _channelInfo.Id.ToString()); + } + SystemWebUtils.SelectSingleItem(DdlSearchType, AuthRequest.GetQueryString("SearchType")); + TbKeyword.Text = AuthRequest.GetQueryString("Keyword"); + TbDateFrom.Text = AuthRequest.GetQueryString("DateFrom"); + TbDateTo.Text = AuthRequest.GetQueryString("DateTo"); + } + + SpContents.DataBind(); + } + + private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) + { + var ltlChannel = (Literal)e.Item.FindControl("ltlChannel"); + var ltlTitle = (Literal)e.Item.FindControl("ltlTitle"); + var ltlSelect = (Literal)e.Item.FindControl("ltlSelect"); + + var dataRowView = (DataRowView) e.Item.DataItem; + var contentInfo = new ContentInfo(TranslateUtils.ToDictionary(dataRowView)); + + var nodeName = _valueHashtable[contentInfo.ChannelId] as string; + if (nodeName == null) + { + nodeName = ChannelManager.GetChannelNameNavigation(SiteId, contentInfo.ChannelId); + _valueHashtable[contentInfo.ChannelId] = nodeName; + } + ltlChannel.Text = nodeName; + + ltlTitle.Text = WebUtils.GetContentTitle(SiteInfo, contentInfo, PageUrl); + + ltlSelect.Text = + $@""; + } + } + + public void AddContent_OnClick(object sender, EventArgs e) + { + WebPageUtils.Redirect(WebUtils.GetContentAddAddUrl(SiteId, _channelInfo, PageUrl)); + } + + public void Search_OnClick(object sender, EventArgs e) + { + Response.Redirect(PageUrl, true); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!string.IsNullOrEmpty(Request.Form["IDsCollection"])) + { + var builder = new StringBuilder(); + foreach (var pair in TranslateUtils.StringCollectionToStringList(Request.Form["IDsCollection"])) + { + var channelId = TranslateUtils.ToInt(pair.Split('_')[0]); + var contentId = TranslateUtils.ToInt(pair.Split('_')[1]); + + //var tableName = ChannelManager.GetTableName(SiteInfo, channelId); + + var channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + + var title = channelInfo.ContentRepository.GetValue(contentId, ContentAttribute.Title); + builder.Append($@"parent.{_jsMethod}('{title}', '{pair}');"); + } + LayerUtils.CloseWithoutRefresh(Page, builder.ToString()); + } + else + { + LayerUtils.CloseWithoutRefresh(Page); + } + } + + private string _pageUrl; + private string PageUrl + { + get + { + if (string.IsNullOrEmpty(_pageUrl)) + { + _pageUrl = FxUtils.GetCmsUrl(SiteId, nameof(ModalContentMultipleSelect), new NameValueCollection + { + {"channelId", DdlChannelId.SelectedValue}, + {"SearchType", DdlSearchType.SelectedValue}, + {"Keyword", TbKeyword.Text}, + {"DateFrom", TbDateFrom.Text}, + {"DateTo", TbDateTo.Text} + }); + } + return _pageUrl; + } + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/ModalContentTagAdd.cs b/net452/SiteServer.BackgroundPages/Cms/ModalContentTagAdd.cs new file mode 100644 index 000000000..7bbf42c19 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/ModalContentTagAdd.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class ModalContentTagAdd : BasePageCms + { + protected TextBox TbTags; + + private string _tagName; + + public static string GetOpenWindowStringToAdd(int siteId) + { + return LayerUtils.GetOpenScript("添加标签", FxUtils.GetCmsUrl(siteId, nameof(ModalContentTagAdd), null), 600, 360); + } + + public static string GetOpenWindowStringToEdit(int siteId, string tagName) + { + return LayerUtils.GetOpenScript("修改标签", FxUtils.GetCmsUrl(siteId, nameof(ModalContentTagAdd), new NameValueCollection + { + {"TagName", tagName} + }), 600, 360); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + _tagName = AuthRequest.GetQueryString("TagName"); + + if (IsPostBack) return; + + if (!string.IsNullOrEmpty(_tagName)) + { + TbTags.Text = _tagName; + + var count = DataProvider.Tag.GetTagCount(_tagName, SiteId); + + InfoMessage($@"标签“{_tagName}”被使用 {count} 次,编辑此标签将更新所有使用此标签的内容。"); + } + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + var isChanged = false; + + if (!string.IsNullOrEmpty(_tagName)) + { + try + { + if (!string.Equals(_tagName, TbTags.Text)) + { + var tagCollection = TagUtils.ParseTagsString(TbTags.Text); + var contentIdList = DataProvider.Tag.GetContentIdListByTag(_tagName, SiteId); + if (contentIdList.Count > 0) + { + foreach (var contentId in contentIdList) + { + if (!tagCollection.Contains(_tagName))//删除 + { + var tagInfo = DataProvider.Tag.GetTagInfo(SiteId, _tagName); + if (tagInfo != null) + { + var idArrayList = TranslateUtils.StringCollectionToIntList(tagInfo.ContentIdCollection); + idArrayList.Remove(contentId); + tagInfo.ContentIdCollection = TranslateUtils.ObjectCollectionToString(idArrayList); + tagInfo.UseNum = idArrayList.Count; + DataProvider.Tag.Update(tagInfo); + } + } + + TagUtils.AddTags(tagCollection, SiteId, contentId); + + if (!SiteInfo.ContentRepository.GetChanelIdAndValue(contentId, ContentAttribute.Tags, + out var channelId, out var tags)) continue; + + var contentTagList = TranslateUtils.StringCollectionToStringList(tags); + contentTagList.Remove(_tagName); + foreach (var theTag in tagCollection) + { + if (!contentTagList.Contains(theTag)) + { + contentTagList.Add(theTag); + } + } + + SiteInfo.ContentRepository.Update(channelId, contentId, ContentAttribute.Tags, + TranslateUtils.ObjectCollectionToString(contentTagList)); + } + } + else + { + DataProvider.Tag.DeleteTag(_tagName, SiteId); + } + } + + AuthRequest.AddSiteLog(SiteId, "修改内容标签", $"内容标签:{TbTags.Text}"); + + isChanged = true; + } + catch(Exception ex) + { + FailMessage(ex, "标签修改失败!"); + } + } + else + { + try + { + var tagCollection = TagUtils.ParseTagsString(TbTags.Text); + TagUtils.AddTags(tagCollection, SiteId, 0); + AuthRequest.AddSiteLog(SiteId, "添加内容标签", $"内容标签:{TbTags.Text}"); + isChanged = true; + } + catch(Exception ex) + { + FailMessage(ex, "标签添加失败!"); + } + } + + if (isChanged) + { + LayerUtils.Close(Page); + } + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/ModalContentTaxis.cs b/net452/SiteServer.BackgroundPages/Cms/ModalContentTaxis.cs new file mode 100644 index 000000000..8a3514ac8 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/ModalContentTaxis.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class ModalContentTaxis : BasePageCms + { + protected DropDownList DdlTaxisType; + protected TextBox TbTaxisNum; + + private int _channelId; + private string _returnUrl; + private List _contentIdList; + private string _tableName; + private ChannelInfo _channelInfo; + + public static string GetOpenWindowString(int siteId, int channelId, string returnUrl) + { + return LayerUtils.GetOpenScriptWithCheckBoxValue("内容排序", FxUtils.GetCmsUrl(siteId, nameof(ModalContentTaxis), new NameValueCollection + { + {"channelId", channelId.ToString()}, + {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} + }), "contentIdCollection", "请选择需要排序的内容!", 400, 280); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "channelId", "ReturnUrl", "contentIdCollection"); + + _channelId = AuthRequest.GetQueryInt("channelId"); + _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); + _contentIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("contentIdCollection")); + _tableName = ChannelManager.GetTableName(SiteInfo, _channelId); + _channelInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); + + if (IsPostBack) return; + + DdlTaxisType.Items.Add(new ListItem("上升", "Up")); + DdlTaxisType.Items.Add(new ListItem("下降", "Down")); + SystemWebUtils.SelectSingleItem(DdlTaxisType, "Up"); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + var isUp = DdlTaxisType.SelectedValue == "Up"; + var taxisNum = TranslateUtils.ToInt(TbTaxisNum.Text); + + var channelInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); + if (ETaxisTypeUtils.Equals(channelInfo.DefaultTaxisType, ETaxisType.OrderByTaxis)) + { + isUp = !isUp; + } + + if (isUp == false) + { + _contentIdList.Reverse(); + } + + foreach (var contentId in _contentIdList) + { + if (!_channelInfo.ContentRepository.GetChanelIdAndValue(contentId, ContentAttribute.IsTop, + out var channelId, out string value)) continue; + + var isTop = TranslateUtils.ToBool(value); + for (var i = 1; i <= taxisNum; i++) + { + if (isUp) + { + if (channelInfo.ContentRepository.SetTaxisToUp(channelId, contentId, isTop) == false) + { + break; + } + } + else + { + if (channelInfo.ContentRepository.SetTaxisToDown(channelId, contentId, isTop) == false) + { + break; + } + } + } + } + + CreateManager.TriggerContentChangedEvent(SiteId, _channelId); + AuthRequest.AddSiteLog(SiteId, _channelId, 0, "对内容排序", string.Empty); + + LayerUtils.CloseAndRedirect(Page, _returnUrl); + } + + } +} diff --git a/SiteServer.BackgroundPages/Cms/ModalContentTidyUp.cs b/net452/SiteServer.BackgroundPages/Cms/ModalContentTidyUp.cs similarity index 81% rename from SiteServer.BackgroundPages/Cms/ModalContentTidyUp.cs rename to net452/SiteServer.BackgroundPages/Cms/ModalContentTidyUp.cs index d209a0c12..786591c1c 100644 --- a/SiteServer.BackgroundPages/Cms/ModalContentTidyUp.cs +++ b/net452/SiteServer.BackgroundPages/Cms/ModalContentTidyUp.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Specialized; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Fx; using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; namespace SiteServer.BackgroundPages.Cms { @@ -12,12 +14,11 @@ public class ModalContentTidyUp : BasePageCms public DropDownList DdlAttributeName; public DropDownList DdlIsDesc; - private string _tableName; private string _returnUrl; public static string GetOpenWindowString(int siteId, int channelId, string returnUrl) { - return LayerUtils.GetOpenScriptWithCheckBoxValue("整理排序", PageUtils.GetCmsUrl(siteId, nameof(ModalContentTidyUp), new NameValueCollection + return LayerUtils.GetOpenScriptWithCheckBoxValue("整理排序", FxUtils.GetCmsUrl(siteId, nameof(ModalContentTidyUp), new NameValueCollection { {"channelId", channelId.ToString()}, {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} @@ -46,9 +47,8 @@ public override void Submit_OnClick(object sender, EventArgs e) { var channelId = AuthRequest.GetQueryInt("channelId"); var channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - _tableName = ChannelManager.GetTableName(SiteInfo, channelInfo); - DataProvider.ContentDao.TidyUp(_tableName, channelId, DdlAttributeName.SelectedValue, TranslateUtils.ToBool(DdlIsDesc.SelectedValue)); + channelInfo.ContentRepository.UpdateArrangeTaxis(channelId, DdlAttributeName.SelectedValue, TranslateUtils.ToBool(DdlIsDesc.SelectedValue)); LayerUtils.CloseAndRedirect(Page, _returnUrl); } diff --git a/net452/SiteServer.BackgroundPages/Cms/ModalContentView.cs b/net452/SiteServer.BackgroundPages/Cms/ModalContentView.cs new file mode 100644 index 000000000..c6a945fbd --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/ModalContentView.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class ModalContentView : BasePageCms + { + public Literal LtlScripts; + public Literal LtlTitle; + public Literal LtlChannelName; + public Literal LtlContentGroup; + public Literal LtlTags; + public Literal LtlLastEditDate; + public Literal LtlAddUserName; + public Literal LtlLastEditUserName; + public Literal LtlContentLevel; + public Repeater RptContents; + public PlaceHolder PhTags; + public PlaceHolder PhContentGroup; + + private int _channelId; + private int _contentId; + private string _returnUrl; + private ContentInfo _contentInfo; + + public static string GetOpenWindowString(int siteId, int channelId, int contentId, string returnUrl) + { + return LayerUtils.GetOpenScript("查看内容", FxUtils.GetCmsUrl(siteId, nameof(ModalContentView), new NameValueCollection + { + {"channelId", channelId.ToString()}, + {"id", contentId.ToString()}, + {"returnUrl", StringUtils.ValueToUrl(returnUrl)} + })); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "channelId", "id", "ReturnUrl"); + + _channelId = AuthRequest.GetQueryInt("channelId"); + if (_channelId < 0) _channelId = -_channelId; + + var channelInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); + _contentId = AuthRequest.GetQueryInt("id"); + _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("returnUrl")); + + _contentInfo = ContentManager.GetContentInfo(SiteInfo, channelInfo, _contentId); + + if (IsPostBack) return; + + var styleInfoList = TableStyleManager.GetContentStyleInfoList(SiteInfo, channelInfo); + + RptContents.DataSource = styleInfoList; + RptContents.ItemDataBound += RptContents_ItemDataBound; + RptContents.DataBind(); + + LtlTitle.Text = _contentInfo.Title; + LtlChannelName.Text = channelInfo.ChannelName; + + LtlTags.Text = _contentInfo.Tags; + if (string.IsNullOrEmpty(LtlTags.Text)) + { + PhTags.Visible = false; + } + + LtlContentGroup.Text = _contentInfo.GroupNameCollection; + if (string.IsNullOrEmpty(LtlContentGroup.Text)) + { + PhContentGroup.Visible = false; + } + + LtlLastEditDate.Text = DateUtils.GetDateAndTimeString(_contentInfo.LastEditDate); + LtlAddUserName.Text = AdminManager.GetDisplayName(_contentInfo.AddUserName, true); + LtlLastEditUserName.Text = AdminManager.GetDisplayName(_contentInfo.LastEditUserName, true); + + LtlContentLevel.Text = CheckManager.GetCheckState(SiteInfo, _contentInfo); + + if (_contentInfo.ReferenceId > 0 && _contentInfo.Get(ContentAttribute.TranslateContentType) != ETranslateContentType.ReferenceContent.ToString()) + { + var referenceSiteId = DataProvider.Channel.GetSiteId(_contentInfo.SourceId); + var referenceSiteInfo = SiteManager.GetSiteInfo(referenceSiteId); + var referenceContentInfo = ContentManager.GetContentInfo(referenceSiteInfo, _contentInfo.SourceId, _contentInfo.ReferenceId); + + if (referenceContentInfo != null) + { + var pageUrl = PageUtility.GetContentUrl(referenceSiteInfo, referenceContentInfo, true); + var referenceNodeInfo = ChannelManager.GetChannelInfo(referenceContentInfo.SiteId, referenceContentInfo.ChannelId); + var addEditUrl = + WebUtils.GetContentAddEditUrl(referenceSiteInfo.Id, + referenceNodeInfo, _contentInfo.ReferenceId, AuthRequest.GetQueryString("ReturnUrl")); + + LtlScripts.Text += $@" +
    此内容为对内容 (站点:{referenceSiteInfo.SiteName},栏目:{referenceNodeInfo.ChannelName})“{_contentInfo.Title}”(编辑) 的引用,内容链接将和原始内容链接一致
    "; + } + } + } + + private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var styleInfo = (TableStyleInfo)e.Item.DataItem; + + var inputHtml = InputParserUtility.GetContentByTableStyle(_contentInfo.Get(styleInfo.AttributeName), SiteInfo, styleInfo); + + var ltlHtml = (Literal)e.Item.FindControl("ltlHtml"); + + ltlHtml.Text = $@" +
    + +
    + {inputHtml} +
    +
    +
    +"; + } + + public string ReturnUrl => _returnUrl; + } +} diff --git a/SiteServer.BackgroundPages/Cms/ModalCreateChannels.cs b/net452/SiteServer.BackgroundPages/Cms/ModalCreateChannels.cs similarity index 84% rename from SiteServer.BackgroundPages/Cms/ModalCreateChannels.cs rename to net452/SiteServer.BackgroundPages/Cms/ModalCreateChannels.cs index 89699a4bf..070733d5f 100644 --- a/SiteServer.BackgroundPages/Cms/ModalCreateChannels.cs +++ b/net452/SiteServer.BackgroundPages/Cms/ModalCreateChannels.cs @@ -1,8 +1,11 @@ using System; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; using SiteServer.Utils; -using SiteServer.CMS.Core; using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Cms @@ -16,14 +19,14 @@ public class ModalCreateChannels : BasePageCms public static string GetOpenWindowString(int siteId) { - return LayerUtils.GetOpenScriptWithCheckBoxValue("生成栏目页", PageUtils.GetCmsUrl(siteId, nameof(ModalCreateChannels), null), "ChannelIDCollection", "请选择需要生成页面的栏目!", 550, 300); + return LayerUtils.GetOpenScriptWithCheckBoxValue("生成栏目页", FxUtils.GetCmsUrl(siteId, nameof(ModalCreateChannels), null), "ChannelIDCollection", "请选择需要生成页面的栏目!", 550, 300); } public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId", "ChannelIDCollection"); + WebPageUtils.CheckRequestParameter("siteId", "ChannelIDCollection"); _channelIdCollection = AuthRequest.GetQueryString("ChannelIDCollection"); } diff --git a/SiteServer.BackgroundPages/Cms/ModalCreateDirectory.cs b/net452/SiteServer.BackgroundPages/Cms/ModalCreateDirectory.cs similarity index 82% rename from SiteServer.BackgroundPages/Cms/ModalCreateDirectory.cs rename to net452/SiteServer.BackgroundPages/Cms/ModalCreateDirectory.cs index f84b2068a..23a349340 100644 --- a/SiteServer.BackgroundPages/Cms/ModalCreateDirectory.cs +++ b/net452/SiteServer.BackgroundPages/Cms/ModalCreateDirectory.cs @@ -1,8 +1,11 @@ using System; using System.Collections.Specialized; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Cms { @@ -15,7 +18,7 @@ public class ModalCreateDirectory : BasePageCms public static string GetOpenWindowString(int siteId, string currentRootPath) { - return LayerUtils.GetOpenScript("创建文件夹", PageUtils.GetCmsUrl(siteId, nameof(ModalCreateDirectory), new NameValueCollection + return LayerUtils.GetOpenScript("创建文件夹", FxUtils.GetCmsUrl(siteId, nameof(ModalCreateDirectory), new NameValueCollection { {"CurrentRootPath", currentRootPath} }), 400, 250); @@ -25,7 +28,7 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId", "CurrentRootPath"); + WebPageUtils.CheckRequestParameter("siteId", "CurrentRootPath"); _currentRootPath = AuthRequest.GetQueryString("CurrentRootPath").TrimEnd('/'); _directoryPath = PathUtility.MapPath(SiteInfo, _currentRootPath); diff --git a/net452/SiteServer.BackgroundPages/Cms/ModalCrossSiteTransEdit.cs b/net452/SiteServer.BackgroundPages/Cms/ModalCrossSiteTransEdit.cs new file mode 100644 index 000000000..ba4fb014d --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/ModalCrossSiteTransEdit.cs @@ -0,0 +1,191 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class ModalCrossSiteTransEdit : BasePageCms + { + public DropDownList DdlTransType; + public PlaceHolder PhSite; + public DropDownList DdlSiteId; + public ListBox LbChannelId; + public PlaceHolder PhNodeNames; + public TextBox TbNodeNames; + public PlaceHolder PhIsAutomatic; + public DropDownList DdlIsAutomatic; + public DropDownList DdlTranslateDoneType; + + private ChannelInfo _channelInfo; + + public static string GetOpenWindowString(int siteId, int channelId) + { + return LayerUtils.GetOpenScript("跨站转发设置", FxUtils.GetCmsUrl(siteId, nameof(ModalCrossSiteTransEdit), new NameValueCollection + { + {"channelId", channelId.ToString()} + })); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "channelId"); + var channelId = int.Parse(AuthRequest.GetQueryString("channelId")); + _channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + + if (IsPostBack) return; + + SystemWebUtils.AddAllListItemsToECrossSiteTransType(DdlTransType, SiteInfo.ParentId > 0); + + SystemWebUtils.SelectSingleItem(DdlTransType, _channelInfo.TransType); + + DdlTransType_OnSelectedIndexChanged(null, EventArgs.Empty); + SystemWebUtils.SelectSingleItem(DdlSiteId, _channelInfo.TransSiteId.ToString()); + + + DdlSiteId_OnSelectedIndexChanged(null, EventArgs.Empty); + SystemWebUtils.SelectMultiItems(LbChannelId, TranslateUtils.StringCollectionToStringList(_channelInfo.TransChannelIds)); + TbNodeNames.Text = _channelInfo.TransChannelNames; + + FxUtils.AddListItems(DdlIsAutomatic, "系统自动转发", "需手动操作"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsAutomatic, _channelInfo.TransIsAutomatic.ToString()); + + SystemWebUtils.AddListItemsToETranslateContentType(DdlTranslateDoneType, false); + SystemWebUtils.SelectSingleItem(DdlTranslateDoneType, _channelInfo.TransDoneType); + } + + protected void DdlTransType_OnSelectedIndexChanged(object sender, EventArgs e) + { + DdlSiteId.Items.Clear(); + DdlSiteId.Enabled = true; + + PhIsAutomatic.Visible = false; + + var contributeType = ECrossSiteTransTypeUtils.GetEnumType(DdlTransType.SelectedValue); + if (contributeType == ECrossSiteTransType.None) + { + PhSite.Visible = PhNodeNames.Visible = false; + } + else if (contributeType == ECrossSiteTransType.SelfSite || contributeType == ECrossSiteTransType.SpecifiedSite) + { + PhSite.Visible = true; + PhNodeNames.Visible = false; + + PhIsAutomatic.Visible = true; + } + else if (contributeType == ECrossSiteTransType.ParentSite) + { + PhSite.Visible = true; + PhNodeNames.Visible = false; + DdlSiteId.Enabled = false; + + PhIsAutomatic.Visible = true; + } + else if (contributeType == ECrossSiteTransType.AllParentSite || contributeType == ECrossSiteTransType.AllSite) + { + PhSite.Visible = false; + PhNodeNames.Visible = true; + } + + if (PhSite.Visible) + { + var siteIdList = SiteManager.GetSiteIdList(); + + var allParentSiteIdList = new List(); + if (contributeType == ECrossSiteTransType.AllParentSite) + { + SiteManager.GetAllParentSiteIdList(allParentSiteIdList, siteIdList, SiteId); + } + else if (contributeType == ECrossSiteTransType.SelfSite) + { + siteIdList = new List + { + SiteId + }; + } + + foreach (var psId in siteIdList) + { + var psInfo = SiteManager.GetSiteInfo(psId); + var show = false; + if (contributeType == ECrossSiteTransType.SpecifiedSite) + { + show = true; + } + else if (contributeType == ECrossSiteTransType.SelfSite) + { + if (psId == SiteId) + { + show = true; + } + } + else if (contributeType == ECrossSiteTransType.ParentSite) + { + if (psInfo.Id == SiteInfo.ParentId || (SiteInfo.ParentId == 0 && psInfo.Root)) + { + show = true; + } + } + if (!show) continue; + + var listitem = new ListItem(psInfo.SiteName, psId.ToString()); + if (psInfo.Root) listitem.Selected = true; + DdlSiteId.Items.Add(listitem); + } + } + DdlSiteId_OnSelectedIndexChanged(sender, e); + } + + protected void DdlSiteId_OnSelectedIndexChanged(object sender, EventArgs e) + { + LbChannelId.Items.Clear(); + if (PhSite.Visible && DdlSiteId.Items.Count > 0) + { + SystemWebUtils.AddListItemsForAddContent(LbChannelId.Items, SiteManager.GetSiteInfo(int.Parse(DdlSiteId.SelectedValue)), false, AuthRequest.AdminPermissionsImpl); + } + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + var isSuccess = false; + + try + { + _channelInfo.TransType = DdlTransType.SelectedValue; + _channelInfo.TransSiteId = ECrossSiteTransTypeUtils.Equals(_channelInfo.TransType, ECrossSiteTransType.SpecifiedSite) ? TranslateUtils.ToInt(DdlSiteId.SelectedValue) : 0; + _channelInfo.TransChannelIds = SystemWebUtils.GetSelectedListControlValueCollection(LbChannelId); + _channelInfo.TransChannelNames = TbNodeNames.Text; + + _channelInfo.TransIsAutomatic = TranslateUtils.ToBool(DdlIsAutomatic.SelectedValue); + + _channelInfo.TransDoneType = DdlTranslateDoneType.SelectedValue; + + DataProvider.Channel.Update(_channelInfo); + + AuthRequest.AddSiteLog(SiteId, "修改跨站转发设置"); + + isSuccess = true; + } + catch (Exception ex) + { + FailMessage(ex, ex.Message); + } + + if (isSuccess) + { + LayerUtils.Close(Page); + } + } + } +} diff --git a/SiteServer.BackgroundPages/Cms/ModalCuttingImage.cs b/net452/SiteServer.BackgroundPages/Cms/ModalCuttingImage.cs similarity index 84% rename from SiteServer.BackgroundPages/Cms/ModalCuttingImage.cs rename to net452/SiteServer.BackgroundPages/Cms/ModalCuttingImage.cs index f7c9adc59..a1a24c1a7 100644 --- a/SiteServer.BackgroundPages/Cms/ModalCuttingImage.cs +++ b/net452/SiteServer.BackgroundPages/Cms/ModalCuttingImage.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Specialized; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; using SiteServer.Utils; -using SiteServer.Utils.Images; using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Cms { @@ -19,7 +21,7 @@ public class ModalCuttingImage : BasePageCms public static string GetOpenWindowStringWithTextBox(int siteId, string textBoxClientId) { - return LayerUtils.GetOpenScript("裁切图片", PageUtils.GetCmsUrl(siteId, nameof(ModalCuttingImage), new NameValueCollection + return LayerUtils.GetOpenScript("裁切图片", FxUtils.GetCmsUrl(siteId, nameof(ModalCuttingImage), new NameValueCollection { {"textBoxClientID", textBoxClientId} })); @@ -27,7 +29,7 @@ public static string GetOpenWindowStringWithTextBox(int siteId, string textBoxCl public static string GetOpenWindowStringToImageUrl(int siteId, string imageUrl) { - return LayerUtils.GetOpenScript("裁切图片", PageUtils.GetCmsUrl(siteId, nameof(ModalCuttingImage), new NameValueCollection + return LayerUtils.GetOpenScript("裁切图片", FxUtils.GetCmsUrl(siteId, nameof(ModalCuttingImage), new NameValueCollection { {"imageUrl", imageUrl} })); @@ -37,7 +39,7 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId"); + WebPageUtils.CheckRequestParameter("siteId"); _textBoxClientId = AuthRequest.GetQueryString("TextBoxClientID"); _imageUrl = AuthRequest.GetQueryString("imageUrl"); @@ -56,11 +58,11 @@ public void Page_Load(object sender, EventArgs e) LtlScript.Text = $@" "; + } + catch (Exception ex) + { + FailMessage(ex, ex.Message); + } + } + } +} diff --git a/SiteServer.BackgroundPages/Cms/ModalUploadImageSingle.cs b/net452/SiteServer.BackgroundPages/Cms/ModalUploadImageSingle.cs similarity index 88% rename from SiteServer.BackgroundPages/Cms/ModalUploadImageSingle.cs rename to net452/SiteServer.BackgroundPages/Cms/ModalUploadImageSingle.cs index 6987be631..044ea5ca9 100644 --- a/SiteServer.BackgroundPages/Cms/ModalUploadImageSingle.cs +++ b/net452/SiteServer.BackgroundPages/Cms/ModalUploadImageSingle.cs @@ -2,8 +2,11 @@ using System.Collections.Specialized; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Cms @@ -22,7 +25,7 @@ public class ModalUploadImageSingle : BasePageCms public static string GetOpenWindowStringToTextBox(int siteId, string textBoxClientId) { - return LayerUtils.GetOpenScript("上传图片", PageUtils.GetCmsUrl(siteId, nameof(ModalUploadImageSingle), new NameValueCollection + return LayerUtils.GetOpenScript("上传图片", FxUtils.GetCmsUrl(siteId, nameof(ModalUploadImageSingle), new NameValueCollection { {"TextBoxClientID", textBoxClientId} }), 520, 220); @@ -30,7 +33,7 @@ public static string GetOpenWindowStringToTextBox(int siteId, string textBoxClie public static string GetOpenWindowStringToTextBox(int siteId, string textBoxClientId, bool isNeedWaterMark) { - return LayerUtils.GetOpenScript("上传图片", PageUtils.GetCmsUrl(siteId, nameof(ModalUploadImageSingle), new NameValueCollection + return LayerUtils.GetOpenScript("上传图片", FxUtils.GetCmsUrl(siteId, nameof(ModalUploadImageSingle), new NameValueCollection { {"TextBoxClientID", textBoxClientId}, {"IsNeedWaterMark", isNeedWaterMark.ToString()} @@ -39,7 +42,7 @@ public static string GetOpenWindowStringToTextBox(int siteId, string textBoxClie public static string GetOpenWindowStringToList(int siteId, string currentRootPath) { - return LayerUtils.GetOpenScript("上传图片", PageUtils.GetCmsUrl(siteId, nameof(ModalUploadImageSingle), new NameValueCollection + return LayerUtils.GetOpenScript("上传图片", FxUtils.GetCmsUrl(siteId, nameof(ModalUploadImageSingle), new NameValueCollection { {"CurrentRootPath", currentRootPath} }), 520, 220); @@ -49,7 +52,7 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId"); + WebPageUtils.CheckRequestParameter("siteId"); _currentRootPath = AuthRequest.GetQueryString("CurrentRootPath"); if (!string.IsNullOrEmpty(_currentRootPath) && !_currentRootPath.StartsWith("@")) { diff --git a/SiteServer.BackgroundPages/Cms/ModalUploadVideo.cs b/net452/SiteServer.BackgroundPages/Cms/ModalUploadVideo.cs similarity index 89% rename from SiteServer.BackgroundPages/Cms/ModalUploadVideo.cs rename to net452/SiteServer.BackgroundPages/Cms/ModalUploadVideo.cs index 5882906a9..ce6c8dc71 100644 --- a/SiteServer.BackgroundPages/Cms/ModalUploadVideo.cs +++ b/net452/SiteServer.BackgroundPages/Cms/ModalUploadVideo.cs @@ -2,8 +2,11 @@ using System.Collections.Specialized; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Cms { @@ -17,7 +20,7 @@ public class ModalUploadVideo : BasePageCms public static string GetOpenWindowStringToTextBox(int siteId, string textBoxClientId) { - return LayerUtils.GetOpenScript("上传视频", PageUtils.GetCmsUrl(siteId, nameof(ModalUploadVideo), new NameValueCollection + return LayerUtils.GetOpenScript("上传视频", FxUtils.GetCmsUrl(siteId, nameof(ModalUploadVideo), new NameValueCollection { {"TextBoxClientID", textBoxClientId} }), 520, 220); @@ -25,7 +28,7 @@ public static string GetOpenWindowStringToTextBox(int siteId, string textBoxClie public static string GetOpenWindowStringToList(int siteId, string currentRootPath) { - return LayerUtils.GetOpenScript("上传视频", PageUtils.GetCmsUrl(siteId, nameof(ModalUploadVideo), new NameValueCollection + return LayerUtils.GetOpenScript("上传视频", FxUtils.GetCmsUrl(siteId, nameof(ModalUploadVideo), new NameValueCollection { {"CurrentRootPath", currentRootPath} }), 520, 220); @@ -35,7 +38,7 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId"); + WebPageUtils.CheckRequestParameter("siteId"); _currentRootPath = AuthRequest.GetQueryString("CurrentRootPath"); if (!string.IsNullOrEmpty(_currentRootPath) && !_currentRootPath.StartsWith("@")) { diff --git a/net452/SiteServer.BackgroundPages/Cms/ModalUploadWord.cs b/net452/SiteServer.BackgroundPages/Cms/ModalUploadWord.cs new file mode 100644 index 000000000..f74cc27c0 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/ModalUploadWord.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.HtmlControls; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.Office; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class ModalUploadWord : BasePageCms + { + public HtmlInputHidden HihFileNames; + public CheckBox CbIsFirstLineTitle; + public CheckBox CbIsFirstLineRemove; + public CheckBox CbIsClearFormat; + public CheckBox CbIsFirstLineIndent; + public CheckBox CbIsClearFontSize; + public CheckBox CbIsClearFontFamily; + public CheckBox CbIsClearImages; + public DropDownList DdlContentLevel; + + private ChannelInfo _channelInfo; + private string _returnUrl; + + public static string GetOpenWindowString(int siteId, int channelId, string returnUrl) + { + return LayerUtils.GetOpenScript("批量导入Word文件", + FxUtils.GetCmsUrl(siteId, nameof(ModalUploadWord), new NameValueCollection + { + {"channelId", channelId.ToString()}, + {"returnUrl", returnUrl} + }), 700, 550); + } + + public string UploadUrl => ModalUploadWordHandler.GetRedirectUrl(SiteId); + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "ReturnUrl"); + var channelId = int.Parse(AuthRequest.GetQueryString("channelId")); + _channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + _returnUrl = AuthRequest.GetQueryString("ReturnUrl"); + + if (IsPostBack) return; + + int checkedLevel; + var isChecked = CheckManager.GetUserCheckLevel(AuthRequest.AdminPermissionsImpl, SiteInfo, SiteId, out checkedLevel); + SystemWebUtils.LoadContentLevelToCheckEdit(DdlContentLevel, SiteInfo, null, isChecked, checkedLevel); + SystemWebUtils.SelectSingleItem(DdlContentLevel, CheckManager.LevelInt.CaoGao.ToString()); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + var fileNames = TranslateUtils.StringCollectionToStringList(HihFileNames.Value); + if (fileNames.Count == 1) + { + var fileName = fileNames[0]; + if (!string.IsNullOrEmpty(fileName)) + { + var redirectUrl = WebUtils.GetContentAddUploadWordUrl(SiteId, _channelInfo, CbIsFirstLineTitle.Checked, CbIsFirstLineRemove.Checked, CbIsClearFormat.Checked, CbIsFirstLineIndent.Checked, CbIsClearFontSize.Checked, CbIsClearFontFamily.Checked, CbIsClearImages.Checked, TranslateUtils.ToIntWithNegative(DdlContentLevel.SelectedValue), fileName, _returnUrl); + LayerUtils.CloseAndRedirect(Page, redirectUrl); + } + + return; + } + + if (fileNames.Count > 1) + { + var tableName = ChannelManager.GetTableName(SiteInfo, _channelInfo); + var styleInfoList = TableStyleManager.GetContentStyleInfoList(SiteInfo, _channelInfo); + + foreach (var fileName in fileNames) + { + if (!string.IsNullOrEmpty(fileName)) + { + var formCollection = WordUtils.GetWordNameValueCollection(SiteId, CbIsFirstLineTitle.Checked, CbIsFirstLineRemove.Checked, CbIsClearFormat.Checked, CbIsFirstLineIndent.Checked, CbIsClearFontSize.Checked, CbIsClearFontFamily.Checked, CbIsClearImages.Checked, fileName); + + if (!string.IsNullOrEmpty(formCollection[ContentAttribute.Title])) + { + var dict = BackgroundInputTypeParser.SaveAttributes(SiteInfo, styleInfoList, formCollection, ContentAttribute.AllAttributes.Value); + + var contentInfo = new ContentInfo(dict) + { + ChannelId = _channelInfo.Id, + SiteId = SiteId, + AddUserName = AuthRequest.AdminName, + AddDate = DateTime.Now + }; + + contentInfo.LastEditUserName = contentInfo.AddUserName; + contentInfo.LastEditDate = contentInfo.AddDate; + + contentInfo.CheckedLevel = TranslateUtils.ToIntWithNegative(DdlContentLevel.SelectedValue); + contentInfo.Checked = contentInfo.CheckedLevel >= SiteInfo.CheckContentLevel; + + contentInfo.Title = formCollection[ContentAttribute.Title]; + + contentInfo.Id = DataProvider.ContentRepository.Insert(tableName, SiteInfo, _channelInfo, contentInfo); + + CreateManager.CreateContent(SiteId, _channelInfo.Id, contentInfo.Id); + CreateManager.TriggerContentChangedEvent(SiteId, _channelInfo.Id); + } + } + } + } + + LayerUtils.Close(Page); + } + } +} diff --git a/SiteServer.BackgroundPages/Cms/ModalUploadWordHandler.cs b/net452/SiteServer.BackgroundPages/Cms/ModalUploadWordHandler.cs similarity index 87% rename from SiteServer.BackgroundPages/Cms/ModalUploadWordHandler.cs rename to net452/SiteServer.BackgroundPages/Cms/ModalUploadWordHandler.cs index acba82275..462485068 100644 --- a/SiteServer.BackgroundPages/Cms/ModalUploadWordHandler.cs +++ b/net452/SiteServer.BackgroundPages/Cms/ModalUploadWordHandler.cs @@ -1,6 +1,6 @@ using System; using System.IO; -using SiteServer.CMS.Core.Office; +using SiteServer.CMS.Fx; using SiteServer.Utils; namespace SiteServer.BackgroundPages.Cms @@ -9,7 +9,7 @@ public class ModalUploadWordHandler : BaseHandler { public static string GetRedirectUrl(int siteId) { - return PageUtils.GetCmsWebHandlerUrl(siteId, nameof(ModalUploadWordHandler), null); + return FxUtils.GetCmsWebHandlerUrl(siteId, nameof(ModalUploadWordHandler), null); } protected override object Process() @@ -32,7 +32,8 @@ protected override object Process() var extendName = fileName.Substring(fileName.LastIndexOf(".", StringComparison.Ordinal)).ToLower(); if (extendName == ".doc" || extendName == ".docx") { - filePath = WordUtils.GetWordFilePath(fileName); + filePath = PathUtils.GetTemporaryFilesPath(fileName); + DirectoryUtils.CreateDirectoryIfNotExists(filePath); file.SaveAs(filePath); } } diff --git a/net452/SiteServer.BackgroundPages/Cms/PageChannel.cs b/net452/SiteServer.BackgroundPages/Cms/PageChannel.cs new file mode 100644 index 000000000..ff2b1eb7b --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageChannel.cs @@ -0,0 +1,158 @@ +using System; +using System.Collections.Specialized; +using System.Text; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageChannel : BasePageCms + { + public Literal LtlButtonsHead; + public Literal LtlButtonsFoot; + public Repeater RptContents; + + private int _currentChannelId; + + public static string GetRedirectUrl(int siteId, int currentChannelId) + { + if (currentChannelId > 0 && currentChannelId != siteId) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageChannel), new NameValueCollection + { + {"CurrentChannelId", currentChannelId.ToString()} + }); + } + return FxUtils.GetCmsUrl(siteId, nameof(PageChannel), null); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId"); + + if (AuthRequest.IsQueryExists("channelId") && (AuthRequest.IsQueryExists("Subtract") || AuthRequest.IsQueryExists("Add"))) + { + var channelId = AuthRequest.GetQueryInt("channelId"); + if (SiteId != channelId) + { + var isSubtract = AuthRequest.IsQueryExists("Subtract"); + DataProvider.Channel.UpdateTaxis(SiteId, channelId, isSubtract); + + AuthRequest.AddSiteLog(SiteId, channelId, 0, "栏目排序" + (isSubtract ? "上升" : "下降"), + $"栏目:{ChannelManager.GetChannelName(SiteId, channelId)}"); + + WebPageUtils.Redirect(GetRedirectUrl(SiteId, channelId)); + return; + } + } + + if (IsPostBack) return; + + ClientScriptRegisterClientScriptBlock("NodeTreeScript", ChannelLoading.GetScript(SiteInfo, string.Empty, ELoadingType.Channel, null)); + + if (AuthRequest.IsQueryExists("CurrentChannelId")) + { + _currentChannelId = AuthRequest.GetQueryInt("CurrentChannelId"); + var onLoadScript = ChannelLoading.GetScriptOnLoad(SiteId, _currentChannelId); + if (!string.IsNullOrEmpty(onLoadScript)) + { + ClientScriptRegisterClientScriptBlock("NodeTreeScriptOnLoad", onLoadScript); + } + } + + LtlButtonsHead.Text = LtlButtonsFoot.Text = GetButtonsHtml(); + + var channelIdList = ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(SiteId, SiteId), EScopeType.SelfAndChildren, string.Empty, string.Empty, string.Empty); + + RptContents.DataSource = channelIdList; + RptContents.ItemDataBound += RptContents_ItemDataBound; + RptContents.DataBind(); + } + + private string GetButtonsHtml() + { + var builder = new StringBuilder(); + + if (HasChannelPermissionsIgnoreChannelId(ConfigManager.ChannelPermissions.ChannelAdd)) + { + builder.Append($@" +快速添加 +添加栏目 +导 入 +"); + } + + builder.Append($@" +导 出 +"); + + if (HasChannelPermissionsIgnoreChannelId(ConfigManager.ChannelPermissions.ChannelEdit)) + { + builder.Append($@" +设置栏目组 +"); + + builder.Append($@" +排 序 +"); + } + + if (HasChannelPermissionsIgnoreChannelId(ConfigManager.ChannelPermissions.ChannelTranslate)) + { + builder.Append($@" +转 移 +"); + } + + if (HasChannelPermissionsIgnoreChannelId(ConfigManager.ChannelPermissions.ChannelDelete)) + { + builder.Append($@" +删 除 +"); + } + + if (HasSitePermissions(ConfigManager.WebSitePermissions.Create) || + HasChannelPermissionsIgnoreChannelId(ConfigManager.ChannelPermissions.CreatePage)) + { + builder.Append($@" +生 成 +"); + } + + return builder.ToString(); + } + + private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + var channelId = (int)e.Item.DataItem; + var enabled = IsOwningChannelId(channelId); + if (!enabled) + { + if (!IsDescendantOwningChannelId(channelId)) e.Item.Visible = false; + } + var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + + var ltlHtml = (Literal)e.Item.FindControl("ltlHtml"); + + ltlHtml.Text = ChannelLoading.GetChannelRowHtml(SiteInfo, nodeInfo, enabled, ELoadingType.Channel, null, AuthRequest.AdminPermissionsImpl); + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/PageChannelAdd.cs b/net452/SiteServer.BackgroundPages/Cms/PageChannelAdd.cs new file mode 100644 index 000000000..fd1cc1cea --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageChannelAdd.cs @@ -0,0 +1,330 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Controls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin; +using SiteServer.Plugin; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageChannelAdd : BasePageCms + { + public DropDownList DdlParentChannelId; + public TextBox TbNodeName; + public TextBox TbNodeIndexName; + public DropDownList DdlContentModelPluginId; + public PlaceHolder PhContentRelatedPluginIds; + public CheckBoxList CblContentRelatedPluginIds; + public TextBox TbLinkUrl; + public CheckBoxList CblNodeGroupNameCollection; + public DropDownList DdlLinkType; + public DropDownList DdlTaxisType; + public DropDownList DdlChannelTemplateId; + public DropDownList DdlContentTemplateId; + public RadioButtonList RblIsChannelAddable; + public RadioButtonList RblIsContentAddable; + public TextBox TbImageUrl; + public TextBox TbFilePath; + public TextBox TbChannelFilePathRule; + public TextBox TbContentFilePathRule; + + public TextEditorControl TbContent; + public TextBox TbKeywords; + public TextBox TbDescription; + + public ChannelAuxiliaryControl CacAttributes; + + public Button BtnCreateChannelRule; + public Button BtnCreateContentRule; + public Button BtnSelectImage; + public Button BtnUploadImage; + + private int _channelId; + + public static string GetRedirectUrl(int siteId, int channelId, string returnUrl) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageChannelAdd), new NameValueCollection + { + {"channelId", channelId.ToString() }, + {"ReturnUrl", StringUtils.ValueToUrl(returnUrl) } + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "channelId", "ReturnUrl"); + _channelId = AuthRequest.GetQueryInt("channelId"); + ReturnUrl = StringUtils.ValueFromUrl(AttackUtils.FilterSqlAndXss(AuthRequest.GetQueryString("ReturnUrl"))); + //if (!base.HasChannelPermissions(this.channelId, AppManager.CMS.Permission.Channel.ChannelAdd)) + //{ + // WebPageUtils.RedirectToErrorPage("您没有添加栏目的权限!"); + // return; + //} + + var parentNodeInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); + if (parentNodeInfo.IsChannelAddable == false) + { + WebPageUtils.RedirectToErrorPage("此栏目不能添加子栏目!"); + return; + } + + CacAttributes.SiteInfo = SiteInfo; + CacAttributes.ChannelId = _channelId; + + if (!IsPostBack) + { + SystemWebUtils.AddListItemsForChannel(DdlParentChannelId.Items, SiteInfo, true, true, AuthRequest.AdminPermissionsImpl); + SystemWebUtils.SelectSingleItem(DdlParentChannelId, _channelId.ToString()); + + DdlContentModelPluginId.Items.Add(new ListItem("<默认>", string.Empty)); + var contentTables = PluginContentManager.GetContentModelPlugins(); + foreach (var contentTable in contentTables) + { + DdlContentModelPluginId.Items.Add(new ListItem(contentTable.Title, contentTable.Id)); + } + SystemWebUtils.SelectSingleItem(DdlContentModelPluginId, parentNodeInfo.ContentModelPluginId); + + var plugins = PluginContentManager.GetAllContentRelatedPlugins(false); + if (plugins.Count > 0) + { + foreach (var pluginMetadata in plugins) + { + CblContentRelatedPluginIds.Items.Add(new ListItem(pluginMetadata.Title, pluginMetadata.Id)); + } + } + else + { + PhContentRelatedPluginIds.Visible = false; + } + + CacAttributes.Attributes = new Dictionary(StringComparer.OrdinalIgnoreCase); + + TbImageUrl.Attributes.Add("onchange", GetShowImageScript("preview_NavigationPicPath", SiteInfo.WebUrl)); + + var showPopWinString = ModalFilePathRule.GetOpenWindowString(SiteId, _channelId, true, TbChannelFilePathRule.ClientID); + BtnCreateChannelRule.Attributes.Add("onclick", showPopWinString); + + showPopWinString = ModalFilePathRule.GetOpenWindowString(SiteId, _channelId, false, TbContentFilePathRule.ClientID); + BtnCreateContentRule.Attributes.Add("onclick", showPopWinString); + + showPopWinString = ModalSelectImage.GetOpenWindowString(SiteInfo, TbImageUrl.ClientID); + BtnSelectImage.Attributes.Add("onclick", showPopWinString); + + showPopWinString = ModalUploadImage.GetOpenWindowString(SiteId, TbImageUrl.ClientID); + BtnUploadImage.Attributes.Add("onclick", showPopWinString); + + SystemWebUtils.AddListItemsToELinkType(DdlLinkType); + + SystemWebUtils.AddListItemsToETaxisTypeForChannelEdit(DdlTaxisType); + SystemWebUtils.SelectSingleItem(DdlTaxisType, ETaxisTypeUtils.GetValue(ETaxisType.OrderByTaxisDesc)); + + SystemWebUtils.AddListControlItems(CblNodeGroupNameCollection, ChannelGroupManager.GetGroupNameList(SiteId)); + //CblNodeGroupNameCollection.DataSource = DataProvider.ChannelGroup.GetDataSource(SiteId); + + DdlChannelTemplateId.DataSource = DataProvider.Template.GetDataSourceByType(SiteId, TemplateType.ChannelTemplate); + DdlContentTemplateId.DataSource = DataProvider.Template.GetDataSourceByType(SiteId, TemplateType.ContentTemplate); + + DataBind(); + + DdlChannelTemplateId.Items.Insert(0, new ListItem("<默认>", "0")); + DdlChannelTemplateId.Items[0].Selected = true; + + DdlContentTemplateId.Items.Insert(0, new ListItem("<默认>", "0")); + DdlContentTemplateId.Items[0].Selected = true; + TbContent.SetParameters(SiteInfo, ChannelAttribute.Content, string.Empty); + } + else + { + CacAttributes.Attributes = TranslateUtils.ToDictionary(Request.Form); + } + } + + public void DdlParentChannelId_SelectedIndexChanged(object sender, EventArgs e) + { + var theChannelId = TranslateUtils.ToInt(DdlParentChannelId.SelectedValue); + if (theChannelId == 0) + { + theChannelId = _channelId; + } + WebPageUtils.Redirect(GetRedirectUrl(SiteId, theChannelId, AuthRequest.GetQueryString("ReturnUrl"))); + } + + public string PreviewImageSrc + { + get + { + if (string.IsNullOrEmpty(TbImageUrl.Text)) return SiteServerAssets.GetIconUrl("empty.gif"); + + var extension = PathUtils.GetExtension(TbImageUrl.Text); + if (EFileSystemTypeUtils.IsImage(extension)) + { + return PageUtility.ParseNavigationUrl(SiteInfo, TbImageUrl.Text, true); + } + if (EFileSystemTypeUtils.IsFlash(extension)) + { + return SiteServerAssets.GetIconUrl("flash.jpg"); + } + if (EFileSystemTypeUtils.IsPlayer(extension)) + { + return SiteServerAssets.GetIconUrl("player.gif"); + } + return SiteServerAssets.GetIconUrl("empty.gif"); + } + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + int insertChannelId; + try + { + var channelId = AuthRequest.GetQueryInt("ChannelId"); + var channelInfo = new ChannelInfo + { + SiteId = SiteId, + ParentId = channelId, + ContentModelPluginId = DdlContentModelPluginId.SelectedValue, + ContentRelatedPluginIds = + SystemWebUtils.GetSelectedListControlValueCollection(CblContentRelatedPluginIds) + }; + + if (TbNodeIndexName.Text.Length != 0) + { + var nodeIndexNameArrayList = DataProvider.Channel.GetIndexNameList(SiteId); + if (nodeIndexNameArrayList.IndexOf(TbNodeIndexName.Text) != -1) + { + FailMessage("栏目添加失败,栏目索引已存在!"); + return; + } + } + + if (TbFilePath.Text.Length != 0) + { + if (!DirectoryUtils.IsDirectoryNameCompliant(TbFilePath.Text)) + { + FailMessage("栏目页面路径不符合系统要求!"); + return; + } + + if (PathUtils.IsDirectoryPath(TbFilePath.Text)) + { + TbFilePath.Text = PageUtils.Combine(TbFilePath.Text, "index.html"); + } + + var filePathArrayList = DataProvider.Channel.GetAllFilePathBySiteId(SiteId); + if (filePathArrayList.IndexOf(TbFilePath.Text) != -1) + { + FailMessage("栏目添加失败,栏目页面路径已存在!"); + return; + } + } + + if (!string.IsNullOrEmpty(TbChannelFilePathRule.Text)) + { + if (!DirectoryUtils.IsDirectoryNameCompliant(TbChannelFilePathRule.Text)) + { + FailMessage("栏目页面命名规则不符合系统要求!"); + return; + } + if (PathUtils.IsDirectoryPath(TbChannelFilePathRule.Text)) + { + FailMessage("栏目页面命名规则必须包含生成文件的后缀!"); + return; + } + } + + if (!string.IsNullOrEmpty(TbContentFilePathRule.Text)) + { + if (!DirectoryUtils.IsDirectoryNameCompliant(TbContentFilePathRule.Text)) + { + FailMessage("内容页面命名规则不符合系统要求!"); + return; + } + if (PathUtils.IsDirectoryPath(TbContentFilePathRule.Text)) + { + FailMessage("内容页面命名规则必须包含生成文件的后缀!"); + return; + } + } + + var parentNodeInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); + var styleInfoList = TableStyleManager.GetChannelStyleInfoList(parentNodeInfo); + var extendedAttributes = BackgroundInputTypeParser.SaveAttributes(SiteInfo, styleInfoList, Request.Form, null); + foreach (var extendedAttribute in extendedAttributes) + { + channelInfo.Set(extendedAttribute.Key, extendedAttribute.Value); + } + //foreach (string key in attributes) + //{ + // nodeInfo.SetExtendedAttribute(key, attributes[key]); + //} + + channelInfo.ChannelName = TbNodeName.Text; + channelInfo.IndexName = TbNodeIndexName.Text; + channelInfo.FilePath = TbFilePath.Text; + channelInfo.ChannelFilePathRule = TbChannelFilePathRule.Text; + channelInfo.ContentFilePathRule = TbContentFilePathRule.Text; + + var list = new ArrayList(); + foreach (ListItem item in CblNodeGroupNameCollection.Items) + { + if (item.Selected) + { + list.Add(item.Value); + } + } + channelInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(list); + channelInfo.ImageUrl = TbImageUrl.Text; + channelInfo.Content = ContentUtility.TextEditorContentEncode(SiteInfo, Request.Form[ChannelAttribute.Content]); + channelInfo.Keywords = TbKeywords.Text; + channelInfo.Description = TbDescription.Text; + channelInfo.IsChannelAddable = TranslateUtils.ToBool(RblIsChannelAddable.SelectedValue); + channelInfo.IsContentAddable = TranslateUtils.ToBool(RblIsContentAddable.SelectedValue); + + channelInfo.LinkUrl = TbLinkUrl.Text; + channelInfo.LinkType = DdlLinkType.SelectedValue; + + channelInfo.DefaultTaxisType = ETaxisTypeUtils.GetValue(ETaxisTypeUtils.GetEnumType(DdlTaxisType.SelectedValue)); + + channelInfo.ChannelTemplateId = DdlChannelTemplateId.Items.Count > 0 ? TranslateUtils.ToInt(DdlChannelTemplateId.SelectedValue) : 0; + channelInfo.ContentTemplateId = DdlContentTemplateId.Items.Count > 0 ? TranslateUtils.ToInt(DdlContentTemplateId.SelectedValue) : 0; + + channelInfo.AddDate = DateTime.Now; + insertChannelId = DataProvider.Channel.Insert(channelInfo); + //栏目选择投票样式后,内容 + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + FailMessage(ex, $"栏目添加失败:{ex.Message}"); + return; + } + + CreateManager.CreateChannel(SiteId, insertChannelId); + + AuthRequest.AddSiteLog(SiteId, "添加栏目", $"栏目:{TbNodeName.Text}"); + + SuccessMessage("栏目添加成功!"); + AddWaitAndRedirectScript(ReturnUrl); + } + + public string ReturnUrl { get; private set; } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/PageChannelDelete.cs b/net452/SiteServer.BackgroundPages/Cms/PageChannelDelete.cs new file mode 100644 index 000000000..b234700cb --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageChannelDelete.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Specialized; +using System.Text; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using System.Collections.Generic; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageChannelDelete : BasePageCms + { + public Literal LtlPageTitle; + public RadioButtonList RblRetainFiles; + public Button BtnDelete; + + private bool _deleteContents; + private readonly List _nodeNameList = new List(); + + public string ReturnUrl { get; private set; } + + public static string GetRedirectUrl(int siteId, string returnUrl) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageChannelDelete), new NameValueCollection + { + {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "ReturnUrl"); + ReturnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); + _deleteContents = AuthRequest.GetQueryBool("DeleteContents"); + + if (IsPostBack) return; + + var channelIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("ChannelIDCollection")); + channelIdList.Sort(); + channelIdList.Reverse(); + foreach (var channelId in channelIdList) + { + if (channelId == SiteId) continue; + if (!HasChannelPermissions(channelId, ConfigManager.ChannelPermissions.ChannelDelete)) continue; + + var channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + var onlyAdminId = AuthRequest.AdminPermissionsImpl.GetOnlyAdminId(SiteId, channelId); + var displayName = channelInfo.ChannelName; + var count = ContentManager.GetCount(SiteInfo, channelInfo, onlyAdminId); + if (count > 0) + { + displayName += $"({count})"; + } + _nodeNameList.Add(displayName); + } + + if (_nodeNameList.Count == 0) + { + BtnDelete.Enabled = false; + } + else + { + if (_deleteContents) + { + LtlPageTitle.Text = "删除内容"; + InfoMessage( + $"此操作将会删除栏目“{TranslateUtils.ObjectCollectionToString(_nodeNameList)}”下的所有内容,确认吗?"); + } + else + { + LtlPageTitle.Text = "删除栏目"; + InfoMessage( + $"此操作将会删除栏目“{TranslateUtils.ObjectCollectionToString(_nodeNameList)}”及包含的下级栏目,确认吗?"); + } + } + } + + public void Delete_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + try + { + var channelIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("ChannelIDCollection")); + channelIdList.Sort(); + channelIdList.Reverse(); + + var channelIdListToDelete = new List(); + foreach (var channelId in channelIdList) + { + if (channelId == SiteId) continue; + if (HasChannelPermissions(channelId, ConfigManager.ChannelPermissions.ChannelDelete)) + { + channelIdListToDelete.Add(channelId); + } + } + + var builder = new StringBuilder(); + foreach (var channelId in channelIdListToDelete) + { + builder.Append(ChannelManager.GetChannelName(SiteId, channelId)).Append(","); + } + + if (builder.Length > 0) + { + builder.Length -= 1; + } + + if (_deleteContents) + { + SuccessMessage(bool.Parse(RblRetainFiles.SelectedValue) == false + ? "成功删除内容以及生成页面!" + : "成功删除内容,生成页面未被删除!"); + + foreach (var channelId in channelIdListToDelete) + { + var channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + var contentIdList = channelInfo.ContentRepository.GetContentIdList(channelId); + DeleteManager.DeleteContents(SiteInfo, channelId, contentIdList); + channelInfo.ContentRepository.UpdateTrashContents(SiteId, channelId, contentIdList); + + //var tableName = ChannelManager.GetTableName(SiteInfo, channelId); + //var contentIdList = DataProvider.ContentRepository.GetContentIdList(tableName, channelId); + //DeleteManager.DeleteContents(SiteInfo, channelId, contentIdList); + //DataProvider.ContentRepository.UpdateTrashContents(SiteId, channelId, tableName, contentIdList); + } + + AuthRequest.AddSiteLog(SiteId, "清空栏目下的内容", $"栏目:{builder}"); + } + else + { + if (bool.Parse(RblRetainFiles.SelectedValue) == false) + { + DeleteManager.DeleteChannels(SiteInfo, channelIdListToDelete); + SuccessMessage("成功删除栏目以及相关生成页面!"); + } + else + { + SuccessMessage("成功删除栏目,相关生成页面未被删除!"); + } + + foreach (var channelId in channelIdListToDelete) + { + var channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + channelInfo.ContentRepository.UpdateTrashContentsByChannelId(SiteId, channelId); + DataProvider.Channel.Delete(SiteId, channelId); + } + + AuthRequest.AddSiteLog(SiteId, "删除栏目", $"栏目:{builder}"); + } + + AddWaitAndRedirectScript(ReturnUrl); + } + catch (Exception ex) + { + FailMessage(ex, _deleteContents ? "删除内容失败!" : "删除栏目失败!"); + + LogUtils.AddErrorLog(ex); + } + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/PageChannelEdit.cs b/net452/SiteServer.BackgroundPages/Cms/PageChannelEdit.cs new file mode 100644 index 000000000..08afc7c50 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageChannelEdit.cs @@ -0,0 +1,319 @@ +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Controls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin; +using SiteServer.Plugin; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageChannelEdit : BasePageCms + { + public TextBox TbNodeName; + public TextBox TbNodeIndexName; + public DropDownList DdlContentModelPluginId; + public PlaceHolder PhContentRelatedPluginIds; + public CheckBoxList CblContentRelatedPluginIds; + public CheckBoxList CblNodeGroupNameCollection; + public RadioButtonList RblIsChannelAddable; + public RadioButtonList RblIsContentAddable; + public TextBox TbLinkUrl; + public DropDownList DdlLinkType; + public DropDownList DdlTaxisType; + public DropDownList DdlChannelTemplateId; + public DropDownList DdlContentTemplateId; + public TextBox TbImageUrl; + public TextBox TbFilePath; + public TextBox TbChannelFilePathRule; + public TextBox TbContentFilePathRule; + public TextEditorControl TbContent; + public TextBox TbKeywords; + public TextBox TbDescription; + public ChannelAuxiliaryControl CacAttributes; + public Button BtnCreateChannelRule; + public Button BtnCreateContentRule; + public Button BtnSelectImage; + public Button BtnUploadImage; + public Button BtnSubmit; + + private int _channelId; + + public static string GetRedirectUrl(int siteId, int channelId, string returnUrl) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageChannelEdit), new NameValueCollection + { + {"channelId", channelId.ToString()}, + {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "channelId", "ReturnUrl"); + + _channelId = AuthRequest.GetQueryInt("channelId"); + ReturnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); + + if (AuthRequest.GetQueryString("CanNotEdit") == null && AuthRequest.GetQueryString("UncheckedChannel") == null) + { + if (!HasChannelPermissions(_channelId, ConfigManager.ChannelPermissions.ChannelEdit)) + { + WebPageUtils.RedirectToErrorPage("您没有修改栏目的权限!"); + return; + } + } + if (AuthRequest.IsQueryExists("CanNotEdit")) + { + BtnSubmit.Visible = false; + } + + var channelInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); + if (channelInfo == null) return; + + CacAttributes.SiteInfo = SiteInfo; + CacAttributes.ChannelId = _channelId; + + if (!IsPostBack) + { + DdlContentModelPluginId.Items.Add(new ListItem("<默认>", string.Empty)); + var contentTables = PluginContentManager.GetContentModelPlugins(); + foreach (var contentTable in contentTables) + { + DdlContentModelPluginId.Items.Add(new ListItem(contentTable.Title, contentTable.Id)); + } + SystemWebUtils.SelectSingleItem(DdlContentModelPluginId, channelInfo.ContentModelPluginId); + + var plugins = PluginContentManager.GetAllContentRelatedPlugins(false); + if (plugins.Count > 0) + { + var relatedPluginIds = + TranslateUtils.StringCollectionToStringList(channelInfo.ContentRelatedPluginIds); + foreach (var pluginMetadata in plugins) + { + CblContentRelatedPluginIds.Items.Add(new ListItem(pluginMetadata.Title, pluginMetadata.Id) + { + Selected = relatedPluginIds.Contains(pluginMetadata.Id) + }); + } + } + else + { + PhContentRelatedPluginIds.Visible = false; + } + + CacAttributes.Attributes = channelInfo.ToDictionary(); + + TbImageUrl.Attributes.Add("onchange", GetShowImageScript("preview_NavigationPicPath", SiteInfo.WebUrl)); + + var showPopWinString = ModalFilePathRule.GetOpenWindowString(SiteId, _channelId, true, TbChannelFilePathRule.ClientID); + BtnCreateChannelRule.Attributes.Add("onclick", showPopWinString); + + showPopWinString = ModalFilePathRule.GetOpenWindowString(SiteId, _channelId, false, TbContentFilePathRule.ClientID); + BtnCreateContentRule.Attributes.Add("onclick", showPopWinString); + + showPopWinString = ModalSelectImage.GetOpenWindowString(SiteInfo, TbImageUrl.ClientID); + BtnSelectImage.Attributes.Add("onclick", showPopWinString); + + showPopWinString = ModalUploadImage.GetOpenWindowString(SiteId, TbImageUrl.ClientID); + BtnUploadImage.Attributes.Add("onclick", showPopWinString); + + SystemWebUtils.AddListItemsToELinkType(DdlLinkType); + SystemWebUtils.AddListItemsToETaxisTypeForChannelEdit(DdlTaxisType); + + SystemWebUtils.AddListControlItems(CblNodeGroupNameCollection, ChannelGroupManager.GetGroupNameList(SiteId)); + //CblNodeGroupNameCollection.DataSource = DataProvider.ChannelGroup.GetDataSource(SiteId); + + DdlChannelTemplateId.DataSource = DataProvider.Template.GetDataSourceByType(SiteId, TemplateType.ChannelTemplate); + + DdlContentTemplateId.DataSource = DataProvider.Template.GetDataSourceByType(SiteId, TemplateType.ContentTemplate); + + DataBind(); + + DdlChannelTemplateId.Items.Insert(0, new ListItem("<未设置>", "0")); + SystemWebUtils.SelectSingleItem(DdlChannelTemplateId, channelInfo.ChannelTemplateId.ToString()); + + DdlContentTemplateId.Items.Insert(0, new ListItem("<未设置>", "0")); + SystemWebUtils.SelectSingleItem(DdlContentTemplateId, channelInfo.ContentTemplateId.ToString()); + + TbNodeName.Text = channelInfo.ChannelName; + TbNodeIndexName.Text = channelInfo.IndexName; + TbLinkUrl.Text = channelInfo.LinkUrl; + + foreach (ListItem item in CblNodeGroupNameCollection.Items) + { + item.Selected = StringUtils.In(channelInfo.GroupNameCollection, item.Value); + } + TbFilePath.Text = channelInfo.FilePath; + TbChannelFilePathRule.Text = channelInfo.ChannelFilePathRule; + TbContentFilePathRule.Text = channelInfo.ContentFilePathRule; + + SystemWebUtils.SelectSingleItem(DdlLinkType, channelInfo.LinkType); + SystemWebUtils.SelectSingleItem(DdlTaxisType, channelInfo.DefaultTaxisType); + SystemWebUtils.SelectSingleItem(RblIsChannelAddable, channelInfo.IsChannelAddable.ToString()); + SystemWebUtils.SelectSingleItem(RblIsContentAddable, channelInfo.IsContentAddable.ToString()); + + TbImageUrl.Text = channelInfo.ImageUrl; + + TbContent.SetParameters(SiteInfo, ChannelAttribute.Content, channelInfo.Content); + + TbKeywords.Text = channelInfo.Keywords; + TbDescription.Text = channelInfo.Description; + + //this.Content.SiteId = base.SiteId; + //this.Content.Text = StringUtility.TextEditorContentDecode(nodeInfo.Content, ConfigUtils.Instance.ApplicationPath, base.SiteInfo.SiteUrl); + } + else + { + CacAttributes.Attributes = TranslateUtils.ToDictionary(Request.Form); + } + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + ChannelInfo channelInfo; + try + { + channelInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); + + if (!channelInfo.IndexName.Equals(TbNodeIndexName.Text) && TbNodeIndexName.Text.Length != 0) + { + var nodeIndexNameList = DataProvider.Channel.GetIndexNameList(SiteId); + if (nodeIndexNameList.IndexOf(TbNodeIndexName.Text) != -1) + { + FailMessage("栏目属性修改失败,栏目索引已存在!"); + return; + } + } + + if (channelInfo.ContentModelPluginId != DdlContentModelPluginId.SelectedValue) + { + channelInfo.ContentModelPluginId = DdlContentModelPluginId.SelectedValue; + } + + channelInfo.ContentRelatedPluginIds = SystemWebUtils.GetSelectedListControlValueCollection(CblContentRelatedPluginIds); + + TbFilePath.Text = TbFilePath.Text.Trim(); + if (!channelInfo.FilePath.Equals(TbFilePath.Text) && TbFilePath.Text.Length != 0) + { + if (!DirectoryUtils.IsDirectoryNameCompliant(TbFilePath.Text)) + { + FailMessage("栏目页面路径不符合系统要求!"); + return; + } + + if (PathUtils.IsDirectoryPath(TbFilePath.Text)) + { + TbFilePath.Text = PageUtils.Combine(TbFilePath.Text, "index.html"); + } + + var filePathArrayList = DataProvider.Channel.GetAllFilePathBySiteId(SiteId); + if (filePathArrayList.IndexOf(TbFilePath.Text) != -1) + { + FailMessage("栏目修改失败,栏目页面路径已存在!"); + return; + } + } + + if (!string.IsNullOrEmpty(TbChannelFilePathRule.Text)) + { + var filePathRule = TbChannelFilePathRule.Text.Replace("|", string.Empty); + if (!DirectoryUtils.IsDirectoryNameCompliant(filePathRule)) + { + FailMessage("栏目页面命名规则不符合系统要求!"); + return; + } + if (PathUtils.IsDirectoryPath(filePathRule)) + { + FailMessage("栏目页面命名规则必须包含生成文件的后缀!"); + return; + } + } + + if (!string.IsNullOrEmpty(TbContentFilePathRule.Text)) + { + var filePathRule = TbContentFilePathRule.Text.Replace("|", string.Empty); + if (!DirectoryUtils.IsDirectoryNameCompliant(filePathRule)) + { + FailMessage("内容页面命名规则不符合系统要求!"); + return; + } + if (PathUtils.IsDirectoryPath(filePathRule)) + { + FailMessage("内容页面命名规则必须包含生成文件的后缀!"); + return; + } + } + + var styleInfoList = TableStyleManager.GetChannelStyleInfoList(channelInfo); + var extendedAttributes = BackgroundInputTypeParser.SaveAttributes(SiteInfo, styleInfoList, Request.Form, null); + foreach (var extendedAttribute in extendedAttributes) + { + channelInfo.Set(extendedAttribute.Key, extendedAttribute.Value); + } + + channelInfo.ChannelName = TbNodeName.Text; + channelInfo.IndexName = TbNodeIndexName.Text; + channelInfo.FilePath = TbFilePath.Text; + channelInfo.ChannelFilePathRule = TbChannelFilePathRule.Text; + channelInfo.ContentFilePathRule = TbContentFilePathRule.Text; + + var list = new ArrayList(); + foreach (ListItem item in CblNodeGroupNameCollection.Items) + { + if (item.Selected) + { + list.Add(item.Value); + } + } + channelInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(list); + channelInfo.ImageUrl = TbImageUrl.Text; + channelInfo.Content = ContentUtility.TextEditorContentEncode(SiteInfo, Request.Form[ChannelAttribute.Content]); + + channelInfo.Keywords = TbKeywords.Text; + channelInfo.Description = TbDescription.Text; + + channelInfo.IsChannelAddable = TranslateUtils.ToBool(RblIsChannelAddable.SelectedValue); + channelInfo.IsContentAddable = TranslateUtils.ToBool(RblIsContentAddable.SelectedValue); + + channelInfo.LinkUrl = TbLinkUrl.Text; + channelInfo.LinkType = DdlLinkType.SelectedValue; + channelInfo.DefaultTaxisType = ETaxisTypeUtils.GetValue(ETaxisTypeUtils.GetEnumType(DdlTaxisType.SelectedValue)); + channelInfo.ChannelTemplateId = DdlChannelTemplateId.Items.Count > 0 ? TranslateUtils.ToInt(DdlChannelTemplateId.SelectedValue) : 0; + channelInfo.ContentTemplateId = DdlContentTemplateId.Items.Count > 0 ? TranslateUtils.ToInt(DdlContentTemplateId.SelectedValue) : 0; + + DataProvider.Channel.Update(channelInfo); + } + catch (Exception ex) + { + FailMessage(ex, $"栏目修改失败:{ex.Message}"); + LogUtils.AddErrorLog(ex); + return; + } + + CreateManager.CreateChannel(SiteId, channelInfo.Id); + + AuthRequest.AddSiteLog(SiteId, "修改栏目", $"栏目:{TbNodeName.Text}"); + + SuccessMessage("栏目修改成功!"); + WebPageUtils.Redirect(ReturnUrl); + } + + public string ReturnUrl { get; private set; } + } +} \ No newline at end of file diff --git a/SiteServer.BackgroundPages/Cms/PageChannelTranslate.cs b/net452/SiteServer.BackgroundPages/Cms/PageChannelTranslate.cs similarity index 75% rename from SiteServer.BackgroundPages/Cms/PageChannelTranslate.cs rename to net452/SiteServer.BackgroundPages/Cms/PageChannelTranslate.cs index 792a430cc..4e0dc254c 100644 --- a/SiteServer.BackgroundPages/Cms/PageChannelTranslate.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageChannelTranslate.cs @@ -3,11 +3,15 @@ using System.Collections.Specialized; using System.Text; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; using SiteServer.Utils; -using SiteServer.CMS.Core; using SiteServer.CMS.Core.Create; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Cms @@ -26,12 +30,12 @@ public class PageChannelTranslate : BasePageCms public static string GetRedirectUrl(int siteId) { - return PageUtils.GetCmsUrl(siteId, nameof(PageChannelTranslate), null); + return FxUtils.GetCmsUrl(siteId, nameof(PageChannelTranslate), null); } public static string GetRedirectUrl(int siteId, int channelId) { - return PageUtils.GetCmsUrl(siteId, nameof(PageChannelTranslate), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageChannelTranslate), new NameValueCollection { {"channelId", channelId.ToString()} }); @@ -39,7 +43,7 @@ public static string GetRedirectUrl(int siteId, int channelId) public static string GetRedirectUrl(int siteId, int channelId, string returnUrl) { - return PageUtils.GetCmsUrl(siteId, nameof(PageChannelTranslate), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageChannelTranslate), new NameValueCollection { {"channelId", channelId.ToString()}, {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} @@ -48,7 +52,7 @@ public static string GetRedirectUrl(int siteId, int channelId, string returnUrl) public static string GetRedirectUrl(int siteId, string returnUrl) { - return PageUtils.GetCmsUrl(siteId, nameof(PageChannelTranslate), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageChannelTranslate), new NameValueCollection { {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} }); @@ -58,7 +62,7 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId"); + WebPageUtils.CheckRequestParameter("siteId"); ReturnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); if (!HasChannelPermissions(SiteId, ConfigManager.ChannelPermissions.ContentDelete)) @@ -69,13 +73,13 @@ public void Page_Load(object sender, EventArgs e) if (IsPostBack) return; PhReturn.Visible = !string.IsNullOrEmpty(ReturnUrl); - ETranslateTypeUtils.AddListItems(DdlTranslateType); - ControlUtils.SelectSingleItem(DdlTranslateType, + SystemWebUtils.AddListItemsToETranslateType(DdlTranslateType); + SystemWebUtils.SelectSingleItem(DdlTranslateType, AuthRequest.IsQueryExists("ChannelIDCollection") ? ETranslateTypeUtils.GetValue(ETranslateType.All) : ETranslateTypeUtils.GetValue(ETranslateType.Content)); - var siteIdList = AuthRequest.AdminPermissions.SiteIdList; + var siteIdList = AuthRequest.AdminPermissionsImpl.GetSiteIdList(); foreach (var psId in siteIdList) { var psInfo = SiteManager.GetSiteInfo(psId); @@ -100,12 +104,12 @@ public void Page_Load(object sender, EventArgs e) { if (!IsDescendantOwningChannelId(theChannelId)) continue; } - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, theChannelId); + var channelInfo = ChannelManager.GetChannelInfo(SiteId, theChannelId); - var value = enabled ? nodeInfo.Id.ToString() : string.Empty; - value = nodeInfo.Additional.IsContentAddable ? value : string.Empty; + var value = enabled ? channelInfo.Id.ToString() : string.Empty; + value = channelInfo.IsContentAddable ? value : string.Empty; - var text = GetTitle(nodeInfo); + var text = GetTitle(channelInfo); var listItem = new ListItem(text, value); if (channelIdStrList.Contains(value)) { @@ -117,30 +121,32 @@ public void Page_Load(object sender, EventArgs e) } } - public string GetTitle(ChannelInfo nodeInfo) + public string GetTitle(ChannelInfo channelInfo) { var str = ""; - if (nodeInfo.Id == SiteId) + if (channelInfo.Id == SiteId) { - nodeInfo.IsLastNode = true; + channelInfo.LastNode = true; } - if (nodeInfo.IsLastNode == false) + if (channelInfo.LastNode == false) { - _isLastNodeArray[nodeInfo.ParentsCount] = false; + _isLastNodeArray[channelInfo.ParentsCount] = false; } else { - _isLastNodeArray[nodeInfo.ParentsCount] = true; + _isLastNodeArray[channelInfo.ParentsCount] = true; } - for (var i = 0; i < nodeInfo.ParentsCount; i++) + for (var i = 0; i < channelInfo.ParentsCount; i++) { str = string.Concat(str, _isLastNodeArray[i] ? " " : "│"); } - str = string.Concat(str, nodeInfo.IsLastNode ? "└" : "├"); - str = string.Concat(str, nodeInfo.ChannelName); - if (nodeInfo.ContentNum != 0) + str = string.Concat(str, channelInfo.LastNode ? "└" : "├"); + str = string.Concat(str, channelInfo.ChannelName); + var onlyAdminId = AuthRequest.AdminPermissionsImpl.GetOnlyAdminId(SiteId, channelInfo.Id); + var count = ContentManager.GetCount(SiteInfo, channelInfo, onlyAdminId); + if (count != 0) { - str = $"{str} ({nodeInfo.ContentNum})"; + str = $"{str} ({count})"; } return str; } @@ -155,7 +161,7 @@ public override void Submit_OnClick(object sender, EventArgs e) var translateType = ETranslateTypeUtils.GetEnumType(DdlTranslateType.SelectedValue); - var channelIdStrArrayList = ControlUtils.GetSelectedListControlValueArrayList(LbChannelIdFrom); + var channelIdStrArrayList = SystemWebUtils.GetSelectedListControlValueArrayList(LbChannelIdFrom); var channelIdList = new List();//需要转移的栏目ID foreach (string channelIdStr in channelIdStrArrayList) @@ -210,7 +216,7 @@ public override void Submit_OnClick(object sender, EventArgs e) { try { - DataProvider.ChannelDao.Delete(SiteId, channelId); + DataProvider.Channel.Delete(SiteId, channelId); } catch { @@ -238,11 +244,11 @@ public override void Submit_OnClick(object sender, EventArgs e) if (!string.IsNullOrEmpty(ReturnUrl)) { - PageUtils.Redirect(ReturnUrl); + WebPageUtils.Redirect(ReturnUrl); } } - private void TranslateChannelAndContent(List nodeInfoList, int targetSiteId, int parentId, ETranslateType translateType, List nodeIndexNameList, List filePathList) + private void TranslateChannelAndContent(List nodeInfoList, int targetSiteId, int parentId, ETranslateType translateType, IList nodeIndexNameList, IList filePathList) { if (nodeInfoList == null || nodeInfoList.Count == 0) { @@ -251,26 +257,23 @@ private void TranslateChannelAndContent(List nodeInfoList, int targ if (nodeIndexNameList == null) { - nodeIndexNameList = DataProvider.ChannelDao.GetIndexNameList(targetSiteId); + nodeIndexNameList = DataProvider.Channel.GetIndexNameList(targetSiteId); } if (filePathList == null) { - filePathList = DataProvider.ChannelDao.GetAllFilePathBySiteId(targetSiteId); + filePathList = DataProvider.Channel.GetAllFilePathBySiteId(targetSiteId); } foreach (var oldNodeInfo in nodeInfoList) { - var nodeInfo = new ChannelInfo(oldNodeInfo) - { - SiteId = targetSiteId, - ParentId = parentId, - ContentNum = 0, - ChildrenCount = 0, - AddDate = DateTime.Now - }; - - if (RblIsDeleteAfterTranslate.Visible && EBooleanUtils.Equals(RblIsDeleteAfterTranslate.SelectedValue, EBoolean.True)) + var nodeInfo = (ChannelInfo)oldNodeInfo.Clone(); + nodeInfo.SiteId = targetSiteId; + nodeInfo.ParentId = parentId; + nodeInfo.ChildrenCount = 0; + nodeInfo.AddDate = DateTime.Now; + + if (RblIsDeleteAfterTranslate.Visible && EBooleanUtils.Equals(RblIsDeleteAfterTranslate.SelectedValue, EBoolean.True)) { nodeIndexNameList.Add(nodeInfo.IndexName); } @@ -293,7 +296,7 @@ private void TranslateChannelAndContent(List nodeInfoList, int targ nodeInfo.FilePath = string.Empty; } - var targetChannelId = DataProvider.ChannelDao.Insert(nodeInfo); + var targetChannelId = DataProvider.Channel.Insert(nodeInfo); if (translateType == ETranslateType.All) { @@ -303,7 +306,7 @@ private void TranslateChannelAndContent(List nodeInfoList, int targ if (targetChannelId != 0) { //var orderByString = ETaxisTypeUtils.GetChannelOrderByString(ETaxisType.OrderByTaxis); - //var childrenNodeInfoList = DataProvider.ChannelDao.GetChannelInfoList(oldNodeInfo, 0, "", EScopeType.Children, orderByString); + //var childrenNodeInfoList = DataProvider.Channel.GetChannelInfoList(oldNodeInfo, 0, "", EScopeType.Children, orderByString); var channelIdList = ChannelManager.GetChannelIdList(oldNodeInfo, EScopeType.Children, string.Empty, string.Empty, string.Empty); var childrenNodeInfoList = new List(); @@ -328,7 +331,7 @@ private void TranslateContent(int channelId, int targetSiteId, int targetChannel var orderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByTaxis); - var contentIdList = DataProvider.ContentDao.GetContentIdListChecked(tableName, channelId, orderByString); + var contentIdList = DataProvider.ContentRepository.GetContentIdListChecked(tableName, channelId, orderByString); var translateType = RblIsDeleteAfterTranslate.Visible && EBooleanUtils.Equals(RblIsDeleteAfterTranslate.SelectedValue, EBoolean.True) ? ETranslateContentType.Cut @@ -336,7 +339,7 @@ private void TranslateContent(int channelId, int targetSiteId, int targetChannel foreach (var contentId in contentIdList) { - ContentUtility.Translate(SiteInfo, channelId, contentId, targetSiteId, targetChannelId, translateType, AuthRequest.AdminName); + ContentManager.Translate(SiteInfo, channelId, contentId, targetSiteId, targetChannelId, translateType); } } @@ -351,11 +354,12 @@ public void DdlSiteId_OnSelectedIndexChanged(object sender, EventArgs e) _isLastNodeArray = new bool[nodeCount]; foreach (var theChannelId in channelIdList) { - var nodeInfo = ChannelManager.GetChannelInfo(psId, theChannelId); - var value = IsOwningChannelId(nodeInfo.Id) ? nodeInfo.Id.ToString() : ""; - value = (nodeInfo.Additional.IsContentAddable) ? value : ""; - var listitem = new ListItem(GetTitle(nodeInfo), value); - DdlChannelIdTo.Items.Add(listitem); + var channelInfo = ChannelManager.GetChannelInfo(psId, theChannelId); + + var value = IsOwningChannelId(channelInfo.Id) ? channelInfo.Id.ToString() : ""; + value = channelInfo.IsContentAddable ? value : ""; + var listItem = new ListItem(GetTitle(channelInfo), value); + DdlChannelIdTo.Items.Add(listItem); } } diff --git a/SiteServer.BackgroundPages/Cms/PageChannelsGroup.cs b/net452/SiteServer.BackgroundPages/Cms/PageChannelsGroup.cs similarity index 91% rename from SiteServer.BackgroundPages/Cms/PageChannelsGroup.cs rename to net452/SiteServer.BackgroundPages/Cms/PageChannelsGroup.cs index 15b919e53..73fa6784a 100644 --- a/SiteServer.BackgroundPages/Cms/PageChannelsGroup.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageChannelsGroup.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Specialized; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Fx; using SiteServer.Utils; -using SiteServer.CMS.Core; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Cms @@ -15,7 +17,7 @@ public class PageChannelsGroup : BasePageCms public static string GetRedirectUrl(int siteId, string nodeGroupName) { - return PageUtils.GetCmsUrl(siteId, nameof(PageChannelsGroup), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageChannelsGroup), new NameValueCollection { {"nodeGroupName", nodeGroupName} }); @@ -71,7 +73,7 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) public void Return_OnClick(object sender, EventArgs e) { - PageUtils.Redirect(PageNodeGroup.GetRedirectUrl(SiteId)); + WebPageUtils.Redirect(PageNodeGroup.GetRedirectUrl(SiteId)); } } } diff --git a/net452/SiteServer.BackgroundPages/Cms/PageConfigurationContent.cs b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationContent.cs new file mode 100644 index 000000000..a9b6e3a62 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationContent.cs @@ -0,0 +1,128 @@ +using System; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Repositories.Contents; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageConfigurationContent : BasePageCms + { + public DropDownList DdlIsSaveImageInTextEditor; + public DropDownList DdlIsAutoPageInTextEditor; + public PlaceHolder PhAutoPage; + public TextBox TbAutoPageWordNum; + public DropDownList DdlIsContentTitleBreakLine; + public DropDownList DdlIsCheckContentUseLevel; + public PlaceHolder PhCheckContentLevel; + public DropDownList DdlCheckContentLevel; + public DropDownList DdlIsAutoCheckKeywords; + + public static string GetRedirectUrl(int siteId) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageConfigurationContent), null); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId"); + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); + + FxUtils.AddListItems(DdlIsSaveImageInTextEditor, "保存", "不保存"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsSaveImageInTextEditor, SiteInfo.IsSaveImageInTextEditor.ToString()); + + FxUtils.AddListItems(DdlIsAutoPageInTextEditor, "自动分页", "手动分页"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsAutoPageInTextEditor, SiteInfo.IsAutoPageInTextEditor.ToString()); + + PhAutoPage.Visible = SiteInfo.IsAutoPageInTextEditor; + TbAutoPageWordNum.Text = SiteInfo.AutoPageWordNum.ToString(); + + FxUtils.AddListItems(DdlIsContentTitleBreakLine, "启用标题换行", "不启用"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsContentTitleBreakLine, SiteInfo.IsContentTitleBreakLine.ToString()); + + //保存时,敏感词自动检测 + FxUtils.AddListItems(DdlIsAutoCheckKeywords, "启用敏感词自动检测", "不启用"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsAutoCheckKeywords, SiteInfo.IsAutoCheckKeywords.ToString()); + + DdlIsCheckContentUseLevel.Items.Add(new ListItem("默认审核机制", false.ToString())); + DdlIsCheckContentUseLevel.Items.Add(new ListItem("多级审核机制", true.ToString())); + + SystemWebUtils.SelectSingleItem(DdlIsCheckContentUseLevel, SiteInfo.IsCheckContentLevel.ToString()); + if (SiteInfo.IsCheckContentLevel) + { + SystemWebUtils.SelectSingleItem(DdlCheckContentLevel, SiteInfo.CheckContentLevel.ToString()); + PhCheckContentLevel.Visible = true; + } + else + { + PhCheckContentLevel.Visible = false; + } + } + + public void DdlIsAutoPageInTextEditor_OnSelectedIndexChanged(object sender, EventArgs e) + { + PhAutoPage.Visible = EBooleanUtils.Equals(DdlIsAutoPageInTextEditor.SelectedValue, EBoolean.True); + } + + public void DdlIsCheckContentUseLevel_OnSelectedIndexChanged(object sender, EventArgs e) + { + PhCheckContentLevel.Visible = EBooleanUtils.Equals(DdlIsCheckContentUseLevel.SelectedValue, EBoolean.True); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + SiteInfo.IsSaveImageInTextEditor = TranslateUtils.ToBool(DdlIsSaveImageInTextEditor.SelectedValue, true); + + var isReCaculate = false; + if (TranslateUtils.ToBool(DdlIsAutoPageInTextEditor.SelectedValue, false)) + { + if (SiteInfo.IsAutoPageInTextEditor == false) + { + isReCaculate = true; + } + else if (SiteInfo.AutoPageWordNum != TranslateUtils.ToInt(TbAutoPageWordNum.Text, SiteInfo.AutoPageWordNum)) + { + isReCaculate = true; + } + } + + SiteInfo.IsAutoPageInTextEditor = TranslateUtils.ToBool(DdlIsAutoPageInTextEditor.SelectedValue, false); + + SiteInfo.AutoPageWordNum = TranslateUtils.ToInt(TbAutoPageWordNum.Text, SiteInfo.AutoPageWordNum); + + SiteInfo.IsContentTitleBreakLine = TranslateUtils.ToBool(DdlIsContentTitleBreakLine.SelectedValue, true); + + SiteInfo.IsAutoCheckKeywords = TranslateUtils.ToBool(DdlIsAutoCheckKeywords.SelectedValue, true); + + SiteInfo.IsCheckContentLevel = TranslateUtils.ToBool(DdlIsCheckContentUseLevel.SelectedValue); + if (SiteInfo.IsCheckContentLevel) + { + SiteInfo.CheckContentLevel = TranslateUtils.ToInt(DdlCheckContentLevel.SelectedValue); + } + + DataProvider.Site.Update(SiteInfo); + if (isReCaculate) + { + foreach (var repository in ContentTableRepository.GetContentRepositoryList(SiteInfo)) + { + repository.SetAutoPageContentToSite(); + } + } + + AuthRequest.AddSiteLog(SiteId, "修改内容设置"); + + SuccessMessage("内容设置修改成功!"); + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/PageConfigurationCreate.cs b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationCreate.cs new file mode 100644 index 000000000..bb891e5d2 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationCreate.cs @@ -0,0 +1,126 @@ +using System; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Controls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageConfigurationCreate : BasePageCms + { + public DropDownList DdlIsCreateContentIfContentChanged; + public DropDownList DdlIsCreateChannelIfChannelChanged; + public DropDownList DdlIsCreateShowPageInfo; + public DropDownList DdlIsCreateIe8Compatible; + public DropDownList DdlIsCreateBrowserNoCache; + public DropDownList DdlIsCreateJsIgnoreError; + public DropDownList DdlIsCreateWithJQuery; + public DropDownList DdlIsCreateDoubleClick; + public TextBox TbCreateStaticMaxPage; + public DropDownList DdlIsCreateUseDefaultFileName; + public PlaceHolder PhIsCreateUseDefaultFileName; + public TextBox TbCreateDefaultFileName; + public DropDownList DdlIsCreateStaticContentByAddDate; + public PlaceHolder PhIsCreateStaticContentByAddDate; + public DateTimeTextBox TbCreateStaticContentAddDate; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId"); + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Create); + + FxUtils.AddListItems(DdlIsCreateContentIfContentChanged, "生成", "不生成"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsCreateContentIfContentChanged, SiteInfo.IsCreateContentIfContentChanged.ToString()); + + FxUtils.AddListItems(DdlIsCreateChannelIfChannelChanged, "生成", "不生成"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsCreateChannelIfChannelChanged, SiteInfo.IsCreateChannelIfChannelChanged.ToString()); + + FxUtils.AddListItems(DdlIsCreateShowPageInfo, "显示", "不显示"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsCreateShowPageInfo, SiteInfo.IsCreateShowPageInfo.ToString()); + + FxUtils.AddListItems(DdlIsCreateIe8Compatible, "强制兼容", "不设置"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsCreateIe8Compatible, SiteInfo.IsCreateIe8Compatible.ToString()); + + FxUtils.AddListItems(DdlIsCreateBrowserNoCache, "强制清除缓存", "不设置"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsCreateBrowserNoCache, SiteInfo.IsCreateBrowserNoCache.ToString()); + + FxUtils.AddListItems(DdlIsCreateJsIgnoreError, "包含JS容错代码", "不设置"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsCreateJsIgnoreError, SiteInfo.IsCreateJsIgnoreError.ToString()); + + FxUtils.AddListItems(DdlIsCreateWithJQuery, "是", "否"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsCreateWithJQuery, SiteInfo.IsCreateWithJQuery.ToString()); + + FxUtils.AddListItems(DdlIsCreateDoubleClick, "启用双击生成", "不启用"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsCreateDoubleClick, SiteInfo.IsCreateDoubleClick.ToString()); + + TbCreateStaticMaxPage.Text = SiteInfo.CreateStaticMaxPage.ToString(); + + FxUtils.AddListItems(DdlIsCreateUseDefaultFileName, "启用", "不启用"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsCreateUseDefaultFileName, SiteInfo.IsCreateUseDefaultFileName.ToString()); + PhIsCreateUseDefaultFileName.Visible = SiteInfo.IsCreateUseDefaultFileName; + TbCreateDefaultFileName.Text = SiteInfo.CreateDefaultFileName; + + FxUtils.AddListItems(DdlIsCreateStaticContentByAddDate, "启用", "不启用"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsCreateStaticContentByAddDate, SiteInfo.IsCreateStaticContentByAddDate.ToString()); + PhIsCreateStaticContentByAddDate.Visible = SiteInfo.IsCreateStaticContentByAddDate; + if (SiteInfo.CreateStaticContentAddDate.HasValue) + { + TbCreateStaticContentAddDate.DateTime = SiteInfo.CreateStaticContentAddDate.Value; + } + } + + public void DdlIsCreateUseDefaultFileName_SelectedIndexChanged(object sender, EventArgs e) + { + PhIsCreateUseDefaultFileName.Visible = TranslateUtils.ToBool(DdlIsCreateUseDefaultFileName.SelectedValue); + } + + public void DdlIsCreateStaticContentByAddDate_SelectedIndexChanged(object sender, EventArgs e) + { + PhIsCreateStaticContentByAddDate.Visible = TranslateUtils.ToBool(DdlIsCreateStaticContentByAddDate.SelectedValue); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + SiteInfo.IsCreateContentIfContentChanged = TranslateUtils.ToBool(DdlIsCreateContentIfContentChanged.SelectedValue); + SiteInfo.IsCreateChannelIfChannelChanged = TranslateUtils.ToBool(DdlIsCreateChannelIfChannelChanged.SelectedValue); + + SiteInfo.IsCreateShowPageInfo = TranslateUtils.ToBool(DdlIsCreateShowPageInfo.SelectedValue); + SiteInfo.IsCreateIe8Compatible = TranslateUtils.ToBool(DdlIsCreateIe8Compatible.SelectedValue); + SiteInfo.IsCreateBrowserNoCache = TranslateUtils.ToBool(DdlIsCreateBrowserNoCache.SelectedValue); + SiteInfo.IsCreateJsIgnoreError = TranslateUtils.ToBool(DdlIsCreateJsIgnoreError.SelectedValue); + SiteInfo.IsCreateWithJQuery = TranslateUtils.ToBool(DdlIsCreateWithJQuery.SelectedValue); + + SiteInfo.IsCreateDoubleClick = TranslateUtils.ToBool(DdlIsCreateDoubleClick.SelectedValue); + SiteInfo.CreateStaticMaxPage = TranslateUtils.ToInt(TbCreateStaticMaxPage.Text); + + SiteInfo.IsCreateUseDefaultFileName = TranslateUtils.ToBool(DdlIsCreateUseDefaultFileName.SelectedValue); + if (SiteInfo.IsCreateUseDefaultFileName) + { + SiteInfo.CreateDefaultFileName = TbCreateDefaultFileName.Text; + } + + SiteInfo.IsCreateStaticContentByAddDate = TranslateUtils.ToBool(DdlIsCreateStaticContentByAddDate.SelectedValue); + if (SiteInfo.IsCreateStaticContentByAddDate) + { + SiteInfo.CreateStaticContentAddDate = TbCreateStaticContentAddDate.DateTime; + } + + DataProvider.Site.Update(SiteInfo); + + AuthRequest.AddSiteLog(SiteId, "修改页面生成设置"); + + SuccessMessage("页面生成设置修改成功!"); + } + } +} diff --git a/SiteServer.BackgroundPages/Cms/PageConfigurationCreateRule.cs b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationCreateRule.cs similarity index 82% rename from SiteServer.BackgroundPages/Cms/PageConfigurationCreateRule.cs rename to net452/SiteServer.BackgroundPages/Cms/PageConfigurationCreateRule.cs index 214bae3bc..f0ca9ea9f 100644 --- a/SiteServer.BackgroundPages/Cms/PageConfigurationCreateRule.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationCreateRule.cs @@ -3,8 +3,10 @@ using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model.Enumerations; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Cms @@ -18,7 +20,7 @@ public class PageConfigurationCreateRule : BasePageCms public static string GetRedirectUrl(int siteId, int currentChannelId) { - return PageUtils.GetCmsUrl(siteId, nameof(PageConfigurationCreateRule), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageConfigurationCreateRule), new NameValueCollection { {"CurrentChannelId", currentChannelId.ToString()} }); @@ -28,7 +30,7 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId"); + WebPageUtils.CheckRequestParameter("siteId"); _additional = new NameValueCollection(); @@ -64,11 +66,11 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) if (!IsDescendantOwningChannelId(channelId)) e.Item.Visible = false; } - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + var channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); var ltlHtml = (Literal)e.Item.FindControl("ltlHtml"); - ltlHtml.Text = ChannelLoading.GetChannelRowHtml(SiteInfo, nodeInfo, enabled, ELoadingType.TemplateFilePathRule, _additional, AuthRequest.AdminPermissions); + ltlHtml.Text = ChannelLoading.GetChannelRowHtml(SiteInfo, channelInfo, enabled, ELoadingType.TemplateFilePathRule, _additional, AuthRequest.AdminPermissionsImpl); } } } diff --git a/SiteServer.BackgroundPages/Cms/PageConfigurationCreateTrigger.cs b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationCreateTrigger.cs similarity index 87% rename from SiteServer.BackgroundPages/Cms/PageConfigurationCreateTrigger.cs rename to net452/SiteServer.BackgroundPages/Cms/PageConfigurationCreateTrigger.cs index 726b3fb0e..a4cf5ac00 100644 --- a/SiteServer.BackgroundPages/Cms/PageConfigurationCreateTrigger.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationCreateTrigger.cs @@ -3,8 +3,10 @@ using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model.Enumerations; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Cms @@ -17,7 +19,7 @@ public class PageConfigurationCreateTrigger : BasePageCms public static string GetRedirectUrl(int siteId, int channelId) { - return PageUtils.GetCmsUrl(siteId, nameof(PageConfigurationCreateTrigger), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageConfigurationCreateTrigger), new NameValueCollection { {"CurrentChannelId", channelId.ToString()} }); @@ -27,7 +29,7 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId"); + WebPageUtils.CheckRequestParameter("siteId"); if (!IsPostBack) { @@ -71,7 +73,7 @@ void rptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) var ltlHtml = e.Item.FindControl("ltlHtml") as Literal; if (ltlHtml != null) { - ltlHtml.Text = ChannelLoading.GetChannelRowHtml(SiteInfo, nodeInfo, enabled, ELoadingType.ConfigurationCreateDetails, null, AuthRequest.AdminPermissions); + ltlHtml.Text = ChannelLoading.GetChannelRowHtml(SiteInfo, nodeInfo, enabled, ELoadingType.ConfigurationCreateDetails, null, AuthRequest.AdminPermissionsImpl); } } } diff --git a/net452/SiteServer.BackgroundPages/Cms/PageConfigurationCrossSiteTrans.cs b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationCrossSiteTrans.cs new file mode 100644 index 000000000..a9a8fe368 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationCrossSiteTrans.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageConfigurationCrossSiteTrans : BasePageCms + { + public RadioButtonList RblIsCrossSiteTransChecked; + + private int _currentChannelId; + + public static string GetRedirectUrl(int siteId, int currentChannelId) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageConfigurationCrossSiteTrans), new NameValueCollection + { + {"CurrentChannelId", currentChannelId.ToString()} + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId"); + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); + + ClientScriptRegisterClientScriptBlock("NodeTreeScript", ChannelLoading.GetScript(SiteInfo, string.Empty, ELoadingType.ConfigurationCrossSiteTrans, null)); + + if (AuthRequest.IsQueryExists("CurrentChannelId")) + { + _currentChannelId = AuthRequest.GetQueryInt("CurrentChannelId"); + var onLoadScript = ChannelLoading.GetScriptOnLoad(SiteId, _currentChannelId); + if (!string.IsNullOrEmpty(onLoadScript)) + { + ClientScriptRegisterClientScriptBlock("NodeTreeScriptOnLoad", onLoadScript); + } + } + + FxUtils.AddListItems(RblIsCrossSiteTransChecked, "无需审核", "需要审核"); + SystemWebUtils.SelectSingleItem(RblIsCrossSiteTransChecked, SiteInfo.IsCrossSiteTransChecked.ToString()); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + SiteInfo.IsCrossSiteTransChecked = TranslateUtils.ToBool(RblIsCrossSiteTransChecked.SelectedValue); + + try + { + DataProvider.Site.Update(SiteInfo); + + AuthRequest.AddSiteLog(SiteId, "修改默认跨站转发设置"); + + SuccessMessage("默认跨站转发设置修改成功!"); + } + catch(Exception ex) + { + FailMessage(ex, "默认跨站转发设置修改失败!"); + } + } + } +} diff --git a/SiteServer.BackgroundPages/Cms/PageConfigurationCrossSiteTransChannels.cs b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationCrossSiteTransChannels.cs similarity index 87% rename from SiteServer.BackgroundPages/Cms/PageConfigurationCrossSiteTransChannels.cs rename to net452/SiteServer.BackgroundPages/Cms/PageConfigurationCrossSiteTransChannels.cs index eda838f32..6249c5031 100644 --- a/SiteServer.BackgroundPages/Cms/PageConfigurationCrossSiteTransChannels.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationCrossSiteTransChannels.cs @@ -3,8 +3,10 @@ using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model.Enumerations; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Cms @@ -17,7 +19,7 @@ public class PageConfigurationCrossSiteTransChannels : BasePageCms public static string GetRedirectUrl(int siteId, int currentChannelId) { - return PageUtils.GetCmsUrl(siteId, nameof(PageConfigurationCrossSiteTransChannels), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageConfigurationCrossSiteTransChannels), new NameValueCollection { {"CurrentChannelId", currentChannelId.ToString()} }); @@ -27,7 +29,7 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId"); + WebPageUtils.CheckRequestParameter("siteId"); if (IsPostBack) return; @@ -62,7 +64,7 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) } var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); var ltlHtml = (Literal)e.Item.FindControl("ltlHtml"); - ltlHtml.Text = ChannelLoading.GetChannelRowHtml(SiteInfo, nodeInfo, enabled, ELoadingType.ConfigurationCrossSiteTrans, null, AuthRequest.AdminPermissions); + ltlHtml.Text = ChannelLoading.GetChannelRowHtml(SiteInfo, nodeInfo, enabled, ELoadingType.ConfigurationCrossSiteTrans, null, AuthRequest.AdminPermissionsImpl); } } } diff --git a/net452/SiteServer.BackgroundPages/Cms/PageConfigurationSite.cs b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationSite.cs new file mode 100644 index 000000000..15d068163 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationSite.cs @@ -0,0 +1,61 @@ +using System; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageConfigurationSite : BasePageCms + { + public DropDownList DdlCharset; + public TextBox TbPageSize; + public DropDownList DdlIsCreateDoubleClick; + + public static string GetRedirectUrl(int siteId) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageConfigurationSite), null); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId"); + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); + + FxUtils.AddListItemsToECharset(DdlCharset); + SystemWebUtils.SelectSingleItem(DdlCharset, SiteInfo.Charset); + + TbPageSize.Text = SiteInfo.PageSize.ToString(); + + FxUtils.AddListItems(DdlIsCreateDoubleClick, "启用双击生成", "不启用"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsCreateDoubleClick, SiteInfo.IsCreateDoubleClick.ToString()); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + if (SiteInfo.Charset != DdlCharset.SelectedValue) + { + SiteInfo.Charset = DdlCharset.SelectedValue; + } + + SiteInfo.PageSize = TranslateUtils.ToInt(TbPageSize.Text, SiteInfo.PageSize); + SiteInfo.IsCreateDoubleClick = TranslateUtils.ToBool(DdlIsCreateDoubleClick.SelectedValue); + + DataProvider.Site.Update(SiteInfo); + + AuthRequest.AddSiteLog(SiteId, "修改站点设置"); + + SuccessMessage("站点设置修改成功!"); + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/PageConfigurationSiteAttributes.cs b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationSiteAttributes.cs new file mode 100644 index 000000000..60764f555 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationSiteAttributes.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Text; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Plugin; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageConfigurationSiteAttributes : BasePageCms + { + public TextBox TbSiteName; + public Literal LtlAttributes; + public Button BtnSubmit; + + private List _styleInfoList; + + public static string GetRedirectUrl(int siteId) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageConfigurationSiteAttributes), null); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId"); + + _styleInfoList = TableStyleManager.GetSiteStyleInfoList(SiteId); + + if (!IsPostBack) + { + VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); + + TbSiteName.Text = SiteInfo.SiteName; + + var nameValueCollection = TranslateUtils.DictionaryToNameValueCollection(SiteInfo.ToDictionary()); + + LtlAttributes.Text = GetAttributesHtml(nameValueCollection); + + BtnSubmit.Attributes.Add("onclick", InputParserUtils.GetValidateSubmitOnClickScript("myForm")); + } + else + { + LtlAttributes.Text = GetAttributesHtml(Request.Form); + } + } + + private string GetAttributesHtml(NameValueCollection formCollection) + { + if (formCollection == null) + { + formCollection = Request.Form.Count > 0 ? Request.Form : new NameValueCollection(); + } + + var pageScripts = new NameValueCollection(); + + if (_styleInfoList == null) return string.Empty; + + var attributes = TranslateUtils.ToDictionary(formCollection); + + var builder = new StringBuilder(); + foreach (var styleInfo in _styleInfoList) + { + string extra; + var value = BackgroundInputTypeParser.Parse(SiteInfo, 0, styleInfo, attributes, pageScripts, out extra); + if (string.IsNullOrEmpty(value) && string.IsNullOrEmpty(extra)) continue; + + if (InputTypeUtils.Equals(styleInfo.Type, InputType.TextEditor)) + { + var commands = WebUtils.GetTextEditorCommands(SiteInfo, styleInfo.AttributeName); + builder.Append($@" +
    + + {commands} +
    + {value} + {extra} +
    "); + } + else + { + builder.Append($@" +
    + + {value} + {extra} +
    "); + } + } + + foreach (string key in pageScripts.Keys) + { + builder.Append(pageScripts[key]); + } + + return builder.ToString(); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + SiteInfo.SiteName = TbSiteName.Text; + + var dict = BackgroundInputTypeParser.SaveAttributes(SiteInfo, _styleInfoList, Page.Request.Form, null); + + foreach (var o in dict) + { + SiteInfo.Set(o.Key, o.Value); + } + + DataProvider.Site.Update(SiteInfo); + + AuthRequest.AddSiteLog(SiteId, "修改站点设置"); + + SuccessMessage("站点设置修改成功!"); + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/PageConfigurationUploadFile.cs b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationUploadFile.cs new file mode 100644 index 000000000..e23f804a5 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationUploadFile.cs @@ -0,0 +1,95 @@ +using System; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageConfigurationUploadFile : BasePageCms + { + public TextBox TbFileUploadDirectoryName; + public DropDownList DdlFileUploadDateFormatString; + public DropDownList DdlIsFileUploadChangeFileName; + public TextBox TbFileUploadTypeCollection; + public DropDownList DdlFileUploadTypeUnit; + public TextBox TbFileUploadTypeMaxSize; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId"); + + if (!IsPostBack) + { + VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); + + TbFileUploadDirectoryName.Text = SiteInfo.FileUploadDirectoryName; + + DdlFileUploadDateFormatString.Items.Add(new ListItem("按年存入不同目录(不推荐)", EDateFormatTypeUtils.GetValue(EDateFormatType.Year))); + DdlFileUploadDateFormatString.Items.Add(new ListItem("按年/月存入不同目录", EDateFormatTypeUtils.GetValue(EDateFormatType.Month))); + DdlFileUploadDateFormatString.Items.Add(new ListItem("按年/月/日存入不同目录", EDateFormatTypeUtils.GetValue(EDateFormatType.Day))); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlFileUploadDateFormatString, SiteInfo.FileUploadDateFormatString); + + FxUtils.AddListItems(DdlIsFileUploadChangeFileName, "自动修改文件名", "保持文件名不变"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsFileUploadChangeFileName, SiteInfo.IsFileUploadChangeFileName.ToString()); + + TbFileUploadTypeCollection.Text = SiteInfo.FileUploadTypeCollection.Replace("|", ","); + var mbSize = GetMbSize(SiteInfo.FileUploadTypeMaxSize); + if (mbSize == 0) + { + DdlFileUploadTypeUnit.SelectedIndex = 0; + TbFileUploadTypeMaxSize.Text = SiteInfo.FileUploadTypeMaxSize.ToString(); + } + else + { + DdlFileUploadTypeUnit.SelectedIndex = 1; + TbFileUploadTypeMaxSize.Text = mbSize.ToString(); + } + } + } + + private static int GetMbSize(int kbSize) + { + var retval = 0; + if (kbSize >= 1024 && ((kbSize % 1024) == 0)) + { + retval = kbSize / 1024; + } + return retval; + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (Page.IsPostBack && Page.IsValid) + { + SiteInfo.FileUploadDirectoryName = TbFileUploadDirectoryName.Text; + + SiteInfo.FileUploadDateFormatString = EDateFormatTypeUtils.GetValue(EDateFormatTypeUtils.GetEnumType(DdlFileUploadDateFormatString.SelectedValue)); + SiteInfo.IsFileUploadChangeFileName = TranslateUtils.ToBool(DdlIsFileUploadChangeFileName.SelectedValue); + + SiteInfo.FileUploadTypeCollection = TbFileUploadTypeCollection.Text.Replace(",", "|"); + var kbSize = int.Parse(TbFileUploadTypeMaxSize.Text); + SiteInfo.FileUploadTypeMaxSize = (DdlFileUploadTypeUnit.SelectedIndex == 0) ? kbSize : 1024 * kbSize; + + try + { + DataProvider.Site.Update(SiteInfo); + + AuthRequest.AddSiteLog(SiteId, "修改附件上传设置"); + + SuccessMessage("上传附件设置修改成功!"); + } + catch(Exception ex) + { + FailMessage(ex, "上传附件设置修改失败!"); + } + } + } + + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/PageConfigurationUploadImage.cs b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationUploadImage.cs new file mode 100644 index 000000000..99a3f73a1 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationUploadImage.cs @@ -0,0 +1,101 @@ +using System; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageConfigurationUploadImage : BasePageCms + { + public TextBox TbImageUploadDirectoryName; + public DropDownList DdlImageUploadDateFormatString; + public DropDownList DdlIsImageUploadChangeFileName; + public TextBox TbImageUploadTypeCollection; + public DropDownList DdlImageUploadTypeUnit; + public TextBox TbImageUploadTypeMaxSize; + + public TextBox TbPhotoSmallWidth; + public TextBox TbPhotoMiddleWidth; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + WebPageUtils.CheckRequestParameter("siteId"); + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); + + TbImageUploadDirectoryName.Text = SiteInfo.ImageUploadDirectoryName; + + DdlImageUploadDateFormatString.Items.Add(new ListItem("按年存入不同目录(不推荐)", EDateFormatTypeUtils.GetValue(EDateFormatType.Year))); + DdlImageUploadDateFormatString.Items.Add(new ListItem("按年/月存入不同目录", EDateFormatTypeUtils.GetValue(EDateFormatType.Month))); + DdlImageUploadDateFormatString.Items.Add(new ListItem("按年/月/日存入不同目录", EDateFormatTypeUtils.GetValue(EDateFormatType.Day))); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlImageUploadDateFormatString, SiteInfo.ImageUploadDateFormatString); + + FxUtils.AddListItems(DdlIsImageUploadChangeFileName, "自动修改文件名", "保持文件名不变"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsImageUploadChangeFileName, SiteInfo.IsImageUploadChangeFileName.ToString()); + + TbImageUploadTypeCollection.Text = SiteInfo.ImageUploadTypeCollection.Replace("|", ","); + var mbSize = GetMbSize(SiteInfo.ImageUploadTypeMaxSize); + if (mbSize == 0) + { + DdlImageUploadTypeUnit.SelectedIndex = 0; + TbImageUploadTypeMaxSize.Text = SiteInfo.ImageUploadTypeMaxSize.ToString(); + } + else + { + DdlImageUploadTypeUnit.SelectedIndex = 1; + TbImageUploadTypeMaxSize.Text = mbSize.ToString(); + } + + TbPhotoSmallWidth.Text = SiteInfo.PhotoSmallWidth.ToString(); + TbPhotoMiddleWidth.Text = SiteInfo.PhotoMiddleWidth.ToString(); + } + + private static int GetMbSize(int kbSize) + { + var retval = 0; + if (kbSize >= 1024 && kbSize % 1024 == 0) + { + retval = kbSize / 1024; + } + return retval; + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + SiteInfo.ImageUploadDirectoryName = TbImageUploadDirectoryName.Text; + + SiteInfo.ImageUploadDateFormatString = EDateFormatTypeUtils.GetValue(EDateFormatTypeUtils.GetEnumType(DdlImageUploadDateFormatString.SelectedValue)); + SiteInfo.IsImageUploadChangeFileName = TranslateUtils.ToBool(DdlIsImageUploadChangeFileName.SelectedValue); + + SiteInfo.ImageUploadTypeCollection = TbImageUploadTypeCollection.Text.Replace(",", "|"); + var kbSize = int.Parse(TbImageUploadTypeMaxSize.Text); + SiteInfo.ImageUploadTypeMaxSize = DdlImageUploadTypeUnit.SelectedIndex == 0 ? kbSize : 1024 * kbSize; + + SiteInfo.PhotoSmallWidth = TranslateUtils.ToInt(TbPhotoSmallWidth.Text, SiteInfo.PhotoSmallWidth); + SiteInfo.PhotoMiddleWidth = TranslateUtils.ToInt(TbPhotoMiddleWidth.Text, SiteInfo.PhotoMiddleWidth); + + try + { + DataProvider.Site.Update(SiteInfo); + + AuthRequest.AddSiteLog(SiteId, "修改图片上传设置"); + + SuccessMessage("上传图片设置修改成功!"); + } + catch(Exception ex) + { + FailMessage(ex, "上传图片设置修改失败!"); + } + } + + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/PageConfigurationUploadVideo.cs b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationUploadVideo.cs new file mode 100644 index 000000000..8aa2691b6 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationUploadVideo.cs @@ -0,0 +1,94 @@ +using System; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageConfigurationUploadVideo : BasePageCms + { + public TextBox TbVideoUploadDirectoryName; + public DropDownList DdlVideoUploadDateFormatString; + public DropDownList DdlIsVideoUploadChangeFileName; + public TextBox TbVideoUploadTypeCollection; + public DropDownList DdlVideoUploadTypeUnit; + public TextBox TbVideoUploadTypeMaxSize; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId"); + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); + + TbVideoUploadDirectoryName.Text = SiteInfo.VideoUploadDirectoryName; + + DdlVideoUploadDateFormatString.Items.Add(new ListItem("按年存入不同目录(不推荐)", EDateFormatTypeUtils.GetValue(EDateFormatType.Year))); + DdlVideoUploadDateFormatString.Items.Add(new ListItem("按年/月存入不同目录", EDateFormatTypeUtils.GetValue(EDateFormatType.Month))); + DdlVideoUploadDateFormatString.Items.Add(new ListItem("按年/月/日存入不同目录", EDateFormatTypeUtils.GetValue(EDateFormatType.Day))); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlVideoUploadDateFormatString, SiteInfo.VideoUploadDateFormatString); + + FxUtils.AddListItems(DdlIsVideoUploadChangeFileName, "自动修改文件名", "保持文件名不变"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsVideoUploadChangeFileName, SiteInfo.IsVideoUploadChangeFileName.ToString()); + + TbVideoUploadTypeCollection.Text = SiteInfo.VideoUploadTypeCollection.Replace("|", ","); + var mbSize = GetMbSize(SiteInfo.VideoUploadTypeMaxSize); + if (mbSize == 0) + { + DdlVideoUploadTypeUnit.SelectedIndex = 0; + TbVideoUploadTypeMaxSize.Text = SiteInfo.VideoUploadTypeMaxSize.ToString(); + } + else + { + DdlVideoUploadTypeUnit.SelectedIndex = 1; + TbVideoUploadTypeMaxSize.Text = mbSize.ToString(); + } + } + + private static int GetMbSize(int kbSize) + { + var retval = 0; + if (kbSize >= 1024 && ((kbSize % 1024) == 0)) + { + retval = kbSize / 1024; + } + return retval; + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (Page.IsPostBack && Page.IsValid) + { + SiteInfo.VideoUploadDirectoryName = TbVideoUploadDirectoryName.Text; + + SiteInfo.VideoUploadDateFormatString = EDateFormatTypeUtils.GetValue(EDateFormatTypeUtils.GetEnumType(DdlVideoUploadDateFormatString.SelectedValue)); + SiteInfo.IsVideoUploadChangeFileName = TranslateUtils.ToBool(DdlIsVideoUploadChangeFileName.SelectedValue); + + SiteInfo.VideoUploadTypeCollection = TbVideoUploadTypeCollection.Text.Replace(",", "|"); + var kbSize = int.Parse(TbVideoUploadTypeMaxSize.Text); + SiteInfo.VideoUploadTypeMaxSize = (DdlVideoUploadTypeUnit.SelectedIndex == 0) ? kbSize : 1024 * kbSize; + + try + { + DataProvider.Site.Update(SiteInfo); + + AuthRequest.AddSiteLog(SiteId, "修改视频上传设置"); + + SuccessMessage("上传视频设置修改成功!"); + } + catch(Exception ex) + { + FailMessage(ex, "上传视频设置修改失败!"); + } + } + } + + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/PageConfigurationWaterMark.cs b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationWaterMark.cs new file mode 100644 index 000000000..95201d022 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageConfigurationWaterMark.cs @@ -0,0 +1,167 @@ +using System; +using System.Drawing.Text; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageConfigurationWaterMark : BasePageCms + { + public DropDownList DdlIsWaterMark; + public Literal LtlWaterMarkPosition; + public PlaceHolder PhWaterMarkPosition; + public DropDownList DdlWaterMarkTransparency; + public PlaceHolder PhWaterMarkTransparency; + public TextBox TbWaterMarkMinWidth; + public TextBox TbWaterMarkMinHeight; + public PlaceHolder PhWaterMarkMin; + public DropDownList DdlIsImageWaterMark; + public PlaceHolder PhIsImageWaterMark; + public TextBox TbWaterMarkFormatString; + public PlaceHolder PhWaterMarkFormatString; + public DropDownList DdlWaterMarkFontName; + public PlaceHolder PhWaterMarkFontName; + public TextBox TbWaterMarkFontSize; + public PlaceHolder PhWaterMarkFontSize; + public TextBox TbWaterMarkImagePath; + public PlaceHolder PhWaterMarkImagePath; + public Button BtnImageUrlSelect; + public Button BtnImageUrlUpload; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId"); + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); + + FxUtils.AddListItems(DdlIsWaterMark); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsWaterMark, SiteInfo.IsWaterMark.ToString()); + + LoadWaterMarkPosition(SiteInfo.WaterMarkPosition); + + for (var i = 1; i <= 10; i++) + { + DdlWaterMarkTransparency.Items.Add(new ListItem(i + "0%", i.ToString())); + } + SystemWebUtils.SelectSingleItemIgnoreCase(DdlWaterMarkTransparency, SiteInfo.WaterMarkTransparency.ToString()); + + TbWaterMarkMinWidth.Text = SiteInfo.WaterMarkMinWidth.ToString(); + TbWaterMarkMinHeight.Text = SiteInfo.WaterMarkMinHeight.ToString(); + + FxUtils.AddListItems(DdlIsImageWaterMark, "图片型", "文字型"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsImageWaterMark, SiteInfo.IsImageWaterMark.ToString()); + + TbWaterMarkFormatString.Text = SiteInfo.WaterMarkFormatString; + + LoadSystemFont(); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlWaterMarkFontName, SiteInfo.WaterMarkFontName); + + TbWaterMarkFontSize.Text = SiteInfo.WaterMarkFontSize.ToString(); + + TbWaterMarkImagePath.Text = SiteInfo.WaterMarkImagePath; + + DdlIsWaterMark_SelectedIndexChanged(null, null); + TbWaterMarkImagePath.Attributes.Add("onchange", GetShowImageScript("preview_WaterMarkImagePath", SiteInfo.WebUrl)); + + var showPopWinString = ModalSelectImage.GetOpenWindowString(SiteInfo, TbWaterMarkImagePath.ClientID); + BtnImageUrlSelect.Attributes.Add("onclick", showPopWinString); + + showPopWinString = ModalUploadImageSingle.GetOpenWindowStringToTextBox(SiteId, TbWaterMarkImagePath.ClientID); + BtnImageUrlUpload.Attributes.Add("onclick", showPopWinString); + } + + private void LoadWaterMarkPosition (int selectPosition) + { + LtlWaterMarkPosition.Text = ""; + for (var i = 1;i < 10; i++) + { + if (i % 3 == 1) + { + LtlWaterMarkPosition.Text = LtlWaterMarkPosition.Text + ""; + } + if (selectPosition == i) + { + object obj1 = LtlWaterMarkPosition.Text; + LtlWaterMarkPosition.Text = string.Concat(obj1, ""); + } + else + { + object obj2 = LtlWaterMarkPosition.Text; + LtlWaterMarkPosition.Text = string.Concat(obj2, ""); + } + if (i % 3 == 0) + { + LtlWaterMarkPosition.Text = LtlWaterMarkPosition.Text + ""; + } + } + LtlWaterMarkPosition.Text = LtlWaterMarkPosition.Text + "
    #", i, "#", i, "
    "; + } + + private void LoadSystemFont() + { + var familyArray = new InstalledFontCollection().Families; + foreach (var family in familyArray) + { + DdlWaterMarkFontName.Items.Add(new ListItem(family.Name, family.Name)); + } + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + SiteInfo.IsWaterMark = TranslateUtils.ToBool(DdlIsWaterMark.SelectedValue); + SiteInfo.WaterMarkPosition = TranslateUtils.ToInt(Request.Form["WaterMarkPosition"]); + SiteInfo.WaterMarkTransparency = TranslateUtils.ToInt(DdlWaterMarkTransparency.SelectedValue); + SiteInfo.WaterMarkMinWidth = TranslateUtils.ToInt(TbWaterMarkMinWidth.Text); + SiteInfo.WaterMarkMinHeight = TranslateUtils.ToInt(TbWaterMarkMinHeight.Text); + SiteInfo.IsImageWaterMark = TranslateUtils.ToBool(DdlIsImageWaterMark.SelectedValue); + SiteInfo.WaterMarkFormatString = TbWaterMarkFormatString.Text; + SiteInfo.WaterMarkFontName = DdlWaterMarkFontName.SelectedValue; + SiteInfo.WaterMarkFontSize = TranslateUtils.ToInt(TbWaterMarkFontSize.Text); + SiteInfo.WaterMarkImagePath = TbWaterMarkImagePath.Text; + + try + { + DataProvider.Site.Update(SiteInfo); + AuthRequest.AddSiteLog(SiteId, "修改图片水印设置"); + SuccessMessage("图片水印设置修改成功!"); + } + catch(Exception ex) + { + FailMessage(ex, "图片水印设置修改失败!"); + } + } + + public void DdlIsWaterMark_SelectedIndexChanged(object sender, EventArgs e) + { + if (EBooleanUtils.Equals(DdlIsWaterMark.SelectedValue, EBoolean.True)) + { + PhWaterMarkPosition.Visible = PhWaterMarkTransparency.Visible = PhWaterMarkMin.Visible = PhIsImageWaterMark.Visible = true; + if (EBooleanUtils.Equals(DdlIsImageWaterMark.SelectedValue, EBoolean.True)) + { + PhWaterMarkFormatString.Visible = PhWaterMarkFontName.Visible = PhWaterMarkFontSize.Visible = false; + PhWaterMarkImagePath.Visible = true; + } + else + { + PhWaterMarkFormatString.Visible = PhWaterMarkFontName.Visible = PhWaterMarkFontSize.Visible = true; + PhWaterMarkImagePath.Visible = false; + } + } + else + { + PhWaterMarkPosition.Visible = PhWaterMarkTransparency.Visible = PhWaterMarkMin.Visible = PhIsImageWaterMark.Visible = PhWaterMarkFormatString.Visible = PhWaterMarkFontName.Visible = PhWaterMarkFontSize.Visible = PhWaterMarkImagePath.Visible = false; + } + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/PageContent.cs b/net452/SiteServer.BackgroundPages/Cms/PageContent.cs new file mode 100644 index 000000000..8bdf6b951 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageContent.cs @@ -0,0 +1,233 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Data; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Controls; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin; +using SiteServer.Plugin; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageContent : BasePageCms + { + public Literal LtlButtonsHead; + public Literal LtlButtonsFoot; + + public Repeater RptContents; + public Pager PgContents; + public Literal LtlColumnsHead; + public DateTimeTextBox TbDateFrom; + public DropDownList DdlSearchType; + public TextBox TbKeyword; + + private ChannelInfo _channelInfo; + private string _tableName; + private List _styleInfoList; + private StringCollection _attributesOfDisplay; + private List _allStyleInfoList; + private List _pluginIds; + private Dictionary>> _pluginColumns; + private bool _isEdit; + private readonly Dictionary _nameValueCacheDict = new Dictionary(); + + protected override bool IsSinglePage => true; + + public static string GetRedirectUrl(int siteId, int channelId) + { + return PageUtils.GetCmsUrl(siteId, nameof(PageContent), new NameValueCollection + { + {"channelId", channelId.ToString()} + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + PageUtils.CheckRequestParameter("siteId", "channelId"); + var channelId = AuthRequest.GetQueryInt("channelId"); + _channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + + _tableName = ChannelManager.GetTableName(SiteInfo, _channelInfo); + _styleInfoList = TableStyleManager.GetContentStyleInfoList(SiteInfo, _channelInfo); + _attributesOfDisplay = TranslateUtils.StringCollectionToStringCollection(ChannelManager.GetContentAttributesOfDisplay(SiteId, channelId)); + _allStyleInfoList = ContentUtility.GetAllTableStyleInfoList(_styleInfoList); + + _pluginIds = PluginContentManager.GetContentPluginIds(_channelInfo); + _pluginColumns = PluginContentManager.GetContentColumns(_pluginIds); + _isEdit = TextUtility.IsEdit(SiteInfo, channelId, AuthRequest.AdminPermissionsImpl); + + if (_channelInfo.Extend.IsPreviewContentsExists) + { + new Action(() => + { + _channelInfo.ContentRepository.DeletePreviewContents(SiteId, _channelInfo); + }).BeginInvoke(null, null); + } + + if (!HasChannelPermissions(channelId, ConfigManager.ChannelPermissions.ContentView, ConfigManager.ChannelPermissions.ContentAdd, ConfigManager.ChannelPermissions.ContentEdit, ConfigManager.ChannelPermissions.ContentDelete, ConfigManager.ChannelPermissions.ContentTranslate)) + { + if (!AuthRequest.IsAdminLoggin) + { + PageUtils.RedirectToLoginPage(); + return; + } + PageUtils.RedirectToErrorPage("您无此栏目的操作权限!"); + return; + } + + RptContents.ItemDataBound += RptContents_ItemDataBound; + + var allAttributeNameList = TableColumnManager.GetTableColumnNameList(_tableName, DataType.Text); + var pagerParam = new PagerParam + { + ControlToPaginate = RptContents, + TableName = _tableName, + PageSize = SiteInfo.Extend.PageSize, + Page = AuthRequest.GetQueryInt(Pager.QueryNamePage, 1), + OrderSqlString = DataProvider.ContentRepository.GetOrderString(_channelInfo, string.Empty), + ReturnColumnNames = allAttributeNameList + }; + + var administratorName = AuthRequest.AdminPermissionsImpl.IsViewContentOnlySelf(SiteId, channelId) ? AuthRequest.AdminName : string.Empty; + + if (AuthRequest.IsQueryExists("searchType")) + { + pagerParam.WhereSqlString = DataProvider.ContentRepository.GetPagerWhereSqlString(SiteInfo, _channelInfo, AuthRequest.GetQueryString("searchType"), AuthRequest.GetQueryString("keyword"), + AuthRequest.GetQueryString("dateFrom"), string.Empty, CheckManager.LevelInt.All, false, true, false, false, false, AuthRequest.AdminPermissionsImpl, allAttributeNameList); + pagerParam.TotalCount = + DatabaseApi.Instance.GetPageTotalCount(_tableName, pagerParam.WhereSqlString); + } + else + { + pagerParam.WhereSqlString = DataProvider.ContentRepository.GetPagerWhereSqlString(channelId, ETriState.All, administratorName); + var count = ContentManager.GetCount(SiteInfo, _channelInfo); + pagerParam.TotalCount = count; + } + + PgContents.Param = pagerParam; + + if (IsPostBack) return; + + PgContents.DataBind(); + + var btnHtmls = WebUtils.GetContentCommands(AuthRequest.AdminPermissionsImpl, SiteInfo, _channelInfo, PageUrl); + var btnDropDownsHtml = + WebUtils.GetContentMoreCommands(AuthRequest.AdminPermissionsImpl, SiteInfo, _channelInfo, PageUrl); + LtlButtonsHead.Text = GetButtonsHtml(true, btnHtmls, btnDropDownsHtml); + if (pagerParam.TotalCount > 10) + { + LtlButtonsFoot.Text = GetButtonsHtml(false, btnHtmls, btnDropDownsHtml); + } + + foreach (var styleInfo in _allStyleInfoList) + { + if (styleInfo.Type == InputType.TextEditor) continue; + + var listitem = new ListItem(styleInfo.DisplayName, styleInfo.AttributeName); + DdlSearchType.Items.Add(listitem); + } + + if (AuthRequest.IsQueryExists("searchType")) + { + TbDateFrom.Text = AuthRequest.GetQueryString("dateFrom"); + ControlUtils.SelectSingleItem(DdlSearchType, AuthRequest.GetQueryString("searchType")); + TbKeyword.Text = AuthRequest.GetQueryString("keyword"); + if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("searchType")) || !string.IsNullOrEmpty(TbDateFrom.Text) || + !string.IsNullOrEmpty(TbKeyword.Text)) + { + LtlButtonsHead.Text += @" + +"; + } + + } + else + { + ControlUtils.SelectSingleItem(DdlSearchType, ContentAttribute.Title); + } + + LtlColumnsHead.Text = TextUtility.GetColumnsHeadHtml(_styleInfoList, _pluginColumns, _attributesOfDisplay); + } + + private static string GetButtonsHtml(bool isHead, string btnsHtml, string btnDropDownsHtml) + { + return $@"
    +
    + {btnsHtml} +
    + +
    + +
    + {btnDropDownsHtml} +
    +
    +
    "; + } + + private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var contentInfo = new ContentInfo((IDataRecord)e.Item.DataItem); + + var ltlTitle = (Literal)e.Item.FindControl("ltlTitle"); + var ltlColumns = (Literal)e.Item.FindControl("ltlColumns"); + var ltlStatus = (Literal)e.Item.FindControl("ltlStatus"); + var ltlCommands = (Literal)e.Item.FindControl("ltlCommands"); + var ltlSelect = (Literal)e.Item.FindControl("ltlSelect"); + + ltlTitle.Text = WebUtils.GetContentTitle(SiteInfo, contentInfo, PageUrl); + + ltlColumns.Text = TextUtility.GetColumnsHtml(_nameValueCacheDict, SiteInfo, contentInfo, _attributesOfDisplay, _allStyleInfoList, _pluginColumns); + + ltlStatus.Text = + $@"{CheckManager.GetCheckState(SiteInfo, contentInfo)}"; + + var pluginMenus = PluginMenuManager.GetContentMenus(_pluginIds, contentInfo); + ltlCommands.Text = TextUtility.GetCommandsHtml(SiteInfo, pluginMenus, contentInfo, PageUrl, AuthRequest.AdminName, _isEdit); + + ltlSelect.Text = $@""; + } + + public void Search_OnClick(object sender, EventArgs e) + { + PageUtils.Redirect(PageUrl); + } + + private string _pageUrl; + private string PageUrl + { + get + { + if (string.IsNullOrEmpty(_pageUrl)) + { + _pageUrl = PageUtils.GetCmsUrl(SiteId, nameof(PageContent), new NameValueCollection + { + {"channelId", _channelInfo.Id.ToString()}, + {"dateFrom", TbDateFrom.Text}, + {"searchType", DdlSearchType.SelectedValue}, + {"keyword", TbKeyword.Text}, + {"page", AuthRequest.GetQueryInt("page", 1).ToString()} + }); + } + return _pageUrl; + } + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/PageContentAdd.cs b/net452/SiteServer.BackgroundPages/Cms/PageContentAdd.cs new file mode 100644 index 000000000..ed38a3c1b --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageContentAdd.cs @@ -0,0 +1,539 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Ajax; +using SiteServer.BackgroundPages.Controls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Core.Office; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin; +using SiteServer.Plugin; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageContentAdd : BasePageCms + { + public Literal LtlPageTitle; + + public TextBox TbTitle; + public Literal LtlTitleHtml; + public AuxiliaryControl AcAttributes; + public CheckBoxList CblContentAttributes; + public CheckBoxList CblContentGroups; + public Button BtnContentGroupAdd; + public DropDownList DdlContentLevel; + public TextBox TbTags; + public Literal LtlTags; + public PlaceHolder PhTranslate; + public Button BtnTranslate; + public DropDownList DdlTranslateType; + public PlaceHolder PhStatus; + public TextBox TbLinkUrl; + public DateTimeTextBox TbAddDate; + public Button BtnSubmit; + + private ChannelInfo _channelInfo; + private List _styleInfoList; + private string _tableName; + + protected override bool IsSinglePage => true; + + public string PageContentAddHandlerUrl => PageContentAddHandler.GetRedirectUrl(SiteId, AuthRequest.GetQueryInt("channelId"), AuthRequest.GetQueryInt("id")); + + public string AjaxGetDetectionReplaceUrl => AjaxCmsService.GetDetectionReplaceUrl(SiteId); + + public static string GetRedirectUrlOfAdd(int siteId, int channelId, string returnUrl) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageContentAdd), new NameValueCollection + { + {"channelId", channelId.ToString()}, + {"returnUrl", StringUtils.ValueToUrl(returnUrl)} + }); + } + + public static string GetRedirectUrlOfEdit(int siteId, int channelId, int id, string returnUrl) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageContentAdd), new NameValueCollection + { + {"channelId", channelId.ToString()}, + {"id", id.ToString()}, + {"returnUrl", StringUtils.ValueToUrl(returnUrl)} + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "channelId"); + + var channelId = AuthRequest.GetQueryInt("channelId"); + var contentId = AuthRequest.GetQueryInt("id"); + ReturnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("returnUrl")); + if (string.IsNullOrEmpty(ReturnUrl)) + { + ReturnUrl = AdminPagesUtils.Cms.GetContentsUrl(SiteId, channelId); + } + + _channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + _tableName = ChannelManager.GetTableName(SiteInfo, _channelInfo); + ContentInfo contentInfo = null; + _styleInfoList = TableStyleManager.GetContentStyleInfoList(SiteInfo, _channelInfo); + + if (!IsPermissions(contentId)) return; + + if (contentId > 0) + { + contentInfo = ContentManager.GetContentInfo(SiteInfo, _channelInfo, contentId); + } + + var titleFormat = IsPostBack ? Request.Form[ContentAttribute.GetFormatStringAttributeName(ContentAttribute.Title)] : contentInfo?.Get(ContentAttribute.GetFormatStringAttributeName(ContentAttribute.Title)); + LtlTitleHtml.Text = ContentUtility.GetTitleHtml(titleFormat, AjaxCmsService.GetTitlesUrl(SiteId, _channelInfo.Id)); + + AcAttributes.SiteInfo = SiteInfo; + AcAttributes.ChannelId = _channelInfo.Id; + AcAttributes.ContentId = contentId; + AcAttributes.StyleInfoList = _styleInfoList; + + if (!IsPostBack) + { + var pageTitle = contentId == 0 ? "添加内容" : "编辑内容"; + + LtlPageTitle.Text = pageTitle; + + if (HasChannelPermissions(_channelInfo.Id, ConfigManager.ChannelPermissions.ContentTranslate)) + { + PhTranslate.Visible = true; + BtnTranslate.Attributes.Add("onclick", ModalChannelMultipleSelect.GetOpenWindowString(SiteId, true)); + + SystemWebUtils.AddListItemsToETranslateContentType(DdlTranslateType, true); + SystemWebUtils.SelectSingleItem(DdlTranslateType, ETranslateContentTypeUtils.GetValue(ETranslateContentType.Copy)); + } + else + { + PhTranslate.Visible = false; + } + + CblContentAttributes.Items.Add(new ListItem("置顶", ContentAttribute.IsTop)); + CblContentAttributes.Items.Add(new ListItem("推荐", ContentAttribute.IsRecommend)); + CblContentAttributes.Items.Add(new ListItem("热点", ContentAttribute.IsHot)); + CblContentAttributes.Items.Add(new ListItem("醒目", ContentAttribute.IsColor)); + TbAddDate.DateTime = DateTime.Now; + TbAddDate.Now = true; + + var contentGroupNameList = ContentGroupManager.GetGroupNameList(SiteId); + foreach (var groupName in contentGroupNameList) + { + var item = new ListItem(groupName, groupName); + CblContentGroups.Items.Add(item); + } + + BtnContentGroupAdd.Attributes.Add("onclick", ModalContentGroupAdd.GetOpenWindowString(SiteId)); + + LtlTags.Text = ContentUtility.GetTagsHtml(AjaxCmsService.GetTagsUrl(SiteId)); + + if (HasChannelPermissions(_channelInfo.Id, ConfigManager.ChannelPermissions.ContentCheck)) + { + PhStatus.Visible = true; + int checkedLevel; + var isChecked = CheckManager.GetUserCheckLevel(AuthRequest.AdminPermissionsImpl, SiteInfo, _channelInfo.Id, out checkedLevel); + if (AuthRequest.IsQueryExists("contentLevel")) + { + checkedLevel = TranslateUtils.ToIntWithNegative(AuthRequest.GetQueryString("contentLevel")); + if (checkedLevel != CheckManager.LevelInt.NotChange) + { + isChecked = checkedLevel >= SiteInfo.CheckContentLevel; + } + } + + SystemWebUtils.LoadContentLevelToCheckEdit(DdlContentLevel, SiteInfo, contentInfo, isChecked, checkedLevel); + } + else + { + PhStatus.Visible = false; + } + + //自动检测敏感词 + BtnSubmit.Attributes.Add("onclick", + SiteInfo.IsAutoCheckKeywords + ? InputParserUtils.GetValidateSubmitOnClickScript("myForm", true, "autoCheckKeywords()") + : InputParserUtils.GetValidateSubmitOnClickScript("myForm", true, string.Empty)); + + if (contentId == 0) + { + var attributes = TableStyleManager.GetDefaultAttributes(_styleInfoList); + + if (AuthRequest.IsQueryExists("isUploadWord")) + { + var isFirstLineTitle = AuthRequest.GetQueryBool("isFirstLineTitle"); + var isFirstLineRemove = AuthRequest.GetQueryBool("isFirstLineRemove"); + var isClearFormat = AuthRequest.GetQueryBool("isClearFormat"); + var isFirstLineIndent = AuthRequest.GetQueryBool("isFirstLineIndent"); + var isClearFontSize = AuthRequest.GetQueryBool("isClearFontSize"); + var isClearFontFamily = AuthRequest.GetQueryBool("isClearFontFamily"); + var isClearImages = AuthRequest.GetQueryBool("isClearImages"); + var contentLevel = AuthRequest.GetQueryInt("contentLevel"); + var fileName = AuthRequest.GetQueryString("fileName"); + + var formCollection = WordUtils.GetWordNameValueCollection(SiteId, isFirstLineTitle, isFirstLineRemove, isClearFormat, isFirstLineIndent, isClearFontSize, isClearFontFamily, isClearImages, fileName); + + if (formCollection != null) + { + foreach (string name in formCollection) + { + var value = formCollection[name]; + attributes[name] = value; + } + } + + TbTitle.Text = formCollection[ContentAttribute.Title]; + } + + AcAttributes.Attributes = attributes; + } + else if (contentInfo != null) + { + TbTitle.Text = contentInfo.Title; + + TbTags.Text = contentInfo.Tags; + + var list = new List(); + if (contentInfo.Top) + { + list.Add(ContentAttribute.IsTop); + } + if (contentInfo.Recommend) + { + list.Add(ContentAttribute.IsRecommend); + } + if (contentInfo.Hot) + { + list.Add(ContentAttribute.IsHot); + } + if (contentInfo.Color) + { + list.Add(ContentAttribute.IsColor); + } + SystemWebUtils.SelectMultiItems(CblContentAttributes, list); + TbLinkUrl.Text = contentInfo.LinkUrl; + if (contentInfo.AddDate.HasValue) + { + TbAddDate.DateTime = contentInfo.AddDate.Value; + } + + SystemWebUtils.SelectMultiItems(CblContentGroups, TranslateUtils.StringCollectionToStringList(contentInfo.GroupNameCollection)); + + AcAttributes.Attributes = contentInfo.ToDictionary(); + } + } + else + { + AcAttributes.Attributes = TranslateUtils.ToDictionary(Request.Form); + } + //DataBind(); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + var contentId = AuthRequest.GetQueryInt("id"); + string redirectUrl; + + if (contentId == 0) + { + try + { + var tagCollection = TagUtils.ParseTagsString(TbTags.Text); + var dict = BackgroundInputTypeParser.SaveAttributes(SiteInfo, _styleInfoList, Request.Form, ContentAttribute.AllAttributes.Value); + + var contentInfo = new ContentInfo(dict) + { + ChannelId = _channelInfo.Id, + SiteId = SiteId, + AdminId = AuthRequest.AdminId, + AddUserName = AuthRequest.AdminName, + LastEditUserName = AuthRequest.AdminName, + LastEditDate = DateTime.Now, + GroupNameCollection = SystemWebUtils.SelectedItemsValueToStringCollection(CblContentGroups.Items), + Title = TbTitle.Text + }; + + var formatString = TranslateUtils.ToBool(Request.Form[ContentAttribute.Title + "_formatStrong"]); + var formatEm = TranslateUtils.ToBool(Request.Form[ContentAttribute.Title + "_formatEM"]); + var formatU = TranslateUtils.ToBool(Request.Form[ContentAttribute.Title + "_formatU"]); + var formatColor = Request.Form[ContentAttribute.Title + "_formatColor"]; + var theFormatString = ContentUtility.GetTitleFormatString(formatString, formatEm, formatU, formatColor); + contentInfo.Set(ContentAttribute.GetFormatStringAttributeName(ContentAttribute.Title), theFormatString); + + foreach (ListItem listItem in CblContentAttributes.Items) + { + var value = listItem.Selected.ToString(); + var attributeName = listItem.Value; + contentInfo.Set(attributeName, value); + } + contentInfo.LinkUrl = TbLinkUrl.Text; + contentInfo.AddDate = TbAddDate.DateTime; + if (contentInfo.AddDate.Value.Year <= DateUtils.SqlMinValue.Year) + { + contentInfo.AddDate = DateTime.Now; + } + + contentInfo.CheckedLevel = TranslateUtils.ToIntWithNegative(DdlContentLevel.SelectedValue); + contentInfo.Checked = contentInfo.CheckedLevel >= SiteInfo.CheckContentLevel; + contentInfo.Tags = TranslateUtils.ObjectCollectionToString(tagCollection, " "); + + foreach (var service in PluginManager.Services) + { + try + { + service.OnContentFormSubmit(new ContentFormSubmitEventArgs(SiteId, _channelInfo.Id, + contentInfo.Id, TranslateUtils.ToDictionary(Request.Form), contentInfo)); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(service.PluginId, ex, nameof(IService.ContentFormSubmit)); + } + } + + //判断是不是有审核权限 + var isCheckedOfUser = CheckManager.GetUserCheckLevel(AuthRequest.AdminPermissionsImpl, SiteInfo, contentInfo.ChannelId, out var checkedLevelOfUser); + if (CheckManager.IsCheckable(contentInfo.Checked, contentInfo.CheckedLevel, isCheckedOfUser, checkedLevelOfUser)) + { + if (contentInfo.Checked) + { + contentInfo.CheckedLevel = 0; + } + + contentInfo.Set(ContentAttribute.CheckUserName, AuthRequest.AdminName); + contentInfo.Set(ContentAttribute.CheckDate, DateUtils.GetDateAndTimeString(DateTime.Now)); + contentInfo.Set(ContentAttribute.CheckReasons, string.Empty); + } + + contentInfo.Id = DataProvider.ContentRepository.Insert(_tableName, SiteInfo, _channelInfo, contentInfo); + + TagUtils.AddTags(tagCollection, SiteId, contentInfo.Id); + + CreateManager.CreateContent(SiteId, _channelInfo.Id, contentInfo.Id); + CreateManager.TriggerContentChangedEvent(SiteId, _channelInfo.Id); + + AuthRequest.AddSiteLog(SiteId, _channelInfo.Id, contentInfo.Id, "添加内容", + $"栏目:{ChannelManager.GetChannelNameNavigation(SiteId, contentInfo.ChannelId)},内容标题:{contentInfo.Title}"); + + ContentManager.Translate(SiteInfo, _channelInfo.Id, contentInfo.Id, Request.Form["translateCollection"], ETranslateContentTypeUtils.GetEnumType(DdlTranslateType.SelectedValue), AuthRequest.AdminName); + + redirectUrl = PageContentAddAfter.GetRedirectUrl(SiteId, _channelInfo.Id, contentInfo.Id, + ReturnUrl); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + FailMessage($"内容添加失败:{ex.Message}"); + return; + } + } + else + { + var contentInfo = ContentManager.GetContentInfo(SiteInfo, _channelInfo, contentId); + try + { + var tagsLast = contentInfo.Tags; + + contentInfo.LastEditUserName = AuthRequest.AdminName; + contentInfo.LastEditDate = DateTime.Now; + if (contentInfo.AdminId == 0) + { + contentInfo.AdminId = AuthRequest.AdminId; + } + + var dict = BackgroundInputTypeParser.SaveAttributes(SiteInfo, _styleInfoList, Request.Form, ContentAttribute.AllAttributes.Value); + foreach (var o in dict) + { + contentInfo.Set(o.Key, o.Value); + } + + contentInfo.GroupNameCollection = SystemWebUtils.SelectedItemsValueToStringCollection(CblContentGroups.Items); + var tagCollection = TagUtils.ParseTagsString(TbTags.Text); + + contentInfo.Title = TbTitle.Text; + var formatString = TranslateUtils.ToBool(Request.Form[ContentAttribute.Title + "_formatStrong"]); + var formatEm = TranslateUtils.ToBool(Request.Form[ContentAttribute.Title + "_formatEM"]); + var formatU = TranslateUtils.ToBool(Request.Form[ContentAttribute.Title + "_formatU"]); + var formatColor = Request.Form[ContentAttribute.Title + "_formatColor"]; + var theFormatString = ContentUtility.GetTitleFormatString(formatString, formatEm, formatU, formatColor); + contentInfo.Set(ContentAttribute.GetFormatStringAttributeName(ContentAttribute.Title), theFormatString); + foreach (ListItem listItem in CblContentAttributes.Items) + { + var value = listItem.Selected.ToString(); + var attributeName = listItem.Value; + contentInfo.Set(attributeName, value); + } + contentInfo.LinkUrl = TbLinkUrl.Text; + contentInfo.AddDate = TbAddDate.DateTime; + + var checkedLevel = TranslateUtils.ToIntWithNegative(DdlContentLevel.SelectedValue); + if (checkedLevel != CheckManager.LevelInt.NotChange) + { + contentInfo.Checked = checkedLevel >= SiteInfo.CheckContentLevel; + contentInfo.CheckedLevel = checkedLevel; + } + contentInfo.Tags = TranslateUtils.ObjectCollectionToString(tagCollection, " "); + + foreach (var service in PluginManager.Services) + { + try + { + service.OnContentFormSubmit(new ContentFormSubmitEventArgs(SiteId, _channelInfo.Id, + contentInfo.Id, TranslateUtils.ToDictionary(Request.Form), contentInfo)); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(service.PluginId, ex, nameof(IService.ContentFormSubmit)); + } + } + + DataProvider.ContentRepository.Update(SiteInfo, _channelInfo, contentInfo); + + TagUtils.UpdateTags(tagsLast, contentInfo.Tags, tagCollection, SiteId, contentId); + + ContentManager.Translate(SiteInfo, _channelInfo.Id, contentInfo.Id, Request.Form["translateCollection"], ETranslateContentTypeUtils.GetEnumType(DdlTranslateType.SelectedValue), AuthRequest.AdminName); + + CreateManager.CreateContent(SiteId, _channelInfo.Id, contentId); + CreateManager.TriggerContentChangedEvent(SiteId, _channelInfo.Id); + + AuthRequest.AddSiteLog(SiteId, _channelInfo.Id, contentId, "修改内容", + $"栏目:{ChannelManager.GetChannelNameNavigation(SiteId, contentInfo.ChannelId)},内容标题:{contentInfo.Title}"); + + redirectUrl = ReturnUrl; + + //更新引用该内容的信息 + //如果不是异步自动保存,那么需要将引用此内容的content修改 + //var sourceContentIdList = new List + //{ + // contentInfo.Id + //}; + //var tableList = DataProvider.TableDao.GetTableCollectionInfoListCreatedInDb(); + //foreach (var table in tableList) + //{ + // var targetContentIdList = DataProvider.ContentRepository.GetReferenceIdList(table.TableName, sourceContentIdList); + // foreach (var targetContentId in targetContentIdList) + // { + // var targetContentInfo = DataProvider.ContentRepository.GetContentInfo(table.TableName, targetContentId); + // if (targetContentInfo == null || targetContentInfo.GetString(ContentAttribute.TranslateContentType) != ETranslateContentType.ReferenceContent.ToString()) continue; + + // contentInfo.Id = targetContentId; + // contentInfo.SiteId = targetContentInfo.SiteId; + // contentInfo.ChannelId = targetContentInfo.ChannelId; + // contentInfo.SourceId = targetContentInfo.SourceId; + // contentInfo.ReferenceId = targetContentInfo.ReferenceId; + // contentInfo.Taxis = targetContentInfo.Taxis; + // contentInfo.Set(ContentAttribute.TranslateContentType, targetContentInfo.GetString(ContentAttribute.TranslateContentType)); + // DataProvider.ContentRepository.UpdateObject(table.TableName, contentInfo); + + // //资源:图片,文件,视频 + // var targetSiteInfo = SiteManager.GetSiteInfo(targetContentInfo.SiteId); + // var bgContentInfo = contentInfo as BackgroundContentInfo; + // var bgTargetContentInfo = targetContentInfo as BackgroundContentInfo; + // if (bgTargetContentInfo != null && bgContentInfo != null) + // { + // if (bgContentInfo.ImageUrl != bgTargetContentInfo.ImageUrl) + // { + // //修改图片 + // var sourceImageUrl = PathUtility.MapPath(SiteInfo, bgContentInfo.ImageUrl); + // CopyReferenceFiles(targetSiteInfo, sourceImageUrl); + // } + // else if (bgContentInfo.GetString(ContentAttribute.GetExtendAttributeName(ContentAttribute.ImageUrl)) != bgTargetContentInfo.GetString(ContentAttribute.GetExtendAttributeName(ContentAttribute.ImageUrl))) + // { + // var sourceImageUrls = TranslateUtils.StringCollectionToStringList(bgContentInfo.GetString(ContentAttribute.GetExtendAttributeName(ContentAttribute.ImageUrl))); + + // foreach (string imageUrl in sourceImageUrls) + // { + // var sourceImageUrl = PathUtility.MapPath(SiteInfo, imageUrl); + // CopyReferenceFiles(targetSiteInfo, sourceImageUrl); + // } + // } + // if (bgContentInfo.FileUrl != bgTargetContentInfo.FileUrl) + // { + // //修改附件 + // var sourceFileUrl = PathUtility.MapPath(SiteInfo, bgContentInfo.FileUrl); + // CopyReferenceFiles(targetSiteInfo, sourceFileUrl); + + // } + // else if (bgContentInfo.GetString(ContentAttribute.GetExtendAttributeName(ContentAttribute.FileUrl)) != bgTargetContentInfo.GetString(ContentAttribute.GetExtendAttributeName(ContentAttribute.FileUrl))) + // { + // var sourceFileUrls = TranslateUtils.StringCollectionToStringList(bgContentInfo.GetString(ContentAttribute.GetExtendAttributeName(ContentAttribute.FileUrl))); + + // foreach (var fileUrl in sourceFileUrls) + // { + // var sourceFileUrl = PathUtility.MapPath(SiteInfo, fileUrl); + // CopyReferenceFiles(targetSiteInfo, sourceFileUrl); + // } + // } + // } + // } + //} + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + FailMessage($"内容修改失败:{ex.Message}"); + return; + } + } + + WebPageUtils.Redirect(redirectUrl); + } + + private bool IsPermissions(int contentId) + { + if (contentId == 0) + { + if (_channelInfo == null || _channelInfo.IsContentAddable == false) + { + WebPageUtils.RedirectToErrorPage("此栏目不能添加内容!"); + return false; + } + + if (!HasChannelPermissions(_channelInfo.Id, ConfigManager.ChannelPermissions.ContentAdd)) + { + if (!AuthRequest.IsAdminLoggin) + { + WebPageUtils.RedirectToLoginPage(); + return false; + } + + WebPageUtils.RedirectToErrorPage("您无此栏目的添加内容权限!"); + return false; + } + } + else + { + if (!HasChannelPermissions(_channelInfo.Id, ConfigManager.ChannelPermissions.ContentEdit)) + { + if (!AuthRequest.IsAdminLoggin) + { + WebPageUtils.RedirectToLoginPage(); + return false; + } + + WebPageUtils.RedirectToErrorPage("您无此栏目的修改内容权限!"); + return false; + } + } + return true; + } + + public string ReturnUrl { get; private set; } + } +} diff --git a/SiteServer.BackgroundPages/Cms/PageContentAddAfter.cs b/net452/SiteServer.BackgroundPages/Cms/PageContentAddAfter.cs similarity index 87% rename from SiteServer.BackgroundPages/Cms/PageContentAddAfter.cs rename to net452/SiteServer.BackgroundPages/Cms/PageContentAddAfter.cs index 309aa24a4..ec91ada78 100644 --- a/SiteServer.BackgroundPages/Cms/PageContentAddAfter.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageContentAddAfter.cs @@ -3,8 +3,11 @@ using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Cms { @@ -29,7 +32,7 @@ public enum EContentAddAfter public static string GetRedirectUrl(int siteId, int channelId, int contentId, string returnUrl) { - return PageUtils.GetCmsUrl(siteId, nameof(PageContentAddAfter), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageContentAddAfter), new NameValueCollection { {"channelId", channelId.ToString()}, {"ContentID", contentId.ToString()}, @@ -41,7 +44,7 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId", "channelId", "ContentID", "ReturnUrl"); + WebPageUtils.CheckRequestParameter("siteId", "channelId", "ContentID", "ReturnUrl"); var channelId = AuthRequest.GetQueryInt("channelId"); _contentId = AuthRequest.GetQueryInt("ContentID"); _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); @@ -72,15 +75,15 @@ public void RblOperation_SelectedIndexChanged(object sender, EventArgs e) var after = (EContentAddAfter)TranslateUtils.ToEnum(typeof(EContentAddAfter), RblOperation.SelectedValue, EContentAddAfter.ContinueAdd); if (after == EContentAddAfter.ContinueAdd) { - PageUtils.Redirect(WebUtils.GetContentAddAddUrl(SiteId, _channelInfo, AuthRequest.GetQueryString("ReturnUrl"))); + WebPageUtils.Redirect(WebUtils.GetContentAddAddUrl(SiteId, _channelInfo, AuthRequest.GetQueryString("ReturnUrl"))); } else if (after == EContentAddAfter.ManageContents) { - PageUtils.Redirect(_returnUrl); + WebPageUtils.Redirect(_returnUrl); } else if (after == EContentAddAfter.Contribute) { - CrossSiteTransUtility.LoadSiteIdDropDownList(DdlSiteId, SiteInfo, _channelInfo.Id); + SystemWebUtils.LoadSiteIdDropDownList(DdlSiteId, SiteInfo, _channelInfo.Id); if (DdlSiteId.Items.Count > 0) { @@ -93,7 +96,7 @@ public void RblOperation_SelectedIndexChanged(object sender, EventArgs e) public void DdlSiteId_SelectedIndexChanged(object sender, EventArgs e) { var psId = int.Parse(DdlSiteId.SelectedValue); - CrossSiteTransUtility.LoadChannelIdListBox(LbChannelId, SiteInfo, psId, _channelInfo, AuthRequest.AdminPermissions); + SystemWebUtils.LoadChannelIdListBox(LbChannelId, SiteInfo, psId, _channelInfo, AuthRequest.AdminPermissionsImpl); } public override void Submit_OnClick(object sender, EventArgs e) diff --git a/SiteServer.BackgroundPages/Cms/PageContentAddHandler.cs b/net452/SiteServer.BackgroundPages/Cms/PageContentAddHandler.cs similarity index 78% rename from SiteServer.BackgroundPages/Cms/PageContentAddHandler.cs rename to net452/SiteServer.BackgroundPages/Cms/PageContentAddHandler.cs index b8fc042bf..ffc7f4231 100644 --- a/SiteServer.BackgroundPages/Cms/PageContentAddHandler.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageContentAddHandler.cs @@ -1,9 +1,13 @@ using System; using System.Collections.Specialized; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Api.Preview; +using SiteServer.CMS.Caches; using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Core.RestRoutes.Preview; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.CMS.Plugin; using SiteServer.Plugin; using SiteServer.Utils; @@ -14,7 +18,7 @@ public class PageContentAddHandler : BaseHandler { public static string GetRedirectUrl(int siteId, int channelId, int contentId) { - return PageUtils.GetCmsWebHandlerUrl(siteId, nameof(PageContentAddHandler), new NameValueCollection + return FxUtils.GetCmsWebHandlerUrl(siteId, nameof(PageContentAddHandler), new NameValueCollection { {"channelId", channelId.ToString()}, {"contentId", contentId.ToString()} @@ -29,11 +33,13 @@ protected override object Process() var siteInfo = SiteManager.GetSiteInfo(siteId); var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); - var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(siteId, channelId); var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); - var styleInfoList = TableStyleManager.GetTableStyleInfoList(tableName, relatedIdentities); + var styleInfoList = TableStyleManager.GetContentStyleInfoList(siteInfo, channelInfo); - var contentInfo = new ContentInfo + var form = AuthRequest.HttpRequest.Form; + + var dict = BackgroundInputTypeParser.SaveAttributes(siteInfo, styleInfoList, form, ContentAttribute.AllAttributes.Value); + var contentInfo = new ContentInfo(dict) { ChannelId = channelId, SiteId = siteId, @@ -42,10 +48,6 @@ protected override object Process() LastEditDate = DateTime.Now }; - var form = AuthRequest.HttpRequest.Form; - - BackgroundInputTypeParser.SaveAttributes(contentInfo, siteInfo, styleInfoList, form, ContentAttribute.AllAttributesLowercase); - //contentInfo.GroupNameCollection = ControlUtils.SelectedItemsValueToStringCollection(CblContentGroups.Items); var tagCollection = TagUtils.ParseTagsString(form["TbTags"]); @@ -64,15 +66,14 @@ protected override object Process() //} //contentInfo.LinkUrl = TbLinkUrl.Text; contentInfo.AddDate = TranslateUtils.ToDateTime(form["TbAddDate"]); - contentInfo.IsChecked = false; + contentInfo.Checked = false; contentInfo.Tags = TranslateUtils.ObjectCollectionToString(tagCollection, " "); foreach (var service in PluginManager.Services) { try { - service.OnContentFormSubmit(new ContentFormSubmitEventArgs(siteId, channelId, - contentInfo, new ExtendedAttributes(form))); + service.OnContentFormSubmit(new ContentFormSubmitEventArgs(siteId, channelId, contentInfo.Id, TranslateUtils.ToDictionary(form), contentInfo)); } catch (Exception ex) { @@ -80,7 +81,7 @@ protected override object Process() } } - contentInfo.Id = DataProvider.ContentDao.InsertPreview(tableName, siteInfo, channelInfo, contentInfo); + contentInfo.Id = DataProvider.ContentRepository.InsertPreview(tableName, siteInfo, channelInfo, contentInfo); return new { diff --git a/net452/SiteServer.BackgroundPages/Cms/PageContentDelete.cs b/net452/SiteServer.BackgroundPages/Cms/PageContentDelete.cs new file mode 100644 index 000000000..cf48e53be --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageContentDelete.cs @@ -0,0 +1,213 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Text; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageContentDelete : BasePageCms + { + public Literal LtlContents; + public PlaceHolder PhRetain; + public RadioButtonList RblRetainFiles; + + private Dictionary> _idsDictionary = new Dictionary>(); + private bool _isDeleteFromTrash; + private string _returnUrl; + + public static string GetRedirectClickStringForMultiChannels(int siteId, bool isDeleteFromTrash, + string returnUrl) + { + return PageUtils.GetRedirectStringWithCheckBoxValue(FxUtils.GetCmsUrl(siteId, nameof(PageContentDelete), + new NameValueCollection + { + {"IsDeleteFromTrash", isDeleteFromTrash.ToString()}, + {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} + }), "IDsCollection", "IDsCollection", "请选择需要删除的内容!"); + } + + public static string GetRedirectClickStringForSingleChannel(int siteId, int channelId, + bool isDeleteFromTrash, string returnUrl) + { + return PageUtils.GetRedirectStringWithCheckBoxValue(FxUtils.GetCmsUrl(siteId, nameof(PageContentDelete), + new NameValueCollection + { + {"channelId", channelId.ToString()}, + {"IsDeleteFromTrash", isDeleteFromTrash.ToString()}, + {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} + }), "contentIdCollection", "contentIdCollection", "请选择需要删除的内容!"); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "ReturnUrl"); + _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); + _isDeleteFromTrash = AuthRequest.GetQueryBool("IsDeleteFromTrash"); + _idsDictionary = ContentUtility.GetIDsDictionary(Request.QueryString); + + //if (this.channelId > 0) + //{ + // this.nodeInfo = NodeManager.GetChannelInfo(base.SiteId, this.channelId); + //} + //else + //{ + // this.nodeInfo = NodeManager.GetChannelInfo(base.SiteId, -this.channelId); + //} + //if (this.nodeInfo != null) + //{ + // this.tableStyle = NodeManager.GetTableStyle(base.SiteInfo, nodeInfo); + // this.tableName = NodeManager.GetTableName(base.SiteInfo, nodeInfo); + //} + + //if (this.contentID == 0) + //{ + // if (!base.HasChannelPermissions(Math.Abs(this.channelId), AppManager.CMS.Permission.Channel.ContentDelete)) + // { + // WebPageUtils.RedirectToErrorPage("您没有删除此栏目内容的权限!"); + // return; + // } + //} + //else + //{ + // ContentInfo contentInfo = DataProvider.ContentDAO.GetContentInfo(this.tableStyle, this.tableName, this.contentID); + + // if (contentInfo == null || !string.Equals(AuthRequest.AdminName, contentInfo.AddUserName)) + // { + // if (!base.HasChannelPermissions(Math.Abs(this.channelId), AppManager.CMS.Permission.Channel.ContentDelete)) + // { + // WebPageUtils.RedirectToErrorPage("您没有删除此栏目内容的权限!"); + // return; + // } + // } + //} + + if (IsPostBack) return; + + var builder = new StringBuilder(); + foreach (var channelId in _idsDictionary.Keys) + { + var contentIdList = _idsDictionary[channelId]; + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(SiteInfo, channelId, contentId); + if (contentInfo != null) + { + builder.Append( + $@"{WebUtils.GetContentTitle(SiteInfo, contentInfo, _returnUrl)}
    "); + } + } + } + LtlContents.Text = builder.ToString(); + + if (!_isDeleteFromTrash) + { + PhRetain.Visible = true; + InfoMessage("此操作将把所选内容放入回收站,确定吗?"); + } + else + { + PhRetain.Visible = false; + InfoMessage("此操作将从回收站中彻底删除所选内容,确定吗?"); + } + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + try + { + foreach (var channelId in _idsDictionary.Keys) + { + var channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + + var tableName = ChannelManager.GetTableName(SiteInfo, channelId); + var contentIdList = _idsDictionary[channelId]; + + if (!_isDeleteFromTrash) + { + if (bool.Parse(RblRetainFiles.SelectedValue) == false) + { + DeleteManager.DeleteContents(SiteInfo, channelId, contentIdList); + SuccessMessage("成功删除内容以及生成页面!"); + } + else + { + SuccessMessage("成功删除内容,生成页面未被删除!"); + } + + if (contentIdList.Count == 1) + { + var contentId = contentIdList[0]; + if (channelInfo.ContentRepository.GetChanelIdAndValue(contentId, ContentAttribute.Title, + out var contentChannelId, out string contentTitle)) + { + AuthRequest.AddSiteLog(SiteId, contentChannelId, contentId, "删除内容", + $"栏目:{ChannelManager.GetChannelNameNavigation(SiteId, contentChannelId)},内容标题:{contentTitle}"); + } + } + else + { + AuthRequest.AddSiteLog(SiteId, "批量删除内容", + $"栏目:{ChannelManager.GetChannelNameNavigation(SiteId, channelId)},内容条数:{contentIdList.Count}"); + } + + channelInfo.ContentRepository.UpdateTrashContents(SiteId, channelId, contentIdList); + + //引用内容,需要删除 + //var siteTableNameList = SiteManager.GetTableNameList(); + //foreach (var siteTableName in siteTableNameList) + //{ + // var targetContentIdList = DataProvider.ContentRepository.GetReferenceIdList(siteTableName, contentIdList); + // if (targetContentIdList.Count > 0) + // { + // var targetContentInfo = ContentManager.GetContentInfo(siteTableName, TranslateUtils.ToInt(targetContentIdList[0].ToString())); + // DataProvider.ContentRepository.DeleteContents(targetContentInfo.SiteId, siteTableName, targetContentIdList, targetContentInfo.ChannelId); + // } + //} + + CreateManager.TriggerContentChangedEvent(SiteId, channelId); + } + else + { + SuccessMessage("成功从回收站清空内容!"); + //channelInfo.ContentRepository.DeleteContents(SiteId, contentIdList, channelId); + + foreach (var contentId in contentIdList) + { + ContentManager.Delete(SiteInfo, channelInfo, contentId); + } + + AuthRequest.AddSiteLog(SiteId, "从回收站清空内容", $"内容条数:{contentIdList.Count}"); + } + } + + + AddWaitAndRedirectScript(_returnUrl); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + FailMessage(ex, "删除内容失败!"); + } + } + + public void Return_OnClick(object sender, EventArgs e) + { + WebPageUtils.Redirect(_returnUrl); + } + + } +} diff --git a/SiteServer.BackgroundPages/Cms/PageContentGroup.cs b/net452/SiteServer.BackgroundPages/Cms/PageContentGroup.cs similarity index 79% rename from SiteServer.BackgroundPages/Cms/PageContentGroup.cs rename to net452/SiteServer.BackgroundPages/Cms/PageContentGroup.cs index db17dbe77..1f8616c18 100644 --- a/SiteServer.BackgroundPages/Cms/PageContentGroup.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageContentGroup.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Specialized; using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Cms { @@ -14,20 +16,20 @@ public class PageContentGroup : BasePageCms public static string GetRedirectUrl(int siteId) { - return PageUtils.GetCmsUrl(siteId, nameof(PageContentGroup), null); + return FxUtils.GetCmsUrl(siteId, nameof(PageContentGroup), null); } public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - if (AuthRequest.IsQueryExists("Delete")) + if (AuthRequest.IsQueryExists("DeleteById")) { var groupName = AuthRequest.GetQueryString("GroupName"); try { - DataProvider.ContentGroupDao.Delete(groupName, SiteId); + DataProvider.ContentGroup.Delete(SiteId, groupName); AuthRequest.AddSiteLog(SiteId, "删除内容组", $"内容组:{groupName}"); SuccessDeleteMessage(); } @@ -44,10 +46,10 @@ public void Page_Load(object sender, EventArgs e) switch (direction.ToUpper()) { case "UP": - DataProvider.ContentGroupDao.UpdateTaxisToUp(SiteId, groupName); + DataProvider.ContentGroup.UpdateTaxisToUp(SiteId, groupName); break; case "DOWN": - DataProvider.ContentGroupDao.UpdateTaxisToDown(SiteId, groupName); + DataProvider.ContentGroup.UpdateTaxisToDown(SiteId, groupName); break; } SuccessMessage("排序成功!"); @@ -58,7 +60,7 @@ public void Page_Load(object sender, EventArgs e) VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); - RptContents.DataSource = DataProvider.ContentGroupDao.GetContentGroupInfoList(SiteId); + RptContents.DataSource = ContentGroupManager.GetContentGroupInfoList(SiteId); RptContents.ItemDataBound += RptContents_ItemDataBound; RptContents.DataBind(); @@ -83,13 +85,13 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) ltlContentGroupName.Text = groupInfo.GroupName; ltlDescription.Text = groupInfo.Description; - hlUp.NavigateUrl = PageUtils.GetCmsUrl(SiteId, nameof(PageContentGroup), new NameValueCollection + hlUp.NavigateUrl = FxUtils.GetCmsUrl(SiteId, nameof(PageContentGroup), new NameValueCollection { {"GroupName", groupInfo.GroupName}, {"SetTaxis", true.ToString()}, {"Direction", "UP"} }); - hlDown.NavigateUrl = PageUtils.GetCmsUrl(SiteId, nameof(PageContentGroup), new NameValueCollection + hlDown.NavigateUrl = FxUtils.GetCmsUrl(SiteId, nameof(PageContentGroup), new NameValueCollection { {"GroupName", groupInfo.GroupName}, {"SetTaxis", true.ToString()}, @@ -101,10 +103,10 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) ltlEdit.Text = $@"修改"; - ltlDelete.Text = $@"删除"; } } diff --git a/net452/SiteServer.BackgroundPages/Cms/PageContentSearch.cs b/net452/SiteServer.BackgroundPages/Cms/PageContentSearch.cs new file mode 100644 index 000000000..b1a0e0d2a --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageContentSearch.cs @@ -0,0 +1,361 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Data; +using System.Web.UI.WebControls; +using Datory; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Controls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Database.Repositories.Contents; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin; +using SiteServer.Plugin; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageContentSearch : BasePageCms + { + public DropDownList DdlChannelId; + public DropDownList DdlState; + public DropDownList DdlSearchType; + public TextBox TbKeyword; + public DateTimeTextBox TbDateFrom; + public DateTimeTextBox TbDateTo; + + public Repeater RptContents; + public Pager PgContents; + public Literal LtlColumnsHead; + + public Button BtnAddToGroup; + public Button BtnDelete; + public Button BtnTranslate; + public Button BtnSelect; + public PlaceHolder PhCheck; + public Button BtnCheck; + public PlaceHolder PhTrash; + public Button BtnRestore; + public Button BtnRestoreAll; + public Button BtnDeleteAll; + + private bool _isCheckOnly; + private bool _isTrashOnly; + private bool _isWritingOnly; + private bool _isAdminOnly; + private int _channelId; + private ChannelInfo _channelInfo; + private List _styleInfoList; + private StringCollection _attributesOfDisplay; + private List _allStyleInfoList; + private List _pluginIds; + private Dictionary>> _pluginColumns; + private bool _isEdit; + private readonly Dictionary _nameValueCacheDict = new Dictionary(); + + public static string GetRedirectUrlCheck(int siteId) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageContentSearch), new NameValueCollection + { + {"isCheckOnly", true.ToString() } + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId"); + _channelId = AuthRequest.IsQueryExists("channelId") ? AuthRequest.GetQueryInt("channelId") : SiteId; + + _isCheckOnly = AuthRequest.GetQueryBool("isCheckOnly"); + _isTrashOnly = AuthRequest.GetQueryBool("isTrashOnly"); + _isWritingOnly = AuthRequest.GetQueryBool("isWritingOnly"); + _isAdminOnly = AuthRequest.GetQueryBool("isAdminOnly"); + + _channelInfo = ChannelManager.GetChannelInfo(SiteId, _channelId); + var tableName = ChannelManager.GetTableName(SiteInfo, _channelInfo); + _styleInfoList = TableStyleManager.GetContentStyleInfoList(SiteInfo, _channelInfo); + _attributesOfDisplay = TranslateUtils.StringCollectionToStringCollection(ChannelManager.GetContentAttributesOfDisplay(SiteId, _channelId)); + _allStyleInfoList = ContentUtility.GetAllTableStyleInfoList(_styleInfoList); + _pluginIds = PluginContentManager.GetContentPluginIds(_channelInfo); + _pluginColumns = PluginContentManager.GetContentColumns(_pluginIds); + _isEdit = TextUtility.IsEdit(SiteInfo, _channelId, AuthRequest.AdminPermissionsImpl); + + var state = AuthRequest.IsQueryExists("state") ? AuthRequest.GetQueryInt("state") : CheckManager.LevelInt.All; + var searchType = AuthRequest.IsQueryExists("searchType") ? AuthRequest.GetQueryString("searchType") : ContentAttribute.Title; + var dateFrom = AuthRequest.IsQueryExists("dateFrom") ? AuthRequest.GetQueryString("dateFrom") : string.Empty; + var dateTo = AuthRequest.IsQueryExists("dateTo") ? AuthRequest.GetQueryString("dateTo") : string.Empty; + var keyword = AuthRequest.IsQueryExists("keyword") ? AuthRequest.GetQueryString("keyword") : string.Empty; + + var checkedLevel = 5; + var isChecked = true; + foreach (var owningChannelId in AuthRequest.AdminPermissionsImpl.ChannelIdList) + { + int checkedLevelByChannelId; + var isCheckedByChannelId = CheckManager.GetUserCheckLevel(AuthRequest.AdminPermissionsImpl, SiteInfo, owningChannelId, out checkedLevelByChannelId); + if (checkedLevel > checkedLevelByChannelId) + { + checkedLevel = checkedLevelByChannelId; + } + if (!isCheckedByChannelId) + { + isChecked = false; + } + } + + RptContents.ItemDataBound += RptContents_ItemDataBound; + + var allAttributeNameList = TableColumnManager.GetTableColumnNameList(tableName, DataType.Text); + var onlyAdminId = _isAdminOnly + ? AuthRequest.AdminId + : AuthRequest.AdminPermissionsImpl.GetOnlyAdminId(SiteInfo.Id, _channelInfo.Id); + var whereString = DataProvider.ContentRepository.GetPagerWhereSqlString(SiteInfo, _channelInfo, + searchType, keyword, + dateFrom, dateTo, state, _isCheckOnly, false, _isTrashOnly, _isWritingOnly, onlyAdminId, + AuthRequest.AdminPermissionsImpl, + allAttributeNameList); + + PgContents.Param = new PagerParam + { + ControlToPaginate = RptContents, + TableName = tableName, + PageSize = SiteInfo.PageSize, + Page = AuthRequest.GetQueryInt(Pager.QueryNamePage, 1), + OrderSqlString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByIdDesc), + ReturnColumnNames = allAttributeNameList, + WhereSqlString = whereString, + TotalCount = DataProvider.DatabaseApi.GetPageTotalCount(tableName, whereString) + }; + + if (IsPostBack) return; + + if (_isTrashOnly) + { + if (AuthRequest.IsQueryExists("IsDeleteAll")) + { + foreach (var repository in ContentTableRepository.GetContentRepositoryList(SiteInfo)) + { + //repository.DeleteContentsByTrash(); + + var list = repository.GetContentIdListByTrash(SiteId); + foreach (var (contentChannelId, contentId) in list) + { + var channelInfo = ChannelManager.GetChannelInfo(SiteId, contentChannelId); + ContentManager.Delete(SiteInfo, channelInfo, contentId); + } + } + + AuthRequest.AddSiteLog(SiteId, "清空回收站"); + SuccessMessage("成功清空回收站!"); + } + else if (AuthRequest.IsQueryExists("IsRestore")) + { + var idsDictionary = ContentUtility.GetIDsDictionary(Request.QueryString); + foreach (var channelId in idsDictionary.Keys) + { + var channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + + var contentIdList = idsDictionary[channelId]; + channelInfo.ContentRepository.UpdateTrashContents(SiteId, channelId, contentIdList); + } + AuthRequest.AddSiteLog(SiteId, "从回收站还原内容"); + SuccessMessage("成功还原内容!"); + } + else if (AuthRequest.IsQueryExists("IsRestoreAll")) + { + _channelInfo.ContentRepository.UpdateRestoreContentsByTrash(SiteId, _channelId); + AuthRequest.AddSiteLog(SiteId, "从回收站还原所有内容"); + SuccessMessage("成功还原所有内容!"); + } + } + + SystemWebUtils.AddListItemsForChannel(DdlChannelId.Items, SiteInfo, true, true, AuthRequest.AdminPermissionsImpl); + + if (_isCheckOnly) + { + SystemWebUtils.LoadContentLevelToCheck(DdlState, SiteInfo, isChecked, checkedLevel); + } + else + { + SystemWebUtils.LoadContentLevelToCheckList(DdlState, SiteInfo, _isCheckOnly, isChecked, checkedLevel); + } + + SystemWebUtils.SelectSingleItem(DdlState, state.ToString()); + + foreach (var styleInfo in _allStyleInfoList) + { + if (styleInfo.Type == InputType.TextEditor) continue; + + var listitem = new ListItem(styleInfo.DisplayName, styleInfo.AttributeName); + DdlSearchType.Items.Add(listitem); + } + + //ETriStateUtils.AddListItems(DdlState, "全部", "已审核", "待审核"); + + if (SiteId != _channelId) + { + SystemWebUtils.SelectSingleItem(DdlChannelId, _channelId.ToString()); + } + //ControlUtils.SelectSingleItem(DdlState, AuthRequest.GetQueryString("State")); + SystemWebUtils.SelectSingleItem(DdlSearchType, searchType); + TbKeyword.Text = keyword; + TbDateFrom.Text = dateFrom; + TbDateTo.Text = dateTo; + + PgContents.DataBind(); + + LtlColumnsHead.Text += TextUtility.GetColumnsHeadHtml(_styleInfoList, _pluginColumns, _attributesOfDisplay); + + + BtnSelect.Attributes.Add("onclick", ModalSelectColumns.GetOpenWindowString(SiteId, _channelId)); + + if (_isTrashOnly) + { + LtlColumnsHead.Text += @"删除时间"; + BtnAddToGroup.Visible = BtnTranslate.Visible = BtnCheck.Visible = false; + PhTrash.Visible = true; + if (!HasChannelPermissions(_channelId, ConfigManager.ChannelPermissions.ContentDelete)) + { + BtnDelete.Visible = false; + BtnDeleteAll.Visible = false; + } + else + { + BtnDelete.Attributes.Add("onclick", PageContentDelete.GetRedirectClickStringForMultiChannels(SiteId, true, PageUrl)); + BtnDeleteAll.Attributes.Add("onclick", PageUtils.GetRedirectStringWithConfirm(PageUtils.AddQueryString(PageUrl, "IsDeleteAll", "True"), "确实要清空回收站吗?")); + } + BtnRestore.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValue(PageUtils.AddQueryString(PageUrl, "IsRestore", "True"), "IDsCollection", "IDsCollection", "请选择需要还原的内容!")); + BtnRestoreAll.Attributes.Add("onclick", PageUtils.GetRedirectStringWithConfirm(PageUtils.AddQueryString(PageUrl, "IsRestoreAll", "True"), "确实要还原所有内容吗?")); + } + else + { + LtlColumnsHead.Text += @"操作"; + + BtnAddToGroup.Attributes.Add("onclick", ModalAddToGroup.GetOpenWindowStringToContentForMultiChannels(SiteId)); + + if (HasChannelPermissions(SiteId, ConfigManager.ChannelPermissions.ContentCheck)) + { + BtnCheck.Attributes.Add("onclick", ModalContentCheck.GetOpenWindowStringForMultiChannels(SiteId, PageUrl)); + if (_isCheckOnly) + { + BtnCheck.CssClass = "btn m-r-5 btn-success"; + } + } + else + { + PhCheck.Visible = false; + } + + if (!HasChannelPermissions(_channelId, ConfigManager.ChannelPermissions.ContentTranslate)) + { + BtnTranslate.Visible = false; + } + else + { + BtnTranslate.Attributes.Add("onclick", PageContentTranslate.GetRedirectClickStringForMultiChannels(SiteId, PageUrl)); + } + + if (!HasChannelPermissions(_channelId, ConfigManager.ChannelPermissions.ContentDelete)) + { + BtnDelete.Visible = false; + } + else + { + BtnDelete.Attributes.Add("onclick", PageContentDelete.GetRedirectClickStringForMultiChannels(SiteId, false, PageUrl)); + } + } + } + + private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var record = (IDataRecord) e.Item.DataItem; + var contentInfo = new ContentInfo(TranslateUtils.ToDictionary(record)); + + var ltlTitle = (Literal)e.Item.FindControl("ltlTitle"); + var ltlChannel = (Literal)e.Item.FindControl("ltlChannel"); + var ltlColumns = (Literal)e.Item.FindControl("ltlColumns"); + var ltlStatus = (Literal)e.Item.FindControl("ltlStatus"); + var ltlSelect = (Literal)e.Item.FindControl("ltlSelect"); + + ltlTitle.Text = WebUtils.GetContentTitle(SiteInfo, contentInfo, PageUrl); + + var specialHtml = string.Empty; + + if (_isTrashOnly) + { + specialHtml = DateUtils.GetDateAndTimeString(contentInfo.LastEditDate); + } + else + { + var pluginMenus = PluginMenuManager.GetContentMenus(_pluginIds, contentInfo); + specialHtml = TextUtility.GetCommandsHtml(SiteInfo, pluginMenus, contentInfo, PageUrl, + AuthRequest.AdminName, _isEdit); + } + + ltlColumns.Text = $@" +{TextUtility.GetColumnsHtml(_nameValueCacheDict, SiteInfo, contentInfo, _attributesOfDisplay, _allStyleInfoList, _pluginColumns)} + +{specialHtml} +"; + + string nodeName; + if (!_nameValueCacheDict.TryGetValue(contentInfo.ChannelId.ToString(), out nodeName)) + { + nodeName = ChannelManager.GetChannelNameNavigation(SiteId, contentInfo.ChannelId); + _nameValueCacheDict[contentInfo.ChannelId.ToString()] = nodeName; + } + + ltlChannel.Text = nodeName; + var checkState = CheckManager.GetCheckState(SiteInfo, contentInfo); + + ltlStatus.Text = _isTrashOnly + ? checkState + : $@"{checkState}"; + + ltlSelect.Text = $@""; + } + + public void Search_OnClick(object sender, EventArgs e) + { + WebPageUtils.Redirect(PageUrl); + } + + private string _pageUrl; + private string PageUrl + { + get + { + if (string.IsNullOrEmpty(_pageUrl)) + { + _pageUrl = FxUtils.GetCmsUrl(SiteId, nameof(PageContentSearch), new NameValueCollection + { + {"channelId", DdlChannelId.SelectedValue}, + {"state", DdlState.SelectedValue}, + {"searchType", DdlSearchType.SelectedValue}, + {"keyword", TbKeyword.Text}, + {"dateFrom", TbDateFrom.Text}, + {"dateTo", TbDateTo.Text}, + {"isCheckOnly", _isCheckOnly.ToString()}, + {"isTrashOnly", _isTrashOnly.ToString()}, + {"isWritingOnly", _isWritingOnly.ToString()}, + {"isAdminOnly", _isAdminOnly.ToString()} + }); + } + return _pageUrl; + } + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/PageContentTags.cs b/net452/SiteServer.BackgroundPages/Cms/PageContentTags.cs new file mode 100644 index 000000000..2f3d0220f --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageContentTags.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Controls; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageContentTags : BasePageCms + { + public Repeater RptContents; + public SqlPager SpContents; + + public Button BtnAddTag; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + if (AuthRequest.IsQueryExists("DeleteById")) + { + var tagName = AuthRequest.GetQueryString("TagName"); + + try + { + var contentIdList = DataProvider.Tag.GetContentIdListByTag(tagName, SiteId); + if (contentIdList.Count > 0) + { + foreach (var contentId in contentIdList) + { + if (!SiteInfo.ContentRepository.GetChanelIdAndValue(contentId, ContentAttribute.Tags, + out var channelId, out string tags)) continue; + + var contentTagList = TranslateUtils.StringCollectionToStringList(tags); + contentTagList.Remove(tagName); + SiteInfo.ContentRepository.Update(channelId, contentId, ContentAttribute.Tags, TranslateUtils.ObjectCollectionToString(contentTagList)); + } + } + DataProvider.Tag.DeleteTag(tagName, SiteId); + AuthRequest.AddSiteLog(SiteId, "删除内容标签", $"内容标签:{tagName}"); + SuccessDeleteMessage(); + } + catch (Exception ex) + { + FailDeleteMessage(ex); + } + } + + SpContents.ControlToPaginate = RptContents; + SpContents.ItemsPerPage = SiteInfo.PageSize; + + SpContents.SelectCommand = DataProvider.Tag.GetSqlString(SiteId, 0, true, 0); + SpContents.SortField = nameof(TagInfo.UseNum); + SpContents.SortMode = SortMode.DESC; + + RptContents.ItemDataBound += RptContents_ItemDataBound; + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); + + SpContents.DataBind(); + + var showPopWinString = ModalContentTagAdd.GetOpenWindowStringToAdd(SiteId); + BtnAddTag.Attributes.Add("onclick", showPopWinString); + } + + private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var tag = SqlUtils.EvalString(e.Item.DataItem, nameof(TagInfo.Tag)); + var level = SqlUtils.EvalInt(e.Item.DataItem, nameof(TagInfo.Level)); + var useNum = SqlUtils.EvalInt(e.Item.DataItem, nameof(TagInfo.UseNum)); + + var ltlTagName = (Literal)e.Item.FindControl("ltlTagName"); + var ltlCount = (Literal)e.Item.FindControl("ltlCount"); + var ltlEditUrl = (Literal)e.Item.FindControl("ltlEditUrl"); + var ltlDeleteUrl = (Literal)e.Item.FindControl("ltlDeleteUrl"); + + var cssClass = "tag_popularity_1"; + if (level == 2) + { + cssClass = "tag_popularity_2"; + } + else if (level == 3) + { + cssClass = "tag_popularity_3"; + } + + ltlTagName.Text = $@"{tag}"; + ltlCount.Text = useNum.ToString(); + + var showPopWinString = ModalContentTagAdd.GetOpenWindowStringToEdit(SiteId, tag); + ltlEditUrl.Text = $"编辑"; + + var urlDelete = FxUtils.GetCmsUrl(SiteId, nameof(PageContentTags), new NameValueCollection + { + {"TagName", tag}, + {"DeleteById", true.ToString()} + }); + ltlDeleteUrl.Text = + $"删除"; + } + } +} diff --git a/SiteServer.BackgroundPages/Cms/PageContentTranslate.cs b/net452/SiteServer.BackgroundPages/Cms/PageContentTranslate.cs similarity index 77% rename from SiteServer.BackgroundPages/Cms/PageContentTranslate.cs rename to net452/SiteServer.BackgroundPages/Cms/PageContentTranslate.cs index f5be47394..cbd481bee 100644 --- a/SiteServer.BackgroundPages/Cms/PageContentTranslate.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageContentTranslate.cs @@ -5,8 +5,11 @@ using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches.Content; using SiteServer.CMS.Core; -using SiteServer.CMS.Model.Enumerations; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Cms { @@ -21,7 +24,7 @@ public class PageContentTranslate : BasePageCms public static string GetRedirectUrl(int siteId, int channelId, string returnUrl) { - return PageUtils.GetCmsUrl(siteId, nameof(PageContentTranslate), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageContentTranslate), new NameValueCollection { {"channelId", channelId.ToString()}, {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} @@ -30,7 +33,7 @@ public static string GetRedirectUrl(int siteId, int channelId, string returnUrl) public static string GetRedirectClickStringForMultiChannels(int siteId, string returnUrl) { - var redirectUrl = PageUtils.GetCmsUrl(siteId, nameof(PageContentTranslate), new NameValueCollection + var redirectUrl = FxUtils.GetCmsUrl(siteId, nameof(PageContentTranslate), new NameValueCollection { {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} }); @@ -39,7 +42,7 @@ public static string GetRedirectClickStringForMultiChannels(int siteId, string r public static string GetRedirectClickString(int siteId, int channelId, string returnUrl) { - var redirectUrl = PageUtils.GetCmsUrl(siteId, nameof(PageContentTranslate), new NameValueCollection + var redirectUrl = FxUtils.GetCmsUrl(siteId, nameof(PageContentTranslate), new NameValueCollection { {"channelId", channelId.ToString()}, {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} @@ -51,11 +54,15 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId", "ReturnUrl"); + WebPageUtils.CheckRequestParameter("siteId"); _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); + if (string.IsNullOrEmpty(_returnUrl)) + { + _returnUrl = AdminPagesUtils.Cms.GetContentsUrl(SiteId, AuthRequest.GetQueryInt("channelId")); + } //if (!base.HasChannelPermissions(this.channelId, AppManager.CMS.Permission.Channel.ContentTranslate)) //{ - // PageUtils.RedirectToErrorPage("您没有此栏目的内容转移权限!"); + // WebPageUtils.RedirectToErrorPage("您没有此栏目的内容转移权限!"); // return; //} @@ -68,13 +75,12 @@ public void Page_Load(object sender, EventArgs e) var builder = new StringBuilder(); foreach (var channelId in _idsDictionary.Keys) { - var tableName = ChannelManager.GetTableName(SiteInfo, channelId); - var contentIdArrayList = _idsDictionary[channelId]; - if (contentIdArrayList != null) + var contentIdList = _idsDictionary[channelId]; + if (contentIdList != null) { - foreach (int contentId in contentIdArrayList) + foreach (var contentId in contentIdList) { - var contentInfo = DataProvider.ContentDao.GetContentInfo(tableName, contentId); + var contentInfo = ContentManager.GetContentInfo(SiteInfo, channelId, contentId); if (contentInfo != null) { builder.Append( @@ -87,8 +93,8 @@ public void Page_Load(object sender, EventArgs e) BtnTranslateAdd.Attributes.Add("onclick", ModalChannelMultipleSelect.GetOpenWindowString(SiteId, true)); - ETranslateContentTypeUtils.AddListItems(RblTranslateType, isCut); - ControlUtils.SelectSingleItem(RblTranslateType, ETranslateContentTypeUtils.GetValue(ETranslateContentType.Copy)); + SystemWebUtils.AddListItemsToETranslateContentType(RblTranslateType, isCut); + SystemWebUtils.SelectSingleItem(RblTranslateType, ETranslateContentTypeUtils.GetValue(ETranslateContentType.Copy)); } public override void Submit_OnClick(object sender, EventArgs e) @@ -111,7 +117,7 @@ public override void Submit_OnClick(object sender, EventArgs e) { foreach (var contentId in contentIdList) { - ContentUtility.Translate(SiteInfo, channelId, contentId, Request.Form["translateCollection"], translateType, AuthRequest.AdminName); + ContentManager.Translate(SiteInfo, channelId, contentId, Request.Form["translateCollection"], translateType, AuthRequest.AdminName); AuthRequest.AddSiteLog(SiteInfo.Id, channelId, contentId, "转移内容", string.Empty); } @@ -136,7 +142,7 @@ public override void Submit_OnClick(object sender, EventArgs e) public void Return_OnClick(object sender, EventArgs e) { - PageUtils.Redirect(_returnUrl); + WebPageUtils.Redirect(_returnUrl); } } } diff --git a/SiteServer.BackgroundPages/Cms/PageContentsGroup.cs b/net452/SiteServer.BackgroundPages/Cms/PageContentsGroup.cs similarity index 76% rename from SiteServer.BackgroundPages/Cms/PageContentsGroup.cs rename to net452/SiteServer.BackgroundPages/Cms/PageContentsGroup.cs index b7428bcc4..85f3cb0be 100644 --- a/SiteServer.BackgroundPages/Cms/PageContentsGroup.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageContentsGroup.cs @@ -1,12 +1,18 @@ using System; using System.Collections.Specialized; +using System.Data; using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Controls; using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Plugin; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Cms { @@ -18,12 +24,12 @@ public class PageContentsGroup : BasePageCms public SqlPager SpContents; private string _tableName; - private ChannelInfo _nodeInfo; + private ChannelInfo _channelInfo; private string _contentGroupName; public static string GetRedirectUrl(int siteId, string contentGroupName) { - return PageUtils.GetCmsUrl(siteId, nameof(PageContentsGroup), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageContentsGroup), new NameValueCollection { {"contentGroupName", contentGroupName} }); @@ -35,14 +41,14 @@ public void Page_Load(object sender, EventArgs e) var siteId = AuthRequest.GetQueryInt("siteId"); _contentGroupName = AuthRequest.GetQueryString("contentGroupName"); - _nodeInfo = ChannelManager.GetChannelInfo(siteId, siteId); - _tableName = ChannelManager.GetTableName(SiteInfo, _nodeInfo); + _channelInfo = ChannelManager.GetChannelInfo(siteId, siteId); + _tableName = ChannelManager.GetTableName(SiteInfo, _channelInfo); if (AuthRequest.IsQueryExists("remove")) { var contentId = AuthRequest.GetQueryInt("contentId"); - var contentInfo = DataProvider.ContentDao.GetContentInfo(_tableName, contentId); + var contentInfo = ContentManager.GetContentInfo(SiteInfo, _channelInfo, contentId); var groupList = TranslateUtils.StringCollectionToStringList(contentInfo.GroupNameCollection); if (groupList.Contains(_contentGroupName)) { @@ -50,7 +56,7 @@ public void Page_Load(object sender, EventArgs e) } contentInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(groupList); - DataProvider.ContentDao.Update(_tableName, SiteInfo, contentInfo); + DataProvider.ContentRepository.Update(SiteInfo, _channelInfo, contentInfo); AuthRequest.AddSiteLog(SiteId, "移除内容", $"内容:{contentInfo.Title}"); SuccessMessage("移除成功"); AddWaitAndRedirectScript(PageUrl); @@ -58,8 +64,8 @@ public void Page_Load(object sender, EventArgs e) SpContents.ControlToPaginate = RptContents; RptContents.ItemDataBound += RptContents_ItemDataBound; - SpContents.ItemsPerPage = SiteInfo.Additional.PageSize; - SpContents.SelectCommand = DataProvider.ContentDao.GetSqlStringByContentGroup(_tableName, _contentGroupName, siteId); + SpContents.ItemsPerPage = SiteInfo.PageSize; + SpContents.SelectCommand = DataProvider.ContentRepository.GetSqlStringByContentGroup(_tableName, _contentGroupName, siteId); SpContents.SortField = ContentAttribute.AddDate; SpContents.SortMode = SortMode.DESC; @@ -81,21 +87,21 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) var ltlItemEditUrl = (Literal) e.Item.FindControl("ltlItemEditUrl"); var ltlItemDeleteUrl = (Literal) e.Item.FindControl("ltlItemDeleteUrl"); - var contentInfo = new ContentInfo(e.Item.DataItem); + var dataView = (DataRowView) e.Item.DataItem; + var contentInfo = new ContentInfo(TranslateUtils.ToDictionary(dataView)); ltlItemTitle.Text = WebUtils.GetContentTitle(SiteInfo, contentInfo, PageUrl); ltlItemChannel.Text = ChannelManager.GetChannelNameNavigation(SiteId, contentInfo.ChannelId); ltlItemAddDate.Text = DateUtils.GetDateAndTimeString(contentInfo.AddDate); - ltlItemStatus.Text = CheckManager.GetCheckState(SiteInfo, contentInfo.IsChecked, - contentInfo.CheckedLevel); + ltlItemStatus.Text = CheckManager.GetCheckState(SiteInfo, contentInfo); if (!HasChannelPermissions(contentInfo.ChannelId, ConfigManager.ChannelPermissions.ContentEdit) && AuthRequest.AdminName != contentInfo.AddUserName) return; ltlItemEditUrl.Text = - $@"编辑"; + $@"编辑"; - var removeUrl = PageUtils.GetCmsUrl(SiteId, nameof(PageContentsGroup), new NameValueCollection + var removeUrl = FxUtils.GetCmsUrl(SiteId, nameof(PageContentsGroup), new NameValueCollection { {"contentGroupName", _contentGroupName}, {"contentId", contentInfo.Id.ToString()}, @@ -113,7 +119,7 @@ private string PageUrl { if (string.IsNullOrEmpty(_pageUrl)) { - _pageUrl = PageUtils.GetCmsUrl(SiteId, nameof(PageContentsGroup), new NameValueCollection + _pageUrl = FxUtils.GetCmsUrl(SiteId, nameof(PageContentsGroup), new NameValueCollection { {"contentGroupName", _contentGroupName} }); @@ -124,7 +130,7 @@ private string PageUrl public void Return_OnClick(object sender, EventArgs e) { - PageUtils.Redirect(PageContentGroup.GetRedirectUrl(SiteId)); + WebPageUtils.Redirect(PageContentGroup.GetRedirectUrl(SiteId)); } } } diff --git a/net452/SiteServer.BackgroundPages/Cms/PageCreateFile.cs b/net452/SiteServer.BackgroundPages/Cms/PageCreateFile.cs new file mode 100644 index 000000000..cb4610dad --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageCreateFile.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.Utils; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageCreateFile : BasePageCms + { + public ListBox LbTemplateIdList; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId"); + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Create); + + var templateInfoList = DataProvider.Template.GetTemplateInfoListOfFile(SiteId); + + foreach (var templateInfo in templateInfoList) + { + var listitem = new ListItem(templateInfo.CreatedFileFullName, templateInfo.Id.ToString()); + LbTemplateIdList.Items.Add(listitem); + } + } + + public void Create_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + var templateIdList = new List(); + foreach (ListItem item in LbTemplateIdList.Items) + { + if (!item.Selected) continue; + + var templateId = int.Parse(item.Value); + templateIdList.Add(templateId); + } + + if (templateIdList.Count == 0) + { + FailMessage("请选择需要生成的文件页!"); + return; + } + + foreach (var templateId in templateIdList) + { + CreateManager.CreateFile(SiteId, templateId); + } + + WebPageUtils.Redirect(AdminPagesUtils.Cms.GetCreateStatusUrl(SiteId)); + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/PageCreateSpecial.cs b/net452/SiteServer.BackgroundPages/Cms/PageCreateSpecial.cs new file mode 100644 index 000000000..8e506f3ab --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageCreateSpecial.cs @@ -0,0 +1,64 @@ +using System; +using System.Collections.Generic; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.Utils; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageCreateSpecial : BasePageCms + { + public ListBox LbSpecialIdList; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId"); + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Create); + + var specialInfoList = DataProvider.Special.GetSpecialInfoList(SiteId); + + foreach (var specialInfo in specialInfoList) + { + var listitem = new ListItem($"{specialInfo.Title}({specialInfo.Url})", specialInfo.Id.ToString()); + LbSpecialIdList.Items.Add(listitem); + } + } + + public void Create_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + var specialIdList = new List(); + foreach (ListItem item in LbSpecialIdList.Items) + { + if (!item.Selected) continue; + + var specialId = TranslateUtils.ToInt(item.Value); + specialIdList.Add(specialId); + } + + if (specialIdList.Count == 0) + { + FailMessage("请选择需要生成的专题!"); + return; + } + + foreach (var specialId in specialIdList) + { + CreateManager.CreateSpecial(SiteId, specialId); + } + + WebPageUtils.Redirect(AdminPagesUtils.Cms.GetCreateStatusUrl(SiteId)); + } + } +} diff --git a/SiteServer.BackgroundPages/Cms/PageNodeGroup.cs b/net452/SiteServer.BackgroundPages/Cms/PageNodeGroup.cs similarity index 78% rename from SiteServer.BackgroundPages/Cms/PageNodeGroup.cs rename to net452/SiteServer.BackgroundPages/Cms/PageNodeGroup.cs index e0f97970f..284609aea 100644 --- a/SiteServer.BackgroundPages/Cms/PageNodeGroup.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageNodeGroup.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Specialized; using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Cms { @@ -14,20 +16,20 @@ public class PageNodeGroup : BasePageCms public static string GetRedirectUrl(int siteId) { - return PageUtils.GetCmsUrl(siteId, nameof(PageNodeGroup), null); + return FxUtils.GetCmsUrl(siteId, nameof(PageNodeGroup), null); } public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - if (AuthRequest.IsQueryExists("Delete")) + if (AuthRequest.IsQueryExists("DeleteById")) { var groupName = AuthRequest.GetQueryString("GroupName"); try { - DataProvider.ChannelGroupDao.Delete(SiteId, groupName); + DataProvider.ChannelGroup.Delete(SiteId, groupName); AuthRequest.AddSiteLog(SiteId, "删除栏目组", $"栏目组:{groupName}"); } @@ -44,10 +46,10 @@ public void Page_Load(object sender, EventArgs e) switch (direction.ToUpper()) { case "UP": - DataProvider.ChannelGroupDao.UpdateTaxisToUp(SiteId, groupName); + DataProvider.ChannelGroup.UpdateTaxisToUp(SiteId, groupName); break; case "DOWN": - DataProvider.ChannelGroupDao.UpdateTaxisToDown(SiteId, groupName); + DataProvider.ChannelGroup.UpdateTaxisToDown(SiteId, groupName); break; } AddWaitAndRedirectScript(GetRedirectUrl(SiteId)); @@ -57,7 +59,7 @@ public void Page_Load(object sender, EventArgs e) VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); - RptContents.DataSource = DataProvider.ChannelGroupDao.GetGroupInfoList(SiteId); + RptContents.DataSource = ChannelGroupManager.GetChannelGroupInfoList(SiteId); RptContents.ItemDataBound += RptContents_ItemDataBound; RptContents.DataBind(); @@ -81,13 +83,13 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) ltlNodeGroupName.Text = groupInfo.GroupName; ltlDescription.Text = groupInfo.Description; - hlUp.NavigateUrl = PageUtils.GetCmsUrl(SiteId, nameof(PageNodeGroup), new NameValueCollection + hlUp.NavigateUrl = FxUtils.GetCmsUrl(SiteId, nameof(PageNodeGroup), new NameValueCollection { {"GroupName", groupInfo.GroupName}, {"SetTaxis", true.ToString()}, {"Direction", "UP"} }); - hlDown.NavigateUrl = PageUtils.GetCmsUrl(SiteId, nameof(PageNodeGroup), new NameValueCollection + hlDown.NavigateUrl = FxUtils.GetCmsUrl(SiteId, nameof(PageNodeGroup), new NameValueCollection { {"GroupName", groupInfo.GroupName}, {"SetTaxis", true.ToString()}, @@ -101,10 +103,10 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) $@"修改"; - ltlDelete.Text = $@"删除"; } } diff --git a/net452/SiteServer.BackgroundPages/Cms/PageProgressBar.cs b/net452/SiteServer.BackgroundPages/Cms/PageProgressBar.cs new file mode 100644 index 000000000..431027977 Binary files /dev/null and b/net452/SiteServer.BackgroundPages/Cms/PageProgressBar.cs differ diff --git a/SiteServer.BackgroundPages/Cms/PageRelatedField.cs b/net452/SiteServer.BackgroundPages/Cms/PageRelatedField.cs similarity index 83% rename from SiteServer.BackgroundPages/Cms/PageRelatedField.cs rename to net452/SiteServer.BackgroundPages/Cms/PageRelatedField.cs index 7e4e67d35..2e3ac9e73 100644 --- a/SiteServer.BackgroundPages/Cms/PageRelatedField.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageRelatedField.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Specialized; using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Cms { @@ -15,19 +17,19 @@ public class PageRelatedField : BasePageCms public static string GetRedirectUrl(int siteId) { - return PageUtils.GetCmsUrl(siteId, nameof(PageRelatedField), null); + return FxUtils.GetCmsUrl(siteId, nameof(PageRelatedField), null); } public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - if (AuthRequest.IsQueryExists("Delete")) + if (AuthRequest.IsQueryExists("DeleteById")) { var relatedFieldId = AuthRequest.GetQueryInt("RelatedFieldID"); - var relatedFieldName = DataProvider.RelatedFieldDao.GetTitle(relatedFieldId); - DataProvider.RelatedFieldDao.Delete(relatedFieldId); + var relatedFieldName = DataProvider.RelatedField.GetTitle(relatedFieldId); + DataProvider.RelatedField.Delete(relatedFieldId); AuthRequest.AddSiteLog(SiteId, "删除联动字段", $"联动字段:{relatedFieldName}"); SuccessDeleteMessage(); } @@ -36,7 +38,7 @@ public void Page_Load(object sender, EventArgs e) VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); - RptContents.DataSource = DataProvider.RelatedFieldDao.GetRelatedFieldInfoList(SiteId); + RptContents.DataSource = DataProvider.RelatedField.GetRelatedFieldInfoList(SiteId); RptContents.ItemDataBound += RptContents_ItemDataBound; RptContents.DataBind(); @@ -69,10 +71,10 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) $@"导出"; ltlDeleteUrl.Text = $@"删除"; } } diff --git a/SiteServer.BackgroundPages/Cms/PageRelatedFieldItem.cs b/net452/SiteServer.BackgroundPages/Cms/PageRelatedFieldItem.cs similarity index 82% rename from SiteServer.BackgroundPages/Cms/PageRelatedFieldItem.cs rename to net452/SiteServer.BackgroundPages/Cms/PageRelatedFieldItem.cs index e05d4b829..d7c8c718d 100644 --- a/SiteServer.BackgroundPages/Cms/PageRelatedFieldItem.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageRelatedFieldItem.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Specialized; using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Cms { @@ -20,7 +22,7 @@ public class PageRelatedFieldItem : BasePageCms public static string GetRedirectUrl(int siteId, int relatedFieldId, int parentId, int level) { - return PageUtils.GetCmsUrl(siteId, nameof(PageRelatedFieldItem), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageRelatedFieldItem), new NameValueCollection { {"RelatedFieldID", relatedFieldId.ToString() }, {"ParentID", parentId.ToString() }, @@ -30,7 +32,7 @@ public static string GetRedirectUrl(int siteId, int relatedFieldId, int parentId public static string GetRedirectUrl(int siteId, int relatedFieldId, int level) { - return PageUtils.GetCmsUrl(siteId, nameof(PageRelatedFieldItem), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageRelatedFieldItem), new NameValueCollection { {"RelatedFieldID", relatedFieldId.ToString() }, {"Level", level.ToString() } @@ -44,12 +46,12 @@ public void Page_Load(object sender, EventArgs e) _relatedFieldId = AuthRequest.GetQueryInt("RelatedFieldID"); _parentId = AuthRequest.GetQueryInt("ParentID"); _level = AuthRequest.GetQueryInt("Level"); - _totalLevel = DataProvider.RelatedFieldDao.GetRelatedFieldInfo(_relatedFieldId).TotalLevel; + _totalLevel = DataProvider.RelatedField.Get(_relatedFieldId).TotalLevel; - if (AuthRequest.IsQueryExists("Delete") && AuthRequest.IsQueryExists("ID")) + if (AuthRequest.IsQueryExists("DeleteById") && AuthRequest.IsQueryExists("ID")) { var id = AuthRequest.GetQueryInt("ID"); - DataProvider.RelatedFieldItemDao.Delete(id); + DataProvider.RelatedFieldItem.Delete(id); if (_level != _totalLevel) { AddScript($@"parent.location.href = '{PageRelatedFieldMain.GetRedirectUrl(SiteId, _relatedFieldId, _totalLevel)}';"); @@ -61,11 +63,11 @@ public void Page_Load(object sender, EventArgs e) var isDown = AuthRequest.IsQueryExists("Down"); if (isDown) { - DataProvider.RelatedFieldItemDao.UpdateTaxisToUp(id, _parentId); + DataProvider.RelatedFieldItem.UpdateTaxisToUp(id, _parentId); } else { - DataProvider.RelatedFieldItemDao.UpdateTaxisToDown(id, _parentId); + DataProvider.RelatedFieldItem.UpdateTaxisToDown(id, _parentId); } } else if (_level != _totalLevel) @@ -82,7 +84,7 @@ public void Page_Load(object sender, EventArgs e) // RptContents.Columns[1].Visible = false; //} - RptContents.DataSource = DataProvider.RelatedFieldItemDao.GetRelatedFieldItemInfoList(_relatedFieldId, _parentId); + RptContents.DataSource = DataProvider.RelatedFieldItem.GetRelatedFieldItemInfoList(_relatedFieldId, _parentId); RptContents.ItemDataBound += RptContents_ItemDataBound; RptContents.DataBind(); @@ -132,7 +134,7 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) SiteId, _relatedFieldId, _parentId, _level, itemInfo.Id)}"">编辑"; ltlDeleteUrl.Text = - $@"删除"; + $@"删除"; } } } diff --git a/SiteServer.BackgroundPages/Cms/PageRelatedFieldMain.cs b/net452/SiteServer.BackgroundPages/Cms/PageRelatedFieldMain.cs similarity index 94% rename from SiteServer.BackgroundPages/Cms/PageRelatedFieldMain.cs rename to net452/SiteServer.BackgroundPages/Cms/PageRelatedFieldMain.cs index d6409ea37..335c7b5ca 100644 --- a/SiteServer.BackgroundPages/Cms/PageRelatedFieldMain.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageRelatedFieldMain.cs @@ -2,6 +2,7 @@ using System.Collections.Specialized; using System.Text; using System.Web.UI.WebControls; +using SiteServer.CMS.Fx; using SiteServer.Utils; namespace SiteServer.BackgroundPages.Cms @@ -12,7 +13,7 @@ public class PageRelatedFieldMain : BasePageCms public static string GetRedirectUrl(int siteId, int relatedFieldId, int totalLevel) { - return PageUtils.GetCmsUrl(siteId, nameof(PageRelatedFieldMain), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageRelatedFieldMain), new NameValueCollection { {"RelatedFieldID", relatedFieldId.ToString()}, {"TotalLevel", totalLevel.ToString()} diff --git a/SiteServer.BackgroundPages/Cms/PageServiceSTL.cs b/net452/SiteServer.BackgroundPages/Cms/PageServiceSTL.cs similarity index 81% rename from SiteServer.BackgroundPages/Cms/PageServiceSTL.cs rename to net452/SiteServer.BackgroundPages/Cms/PageServiceSTL.cs index 57c75ade5..ed07a960f 100644 --- a/SiteServer.BackgroundPages/Cms/PageServiceSTL.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageServiceSTL.cs @@ -5,7 +5,8 @@ using System.Web.UI; using SiteServer.Utils; using SiteServer.CMS.Core; -using SiteServer.CMS.Model.Enumerations; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Cms { @@ -15,7 +16,7 @@ public class PageServiceStl : Page public static string GetRedirectUrl(int siteId, string type) { - return PageUtils.GetCmsUrl(siteId, nameof(PageServiceStl), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageServiceStl), new NameValueCollection { {"type", type} }); @@ -43,7 +44,7 @@ public string GetLoadingTemplates(int siteId, string templateType) var theTemplateType = TemplateTypeUtils.GetEnumType(templateType); - var templateInfoList = DataProvider.TemplateDao.GetTemplateInfoListByType(siteId, theTemplateType); + var templateInfoList = DataProvider.Template.GetTemplateInfoListByType(siteId, theTemplateType); foreach (var templateInfo in templateInfoList) { @@ -51,7 +52,7 @@ public string GetLoadingTemplates(int siteId, string templateType) list.Add($@" -  {templateInfo.TemplateName} +  {templateInfo.TemplateName} "); diff --git a/net452/SiteServer.BackgroundPages/Cms/PageSpecial.cs b/net452/SiteServer.BackgroundPages/Cms/PageSpecial.cs new file mode 100644 index 000000000..0b4f2fa10 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageSpecial.cs @@ -0,0 +1,114 @@ +using System; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageSpecial : BasePageCms + { + protected TextBox TbKeyword; + protected Repeater RptContents; + protected Button BtnAdd; + + public static string GetRedirectUrl(int siteId) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageSpecial), null); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId"); + + var specialId = AuthRequest.GetQueryInt("specialId"); + var keyword = AuthRequest.GetQueryString("keyword"); + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Template); + + TbKeyword.Text = keyword; + + if (specialId > 0) + { + if (!string.IsNullOrEmpty(Request.QueryString["delete"])) + { + var specialInfo = SpecialManager.DeleteSpecialInfo(SiteId, specialId); + + AuthRequest.AddSiteLog(SiteId, + "删除专题", + $"专题名称:{specialInfo.Title}"); + + SuccessDeleteMessage(); + } + else if (!string.IsNullOrEmpty(Request.QueryString["download"])) + { + var specialInfo = SpecialManager.GetSpecialInfo(SiteId, specialId); + var directoryPath = SpecialManager.GetSpecialDirectoryPath(SiteInfo, specialInfo.Url); + var zipFilePath = SpecialManager.GetSpecialZipFilePath(directoryPath); + WebPageUtils.Download(Response, zipFilePath, $"{specialInfo.Title}.zip"); + return; + } + } + + RptContents.DataSource = string.IsNullOrEmpty(keyword) + ? DataProvider.Special.GetSpecialInfoList(SiteId) + : DataProvider.Special.GetSpecialInfoList(SiteId, keyword); + RptContents.ItemDataBound += RptContents_ItemDataBound; + RptContents.DataBind(); + + BtnAdd.Attributes.Add("onclick", ModalSpecialAdd.GetOpenWindowString(SiteId)); + } + + private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var specialInfo = (SpecialInfo)e.Item.DataItem; + + var ltlTitle = (Literal)e.Item.FindControl("ltlTitle"); + var ltlUrl = (Literal)e.Item.FindControl("ltlUrl"); + var ltlAddDate = (Literal)e.Item.FindControl("ltlAddDate"); + var ltlActions = (Literal)e.Item.FindControl("ltlActions"); + + ltlTitle.Text = $@"{specialInfo.Title}"; + ltlUrl.Text = specialInfo.Url; + if (specialInfo.AddDate != null) + { + ltlAddDate.Text = specialInfo.AddDate.Value.ToString("yyyy-MM-dd HH:mm"); + } + + ltlActions.Text = $@" +编辑 +上传压缩包 +下载压缩包 +删除 +"; + } + + public void Search_OnClick(object sender, EventArgs e) + { + Page.Response.Redirect(PageUrl); + } + + private string _pageUrl; + private string PageUrl + { + get + { + if (string.IsNullOrEmpty(_pageUrl)) + { + _pageUrl = $"{GetRedirectUrl(SiteId)}&keyword={TbKeyword.Text}"; + } + return _pageUrl; + } + } + } +} diff --git a/SiteServer.BackgroundPages/Cms/PageTableStyleChannel.cs b/net452/SiteServer.BackgroundPages/Cms/PageTableStyleChannel.cs similarity index 83% rename from SiteServer.BackgroundPages/Cms/PageTableStyleChannel.cs rename to net452/SiteServer.BackgroundPages/Cms/PageTableStyleChannel.cs index 010751343..39cba2491 100644 --- a/SiteServer.BackgroundPages/Cms/PageTableStyleChannel.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageTableStyleChannel.cs @@ -2,9 +2,13 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Cms { @@ -24,7 +28,7 @@ public class PageTableStyleChannel : BasePageCms public static string GetRedirectUrl(int siteId, int channelId) { - return PageUtils.GetCmsUrl(siteId, nameof(PageTableStyleChannel), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageTableStyleChannel), new NameValueCollection { {"SiteId", siteId.ToString()}, {"channelId", channelId.ToString()} @@ -35,11 +39,11 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - _tableName = DataProvider.ChannelDao.TableName; + _tableName = DataProvider.Channel.TableName; var channelId = AuthRequest.GetQueryInt("channelId", SiteId); _channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); _redirectUrl = GetRedirectUrl(SiteId, channelId); - _relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(SiteId, channelId); + _relatedIdentities = TableStyleManager.GetRelatedIdentities(_channelInfo); if (IsPostBack) return; @@ -53,7 +57,7 @@ public void Page_Load(object sender, EventArgs e) { try { - TableStyleManager.Delete(_channelInfo.Id, _tableName, attributeName); + DataProvider.TableStyle.Delete(_channelInfo.Id, _tableName, attributeName); AuthRequest.AddSiteLog(SiteId, "删除数据表单样式", $"表单:{_tableName},字段:{attributeName}"); SuccessDeleteMessage(); } @@ -64,10 +68,10 @@ public void Page_Load(object sender, EventArgs e) } } - ChannelManager.AddListItems(DdlChannelId.Items, SiteInfo, false, true, AuthRequest.AdminPermissions); - ControlUtils.SelectSingleItem(DdlChannelId, channelId.ToString()); + SystemWebUtils.AddListItemsForChannel(DdlChannelId.Items, SiteInfo, false, true, AuthRequest.AdminPermissionsImpl); + SystemWebUtils.SelectSingleItem(DdlChannelId, channelId.ToString()); - RptContents.DataSource = TableStyleManager.GetTableStyleInfoList(_tableName, _relatedIdentities); + RptContents.DataSource = TableStyleManager.GetChannelStyleInfoList(_channelInfo); RptContents.ItemDataBound += RptContents_ItemDataBound; RptContents.DataBind(); @@ -79,7 +83,7 @@ public void Page_Load(object sender, EventArgs e) public void Redirect(object sender, EventArgs e) { - PageUtils.Redirect(GetRedirectUrl(SiteId, TranslateUtils.ToInt(DdlChannelId.SelectedValue))); + WebPageUtils.Redirect(GetRedirectUrl(SiteId, TranslateUtils.ToInt(DdlChannelId.SelectedValue))); } private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) @@ -99,7 +103,7 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) ltlAttributeName.Text = styleInfo.AttributeName; ltlDisplayName.Text = styleInfo.DisplayName; - ltlInputType.Text = InputTypeUtils.GetText(styleInfo.InputType); + ltlInputType.Text = InputTypeUtils.GetText(styleInfo.Type); ltlValidate.Text = TableStyleManager.GetValidateInfo(styleInfo); @@ -114,7 +118,7 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) if (styleInfo.RelatedIdentity != _channelInfo.Id) return; - var urlStyle = PageUtils.GetCmsUrl(SiteId, nameof(PageTableStyleChannel), new NameValueCollection + var urlStyle = FxUtils.GetCmsUrl(SiteId, nameof(PageTableStyleChannel), new NameValueCollection { {"channelId", _channelInfo.Id.ToString()}, {"DeleteStyle", true.ToString()}, diff --git a/net452/SiteServer.BackgroundPages/Cms/PageTableStyleContent.cs b/net452/SiteServer.BackgroundPages/Cms/PageTableStyleContent.cs new file mode 100644 index 000000000..3be32b56a --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageTableStyleContent.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageTableStyleContent : BasePageCms + { + public DropDownList DdlChannelId; + public Repeater RptContents; + + public Button BtnAddStyle; + public Button BtnAddStyles; + public Button BtnImport; + public Button BtnExport; + + private ChannelInfo _channelInfo; + private string _tableName; + private List _relatedIdentities; + private string _redirectUrl; + + public static string GetRedirectUrl(int siteId, int channelId) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageTableStyleContent), new NameValueCollection + { + {"channelId", channelId.ToString()} + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + var channelId = AuthRequest.GetQueryInt("channelId", SiteId); + _channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + _tableName = ChannelManager.GetTableName(SiteInfo, _channelInfo); + _redirectUrl = GetRedirectUrl(SiteId, channelId); + _relatedIdentities = TableStyleManager.GetRelatedIdentities(_channelInfo); + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); + + //删除样式 + if (AuthRequest.IsQueryExists("DeleteStyle")) + { + var attributeName = AuthRequest.GetQueryString("AttributeName"); + if (TableStyleManager.IsExists(_channelInfo.Id, _tableName, attributeName)) + { + try + { + DataProvider.TableStyle.Delete(_channelInfo.Id, _tableName, attributeName); + AuthRequest.AddSiteLog(SiteId, "删除数据表单样式", $"表单:{_tableName},字段:{attributeName}"); + SuccessDeleteMessage(); + } + catch (Exception ex) + { + FailDeleteMessage(ex); + } + } + } + + InfoMessage( + $"在此编辑内容模型字段,子栏目默认继承父栏目字段设置; 内容表:{_tableName}"); + SystemWebUtils.AddListItemsForChannel(DdlChannelId.Items, SiteInfo, false, true, AuthRequest.AdminPermissionsImpl); + SystemWebUtils.SelectSingleItem(DdlChannelId, channelId.ToString()); + + RptContents.DataSource = TableStyleManager.GetContentStyleInfoList(SiteInfo, _channelInfo); + RptContents.ItemDataBound += RptContents_ItemDataBound; + RptContents.DataBind(); + + BtnAddStyle.Attributes.Add("onclick", ModalTableStyleAdd.GetOpenWindowString(SiteId, 0, _relatedIdentities, _tableName, string.Empty, _redirectUrl)); + BtnAddStyles.Attributes.Add("onclick", ModalTableStylesAdd.GetOpenWindowString(SiteId, _relatedIdentities, _tableName, _redirectUrl)); + BtnImport.Attributes.Add("onclick", ModalTableStyleImport.GetOpenWindowString(_tableName, SiteId, channelId)); + BtnExport.Attributes.Add("onclick", ModalExportMessage.GetOpenWindowStringToSingleTableStyle(_tableName, SiteId, channelId)); + } + + public void Redirect(object sender, EventArgs e) + { + WebPageUtils.Redirect(GetRedirectUrl(SiteId, TranslateUtils.ToInt(DdlChannelId.SelectedValue))); + } + + private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var styleInfo = (TableStyleInfo)e.Item.DataItem; + + var ltlAttributeName = (Literal)e.Item.FindControl("ltlAttributeName"); + var ltlDisplayName = (Literal)e.Item.FindControl("ltlDisplayName"); + var ltlInputType = (Literal)e.Item.FindControl("ltlInputType"); + var ltlFieldType = (Literal)e.Item.FindControl("ltlFieldType"); + var ltlValidate = (Literal)e.Item.FindControl("ltlValidate"); + var ltlTaxis = (Literal)e.Item.FindControl("ltlTaxis"); + var ltlEditStyle = (Literal)e.Item.FindControl("ltlEditStyle"); + var ltlEditValidate = (Literal)e.Item.FindControl("ltlEditValidate"); + + ltlAttributeName.Text = styleInfo.AttributeName; + + ltlDisplayName.Text = styleInfo.DisplayName; + ltlInputType.Text = InputTypeUtils.GetText(styleInfo.Type); + + var columnInfo = TableColumnManager.GetTableColumnInfo(_tableName, styleInfo.AttributeName); + + ltlFieldType.Text = columnInfo != null ? $"真实 {DataTypeUtils.GetText(columnInfo.DataType)}" : "虚拟字段"; + + ltlValidate.Text = TableStyleManager.GetValidateInfo(styleInfo); + + if (!StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.Title)) + { + var showPopWinString = ModalTableStyleAdd.GetOpenWindowString(SiteId, styleInfo.Id, _relatedIdentities, _tableName, styleInfo.AttributeName, _redirectUrl); + + ltlEditStyle.Text = $@"设置"; + + showPopWinString = ModalTableStyleValidateAdd.GetOpenWindowString(SiteId, styleInfo.Id, _relatedIdentities, _tableName, styleInfo.AttributeName, _redirectUrl); + ltlEditValidate.Text = $@"设置"; + } + + ltlTaxis.Text = styleInfo.Taxis.ToString(); + + if (styleInfo.RelatedIdentity != _channelInfo.Id) return; + + var urlStyle = FxUtils.GetCmsUrl(SiteId, nameof(PageTableStyleContent), new NameValueCollection + { + {"channelId", _channelInfo.Id.ToString()}, + {"DeleteStyle", true.ToString()}, + {"TableName", _tableName}, + {"AttributeName", styleInfo.AttributeName} + }); + ltlEditStyle.Text += + $@"  删除"; + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/PageTableStyleSite.cs b/net452/SiteServer.BackgroundPages/Cms/PageTableStyleSite.cs new file mode 100644 index 000000000..9c7e4f3c8 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageTableStyleSite.cs @@ -0,0 +1,141 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageTableStyleSite : BasePageCms + { + public Repeater RptContents; + + public Button BtnAddStyle; + public Button BtnAddStyles; + public Button BtnImport; + public Button BtnExport; + public Button BtnReturn; + + private List _relatedIdentities; + private string _tableName; + private int _itemId; + private List _attributeNames; + private string _returnUrl; + + public static string GetRedirectUrl(int siteId, int itemId, string returnUrl) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageTableStyleSite), new NameValueCollection + { + {"ItemID", itemId.ToString()}, + {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + _tableName = DataProvider.Site.TableName; + _itemId = AuthRequest.GetQueryInt("itemID"); + _relatedIdentities = TableStyleManager.GetRelatedIdentities(SiteId); + _attributeNames = TableColumnManager.GetTableColumnNameList(_tableName); + _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("ReturnUrl")); + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Configration); + + //删除样式 + if (AuthRequest.IsQueryExists("DeleteStyle")) + { + var attributeName = AuthRequest.GetQueryString("AttributeName"); + if (TableStyleManager.IsExists(SiteId, _tableName, attributeName)) + { + try + { + DataProvider.TableStyle.Delete(SiteId, _tableName, attributeName); + AuthRequest.AddSiteLog(SiteId, "删除数据表单样式", $"表单:{_tableName},字段:{attributeName}"); + SuccessDeleteMessage(); + } + catch (Exception ex) + { + FailDeleteMessage(ex); + } + } + } + + if (!string.IsNullOrEmpty(_returnUrl)) + { + BtnReturn.Attributes.Add("onclick", $"location.href='{_returnUrl}';return false;"); + } + else + { + BtnReturn.Visible = false; + } + + RptContents.DataSource = TableStyleManager.GetSiteStyleInfoList(SiteId); + RptContents.ItemDataBound += RptContents_ItemDataBound; + RptContents.DataBind(); + + var redirectUrl = GetRedirectUrl(SiteId, _itemId, _returnUrl); + + BtnAddStyle.Attributes.Add("onclick", ModalTableStyleAdd.GetOpenWindowString(SiteId, 0, _relatedIdentities, _tableName, string.Empty, redirectUrl)); + BtnAddStyles.Attributes.Add("onclick", ModalTableStylesAdd.GetOpenWindowString(SiteId, _relatedIdentities, _tableName, redirectUrl)); + + BtnImport.Attributes.Add("onclick", ModalTableStyleImport.GetOpenWindowString(_tableName, SiteId, SiteId)); + BtnExport.Attributes.Add("onclick", ModalExportMessage.GetOpenWindowStringToSingleTableStyle(_tableName, SiteId, SiteId)); + } + + private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var styleInfo = (TableStyleInfo)e.Item.DataItem; + + if (_attributeNames.Contains(styleInfo.AttributeName)) + { + e.Item.Visible = false; + return; + } + + var ltlAttributeName = (Literal)e.Item.FindControl("ltlAttributeName"); + var ltlDisplayName = (Literal)e.Item.FindControl("ltlDisplayName"); + var ltlInputType = (Literal)e.Item.FindControl("ltlInputType"); + var ltlValidate = (Literal)e.Item.FindControl("ltlValidate"); + var ltlTaxis = (Literal)e.Item.FindControl("ltlTaxis"); + var ltlEditStyle = (Literal)e.Item.FindControl("ltlEditStyle"); + var ltlEditValidate = (Literal)e.Item.FindControl("ltlEditValidate"); + + ltlAttributeName.Text = styleInfo.AttributeName; + + ltlDisplayName.Text = styleInfo.DisplayName; + ltlInputType.Text = InputTypeUtils.GetText(styleInfo.Type); + + ltlValidate.Text = TableStyleManager.GetValidateInfo(styleInfo); + + var redirectUrl = GetRedirectUrl(SiteId, _itemId, _returnUrl); + var showPopWinString = ModalTableStyleAdd.GetOpenWindowString(SiteId, styleInfo.Id, _relatedIdentities, _tableName, styleInfo.AttributeName, redirectUrl); + ltlEditStyle.Text = $@"修改"; + + showPopWinString = ModalTableStyleValidateAdd.GetOpenWindowString(SiteId, styleInfo.Id, _relatedIdentities, _tableName, styleInfo.AttributeName, redirectUrl); + ltlEditValidate.Text = $@"设置"; + + ltlTaxis.Text = styleInfo.Taxis == 0 ? string.Empty : styleInfo.Taxis.ToString(); + + var urlStyle = FxUtils.GetCmsUrl(SiteId, nameof(PageTableStyleSite), new NameValueCollection + { + {"TableName", _tableName}, + {"RelatedIdentity", SiteId.ToString()}, + {"DeleteStyle", true.ToString()}, + {"AttributeName", styleInfo.AttributeName} + }); + ltlEditStyle.Text += + $@"  删除"; + } + } +} diff --git a/SiteServer.BackgroundPages/Cms/PageTemplate.cs b/net452/SiteServer.BackgroundPages/Cms/PageTemplate.cs similarity index 81% rename from SiteServer.BackgroundPages/Cms/PageTemplate.cs rename to net452/SiteServer.BackgroundPages/Cms/PageTemplate.cs index 7408f15ba..b11d4d7ac 100644 --- a/SiteServer.BackgroundPages/Cms/PageTemplate.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageTemplate.cs @@ -1,9 +1,14 @@ using System; using System.Collections.Specialized; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.Plugin; namespace SiteServer.BackgroundPages.Cms @@ -20,12 +25,12 @@ public class PageTemplate : BasePageCms public static string GetRedirectUrl(int siteId) { - return PageUtils.GetCmsUrl(siteId, nameof(PageTemplate), null); + return FxUtils.GetCmsUrl(siteId, nameof(PageTemplate), null); } public static string GetRedirectUrl(int siteId, TemplateType templateType) { - return PageUtils.GetCmsUrl(siteId, nameof(PageTemplate), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageTemplate), new NameValueCollection { {"templateType", templateType.Value} }); @@ -35,7 +40,7 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId"); + WebPageUtils.CheckRequestParameter("siteId"); _templateType = AuthRequest.GetQueryString("templateType"); _keywords = AuthRequest.GetQueryString("keywords"); @@ -45,12 +50,12 @@ public void Page_Load(object sender, EventArgs e) VerifySitePermissions(ConfigManager.WebSitePermissions.Template); DdlTemplateType.Items.Add(new ListItem("<所有类型>", string.Empty)); - TemplateTypeUtils.AddListItems(DdlTemplateType); - ControlUtils.SelectSingleItem(DdlTemplateType, _templateType); + SystemWebUtils.AddListItemsToTemplateType(DdlTemplateType); + SystemWebUtils.SelectSingleItem(DdlTemplateType, _templateType); TbKeywords.Text = _keywords; - if (AuthRequest.IsQueryExists("Delete")) + if (AuthRequest.IsQueryExists("DeleteById")) { var templateId = AuthRequest.GetQueryInt("TemplateID"); @@ -59,9 +64,9 @@ public void Page_Load(object sender, EventArgs e) var templateInfo = TemplateManager.GetTemplateInfo(SiteId, templateId); if (templateInfo != null) { - DataProvider.TemplateDao.Delete(SiteId, templateId); + DataProvider.Template.Delete(SiteId, templateId); AuthRequest.AddSiteLog(SiteId, - $"删除{TemplateTypeUtils.GetText(templateInfo.TemplateType)}", + $"删除{TemplateTypeUtils.GetText(templateInfo.Type)}", $"模板名称:{templateInfo.TemplateName}"); } SuccessDeleteMessage(); @@ -80,9 +85,9 @@ public void Page_Load(object sender, EventArgs e) var templateInfo = TemplateManager.GetTemplateInfo(SiteId, templateId); if (templateInfo != null) { - DataProvider.TemplateDao.SetDefault(SiteId, templateId); + DataProvider.Template.SetDefault(SiteId, templateId); AuthRequest.AddSiteLog(SiteId, - $"设置默认{TemplateTypeUtils.GetText(templateInfo.TemplateType)}", + $"设置默认{TemplateTypeUtils.GetText(templateInfo.Type)}", $"模板名称:{templateInfo.TemplateName}"); } SuccessMessage(); @@ -110,14 +115,14 @@ public void Page_Load(object sender, EventArgs e) "; } - RptContents.DataSource = DataProvider.TemplateDao.GetDataSource(SiteId, _keywords, _templateType); + RptContents.DataSource = DataProvider.Template.GetDataSource(SiteId, _keywords, _templateType); RptContents.ItemDataBound += RptContents_ItemDataBound; RptContents.DataBind(); } public void DdlTemplateType_OnSelectedIndexChanged(object sender, EventArgs e) { - PageUtils.Redirect(PageUtils.GetCmsUrl(SiteId, nameof(PageTemplate), new NameValueCollection + WebPageUtils.Redirect(FxUtils.GetCmsUrl(SiteId, nameof(PageTemplate), new NameValueCollection { {"templateType", DdlTemplateType.SelectedValue}, {"keywords", TbKeywords.Text} @@ -126,7 +131,7 @@ public void DdlTemplateType_OnSelectedIndexChanged(object sender, EventArgs e) public void BtnSearch_Click(object sender, EventArgs e) { - PageUtils.Redirect(PageUtils.GetCmsUrl(SiteId, nameof(PageTemplate), new NameValueCollection + WebPageUtils.Redirect(FxUtils.GetCmsUrl(SiteId, nameof(PageTemplate), new NameValueCollection { {"templateType", DdlTemplateType.SelectedValue}, {"keywords", TbKeywords.Text} @@ -138,11 +143,11 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; var templateId = SqlUtils.EvalInt(e.Item.DataItem, nameof(TemplateInfo.Id)); - var templateType = TemplateTypeUtils.GetEnumType(SqlUtils.EvalString(e.Item.DataItem, nameof(TemplateInfo.TemplateType))); + var templateType = TemplateTypeUtils.GetEnumType(SqlUtils.EvalString(e.Item.DataItem, nameof(TemplateInfo.Type))); var templateName = SqlUtils.EvalString(e.Item.DataItem, nameof(TemplateInfo.TemplateName)); var relatedFileName = SqlUtils.EvalString(e.Item.DataItem, nameof(TemplateInfo.RelatedFileName)); var createdFileFullName = SqlUtils.EvalString(e.Item.DataItem, nameof(TemplateInfo.CreatedFileFullName)); - var isDefault = TranslateUtils.ToBool(SqlUtils.EvalString(e.Item.DataItem, nameof(TemplateInfo.IsDefault))); + var isDefault = TranslateUtils.ToBool(SqlUtils.EvalString(e.Item.DataItem, nameof(TemplateInfo.Default))); var ltlTemplateName = (Literal)e.Item.FindControl("ltlTemplateName"); var ltlRelatedFileName = (Literal)e.Item.FindControl("ltlRelatedFileName"); @@ -165,7 +170,7 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) ltlFileName.Text = $"{createdFileFullName}"; } - ltlUseCount.Text = DataProvider.ChannelDao.GetTemplateUseCount(SiteId, templateId, templateType, isDefault).ToString(); + ltlUseCount.Text = DataProvider.Channel.GetTemplateUseCount(SiteId, templateId, templateType, isDefault).ToString(); ltlTemplateType.Text = TemplateTypeUtils.GetText(templateType); @@ -177,10 +182,11 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) } else { - var defaultUrl = PageUtils.GetCmsUrl(SiteId, nameof(PageTemplate), new NameValueCollection + var defaultUrl = FxUtils.GetCmsUrl(SiteId, nameof(PageTemplate), new NameValueCollection { {"TemplateID", templateId.ToString()}, - {"SetDefault", true.ToString()} + {"SetDefault", true.ToString()}, + { "TemplateType", templateType.Value } }); ltlDefaultUrl.Text = $@"设为默认"; @@ -199,10 +205,11 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) if (!isDefault) { - var deleteUrl = PageUtils.GetCmsUrl(SiteId, nameof(PageTemplate), new NameValueCollection + var deleteUrl = FxUtils.GetCmsUrl(SiteId, nameof(PageTemplate), new NameValueCollection { {"TemplateID", templateId.ToString()}, - {"Delete", true.ToString()} + {"DeleteById", true.ToString()}, + { "TemplateType", templateType.Value } }); ltlDeleteUrl.Text = diff --git a/SiteServer.BackgroundPages/Cms/PageTemplateAdd.cs b/net452/SiteServer.BackgroundPages/Cms/PageTemplateAdd.cs similarity index 75% rename from SiteServer.BackgroundPages/Cms/PageTemplateAdd.cs rename to net452/SiteServer.BackgroundPages/Cms/PageTemplateAdd.cs index 3bf0238e0..4960edebd 100644 --- a/SiteServer.BackgroundPages/Cms/PageTemplateAdd.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageTemplateAdd.cs @@ -2,10 +2,14 @@ using System.Collections.Specialized; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; using SiteServer.CMS.Core.Create; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.Plugin; using SiteServer.Utils.Enumerations; @@ -21,7 +25,6 @@ public class PageTemplateAdd : BasePageCms public TextBox TbRelatedFileName; public PlaceHolder PhCreatedFileFullName; public TextBox TbCreatedFileFullName; - public DropDownList DdlCharset; public Literal LtlCommands; public TextBox TbContent; public PlaceHolder PhCodeMirror; @@ -32,7 +35,7 @@ public class PageTemplateAdd : BasePageCms public static string GetRedirectUrl(int siteId, int templateId, TemplateType templateType) { - return PageUtils.GetCmsUrl(siteId, nameof(PageTemplateAdd), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageTemplateAdd), new NameValueCollection { {"TemplateID", templateId.ToString()}, {"TemplateType", templateType.Value} @@ -41,7 +44,7 @@ public static string GetRedirectUrl(int siteId, int templateId, TemplateType tem public static string GetRedirectUrlToCopy(int siteId, int templateId) { - return PageUtils.GetCmsUrl(siteId, nameof(PageTemplateAdd), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageTemplateAdd), new NameValueCollection { {"TemplateID", templateId.ToString()}, {"IsCopy", true.ToString()} @@ -50,7 +53,7 @@ public static string GetRedirectUrlToCopy(int siteId, int templateId) public static string GetRedirectUrlToRestore(int siteId, int templateId, int templateLogId) { - return PageUtils.GetCmsUrl(siteId, nameof(PageTemplateAdd), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageTemplateAdd), new NameValueCollection { {"TemplateID", templateId.ToString()}, {"TemplateLogID", templateLogId.ToString()} @@ -61,7 +64,7 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId"); + WebPageUtils.CheckRequestParameter("siteId"); TemplateInfo templateInfo = null; if (AuthRequest.GetQueryInt("TemplateID") > 0) @@ -71,7 +74,7 @@ public void Page_Load(object sender, EventArgs e) templateInfo = TemplateManager.GetTemplateInfo(SiteId, templateId); if (templateInfo != null) { - _templateType = templateInfo.TemplateType; + _templateType = templateInfo.Type; } } else @@ -96,13 +99,11 @@ public void Page_Load(object sender, EventArgs e) LtlPageTitle.Text = AuthRequest.GetQueryInt("TemplateID") > 0 ? "编辑模板" : "添加模板"; - var isCodeMirror = SiteInfo.Additional.ConfigTemplateIsCodeMirror; + var isCodeMirror = SiteInfo.ConfigTemplateIsCodeMirror; BtnEditorType.Text = isCodeMirror ? "采用纯文本编辑模式" : "采用代码编辑模式"; PhCodeMirror.Visible = isCodeMirror; - EFileSystemTypeUtils.AddWebPageListItems(DdlCreatedFileExtName); - - ECharsetUtils.AddListItems(DdlCharset); + FxUtils.AddListItemsToEFileSystemType(DdlCreatedFileExtName); if (AuthRequest.GetQueryInt("TemplateID") > 0) { @@ -131,23 +132,20 @@ public void Page_Load(object sender, EventArgs e) var templateLogId = AuthRequest.GetQueryInt("TemplateLogID"); if (templateLogId > 0) { - TbContent.Text = DataProvider.TemplateLogDao.GetTemplateContent(templateLogId); + TbContent.Text = DataProvider.TemplateLog.GetTemplateContent(templateLogId); SuccessMessage("已导入历史版本的模板内容,点击确定保存模板"); } } } - ControlUtils.SelectSingleItemIgnoreCase(DdlCharset, ECharsetUtils.GetValue(templateInfo.Charset)); - - ControlUtils.SelectSingleItem(DdlCreatedFileExtName, GetTemplateFileExtension(templateInfo)); - HihTemplateType.Value = templateInfo.TemplateType.Value; + SystemWebUtils.SelectSingleItem(DdlCreatedFileExtName, GetTemplateFileExtension(templateInfo)); + HihTemplateType.Value = templateInfo.Type.Value; } else { TbRelatedFileName.Text = "T_"; TbCreatedFileFullName.Text = _templateType == TemplateType.ChannelTemplate ? "index" : "@/"; - ControlUtils.SelectSingleItemIgnoreCase(DdlCharset, SiteInfo.Additional.Charset); - ControlUtils.SelectSingleItem(DdlCreatedFileExtName, EFileSystemTypeUtils.GetValue(EFileSystemType.Html)); + SystemWebUtils.SelectSingleItem(DdlCreatedFileExtName, EFileSystemTypeUtils.GetValue(EFileSystemType.Html)); HihTemplateType.Value = AuthRequest.GetQueryString("TemplateType"); } } @@ -156,10 +154,10 @@ public void EditorType_OnClick(object sender, EventArgs e) { if (!Page.IsPostBack || !Page.IsValid) return; - var isCodeMirror = SiteInfo.Additional.ConfigTemplateIsCodeMirror; + var isCodeMirror = SiteInfo.ConfigTemplateIsCodeMirror; isCodeMirror = !isCodeMirror; - SiteInfo.Additional.ConfigTemplateIsCodeMirror = isCodeMirror; - DataProvider.SiteDao.Update(SiteInfo); + SiteInfo.ConfigTemplateIsCodeMirror = isCodeMirror; + DataProvider.Site.Update(SiteInfo); BtnEditorType.Text = isCodeMirror ? "采用纯文本编辑模式" : "采用代码编辑模式"; PhCodeMirror.Visible = isCodeMirror; @@ -188,7 +186,7 @@ public override void Submit_OnClick(object sender, EventArgs e) var templateInfo = TemplateManager.GetTemplateInfo(SiteId, templateId); if (templateInfo.TemplateName != TbTemplateName.Text) { - var templateNameList = DataProvider.TemplateDao.GetTemplateNameList(SiteId, templateInfo.TemplateType); + var templateNameList = DataProvider.Template.GetTemplateNameList(SiteId, templateInfo.Type); if (templateNameList.IndexOf(TbTemplateName.Text) != -1) { FailMessage("模板修改失败,模板名称已存在!"); @@ -199,7 +197,7 @@ public override void Submit_OnClick(object sender, EventArgs e) var isChanged = false; if (PathUtils.RemoveExtension(templateInfo.RelatedFileName) != PathUtils.RemoveExtension(TbRelatedFileName.Text))//文件名改变 { - var fileNameList = DataProvider.TemplateDao.GetLowerRelatedFileNameList(SiteId, templateInfo.TemplateType); + var fileNameList = DataProvider.Template.GetLowerRelatedFileNameList(SiteId, templateInfo.Type); foreach (var fileName in fileNameList) { var fileNameWithoutExtension = PathUtils.RemoveExtension(fileName); @@ -220,16 +218,25 @@ public override void Submit_OnClick(object sender, EventArgs e) if (isChanged) { - previousTemplateInfo = new TemplateInfo(templateInfo.Id, templateInfo.SiteId, templateInfo.TemplateName, templateInfo.TemplateType, templateInfo.RelatedFileName, templateInfo.CreatedFileFullName, templateInfo.CreatedFileExtName, templateInfo.Charset, templateInfo.IsDefault); + previousTemplateInfo = new TemplateInfo + { + Id = templateInfo.Id, + SiteId = templateInfo.SiteId, + TemplateName = templateInfo.TemplateName, + Type = templateInfo.Type, + RelatedFileName = templateInfo.RelatedFileName, + CreatedFileExtName = templateInfo.CreatedFileFullName, + CreatedFileFullName = templateInfo.CreatedFileExtName, + Default = templateInfo.Default + }; } templateInfo.TemplateName = TbTemplateName.Text; templateInfo.RelatedFileName = TbRelatedFileName.Text + DdlCreatedFileExtName.SelectedValue; templateInfo.CreatedFileExtName = DdlCreatedFileExtName.SelectedValue; templateInfo.CreatedFileFullName = TbCreatedFileFullName.Text + DdlCreatedFileExtName.SelectedValue; - templateInfo.Charset = ECharsetUtils.GetEnumType(DdlCharset.SelectedValue); - DataProvider.TemplateDao.Update(SiteInfo, templateInfo, TbContent.Text, AuthRequest.AdminName); + DataProvider.Template.Update(SiteInfo, templateInfo, TbContent.Text, AuthRequest.AdminName); if (previousTemplateInfo != null) { FileUtils.DeleteFileIfExists(TemplateManager.GetTemplateFilePath(SiteInfo, previousTemplateInfo)); @@ -237,20 +244,20 @@ public override void Submit_OnClick(object sender, EventArgs e) CreatePages(templateInfo); AuthRequest.AddSiteLog(SiteId, - $"修改{TemplateTypeUtils.GetText(templateInfo.TemplateType)}", + $"修改{TemplateTypeUtils.GetText(templateInfo.Type)}", $"模板名称:{templateInfo.TemplateName}"); SuccessMessage("模板修改成功!"); } else { - var templateNameList = DataProvider.TemplateDao.GetTemplateNameList(SiteId, TemplateTypeUtils.GetEnumType(HihTemplateType.Value)); + var templateNameList = DataProvider.Template.GetTemplateNameList(SiteId, TemplateTypeUtils.GetEnumType(HihTemplateType.Value)); if (templateNameList.IndexOf(TbTemplateName.Text) != -1) { FailMessage("模板添加失败,模板名称已存在!"); return; } - var fileNameList = DataProvider.TemplateDao.GetLowerRelatedFileNameList(SiteId, TemplateTypeUtils.GetEnumType(HihTemplateType.Value)); + var fileNameList = DataProvider.Template.GetLowerRelatedFileNameList(SiteId, TemplateTypeUtils.GetEnumType(HihTemplateType.Value)); if (fileNameList.IndexOf(TbRelatedFileName.Text.ToLower()) != -1) { FailMessage("模板添加失败,模板文件已存在!"); @@ -261,38 +268,37 @@ public override void Submit_OnClick(object sender, EventArgs e) { SiteId = SiteId, TemplateName = TbTemplateName.Text, - TemplateType = TemplateTypeUtils.GetEnumType(HihTemplateType.Value), + Type = TemplateTypeUtils.GetEnumType(HihTemplateType.Value), RelatedFileName = TbRelatedFileName.Text + DdlCreatedFileExtName.SelectedValue, CreatedFileExtName = DdlCreatedFileExtName.SelectedValue, CreatedFileFullName = TbCreatedFileFullName.Text + DdlCreatedFileExtName.SelectedValue, - Charset = ECharsetUtils.GetEnumType(DdlCharset.SelectedValue), - IsDefault = false + Default = false }; - templateInfo.Id = DataProvider.TemplateDao.Insert(templateInfo, TbContent.Text, AuthRequest.AdminName); + templateInfo.Id = DataProvider.Template.Insert(templateInfo, TbContent.Text, AuthRequest.AdminName); CreatePages(templateInfo); AuthRequest.AddSiteLog(SiteId, - $"添加{TemplateTypeUtils.GetText(templateInfo.TemplateType)}", + $"添加{TemplateTypeUtils.GetText(templateInfo.Type)}", $"模板名称:{templateInfo.TemplateName}"); SuccessMessage("模板添加成功!"); - AddWaitAndRedirectScript(PageTemplate.GetRedirectUrl(SiteId)); - } + AddWaitAndRedirectScript(PageTemplate.GetRedirectUrl(SiteId, _templateType)); + } } public void Return_OnClick(object sender, EventArgs e) { - PageUtils.Redirect(PageTemplate.GetRedirectUrl(SiteId, _templateType)); + WebPageUtils.Redirect(PageTemplate.GetRedirectUrl(SiteId, _templateType)); } private void CreatePages(TemplateInfo templateInfo) { - if (templateInfo.TemplateType == TemplateType.FileTemplate) + if (templateInfo.Type == TemplateType.FileTemplate) { CreateManager.CreateFile(SiteId, templateInfo.Id); } - else if (templateInfo.TemplateType == TemplateType.IndexPageTemplate) + else if (templateInfo.Type == TemplateType.IndexPageTemplate) { - if (templateInfo.IsDefault) + if (templateInfo.Default) { CreateManager.CreateChannel(SiteId, SiteId); } @@ -302,7 +308,7 @@ private void CreatePages(TemplateInfo templateInfo) private static string GetTemplateFileExtension(TemplateInfo templateInfo) { string extension; - if (templateInfo.TemplateType == TemplateType.IndexPageTemplate || templateInfo.TemplateType == TemplateType.FileTemplate) + if (templateInfo.Type == TemplateType.IndexPageTemplate || templateInfo.Type == TemplateType.FileTemplate) { extension = PathUtils.GetExtension(templateInfo.CreatedFileFullName); } diff --git a/net452/SiteServer.BackgroundPages/Cms/PageTemplateAssets.cs b/net452/SiteServer.BackgroundPages/Cms/PageTemplateAssets.cs new file mode 100644 index 000000000..a98f8c613 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageTemplateAssets.cs @@ -0,0 +1,148 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageTemplateAssets : BasePageCms + { + public Literal LtlPageTitle; + public Repeater RptContents; + public Button BtnConfig; + public Button BtnAdd; + + private string _type; + private string _name; + private string _ext; + private string _assetsDir; + private string _directoryPath; + + public const string TypeInclude = "include"; + public const string TypeJs = "js"; + public const string TypeCss= "css"; + public const string NameInclude = "包含文件"; + public const string NameJs = "脚本文件"; + public const string NameCss = "样式文件"; + public const string ExtInclude = ".html"; + public const string ExtJs = ".js"; + public const string ExtCss = ".css"; + + public static string GetRedirectUrl(int siteId, string type) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageTemplateAssets), new NameValueCollection + { + {"type", type} + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "type"); + _type = AuthRequest.GetQueryString("type"); + var tips = string.Empty; + + if (_type == TypeInclude) + { + _name = NameInclude; + _ext = ExtInclude; + _assetsDir = SiteInfo.TemplatesAssetsIncludeDir.Trim('/'); + + tips = $@"包含文件存放在 {_assetsDir} 目录中,模板中使用 <stl:include file=""/{_assetsDir}/包含文件.html""></stl:include> 引用。"; + } + else if (_type == TypeJs) + { + _name = NameJs; + _ext = ExtJs; + _assetsDir = SiteInfo.TemplatesAssetsJsDir.Trim('/'); + tips = + $@"脚本文件存放在 {_assetsDir} 目录中,模板中使用 <script type=""text/javascript"" src=""{{stl.siteUrl}}/{_assetsDir}/脚本文件.js""></script> 引用。"; + } + else if (_type == TypeCss) + { + _name = NameCss; + _ext = ExtCss; + _assetsDir = SiteInfo.TemplatesAssetsCssDir.Trim('/'); + tips = $@"样式文件存放在 {_assetsDir} 目录中,模板中使用 <link rel=""stylesheet"" type=""text/css"" href=""{{stl.siteUrl}}/{_assetsDir}/样式文件.css"" /> 引用。"; + } + + if (string.IsNullOrEmpty(_assetsDir)) return; + + _directoryPath = PathUtility.MapPath(SiteInfo, "@/" + _assetsDir); + + if (AuthRequest.IsQueryExists("delete")) + { + var fileName = AuthRequest.GetQueryString("fileName"); + + try + { + FileUtils.DeleteFileIfExists(PathUtils.Combine(_directoryPath, fileName)); + AuthRequest.AddSiteLog(SiteId, $"删除{_name}", $"{_name}:{fileName}"); + SuccessDeleteMessage(); + } + catch (Exception ex) + { + FailDeleteMessage(ex); + } + } + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Template); + + LtlPageTitle.Text = $"{_name}管理"; + InfoMessage(tips); + + DirectoryUtils.CreateDirectoryIfNotExists(_directoryPath); + var fileNames = DirectoryUtils.GetFileNames(_directoryPath); + var fileNameList = new List(); + foreach (var fileName in fileNames) + { + if (StringUtils.EqualsIgnoreCase(PathUtils.GetExtension(fileName), _ext)) + { + fileNameList.Add(fileName); + } + } + + RptContents.DataSource = fileNameList; + RptContents.ItemDataBound += RptContents_ItemDataBound; + RptContents.DataBind(); + + BtnConfig.Attributes.Add("onclick", ModalTemplateAssetsConfig.GetOpenWindowString(SiteId, _type)); + BtnAdd.Attributes.Add("onclick", $"location.href='{PageTemplateAssetsAdd.GetRedirectUrlToAdd(SiteId, _type)}';return false"); + } + + private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var fileName = (string)e.Item.DataItem; + + var ltlFileName = (Literal)e.Item.FindControl("ltlFileName"); + var ltlCharset = (Literal)e.Item.FindControl("ltlCharset"); + var ltlView = (Literal)e.Item.FindControl("ltlView"); + var ltlEdit = (Literal)e.Item.FindControl("ltlEdit"); + var ltlDelete = (Literal)e.Item.FindControl("ltlDelete"); + + ltlFileName.Text = fileName; + + var charset = FileUtils.GetFileCharset(PathUtils.Combine(_directoryPath, fileName)); + ltlCharset.Text = ECharsetUtils.GetText(charset); + + ltlView.Text = $@"查看"; + ltlEdit.Text = + $@"编辑"; + ltlDelete.Text = + $@"删除"; + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Cms/PageTemplateAssetsAdd.cs b/net452/SiteServer.BackgroundPages/Cms/PageTemplateAssetsAdd.cs new file mode 100644 index 000000000..900982e80 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageTemplateAssetsAdd.cs @@ -0,0 +1,202 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageTemplateAssetsAdd : BasePageCms + { + public Literal LtlPageTitle; + public TextBox TbRelatedFileName; + public DropDownList DdlCharset; + public TextBox TbContent; + public PlaceHolder PhCodeMirror; + public PlaceHolder PhCodeMirrorInclude; + public PlaceHolder PhCodeMirrorJs; + public PlaceHolder PhCodeMirrorCss; + public Button BtnEditorType; + + private string _type; + private string _name; + private string _ext; + private string _assetsDir; + private string _directoryPath; + private string _fileName; + + public static string GetRedirectUrlToAdd(int siteId, string type) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageTemplateAssetsAdd), new NameValueCollection + { + {"type", type} + }); + } + + public static string GetRedirectUrlToEdit(int siteId, string type, string fileName) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageTemplateAssetsAdd), new NameValueCollection + { + {"type", type}, + {"fileName", fileName} + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId", "type"); + _type = AuthRequest.GetQueryString("type"); + if (_type == PageTemplateAssets.TypeInclude) + { + _name = PageTemplateAssets.NameInclude; + _ext = PageTemplateAssets.ExtInclude; + _assetsDir = SiteInfo.TemplatesAssetsIncludeDir.Trim('/'); + PhCodeMirrorInclude.Visible = true; + } + else if (_type == PageTemplateAssets.TypeJs) + { + _name = PageTemplateAssets.NameJs; + _ext = PageTemplateAssets.ExtJs; + _assetsDir = SiteInfo.TemplatesAssetsJsDir.Trim('/'); + PhCodeMirrorJs.Visible = true; + } + else if (_type == PageTemplateAssets.TypeCss) + { + _name = PageTemplateAssets.NameCss; + _ext = PageTemplateAssets.ExtCss; + _assetsDir = SiteInfo.TemplatesAssetsCssDir.Trim('/'); + PhCodeMirrorCss.Visible = true; + } + + if (string.IsNullOrEmpty(_assetsDir)) return; + + _directoryPath = PathUtility.MapPath(SiteInfo, "@/" + _assetsDir); + + if (AuthRequest.IsQueryExists("fileName")) + { + _fileName = AuthRequest.GetQueryString("fileName"); + _fileName = PathUtils.RemoveParentPath(_fileName); + } + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Template); + + LtlPageTitle.Text = string.IsNullOrEmpty(_fileName) ? $"添加{_name}" : $"编辑{_name}"; + + var isCodeMirror = SiteInfo.ConfigTemplateIsCodeMirror; + BtnEditorType.Text = isCodeMirror ? "采用纯文本编辑模式" : "采用代码编辑模式"; + PhCodeMirror.Visible = isCodeMirror; + + FxUtils.AddListItemsToECharset(DdlCharset); + + if (_fileName != null) + { + if (!StringUtils.EqualsIgnoreCase(PathUtils.GetExtension(_fileName), _ext)) + { + WebPageUtils.RedirectToErrorPage("对不起,此文件格式无法编辑!"); + } + else + { + TbRelatedFileName.Text = _fileName; + var fileCharset = FileUtils.GetFileCharset(PathUtils.Combine(_directoryPath, _fileName)); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlCharset, ECharsetUtils.GetValue(fileCharset)); + TbContent.Text = FileUtils.ReadText(PathUtils.Combine(_directoryPath, _fileName), fileCharset); + } + } + else + { + SystemWebUtils.SelectSingleItemIgnoreCase(DdlCharset, SiteInfo.Charset); + } + } + + public void EditorType_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + var isCodeMirror = SiteInfo.ConfigTemplateIsCodeMirror; + isCodeMirror = !isCodeMirror; + SiteInfo.ConfigTemplateIsCodeMirror = isCodeMirror; + DataProvider.Site.Update(SiteInfo); + + BtnEditorType.Text = isCodeMirror ? "采用纯文本编辑模式" : "采用代码编辑模式"; + PhCodeMirror.Visible = isCodeMirror; + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + var relatedFileName = TbRelatedFileName.Text; + if (!StringUtils.EndsWithIgnoreCase(relatedFileName, _ext)) + { + relatedFileName += _ext; + } + + if (_fileName != null) + { + var isChanged = false; + if (!StringUtils.EqualsIgnoreCase(_fileName, relatedFileName))//文件名改变 + { + var fileNames = DirectoryUtils.GetFileNames(_directoryPath); + foreach (var theFileName in fileNames) + { + if (StringUtils.EqualsIgnoreCase(theFileName, relatedFileName)) + { + FailMessage($"{_name}修改失败,文件已存在!"); + return; + } + } + + isChanged = true; + } + + var previousFileName = string.Empty; + if (isChanged) + { + previousFileName = _fileName; + } + + var charset = ECharsetUtils.GetEnumType(DdlCharset.SelectedValue); + FileUtils.WriteText(PathUtils.Combine(_directoryPath, relatedFileName), charset, TbContent.Text); + if (!string.IsNullOrEmpty(previousFileName)) + { + FileUtils.DeleteFileIfExists(PathUtils.Combine(_directoryPath, previousFileName)); + } + AuthRequest.AddSiteLog(SiteId, $"修改{_name}", $"{_name}:{relatedFileName}"); + SuccessMessage($"{_name}修改成功!"); + AddWaitAndRedirectScript(PageTemplateAssets.GetRedirectUrl(SiteId, _type)); + } + else + { + var fileNames = DirectoryUtils.GetFileNames(_directoryPath); + foreach (var theFileName in fileNames) + { + if (StringUtils.EqualsIgnoreCase(theFileName, relatedFileName)) + { + FailMessage($"{_name}添加失败,文件已存在!"); + return; + } + } + + var charset = ECharsetUtils.GetEnumType(DdlCharset.SelectedValue); + FileUtils.WriteText(PathUtils.Combine(_directoryPath, relatedFileName), charset, TbContent.Text); + AuthRequest.AddSiteLog(SiteId, $"添加{_name}", $"{_name}:{relatedFileName}"); + SuccessMessage($"{_name}添加成功!"); + AddWaitAndRedirectScript(PageTemplateAssets.GetRedirectUrl(SiteId, _type)); + } + } + + public void Return_OnClick(object sender, EventArgs e) + { + WebPageUtils.Redirect(PageTemplateAssets.GetRedirectUrl(SiteId, _type)); + } + } +} diff --git a/SiteServer.BackgroundPages/Cms/PageTemplateLeft.cs b/net452/SiteServer.BackgroundPages/Cms/PageTemplateLeft.cs similarity index 89% rename from SiteServer.BackgroundPages/Cms/PageTemplateLeft.cs rename to net452/SiteServer.BackgroundPages/Cms/PageTemplateLeft.cs index 05ecda674..a742c6ec8 100644 --- a/SiteServer.BackgroundPages/Cms/PageTemplateLeft.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageTemplateLeft.cs @@ -1,8 +1,11 @@ using System; using System.Collections.Generic; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; using SiteServer.Plugin; namespace SiteServer.BackgroundPages.Cms @@ -21,11 +24,11 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId"); + WebPageUtils.CheckRequestParameter("siteId"); if (IsPostBack) return; - _dictionary = DataProvider.TemplateDao.GetCountDictionary(SiteId); + _dictionary = DataProvider.Template.GetCountDictionary(SiteId); LtlTotalCount.Text = $"({GetCount(string.Empty)})"; LtlIndexPageCount.Text = $"({GetCount("IndexPageTemplate")})"; diff --git a/SiteServer.BackgroundPages/Cms/PageTemplateLog.cs b/net452/SiteServer.BackgroundPages/Cms/PageTemplateLog.cs similarity index 82% rename from SiteServer.BackgroundPages/Cms/PageTemplateLog.cs rename to net452/SiteServer.BackgroundPages/Cms/PageTemplateLog.cs index 3f255cb4b..3673ba168 100644 --- a/SiteServer.BackgroundPages/Cms/PageTemplateLog.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageTemplateLog.cs @@ -4,8 +4,10 @@ using SiteServer.Utils; using SiteServer.BackgroundPages.Controls; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Cms { @@ -19,7 +21,7 @@ public class PageTemplateLog : BasePageCms public static string GetRedirectUrl(int siteId, int templateId) { - return PageUtils.GetCmsUrl(siteId, nameof(PageTemplateLog), new NameValueCollection + return FxUtils.GetCmsUrl(siteId, nameof(PageTemplateLog), new NameValueCollection { {"TemplateID", templateId.ToString()} }); @@ -31,12 +33,12 @@ public void Page_Load(object sender, EventArgs e) _templateId = AuthRequest.GetQueryInt("templateID"); - if (AuthRequest.IsQueryExists("Delete")) + if (AuthRequest.IsQueryExists("DeleteById")) { var arraylist = TranslateUtils.StringCollectionToIntList(Request.QueryString["IDCollection"]); try { - DataProvider.TemplateLogDao.Delete(arraylist); + DataProvider.TemplateLog.Delete(arraylist); SuccessDeleteMessage(); } catch (Exception ex) @@ -46,9 +48,9 @@ public void Page_Load(object sender, EventArgs e) } SpContents.ControlToPaginate = RptContents; - SpContents.ItemsPerPage = StringUtils.Constants.PageSize; + SpContents.ItemsPerPage = Constants.PageSize; - SpContents.SelectCommand = DataProvider.TemplateLogDao.GetSelectCommend(SiteId, _templateId); + SpContents.SelectCommand = DataProvider.TemplateLog.GetSelectCommend(SiteId, _templateId); SpContents.SortField = nameof(TemplateLogInfo.Id); SpContents.SortMode = SortMode.DESC; @@ -60,10 +62,10 @@ public void Page_Load(object sender, EventArgs e) BtnDelete.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert( - PageUtils.GetCmsUrl(SiteId, nameof(PageTemplateLog), new NameValueCollection + FxUtils.GetCmsUrl(SiteId, nameof(PageTemplateLog), new NameValueCollection { {"TemplateID", _templateId.ToString()}, - {"Delete", true.ToString()} + {"DeleteById", true.ToString()} }), "IDCollection", "IDCollection", "请选择需要删除的修订历史!", "此操作将删除所选修订历史,确认吗?")); SpContents.DataBind(); diff --git a/net452/SiteServer.BackgroundPages/Cms/PageTemplateMatch.cs b/net452/SiteServer.BackgroundPages/Cms/PageTemplateMatch.cs new file mode 100644 index 000000000..60f0af3d9 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageTemplateMatch.cs @@ -0,0 +1,543 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Plugin; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageTemplateMatch : BasePageCms + { + public ListBox LbChannelId; + public ListBox LbChannelTemplateId; + public ListBox LbContentTemplateId; + public Button BtnCreateChannelTemplate; + public Button BtnCreateSubChannelTemplate; + public Button BtnCreateContentTemplate; + public Button BtnCreateSubContentTemplate; + + private bool[] _isLastNodeArray; + private string _defaultChannelTemplateName; + private string _defaultContentTemplateName; + + public static string GetRedirectUrl(int siteId) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageTemplateMatch), null); + } + + public string GetTitle(ChannelInfo nodeInfo) + { + var str = string.Empty; + if (nodeInfo.Id == SiteId) + { + nodeInfo.LastNode = true; + } + if (nodeInfo.LastNode == false) + { + _isLastNodeArray[nodeInfo.ParentsCount] = false; + } + else + { + _isLastNodeArray[nodeInfo.ParentsCount] = true; + } + for (var i = 0; i < nodeInfo.ParentsCount; i++) + { + str = string.Concat(str, _isLastNodeArray[i] ? " " : "│"); + } + str = string.Concat(str, nodeInfo.LastNode ? "└" : "├"); + str = string.Concat(str, StringUtils.MaxLengthText(nodeInfo.ChannelName, 8)); + + if (nodeInfo.ParentId == 0) + { + var indexTemplateId = TemplateManager.GetDefaultTemplateId(SiteId, TemplateType.IndexPageTemplate); + var indexTemplateName = TemplateManager.GetTemplateName(SiteId, indexTemplateId); + str = string.Concat(str, $" ({indexTemplateName})"); + } + else + { + var channelTemplateId = nodeInfo.ChannelTemplateId; + var contentTemplateId = nodeInfo.ContentTemplateId; + + var channelTemplateName = string.Empty; + if (channelTemplateId != 0) + { + channelTemplateName = TemplateManager.GetTemplateName(SiteId, channelTemplateId); + } + if (string.IsNullOrEmpty(channelTemplateName)) + { + channelTemplateName = _defaultChannelTemplateName; + } + str = string.Concat(str, $" ({channelTemplateName})"); + + var contentTemplateName = string.Empty; + if (contentTemplateId != 0) + { + contentTemplateName = TemplateManager.GetTemplateName(SiteId, contentTemplateId); + } + if (string.IsNullOrEmpty(contentTemplateName)) + { + contentTemplateName = _defaultContentTemplateName; + } + str = string.Concat(str, $" ({contentTemplateName})"); + } + + return str; + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId"); + + var defaultChannelTemplateId = TemplateManager.GetDefaultTemplateId(SiteId, TemplateType.ChannelTemplate); + _defaultChannelTemplateName = TemplateManager.GetTemplateName(SiteId, defaultChannelTemplateId); + + var defaultContentTemplateId = TemplateManager.GetDefaultTemplateId(SiteId, TemplateType.ContentTemplate); + _defaultContentTemplateName = TemplateManager.GetTemplateName(SiteId, defaultContentTemplateId); + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Template); + + LbChannelTemplateId.Attributes.Add("onfocus", "$('#LbContentTemplateId option:selected').removeAttr('selected')"); + LbContentTemplateId.Attributes.Add("onfocus", "$('#LbChannelTemplateId option:selected').removeAttr('selected')"); + + BindListBox(); + + BtnCreateChannelTemplate.OnClientClick = $"{AlertUtils.Confirm("创建栏目模板", "此操作将创建空的栏目模板并匹配选中栏目,确认吗?", "创 建", "$('#BtnCreateChannelTemplateReal').click()")}"; + BtnCreateSubChannelTemplate.OnClientClick = $"{AlertUtils.Confirm("创建下级栏目模版", "此操作将创建空的栏目模板并匹配选中栏目的下级栏目,确认吗?", "创 建", "$('#BtnCreateSubChannelTemplateReal').click()")}"; + BtnCreateContentTemplate.OnClientClick = $"{AlertUtils.Confirm("创建内容模版", "此操作将创建空的内容模板并匹配选中栏目,确认吗?", "创 建", "$('#BtnCreateContentTemplateReal').click()")}"; + BtnCreateSubContentTemplate.OnClientClick = $"{AlertUtils.Confirm("创建下级内容模版", "此操作将创建空的内容模板并匹配选中栏目的下级栏目,确认吗?", "创 建", "$('#BtnCreateSubContentTemplateReal').click()")}"; + } + + + public void BindListBox() + { + var selectedChannelIdList = new List(); + foreach (ListItem listitem in LbChannelId.Items) + { + if (listitem.Selected) selectedChannelIdList.Add(listitem.Value); + } + var selectedChannelTemplateId = LbChannelTemplateId.SelectedValue; + var selectedContentTemplateId = LbContentTemplateId.SelectedValue; + + LbChannelId.Items.Clear(); + LbChannelTemplateId.Items.Clear(); + LbContentTemplateId.Items.Clear(); + var channelIdList = ChannelManager.GetChannelIdList(SiteId); + var nodeCount = channelIdList.Count; + _isLastNodeArray = new bool[nodeCount]; + foreach (var theChannelId in channelIdList) + { + var nodeInfo = ChannelManager.GetChannelInfo(SiteId, theChannelId); + var listitem = new ListItem(GetTitle(nodeInfo), nodeInfo.Id.ToString()); + LbChannelId.Items.Add(listitem); + } + + LbChannelTemplateId.DataSource = DataProvider.Template.GetDataSourceByType(SiteId, TemplateType.ChannelTemplate); + LbContentTemplateId.DataSource = DataProvider.Template.GetDataSourceByType(SiteId, TemplateType.ContentTemplate); + DataBind(); + + SystemWebUtils.SelectMultiItems(LbChannelId, selectedChannelIdList); + SystemWebUtils.SelectSingleItem(LbChannelTemplateId, selectedChannelTemplateId); + SystemWebUtils.SelectSingleItem(LbContentTemplateId, selectedContentTemplateId); + } + + public void MatchChannelTemplateButton_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid || !Validate(true, true)) return; + + var channelIdList = new List(); + foreach (ListItem item in LbChannelId.Items) + { + if (item.Selected) + { + var channelId = int.Parse(item.Value); + channelIdList.Add(channelId); + } + } + var channelTemplateId = int.Parse(LbChannelTemplateId.SelectedValue); + Process(channelIdList, channelTemplateId, true); + } + + public void RemoveChannelTemplateButton_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid || !Validate(false, true)) return; + + var channelIdList = new List(); + foreach (ListItem item in LbChannelId.Items) + { + if (item.Selected) + { + var channelId = int.Parse(item.Value); + channelIdList.Add(channelId); + } + } + Process(channelIdList, 0, true); + } + + public void MatchContentTemplateButton_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid || !Validate(true, false)) return; + + var channelIdList = new List(); + foreach (ListItem item in LbChannelId.Items) + { + if (item.Selected) + { + var channelId = int.Parse(item.Value); + channelIdList.Add(channelId); + } + } + var contentTemplateId = int.Parse(LbContentTemplateId.SelectedValue); + Process(channelIdList, contentTemplateId, false); + } + + public void RemoveContentTemplateButton_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid || !Validate(false, false)) return; + + var channelIdList = new List(); + foreach (ListItem item in LbChannelId.Items) + { + if (item.Selected) + { + var channelId = int.Parse(item.Value); + channelIdList.Add(channelId); + } + } + Process(channelIdList, 0, false); + } + + private bool Validate(bool isMatch, bool isChannelTemplate) + { + if (LbChannelId.SelectedIndex < 0) + { + FailMessage("请选择栏目!"); + return false; + } + if (isMatch) + { + if (isChannelTemplate) + { + if (LbChannelTemplateId.SelectedIndex < 0) + { + FailMessage("请选择栏目模板!"); + return false; + } + } + else + { + if (LbContentTemplateId.SelectedIndex < 0) + { + FailMessage("请选择内容模板!"); + return false; + } + } + } + return true; + } + + private void Process(List channelIdList, int templateId, bool isChannelTemplate) + { + if (channelIdList != null && channelIdList.Count > 0) + { + if (isChannelTemplate) + { + foreach (var channelId in channelIdList) + { + var channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + channelInfo.ChannelTemplateId = templateId; + DataProvider.Channel.UpdateChannelTemplateId(channelInfo); + } + } + else + { + foreach (var channelId in channelIdList) + { + var channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + channelInfo.ContentTemplateId = templateId; + DataProvider.Channel.UpdateContentTemplateId(channelInfo); + } + } + } + + if (templateId == 0) + { + AuthRequest.AddSiteLog(SiteId, "取消模板匹配", $"栏目:{GetNodeNames()}"); + SuccessMessage("取消匹配成功!"); + } + else + { + AuthRequest.AddSiteLog(SiteId, "模板匹配", $"栏目:{GetNodeNames()}"); + SuccessMessage("模板匹配成功!"); + } + + BindListBox(); + } + + private string GetNodeNames() + { + var builder = new StringBuilder(); + foreach (ListItem listItem in LbChannelId.Items) + { + if (listItem.Selected) + { + builder.Append(listItem.Text).Append(","); + } + } + + if (builder.Length > 0) + { + builder.Length = builder.Length - 1; + } + + return RegexUtils.Replace("\\(.*?\\)|│|├| |└", builder.ToString(), string.Empty); + } + + public void CreateChannelTemplate_Click(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid || !Validate(false, false)) return; + + var defaultChannelTemplateId = TemplateManager.GetDefaultTemplateId(SiteId, TemplateType.ChannelTemplate); + var relatedFileNameList = DataProvider.Template.GetLowerRelatedFileNameList(SiteId, TemplateType.ChannelTemplate); + var templateNameList = DataProvider.Template.GetTemplateNameList(SiteId, TemplateType.ChannelTemplate); + foreach (ListItem item in LbChannelId.Items) + { + if (!item.Selected) continue; + + var channelId = int.Parse(item.Value); + var channelTemplateId = -1; + + var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + if (nodeInfo.ParentId > 0) + { + channelTemplateId = nodeInfo.ChannelTemplateId; + } + + if (channelTemplateId != -1 && channelTemplateId != 0 && channelTemplateId != defaultChannelTemplateId) + { + if (TemplateManager.GetTemplateInfo(SiteId, channelTemplateId) == null) + { + channelTemplateId = -1; + } + } + + if (channelTemplateId != -1) + { + var templateInfo = new TemplateInfo + { + SiteId = SiteId, + TemplateName = nodeInfo.ChannelName, + Type = TemplateType.ChannelTemplate, + RelatedFileName = "T_" + nodeInfo.ChannelName + ".html", + CreatedFileFullName = "index.html", + CreatedFileExtName = ".html", + Default = false + }; + + if (relatedFileNameList.Contains(templateInfo.RelatedFileName.ToLower())) + { + continue; + } + if (templateNameList.Contains(templateInfo.TemplateName)) + { + continue; + } + var insertedTemplateId = DataProvider.Template.Insert(templateInfo, string.Empty, AuthRequest.AdminName); + if (nodeInfo.ParentId > 0) + { + nodeInfo.ChannelTemplateId = insertedTemplateId; + DataProvider.Channel.UpdateChannelTemplateId(nodeInfo); + + //TemplateManager.UpdateChannelTemplateId(SiteId, channelId, insertedTemplateId); + //DataProvider.BackgroundNodeDAO.UpdateChannelTemplateID(channelId, insertedTemplateID); + } + + } + } + + AuthRequest.AddSiteLog(SiteId, "生成并匹配栏目模版", $"栏目:{GetNodeNames()}"); + + SuccessMessage("生成栏目模版并匹配成功!"); + + BindListBox(); + } + + public void CreateSubChannelTemplate_Click(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid || !Validate(false, false)) return; + + var relatedFileNameList = DataProvider.Template.GetLowerRelatedFileNameList(SiteId, TemplateType.ChannelTemplate); + var templateNameList = DataProvider.Template.GetTemplateNameList(SiteId, TemplateType.ChannelTemplate); + foreach (ListItem item in LbChannelId.Items) + { + if (!item.Selected) continue; + + var channelId = int.Parse(item.Value); + var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + + var templateInfo = new TemplateInfo + { + SiteId = SiteId, + TemplateName = nodeInfo.ChannelName + "_下级", + Type = TemplateType.ChannelTemplate, + RelatedFileName = "T_" + nodeInfo.ChannelName + "_下级.html", + CreatedFileFullName = "index.html", + CreatedFileExtName = ".html", + Default = false + }; + + if (relatedFileNameList.Contains(templateInfo.RelatedFileName.ToLower())) + { + continue; + } + if (templateNameList.Contains(templateInfo.TemplateName)) + { + continue; + } + var insertedTemplateId = DataProvider.Template.Insert(templateInfo, string.Empty, AuthRequest.AdminName); + var childChannelIdList = ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(SiteId, channelId), EScopeType.Descendant, string.Empty, string.Empty, string.Empty); + foreach (var childChannelId in childChannelIdList) + { + var childChannelInfo = ChannelManager.GetChannelInfo(SiteId, childChannelId); + childChannelInfo.ChannelTemplateId = insertedTemplateId; + DataProvider.Channel.UpdateChannelTemplateId(childChannelInfo); + + //TemplateManager.UpdateChannelTemplateId(SiteId, childChannelId, insertedTemplateId); + //DataProvider.BackgroundNodeDAO.UpdateChannelTemplateID(childChannelId, insertedTemplateID); + } + } + + AuthRequest.AddSiteLog(SiteId, "生成并匹配下级栏目模版", $"栏目:{GetNodeNames()}"); + + SuccessMessage("生成下级栏目模版并匹配成功!"); + + BindListBox(); + } + + public void CreateContentTemplate_Click(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid || !Validate(false, false)) return; + + var defaultContentTemplateId = TemplateManager.GetDefaultTemplateId(SiteId, TemplateType.ContentTemplate); + var relatedFileNameList = DataProvider.Template.GetLowerRelatedFileNameList(SiteId, TemplateType.ContentTemplate); + var templateNameList = DataProvider.Template.GetTemplateNameList(SiteId, TemplateType.ContentTemplate); + foreach (ListItem item in LbChannelId.Items) + { + if (!item.Selected) continue; + + var channelId = TranslateUtils.ToInt(item.Value); + + var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + + var contentTemplateId = nodeInfo.ContentTemplateId; + + if (contentTemplateId != 0 && contentTemplateId != defaultContentTemplateId) + { + if (TemplateManager.GetTemplateInfo(SiteId, contentTemplateId) == null) + { + contentTemplateId = -1; + } + } + + if (contentTemplateId != -1) + { + var templateInfo = new TemplateInfo + { + SiteId = SiteId, + TemplateName = nodeInfo.ChannelName, + Type = TemplateType.ContentTemplate, + RelatedFileName = "T_" + nodeInfo.ChannelName + ".html", + CreatedFileFullName = "index.html", + CreatedFileExtName = ".html", + Default = false + }; + if (relatedFileNameList.Contains(templateInfo.RelatedFileName.ToLower())) + { + continue; + } + if (templateNameList.Contains(templateInfo.TemplateName)) + { + continue; + } + var insertedTemplateId = DataProvider.Template.Insert(templateInfo, string.Empty, AuthRequest.AdminName); + + var channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + channelInfo.ContentTemplateId = insertedTemplateId; + DataProvider.Channel.UpdateContentTemplateId(channelInfo); + + //TemplateManager.UpdateContentTemplateId(SiteId, channelId, insertedTemplateId); + //DataProvider.BackgroundNodeDAO.UpdateContentTemplateID(channelId, insertedTemplateID); + } + } + + AuthRequest.AddSiteLog(SiteId, "生成并匹配内容模版", $"栏目:{GetNodeNames()}"); + + SuccessMessage("生成内容模版并匹配成功!"); + + BindListBox(); + } + + public void CreateSubContentTemplate_Click(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid || !Validate(false, false)) return; + + var relatedFileNameList = DataProvider.Template.GetLowerRelatedFileNameList(SiteId, TemplateType.ContentTemplate); + var templateNameList = DataProvider.Template.GetTemplateNameList(SiteId, TemplateType.ContentTemplate); + foreach (ListItem item in LbChannelId.Items) + { + if (!item.Selected) continue; + + var channelId = int.Parse(item.Value); + var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + + var templateInfo = new TemplateInfo + { + SiteId = SiteId, + TemplateName = nodeInfo.ChannelName + "_下级", + Type = TemplateType.ContentTemplate, + RelatedFileName = "T_" + nodeInfo.ChannelName + "_下级.html", + CreatedFileFullName = "index.html", + CreatedFileExtName = ".html", + Default = false + }; + + if (relatedFileNameList.Contains(templateInfo.RelatedFileName.ToLower())) + { + continue; + } + if (templateNameList.Contains(templateInfo.TemplateName)) + { + continue; + } + var insertedTemplateId = DataProvider.Template.Insert(templateInfo, string.Empty, AuthRequest.AdminName); + var childChannelIdList = ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(SiteId, channelId), EScopeType.Descendant, string.Empty, string.Empty, string.Empty); + foreach (var childChannelId in childChannelIdList) + { + var childChannelInfo = ChannelManager.GetChannelInfo(SiteId, childChannelId); + childChannelInfo.ContentTemplateId = insertedTemplateId; + DataProvider.Channel.UpdateContentTemplateId(childChannelInfo); + + //TemplateManager.UpdateContentTemplateId(SiteId, childChannelId, insertedTemplateId); + //DataProvider.BackgroundNodeDAO.UpdateContentTemplateID(childChannelId, insertedTemplateID); + } + } + + AuthRequest.AddSiteLog(SiteId, "生成并匹配下级内容模版", $"栏目:{GetNodeNames()}"); + + SuccessMessage("生成下级内容模版并匹配成功!"); + + BindListBox(); + } + } +} diff --git a/SiteServer.BackgroundPages/Cms/PageTemplatePreview.cs b/net452/SiteServer.BackgroundPages/Cms/PageTemplatePreview.cs similarity index 78% rename from SiteServer.BackgroundPages/Cms/PageTemplatePreview.cs rename to net452/SiteServer.BackgroundPages/Cms/PageTemplatePreview.cs index b94b17d56..ec8f4488b 100644 --- a/SiteServer.BackgroundPages/Cms/PageTemplatePreview.cs +++ b/net452/SiteServer.BackgroundPages/Cms/PageTemplatePreview.cs @@ -1,7 +1,11 @@ using System; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; using SiteServer.CMS.StlParser.Utility; using SiteServer.Plugin; @@ -21,13 +25,13 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId"); + WebPageUtils.CheckRequestParameter("siteId"); if (IsPostBack) return; VerifySitePermissions(ConfigManager.WebSitePermissions.Template); - TemplateTypeUtils.AddListItems(DdlTemplateType); - ChannelManager.AddListItems(DdlChannelId.Items, SiteInfo, false, true, AuthRequest.AdminPermissions); + SystemWebUtils.AddListItemsToTemplateType(DdlTemplateType); + SystemWebUtils.AddListItemsForChannel(DdlChannelId.Items, SiteInfo, false, true, AuthRequest.AdminPermissionsImpl); if (AuthRequest.IsQueryExists("fromCache")) { TbTemplate.Text = TranslateUtils.DecryptStringBySecretKey(CacheUtils.Get("SiteServer.BackgroundPages.Cms.PageTemplatePreview")); @@ -68,11 +72,11 @@ public void BtnPreview_OnClick(object sender, EventArgs e) channelId = TranslateUtils.ToInt(DdlChannelId.SelectedValue); if (templateType == TemplateType.ContentTemplate) { - var nodeInfo = ChannelManager.GetChannelInfo(SiteId, channelId); - if (nodeInfo.ContentNum > 0) + var channelInfo = ChannelManager.GetChannelInfo(SiteId, channelId); + var count = ContentManager.GetCount(SiteInfo, channelInfo, true); + if (count > 0) { - var tableName = ChannelManager.GetTableName(SiteInfo, nodeInfo); - contentId = DataProvider.ContentDao.GetFirstContentId(tableName, channelId); + contentId = channelInfo.ContentRepository.GetFirstContentId(SiteId, channelId); } if (contentId == 0) @@ -90,7 +94,7 @@ public void BtnPreview_OnClick(object sender, EventArgs e) public void BtnReturn_OnClick(object sender, EventArgs e) { - PageUtils.Redirect(TranslateUtils.DecryptStringBySecretKey(AuthRequest.GetQueryString("returnUrl"))); + WebPageUtils.Redirect(TranslateUtils.DecryptStringBySecretKey(AuthRequest.GetQueryString("returnUrl"))); } } } \ No newline at end of file diff --git a/net452/SiteServer.BackgroundPages/Cms/PageTemplateReference.cs b/net452/SiteServer.BackgroundPages/Cms/PageTemplateReference.cs new file mode 100644 index 000000000..6e4532867 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Cms/PageTemplateReference.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Specialized; +using System.Reflection; +using System.Text; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Fx; +using SiteServer.CMS.StlParser.Model; +using SiteServer.Utils; + +namespace SiteServer.BackgroundPages.Cms +{ + public class PageTemplateReference : BasePageCms + { + public Literal LtlAll; + public PlaceHolder PhRefenreces; + public Literal LtlReferences; + + public static string GetRedirectUrl(int siteId, string elementName) + { + return FxUtils.GetCmsUrl(siteId, nameof(PageTemplateReference), new NameValueCollection + { + {"elementName", elementName} + }); + } + + private string _elementName = string.Empty; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId"); + + _elementName = AuthRequest.GetQueryString("elementName"); + + if (IsPostBack) return; + + VerifySitePermissions(ConfigManager.WebSitePermissions.Template); + + var elements = StlAll.Elements; + var allBuilder = new StringBuilder(); + foreach (var elementName in elements.Keys) + { + if (!elements.TryGetValue(elementName, out var elementType)) continue; + + var tagName = elementName.Substring(4); + var stlAttribute = (StlElementAttribute)Attribute.GetCustomAttribute(elementType, typeof(StlElementAttribute)); + + allBuilder.Append($@" + + + + {elementName} + + + {stlAttribute.Title} + https://www.siteserver.cn/docs/stl/{tagName}/ +"); + } + + LtlAll.Text = $@" +
    +
    +
    + + + + + + + + + + {allBuilder} + +
    标签说明参考
    +
    +
    +
    +"; + + if (!string.IsNullOrEmpty(_elementName)) + { + if (elements.TryGetValue(_elementName, out var elementType)) + { + var tagName = _elementName.Substring(4); + PhRefenreces.Visible = true; + + var attrBuilder = new StringBuilder(); + + var fields = elementType.GetFields(BindingFlags.Static | BindingFlags.NonPublic); + foreach (var field in fields) + { + var fieldName = field.Name.ToCamelCase(); + var attr = (StlAttributeAttribute)Attribute.GetCustomAttribute(field, typeof(StlAttributeAttribute)); + + if (attr != null) + { + var attrUrl = + $"https://www.siteserver.cn/docs/stl/{tagName}/#{fieldName.ToLower()}-{attr.Title.ToLower()}"; + + attrBuilder.Append($@" + + {fieldName} + {attr.Title} + {attrUrl} +"); + } + } + + var helpUrl = $"https://www.siteserver.cn/docs/stl/{tagName}/"; + + var stlAttribute = (StlElementAttribute)Attribute.GetCustomAttribute(elementType, typeof(StlElementAttribute)); + + LtlReferences.Text = $@" +
    +

    + <{_elementName}> {stlAttribute.Title} +

    +

    + {stlAttribute.Description} + 详细使用说明 +

    +
    +
    +
    + + + + + + + + + + {attrBuilder} + +
    属性说明参考
    +
    +
    +
    +
    +"; + } + } + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.BackgroundPages/Controls/Alerts.cs b/net452/SiteServer.BackgroundPages/Controls/Alerts.cs new file mode 100644 index 000000000..7cb8aa360 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Controls/Alerts.cs @@ -0,0 +1,43 @@ +using System.Web.UI; +using System.Web.UI.HtmlControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Fx; +using SiteServer.Utils; + +namespace SiteServer.BackgroundPages.Controls +{ + public class Alerts : HtmlContainerControl + { + public bool IsShowImmidiatary { get; set; } + + public WebPageUtils.Message.EMessageType MessageType { get; set; } = WebPageUtils.Message.EMessageType.None; + + public string Content { get; set; } = string.Empty; + + public string Text + { + get + { + var state = ViewState["Text"]; + if (state != null) + { + return (string)state; + } + return string.Empty; + } + set + { + ViewState["Text"] = value; + } + } + + protected override void Render(HtmlTextWriter writer) + { + writer.Write(IsShowImmidiatary + ? WebPageUtils.GetAlertHtml(MessageType, Content, this) + : WebPageUtils.GetAlertHtml(this, string.IsNullOrEmpty(Text) ? InnerHtml : Text)); + + writer.Write(@"
    提示!  
    "); + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Controls/AuxiliaryControl.cs b/net452/SiteServer.BackgroundPages/Controls/AuxiliaryControl.cs new file mode 100644 index 000000000..763a20c91 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Controls/AuxiliaryControl.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Text; +using System.Web.UI; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.BackgroundPages.Controls +{ + public class AuxiliaryControl : Control + { + public IDictionary Attributes { get; set; } + + public SiteInfo SiteInfo { get; set; } + + public int ChannelId { get; set; } + + public int ContentId { get; set; } + + public List StyleInfoList { get; set; } + + protected override void Render(HtmlTextWriter output) + { + if (StyleInfoList == null || StyleInfoList.Count == 0 || Attributes == null) return; + + var pageScripts = new NameValueCollection(); + + var builder = new StringBuilder(); + foreach (var styleInfo in StyleInfoList) + { + if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.Title)) continue; + + var value = BackgroundInputTypeParser.Parse(SiteInfo, ChannelId, styleInfo, Attributes, pageScripts, out var extra); + + if (string.IsNullOrEmpty(value) && string.IsNullOrEmpty(extra)) continue; + + if (styleInfo.Type == InputType.TextEditor) + { + var commands = WebUtils.GetTextEditorCommands(SiteInfo, styleInfo.AttributeName); + builder.Append($@" +
    + +
    + {commands} +
    + {value} +
    +
    +
    + {extra} +
    +
    "); + } + else + { + var html = $@" +
    + +
    + {value} +
    +
    + {extra} +
    +
    "; + + if (styleInfo.Type == InputType.Customize) + { + var eventArgs = new ContentFormLoadEventArgs(SiteInfo.Id, ChannelId, ContentId, Attributes, styleInfo.AttributeName, html); + foreach (var service in PluginManager.Services) + { + try + { + html = service.OnContentFormLoad(eventArgs); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(service.PluginId, ex, nameof(IService.ContentFormLoad)); + } + } + } + + builder.Append(html); + } + } + + output.Write(builder.ToString()); + + foreach (string key in pageScripts.Keys) + { + output.Write(pageScripts[key]); + } + } + } +} diff --git a/SiteServer.BackgroundPages/Controls/ChannelAuxiliaryControl.cs b/net452/SiteServer.BackgroundPages/Controls/ChannelAuxiliaryControl.cs similarity index 75% rename from SiteServer.BackgroundPages/Controls/ChannelAuxiliaryControl.cs rename to net452/SiteServer.BackgroundPages/Controls/ChannelAuxiliaryControl.cs index e2dd0cf40..5e121858f 100644 --- a/SiteServer.BackgroundPages/Controls/ChannelAuxiliaryControl.cs +++ b/net452/SiteServer.BackgroundPages/Controls/ChannelAuxiliaryControl.cs @@ -1,17 +1,17 @@ +using System.Collections.Generic; using System.Collections.Specialized; using System.Text; using System.Web.UI; -using SiteServer.Utils; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; using SiteServer.Plugin; namespace SiteServer.BackgroundPages.Controls { public class ChannelAuxiliaryControl : Control { - public IAttributes Attributes { get; set; } + public IDictionary Attributes { get; set; } public SiteInfo SiteInfo { get; set; } @@ -23,8 +23,8 @@ protected override void Render(HtmlTextWriter output) { if (Attributes == null) return; - var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(SiteInfo.Id, ChannelId); - var styleInfoList = TableStyleManager.GetTableStyleInfoList(DataProvider.ChannelDao.TableName, relatedIdentities); + var channelInfo = ChannelManager.GetChannelInfo(SiteInfo.Id, ChannelId); + var styleInfoList = TableStyleManager.GetChannelStyleInfoList(channelInfo); if (styleInfoList == null) return; @@ -32,12 +32,11 @@ protected override void Render(HtmlTextWriter output) var pageScripts = new NameValueCollection(); foreach (var styleInfo in styleInfoList) { - string extra; - var value = BackgroundInputTypeParser.Parse(SiteInfo, ChannelId, styleInfo, Attributes, pageScripts, out extra); + var value = BackgroundInputTypeParser.Parse(SiteInfo, ChannelId, styleInfo, Attributes, pageScripts, out var extra); if (string.IsNullOrEmpty(value) && string.IsNullOrEmpty(extra)) continue; - if (InputTypeUtils.Equals(styleInfo.InputType, InputType.TextEditor)) + if (styleInfo.Type == InputType.TextEditor) { builder.Append($@"
    diff --git a/SiteServer.BackgroundPages/Controls/ChannelTree.cs b/net452/SiteServer.BackgroundPages/Controls/ChannelTree.cs similarity index 79% rename from SiteServer.BackgroundPages/Controls/ChannelTree.cs rename to net452/SiteServer.BackgroundPages/Controls/ChannelTree.cs index b7fbcfb63..b56fe9e32 100644 --- a/SiteServer.BackgroundPages/Controls/ChannelTree.cs +++ b/net452/SiteServer.BackgroundPages/Controls/ChannelTree.cs @@ -2,10 +2,12 @@ using System.Text; using System.Web.UI; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.Plugin; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; using SiteServer.Utils; using SiteServer.Utils.Enumerations; @@ -17,7 +19,9 @@ protected override void Render(HtmlTextWriter writer) { var builder = new StringBuilder(); - var request = new AuthRequest(); +#pragma warning disable CS0612 // '“RequestImpl”已过时 + var request = new RequestImpl(Page.Request); +#pragma warning restore CS0612 // '“RequestImpl”已过时 var siteId = TranslateUtils.ToInt(Page.Request.QueryString["siteId"]); var contentModelPluginId = Page.Request.QueryString["contentModelPluginId"]; @@ -40,7 +44,7 @@ protected override void Render(HtmlTextWriter writer) foreach (var channelId in channelIdList) { var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - var enabled = request.AdminPermissions.IsOwningChannelId(channelInfo.Id); + var enabled = request.AdminPermissionsImpl.IsOwningChannelId(channelInfo.Id); if (!string.IsNullOrEmpty(contentModelPluginId) && !StringUtils.EqualsIgnoreCase(channelInfo.ContentModelPluginId, contentModelPluginId)) { @@ -48,11 +52,11 @@ protected override void Render(HtmlTextWriter writer) } if (!enabled) { - if (!request.AdminPermissions.IsDescendantOwningChannelId(channelInfo.SiteId, channelInfo.Id)) continue; + if (!request.AdminPermissionsImpl.IsDescendantOwningChannelId(channelInfo.SiteId, channelInfo.Id)) continue; if (!IsDesendantContentModelPluginIdExists(channelInfo, contentModelPluginId)) continue; } - builder.Append(ChannelLoading.GetChannelRowHtml(siteInfo, channelInfo, enabled, ELoadingType.ContentTree, additional, request.AdminPermissions)); + builder.Append(ChannelLoading.GetChannelRowHtml(siteInfo, channelInfo, enabled, ELoadingType.ContentTree, additional, request.AdminPermissionsImpl)); } } } diff --git a/SiteServer.BackgroundPages/Controls/Code.cs b/net452/SiteServer.BackgroundPages/Controls/Code.cs similarity index 97% rename from SiteServer.BackgroundPages/Controls/Code.cs rename to net452/SiteServer.BackgroundPages/Controls/Code.cs index d5808f972..01d89f22d 100644 --- a/SiteServer.BackgroundPages/Controls/Code.cs +++ b/net452/SiteServer.BackgroundPages/Controls/Code.cs @@ -1,4 +1,6 @@ using System.Web.UI; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; using SiteServer.Utils; namespace SiteServer.BackgroundPages.Controls diff --git a/SiteServer.BackgroundPages/Controls/DateTimeTextBox.cs b/net452/SiteServer.BackgroundPages/Controls/DateTimeTextBox.cs similarity index 98% rename from SiteServer.BackgroundPages/Controls/DateTimeTextBox.cs rename to net452/SiteServer.BackgroundPages/Controls/DateTimeTextBox.cs index 05ca6cf31..ae6a7a9d9 100644 --- a/SiteServer.BackgroundPages/Controls/DateTimeTextBox.cs +++ b/net452/SiteServer.BackgroundPages/Controls/DateTimeTextBox.cs @@ -1,6 +1,8 @@ using System; using System.Web.UI; using System.Web.UI.WebControls; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; using SiteServer.Utils; namespace SiteServer.BackgroundPages.Controls diff --git a/SiteServer.BackgroundPages/Controls/Flash.cs b/net452/SiteServer.BackgroundPages/Controls/Flash.cs similarity index 95% rename from SiteServer.BackgroundPages/Controls/Flash.cs rename to net452/SiteServer.BackgroundPages/Controls/Flash.cs index 8b2f1ff8b..3b59ca08d 100644 --- a/SiteServer.BackgroundPages/Controls/Flash.cs +++ b/net452/SiteServer.BackgroundPages/Controls/Flash.cs @@ -1,5 +1,6 @@ using System; using System.Web.UI; +using SiteServer.CMS.Fx; using SiteServer.Utils; namespace SiteServer.BackgroundPages.Controls @@ -15,7 +16,7 @@ public virtual String FlashUrl { if (state.StartsWith("~")) { - return PageUtils.ParseNavigationUrl(state); + return FxUtils.ParseNavigationUrl(state); } return ResolveUrl(state); } diff --git a/SiteServer.BackgroundPages/Controls/Help.cs b/net452/SiteServer.BackgroundPages/Controls/Help.cs similarity index 100% rename from SiteServer.BackgroundPages/Controls/Help.cs rename to net452/SiteServer.BackgroundPages/Controls/Help.cs diff --git a/net452/SiteServer.BackgroundPages/Controls/Message.cs b/net452/SiteServer.BackgroundPages/Controls/Message.cs new file mode 100644 index 000000000..aee183896 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Controls/Message.cs @@ -0,0 +1,43 @@ +using System.Web.UI; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Fx; +using SiteServer.Utils; + +namespace SiteServer.BackgroundPages.Controls +{ + public class Message : Control + { + private bool isShowImmidiatary = false; + public bool IsShowImmidiatary + { + get { return isShowImmidiatary; } + set { isShowImmidiatary = value; } + } + + private WebPageUtils.Message.EMessageType messageType = WebPageUtils.Message.EMessageType.None; + public WebPageUtils.Message.EMessageType MessageType + { + get { return messageType; } + set { messageType = value; } + } + + private string content = string.Empty; + public string Content + { + get { return content; } + set { content = value; } + } + + protected override void Render(HtmlTextWriter writer) + { + if (isShowImmidiatary) // 有直接显示的消息 + { + writer.Write(WebPageUtils.GetMessageHtml(messageType, content, this)); + } + else // 没有直接显示的消息则去cookies中检查是否有消息需要显示 + { + writer.Write(WebPageUtils.GetMessageHtml(this)); + } + } + } +} diff --git a/SiteServer.BackgroundPages/Controls/NoTagText.cs b/net452/SiteServer.BackgroundPages/Controls/NoTagText.cs similarity index 100% rename from SiteServer.BackgroundPages/Controls/NoTagText.cs rename to net452/SiteServer.BackgroundPages/Controls/NoTagText.cs diff --git a/net452/SiteServer.BackgroundPages/Controls/Pager.cs b/net452/SiteServer.BackgroundPages/Controls/Pager.cs new file mode 100644 index 000000000..c1eabf575 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Controls/Pager.cs @@ -0,0 +1,129 @@ +using System; +using System.Collections.Specialized; +using System.Text; +using System.Web.UI; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using System.Collections.Generic; +using SiteServer.CMS.Apis; +using Datory; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Controls +{ + public class PagerParam + { + public Repeater ControlToPaginate { get; set; } + public string TableName { get; set; } + public IList ReturnColumnNames { get; set; } + public string WhereSqlString { get; set; } + public string OrderSqlString { get; set; } + public int PageSize { get; set; } + public int TotalCount { get; set; } + public int Page { get; set; } + } + + public class Pager : Control + { + public const string QueryNamePage = "page"; + + public PagerParam Param { get; set; } + + public override void DataBind() + { + if (Param == null) return; + + Param.Page = Param.Page > 1 ? Param.Page : 1; + + base.DataBind(); + + if (Param.ControlToPaginate == null) return; + + var sqlString = DataProvider.DatabaseApi.GetSqlString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, Param.TableName, Param.ReturnColumnNames, Param.WhereSqlString, Param.OrderSqlString, (Param.Page - 1) * Param.PageSize, Param.PageSize); + var dataSource = DataProvider.DatabaseApi.GetDataReader(WebConfigUtils.ConnectionString, sqlString); + + Param.ControlToPaginate.DataSource = dataSource; + Param.ControlToPaginate.DataBind(); + } + + private string GetPageUrl(int page) + { + var queryString = new NameValueCollection(Page.Request.QueryString); + if (page > 1) + { + queryString[QueryNamePage] = page.ToString(); + } + else + { + queryString.Remove(QueryNamePage); + } + return PageUtils.AddQueryString(PageUtils.GetUrlWithoutQueryString(Page.Request.RawUrl), queryString); + } + + protected override void Render(HtmlTextWriter output) + { + if (Param == null || Param.PageSize <= 0) return; + + var pageCount = (int)Math.Ceiling((double)Param.TotalCount / Param.PageSize); + + if (pageCount <= 1) return; + + var isFirst = Param.Page - 1 > 0; + var isPrevious = Param.Page - 1 > 0; + var isNext = Param.Page + 1 <= pageCount; + var isLast = Param.Page + 1 <= pageCount; + + var dropdownBuilder = new StringBuilder(); + for (var i = 1; i <= pageCount; i++) + { + dropdownBuilder.Append($@"第 {i} 页"); + } + + var top = -(pageCount * 28 + 10); + if (pageCount > 10) + { + top = 0; + } + + output.Write($@" +
    + + + +
    + {dropdownBuilder} +
    +
    +
    + +"); + } + } +} diff --git a/SiteServer.BackgroundPages/Controls/Script.cs b/net452/SiteServer.BackgroundPages/Controls/Script.cs similarity index 82% rename from SiteServer.BackgroundPages/Controls/Script.cs rename to net452/SiteServer.BackgroundPages/Controls/Script.cs index 18e3c8909..cbe1a531d 100644 --- a/SiteServer.BackgroundPages/Controls/Script.cs +++ b/net452/SiteServer.BackgroundPages/Controls/Script.cs @@ -1,4 +1,5 @@ using System.Web.UI; +using SiteServer.CMS.Fx; using SiteServer.Utils; namespace SiteServer.BackgroundPages.Controls @@ -22,7 +23,7 @@ protected override void Render(HtmlTextWriter writer) { if (!string.IsNullOrEmpty(Src)) { - writer.Write($@""); + writer.Write($@""); } } diff --git a/SiteServer.BackgroundPages/Controls/SqlPager.cs b/net452/SiteServer.BackgroundPages/Controls/SqlPager.cs similarity index 84% rename from SiteServer.BackgroundPages/Controls/SqlPager.cs rename to net452/SiteServer.BackgroundPages/Controls/SqlPager.cs index a09997fb2..2bed0180e 100644 --- a/SiteServer.BackgroundPages/Controls/SqlPager.cs +++ b/net452/SiteServer.BackgroundPages/Controls/SqlPager.cs @@ -1,13 +1,21 @@ using System; -using System.Collections; using System.Collections.Specialized; using System.ComponentModel; using System.Data; +using System.Data.SqlClient; using System.Web.UI; using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Database.Core; +using Datory; +using MySql.Data.MySqlClient; +using Npgsql; +using Oracle.ManagedDataAccess.Client; +using SiteServer.BackgroundPages.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Controls { @@ -16,9 +24,131 @@ namespace SiteServer.BackgroundPages.Controls [ToolboxData("<{0}:SqlPager runat=\"server\" />")] public class SqlPager : Table, INamingContainer { + public static IDbCommand GetIDbCommand() + { + IDbCommand command = null; + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + command = new MySqlCommand(); + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + command = new SqlCommand(); + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + command = new NpgsqlCommand(); + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + command = new OracleCommand(); + } + + return command; + } + + public static IDbDataAdapter GetIDbDataAdapter() + { + IDbDataAdapter adapter = null; + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + adapter = new MySqlDataAdapter(); + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + adapter = new SqlDataAdapter(); + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + adapter = new NpgsqlDataAdapter(); + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + adapter = new OracleDataAdapter(); + } + + return adapter; + } + + public static void FillDataAdapterWithDataTable(IDbDataAdapter adapter, DataTable table) + { + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + ((MySqlDataAdapter)adapter).Fill(table); + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + ((SqlDataAdapter)adapter).Fill(table); + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + ((NpgsqlDataAdapter)adapter).Fill(table); + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + ((OracleDataAdapter)adapter).Fill(table); + } + } + + public static string GetPageSqlString(string sqlString, string orderString, int itemsPerPage, int currentPageIndex, int pageCount, int recordsInLastPage) + { + var retVal = string.Empty; + + var recsToRetrieve = itemsPerPage; + if (currentPageIndex == pageCount - 1) + { + recsToRetrieve = recordsInLastPage; + } + + orderString = orderString.ToUpper(); + var orderStringReverse = orderString.Replace(" DESC", " DESC2"); + orderStringReverse = orderStringReverse.Replace(" ASC", " DESC"); + orderStringReverse = orderStringReverse.Replace(" DESC2", " ASC"); + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + retVal = $@" +SELECT * FROM ( + SELECT * FROM ( + SELECT * FROM ({sqlString}) AS t0 {orderString} LIMIT {itemsPerPage * (currentPageIndex + 1)} + ) AS t1 {orderStringReverse} LIMIT {recsToRetrieve} +) AS t2 {orderString}"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + retVal = $@" +SELECT * FROM ( + SELECT TOP {recsToRetrieve} * FROM ( + SELECT TOP {itemsPerPage * (currentPageIndex + 1)} * FROM ({sqlString}) AS t0 {orderString} + ) AS t1 {orderStringReverse} +) AS t2 {orderString}"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + retVal = $@" +SELECT * FROM ( + SELECT * FROM ( + SELECT * FROM ({sqlString}) AS t0 {orderString} LIMIT {itemsPerPage * (currentPageIndex + 1)} + ) AS t1 {orderStringReverse} LIMIT {recsToRetrieve} +) AS t2 {orderString}"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + retVal = $@" +SELECT * FROM ( + SELECT * FROM ( + SELECT * FROM ({sqlString}) {orderString} FETCH FIRST {itemsPerPage * (currentPageIndex + 1)} ROWS ONLY + ) {orderStringReverse} FETCH FIRST {recsToRetrieve} ROWS ONLY +) {orderString}"; + } + + return retVal; + } + private PagedDataSource _dataSource; - private string CacheKeyName => Page.Request.FilePath + "_" + UniqueID + "_Data"; - public const string ParmPage = "page"; + private const string ParmPage = "page"; private bool _isSetTotalCount; // private string GetQueryPageCommandText(int recsToRetrieve) @@ -76,39 +206,14 @@ public SqlPager() _dataSource = null; ControlToPaginate = null; - PagingMode = PagingMode.NonCached; PagerStyle = PagerStyle.NextPrev; CurrentPageIndex = 0; SelectCommand = ""; ItemsPerPage = 10; TotalPages = -1; - CacheDuration = 60; SortMode = SortMode.DESC; } - /// - /// Removes any data cached for paging - /// - public void ClearCache() - { - if (PagingMode == PagingMode.Cached) - Page.Cache.Remove(CacheKeyName); - } - - [Description("Gets and sets for how many seconds the data should stay in the cache")] - public int CacheDuration - { - get { return Convert.ToInt32(ViewState["CacheDuration"]); } - set { ViewState["CacheDuration"] = value; } - } - - [Description("Indicates whether the data are retrieved page by page or can be cached")] - public PagingMode PagingMode - { - get { return (PagingMode)ViewState["PagingMode"]; } - set { ViewState["PagingMode"] = value; } - } - [Description("Indicates the style of the pager's navigation bar")] public PagerStyle PagerStyle { @@ -298,14 +403,7 @@ public override void DataBind() return; // Fetch data - if (PagingMode == PagingMode.Cached) - { - FetchAllData(); - } - else - { - FetchPageData(); - } + FetchPageData(); // Bind data to the buddy control if (ControlToPaginate is BaseDataList) @@ -398,8 +496,6 @@ private void BuildControlHierarchy() } } - public ArrayList RemoveQueryString = new ArrayList(); - private string GetNavigationUrl(int page) { var queryString = new NameValueCollection(Page.Request.QueryString); @@ -411,13 +507,6 @@ private string GetNavigationUrl(int page) { queryString.Remove(ParmPage); } - if (RemoveQueryString.Count > 0) - { - foreach (string name in RemoveQueryString) - { - queryString.Remove(name); - } - } return PageUtils.AddQueryString(PageUtils.GetUrlWithoutQueryString(Page.Request.RawUrl), queryString); } @@ -654,49 +743,6 @@ private void ValidatePageIndex() } } - /// - /// Runs the query for all data to be paged and caches the resulting data - /// - private void FetchAllData() - { - // Looks for data in the ASP.NET Cache - var data = (DataTable)Page.Cache[CacheKeyName]; - if (data == null) - { - // Fix SelectCommand with order-by info - AdjustSelectCommand(true); - - // If data expired or has never been fetched, go to the database - //SqlDataAdapter adapter = new SqlDataAdapter(SelectCommand, ConnectionString); - var adapter = SqlUtils.GetIDbDataAdapter(SelectCommand, WebConfigUtils.ConnectionString); - data = new DataTable(); - //adapter.Fill(data); - SqlUtils.FillDataAdapterWithDataTable(adapter, data); - Page.Cache.Insert(CacheKeyName, data, null, - DateTime.Now.AddSeconds(CacheDuration), - System.Web.Caching.Cache.NoSlidingExpiration); - } - - // Configures the paged data source component - if (_dataSource == null) - _dataSource = new PagedDataSource(); - _dataSource.DataSource = data.DefaultView; // must be IEnumerable! - _dataSource.AllowPaging = true; - _dataSource.PageSize = ItemsPerPage; - TotalPages = _dataSource.PageCount; - - // Ensures the page index is valid - ValidatePageIndex(); - if (CurrentPageIndex == -1) - { - _dataSource = null; - return; - } - - // Selects the page to view - _dataSource.CurrentPageIndex = CurrentPageIndex; - } - /// /// Runs the query to get only the data that fit into the current page /// @@ -721,11 +767,11 @@ private void FetchPageData() return; } //SqlDataAdapter adapter = new SqlDataAdapter(cmd); - var adapter = SqlUtils.GetIDbDataAdapter(); + var adapter = GetIDbDataAdapter(); adapter.SelectCommand = cmd; var data = new DataTable(); //adapter.Fill(data); - SqlUtils.FillDataAdapterWithDataTable(adapter, data); + FillDataAdapterWithDataTable(adapter, data); // Configures the paged data source component if (_dataSource == null) @@ -757,7 +803,7 @@ private void AdjustSelectCommand(bool addCustomSortInfo) private int GetQueryVirtualCount() { - var recCount = DataProvider.DatabaseDao.GetPageTotalCount(SelectCommand); + var recCount = DataProvider.DatabaseApi.GetPageTotalCount(SelectCommand); // SqlConnection conn = new SqlConnection(ConnectionString); // SqlCommand cmd = new SqlCommand(cmdText, conn); //IDbConnection conn = SqlUtils.GetIDbConnection(DataProvider.ADOType, ConnectionString); @@ -816,10 +862,10 @@ private IDbCommand PrepareCommand(VirtualRecordCount countInfo) { orderString = $"ORDER BY {SortField} {SortMode}"; } - var cmdText = SqlUtils.GetPageSqlString(SelectCommand, orderString, ItemsPerPage, CurrentPageIndex, countInfo.PageCount, countInfo.RecordsInLastPage); + var cmdText = GetPageSqlString(SelectCommand, orderString, ItemsPerPage, CurrentPageIndex, countInfo.PageCount, countInfo.RecordsInLastPage); - var conn = SqlUtils.GetIDbConnection(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString); - var cmd = SqlUtils.GetIDbCommand(); + var conn = DatoryUtils.GetConnection(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString); + var cmd = GetIDbCommand(); cmd.Connection = conn; cmd.CommandText = cmdText; return cmd; @@ -832,7 +878,7 @@ private void PageList_Click(object sender, EventArgs e) { var pageList = (DropDownList)sender; var pageIndex = Convert.ToInt32(pageList.SelectedValue); - PageUtils.Redirect(GetNavigationUrl(pageIndex + 1)); + WebPageUtils.Redirect(GetNavigationUrl(pageIndex + 1)); } } } diff --git a/SiteServer.BackgroundPages/Controls/Style.cs b/net452/SiteServer.BackgroundPages/Controls/Style.cs similarity index 82% rename from SiteServer.BackgroundPages/Controls/Style.cs rename to net452/SiteServer.BackgroundPages/Controls/Style.cs index 5d5259364..1996102fb 100644 --- a/SiteServer.BackgroundPages/Controls/Style.cs +++ b/net452/SiteServer.BackgroundPages/Controls/Style.cs @@ -1,4 +1,5 @@ using System.Web.UI; +using SiteServer.CMS.Fx; using SiteServer.Utils; namespace SiteServer.BackgroundPages.Controls @@ -22,7 +23,7 @@ protected override void Render(HtmlTextWriter writer) { if (!string.IsNullOrEmpty(Href)) { - writer.Write($@""); + writer.Write($@""); } } } diff --git a/SiteServer.BackgroundPages/Controls/TextEditorBase.cs b/net452/SiteServer.BackgroundPages/Controls/TextEditorBase.cs similarity index 100% rename from SiteServer.BackgroundPages/Controls/TextEditorBase.cs rename to net452/SiteServer.BackgroundPages/Controls/TextEditorBase.cs diff --git a/SiteServer.BackgroundPages/Controls/TextEditorControl.cs b/net452/SiteServer.BackgroundPages/Controls/TextEditorControl.cs similarity index 78% rename from SiteServer.BackgroundPages/Controls/TextEditorControl.cs rename to net452/SiteServer.BackgroundPages/Controls/TextEditorControl.cs index 7df62fb8f..38770773c 100644 --- a/SiteServer.BackgroundPages/Controls/TextEditorControl.cs +++ b/net452/SiteServer.BackgroundPages/Controls/TextEditorControl.cs @@ -1,8 +1,10 @@ -using System.Collections.Specialized; +using System; +using System.Collections.Generic; +using System.Collections.Specialized; using System.Text; using System.Web.UI; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Models; namespace SiteServer.BackgroundPages.Controls { @@ -25,8 +27,10 @@ protected override void Render(HtmlTextWriter output) var pageScripts = new NameValueCollection(); - var attributes = new ExtendedAttributes(); - attributes.Set(_attributeName, _value); + var attributes = new Dictionary(StringComparer.OrdinalIgnoreCase) + { + [_attributeName] = _value + }; var extraBuilder = new StringBuilder(); var inputHtml = BackgroundInputTypeParser.ParseTextEditor(attributes, _attributeName, _siteInfo, pageScripts, extraBuilder); diff --git a/SiteServer.BackgroundPages/Controls/UEditor.cs b/net452/SiteServer.BackgroundPages/Controls/UEditor.cs similarity index 87% rename from SiteServer.BackgroundPages/Controls/UEditor.cs rename to net452/SiteServer.BackgroundPages/Controls/UEditor.cs index 0ad3584f6..fb381ee68 100644 --- a/SiteServer.BackgroundPages/Controls/UEditor.cs +++ b/net452/SiteServer.BackgroundPages/Controls/UEditor.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Specialized; using System.Text; -using System.Web; using System.Web.UI; -using SiteServer.CMS.Api; -using SiteServer.CMS.Api.Sys.Editors; using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes; +using SiteServer.CMS.Core.RestRoutes.Sys.Editors; +using SiteServer.CMS.Fx; using SiteServer.Utils; namespace SiteServer.BackgroundPages.Controls @@ -15,8 +15,7 @@ public class UEditor : TextEditorBase, IPostBackDataHandler protected override void Render(HtmlTextWriter writer) { var controllerUrl = ApiRouteUEditor.GetUrl(ApiManager.InnerApiUrl, 0); - var editorUrl = SiteFilesAssets.GetUrl(ApiManager.InnerApiUrl, "ueditor"); - + var editorUrl = SiteServerAssets.GetUrl("ueditor"); if (string.IsNullOrEmpty(Height) || Height == "0") { Height = "280"; @@ -31,10 +30,10 @@ protected override void Render(HtmlTextWriter writer) $@""); builder.Append($@" - + "); diff --git a/SiteServer.BackgroundPages/Controls/Weather.cs b/net452/SiteServer.BackgroundPages/Controls/Weather.cs similarity index 99% rename from SiteServer.BackgroundPages/Controls/Weather.cs rename to net452/SiteServer.BackgroundPages/Controls/Weather.cs index 7cdbdc2fc..a4f65423c 100644 --- a/SiteServer.BackgroundPages/Controls/Weather.cs +++ b/net452/SiteServer.BackgroundPages/Controls/Weather.cs @@ -1,5 +1,6 @@ using System; using System.Web.UI; +using SiteServer.CMS.Fx; using SiteServer.Utils; using SiteServer.Utils.Enumerations; diff --git a/SiteServer.BackgroundPages/Core/AjaxManager.cs b/net452/SiteServer.BackgroundPages/Core/AjaxManager.cs similarity index 100% rename from SiteServer.BackgroundPages/Core/AjaxManager.cs rename to net452/SiteServer.BackgroundPages/Core/AjaxManager.cs diff --git a/SiteServer.Utils/AlertUtils.cs b/net452/SiteServer.BackgroundPages/Core/AlertUtils.cs similarity index 93% rename from SiteServer.Utils/AlertUtils.cs rename to net452/SiteServer.BackgroundPages/Core/AlertUtils.cs index 2b8fe8774..c4e713d8b 100644 --- a/SiteServer.Utils/AlertUtils.cs +++ b/net452/SiteServer.BackgroundPages/Core/AlertUtils.cs @@ -1,11 +1,9 @@ -namespace SiteServer.Utils +using SiteServer.Utils; + +namespace SiteServer.BackgroundPages.Core { - public class AlertUtils + public static class AlertUtils { - private AlertUtils() - { - } - public static string Error(string title, string text) { var script = $@" @@ -21,7 +19,7 @@ public static string Error(string title, string text) public static string Success(string title, string text) { - return Success(title, text, "关 闭", null); + return Success(title, text, "关 闭", string.Empty); } public static string Success(string title, string text, string button, string scripts) diff --git a/SiteServer.BackgroundPages/Core/AreaTreeItem.cs b/net452/SiteServer.BackgroundPages/Core/AreaTreeItem.cs similarity index 99% rename from SiteServer.BackgroundPages/Core/AreaTreeItem.cs rename to net452/SiteServer.BackgroundPages/Core/AreaTreeItem.cs index 5dc24feb8..6e4934e49 100644 --- a/SiteServer.BackgroundPages/Core/AreaTreeItem.cs +++ b/net452/SiteServer.BackgroundPages/Core/AreaTreeItem.cs @@ -3,7 +3,9 @@ using System.Text; using SiteServer.Utils; using SiteServer.BackgroundPages.Ajax; -using SiteServer.CMS.Model; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Core { diff --git a/SiteServer.BackgroundPages/Core/BackgroundInputTypeParser.cs b/net452/SiteServer.BackgroundPages/Core/BackgroundInputTypeParser.cs similarity index 75% rename from SiteServer.BackgroundPages/Core/BackgroundInputTypeParser.cs rename to net452/SiteServer.BackgroundPages/Core/BackgroundInputTypeParser.cs index 6c64fde88..2768521aa 100644 --- a/SiteServer.BackgroundPages/Core/BackgroundInputTypeParser.cs +++ b/net452/SiteServer.BackgroundPages/Core/BackgroundInputTypeParser.cs @@ -6,27 +6,26 @@ using SiteServer.Utils; using SiteServer.BackgroundPages.Ajax; using SiteServer.CMS.Core; -using SiteServer.CMS.Model; using SiteServer.BackgroundPages.Cms; -using SiteServer.CMS.Api; -using SiteServer.CMS.Api.Sys.Editors; -using SiteServer.CMS.Api.Sys.Stl; -using SiteServer.CMS.Model.Enumerations; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Core.RestRoutes; +using SiteServer.CMS.Core.RestRoutes.Sys.Editors; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.Plugin; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Core { - public class BackgroundInputTypeParser + public static class BackgroundInputTypeParser { - private BackgroundInputTypeParser() - { - } - public const string Current = "{Current}"; public const string Value = "{Value}"; - public static string Parse(SiteInfo siteInfo, int channelId, TableStyleInfo styleInfo, IAttributes attributes, NameValueCollection pageScripts, out string extraHtml) + public static string Parse(SiteInfo siteInfo, int channelId, TableStyleInfo styleInfo, IDictionary attributes, NameValueCollection pageScripts, out string extraHtml) { var retval = string.Empty; var extraBuilder = new StringBuilder(); @@ -35,7 +34,7 @@ public static string Parse(SiteInfo siteInfo, int channelId, TableStyleInfo styl extraBuilder.Append($@"{styleInfo.HelpText}"); } - var inputType = styleInfo.InputType; + var inputType = styleInfo.Type; if (inputType == InputType.Text) { @@ -103,23 +102,26 @@ public static string Parse(SiteInfo siteInfo, int channelId, TableStyleInfo styl return retval; } - public static string ParseText(IAttributes attributes, SiteInfo siteInfo, int channelId, TableStyleInfo styleInfo, StringBuilder extraBuilder) + public static string ParseText(IDictionary attributes, SiteInfo siteInfo, int channelId, TableStyleInfo styleInfo, StringBuilder extraBuilder) { - var validateAttributes = InputParserUtils.GetValidateAttributes(styleInfo.Additional.IsValidate, styleInfo.DisplayName, styleInfo.Additional.IsRequired, styleInfo.Additional.MinNum, styleInfo.Additional.MaxNum, styleInfo.Additional.ValidateType, styleInfo.Additional.RegExp, styleInfo.Additional.ErrorMessage); + var validateAttributes = InputParserUtils.GetValidateAttributes(styleInfo.Validate, styleInfo.DisplayName, styleInfo.Required, styleInfo.MinNum, styleInfo.MaxNum, styleInfo.ValidateType, styleInfo.RegExp, styleInfo.ErrorMessage); - if (styleInfo.Additional.IsValidate) + if (styleInfo.Validate) { extraBuilder.Append( $@"*"); } - if (styleInfo.Additional.IsFormatString) + if (styleInfo.FormatString) { var formatStrong = false; var formatEm = false; var formatU = false; var formatColor = string.Empty; - var formatValues = attributes.GetString(ContentAttribute.GetFormatStringAttributeName(styleInfo.AttributeName)); + + var formatValues = TranslateUtils.Get(attributes, + ContentAttribute.GetFormatStringAttributeName(styleInfo.AttributeName), string.Empty); + if (!string.IsNullOrEmpty(formatValues)) { ContentUtility.SetTitleFormatControls(formatValues, out formatStrong, out formatEm, out formatU, out formatColor); @@ -238,45 +240,47 @@ function getTitles(title){ extraBuilder.Replace("[url]", AjaxCmsService.GetTitlesUrl(siteInfo.Id, channelId)); } - var value = StringUtils.HtmlDecode(attributes.GetString(styleInfo.AttributeName)); + var value = StringUtils.HtmlDecode(TranslateUtils.Get(attributes, styleInfo.AttributeName, string.Empty)); return $@""; } - public static string ParseTextArea(IAttributes attributes, TableStyleInfo styleInfo, StringBuilder extraBuilder) + public static string ParseTextArea(IDictionary attributes, TableStyleInfo styleInfo, StringBuilder extraBuilder) { - if (styleInfo.Additional.IsValidate) + if (styleInfo.Validate) { extraBuilder.Append( $@"*"); } - var validateAttributes = InputParserUtils.GetValidateAttributes(styleInfo.Additional.IsValidate, styleInfo.DisplayName, styleInfo.Additional.IsRequired, styleInfo.Additional.MinNum, styleInfo.Additional.MaxNum, styleInfo.Additional.ValidateType, styleInfo.Additional.RegExp, styleInfo.Additional.ErrorMessage); + var validateAttributes = InputParserUtils.GetValidateAttributes(styleInfo.Validate, styleInfo.DisplayName, styleInfo.Required, styleInfo.MinNum, styleInfo.MaxNum, styleInfo.ValidateType, styleInfo.RegExp, styleInfo.ErrorMessage); - var height = styleInfo.Additional.Height; + var height = styleInfo.Height; if (height == 0) { height = 80; } - string style = $@"style=""height:{height}px;"""; + var style = $@"style=""height:{height}px;"""; - var value = StringUtils.HtmlDecode(attributes.GetString(styleInfo.AttributeName)); + var value = StringUtils.HtmlDecode(TranslateUtils.Get(attributes, styleInfo.AttributeName, string.Empty)); return $@""; } - public static string ParseTextEditor(IAttributes attributes, string attributeName, SiteInfo siteInfo, NameValueCollection pageScripts, StringBuilder extraBuilder) + public static string ParseTextEditor(IDictionary attributes, string attributeName, SiteInfo siteInfo, NameValueCollection pageScripts, StringBuilder extraBuilder) { - var value = attributes.GetString(attributeName); - - value = ContentUtility.TextEditorContentDecode(siteInfo, value, true); - value = ETextEditorTypeUtils.TranslateToHtml(value); - value = StringUtils.HtmlEncode(value); + var value = TranslateUtils.Get(attributes, attributeName, string.Empty); + if (!string.IsNullOrWhiteSpace(value)) + { + value = ContentUtility.TextEditorContentDecode(siteInfo, value, true); + value = UEditorUtils.TranslateToHtml(value); + value = StringUtils.HtmlEncode(value); + } var controllerUrl = ApiRouteUEditor.GetUrl(ApiManager.InnerApiUrl, siteInfo.Id); - var editorUrl = SiteFilesAssets.GetUrl(ApiManager.InnerApiUrl, "ueditor"); + var editorUrl = SiteServerAssets.GetUrl("ueditor"); if (pageScripts["uEditor"] == null) { @@ -288,7 +292,7 @@ public static string ParseTextEditor(IAttributes attributes, string attributeNam extraBuilder.Append($@" "); @@ -296,20 +300,20 @@ public static string ParseTextEditor(IAttributes attributes, string attributeNam return $@""; } - private static string ParseSelectOne(IAttributes attributes, TableStyleInfo styleInfo, StringBuilder extraBuilder) + private static string ParseSelectOne(IDictionary attributes, TableStyleInfo styleInfo, StringBuilder extraBuilder) { - if (styleInfo.Additional.IsValidate) + if (styleInfo.Validate) { extraBuilder.Append( $@"*"); } var builder = new StringBuilder(); - var styleItems = styleInfo.StyleItems ?? DataProvider.TableStyleItemDao.GetStyleItemInfoList(styleInfo.Id); + var styleItems = styleInfo.StyleItems ?? new List(); - var selectedValue = attributes.GetString(styleInfo.AttributeName); + var selectedValue = TranslateUtils.Get(attributes, styleInfo.AttributeName, string.Empty); - var validateAttributes = InputParserUtils.GetValidateAttributes(styleInfo.Additional.IsValidate, styleInfo.DisplayName, styleInfo.Additional.IsRequired, styleInfo.Additional.MinNum, styleInfo.Additional.MaxNum, styleInfo.Additional.ValidateType, styleInfo.Additional.RegExp, styleInfo.Additional.ErrorMessage); + var validateAttributes = InputParserUtils.GetValidateAttributes(styleInfo.Validate, styleInfo.DisplayName, styleInfo.Required, styleInfo.MinNum, styleInfo.MaxNum, styleInfo.ValidateType, styleInfo.RegExp, styleInfo.ErrorMessage); builder.Append($@""); foreach (var styleItem in styleItems) @@ -355,18 +359,18 @@ private static string ParseSelectMultiple(IAttributes attributes, TableStyleInfo return builder.ToString(); } - private static string ParseSelectCascading(IAttributes attributes, SiteInfo siteInfo, TableStyleInfo styleInfo, StringBuilder extraBuilder) + private static string ParseSelectCascading(IDictionary attributes, SiteInfo siteInfo, TableStyleInfo styleInfo, StringBuilder extraBuilder) { var attributeName = styleInfo.AttributeName; - var fieldInfo = DataProvider.RelatedFieldDao.GetRelatedFieldInfo(styleInfo.Additional.RelatedFieldId); + var fieldInfo = DataProvider.RelatedField.Get(styleInfo.RelatedFieldId); if (fieldInfo == null) return string.Empty; - var list = DataProvider.RelatedFieldItemDao.GetRelatedFieldItemInfoList(styleInfo.Additional.RelatedFieldId, 0); + var list = DataProvider.RelatedFieldItem.GetRelatedFieldItemInfoList(styleInfo.RelatedFieldId, 0); var prefixes = TranslateUtils.StringCollectionToStringCollection(fieldInfo.Prefixes); var suffixes = TranslateUtils.StringCollectionToStringCollection(fieldInfo.Suffixes); - var style = ERelatedFieldStyleUtils.GetEnumType(styleInfo.Additional.RelatedFieldStyle); + var style = ERelatedFieldStyleUtils.GetEnumType(styleInfo.RelatedFieldStyle); var builder = new StringBuilder(); builder.Append($@" @@ -375,7 +379,7 @@ private static string ParseSelectCascading(IAttributes attributes, SiteInfo site "; } - private static string ParseDateTime(IAttributes attributes, NameValueCollection pageScripts, TableStyleInfo styleInfo, StringBuilder extraBuilder) + private static string ParseDateTime(IDictionary attributes, NameValueCollection pageScripts, TableStyleInfo styleInfo, StringBuilder extraBuilder) { - if (styleInfo.Additional.IsValidate) + if (styleInfo.Validate) { extraBuilder.Append( $@"*"); } - var selectedValue = attributes.GetString(styleInfo.AttributeName); + var selectedValue = TranslateUtils.Get(attributes, styleInfo.AttributeName, string.Empty); var dateTime = selectedValue == Current ? DateTime.Now : TranslateUtils.ToDateTime(selectedValue); if (pageScripts != null) @@ -626,7 +630,7 @@ private static string ParseDateTime(IAttributes attributes, NameValueCollection return $@""; } - private static string ParseImage(IAttributes attributes, SiteInfo siteInfo, int channelId, TableStyleInfo styleInfo, StringBuilder extraBuilder) + private static string ParseImage(IDictionary attributes, SiteInfo siteInfo, int channelId, TableStyleInfo styleInfo, StringBuilder extraBuilder) { var btnAddHtml = string.Empty; @@ -699,7 +703,7 @@ private static string ParseImage(IAttributes attributes, SiteInfo siteInfo, int }} "); - var extendValues = attributes.GetString(extendAttributeName); + var extendValues = TranslateUtils.Get(attributes, extendAttributeName, string.Empty); if (!string.IsNullOrEmpty(extendValues)) { foreach (var extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) @@ -713,10 +717,12 @@ private static string ParseImage(IAttributes attributes, SiteInfo siteInfo, int extraBuilder.Append(""); - return $@""; + var value = TranslateUtils.Get(attributes, attributeName, string.Empty); + + return $@""; } - private static string ParseVideo(IAttributes attributes, SiteInfo siteInfo, int channelId, TableStyleInfo styleInfo, StringBuilder extraBulder) + private static string ParseVideo(IDictionary attributes, SiteInfo siteInfo, int channelId, TableStyleInfo styleInfo, StringBuilder extraBulder) { var attributeName = styleInfo.AttributeName; @@ -780,7 +786,7 @@ private static string ParseVideo(IAttributes attributes, SiteInfo siteInfo, int }} "); - var extendValues = attributes.GetString(extendAttributeName); + var extendValues = TranslateUtils.Get(attributes, extendAttributeName, string.Empty); if (!string.IsNullOrEmpty(extendValues)) { foreach (var extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) @@ -794,13 +800,16 @@ private static string ParseVideo(IAttributes attributes, SiteInfo siteInfo, int extraBulder.Append(""); - return $@""; + var value = TranslateUtils.Get(attributes, attributeName, string.Empty); + + return $@""; } - private static string ParseFile(IAttributes attributes, SiteInfo siteInfo, int channelId, TableStyleInfo styleInfo, StringBuilder extraBuilder) + private static string ParseFile(IDictionary attributes, SiteInfo siteInfo, int channelId, TableStyleInfo styleInfo, StringBuilder extraBuilder) { var attributeName = styleInfo.AttributeName; - var value = attributes.GetString(attributeName); + var value = TranslateUtils.Get(attributes, attributeName, string.Empty); + var relatedPath = string.Empty; if (!string.IsNullOrEmpty(value)) { @@ -874,7 +883,8 @@ private static string ParseFile(IAttributes attributes, SiteInfo siteInfo, int c }} "); - var extendValues = attributes.GetString(extendAttributeName); + var extendValues = TranslateUtils.Get(attributes, extendAttributeName, string.Empty); + if (!string.IsNullOrEmpty(extendValues)) { foreach (var extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) @@ -892,51 +902,52 @@ private static string ParseFile(IAttributes attributes, SiteInfo siteInfo, int c $@""; } - private static string ParseCustomize(IAttributes attributes, TableStyleInfo styleInfo, StringBuilder extraBuilder) + private static string ParseCustomize(IDictionary attributes, TableStyleInfo styleInfo, StringBuilder extraBuilder) { - if (styleInfo.Additional.IsValidate) + if (styleInfo.Validate) { extraBuilder.Append( $@"*"); } - var value = attributes.GetString(styleInfo.AttributeName); - var left = styleInfo.Additional.CustomizeLeft.Replace(Value, value); - var right = styleInfo.Additional.CustomizeRight.Replace(Value, value); + var value = TranslateUtils.Get(attributes, styleInfo.AttributeName, string.Empty); + var left = styleInfo.CustomizeLeft.Replace(Value, value); + var right = styleInfo.CustomizeRight.Replace(Value, value); extraBuilder.Append(right); return left; } - public static void SaveAttributes(IAttributes attributes, SiteInfo siteInfo, List styleInfoList, NameValueCollection formCollection, List dontAddAttributesLowercase) + public static Dictionary SaveAttributes(SiteInfo siteInfo, List styleInfoList, NameValueCollection formCollection, List dontAddAttributes) { - if (dontAddAttributesLowercase == null) + var dict = new Dictionary(); + + if (dontAddAttributes == null) { - dontAddAttributesLowercase = new List(); + dontAddAttributes = new List(); } foreach (var styleInfo in styleInfoList) { - if (dontAddAttributesLowercase.Contains(styleInfo.AttributeName.ToLower())) continue; + if (StringUtils.ContainsIgnoreCase(dontAddAttributes, styleInfo.AttributeName)) continue; //var theValue = GetValueByForm(styleInfo, siteInfo, formCollection); var theValue = formCollection[styleInfo.AttributeName] ?? string.Empty; - var inputType = styleInfo.InputType; + var inputType = styleInfo.Type; if (inputType == InputType.TextEditor) { theValue = ContentUtility.TextEditorContentEncode(siteInfo, theValue); - theValue = ETextEditorTypeUtils.TranslateToStlElement(theValue); + theValue = UEditorUtils.TranslateToStlElement(theValue); } if (inputType != InputType.TextEditor && inputType != InputType.Image && inputType != InputType.File && inputType != InputType.Video && styleInfo.AttributeName != ContentAttribute.LinkUrl) { - theValue = PageUtils.FilterSqlAndXss(theValue); + theValue = AttackUtils.FilterXss(theValue); } - attributes.Set(styleInfo.AttributeName, theValue); - //TranslateUtils.SetOrRemoveAttributeLowerCase(attributes, styleInfo.AttributeName, theValue); + dict[styleInfo.AttributeName] = theValue; - if (styleInfo.Additional.IsFormatString) + if (styleInfo.FormatString) { var formatString = TranslateUtils.ToBool(formCollection[styleInfo.AttributeName + "_formatStrong"]); var formatEm = TranslateUtils.ToBool(formCollection[styleInfo.AttributeName + "_formatEM"]); @@ -944,17 +955,66 @@ public static void SaveAttributes(IAttributes attributes, SiteInfo siteInfo, Lis var formatColor = formCollection[styleInfo.AttributeName + "_formatColor"]; var theFormatString = ContentUtility.GetTitleFormatString(formatString, formatEm, formatU, formatColor); - attributes.Set(ContentAttribute.GetFormatStringAttributeName(styleInfo.AttributeName), theFormatString); - //TranslateUtils.SetOrRemoveAttributeLowerCase(attributes, ContentAttribute.GetFormatStringAttributeName(styleInfo.AttributeName), theFormatString); + dict[ContentAttribute.GetFormatStringAttributeName(styleInfo.AttributeName)] = theFormatString; } if (inputType == InputType.Image || inputType == InputType.File || inputType == InputType.Video) { var attributeName = ContentAttribute.GetExtendAttributeName(styleInfo.AttributeName); - attributes.Set(attributeName, formCollection[attributeName]); - //TranslateUtils.SetOrRemoveAttributeLowerCase(attributes, attributeName, formCollection[attributeName]); + dict[attributeName] = formCollection[attributeName]; } } + + return dict; } + + //public static void SaveAttributes(IDictionary attributes, SiteInfo siteInfo, List styleInfoList, NameValueCollection formCollection, List dontAddAttributes) + //{ + // if (dontAddAttributes == null) + // { + // dontAddAttributes = new List(); + // } + + // foreach (var styleInfo in styleInfoList) + // { + // if (StringUtils.ContainsIgnoreCase(dontAddAttributes, styleInfo.AttributeName)) continue; + // //var theValue = GetValueByForm(styleInfo, siteInfo, formCollection); + + // var theValue = formCollection[styleInfo.AttributeName] ?? string.Empty; + // var inputType = styleInfo.InputType; + // if (inputType == InputType.TextEditor) + // { + // theValue = ContentUtility.TextEditorContentEncode(siteInfo, theValue); + // theValue = UEditorUtils.TranslateToStlElement(theValue); + // } + + // if (inputType != InputType.TextEditor && inputType != InputType.Image && inputType != InputType.File && inputType != InputType.Video && styleInfo.AttributeName != ContentAttribute.LinkUrl) + // { + // theValue = AttackUtils.FilterSqlAndXss(theValue); + // } + + // attributes.Set(styleInfo.AttributeName, theValue); + // //TranslateUtils.SetOrRemoveAttributeLowerCase(attributes, styleInfo.AttributeName, theValue); + + // if (styleInfo.IsFormatString) + // { + // var formatString = TranslateUtils.ToBool(formCollection[styleInfo.AttributeName + "_formatStrong"]); + // var formatEm = TranslateUtils.ToBool(formCollection[styleInfo.AttributeName + "_formatEM"]); + // var formatU = TranslateUtils.ToBool(formCollection[styleInfo.AttributeName + "_formatU"]); + // var formatColor = formCollection[styleInfo.AttributeName + "_formatColor"]; + // var theFormatString = ContentUtility.GetTitleFormatString(formatString, formatEm, formatU, formatColor); + + // attributes.Set(ContentAttribute.GetFormatStringAttributeName(styleInfo.AttributeName), theFormatString); + // //TranslateUtils.SetOrRemoveAttributeLowerCase(attributes, ContentAttribute.GetFormatStringAttributeName(styleInfo.AttributeName), theFormatString); + // } + + // if (inputType == InputType.Image || inputType == InputType.File || inputType == InputType.Video) + // { + // var attributeName = ContentAttribute.GetExtendAttributeName(styleInfo.AttributeName); + // attributes.Set(attributeName, formCollection[attributeName]); + // //TranslateUtils.SetOrRemoveAttributeLowerCase(attributes, attributeName, formCollection[attributeName]); + // } + // } + //} } } diff --git a/net452/SiteServer.BackgroundPages/Core/ChannelLoading.cs b/net452/SiteServer.BackgroundPages/Core/ChannelLoading.cs new file mode 100644 index 000000000..9e0d158d4 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Core/ChannelLoading.cs @@ -0,0 +1,206 @@ +using System; +using System.Text; +using SiteServer.Utils; +using System.Collections.Specialized; +using SiteServer.BackgroundPages.Cms; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Core +{ + public static class ChannelLoading + { + public static string GetChannelRowHtml(SiteInfo siteInfo, ChannelInfo channelInfo, bool enabled, ELoadingType loadingType, NameValueCollection additional, PermissionsImpl permissionsImpl) + { + var nodeTreeItem = ChannelTreeItem.CreateInstance(siteInfo, channelInfo, enabled, permissionsImpl); + var onlyAdminId = permissionsImpl.GetOnlyAdminId(siteInfo.Id, channelInfo.Id); + var title = nodeTreeItem.GetItemHtml(loadingType, PageChannel.GetRedirectUrl(siteInfo.Id, channelInfo.Id), onlyAdminId, additional); + + var rowHtml = string.Empty; + + if (loadingType == ELoadingType.ContentTree) + { + rowHtml = $@" + + {title} + +"; + } + else if (loadingType == ELoadingType.Channel) + { + var upLink = string.Empty; + var downLink = string.Empty; + var editUrl = string.Empty; + var checkBoxHtml = string.Empty; + + if (enabled) + { + if (permissionsImpl.HasChannelPermissions(channelInfo.SiteId, channelInfo.Id, ConfigManager.ChannelPermissions.ChannelEdit)) + { + editUrl = $@"编辑"; + upLink = + $@""; + downLink = + $@""; + } + checkBoxHtml = $@""; + } + + rowHtml = $@" + + {title} + {channelInfo.GroupNameCollection} + {channelInfo.IndexName} + {upLink} + {downLink} + {editUrl} + {checkBoxHtml} + +"; + } + else if (loadingType == ELoadingType.SiteAnalysis) + { + var startDate = TranslateUtils.ToDateTime(additional["StartDate"]); + var endDate = TranslateUtils.ToDateTime(additional["EndDate"]); + + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + var num = DataProvider.ContentRepository.GetCountOfContentAdd(tableName, siteInfo.Id, channelInfo.Id, EScopeType.All, startDate, endDate, string.Empty, ETriState.All); + var contentAddNum = num == 0 ? "0" : $"{num}"; + + num = DataProvider.ContentRepository.GetCountOfContentUpdate(tableName, siteInfo.Id, channelInfo.Id, EScopeType.All, startDate, endDate, string.Empty); + var contentUpdateNum = num == 0 ? "0" : $"{num}"; + + rowHtml = $@" + + {title} + {contentAddNum} + {contentUpdateNum} + +"; + } + else if (loadingType == ELoadingType.TemplateFilePathRule) + { + var editLink = string.Empty; + + if (enabled) + { + var showPopWinString = ModalTemplateFilePathRule.GetOpenWindowString(channelInfo.SiteId, channelInfo.Id); + editLink = $"更改"; + } + var filePath = PageUtility.GetInputChannelUrl(siteInfo, channelInfo, false); + + rowHtml = $@" + + {title} + {filePath} + {editLink} + +"; + } + else if (loadingType == ELoadingType.ConfigurationCreateDetails) + { + var editChannelLink = string.Empty; + + var nodeNames = string.Empty; + + if (enabled) + { + var showPopWinString = ModalConfigurationCreateChannel.GetOpenWindowString(channelInfo.SiteId, channelInfo.Id); + editChannelLink = $"触发栏目"; + } + + var nodeNameBuilder = new StringBuilder(); + var channelIdList = TranslateUtils.StringCollectionToIntList(channelInfo.CreateChannelIdsIfContentChanged); + foreach (var theChannelId in channelIdList) + { + var theNodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, theChannelId); + if (theNodeInfo != null) + { + nodeNameBuilder.Append(theNodeInfo.ChannelName).Append(","); + } + } + if (nodeNameBuilder.Length > 0) + { + nodeNameBuilder.Length--; + nodeNames = nodeNameBuilder.ToString(); + } + + rowHtml = $@" + + {title} + {nodeNames} + {editChannelLink} + +"; + } + else if (loadingType == ELoadingType.ConfigurationCrossSiteTrans) + { + var editLink = string.Empty; + + if (enabled) + { + var showPopWinString = ModalCrossSiteTransEdit.GetOpenWindowString(channelInfo.SiteId, channelInfo.Id); + editLink = $"更改"; + } + + var contribute = CrossSiteTransUtility.GetDescription(channelInfo.SiteId, channelInfo); + + rowHtml = $@" + + {title} + {contribute} + {editLink} + +"; + } + else if (loadingType == ELoadingType.ChannelClickSelect) + { + rowHtml = $@" + + {title} + +"; + } + + return rowHtml; + } + + public static string GetScript(SiteInfo siteInfo, string contentModelPluginId, ELoadingType loadingType, NameValueCollection additional) + { + return ChannelTreeItem.GetScript(siteInfo, loadingType, contentModelPluginId, additional); + } + + public static string GetScriptOnLoad(int siteId, int currentChannelId) + { + if (currentChannelId == 0 || currentChannelId == siteId) return string.Empty; + + var nodeInfo = ChannelManager.GetChannelInfo(siteId, currentChannelId); + if (nodeInfo == null) return string.Empty; + + string path; + if (nodeInfo.ParentId == siteId) + { + path = currentChannelId.ToString(); + } + else + { + path = nodeInfo.ParentsPath.Substring(nodeInfo.ParentsPath.IndexOf(",", StringComparison.Ordinal) + 1) + "," + currentChannelId; + } + return ChannelTreeItem.GetScriptOnLoad(path); + } + } +} diff --git a/SiteServer.BackgroundPages/Core/ChannelTreeItem.cs b/net452/SiteServer.BackgroundPages/Core/ChannelTreeItem.cs similarity index 79% rename from SiteServer.BackgroundPages/Core/ChannelTreeItem.cs rename to net452/SiteServer.BackgroundPages/Core/ChannelTreeItem.cs index 5ab0983b4..ca9ae2d75 100644 --- a/SiteServer.BackgroundPages/Core/ChannelTreeItem.cs +++ b/net452/SiteServer.BackgroundPages/Core/ChannelTreeItem.cs @@ -1,18 +1,20 @@ using System.Text; using SiteServer.Utils; -using SiteServer.CMS.Model; using System.Collections.Specialized; using SiteServer.BackgroundPages.Ajax; using SiteServer.BackgroundPages.Cms; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; using SiteServer.CMS.Core; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.Plugin; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; namespace SiteServer.BackgroundPages.Core { public class ChannelTreeItem { - private readonly string _contentModelIconUrl; private readonly string _contentModelIconClass; private readonly string _iconEmptyUrl; private readonly string _iconMinusUrl; @@ -21,41 +23,33 @@ public class ChannelTreeItem private readonly SiteInfo _siteInfo; private readonly ChannelInfo _channelInfo; private readonly bool _enabled; - private readonly PermissionManager _permissionManager; + private readonly PermissionsImpl _permissionsImpl; - public static ChannelTreeItem CreateInstance(SiteInfo siteInfo, ChannelInfo channelInfo, bool enabled, PermissionManager permissionManager) + public static ChannelTreeItem CreateInstance(SiteInfo siteInfo, ChannelInfo channelInfo, bool enabled, PermissionsImpl permissionsImpl) { - return new ChannelTreeItem(siteInfo, channelInfo, enabled, permissionManager); + return new ChannelTreeItem(siteInfo, channelInfo, enabled, permissionsImpl); } - private ChannelTreeItem(SiteInfo siteInfo, ChannelInfo channelInfo, bool enabled, PermissionManager permissionManager) + private ChannelTreeItem(SiteInfo siteInfo, ChannelInfo channelInfo, bool enabled, PermissionsImpl permissionsImpl) { _siteInfo = siteInfo; _channelInfo = channelInfo; _enabled = enabled; - _permissionManager = permissionManager; + _permissionsImpl = permissionsImpl; var treeDirectoryUrl = SiteServerAssets.GetIconUrl("tree"); - _contentModelIconUrl = PageUtils.Combine(treeDirectoryUrl, "folder.gif"); + + //为后台栏目树中的首页和外链栏目添加图标 + if (_channelInfo.ParentId == 0) _contentModelIconClass = "ion-ios-home"; + else if (_channelInfo.LinkUrl.Length != 0) _contentModelIconClass = "ion-link"; + else _contentModelIconClass = "ion-folder"; + _iconEmptyUrl = PageUtils.Combine(treeDirectoryUrl, "empty.gif"); _iconMinusUrl = PageUtils.Combine(treeDirectoryUrl, "minus.png"); _iconPlusUrl = PageUtils.Combine(treeDirectoryUrl, "plus.png"); - - if (!string.IsNullOrEmpty(channelInfo.ContentModelPluginId)) - { - _contentModelIconClass = PluginMenuManager.GetPluginIconClass(channelInfo.ContentModelPluginId); - if (string.IsNullOrEmpty(_contentModelIconClass)) - { - var iconUrl = PluginManager.GetPluginIconUrl(channelInfo.ContentModelPluginId); - if (!string.IsNullOrEmpty(iconUrl)) - { - _contentModelIconUrl = iconUrl; - } - } - } } - public string GetItemHtml(ELoadingType loadingType, string returnUrl, NameValueCollection additional) + public string GetItemHtml(ELoadingType loadingType, string returnUrl, int? onlyAdminId, NameValueCollection additional) { var htmlBuilder = new StringBuilder(); var parentsCount = _channelInfo.ParentsCount; @@ -68,9 +62,9 @@ public string GetItemHtml(ELoadingType loadingType, string returnUrl, NameValueC { htmlBuilder.Append( _channelInfo.SiteId == _channelInfo.Id - ? $@"" - : $@""); } else @@ -78,13 +72,11 @@ public string GetItemHtml(ELoadingType loadingType, string returnUrl, NameValueC htmlBuilder.Append($@""); } - var contentModelIconHtml = !string.IsNullOrEmpty(_contentModelIconClass) - ? $@"" - : $@""; + var contentModelIconHtml = $@""; if (_channelInfo.Id > 0) { - contentModelIconHtml = $@"{contentModelIconHtml}"; + contentModelIconHtml = $@"{contentModelIconHtml}"; } htmlBuilder.Append(contentModelIconHtml); @@ -94,7 +86,7 @@ public string GetItemHtml(ELoadingType loadingType, string returnUrl, NameValueC { if (loadingType == ELoadingType.ContentTree) { - var linkUrl = PageContent.GetRedirectUrl(_channelInfo.SiteId, _channelInfo.Id); + var linkUrl = AdminPagesUtils.Cms.GetContentsUrl(_channelInfo.SiteId, _channelInfo.Id); if (!string.IsNullOrEmpty(additional?["linkUrl"])) { linkUrl = PageUtils.AddQueryStringIfNotExists(additional["linkUrl"], new NameValueCollection @@ -103,10 +95,12 @@ public string GetItemHtml(ELoadingType loadingType, string returnUrl, NameValueC }); } + //linkUrl = PageUtils.GetLoadingUrl(linkUrl); + htmlBuilder.Append( $"{_channelInfo.ChannelName}"); } - else if (loadingType == ELoadingType.ChannelSelect) + else if (loadingType == ELoadingType.ChannelClickSelect) { var linkUrl = ModalChannelSelect.GetRedirectUrl(_channelInfo.SiteId, _channelInfo.Id); if (additional != null) @@ -127,7 +121,7 @@ public string GetItemHtml(ELoadingType loadingType, string returnUrl, NameValueC } else { - if (_permissionManager.HasChannelPermissions(_channelInfo.SiteId, _channelInfo.Id, ConfigManager.ChannelPermissions.ChannelEdit)) + if (_permissionsImpl.HasChannelPermissions(_channelInfo.SiteId, _channelInfo.Id, ConfigManager.ChannelPermissions.ChannelEdit)) { var onClickUrl = ModalChannelEdit.GetOpenWindowString(_channelInfo.SiteId, _channelInfo.Id, returnUrl); htmlBuilder.Append( @@ -136,7 +130,7 @@ public string GetItemHtml(ELoadingType loadingType, string returnUrl, NameValueC } else { - htmlBuilder.Append($@"{_channelInfo.ChannelName}"); + htmlBuilder.Append($@"{_channelInfo.ChannelName}"); } } } @@ -149,12 +143,12 @@ public string GetItemHtml(ELoadingType loadingType, string returnUrl, NameValueC { htmlBuilder.Append(" "); - htmlBuilder.Append(ChannelManager.GetNodeTreeLastImageHtml(_siteInfo, _channelInfo)); + htmlBuilder.Append(ChannelManager.GetNodeTreeLastImageHtml(_channelInfo)); - if (_channelInfo.ContentNum < 0) return htmlBuilder.ToString(); + var count = ContentManager.GetCount(_siteInfo, _channelInfo, onlyAdminId); htmlBuilder.Append( - $@"({_channelInfo.ContentNum})"); + $@"({count})"); } return htmlBuilder.ToString(); @@ -215,6 +209,15 @@ function fontWeightLink(element){ } } +function unSelectRow(tr) { + tr = $(tr); + var cb = tr.find('input:checkbox:first'); + if (cb.length === 0) return; + var checked = cb.is(':checked'); + cb[0].checked = false; + tr.removeClass('table-active'); +} + var completedChannelId = null; function displayChildren(img){ if (!img) return; @@ -238,7 +241,7 @@ function displayChildren(img){ if (isToOpen && isByAjax) { var div = document.createElement('div'); - div.innerHTML = "" 加载中,请稍候...""; + div.innerHTML = """"; img.parentNode.appendChild(div); $(div).addClass('loading'); loadingChannels(tr, img, div, channelId); @@ -256,6 +259,7 @@ function displayChildren(img){ if (currentLevel <= level) break; if(e.style.display == '') { e.style.display = 'none'; + unSelectRow(e); }else{ if (currentLevel != level + 1) continue; e.style.display = ''; @@ -318,7 +322,7 @@ function loadingChannelsOnLoad(paths){{ script = script.Replace("{iconEmptyUrl}", PageUtils.Combine(treeDirectoryUrl, "empty.gif")); script = script.Replace("{iconMinusUrl}", PageUtils.Combine(treeDirectoryUrl, "minus.png")); script = script.Replace("{iconPlusUrl}", PageUtils.Combine(treeDirectoryUrl, "plus.png")); - script = script.Replace("{iconLoadingUrl}", SiteServerAssets.GetIconUrl("loading.gif")); + script = script.Replace("{iconLoadingUrl}", SiteServerAssets.GetUrl("layer/skin/default/xubox_loading0.gif")); return script; } diff --git a/SiteServer.BackgroundPages/Core/ControlUtility.cs b/net452/SiteServer.BackgroundPages/Core/ControlUtility.cs similarity index 100% rename from SiteServer.BackgroundPages/Core/ControlUtility.cs rename to net452/SiteServer.BackgroundPages/Core/ControlUtility.cs diff --git a/SiteServer.BackgroundPages/Core/DepartmentTreeItem.cs b/net452/SiteServer.BackgroundPages/Core/DepartmentTreeItem.cs similarity index 97% rename from SiteServer.BackgroundPages/Core/DepartmentTreeItem.cs rename to net452/SiteServer.BackgroundPages/Core/DepartmentTreeItem.cs index 96fddce70..68d95d032 100644 --- a/SiteServer.BackgroundPages/Core/DepartmentTreeItem.cs +++ b/net452/SiteServer.BackgroundPages/Core/DepartmentTreeItem.cs @@ -3,9 +3,9 @@ using System.Text; using SiteServer.Utils; using SiteServer.BackgroundPages.Ajax; -using SiteServer.BackgroundPages.Cms; -using SiteServer.BackgroundPages.Settings; -using SiteServer.CMS.Model; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Core { @@ -161,7 +161,7 @@ public string GetItemHtml(EDepartmentLoadingType loadingType, NameValueCollectio if (loadingType == EDepartmentLoadingType.AdministratorTree) { - var linkUrl = PageAdministrator.GetRedirectUrl(); + var linkUrl = AdminPagesUtils.Settings.AdministratorsUrl; htmlBuilder.Append( $"{_departmentInfo.DepartmentName}"); @@ -177,7 +177,7 @@ public string GetItemHtml(EDepartmentLoadingType loadingType, NameValueCollectio } else if (loadingType == EDepartmentLoadingType.ContentTree) { - var linkUrl = PageContent.GetRedirectUrl(TranslateUtils.ToInt(additional["SiteId"]), _departmentInfo.Id); + var linkUrl = AdminPagesUtils.Cms.GetContentsUrl(TranslateUtils.ToInt(additional["SiteId"]), _departmentInfo.Id); htmlBuilder.Append( $"{_departmentInfo.DepartmentName}"); diff --git a/net452/SiteServer.BackgroundPages/Core/GlobalSuppressions.cs b/net452/SiteServer.BackgroundPages/Core/GlobalSuppressions.cs new file mode 100644 index 000000000..a5cc44efc Binary files /dev/null and b/net452/SiteServer.BackgroundPages/Core/GlobalSuppressions.cs differ diff --git a/SiteServer.Utils/LayerUtils.cs b/net452/SiteServer.BackgroundPages/Core/LayerUtils.cs similarity index 98% rename from SiteServer.Utils/LayerUtils.cs rename to net452/SiteServer.BackgroundPages/Core/LayerUtils.cs index af042a105..95910f05b 100644 --- a/SiteServer.Utils/LayerUtils.cs +++ b/net452/SiteServer.BackgroundPages/Core/LayerUtils.cs @@ -1,13 +1,10 @@ -using System.Web.UI; + +using System.Web.UI; -namespace SiteServer.Utils +namespace SiteServer.BackgroundPages.Core { - public class LayerUtils + public static class LayerUtils { - private LayerUtils() - { - } - public const string CloseScript = "if (window.parent.closeWindow) window.parent.closeWindow();if (window.parent.layer) window.parent.layer.closeAll();"; public const string OpenPageCreateStatusFuncName = "openPageCreateStatus"; diff --git a/SiteServer.Utils/LitJson/IJsonWrapper.cs b/net452/SiteServer.BackgroundPages/Core/LitJson/IJsonWrapper.cs similarity index 96% rename from SiteServer.Utils/LitJson/IJsonWrapper.cs rename to net452/SiteServer.BackgroundPages/Core/LitJson/IJsonWrapper.cs index 5e15c4554..9e0394366 100644 --- a/SiteServer.Utils/LitJson/IJsonWrapper.cs +++ b/net452/SiteServer.BackgroundPages/Core/LitJson/IJsonWrapper.cs @@ -13,7 +13,7 @@ using System.Collections; using System.Collections.Specialized; -namespace SiteServer.Utils.LitJson +namespace SiteServer.BackgroundPages.Core.LitJson { public enum JsonType { diff --git a/SiteServer.Utils/LitJson/JsonData.cs b/net452/SiteServer.BackgroundPages/Core/LitJson/JsonData.cs similarity index 99% rename from SiteServer.Utils/LitJson/JsonData.cs rename to net452/SiteServer.BackgroundPages/Core/LitJson/JsonData.cs index 0d380edec..4eba16f86 100644 --- a/SiteServer.Utils/LitJson/JsonData.cs +++ b/net452/SiteServer.BackgroundPages/Core/LitJson/JsonData.cs @@ -15,7 +15,7 @@ using System.Collections.Specialized; using System.IO; -namespace SiteServer.Utils.LitJson +namespace SiteServer.BackgroundPages.Core.LitJson { public class JsonData : IJsonWrapper, IEquatable { diff --git a/SiteServer.Utils/LitJson/JsonException.cs b/net452/SiteServer.BackgroundPages/Core/LitJson/JsonException.cs similarity index 96% rename from SiteServer.Utils/LitJson/JsonException.cs rename to net452/SiteServer.BackgroundPages/Core/LitJson/JsonException.cs index 55b437829..46168acb4 100644 --- a/SiteServer.Utils/LitJson/JsonException.cs +++ b/net452/SiteServer.BackgroundPages/Core/LitJson/JsonException.cs @@ -10,7 +10,7 @@ using System; -namespace SiteServer.Utils.LitJson +namespace SiteServer.BackgroundPages.Core.LitJson { public class JsonException : ApplicationException { diff --git a/SiteServer.Utils/LitJson/JsonMapper.cs b/net452/SiteServer.BackgroundPages/Core/LitJson/JsonMapper.cs similarity index 99% rename from SiteServer.Utils/LitJson/JsonMapper.cs rename to net452/SiteServer.BackgroundPages/Core/LitJson/JsonMapper.cs index 29f9aaf16..5b91c1fdd 100644 --- a/SiteServer.Utils/LitJson/JsonMapper.cs +++ b/net452/SiteServer.BackgroundPages/Core/LitJson/JsonMapper.cs @@ -15,7 +15,7 @@ using System.IO; using System.Reflection; -namespace SiteServer.Utils.LitJson +namespace SiteServer.BackgroundPages.Core.LitJson { internal struct PropertyMetadata { diff --git a/SiteServer.Utils/LitJson/JsonReader.cs b/net452/SiteServer.BackgroundPages/Core/LitJson/JsonReader.cs similarity index 99% rename from SiteServer.Utils/LitJson/JsonReader.cs rename to net452/SiteServer.BackgroundPages/Core/LitJson/JsonReader.cs index 08b7860ff..11cc8e5b2 100644 --- a/SiteServer.Utils/LitJson/JsonReader.cs +++ b/net452/SiteServer.BackgroundPages/Core/LitJson/JsonReader.cs @@ -12,7 +12,7 @@ using System.Collections.Generic; using System.IO; -namespace SiteServer.Utils.LitJson +namespace SiteServer.BackgroundPages.Core.LitJson { public enum JsonToken { diff --git a/SiteServer.Utils/LitJson/JsonWriter.cs b/net452/SiteServer.BackgroundPages/Core/LitJson/JsonWriter.cs similarity index 99% rename from SiteServer.Utils/LitJson/JsonWriter.cs rename to net452/SiteServer.BackgroundPages/Core/LitJson/JsonWriter.cs index 163661474..76aec605a 100644 --- a/SiteServer.Utils/LitJson/JsonWriter.cs +++ b/net452/SiteServer.BackgroundPages/Core/LitJson/JsonWriter.cs @@ -14,7 +14,7 @@ using System.IO; using System.Text; -namespace SiteServer.Utils.LitJson +namespace SiteServer.BackgroundPages.Core.LitJson { internal enum Condition { diff --git a/SiteServer.Utils/LitJson/Lexer.cs b/net452/SiteServer.BackgroundPages/Core/LitJson/Lexer.cs similarity index 99% rename from SiteServer.Utils/LitJson/Lexer.cs rename to net452/SiteServer.BackgroundPages/Core/LitJson/Lexer.cs index 8e180a250..254651aff 100644 --- a/SiteServer.Utils/LitJson/Lexer.cs +++ b/net452/SiteServer.BackgroundPages/Core/LitJson/Lexer.cs @@ -12,7 +12,7 @@ using System.IO; using System.Text; -namespace SiteServer.Utils.LitJson +namespace SiteServer.BackgroundPages.Core.LitJson { internal class FsmContext { diff --git a/SiteServer.Utils/LitJson/ParserToken.cs b/net452/SiteServer.BackgroundPages/Core/LitJson/ParserToken.cs similarity index 93% rename from SiteServer.Utils/LitJson/ParserToken.cs rename to net452/SiteServer.BackgroundPages/Core/LitJson/ParserToken.cs index 9a9288867..0d82f3c54 100644 --- a/SiteServer.Utils/LitJson/ParserToken.cs +++ b/net452/SiteServer.BackgroundPages/Core/LitJson/ParserToken.cs @@ -9,7 +9,7 @@ #endregion -namespace SiteServer.Utils.LitJson +namespace SiteServer.BackgroundPages.Core.LitJson { internal enum ParserToken { diff --git a/net452/SiteServer.BackgroundPages/Core/NavigationTree.cs b/net452/SiteServer.BackgroundPages/Core/NavigationTree.cs new file mode 100644 index 000000000..c636b99aa --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Core/NavigationTree.cs @@ -0,0 +1,115 @@ +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Text; +using SiteServer.CMS.Core; +using SiteServer.Utils; + +namespace SiteServer.BackgroundPages.Core +{ + public static class NavigationTree + { + public static string BuildNavigationTree(int siteId, string topId, List permissionList) + { + var tabs = TabManager.GetTabList(topId, siteId); + if (tabs == null || tabs.Count == 0) return string.Empty; + + var builder = new StringBuilder(); + + foreach (var parent in tabs) + { + if (!TabManager.IsValid(parent, permissionList)) continue; + + var childBuilder = new StringBuilder(); + if (parent.Children != null && parent.Children.Length > 0) + { + var tabCollection = new TabCollection(parent.Children); + if (tabCollection.Tabs != null && tabCollection.Tabs.Length > 0) + { + foreach (var childTab in tabCollection.Tabs) + { + if (!TabManager.IsValid(childTab, permissionList)) continue; + + var href = childTab.Href; + if (!PageUtils.IsAbsoluteUrl(href)) + { + href = PageUtils.AddQueryString(href, + new NameValueCollection { { "siteId", siteId.ToString() } }); + } + + if (childTab.HasHref) + { + childBuilder.Append($@" +
  • + + + {childTab.Text} + +
  • "); + } + else + { + childBuilder.Append($@" +
  • + + + {childTab.Text} + +
  • "); + } + + } + } + } + + if (childBuilder.Length > 0) + { + builder.Append($@" +
  • + + + {parent.Text} + + +
      + {childBuilder} +
    +
  • +"); + } + else + { + var href = parent.Href; + if (!PageUtils.IsAbsoluteUrl(href)) + { + href = PageUtils.AddQueryString(href, + new NameValueCollection {{"siteId", siteId.ToString()}}); + } + + if (parent.HasHref) + { + builder.Append($@" +
  • + + + {parent.Text} + +
  • "); + } + else + { + builder.Append($@" +
  • + + + {parent.Text} + +
  • "); + } + + } + } + + return builder.ToString(); + } + } +} diff --git a/SiteServer.BackgroundPages/Core/NavigationTreeItem.cs b/net452/SiteServer.BackgroundPages/Core/NavigationTreeItem.cs similarity index 100% rename from SiteServer.BackgroundPages/Core/NavigationTreeItem.cs rename to net452/SiteServer.BackgroundPages/Core/NavigationTreeItem.cs diff --git a/SiteServer.BackgroundPages/Core/NodeNaviTreeItem.cs b/net452/SiteServer.BackgroundPages/Core/NodeNaviTreeItem.cs similarity index 99% rename from SiteServer.BackgroundPages/Core/NodeNaviTreeItem.cs rename to net452/SiteServer.BackgroundPages/Core/NodeNaviTreeItem.cs index a16b3fd6d..36bfe9bf6 100644 --- a/SiteServer.BackgroundPages/Core/NodeNaviTreeItem.cs +++ b/net452/SiteServer.BackgroundPages/Core/NodeNaviTreeItem.cs @@ -1,6 +1,7 @@ using System.Text; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.DataCache; namespace SiteServer.BackgroundPages.Core { diff --git a/SiteServer.BackgroundPages/Core/PagerStyle.cs b/net452/SiteServer.BackgroundPages/Core/PagerStyle.cs similarity index 100% rename from SiteServer.BackgroundPages/Core/PagerStyle.cs rename to net452/SiteServer.BackgroundPages/Core/PagerStyle.cs diff --git a/SiteServer.BackgroundPages/Core/SortMode.cs b/net452/SiteServer.BackgroundPages/Core/SortMode.cs similarity index 100% rename from SiteServer.BackgroundPages/Core/SortMode.cs rename to net452/SiteServer.BackgroundPages/Core/SortMode.cs diff --git a/net452/SiteServer.BackgroundPages/Core/TextUtility.cs b/net452/SiteServer.BackgroundPages/Core/TextUtility.cs new file mode 100644 index 000000000..abaec34a1 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Core/TextUtility.cs @@ -0,0 +1,236 @@ +using System; +using System.Text; +using SiteServer.Utils; +using System.Collections.Generic; +using System.Collections.Specialized; +using SiteServer.BackgroundPages.Cms; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; + +namespace SiteServer.BackgroundPages.Core +{ + public static class TextUtility + { + private static string GetColumnValue(Dictionary nameValueCacheDict, SiteInfo siteInfo, ContentInfo contentInfo, TableStyleInfo styleInfo) + { + var value = string.Empty; + if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.AddUserName)) + { + if (!string.IsNullOrEmpty(contentInfo.AddUserName)) + { + var key = ContentAttribute.AddUserName + ":" + contentInfo.AddUserName; + if (!nameValueCacheDict.TryGetValue(key, out value)) + { + value = AdminManager.GetDisplayName(contentInfo.AddUserName, false); + nameValueCacheDict[key] = value; + } + } + } + else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.LastEditUserName)) + { + if (!string.IsNullOrEmpty(contentInfo.LastEditUserName)) + { + var key = ContentAttribute.LastEditUserName + ":" + contentInfo.LastEditUserName; + if (!nameValueCacheDict.TryGetValue(key, out value)) + { + value = AdminManager.GetDisplayName(contentInfo.LastEditUserName, false); + nameValueCacheDict[key] = value; + } + } + } + else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.CheckUserName)) + { + var checkUserName = contentInfo.Get(ContentAttribute.CheckUserName); + if (!string.IsNullOrEmpty(checkUserName)) + { + var key = ContentAttribute.CheckUserName + ":" + checkUserName; + if (!nameValueCacheDict.TryGetValue(key, out value)) + { + value = AdminManager.GetDisplayName(checkUserName, false); + nameValueCacheDict[key] = value; + } + } + } + else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.CheckDate)) + { + var checkDate = contentInfo.Get(ContentAttribute.CheckDate); + if (checkDate.HasValue) + { + value = DateUtils.GetDateAndTimeString(checkDate); + } + } + else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.CheckReasons)) + { + value = contentInfo.Get(ContentAttribute.CheckReasons); + } + else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.AddDate)) + { + value = DateUtils.GetDateAndTimeString(contentInfo.AddDate); + } + else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.LastEditDate)) + { + value = DateUtils.GetDateAndTimeString(contentInfo.LastEditDate); + } + else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.SourceId)) + { + value = SourceManager.GetSourceName(contentInfo.SourceId); + } + else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.Tags)) + { + value = contentInfo.Tags; + } + else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.GroupNameCollection)) + { + value = contentInfo.GroupNameCollection; + } + else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.Hits)) + { + value = contentInfo.Hits.ToString(); + } + else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.HitsByDay)) + { + value = contentInfo.HitsByDay.ToString(); + } + else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.HitsByWeek)) + { + value = contentInfo.HitsByWeek.ToString(); + } + else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.HitsByMonth)) + { + value = contentInfo.HitsByMonth.ToString(); + } + else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.LastHitsDate)) + { + value = DateUtils.GetDateAndTimeString(contentInfo.LastHitsDate); + } + else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.Downloads)) + { + value = contentInfo.Downloads.ToString(); + } + else if (StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.IsTop) || StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.IsColor) || StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.IsHot) || StringUtils.EqualsIgnoreCase(styleInfo.AttributeName, ContentAttribute.IsRecommend)) + { + value = StringUtils.GetTrueImageHtml(contentInfo.Get(styleInfo.AttributeName)); + } + else + { + value = InputParserUtility.GetContentByTableStyle(contentInfo.Get(styleInfo.AttributeName), siteInfo, styleInfo); + } + return value; + } + + public static bool IsEdit(SiteInfo siteInfo, int channelId, PermissionsImpl permissionsImpl) + { + return permissionsImpl.HasChannelPermissions(siteInfo.Id, channelId, ConfigManager.ChannelPermissions.ContentEdit); + } + + //public static bool IsComment(SiteInfo siteInfo, int channelId, string administratorName) + //{ + // return siteInfo.IsCommentable && AdminUtility.HasChannelPermissions(administratorName, siteInfo.Id, channelId, ConfigManager.Permissions.Channel.CommentCheck, ConfigManager.Permissions.Channel.CommentDelete); + //} + + public static string GetColumnsHeadHtml(List tableStyleInfoList, Dictionary>> pluginColumns, StringCollection attributesOfDisplay) + { + var builder = new StringBuilder(); + + var styleInfoList = ContentUtility.GetAllTableStyleInfoList(tableStyleInfoList); + + foreach (var styleInfo in styleInfoList) + { + if (!attributesOfDisplay.Contains(styleInfo.AttributeName) || styleInfo.AttributeName == ContentAttribute.Title) continue; + builder.Append($@"{styleInfo.DisplayName}"); + } + + if (pluginColumns != null) + { + foreach (var pluginId in pluginColumns.Keys) + { + var contentColumns = pluginColumns[pluginId]; + if (contentColumns == null || contentColumns.Count == 0) continue; + + foreach (var columnName in contentColumns.Keys) + { + var attributeName = $"{pluginId}:{columnName}"; + if (!attributesOfDisplay.Contains(attributeName)) continue; + + builder.Append($@"{columnName}"); + } + } + } + + return builder.ToString(); + } + + public static string GetColumnsHtml(Dictionary nameValueCacheDict, SiteInfo siteInfo, ContentInfo contentInfo, StringCollection attributesOfDisplay, List displayStyleInfoList, Dictionary>> pluginColumns) + { + var builder = new StringBuilder(); + + foreach (var styleInfo in displayStyleInfoList) + { + if (!attributesOfDisplay.Contains(styleInfo.AttributeName) || styleInfo.AttributeName == ContentAttribute.Title) continue; + + var value = GetColumnValue(nameValueCacheDict, siteInfo, contentInfo, styleInfo); + builder.Append($@"{value}"); + } + + if (pluginColumns != null) + { + foreach (var pluginId in pluginColumns.Keys) + { + var contentColumns = pluginColumns[pluginId]; + if (contentColumns == null || contentColumns.Count == 0) continue; + + foreach (var columnName in contentColumns.Keys) + { + var attributeName = $"{pluginId}:{columnName}"; + if (!attributesOfDisplay.Contains(attributeName)) continue; + + try + { + var func = contentColumns[columnName]; + var value = func(new ContentContextImpl + { + SiteId = contentInfo.SiteId, + ChannelId = contentInfo.ChannelId, + ContentId = contentInfo.Id + }); + builder.Append($@"{value}"); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(pluginId, ex); + } + } + } + } + + return builder.ToString(); + } + + public static string GetCommandsHtml(SiteInfo siteInfo, List pluginMenus, ContentInfo contentInfo, string pageUrl, string administratorName, bool isEdit) + { + var builder = new StringBuilder(); + + if (isEdit || administratorName == contentInfo.AddUserName) + { + builder.Append($@"编辑"); + } + + if (pluginMenus != null) + { + foreach (var menu in pluginMenus) + { + builder.Append(string.IsNullOrEmpty(menu.Target) + ? $@"{menu.Text}" + : $@"{menu.Text}"); + } + } + + return builder.ToString(); + } + } +} diff --git a/SiteServer.BackgroundPages/Core/VCManager.cs b/net452/SiteServer.BackgroundPages/Core/VCManager.cs similarity index 83% rename from SiteServer.BackgroundPages/Core/VCManager.cs rename to net452/SiteServer.BackgroundPages/Core/VCManager.cs index c988d356b..ab1038392 100644 --- a/SiteServer.BackgroundPages/Core/VCManager.cs +++ b/net452/SiteServer.BackgroundPages/Core/VCManager.cs @@ -1,13 +1,12 @@ using System; +using SiteServer.CMS.Fx; using SiteServer.Utils; namespace SiteServer.BackgroundPages.Core { public class VcManager { - protected const string AdminLoginCookieName = "BAIRONG.VC.ADMINLOGIN"; - - public const string AttributeName = "validateCode"; + private const string AdminLoginCookieName = "SITESERVER.VC.ADMINLOGIN"; private string _cookieName; @@ -17,8 +16,6 @@ public static VcManager GetInstance() return vc; } - protected VcManager() { } - public string GetCookieName() { return _cookieName; @@ -28,7 +25,7 @@ public static string CreateValidateCode() { var validateCode = ""; - char[] s = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z' }; + char[] s = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z' }; var r = new Random(); for (var i = 0; i < 4; i++) { diff --git a/SiteServer.BackgroundPages/Core/VirtualRecordCount.cs b/net452/SiteServer.BackgroundPages/Core/VirtualRecordCount.cs similarity index 100% rename from SiteServer.BackgroundPages/Core/VirtualRecordCount.cs rename to net452/SiteServer.BackgroundPages/Core/VirtualRecordCount.cs diff --git a/net452/SiteServer.BackgroundPages/Core/WebUtils.cs b/net452/SiteServer.BackgroundPages/Core/WebUtils.cs new file mode 100644 index 000000000..179e2868f --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Core/WebUtils.cs @@ -0,0 +1,367 @@ +using SiteServer.Utils; +using SiteServer.BackgroundPages.Ajax; +using SiteServer.BackgroundPages.Cms; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Core +{ + public static class WebUtils + { + public static string GetContentTitle(SiteInfo siteInfo, ContentInfo contentInfo, string pageUrl) + { + string url; + var title = ContentUtility.FormatTitle(contentInfo.Get(ContentAttribute.GetFormatStringAttributeName(ContentAttribute.Title)), contentInfo.Title); + + var displayString = contentInfo.Color ? $"{title}" : title; + + if (contentInfo.Checked && contentInfo.ChannelId > 0) + { + url = + $"{displayString}"; + } + else + { + url = + $@"{displayString}"; + } + + var image = string.Empty; + if (contentInfo.Recommend) + { + image += " "; + } + if (contentInfo.Hot) + { + image += " "; + } + if (contentInfo.Top) + { + image += " "; + } + if (contentInfo.ReferenceId > 0) + { + if (contentInfo.Get(ContentAttribute.TranslateContentType) == ETranslateContentType.ReferenceContent.ToString()) + { + image += " (引用内容)"; + } + else if (contentInfo.Get(ContentAttribute.TranslateContentType) != ETranslateContentType.ReferenceContent.ToString()) + { + image += " (引用地址)"; + } + } + if (!string.IsNullOrEmpty(contentInfo.Get(ContentAttribute.LinkUrl))) + { + image += " "; + } + if (!string.IsNullOrEmpty(contentInfo.Get(ContentAttribute.ImageUrl))) + { + var imageUrl = PageUtility.ParseNavigationUrl(siteInfo, contentInfo.Get(ContentAttribute.ImageUrl), true); + var openWindowString = ModalMessage.GetOpenWindowString(siteInfo.Id, "预览图片", $"", 500, 500); + image += + $@" "; + } + if (!string.IsNullOrEmpty(contentInfo.Get(ContentAttribute.VideoUrl))) + { + var openWindowString = ModalMessage.GetOpenWindowStringToPreviewVideoByUrl(siteInfo.Id, contentInfo.Get(ContentAttribute.VideoUrl)); + image += + $@" "; + } + if (!string.IsNullOrEmpty(contentInfo.Get(ContentAttribute.FileUrl))) + { + image += " "; + } + return url + image; + } + + public static string GetContentAddUploadWordUrl(int siteId, ChannelInfo nodeInfo, bool isFirstLineTitle, bool isFirstLineRemove, bool isClearFormat, bool isFirstLineIndent, bool isClearFontSize, bool isClearFontFamily, bool isClearImages, int contentLevel, string fileName, string returnUrl) + { + return + $"{PageContentAdd.GetRedirectUrlOfAdd(siteId, nodeInfo.Id, returnUrl)}&isUploadWord=True&isFirstLineTitle={isFirstLineTitle}&isFirstLineRemove={isFirstLineRemove}&isClearFormat={isClearFormat}&isFirstLineIndent={isFirstLineIndent}&isClearFontSize={isClearFontSize}&isClearFontFamily={isClearFontFamily}&isClearImages={isClearImages}&contentLevel={contentLevel}&fileName={fileName}"; + } + + public static string GetContentAddAddUrl(int siteId, ChannelInfo nodeInfo, string returnUrl) + { + return PageContentAdd.GetRedirectUrlOfAdd(siteId, nodeInfo.Id, returnUrl); + } + + public static string GetContentAddEditUrl(int siteId, ChannelInfo nodeInfo, int id, string returnUrl) + { + return PageContentAdd.GetRedirectUrlOfEdit(siteId, nodeInfo.Id, id, returnUrl); + } + +// public static string GetContentCommands(PermissionsImpl permissionsImpl, SiteInfo siteInfo, ChannelInfo channelInfo, string pageUrl) +// { +// var builder = new StringBuilder(); + +// if (permissionsImpl.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentAdd) && channelInfo.IsContentAddable) +// { +// builder.Append($@" +// +// +// 添加 +//"); + +// builder.Append($@" +// +// 导入Word +//"); +// } + +// var onlyAdminId = permissionsImpl.GetOnlyAdminId(siteInfo.Id, channelInfo.Id); +// var count = ContentManager.GetCount(siteInfo, channelInfo, onlyAdminId); + +// if (count > 0 && permissionsImpl.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentDelete)) +// { +// builder.Append($@" +// +// +// 删 除 +//"); +// } + +// if (count > 0) +// { +// if (permissionsImpl.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentEdit)) +// { +// builder.Append($@" +// +// +// 属性 +//"); +// builder.Append($@" +// +// 内容组 +//"); +// } +// if (permissionsImpl.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentTranslate)) +// { +// var redirectUrl = PageContentTranslate.GetRedirectUrl(siteInfo.Id, channelInfo.Id, pageUrl); +// var clickString = PageUtils.GetRedirectStringWithCheckBoxValue(redirectUrl, "contentIdCollection", "contentIdCollection", "请选择需要转移的内容!"); +// builder.Append($@" +// +// 转 移 +//"); +// } +// if (permissionsImpl.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentEdit)) +// { +// builder.Append($@" +// +// 排 序 +//"); +// } +// if (permissionsImpl.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentCheck)) +// { +// builder.Append($@" +// +// 审 核 +//"); +// } +// if (permissionsImpl.HasSitePermissions(siteInfo.Id, ConfigManager.WebSitePermissions.Create) || permissionsImpl.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.CreatePage)) +// { +// builder.Append($@" +// +// +// 生 成 +//"); +// } +// } + +// if (permissionsImpl.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ChannelEdit)) +// { +// builder.Append($@" +// +// +// 显示项 +//"); +// } + +// if (count > 0) +// { +// builder.Append(@" +// +// +// 查找 +//"); +// } + +// return builder.ToString(); +// } + +// public static string GetContentMoreCommands(PermissionsImpl permissionsImpl, SiteInfo siteInfo, ChannelInfo channelInfo, string pageUrl) +// { +// var builder = new StringBuilder(); + +// if (permissionsImpl.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentAdd) && channelInfo.IsContentAddable) +// { +// builder.Append($@" +// +// 导 入 +//"); +// } + +// var onlyAdminId = permissionsImpl.GetOnlyAdminId(siteInfo.Id, channelInfo.Id); +// var count = ContentManager.GetCount(siteInfo, channelInfo, onlyAdminId); + +// if (count > 0) +// { +// builder.Append($@" +// +// 导 出 +//"); +// if (permissionsImpl.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentOrder)) +// { +// builder.Append($@" +// +// 整 理 +//"); +// } +// if (CrossSiteTransUtility.IsCrossSiteTrans(siteInfo, channelInfo) && !CrossSiteTransUtility.IsAutomatic(channelInfo)) +// { +// builder.Append($@" +// +// 跨站转发 +//"); +// } +// } + +// return builder.ToString(); +// } + + public static string GetTextEditorCommands(SiteInfo siteInfo, string attributeName) + { + return $@" + +
    + + + + + + +
    +"; + } + +// public static string GetAutoCheckKeywordsScript(SiteInfo siteInfo) +// { +// var isAutoCheckKeywords = siteInfo.IsAutoCheckKeywords.ToString().ToLower(); +// var url = AjaxCmsService.GetDetectionReplaceUrl(siteInfo.Id); +// var getPureText = UEditorUtils.GetPureTextScript(ContentAttribute.Content); +// var getContent = UEditorUtils.GetContentScript(ContentAttribute.Content); +// var setContent = UEditorUtils.GetSetContentScript(ContentAttribute.Content, "htmlContent"); +// var tipsWarn = AlertUtils.Warning("敏感词检测", "内容中共检测到' + i + '个敏感词,已用黄色背景标明", "取 消", "自动替换并保存", +// "autoReplaceKeywords"); + +// var command = $@" +// +//"; + + + +// return command; +// } + + public static string GetImageUrlButtonGroupHtml(SiteInfo siteInfo, string attributeName) + { + return $@" +
    + + + + +
    +"; + } + } +} diff --git a/SiteServer.BackgroundPages/PageDefault.cs b/net452/SiteServer.BackgroundPages/PageDefault.cs similarity index 100% rename from SiteServer.BackgroundPages/PageDefault.cs rename to net452/SiteServer.BackgroundPages/PageDefault.cs diff --git a/SiteServer.BackgroundPages/PageInitialization.cs b/net452/SiteServer.BackgroundPages/PageInitialization.cs similarity index 78% rename from SiteServer.BackgroundPages/PageInitialization.cs rename to net452/SiteServer.BackgroundPages/PageInitialization.cs index e7bd3f30f..459870297 100644 --- a/SiteServer.BackgroundPages/PageInitialization.cs +++ b/net452/SiteServer.BackgroundPages/PageInitialization.cs @@ -21,14 +21,12 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; // 检测是否允许访问本页面 - if (SystemManager.DetermineRedirectToInstaller()) return; // 检测系统是否需要安装,如果需要转到安装页面。 - var redirectUrl = PageMain.GetRedirectUrl(); // 如果检测登录帐号一切正常,则准备转到框架主页 pagemain.aspx - var siteIdList = AuthRequest.AdminPermissions.SiteIdList; // 获取当前站点ID + var siteIdList = AuthRequest.AdminPermissionsImpl.GetSiteIdList(); // 获取当前站点ID if (siteIdList == null || siteIdList.Count == 0) // 如果目前还没有创建站点 { - if (AuthRequest.AdminPermissions.IsSystemAdministrator) // 如果目前还没有创建站点并且当前登录管理员是系统管理员 + if (AuthRequest.AdminPermissionsImpl.IsSystemAdministrator) // 如果目前还没有创建站点并且当前登录管理员是系统管理员 { redirectUrl = PageSiteAdd.GetRedirectUrl(); // 则直接跳到站点创建页面 } diff --git a/SiteServer.BackgroundPages/PageInstaller.cs b/net452/SiteServer.BackgroundPages/PageInstaller.cs similarity index 86% rename from SiteServer.BackgroundPages/PageInstaller.cs rename to net452/SiteServer.BackgroundPages/PageInstaller.cs index 1294d07a3..efcc9a66d 100644 --- a/SiteServer.BackgroundPages/PageInstaller.cs +++ b/net452/SiteServer.BackgroundPages/PageInstaller.cs @@ -1,10 +1,15 @@ using System; using System.Collections.Generic; +using System.Security.Permissions; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; +using Datory; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Apis; using SiteServer.Utils; using SiteServer.CMS.Core; -using SiteServer.Plugin; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages @@ -56,7 +61,7 @@ public class PageInstaller : BasePage public static string GetRedirectUrl() { - return PageUtils.GetSiteServerUrl("installer/default", null); + return FxUtils.GetSiteServerUrl("installer/default", null); } public void Page_Load(object sender, EventArgs e) @@ -73,17 +78,17 @@ public void Page_Load(object sender, EventArgs e) LtlVersionInfo.Text = SystemManager.Version; SetSetp(1); - DatabaseTypeUtils.AddListItems(DdlSqlDatabaseType); + FxUtils.AddListItemsToDatabaseType(DdlSqlDatabaseType); - EBooleanUtils.AddListItems(DdlIsDefaultPort, "默认数据库端口", "自定义数据库端口"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsDefaultPort, true.ToString()); + FxUtils.AddListItems(DdlIsDefaultPort, "默认数据库端口", "自定义数据库端口"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsDefaultPort, true.ToString()); PhSqlPort.Visible = false; - EBooleanUtils.AddListItems(DdlIsProtectData, "加密", "不加密"); - ControlUtils.SelectSingleItemIgnoreCase(DdlIsProtectData, false.ToString()); + FxUtils.AddListItems(DdlIsProtectData, "加密", "不加密"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlIsProtectData, false.ToString()); - LtlGo.Text = $@"进入后台"; + LtlGo.Text = $@"进入后台"; } public void DdlSqlDatabaseType_SelectedIndexChanged(object sender, EventArgs e) @@ -103,7 +108,7 @@ public void BtnStep1_Click(object sender, EventArgs e) { BtnStep2.Visible = true; - LtlDomain.Text = PageUtils.GetHost(); + LtlDomain.Text = FxUtils.GetHost(); LtlVersion.Text = SystemManager.Version; LtlNetVersion.Text = $"{Environment.Version.Major}.{Environment.Version.Minor}"; LtlPhysicalApplicationPath.Text = WebConfigUtils.PhysicalApplicationPath; @@ -111,21 +116,28 @@ public void BtnStep1_Click(object sender, EventArgs e) var isRootWritable = false; try { - var filePath = PathUtils.Combine(WebConfigUtils.PhysicalApplicationPath, "robots.txt"); - FileUtils.WriteText(filePath, ECharset.utf_8, @"User-agent: * -Disallow: /SiteServer/ -Disallow: /SiteFiles/"); + var filePath = PathUtils.Combine(WebConfigUtils.PhysicalApplicationPath, "version.txt"); + FileUtils.WriteText(filePath, ECharset.utf_8, SystemManager.Version); + + var ioPermission = new FileIOPermission(FileIOPermissionAccess.Write, WebConfigUtils.PhysicalApplicationPath); + ioPermission.Demand(); + isRootWritable = true; } catch { // ignored } + var isSiteFilesWritable = false; try { var filePath = PathUtils.Combine(WebConfigUtils.PhysicalApplicationPath, DirectoryUtils.SiteFiles.DirectoryName, "index.htm"); - FileUtils.WriteText(filePath, ECharset.utf_8, StringUtils.Constants.Html5Empty); + FileUtils.WriteText(filePath, ECharset.utf_8, Constants.Html5Empty); + + var ioPermission = new FileIOPermission(FileIOPermissionAccess.Write, PathUtils.Combine(WebConfigUtils.PhysicalApplicationPath, DirectoryUtils.SiteFiles.DirectoryName)); + ioPermission.Demand(); + isSiteFilesWritable = true; } catch @@ -139,7 +151,7 @@ public void BtnStep1_Click(object sender, EventArgs e) if (!isRootWritable || !isSiteFilesWritable) { - FailMessage("系统检测到文件夹权限不足,您需要赋予可写权限"); + FailMessage("系统检测到文件夹权限不足,您需要赋予根目录 NETWORK SERVICE 以及 IIS_IUSRS 读写权限"); BtnStep2.Visible = false; } @@ -188,7 +200,7 @@ public void BtnStep3_Click(object sender, EventArgs e) else { var connectionStringWithoutDatabaseName = GetConnectionString(databaseType == DatabaseType.Oracle); - isConnectValid = DataProvider.DatabaseDao.ConnectToServer(databaseType, connectionStringWithoutDatabaseName, out databaseNameList, out errorMessage); + isConnectValid = DataProvider.DatabaseApi.ConnectToServer(databaseType, connectionStringWithoutDatabaseName, out databaseNameList, out errorMessage); } if (isConnectValid) @@ -305,7 +317,7 @@ private string GetConnectionString(bool isDatabaseName) { databaseName = databaseType == DatabaseType.Oracle ? TbSqlOracleDatabase.Text : DdlSqlDatabaseName.SelectedValue; } - return SqlUtils.GetConnectionString(databaseType, TbSqlServer.Text, TranslateUtils.ToBool(DdlIsDefaultPort.SelectedValue), TranslateUtils.ToInt(TbSqlPort.Text), TbSqlUserName.Text, HihSqlHiddenPassword.Value, databaseName); + return WebConfigUtils.GetConnectionString(databaseType, TbSqlServer.Text, TranslateUtils.ToBool(DdlIsDefaultPort.SelectedValue), TranslateUtils.ToInt(TbSqlPort.Text), TbSqlUserName.Text, HihSqlHiddenPassword.Value, databaseName); } private bool CheckLoginValid(out string errorMessage) @@ -350,8 +362,6 @@ private bool InstallDatabase(out string errorMessage) try { - //var errorBuilder = new StringBuilder(); - //DataProvider.DatabaseDao.Install(errorBuilder); SystemManager.InstallDatabase(TbAdminName.Text, TbAdminPassword.Text); return true; @@ -375,7 +385,9 @@ private bool UpdateWebConfig(out string errorMessage) var databaseType = DatabaseTypeUtils.GetEnumType(DdlSqlDatabaseType.SelectedValue); var connectionString = GetConnectionString(true); - WebConfigUtils.UpdateWebConfig(isProtectData, databaseType, connectionString, "SiteServer", StringUtils.GetShortGuid(), false); + WebConfigUtils.UpdateWebConfig(isProtectData, databaseType, connectionString, "api", "SiteServer", "Home", StringUtils.GetShortGuid(), false); + + DataProvider.Reset(); returnValue = true; } diff --git a/SiteServer.BackgroundPages/PageLoading.cs b/net452/SiteServer.BackgroundPages/PageLoading.cs similarity index 100% rename from SiteServer.BackgroundPages/PageLoading.cs rename to net452/SiteServer.BackgroundPages/PageLoading.cs diff --git a/net452/SiteServer.BackgroundPages/PageLogout.cs b/net452/SiteServer.BackgroundPages/PageLogout.cs new file mode 100644 index 000000000..69309cdec --- /dev/null +++ b/net452/SiteServer.BackgroundPages/PageLogout.cs @@ -0,0 +1,18 @@ +using System; +using SiteServer.Utils; + +namespace SiteServer.BackgroundPages +{ + public class PageLogout : BasePage + { + protected override bool IsAccessable => true; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + AuthRequest.AdminLogout(); + PageUtils.Redirect(PageUtils.GetLoginUrl()); + } + } +} diff --git a/net452/SiteServer.BackgroundPages/PageMain.cs b/net452/SiteServer.BackgroundPages/PageMain.cs new file mode 100644 index 000000000..1f780974b --- /dev/null +++ b/net452/SiteServer.BackgroundPages/PageMain.cs @@ -0,0 +1,391 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Text; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Cms; +using SiteServer.BackgroundPages.Settings; +using SiteServer.CMS.Api; +using SiteServer.CMS.Api.Preview; +using SiteServer.CMS.Core; +using SiteServer.CMS.Model; +using System.Linq; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.DataCache; +using SiteServer.CMS.Plugin.Impl; + +namespace SiteServer.BackgroundPages +{ + public class PageMain : BasePageCms + { + protected override bool IsSinglePage => true; + + public string InnerApiUrl => ApiManager.InnerApiUrl.TrimEnd('/'); + + public static string GetRedirectUrl() + { + return PageUtils.GetSiteServerUrl(nameof(PageMain), null); + } + + public static string GetRedirectUrl(int siteId) + { + return PageUtils.GetSiteServerUrl(nameof(PageMain), new NameValueCollection + { + {"siteId", siteId.ToString()} + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + var isLeft = false; + var adminInfo = AuthRequest.AdminInfo; + var permissions = AuthRequest.AdminPermissionsImpl; + + var pageSiteId = SiteId; + var currentSiteId = 0; + var siteIdList = permissions.GetSiteIdList(); + var siteInfoList = new List(); + SiteInfo rootSiteInfo = null; + foreach (var theSiteId in siteIdList) + { + var siteInfo = SiteManager.GetSiteInfo(theSiteId); + if (siteInfo == null) continue; + if (siteInfo.IsRoot) + { + rootSiteInfo = siteInfo; + } + siteInfoList.Add(siteInfo); + } + + if (siteIdList.Contains(pageSiteId)) + { + currentSiteId = pageSiteId; + } + else if (siteIdList.Contains(adminInfo.SiteId)) + { + currentSiteId = adminInfo.SiteId; + } + + if (currentSiteId == 0 || !SiteManager.IsExists(currentSiteId) || !siteIdList.Contains(currentSiteId)) + { + if (siteIdList.Count > 0) + { + currentSiteId = siteIdList[0]; + } + } + + var currentSiteInfo = SiteManager.GetSiteInfo(currentSiteId); + var addedSiteIdList = new List(); + + if (currentSiteInfo != null && currentSiteInfo.Id > 0) + { + if (pageSiteId == 0) + { + PageUtils.Redirect(GetRedirectUrl(currentSiteInfo.Id)); + return; + } + } + else + { + if (permissions.IsConsoleAdministrator) + { + PageUtils.Redirect(PageSiteAdd.GetRedirectUrl()); + return; + } + } + + if (currentSiteInfo != null && currentSiteInfo.Id > 0) + { + var permissionList = new List(permissions.PermissionList); + + if (permissions.HasSitePermissions(currentSiteInfo.Id)) + { + var websitePermissionList = permissions.GetSitePermissions(currentSiteInfo.Id); + if (websitePermissionList != null) + { + isLeft = true; + permissionList.AddRange(websitePermissionList); + } + } + + var channelPermissions = permissions.GetChannelPermissions(currentSiteInfo.Id); + if (channelPermissions.Count > 0) + { + isLeft = true; + permissionList.AddRange(channelPermissions); + } + + //LtlLeftManagement.Text = + // NavigationTree.BuildNavigationTree(currentSiteInfo.Id, ConfigManager.TopMenu.IdSite, + // permissionList); + + //LtlLeftFunctions.Text = NavigationTree.BuildNavigationTree(currentSiteInfo.Id, string.Empty, + // permissionList); + + if (adminInfo.SiteId != currentSiteInfo.Id) + { + DataProvider.AdministratorDao.UpdateSiteId(adminInfo, currentSiteInfo.Id); + } + } + + //LtlTopMenus.Text = isLeft + // ? GetTopMenuSitesHtml(permissions, siteInfoList, rootSiteInfo, addedSiteIdList, currentSiteInfo) + + // GetTopMenuLinksHtml(currentSiteInfo) + GetTopMenusHtml(permissions, pageSiteId) + // : GetTopMenusHtml(permissions, pageSiteId); + } + + private static void AddSite(StringBuilder builder, SiteInfo siteInfoToAdd, Dictionary> parentWithChildren, int level, List addedSiteIdList, SiteInfo currentSiteInfo) + { + if (addedSiteIdList.Contains(siteInfoToAdd.Id)) return; + + var loadingUrl = PageUtils.GetLoadingUrl(GetRedirectUrl(siteInfoToAdd.Id)); + + if (parentWithChildren.ContainsKey(siteInfoToAdd.Id)) + { + var children = parentWithChildren[siteInfoToAdd.Id]; + + builder.Append($@" +
  • + {siteInfoToAdd.SiteName} +
      +"); + + level++; + + var list = children.OrderByDescending(o => o.Taxis).ToList(); + + foreach (var subSiteInfo in list) + { + AddSite(builder, subSiteInfo, parentWithChildren, level, addedSiteIdList, currentSiteInfo); + } + + builder.Append(@" +
    +
  • "); + } + else + { + builder.Append( + $@"
  • {siteInfoToAdd.SiteName}
  • "); + } + + addedSiteIdList.Add(siteInfoToAdd.Id); + } + + private static string GetTopMenuSitesHtml(PermissionsImpl permissions, List siteInfoList, SiteInfo rootSiteInfo, List addedSiteIdList, SiteInfo currentSiteInfo) + { + if (siteInfoList.Count == 0) + { + return string.Empty; + } + + //操作者拥有的站点列表 + var mySiteInfoList = new List(); + + var parentWithChildren = new Dictionary>(); + + if (permissions.IsSystemAdministrator) + { + foreach (var siteInfo in siteInfoList) + { + AddToMySiteInfoList(mySiteInfoList, siteInfo, parentWithChildren); + } + } + else + { + var permissionChannelIdList = permissions.ChannelPermissionChannelIdList; + foreach (var siteInfo in siteInfoList) + { + var showSite = IsShowSite(siteInfo.Id, permissionChannelIdList); + if (showSite) + { + AddToMySiteInfoList(mySiteInfoList, siteInfo, parentWithChildren); + } + } + } + + var builder = new StringBuilder(); + + if (rootSiteInfo != null || mySiteInfoList.Count > 0) + { + if (rootSiteInfo != null) + { + AddSite(builder, rootSiteInfo, parentWithChildren, 0, addedSiteIdList, currentSiteInfo); + } + + if (mySiteInfoList.Count > 0) + { + var count = 0; + var list = mySiteInfoList.OrderByDescending(o => o.Taxis).ToList(); + foreach (var siteInfo in list) + { + if (siteInfo.IsRoot == false) + { + count++; + AddSite(builder, siteInfo, parentWithChildren, 0, addedSiteIdList, currentSiteInfo); + } + if (count == 13) + { + break; + } + } + builder.Append( + $@"
  • 全部站点...
  • "); + } + } + + var clazz = "has-submenu"; + var menuText = "站点管理"; + if (currentSiteInfo != null && currentSiteInfo.Id > 0) + { + clazz = "has-submenu active"; + menuText = currentSiteInfo.SiteName; + if (currentSiteInfo.ParentId > 0) + { + menuText += $" ({SiteManager.GetSiteLevel(currentSiteInfo.Id) + 1}级)"; + } + } + + return $@"
  • + {menuText} +
      + {builder} +
    +
  • "; + } + + private static string GetTopMenuLinksHtml(SiteInfo currentSiteInfo) + { + if (currentSiteInfo == null || currentSiteInfo.Id <= 0) + { + return string.Empty; + } + + var builder = new StringBuilder(); + + builder.Append( + $@"
  • 访问站点
  • "); + builder.Append( + $@"
  • 预览站点
  • "); + + return $@"
  • + 站点链接 +
      + {builder} +
    +
  • "; + } + + private static string GetTopMenusHtml(PermissionsImpl permissions, int siteId) + { + var topMenuTabs = TabManager.GetTopMenuTabs(); + + if (topMenuTabs == null || topMenuTabs.Count == 0) + { + return string.Empty; + } + + var permissionList = new List(); + if (permissions.HasSitePermissions(siteId)) + { + var websitePermissionList = permissions.GetSitePermissions(siteId); + if (websitePermissionList != null) + { + permissionList.AddRange(websitePermissionList); + } + } + + permissionList.AddRange(permissions.PermissionList); + + var builder = new StringBuilder(); + foreach (var tab in topMenuTabs) + { + if (!permissions.IsConsoleAdministrator && !TabManager.IsValid(tab, permissionList)) continue; + + var tabs = TabManager.GetTabList(tab.Id, 0); + var tabsBuilder = new StringBuilder(); + foreach (var parent in tabs) + { + if (!permissions.IsConsoleAdministrator && !TabManager.IsValid(parent, permissionList)) continue; + + var hasChildren = parent.Children != null && parent.Children.Length > 0; + + var parentUrl = !string.IsNullOrEmpty(parent.Href) ? PageUtils.GetLoadingUrl(parent.Href) : "javascript:;"; + var parentTarget = !string.IsNullOrEmpty(parent.Target) ? parent.Target : "right"; + + if (hasChildren) + { + tabsBuilder.Append($@" +
  • + {parent.Text} +
      +"); + + if (parent.Children != null && parent.Children.Length > 0) + { + foreach (var childTab in parent.Children) + { + var childTarget = !string.IsNullOrEmpty(childTab.Target) ? childTab.Target : "right"; + tabsBuilder.Append($@"
    • {childTab.Text}
    • "); + } + } + + tabsBuilder.Append(@" +
    +
  • "); + } + else + { + tabsBuilder.Append( + $@"
  • {parent.Text}
  • "); + } + } + + var url = !string.IsNullOrEmpty(tab.Href) ? PageUtils.ParseNavigationUrl(tab.Href) : "javascript:;"; + var target = !string.IsNullOrEmpty(tab.Target) ? tab.Target : "right"; + + builder.Append( + $@"
  • + {tab.Text} +
      + {tabsBuilder} +
    +
  • "); + } + + return builder.ToString(); + } + + private static bool IsShowSite(int siteId, List permissionChannelIdList) + { + foreach (var permissionChannelId in permissionChannelIdList) + { + if (ChannelManager.IsAncestorOrSelf(siteId, siteId, permissionChannelId)) + { + return true; + } + } + return false; + } + + private static void AddToMySiteInfoList(List mySiteInfoList, SiteInfo mySiteInfo, Dictionary> parentWithChildren) + { + if (mySiteInfo == null) return; + + if (mySiteInfo.ParentId > 0) + { + var children = new List(); + if (parentWithChildren.ContainsKey(mySiteInfo.ParentId)) + { + children = parentWithChildren[mySiteInfo.ParentId]; + } + children.Add(mySiteInfo); + parentWithChildren[mySiteInfo.ParentId] = children; + } + mySiteInfoList.Add(mySiteInfo); + } + } +} diff --git a/SiteServer.BackgroundPages/PageRedirect.cs b/net452/SiteServer.BackgroundPages/PageRedirect.cs similarity index 83% rename from SiteServer.BackgroundPages/PageRedirect.cs rename to net452/SiteServer.BackgroundPages/PageRedirect.cs index cebab9dbe..1f0be5ab9 100644 --- a/SiteServer.BackgroundPages/PageRedirect.cs +++ b/net452/SiteServer.BackgroundPages/PageRedirect.cs @@ -3,6 +3,7 @@ using SiteServer.CMS.Api.Preview; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.DataCache; namespace SiteServer.BackgroundPages { @@ -39,12 +40,21 @@ public static string GetRedirectUrlToContent(int siteId, int channelId, int cont }); } - public static string GetRedirectUrlToFile(int siteId, int templateId) + public static string GetRedirectUrlToFile(int siteId, int fileTemplateId) { return PageUtils.GetSiteServerUrl(nameof(PageRedirect), new NameValueCollection { {nameof(siteId), siteId.ToString() }, - {nameof(templateId), templateId.ToString() } + {nameof(fileTemplateId), fileTemplateId.ToString() } + }); + } + + public static string GetRedirectUrlToSpecial(int siteId, int specialId) + { + return PageUtils.GetSiteServerUrl(nameof(PageRedirect), new NameValueCollection + { + {nameof(siteId), siteId.ToString() }, + {nameof(specialId), specialId.ToString() } }); } @@ -53,7 +63,8 @@ public void Page_Load(object sender, EventArgs e) var siteId = TranslateUtils.ToInt(Request.QueryString["siteId"]); var channelId = TranslateUtils.ToInt(Request.QueryString["channelId"]); var contentId = TranslateUtils.ToInt(Request.QueryString["contentId"]); - var templateId = TranslateUtils.ToInt(Request.QueryString["templateId"]); + var fileTemplateId = TranslateUtils.ToInt(Request.QueryString["fileTemplateId"]); + var specialId = TranslateUtils.ToInt(Request.QueryString["specialId"]); var siteInfo = SiteManager.GetSiteInfo(siteId); var url = string.Empty; var isLocal = siteInfo.Additional.IsSeparatedWeb || siteInfo.Additional.IsSeparatedAssets; @@ -68,9 +79,13 @@ public void Page_Load(object sender, EventArgs e) var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); url = PageUtility.GetChannelUrl(siteInfo, nodeInfo, isLocal); } - else if (siteId > 0 && templateId > 0) + else if (siteId > 0 && fileTemplateId > 0) + { + url = PageUtility.GetFileUrl(siteInfo, fileTemplateId, isLocal); + } + else if (siteId > 0 && specialId > 0) { - url = PageUtility.GetFileUrl(siteInfo, templateId, isLocal); + url = PageUtility.GetSpecialUrl(siteInfo, specialId, isLocal); } else if (siteId > 0) { diff --git a/SiteServer.BackgroundPages/PageSyncDatabase.cs b/net452/SiteServer.BackgroundPages/PageSyncDatabase.cs similarity index 79% rename from SiteServer.BackgroundPages/PageSyncDatabase.cs rename to net452/SiteServer.BackgroundPages/PageSyncDatabase.cs index 57b79e648..7aa0d24c1 100644 --- a/SiteServer.BackgroundPages/PageSyncDatabase.cs +++ b/net452/SiteServer.BackgroundPages/PageSyncDatabase.cs @@ -1,15 +1,15 @@ using System; +using System.Web.UI; using SiteServer.CMS.Api; using SiteServer.CMS.Api.Sys.Packaging; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.DataCache; namespace SiteServer.BackgroundPages { - public class PageSyncDatabase : BasePage + public class PageSyncDatabase : Page { - protected override bool IsSinglePage => true; - public static string GetRedirectUrl() { return PageUtils.GetSiteServerUrl(nameof(PageSyncDatabase), null); @@ -17,7 +17,7 @@ public static string GetRedirectUrl() public string UpdateDatabaseApiUrl => ApiRouteSyncDatabase.GetUrl(ApiManager.InnerApiUrl); - public string AdminUrl => PageUtils.GetAdminDirectoryUrl(string.Empty); + public string AdminUrl => PageUtils.GetAdminUrl(string.Empty); public void Page_Load(object sender, EventArgs e) { @@ -25,7 +25,7 @@ public void Page_Load(object sender, EventArgs e) if (SystemManager.IsNeedInstall()) { - Page.Response.Write("系统未安装,向导被禁用"); + Page.Response.Write("系统未安装,向导被禁用!"); Page.Response.End(); } } diff --git a/net452/SiteServer.BackgroundPages/PageTest.cs b/net452/SiteServer.BackgroundPages/PageTest.cs new file mode 100644 index 000000000..15e97709f --- /dev/null +++ b/net452/SiteServer.BackgroundPages/PageTest.cs @@ -0,0 +1,159 @@ +using System; +using System.Collections.Generic; +using System.Web.UI; +using System.Web.UI.WebControls; +using Datory; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.BackgroundPages +{ + public class MyTableInfo + { + public List Columns { get; set; } + public int TotalCount { get; set; } + public List RowFiles { get; set; } + } + + public class PageTest : Page + { + public Literal LtlContent; + + public void Page_Load(object sender, EventArgs e) + { + var json = @"{ + ""columns"": [ + { + ""attributeName"": ""IsAbolition"", + ""dataType"": ""VarChar"", + ""dataLength"": 10, + ""isPrimaryKey"": false, + ""isIdentity"": false, + ""inputStyle"": { + ""inputType"": ""Radio"", + ""displayName"": ""是否废止"", + ""helpText"": null, + ""listItems"": [ + { + ""text"": ""是"", + ""value"": ""True"", + ""selected"": false + }, + { + ""text"": ""否"", + ""value"": ""False"", + ""selected"": true + } + ], + ""defaultValue"": null, + ""isRequired"": true, + ""validateType"": null, + ""minNum"": 0, + ""maxNum"": 0, + ""regExp"": null, + ""width"": null, + ""height"": null + } + } + ], + ""totalCount"": 796, + ""rowFiles"": [ + ""1.json"", + ""2.json"" + ] +}"; + + var tableInfo = TranslateUtils.JsonDeserialize(json); + + LtlContent.Text = ""; + } + + // MODEL Reference + // public void Page_Load(object sender, EventArgs e) + // { + // var builder = new StringBuilder(); + // foreach (var provider in DataProvider.AllProviders) + // { + // if (string.IsNullOrEmpty(provider.TableName) || provider.TableColumns == null || + // provider.TableColumns.Count == 0) continue; + + // builder.Append($@"{provider.TableName}

    + //字段 | 数据类型 | 数据大小 | 说明3
    + //------ | ------ | ------ | ------
    + //"); + // foreach (var column in provider.TableColumns) + // { + // builder.Append($"{column.AttributeName} | {column.DataType} | {(column.DataLength == 0 ? string.Empty : column.DataLength.ToString())} | {(column.IsIdentity ? "自增长" : string.Empty) + (column.IsPrimaryKey ? "主键" : string.Empty)}
    "); + // } + + // builder.Append("

    "); + // } + + // builder.Append($@"model_Content

    + //字段 | 数据类型 | 数据大小 | 说明
    + //------ | ------ | ------ | ------
    + //"); + // foreach (var column in DataProvider.ContentRepository.TableColumns) + // { + // builder.Append($"{column.AttributeName} | {column.DataType} | {(column.DataLength == 0 ? string.Empty : column.DataLength.ToString())} | {(column.IsIdentity ? "自增长" : string.Empty) + (column.IsPrimaryKey ? "主键" : string.Empty)}
    "); + // } + + // LtlContent.Text = builder.ToString(); + // } + + // STL Reference + //public void Page_Load(object sender, EventArgs e) + //{ + // var _elementName = Request.QueryString["name"]; + + // Type elementType; + // if (StlAll.Elements.TryGetValue(_elementName, out elementType)) + // { + // var elementBuilder = new StringBuilder(); + // var tableBuilder = new StringBuilder(); + + // var elementName = _elementName.Replace("stl:", string.Empty); + + // var fields = elementType.GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); + // foreach (var field in fields) + // { + // var stlAttribute = + // (StlAttributeAttribute)Attribute.GetCustomAttribute(field, typeof(StlAttributeAttribute)); + + // if (stlAttribute != null) + // { + // var attrName = field.Name.ToCamelCase(); + + // elementBuilder.Append($@" {attrName}=""{stlAttribute.Title}""
    "); + + // tableBuilder.Append($@"|[{attrName}]({elementName}/attributes?id={attrName}) | {stlAttribute.Title} |
    "); + // } + // } + + // if (elementName == "channels" || elementName == "contents" || elementName == "each" || elementName == "sites" || elementName == "sqlContents") + // { + // fields = typeof(StlListBase).GetFields(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic); + // foreach (var field in fields) + // { + // var stlAttribute = + // (StlAttributeAttribute)Attribute.GetCustomAttribute(field, typeof(StlAttributeAttribute)); + + // if (stlAttribute != null) + // { + // var attrName = field.Name.ToCamelCase(); + + // elementBuilder.Append($@" {attrName}=""{stlAttribute.Title}""
    "); + + // tableBuilder.Append($@"|[{attrName}]({elementName}/attributes?id={attrName}) | {stlAttribute.Title} |
    "); + // } + // } + // } + + // if (elementBuilder.Length > 0) elementBuilder.Length -= 6; + + // LtlContent.Text = $"<stl:{elementName}
    {elementBuilder}>
    </stl:{elementName}>" + "


    " + tableBuilder; + + // } + //} + } +} diff --git a/SiteServer.BackgroundPages/PageUpdateSystem.cs b/net452/SiteServer.BackgroundPages/PageUpdateSystem.cs similarity index 80% rename from SiteServer.BackgroundPages/PageUpdateSystem.cs rename to net452/SiteServer.BackgroundPages/PageUpdateSystem.cs index 19ef417ae..3dd1ca957 100644 --- a/SiteServer.BackgroundPages/PageUpdateSystem.cs +++ b/net452/SiteServer.BackgroundPages/PageUpdateSystem.cs @@ -5,6 +5,7 @@ using SiteServer.CMS.Api.Sys.Packaging; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.DataCache; using SiteServer.CMS.Packaging; namespace SiteServer.BackgroundPages @@ -24,7 +25,7 @@ public static string GetRedirectUrl() public string InstalledVersion => SystemManager.Version; - public string AdminUrl => PageUtils.GetAdminDirectoryUrl(string.Empty); + public string AdminUrl => PageUtils.GetAdminUrl(string.Empty); public string DownloadApiUrl => ApiRouteDownload.GetUrl(ApiManager.InnerApiUrl); @@ -36,6 +37,13 @@ public void Page_Load(object sender, EventArgs e) { if (IsPostBack) return; + if (!AuthRequest.AdminPermissionsImpl.IsConsoleAdministrator) + { + Page.Response.Write("非授权管理员,向导被禁用"); + Page.Response.End(); + return; + } + if (SystemManager.IsNeedInstall()) { Page.Response.Write("系统未安装,向导被禁用"); diff --git a/SiteServer.BackgroundPages/PageValidateCode.cs b/net452/SiteServer.BackgroundPages/PageValidateCode.cs similarity index 100% rename from SiteServer.BackgroundPages/PageValidateCode.cs rename to net452/SiteServer.BackgroundPages/PageValidateCode.cs diff --git a/net452/SiteServer.BackgroundPages/Plugins/PageAdd.cs b/net452/SiteServer.BackgroundPages/Plugins/PageAdd.cs new file mode 100644 index 000000000..4960edf16 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Plugins/PageAdd.cs @@ -0,0 +1,39 @@ +using System; +using System.Linq; +using System.Web.UI.WebControls; +using SiteServer.CMS.Core; +using SiteServer.CMS.DataCache; +using SiteServer.CMS.Plugin; +using SiteServer.Utils; + +namespace SiteServer.BackgroundPages.Plugins +{ + public class PageAdd : BasePage + { + public string PackageIds + { + get + { + var dict = PluginManager.GetPluginIdAndVersionDict(); + + var list = dict.Keys.ToList(); + + return TranslateUtils.ObjectCollectionToString(list); + } + } + + public static string GetRedirectUrl() + { + return PageUtils.GetPluginsUrl(nameof(PageAdd), null); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + if (Page.IsPostBack) return; + + VerifySystemPermissions(ConfigManager.PluginsPermissions.Add); + } + } +} diff --git a/SiteServer.BackgroundPages/Plugins/PageConfig.cs b/net452/SiteServer.BackgroundPages/Plugins/PageConfig.cs similarity index 96% rename from SiteServer.BackgroundPages/Plugins/PageConfig.cs rename to net452/SiteServer.BackgroundPages/Plugins/PageConfig.cs index 585017b31..070001ee0 100644 --- a/SiteServer.BackgroundPages/Plugins/PageConfig.cs +++ b/net452/SiteServer.BackgroundPages/Plugins/PageConfig.cs @@ -19,7 +19,7 @@ // private string _pluginId; - // public static string GetRedirectUrl(string pluginId) + // public static string GetPageUrl(string pluginId) // { // return PageUtils.GetPluginsUrl(nameof(PageConfig), new NameValueCollection // { @@ -35,7 +35,7 @@ // if (Page.IsPostBack) return; - // VerifyAdministratorPermissions(ConfigManager.Permissions.Plugins.Management); + // VerifySystemPermissions(ConfigManager.Permissions.Plugins.Management); // var metadata = PluginManager.GetMetadata(_pluginId); // var isDefault = string.IsNullOrEmpty(metadata.DatabaseType) && @@ -79,7 +79,7 @@ // foreach (var str in connectionString.Split(';')) // { // var arr = str.Split('='); - // if (arr.Length == 2) + // if (arr.DataLength == 2) // { // var name = StringUtils.Trim(arr[0]); // var value = StringUtils.Trim(arr[1]); @@ -196,7 +196,7 @@ // public void Return_OnClick(object sender, EventArgs e) // { - // PageUtils.Redirect(PageManagement.GetRedirectUrl()); + // PageUtils.Redirect(PageManagement.GetPageUrl()); // } //} } diff --git a/SiteServer.BackgroundPages/Plugins/PageManagement.cs b/net452/SiteServer.BackgroundPages/Plugins/PageManagement.cs similarity index 95% rename from SiteServer.BackgroundPages/Plugins/PageManagement.cs rename to net452/SiteServer.BackgroundPages/Plugins/PageManagement.cs index 02e68bc6c..a5c582dd2 100644 --- a/SiteServer.BackgroundPages/Plugins/PageManagement.cs +++ b/net452/SiteServer.BackgroundPages/Plugins/PageManagement.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Web.UI.WebControls; using SiteServer.CMS.Core; +using SiteServer.CMS.DataCache; using SiteServer.Utils; using SiteServer.CMS.Plugin; @@ -86,7 +87,7 @@ public void Page_Load(object sender, EventArgs e) if (Page.IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.PluginsPermissions.Management); + VerifySystemPermissions(ConfigManager.PluginsPermissions.Management); } public void BtnReload_Click(object sender, EventArgs e) @@ -113,7 +114,7 @@ public void BtnReload_Click(object sender, EventArgs e) // var ltlCmd = (Literal)e.Item.FindControl("ltlCmd"); // ltlLogo.Text = $@""; -// ltlPluginId.Text = $@"{pluginInfo.Id}"; +// ltlPluginId.Text = $@"{pluginInfo.Id}"; // ltlPluginName.Text = pluginInfo.Plugin.Title; // ltlVersion.Text = pluginInfo.Plugin.Version; // if (pluginInfo.Plugin.Owners != null) @@ -163,7 +164,7 @@ public void BtnReload_Click(object sender, EventArgs e) // var ltlErrorMessage = (Literal)e.Item.FindControl("ltlErrorMessage"); // var ltlCmd = (Literal)e.Item.FindControl("ltlCmd"); -// ltlPluginId.Text = $@"{pluginInfo.Id}"; +// ltlPluginId.Text = $@"{pluginInfo.Id}"; // ltlErrorMessage.Text = pluginInfo.ErrorMessage; diff --git a/SiteServer.BackgroundPages/Plugins/PageView.cs b/net452/SiteServer.BackgroundPages/Plugins/PageView.cs similarity index 76% rename from SiteServer.BackgroundPages/Plugins/PageView.cs rename to net452/SiteServer.BackgroundPages/Plugins/PageView.cs index 604e4e9b5..10bb35274 100644 --- a/SiteServer.BackgroundPages/Plugins/PageView.cs +++ b/net452/SiteServer.BackgroundPages/Plugins/PageView.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Specialized; using SiteServer.CMS.Core; +using SiteServer.CMS.DataCache; using SiteServer.Utils; using SiteServer.CMS.Plugin; @@ -40,18 +41,9 @@ public void Page_Load(object sender, EventArgs e) _pluginId = AuthRequest.GetQueryString("pluginId"); _returnUrl = AuthRequest.GetQueryString("returnUrl"); - if (AuthRequest.IsQueryExists("install")) - { - PageUtils.Redirect(PageInstall.GetRedirectUrl(false, _pluginId)); - } - else if (AuthRequest.IsQueryExists("update")) - { - PageUtils.Redirect(PageInstall.GetRedirectUrl(true, _pluginId)); - } - if (Page.IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.PluginsPermissions.Add, ConfigManager.PluginsPermissions.Management); + VerifySystemPermissions(ConfigManager.PluginsPermissions.Add, ConfigManager.PluginsPermissions.Management); } public void Return_Click(object sender, EventArgs e) diff --git a/net452/SiteServer.BackgroundPages/Properties/AssemblyInfo.cs b/net452/SiteServer.BackgroundPages/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..5e9a74590 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("SiteServer.BackgroundPages")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SiteServer.BackgroundPages")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("aab355c2-8dd2-43d3-880c-eb9b51a59971")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("0.0.0")] +[assembly: AssemblyFileVersion("0.0.0")] +[assembly: AssemblyInformationalVersion("0.0.0")] diff --git a/SiteServer.BackgroundPages/Settings/ModalAdminSelect.cs b/net452/SiteServer.BackgroundPages/Settings/ModalAdminSelect.cs similarity index 86% rename from SiteServer.BackgroundPages/Settings/ModalAdminSelect.cs rename to net452/SiteServer.BackgroundPages/Settings/ModalAdminSelect.cs index 0f7ea745b..8b732b208 100644 --- a/SiteServer.BackgroundPages/Settings/ModalAdminSelect.cs +++ b/net452/SiteServer.BackgroundPages/Settings/ModalAdminSelect.cs @@ -3,7 +3,9 @@ using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Settings { @@ -19,7 +21,7 @@ public class ModalAdminSelect : BasePage public static string GetShowPopWinString(int departmentId, string scriptName) { - return LayerUtils.GetOpenScript("管理员选择", PageUtils.GetSettingsUrl(nameof(ModalAdminSelect), new NameValueCollection + return LayerUtils.GetOpenScript("管理员选择", FxUtils.GetSettingsUrl(nameof(ModalAdminSelect), new NameValueCollection { {"departmentID", departmentId.ToString()}, {"scriptName", scriptName} @@ -30,7 +32,7 @@ public void Page_Load(object sender, EventArgs e) { _departmentId = AuthRequest.GetQueryInt("departmentID"); _scriptName = AuthRequest.GetQueryString("ScriptName"); - var url = PageUtils.GetSettingsUrl(nameof(ModalAdminSelect), new NameValueCollection + var url = FxUtils.GetSettingsUrl(nameof(ModalAdminSelect), new NameValueCollection { {"scriptName", _scriptName} }); @@ -51,7 +53,7 @@ public void Page_Load(object sender, EventArgs e) if (_departmentId > 0) { LtlDepartment.Text = DepartmentManager.GetDepartmentName(_departmentId); - RptUser.DataSource = DataProvider.AdministratorDao.GetUserNameList(_departmentId, false); + RptUser.DataSource = DataProvider.Administrator.GetUserNameList(_departmentId); RptUser.ItemDataBound += RptUser_ItemDataBound; RptUser.DataBind(); } @@ -67,7 +69,7 @@ public void Page_Load(object sender, EventArgs e) public void BindGrid() { - RptDepartment.DataSource = DataProvider.DepartmentDao.GetIdListByParentId(0); + RptDepartment.DataSource = DataProvider.Department.GetIdListByParentId(0); RptDepartment.ItemDataBound += rptDepartment_ItemDataBound; RptDepartment.DataBind(); } @@ -91,7 +93,7 @@ private void RptUser_ItemDataBound(object sender, RepeaterItemEventArgs e) var ltlUrl = e.Item.FindControl("ltlUrl") as Literal; - var url = PageUtils.GetSettingsUrl(nameof(ModalAdminSelect), new NameValueCollection + var url = FxUtils.GetSettingsUrl(nameof(ModalAdminSelect), new NameValueCollection { {"scriptName", _scriptName}, {"UserName", userName} diff --git a/SiteServer.BackgroundPages/Settings/ModalAreaAdd.cs b/net452/SiteServer.BackgroundPages/Settings/ModalAreaAdd.cs similarity index 86% rename from SiteServer.BackgroundPages/Settings/ModalAreaAdd.cs rename to net452/SiteServer.BackgroundPages/Settings/ModalAreaAdd.cs index 5bc0220aa..557711810 100644 --- a/SiteServer.BackgroundPages/Settings/ModalAreaAdd.cs +++ b/net452/SiteServer.BackgroundPages/Settings/ModalAreaAdd.cs @@ -1,8 +1,11 @@ using System; using System.Collections.Specialized; using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.Utils; namespace SiteServer.BackgroundPages.Settings @@ -19,7 +22,7 @@ public class ModalAreaAdd : BasePage public static string GetOpenWindowStringToAdd(string returnUrl) { - return LayerUtils.GetOpenScript("添加区域", PageUtils.GetSettingsUrl(nameof(ModalAreaAdd), new NameValueCollection + return LayerUtils.GetOpenScript("添加区域", FxUtils.GetSettingsUrl(nameof(ModalAreaAdd), new NameValueCollection { {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} }), 460, 360); @@ -27,7 +30,7 @@ public static string GetOpenWindowStringToAdd(string returnUrl) public static string GetOpenWindowStringToEdit(int areaId, string returnUrl) { - return LayerUtils.GetOpenScript("修改区域", PageUtils.GetSettingsUrl(nameof(ModalAreaAdd), new NameValueCollection + return LayerUtils.GetOpenScript("修改区域", FxUtils.GetSettingsUrl(nameof(ModalAreaAdd), new NameValueCollection { {"AreaID", areaId.ToString()}, {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} @@ -57,7 +60,7 @@ public void Page_Load(object sender, EventArgs e) foreach (var theAreaId in areaIdList) { var areaInfo = AreaManager.GetAreaInfo(theAreaId); - var listitem = new ListItem(GetTitle(areaInfo.Id, areaInfo.AreaName, areaInfo.ParentsCount, areaInfo.IsLastNode), theAreaId.ToString()); + var listitem = new ListItem(GetTitle(areaInfo.Id, areaInfo.AreaName, areaInfo.ParentsCount, areaInfo.LastNode), theAreaId.ToString()); DdlParentId.Items.Add(listitem); } } @@ -109,16 +112,15 @@ public override void Submit_OnClick(object sender, EventArgs e) ParentId = TranslateUtils.ToInt(DdlParentId.SelectedValue) }; - DataProvider.AreaDao.Insert(areaInfo); + DataProvider.Area.Insert(areaInfo); } else { var areaInfo = AreaManager.GetAreaInfo(_areaId); areaInfo.AreaName = TbAreaName.Text; - areaInfo.ParentId = TranslateUtils.ToInt(DdlParentId.SelectedValue); - DataProvider.AreaDao.Update(areaInfo); + DataProvider.Area.Update(areaInfo); } AuthRequest.AddAdminLog("维护区域信息"); diff --git a/SiteServer.BackgroundPages/Settings/ModalChangeSiteType.cs b/net452/SiteServer.BackgroundPages/Settings/ModalChangeSiteType.cs similarity index 87% rename from SiteServer.BackgroundPages/Settings/ModalChangeSiteType.cs rename to net452/SiteServer.BackgroundPages/Settings/ModalChangeSiteType.cs index 8e1a0d1f5..c12545ce7 100644 --- a/SiteServer.BackgroundPages/Settings/ModalChangeSiteType.cs +++ b/net452/SiteServer.BackgroundPages/Settings/ModalChangeSiteType.cs @@ -3,8 +3,13 @@ using System.Collections.Generic; using System.Collections.Specialized; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; using SiteServer.Plugin; using SiteServer.Utils.IO; @@ -26,9 +31,9 @@ public class ModalChangeSiteType : BasePageCms public static string GetOpenWindowString(int siteId) { var siteInfo = SiteManager.GetSiteInfo(siteId); - var title = siteInfo.IsRoot ? "转移到子目录" : "转移到根目录"; + var title = siteInfo.Root ? "转移到子目录" : "转移到根目录"; return LayerUtils.GetOpenScript(title, - PageUtils.GetSettingsUrl(nameof(ModalChangeSiteType), + FxUtils.GetSettingsUrl(nameof(ModalChangeSiteType), new NameValueCollection { {"SiteId", siteId.ToString()} @@ -39,9 +44,9 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId"); + WebPageUtils.CheckRequestParameter("siteId"); - _isHeadquarters = SiteInfo.IsRoot; + _isHeadquarters = SiteInfo.Root; var selectedList = new List(); @@ -54,7 +59,7 @@ public void Page_Load(object sender, EventArgs e) PhChangeToSite.Visible = true; PhChangeToHeadquarters.Visible = false; var fileSystems = FileManager.GetFileSystemInfoExtendCollection(WebConfigUtils.PhysicalApplicationPath, true); - var siteDirList = DataProvider.SiteDao.GetLowerSiteDirListThatNotIsRoot(); + var siteDirList = DataProvider.Site.GetLowerSiteDirListThatNotIsRoot(); foreach (FileSystemInfoExtend fileSystem in fileSystems) { if (fileSystem.IsDirectory) @@ -79,7 +84,7 @@ public void Page_Load(object sender, EventArgs e) } //主站下的单页模板 - var fileTemplateInfoList = DataProvider.TemplateDao.GetTemplateInfoListByType(SiteId, TemplateType.FileTemplate); + var fileTemplateInfoList = DataProvider.Template.GetTemplateInfoListByType(SiteId, TemplateType.FileTemplate); foreach (var fileT in fileTemplateInfoList) { if (fileT.CreatedFileFullName.StartsWith("@/") || fileT.CreatedFileFullName.StartsWith("~/")) @@ -99,7 +104,7 @@ public void Page_Load(object sender, EventArgs e) foreach (var psId in siteIdList) { var psInfo = SiteManager.GetSiteInfo(psId); - if (psInfo.IsRoot) + if (psInfo.Root) { headquartersExists = true; break; @@ -120,14 +125,14 @@ public void Page_Load(object sender, EventArgs e) } //设置选中的文件以及文件夹 - ControlUtils.SelectMultiItems(CblFilesToSite, selectedList); + SystemWebUtils.SelectMultiItems(CblFilesToSite, selectedList); } public override void Submit_OnClick(object sender, EventArgs e) { if (_isHeadquarters) { - var list = DataProvider.SiteDao.GetLowerSiteDirList(SiteInfo.ParentId); + var list = DataProvider.Site.GetLowerSiteDirList(SiteInfo.ParentId); if (list.IndexOf(TbSiteDir.Text.Trim().ToLower()) != -1) { FailMessage("操作失败,已存在相同的发布路径"); diff --git a/SiteServer.BackgroundPages/Settings/ModalDepartmentAdd.cs b/net452/SiteServer.BackgroundPages/Settings/ModalDepartmentAdd.cs similarity index 89% rename from SiteServer.BackgroundPages/Settings/ModalDepartmentAdd.cs rename to net452/SiteServer.BackgroundPages/Settings/ModalDepartmentAdd.cs index 0ff4b467a..6ac210e82 100644 --- a/SiteServer.BackgroundPages/Settings/ModalDepartmentAdd.cs +++ b/net452/SiteServer.BackgroundPages/Settings/ModalDepartmentAdd.cs @@ -1,8 +1,11 @@ using System; using System.Collections.Specialized; using System.Web.UI.WebControls; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.Utils; namespace SiteServer.BackgroundPages.Settings @@ -22,7 +25,7 @@ public class ModalDepartmentAdd : BasePage public static string GetOpenWindowStringToAdd(string returnUrl) { return LayerUtils.GetOpenScript("添加部门", - PageUtils.GetSettingsUrl(nameof(ModalDepartmentAdd), new NameValueCollection + FxUtils.GetSettingsUrl(nameof(ModalDepartmentAdd), new NameValueCollection { {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} }), 460, 400); @@ -31,7 +34,7 @@ public static string GetOpenWindowStringToAdd(string returnUrl) public static string GetOpenWindowStringToEdit(int departmentId, string returnUrl) { return LayerUtils.GetOpenScript("修改部门", - PageUtils.GetSettingsUrl(nameof(ModalDepartmentAdd), new NameValueCollection + FxUtils.GetSettingsUrl(nameof(ModalDepartmentAdd), new NameValueCollection { {"DepartmentID", departmentId.ToString()}, {"ReturnUrl", StringUtils.ValueToUrl(returnUrl)} @@ -61,7 +64,7 @@ public void Page_Load(object sender, EventArgs e) foreach (var theDepartmentId in departmentIdList) { var departmentInfo = DepartmentManager.GetDepartmentInfo(theDepartmentId); - var listitem = new ListItem(GetTitle(departmentInfo.Id, departmentInfo.DepartmentName, departmentInfo.ParentsCount, departmentInfo.IsLastNode), theDepartmentId.ToString()); + var listitem = new ListItem(GetTitle(departmentInfo.Id, departmentInfo.DepartmentName, departmentInfo.ParentsCount, departmentInfo.LastNode), theDepartmentId.ToString()); DdlParentId.Items.Add(listitem); } } @@ -117,7 +120,7 @@ public override void Submit_OnClick(object sender, EventArgs e) Summary = TbSummary.Text }; - DataProvider.DepartmentDao.Insert(departmentInfo); + DataProvider.Department.Insert(departmentInfo); } else { @@ -125,10 +128,9 @@ public override void Submit_OnClick(object sender, EventArgs e) departmentInfo.DepartmentName = TbDepartmentName.Text; departmentInfo.Code = TbCode.Text; - departmentInfo.ParentId = TranslateUtils.ToInt(DdlParentId.SelectedValue); departmentInfo.Summary = TbSummary.Text; - DataProvider.DepartmentDao.Update(departmentInfo); + DataProvider.Department.Update(departmentInfo); } AuthRequest.AddAdminLog("维护部门信息"); diff --git a/net452/SiteServer.BackgroundPages/Settings/ModalExportMessage.cs b/net452/SiteServer.BackgroundPages/Settings/ModalExportMessage.cs new file mode 100644 index 000000000..eedecb7de --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/ModalExportMessage.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Core.RestRoutes; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.CMS.ImportExport; + +namespace SiteServer.BackgroundPages.Settings +{ + public class ModalExportMessage : BasePage + { + private string _exportType; + public const string ExportTypeSingleTableStyle = "SingleTableStyle"; + + public static string GetOpenWindowStringToSingleTableStyle(string tableName) + { + return LayerUtils.GetOpenScript("导出数据", + FxUtils.GetSettingsUrl(nameof(ModalExportMessage), new NameValueCollection + { + {"TableName", tableName}, + {"ExportType", ExportTypeSingleTableStyle} + }), 380, 250); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + _exportType = AuthRequest.GetQueryString("ExportType"); + + if (!IsPostBack) + { + var fileName = string.Empty; + try + { + if (_exportType == ExportTypeSingleTableStyle) + { + var tableName = AuthRequest.GetQueryString("TableName"); + fileName = ExportSingleTableStyle(tableName); + } + + var link = new HyperLink(); + var filePath = PathUtils.GetTemporaryFilesPath(fileName); + link.NavigateUrl = ApiRouteActionsDownload.GetUrl(ApiManager.InnerApiUrl, filePath); + link.Text = "下载"; + var successMessage = "成功导出文件!  " + ControlUtils.GetControlRenderHtml(link); + SuccessMessage(successMessage); + } + catch (Exception ex) + { + var failedMessage = "文件导出失败!

    原因为:" + ex.Message; + FailMessage(ex, failedMessage); + } + } + } + + private static string ExportSingleTableStyle(string tableName) + { + return ExportObject.ExportRootSingleTableStyle(tableName); + } + } +} diff --git a/SiteServer.BackgroundPages/Settings/ModalImportZip.cs b/net452/SiteServer.BackgroundPages/Settings/ModalImportZip.cs similarity index 86% rename from SiteServer.BackgroundPages/Settings/ModalImportZip.cs rename to net452/SiteServer.BackgroundPages/Settings/ModalImportZip.cs index 7e749880d..62b4af66f 100644 --- a/SiteServer.BackgroundPages/Settings/ModalImportZip.cs +++ b/net452/SiteServer.BackgroundPages/Settings/ModalImportZip.cs @@ -4,7 +4,10 @@ using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Cms; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Settings @@ -24,7 +27,7 @@ public class ModalImportZip : BasePageCms public static string GetOpenWindowString(string type) { return LayerUtils.GetOpenScript(type == TypeSiteTemplate ? "导入站点模板" : "导入插件", - PageUtils.GetSettingsUrl(nameof(ModalImportZip), new NameValueCollection + FxUtils.GetSettingsUrl(nameof(ModalImportZip), new NameValueCollection { {"type", type} }), 520, 240); @@ -36,8 +39,8 @@ public void Page_Load(object sender, EventArgs e) _type = AuthRequest.GetQueryString("type"); if (Page.IsPostBack) return; - EBooleanUtils.AddListItems(DdlImportType, "上传压缩包并导入", "从指定地址下载压缩包并导入"); - ControlUtils.SelectSingleItemIgnoreCase(DdlImportType, true.ToString()); + FxUtils.AddListItems(DdlImportType, "上传压缩包并导入", "从指定地址下载压缩包并导入"); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlImportType, true.ToString()); PhUpload.Visible = true; PhDownload.Visible = false; @@ -93,7 +96,7 @@ private void ImportSiteTemplate(bool isUpload) HifFile.PostedFile.SaveAs(localFilePath); - ZipUtils.UnpackFiles(localFilePath, directoryPath); + ZipUtils.ExtractZip(localFilePath, directoryPath); LayerUtils.CloseAndRedirect(Page, PageSiteTemplate.GetRedirectUrl()); } @@ -112,7 +115,7 @@ private void ImportSiteTemplate(bool isUpload) return; } - PageUtils.Redirect(ModalProgressBar.GetRedirectUrlStringWithSiteTemplateDownload(0, TbDownloadUrl.Text)); + WebPageUtils.Redirect(ModalProgressBar.GetRedirectUrlStringWithSiteTemplateDownload(0, TbDownloadUrl.Text)); } } } diff --git a/net452/SiteServer.BackgroundPages/Settings/ModalKeywordAdd.cs b/net452/SiteServer.BackgroundPages/Settings/ModalKeywordAdd.cs new file mode 100644 index 000000000..60b8fad1a --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/ModalKeywordAdd.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.Utils; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Settings +{ + public class ModalKeywordAdd : BasePageCms + { + protected TextBox TbKeyword; + protected TextBox TbAlternative; + protected DropDownList DdlGrade; + + private int _keywordId; + + public static string GetOpenWindowStringToAdd() + { + return LayerUtils.GetOpenScript("添加敏感词", FxUtils.GetSettingsUrl(nameof(ModalKeywordAdd), null), 460, 300); + } + + public static string GetOpenWindowStringToEdit(int keywordId) + { + return LayerUtils.GetOpenScript("修改敏感词", + FxUtils.GetSettingsUrl(nameof(ModalKeywordAdd), new NameValueCollection + { + {"KeywordID", keywordId.ToString()} + }), 460, 300); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + _keywordId = AuthRequest.GetQueryInt("KeywordID"); + + if (IsPostBack) return; + + SystemWebUtils.AddListItemsToEKeywordGrade(DdlGrade); + if (_keywordId <= 0) return; + + var keywordInfo = DataProvider.Keyword.Get(_keywordId); + TbKeyword.Text = keywordInfo.Keyword; + TbAlternative.Text = keywordInfo.Alternative; + SystemWebUtils.SelectSingleItem(DdlGrade, EKeywordGradeUtils.GetValue(keywordInfo.KeywordGrade)); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + var isChanged = false; + + if (_keywordId > 0) + { + try + { + var keywordInfo = DataProvider.Keyword.Get(_keywordId); + keywordInfo.Keyword = TbKeyword.Text.Trim(); + keywordInfo.Alternative = TbAlternative.Text.Trim(); + keywordInfo.KeywordGrade = EKeywordGradeUtils.GetEnumType(DdlGrade.SelectedValue); + DataProvider.Keyword.Update(keywordInfo); + + isChanged = true; + } + catch (Exception ex) + { + FailMessage(ex, "修改敏感词失败!"); + } + } + else + { + if (DataProvider.Keyword.IsExists(TbKeyword.Text)) + { + FailMessage("敏感词添加失败,敏感词名称已存在!"); + } + else + { + try + { + var keywordInfo = new KeywordInfo + { + Keyword = TbKeyword.Text.Trim(), + Alternative = TbAlternative.Text.Trim(), + KeywordGrade = EKeywordGradeUtils.GetEnumType(DdlGrade.SelectedValue) + }; + DataProvider.Keyword.Insert(keywordInfo); + isChanged = true; + } + catch (Exception ex) + { + FailMessage(ex, "添加敏感词失败!"); + } + } + } + + if (isChanged) + { + LayerUtils.Close(Page); + } + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Settings/ModalKeywordImport.cs b/net452/SiteServer.BackgroundPages/Settings/ModalKeywordImport.cs new file mode 100644 index 000000000..9b7ede9e8 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/ModalKeywordImport.cs @@ -0,0 +1,86 @@ +using System; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.Utils; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Settings +{ + public class ModalKeywordImport : BasePageCms + { + public DropDownList DdlGrade; + public TextBox TbKeywords; + + public static string GetOpenWindowString() + { + return LayerUtils.GetOpenScript("导入敏感词", + FxUtils.GetSettingsUrl(nameof(ModalKeywordImport), null), 500, 530); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + if (!IsPostBack) + { + SystemWebUtils.AddListItemsToEKeywordGrade(DdlGrade); + } + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + var isChanged = false; + + try + { + var grade = EKeywordGradeUtils.GetEnumType(DdlGrade.SelectedValue); + + var keywordArray = TbKeywords.Text.Split(','); + foreach (var item in keywordArray) + { + if (!string.IsNullOrEmpty(item)) + { + var value = item.Trim(); + string keyword; + var alternative = string.Empty; + + if (value.IndexOf('|') != -1) + { + keyword = value.Split('|')[0]; + alternative = value.Split('|')[1]; + } + else + { + keyword = value; + } + + if (!string.IsNullOrEmpty(keyword) && !DataProvider.Keyword.IsExists(keyword)) + { + var keywordInfo = new KeywordInfo + { + Keyword = keyword, + Alternative = alternative, + KeywordGrade = grade + }; + DataProvider.Keyword.Insert(keywordInfo); + } + } + } + + isChanged = true; + } + catch (Exception ex) + { + FailMessage(ex, "导入敏感词失败"); + } + + if (isChanged) + { + LayerUtils.Close(Page); + } + } + } +} diff --git a/SiteServer.BackgroundPages/Settings/ModalManualUpdateSystem.cs b/net452/SiteServer.BackgroundPages/Settings/ModalManualUpdateSystem.cs similarity index 79% rename from SiteServer.BackgroundPages/Settings/ModalManualUpdateSystem.cs rename to net452/SiteServer.BackgroundPages/Settings/ModalManualUpdateSystem.cs index d9a9a11ac..7c346ce47 100644 --- a/SiteServer.BackgroundPages/Settings/ModalManualUpdateSystem.cs +++ b/net452/SiteServer.BackgroundPages/Settings/ModalManualUpdateSystem.cs @@ -2,8 +2,10 @@ using System.IO; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; -using SiteServer.BackgroundPages.Plugins; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; using SiteServer.Utils; using SiteServer.Utils.Enumerations; @@ -23,7 +25,7 @@ public class ModalManualUpdateSystem : BasePage public static string GetOpenWindowString() { - return LayerUtils.GetOpenScript("手动升级 SiteServer CMS 版本", PageUtils.GetSettingsUrl(nameof(ModalManualUpdateSystem), null), 560, 430); + return LayerUtils.GetOpenScript("手动升级 SiteServer CMS 版本", FxUtils.GetSettingsUrl(nameof(ModalManualUpdateSystem), null), 560, 430); } public void Page_Load(object sender, EventArgs e) @@ -32,8 +34,8 @@ public void Page_Load(object sender, EventArgs e) if (IsPostBack) return; - EBooleanUtils.AddListItems(RblInstallType, "上传升级包", "指定版本号"); - ControlUtils.SelectSingleItem(RblInstallType, true.ToString()); + FxUtils.AddListItems(RblInstallType, "上传升级包", "指定版本号"); + SystemWebUtils.SelectSingleItem(RblInstallType, true.ToString()); } public void RblInstallType_SelectedIndexChanged(object sender, EventArgs e) @@ -65,7 +67,7 @@ private void UpdateByVersion() AuthRequest.AddAdminLog($"手动升级 SiteServer CMS 版本:{TbVersion.Text}"); - LayerUtils.CloseAndRedirect(Page, PageManagement.GetRedirectUrl()); + LayerUtils.CloseAndRedirect(Page, AdminPagesUtils.Plugins.ManageUrl); } private void UpdateByUpload() @@ -80,7 +82,7 @@ private void UpdateByUpload() } var idAndVersion = Path.GetFileNameWithoutExtension(filePath); - var directoryPath = PathUtils.GetPackagesPath(idAndVersion); + var directoryPath = FxUtils.GetPackagesPath(idAndVersion); var localFilePath = PathUtils.Combine(directoryPath, idAndVersion + ".nupkg"); if (!Directory.Exists(directoryPath)) @@ -90,11 +92,11 @@ private void UpdateByUpload() HifFile.PostedFile.SaveAs(localFilePath); - ZipUtils.UnpackFiles(localFilePath, directoryPath); + ZipUtils.ExtractZip(localFilePath, directoryPath); AuthRequest.AddAdminLog("手动升级 SiteServer CMS 版本:" + idAndVersion); - LayerUtils.CloseAndRedirect(Page, PageManagement.GetRedirectUrl()); + LayerUtils.CloseAndRedirect(Page, AdminPagesUtils.Plugins.ManageUrl); } } } diff --git a/net452/SiteServer.BackgroundPages/Settings/ModalPermissionsSet.cs b/net452/SiteServer.BackgroundPages/Settings/ModalPermissionsSet.cs new file mode 100644 index 000000000..399c6dc62 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/ModalPermissionsSet.cs @@ -0,0 +1,237 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Settings +{ + public class ModalPermissionsSet : BasePageCms + { + public DropDownList DdlPredefinedRole; + public PlaceHolder PhSiteId; + public CheckBoxList CblSiteId; + public PlaceHolder PhRoles; + public ListBox LbAvailableRoles; + public ListBox LbAssignedRoles; + + private string _userName = string.Empty; + + public static string GetOpenWindowString(string userName) + { + return LayerUtils.GetOpenScript("权限设置", + FxUtils.GetSettingsUrl(nameof(ModalPermissionsSet), new NameValueCollection + { + {"UserName", userName} + })); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + _userName = AuthRequest.GetQueryString("UserName"); + + if (IsPostBack) return; + + var roles = DataProvider.AdministratorsInRoles.GetRolesForUser(_userName); + if (AuthRequest.AdminPermissionsImpl.IsConsoleAdministrator) + { + DdlPredefinedRole.Items.Add(FxUtils.GetListItem(EPredefinedRole.ConsoleAdministrator, false)); + DdlPredefinedRole.Items.Add(FxUtils.GetListItem(EPredefinedRole.SystemAdministrator, false)); + } + DdlPredefinedRole.Items.Add(FxUtils.GetListItem(EPredefinedRole.Administrator, false)); + + var type = EPredefinedRoleUtils.GetEnumTypeByRoles(roles); + SystemWebUtils.SelectSingleItem(DdlPredefinedRole, EPredefinedRoleUtils.GetValue(type)); + + var adminInfo = AdminManager.GetAdminInfoByUserName(_userName); + var siteIdList = TranslateUtils.StringCollectionToIntList(adminInfo.SiteIdCollection); + + SystemWebUtils.AddListItemsForSite(CblSiteId); + SystemWebUtils.SelectMultiItems(CblSiteId, siteIdList); + + ListBoxDataBind(); + + DdlPredefinedRole_SelectedIndexChanged(null, EventArgs.Empty); + } + + public void DdlPredefinedRole_SelectedIndexChanged(object sender, EventArgs e) + { + if (EPredefinedRoleUtils.Equals(EPredefinedRole.ConsoleAdministrator, DdlPredefinedRole.SelectedValue)) + { + PhRoles.Visible = PhSiteId.Visible = false; + } + else if (EPredefinedRoleUtils.Equals(EPredefinedRole.SystemAdministrator, DdlPredefinedRole.SelectedValue)) + { + PhRoles.Visible = false; + PhSiteId.Visible = true; + } + else + { + PhRoles.Visible = true; + PhSiteId.Visible = false; + } + } + + private void ListBoxDataBind() + { + LbAvailableRoles.Items.Clear(); + LbAssignedRoles.Items.Clear(); + var allRoles = AuthRequest.AdminPermissionsImpl.IsConsoleAdministrator ? DataProvider.Role.GetRoleNameList() : DataProvider.Role.GetRoleNameListByCreatorUserName(AuthRequest.AdminName); + var userRoles = DataProvider.AdministratorsInRoles.GetRolesForUser(_userName); + var userRoleNameList = new List(userRoles); + foreach (var roleName in allRoles) + { + if (!EPredefinedRoleUtils.IsPredefinedRole(roleName) && !userRoleNameList.Contains(roleName)) + { + LbAvailableRoles.Items.Add(new ListItem(roleName, roleName)); + } + } + foreach (var roleName in userRoles) + { + if (!EPredefinedRoleUtils.IsPredefinedRole(roleName)) + { + LbAssignedRoles.Items.Add(new ListItem(roleName, roleName)); + } + } + } + + public void AddRole_OnClick(object sender, EventArgs e) + { + if (!IsPostBack || !IsValid) return; + + try + { + if (LbAvailableRoles.SelectedIndex != -1) + { + var selectedRoles = SystemWebUtils.GetSelectedListControlValueArray(LbAvailableRoles); + if (selectedRoles.Length > 0) + { + foreach (var selectedRole in selectedRoles) + { + DataProvider.AdministratorsInRoles.AddUserToRole(_userName, selectedRole); + } + } + } + ListBoxDataBind(); + } + catch (Exception ex) + { + FailMessage(ex, "用户角色分配失败"); + } + } + + public void AddRoles_OnClick(object sender, EventArgs e) + { + if (!IsPostBack || !IsValid) return; + + try + { + var roles = SystemWebUtils.GetListControlValues(LbAvailableRoles); + if (roles.Length > 0) + { + foreach (var role in roles) + { + DataProvider.AdministratorsInRoles.AddUserToRole(_userName, role); + } + } + ListBoxDataBind(); + } + catch (Exception ex) + { + FailMessage(ex, "用户角色分配失败"); + } + } + + public void DeleteRole_OnClick(object sender, EventArgs e) + { + if (!IsPostBack || !IsValid) return; + + try + { + if (LbAssignedRoles.SelectedIndex != -1) + { + var selectedRoles = SystemWebUtils.GetSelectedListControlValueArray(LbAssignedRoles); + foreach (var selectedRole in selectedRoles) + { + DataProvider.AdministratorsInRoles.RemoveUserFromRole(_userName, selectedRole); + } + } + ListBoxDataBind(); + } + catch (Exception ex) + { + FailMessage(ex, "用户角色分配失败"); + } + } + + public void DeleteRoles_OnClick(object sender, EventArgs e) + { + if (!IsPostBack || !IsValid) return; + + try + { + var roles = SystemWebUtils.GetListControlValues(LbAssignedRoles); + if (roles.Length > 0) + { + foreach (var role in roles) + { + DataProvider.AdministratorsInRoles.RemoveUserFromRole(_userName, role); + } + } + ListBoxDataBind(); + } + catch (Exception ex) + { + FailMessage(ex, "用户角色分配失败"); + } + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + var isChanged = false; + + try + { + var allRoles = EPredefinedRoleUtils.GetAllPredefinedRoleName(); + foreach (var roleName in allRoles) + { + DataProvider.AdministratorsInRoles.RemoveUserFromRole(_userName, roleName); + } + DataProvider.AdministratorsInRoles.AddUserToRole(_userName, DdlPredefinedRole.SelectedValue); + + var adminInfo = AdminManager.GetAdminInfoByUserName(_userName); + + DataProvider.Administrator.UpdateSiteIdCollection(adminInfo, + EPredefinedRoleUtils.Equals(EPredefinedRole.SystemAdministrator, DdlPredefinedRole.SelectedValue) + ? SystemWebUtils.SelectedItemsValueToStringCollection(CblSiteId.Items) + : string.Empty); + + PermissionsImpl.ClearAllCache(); + + AuthRequest.AddAdminLog("设置管理员权限", $"管理员:{_userName}"); + + SuccessMessage("权限设置成功!"); + isChanged = true; + } + catch (Exception ex) + { + FailMessage(ex, "权限设置失败!"); + } + + if (isChanged) + { + LayerUtils.CloseAndRedirect(Page, AdminPagesUtils.Settings.AdministratorsUrl); + } + } + } +} \ No newline at end of file diff --git a/SiteServer.BackgroundPages/Settings/ModalUserExport.cs b/net452/SiteServer.BackgroundPages/Settings/ModalUserExport.cs similarity index 76% rename from SiteServer.BackgroundPages/Settings/ModalUserExport.cs rename to net452/SiteServer.BackgroundPages/Settings/ModalUserExport.cs index fcb1edec7..6dca62865 100644 --- a/SiteServer.BackgroundPages/Settings/ModalUserExport.cs +++ b/net452/SiteServer.BackgroundPages/Settings/ModalUserExport.cs @@ -1,10 +1,12 @@ using System; using System.Web.UI.WebControls; -using SiteServer.CMS.Api; -using SiteServer.CMS.Api.Sys.Stl; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; using SiteServer.Utils; -using SiteServer.CMS.Core; using SiteServer.CMS.Core.Office; +using SiteServer.CMS.Core.RestRoutes; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Settings @@ -17,7 +19,7 @@ public class ModalUserExport : BasePage public static string GetOpenWindowString() { - return LayerUtils.GetOpenScript("导出用户", PageUtils.GetSettingsUrl(nameof(ModalUserExport), null), 450, 270); + return LayerUtils.GetOpenScript("导出用户", FxUtils.GetSettingsUrl(nameof(ModalUserExport), null), 450, 270); } public void Page_Load(object sender, EventArgs e) @@ -27,8 +29,8 @@ public void Page_Load(object sender, EventArgs e) if (!IsPostBack) { PhExport.Visible = true; - ETriStateUtils.AddListItems(DdlCheckedState, "全部", "审核通过", "未审核"); - ControlUtils.SelectSingleItem(DdlCheckedState, ETriStateUtils.GetValue(ETriState.All)); + FxUtils.AddListItemsToETriState(DdlCheckedState, "全部", "审核通过", "未审核"); + SystemWebUtils.SelectSingleItem(DdlCheckedState, ETriStateUtils.GetValue(ETriState.All)); } } diff --git a/SiteServer.BackgroundPages/Settings/ModalUserPassword.cs b/net452/SiteServer.BackgroundPages/Settings/ModalUserPassword.cs similarity index 81% rename from SiteServer.BackgroundPages/Settings/ModalUserPassword.cs rename to net452/SiteServer.BackgroundPages/Settings/ModalUserPassword.cs index 9648819df..b43aa8aed 100644 --- a/SiteServer.BackgroundPages/Settings/ModalUserPassword.cs +++ b/net452/SiteServer.BackgroundPages/Settings/ModalUserPassword.cs @@ -1,7 +1,9 @@ using System; using System.Collections.Specialized; using System.Web.UI.WebControls; -using SiteServer.CMS.Core; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; using SiteServer.Utils; namespace SiteServer.BackgroundPages.Settings @@ -15,7 +17,7 @@ public class ModalUserPassword : BasePage public static string GetOpenWindowString(string userName) { - return LayerUtils.GetOpenScript("重设密码", PageUtils.GetSettingsUrl(nameof(ModalUserPassword), new NameValueCollection + return LayerUtils.GetOpenScript("重设密码", FxUtils.GetSettingsUrl(nameof(ModalUserPassword), new NameValueCollection { {"userName", userName} }), 450, 290); @@ -45,8 +47,7 @@ public override void Submit_OnClick(object sender, EventArgs e) try { - string errorMessage; - if (DataProvider.UserDao.ChangePassword(_userName, TbPassword.Text, out errorMessage)) + if (DataProvider.User.ChangePassword(_userName, TbPassword.Text, out var errorMessage)) { SuccessMessage("重设密码成功!"); } diff --git a/net452/SiteServer.BackgroundPages/Settings/ModalUserView.cs b/net452/SiteServer.BackgroundPages/Settings/ModalUserView.cs new file mode 100644 index 000000000..0391bac3d --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/ModalUserView.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Specialized; +using System.Text; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Utils; + +namespace SiteServer.BackgroundPages.Settings +{ + public class ModalUserView : BasePage + { + protected Literal LtlUserId; + protected Literal LtlUserName; + protected Literal LtlCreateDate; + protected Literal LtlLoginCount; + protected Literal LtlLastResetPasswordDate; + protected Literal LtlLastActivityDate; + protected Literal LtlAttributes; + + private UserInfo _userInfo; + + public static string GetOpenWindowString(string userName) + { + return LayerUtils.GetOpenScript("查看用户信息", FxUtils.GetSettingsUrl(nameof(ModalUserView), new NameValueCollection + { + {"UserName", userName} + })); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + var userName = Request.QueryString["UserName"]; + _userInfo = UserManager.GetUserInfoByUserName(userName); + + LtlUserId.Text = _userInfo.Id.ToString(); + LtlUserName.Text = _userInfo.UserName; + LtlCreateDate.Text = DateUtils.GetDateAndTimeString(_userInfo.CreateDate); + LtlLastActivityDate.Text = DateUtils.GetDateAndTimeString(_userInfo.LastActivityDate); + LtlLastResetPasswordDate.Text = DateUtils.GetDateAndTimeString(_userInfo.LastResetPasswordDate); + LtlLoginCount.Text = _userInfo.CountOfLogin.ToString(); + + var builder = new StringBuilder(); + var sep = true; + foreach (var styleInfo in TableStyleManager.GetUserStyleInfoList()) + { + var value = _userInfo.Get(styleInfo.AttributeName) ?? string.Empty; + if (sep) + { + builder.Append(@"
    "); + } + + builder.Append($@" + +
    + {value} +
    +"); + + if (!sep) + { + builder.Append("
    "); + } + + sep = !sep; + } + + LtlAttributes.Text = builder.ToString(); + } + } +} diff --git a/SiteServer.BackgroundPages/Settings/PageAdminArea.cs b/net452/SiteServer.BackgroundPages/Settings/PageAdminArea.cs similarity index 82% rename from SiteServer.BackgroundPages/Settings/PageAdminArea.cs rename to net452/SiteServer.BackgroundPages/Settings/PageAdminArea.cs index 425a057a5..3bd985d43 100644 --- a/SiteServer.BackgroundPages/Settings/PageAdminArea.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageAdminArea.cs @@ -3,8 +3,11 @@ using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Settings { @@ -21,24 +24,24 @@ public static string GetRedirectUrl(int currentAreaId) { if (currentAreaId > 0) { - return PageUtils.GetSettingsUrl(nameof(PageAdminArea), new NameValueCollection + return FxUtils.GetSettingsUrl(nameof(PageAdminArea), new NameValueCollection { {"CurrentAreaID", currentAreaId.ToString()} }); } - return PageUtils.GetSettingsUrl(nameof(PageAdminArea), null); + return FxUtils.GetSettingsUrl(nameof(PageAdminArea), null); } public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - if (AuthRequest.IsQueryExists("Delete") && AuthRequest.IsQueryExists("AreaIDCollection")) + if (AuthRequest.IsQueryExists("DeleteById") && AuthRequest.IsQueryExists("AreaIDCollection")) { var areaIdArrayList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("AreaIDCollection")); foreach (var areaId in areaIdArrayList) { - DataProvider.AreaDao.Delete(areaId); + DataProvider.Area.Delete(areaId); } SuccessMessage("成功删除所选区域"); } @@ -46,15 +49,15 @@ public void Page_Load(object sender, EventArgs e) { var areaId = int.Parse(AuthRequest.GetQueryString("AreaID")); var isSubtract = AuthRequest.IsQueryExists("Subtract"); - DataProvider.AreaDao.UpdateTaxis(areaId, isSubtract); + DataProvider.Area.UpdateTaxis(areaId, isSubtract); - PageUtils.Redirect(GetRedirectUrl(areaId)); + WebPageUtils.Redirect(GetRedirectUrl(areaId)); return; } if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Admin); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Admin); ClientScriptRegisterClientScriptBlock("NodeTreeScript", AreaTreeItem.GetScript(EAreaLoadingType.Management, null)); @@ -70,9 +73,9 @@ public void Page_Load(object sender, EventArgs e) BtnAdd.Attributes.Add("onclick", ModalAreaAdd.GetOpenWindowStringToAdd(GetRedirectUrl(0))); - var urlDelete = PageUtils.GetSettingsUrl(nameof(PageAdminArea), new NameValueCollection + var urlDelete = FxUtils.GetSettingsUrl(nameof(PageAdminArea), new NameValueCollection { - {"Delete", "True"} + {"DeleteById", "True"} }); BtnDelete.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert(urlDelete, "AreaIDCollection", "AreaIDCollection", "请选择需要删除的区域!", "此操作将删除对应区域以及所有下级区域,确认删除吗?")); @@ -101,7 +104,7 @@ public string GetScriptOnLoad(int currentAreaId) public void BindGrid() { - RptContents.DataSource = DataProvider.AreaDao.GetIdListByParentId(0); + RptContents.DataSource = DataProvider.Area.GetIdListByParentId(0); RptContents.ItemDataBound += rptContents_ItemDataBound; RptContents.DataBind(); } @@ -129,14 +132,14 @@ public static string GetAreaRowHtml(AreaInfo areaInfo, EAreaLoadingType loadingT string editUrl = $@"编辑"; - var urlUp = PageUtils.GetSettingsUrl(nameof(PageAdminArea), new NameValueCollection + var urlUp = FxUtils.GetSettingsUrl(nameof(PageAdminArea), new NameValueCollection { {"Subtract", "True"}, {"AreaID", areaInfo.Id.ToString()} }); string upLink = $@""; - var urlDown = PageUtils.GetSettingsUrl(nameof(PageAdminArea), new NameValueCollection + var urlDown = FxUtils.GetSettingsUrl(nameof(PageAdminArea), new NameValueCollection { {"Add", "True"}, {"AreaID", areaInfo.Id.ToString()} diff --git a/net452/SiteServer.BackgroundPages/Settings/PageAdminConfiguration.cs b/net452/SiteServer.BackgroundPages/Settings/PageAdminConfiguration.cs new file mode 100644 index 000000000..576d28e89 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageAdminConfiguration.cs @@ -0,0 +1,97 @@ +using System; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageAdminConfiguration : BasePage + { + public TextBox TbLoginUserNameMinLength; + public TextBox TbLoginPasswordMinLength; + public DropDownList DdlLoginPasswordRestriction; + + public RadioButtonList RblIsLoginFailToLock; + public PlaceHolder PhFailToLock; + public TextBox TbLoginFailToLockCount; + public DropDownList DdlLoginLockingType; + public PlaceHolder PhLoginLockingHours; + public TextBox TbLoginLockingHours; + + public RadioButtonList RblIsViewContentOnlySelf; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.Admin); + + TbLoginUserNameMinLength.Text = ConfigManager.Instance.AdminUserNameMinLength.ToString(); + TbLoginPasswordMinLength.Text = ConfigManager.Instance.AdminPasswordMinLength.ToString(); + FxUtils.AddListItemsToEUserPasswordRestriction(DdlLoginPasswordRestriction); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlLoginPasswordRestriction, ConfigManager.Instance.AdminPasswordRestriction); + + FxUtils.AddListItems(RblIsLoginFailToLock, "是", "否"); + SystemWebUtils.SelectSingleItemIgnoreCase(RblIsLoginFailToLock, ConfigManager.Instance.IsAdminLockLogin.ToString()); + + PhFailToLock.Visible = ConfigManager.Instance.IsAdminLockLogin; + + TbLoginFailToLockCount.Text = ConfigManager.Instance.AdminLockLoginCount.ToString(); + + DdlLoginLockingType.Items.Add(new ListItem("按小时锁定", EUserLockTypeUtils.GetValue(EUserLockType.Hours))); + DdlLoginLockingType.Items.Add(new ListItem("永久锁定", EUserLockTypeUtils.GetValue(EUserLockType.Forever))); + SystemWebUtils.SelectSingleItemIgnoreCase(DdlLoginLockingType, ConfigManager.Instance.AdminLockLoginType); + + PhLoginLockingHours.Visible = false; + if (!EUserLockTypeUtils.Equals(ConfigManager.Instance.AdminLockLoginType, EUserLockType.Forever)) + { + PhLoginLockingHours.Visible = true; + TbLoginLockingHours.Text = ConfigManager.Instance.AdminLockLoginHours.ToString(); + } + + FxUtils.AddListItems(RblIsViewContentOnlySelf, "不可以", "可以"); + SystemWebUtils.SelectSingleItemIgnoreCase(RblIsViewContentOnlySelf, ConfigManager.Instance.IsViewContentOnlySelf.ToString()); + } + + public void RblIsLoginFailToLock_SelectedIndexChanged(object sender, EventArgs e) + { + PhFailToLock.Visible = TranslateUtils.ToBool(RblIsLoginFailToLock.SelectedValue); + } + + public void DdlLoginLockingType_SelectedIndexChanged(object sender, EventArgs e) + { + PhLoginLockingHours.Visible = !EUserLockTypeUtils.Equals(EUserLockType.Forever, DdlLoginLockingType.SelectedValue); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + try + { + ConfigManager.Instance.AdminUserNameMinLength = TranslateUtils.ToInt(TbLoginUserNameMinLength.Text); + ConfigManager.Instance.AdminPasswordMinLength = TranslateUtils.ToInt(TbLoginPasswordMinLength.Text); + ConfigManager.Instance.AdminPasswordRestriction = DdlLoginPasswordRestriction.SelectedValue; + + ConfigManager.Instance.IsAdminLockLogin = TranslateUtils.ToBool(RblIsLoginFailToLock.SelectedValue); + ConfigManager.Instance.AdminLockLoginCount = TranslateUtils.ToInt(TbLoginFailToLockCount.Text, 3); + ConfigManager.Instance.AdminLockLoginType = DdlLoginLockingType.SelectedValue; + ConfigManager.Instance.AdminLockLoginHours = TranslateUtils.ToInt(TbLoginLockingHours.Text); + + ConfigManager.Instance.IsViewContentOnlySelf = TranslateUtils.ToBool(RblIsViewContentOnlySelf.SelectedValue); + + DataProvider.Config.Update(ConfigManager.Instance); + + AuthRequest.AddAdminLog("管理员设置"); + SuccessMessage("管理员设置成功"); + } + catch (Exception ex) + { + FailMessage(ex, ex.Message); + } + } + } +} diff --git a/SiteServer.BackgroundPages/Settings/PageAdminDepartment.cs b/net452/SiteServer.BackgroundPages/Settings/PageAdminDepartment.cs similarity index 83% rename from SiteServer.BackgroundPages/Settings/PageAdminDepartment.cs rename to net452/SiteServer.BackgroundPages/Settings/PageAdminDepartment.cs index a578a5820..1b408076e 100644 --- a/SiteServer.BackgroundPages/Settings/PageAdminDepartment.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageAdminDepartment.cs @@ -3,8 +3,11 @@ using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Settings { @@ -21,24 +24,24 @@ public static string GetRedirectUrl(int currentDepartmentId) { if (currentDepartmentId != 0) { - return PageUtils.GetSettingsUrl(nameof(PageAdminDepartment), new NameValueCollection + return FxUtils.GetSettingsUrl(nameof(PageAdminDepartment), new NameValueCollection { {"CurrentDepartmentID", currentDepartmentId.ToString() } }); } - return PageUtils.GetSettingsUrl(nameof(PageAdminDepartment), null); + return FxUtils.GetSettingsUrl(nameof(PageAdminDepartment), null); } public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - if (AuthRequest.IsQueryExists("Delete") && AuthRequest.IsQueryExists("DepartmentIDCollection")) + if (AuthRequest.IsQueryExists("DeleteById") && AuthRequest.IsQueryExists("DepartmentIDCollection")) { var departmentIdArrayList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("DepartmentIDCollection")); foreach (var departmentId in departmentIdArrayList) { - DataProvider.DepartmentDao.Delete(departmentId); + DataProvider.Department.Delete(departmentId); } SuccessMessage("成功删除所选部门"); } @@ -46,15 +49,15 @@ public void Page_Load(object sender, EventArgs e) { var departmentId = AuthRequest.GetQueryInt("DepartmentID"); var isSubtract = AuthRequest.IsQueryExists("Subtract"); - DataProvider.DepartmentDao.UpdateTaxis(departmentId, isSubtract); + DataProvider.Department.UpdateTaxis(departmentId, isSubtract); - PageUtils.Redirect(GetRedirectUrl(departmentId)); + WebPageUtils.Redirect(GetRedirectUrl(departmentId)); return; } if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Admin); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Admin); ClientScriptRegisterClientScriptBlock("NodeTreeScript", DepartmentTreeItem.GetScript(EDepartmentLoadingType.ContentList, null)); @@ -70,12 +73,12 @@ public void Page_Load(object sender, EventArgs e) BtnAdd.Attributes.Add("onclick", ModalDepartmentAdd.GetOpenWindowStringToAdd(GetRedirectUrl(0))); - BtnDelete.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert(PageUtils.GetSettingsUrl(nameof(PageAdminDepartment), new NameValueCollection + BtnDelete.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert(FxUtils.GetSettingsUrl(nameof(PageAdminDepartment), new NameValueCollection { - {"Delete", "True" } + {"DeleteById", "True" } }), "DepartmentIDCollection", "DepartmentIDCollection", "请选择需要删除的部门!", "此操作将删除对应部门以及所有下级部门,确认删除吗?")); - RptContents.DataSource = DataProvider.DepartmentDao.GetIdListByParentId(0); + RptContents.DataSource = DataProvider.Department.GetIdListByParentId(0); RptContents.ItemDataBound += RptContents_ItemDataBound; RptContents.DataBind(); } @@ -133,14 +136,14 @@ public static string GetDepartmentRowHtml(DepartmentInfo departmentInfo, EDepart string editUrl = $@"编辑"; - var urlUp = PageUtils.GetSettingsUrl(nameof(PageAdminDepartment), new NameValueCollection + var urlUp = FxUtils.GetSettingsUrl(nameof(PageAdminDepartment), new NameValueCollection { {"Subtract", "True"}, {"DepartmentID", departmentInfo.Id.ToString()} }); string upLink = $@""; - var urlDown = PageUtils.GetSettingsUrl(nameof(PageAdminDepartment), new NameValueCollection + var urlDown = FxUtils.GetSettingsUrl(nameof(PageAdminDepartment), new NameValueCollection { {"Add", "True"}, {"DepartmentID", departmentInfo.Id.ToString()} diff --git a/net452/SiteServer.BackgroundPages/Settings/PageAdminPermissionAdd.cs b/net452/SiteServer.BackgroundPages/Settings/PageAdminPermissionAdd.cs new file mode 100644 index 000000000..ad3c54160 Binary files /dev/null and b/net452/SiteServer.BackgroundPages/Settings/PageAdminPermissionAdd.cs differ diff --git a/net452/SiteServer.BackgroundPages/Settings/PageAdminRole.cs b/net452/SiteServer.BackgroundPages/Settings/PageAdminRole.cs new file mode 100644 index 000000000..5b130a8e7 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageAdminRole.cs @@ -0,0 +1,75 @@ +using System; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageAdminRole : BasePage + { + public Repeater RptContents; + public Button BtnAdd; + + public static string GetRedirectUrl() + { + return FxUtils.GetSettingsUrl(nameof(PageAdminRole), null); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + if (AuthRequest.IsQueryExists("DeleteById")) + { + var roleName = AuthRequest.GetQueryString("RoleName"); + try + { + DataProvider.PermissionsInRoles.Delete(roleName); + DataProvider.Role.DeleteRole(roleName); + + AuthRequest.AddAdminLog("删除管理员角色", $"角色名称:{roleName}"); + + SuccessDeleteMessage(); + } + catch(Exception ex) + { + FailDeleteMessage(ex); + } + } + + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.Admin); + + RptContents.DataSource = AuthRequest.AdminPermissionsImpl.IsConsoleAdministrator + ? DataProvider.Role.GetRoleNameList() + : DataProvider.Role.GetRoleNameListByCreatorUserName(AuthRequest.AdminName); + RptContents.ItemDataBound += RptContents_ItemDataBound; + RptContents.DataBind(); + + BtnAdd.Attributes.Add("onclick", $"location.href = '{PageAdminRoleAdd.GetRedirectUrl()}';return false;"); + } + + private static void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var roleName = (string)e.Item.DataItem; + e.Item.Visible = !EPredefinedRoleUtils.IsPredefinedRole(roleName); + + var ltlRoleName = (Literal) e.Item.FindControl("ltlRoleName"); + var ltlDescription = (Literal)e.Item.FindControl("ltlDescription"); + var ltlEdit = (Literal)e.Item.FindControl("ltlEdit"); + var ltlDelete = (Literal)e.Item.FindControl("ltlDelete"); + + ltlRoleName.Text = roleName; + ltlDescription.Text = DataProvider.Role.GetRoleDescription(roleName); + ltlEdit.Text = $@"修改"; + ltlDelete.Text = $@"删除"; + } + } +} diff --git a/SiteServer.BackgroundPages/Settings/PageAdminRoleAdd.cs b/net452/SiteServer.BackgroundPages/Settings/PageAdminRoleAdd.cs similarity index 76% rename from SiteServer.BackgroundPages/Settings/PageAdminRoleAdd.cs rename to net452/SiteServer.BackgroundPages/Settings/PageAdminRoleAdd.cs index 65fd7d844..cd633e6d7 100644 --- a/SiteServer.BackgroundPages/Settings/PageAdminRoleAdd.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageAdminRoleAdd.cs @@ -3,9 +3,14 @@ using System.Collections.Specialized; using System.Text; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Settings { @@ -26,12 +31,12 @@ public class PageAdminRoleAdd : BasePageCms public static string GetRedirectUrl() { - return PageUtils.GetSettingsUrl(nameof(PageAdminRoleAdd), null); + return FxUtils.GetSettingsUrl(nameof(PageAdminRoleAdd), null); } public static string GetRedirectUrl(string roleName) { - return PageUtils.GetSettingsUrl(nameof(PageAdminRoleAdd), new NameValueCollection { { "RoleName", roleName } }); + return FxUtils.GetSettingsUrl(nameof(PageAdminRoleAdd), new NameValueCollection { { "RoleName", roleName } }); } public static string GetReturnRedirectUrl(string roleName) @@ -41,7 +46,7 @@ public static string GetReturnRedirectUrl(string roleName) { queryString.Add("RoleName", roleName); } - return PageUtils.GetSettingsUrl(nameof(PageAdminRoleAdd), queryString); + return FxUtils.GetSettingsUrl(nameof(PageAdminRoleAdd), queryString); } public string GetSitesHtml(List allSiteIdList, List managedSiteIdList) @@ -77,21 +82,21 @@ public void Page_Load(object sender, EventArgs e) if (IsForbidden) return; _theRoleName = AuthRequest.GetQueryString("RoleName"); - _generalPermissionList = AuthRequest.AdminPermissions.PermissionList; + _generalPermissionList = AuthRequest.AdminPermissionsImpl.PermissionList; if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Admin); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Admin); if (!string.IsNullOrEmpty(_theRoleName)) { TbRoleName.Text = _theRoleName; TbRoleName.Enabled = false; - TbDescription.Text = DataProvider.RoleDao.GetRoleDescription(_theRoleName); + TbDescription.Text = DataProvider.Role.GetRoleDescription(_theRoleName); if (AuthRequest.GetQueryString("Return") == null) { - var systemPermissionsInfoList = DataProvider.SitePermissionsDao.GetSystemPermissionsInfoList(_theRoleName); + var systemPermissionsInfoList = DataProvider.SitePermissions.GetSystemPermissionsInfoList(_theRoleName); Session[SystemPermissionsInfoListKey] = systemPermissionsInfoList; } } @@ -117,10 +122,10 @@ public void Page_Load(object sender, EventArgs e) if (!string.IsNullOrEmpty(_theRoleName)) { - var permissionList = DataProvider.PermissionsInRolesDao.GetGeneralPermissionList(new[] { _theRoleName }); + var permissionList = DataProvider.PermissionsInRoles.GetGeneralPermissionList(new[] { _theRoleName }); if (permissionList != null && permissionList.Count > 0) { - ControlUtils.SelectMultiItems(CblPermissions, permissionList); + SystemWebUtils.SelectMultiItems(CblPermissions, permissionList); } } } @@ -131,12 +136,12 @@ public void Page_Load(object sender, EventArgs e) if (psPermissionsInRolesInfoList != null) { var allSiteIdList = new List(); - foreach (var permissionSiteId in AuthRequest.AdminPermissions.SiteIdList) + foreach (var permissionSiteId in AuthRequest.AdminPermissionsImpl.GetSiteIdList()) { - if (AuthRequest.AdminPermissions.HasChannelPermissions(permissionSiteId, permissionSiteId) && AuthRequest.AdminPermissions.HasSitePermissions(permissionSiteId)) + if (AuthRequest.AdminPermissionsImpl.HasChannelPermissions(permissionSiteId, permissionSiteId) && AuthRequest.AdminPermissionsImpl.HasSitePermissions(permissionSiteId)) { - var listOne = AuthRequest.AdminPermissions.GetChannelPermissions(permissionSiteId, permissionSiteId); - var listTwo = AuthRequest.AdminPermissions.GetSitePermissions(permissionSiteId); + var listOne = AuthRequest.AdminPermissionsImpl.GetChannelPermissions(permissionSiteId, permissionSiteId); + var listTwo = AuthRequest.AdminPermissionsImpl.GetSitePermissions(permissionSiteId); if (listOne != null && listOne.Count > 0 || listTwo != null && listTwo.Count > 0) { PhSitePermissions.Visible = true; @@ -153,7 +158,7 @@ public void Page_Load(object sender, EventArgs e) } else { - PageUtils.RedirectToErrorPage("页面超时,请重新进入。"); + WebPageUtils.RedirectToErrorPage("页面超时,请重新进入。"); } if (Request.QueryString["Return"] == null) @@ -190,12 +195,12 @@ public override void Submit_OnClick(object sender, EventArgs e) { var sitePermissionsInRolesInfoList = Session[SystemPermissionsInfoListKey] as List; - var generalPermissionList = ControlUtils.GetSelectedListControlValueStringList(CblPermissions); - DataProvider.PermissionsInRolesDao.UpdateRoleAndGeneralPermissions(_theRoleName, TbDescription.Text, generalPermissionList); + var generalPermissionList = SystemWebUtils.GetSelectedListControlValueStringList(CblPermissions); + DataProvider.PermissionsInRoles.UpdateRoleAndGeneralPermissions(_theRoleName, TbDescription.Text, generalPermissionList); - DataProvider.SitePermissionsDao.UpdateSitePermissions(_theRoleName, sitePermissionsInRolesInfoList); + DataProvider.SitePermissions.UpdateSitePermissions(_theRoleName, sitePermissionsInRolesInfoList); - PermissionManager.ClearAllCache(); + PermissionsImpl.ClearAllCache(); AuthRequest.AddAdminLog("修改管理员角色", $"角色名称:{_theRoleName}"); SuccessMessage("角色修改成功!"); @@ -208,20 +213,24 @@ public override void Submit_OnClick(object sender, EventArgs e) } else { - if (DataProvider.RoleDao.IsRoleExists(TbRoleName.Text)) + if (EPredefinedRoleUtils.IsPredefinedRole(TbRoleName.Text)) + { + FailMessage($"角色添加失败,{TbRoleName.Text}为系统角色!"); + } + else if (DataProvider.Role.IsRoleExists(TbRoleName.Text)) { FailMessage("角色添加失败,角色标识已存在!"); } else { var sitePermissionsInRolesInfoList = Session[SystemPermissionsInfoListKey] as List; - var generalPermissionList = ControlUtils.GetSelectedListControlValueStringList(CblPermissions); + var generalPermissionList = SystemWebUtils.GetSelectedListControlValueStringList(CblPermissions); try { - DataProvider.SitePermissionsDao.InsertRoleAndPermissions(TbRoleName.Text, AuthRequest.AdminName, TbDescription.Text, generalPermissionList, sitePermissionsInRolesInfoList); + DataProvider.SitePermissions.InsertRoleAndPermissions(TbRoleName.Text, AuthRequest.AdminName, TbDescription.Text, generalPermissionList, sitePermissionsInRolesInfoList); - PermissionManager.ClearAllCache(); + PermissionsImpl.ClearAllCache(); AuthRequest.AddAdminLog("新增管理员角色", $"角色名称:{TbRoleName.Text}"); @@ -241,7 +250,7 @@ public void Return_OnClick(object sender, EventArgs e) { if (AuthRequest.GetQueryString("Return") != null) { - PageUtils.Redirect(PageAdminRole.GetRedirectUrl()); + WebPageUtils.Redirect(PageAdminRole.GetRedirectUrl()); } } } diff --git a/net452/SiteServer.BackgroundPages/Settings/PageAdministrator.cs b/net452/SiteServer.BackgroundPages/Settings/PageAdministrator.cs new file mode 100644 index 000000000..5795a8dd9 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageAdministrator.cs @@ -0,0 +1,328 @@ +using System; +using System.Collections.Generic; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Controls; +using SiteServer.CMS.Core; +using SiteServer.CMS.DataCache; +using SiteServer.CMS.Model; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageAdministrator : BasePage + { + public DropDownList DdlRoleName; + public DropDownList DdlPageNum; + public DropDownList DdlOrder; + public DropDownList DdlLastActivityDate; + public DropDownList DdlDepartmentId; + public DropDownList DdlAreaId; + public TextBox TbKeyword; + + public Repeater RptContents; + public Pager PgContents; + + public Button BtnLock; + public Button BtnUnLock; + public Button BtnDelete; + + private readonly Dictionary _parentsCountDictOfDepartment = new Dictionary(); + private readonly Dictionary _parentsCountDictOfArea = new Dictionary(); + private EUserLockType _lockType = EUserLockType.Forever; + + public static string GetRedirectUrl() + { + return PageUtils.GetSettingsUrl(nameof(PageAdministrator), null); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + var pageNum = AuthRequest.GetQueryInt("pageNum") == 0 ? 30 : AuthRequest.GetQueryInt("pageNum"); + var keyword = AuthRequest.GetQueryString("keyword"); + var roleName = AuthRequest.GetQueryString("roleName"); + var lastActivityDate = AuthRequest.GetQueryInt("lastActivityDate"); + var isConsoleAdministrator = AuthRequest.AdminPermissionsImpl.IsConsoleAdministrator; + var adminName = AuthRequest.AdminName; + var order = AuthRequest.IsQueryExists("order") ? AuthRequest.GetQueryString("order") : nameof(AdministratorInfo.UserName); + var departmentId = AuthRequest.GetQueryInt("departmentId"); + var areaId = AuthRequest.GetQueryInt("areaId"); + + if (AuthRequest.IsQueryExists("Delete")) + { + var userNameCollection = AuthRequest.GetQueryString("UserNameCollection"); + try + { + var userNameArrayList = TranslateUtils.StringCollectionToStringList(userNameCollection); + foreach (var userName in userNameArrayList) + { + var adminInfo = AdminManager.GetAdminInfoByUserName(userName); + DataProvider.AdministratorDao.Delete(adminInfo); + } + + AuthRequest.AddAdminLog("删除管理员", $"管理员:{userNameCollection}"); + + SuccessDeleteMessage(); + } + catch (Exception ex) + { + FailDeleteMessage(ex); + } + } + else if (AuthRequest.IsQueryExists("Lock")) + { + var userNameCollection = AuthRequest.GetQueryString("UserNameCollection"); + try + { + var userNameList = TranslateUtils.StringCollectionToStringList(userNameCollection); + //DataProvider.AdministratorDao.Lock(userNameList); + + AuthRequest.AddAdminLog("锁定管理员", $"管理员:{userNameCollection}"); + + SuccessMessage("成功锁定所选管理员!"); + } + catch (Exception ex) + { + FailMessage(ex, "锁定所选管理员失败!"); + } + } + else if (AuthRequest.IsQueryExists("UnLock")) + { + var userNameCollection = AuthRequest.GetQueryString("UserNameCollection"); + try + { + var userNameList = TranslateUtils.StringCollectionToStringList(userNameCollection); + //DataProvider.AdministratorDao.UnLock(userNameList); + + AuthRequest.AddAdminLog("解除锁定管理员", $"管理员:{userNameCollection}"); + + SuccessMessage("成功解除锁定所选管理员!"); + } + catch (Exception ex) + { + FailMessage(ex, "解除锁定所选管理员失败!"); + } + } + + PgContents.Param = new PagerParam + { + ControlToPaginate = RptContents, + TableName = DataProvider.AdministratorDao.TableName, + PageSize = pageNum, + Page = AuthRequest.GetQueryInt(Pager.QueryNamePage, 1), + OrderSqlString = DataProvider.AdministratorDao.GetOrderSqlString(order), + ReturnColumnNames = SqlUtils.Asterisk, + WhereSqlString = DataProvider.AdministratorDao.GetWhereSqlString(isConsoleAdministrator, adminName, keyword, roleName, lastActivityDate, departmentId, areaId) + }; + + PgContents.Param.TotalCount = + DataProvider.DatabaseDao.GetPageTotalCount(DataProvider.AdministratorDao.TableName, PgContents.Param.WhereSqlString); + + RptContents.ItemDataBound += RptContents_ItemDataBound; + + _lockType = EUserLockTypeUtils.GetEnumType(ConfigManager.SystemConfigInfo.AdminLockLoginType); + + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.Admin); + + var theListItem = new ListItem("全部", string.Empty) + { + Selected = true + }; + DdlRoleName.Items.Add(theListItem); + + var allRoles = AuthRequest.AdminPermissionsImpl.IsConsoleAdministrator ? DataProvider.RoleDao.GetRoleNameList() : DataProvider.RoleDao.GetRoleNameListByCreatorUserName(AuthRequest.AdminName); + + var allPredefinedRoles = EPredefinedRoleUtils.GetAllPredefinedRoleName(); + foreach (var theRoleName in allRoles) + { + if (allPredefinedRoles.Contains(theRoleName)) + { + var listitem = new ListItem(EPredefinedRoleUtils.GetText(EPredefinedRoleUtils.GetEnumType(theRoleName)), theRoleName); + DdlRoleName.Items.Add(listitem); + } + else + { + var listitem = new ListItem(theRoleName, theRoleName); + DdlRoleName.Items.Add(listitem); + } + } + + DdlDepartmentId.Items.Add(new ListItem("<所有部门>", "0")); + var departmentIdList = DepartmentManager.GetDepartmentIdList(); + foreach (var theDepartmentId in departmentIdList) + { + var departmentInfo = DepartmentManager.GetDepartmentInfo(theDepartmentId); + DdlDepartmentId.Items.Add(new ListItem(GetTreeItem(departmentInfo.DepartmentName, departmentInfo.ParentsCount, departmentInfo.IsLastNode, _parentsCountDictOfDepartment), theDepartmentId.ToString())); + } + ControlUtils.SelectSingleItem(DdlDepartmentId, departmentId.ToString()); + + DdlAreaId.Items.Add(new ListItem("<全部区域>", "0")); + var areaIdList = AreaManager.GetAreaIdList(); + foreach (var theAreaId in areaIdList) + { + var areaInfo = AreaManager.GetAreaInfo(theAreaId); + DdlAreaId.Items.Add(new ListItem(GetTreeItem(areaInfo.AreaName, areaInfo.ParentsCount, areaInfo.IsLastNode, _parentsCountDictOfArea), theAreaId.ToString())); + } + ControlUtils.SelectSingleItem(DdlAreaId, areaId.ToString()); + + ControlUtils.SelectSingleItem(DdlRoleName, roleName); + ControlUtils.SelectSingleItem(DdlPageNum, pageNum.ToString()); + TbKeyword.Text = keyword; + ControlUtils.SelectSingleItem(DdlDepartmentId, departmentId.ToString()); + ControlUtils.SelectSingleItem(DdlAreaId, areaId.ToString()); + ControlUtils.SelectSingleItem(DdlLastActivityDate, lastActivityDate.ToString()); + ControlUtils.SelectSingleItem(DdlOrder, order); + + PgContents.DataBind(); + + var urlAdministrator = GetRedirectUrl(); + + BtnLock.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert(urlAdministrator + "?Lock=True", "UserNameCollection", "UserNameCollection", "请选择需要锁定的管理员!", "此操作将锁定所选管理员,确认吗?")); + + BtnUnLock.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert(urlAdministrator + "?UnLock=True", "UserNameCollection", "UserNameCollection", "请选择需要解除锁定的管理员!", "此操作将解除锁定所选管理员,确认吗?")); + + BtnDelete.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert(urlAdministrator + "?Delete=True", "UserNameCollection", "UserNameCollection", "请选择需要删除的管理员!", "此操作将删除所选管理员,确认吗?")); + } + + public string GetTreeItem(string areaName, int parentsCount, bool isLastNode, Dictionary parentsCountDict) + { + var str = ""; + if (isLastNode == false) + { + parentsCountDict[parentsCount] = false; + } + else + { + parentsCountDict[parentsCount] = true; + } + for (var i = 0; i < parentsCount; i++) + { + str = string.Concat(str, TranslateUtils.DictGetValue(parentsCountDict, i) ? " " : "│"); + } + str = string.Concat(str, isLastNode ? "└" : "├"); + str = string.Concat(str, areaName); + return str; + } + + private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var userId = SqlUtils.EvalInt(e.Item.DataItem, nameof(AdministratorInfo.Id)); + var userName = SqlUtils.EvalString(e.Item.DataItem, nameof(AdministratorInfo.UserName)); + var displayName = SqlUtils.EvalString(e.Item.DataItem, nameof(AdministratorInfo.DisplayName)); + var mobile = SqlUtils.EvalString(e.Item.DataItem, nameof(AdministratorInfo.Mobile)); + var avatarUrl = SqlUtils.EvalString(e.Item.DataItem, nameof(AdministratorInfo.AvatarUrl)); + var departmentId = SqlUtils.EvalInt(e.Item.DataItem, nameof(AdministratorInfo.DepartmentId)); + var areaId = SqlUtils.EvalInt(e.Item.DataItem, nameof(AdministratorInfo.AreaId)); + if (string.IsNullOrEmpty(displayName)) + { + displayName = userName; + } + var countOfFailedLogin = SqlUtils.EvalInt(e.Item.DataItem, nameof(AdministratorInfo.CountOfFailedLogin)); + var countOfLogin = SqlUtils.EvalInt(e.Item.DataItem, nameof(AdministratorInfo.CountOfLogin)); + var isLockedOut = SqlUtils.EvalBool(e.Item.DataItem, nameof(AdministratorInfo.Locked)); + var lastActivityDate = SqlUtils.EvalDateTime(e.Item.DataItem, nameof(AdministratorInfo.LastActivityDate)); + + var ltlAvatar = (Literal)e.Item.FindControl("ltlAvatar"); + var ltlUserName = (Literal)e.Item.FindControl("ltlUserName"); + var ltlDisplayName = (Literal)e.Item.FindControl("ltlDisplayName"); + var ltlMobile = (Literal)e.Item.FindControl("ltlMobile"); + var ltlDepartment = (Literal)e.Item.FindControl("ltlDepartment"); + var ltlArea = (Literal)e.Item.FindControl("ltlArea"); + var ltlLastActivityDate = (Literal)e.Item.FindControl("ltlLastActivityDate"); + var ltlCountOfLogin = (Literal)e.Item.FindControl("ltlCountOfLogin"); + var ltlRoles = (Literal)e.Item.FindControl("ltlRoles"); + var ltlActions = (Literal)e.Item.FindControl("ltlActions"); + var ltlSelect = (Literal)e.Item.FindControl("ltlSelect"); + + ltlAvatar.Text = $@""; + ltlUserName.Text = GetUserNameHtml(userId, userName, countOfFailedLogin, isLockedOut, lastActivityDate); + ltlDisplayName.Text = displayName; + ltlMobile.Text = mobile; + ltlDepartment.Text = DepartmentManager.GetDepartmentName(departmentId); + ltlArea.Text = AreaManager.GetAreaName(areaId); + + ltlLastActivityDate.Text = GetDateTime(lastActivityDate); + ltlCountOfLogin.Text = countOfLogin.ToString(); + ltlRoles.Text = AdminManager.GetRoleNames(userName); + + if (AuthRequest.AdminName != userName) + { + ltlActions.Text = $@" +修改资料 +更改密码 +权限设置 +"; + + ltlSelect.Text = $@""; + } + else + { + ltlActions.Text = $@" +修改资料 +更改密码 +"; + } + } + + private static string GetDateTime(DateTime datetime) + { + var retval = string.Empty; + if (datetime > DateUtils.SqlMinValue) + { + retval = DateUtils.GetDateString(datetime); + } + return retval; + } + + private string GetUserNameHtml(int userId, string userName, int countOfFailedLogin, bool isLockedOut, DateTime lastActivityDate) + { + var state = string.Empty; + if (isLockedOut) + { + state = @"[已被锁定]"; + } + else if (ConfigManager.SystemConfigInfo.IsAdminLockLogin && + ConfigManager.SystemConfigInfo.AdminLockLoginCount <= countOfFailedLogin) + { + if (_lockType == EUserLockType.Forever) + { + state = @"[已被锁定]"; + } + else + { + var ts = new TimeSpan(DateTime.Now.Ticks - lastActivityDate.Ticks); + var hours = Convert.ToInt32(ConfigManager.SystemConfigInfo.AdminLockLoginHours - ts.TotalHours); + if (hours > 0) + { + state = $@"[错误登录次数过多,已被锁定{hours}小时]"; + } + } + } + return $@"{userName} {state}"; + } + + public void Search_OnClick(object sender, EventArgs e) + { + PageUtils.Redirect(PageUrl); + } + + private string _pageUrl; + private string PageUrl + { + get + { + if (string.IsNullOrEmpty(_pageUrl)) + { + _pageUrl = $"{GetRedirectUrl()}?roleName={DdlRoleName.SelectedValue}&pageNum={DdlPageNum.SelectedValue}&keyword={TbKeyword.Text}&departmentId={DdlDepartmentId.SelectedValue}&areaId={DdlAreaId.SelectedValue}&lastActivityDate={DdlLastActivityDate.SelectedValue}&order={DdlOrder.SelectedValue}"; + } + return _pageUrl; + } + } + } +} diff --git a/SiteServer.BackgroundPages/Settings/PageAdministratorAdd.cs b/net452/SiteServer.BackgroundPages/Settings/PageAdministratorAdd.cs similarity index 90% rename from SiteServer.BackgroundPages/Settings/PageAdministratorAdd.cs rename to net452/SiteServer.BackgroundPages/Settings/PageAdministratorAdd.cs index 04718380d..ef188eba2 100644 --- a/SiteServer.BackgroundPages/Settings/PageAdministratorAdd.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageAdministratorAdd.cs @@ -2,6 +2,7 @@ using System.Collections.Specialized; using System.Web.UI.WebControls; using SiteServer.CMS.Core; +using SiteServer.CMS.DataCache; using SiteServer.CMS.Model; using SiteServer.Utils; @@ -53,7 +54,7 @@ public void Page_Load(object sender, EventArgs e) if (Page.IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Admin); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Admin); LtlPageTitle.Text = string.IsNullOrEmpty(_userName) ? "添加管理员" : "编辑管理员"; @@ -89,7 +90,7 @@ public void Page_Load(object sender, EventArgs e) if (!string.IsNullOrEmpty(_userName)) { - var adminInfo = DataProvider.AdministratorDao.GetByUserName(_userName); + var adminInfo = AdminManager.GetAdminInfoByUserName(_userName); if (adminInfo != null) { ControlUtils.SelectSingleItem(DdlDepartmentId, adminInfo.DepartmentId.ToString()); @@ -136,8 +137,7 @@ public override void Submit_OnClick(object sender, EventArgs e) return; } - string errorMessage; - if (!AdminManager.CreateAdministrator(adminInfo, out errorMessage)) + if (DataProvider.AdministratorDao.Insert(adminInfo, out var errorMessage) == 0) { FailMessage($"管理员添加失败:{errorMessage}"); return; @@ -149,7 +149,7 @@ public override void Submit_OnClick(object sender, EventArgs e) } else { - var adminInfo = DataProvider.AdministratorDao.GetByUserName(_userName); + var adminInfo = AdminManager.GetAdminInfoByUserName(_userName); if (adminInfo.Email != TbEmail.Text && !string.IsNullOrEmpty(DataProvider.AdministratorDao.GetUserNameByEmail(TbEmail.Text))) { @@ -169,11 +169,18 @@ public override void Submit_OnClick(object sender, EventArgs e) adminInfo.DepartmentId = TranslateUtils.ToInt(DdlDepartmentId.SelectedValue); adminInfo.AreaId = TranslateUtils.ToInt(DdlAreaId.SelectedValue); - DataProvider.AdministratorDao.Update(adminInfo); + var updated = DataProvider.AdministratorDao.Update(adminInfo, out var errorMessage); - AuthRequest.AddAdminLog("修改管理员属性", $"管理员:{TbUserName.Text.Trim()}"); - SuccessMessage("管理员设置成功!"); - AddWaitAndRedirectScript(PageAdministrator.GetRedirectUrl()); + if (updated) + { + AuthRequest.AddAdminLog("修改管理员属性", $"管理员:{TbUserName.Text.Trim()}"); + SuccessMessage("管理员设置成功!"); + AddWaitAndRedirectScript(PageAdministrator.GetRedirectUrl()); + } + else + { + FailMessage(errorMessage); + } } } diff --git a/SiteServer.BackgroundPages/Settings/PageAnalysisAdminLogin.cs b/net452/SiteServer.BackgroundPages/Settings/PageAnalysisAdminLogin.cs similarity index 88% rename from SiteServer.BackgroundPages/Settings/PageAnalysisAdminLogin.cs rename to net452/SiteServer.BackgroundPages/Settings/PageAnalysisAdminLogin.cs index e788855d9..fe6d827d9 100644 --- a/SiteServer.BackgroundPages/Settings/PageAnalysisAdminLogin.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageAnalysisAdminLogin.cs @@ -4,8 +4,11 @@ using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Controls; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Settings @@ -113,12 +116,12 @@ public void Page_Load(object sender, EventArgs e) if (IsForbidden) return; if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Chart); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Chart); LtlPageTitle1.Text = $"管理员登录最近{_count}{EStatictisXTypeUtils.GetText(EStatictisXTypeUtils.GetEnumType(AuthRequest.GetQueryString("XType")))}分配图表(按日期统计)"; LtlPageTitle2.Text = $"管理员登录最近{_count}{EStatictisXTypeUtils.GetText(EStatictisXTypeUtils.GetEnumType(AuthRequest.GetQueryString("XType")))}分配图表(按管理员统计)"; - EStatictisXTypeUtils.AddListItems(DdlXType); + FxUtils.AddListItemsToEStatictisXType(DdlXType); _xType = EStatictisXTypeUtils.GetEnumType(AuthRequest.GetQueryString("XType")); @@ -141,10 +144,10 @@ public void Page_Load(object sender, EventArgs e) DdlXType.SelectedValue = EStatictisXTypeUtils.GetValue(_xType); //管理员登录量统计,按照日期 - var trackingDayDictionary = DataProvider.LogDao.GetAdminLoginDictionaryByDate(TranslateUtils.ToDateTime(AuthRequest.GetQueryString("DateFrom")), TranslateUtils.ToDateTime(AuthRequest.GetQueryString("DateTo"), DateTime.Now), EStatictisXTypeUtils.GetValue(_xType), LogInfo.AdminLogin); + var trackingDayDictionary = DataProvider.Log.GetAdminLoginDictionaryByDate(TranslateUtils.ToDateTime(AuthRequest.GetQueryString("DateFrom")), TranslateUtils.ToDateTime(AuthRequest.GetQueryString("DateTo"), DateTime.Now), EStatictisXTypeUtils.GetValue(_xType), LogInfo.AdminLogin); //管理员登录量统计,按照用户名 - var adminNumDictionaryName = DataProvider.LogDao.GetAdminLoginDictionaryByName(TranslateUtils.ToDateTime(AuthRequest.GetQueryString("DateFrom")), TranslateUtils.ToDateTime(AuthRequest.GetQueryString("DateTo"), DateTime.Now), LogInfo.AdminLogin); + var adminNumDictionaryName = DataProvider.Log.GetAdminLoginDictionaryByName(TranslateUtils.ToDateTime(AuthRequest.GetQueryString("DateFrom")), TranslateUtils.ToDateTime(AuthRequest.GetQueryString("DateTo"), DateTime.Now), LogInfo.AdminLogin); var now = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0); for (var i = 0; i < _count; i++) @@ -197,7 +200,7 @@ public void Page_Load(object sender, EventArgs e) public void Search_OnClick(object sender, EventArgs e) { - PageUtils.Redirect(PageUrl); + WebPageUtils.Redirect(PageUrl); } private string _pageUrl; @@ -207,7 +210,7 @@ private string PageUrl { if (string.IsNullOrEmpty(_pageUrl)) { - _pageUrl = PageUtils.GetSettingsUrl(nameof(PageAnalysisAdminLogin), new NameValueCollection + _pageUrl = FxUtils.GetSettingsUrl(nameof(PageAnalysisAdminLogin), new NameValueCollection { {"DateFrom", TbDateFrom.Text }, {"DateTo", TbDateTo.Text }, diff --git a/SiteServer.BackgroundPages/Settings/PageAnalysisAdminWork.cs b/net452/SiteServer.BackgroundPages/Settings/PageAnalysisAdminWork.cs similarity index 89% rename from SiteServer.BackgroundPages/Settings/PageAnalysisAdminWork.cs rename to net452/SiteServer.BackgroundPages/Settings/PageAnalysisAdminWork.cs index a3ac695bf..6b43c181d 100644 --- a/SiteServer.BackgroundPages/Settings/PageAnalysisAdminWork.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageAnalysisAdminWork.cs @@ -7,7 +7,10 @@ using SiteServer.Utils; using SiteServer.BackgroundPages.Controls; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Settings { @@ -37,7 +40,7 @@ public class PageAnalysisAdminWork : BasePageCms public static string GetRedirectUrl(int siteId, string startDate, string endDate) { - return PageUtils.GetSettingsUrl(nameof(PageAnalysisAdminWork), new NameValueCollection + return FxUtils.GetSettingsUrl(nameof(PageAnalysisAdminWork), new NameValueCollection { {"siteId", siteId.ToString()}, {"startDate", startDate}, @@ -63,20 +66,20 @@ public void Page_Load(object sender, EventArgs e) if (SiteId == 0 && siteIdList.Count > 0) { - PageUtils.Redirect(GetRedirectUrl(siteIdList[0], DateUtils.GetDateAndTimeString(_begin), DateUtils.GetDateAndTimeString(_end))); + WebPageUtils.Redirect(GetRedirectUrl(siteIdList[0], DateUtils.GetDateAndTimeString(_begin), DateUtils.GetDateAndTimeString(_end))); return; } if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Chart); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Chart); foreach (var siteId in siteIdList) { var siteInfo = SiteManager.GetSiteInfo(siteId); DdlSiteId.Items.Add(new ListItem(siteInfo.SiteName, siteId.ToString())); } - ControlUtils.SelectSingleItem(DdlSiteId, SiteId.ToString()); + SystemWebUtils.SelectSingleItem(DdlSiteId, SiteId.ToString()); TbStartDate.Text = DateUtils.GetDateAndTimeString(_begin); TbEndDate.Text = DateUtils.GetDateAndTimeString(_end); @@ -87,7 +90,7 @@ public void Page_Load(object sender, EventArgs e) return; } - var ds = DataProvider.ContentDao.GetDataSetOfAdminExcludeRecycle(SiteInfo.TableName, SiteId, _begin, _end); + var ds = DataProvider.ContentRepository.GetDataSetOfAdminExcludeRecycle(SiteInfo.TableName, SiteId, _begin, _end); if (ds == null || ds.Tables.Count <= 0) return; var dt = ds.Tables[0]; @@ -112,11 +115,11 @@ public void Page_Load(object sender, EventArgs e) SpContents.ControlToPaginate = RptContents; RptContents.ItemDataBound += RptContents_ItemDataBound; - SpContents.ItemsPerPage = StringUtils.Constants.PageSize; + SpContents.ItemsPerPage = Constants.PageSize; SpContents.SortField = "UserName"; SpContents.SortMode = SortMode.DESC; - SpContents.SelectCommand = DataProvider.ContentDao.GetSqlStringOfAdminExcludeRecycle(SiteInfo.TableName, SiteId, _begin, _end); + SpContents.SelectCommand = DataProvider.ContentRepository.GetSqlStringOfAdminExcludeRecycle(SiteInfo.TableName, SiteId, _begin, _end); SpContents.DataBind(); } @@ -135,7 +138,7 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) var ltlContentUpdate = (Literal)e.Item.FindControl("ltlContentUpdate"); ltlUserName.Text = userName; - ltlDisplayName.Text = DataProvider.AdministratorDao.GetDisplayName(userName); + ltlDisplayName.Text = AdminManager.GetDisplayName(userName, false); ltlContentAdd.Text = addCount == 0 ? "0" : $"{addCount}"; ltlContentUpdate.Text = updateCount == 0 ? "0" : $"{updateCount}"; @@ -143,7 +146,7 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) public void Analysis_OnClick(object sender, EventArgs e) { - PageUtils.Redirect(GetRedirectUrl(TranslateUtils.ToInt(DdlSiteId.SelectedValue), TbStartDate.Text, TbEndDate.Text)); + WebPageUtils.Redirect(GetRedirectUrl(TranslateUtils.ToInt(DdlSiteId.SelectedValue), TbStartDate.Text, TbEndDate.Text)); } private void SetXHashtableUser(string userName, string siteName) diff --git a/SiteServer.BackgroundPages/Settings/PageAnalysisSite.cs b/net452/SiteServer.BackgroundPages/Settings/PageAnalysisSite.cs similarity index 92% rename from SiteServer.BackgroundPages/Settings/PageAnalysisSite.cs rename to net452/SiteServer.BackgroundPages/Settings/PageAnalysisSite.cs index bd78678f2..5ee5defd5 100644 --- a/SiteServer.BackgroundPages/Settings/PageAnalysisSite.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageAnalysisSite.cs @@ -5,7 +5,10 @@ using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Controls; -using SiteServer.CMS.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Settings @@ -40,7 +43,7 @@ public class PageAnalysisSite : BasePageCms public static string GetRedirectUrl(string startDate, string endDate) { - return PageUtils.GetSettingsUrl(nameof(PageAnalysisSite), new NameValueCollection + return FxUtils.GetSettingsUrl(nameof(PageAnalysisSite), new NameValueCollection { {"startDate", startDate}, {"endDate", endDate} @@ -64,7 +67,7 @@ public void Page_Load(object sender, EventArgs e) if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Chart); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Chart); DdlSiteId.Items.Add(new ListItem("<<全部站点>>", "0")); var siteIdList = SiteManager.GetSiteIdListOrderByLevel(); @@ -115,8 +118,8 @@ public void BindGrid() //x轴信息 SetXHashtable(key, siteInfo.SiteName); //y轴信息 - SetYHashtable(key, DataProvider.ContentDao.GetCountOfContentAdd(siteInfo.TableName, siteInfo.Id, siteInfo.Id, EScopeType.All, _begin, _end, string.Empty, ETriState.All), YTypeNew); - SetYHashtable(key, DataProvider.ContentDao.GetCountOfContentUpdate(siteInfo.TableName, siteInfo.Id, siteInfo.Id, EScopeType.All, _begin, _end, string.Empty), YTypeUpdate); + SetYHashtable(key, DataProvider.ContentRepository.GetCountOfContentAdd(siteInfo.TableName, siteInfo.Id, siteInfo.Id, EScopeType.All, _begin, _end, string.Empty, ETriState.All), YTypeNew); + SetYHashtable(key, DataProvider.ContentRepository.GetCountOfContentUpdate(siteInfo.TableName, siteInfo.Id, siteInfo.Id, EScopeType.All, _begin, _end, string.Empty), YTypeUpdate); } RptContents.DataSource = siteIdList; @@ -147,12 +150,12 @@ public void Analysis_OnClick(object sender, EventArgs e) var siteId = TranslateUtils.ToInt(DdlSiteId.SelectedValue); if (siteId > 0) { - PageUtils.Redirect(PageAnalysisSiteChannels.GetRedirectUrl(siteId, TbStartDate.Text, + WebPageUtils.Redirect(PageAnalysisSiteChannels.GetRedirectUrl(siteId, TbStartDate.Text, TbEndDate.Text)); } else { - PageUtils.Redirect(GetRedirectUrl(TbStartDate.Text, TbEndDate.Text)); + WebPageUtils.Redirect(GetRedirectUrl(TbStartDate.Text, TbEndDate.Text)); } } diff --git a/SiteServer.BackgroundPages/Settings/PageAnalysisSiteChannels.cs b/net452/SiteServer.BackgroundPages/Settings/PageAnalysisSiteChannels.cs similarity index 88% rename from SiteServer.BackgroundPages/Settings/PageAnalysisSiteChannels.cs rename to net452/SiteServer.BackgroundPages/Settings/PageAnalysisSiteChannels.cs index babcd6cd0..a9cd5f59d 100644 --- a/SiteServer.BackgroundPages/Settings/PageAnalysisSiteChannels.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageAnalysisSiteChannels.cs @@ -6,8 +6,11 @@ using SiteServer.Utils; using SiteServer.BackgroundPages.Controls; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model.Enumerations; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Settings @@ -38,7 +41,7 @@ public class PageAnalysisSiteChannels : BasePageCms public static string GetRedirectUrl(int siteId) { - return PageUtils.GetSettingsUrl(nameof(PageAnalysisSiteChannels), new NameValueCollection + return FxUtils.GetSettingsUrl(nameof(PageAnalysisSiteChannels), new NameValueCollection { {"siteId", siteId.ToString()} }); @@ -46,7 +49,7 @@ public static string GetRedirectUrl(int siteId) public static string GetRedirectUrl(int siteId, string startDate, string endDate) { - return PageUtils.GetSettingsUrl(nameof(PageAnalysisSiteChannels), new NameValueCollection + return FxUtils.GetSettingsUrl(nameof(PageAnalysisSiteChannels), new NameValueCollection { {"siteId", siteId.ToString()}, {"startDate", startDate}, @@ -71,7 +74,7 @@ public void Page_Load(object sender, EventArgs e) if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Chart); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Chart); DdlSiteId.Items.Add(new ListItem("<<全部站点>>", "0")); var siteIdList = SiteManager.GetSiteIdListOrderByLevel(); @@ -80,7 +83,7 @@ public void Page_Load(object sender, EventArgs e) var siteInfo = SiteManager.GetSiteInfo(siteId); DdlSiteId.Items.Add(new ListItem(siteInfo.SiteName, siteId.ToString())); } - ControlUtils.SelectSingleItem(DdlSiteId, SiteId.ToString()); + SystemWebUtils.SelectSingleItem(DdlSiteId, SiteId.ToString()); TbStartDate.Text = DateUtils.GetDateAndTimeString(_begin); TbEndDate.Text = DateUtils.GetDateAndTimeString(_end); @@ -117,8 +120,8 @@ public void BindGrid() SetXHashtable(channelId, nodeInfo.ChannelName); - SetYHashtable(channelId, DataProvider.ContentDao.GetCountOfContentAdd(tableName, SiteId, nodeInfo.Id, EScopeType.All, TranslateUtils.ToDateTime(_additional["StartDate"]), TranslateUtils.ToDateTime(_additional["EndDate"]), string.Empty, ETriState.All), YTypeNew); - SetYHashtable(channelId, DataProvider.ContentDao.GetCountOfContentUpdate(tableName, SiteId, nodeInfo.Id, EScopeType.All, TranslateUtils.ToDateTime(_additional["StartDate"]), TranslateUtils.ToDateTime(_additional["EndDate"]), string.Empty), YTypeUpdate); + SetYHashtable(channelId, DataProvider.ContentRepository.GetCountOfContentAdd(tableName, SiteId, nodeInfo.Id, EScopeType.All, TranslateUtils.ToDateTime(_additional["StartDate"]), TranslateUtils.ToDateTime(_additional["EndDate"]), string.Empty, ETriState.All), YTypeNew); + SetYHashtable(channelId, DataProvider.ContentRepository.GetCountOfContentUpdate(tableName, SiteId, nodeInfo.Id, EScopeType.All, TranslateUtils.ToDateTime(_additional["StartDate"]), TranslateUtils.ToDateTime(_additional["EndDate"]), string.Empty), YTypeUpdate); } RptChannels.DataSource = channelIdList; @@ -140,13 +143,13 @@ private void RptChannels_ItemDataBound(object sender, RepeaterItemEventArgs e) var ltlRow = (Literal)e.Item.FindControl("ltlRow"); - ltlRow.Text = ChannelLoading.GetChannelRowHtml(SiteInfo, nodeInfo, enabled, ELoadingType.SiteAnalysis, _additional, AuthRequest.AdminPermissions); + ltlRow.Text = ChannelLoading.GetChannelRowHtml(SiteInfo, nodeInfo, enabled, ELoadingType.SiteAnalysis, _additional, AuthRequest.AdminPermissionsImpl); } public void Analysis_OnClick(object sender, EventArgs e) { var siteId = TranslateUtils.ToInt(DdlSiteId.SelectedValue); - PageUtils.Redirect(siteId > 0 + WebPageUtils.Redirect(siteId > 0 ? GetRedirectUrl(siteId, TbStartDate.Text, TbEndDate.Text) : PageAnalysisSite.GetRedirectUrl(TbStartDate.Text, TbEndDate.Text)); } diff --git a/SiteServer.BackgroundPages/Settings/PageAnalysisSiteHits.cs b/net452/SiteServer.BackgroundPages/Settings/PageAnalysisSiteHits.cs similarity index 94% rename from SiteServer.BackgroundPages/Settings/PageAnalysisSiteHits.cs rename to net452/SiteServer.BackgroundPages/Settings/PageAnalysisSiteHits.cs index a4343739e..3659310ae 100644 --- a/SiteServer.BackgroundPages/Settings/PageAnalysisSiteHits.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageAnalysisSiteHits.cs @@ -2,8 +2,10 @@ using System.Collections; using System.Collections.Generic; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Fx; using SiteServer.Utils; -using SiteServer.CMS.Core; namespace SiteServer.BackgroundPages.Settings { @@ -24,7 +26,7 @@ public class PageAnalysisSiteHits : BasePageCms public static string GetRedirectUrl() { - return PageUtils.GetSettingsUrl(nameof(PageAnalysisSiteHits), null); + return FxUtils.GetSettingsUrl(nameof(PageAnalysisSiteHits), null); } public void Page_Load(object sender, EventArgs e) @@ -32,7 +34,7 @@ public void Page_Load(object sender, EventArgs e) if (IsForbidden) return; if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Chart); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Chart); DdlSiteId.Items.Add(new ListItem("<<全部站点>>", "0")); var siteIdList = SiteManager.GetSiteIdListOrderByLevel(); @@ -45,7 +47,7 @@ public void Page_Load(object sender, EventArgs e) //x轴信息 SetXHashtable(key, siteInfo.SiteName); //y轴信息 - SetYHashtable(key, DataProvider.ContentDao.GetTotalHits(siteInfo.TableName, siteId)); + SetYHashtable(key, siteInfo.ContentRepository.GetTotalHits(siteId)); } RptContents.DataSource = siteIdList; @@ -83,7 +85,7 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) public void Analysis_OnClick(object sender, EventArgs e) { var siteId = TranslateUtils.ToInt(DdlSiteId.SelectedValue); - PageUtils.Redirect(siteId > 0 + WebPageUtils.Redirect(siteId > 0 ? PageAnalysisSiteHitsChannels.GetRedirectUrl(siteId) : GetRedirectUrl()); } diff --git a/SiteServer.BackgroundPages/Settings/PageAnalysisSiteHitsChannels.cs b/net452/SiteServer.BackgroundPages/Settings/PageAnalysisSiteHitsChannels.cs similarity index 92% rename from SiteServer.BackgroundPages/Settings/PageAnalysisSiteHitsChannels.cs rename to net452/SiteServer.BackgroundPages/Settings/PageAnalysisSiteHitsChannels.cs index aff0862cc..50fd58d7b 100644 --- a/SiteServer.BackgroundPages/Settings/PageAnalysisSiteHitsChannels.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageAnalysisSiteHitsChannels.cs @@ -2,12 +2,17 @@ using System.Collections; using System.Collections.Generic; using System.Collections.Specialized; +using System.Data; using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Controls; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Settings { @@ -36,7 +41,7 @@ public class PageAnalysisSiteHitsChannels : BasePageCms public static string GetRedirectUrl(int siteId) { - return PageUtils.GetSettingsUrl(nameof(PageAnalysisSiteHitsChannels), new NameValueCollection + return FxUtils.GetSettingsUrl(nameof(PageAnalysisSiteHitsChannels), new NameValueCollection { {"siteId", siteId.ToString()} }); @@ -46,13 +51,13 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId"); + WebPageUtils.CheckRequestParameter("siteId"); SpContents.ControlToPaginate = RptContents; RptContents.ItemDataBound += RptContents_ItemDataBound; - SpContents.ItemsPerPage = SiteInfo.Additional.PageSize; + SpContents.ItemsPerPage = SiteInfo.PageSize; - SpContents.SelectCommand = DataProvider.ContentDao.GetSelectCommandByHitsAnalysis(SiteInfo.TableName, SiteId); + SpContents.SelectCommand = DataProvider.ContentRepository.GetSelectCommandByHitsAnalysis(SiteInfo.TableName, SiteId); SpContents.SortField = ContentAttribute.Hits; SpContents.SortMode = SortMode.DESC; @@ -61,7 +66,7 @@ public void Page_Load(object sender, EventArgs e) if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Chart); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Chart); DdlSiteId.Items.Add(new ListItem("<<全部站点>>", "0")); var siteIdList = SiteManager.GetSiteIdListOrderByLevel(); @@ -70,7 +75,7 @@ public void Page_Load(object sender, EventArgs e) var siteInfo = SiteManager.GetSiteInfo(siteId); DdlSiteId.Items.Add(new ListItem(siteInfo.SiteName, siteId.ToString())); } - ControlUtils.SelectSingleItem(DdlSiteId, SiteId.ToString()); + SystemWebUtils.SelectSingleItem(DdlSiteId, SiteId.ToString()); SpContents.DataBind(); @@ -96,7 +101,7 @@ public void Page_Load(object sender, EventArgs e) public void Analysis_OnClick(object sender, EventArgs e) { var siteId = TranslateUtils.ToInt(DdlSiteId.SelectedValue); - PageUtils.Redirect(siteId > 0 + WebPageUtils.Redirect(siteId > 0 ? GetRedirectUrl(siteId) : PageAnalysisSiteHits.GetRedirectUrl()); } @@ -113,7 +118,8 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) var ltlHitsByMonth = (Literal)e.Item.FindControl("ltlHitsByMonth"); var ltlLastHitsDate = (Literal)e.Item.FindControl("ltlLastHitsDate"); - var contentInfo = new ContentInfo(e.Item.DataItem); + var dataView = (DataRowView) e.Item.DataItem; + var contentInfo = new ContentInfo(TranslateUtils.ToDictionary(dataView)); ltlItemTitle.Text = WebUtils.GetContentTitle(SiteInfo, contentInfo, _pageUrl); diff --git a/SiteServer.BackgroundPages/Settings/PageAnalysisUser.cs b/net452/SiteServer.BackgroundPages/Settings/PageAnalysisUser.cs similarity index 90% rename from SiteServer.BackgroundPages/Settings/PageAnalysisUser.cs rename to net452/SiteServer.BackgroundPages/Settings/PageAnalysisUser.cs index d8105f140..0c8d9e997 100644 --- a/SiteServer.BackgroundPages/Settings/PageAnalysisUser.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageAnalysisUser.cs @@ -4,7 +4,10 @@ using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Controls; -using SiteServer.CMS.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Settings @@ -100,10 +103,10 @@ public void Page_Load(object sender, EventArgs e) if (IsForbidden) return; if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Chart); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Chart); LtlPageTitle.Text = $"用户增加最近{_count}{EStatictisXTypeUtils.GetText(EStatictisXTypeUtils.GetEnumType(AuthRequest.GetQueryString("XType")))}分配图表"; - EStatictisXTypeUtils.AddListItems(DdlXType); + FxUtils.AddListItemsToEStatictisXType(DdlXType); _xType = EStatictisXTypeUtils.GetEnumType(AuthRequest.GetQueryString("XType")); @@ -125,7 +128,7 @@ public void Page_Load(object sender, EventArgs e) DdlXType.SelectedValue = EStatictisXTypeUtils.GetValue(_xType); //用户添加量统计 - var trackingDayDict = DataProvider.UserDao.GetTrackingDictionary( TranslateUtils.ToDateTime(AuthRequest.GetQueryString("DateFrom")), TranslateUtils.ToDateTime(AuthRequest.GetQueryString("DateTo"), DateTime.Now), EStatictisXTypeUtils.GetValue(_xType)); + var trackingDayDict = DataProvider.User.GetTrackingDictionary( TranslateUtils.ToDateTime(AuthRequest.GetQueryString("DateFrom")), TranslateUtils.ToDateTime(AuthRequest.GetQueryString("DateTo"), DateTime.Now), EStatictisXTypeUtils.GetValue(_xType)); var now = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0); for (var i = 0; i < _count; i++) @@ -170,7 +173,7 @@ public void Page_Load(object sender, EventArgs e) public void Search_OnClick(object sender, EventArgs e) { - PageUtils.Redirect(PageUrl); + WebPageUtils.Redirect(PageUrl); } private string _pageUrl; @@ -180,7 +183,7 @@ private string PageUrl { if (string.IsNullOrEmpty(_pageUrl)) { - _pageUrl = PageUtils.GetSettingsUrl(nameof(PageAnalysisUser), new NameValueCollection + _pageUrl = FxUtils.GetSettingsUrl(nameof(PageAnalysisUser), new NameValueCollection { {"DateFrom", TbDateFrom.Text}, {"DateTo", TbDateTo.Text}, diff --git a/net452/SiteServer.BackgroundPages/Settings/PageLogAdmin.cs b/net452/SiteServer.BackgroundPages/Settings/PageLogAdmin.cs new file mode 100644 index 000000000..baec2cfdb --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageLogAdmin.cs @@ -0,0 +1,143 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Controls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageLogAdmin : BasePage + { + public DateTimeTextBox TbDateFrom; + public DateTimeTextBox TbDateTo; + public TextBox TbUserName; + public TextBox TbKeyword; + public Repeater RptContents; + public SqlPager SpContents; + public Literal LtlState; + public Button BtnDelete; + public Button BtnDeleteAll; + public Button BtnSetting; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + SpContents.ControlToPaginate = RptContents; + SpContents.ItemsPerPage = Constants.PageSize; + + SpContents.SelectCommand = !AuthRequest.IsQueryExists("Keyword") ? DataProvider.Log.GetSelectCommend() : DataProvider.Log.GetSelectCommend(AuthRequest.GetQueryString("UserName"), AuthRequest.GetQueryString("Keyword"), AuthRequest.GetQueryString("DateFrom"), AuthRequest.GetQueryString("DateTo")); + + SpContents.SortField = nameof(LogInfo.Id); + SpContents.SortMode = SortMode.DESC; + RptContents.ItemDataBound += RptContents_ItemDataBound; + + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.Log); + + if (AuthRequest.IsQueryExists("Keyword")) + { + TbUserName.Text = AuthRequest.GetQueryString("UserName"); + TbKeyword.Text = AuthRequest.GetQueryString("Keyword"); + TbDateFrom.Text = AuthRequest.GetQueryString("DateFrom"); + TbDateTo.Text = AuthRequest.GetQueryString("DateTo"); + } + + if (AuthRequest.IsQueryExists("DeleteById")) + { + var arraylist = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("IDCollection")); + try + { + DataProvider.Log.Delete(arraylist); + SuccessDeleteMessage(); + } + catch (Exception ex) + { + FailDeleteMessage(ex); + } + } + else if (AuthRequest.IsQueryExists("DeleteAll")) + { + DataProvider.Log.DeleteAll(); + SuccessDeleteMessage(); + } + else if (AuthRequest.IsQueryExists("Setting")) + { + ConfigManager.Instance.IsLogAdmin = !ConfigManager.Instance.IsLogAdmin; + DataProvider.Config.Update(ConfigManager.Instance); + SuccessMessage($"成功{(ConfigManager.Instance.IsLogAdmin ? "启用" : "禁用")}日志记录"); + } + + BtnDelete.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert(FxUtils.GetSettingsUrl(nameof(PageLogAdmin), new NameValueCollection + { + {"DeleteById", "True" } + }), "IDCollection", "IDCollection", "请选择需要删除的日志!", "此操作将删除所选日志,确认吗?")); + + BtnDeleteAll.Attributes.Add("onclick", + AlertUtils.ConfirmRedirect("删除所有日志", "此操作将删除所有日志信息,确定吗?", "删除全部", + FxUtils.GetSettingsUrl(nameof(PageLogAdmin), new NameValueCollection + { + {"DeleteAll", "True"} + }))); + + if (ConfigManager.Instance.IsLogAdmin) + { + BtnSetting.Text = "禁用管理员日志"; + BtnSetting.Attributes.Add("onclick", + AlertUtils.ConfirmRedirect("禁用管理员日志", "此操作将禁用管理员日志记录功能,确定吗?", "禁 用", + FxUtils.GetSettingsUrl(nameof(PageLogAdmin), new NameValueCollection + { + {"Setting", "True"} + }))); + } + else + { + LtlState.Text = @"
    管理员日志当前处于禁用状态,系统将不会记录管理员操作日志!
    "; + BtnSetting.Text = "启用管理员日志"; + BtnSetting.Attributes.Add("onclick", + AlertUtils.ConfirmRedirect("启用管理员日志", "此操作将启用管理员日志记录功能,确定吗?", "启 用", + FxUtils.GetSettingsUrl(nameof(PageLogAdmin), new NameValueCollection + { + {"Setting", "True"} + }))); + } + + SpContents.DataBind(); + } + + private static void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var ltlUserName = (Literal)e.Item.FindControl("ltlUserName"); + var ltlAddDate = (Literal)e.Item.FindControl("ltlAddDate"); + var ltlIpAddress = (Literal)e.Item.FindControl("ltlIpAddress"); + var ltlAction = (Literal)e.Item.FindControl("ltlAction"); + var ltlSummary = (Literal)e.Item.FindControl("ltlSummary"); + + ltlUserName.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(LogInfo.UserName)); + ltlAddDate.Text = DateUtils.GetDateAndTimeString(SqlUtils.EvalDateTime(e.Item.DataItem, nameof(LogInfo.AddDate))); + ltlIpAddress.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(LogInfo.IpAddress)); + ltlAction.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(LogInfo.Action)); + ltlSummary.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(LogInfo.Summary)); + } + + public void Search_OnClick(object sender, EventArgs e) + { + WebPageUtils.Redirect(FxUtils.GetSettingsUrl(nameof(PageLogAdmin), new NameValueCollection + { + {"UserName", TbUserName.Text}, + {"Keyword", TbKeyword.Text}, + {"DateFrom", TbDateFrom.Text}, + {"DateTo", TbDateTo.Text} + })); + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Settings/PageLogConfiguration.cs b/net452/SiteServer.BackgroundPages/Settings/PageLogConfiguration.cs new file mode 100644 index 000000000..bb216a284 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageLogConfiguration.cs @@ -0,0 +1,51 @@ +using System; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageLogConfiguration : BasePage + { + protected RadioButtonList RblIsTimeThreshold; + public PlaceHolder PhTimeThreshold; + protected TextBox TbTime; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.Log); + + FxUtils.AddListItems(RblIsTimeThreshold, "启用", "不启用"); + SystemWebUtils.SelectSingleItem(RblIsTimeThreshold, ConfigManager.Instance.IsTimeThreshold.ToString()); + TbTime.Text = ConfigManager.Instance.TimeThreshold.ToString(); + + PhTimeThreshold.Visible = TranslateUtils.ToBool(RblIsTimeThreshold.SelectedValue); + } + + public void RblIsTimeThreshold_SelectedIndexChanged(object sender, EventArgs e) + { + PhTimeThreshold.Visible = TranslateUtils.ToBool(RblIsTimeThreshold.SelectedValue); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + ConfigManager.Instance.IsTimeThreshold = TranslateUtils.ToBool(RblIsTimeThreshold.SelectedValue); + if (ConfigManager.Instance.IsTimeThreshold) + { + ConfigManager.Instance.TimeThreshold = TranslateUtils.ToInt(TbTime.Text); + } + + DataProvider.Config.Update(ConfigManager.Instance); + + AuthRequest.AddAdminLog("设置日志阈值参数"); + SuccessMessage("日志设置成功"); + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Settings/PageLogError.cs b/net452/SiteServer.BackgroundPages/Settings/PageLogError.cs new file mode 100644 index 000000000..cc2edc5f7 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageLogError.cs @@ -0,0 +1,175 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Controls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageLogError : BasePage + { + public DropDownList DdlCategory; + public DropDownList DdlPluginId; + public DateTimeTextBox TbDateFrom; + public DateTimeTextBox TbDateTo; + public TextBox TbKeyword; + public Repeater RptContents; + public SqlPager SpContents; + public Button BtnDelete; + public Button BtnDeleteAll; + public Literal LtlState; + public Button BtnSetting; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + if (AuthRequest.IsQueryExists("DeleteById")) + { + var list = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("IDCollection")); + try + { + DataProvider.ErrorLog.Delete(list); + SuccessDeleteMessage(); + } + catch (Exception ex) + { + FailDeleteMessage(ex); + } + } + else if (AuthRequest.IsQueryExists("DeleteAll")) + { + try + { + DataProvider.ErrorLog.DeleteAll(); + SuccessDeleteMessage(); + } + catch (Exception ex) + { + FailDeleteMessage(ex); + } + } + else if (AuthRequest.IsQueryExists("Setting")) + { + ConfigManager.Instance.IsLogError = !ConfigManager.Instance.IsLogError; + DataProvider.Config.Update(ConfigManager.Instance); + SuccessMessage($"成功{(ConfigManager.Instance.IsLogError ? "启用" : "禁用")}日志记录"); + } + + SpContents.ControlToPaginate = RptContents; + SpContents.ItemsPerPage = Constants.PageSize; + + SpContents.SelectCommand = DataProvider.ErrorLog.GetSelectCommend(AuthRequest.GetQueryString("category"), AuthRequest.GetQueryString("pluginId"), AuthRequest.GetQueryString("keyword"), + AuthRequest.GetQueryString("dateFrom"), AuthRequest.GetQueryString("dateTo")); + + SpContents.SortField = nameof(ErrorLogInfo.Id); + SpContents.SortMode = SortMode.DESC; + RptContents.ItemDataBound += RptContents_ItemDataBound; + + if (IsPostBack) return; + + DdlCategory.Items.Add(new ListItem("全部", string.Empty)); + foreach (var category in LogUtils.AllCategoryList.Value) + { + DdlCategory.Items.Add(new ListItem(category.Value, category.Key)); + } + + DdlPluginId.Items.Add(new ListItem("全部", string.Empty)); + foreach (var pluginInfo in PluginManager.AllPluginInfoList) + { + DdlPluginId.Items.Add(new ListItem(pluginInfo.Id, pluginInfo.Id)); + } + + VerifySystemPermissions(ConfigManager.SettingsPermissions.Log); + + if (AuthRequest.IsQueryExists("keyword")) + { + SystemWebUtils.SelectSingleItem(DdlCategory, AuthRequest.GetQueryString("category")); + SystemWebUtils.SelectSingleItem(DdlPluginId, AuthRequest.GetQueryString("pluginId")); + TbKeyword.Text = AuthRequest.GetQueryString("keyword"); + TbDateFrom.Text = AuthRequest.GetQueryString("dateFrom"); + TbDateTo.Text = AuthRequest.GetQueryString("dateTo"); + } + + BtnDelete.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert(FxUtils.GetSettingsUrl(nameof(PageLogError), new NameValueCollection + { + {"DeleteById", "True" } + }), "IDCollection", "IDCollection", "请选择需要删除的日志!", "此操作将删除所选日志,确认吗?")); + + BtnDeleteAll.Attributes.Add("onclick", + AlertUtils.ConfirmRedirect("删除所有日志", "此操作将删除所有日志信息,确定吗?", "删除全部", + FxUtils.GetSettingsUrl(nameof(PageLogError), new NameValueCollection + { + {"DeleteAll", "True"} + }))); + + if (ConfigManager.Instance.IsLogError) + { + BtnSetting.Text = "禁用系统错误日志"; + BtnSetting.Attributes.Add("onclick", + AlertUtils.ConfirmRedirect("禁用系统错误日志", "此操作将禁用系统错误日志记录功能,确定吗?", "禁 用", + FxUtils.GetSettingsUrl(nameof(PageLogError), new NameValueCollection + { + {"Setting", "True"} + }))); + } + else + { + LtlState.Text = @"
    系统错误日志当前处于禁用状态,系统将不会记录系统错误日志!
    "; + BtnSetting.Text = "启用系统错误日志"; + BtnSetting.Attributes.Add("onclick", + AlertUtils.ConfirmRedirect("启用系统错误日志", "此操作将启用系统错误日志记录功能,确定吗?", "启 用", + FxUtils.GetSettingsUrl(nameof(PageLogError), new NameValueCollection + { + {"Setting", "True"} + }))); + } + + SpContents.DataBind(); + } + + private static void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var id = SqlUtils.EvalInt(e.Item.DataItem, nameof(ErrorLogInfo.Id)); + var addDate = SqlUtils.EvalDateTime(e.Item.DataItem, nameof(ErrorLogInfo.AddDate)); + var message = SqlUtils.EvalString(e.Item.DataItem, nameof(ErrorLogInfo.Message)); + var summary = SqlUtils.EvalString(e.Item.DataItem, nameof(ErrorLogInfo.Summary)); + + var ltlId = (Literal)e.Item.FindControl("ltlId"); + var ltlAddDate = (Literal)e.Item.FindControl("ltlAddDate"); + var ltlMessage = (Literal)e.Item.FindControl("ltlMessage"); + var ltlSummary = (Literal)e.Item.FindControl("ltlSummary"); + + ltlId.Text = $@"{id}"; + ltlAddDate.Text = DateUtils.GetDateAndTimeString(addDate); + ltlMessage.Text = message; + ltlSummary.Text = summary; + if (!string.IsNullOrEmpty(ltlSummary.Text)) + { + ltlSummary.Text += "
    "; + } + } + + public void Search_OnClick(object sender, EventArgs e) + { + WebPageUtils.Redirect(FxUtils.GetSettingsUrl(nameof(PageLogError), new NameValueCollection + { + {"category", DdlCategory.SelectedValue}, + {"pluginId", DdlPluginId.SelectedValue}, + {"keyword", TbKeyword.Text}, + {"dateFrom", TbDateFrom.Text}, + {"dateTo", TbDateTo.Text} + })); + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Settings/PageLogSite.cs b/net452/SiteServer.BackgroundPages/Settings/PageLogSite.cs new file mode 100644 index 000000000..446bf8286 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageLogSite.cs @@ -0,0 +1,179 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Controls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageLogSite : BasePageCms + { + public DropDownList DdlSiteId; + public DropDownList DdlLogType; + public TextBox TbUserName; + public TextBox TbKeyword; + public DateTimeTextBox TbDateFrom; + public DateTimeTextBox TbDateTo; + + public Repeater RptContents; + public SqlPager SpContents; + public Literal LtlSite; + public Literal LtlState; + public Button BtnDelete; + public Button BtnDeleteAll; + public Button BtnSetting; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + SpContents.ControlToPaginate = RptContents; + SpContents.ItemsPerPage = Constants.PageSize; + + SpContents.SelectCommand = !AuthRequest.IsQueryExists("LogType") + ? DataProvider.SiteLog.GetSelectCommend() + : DataProvider.SiteLog.GetSelectCommend(SiteId, AuthRequest.GetQueryString("LogType"), + AuthRequest.GetQueryString("UserName"), AuthRequest.GetQueryString("Keyword"), AuthRequest.GetQueryString("DateFrom"), + AuthRequest.GetQueryString("DateTo")); + + SpContents.SortField = nameof(SiteLogInfo.Id); + SpContents.SortMode = SortMode.DESC; + RptContents.ItemDataBound += RptContents_ItemDataBound; + + if (AuthRequest.IsQueryExists("DeleteById")) + { + var arraylist = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("IDCollection")); + DataProvider.SiteLog.Delete(arraylist); + SuccessDeleteMessage(); + } + else if (AuthRequest.IsQueryExists("DeleteAll")) + { + DataProvider.SiteLog.DeleteAll(); + SuccessDeleteMessage(); + } + else if (AuthRequest.IsQueryExists("Setting")) + { + ConfigManager.Instance.IsLogSite = !ConfigManager.Instance.IsLogSite; + DataProvider.Config.Update(ConfigManager.Instance); + SuccessMessage($"成功{(ConfigManager.Instance.IsLogSite ? "启用" : "禁用")}日志记录"); + } + + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.Log); + + if (SiteId == 0) + { + LtlSite.Text = @"站点名称"; + } + + DdlSiteId.Items.Add(new ListItem("<<全部站点>>", "0")); + + var siteIdList = SiteManager.GetSiteIdListOrderByLevel(); + foreach (var psId in siteIdList) + { + DdlSiteId.Items.Add(new ListItem(SiteManager.GetSiteInfo(psId).SiteName, psId.ToString())); + } + + DdlLogType.Items.Add(new ListItem("全部记录", "All")); + DdlLogType.Items.Add(new ListItem("栏目相关记录", "Channel")); + DdlLogType.Items.Add(new ListItem("内容相关记录", "Content")); + + if (AuthRequest.IsQueryExists("LogType")) + { + SystemWebUtils.SelectSingleItem(DdlSiteId, SiteId.ToString()); + SystemWebUtils.SelectSingleItem(DdlLogType, AuthRequest.GetQueryString("LogType")); + TbUserName.Text = AuthRequest.GetQueryString("UserName"); + TbKeyword.Text = AuthRequest.GetQueryString("Keyword"); + TbDateFrom.Text = AuthRequest.GetQueryString("DateFrom"); + TbDateTo.Text = AuthRequest.GetQueryString("DateTo"); + } + + BtnDelete.Attributes.Add("onclick", + PageUtils.GetRedirectStringWithCheckBoxValueAndAlert( + FxUtils.GetSettingsUrl(nameof(PageLogSite), new NameValueCollection + { + {"DeleteById", "True"} + }), "IDCollection", "IDCollection", "请选择需要删除的日志!", "此操作将删除所选日志,确认吗?")); + + BtnDeleteAll.Attributes.Add("onclick", + AlertUtils.ConfirmRedirect("删除所有日志", "此操作将删除所有日志信息,确定吗?", "删除全部", + FxUtils.GetSettingsUrl(nameof(PageLogSite), new NameValueCollection + { + {"DeleteAll", "True"} + }))); + + if (ConfigManager.Instance.IsLogSite) + { + BtnSetting.Text = "禁用站点日志"; + BtnSetting.Attributes.Add("onclick", + AlertUtils.ConfirmRedirect("禁用站点日志", "此操作将禁用站点日志记录功能,确定吗?", "禁 用", + FxUtils.GetSettingsUrl(nameof(PageLogSite), new NameValueCollection + { + {"Setting", "True"} + }))); + } + else + { + LtlState.Text = @"
    站点日志当前处于禁用状态,系统将不会记录站点操作日志!
    "; + BtnSetting.Text = "启用站点日志"; + BtnSetting.Attributes.Add("onclick", + AlertUtils.ConfirmRedirect("启用站点日志", "此操作将启用站点日志记录功能,确定吗?", "启 用", + FxUtils.GetSettingsUrl(nameof(PageLogSite), new NameValueCollection + { + {"Setting", "True"} + }))); + } + + SpContents.DataBind(); + } + + private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var ltlSite = (Literal)e.Item.FindControl("ltlSite"); + var ltlUserName = (Literal)e.Item.FindControl("ltlUserName"); + var ltlAddDate = (Literal)e.Item.FindControl("ltlAddDate"); + var ltlIpAddress = (Literal)e.Item.FindControl("ltlIpAddress"); + var ltlAction = (Literal)e.Item.FindControl("ltlAction"); + var ltlSummary = (Literal)e.Item.FindControl("ltlSummary"); + + if (SiteId == 0) + { + var siteInfo = SiteManager.GetSiteInfo(SqlUtils.EvalInt(e.Item.DataItem, nameof(SiteLogInfo.SiteId))); + var siteName = string.Empty; + if (siteInfo != null) + { + siteName = + $"{siteInfo.SiteName}"; + } + ltlSite.Text = $@"{siteName}"; + } + ltlUserName.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(SiteLogInfo.UserName)); + ltlAddDate.Text = DateUtils.GetDateAndTimeString(SqlUtils.EvalDateTime(e.Item.DataItem, nameof(SiteLogInfo.AddDate))); + ltlIpAddress.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(SiteLogInfo.IpAddress)); + ltlAction.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(SiteLogInfo.Action)); + ltlSummary.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(SiteLogInfo.Summary)); + } + + public void Search_OnClick(object sender, EventArgs e) + { + WebPageUtils.Redirect(FxUtils.GetSettingsUrl(nameof(PageLogSite), new NameValueCollection + { + {"UserName", TbUserName.Text}, + {"Keyword", TbKeyword.Text}, + {"DateFrom", TbDateFrom.Text}, + {"DateTo", TbDateTo.Text}, + {"SiteId", DdlSiteId.SelectedValue}, + {"LogType", DdlLogType.SelectedValue} + })); + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Settings/PageLogUser.cs b/net452/SiteServer.BackgroundPages/Settings/PageLogUser.cs new file mode 100644 index 000000000..433be2c43 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageLogUser.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Controls; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageLogUser : BasePage + { + public DateTimeTextBox TbDateFrom; + public DateTimeTextBox TbDateTo; + public TextBox TbUserName; + public TextBox TbKeyword; + public Repeater RptContents; + public SqlPager SpContents; + public Literal LtlState; + public Button BtnDelete; + public Button BtnDeleteAll; + public Button BtnSetting; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + SpContents.ControlToPaginate = RptContents; + SpContents.ItemsPerPage = Constants.PageSize; + + SpContents.SelectCommand = !AuthRequest.IsQueryExists("Keyword") ? DataProvider.UserLog.GetSelectCommend() : DataProvider.UserLog.GetSelectCommend(AuthRequest.GetQueryString("UserName"), AuthRequest.GetQueryString("Keyword"), AuthRequest.GetQueryString("DateFrom"), AuthRequest.GetQueryString("DateTo")); + + SpContents.SortField = nameof(UserLogInfo.Id); + SpContents.SortMode = SortMode.DESC; + RptContents.ItemDataBound += RptContents_ItemDataBound; + + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.Log); + + if (AuthRequest.IsQueryExists("Keyword")) + { + TbUserName.Text = AuthRequest.GetQueryString("UserName"); + TbKeyword.Text = AuthRequest.GetQueryString("Keyword"); + TbDateFrom.Text = AuthRequest.GetQueryString("DateFrom"); + TbDateTo.Text = AuthRequest.GetQueryString("DateTo"); + } + + if (AuthRequest.IsQueryExists("DeleteById")) + { + var list = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("IDCollection")); + DataProvider.UserLog.Delete(list); + SuccessDeleteMessage(); + } + else if (AuthRequest.IsQueryExists("DeleteAll")) + { + DataProvider.UserLog.DeleteAll(); + SuccessDeleteMessage(); + } + else if (AuthRequest.IsQueryExists("Setting")) + { + ConfigManager.Instance.IsLogUser = !ConfigManager.Instance.IsLogUser; + DataProvider.Config.Update(ConfigManager.Instance); + SuccessMessage($"成功{(ConfigManager.Instance.IsLogUser ? "启用" : "禁用")}日志记录"); + } + + BtnDelete.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert(FxUtils.GetSettingsUrl(nameof(PageLogUser), new NameValueCollection + { + {"DeleteById", "True" } + }), "IDCollection", "IDCollection", "请选择需要删除的日志!", "此操作将删除所选日志,确认吗?")); + + BtnDeleteAll.Attributes.Add("onclick", + AlertUtils.ConfirmRedirect("删除所有日志", "此操作将删除所有日志信息,确定吗?", "删除全部", + FxUtils.GetSettingsUrl(nameof(PageLogUser), new NameValueCollection + { + {"DeleteAll", "True"} + }))); + + if (ConfigManager.Instance.IsLogUser) + { + BtnSetting.Text = "禁用用户日志"; + BtnSetting.Attributes.Add("onclick", + AlertUtils.ConfirmRedirect("禁用用户日志", "此操作将禁用用户日志记录功能,确定吗?", "禁 用", + FxUtils.GetSettingsUrl(nameof(PageLogUser), new NameValueCollection + { + {"Setting", "True"} + }))); + } + else + { + LtlState.Text = @"
    用户日志当前处于禁用状态,系统将不会记录用户操作日志!
    "; + BtnSetting.Text = "启用用户日志"; + BtnSetting.Attributes.Add("onclick", + AlertUtils.ConfirmRedirect("启用用户日志", "此操作将启用用户日志记录功能,确定吗?", "启 用", + FxUtils.GetSettingsUrl(nameof(PageLogUser), new NameValueCollection + { + {"Setting", "True"} + }))); + } + + SpContents.DataBind(); + } + + private static void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var ltlUserName = (Literal)e.Item.FindControl("ltlUserName"); + var ltlAddDate = (Literal)e.Item.FindControl("ltlAddDate"); + var ltlIpAddress = (Literal)e.Item.FindControl("ltlIpAddress"); + var ltlAction = (Literal)e.Item.FindControl("ltlAction"); + var ltlSummary = (Literal)e.Item.FindControl("ltlSummary"); + + ltlUserName.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(UserLogInfo.UserName)); + ltlAddDate.Text = DateUtils.GetDateAndTimeString(SqlUtils.EvalDateTime(e.Item.DataItem, nameof(UserLogInfo.AddDate))); + ltlIpAddress.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(UserLogInfo.IpAddress)); + ltlAction.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(UserLogInfo.Action)); + ltlSummary.Text = SqlUtils.EvalString(e.Item.DataItem, nameof(UserLogInfo.Summary)); + } + + public void Search_OnClick(object sender, EventArgs e) + { + WebPageUtils.Redirect(FxUtils.GetSettingsUrl(nameof(PageLogUser), new NameValueCollection + { + {"UserName", TbUserName.Text}, + {"Keyword", TbKeyword.Text}, + {"DateFrom", TbDateFrom.Text}, + {"DateTo", TbDateTo.Text} + })); + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Settings/PageSite.cs b/net452/SiteServer.BackgroundPages/Settings/PageSite.cs new file mode 100644 index 000000000..270757a91 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageSite.cs @@ -0,0 +1,107 @@ +using System; +using System.Text; +using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageSite : BasePageCms + { + public Repeater RptContents; + + private int _hqSiteId; + + public static string GetRedirectUrl() + { + return FxUtils.GetSettingsUrl(nameof(PageSite), null); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.Site); + + _hqSiteId = DataProvider.Site.GetIdByIsRoot(); + + RptContents.DataSource = SiteManager.GetSiteIdListOrderByLevel(); + RptContents.ItemDataBound += RptContents_ItemDataBound; + RptContents.DataBind(); + } + + private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var siteId = (int)e.Item.DataItem; + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return; + + var ltlSiteName = (Literal)e.Item.FindControl("ltlSiteName"); + var ltlSiteDir = (Literal)e.Item.FindControl("ltlSiteDir"); + var ltlTableName = (Literal)e.Item.FindControl("ltlTableName"); + var ltlTaxis = (Literal)e.Item.FindControl("ltlTaxis"); + var ltlActions = (Literal)e.Item.FindControl("ltlActions"); + + ltlSiteName.Text = GetSiteNameHtml(siteInfo); + ltlSiteDir.Text = siteInfo.SiteDir; + ltlTableName.Text = siteInfo.TableName; + ltlTaxis.Text = siteInfo.Taxis == 0 ? string.Empty : siteInfo.Taxis.ToString(); + + var builder = new StringBuilder(); + + builder.Append($@"保存"); + builder.Append($@"修改"); + if (siteInfo.ParentId == 0 && (_hqSiteId == 0 || siteId == _hqSiteId)) + { + builder.Append($@"{(siteInfo.Root ? "转移到子目录" : "转移到根目录")}"); + } + + if (siteInfo.Root == false) + { + builder.Append($@"删除"); + } + + ltlActions.Text = builder.ToString(); + } + + private static string GetSiteNameHtml(SiteInfo siteInfo) + { + var level = SiteManager.GetSiteLevel(siteInfo.Id); + string psLogo; + if (siteInfo.Root) + { + psLogo = "siteHQ.gif"; + } + else + { + psLogo = "site.gif"; + if (level > 0 && level < 10) + { + psLogo = $"subsite{level + 1}.gif"; + } + } + psLogo = SiteServerAssets.GetIconUrl("tree/" + psLogo); + + var padding = string.Empty; + for (var i = 0; i < level; i++) + { + padding += " "; + } + if (level > 0) + { + padding += "└ "; + } + + return + $"{padding} {StringUtils.MaxLengthText(siteInfo.SiteName, 20)}"; + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Settings/PageSiteAdd.cs b/net452/SiteServer.BackgroundPages/Settings/PageSiteAdd.cs new file mode 100644 index 000000000..69b597686 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageSiteAdd.cs @@ -0,0 +1,598 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.IO; +using System.Web.UI.HtmlControls; +using System.Web.UI.WebControls; +using Datory; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Cms; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Database.Repositories.Contents; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageSiteAdd : BasePageCms + { + protected override bool IsSinglePage => true; + + public PlaceHolder PhSource; + public RadioButtonList RblSource; + public HtmlInputHidden HihSiteTemplateDir; + public HtmlInputHidden HihOnlineTemplateName; + public PlaceHolder PhSiteTemplates; + public Repeater RptSiteTemplates; + public PlaceHolder PhOnlineTemplates; + public Repeater RptOnlineTemplates; + public PlaceHolder PhSubmit; + public Literal LtlSource; + public TextBox TbSiteName; + public RadioButtonList RblIsRoot; + public PlaceHolder PhIsNotRoot; + public DropDownList DdlParentId; + public TextBox TbSiteDir; + public DropDownList DdlCharset; + public PlaceHolder PhIsImportContents; + public CheckBox CbIsImportContents; + public PlaceHolder PhIsImportTableStyles; + public CheckBox CbIsImportTableStyles; + + public RadioButtonList RblTableRule; + public PlaceHolder PhTableChoose; + public DropDownList DdlTableChoose; + public PlaceHolder PhTableHandWrite; + public TextBox TbTableHandWrite; + + public RadioButtonList RblIsCheckContentUseLevel; + public PlaceHolder PhCheckContentLevel; + public DropDownList DdlCheckContentLevel; + + public Button BtnPrevious; + public Button BtnNext; + public Button BtnSubmit; + + public static string GetRedirectUrl() + { + return FxUtils.GetSettingsUrl(nameof(PageSiteAdd), null); + } + + public static string GetRedirectUrl(string siteTemplateDir, string onlineTemplateName) + { + return FxUtils.GetSettingsUrl(nameof(PageSiteAdd), new NameValueCollection + { + {"siteTemplateDir", siteTemplateDir}, + {"onlineTemplateName", onlineTemplateName} + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.SiteAdd); + + //DataProvider.TableDao.CreateAllTableCollectionInfoIfNotExists(); + + var hqSiteId = DataProvider.Site.GetIdByIsRoot(); + if (hqSiteId == 0) + { + SystemWebUtils.SelectSingleItem(RblIsRoot, true.ToString()); + PhIsNotRoot.Visible = false; + } + else + { + RblIsRoot.Enabled = false; + } + + DdlParentId.Items.Add(new ListItem("<无上级站点>", "0")); + var siteIdArrayList = SiteManager.GetSiteIdList(); + var mySystemInfoArrayList = new ArrayList(); + var parentWithChildren = new Hashtable(); + foreach (var siteId in siteIdArrayList) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo.Root == false) + { + if (siteInfo.ParentId == 0) + { + mySystemInfoArrayList.Add(siteInfo); + } + else + { + var children = new ArrayList(); + if (parentWithChildren.Contains(siteInfo.ParentId)) + { + children = (ArrayList)parentWithChildren[siteInfo.ParentId]; + } + children.Add(siteInfo); + parentWithChildren[siteInfo.ParentId] = children; + } + } + } + foreach (SiteInfo siteInfo in mySystemInfoArrayList) + { + AddSite(DdlParentId, siteInfo, parentWithChildren, 0); + } + SystemWebUtils.SelectSingleItem(DdlParentId, "0"); + + FxUtils.AddListItemsToECharset(DdlCharset); + SystemWebUtils.SelectSingleItem(DdlCharset, ECharsetUtils.GetValue(ECharset.utf_8)); + + var tableNameList = SiteManager.GetSiteTableNames(); + if (tableNameList.Count > 0) + { + RblTableRule.Items.Add(SystemWebUtils.GetListItem(ETableRule.Choose, true)); + RblTableRule.Items.Add(SystemWebUtils.GetListItem(ETableRule.Create, false)); + RblTableRule.Items.Add(SystemWebUtils.GetListItem(ETableRule.HandWrite, false)); + + PhTableChoose.Visible = true; + PhTableHandWrite.Visible = false; + + foreach (var tableName in tableNameList) + { + DdlTableChoose.Items.Add(new ListItem(tableName, tableName)); + } + } + else + { + RblTableRule.Items.Add(SystemWebUtils.GetListItem(ETableRule.Create, true)); + RblTableRule.Items.Add(SystemWebUtils.GetListItem(ETableRule.HandWrite, false)); + + PhTableChoose.Visible = false; + PhTableHandWrite.Visible = false; + } + + RblIsCheckContentUseLevel.Items.Add(new ListItem("默认审核机制", false.ToString())); + RblIsCheckContentUseLevel.Items.Add(new ListItem("多级审核机制", true.ToString())); + SystemWebUtils.SelectSingleItem(RblIsCheckContentUseLevel, false.ToString()); + + if (SiteTemplateManager.Instance.IsSiteTemplateExists) + { + RblSource.Items.Add(new ListItem("创建空站点(不使用站点模板)", ETriStateUtils.GetValue(ETriState.True))); + RblSource.Items.Add(new ListItem("使用本地站点模板创建站点", ETriStateUtils.GetValue(ETriState.False))); + RblSource.Items.Add(new ListItem("使用在线站点模板创建站点", ETriStateUtils.GetValue(ETriState.All))); + } + else + { + RblSource.Items.Add(new ListItem("创建空站点(不使用站点模板)", ETriStateUtils.GetValue(ETriState.True))); + RblSource.Items.Add(new ListItem("使用在线站点模板创建站点", ETriStateUtils.GetValue(ETriState.All))); + } + SystemWebUtils.SelectSingleItem(RblSource, ETriStateUtils.GetValue(ETriState.True)); + + var siteTemplateDir = AuthRequest.GetQueryString("siteTemplateDir"); + var onlineTemplateName = AuthRequest.GetQueryString("onlineTemplateName"); + + if (!string.IsNullOrEmpty(siteTemplateDir)) + { + HihSiteTemplateDir.Value = siteTemplateDir; + SystemWebUtils.SelectSingleItem(RblSource, ETriStateUtils.GetValue(ETriState.False)); + BtnNext_Click(null, EventArgs.Empty); + } + else if (!string.IsNullOrEmpty(onlineTemplateName)) + { + HihOnlineTemplateName.Value = onlineTemplateName; + SystemWebUtils.SelectSingleItem(RblSource, ETriStateUtils.GetValue(ETriState.All)); + BtnNext_Click(null, EventArgs.Empty); + } + } + + private bool IsSiteTemplate => ETriStateUtils.GetEnumType(RblSource.SelectedValue) == ETriState.False; + + private bool IsOnlineTemplate => ETriStateUtils.GetEnumType(RblSource.SelectedValue) == ETriState.All; + + public void RblIsRoot_SelectedIndexChanged(object sender, EventArgs e) + { + PhIsNotRoot.Visible = !TranslateUtils.ToBool(RblIsRoot.SelectedValue); + } + + public void RblIsCheckContentUseLevel_OnSelectedIndexChanged(object sender, EventArgs e) + { + PhCheckContentLevel.Visible = EBooleanUtils.Equals(RblIsCheckContentUseLevel.SelectedValue, EBoolean.True); + } + + public void RblTableRule_OnSelectedIndexChanged(object sender, EventArgs e) + { + var tableRule = ETableRuleUtils.GetEnumType(RblTableRule.SelectedValue); + PhTableChoose.Visible = PhTableHandWrite.Visible = false; + if (tableRule == ETableRule.Choose) + { + PhTableChoose.Visible = true; + } + else if (tableRule == ETableRule.HandWrite) + { + PhTableHandWrite.Visible = true; + } + } + + public void BtnNext_Click(object sender, EventArgs e) + { + if (PhSource.Visible) + { + HideAll(); + + if (IsSiteTemplate) + { + var siteTemplates = SiteTemplateManager.Instance.GetSiteTemplateSortedList(); + + RptSiteTemplates.DataSource = siteTemplates.Values; + RptSiteTemplates.ItemDataBound += RptSiteTemplates_ItemDataBound; + RptSiteTemplates.DataBind(); + + ShowSiteTemplates(); + } + else if (IsOnlineTemplate) + { + List> list; + if (OnlineTemplateManager.TryGetOnlineTemplates(out list)) + { + RptOnlineTemplates.DataSource = list; + RptOnlineTemplates.ItemDataBound += RptOnlineTemplates_ItemDataBound; + RptOnlineTemplates.DataBind(); + + ShowOnlineTemplates(); + } + else + { + FailMessage($"在线模板获取失败:页面地址{OnlineTemplateManager.UrlHome}无法访问!"); + + ShowSource(); + } + } + else + { + LtlSource.Text = "创建空站点(不使用站点模板)"; + + ShowSubmit(); + } + } + else if (PhSiteTemplates.Visible) + { + HideAll(); + + var siteTemplateDir = HihSiteTemplateDir.Value; + + if (string.IsNullOrEmpty(siteTemplateDir)) + { + FailMessage("请选择需要使用的站点模板"); + ShowSiteTemplates(); + return; + } + + LtlSource.Text = $"使用本地站点模板创建站点({siteTemplateDir})"; + + ShowSubmit(); + } + else if (PhOnlineTemplates.Visible) + { + HideAll(); + + var onlineTemplateName = HihOnlineTemplateName.Value; + + if (string.IsNullOrEmpty(onlineTemplateName)) + { + FailMessage("请选择需要使用的在线站点模板"); + ShowOnlineTemplates(); + return; + } + + LtlSource.Text = $@"使用在线站点模板创建站点({onlineTemplateName})"; + + ShowSubmit(); + } + } + + public void BtnSubmit_Click(object sender, EventArgs e) + { + HideAll(); + + string errorMessage; + var theSiteId = Validate_SiteInfo(out errorMessage); + if (theSiteId > 0) + { + var siteTemplateDir = IsSiteTemplate ? HihSiteTemplateDir.Value : string.Empty; + var onlineTemplateName = IsOnlineTemplate ? HihOnlineTemplateName.Value : string.Empty; + WebPageUtils.Redirect(PageProgressBar.GetCreateSiteUrl(theSiteId, + CbIsImportContents.Checked, CbIsImportTableStyles.Checked, siteTemplateDir, onlineTemplateName, StringUtils.GetGuid())); + } + else + { + FailMessage(errorMessage); + + ShowSubmit(); + } + } + + public void BtnPrevious_Click(object sender, EventArgs e) + { + if (PhSiteTemplates.Visible || PhOnlineTemplates.Visible) + { + HideAll(); + ShowSource(); + } + else if (PhSubmit.Visible) + { + HideAll(); + + if (IsSiteTemplate) + { + ShowSiteTemplates(); + } + else if (IsOnlineTemplate) + { + ShowOnlineTemplates(); + } + else + { + ShowSource(); + } + } + } + + private void RptSiteTemplates_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.AlternatingItem && e.Item.ItemType != ListItemType.Item) return; + + var templateInfo = (SiteTemplateInfo)e.Item.DataItem; + if (templateInfo == null) return; + + var directoryPath = PathUtility.GetSiteTemplatesPath(templateInfo.DirectoryName); + var directoryInfo = new DirectoryInfo(directoryPath); + + var ltlChoose = (Literal)e.Item.FindControl("ltlChoose"); + var ltlTemplateName = (Literal)e.Item.FindControl("ltlTemplateName"); + var ltlName = (Literal)e.Item.FindControl("ltlName"); + var ltlDescription = (Literal)e.Item.FindControl("ltlDescription"); + var ltlSamplePic = (Literal)e.Item.FindControl("ltlSamplePic"); + + ltlChoose.Text = $@""; + + if (!string.IsNullOrEmpty(templateInfo.SiteTemplateName)) + { + ltlTemplateName.Text = !string.IsNullOrEmpty(templateInfo.WebSiteUrl) ? $@"{templateInfo.SiteTemplateName}" : templateInfo.SiteTemplateName; + } + + ltlName.Text = directoryInfo.Name; + + if (!string.IsNullOrEmpty(templateInfo.Description)) + { + ltlDescription.Text = templateInfo.Description; + } + + if (!string.IsNullOrEmpty(templateInfo.PicFileName)) + { + var siteTemplateUrl = FxUtils.GetSiteTemplatesUrl(directoryInfo.Name); + var picFileName = FxUtils.GetSiteTemplateMetadataUrl(siteTemplateUrl, templateInfo.PicFileName); + ltlSamplePic.Text = $@"样图"; + } + } + + private void RptOnlineTemplates_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.AlternatingItem && e.Item.ItemType != ListItemType.Item) return; + + var dict = (Dictionary)e.Item.DataItem; + var title = dict["title"]; + var description = dict["description"]; + var author = dict["author"]; + var source = dict["source"]; + var lastEditDate = dict["lastEditDate"]; + + var ltlChoose = (Literal)e.Item.FindControl("ltlChoose"); + var ltlTitle = (Literal)e.Item.FindControl("ltlTitle"); + var ltlDescription = (Literal)e.Item.FindControl("ltlDescription"); + var ltlAuthor = (Literal)e.Item.FindControl("ltlAuthor"); + var ltlLastEditDate = (Literal)e.Item.FindControl("ltlLastEditDate"); + var ltlPreviewUrl = (Literal)e.Item.FindControl("ltlPreviewUrl"); + + ltlChoose.Text = $@""; + + var templateUrl = OnlineTemplateManager.GetTemplateUrl(title); + + ltlTitle.Text = $@"{title}"; + + ltlDescription.Text = description; + ltlAuthor.Text = author; + if (!string.IsNullOrEmpty(source) && PageUtils.IsProtocolUrl(source)) + { + ltlAuthor.Text = $@"{ltlAuthor.Text}"; + } + ltlLastEditDate.Text = lastEditDate; + + ltlPreviewUrl.Text = $@"模板详情"; + } + + private int Validate_SiteInfo(out string errorMessage) + { + try + { + var isRoot = TranslateUtils.ToBool(RblIsRoot.SelectedValue); // 是否主站 + var parentSiteId = 0; + var siteDir = string.Empty; + + if (isRoot == false) + { + if (DirectoryUtils.IsSystemDirectory(TbSiteDir.Text)) + { + errorMessage = "文件夹名称不能为系统文件夹名称!"; + return 0; + } + + parentSiteId = TranslateUtils.ToInt(DdlParentId.SelectedValue); + siteDir = TbSiteDir.Text; + + var list = DataProvider.Site.GetLowerSiteDirList(parentSiteId); + if (list.IndexOf(siteDir.ToLower()) != -1) + { + errorMessage = "已存在相同的发布路径!"; + return 0; + } + + if (!DirectoryUtils.IsDirectoryNameCompliant(siteDir)) + { + errorMessage = "文件夹名称不符合系统要求!"; + return 0; + } + } + + var nodeInfo = new ChannelInfo(); + + nodeInfo.ChannelName = nodeInfo.IndexName = "首页"; + nodeInfo.ParentId = 0; + nodeInfo.ContentModelPluginId = string.Empty; + + var tableName = string.Empty; + var tableRule = ETableRuleUtils.GetEnumType(RblTableRule.SelectedValue); + if (tableRule == ETableRule.Choose) + { + tableName = DdlTableChoose.SelectedValue; + } + else if (tableRule == ETableRule.HandWrite) + { + tableName = TbTableHandWrite.Text; + if (!DatoryUtils.IsTableExists(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName)) + { + TableColumnManager.CreateTable(tableName, DataProvider.ContentRepository.TableColumnsDefault, string.Empty, true, out _); + } + else + { + TableColumnManager.AlterTable(tableName, DataProvider.ContentRepository.TableColumnsDefault, string.Empty); + } + } + + var siteInfo = new SiteInfo + { + SiteName = AttackUtils.FilterXss(TbSiteName.Text), + SiteDir = siteDir, + TableName = tableName, + ParentId = parentSiteId, + Root = isRoot + }; + + siteInfo.IsCheckContentLevel = TranslateUtils.ToBool(RblIsCheckContentUseLevel.SelectedValue); + + if (siteInfo.IsCheckContentLevel) + { + siteInfo.CheckContentLevel = TranslateUtils.ToInt(DdlCheckContentLevel.SelectedValue); + } + siteInfo.Charset = DdlCharset.SelectedValue; + + var siteId = DataProvider.Channel.InsertSiteInfo(nodeInfo, siteInfo, AuthRequest.AdminName); + + if (string.IsNullOrEmpty(tableName)) + { + tableName = ContentRepository.GetContentTableName(siteId); + if (!DatoryUtils.IsTableExists(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName)) + { + TableColumnManager.CreateTable(tableName, DataProvider.ContentRepository.TableColumnsDefault, string.Empty, true, out _); + } + DataProvider.Site.UpdateTableName(siteId, tableName); + } + + if (AuthRequest.AdminPermissionsImpl.IsSystemAdministrator && !AuthRequest.AdminPermissionsImpl.IsConsoleAdministrator) + { + var siteIdList = AuthRequest.AdminPermissionsImpl.GetSiteIdList() ?? new List(); + siteIdList.Add(siteId); + var adminInfo = AdminManager.GetAdminInfoByUserId(AuthRequest.AdminId); + DataProvider.Administrator.UpdateSiteIdCollection(adminInfo, TranslateUtils.ObjectCollectionToString(siteIdList)); + } + + AuthRequest.AddAdminLog("创建新站点", $"站点名称:{AttackUtils.FilterXss(TbSiteName.Text)}"); + + errorMessage = string.Empty; + return siteId; + } + catch (Exception e) + { + errorMessage = e.Message; + return 0; + } + } + + private static void AddSite(ListControl listControl, SiteInfo siteInfo, Hashtable parentWithChildren, int level) + { + if (level > 1) return; + var padding = string.Empty; + for (var i = 0; i < level; i++) + { + padding += " "; + } + if (level > 0) + { + padding += "└ "; + } + + if (parentWithChildren[siteInfo.Id] != null) + { + var children = (ArrayList)parentWithChildren[siteInfo.Id]; + listControl.Items.Add(new ListItem(padding + siteInfo.SiteName + $"({children.Count})", siteInfo.Id.ToString())); + level++; + foreach (SiteInfo subSiteInfo in children) + { + AddSite(listControl, subSiteInfo, parentWithChildren, level); + } + } + else + { + listControl.Items.Add(new ListItem(padding + siteInfo.SiteName, siteInfo.Id.ToString())); + } + } + + private void HideAll() + { + PhSource.Visible = + PhSiteTemplates.Visible = + PhOnlineTemplates.Visible = + PhSubmit.Visible = PhIsImportContents.Visible = + PhIsImportTableStyles.Visible = + BtnPrevious.Enabled = BtnNext.Visible = BtnSubmit.Visible = false; + } + + private void ShowSource() + { + PhSource.Visible = BtnNext.Visible = true; + } + + private void ShowSiteTemplates() + { + PhSiteTemplates.Visible = BtnPrevious.Enabled = BtnNext.Visible = true; + } + + private void ShowOnlineTemplates() + { + PhOnlineTemplates.Visible = BtnPrevious.Enabled = BtnNext.Visible = true; + } + + private void ShowSubmit() + { + if (IsSiteTemplate) + { + PhSubmit.Visible = + PhIsImportContents.Visible = + PhIsImportTableStyles.Visible = + BtnPrevious.Enabled = BtnSubmit.Visible = true; + } + else if (IsOnlineTemplate) + { + PhSubmit.Visible = + PhIsImportContents.Visible = + PhIsImportTableStyles.Visible = + BtnPrevious.Enabled = BtnSubmit.Visible = true; + } + else + { + PhSubmit.Visible = BtnPrevious.Enabled = BtnSubmit.Visible = true; + } + } + } +} diff --git a/SiteServer.BackgroundPages/Settings/PageSiteDelete.cs b/net452/SiteServer.BackgroundPages/Settings/PageSiteDelete.cs similarity index 77% rename from SiteServer.BackgroundPages/Settings/PageSiteDelete.cs rename to net452/SiteServer.BackgroundPages/Settings/PageSiteDelete.cs index b67a88222..5eb83a648 100644 --- a/SiteServer.BackgroundPages/Settings/PageSiteDelete.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageSiteDelete.cs @@ -1,8 +1,12 @@ using System; using System.Collections.Specialized; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Settings { @@ -13,7 +17,7 @@ public class PageSiteDelete : BasePageCms public static string GetRedirectUrl(int siteId) { - return PageUtils.GetSettingsUrl(nameof(PageSiteDelete), new NameValueCollection + return FxUtils.GetSettingsUrl(nameof(PageSiteDelete), new NameValueCollection { {"siteId", siteId.ToString()} }); @@ -25,7 +29,7 @@ public void Page_Load(object sender, EventArgs e) if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Site); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Site); LtlSiteName.Text = SiteInfo.SiteName; @@ -55,17 +59,17 @@ public override void Submit_OnClick(object sender, EventArgs e) else { AddScript( - $@"setTimeout(""window.top.location.href='{PageMain.GetRedirectUrl()}'"", 1500);"); + $@"setTimeout(""window.top.location.href='{FxUtils.GetMainUrl(0, string.Empty)}'"", 1500);"); } AuthRequest.AddAdminLog("删除站点", $"站点:{SiteInfo.SiteName}"); - DataProvider.SiteDao.Delete(SiteId); + DataProvider.Site.Delete(SiteId); } public void Return_OnClick(object sender, EventArgs e) { - PageUtils.Redirect(PageSite.GetRedirectUrl()); + WebPageUtils.Redirect(PageSite.GetRedirectUrl()); } } } diff --git a/net452/SiteServer.BackgroundPages/Settings/PageSiteEdit.cs b/net452/SiteServer.BackgroundPages/Settings/PageSiteEdit.cs new file mode 100644 index 000000000..c19f7b74a --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageSiteEdit.cs @@ -0,0 +1,295 @@ +using System; +using System.Collections; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using Datory; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageSiteEdit : BasePageCms + { + public TextBox TbSiteName; + public PlaceHolder PhSiteDir; + public TextBox TbSiteDir; + public PlaceHolder PhParentId; + public DropDownList DdlParentId; + + public RadioButtonList RblTableRule; + public PlaceHolder PhTableChoose; + public DropDownList DdlTableChoose; + public PlaceHolder PhTableHandWrite; + public TextBox TbTableHandWrite; + + public TextBox TbTaxis; + public RadioButtonList RblIsCheckContentUseLevel; + public PlaceHolder PhCheckContentLevel; + public DropDownList DdlCheckContentLevel; + public Button BtnSubmit; + + public static string GetRedirectUrl(int siteId) + { + return FxUtils.GetSettingsUrl(nameof(PageSiteEdit), new NameValueCollection + { + {"siteId", siteId.ToString()} + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + WebPageUtils.CheckRequestParameter("siteId"); + + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.Site); + + if (SiteInfo.Root) + { + PhParentId.Visible = false; + } + else + { + PhParentId.Visible = true; + + DdlParentId.Items.Add(new ListItem("<无上级站点>", "0")); + var siteIdList = SiteManager.GetSiteIdList(); + var mySystemInfoArrayList = new ArrayList(); + var parentWithChildren = new Hashtable(); + foreach (var siteId in siteIdList) + { + if (siteId == SiteId) continue; + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo.Root == false) + { + if (siteInfo.ParentId == 0) + { + mySystemInfoArrayList.Add(siteInfo); + } + else + { + var children = new ArrayList(); + if (parentWithChildren.Contains(siteInfo.ParentId)) + { + children = (ArrayList)parentWithChildren[siteInfo.ParentId]; + } + children.Add(siteInfo); + parentWithChildren[siteInfo.ParentId] = children; + } + } + } + foreach (SiteInfo siteInfo in mySystemInfoArrayList) + { + AddSite(DdlParentId, siteInfo, parentWithChildren, 0); + } + SystemWebUtils.SelectSingleItem(DdlParentId, SiteInfo.ParentId.ToString()); + } + + var tableNameList = SiteManager.GetSiteTableNames(); + if (tableNameList.Count > 0) + { + RblTableRule.Items.Add(SystemWebUtils.GetListItem(ETableRule.Choose, true)); + RblTableRule.Items.Add(SystemWebUtils.GetListItem(ETableRule.HandWrite, false)); + + PhTableChoose.Visible = true; + PhTableHandWrite.Visible = false; + + foreach (var tableName in tableNameList) + { + DdlTableChoose.Items.Add(new ListItem(tableName, tableName)); + } + } + else + { + RblTableRule.Items.Add(SystemWebUtils.GetListItem(ETableRule.HandWrite, false)); + + PhTableChoose.Visible = false; + PhTableHandWrite.Visible = false; + } + + TbTaxis.Text = SiteInfo.Taxis.ToString(); + + RblIsCheckContentUseLevel.Items.Add(new ListItem("默认审核机制",false.ToString())); + RblIsCheckContentUseLevel.Items.Add(new ListItem("多级审核机制", true.ToString())); + + if (SiteInfo == null) + { + WebPageUtils.RedirectToErrorPage("站点不存在,请确认后再试!"); + return; + } + TbSiteName.Text = SiteInfo.SiteName; + SystemWebUtils.SelectSingleItem(RblIsCheckContentUseLevel, SiteInfo.IsCheckContentLevel.ToString()); + if (SiteInfo.IsCheckContentLevel) + { + SystemWebUtils.SelectSingleItem(DdlCheckContentLevel, SiteInfo.CheckContentLevel.ToString()); + PhCheckContentLevel.Visible = true; + } + else + { + PhCheckContentLevel.Visible = false; + } + if (!string.IsNullOrEmpty(SiteInfo.SiteDir)) + { + TbSiteDir.Text = PathUtils.GetDirectoryName(SiteInfo.SiteDir, false); + } + if (SiteInfo.Root) + { + PhSiteDir.Visible = false; + } + + SystemWebUtils.SelectSingleItem(DdlTableChoose, SiteInfo.TableName); + } + + private static void AddSite(ListControl listControl, SiteInfo siteInfo, Hashtable parentWithChildren, int level) + { + var padding = string.Empty; + for (var i = 0; i < level; i++) + { + padding += " "; + } + if (level > 0) + { + padding += "└ "; + } + + if (parentWithChildren[siteInfo.Id] != null) + { + var children = (ArrayList)parentWithChildren[siteInfo.Id]; + listControl.Items.Add(new ListItem(padding + siteInfo.SiteName + + $"({children.Count})", siteInfo.Id.ToString())); + level++; + foreach (SiteInfo subSiteInfo in children) + { + AddSite(listControl, subSiteInfo, parentWithChildren, level); + } + } + else + { + listControl.Items.Add(new ListItem(padding + siteInfo.SiteName, siteInfo.Id.ToString())); + } + } + + public void RblIsCheckContentUseLevel_OnSelectedIndexChanged(object sender, EventArgs e) + { + PhCheckContentLevel.Visible = EBooleanUtils.Equals(RblIsCheckContentUseLevel.SelectedValue, EBoolean.True); + } + + public void RblTableRule_OnSelectedIndexChanged(object sender, EventArgs e) + { + var tableRule = ETableRuleUtils.GetEnumType(RblTableRule.SelectedValue); + PhTableChoose.Visible = PhTableHandWrite.Visible = false; + if (tableRule == ETableRule.Choose) + { + PhTableChoose.Visible = true; + } + else if (tableRule == ETableRule.HandWrite) + { + PhTableHandWrite.Visible = true; + } + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + SiteInfo.SiteName = TbSiteName.Text; + SiteInfo.Taxis = TranslateUtils.ToInt(TbTaxis.Text); + SiteInfo.IsCheckContentLevel = TranslateUtils.ToBool(RblIsCheckContentUseLevel.SelectedValue); + if (SiteInfo.IsCheckContentLevel) + { + SiteInfo.CheckContentLevel = TranslateUtils.ToInt(DdlCheckContentLevel.SelectedValue); + } + + var isTableChanged = false; + + var tableName = string.Empty; + var tableRule = ETableRuleUtils.GetEnumType(RblTableRule.SelectedValue); + if (tableRule == ETableRule.Choose) + { + tableName = DdlTableChoose.SelectedValue; + } + else if (tableRule == ETableRule.HandWrite) + { + tableName = TbTableHandWrite.Text; + if (!DatoryUtils.IsTableExists(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName)) + { + TableColumnManager.CreateTable(tableName, DataProvider.ContentRepository.TableColumnsDefault, string.Empty, true, out _); + } + else + { + TableColumnManager.AlterTable(tableName, DataProvider.ContentRepository.TableColumnsDefault, string.Empty); + } + } + + if (!StringUtils.EqualsIgnoreCase(SiteInfo.TableName, tableName)) + { + isTableChanged = true; + SiteInfo.TableName = tableName; + } + + if (SiteInfo.Root == false) + { + if (!StringUtils.EqualsIgnoreCase(PathUtils.GetDirectoryName(SiteInfo.SiteDir, false), TbSiteDir.Text)) + { + var list = DataProvider.Site.GetLowerSiteDirList(SiteInfo.ParentId); + if (list.IndexOf(TbSiteDir.Text.ToLower()) != -1) + { + FailMessage("站点修改失败,已存在相同的发布路径!"); + return; + } + + var parentPsPath = WebConfigUtils.PhysicalApplicationPath; + if (SiteInfo.ParentId > 0) + { + var parentSiteInfo = SiteManager.GetSiteInfo(SiteInfo.ParentId); + parentPsPath = PathUtility.GetSitePath(parentSiteInfo); + } + DirectoryUtility.ChangeSiteDir(parentPsPath, SiteInfo.SiteDir, TbSiteDir.Text); + } + + if (PhParentId.Visible && SiteInfo.ParentId != TranslateUtils.ToInt(DdlParentId.SelectedValue)) + { + var newParentId = TranslateUtils.ToInt(DdlParentId.SelectedValue); + var list = DataProvider.Site.GetLowerSiteDirList(newParentId); + if (list.IndexOf(TbSiteDir.Text.ToLower()) != -1) + { + FailMessage("站点修改失败,已存在相同的发布路径!"); + return; + } + + DirectoryUtility.ChangeParentSite(SiteInfo.ParentId, TranslateUtils.ToInt(DdlParentId.SelectedValue), SiteId, TbSiteDir.Text); + SiteInfo.ParentId = newParentId; + } + + SiteInfo.SiteDir = TbSiteDir.Text; + } + + DataProvider.Site.Update(SiteInfo); + if (isTableChanged) + { + ContentManager.RemoveCountCache(tableName); + } + + AuthRequest.AddAdminLog("修改站点属性", $"站点:{SiteInfo.SiteName}"); + + SuccessMessage("站点修改成功!"); + AddWaitAndRedirectScript(PageSite.GetRedirectUrl()); + } + + public void Return_OnClick(object sender, EventArgs e) + { + WebPageUtils.Redirect(PageSite.GetRedirectUrl()); + } + } +} diff --git a/SiteServer.BackgroundPages/Settings/PageSiteKeyword.cs b/net452/SiteServer.BackgroundPages/Settings/PageSiteKeyword.cs similarity index 82% rename from SiteServer.BackgroundPages/Settings/PageSiteKeyword.cs rename to net452/SiteServer.BackgroundPages/Settings/PageSiteKeyword.cs index 7b603c240..bdd531746 100644 --- a/SiteServer.BackgroundPages/Settings/PageSiteKeyword.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageSiteKeyword.cs @@ -5,9 +5,12 @@ using SiteServer.Utils; using SiteServer.BackgroundPages.Controls; using SiteServer.BackgroundPages.Core; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.BackgroundPages.Settings @@ -24,12 +27,12 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - if (AuthRequest.IsQueryExists("Delete") && AuthRequest.IsQueryExists("KeywordID")) + if (AuthRequest.IsQueryExists("DeleteById") && AuthRequest.IsQueryExists("KeywordID")) { var keywordId = AuthRequest.GetQueryInt("KeywordID"); try { - DataProvider.KeywordDao.Delete(keywordId); + DataProvider.Keyword.Delete(keywordId); SuccessDeleteMessage(); } catch (Exception ex) @@ -39,7 +42,7 @@ public void Page_Load(object sender, EventArgs e) } SpContents.ControlToPaginate = RptContents; - SpContents.SelectCommand = DataProvider.KeywordDao.GetSelectCommand(); + SpContents.SelectCommand = DataProvider.Keyword.GetSelectCommand(); RptContents.ItemDataBound += RptContents_ItemDataBound; SpContents.SortField = nameof(KeywordInfo.Id); SpContents.SortMode = SortMode.DESC; //排序 @@ -47,7 +50,7 @@ public void Page_Load(object sender, EventArgs e) if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Site); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Site); SpContents.DataBind(); BtnAdd.Attributes.Add("onclick", ModalKeywordAdd.GetOpenWindowStringToAdd()); @@ -61,7 +64,7 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) var keywordId = SqlUtils.EvalInt(e.Item.DataItem, nameof(KeywordInfo.Id)); var keyword = SqlUtils.EvalString(e.Item.DataItem, nameof(KeywordInfo.Keyword)); var alternative = SqlUtils.EvalString(e.Item.DataItem, nameof(KeywordInfo.Alternative)); - var grade = EKeywordGradeUtils.GetEnumType(SqlUtils.EvalString(e.Item.DataItem, nameof(KeywordInfo.Grade))); + var grade = EKeywordGradeUtils.GetEnumType(SqlUtils.EvalString(e.Item.DataItem, "Grade")); var ltlKeyword = (Literal)e.Item.FindControl("ltlKeyword"); var ltlAlternative = (Literal)e.Item.FindControl("ltlAlternative"); @@ -75,9 +78,9 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) ltlEdit.Text = $@"编辑"; - var urlDelete = PageUtils.GetSettingsUrl(nameof(PageSiteKeyword), new NameValueCollection + var urlDelete = FxUtils.GetSettingsUrl(nameof(PageSiteKeyword), new NameValueCollection { - {"Delete", "True"}, + {"DeleteById", "True"}, {"KeywordID", keywordId.ToString()} }); ltlDelete.Text = @@ -87,7 +90,7 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) protected void ExportWord_Click(object sender, EventArgs e) { var sbContent = new StringBuilder(); - var list = DataProvider.KeywordDao.GetKeywordInfoList(); + var list = DataProvider.Keyword.GetKeywordInfoList(); if (list.Count <= 0) return; foreach (var keywordInfo in list) @@ -105,7 +108,7 @@ protected void ExportWord_Click(object sender, EventArgs e) var filePath = PathUtils.GetTemporaryFilesPath("敏感词.txt"); FileUtils.DeleteFileIfExists(filePath); FileUtils.WriteText(filePath, ECharset.utf_8, sbContent.ToString()); - PageUtils.Download(Page.Response, filePath); + WebPageUtils.Download(Page.Response, filePath); } } } diff --git a/SiteServer.BackgroundPages/Settings/PageSiteSave.cs b/net452/SiteServer.BackgroundPages/Settings/PageSiteSave.cs similarity index 85% rename from SiteServer.BackgroundPages/Settings/PageSiteSave.cs rename to net452/SiteServer.BackgroundPages/Settings/PageSiteSave.cs index aa79ebf19..16fd17d26 100644 --- a/SiteServer.BackgroundPages/Settings/PageSiteSave.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageSiteSave.cs @@ -4,10 +4,15 @@ using System.Text; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.CMS.ImportExport; -using SiteServer.CMS.Model; using SiteServer.Utils.Enumerations; using SiteServer.Utils.IO; @@ -50,7 +55,7 @@ public class PageSiteSave : BasePageCms public static string GetRedirectUrl(int siteId) { - return PageUtils.GetSettingsUrl(nameof(PageSiteSave), new NameValueCollection + return FxUtils.GetSettingsUrl(nameof(PageSiteSave), new NameValueCollection { {"siteId", siteId.ToString()} }); @@ -60,15 +65,15 @@ public void Page_Load(object sender, EventArgs e) { if (IsForbidden) return; - PageUtils.CheckRequestParameter("siteId"); + WebPageUtils.CheckRequestParameter("siteId"); _exportObject = new ExportObject(SiteId, AuthRequest.AdminName); if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Site); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Site); - if (SiteInfo.IsRoot) + if (SiteInfo.Root) { TbSiteTemplateDir.Text = "T_" + SiteInfo.SiteName; } @@ -78,17 +83,17 @@ public void Page_Load(object sender, EventArgs e) } TbSiteTemplateName.Text = SiteInfo.SiteName; - EBooleanUtils.AddListItems(RblIsSaveAllFiles, "全部文件", "指定文件"); - ControlUtils.SelectSingleItemIgnoreCase(RblIsSaveAllFiles, true.ToString()); + FxUtils.AddListItems(RblIsSaveAllFiles, "全部文件", "指定文件"); + SystemWebUtils.SelectSingleItemIgnoreCase(RblIsSaveAllFiles, true.ToString()); - var siteDirList = DataProvider.SiteDao.GetLowerSiteDirListThatNotIsRoot(); + var siteDirList = DataProvider.Site.GetLowerSiteDirListThatNotIsRoot(); var fileSystems = FileManager.GetFileSystemInfoExtendCollection(PathUtility.GetSitePath(SiteInfo), true); foreach (FileSystemInfoExtend fileSystem in fileSystems) { if (!fileSystem.IsDirectory) continue; var isSiteDirectory = false; - if (SiteInfo.IsRoot) + if (SiteInfo.Root) { foreach (var siteDir in siteDirList) { @@ -112,11 +117,11 @@ public void Page_Load(object sender, EventArgs e) } } - EBooleanUtils.AddListItems(RblIsSaveContents, "保存内容数据", "不保存内容数据"); - ControlUtils.SelectSingleItemIgnoreCase(RblIsSaveContents, true.ToString()); + FxUtils.AddListItems(RblIsSaveContents, "保存内容数据", "不保存内容数据"); + SystemWebUtils.SelectSingleItemIgnoreCase(RblIsSaveContents, true.ToString()); - EBooleanUtils.AddListItems(RblIsSaveAllChannels, "全部栏目", "指定栏目"); - ControlUtils.SelectSingleItemIgnoreCase(RblIsSaveAllChannels, true.ToString()); + FxUtils.AddListItems(RblIsSaveAllChannels, "全部栏目", "指定栏目"); + SystemWebUtils.SelectSingleItemIgnoreCase(RblIsSaveAllChannels, true.ToString()); LtlChannelTree.Text = GetChannelTreeHtml(); } @@ -140,42 +145,45 @@ private string GetChannelTreeHtml() return htmlBuilder.ToString(); } - private string GetTitle(ChannelInfo nodeInfo, string treeDirectoryUrl, IList isLastNodeArray) + private string GetTitle(ChannelInfo channelInfo, string treeDirectoryUrl, IList isLastNodeArray) { var itemBuilder = new StringBuilder(); - if (nodeInfo.Id == SiteId) + if (channelInfo.Id == SiteId) { - nodeInfo.IsLastNode = true; + channelInfo.LastNode = true; } - if (nodeInfo.IsLastNode == false) + if (channelInfo.LastNode == false) { - isLastNodeArray[nodeInfo.ParentsCount] = false; + isLastNodeArray[channelInfo.ParentsCount] = false; } else { - isLastNodeArray[nodeInfo.ParentsCount] = true; + isLastNodeArray[channelInfo.ParentsCount] = true; } - for (var i = 0; i < nodeInfo.ParentsCount; i++) + for (var i = 0; i < channelInfo.ParentsCount; i++) { itemBuilder.Append($""); } - if (nodeInfo.IsLastNode) + if (channelInfo.LastNode) { - itemBuilder.Append(nodeInfo.ChildrenCount > 0 + itemBuilder.Append(channelInfo.ChildrenCount > 0 ? $"" : $""); } else { - itemBuilder.Append(nodeInfo.ChildrenCount > 0 + itemBuilder.Append(channelInfo.ChildrenCount > 0 ? $"" : $""); } + var onlyAdminId = AuthRequest.AdminPermissionsImpl.GetOnlyAdminId(SiteId, channelInfo.Id); + var count = ContentManager.GetCount(SiteInfo, channelInfo, onlyAdminId); + itemBuilder.Append($@" - - + + "); @@ -232,7 +240,7 @@ private bool SaveFiles(out string errorMessage) { var siteTemplatePath = PathUtility.GetSiteTemplatesPath(TbSiteTemplateDir.Text); var isSaveAll = TranslateUtils.ToBool(RblIsSaveAllFiles.SelectedValue); - var lowerFileSystemArrayList = ControlUtils.GetSelectedListControlValueArrayList(CblDirectoriesAndFiles); + var lowerFileSystemArrayList = SystemWebUtils.GetSelectedListControlValueArrayList(CblDirectoriesAndFiles); _exportObject.ExportFilesToSite(siteTemplatePath, isSaveAll, lowerFileSystemArrayList, true); errorMessage = ""; return true; @@ -379,7 +387,7 @@ public void BtnUploadImageFileNext_Click(object sender, EventArgs e) public void Return_OnClick(object sender, EventArgs e) { - PageUtils.Redirect(PageSite.GetRedirectUrl()); + WebPageUtils.Redirect(PageSite.GetRedirectUrl()); } } } diff --git a/net452/SiteServer.BackgroundPages/Settings/PageSiteTable.cs b/net452/SiteServer.BackgroundPages/Settings/PageSiteTable.cs new file mode 100644 index 000000000..1546cc3f0 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageSiteTable.cs @@ -0,0 +1,90 @@ +using System; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageSiteTable : BasePageCms + { + public Repeater RptContents; + public Button BtnAdd; + + public static string GetRedirectUrl() + { + return FxUtils.GetSettingsUrl(nameof(PageSiteTable), null); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + //if (AuthRequest.IsQueryExists("DeleteById")) + //{ + // var enName = AuthRequest.GetQueryString("ENName");//内容表 + // var enNameArchive = enName + "_Archive";//内容表归档 + + // try + // { + // DataProvider.TableDao.DeleteCollectionTableInfoAndDbTable(enName);//删除内容表 + // DataProvider.TableDao.DeleteCollectionTableInfoAndDbTable(enNameArchive);//删除内容表归档 + + // AuthRequest.AddAdminLog("删除内容表", $"内容表:{enName}"); + + // SuccessDeleteMessage(); + // } + // catch(Exception ex) + // { + // FailDeleteMessage(ex); + // } + //} + + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.Site); + + RptContents.DataSource = SiteManager.GetSiteTableNames(); + RptContents.ItemDataBound += RptContents_ItemDataBound; + RptContents.DataBind(); + + //BtnAdd.OnClientClick = ModalAuxiliaryTableAdd.GetOpenWindowString(); + } + + private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var tableName = (string)e.Item.DataItem; + //var isHighlight = !collectionInfo.IsCreatedInDb || collectionInfo.IsChangedAfterCreatedInDb; + var isTableUsed = DataProvider.Site.IsTableUsed(tableName); + + //if (isHighlight) e.Item.Attributes.Add("style", "color: red"); + + var ltlTableName = (Literal)e.Item.FindControl("ltlTableName"); + var ltlMetadataEdit = (Literal)e.Item.FindControl("ltlMetadataEdit"); + var ltlStyleEdit = (Literal)e.Item.FindControl("ltlStyleEdit"); + var ltlEdit = (Literal)e.Item.FindControl("ltlEdit"); + var ltlDelete = (Literal)e.Item.FindControl("ltlDelete"); + + ltlTableName.Text = tableName; + + //ltlMetadataEdit.Text = + // $@"管理真实字段"; + + ltlStyleEdit.Text = $@"管理虚拟字段"; + + //ltlEdit.Text = $@"编辑"; + + if (!isTableUsed) + { + var script = AlertUtils.Warning("删除内容表", $"此操作将删除内容表“{tableName}”,如果内容表已在数据库中建立,将同时删除建立的内容表,确认吗?", "取 消", + "确认删除", $"location.href = '{GetRedirectUrl()}?DeleteById=True&ENName={tableName}';"); + ltlDelete.Text = + $@"删除"; + } + } + } +} diff --git a/SiteServer.BackgroundPages/Settings/PageSiteTableStyle.cs b/net452/SiteServer.BackgroundPages/Settings/PageSiteTableStyle.cs similarity index 80% rename from SiteServer.BackgroundPages/Settings/PageSiteTableStyle.cs rename to net452/SiteServer.BackgroundPages/Settings/PageSiteTableStyle.cs index 458090058..9e34c7b3d 100644 --- a/SiteServer.BackgroundPages/Settings/PageSiteTableStyle.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageSiteTableStyle.cs @@ -4,8 +4,12 @@ using System.Web.UI.WebControls; using SiteServer.Utils; using SiteServer.BackgroundPages.Cms; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; namespace SiteServer.BackgroundPages.Settings { @@ -23,7 +27,7 @@ public class PageSiteTableStyle : BasePage public static string GetRedirectUrl(string tableName) { - return PageUtils.GetSettingsUrl(nameof(PageSiteTableStyle), new NameValueCollection + return FxUtils.GetSettingsUrl(nameof(PageSiteTableStyle), new NameValueCollection { {"tableName", tableName} }); @@ -31,7 +35,8 @@ public static string GetRedirectUrl(string tableName) public string GetReturnUrl() { - return PageSiteAuxiliaryTable.GetRedirectUrl(); + return string.Empty; + //return PageSiteAuxiliaryTable.GetRedirectUrl(); } public void Page_Load(object sender, EventArgs e) @@ -43,20 +48,20 @@ public void Page_Load(object sender, EventArgs e) if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Site); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Site); if (AuthRequest.IsQueryExists("DeleteStyle")) { var attributeName = AuthRequest.GetQueryString("AttributeName"); if (TableStyleManager.IsExists(0, _tableName, attributeName)) { - TableStyleManager.Delete(0, _tableName, attributeName); + DataProvider.TableStyle.Delete(0, _tableName, attributeName); AuthRequest.AddAdminLog("删除数据表单样式", $"表单:{_tableName},字段:{attributeName}"); SuccessDeleteMessage(); } } - var styleInfoList = TableStyleManager.GetTableStyleInfoList(_tableName, new List {0}); + var styleInfoList = TableStyleManager.GetStyleInfoList(_tableName, TableStyleManager.EmptyRelatedIdentities); RptContents.DataSource = styleInfoList; RptContents.ItemDataBound += RptContents_ItemDataBound; @@ -71,7 +76,7 @@ public void Page_Load(object sender, EventArgs e) public void Redirect(object sender, EventArgs e) { - PageUtils.Redirect(GetRedirectUrl(_tableName)); + WebPageUtils.Redirect(GetRedirectUrl(_tableName)); } private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) @@ -92,8 +97,11 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) ltlAttributeName.Text = styleInfo.AttributeName; ltlDisplayName.Text = styleInfo.DisplayName; - ltlInputType.Text = InputTypeUtils.GetText(styleInfo.InputType); - ltlFieldType.Text = TableMetadataManager.IsAttributeNameExists(_tableName, styleInfo.AttributeName) ? $"真实 {TableMetadataManager.GetTableMetadataDataType(_tableName, styleInfo.AttributeName)}" : "虚拟字段"; + ltlInputType.Text = InputTypeUtils.GetText(styleInfo.Type); + + var columnInfo = TableColumnManager.GetTableColumnInfo(_tableName, styleInfo.AttributeName); + + ltlFieldType.Text = columnInfo != null ? $"真实 {DataTypeUtils.GetText(columnInfo.DataType)}" : "虚拟字段"; ltlValidate.Text = TableStyleManager.GetValidateInfo(styleInfo); @@ -109,7 +117,7 @@ private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) if (styleInfo.Id == 0) return; ltlEditStyle.Text += - $@"  (); @@ -128,15 +129,15 @@ private void RptDirectories_ItemDataBound(object sender, RepeaterItemEventArgs e ltlDescription.Text = siteTemplateInfo.Description; if (!string.IsNullOrEmpty(siteTemplateInfo.PicFileName)) { - var siteTemplateUrl = PageUtils.GetSiteTemplatesUrl(dirInfo.Name); + var siteTemplateUrl = FxUtils.GetSiteTemplatesUrl(dirInfo.Name); ltlDownloadUrl.Text += - $"样图  "; + $"样图  "; } ltlCreationDate.Text = DateUtils.GetDateString(dirInfo.CreationTime); if (!string.IsNullOrEmpty(siteTemplateInfo.WebSiteUrl)) { ltlDownloadUrl.Text += - $"演示  "; + $"演示  "; } var fileName = dirInfo.Name + ".zip"; @@ -147,7 +148,7 @@ private void RptDirectories_ItemDataBound(object sender, RepeaterItemEventArgs e $@"重新压缩  "; ltlDownloadUrl.Text += - $@"下载压缩包"; + $@"下载压缩包"; } else { @@ -155,10 +156,11 @@ private void RptDirectories_ItemDataBound(object sender, RepeaterItemEventArgs e $@"压缩"; } - var urlAdd = PageSiteAdd.GetRedirectUrl(dirInfo.Name, string.Empty); + //var urlAdd = PageSiteAdd.GetRedirectUrl(dirInfo.Name, string.Empty); + var urlAdd = $"{AdminPagesUtils.Settings.SiteAddUrl}?type=create&createType=local&createTemplateId={dirInfo.Name}"; ltlCreateUrl.Text = $@"创建站点"; - var urlDelete = PageUtils.GetSettingsUrl(nameof(PageSiteTemplate), new NameValueCollection + var urlDelete = FxUtils.GetSettingsUrl(nameof(PageSiteTemplate), new NameValueCollection { {"DeleteDirectory", "True"}, {"SiteTemplateDir", dirInfo.Name} @@ -187,9 +189,9 @@ private void RptZipFiles_ItemDataBound(object sender, RepeaterItemEventArgs e) $@"解压  "; ltlDownloadUrl.Text += - $@"下载压缩包"; + $@"下载压缩包"; - var urlDelete = PageUtils.GetSettingsUrl(nameof(PageSiteTemplate), new NameValueCollection + var urlDelete = FxUtils.GetSettingsUrl(nameof(PageSiteTemplate), new NameValueCollection { {"DeleteZipFile", "True"}, {"FileName", fileInfo.Name} diff --git a/SiteServer.BackgroundPages/Settings/PageSiteTemplateOnline.cs b/net452/SiteServer.BackgroundPages/Settings/PageSiteTemplateOnline.cs similarity index 96% rename from SiteServer.BackgroundPages/Settings/PageSiteTemplateOnline.cs rename to net452/SiteServer.BackgroundPages/Settings/PageSiteTemplateOnline.cs index d235b7ce2..f5d80f23e 100644 --- a/SiteServer.BackgroundPages/Settings/PageSiteTemplateOnline.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageSiteTemplateOnline.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; @@ -18,7 +19,7 @@ public void Page_Load(object sender, EventArgs e) if (Page.IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Site); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Site); InfoMessage($@"本页面只显示部分免费模板,更多站点模板请访问官网:{OnlineTemplateManager.UrlHome}"); diff --git a/net452/SiteServer.BackgroundPages/Settings/PageSiteUrlApi.cs b/net452/SiteServer.BackgroundPages/Settings/PageSiteUrlApi.cs new file mode 100644 index 000000000..89e440a2f --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageSiteUrlApi.cs @@ -0,0 +1,47 @@ +using System; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageSiteUrlApi : BasePage + { + public RadioButtonList RblIsSeparatedApi; + public PlaceHolder PhSeparatedApi; + public TextBox TbSeparatedApiUrl; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.Site); + + FxUtils.AddListItems(RblIsSeparatedApi, "API独立部署", "API与CMS部署在一起"); + SystemWebUtils.SelectSingleItem(RblIsSeparatedApi, ConfigManager.Instance.IsSeparatedApi.ToString()); + PhSeparatedApi.Visible = ConfigManager.Instance.IsSeparatedApi; + TbSeparatedApiUrl.Text = ConfigManager.Instance.SeparatedApiUrl; + } + + public void RblIsSeparatedApi_SelectedIndexChanged(object sender, EventArgs e) + { + PhSeparatedApi.Visible = TranslateUtils.ToBool(RblIsSeparatedApi.SelectedValue); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + ConfigManager.Instance.IsSeparatedApi = TranslateUtils.ToBool(RblIsSeparatedApi.SelectedValue); + ConfigManager.Instance.SeparatedApiUrl = TbSeparatedApiUrl.Text; + + DataProvider.Config.Update(ConfigManager.Instance); + + AuthRequest.AddAdminLog("修改API访问地址"); + SuccessUpdateMessage(); + } + } +} diff --git a/SiteServer.BackgroundPages/Settings/PageSiteUrlAssets.cs b/net452/SiteServer.BackgroundPages/Settings/PageSiteUrlAssets.cs similarity index 80% rename from SiteServer.BackgroundPages/Settings/PageSiteUrlAssets.cs rename to net452/SiteServer.BackgroundPages/Settings/PageSiteUrlAssets.cs index e78c3ee9f..aea0c53ad 100644 --- a/SiteServer.BackgroundPages/Settings/PageSiteUrlAssets.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageSiteUrlAssets.cs @@ -1,7 +1,8 @@ using System; using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Fx; using SiteServer.Utils; -using SiteServer.CMS.Core; namespace SiteServer.BackgroundPages.Settings { @@ -11,7 +12,7 @@ public class PageSiteUrlAssets : BasePageCms public static string GetRedirectUrl() { - return PageUtils.GetSettingsUrl(nameof(PageSiteUrlAssets), null); + return FxUtils.GetSettingsUrl(nameof(PageSiteUrlAssets), null); } public void Page_Load(object sender, EventArgs e) @@ -19,7 +20,7 @@ public void Page_Load(object sender, EventArgs e) if (IsForbidden) return; if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Site); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Site); var siteList = SiteManager.GetSiteIdListOrderByLevel(); RptContents.DataSource = siteList; @@ -43,8 +44,8 @@ private static void RptContents_ItemDataBound(object sender, RepeaterItemEventAr ltlName.Text = SiteManager.GetSiteName(siteInfo); ltlDir.Text = siteInfo.SiteDir; - ltlAssetsDir.Text = siteInfo.Additional.AssetsDir; - ltlAssetsUrl.Text = $@"{siteInfo.Additional.AssetsUrl}"; + ltlAssetsDir.Text = siteInfo.AssetsDir; + ltlAssetsUrl.Text = $@"{siteInfo.AssetsUrl}"; ltlEditUrl.Text = $@"修改"; } diff --git a/net452/SiteServer.BackgroundPages/Settings/PageSiteUrlAssetsConfig.cs b/net452/SiteServer.BackgroundPages/Settings/PageSiteUrlAssetsConfig.cs new file mode 100644 index 000000000..6989f5a16 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageSiteUrlAssetsConfig.cs @@ -0,0 +1,71 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageSiteUrlAssetsConfig : BasePageCms + { + public Literal LtlSiteName; + + public RadioButtonList RblIsSeparatedAssets; + public PlaceHolder PhSeparatedAssets; + public TextBox TbSeparatedAssetsUrl; + public TextBox TbAssetsDir; + + public static string GetRedirectUrl(int siteId) + { + return FxUtils.GetSettingsUrl(nameof(PageSiteUrlAssetsConfig), new NameValueCollection + { + { + "SiteId", siteId.ToString() + } + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.Site); + + LtlSiteName.Text = SiteInfo.SiteName; + + FxUtils.AddListItems(RblIsSeparatedAssets, "资源文件独立部署", "资源文件与Web部署在一起"); + SystemWebUtils.SelectSingleItem(RblIsSeparatedAssets, SiteInfo.IsSeparatedAssets.ToString()); + PhSeparatedAssets.Visible = SiteInfo.IsSeparatedAssets; + TbSeparatedAssetsUrl.Text = SiteInfo.SeparatedAssetsUrl; + TbAssetsDir.Text = SiteInfo.AssetsDir; + } + + public void RblIsSeparatedAssets_SelectedIndexChanged(object sender, EventArgs e) + { + PhSeparatedAssets.Visible = TranslateUtils.ToBool(RblIsSeparatedAssets.SelectedValue); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + SiteInfo.IsSeparatedAssets = TranslateUtils.ToBool(RblIsSeparatedAssets.SelectedValue); + SiteInfo.SeparatedAssetsUrl = TbSeparatedAssetsUrl.Text; + SiteInfo.AssetsDir = TbAssetsDir.Text; + + DataProvider.Site.Update(SiteInfo); + AuthRequest.AddSiteLog(SiteId, "修改资源文件访问地址"); + + SuccessMessage("资源文件访问地址修改成功!"); + AddWaitAndRedirectScript(PageSiteUrlAssets.GetRedirectUrl()); + } + + public void Return_OnClick(object sender, EventArgs e) + { + WebPageUtils.Redirect(PageSiteUrlAssets.GetRedirectUrl()); + } + } +} diff --git a/SiteServer.BackgroundPages/Settings/PageSiteUrlWeb.cs b/net452/SiteServer.BackgroundPages/Settings/PageSiteUrlWeb.cs similarity index 82% rename from SiteServer.BackgroundPages/Settings/PageSiteUrlWeb.cs rename to net452/SiteServer.BackgroundPages/Settings/PageSiteUrlWeb.cs index e17397057..28e1401ea 100644 --- a/SiteServer.BackgroundPages/Settings/PageSiteUrlWeb.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageSiteUrlWeb.cs @@ -1,7 +1,8 @@ using System; using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Fx; using SiteServer.Utils; -using SiteServer.CMS.Core; namespace SiteServer.BackgroundPages.Settings { @@ -11,7 +12,7 @@ public class PageSiteUrlWeb : BasePageCms public static string GetRedirectUrl() { - return PageUtils.GetSettingsUrl(nameof(PageSiteUrlWeb), null); + return FxUtils.GetSettingsUrl(nameof(PageSiteUrlWeb), null); } public void Page_Load(object sender, EventArgs e) @@ -19,7 +20,7 @@ public void Page_Load(object sender, EventArgs e) if (IsForbidden) return; if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Site); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Site); var siteList = SiteManager.GetSiteIdListOrderByLevel(); RptContents.DataSource = siteList; @@ -42,7 +43,7 @@ private static void DgContents_ItemDataBound(object sender, RepeaterItemEventArg ltlName.Text = SiteManager.GetSiteName(siteInfo); ltlDir.Text = siteInfo.SiteDir; - ltlWebUrl.Text = $@"{siteInfo.Additional.WebUrl}"; + ltlWebUrl.Text = $@"{siteInfo.WebUrl}"; ltlEditUrl.Text = $@"修改"; } diff --git a/net452/SiteServer.BackgroundPages/Settings/PageSiteUrlWebConfig.cs b/net452/SiteServer.BackgroundPages/Settings/PageSiteUrlWebConfig.cs new file mode 100644 index 000000000..75614e9e6 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageSiteUrlWebConfig.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageSiteUrlWebConfig : BasePageCms + { + public Literal LtlSiteName; + + public RadioButtonList RblIsSeparatedWeb; + public PlaceHolder PhSeparatedWeb; + public TextBox TbSeparatedWebUrl; + + public static string GetRedirectUrl(int siteId) + { + return FxUtils.GetSettingsUrl(nameof(PageSiteUrlWebConfig), new NameValueCollection + { + { + "SiteId", siteId.ToString() + } + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.Site); + + LtlSiteName.Text = SiteInfo.SiteName; + + FxUtils.AddListItems(RblIsSeparatedWeb, "Web独立部署", "Web与CMS部署在一起"); + SystemWebUtils.SelectSingleItem(RblIsSeparatedWeb, SiteInfo.IsSeparatedWeb.ToString()); + PhSeparatedWeb.Visible = SiteInfo.IsSeparatedWeb; + TbSeparatedWebUrl.Text = PageUtils.AddEndSlashToUrl(SiteInfo.SeparatedWebUrl); + } + + public void RblIsSeparatedWeb_SelectedIndexChanged(object sender, EventArgs e) + { + PhSeparatedWeb.Visible = TranslateUtils.ToBool(RblIsSeparatedWeb.SelectedValue); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + SiteInfo.IsSeparatedWeb = TranslateUtils.ToBool(RblIsSeparatedWeb.SelectedValue); + SiteInfo.SeparatedWebUrl = TbSeparatedWebUrl.Text; + if (!string.IsNullOrEmpty(SiteInfo.SeparatedWebUrl) && !SiteInfo.SeparatedWebUrl.EndsWith("/")) + { + SiteInfo.SeparatedWebUrl = PageUtils.AddEndSlashToUrl(SiteInfo.SeparatedWebUrl); + } + + DataProvider.Site.Update(SiteInfo); + AuthRequest.AddSiteLog(SiteId, "修改Web访问地址"); + + SuccessMessage("Web访问地址修改成功!"); + AddWaitAndRedirectScript(PageSiteUrlWeb.GetRedirectUrl()); + } + + public void Return_OnClick(object sender, EventArgs e) + { + WebPageUtils.Redirect(PageSiteUrlWeb.GetRedirectUrl()); + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Settings/PageUser.cs b/net452/SiteServer.BackgroundPages/Settings/PageUser.cs new file mode 100644 index 000000000..425c3f4e4 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageUser.cs @@ -0,0 +1,287 @@ +using System; +using System.Web.UI.WebControls; +using SiteServer.Utils; +using SiteServer.BackgroundPages.Controls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageUser : BasePage + { + public DropDownList DdlGroupId; + public DropDownList DdlPageNum; + public DropDownList DdlLoginCount; + + public DropDownList DdlSearchType; + public TextBox TbKeyword; + public DropDownList DdlCreationDate; + public DropDownList DdlLastActivityDate; + + public Repeater RptContents; + public SqlPager SpContents; + + public Button BtnCheck; + public Button BtnAdd; + public Button BtnLock; + public Button BtnUnLock; + public Button BtnDelete; + public Button BtnExport; + + private EUserLockType _lockType = EUserLockType.Forever; + + public static string GetRedirectUrl() + { + return FxUtils.GetSettingsUrl(nameof(PageUser), null); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + if (AuthRequest.IsQueryExists("Check")) + { + var userIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("UserIDCollection")); + DataProvider.User.Check(userIdList); + + SuccessCheckMessage(); + } + else if (AuthRequest.IsQueryExists("DeleteById")) + { + var userIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("UserIDCollection")); + try + { + foreach (var userId in userIdList) + { + var userInfo = UserManager.GetUserInfoByUserId(userId); + DataProvider.User.Delete(userInfo); + } + + AuthRequest.AddAdminLog("删除用户", string.Empty); + + SuccessDeleteMessage(); + } + catch (Exception ex) + { + FailDeleteMessage(ex); + } + } + else if (AuthRequest.IsQueryExists("Lock")) + { + var userIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("UserIDCollection")); + try + { + DataProvider.User.Lock(userIdList); + + AuthRequest.AddAdminLog("锁定用户", string.Empty); + + SuccessMessage("成功锁定所选会员!"); + } + catch (Exception ex) + { + FailMessage(ex, "锁定所选会员失败!"); + } + } + else if (AuthRequest.IsQueryExists("UnLock")) + { + var userIdList = TranslateUtils.StringCollectionToIntList(AuthRequest.GetQueryString("UserIDCollection")); + try + { + DataProvider.User.UnLock(userIdList); + + AuthRequest.AddAdminLog("解除锁定用户", string.Empty); + + SuccessMessage("成功解除锁定所选会员!"); + } + catch (Exception ex) + { + FailMessage(ex, "解除锁定所选会员失败!"); + } + } + + SpContents.ControlToPaginate = RptContents; + + if (string.IsNullOrEmpty(AuthRequest.GetQueryString("PageNum"))) + { + SpContents.ItemsPerPage = TranslateUtils.ToInt(DdlPageNum.SelectedValue) == 0 ? 25 : TranslateUtils.ToInt(DdlPageNum.SelectedValue); + + SpContents.SelectCommand = DataProvider.User.GetSelectCommand(); + } + else + { + SpContents.ItemsPerPage = AuthRequest.GetQueryInt("PageNum") == 0 ? Constants.PageSize : AuthRequest.GetQueryInt("PageNum"); + + SpContents.SelectCommand = DataProvider.User.GetSelectCommand(AuthRequest.GetQueryInt("groupId"), AuthRequest.GetQueryString("keyword"), AuthRequest.GetQueryInt("creationDate"), AuthRequest.GetQueryInt("lastActivityDate"), AuthRequest.GetQueryInt("loginCount"), AuthRequest.GetQueryString("searchType")); + } + + RptContents.ItemDataBound += rptContents_ItemDataBound; + SpContents.OrderByString = "ORDER BY IsChecked, Id DESC"; + + _lockType = EUserLockTypeUtils.GetEnumType(ConfigManager.Instance.UserLockLoginType); + + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.User); + + DdlGroupId.Items.Add(new ListItem("<全部用户组>", "-1")); + foreach (var groupInfo in UserGroupManager.GetUserGroupInfoList()) + { + DdlGroupId.Items.Add(new ListItem(groupInfo.GroupName, groupInfo.Id.ToString())); + } + + //添加隐藏属性 + DdlSearchType.Items.Add(new ListItem("用户Id", UserAttribute.Id)); + DdlSearchType.Items.Add(new ListItem("用户名", UserAttribute.UserName)); + DdlSearchType.Items.Add(new ListItem("邮箱", UserAttribute.Email)); + DdlSearchType.Items.Add(new ListItem("手机", UserAttribute.Mobile)); + + //默认选择用户名 + DdlSearchType.SelectedValue = UserAttribute.UserName; + + if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("groupId"))) + { + SystemWebUtils.SelectSingleItem(DdlGroupId, AuthRequest.GetQueryString("groupId")); + } + if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("searchType"))) + { + SystemWebUtils.SelectSingleItem(DdlSearchType, AuthRequest.GetQueryString("searchType")); + } + if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("pageNum"))) + { + SystemWebUtils.SelectSingleItem(DdlPageNum, AuthRequest.GetQueryString("pageNum")); + } + if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("loginCount"))) + { + SystemWebUtils.SelectSingleItem(DdlLoginCount, AuthRequest.GetQueryString("loginCount")); + } + if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("keyword"))) + { + TbKeyword.Text = AuthRequest.GetQueryString("keyword"); + } + if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("creationDate"))) + { + SystemWebUtils.SelectSingleItem(DdlCreationDate, AuthRequest.GetQueryString("creationDate")); + } + if (!string.IsNullOrEmpty(AuthRequest.GetQueryString("lastActivityDate"))) + { + SystemWebUtils.SelectSingleItem(DdlLastActivityDate, AuthRequest.GetQueryString("lastActivityDate")); + } + + var backgroundUrl = GetRedirectUrl(); + + BtnCheck.Attributes.Add("onclick", + PageUtils.GetRedirectStringWithCheckBoxValueAndAlert($"{backgroundUrl}?Check=True", "UserIDCollection", + "UserIDCollection", "请选择需要审核的会员!", "此操作将审核通过所选会员,确认吗?")); + + BtnAdd.Attributes.Add("onclick", + $"location.href='{PageUserAdd.GetRedirectUrlToAdd(PageUrl)}';return false;"); + + BtnLock.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert( + $"{backgroundUrl}?Lock=True", "UserIDCollection", "UserIDCollection", "请选择需要锁定的会员!", "此操作将锁定所选会员,确认吗?")); + + BtnUnLock.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert( + $"{backgroundUrl}?UnLock=True", "UserIDCollection", "UserIDCollection", "请选择需要解除锁定的会员!", "此操作将解除锁定所选会员,确认吗?")); + + BtnDelete.Attributes.Add("onclick", PageUtils.GetRedirectStringWithCheckBoxValueAndAlert( + $"{backgroundUrl}?DeleteById=True", "UserIDCollection", "UserIDCollection", "请选择需要删除的会员!", "此操作将删除所选会员,确认吗?")); + + BtnExport.Attributes.Add("onclick", ModalUserExport.GetOpenWindowString()); + + SpContents.DataBind(); + } + + private void rptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + if (e.Item.DataItem == null) return; + + var id = SqlUtils.EvalInt(e.Item.DataItem, nameof(UserInfo.Id)); + var userName = SqlUtils.EvalString(e.Item.DataItem, nameof(UserInfo.UserName)); + var createDate = SqlUtils.EvalDateTime(e.Item.DataItem, nameof(UserInfo.CreateDate)); + var lastActivityDate = SqlUtils.EvalDateTime(e.Item.DataItem, nameof(UserInfo.LastActivityDate)); + var countOfLogin = SqlUtils.EvalInt(e.Item.DataItem, nameof(UserInfo.CountOfLogin)); + var countOfFailedLogin = SqlUtils.EvalInt(e.Item.DataItem, nameof(UserInfo.CountOfFailedLogin)); + var groupId = SqlUtils.EvalInt(e.Item.DataItem, nameof(UserInfo.GroupId)); + var isChecked = SqlUtils.EvalBool(e.Item.DataItem, UserAttribute.IsChecked); + var isLockedOut = SqlUtils.EvalBool(e.Item.DataItem, UserAttribute.IsLockedOut); + var displayName = SqlUtils.EvalString(e.Item.DataItem, nameof(UserInfo.DisplayName)); + var email = SqlUtils.EvalString(e.Item.DataItem, nameof(UserInfo.Email)); + var mobile = SqlUtils.EvalString(e.Item.DataItem, nameof(UserInfo.Mobile)); + + var ltlUserName = (Literal)e.Item.FindControl("ltlUserName"); + var ltlEmail = (Literal)e.Item.FindControl("ltlEmail"); + var ltlMobile = (Literal)e.Item.FindControl("ltlMobile"); + var ltlGroupName = (Literal)e.Item.FindControl("ltlGroupName"); + var ltlLoginCount = (Literal)e.Item.FindControl("ltlLoginCount"); + var ltlCreationDate = (Literal)e.Item.FindControl("ltlCreationDate"); + var ltlSelect = (Literal)e.Item.FindControl("ltlSelect"); + var hlChangePassword = (HyperLink)e.Item.FindControl("hlChangePassword"); + var hlEditLink = (HyperLink)e.Item.FindControl("hlEditLink"); + + var showPopWinString = ModalUserView.GetOpenWindowString(userName); + var state = isChecked ? string.Empty : @"[待审核]"; + if (isLockedOut) + { + state += @"[已锁定]"; + } + else if (ConfigManager.Instance.IsUserLockLogin && + ConfigManager.Instance.UserLockLoginCount <= countOfFailedLogin) + { + if (_lockType == EUserLockType.Forever) + { + state += @"[已锁定]"; + } + else + { + var ts = new TimeSpan(DateTime.Now.Ticks - lastActivityDate.Ticks); + var hours = Convert.ToInt32(ConfigManager.Instance.UserLockLoginHours - ts.TotalHours); + if (hours > 0) + { + state += $@"[已锁定{hours}小时]"; + } + } + } + + ltlUserName.Text = $@"{userName} {state}"; + + if (!string.IsNullOrEmpty(displayName)) + { + ltlUserName.Text += $"({displayName})"; + } + ltlEmail.Text = email; + ltlMobile.Text = mobile; + ltlGroupName.Text = UserGroupManager.GetUserGroupInfo(groupId).GroupName; + ltlLoginCount.Text = countOfLogin.ToString(); + ltlCreationDate.Text = DateUtils.GetDateAndTimeString(createDate); + + hlEditLink.NavigateUrl = PageUserAdd.GetRedirectUrlToEdit(id, GetRedirectUrl()); + hlChangePassword.Attributes.Add("onclick", ModalUserPassword.GetOpenWindowString(userName)); + ltlSelect.Text = $@""; + } + + public void Search_OnClick(object sender, EventArgs e) + { + WebPageUtils.Redirect(PageUrl); + } + + private string _pageUrl; + private string PageUrl + { + get + { + if (string.IsNullOrEmpty(_pageUrl)) + { + _pageUrl = + $"{GetRedirectUrl()}?groupId={DdlGroupId.SelectedValue}&pageNum={DdlPageNum.SelectedValue}&keyword={TbKeyword.Text}&creationDate={DdlCreationDate.SelectedValue}&lastActivityDate={DdlLastActivityDate.SelectedValue}&loginCount={DdlLoginCount.SelectedValue}&searchType={DdlSearchType.SelectedValue}"; + } + return _pageUrl; + } + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Settings/PageUserAdd.cs b/net452/SiteServer.BackgroundPages/Settings/PageUserAdd.cs new file mode 100644 index 000000000..45cac4809 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageUserAdd.cs @@ -0,0 +1,150 @@ +using System; +using System.Collections.Specialized; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageUserAdd : BasePage + { + public Literal LtlPageTitle; + public TextBox TbUserName; + public DropDownList DdlGroupId; + public TextBox TbDisplayName; + public PlaceHolder PhPassword; + public TextBox TbPassword; + public Literal LtlPasswordTips; + public TextBox TbEmail; + public TextBox TbMobile; + public Button BtnReturn; + + private int _userId; + private string _returnUrl; + + public static string GetRedirectUrlToAdd(string returnUrl) + { + return FxUtils.GetSettingsUrl(nameof(PageUserAdd), new NameValueCollection + { + {"returnUrl", StringUtils.ValueToUrl(returnUrl) } + }); + } + + public static string GetRedirectUrlToEdit(int userId, string returnUrl) + { + return FxUtils.GetSettingsUrl(nameof(PageUserAdd), new NameValueCollection + { + {"userID", userId.ToString() }, + {"returnUrl", StringUtils.ValueToUrl(returnUrl) } + }); + } + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + _userId = AuthRequest.GetQueryInt("userID"); + _returnUrl = StringUtils.ValueFromUrl(AuthRequest.GetQueryString("returnUrl")); + + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.User); + + LtlPageTitle.Text = _userId == 0 ? "添加用户" : "编辑用户"; + + foreach (var groupInfo in UserGroupManager.GetUserGroupInfoList()) + { + DdlGroupId.Items.Add(new ListItem(groupInfo.GroupName, groupInfo.Id.ToString())); + } + + if (_userId > 0) + { + var userInfo = UserManager.GetUserInfoByUserId(_userId); + if (userInfo != null) + { + TbUserName.Text = userInfo.UserName; + SystemWebUtils.SelectSingleItem(DdlGroupId, userInfo.GroupId.ToString()); + TbUserName.Enabled = false; + TbDisplayName.Text = userInfo.DisplayName; + PhPassword.Visible = false; + TbEmail.Text = userInfo.Email; + TbMobile.Text = userInfo.Mobile; + } + } + + if (!EUserPasswordRestrictionUtils.Equals(ConfigManager.Instance.UserPasswordRestriction, EUserPasswordRestriction.None)) + { + LtlPasswordTips.Text = $"请包含{EUserPasswordRestrictionUtils.GetText(EUserPasswordRestrictionUtils.GetEnumType(ConfigManager.Instance.UserPasswordRestriction))}"; + } + + if (!string.IsNullOrEmpty(_returnUrl)) + { + BtnReturn.Attributes.Add("onclick", $"window.location.href='{_returnUrl}';return false;"); + } + else + { + BtnReturn.Visible = false; + } + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + if (_userId == 0) + { + var userInfo = new UserInfo + { + UserName = TbUserName.Text, + Password = TbPassword.Text, + CreateDate = DateTime.Now, + LastActivityDate = DateUtils.SqlMinValue, + Checked = true, + Locked = false, + DisplayName = TbDisplayName.Text, + Email = TbEmail.Text, + Mobile = TbMobile.Text, + GroupId = TranslateUtils.ToInt(DdlGroupId.SelectedValue) + }; + + string errorMessage; + var userId = DataProvider.User.Insert(userInfo, userInfo.Password, string.Empty, out errorMessage); + + if (userId > 0) + { + AuthRequest.AddAdminLog("添加用户", + $"用户:{TbUserName.Text}"); + + SuccessMessage("用户添加成功,可以继续添加!"); + AddWaitAndRedirectScript(GetRedirectUrlToAdd(_returnUrl)); + } + else + { + FailMessage($"用户添加失败:
    {errorMessage}"); + } + } + else + { + var userInfo = UserManager.GetUserInfoByUserId(_userId); + + userInfo.GroupId = TranslateUtils.ToInt(DdlGroupId.SelectedValue); + userInfo.DisplayName = TbDisplayName.Text; + userInfo.Email = TbEmail.Text; + userInfo.Mobile = TbMobile.Text; + + DataProvider.User.Update(userInfo); + + AuthRequest.AddAdminLog("修改用户", + $"用户:{TbUserName.Text}"); + + SuccessMessage("用户修改成功!"); + AddWaitAndRedirectScript(_returnUrl); + } + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.BackgroundPages/Settings/PageUtilityCache.cs b/net452/SiteServer.BackgroundPages/Settings/PageUtilityCache.cs new file mode 100644 index 000000000..33ea7bafc --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageUtilityCache.cs @@ -0,0 +1,79 @@ +using System; +using System.Collections; +using System.Web.UI.WebControls; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageUtilityCache : BasePage + { + public Literal LtlCount; + public Repeater RptContents; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.Utility); + + LtlCount.Text = CacheUtils.Count.ToString(); + + RptContents.DataSource = CacheUtils.AllKeys; + RptContents.ItemDataBound += RptContents_ItemDataBound; + RptContents.DataBind(); + } + + private void RptContents_ItemDataBound(object sender, RepeaterItemEventArgs e) + { + if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem) return; + + var key = (string) e.Item.DataItem; + var value = CacheUtils.Get(key); + + var valueType = value?.GetType().FullName; + if (valueType == null) + { + e.Item.Visible = false; + return; + } + + var ltlKey = (Literal)e.Item.FindControl("ltlKey"); + var ltlValue = (Literal)e.Item.FindControl("ltlValue"); + + ltlKey.Text = key; + + if (valueType == "System.String") + { + ltlValue.Text = $"String, Length:{value.ToString().Length}"; + } + else if (valueType == "System.Int32") + { + ltlValue.Text = value.ToString(); + } + else if (valueType.StartsWith("System.Collections.Generic.List")) + { + ltlValue.Text = $"List, Count:{((ICollection)value).Count}"; + } + else + { + ltlValue.Text = valueType; + } + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + CacheUtils.ClearAll(); + CacheDbUtils.Clear(); + WebPageUtils.Redirect(FxUtils.GetSettingsUrl(nameof(PageUtilityCache), null)); + } + + } +} diff --git a/net452/SiteServer.BackgroundPages/Settings/PageUtilityDbLogDelete.cs b/net452/SiteServer.BackgroundPages/Settings/PageUtilityDbLogDelete.cs new file mode 100644 index 000000000..508221a38 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageUtilityDbLogDelete.cs @@ -0,0 +1,72 @@ +using System; +using System.Web.UI.WebControls; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.Utils; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageUtilityDbLogDelete : BasePage + { + public Literal LtlLastExecuteDate; + + protected override bool IsAccessable => true; + + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + if (IsPostBack) return; + + VerifySystemPermissions(ConfigManager.SettingsPermissions.Utility); + var dt = DataProvider.Log.GetLastRemoveLogDate(); + LtlLastExecuteDate.Text = dt == DateTime.MinValue ? "无记录" : DateUtils.GetDateAndTimeString(dt); + } + + public override void Submit_OnClick(object sender, EventArgs e) + { + if (!Page.IsPostBack || !Page.IsValid) return; + + //DataProvider.DatabaseApi.DeleteDbLog(); + + var repository = new Repository(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString); + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + DataProvider.DatabaseApi.Execute("PURGE MASTER LOGS BEFORE DATE_SUB( NOW( ), INTERVAL 3 DAY)"); + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + var databaseName = WebConfigUtils.GetDatabaseNameFormConnectionString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString); + + var versions = repository.Get(Q.SelectRaw("SERVERPROPERTY('productversion')")); + + var version = 8; + var arr = versions.Split(new[] { '.' }, StringSplitOptions.RemoveEmptyEntries); + if (arr.Length > 0) + { + version = TranslateUtils.ToInt(arr[0], 8); + } + if (version < 10) + { + //2000,2005 + var sql = $"BACKUP LOG [{databaseName}] WITH NO_LOG"; + DataProvider.DatabaseApi.Execute(sql); + } + else + { + //2008+ + var sql = + $@"ALTER DATABASE [{databaseName}] SET RECOVERY SIMPLE;DBCC shrinkfile ([{databaseName}_log], 1); ALTER DATABASE [{databaseName}] SET RECOVERY FULL; "; + DataProvider.DatabaseApi.Execute(sql); + } + } + + AuthRequest.AddAdminLog("清空数据库日志"); + + SuccessMessage("清空日志成功!"); + } + + } +} diff --git a/SiteServer.BackgroundPages/Settings/PageUtilityEncrypt.cs b/net452/SiteServer.BackgroundPages/Settings/PageUtilityEncrypt.cs similarity index 85% rename from SiteServer.BackgroundPages/Settings/PageUtilityEncrypt.cs rename to net452/SiteServer.BackgroundPages/Settings/PageUtilityEncrypt.cs index 1efe903f4..0cc104b6b 100644 --- a/SiteServer.BackgroundPages/Settings/PageUtilityEncrypt.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageUtilityEncrypt.cs @@ -1,6 +1,6 @@ using System; using System.Web.UI.WebControls; -using SiteServer.CMS.Core; +using SiteServer.CMS.Caches; using SiteServer.Utils; namespace SiteServer.BackgroundPages.Settings @@ -17,7 +17,7 @@ public void Page_Load(object sender, EventArgs e) if (!IsPostBack) { - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Utility); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Utility); } } diff --git a/net452/SiteServer.BackgroundPages/Settings/PageUtilityJsMin.cs b/net452/SiteServer.BackgroundPages/Settings/PageUtilityJsMin.cs new file mode 100644 index 000000000..514194c8b --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Settings/PageUtilityJsMin.cs @@ -0,0 +1,18 @@ +using System; +using SiteServer.CMS.Caches; + +namespace SiteServer.BackgroundPages.Settings +{ + public class PageUtilityJsMin : BasePage + { + public void Page_Load(object sender, EventArgs e) + { + if (IsForbidden) return; + + if (!IsPostBack) + { + VerifySystemPermissions(ConfigManager.SettingsPermissions.Utility); + } + } + } +} diff --git a/SiteServer.BackgroundPages/Settings/PageUtilityParameter.cs b/net452/SiteServer.BackgroundPages/Settings/PageUtilityParameter.cs similarity index 81% rename from SiteServer.BackgroundPages/Settings/PageUtilityParameter.cs rename to net452/SiteServer.BackgroundPages/Settings/PageUtilityParameter.cs index 26d4b5bd3..8d3bfc17b 100644 --- a/SiteServer.BackgroundPages/Settings/PageUtilityParameter.cs +++ b/net452/SiteServer.BackgroundPages/Settings/PageUtilityParameter.cs @@ -2,7 +2,12 @@ using System.Collections.Generic; using System.Net; using System.Web.UI.WebControls; +using Datory; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; using SiteServer.Utils; namespace SiteServer.BackgroundPages.Settings @@ -17,21 +22,21 @@ public void Page_Load(object sender, EventArgs e) if (IsPostBack) return; - VerifyAdministratorPermissions(ConfigManager.SettingsPermissions.Utility); + VerifySystemPermissions(ConfigManager.SettingsPermissions.Utility); var parameterList = new List> { new KeyValuePair("系统主机名", Dns.GetHostName().ToUpper()), new KeyValuePair("系统根目录地址", WebConfigUtils.PhysicalApplicationPath), new KeyValuePair("系统程序目录地址", PathUtils.PhysicalSiteServerPath), - new KeyValuePair("域名", PageUtils.GetHost()), - new KeyValuePair("访问IP", PageUtils.GetIpAddress()), + new KeyValuePair("域名", FxUtils.GetHost()), + new KeyValuePair("访问IP", FxUtils.GetIpAddress()), new KeyValuePair(".NET版本", Environment.Version.ToString()), new KeyValuePair("SiteServer CMS 版本", SystemManager.Version), new KeyValuePair("SiteServer.Plugin 版本", SystemManager.PluginVersion), new KeyValuePair("最近升级时间", DateUtils.GetDateAndTimeString(ConfigManager.Instance.UpdateDate)), new KeyValuePair("数据库类型", WebConfigUtils.DatabaseType.Value), - new KeyValuePair("数据库名称", SqlUtils.GetDatabaseNameFormConnectionString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString)) + new KeyValuePair("数据库名称", WebConfigUtils.GetDatabaseNameFormConnectionString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString)) }; RptContents.DataSource = parameterList; diff --git a/SiteServer.BackgroundPages/SiteServer.BackgroundPages.csproj b/net452/SiteServer.BackgroundPages/SiteServer.BackgroundPages.csproj similarity index 76% rename from SiteServer.BackgroundPages/SiteServer.BackgroundPages.csproj rename to net452/SiteServer.BackgroundPages/SiteServer.BackgroundPages.csproj index 18ac4e5f7..8bdeb1d24 100644 --- a/SiteServer.BackgroundPages/SiteServer.BackgroundPages.csproj +++ b/net452/SiteServer.BackgroundPages/SiteServer.BackgroundPages.csproj @@ -1,6 +1,6 @@  - + Debug @@ -34,13 +34,73 @@ 4 - - ..\packages\SiteServer.Plugin.1.5.0\lib\net45\SiteServer.Plugin.dll + + ..\..\packages\Dapper.1.60.6\lib\net451\Dapper.dll + + + ..\..\packages\Datory.0.1.7\lib\net452\Datory.dll + + + ..\..\packages\Google.Protobuf.3.5.1\lib\net45\Google.Protobuf.dll + + + ..\..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + + ..\..\packages\MySql.Data.8.0.15\lib\net452\MySql.Data.dll + + + ..\..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll + + + ..\..\packages\Npgsql.4.0.5\lib\net451\Npgsql.dll + + + ..\..\packages\Oracle.ManagedDataAccess.18.6.0\lib\net40\Oracle.ManagedDataAccess.dll + + + ..\..\packages\SqlKata.1.1.7\lib\net45\QueryBuilder.dll + + + ..\..\packages\SiteServer.Plugin.2.2.14-beta\lib\net452\SiteServer.Plugin.dll + + ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll + + + + + + + + + + ..\..\packages\System.Memory.4.5.2\lib\netstandard2.0\System.Memory.dll + + + ..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll + + + + ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + + + + ..\..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll + + + ..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.7\lib\net45\System.Web.Http.dll + @@ -80,6 +140,18 @@ ASPXCodeBehind + + ASPXCodeBehind + + + ASPXCodeBehind + + + ASPXCodeBehind + + + ASPXCodeBehind + ASPXCodeBehind @@ -104,12 +176,6 @@ ASPXCodeBehind - - ASPXCodeBehind - - - ASPXCodeBehind - ASPXCodeBehind @@ -303,18 +369,12 @@ ASPXCodeBehind - - ASPXCodeBehind - ASPXCodeBehind ASPXCodeBehind - - ASPXCodeBehind - ASPXCodeBehind @@ -333,27 +393,15 @@ ASPXCodeBehind - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - + ASPXCodeBehind - + ASPXCodeBehind ASPXCodeBehind - - ASPXCodeBehind - ASPXCodeBehind @@ -381,28 +429,19 @@ ASPXCodeBehind - - ASPXCodeBehind - - - ASPXCodeBehind - - + ASPXCodeBehind - - ASPXCodeBehind - - + ASPXCodeBehind - + ASPXCodeBehind - + ASPXCodeBehind - + ASPXCodeBehind @@ -417,11 +456,11 @@ ASPXCodeBehind + + ASPXCodeBehind - - @@ -430,11 +469,10 @@ - - + @@ -442,98 +480,43 @@ + - - + + + + + + + + + + - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - ASPXCodeBehind - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - + ASPXCodeBehind - - ASPXCodeBehind - - - ASPXCodeBehind - - - - ASPXCodeBehind - - - ASPXCodeBehind - - - ASPXCodeBehind - ASPXCodeBehind - - ASPXCodeBehind - ASPXCodeBehind - - ASPXCodeBehind - ASPXCodeBehind @@ -555,9 +538,6 @@ ASPXCodeBehind - - ASPXCodeBehind - ASPXCodeBehind @@ -576,12 +556,6 @@ ASPXCodeBehind - - ASPXCodeBehind - - - ASPXCodeBehind - ASPXCodeBehind @@ -603,12 +577,6 @@ ASPXCodeBehind - - ASPXCodeBehind - - - ASPXCodeBehind - ASPXCodeBehind @@ -618,9 +586,6 @@ ASPXCodeBehind - - ASPXCodeBehind - ASPXCodeBehind @@ -636,18 +601,12 @@ ASPXCodeBehind - - ASPXCodeBehind - ASPXCodeBehind ASPXCodeBehind - - ASPXCodeBehind - ASPXCodeBehind @@ -657,13 +616,10 @@ ASPXCodeBehind - - ASPXCodeBehind - ASPXCodeBehind - + ASPXCodeBehind @@ -696,12 +652,6 @@ ASPXCodeBehind - - ASPXCodeBehind - - - ASPXCodeBehind - ASPXCodeBehind @@ -717,26 +667,29 @@ ASPXCodeBehind + + + + + {059e3927-37e1-4f6f-b525-fef40c54906b} + SiteServer.Utils + {944127c3-915d-4f02-a534-64ec668c46ec} SiteServer.CMS - - {2176d8ba-5f57-4c56-8e21-a09011517ae2} - SiteServer.Utils - 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 - + \ No newline at end of file diff --git a/net452/SiteServer.BackgroundPages/Utils/RequestImpl.cs b/net452/SiteServer.BackgroundPages/Utils/RequestImpl.cs new file mode 100644 index 000000000..afd10b219 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Utils/RequestImpl.cs @@ -0,0 +1,510 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.IO; +using System.Web; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.BackgroundPages.Utils +{ + [Obsolete] + public class RequestImpl + { + public RequestImpl(HttpRequest request) + { + try + { + HttpRequest = request; + + var apiToken = ApiToken; + if (!string.IsNullOrEmpty(apiToken)) + { + var tokenInfo = AccessTokenManager.GetAccessTokenInfo(apiToken); + if (tokenInfo != null) + { + if (!string.IsNullOrEmpty(tokenInfo.AdminName)) + { + var adminInfo = AdminManager.GetAdminInfoByUserName(tokenInfo.AdminName); + if (adminInfo != null && !adminInfo.Locked) + { + AdminInfo = adminInfo; + IsAdminLoggin = true; + } + } + + IsApiAuthenticated = true; + } + } + + var userToken = UserToken; + if (!string.IsNullOrEmpty(userToken)) + { + var tokenImpl = UserApi.Instance.ParseAccessToken(userToken); + if (tokenImpl.UserId > 0 && !string.IsNullOrEmpty(tokenImpl.UserName)) + { + var userInfo = UserManager.GetUserInfoByUserId(tokenImpl.UserId); + if (userInfo != null && !userInfo.Locked && userInfo.Checked && userInfo.UserName == tokenImpl.UserName) + { + UserInfo = userInfo; + IsUserLoggin = true; + } + } + } + + var adminToken = AdminToken; + if (!string.IsNullOrEmpty(adminToken)) + { + var tokenImpl = AdminApi.Instance.ParseAccessToken(adminToken); + if (tokenImpl.UserId > 0 && !string.IsNullOrEmpty(tokenImpl.UserName)) + { + var adminInfo = AdminManager.GetAdminInfoByUserId(tokenImpl.UserId); + if (adminInfo != null && !adminInfo.Locked && adminInfo.UserName == tokenImpl.UserName) + { + AdminInfo = adminInfo; + IsAdminLoggin = true; + } + } + } + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + } + } + + public bool IsApiAuthenticated { get; } + + public bool IsUserLoggin { get; } + + public bool IsAdminLoggin { get; private set; } + + public string ApiToken + { + get + { + var accessTokenStr = string.Empty; + if (!string.IsNullOrEmpty(HttpRequest.Headers.Get(Constants.AuthKeyApiHeader))) + { + accessTokenStr = HttpRequest.Headers.Get(Constants.AuthKeyApiHeader); + } + else if (!string.IsNullOrEmpty(HttpRequest.QueryString[Constants.AuthKeyApiQuery])) + { + accessTokenStr = HttpRequest.QueryString[Constants.AuthKeyApiQuery]; + } + else if (!string.IsNullOrEmpty(CookieUtils.GetCookie(Constants.AuthKeyApiCookie))) + { + accessTokenStr = CookieUtils.GetCookie(Constants.AuthKeyApiCookie); + } + + if (StringUtils.EndsWith(accessTokenStr, TranslateUtils.EncryptStingIndicator)) + { + accessTokenStr = TranslateUtils.DecryptStringBySecretKey(accessTokenStr); + } + + return accessTokenStr; + } + } + + private string UserToken + { + get + { + var accessTokenStr = string.Empty; + if (!string.IsNullOrEmpty(CookieUtils.GetCookie(Constants.AuthKeyUserCookie))) + { + accessTokenStr = CookieUtils.GetCookie(Constants.AuthKeyUserCookie); + } + else if (!string.IsNullOrEmpty(HttpRequest.Headers.Get(Constants.AuthKeyUserHeader))) + { + accessTokenStr = HttpRequest.Headers.Get(Constants.AuthKeyUserHeader); + } + else if (!string.IsNullOrEmpty(HttpRequest.QueryString[Constants.AuthKeyUserQuery])) + { + accessTokenStr = HttpRequest.QueryString[Constants.AuthKeyUserQuery]; + } + + if (StringUtils.EndsWith(accessTokenStr, TranslateUtils.EncryptStingIndicator)) + { + accessTokenStr = TranslateUtils.DecryptStringBySecretKey(accessTokenStr); + } + + return accessTokenStr; + } + } + + public string AdminToken + { + get + { + var accessTokenStr = string.Empty; + if (!string.IsNullOrEmpty(CookieUtils.GetCookie(Constants.AuthKeyAdminCookie))) + { + accessTokenStr = CookieUtils.GetCookie(Constants.AuthKeyAdminCookie); + } + else if (!string.IsNullOrEmpty(HttpRequest.Headers.Get(Constants.AuthKeyAdminHeader))) + { + accessTokenStr = HttpRequest.Headers.Get(Constants.AuthKeyAdminHeader); + } + else if (!string.IsNullOrEmpty(HttpRequest.QueryString[Constants.AuthKeyAdminQuery])) + { + accessTokenStr = HttpRequest.QueryString[Constants.AuthKeyAdminQuery]; + } + + if (StringUtils.EndsWith(accessTokenStr, TranslateUtils.EncryptStingIndicator)) + { + accessTokenStr = TranslateUtils.DecryptStringBySecretKey(accessTokenStr); + } + + return accessTokenStr; + } + } + + private Dictionary _postData; + + public Dictionary PostData + { + get + { + if (_postData != null) return _postData; + + var bodyStream = new StreamReader(HttpRequest.InputStream); + bodyStream.BaseStream.Seek(0, SeekOrigin.Begin); + var json = bodyStream.ReadToEnd(); + + _postData = new Dictionary(StringComparer.OrdinalIgnoreCase); + + if (string.IsNullOrEmpty(json)) return _postData; + + var dict = TranslateUtils.JsonDeserialize>(json); + foreach (var key in dict.Keys) + { + _postData[key] = dict[key]; + } + + return _postData; + } + } + + public HttpRequest HttpRequest { get; } + + public NameValueCollection QueryString => HttpRequest.QueryString; + + public int SiteId => GetQueryInt("siteId"); + + public int ChannelId => GetQueryInt("channelId"); + + public int ContentId => GetQueryInt("contentId"); + + public bool IsQueryExists(string name) + { + return HttpRequest.QueryString[name] != null; + } + + public string GetQueryString(string name) + { + return !string.IsNullOrEmpty(HttpRequest.QueryString[name]) + ? AttackUtils.FilterSql(HttpRequest.QueryString[name]) + : null; + } + + public int GetQueryInt(string name, int defaultValue = 0) + { + return !string.IsNullOrEmpty(HttpRequest.QueryString[name]) + ? TranslateUtils.ToIntWithNegative(HttpRequest.QueryString[name]) + : defaultValue; + } + + public decimal GetQueryDecimal(string name, decimal defaultValue = 0) + { + return !string.IsNullOrEmpty(HttpRequest.QueryString[name]) + ? TranslateUtils.ToDecimalWithNegative(HttpRequest.QueryString[name]) + : defaultValue; + } + + public bool GetQueryBool(string name, bool defaultValue = false) + { + var str = HttpRequest.QueryString[name]; + return !string.IsNullOrEmpty(str) ? TranslateUtils.ToBool(str) : defaultValue; + } + + public bool IsPostExists(string name) + { + return PostData.ContainsKey(name); + } + + public T GetPostObject(string name = "") + { + string json; + if (string.IsNullOrEmpty(name)) + { + var bodyStream = new StreamReader(HttpRequest.InputStream); + bodyStream.BaseStream.Seek(0, SeekOrigin.Begin); + json = bodyStream.ReadToEnd(); + } + else + { + json = GetPostString(name); + } + + return TranslateUtils.JsonDeserialize(json); + } + + private object GetPostObject(string name) + { + if (string.IsNullOrEmpty(name)) return null; + + return PostData.TryGetValue(name, out var value) ? value : null; + } + + public string GetPostString(string name) + { + var value = GetPostObject(name); + if (value == null) return null; + if (value is string) return (string)value; + return value.ToString(); + } + + public int GetPostInt(string name, int defaultValue = 0) + { + var value = GetPostObject(name); + if (value == null) return defaultValue; + if (value is int) return (int)value; + return TranslateUtils.ToIntWithNegative(value.ToString(), defaultValue); + } + + public decimal GetPostDecimal(string name, decimal defaultValue = 0) + { + var value = GetPostObject(name); + if (value == null) return defaultValue; + if (value is decimal) return (decimal)value; + return TranslateUtils.ToDecimalWithNegative(value.ToString(), defaultValue); + } + + public bool GetPostBool(string name, bool defaultValue = false) + { + var value = GetPostObject(name); + if (value == null) return defaultValue; + if (value is bool) return (bool)value; + return TranslateUtils.ToBool(value.ToString(), defaultValue); + } + + public DateTime GetPostDateTime(string name, DateTime defaultValue) + { + var value = GetPostObject(name); + if (value == null) return defaultValue; + if (value is DateTime) return (DateTime)value; + return TranslateUtils.ToDateTime(value.ToString(), defaultValue); + } + + #region Log + + public void AddSiteLog(int siteId, string action) + { + AddSiteLog(siteId, 0, 0, action, string.Empty); + } + + public void AddSiteLog(int siteId, string action, string summary) + { + AddSiteLog(siteId, 0, 0, action, summary); + } + + public void AddSiteLog(int siteId, int channelId, string action, string summary) + { + LogUtils.AddSiteLog(siteId, channelId, 0, AdminName, action, summary); + } + + public void AddSiteLog(int siteId, int channelId, int contentId, string action, string summary) + { + LogUtils.AddSiteLog(siteId, channelId, contentId, AdminName, action, summary); + } + + public void AddAdminLog(string action, string summary) + { + LogUtils.AddAdminLog(AdminName, action, summary); + } + + public void AddAdminLog(string action) + { + LogUtils.AddAdminLog(AdminName, action); + } + + #endregion + + #region Cookie + + public void SetCookie(string name, string value) + { + CookieUtils.SetCookie(name, value); + } + + public void SetCookie(string name, string value, TimeSpan expiresAt) + { + CookieUtils.SetCookie(name, value, expiresAt); + } + + public string GetCookie(string name) + { + return CookieUtils.GetCookie(name); + } + + public bool IsCookieExists(string name) + { + return CookieUtils.IsExists(name); + } + + #endregion + + private PermissionsImpl _userPermissionsImpl; + + public PermissionsImpl UserPermissionsImpl + { + get + { + if (_userPermissionsImpl != null) return _userPermissionsImpl; + + if (UserInfo != null) + { + var groupInfo = UserGroupManager.GetUserGroupInfo(UserInfo.GroupId); + if (groupInfo != null) + { + AdminInfo = AdminManager.GetAdminInfoByUserName(groupInfo.AdminName); + } + } + + _userPermissionsImpl = new PermissionsImpl(AdminInfo); + + return _userPermissionsImpl; + } + } + + public IPermissions UserPermissions => UserPermissionsImpl; + + private PermissionsImpl _adminPermissionsImpl; + + public PermissionsImpl AdminPermissionsImpl + { + get + { + if (_adminPermissionsImpl != null) return _adminPermissionsImpl; + + _adminPermissionsImpl = new PermissionsImpl(AdminInfo); + + return _adminPermissionsImpl; + } + } + + public IPermissions AdminPermissions => AdminPermissionsImpl; + + #region Administrator + + public int AdminId => AdminInfo?.Id ?? 0; + + public string AdminName + { + get + { + if (AdminInfo != null) + { + return AdminInfo.UserName; + } + + if (UserInfo != null) + { + var groupInfo = UserGroupManager.GetUserGroupInfo(UserInfo.GroupId); + if (groupInfo != null) + { + return groupInfo.AdminName; + } + } + + return string.Empty; + } + } + + public AdministratorInfo AdminInfo { get; private set; } + + public string AdminLogin(string userName, bool isAutoLogin) + { + if (string.IsNullOrEmpty(userName)) return null; + var adminInfo = AdminManager.GetAdminInfoByUserName(userName); + if (adminInfo == null || adminInfo.Locked) return null; + + AdminInfo = adminInfo; + IsAdminLoggin = true; + + var expiresAt = TimeSpan.FromDays(Constants.AccessTokenExpireDays); + var accessToken = AdminApi.Instance.GetAccessToken(adminInfo.Id, adminInfo.UserName, expiresAt); + + LogUtils.AddAdminLog(adminInfo.UserName, "管理员登录"); + + if (isAutoLogin) + { + CookieUtils.SetCookie(Constants.AuthKeyAdminCookie, accessToken, expiresAt); + } + else + { + CookieUtils.SetCookie(Constants.AuthKeyAdminCookie, accessToken); + } + + return accessToken; + } + + public void AdminLogout() + { + CookieUtils.Erase(Constants.AuthKeyAdminCookie); + } + + #endregion + + #region User + + public int UserId => UserInfo?.Id ?? 0; + + public string UserName => UserInfo?.UserName ?? string.Empty; + + public UserInfo UserInfo { get; private set; } + + public string UserLogin(string userName, bool isAutoLogin) + { + if (string.IsNullOrEmpty(userName)) return null; + + var userInfo = UserManager.GetUserInfoByUserName(userName); + if (userInfo == null || userInfo.Locked || !userInfo.Checked) return null; + + UserInfo = userInfo; + + var expiresAt = TimeSpan.FromDays(Constants.AccessTokenExpireDays); + var accessToken = UserApi.Instance.GetAccessToken(UserId, UserName, expiresAt); + + DataProvider.User.UpdateLastActivityDateAndCountOfLogin(UserInfo); + LogUtils.AddUserLoginLog(userName); + + if (isAutoLogin) + { + CookieUtils.SetCookie(Constants.AuthKeyUserCookie, accessToken, expiresAt); + } + else + { + CookieUtils.SetCookie(Constants.AuthKeyUserCookie, accessToken); + } + + return accessToken; + } + + public void UserLogout() + { + UserInfo = null; + CookieUtils.Erase(Constants.AuthKeyUserCookie); + } + + #endregion + } +} \ No newline at end of file diff --git a/net452/SiteServer.BackgroundPages/Utils/SystemWebUtils.cs b/net452/SiteServer.BackgroundPages/Utils/SystemWebUtils.cs new file mode 100644 index 000000000..3196d94c1 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Utils/SystemWebUtils.cs @@ -0,0 +1,1268 @@ +using System.Collections; +using System.Collections.Generic; +using System.Text; +using System.Web.UI; +using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.BackgroundPages.Utils +{ + public static class SystemWebUtils + { + private static string GetSelectText(SiteInfo siteInfo, ChannelInfo channelInfo, PermissionsImpl adminPermissions, bool[] isLastNodeArray, bool isShowContentNum) + { + var retVal = string.Empty; + if (channelInfo.Id == channelInfo.SiteId) + { + channelInfo.LastNode = true; + } + if (channelInfo.LastNode == false) + { + isLastNodeArray[channelInfo.ParentsCount] = false; + } + else + { + isLastNodeArray[channelInfo.ParentsCount] = true; + } + for (var i = 0; i < channelInfo.ParentsCount; i++) + { + retVal = string.Concat(retVal, isLastNodeArray[i] ? " " : "│"); + } + retVal = string.Concat(retVal, channelInfo.LastNode ? "└" : "├"); + retVal = string.Concat(retVal, channelInfo.ChannelName); + + if (isShowContentNum) + { + var onlyAdminId = adminPermissions.GetOnlyAdminId(siteInfo.Id, channelInfo.Id); + var count = ContentManager.GetCount(siteInfo, channelInfo, onlyAdminId); + retVal = string.Concat(retVal, " (", count, ")"); + } + + return retVal; + } + + public static void AddListItemsForChannel(ListItemCollection listItemCollection, SiteInfo siteInfo, bool isSeeOwning, bool isShowContentNum, PermissionsImpl permissionsImpl) + { + var list = ChannelManager.GetChannelIdList(siteInfo.Id); + var nodeCount = list.Count; + var isLastNodeArray = new bool[nodeCount]; + foreach (var channelId in list) + { + var enabled = true; + if (isSeeOwning) + { + enabled = permissionsImpl.IsOwningChannelId(channelId); + if (!enabled) + { + if (!permissionsImpl.IsDescendantOwningChannelId(siteInfo.Id, channelId)) continue; + } + } + var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + + var listItem = new ListItem(GetSelectText(siteInfo, channelInfo, permissionsImpl, isLastNodeArray, isShowContentNum), channelInfo.Id.ToString()); + if (!enabled) + { + listItem.Attributes.Add("style", "color:gray;"); + } + listItemCollection.Add(listItem); + } + } + + public static void AddListItemsForAddContent(ListItemCollection listItemCollection, SiteInfo siteInfo, bool isSeeOwning, PermissionsImpl permissionsImpl) + { + var list = ChannelManager.GetChannelIdList(siteInfo.Id); + var nodeCount = list.Count; + var isLastNodeArray = new bool[nodeCount]; + foreach (var channelId in list) + { + var enabled = true; + if (isSeeOwning) + { + enabled = permissionsImpl.IsOwningChannelId(channelId); + } + + var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + if (enabled) + { + if (channelInfo.IsContentAddable == false) enabled = false; + } + + if (!enabled) + { + continue; + } + + var listItem = new ListItem(GetSelectText(siteInfo, channelInfo, permissionsImpl, isLastNodeArray, true), channelInfo.Id.ToString()); + listItemCollection.Add(listItem); + } + } + + /// + /// 得到栏目,并且不对(栏目是否可添加内容)进行判断 + /// 提供给触发器页面使用 + /// 使用场景:其他栏目的内容变动之后,设置某个栏目(此栏目不能添加内容)触发生成 + /// + public static void AddListItemsForCreateChannel(ListItemCollection listItemCollection, SiteInfo siteInfo, bool isSeeOwning, PermissionsImpl permissionsImpl) + { + var list = ChannelManager.GetChannelIdList(siteInfo.Id); + var nodeCount = list.Count; + var isLastNodeArray = new bool[nodeCount]; + foreach (var channelId in list) + { + var enabled = true; + if (isSeeOwning) + { + enabled = permissionsImpl.IsOwningChannelId(channelId); + } + + var nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + + if (!enabled) + { + continue; + } + + var listItem = new ListItem(GetSelectText(siteInfo, nodeInfo, permissionsImpl, isLastNodeArray, true), nodeInfo.Id.ToString()); + listItemCollection.Add(listItem); + } + } + + public static void LoadChannelIdListBox(ListBox channelIdListBox, SiteInfo siteInfo, int psId, ChannelInfo channelInfo, PermissionsImpl permissionsImpl) + { + channelIdListBox.Items.Clear(); + + var transType = ECrossSiteTransTypeUtils.GetEnumType(channelInfo.TransType); + + var isUseNodeNames = transType == ECrossSiteTransType.AllParentSite || transType == ECrossSiteTransType.AllSite; + + if (!isUseNodeNames) + { + var channelIdList = TranslateUtils.StringCollectionToIntList(channelInfo.TransChannelIds); + foreach (var theChannelId in channelIdList) + { + var theNodeInfo = ChannelManager.GetChannelInfo(psId, theChannelId); + if (theNodeInfo != null) + { + var listitem = new ListItem(theNodeInfo.ChannelName, theNodeInfo.Id.ToString()); + channelIdListBox.Items.Add(listitem); + } + } + } + else + { + if (!string.IsNullOrEmpty(channelInfo.TransChannelNames)) + { + var nodeNameArrayList = TranslateUtils.StringCollectionToStringList(channelInfo.TransChannelNames); + var channelIdList = ChannelManager.GetChannelIdList(psId); + foreach (var nodeName in nodeNameArrayList) + { + foreach (var theChannelId in channelIdList) + { + var theNodeInfo = ChannelManager.GetChannelInfo(psId, theChannelId); + if (theNodeInfo.ChannelName == nodeName) + { + var listitem = new ListItem(theNodeInfo.ChannelName, theNodeInfo.Id.ToString()); + channelIdListBox.Items.Add(listitem); + break; + } + } + } + } + else + { + AddListItemsForAddContent(channelIdListBox.Items, SiteManager.GetSiteInfo(psId), false, permissionsImpl); + } + } + } + + public static void AddListItemsForSite(ListControl listControl) + { + var siteIdList = SiteManager.GetSiteIdList(); + var mySystemInfoList = new List(); + var parentWithChildren = new Hashtable(); + SiteInfo hqSiteInfo = null; + foreach (var siteId in siteIdList) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo.Root) + { + hqSiteInfo = siteInfo; + } + else + { + if (siteInfo.ParentId == 0) + { + mySystemInfoList.Add(siteInfo); + } + else + { + var children = new List(); + if (parentWithChildren.Contains(siteInfo.ParentId)) + { + children = (List)parentWithChildren[siteInfo.ParentId]; + } + children.Add(siteInfo); + parentWithChildren[siteInfo.ParentId] = children; + } + } + } + if (hqSiteInfo != null) + { + AddListItemForSite(listControl, hqSiteInfo, parentWithChildren, 0); + } + foreach (var siteInfo in mySystemInfoList) + { + AddListItemForSite(listControl, siteInfo, parentWithChildren, 0); + } + } + + private static void AddListItemForSite(ListControl listControl, SiteInfo siteInfo, Hashtable parentWithChildren, int level) + { + var padding = string.Empty; + for (var i = 0; i < level; i++) + { + padding += " "; + } + if (level > 0) + { + padding += "└ "; + } + + if (parentWithChildren[siteInfo.Id] != null) + { + var children = (List)parentWithChildren[siteInfo.Id]; + listControl.Items.Add(new ListItem(padding + siteInfo.SiteName + $"({children.Count})", siteInfo.Id.ToString())); + level++; + foreach (SiteInfo subSiteInfo in children) + { + AddListItemForSite(listControl, subSiteInfo, parentWithChildren, level); + } + } + else + { + listControl.Items.Add(new ListItem(padding + siteInfo.SiteName, siteInfo.Id.ToString())); + } + } + + public static string SelectedItemsValueToStringCollection(ListItemCollection items) + { + var builder = new StringBuilder(); + if (items != null) + { + foreach (ListItem item in items) + { + if (item.Selected) + { + builder.Append(item.Value).Append(","); + } + } + if (builder.Length != 0) + builder.Remove(builder.Length - 1, 1); + } + return builder.ToString(); + } + + private static ListItem GetListItem(ECrossSiteTransType type, bool selected) + { + var item = new ListItem(ECrossSiteTransTypeUtils.GetText(type), ECrossSiteTransTypeUtils.GetValue(type)); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddAllListItemsToECrossSiteTransType(ListControl listControl, bool isParentSite) + { + if (listControl == null) return; + + listControl.Items.Add(GetListItem(ECrossSiteTransType.None, false)); + listControl.Items.Add(GetListItem(ECrossSiteTransType.SelfSite, false)); + listControl.Items.Add(GetListItem(ECrossSiteTransType.SpecifiedSite, false)); + if (isParentSite) + { + listControl.Items.Add(GetListItem(ECrossSiteTransType.ParentSite, false)); + listControl.Items.Add(GetListItem(ECrossSiteTransType.AllParentSite, false)); + } + listControl.Items.Add(GetListItem(ECrossSiteTransType.AllSite, false)); + } + + public static void AddListItemsToEKeywordGrade(ListControl listControl) + { + if (listControl != null) + { + var item = new ListItem(EKeywordGradeUtils.GetText(EKeywordGrade.Normal), EKeywordGradeUtils.GetValue(EKeywordGrade.Normal)); + listControl.Items.Add(item); + item = new ListItem(EKeywordGradeUtils.GetText(EKeywordGrade.Sensitive), EKeywordGradeUtils.GetValue(EKeywordGrade.Sensitive)); + listControl.Items.Add(item); + item = new ListItem(EKeywordGradeUtils.GetText(EKeywordGrade.Dangerous), EKeywordGradeUtils.GetValue(EKeywordGrade.Dangerous)); + listControl.Items.Add(item); + } + } + + private static ListItem GetListItem(ELinkType type, bool selected) + { + var item = new ListItem(ELinkTypeUtils.GetText(type), ELinkTypeUtils.GetValue(type)); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddListItemsToELinkType(ListControl listControl) + { + if (listControl == null) return; + + listControl.Items.Add(GetListItem(ELinkType.None, false)); + listControl.Items.Add(GetListItem(ELinkType.NoLinkIfContentNotExists, false)); + listControl.Items.Add(GetListItem(ELinkType.LinkToOnlyOneContent, false)); + listControl.Items.Add(GetListItem(ELinkType.NoLinkIfContentNotExistsAndLinkToOnlyOneContent, false)); + listControl.Items.Add(GetListItem(ELinkType.LinkToFirstContent, false)); + listControl.Items.Add(GetListItem(ELinkType.NoLinkIfContentNotExistsAndLinkToFirstContent, false)); + listControl.Items.Add(GetListItem(ELinkType.NoLinkIfChannelNotExists, false)); + listControl.Items.Add(GetListItem(ELinkType.LinkToLastAddChannel, false)); + listControl.Items.Add(GetListItem(ELinkType.LinkToFirstChannel, false)); + listControl.Items.Add(GetListItem(ELinkType.NoLinkIfChannelNotExistsAndLinkToLastAddChannel, false)); + listControl.Items.Add(GetListItem(ELinkType.NoLinkIfChannelNotExistsAndLinkToFirstChannel, false)); + listControl.Items.Add(GetListItem(ELinkType.NoLink, false)); + } + + private static ListItem GetListItem(TemplateType type, bool selected) + { + var item = new ListItem(TemplateTypeUtils.GetText(type), type.Value); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddListItemsToTemplateType(ListControl listControl) + { + if (listControl != null) + { + listControl.Items.Add(GetListItem(TemplateType.IndexPageTemplate, false)); + listControl.Items.Add(GetListItem(TemplateType.ChannelTemplate, false)); + listControl.Items.Add(GetListItem(TemplateType.ContentTemplate, false)); + listControl.Items.Add(GetListItem(TemplateType.FileTemplate, false)); + } + } + + private static ListItem GetListItem(ERelatedFieldStyle type, bool selected) + { + var item = new ListItem(ERelatedFieldStyleUtils.GetText(type), ERelatedFieldStyleUtils.GetValue(type)); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddListItemsToERelatedFieldStyle(ListControl listControl) + { + if (listControl != null) + { + listControl.Items.Add(GetListItem(ERelatedFieldStyle.Horizontal, false)); + listControl.Items.Add(GetListItem(ERelatedFieldStyle.Virtical, false)); + } + } + + public static ListItem GetListItem(ETableRule type, bool selected) + { + var item = new ListItem(ETableRuleUtils.GetText(type), ETableRuleUtils.GetValue(type)); + if (selected) + { + item.Selected = true; + } + return item; + } + + private static ListItem GetListItem(ETaxisType type, bool selected) + { + var item = new ListItem(ETaxisTypeUtils.GetText(type), ETaxisTypeUtils.GetValue(type)); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddListItemsToETaxisTypeForChannelEdit(ListControl listControl) + { + if (listControl == null) return; + + listControl.Items.Add(GetListItem(ETaxisType.OrderById, false)); + listControl.Items.Add(GetListItem(ETaxisType.OrderByIdDesc, false)); + listControl.Items.Add(GetListItem(ETaxisType.OrderByAddDate, false)); + listControl.Items.Add(GetListItem(ETaxisType.OrderByAddDateDesc, false)); + listControl.Items.Add(GetListItem(ETaxisType.OrderByLastEditDate, false)); + listControl.Items.Add(GetListItem(ETaxisType.OrderByLastEditDateDesc, false)); + listControl.Items.Add(GetListItem(ETaxisType.OrderByTaxis, false)); + listControl.Items.Add(GetListItem(ETaxisType.OrderByTaxisDesc, false)); + } + + private static ListItem GetListItem(ETranslateContentType type, bool selected) + { + var item = new ListItem(ETranslateContentTypeUtils.GetText(type), ETranslateContentTypeUtils.GetValue(type)); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddListItemsToETranslateContentType(ListControl listControl, bool isCut) + { + if (listControl != null) + { + listControl.Items.Add(GetListItem(ETranslateContentType.Copy, false)); + if (isCut) + { + listControl.Items.Add(GetListItem(ETranslateContentType.Cut, false)); + } + listControl.Items.Add(GetListItem(ETranslateContentType.Reference, false)); + listControl.Items.Add(GetListItem(ETranslateContentType.ReferenceContent, false)); + } + } + + private static ListItem GetListItem(ETranslateType type, bool selected) + { + var item = new ListItem(ETranslateTypeUtils.GetText(type), ETranslateTypeUtils.GetValue(type)); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddListItemsToETranslateType(ListControl listControl) + { + if (listControl != null) + { + listControl.Items.Add(GetListItem(ETranslateType.Content, false)); + listControl.Items.Add(GetListItem(ETranslateType.Channel, false)); + listControl.Items.Add(GetListItem(ETranslateType.All, false)); + } + } + + public static Control FindControlBySelfAndChildren(string id, Control baseControl) + { + Control ctrl = null; + if (baseControl != null) + { + ctrl = baseControl.FindControl(id); + if (ctrl == baseControl) ctrl = null;//DropDownList中FindControl将返回自身 + if (ctrl == null && baseControl.HasControls()) + { + ctrl = FindControlByChildren(id, baseControl.Controls); + } + } + return ctrl; + } + + public static Control FindControlByChildren(string id, ControlCollection controls) + { + foreach (Control control in controls) + { + var ctrl = FindControlBySelfAndChildren(id, control); + if (ctrl != null) + { + return ctrl; + } + } + return null; + } + + public static void LoadContentLevelToCheckEdit(ListControl listControl, SiteInfo siteInfo, ContentInfo contentInfo, bool isChecked, int checkedLevel) + { + var checkContentLevel = siteInfo.CheckContentLevel; + if (isChecked) + { + checkedLevel = checkContentLevel; + } + + ListItem listItem; + + var isCheckable = false; + if (contentInfo != null) + { + isCheckable = CheckManager.IsCheckable(contentInfo.Checked, contentInfo.CheckedLevel, isChecked, checkedLevel); + if (isCheckable) + { + listItem = new ListItem(CheckManager.Level.NotChange, CheckManager.LevelInt.NotChange.ToString()); + listControl.Items.Add(listItem); + } + } + + listItem = new ListItem(CheckManager.Level.CaoGao, CheckManager.LevelInt.CaoGao.ToString()); + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level.DaiShen, CheckManager.LevelInt.DaiShen.ToString()); + listControl.Items.Add(listItem); + + if (checkContentLevel == 0 || checkContentLevel == 1) + { + listItem = new ListItem(CheckManager.Level1.Pass1, CheckManager.LevelInt.Pass1.ToString()) + { + Enabled = isChecked + }; + listControl.Items.Add(listItem); + } + else if (checkContentLevel == 2) + { + listItem = new ListItem(CheckManager.Level2.Pass1, CheckManager.LevelInt.Pass1.ToString()) + { + Enabled = checkedLevel >= 1 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level2.Pass2, CheckManager.LevelInt.Pass2.ToString()) + { + Enabled = isChecked + }; + listControl.Items.Add(listItem); + } + else if (checkContentLevel == 3) + { + listItem = new ListItem(CheckManager.Level3.Pass1, CheckManager.LevelInt.Pass1.ToString()) + { + Enabled = checkedLevel >= 1 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level3.Pass2, CheckManager.LevelInt.Pass2.ToString()) + { + Enabled = checkedLevel >= 2 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level3.Pass3, CheckManager.LevelInt.Pass3.ToString()) + { + Enabled = isChecked + }; + listControl.Items.Add(listItem); + } + else if (checkContentLevel == 4) + { + listItem = new ListItem(CheckManager.Level4.Pass1, CheckManager.LevelInt.Pass1.ToString()) + { + Enabled = checkedLevel >= 1 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level4.Pass2, CheckManager.LevelInt.Pass2.ToString()) + { + Enabled = checkedLevel >= 2 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level4.Pass3, CheckManager.LevelInt.Pass3.ToString()) + { + Enabled = checkedLevel >= 3 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level4.Pass4, CheckManager.LevelInt.Pass4.ToString()) + { + Enabled = isChecked + }; + listControl.Items.Add(listItem); + } + else if (checkContentLevel == 5) + { + listItem = new ListItem(CheckManager.Level5.Pass1, CheckManager.LevelInt.Pass1.ToString()) + { + Enabled = checkedLevel >= 1 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level5.Pass2, CheckManager.LevelInt.Pass2.ToString()) + { + Enabled = checkedLevel >= 2 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level5.Pass3, CheckManager.LevelInt.Pass3.ToString()) + { + Enabled = checkedLevel >= 3 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level5.Pass4, CheckManager.LevelInt.Pass4.ToString()) + { + Enabled = checkedLevel >= 4 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level5.Pass5, CheckManager.LevelInt.Pass5.ToString()) + { + Enabled = isChecked + }; + listControl.Items.Add(listItem); + } + + if (contentInfo == null) + { + SelectSingleItem(listControl, checkedLevel.ToString()); + } + else + { + SelectSingleItem(listControl, + isCheckable ? CheckManager.LevelInt.NotChange.ToString() : checkedLevel.ToString()); + } + } + + public static void LoadContentLevelToCheckList(ListControl listControl, SiteInfo siteInfo, bool isCheckOnly, bool isChecked, int checkedLevel) + { + var checkContentLevel = siteInfo.CheckContentLevel; + + if (isChecked) + { + checkedLevel = checkContentLevel; + } + + listControl.Items.Add(new ListItem(CheckManager.Level.All, CheckManager.LevelInt.All.ToString())); + listControl.Items.Add(new ListItem(CheckManager.Level.CaoGao, CheckManager.LevelInt.CaoGao.ToString())); + listControl.Items.Add(new ListItem(CheckManager.Level.DaiShen, CheckManager.LevelInt.DaiShen.ToString())); + + if (checkContentLevel == 1) + { + if (isChecked) + { + listControl.Items.Add(new ListItem(CheckManager.Level1.Fail1, CheckManager.LevelInt.Fail1.ToString())); + } + } + else if (checkContentLevel == 2) + { + if (checkedLevel >= 1) + { + listControl.Items.Add(new ListItem(CheckManager.Level2.Fail1, CheckManager.LevelInt.Fail1.ToString())); + } + + if (isChecked) + { + listControl.Items.Add(new ListItem(CheckManager.Level2.Fail2, CheckManager.LevelInt.Fail2.ToString())); + } + } + else if (checkContentLevel == 3) + { + if (checkedLevel >= 1) + { + listControl.Items.Add(new ListItem(CheckManager.Level3.Fail1, CheckManager.LevelInt.Fail1.ToString())); + } + + if (checkedLevel >= 2) + { + listControl.Items.Add(new ListItem(CheckManager.Level3.Fail2, CheckManager.LevelInt.Fail2.ToString())); + } + + if (isChecked) + { + listControl.Items.Add(new ListItem(CheckManager.Level3.Fail3, CheckManager.LevelInt.Fail3.ToString())); + } + } + else if (checkContentLevel == 4) + { + if (checkedLevel >= 1) + { + listControl.Items.Add(new ListItem(CheckManager.Level4.Fail1, CheckManager.LevelInt.Fail1.ToString())); + } + + if (checkedLevel >= 2) + { + listControl.Items.Add(new ListItem(CheckManager.Level4.Fail2, CheckManager.LevelInt.Fail2.ToString())); + } + + if (checkedLevel >= 3) + { + listControl.Items.Add(new ListItem(CheckManager.Level4.Fail3, CheckManager.LevelInt.Fail3.ToString())); + } + + if (isChecked) + { + listControl.Items.Add(new ListItem(CheckManager.Level4.Fail4, CheckManager.LevelInt.Fail4.ToString())); + } + } + else if (checkContentLevel == 5) + { + if (checkedLevel >= 1) + { + listControl.Items.Add(new ListItem(CheckManager.Level5.Fail1, CheckManager.LevelInt.Fail1.ToString())); + } + + if (checkedLevel >= 2) + { + listControl.Items.Add(new ListItem(CheckManager.Level5.Fail2, CheckManager.LevelInt.Fail2.ToString())); + } + + if (checkedLevel >= 3) + { + listControl.Items.Add(new ListItem(CheckManager.Level5.Fail3, CheckManager.LevelInt.Fail3.ToString())); + } + + if (checkedLevel >= 4) + { + listControl.Items.Add(new ListItem(CheckManager.Level5.Fail4, CheckManager.LevelInt.Fail4.ToString())); + } + + if (isChecked) + { + listControl.Items.Add(new ListItem(CheckManager.Level5.Fail5, CheckManager.LevelInt.Fail5.ToString())); + } + } + + if (isCheckOnly) return; + + if (checkContentLevel == 1) + { + if (isChecked) + { + listControl.Items.Add(new ListItem(CheckManager.Level1.Pass1, CheckManager.LevelInt.Pass1.ToString())); + } + } + if (checkContentLevel == 2) + { + if (checkedLevel >= 1) + { + listControl.Items.Add(new ListItem(CheckManager.Level2.Pass1, CheckManager.LevelInt.Pass1.ToString())); + } + + if (isChecked) + { + listControl.Items.Add(new ListItem(CheckManager.Level2.Pass2, CheckManager.LevelInt.Pass2.ToString())); + } + } + else if (checkContentLevel == 3) + { + if (checkedLevel >= 1) + { + listControl.Items.Add(new ListItem(CheckManager.Level3.Pass1, CheckManager.LevelInt.Pass1.ToString())); + } + + if (checkedLevel >= 2) + { + listControl.Items.Add(new ListItem(CheckManager.Level3.Pass2, CheckManager.LevelInt.Pass2.ToString())); + } + + if (isChecked) + { + listControl.Items.Add(new ListItem(CheckManager.Level3.Pass3, CheckManager.LevelInt.Pass3.ToString())); + } + } + else if (checkContentLevel == 4) + { + if (checkedLevel >= 1) + { + listControl.Items.Add(new ListItem(CheckManager.Level4.Pass1, CheckManager.LevelInt.Pass1.ToString())); + } + + if (checkedLevel >= 2) + { + listControl.Items.Add(new ListItem(CheckManager.Level4.Pass2, CheckManager.LevelInt.Pass2.ToString())); + } + + if (checkedLevel >= 3) + { + listControl.Items.Add(new ListItem(CheckManager.Level4.Pass3, CheckManager.LevelInt.Pass3.ToString())); + } + + if (isChecked) + { + listControl.Items.Add(new ListItem(CheckManager.Level4.Pass4, CheckManager.LevelInt.Pass4.ToString())); + } + } + else if (checkContentLevel == 5) + { + if (checkedLevel >= 2) + { + listControl.Items.Add(new ListItem(CheckManager.Level5.Pass1, CheckManager.LevelInt.Pass1.ToString())); + } + + if (checkedLevel >= 3) + { + listControl.Items.Add(new ListItem(CheckManager.Level5.Pass2, CheckManager.LevelInt.Pass2.ToString())); + } + + if (checkedLevel >= 4) + { + listControl.Items.Add(new ListItem(CheckManager.Level5.Pass3, CheckManager.LevelInt.Pass3.ToString())); + } + + if (checkedLevel >= 5) + { + listControl.Items.Add(new ListItem(CheckManager.Level5.Pass4, CheckManager.LevelInt.Pass4.ToString())); + } + + if (isChecked) + { + listControl.Items.Add(new ListItem(CheckManager.Level5.Pass5, CheckManager.LevelInt.Pass5.ToString())); + } + } + } + + public static void LoadContentLevelToCheck(ListControl listControl, SiteInfo siteInfo, bool isChecked, int checkedLevel) + { + var checkContentLevel = siteInfo.CheckContentLevel; + if (isChecked) + { + checkedLevel = checkContentLevel; + } + + var listItem = new ListItem(CheckManager.Level.CaoGao, CheckManager.LevelInt.CaoGao.ToString()); + listControl.Items.Add(listItem); + + listItem = new ListItem(CheckManager.Level.DaiShen, CheckManager.LevelInt.DaiShen.ToString()); + listControl.Items.Add(listItem); + + if (checkContentLevel == 1) + { + listItem = new ListItem(CheckManager.Level1.Fail1, CheckManager.LevelInt.Fail1.ToString()) + { + Enabled = isChecked + }; + listControl.Items.Add(listItem); + } + else if (checkContentLevel == 2) + { + listItem = new ListItem(CheckManager.Level2.Fail1, CheckManager.LevelInt.Fail1.ToString()) + { + Enabled = checkedLevel >= 1 + }; + listControl.Items.Add(listItem); + + listItem = new ListItem(CheckManager.Level2.Fail2, CheckManager.LevelInt.Fail2.ToString()) + { + Enabled = isChecked + }; + listControl.Items.Add(listItem); + } + else if (checkContentLevel == 3) + { + listItem = new ListItem(CheckManager.Level3.Fail1, CheckManager.LevelInt.Fail1.ToString()) + { + Enabled = checkedLevel >= 1 + }; + listControl.Items.Add(listItem); + + listItem = new ListItem(CheckManager.Level3.Fail2, CheckManager.LevelInt.Fail2.ToString()) + { + Enabled = checkedLevel >= 2 + }; + listControl.Items.Add(listItem); + + listItem = new ListItem(CheckManager.Level3.Fail3, CheckManager.LevelInt.Fail3.ToString()) + { + Enabled = isChecked + }; + listControl.Items.Add(listItem); + } + else if (checkContentLevel == 4) + { + listItem = new ListItem(CheckManager.Level4.Fail1, CheckManager.LevelInt.Fail1.ToString()) + { + Enabled = checkedLevel >= 1 + }; + listControl.Items.Add(listItem); + + listItem = new ListItem(CheckManager.Level4.Fail2, CheckManager.LevelInt.Fail2.ToString()) + { + Enabled = checkedLevel >= 2 + }; + listControl.Items.Add(listItem); + + listItem = new ListItem(CheckManager.Level4.Fail3, CheckManager.LevelInt.Fail3.ToString()) + { + Enabled = checkedLevel >= 3 + }; + listControl.Items.Add(listItem); + + listItem = new ListItem(CheckManager.Level4.Fail4, CheckManager.LevelInt.Fail4.ToString()) + { + Enabled = isChecked + }; + listControl.Items.Add(listItem); + } + else if (checkContentLevel == 5) + { + listItem = new ListItem(CheckManager.Level5.Fail1, CheckManager.LevelInt.Fail1.ToString()) + { + Enabled = checkedLevel >= 1 + }; + listControl.Items.Add(listItem); + + listItem = new ListItem(CheckManager.Level5.Fail2, CheckManager.LevelInt.Fail2.ToString()) + { + Enabled = checkedLevel >= 2 + }; + listControl.Items.Add(listItem); + + listItem = new ListItem(CheckManager.Level5.Fail3, CheckManager.LevelInt.Fail3.ToString()) + { + Enabled = checkedLevel >= 3 + }; + listControl.Items.Add(listItem); + + listItem = new ListItem(CheckManager.Level5.Fail4, CheckManager.LevelInt.Fail4.ToString()) + { + Enabled = checkedLevel >= 4 + }; + listControl.Items.Add(listItem); + + listItem = new ListItem(CheckManager.Level5.Fail5, CheckManager.LevelInt.Fail5.ToString()) + { + Enabled = isChecked + }; + listControl.Items.Add(listItem); + } + + if (checkContentLevel == 0 || checkContentLevel == 1) + { + listItem = new ListItem(CheckManager.Level1.Pass1, CheckManager.LevelInt.Pass1.ToString()) + { + Enabled = isChecked + }; + listControl.Items.Add(listItem); + } + else if (checkContentLevel == 2) + { + listItem = new ListItem(CheckManager.Level2.Pass1, CheckManager.LevelInt.Pass1.ToString()) + { + Enabled = checkedLevel >= 1 + }; + listControl.Items.Add(listItem); + + listItem = new ListItem(CheckManager.Level2.Pass2, CheckManager.LevelInt.Pass2.ToString()) + { + Enabled = isChecked + }; + listControl.Items.Add(listItem); + } + else if (checkContentLevel == 3) + { + listItem = new ListItem(CheckManager.Level3.Pass1, CheckManager.LevelInt.Pass1.ToString()) + { + Enabled = checkedLevel >= 1 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level3.Pass2, CheckManager.LevelInt.Pass2.ToString()) + { + Enabled = checkedLevel >= 2 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level3.Pass3, CheckManager.LevelInt.Pass3.ToString()) + { + Enabled = isChecked + }; + listControl.Items.Add(listItem); + } + else if (checkContentLevel == 4) + { + listItem = new ListItem(CheckManager.Level4.Pass1, CheckManager.LevelInt.Pass1.ToString()) + { + Enabled = checkedLevel >= 1 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level4.Pass2, CheckManager.LevelInt.Pass2.ToString()) + { + Enabled = checkedLevel >= 2 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level4.Pass3, CheckManager.LevelInt.Pass3.ToString()) + { + Enabled = checkedLevel >= 3 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level4.Pass4, CheckManager.LevelInt.Pass4.ToString()) + { + Enabled = isChecked + }; + listControl.Items.Add(listItem); + } + else if (checkContentLevel == 5) + { + listItem = new ListItem(CheckManager.Level5.Pass1, CheckManager.LevelInt.Pass1.ToString()) + { + Enabled = checkedLevel >= 1 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level5.Pass2, CheckManager.LevelInt.Pass2.ToString()) + { + Enabled = checkedLevel >= 2 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level5.Pass3, CheckManager.LevelInt.Pass3.ToString()) + { + Enabled = checkedLevel >= 3 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level5.Pass4, CheckManager.LevelInt.Pass4.ToString()) + { + Enabled = checkedLevel >= 4 + }; + listControl.Items.Add(listItem); + listItem = new ListItem(CheckManager.Level5.Pass5, CheckManager.LevelInt.Pass5.ToString()) + { + Enabled = isChecked + }; + listControl.Items.Add(listItem); + } + + SelectSingleItem(listControl, checkedLevel.ToString()); + } + + public static void AddListControlItems(ListControl listControl, List list) + { + if (listControl == null) return; + + foreach (var value in list) + { + var item = new ListItem(value, value); + listControl.Items.Add(item); + } + } + + public static string[] GetSelectedListControlValueArray(ListControl listControl) + { + var arraylist = new ArrayList(); + if (listControl != null) + { + foreach (ListItem item in listControl.Items) + { + if (item.Selected) + { + arraylist.Add(item.Value); + } + } + } + var retval = new string[arraylist.Count]; + arraylist.CopyTo(retval); + return retval; + } + + public static string GetSelectedListControlValueCollection(ListControl listControl) + { + var list = new List(); + if (listControl != null) + { + foreach (ListItem item in listControl.Items) + { + if (item.Selected) + { + list.Add(item.Value); + } + } + } + return TranslateUtils.ObjectCollectionToString(list); + } + + public static ArrayList GetSelectedListControlValueArrayList(ListControl listControl) + { + var arraylist = new ArrayList(); + if (listControl != null) + { + foreach (ListItem item in listControl.Items) + { + if (item.Selected) + { + arraylist.Add(item.Value); + } + } + } + return arraylist; + } + + public static List GetSelectedListControlValueStringList(ListControl listControl) + { + var list = new List(); + if (listControl != null) + { + foreach (ListItem item in listControl.Items) + { + if (item.Selected) + { + list.Add(item.Value); + } + } + } + return list; + } + + public static string[] GetListControlValues(ListControl listControl) + { + var arraylist = new ArrayList(); + if (listControl != null) + { + foreach (ListItem item in listControl.Items) + { + arraylist.Add(item.Value); + } + } + var retval = new string[arraylist.Count]; + arraylist.CopyTo(retval); + return retval; + } + + public static void SelectSingleItem(ListControl listControl, string value) + { + if (listControl == null) return; + + listControl.ClearSelection(); + + foreach (ListItem item in listControl.Items) + { + if (string.Equals(item.Value, value)) + { + item.Selected = true; + break; + } + } + } + + public static void SelectSingleItemIgnoreCase(ListControl listControl, string value) + { + if (listControl == null) return; + + listControl.ClearSelection(); + foreach (ListItem item in listControl.Items) + { + if (StringUtils.EqualsIgnoreCase(item.Value, value)) + { + item.Selected = true; + break; + } + } + } + + public static void SelectMultiItems(ListControl listControl, List values) + { + if (listControl == null) return; + + listControl.ClearSelection(); + foreach (ListItem item in listControl.Items) + { + foreach (var value in values) + { + if (string.Equals(item.Value, value)) + { + item.Selected = true; + break; + } + } + } + } + + public static void SelectMultiItems(ListControl listControl, List values) + { + if (listControl == null) return; + + listControl.ClearSelection(); + foreach (ListItem item in listControl.Items) + { + foreach (var intVal in values) + { + if (string.Equals(item.Value, intVal.ToString())) + { + item.Selected = true; + break; + } + } + } + } + + public static void LoadSiteIdDropDownList(DropDownList siteIdDropDownList, SiteInfo siteInfo, int channelId) + { + siteIdDropDownList.Items.Clear(); + + var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + + var transType = ECrossSiteTransTypeUtils.GetEnumType(channelInfo.TransType); + + if (transType == ECrossSiteTransType.SelfSite || transType == ECrossSiteTransType.SpecifiedSite || transType == ECrossSiteTransType.ParentSite) + { + int theSiteId; + if (transType == ECrossSiteTransType.SelfSite) + { + theSiteId = siteInfo.Id; + } + else if (transType == ECrossSiteTransType.SpecifiedSite) + { + theSiteId = channelInfo.TransSiteId; + } + else + { + theSiteId = SiteManager.GetParentSiteId(siteInfo.Id); + } + if (theSiteId > 0) + { + var theSiteInfo = SiteManager.GetSiteInfo(theSiteId); + if (theSiteInfo != null) + { + var listitem = new ListItem(theSiteInfo.SiteName, theSiteInfo.Id.ToString()); + siteIdDropDownList.Items.Add(listitem); + } + } + } + else if (transType == ECrossSiteTransType.AllParentSite) + { + var siteIdList = SiteManager.GetSiteIdList(); + + var allParentSiteIdList = new List(); + SiteManager.GetAllParentSiteIdList(allParentSiteIdList, siteIdList, siteInfo.Id); + + foreach (var psId in siteIdList) + { + if (psId == siteInfo.Id) continue; + var psInfo = SiteManager.GetSiteInfo(psId); + var show = psInfo.Root || allParentSiteIdList.Contains(psInfo.Id); + if (show) + { + var listitem = new ListItem(psInfo.SiteName, psId.ToString()); + if (psInfo.Root) listitem.Selected = true; + siteIdDropDownList.Items.Add(listitem); + } + } + } + else if (transType == ECrossSiteTransType.AllSite) + { + var siteIdList = SiteManager.GetSiteIdList(); + + foreach (var psId in siteIdList) + { + var psInfo = SiteManager.GetSiteInfo(psId); + var listitem = new ListItem(psInfo.SiteName, psId.ToString()); + if (psInfo.Root) listitem.Selected = true; + siteIdDropDownList.Items.Add(listitem); + } + } + } + + public static ListItem GetListItem(InputType type, bool selected) + { + var item = new ListItem(InputTypeUtils.GetText(type), type.Value); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddListItemsToInputType(ListControl listControl) + { + if (listControl != null) + { + listControl.Items.Add(GetListItem(InputType.Text, false)); + listControl.Items.Add(GetListItem(InputType.TextArea, false)); + listControl.Items.Add(GetListItem(InputType.TextEditor, false)); + listControl.Items.Add(GetListItem(InputType.CheckBox, false)); + listControl.Items.Add(GetListItem(InputType.Radio, false)); + listControl.Items.Add(GetListItem(InputType.SelectOne, false)); + listControl.Items.Add(GetListItem(InputType.SelectMultiple, false)); + listControl.Items.Add(GetListItem(InputType.SelectCascading, false)); + listControl.Items.Add(GetListItem(InputType.Date, false)); + listControl.Items.Add(GetListItem(InputType.DateTime, false)); + listControl.Items.Add(GetListItem(InputType.Image, false)); + listControl.Items.Add(GetListItem(InputType.Video, false)); + listControl.Items.Add(GetListItem(InputType.File, false)); + listControl.Items.Add(GetListItem(InputType.Customize, false)); + listControl.Items.Add(GetListItem(InputType.Hidden, false)); + } + } + } +} diff --git a/net452/SiteServer.BackgroundPages/Utils/WebPageUtils.cs b/net452/SiteServer.BackgroundPages/Utils/WebPageUtils.cs new file mode 100644 index 000000000..c2bfc7cee --- /dev/null +++ b/net452/SiteServer.BackgroundPages/Utils/WebPageUtils.cs @@ -0,0 +1,298 @@ +using System; +using System.Web; +using System.Web.UI; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.BackgroundPages.Utils +{ + public static class WebPageUtils + { + public static void AddErrorLogAndRedirect(Exception ex, string summary = "") + { + if (ex == null || ex.StackTrace.Contains("System.Web.HttpResponse.set_StatusCode(Int32 value)")) return; + + var logId = LogUtils.AddErrorLog(ex, summary); + if (logId > 0) + { + RedirectToErrorPage(logId); + } + else + { + RedirectToErrorPage(ex.Message); + } + } + + public static void Redirect(string url) + { + if (string.IsNullOrWhiteSpace(url)) return; + var response = HttpContext.Current.Response; + response.Clear();//这里是关键,清除在返回前已经设置好的标头信息,这样后面的跳转才不会报错 + response.BufferOutput = true;//设置输出缓冲 + if (!response.IsRequestBeingRedirected) //在跳转之前做判断,防止重复 + { + response.Redirect(url, true); + } + } + + public static void Download(HttpResponse response, string filePath, string fileName) + { + var fileType = PathUtils.GetExtension(filePath); + var fileSystemType = EFileSystemTypeUtils.GetEnumType(fileType); + response.Buffer = true; + response.Clear(); + response.ContentType = EFileSystemTypeUtils.GetResponseContentType(fileSystemType); + response.AddHeader("Content-Disposition", "attachment; filename=" + PageUtils.UrlEncode(fileName)); + response.WriteFile(filePath); + response.Flush(); + response.End(); + } + + public static void Download(HttpResponse response, string filePath) + { + var fileName = PathUtils.GetFileName(filePath); + Download(response, filePath, fileName); + } + + public static void RedirectToErrorPage(int logId) + { + Redirect(GetErrorPageUrl(logId)); + } + + public static void RedirectToErrorPage(string message) + { + Redirect(GetErrorPageUrl(message)); + } + + public static string GetErrorPageUrl(int logId) + { + return $"{AdminPagesUtils.ErrorUrl}?logId={logId}"; + } + + public static string GetErrorPageUrl(string message) + { + return $"{AdminPagesUtils.ErrorUrl}?message={PageUtils.UrlEncode(message)}"; + } + + public static void RedirectToLoginPage() + { + Redirect(AdminPagesUtils.LoginUrl); + } + + public static void CheckRequestParameter(params string[] parameters) + { + foreach (var parameter in parameters) + { + if (!string.IsNullOrEmpty(parameter) && HttpContext.Current.Request.QueryString[parameter] == null) + { + Redirect(GetErrorPageUrl(PageErrorParameterIsNotCorrect)); + return; + } + } + } + + public static void SaveMessage(Message.EMessageType messageType, string message) + { + CookieUtils.SetCookie(Message.GetCookieName(messageType), message, TimeSpan.FromDays(1)); + } + + private static string DecodeMessage(string message) + { + if (!string.IsNullOrEmpty(message)) + { + //message = StringUtils.HtmlDecode(message); + message = message.Replace("''", "\""); + } + return message; + } + + public static string GetMessageHtml(Message.EMessageType messageType, string message, Control control) + { + var messageHtml = string.Empty; + message = DecodeMessage(message); + if (!string.IsNullOrEmpty(message)) + { + if (messageType == Message.EMessageType.Success) + { + messageHtml = $@"
    {message}
    "; + } + else if (messageType == Message.EMessageType.Error) + { + messageHtml = $@"
    {message}
    "; + } + else if (messageType == Message.EMessageType.Info) + { + messageHtml = $@"
    {message}
    "; + } + } + return messageHtml; + } + + public static string GetMessageHtml(Control control) + { + var messageType = Message.EMessageType.None; + var message = string.Empty; + if (CookieUtils.IsExists(Message.GetCookieName(Message.EMessageType.Success))) + { + messageType = Message.EMessageType.Success; + message = CookieUtils.GetCookie(Message.GetCookieName(Message.EMessageType.Success)); + CookieUtils.Erase(Message.GetCookieName(Message.EMessageType.Success)); + } + else if (CookieUtils.IsExists(Message.GetCookieName(Message.EMessageType.Error))) + { + messageType = Message.EMessageType.Error; + message = CookieUtils.GetCookie(Message.GetCookieName(Message.EMessageType.Error)); + CookieUtils.Erase(Message.GetCookieName(Message.EMessageType.Error)); + } + else if (CookieUtils.IsExists(Message.GetCookieName(Message.EMessageType.Info))) + { + messageType = Message.EMessageType.Info; + message = CookieUtils.GetCookie(Message.GetCookieName(Message.EMessageType.Info)); + CookieUtils.Erase(Message.GetCookieName(Message.EMessageType.Info)); + } + return GetMessageHtml(messageType, message, control); + } + + public static string GetAlertHtml(Message.EMessageType messageType, string message, Control control) + { + var messageHtml = string.Empty; + message = DecodeMessage(message); + if (messageType == Message.EMessageType.Success) + { + if (!string.IsNullOrEmpty(message)) + { + messageHtml = $@" +
    + + 成功!   {message}
    "; + } + } + else if (messageType == Message.EMessageType.Error) + { + if (!string.IsNullOrEmpty(message)) + { + messageHtml = $@" +
    + + 错误!   {message}
    "; + } + } + else if (messageType == Message.EMessageType.Info) + { + if (!string.IsNullOrEmpty(message)) + { + messageHtml = $@" +
    + + 提示!   {message}
    "; + } + } + return messageHtml; + } + + public static string GetAlertHtml(Control control, string text) + { + var messageType = Message.EMessageType.None; + var message = string.Empty; + if (CookieUtils.IsExists(Message.GetCookieName(Message.EMessageType.Success))) + { + messageType = Message.EMessageType.Success; + message = CookieUtils.GetCookie(Message.GetCookieName(Message.EMessageType.Success)); + CookieUtils.Erase(Message.GetCookieName(Message.EMessageType.Success)); + } + else if (CookieUtils.IsExists(Message.GetCookieName(Message.EMessageType.Error))) + { + messageType = Message.EMessageType.Error; + message = CookieUtils.GetCookie(Message.GetCookieName(Message.EMessageType.Error)); + CookieUtils.Erase(Message.GetCookieName(Message.EMessageType.Error)); + } + else if (CookieUtils.IsExists(Message.GetCookieName(Message.EMessageType.Info))) + { + messageType = Message.EMessageType.Info; + message = CookieUtils.GetCookie(Message.GetCookieName(Message.EMessageType.Info)); + CookieUtils.Erase(Message.GetCookieName(Message.EMessageType.Info)); + } + else if (!string.IsNullOrEmpty(text)) + { + messageType = Message.EMessageType.Info; + message = text; + } + return GetAlertHtml(messageType, message, control); + } + + #region Message + public class Message + { + private const string CookieName = "BaiRong_Message"; + public static string GetCookieName(EMessageType messageType) + { + return $"{CookieName}_{EMessageTypeUtils.GetValue(messageType)}"; + } + + public enum EMessageType + { + Success, + Error, + Info, + None + } + + public class EMessageTypeUtils + { + public static string GetValue(EMessageType type) + { + if (type == EMessageType.Success) + { + return "Success"; + } + if (type == EMessageType.Error) + { + return "Error"; + } + if (type == EMessageType.Info) + { + return "Info"; + } + if (type == EMessageType.None) + { + return "None"; + } + throw new Exception(); + } + } + } + #endregion + + #region Constants + + public const string InsertSuccess = "添加成功!"; + public const string UpdateSuccess = "更新成功!"; + public const string DeleteSuccess = "删除成功!"; + public const string CheckSuccess = "审核成功!"; + public const string InsertFail = "添加失败!"; + public const string UpdateFail = "更新失败!"; + public const string DeleteFail = "删除失败!"; + public const string CheckFail = "审核失败!"; + + public const string AccountLocked = "登录失败,您的帐户已经被锁定!"; + public const string AccountUnchecked = "登录失败,您的帐户还未被审核!"; + public const string AccountError = "登录失败,请重试!"; + + //public const string CheckDenied = "审核不通过"; + //public const string Unchecked = "未审核"; + //public const string CheckedLevel1 = "一级审核通过"; + //public const string CheckedLevel2 = "二级审核通过"; + //public const string CheckedLevel3 = "三级审核通过"; + //public const string CheckedLevel4 = "四级审核通过"; + //public const string CheckedLevel5 = "五级审核通过"; + + + public const string PageErrorParameterIsNotCorrect = "此页需要正确的参数传输进入!"; + + public const string PermissionNotVisible = "对不起,您没有权限浏览此页!"; + + #endregion + } +} diff --git a/net452/SiteServer.BackgroundPages/app.config b/net452/SiteServer.BackgroundPages/app.config new file mode 100644 index 000000000..44b709f20 --- /dev/null +++ b/net452/SiteServer.BackgroundPages/app.config @@ -0,0 +1,41 @@ + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/net452/SiteServer.BackgroundPages/packages.config b/net452/SiteServer.BackgroundPages/packages.config new file mode 100644 index 000000000..fdbfe5f9a --- /dev/null +++ b/net452/SiteServer.BackgroundPages/packages.config @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.CMS.Tests/Database/Core/GenericRepositoryTest.cs b/net452/SiteServer.CMS.Tests/Database/Core/GenericRepositoryTest.cs new file mode 100644 index 000000000..02fe9e1bc --- /dev/null +++ b/net452/SiteServer.CMS.Tests/Database/Core/GenericRepositoryTest.cs @@ -0,0 +1,429 @@ +using System; +using System.Linq; +using Datory; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Tests.Database.Mocks; +using SiteServer.Utils; +using SqlKata; +using Xunit; +using Xunit.Abstractions; + +namespace SiteServer.CMS.Tests.Database.Core +{ + [TestCaseOrderer("SiteServer.CMS.Tests.PriorityOrderer", "SiteServer.CMS.Tests")] + public class GenericRepositoryTest : IClassFixture + { + public EnvironmentFixture Fixture { get; } + private readonly ITestOutputHelper _output; + private readonly TestTableRepository _repository; + + public GenericRepositoryTest(EnvironmentFixture fixture, ITestOutputHelper output) + { + Fixture = fixture; + _output = output; + _repository = new TestTableRepository(); + } + + [SkippableFact, TestPriority(0)] + public void Start() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var tableName = _repository.TableName; + var tableColumns = _repository.TableColumns; + + Assert.Equal("TestTable", tableName); + Assert.NotNull(tableColumns); + Assert.Equal(10, tableColumns.Count); + + var varChar100Column = tableColumns.FirstOrDefault(x => x.AttributeName == nameof(TestTableInfo.VarChar100)); + Assert.NotNull(varChar100Column); + Assert.Equal(DataType.VarChar, varChar100Column.DataType); + Assert.Equal(100, varChar100Column.DataLength); + + var varCharDefaultColumn = tableColumns.FirstOrDefault(x => x.AttributeName == nameof(TestTableInfo.VarCharDefault)); + Assert.NotNull(varCharDefaultColumn); + Assert.Equal(DataType.VarChar, varCharDefaultColumn.DataType); + Assert.Equal(2000, varCharDefaultColumn.DataLength); + + var contentColumn = tableColumns.FirstOrDefault(x => x.AttributeName == nameof(TestTableInfo.Content)); + Assert.NotNull(contentColumn); + Assert.Equal(DataType.Text, contentColumn.DataType); + + var isLockedOutColumn = tableColumns.FirstOrDefault(x => x.AttributeName == "IsLockedOut"); + Assert.NotNull(isLockedOutColumn); + + var lockedColumn = tableColumns.FirstOrDefault(x => x.AttributeName == nameof(TestTableInfo.Locked)); + Assert.Null(lockedColumn); + + var isExists = DatorySql.IsTableExists(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName); + if (isExists) + { + DatabaseApi.Instance.DropTable(_repository.TableName); + } + + var created = DatabaseApi.Instance.CreateTable(tableName, tableColumns, string.Empty, false, out _, out var sqlString); + _output.WriteLine(sqlString); + Assert.True(created); + } + + [SkippableFact, TestPriority(1)] + public void TestInsert() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var id = _repository.Insert(null); + Assert.Equal(0, id); + + var dataInfo = new TestTableInfo(); + _repository.Insert(dataInfo); + Assert.Equal(1, dataInfo.Id); + Assert.True(StringUtils.IsGuid(dataInfo.Guid)); + Assert.True(dataInfo.LastModifiedDate.HasValue); + Assert.Null(dataInfo.VarChar100); + Assert.Null(dataInfo.VarCharDefault); + Assert.Null(dataInfo.Content); + Assert.Equal(0, dataInfo.Num); + Assert.Equal(0, dataInfo.Currency); + Assert.False(dataInfo.Date.HasValue); + Assert.True(dataInfo.Date == null); + Assert.False(dataInfo.Locked); + + dataInfo = new TestTableInfo + { + Guid = "wrong guid", + VarChar100 = "string", + Num = -100, + Date = DateTime.Now, + Locked = true + }; + _repository.Insert(dataInfo); + Assert.Equal(2, dataInfo.Id); + Assert.True(StringUtils.IsGuid(dataInfo.Guid)); + Assert.True(dataInfo.LastModifiedDate.HasValue); + Assert.Equal("string", dataInfo.VarChar100); + Assert.Null(dataInfo.VarCharDefault); + Assert.Null(dataInfo.Content); + Assert.Equal(-100, dataInfo.Num); + Assert.Equal(0, dataInfo.Currency); + Assert.True(dataInfo.Date.HasValue); + Assert.True(dataInfo.Locked); + + _output.WriteLine(dataInfo.Guid); + _output.WriteLine(DateUtils.GetDateAndTimeString(dataInfo.LastModifiedDate)); + } + + [SkippableFact, TestPriority(2)] + public void TestGet() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var dataInfo = _repository.First(1); + Assert.NotNull(dataInfo); + Assert.Equal(1, dataInfo.Id); + Assert.True(StringUtils.IsGuid(dataInfo.Guid)); + Assert.True(dataInfo.LastModifiedDate.HasValue); + Assert.Null(dataInfo.VarChar100); + Assert.Null(dataInfo.VarCharDefault); + Assert.Null(dataInfo.Content); + Assert.Equal(0, dataInfo.Num); + Assert.Equal(0, dataInfo.Currency); + Assert.False(dataInfo.Date.HasValue); + Assert.True(dataInfo.Date == null); + + _output.WriteLine(dataInfo.Guid); + _output.WriteLine(DateUtils.GetDateAndTimeString(dataInfo.LastModifiedDate)); + + dataInfo = _repository.First(2); + Assert.NotNull(dataInfo); + Assert.Equal(2, dataInfo.Id); + Assert.True(StringUtils.IsGuid(dataInfo.Guid)); + Assert.True(dataInfo.LastModifiedDate.HasValue); + Assert.Equal("string", dataInfo.VarChar100); + Assert.Null(dataInfo.VarCharDefault); + Assert.Null(dataInfo.Content); + Assert.Equal(-100, dataInfo.Num); + Assert.Equal(0, dataInfo.Currency); + Assert.True(dataInfo.Date.HasValue); + } + + [SkippableFact, TestPriority(2)] + public void TestGetWithParameters() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var dataInfo = _repository.First(new Query().Where(Attr.VarChar100, "string")); + Assert.NotNull(dataInfo); + Assert.Equal(2, dataInfo.Id); + Assert.True(StringUtils.IsGuid(dataInfo.Guid)); + Assert.True(dataInfo.LastModifiedDate.HasValue); + Assert.Equal("string", dataInfo.VarChar100); + Assert.Null(dataInfo.VarCharDefault); + Assert.Null(dataInfo.Content); + Assert.Equal(-100, dataInfo.Num); + Assert.Equal(0, dataInfo.Currency); + Assert.True(dataInfo.Date.HasValue); + + dataInfo = _repository.First(dataInfo.Guid); + Assert.NotNull(dataInfo); + Assert.Equal(2, dataInfo.Id); + Assert.True(StringUtils.IsGuid(dataInfo.Guid)); + Assert.True(dataInfo.LastModifiedDate.HasValue); + Assert.Equal("string", dataInfo.VarChar100); + Assert.Null(dataInfo.VarCharDefault); + Assert.Null(dataInfo.Content); + Assert.Equal(-100, dataInfo.Num); + Assert.Equal(0, dataInfo.Currency); + Assert.True(dataInfo.Date.HasValue); + + dataInfo = _repository.First(dataInfo.Guid); + Assert.NotNull(dataInfo); + Assert.Equal(2, dataInfo.Id); + Assert.True(StringUtils.IsGuid(dataInfo.Guid)); + Assert.True(dataInfo.LastModifiedDate.HasValue); + Assert.Equal("string", dataInfo.VarChar100); + Assert.Null(dataInfo.VarCharDefault); + Assert.Null(dataInfo.Content); + Assert.Equal(-100, dataInfo.Num); + Assert.Equal(0, dataInfo.Currency); + Assert.True(dataInfo.Date.HasValue); + + dataInfo = _repository.First(new Query().Where(Attr.VarChar100, "not exists")); + Assert.Null(dataInfo); + + dataInfo = _repository.First(new Query()); + Assert.NotNull(dataInfo); + } + + [SkippableFact, TestPriority(2)] + public void TestExists() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var exists = _repository.Exists(new Query() + .Where(nameof(TestTableInfo.VarChar100), "string")); + Assert.True(exists); + + exists = _repository.Exists(new Query().Where(nameof(TestTableInfo.VarChar100), "not exists")); + Assert.False(exists); + + exists = _repository.Exists(new Query()); + Assert.True(exists); + } + + [SkippableFact, TestPriority(2)] + public void TestCount() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var count = _repository.Count(); + Assert.Equal(2, count); + + count = _repository.Count(new Query().Where("Id", 1)); + Assert.Equal(1, count); + } + + [SkippableFact, TestPriority(2)] + public void TestGetValue() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var guid = _repository.GetValue(new Query() + .Select(nameof(DynamicEntity.Guid)).Where("Id", 1)); + Assert.True(StringUtils.IsGuid(guid)); + + var date = _repository.GetValue(new Query() + .Select(nameof(TestTableInfo.Date)).Where("Guid", guid)); + Assert.False(date.HasValue); + + var lastModifiedDate = _repository.GetValue(new Query() + .Select(nameof(TestTableInfo.LastModifiedDate)) + .Where("Guid", guid)); + Assert.True(lastModifiedDate.HasValue); + _output.WriteLine(DateUtils.GetDateAndTimeString(lastModifiedDate.Value)); + } + + [SkippableFact, TestPriority(2)] + public void TestGetValues() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var guidList = _repository.GetValueList(new Query() + .Select(nameof(TestTableInfo.Guid)) + .Where("Id", 1)).ToList(); + + Assert.NotNull(guidList); + Assert.True(StringUtils.IsGuid(guidList.First())); + + var dateList = _repository.GetValueList(new Query() + .Select(nameof(TestTableInfo.Date)) + .Where("Guid", guidList.First())).ToList(); + Assert.False(dateList.First().HasValue); + + var lastModifiedDateList = _repository.GetValueList(new Query() + .Select(nameof(TestTableInfo.LastModifiedDate)) + .Where("Id", 1)).ToList(); + Assert.True(lastModifiedDateList.First().HasValue); + } + + [SkippableFact, TestPriority(2)] + public void TestGetAll() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var allList = _repository.GetAll().ToList(); + Assert.Equal(2, allList.Count); + + var list = _repository.GetAll(new Query() + .Where("Guid", allList[0].Guid)).ToList(); + + Assert.Single(list); + } + + [SkippableFact, TestPriority(3)] + public void TestUpdate() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var dataInfo = _repository.First(1); + Assert.True(dataInfo.LastModifiedDate.HasValue); + var lastModified = dataInfo.LastModifiedDate.Value.Ticks; + + dataInfo.Content = "new content"; + dataInfo.LastModifiedDate = DateTime.Now.AddDays(-1); + + var updated = _repository.UpdateObject(dataInfo); + Assert.True(updated); + + Assert.Equal(1, dataInfo.Id); + Assert.True(StringUtils.IsGuid(dataInfo.Guid)); + Assert.True(dataInfo.LastModifiedDate.HasValue); + Assert.Null(dataInfo.VarChar100); + Assert.Null(dataInfo.VarCharDefault); + Assert.Equal("new content", dataInfo.Content); + Assert.Equal(0, dataInfo.Num); + Assert.Equal(0, dataInfo.Currency); + Assert.False(dataInfo.Date.HasValue); + Assert.True(dataInfo.Date == null); + + var lastModified2 = dataInfo.LastModifiedDate.Value.Ticks; + _output.WriteLine(lastModified.ToString()); + _output.WriteLine(lastModified2.ToString()); + Assert.True(lastModified2 > lastModified); + + updated = _repository.UpdateObject(null); + Assert.False(updated); + } + + [SkippableFact, TestPriority(3)] + public void TestUpdateWithParameters() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var lastModified = _repository.GetValue(new Query() + .Select(nameof(DynamicEntity.LastModifiedDate)).Where("Id", 1)); + Assert.True(lastModified.HasValue); + + var updated = _repository.UpdateAll(new Query() + .Set("Content", "new content2") + .Set("LastModifiedDate", DateTime.Now.AddDays(-1)) + .Where(nameof(Attr.Id), 1)); + Assert.True(updated == 1); + + var dataInfo = _repository.First(1); + Assert.True(dataInfo.LastModifiedDate.HasValue); + var lastModified2 = dataInfo.LastModifiedDate.Value.Ticks; + + Assert.Equal(1, dataInfo.Id); + Assert.True(StringUtils.IsGuid(dataInfo.Guid)); + Assert.True(dataInfo.LastModifiedDate.HasValue); + Assert.Null(dataInfo.VarChar100); + Assert.Null(dataInfo.VarCharDefault); + Assert.Equal("new content2", dataInfo.Content); + Assert.Equal(0, dataInfo.Num); + Assert.Equal(0, dataInfo.Currency); + Assert.False(dataInfo.Date.HasValue); + Assert.True(dataInfo.Date == null); + + Assert.True(lastModified2 > lastModified.Value.Ticks); + + updated = _repository.UpdateAll(new Query()); + Assert.True(updated == 2); + } + + [SkippableFact, TestPriority(3)] + public void TestUpdateAll() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var lastModified = _repository.GetValue(new Query() + .Select(nameof(DynamicEntity.LastModifiedDate)) + .Where("Id", 1)); + Assert.True(lastModified.HasValue); + + var updatedCount = _repository.UpdateAll(new Query() + .Set("Content", "new content2") + .Set("LastModifiedDate", DateTime.Now.AddDays(-1)) + .Where("Id", 1)); + + Assert.True(updatedCount == 1); + + updatedCount = _repository.UpdateAll(new Query() + .Set("Content", "new content3") + .Where("Content", "new content2")); + + Assert.True(updatedCount == 1); + + var dataInfo = _repository.First(1); + Assert.True(dataInfo.LastModifiedDate.HasValue); + var lastModified2 = dataInfo.LastModifiedDate.Value.Ticks; + + Assert.True(lastModified2 > lastModified.Value.Ticks); + + updatedCount = _repository.UpdateAll(null); + Assert.True(updatedCount == 2); + } + + [SkippableFact, TestPriority(3)] + public void TestIncrementAll() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var dataInfo = _repository.First(1); + Assert.Equal(0, dataInfo.Num); + + var affected = _repository.IncrementAll(Attr.Num, new Query().Where(Attr.Id, 1)); + Assert.True(affected == 1); + + dataInfo = _repository.First(1); + Assert.Equal(1, dataInfo.Num); + + affected = _repository.DecrementAll(Attr.Num, new Query().Where(Attr.Id, 1)); + Assert.True(affected == 1); + + dataInfo = _repository.First(1); + Assert.Equal(0, dataInfo.Num); + } + + [SkippableFact, TestPriority(4)] + public void TestDelete() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var deleted = _repository.Delete(1); + Assert.True(deleted); + + deleted = _repository.Delete(3); + Assert.False(deleted); + } + + [SkippableFact, TestPriority(5)] + public void End() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + DatabaseApi.Instance.DropTable(_repository.TableName); + } + } +} diff --git a/net452/SiteServer.CMS.Tests/Database/Core/ReflectionUtilsTest.cs b/net452/SiteServer.CMS.Tests/Database/Core/ReflectionUtilsTest.cs new file mode 100644 index 000000000..e4d35ee1e --- /dev/null +++ b/net452/SiteServer.CMS.Tests/Database/Core/ReflectionUtilsTest.cs @@ -0,0 +1,50 @@ +using SiteServer.CMS.Database.Core; +using Xunit; + +namespace SiteServer.CMS.Tests.Database.Core +{ + public class ReflectionUtilsTest + { + public class MyClass + { + public string Foo { get; set; } + private string Bar { get; set; } + protected string Pro { get; set; } + internal string Inter { get; set; } + } + + [Fact] + public void TestGetAllInstancePropertyInfosEmpty() + { + var properties = ReflectionUtils.GetTypeProperties(typeof(int)); + Assert.Empty(properties); + } + + [Fact] + public void TestGetAllInstancePropertyInfosObject() + { + var properties = ReflectionUtils.GetTypeProperties(typeof(MyClass)); + Assert.Equal(4, properties.Count); + } + + [Fact] + public void TestToKeyValueListEmpty() + { + var kvs = ReflectionUtils.ToKeyValueList(null); + Assert.Empty(kvs); + } + + [Fact] + public void TestToKeyValueListObject() + { + var kvs = ReflectionUtils.ToKeyValueList(new + { + A = "a", + B = "b", + C = "c", + D = "d" + }); + Assert.Equal(4, kvs.Count); + } + } +} diff --git a/net452/SiteServer.CMS.Tests/Database/IntegrationTests.cs b/net452/SiteServer.CMS.Tests/Database/IntegrationTests.cs new file mode 100644 index 000000000..081801d2b --- /dev/null +++ b/net452/SiteServer.CMS.Tests/Database/IntegrationTests.cs @@ -0,0 +1,31 @@ +using System; +using SiteServer.CMS.Core; +using SiteServer.Utils; +using Xunit; +using Xunit.Abstractions; + +namespace SiteServer.CMS.Tests.Database +{ + [TestCaseOrderer("SiteServer.CMS.Tests.PriorityOrderer", "SiteServer.CMS.Tests")] + public class IntegrationTests : IClassFixture + { + private readonly EnvironmentFixture _fixture; + private readonly ITestOutputHelper _output; + + public IntegrationTests(EnvironmentFixture fixture, ITestOutputHelper output) + { + _fixture = fixture; + _output = output; + } + + [SkippableFact, TestPriority(0)] + public void TrueTest() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + SystemManager.SyncDatabase(); + + Assert.True(true); + } + } +} diff --git a/net452/SiteServer.CMS.Tests/Database/Mocks/Attr.cs b/net452/SiteServer.CMS.Tests/Database/Mocks/Attr.cs new file mode 100644 index 000000000..e4f53968a --- /dev/null +++ b/net452/SiteServer.CMS.Tests/Database/Mocks/Attr.cs @@ -0,0 +1,25 @@ +namespace SiteServer.CMS.Tests.Database.Mocks +{ + public class Attr + { + public const string Id = nameof(TestTableInfo.Id); + + public const string Guid = nameof(TestTableInfo.Guid); + + public const string LastModifiedDate = nameof(TestTableInfo.LastModifiedDate); + + public const string VarChar100 = nameof(TestTableInfo.VarChar100); + + public const string VarCharDefault = nameof(TestTableInfo.VarCharDefault); + + public const string Content = nameof(TestTableInfo.Content); + + public const string Num = nameof(TestTableInfo.Num); + + public const string Currency = nameof(TestTableInfo.Currency); + + public const string Date = nameof(TestTableInfo.Date); + + public const string IsLockedOut = "IsLockedOut"; + } +} diff --git a/net452/SiteServer.CMS.Tests/Database/Mocks/TestTableInfo.cs b/net452/SiteServer.CMS.Tests/Database/Mocks/TestTableInfo.cs new file mode 100644 index 000000000..32e9308af --- /dev/null +++ b/net452/SiteServer.CMS.Tests/Database/Mocks/TestTableInfo.cs @@ -0,0 +1,37 @@ +using System; +using Datory; +using SiteServer.Utils; + +namespace SiteServer.CMS.Tests.Database.Mocks +{ + [Table("TestTable")] + public class TestTableInfo : DynamicEntity + { + [TableColumn(Length = 100)] + public string VarChar100 { get; set; } + + [TableColumn(Length = 100)] + public string VarCharDefault { get; set; } + + [TableColumn(Text = true)] + public string Content { get; set; } + + [TableColumn] + public int Num { get; set; } + + [TableColumn] + public decimal Currency { get; set; } + + [TableColumn] + public DateTime? Date { get; set; } + + [TableColumn] + private string IsLockedOut { get; set; } + + public bool Locked + { + get => TranslateUtils.ToBool(IsLockedOut); + set => IsLockedOut = value.ToString(); + } + } +} diff --git a/net452/SiteServer.CMS.Tests/Database/Mocks/TestTableRepository.cs b/net452/SiteServer.CMS.Tests/Database/Mocks/TestTableRepository.cs new file mode 100644 index 000000000..51b799e98 --- /dev/null +++ b/net452/SiteServer.CMS.Tests/Database/Mocks/TestTableRepository.cs @@ -0,0 +1,119 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Database.Core; +using SiteServer.Utils; +using SqlKata; + +namespace SiteServer.CMS.Tests.Database.Mocks +{ + public class TestTableRepository : GenericRepository + { + public override DatabaseType DatabaseType => WebConfigUtils.DatabaseType; + public override string ConnectionString => WebConfigUtils.ConnectionString; + public override bool UseLegacyPagination => DatabaseApi.Instance.UseLegacyPagination; + + public new Query Q => base.Q; + + public int Insert(TestTableInfo dataInfo) + { + return InsertObject(dataInfo); + } + + public new bool Exists(int id) + { + return base.Exists(id); + } + + public new bool Exists(string guid) + { + return base.Exists(guid); + } + + public new bool Exists(Query query = null) + { + return base.Exists(query); + } + + public new int Count(Query query = null) + { + return base.Count(query); + } + + public new TValue GetValue(Query query) + { + return base.GetValue(query); + } + + public new int? Max(string columnName, Query query) + { + return base.Max(columnName, query); + } + + public new IList GetValueList(Query query = null) + { + return base.GetValueList(query); + } + + public TestTableInfo First(int id) + { + return GetObjectById(id); + } + + public TestTableInfo First(string guid) + { + return GetObjectByGuid(guid); + } + + + public TestTableInfo First(Query query = null) + { + return GetObject(query); + } + + + + public IList GetAll(Query query = null) + { + return GetObjectList(query); + } + + + public new bool UpdateObject(TestTableInfo dataInfo) + { + return base.UpdateObject(dataInfo); + } + + + public new int UpdateAll(Query query) + { + return base.UpdateAll(query); + } + + + public bool Delete(int id) + { + return DeleteById(id); + } + + public bool Delete(string guid) + { + return DeleteByGuid(guid); + } + + public new int DeleteAll(Query query = null) + { + return base.DeleteAll(query); + } + + public new int IncrementAll(string columnName, Query query, int num = 1) + { + return base.IncrementAll(columnName, query, num); + } + + public new int DecrementAll(string columnName, Query query, int num = 1) + { + return base.DecrementAll(columnName, query, num); + } + } +} diff --git a/net452/SiteServer.CMS.Tests/Database/Repositories/AccessTokenRepositoryTest.cs b/net452/SiteServer.CMS.Tests/Database/Repositories/AccessTokenRepositoryTest.cs new file mode 100644 index 000000000..9dac0debd --- /dev/null +++ b/net452/SiteServer.CMS.Tests/Database/Repositories/AccessTokenRepositoryTest.cs @@ -0,0 +1,89 @@ +using System.Linq; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; +using Xunit; + +namespace SiteServer.CMS.Tests.Database.Repositories +{ + [TestCaseOrderer("SiteServer.CMS.Tests.PriorityOrderer", "SiteServer.CMS.Tests")] + public class AccessTokenRepositoryTest: IClassFixture + { + public EnvironmentFixture Fixture { get; } + + public AccessTokenRepositoryTest(EnvironmentFixture fixture) + { + Fixture = fixture; + } + + [SkippableFact, TestPriority(0)] + public void BasicTest() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var accessTokenInfo = new AccessTokenInfo(); + + DataProvider.AccessToken.Insert(accessTokenInfo); + Assert.True(accessTokenInfo.Id > 0); + var token = accessTokenInfo.Token; + Assert.False(string.IsNullOrWhiteSpace(token)); + + accessTokenInfo = DataProvider.AccessToken.Get(accessTokenInfo.Id); + Assert.NotNull(accessTokenInfo); + + accessTokenInfo.Title = "title"; + var updated = DataProvider.AccessToken.Update(accessTokenInfo); + Assert.True(updated); + + DataProvider.AccessToken.Regenerate(accessTokenInfo); + Assert.NotEqual(token, accessTokenInfo.Token); + + var deleted = DataProvider.AccessToken.Delete(accessTokenInfo.Id); + Assert.True(deleted); + } + + [SkippableFact, TestPriority(0)] + public void IsTitleExists() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + const string testTitle = "IsTitleExists"; + + var exists = DataProvider.AccessToken.IsTitleExists(testTitle); + + Assert.False(exists); + + var accessTokenInfo = new AccessTokenInfo + { + Title = testTitle + }; + DataProvider.AccessToken.Insert(accessTokenInfo); + + exists = DataProvider.AccessToken.IsTitleExists(testTitle); + + Assert.True(exists); + + var deleted = DataProvider.AccessToken.Delete(accessTokenInfo.Id); + Assert.True(deleted); + } + + [SkippableFact, TestPriority(0)] + public void GetAccessTokenInfoList() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var accessTokenInfo = new AccessTokenInfo + { + Title = "title" + }; + DataProvider.AccessToken.Insert(accessTokenInfo); + + var list = DataProvider.AccessToken.GetAll(); + + Assert.True(list.Any()); + + var deleted = DataProvider.AccessToken.Delete(accessTokenInfo.Id); + Assert.True(deleted); + } + } +} diff --git a/net452/SiteServer.CMS.Tests/Database/Repositories/AdministratorRepositoryTest.cs b/net452/SiteServer.CMS.Tests/Database/Repositories/AdministratorRepositoryTest.cs new file mode 100644 index 000000000..9306d37ff --- /dev/null +++ b/net452/SiteServer.CMS.Tests/Database/Repositories/AdministratorRepositoryTest.cs @@ -0,0 +1,111 @@ +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; +using Xunit; +using Xunit.Abstractions; + +namespace SiteServer.CMS.Tests.Database.Repositories +{ + [TestCaseOrderer("SiteServer.CMS.Tests.PriorityOrderer", "SiteServer.CMS.Tests")] + public class AdministratorRepositoryTest : IClassFixture + { + public EnvironmentFixture Fixture { get; } + private readonly ITestOutputHelper _output; + + public AdministratorRepositoryTest(EnvironmentFixture fixture, ITestOutputHelper output) + { + Fixture = fixture; + _output = output; + } + + public const string TestUserName = "Tests_UserName"; + + [SkippableFact, TestPriority(0)] + public void TestInsert() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var adminInfo = new AdministratorInfo(); + + var id = DataProvider.Administrator.Insert(adminInfo, out _); + + Assert.True(id == 0); + + adminInfo = new AdministratorInfo + { + UserName = TestUserName, + Password = "InsertTest" + }; + + id = DataProvider.Administrator.Insert(adminInfo, out var errorMessage); + _output.WriteLine(errorMessage); + + Assert.True(id == 0); + + adminInfo = new AdministratorInfo + { + UserName = TestUserName, + Password = "InsertTest@2" + }; + + id = DataProvider.Administrator.Insert(adminInfo, out errorMessage); + _output.WriteLine(errorMessage); + + Assert.True(id > 0); + Assert.True(!string.IsNullOrWhiteSpace(adminInfo.Password)); + Assert.True(adminInfo.PasswordFormat == EPasswordFormatUtils.GetValue(EPasswordFormat.Encrypted)); + Assert.True(!string.IsNullOrWhiteSpace(adminInfo.PasswordSalt)); + } + + [SkippableFact, TestPriority(1)] + public void TestUpdate() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var adminInfo = DataProvider.Administrator.GetByUserName(TestUserName); + + var password = adminInfo.Password; + var passwordFormat = adminInfo.PasswordFormat; + var passwordSalt = adminInfo.PasswordSalt; + + adminInfo.Password = "cccc@d"; + + var updated = DataProvider.Administrator.Update(adminInfo, out _); + Assert.True(updated); + Assert.True(adminInfo.Password == password); + Assert.True(adminInfo.PasswordFormat == passwordFormat); + Assert.True(adminInfo.PasswordSalt == passwordSalt); + } + + [SkippableFact, TestPriority(1)] + public void TestUpdateLastActivityDateAndCountOfFailedLogin() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var adminInfo = DataProvider.Administrator.GetByUserName(TestUserName); + Assert.NotNull(adminInfo); + Assert.Equal(TestUserName, adminInfo.UserName); + + var countOfFailedLogin = adminInfo.CountOfFailedLogin; + + var updated = DataProvider.Administrator.UpdateLastActivityDateAndCountOfFailedLogin(adminInfo); + Assert.True(updated); + Assert.Equal(countOfFailedLogin, adminInfo.CountOfFailedLogin - 1); + } + + [SkippableFact, TestPriority(2)] + public void TestDelete() + { + Skip.IfNot(TestEnv.IntegrationTestMachine); + + var adminInfo = DataProvider.Administrator.GetByUserName(TestUserName); + Assert.NotNull(adminInfo); + Assert.Equal(TestUserName, adminInfo.UserName); + + var deleted = DataProvider.Administrator.Delete(adminInfo); + + Assert.True(deleted); + } + } +} diff --git a/net452/SiteServer.CMS.Tests/EnvironmentFixture.cs b/net452/SiteServer.CMS.Tests/EnvironmentFixture.cs new file mode 100644 index 000000000..fef7993dc --- /dev/null +++ b/net452/SiteServer.CMS.Tests/EnvironmentFixture.cs @@ -0,0 +1,28 @@ +using System; +using System.IO; +using System.Reflection; +using SiteServer.CMS.Fx; +using SiteServer.Utils; + +namespace SiteServer.CMS.Tests +{ + public class EnvironmentFixture : IDisposable + { + public string ApplicationPhysicalPath { get; } + + public EnvironmentFixture() + { + var codeBaseUrl = new Uri(Assembly.GetExecutingAssembly().CodeBase); + var codeBasePath = Uri.UnescapeDataString(codeBaseUrl.AbsolutePath); + var dirPath = Path.GetDirectoryName(codeBasePath); + ApplicationPhysicalPath = PathUtils.Combine(DirectoryUtils.GetParentPath(DirectoryUtils.GetParentPath(DirectoryUtils.GetParentPath(dirPath))), "SiteServer.Web"); + + WebConfigUtils.Load(ApplicationPhysicalPath, PathUtils.Combine(ApplicationPhysicalPath, WebConfigUtils.WebConfigFileName)); + } + + public void Dispose() + { + // ... clean up test data from the database ... + } + } +} diff --git a/net452/SiteServer.CMS.Tests/PriorityOrderer.cs b/net452/SiteServer.CMS.Tests/PriorityOrderer.cs new file mode 100644 index 000000000..0dd8cebdd --- /dev/null +++ b/net452/SiteServer.CMS.Tests/PriorityOrderer.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Xunit.Abstractions; +using Xunit.Sdk; + +namespace SiteServer.CMS.Tests +{ + public class PriorityOrderer : ITestCaseOrderer + { + public IEnumerable OrderTestCases(IEnumerable testCases) where TTestCase : ITestCase + { + var sortedMethods = new SortedDictionary>(); + + foreach (TTestCase testCase in testCases) + { + int priority = 0; + + foreach (IAttributeInfo attr in testCase.TestMethod.Method.GetCustomAttributes((typeof(TestPriorityAttribute).AssemblyQualifiedName))) + priority = attr.GetNamedArgument("Priority"); + + GetOrCreate(sortedMethods, priority).Add(testCase); + } + + foreach (var list in sortedMethods.Keys.Select(priority => sortedMethods[priority])) + { + list.Sort((x, y) => StringComparer.OrdinalIgnoreCase.Compare(x.TestMethod.Method.Name, y.TestMethod.Method.Name)); + foreach (TTestCase testCase in list) + yield return testCase; + } + } + + static TValue GetOrCreate(IDictionary dictionary, TKey key) where TValue : new() + { + TValue result; + + if (dictionary.TryGetValue(key, out result)) return result; + + result = new TValue(); + dictionary[key] = result; + + return result; + } + } +} diff --git a/net452/SiteServer.CMS.Tests/Properties/AssemblyInfo.cs b/net452/SiteServer.CMS.Tests/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..be72a1509 --- /dev/null +++ b/net452/SiteServer.CMS.Tests/Properties/AssemblyInfo.cs @@ -0,0 +1,19 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("SiteServer.CMS.Tests")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SiteServer.CMS.Tests")] +[assembly: AssemblyCopyright("Copyright © 2019")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +[assembly: ComVisible(false)] + +[assembly: Guid("9cd127c6-08e2-406d-9630-463da1431ea4")] + +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/net452/SiteServer.CMS.Tests/SiteServer.CMS.Tests.csproj b/net452/SiteServer.CMS.Tests/SiteServer.CMS.Tests.csproj new file mode 100644 index 000000000..35a48334d --- /dev/null +++ b/net452/SiteServer.CMS.Tests/SiteServer.CMS.Tests.csproj @@ -0,0 +1,185 @@ + + + + + + + + Debug + AnyCPU + {9CD127C6-08E2-406D-9630-463DA1431EA4} + Library + Properties + SiteServer.CMS.Tests + SiteServer.CMS.Tests + v4.6.1 + 512 + {3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} + 15.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + $(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages + False + UnitTest + + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\packages\Castle.Core.4.4.0\lib\net45\Castle.Core.dll + + + ..\..\packages\Dapper.1.60.6\lib\net451\Dapper.dll + + + ..\..\packages\Datory.0.1.7\lib\net452\Datory.dll + + + ..\..\packages\Google.Protobuf.3.5.1\lib\net45\Google.Protobuf.dll + + + + ..\..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll + + + ..\..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll + + + ..\..\packages\Moq.4.10.1\lib\net45\Moq.dll + + + ..\..\packages\MySql.Data.8.0.15\lib\net452\MySql.Data.dll + + + ..\..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll + + + ..\..\packages\Npgsql.4.0.5\lib\net451\Npgsql.dll + + + ..\..\packages\Oracle.ManagedDataAccess.18.6.0\lib\net40\Oracle.ManagedDataAccess.dll + + + ..\..\packages\SqlKata.1.1.7\lib\net45\QueryBuilder.dll + + + ..\..\packages\SiteServer.Plugin.2.2.14-beta\lib\net452\SiteServer.Plugin.dll + + + + ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll + + + + + + + + + + + + + + ..\..\packages\System.Memory.4.5.2\lib\netstandard2.0\System.Memory.dll + + + + ..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll + + + + ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll + + + ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll + + + + ..\..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll + + + ..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.7\lib\net45\System.Web.Http.dll + + + + + ..\..\packages\Validation.2.4.18\lib\net45\Validation.dll + + + ..\..\packages\xunit.abstractions.2.0.3\lib\net35\xunit.abstractions.dll + + + ..\..\packages\xunit.assert.2.4.1\lib\netstandard1.1\xunit.assert.dll + + + ..\..\packages\xunit.extensibility.core.2.4.1\lib\net452\xunit.core.dll + + + ..\..\packages\xunit.extensibility.execution.2.4.1\lib\net452\xunit.execution.desktop.dll + + + ..\..\packages\Xunit.SkippableFact.1.3.12\lib\net452\Xunit.SkippableFact.dll + + + + + + + + + + + + + + + + + + + + + {059e3927-37e1-4f6f-b525-fef40c54906b} + SiteServer.Utils + + + {944127c3-915d-4f02-a534-64ec668c46ec} + SiteServer.CMS + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.CMS.Tests/TestPriorityAttribute.cs b/net452/SiteServer.CMS.Tests/TestPriorityAttribute.cs new file mode 100644 index 000000000..4e411b074 --- /dev/null +++ b/net452/SiteServer.CMS.Tests/TestPriorityAttribute.cs @@ -0,0 +1,15 @@ +using System; + +namespace SiteServer.CMS.Tests +{ + [AttributeUsage(AttributeTargets.Method, AllowMultiple = false)] + public class TestPriorityAttribute : Attribute + { + public TestPriorityAttribute(int priority) + { + Priority = priority; + } + + public int Priority { get; private set; } + } +} diff --git a/net452/SiteServer.CMS.Tests/app.config b/net452/SiteServer.CMS.Tests/app.config new file mode 100644 index 000000000..bfc5db33a --- /dev/null +++ b/net452/SiteServer.CMS.Tests/app.config @@ -0,0 +1,49 @@ + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/net452/SiteServer.CMS.Tests/packages.config b/net452/SiteServer.CMS.Tests/packages.config new file mode 100644 index 000000000..b45c0cf28 --- /dev/null +++ b/net452/SiteServer.CMS.Tests/packages.config @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.CMS/Apis/AdminApi.cs b/net452/SiteServer.CMS/Apis/AdminApi.cs new file mode 100644 index 000000000..2b7fabbe1 --- /dev/null +++ b/net452/SiteServer.CMS/Apis/AdminApi.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Auth; + +namespace SiteServer.CMS.Apis +{ + public class AdminApi : IAdminApi + { + private AdminApi() { } + + private static AdminApi _instance; + public static AdminApi Instance => _instance ?? (_instance = new AdminApi()); + + public IAdministratorInfo GetAdminInfoByUserId(int userId) + { + return AdminManager.GetAdminInfoByUserId(userId); + } + + public IAdministratorInfo GetAdminInfoByUserName(string userName) + { + return AdminManager.GetAdminInfoByUserName(userName); + } + + public IAdministratorInfo GetAdminInfoByEmail(string email) + { + return AdminManager.GetAdminInfoByEmail(email); + } + + public IAdministratorInfo GetAdminInfoByMobile(string mobile) + { + return AdminManager.GetAdminInfoByMobile(mobile); + } + + public IAdministratorInfo GetAdminInfoByAccount(string account) + { + return AdminManager.GetAdminInfoByAccount(account); + } + + public List GetUserNameList() + { + return DataProvider.Administrator.GetUserNameList().ToList(); + } + + public IPermissions GetPermissions(string userName) + { + return new PermissionsImpl(AdminManager.GetAdminInfoByUserName(userName)); + } + + public bool IsUserNameExists(string userName) + { + return DataProvider.Administrator.IsUserNameExists(userName); + } + + public bool IsEmailExists(string email) + { + return DataProvider.Administrator.IsEmailExists(email); + } + + public bool IsMobileExists(string mobile) + { + return DataProvider.Administrator.IsMobileExists(mobile); + } + + public string GetAccessToken(int userId, string userName, TimeSpan expiresAt) + { + if (userId <= 0 || string.IsNullOrEmpty(userName)) return null; + + var userToken = new AccessTokenImpl + { + UserId = userId, + UserName = userName, + ExpiresAt = DateUtils.GetExpiresAt(expiresAt) + }; + + return JsonWebToken.Encode(userToken, WebConfigUtils.SecretKey, JwtHashAlgorithm.HS256); + } + + public IAccessToken ParseAccessToken(string accessToken) + { + if (string.IsNullOrEmpty(accessToken)) return new AccessTokenImpl(); + + try + { + var tokenObj = JsonWebToken.DecodeToObject(accessToken, WebConfigUtils.SecretKey); + + if (tokenObj?.ExpiresAt.AddDays(Constants.AccessTokenExpireDays) > DateTime.Now) + { + return tokenObj; + } + } + catch + { + // ignored + } + + return new AccessTokenImpl(); + } + } +} diff --git a/net452/SiteServer.CMS/Apis/ChannelApi.cs b/net452/SiteServer.CMS/Apis/ChannelApi.cs new file mode 100644 index 000000000..33aa67213 --- /dev/null +++ b/net452/SiteServer.CMS/Apis/ChannelApi.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Plugin; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Apis +{ + public class ChannelApi : IChannelApi + { + private ChannelApi() { } + + private static ChannelApi _instance; + public static ChannelApi Instance => _instance ?? (_instance = new ChannelApi()); + + public IChannelInfo GetChannelInfo(int siteId, int channelId) + { + return ChannelManager.GetChannelInfo(siteId, channelId); + } + + public int GetChannelId(int siteId, string channelIndex) + { + if (string.IsNullOrEmpty(channelIndex)) return 0; + + var channelInfoList = ChannelManager.GetChannelInfoList(siteId); + foreach (var channelInfo in channelInfoList) + { + if (channelInfo.IndexName == channelIndex) + { + return channelInfo.Id; + } + } + + return 0; + } + + public IChannelInfo NewInstance(int siteId) + { + return new ChannelInfo + { + ParentId = siteId, + SiteId = siteId, + AddDate = DateTime.Now + }; + } + + public int Insert(int siteId, IChannelInfo nodeInfo) + { + return DataProvider.Channel.Insert(nodeInfo as ChannelInfo); + } + + public List GetChannelIdList(int siteId) + { + return ChannelManager.GetChannelIdList(siteId); + } + + public List GetChannelIdList(int siteId, int parentId) + { + return ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(siteId, parentId == 0 ? siteId : parentId), EScopeType.Children, string.Empty, string.Empty, string.Empty); + } + + //public List GetChannelIdListByAdminName(int siteId, string adminName) + //{ + // var channelIdList = new List(); + // if (string.IsNullOrEmpty(adminName)) return channelIdList; + + // var permissionManager = PermissionManager.GetInstance(adminName); + + // if (permissionManager.IsConsoleAdministrator || permissionManager.IsSystemAdministrator)//如果是超级管理员或站点管理员 + // { + // channelIdList = ChannelManager.GetChannelIdList(siteId); + // } + // else + // { + // foreach (var channelId in permissionManager.ChannelPermissionChannelIdList) + // { + // var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + // var allChannelIdList = ChannelManager.GetChannelIdList(channelInfo, EScopeType.Descendant, string.Empty, string.Empty, string.Empty); + // allChannelIdList.InsertObject(0, channelId); + + // foreach (var ownChannelId in allChannelIdList) + // { + // var nodeInfo = ChannelManager.GetChannelInfo(siteId, ownChannelId); + // if (nodeInfo != null) + // { + // channelIdList.Add(nodeInfo.Id); + // } + // } + // } + // } + // return channelIdList; + //} + + public string GetChannelName(int siteId, int channelId) + { + return ChannelManager.GetChannelName(siteId, channelId); + } + + public void Update(int siteId, IChannelInfo channelInfo) + { + if (channelInfo == null) return; + DataProvider.Channel.Update((ChannelInfo)channelInfo); + } + + public void Delete(int siteId, int channelId) + { + DataProvider.Channel.Delete(siteId, channelId); + } + + public string GetChannelUrl(int siteId, int channelId) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + return PageUtility.GetChannelUrl(siteInfo, ChannelManager.GetChannelInfo(siteId, channelId), false); + } + } +} diff --git a/net452/SiteServer.CMS/Apis/ConfigApi.cs b/net452/SiteServer.CMS/Apis/ConfigApi.cs new file mode 100644 index 000000000..dffc09654 --- /dev/null +++ b/net452/SiteServer.CMS/Apis/ConfigApi.cs @@ -0,0 +1,106 @@ +using System; +using Newtonsoft.Json; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Apis +{ + public class ConfigApi : IConfigApi + { + private ConfigApi() { } + + private static ConfigApi _instance; + public static ConfigApi Instance => _instance ?? (_instance = new ConfigApi()); + + public bool SetConfig(string pluginId, int siteId, object config) + { + return SetConfig(pluginId, siteId, string.Empty, config); + } + + public bool SetConfig(string pluginId, int siteId, string name, object config) + { + if (name == null) name = string.Empty; + + try + { + if (config == null) + { + DataProvider.PluginConfig.Delete(pluginId, siteId, name); + } + else + { + var settings = new JsonSerializerSettings + { + NullValueHandling = NullValueHandling.Ignore + }; + var json = JsonConvert.SerializeObject(config, Formatting.Indented, settings); + if (DataProvider.PluginConfig.IsExists(pluginId, siteId, name)) + { + var configInfo = new PluginConfigInfo + { + PluginId = pluginId, + SiteId = siteId, + ConfigName = name, + ConfigValue = json + }; + DataProvider.PluginConfig.Update(configInfo); + } + else + { + var configInfo = new PluginConfigInfo + { + PluginId = pluginId, + SiteId = siteId, + ConfigName = name, + ConfigValue = json + }; + DataProvider.PluginConfig.Insert(configInfo); + } + } + } + catch (Exception ex) + { + LogUtils.AddErrorLog(pluginId, ex); + return false; + } + return true; + } + + public T GetConfig(string pluginId, int siteId, string name = "") + { + if (name == null) name = string.Empty; + + try + { + var value = DataProvider.PluginConfig.GetValue(pluginId, siteId, name); + if (!string.IsNullOrEmpty(value)) + { + return JsonConvert.DeserializeObject(value); + } + } + catch (Exception ex) + { + LogUtils.AddErrorLog(pluginId, ex); + } + return default(T); + } + + public bool RemoveConfig(string pluginId, int siteId, string name = "") + { + if (name == null) name = string.Empty; + + try + { + DataProvider.PluginConfig.Delete(pluginId, siteId, name); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(pluginId, ex); + return false; + } + return true; + } + } +} diff --git a/net452/SiteServer.CMS/Apis/ContentApi.cs b/net452/SiteServer.CMS/Apis/ContentApi.cs new file mode 100644 index 000000000..f2c10efba --- /dev/null +++ b/net452/SiteServer.CMS/Apis/ContentApi.cs @@ -0,0 +1,191 @@ +using System; +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Apis +{ + public class ContentApi : IContentApi + { + private ContentApi() { } + + private static ContentApi _instance; + public static ContentApi Instance => _instance ?? (_instance = new ContentApi()); + + public IContentInfo GetContentInfo(int siteId, int channelId, int contentId) + { + if (siteId <= 0 || channelId <= 0 || contentId <= 0) return null; + + var siteInfo = SiteManager.GetSiteInfo(siteId); + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + + return ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + } + + public List GetContentInfoList(int siteId, int channelId, string whereString, string orderString, int limit, int offset) + { + if (siteId <= 0 || channelId <= 0) return null; + + var siteInfo = SiteManager.GetSiteInfo(siteId); + var tableName = ChannelManager.GetTableName(siteInfo, channelId); + + var list = DataProvider.ContentRepository.GetContentInfoList(tableName, whereString, orderString, offset, limit); + var retVal = new List(); + foreach (var contentInfo in list) + { + retVal.Add(contentInfo); + } + return retVal; + } + + public int GetCount(int siteId, int channelId, string whereString) + { + if (siteId <= 0 || channelId <= 0) return 0; + + var siteInfo = SiteManager.GetSiteInfo(siteId); + var tableName = ChannelManager.GetTableName(siteInfo, channelId); + + return DataProvider.ContentRepository.GetCount(tableName, whereString); + } + + public string GetTableName(int siteId, int channelId) + { + if (siteId <= 0 || channelId <= 0) return string.Empty; + + var siteInfo = SiteManager.GetSiteInfo(siteId); + var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); + return ChannelManager.GetTableName(siteInfo, nodeInfo); + } + + public List GetTableColumns(int siteId, int channelId) + { + if (siteId <= 0 || channelId <= 0) return null; + + var siteInfo = SiteManager.GetSiteInfo(siteId); + var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); + var tableStyleInfoList = TableStyleManager.GetContentStyleInfoList(siteInfo, nodeInfo); + var tableColumnList = new List + { + new TableColumn + { + AttributeName = ContentAttribute.Title, + DataType = DataType.VarChar + } + }; + + foreach (var styleInfo in tableStyleInfoList) + { + tableColumnList.Add(new TableColumn + { + AttributeName = styleInfo.AttributeName, + DataType = DataType.VarChar + }); + } + + tableColumnList.Add(new TableColumn + { + AttributeName = ContentAttribute.IsTop, + DataType = DataType.VarChar + }); + tableColumnList.Add(new TableColumn + { + AttributeName = ContentAttribute.IsRecommend, + DataType = DataType.VarChar + }); + tableColumnList.Add(new TableColumn + { + AttributeName = ContentAttribute.IsHot, + DataType = DataType.VarChar + }); + tableColumnList.Add(new TableColumn + { + AttributeName = ContentAttribute.IsColor, + DataType = DataType.VarChar + }); + tableColumnList.Add(new TableColumn + { + AttributeName = ContentAttribute.AddDate, + DataType = DataType.DateTime + }); + + return tableColumnList; + } + + public string GetContentValue(int siteId, int channelId, int contentId, string attributeName) + { + if (siteId <= 0 || channelId <= 0 || contentId <= 0) return null; + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + + return channelInfo.ContentRepository.GetValue(contentId, attributeName); + } + + public IContentInfo NewInstance(int siteId, int channelId) + { + return new ContentInfo + { + SiteId = siteId, + ChannelId = channelId, + AddDate = DateTime.Now + }; + } + + //public void SetValuesToContentInfo(int siteId, int channelId, NameValueCollection form, IContentInfo contentInfo) + //{ + // var siteInfo = SiteManager.GetSiteInfo(siteId); + // var nodeInfo = NodeManager.GetChannelInfo(siteId, channelId); + // var tableName = NodeManager.GetTableName(siteInfo, nodeInfo); + // var tableStyle = NodeManager.GetTableStyle(siteInfo, nodeInfo); + // var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(siteId, channelId); + + // var extendImageUrl = ContentAttribute.GetExtendAttributeName(ContentAttribute.ImageUrl); + // if (form.AllKeys.Contains(StringUtils.LowerFirst(extendImageUrl))) + // { + // form[extendImageUrl] = form[StringUtils.LowerFirst(extendImageUrl)]; + // } + + // InputTypeParser.AddValuesToAttributes(tableStyle, tableName, siteInfo, relatedIdentities, form, contentInfo.ToNameValueCollection(), ContentAttribute.HiddenAttributes); + //} + + public int Insert(int siteId, int channelId, IContentInfo contentInfo) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + + return DataProvider.ContentRepository.Insert(tableName, siteInfo, channelInfo, (ContentInfo)contentInfo); + } + + public void Update(int siteId, int channelId, IContentInfo contentInfo) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + DataProvider.ContentRepository.Update(siteInfo, channelInfo, (ContentInfo)contentInfo); + } + + public void Delete(int siteId, int channelId, int contentId) + { + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + var contentIdList = new List { contentId }; + channelInfo.ContentRepository.UpdateTrashContents(siteId, channelId, contentIdList); + } + + public IList GetContentIdList(int siteId, int channelId) + { + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + return channelInfo.ContentRepository.GetContentIdListCheckedByChannelId(siteId, channelId); + } + + public string GetContentUrl(int siteId, int channelId, int contentId) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + return PageUtility.GetContentUrl(siteInfo, ChannelManager.GetChannelInfo(siteId, channelId), contentId, false); + } + } +} diff --git a/net452/SiteServer.CMS/Apis/ParseApi.cs b/net452/SiteServer.CMS/Apis/ParseApi.cs new file mode 100644 index 000000000..fc21f68e5 --- /dev/null +++ b/net452/SiteServer.CMS/Apis/ParseApi.cs @@ -0,0 +1,49 @@ +using System.Collections.Generic; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Parsers; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Apis +{ + public class ParseApi : IParseApi + { + private ParseApi() { } + + private static ParseApi _instance; + public static ParseApi Instance => _instance ?? (_instance = new ParseApi()); + + public Dictionary GetStlElements(string html, List stlElementNames) + { + return StlParserUtility.GetStlElements(html, stlElementNames); + } + + public string Parse(string html, IParseContext context) + { + return StlParserManager.ParseInnerContent(html, (ParseContextImpl)context); + } + + public string ParseAttributeValue(string attributeValue, IParseContext context) + { + var siteInfo = SiteManager.GetSiteInfo(context.SiteId); + var templateInfo = new TemplateInfo + { + Id = context.TemplateId, + Type = context.TemplateType + }; + var pageInfo = new PageInfo(context.ChannelId, context.ContentId, siteInfo, templateInfo, new Dictionary()); + var contextInfo = new ContextInfo(pageInfo); + return StlEntityParser.ReplaceStlEntitiesForAttributeValue(attributeValue, pageInfo, contextInfo); + } + + public string GetCurrentUrl(IParseContext context) + { + var siteInfo = SiteManager.GetSiteInfo(context.SiteId); + return StlParserUtility.GetStlCurrentUrl(siteInfo, context.ChannelId, context.ContentId, + (ContentInfo)context.ContentInfo, context.TemplateType, context.TemplateId, false); + } + } +} diff --git a/net452/SiteServer.CMS/Apis/PluginApi.cs b/net452/SiteServer.CMS/Apis/PluginApi.cs new file mode 100644 index 000000000..1f1ac0310 --- /dev/null +++ b/net452/SiteServer.CMS/Apis/PluginApi.cs @@ -0,0 +1,52 @@ +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Apis +{ + public class PluginApi : IPluginApi + { + private PluginApi() { } + + private static PluginApi _instance; + public static PluginApi Instance => _instance ?? (_instance = new PluginApi()); + + public string GetPluginUrl(string pluginId, string relatedUrl = "") + { + if (PageUtils.IsProtocolUrl(relatedUrl)) return relatedUrl; + + if (StringUtils.StartsWith(relatedUrl, "~/")) + { + return FxUtils.GetRootUrl(relatedUrl.Substring(1)); + } + + if (StringUtils.StartsWith(relatedUrl, "@/")) + { + return FxUtils.GetAdminUrl(relatedUrl.Substring(1)); + } + + return PageUtility.GetSiteFilesUrl(ApiManager.ApiUrl, PageUtils.Combine(DirectoryUtils.SiteFiles.Plugins, pluginId, relatedUrl)); + } + + public string GetPluginApiUrl(string pluginId) + { + return ApiManager.GetApiUrl($"plugins/{pluginId}"); + } + + public string GetPluginPath(string pluginId, string relatedPath = "") + { + var path = PathUtils.Combine(FxUtils.GetPluginPath(pluginId), relatedPath); + DirectoryUtils.CreateDirectoryIfNotExists(path); + return path; + } + + public T GetPlugin() where T : PluginBase + { + var pluginInfo = PluginManager.GetPluginInfo(); + return pluginInfo?.Plugin as T; + } + } +} diff --git a/net452/SiteServer.CMS/Apis/SiteApi.cs b/net452/SiteServer.CMS/Apis/SiteApi.cs new file mode 100644 index 000000000..83756e232 --- /dev/null +++ b/net452/SiteServer.CMS/Apis/SiteApi.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Apis +{ + public class SiteApi : ISiteApi + { + private SiteApi() { } + + private static SiteApi _instance; + public static SiteApi Instance => _instance ?? (_instance = new SiteApi()); + + public int GetSiteIdByFilePath(string path) + { + var siteInfo = PathUtility.GetSiteInfo(path); + return siteInfo?.Id ?? 0; + } + + public string GetSitePath(int siteId) + { + if (siteId <= 0) return null; + + var siteInfo = SiteManager.GetSiteInfo(siteId); + return siteInfo == null ? null : PathUtility.GetSitePath(siteInfo); + } + + public List GetSiteIdList() + { + return SiteManager.GetSiteIdList(); + } + + public ISiteInfo GetSiteInfo(int siteId) + { + return SiteManager.GetSiteInfo(siteId); + } + + //public List GetSiteIdListByAdminName(string adminName) + //{ + // var permissionManager = PermissionManager.GetInstance(adminName); + // return SiteManager.GetWritingSiteIdList(permissionManager); + //} + + public string GetSitePath(int siteId, string virtualPath) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + return PathUtility.MapPath(siteInfo, virtualPath); + } + + public string GetSiteUrl(int siteId) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + return PageUtility.GetSiteUrl(siteInfo, false); + } + + public string GetSiteUrl(int siteId, string virtualPath) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + return PageUtility.ParseNavigationUrl(siteInfo, virtualPath, false); + } + + public string GetSiteUrlByFilePath(string filePath) + { + var siteId = Instance.GetSiteIdByFilePath(filePath); + var siteInfo = SiteManager.GetSiteInfo(siteId); + return PageUtility.GetSiteUrlByPhysicalPath(siteInfo, filePath, false); + } + } +} diff --git a/net452/SiteServer.CMS/Apis/UserApi.cs b/net452/SiteServer.CMS/Apis/UserApi.cs new file mode 100644 index 000000000..9c06cd69e --- /dev/null +++ b/net452/SiteServer.CMS/Apis/UserApi.cs @@ -0,0 +1,139 @@ +using System; +using System.Collections.Generic; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Auth; + +namespace SiteServer.CMS.Apis +{ + public class UserApi : IUserApi + { + private UserApi() { } + + private static UserApi _instance; + public static UserApi Instance => _instance ?? (_instance = new UserApi()); + + public IUserInfo NewInstance() + { + return new UserInfo(); + } + + public IUserInfo GetUserInfoByUserId(int userId) + { + return UserManager.GetUserInfoByUserId(userId); + } + + public IUserInfo GetUserInfoByUserName(string userName) + { + return UserManager.GetUserInfoByUserName(userName); + } + + public IUserInfo GetUserInfoByEmail(string email) + { + return UserManager.GetUserInfoByEmail(email); + } + + public IUserInfo GetUserInfoByMobile(string mobile) + { + return UserManager.GetUserInfoByMobile(mobile); + } + + public IUserInfo GetUserInfoByAccount(string account) + { + return UserManager.GetUserInfoByAccount(account); + } + + public bool IsUserNameExists(string userName) + { + return DataProvider.User.IsUserNameExists(userName); + } + + public bool IsEmailExists(string email) + { + return DataProvider.User.IsEmailExists(email); + } + + public bool IsMobileExists(string mobile) + { + return DataProvider.User.IsMobileExists(mobile); + } + + public bool Insert(IUserInfo userInfo, string password, out string errorMessage) + { + var userId = DataProvider.User.Insert(userInfo as UserInfo, password, FxUtils.GetIpAddress(), out errorMessage); + return userId > 0; + } + + public bool Validate(string account, string password, out string userName, out string errorMessage) + { + var userInfo = DataProvider.User.Validate(account, password, false, out userName, out errorMessage); + return userInfo != null; + } + + public bool ChangePassword(string userName, string password, out string errorMessage) + { + return DataProvider.User.ChangePassword(userName, password, out errorMessage); + } + + public void Update(IUserInfo userInfo) + { + DataProvider.User.Update(userInfo as UserInfo); + } + + public bool IsPasswordCorrect(string password, out string errorMessage) + { + return DataProvider.User.IsPasswordCorrect(password, out errorMessage); + } + + public void AddLog(string userName, string action, string summary) + { + LogUtils.AddUserLog(userName, action, summary); + } + + public List GetLogs(string userName, int totalNum, string action = "") + { + return DataProvider.UserLog.List(userName, totalNum, action); + } + + public string GetAccessToken(int userId, string userName, TimeSpan expiresAt) + { + if (userId <= 0 || string.IsNullOrEmpty(userName)) return null; + + var userToken = new AccessTokenImpl + { + UserId = userId, + UserName = userName, + ExpiresAt = DateUtils.GetExpiresAt(expiresAt) + }; + + return JsonWebToken.Encode(userToken, WebConfigUtils.SecretKey, JwtHashAlgorithm.HS256); + } + + public IAccessToken ParseAccessToken(string accessToken) + { + if (string.IsNullOrEmpty(accessToken)) return new AccessTokenImpl(); + + try + { + var tokenObj = JsonWebToken.DecodeToObject(accessToken, WebConfigUtils.SecretKey); + + if (tokenObj?.ExpiresAt.AddDays(Constants.AccessTokenExpireDays) > DateTime.Now) + { + return tokenObj; + } + } + catch + { + // ignored + } + + return new AccessTokenImpl(); + } + } +} diff --git a/net452/SiteServer.CMS/Apis/UtilsApi.cs b/net452/SiteServer.CMS/Apis/UtilsApi.cs new file mode 100644 index 000000000..1bd7a9c39 --- /dev/null +++ b/net452/SiteServer.CMS/Apis/UtilsApi.cs @@ -0,0 +1,136 @@ +using System.Collections.Generic; +using System.Net.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes; +using SiteServer.CMS.Fx; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Apis +{ + public class UtilsApi : IUtilsApi + { + private UtilsApi() { } + + private static UtilsApi _instance; + public static UtilsApi Instance => _instance ?? (_instance = new UtilsApi()); + + public string Encrypt(string inputString) + { + return TranslateUtils.EncryptStringBySecretKey(inputString); + } + + public string Decrypt(string inputString) + { + return TranslateUtils.DecryptStringBySecretKey(inputString); + } + + public string FilterXss(string html) + { + return AttackUtils.FilterXss(html); + } + + public string FilterSql(string sql) + { + return AttackUtils.FilterSql(sql); + } + + public void MoveFiles(int sourceSiteId, int targetSiteId, List relatedUrls) + { + if (sourceSiteId == targetSiteId) return; + + var siteInfo = SiteManager.GetSiteInfo(sourceSiteId); + var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); + if (siteInfo == null || targetSiteInfo == null) return; + + foreach (var relatedUrl in relatedUrls) + { + if (!string.IsNullOrEmpty(relatedUrl) && !PageUtils.IsProtocolUrl(relatedUrl)) + { + FileUtility.MoveFile(siteInfo, targetSiteInfo, relatedUrl); + } + } + } + + public void AddWaterMark(int siteId, string filePath) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + FileUtility.AddWaterMark(siteInfo, filePath); + } + + public string GetUploadFilePath(int siteId, string fileName) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + var localDirectoryPath = PathUtility.GetUploadDirectoryPath(siteInfo, PathUtils.GetExtension(fileName)); + var localFileName = PathUtility.GetUploadFileName(siteInfo, fileName); + return PathUtils.Combine(localDirectoryPath, localFileName); + } + + public string GetUploadFileUrl(int siteId, string fileName) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + var localDirectoryPath = PathUtility.GetUploadDirectoryPath(siteInfo, PathUtils.GetExtension(fileName)); + var localFileName = PathUtility.GetUploadFileName(siteInfo, fileName); + var path = PathUtils.Combine(localDirectoryPath, localFileName); + return PageUtility.GetSiteUrlByPhysicalPath(siteInfo, path, false); + } + + public string GetTemporaryFilesPath(string relatedPath) + { + return PathUtils.GetTemporaryFilesPath(relatedPath); + } + + public string GetRootUrl(string relatedUrl = "") + { + return FxUtils.GetRootUrl(relatedUrl); + } + + public string GetAdminUrl(string relatedUrl = "") + { + return FxUtils.GetAdminUrl(relatedUrl); + } + + public string GetHomeUrl(string relatedUrl = "") + { + return FxUtils.GetHomeUrl(relatedUrl); + } + + public string GetApiUrl(string relatedUrl = "") + { + return ApiManager.GetApiUrl(relatedUrl); + } + + public void CreateZip(string zipFilePath, string directoryPath) + { + ZipUtils.CreateZip(zipFilePath, directoryPath); + } + + public void ExtractZip(string zipFilePath, string directoryPath) + { + ZipUtils.ExtractZip(zipFilePath, directoryPath); + } + + public string JsonSerialize(object obj) + { + return TranslateUtils.JsonSerialize(obj); + } + + public T JsonDeserialize(string json, T defaultValue = default(T)) + { + return TranslateUtils.JsonDeserialize(json, defaultValue); + } + + public IAuthenticatedRequest GetAuthenticatedRequest(HttpRequestMessage request) + { + if (request.Properties.ContainsKey("AuthenticatedRequest")) + { + return request.Properties["AuthenticatedRequest"] as IAuthenticatedRequest; + } + + var authenticatedRequest = new AuthenticatedRequest(request); + request.Properties["AuthenticatedRequest"] = authenticatedRequest; + return authenticatedRequest; + } + } +} diff --git a/net452/SiteServer.CMS/Caches/AccessTokenManager.cs b/net452/SiteServer.CMS/Caches/AccessTokenManager.cs new file mode 100644 index 000000000..3cf896acf --- /dev/null +++ b/net452/SiteServer.CMS/Caches/AccessTokenManager.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Caches +{ + public static class AccessTokenManager + { + private static class AccessTokenManagerCache + { + private static readonly object LockObject = new object(); + + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(AccessTokenManager)); + + public static void Clear() + { + DataCacheManager.Remove(CacheKey); + } + + public static Dictionary GetAccessTokenDictionary() + { + var retVal = DataCacheManager.Get>(CacheKey); + if (retVal != null) return retVal; + + lock (LockObject) + { + retVal = DataCacheManager.Get>(CacheKey); + if (retVal != null) return retVal; + + retVal = new Dictionary(); + foreach (var accessTokenInfo in DataProvider.AccessToken.GetAll()) + { + var token = TranslateUtils.DecryptStringBySecretKey(accessTokenInfo.Token); + if (!string.IsNullOrEmpty(token)) + { + retVal[token] = accessTokenInfo; + } + } + + DataCacheManager.Insert(CacheKey, retVal); + } + + return retVal; + } + } + + public const string ScopeContents = "Contents"; + public const string ScopeAdministrators = "Administrators"; + public const string ScopeUsers = "Users"; + public const string ScopeStl = "STL"; + + public static List ScopeList => new List + { + ScopeContents, + ScopeAdministrators, + ScopeUsers, + ScopeStl + }; + + public static void ClearCache() + { + AccessTokenManagerCache.Clear(); + } + + public static bool IsScope(string token, string scope) + { + if (string.IsNullOrEmpty(token)) return false; + + var tokenInfo = GetAccessTokenInfo(token); + return tokenInfo != null && + StringUtils.ContainsIgnoreCase(TranslateUtils.StringCollectionToStringList(tokenInfo.Scopes), scope); + } + + public static AccessTokenInfo GetAccessTokenInfo(string token) + { + AccessTokenInfo tokenInfo = null; + var dict = AccessTokenManagerCache.GetAccessTokenDictionary(); + + if (dict != null && dict.ContainsKey(token)) + { + tokenInfo = dict[token]; + } + return tokenInfo; + } + } +} diff --git a/net452/SiteServer.CMS/Caches/AdminManager.cs b/net452/SiteServer.CMS/Caches/AdminManager.cs new file mode 100644 index 000000000..6bf69a7a4 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/AdminManager.cs @@ -0,0 +1,415 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Caches +{ + public static class AdminManager + { + private static class AdminManagerCache + { + private static readonly object LockObject = new object(); + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(AdminManager)); + + public static void Clear() + { + DataCacheManager.Remove(CacheKey); + } + + public static void Update(AdministratorInfo adminInfo) + { + if (adminInfo == null) return; + + var dict = GetDict(); + + lock (LockObject) + { + dict[GetDictKeyByUserId(adminInfo.Id)] = adminInfo; + dict[GetDictKeyByUserName(adminInfo.UserName)] = adminInfo; + if (!string.IsNullOrEmpty(adminInfo.Mobile)) + { + dict[GetDictKeyByMobile(adminInfo.Mobile)] = adminInfo; + } + if (!string.IsNullOrEmpty(adminInfo.Email)) + { + dict[GetDictKeyByEmail(adminInfo.Email)] = adminInfo; + } + } + } + + public static void Remove(AdministratorInfo adminInfo) + { + if (adminInfo == null) return; + + var dict = GetDict(); + + lock (LockObject) + { + dict.Remove(GetDictKeyByUserId(adminInfo.Id)); + dict.Remove(GetDictKeyByUserName(adminInfo.UserName)); + if (!string.IsNullOrEmpty(adminInfo.Mobile)) + { + dict.Remove(GetDictKeyByMobile(adminInfo.Mobile)); + } + + if (!string.IsNullOrEmpty(adminInfo.Email)) + { + dict.Remove(GetDictKeyByEmail(adminInfo.Email)); + } + } + } + + private static string GetDictKeyByUserId(int userId) + { + return $"userId:{userId}"; + } + + private static string GetDictKeyByUserName(string userName) + { + return $"userName:{userName}"; + } + + private static string GetDictKeyByMobile(string mobile) + { + return $"mobile:{mobile}"; + } + + private static string GetDictKeyByEmail(string email) + { + return $"email:{email}"; + } + + public static AdministratorInfo GetCacheByUserId(int userId) + { + if (userId <= 0) return null; + + var dict = GetDict(); + + dict.TryGetValue(GetDictKeyByUserId(userId), out AdministratorInfo adminInfo); + if (adminInfo != null) return adminInfo; + + lock (LockObject) + { + dict.TryGetValue(GetDictKeyByUserId(userId), out adminInfo); + + if (adminInfo == null) + { + adminInfo = DataProvider.Administrator.GetByUserId(userId); + if (adminInfo != null) + { + dict[GetDictKeyByUserId(adminInfo.Id)] = adminInfo; + dict[GetDictKeyByUserName(adminInfo.UserName)] = adminInfo; + if (!string.IsNullOrEmpty(adminInfo.Mobile)) + { + dict[GetDictKeyByMobile(adminInfo.Mobile)] = adminInfo; + } + if (!string.IsNullOrEmpty(adminInfo.Email)) + { + dict[GetDictKeyByEmail(adminInfo.Email)] = adminInfo; + } + } + } + } + + return adminInfo; + } + + public static AdministratorInfo GetCacheByUserName(string userName) + { + if (string.IsNullOrEmpty(userName)) return null; + + var dict = GetDict(); + + dict.TryGetValue(GetDictKeyByUserName(userName), out AdministratorInfo adminInfo); + if (adminInfo != null) return adminInfo; + + lock (LockObject) + { + dict.TryGetValue(GetDictKeyByUserName(userName), out adminInfo); + + if (adminInfo == null) + { + adminInfo = DataProvider.Administrator.GetByUserName(userName); + if (adminInfo != null) + { + dict[GetDictKeyByUserId(adminInfo.Id)] = adminInfo; + dict[GetDictKeyByUserName(adminInfo.UserName)] = adminInfo; + if (!string.IsNullOrEmpty(adminInfo.Mobile)) + { + dict[GetDictKeyByMobile(adminInfo.Mobile)] = adminInfo; + } + if (!string.IsNullOrEmpty(adminInfo.Email)) + { + dict[GetDictKeyByEmail(adminInfo.Email)] = adminInfo; + } + } + } + } + + return adminInfo; + } + + public static AdministratorInfo GetCacheByMobile(string mobile) + { + if (string.IsNullOrEmpty(mobile)) return null; + + var dict = GetDict(); + + dict.TryGetValue(GetDictKeyByMobile(mobile), out AdministratorInfo adminInfo); + if (adminInfo != null) return adminInfo; + + lock (LockObject) + { + dict.TryGetValue(GetDictKeyByMobile(mobile), out adminInfo); + + if (adminInfo == null) + { + adminInfo = DataProvider.Administrator.GetByMobile(mobile); + if (adminInfo != null) + { + dict[GetDictKeyByUserId(adminInfo.Id)] = adminInfo; + dict[GetDictKeyByUserName(adminInfo.UserName)] = adminInfo; + if (!string.IsNullOrEmpty(adminInfo.Mobile)) + { + dict[GetDictKeyByMobile(adminInfo.Mobile)] = adminInfo; + } + if (!string.IsNullOrEmpty(adminInfo.Email)) + { + dict[GetDictKeyByEmail(adminInfo.Email)] = adminInfo; + } + } + } + } + + return adminInfo; + } + + public static AdministratorInfo GetCacheByEmail(string email) + { + if (string.IsNullOrEmpty(email)) return null; + + var dict = GetDict(); + + dict.TryGetValue(GetDictKeyByEmail(email), out AdministratorInfo adminInfo); + if (adminInfo != null) return adminInfo; + + lock (LockObject) + { + dict.TryGetValue(GetDictKeyByEmail(email), out adminInfo); + + if (adminInfo == null) + { + adminInfo = DataProvider.Administrator.GetByEmail(email); + if (adminInfo != null) + { + dict[GetDictKeyByUserId(adminInfo.Id)] = adminInfo; + dict[GetDictKeyByUserName(adminInfo.UserName)] = adminInfo; + if (!string.IsNullOrEmpty(adminInfo.Mobile)) + { + dict[GetDictKeyByMobile(adminInfo.Mobile)] = adminInfo; + } + if (!string.IsNullOrEmpty(adminInfo.Email)) + { + dict[GetDictKeyByEmail(adminInfo.Email)] = adminInfo; + } + } + } + } + + return adminInfo; + } + + private static Dictionary GetDict() + { + var dict = DataCacheManager.Get>(CacheKey); + if (dict != null) return dict; + + lock (LockObject) + { + dict = DataCacheManager.Get>(CacheKey); + if (dict == null) + { + dict = new Dictionary(); + DataCacheManager.Insert(CacheKey, dict); + } + } + + return dict; + } + } + + public static void ClearCache() + { + AdminManagerCache.Clear(); + } + + public static void UpdateCache(AdministratorInfo adminInfo) + { + AdminManagerCache.Update(adminInfo); + } + + public static void RemoveCache(AdministratorInfo adminInfo) + { + AdminManagerCache.Remove(adminInfo); + } + + public static AdministratorInfo GetAdminInfoByUserId(int userId) + { + return AdminManagerCache.GetCacheByUserId(userId); + } + + public static AdministratorInfo GetAdminInfoByUserName(string userName) + { + return AdminManagerCache.GetCacheByUserName(userName); + } + + public static AdministratorInfo GetAdminInfoByMobile(string mobile) + { + return AdminManagerCache.GetCacheByMobile(mobile); + } + + public static AdministratorInfo GetAdminInfoByEmail(string email) + { + return AdminManagerCache.GetCacheByEmail(email); + } + + public static AdministratorInfo GetAdminInfoByAccount(string account) + { + if (string.IsNullOrEmpty(account)) return null; + + if (StringUtils.IsMobile(account)) + { + return GetAdminInfoByMobile(account); + } + if (StringUtils.IsEmail(account)) + { + return GetAdminInfoByEmail(account); + } + + return GetAdminInfoByUserName(account); + } + + public static List GetLatestTop10SiteIdList(List siteIdListLatestAccessed, List siteIdListWithPermissions) + { + var siteIdList = new List(); + + foreach (var siteId in siteIdListLatestAccessed) + { + if (siteIdList.Count >= 10) break; + if (!siteIdList.Contains(siteId) && siteIdListWithPermissions.Contains(siteId)) + { + siteIdList.Add(siteId); + } + } + + if (siteIdList.Count < 10) + { + var siteIdListOrderByLevel = SiteManager.GetSiteIdListOrderByLevel(); + foreach (var siteId in siteIdListOrderByLevel) + { + if (siteIdList.Count >= 5) break; + if (!siteIdList.Contains(siteId) && siteIdListWithPermissions.Contains(siteId)) + { + siteIdList.Add(siteId); + } + } + } + + return siteIdList; + } + + public static string GetDisplayName(string userName, bool isDepartment) + { + var adminInfo = GetAdminInfoByUserName(userName); + if (adminInfo == null) return userName; + + if (!isDepartment) return adminInfo.DisplayName; + var departmentName = DepartmentManager.GetDepartmentName(adminInfo.DepartmentId); + return !string.IsNullOrEmpty(departmentName) ? $"{adminInfo.DisplayName}({departmentName})" : adminInfo.DisplayName; + } + + public static string GetRoleNames(string userName) + { + var isConsoleAdministrator = false; + var isSystemAdministrator = false; + var roleNameList = new List(); + var roles = DataProvider.AdministratorsInRoles.GetRolesForUser(userName); + foreach (var role in roles) + { + if (!EPredefinedRoleUtils.IsPredefinedRole(role)) + { + roleNameList.Add(role); + } + else + { + if (EPredefinedRoleUtils.Equals(EPredefinedRole.ConsoleAdministrator, role)) + { + isConsoleAdministrator = true; + break; + } + if (EPredefinedRoleUtils.Equals(EPredefinedRole.SystemAdministrator, role)) + { + isSystemAdministrator = true; + break; + } + } + } + + var roleNames = string.Empty; + + if (isConsoleAdministrator) + { + roleNames += EPredefinedRoleUtils.GetText(EPredefinedRole.ConsoleAdministrator); + } + else if (isSystemAdministrator) + { + roleNames += EPredefinedRoleUtils.GetText(EPredefinedRole.SystemAdministrator); + } + else + { + roleNames += TranslateUtils.ObjectCollectionToString(roleNameList); + } + return roleNames; + } + + public static bool IsSuperAdmin(string userName) + { + var roles = DataProvider.AdministratorsInRoles.GetRolesForUser(userName); + return roles.Any(role => EPredefinedRoleUtils.Equals(EPredefinedRole.ConsoleAdministrator, role)); + } + + public static string GetUploadPath(params string[] paths) + { + var path = FxUtils.GetSiteFilesPath(DirectoryUtils.SiteFiles.Administrators, PathUtils.Combine(paths)); + DirectoryUtils.CreateDirectoryIfNotExists(path); + return path; + } + + public static string GetUserUploadPath(int userId, string relatedPath) + { + return GetUploadPath(userId.ToString(), relatedPath); + } + + public static string GetUserUploadFileName(string filePath) + { + var dt = DateTime.Now; + return $"{dt.Day}{dt.Hour}{dt.Minute}{dt.Second}{dt.Millisecond}{PathUtils.GetExtension(filePath)}"; + } + + public static string GetUploadUrl(params string[] paths) + { + return FxUtils.GetSiteFilesUrl(PageUtils.Combine(DirectoryUtils.SiteFiles.Administrators, PageUtils.Combine(paths))); + } + + public static string GetUserUploadUrl(int userId, string relatedUrl) + { + return GetUploadUrl(userId.ToString(), relatedUrl); + } + } +} diff --git a/net452/SiteServer.CMS/Caches/AreaManager.cs b/net452/SiteServer.CMS/Caches/AreaManager.cs new file mode 100644 index 000000000..1944ab436 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/AreaManager.cs @@ -0,0 +1,153 @@ +using System.Collections.Generic; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Caches +{ + public static class AreaManager + { + private static readonly object LockObject = new object(); + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(AreaManager)); + + public static List> GetRestAreas() + { + var list = new List>(); + + var areaIdList = GetAreaIdList(); + var parentsCountDict = new Dictionary(); + foreach (var areaId in areaIdList) + { + var areaInfo = GetAreaInfo(areaId); + list.Add(new KeyValuePair(areaId, GetTreeItem(areaInfo.AreaName, areaInfo.ParentsCount, areaInfo.LastNode, parentsCountDict))); + } + + return list; + } + + public static string GetTreeItem(string name, int parentsCount, bool isLastNode, Dictionary parentsCountDict) + { + var str = ""; + if (isLastNode == false) + { + parentsCountDict[parentsCount] = false; + } + else + { + parentsCountDict[parentsCount] = true; + } + for (var i = 0; i < parentsCount; i++) + { + str = string.Concat(str, TranslateUtils.DictGetValue(parentsCountDict, i) ? "" : ""); + } + str = string.Concat(str, isLastNode ? "" : ""); + str = string.Concat(str, name); + return str; + } + + public static AreaInfo GetAreaInfo(int areaId) + { + var pairList = GetAreaInfoPairList(); + + foreach (var pair in pairList) + { + var theAreaId = pair.Key; + if (theAreaId == areaId) + { + var areaInfo = pair.Value; + return areaInfo; + } + } + return null; + } + + public static string GetThisAreaName(int areaId) + { + var areaInfo = GetAreaInfo(areaId); + if (areaInfo != null) + { + return areaInfo.AreaName; + } + return string.Empty; + } + + public static string GetAreaName(int areaId) + { + if (areaId <= 0) return string.Empty; + + var areaNameList = new List(); + + var parentsPath = GetParentsPath(areaId); + var areaIdList = new List(); + if (!string.IsNullOrEmpty(parentsPath)) + { + areaIdList = TranslateUtils.StringCollectionToIntList(parentsPath); + } + areaIdList.Add(areaId); + + foreach (var theAreaId in areaIdList) + { + var areaInfo = GetAreaInfo(theAreaId); + if (areaInfo != null) + { + areaNameList.Add(areaInfo.AreaName); + } + } + + return TranslateUtils.ObjectCollectionToString(areaNameList, " > "); + } + + public static string GetParentsPath(int areaId) + { + var retval = string.Empty; + var areaInfo = GetAreaInfo(areaId); + if (areaInfo != null) + { + retval = areaInfo.ParentsPath; + } + return retval; + } + + public static List GetAreaIdList() + { + var pairList = GetAreaInfoPairList(); + var list = new List(); + foreach (var pair in pairList) + { + list.Add(pair.Key); + } + return list; + } + + public static void ClearCache() + { + lock (LockObject) + { + DataCacheManager.Remove(CacheKey); + } + } + + public static List> GetAreaInfoPairList() + { + lock (LockObject) + { + var list = DataCacheManager.Get>>(CacheKey); + if (list != null) return list; + + var pairListFormDb = DataProvider.Area.GetAreaInfoPairList(); + list = new List>(); + foreach (var pair in pairListFormDb) + { + var areaInfo = pair.Value; + if (areaInfo != null) + { + list.Add(pair); + } + } + DataCacheManager.Insert(CacheKey, list); + return list; + } + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Caches/ChannelGroupManager.cs b/net452/SiteServer.CMS/Caches/ChannelGroupManager.cs new file mode 100644 index 000000000..48cf4751a --- /dev/null +++ b/net452/SiteServer.CMS/Caches/ChannelGroupManager.cs @@ -0,0 +1,77 @@ +using System.Collections.Generic; +using System.Linq; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.CMS.Caches +{ + public static class ChannelGroupManager + { + private static class ChannelGroupManagerCache + { + private static readonly object LockObject = new object(); + + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(ChannelGroupManager)); + + public static void Clear() + { + DataCacheManager.Remove(CacheKey); + } + + public static Dictionary> GetAllChannelGroups() + { + var retval = DataCacheManager.Get>>(CacheKey); + if (retval != null) return retval; + + lock (LockObject) + { + retval = DataCacheManager.Get>>(CacheKey); + if (retval == null) + { + retval = DataProvider.ChannelGroup.GetAllChannelGroups(); + + DataCacheManager.Insert(CacheKey, retval); + } + } + + return retval; + } + } + + public static void ClearCache() + { + ChannelGroupManagerCache.Clear(); + } + + public static bool IsExists(int siteId, string groupName) + { + var list = GetChannelGroupInfoList(siteId); + return list.Any(group => group.GroupName == groupName); + } + + public static ChannelGroupInfo GetChannelGroupInfo(int siteId, string groupName) + { + var list = GetChannelGroupInfoList(siteId); + return list.FirstOrDefault(group => group.GroupName == groupName); + } + + public static List GetGroupNameList(int siteId) + { + var list = GetChannelGroupInfoList(siteId); + return list.Select(group => group.GroupName).ToList(); + } + + public static List GetChannelGroupInfoList(int siteId) + { + List list = null; + var dict = ChannelGroupManagerCache.GetAllChannelGroups(); + + if (dict != null && dict.ContainsKey(siteId)) + { + list = dict[siteId]; + } + return list ?? new List(); + } + } +} diff --git a/net452/SiteServer.CMS/Caches/ChannelManager.cs b/net452/SiteServer.CMS/Caches/ChannelManager.cs new file mode 100644 index 000000000..70a5b0ec7 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/ChannelManager.cs @@ -0,0 +1,649 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Caches.Stl; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Caches +{ + public static class ChannelManager + { + private static class ChannelManagerCache + { + private static readonly object LockObject = new object(); + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(ChannelManager)); + + private static void Update(Dictionary> allDict, Dictionary dic, int siteId) + { + lock (LockObject) + { + allDict[siteId] = dic; + } + } + + private static Dictionary> GetAllDictionary() + { + var allDict = DataCacheManager.Get>>(CacheKey); + if (allDict != null) return allDict; + + allDict = new Dictionary>(); + DataCacheManager.Insert(CacheKey, allDict); + return allDict; + } + + public static void Remove(int siteId) + { + var allDict = GetAllDictionary(); + + lock (LockObject) + { + allDict.Remove(siteId); + } + } + + public static void Update(int siteId, ChannelInfo channelInfo) + { + var dict = GetChannelInfoDictionaryBySiteId(siteId); + + lock (LockObject) + { + dict[channelInfo.Id] = channelInfo; + } + } + + public static Dictionary GetChannelInfoDictionaryBySiteId(int siteId) + { + var allDict = GetAllDictionary(); + + allDict.TryGetValue(siteId, out var dict); + + if (dict != null) return dict; + + dict = DataProvider.Channel.GetChannelInfoDictionaryBySiteId(siteId); + Update(allDict, dict, siteId); + return dict; + } + } + + public static void RemoveCacheBySiteId(int siteId) + { + ChannelManagerCache.Remove(siteId); + StlChannelCache.ClearCache(); + } + + public static void UpdateCache(int siteId, ChannelInfo channelInfo) + { + ChannelManagerCache.Update(siteId, channelInfo); + StlChannelCache.ClearCache(); + } + + public static ChannelInfo GetChannelInfo(int siteId, int channelId) + { + ChannelInfo channelInfo = null; + var dict = ChannelManagerCache.GetChannelInfoDictionaryBySiteId(siteId); + dict?.TryGetValue(Math.Abs(channelId), out channelInfo); + return channelInfo; + } + + public static int GetChannelId(int siteId, int channelId, string channelIndex, string channelName) + { + var retVal = channelId; + + if (!string.IsNullOrEmpty(channelIndex)) + { + var theChannelId = GetChannelIdByIndexName(siteId, channelIndex); + if (theChannelId != 0) + { + retVal = theChannelId; + } + } + if (!string.IsNullOrEmpty(channelName)) + { + var theChannelId = GetChannelIdByParentIdAndChannelName(siteId, retVal, channelName, true); + if (theChannelId == 0) + { + theChannelId = GetChannelIdByParentIdAndChannelName(siteId, siteId, channelName, true); + } + if (theChannelId != 0) + { + retVal = theChannelId; + } + } + + return retVal; + } + + public static int GetChannelIdByIndexName(int siteId, string indexName) + { + if (string.IsNullOrEmpty(indexName)) return 0; + + var dict = ChannelManagerCache.GetChannelInfoDictionaryBySiteId(siteId); + var channelInfo = dict.Values.FirstOrDefault(x => x != null && x.IndexName == indexName); + return channelInfo?.Id ?? 0; + } + + public static int GetChannelIdByParentIdAndChannelName(int siteId, int parentId, string channelName, bool recursive) + { + if (parentId <= 0 || string.IsNullOrEmpty(channelName)) return 0; + + var dict = ChannelManagerCache.GetChannelInfoDictionaryBySiteId(siteId); + var channelInfoList = dict.Values.OrderBy(x => x.Taxis).ToList(); + + ChannelInfo channelInfo; + + if (recursive) + { + channelInfo = siteId == parentId + ? channelInfoList.FirstOrDefault(x => x.ChannelName == channelName) + : channelInfoList.FirstOrDefault(x => + (x.ParentId == parentId || + TranslateUtils.StringCollectionToIntList(x.ParentsPath).Contains(parentId)) && + x.ChannelName == channelName); + } + else + { + channelInfo = channelInfoList.FirstOrDefault(x => x.ParentId == parentId && x.ChannelName == channelName); + + //sqlString = $"SELECT Id FROM siteserver_Channel WHERE (ParentId = {parentId} AND ChannelName = '{AttackUtils.FilterSql(channelName)}') ORDER BY Taxis"; + } + + return channelInfo?.Id ?? 0; + } + + //public static List GetIndexNameList(int siteId) + //{ + // var dic = ChannelManagerCache.GetChannelInfoDictionaryBySiteId(siteId); + // return dic.Values.Where(x => !string.IsNullOrEmpty(x?.IndexName)).Select(x => x.IndexName).Distinct().ToList(); + //} + + public static List GetChannelInfoList(int siteId) + { + var dic = ChannelManagerCache.GetChannelInfoDictionaryBySiteId(siteId); + return dic.Values.Where(channelInfo => channelInfo != null).ToList(); + } + + public static List GetChannelIdList(int siteId) + { + var dic = ChannelManagerCache.GetChannelInfoDictionaryBySiteId(siteId); + return dic.Values.OrderBy(c => c.Taxis).Select(channelInfo => channelInfo.Id).ToList(); + } + + public static List GetChannelIdList(int siteId, string channelGroup) + { + var channelInfoList = new List(); + var dic = ChannelManagerCache.GetChannelInfoDictionaryBySiteId(siteId); + foreach (var channelInfo in dic.Values) + { + if (string.IsNullOrEmpty(channelInfo.GroupNameCollection)) continue; + + if (StringUtils.Contains(channelInfo.GroupNameCollection, channelGroup)) + { + channelInfoList.Add(channelInfo); + } + } + return channelInfoList.OrderBy(c => c.Taxis).Select(channelInfo => channelInfo.Id).ToList(); + } + + public static List GetChannelIdList(ChannelInfo channelInfo, EScopeType scopeType) + { + return GetChannelIdList(channelInfo, scopeType, string.Empty, string.Empty, string.Empty); + } + + public static List GetChannelIdList(ChannelInfo channelInfo, EScopeType scopeType, string group, string groupNot, string contentModelPluginId) + { + if (channelInfo == null) return new List(); + + var dic = ChannelManagerCache.GetChannelInfoDictionaryBySiteId(channelInfo.SiteId); + var channelInfoList = new List(); + + if (channelInfo.ChildrenCount == 0) + { + if (scopeType != EScopeType.Children && scopeType != EScopeType.Descendant) + { + channelInfoList.Add(channelInfo); + } + } + else if (scopeType == EScopeType.Self) + { + channelInfoList.Add(channelInfo); + } + else if (scopeType == EScopeType.All) + { + foreach (var nodeInfo in dic.Values) + { + if (nodeInfo.Id == channelInfo.Id || nodeInfo.ParentId == channelInfo.Id || StringUtils.In(nodeInfo.ParentsPath, channelInfo.Id)) + { + channelInfoList.Add(nodeInfo); + } + } + } + else if (scopeType == EScopeType.Children) + { + foreach (var nodeInfo in dic.Values) + { + if (nodeInfo.ParentId == channelInfo.Id) + { + channelInfoList.Add(nodeInfo); + } + } + } + else if (scopeType == EScopeType.Descendant) + { + foreach (var nodeInfo in dic.Values) + { + if (nodeInfo.ParentId == channelInfo.Id || StringUtils.In(nodeInfo.ParentsPath, channelInfo.Id)) + { + channelInfoList.Add(nodeInfo); + } + } + } + else if (scopeType == EScopeType.SelfAndChildren) + { + foreach (var nodeInfo in dic.Values) + { + if (nodeInfo.Id == channelInfo.Id || nodeInfo.ParentId == channelInfo.Id) + { + channelInfoList.Add(nodeInfo); + } + } + } + + var filteredChannelInfoList = new List(); + foreach (var nodeInfo in channelInfoList) + { + if (!string.IsNullOrEmpty(group)) + { + if (!StringUtils.In(nodeInfo.GroupNameCollection, group)) + { + continue; + } + } + if (!string.IsNullOrEmpty(groupNot)) + { + if (StringUtils.In(nodeInfo.GroupNameCollection, groupNot)) + { + continue; + } + } + if (!string.IsNullOrEmpty(contentModelPluginId)) + { + if (!StringUtils.EqualsIgnoreCase(nodeInfo.ContentModelPluginId, contentModelPluginId)) + { + continue; + } + } + filteredChannelInfoList.Add(nodeInfo); + } + + return filteredChannelInfoList.OrderBy(c => c.Taxis).Select(channelInfoInList => channelInfoInList.Id).ToList(); + } + + public static bool IsExists(int siteId, int channelId) + { + var nodeInfo = GetChannelInfo(siteId, channelId); + return nodeInfo != null; + } + + public static bool IsExists(int channelId) + { + var list = SiteManager.GetSiteIdList(); + foreach (var siteId in list) + { + var nodeInfo = GetChannelInfo(siteId, channelId); + if (nodeInfo != null) return true; + } + + return false; + } + + public static string GetTableName(SiteInfo siteInfo, int channelId) + { + return GetTableName(siteInfo, GetChannelInfo(siteInfo.Id, channelId)); + } + + public static string GetTableName(SiteInfo siteInfo, ChannelInfo channelInfo) + { + return channelInfo != null ? GetTableName(siteInfo, channelInfo.ContentModelPluginId) : string.Empty; + } + + private static string GetTableName(SiteInfo siteInfo, string pluginId) + { + var tableName = siteInfo.TableName; + + if (string.IsNullOrEmpty(pluginId)) return tableName; + + var contentTable = PluginContentTableManager.GetTableName(pluginId); + if (!string.IsNullOrEmpty(contentTable)) + { + tableName = contentTable; + } + + return tableName; + } + + //public static ETableStyle GetTableStyle(SiteInfo siteInfo, int channelId) + //{ + // return GetTableStyle(siteInfo, GetChannelInfo(siteInfo.Id, channelId)); + //} + + //public static ETableStyle GetTableStyle(SiteInfo siteInfo, NodeInfo nodeInfo) + //{ + // var tableStyle = ETableStyle.BackgroundContent; + + // if (string.IsNullOrEmpty(nodeInfo.ContentModelPluginId)) return tableStyle; + + // var contentTable = PluginCache.GetEnabledPluginMetadata(nodeInfo.ContentModelPluginId); + // if (contentTable != null) + // { + // tableStyle = ETableStyle.Custom; + // } + + // return tableStyle; + //} + + public static bool IsContentModelPlugin(ChannelInfo nodeInfo) + { + if (string.IsNullOrEmpty(nodeInfo.ContentModelPluginId)) return false; + + var contentTable = PluginContentTableManager.GetTableName(nodeInfo.ContentModelPluginId); + return !string.IsNullOrEmpty(contentTable); + } + + public static string GetNodeTreeLastImageHtml(ChannelInfo nodeInfo) + { + var imageHtml = string.Empty; + if (!string.IsNullOrEmpty(nodeInfo.ContentModelPluginId) || !string.IsNullOrEmpty(nodeInfo.ContentRelatedPluginIds)) + { + var list = PluginContentManager.GetContentPlugins(nodeInfo, true); + if (list != null && list.Count > 0) + { + imageHtml += @" "; + } + } + return imageHtml; + } + + public static DateTime GetAddDate(int siteId, int channelId) + { + var retVal = DateTime.MinValue; + var nodeInfo = GetChannelInfo(siteId, channelId); + if (nodeInfo?.AddDate != null) retVal = nodeInfo.AddDate.Value; + return retVal; + } + + public static int GetParentId(int siteId, int channelId) + { + var retVal = 0; + var nodeInfo = GetChannelInfo(siteId, channelId); + if (nodeInfo != null) + { + retVal = nodeInfo.ParentId; + } + return retVal; + } + + private static string GetParentsPath(int siteId, int channelId) + { + var retVal = string.Empty; + var nodeInfo = GetChannelInfo(siteId, channelId); + if (nodeInfo != null) + { + retVal = nodeInfo.ParentsPath; + } + return retVal; + } + + public static int GetTopLevel(int siteId, int channelId) + { + var parentsPath = GetParentsPath(siteId, channelId); + return string.IsNullOrEmpty(parentsPath) ? 0 : parentsPath.Split(',').Length; + } + + public static string GetChannelName(int siteId, int channelId) + { + var retVal = string.Empty; + var nodeInfo = GetChannelInfo(siteId, channelId); + if (nodeInfo != null) + { + retVal = nodeInfo.ChannelName; + } + return retVal; + } + + public static string GetChannelNameNavigation(int siteId, int channelId) + { + var nodeNameList = new List(); + + if (channelId == 0) channelId = siteId; + + if (channelId == siteId) + { + var nodeInfo = GetChannelInfo(siteId, siteId); + return nodeInfo.ChannelName; + } + var parentsPath = GetParentsPath(siteId, channelId); + var channelIdList = new List(); + if (!string.IsNullOrEmpty(parentsPath)) + { + channelIdList = TranslateUtils.StringCollectionToIntList(parentsPath); + } + channelIdList.Add(channelId); + channelIdList.Remove(siteId); + + foreach (var theChannelId in channelIdList) + { + var nodeInfo = GetChannelInfo(siteId, theChannelId); + if (nodeInfo != null) + { + nodeNameList.Add(nodeInfo.ChannelName); + } + } + + return TranslateUtils.ObjectCollectionToString(nodeNameList, " > "); + } + + + + + + + + + + public static string GetContentAttributesOfDisplay(int siteId, int channelId) + { + var channelInfo = GetChannelInfo(siteId, channelId); + if (channelInfo == null) return string.Empty; + if (siteId != channelId && string.IsNullOrEmpty(channelInfo.ContentAttributesOfDisplay)) + { + return GetContentAttributesOfDisplay(siteId, channelInfo.ParentId); + } + return channelInfo.ContentAttributesOfDisplay; + } + + public static List GetContentsColumns(SiteInfo siteInfo, ChannelInfo channelInfo, bool includeAll) + { + var items = new List(); + + var attributesOfDisplay = TranslateUtils.StringCollectionToStringCollection(channelInfo.ContentAttributesOfDisplay); + var pluginIds = PluginContentManager.GetContentPluginIds(channelInfo); + var pluginColumns = PluginContentManager.GetContentColumns(pluginIds); + + var styleInfoList = ContentUtility.GetAllTableStyleInfoList(TableStyleManager.GetContentStyleInfoList(siteInfo, channelInfo)); + + styleInfoList.Insert(0, new TableStyleInfo + { + AttributeName = ContentAttribute.Sequence, + DisplayName = "序号" + }); + + foreach (var styleInfo in styleInfoList) + { + if (styleInfo.Type == InputType.TextEditor) continue; + + var listItem = new InputListItem + { + Text = styleInfo.DisplayName, + Value = styleInfo.AttributeName + }; + if (styleInfo.AttributeName == ContentAttribute.Title) + { + listItem.Selected = true; + } + else + { + if (attributesOfDisplay.Contains(styleInfo.AttributeName)) + { + listItem.Selected = true; + } + } + + if (includeAll || listItem.Selected) + { + items.Add(listItem); + } + } + + if (pluginColumns != null) + { + foreach (var pluginId in pluginColumns.Keys) + { + var contentColumns = pluginColumns[pluginId]; + if (contentColumns == null || contentColumns.Count == 0) continue; + + foreach (var columnName in contentColumns.Keys) + { + var attributeName = $"{pluginId}:{columnName}"; + var listItem = new InputListItem + { + Text = $"{columnName}({pluginId})", + Value = attributeName + }; + + if (attributesOfDisplay.Contains(attributeName)) + { + listItem.Selected = true; + } + + if (includeAll || listItem.Selected) + { + items.Add(listItem); + } + } + } + } + + return items; + } + + public static bool IsAncestorOrSelf(int siteId, int parentId, int childId) + { + if (parentId == childId) + { + return true; + } + var nodeInfo = GetChannelInfo(siteId, childId); + if (nodeInfo == null) + { + return false; + } + if (StringUtils.In(nodeInfo.ParentsPath, parentId.ToString())) + { + return true; + } + return false; + } + + public static List> GetChannels(int siteId, IPermissions permissions, params string[] channelPermissions) + { + var options = new List>(); + + var list = GetChannelIdList(siteId); + foreach (var channelId in list) + { + var enabled = permissions.HasChannelPermissions(siteId, channelId, channelPermissions); + + var channelInfo = GetChannelInfo(siteId, channelId); + + if (enabled && channelPermissions.Contains(ConfigManager.ChannelPermissions.ContentAdd)) + { + if (channelInfo.IsContentAddable == false) enabled = false; + } + + if (enabled) + { + var tuple = new KeyValuePair(channelId, + GetChannelNameNavigation(siteId, channelId)); + options.Add(tuple); + } + } + + return options; + } + + public static bool IsCreatable(SiteInfo siteInfo, ChannelInfo channelInfo) + { + if (siteInfo == null || channelInfo == null) return false; + + if (!channelInfo.IsChannelCreatable || !string.IsNullOrEmpty(channelInfo.LinkUrl)) return false; + + var isCreatable = false; + + var linkType = ELinkTypeUtils.GetEnumType(channelInfo.LinkType); + + if (linkType == ELinkType.None) + { + isCreatable = true; + } + else if (linkType == ELinkType.NoLinkIfContentNotExists) + { + var count = ContentManager.GetCount(siteInfo, channelInfo, true); + isCreatable = count != 0; + } + else if (linkType == ELinkType.LinkToOnlyOneContent) + { + var count = ContentManager.GetCount(siteInfo, channelInfo, true); + isCreatable = count != 1; + } + else if (linkType == ELinkType.NoLinkIfContentNotExistsAndLinkToOnlyOneContent) + { + var count = ContentManager.GetCount(siteInfo, channelInfo, true); + if (count != 0 && count != 1) + { + isCreatable = true; + } + } + else if (linkType == ELinkType.LinkToFirstContent) + { + var count = ContentManager.GetCount(siteInfo, channelInfo, true); + isCreatable = count < 1; + } + else if (linkType == ELinkType.NoLinkIfChannelNotExists) + { + isCreatable = channelInfo.ChildrenCount != 0; + } + else if (linkType == ELinkType.LinkToLastAddChannel) + { + isCreatable = channelInfo.ChildrenCount <= 0; + } + else if (linkType == ELinkType.LinkToFirstChannel) + { + isCreatable = channelInfo.ChildrenCount <= 0; + } + + return isCreatable; + } + } + +} \ No newline at end of file diff --git a/SiteServer.CMS/Core/ConfigManager.cs b/net452/SiteServer.CMS/Caches/ConfigManager.cs similarity index 77% rename from SiteServer.CMS/Core/ConfigManager.cs rename to net452/SiteServer.CMS/Caches/ConfigManager.cs index 8096cbbed..d6aa4aa75 100644 --- a/SiteServer.CMS/Core/ConfigManager.cs +++ b/net452/SiteServer.CMS/Caches/ConfigManager.cs @@ -1,11 +1,12 @@ -using SiteServer.CMS.Model; -using SiteServer.Utils; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; -namespace SiteServer.CMS.Core +namespace SiteServer.CMS.Caches { public static class ConfigManager { - private const string CacheKey = "SiteServer.CMS.Core.ConfigManager"; + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(ConfigManager)); private static readonly object LockObject = new object(); public static class PluginsPermissions @@ -40,7 +41,6 @@ public static class ChannelPermissions public const string ContentEdit = "cms_contentEdit"; public const string ContentDelete = "cms_contentDelete"; public const string ContentTranslate = "cms_contentTranslate"; - public const string ContentArchive = "cms_contentArchive"; public const string ContentOrder = "cms_contentOrder"; public const string ChannelAdd = "cms_channelAdd"; public const string ChannelEdit = "cms_channelEdit"; @@ -72,62 +72,62 @@ public static class LeftMenu public static string GetTopMenuName(string menuId) { - var retval = string.Empty; + var retVal = string.Empty; if (menuId == TopMenu.IdSite) { - retval = "站点管理"; + retVal = "站点管理"; } else if (menuId == TopMenu.IdPlugins) { - retval = "插件管理"; + retVal = "插件管理"; } else if (menuId == TopMenu.IdSettings) { - retval = "系统管理"; + retVal = "系统管理"; } - return retval; + return retVal; } public static string GetLeftMenuName(string menuId) { - var retval = string.Empty; + var retVal = string.Empty; if (menuId == LeftMenu.IdContent) { - retval = "信息管理"; + retVal = "信息管理"; } else if (menuId == LeftMenu.IdTemplate) { - retval = "显示管理"; + retVal = "显示管理"; } else if (menuId == LeftMenu.IdConfigration) { - retval = "设置管理"; + retVal = "设置管理"; } else if (menuId == LeftMenu.IdCreate) { - retval = "生成管理"; + retVal = "生成管理"; } - return retval; + return retVal; } public static ConfigInfo Instance { get { - var retval = CacheUtils.Get(CacheKey); - if (retval != null) return retval; + var retVal = DataCacheManager.Get(CacheKey); + if (retVal != null) return retVal; lock (LockObject) { - retval = CacheUtils.Get(CacheKey); - if (retval == null) + retVal = DataCacheManager.Get(CacheKey); + if (retVal == null) { - retval = DataProvider.ConfigDao.GetConfigInfo(); - CacheUtils.Insert(CacheKey, retval); + retVal = DataProvider.Config.GetConfigInfo(); + DataCacheManager.Insert(CacheKey, retVal); } } - return retval; + return retVal; } } @@ -137,11 +137,9 @@ public static bool IsChanged { if (value) { - CacheUtils.Remove(CacheKey); + DataCacheManager.Remove(CacheKey); } } } - - public static SystemConfigInfo SystemConfigInfo => Instance.SystemConfigInfo; } } diff --git a/net452/SiteServer.CMS/Caches/Content/ContentManager.ContentCache.cs b/net452/SiteServer.CMS/Caches/Content/ContentManager.ContentCache.cs new file mode 100644 index 000000000..55fb82aa0 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/Content/ContentManager.ContentCache.cs @@ -0,0 +1,86 @@ +using System.Collections.Generic; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.CMS.Caches.Content +{ + public static partial class ContentManager + { + private static class ContentCache + { + private static readonly object LockObject = new object(); + private static readonly string CachePrefix = DataCacheManager.GetCacheKey(nameof(ContentManager)) + "." + nameof(ContentCache); + + private static string GetCacheKey(int channelId) + { + return $"{CachePrefix}.{channelId}"; + } + + public static void Remove(int channelId) + { + lock (LockObject) + { + var cacheKey = GetCacheKey(channelId); + DataCacheManager.Remove(cacheKey); + } + } + + public static Dictionary GetContentDict(int channelId) + { + lock (LockObject) + { + var cacheKey = GetCacheKey(channelId); + var dict = DataCacheManager.Get>(cacheKey); + if (dict == null) + { + dict = new Dictionary(); + DataCacheManager.InsertHours(cacheKey, dict, 12); + } + + return dict; + } + } + + public static ContentInfo GetContent(SiteInfo siteInfo, int channelId, int contentId) + { + lock (LockObject) + { + var dict = GetContentDict(channelId); + dict.TryGetValue(contentId, out var contentInfo); + if (contentInfo != null && contentInfo.ChannelId == channelId && contentInfo.Id == contentId) return contentInfo; + + contentInfo = DataProvider.ContentRepository.GetCacheContentInfo(ChannelManager.GetTableName(siteInfo, channelId), channelId, contentId); + dict[contentId] = contentInfo; + + return contentInfo; + } + } + + public static ContentInfo GetContent(SiteInfo siteInfo, ChannelInfo channelInfo, int contentId) + { + lock (LockObject) + { + var dict = GetContentDict(channelInfo.Id); + dict.TryGetValue(contentId, out var contentInfo); + if (contentInfo != null && contentInfo.ChannelId == channelInfo.Id && contentInfo.Id == contentId) return contentInfo; + + contentInfo = DataProvider.ContentRepository.GetCacheContentInfo(ChannelManager.GetTableName(siteInfo, channelInfo), channelInfo.Id, contentId); + dict[contentId] = contentInfo; + + return contentInfo; + } + } + } + + public static ContentInfo GetContentInfo(SiteInfo siteInfo, int channelId, int contentId) + { + return ContentCache.GetContent(siteInfo, channelId, contentId); + } + + public static ContentInfo GetContentInfo(SiteInfo siteInfo, ChannelInfo channelInfo, int contentId) + { + return ContentCache.GetContent(siteInfo, channelInfo, contentId); + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Caches/Content/ContentManager.CountCache.cs b/net452/SiteServer.CMS/Caches/Content/ContentManager.CountCache.cs new file mode 100644 index 000000000..405859676 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/Content/ContentManager.CountCache.cs @@ -0,0 +1,187 @@ +using System.Collections.Generic; +using System.Linq; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.CMS.Caches.Content +{ + public static partial class ContentManager + { + private static class CountCache + { + private static readonly object LockObject = new object(); + private static readonly string CacheKey = + DataCacheManager.GetCacheKey(nameof(ContentManager)) + "." + nameof(CountCache); + + private static Dictionary> GetAllContentCounts() + { + lock (LockObject) + { + var retVal = DataCacheManager.Get>>(CacheKey); + if (retVal != null) return retVal; + + retVal = DataCacheManager.Get>>(CacheKey); + if (retVal == null) + { + retVal = new Dictionary>(); + DataCacheManager.Insert(CacheKey, retVal); + } + + return retVal; + } + } + + private static IList GetContentCountInfoList(string tableName) + { + if (string.IsNullOrEmpty(tableName)) return new List(); + + var dict = GetAllContentCounts(); + dict.TryGetValue(tableName, out var countList); + if (countList != null) return countList; + + countList = DataProvider.ContentRepository.GetContentCountInfoList(tableName); + dict[tableName] = countList; + + return countList; + } + + public static void Clear(string tableName) + { + if (string.IsNullOrEmpty(tableName)) return; + + lock (LockObject) + { + var dict = GetAllContentCounts(); + dict.Remove(tableName); + } + } + + public static void Add(string tableName, ContentInfo contentInfo) + { + if (string.IsNullOrEmpty(tableName) || contentInfo == null) return; + + lock (LockObject) + { + var countInfoList = GetContentCountInfoList(tableName); + var countInfo = countInfoList.FirstOrDefault(x => + x.SiteId == contentInfo.SiteId && x.ChannelId == contentInfo.ChannelId && + x.IsChecked == contentInfo.Checked.ToString() && x.CheckedLevel == contentInfo.CheckedLevel && x.AdminId == contentInfo.AdminId); + if (countInfo != null) + { + countInfo.Count++; + } + else + { + countInfo = new ContentCountInfo + { + SiteId = contentInfo.SiteId, + ChannelId = contentInfo.ChannelId, + IsChecked = contentInfo.Checked.ToString(), + CheckedLevel = contentInfo.CheckedLevel, + AdminId = contentInfo.AdminId, + Count = 1 + }; + countInfoList.Add(countInfo); + } + } + } + + public static bool IsChanged(ContentInfo contentInfo1, ContentInfo contentInfo2) + { + if (contentInfo1 == null || contentInfo2 == null) return true; + + return contentInfo1.SiteId != contentInfo2.SiteId || + contentInfo1.ChannelId != contentInfo2.ChannelId || + contentInfo1.Checked != contentInfo2.Checked || + contentInfo1.CheckedLevel != contentInfo2.CheckedLevel || + contentInfo1.AdminId != contentInfo2.AdminId; + } + + public static void Remove(string tableName, ContentInfo contentInfo) + { + if (string.IsNullOrEmpty(tableName) || contentInfo == null) return; + + lock (LockObject) + { + var countInfoList = GetContentCountInfoList(tableName); + var countInfo = countInfoList.FirstOrDefault(x => + x.SiteId == contentInfo.SiteId && x.ChannelId == contentInfo.ChannelId && + x.IsChecked == contentInfo.Checked.ToString() && x.CheckedLevel == contentInfo.CheckedLevel && x.AdminId == contentInfo.AdminId); + if (countInfo != null && countInfo.Count > 0) + { + countInfo.Count--; + } + } + } + + public static int GetSiteCountByIsChecked(SiteInfo siteInfo, bool isChecked) + { + var tableNames = SiteManager.GetTableNameList(siteInfo); + + lock (LockObject) + { + var count = 0; + foreach (var tableName in tableNames) + { + var list = GetContentCountInfoList(tableName); + count += list.Where(x => x.SiteId == siteInfo.Id && x.IsChecked == isChecked.ToString()) + .Sum(x => x.Count); + } + + return count; + } + } + + public static int GetChannelCountByOnlyAdminId(SiteInfo siteInfo, ChannelInfo channelInfo, int? onlyAdminId) + { + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + + lock (LockObject) + { + var list = GetContentCountInfoList(tableName); + return onlyAdminId.HasValue + ? list.Where(x => + x.SiteId == siteInfo.Id && + x.ChannelId == channelInfo.Id && + x.AdminId == onlyAdminId.Value) + .Sum(x => x.Count) + : list.Where(x => + x.SiteId == siteInfo.Id && + x.ChannelId == channelInfo.Id) + .Sum(x => x.Count); + } + } + + public static int GetChannelCountByIsChecked(SiteInfo siteInfo, ChannelInfo channelInfo, bool isChecked) + { + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + + lock (LockObject) + { + var list = GetContentCountInfoList(tableName); + return list.Where(x => + x.SiteId == siteInfo.Id && x.ChannelId == channelInfo.Id && + x.IsChecked == isChecked.ToString()) + .Sum(x => x.Count); + } + } + } + + public static int GetCount(SiteInfo siteInfo, bool isChecked) + { + return CountCache.GetSiteCountByIsChecked(siteInfo, isChecked); + } + + public static int GetCount(SiteInfo siteInfo, ChannelInfo channelInfo, int? onlyAdminId) + { + return CountCache.GetChannelCountByOnlyAdminId(siteInfo, channelInfo, onlyAdminId); + } + + public static int GetCount(SiteInfo siteInfo, ChannelInfo channelInfo, bool isChecked) + { + return CountCache.GetChannelCountByIsChecked(siteInfo, channelInfo, isChecked); + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Caches/Content/ContentManager.ListCache.cs b/net452/SiteServer.CMS/Caches/Content/ContentManager.ListCache.cs new file mode 100644 index 000000000..62bb966f1 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/Content/ContentManager.ListCache.cs @@ -0,0 +1,107 @@ +using System.Collections.Generic; +using System.Linq; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.CMS.Caches.Content +{ + public static partial class ContentManager + { + private static class ListCache + { + private static readonly object LockObject = new object(); + private static readonly string CachePrefix = DataCacheManager.GetCacheKey(nameof(ContentManager), nameof(ListCache)); + + private static string GetCacheKey(int channelId, int? onlyAdminId = null) + { + return onlyAdminId.HasValue + ? $"{CachePrefix}.{channelId}.{onlyAdminId.Value}" + : $"{CachePrefix}.{channelId}"; + } + + public static void Remove(int channelId) + { + lock(LockObject) + { + var cacheKey = GetCacheKey(channelId); + DataCacheManager.Remove(cacheKey); + DataCacheManager.RemoveByPrefix(cacheKey); + } + } + + public static List GetContentIdList(int channelId, int? onlyAdminId) + { + lock (LockObject) + { + var cacheKey = GetCacheKey(channelId, onlyAdminId); + var list = DataCacheManager.Get>(cacheKey); + if (list != null) return list; + + list = new List(); + DataCacheManager.Insert(cacheKey, list); + return list; + } + } + + public static void Add(ChannelInfo channelInfo, ContentInfo contentInfo) + { + if (ETaxisTypeUtils.Equals(ETaxisType.OrderByTaxisDesc, channelInfo.DefaultTaxisType)) + { + var contentIdList = GetContentIdList(channelInfo.Id, null); + contentIdList.Insert(0, contentInfo.Id); + + contentIdList = GetContentIdList(channelInfo.Id, contentInfo.AdminId); + contentIdList.Insert(0, contentInfo.Id); + } + else + { + Remove(channelInfo.Id); + } + } + + public static bool IsChanged(ChannelInfo channelInfo, ContentInfo contentInfo1, ContentInfo contentInfo2) + { + if (contentInfo1.Top != contentInfo2.Top) return true; + + var orderAttributeName = + ETaxisTypeUtils.GetContentOrderAttributeName( + ETaxisTypeUtils.GetEnumType(channelInfo.DefaultTaxisType)); + + return contentInfo1.Get(orderAttributeName) != contentInfo2.Get(orderAttributeName); + } + } + + public static List GetContentIdList(SiteInfo siteInfo, ChannelInfo channelInfo, int? onlyAdminId, int offset, int limit) + { + var list = ListCache.GetContentIdList(channelInfo.Id, onlyAdminId); + if (list.Count >= offset + limit) + { + return list.Skip(offset).Take(limit).ToList(); + } + + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + + if (list.Count == offset) + { + var dict = ContentCache.GetContentDict(channelInfo.Id); + + var pageContentInfoList = DataProvider.ContentRepository.GetContentInfoList(tableName, DataProvider.ContentRepository.GetCacheWhereString(siteInfo, channelInfo, onlyAdminId), + DataProvider.ContentRepository.GetOrderString(channelInfo, string.Empty), offset, limit); + + foreach (var contentInfo in pageContentInfoList) + { + dict[contentInfo.Id] = contentInfo; + } + + var pageContentIdList = pageContentInfoList.Select(x => x.Id).ToList(); + list.AddRange(pageContentIdList); + return pageContentIdList; + } + + return DataProvider.ContentRepository.GetCacheContentIdList(tableName, DataProvider.ContentRepository.GetCacheWhereString(siteInfo, channelInfo, onlyAdminId), + DataProvider.ContentRepository.GetOrderString(channelInfo, string.Empty), offset, limit); + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Caches/Content/ContentManager.Trigger.cs b/net452/SiteServer.CMS/Caches/Content/ContentManager.Trigger.cs new file mode 100644 index 000000000..db6f606f0 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/Content/ContentManager.Trigger.cs @@ -0,0 +1,182 @@ +using System; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Caches.Content +{ + public static partial class ContentManager + { + public static void Delete(SiteInfo siteInfo, ChannelInfo channelInfo, int contentId) + { + if (siteInfo == null || channelInfo == null || contentId <= 0) return; + + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + + channelInfo.ContentRepository.Delete(siteInfo.Id, contentId); + + TagUtils.RemoveTags(siteInfo.Id, contentId); + + foreach (var service in PluginManager.Services) + { + try + { + service.OnContentDeleteCompleted(new ContentEventArgs(siteInfo.Id, channelInfo.Id, contentId)); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(service.PluginId, ex, nameof(service.OnContentDeleteCompleted)); + } + } + + RemoveCache(tableName, channelInfo.Id); + } + + public static void Translate(SiteInfo siteInfo, int channelId, int contentId, string translateCollection, ETranslateContentType translateType, string administratorName) + { + var translateList = TranslateUtils.StringCollectionToStringList(translateCollection); + foreach (var translate in translateList) + { + if (string.IsNullOrEmpty(translate)) continue; + + var translates = translate.Split('_'); + if (translates.Length != 2) continue; + + var targetSiteId = TranslateUtils.ToInt(translates[0]); + var targetChannelId = TranslateUtils.ToInt(translates[1]); + + Translate(siteInfo, channelId, contentId, targetSiteId, targetChannelId, translateType); + } + } + + public static void Translate(SiteInfo siteInfo, int channelId, int contentId, int targetSiteId, int targetChannelId, ETranslateContentType translateType) + { + if (siteInfo == null || channelId <= 0 || contentId <= 0 || targetSiteId <= 0 || targetChannelId <= 0) return; + + var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); + var targetChannelInfo = ChannelManager.GetChannelInfo(targetSiteId, targetChannelId); + var targetTableName = ChannelManager.GetTableName(targetSiteInfo, targetChannelInfo); + + var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + + var contentInfo = GetContentInfo(siteInfo, channelInfo, contentId); + + if (contentInfo == null) return; + + if (translateType == ETranslateContentType.Copy) + { + FileUtility.MoveFileByContentInfo(siteInfo, targetSiteInfo, contentInfo); + + contentInfo.SiteId = targetSiteId; + contentInfo.SourceId = contentInfo.ChannelId; + contentInfo.ChannelId = targetChannelId; + contentInfo.Set(ContentAttribute.TranslateContentType, ETranslateContentType.Copy.ToString()); + //contentInfo.Attributes.Add(ContentAttribute.TranslateContentType, ETranslateContentType.Copy.ToString()); + var theContentId = DataProvider.ContentRepository.Insert(targetTableName, targetSiteInfo, targetChannelInfo, contentInfo); + + foreach (var service in PluginManager.Services) + { + try + { + service.OnContentTranslateCompleted(new ContentTranslateEventArgs(siteInfo.Id, channelInfo.Id, contentId, targetSiteId, targetChannelId, theContentId)); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(service.PluginId, ex, nameof(service.OnContentTranslateCompleted)); + } + } + + CreateManager.CreateContent(targetSiteInfo.Id, contentInfo.ChannelId, theContentId); + CreateManager.TriggerContentChangedEvent(targetSiteInfo.Id, contentInfo.ChannelId); + } + else if (translateType == ETranslateContentType.Cut) + { + FileUtility.MoveFileByContentInfo(siteInfo, targetSiteInfo, contentInfo); + + contentInfo.SiteId = targetSiteId; + contentInfo.SourceId = contentInfo.ChannelId; + contentInfo.ChannelId = targetChannelId; + contentInfo.Set(ContentAttribute.TranslateContentType, ETranslateContentType.Cut.ToString()); + //contentInfo.Attributes.Add(ContentAttribute.TranslateContentType, ETranslateContentType.Cut.ToString()); + + var newContentId = DataProvider.ContentRepository.Insert(targetTableName, targetSiteInfo, targetChannelInfo, contentInfo); + //channelInfo.ContentRepository.DeleteContents(siteInfo.Id, TranslateUtils.ToIntList(contentId), channelId); + + foreach (var service in PluginManager.Services) + { + try + { + service.OnContentTranslateCompleted(new ContentTranslateEventArgs(siteInfo.Id, channelInfo.Id, contentId, targetSiteId, targetChannelId, newContentId)); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(service.PluginId, ex, nameof(service.OnContentTranslateCompleted)); + } + + //try + //{ + // service.OnContentDeleteCompleted(new ContentEventArgs(siteInfo.Id, channelInfo.Id, contentId)); + //} + //catch (Exception ex) + //{ + // LogUtils.AddErrorLog(service.PluginId, ex, nameof(service.OnContentDeleteCompleted)); + //} + } + + Delete(siteInfo, channelInfo, contentId); + + CreateManager.CreateContent(targetSiteInfo.Id, contentInfo.ChannelId, newContentId); + CreateManager.TriggerContentChangedEvent(targetSiteInfo.Id, contentInfo.ChannelId); + } + else if (translateType == ETranslateContentType.Reference) + { + if (contentInfo.ReferenceId != 0) return; + + contentInfo.SiteId = targetSiteId; + contentInfo.SourceId = contentInfo.ChannelId; + contentInfo.ChannelId = targetChannelId; + contentInfo.ReferenceId = contentId; + contentInfo.Set(ContentAttribute.TranslateContentType, ETranslateContentType.Reference.ToString()); + //contentInfo.Attributes.Add(ContentAttribute.TranslateContentType, ETranslateContentType.Reference.ToString()); + int theContentId = DataProvider.ContentRepository.Insert(targetTableName, targetSiteInfo, targetChannelInfo, contentInfo); + + CreateManager.CreateContent(targetSiteInfo.Id, contentInfo.ChannelId, theContentId); + CreateManager.TriggerContentChangedEvent(targetSiteInfo.Id, contentInfo.ChannelId); + } + else if (translateType == ETranslateContentType.ReferenceContent) + { + if (contentInfo.ReferenceId != 0) return; + + FileUtility.MoveFileByContentInfo(siteInfo, targetSiteInfo, contentInfo); + + contentInfo.SiteId = targetSiteId; + contentInfo.SourceId = contentInfo.ChannelId; + contentInfo.ChannelId = targetChannelId; + contentInfo.ReferenceId = contentId; + contentInfo.Set(ContentAttribute.TranslateContentType, ETranslateContentType.ReferenceContent.ToString()); + var theContentId = DataProvider.ContentRepository.Insert(targetTableName, targetSiteInfo, targetChannelInfo, contentInfo); + + foreach (var service in PluginManager.Services) + { + try + { + service.OnContentTranslateCompleted(new ContentTranslateEventArgs(siteInfo.Id, channelInfo.Id, contentId, targetSiteId, targetChannelId, theContentId)); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(service.PluginId, ex, nameof(service.OnContentTranslateCompleted)); + } + } + + CreateManager.CreateContent(targetSiteInfo.Id, contentInfo.ChannelId, theContentId); + CreateManager.TriggerContentChangedEvent(targetSiteInfo.Id, contentInfo.ChannelId); + } + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Caches/Content/ContentManager.cs b/net452/SiteServer.CMS/Caches/Content/ContentManager.cs new file mode 100644 index 000000000..ad1950a91 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/Content/ContentManager.cs @@ -0,0 +1,288 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using SiteServer.CMS.Caches.Stl; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Caches.Content +{ + public static partial class ContentManager + { + public static void RemoveCacheBySiteId(string tableName, int siteId) + { + foreach (var channelId in ChannelManager.GetChannelIdList(siteId)) + { + ListCache.Remove(channelId); + ContentCache.Remove(channelId); + } + CountCache.Clear(tableName); + StlContentCache.ClearCache(); + } + + public static void RemoveCache(string tableName, int channelId) + { + ListCache.Remove(channelId); + ContentCache.Remove(channelId); + CountCache.Clear(tableName); + StlContentCache.ClearCache(); + } + + public static void RemoveCountCache(string tableName) + { + CountCache.Clear(tableName); + StlContentCache.ClearCache(); + } + + public static void InsertCache(SiteInfo siteInfo, ChannelInfo channelInfo, ContentInfo contentInfo) + { + if (contentInfo.SourceId == SourceManager.Preview) return; + + ListCache.Add(channelInfo, contentInfo); + + var dict = ContentCache.GetContentDict(contentInfo.ChannelId); + dict[contentInfo.Id] = contentInfo; + + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + CountCache.Add(tableName, contentInfo); + + StlContentCache.ClearCache(); + } + + public static void UpdateCache(SiteInfo siteInfo, ChannelInfo channelInfo, ContentInfo contentInfoToUpdate) + { + var dict = ContentCache.GetContentDict(channelInfo.Id); + + var contentInfo = GetContentInfo(siteInfo, channelInfo, contentInfoToUpdate.Id); + if (contentInfo != null) + { + if (ListCache.IsChanged(channelInfo, contentInfo, contentInfoToUpdate)) + { + ListCache.Remove(channelInfo.Id); + } + + if (CountCache.IsChanged(contentInfo, contentInfoToUpdate)) + { + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + CountCache.Remove(tableName, contentInfo); + CountCache.Add(tableName, contentInfoToUpdate); + } + } + + dict[contentInfoToUpdate.Id] = contentInfoToUpdate; + + StlContentCache.ClearCache(); + } + + public static List GetContentColumns(SiteInfo siteInfo, ChannelInfo channelInfo, bool includeAll) + { + var columns = new List(); + + var attributesOfDisplay = TranslateUtils.StringCollectionToStringCollection(channelInfo.ContentAttributesOfDisplay); + var pluginIds = PluginContentManager.GetContentPluginIds(channelInfo); + var pluginColumns = PluginContentManager.GetContentColumns(pluginIds); + + var styleInfoList = ContentUtility.GetAllTableStyleInfoList(TableStyleManager.GetContentStyleInfoList(siteInfo, channelInfo)); + + styleInfoList.Insert(0, new TableStyleInfo + { + AttributeName = ContentAttribute.Sequence, + DisplayName = "序号" + }); + + foreach (var styleInfo in styleInfoList) + { + if (styleInfo.Type == InputType.TextEditor) continue; + + var column = new ContentColumn + { + AttributeName = styleInfo.AttributeName, + DisplayName = styleInfo.DisplayName, + InputType = styleInfo.Type + }; + if (styleInfo.AttributeName == ContentAttribute.Title) + { + column.IsList = true; + } + else + { + if (attributesOfDisplay.Contains(styleInfo.AttributeName)) + { + column.IsList = true; + } + } + + if (StringUtils.ContainsIgnoreCase(ContentAttribute.CalculateAttributes.Value, styleInfo.AttributeName)) + { + column.IsCalculate = true; + } + + if (includeAll || column.IsList) + { + columns.Add(column); + } + } + + if (pluginColumns != null) + { + foreach (var pluginId in pluginColumns.Keys) + { + var contentColumns = pluginColumns[pluginId]; + if (contentColumns == null || contentColumns.Count == 0) continue; + + foreach (var columnName in contentColumns.Keys) + { + var attributeName = $"{pluginId}:{columnName}"; + var column = new ContentColumn + { + AttributeName = attributeName, + DisplayName = $"{columnName}({pluginId})", + InputType = InputType.Text, + IsCalculate = true + }; + + if (attributesOfDisplay.Contains(attributeName)) + { + column.IsList = true; + } + + if (includeAll || column.IsList) + { + columns.Add(column); + } + } + } + } + + return columns; + } + + public static IDictionary Calculate(int sequence, ContentInfo contentInfo, List columns, Dictionary>> pluginColumns) + { + if (contentInfo == null) return null; + + var retVal = contentInfo.ToDictionary(); + + foreach (var column in columns) + { + if (!column.IsCalculate) continue; + + if (StringUtils.EqualsIgnoreCase(column.AttributeName, ContentAttribute.Sequence)) + { + retVal[ContentAttribute.Sequence] = sequence; + } + else if (StringUtils.EqualsIgnoreCase(column.AttributeName, ContentAttribute.AdminId)) + { + var value = string.Empty; + if (contentInfo.AdminId > 0) + { + var adminInfo = AdminManager.GetAdminInfoByUserId(contentInfo.AdminId); + if (adminInfo != null) + { + value = string.IsNullOrEmpty(adminInfo.DisplayName) ? adminInfo.UserName : adminInfo.DisplayName; + } + } + retVal[ContentAttribute.AdminId] = value; + } + else if (StringUtils.EqualsIgnoreCase(column.AttributeName, ContentAttribute.UserId)) + { + var value = string.Empty; + if (contentInfo.UserId > 0) + { + var userInfo = UserManager.GetUserInfoByUserId(contentInfo.UserId); + if (userInfo != null) + { + value = string.IsNullOrEmpty(userInfo.DisplayName) ? userInfo.UserName : userInfo.DisplayName; + } + } + retVal[ContentAttribute.UserId] = value; + } + else if (StringUtils.EqualsIgnoreCase(column.AttributeName, ContentAttribute.SourceId)) + { + retVal[ContentAttribute.SourceId] = SourceManager.GetSourceName(contentInfo.SourceId); + } + else if (StringUtils.EqualsIgnoreCase(column.AttributeName, ContentAttribute.AddUserName)) + { + var value = string.Empty; + if (!string.IsNullOrEmpty(contentInfo.AddUserName)) + { + var adminInfo = AdminManager.GetAdminInfoByUserName(contentInfo.AddUserName); + if (adminInfo != null) + { + value = string.IsNullOrEmpty(adminInfo.DisplayName) ? adminInfo.UserName : adminInfo.DisplayName; + } + } + retVal[ContentAttribute.AddUserName] = value; + } + else if (StringUtils.EqualsIgnoreCase(column.AttributeName, ContentAttribute.LastEditUserName)) + { + var value = string.Empty; + if (!string.IsNullOrEmpty(contentInfo.LastEditUserName)) + { + var adminInfo = AdminManager.GetAdminInfoByUserName(contentInfo.LastEditUserName); + if (adminInfo != null) + { + value = string.IsNullOrEmpty(adminInfo.DisplayName) ? adminInfo.UserName : adminInfo.DisplayName; + } + } + retVal[ContentAttribute.LastEditUserName] = value; + } + } + + if (pluginColumns != null) + { + foreach (var pluginId in pluginColumns.Keys) + { + var contentColumns = pluginColumns[pluginId]; + if (contentColumns == null || contentColumns.Count == 0) continue; + + foreach (var columnName in contentColumns.Keys) + { + var attributeName = $"{pluginId}:{columnName}"; + if (columns.All(x => x.AttributeName != attributeName)) continue; + + try + { + var func = contentColumns[columnName]; + var value = func(new ContentContextImpl + { + SiteId = contentInfo.SiteId, + ChannelId = contentInfo.ChannelId, + ContentId = contentInfo.Id + }); + + retVal[attributeName] = value; + } + catch (Exception ex) + { + LogUtils.AddErrorLog(pluginId, ex); + } + } + } + } + + return retVal; + } + + public static bool IsCreatable(ChannelInfo channelInfo, ContentInfo contentInfo) + { + if (channelInfo == null || contentInfo == null) return false; + + //引用链接,不需要生成内容页;引用内容,需要生成内容页; + if (contentInfo.ReferenceId > 0 && + ETranslateContentTypeUtils.GetEnumType(contentInfo.Get(ContentAttribute.TranslateContentType)) != + ETranslateContentType.ReferenceContent) + { + return false; + } + + return channelInfo.IsContentCreatable && string.IsNullOrEmpty(contentInfo.LinkUrl) && contentInfo.Checked && contentInfo.SourceId != SourceManager.Preview && contentInfo.ChannelId > 0; + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Caches/ContentGroupManager.cs b/net452/SiteServer.CMS/Caches/ContentGroupManager.cs new file mode 100644 index 000000000..83e57866e --- /dev/null +++ b/net452/SiteServer.CMS/Caches/ContentGroupManager.cs @@ -0,0 +1,77 @@ +using System.Collections.Generic; +using System.Linq; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.CMS.Caches +{ + public static class ContentGroupManager + { + private static class ContentGroupManagerCache + { + private static readonly object LockObject = new object(); + + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(ContentGroupManager)); + + public static void Clear() + { + DataCacheManager.Remove(CacheKey); + } + + public static Dictionary> GetAllContentGroups() + { + var retval = DataCacheManager.Get>>(CacheKey); + if (retval != null) return retval; + + lock (LockObject) + { + retval = DataCacheManager.Get>>(CacheKey); + if (retval == null) + { + retval = DataProvider.ContentGroup.GetAllContentGroups(); + + DataCacheManager.Insert(CacheKey, retval); + } + } + + return retval; + } + } + + public static void ClearCache() + { + ContentGroupManagerCache.Clear(); + } + + public static bool IsExists(int siteId, string groupName) + { + var list = GetContentGroupInfoList(siteId); + return list.Any(group => group.GroupName == groupName); + } + + public static ContentGroupInfo GetContentGroupInfo(int siteId, string groupName) + { + var list = GetContentGroupInfoList(siteId); + return list.FirstOrDefault(group => group.GroupName == groupName); + } + + public static List GetGroupNameList(int siteId) + { + var list = GetContentGroupInfoList(siteId); + return list.Select(group => group.GroupName).ToList(); + } + + public static List GetContentGroupInfoList(int siteId) + { + List list = null; + var dict = ContentGroupManagerCache.GetAllContentGroups(); + + if (dict != null && dict.ContainsKey(siteId)) + { + list = dict[siteId]; + } + return list ?? new List(); + } + } +} diff --git a/net452/SiteServer.CMS/Caches/ContentTagManager.cs b/net452/SiteServer.CMS/Caches/ContentTagManager.cs new file mode 100644 index 000000000..6af8741aa --- /dev/null +++ b/net452/SiteServer.CMS/Caches/ContentTagManager.cs @@ -0,0 +1,77 @@ +using System.Collections.Generic; +using System.Linq; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.CMS.Caches +{ + public static class ContentTagManager + { + private static class ContentTagManagerCache + { + private static readonly object LockObject = new object(); + + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(ContentTagManager)); + + public static void Clear() + { + DataCacheManager.Remove(CacheKey); + } + + public static Dictionary> GetAllContentTags() + { + var retval = DataCacheManager.Get>>(CacheKey); + if (retval != null) return retval; + + lock (LockObject) + { + retval = DataCacheManager.Get>>(CacheKey); + if (retval == null) + { + retval = DataProvider.ContentTag.GetAllContentTags(); + + DataCacheManager.Insert(CacheKey, retval); + } + } + + return retval; + } + } + + public static void ClearCache() + { + ContentTagManagerCache.Clear(); + } + + public static bool IsExists(int siteId, string groupName) + { + var list = GetContentTagInfoList(siteId); + return list.Any(group => group.TagName == groupName); + } + + public static ContentTagInfo GetContentTagInfo(int siteId, string groupName) + { + var list = GetContentTagInfoList(siteId); + return list.FirstOrDefault(group => group.TagName == groupName); + } + + public static List GetTagNameList(int siteId) + { + var list = GetContentTagInfoList(siteId); + return list.Select(group => group.TagName).ToList(); + } + + public static List GetContentTagInfoList(int siteId) + { + List list = null; + var dict = ContentTagManagerCache.GetAllContentTags(); + + if (dict != null && dict.ContainsKey(siteId)) + { + list = dict[siteId]; + } + return list ?? new List(); + } + } +} diff --git a/net452/SiteServer.CMS/Caches/Core/DataCacheManager.cs b/net452/SiteServer.CMS/Caches/Core/DataCacheManager.cs new file mode 100644 index 000000000..7c918cdb2 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/Core/DataCacheManager.cs @@ -0,0 +1,64 @@ +using System; +using System.Linq; +using SiteServer.CMS.Fx; +using SiteServer.Utils; + +namespace SiteServer.CMS.Caches.Core +{ + public static class DataCacheManager + { + private const string CachePrefix = "DataCacheManager"; + + public static string GetCacheKey(string nameofClass, params string[] values) + { + var key = $"{CachePrefix}.{nameofClass}"; + if (values == null || values.Length == 0) return key; + return values.Aggregate(key, (current, t) => current + "." + t); + } + + public static T Get(string cacheKey) where T : class + { + return CacheUtils.Get(cacheKey); + } + + public static void Insert(string cacheKey, object value) + { + CacheUtils.Insert(cacheKey, value); + } + + public static void Insert(string cacheKey, object value, string filePath) + { + CacheUtils.Insert(cacheKey, value, filePath); + } + + public static void Insert(string key, object obj, TimeSpan timeSpan, string filePath) + { + CacheUtils.Insert(key, obj, timeSpan, filePath); + } + + public static void InsertHours(string cacheKey, object value, int hours) + { + CacheUtils.InsertHours(cacheKey, value, hours); + } + + public static void InsertMinutes(string cacheKey, object value, int minutes) + { + CacheUtils.InsertMinutes(cacheKey, value, minutes); + } + + public static void Remove(string cacheKey) + { + CacheUtils.Remove(cacheKey); + } + + public static void RemoveByClassName(string className) + { + CacheUtils.RemoveByStartString(GetCacheKey(className)); + } + + public static void RemoveByPrefix(string prefix) + { + CacheUtils.RemoveByStartString(prefix); + } + } +} diff --git a/net452/SiteServer.CMS/Caches/Core/StlCacheManager.cs b/net452/SiteServer.CMS/Caches/Core/StlCacheManager.cs new file mode 100644 index 000000000..89e938ece --- /dev/null +++ b/net452/SiteServer.CMS/Caches/Core/StlCacheManager.cs @@ -0,0 +1,46 @@ +using SiteServer.CMS.Fx; +using SiteServer.Utils; + +namespace SiteServer.CMS.Caches.Core +{ + public static class StlCacheManager + { + private const string CachePrefix = "StlCacheManager"; + + public static string GetCacheKey(string nameofClass, string nameofMethod, params string[] values) + { + var key = $"{CachePrefix}.{nameofClass}.{nameofMethod}"; + if (values == null || values.Length <= 0) return key; + foreach (var t in values) + { + key += "." + t; + } + return key; + } + + public static T Get(string cacheKey) where T : class + { + return CacheUtils.Get(cacheKey); + } + + public static int GetInt(string cacheKey) + { + return CacheUtils.GetInt(cacheKey, -1); + } + + public static void Set(string cacheKey, object value) + { + CacheUtils.InsertMinutes(cacheKey, value, 2); + } + + public static void Clear(string nameofClass) + { + CacheUtils.RemoveByStartString(GetCacheKey(nameofClass, string.Empty)); + } + + public static void ClearAll() + { + CacheUtils.RemoveByStartString(CachePrefix); + } + } +} diff --git a/net452/SiteServer.CMS/Caches/DepartmentManager.cs b/net452/SiteServer.CMS/Caches/DepartmentManager.cs new file mode 100644 index 000000000..220a9b566 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/DepartmentManager.cs @@ -0,0 +1,132 @@ +using System.Collections.Generic; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Caches +{ + public static class DepartmentManager + { + private static readonly object LockObject = new object(); + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(DepartmentManager)); + + public static List> GetRestDepartments() + { + var list = new List>(); + + var departmentIdList = GetDepartmentIdList(); + var parentsCountDict = new Dictionary(); + foreach (var departmentId in departmentIdList) + { + var departmentInfo = GetDepartmentInfo(departmentId); + list.Add(new KeyValuePair(departmentId, GetTreeItem(departmentInfo.DepartmentName, departmentInfo.ParentsCount, departmentInfo.LastNode, parentsCountDict))); + } + + return list; + } + + public static string GetTreeItem(string name, int parentsCount, bool isLastNode, Dictionary parentsCountDict) + { + var str = ""; + if (isLastNode == false) + { + parentsCountDict[parentsCount] = false; + } + else + { + parentsCountDict[parentsCount] = true; + } + for (var i = 0; i < parentsCount; i++) + { + str = string.Concat(str, TranslateUtils.DictGetValue(parentsCountDict, i) ? "" : ""); + } + str = string.Concat(str, isLastNode ? "" : ""); + str = string.Concat(str, name); + return str; + } + + public static DepartmentInfo GetDepartmentInfo(int departmentId) + { + var pairList = GetDepartmentInfoKeyValuePair(); + + foreach (var pair in pairList) + { + if (pair.Key == departmentId) + { + return pair.Value; + } + } + return null; + } + + public static string GetDepartmentName(int departmentId) + { + if (departmentId <= 0) return string.Empty; + + var departmentNameList = new List(); + + var parentsPath = GetParentsPath(departmentId); + var departmentIdList = new List(); + if (!string.IsNullOrEmpty(parentsPath)) + { + departmentIdList = TranslateUtils.StringCollectionToIntList(parentsPath); + } + departmentIdList.Add(departmentId); + + foreach (var theDepartmentId in departmentIdList) + { + var departmentInfo = GetDepartmentInfo(theDepartmentId); + if (departmentInfo != null) + { + departmentNameList.Add(departmentInfo.DepartmentName); + } + } + + return TranslateUtils.ObjectCollectionToString(departmentNameList, " > "); + } + + public static string GetParentsPath(int departmentId) + { + var retval = string.Empty; + var departmentInfo = GetDepartmentInfo(departmentId); + if (departmentInfo != null) + { + retval = departmentInfo.ParentsPath; + } + return retval; + } + + public static List GetDepartmentIdList() + { + var pairList = GetDepartmentInfoKeyValuePair(); + var list = new List(); + foreach (var pair in pairList) + { + list.Add(pair.Key); + } + return list; + } + + public static void ClearCache() + { + lock (LockObject) + { + DataCacheManager.Remove(CacheKey); + } + } + + public static List> GetDepartmentInfoKeyValuePair() + { + lock (LockObject) + { + var list = DataCacheManager.Get>>(CacheKey); + if (list != null) return list; + + list = DataProvider.Department.GetDepartmentInfoKeyValuePair(); + DataCacheManager.Insert(CacheKey, list); + return list; + } + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Caches/PermissionConfigManager.cs b/net452/SiteServer.CMS/Caches/PermissionConfigManager.cs new file mode 100644 index 000000000..1b20482bd --- /dev/null +++ b/net452/SiteServer.CMS/Caches/PermissionConfigManager.cs @@ -0,0 +1,116 @@ +using System.Collections.Generic; +using System.Xml; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Caches +{ + public class PermissionConfigManager + { + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(PermissionConfigManager)); + + public class PermissionConfig + { + public PermissionConfig(string name, string text) + { + Name = name; + Text = text; + } + + public string Name { get; set; } + + public string Text { get; set; } + } + + + + public List GeneralPermissions { get; } = new List(); + + public List WebsitePermissions { get; } = new List(); + + public List WebsiteSysPermissions { get; } = new List(); + + public List WebsitePluginPermissions { get; } = new List(); + + public List ChannelPermissions { get; } = new List(); + + private PermissionConfigManager() + { + } + + public static PermissionConfigManager Instance + { + get + { + var permissionManager = DataCacheManager.Get(CacheKey); + if (permissionManager != null) return permissionManager; + + permissionManager = new PermissionConfigManager(); + + var path = FxUtils.GetMenusPath("Permissions.config"); + if (FileUtils.IsFileExists(path)) + { + var doc = new XmlDocument(); + doc.Load(path); + permissionManager.LoadValuesFromConfigurationXml(doc); + } + + DataCacheManager.Insert(CacheKey, permissionManager, path); + return permissionManager; + } + } + + private void LoadValuesFromConfigurationXml(XmlDocument doc) + { + var coreNode = doc.SelectSingleNode("Config"); + if (coreNode != null) + { + var isMultiple = true; + foreach (XmlNode child in coreNode.ChildNodes) + { + if (child.NodeType == XmlNodeType.Comment) continue; + if (child.Name == "generalPermissions") + { + GetPermissions(child, GeneralPermissions); + } + else if (child.Name == "websitePermissions") + { + GetPermissions(child, WebsiteSysPermissions); + GetPermissions(child, WebsitePermissions); + } + else if (child.Name == "channelPermissions") + { + GetPermissions(child, ChannelPermissions); + } + else + { + isMultiple = false; + break; + } + } + if (!isMultiple) + { + GetPermissions(coreNode, GeneralPermissions); + } + } + + GeneralPermissions.AddRange(PluginMenuManager.GetTopPermissions()); + var pluginPermissions = PluginMenuManager.GetSitePermissions(0); + WebsitePluginPermissions.AddRange(pluginPermissions); + WebsitePermissions.AddRange(pluginPermissions); + } + + private static void GetPermissions(XmlNode node, List list) + { + foreach (XmlNode permission in node.ChildNodes) + { + if (permission.Name == "add" && permission.Attributes != null) + { + list.Add(new PermissionConfig(permission.Attributes["name"].Value, permission.Attributes["text"].Value)); + } + } + } + } +} diff --git a/net452/SiteServer.CMS/Caches/SiteManager.cs b/net452/SiteServer.CMS/Caches/SiteManager.cs new file mode 100644 index 000000000..7fcf6f615 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/SiteManager.cs @@ -0,0 +1,442 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Caches +{ + public static class SiteManager + { + private static class SiteManagerCache + { + private static readonly object LockObject = new object(); + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(SiteManager)); + + //private static readonly FileWatcherClass FileWatcher; + + //static SiteManagerCache() + //{ + // FileWatcher = new FileWatcherClass(FileWatcherClass.Site); + // FileWatcher.OnFileChange += FileWatcher_OnFileChange; + //} + + //private static void FileWatcher_OnFileChange(object sender, EventArgs e) + //{ + // CacheManager.Remove(CacheKey); + //} + + public static void Clear() + { + DataCacheManager.Remove(CacheKey); + //FileWatcher.UpdateCacheFile(); + } + + public static List> GetSiteInfoKeyValuePairList() + { + var retval = DataCacheManager.Get>>(CacheKey); + if (retval != null) return retval; + + lock (LockObject) + { + retval = DataCacheManager.Get>>(CacheKey); + if (retval == null) + { + var list = DataProvider.Site.GetSiteInfoKeyValuePairList(); + retval = new List>(); + foreach (var pair in list) + { + var siteInfo = pair.Value; + if (siteInfo == null) continue; + + siteInfo.SiteDir = GetSiteDir(list, siteInfo); + retval.Add(pair); + } + + DataCacheManager.Insert(CacheKey, retval); + } + } + + return retval; + } + } + + public static void ClearCache() + { + SiteManagerCache.Clear(); + } + + public static List GetSiteInfoList() + { + var pairList = SiteManagerCache.GetSiteInfoKeyValuePairList(); + return pairList.Select(pair => pair.Value).ToList(); + } + + public static SiteInfo GetSiteInfo(int siteId) + { + if (siteId <= 0) return null; + + var list = SiteManagerCache.GetSiteInfoKeyValuePairList(); + + foreach (var pair in list) + { + var theSiteId = pair.Key; + if (theSiteId != siteId) continue; + var siteInfo = pair.Value; + return siteInfo; + } + return null; + } + + public static SiteInfo GetSiteInfoBySiteName(string siteName) + { + var list = SiteManagerCache.GetSiteInfoKeyValuePairList(); + + foreach (var pair in list) + { + var siteInfo = pair.Value; + if (siteInfo == null) continue; + + if (StringUtils.EqualsIgnoreCase(siteInfo.SiteName, siteName)) + { + return siteInfo; + } + } + return null; + } + + public static SiteInfo GetSiteInfoByIsRoot() + { + var list = SiteManagerCache.GetSiteInfoKeyValuePairList(); + + foreach (var pair in list) + { + var siteInfo = pair.Value; + if (siteInfo == null) continue; + + if (siteInfo.Root) + { + return siteInfo; + } + } + return null; + } + + public static SiteInfo GetSiteInfoByDirectory(string siteDir) + { + var list = SiteManagerCache.GetSiteInfoKeyValuePairList(); + + foreach (var pair in list) + { + var siteInfo = pair.Value; + if (siteInfo == null) continue; + + if (StringUtils.EqualsIgnoreCase(siteInfo.SiteDir, siteDir)) + { + return siteInfo; + } + } + return null; + } + + public static List GetSiteIdList() + { + var pairList = SiteManagerCache.GetSiteInfoKeyValuePairList(); + var list = new List(); + foreach (var pair in pairList) + { + list.Add(pair.Key); + } + return list; + } + + public static List GetSiteIdListOrderByLevel() + { + var retval = new List(); + + var siteIdList = GetSiteIdList(); + var siteInfoList = new List(); + var parentWithChildren = new Hashtable(); + var hqSiteId = 0; + foreach (var siteId in siteIdList) + { + var siteInfo = GetSiteInfo(siteId); + if (siteInfo.Root) + { + hqSiteId = siteInfo.Id; + } + else + { + if (siteInfo.ParentId == 0) + { + siteInfoList.Add(siteInfo); + } + else + { + var children = new List(); + if (parentWithChildren.Contains(siteInfo.ParentId)) + { + children = (List)parentWithChildren[siteInfo.ParentId]; + } + children.Add(siteInfo); + parentWithChildren[siteInfo.ParentId] = children; + } + } + } + + if (hqSiteId > 0) + { + retval.Add(hqSiteId); + } + + var list = siteInfoList.OrderBy(siteInfo => siteInfo.Taxis == 0 ? int.MaxValue : siteInfo.Taxis).ToList(); + + foreach (var siteInfo in list) + { + AddSiteIdList(retval, siteInfo, parentWithChildren, 0); + } + return retval; + } + + private static void AddSiteIdList(List dataSource, SiteInfo siteInfo, Hashtable parentWithChildren, int level) + { + dataSource.Add(siteInfo.Id); + + if (parentWithChildren[siteInfo.Id] != null) + { + var children = (List)parentWithChildren[siteInfo.Id]; + level++; + + var list = children.OrderBy(child => child.Taxis == 0 ? int.MaxValue : child.Taxis).ToList(); + + foreach (var subSiteInfo in list) + { + AddSiteIdList(dataSource, subSiteInfo, parentWithChildren, level); + } + } + } + + public static void GetAllParentSiteIdList(List parentSiteIds, List siteIdCollection, int siteId) + { + var siteInfo = GetSiteInfo(siteId); + var parentSiteId = -1; + foreach (var psId in siteIdCollection) + { + if (psId != siteInfo.ParentId) continue; + parentSiteId = psId; + break; + } + if (parentSiteId == -1) return; + + parentSiteIds.Add(parentSiteId); + GetAllParentSiteIdList(parentSiteIds, siteIdCollection, parentSiteId); + } + + public static bool IsExists(int siteId) + { + if (siteId == 0) return false; + return GetSiteInfo(siteId) != null; + } + + public static List GetSiteTableNames() + { + return GetTableNameList(true, false); + } + + public static List GetAllTableNameList() + { + return GetTableNameList(true, true); + } + + private static List GetTableNameList(bool includeSiteTables, bool includePluginTables) + { + var tableNames = new List(); + + if (includeSiteTables) + { + var pairList = SiteManagerCache.GetSiteInfoKeyValuePairList(); + foreach (var pair in pairList) + { + if (!StringUtils.ContainsIgnoreCase(tableNames, pair.Value.TableName)) + { + tableNames.Add(pair.Value.TableName); + } + } + } + + if (includePluginTables) + { + var pluginTableNames = PluginContentManager.GetContentTableNameList(); + foreach (var pluginTableName in pluginTableNames) + { + if (!StringUtils.ContainsIgnoreCase(tableNames, pluginTableName)) + { + tableNames.Add(pluginTableName); + } + } + } + + return tableNames; + } + + public static List GetTableNameList(SiteInfo siteInfo) + { + var tableNames = new List{ siteInfo.TableName }; + var pluginTableNames = PluginContentManager.GetContentTableNameList(); + foreach (var pluginTableName in pluginTableNames) + { + if (!string.IsNullOrEmpty(pluginTableName) && !StringUtils.ContainsIgnoreCase(tableNames, pluginTableName)) + { + tableNames.Add(pluginTableName); + } + } + return tableNames; + } + + //public static ETableStyle GetTableStyle(SiteInfo siteInfo, string tableName) + //{ + // var tableStyle = ETableStyle.Custom; + + // if (StringUtils.EqualsIgnoreCase(tableName, siteInfo.AuxiliaryTableForContent)) + // { + // tableStyle = ETableStyle.BackgroundContent; + // } + // else if (StringUtils.EqualsIgnoreCase(tableName, DataProvider.Site.TableName)) + // { + // tableStyle = ETableStyle.Site; + // } + // else if (StringUtils.EqualsIgnoreCase(tableName, DataProvider.Channel.TableName)) + // { + // tableStyle = ETableStyle.Channel; + // } + // //else if (StringUtils.EqualsIgnoreCase(tableName, DataProvider.InputContentDao.TableName)) + // //{ + // // tableStyle = ETableStyle.InputContent; + // //} + // return tableStyle; + //} + + public static int GetSiteLevel(int siteId) + { + var level = 0; + var siteInfo = GetSiteInfo(siteId); + if (siteInfo.ParentId != 0) + { + level++; + level += GetSiteLevel(siteInfo.ParentId); + } + return level; + } + + public static int GetParentSiteId(int siteId) + { + var parentSiteId = 0; + var siteInfo = GetSiteInfo(siteId); + if (siteInfo != null && siteInfo.Root == false) + { + parentSiteId = siteInfo.ParentId; + if (parentSiteId == 0) + { + parentSiteId = DataProvider.Site.GetIdByIsRoot(); + } + } + return parentSiteId; + } + + private static string GetSiteDir(List> listFromDb, SiteInfo siteInfo) + { + if (siteInfo == null || siteInfo.Root) return string.Empty; + if (siteInfo.ParentId != 0) + { + SiteInfo parent = null; + foreach (var pair in listFromDb) + { + var theSiteId = pair.Key; + if (theSiteId != siteInfo.ParentId) continue; + parent = pair.Value; + break; + } + return PathUtils.Combine(GetSiteDir(listFromDb, parent), PathUtils.GetDirectoryName(siteInfo.SiteDir, false)); + } + return PathUtils.GetDirectoryName(siteInfo.SiteDir, false); + } + + //public static List GetWritingSiteIdList(PermissionsImpl permissionsImpl) + //{ + // var siteIdList = new List(); + + // if (!string.IsNullOrEmpty(permissionsImpl.UserName)) + // { + // if (permissionsImpl.IsConsoleAdministrator || permissionsImpl.IsSystemAdministrator)//如果是超级管理员或站点管理员 + // { + // foreach (var siteId in permissionsImpl.SiteIdList) + // { + // if (!siteIdList.Contains(siteId)) + // { + // siteIdList.Add(siteId); + // } + // } + // } + // else + // { + // foreach (var siteId in permissionsImpl.SiteIdList) + // { + // if (!siteIdList.Contains(siteId)) + // { + // var channelIdCollection = DataProvider.SitePermissions.GetAllPermissionList(permissionsImpl.Roles, siteId, true); + // if (channelIdCollection.Count > 0) + // { + // siteIdList.Add(siteId); + // } + // } + // } + // } + // } + + // return siteIdList; + //} + + public static string GetSiteName(SiteInfo siteInfo) + { + var padding = string.Empty; + + var level = GetSiteLevel(siteInfo.Id); + string psLogo; + if (siteInfo.Root) + { + psLogo = "siteHQ.gif"; + } + else + { + psLogo = "site.gif"; + if (level > 0 && level < 10) + { + psLogo = $"subsite{level + 1}.gif"; + } + } + psLogo = SiteServerAssets.GetIconUrl("tree/" + psLogo); + + for (var i = 0; i < level; i++) + { + padding += " "; + } + if (level > 0) + { + padding += "└ "; + } + + return $"{padding} {siteInfo.SiteName}"; + } + + public static bool IsSiteTable(string tableName) + { + var pairList = SiteManagerCache.GetSiteInfoKeyValuePairList(); + return pairList.Any(pair => StringUtils.EqualsIgnoreCase(pair.Value.TableName, tableName) || StringUtils.EqualsIgnoreCase(pair.Value.TableName, tableName)); + } + } +} diff --git a/net452/SiteServer.CMS/Caches/SpecialManager.cs b/net452/SiteServer.CMS/Caches/SpecialManager.cs new file mode 100644 index 000000000..6487cd535 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/SpecialManager.cs @@ -0,0 +1,202 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Text; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Caches +{ + public static class SpecialManager + { + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(SpecialManager)); + private static readonly object SyncRoot = new object(); + + public static SpecialInfo DeleteSpecialInfo(int siteId, int specialId) + { + var specialInfo = GetSpecialInfo(siteId, specialId); + DataProvider.Special.Delete(siteId, specialId); + + return specialInfo; + } + + public static SpecialInfo GetSpecialInfo(int siteId, int specialId) + { + SpecialInfo specialInfo = null; + var specialInfoDictionary = GetSpecialInfoDictionaryBySiteId(siteId); + + if (specialInfoDictionary != null && specialInfoDictionary.ContainsKey(specialId)) + { + specialInfo = specialInfoDictionary[specialId]; + } + return specialInfo; + } + + public static string GetTitle(int siteId, int specialId) + { + var title = string.Empty; + + var specialInfo = GetSpecialInfo(siteId, specialId); + if (specialInfo != null) + { + title = specialInfo.Title; + } + + return title; + } + + public static List GetTemplateInfoList(SiteInfo siteInfo, int specialId) + { + var list = new List(); + + var specialInfo = GetSpecialInfo(siteInfo.Id, specialId); + if (specialInfo != null) + { + var directoryPath = GetSpecialDirectoryPath(siteInfo, specialInfo.Url); + var srcDirectoryPath = GetSpecialSrcDirectoryPath(directoryPath); + + var htmlFilePaths = Directory.GetFiles(srcDirectoryPath, "*.html", SearchOption.AllDirectories); + foreach (var htmlFilePath in htmlFilePaths) + { + var relatedPath = PathUtils.GetPathDifference(srcDirectoryPath, htmlFilePath); + + var templateInfo = new TemplateInfo + { + Content = GetContentByFilePath(htmlFilePath), + CreatedFileExtName = ".html", + CreatedFileFullName = PathUtils.Combine(specialInfo.Url, relatedPath), + Id = 0, + Default = false, + RelatedFileName = string.Empty, + SiteId = siteInfo.Id, + Type = TemplateType.FileTemplate, + TemplateName = relatedPath + }; + + list.Add(templateInfo); + } + } + + return list; + } + + public static List GetAllSpecialIdList(int siteId) + { + var list = new List(); + + var specialInfoDictionary = GetSpecialInfoDictionaryBySiteId(siteId); + if (specialInfoDictionary == null) return list; + + foreach (var specialInfo in specialInfoDictionary.Values) + { + list.Add(specialInfo.Id); + } + + return list; + } + + private static Dictionary GetSpecialInfoDictionaryBySiteId(int siteId, bool flush = false) + { + var dictionary = GetCacheDictionary(); + + Dictionary specialInfoDictionary = null; + + if (!flush && dictionary.ContainsKey(siteId)) + { + specialInfoDictionary = dictionary[siteId]; + } + + if (specialInfoDictionary == null) + { + specialInfoDictionary = DataProvider.Special.GetSpecialInfoDictionaryBySiteId(siteId); + + if (specialInfoDictionary != null) + { + UpdateCache(dictionary, specialInfoDictionary, siteId); + } + } + return specialInfoDictionary; + } + + private static void UpdateCache(Dictionary> dictionary, Dictionary specialInfoDictionary, int siteId) + { + lock (SyncRoot) + { + dictionary[siteId] = specialInfoDictionary; + } + } + + public static void RemoveCache(int siteId) + { + var dictionary = GetCacheDictionary(); + + lock (SyncRoot) + { + dictionary.Remove(siteId); + } + } + + private static Dictionary> GetCacheDictionary() + { + var dictionary = DataCacheManager.Get>>(CacheKey); + if (dictionary != null) return dictionary; + + dictionary = new Dictionary>(); + DataCacheManager.InsertHours(CacheKey, dictionary, 24); + return dictionary; + } + + private static string GetContentByFilePath(string filePath) + { + try + { + var content = DataCacheManager.Get(filePath); + if (content != null) return content; + + if (FileUtils.IsFileExists(filePath)) + { + content = FileUtils.ReadText(filePath, Encoding.UTF8); + } + + DataCacheManager.Insert(filePath, content, TimeSpan.FromHours(12), filePath); + return content; + } + catch + { + return string.Empty; + } + } + + public static string GetSpecialDirectoryPath(SiteInfo siteInfo, string url) + { + var virtualPath = PageUtils.RemoveFileNameFromUrl(url); + return PathUtility.MapPath(siteInfo, virtualPath); + } + + public static string GetSpecialUrl(SiteInfo siteInfo, string url) + { + var virtualPath = PageUtils.RemoveFileNameFromUrl(url); + return PageUtility.ParseNavigationUrl(siteInfo, virtualPath, false); + } + + public static string GetSpecialUrl(SiteInfo siteInfo, int specialId) + { + var specialInfo = GetSpecialInfo(siteInfo.Id, specialId); + return GetSpecialUrl(siteInfo, specialInfo.Url); + } + + public static string GetSpecialZipFilePath(string directoryPath) + { + return PathUtils.Combine(directoryPath, "_src.zip"); + } + + public static string GetSpecialSrcDirectoryPath(string directoryPath) + { + return PathUtils.Combine(directoryPath, "_src"); + } + } +} diff --git a/net452/SiteServer.CMS/Caches/Stl/StlChannelCache.cs b/net452/SiteServer.CMS/Caches/Stl/StlChannelCache.cs new file mode 100644 index 000000000..613b9faee --- /dev/null +++ b/net452/SiteServer.CMS/Caches/Stl/StlChannelCache.cs @@ -0,0 +1,221 @@ +using System.Collections.Generic; +using System.Data; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Caches.Stl +{ + public static class StlChannelCache + { + private static readonly object LockObject = new object(); + + public static void ClearCache() + { + StlCacheManager.Clear(nameof(StlChannelCache)); + } + + public static int GetSiteId(int channelId) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlChannelCache), nameof(GetSiteId), + channelId.ToString()); + var retval = StlCacheManager.GetInt(cacheKey); + if (retval != -1) return retval; + + lock (LockObject) + { + retval = StlCacheManager.GetInt(cacheKey); + if (retval == -1) + { + retval = DataProvider.Channel.GetSiteId(channelId); + StlCacheManager.Set(cacheKey, retval); + } + } + + return retval; + } + + public static int GetSequence(int siteId, int channelId) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlChannelCache), nameof(GetSequence), + siteId.ToString(), channelId.ToString()); + var retval = StlCacheManager.GetInt(cacheKey); + if (retval != -1) return retval; + + lock (LockObject) + { + retval = StlCacheManager.GetInt(cacheKey); + if (retval == -1) + { + retval = DataProvider.Channel.GetSequence(siteId, channelId); + StlCacheManager.Set(cacheKey, retval); + } + } + + return retval; + } + + public static DataSet GetStlDataSourceBySiteId(int siteId, int startNum, int totalNum, string whereString, string orderByString) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlChannelCache), nameof(GetStlDataSourceBySiteId), + siteId.ToString(), startNum.ToString(), totalNum.ToString(), whereString, orderByString); + var retval = StlCacheManager.Get(cacheKey); + if (retval != null) return retval; + + lock (LockObject) + { + retval = StlCacheManager.Get(cacheKey); + if (retval == null) + { + retval = DataProvider.Channel.GetStlDataSourceBySiteId(siteId, startNum, totalNum, whereString, orderByString); + StlCacheManager.Set(cacheKey, retval); + } + } + + return retval; + } + + public static DataSet GetStlDataSet(List channelIdList, int startNum, int totalNum, string whereString, string orderByString) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlChannelCache), nameof(GetStlDataSet), + TranslateUtils.ObjectCollectionToString(channelIdList), startNum.ToString(), totalNum.ToString(), whereString, orderByString); + var retval = StlCacheManager.Get(cacheKey); + if (retval != null) return retval; + + lock (LockObject) + { + retval = StlCacheManager.Get(cacheKey); + if (retval == null) + { + retval = DataProvider.Channel.GetStlDataSet(channelIdList, startNum, totalNum, whereString, orderByString); + StlCacheManager.Set(cacheKey, retval); + } + } + + return retval; + } + + //public static int GetIdByIndexName(int siteId, string channelIndex) + //{ + // var cacheKey = StlCacheManager.GetCacheKey(nameof(StlChannelCache), nameof(GetIdByIndexName), + // siteId.ToString(), channelIndex); + // var retval = StlCacheManager.GetInt(cacheKey); + // if (retval != -1) return retval; + + // lock (LockObject) + // { + // retval = StlCacheManager.GetInt(cacheKey); + // if (retval == -1) + // { + // retval = DataProvider.Channel.GetIdByIndexName(siteId, channelIndex); + // StlCacheManager.Set(cacheKey, retval); + // } + // } + + // return retval; + //} + + public static int GetIdByParentIdAndTaxis(int parentId, int taxis, bool isNextChannel) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlChannelCache), nameof(GetIdByParentIdAndTaxis), + parentId.ToString(), taxis.ToString(), isNextChannel.ToString()); + var retval = StlCacheManager.GetInt(cacheKey); + if (retval != -1) return retval; + + lock (LockObject) + { + retval = StlCacheManager.GetInt(cacheKey); + if (retval == -1) + { + retval = DataProvider.Channel.GetIdByParentIdAndTaxis(parentId, taxis, isNextChannel); + StlCacheManager.Set(cacheKey, retval); + } + } + + return retval; + } + + public static string GetWhereString(int siteId, string groupContent, string groupContentNot, bool isImageExists, bool isImage, string where) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlChannelCache), nameof(GetWhereString), + siteId.ToString(), groupContent, groupContentNot, isImageExists.ToString(), + isImage.ToString(), where); + var retval = StlCacheManager.Get(cacheKey); + if (retval != null) return retval; + + lock (LockObject) + { + retval = StlCacheManager.Get(cacheKey); + if (retval == null) + { + retval = DataProvider.Channel.GetWhereString(groupContent, groupContentNot, + isImageExists, isImage, where); + StlCacheManager.Set(cacheKey, retval); + } + } + + return retval; + } + + public static List GetIdListByTotalNum(List channelIdList, int totalNum, string orderByString, string whereString) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlChannelCache), nameof(GetIdListByTotalNum), + TranslateUtils.ObjectCollectionToString(channelIdList), totalNum.ToString(), orderByString, whereString); + var retval = StlCacheManager.Get>(cacheKey); + if (retval != null) return retval; + + lock (LockObject) + { + retval = StlCacheManager.Get>(cacheKey); + if (retval == null) + { + retval = DataProvider.Channel.GetIdListByTotalNum(channelIdList, totalNum, orderByString, whereString); + StlCacheManager.Set(cacheKey, retval); + } + } + + return retval; + } + + public static ChannelInfo GetChannelInfoByLastAddDate(int channelId) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlChannelCache), nameof(GetChannelInfoByLastAddDate), + channelId.ToString()); + var retval = StlCacheManager.Get(cacheKey); + if (retval != null) return retval; + + lock (LockObject) + { + retval = StlCacheManager.Get(cacheKey); + if (retval == null) + { + retval = DataProvider.Channel.GetChannelInfoByLastAddDate(channelId); + StlCacheManager.Set(cacheKey, retval); + } + } + + return retval; + } + + public static ChannelInfo GetChannelInfoByTaxis(int channelId) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlChannelCache), nameof(GetChannelInfoByTaxis), + channelId.ToString()); + var retval = StlCacheManager.Get(cacheKey); + if (retval != null) return retval; + + lock (LockObject) + { + retval = StlCacheManager.Get(cacheKey); + if (retval == null) + { + retval = DataProvider.Channel.GetChannelInfoByTaxis(channelId); + StlCacheManager.Set(cacheKey, retval); + } + } + + return retval; + } + } +} diff --git a/net452/SiteServer.CMS/Caches/Stl/StlContentCache.cs b/net452/SiteServer.CMS/Caches/Stl/StlContentCache.cs new file mode 100644 index 000000000..79635514c --- /dev/null +++ b/net452/SiteServer.CMS/Caches/Stl/StlContentCache.cs @@ -0,0 +1,328 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Data; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Caches.Stl +{ + public static class StlContentCache + { + private static readonly object LockObject = new object(); + + public static void ClearCache() + { + StlCacheManager.Clear(nameof(StlContentCache)); + } + + public static List GetContentIdListChecked(string tableName, int channelId, string orderByFormatString) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlContentCache), nameof(GetContentIdListChecked), + tableName, channelId.ToString(), orderByFormatString); + var retVal = StlCacheManager.Get>(cacheKey); + if (retVal != null) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.Get>(cacheKey); + if (retVal == null) + { + retVal = DataProvider.ContentRepository.GetContentIdListChecked(tableName, channelId, orderByFormatString); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + + public static DataSet GetStlDataSourceChecked(List channelIdList, string tableName, int startNum, int totalNum, string orderByString, string whereString, NameValueCollection others) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlContentCache), nameof(GetStlDataSourceChecked), + TranslateUtils.ObjectCollectionToString(channelIdList), tableName, startNum.ToString(), totalNum.ToString(), orderByString, whereString, TranslateUtils.NameValueCollectionToString(others)); + var retVal = StlCacheManager.Get(cacheKey); + if (retVal != null) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.Get(cacheKey); + if (retVal == null) + { + retVal = DataProvider.ContentRepository.GetStlDataSourceChecked(channelIdList, tableName, startNum, totalNum, orderByString, whereString, others); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + + public static string GetValue(ChannelInfo channelInfo, int contentId, string type) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlContentCache), nameof(GetValue), channelInfo.Id.ToString(), + contentId.ToString(), type); + var retVal = StlCacheManager.Get(cacheKey); + if (retVal != null) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.Get(cacheKey); + if (retVal == null) + { + var value = channelInfo.ContentRepository.GetValue(contentId, type); + if (value != null) + { + retVal = value; + StlCacheManager.Set(cacheKey, retVal); + } + } + } + + return retVal; + } + + public static int GetSequence(ChannelInfo channelInfo, int contentId) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlContentCache), nameof(GetSequence), + channelInfo.Id.ToString(), contentId.ToString()); + var retVal = StlCacheManager.GetInt(cacheKey); + if (retVal != -1) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.GetInt(cacheKey); + if (retVal == -1) + { + retVal = channelInfo.ContentRepository.GetSequence(channelInfo.Id, contentId); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + + public static int GetCountCheckedImage(int siteId, ChannelInfo channelInfo) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlContentCache), nameof(GetCountCheckedImage), + siteId.ToString(), channelInfo.Id.ToString()); + var retVal = StlCacheManager.GetInt(cacheKey); + if (retVal != -1) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.GetInt(cacheKey); + if (retVal == -1) + { + retVal = channelInfo.ContentRepository.GetCountCheckedImage(siteId, channelInfo.Id); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + + public static int GetCountOfContentAdd(string tableName, int siteId, int channelId, EScopeType scope, + DateTime begin, DateTime end, string userName, ETriState checkedState) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlContentCache), nameof(GetCountOfContentAdd), + siteId.ToString(), channelId.ToString(), EScopeTypeUtils.GetValue(scope), + DateUtils.GetDateString(begin), DateUtils.GetDateString(end), userName, ETriStateUtils.GetValue(checkedState)); + var retVal = StlCacheManager.GetInt(cacheKey); + if (retVal != -1) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.GetInt(cacheKey); + if (retVal == -1) + { + retVal = DataProvider.ContentRepository.GetCountOfContentAdd(tableName, siteId, channelId, scope, + begin, end, userName, checkedState); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + + public static int GetContentId(ChannelInfo channelInfo, int taxis, bool isNextContent) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlContentCache), nameof(GetContentId), channelInfo.Id.ToString(), taxis.ToString(), isNextContent.ToString()); + var retVal = StlCacheManager.GetInt(cacheKey); + if (retVal != -1) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.GetInt(cacheKey); + if (retVal == -1) + { + retVal = channelInfo.ContentRepository.GetContentId(channelInfo.Id, taxis, isNextContent); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + + public static int GetContentId(string tableName, int channelId, string orderByString) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlContentCache), nameof(GetContentId), tableName, + channelId.ToString(), orderByString); + var retVal = StlCacheManager.GetInt(cacheKey); + if (retVal != -1) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.GetInt(cacheKey); + if (retVal == -1) + { + retVal = DataProvider.ContentRepository.GetContentId(tableName, channelId, orderByString); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + + public static int GetChannelId(string tableName, int contentId) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlContentCache), nameof(GetChannelId), tableName, + contentId.ToString()); + var retVal = StlCacheManager.GetInt(cacheKey); + if (retVal != -1) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.GetInt(cacheKey); + if (retVal == -1) + { + retVal = DataProvider.ContentRepository.GetChannelId(tableName, contentId); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + + public static string GetStlWhereString(int siteId, string group, string groupNot, string tags, bool isImageExists, bool isImage, bool isVideoExists, bool isVideo, bool isFileExists, bool isFile, bool isTopExists, bool isTop, bool isRecommendExists, bool isRecommend, bool isHotExists, bool isHot, bool isColorExists, bool isColor, string where) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlContentCache), nameof(GetStlWhereString), + siteId.ToString(), group, groupNot, + tags, isImageExists.ToString(), isImage.ToString(), isVideoExists.ToString(), isVideo.ToString(), + isFileExists.ToString(), isFile.ToString(), isTopExists.ToString(), isTop.ToString(), + isRecommendExists.ToString(), isRecommend.ToString(), isHotExists.ToString(), isHot.ToString(), + isColorExists.ToString(), isColor.ToString(), where); + var retVal = StlCacheManager.Get(cacheKey); + if (retVal != null) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.Get(cacheKey); + if (retVal == null) + { + retVal = DataProvider.ContentRepository.GetStlWhereString(siteId, group, + groupNot, + tags, isImageExists, isImage, isVideoExists, isVideo, isFileExists, isFile, isTopExists, isTop, + isRecommendExists, isRecommend, isHotExists, isHot, isColorExists, isColor, where); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + + public static string GetStlWhereString(int siteId, string group, string groupNot, string tags, bool isTopExists, bool isTop, string where) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlContentCache), nameof(GetStlWhereString), + siteId.ToString(), group, groupNot, tags, isTopExists.ToString(), isTop.ToString(), + where); + var retVal = StlCacheManager.Get(cacheKey); + if (retVal != null) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.Get(cacheKey); + if (retVal == null) + { + retVal = DataProvider.ContentRepository.GetStlWhereString(siteId, group, groupNot, tags, + isTopExists, isTop, where); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + + public static string GetStlSqlStringChecked(string tableName, int siteId, int channelId, int startNum, int totalNum, string orderByString, string whereString, EScopeType scopeType, string groupChannel, string groupChannelNot) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlContentCache), nameof(GetStlSqlStringChecked), + tableName, siteId.ToString(), channelId.ToString(), startNum.ToString(), + totalNum.ToString(), orderByString, whereString, EScopeTypeUtils.GetValue(scopeType), groupChannel, + groupChannelNot); + var retVal = StlCacheManager.Get(cacheKey); + if (retVal != null) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.Get(cacheKey); + if (retVal == null) + { + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + var channelIdList = ChannelManager.GetChannelIdList(channelInfo, scopeType, groupChannel, groupChannelNot, string.Empty); + retVal = DataProvider.ContentRepository.GetStlSqlStringChecked(channelIdList, tableName, siteId, channelId, startNum, + totalNum, orderByString, whereString, scopeType, groupChannel, groupChannelNot); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + + public static string GetStlWhereStringBySearch(string group, string groupNot, bool isImageExists, bool isImage, bool isVideoExists, bool isVideo, bool isFileExists, bool isFile, bool isTopExists, bool isTop, bool isRecommendExists, bool isRecommend, bool isHotExists, bool isHot, bool isColorExists, bool isColor, string where) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlContentCache), nameof(GetStlWhereStringBySearch), group, groupNot, isImageExists.ToString(), isImage.ToString(), + isVideoExists.ToString(), isVideo.ToString(), isFileExists.ToString(), isFile.ToString(), + isTopExists.ToString(), isTop.ToString(), isRecommendExists.ToString(), isRecommend.ToString(), + isHotExists.ToString(), isHot.ToString(), isColorExists.ToString(), isColor.ToString(), where); + var retVal = StlCacheManager.Get(cacheKey); + if (retVal != null) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.Get(cacheKey); + if (retVal == null) + { + retVal = DataProvider.ContentRepository.GetStlWhereStringBySearch(group, groupNot, + isImageExists, isImage, isVideoExists, isVideo, isFileExists, isFile, isTopExists, isTop, + isRecommendExists, isRecommend, isHotExists, isHot, isColorExists, isColor, where); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + + public static string GetStlSqlStringCheckedBySearch(string tableName, int startNum, int totalNum, string orderByString, string whereString) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlContentCache), + nameof(GetStlSqlStringCheckedBySearch), + tableName, startNum.ToString(), totalNum.ToString(), orderByString, whereString); + var retVal = StlCacheManager.Get(cacheKey); + if (retVal != null) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.Get(cacheKey); + if (retVal == null) + { + retVal = DataProvider.ContentRepository.GetStlSqlStringCheckedBySearch(tableName, startNum, totalNum, + orderByString, whereString); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + } +} diff --git a/net452/SiteServer.CMS/Caches/Stl/StlDatabaseCache.cs b/net452/SiteServer.CMS/Caches/Stl/StlDatabaseCache.cs new file mode 100644 index 000000000..5a1b795ef --- /dev/null +++ b/net452/SiteServer.CMS/Caches/Stl/StlDatabaseCache.cs @@ -0,0 +1,112 @@ +using System.Data; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; + +namespace SiteServer.CMS.Caches.Stl +{ + public static class StlDatabaseCache + { + private static readonly object LockObject = new object(); + + public static int GetPageTotalCount(string sqlString) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlDatabaseCache), nameof(GetPageTotalCount), + sqlString); + var retVal = StlCacheManager.GetInt(cacheKey); + if (retVal != -1) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.GetInt(cacheKey); + if (retVal == -1) + { + retVal = DataProvider.DatabaseApi.GetPageTotalCount(sqlString); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + + public static string GetStlPageSqlString(string sqlString, string orderByString, int totalNum, int pageNum, int currentPageIndex) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlDatabaseCache), nameof(GetStlPageSqlString), + sqlString, orderByString, totalNum.ToString(), pageNum.ToString(), currentPageIndex.ToString()); + var retVal = StlCacheManager.Get(cacheKey); + if (retVal != null) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.Get(cacheKey); + if (retVal == null) + { + retVal = DataProvider.DatabaseApi.GetStlPageSqlString(sqlString, orderByString, totalNum, pageNum, + currentPageIndex); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + + public static string GetString(string connectionString, string queryString) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlDatabaseCache), nameof(GetString), + connectionString, queryString); + var retVal = StlCacheManager.Get(cacheKey); + if (retVal != null) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.Get(cacheKey); + if (retVal == null) + { + retVal = DataProvider.DatabaseApi.GetString(connectionString, queryString); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + + public static DataSet GetDataSet(string connectionString, string queryString) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlDatabaseCache), nameof(GetDataSet), + connectionString, queryString); + var retVal = StlCacheManager.Get(cacheKey); + if (retVal != null) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.Get(cacheKey); + if (retVal == null) + { + retVal = DataProvider.DatabaseApi.GetDataSet(connectionString, queryString); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + + public static DataTable GetDataTable(string connectionString, string queryString) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlDatabaseCache), nameof(GetDataTable), + connectionString, queryString); + var retVal = StlCacheManager.Get(cacheKey); + if (retVal != null) return retVal; + + lock (LockObject) + { + retVal = StlCacheManager.Get(cacheKey); + if (retVal == null) + { + retVal = DataProvider.DatabaseApi.GetDataTable(connectionString, queryString); + StlCacheManager.Set(cacheKey, retVal); + } + } + + return retVal; + } + } +} diff --git a/net452/SiteServer.CMS/Caches/Stl/StlSiteCache.cs b/net452/SiteServer.CMS/Caches/Stl/StlSiteCache.cs new file mode 100644 index 000000000..7f18bd4b3 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/Stl/StlSiteCache.cs @@ -0,0 +1,54 @@ +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; + +namespace SiteServer.CMS.Caches.Stl +{ + public static class StlSiteCache + { + private static readonly object LockObject = new object(); + + public static int GetSiteIdByIsRoot() + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlSiteCache), + nameof(GetSiteIdByIsRoot)); + var retval = StlCacheManager.GetInt(cacheKey); + if (retval != -1) return retval; + + lock (LockObject) + { + retval = StlCacheManager.GetInt(cacheKey); + if (retval == -1) + { + retval = DataProvider.Site.GetIdByIsRoot(); + StlCacheManager.Set(cacheKey, retval); + } + } + + return retval; + } + + public static int GetSiteIdBySiteDir(string siteDir) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlSiteCache), + nameof(GetSiteIdBySiteDir), siteDir); + var retval = StlCacheManager.GetInt(cacheKey); + if (retval != -1) return retval; + + lock (LockObject) + { + retval = StlCacheManager.GetInt(cacheKey); + if (retval == -1) + { + retval = + DataProvider.Site.GetIdBySiteDir( + siteDir); + StlCacheManager.Set(cacheKey, retval); + } + } + + return retval; + } + + + } +} diff --git a/net452/SiteServer.CMS/Caches/Stl/StlSqlContentsCache.cs b/net452/SiteServer.CMS/Caches/Stl/StlSqlContentsCache.cs new file mode 100644 index 000000000..3a94f0254 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/Stl/StlSqlContentsCache.cs @@ -0,0 +1,34 @@ +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; + +namespace SiteServer.CMS.Caches.Stl +{ + public static class StlSqlContentsCache + { + private static readonly object LockObject = new object(); + + public static string GetSelectSqlStringByQueryString(string connectionString, string queryString, int startNum, + int totalNum, string orderByString) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlSqlContentsCache), + nameof(GetSelectSqlStringByQueryString), connectionString, queryString, startNum.ToString(), + totalNum.ToString(), orderByString); + var retval = StlCacheManager.Get(cacheKey); + if (retval != null) return retval; + + lock (LockObject) + { + retval = StlCacheManager.Get(cacheKey); + if (retval == null) + { + retval = DataProvider.DatabaseApi.GetSelectSqlStringByQueryString(connectionString, + queryString, startNum, totalNum, orderByString); + StlCacheManager.Set(cacheKey, retval); + } + } + + return retval; + } + } +} diff --git a/net452/SiteServer.CMS/Caches/Stl/StlTagCache.cs b/net452/SiteServer.CMS/Caches/Stl/StlTagCache.cs new file mode 100644 index 000000000..f24e3d47d --- /dev/null +++ b/net452/SiteServer.CMS/Caches/Stl/StlTagCache.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Caches.Stl +{ + public static class StlTagCache + { + private static readonly object LockObject = new object(); + + public static IList GetContentIdListByTagCollection(List tagCollection, int siteId) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlTagCache), + nameof(GetContentIdListByTagCollection), TranslateUtils.ObjectCollectionToString(tagCollection), + siteId.ToString()); + var retval = StlCacheManager.Get>(cacheKey); + if (retval != null) return retval; + + lock (LockObject) + { + retval = StlCacheManager.Get>(cacheKey); + if (retval == null) + { + retval = DataProvider.Tag.GetContentIdListByTagCollection(tagCollection, siteId); + StlCacheManager.Set(cacheKey, retval); + } + } + + return retval; + } + + public static IList GetTagInfoList(int siteId, int contentId, bool isOrderByCount, int totalNum) + { + var cacheKey = StlCacheManager.GetCacheKey(nameof(StlTagCache), + nameof(GetTagInfoList), siteId.ToString(), contentId.ToString(), isOrderByCount.ToString(), totalNum.ToString()); + var retval = StlCacheManager.Get>(cacheKey); + if (retval != null) return retval; + + lock (LockObject) + { + retval = StlCacheManager.Get>(cacheKey); + if (retval == null) + { + retval = DataProvider.Tag.GetTagInfoList(siteId, contentId, isOrderByCount, totalNum); + StlCacheManager.Set(cacheKey, retval); + } + } + + return retval; + } + } +} diff --git a/net452/SiteServer.CMS/Caches/TableColumnManager.cs b/net452/SiteServer.CMS/Caches/TableColumnManager.cs new file mode 100644 index 000000000..f1985059b --- /dev/null +++ b/net452/SiteServer.CMS/Caches/TableColumnManager.cs @@ -0,0 +1,256 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Datory; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.Utils; +using TableColumn = Datory.TableColumn; + +namespace SiteServer.CMS.Caches +{ + public static class TableColumnManager + { + private static class TableColumnManagerCache + { + private static readonly object LockObject = new object(); + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(TableColumnManager)); + //private static readonly FileWatcherClass FileWatcher; + + //static TableColumnManagerCache() + //{ + // FileWatcher = new FileWatcherClass(FileWatcherClass.TableColumn); + // FileWatcher.OnFileChange += FileWatcher_OnFileChange; + //} + + //private static void FileWatcher_OnFileChange(object sender, EventArgs e) + //{ + // CacheManager.Remove(CacheKey); + //} + + public static void Clear() + { + DataCacheManager.Remove(CacheKey); + //FileWatcher.UpdateCacheFile(); + } + + private static void Update(Dictionary> allDict, List list, + string key) + { + lock (LockObject) + { + allDict[key] = list; + } + } + + private static Dictionary> GetAllDictionary() + { + var allDict = DataCacheManager.Get>>(CacheKey); + if (allDict != null) return allDict; + + allDict = new Dictionary>(); + DataCacheManager.InsertHours(CacheKey, allDict, 24); + return allDict; + } + + public static List GetTableColumnInfoListByCache(string tableName) + { + var allDict = GetAllDictionary(); + + allDict.TryGetValue(tableName, out var list); + + if (list != null) return list; + + list = DatoryUtils.GetTableColumns(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName); + Update(allDict, list, tableName); + return list; + } + } + + public static bool CreateTable(string tableName, List tableColumns, string pluginId, bool isContentTable, out Exception ex) + { + ex = null; + + try + { + DatoryUtils.CreateTable(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, + tableColumns); + } + catch (Exception e) + { + ex = e; + LogUtils.AddErrorLog(pluginId, ex, string.Empty); + return false; + } + + if (isContentTable) + { + try + { + DatoryUtils.CreateIndex(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, $"IX_{tableName}_General", $"{ContentAttribute.IsTop} DESC", $"{ContentAttribute.Taxis} DESC", $"{ContentAttribute.Id} DESC"); + + + //sqlString = + // $@"CREATE INDEX {DatorySql.GetQuotedIdentifier(DatabaseType, $"IX_{tableName}_General")} ON {DatorySql.GetQuotedIdentifier(DatabaseType, tableName)}({DatorySql.GetQuotedIdentifier(DatabaseType, ContentAttribute.IsTop)} DESC, {DatorySql.GetQuotedIdentifier(DatabaseType, ContentAttribute.Taxis)} DESC, {DatorySql.GetQuotedIdentifier(DatabaseType, ContentAttribute.Id)} DESC)"; + + //ExecuteNonQuery(ConnectionString, sqlString); + } + catch (Exception e) + { + ex = e; + LogUtils.AddErrorLog(pluginId, ex, string.Empty); + return false; + } + + try + { + DatoryUtils.CreateIndex(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, $"IX_{tableName}_Taxis", $"{ContentAttribute.Taxis} DESC"); + + //sqlString = + // $@"CREATE INDEX {DatorySql.GetQuotedIdentifier(DatabaseType, $"IX_{tableName}_Taxis")} ON {DatorySql.GetQuotedIdentifier(DatabaseType, tableName)}({DatorySql.GetQuotedIdentifier(DatabaseType, ContentAttribute.Taxis)} DESC)"; + + //ExecuteNonQuery(ConnectionString, sqlString); + } + catch (Exception e) + { + ex = e; + LogUtils.AddErrorLog(pluginId, ex, string.Empty); + return false; + } + } + + ClearCache(); + return true; + } + + public static void AlterTable(string tableName, List tableColumns, string pluginId, List dropColumnNames = null) + { + try + { + DatoryUtils.AlterTable(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, + GetRealTableColumns(tableColumns), dropColumnNames); + + ClearCache(); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(pluginId, ex, string.Empty); + } + } + + //public static void DropTable(string tableName) + //{ + // if (DatoryUtils.DropTable(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, out var ex)) + // { + // ClearCache(); + // } + // else + // { + // LogUtils.AddErrorLog(ex); + // } + //} + + private static IList GetRealTableColumns(IEnumerable tableColumns) + { + var realTableColumns = new List(); + foreach (var tableColumn in tableColumns) + { + if (string.IsNullOrEmpty(tableColumn.AttributeName) || StringUtils.EqualsIgnoreCase(tableColumn.AttributeName, nameof(Entity.Id)) || StringUtils.EqualsIgnoreCase(tableColumn.AttributeName, nameof(Entity.Guid)) || StringUtils.EqualsIgnoreCase(tableColumn.AttributeName, nameof(Entity.LastModifiedDate))) + { + continue; + } + + if (tableColumn.DataType == DataType.VarChar && tableColumn.DataLength == 0) + { + tableColumn.DataLength = 2000; + } + realTableColumns.Add(tableColumn); + } + + realTableColumns.InsertRange(0, new List + { + new TableColumn + { + AttributeName = nameof(Entity.Id), + DataType = DataType.Integer, + IsIdentity = true, + IsPrimaryKey = true + }, + new TableColumn + { + AttributeName = nameof(Entity.Guid), + DataType = DataType.VarChar, + DataLength = 50 + }, + new TableColumn + { + AttributeName = nameof(Entity.LastModifiedDate), + DataType = DataType.DateTime + } + }); + + return realTableColumns; + } + + private static List GetTableColumnInfoList(string tableName) + { + return TableColumnManagerCache.GetTableColumnInfoListByCache(tableName); + } + + public static List GetTableColumnInfoList(string tableName, List excludeAttributeNameList) + { + var list = TableColumnManagerCache.GetTableColumnInfoListByCache(tableName); + if (excludeAttributeNameList == null || excludeAttributeNameList.Count == 0) return list; + + return list.Where(tableColumnInfo => + !StringUtils.ContainsIgnoreCase(excludeAttributeNameList, tableColumnInfo.AttributeName)).ToList(); + } + + private static List GetTableColumnInfoList(string tableName, DataType excludeDataType) + { + var list = TableColumnManagerCache.GetTableColumnInfoListByCache(tableName); + + return list.Where(tableColumnInfo => + tableColumnInfo.DataType != excludeDataType).ToList(); + } + + public static TableColumn GetTableColumnInfo(string tableName, string attributeName) + { + var list = TableColumnManagerCache.GetTableColumnInfoListByCache(tableName); + return list.FirstOrDefault(tableColumnInfo => + StringUtils.EqualsIgnoreCase(tableColumnInfo.AttributeName, attributeName)); + } + + public static bool IsAttributeNameExists(string tableName, string attributeName) + { + var list = TableColumnManagerCache.GetTableColumnInfoListByCache(tableName); + return list.Any(tableColumnInfo => + StringUtils.EqualsIgnoreCase(tableColumnInfo.AttributeName, attributeName)); + } + + public static List GetTableColumnNameList(string tableName) + { + var allTableColumnInfoList = GetTableColumnInfoList(tableName); + return allTableColumnInfoList.Select(tableColumnInfo => tableColumnInfo.AttributeName).ToList(); + } + + public static List GetTableColumnNameList(string tableName, List excludeAttributeNameList) + { + var allTableColumnInfoList = GetTableColumnInfoList(tableName, excludeAttributeNameList); + return allTableColumnInfoList.Select(tableColumnInfo => tableColumnInfo.AttributeName).ToList(); + } + + public static List GetTableColumnNameList(string tableName, DataType excludeDataType) + { + var allTableColumnInfoList = GetTableColumnInfoList(tableName, excludeDataType); + return allTableColumnInfoList.Select(tableColumnInfo => tableColumnInfo.AttributeName).ToList(); + } + + public static void ClearCache() + { + TableColumnManagerCache.Clear(); + } + } + +} diff --git a/net452/SiteServer.CMS/Caches/TableStyleManager.cs b/net452/SiteServer.CMS/Caches/TableStyleManager.cs new file mode 100644 index 000000000..3c75453b0 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/TableStyleManager.cs @@ -0,0 +1,511 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Caches +{ + public static class TableStyleManager + { + private static class TableStyleManagerCache + { + private static readonly object LockObject = new object(); + + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(TableStyleManager)); + + public static List> GetAllTableStyles() + { + var retVal = DataCacheManager.Get>>(CacheKey); + if (retVal != null) return retVal; + + lock (LockObject) + { + retVal = DataCacheManager.Get>>(CacheKey); + if (retVal == null) + { + retVal = DataProvider.TableStyle.GetAllTableStyles(); + + DataCacheManager.Insert(CacheKey, retVal); + } + } + + return retVal; + } + + public static void Clear() + { + DataCacheManager.Remove(CacheKey); + } + } + + public static string GetKey(int relatedIdentity, string tableName, string attributeName) + { + return $"{GetKeyPrefix(relatedIdentity, tableName)}{attributeName}".ToLower(); + } + + private static string GetKeyPrefix(int relatedIdentity, string tableName) + { + return $"{relatedIdentity}${tableName}$".ToLower(); + } + + public static List GetStyleInfoList(string tableName, List relatedIdentities) + { + var allAttributeNames = new List(); + var styleInfoList = new List(); + + var entries = TableStyleManagerCache.GetAllTableStyles(); + relatedIdentities = ParseRelatedIdentities(relatedIdentities); + foreach (var relatedIdentity in relatedIdentities) + { + var startKey = GetKeyPrefix(relatedIdentity, tableName); + var list = entries.Where(tuple => tuple.Key.StartsWith(startKey)).ToList(); + foreach (var pair in list) + { + if (pair.IsDefault()) continue; + + if (!allAttributeNames.Contains(pair.Value.AttributeName)) + { + allAttributeNames.Add(pair.Value.AttributeName); + styleInfoList.Add(pair.Value); + } + } + } + + if (tableName == DataProvider.User.TableName || tableName == DataProvider.Channel.TableName || tableName == DataProvider.Site.TableName) + { + if (tableName == DataProvider.User.TableName) + { + foreach (var columnName in UserAttribute.TableStyleAttributes.Value) + { + if (!StringUtils.ContainsIgnoreCase(allAttributeNames, columnName)) + { + allAttributeNames.Add(columnName); + styleInfoList.Add(GetDefaultUserTableStyleInfo(tableName, columnName)); + } + } + } + } + else + { + var columnNames = TableColumnManager.GetTableColumnNameList(tableName, ContentAttribute.MetadataAttributes.Value); + + foreach (var columnName in columnNames) + { + if (!StringUtils.ContainsIgnoreCase(allAttributeNames, columnName)) + { + allAttributeNames.Add(columnName); + styleInfoList.Add(GetDefaultContentTableStyleInfo(tableName, columnName)); + } + } + } + + return styleInfoList.OrderBy(styleInfo => styleInfo.Taxis == 0 ? int.MaxValue : styleInfo.Taxis).ToList(); + } + + public static List GetSiteStyleInfoList(int siteId) + { + var relatedIdentities = GetRelatedIdentities(siteId); + return GetStyleInfoList(DataProvider.Site.TableName, relatedIdentities); + } + + public static List GetChannelStyleInfoList(ChannelInfo channelInfo) + { + var relatedIdentities = GetRelatedIdentities(channelInfo); + return GetStyleInfoList(DataProvider.Channel.TableName, relatedIdentities); + } + + public static List GetContentStyleInfoList(SiteInfo siteInfo, ChannelInfo channelInfo) + { + var relatedIdentities = GetRelatedIdentities(channelInfo); + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + return GetStyleInfoList(tableName, relatedIdentities); + } + + public static List GetUserStyleInfoList() + { + var relatedIdentities = EmptyRelatedIdentities; + return GetStyleInfoList(DataProvider.User.TableName, relatedIdentities); + } + + public static IDictionary GetDefaultAttributes(List styleInfoList) + { + var attributes = new Dictionary(StringComparer.OrdinalIgnoreCase); + + foreach (var styleInfo in styleInfoList) + { + var defaultValue = string.Empty; + if (!string.IsNullOrEmpty(styleInfo.DefaultValue)) + { + defaultValue = styleInfo.DefaultValue; + } + else if (styleInfo.StyleItems != null) + { + var defaultValues = new List(); + foreach (var styleItem in styleInfo.StyleItems) + { + if (styleItem.Selected) + { + defaultValues.Add(styleItem.ItemValue); + } + } + if (defaultValues.Count > 0) + { + defaultValue = TranslateUtils.ObjectCollectionToString(defaultValues); + } + } + + if (!string.IsNullOrEmpty(defaultValue)) + { + attributes[styleInfo.AttributeName] = defaultValue; + } + } + + return attributes; + } + + public static void ClearCache() + { + TableStyleManagerCache.Clear(); + } + + //relatedIdentities从大到小,最后是0 + public static TableStyleInfo GetTableStyleInfo(string tableName, string attributeName, List relatedIdentities) + { + if (attributeName == null) attributeName = string.Empty; + + relatedIdentities = ParseRelatedIdentities(relatedIdentities); + var entries = TableStyleManagerCache.GetAllTableStyles(); + foreach (var relatedIdentity in relatedIdentities) + { + var key = GetKey(relatedIdentity, tableName, attributeName); + var pair = entries.FirstOrDefault(x => x.Key == key && x.Value != null); + if (pair.IsDefault()) continue; + + if (pair.Value != null) + { + return pair.Value; + } + } + + if (tableName == DataProvider.User.TableName || tableName == DataProvider.Channel.TableName || tableName == DataProvider.Site.TableName) + { + if (tableName == DataProvider.User.TableName) + { + return GetDefaultUserTableStyleInfo(tableName, attributeName); + } + } + else + { + return GetDefaultContentTableStyleInfo(tableName, attributeName); + } + + return new TableStyleInfo + { + TableName = tableName, + AttributeName = attributeName, + DisplayName = attributeName, + VisibleInList = false, + Type = InputType.Text, + Horizontal = true + }; + } + + public static TableStyleInfo GetTableStyleInfo(int id) + { + var entries = TableStyleManagerCache.GetAllTableStyles(); + + var entry = entries.FirstOrDefault(x => x.Value != null && x.Value.Id == id); + return entry.IsDefault() ? null : entry.Value; + } + + private static List ParseRelatedIdentities(IReadOnlyCollection list) + { + var relatedIdentities = new List(); + + if (list != null && list.Count > 0) + { + foreach (var i in list) + { + if (!relatedIdentities.Contains(i)) + { + relatedIdentities.Add(i); + } + } + } + + relatedIdentities.Sort(); + relatedIdentities.Reverse(); + + if (!relatedIdentities.Contains(0)) + { + relatedIdentities.Add(0); + } + + return relatedIdentities; + } + + public static bool IsExists(int relatedIdentity, string tableName, string attributeName) + { + var key = GetKey(relatedIdentity, tableName, attributeName); + var entries = TableStyleManagerCache.GetAllTableStyles(); + return entries.Any(x => x.Key == key); + } + + public static Dictionary> GetTableStyleInfoWithItemsDictionary(string tableName, List allRelatedIdentities) + { + var dict = new Dictionary>(); + + var entries = TableStyleManagerCache.GetAllTableStyles(); + foreach (var pair in entries) + { + var arr = pair.Key.Split('$'); + var identityFromKey = TranslateUtils.ToInt(arr[0]); + var tableNameFromKey = arr[1]; + if (!StringUtils.EqualsIgnoreCase(tableNameFromKey, tableName) || + !allRelatedIdentities.Contains(identityFromKey)) continue; + + var styleInfo = pair.Value; + var tableStyleInfoWithItemList = dict.ContainsKey(styleInfo.AttributeName) ? dict[styleInfo.AttributeName] : new List(); + tableStyleInfoWithItemList.Add(styleInfo); + dict[styleInfo.AttributeName] = tableStyleInfoWithItemList; + } + + return dict; + } + + public static string GetValidateInfo(TableStyleInfo styleInfo) + { + var builder = new StringBuilder(); + if (styleInfo.Required) + { + builder.Append("必填项;"); + } + if (styleInfo.MinNum > 0) + { + builder.Append($"最少{styleInfo.MinNum}个字符;"); + } + if (styleInfo.MaxNum > 0) + { + builder.Append($"最多{styleInfo.MaxNum}个字符;"); + } + if (ValidateTypeUtils.Equals(styleInfo.ValidateType, ValidateType.None)) + { + builder.Append($"验证:{ValidateTypeUtils.GetText(ValidateTypeUtils.GetEnumType(styleInfo.ValidateType))};"); + } + + if (builder.Length > 0) + { + builder.Length = builder.Length - 1; + } + else + { + builder.Append("无验证"); + } + return builder.ToString(); + } + + public static List GetRelatedIdentities(int siteId) + { + return new List {siteId, 0}; + } + + public static List GetRelatedIdentities(ChannelInfo channelInfo) + { + var list = new List(); + if (channelInfo != null) + { + var channelIdCollection = "0," + channelInfo.Id; + if (channelInfo.ParentsCount > 0) + { + channelIdCollection = "0," + channelInfo.ParentsPath + "," + channelInfo.Id; + } + + list = TranslateUtils.StringCollectionToIntList(channelIdCollection); + list.Reverse(); + } + else + { + list.Add(0); + } + return list; + } + + public static List EmptyRelatedIdentities => new List {0}; + + private static TableStyleInfo GetDefaultContentTableStyleInfo(string tableName, string attributeName) + { + var styleInfo = new TableStyleInfo + { + TableName = tableName, + AttributeName = attributeName, + DisplayName = attributeName, + VisibleInList = false, + Type = InputType.Text, + Horizontal = true + }; + + if (StringUtils.EqualsIgnoreCase(attributeName, ContentAttribute.Title)) + { + styleInfo.AttributeName = ContentAttribute.Title; + styleInfo.DisplayName = "标题"; + styleInfo.VeeValidate = "required"; + styleInfo.Taxis = 1; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, ContentAttribute.SubTitle)) + { + styleInfo.AttributeName = ContentAttribute.SubTitle; + styleInfo.DisplayName = "副标题"; + styleInfo.Taxis = 2; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, ContentAttribute.ImageUrl)) + { + styleInfo.AttributeName = ContentAttribute.ImageUrl; + styleInfo.DisplayName = "图片"; + styleInfo.Type = InputType.Image; + styleInfo.Taxis = 3; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, ContentAttribute.VideoUrl)) + { + styleInfo.AttributeName = ContentAttribute.VideoUrl; + styleInfo.DisplayName = "视频"; + styleInfo.Type = InputType.Video; + styleInfo.Taxis = 4; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, ContentAttribute.FileUrl)) + { + styleInfo.AttributeName = ContentAttribute.FileUrl; + styleInfo.DisplayName = "附件"; + styleInfo.Type = InputType.File; + styleInfo.Taxis = 5; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, ContentAttribute.Content)) + { + styleInfo.AttributeName = ContentAttribute.Content; + styleInfo.DisplayName = "内容"; + styleInfo.VeeValidate = "required"; + styleInfo.Type = InputType.TextEditor; + styleInfo.Taxis = 6; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, ContentAttribute.Summary)) + { + styleInfo.AttributeName = ContentAttribute.Summary; + styleInfo.DisplayName = "内容摘要"; + styleInfo.Type = InputType.TextArea; + styleInfo.Taxis = 7; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, ContentAttribute.Author)) + { + styleInfo.AttributeName = ContentAttribute.Author; + styleInfo.DisplayName = "作者"; + styleInfo.Taxis = 8; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, ContentAttribute.Source)) + { + styleInfo.AttributeName = ContentAttribute.Source; + styleInfo.DisplayName = "来源"; + styleInfo.Taxis = 9; + } + + return styleInfo; + } + + private static TableStyleInfo GetDefaultUserTableStyleInfo(string tableName, string attributeName) + { + var styleInfo = new TableStyleInfo + { + TableName = tableName, + AttributeName = attributeName, + Taxis = 0, + DisplayName = attributeName, + HelpText = string.Empty, + VisibleInList = false, + Type = InputType.Text, + DefaultValue = string.Empty, + Horizontal = true + }; + + if (StringUtils.EqualsIgnoreCase(attributeName, nameof(UserInfo.DisplayName))) + { + styleInfo.AttributeName = nameof(UserInfo.DisplayName); + styleInfo.DisplayName = "姓名"; + styleInfo.VeeValidate = "required"; + styleInfo.Taxis = 1; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, nameof(UserInfo.Mobile))) + { + styleInfo.AttributeName = nameof(UserInfo.Mobile); + styleInfo.DisplayName = "手机号"; + styleInfo.VeeValidate = "mobile"; + styleInfo.Taxis = 2; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, nameof(UserInfo.Email))) + { + styleInfo.AttributeName = nameof(UserInfo.Email); + styleInfo.DisplayName = "邮箱"; + styleInfo.VeeValidate = "email"; + styleInfo.Taxis = 3; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, nameof(UserInfo.Gender))) + { + styleInfo.AttributeName = nameof(UserInfo.Gender); + styleInfo.DisplayName = "性别"; + styleInfo.Type = InputType.Radio; + styleInfo.StyleItems = new List + { + new TableStyleItemInfo + { + ItemTitle = "男", + ItemValue = "男" + }, + new TableStyleItemInfo + { + ItemTitle = "女", + ItemValue = "女" + } + }; + styleInfo.Taxis = 4; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, nameof(UserInfo.Birthday))) + { + styleInfo.AttributeName = nameof(UserInfo.Birthday); + styleInfo.DisplayName = "出生日期"; + styleInfo.Type = InputType.Date; + styleInfo.Taxis = 5; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, nameof(UserInfo.WeiXin))) + { + styleInfo.AttributeName = nameof(UserInfo.WeiXin); + styleInfo.DisplayName = "微博"; + styleInfo.Taxis = 6; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, nameof(UserInfo.Qq))) + { + styleInfo.AttributeName = nameof(UserInfo.Qq); + styleInfo.DisplayName = "QQ"; + styleInfo.Taxis = 7; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, nameof(UserInfo.WeiBo))) + { + styleInfo.AttributeName = nameof(UserInfo.WeiBo); + styleInfo.DisplayName = "微信"; + styleInfo.Taxis = 8; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, nameof(UserInfo.Bio))) + { + styleInfo.AttributeName = nameof(UserInfo.Bio); + styleInfo.Type = InputType.TextArea; + styleInfo.DisplayName = "个人简介"; + styleInfo.Taxis = 9; + } + + return styleInfo; + } + } + +} diff --git a/SiteServer.CMS/Core/TemplateManager.cs b/net452/SiteServer.CMS/Caches/TemplateManager.cs similarity index 82% rename from SiteServer.CMS/Core/TemplateManager.cs rename to net452/SiteServer.CMS/Caches/TemplateManager.cs index 73636e67d..70eccec82 100644 --- a/SiteServer.CMS/Core/TemplateManager.cs +++ b/net452/SiteServer.CMS/Caches/TemplateManager.cs @@ -1,19 +1,18 @@ using System; -using SiteServer.Utils; -using SiteServer.CMS.Model; using System.Collections.Generic; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; +using SiteServer.Utils; -namespace SiteServer.CMS.Core +namespace SiteServer.CMS.Caches { - public class TemplateManager + public static class TemplateManager { - private TemplateManager() - { - } - - private const string CacheKey = "SiteServer.CMS.Core.TemplateManager"; + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(TemplateManager)); private static readonly object SyncRoot = new object(); public static TemplateInfo GetTemplateInfo(int siteId, int templateId) @@ -63,7 +62,7 @@ public static TemplateInfo GetTemplateInfoByTemplateName(int siteId, TemplateTyp { foreach (var templateInfo in templateInfoDictionary.Values) { - if (templateInfo.TemplateType == templateType && templateInfo.TemplateName == templateName) + if (templateInfo.Type == templateType && templateInfo.TemplateName == templateName) { info = templateInfo; break; @@ -83,7 +82,7 @@ public static TemplateInfo GetDefaultTemplateInfo(int siteId, TemplateType templ { foreach (var templateInfo in templateInfoDictionary.Values) { - if (templateInfo.TemplateType == templateType && templateInfo.IsDefault) + if (templateInfo.Type == templateType && templateInfo.Default) { info = templateInfo; break; @@ -94,7 +93,7 @@ public static TemplateInfo GetDefaultTemplateInfo(int siteId, TemplateType templ return info ?? new TemplateInfo { SiteId = siteId, - TemplateType = templateType + Type = templateType }; } @@ -107,7 +106,7 @@ public static int GetDefaultTemplateId(int siteId, TemplateType templateType) { foreach (var templateInfo in templateInfoDictionary.Values) { - if (templateInfo.TemplateType == templateType && templateInfo.IsDefault) + if (templateInfo.Type == templateType && templateInfo.Default) { id = templateInfo.Id; break; @@ -127,7 +126,7 @@ public static int GetTemplateIdByTemplateName(int siteId, TemplateType templateT { foreach (var templateInfo in templateInfoDictionary.Values) { - if (templateInfo.TemplateType == templateType && templateInfo.TemplateName == templateName) + if (templateInfo.Type == templateType && templateInfo.TemplateName == templateName) { id = templateInfo.Id; break; @@ -147,7 +146,7 @@ public static List GetAllFileTemplateIdList(int siteId) foreach (var templateInfo in templateInfoDictionary.Values) { - if (templateInfo.TemplateType == TemplateType.FileTemplate) + if (templateInfo.Type == TemplateType.FileTemplate) { list.Add(templateInfo.Id); } @@ -169,7 +168,7 @@ private static Dictionary GetTemplateInfoDictionaryBySiteId(i if (templateInfoDictionary == null) { - templateInfoDictionary = DataProvider.TemplateDao.GetTemplateInfoDictionaryBySiteId(siteId); + templateInfoDictionary = DataProvider.Template.GetTemplateInfoDictionaryBySiteId(siteId); if (templateInfoDictionary != null) { @@ -199,11 +198,11 @@ public static void RemoveCache(int siteId) private static Dictionary> GetCacheDictionary() { - var dictionary = CacheUtils.Get(CacheKey) as Dictionary>; + var dictionary = DataCacheManager.Get>>(CacheKey); if (dictionary == null) { dictionary = new Dictionary>(); - CacheUtils.InsertHours(CacheKey, dictionary, 24); + DataCacheManager.InsertHours(CacheKey, dictionary, 24); } return dictionary; } @@ -211,11 +210,11 @@ private static Dictionary> GetCacheDictionary public static string GetTemplateFilePath(SiteInfo siteInfo, TemplateInfo templateInfo) { string filePath; - if (templateInfo.TemplateType == TemplateType.IndexPageTemplate) + if (templateInfo.Type == TemplateType.IndexPageTemplate) { filePath = PathUtils.Combine(WebConfigUtils.PhysicalApplicationPath, siteInfo.SiteDir, templateInfo.RelatedFileName); } - else if (templateInfo.TemplateType == TemplateType.ContentTemplate) + else if (templateInfo.Type == TemplateType.ContentTemplate) { filePath = PathUtils.Combine(WebConfigUtils.PhysicalApplicationPath, siteInfo.SiteDir, DirectoryUtils.PublishmentSytem.Template, DirectoryUtils.PublishmentSytem.Content, templateInfo.RelatedFileName); } @@ -298,25 +297,23 @@ public static void WriteContentToTemplateFile(SiteInfo siteInfo, TemplateInfo te { if (content == null) content = string.Empty; var filePath = GetTemplateFilePath(siteInfo, templateInfo); - FileUtils.WriteText(filePath, templateInfo.Charset, content); + FileUtils.WriteText(filePath, content); if (templateInfo.Id > 0) { - var logInfo = new TemplateLogInfo(0, templateInfo.Id, templateInfo.SiteId, DateTime.Now, administratorName, content.Length, content); - DataProvider.TemplateLogDao.Insert(logInfo); + var logInfo = new TemplateLogInfo + { + TemplateId = templateInfo.Id, + SiteId = templateInfo.SiteId, + AddDate = DateTime.Now, + AddUserName = administratorName, + ContentLength = content.Length, + TemplateContent = content + }; + DataProvider.TemplateLog.Insert(logInfo); } } - public static void UpdateChannelTemplateId(int siteId, int channelId, int channelTemplateId) - { - DataProvider.ChannelDao.UpdateChannelTemplateId(channelId, channelTemplateId); - } - - public static void UpdateContentTemplateId(int siteId, int channelId, int contentTemplateId) - { - DataProvider.ChannelDao.UpdateContentTemplateId(channelId, contentTemplateId); - } - public static int GetIndexTempalteId(int siteId) { return GetDefaultTemplateId(siteId, TemplateType.IndexPageTemplate); @@ -361,28 +358,28 @@ public static int GetContentTempalteId(int siteId, int channelId) public static string GetTemplateContent(SiteInfo siteInfo, TemplateInfo templateInfo) { var filePath = GetTemplateFilePath(siteInfo, templateInfo); - return GetContentByFilePath(filePath, templateInfo.Charset); + return GetContentByFilePath(filePath); } - public static string GetIncludeContent(SiteInfo siteInfo, string file, ECharset charset) + public static string GetIncludeContent(SiteInfo siteInfo, string file) { var filePath = PathUtility.MapPath(siteInfo, PathUtility.AddVirtualToPath(file)); - return GetContentByFilePath(filePath, charset); + return GetContentByFilePath(filePath); } - public static string GetContentByFilePath(string filePath, ECharset charset = ECharset.utf_8) + public static string GetContentByFilePath(string filePath) { try { - if (CacheUtils.Get(filePath) != null) return CacheUtils.Get(filePath) as string; - - var content = string.Empty; + var content = DataCacheManager.Get(filePath); + if (content != null) return content; + if (FileUtils.IsFileExists(filePath)) { - content = FileUtils.ReadText(filePath, charset); + content = FileUtils.ReadText(filePath); } - CacheUtils.Insert(filePath, content, TimeSpan.FromHours(12), filePath); + DataCacheManager.Insert(filePath, content, TimeSpan.FromHours(12), filePath); return content; } catch diff --git a/net452/SiteServer.CMS/Caches/UserGroupManager.cs b/net452/SiteServer.CMS/Caches/UserGroupManager.cs new file mode 100644 index 000000000..204a39a43 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/UserGroupManager.cs @@ -0,0 +1,72 @@ +using System.Collections.Generic; +using System.Linq; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.CMS.Caches +{ + public static class UserGroupManager + { + private static class UserGroupManagerCache + { + private static readonly object LockObject = new object(); + + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(UserGroupManager)); + + public static void Clear() + { + DataCacheManager.Remove(CacheKey); + } + + public static IList GetAllUserGroups() + { + var list = DataCacheManager.Get>(CacheKey); + if (list == null) + { + lock (LockObject) + { + list = DataCacheManager.Get>(CacheKey); + if (list == null) + { + list = DataProvider.UserGroup.GetUserGroupInfoList() ?? new List(); + + DataCacheManager.Insert(CacheKey, list); + } + } + } + + list.Insert(0, new UserGroupInfo + { + Id = 0, + GroupName = "默认用户组", + AdminName = ConfigManager.Instance.UserDefaultGroupAdminName + }); + + return list; + } + } + + public static void ClearCache() + { + UserGroupManagerCache.Clear(); + } + + public static bool IsExists(string groupName) + { + var list = UserGroupManagerCache.GetAllUserGroups(); + return list.Any(group => group.GroupName == groupName); + } + + public static UserGroupInfo GetUserGroupInfo(int groupId) + { + var list = UserGroupManagerCache.GetAllUserGroups(); + return list.FirstOrDefault(group => group.Id == groupId) ?? list[0]; + } + + public static IList GetUserGroupInfoList() + { + return UserGroupManagerCache.GetAllUserGroups(); + } + } +} diff --git a/net452/SiteServer.CMS/Caches/UserManager.cs b/net452/SiteServer.CMS/Caches/UserManager.cs new file mode 100644 index 000000000..e828c6f95 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/UserManager.cs @@ -0,0 +1,359 @@ +using System; +using System.Collections.Generic; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Caches +{ + public static class UserManager + { + private static class UserManagerCache + { + private static readonly object LockObject = new object(); + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(UserManager)); + + public static void Clear() + { + DataCacheManager.Remove(CacheKey); + } + + public static void Update(UserInfo userInfo) + { + if (userInfo == null) return; + + var dict = GetDict(); + + lock (LockObject) + { + dict[GetDictKeyByUserId(userInfo.Id)] = userInfo; + dict[GetDictKeyByUserName(userInfo.UserName)] = userInfo; + if (!string.IsNullOrEmpty(userInfo.Mobile)) + { + dict[GetDictKeyByMobile(userInfo.Mobile)] = userInfo; + } + if (!string.IsNullOrEmpty(userInfo.Email)) + { + dict[GetDictKeyByEmail(userInfo.Email)] = userInfo; + } + } + } + + public static void Remove(UserInfo userInfo) + { + if (userInfo == null) return; + + var dict = GetDict(); + + lock (LockObject) + { + dict.Remove(GetDictKeyByUserId(userInfo.Id)); + dict.Remove(GetDictKeyByUserName(userInfo.UserName)); + if (!string.IsNullOrEmpty(userInfo.Mobile)) + { + dict.Remove(GetDictKeyByMobile(userInfo.Mobile)); + } + + if (!string.IsNullOrEmpty(userInfo.Email)) + { + dict.Remove(GetDictKeyByEmail(userInfo.Email)); + } + } + } + + private static string GetDictKeyByUserId(int userId) + { + return $"userId:{userId}"; + } + + private static string GetDictKeyByUserName(string userName) + { + return $"userName:{userName}"; + } + + private static string GetDictKeyByMobile(string mobile) + { + return $"mobile:{mobile}"; + } + + private static string GetDictKeyByEmail(string email) + { + return $"email:{email}"; + } + + public static UserInfo GetCacheByUserId(int userId) + { + if (userId <= 0) return null; + + var dict = GetDict(); + + dict.TryGetValue(GetDictKeyByUserId(userId), out UserInfo userInfo); + if (userInfo != null) return userInfo; + + lock (LockObject) + { + dict.TryGetValue(GetDictKeyByUserId(userId), out userInfo); + + if (userInfo == null) + { + userInfo = DataProvider.User.GetByUserId(userId); + if (userInfo != null) + { + dict[GetDictKeyByUserId(userInfo.Id)] = userInfo; + dict[GetDictKeyByUserName(userInfo.UserName)] = userInfo; + if (!string.IsNullOrEmpty(userInfo.Mobile)) + { + dict[GetDictKeyByMobile(userInfo.Mobile)] = userInfo; + } + if (!string.IsNullOrEmpty(userInfo.Email)) + { + dict[GetDictKeyByEmail(userInfo.Email)] = userInfo; + } + } + } + } + + return userInfo; + } + + public static UserInfo GetCacheByUserName(string userName) + { + if (string.IsNullOrEmpty(userName)) return null; + + var dict = GetDict(); + + dict.TryGetValue(GetDictKeyByUserName(userName), out UserInfo userInfo); + if (userInfo != null) return userInfo; + + lock (LockObject) + { + dict.TryGetValue(GetDictKeyByUserName(userName), out userInfo); + + if (userInfo == null) + { + userInfo = DataProvider.User.GetByUserName(userName); + if (userInfo != null) + { + dict[GetDictKeyByUserId(userInfo.Id)] = userInfo; + dict[GetDictKeyByUserName(userInfo.UserName)] = userInfo; + if (!string.IsNullOrEmpty(userInfo.Mobile)) + { + dict[GetDictKeyByMobile(userInfo.Mobile)] = userInfo; + } + if (!string.IsNullOrEmpty(userInfo.Email)) + { + dict[GetDictKeyByEmail(userInfo.Email)] = userInfo; + } + } + } + } + + return userInfo; + } + + public static UserInfo GetCacheByMobile(string mobile) + { + if (string.IsNullOrEmpty(mobile)) return null; + + var dict = GetDict(); + + dict.TryGetValue(GetDictKeyByMobile(mobile), out UserInfo userInfo); + if (userInfo != null) return userInfo; + + lock (LockObject) + { + dict.TryGetValue(GetDictKeyByMobile(mobile), out userInfo); + + if (userInfo == null) + { + userInfo = DataProvider.User.GetByMobile(mobile); + if (userInfo != null) + { + dict[GetDictKeyByUserId(userInfo.Id)] = userInfo; + dict[GetDictKeyByUserName(userInfo.UserName)] = userInfo; + if (!string.IsNullOrEmpty(userInfo.Mobile)) + { + dict[GetDictKeyByMobile(userInfo.Mobile)] = userInfo; + } + if (!string.IsNullOrEmpty(userInfo.Email)) + { + dict[GetDictKeyByEmail(userInfo.Email)] = userInfo; + } + } + } + } + + return userInfo; + } + + public static UserInfo GetCacheByEmail(string email) + { + if (string.IsNullOrEmpty(email)) return null; + + var dict = GetDict(); + + dict.TryGetValue(GetDictKeyByEmail(email), out UserInfo userInfo); + if (userInfo != null) return userInfo; + + lock (LockObject) + { + dict.TryGetValue(GetDictKeyByEmail(email), out userInfo); + + if (userInfo == null) + { + userInfo = DataProvider.User.GetByEmail(email); + if (userInfo != null) + { + dict[GetDictKeyByUserId(userInfo.Id)] = userInfo; + dict[GetDictKeyByUserName(userInfo.UserName)] = userInfo; + if (!string.IsNullOrEmpty(userInfo.Mobile)) + { + dict[GetDictKeyByMobile(userInfo.Mobile)] = userInfo; + } + if (!string.IsNullOrEmpty(userInfo.Email)) + { + dict[GetDictKeyByEmail(userInfo.Email)] = userInfo; + } + } + } + } + + return userInfo; + } + + private static Dictionary GetDict() + { + var dict = DataCacheManager.Get>(CacheKey); + if (dict != null) return dict; + + lock (LockObject) + { + dict = DataCacheManager.Get>(CacheKey); + if (dict == null) + { + dict = new Dictionary(); + DataCacheManager.Insert(CacheKey, dict); + } + } + + return dict; + } + } + + public static void ClearCache() + { + UserManagerCache.Clear(); + } + + public static void UpdateCache(UserInfo userInfo) + { + UserManagerCache.Update(userInfo); + } + + public static void RemoveCache(UserInfo userInfo) + { + UserManagerCache.Remove(userInfo); + } + + public static UserInfo GetUserInfoByUserId(int userId) + { + return UserManagerCache.GetCacheByUserId(userId); + } + + public static UserInfo GetUserInfoByUserName(string userName) + { + return UserManagerCache.GetCacheByUserName(userName); + } + + public static UserInfo GetUserInfoByMobile(string mobile) + { + return UserManagerCache.GetCacheByMobile(mobile); + } + + public static UserInfo GetUserInfoByEmail(string email) + { + return UserManagerCache.GetCacheByEmail(email); + } + + public static UserInfo GetUserInfoByAccount(string account) + { + if (string.IsNullOrEmpty(account)) return null; + + if (StringUtils.IsMobile(account)) + { + return GetUserInfoByMobile(account); + } + if (StringUtils.IsEmail(account)) + { + return GetUserInfoByEmail(account); + } + + return GetUserInfoByUserName(account); + } + + public static bool IsIpAddressCached(string ipAddress) + { + if (ConfigManager.Instance.UserRegistrationMinMinutes == 0 || string.IsNullOrEmpty(ipAddress)) + { + return true; + } + var obj = CacheUtils.Get($"SiteServer.CMS.Provider.User.InsertObject.IpAddress.{ipAddress}"); + return obj == null; + } + + public static void CacheIpAddress(string ipAddress) + { + if (ConfigManager.Instance.UserRegistrationMinMinutes > 0 && !string.IsNullOrEmpty(ipAddress)) + { + CacheUtils.InsertMinutes($"SiteServer.CMS.Provider.User.InsertObject.IpAddress.{ipAddress}", ipAddress, ConfigManager.Instance.UserRegistrationMinMinutes); + } + } + + public static string GetHomeUploadPath(params string[] paths) + { + + var path = FxUtils.GetSiteFilesPath(DirectoryUtils.SiteFiles.Home, PathUtils.Combine(paths)); + DirectoryUtils.CreateDirectoryIfNotExists(path); + return path; + } + + public static string GetUserUploadPath(int userId, string relatedPath) + { + return GetHomeUploadPath(userId.ToString(), relatedPath); + } + + public static string GetUserUploadFileName(string filePath) + { + var dt = DateTime.Now; + return $"{dt.Day}{dt.Hour}{dt.Minute}{dt.Second}{dt.Millisecond}{PathUtils.GetExtension(filePath)}"; + } + + public static string GetHomeUploadUrl(params string[] paths) + { + return FxUtils.GetSiteFilesUrl(PageUtils.Combine(DirectoryUtils.SiteFiles.Home, PageUtils.Combine(paths))); + } + + public static string DefaultAvatarUrl => GetHomeUploadUrl("default_avatar.png"); + + public static string GetUserUploadUrl(int userId, string relatedUrl) + { + return GetHomeUploadUrl(userId.ToString(), relatedUrl); + } + + public static string GetUserAvatarUrl(UserInfo userInfo) + { + var imageUrl = userInfo?.AvatarUrl; + + if (!string.IsNullOrEmpty(imageUrl)) + { + return PageUtils.IsProtocolUrl(imageUrl) ? imageUrl : GetUserUploadUrl(userInfo.Id, imageUrl); + } + + return DefaultAvatarUrl; + } + } +} diff --git a/net452/SiteServer.CMS/Caches/UserMenuManager .cs b/net452/SiteServer.CMS/Caches/UserMenuManager .cs new file mode 100644 index 000000000..af6ebb5c3 --- /dev/null +++ b/net452/SiteServer.CMS/Caches/UserMenuManager .cs @@ -0,0 +1,122 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.CMS.Caches +{ + public static class UserMenuManager + { + private static class UserMenuManagerCache + { + private static readonly object LockObject = new object(); + + private static readonly string CacheKey = DataCacheManager.GetCacheKey(nameof(UserMenuManager)); + + public static void Clear() + { + DataCacheManager.Remove(CacheKey); + } + + public static List GetAllUserMenus() + { + var retval = DataCacheManager.Get>(CacheKey); + if (retval != null) return retval; + + lock (LockObject) + { + retval = DataCacheManager.Get>(CacheKey); + if (retval == null) + { + retval = DataProvider.UserMenu.GetUserMenuInfoList(); + + DataCacheManager.Insert(CacheKey, retval); + } + } + + return retval; + } + } + + public static void ClearCache() + { + UserMenuManagerCache.Clear(); + } + + public static UserMenuInfo GetUserMenuInfo(int menuId) + { + var list = UserMenuManagerCache.GetAllUserMenus(); + return list.FirstOrDefault(menu => menu.Id == menuId); + } + + public static List GetAllUserMenuInfoList() + { + return UserMenuManagerCache.GetAllUserMenus(); + } + + private const string Dashboard = nameof(Dashboard); + private const string ContentAdd = nameof(ContentAdd); + private const string Contents = nameof(Contents); + private const string Return = nameof(Return); + + public static readonly Lazy>>> SystemMenus = + new Lazy>>>(() => + new List>> + { + new KeyValuePair>(new UserMenuInfo + { + Id = 0, + SystemId = Dashboard, + GroupIdCollection = string.Empty, + Disabled = false, + ParentId = 0, + Taxis = 1, + Text = "用户中心", + IconClass = "fa fa-home", + Href = "index.html", + Target = "_top" + }, null), + new KeyValuePair>(new UserMenuInfo + { + Id = 0, + SystemId = ContentAdd, + GroupIdCollection = string.Empty, + Disabled = false, + ParentId = 0, + Taxis = 2, + Text = "新增稿件", + IconClass = "fa fa-plus", + Href = "pages/contentAdd.html", + Target = "_self" + }, null), + new KeyValuePair>(new UserMenuInfo + { + Id = 0, + SystemId = Contents, + GroupIdCollection = string.Empty, + Disabled = false, + ParentId = 0, + Taxis = 3, + Text = "稿件管理", + IconClass = "fa fa-list", + Href = "pages/contents.html", + Target = "_self" + }, null), + new KeyValuePair>(new UserMenuInfo + { + Id = 0, + SystemId = Return, + GroupIdCollection = string.Empty, + Disabled = false, + ParentId = 0, + Taxis = 4, + Text = "返回网站", + IconClass = "fa fa-arrow-left", + Href = "/", + Target = "_top" + }, null) + }); + } +} diff --git a/net452/SiteServer.CMS/Core/AdminPagesUtils.cs b/net452/SiteServer.CMS/Core/AdminPagesUtils.cs new file mode 100644 index 000000000..a1dc609c5 --- /dev/null +++ b/net452/SiteServer.CMS/Core/AdminPagesUtils.cs @@ -0,0 +1,58 @@ +using System.Linq; +using SiteServer.CMS.Fx; +using SiteServer.Utils; + +namespace SiteServer.CMS.Core +{ + public static class AdminPagesUtils + { + public static string DashboardUrl => FxUtils.GetAdminUrl("dashboard.cshtml"); + public static string ErrorUrl => FxUtils.GetAdminUrl("error.cshtml"); + public static string MainUrl => FxUtils.GetAdminUrl("main.cshtml"); + public static string LoginUrl => FxUtils.GetAdminUrl("login.cshtml"); + public static string LogoutUrl => FxUtils.GetAdminUrl("logout.cshtml"); + public static string UpdateUrl => FxUtils.GetAdminUrl("update.cshtml"); + public static string UpgradeUrl => FxUtils.GetAdminUrl("upgrade.cshtml"); + public static string LoadingUrl => FxUtils.GetAdminUrl("loading.cshtml"); + + public static class Plugins + { + private const string DirectoryName = nameof(Plugins); + + public static string ManageUrl => FxUtils.GetAdminUrl(PageUtils.Combine(DirectoryName, "manage.cshtml")); + } + + public static class Settings + { + private const string DirectoryName = nameof(Settings); + + public static string AdministratorsUrl => FxUtils.GetAdminUrl(PageUtils.Combine(DirectoryName, "administrators.cshtml")); + + public static string SiteAddUrl => FxUtils.GetAdminUrl(PageUtils.Combine(DirectoryName, "siteAdd.cshtml")); + } + + public static class Cms + { + private const string DirectoryName = nameof(Cms); + + private static string GetUrl(string pageName, int siteId, object param = null) + { + var url = FxUtils.GetAdminUrl(PageUtils.Combine(DirectoryName, $"{pageName}?siteId={siteId}")); + return param == null ? url : param.GetType().GetProperties().Aggregate(url, (current, p) => current + $"&{p.Name.ToCamelCase()}={p.GetValue(param)}"); + } + + public static string GetContentsUrl(int siteId, int channelId) + { + return GetUrl("contents.cshtml", siteId, new + { + channelId + }); + } + + public static string GetCreateStatusUrl(int siteId) + { + return GetUrl("createStatus.cshtml", siteId); + } + } + } +} diff --git a/net452/SiteServer.CMS/Core/AuthenticatedRequest.cs b/net452/SiteServer.CMS/Core/AuthenticatedRequest.cs new file mode 100644 index 000000000..528a41fc6 --- /dev/null +++ b/net452/SiteServer.CMS/Core/AuthenticatedRequest.cs @@ -0,0 +1,229 @@ +using System; +using System.Net.Http; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Core +{ + internal class AuthenticatedRequest: IAuthenticatedRequest + { + private readonly HttpRequestMessage _request; + + public AuthenticatedRequest(HttpRequestMessage request) + { + _request = request; + + try + { + var apiToken = request.GetApiToken(); + if (!string.IsNullOrEmpty(apiToken)) + { + var tokenInfo = AccessTokenManager.GetAccessTokenInfo(apiToken); + if (tokenInfo != null) + { + if (!string.IsNullOrEmpty(tokenInfo.AdminName)) + { + var adminInfo = AdminManager.GetAdminInfoByUserName(tokenInfo.AdminName); + if (adminInfo != null && !adminInfo.Locked) + { + AdminInfo = adminInfo; + IsAdminLoggin = true; + } + } + + IsApiAuthenticated = true; + } + } + + var userToken = request.GetUserToken(); + if (!string.IsNullOrEmpty(userToken)) + { + var tokenImpl = UserApi.Instance.ParseAccessToken(userToken); + if (tokenImpl.UserId > 0 && !string.IsNullOrEmpty(tokenImpl.UserName)) + { + var userInfo = UserManager.GetUserInfoByUserId(tokenImpl.UserId); + if (userInfo != null && !userInfo.Locked && userInfo.Checked && userInfo.UserName == tokenImpl.UserName) + { + UserInfo = userInfo; + IsUserLoggin = true; + } + } + } + + var adminToken = request.GetAdminToken(); + if (!string.IsNullOrEmpty(adminToken)) + { + var tokenImpl = AdminApi.Instance.ParseAccessToken(adminToken); + if (tokenImpl.UserId > 0 && !string.IsNullOrEmpty(tokenImpl.UserName)) + { + var adminInfo = AdminManager.GetAdminInfoByUserId(tokenImpl.UserId); + if (adminInfo != null && !adminInfo.Locked && adminInfo.UserName == tokenImpl.UserName) + { + AdminInfo = adminInfo; + IsAdminLoggin = true; + } + } + } + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + } + } + + public bool IsApiAuthenticated { get; } + + public bool IsUserLoggin { get; } + + public bool IsAdminLoggin { get; private set; } + + private PermissionsImpl _userPermissionsImpl; + + private PermissionsImpl UserPermissionsImpl + { + get + { + if (_userPermissionsImpl != null) return _userPermissionsImpl; + + if (UserInfo != null) + { + var groupInfo = UserGroupManager.GetUserGroupInfo(UserInfo.GroupId); + if (groupInfo != null) + { + AdminInfo = AdminManager.GetAdminInfoByUserName(groupInfo.AdminName); + } + } + + _userPermissionsImpl = new PermissionsImpl(AdminInfo); + + return _userPermissionsImpl; + } + } + + public IPermissions UserPermissions => UserPermissionsImpl; + + private PermissionsImpl _adminPermissionsImpl; + + private PermissionsImpl AdminPermissionsImpl + { + get + { + if (_adminPermissionsImpl != null) return _adminPermissionsImpl; + + _adminPermissionsImpl = new PermissionsImpl(AdminInfo); + + return _adminPermissionsImpl; + } + } + + public IPermissions AdminPermissions => AdminPermissionsImpl; + + public int AdminId => AdminInfo?.Id ?? 0; + + public string AdminName + { + get + { + if (AdminInfo != null) + { + return AdminInfo.UserName; + } + + if (UserInfo != null) + { + var groupInfo = UserGroupManager.GetUserGroupInfo(UserInfo.GroupId); + if (groupInfo != null) + { + return groupInfo.AdminName; + } + } + + return string.Empty; + } + } + + private AdministratorInfo AdminInfo { get; set; } + + public string AdminLogin(string userName, bool isAutoLogin) + { + if (string.IsNullOrEmpty(userName)) return null; + var adminInfo = AdminManager.GetAdminInfoByUserName(userName); + if (adminInfo == null || adminInfo.Locked) return null; + + AdminInfo = adminInfo; + IsAdminLoggin = true; + + var expiresAt = TimeSpan.FromDays(Constants.AccessTokenExpireDays); + var accessToken = AdminApi.Instance.GetAccessToken(adminInfo.Id, adminInfo.UserName, expiresAt); + + LogUtils.AddAdminLog(adminInfo.UserName, "管理员登录"); + + if (isAutoLogin) + { + CookieUtils.SetCookie(Constants.AuthKeyAdminCookie, accessToken, expiresAt); + } + else + { + CookieUtils.SetCookie(Constants.AuthKeyAdminCookie, accessToken); + } + + return accessToken; + } + + public void AdminLogout() + { + if (IsAdminLoggin) + { + PermissionsImpl.ClearAllCache(); + AdminManager.RemoveCache(AdminInfo); + } + + CookieUtils.Erase(Constants.AuthKeyAdminCookie); + } + + public int UserId => UserInfo?.Id ?? 0; + + public string UserName => UserInfo?.UserName ?? string.Empty; + + private UserInfo UserInfo { get; set; } + + public string UserLogin(string userName, bool isAutoLogin) + { + if (string.IsNullOrEmpty(userName)) return null; + + var userInfo = UserManager.GetUserInfoByUserName(userName); + if (userInfo == null || userInfo.Locked || !userInfo.Checked) return null; + + UserInfo = userInfo; + + var expiresAt = TimeSpan.FromDays(Constants.AccessTokenExpireDays); + var accessToken = UserApi.Instance.GetAccessToken(UserId, UserName, expiresAt); + + DataProvider.User.UpdateLastActivityDateAndCountOfLogin(UserInfo); + LogUtils.AddUserLoginLog(userName); + + if (isAutoLogin) + { + CookieUtils.SetCookie(Constants.AuthKeyUserCookie, accessToken, expiresAt); + } + else + { + CookieUtils.SetCookie(Constants.AuthKeyUserCookie, accessToken); + } + + return accessToken; + } + + public void UserLogout() + { + UserInfo = null; + CookieUtils.Erase(Constants.AuthKeyUserCookie); + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Core/CacheDbUtils.cs b/net452/SiteServer.CMS/Core/CacheDbUtils.cs new file mode 100644 index 000000000..f94902dd3 --- /dev/null +++ b/net452/SiteServer.CMS/Core/CacheDbUtils.cs @@ -0,0 +1,41 @@ +using SiteServer.CMS.Database.Core; + +namespace SiteServer.CMS.Core +{ + public static class CacheDbUtils + { + public static void RemoveAndInsert(string cacheKey, string cacheValue) + { + if (!string.IsNullOrEmpty(cacheKey)) + { + DataProvider.DbCache.RemoveAndInsert(cacheKey, cacheValue); + } + } + + public static void Clear() + { + DataProvider.DbCache.Clear(); + } + + public static bool IsExists(string cacheKey) + { + return DataProvider.DbCache.IsExists(cacheKey); + } + + public static string GetValue(string cacheKey) + { + return DataProvider.DbCache.GetValue(cacheKey); + } + + public static string GetValueAndRemove(string cacheKey) + { + return DataProvider.DbCache.GetValueAndRemove(cacheKey); + } + + public static int GetCount() + { + return DataProvider.DbCache.GetCount(); + } + + } +} diff --git a/net452/SiteServer.CMS/Core/CheckManager.cs b/net452/SiteServer.CMS/Core/CheckManager.cs new file mode 100644 index 000000000..680e7821d --- /dev/null +++ b/net452/SiteServer.CMS/Core/CheckManager.cs @@ -0,0 +1,588 @@ +using System.Collections.Generic; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Core +{ + public static class CheckManager + { + public static class LevelInt + { + public const int CaoGao = -99;//草稿 + public const int DaiShen = 0;//待审 + + public const int Pass1 = 1;//初审通过 + public const int Pass2 = 2;//二审通过 + public const int Pass3 = 3;//三审通过 + public const int Pass4 = 4;//四审通过 + public const int Pass5 = 5;//终审通过 + + public const int Fail1 = -1;//初审退稿 + public const int Fail2 = -2;//二审退稿 + public const int Fail3 = -3;//三审退稿 + public const int Fail4 = -4;//四审退稿 + public const int Fail5 = -5;//终审退稿 + + public const int NotChange = -100;//保持不变 + public const int All = -200;//全部 + } + + public static class Level + { + public const string All = "全部";//全部 + public const string CaoGao = "草稿";//草稿 + public const string DaiShen = "待审核";//待审 + public const string YiShenHe = "已审核";//已审核 + + public const string NotChange = "保持不变";//保持不变 + } + + public static class Level5 + { + public const string Pass1 = "初审通过,等待二审"; + public const string Pass2 = "二审通过,等待三审"; + public const string Pass3 = "三审通过,等待四审"; + public const string Pass4 = "四审通过,等待终审"; + public const string Pass5 = "终审通过"; + + public const string Fail1 = "初审退稿"; + public const string Fail2 = "二审退稿"; + public const string Fail3 = "三审退稿"; + public const string Fail4 = "四审退稿"; + public const string Fail5 = "终审退稿"; + } + + public static class Level4 + { + public const string Pass1 = "初审通过,等待二审"; + public const string Pass2 = "二审通过,等待三审"; + public const string Pass3 = "三审通过,等待终审"; + public const string Pass4 = "终审通过"; + + public const string Fail1 = "初审退稿"; + public const string Fail2 = "二审退稿"; + public const string Fail3 = "三审退稿"; + public const string Fail4 = "终审退稿"; + } + + public static class Level3 + { + public const string Pass1 = "初审通过,等待二审"; + public const string Pass2 = "二审通过,等待终审"; + public const string Pass3 = "终审通过"; + + public const string Fail1 = "初审退稿"; + public const string Fail2 = "二审退稿"; + public const string Fail3 = "终审退稿"; + } + + public static class Level2 + { + public const string Pass1 = "初审通过,等待终审"; + public const string Pass2 = "终审通过"; + + public const string Fail1 = "初审退稿"; + public const string Fail2 = "终审退稿"; + } + + public static class Level1 + { + public const string Pass1 = "终审通过"; + + public const string Fail1 = "终审退稿"; + } + + public static List> GetCheckedLevels(SiteInfo siteInfo, bool isChecked, int checkedLevel, bool includeFail) + { + var checkedLevels = new List>(); + + var checkContentLevel = siteInfo.CheckContentLevel; + if (isChecked) + { + checkedLevel = checkContentLevel; + } + + checkedLevels.Add(new KeyValuePair(LevelInt.CaoGao, Level.CaoGao)); + checkedLevels.Add(new KeyValuePair(LevelInt.DaiShen, Level.DaiShen)); + + if (checkContentLevel == 0 || checkContentLevel == 1) + { + if (isChecked) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Pass1, Level1.Pass1)); + } + } + else if (checkContentLevel == 2) + { + if (checkedLevel >= 1) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Pass1, Level2.Pass1)); + } + + if (isChecked) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Pass2, Level2.Pass2)); + } + } + else if (checkContentLevel == 3) + { + if (checkedLevel >= 1) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Pass1, Level3.Pass1)); + } + + if (checkedLevel >= 2) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Pass2, Level3.Pass2)); + } + + if (isChecked) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Pass3, Level3.Pass3)); + } + } + else if (checkContentLevel == 4) + { + if (checkedLevel >= 1) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Pass1, Level4.Pass1)); + } + + if (checkedLevel >= 2) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Pass2, Level4.Pass2)); + } + + if (checkedLevel >= 3) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Pass3, Level4.Pass3)); + } + + if (isChecked) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Pass4, Level4.Pass4)); + } + } + else if (checkContentLevel == 5) + { + if (checkedLevel >= 1) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Pass1, Level5.Pass1)); + } + + if (checkedLevel >= 2) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Pass2, Level5.Pass2)); + } + + if (checkedLevel >= 3) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Pass3, Level5.Pass3)); + } + + if (checkedLevel >= 4) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Pass4, Level5.Pass4)); + } + + if (isChecked) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Pass5, Level5.Pass5)); + } + } + + if (includeFail) + { + if (checkContentLevel == 1) + { + if (isChecked) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Fail1, Level1.Fail1)); + } + } + else if (checkContentLevel == 2) + { + if (checkedLevel >= 1) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Fail1, Level2.Fail1)); + } + + if (isChecked) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Fail2, Level2.Fail2)); + } + } + else if (checkContentLevel == 3) + { + if (checkedLevel >= 1) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Fail1, Level3.Fail1)); + } + + if (checkedLevel >= 2) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Fail2, Level3.Fail2)); + } + + if (isChecked) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Fail3, Level3.Fail3)); + } + } + else if (checkContentLevel == 4) + { + if (checkedLevel >= 1) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Fail1, Level4.Fail1)); + } + + if (checkedLevel >= 2) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Fail2, Level4.Fail2)); + } + + if (checkedLevel >= 3) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Fail3, Level4.Fail3)); + } + + if (isChecked) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Fail4, Level4.Fail4)); + } + } + else if (checkContentLevel == 5) + { + if (checkedLevel >= 1) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Fail1, Level5.Fail1)); + } + + if (checkedLevel >= 2) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Fail2, Level5.Fail2)); + } + + if (checkedLevel >= 3) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Fail3, Level5.Fail3)); + } + + if (checkedLevel >= 4) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Fail4, Level5.Fail4)); + } + + if (isChecked) + { + checkedLevels.Add(new KeyValuePair(LevelInt.Fail5, Level5.Fail5)); + } + } + } + + return checkedLevels; + } + + public static string GetCheckState(SiteInfo siteInfo, ContentInfo contentInfo) + { + if (contentInfo.Checked) + { + return Level.YiShenHe; + } + + var retval = string.Empty; + + if (contentInfo.CheckedLevel == LevelInt.CaoGao) + { + retval = Level.CaoGao; + } + else if (contentInfo.CheckedLevel == LevelInt.DaiShen) + { + retval = Level.DaiShen; + } + else + { + var checkContentLevel = siteInfo.CheckContentLevel; + + if (checkContentLevel == 1) + { + if (contentInfo.CheckedLevel == LevelInt.Fail1) + { + retval = Level1.Fail1; + } + } + else if (checkContentLevel == 2) + { + if (contentInfo.CheckedLevel == LevelInt.Pass1) + { + retval = Level2.Pass1; + } + else if (contentInfo.CheckedLevel == LevelInt.Fail1) + { + retval = Level2.Fail1; + } + else if (contentInfo.CheckedLevel == LevelInt.Fail2) + { + retval = Level2.Fail2; + } + } + else if (checkContentLevel == 3) + { + if (contentInfo.CheckedLevel == LevelInt.Pass1) + { + retval = Level3.Pass1; + } + else if (contentInfo.CheckedLevel == LevelInt.Pass2) + { + retval = Level3.Pass2; + } + else if (contentInfo.CheckedLevel == LevelInt.Fail1) + { + retval = Level3.Fail1; + } + else if (contentInfo.CheckedLevel == LevelInt.Fail2) + { + retval = Level3.Fail2; + } + else if (contentInfo.CheckedLevel == LevelInt.Fail3) + { + retval = Level3.Fail3; + } + } + else if (checkContentLevel == 4) + { + if (contentInfo.CheckedLevel == LevelInt.Pass1) + { + retval = Level4.Pass1; + } + else if (contentInfo.CheckedLevel == LevelInt.Pass2) + { + retval = Level4.Pass2; + } + else if (contentInfo.CheckedLevel == LevelInt.Pass3) + { + retval = Level4.Pass3; + } + else if (contentInfo.CheckedLevel == LevelInt.Fail1) + { + retval = Level4.Fail1; + } + else if (contentInfo.CheckedLevel == LevelInt.Fail2) + { + retval = Level4.Fail2; + } + else if (contentInfo.CheckedLevel == LevelInt.Fail3) + { + retval = Level4.Fail3; + } + else if (contentInfo.CheckedLevel == LevelInt.Fail4) + { + retval = Level4.Fail4; + } + } + else if (checkContentLevel == 5) + { + if (contentInfo.CheckedLevel == LevelInt.Pass1) + { + retval = Level5.Pass1; + } + else if (contentInfo.CheckedLevel == LevelInt.Pass2) + { + retval = Level5.Pass2; + } + else if (contentInfo.CheckedLevel == LevelInt.Pass3) + { + retval = Level5.Pass3; + } + else if (contentInfo.CheckedLevel == LevelInt.Pass4) + { + retval = Level5.Pass4; + } + else if (contentInfo.CheckedLevel == LevelInt.Fail1) + { + retval = Level5.Fail1; + } + else if (contentInfo.CheckedLevel == LevelInt.Fail2) + { + retval = Level5.Fail2; + } + else if (contentInfo.CheckedLevel == LevelInt.Fail3) + { + retval = Level5.Fail3; + } + else if (contentInfo.CheckedLevel == LevelInt.Fail4) + { + retval = Level5.Fail4; + } + else if (contentInfo.CheckedLevel == LevelInt.Fail5) + { + retval = Level5.Fail5; + } + } + + if (string.IsNullOrEmpty(retval)) + { + if (checkContentLevel == 1) + { + retval = Level.DaiShen; + } + else if (checkContentLevel == 2) + { + retval = Level2.Pass1; + } + else if (checkContentLevel == 3) + { + retval = Level3.Pass2; + } + else if (checkContentLevel == 4) + { + retval = Level4.Pass3; + } + } + } + + return retval; + } + + public static bool IsCheckable(bool contentIsChecked, int contentCheckLevel, bool isChecked, int checkedLevel) + { + if (isChecked || checkedLevel >= 5) + { + return true; + } + if (contentIsChecked) + { + return false; + } + if (checkedLevel == 0) + { + return false; + } + if (checkedLevel == 1) + { + if (contentCheckLevel == LevelInt.CaoGao || contentCheckLevel == LevelInt.DaiShen || contentCheckLevel == LevelInt.Pass1 || contentCheckLevel == LevelInt.Fail1) + { + return true; + } + return false; + } + if (checkedLevel == 2) + { + if (contentCheckLevel == LevelInt.CaoGao || contentCheckLevel == LevelInt.DaiShen || contentCheckLevel == LevelInt.Pass1 || contentCheckLevel == LevelInt.Pass2 || contentCheckLevel == LevelInt.Fail1 || contentCheckLevel == LevelInt.Fail2) + { + return true; + } + return false; + } + if (checkedLevel == 3) + { + if (contentCheckLevel == LevelInt.CaoGao || contentCheckLevel == LevelInt.DaiShen || contentCheckLevel == LevelInt.Pass1 || contentCheckLevel == LevelInt.Pass2 || contentCheckLevel == LevelInt.Pass3 || contentCheckLevel == LevelInt.Fail1 || contentCheckLevel == LevelInt.Fail2 || contentCheckLevel == LevelInt.Fail3) + { + return true; + } + return false; + } + if (checkedLevel == 4) + { + if (contentCheckLevel == LevelInt.CaoGao || contentCheckLevel == LevelInt.DaiShen || contentCheckLevel == LevelInt.Pass1 || contentCheckLevel == LevelInt.Pass2 || contentCheckLevel == LevelInt.Pass3 || contentCheckLevel == LevelInt.Pass4 || contentCheckLevel == LevelInt.Fail1 || contentCheckLevel == LevelInt.Fail2 || contentCheckLevel == LevelInt.Fail3 || contentCheckLevel == LevelInt.Fail4) + { + return true; + } + return false; + } + + return false; + } + + public static KeyValuePair GetUserCheckLevel(IPermissions permissionsImpl, SiteInfo siteInfo, int channelId) + { + if (permissionsImpl.IsSuperAdmin()) + { + return new KeyValuePair(true, siteInfo.CheckContentLevel); + } + + var isChecked = false; + var checkedLevel = 0; + if (siteInfo.IsCheckContentLevel == false) + { + if (permissionsImpl.HasChannelPermissions(siteInfo.Id, channelId, ConfigManager.ChannelPermissions.ContentCheck)) + { + isChecked = true; + } + } + else + { + if (permissionsImpl.HasChannelPermissions(siteInfo.Id, channelId, ConfigManager.ChannelPermissions.ContentCheckLevel5)) + { + isChecked = true; + } + else if (permissionsImpl.HasChannelPermissions(siteInfo.Id, channelId, ConfigManager.ChannelPermissions.ContentCheckLevel4)) + { + if (siteInfo.CheckContentLevel <= 4) + { + isChecked = true; + } + else + { + checkedLevel = 4; + } + } + else if (permissionsImpl.HasChannelPermissions(siteInfo.Id, channelId, ConfigManager.ChannelPermissions.ContentCheckLevel3)) + { + if (siteInfo.CheckContentLevel <= 3) + { + isChecked = true; + } + else + { + checkedLevel = 3; + } + } + else if (permissionsImpl.HasChannelPermissions(siteInfo.Id, channelId, ConfigManager.ChannelPermissions.ContentCheckLevel2)) + { + if (siteInfo.CheckContentLevel <= 2) + { + isChecked = true; + } + else + { + checkedLevel = 2; + } + } + else if (permissionsImpl.HasChannelPermissions(siteInfo.Id, channelId, ConfigManager.ChannelPermissions.ContentCheckLevel1)) + { + if (siteInfo.CheckContentLevel <= 1) + { + isChecked = true; + } + else + { + checkedLevel = 1; + } + } + else + { + checkedLevel = 0; + } + } + return new KeyValuePair(isChecked, checkedLevel); + } + + public static bool GetUserCheckLevel(IPermissions permissionsImpl, SiteInfo siteInfo, int channelId, out int userCheckedLevel) + { + var checkContentLevel = siteInfo.CheckContentLevel; + + var pair = GetUserCheckLevel(permissionsImpl, siteInfo, channelId); + var isChecked = pair.Key; + var checkedLevel = pair.Value; + if (isChecked) + { + checkedLevel = checkContentLevel; + } + userCheckedLevel = checkedLevel; + return isChecked; + } + } +} diff --git a/net452/SiteServer.CMS/Core/ContentColumn.cs b/net452/SiteServer.CMS/Core/ContentColumn.cs new file mode 100644 index 000000000..afba425d0 --- /dev/null +++ b/net452/SiteServer.CMS/Core/ContentColumn.cs @@ -0,0 +1,17 @@ +using SiteServer.Plugin; + +namespace SiteServer.CMS.Core +{ + public class ContentColumn + { + public string AttributeName { get; set; } + + public string DisplayName { get; set; } + + public InputType InputType { get; set; } + + public bool IsList { get; set; } + + public bool IsCalculate { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Core/ContentCountInfo.cs b/net452/SiteServer.CMS/Core/ContentCountInfo.cs new file mode 100644 index 000000000..8d0bcf02b --- /dev/null +++ b/net452/SiteServer.CMS/Core/ContentCountInfo.cs @@ -0,0 +1,12 @@ +namespace SiteServer.CMS.Core +{ + public class ContentCountInfo + { + public int SiteId { get; set; } + public int ChannelId { get; set; } + public string IsChecked { get; set; } + public int CheckedLevel { get; set; } + public int AdminId { get; set; } + public int Count { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Core/ContentUtility.cs b/net452/SiteServer.CMS/Core/ContentUtility.cs new file mode 100644 index 000000000..49f5730ef --- /dev/null +++ b/net452/SiteServer.CMS/Core/ContentUtility.cs @@ -0,0 +1,693 @@ +using System; +using System.Text; +using SiteServer.Utils; +using System.Collections.Generic; +using System.Collections.Specialized; +using SiteServer.CMS.Plugin; +using SiteServer.Plugin; +using System.Linq; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; + +namespace SiteServer.CMS.Core +{ + public static class ContentUtility + { + public static string PagePlaceHolder = "[SITESERVER_PAGE]";//内容翻页占位符 + + public static string TextEditorContentEncode(SiteInfo siteInfo, string content) + { + if (siteInfo == null) return content; + + if (siteInfo.IsSaveImageInTextEditor && !string.IsNullOrEmpty(content)) + { + content = PathUtility.SaveImage(siteInfo, content); + } + + var builder = new StringBuilder(content); + + var url = siteInfo.WebUrl; + if (!string.IsNullOrEmpty(url) && url != "/") + { + StringUtils.ReplaceHrefOrSrc(builder, url, "@"); + } + //if (!string.IsNullOrEmpty(url)) + //{ + // StringUtils.ReplaceHrefOrSrc(builder, url, "@"); + //} + + var relatedSiteUrl = FxUtils.ParseNavigationUrl($"~/{siteInfo.SiteDir}"); + StringUtils.ReplaceHrefOrSrc(builder, relatedSiteUrl, "@"); + + builder.Replace("@'@", "'@"); + builder.Replace("@\"@", "\"@"); + + return builder.ToString(); + } + + public static string TextEditorContentDecode(SiteInfo siteInfo, string content, bool isLocal) + { + if (string.IsNullOrWhiteSpace(content)) return string.Empty; + if (siteInfo == null) return content; + + var builder = new StringBuilder(content); + + var virtualAssetsUrl = $"@/{siteInfo.AssetsDir}"; + string assetsUrl; + if (isLocal) + { + assetsUrl = PageUtility.GetSiteUrl(siteInfo, + siteInfo.AssetsDir, true); + } + else + { + assetsUrl = siteInfo.AssetsUrl; + } + StringUtils.ReplaceHrefOrSrc(builder, virtualAssetsUrl, assetsUrl); + StringUtils.ReplaceHrefOrSrc(builder, "@/", siteInfo.WebUrl); + StringUtils.ReplaceHrefOrSrc(builder, "@", siteInfo.WebUrl); + + builder.Replace(" ", " "); + + return builder.ToString(); + } + + public static string GetTitleFormatString(bool isStrong, bool isEm, bool isU, string color) + { + return $"{isStrong}_{isEm}_{isU}_{color}"; + } + + //public static bool SetTitleFormatControls(string titleFormatString, CheckBox formatStrong, CheckBox formatEm, CheckBox formatU, TextBox formatColor) + //{ + // var isTitleFormatted = false; + // if (!string.IsNullOrEmpty(titleFormatString)) + // { + // var formats = titleFormatString.Split('_'); + // if (formats.Length == 4) + // { + // formatStrong.Checked = TranslateUtils.ToBool(formats[0]); + // formatEm.Checked = TranslateUtils.ToBool(formats[1]); + // formatU.Checked = TranslateUtils.ToBool(formats[2]); + // formatColor.Text = formats[3]; + // if (formatStrong.Checked || formatEm.Checked || formatU.Checked || !string.IsNullOrEmpty(formatColor.Text)) + // { + // isTitleFormatted = true; + // } + // } + // } + // return isTitleFormatted; + //} + + public static void SetTitleFormatControls(string titleFormatString, out bool formatStrong, out bool formatEm, out bool formatU, out string formatColor) + { + formatStrong = formatEm = formatU = false; + formatColor = string.Empty; + + if (!string.IsNullOrEmpty(titleFormatString)) + { + var formats = titleFormatString.Split('_'); + if (formats.Length == 4) + { + formatStrong = TranslateUtils.ToBool(formats[0]); + formatEm = TranslateUtils.ToBool(formats[1]); + formatU = TranslateUtils.ToBool(formats[2]); + formatColor = formats[3]; + } + } + } + + public static string FormatTitle(string titleFormatString, string title) + { + var formattedTitle = title; + if (!string.IsNullOrEmpty(titleFormatString)) + { + var formats = titleFormatString.Split('_'); + if (formats.Length == 4) + { + var isStrong = TranslateUtils.ToBool(formats[0]); + var isEm = TranslateUtils.ToBool(formats[1]); + var isU = TranslateUtils.ToBool(formats[2]); + var color = formats[3]; + + if (!string.IsNullOrEmpty(color)) + { + if (!color.StartsWith("#")) + { + color = "#" + color; + } + formattedTitle = $@"{formattedTitle}"; + } + if (isStrong) + { + formattedTitle = $"{formattedTitle}"; + } + if (isEm) + { + formattedTitle = $"{formattedTitle}"; + } + if (isU) + { + formattedTitle = $"{formattedTitle}"; + } + } + } + return formattedTitle; + } + + public static void PutImagePaths(SiteInfo siteInfo, ContentInfo contentInfo, NameValueCollection collection) + { + if (contentInfo == null) return; + + var imageUrl = contentInfo.Get(ContentAttribute.ImageUrl); + var videoUrl = contentInfo.Get(ContentAttribute.VideoUrl); + var fileUrl = contentInfo.Get(ContentAttribute.FileUrl); + var content = contentInfo.Get(ContentAttribute.Content); + + if (!string.IsNullOrEmpty(imageUrl) && PageUtility.IsVirtualUrl(imageUrl)) + { + collection[imageUrl] = PathUtility.MapPath(siteInfo, imageUrl); + } + if (!string.IsNullOrEmpty(videoUrl) && PageUtility.IsVirtualUrl(videoUrl)) + { + collection[videoUrl] = PathUtility.MapPath(siteInfo, videoUrl); + } + if (!string.IsNullOrEmpty(fileUrl) && PageUtility.IsVirtualUrl(fileUrl)) + { + collection[fileUrl] = PathUtility.MapPath(siteInfo, fileUrl); + } + + var srcList = RegexUtils.GetOriginalImageSrcs(content); + foreach (var src in srcList) + { + if (PageUtility.IsVirtualUrl(src)) + { + collection[src] = PathUtility.MapPath(siteInfo, src); + } + } + } + + public static string GetAutoPageContent(string content, int pageWordNum) + { + var builder = new StringBuilder(); + if (!string.IsNullOrEmpty(content)) + { + content = content.Replace(PagePlaceHolder, string.Empty); + AutoPage(builder, content, pageWordNum); + } + return builder.ToString(); + } + + private static void AutoPage(StringBuilder builder, string content, int pageWordNum) + { + if (content.Length > pageWordNum) + { + var i = content.IndexOf("

    ", pageWordNum, StringComparison.Ordinal); + if (i == -1) + { + i = content.IndexOf("

    ", pageWordNum, StringComparison.Ordinal); + } + + if (i != -1) + { + var start = i + 4; + builder.Append(content.Substring(0, start)); + content = content.Substring(start); + if (!string.IsNullOrEmpty(content)) + { + builder.Append(PagePlaceHolder); + AutoPage(builder, content, pageWordNum); + } + } + else + { + builder.Append(content); + } + } + else + { + builder.Append(content); + } + } + + public static List GetAllTableStyleInfoList(List tableStyleInfoList) + { + var taxis = 1; + var list = new List + { + new TableStyleInfo + { + AttributeName = ContentAttribute.Id, + DisplayName = "内容Id", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.Title, + DisplayName = "标题", + Taxis = taxis++ + } + }; + + if (tableStyleInfoList != null) + { + foreach (var tableStyleInfo in tableStyleInfoList) + { + if (!list.Exists(t => t.AttributeName == tableStyleInfo.AttributeName)) + { + list.Add(new TableStyleInfo + { + AttributeName = tableStyleInfo.AttributeName, + DisplayName = tableStyleInfo.DisplayName, + Type = tableStyleInfo.Type, + Taxis = taxis++ + }); + } + } + } + + list.AddRange(new List + { + new TableStyleInfo + { + AttributeName = ContentAttribute.LinkUrl, + DisplayName = "外部链接", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.AddDate, + DisplayName = "添加时间", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.LastEditDate, + DisplayName = "最后修改时间", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.AddUserName, + DisplayName = "添加人", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.LastEditUserName, + DisplayName = "最后修改人", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.GroupNameCollection, + DisplayName = "内容组", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.Tags, + DisplayName = "标签", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.AdminId, + DisplayName = "管理员", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.UserId, + DisplayName = "投稿用户", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.SourceId, + DisplayName = "来源标识", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.Hits, + DisplayName = "点击量", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.HitsByDay, + DisplayName = "日点击", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.HitsByWeek, + DisplayName = "周点击", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.HitsByMonth, + DisplayName = "月点击", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.LastHitsDate, + DisplayName = "最后点击时间", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.Downloads, + DisplayName = "下载量", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.CheckUserName, + DisplayName = "审核人", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.CheckDate, + DisplayName = "审核时间", + Taxis = taxis++ + }, + new TableStyleInfo + { + AttributeName = ContentAttribute.CheckReasons, + DisplayName = "审核原因", + Taxis = taxis + }, + }); + + return list.OrderBy(styleInfo => styleInfo.Taxis == 0 ? int.MaxValue : styleInfo.Taxis).ToList(); + } + + //public static List GetEditableTableStyleInfoList(List tableStyleInfoList) + //{ + // var list = new List + // { + // new TableStyleInfo + // { + // AttributeName = ContentAttribute.Title, + // Type = InputType.Text, + // DisplayName = "标题" + // }, + // new TableStyleInfo + // { + // AttributeName = ContentAttribute.LinkUrl, + // Type = InputType.Text, + // DisplayName = "外部链接" + // }, + // new TableStyleInfo + // { + // AttributeName = ContentAttribute.AddDate, + // Type = InputType.DateTime, + // DisplayName = "添加时间" + // }, + // new TableStyleInfo + // { + // AttributeName = ContentAttribute.GroupNameCollection, + // Type = InputType.CheckBox, + // DisplayName = "内容组" + // }, + // new TableStyleInfo + // { + // AttributeName = ContentAttribute.Tags, + // Type = InputType.CheckBox, + // DisplayName = "标签" + // } + // }; + + // if (tableStyleInfoList != null) + // { + // list.InsertRange(2, tableStyleInfoList); + // } + + // return list; + //} + + public static bool AfterContentAdded(SiteInfo siteInfo, ChannelInfo channelInfo, int contentId, bool isCrossSiteTrans, bool isAutomatic) + { + var isTranslated = false; + if (isCrossSiteTrans && isAutomatic) + { + var targetSiteId = 0; + var transType = ECrossSiteTransTypeUtils.GetEnumType(channelInfo.TransType); + + if (transType == ECrossSiteTransType.SpecifiedSite) + { + targetSiteId = channelInfo.TransSiteId; + } + else if (transType == ECrossSiteTransType.SelfSite) + { + targetSiteId = siteInfo.Id; + } + else if (transType == ECrossSiteTransType.ParentSite) + { + targetSiteId = SiteManager.GetParentSiteId(siteInfo.Id); + } + + if (targetSiteId > 0) + { + var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); + if (targetSiteInfo != null) + { + var targetChannelIdArrayList = TranslateUtils.StringCollectionToIntList(channelInfo.TransChannelIds); + if (targetChannelIdArrayList.Count > 0) + { + foreach (var targetChannelId in targetChannelIdArrayList) + { + CrossSiteTransUtility.TransContentInfo(siteInfo, channelInfo, contentId, targetSiteInfo, targetChannelId); + isTranslated = true; + } + } + } + } + } + + foreach (var service in PluginManager.Services) + { + try + { + service.OnContentAddCompleted(new ContentEventArgs(siteInfo.Id, channelInfo.Id, contentId)); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(service.PluginId, ex, nameof(service.OnContentAddCompleted)); + } + } + + return isTranslated; + } + + public static Dictionary> GetIDsDictionary(NameValueCollection queryString) + { + var dic = new Dictionary>(); + + if (!string.IsNullOrEmpty(queryString["IDsCollection"])) + { + foreach (var ids in TranslateUtils.StringCollectionToStringList(queryString["IDsCollection"])) + { + var channelId = TranslateUtils.ToIntWithNegative(ids.Split('_')[0]); + var contentId = TranslateUtils.ToInt(ids.Split('_')[1]); + var contentIdList = new List(); + if (dic.ContainsKey(channelId)) + { + contentIdList = dic[channelId]; + } + if (!contentIdList.Contains(contentId)) + { + contentIdList.Add(contentId); + } + + dic[channelId] = contentIdList; + } + } + else + { + var channelId = TranslateUtils.ToInt(queryString["channelId"]); + dic[channelId] = TranslateUtils.StringCollectionToIntList(queryString["contentIdCollection"]); + } + + return dic; + } + + public static string GetTitleHtml(string titleFormat, string titleAjaxUrl) + { + var builder = new StringBuilder(); + var formatStrong = false; + var formatEm = false; + var formatU = false; + var formatColor = string.Empty; + if (titleFormat != null) + { + SetTitleFormatControls(titleFormat, out formatStrong, out formatEm, out formatU, out formatColor); + } + + builder.Append( + $@" + +"); + + builder.Append($@" +
    + + + + +
    +
    + + +
    + + + +"); + + builder.Append(@" + +
    "); + builder.Replace("[url]", titleAjaxUrl); + + return builder.ToString(); + } + + public static string GetTagsHtml(string tagsAjaxUrl) + { + const string tagScript = @" + +
    +"; + return tagScript.Replace("[url]", tagsAjaxUrl); + } + } +} diff --git a/net452/SiteServer.CMS/Core/Create/CreateManager.cs b/net452/SiteServer.CMS/Core/Create/CreateManager.cs new file mode 100644 index 000000000..f5661d13b --- /dev/null +++ b/net452/SiteServer.CMS/Core/Create/CreateManager.cs @@ -0,0 +1,204 @@ +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.Utils; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Core.Create +{ + public static class CreateManager + { + private static string GetTaskName(ECreateType createType, int siteId, int channelId, int contentId, + int fileTemplateId, int specialId, out int pageCount) + { + pageCount = 0; + var name = string.Empty; + if (createType == ECreateType.Channel) + { + name = channelId == siteId ? "首页" : ChannelManager.GetChannelName(siteId, channelId); + if (!string.IsNullOrEmpty(name)) + { + pageCount = 1; + } + } + else if (createType == ECreateType.AllContent) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + + if (channelInfo != null) + { + var count = ContentManager.GetCount(siteInfo, channelInfo, true); + if (count > 0) + { + pageCount = count; + name = $"{channelInfo.ChannelName}下所有内容页,共 {pageCount} 项"; + } + } + } + else if (createType == ECreateType.Content) + { + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + + var title = channelInfo.ContentRepository.GetValue(contentId, ContentAttribute.Title); + if (!string.IsNullOrEmpty(title)) + { + name = title; + pageCount = 1; + } + } + else if (createType == ECreateType.File) + { + name = TemplateManager.GetTemplateName(siteId, fileTemplateId); + if (!string.IsNullOrEmpty(name)) + { + pageCount = 1; + } + } + else if (createType == ECreateType.Special) + { + name = SpecialManager.GetTitle(siteId, specialId); + if (!string.IsNullOrEmpty(name)) + { + pageCount = 1; + } + } + return name; + } + + public static void CreateByAll(int siteId) + { + CreateTaskManager.ClearAllTask(siteId); + + var channelIdList = ChannelManager.GetChannelIdList(siteId); + foreach (var channelId in channelIdList) + { + CreateChannel(siteId, channelId); + } + + foreach (var channelId in channelIdList) + { + CreateAllContent(siteId, channelId); + } + + foreach (var specialId in SpecialManager.GetAllSpecialIdList(siteId)) + { + CreateSpecial(siteId, specialId); + } + + foreach (var fileTemplateId in TemplateManager.GetAllFileTemplateIdList(siteId)) + { + CreateFile(siteId, fileTemplateId); + } + } + + public static void CreateByTemplate(int siteId, int templateId) + { + var templateInfo = TemplateManager.GetTemplateInfo(siteId, templateId); + + if (templateInfo.Type == TemplateType.IndexPageTemplate) + { + CreateChannel(siteId, siteId); + } + else if (templateInfo.Type == TemplateType.ChannelTemplate) + { + var channelIdList = DataProvider.Channel.GetChannelIdList(templateInfo); + foreach (var channelId in channelIdList) + { + CreateChannel(siteId, channelId); + } + } + else if (templateInfo.Type == TemplateType.ContentTemplate) + { + var channelIdList = DataProvider.Channel.GetChannelIdList(templateInfo); + foreach (var channelId in channelIdList) + { + CreateAllContent(siteId, channelId); + } + } + else if (templateInfo.Type == TemplateType.FileTemplate) + { + CreateFile(siteId, templateId); + } + } + + public static void CreateChannel(int siteId, int channelId) + { + if (siteId <= 0 || channelId <= 0) return; + + int pageCount; + var taskName = GetTaskName(ECreateType.Channel, siteId, channelId, 0, 0, 0, out pageCount); + if (pageCount == 0) return; + + var taskInfo = new CreateTaskInfo(0, taskName, ECreateType.Channel, siteId, channelId, 0, 0, 0, pageCount); + CreateTaskManager.AddPendingTask(taskInfo); + } + + public static void CreateContent(int siteId, int channelId, int contentId) + { + if (siteId <= 0 || channelId <= 0 || contentId <= 0) return; + + int pageCount; + var taskName = GetTaskName(ECreateType.Content, siteId, channelId, contentId, 0, 0, out pageCount); + if (pageCount == 0) return; + + var taskInfo = new CreateTaskInfo(0, taskName, ECreateType.Content, siteId, channelId, contentId, 0, 0, pageCount); + CreateTaskManager.AddPendingTask(taskInfo); + } + + public static void CreateAllContent(int siteId, int channelId) + { + if (siteId <= 0 || channelId <= 0) return; + + int pageCount; + var taskName = GetTaskName(ECreateType.AllContent, siteId, channelId, 0, 0, 0, out pageCount); + if (pageCount == 0) return; + + var taskInfo = new CreateTaskInfo(0, taskName, ECreateType.AllContent, siteId, channelId, 0, 0, 0, pageCount); + CreateTaskManager.AddPendingTask(taskInfo); + } + + public static void CreateFile(int siteId, int fileTemplateId) + { + if (siteId <= 0 || fileTemplateId <= 0) return; + + int pageCount; + var taskName = GetTaskName(ECreateType.File, siteId, 0, 0, fileTemplateId, 0, out pageCount); + if (pageCount == 0) return; + + var taskInfo = new CreateTaskInfo(0, taskName, ECreateType.File, siteId, 0, 0, fileTemplateId, 0, pageCount); + CreateTaskManager.AddPendingTask(taskInfo); + } + + public static void CreateSpecial(int siteId, int specialId) + { + if (siteId <= 0 || specialId <= 0) return; + + int pageCount; + var taskName = GetTaskName(ECreateType.Special, siteId, 0, 0, 0, specialId, out pageCount); + if (pageCount == 0) return; + + var taskInfo = new CreateTaskInfo(0, taskName, ECreateType.Special, siteId, 0, 0, 0, specialId, pageCount); + CreateTaskManager.AddPendingTask(taskInfo); + } + + public static void TriggerContentChangedEvent(int siteId, int channelId) + { + if (siteId <= 0 || channelId <= 0) return; + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + + var channelIdList = TranslateUtils.StringCollectionToIntList(channelInfo.CreateChannelIdsIfContentChanged); + if (channelInfo.IsCreateChannelIfContentChanged && !channelIdList.Contains(channelId)) + { + channelIdList.Add(channelId); + } + foreach (var theChannelId in channelIdList) + { + CreateChannel(siteId, theChannelId); + } + } + } +} diff --git a/net452/SiteServer.CMS/Core/Create/CreateTaskInfo.cs b/net452/SiteServer.CMS/Core/Create/CreateTaskInfo.cs new file mode 100644 index 000000000..3357ad03a --- /dev/null +++ b/net452/SiteServer.CMS/Core/Create/CreateTaskInfo.cs @@ -0,0 +1,33 @@ +using SiteServer.CMS.Core.Enumerations; + +namespace SiteServer.CMS.Core.Create +{ + public class CreateTaskInfo + { + public CreateTaskInfo(int id, string name, ECreateType createType, int siteId, int channelId, int contentId, int fileTemplateId, int specialId, int pageCount) + { + Id = id; + Name = name; + CreateType = createType; + SiteId = siteId; + ChannelId = channelId; + ContentId = contentId; + FileTemplateId = fileTemplateId; + SpecialId = specialId; + PageCount = pageCount; + Executing = false; + } + + public int Id { get; set; } + public string Name { get; set; } + public ECreateType CreateType { get; set; } + public int SiteId { get; set; } + public int ChannelId { get; set; } + public int ContentId { get; set; } + public int FileTemplateId { get; set; } + public int SpecialId { get; set; } + public int PageCount { get; set; } + + public bool Executing { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Core/Create/CreateTaskLogInfo.cs b/net452/SiteServer.CMS/Core/Create/CreateTaskLogInfo.cs new file mode 100644 index 000000000..3199e50db --- /dev/null +++ b/net452/SiteServer.CMS/Core/Create/CreateTaskLogInfo.cs @@ -0,0 +1,48 @@ +using System; +using SiteServer.CMS.Core.Enumerations; + +namespace SiteServer.CMS.Core.Create +{ + public class CreateTaskLogInfo + { + public CreateTaskLogInfo(int id, ECreateType createType, int siteId, int channelId, int contentId, int fileTemplateId, int specialId, string taskName, string timeSpan, bool isSuccess, string errorMessage, DateTime addDate) + { + Id = id; + CreateType = createType; + SiteId = siteId; + ChannelId = channelId; + ContentId = contentId; + FileTemplateId = fileTemplateId; + SpecialId = specialId; + TaskName = taskName; + TimeSpan = timeSpan; + IsSuccess = isSuccess; + ErrorMessage = errorMessage; + AddDate = addDate; + } + + public int Id { get; set; } + + public ECreateType CreateType { get; set; } + + public int SiteId { get; set; } + + public int ChannelId { get; set; } + + public int ContentId { get; set; } + + public int FileTemplateId { get; set; } + + public int SpecialId { get; set; } + + public string TaskName { get; set; } + + public string TimeSpan { get; set; } + + public bool IsSuccess { get; set; } + + public string ErrorMessage { get; set; } + + public DateTime AddDate { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Core/Create/CreateTaskManager.cs b/net452/SiteServer.CMS/Core/Create/CreateTaskManager.cs new file mode 100644 index 000000000..a8b1c863c --- /dev/null +++ b/net452/SiteServer.CMS/Core/Create/CreateTaskManager.cs @@ -0,0 +1,166 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using SiteServer.CMS.Core.Enumerations; + +namespace SiteServer.CMS.Core.Create +{ + public static class CreateTaskManager + { + private static readonly List PendingTasks = new List(); + private static readonly List TaskLogs = new List(); + private static readonly object LockObject = new object(); + + public static void AddPendingTask(CreateTaskInfo task) + { + lock (LockObject) + { + if (task.CreateType == ECreateType.Content) + { + if (PendingTasks.Any(taskInfo => + taskInfo.CreateType == ECreateType.AllContent && taskInfo.ChannelId == task.ChannelId)) + { + return; + } + } + if (PendingTasks.Any(taskInfo => + task.CreateType == taskInfo.CreateType && task.SiteId == taskInfo.SiteId && + task.ChannelId == taskInfo.ChannelId && task.ContentId == taskInfo.ContentId && + task.FileTemplateId == taskInfo.FileTemplateId && task.SpecialId == taskInfo.SpecialId)) + { + return; + } + PendingTasks.Insert(0, task); + } + } + + public static int PendingTaskCount => PendingTasks.Count == 0 ? 0 : PendingTasks.Sum(taskInfo => taskInfo.PageCount); + + public static CreateTaskInfo GetFirstPendingTask() + { + lock (LockObject) + { + var taskInfo = PendingTasks.FirstOrDefault(task => !task.Executing); + if (taskInfo == null) return null; + //var taskInfo = PendingTasks[0]; + taskInfo.Executing = true; + PendingTasks.Remove(taskInfo); + PendingTasks.Add(taskInfo); + return taskInfo; + } + } + + public static void RemovePendingTask(CreateTaskInfo taskInfo) + { + lock (LockObject) + { + PendingTasks.Remove(taskInfo); + } + } + + public static void AddSuccessLog(CreateTaskInfo taskInfo, string timeSpan) + { + var taskLog = new CreateTaskLogInfo(0, taskInfo.CreateType, taskInfo.SiteId, taskInfo.ChannelId, taskInfo.ContentId, taskInfo.FileTemplateId, taskInfo.SpecialId, taskInfo.Name, timeSpan, true, string.Empty, DateTime.Now); + lock (LockObject) + { + if (TaskLogs.Count > 20) + { + TaskLogs.RemoveAt(20); + } + TaskLogs.Insert(0, taskLog); + } + } + + public static void AddFailureLog(CreateTaskInfo taskInfo, Exception ex) + { + var taskLog = new CreateTaskLogInfo(0, taskInfo.CreateType, taskInfo.SiteId, taskInfo.ChannelId, taskInfo.ContentId, taskInfo.FileTemplateId, taskInfo.SpecialId, taskInfo.Name, string.Empty, false, ex.Message, DateTime.Now); + lock (LockObject) + { + if (TaskLogs.Count > 20) + { + TaskLogs.RemoveAt(20); + } + TaskLogs.Insert(0, taskLog); + } + } + + public static void ClearAllTask(int siteId) + { + lock (LockObject) + { + var pendingTasks = new List(); + foreach (var createTaskInfo in PendingTasks) + { + if (createTaskInfo.SiteId != siteId) + { + pendingTasks.Add(createTaskInfo); + } + } + PendingTasks.Clear(); + PendingTasks.AddRange(pendingTasks); + } + } + + public static CreateTaskSummary GetTaskSummary(int siteId) + { + var list = new List(); + + var channelsCount = 0; + var contentsCount = 0; + var filesCount = 0; + var specialsCount = 0; + + foreach (var taskInfo in PendingTasks) + { + if (taskInfo.SiteId != siteId) continue; + + if (taskInfo.CreateType == ECreateType.Channel) + { + channelsCount += taskInfo.PageCount; + } + else if (taskInfo.CreateType == ECreateType.Content || taskInfo.CreateType == ECreateType.AllContent) + { + contentsCount += taskInfo.PageCount; + } + else if (taskInfo.CreateType == ECreateType.File) + { + filesCount += taskInfo.PageCount; + } + else if (taskInfo.CreateType == ECreateType.Special) + { + specialsCount += taskInfo.PageCount; + } + + var summaryItem = new CreateTaskSummaryItem(taskInfo, string.Empty, true, false, string.Empty); + list.Add(summaryItem); + } + + //var count = _pendingTasks.Count; + //if (count > 0) + //{ + // foreach (var taskInfo in _pendingTasks) + // { + // var summaryItem = new CreateTaskSummaryItem(taskInfo, string.Empty, true, false, string.Empty); + // list.Add(summaryItem); + // } + // //var pendingTaskList = _pendingTasks.ToList(); + // //for (var i = 0; i < count; i++) + // //{ + // // var taskInfo = pendingTaskList[i]; + // // var summaryItem = new CreateTaskSummaryItem(taskInfo, string.Empty, true, false, string.Empty); + // // list.Add(summaryItem); + // //} + //} + + foreach (var logInfo in TaskLogs) + { + var summaryItem = new CreateTaskSummaryItem(logInfo); + list.Add(summaryItem); + } + + var summary = new CreateTaskSummary(list, channelsCount, contentsCount, filesCount, specialsCount); + + return summary; + } + } +} diff --git a/net452/SiteServer.CMS/Core/Create/CreateTaskSummary.cs b/net452/SiteServer.CMS/Core/Create/CreateTaskSummary.cs new file mode 100644 index 000000000..7172fe096 --- /dev/null +++ b/net452/SiteServer.CMS/Core/Create/CreateTaskSummary.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; + +namespace SiteServer.CMS.Core.Create +{ + public class CreateTaskSummary + { + public CreateTaskSummary(List tasks, int channelsCount, int contentsCount, + int filesCount, int specialsCount) + { + Tasks = tasks; + ChannelsCount = channelsCount; + ContentsCount = contentsCount; + FilesCount = filesCount; + SpecialsCount = specialsCount; + } + + public List Tasks { get; } + + public int ChannelsCount { get; } + + public int ContentsCount { get; } + + public int FilesCount { get; } + + public int SpecialsCount { get; } + } +} diff --git a/SiteServer.CMS/Model/CreateTaskSummaryItem.cs b/net452/SiteServer.CMS/Core/Create/CreateTaskSummaryItem.cs similarity index 76% rename from SiteServer.CMS/Model/CreateTaskSummaryItem.cs rename to net452/SiteServer.CMS/Core/Create/CreateTaskSummaryItem.cs index 39d2336f1..e63b561a0 100644 --- a/SiteServer.CMS/Model/CreateTaskSummaryItem.cs +++ b/net452/SiteServer.CMS/Core/Create/CreateTaskSummaryItem.cs @@ -1,19 +1,19 @@ -using SiteServer.CMS.Model.Enumerations; +using SiteServer.CMS.Core.Enumerations; -namespace SiteServer.CMS.Model +namespace SiteServer.CMS.Core.Create { public class CreateTaskSummaryItem { - public CreateTaskSummaryItem(CreateTaskInfo taskInfo, string timeSpan, bool isExecuting, bool isPending, bool isSuccess, string errorMessage) + public CreateTaskSummaryItem(CreateTaskInfo taskInfo, string timeSpan, bool isPending, bool isSuccess, string errorMessage) { siteId = taskInfo.SiteId; channelId = taskInfo.ChannelId; contentId = taskInfo.ContentId; - templateId = taskInfo.TemplateId; + fileTemplateId = taskInfo.FileTemplateId; + specialId = taskInfo.SpecialId; type = ECreateTypeUtils.GetText(taskInfo.CreateType); name = taskInfo.Name; this.timeSpan = timeSpan; - this.isExecuting = isExecuting; this.isPending = isPending; this.isSuccess = isSuccess; this.errorMessage = errorMessage; @@ -24,11 +24,11 @@ public CreateTaskSummaryItem(CreateTaskLogInfo logInfo) siteId = logInfo.SiteId; channelId = logInfo.ChannelId; contentId = logInfo.ContentId; - templateId = logInfo.TemplateId; + fileTemplateId = logInfo.FileTemplateId; + specialId = logInfo.SpecialId; type = ECreateTypeUtils.GetText(logInfo.CreateType); name = logInfo.TaskName; timeSpan = logInfo.TimeSpan; - isExecuting = false; isPending = false; isSuccess = logInfo.IsSuccess; errorMessage = logInfo.ErrorMessage; @@ -37,12 +37,12 @@ public CreateTaskSummaryItem(CreateTaskLogInfo logInfo) public int siteId { get; set; } public int channelId { get; set; } public int contentId { get; set; } - public int templateId { get; set; } + public int fileTemplateId { get; set; } + public int specialId { get; set; } public string type { get; set; } public string name { get; set; } public string timeSpan { get; set; } - public bool isExecuting { get; set; } public bool isPending { get; set; } public bool isSuccess { get; set; } public string errorMessage { get; set; } diff --git a/SiteServer.CMS/Core/Create/DeleteManager.cs b/net452/SiteServer.CMS/Core/Create/DeleteManager.cs similarity index 85% rename from SiteServer.CMS/Core/Create/DeleteManager.cs rename to net452/SiteServer.CMS/Core/Create/DeleteManager.cs index 3a9b18e02..f18b573a1 100644 --- a/SiteServer.CMS/Core/Create/DeleteManager.cs +++ b/net452/SiteServer.CMS/Core/Create/DeleteManager.cs @@ -1,19 +1,22 @@ using System.Collections.Generic; using System.IO; -using SiteServer.CMS.Model; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; using SiteServer.Plugin; using SiteServer.Utils; namespace SiteServer.CMS.Core.Create { - public class DeleteManager + public static class DeleteManager { public static void DeleteContentsByPage(SiteInfo siteInfo, List channelIdList) { foreach (var channelId in channelIdList) { - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - var contentIdList = DataProvider.ContentDao.GetContentIdList(tableName, channelId); + var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + + var contentIdList = channelInfo.ContentRepository.GetContentIdList(channelId); if (contentIdList.Count > 0) { foreach (var contentId in contentIdList) @@ -27,7 +30,7 @@ public static void DeleteContentsByPage(SiteInfo siteInfo, List channelIdLi } } - public static void DeleteContents(SiteInfo siteInfo, int channelId, List contentIdList) + public static void DeleteContents(SiteInfo siteInfo, int channelId, IList contentIdList) { foreach (var contentId in contentIdList) { @@ -49,8 +52,9 @@ public static void DeleteChannels(SiteInfo siteInfo, List channelIdList) FileUtils.DeleteFileIfExists(filePath); - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - var contentIdList = DataProvider.ContentDao.GetContentIdList(tableName, channelId); + var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + + var contentIdList = channelInfo.ContentRepository.GetContentIdList(channelId); if (contentIdList.Count > 0) { DeleteContents(siteInfo, channelId, contentIdList); @@ -97,7 +101,7 @@ public static void DeleteFiles(SiteInfo siteInfo, List templateIdList) foreach (var templateId in templateIdList) { var templateInfo = TemplateManager.GetTemplateInfo(siteInfo.Id, templateId); - if (templateInfo == null || templateInfo.TemplateType != TemplateType.FileTemplate) + if (templateInfo == null || templateInfo.Type != TemplateType.FileTemplate) { return; } diff --git a/net452/SiteServer.CMS/Core/Create/ICreateTaskManager.cs b/net452/SiteServer.CMS/Core/Create/ICreateTaskManager.cs new file mode 100644 index 000000000..e8c73826f --- /dev/null +++ b/net452/SiteServer.CMS/Core/Create/ICreateTaskManager.cs @@ -0,0 +1,23 @@ +using System; + +namespace SiteServer.CMS.Core.Create +{ + public interface ICreateTaskManager + { + void AddPendingTask(CreateTaskInfo task); + + int PendingTaskCount { get; } + + CreateTaskInfo GetAndRemoveFirstPendingTask(); + + void AddSuccessLog(CreateTaskInfo taskInfo, string timeSpan); + + void AddFailureLog(CreateTaskInfo taskInfo, Exception ex); + + void ClearAllTask(); + + void ClearAllTask(int siteId); + + CreateTaskSummary GetTaskSummary(int siteId); + } +} diff --git a/net452/SiteServer.CMS/Core/CrossSiteTransUtility.cs b/net452/SiteServer.CMS/Core/CrossSiteTransUtility.cs new file mode 100644 index 000000000..62d85d41c --- /dev/null +++ b/net452/SiteServer.CMS/Core/CrossSiteTransUtility.cs @@ -0,0 +1,233 @@ +using System.Text; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Core +{ + public static class CrossSiteTransUtility + { + public static bool IsCrossSiteTrans(SiteInfo siteInfo, ChannelInfo channelInfo) + { + var isCrossSiteTrans = false; + + + if (channelInfo != null) + { + var transType = ECrossSiteTransTypeUtils.GetEnumType(channelInfo.TransType); + + if (transType != ECrossSiteTransType.None) + { + if (transType == ECrossSiteTransType.AllParentSite) + { + var parentSiteId = SiteManager.GetParentSiteId(siteInfo.Id); + if (parentSiteId != 0) + { + isCrossSiteTrans = true; + } + } + else if (transType == ECrossSiteTransType.SelfSite) + { + isCrossSiteTrans = true; + } + else if (transType == ECrossSiteTransType.AllSite) + { + isCrossSiteTrans = true; + } + else if (transType == ECrossSiteTransType.SpecifiedSite) + { + if (channelInfo.TransSiteId > 0) + { + var theSiteInfo = SiteManager.GetSiteInfo(channelInfo.TransSiteId); + if (theSiteInfo != null) + { + isCrossSiteTrans = true; + } + } + } + else if (transType == ECrossSiteTransType.ParentSite) + { + var parentSiteId = SiteManager.GetParentSiteId(siteInfo.Id); + if (parentSiteId != 0) + { + isCrossSiteTrans = true; + } + } + } + } + + return isCrossSiteTrans; + } + + public static bool IsAutomatic(ChannelInfo channelInfo) + { + var isAutomatic = false; + + if (channelInfo != null) + { + var transType = ECrossSiteTransTypeUtils.GetEnumType(channelInfo.TransType); + + if (transType == ECrossSiteTransType.SelfSite || transType == ECrossSiteTransType.ParentSite || transType == ECrossSiteTransType.SpecifiedSite) + { + isAutomatic = channelInfo.TransIsAutomatic; + } + } + + return isAutomatic; + } + + public static string GetDescription(int siteId, ChannelInfo channelInfo) + { + var results = string.Empty; + + if (channelInfo != null) + { + var transType = ECrossSiteTransTypeUtils.GetEnumType(channelInfo.TransType); + + results = ECrossSiteTransTypeUtils.GetText(transType); + + if (transType == ECrossSiteTransType.AllParentSite || transType == ECrossSiteTransType.AllSite) + { + if (!string.IsNullOrEmpty(channelInfo.TransChannelNames)) + { + results += $"({channelInfo.TransChannelNames})"; + } + } + else if (transType == ECrossSiteTransType.SelfSite || transType == ECrossSiteTransType.SpecifiedSite || transType == ECrossSiteTransType.ParentSite) + { + SiteInfo siteInfo = null; + + if (transType == ECrossSiteTransType.SelfSite) + { + siteInfo = SiteManager.GetSiteInfo(siteId); + } + else if (transType == ECrossSiteTransType.SpecifiedSite) + { + siteInfo = SiteManager.GetSiteInfo(channelInfo.TransSiteId); + } + else + { + var parentSiteId = SiteManager.GetParentSiteId(siteId); + if (parentSiteId != 0) + { + siteInfo = SiteManager.GetSiteInfo(parentSiteId); + } + } + + if (siteInfo != null && !string.IsNullOrEmpty(channelInfo.TransChannelIds)) + { + var nodeNameBuilder = new StringBuilder(); + var channelIdArrayList = TranslateUtils.StringCollectionToIntList(channelInfo.TransChannelIds); + foreach (int channelId in channelIdArrayList) + { + var theNodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + if (theNodeInfo != null) + { + nodeNameBuilder.Append(theNodeInfo.ChannelName).Append(","); + } + } + if (nodeNameBuilder.Length > 0) + { + nodeNameBuilder.Length--; + results += $"({siteInfo.SiteName}:{nodeNameBuilder})"; + } + } + } + } + return results; + } + + public static void TransContentInfo(SiteInfo siteInfo, ChannelInfo channelInfo, int contentId, SiteInfo targetSiteInfo, int targetChannelId) + { + var targetTableName = ChannelManager.GetTableName(targetSiteInfo, targetChannelId); + + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + FileUtility.MoveFileByContentInfo(siteInfo, targetSiteInfo, contentInfo); + contentInfo.SiteId = targetSiteInfo.Id; + contentInfo.SourceId = channelInfo.Id; + contentInfo.ChannelId = targetChannelId; + contentInfo.Checked = targetSiteInfo.IsCrossSiteTransChecked; + contentInfo.CheckedLevel = 0; + + //复制 + if (Equals(channelInfo.TransDoneType, ETranslateContentType.Copy)) + { + contentInfo.Set(ContentAttribute.TranslateContentType, ETranslateContentType.Copy.ToString()); + } + //引用地址 + else if (Equals(channelInfo.TransDoneType, ETranslateContentType.Reference)) + { + contentInfo.SiteId = targetSiteInfo.Id; + contentInfo.SourceId = channelInfo.Id; + contentInfo.ChannelId = targetChannelId; + contentInfo.ReferenceId = contentId; + contentInfo.Set(ContentAttribute.TranslateContentType, ETranslateContentType.Reference.ToString()); + } + //引用内容 + else if (Equals(channelInfo.TransDoneType, ETranslateContentType.ReferenceContent)) + { + contentInfo.SiteId = targetSiteInfo.Id; + contentInfo.SourceId = channelInfo.Id; + contentInfo.ChannelId = targetChannelId; + contentInfo.ReferenceId = contentId; + contentInfo.Set(ContentAttribute.TranslateContentType, ETranslateContentType.ReferenceContent.ToString()); + } + + if (!string.IsNullOrEmpty(targetTableName)) + { + DataProvider.ContentRepository.Insert(targetTableName, targetSiteInfo, channelInfo, contentInfo); + + #region 复制资源 + //资源:图片,文件,视频 + if (!string.IsNullOrEmpty(contentInfo.Get(ContentAttribute.ImageUrl))) + { + //修改图片 + var sourceImageUrl = PathUtility.MapPath(siteInfo, contentInfo.Get(ContentAttribute.ImageUrl)); + CopyReferenceFiles(targetSiteInfo, sourceImageUrl, siteInfo); + + } + else if (!string.IsNullOrEmpty(contentInfo.Get(ContentAttribute.GetExtendAttributeName(ContentAttribute.ImageUrl)))) + { + var sourceImageUrls = TranslateUtils.StringCollectionToStringList(contentInfo.Get(ContentAttribute.GetExtendAttributeName(ContentAttribute.ImageUrl))); + + foreach (string imageUrl in sourceImageUrls) + { + var sourceImageUrl = PathUtility.MapPath(siteInfo, imageUrl); + CopyReferenceFiles(targetSiteInfo, sourceImageUrl, siteInfo); + } + } + if (!string.IsNullOrEmpty(contentInfo.Get(ContentAttribute.FileUrl))) + { + //修改附件 + var sourceFileUrl = PathUtility.MapPath(siteInfo, contentInfo.Get(ContentAttribute.FileUrl)); + CopyReferenceFiles(targetSiteInfo, sourceFileUrl, siteInfo); + + } + else if (!string.IsNullOrEmpty(contentInfo.Get(ContentAttribute.GetExtendAttributeName(ContentAttribute.FileUrl)))) + { + var sourceFileUrls = TranslateUtils.StringCollectionToStringList(contentInfo.Get(ContentAttribute.GetExtendAttributeName(ContentAttribute.FileUrl))); + + foreach (string fileUrl in sourceFileUrls) + { + var sourceFileUrl = PathUtility.MapPath(siteInfo, fileUrl); + CopyReferenceFiles(targetSiteInfo, sourceFileUrl, siteInfo); + } + } + #endregion + } + } + + private static void CopyReferenceFiles(SiteInfo targetSiteInfo, string sourceUrl, SiteInfo sourceSiteInfo) + { + var targetUrl = StringUtils.ReplaceFirst(sourceSiteInfo.SiteDir, sourceUrl, targetSiteInfo.SiteDir); + if (!FileUtils.IsFileExists(targetUrl)) + { + FileUtils.CopyFile(sourceUrl, targetUrl, true); + } + } + } +} \ No newline at end of file diff --git a/SiteServer.CMS/Core/DirectoryUtility.cs b/net452/SiteServer.CMS/Core/DirectoryUtility.cs similarity index 89% rename from SiteServer.CMS/Core/DirectoryUtility.cs rename to net452/SiteServer.CMS/Core/DirectoryUtility.cs index 63abb2824..dfd47ed5c 100644 --- a/SiteServer.CMS/Core/DirectoryUtility.cs +++ b/net452/SiteServer.CMS/Core/DirectoryUtility.cs @@ -1,17 +1,15 @@ using System; using SiteServer.Utils; -using SiteServer.CMS.Model; using System.Collections; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; namespace SiteServer.CMS.Core { - public class DirectoryUtility + public static class DirectoryUtility { - public static string GetIndexesDirectoryPath(string siteFilesDirectoryPath) - { - return PathUtils.Combine(siteFilesDirectoryPath, "Indexes"); - } - public static void ChangeSiteDir(string parentPsPath, string oldPsDir, string newPsDir) { var oldPsPath = PathUtils.Combine(parentPsPath, oldPsDir); @@ -32,9 +30,11 @@ public static void ChangeSiteDir(string parentPsPath, string oldPsDir, string ne public static void DeleteSiteFiles(SiteInfo siteInfo) { + if (siteInfo == null) return; + var sitePath = PathUtility.GetSitePath(siteInfo); - if (siteInfo.IsRoot) + if (siteInfo.Root) { var filePaths = DirectoryUtils.GetFilePaths(sitePath); foreach (var filePath in filePaths) @@ -46,7 +46,7 @@ public static void DeleteSiteFiles(SiteInfo siteInfo) } } - var siteDirList = DataProvider.SiteDao.GetLowerSiteDirListThatNotIsRoot(); + var siteDirList = DataProvider.Site.GetLowerSiteDirListThatNotIsRoot(); var directoryPaths = DirectoryUtils.GetDirectoryPaths(sitePath); foreach (var subDirectoryPath in directoryPaths) @@ -69,7 +69,7 @@ public static void ImportSiteFiles(SiteInfo siteInfo, string siteTemplatePath, b { var sitePath = PathUtility.GetSitePath(siteInfo); - if (siteInfo.IsRoot) + if (siteInfo.Root) { var filePaths = DirectoryUtils.GetFilePaths(siteTemplatePath); foreach (var filePath in filePaths) @@ -82,7 +82,7 @@ public static void ImportSiteFiles(SiteInfo siteInfo, string siteTemplatePath, b } } - var siteDirList = DataProvider.SiteDao.GetLowerSiteDirListThatNotIsRoot(); + var siteDirList = DataProvider.Site.GetLowerSiteDirListThatNotIsRoot(); var directoryPaths = DirectoryUtils.GetDirectoryPaths(siteTemplatePath); foreach (var subDirectoryPath in directoryPaths) @@ -148,16 +148,16 @@ public static void ChangeParentSite(int oldParentSiteId, int newParentSiteId, in public static void ChangeToHeadquarters(SiteInfo siteInfo, bool isMoveFiles) { - if (siteInfo.IsRoot == false) + if (siteInfo.Root == false) { var sitePath = PathUtility.GetSitePath(siteInfo); - DataProvider.SiteDao.UpdateParentIdToZero(siteInfo.Id); + DataProvider.Site.UpdateParentIdToZero(siteInfo.Id); - siteInfo.IsRoot = true; + siteInfo.Root = true; siteInfo.SiteDir = string.Empty; - DataProvider.SiteDao.Update(siteInfo); + DataProvider.Site.Update(siteInfo); if (isMoveFiles) { DirectoryUtils.MoveDirectory(sitePath, WebConfigUtils.PhysicalApplicationPath, false); @@ -168,12 +168,12 @@ public static void ChangeToHeadquarters(SiteInfo siteInfo, bool isMoveFiles) public static void ChangeToSubSite(SiteInfo siteInfo, string psDir, ArrayList fileSystemNameArrayList) { - if (siteInfo.IsRoot) + if (siteInfo.Root) { - siteInfo.IsRoot = false; + siteInfo.Root = false; siteInfo.SiteDir = psDir.Trim(); - DataProvider.SiteDao.Update(siteInfo); + DataProvider.Site.Update(siteInfo); var psPath = PathUtils.Combine(WebConfigUtils.PhysicalApplicationPath, psDir); DirectoryUtils.CreateDirectoryIfNotExists(psPath); diff --git a/net452/SiteServer.CMS/Core/Enumerations/EAccessControlEntry.cs b/net452/SiteServer.CMS/Core/Enumerations/EAccessControlEntry.cs new file mode 100644 index 000000000..ea3741646 --- /dev/null +++ b/net452/SiteServer.CMS/Core/Enumerations/EAccessControlEntry.cs @@ -0,0 +1,9 @@ +namespace SiteServer.CMS.Core.Enumerations +{ + public enum AccessControlEntry + { + NotSet = 0x00, + Allow = 0x01, + Deny = 0x02 + } +} diff --git a/net452/SiteServer.CMS/Core/Enumerations/EBackupType.cs b/net452/SiteServer.CMS/Core/Enumerations/EBackupType.cs new file mode 100644 index 000000000..0ba399232 --- /dev/null +++ b/net452/SiteServer.CMS/Core/Enumerations/EBackupType.cs @@ -0,0 +1,96 @@ +namespace SiteServer.CMS.Core.Enumerations +{ + public enum EBackupType + { + Undefined, + Templates, //模板页 + ChannelsAndContents, //栏目及内容 + Files, //文件 + Site, //整站 + } + + public class EBackupTypeUtils + { + public static string GetValue(EBackupType type) + { + if (type == EBackupType.Templates) + { + return "Templates"; + } + if (type == EBackupType.ChannelsAndContents) + { + return "ChannelsAndContents"; + } + if (type == EBackupType.Files) + { + return "Files"; + } + if (type == EBackupType.Site) + { + return "Site"; + } + return "Undefined"; + } + + public static string GetText(EBackupType type) + { + if (type == EBackupType.Templates) + { + return "显示模板"; + } + if (type == EBackupType.ChannelsAndContents) + { + return "栏目及内容"; + } + if (type == EBackupType.Files) + { + return "文件"; + } + if (type == EBackupType.Site) + { + return "整站"; + } + + return "Undefined"; + } + + public static EBackupType GetEnumType(string typeStr) + { + var retval = EBackupType.Undefined; + + if (Equals(EBackupType.Templates, typeStr)) + { + retval = EBackupType.Templates; + } + else if (Equals(EBackupType.ChannelsAndContents, typeStr)) + { + retval = EBackupType.ChannelsAndContents; + } + else if (Equals(EBackupType.Files, typeStr)) + { + retval = EBackupType.Files; + } + else if (Equals(EBackupType.Site, typeStr)) + { + retval = EBackupType.Site; + } + + return retval; + } + + public static bool Equals(EBackupType type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, EBackupType type) + { + return Equals(type, typeStr); + } + } +} diff --git a/SiteServer.CMS/Model/Enumerations/EChangedType.cs b/net452/SiteServer.CMS/Core/Enumerations/EChangedType.cs similarity index 96% rename from SiteServer.CMS/Model/Enumerations/EChangedType.cs rename to net452/SiteServer.CMS/Core/Enumerations/EChangedType.cs index ec687bac0..537c4067d 100644 --- a/SiteServer.CMS/Model/Enumerations/EChangedType.cs +++ b/net452/SiteServer.CMS/Core/Enumerations/EChangedType.cs @@ -1,6 +1,6 @@ using System; -namespace SiteServer.CMS.Model.Enumerations +namespace SiteServer.CMS.Core.Enumerations { public enum EChangedType { @@ -24,7 +24,7 @@ public static string GetValue(EChangedType type) } if (type == EChangedType.Delete) { - return "Delete"; + return "DeleteById"; } if (type == EChangedType.None) { diff --git a/net452/SiteServer.CMS/Core/Enumerations/ECreateType.cs b/net452/SiteServer.CMS/Core/Enumerations/ECreateType.cs new file mode 100644 index 000000000..1d69fe217 --- /dev/null +++ b/net452/SiteServer.CMS/Core/Enumerations/ECreateType.cs @@ -0,0 +1,40 @@ +namespace SiteServer.CMS.Core.Enumerations +{ + public enum ECreateType + { + Channel, + Content, + File, + Special, + AllContent + } + + public static class ECreateTypeUtils + { + public static string GetText(ECreateType createType) + { + if (createType == ECreateType.Channel) + { + return "栏目页"; + } + if (createType == ECreateType.Content) + { + return "内容页"; + } + if (createType == ECreateType.File) + { + return "文件页"; + } + if (createType == ECreateType.Special) + { + return "专题页"; + } + if (createType == ECreateType.AllContent) + { + return "栏目下所有内容页"; + } + + return string.Empty; + } + } +} diff --git a/net452/SiteServer.CMS/Core/Enumerations/ECrossSiteTransType.cs b/net452/SiteServer.CMS/Core/Enumerations/ECrossSiteTransType.cs new file mode 100644 index 000000000..89729ff64 --- /dev/null +++ b/net452/SiteServer.CMS/Core/Enumerations/ECrossSiteTransType.cs @@ -0,0 +1,122 @@ +using System; + +namespace SiteServer.CMS.Core.Enumerations +{ + public enum ECrossSiteTransType + { + None, + SelfSite, + SpecifiedSite, + ParentSite, + AllParentSite, + AllSite + } + + public class ECrossSiteTransTypeUtils + { + public static string GetValue(ECrossSiteTransType type) + { + if (type == ECrossSiteTransType.None) + { + return "None"; + } + if (type == ECrossSiteTransType.SelfSite) + { + return "SelfSite"; + } + if (type == ECrossSiteTransType.SpecifiedSite) + { + return "SpecifiedSite"; + } + if (type == ECrossSiteTransType.ParentSite) + { + return "ParentSite"; + } + if (type == ECrossSiteTransType.AllParentSite) + { + return "AllParentSite"; + } + if (type == ECrossSiteTransType.AllSite) + { + return "AllSite"; + } + throw new Exception(); + } + + public static string GetText(ECrossSiteTransType type) + { + if (type == ECrossSiteTransType.None) + { + return "不转发"; + } + if (type == ECrossSiteTransType.SelfSite) + { + return "可向本站转发"; + } + if (type == ECrossSiteTransType.SpecifiedSite) + { + return "可向指定站点转发"; + } + if (type == ECrossSiteTransType.ParentSite) + { + return "可向上一级站点转发"; + } + if (type == ECrossSiteTransType.AllParentSite) + { + return "可向所有上级站点转发"; + } + if (type == ECrossSiteTransType.AllSite) + { + return "可向所有站点转发"; + } + throw new Exception(); + } + + public static ECrossSiteTransType GetEnumType(string typeStr) + { + var retval = ECrossSiteTransType.AllSite; + + if (Equals(ECrossSiteTransType.None, typeStr)) + { + retval = ECrossSiteTransType.None; + } + else if (Equals(ECrossSiteTransType.SelfSite, typeStr)) + { + retval = ECrossSiteTransType.SelfSite; + } + else if (Equals(ECrossSiteTransType.SpecifiedSite, typeStr)) + { + retval = ECrossSiteTransType.SpecifiedSite; + } + else if (Equals(ECrossSiteTransType.ParentSite, typeStr)) + { + retval = ECrossSiteTransType.ParentSite; + } + else if (Equals(ECrossSiteTransType.AllParentSite, typeStr)) + { + retval = ECrossSiteTransType.AllParentSite; + } + else if (Equals(ECrossSiteTransType.AllSite, typeStr)) + { + retval = ECrossSiteTransType.AllSite; + } + + return retval; + } + + public static bool Equals(ECrossSiteTransType type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, ECrossSiteTransType type) + { + return Equals(type, typeStr); + } + } +} diff --git a/net452/SiteServer.CMS/Core/Enumerations/EKeywordGrade.cs b/net452/SiteServer.CMS/Core/Enumerations/EKeywordGrade.cs new file mode 100644 index 000000000..4dd12b2ad --- /dev/null +++ b/net452/SiteServer.CMS/Core/Enumerations/EKeywordGrade.cs @@ -0,0 +1,83 @@ +using System; + +namespace SiteServer.CMS.Core.Enumerations +{ + public enum EKeywordGrade + { + Normal, //一般 + Sensitive, //比较敏感 + Dangerous //危险 + } + + public static class EKeywordGradeUtils + { + public static string GetValue(EKeywordGrade type) + { + if (type == EKeywordGrade.Normal) + { + return "Normal"; + } + if (type == EKeywordGrade.Sensitive) + { + return "Sensitive"; + } + if (type == EKeywordGrade.Dangerous) + { + return "Dangerous"; + } + throw new Exception(); + } + + public static string GetText(EKeywordGrade type) + { + if (type == EKeywordGrade.Normal) + { + return "一般"; + } + if (type == EKeywordGrade.Sensitive) + { + return "比较敏感"; + } + if (type == EKeywordGrade.Dangerous) + { + return "危险"; + } + throw new Exception(); + } + + public static EKeywordGrade GetEnumType(string typeStr) + { + var retval = EKeywordGrade.Normal; + + if (Equals(EKeywordGrade.Normal, typeStr)) + { + retval = EKeywordGrade.Normal; + } + else if (Equals(EKeywordGrade.Sensitive, typeStr)) + { + retval = EKeywordGrade.Sensitive; + } + else if (Equals(EKeywordGrade.Dangerous, typeStr)) + { + retval = EKeywordGrade.Dangerous; + } + + return retval; + } + + public static bool Equals(EKeywordGrade type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, EKeywordGrade type) + { + return Equals(type, typeStr); + } + } +} diff --git a/net452/SiteServer.CMS/Core/Enumerations/ELayout.cs b/net452/SiteServer.CMS/Core/Enumerations/ELayout.cs new file mode 100644 index 000000000..fd842fc03 --- /dev/null +++ b/net452/SiteServer.CMS/Core/Enumerations/ELayout.cs @@ -0,0 +1,84 @@ +using System; + +namespace SiteServer.CMS.Core.Enumerations +{ + + public enum ELayout + { + Table, //表格 + Flow, //流 + None, //无布局 + } + + public static class ELayoutUtils + { + public static string GetValue(ELayout type) + { + if (type == ELayout.Table) + { + return "Table"; + } + if (type == ELayout.Flow) + { + return "Flow"; + } + if (type == ELayout.None) + { + return "None"; + } + throw new Exception(); + } + + public static string GetText(ELayout type) + { + if (type == ELayout.Table) + { + return "表格"; + } + if (type == ELayout.Flow) + { + return "流"; + } + if (type == ELayout.None) + { + return "无布局"; + } + throw new Exception(); + } + + public static ELayout GetEnumType(string typeStr) + { + var retval = ELayout.None; + + if (Equals(ELayout.Table, typeStr)) + { + retval = ELayout.Table; + } + else if (Equals(ELayout.Flow, typeStr)) + { + retval = ELayout.Flow; + } + else if (Equals(ELayout.None, typeStr)) + { + retval = ELayout.None; + } + + return retval; + } + + public static bool Equals(ELayout type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, ELayout type) + { + return Equals(type, typeStr); + } + } +} diff --git a/net452/SiteServer.CMS/Core/Enumerations/ELinkType.cs b/net452/SiteServer.CMS/Core/Enumerations/ELinkType.cs new file mode 100644 index 000000000..75bc9fe9a --- /dev/null +++ b/net452/SiteServer.CMS/Core/Enumerations/ELinkType.cs @@ -0,0 +1,190 @@ +namespace SiteServer.CMS.Core.Enumerations +{ + public enum ELinkType + { + None, //默认 + NoLinkIfContentNotExists, //无内容时不可链接 + LinkToOnlyOneContent, //仅一条内容时链接到此内容 + NoLinkIfContentNotExistsAndLinkToOnlyOneContent, //无内容时不可链接,仅一条内容时链接到此内容 + LinkToFirstContent, //链接到第一条内容 + NoLinkIfContentNotExistsAndLinkToFirstContent, //无内容时不可链接,有内容时链接到第一条内容 + NoLinkIfChannelNotExists, //无栏目时不可链接 + LinkToLastAddChannel, //链接到最近增加的子栏目 + LinkToFirstChannel, //链接到第一个子栏目 + NoLinkIfChannelNotExistsAndLinkToLastAddChannel, //无栏目时不可链接,有栏目时链接到最近增加的子栏目 + NoLinkIfChannelNotExistsAndLinkToFirstChannel, //无栏目时不可链接,有栏目时链接到第一个子栏目 + NoLink //不可链接 + } + + public static class ELinkTypeUtils + { + public static string GetValue(ELinkType type) + { + if (type == ELinkType.NoLinkIfContentNotExists) + { + return "NoLinkIfContentNotExists"; + } + if (type == ELinkType.LinkToOnlyOneContent) + { + return "LinkToOnlyOneContent"; + } + if (type == ELinkType.NoLinkIfContentNotExistsAndLinkToOnlyOneContent) + { + return "NoLinkIfContentNotExistsAndLinkToOnlyOneContent"; + } + if (type == ELinkType.LinkToFirstContent) + { + return "LinkToFirstContent"; + } + if (type == ELinkType.NoLinkIfContentNotExistsAndLinkToFirstContent) + { + return "NoLinkIfContentNotExistsAndLinkToFirstContent"; + } + if (type == ELinkType.NoLinkIfChannelNotExists) + { + return "NoLinkIfChannelNotExists"; + } + if (type == ELinkType.LinkToLastAddChannel) + { + return "LinkToLastAddChannel"; + } + if (type == ELinkType.LinkToFirstChannel) + { + return "LinkToFirstChannel"; + } + if (type == ELinkType.NoLinkIfChannelNotExistsAndLinkToLastAddChannel) + { + return "NoLinkIfChannelNotExistsAndLinkToLastAddChannel"; + } + if (type == ELinkType.NoLinkIfChannelNotExistsAndLinkToFirstChannel) + { + return "NoLinkIfChannelNotExistsAndLinkToFirstChannel"; + } + if (type == ELinkType.NoLink) + { + return "NoLink"; + } + + return "None"; + } + + public static string GetText(ELinkType type) + { + if (type == ELinkType.NoLinkIfContentNotExists) + { + return "无内容时不可链接"; + } + if (type == ELinkType.LinkToOnlyOneContent) + { + return "仅一条内容时链接到此内容"; + } + if (type == ELinkType.NoLinkIfContentNotExistsAndLinkToOnlyOneContent) + { + return "无内容时不可链接,仅一条内容时链接到此内容"; + } + if (type == ELinkType.LinkToFirstContent) + { + return "链接到第一条内容"; + } + if (type == ELinkType.NoLinkIfContentNotExistsAndLinkToFirstContent) + { + return "无内容时不可链接,有内容时链接到第一条内容"; + } + if (type == ELinkType.NoLinkIfChannelNotExists) + { + return "无栏目时不可链接"; + } + if (type == ELinkType.LinkToLastAddChannel) + { + return "链接到最近增加的子栏目"; + } + if (type == ELinkType.LinkToFirstChannel) + { + return "链接到第一个子栏目"; + } + if (type == ELinkType.NoLinkIfChannelNotExistsAndLinkToLastAddChannel) + { + return "无栏目时不可链接,有栏目时链接到最近增加的子栏目"; + } + if (type == ELinkType.NoLinkIfChannelNotExistsAndLinkToFirstChannel) + { + return "无栏目时不可链接,有栏目时链接到第一个子栏目"; + } + if (type == ELinkType.NoLink) + { + return "不可链接"; + } + + return "默认"; + } + + public static ELinkType GetEnumType(string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return ELinkType.None; + + var retval = ELinkType.None; + + if (Equals(ELinkType.NoLinkIfContentNotExists, typeStr)) + { + retval = ELinkType.NoLinkIfContentNotExists; + } + else if (Equals(ELinkType.LinkToOnlyOneContent, typeStr)) + { + retval = ELinkType.LinkToOnlyOneContent; + } + else if (Equals(ELinkType.NoLinkIfContentNotExistsAndLinkToOnlyOneContent, typeStr)) + { + retval = ELinkType.NoLinkIfContentNotExistsAndLinkToOnlyOneContent; + } + else if (Equals(ELinkType.LinkToFirstContent, typeStr)) + { + retval = ELinkType.LinkToFirstContent; + } + else if (Equals(ELinkType.NoLinkIfContentNotExistsAndLinkToFirstContent, typeStr)) + { + retval = ELinkType.NoLinkIfContentNotExistsAndLinkToFirstContent; + } + else if (Equals(ELinkType.NoLinkIfChannelNotExists, typeStr)) + { + retval = ELinkType.NoLinkIfChannelNotExists; + } + else if (Equals(ELinkType.LinkToLastAddChannel, typeStr)) + { + retval = ELinkType.LinkToLastAddChannel; + } + else if (Equals(ELinkType.LinkToFirstChannel, typeStr)) + { + retval = ELinkType.LinkToFirstChannel; + } + else if (Equals(ELinkType.NoLinkIfChannelNotExistsAndLinkToLastAddChannel, typeStr)) + { + retval = ELinkType.NoLinkIfChannelNotExistsAndLinkToLastAddChannel; + } + else if (Equals(ELinkType.NoLinkIfChannelNotExistsAndLinkToFirstChannel, typeStr)) + { + retval = ELinkType.NoLinkIfChannelNotExistsAndLinkToFirstChannel; + } + else if (Equals(ELinkType.NoLink, typeStr)) + { + retval = ELinkType.NoLink; + } + + return retval; + } + + public static bool Equals(ELinkType type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, ELinkType type) + { + return Equals(type, typeStr); + } + } +} diff --git a/SiteServer.CMS/Model/Enumerations/ELoadingType.cs b/net452/SiteServer.CMS/Core/Enumerations/ELoadingType.cs similarity index 88% rename from SiteServer.CMS/Model/Enumerations/ELoadingType.cs rename to net452/SiteServer.CMS/Core/Enumerations/ELoadingType.cs index 8517078a3..8652072f8 100644 --- a/SiteServer.CMS/Model/Enumerations/ELoadingType.cs +++ b/net452/SiteServer.CMS/Core/Enumerations/ELoadingType.cs @@ -1,19 +1,19 @@ using System; -namespace SiteServer.CMS.Model.Enumerations +namespace SiteServer.CMS.Core.Enumerations { public enum ELoadingType { ContentTree, Channel, - ChannelSelect, + ChannelClickSelect, SiteAnalysis, TemplateFilePathRule, ConfigurationCreateDetails, ConfigurationCrossSiteTrans } - public class ELoadingTypeUtils + public static class ELoadingTypeUtils { public static string GetValue(ELoadingType type) { @@ -25,9 +25,9 @@ public static string GetValue(ELoadingType type) { return "Channel"; } - if (type == ELoadingType.ChannelSelect) + if (type == ELoadingType.ChannelClickSelect) { - return "ChannelSelect"; + return "ChannelClickSelect"; } if (type == ELoadingType.SiteAnalysis) { @@ -60,9 +60,9 @@ public static ELoadingType GetEnumType(string typeStr) { retval = ELoadingType.Channel; } - else if (Equals(ELoadingType.ChannelSelect, typeStr)) + else if (Equals(ELoadingType.ChannelClickSelect, typeStr)) { - retval = ELoadingType.ChannelSelect; + retval = ELoadingType.ChannelClickSelect; } else if (Equals(ELoadingType.SiteAnalysis, typeStr)) { diff --git a/net452/SiteServer.CMS/Core/Enumerations/ERelatedFieldStyle.cs b/net452/SiteServer.CMS/Core/Enumerations/ERelatedFieldStyle.cs new file mode 100644 index 000000000..7f7255f63 --- /dev/null +++ b/net452/SiteServer.CMS/Core/Enumerations/ERelatedFieldStyle.cs @@ -0,0 +1,70 @@ +using System; + +namespace SiteServer.CMS.Core.Enumerations +{ + public enum ERelatedFieldStyle + { + Horizontal, //水平显示 + Virtical, //垂直显示 + } + + public static class ERelatedFieldStyleUtils + { + public static string GetValue(ERelatedFieldStyle type) + { + if (type == ERelatedFieldStyle.Horizontal) + { + return "Horizontal"; + } + if (type == ERelatedFieldStyle.Virtical) + { + return "Virtical"; + } + throw new Exception(); + } + + public static string GetText(ERelatedFieldStyle type) + { + if (type == ERelatedFieldStyle.Horizontal) + { + return "水平显示"; + } + if (type == ERelatedFieldStyle.Virtical) + { + return "垂直显示"; + } + throw new Exception(); + } + + public static ERelatedFieldStyle GetEnumType(string typeStr) + { + var retval = ERelatedFieldStyle.Horizontal; + + if (Equals(ERelatedFieldStyle.Horizontal, typeStr)) + { + retval = ERelatedFieldStyle.Horizontal; + } + else if (Equals(ERelatedFieldStyle.Virtical, typeStr)) + { + retval = ERelatedFieldStyle.Virtical; + } + + return retval; + } + + public static bool Equals(ERelatedFieldStyle type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, ERelatedFieldStyle type) + { + return Equals(type, typeStr); + } + } +} diff --git a/net452/SiteServer.CMS/Core/Enumerations/ETableRule.cs b/net452/SiteServer.CMS/Core/Enumerations/ETableRule.cs new file mode 100644 index 000000000..570efc31c --- /dev/null +++ b/net452/SiteServer.CMS/Core/Enumerations/ETableRule.cs @@ -0,0 +1,83 @@ +using System; + +namespace SiteServer.CMS.Core.Enumerations +{ + public enum ETableRule + { + Choose, + HandWrite, + Create + } + + public static class ETableRuleUtils + { + public static string GetValue(ETableRule type) + { + if (type == ETableRule.Choose) + { + return "Choose"; + } + if (type == ETableRule.HandWrite) + { + return "HandWrite"; + } + if (type == ETableRule.Create) + { + return "Create"; + } + throw new Exception(); + } + + public static string GetText(ETableRule type) + { + if (type == ETableRule.Choose) + { + return "选择内容表"; + } + if (type == ETableRule.HandWrite) + { + return "指定内容表"; + } + if (type == ETableRule.Create) + { + return "创建新的内容表"; + } + throw new Exception(); + } + + public static ETableRule GetEnumType(string typeStr) + { + var retval = ETableRule.Create; + + if (Equals(ETableRule.Choose, typeStr)) + { + retval = ETableRule.Choose; + } + else if (Equals(ETableRule.HandWrite, typeStr)) + { + retval = ETableRule.HandWrite; + } + else if (Equals(ETableRule.Create, typeStr)) + { + retval = ETableRule.Create; + } + + return retval; + } + + public static bool Equals(ETableRule type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, ETableRule type) + { + return Equals(type, typeStr); + } + } +} diff --git a/net452/SiteServer.CMS/Core/Enumerations/ETaxisType.cs b/net452/SiteServer.CMS/Core/Enumerations/ETaxisType.cs new file mode 100644 index 000000000..1198a8e5d --- /dev/null +++ b/net452/SiteServer.CMS/Core/Enumerations/ETaxisType.cs @@ -0,0 +1,436 @@ +using System; +using System.Collections.Generic; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Core.Enumerations +{ + public enum ETaxisType + { + OrderById, //内容ID(升序) + OrderByIdDesc, //内容ID(降序) + OrderByChannelId, //栏目ID(升序) + OrderByChannelIdDesc, //栏目ID(降序) + OrderByAddDate, //添加时间(升序) + OrderByAddDateDesc, //添加时间(降序) + OrderByLastEditDate, //更新时间(升序) + OrderByLastEditDateDesc, //更新时间(降序) + OrderByTaxis, //自定义排序(反方向) + OrderByTaxisDesc, //自定义排序 + OrderByHits, //按点击量排序 + OrderByHitsByDay, //按日点击量排序 + OrderByHitsByWeek, //按周点击量排序 + OrderByHitsByMonth, //按月点击量排序 + OrderByRandom //随机排序 + } + + public static class ETaxisTypeUtils + { + public static string GetValue(ETaxisType type) + { + if (type == ETaxisType.OrderById) + { + return nameof(ETaxisType.OrderById); + } + if (type == ETaxisType.OrderByIdDesc) + { + return nameof(ETaxisType.OrderByIdDesc); + } + if (type == ETaxisType.OrderByChannelId) + { + return nameof(ETaxisType.OrderByChannelId); + } + if (type == ETaxisType.OrderByChannelIdDesc) + { + return nameof(ETaxisType.OrderByChannelIdDesc); + } + if (type == ETaxisType.OrderByAddDate) + { + return nameof(ETaxisType.OrderByAddDate); + } + if (type == ETaxisType.OrderByAddDateDesc) + { + return nameof(ETaxisType.OrderByAddDateDesc); + } + if (type == ETaxisType.OrderByLastEditDate) + { + return nameof(ETaxisType.OrderByLastEditDate); + } + if (type == ETaxisType.OrderByLastEditDateDesc) + { + return nameof(ETaxisType.OrderByLastEditDateDesc); + } + if (type == ETaxisType.OrderByTaxis) + { + return nameof(ETaxisType.OrderByTaxis); + } + if (type == ETaxisType.OrderByTaxisDesc) + { + return nameof(ETaxisType.OrderByTaxisDesc); + } + if (type == ETaxisType.OrderByHits) + { + return nameof(ETaxisType.OrderByHits); + } + if (type == ETaxisType.OrderByHitsByDay) + { + return nameof(ETaxisType.OrderByHitsByDay); + } + if (type == ETaxisType.OrderByHitsByWeek) + { + return nameof(ETaxisType.OrderByHitsByWeek); + } + if (type == ETaxisType.OrderByHitsByMonth) + { + return nameof(ETaxisType.OrderByHitsByMonth); + } + if (type == ETaxisType.OrderByRandom) + { + return nameof(ETaxisType.OrderByRandom); + } + + throw new Exception(); + } + + public static string GetChannelOrderByString(ETaxisType taxisType) + { + return GetChannelOrderByString(taxisType, string.Empty, null); + } + + public static string GetChannelOrderByString(ETaxisType taxisType, string orderByString, List orderedContentIdList) + { + if (!string.IsNullOrEmpty(orderByString)) + { + if (orderByString.Trim().ToUpper().StartsWith("ORDER BY ")) + { + return orderByString; + } + return "ORDER BY " + orderByString; + } + + var retVal = string.Empty; + if (taxisType == ETaxisType.OrderById) + { + retVal = $"ORDER BY {nameof(IChannelInfo.Id)} ASC"; + } + else if (taxisType == ETaxisType.OrderByIdDesc) + { + retVal = $"ORDER BY {nameof(IChannelInfo.Id)} DESC"; + } + else if (taxisType == ETaxisType.OrderByChannelId) + { + retVal = $"ORDER BY {nameof(IChannelInfo.Id)} ASC"; + } + else if (taxisType == ETaxisType.OrderByChannelIdDesc) + { + retVal = $"ORDER BY {nameof(IChannelInfo.Id)} DESC"; + } + else if (taxisType == ETaxisType.OrderByAddDate) + { + retVal = $"ORDER BY {nameof(IChannelInfo.AddDate)} ASC"; + } + else if (taxisType == ETaxisType.OrderByAddDateDesc) + { + retVal = $"ORDER BY {nameof(IChannelInfo.AddDate)} DESC"; + } + else if (taxisType == ETaxisType.OrderByLastEditDate) + { + retVal = $"ORDER BY {nameof(IChannelInfo.AddDate)} ASC"; + } + else if (taxisType == ETaxisType.OrderByLastEditDateDesc) + { + retVal = $"ORDER BY {nameof(IChannelInfo.AddDate)} DESC"; + } + else if (taxisType == ETaxisType.OrderByTaxis) + { + retVal = $"ORDER BY {nameof(IChannelInfo.Taxis)} ASC"; + } + else if (taxisType == ETaxisType.OrderByTaxisDesc) + { + retVal = $"ORDER BY {nameof(IChannelInfo.Taxis)} DESC"; + } + else if (taxisType == ETaxisType.OrderByHits) + { + if (orderedContentIdList != null && orderedContentIdList.Count > 0) + { + orderedContentIdList.Reverse(); + retVal = + $"ORDER BY CHARINDEX(CONVERT(VARCHAR, {nameof(IChannelInfo.Id)}), '{TranslateUtils.ObjectCollectionToString(orderedContentIdList)}') DESC, {nameof(IChannelInfo.Taxis)} ASC"; + } + else + { + retVal = $"ORDER BY {nameof(IChannelInfo.Taxis)} ASC"; + } + } + else if (taxisType == ETaxisType.OrderByRandom) + { + retVal = SqlUtils.GetOrderByRandom(); + } + + return retVal; + } + + public static string GetContentOrderByString(ETaxisType taxisType) + { + return GetContentOrderByString(taxisType, string.Empty); + } + + public static string GetContentOrderByString(ETaxisType taxisType, string orderByString) + { + if (!string.IsNullOrEmpty(orderByString)) + { + if (orderByString.Trim().ToUpper().StartsWith("ORDER BY ")) + { + return orderByString; + } + return "ORDER BY " + orderByString; + } + + var retVal = string.Empty; + + if (taxisType == ETaxisType.OrderById) + { + retVal = $"ORDER BY {ContentAttribute.IsTop} DESC, {ContentAttribute.Id} ASC"; + } + else if (taxisType == ETaxisType.OrderByIdDesc) + { + retVal = $"ORDER BY {ContentAttribute.IsTop} DESC, {ContentAttribute.Id} DESC"; + } + else if (taxisType == ETaxisType.OrderByChannelId) + { + retVal = $"ORDER BY {ContentAttribute.IsTop} DESC, {ContentAttribute.ChannelId} ASC, {ContentAttribute.Id} DESC"; + } + else if (taxisType == ETaxisType.OrderByChannelIdDesc) + { + retVal = $"ORDER BY {ContentAttribute.IsTop} DESC, {ContentAttribute.ChannelId} DESC, {ContentAttribute.Id} DESC"; + } + else if (taxisType == ETaxisType.OrderByAddDate) + { + retVal = $"ORDER BY {ContentAttribute.IsTop} DESC, {ContentAttribute.AddDate} ASC, {ContentAttribute.Id} DESC"; + } + else if (taxisType == ETaxisType.OrderByAddDateDesc) + { + retVal = $"ORDER BY {ContentAttribute.IsTop} DESC, {ContentAttribute.AddDate} DESC, {ContentAttribute.Id} DESC"; + } + else if (taxisType == ETaxisType.OrderByLastEditDate) + { + retVal = $"ORDER BY {ContentAttribute.IsTop} DESC, {ContentAttribute.LastEditDate} ASC, {ContentAttribute.Id} DESC"; + } + else if (taxisType == ETaxisType.OrderByLastEditDateDesc) + { + retVal = $"ORDER BY {ContentAttribute.IsTop} DESC, {ContentAttribute.LastEditDate} DESC, {ContentAttribute.Id} DESC"; + } + else if (taxisType == ETaxisType.OrderByTaxis) + { + retVal = $"ORDER BY {ContentAttribute.IsTop} DESC, {ContentAttribute.Taxis} ASC, {ContentAttribute.Id} DESC"; + } + else if (taxisType == ETaxisType.OrderByTaxisDesc) + { + retVal = $"ORDER BY {ContentAttribute.IsTop} DESC, {ContentAttribute.Taxis} DESC, {ContentAttribute.Id} DESC"; + } + else if (taxisType == ETaxisType.OrderByHits) + { + retVal = $"ORDER BY {ContentAttribute.Hits} DESC, {ContentAttribute.Id} DESC"; + } + else if (taxisType == ETaxisType.OrderByHitsByDay) + { + retVal = $"ORDER BY {ContentAttribute.HitsByDay} DESC, {ContentAttribute.Id} DESC"; + } + else if (taxisType == ETaxisType.OrderByHitsByWeek) + { + retVal = $"ORDER BY {ContentAttribute.HitsByWeek} DESC, {ContentAttribute.Id} DESC"; + } + else if (taxisType == ETaxisType.OrderByHitsByMonth) + { + retVal = $"ORDER BY {ContentAttribute.HitsByMonth} DESC, {ContentAttribute.Id} DESC"; + } + else if (taxisType == ETaxisType.OrderByRandom) + { + retVal = SqlUtils.GetOrderByRandom(); + } + + return retVal; + } + + public static string GetContentOrderAttributeName(ETaxisType taxisType) + { + var retVal = ContentAttribute.Taxis; + + switch (taxisType) + { + case ETaxisType.OrderById: + case ETaxisType.OrderByIdDesc: + retVal = ContentAttribute.Id; + break; + case ETaxisType.OrderByChannelId: + case ETaxisType.OrderByChannelIdDesc: + retVal = ContentAttribute.ChannelId; + break; + case ETaxisType.OrderByAddDate: + case ETaxisType.OrderByAddDateDesc: + retVal = ContentAttribute.AddDate; + break; + case ETaxisType.OrderByLastEditDate: + case ETaxisType.OrderByLastEditDateDesc: + retVal = ContentAttribute.LastEditDate; + break; + case ETaxisType.OrderByHits: + retVal = ContentAttribute.Hits; + break; + case ETaxisType.OrderByHitsByDay: + retVal = ContentAttribute.HitsByDay; + break; + case ETaxisType.OrderByHitsByWeek: + retVal = ContentAttribute.HitsByWeek; + break; + case ETaxisType.OrderByHitsByMonth: + retVal = ContentAttribute.HitsByMonth; + break; + } + + return retVal; + } + + public static string GetText(ETaxisType type) + { + if (type == ETaxisType.OrderById) + { + return "内容ID(升序)"; + } + if (type == ETaxisType.OrderByIdDesc) + { + return "内容ID(降序)"; + } + if (type == ETaxisType.OrderByChannelId) + { + return "栏目ID(升序)"; + } + if (type == ETaxisType.OrderByChannelIdDesc) + { + return "栏目ID(降序)"; + } + if (type == ETaxisType.OrderByAddDate) + { + return "添加时间(升序)"; + } + if (type == ETaxisType.OrderByAddDateDesc) + { + return "添加时间(降序)"; + } + if (type == ETaxisType.OrderByLastEditDate) + { + return "更新时间(升序)"; + } + if (type == ETaxisType.OrderByLastEditDateDesc) + { + return "更新时间(降序)"; + } + if (type == ETaxisType.OrderByTaxis) + { + return "自定义排序(升序)"; + } + if (type == ETaxisType.OrderByTaxisDesc) + { + return "自定义排序(降序)"; + } + if (type == ETaxisType.OrderByHits) + { + return "点击量排序"; + } + if (type == ETaxisType.OrderByHitsByDay) + { + return "日点击量排序"; + } + if (type == ETaxisType.OrderByHitsByWeek) + { + return "周点击量排序"; + } + if (type == ETaxisType.OrderByHitsByMonth) + { + return "月点击量排序"; + } + throw new Exception(); + } + + public static ETaxisType GetEnumType(string typeStr) + { + var retVal = ETaxisType.OrderByTaxisDesc; + + if (Equals(ETaxisType.OrderById, typeStr)) + { + retVal = ETaxisType.OrderById; + } + else if (Equals(ETaxisType.OrderByIdDesc, typeStr)) + { + retVal = ETaxisType.OrderByIdDesc; + } + else if (Equals(ETaxisType.OrderByChannelId, typeStr)) + { + retVal = ETaxisType.OrderByChannelId; + } + else if (Equals(ETaxisType.OrderByChannelIdDesc, typeStr)) + { + retVal = ETaxisType.OrderByChannelIdDesc; + } + else if (Equals(ETaxisType.OrderByAddDate, typeStr)) + { + retVal = ETaxisType.OrderByAddDate; + } + else if (Equals(ETaxisType.OrderByAddDateDesc, typeStr)) + { + retVal = ETaxisType.OrderByAddDateDesc; + } + else if (Equals(ETaxisType.OrderByLastEditDate, typeStr)) + { + retVal = ETaxisType.OrderByLastEditDate; + } + else if (Equals(ETaxisType.OrderByLastEditDateDesc, typeStr)) + { + retVal = ETaxisType.OrderByLastEditDateDesc; + } + else if (Equals(ETaxisType.OrderByTaxis, typeStr)) + { + retVal = ETaxisType.OrderByTaxis; + } + else if (Equals(ETaxisType.OrderByTaxisDesc, typeStr)) + { + retVal = ETaxisType.OrderByTaxisDesc; + } + else if (Equals(ETaxisType.OrderByHits, typeStr)) + { + retVal = ETaxisType.OrderByHits; + } + else if (Equals(ETaxisType.OrderByHitsByDay, typeStr)) + { + retVal = ETaxisType.OrderByHitsByDay; + } + else if (Equals(ETaxisType.OrderByHitsByWeek, typeStr)) + { + retVal = ETaxisType.OrderByHitsByWeek; + } + else if (Equals(ETaxisType.OrderByHitsByMonth, typeStr)) + { + retVal = ETaxisType.OrderByHitsByMonth; + } + + return retVal; + } + + public static bool Equals(ETaxisType type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, ETaxisType type) + { + return Equals(type, typeStr); + } + } +} diff --git a/net452/SiteServer.CMS/Core/Enumerations/ETranslateContentType.cs b/net452/SiteServer.CMS/Core/Enumerations/ETranslateContentType.cs new file mode 100644 index 000000000..02e1a1be1 --- /dev/null +++ b/net452/SiteServer.CMS/Core/Enumerations/ETranslateContentType.cs @@ -0,0 +1,98 @@ +using System; + +namespace SiteServer.CMS.Core.Enumerations +{ + public enum ETranslateContentType + { + Copy, //复制 + Cut, //剪切 + Reference, //引用地址 + ReferenceContent, //引用内容 + } + + public static class ETranslateContentTypeUtils + { + public static string GetValue(ETranslateContentType type) + { + if (type == ETranslateContentType.Copy) + { + return "Copy"; + } + if (type == ETranslateContentType.Cut) + { + return "Cut"; + } + if (type == ETranslateContentType.Reference) + { + return "Reference"; + } + if (type == ETranslateContentType.ReferenceContent) + { + return "ReferenceContent"; + } + throw new Exception(); + } + + public static string GetText(ETranslateContentType type) + { + if (type == ETranslateContentType.Copy) + { + return "复制"; + } + if (type == ETranslateContentType.Cut) + { + return "剪切"; + } + if (type == ETranslateContentType.Reference) + { + return "引用地址"; + } + if (type == ETranslateContentType.ReferenceContent) + { + return "引用内容"; + } + throw new Exception(); + } + + public static ETranslateContentType GetEnumType(string typeStr) + { + var retval = ETranslateContentType.Copy; + + if (Equals(ETranslateContentType.Copy, typeStr)) + { + retval = ETranslateContentType.Copy; + } + else if (Equals(ETranslateContentType.Cut, typeStr)) + { + retval = ETranslateContentType.Cut; + } + else if (Equals(ETranslateContentType.Reference, typeStr)) + { + retval = ETranslateContentType.Reference; + } + else if (Equals(ETranslateContentType.ReferenceContent, typeStr)) + { + retval = ETranslateContentType.ReferenceContent; + } + + return retval; + } + + public static bool Equals(ETranslateContentType type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, ETranslateContentType type) + { + return Equals(type, typeStr); + } + + + } +} diff --git a/net452/SiteServer.CMS/Core/Enumerations/ETranslateType.cs b/net452/SiteServer.CMS/Core/Enumerations/ETranslateType.cs new file mode 100644 index 000000000..39f1a59da --- /dev/null +++ b/net452/SiteServer.CMS/Core/Enumerations/ETranslateType.cs @@ -0,0 +1,86 @@ +using System; + +namespace SiteServer.CMS.Core.Enumerations +{ + /// + /// 批量转移类型 + /// + public enum ETranslateType + { + Content, //仅转移内容 + Channel, //仅转移栏目 + All //转移栏目及内容 + } + + public static class ETranslateTypeUtils + { + public static string GetValue(ETranslateType type) + { + if (type == ETranslateType.Content) + { + return "Content"; + } + if (type == ETranslateType.Channel) + { + return "Channel"; + } + if (type == ETranslateType.All) + { + return "All"; + } + throw new Exception(); + } + + public static string GetText(ETranslateType type) + { + if (type == ETranslateType.Content) + { + return "仅转移内容"; + } + if (type == ETranslateType.Channel) + { + return "仅转移栏目"; + } + if (type == ETranslateType.All) + { + return "转移栏目及内容"; + } + throw new Exception(); + } + + public static ETranslateType GetEnumType(string typeStr) + { + var retval = ETranslateType.Content; + + if (Equals(ETranslateType.Content, typeStr)) + { + retval = ETranslateType.Content; + } + else if (Equals(ETranslateType.Channel, typeStr)) + { + retval = ETranslateType.Channel; + } + else if (Equals(ETranslateType.All, typeStr)) + { + retval = ETranslateType.All; + } + + return retval; + } + + public static bool Equals(ETranslateType type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, ETranslateType type) + { + return Equals(type, typeStr); + } + } +} diff --git a/net452/SiteServer.CMS/Core/FileUtility.cs b/net452/SiteServer.CMS/Core/FileUtility.cs new file mode 100644 index 000000000..d6a7139ef --- /dev/null +++ b/net452/SiteServer.CMS/Core/FileUtility.cs @@ -0,0 +1,139 @@ +using System; +using SiteServer.Utils; +using System.Collections.Generic; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Core +{ + public static class FileUtility + { + public static void AddWaterMark(SiteInfo siteInfo, string imagePath) + { + try + { + var fileExtName = PathUtils.GetExtension(imagePath); + if (EFileSystemTypeUtils.IsImage(fileExtName)) + { + if (siteInfo.IsWaterMark) + { + if (siteInfo.IsImageWaterMark) + { + if (!string.IsNullOrEmpty(siteInfo.WaterMarkImagePath)) + { + ImageUtils.AddImageWaterMark(imagePath, PathUtility.MapPath(siteInfo, siteInfo.WaterMarkImagePath), siteInfo.WaterMarkPosition, siteInfo.WaterMarkTransparency, siteInfo.WaterMarkMinWidth, siteInfo.WaterMarkMinHeight); + } + } + else + { + if (!string.IsNullOrEmpty(siteInfo.WaterMarkFormatString)) + { + var now = DateTime.Now; + ImageUtils.AddTextWaterMark(imagePath, string.Format(siteInfo.WaterMarkFormatString, DateUtils.GetDateString(now), DateUtils.GetTimeString(now)), siteInfo.WaterMarkFontName, siteInfo.WaterMarkFontSize, siteInfo.WaterMarkPosition, siteInfo.WaterMarkTransparency, siteInfo.WaterMarkMinWidth, siteInfo.WaterMarkMinHeight); + } + } + } + } + } + catch + { + // ignored + } + } + + public static void MoveFile(SiteInfo sourceSiteInfo, SiteInfo destSiteInfo, string relatedUrl) + { + if (!string.IsNullOrEmpty(relatedUrl)) + { + var sourceFilePath = PathUtility.MapPath(sourceSiteInfo, relatedUrl); + var descFilePath = PathUtility.MapPath(destSiteInfo, relatedUrl); + if (FileUtils.IsFileExists(sourceFilePath)) + { + FileUtils.MoveFile(sourceFilePath, descFilePath, false); + } + } + } + + public static void MoveFileByContentInfo(SiteInfo sourceSiteInfo, SiteInfo destSiteInfo, ContentInfo contentInfo) + { + if (contentInfo == null || sourceSiteInfo.Id == destSiteInfo.Id) return; + + try + { + var fileUrls = new List + { + contentInfo.Get(ContentAttribute.ImageUrl), + contentInfo.Get(ContentAttribute.VideoUrl), + contentInfo.Get(ContentAttribute.FileUrl) + }; + + foreach (var url in TranslateUtils.StringCollectionToStringList(contentInfo.Get(ContentAttribute.GetExtendAttributeName(ContentAttribute.ImageUrl)))) + { + if (!fileUrls.Contains(url)) + { + fileUrls.Add(url); + } + } + foreach (var url in TranslateUtils.StringCollectionToStringList(contentInfo.Get(ContentAttribute.GetExtendAttributeName(ContentAttribute.VideoUrl)))) + { + if (!fileUrls.Contains(url)) + { + fileUrls.Add(url); + } + } + foreach (var url in TranslateUtils.StringCollectionToStringList(contentInfo.Get(ContentAttribute.GetExtendAttributeName(ContentAttribute.FileUrl)))) + { + if (!fileUrls.Contains(url)) + { + fileUrls.Add(url); + } + } + foreach (var url in RegexUtils.GetOriginalImageSrcs(contentInfo.Get(ContentAttribute.Content))) + { + if (!fileUrls.Contains(url)) + { + fileUrls.Add(url); + } + } + foreach (var url in RegexUtils.GetOriginalLinkHrefs(contentInfo.Get(ContentAttribute.Content))) + { + if (!fileUrls.Contains(url) && PageUtils.IsVirtualUrl(url)) + { + fileUrls.Add(url); + } + } + + foreach (var fileUrl in fileUrls) + { + if (!string.IsNullOrEmpty(fileUrl) && PageUtility.IsVirtualUrl(fileUrl)) + { + MoveFile(sourceSiteInfo, destSiteInfo, fileUrl); + } + } + } + catch + { + // ignored + } + } + + public static void MoveFileByVirtaulUrl(SiteInfo sourceSiteInfo, SiteInfo destSiteInfo, string fileVirtaulUrl) + { + if (string.IsNullOrEmpty(fileVirtaulUrl) || sourceSiteInfo.Id == destSiteInfo.Id) return; + + try + { + if (PageUtility.IsVirtualUrl(fileVirtaulUrl)) + { + MoveFile(sourceSiteInfo, destSiteInfo, fileVirtaulUrl); + } + } + catch + { + // ignored + } + } + } +} diff --git a/net452/SiteServer.CMS/Core/InputParserUtility.cs b/net452/SiteServer.CMS/Core/InputParserUtility.cs new file mode 100644 index 000000000..6edecb6ab --- /dev/null +++ b/net452/SiteServer.CMS/Core/InputParserUtility.cs @@ -0,0 +1,385 @@ +using System.Collections; +using System.Collections.Specialized; +using System.Web.UI.HtmlControls; +using SiteServer.CMS.Core.RestRoutes; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Core +{ + public static class InputParserUtility + { + public static string GetContentByTableStyle(string content, SiteInfo siteInfo, TableStyleInfo styleInfo) + { + if (!string.IsNullOrEmpty(content)) + { + return GetContentByTableStyle(content, ",", siteInfo, styleInfo, string.Empty, null, string.Empty, false, false, false); + } + return string.Empty; + } + + public static string GetContentByTableStyle(string content, string separator, SiteInfo siteInfo, TableStyleInfo styleInfo, string formatString, NameValueCollection attributes, string innerHtml, bool isStlEntity, bool isLower, bool isUpper) + { + var parsedContent = content; + + var inputType = styleInfo.Type; + + if (inputType == InputType.Date) + { + var dateTime = TranslateUtils.ToDateTime(content); + if (dateTime != DateUtils.SqlMinValue) + { + if (string.IsNullOrEmpty(formatString)) + { + formatString = DateUtils.FormatStringDateOnly; + } + parsedContent = DateUtils.Format(dateTime, formatString); + } + else + { + parsedContent = string.Empty; + } + } + else if (inputType == InputType.DateTime) + { + var dateTime = TranslateUtils.ToDateTime(content); + if (dateTime != DateUtils.SqlMinValue) + { + if (string.IsNullOrEmpty(formatString)) + { + formatString = DateUtils.FormatStringDateTime; + } + parsedContent = DateUtils.Format(dateTime, formatString); + } + else + { + parsedContent = string.Empty; + } + } + else if (inputType == InputType.CheckBox || inputType == InputType.Radio || inputType == InputType.SelectMultiple || inputType == InputType.SelectOne)//选择类型 + { + var selectedTexts = new ArrayList(); + var selectedValues = TranslateUtils.StringCollectionToStringList(content); + var styleItems = styleInfo.StyleItems; + if (styleItems != null) + { + foreach (var itemInfo in styleItems) + { + if (selectedValues.Contains(itemInfo.ItemValue)) + { + selectedTexts.Add(isStlEntity ? itemInfo.ItemValue : itemInfo.ItemTitle); + } + } + } + + parsedContent = separator == null ? TranslateUtils.ObjectCollectionToString(selectedTexts) : TranslateUtils.ObjectCollectionToString(selectedTexts, separator); + } + //else if (styleInfo.InputType == InputType.TextArea) + //{ + // parsedContent = StringUtils.ReplaceNewlineToBR(parsedContent); + //} + else if (inputType == InputType.TextEditor) + { + parsedContent = ContentUtility.TextEditorContentDecode(siteInfo, parsedContent, true); + } + else if (inputType == InputType.Image) + { + parsedContent = GetImageOrFlashHtml(siteInfo, parsedContent, attributes, isStlEntity); + } + else if (inputType == InputType.Video) + { + parsedContent = GetVideoHtml(siteInfo, parsedContent, attributes, isStlEntity); + } + else if (inputType == InputType.File) + { + parsedContent = GetFileHtmlWithoutCount(siteInfo, parsedContent, attributes, innerHtml, isStlEntity, isLower, isUpper); + } + + return parsedContent; + } + + public static string GetContentByTableStyle(ContentInfo contentInfo, string separator, SiteInfo siteInfo, TableStyleInfo styleInfo, string formatString, int no, NameValueCollection attributes, string innerHtml, bool isStlEntity, bool isLower, bool isUpper) + { + var value = contentInfo.Get(styleInfo.AttributeName); + var parsedContent = string.Empty; + + var inputType = styleInfo.Type; + + if (inputType == InputType.Date) + { + var dateTime = TranslateUtils.ToDateTime(value); + if (dateTime != DateUtils.SqlMinValue) + { + if (string.IsNullOrEmpty(formatString)) + { + formatString = DateUtils.FormatStringDateOnly; + } + parsedContent = DateUtils.Format(dateTime, formatString); + } + } + else if (inputType == InputType.DateTime) + { + var dateTime = TranslateUtils.ToDateTime(value); + if (dateTime != DateUtils.SqlMinValue) + { + if (string.IsNullOrEmpty(formatString)) + { + formatString = DateUtils.FormatStringDateTime; + } + parsedContent = DateUtils.Format(dateTime, formatString); + } + } + else if (inputType == InputType.CheckBox || inputType == InputType.Radio || inputType == InputType.SelectMultiple || inputType == InputType.SelectOne)//选择类型 + { + var selectedTexts = new ArrayList(); + var selectedValues = TranslateUtils.StringCollectionToStringList(value); + var styleItems = styleInfo.StyleItems; + if (styleItems != null) + { + foreach (var itemInfo in styleItems) + { + if (selectedValues.Contains(itemInfo.ItemValue)) + { + selectedTexts.Add(isStlEntity ? itemInfo.ItemValue : itemInfo.ItemTitle); + } + } + } + + parsedContent = separator == null ? TranslateUtils.ObjectCollectionToString(selectedTexts) : TranslateUtils.ObjectCollectionToString(selectedTexts, separator); + } + else if (inputType == InputType.TextEditor) + { + parsedContent = ContentUtility.TextEditorContentDecode(siteInfo, value, true); + } + else if (inputType == InputType.Image) + { + if (no <= 1) + { + parsedContent = GetImageOrFlashHtml(siteInfo, value, attributes, isStlEntity); + } + else + { + var extendAttributeName = ContentAttribute.GetExtendAttributeName(styleInfo.AttributeName); + var extendValues = contentInfo.Get(extendAttributeName); + if (!string.IsNullOrEmpty(extendValues)) + { + var index = 2; + foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) + { + if (index == no) + { + parsedContent = GetImageOrFlashHtml(siteInfo, extendValue, attributes, isStlEntity); + break; + } + index++; + } + } + } + } + else if (inputType == InputType.Video) + { + if (no <= 1) + { + parsedContent = GetVideoHtml(siteInfo, value, attributes, isStlEntity); + } + else + { + var extendAttributeName = ContentAttribute.GetExtendAttributeName(styleInfo.AttributeName); + var extendValues = contentInfo.Get(extendAttributeName); + if (!string.IsNullOrEmpty(extendValues)) + { + var index = 2; + foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) + { + if (index == no) + { + parsedContent = GetVideoHtml(siteInfo, extendValue, attributes, isStlEntity); + break; + } + index++; + } + } + } + } + else if (inputType == InputType.File) + { + if (no <= 1) + { + parsedContent = GetFileHtmlWithoutCount(siteInfo, value, attributes, innerHtml, isStlEntity, isLower, isUpper); + } + else + { + var extendAttributeName = ContentAttribute.GetExtendAttributeName(styleInfo.AttributeName); + var extendValues = contentInfo.Get(extendAttributeName); + if (!string.IsNullOrEmpty(extendValues)) + { + var index = 2; + foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) + { + if (index == no) + { + parsedContent = GetFileHtmlWithoutCount(siteInfo, extendValue, attributes, innerHtml, isStlEntity, isLower, isUpper); + break; + } + index++; + } + } + } + } + else + { + parsedContent = value; + } + + return parsedContent; + } + + public static string GetImageOrFlashHtml(SiteInfo siteInfo, string imageUrl, NameValueCollection attributes, bool isStlEntity) + { + var retVal = string.Empty; + if (!string.IsNullOrEmpty(imageUrl)) + { + imageUrl = PageUtility.ParseNavigationUrl(siteInfo, imageUrl, false); + if (isStlEntity) + { + retVal = imageUrl; + } + else + { + if (!imageUrl.ToUpper().Trim().EndsWith(".SWF")) + { + var htmlImage = new HtmlImage(); + ControlUtils.AddAttributesIfNotExists(htmlImage, attributes); + htmlImage.Src = imageUrl; + retVal = ControlUtils.GetControlRenderHtml(htmlImage); + } + else + { + var width = 100; + var height = 100; + if (attributes != null) + { + if (!string.IsNullOrEmpty(attributes["width"])) + { + try + { + width = int.Parse(attributes["width"]); + } + catch + { + // ignored + } + } + if (!string.IsNullOrEmpty(attributes["height"])) + { + try + { + height = int.Parse(attributes["height"]); + } + catch + { + // ignored + } + } + } + retVal = $@" + + + + + +"; + } + } + } + return retVal; + } + + public static string GetVideoHtml(SiteInfo siteInfo, string videoUrl, NameValueCollection attributes, bool isStlEntity) + { + var retVal = string.Empty; + if (!string.IsNullOrEmpty(videoUrl)) + { + videoUrl = PageUtility.ParseNavigationUrl(siteInfo, videoUrl, false); + if (isStlEntity) + { + retVal = videoUrl; + } + else + { + retVal = $@" + +"; + } + } + return retVal; + } + + public static string GetFileHtmlWithCount(SiteInfo siteInfo, int channelId, int contentId, string fileUrl, NameValueCollection attributes, string innerHtml, bool isStlEntity, bool isLower, bool isUpper) + { + if (siteInfo == null || string.IsNullOrEmpty(fileUrl)) return string.Empty; + + string retVal; + if (isStlEntity) + { + retVal = ApiRouteActionsDownload.GetUrl(ApiManager.ApiUrl, siteInfo.Id, channelId, contentId, fileUrl); + } + else + { + var stlAnchor = new HtmlAnchor(); + ControlUtils.AddAttributesIfNotExists(stlAnchor, attributes); + stlAnchor.HRef = ApiRouteActionsDownload.GetUrl(ApiManager.ApiUrl, siteInfo.Id, channelId, contentId, fileUrl); + stlAnchor.InnerHtml = string.IsNullOrEmpty(innerHtml) ? PageUtils.GetFileNameFromUrl(fileUrl) : innerHtml; + + if (isLower) + { + stlAnchor.InnerHtml = stlAnchor.InnerHtml.ToLower(); + } + if (isUpper) + { + stlAnchor.InnerHtml = stlAnchor.InnerHtml.ToUpper(); + } + + retVal = ControlUtils.GetControlRenderHtml(stlAnchor); + } + return retVal; + } + + public static string GetFileHtmlWithoutCount(SiteInfo siteInfo, string fileUrl, NameValueCollection attributes, string innerHtml, bool isStlEntity, bool isLower, bool isUpper) + { + if (siteInfo == null || string.IsNullOrEmpty(fileUrl)) return string.Empty; + + string retVal; + if (isStlEntity) + { + retVal = ApiRouteActionsDownload.GetUrl(ApiManager.ApiUrl, siteInfo.Id, fileUrl); + } + else + { + var stlAnchor = new HtmlAnchor(); + ControlUtils.AddAttributesIfNotExists(stlAnchor, attributes); + stlAnchor.HRef = ApiRouteActionsDownload.GetUrl(ApiManager.ApiUrl, siteInfo.Id, fileUrl); + stlAnchor.InnerHtml = string.IsNullOrEmpty(innerHtml) ? PageUtils.GetFileNameFromUrl(fileUrl) : innerHtml; + + if (isLower) + { + stlAnchor.InnerHtml = stlAnchor.InnerHtml.ToLower(); + } + if (isUpper) + { + stlAnchor.InnerHtml = stlAnchor.InnerHtml.ToUpper(); + } + + retVal = ControlUtils.GetControlRenderHtml(stlAnchor); + } + return retVal; + } + + + } +} diff --git a/net452/SiteServer.CMS/Core/InputTypeUtils.cs b/net452/SiteServer.CMS/Core/InputTypeUtils.cs new file mode 100644 index 000000000..62aeaa08b --- /dev/null +++ b/net452/SiteServer.CMS/Core/InputTypeUtils.cs @@ -0,0 +1,292 @@ +using System; +using System.Collections.Generic; +using SiteServer.CMS.Database.Core; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Core +{ + public static class InputTypeUtils + { + public static string GetText(InputType type) + { + if (type == InputType.CheckBox) + { + return "复选框"; + } + if (type == InputType.Radio) + { + return "单选框"; + } + if (type == InputType.SelectOne) + { + return "下拉列表(单选)"; + } + if (type == InputType.SelectMultiple) + { + return "下拉列表(多选)"; + } + if (type == InputType.SelectCascading) + { + return "下拉列表(级联)"; + } + if (type == InputType.Date) + { + return "日期选择框"; + } + if (type == InputType.DateTime) + { + return "日期时间选择框"; + } + if (type == InputType.Image) + { + return "图片"; + } + if (type == InputType.Video) + { + return "视频"; + } + if (type == InputType.File) + { + return "附件"; + } + if (type == InputType.Text) + { + return "文本框(单行)"; + } + if (type == InputType.TextArea) + { + return "文本框(多行)"; + } + if (type == InputType.TextEditor) + { + return "内容编辑器"; + } + if (type == InputType.Customize) + { + return "自定义"; + } + if (type == InputType.Hidden) + { + return "隐藏"; + } + + throw new Exception(); + } + + public static InputType GetEnumType(string typeStr) + { + var retVal = InputType.Text; + + if (Equals(InputType.CheckBox, typeStr)) + { + retVal = InputType.CheckBox; + } + else if (Equals(InputType.Radio, typeStr)) + { + retVal = InputType.Radio; + } + else if (Equals(InputType.SelectOne, typeStr)) + { + retVal = InputType.SelectOne; + } + else if (Equals(InputType.SelectMultiple, typeStr)) + { + retVal = InputType.SelectMultiple; + } + else if (Equals(InputType.SelectCascading, typeStr)) + { + retVal = InputType.SelectCascading; + } + else if (Equals(InputType.Date, typeStr)) + { + retVal = InputType.Date; + } + else if (Equals(InputType.DateTime, typeStr)) + { + retVal = InputType.DateTime; + } + else if (Equals(InputType.Image, typeStr)) + { + retVal = InputType.Image; + } + else if (Equals(InputType.Video, typeStr)) + { + retVal = InputType.Video; + } + else if (Equals(InputType.File, typeStr)) + { + retVal = InputType.File; + } + else if (Equals(InputType.Text, typeStr)) + { + retVal = InputType.Text; + } + else if (Equals(InputType.TextArea, typeStr)) + { + retVal = InputType.TextArea; + } + else if (Equals(InputType.TextEditor, typeStr)) + { + retVal = InputType.TextEditor; + } + else if (Equals(InputType.Customize, typeStr)) + { + retVal = InputType.Customize; + } + else if (Equals(InputType.Hidden, typeStr)) + { + retVal = InputType.Hidden; + } + + return retVal; + } + + public static bool Equals(InputType type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(type.Value.ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, InputType type) + { + return Equals(type, typeStr); + } + + public static bool EqualsAny(InputType type, params InputType[] types) + { + foreach (var theType in types) + { + if (type == theType) + { + return true; + } + } + return false; + } + + public static bool IsWithStyleItems(InputType type) + { + if (type == InputType.CheckBox || type == InputType.Radio || type == InputType.SelectMultiple || type == InputType.SelectOne || type == InputType.SelectCascading) + { + return true; + } + return false; + } + + public static bool IsPureString(InputType type) + { + if (type == InputType.Date || type == InputType.DateTime || type == InputType.CheckBox || type == InputType.Radio || type == InputType.SelectMultiple || type == InputType.SelectOne || type == InputType.Image || type == InputType.Video || type == InputType.File || type == InputType.SelectCascading) + { + return false; + } + return true; + } + + public static List> GetInputTypes(string tableName) + { + if (tableName == DataProvider.User.TableName) + { + return new List> + { + new KeyValuePair(InputType.Text, GetText(InputType.Text)), + new KeyValuePair(InputType.TextArea, GetText(InputType.TextArea)), + new KeyValuePair(InputType.CheckBox, GetText(InputType.CheckBox)), + new KeyValuePair(InputType.Radio, GetText(InputType.Radio)), + new KeyValuePair(InputType.SelectOne, GetText(InputType.SelectOne)), + new KeyValuePair(InputType.SelectMultiple, GetText(InputType.SelectMultiple)), + new KeyValuePair(InputType.Date, GetText(InputType.Date)), + new KeyValuePair(InputType.DateTime, GetText(InputType.DateTime)), + new KeyValuePair(InputType.Image, GetText(InputType.Image)), + new KeyValuePair(InputType.Video, GetText(InputType.Video)), + new KeyValuePair(InputType.File, GetText(InputType.File)), + new KeyValuePair(InputType.Hidden, GetText(InputType.Hidden)) + }; + } + + return new List> + { + new KeyValuePair(InputType.Text, GetText(InputType.Text)), + new KeyValuePair(InputType.TextArea, GetText(InputType.TextArea)), + new KeyValuePair(InputType.TextEditor, GetText(InputType.TextEditor)), + new KeyValuePair(InputType.CheckBox, GetText(InputType.CheckBox)), + new KeyValuePair(InputType.Radio, GetText(InputType.Radio)), + new KeyValuePair(InputType.SelectOne, GetText(InputType.SelectOne)), + new KeyValuePair(InputType.SelectMultiple, GetText(InputType.SelectMultiple)), + new KeyValuePair(InputType.SelectCascading, GetText(InputType.SelectCascading)), + new KeyValuePair(InputType.Date, GetText(InputType.Date)), + new KeyValuePair(InputType.DateTime, GetText(InputType.DateTime)), + new KeyValuePair(InputType.Image, GetText(InputType.Image)), + new KeyValuePair(InputType.Video, GetText(InputType.Video)), + new KeyValuePair(InputType.File, GetText(InputType.File)), + new KeyValuePair(InputType.Customize, GetText(InputType.Customize)), + new KeyValuePair(InputType.Hidden, GetText(InputType.Hidden)) + }; + } + + public static string ParseString(InputType inputType, string content, string replace, string to, int startIndex, int length, int wordNum, string ellipsis, bool isClearTags, bool isReturnToBr, bool isLower, bool isUpper, string formatString) + { + return IsPureString(inputType) ? ParseString(content, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString) : content; + } + + private static string ParseString(string content, string replace, string to, int startIndex, int length, int wordNum, string ellipsis, bool isClearTags, bool isReturnToBr, bool isLower, bool isUpper, string formatString) + { + var parsedContent = content; + + if (!string.IsNullOrEmpty(replace)) + { + parsedContent = StringUtils.ParseReplace(parsedContent, replace, to); + } + + if (isClearTags) + { + parsedContent = StringUtils.StripTags(parsedContent); + } + + if (!string.IsNullOrEmpty(parsedContent)) + { + if (startIndex > 0 || length > 0) + { + try + { + parsedContent = length > 0 ? parsedContent.Substring(startIndex, length) : parsedContent.Substring(startIndex); + } + catch + { + // ignored + } + } + + if (wordNum > 0) + { + parsedContent = StringUtils.MaxLengthText(parsedContent, wordNum, ellipsis); + } + + if (isReturnToBr) + { + parsedContent = StringUtils.ReplaceNewlineToBr(parsedContent); + } + + if (!string.IsNullOrEmpty(formatString)) + { + parsedContent = string.Format(formatString, parsedContent); + } + + if (isLower) + { + parsedContent = parsedContent.ToLower(); + } + if (isUpper) + { + parsedContent = parsedContent.ToUpper(); + } + } + + return parsedContent; + } + } +} diff --git a/net452/SiteServer.CMS/Core/LogUtils.cs b/net452/SiteServer.CMS/Core/LogUtils.cs new file mode 100644 index 000000000..c866c2653 --- /dev/null +++ b/net452/SiteServer.CMS/Core/LogUtils.cs @@ -0,0 +1,236 @@ +using System; +using System.Collections.Generic; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.StlParser.Model; +using SiteServer.Utils; + +namespace SiteServer.CMS.Core +{ + public static class LogUtils + { + private const string CategoryStl = "stl"; + private const string CategoryAdmin = "admin"; + private const string CategoryHome = "home"; + private const string CategoryApi = "api"; + + public static readonly Lazy>> AllCategoryList = new Lazy>>( + () => + { + var list = new List> + { + new KeyValuePair(CategoryStl, "STL 解析错误"), + new KeyValuePair(CategoryAdmin, "后台错误"), + new KeyValuePair(CategoryHome, "用户中心错误"), + new KeyValuePair(CategoryApi, "API错误") + }; + return list; + }); + + private static int AddErrorLog(ErrorLogInfo logInfo) + { + try + { + if (!ConfigManager.Instance.IsLogError) return 0; + + DataProvider.ErrorLog.DeleteIfThreshold(); + + return DataProvider.ErrorLog.Insert(logInfo); + } + catch + { + // ignored + } + + return 0; + } + + public static int AddErrorLog(Exception ex, string summary = "") + { + //0, CategoryAdmin, string.Empty, ex.Message, ex.StackTrace, summary, DateTime.Now + return AddErrorLog(new ErrorLogInfo + { + Category = CategoryAdmin, + PluginId = string.Empty, + Message = ex.Message, + Stacktrace = ex.StackTrace, + Summary = summary, + AddDate = DateTime.Now + }); + } + public static void AddErrorLog(string pluginId, Exception ex, string summary = "") + { + AddErrorLog(new ErrorLogInfo + { + Category = CategoryAdmin, + PluginId = pluginId, + Message = ex.Message, + Stacktrace = ex.StackTrace, + Summary = summary, + AddDate = DateTime.Now + }); + } + + public static string AddStlErrorLog(PageInfo pageInfo, string elementName, string stlContent, Exception ex) + { + var summary = string.Empty; + if (pageInfo != null) + { + summary = $@"站点名称:{pageInfo.SiteInfo.SiteName}, +模板类型:{TemplateTypeUtils.GetText(pageInfo.TemplateInfo.Type)}, +模板名称:{pageInfo.TemplateInfo.TemplateName} +
    "; + } + + summary += $@"STL标签:{StringUtils.HtmlEncode(stlContent)}"; + AddErrorLog(new ErrorLogInfo + { + Category = CategoryStl, + PluginId = string.Empty, + Message = ex.Message, + Stacktrace = ex.StackTrace, + Summary = summary, + AddDate = DateTime.Now + }); + + return $@" +"; + } + + public static void AddSiteLog(int siteId, string adminName, string action) + { + AddSiteLog(siteId, 0, 0, adminName, action, string.Empty); + } + + public static void AddSiteLog(int siteId, string adminName, string action, string summary) + { + AddSiteLog(siteId, 0, 0, adminName, action, summary); + } + + public static void AddSiteLog(int siteId, int channelId, string adminName, string action, string summary) + { + AddSiteLog(siteId, channelId, 0, adminName, action, summary); + } + + public static void AddSiteLog(int siteId, int channelId, int contentId, string adminName, string action, string summary) + { + if (!ConfigManager.Instance.IsLogSite) return; + + if (siteId <= 0) + { + AddAdminLog(adminName, action, summary); + } + else + { + try + { + DataProvider.SiteLog.DeleteIfThreshold(); + + if (!string.IsNullOrEmpty(action)) + { + action = StringUtils.MaxLengthText(action, 250); + } + if (!string.IsNullOrEmpty(summary)) + { + summary = StringUtils.MaxLengthText(summary, 250); + } + if (channelId < 0) + { + channelId = -channelId; + } + var siteLogInfo = new SiteLogInfo + { + SiteId = siteId, + ChannelId = channelId, + ContentId = contentId, + UserName = adminName, + IpAddress = FxUtils.GetIpAddress(), + AddDate = DateTime.Now, + Action = action, + Summary = summary + }; + + DataProvider.SiteLog.Insert(siteLogInfo); + } + catch (Exception ex) + { + AddErrorLog(ex); + } + } + } + + public static void AddAdminLog(string adminName, string action, string summary = "") + { + if (!ConfigManager.Instance.IsLogAdmin) return; + + try + { + DataProvider.Log.DeleteIfThreshold(); + + if (!string.IsNullOrEmpty(action)) + { + action = StringUtils.MaxLengthText(action, 250); + } + if (!string.IsNullOrEmpty(summary)) + { + summary = StringUtils.MaxLengthText(summary, 250); + } + var logInfo = new LogInfo + { + UserName = adminName, + IpAddress = FxUtils.GetIpAddress(), + AddDate = DateTime.Now, + Action = action, + Summary = summary + }; + + DataProvider.Log.Insert(logInfo); + } + catch (Exception ex) + { + AddErrorLog(ex); + } + } + + public static void AddUserLoginLog(string userName) + { + AddUserLog(userName, "用户登录", string.Empty); + } + + public static void AddUserLog(string userName, string actionType, string summary) + { + if (!ConfigManager.Instance.IsLogUser) return; + + try + { + DataProvider.UserLog.DeleteIfThreshold(); + + if (!string.IsNullOrEmpty(summary)) + { + summary = StringUtils.MaxLengthText(summary, 250); + } + + var userLogInfo = new UserLogInfo + { + UserName = userName, + IpAddress = FxUtils.GetIpAddress(), + AddDate = DateTime.Now, + Action = actionType, + Summary = summary + }; + + DataProvider.UserLog.Insert(userLogInfo); + } + catch (Exception ex) + { + AddErrorLog(ex); + } + } + } +} diff --git a/net452/SiteServer.CMS/Core/Office/AccessDao.cs b/net452/SiteServer.CMS/Core/Office/AccessDao.cs new file mode 100644 index 000000000..9fcefaf34 --- /dev/null +++ b/net452/SiteServer.CMS/Core/Office/AccessDao.cs @@ -0,0 +1,163 @@ +using System.Data; +using System.Data.OleDb; +using System.Collections.Generic; +using System.Text; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Core.Office +{ + public class AccessDao + { + private readonly OleDbConnection _connection; + + public AccessDao(string filePath) + { + ConnectionString = $"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={filePath};User Id=;Password=;"; + _connection = new OleDbConnection(ConnectionString); + } + + public string ConnectionString { get; } + + public string GetCreateTableSqlString(string nodeName, List tableStyleInfoList, List displayAttributes) + { + var createBuilder = new StringBuilder(); + createBuilder.Append($"CREATE TABLE {nodeName} ( "); + + foreach (var tableStyleInfo in tableStyleInfoList) + { + if (displayAttributes.Contains(tableStyleInfo.AttributeName)) + { + createBuilder.Append($" [{tableStyleInfo.DisplayName}] memo, "); + } + } + + createBuilder.Length = createBuilder.Length - 2; + createBuilder.Append(" )"); + + return createBuilder.ToString(); + } + + public List GetInsertSqlStringList(string nodeName, int siteId, int channelId, List styleInfoList, List displayAttributes, IList contentIdList, bool isPeriods, string dateFrom, string dateTo, ETriState checkedState, out bool isExport) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + var insertSqlList = new List(); + + var preInsertBuilder = new StringBuilder(); + preInsertBuilder.Append($"INSERT INTO {nodeName} ("); + + foreach (var tableStyleInfo in styleInfoList) + { + if (displayAttributes.Contains(tableStyleInfo.AttributeName)) + { + preInsertBuilder.Append($"[{tableStyleInfo.DisplayName}], "); + } + } + + preInsertBuilder.Length = preInsertBuilder.Length - 2; + preInsertBuilder.Append(") VALUES ("); + + if (contentIdList == null || contentIdList.Count == 0) + { + contentIdList = channelInfo.ContentRepository.GetContentIdList(channelId, isPeriods, dateFrom, dateTo, checkedState); + } + + isExport = contentIdList.Count > 0; + + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var insertBuilder = new StringBuilder(); + insertBuilder.Append(preInsertBuilder); + + foreach (var tableStyleInfo in styleInfoList) + { + if (displayAttributes.Contains(tableStyleInfo.AttributeName)) + { + var value = contentInfo.Get(tableStyleInfo.AttributeName); + insertBuilder.Append($"'{SqlUtils.ToSqlString(StringUtils.StripTags(value))}', "); + } + } + + insertBuilder.Length = insertBuilder.Length - 2; + insertBuilder.Append(") "); + + insertSqlList.Add(insertBuilder.ToString()); + } + return insertSqlList; + } + + public bool ExecuteSqlString(string sqlString) + { + bool resultState; + OleDbTransaction myTrans = null; + + try + { + _connection.Open(); + myTrans = _connection.BeginTransaction(); + var command = new OleDbCommand(sqlString, _connection, myTrans); + command.ExecuteNonQuery(); + myTrans.Commit(); + resultState = true; + } + catch + { + myTrans?.Rollback(); + resultState = false; + } + finally + { + _connection.Close(); + } + + return resultState; + } + + public DataSet ReturnDataSet(string strSql) + { + var dataSet = new DataSet(); + try + { + _connection.Open(); + var oleDbDa = new OleDbDataAdapter(strSql, _connection); + oleDbDa.Fill(dataSet, "objDataSet"); + } + finally + { + _connection.Close(); + } + return dataSet; + } + + public string[] GetTableNames() + { + try + { + _connection.Open(); + var shemaTable = _connection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" }); + var n = shemaTable.Rows.Count; + var strTable = new string[n]; + var m = shemaTable.Columns.IndexOf("TABLE_NAME"); + for (var i = 0; i < n; i++) + { + var m_DataRow = shemaTable.Rows[i]; + strTable[i] = m_DataRow.ItemArray.GetValue(m).ToString(); + } + return strTable; + } + finally + { + _connection.Close(); + } + } + } + +} diff --git a/net452/SiteServer.CMS/Core/Office/AccessObject.cs b/net452/SiteServer.CMS/Core/Office/AccessObject.cs new file mode 100644 index 000000000..0caf822a3 --- /dev/null +++ b/net452/SiteServer.CMS/Core/Office/AccessObject.cs @@ -0,0 +1,96 @@ +using SiteServer.Utils; +using System; +using System.Collections.Generic; +using System.Data; +using System.Collections.Specialized; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Core.Office +{ + public static class AccessObject + { + public static bool CreateAccessFileForContents(string filePath, SiteInfo siteInfo, ChannelInfo nodeInfo, List contentIdList, List displayAttributes, bool isPeriods, string dateFrom, string dateTo, ETriState checkedState) + { + DirectoryUtils.CreateDirectoryIfNotExists(DirectoryUtils.GetDirectoryPath(filePath)); + FileUtils.DeleteFileIfExists(filePath); + + var sourceFilePath = SiteServerAssets.GetPath(SiteServerAssets.Default.AccessMdb); + FileUtils.CopyFile(sourceFilePath, filePath); + + var styleInfoList = TableStyleManager.GetContentStyleInfoList(siteInfo, nodeInfo); + styleInfoList = ContentUtility.GetAllTableStyleInfoList(styleInfoList); + + var accessDao = new AccessDao(filePath); + + var createTableSqlString = accessDao.GetCreateTableSqlString(nodeInfo.ChannelName, styleInfoList, displayAttributes); + accessDao.ExecuteSqlString(createTableSqlString); + + var insertSqlList = accessDao.GetInsertSqlStringList(nodeInfo.ChannelName, siteInfo.Id, nodeInfo.Id, styleInfoList, displayAttributes, contentIdList, isPeriods, dateFrom, dateTo, checkedState, out var isExport); + + foreach (var insertSql in insertSqlList) + { + accessDao.ExecuteSqlString(insertSql); + } + + return isExport; + } + + public static List GetContentsByAccessFile(string filePath, SiteInfo siteInfo, ChannelInfo nodeInfo) + { + var contentInfoList = new List(); + + var accessDao = new AccessDao(filePath); + var tableNames = accessDao.GetTableNames(); + if (tableNames != null && tableNames.Length > 0) + { + foreach (var tableName in tableNames) + { + var sqlString = $"SELECT * FROM [{tableName}]"; + var dataset = accessDao.ReturnDataSet(sqlString); + + var oleDt = dataset.Tables[0]; + + if (oleDt.Rows.Count > 0) + { + var tableStyleInfoList = TableStyleManager.GetContentStyleInfoList(siteInfo, nodeInfo); + + var nameValueCollection = new NameValueCollection(); + + foreach (var styleInfo in tableStyleInfoList) + { + nameValueCollection[styleInfo.DisplayName] = styleInfo.AttributeName.ToLower(); + } + + //var attributeNames = new ArrayList(); + //for (var i = 0; i < oleDt.Columns.Count; i++) + //{ + // var columnName = oleDt.Columns[i].ColumnName; + // attributeNames.Add(!string.IsNullOrEmpty(nameValueCollection[columnName]) + // ? nameValueCollection[columnName] + // : columnName); + //} + + foreach (DataRow row in oleDt.Rows) + { + var contentInfo = new ContentInfo(TranslateUtils.ToDictionary(row)); + + if (!string.IsNullOrEmpty(contentInfo.Title)) + { + contentInfo.SiteId = siteInfo.Id; + contentInfo.ChannelId = nodeInfo.Id; + contentInfo.LastEditDate = DateTime.Now; + + contentInfoList.Add(contentInfo); + } + } + } + } + } + + return contentInfoList; + } + } +} diff --git a/net452/SiteServer.CMS/Core/Office/ExcelObject.cs b/net452/SiteServer.CMS/Core/Office/ExcelObject.cs new file mode 100644 index 000000000..ef246293e --- /dev/null +++ b/net452/SiteServer.CMS/Core/Office/ExcelObject.cs @@ -0,0 +1,196 @@ +using SiteServer.Utils; +using System; +using System.Collections.Specialized; +using System.Collections.Generic; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Core.Office +{ + public static class ExcelObject + { + public static void CreateExcelFileForContents(string filePath, SiteInfo siteInfo, + ChannelInfo channelInfo, IList contentIdList, List displayAttributes, bool isPeriods, string startDate, + string endDate, ETriState checkedState) + { + DirectoryUtils.CreateDirectoryIfNotExists(DirectoryUtils.GetDirectoryPath(filePath)); + FileUtils.DeleteFileIfExists(filePath); + + var head = new List(); + var rows = new List>(); + + var styleInfoList = ContentUtility.GetAllTableStyleInfoList(TableStyleManager.GetContentStyleInfoList(siteInfo, channelInfo)); + + foreach (var styleInfo in styleInfoList) + { + if (displayAttributes.Contains(styleInfo.AttributeName)) + { + head.Add(styleInfo.DisplayName); + } + } + + if (contentIdList == null || contentIdList.Count == 0) + { + contentIdList = channelInfo.ContentRepository.GetContentIdList(channelInfo.Id, isPeriods, + startDate, endDate, checkedState); + } + + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo != null) + { + var row = new List(); + + foreach (var styleInfo in styleInfoList) + { + if (displayAttributes.Contains(styleInfo.AttributeName)) + { + var value = contentInfo.Get(styleInfo.AttributeName); + row.Add(StringUtils.StripTags(value)); + } + } + + rows.Add(row); + } + } + + CsvUtils.Export(filePath, head, rows); + } + + public static void CreateExcelFileForContents(string filePath, SiteInfo siteInfo, + ChannelInfo channelInfo, List contentInfoList, List columnNames) + { + DirectoryUtils.CreateDirectoryIfNotExists(DirectoryUtils.GetDirectoryPath(filePath)); + FileUtils.DeleteFileIfExists(filePath); + + var head = new List(); + var rows = new List>(); + + var columns = ContentManager.GetContentColumns(siteInfo, channelInfo, true); + + foreach (var column in columns) + { + if (StringUtils.ContainsIgnoreCase(columnNames, column.AttributeName)) + { + head.Add(column.DisplayName); + } + } + + foreach (var contentInfo in contentInfoList) + { + var row = new List(); + + foreach (var column in columns) + { + if (StringUtils.ContainsIgnoreCase(columnNames, column.AttributeName)) + { + var value = contentInfo.Get(column.AttributeName); + row.Add(StringUtils.StripTags(value)); + } + } + + rows.Add(row); + } + + CsvUtils.Export(filePath, head, rows); + } + + public static void CreateExcelFileForUsers(string filePath, ETriState checkedState) + { + DirectoryUtils.CreateDirectoryIfNotExists(DirectoryUtils.GetDirectoryPath(filePath)); + FileUtils.DeleteFileIfExists(filePath); + + var head = new List + { + "用户名", + "姓名", + "邮箱", + "手机", + "注册时间", + "最后一次活动时间" + }; + var rows = new List>(); + + var userIdList = DataProvider.User.GetIdList(checkedState != ETriState.False); + if (checkedState == ETriState.All) + { + userIdList.AddRange(DataProvider.User.GetIdList(false)); + } + + foreach (var userId in userIdList) + { + var userInfo = UserManager.GetUserInfoByUserId(userId); + + rows.Add(new List + { + userInfo.UserName, + userInfo.DisplayName, + userInfo.Email, + userInfo.Mobile, + DateUtils.GetDateAndTimeString(userInfo.CreateDate), + DateUtils.GetDateAndTimeString(userInfo.LastActivityDate) + }); + } + + CsvUtils.Export(filePath, head, rows); + } + + public static List GetContentsByCsvFile(string filePath, SiteInfo siteInfo, + ChannelInfo nodeInfo) + { + var contentInfoList = new List(); + + CsvUtils.Import(filePath, out var head, out var rows); + + if (rows.Count <= 0) return contentInfoList; + + var styleInfoList = ContentUtility.GetAllTableStyleInfoList(TableStyleManager.GetContentStyleInfoList(siteInfo, nodeInfo)); + var nameValueCollection = new NameValueCollection(); + foreach (var styleInfo in styleInfoList) + { + nameValueCollection[styleInfo.DisplayName] = styleInfo.AttributeName.ToLower(); + } + + var attributeNames = new List(); + foreach (var columnName in head) + { + attributeNames.Add(!string.IsNullOrEmpty(nameValueCollection[columnName]) + ? nameValueCollection[columnName] + : columnName); + } + + foreach (var row in rows) + { + if (row.Count != attributeNames.Count) continue; + + var dict = new Dictionary(); + + for (var i = 0; i < attributeNames.Count; i++) + { + var attributeName = attributeNames[i]; + if (!string.IsNullOrEmpty(attributeName)) + { + dict[attributeName] = row[i]; + } + } + + var contentInfo = new ContentInfo(dict); + + if (!string.IsNullOrEmpty(contentInfo.Title)) + { + contentInfo.SiteId = siteInfo.Id; + contentInfo.ChannelId = nodeInfo.Id; + contentInfo.LastEditDate = DateTime.Now; + + contentInfoList.Add(contentInfo); + } + } + + return contentInfoList; + } + } +} diff --git a/net452/SiteServer.CMS/Core/Office/TxtObject.cs b/net452/SiteServer.CMS/Core/Office/TxtObject.cs new file mode 100644 index 000000000..4d6f940ac --- /dev/null +++ b/net452/SiteServer.CMS/Core/Office/TxtObject.cs @@ -0,0 +1,53 @@ +using SiteServer.Utils; +using System; +using System.Collections.Generic; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Core.Office +{ + public static class TxtObject + { + public static List GetContentListByTxtFile(string directoryPath, SiteInfo siteInfo, ChannelInfo nodeInfo) + { + var contentInfoList = new List(); + + var filePaths = DirectoryUtils.GetFilePaths(directoryPath); + foreach (var filePath in filePaths) + { + if (!EFileSystemTypeUtils.Equals(EFileSystemType.Txt, PathUtils.GetExtension(filePath))) continue; + + try + { + var content = FileUtils.ReadText(filePath, ECharset.gb2312); + if (!string.IsNullOrEmpty(content)) + { + content = content.Trim(); + var title = StringUtils.GetFirstOfStringCollection(content, '\r'); + if (!string.IsNullOrEmpty(title)) + { + var dict = new Dictionary + { + {ContentAttribute.Title, title.Trim()}, + {ContentAttribute.SiteId, siteInfo.Id}, + {ContentAttribute.ChannelId, nodeInfo.Id}, + {ContentAttribute.LastEditDate, DateTime.Now} + }; + var contentInfo = new ContentInfo(dict); + contentInfo.Set(ContentAttribute.Content, StringUtils.ReplaceNewlineToBr(content.Replace(title, string.Empty).Trim())); + + contentInfoList.Add(contentInfo); + } + } + } + catch + { + // ignored + } + } + + return contentInfoList; + } + } +} diff --git a/SiteServer.CMS/Core/Office/WordUtils.cs b/net452/SiteServer.CMS/Core/Office/WordUtils.cs similarity index 89% rename from SiteServer.CMS/Core/Office/WordUtils.cs rename to net452/SiteServer.CMS/Core/Office/WordUtils.cs index 9c68514f1..856b7da63 100644 --- a/SiteServer.CMS/Core/Office/WordUtils.cs +++ b/net452/SiteServer.CMS/Core/Office/WordUtils.cs @@ -2,17 +2,13 @@ using SiteServer.Utils; using Word.Plugin; using System.Collections.Specialized; -using SiteServer.CMS.Model; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Attributes; namespace SiteServer.CMS.Core.Office { - public class WordUtils + public static class WordUtils { - public static string GetWordFilePath(string fileName) - { - return PathUtils.GetTemporaryFilesPath(fileName); - } - public static string Parse(int siteId, string filePath, bool isClearFormat, bool isFirstLineIndent, bool isClearFontSize, bool isClearFontFamily, bool isClearImages) { if (string.IsNullOrEmpty(filePath)) return string.Empty; @@ -94,10 +90,10 @@ public static string Parse(int siteId, string filePath, bool isClearFormat, bool } } - public static NameValueCollection GetWordNameValueCollection(int siteId, bool isFirstLineTitle, bool isFirstLineRemove, bool isClearFormat, bool isFirstLineIndent, bool isClearFontSize, bool isClearFontFamily, bool isClearImages, int contentLevel, string fileName) + public static NameValueCollection GetWordNameValueCollection(int siteId, bool isFirstLineTitle, bool isFirstLineRemove, bool isClearFormat, bool isFirstLineIndent, bool isClearFontSize, bool isClearFontFamily, bool isClearImages, string fileName) { var formCollection = new NameValueCollection(); - var wordContent = Parse(siteId, GetWordFilePath(fileName), isClearFormat, isFirstLineIndent, isClearFontSize, isClearFontFamily, isClearImages); + var wordContent = Parse(siteId, PathUtils.GetTemporaryFilesPath(fileName), isClearFormat, isFirstLineIndent, isClearFontSize, isClearFontFamily, isClearImages); if (!string.IsNullOrEmpty(wordContent)) { var title = string.Empty; @@ -120,15 +116,15 @@ public static NameValueCollection GetWordNameValueCollection(int siteId, bool is { title = PathUtils.GetFileNameWithoutExtension(fileName); } - if (!string.IsNullOrEmpty(title) && title.Length > 255) + if (!string.IsNullOrEmpty(title)) { - title = title.Substring(0, 255); + title = StringUtils.MaxLengthText(title, 200, string.Empty); } formCollection[ContentAttribute.Title] = title; wordContent = StringUtils.ReplaceFirst("

    ", wordContent, string.Empty); - formCollection[BackgroundContentAttribute.Content] = wordContent; + formCollection[ContentAttribute.Content] = wordContent; } return formCollection; } diff --git a/SiteServer.CMS/Core/OnlineTemplateManager.cs b/net452/SiteServer.CMS/Core/OnlineTemplateManager.cs similarity index 96% rename from SiteServer.CMS/Core/OnlineTemplateManager.cs rename to net452/SiteServer.CMS/Core/OnlineTemplateManager.cs index f3d86a74d..1d64515e8 100644 --- a/SiteServer.CMS/Core/OnlineTemplateManager.cs +++ b/net452/SiteServer.CMS/Core/OnlineTemplateManager.cs @@ -1,11 +1,12 @@ using System.Collections.Generic; using System.Xml; +using SiteServer.CMS.Fx; using SiteServer.Utils; using SiteServer.Utils.Enumerations; namespace SiteServer.CMS.Core { - public class OnlineTemplateManager + public static class OnlineTemplateManager { private const string UrlTemplatesXml = "http://templates.siteserver.cn/templates.xml"; @@ -89,7 +90,7 @@ public static string GetTemplateUrl(string name) public static string GetDownloadUrl(string name) { - return $"http://cloud.siteserver.cn/api/downloads/template/{name}"; + return $"https://api.siteserver.cn/downloads/template/{name}"; } } } diff --git a/net452/SiteServer.CMS/Core/PageUtility.cs b/net452/SiteServer.CMS/Core/PageUtility.cs new file mode 100644 index 000000000..b6b1613a8 --- /dev/null +++ b/net452/SiteServer.CMS/Core/PageUtility.cs @@ -0,0 +1,521 @@ +using System; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Caches.Stl; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Core.RestRoutes.Preview; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Utils; + +namespace SiteServer.CMS.Core +{ + public static class PageUtility + { + public static string GetSiteUrl(SiteInfo siteInfo, bool isLocal) + { + return GetSiteUrl(siteInfo, string.Empty, isLocal); + } + + public static string GetSiteUrl(SiteInfo siteInfo, string requestPath, bool isLocal) + { + var url = isLocal + ? GetLocalSiteUrl(siteInfo, requestPath) + : GetRemoteSiteUrl(siteInfo, requestPath); + + return RemoveDefaultFileName(siteInfo, url); + } + + public static string GetSiteUrlByPhysicalPath(SiteInfo siteInfo, string physicalPath, bool isLocal) + { + if (siteInfo == null) + { + var siteId = PathUtility.GetCurrentSiteId(); + siteInfo = SiteManager.GetSiteInfo(siteId); + } + if (string.IsNullOrEmpty(physicalPath)) return siteInfo.WebUrl; + + var sitePath = PathUtility.GetSitePath(siteInfo); + var requestPath = StringUtils.StartsWithIgnoreCase(physicalPath, sitePath) + ? StringUtils.ReplaceStartsWithIgnoreCase(physicalPath, sitePath, string.Empty) + : string.Empty; + + return GetSiteUrl(siteInfo, requestPath, isLocal); + } + + private static string GetRemoteSiteUrl(SiteInfo siteInfo, string requestPath) + { + var url = siteInfo.WebUrl; + + if (string.IsNullOrEmpty(url)) + { + url = "/"; + } + else + { + if (url != "/" && url.EndsWith("/")) + { + url = url.Substring(0, url.Length - 1); + } + } + + if (string.IsNullOrEmpty(requestPath)) return url; + + requestPath = requestPath.Replace(PathUtils.SeparatorChar, PageUtils.SeparatorChar); + requestPath = PathUtils.RemovePathInvalidChar(requestPath); + if (requestPath.StartsWith("/")) + { + requestPath = requestPath.Substring(1); + } + + url = PageUtils.Combine(url, requestPath); + + if (!siteInfo.IsSeparatedAssets) return url; + + var assetsUrl = PageUtils.Combine(siteInfo.WebUrl, + siteInfo.AssetsDir); + if (StringUtils.StartsWithIgnoreCase(url, assetsUrl)) + { + url = StringUtils.ReplaceStartsWithIgnoreCase(url, assetsUrl, siteInfo.AssetsUrl); + } + + return url; + } + + private static string GetLocalSiteUrl(SiteInfo siteInfo, string requestPath) + { + var url = FxUtils.ParseNavigationUrl($"~/{siteInfo.SiteDir}"); + + if (string.IsNullOrEmpty(url)) + { + url = "/"; + } + else + { + if (url != "/" && url.EndsWith("/")) + { + url = url.Substring(0, url.Length - 1); + } + } + + if (string.IsNullOrEmpty(requestPath)) return url; + + requestPath = requestPath.Replace(PathUtils.SeparatorChar, PageUtils.SeparatorChar); + requestPath = PathUtils.RemovePathInvalidChar(requestPath); + if (requestPath.StartsWith("/")) + { + requestPath = requestPath.Substring(1); + } + + url = PageUtils.Combine(url, requestPath); + + return url; + } + + // 得到发布系统首页地址 + public static string GetIndexPageUrl(SiteInfo siteInfo, bool isLocal) + { + var indexTemplateId = TemplateManager.GetIndexTempalteId(siteInfo.Id); + var createdFileFullName = TemplateManager.GetCreatedFileFullName(siteInfo.Id, indexTemplateId); + + var url = isLocal + ? ApiRoutePreview.GetSiteUrl(siteInfo.Id) + : ParseNavigationUrl(siteInfo, createdFileFullName, false); + + return RemoveDefaultFileName(siteInfo, url); + } + + public static string GetSpecialUrl(SiteInfo siteInfo, int specialId, bool isLocal) + { + var specialUrl = SpecialManager.GetSpecialUrl(siteInfo, specialId); + + var url = isLocal + ? ApiRoutePreview.GetSpecialUrl(siteInfo.Id, specialId) + : ParseNavigationUrl(siteInfo, specialUrl, false); + + return RemoveDefaultFileName(siteInfo, url); + } + + public static string GetFileUrl(SiteInfo siteInfo, int fileTemplateId, bool isLocal) + { + var createdFileFullName = TemplateManager.GetCreatedFileFullName(siteInfo.Id, fileTemplateId); + + var url = isLocal + ? ApiRoutePreview.GetFileUrl(siteInfo.Id, fileTemplateId) + : ParseNavigationUrl(siteInfo, createdFileFullName, false); + + return RemoveDefaultFileName(siteInfo, url); + } + + public static string GetContentUrl(SiteInfo siteInfo, ContentInfo contentInfo, bool isLocal) + { + return GetContentUrlById(siteInfo, contentInfo, isLocal); + } + + public static string GetContentUrl(SiteInfo siteInfo, ChannelInfo channelInfo, int contentId, bool isLocal) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + return GetContentUrlById(siteInfo, contentInfo, isLocal); + } + + /// + /// 对GetContentUrlByID的优化 + /// 通过传入参数contentInfoCurrent,避免对ContentInfo查询太多 + /// + private static string GetContentUrlById(SiteInfo siteInfo, ContentInfo contentInfoCurrent, bool isLocal) + { + if (contentInfoCurrent == null) return PageUtils.UnClickedUrl; + + if (isLocal) + { + return ApiRoutePreview.GetContentUrl(siteInfo.Id, contentInfoCurrent.ChannelId, + contentInfoCurrent.Id); + } + + var sourceId = contentInfoCurrent.SourceId; + var referenceId = contentInfoCurrent.ReferenceId; + var linkUrl = contentInfoCurrent.Get(ContentAttribute.LinkUrl); + var channelId = contentInfoCurrent.ChannelId; + if (referenceId > 0 && contentInfoCurrent.Get(ContentAttribute.TranslateContentType) != ETranslateContentType.ReferenceContent.ToString()) + { + if (sourceId > 0 && (ChannelManager.IsExists(siteInfo.Id, sourceId) || ChannelManager.IsExists(sourceId))) + { + var targetChannelId = sourceId; + var targetSiteId = StlChannelCache.GetSiteId(targetChannelId); + var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); + var targetChannelInfo = ChannelManager.GetChannelInfo(targetSiteId, targetChannelId); + + var contentInfo = ContentManager.GetContentInfo(targetSiteInfo, targetChannelInfo, referenceId); + if (contentInfo == null || contentInfo.ChannelId <= 0) + { + return PageUtils.UnClickedUrl; + } + if (contentInfo.SiteId == targetSiteInfo.Id) + { + return GetContentUrlById(targetSiteInfo, contentInfo, false); + } + var siteInfoTmp = SiteManager.GetSiteInfo(contentInfo.SiteId); + return GetContentUrlById(siteInfoTmp, contentInfo, false); + } + else + { + var tableName = ChannelManager.GetTableName(siteInfo, channelId); + channelId = StlContentCache.GetChannelId(tableName, referenceId); + var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + linkUrl = StlContentCache.GetValue(channelInfo, referenceId, ContentAttribute.LinkUrl); + if (ChannelManager.IsExists(siteInfo.Id, channelId)) + { + return GetContentUrlById(siteInfo, channelId, referenceId, 0, 0, linkUrl, false); + } + var targetSiteId = StlChannelCache.GetSiteId(channelId); + var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); + return GetContentUrlById(targetSiteInfo, channelId, referenceId, 0, 0, linkUrl, false); + } + } + + if (!string.IsNullOrEmpty(linkUrl)) + { + return ParseNavigationUrl(siteInfo, linkUrl, false); + } + var contentUrl = PathUtility.ContentFilePathRules.Parse(siteInfo, channelId, contentInfoCurrent); + return GetSiteUrl(siteInfo, contentUrl, false); + } + + private static string GetContentUrlById(SiteInfo siteInfo, int channelId, int contentId, int sourceId, int referenceId, string linkUrl, bool isLocal) + { + if (isLocal) + { + return ApiRoutePreview.GetContentUrl(siteInfo.Id, channelId, contentId); + } + + var contentInfoCurrent = ContentManager.GetContentInfo(siteInfo, channelId, contentId); + + if (referenceId > 0 && contentInfoCurrent.Get(ContentAttribute.TranslateContentType) != ETranslateContentType.ReferenceContent.ToString()) + { + if (sourceId > 0 && (ChannelManager.IsExists(siteInfo.Id, sourceId) || ChannelManager.IsExists(sourceId))) + { + var targetChannelId = sourceId; + var targetSiteId = StlChannelCache.GetSiteId(targetChannelId); + var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); + var targetChannelInfo = ChannelManager.GetChannelInfo(targetSiteId, targetChannelId); + + var contentInfo = ContentManager.GetContentInfo(targetSiteInfo, targetChannelInfo, referenceId); + if (contentInfo == null || contentInfo.ChannelId <= 0) + { + return PageUtils.UnClickedUrl; + } + if (contentInfo.SiteId == targetSiteInfo.Id) + { + return GetContentUrlById(targetSiteInfo, contentInfo.ChannelId, contentInfo.Id, contentInfo.SourceId, contentInfo.ReferenceId, contentInfo.Get(ContentAttribute.LinkUrl), false); + } + var siteInfoTmp = SiteManager.GetSiteInfo(contentInfo.SiteId); + return GetContentUrlById(siteInfoTmp, contentInfo.ChannelId, contentInfo.Id, contentInfo.SourceId, contentInfo.ReferenceId, contentInfo.Get(ContentAttribute.LinkUrl), false); + } + else + { + var tableName = ChannelManager.GetTableName(siteInfo, channelId); + channelId = StlContentCache.GetChannelId(tableName, referenceId); + var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + linkUrl = StlContentCache.GetValue(channelInfo, referenceId, ContentAttribute.LinkUrl); + return GetContentUrlById(siteInfo, channelId, referenceId, 0, 0, linkUrl, false); + } + } + if (!string.IsNullOrEmpty(linkUrl)) + { + return ParseNavigationUrl(siteInfo, linkUrl, false); + } + var contentUrl = PathUtility.ContentFilePathRules.Parse(siteInfo, channelId, contentId); + return GetSiteUrl(siteInfo, contentUrl, false); + } + + private static string GetChannelUrlNotComputed(SiteInfo siteInfo, int channelId, bool isLocal) + { + if (channelId == siteInfo.Id) + { + return GetIndexPageUrl(siteInfo, isLocal); + } + var linkUrl = string.Empty; + var nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + if (nodeInfo != null) + { + linkUrl = nodeInfo.LinkUrl; + } + + if (string.IsNullOrEmpty(linkUrl)) + { + if (nodeInfo != null) + { + var filePath = nodeInfo.FilePath; + + if (string.IsNullOrEmpty(filePath)) + { + var channelUrl = PathUtility.ChannelFilePathRules.Parse(siteInfo, channelId); + return GetSiteUrl(siteInfo, channelUrl, isLocal); + } + return ParseNavigationUrl(siteInfo, PathUtility.AddVirtualToPath(filePath), isLocal); + } + } + + return ParseNavigationUrl(siteInfo, linkUrl, isLocal); + } + + //得到栏目经过计算后的连接地址 + public static string GetChannelUrl(SiteInfo siteInfo, ChannelInfo channelInfo, bool isLocal) + { + if (channelInfo == null) return string.Empty; + + if (isLocal) + { + return ApiRoutePreview.GetChannelUrl(siteInfo.Id, channelInfo.Id); + } + + var url = string.Empty; + + if (channelInfo.ParentId == 0) + { + url = GetChannelUrlNotComputed(siteInfo, channelInfo.Id, false); + } + else + { + var linkType = ELinkTypeUtils.GetEnumType(channelInfo.LinkType); + if (linkType == ELinkType.None) + { + url = GetChannelUrlNotComputed(siteInfo, channelInfo.Id, false); + } + else if (linkType == ELinkType.NoLink) + { + url = PageUtils.UnClickedUrl; + } + else + { + if (linkType == ELinkType.NoLinkIfContentNotExists) + { + var count = ContentManager.GetCount(siteInfo, channelInfo, true); + url = count == 0 ? PageUtils.UnClickedUrl : GetChannelUrlNotComputed(siteInfo, channelInfo.Id, false); + } + else if (linkType == ELinkType.LinkToOnlyOneContent) + { + var count = ContentManager.GetCount(siteInfo, channelInfo, true); + if (count == 1) + { + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + var contentId = StlContentCache.GetContentId(tableName, channelInfo.Id, ETaxisTypeUtils.GetContentOrderByString(ETaxisTypeUtils.GetEnumType(channelInfo.DefaultTaxisType))); + url = GetContentUrl(siteInfo, channelInfo, contentId, false); + } + else + { + url = GetChannelUrlNotComputed(siteInfo, channelInfo.Id, false); + } + } + else if (linkType == ELinkType.NoLinkIfContentNotExistsAndLinkToOnlyOneContent) + { + var count = ContentManager.GetCount(siteInfo, channelInfo, true); + if (count == 0) + { + url = PageUtils.UnClickedUrl; + } + else if (count == 1) + { + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + var contentId = StlContentCache.GetContentId(tableName, channelInfo.Id, ETaxisTypeUtils.GetContentOrderByString(ETaxisTypeUtils.GetEnumType(channelInfo.DefaultTaxisType))); + url = GetContentUrl(siteInfo, channelInfo, contentId, false); + } + else + { + url = GetChannelUrlNotComputed(siteInfo, channelInfo.Id, false); + } + } + else if (linkType == ELinkType.LinkToFirstContent) + { + var count = ContentManager.GetCount(siteInfo, channelInfo, true); + if (count >= 1) + { + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + var contentId = StlContentCache.GetContentId(tableName, channelInfo.Id, ETaxisTypeUtils.GetContentOrderByString(ETaxisTypeUtils.GetEnumType(channelInfo.DefaultTaxisType))); + //var contentId = StlCacheManager.FirstContentId.GetValueById(siteInfo, nodeInfo); + url = GetContentUrl(siteInfo, channelInfo, contentId, false); + } + else + { + url = GetChannelUrlNotComputed(siteInfo, channelInfo.Id, false); + } + } + else if (linkType == ELinkType.NoLinkIfContentNotExistsAndLinkToFirstContent) + { + var count = ContentManager.GetCount(siteInfo, channelInfo, true); + if (count >= 1) + { + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + var contentId = StlContentCache.GetContentId(tableName, channelInfo.Id, ETaxisTypeUtils.GetContentOrderByString(ETaxisTypeUtils.GetEnumType(channelInfo.DefaultTaxisType))); + //var contentId = StlCacheManager.FirstContentId.GetValueById(siteInfo, nodeInfo); + url = GetContentUrl(siteInfo, channelInfo, contentId, false); + } + else + { + url = PageUtils.UnClickedUrl; + } + } + else if (linkType == ELinkType.NoLinkIfChannelNotExists) + { + url = channelInfo.ChildrenCount == 0 ? PageUtils.UnClickedUrl : GetChannelUrlNotComputed(siteInfo, channelInfo.Id, false); + } + else if (linkType == ELinkType.LinkToLastAddChannel) + { + var lastAddChannelInfo = StlChannelCache.GetChannelInfoByLastAddDate(channelInfo.Id); + url = lastAddChannelInfo != null ? GetChannelUrl(siteInfo, lastAddChannelInfo, false) : GetChannelUrlNotComputed(siteInfo, channelInfo.Id, false); + } + else if (linkType == ELinkType.LinkToFirstChannel) + { + var firstChannelInfo = StlChannelCache.GetChannelInfoByTaxis(channelInfo.Id); + url = firstChannelInfo != null ? GetChannelUrl(siteInfo, firstChannelInfo, false) : GetChannelUrlNotComputed(siteInfo, channelInfo.Id, false); + } + else if (linkType == ELinkType.NoLinkIfChannelNotExistsAndLinkToLastAddChannel) + { + var lastAddChannelInfo = StlChannelCache.GetChannelInfoByLastAddDate(channelInfo.Id); + url = lastAddChannelInfo != null ? GetChannelUrl(siteInfo, lastAddChannelInfo, false) : PageUtils.UnClickedUrl; + } + else if (linkType == ELinkType.NoLinkIfChannelNotExistsAndLinkToFirstChannel) + { + var firstChannelInfo = StlChannelCache.GetChannelInfoByTaxis(channelInfo.Id); + url = firstChannelInfo != null ? GetChannelUrl(siteInfo, firstChannelInfo, false) : PageUtils.UnClickedUrl; + } + } + } + + return RemoveDefaultFileName(siteInfo, url); + } + + private static string RemoveDefaultFileName(SiteInfo siteInfo, string url) + { + if (!siteInfo.IsCreateUseDefaultFileName || string.IsNullOrEmpty(url)) return url; + + return url.EndsWith("/" + siteInfo.CreateDefaultFileName) + ? url.Substring(0, url.Length - siteInfo.CreateDefaultFileName.Length) + : url; + } + + public static string GetInputChannelUrl(SiteInfo siteInfo, ChannelInfo nodeInfo, bool isLocal) + { + var channelUrl = GetChannelUrl(siteInfo, nodeInfo, isLocal); + if (string.IsNullOrEmpty(channelUrl)) return channelUrl; + + channelUrl = StringUtils.ReplaceStartsWith(channelUrl, siteInfo.WebUrl, string.Empty); + channelUrl = channelUrl.Trim('/'); + if (channelUrl != PageUtils.UnClickedUrl) + { + channelUrl = "/" + channelUrl; + } + + return channelUrl; + } + + public static string AddVirtualToUrl(string url) + { + var resolvedUrl = url; + if (string.IsNullOrEmpty(url) || PageUtils.IsProtocolUrl(url)) return resolvedUrl; + + if (!url.StartsWith("@") && !url.StartsWith("~")) + { + resolvedUrl = PageUtils.Combine("@/", url); + } + return resolvedUrl; + } + + //根据发布系统属性判断是否为相对路径并返回解析后路径 + public static string ParseNavigationUrl(SiteInfo siteInfo, string url, bool isLocal) + { + if (string.IsNullOrEmpty(url)) return string.Empty; + + if (siteInfo != null) + { + if (!string.IsNullOrEmpty(url) && url.StartsWith("@")) + { + return GetSiteUrl(siteInfo, url.Substring(1), isLocal); + } + return FxUtils.ParseNavigationUrl(url); + } + return FxUtils.ParseNavigationUrl(url); + } + + public static string GetVirtualUrl(SiteInfo siteInfo, string url) + { + var relatedSiteUrl = FxUtils.ParseNavigationUrl($"~/{siteInfo.SiteDir}"); + var virtualUrl = StringUtils.ReplaceStartsWith(url, relatedSiteUrl, "@/"); + return StringUtils.ReplaceStartsWith(virtualUrl, "@//", "@/"); + } + + public static bool IsVirtualUrl(string url) + { + if (string.IsNullOrEmpty(url)) return false; + + return url.StartsWith("~") || url.StartsWith("@"); + } + + public static string GetSiteFilesUrl(string apiUrl, string relatedUrl) + { + if (string.IsNullOrEmpty(apiUrl)) + { + apiUrl = "/api"; + } + apiUrl = apiUrl.Trim().ToLower(); + if (apiUrl == "/api") + { + apiUrl = "/"; + } + else if (apiUrl.EndsWith("/api")) + { + apiUrl = apiUrl.Substring(0, apiUrl.LastIndexOf("/api", StringComparison.Ordinal)); + } + else if (apiUrl.EndsWith("/api/")) + { + apiUrl = apiUrl.Substring(0, apiUrl.LastIndexOf("/api/", StringComparison.Ordinal)); + } + if (string.IsNullOrEmpty(apiUrl)) + { + apiUrl = "/"; + } + return PageUtils.Combine(apiUrl, DirectoryUtils.SiteFiles.DirectoryName, relatedUrl); + } + } +} \ No newline at end of file diff --git a/SiteServer.CMS/Core/PathUtility.cs b/net452/SiteServer.CMS/Core/PathUtility.cs similarity index 79% rename from SiteServer.CMS/Core/PathUtility.cs rename to net452/SiteServer.CMS/Core/PathUtility.cs index da6a4ad36..0cbb78537 100644 --- a/SiteServer.CMS/Core/PathUtility.cs +++ b/net452/SiteServer.CMS/Core/PathUtility.cs @@ -2,21 +2,20 @@ using System.Collections; using System.Collections.Specialized; using SiteServer.Utils; -using SiteServer.CMS.Model; using System.Text.RegularExpressions; -using SiteServer.CMS.Model.Enumerations; -using SiteServer.CMS.StlParser.Cache; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Caches.Stl; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.Plugin; using SiteServer.Utils.Enumerations; namespace SiteServer.CMS.Core { - public class PathUtility + public static class PathUtility { - private PathUtility() - { - } - public static string GetSitePath(SiteInfo siteInfo) { return PathUtils.Combine(WebConfigUtils.PhysicalApplicationPath, siteInfo.SiteDir); @@ -95,18 +94,18 @@ public static string GetUploadDirectoryPath(SiteInfo siteInfo, string fileExtens public static string GetUploadDirectoryPath(SiteInfo siteInfo, DateTime datetime, string fileExtension) { - var uploadDateFormatString = siteInfo.Additional.FileUploadDateFormatString; - var uploadDirectoryName = siteInfo.Additional.FileUploadDirectoryName; + var uploadDateFormatString = siteInfo.FileUploadDateFormatString; + var uploadDirectoryName = siteInfo.FileUploadDirectoryName; if (IsImageExtenstionAllowed(siteInfo, fileExtension)) { - uploadDateFormatString = siteInfo.Additional.ImageUploadDateFormatString; - uploadDirectoryName = siteInfo.Additional.ImageUploadDirectoryName; + uploadDateFormatString = siteInfo.ImageUploadDateFormatString; + uploadDirectoryName = siteInfo.ImageUploadDirectoryName; } else if (IsVideoExtenstionAllowed(siteInfo, fileExtension)) { - uploadDateFormatString = siteInfo.Additional.VideoUploadDateFormatString; - uploadDirectoryName = siteInfo.Additional.VideoUploadDirectoryName; + uploadDateFormatString = siteInfo.VideoUploadDateFormatString; + uploadDirectoryName = siteInfo.VideoUploadDirectoryName; } string directoryPath; @@ -140,27 +139,27 @@ public static string GetUploadDirectoryPath(SiteInfo siteInfo, DateTime datetime if (uploadType == EUploadType.Image) { - uploadDateFormatString = siteInfo.Additional.ImageUploadDateFormatString; - uploadDirectoryName = siteInfo.Additional.ImageUploadDirectoryName; + uploadDateFormatString = siteInfo.ImageUploadDateFormatString; + uploadDirectoryName = siteInfo.ImageUploadDirectoryName; } else if (uploadType == EUploadType.Video) { - uploadDateFormatString = siteInfo.Additional.VideoUploadDateFormatString; - uploadDirectoryName = siteInfo.Additional.VideoUploadDirectoryName; + uploadDateFormatString = siteInfo.VideoUploadDateFormatString; + uploadDirectoryName = siteInfo.VideoUploadDirectoryName; } else if (uploadType == EUploadType.File) { - uploadDateFormatString = siteInfo.Additional.FileUploadDateFormatString; - uploadDirectoryName = siteInfo.Additional.FileUploadDirectoryName; + uploadDateFormatString = siteInfo.FileUploadDateFormatString; + uploadDirectoryName = siteInfo.FileUploadDirectoryName; } else if (uploadType == EUploadType.Special) { - uploadDateFormatString = siteInfo.Additional.FileUploadDateFormatString; + uploadDateFormatString = siteInfo.FileUploadDateFormatString; uploadDirectoryName = "/Special"; } else if (uploadType == EUploadType.AdvImage) { - uploadDateFormatString = siteInfo.Additional.FileUploadDateFormatString; + uploadDateFormatString = siteInfo.FileUploadDateFormatString; uploadDirectoryName = "/AdvImage"; } @@ -187,14 +186,14 @@ public static string GetUploadFileName(SiteInfo siteInfo, string filePath) { var fileExtension = PathUtils.GetExtension(filePath); - var isUploadChangeFileName = siteInfo.Additional.IsFileUploadChangeFileName; + var isUploadChangeFileName = siteInfo.IsFileUploadChangeFileName; if (IsImageExtenstionAllowed(siteInfo, fileExtension)) { - isUploadChangeFileName = siteInfo.Additional.IsImageUploadChangeFileName; + isUploadChangeFileName = siteInfo.IsImageUploadChangeFileName; } else if (IsVideoExtenstionAllowed(siteInfo, fileExtension)) { - isUploadChangeFileName = siteInfo.Additional.IsVideoUploadChangeFileName; + isUploadChangeFileName = siteInfo.IsVideoUploadChangeFileName; } return GetUploadFileName(siteInfo, filePath, isUploadChangeFileName); @@ -202,58 +201,22 @@ public static string GetUploadFileName(SiteInfo siteInfo, string filePath) public static string GetUploadFileName(SiteInfo siteInfo, string filePath, bool isUploadChangeFileName) { - string retval; - - if (isUploadChangeFileName) - { - var strDateTime = StringUtils.GetShortGuid(false); - retval = $"{strDateTime}{PathUtils.GetExtension(filePath)}"; - } - else - { - retval = PathUtils.GetFileName(filePath); - } + var retVal = isUploadChangeFileName + ? $"{StringUtils.GetShortGuid(false)}{PathUtils.GetExtension(filePath)}" + : PathUtils.GetFileName(filePath); - retval = StringUtils.ReplaceIgnoreCase(retval, ";", string.Empty); - return retval; + retVal = StringUtils.ReplaceIgnoreCase(retVal, "as", string.Empty); + retVal = StringUtils.ReplaceIgnoreCase(retVal, ";", string.Empty); + return retVal; } public static string GetUploadSpecialName(SiteInfo siteInfo, string filePath, bool isUploadChangeFileName) { - string retval; - - if (isUploadChangeFileName) - { - string strDateTime = StringUtils.GetShortGuid(false); - retval = $"{strDateTime}{PathUtils.GetExtension(filePath)}"; - } - else - { - retval = PathUtils.GetFileName(filePath); - } - - retval = StringUtils.ReplaceIgnoreCase(retval, "as", string.Empty); - retval = StringUtils.ReplaceIgnoreCase(retval, ";", string.Empty); - return retval; - } - - public static string GetUploadAdvImageName(SiteInfo siteInfo, string filePath, bool isUploadChangeFileName) - { - string retval; + var retVal = isUploadChangeFileName ? $"{StringUtils.GetShortGuid(false)}{PathUtils.GetExtension(filePath)}" : PathUtils.GetFileName(filePath); - if (isUploadChangeFileName) - { - string strDateTime = StringUtils.GetShortGuid(false); - retval = $"{strDateTime}{PathUtils.GetExtension(filePath)}"; - } - else - { - retval = PathUtils.GetFileName(filePath); - } - - retval = StringUtils.ReplaceIgnoreCase(retval, "as", string.Empty); - retval = StringUtils.ReplaceIgnoreCase(retval, ";", string.Empty); - return retval; + retVal = StringUtils.ReplaceIgnoreCase(retVal, "as", string.Empty); + retVal = StringUtils.ReplaceIgnoreCase(retVal, ";", string.Empty); + return retVal; } public static SiteInfo GetSiteInfo(string path) @@ -268,7 +231,7 @@ public static SiteInfo GetSiteInfo(string path) SiteInfo headquarter = null; foreach (var siteInfo in siteInfoList) { - if (siteInfo.IsRoot) + if (siteInfo.Root) { headquarter = siteInfo; } @@ -298,7 +261,7 @@ public static string GetSiteDir(string path) var siteInfoList = SiteManager.GetSiteInfoList(); foreach (var siteInfo in siteInfoList) { - if (siteInfo?.IsRoot!= false) continue; + if (siteInfo?.Root!= false) continue; if (StringUtils.Contains(directoryDir, siteInfo.SiteDir.ToLower())) { @@ -311,7 +274,7 @@ public static string GetSiteDir(string path) public static string GetCurrentSiteDir() { - return GetSiteDir(PathUtils.GetCurrentPagePath()); + return GetSiteDir(FxUtils.GetCurrentPagePath()); } public static int GetCurrentSiteId() @@ -325,11 +288,11 @@ public static int GetCurrentSiteId() else { var siteDir = GetCurrentSiteDir(); - siteId = !string.IsNullOrEmpty(siteDir) ? Site.GetSiteIdBySiteDir(siteDir) : Site.GetSiteIdByIsRoot(); + siteId = !string.IsNullOrEmpty(siteDir) ? StlSiteCache.GetSiteIdBySiteDir(siteDir) : StlSiteCache.GetSiteIdByIsRoot(); if (siteId == 0) { - siteId = Site.GetSiteIdByIsRoot(); + siteId = StlSiteCache.GetSiteIdByIsRoot(); } } return siteId; @@ -360,13 +323,13 @@ public static string MapPath(SiteInfo siteInfo, string virtualPath) { virtualPath = "@" + virtualPath; } - if (!virtualPath.StartsWith("@")) return PathUtils.MapPath(resolvedPath); + if (!virtualPath.StartsWith("@")) return FxUtils.MapPath(resolvedPath); if (siteInfo != null) { - resolvedPath = siteInfo.IsRoot ? string.Concat("~", virtualPath.Substring(1)) : PageUtils.Combine(siteInfo.SiteDir, virtualPath.Substring(1)); + resolvedPath = siteInfo.Root ? string.Concat("~", virtualPath.Substring(1)) : PageUtils.Combine(siteInfo.SiteDir, virtualPath.Substring(1)); } - return PathUtils.MapPath(resolvedPath); + return FxUtils.MapPath(resolvedPath); } public static string MapPath(SiteInfo siteInfo, string virtualPath, bool isCopyToSite) @@ -382,13 +345,13 @@ public static string MapPath(SiteInfo siteInfo, string virtualPath, bool isCopyT { virtualPath = "@" + virtualPath; } - if (!virtualPath.StartsWith("@")) return PathUtils.MapPath(resolvedPath); + if (!virtualPath.StartsWith("@")) return FxUtils.MapPath(resolvedPath); if (siteInfo != null) { - resolvedPath = siteInfo.IsRoot ? string.Concat("~", virtualPath.Substring(1)) : PageUtils.Combine(siteInfo.SiteDir, virtualPath.Substring(1)); + resolvedPath = siteInfo.Root ? string.Concat("~", virtualPath.Substring(1)) : PageUtils.Combine(siteInfo.SiteDir, virtualPath.Substring(1)); } - return PathUtils.MapPath(resolvedPath); + return FxUtils.MapPath(resolvedPath); } public static string MapPath(string directoryPath, string virtualPath) @@ -413,7 +376,7 @@ public static string MapPath(string directoryPath, string virtualPath) return PageUtils.Combine(directoryPath, virtualPath.Substring(1)); } } - return PathUtils.MapPath(resolvedPath); + return FxUtils.MapPath(resolvedPath); } //将编辑器中图片上传至本机 @@ -423,8 +386,8 @@ public static string SaveImage(SiteInfo siteInfo, string content) foreach (var originalImageSrc in originalImageSrcs) { if (!PageUtils.IsProtocolUrl(originalImageSrc) || - StringUtils.StartsWithIgnoreCase(originalImageSrc, PageUtils.ApplicationPath) || - StringUtils.StartsWithIgnoreCase(originalImageSrc, siteInfo.Additional.WebUrl)) + StringUtils.StartsWithIgnoreCase(originalImageSrc, FxUtils.ApplicationPath) || + StringUtils.StartsWithIgnoreCase(originalImageSrc, siteInfo.WebUrl)) continue; var fileExtName = PageUtils.GetExtensionFromUrl(originalImageSrc); if (!EFileSystemTypeUtils.IsImageOrFlashOrPlayer(fileExtName)) continue; @@ -551,12 +514,11 @@ public static IDictionary GetDictionary(SiteInfo siteInfo, int channelId) {LowerChannelIndex, "栏目索引(小写)"} }; - var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(siteInfo.Id, channelId); - - var styleInfoList = TableStyleManager.GetTableStyleInfoList(DataProvider.ChannelDao.TableName, relatedIdentities); + var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + var styleInfoList = TableStyleManager.GetChannelStyleInfoList(channelInfo); foreach (var styleInfo in styleInfoList) { - if (styleInfo.InputType == InputType.Text) + if (styleInfo.Type == InputType.Text) { dictionary.Add($@"{{@{StringUtils.LowerFirst(styleInfo.AttributeName)}}}", styleInfo.DisplayName); dictionary.Add($@"{{@lower{styleInfo.AttributeName}}}", styleInfo.DisplayName + "(小写)"); @@ -579,7 +541,7 @@ private static string ParseChannelPath(SiteInfo siteInfo, int channelId, string var filePath = channelFilePathRule.Trim(); const string regex = "(?{@[^}]+})"; var elements = RegexUtils.GetContents("element", regex, filePath); - ChannelInfo nodeInfo = null; + ChannelInfo channelInfo = null; foreach (var element in elements) { @@ -591,42 +553,42 @@ private static string ParseChannelPath(SiteInfo siteInfo, int channelId, string } else if (StringUtils.EqualsIgnoreCase(element, Year)) { - if (nodeInfo == null) nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - value = nodeInfo.AddDate.Year.ToString(); + if (channelInfo == null) channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + if (channelInfo.AddDate != null) value = channelInfo.AddDate.Value.Year.ToString(); } else if (StringUtils.EqualsIgnoreCase(element, Month)) { - if (nodeInfo == null) nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - value = nodeInfo.AddDate.Month.ToString(); + if (channelInfo == null) channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + if (channelInfo.AddDate != null) value = channelInfo.AddDate.Value.Month.ToString(); } else if (StringUtils.EqualsIgnoreCase(element, Day)) { - if (nodeInfo == null) nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - value = nodeInfo.AddDate.Day.ToString(); + if (channelInfo == null) channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + if (channelInfo.AddDate != null) value = channelInfo.AddDate.Value.Day.ToString(); } else if (StringUtils.EqualsIgnoreCase(element, Hour)) { - if (nodeInfo == null) nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - value = nodeInfo.AddDate.Hour.ToString(); + if (channelInfo == null) channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + if (channelInfo.AddDate != null) value = channelInfo.AddDate.Value.Hour.ToString(); } else if (StringUtils.EqualsIgnoreCase(element, Minute)) { - if (nodeInfo == null) nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - value = nodeInfo.AddDate.Minute.ToString(); + if (channelInfo == null) channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + if (channelInfo.AddDate != null) value = channelInfo.AddDate.Value.Minute.ToString(); } else if (StringUtils.EqualsIgnoreCase(element, Second)) { - if (nodeInfo == null) nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - value = nodeInfo.AddDate.Second.ToString(); + if (channelInfo == null) channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + if (channelInfo.AddDate != null) value = channelInfo.AddDate.Value.Second.ToString(); } else if (StringUtils.EqualsIgnoreCase(element, Sequence)) { - value = Node.GetSequence(siteInfo.Id, channelId).ToString(); + value = StlChannelCache.GetSequence(siteInfo.Id, channelId).ToString(); } else if (StringUtils.EqualsIgnoreCase(element, ParentRule)) { - if (nodeInfo == null) nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - var parentInfo = ChannelManager.GetChannelInfo(siteInfo.Id, nodeInfo.ParentId); + if (channelInfo == null) channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + var parentInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelInfo.ParentId); if (parentInfo != null) { var parentRule = GetChannelFilePathRule(siteInfo, parentInfo.Id); @@ -635,22 +597,22 @@ private static string ParseChannelPath(SiteInfo siteInfo, int channelId, string } else if (StringUtils.EqualsIgnoreCase(element, ChannelName)) { - if (nodeInfo == null) nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - value = nodeInfo.ChannelName; + if (channelInfo == null) channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + value = channelInfo.ChannelName; } else if (StringUtils.EqualsIgnoreCase(element, LowerChannelName)) { - if (nodeInfo == null) nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - value = nodeInfo.ChannelName.ToLower(); + if (channelInfo == null) channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + value = channelInfo.ChannelName.ToLower(); } else if (StringUtils.EqualsIgnoreCase(element, LowerChannelIndex)) { - if (nodeInfo == null) nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); - value = nodeInfo.IndexName.ToLower(); + if (channelInfo == null) channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + value = channelInfo.IndexName.ToLower(); } else { - if (nodeInfo == null) nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + if (channelInfo == null) channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); var attributeName = element.Replace("{@", string.Empty).Replace("}", string.Empty); var isLower = false; @@ -660,7 +622,7 @@ private static string ParseChannelPath(SiteInfo siteInfo, int channelId, string attributeName = attributeName.Substring(5); } - value = nodeInfo.Additional.GetString(attributeName); + value = channelInfo.Get(attributeName, string.Empty); if (isLower) { @@ -724,13 +686,11 @@ public static IDictionary GetDictionary(SiteInfo siteInfo, int channelId) {LowerChannelIndex, "栏目索引(小写)"} }; - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - var relatedIdentities = RelatedIdentities.GetChannelRelatedIdentities(siteInfo.Id, channelId); - - var styleInfoList = TableStyleManager.GetTableStyleInfoList(tableName, relatedIdentities); + var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + var styleInfoList = TableStyleManager.GetContentStyleInfoList(siteInfo, channelInfo); foreach (var styleInfo in styleInfoList) { - if (styleInfo.InputType == InputType.Text) + if (styleInfo.Type == InputType.Text) { dictionary.Add($@"{{@{StringUtils.LowerFirst(styleInfo.AttributeName)}}}", styleInfo.DisplayName); dictionary.Add($@"{{@lower{styleInfo.AttributeName}}}", styleInfo.DisplayName + "(小写)"); @@ -743,25 +703,24 @@ public static IDictionary GetDictionary(SiteInfo siteInfo, int channelId) public static string Parse(SiteInfo siteInfo, int channelId, int contentId) { var contentFilePathRule = GetContentFilePathRule(siteInfo, channelId); - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - var contentInfo = Content.GetContentInfo(tableName, contentId); + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelId, contentId); var filePath = ParseContentPath(siteInfo, channelId, contentInfo, contentFilePathRule); return filePath; } - public static string Parse(SiteInfo siteInfo, int channelId, IContentInfo contentInfo) + public static string Parse(SiteInfo siteInfo, int channelId, ContentInfo contentInfo) { var contentFilePathRule = GetContentFilePathRule(siteInfo, channelId); var filePath = ParseContentPath(siteInfo, channelId, contentInfo, contentFilePathRule); return filePath; } - private static string ParseContentPath(SiteInfo siteInfo, int channelId, IContentInfo contentInfo, string contentFilePathRule) + private static string ParseContentPath(SiteInfo siteInfo, int channelId, ContentInfo contentInfo, string contentFilePathRule) { var filePath = contentFilePathRule.Trim(); var regex = "(?{@[^}]+})"; var elements = RegexUtils.GetContents("element", regex, filePath); - var addDate = DateTime.MinValue; + var addDate = contentInfo.AddDate; var contentId = contentInfo.Id; foreach (var element in elements) { @@ -777,8 +736,8 @@ private static string ParseContentPath(SiteInfo siteInfo, int channelId, IConten } else if (StringUtils.EqualsIgnoreCase(element, Sequence)) { - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - value = Content.GetSequence(tableName, channelId, contentId).ToString(); + var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + value = StlContentCache.GetSequence(channelInfo, contentId).ToString(); } else if (StringUtils.EqualsIgnoreCase(element, ParentRule))//继承父级设置 20151113 sessionliang { @@ -822,39 +781,33 @@ private static string ParseContentPath(SiteInfo siteInfo, int channelId, IConten value = nodeInfo.IndexName.ToLower(); } } - else if (StringUtils.EqualsIgnoreCase(element, Year) || StringUtils.EqualsIgnoreCase(element, Month) || StringUtils.EqualsIgnoreCase(element, Day) || StringUtils.EqualsIgnoreCase(element, Hour) || StringUtils.EqualsIgnoreCase(element, Minute) || StringUtils.EqualsIgnoreCase(element, Second)) + else if (addDate.HasValue && (StringUtils.EqualsIgnoreCase(element, Year) || StringUtils.EqualsIgnoreCase(element, Month) || StringUtils.EqualsIgnoreCase(element, Day) || StringUtils.EqualsIgnoreCase(element, Hour) || StringUtils.EqualsIgnoreCase(element, Minute) || StringUtils.EqualsIgnoreCase(element, Second))) { - if (addDate == DateTime.MinValue) - { - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - addDate = Content.GetAddDate(tableName, contentId); - } - if (StringUtils.EqualsIgnoreCase(element, Year)) { - value = addDate.Year.ToString(); + value = addDate.Value.Year.ToString(); } else if (StringUtils.EqualsIgnoreCase(element, Month)) { - value = addDate.Month.ToString("D2"); + value = addDate.Value.Month.ToString("D2"); //value = addDate.ToString("MM"); } else if (StringUtils.EqualsIgnoreCase(element, Day)) { - value = addDate.Day.ToString("D2"); + value = addDate.Value.Day.ToString("D2"); //value = addDate.ToString("dd"); } else if (StringUtils.EqualsIgnoreCase(element, Hour)) { - value = addDate.Hour.ToString(); + value = addDate.Value.Hour.ToString(); } else if (StringUtils.EqualsIgnoreCase(element, Minute)) { - value = addDate.Minute.ToString(); + value = addDate.Value.Minute.ToString(); } else if (StringUtils.EqualsIgnoreCase(element, Second)) { - value = addDate.Second.ToString(); + value = addDate.Value.Second.ToString(); } } else @@ -868,7 +821,7 @@ private static string ParseContentPath(SiteInfo siteInfo, int channelId, IConten attributeName = attributeName.Substring(5); } - value = contentInfo.GetString(attributeName); + value = contentInfo.Get(attributeName); if (isLower) { value = value.ToLower(); @@ -916,7 +869,7 @@ public static string GetChannelFilePathRule(SiteInfo siteInfo, int channelId) var channelFilePathRule = GetChannelFilePathRule(siteInfo.Id, channelId); if (string.IsNullOrEmpty(channelFilePathRule)) { - channelFilePathRule = siteInfo.Additional.ChannelFilePathRule; + channelFilePathRule = siteInfo.ChannelFilePathRule; if (string.IsNullOrEmpty(channelFilePathRule)) { @@ -946,7 +899,7 @@ public static string GetContentFilePathRule(SiteInfo siteInfo, int channelId) var contentFilePathRule = GetContentFilePathRule(siteInfo.Id, channelId); if (string.IsNullOrEmpty(contentFilePathRule)) { - contentFilePathRule = siteInfo.Additional.ContentFilePathRule; + contentFilePathRule = siteInfo.ContentFilePathRule; if (string.IsNullOrEmpty(contentFilePathRule)) { @@ -977,7 +930,7 @@ public static string GetChannelPageFilePath(SiteInfo siteInfo, int channelId, in if (nodeInfo.ParentId == 0) { var templateInfo = TemplateManager.GetDefaultTemplateInfo(siteInfo.Id, TemplateType.IndexPageTemplate); - return GetIndexPageFilePath(siteInfo, templateInfo.CreatedFileFullName, siteInfo.IsRoot, currentPageIndex); + return GetIndexPageFilePath(siteInfo, templateInfo.CreatedFileFullName, siteInfo.Root, currentPageIndex); } var filePath = nodeInfo.FilePath; @@ -1005,8 +958,7 @@ public static string GetChannelPageFilePath(SiteInfo siteInfo, int channelId, in public static string GetContentPageFilePath(SiteInfo siteInfo, int channelId, int contentId, int currentPageIndex) { - var tableName = ChannelManager.GetTableName(siteInfo, channelId); - var contentInfo = Content.GetContentInfo(tableName, contentId); + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelId, contentId); return GetContentPageFilePath(siteInfo, channelId, contentInfo, currentPageIndex); } @@ -1032,33 +984,33 @@ public static string GetContentPageFilePath(SiteInfo siteInfo, int channelId, Co public static bool IsImageExtenstionAllowed(SiteInfo siteInfo, string fileExtention) { - return PathUtils.IsFileExtenstionAllowed(siteInfo.Additional.ImageUploadTypeCollection, fileExtention); + return PathUtils.IsFileExtenstionAllowed(siteInfo.ImageUploadTypeCollection, fileExtention); } public static bool IsImageSizeAllowed(SiteInfo siteInfo, int contentLength) { - return contentLength <= siteInfo.Additional.ImageUploadTypeMaxSize * 1024; + return contentLength <= siteInfo.ImageUploadTypeMaxSize * 1024; } public static bool IsVideoExtenstionAllowed(SiteInfo siteInfo, string fileExtention) { - return PathUtils.IsFileExtenstionAllowed(siteInfo.Additional.VideoUploadTypeCollection, fileExtention); + return PathUtils.IsFileExtenstionAllowed(siteInfo.VideoUploadTypeCollection, fileExtention); } public static bool IsVideoSizeAllowed(SiteInfo siteInfo, int contentLength) { - return contentLength <= siteInfo.Additional.VideoUploadTypeMaxSize * 1024; + return contentLength <= siteInfo.VideoUploadTypeMaxSize * 1024; } public static bool IsFileExtenstionAllowed(SiteInfo siteInfo, string fileExtention) { - var typeCollection = siteInfo.Additional.FileUploadTypeCollection + "," + siteInfo.Additional.ImageUploadTypeCollection + "," + siteInfo.Additional.VideoUploadTypeCollection; + var typeCollection = siteInfo.FileUploadTypeCollection + "," + siteInfo.ImageUploadTypeCollection + "," + siteInfo.VideoUploadTypeCollection; return PathUtils.IsFileExtenstionAllowed(typeCollection, fileExtention); } public static bool IsFileSizeAllowed(SiteInfo siteInfo, int contentLength) { - return contentLength <= siteInfo.Additional.FileUploadTypeMaxSize * 1024; + return contentLength <= siteInfo.FileUploadTypeMaxSize * 1024; } public static bool IsUploadExtenstionAllowed(EUploadType uploadType, SiteInfo siteInfo, string fileExtention) diff --git a/net452/SiteServer.CMS/Core/RestRoutes/ApiManager.cs b/net452/SiteServer.CMS/Core/RestRoutes/ApiManager.cs new file mode 100644 index 000000000..03c2166c6 --- /dev/null +++ b/net452/SiteServer.CMS/Core/RestRoutes/ApiManager.cs @@ -0,0 +1,43 @@ +using SiteServer.CMS.Caches; +using SiteServer.CMS.Fx; +using SiteServer.Utils; + +namespace SiteServer.CMS.Core.RestRoutes +{ + public static class ApiManager + { + public static bool IsSeparatedApi => ConfigManager.Instance.IsSeparatedApi; + + public static string ApiUrl => ConfigManager.Instance.ApiUrl; + + public static string RootUrl => FxUtils.ApplicationPath; + + public static string ApiPrefix => WebConfigUtils.ApiPrefix; + + public const string ApiVersion = "v1"; + + private static string _innerApiUrl; + + public static string InnerApiUrl + { + get + { + if (string.IsNullOrEmpty(_innerApiUrl)) + { + _innerApiUrl = FxUtils.ParseNavigationUrl($"~/{WebConfigUtils.ApiPrefix}"); + } + return _innerApiUrl; + } + } + + public static string GetApiUrl(string route) + { + return PageUtils.Combine(ApiUrl, route); + } + + public static string GetInnerApiUrl(string route) + { + return PageUtils.Combine(InnerApiUrl, route); + } + } +} diff --git a/net452/SiteServer.CMS/Core/RestRoutes/ApiRoutePlugin.cs b/net452/SiteServer.CMS/Core/RestRoutes/ApiRoutePlugin.cs new file mode 100644 index 000000000..d8f87c242 --- /dev/null +++ b/net452/SiteServer.CMS/Core/RestRoutes/ApiRoutePlugin.cs @@ -0,0 +1,67 @@ +using SiteServer.Utils; + +namespace SiteServer.CMS.Core.RestRoutes +{ + public static class ApiRoutePlugin + { + public const string Route = "plugins/{pluginId}"; + public const string RouteAction = "plugins/{pluginId}/actions/{routeAction}"; + public const string RouteResource = "plugins/{pluginId}/{routeResource}"; + public const string RouteResourceAction = "plugins/{pluginId}/{routeResource}/actions/{routeAction}"; + public const string RouteResourceId = "plugins/{pluginId}/{routeResource}/{routeId}"; + public const string RouteResourceIdAction = "plugins/{pluginId}/{routeResource}/{routeId}/actions/{routeAction}"; + + public static string GetRoute(string routeResource, string routeId, string routeAction) + { + var route = string.Empty; + if (!string.IsNullOrEmpty(routeResource)) + { + route = PageUtils.Combine(route, routeResource); + if (!string.IsNullOrEmpty(routeId)) + { + route = PageUtils.Combine(route, routeId); + if (!string.IsNullOrEmpty(routeAction)) + { + route = PageUtils.Combine(route, "actions", routeAction); + } + } + else if (!string.IsNullOrEmpty(routeAction)) + { + route = PageUtils.Combine(route, "actions", routeAction); + } + } + else if (!string.IsNullOrEmpty(routeAction)) + { + route = PageUtils.Combine(route, "actions", routeAction); + } + return route; + } + + public static string GetUrl(string pluginId, string routeResource = "", string routeId = "", string routeAction = "") + { + var apiUrl = ApiManager.GetApiUrl(Route); + apiUrl = apiUrl.Replace("{pluginId}", pluginId); + if (!string.IsNullOrEmpty(routeResource)) + { + apiUrl = PageUtils.Combine(apiUrl, routeResource); + if (!string.IsNullOrEmpty(routeId)) + { + apiUrl = PageUtils.Combine(apiUrl, routeId); + if (!string.IsNullOrEmpty(routeAction)) + { + apiUrl = PageUtils.Combine(apiUrl, "actions", routeAction); + } + } + else if (!string.IsNullOrEmpty(routeAction)) + { + apiUrl = PageUtils.Combine(apiUrl, "actions", routeAction); + } + } + else if (!string.IsNullOrEmpty(routeAction)) + { + apiUrl = PageUtils.Combine(apiUrl, "actions", routeAction); + } + return apiUrl; + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Core/RestRoutes/Preview/ApiRoutePreview.cs b/net452/SiteServer.CMS/Core/RestRoutes/Preview/ApiRoutePreview.cs new file mode 100644 index 000000000..e81381f84 --- /dev/null +++ b/net452/SiteServer.CMS/Core/RestRoutes/Preview/ApiRoutePreview.cs @@ -0,0 +1,83 @@ +namespace SiteServer.CMS.Core.RestRoutes.Preview +{ + public class ApiRoutePreview + { + public const string Route = "preview/{siteId}"; + public const string RouteChannel = "preview/{siteId}/{channelId}"; + public const string RouteContent = "preview/{siteId}/{channelId}/{contentId}"; + public const string RouteFile = "preview/{siteId}/file/{fileTemplateId}"; + public const string RouteSpecial = "preview/{siteId}/special/{specialId}"; + + public static string GetSiteUrl(int siteId) + { + var apiUrl = ApiManager.GetInnerApiUrl(Route); + apiUrl = apiUrl.Replace("{siteId}", siteId.ToString()); + return apiUrl; + } + + public static string GetChannelUrl(int siteId, int channelId) + { + var apiUrl = ApiManager.GetInnerApiUrl(RouteChannel); + apiUrl = apiUrl.Replace("{siteId}", siteId.ToString()); + apiUrl = apiUrl.Replace("{channelId}", channelId.ToString()); + return apiUrl; + } + + public static string GetContentUrl(int siteId, int channelId, int contentId) + { + var apiUrl = ApiManager.GetInnerApiUrl(RouteContent); + apiUrl = apiUrl.Replace("{siteId}", siteId.ToString()); + apiUrl = apiUrl.Replace("{channelId}", channelId.ToString()); + apiUrl = apiUrl.Replace("{contentId}", contentId.ToString()); + return apiUrl; + } + + public static string GetContentPreviewUrl(int siteId, int channelId, int contentId, int previewId) + { + if (contentId == 0) + { + contentId = previewId; + } + return $"{GetContentUrl(siteId, channelId, contentId)}?isPreview=true&previewId={previewId}"; + } + + public static string GetFileUrl(int siteId, int fileTemplateId) + { + var apiUrl = ApiManager.GetInnerApiUrl(RouteFile); + apiUrl = apiUrl.Replace("{siteId}", siteId.ToString()); + apiUrl = apiUrl.Replace("{fileTemplateId}", fileTemplateId.ToString()); + return apiUrl; + } + + public static string GetSpecialUrl(int siteId, int specialId) + { + var apiUrl = ApiManager.GetInnerApiUrl(RouteSpecial); + apiUrl = apiUrl.Replace("{siteId}", siteId.ToString()); + apiUrl = apiUrl.Replace("{specialId}", specialId.ToString()); + return apiUrl; + } + + public static string GetUrl(int siteId, int channelId, int contentId, int fileTemplateId, int specialId) + { + var apiUrl = GetSiteUrl(siteId); + if (channelId > 0) + { + apiUrl = GetChannelUrl(siteId, channelId); + if (contentId > 0) + { + apiUrl = GetContentUrl(siteId, channelId, contentId); + } + } + else if (fileTemplateId > 0) + { + apiUrl = GetFileUrl(siteId, fileTemplateId); + } + else if (specialId > 0) + { + apiUrl = GetSpecialUrl(siteId, specialId); + } + + return apiUrl; + } + } +} \ No newline at end of file diff --git a/SiteServer.CMS/Api/Sys/Editors/ApiRouteUEditor.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Editors/ApiRouteUEditor.cs similarity index 87% rename from SiteServer.CMS/Api/Sys/Editors/ApiRouteUEditor.cs rename to net452/SiteServer.CMS/Core/RestRoutes/Sys/Editors/ApiRouteUEditor.cs index 6b8bbea28..2d6ed7877 100644 --- a/SiteServer.CMS/Api/Sys/Editors/ApiRouteUEditor.cs +++ b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Editors/ApiRouteUEditor.cs @@ -1,6 +1,6 @@ using SiteServer.Utils; -namespace SiteServer.CMS.Api.Sys.Editors +namespace SiteServer.CMS.Core.RestRoutes.Sys.Editors { public class ApiRouteUEditor { diff --git a/SiteServer.CMS/Api/Sys/Packaging/ApiRouteClearCache.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Packaging/ApiRouteClearCache.cs similarity index 100% rename from SiteServer.CMS/Api/Sys/Packaging/ApiRouteClearCache.cs rename to net452/SiteServer.CMS/Core/RestRoutes/Sys/Packaging/ApiRouteClearCache.cs diff --git a/SiteServer.CMS/Api/Sys/Packaging/ApiRouteDownload.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Packaging/ApiRouteDownload.cs similarity index 100% rename from SiteServer.CMS/Api/Sys/Packaging/ApiRouteDownload.cs rename to net452/SiteServer.CMS/Core/RestRoutes/Sys/Packaging/ApiRouteDownload.cs diff --git a/SiteServer.CMS/Api/Sys/Packaging/ApiRouteSyncDatabase.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Packaging/ApiRouteSyncDatabase.cs similarity index 100% rename from SiteServer.CMS/Api/Sys/Packaging/ApiRouteSyncDatabase.cs rename to net452/SiteServer.CMS/Core/RestRoutes/Sys/Packaging/ApiRouteSyncDatabase.cs diff --git a/SiteServer.CMS/Api/Sys/Packaging/ApiRouteUpdate.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Packaging/ApiRouteUpdate.cs similarity index 100% rename from SiteServer.CMS/Api/Sys/Packaging/ApiRouteUpdate.cs rename to net452/SiteServer.CMS/Core/RestRoutes/Sys/Packaging/ApiRouteUpdate.cs diff --git a/SiteServer.CMS/Api/Sys/Packaging/ApiRouteUpdateSsCms.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Packaging/ApiRouteUpdateSsCms.cs similarity index 100% rename from SiteServer.CMS/Api/Sys/Packaging/ApiRouteUpdateSsCms.cs rename to net452/SiteServer.CMS/Core/RestRoutes/Sys/Packaging/ApiRouteUpdateSsCms.cs diff --git a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsDownload.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsDownload.cs similarity index 97% rename from SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsDownload.cs rename to net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsDownload.cs index 1687bbe3f..7094e4dbb 100644 --- a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsDownload.cs +++ b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsDownload.cs @@ -1,7 +1,7 @@ using System.Collections.Specialized; using SiteServer.Utils; -namespace SiteServer.CMS.Api.Sys.Stl +namespace SiteServer.CMS.Core.RestRoutes.Sys.Stl { public class ApiRouteActionsDownload { diff --git a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsDynamic.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsDynamic.cs similarity index 94% rename from SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsDynamic.cs rename to net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsDynamic.cs index fabcb9973..9d3ee611f 100644 --- a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsDynamic.cs +++ b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsDynamic.cs @@ -1,6 +1,6 @@ using SiteServer.Utils; -namespace SiteServer.CMS.Api.Sys.Stl +namespace SiteServer.CMS.Core.RestRoutes.Sys.Stl { public class ApiRouteActionsDynamic { diff --git a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsIf.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsIf.cs similarity index 95% rename from SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsIf.cs rename to net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsIf.cs index d55f64895..2618660f8 100644 --- a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsIf.cs +++ b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsIf.cs @@ -1,6 +1,6 @@ using SiteServer.Utils; -namespace SiteServer.CMS.Api.Sys.Stl +namespace SiteServer.CMS.Core.RestRoutes.Sys.Stl { public class ApiRouteActionsIf { diff --git a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsInputAdd.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsInputAdd.cs similarity index 90% rename from SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsInputAdd.cs rename to net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsInputAdd.cs index ff5a7a3e2..0af33e287 100644 --- a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsInputAdd.cs +++ b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsInputAdd.cs @@ -1,6 +1,6 @@ using SiteServer.Utils; -namespace SiteServer.CMS.Api.Sys.Stl +namespace SiteServer.CMS.Core.RestRoutes.Sys.Stl { public class ApiRouteActionsInputAdd { diff --git a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsLoadingChannels.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsLoadingChannels.cs similarity index 86% rename from SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsLoadingChannels.cs rename to net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsLoadingChannels.cs index 4a82a6575..ff9197fb0 100644 --- a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsLoadingChannels.cs +++ b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsLoadingChannels.cs @@ -1,6 +1,6 @@ using SiteServer.Utils; -namespace SiteServer.CMS.Api.Sys.Stl +namespace SiteServer.CMS.Core.RestRoutes.Sys.Stl { public class ApiRouteActionsLoadingChannels { diff --git a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsPageContents.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsPageContents.cs similarity index 94% rename from SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsPageContents.cs rename to net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsPageContents.cs index 534ef863a..72987e471 100644 --- a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsPageContents.cs +++ b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsPageContents.cs @@ -1,6 +1,6 @@ using SiteServer.Utils; -namespace SiteServer.CMS.Api.Sys.Stl +namespace SiteServer.CMS.Core.RestRoutes.Sys.Stl { public class ApiRouteActionsPageContents { diff --git a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsRelatedField.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsRelatedField.cs similarity index 93% rename from SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsRelatedField.cs rename to net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsRelatedField.cs index bbf799ced..52e07768b 100644 --- a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsRelatedField.cs +++ b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsRelatedField.cs @@ -1,7 +1,7 @@ using System.Collections.Specialized; using SiteServer.Utils; -namespace SiteServer.CMS.Api.Sys.Stl +namespace SiteServer.CMS.Core.RestRoutes.Sys.Stl { public class ApiRouteActionsRelatedField { diff --git a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsResumeAdd.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsResumeAdd.cs similarity index 88% rename from SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsResumeAdd.cs rename to net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsResumeAdd.cs index a2b4c2e1f..5ae38cb27 100644 --- a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsResumeAdd.cs +++ b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsResumeAdd.cs @@ -1,6 +1,6 @@ using SiteServer.Utils; -namespace SiteServer.CMS.Api.Sys.Stl +namespace SiteServer.CMS.Core.RestRoutes.Sys.Stl { public class ApiRouteActionsResumeAdd { diff --git a/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsSearch.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsSearch.cs new file mode 100644 index 000000000..0f65aae7c --- /dev/null +++ b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsSearch.cs @@ -0,0 +1,63 @@ +using System.Collections.Generic; +using SiteServer.CMS.StlParser.StlElement; +using SiteServer.Utils; + +namespace SiteServer.CMS.Core.RestRoutes.Sys.Stl +{ + public static class ApiRouteActionsSearch + { + public const string Route = "sys/stl/actions/search"; + + public static string GetUrl(string apiUrl) + { + return PageUtils.Combine(apiUrl, Route); + } + + public static string GetParameters(bool isAllSites, string siteName, string siteDir, string siteIds, string channelIndex, string channelName, string channelIds, string type, string word, string dateAttribute, string dateFrom, string dateTo, string since, int pageNum, bool isHighlight, int siteId, string ajaxDivId, string template) + { + return $@" +{{ + {StlSearch.IsAllSites.ToLower()}: {isAllSites.ToString().ToLower()}, + {StlSearch.SiteName.ToLower()}: '{siteName}', + {StlSearch.SiteDir.ToLower()}: '{siteDir}', + {StlSearch.SiteIds.ToLower()}: '{siteIds}', + {StlSearch.ChannelIndex.ToLower()}: '{channelIndex}', + {StlSearch.ChannelName.ToLower()}: '{channelName}', + {StlSearch.ChannelIds.ToLower()}: '{channelIds}', + {StlSearch.Type.ToLower()}: '{type}', + {StlSearch.Word.ToLower()}: '{word}', + {StlSearch.DateAttribute.ToLower()}: '{dateAttribute}', + {StlSearch.DateFrom.ToLower()}: '{dateFrom}', + {StlSearch.DateTo.ToLower()}: '{dateTo}', + {StlSearch.Since.ToLower()}: '{since}', + {StlSearch.PageNum.ToLower()}: {pageNum}, + {StlSearch.IsHighlight.ToLower()}: {isHighlight.ToString().ToLower()}, + siteid: '{siteId}', + ajaxdivid: '{ajaxDivId}', + template: '{TranslateUtils.EncryptStringBySecretKey(template)}', +}}"; + } + + public static List ExlcudeAttributeNames => new List + { + StlSearch.IsAllSites.ToLower(), + StlSearch.SiteName.ToLower(), + StlSearch.SiteDir.ToLower(), + StlSearch.SiteIds.ToLower(), + StlSearch.ChannelIndex.ToLower(), + StlSearch.ChannelName.ToLower(), + StlSearch.ChannelIds.ToLower(), + StlSearch.Type.ToLower(), + StlSearch.Word.ToLower(), + StlSearch.DateAttribute.ToLower(), + StlSearch.DateFrom.ToLower(), + StlSearch.DateTo.ToLower(), + StlSearch.Since.ToLower(), + StlSearch.PageNum.ToLower(), + StlSearch.IsHighlight.ToLower(), + "siteid", + "ajaxdivid", + "template", + }; + } +} \ No newline at end of file diff --git a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsTrigger.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsTrigger.cs similarity index 93% rename from SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsTrigger.cs rename to net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsTrigger.cs index a5d1482e0..05d9165ab 100644 --- a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsTrigger.cs +++ b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsTrigger.cs @@ -1,7 +1,7 @@ using System.Collections.Specialized; using SiteServer.Utils; -namespace SiteServer.CMS.Api.Sys.Stl +namespace SiteServer.CMS.Core.RestRoutes.Sys.Stl { public class ApiRouteActionsTrigger { diff --git a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsUpload.cs b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsUpload.cs similarity index 93% rename from SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsUpload.cs rename to net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsUpload.cs index c3efbc428..9cd9c6929 100644 --- a/SiteServer.CMS/Api/Sys/Stl/ApiRouteActionsUpload.cs +++ b/net452/SiteServer.CMS/Core/RestRoutes/Sys/Stl/ApiRouteActionsUpload.cs @@ -1,7 +1,7 @@ using System.Collections.Specialized; using SiteServer.Utils; -namespace SiteServer.CMS.Api.Sys.Stl +namespace SiteServer.CMS.Core.RestRoutes.Sys.Stl { public class ApiRouteActionsUpload { diff --git a/net452/SiteServer.CMS/Core/RestRoutes/V1/ApiContentsParameters.cs b/net452/SiteServer.CMS/Core/RestRoutes/V1/ApiContentsParameters.cs new file mode 100644 index 000000000..3fc49f7e3 --- /dev/null +++ b/net452/SiteServer.CMS/Core/RestRoutes/V1/ApiContentsParameters.cs @@ -0,0 +1,57 @@ +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Net.Http; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Core.RestRoutes.V1 +{ + public class ApiContentsParameters + { + public ApiContentsParameters(HttpRequestMessage request) + { + ChannelIds = TranslateUtils.StringCollectionToIntList(request.GetQueryString("channelIds")); + ChannelGroup = StringUtils.Trim(AttackUtils.FilterSql(request.GetQueryString("channelGroup"))); + ContentGroup = StringUtils.Trim(AttackUtils.FilterSql(request.GetQueryString("contentGroup"))); + Tag = StringUtils.Trim(AttackUtils.FilterSql(request.GetQueryString("tag"))); + Top = request.GetQueryInt("top", 20); + Skip = request.GetQueryInt("skip"); + Likes = TranslateUtils.StringCollectionToStringList(StringUtils.Trim(AttackUtils.FilterSql(request.GetQueryString("like")))); + OrderBy = StringUtils.Trim(AttackUtils.FilterSql(request.GetQueryString("orderBy"))); + + //var queryDict = new Dictionary(StringComparer.InvariantCultureIgnoreCase); + //queryDict.AddRange(request.QueryDict); + QueryString = request.GetQueryDirectory(); + + QueryString.Remove("siteId"); + QueryString.Remove("channelIds"); + QueryString.Remove("channelGroup"); + QueryString.Remove("contentGroup"); + QueryString.Remove("tag"); + QueryString.Remove("top"); + QueryString.Remove("skip"); + QueryString.Remove("like"); + QueryString.Remove("orderBy"); + } + + public List ChannelIds { get; set; } + + public string ChannelGroup { get; set; } + + public string ContentGroup { get; set; } + + public string Tag { get; set; } + + public int Top { get; set; } + + public int Skip { get; set; } + + public List Likes { get; set; } + + public string OrderBy { get; set; } + + public IDictionary QueryString { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Core/RestRoutes/V1/PageResponse.cs b/net452/SiteServer.CMS/Core/RestRoutes/V1/PageResponse.cs new file mode 100644 index 000000000..d2702671a --- /dev/null +++ b/net452/SiteServer.CMS/Core/RestRoutes/V1/PageResponse.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using Newtonsoft.Json; +using SiteServer.Utils; + +namespace SiteServer.CMS.Core.RestRoutes.V1 +{ + public class PageResponse + { + private int? _count; + private int? _top; + private int? _skip; + private string _rowUrl; + + public PageResponse(object value, int top, int skip, string rowUrl) + { + Value = value; + _top = top; + _skip = skip; + _rowUrl = rowUrl; + } + + [JsonProperty(PropertyName = "value")] + public object Value { get; set; } + + [JsonProperty(PropertyName = "first", NullValueHandling = NullValueHandling.Ignore)] + public string First { get; private set; } + + [JsonProperty(PropertyName = "prev", NullValueHandling = NullValueHandling.Ignore)] + public string Prev { get; private set; } + + [JsonProperty(PropertyName = "next", NullValueHandling = NullValueHandling.Ignore)] + public string Next { get; private set; } + + [JsonProperty(PropertyName = "last", NullValueHandling = NullValueHandling.Ignore)] + public string Last { get; private set; } + + [JsonProperty(PropertyName = "count", NullValueHandling = NullValueHandling.Ignore)] + public int? Count + { + get { return _count; } + set + { + _count = value; + if (_count != null && _top != null && _skip != null && _rowUrl != null) + { + var url = PageUtils.RemoveQueryString(_rowUrl, new List {"top", "skip"}); + var pages = Convert.ToInt32(Math.Ceiling(Convert.ToDouble((int)_count / _top))); + var pageIndex = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(_skip / _top))); + + if (_skip > 0) + { + First = PageUtils.AddQueryString(url, + new NameValueCollection + { + {"top", _top.ToString()}, + {"skip", "0"} + }); + + Prev = PageUtils.AddQueryString(url, + new NameValueCollection + { + {"top", _top.ToString()}, + {"skip", ((pageIndex - 1) * _top).ToString()} + }); + } + + if (_top + _skip < _count) + { + Next = + PageUtils.AddQueryString(url, + new NameValueCollection + { + {"top", _top.ToString()}, + {"skip", ((pageIndex + 1) * _top).ToString()} + }); + + Last = + PageUtils.AddQueryString(url, + new NameValueCollection + { + {"top", _top.ToString()}, + {"skip", ((pages - 1) * _top).ToString()} + }); + } + } + } + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Core/RestRoutes/V1/StlRequest.cs b/net452/SiteServer.CMS/Core/RestRoutes/V1/StlRequest.cs new file mode 100644 index 000000000..77e6731dc --- /dev/null +++ b/net452/SiteServer.CMS/Core/RestRoutes/V1/StlRequest.cs @@ -0,0 +1,109 @@ +using System.Collections.Generic; +using System.Net.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.StlParser.Model; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Core.RestRoutes.V1 +{ + public class StlRequest + { + private HttpRequestMessage Request { get; } + + public bool IsApiAuthorized { get; } + + public SiteInfo SiteInfo { get; } + + public PageInfo PageInfo { get; } + + public ContextInfo ContextInfo { get; } + + public StlRequest(HttpRequestMessage request) + { + Request = request; + + var rest = request.GetAuthenticatedRequest(); + + IsApiAuthorized = AccessTokenManager.IsScope(request.GetApiToken(), AccessTokenManager.ScopeStl); + + if (!IsApiAuthorized) return; + + var siteId = Request.GetQueryInt("siteId"); + var siteDir = Request.GetQueryString("siteDir"); + + var channelId = Request.GetQueryInt("channelId"); + var contentId = Request.GetQueryInt("contentId"); + + if (siteId > 0) + { + SiteInfo = SiteManager.GetSiteInfo(siteId); + } + else if (!string.IsNullOrEmpty(siteDir)) + { + SiteInfo = SiteManager.GetSiteInfoByDirectory(siteDir); + } + else + { + SiteInfo = SiteManager.GetSiteInfoByIsRoot(); + if (SiteInfo == null) + { + var siteInfoList = SiteManager.GetSiteInfoList(); + if (siteInfoList != null && siteInfoList.Count > 0) + { + SiteInfo = siteInfoList[0]; + } + } + } + + if (SiteInfo == null) return; + + if (channelId == 0) + { + channelId = SiteInfo.Id; + } + + var templateInfo = new TemplateInfo + { + SiteId = SiteInfo.Id, + TemplateName = string.Empty, + Type = TemplateType.IndexPageTemplate, + RelatedFileName = string.Empty, + CreatedFileFullName = string.Empty, + CreatedFileExtName = string.Empty, + Default = true + }; + + var userInfo = UserManager.GetUserInfoByUserId(rest.UserId); + + PageInfo = new PageInfo(channelId, contentId, SiteInfo, templateInfo, new Dictionary()) + { + UniqueId = 1000, + UserInfo = userInfo + }; + + var attributes = TranslateUtils.NewIgnoreCaseNameValueCollection(); + //foreach (var key in Request.QueryDict.Keys) + //{ + // attributes[key] = Request.QueryDict[key]; + //} + var dict = request.GetQueryDirectory(); + if (dict != null && dict.Count > 0) + { + foreach (var key in dict.Keys) + { + attributes[key] = dict[key]; + } + } + + + ContextInfo = new ContextInfo(PageInfo) + { + IsStlEntity = true, + Attributes = attributes, + InnerHtml = string.Empty + }; + } + } +} diff --git a/net452/SiteServer.CMS/Core/RoleManager.cs b/net452/SiteServer.CMS/Core/RoleManager.cs new file mode 100644 index 000000000..5ef43c487 --- /dev/null +++ b/net452/SiteServer.CMS/Core/RoleManager.cs @@ -0,0 +1,39 @@ +using SiteServer.Utils.Enumerations; +using System.Collections.Generic; +using System.Linq; +using SiteServer.CMS.Database.Core; + +namespace SiteServer.CMS.Core +{ + public static class RoleManager + { + public static List> GetRestRoles(bool isSuperAdmin, string adminName) + { + var list = new List>(); + + IList roleNames; + if (isSuperAdmin) + { + foreach (var predefinedRuleName in EPredefinedRoleUtils.GetAllPredefinedRoleName()) + { + list.Add(new KeyValuePair(predefinedRuleName, EPredefinedRoleUtils.GetText(EPredefinedRoleUtils.GetEnumType(predefinedRuleName)))); + } + + roleNames = DataProvider.Role.GetRoleNameList(); + } + else + { + roleNames = DataProvider.Role.GetRoleNameListByCreatorUserName(adminName); + } + + foreach (var roleName in roleNames) + { + if (list.Any(x=> x.Key == roleName)) continue; + + list.Add(new KeyValuePair(roleName, roleName)); + } + + return list; + } + } +} diff --git a/SiteServer.Utils/SiteFilesAssets.cs b/net452/SiteServer.CMS/Core/SiteFilesAssets.cs similarity index 97% rename from SiteServer.Utils/SiteFilesAssets.cs rename to net452/SiteServer.CMS/Core/SiteFilesAssets.cs index e0afa9701..666387f60 100644 --- a/SiteServer.Utils/SiteFilesAssets.cs +++ b/net452/SiteServer.CMS/Core/SiteFilesAssets.cs @@ -1,8 +1,10 @@ using System; +using SiteServer.CMS.Fx; +using SiteServer.Utils; -namespace SiteServer.Utils +namespace SiteServer.CMS.Core { - public class SiteFilesAssets + public static class SiteFilesAssets { public const string FileLoading = "loading.gif"; public const string FileS = "s.gif"; @@ -35,7 +37,7 @@ public static string GetUrl(string apiUrl, string relatedUrl) return PageUtils.Combine(apiUrl, "sitefiles/assets", relatedUrl); } - public static string GetPath(params string[] paths) => PathUtils.GetSiteFilesPath("assets", PathUtils.Combine(paths)); + public static string GetPath(params string[] paths) => FxUtils.GetSiteFilesPath("assets", PathUtils.Combine(paths)); public class CommentInput { @@ -303,7 +305,6 @@ public class Slide public class Print { public const string JsUtf8 = "scripts/print_uft8.js"; - public const string JsGb2312 = "scripts/print.js"; public const string IconUrl = "Icons/print"; } diff --git a/SiteServer.Utils/SiteServerAssets.cs b/net452/SiteServer.CMS/Core/SiteServerAssets.cs similarity index 97% rename from SiteServer.Utils/SiteServerAssets.cs rename to net452/SiteServer.CMS/Core/SiteServerAssets.cs index 854f4f48d..946d868d4 100644 --- a/SiteServer.Utils/SiteServerAssets.cs +++ b/net452/SiteServer.CMS/Core/SiteServerAssets.cs @@ -1,14 +1,16 @@ +using SiteServer.CMS.Fx; +using SiteServer.Utils; using SiteServer.Utils.Enumerations; -namespace SiteServer.Utils +namespace SiteServer.CMS.Core { - public class SiteServerAssets + public static class SiteServerAssets { public const string DirectoryName = "assets"; public static string GetUrl(string relatedUrl) { - return PageUtils.Combine(PageUtils.GetAdminDirectoryUrl(DirectoryName), relatedUrl); + return PageUtils.Combine(FxUtils.GetAdminUrl(DirectoryName), relatedUrl); } public static string GetPath(params string[] paths) diff --git a/net452/SiteServer.CMS/Core/SiteTemplateInfo.cs b/net452/SiteServer.CMS/Core/SiteTemplateInfo.cs new file mode 100644 index 000000000..8ae82bb02 --- /dev/null +++ b/net452/SiteServer.CMS/Core/SiteTemplateInfo.cs @@ -0,0 +1,41 @@ +using System; +using System.Xml.Serialization; + +namespace SiteServer.CMS.Core +{ + [Serializable] + [XmlRoot("SiteTemplate")] + public class SiteTemplateInfo + { + public SiteTemplateInfo() + { + SiteTemplateName = string.Empty; + WebSiteUrl = string.Empty; + PicFileName = string.Empty; + Description = string.Empty; + } + + public SiteTemplateInfo(string siteTemplateName, string webSiteUrl, string picFileName, string description) + { + SiteTemplateName = siteTemplateName; + WebSiteUrl = webSiteUrl; + PicFileName = picFileName; + Description = description; + } + + [XmlElement(ElementName = "SiteTemplateName")] + public string SiteTemplateName { get; set; } + + [XmlElement(ElementName = "WebSiteUrl")] + public string WebSiteUrl { get; set; } + + [XmlElement(ElementName = "PicFileName")] + public string PicFileName { get; set; } + + [XmlElement(ElementName = "Description")] + public string Description { get; set; } + + public string DirectoryName { get; set; } + + } +} diff --git a/SiteServer.CMS/Core/SiteTemplateManager.cs b/net452/SiteServer.CMS/Core/SiteTemplateManager.cs similarity index 86% rename from SiteServer.CMS/Core/SiteTemplateManager.cs rename to net452/SiteServer.CMS/Core/SiteTemplateManager.cs index fb1ad3611..003ebb698 100644 --- a/SiteServer.CMS/Core/SiteTemplateManager.cs +++ b/net452/SiteServer.CMS/Core/SiteTemplateManager.cs @@ -1,8 +1,8 @@ using System.Collections; using System.Collections.Generic; +using SiteServer.CMS.Database.Models; using SiteServer.Utils; using SiteServer.CMS.ImportExport; -using SiteServer.CMS.Model; using SiteServer.Utils.Enumerations; namespace SiteServer.CMS.Core @@ -16,11 +16,6 @@ private SiteTemplateManager(string rootPath) DirectoryUtils.CreateDirectoryIfNotExists(_rootPath); } - public static SiteTemplateManager GetInstance(string rootPath) - { - return new SiteTemplateManager(rootPath); - } - public static SiteTemplateManager Instance => new SiteTemplateManager(PathUtility.GetSiteTemplatesPath(string.Empty)); @@ -45,23 +40,6 @@ public bool IsSiteTemplateDirectoryExists(string siteTemplateDir) return DirectoryUtils.IsDirectoryExists(siteTemplatePath); } - public int GetSiteTemplateCount() - { - var directorys = DirectoryUtils.GetDirectoryPaths(_rootPath); - return directorys.Length; - } - - public List GetDirectoryNameLowerList() - { - var directorys = DirectoryUtils.GetDirectoryNames(_rootPath); - var list = new List(); - foreach (var directoryName in directorys) - { - list.Add(directoryName.ToLower().Trim()); - } - return list; - } - public bool IsSiteTemplateExists { get @@ -117,13 +95,11 @@ public List GetZipSiteTemplateList() return list; } - public void ImportSiteTemplateToEmptySite(int siteId, string siteTemplateDir, bool isUseTables, bool isImportContents, bool isImportTableStyles, string administratorName) + public void ImportSiteTemplateToEmptySite(int siteId, string siteTemplateDir, bool isImportContents, bool isImportTableStyles, string administratorName) { var siteTemplatePath = PathUtility.GetSiteTemplatesPath(siteTemplateDir); if (DirectoryUtils.IsDirectoryExists(siteTemplatePath)) { - var siteInfo = SiteManager.GetSiteInfo(siteId); - var templateFilePath = PathUtility.GetSiteTemplateMetadataPath(siteTemplatePath, DirectoryUtils.SiteTemplates.FileTemplate); var tableDirectoryPath = PathUtility.GetSiteTemplateMetadataPath(siteTemplatePath, DirectoryUtils.SiteTemplates.Table); var configurationFilePath = PathUtility.GetSiteTemplateMetadataPath(siteTemplatePath, DirectoryUtils.SiteTemplates.FileConfiguration); @@ -135,8 +111,6 @@ public void ImportSiteTemplateToEmptySite(int siteId, string siteTemplateDir, bo importObject.ImportTemplates(templateFilePath, true, administratorName); - importObject.ImportAuxiliaryTables(tableDirectoryPath, isUseTables); - importObject.ImportConfiguration(configurationFilePath); var filePathList = ImportObject.GetSiteContentFilePathList(siteContentDirectoryPath); @@ -146,8 +120,6 @@ public void ImportSiteTemplateToEmptySite(int siteId, string siteTemplateDir, bo importObject.ImportSiteContent(siteContentDirectoryPath, filePath, isImportContents); } - DataProvider.ChannelDao.UpdateContentNum(siteInfo); - if (isImportTableStyles) { importObject.ImportTableStyles(tableDirectoryPath); diff --git a/net452/SiteServer.CMS/Core/SourceManager.cs b/net452/SiteServer.CMS/Core/SourceManager.cs new file mode 100644 index 000000000..ec92a91d4 --- /dev/null +++ b/net452/SiteServer.CMS/Core/SourceManager.cs @@ -0,0 +1,40 @@ +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; + +namespace SiteServer.CMS.Core +{ + public static class SourceManager + { + public const int User = -1; //用户投稿 + public const int Preview = -99; //预览 + public const int Default = 0; //正常录入 + + public static string GetSourceName(int sourceId) + { + if (sourceId == Default) + { + return "后台录入"; + } + if (sourceId == User) + { + return "用户投稿"; + } + if (sourceId == Preview) + { + return "预览插入"; + } + if (sourceId <= 0) return string.Empty; + + var sourceSiteId = DataProvider.Channel.GetSiteId(sourceId); + var siteInfo = SiteManager.GetSiteInfo(sourceSiteId); + if (siteInfo == null) return "内容转移"; + + var nodeNames = ChannelManager.GetChannelNameNavigation(siteInfo.Id, sourceId); + if (!string.IsNullOrEmpty(nodeNames)) + { + return siteInfo.SiteName + ":" + nodeNames; + } + return siteInfo.SiteName; + } + } +} diff --git a/net452/SiteServer.CMS/Core/SystemManager.cs b/net452/SiteServer.CMS/Core/SystemManager.cs new file mode 100644 index 000000000..57d51f9ba --- /dev/null +++ b/net452/SiteServer.CMS/Core/SystemManager.cs @@ -0,0 +1,144 @@ +using System; +using System.Diagnostics; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Core +{ + public static class SystemManager + { + static SystemManager() + { + try + { + Version = FileVersionInfo.GetVersionInfo(PathUtils.GetBinDirectoryPath("SiteServer.CMS.dll")).ProductVersion; + PluginVersion = FileVersionInfo.GetVersionInfo(PathUtils.GetBinDirectoryPath("SiteServer.Plugin.dll")).ProductVersion; + } + catch + { + // ignored + } + + //var ssemblyName = assembly.GetName(); + //var assemblyVersion = ssemblyName.Version; + //var version = assemblyVersion.ToString(); + //if (StringUtils.EndsWith(version, ".0")) + //{ + // version = version.Substring(0, version.DataLength - 2); + //} + //Version = version; + } + + public static string Version { get; } + + public static string PluginVersion { get; } + + public const string ApiVersion = "v1"; + + public static void InstallDatabase(string adminName, string adminPassword) + { + SyncDatabase(); + + if (!string.IsNullOrEmpty(adminName) && !string.IsNullOrEmpty(adminPassword)) + { + var administratorInfo = new AdministratorInfo + { + UserName = adminName, + Password = adminPassword + }; + + DataProvider.Administrator.Insert(administratorInfo, out _); + DataProvider.AdministratorsInRoles.AddUserToRole(adminName, EPredefinedRoleUtils.GetValue(EPredefinedRole.ConsoleAdministrator)); + } + } + + public static void SyncSystemTables() + { + foreach (var repository in DataProvider.AllRepositories) + { + if (string.IsNullOrEmpty(repository.TableName) || repository.TableColumns == null || repository.TableColumns.Count <= 0) continue; + + if (!DatoryUtils.IsTableExists(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, repository.TableName)) + { + TableColumnManager.CreateTable(repository.TableName, repository.TableColumns, string.Empty, false, out _); + } + else + { + TableColumnManager.AlterTable(repository.TableName, repository.TableColumns, string.Empty); + } + } + } + + public static void SyncContentTables() + { + var tableNameList = SiteManager.GetAllTableNameList(); + foreach (var tableName in tableNameList) + { + if (!DatoryUtils.IsTableExists(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName)) + { + TableColumnManager.CreateTable(tableName, DataProvider.ContentRepository.TableColumns, string.Empty, true, out _); + } + else + { + TableColumnManager.AlterTable(tableName, DataProvider.ContentRepository.TableColumns, string.Empty, ContentAttribute.DropAttributes.Value); + } + } + } + + public static void UpdateConfigVersion() + { + var configInfo = DataProvider.Config.GetConfigInfo(); + if (configInfo == null) + { + configInfo = new ConfigInfo + { + Initialized = true, + DatabaseVersion = Version, + UpdateDate = DateTime.Now + }; + DataProvider.Config.Insert(configInfo); + } + else + { + configInfo.DatabaseVersion = Version; + configInfo.Initialized = true; + configInfo.UpdateDate = DateTime.Now; + DataProvider.Config.Update(configInfo); + } + } + + public static void SyncDatabase() + { + CacheUtils.ClearAll(); + + SyncSystemTables(); + + SyncContentTables(); + + UpdateConfigVersion(); + } + + public static bool IsNeedInstall() + { + var isNeedInstall = !DataProvider.Config.IsInitialized(); + if (isNeedInstall) + { + isNeedInstall = !DataProvider.Config.IsInitialized(); + } + return isNeedInstall; + } + + //public static bool DetermineRedirectToInstaller() + //{ + // if (!IsNeedInstall()) return false; + // PageUtils.Redirect(PageUtils.GetAdminDirectoryUrl("Installer")); + // return true; + //} + } +} diff --git a/net452/SiteServer.CMS/Core/TabManager.cs b/net452/SiteServer.CMS/Core/TabManager.cs new file mode 100644 index 000000000..d307e2fb0 --- /dev/null +++ b/net452/SiteServer.CMS/Core/TabManager.cs @@ -0,0 +1,204 @@ +using System.Collections; +using System.Collections.Generic; +using System.Web; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Core +{ + public static class TabManager + { + public static TabCollection GetTabs(string filePath) + { + if (filePath.StartsWith("/") || filePath.StartsWith("~")) + { + filePath = HttpContext.Current.Server.MapPath(filePath); + } + + var tc = CacheUtils.Get(filePath) as TabCollection; + if (tc != null) return tc; + + tc = (TabCollection)Serializer.ConvertFileToObject(filePath, typeof(TabCollection)); + CacheUtils.Insert(filePath, tc, filePath); + return tc; + } + + public static List GetTopMenuTabs() + { + var list = new List(); + + var menuPath = FxUtils.GetMenusPath("Top.config"); + if (!FileUtils.IsFileExists(menuPath)) return list; + + var tabs = GetTabs(menuPath); + foreach (var parent in tabs.Tabs) + { + list.Add(parent); + } + + return list; + } + + public static List GetTopMenuTabsWithChildren() + { + var list = new List(); + + var menuPath = FxUtils.GetMenusPath("Top.config"); + if (!FileUtils.IsFileExists(menuPath)) return list; + + var tabs = GetTabs(menuPath); + foreach (var parent in tabs.Tabs) + { + if (parent.HasChildren) + { + + } + list.Add(parent); + } + + return list; + } + + public static bool IsValid(Tab tab, IList permissionList) + { + if (tab.HasPermissions) + { + if (permissionList != null && permissionList.Count > 0) + { + var tabPermissions = tab.Permissions.Split(','); + foreach (var tabPermission in tabPermissions) + { + if (permissionList.Contains(tabPermission)) + return true; + } + } + + //ITab valid, but invalid role set + return false; + } + + //ITab valid, but no roles + return true; + } + + private static Tab GetPluginTab(SiteServer.Plugin.Menu menu, string permission) + { + var tab = new Tab + { + Id = menu.Id, + Text = menu.Text, + IconClass = menu.IconClass, + Selected = false, + Href = menu.Href, + Target = menu.Target, + Permissions = permission + }; + if (menu.Menus != null && menu.Menus.Count > 0) + { + tab.Children = new Tab[menu.Menus.Count]; + for (var i = 0; i < menu.Menus.Count; i++) + { + tab.Children[i] = GetPluginTab(menu.Menus[i], permission); + } + } + return tab; + } + + public static List GetTabList(string topId, int siteId) + { + var tabs = new List(); + + if (!string.IsNullOrEmpty(topId)) + { + var filePath = FxUtils.GetMenusPath($"{topId}.config"); + var tabCollection = GetTabs(filePath); + if (tabCollection?.Tabs != null) + { + foreach (var tabCollectionTab in tabCollection.Tabs) + { + tabs.Add(tabCollectionTab.Clone()); + } + } + } + + var menus = new List(); + if (siteId > 0 && topId == string.Empty) + { + var siteMenus = PluginMenuManager.GetSiteMenus(siteId); + if (siteMenus != null) + { + menus.AddRange(siteMenus); + } + } + else if (topId == "Plugins") + { + var topMenus = PluginMenuManager.GetTopMenus(); + if (topMenus != null) + { + menus.AddRange(topMenus); + } + } + + foreach (var menu in menus) + { + var isExists = false; + foreach (var childTab in tabs) + { + if (childTab.Id == menu.Id) + { + isExists = true; + } + } + + if (isExists) continue; + + tabs.Add(GetPluginTab(menu, menu.PluginId)); + + //if (string.IsNullOrEmpty(menu.ParentId)) + //{ + // var isExists = false; + // foreach (var childTab in tabs) + // { + // if (childTab.Id == menu.Id) + // { + // isExists = true; + // } + // } + + // if (isExists) continue; + + // tabs.Add(GetPluginTab(menu)); + //} + //else + //{ + // foreach (var tab in tabs) + // { + // if (!StringUtils.EqualsIgnoreCase(menu.ParentId, tab.Id)) continue; + + // var isExists = false; + // foreach (var childTab in tab.Children) + // { + // if (childTab.Id == menu.Id) + // { + // isExists = true; + // } + // } + + // if (isExists) continue; + + // var list = new List(); + // if (tab.Children != null) + // { + // list = tab.Children.ToList(); + // } + // list.Add(GetPluginTab(menu)); + // tab.Children = list.ToArray(); + // } + //} + } + + return tabs; + } + } +} diff --git a/SiteServer.CMS/Core/TagUtils.cs b/net452/SiteServer.CMS/Core/TagUtils.cs similarity index 84% rename from SiteServer.CMS/Core/TagUtils.cs rename to net452/SiteServer.CMS/Core/TagUtils.cs index 023a15170..c5b65b618 100644 --- a/SiteServer.CMS/Core/TagUtils.cs +++ b/net452/SiteServer.CMS/Core/TagUtils.cs @@ -4,24 +4,21 @@ using System.Collections; using System; using System.Collections.Generic; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; using SiteServer.Utils; namespace SiteServer.CMS.Core { - public class TagUtils + public static class TagUtils { - private TagUtils() - { - } - - public static void AddTags(StringCollection tags, int siteId, int contentId) + public static void AddTags(List tags, int siteId, int contentId) { if (tags == null || tags.Count == 0) return; foreach (var tagName in tags) { - var tagInfo = DataProvider.TagDao.GetTagInfo(siteId,PageUtils.FilterXss(tagName)); + var tagInfo = DataProvider.Tag.GetTagInfo(siteId, AttackUtils.FilterXss(tagName)); if (tagInfo != null) { var contentIdList = TranslateUtils.StringCollectionToIntList(tagInfo.ContentIdCollection); @@ -30,18 +27,24 @@ public static void AddTags(StringCollection tags, int siteId, int contentId) contentIdList.Add(contentId); tagInfo.ContentIdCollection = TranslateUtils.ObjectCollectionToString(contentIdList); tagInfo.UseNum = contentIdList.Count; - DataProvider.TagDao.Update(tagInfo); + DataProvider.Tag.Update(tagInfo); } } else { - tagInfo = new TagInfo(0, siteId, contentId.ToString(), tagName, contentId > 0 ? 1 : 0); - DataProvider.TagDao.Insert(tagInfo); + tagInfo = new TagInfo + { + SiteId = siteId, + ContentIdCollection = contentId.ToString(), + Tag = tagName, + UseNum = contentId > 0 ? 1 : 0 + }; + DataProvider.Tag.Insert(tagInfo); } } } - public static void UpdateTags(string tagsLast, string tagsNow, StringCollection tagCollection, int siteId, int contentId) + public static void UpdateTags(string tagsLast, string tagsNow, List tagCollection, int siteId, int contentId) { if (tagsLast == tagsNow) return; @@ -50,19 +53,19 @@ public static void UpdateTags(string tagsLast, string tagsNow, StringCollection { if (!tagCollection.Contains(tag))//删除 { - var tagInfo = DataProvider.TagDao.GetTagInfo(siteId, tag); + var tagInfo = DataProvider.Tag.GetTagInfo(siteId, tag); if (tagInfo != null) { var contentIdList = TranslateUtils.StringCollectionToIntList(tagInfo.ContentIdCollection); contentIdList.Remove(contentId); tagInfo.ContentIdCollection = TranslateUtils.ObjectCollectionToString(contentIdList); tagInfo.UseNum = contentIdList.Count; - DataProvider.TagDao.Update(tagInfo); + DataProvider.Tag.Update(tagInfo); } } } - var tagsToAdd = new StringCollection(); + var tagsToAdd = new List(); foreach (var tag in tagCollection) { if (!tagsList.Contains(tag)) @@ -74,7 +77,7 @@ public static void UpdateTags(string tagsLast, string tagsNow, StringCollection AddTags(tagsToAdd, siteId, contentId); } - public static void RemoveTags(int siteId, List contentIdList) + public static void RemoveTags(int siteId, IList contentIdList) { foreach (var contentId in contentIdList) { @@ -84,7 +87,7 @@ public static void RemoveTags(int siteId, List contentIdList) public static void RemoveTags(int siteId, int contentId) { - var tagInfoList = DataProvider.TagDao.GetTagInfoList(siteId, contentId); + var tagInfoList = DataProvider.Tag.GetTagInfoList(siteId, contentId); if (tagInfoList == null || tagInfoList.Count == 0) return; foreach (var tagInfo in tagInfoList) @@ -93,7 +96,7 @@ public static void RemoveTags(int siteId, int contentId) contentIdList.Remove(contentId); tagInfo.ContentIdCollection = TranslateUtils.ObjectCollectionToString(contentIdList); tagInfo.UseNum = contentIdList.Count; - DataProvider.TagDao.Update(tagInfo); + DataProvider.Tag.Update(tagInfo); } } @@ -111,9 +114,9 @@ public static string GetTagsString(StringCollection tags) return tagsBuilder.ToString(); } - public static StringCollection ParseTagsString(string tagsString) + public static List ParseTagsString(string tagsString) { - var stringCollection = new StringCollection(); + var stringCollection = new List(); if (string.IsNullOrEmpty(tagsString)) return stringCollection; @@ -159,7 +162,7 @@ public static List GetTagInfoList(List tagInfoList) return GetTagInfoList(tagInfoList, 0, 0); } - public static List GetTagInfoList(List tagInfoList, int totalNum, int tagLevel) + public static List GetTagInfoList(IList tagInfoList, int totalNum, int tagLevel) { var list = new List(); var sortedlist = new SortedList(); diff --git a/net452/SiteServer.CMS/Core/TemplateTypeUtils.cs b/net452/SiteServer.CMS/Core/TemplateTypeUtils.cs new file mode 100644 index 000000000..2e2d5d547 --- /dev/null +++ b/net452/SiteServer.CMS/Core/TemplateTypeUtils.cs @@ -0,0 +1,68 @@ +using System; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Core +{ + public static class TemplateTypeUtils + { + public static TemplateType GetEnumType(string typeStr) + { + var retVal = TemplateType.FileTemplate; + + if (Equals(TemplateType.ChannelTemplate, typeStr)) + { + retVal = TemplateType.ChannelTemplate; + } + else if (Equals(TemplateType.IndexPageTemplate, typeStr)) + { + retVal = TemplateType.IndexPageTemplate; + } + else if (Equals(TemplateType.ContentTemplate, typeStr)) + { + retVal = TemplateType.ContentTemplate; + } + else if (Equals(TemplateType.FileTemplate, typeStr)) + { + retVal = TemplateType.FileTemplate; + } + return retVal; + } + + private static bool Equals(TemplateType type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(type.Value.ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, TemplateType type) + { + return Equals(type, typeStr); + } + + public static string GetText(TemplateType templateType) + { + if (templateType == TemplateType.IndexPageTemplate) + { + return "首页模板"; + } + if (templateType == TemplateType.ChannelTemplate) + { + return "栏目模板"; + } + if (templateType == TemplateType.ContentTemplate) + { + return "内容模板"; + } + if (templateType == TemplateType.FileTemplate) + { + return "单页模板"; + } + + throw new Exception(); + } + } +} diff --git a/SiteServer.CMS/Core/UEditorUploader.cs b/net452/SiteServer.CMS/Core/UEditorUploader.cs similarity index 99% rename from SiteServer.CMS/Core/UEditorUploader.cs rename to net452/SiteServer.CMS/Core/UEditorUploader.cs index 21d8c1208..edf63b6e8 100644 --- a/SiteServer.CMS/Core/UEditorUploader.cs +++ b/net452/SiteServer.CMS/Core/UEditorUploader.cs @@ -2,7 +2,7 @@ using System.Web; using System.Collections; using System.IO; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Models; using SiteServer.Utils; using SiteServer.Utils.Enumerations; diff --git a/net452/SiteServer.CMS/Core/UEditorUtils.cs b/net452/SiteServer.CMS/Core/UEditorUtils.cs new file mode 100644 index 000000000..5cef0731b --- /dev/null +++ b/net452/SiteServer.CMS/Core/UEditorUtils.cs @@ -0,0 +1,115 @@ +using System.Collections.Generic; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.StlParser.StlElement; +using SiteServer.Utils; + +namespace SiteServer.CMS.Core +{ + public static class UEditorUtils + { + public const string ConfigValues = "{allowDivTransToP: false, maximumWords:99999999}"; + + public static string GetInsertHtmlScript(string attributeName, string html) + { + html = html.Replace("\"", "'"); + string script = $@"UE.getEditor(""{attributeName}"", {ConfigValues}).execCommand(""insertHTML"",""{html}"");"; + if (!string.IsNullOrEmpty(html)) + { + html = html.Replace(@"""", @"\"""); + script = $@"UE.getEditor(""{attributeName}"", {ConfigValues}).execCommand(""insertHTML"",""{html}"");"; + } + return script; + } + + public static string GetEditorInstanceScript() + { + return "UE"; + } + + public static string GetInsertVideoScript(string attributeName, string playUrl, string imageUrl, SiteInfo siteInfo) + { + if (string.IsNullOrEmpty(playUrl)) return string.Empty; + + var dict = new Dictionary + { + {StlPlayer.PlayUrl, playUrl}, + {StlPlayer.IsAutoPlay, siteInfo.ConfigUEditorVideoIsAutoPlay.ToString()}, + {StlPlayer.PlayBy, siteInfo.ConfigUEditorVideoPlayBy}, + {"style", "width: 333px; height: 333px;" } + }; + if (siteInfo.ConfigUEditorVideoIsImageUrl && !string.IsNullOrEmpty(imageUrl)) + { + dict.Add(StlPlayer.ImageUrl, imageUrl); + } + if (siteInfo.ConfigUEditorVideoIsWidth) + { + dict.Add(StlPlayer.Width, siteInfo.ConfigUEditorVideoWidth.ToString()); + } + if (siteInfo.ConfigUEditorVideoIsHeight) + { + dict.Add(StlPlayer.Height, siteInfo.ConfigUEditorVideoHeight.ToString()); + } + + return GetInsertHtmlScript(attributeName, + $@""); + } + + public static string GetInsertAudioScript(string attributeName, string playUrl, SiteInfo siteInfo) + { + if (string.IsNullOrEmpty(playUrl)) return string.Empty; + + var dict = new Dictionary + { + {StlPlayer.PlayUrl, playUrl}, + {StlPlayer.IsAutoPlay, siteInfo.ConfigUEditorAudioIsAutoPlay.ToString()}, + {"style", "width: 400px; height: 40px;" } + }; + + return GetInsertHtmlScript(attributeName, + $@""); + } + + public static string GetPureTextScript(string attributeName) + { + string script = $@"UE.getEditor(""{attributeName}"", {ConfigValues}).getContentTxt();"; + return script; + } + + public static string GetContentScript(string attributeName) + { + string script = $@"UE.getEditor(""{attributeName}"", {ConfigValues}).getContent();"; + return script; + } + + public static string GetSetContentScript(string attributeName, string contentWithoutQuote) + { + string script = $@"UE.getEditor(""{attributeName}"", {ConfigValues}).setContent({contentWithoutQuote});"; + return script; + } + + public static string TranslateToStlElement(string html) + { + var retval = html; + if (!string.IsNullOrEmpty(retval)) + { + retval = retval.Replace(@" 0) { foreach (var line in tagList) @@ -219,12 +220,12 @@ public static string[] DoSplit(string content, int siteId) public static string GetKeywords(string content, int siteId, int totalNum) { var value = ""; - var _key = DoSplit(content, siteId); + var split = DoSplit(content, siteId); var currentNum = 1; - for (var i = 1; i < _key.Length; i++) + for (var i = 1; i < split.Length; i++) { if (totalNum > 0 && currentNum > totalNum) break; - var key = _key[i].Trim(); + var key = split[i].Trim(); if (key.Length == 1) continue; if (i == 1) value = key; diff --git a/net452/SiteServer.CMS/Database/Attributes/ChannelAttribute.cs b/net452/SiteServer.CMS/Database/Attributes/ChannelAttribute.cs new file mode 100644 index 000000000..1bb01405e --- /dev/null +++ b/net452/SiteServer.CMS/Database/Attributes/ChannelAttribute.cs @@ -0,0 +1,108 @@ +using Datory; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.StlParser.Model; + +namespace SiteServer.CMS.Database.Attributes +{ + public static class ChannelAttribute + { + [StlAttribute(Title = "栏目Id")] + public const string Id = nameof(Entity.Id); + + [StlAttribute(Title = "站点Id")] + public const string SiteId = nameof(ChannelInfo.SiteId); + + [StlAttribute(Title = "内容模型插件Id")] + public const string ContentModelPluginId = nameof(ChannelInfo.ContentModelPluginId); + + [StlAttribute(Title = "内容关联插件Id列表")] + public const string ContentRelatedPluginIds = nameof(ChannelInfo.ContentRelatedPluginIds); + + [StlAttribute(Title = "父栏目Id")] + public const string ParentId = nameof(ChannelInfo.ParentId); + + [StlAttribute(Title = "上级栏目路径")] + public const string ParentsPath = nameof(ChannelInfo.ParentsPath); + + [StlAttribute(Title = "上级栏目数量")] + public const string ParentsCount = nameof(ChannelInfo.ParentsCount); + + [StlAttribute(Title = "下级栏目数量")] + public const string ChildrenCount = nameof(ChannelInfo.ChildrenCount); + + [StlAttribute(Title = "是否最后一级栏目")] + public const string LastNode = nameof(ChannelInfo.LastNode); + + [StlAttribute(Title = "栏目索引")] + public const string IndexName = nameof(ChannelInfo.IndexName); + + [StlAttribute(Title = "栏目组")] + public const string GroupNameCollection = nameof(ChannelInfo.GroupNameCollection); + + [StlAttribute(Title = "栏目排序")] + public const string Taxis = nameof(ChannelInfo.Taxis); + + [StlAttribute(Title = "栏目添加时间")] + public const string AddDate = nameof(ChannelInfo.AddDate); + + [StlAttribute(Title = "栏目图片")] + public const string ImageUrl = nameof(ChannelInfo.ImageUrl); + + [StlAttribute(Title = "栏目正文")] + public const string Content = nameof(ChannelInfo.Content); + + [StlAttribute(Title = "页面路径")] + public const string FilePath = nameof(ChannelInfo.FilePath); + + [StlAttribute(Title = "下级栏目页面命名规则")] + public const string ChannelFilePathRule = nameof(ChannelInfo.ChannelFilePathRule); + + [StlAttribute(Title = "下级内容页面命名规则")] + public const string ContentFilePathRule = nameof(ChannelInfo.ContentFilePathRule); + + [StlAttribute(Title = "外部链接")] + public const string LinkUrl = nameof(ChannelInfo.LinkUrl); + + [StlAttribute(Title = "链接类型")] + public const string LinkType = nameof(ChannelInfo.LinkType); + + [StlAttribute(Title = "栏目模板Id")] + public const string ChannelTemplateId = nameof(ChannelInfo.ChannelTemplateId); + + [StlAttribute(Title = "内容模板Id")] + public const string ContentTemplateId = nameof(ChannelInfo.ContentTemplateId); + + [StlAttribute(Title = "关键字列表")] + public const string Keywords = nameof(ChannelInfo.Keywords); + + [StlAttribute(Title = "页面描述")] + public const string Description = nameof(ChannelInfo.Description); + + [StlAttribute(Title = "栏目扩展值")] + public const string ExtendValues = nameof(ExtendValues); + + [StlAttribute(Title = "栏目名称")] + public const string Title = nameof(Title); + + [StlAttribute(Title = "栏目名称")] + public const string ChannelName = nameof(ChannelInfo.ChannelName); + + [StlAttribute(Title = "栏目索引")] + public const string ChannelIndex = nameof(ChannelIndex); + + [StlAttribute(Title = "栏目正文(翻页)")] + public const string PageContent = nameof(PageContent); + + [StlAttribute(Title = "顺序")] + public const string ItemIndex = nameof(ItemIndex); + + [StlAttribute(Title = "下级栏目数")] + public const string CountOfChannels = nameof(CountOfChannels); + + [StlAttribute(Title = "包含内容数")] + public const string CountOfContents = nameof(CountOfContents); + + [StlAttribute(Title = "包含图片内容数")] + public const string CountOfImageContents = nameof(CountOfImageContents); + } +} diff --git a/net452/SiteServer.CMS/Database/Attributes/ContentAttribute.cs b/net452/SiteServer.CMS/Database/Attributes/ContentAttribute.cs new file mode 100644 index 000000000..a48b78d17 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Attributes/ContentAttribute.cs @@ -0,0 +1,157 @@ +using System; +using System.Collections.Generic; +using Datory; + +namespace SiteServer.CMS.Database.Attributes +{ + public static class ContentAttribute + { + public const string Id = nameof(Entity.Id); + public const string Guid = nameof(Entity.Guid); + public const string LastModifiedDate = nameof(Entity.LastModifiedDate); + public const string ChannelId = nameof(ChannelId); + public const string SiteId = nameof(SiteId); + public const string AddUserName = nameof(AddUserName); + public const string LastEditUserName = nameof(LastEditUserName); + public const string LastEditDate = nameof(LastEditDate); + public const string AdminId = nameof(AdminId); + public const string UserId = nameof(UserId); + public const string Taxis = nameof(Taxis); + public const string GroupNameCollection = nameof(GroupNameCollection); + public const string Tags = nameof(Tags); + public const string SourceId = nameof(SourceId); + public const string ReferenceId = nameof(ReferenceId); + public const string IsChecked = nameof(IsChecked); + public const string CheckedLevel = nameof(CheckedLevel); + public const string Hits = nameof(Hits); + public const string HitsByDay = nameof(HitsByDay); + public const string HitsByWeek = nameof(HitsByWeek); + public const string HitsByMonth = nameof(HitsByMonth); + public const string LastHitsDate = nameof(LastHitsDate); + public const string Downloads = nameof(Downloads); + public const string SettingsXml = nameof(SettingsXml); + public const string Title = nameof(Title); + public const string IsTop = nameof(IsTop); + public const string IsRecommend = nameof(IsRecommend); + public const string IsHot = nameof(IsHot); + public const string IsColor = nameof(IsColor); + public const string LinkUrl = nameof(LinkUrl); + public const string AddDate = nameof(AddDate); + public const string Content = nameof(Content); + + public const string SubTitle = nameof(SubTitle); + public const string ImageUrl = nameof(ImageUrl); + public const string VideoUrl = nameof(VideoUrl); + public const string FileUrl = nameof(FileUrl); + public const string Author = nameof(Author); + public const string Source = nameof(Source); + public const string Summary = nameof(Summary); + + public static string GetFormatStringAttributeName(string attributeName) + { + return attributeName + "FormatString"; + } + + public static string GetExtendAttributeName(string attributeName) + { + return attributeName + "_Extend"; + } + + // 计算字段 + public const string Sequence = nameof(Sequence); //序号 + public const string PageContent = nameof(PageContent); + public const string NavigationUrl = nameof(NavigationUrl); + public const string CheckState = nameof(CheckState); + + // 附加字段 + public const string CheckUserName = nameof(CheckUserName); //审核者 + public const string CheckDate = nameof(CheckDate); //审核时间 + public const string CheckReasons = nameof(CheckReasons); //审核原因 + public const string TranslateContentType = nameof(TranslateContentType); //转移内容类型 + + public static readonly Lazy> AllAttributes = new Lazy>(() => new List + { + Id, + ChannelId, + SiteId, + AddUserName, + LastEditUserName, + LastEditDate, + AdminId, + UserId, + Taxis, + GroupNameCollection, + Tags, + SourceId, + ReferenceId, + IsChecked, + CheckedLevel, + Hits, + HitsByDay, + HitsByWeek, + HitsByMonth, + LastHitsDate, + Downloads, + SettingsXml, + Title, + IsTop, + IsRecommend, + IsHot, + IsColor, + LinkUrl, + AddDate + }); + + public static readonly Lazy> MetadataAttributes = new Lazy>(() => new List + { + Id, + ChannelId, + SiteId, + AddUserName, + LastEditUserName, + LastEditDate, + AdminId, + UserId, + Taxis, + GroupNameCollection, + Tags, + SourceId, + ReferenceId, + IsChecked, + CheckedLevel, + Hits, + HitsByDay, + HitsByWeek, + HitsByMonth, + LastHitsDate, + Downloads, + SettingsXml, + IsTop, + IsRecommend, + IsHot, + IsColor, + AddDate, + LinkUrl + }); + + public static readonly Lazy> CalculateAttributes = new Lazy>(() => new List + { + Sequence, + AdminId, + UserId, + SourceId, + AddUserName, + LastEditUserName + }); + + public static readonly Lazy> DropAttributes = new Lazy>(() => new List + { + "WritingUserName", + "ConsumePoint", + "Comments", + "Reply", + "CheckTaskDate", + "UnCheckTaskDate" + }); + } +} diff --git a/net452/SiteServer.CMS/Database/Attributes/SiteAttribute.cs b/net452/SiteServer.CMS/Database/Attributes/SiteAttribute.cs new file mode 100644 index 000000000..639b84a5c --- /dev/null +++ b/net452/SiteServer.CMS/Database/Attributes/SiteAttribute.cs @@ -0,0 +1,16 @@ +using SiteServer.Plugin; + +namespace SiteServer.CMS.Database.Attributes +{ + public static class SiteAttribute + { + public const string Id = nameof(ISiteInfo.Id); + public const string SiteName = nameof(ISiteInfo.SiteName); + public const string SiteDir = nameof(ISiteInfo.SiteDir); + public const string TableName = nameof(ISiteInfo.TableName); + public const string Root = nameof(ISiteInfo.Root); + public const string ParentId = nameof(ISiteInfo.ParentId); + public const string Taxis = nameof(ISiteInfo.Taxis); + public const string SettingsXml = nameof(SettingsXml); + } +} diff --git a/net452/SiteServer.CMS/Database/Attributes/UserAttribute.cs b/net452/SiteServer.CMS/Database/Attributes/UserAttribute.cs new file mode 100644 index 000000000..00a544def --- /dev/null +++ b/net452/SiteServer.CMS/Database/Attributes/UserAttribute.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.CMS.Database.Attributes +{ + public static class UserAttribute + { + public const string Id = nameof(UserInfo.Id); + public const string Guid = nameof(UserInfo.Guid); + public const string LastModifiedDate = nameof(UserInfo.LastModifiedDate); + public const string UserName = nameof(UserInfo.UserName); + public const string Password = nameof(UserInfo.Password); + public const string PasswordFormat = nameof(UserInfo.PasswordFormat); + public const string PasswordSalt = nameof(UserInfo.PasswordSalt); + public const string CreateDate = nameof(UserInfo.CreateDate); + public const string LastResetPasswordDate = nameof(UserInfo.LastResetPasswordDate); + public const string LastActivityDate = nameof(UserInfo.LastActivityDate); + public const string CountOfLogin = nameof(UserInfo.CountOfLogin); + public const string CountOfFailedLogin = nameof(UserInfo.CountOfFailedLogin); + public const string GroupId = nameof(UserInfo.GroupId); + public const string IsChecked = nameof(IsChecked); + public const string IsLockedOut = nameof(IsLockedOut); + public const string AvatarUrl = nameof(UserInfo.AvatarUrl); + public const string DisplayName = nameof(UserInfo.DisplayName); + public const string Mobile = nameof(UserInfo.Mobile); + public const string Email = nameof(UserInfo.Email); + public const string Gender = nameof(UserInfo.Gender); + public const string Birthday = nameof(UserInfo.Birthday); + public const string WeiXin = nameof(UserInfo.WeiXin); + public const string Qq = nameof(UserInfo.Qq); + public const string WeiBo = nameof(UserInfo.WeiBo); + public const string Bio = nameof(UserInfo.Bio); + public const string SettingsXml = nameof(SettingsXml); + + public static readonly Lazy> AllAttributes = new Lazy>(() => new List + { + Id, + Guid, + LastModifiedDate, + UserName, + Password, + PasswordFormat, + PasswordSalt, + CreateDate, + LastResetPasswordDate, + LastActivityDate, + CountOfLogin, + CountOfFailedLogin, + GroupId, + IsChecked, + IsLockedOut, + AvatarUrl, + DisplayName, + Mobile, + Email, + Gender, + Birthday, + WeiXin, + Qq, + WeiBo, + Bio, + SettingsXml + }); + + public static readonly Lazy> TableStyleAttributes = new Lazy>(() => new List + { + DisplayName, + Mobile, + Email, + Gender, + Birthday, + WeiXin, + Qq, + WeiBo, + Bio + }); + + public static readonly Lazy> ExcludedAttributes = new Lazy>(() => new List + { + Password, + PasswordFormat, + PasswordSalt, + SettingsXml + }); + } +} diff --git a/net452/SiteServer.CMS/Database/AttributesImpl.cs b/net452/SiteServer.CMS/Database/AttributesImpl.cs new file mode 100644 index 000000000..682215327 --- /dev/null +++ b/net452/SiteServer.CMS/Database/AttributesImpl.cs @@ -0,0 +1,322 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Data; +using System.Linq; +using SiteServer.CMS.Database.Core; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Plugin.Impl +{ + [Serializable] + public class AttributesImpl : IAttributes + { + private const string SettingsXml = nameof(SettingsXml); + private const string ExtendedValues = nameof(ExtendedValues); + + private readonly Dictionary _dataDict = new Dictionary(StringComparer.OrdinalIgnoreCase); + + public AttributesImpl() + { + } + + public AttributesImpl(IDataReader reader) + { + Load(reader); + } + + public AttributesImpl(AttributesImpl attributes) + { + Load(attributes); + } + + public void Load(AttributesImpl attributes) + { + if (attributes == null) return; + foreach (var entry in attributes._dataDict) + { + _dataDict[entry.Key] = entry.Value; + } + } + + public void Load(IDataReader reader) + { + if (reader == null) return; + + for (var i = 0; i < reader.FieldCount; i++) + { + var name = reader.GetName(i); + var value = reader.GetValue(i); + + if (value is string && WebConfigUtils.DatabaseType == DatabaseType.Oracle && (string)value == SqlUtils.OracleEmptyValue) + { + value = string.Empty; + } + Set(name, value); + } + } + + public AttributesImpl(IDataRecord record) + { + Load(record); + } + + public void Load(IDataRecord record) + { + if (record == null) return; + + for (var i = 0; i < record.FieldCount; i++) + { + var name = record.GetName(i); + var value = record.GetValue(i); + + if (value is string && WebConfigUtils.DatabaseType == DatabaseType.Oracle && (string)value == SqlUtils.OracleEmptyValue) + { + value = string.Empty; + } + Set(name, value); + } + } + + public AttributesImpl(DataRowView view) + { + Load(view); + } + + public void Load(DataRowView rowView) + { + if (rowView == null) return; + + Load(rowView.Row); + } + + public AttributesImpl(DataRow row) + { + Load(row); + } + + public void Load(DataRow row) + { + if (row == null) return; + + var dict = row.Table.Columns + .Cast() + .ToDictionary(c => c.ColumnName, c => row[c]); + + Load(dict); + } + + public AttributesImpl(NameValueCollection attributes) + { + Load(attributes); + } + + public void Load(NameValueCollection attributes) + { + if (attributes == null) return; + + foreach (string name in attributes) + { + var value = attributes[name]; + Set(name, value); + } + } + + public AttributesImpl(Dictionary dict) + { + Load(dict); + } + + public void Load(Dictionary dict) + { + if (dict == null) return; + + foreach (var key in dict.Keys) + { + Set(key, dict[key]); + } + } + + public AttributesImpl(string json) + { + Load(json); + } + + public void Load(string json) + { + if (string.IsNullOrEmpty(json)) return; + + if (json.StartsWith("{") && json.EndsWith("}")) + { + var dict = TranslateUtils.JsonDeserialize>(json); + foreach (var key in dict.Keys) + { + _dataDict[key] = dict[key]; + } + } + else + { + json = json.Replace("/u0026", "&"); + + var attributes = new NameValueCollection(); + + var pairs = json.Split('&'); + foreach (var pair in pairs) + { + if (pair.IndexOf("=", StringComparison.Ordinal) == -1) continue; + var name = pair.Split('=')[0]; + if (string.IsNullOrEmpty(name)) continue; + + name = name.Replace("_equals_", "=").Replace("_and_", "&").Replace("_question_", "?").Replace("_quote_", "'").Replace("_add_", "+").Replace("_return_", "\r").Replace("_newline_", "\n"); + var value = pair.Split('=')[1]; + if (!string.IsNullOrEmpty(value)) + { + value = value.Replace("_equals_", "=").Replace("_and_", "&").Replace("_question_", "?").Replace("_quote_", "'").Replace("_add_", "+").Replace("_return_", "\r").Replace("_newline_", "\n"); + } + attributes.Add(name.ToLower(), value); + } + + foreach (string key in attributes.Keys) + { + Set(key, attributes[key]); + } + } + } + + public AttributesImpl(object anonymous) + { + Load(anonymous); + } + + public void Load(object anonymous) + { + if (anonymous == null) return; + + foreach (var p in anonymous.GetType().GetProperties()) + { + Set(p.Name.ToCamelCase(), p.GetValue(anonymous)); + } + } + + public object Get(string key) + { + if (string.IsNullOrEmpty(key)) return null; + + return _dataDict.TryGetValue(key, out var value) ? value : null; + } + + public string GetString(string key, string defaultValue = "") + { + var value = Get(key); + if (value == null) return defaultValue; + if (value is string) return (string)value; + return value.ToString(); + } + + public bool GetBool(string key, bool defaultValue = false) + { + var value = Get(key); + if (value == null) return defaultValue; + if (value is bool) return (bool)value; + return TranslateUtils.ToBool(value.ToString(), defaultValue); + } + + public int GetInt(string key, int defaultValue = 0) + { + var value = Get(key); + if (value == null) return defaultValue; + if (value is int) return (int)value; + return TranslateUtils.ToIntWithNegative(value.ToString(), defaultValue); + } + + public decimal GetDecimal(string key, decimal defaultValue = 0) + { + var value = Get(key); + if (value == null) return defaultValue; + if (value is decimal) return (decimal)value; + return TranslateUtils.ToDecimalWithNegative(value.ToString(), defaultValue); + } + + public DateTime GetDateTime(string key, DateTime defaultValue) + { + var value = Get(key); + if (value == null) return defaultValue; + if (value is DateTime) return (DateTime)value; + return TranslateUtils.ToDateTime(value.ToString(), defaultValue); + } + + public DateTime? GetDateTime(string key) + { + var value = Get(key); + if (value == null) return null; + if (value is DateTime) return (DateTime)value; + return TranslateUtils.ToDateTime(value.ToString()); + } + + public void Remove(string key) + { + if (string.IsNullOrEmpty(key)) return; + + _dataDict.Remove(key); + } + + public virtual void Set(string name, object value) + { + if (string.IsNullOrEmpty(name)) return; + + if (value == null) + { + _dataDict.Remove(name); + } + else + { + if (StringUtils.EqualsIgnoreCase(name, SettingsXml) || StringUtils.EqualsIgnoreCase(name, ExtendedValues)) + { + Load(value.ToString()); + } + else + { + _dataDict[name] = value; + } + } + } + + public bool ContainsKey(string key) + { + if (string.IsNullOrEmpty(key)) return false; + + return _dataDict.ContainsKey(key); + } + + public override string ToString() + { + return TranslateUtils.JsonSerialize(_dataDict); + } + + public string ToString(List excludeKeys) + { + if (excludeKeys == null || excludeKeys.Count == 0) return ToString(); + + var dict = new Dictionary(StringComparer.OrdinalIgnoreCase); + foreach (var key in _dataDict.Keys) + { + if (!StringUtils.ContainsIgnoreCase(excludeKeys, key)) + { + dict[key] = _dataDict[key]; + } + } + return TranslateUtils.JsonSerialize(dict); + } + + public virtual Dictionary ToDictionary() + { + var ret = new Dictionary(_dataDict.Count, _dataDict.Comparer); + foreach (KeyValuePair entry in _dataDict) + { + ret.Add(entry.Key, entry.Value); + } + return ret; + } + } +} diff --git a/net452/SiteServer.CMS/Database/Core/DatabaseApi.cs b/net452/SiteServer.CMS/Database/Core/DatabaseApi.cs new file mode 100644 index 000000000..bd69b3d8d --- /dev/null +++ b/net452/SiteServer.CMS/Database/Core/DatabaseApi.cs @@ -0,0 +1,1343 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlClient; +using System.Linq; +using System.Text; +using Dapper; +using Datory; +using MySql.Data.MySqlClient; +using Newtonsoft.Json.Linq; +using Npgsql; +using Oracle.ManagedDataAccess.Client; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using TableColumn = Datory.TableColumn; + +namespace SiteServer.CMS.Database.Core +{ + public class DatabaseApi + { + public int Execute(string sql, object param = null) + { + int affected; + using (var connection = DatoryUtils.GetConnection(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString)) + { + affected = connection.Execute(sql, param); + } + + return affected; + } + + private int GetIntResult(string connectionString, string sqlString) + { + if (string.IsNullOrEmpty(connectionString)) + { + connectionString = WebConfigUtils.ConnectionString; + } + + var count = 0; + + using (var conn = DatoryUtils.GetConnection(WebConfigUtils.DatabaseType, connectionString)) + { + conn.Open(); + using (var rdr = ExecuteReader(conn, sqlString)) + { + if (rdr.Read()) + { + count = GetInt(rdr, 0); + } + rdr.Close(); + } + } + return count; + } + + public int GetIntResult(string sqlString) + { + var count = 0; + + using (var conn = DatoryUtils.GetConnection(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString)) + { + conn.Open(); + using (var rdr = ExecuteReader(conn, sqlString)) + { + if (rdr.Read()) + { + count = GetInt(rdr, 0); + } + rdr.Close(); + } + } + return count; + } + + public string GetString(string connectionString, string sqlString) + { + if (string.IsNullOrEmpty(connectionString)) + { + connectionString = WebConfigUtils.ConnectionString; + } + + var retVal = string.Empty; + + using (var conn = DatoryUtils.GetConnection(WebConfigUtils.DatabaseType, connectionString)) + { + conn.Open(); + using (var rdr = ExecuteReader(conn, sqlString)) + { + if (rdr.Read()) + { + retVal = GetString(rdr, 0); + } + rdr.Close(); + } + } + return retVal; + } + + public List GetStringList(string sqlString) + { + var list = new List(); + + using (var conn = DatoryUtils.GetConnection(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString)) + { + conn.Open(); + using (var rdr = ExecuteReader(conn, sqlString)) + { + while (rdr.Read()) + { + list.Add(GetString(rdr, 0)); + } + rdr.Close(); + } + } + return list; + } + + public IDataReader GetDataReader(string connectionString, string sqlString) + { + if (string.IsNullOrEmpty(connectionString)) + { + connectionString = WebConfigUtils.ConnectionString; + } + + return string.IsNullOrEmpty(sqlString) ? null : ExecuteReader(connectionString, sqlString); + } + + public IDataReader GetDataSource(string sqlString) + { + if (string.IsNullOrEmpty(sqlString)) return null; + var enumerable = ExecuteReader(WebConfigUtils.ConnectionString, sqlString); + return enumerable; + } + + public DataTable GetDataTable(string connectionString, string sqlString) + { + if (string.IsNullOrEmpty(connectionString)) + { + connectionString = WebConfigUtils.ConnectionString; + } + + if (string.IsNullOrEmpty(sqlString)) return null; + var dataSet = ExecuteDataset(connectionString, sqlString); + + if (dataSet == null || dataSet.Tables.Count == 0) return null; + + return dataSet.Tables[0]; + } + + public DataSet GetDataSet(string connectionString, string sqlString) + { + if (string.IsNullOrEmpty(connectionString)) + { + connectionString = WebConfigUtils.ConnectionString; + } + + if (string.IsNullOrEmpty(sqlString)) return null; + return ExecuteDataset(connectionString, sqlString); + } + + public int GetPageTotalCount(string sqlString) + { + var temp = sqlString.ToLower(); + var pos = temp.LastIndexOf("order by", StringComparison.Ordinal); + if (pos > -1) + sqlString = sqlString.Substring(0, pos); + + // Add new ORDER BY info if SortKeyField is specified + //if (!string.IsNullOrEmpty(sortField) && addCustomSortInfo) + // SelectCommand += " ORDER BY " + SortField; + + var cmdText = WebConfigUtils.DatabaseType == DatabaseType.Oracle + ? $"SELECT COUNT(*) FROM ({sqlString})" + : $"SELECT COUNT(*) FROM ({sqlString}) AS T0"; + return GetIntResult(cmdText); + } + + public string GetStlPageSqlString(string sqlString, string orderString, int totalCount, int itemsPerPage, int currentPageIndex) + { + var retVal = string.Empty; + + var temp = sqlString.ToLower(); + var pos = temp.LastIndexOf("order by", StringComparison.Ordinal); + if (pos > -1) + sqlString = sqlString.Substring(0, pos); + + var recordsInLastPage = itemsPerPage; + + // Calculate the correspondent number of pages + var lastPage = totalCount / itemsPerPage; + var remainder = totalCount % itemsPerPage; + if (remainder > 0) + lastPage++; + var pageCount = lastPage; + + if (remainder > 0) + recordsInLastPage = remainder; + + var toRetrieve = itemsPerPage; + if (currentPageIndex == pageCount - 1) + toRetrieve = recordsInLastPage; + + orderString = orderString.ToUpper(); + var orderStringReverse = orderString.Replace(" DESC", " DESC2"); + orderStringReverse = orderStringReverse.Replace(" ASC", " DESC"); + orderStringReverse = orderStringReverse.Replace(" DESC2", " ASC"); + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + retVal = $@" +SELECT * FROM ( + SELECT * FROM ( + SELECT * FROM ({sqlString}) AS t0 {orderString} LIMIT {itemsPerPage * (currentPageIndex + 1)} + ) AS t1 {orderStringReverse} LIMIT {toRetrieve} +) AS t2 {orderString}"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + retVal = $@" +SELECT * FROM ( + SELECT TOP {toRetrieve} * FROM ( + SELECT TOP {itemsPerPage * (currentPageIndex + 1)} * FROM ({sqlString}) AS t0 {orderString} + ) AS t1 {orderStringReverse} +) AS t2 {orderString}"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + retVal = $@" +SELECT * FROM ( + SELECT * FROM ( + SELECT * FROM ({sqlString}) AS t0 {orderString} LIMIT {itemsPerPage * (currentPageIndex + 1)} + ) AS t1 {orderStringReverse} LIMIT {toRetrieve} +) AS t2 {orderString}"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + retVal = $@" +SELECT * FROM ( + SELECT * FROM ( + SELECT * FROM ({sqlString}) WHERE ROWNUM <= {itemsPerPage * (currentPageIndex + 1)} {orderString} + ) WHERE ROWNUM <= {toRetrieve} {orderStringReverse} +) {orderString}"; + } + + return retVal; + } + + public bool ConnectToServer(DatabaseType databaseType, string connectionStringWithoutDatabaseName, out List databaseNameList, out string errorMessage) + { + errorMessage = string.Empty; + databaseNameList = new List(); + try + { + databaseNameList = GetDatabaseNameList(databaseType, connectionStringWithoutDatabaseName); + return true; + } + catch (Exception e) + { + errorMessage = e.Message; + } + + return false; + } + + private List GetDatabaseNameList(DatabaseType databaseType, string connectionStringWithoutDatabaseName) + { + if (string.IsNullOrEmpty(connectionStringWithoutDatabaseName)) + { + connectionStringWithoutDatabaseName = WebConfigUtils.ConnectionString; + } + + var list = new List(); + + if (databaseType == DatabaseType.MySql) + { + var connection = new MySqlConnection(connectionStringWithoutDatabaseName); + var command = new MySqlCommand("show databases", connection); + + connection.Open(); + + var rdr = command.ExecuteReader(); + + while (rdr.Read()) + { + var dbName = rdr.GetString(0); + if (dbName == null) continue; + if (dbName != "information_schema" && + dbName != "mysql" && + dbName != "performance_schema" && + dbName != "sakila" && + dbName != "sys" && + dbName != "world") + { + list.Add(dbName); + } + } + + connection.Close(); + } + else if (databaseType == DatabaseType.SqlServer) + { + var connection = new SqlConnection(connectionStringWithoutDatabaseName); + var command = new SqlCommand("select name from master..sysdatabases order by name asc", connection); + + connection.Open(); + + connection.ChangeDatabase("master"); + + var dr = command.ExecuteReader(); + + while (dr.Read()) + { + var dbName = dr["name"] as string; + if (dbName == null) continue; + if (dbName != "master" && + dbName != "msdb" && + dbName != "tempdb" && + dbName != "model") + { + list.Add(dbName); + } + } + + connection.Close(); + } + else if (databaseType == DatabaseType.PostgreSql) + { + var connection = new NpgsqlConnection(connectionStringWithoutDatabaseName); + var command = + new NpgsqlCommand( + "select datname from pg_database where datistemplate = false order by datname asc", + connection); + + connection.Open(); + + var dr = command.ExecuteReader(); + + while (dr.Read()) + { + var dbName = dr["datname"] as string; + if (dbName == null) continue; + + list.Add(dbName); + } + + connection.Close(); + } + else if (databaseType == DatabaseType.Oracle) + { + var connection = new OracleConnection(connectionStringWithoutDatabaseName); + connection.Open(); + connection.Close(); + } + + return list; + } + + public bool IsConnectionStringWork(DatabaseType databaseType, string connectionString) + { + var retVal = false; + try + { + var connection = DatoryUtils.GetConnection(databaseType, connectionString); + connection.Open(); + if (connection.State == ConnectionState.Open) + { + retVal = true; + connection.Close(); + } + } + catch + { + // ignored + } + + return retVal; + } + + private string GetOracleSequence(string tableName, string idColumnName) + { + var cacheKey = $"SiteServer.CMS.Provider.{nameof(DatabaseApi)}.{nameof(GetOracleSequence)}.{tableName}.{idColumnName}"; + var sequence = CacheUtils.Get(cacheKey); + if (string.IsNullOrEmpty(sequence)) + { + using (var conn = new OracleConnection(WebConfigUtils.ConnectionString)) + { + conn.Open(); + var cmd = new OracleCommand + { + CommandType = CommandType.Text, + CommandText = $"SELECT DATA_DEFAULT FROM all_tab_cols WHERE OWNER = '{WebConfigUtils.ConnectionStringUserId.ToUpper()}' and table_name = '{tableName.ToUpper()}' AND column_name = '{idColumnName.ToUpper()}'", + Connection = conn, + InitialLONGFetchSize = -1 + }; + + using (var rdr = cmd.ExecuteReader()) + { + if (rdr.Read()) + { + var dataDefault = rdr.GetValue(0).ToString(); + + if (dataDefault.Contains(".nextval")) + { + sequence = dataDefault.Replace(".nextval", string.Empty); + } + } + rdr.Close(); + } + } + + CacheUtils.Insert(cacheKey, sequence); + } + + return sequence; + } + + public string GetSelectSqlString(string tableName, string whereString) + { + return GetSelectSqlString(tableName, 0, new List { "*" }, whereString, null); + } + + public string GetSelectSqlString(string tableName, int totalNum, IList columns, string whereString, string orderByString) + { + return GetSelectSqlString(WebConfigUtils.ConnectionString, tableName, totalNum, columns, whereString, orderByString, string.Empty); + } + + public string GetSqlString(DatabaseType databaseType, string connectionString, string tableName, IList columnNames = null, string whereSqlString = null, string orderSqlString = null, int offset = 0, int limit = 0, bool distinct = false) + { + var select = distinct ? "SELECT DISTINCT" : "SELECT"; + var columns = columnNames != null && columnNames.Count > 0 ? string.Join(", ", columnNames) : "*"; + + var retVal = string.Empty; + + if (offset == 0 && limit == 0) + { + return $@"{select} {columns} FROM {tableName} {whereSqlString} {orderSqlString}"; + } + + if (databaseType == DatabaseType.MySql) + { + retVal = limit == 0 + ? $@"{select} {columns} FROM {tableName} {whereSqlString} {orderSqlString} OFFSET {offset}" + : $@"{select} {columns} FROM {tableName} {whereSqlString} {orderSqlString} LIMIT {limit} OFFSET {offset}"; + } + else if (databaseType == DatabaseType.SqlServer) + { + var useLegacyPagination = DatoryUtils.IsUseLegacyPagination(databaseType, connectionString); + + if (useLegacyPagination) + { + if (offset == 0) + { + retVal = $"{select} TOP {limit} {columns} FROM {tableName} {whereSqlString} {orderSqlString}"; + } + else + { + var rowWhere = limit == 0 + ? $@"WHERE [row_num] > {offset}" + : $@"WHERE [row_num] BETWEEN {offset + 1} AND {offset + limit}"; + + retVal = $@"SELECT * FROM ( + {select} {columns}, ROW_NUMBER() OVER ({orderSqlString}) AS [row_num] FROM [{tableName}] {whereSqlString} +) as T {rowWhere}"; + } + } + else + { + retVal = limit == 0 + ? $"{select} {columns} FROM {tableName} {whereSqlString} {orderSqlString} OFFSET {offset} ROWS" + : $"{select} {columns} FROM {tableName} {whereSqlString} {orderSqlString} OFFSET {offset} ROWS FETCH NEXT {limit} ROWS ONLY"; + } + } + else if (databaseType == DatabaseType.PostgreSql) + { + retVal = limit == 0 + ? $@"{select} {columns} FROM {tableName} {whereSqlString} {orderSqlString} OFFSET {offset}" + : $@"{select} {columns} FROM {tableName} {whereSqlString} {orderSqlString} LIMIT {limit} OFFSET {offset}"; + } + else if (databaseType == DatabaseType.Oracle) + { + retVal = limit == 0 + ? $"{select} {columns} FROM {tableName} {whereSqlString} {orderSqlString} OFFSET {offset} ROWS" + : $"{select} {columns} FROM {tableName} {whereSqlString} {orderSqlString} OFFSET {offset} ROWS FETCH NEXT {limit} ROWS ONLY"; + } + + return retVal; + } + + private string GetSelectSqlString(string connectionString, string tableName, int totalNum, IList columns, string whereString, string orderByString, string joinString) + { + if (!string.IsNullOrEmpty(whereString)) + { + whereString = StringUtils.ReplaceStartsWith(whereString.Trim(), "AND", string.Empty); + if (!StringUtils.StartsWithIgnoreCase(whereString, "WHERE ")) + { + whereString = "WHERE " + whereString; + } + } + + if (!string.IsNullOrEmpty(joinString)) + { + whereString = joinString + " " + whereString; + } + + return GetSqlString(WebConfigUtils.DatabaseType, connectionString, tableName, columns, whereString, orderByString, totalNum); + } + + private string GetSelectSqlStringByQueryString(string queryString, int totalNum, string orderByString) + { + if (totalNum == 0 && string.IsNullOrEmpty(orderByString)) + { + return queryString; + } + string sqlString; + if (totalNum > 0) + { + sqlString = SqlUtils.ToTopSqlString(queryString, orderByString, totalNum); + } + else + { + sqlString = string.IsNullOrEmpty(orderByString) ? queryString : $"SELECT * FROM ({queryString}) tmp {orderByString}"; + } + return sqlString; + } + + public string GetSelectSqlStringByQueryString(string connectionString, string queryString, int startNum, int totalNum, string orderByString) + { + if (string.IsNullOrEmpty(connectionString)) + { + connectionString = WebConfigUtils.ConnectionString; + } + + if (startNum == 1 && totalNum == 0 && string.IsNullOrEmpty(orderByString)) + { + return queryString; + } + //queryString = queryString.Trim().ToUpper(); + if (queryString.LastIndexOf(" ORDER ", StringComparison.Ordinal) != -1) + { + if (string.IsNullOrEmpty(orderByString)) + { + orderByString = queryString.Substring(queryString.LastIndexOf(" ORDER ", StringComparison.Ordinal) + 1); + } + queryString = queryString.Substring(0, queryString.LastIndexOf(" ORDER ", StringComparison.Ordinal)); + } + orderByString = ParseOrderByString(orderByString); + + if (startNum <= 1) + { + return GetSelectSqlStringByQueryString(queryString, totalNum, orderByString); + } + + string countSqlString = $"SELECT Count(*) FROM ({queryString}) tmp"; + var count = GetIntResult(connectionString, countSqlString); + if (totalNum == 0) + { + totalNum = count; + } + + if (startNum > count) return string.Empty; + + var topNum = startNum + totalNum - 1; + + if (count < topNum) + { + totalNum = count - startNum + 1; + if (totalNum < 1) + { + return GetSelectSqlStringByQueryString(queryString, totalNum, orderByString); + } + } + + var orderByStringOpposite = GetOrderByStringOpposite(orderByString); + + var retVal = string.Empty; + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + retVal = $@" +SELECT * FROM ( + SELECT * FROM ( + SELECT * FROM ({queryString}) tmp {orderByString} LIMIT {topNum} + ) AS tmp {orderByStringOpposite} LIMIT {totalNum} +) AS tmp {orderByString}"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + retVal = $@" +SELECT * +FROM (SELECT TOP {totalNum} * + FROM (SELECT TOP {topNum} * + FROM ({queryString}) tmp {orderByString}) tmp + {orderByStringOpposite}) tmp +{orderByString} +"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + retVal = $@" +SELECT * FROM ( + SELECT * FROM ( + SELECT * FROM ({queryString}) tmp {orderByString} LIMIT {topNum} + ) AS tmp {orderByStringOpposite} LIMIT {totalNum} +) AS tmp {orderByString}"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + retVal = $@" +SELECT * +FROM (SELECT TOP {totalNum} * + FROM (SELECT TOP {topNum} * + FROM ({queryString}) tmp {orderByString}) tmp + {orderByStringOpposite}) tmp +{orderByString} +"; + } + + return retVal; + } + + private static string ParseOrderByString(string orderByString) + { + if (string.IsNullOrEmpty(orderByString)) return orderByString; + + orderByString = orderByString.ToUpper().Trim(); + if (!orderByString.StartsWith("ORDER BY")) + { + orderByString = "ORDER BY " + orderByString; + } + if (!orderByString.EndsWith("DESC") && !orderByString.EndsWith("ASC")) + { + orderByString = orderByString + " ASC"; + } + return orderByString; + } + + private string GetOrderByStringOpposite(string orderByString) + { + var retVal = string.Empty; + if (!string.IsNullOrEmpty(orderByString)) + { + retVal = orderByString.Replace(" DESC", " DESC_OPPOSITE").Replace(" ASC", " DESC").Replace(" DESC_OPPOSITE", " ASC"); + } + return retVal; + } + + public int GetCount(string tableName) + { + return GetIntResult($"select count(*) from {tableName}"); + } + + public IEnumerable GetObjects(string tableName) + { + IEnumerable objects; + var sqlString = $"select * from {tableName}"; + + using (var connection = DatoryUtils.GetConnection(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString)) + { + connection.Open(); + + objects = connection.Query(sqlString, null, null, false).ToList(); + } + + return objects; + } + + public IEnumerable GetPageObjects(string tableName, string identityColumnName, int offset, int limit) + { + IEnumerable objects; + var sqlString = GetSqlString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, orderSqlString: $"ORDER BY {identityColumnName} ASC", offset: offset, limit: limit); + + using (var connection = DatoryUtils.GetConnection(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString)) + { + connection.Open(); + + objects = connection.Query(sqlString, null, null, false).ToList(); + } + + return objects; + } + + public void InsertMultiple(string tableName, IEnumerable items, List tableColumns) + { + var columnNames = new StringBuilder(); + foreach (var tableColumn in tableColumns) + { + columnNames.Append($"{tableColumn.AttributeName},"); + } + if (columnNames.Length > 0) columnNames.Length -= 1; + + var valuesList = new List(); + var parameterList = new List(); + var index = 0; + foreach (var item in items) + { + var dict = TranslateUtils.JsonGetDictionaryIgnoreCase(item); + + index++; + var values = new StringBuilder(); + foreach (var tableColumn in tableColumns) + { + if (string.IsNullOrEmpty(tableColumn?.AttributeName)) continue; + + dict.TryGetValue(tableColumn.AttributeName, out var value); + + if (tableColumn.DataType == DataType.Integer) + { + if (value == null) value = 0; + values.Append($"{Convert.ToInt32(value)},"); + } + else if (tableColumn.DataType == DataType.Decimal) + { + if (value == null) value = 0; + values.Append($"{Convert.ToDecimal(value)},"); + } + else if (tableColumn.DataType == DataType.Boolean) + { + var paramName = $"@{tableColumn.AttributeName}_{index}"; + if (value == null) value = false; + values.Append($"{paramName},"); + parameterList.Add(GetParameter(paramName, Convert.ToBoolean(value))); + } + else if (tableColumn.DataType == DataType.DateTime) + { + if (value == null) value = DateTime.Now; + values.Append($"{SqlUtils.GetComparableDateTime(Convert.ToDateTime(value))},"); + } + else + { + var paramName = $"@{tableColumn.AttributeName}_{index}"; + values.Append($"{paramName},"); + parameterList.Add(GetParameter(paramName, Convert.ToString(value))); + } + } + + if (values.Length > 0) + { + values.Length -= 1; + valuesList.Add(values.ToString()); + + if (parameterList.Count > 1000) + { + InsertRows(tableName, columnNames.ToString(), valuesList, parameterList); + valuesList.Clear(); + parameterList.Clear(); + } + } + } + + if (valuesList.Count > 0 && parameterList.Count > 0) + { + InsertRows(tableName, columnNames.ToString(), valuesList, parameterList); + } + } + + private void InsertRows(string tableName, string columnNames, List valuesList, List parameterList) + { + if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + var sqlStringBuilder = new StringBuilder($@"INSERT INTO {tableName} ({columnNames}) VALUES "); + foreach (var values in valuesList) + { + sqlStringBuilder.Append($"({values}), "); + } + sqlStringBuilder.Length -= 2; + + var sqlString = sqlStringBuilder.ToString(); + + var isIdentityColumn = !StringUtils.EqualsIgnoreCase(tableName, DataProvider.Site.TableName); + if (isIdentityColumn) + { + sqlString = $@" +SET IDENTITY_INSERT {tableName} ON +{sqlString} +SET IDENTITY_INSERT {tableName} OFF +"; + } + + ExecuteNonQuery(WebConfigUtils.ConnectionString, sqlString, parameterList.ToArray()); + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + var sqlStringBuilder = new StringBuilder("INSERT ALL"); + foreach (var values in valuesList) + { + sqlStringBuilder.Append($@" INTO {tableName} ({columnNames}) VALUES ({values})"); + } + + sqlStringBuilder.Append(" SELECT 1 FROM DUAL"); + + ExecuteNonQuery(WebConfigUtils.ConnectionString, sqlStringBuilder.ToString(), parameterList.ToArray()); + } + else + { + var sqlStringBuilder = new StringBuilder($@"INSERT INTO {tableName} ({columnNames}) VALUES "); + foreach (var values in valuesList) + { + sqlStringBuilder.Append($"({values}), "); + } + sqlStringBuilder.Length -= 2; + + ExecuteNonQuery(WebConfigUtils.ConnectionString, sqlStringBuilder.ToString(), parameterList.ToArray()); + } + } + + public int GetPageTotalCount(string tableName, string whereSqlString) + { + return GetIntResult($@"SELECT COUNT(*) FROM {tableName} {whereSqlString}"); + } + + public int GetPageTotalCount(string tableName, string whereSqlString, Dictionary parameters) + { + int totalCount; + + using (var connection = DatoryUtils.GetConnection(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString)) + { + totalCount = connection.QueryFirstOrDefault($@"SELECT COUNT(*) FROM {tableName} {whereSqlString}", parameters); + } + + return totalCount; + } + + public virtual string GetString(IDataReader rdr, int i) + { + if (i < 0 || i >= rdr.FieldCount) return string.Empty; + return rdr.IsDBNull(i) ? string.Empty : rdr.GetValue(i).ToString(); + } + + public int GetInt(IDataReader rdr, int i) + { + if (i < 0 || i >= rdr.FieldCount) return 0; + return rdr.IsDBNull(i) ? 0 : rdr.GetInt32(i); + } + + protected enum AdoConnectionOwnership + { + Internal, + External + } + + private IDbDataAdapter GetDataAdapter() + { + return new SqlDataAdapter(); + } + + private IDataParameter GetParameter() + { + return new SqlParameter(); + } + + private void ClearCommand(IDbCommand command) + { + var canClear = true; + + foreach (IDataParameter commandParameter in command.Parameters) + { + if (commandParameter.Direction != ParameterDirection.Input) + canClear = false; + + } + if (canClear) + { + command.Parameters.Clear(); + } + } + + private IDataParameter GetBlobParameter(IDataParameter p) + { + // do nothing special for BLOBs...as far as we know now. + return p; + } + + public IDataParameter GetParameter(string name, object value) + { + var parameter = GetParameter(); + parameter.ParameterName = name; + if (value is DateTime && (DateTime)value < DateUtils.SqlMinValue) + { + value = DateUtils.SqlMinValue; + } + parameter.Value = value; + + return parameter; + } + + private void AttachParameters(IDbCommand command, IDataParameter[] commandParameters) + { + if (command == null) throw new ArgumentNullException(nameof(command)); + if (commandParameters != null) + { + foreach (var p in commandParameters) + { + if (p != null) + { + // Check for derived output value with no value assigned + if ((p.Direction == ParameterDirection.InputOutput || + p.Direction == ParameterDirection.Input) && + p.Value == null) + { + p.Value = DBNull.Value; + } + command.Parameters.Add(p.DbType == DbType.Binary ? GetBlobParameter(p) : p); + } + } + } + } + + private void PrepareCommand(IDbCommand command, IDbConnection connection, IDbTransaction transaction, + string commandText, IDataParameter[] commandParameters, out bool mustCloseConnection) + { + if (command == null) throw new ArgumentNullException(nameof(command)); + if (string.IsNullOrEmpty(commandText)) throw new ArgumentNullException(nameof(commandText)); + if (WebConfigUtils.DatabaseType != DatabaseType.SqlServer) + { + commandText = commandText.Replace("[", string.Empty).Replace("]", string.Empty); + if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + commandText = commandText.Replace("@", ":"); + } + } + + // If the provided connection is not open, we will open it + if (connection.State != ConnectionState.Open) + { + mustCloseConnection = true; + connection.Open(); + } + else + { + mustCloseConnection = false; + } + + // Associate the connection with the command + command.Connection = connection; + + // Set the command text (stored procedure name or SQL statement) + command.CommandText = commandText; + + // If we were provided a transaction, assign it + if (transaction != null) + { + if (transaction.Connection == null) + throw new ArgumentException( + "The transaction was rolled back or commited, please provide an open transaction.", + nameof(transaction)); + command.Transaction = transaction; + } + + // Set the command type + command.CommandType = CommandType.Text; + + // Attach the command parameters if they are provided + if (commandParameters != null) + { + AttachParameters(command, commandParameters); + } + } + + private DataSet ExecuteDataset(IDbCommand command) + { + var mustCloseConnection = false; + + if (command.Connection.State != ConnectionState.Open) + { + command.Connection.Open(); + mustCloseConnection = true; + } + + // Create the DataAdapter & DataSet + IDbDataAdapter da = null; + try + { + da = GetDataAdapter(); + da.SelectCommand = command; + + var ds = new DataSet(); + + // Fill the DataSet using default values for DataTable names, etc + da.Fill(ds); + + // Detach the IDataParameters from the command object, so they can be used again + // Don't do this...screws up output params -- cjb + //command.Parameters.Clear(); + + // Return the DataSet + return ds; + } + finally + { + if (mustCloseConnection) + { + command.Connection.Close(); + } + if (da != null) + { + var id = da as IDisposable; + if (id != null) + id.Dispose(); + } + } + } + + public DataSet ExecuteDataset(string connectionString, string commandText) + { + // Pass through the call providing null for the set of IDataParameters + return ExecuteDataset(connectionString, commandText, null); + } + + private DataSet ExecuteDataset(string connectionString, string commandText, + params IDataParameter[] commandParameters) + { + if (string.IsNullOrEmpty(connectionString)) throw new ArgumentNullException(nameof(connectionString)); + + // Create & open an IDbConnection, and dispose of it after we are done + using (var connection = DatoryUtils.GetConnection(WebConfigUtils.DatabaseType, connectionString)) + { + connection.Open(); + + // Call the overload that takes a connection in place of the connection string + return ExecuteDataset(connection, commandText, commandParameters); + } + } + + private DataSet ExecuteDataset(IDbConnection connection, string commandText, + params IDataParameter[] commandParameters) + { + if (connection == null) throw new ArgumentNullException(nameof(connection)); + + // Create a command and prepare it for execution + var cmd = connection.CreateCommand(); + bool mustCloseConnection; + PrepareCommand(cmd, connection, null, commandText, commandParameters, out mustCloseConnection); + + var ds = ExecuteDataset(cmd); + + if (mustCloseConnection) + connection.Close(); + + // Return the DataSet + return ds; + } + + private void ExecuteNonQuery(IDbCommand command) + { + var mustCloseConnection = false; + + if (command.Connection.State != ConnectionState.Open) + { + command.Connection.Open(); + mustCloseConnection = true; + } + + if (command == null) throw new ArgumentNullException(nameof(command)); + + command.ExecuteNonQuery(); + + if (mustCloseConnection) + { + command.Connection.Close(); + } + } + + public void ExecuteNonQuery(string connectionString, string commandText, + params IDataParameter[] commandParameters) + { + if (string.IsNullOrEmpty(connectionString)) throw new ArgumentNullException(nameof(connectionString)); + + // Create & open an IDbConnection, and dispose of it after we are done + using (var connection = DatoryUtils.GetConnection(WebConfigUtils.DatabaseType, connectionString)) + { + connection.Open(); + + // Call the overload that takes a connection in place of the connection string + ExecuteNonQuery(connection, commandText, commandParameters); + } + } + + public int ExecuteNonQueryAndReturnId(string tableName, string idColumnName, string connectionString, + string commandText, + params IDataParameter[] commandParameters) + { + if (string.IsNullOrEmpty(connectionString)) throw new ArgumentNullException(nameof(connectionString)); + + int id; + + using (var conn = DatoryUtils.GetConnection(WebConfigUtils.DatabaseType, connectionString)) + { + conn.Open(); + using (var trans = conn.BeginTransaction()) + { + try + { + id = ExecuteNonQueryAndReturnId(tableName, idColumnName, trans, commandText, commandParameters); + + trans.Commit(); + } + catch + { + trans.Rollback(); + throw; + } + } + } + + return id; + } + + private int ExecuteNonQueryAndReturnId(string tableName, string idColumnName, IDbTransaction trans, + string commandText, params IDataParameter[] commandParameters) + { + if (string.IsNullOrEmpty(commandText)) return 0; + + var id = 0; + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + ExecuteNonQuery(trans, commandText, commandParameters); + + using (var rdr = ExecuteReader(trans, $"SELECT @@IDENTITY AS '{idColumnName}'")) + { + if (rdr.Read() && !rdr.IsDBNull(0)) + { + id = rdr.GetInt32(0); + } + rdr.Close(); + } + + if (id == 0) + { + trans.Rollback(); + } + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + ExecuteNonQuery(trans, commandText, commandParameters); + + using (var rdr = ExecuteReader(trans, $"SELECT @@IDENTITY AS '{idColumnName}'")) + { + if (rdr.Read() && !rdr.IsDBNull(0)) + { + id = Convert.ToInt32(rdr[0]); + } + rdr.Close(); + } + + if (id == 0) + { + trans.Rollback(); + } + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + commandText += " RETURNING " + idColumnName; + + using (var rdr = ExecuteReader(trans, commandText, commandParameters)) + { + if (rdr.Read() && !rdr.IsDBNull(0)) + { + id = rdr.GetInt32(0); + } + rdr.Close(); + } + + if (id == 0) + { + trans.Rollback(); + } + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + ExecuteNonQuery(trans, commandText, commandParameters); + + var sequence = GetOracleSequence(tableName, idColumnName); + + if (!string.IsNullOrEmpty(sequence)) + { + using (var rdr = ExecuteReader(trans, $"SELECT {sequence}.currval from dual")) + { + if (rdr.Read() && !rdr.IsDBNull(0)) + { + id = Convert.ToInt32(rdr[0]); + } + rdr.Close(); + } + } + + if (id == 0) + { + trans.Rollback(); + } + } + + return id; + } + + private void ExecuteNonQuery(IDbConnection connection, string commandText, + params IDataParameter[] commandParameters) + { + if (connection == null) throw new ArgumentNullException(nameof(connection)); + + // Create a command and prepare it for execution + var cmd = connection.CreateCommand(); + PrepareCommand(cmd, connection, null, commandText, commandParameters, out var mustCloseConnection); + + // Finally, execute the command + ExecuteNonQuery(cmd); + + if (mustCloseConnection) + connection.Close(); + } + + private void ExecuteNonQuery(IDbTransaction transaction, string commandText, + params IDataParameter[] commandParameters) + { + if (transaction == null) throw new ArgumentNullException(nameof(transaction)); + if (transaction != null && transaction.Connection == null) + throw new ArgumentException( + "The transaction was rolled back or commited, please provide an open transaction.", + nameof(transaction)); + + // Create a command and prepare it for execution + var cmd = transaction.Connection.CreateCommand(); + PrepareCommand(cmd, transaction.Connection, transaction, commandText, commandParameters, + out _); + + ExecuteNonQuery(cmd); + } + + protected IDataReader ExecuteReader(IDbCommand command, AdoConnectionOwnership connectionOwnership) + { + if (command.Connection.State != ConnectionState.Open) + { + command.Connection.Open(); + connectionOwnership = AdoConnectionOwnership.Internal; + } + + // Create a reader + + // Call ExecuteReader with the appropriate CommandBehavior + var dataReader = connectionOwnership == AdoConnectionOwnership.External + ? command.ExecuteReader() + : command.ExecuteReader(CommandBehavior.CloseConnection); + + ClearCommand(command); + + return dataReader; + } + + private IDataReader ExecuteReader(IDbConnection connection, IDbTransaction transaction, string commandText, + IDataParameter[] commandParameters, AdoConnectionOwnership connectionOwnership) + { + if (connection == null) throw new ArgumentNullException(nameof(connection)); + + var mustCloseConnection = false; + // Create a command and prepare it for execution + var cmd = connection.CreateCommand(); + try + { + PrepareCommand(cmd, connection, transaction, commandText, commandParameters, out mustCloseConnection); + + if (mustCloseConnection) + { + connectionOwnership = AdoConnectionOwnership.Internal; + } + + // Create a reader + + var dataReader = ExecuteReader(cmd, connectionOwnership); + + ClearCommand(cmd); + + return dataReader; + } + catch + { + if (mustCloseConnection) + connection.Close(); + throw; + } + } + + public IDataReader ExecuteReader(string connectionString, string commandText) + { + // Pass through the call providing null for the set of IDataParameters + return ExecuteReader(connectionString, commandText, null); + } + + public IDataReader ExecuteReader(string connectionString, string commandText, + params IDataParameter[] commandParameters) + { + if (string.IsNullOrEmpty(connectionString)) throw new ArgumentNullException(nameof(connectionString)); + IDbConnection connection = null; + try + { + connection = DatoryUtils.GetConnection(WebConfigUtils.DatabaseType, connectionString); + connection.Open(); + + // Call the private overload that takes an internally owned connection in place of the connection string + return ExecuteReader(connection, null, commandText, commandParameters, AdoConnectionOwnership.Internal); + } + catch + { + // If we fail to return the IDataReader, we need to close the connection ourselves + connection?.Close(); + throw; + } + + } + + private IDataReader ExecuteReader(IDbConnection connection, string commandText) + { + // Pass through the call providing null for the set of IDataParameters + return ExecuteReader(connection, commandText, null); + } + + private IDataReader ExecuteReader(IDbConnection connection, string commandText, + params IDataParameter[] commandParameters) + { + // Pass through the call to the private overload using a null transaction value and an externally owned connection + return ExecuteReader(connection, null, commandText, commandParameters, AdoConnectionOwnership.External); + } + + private IDataReader ExecuteReader(IDbTransaction transaction, string commandText) + { + // Pass through the call providing null for the set of IDataParameters + return ExecuteReader(transaction, commandText, null); + } + + private IDataReader ExecuteReader(IDbTransaction transaction, string commandText, + params IDataParameter[] commandParameters) + { + if (transaction == null) throw new ArgumentNullException(nameof(transaction)); + if (transaction != null && transaction.Connection == null) + throw new ArgumentException( + "The transaction was rolled back or commited, please provide an open transaction.", + nameof(transaction)); + + // Pass through to private overload, indicating that the connection is owned by the caller + return ExecuteReader(transaction.Connection, transaction, commandText, commandParameters, + AdoConnectionOwnership.External); + } + } +} diff --git a/net452/SiteServer.CMS/Database/DataProvider.cs b/net452/SiteServer.CMS/Database/DataProvider.cs new file mode 100644 index 000000000..70f4d3bb3 --- /dev/null +++ b/net452/SiteServer.CMS/Database/DataProvider.cs @@ -0,0 +1,197 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Database.Repositories; +using SiteServer.CMS.Database.Repositories.Contents; + +namespace SiteServer.CMS.Database.Core +{ + public static class DataProvider + { + private static DatabaseApi _databaseApi; + public static DatabaseApi DatabaseApi => _databaseApi ?? (_databaseApi = new DatabaseApi()); + + private static AccessTokenRepository _accessToken; + public static AccessTokenRepository AccessToken => _accessToken ?? (_accessToken = new AccessTokenRepository()); + + private static AdministratorRepository _administrator; + public static AdministratorRepository Administrator => _administrator ?? (_administrator = new AdministratorRepository()); + + private static AdministratorsInRolesRepository _administratorsInRoles; + public static AdministratorsInRolesRepository AdministratorsInRoles => _administratorsInRoles ?? (_administratorsInRoles = new AdministratorsInRolesRepository()); + + private static AreaRepository _area; + public static AreaRepository Area => _area ?? (_area = new AreaRepository()); + + private static ChannelRepository _channel; + public static ChannelRepository Channel => _channel ?? (_channel = new ChannelRepository()); + + private static ChannelGroupRepository _channelGroup; + public static ChannelGroupRepository ChannelGroup => _channelGroup ?? (_channelGroup = new ChannelGroupRepository()); + + private static ConfigRepository _config; + public static ConfigRepository Config => _config ?? (_config = new ConfigRepository()); + + private static ContentCheckRepository _contentCheck; + public static ContentCheckRepository ContentCheck => _contentCheck ?? (_contentCheck = new ContentCheckRepository()); + + private static ContentGroupRepository _contentGroup; + public static ContentGroupRepository ContentGroup => _contentGroup ?? (_contentGroup = new ContentGroupRepository()); + + private static ContentTagRepository _contentTag; + public static ContentTagRepository ContentTag => _contentTag ?? (_contentTag = new ContentTagRepository()); + + private static DbCacheRepository _dbCache; + public static DbCacheRepository DbCache => _dbCache ?? (_dbCache = new DbCacheRepository()); + + private static DepartmentRepository _department; + public static DepartmentRepository Department => _department ?? (_department = new DepartmentRepository()); + + private static ErrorLogRepository _errorLog; + public static ErrorLogRepository ErrorLog => _errorLog ?? (_errorLog = new ErrorLogRepository()); + + private static KeywordRepository _keyword; + public static KeywordRepository Keyword => _keyword ?? (_keyword = new KeywordRepository()); + + private static LogRepository _log; + public static LogRepository Log => _log ?? (_log = new LogRepository()); + + private static PermissionsInRolesRepository _permissionsInRoles; + public static PermissionsInRolesRepository PermissionsInRoles => _permissionsInRoles ?? (_permissionsInRoles = new PermissionsInRolesRepository()); + + private static PluginConfigRepository _pluginConfig; + public static PluginConfigRepository PluginConfig => _pluginConfig ?? (_pluginConfig = new PluginConfigRepository()); + + private static PluginRepository _plugin; + public static PluginRepository Plugin => _plugin ?? (_plugin = new PluginRepository()); + + private static RelatedFieldRepository _relatedField; + public static RelatedFieldRepository RelatedField => _relatedField ?? (_relatedField = new RelatedFieldRepository()); + + private static RelatedFieldItemRepository _relatedFieldItem; + public static RelatedFieldItemRepository RelatedFieldItem => _relatedFieldItem ?? (_relatedFieldItem = new RelatedFieldItemRepository()); + + private static RoleRepository _role; + public static RoleRepository Role => _role ?? (_role = new RoleRepository()); + + private static SiteRepository _site; + public static SiteRepository Site => _site ?? (_site = new SiteRepository()); + + private static SiteLogRepository _siteLog; + public static SiteLogRepository SiteLog => _siteLog ?? (_siteLog = new SiteLogRepository()); + + private static SitePermissionsRepository _sitePermissions; + public static SitePermissionsRepository SitePermissions => _sitePermissions ?? (_sitePermissions = new SitePermissionsRepository()); + + private static SpecialRepository _special; + public static SpecialRepository Special => _special ?? (_special = new SpecialRepository()); + + private static TableStyleRepository _tableStyle; + public static TableStyleRepository TableStyle => _tableStyle ?? (_tableStyle = new TableStyleRepository()); + + private static TableStyleItemRepository _tableStyleItem; + public static TableStyleItemRepository TableStyleItem => _tableStyleItem ?? (_tableStyleItem = new TableStyleItemRepository()); + + private static TagRepository _tag; + public static TagRepository Tag => _tag ?? (_tag = new TagRepository()); + + private static TemplateRepository _template; + public static TemplateRepository Template => _template ?? (_template = new TemplateRepository()); + + private static TemplateLogRepository _templateLog; + public static TemplateLogRepository TemplateLog => _templateLog ?? (_templateLog = new TemplateLogRepository()); + + private static UserRepository _user; + public static UserRepository User => _user ?? (_user = new UserRepository()); + + private static UserGroupRepository _userGroup; + public static UserGroupRepository UserGroup => _userGroup ?? (_userGroup = new UserGroupRepository()); + + private static UserLogRepository _userLog; + public static UserLogRepository UserLog => _userLog ?? (_userLog = new UserLogRepository()); + + private static UserMenuRepository _userMenu; + public static UserMenuRepository UserMenu => _userMenu ?? (_userMenu = new UserMenuRepository()); + + private static ContentRepository _contentRepository; + public static ContentRepository ContentRepository => _contentRepository ?? (_contentRepository = new ContentRepository()); + + public static void Reset() + { + _databaseApi = null; + _contentRepository = null; + + _accessToken = null; + _administrator = null; + _administratorsInRoles = null; + _area = null; + _channel = null; + _channelGroup = null; + _config = null; + _contentCheck = null; + _contentGroup = null; + _contentTag = null; + _dbCache = null; + _department = null; + _errorLog = null; + _keyword = null; + _log = null; + _permissionsInRoles = null; + _pluginConfig = null; + _plugin = null; + _relatedField = null; + _relatedFieldItem = null; + _role = null; + _site = null; + _siteLog = null; + _sitePermissions = null; + _special = null; + _tableStyle = null; + _tableStyleItem = null; + _tag = null; + _template = null; + _templateLog = null; + _user = null; + _userGroup = null; + _userLog = null; + _userMenu = null; + } + + public static IEnumerable AllRepositories => new List + { + AccessToken, + Administrator, + AdministratorsInRoles, + Area, + Channel, + ChannelGroup, + Config, + ContentCheck, + ContentGroup, + ContentTag, + DbCache, + Department, + ErrorLog, + Keyword, + Log, + PermissionsInRoles, + PluginConfig, + Plugin, + RelatedField, + RelatedFieldItem, + Role, + Site, + SiteLog, + SitePermissions, + Special, + TableStyle, + TableStyleItem, + Tag, + Template, + TemplateLog, + User, + UserGroup, + UserLog, + UserMenu + }; + } +} diff --git a/net452/SiteServer.CMS/Database/DataProviderBase.cs b/net452/SiteServer.CMS/Database/DataProviderBase.cs new file mode 100644 index 000000000..06dad4078 --- /dev/null +++ b/net452/SiteServer.CMS/Database/DataProviderBase.cs @@ -0,0 +1,357 @@ +using System.Collections.Generic; +using System.Data; +using Datory; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Fx; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Core +{ + public class DataProviderBase + { + + + //public virtual string TableName => string.Empty; + + //public virtual List TableColumns => null; + + + + //protected IDbConnection GetConnection(string connectionString) + //{ + // return DatoryUtils.GetConnection(WebConfigUtils.DatabaseType, connectionString); + //} + + //protected IDbConnection GetConnection(DatabaseType databaseType, string connectionString) + //{ + // return DatoryUtils.GetConnection(databaseType, connectionString); + //} + + + + //protected int InsertEntity(T entityInfo) where T : class, IDataInfo + //{ + // if (entityInfo == null) return 0; + + // if (string.IsNullOrEmpty(entityInfo.Guid) || !StringUtils.IsGuid(entityInfo.Guid)) + // { + // entityInfo.Guid = StringUtils.GetGuid(); + // } + // entityInfo.LastModifiedDate = DateTime.Now; + + // using (var connection = GetConnection()) + // { + // entityInfo.Id = Convert.ToInt32(connection.InsertObject(entityInfo)); + // } + + // return entityInfo.Id; + //} + + //protected T GetEntity(int identity) where T : class, IDataInfo + //{ + // if (identity <= 0) return null; + + // T entityInfo; + + // using (var connection = GetConnection()) + // { + // entityInfo = connection.Get(identity); + // } + + // if (entityInfo != null && (string.IsNullOrEmpty(entityInfo.Guid) || !StringUtils.IsGuid(entityInfo.Guid))) + // { + // entityInfo.Guid = StringUtils.GetGuid(); + // entityInfo.LastModifiedDate = DateTime.Now; + // UpdateEntity(entityInfo); + // } + + // return entityInfo; + //} + + //protected bool UpdateEntity(T entityInfo) where T : class, IDataInfo + //{ + // if (entityInfo == null) return false; + + // bool updated; + // if (string.IsNullOrEmpty(entityInfo.Guid) || !StringUtils.IsGuid(entityInfo.Guid)) + // { + // entityInfo.Guid = StringUtils.GetGuid(); + // } + // entityInfo.LastModifiedDate = DateTime.Now; + + // using (var connection = GetConnection()) + // { + // updated = connection.UpdateObject(entityInfo); + // } + + // return updated; + //} + + //protected bool DeleteEntity(int identity) where T : class, IDataInfo, new() + //{ + // if (identity <= 0) return false; + + // bool deleted; + + // using (var connection = GetConnection()) + // { + // deleted = connection.DeleteById(new T { Id = identity }); + // } + + // return deleted; + //} + + //private void SaveAsync(string tableName, BaseEntityInfo entityInfo) + //{ + // if (string.IsNullOrEmpty(entityInfo.Guid) || !StringUtils.IsGuid(entityInfo.Guid)) + // { + // var sqlString = $@"UPDATE {tableName} SET {nameof(BaseEntityInfo.LastModifiedDate)} = @{nameof(BaseEntityInfo.LastModifiedDate)} WHERE {nameof(BaseEntityInfo.Id)} = @{nameof(BaseEntityInfo.Id)}"; + + // IDataParameter[] parameters = + // { + // GetParameter(nameof(entityInfo.LastModifiedDate), DateTimeOffset.UtcNow), + // GetParameter(nameof(entityInfo.Id), entityInfo.Id) + // }; + + // DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + // } + // else + // { + // var sqlString = $@"UPDATE {tableName} SET + // {nameof(BaseEntityInfo.Guid)} = @{nameof(BaseEntityInfo.Guid)}, + // {nameof(BaseEntityInfo.LastModifiedDate)} = @{nameof(BaseEntityInfo.LastModifiedDate)} + // WHERE {nameof(BaseEntityInfo.Id)} = @{nameof(BaseEntityInfo.Id)}"; + + // IDataParameter[] parameters = + // { + // GetParameter(nameof(entityInfo.Guid), entityInfo.Guid), + // GetParameter(nameof(entityInfo.LastModifiedDate), DateTimeOffset.UtcNow), + // GetParameter(nameof(entityInfo.Id), entityInfo.Id) + // }; + + // DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + // } + //} + + //protected IDbDataParameter GetParameter(string parameterName, DataType dataType, int value) + //{ + // return SqlUtils.GetIDbDataParameter(parameterName, dataType, 0, value); + //} + + //protected IDbDataParameter GetParameter(string parameterName, DataType dataType, bool value) + //{ + // return SqlUtils.GetIDbDataParameter(parameterName, dataType, 0, value); + //} + + //protected IDbDataParameter GetParameter(string parameterName, DataType dataType, decimal value) + //{ + // return SqlUtils.GetIDbDataParameter(parameterName, dataType, 0, value); + //} + + //protected IDbDataParameter GetParameter(string parameterName, DataType dataType, DateTime value) + //{ + // return SqlUtils.GetIDbDataParameter(parameterName, dataType, 0, value); + //} + + //protected IDbDataParameter GetParameter(string parameterName, DataType dataType, string value) + //{ + // return SqlUtils.GetIDbDataParameter(parameterName, dataType, 0, value); + //} + + //protected IDbDataParameter GetParameter(string parameterName, DataType dataType, int size, string value) + //{ + // return SqlUtils.GetIDbDataParameter(parameterName, dataType, size, value); + //} + + //protected IDbDataParameter GetParameter(string parameterName, DataType dataType, int size, decimal value) + //{ + // return SqlUtils.GetIDbDataParameter(parameterName, dataType, size, value); + //} + + + + + //protected IDataReader ExecuteReader(string commandText, params IDataParameter[] commandParameters) + //{ + // return DatabaseApi.Instance.ExecuteReader(ConnectionString, commandText, commandParameters); + //} + + + //protected IDataReader ExecuteReader(string commandText) + //{ + // return DatabaseApi.Instance.ExecuteReader(ConnectionString, commandText); + //} + + + //protected IDataReader ExecuteReader(IDbConnection conn, string commandText, params IDataParameter[] commandParameters) + //{ + // return DatabaseApi.Instance.ExecuteReader(conn, commandText, commandParameters); + //} + + + //protected IDataReader ExecuteReader(IDbConnection conn, string commandText) + //{ + // return DatabaseApi.Instance.ExecuteReader(conn, commandText); + //} + + + //protected IDataReader ExecuteReader(IDbTransaction trans, string commandText, params IDataParameter[] commandParameters) + //{ + // return DatabaseApi.Instance.ExecuteReader(trans, commandText, commandParameters); + //} + + + //protected IDataReader ExecuteReader(IDbTransaction trans, string commandText) + //{ + // return DatabaseApi.Instance.ExecuteReader(trans, commandText); + //} + + + //protected IDataReader ExecuteReader(string connectionString, string commandText) + //{ + // return DatabaseApi.Instance.ExecuteReader(connectionString, commandText); + //} + + //protected IDataReader ExecuteReader(string connectionString, string commandText, params IDataParameter[] commandParameters) + //{ + // return DatabaseApi.Instance.ExecuteReader(connectionString, commandText, commandParameters); + //} + + + //protected DataSet ExecuteDataset(string commandText, params IDataParameter[] commandParameters) + //{ + // return DatabaseApi.Instance.ExecuteDataset(ConnectionString, commandText, commandParameters); + //} + + + //protected DataSet ExecuteDataset(string commandText) + //{ + // return DatabaseApi.Instance.ExecuteDataset(ConnectionString, commandText); + //} + + //protected DataSet ExecuteDataset(string connectionString, string commandText) + //{ + // return DatabaseApi.Instance.ExecuteDataset(connectionString, commandText); + //} + + //protected int ExecuteNonQuery(IDbConnection conn, string commandText, params IDataParameter[] commandParameters) + //{ + // return DatabaseApi.Instance.ExecuteNonQuery(conn, commandText, commandParameters); + //} + + + //protected int ExecuteNonQuery(IDbConnection conn, string commandText) + //{ + // return DatabaseApi.Instance.ExecuteNonQuery(conn, commandText); + //} + + //protected int ExecuteNonQuery(IDbTransaction trans, string commandText, params IDataParameter[] commandParameters) + //{ + // return DatabaseApi.Instance.ExecuteNonQuery(trans, commandText, commandParameters); + //} + + //protected int ExecuteNonQuery(IDbTransaction trans, string commandText) + //{ + // return DatabaseApi.Instance.ExecuteNonQuery(trans, commandText); + //} + + //protected int ExecuteNonQuery(string connectionString, string commandText, params IDataParameter[] commandParameters) + //{ + // return DatabaseApi.Instance.ExecuteNonQuery(connectionString, commandText, commandParameters); + //} + + //protected int ExecuteNonQuery(string commandText, params IDataParameter[] commandParameters) + //{ + // return DatabaseApi.Instance.ExecuteNonQuery(ConnectionString, commandText, commandParameters); + //} + + //protected int ExecuteNonQuery(string commandText) + //{ + // return DatabaseApi.Instance.ExecuteNonQuery(ConnectionString, commandText); + //} + + //protected int ExecuteNonQueryAndReturnId(string tableName, string idColumnName, string commandText, params IDataParameter[] commandParameters) + //{ + // return DatabaseApi.Instance.ExecuteNonQueryAndReturnId(tableName, idColumnName, ConnectionString, commandText, commandParameters); + //} + + //protected int ExecuteNonQueryAndReturnId(string tableName, string idColumnName, IDbTransaction trans, string commandText, params IDataParameter[] commandParameters) + //{ + // return DatabaseApi.Instance.ExecuteNonQueryAndReturnId(tableName, idColumnName, trans, commandText, commandParameters); + //} + + //protected int ExecuteCurrentId(IDbTransaction trans, string tableName, string idColumnName) + //{ + // return DatabaseApi.Instance.ExecuteCurrentId(trans, tableName, idColumnName); + //} + + //protected object ExecuteScalar(IDbConnection conn, string commandText, params IDataParameter[] commandParameters) + //{ + // return DatabaseApi.Instance.ExecuteScalar(conn, commandText, commandParameters); + //} + + //protected object ExecuteScalar(IDbConnection conn, string commandText) + //{ + // return DatabaseApi.Instance.ExecuteScalar(conn, commandText); + //} + + //protected object ExecuteScalar(IDbTransaction trans, string commandText, params IDataParameter[] commandParameters) + //{ + // return DatabaseApi.Instance.ExecuteScalar(trans, commandText, commandParameters); + //} + + //protected object ExecuteScalar(IDbTransaction trans, string commandText) + //{ + // return DatabaseApi.Instance.ExecuteScalar(trans, commandText); + //} + + //protected object ExecuteScalar(string commandText, params IDataParameter[] commandParameters) + //{ + // return DatabaseApi.Instance.ExecuteScalar(ConnectionString, commandText, commandParameters); + //} + + //protected object ExecuteScalar(string commandText) + //{ + // return DatabaseApi.Instance.ExecuteScalar(ConnectionString, commandText); + //} + + //protected string GetString(IDataReader rdr, int i) + //{ + // var value = rdr.IsDBNull(i) ? string.Empty : rdr.GetValueById(i).ToString(); + // if (!string.IsNullOrEmpty(value)) + // { + // value = AttackUtils.UnFilterSql(value); + // } + // if (WebConfigUtils.DatabaseType == DatabaseType.Oracle && value == SqlUtils.OracleEmptyValue) + // { + // value = string.Empty; + // } + // return value; + //} + + //protected bool GetBool(IDataReader rdr, int i) + //{ + // return !rdr.IsDBNull(i) && TranslateUtils.ToBool(rdr.GetValueById(i).ToString()); + //} + + //protected int GetInt(IDataReader rdr, int i) + //{ + // return rdr.IsDBNull(i) ? 0 : rdr.GetInt32(i); + //} + + //protected decimal GetDecimal(IDataReader rdr, int i) + //{ + // return rdr.IsDBNull(i) ? 0 : rdr.GetDecimal(i); + //} + + //protected double GetDouble(IDataReader rdr, int i) + //{ + // return rdr.IsDBNull(i) ? 0 : rdr.GetDouble(i); + //} + + //protected DateTime GetDateTime(IDataReader rdr, int i) + //{ + // return rdr.IsDBNull(i) ? DateTime.Now : rdr.GetDateTime(i); + //} + } +} diff --git a/net452/SiteServer.CMS/Database/IDatabaseApi.cs b/net452/SiteServer.CMS/Database/IDatabaseApi.cs new file mode 100644 index 000000000..ad5fb4157 --- /dev/null +++ b/net452/SiteServer.CMS/Database/IDatabaseApi.cs @@ -0,0 +1,30 @@ +using System.Data; +using System.Xml; + +namespace SiteServer.CMS.Database.Core +{ + public interface IDatabaseApi + { + //IDataParameter[] GetDataParameters(int size); + + + //IDbConnection GetConnection(string connectionString); + + + //IDbDataAdapter GetDataAdapter(); + + //void DeriveParameters(IDbCommand cmd); + + + //IDataParameter GetParameter(); + + + //void ClearCommand(IDbCommand command); + + + //void CleanParameterSyntax(IDbCommand command); + + + //XmlReader ExecuteXmlReader(IDbCommand command); + } +} diff --git a/net452/SiteServer.CMS/Database/Models/AccessTokenInfo.cs b/net452/SiteServer.CMS/Database/Models/AccessTokenInfo.cs new file mode 100644 index 000000000..f0b59333d --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/AccessTokenInfo.cs @@ -0,0 +1,27 @@ +using System; +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_AccessToken")] + public class AccessTokenInfo : Entity + { + [TableColumn] + public string Title { get; set; } + + [TableColumn] + public string Token { get; set; } + + [TableColumn] + public string AdminName { get; set; } + + [TableColumn] + public string Scopes { get; set; } + + [TableColumn] + public int RateLimit { get; set; } + + [TableColumn] + public DateTimeOffset? AddDate { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/AdministratorInfo.cs b/net452/SiteServer.CMS/Database/Models/AdministratorInfo.cs new file mode 100644 index 000000000..e4a168326 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/AdministratorInfo.cs @@ -0,0 +1,74 @@ +using System; +using Datory; +using Newtonsoft.Json; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_Administrator")] + public class AdministratorInfo : Entity, IAdministratorInfo + { + [TableColumn] + public string UserName { get; set; } + + [JsonIgnore] + [TableColumn] + public string Password { get; set; } + + [JsonIgnore] + [TableColumn] + public string PasswordFormat { get; set; } + + [JsonIgnore] + [TableColumn] + public string PasswordSalt { get; set; } + + [TableColumn] + public DateTime? CreationDate { get; set; } + + [TableColumn] + public DateTime? LastActivityDate { get; set; } + + [TableColumn] + public int CountOfLogin { get; set; } + + [TableColumn] + public int CountOfFailedLogin { get; set; } + + [TableColumn] + public string CreatorUserName { get; set; } + + [TableColumn] + private string IsLockedOut { get; set; } + + public bool Locked + { + get => IsLockedOut == "True"; + set => IsLockedOut = value.ToString(); + } + + [TableColumn(Text = true)] + public string SiteIdCollection { get; set; } + + [TableColumn] + public int SiteId { get; set; } + + [TableColumn] + public int DepartmentId { get; set; } + + [TableColumn] + public int AreaId { get; set; } + + [TableColumn] + public string DisplayName { get; set; } + + [TableColumn] + public string Mobile { get; set; } + + [TableColumn] + public string Email { get; set; } + + [TableColumn(Length = 1000)] + public string AvatarUrl { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/AdministratorsInRolesInfo.cs b/net452/SiteServer.CMS/Database/Models/AdministratorsInRolesInfo.cs new file mode 100644 index 000000000..704e318ad --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/AdministratorsInRolesInfo.cs @@ -0,0 +1,14 @@ +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_AdministratorsInRoles")] + public class AdministratorsInRolesInfo : Entity + { + [TableColumn] + public string RoleName { get; set; } + + [TableColumn] + public string UserName { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/AreaInfo.cs b/net452/SiteServer.CMS/Database/Models/AreaInfo.cs new file mode 100644 index 000000000..8fa3bddcf --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/AreaInfo.cs @@ -0,0 +1,38 @@ +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_Area")] + public class AreaInfo : Entity + { + [TableColumn] + public string AreaName { get; set; } + + [TableColumn] + public int ParentId { get; set; } + + [TableColumn] + public string ParentsPath { get; set; } + + [TableColumn] + public int ParentsCount { get; set; } + + [TableColumn] + public int ChildrenCount { get; set; } + + [TableColumn] + private string IsLastNode { get; set; } + + public bool LastNode + { + get => IsLastNode == "True"; + set => IsLastNode = value.ToString(); + } + + [TableColumn] + public int Taxis { get; set; } + + [TableColumn] + public int CountOfAdmin { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/ChannelGroupInfo.cs b/net452/SiteServer.CMS/Database/Models/ChannelGroupInfo.cs new file mode 100644 index 000000000..107ff76d6 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/ChannelGroupInfo.cs @@ -0,0 +1,20 @@ +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_ChannelGroup")] + public class ChannelGroupInfo : Entity + { + [TableColumn] + public string GroupName { get; set; } + + [TableColumn] + public int SiteId { get; set; } + + [TableColumn] + public int Taxis { get; set; } + + [TableColumn(Length = 2000)] + public string Description { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/ChannelInfo.Extend.cs b/net452/SiteServer.CMS/Database/Models/ChannelInfo.Extend.cs new file mode 100644 index 000000000..c2094e566 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/ChannelInfo.Extend.cs @@ -0,0 +1,49 @@ +using Newtonsoft.Json; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Repositories.Contents; + +namespace SiteServer.CMS.Database.Models +{ + public partial class ChannelInfo + { + [JsonIgnore] + public ContentTableRepository ContentRepository => new ContentTableRepository(SiteId, + ChannelManager.GetTableName(SiteManager.GetSiteInfo(SiteId), this)); + + //是否可以添加栏目 + public bool IsChannelAddable { get; set; } = true; + + //是否可以添加内容 + public bool IsContentAddable { get; set; } = true; + + //是否可以生成栏目 + public bool IsChannelCreatable { get; set; } = true; + + //是否可以生成内容 + public bool IsContentCreatable { get; set; } = true; + + public bool IsCreateChannelIfContentChanged { get; set; } = true; + + public string CreateChannelIdsIfContentChanged { get; set; } + + public string ContentAttributesOfDisplay { get; set; } + + public string TransType { get; set; } = ECrossSiteTransTypeUtils.GetValue(ECrossSiteTransType.AllSite); + + public int TransSiteId { get; set; } + + public string TransChannelIds { get; set; } + + public string TransChannelNames { get; set; } + + public bool TransIsAutomatic { get; set; } + + //跨站转发操作类型:复制 引用地址 引用内容 + public string TransDoneType { get; set; } = ETranslateContentTypeUtils.GetValue(ETranslateContentType.Copy); + + public bool IsPreviewContentsExists { get; set; } + + public string DefaultTaxisType { get; set; } = ETaxisTypeUtils.GetValue(ETaxisType.OrderByTaxisDesc); + } +} diff --git a/net452/SiteServer.CMS/Database/Models/ChannelInfo.cs b/net452/SiteServer.CMS/Database/Models/ChannelInfo.cs new file mode 100644 index 000000000..f22a61dda --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/ChannelInfo.cs @@ -0,0 +1,96 @@ +using System; +using Datory; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_Channel")] + public partial class ChannelInfo : Entity, IChannelInfo, ICloneable + { + [TableColumn] + public string ChannelName { get; set; } + + [TableColumn] + public int SiteId { get; set; } + + [TableColumn] + public string ContentModelPluginId { get; set; } + + [TableColumn(Text = true)] + public string ContentRelatedPluginIds { get; set; } + + [TableColumn] + public int ParentId { get; set; } + + [TableColumn] + public string ParentsPath { get; set; } + + [TableColumn] + public int ParentsCount { get; set; } + + [TableColumn] + public int ChildrenCount { get; set; } + + [TableColumn] + private string IsLastNode { get; set; } + + public bool LastNode + { + get => IsLastNode == "True"; + set => IsLastNode = value.ToString(); + } + + [TableColumn] + public string IndexName { get; set; } + + [TableColumn(Text = true)] + public string GroupNameCollection { get; set; } + + [TableColumn] + public int Taxis { get; set; } + + [TableColumn] + public DateTime? AddDate { get; set; } + + [TableColumn(Length = 1000)] + public string ImageUrl { get; set; } + + [TableColumn(Text = true)] + public string Content { get; set; } + + [TableColumn(Length = 1000)] + public string FilePath { get; set; } + + [TableColumn(Length = 1000)] + public string ChannelFilePathRule { get; set; } + + [TableColumn(Length = 1000)] + public string ContentFilePathRule { get; set; } + + [TableColumn(Length = 1000)] + public string LinkUrl { get; set; } + + [TableColumn] + public string LinkType { get; set; } + + [TableColumn] + public int ChannelTemplateId { get; set; } + + [TableColumn] + public int ContentTemplateId { get; set; } + + [TableColumn(Length = 2000)] + public string Keywords { get; set; } + + [TableColumn(Length = 2000)] + public string Description { get; set; } + + [TableColumn(Text = true, Extend = true)] + public string ExtendValues { get; set; } + + public object Clone() + { + return (ChannelInfo)MemberwiseClone(); + } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/ConfigInfo.Extend.cs b/net452/SiteServer.CMS/Database/Models/ConfigInfo.Extend.cs new file mode 100644 index 000000000..2cb8db061 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/ConfigInfo.Extend.cs @@ -0,0 +1,112 @@ +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Database.Models +{ + public partial class ConfigInfo + { + public bool IsSeparatedApi { get; set; } + + public string SeparatedApiUrl { get; set; } + + public string ApiUrl => + IsSeparatedApi ? SeparatedApiUrl : FxUtils.ParseNavigationUrl($"~/{WebConfigUtils.ApiPrefix}"); + + public bool IsLogSite { get; set; } = true; + + public bool IsLogAdmin { get; set; } = true; + + public bool IsLogUser { get; set; } = true; + + public bool IsLogError { get; set; } = true; + + /// + /// Ƿֻ鿴Լӵ + /// ǣôԱֻܲ鿴Լӵ + /// ǣôԱԲ鿴ԱݣĬfalse + /// ע⣺룬վԱ˹ԱЧ + /// + public bool IsViewContentOnlySelf { get; set; } + + // Ƿʱֵ + public bool IsTimeThreshold { get; set; } + + public int TimeThreshold { get; set; } = 60; + + /****************Ա********************/ + + public int AdminUserNameMinLength { get; set; } + + public int AdminPasswordMinLength { get; set; } = 6; + + public string AdminPasswordRestriction { get; set; } = + EUserPasswordRestrictionUtils.GetValue(EUserPasswordRestriction.LetterAndDigit); + + public bool IsAdminLockLogin { get; set; } + + public int AdminLockLoginCount { get; set; } = 3; + + public string AdminLockLoginType { get; set; } = EUserLockTypeUtils.GetValue(EUserLockType.Hours); + + public int AdminLockLoginHours { get; set; } = 3; + + /****************û********************/ + + public bool IsUserRegistrationAllowed { get; set; } = true; + + public string UserRegistrationAttributes { get; set; } + + public bool IsUserRegistrationGroup { get; set; } + + public bool IsUserRegistrationChecked { get; set; } = true; + + public bool IsUserUnRegistrationAllowed { get; set; } = true; + + public int UserPasswordMinLength { get; set; } = 6; + + public string UserPasswordRestriction { get; set; } = + EUserPasswordRestrictionUtils.GetValue(EUserPasswordRestriction.LetterAndDigit); + + public int UserRegistrationMinMinutes { get; set; } + + public bool IsUserLockLogin { get; set; } + + public int UserLockLoginCount { get; set; } = 3; + + public string UserLockLoginType { get; set; } = "Hours"; + + public int UserLockLoginHours { get; set; } = 3; + + public string UserDefaultGroupAdminName { get; set; } + + /****************û********************/ + + public bool IsHomeClosed { get; set; } + + public string HomeTitle { get; set; } = "û"; + + public bool IsHomeLogo { get; set; } + + public string HomeLogoUrl { get; set; } + + public bool IsHomeBackground { get; set; } + + public string HomeBackgroundUrl { get; set; } + + public string HomeDefaultAvatarUrl { get; set; } + + public bool IsHomeAgreement { get; set; } + + public string HomeAgreementHtml { get; set; } = + @"ĶûЭ顷"; + + /****************Ʒ********************/ + + public string RepositoryOwner { get; set; } + + public string RepositoryName { get; set; } + + public string RepositoryToken { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/ConfigInfo.cs b/net452/SiteServer.CMS/Database/Models/ConfigInfo.cs new file mode 100644 index 000000000..cbee04976 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/ConfigInfo.cs @@ -0,0 +1,27 @@ +using System; +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_Config")] + public partial class ConfigInfo : Entity + { + [TableColumn] + private string IsInitialized { get; set; } + + public bool Initialized + { + get => IsInitialized == "True"; + set => IsInitialized = value.ToString(); + } + + [TableColumn] + public string DatabaseVersion { get; set; } + + [TableColumn] + public DateTime? UpdateDate { get; set; } + + [TableColumn(Text = true, Extend = true)] + private string SystemConfig { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/ContentCheckInfo.cs b/net452/SiteServer.CMS/Database/Models/ContentCheckInfo.cs new file mode 100644 index 000000000..7dc10ac92 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/ContentCheckInfo.cs @@ -0,0 +1,42 @@ +using System; +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_ContentCheck")] + public class ContentCheckInfo : Entity + { + [TableColumn] + public string TableName { get; set; } + + [TableColumn] + public int SiteId { get; set; } + + [TableColumn] + public int ChannelId { get; set; } + + [TableColumn] + public int ContentId { get; set; } + + [TableColumn] + public string UserName { get; set; } + + [TableColumn] + private string IsChecked { get; set; } + + public bool Checked + { + get => IsChecked == "True"; + set => IsChecked = value.ToString(); + } + + [TableColumn] + public int CheckedLevel { get; set; } + + [TableColumn] + public DateTime? CheckDate { get; set; } + + [TableColumn] + public string Reasons { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/ContentGroupInfo.cs b/net452/SiteServer.CMS/Database/Models/ContentGroupInfo.cs new file mode 100644 index 000000000..b7ae7a03d --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/ContentGroupInfo.cs @@ -0,0 +1,20 @@ +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_ContentGroup")] + public class ContentGroupInfo : Entity + { + [TableColumn] + public string GroupName { get; set; } + + [TableColumn] + public int SiteId { get; set; } + + [TableColumn] + public int Taxis { get; set; } + + [TableColumn(Length = 2000)] + public string Description { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/ContentInfo.cs b/net452/SiteServer.CMS/Database/Models/ContentInfo.cs new file mode 100644 index 000000000..865b7170a --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/ContentInfo.cs @@ -0,0 +1,506 @@ +using System; +using System.Collections.Generic; +using Datory; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Database.Models +{ + public class ContentInfo : Entity, IContentInfo + { + public ContentInfo() { } + + public ContentInfo(IDictionary dict) : base(dict) + { + + } + + //public ContentInfo(IDictionary dict) + //{ + // foreach (var o in dict) + // { + // var name = o.Key; + // var value = o.Value; + + // if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.Id)) + // { + // Id = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.Guid)) + // { + // Guid = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.LastModifiedDate)) + // { + // LastModifiedDate = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.ChannelId)) + // { + // ChannelId = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.SiteId)) + // { + // SiteId = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.AddUserName)) + // { + // AddUserName = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.LastEditUserName)) + // { + // LastEditUserName = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.LastEditDate)) + // { + // LastEditDate = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.AdminId)) + // { + // AdminId = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.UserId)) + // { + // UserId = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.Taxis)) + // { + // Taxis = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.GroupNameCollection)) + // { + // GroupNameCollection = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.Tags)) + // { + // Tags = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.SourceId)) + // { + // SourceId = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.ReferenceId)) + // { + // ReferenceId = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.IsChecked)) + // { + // IsChecked = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, nameof(Checked))) + // { + // Checked = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.CheckedLevel)) + // { + // CheckedLevel = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.Hits)) + // { + // Hits = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.HitsByDay)) + // { + // HitsByDay = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.HitsByWeek)) + // { + // HitsByWeek = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.HitsByMonth)) + // { + // HitsByMonth = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.LastHitsDate)) + // { + // LastHitsDate = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.Title)) + // { + // Title = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.IsTop)) + // { + // IsTop = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, nameof(Top))) + // { + // Top = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.IsRecommend)) + // { + // IsRecommend = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, nameof(Recommend))) + // { + // Recommend = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.IsHot)) + // { + // IsHot = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, nameof(Hot))) + // { + // Hot = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.IsColor)) + // { + // IsColor = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, nameof(Color))) + // { + // Color = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.AddDate)) + // { + // AddDate = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.LinkUrl)) + // { + // LinkUrl = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.SubTitle)) + // { + // SubTitle = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.ImageUrl)) + // { + // ImageUrl = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.VideoUrl)) + // { + // VideoUrl = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.FileUrl)) + // { + // FileUrl = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.Author)) + // { + // Author = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.Source)) + // { + // Source = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.Summary)) + // { + // Summary = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.Content)) + // { + // Content = TranslateUtils.Get(value); + // } + // else if (StringUtils.EqualsIgnoreCase(name, ContentAttribute.SettingsXml)) + // { + // SettingsXml = TranslateUtils.Get(value); + // } + // else + // { + // Set(name, value); + // } + // } + //} + + //public IDictionary ToDictionary() + //{ + // var dict = new Dictionary(StringComparer.OrdinalIgnoreCase); + + // foreach (var o in this) + // { + // dict[o.Key] = o.Value; + // } + + // dict[ContentAttribute.Id] = Id; + // dict[ContentAttribute.Guid] = Guid; + // dict[ContentAttribute.LastModifiedDate] = LastModifiedDate; + // dict[ContentAttribute.ChannelId] = ChannelId; + // dict[ContentAttribute.SiteId] = SiteId; + // dict[ContentAttribute.AddUserName] = AddUserName; + // dict[ContentAttribute.LastEditUserName] = LastEditUserName; + // dict[ContentAttribute.LastEditDate] = LastEditDate; + // dict[ContentAttribute.AdminId] = AdminId; + // dict[ContentAttribute.UserId] = UserId; + // dict[ContentAttribute.Taxis] = Taxis; + // dict[ContentAttribute.GroupNameCollection] = GroupNameCollection; + // dict[ContentAttribute.Tags] = Tags; + // dict[ContentAttribute.SourceId] = SourceId; + // dict[ContentAttribute.ReferenceId] = ReferenceId; + // dict[nameof(Checked)] = Checked; + // dict[ContentAttribute.CheckedLevel] = CheckedLevel; + // dict[ContentAttribute.Hits] = Hits; + // dict[ContentAttribute.HitsByDay] = HitsByDay; + // dict[ContentAttribute.HitsByWeek] = HitsByWeek; + // dict[ContentAttribute.HitsByMonth] = HitsByMonth; + // dict[ContentAttribute.LastHitsDate] = LastHitsDate; + // dict[ContentAttribute.Title] = Title; + // dict[nameof(Top)] = Top; + // dict[nameof(Recommend)] = Recommend; + // dict[nameof(Hot)] = Hot; + // dict[nameof(Color)] = Color; + // dict[ContentAttribute.AddDate] = AddDate; + // dict[ContentAttribute.LinkUrl] = LinkUrl; + // dict[ContentAttribute.SubTitle] = SubTitle; + // dict[ContentAttribute.ImageUrl] = ImageUrl; + // dict[ContentAttribute.VideoUrl] = VideoUrl; + // dict[ContentAttribute.FileUrl] = FileUrl; + // dict[ContentAttribute.Author] = Author; + // dict[ContentAttribute.Source] = Source; + // dict[ContentAttribute.Summary] = Summary; + // dict[ContentAttribute.Content] = Content; + + // return dict; + //} + + [TableColumn] + public int ChannelId { get; set; } + + [TableColumn] + public int SiteId { get; set; } + + [TableColumn] + public string AddUserName { get; set; } + + [TableColumn] + public string LastEditUserName { get; set; } + + [TableColumn] + public DateTime? LastEditDate { get; set; } + + [TableColumn] + public int AdminId { get; set; } + + [TableColumn] + public int UserId { get; set; } + + [TableColumn] + public int Taxis { get; set; } + + [TableColumn] + public string GroupNameCollection { get; set; } + + [TableColumn] + public string Tags { get; set; } + + [TableColumn] + public int SourceId { get; set; } + + [TableColumn] + public int ReferenceId { get; set; } + + [TableColumn] + private string IsChecked { get; set; } + + public bool Checked + { + get => IsChecked == "True"; + set => IsChecked = value.ToString(); + } + + [TableColumn] + public int CheckedLevel { get; set; } + + [TableColumn] + public int Hits { get; set; } + + [TableColumn] + public int HitsByDay { get; set; } + + [TableColumn] + public int HitsByWeek { get; set; } + + [TableColumn] + public int HitsByMonth { get; set; } + + [TableColumn] + public DateTime? LastHitsDate { get; set; } + + [TableColumn] + public int Downloads { get; set; } + + [TableColumn] + public string Title { get; set; } + + [TableColumn] + private string IsTop { get; set; } + + public bool Top + { + get => IsTop == "True"; + set => IsTop = value.ToString(); + } + + [TableColumn] + private string IsRecommend { get; set; } + + public bool Recommend + { + get => IsRecommend == "True"; + set => IsRecommend = value.ToString(); + } + + [TableColumn] + private string IsHot { get; set; } + + public bool Hot + { + get => IsHot == "True"; + set => IsHot = value.ToString(); + } + + [TableColumn] + private string IsColor { get; set; } + + public bool Color + { + get => IsColor == "True"; + set => IsColor = value.ToString(); + } + + [TableColumn] + public DateTime? AddDate { get; set; } + + [TableColumn] + public string LinkUrl { get; set; } + + [TableColumn] + public string SubTitle { get; set; } + + [TableColumn] + public string ImageUrl { get; set; } + + [TableColumn] + public string VideoUrl { get; set; } + + [TableColumn] + public string FileUrl { get; set; } + + [TableColumn] + public string Author { get; set; } + + [TableColumn] + public string Source { get; set; } + + [TableColumn(Text = true)] + public string Summary { get; set; } + + [TableColumn(Text = true)] + public string Content { get; set; } + + [TableColumn(Text = true, Extend = true)] + public string SettingsXml { get; set; } + + // public override Dictionary ToDictionary() + //{ + // var dict = base.ToDictionary(); + // //dict.Remove(nameof(SettingsXml)); + + // var siteInfo = SiteManager.GetSiteInfo(SiteId); + // var channelInfo = ChannelManager.GetChannelInfo(SiteId, ChannelId); + // var styleInfoList = TableStyleManager.GetContentStyleInfoList(siteInfo, channelInfo); + + // foreach (var styleInfo in styleInfoList) + // { + // if (styleInfo.Type == InputType.Image || styleInfo.Type == InputType.File || styleInfo.Type == InputType.Video) + // { + // var value = GetString(styleInfo.AttributeName); + // if (!string.IsNullOrEmpty(value)) + // { + // value = PageUtility.ParseNavigationUrl(siteInfo, value, false); + // } + + // dict.Remove(styleInfo.AttributeName); + // dict[styleInfo.AttributeName] = value; + // } + // else if (styleInfo.Type == InputType.TextEditor) + // { + // var value = GetString(styleInfo.AttributeName); + // if (!string.IsNullOrEmpty(value)) + // { + // value = ContentUtility.TextEditorContentDecode(siteInfo, value, false); + // } + // dict.Remove(styleInfo.AttributeName); + // dict[styleInfo.AttributeName] = value; + // } + // else + // { + // dict.Remove(styleInfo.AttributeName); + // dict[styleInfo.AttributeName] = Get(styleInfo.AttributeName); + // } + // } + + // foreach (var attributeName in ContentAttribute.AllAttributes.Value) + // { + // if (StringUtils.StartsWith(attributeName, "Is")) + // { + // dict.Remove(attributeName); + // dict[attributeName] = GetBool(attributeName); + // } + // else if (StringUtils.EqualsIgnoreCase(attributeName, ContentAttribute.Title)) + // { + // var value = GetString(ContentAttribute.Title); + // if (siteInfo.IsContentTitleBreakLine) + // { + // value = value.Replace(" ", "
    "); + // } + // dict.Remove(attributeName); + // dict[attributeName] = value; + // } + // else + // { + // dict.Remove(attributeName); + // dict[attributeName] = Get(attributeName); + // } + // } + + // foreach (var attributeName in ContentAttribute.IncludedAttributes.Value) + // { + // if (attributeName == ContentAttribute.NavigationUrl) + // { + // dict.Remove(attributeName); + // dict[attributeName] = PageUtility.GetContentUrl(siteInfo, this, false); + // } + // else if (attributeName == ContentAttribute.CheckState) + // { + // dict.Remove(attributeName); + // dict[attributeName] = CheckManager.GetCheckState(siteInfo, this); + // } + // else + // { + // dict.Remove(attributeName); + // dict[attributeName] = Get(attributeName); + // } + // } + + // foreach (var attributeName in ContentAttribute.ExcludedAttributes.Value) + // { + // dict.Remove(attributeName); + // } + + // return dict; + //} + + //private class ContentConverter : JsonConverter + //{ + // public override bool CanConvert(Type objectType) + // { + // return objectType == typeof(IAttributes); + // } + + // public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + // { + // var attributes = value as IAttributes; + // serializer.Serialize(writer, attributes?.ToDictionary()); + // } + + // public override object ReadJson(JsonReader reader, Type objectType, object existingValue, + // JsonSerializer serializer) + // { + // var value = (string)reader.Value; + // if (string.IsNullOrEmpty(value)) return null; + // var dict = TranslateUtils.JsonDeserialize>(value); + // var content = new ContentInfo(dict); + + // return content; + // } + //} + } +} diff --git a/net452/SiteServer.CMS/Database/Models/ContentTagInfo.cs b/net452/SiteServer.CMS/Database/Models/ContentTagInfo.cs new file mode 100644 index 000000000..e9306572c --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/ContentTagInfo.cs @@ -0,0 +1,17 @@ +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_ContentTag")] + public class ContentTagInfo : Entity + { + [TableColumn] + public string TagName { get; set; } + + [TableColumn] + public int SiteId { get; set; } + + [TableColumn] + public int UseNum { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/DbCacheInfo.cs b/net452/SiteServer.CMS/Database/Models/DbCacheInfo.cs new file mode 100644 index 000000000..5b7adf686 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/DbCacheInfo.cs @@ -0,0 +1,18 @@ +using System; +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_DbCache")] + public class DbCacheInfo : Entity + { + [TableColumn] + public string CacheKey { get; set; } + + [TableColumn] + public string CacheValue { get; set; } + + [TableColumn] + public DateTime? AddDate { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/DepartmentInfo.cs b/net452/SiteServer.CMS/Database/Models/DepartmentInfo.cs new file mode 100644 index 000000000..348f22182 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/DepartmentInfo.cs @@ -0,0 +1,48 @@ +using System; +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_Department")] + public class DepartmentInfo : Entity + { + [TableColumn] + public string DepartmentName { get; set; } + + [TableColumn] + public string Code { get; set; } + + [TableColumn] + public int ParentId { get; set; } + + [TableColumn] + public string ParentsPath { get; set; } + + [TableColumn] + public int ParentsCount { get; set; } + + [TableColumn] + public int ChildrenCount { get; set; } + + [TableColumn] + private string IsLastNode { get; set; } + + public bool LastNode + { + get => IsLastNode == "True"; + set => IsLastNode = value.ToString(); + } + + [TableColumn] + public int Taxis { get; set; } + + [TableColumn] + public DateTime? AddDate { get; set; } + + [TableColumn] + public string Summary { get; set; } + + [TableColumn] + public int CountOfAdmin { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/ErrorLogInfo.cs b/net452/SiteServer.CMS/Database/Models/ErrorLogInfo.cs new file mode 100644 index 000000000..ade4174dc --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/ErrorLogInfo.cs @@ -0,0 +1,28 @@ +using System; +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_ErrorLog")] + [Serializable] + public class ErrorLogInfo : Entity + { + [TableColumn] + public string Category { get; set; } + + [TableColumn] + public string PluginId { get; set; } + + [TableColumn] + public string Message { get; set; } + + [TableColumn(Text = true)] + public string Stacktrace { get; set; } + + [TableColumn(Text = true)] + public string Summary { get; set; } + + [TableColumn] + public DateTime? AddDate { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/KeywordInfo.cs b/net452/SiteServer.CMS/Database/Models/KeywordInfo.cs new file mode 100644 index 000000000..635e853c4 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/KeywordInfo.cs @@ -0,0 +1,24 @@ +using Datory; +using SiteServer.CMS.Core.Enumerations; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_ErrorLog")] + public class KeywordInfo : Entity + { + [TableColumn] + public string Keyword { get; set; } + + [TableColumn] + public string Alternative { get; set; } + + [TableColumn] + private string Grade { get; set; } + + public EKeywordGrade KeywordGrade + { + get => EKeywordGradeUtils.GetEnumType(Grade); + set => Grade = EKeywordGradeUtils.GetValue(value); + } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/LogInfo.cs b/net452/SiteServer.CMS/Database/Models/LogInfo.cs new file mode 100644 index 000000000..81a232979 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/LogInfo.cs @@ -0,0 +1,27 @@ +using System; +using Datory; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_Log")] + public class LogInfo : Entity, ILogInfo + { + public const string AdminLogin = "后台管理员登录"; + + [TableColumn] + public string UserName { get; set; } + + [TableColumn] + public string IpAddress { get; set; } + + [TableColumn] + public DateTime? AddDate { get; set; } + + [TableColumn] + public string Action { get; set; } + + [TableColumn] + public string Summary { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/PermissionsInRolesInfo.cs b/net452/SiteServer.CMS/Database/Models/PermissionsInRolesInfo.cs new file mode 100644 index 000000000..53aa68cad --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/PermissionsInRolesInfo.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_PermissionsInRoles")] + public class PermissionsInRolesInfo : Entity + { + [TableColumn] + public string RoleName { get; set; } + + [TableColumn(Text = true)] + private string GeneralPermissions { get; set; } + + public List GeneralPermissionList + { + get => TranslateUtils.StringCollectionToStringList(GeneralPermissions); + set => GeneralPermissions = TranslateUtils.ObjectCollectionToString(value); + } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/PluginConfigInfo.cs b/net452/SiteServer.CMS/Database/Models/PluginConfigInfo.cs new file mode 100644 index 000000000..3322abd8f --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/PluginConfigInfo.cs @@ -0,0 +1,20 @@ +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_PluginConfig")] + public class PluginConfigInfo : Entity + { + [TableColumn] + public string PluginId { get; set; } + + [TableColumn] + public int SiteId { get; set; } + + [TableColumn] + public string ConfigName { get; set; } + + [TableColumn(Text = true)] + public string ConfigValue { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/PluginInfo.cs b/net452/SiteServer.CMS/Database/Models/PluginInfo.cs new file mode 100644 index 000000000..1cf7a6c3f --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/PluginInfo.cs @@ -0,0 +1,23 @@ +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_Plugin")] + public class PluginInfo : Entity + { + [TableColumn] + public string PluginId { get; set; } + + [TableColumn] + private string IsDisabled { get; set; } + + public bool Disabled + { + get => IsDisabled == "True"; + set => IsDisabled = value.ToString(); + } + + [TableColumn] + public int Taxis { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/RelatedFieldInfo.cs b/net452/SiteServer.CMS/Database/Models/RelatedFieldInfo.cs new file mode 100644 index 000000000..5a73537b4 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/RelatedFieldInfo.cs @@ -0,0 +1,23 @@ +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_RelatedField")] + public class RelatedFieldInfo : Entity + { + [TableColumn] + public string Title { get; set; } + + [TableColumn] + public int SiteId { get; set; } + + [TableColumn] + public int TotalLevel { get; set; } + + [TableColumn] + public string Prefixes { get; set; } + + [TableColumn] + public string Suffixes { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/RelatedFieldItemInfo.cs b/net452/SiteServer.CMS/Database/Models/RelatedFieldItemInfo.cs new file mode 100644 index 000000000..a10909d39 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/RelatedFieldItemInfo.cs @@ -0,0 +1,23 @@ +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_RelatedFieldItem")] + public class RelatedFieldItemInfo : Entity + { + [TableColumn] + public int RelatedFieldId { get; set; } + + [TableColumn] + public string ItemName { get; set; } + + [TableColumn] + public string ItemValue { get; set; } + + [TableColumn] + public int ParentId { get; set; } + + [TableColumn] + public int Taxis { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/RoleInfo.cs b/net452/SiteServer.CMS/Database/Models/RoleInfo.cs new file mode 100644 index 000000000..3646d0efc --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/RoleInfo.cs @@ -0,0 +1,17 @@ +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_Role")] + public class RoleInfo : Entity + { + [TableColumn] + public string RoleName { get; set; } + + [TableColumn] + public string CreatorUserName { get; set; } + + [TableColumn] + public string Description { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/SiteInfo.Extend.cs b/net452/SiteServer.CMS/Database/Models/SiteInfo.Extend.cs new file mode 100644 index 000000000..27f56acb0 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/SiteInfo.Extend.cs @@ -0,0 +1,221 @@ +using System; +using Newtonsoft.Json; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Repositories.Contents; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Database.Models +{ + public partial class SiteInfo + { + [JsonIgnore] + public ContentTableRepository ContentRepository => new ContentTableRepository(Id, ChannelManager.GetTableName(this, Id)); + + /****************վ********************/ + + public string Charset { get; set; } = ECharsetUtils.GetValue(ECharset.utf_8); + + public int PageSize { get; set; } = 30; + + public bool IsCheckContentLevel { get; set; } + + public int CheckContentLevel { get; set; } + + public bool IsSaveImageInTextEditor { get; set; } = true; + + public bool IsAutoPageInTextEditor { get; set; } + + public int AutoPageWordNum { get; set; } = 1500; + + public bool IsContentTitleBreakLine { get; set; } = true; + + public bool IsAutoCheckKeywords { get; set; } + + public int PhotoSmallWidth { get; set; } = 70; + + public int PhotoMiddleWidth { get; set; } = 400; + + /****************ͼƬˮӡ********************/ + + public bool IsWaterMark { get; set; } + + public bool IsImageWaterMark { get; set; } + + public int WaterMarkPosition { get; set; } = 9; + + public int WaterMarkTransparency { get; set; } = 5; + + public int WaterMarkMinWidth { get; set; } = 200; + + public int WaterMarkMinHeight { get; set; } = 200; + + public string WaterMarkFormatString { get; set; } + + public string WaterMarkFontName { get; set; } + + public int WaterMarkFontSize { get; set; } = 12; + + public string WaterMarkImagePath { get; set; } + + /****************ҳ********************/ + + public bool IsSeparatedWeb { get; set; } + + public string SeparatedWebUrl { get; set; } + + public string WebUrl => IsSeparatedWeb + ? PageUtils.AddEndSlashToUrl(SeparatedWebUrl) + : FxUtils.ParseNavigationUrl($"~/{SiteDir}"); + + public bool IsSeparatedAssets { get; set; } + + public string SeparatedAssetsUrl { get; set; } + + public string AssetsDir { get; set; } = "upload"; + + public string AssetsUrl => IsSeparatedAssets ? SeparatedAssetsUrl : PageUtils.Combine(WebUrl, AssetsDir); + + public string ChannelFilePathRule { get; set; } = "/channels/{@ChannelID}.html"; + + public string ContentFilePathRule { get; set; } = "/contents/{@ChannelID}/{@ContentID}.html"; + + public bool IsCreateContentIfContentChanged { get; set; } = true; + + public bool IsCreateChannelIfChannelChanged { get; set; } = true; + + public bool IsCreateShowPageInfo { get; set; } + + public bool IsCreateIe8Compatible { get; set; } + + public bool IsCreateBrowserNoCache { get; set; } + + public bool IsCreateJsIgnoreError { get; set; } + + public bool IsCreateWithJQuery { get; set; } = true; + + public bool IsCreateDoubleClick { get; set; } + + public int CreateStaticMaxPage { get; set; } = 10; + + public bool IsCreateUseDefaultFileName { get; set; } + + public string CreateDefaultFileName { get; set; } = "index.html"; + + public bool IsCreateStaticContentByAddDate { get; set; } + + public DateTime? CreateStaticContentAddDate { get; set; } + + /****************վת********************/ + + public bool IsCrossSiteTransChecked { get; set; } + + /****************¼ϵͳ********************/ + + public bool ConfigTemplateIsCodeMirror { get; set; } = true; + + public bool ConfigUEditorVideoIsImageUrl { get; set; } + + public bool ConfigUEditorVideoIsAutoPlay { get; set; } + + public bool ConfigUEditorVideoIsWidth { get; set; } + + public bool ConfigUEditorVideoIsHeight { get; set; } + + public string ConfigUEditorVideoPlayBy { get; set; } + + public int ConfigUEditorVideoWidth { get; set; } = 600; + + public int ConfigUEditorVideoHeight { get; set; } = 400; + + public bool ConfigUEditorAudioIsAutoPlay { get; set; } + + public string ConfigExportType { get; set; } + + public string ConfigExportPeriods { get; set; } + + public string ConfigExportDisplayAttributes { get; set; } + + public string ConfigExportIsChecked { get; set; } + + public string ConfigSelectImageCurrentUrl { get; set; } + + public string ConfigSelectVideoCurrentUrl { get; set; } + + public string ConfigSelectFileCurrentUrl { get; set; } + + public string ConfigUploadImageIsTitleImage { get; set; } = "True"; + + public string ConfigUploadImageTitleImageWidth { get; set; } = "300"; + + public string ConfigUploadImageTitleImageHeight { get; set; } + + public string ConfigUploadImageIsShowImageInTextEditor { get; set; } = "True"; + + public string ConfigUploadImageIsLinkToOriginal { get; set; } + + public string ConfigUploadImageIsSmallImage { get; set; } = "True"; + + public string ConfigUploadImageSmallImageWidth { get; set; } = "500"; + + public string ConfigUploadImageSmallImageHeight { get; set; } + + public bool ConfigImageIsFix { get; set; } = true; + + public string ConfigImageFixWidth { get; set; } = "300"; + + public string ConfigImageFixHeight { get; set; } + + public bool ConfigImageIsEditor { get; set; } = true; + + public bool ConfigImageEditorIsFix { get; set; } = true; + + public string ConfigImageEditorFixWidth { get; set; } = "500"; + + public string ConfigImageEditorFixHeight { get; set; } + + public bool ConfigImageEditorIsLinkToOriginal { get; set; } + + /****************ϴ*************************/ + + public string ImageUploadDirectoryName { get; set; } = "upload/images"; + + public string ImageUploadDateFormatString { get; set; } = EDateFormatTypeUtils.GetValue(EDateFormatType.Month); + + public bool IsImageUploadChangeFileName { get; set; } = true; + + public string ImageUploadTypeCollection { get; set; } = "gif|jpg|jpeg|bmp|png|pneg|swf|webp"; + + public int ImageUploadTypeMaxSize { get; set; } = 15360; + + public string VideoUploadDirectoryName { get; set; } = "upload/videos"; + + public string VideoUploadDateFormatString { get; set; } = EDateFormatTypeUtils.GetValue(EDateFormatType.Month); + + public bool IsVideoUploadChangeFileName { get; set; } = true; + + public string VideoUploadTypeCollection { get; set; } = + "asf|asx|avi|flv|mid|midi|mov|mp3|mp4|mpg|mpeg|ogg|ra|rm|rmb|rmvb|rp|rt|smi|swf|wav|webm|wma|wmv|viv"; + + public int VideoUploadTypeMaxSize { get; set; } = 307200; + + public string FileUploadDirectoryName { get; set; } = "upload/files"; + + public string FileUploadDateFormatString { get; set; } = EDateFormatTypeUtils.GetValue(EDateFormatType.Month); + + public bool IsFileUploadChangeFileName { get; set; } = true; + + public string FileUploadTypeCollection { get; set; } = "zip,rar,7z,js,css,txt,doc,docx,ppt,pptx,xls,xlsx,pdf"; + + public int FileUploadTypeMaxSize { get; set; } = 307200; + + /****************ģԴļ*************************/ + + public string TemplatesAssetsIncludeDir { get; set; } = "include"; + + public string TemplatesAssetsJsDir { get; set; } = "js"; + + public string TemplatesAssetsCssDir { get; set; } = "css"; + } +} diff --git a/net452/SiteServer.CMS/Database/Models/SiteInfo.cs b/net452/SiteServer.CMS/Database/Models/SiteInfo.cs new file mode 100644 index 000000000..8c4cde31b --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/SiteInfo.cs @@ -0,0 +1,36 @@ +using Datory; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_Site")] + public partial class SiteInfo: Entity, ISiteInfo + { + [TableColumn] + public string SiteDir { get; set; } + + [TableColumn] + public string SiteName { get; set; } + + [TableColumn] + public string TableName { get; set; } + + [TableColumn] + private string IsRoot { get; set; } + + public bool Root + { + get => IsRoot == "True"; + set => IsRoot = value.ToString(); + } + + [TableColumn] + public int ParentId { get; set; } + + [TableColumn] + public int Taxis { get; set; } + + [TableColumn(Text = true, Extend = true)] + public string SettingsXml { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/SiteLogInfo.cs b/net452/SiteServer.CMS/Database/Models/SiteLogInfo.cs new file mode 100644 index 000000000..a1e3b9f80 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/SiteLogInfo.cs @@ -0,0 +1,33 @@ +using System; +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_SiteLog")] + public class SiteLogInfo : Entity + { + [TableColumn] + public int SiteId { get; set; } + + [TableColumn] + public int ChannelId { get; set; } + + [TableColumn] + public int ContentId { get; set; } + + [TableColumn] + public string UserName { get; set; } + + [TableColumn] + public string IpAddress { get; set; } + + [TableColumn] + public DateTime? AddDate { get; set; } + + [TableColumn] + public string Action { get; set; } + + [TableColumn] + public string Summary { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/SitePermissionsInfo.cs b/net452/SiteServer.CMS/Database/Models/SitePermissionsInfo.cs new file mode 100644 index 000000000..934e6c9f5 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/SitePermissionsInfo.cs @@ -0,0 +1,23 @@ +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_SitePermissions")] + public class SitePermissionsInfo : Entity + { + [TableColumn] + public string RoleName { get; set; } + + [TableColumn] + public int SiteId { get; set; } + + [TableColumn(Text = true)] + public string ChannelIdCollection { get; set; } + + [TableColumn(Text = true)] + public string ChannelPermissions { get; set; } + + [TableColumn(Text = true)] + public string WebsitePermissions { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/SpecialInfo.cs b/net452/SiteServer.CMS/Database/Models/SpecialInfo.cs new file mode 100644 index 000000000..0caaa0973 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/SpecialInfo.cs @@ -0,0 +1,21 @@ +using System; +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_Special")] + public class SpecialInfo : Entity + { + [TableColumn] + public int SiteId { get; set; } + + [TableColumn] + public string Title { get; set; } + + [TableColumn] + public string Url { get; set; } + + [TableColumn] + public DateTime? AddDate { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/TableInfo.cs b/net452/SiteServer.CMS/Database/Models/TableInfo.cs new file mode 100644 index 000000000..737a48963 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/TableInfo.cs @@ -0,0 +1,45 @@ +namespace SiteServer.CMS.Database.Models +{ + public class TableInfo + { + public TableInfo() + { + Id = 0; + TableName = string.Empty; + DisplayName = string.Empty; + AttributeNum = 0; + IsCreatedInDb = false; + IsChangedAfterCreatedInDb = false; + IsDefault = false; + Description = string.Empty; + } + + public TableInfo(int id, string tableName, string displayName, int attributeNum, bool isCreatedInDb, bool isChangedAfterCreatedInDb, bool isDefault, string description) + { + Id = id; + TableName = tableName; + DisplayName = displayName; + AttributeNum = attributeNum; + IsCreatedInDb = isCreatedInDb; + IsChangedAfterCreatedInDb = isChangedAfterCreatedInDb; + IsDefault = isDefault; + Description = description; + } + + public int Id { get; set; } + + public string TableName { get; set; } + + public string DisplayName { get; set; } + + public int AttributeNum { get; set; } + + public bool IsCreatedInDb { get; set; } + + public bool IsChangedAfterCreatedInDb { get; set; } + + public bool IsDefault { get; set; } + + public string Description { get; set; } + } +} diff --git a/SiteServer.CMS/Model/TableMetadataInfo.cs b/net452/SiteServer.CMS/Database/Models/TableMetadataInfo.cs similarity index 96% rename from SiteServer.CMS/Model/TableMetadataInfo.cs rename to net452/SiteServer.CMS/Database/Models/TableMetadataInfo.cs index a5484bba1..6cc0a8128 100644 --- a/SiteServer.CMS/Model/TableMetadataInfo.cs +++ b/net452/SiteServer.CMS/Database/Models/TableMetadataInfo.cs @@ -1,7 +1,7 @@ using System; using SiteServer.Plugin; -namespace SiteServer.CMS.Model +namespace SiteServer.CMS.Database.Models { [Serializable] public class TableMetadataInfo @@ -20,7 +20,7 @@ public TableMetadataInfo() _tableName = string.Empty; _attributeName = string.Empty; _dataType = DataType.VarChar; - _dataLength = 50; + _dataLength = 2000; _taxis = 0; _isSystem = false; } diff --git a/net452/SiteServer.CMS/Database/Models/TableStyleInfo.Extend.cs b/net452/SiteServer.CMS/Database/Models/TableStyleInfo.Extend.cs new file mode 100644 index 000000000..a634eecea --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/TableStyleInfo.Extend.cs @@ -0,0 +1,41 @@ +using System.Collections.Generic; + +namespace SiteServer.CMS.Database.Models +{ + public partial class TableStyleInfo + { + public List StyleItems { get; set; } + + public int Height { get; set; } + + public string Width { get; set; } + + public int Columns { get; set; } + + public bool FormatString { get; set; } + + public int RelatedFieldId { get; set; } + + public string RelatedFieldStyle { get; set; } + + public string CustomizeLeft { get; set; } + + public string CustomizeRight { get; set; } + + public bool Validate { get; set; } + + public bool Required { get; set; } + + public int MinNum { get; set; } + + public int MaxNum { get; set; } + + public string ValidateType { get; set; } = SiteServer.Plugin.ValidateType.None.Value; + + public string RegExp { get; set; } + + public string ErrorMessage { get; set; } + + public string VeeValidate { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/TableStyleInfo.cs b/net452/SiteServer.CMS/Database/Models/TableStyleInfo.cs new file mode 100644 index 000000000..5bde062c6 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/TableStyleInfo.cs @@ -0,0 +1,61 @@ +using Datory; +using SiteServer.CMS.Core; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_TableStyle")] + public partial class TableStyleInfo : Entity + { + [TableColumn] + public int RelatedIdentity { get; set; } + + [TableColumn] + public string TableName { get; set; } + + [TableColumn] + public string AttributeName { get; set; } + + [TableColumn] + public int Taxis { get; set; } + + [TableColumn] + public string DisplayName { get; set; } + + [TableColumn] + public string HelpText { get; set; } + + [TableColumn] + private string IsVisibleInList { get; set; } + + public bool VisibleInList + { + get => IsVisibleInList == "True"; + set => IsVisibleInList = value.ToString(); + } + + [TableColumn] + private string InputType { get; set; } + + public InputType Type + { + get => InputTypeUtils.GetEnumType(InputType); + set => InputType = value.Value; + } + + [TableColumn] + public string DefaultValue { get; set; } + + [TableColumn] + private string IsHorizontal { get; set; } + + public bool Horizontal + { + get => IsHorizontal == "True"; + set => IsHorizontal = value.ToString(); + } + + [TableColumn(Text = true, Extend = true)] + public string ExtendValues { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/TableStyleItemInfo.cs b/net452/SiteServer.CMS/Database/Models/TableStyleItemInfo.cs new file mode 100644 index 000000000..4e83eaa71 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/TableStyleItemInfo.cs @@ -0,0 +1,26 @@ +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_TableStyleItem")] + public class TableStyleItemInfo : Entity + { + [TableColumn] + public int TableStyleId { get; set; } + + [TableColumn] + public string ItemTitle { get; set; } + + [TableColumn] + public string ItemValue { get; set; } + + [TableColumn] + private string IsSelected { get; set; } + + public bool Selected + { + get => IsSelected == "True"; + set => IsSelected = value.ToString(); + } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/TagInfo.cs b/net452/SiteServer.CMS/Database/Models/TagInfo.cs new file mode 100644 index 000000000..c40ddd689 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/TagInfo.cs @@ -0,0 +1,23 @@ +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_Tag")] + public class TagInfo : Entity + { + [TableColumn] + public int SiteId { get; set; } + + [TableColumn] + public string ContentIdCollection { get; set; } + + [TableColumn] + public string Tag { get; set; } + + [TableColumn] + public int UseNum { get; set; } + + [TableColumn] + public int Level { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/TemplateInfo.cs b/net452/SiteServer.CMS/Database/Models/TemplateInfo.cs new file mode 100644 index 000000000..dab7330e4 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/TemplateInfo.cs @@ -0,0 +1,45 @@ +using Datory; +using SiteServer.CMS.Core; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_Template")] + public class TemplateInfo : Entity + { + [TableColumn] + public int SiteId { get; set; } + + [TableColumn] + public string TemplateName { get; set; } + + [TableColumn] + private string TemplateType { get; set; } + + public TemplateType Type + { + get => TemplateTypeUtils.GetEnumType(TemplateType); + set => TemplateType = value.Value; + } + + [TableColumn] + public string RelatedFileName { get; set; } + + [TableColumn] + public string CreatedFileFullName { get; set; } + + [TableColumn] + public string CreatedFileExtName { get; set; } + + [TableColumn] + private string IsDefault { get; set; } + + public bool Default + { + get => IsDefault == "True"; + set => IsDefault = value.ToString(); + } + + public string Content { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/TemplateLogInfo.cs b/net452/SiteServer.CMS/Database/Models/TemplateLogInfo.cs new file mode 100644 index 000000000..a550261f7 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/TemplateLogInfo.cs @@ -0,0 +1,27 @@ +using System; +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_TemplateLog")] + public class TemplateLogInfo : Entity + { + [TableColumn] + public int TemplateId { get; set; } + + [TableColumn] + public int SiteId { get; set; } + + [TableColumn] + public DateTime? AddDate { get; set; } + + [TableColumn] + public string AddUserName { get; set; } + + [TableColumn] + public int ContentLength { get; set; } + + [TableColumn(Text = true)] + public string TemplateContent { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/UserGroupInfo.cs b/net452/SiteServer.CMS/Database/Models/UserGroupInfo.cs new file mode 100644 index 000000000..d310a0645 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/UserGroupInfo.cs @@ -0,0 +1,14 @@ +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_UserGroup")] + public class UserGroupInfo : Entity + { + [TableColumn] + public string GroupName { get; set; } + + [TableColumn] + public string AdminName { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/UserInfo.cs b/net452/SiteServer.CMS/Database/Models/UserInfo.cs new file mode 100644 index 000000000..0d4da9555 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/UserInfo.cs @@ -0,0 +1,198 @@ +using System; +using Datory; +using Newtonsoft.Json; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_User")] + public class UserInfo : Entity, IUserInfo + { + /// + /// 用户名。 + /// + [TableColumn] + public string UserName { get; set; } + + /// + /// 密码。 + /// + [TableColumn] + [JsonIgnore] + public string Password { get; set; } + + /// + /// 加密格式。 + /// + [TableColumn] + [JsonIgnore] + public string PasswordFormat { get; set; } + + /// + /// 秘钥。 + /// + [TableColumn] + [JsonIgnore] + public string PasswordSalt { get; set; } + + /// + /// 创建时间。 + /// + [TableColumn] + public DateTime? CreateDate { get; set; } + + /// + /// 最后一次重设密码时间。 + /// + [TableColumn] + public DateTime? LastResetPasswordDate { get; set; } + + /// + /// 最后活动时间。 + /// + [TableColumn] + public DateTime? LastActivityDate { get; set; } + + /// + /// 用户组Id。 + /// + [TableColumn] + public int GroupId { get; set; } + + /// + /// 登录次数。 + /// + [TableColumn] + public int CountOfLogin { get; set; } + + /// + /// 连续登录失败次数。 + /// + [TableColumn] + public int CountOfFailedLogin { get; set; } + + /// + /// 是否已审核用户。 + /// + [TableColumn] + private string IsChecked { get; set; } + + public bool Checked + { + get => IsChecked == "True"; + set => IsChecked = value.ToString(); + } + + /// + /// 是否被锁定。 + /// + [TableColumn] + private string IsLockedOut { get; set; } + + public bool Locked + { + get => IsLockedOut == "True"; + set => IsLockedOut = value.ToString(); + } + + /// + /// 姓名。 + /// + [TableColumn] + public string DisplayName { get; set; } + + /// + /// 手机号。 + /// + [TableColumn] + public string Mobile { get; set; } + + /// + /// 邮箱。 + /// + [TableColumn] + public string Email { get; set; } + + /// + /// 头像图片路径。 + /// + [TableColumn] + public string AvatarUrl { get; set; } + + /// + /// 性别。 + /// + [TableColumn] + public string Gender { get; set; } + + /// + /// 出生日期。 + /// + [TableColumn] + public string Birthday { get; set; } + + /// + /// 微信。 + /// + [TableColumn] + public string WeiXin { get; set; } + + /// + /// QQ。 + /// + [TableColumn] + public string Qq { get; set; } + + /// + /// 微博。 + /// + [TableColumn] + public string WeiBo { get; set; } + + /// + /// 简介。 + /// + [TableColumn(Text = true)] + public string Bio { get; set; } + + /// + /// 附加字段。 + /// + [TableColumn(Text = true, Extend = true)] + public string SettingsXml { get; set; } + + //public Dictionary ToDictionary() + //{ + // var dict = base.ToDictionary(); + + // var styleInfoList = TableStyleManager.GetUserStyleInfoList(); + + // foreach (var styleInfo in styleInfoList) + // { + // dict.Remove(styleInfo.AttributeName); + // dict[styleInfo.AttributeName] = Get(styleInfo.AttributeName); + // } + + // foreach (var attributeName in UserAttribute.AllAttributes.Value) + // { + // if (StringUtils.StartsWith(attributeName, "Is")) + // { + // dict.Remove(attributeName); + // dict[attributeName] = GetBool(attributeName); + // } + // else + // { + // dict.Remove(attributeName); + // dict[attributeName] = Get(attributeName); + // } + // } + + // foreach (var attributeName in UserAttribute.ExcludedAttributes.Value) + // { + // dict.Remove(attributeName); + // } + + // return dict; + //} + } +} diff --git a/net452/SiteServer.CMS/Database/Models/UserLogInfo.cs b/net452/SiteServer.CMS/Database/Models/UserLogInfo.cs new file mode 100644 index 000000000..dbd591a97 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/UserLogInfo.cs @@ -0,0 +1,25 @@ +using System; +using Datory; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_UserLog")] + public class UserLogInfo : Entity, ILogInfo + { + [TableColumn] + public string UserName { get; set; } + + [TableColumn] + public string IpAddress { get; set; } + + [TableColumn] + public DateTime? AddDate { get; set; } + + [TableColumn] + public string Action { get; set; } + + [TableColumn] + public string Summary { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/Models/UserMenuInfo.cs b/net452/SiteServer.CMS/Database/Models/UserMenuInfo.cs new file mode 100644 index 000000000..4b72b8e2f --- /dev/null +++ b/net452/SiteServer.CMS/Database/Models/UserMenuInfo.cs @@ -0,0 +1,41 @@ +using Datory; + +namespace SiteServer.CMS.Database.Models +{ + [Table("siteserver_UserMenu")] + public class UserMenuInfo : Entity + { + [TableColumn] + public string SystemId { get; set; } + + [TableColumn] + public string GroupIdCollection { get; set; } + + [TableColumn] + private string IsDisabled { get; set; } + + public bool Disabled + { + get => IsDisabled == "True"; + set => IsDisabled = value.ToString(); + } + + [TableColumn] + public int ParentId { get; set; } + + [TableColumn] + public int Taxis { get; set; } + + [TableColumn] + public string Text { get; set; } + + [TableColumn] + public string IconClass { get; set; } + + [TableColumn] + public string Href { get; set; } + + [TableColumn] + public string Target { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Database/MySql.cs b/net452/SiteServer.CMS/Database/MySql.cs new file mode 100644 index 000000000..d5b105609 --- /dev/null +++ b/net452/SiteServer.CMS/Database/MySql.cs @@ -0,0 +1,135 @@ +using System; +using System.Data; +using System.IO; +using System.Xml; +using MySql.Data.MySqlClient; +using SiteServer.CMS.Apis; + +namespace SiteServer.CMS.Database.Core +{ + public class MySql : DatabaseApi + { + //public override IDataParameter[] GetDataParameters(int size) + //{ + // return new MySqlParameter[size]; + ////} + + //public override IDbConnection GetConnection(string connectionString) + //{ + // return new MySqlConnection(connectionString); + //} + + + + //public override IDbDataAdapter GetDataAdapter() + //{ + // return new MySqlDataAdapter(); + //} + + + + //public override void DeriveParameters(IDbCommand cmd) + //{ + // bool mustCloseConnection = false; + + + // if (!(cmd is MySqlCommand)) + // throw new ArgumentException("The command provided is not a SqlCommand instance.", "cmd"); + + + // if (cmd.Connection.State != ConnectionState.Open) + // { + // cmd.Connection.Open(); + // mustCloseConnection = true; + // } + + + // MySqlCommandBuilder.DeriveParameters((MySqlCommand)cmd); + + + // if (mustCloseConnection) + // { + // cmd.Connection.Close(); + // } + //} + + + + //public override IDataParameter GetParameter() + //{ + // return new MySqlParameter(); + //} + + + + //public override void ClearCommand(IDbCommand command) + //{ + // // HACK: There is a problem here, the output parameter values are fletched + // // when the reader is closed, so if the parameters are detached from the command + // // then the IDataReader can磘 set its values. + // // When this happen, the parameters can磘 be used again in other command. + // bool canClear = true; + + + // foreach (IDataParameter commandParameter in command.Parameters) + // { + // if (commandParameter.Direction != ParameterDirection.Input) + // canClear = false; + + + // } + // if (canClear) + // { + // command.Parameters.Clear(); + // } + //} + + + + //public override void CleanParameterSyntax(IDbCommand command) + //{ + // // do nothing for SQL + //} + + + + //public override XmlReader ExecuteXmlReader(IDbCommand command) + //{ + // bool mustCloseConnection = false; + + + // if (command.Connection.State != ConnectionState.Open) + // { + // command.Connection.Open(); + // mustCloseConnection = true; + // } + + + // CleanParameterSyntax(command); + // MySqlDataAdapter da = new MySqlDataAdapter((MySqlCommand)command); + // DataSet ds = new DataSet(); + + + // da.MissingSchemaAction = MissingSchemaAction.AddWithKey; + // da.Fill(ds); + + + // StringReader stream = new StringReader(ds.GetXml()); + // if (mustCloseConnection) + // { + // command.Connection.Close(); + // } + + + // return new XmlTextReader(stream); + //} + + + + //protected override IDataParameter GetBlobParameter(IDbConnection connection, IDataParameter p) + //{ + // // do nothing special for BLOBs...as far as we know now. + // return p; + //} + } +} diff --git a/net452/SiteServer.CMS/Database/Oracle.cs b/net452/SiteServer.CMS/Database/Oracle.cs new file mode 100644 index 000000000..527f9141a --- /dev/null +++ b/net452/SiteServer.CMS/Database/Oracle.cs @@ -0,0 +1,188 @@ +using System; +using System.Data; +using System.IO; +using System.Xml; +using Datory; +using Oracle.ManagedDataAccess.Client; +using SiteServer.CMS.Apis; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Core +{ + public class Oracle : DatabaseApi + { + //public override IDataParameter[] GetDataParameters(int size) + //{ + // return new OracleParameter[size]; + ////} + + //public override IDbConnection GetConnection(string connectionString) + //{ + // return new OracleConnection(connectionString); + //} + + //public override IDbDataAdapter GetDataAdapter() + //{ + // return new OracleDataAdapter(); + //} + + //public override void DeriveParameters(IDbCommand cmd) + //{ + // bool mustCloseConnection = false; + + + // if (!(cmd is OracleCommand)) + // throw new ArgumentException("The command provided is not a SqlCommand instance.", "cmd"); + + + // if (cmd.Connection.State != ConnectionState.Open) + // { + // cmd.Connection.Open(); + // mustCloseConnection = true; + // } + + + // OracleCommandBuilder.DeriveParameters((OracleCommand)cmd); + + + // if (mustCloseConnection) + // { + // cmd.Connection.Close(); + // } + //} + + //public override IDataParameter GetParameter() + //{ + // return new OracleParameter(); + //} + + //public override IDataParameter GetParameter(string name, object value) + //{ + // var parameter = new OracleParameter + // { + // ParameterName = name + // }; + // if (value == null) + // { + // parameter.DbType = DbType.String; + // parameter.Value = null; + // } + // else if (value is DateTime) + // { + // parameter.DbType = DbType.DateTime; + // var dbValue = (DateTime)value; + // if (dbValue < DateUtils.SqlMinValue) + // { + // dbValue = DateUtils.SqlMinValue; + // } + // parameter.Value = dbValue; + // } + // else if (value is int) + // { + // parameter.DbType = DbType.Int32; + // parameter.Value = (int)value; + // } + // else if (value is decimal) + // { + // parameter.DbType = DbType.Decimal; + // parameter.Value = (decimal)value; + // } + // else if (value is string) + // { + // parameter.DbType = DbType.String; + // parameter.Value = SqlUtils.ToOracleDbValue(DataType.VarChar, value); + // //parameter.Value = (string)value; + // } + // else if (value is bool) + // { + // parameter.DbType = DbType.Int32; + // parameter.Value = (bool)value ? 1 : 0; + // } + // else + // { + // parameter.DbType = DbType.String; + // parameter.Value = SqlUtils.ToOracleDbValue(DataType.VarChar, value.ToString()); + // //parameter.Value = value.ToString(); + // } + + // return parameter; + //} + + public override void ClearCommand(IDbCommand command) + { + // HACK: There is a problem here, the output parameter values are fletched + // when the reader is closed, so if the parameters are detached from the command + // then the IDataReader can磘 set its values. + // When this happen, the parameters can磘 be used again in other command. + bool canClear = true; + + + foreach (IDataParameter commandParameter in command.Parameters) + { + if (commandParameter.Direction != ParameterDirection.Input) + canClear = false; + + + } + if (canClear) + { + command.Parameters.Clear(); + } + } + + public override void CleanParameterSyntax(IDbCommand command) + { + // do nothing for SQL + } + + public override XmlReader ExecuteXmlReader(IDbCommand command) + { + bool mustCloseConnection = false; + + + if (command.Connection.State != ConnectionState.Open) + { + command.Connection.Open(); + mustCloseConnection = true; + } + + + CleanParameterSyntax(command); + OracleDataAdapter da = new OracleDataAdapter((OracleCommand)command); + DataSet ds = new DataSet(); + + + da.MissingSchemaAction = MissingSchemaAction.AddWithKey; + da.Fill(ds); + + + StringReader stream = new StringReader(ds.GetXml()); + if (mustCloseConnection) + { + command.Connection.Close(); + } + + + return new XmlTextReader(stream); + } + + + + protected override IDataParameter GetBlobParameter(IDbConnection connection, IDataParameter p) + { + // do nothing special for BLOBs...as far as we know now. + return p; + } + + public override string GetString(IDataReader rdr, int i) + { + var retVal = base.GetString(rdr, i); + + if (retVal == StringUtils.Constants.OracleEmptyValue) + { + retVal = string.Empty; + } + return retVal; + } + } +} diff --git a/net452/SiteServer.CMS/Database/PostgreSql.cs b/net452/SiteServer.CMS/Database/PostgreSql.cs new file mode 100644 index 000000000..2c71affbd --- /dev/null +++ b/net452/SiteServer.CMS/Database/PostgreSql.cs @@ -0,0 +1,123 @@ +using System; +using System.Data; +using System.IO; +using System.Xml; +using Npgsql; +using SiteServer.CMS.Apis; + +namespace SiteServer.CMS.Database.Core +{ + public class PostgreSql : DatabaseApi + { + //public override IDataParameter[] GetDataParameters(int size) + //{ + // return new NpgsqlParameter[size]; + //} + + //public override IDbConnection GetConnection(string connectionString) + //{ + // return new NpgsqlConnection(connectionString); + //} + + //public override IDbDataAdapter GetDataAdapter() + //{ + // return new NpgsqlDataAdapter(); + //} + + //public override void DeriveParameters(IDbCommand cmd) + //{ + // bool mustCloseConnection = false; + + + // if (!(cmd is NpgsqlCommand)) + // throw new ArgumentException("The command provided is not a SqlCommand instance.", "cmd"); + + + // if (cmd.Connection.State != ConnectionState.Open) + // { + // cmd.Connection.Open(); + // mustCloseConnection = true; + // } + + + // NpgsqlCommandBuilder.DeriveParameters((NpgsqlCommand)cmd); + + + // if (mustCloseConnection) + // { + // cmd.Connection.Close(); + // } + //} + + //public override IDataParameter GetParameter() + //{ + // return new NpgsqlParameter(); + //} + + public override void ClearCommand(IDbCommand command) + { + // HACK: There is a problem here, the output parameter values are fletched + // when the reader is closed, so if the parameters are detached from the command + // then the IDataReader can磘 set its values. + // When this happen, the parameters can磘 be used again in other command. + bool canClear = true; + + + foreach (IDataParameter commandParameter in command.Parameters) + { + if (commandParameter.Direction != ParameterDirection.Input) + canClear = false; + + + } + if (canClear) + { + command.Parameters.Clear(); + } + } + + public override void CleanParameterSyntax(IDbCommand command) + { + // do nothing for SQL + } + + public override XmlReader ExecuteXmlReader(IDbCommand command) + { + bool mustCloseConnection = false; + + + if (command.Connection.State != ConnectionState.Open) + { + command.Connection.Open(); + mustCloseConnection = true; + } + + + CleanParameterSyntax(command); + NpgsqlDataAdapter da = new NpgsqlDataAdapter((NpgsqlCommand)command); + DataSet ds = new DataSet(); + + + da.MissingSchemaAction = MissingSchemaAction.AddWithKey; + da.Fill(ds); + + + StringReader stream = new StringReader(ds.GetXml()); + if (mustCloseConnection) + { + command.Connection.Close(); + } + + + return new XmlTextReader(stream); + } + + + + protected override IDataParameter GetBlobParameter(IDbConnection connection, IDataParameter p) + { + // do nothing special for BLOBs...as far as we know now. + return p; + } + } +} diff --git a/net452/SiteServer.CMS/Database/Repositories/AccessTokenRepository.cs b/net452/SiteServer.CMS/Database/Repositories/AccessTokenRepository.cs new file mode 100644 index 000000000..2d92a3af2 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/AccessTokenRepository.cs @@ -0,0 +1,81 @@ +using System; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class AccessTokenRepository : Repository + { + public AccessTokenRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Title = nameof(AccessTokenInfo.Title); + } + + public override int Insert(AccessTokenInfo accessTokenInfo) + { + accessTokenInfo.Token = TranslateUtils.EncryptStringBySecretKey(StringUtils.GetGuid()); + accessTokenInfo.AddDate = DateTime.Now; + + accessTokenInfo.Id = base.Insert(accessTokenInfo); + if (accessTokenInfo.Id > 0) + { + AccessTokenManager.ClearCache(); + } + return accessTokenInfo.Id; + } + + public override bool Update(AccessTokenInfo accessTokenInfo) + { + var updated = base.Update(accessTokenInfo); + if (updated) + { + AccessTokenManager.ClearCache(); + } + return updated; + } + + public override bool Delete(int id) + { + var deleted = base.Delete(id); + if (deleted) + { + AccessTokenManager.ClearCache(); + } + return deleted; + } + + public string Regenerate(AccessTokenInfo accessTokenInfo) + { + accessTokenInfo.Token = TranslateUtils.EncryptStringBySecretKey(StringUtils.GetGuid()); + + Update(accessTokenInfo); + + return accessTokenInfo.Token; + } + + public bool IsTitleExists(string title) + { + return Exists(Q.Where(Attr.Title, title)); + //bool exists; + + //using (var connection = GetConnection()) + //{ + // exists = connection.ExecuteScalar($"SELECT COUNT(1) FROM {TableName} WHERE {nameof(AccessTokenInfo.Title)} = @{nameof(AccessTokenInfo.Title)}", new + // { + // Title = title + // }); + //} + + //return exists; + } + + + } + +} diff --git a/net452/SiteServer.CMS/Database/Repositories/AdministratorRepository.cs b/net452/SiteServer.CMS/Database/Repositories/AdministratorRepository.cs new file mode 100644 index 000000000..e60c3fca7 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/AdministratorRepository.cs @@ -0,0 +1,893 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Auth; +using SiteServer.Utils.Enumerations; +using SqlKata; + +namespace SiteServer.CMS.Database.Repositories +{ + public class AdministratorRepository : Repository + { + public AdministratorRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(AdministratorInfo.Id); + public const string UserName = nameof(AdministratorInfo.UserName); + public const string DepartmentId = nameof(AdministratorInfo.DepartmentId); + public const string AreaId = nameof(AdministratorInfo.AreaId); + public const string Mobile = nameof(AdministratorInfo.Mobile); + public const string Email = nameof(AdministratorInfo.Email); + public const string Password = nameof(AdministratorInfo.Password); + public const string PasswordFormat = nameof(AdministratorInfo.PasswordFormat); + public const string PasswordSalt = nameof(AdministratorInfo.PasswordSalt); + public const string IsLockedOut = "IsLockedOut"; + } + + public int GetCount(Query query) + { + return Count(query); + } + + public int GetCount() + { + return Count(); + } + + public int Insert(AdministratorInfo adminInfo, out string errorMessage) + { + if (!InsertValidate(adminInfo.UserName, adminInfo.Password, adminInfo.Email, adminInfo.Mobile, out errorMessage)) return 0; + + try + { + adminInfo.CreationDate = DateTime.Now; + adminInfo.PasswordFormat = EPasswordFormatUtils.GetValue(EPasswordFormat.Encrypted); + adminInfo.Password = EncodePassword(adminInfo.Password, EPasswordFormatUtils.GetEnumType(adminInfo.PasswordFormat), out var passwordSalt); + adminInfo.PasswordSalt = passwordSalt; + + var identity = Insert(adminInfo); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamUsername, adminInfo.UserName), + // GetParameter(ParamPassword, adminInfo.Password), + // GetParameter(ParamPasswordFormat, adminInfo.PasswordFormat), + // GetParameter(ParamPasswordSalt, adminInfo.PasswordSalt), + // GetParameter(ParamCreationDate, adminInfo.CreationDate), + // GetParameter(ParamLastActivityDate, adminInfo.LastActivityDate), + // GetParameter(ParamCountOfLogin, adminInfo.CountOfLogin), + // GetParameter(ParamCountOfFailedLogin, adminInfo.CountOfFailedLogin), + // GetParameter(ParamCreatorUsername, adminInfo.CreatorUserName), + // GetParameter(ParamIsLockedOut, adminInfo.IsLockedOut.ToString()), + // GetParameter(ParamSiteIdCollection, adminInfo.SiteIdCollection), + // GetParameter(ParamSiteId, adminInfo.SiteId), + // GetParameter(ParamDepartmentId, adminInfo.DepartmentId), + // GetParameter(ParamAreaId, adminInfo.AreaId), + // GetParameter(ParamDisplayName, adminInfo.DisplayName), + // GetParameter(ParamMobile, adminInfo.Mobile), + // GetParameter(ParamEmail, adminInfo.Email), + // GetParameter(ParamAvatarUrl, adminInfo.AvatarUrl) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlInsertUser, parameters); + + if (identity <= 0) return 0; + + DataProvider.Department.UpdateCountOfAdmin(); + DataProvider.Area.UpdateCountOfAdmin(); + + //var roles = new[] { EPredefinedRoleUtils.GetValueById(EPredefinedRole.Administrator) }; + //DataProvider.AdministratorsInRoles.AddUserToRoles(adminInfo.UserName, roles); + + DataProvider.AdministratorsInRoles.AddUserToRole(adminInfo.UserName, EPredefinedRoleUtils.GetValue(EPredefinedRole.Administrator)); + + return identity; + } + catch (Exception ex) + { + errorMessage = ex.Message; + return 0; + } + } + + public bool Update(AdministratorInfo administratorInfo, out string errorMessage) + { + var adminInfo = AdminManager.GetAdminInfoByUserId(administratorInfo.Id); + + administratorInfo.Password = adminInfo.Password; + administratorInfo.PasswordFormat = adminInfo.PasswordFormat; + administratorInfo.PasswordSalt = adminInfo.PasswordSalt; + + if (!UpdateValidate(administratorInfo, adminInfo.UserName, adminInfo.Email, adminInfo.Mobile, out errorMessage)) return false; + + var updated = Update(administratorInfo); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamLastActivityDate, administratorInfo.LastActivityDate), + // GetParameter(ParamCountOfLogin, administratorInfo.CountOfLogin), + // GetParameter(ParamCountOfFailedLogin, administratorInfo.CountOfFailedLogin), + // GetParameter(ParamIsLockedOut, administratorInfo.IsLockedOut.ToString()), + // GetParameter(ParamSiteIdCollection, administratorInfo.SiteIdCollection), + // GetParameter(ParamSiteId, administratorInfo.SiteId), + // GetParameter(ParamDepartmentId, administratorInfo.DepartmentId), + // GetParameter(ParamAreaId, administratorInfo.AreaId), + // GetParameter(ParamDisplayName, administratorInfo.DisplayName), + // GetParameter(ParamMobile, administratorInfo.Mobile), + // GetParameter(ParamEmail, administratorInfo.Email), + // GetParameter(ParamAvatarUrl, administratorInfo.AvatarUrl), + // GetParameter(ParamUsername, administratorInfo.UserName) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdateUser, parameters); + + if (updated) + { + DataProvider.Department.UpdateCountOfAdmin(); + DataProvider.Area.UpdateCountOfAdmin(); + + AdminManager.UpdateCache(administratorInfo); + } + + return updated; + } + + public bool UpdateLastActivityDateAndCountOfFailedLogin(AdministratorInfo adminInfo) + { + if (adminInfo == null) return false; + + adminInfo.LastActivityDate = DateTime.Now; + adminInfo.CountOfFailedLogin += 1; + + //var sqlString = $"UPDATE {TableName} SET LastActivityDate = @LastActivityDate, CountOfFailedLogin = @CountOfFailedLogin WHERE Id = @Id"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamLastActivityDate, adminInfo.LastActivityDate), + // GetParameter(ParamCountOfFailedLogin, adminInfo.CountOfFailedLogin), + // GetParameter(ParamId, adminInfo.Id) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + var updated = Update(adminInfo, out _); + if (updated) + { + AdminManager.UpdateCache(adminInfo); + } + return updated; + } + + public void UpdateLastActivityDateAndCountOfLogin(AdministratorInfo adminInfo) + { + if (adminInfo == null) return; + + adminInfo.LastActivityDate = DateTime.Now; + adminInfo.CountOfLogin += 1; + adminInfo.CountOfFailedLogin = 0; + + //var sqlString = + // $"UPDATE {TableName} SET LastActivityDate = @LastActivityDate, CountOfLogin = @CountOfLogin, CountOfFailedLogin = @CountOfFailedLogin WHERE Id = @Id"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamLastActivityDate, adminInfo.LastActivityDate), + // GetParameter(ParamCountOfLogin, adminInfo.CountOfLogin), + // GetParameter(ParamCountOfFailedLogin, adminInfo.CountOfFailedLogin), + // GetParameter(ParamId, adminInfo.Id) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + var updated = Update(adminInfo, out _); + if (updated) + { + AdminManager.UpdateCache(adminInfo); + } + } + + public void UpdateSiteIdCollection(AdministratorInfo adminInfo, string siteIdCollection) + { + if (adminInfo == null) return; + + adminInfo.SiteIdCollection = siteIdCollection; + + //var sqlString = $"UPDATE {TableName} SET SiteIdCollection = @SiteIdCollection WHERE Id = @Id"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamSiteIdCollection, adminInfo.SiteIdCollection), + // GetParameter(ParamId, adminInfo.Id) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + var updated = Update(adminInfo, out _); + if (updated) + { + AdminManager.UpdateCache(adminInfo); + } + } + + public List UpdateSiteId(AdministratorInfo adminInfo, int siteId) + { + if (adminInfo == null) return null; + + var siteIdListLatestAccessed = TranslateUtils.StringCollectionToIntList(adminInfo.SiteIdCollection); + if (adminInfo.SiteId != siteId || siteIdListLatestAccessed.FirstOrDefault() != siteId) + { + siteIdListLatestAccessed.Remove(siteId); + siteIdListLatestAccessed.Insert(0, siteId); + + adminInfo.SiteIdCollection = TranslateUtils.ObjectCollectionToString(siteIdListLatestAccessed); + adminInfo.SiteId = siteId; + + //var sqlString = + // $"UPDATE {TableName} SET SiteIdCollection = @SiteIdCollection, SiteId = @SiteId WHERE Id = @Id"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamSiteIdCollection, adminInfo.SiteIdCollection), + // GetParameter(ParamSiteId, adminInfo.SiteId), + // GetParameter(ParamId, adminInfo.Id) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + //AdminManager.UpdateCache(adminInfo); + + if (Update(adminInfo, out _)) + { + AdminManager.UpdateCache(adminInfo); + } + } + + return siteIdListLatestAccessed; + } + + private void ChangePassword(AdministratorInfo adminInfo, EPasswordFormat passwordFormat, string passwordSalt, string password) + { + adminInfo.Password = password; + adminInfo.PasswordFormat = EPasswordFormatUtils.GetValue(passwordFormat); + adminInfo.PasswordSalt = passwordSalt; + + //UpdateValue(new Dictionary + //{ + // {Attr.Password, adminInfo.Password}, + // {Attr.PasswordFormat, adminInfo.PasswordFormat}, + // {Attr.PasswordSalt, adminInfo.PasswordSalt} + //}, Q.Where(nameof(Attr.Id), adminInfo.Id)); + + Update(adminInfo, Attr.Password, Attr.PasswordFormat, Attr.PasswordSalt); + + //var sqlString = + // $"UPDATE {TableName} SET Password = @Password, PasswordFormat = @PasswordFormat, PasswordSalt = @PasswordSalt WHERE Id = @Id"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamPassword, adminInfo.Password), + // GetParameter(ParamPasswordFormat, adminInfo.PasswordFormat), + // GetParameter(ParamPasswordSalt, adminInfo.PasswordSalt), + // GetParameter(ParamId, adminInfo.Id) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + AdminManager.RemoveCache(adminInfo); + } + + public bool Delete(AdministratorInfo adminInfo) + { + if (adminInfo == null) return false; + + var deleted = Delete(adminInfo.Id); + + //var sqlString = $"DELETE FROM {TableName} WHERE Id = @Id"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamId, adminInfo.Id) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + if (deleted) + { + AdminManager.RemoveCache(adminInfo); + + DataProvider.AdministratorsInRoles.RemoveUser(adminInfo.UserName); + DataProvider.Department.UpdateCountOfAdmin(); + DataProvider.Area.UpdateCountOfAdmin(); + } + + return deleted; + } + + public void Lock(List userIdList) + { + //var sqlString = + // $"UPDATE {TableName} SET IsLockedOut = '{true}' WHERE UserName IN ({TranslateUtils.ToSqlInStringWithQuote(userNameList)})"; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + //UpdateValue(new Dictionary + //{ + // {Attr.IsLockedOut, true.ToString()} + //}, Q.WhereIn(Attr.Id, userIdList)); + + Update(Q + .Set(Attr.IsLockedOut, true.ToString()) + .WhereIn(Attr.Id, userIdList) + ); + + AdminManager.ClearCache(); + } + + public void UnLock(List userIdList) + { + //var sqlString = + // $"UPDATE {TableName} SET IsLockedOut = '{false}', CountOfFailedLogin = 0 WHERE UserName IN ({TranslateUtils.ToSqlInStringWithQuote(userNameList)})"; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + //UpdateValue(new Dictionary + //{ + // {Attr.IsLockedOut, false.ToString()} + //}, Q.WhereIn(Attr.Id, userIdList)); + + Update(Q + .Set(Attr.IsLockedOut, false.ToString()) + .WhereIn(Attr.Id, userIdList) + ); + + AdminManager.ClearCache(); + } + + private AdministratorInfo GetByAccount(string account) + { + var administratorInfo = GetByUserName(account); + if (administratorInfo != null) return administratorInfo; + if (StringUtils.IsMobile(account)) return GetByMobile(account); + if (StringUtils.IsEmail(account)) return GetByEmail(account); + + return null; + } + + public AdministratorInfo GetByUserId(int userId) + { + return Get(userId); + //if (userId <= 0) return null; + + //AdministratorInfo info = null; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamId, userId) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectUserByUserId, parameters)) + //{ + // if (rdr.Read()) + // { + // var i = 0; + // info = new AdministratorInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), + // DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetDateTime(rdr, i++), DatabaseApi.GetDateTime(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), + // DatabaseApi.GetString(rdr, i++), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetString(rdr, i++), + // DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), + // DatabaseApi.GetString(rdr, i)); + // } + // rdr.Close(); + //} + + //return info; + } + + public AdministratorInfo GetByUserName(string userName) + { + return Get(Q.Where(Attr.UserName, userName)); + + //AdministratorInfo info = null; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamUsername, userName) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectUserByUserName, parameters)) + //{ + // if (rdr.Read()) + // { + // var i = 0; + // info = new AdministratorInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), + // DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetDateTime(rdr, i++), DatabaseApi.GetDateTime(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), + // DatabaseApi.GetString(rdr, i++), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetString(rdr, i++), + // DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), + // DatabaseApi.GetString(rdr, i)); + // } + // rdr.Close(); + //} + + //return info; + } + + public AdministratorInfo GetByMobile(string mobile) + { + return Get(Q.Where(Attr.Mobile, mobile)); + + //if (string.IsNullOrEmpty(mobile)) return null; + + //AdministratorInfo info = null; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamMobile, mobile) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectUserByMobile, parameters)) + //{ + // if (rdr.Read()) + // { + // var i = 0; + // info = new AdministratorInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), + // DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetDateTime(rdr, i++), DatabaseApi.GetDateTime(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), + // DatabaseApi.GetString(rdr, i++), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetString(rdr, i++), + // DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), + // DatabaseApi.GetString(rdr, i)); + // } + // rdr.Close(); + //} + + //return info; + } + + public AdministratorInfo GetByEmail(string email) + { + return Get(Q.Where(Attr.Email, email)); + //if (string.IsNullOrEmpty(email)) return null; + + //AdministratorInfo info = null; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamEmail, email) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectUserByEmail, parameters)) + //{ + // if (rdr.Read()) + // { + // var i = 0; + // info = new AdministratorInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), + // DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetDateTime(rdr, i++), DatabaseApi.GetDateTime(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), + // DatabaseApi.GetString(rdr, i++), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetString(rdr, i++), + // DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), + // DatabaseApi.GetString(rdr, i)); + // } + // rdr.Close(); + //} + + //return info; + } + + public bool IsUserNameExists(string adminName) + { + return Exists(Q.Where(Attr.UserName, adminName)); + //if (string.IsNullOrEmpty(adminName)) + //{ + // return false; + //} + + //var exists = false; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamUsername, adminName) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectUsername, parameters)) + //{ + // if (rdr.Read() && !rdr.IsDBNull(0)) + // { + // exists = true; + // } + // rdr.Close(); + //} + //return exists; + } + + public bool IsEmailExists(string email) + { + //if (string.IsNullOrEmpty(email)) return false; + + var exists = IsUserNameExists(email); + if (exists) return true; + + return Exists(Q + .Where(Attr.Email, email)); + + //var sqlSelect = $"SELECT {nameof(AdministratorInfo.Email)} FROM {TableName} WHERE {nameof(AdministratorInfo.Email)} = @{nameof(AdministratorInfo.Email)}"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamEmail, email) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlSelect, parameters)) + //{ + // if (rdr.Read()) + // { + // exists = true; + // } + // rdr.Close(); + //} + + //return exists; + } + + public bool IsMobileExists(string mobile) + { + //if (string.IsNullOrEmpty(mobile)) return false; + + var exists = IsUserNameExists(mobile); + if (exists) return true; + + return Exists(Q + .Where(Attr.Mobile, mobile)); + + //var sqlString = $"SELECT {nameof(AdministratorInfo.Mobile)} FROM {TableName} WHERE {nameof(AdministratorInfo.Mobile)} = @{nameof(AdministratorInfo.Mobile)}"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamMobile, mobile) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // exists = true; + // } + // rdr.Close(); + //} + + //return exists; + } + + public int GetCountByAreaId(int areaId) + { + return Count(Q + .Where(Attr.AreaId, areaId)); + //var sqlString = $"SELECT COUNT(*) FROM {TableName} WHERE {nameof(AdministratorInfo.AreaId)} = {areaId}"; + + //return DatabaseApi.Instance.GetIntResult(sqlString); + } + + public int GetCountByDepartmentId(int departmentId) + { + return Count(Q + .Where(Attr.DepartmentId, departmentId)); + //var sqlString = $"SELECT COUNT(*) FROM {TableName} WHERE {nameof(AdministratorInfo.DepartmentId)} = {departmentId}"; + + //return DatabaseApi.Instance.GetIntResult(sqlString); + } + + public IList GetUserNameList() + { + return GetAll(Q.Select(Attr.UserName)); + //var list = new List(); + //var sqlSelect = $"SELECT UserName FROM {TableName}"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlSelect)) + //{ + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetString(rdr, 0)); + // } + // rdr.Close(); + //} + //return list; + } + + public IList GetUserNameList(int departmentId) + { + return GetAll(Q + .Select(Attr.UserName) + .Where(Attr.DepartmentId, departmentId)); + + //var list = new List(); + //var sqlSelect = $"SELECT UserName FROM {TableName} WHERE DepartmentId = {departmentId}"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlSelect)) + //{ + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetString(rdr, 0)); + // } + // rdr.Close(); + //} + //return list; + } + + private bool UpdateValidate(IAdministratorInfo adminInfoToUpdate, string userName, string email, string mobile, out string errorMessage) + { + errorMessage = string.Empty; + + if (adminInfoToUpdate.UserName != null && adminInfoToUpdate.UserName != userName) + { + if (string.IsNullOrEmpty(adminInfoToUpdate.UserName)) + { + errorMessage = "用户名不能为空"; + return false; + } + if (adminInfoToUpdate.UserName.Length < ConfigManager.Instance.AdminUserNameMinLength) + { + errorMessage = $"用户名长度必须大于等于{ConfigManager.Instance.AdminUserNameMinLength}"; + return false; + } + if (IsUserNameExists(adminInfoToUpdate.UserName)) + { + errorMessage = "用户名已存在,请更换用户名"; + return false; + } + } + + if (adminInfoToUpdate.Mobile != null && adminInfoToUpdate.Mobile != mobile) + { + if (!string.IsNullOrEmpty(adminInfoToUpdate.Mobile) && IsMobileExists(adminInfoToUpdate.Mobile)) + { + errorMessage = "手机号码已被注册,请更换手机号码"; + return false; + } + } + + if (adminInfoToUpdate.Email != null && adminInfoToUpdate.Email != email) + { + if (!string.IsNullOrEmpty(adminInfoToUpdate.Email) && IsEmailExists(adminInfoToUpdate.Email)) + { + errorMessage = "电子邮件地址已被注册,请更换邮箱"; + return false; + } + } + + return true; + } + + private bool InsertValidate(string userName, string password, string email, string mobile, out string errorMessage) + { + errorMessage = string.Empty; + if (string.IsNullOrEmpty(userName)) + { + errorMessage = "用户名不能为空"; + return false; + } + if (userName.Length < ConfigManager.Instance.AdminUserNameMinLength) + { + errorMessage = $"用户名长度必须大于等于{ConfigManager.Instance.AdminUserNameMinLength}"; + return false; + } + if (IsUserNameExists(userName)) + { + errorMessage = "用户名已存在,请更换用户名"; + return false; + } + + if (string.IsNullOrEmpty(password)) + { + errorMessage = "密码不能为空"; + return false; + } + if (password.Length < ConfigManager.Instance.AdminPasswordMinLength) + { + errorMessage = $"密码长度必须大于等于{ConfigManager.Instance.AdminPasswordMinLength}"; + return false; + } + if ( + !EUserPasswordRestrictionUtils.IsValid(password, + ConfigManager.Instance.AdminPasswordRestriction)) + { + errorMessage = + $"密码不符合规则,请包含{EUserPasswordRestrictionUtils.GetText(EUserPasswordRestrictionUtils.GetEnumType(ConfigManager.Instance.AdminPasswordRestriction))}"; + return false; + } + + if (!string.IsNullOrEmpty(mobile) && IsMobileExists(mobile)) + { + errorMessage = "手机号码已被注册,请更换手机号码"; + return false; + } + if (!string.IsNullOrEmpty(email) && IsEmailExists(email)) + { + errorMessage = "电子邮件地址已被注册,请更换邮箱"; + return false; + } + + return true; + } + + public bool ChangePassword(AdministratorInfo adminInfo, string password, out string errorMessage) + { + errorMessage = string.Empty; + + if (string.IsNullOrEmpty(password)) + { + errorMessage = "密码不能为空"; + return false; + } + if (password.Length < ConfigManager.Instance.AdminPasswordMinLength) + { + errorMessage = $"密码长度必须大于等于{ConfigManager.Instance.AdminPasswordMinLength}"; + return false; + } + if ( + !EUserPasswordRestrictionUtils.IsValid(password, ConfigManager.Instance.AdminPasswordRestriction)) + { + errorMessage = + $"密码不符合规则,请包含{EUserPasswordRestrictionUtils.GetText(EUserPasswordRestrictionUtils.GetEnumType(ConfigManager.Instance.AdminPasswordRestriction))}"; + return false; + } + + password = EncodePassword(password, EPasswordFormat.Encrypted, out var passwordSalt); + ChangePassword(adminInfo, EPasswordFormat.Encrypted, passwordSalt, password); + return true; + } + + public bool Validate(string account, string password, bool isPasswordMd5, out string userName, out string errorMessage) + { + userName = string.Empty; + errorMessage = string.Empty; + + if (string.IsNullOrEmpty(account)) + { + errorMessage = "账号不能为空"; + return false; + } + if (string.IsNullOrEmpty(password)) + { + errorMessage = "密码不能为空"; + return false; + } + + var adminInfo = GetByAccount(account); + if (string.IsNullOrEmpty(adminInfo?.UserName)) + { + errorMessage = "帐号或密码错误"; + return false; + } + + userName = adminInfo.UserName; + + if (adminInfo.Locked) + { + errorMessage = "此账号被锁定,无法登录"; + return false; + } + + if (ConfigManager.Instance.IsAdminLockLogin) + { + if (adminInfo.CountOfFailedLogin > 0 && + adminInfo.CountOfFailedLogin >= ConfigManager.Instance.AdminLockLoginCount) + { + var lockType = EUserLockTypeUtils.GetEnumType(ConfigManager.Instance.AdminLockLoginType); + if (lockType == EUserLockType.Forever) + { + errorMessage = "此账号错误登录次数过多,已被永久锁定"; + return false; + } + if (lockType == EUserLockType.Hours) + { + if (adminInfo.LastActivityDate.HasValue) + { + var ts = new TimeSpan(DateTime.Now.Ticks - adminInfo.LastActivityDate.Value.Ticks); + var hours = Convert.ToInt32(ConfigManager.Instance.AdminLockLoginHours - ts.TotalHours); + if (hours > 0) + { + errorMessage = + $"此账号错误登录次数过多,已被锁定,请等待{hours}小时后重试"; + return false; + } + } + } + } + } + + if (CheckPassword(password, isPasswordMd5, adminInfo.Password, EPasswordFormatUtils.GetEnumType(adminInfo.PasswordFormat), adminInfo.PasswordSalt)) + return true; + + errorMessage = "账号或密码错误"; + return false; + } + + public bool CheckPassword(string password, bool isPasswordMd5, string dbPassword, EPasswordFormat passwordFormat, string passwordSalt) + { + var decodePassword = DecodePassword(dbPassword, passwordFormat, passwordSalt); + if (isPasswordMd5) + { + return password == AuthUtils.Md5ByString(decodePassword); + } + return password == decodePassword; + } + + private static string EncodePassword(string password, EPasswordFormat passwordFormat, out string passwordSalt) + { + var retVal = string.Empty; + passwordSalt = string.Empty; + + if (passwordFormat == EPasswordFormat.Clear) + { + retVal = password; + } + else if (passwordFormat == EPasswordFormat.Hashed) + { + passwordSalt = GenerateSalt(); + + var src = Encoding.Unicode.GetBytes(password); + var buffer2 = Convert.FromBase64String(passwordSalt); + var dst = new byte[buffer2.Length + src.Length]; + Buffer.BlockCopy(buffer2, 0, dst, 0, buffer2.Length); + Buffer.BlockCopy(src, 0, dst, buffer2.Length, src.Length); + var algorithm = HashAlgorithm.Create("SHA1"); + if (algorithm == null) return retVal; + var inArray = algorithm.ComputeHash(dst); + + retVal = Convert.ToBase64String(inArray); + } + else if (passwordFormat == EPasswordFormat.Encrypted) + { + passwordSalt = GenerateSalt(); + + var encrypt = new DesEncryptor + { + InputString = password, + EncryptKey = passwordSalt + }; + encrypt.DesEncrypt(); + + retVal = encrypt.OutString; + } + return retVal; + } + + private static string GenerateSalt() + { + var data = new byte[0x10]; + new RNGCryptoServiceProvider().GetBytes(data); + return Convert.ToBase64String(data); + } + + private static string DecodePassword(string password, EPasswordFormat passwordFormat, string passwordSalt) + { + var retVal = string.Empty; + if (passwordFormat == EPasswordFormat.Clear) + { + retVal = password; + } + else if (passwordFormat == EPasswordFormat.Hashed) + { + throw new Exception("can not decode hashed password"); + } + else if (passwordFormat == EPasswordFormat.Encrypted) + { + var encrypt = new DesEncryptor + { + InputString = password, + DecryptKey = passwordSalt + }; + encrypt.DesDecrypt(); + + retVal = encrypt.OutString; + } + return retVal; + } + } +} diff --git a/net452/SiteServer.CMS/Database/Repositories/AdministratorsInRolesRepository.cs b/net452/SiteServer.CMS/Database/Repositories/AdministratorsInRolesRepository.cs new file mode 100644 index 000000000..c67db7447 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/AdministratorsInRolesRepository.cs @@ -0,0 +1,207 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class AdministratorsInRolesRepository : Repository + { + public AdministratorsInRolesRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + //public override string TableName => "siteserver_AdministratorsInRoles"; + + //public override List TableColumns => new List + //{ + // new TableColumn + // { + // AttributeName = nameof(AdministratorsInRolesInfo.Id), + // DataType = DataType.Integer, + // IsIdentity = true, + // IsPrimaryKey = true + // }, + // new TableColumn + // { + // AttributeName = nameof(AdministratorsInRolesInfo.RoleName), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = nameof(AdministratorsInRolesInfo.UserName), + // DataType = DataType.VarChar + // } + //}; + + private static class Attr + { + public const string Id = nameof(AdministratorsInRolesInfo.Id); + public const string Guid = nameof(AdministratorsInRolesInfo.Guid); + public const string LastModifiedDate = nameof(AdministratorsInRolesInfo.LastModifiedDate); + public const string RoleName = nameof(AdministratorsInRolesInfo.RoleName); + public const string UserName = nameof(AdministratorsInRolesInfo.UserName); + } + + public IEnumerable GetUserNameListByRoleName(string roleName) + { + return GetAll(Q + .Select(Attr.UserName) + .Where(Attr.RoleName, roleName) + .Distinct()); + //var list = new List(); + + //const string sqlString = "SELECT DISTINCT UserName FROM siteserver_AdministratorsInRoles WHERE RoleName = @RoleName"; + + //IDataParameter[] parameters = + //{ + // GetParameter("@RoleName", roleName) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetString(rdr, 0)); + // } + // rdr.Close(); + //} + + //return list; + } + + public IList GetRolesForUser(string userName) + { + return GetAll(Q + .Select(Attr.RoleName) + .Where(Attr.UserName, userName) + .Distinct()); + //var tmpRoleNames = string.Empty; + //const string sqlString = "SELECT RoleName FROM siteserver_AdministratorsInRoles WHERE UserName = @UserName ORDER BY RoleName"; + + //IDataParameter[] parameters = + //{ + // GetParameter("@UserName", userName) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // while (rdr.Read()) + // { + // tmpRoleNames += DatabaseApi.GetString(rdr, 0) + ","; + // } + // rdr.Close(); + //} + + //if (tmpRoleNames.Length > 0) + //{ + // tmpRoleNames = tmpRoleNames.Substring(0, tmpRoleNames.Length - 1); + // return tmpRoleNames.Split(','); + //} + + //return new string[0]; + } + + public void RemoveUser(string userName) + { + Delete(Q + .Where(Attr.UserName, userName)); + //const string sqlString = "DELETE FROM siteserver_AdministratorsInRoles WHERE UserName = @UserName"; + //IDataParameter[] parameters = + //{ + // GetParameter("@UserName", userName) + //}; + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + } + + //public void RemoveUserFromRoles(string userName, string[] roleNames) + //{ + // foreach (var roleName in roleNames) + // { + // DeleteAll(new Query() + // .Equal(Attr.UserName, userName) + // .Equal(Attr.RoleName, roleName)); + // } + // //const string sqlString = "DELETE FROM siteserver_AdministratorsInRoles WHERE UserName = @UserName AND RoleName = @RoleName"; + // //foreach (var roleName in roleNames) + // //{ + // // IDataParameter[] parameters = + // // { + // // GetParameter("@UserName", userName), + // // GetParameter("@RoleName", roleName) + // // }; + // // DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + // //} + //} + + public void RemoveUserFromRole(string userName, string roleName) + { + Delete(Q + .Where(Attr.UserName, userName) + .Where(Attr.RoleName, roleName)); + + //const string sqlString = "DELETE FROM siteserver_AdministratorsInRoles WHERE UserName = @UserName AND RoleName = @RoleName"; + + //IDataParameter[] parameters = + //{ + // GetParameter("@UserName", userName), + // GetParameter("@RoleName", roleName) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + } + + public bool IsUserInRole(string userName, string roleName) + { + return Exists(Q + .Where(Attr.UserName, userName) + .Where(Attr.RoleName, roleName)); + + //var isUserInRole = false; + //const string sqlString = "SELECT * FROM siteserver_AdministratorsInRoles WHERE UserName = @UserName AND RoleName = @RoleName"; + + //IDataParameter[] parameters = + //{ + // GetParameter("@UserName", userName), + // GetParameter("@RoleName", roleName) + //}; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // if (!rdr.IsDBNull(0)) + // { + // isUserInRole = true; + // } + // } + // rdr.Close(); + //} + //return isUserInRole; + } + + public int AddUserToRole(string userName, string roleName) + { + if (!DataProvider.Administrator.IsUserNameExists(userName)) return 0; + if (!IsUserInRole(userName, roleName)) + { + return Insert(new AdministratorsInRolesInfo + { + UserName = userName, + RoleName = roleName + }); + //const string sqlString = "INSERT INTO siteserver_AdministratorsInRoles (UserName, RoleName) VALUES (@UserName, @RoleName)"; + + //IDataParameter[] parameters = + //{ + // GetParameter("@UserName", userName), + // GetParameter("@RoleName", roleName) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + } + + return 0; + } + } +} diff --git a/net452/SiteServer.CMS/Database/Repositories/AreaRepository.cs b/net452/SiteServer.CMS/Database/Repositories/AreaRepository.cs new file mode 100644 index 000000000..0688d2a60 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/AreaRepository.cs @@ -0,0 +1,1103 @@ +using System.Collections.Generic; +using System.Linq; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class AreaRepository : Repository + { + public AreaRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(AreaInfo.Id); + public const string ParentId = nameof(AreaInfo.ParentId); + public const string ParentsPath = nameof(AreaInfo.ParentsPath); + public const string ChildrenCount = nameof(AreaInfo.ChildrenCount); + public const string Taxis = nameof(AreaInfo.Taxis); + public const string IsLastNode = "IsLastNode"; + public const string CountOfAdmin = nameof(AreaInfo.CountOfAdmin); + } + + private int Insert(AreaInfo parentInfo, AreaInfo areaInfo) + { + if (parentInfo != null) + { + areaInfo.ParentsPath = parentInfo.ParentsPath + "," + parentInfo.Id; + areaInfo.ParentsCount = parentInfo.ParentsCount + 1; + + var maxTaxis = GetMaxTaxisByParentPath(areaInfo.ParentsPath); + if (maxTaxis == 0) + { + maxTaxis = parentInfo.Taxis; + } + areaInfo.Taxis = maxTaxis + 1; + } + else + { + areaInfo.ParentsPath = "0"; + areaInfo.ParentsCount = 0; + var maxTaxis = GetMaxTaxisByParentPath("0"); + areaInfo.Taxis = maxTaxis + 1; + } + areaInfo.ChildrenCount = 0; + areaInfo.LastNode = true; + + //DatabaseApi.Instance.ExecuteNonQuery(trans, $"UPDATE siteserver_Area SET {SqlUtils.ToPlusSqlString("Taxis")} WHERE (Taxis >= {areaInfo.Taxis})"); + Increment(Q.Select(Attr.Taxis) + .Where(Attr.Taxis, ">=", areaInfo.Taxis)); + + //IDataParameter[] parameters = { + // _db.GetParameter(ParamName, areaInfo.AreaName), + // _db.GetParameter(ParamParentId, areaInfo.ParentId), + // _db.GetParameter(ParamParentsPath, areaInfo.ParentsPath), + // _db.GetParameter(ParamParentsCount, areaInfo.ParentsCount), + // _db.GetParameter(ParamChildrenCount, 0), + // _db.GetParameter(ParamIsLastNode, true.ToString()), + // _db.GetParameter(ParamTaxis, areaInfo.Taxis), + // _db.GetParameter(ParamCountOfAdmin, areaInfo.CountOfAdmin) + //}; + + //areaInfo.Id = _db.ExecuteNonQueryAndReturnId(TableName, nameof(AreaInfo.Id), trans, "INSERT INTO siteserver_Area (AreaName, ParentID, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, Taxis, CountOfAdmin) VALUES (@AreaName, @ParentID, @ParentsPath, @ParentsCount, @ChildrenCount, @IsLastNode, @Taxis, @CountOfAdmin)", parameters); + Insert(areaInfo); + + if (!string.IsNullOrEmpty(areaInfo.ParentsPath) && areaInfo.ParentsPath != "0") + { + //_db.ExecuteNonQuery(trans, $"UPDATE siteserver_Area SET {SqlUtils.ToPlusSqlString("ChildrenCount")} WHERE Id IN ({AttackUtils.FilterSql(areaInfo.ParentsPath)})"); + Increment(Q.Select(Attr.ChildrenCount) + .WhereIn(Attr.Id, TranslateUtils.StringCollectionToIntList(areaInfo.ParentsPath))); + } + + //_db.ExecuteNonQuery(trans, $"UPDATE siteserver_Area SET IsLastNode = '{false}' WHERE ParentID = {areaInfo.ParentId}"); + //UpdateValue(new Dictionary + //{ + // {Attr.IsLastNode, false.ToString()} + //}, Q.Where(Attr.ParentId, areaInfo.ParentId)); + Update(Q + .Set(Attr.IsLastNode, false.ToString()) + .Where(Attr.ParentId, areaInfo.ParentId) + ); + + //sqlString = + // $"UPDATE siteserver_Area SET IsLastNode = 'True' WHERE (Id IN (SELECT TOP 1 Id FROM siteserver_Area WHERE ParentID = {areaInfo.ParentId} ORDER BY Taxis DESC))"; + + var topId = Get(Q + .Select(Attr.Id) + .Where(Attr.ParentId, areaInfo.ParentId) + .OrderByDesc(Attr.Taxis)); + + if (topId > 0) + { + Update(Q + .Set(Attr.IsLastNode, true.ToString()) + .Where(nameof(Attr.Id), topId) + ); + } + + //_db.ExecuteNonQuery(trans, $"UPDATE siteserver_Area SET IsLastNode = '{true}' WHERE Id IN ({SqlUtils.ToInTopSqlString(TableName, "Id", $"WHERE ParentID = {areaInfo.ParentId}", "ORDER BY Taxis DESC", 1)})"); + + AreaManager.ClearCache(); + + return areaInfo.Id; + } + + private void UpdateSubtractChildrenCount(string parentsPath, int subtractNum) + { + if (string.IsNullOrEmpty(parentsPath)) return; + + //var sqlString = string.Concat("UPDATE siteserver_Area SET ChildrenCount = ChildrenCount - ", subtractNum, " WHERE Id IN (", AttackUtils.FilterSql(parentsPath), ")"); + //_db.ExecuteNonQuery(_connectionString, sqlString); + Decrement(Q.Select(Attr.ChildrenCount) + .WhereIn(Attr.Id, TranslateUtils.StringCollectionToIntList(parentsPath)), subtractNum); + + AreaManager.ClearCache(); + } + + private void TaxisSubtract(int selectedId) + { + var areaInfo = Get(selectedId); + if (areaInfo == null) return; + //Get Lower Taxis and Id + // int lowerId; + // int lowerChildrenCount; + // string lowerParentsPath; + + // var sqlString = SqlUtils.ToTopSqlString(TableName, "Id, ChildrenCount, ParentsPath", + // "WHERE (ParentID = @ParentID) AND (Id <> @Id) AND (Taxis < @Taxis)", "ORDER BY Taxis DESC", 1); + + // IDataParameter[] parameters = { + // _db.GetParameter(ParamParentId, areaInfo.ParentId), + // _db.GetParameter(ParamId, areaInfo.Id), + // _db.GetParameter(ParamTaxis, areaInfo.Taxis), + //}; + + // using (var rdr = DatabaseApi.Instance.ExecuteReader(_connectionString, sqlString, parameters)) + // { + // if (rdr.Read()) + // { + // lowerId = _db.GetInt(rdr, 0); + // lowerChildrenCount = _db.GetInt(rdr, 1); + // lowerParentsPath = _db.GetString(rdr, 2); + // } + // else + // { + // return; + // } + // rdr.Close(); + // } + + //var dataInfo = Get(new GenericQuery() + // .Equal(Attr.ParentId, areaInfo.ParentId) + // .NotEqual(Attr.Id, areaInfo.Id) + // .Less(Attr.Taxis, areaInfo.Taxis) + // .OrderByDescending(Attr.Taxis)); + + var dataInfo = Get(Q + .Where(Attr.ParentId, areaInfo.ParentId) + .WhereNot(Attr.Id, areaInfo.Id) + .Where(Attr.Taxis, "<", areaInfo.Taxis) + .OrderByDesc(Attr.Taxis)); + + if (dataInfo == null) return; + + var lowerId = dataInfo.Id; + var lowerChildrenCount = dataInfo.ChildrenCount; + var lowerParentsPath = dataInfo.ParentsPath; + + var lowerNodePath = string.Concat(lowerParentsPath, ",", lowerId); + var selectedNodePath = string.Concat(areaInfo.ParentsPath, ",", areaInfo.Id); + + SetTaxisSubtract(selectedId, selectedNodePath, lowerChildrenCount + 1); + SetTaxisAdd(lowerId, lowerNodePath, areaInfo.ChildrenCount + 1); + + UpdateIsLastNode(areaInfo.ParentId); + } + + private void TaxisAdd(int selectedId) + { + var areaInfo = Get(selectedId); + if (areaInfo == null) return; + //Get Higher Taxis and Id + // int higherId; + // int higherChildrenCount; + // string higherParentsPath; + + // var sqlString = SqlUtils.ToTopSqlString(TableName, "Id, ChildrenCount, ParentsPath", + // "WHERE (ParentID = @ParentID) AND (Id <> @Id) AND (Taxis > @Taxis)", "ORDER BY Taxis", 1); + + // IDataParameter[] parameters = { + // _db.GetParameter(ParamParentId, areaInfo.ParentId), + // _db.GetParameter(ParamId, areaInfo.Id), + // _db.GetParameter(ParamTaxis, areaInfo.Taxis) + //}; + + // using (var rdr = _db.ExecuteReader(_connectionString, sqlString, parameters)) + // { + // if (rdr.Read()) + // { + // higherId = _db.GetInt(rdr, 0); + // higherChildrenCount = _db.GetInt(rdr, 1); + // higherParentsPath = _db.GetString(rdr, 2); + // } + // else + // { + // return; + // } + // rdr.Close(); + // } + + //var dataInfo = Get(new GenericQuery() + // .Select(new[] + // { + // Attr.Id, + // Attr.ChildrenCount, + // Attr.ParentsPath + // }) + // .Equal(Attr.ParentId, areaInfo.ParentId) + // .NotEqual(Attr.Id, areaInfo.Id) + // .Greater(Attr.Taxis, areaInfo.Taxis) + // .OrderBy(Attr.Taxis)); + + var dataInfo = Get(Q + .Where(Attr.ParentId, areaInfo.ParentId) + .WhereNot(Attr.Id, areaInfo.Id) + .Where(Attr.Taxis, ">", areaInfo.Taxis) + .OrderBy(Attr.Taxis)); + + if (dataInfo == null) return; + + var higherId = dataInfo.Id; + var higherChildrenCount = dataInfo.ChildrenCount; + var higherParentsPath = dataInfo.ParentsPath; + + var higherNodePath = string.Concat(higherParentsPath, ",", higherId); + var selectedNodePath = string.Concat(areaInfo.ParentsPath, ",", areaInfo.Id); + + SetTaxisAdd(selectedId, selectedNodePath, higherChildrenCount + 1); + SetTaxisSubtract(higherId, higherNodePath, areaInfo.ChildrenCount + 1); + + UpdateIsLastNode(areaInfo.ParentId); + } + + private void SetTaxisAdd(int areaId, string parentsPath, int addNum) + { + //var path = AttackUtils.FilterSql(parentsPath); + //var sqlString = + // $"UPDATE siteserver_Area SET Taxis = Taxis + {addNum} WHERE Id = {areaId} OR ParentsPath = '{path}' OR ParentsPath LIKE '{path},%'"; + + //_db.ExecuteNonQuery(_connectionString, sqlString); + Increment(Q.Select(Attr.Taxis) + .Where(Attr.Id, areaId) + .OrWhere(Attr.ParentsPath, parentsPath) + .OrWhereStarts(Attr.ParentsPath, parentsPath + ","), addNum); + + AreaManager.ClearCache(); + } + + private void SetTaxisSubtract(int areaId, string parentsPath, int subtractNum) + { + //var path = AttackUtils.FilterSql(parentsPath); + //var sqlString = + // $"UPDATE siteserver_Area SET Taxis = Taxis - {subtractNum} WHERE Id = {areaId} OR ParentsPath = '{path}' OR ParentsPath LIKE '{path},%'"; + + //_db.ExecuteNonQuery(_connectionString, sqlString); + Decrement(Q.Select(Attr.Taxis) + .Where(Attr.Id, areaId) + .OrWhere(Attr.ParentsPath, parentsPath) + .OrWhereStarts(Attr.ParentsPath, parentsPath + ","), subtractNum); + + AreaManager.ClearCache(); + } + + private void UpdateIsLastNode(int parentId) + { + if (parentId <= 0) return; + + //var sqlString = "UPDATE siteserver_Area SET IsLastNode = @IsLastNode WHERE ParentID = @ParentID"; + + //IDataParameter[] parameters = { + // _db.GetParameter(ParamIsLastNode, false.ToString()), + // _db.GetParameter(ParamParentId, parentId) + //}; + + //_db.ExecuteNonQuery(_connectionString, sqlString, parameters); + + Update(Q + .Set(Attr.IsLastNode, false.ToString()) + .Where(Attr.ParentId, parentId) + ); + + //sqlString = + // $"UPDATE siteserver_Area SET IsLastNode = '{true}' WHERE Id IN ({SqlUtils.ToInTopSqlString(TableName, "Id", $"WHERE ParentID = {parentId}", "ORDER BY Taxis DESC", 1)})"; + + //_db.ExecuteNonQuery(_connectionString, sqlString); + + var topId = Get(Q + .Select(Attr.Id) + .Where(Attr.ParentId, parentId) + .OrderByDesc(Attr.Taxis)); + + if (topId > 0) + { + Update(Q + .Set(Attr.IsLastNode, true.ToString()) + .Where(nameof(Attr.Id), topId) + ); + } + } + + private int GetMaxTaxisByParentPath(string parentPath) + { + return Max(Q.Select(Attr.Taxis) + .Where(Attr.ParentsPath, parentPath) + .OrWhereStarts(Attr.ParentsPath, parentPath + ",")) ?? 0; + + //var sqlString = string.Concat("SELECT MAX(Taxis) AS MaxTaxis FROM siteserver_Area WHERE (ParentsPath = '", AttackUtils.FilterSql(parentPath), "') OR (ParentsPath LIKE '", AttackUtils.FilterSql(parentPath), ",%')"); + //var maxTaxis = 0; + + //using (var rdr = _db.ExecuteReader(_connectionString, sqlString)) + //{ + // if (rdr.Read()) + // { + // maxTaxis = _db.GetInt(rdr, 0); + // } + // rdr.Close(); + //} + //return maxTaxis; + } + + public override int Insert(AreaInfo areaInfo) + { + //using (var conn = GetConnection()) + //{ + // conn.Open(); + // using (var trans = conn.BeginTransaction()) + // { + // try + // { + // var parentAreaInfo = GetAreaInfo(areaInfo.ParentId); + + // InsertWithTrans(parentAreaInfo, areaInfo, trans); + + // trans.Commit(); + // } + // catch + // { + // trans.Rollback(); + // throw; + // } + // } + //} + + var parentAreaInfo = base.Get(areaInfo.ParentId); + + areaInfo.Id = Insert(parentAreaInfo, areaInfo); + + //var parentAreaInfo = GetAreaInfo(areaInfo.ParentId); + //InsertObject(parentAreaInfo, areaInfo); + + AreaManager.ClearCache(); + + return areaInfo.Id; + } + + public override bool Update(AreaInfo areaInfo) + { + // IDataParameter[] updateParams = { + // _db.GetParameter(ParamName, areaInfo.AreaName), + // _db.GetParameter(ParamParentsPath, areaInfo.ParentsPath), + // _db.GetParameter(ParamParentsCount, areaInfo.ParentsCount), + // _db.GetParameter(ParamChildrenCount, areaInfo.ChildrenCount), + // _db.GetParameter(ParamIsLastNode, areaInfo.LastNode.ToString()), + // _db.GetParameter(ParamCountOfAdmin, areaInfo.CountOfAdmin), + // _db.GetParameter(ParamId, areaInfo.Id) + //}; + + // var i = _db.ExecuteNonQuery(_connectionString, SqlUpdate, updateParams); + + var updated = base.Update(areaInfo); + if (updated) + { + AreaManager.ClearCache(); + } + + return updated; + } + + public void UpdateTaxis(int selectedId, bool isSubtract) + { + if (isSubtract) + { + TaxisSubtract(selectedId); + } + else + { + TaxisAdd(selectedId); + } + } + + public void UpdateCountOfAdmin() + { + var areaIdList = AreaManager.GetAreaIdList(); + foreach (var areaId in areaIdList) + { + var count = DataProvider.Administrator.GetCountByAreaId(areaId); + //var sqlString = $"UPDATE {TableName} SET CountOfAdmin = {count} WHERE Id = {areaId}"; + //_db.ExecuteNonQuery(_connectionString, sqlString); + + Update(Q + .Set(Attr.CountOfAdmin, count) + .Where(nameof(Attr.Id), areaId) + ); + } + AreaManager.ClearCache(); + } + + public override bool Delete(int areaId) + { + var areaInfo = Get(areaId); + if (areaInfo != null) + { + IList areaIdList = new List(); + if (areaInfo.ChildrenCount > 0) + { + areaIdList = GetIdListForDescendant(areaId); + } + areaIdList.Add(areaId); + + //var sqlString = + // $"DELETE FROM siteserver_Area WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(areaIdList)})"; + + //int deletedNum; + + //using (var conn = GetConnection()) + //{ + // conn.Open(); + // using (var trans = conn.BeginTransaction()) + // { + // try + // { + // deletedNum = _db.ExecuteNonQuery(trans, sqlString); + + // if (deletedNum > 0) + // { + // string sqlStringTaxis = + // $"UPDATE siteserver_Area SET Taxis = Taxis - {deletedNum} WHERE (Taxis > {areaInfo.Taxis})"; + // _db.ExecuteNonQuery(trans, sqlStringTaxis); + // } + + // trans.Commit(); + // } + // catch + // { + // trans.Rollback(); + // throw; + // } + // } + //} + var deletedNum = Delete(Q + .WhereIn(Attr.Id, areaIdList)); + + if (deletedNum > 0) + { + Decrement(Q.Select(Attr.Taxis) + .Where(Attr.Taxis, ">", areaInfo.Taxis), deletedNum); + } + + UpdateIsLastNode(areaInfo.ParentId); + UpdateSubtractChildrenCount(areaInfo.ParentsPath, deletedNum); + } + + AreaManager.ClearCache(); + + return true; + } + + //private AreaInfo GetAreaInfo(int areaId) + //{ + // // AreaInfo areaInfo = null; + + // // IDataParameter[] parameters = { + // // _db.GetParameter(ParamId, areaId) + // //}; + + // // using (var rdr = _db.ExecuteReader(_connectionString, SqlSelect, parameters)) + // // { + // // if (rdr.Read()) + // // { + // // areaInfo = GetAreaInfo(rdr); + // // } + // // rdr.Close(); + // // } + // // return areaInfo; + // return base.Get(areaId); + //} + + private IList GetAreaInfoList() + { + //var list = new List(); + + //using (var rdr = _db.ExecuteReader(_connectionString, SqlSelectAll)) + //{ + // while (rdr.Read()) + // { + // var areaInfo = GetAreaInfo(rdr); + // list.Add(areaInfo); + // } + // rdr.Close(); + //} + //return list; + return GetAll(Q + .OrderBy(Attr.Taxis)); + } + + public IList GetIdListByParentId(int parentId) + { + //var sqlString = $@"SELECT Id FROM siteserver_Area WHERE ParentID = '{parentId}' ORDER BY Taxis"; + //var list = new List(); + + //using (var rdr = _db.ExecuteReader(_connectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // list.Add(_db.GetInt(rdr, 0)); + // } + // rdr.Close(); + //} + + //return list; + return GetAll(Q + .Select(Attr.Id) + .Where(Attr.ParentId, parentId) + .OrderBy(Attr.Taxis)); + } + + private IList GetIdListForDescendant(int areaId) + { +// string sqlString = $@"SELECT Id +//FROM siteserver_Area +//WHERE (ParentsPath LIKE '{areaId},%') OR +// (ParentsPath LIKE '%,{areaId},%') OR +// (ParentsPath LIKE '%,{areaId}') OR +// (ParentID = {areaId}) +//"; +// var list = new List(); + +// using (var rdr = _db.ExecuteReader(_connectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var theId = _db.GetInt(rdr, 0); +// list.Add(theId); +// } +// rdr.Close(); +// } + +// return list; + return GetAll(Q + .Select(Attr.Id) + .WhereStarts(Attr.ParentsPath, $"{areaId},") + .OrWhereContains(Attr.ParentsPath, $",{areaId},") + .OrWhereEnds(Attr.ParentsPath, $",{areaId}")); + } + + public List> GetAreaInfoPairList() + { + var areaInfoList = GetAreaInfoList(); + + return areaInfoList.Select(areaInfo => new KeyValuePair(areaInfo.Id, areaInfo)).ToList(); + } + + //private AreaInfo GetAreaInfo(IDataReader rdr) + //{ + // var i = 0; + // return new AreaInfo + // { + // Id = _db.GetInt(rdr, i++), + // Guid = _db.GetString(rdr, i++), + // LastModifiedDate = _db.GetDateTime(rdr, i++), + // AreaName = _db.GetString(rdr, i++), + // ParentId = _db.GetInt(rdr, i++), + // ParentsPath = _db.GetString(rdr, i++), + // ParentsCount = _db.GetInt(rdr, i++), + // ChildrenCount = _db.GetInt(rdr, i++), + // LastNode = TranslateUtils.ToBool(_db.GetString(rdr, i++)), + // Taxis = _db.GetInt(rdr, i++), + // CountOfAdmin = _db.GetInt(rdr, i) + // }; + //} + } +} + +//using System.Collections.Generic; +//using System.Data; +//using SiteServer.CMS.Core; +//using SiteServer.CMS.Core.Database; +//using SiteServer.CMS.DataCache; +//using SiteServer.CMS.Model; +//using SiteServer.Plugin; +//using SiteServer.Utils; + +//namespace SiteServer.CMS.Repositories +//{ +// public class AreaDao : DataProviderBase +// { +// public override string TableName => "siteserver_Area"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(AreaInfo.Id), +// DataType = DataType.Integer, +// IsPrimaryKey = true, +// IsIdentity = true +// }, +// new TableColumn +// { +// AttributeName = nameof(AreaInfo.AreaName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(AreaInfo.ParentId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(AreaInfo.ParentsPath), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(AreaInfo.ParentsCount), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(AreaInfo.ChildrenCount), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(AreaInfo.IsLastNode), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(AreaInfo.Taxis), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(AreaInfo.CountOfAdmin), +// DataType = DataType.Integer +// } +// }; + +// private const string SqlSelect = "SELECT Id, AreaName, ParentID, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, Taxis, CountOfAdmin FROM siteserver_Area WHERE Id = @Id"; +// private const string SqlSelectAll = "SELECT Id, AreaName, ParentID, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, Taxis, CountOfAdmin FROM siteserver_Area ORDER BY TAXIS"; +// private const string SqlUpdate = "UPDATE siteserver_Area SET AreaName = @AreaName, ParentsPath = @ParentsPath, ParentsCount = @ParentsCount, ChildrenCount = @ChildrenCount, IsLastNode = @IsLastNode, CountOfAdmin = @CountOfAdmin WHERE Id = @Id"; + +// private const string ParamId = "@Id"; +// private const string ParamName = "@AreaName"; +// private const string ParamParentId = "@ParentID"; +// private const string ParamParentsPath = "@ParentsPath"; +// private const string ParamParentsCount = "@ParentsCount"; +// private const string ParamChildrenCount = "@ChildrenCount"; +// private const string ParamIsLastNode = "@IsLastNode"; +// private const string ParamTaxis = "@Taxis"; +// private const string ParamCountOfAdmin = "@CountOfAdmin"; + +// private void InsertWithTrans(AreaInfo parentInfo, AreaInfo areaInfo, IDbTransaction trans) +// { +// if (parentInfo != null) +// { +// areaInfo.ParentsPath = parentInfo.ParentsPath + "," + parentInfo.Id; +// areaInfo.ParentsCount = parentInfo.ParentsCount + 1; + +// var maxTaxis = GetMaxTaxisByParentPath(areaInfo.ParentsPath); +// if (maxTaxis == 0) +// { +// maxTaxis = parentInfo.Taxis; +// } +// areaInfo.Taxis = maxTaxis + 1; +// } +// else +// { +// areaInfo.ParentsPath = "0"; +// areaInfo.ParentsCount = 0; +// var maxTaxis = GetMaxTaxisByParentPath("0"); +// areaInfo.Taxis = maxTaxis + 1; +// } + +// var sqlInsert = "INSERT INTO siteserver_Area (AreaName, ParentID, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, Taxis, CountOfAdmin) VALUES (@AreaName, @ParentID, @ParentsPath, @ParentsCount, @ChildrenCount, @IsLastNode, @Taxis, @CountOfAdmin)"; + +// IDataParameter[] insertParams = { +// GetParameter(ParamName, areaInfo.AreaName), +// GetParameter(ParamParentId, areaInfo.ParentId), +// GetParameter(ParamParentsPath, areaInfo.ParentsPath), +// GetParameter(ParamParentsCount, areaInfo.ParentsCount), +// GetParameter(ParamChildrenCount, 0), +// GetParameter(ParamIsLastNode, true.ToString()), +// GetParameter(ParamTaxis, areaInfo.Taxis), +// GetParameter(ParamCountOfAdmin, areaInfo.CountOfAdmin) +// }; + +// string sqlString = $"UPDATE siteserver_Area SET {SqlUtils.ToPlusSqlString("Taxis")} WHERE (Taxis >= {areaInfo.Taxis})"; +// DatabaseApi.ExecuteNonQuery(trans, sqlString); + +// areaInfo.Id = DatabaseApi.ExecuteNonQueryAndReturnId(TableName, nameof(AreaInfo.Id), trans, sqlInsert, insertParams); + +// if (!string.IsNullOrEmpty(areaInfo.ParentsPath) && areaInfo.ParentsPath != "0") +// { +// sqlString = $"UPDATE siteserver_Area SET {SqlUtils.ToPlusSqlString("ChildrenCount")} WHERE Id IN ({AttackUtils.FilterSql(areaInfo.ParentsPath)})"; + +// DatabaseApi.ExecuteNonQuery(trans, sqlString); +// } + +// sqlString = $"UPDATE siteserver_Area SET IsLastNode = '{false}' WHERE ParentID = {areaInfo.ParentId}"; + +// DatabaseApi.ExecuteNonQuery(trans, sqlString); + +// //sqlString = +// // $"UPDATE siteserver_Area SET IsLastNode = 'True' WHERE (Id IN (SELECT TOP 1 Id FROM siteserver_Area WHERE ParentID = {areaInfo.ParentId} ORDER BY Taxis DESC))"; +// sqlString = +// $"UPDATE siteserver_Area SET IsLastNode = '{true}' WHERE Id IN ({SqlUtils.ToInTopSqlString(TableName, "Id", $"WHERE ParentID = {areaInfo.ParentId}", "ORDER BY Taxis DESC", 1)})"; + +// DatabaseApi.ExecuteNonQuery(trans, sqlString); + +// AreaManager.ClearCache(); +// } + +// private void UpdateSubtractChildrenCount(string parentsPath, int subtractNum) +// { +// if (!string.IsNullOrEmpty(parentsPath)) +// { +// var sqlString = string.Concat("UPDATE siteserver_Area SET ChildrenCount = ChildrenCount - ", subtractNum, " WHERE Id IN (", AttackUtils.FilterSql(parentsPath), ")"); +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + +// AreaManager.ClearCache(); +// } +// } + +// private void TaxisSubtract(int selectedId) +// { +// var areaInfo = GetAreaInfo(selectedId); +// if (areaInfo == null) return; +// //Get Lower Taxis and Id +// int lowerId; +// int lowerChildrenCount; +// string lowerParentsPath; + +// var sqlString = SqlUtils.ToTopSqlString(TableName, "Id, ChildrenCount, ParentsPath", +// "WHERE (ParentID = @ParentID) AND (Id <> @Id) AND (Taxis < @Taxis)", "ORDER BY Taxis DESC", 1); + +// IDataParameter[] parameters = { +// GetParameter(ParamParentId, areaInfo.ParentId), +// GetParameter(ParamId, areaInfo.Id), +// GetParameter(ParamTaxis, areaInfo.Taxis), +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// lowerId = DatabaseApi.GetInt(rdr, 0); +// lowerChildrenCount = DatabaseApi.GetInt(rdr, 1); +// lowerParentsPath = DatabaseApi.GetString(rdr, 2); +// } +// else +// { +// return; +// } +// rdr.Close(); +// } + + +// var lowerNodePath = string.Concat(lowerParentsPath, ",", lowerId); +// var selectedNodePath = string.Concat(areaInfo.ParentsPath, ",", areaInfo.Id); + +// SetTaxisSubtract(selectedId, selectedNodePath, lowerChildrenCount + 1); +// SetTaxisAdd(lowerId, lowerNodePath, areaInfo.ChildrenCount + 1); + +// UpdateIsLastNode(areaInfo.ParentId); +// } + +// private void TaxisAdd(int selectedId) +// { +// var areaInfo = GetAreaInfo(selectedId); +// if (areaInfo == null) return; +// //Get Higher Taxis and Id +// int higherId; +// int higherChildrenCount; +// string higherParentsPath; + +// var sqlString = SqlUtils.ToTopSqlString(TableName, "Id, ChildrenCount, ParentsPath", +// "WHERE (ParentID = @ParentID) AND (Id <> @Id) AND (Taxis > @Taxis)", "ORDER BY Taxis", 1); + +// IDataParameter[] parameters = { +// GetParameter(ParamParentId, areaInfo.ParentId), +// GetParameter(ParamId, areaInfo.Id), +// GetParameter(ParamTaxis, areaInfo.Taxis) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// higherId = DatabaseApi.GetInt(rdr, 0); +// higherChildrenCount = DatabaseApi.GetInt(rdr, 1); +// higherParentsPath = DatabaseApi.GetString(rdr, 2); +// } +// else +// { +// return; +// } +// rdr.Close(); +// } + + +// var higherNodePath = string.Concat(higherParentsPath, ",", higherId); +// var selectedNodePath = string.Concat(areaInfo.ParentsPath, ",", areaInfo.Id); + +// SetTaxisAdd(selectedId, selectedNodePath, higherChildrenCount + 1); +// SetTaxisSubtract(higherId, higherNodePath, areaInfo.ChildrenCount + 1); + +// UpdateIsLastNode(areaInfo.ParentId); +// } + +// private void SetTaxisAdd(int areaId, string parentsPath, int addNum) +// { +// var path = AttackUtils.FilterSql(parentsPath); +// string sqlString = +// $"UPDATE siteserver_Area SET Taxis = Taxis + {addNum} WHERE Id = {areaId} OR ParentsPath = '{path}' OR ParentsPath LIKE '{path},%'"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + +// AreaManager.ClearCache(); +// } + +// private void SetTaxisSubtract(int areaId, string parentsPath, int subtractNum) +// { +// var path = AttackUtils.FilterSql(parentsPath); +// string sqlString = +// $"UPDATE siteserver_Area SET Taxis = Taxis - {subtractNum} WHERE Id = {areaId} OR ParentsPath = '{path}' OR ParentsPath LIKE '{path},%'"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + +// AreaManager.ClearCache(); +// } + +// private void UpdateIsLastNode(int parentId) +// { +// if (parentId <= 0) return; + +// var sqlString = "UPDATE siteserver_Area SET IsLastNode = @IsLastNode WHERE ParentID = @ParentID"; + +// IDataParameter[] parameters = { +// GetParameter(ParamIsLastNode, false.ToString()), +// GetParameter(ParamParentId, parentId) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// sqlString = +// $"UPDATE siteserver_Area SET IsLastNode = '{true}' WHERE Id IN ({SqlUtils.ToInTopSqlString(TableName, "Id", $"WHERE ParentID = {parentId}", "ORDER BY Taxis DESC", 1)})"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } + +// private int GetMaxTaxisByParentPath(string parentPath) +// { +// var sqlString = string.Concat("SELECT MAX(Taxis) AS MaxTaxis FROM siteserver_Area WHERE (ParentsPath = '", AttackUtils.FilterSql(parentPath), "') OR (ParentsPath LIKE '", AttackUtils.FilterSql(parentPath), ",%')"); +// var maxTaxis = 0; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// if (rdr.Read()) +// { +// maxTaxis = DatabaseApi.GetInt(rdr, 0); +// } +// rdr.Close(); +// } +// return maxTaxis; +// } + +// public int InsertObject(AreaInfo areaInfo) +// { +// using (var conn = GetConnection()) +// { +// conn.Open(); +// using (var trans = conn.BeginTransaction()) +// { +// try +// { +// var parentAreaInfo = GetAreaInfo(areaInfo.ParentId); + +// InsertWithTrans(parentAreaInfo, areaInfo, trans); + +// trans.Commit(); +// } +// catch +// { +// trans.Rollback(); +// throw; +// } +// } +// } + +// AreaManager.ClearCache(); + +// return areaInfo.Id; +// } + +// public void UpdateObject(AreaInfo areaInfo) +// { +// IDataParameter[] updateParams = { +// GetParameter(ParamName, areaInfo.AreaName), +// GetParameter(ParamParentsPath, areaInfo.ParentsPath), +// GetParameter(ParamParentsCount, areaInfo.ParentsCount), +// GetParameter(ParamChildrenCount, areaInfo.ChildrenCount), +// GetParameter(ParamIsLastNode, areaInfo.IsLastNode.ToString()), +// GetParameter(ParamCountOfAdmin, areaInfo.CountOfAdmin), +// GetParameter(ParamId, areaInfo.Id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdate, updateParams); + +// AreaManager.ClearCache(); +// } + +// public void UpdateTaxis(int selectedId, bool isSubtract) +// { +// if (isSubtract) +// { +// TaxisSubtract(selectedId); +// } +// else +// { +// TaxisAdd(selectedId); +// } +// } + +// public void UpdateCountOfAdmin() +// { +// var areaIdList = AreaManager.GetAreaIdList(); +// foreach (var areaId in areaIdList) +// { +// var count = DataProvider.Administrator.GetCountByAreaId(areaId); +// string sqlString = $"UPDATE {TableName} SET CountOfAdmin = {count} WHERE Id = {areaId}"; +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } +// AreaManager.ClearCache(); +// } + +// public void DeleteById(int areaId) +// { +// var areaInfo = GetAreaInfo(areaId); +// if (areaInfo != null) +// { +// var areaIdList = new List(); +// if (areaInfo.ChildrenCount > 0) +// { +// areaIdList = GetIdListForDescendant(areaId); +// } +// areaIdList.Add(areaId); + +// string sqlString = +// $"DELETE FROM siteserver_Area WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(areaIdList)})"; + +// int deletedNum; + +// using (var conn = GetConnection()) +// { +// conn.Open(); +// using (var trans = conn.BeginTransaction()) +// { +// try +// { +// deletedNum = DatabaseApi.ExecuteNonQuery(trans, sqlString); + +// if (deletedNum > 0) +// { +// string sqlStringTaxis = +// $"UPDATE siteserver_Area SET Taxis = Taxis - {deletedNum} WHERE (Taxis > {areaInfo.Taxis})"; +// DatabaseApi.ExecuteNonQuery(trans, sqlStringTaxis); +// } + +// trans.Commit(); +// } +// catch +// { +// trans.Rollback(); +// throw; +// } +// } +// } +// UpdateIsLastNode(areaInfo.ParentId); +// UpdateSubtractChildrenCount(areaInfo.ParentsPath, deletedNum); +// } + +// AreaManager.ClearCache(); +// } + +// private AreaInfo GetAreaInfo(int areaId) +// { +// AreaInfo areaInfo = null; + +// IDataParameter[] parameters = { +// GetParameter(ParamId, areaId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelect, parameters)) +// { +// if (rdr.Read()) +// { +// var i = 0; +// areaInfo = new AreaInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i)); +// } +// rdr.Close(); +// } +// return areaInfo; +// } + +// private List GetAreaInfoList() +// { +// var list = new List(); + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAll)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var areaInfo = new AreaInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i)); +// list.Add(areaInfo); +// } +// rdr.Close(); +// } +// return list; +// } + +// public List GetIdListByParentId(int parentId) +// { +// var sqlString = $@"SELECT Id FROM siteserver_Area WHERE ParentID = '{parentId}' ORDER BY Taxis"; +// var list = new List(); + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// list.Add(DatabaseApi.GetInt(rdr, 0)); +// } +// rdr.Close(); +// } + +// return list; +// } + +// public List GetIdListForDescendant(int areaId) +// { +// string sqlString = $@"SELECT Id +//FROM siteserver_Area +//WHERE (ParentsPath LIKE '{areaId},%') OR +// (ParentsPath LIKE '%,{areaId},%') OR +// (ParentsPath LIKE '%,{areaId}') OR +// (ParentID = {areaId}) +//"; +// var list = new List(); + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var theId = DatabaseApi.GetInt(rdr, 0); +// list.Add(theId); +// } +// rdr.Close(); +// } + +// return list; +// } + +// public List> GetAreaInfoPairList() +// { +// var pairList = new List>(); + +// var areaInfoList = GetAreaInfoList(); +// foreach (var areaInfo in areaInfoList) +// { +// var pair = new KeyValuePair(areaInfo.Id, areaInfo); +// pairList.Add(pair); +// } + +// return pairList; +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/ChannelGroupRepository.cs b/net452/SiteServer.CMS/Database/Repositories/ChannelGroupRepository.cs new file mode 100644 index 000000000..95eaecf3f --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/ChannelGroupRepository.cs @@ -0,0 +1,587 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Database.Repositories +{ + public class ChannelGroupRepository : Repository + { + public ChannelGroupRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string GroupName = nameof(ChannelGroupInfo.GroupName); + public const string SiteId = nameof(ChannelGroupInfo.SiteId); + public const string Taxis = nameof(ChannelGroupInfo.Taxis); + } + + public override int Insert(ChannelGroupInfo groupInfo) + { + var maxTaxis = GetMaxTaxis(groupInfo.SiteId); + groupInfo.Taxis = maxTaxis + 1; + + //var sqlString = $"INSERT INTO {TableName} (GroupName, SiteId, Taxis, Description) VALUES (@GroupName, @SiteId, @Taxis, @Description)"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamGroupName, groupInfo.GroupName), + // GetParameter(ParamSiteId, groupInfo.SiteId), + // GetParameter(ParamTaxis, groupInfo.Taxis), + // GetParameter(ParamDescription,groupInfo.Description) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + groupInfo.Id = base.Insert(groupInfo); + ChannelGroupManager.ClearCache(); + return groupInfo.Id; + } + + public override bool Update(ChannelGroupInfo groupInfo) + { + //var sqlString = $"UPDATE {TableName} SET Description = @Description WHERE GroupName = @GroupName AND SiteId = @SiteId"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamDescription,groupInfo.Description), + // GetParameter(ParamGroupName, groupInfo.GroupName), + // GetParameter(ParamSiteId, groupInfo.SiteId) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + var updated = base.Update(groupInfo); + + ChannelGroupManager.ClearCache(); + + return updated; + } + + public void Delete(int siteId, string groupName) + { + //var sqlString = $"DELETE FROM {TableName} WHERE GroupName = @GroupName AND SiteId = @SiteId"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamGroupName, groupName), + // GetParameter(ParamSiteId, siteId) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Delete(Q + .Where(Attr.SiteId, siteId) + .Where(Attr.GroupName, groupName)); + + var channelIdList = ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(siteId, siteId), EScopeType.All, groupName, string.Empty, string.Empty); + foreach (var channelId in channelIdList) + { + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + var groupNameList = TranslateUtils.StringCollectionToStringList(channelInfo.GroupNameCollection); + groupNameList.Remove(groupName); + channelInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(groupNameList); + DataProvider.Channel.Update(channelInfo); + } + + ChannelGroupManager.ClearCache(); + } + + private int GetTaxis(int siteId, string groupName) + { + //const string sqlString = "SELECT Taxis FROM siteserver_ChannelGroup WHERE (GroupName = @GroupName AND SiteId = @SiteId)"; + //IDataParameter[] parameters = + //{ + // GetParameter(ParamGroupName, groupName), + // GetParameter(ParamSiteId, siteId) + //}; + //return DatabaseApi.Instance.GetIntResult(sqlString, parameters); + + return Get(Q + .Select(Attr.Taxis) + .Where(Attr.SiteId, siteId) + .Where(Attr.GroupName, groupName)); + } + + private void SetTaxis(int siteId, string groupName, int taxis) + { + //var sqlString = + // $"UPDATE siteserver_ChannelGroup SET Taxis = {taxis} WHERE (GroupName = @GroupName AND SiteId = @SiteId)"; + //IDataParameter[] parameters = + //{ + // GetParameter(ParamGroupName, groupName), + // GetParameter(ParamSiteId, siteId) + //}; + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Update(Q + .Set(Attr.Taxis, taxis) + .Where(Attr.SiteId, siteId) + .Where(Attr.GroupName, groupName) + ); + + ChannelGroupManager.ClearCache(); + } + + private int GetMaxTaxis(int siteId) + { + //var sqlString = + // $"SELECT MAX(Taxis) FROM {TableName} WHERE (SiteId = {siteId})"; + //var maxTaxis = 0; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // if (rdr.Read()) + // { + // maxTaxis = DatabaseApi.GetInt(rdr, 0); + // } + // rdr.Close(); + //} + //return maxTaxis; + + return Max(Q + .Select(Attr.Taxis) + .Where(Attr.SiteId, siteId) + ) ?? 0; + } + + public void UpdateTaxisToUp(int siteId, string groupName) + { + //var sqlString = SqlDifferences.GetSqlString("siteserver_ChannelGroup", new List + // { + // nameof(ChannelGroupInfo.GroupName), + // nameof(ChannelGroupInfo.Taxis) + // }, + // "WHERE (Taxis > (SELECT Taxis FROM siteserver_ChannelGroup WHERE GroupName = @GroupName AND SiteId = @SiteId) AND SiteId = @SiteId)", + // "ORDER BY Taxis", 1); + + //var higherGroupName = string.Empty; + //var higherTaxis = 0; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamGroupName, groupName), + // GetParameter(ParamSiteId, siteId) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // higherGroupName = DatabaseApi.GetString(rdr, 0); + // higherTaxis = DatabaseApi.GetInt(rdr, 1); + // } + // rdr.Close(); + //} + + var taxis = GetTaxis(siteId, groupName); + var result = Get<(string GroupName, int Taxis)?> (Q + .Select(Attr.GroupName, Attr.Taxis) + .Where(Attr.SiteId, siteId) + .Where(Attr.Taxis, ">", taxis) + .OrderBy(Attr.Taxis)); + + var higherGroupName = string.Empty; + var higherTaxis = 0; + if (result != null) + { + higherGroupName = result.Value.GroupName; + higherTaxis = result.Value.Taxis; + } + + if (!string.IsNullOrEmpty(higherGroupName)) + { + //Get Taxis Of Selected ID + var selectedTaxis = GetTaxis(siteId, groupName); + + //Set The Selected Class Taxis To Higher Level + SetTaxis(siteId, groupName, higherTaxis); + //Set The Higher Class Taxis To Lower Level + SetTaxis(siteId, higherGroupName, selectedTaxis); + } + + ChannelGroupManager.ClearCache(); + } + + public void UpdateTaxisToDown(int siteId, string groupName) + { + //var sqlString = SqlDifferences.GetSqlString("siteserver_ChannelGroup", new List + // { + // nameof(ChannelGroupInfo.GroupName), + // nameof(ChannelGroupInfo.Taxis) + // }, + // "WHERE (Taxis < (SELECT Taxis FROM siteserver_ChannelGroup WHERE GroupName = @GroupName AND SiteId = @SiteId) AND SiteId = @SiteId)", + // "ORDER BY Taxis DESC", 1); + + //var lowerGroupName = string.Empty; + //var lowerTaxis = 0; + //IDataParameter[] parameters = + //{ + // GetParameter(ParamGroupName, groupName), + // GetParameter(ParamSiteId, siteId) + //}; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // lowerGroupName = DatabaseApi.GetString(rdr, 0); + // lowerTaxis = DatabaseApi.GetInt(rdr, 1); + // } + // rdr.Close(); + //} + var taxis = GetTaxis(siteId, groupName); + var result = Get<(string GroupName, int Taxis)?>(Q + .Select(Attr.GroupName, Attr.Taxis) + .Where(Attr.SiteId, siteId) + .Where(Attr.Taxis, "<", taxis) + .OrderByDesc(Attr.Taxis)); + + var lowerGroupName = string.Empty; + var lowerTaxis = 0; + if (result != null) + { + lowerGroupName = result.Value.GroupName; + lowerTaxis = result.Value.Taxis; + } + + if (!string.IsNullOrEmpty(lowerGroupName)) + { + //Get Taxis Of Selected Class + var selectedTaxis = GetTaxis(siteId, groupName); + + //Set The Selected Class Taxis To Lower Level + SetTaxis(siteId, groupName, lowerTaxis); + //Set The Lower Class Taxis To Higher Level + SetTaxis(siteId, lowerGroupName, selectedTaxis); + } + + ChannelGroupManager.ClearCache(); + } + + public Dictionary> GetAllChannelGroups() + { + var allDict = new Dictionary>(); + + //var sqlString = + // $"SELECT GroupName, SiteId, Taxis, Description FROM {TableName} ORDER BY Taxis DESC, GroupName"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var group = new ChannelGroupInfo(DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), + // DatabaseApi.GetString(rdr, i)); + + // allDict.TryGetValue(group.SiteId, out var list); + + // if (list == null) + // { + // list = new List(); + // } + + // list.Add(group); + + // allDict[group.SiteId] = list; + // } + // rdr.Close(); + //} + + var groupList = GetAll(Q + .OrderByDesc(Attr.Taxis) + .OrderBy(Attr.GroupName)); + + foreach (var group in groupList) + { + allDict.TryGetValue(group.SiteId, out var list); + + if (list == null) + { + list = new List(); + } + + list.Add(group); + + allDict[group.SiteId] = list; + } + + return allDict; + } + } +} + + +//using System.Collections.Generic; +//using System.Data; +//using SiteServer.CMS.Database.Caches; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; +//using SiteServer.Utils.Enumerations; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class ChannelGroup : DataProviderBase +// { +// public override string TableName => "siteserver_ChannelGroup"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(ChannelGroupInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelGroupInfo.GroupName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelGroupInfo.SiteId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelGroupInfo.Taxis), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelGroupInfo.Description), +// DataType = DataType.Text +// } +// }; + +// private const string ParamGroupName = "@GroupName"; +// private const string ParamSiteId = "@SiteId"; +// private const string ParamTaxis = "@Taxis"; +// private const string ParamDescription = "@Description"; + + +// public void InsertObject(ChannelGroupInfo groupInfo) +// { +// var maxTaxis = GetMaxTaxis(groupInfo.SiteId); +// groupInfo.Taxis = maxTaxis + 1; + +// var sqlString = $"INSERT INTO {TableName} (GroupName, SiteId, Taxis, Description) VALUES (@GroupName, @SiteId, @Taxis, @Description)"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamGroupName, groupInfo.GroupName), +// GetParameter(ParamSiteId, groupInfo.SiteId), +// GetParameter(ParamTaxis, groupInfo.Taxis), +// GetParameter(ParamDescription,groupInfo.Description) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// ChannelGroupManager.ClearCache(); +// } + +// public void UpdateObject(ChannelGroupInfo groupInfo) +// { +// var sqlString = $"UPDATE {TableName} SET Description = @Description WHERE GroupName = @GroupName AND SiteId = @SiteId"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamDescription,groupInfo.Description), +// GetParameter(ParamGroupName, groupInfo.GroupName), +// GetParameter(ParamSiteId, groupInfo.SiteId) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// ChannelGroupManager.ClearCache(); +// } + +// public void DeleteById(int siteId, string groupName) +// { +// var sqlString = $"DELETE FROM {TableName} WHERE GroupName = @GroupName AND SiteId = @SiteId"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamGroupName, groupName), +// GetParameter(ParamSiteId, siteId) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// var channelIdList = ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(siteId, siteId), EScopeType.All, groupName, string.Empty, string.Empty); +// foreach (var channelId in channelIdList) +// { +// var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); +// var groupNameList = TranslateUtils.StringCollectionToStringList(channelInfo.GroupNameCollection); +// groupNameList.Remove(groupName); +// channelInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(groupNameList); +// DataProvider.Channel.UpdateObject(channelInfo); +// } + +// ChannelGroupManager.ClearCache(); +// } + +// private int GetTaxis(int siteId, string groupName) +// { +// const string sqlString = "SELECT Taxis FROM siteserver_ChannelGroup WHERE (GroupName = @GroupName AND SiteId = @SiteId)"; +// IDataParameter[] parameters = +// { +// GetParameter(ParamGroupName, groupName), +// GetParameter(ParamSiteId, siteId) +// }; +// return DatabaseApi.Instance.GetIntResult(sqlString, parameters); +// } + +// private void SetTaxis(int siteId, string groupName, int taxis) +// { +// var sqlString = +// $"UPDATE siteserver_ChannelGroup SET Taxis = {taxis} WHERE (GroupName = @GroupName AND SiteId = @SiteId)"; +// IDataParameter[] parameters = +// { +// GetParameter(ParamGroupName, groupName), +// GetParameter(ParamSiteId, siteId) +// }; +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// private int GetMaxTaxis(int siteId) +// { +// var sqlString = +// $"SELECT MAX(Taxis) FROM {TableName} WHERE (SiteId = {siteId})"; +// var maxTaxis = 0; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// if (rdr.Read()) +// { +// maxTaxis = DatabaseApi.GetInt(rdr, 0); +// } +// rdr.Close(); +// } +// return maxTaxis; +// } + +// public void UpdateTaxisToUp(int siteId, string groupName) +// { +// var sqlString = SqlDifferences.GetSqlString("siteserver_ChannelGroup", new List +// { +// nameof(ChannelGroupInfo.GroupName), +// nameof(ChannelGroupInfo.Taxis) +// }, +// "WHERE (Taxis > (SELECT Taxis FROM siteserver_ChannelGroup WHERE GroupName = @GroupName AND SiteId = @SiteId) AND SiteId = @SiteId)", +// "ORDER BY Taxis", 1); + +// var higherGroupName = string.Empty; +// var higherTaxis = 0; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamGroupName, groupName), +// GetParameter(ParamSiteId, siteId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// higherGroupName = DatabaseApi.GetString(rdr, 0); +// higherTaxis = DatabaseApi.GetInt(rdr, 1); +// } +// rdr.Close(); +// } + +// if (!string.IsNullOrEmpty(higherGroupName)) +// { +// //Get Taxis Of Selected ID +// var selectedTaxis = GetTaxis(siteId, groupName); + +// //Set The Selected Class Taxis To Higher Level +// SetTaxis(siteId, groupName, higherTaxis); +// //Set The Higher Class Taxis To Lower Level +// SetTaxis(siteId, higherGroupName, selectedTaxis); +// } + +// ChannelGroupManager.ClearCache(); +// } + +// public void UpdateTaxisToDown(int siteId, string groupName) +// { +// var sqlString = SqlDifferences.GetSqlString("siteserver_ChannelGroup", new List +// { +// nameof(ChannelGroupInfo.GroupName), +// nameof(ChannelGroupInfo.Taxis) +// }, +// "WHERE (Taxis < (SELECT Taxis FROM siteserver_ChannelGroup WHERE GroupName = @GroupName AND SiteId = @SiteId) AND SiteId = @SiteId)", +// "ORDER BY Taxis DESC", 1); + +// var lowerGroupName = string.Empty; +// var lowerTaxis = 0; +// IDataParameter[] parameters = +// { +// GetParameter(ParamGroupName, groupName), +// GetParameter(ParamSiteId, siteId) +// }; +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// lowerGroupName = DatabaseApi.GetString(rdr, 0); +// lowerTaxis = DatabaseApi.GetInt(rdr, 1); +// } +// rdr.Close(); +// } + +// if (!string.IsNullOrEmpty(lowerGroupName)) +// { +// //Get Taxis Of Selected Class +// var selectedTaxis = GetTaxis(siteId, groupName); + +// //Set The Selected Class Taxis To Lower Level +// SetTaxis(siteId, groupName, lowerTaxis); +// //Set The Lower Class Taxis To Higher Level +// SetTaxis(siteId, lowerGroupName, selectedTaxis); +// } + +// ChannelGroupManager.ClearCache(); +// } + +// public Dictionary> GetAllChannelGroups() +// { +// var allDict = new Dictionary>(); + +// var sqlString = +// $"SELECT GroupName, SiteId, Taxis, Description FROM {TableName} ORDER BY Taxis DESC, GroupName"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var group = new ChannelGroupInfo(DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), +// DatabaseApi.GetString(rdr, i)); + +// allDict.TryGetValue(group.SiteId, out var list); + +// if (list == null) +// { +// list = new List(); +// } + +// list.Add(group); + +// allDict[group.SiteId] = list; +// } +// rdr.Close(); +// } + +// return allDict; +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/ChannelRepository.cs b/net452/SiteServer.CMS/Database/Repositories/ChannelRepository.cs new file mode 100644 index 000000000..d17810961 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/ChannelRepository.cs @@ -0,0 +1,2798 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Text; +using Datory; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Database.Repositories +{ + public class ChannelRepository : Repository + { + public ChannelRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static readonly List SqlColumns = new List + { + ChannelAttribute.Id, + ChannelAttribute.AddDate, + ChannelAttribute.Taxis + }; + + //public override string TableName => "siteserver_Channel"; + + //public override List TableColumns => new List + //{ + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.Id), + // DataType = DataType.Integer, + // IsIdentity = true, + // IsPrimaryKey = true + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.ChannelName), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.SiteId), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.ContentModelPluginId), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.ContentRelatedPluginIds), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.ParentId), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.ParentsPath), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.ParentsCount), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.ChildrenCount), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.IsLastNode), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.IndexName), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.GroupNameCollection), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.Taxis), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.AddDate), + // DataType = DataType.DateTime + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.ImageUrl), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.Content), + // DataType = DataType.Text + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.FilePath), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.ChannelFilePathRule), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.ContentFilePathRule), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.LinkUrl), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.LinkType), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.ChannelTemplateId), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.ContentTemplateId), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.Keywords), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = nameof(ChannelInfo.Description), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = "ExtendValues", + // DataType = DataType.Text + // } + //}; + + //private const string SqlSelectByLastAddDate = "SELECT Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues FROM siteserver_Channel WHERE ParentId = @ParentId ORDER BY AddDate Desc"; + + //private const string SqlSelectByTaxis = "SELECT Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues FROM siteserver_Channel WHERE ParentId = @ParentId ORDER BY Taxis"; + + //private const string SqlSelectParentId = "SELECT ParentId FROM siteserver_Channel WHERE Id = @Id"; + + //private const string SqlSelectCount = "SELECT COUNT(*) FROM siteserver_Channel WHERE ParentId = @ParentId"; + + //private const string SqlSelectSiteIdById = "SELECT SiteId FROM siteserver_Channel WHERE Id = @Id"; + + //private const string SqlSelectIndexNameCollection = "SELECT DISTINCT IndexName FROM siteserver_Channel WHERE SiteId = @SiteId"; + + //private const string SqlUpdate = "UPDATE siteserver_Channel SET ChannelName = @ChannelName, ContentModelPluginId = @ContentModelPluginId, ContentRelatedPluginIds = @ContentRelatedPluginIds, ParentsPath = @ParentsPath, ParentsCount = @ParentsCount, ChildrenCount = @ChildrenCount, IsLastNode = @IsLastNode, IndexName = @IndexName, GroupNameCollection = @GroupNameCollection, ImageUrl = @ImageUrl, Content = @Content, FilePath = @FilePath, ChannelFilePathRule = @ChannelFilePathRule, ContentFilePathRule = @ContentFilePathRule, LinkUrl = @LinkUrl,LinkType = @LinkType, ChannelTemplateId = @ChannelTemplateId, ContentTemplateId = @ContentTemplateId, Keywords = @Keywords, Description = @Description, ExtendValues = @ExtendValues WHERE Id = @Id"; + + //private const string SqlUpdateExtendValues = "UPDATE siteserver_Channel SET ExtendValues = @ExtendValues WHERE Id = @Id"; + + //private const string SqlUpdateGroupNameCollection = "UPDATE siteserver_Channel SET GroupNameCollection = @GroupNameCollection WHERE Id = @Id"; + + //private const string ParamId = "@Id"; + //private const string ParamChannelName = "@ChannelName"; + //private const string ParamSiteId = "@SiteId"; + //private const string ParamContentModelPluginId = "@ContentModelPluginId"; + //private const string ParamContentRelatedPluginIds = "@ContentRelatedPluginIds"; + //private const string ParamParentId = "@ParentId"; + //private const string ParamParentsPath = "@ParentsPath"; + //private const string ParamParentsCount = "@ParentsCount"; + //private const string ParamChildrenCount = "@ChildrenCount"; + //private const string ParamIsLastNode = "@IsLastNode"; + //private const string ParamIndexName = "@IndexName"; + //private const string ParamGroupNameCollection = "@GroupNameCollection"; + //private const string ParamTaxis = "@Taxis"; + //private const string ParamAddDate = "@AddDate"; + //private const string ParamImageUrl = "@ImageUrl"; + //private const string ParamContent = "@Content"; + //private const string ParamFilePath = "@FilePath"; + //private const string ParamChannelFilePathRule = "@ChannelFilePathRule"; + //private const string ParamContentFilePathRule = "@ContentFilePathRule"; + //private const string ParamLinkUrl = "@LinkUrl"; + //private const string ParamLinkType = "@LinkType"; + //private const string ParamChannelTemplateId = "@ChannelTemplateId"; + //private const string ParamContentTemplateId = "@ContentTemplateId"; + //private const string ParamKeywords = "@Keywords"; + //private const string ParamDescription = "@Description"; + //private const string ParamExtendValues = "@ExtendValues"; + + private static class Attr + { + public const string Id = nameof(ChannelInfo.Id); + public const string SiteId = nameof(ChannelInfo.SiteId); + public const string ContentModelPluginId = nameof(ChannelInfo.ContentModelPluginId); + public const string ParentId = nameof(ChannelInfo.ParentId); + public const string ParentsPath = nameof(ChannelInfo.ParentsPath); + public const string ChildrenCount = nameof(ChannelInfo.ChildrenCount); + public const string IsLastNode = "IsLastNode"; + public const string IndexName = nameof(ChannelInfo.IndexName); + public const string GroupNameCollection = nameof(ChannelInfo.GroupNameCollection); + public const string Taxis = nameof(ChannelInfo.Taxis); + public const string AddDate = nameof(ChannelInfo.AddDate); + public const string FilePath = nameof(ChannelInfo.FilePath); + public const string ChannelTemplateId = nameof(ChannelInfo.ChannelTemplateId); + public const string ContentTemplateId = nameof(ChannelInfo.ContentTemplateId); + public const string ExtendValues = "ExtendValues"; + } + + private void InsertChannelInfo(ChannelInfo parentChannelInfo, ChannelInfo channelInfo) + { + if (parentChannelInfo != null) + { + channelInfo.SiteId = parentChannelInfo.SiteId; + if (parentChannelInfo.ParentsPath.Length == 0) + { + channelInfo.ParentsPath = parentChannelInfo.Id.ToString(); + } + else + { + channelInfo.ParentsPath = parentChannelInfo.ParentsPath + "," + parentChannelInfo.Id; + } + channelInfo.ParentsCount = parentChannelInfo.ParentsCount + 1; + + var maxTaxis = GetMaxTaxisByParentPath(channelInfo.ParentsPath); + if (maxTaxis == 0) + { + maxTaxis = parentChannelInfo.Taxis; + } + channelInfo.Taxis = maxTaxis + 1; + } + else + { + channelInfo.Taxis = 1; + } + + channelInfo.ChildrenCount = 0; + channelInfo.LastNode = true; + + //const string sqlInsertNode = "INSERT INTO siteserver_Channel (ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues) VALUES (@ChannelName, @SiteId, @ContentModelPluginId, @ContentRelatedPluginIds, @ParentId, @ParentsPath, @ParentsCount, @ChildrenCount, @IsLastNode, @IndexName, @GroupNameCollection, @Taxis, @AddDate, @ImageUrl, @Content, @FilePath, @ChannelFilePathRule, @ContentFilePathRule, @LinkUrl, @LinkType, @ChannelTemplateId, @ContentTemplateId, @Keywords, @Description, @ExtendValues)"; + + //IDataParameter[] insertParams = + //{ + // GetParameter(ParamChannelName, channelInfo.ChannelName), + // GetParameter(ParamSiteId, channelInfo.SiteId), + // GetParameter(ParamContentModelPluginId, channelInfo.ContentModelPluginId), + // GetParameter(ParamContentRelatedPluginIds, channelInfo.ContentRelatedPluginIds), + // GetParameter(ParamParentId, channelInfo.ParentId), + // GetParameter(ParamParentsPath, channelInfo.ParentsPath), + // GetParameter(ParamParentsCount, channelInfo.ParentsCount), + // GetParameter(ParamChildrenCount, 0), + // GetParameter(ParamIsLastNode, true.ToString()), + // GetParameter(ParamIndexName, channelInfo.IndexName), + // GetParameter(ParamGroupNameCollection, channelInfo.GroupNameCollection), + // GetParameter(ParamTaxis, channelInfo.Taxis), + // GetParameter(ParamAddDate, channelInfo.AddDate), + // GetParameter(ParamImageUrl, channelInfo.ImageUrl), + // GetParameter(ParamContent, channelInfo.Content), + // GetParameter(ParamFilePath, channelInfo.FilePath), + // GetParameter(ParamChannelFilePathRule, channelInfo.ChannelFilePathRule), + // GetParameter(ParamContentFilePathRule, channelInfo.ContentFilePathRule), + // GetParameter(ParamLinkUrl, channelInfo.LinkUrl), + // GetParameter(ParamLinkType, channelInfo.LinkType), + // GetParameter(ParamChannelTemplateId, channelInfo.ChannelTemplateId), + // GetParameter(ParamContentTemplateId, channelInfo.ContentTemplateId), + // GetParameter(ParamKeywords, channelInfo.Keywords), + // GetParameter(ParamDescription, channelInfo.Description), + // GetParameter(ParamExtendValues, channelInfo.Attributes.ToString()) + //}; + + if (channelInfo.SiteId != 0) + { + //var sqlString = + // $"UPDATE siteserver_Channel SET Taxis = {DatorySql.ColumnIncrement("Taxis")} WHERE (Taxis >= {channelInfo.Taxis}) AND (SiteId = {channelInfo.SiteId})"; + //DatabaseApi.ExecuteNonQuery(trans, sqlString); + + Increment(Q + .Select(Attr.Taxis) + .Where(Attr.Taxis, ">=", channelInfo.Taxis) + .Where(Attr.SiteId, channelInfo.SiteId) + ); + } + //channelInfo.Id = DatabaseApi.ExecuteNonQueryAndReturnId(TableName, nameof(ChannelInfo.Id), trans, sqlInsertNode, insertParams); + Insert(channelInfo); + + if (!string.IsNullOrEmpty(channelInfo.ParentsPath)) + { + //var sqlString = $"UPDATE siteserver_Channel SET ChildrenCount = {DatorySql.ColumnIncrement("ChildrenCount")} WHERE Id IN ({channelInfo.ParentsPath})"; + + //DatabaseApi.ExecuteNonQuery(trans, sqlString); + + Increment(Q + .Select(Attr.ChildrenCount) + .WhereIn(Attr.ParentsPath, + TranslateUtils.StringCollectionToIntList(channelInfo.ParentsPath)) + ); + } + + //var sqlUpdateIsLastNode = "UPDATE siteserver_Channel SET IsLastNode = @IsLastNode WHERE ParentId = @ParentId"; + //IDataParameter[] parameters = + //{ + // GetParameter(ParamIsLastNode, false.ToString()), + // GetParameter(ParamParentId, channelInfo.ParentId) + //}; + //DatabaseApi.ExecuteNonQuery(trans, sqlUpdateIsLastNode, parameters); + + Update(Q + .Set(Attr.IsLastNode, false.ToString()) + .Where(Attr.ParentId, channelInfo.ParentId) + ); + + //sqlUpdateIsLastNode = + // $"UPDATE siteserver_Channel SET IsLastNode = '{true}' WHERE (Id IN ({SqlUtils.ToInTopSqlString(TableName, new List{ nameof(ChannelInfo.Id) }, $"WHERE ParentId = {channelInfo.ParentId}", "ORDER BY Taxis DESC", 1)}))"; + //DatabaseApi.ExecuteNonQuery(trans, sqlUpdateIsLastNode); + var topId = Get(Q + .Select(Attr.Id) + .Where(Attr.ParentId, channelInfo.ParentId) + .OrderByDesc(Attr.Taxis)); + + if (topId > 0) + { + Update(Q + .Set(Attr.IsLastNode, true.ToString()) + .Where(nameof(Attr.Id), topId) + ); + } + + //OwningIdCache.IsChanged = true; + ChannelManager.RemoveCacheBySiteId(channelInfo.SiteId); + PermissionsImpl.ClearAllCache(); + } + + /// + /// 将节点数减1 + /// + /// + /// + private void UpdateSubtractChildrenCount(string parentsPath, int subtractNum) + { + if (string.IsNullOrEmpty(parentsPath)) return; + + //var sqlString = string.Concat("UPDATE siteserver_Channel SET ChildrenCount = ChildrenCount - ", subtractNum, " WHERE Id in (", parentsPath, ")"); + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + Decrement(Q + .Select(Attr.ChildrenCount) + .WhereIn(Attr.Id, TranslateUtils.StringCollectionToIntList(parentsPath)), + subtractNum); + } + + /// + /// Change The Taxis To Lower Level + /// + private void TaxisSubtract(int siteId, int selectedId) + { + var channelInfo = ChannelManager.GetChannelInfo(siteId, selectedId); + if (channelInfo == null || channelInfo.ParentId == 0 || channelInfo.SiteId == 0) return; + //UpdateWholeTaxisBySiteId(channelInfo.SiteId); + //Get Lower Taxis and Id + //int lowerId; + //int lowerChildrenCount; + //string lowerParentsPath; + + //var sqlString = DatorySql.GetSqlString(TableName, new List + //{ + // nameof(ChannelInfo.Id), + // nameof(ChannelInfo.ChildrenCount), + // nameof(ChannelInfo.ParentsPath) + //}, "WHERE (ParentId = @ParentId) AND (Id <> @Id) AND (Taxis < @Taxis) AND (SiteId = @SiteId)", "ORDER BY Taxis DESC", 1); + //IDataParameter[] parameters = + //{ + // GetParameter(ParamParentId, channelInfo.ParentId), + // GetParameter(ParamId, channelInfo.Id), + // GetParameter(ParamTaxis, channelInfo.Taxis), + // GetParameter(ParamSiteId, channelInfo.SiteId) + //}; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // lowerId = DatabaseApi.GetInt(rdr, 0); + // lowerChildrenCount = DatabaseApi.GetInt(rdr, 1); + // lowerParentsPath = DatabaseApi.GetString(rdr, 2); + // } + // else + // { + // return; + // } + // rdr.Close(); + //} + var dataInfo = Get(Q + .Where(Attr.ParentId, channelInfo.ParentId) + .WhereNot(Attr.Id, channelInfo.Id) + .Where(Attr.Taxis, "<", channelInfo.Taxis) + .Where(Attr.SiteId, channelInfo.SiteId) + .OrderByDesc(Attr.Taxis)); + if (dataInfo == null) return; + + var lowerId = dataInfo.Id; + var lowerChildrenCount = dataInfo.ChildrenCount; + var lowerParentsPath = dataInfo.ParentsPath; + + var lowerPath = lowerParentsPath == "" ? lowerId.ToString() : string.Concat(lowerParentsPath, ",", lowerId); + var selectedPath = channelInfo.ParentsPath == "" ? channelInfo.Id.ToString() : string.Concat(channelInfo.ParentsPath, ",", channelInfo.Id); + + SetTaxisSubtract(selectedId, selectedPath, lowerChildrenCount + 1); + SetTaxisAdd(lowerId, lowerPath, channelInfo.ChildrenCount + 1); + + UpdateIsLastNode(channelInfo.ParentId); + } + + /// + /// Change The Taxis To Higher Level + /// + private void TaxisAdd(int siteId, int selectedId) + { + var channelInfo = ChannelManager.GetChannelInfo(siteId, selectedId); + if (channelInfo == null || channelInfo.ParentId == 0 || channelInfo.SiteId == 0) return; + //UpdateWholeTaxisBySiteId(channelInfo.SiteId); + //Get Higher Taxis and Id + //int higherId; + //int higherChildrenCount; + //string higherParentsPath; + + //var sqlString = DatorySql.GetSqlString(TableName, new List + //{ + // nameof(ChannelInfo.Id), + // nameof(ChannelInfo.ChildrenCount), + // nameof(ChannelInfo.ParentsPath) + //}, "WHERE (ParentId = @ParentId) AND (Id <> @Id) AND (Taxis > @Taxis) AND (SiteId = @SiteId)", "ORDER BY Taxis", 1); + //IDataParameter[] parameters = + //{ + // GetParameter(ParamParentId, channelInfo.ParentId), + // GetParameter(ParamId, channelInfo.Id), + // GetParameter(ParamTaxis, channelInfo.Taxis), + // GetParameter(ParamSiteId, channelInfo.SiteId) + //}; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // higherId = DatabaseApi.GetInt(rdr, 0); + // higherChildrenCount = DatabaseApi.GetInt(rdr, 1); + // higherParentsPath = DatabaseApi.GetString(rdr, 2); + // } + // else + // { + // return; + // } + // rdr.Close(); + //} + var dataInfo = Get(Q + .Where(Attr.ParentId, channelInfo.ParentId) + .WhereNot(Attr.Id, channelInfo.Id) + .Where(Attr.Taxis, ">", channelInfo.Taxis) + .Where(Attr.SiteId, channelInfo.SiteId) + .OrderBy(Attr.Taxis)); + + if (dataInfo == null) return; + + var higherId = dataInfo.Id; + var higherChildrenCount = dataInfo.ChildrenCount; + var higherParentsPath = dataInfo.ParentsPath; + + var higherPath = higherParentsPath == string.Empty ? higherId.ToString() : string.Concat(higherParentsPath, ",", higherId); + var selectedPath = channelInfo.ParentsPath == string.Empty ? channelInfo.Id.ToString() : String.Concat(channelInfo.ParentsPath, ",", channelInfo.Id); + + SetTaxisAdd(selectedId, selectedPath, higherChildrenCount + 1); + SetTaxisSubtract(higherId, higherPath, channelInfo.ChildrenCount + 1); + + UpdateIsLastNode(channelInfo.ParentId); + } + + private void SetTaxisAdd(int channelId, string parentsPath, int addNum) + { + //var sqlString = + // $"UPDATE siteserver_Channel SET Taxis = {DatorySql.ColumnIncrement("Taxis", addNum)} WHERE Id = {channelId} OR ParentsPath = '{parentsPath}' OR ParentsPath like '{parentsPath},%'"; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + Increment(Q + .Select(Attr.Taxis) + .Where(Attr.Id, channelId) + .OrWhere(Attr.ParentsPath, parentsPath) + .OrWhereStarts(Attr.ParentsPath, $"{parentsPath},"), addNum + ); + } + + private void SetTaxisSubtract(int channelId, string parentsPath, int subtractNum) + { + //string sqlString = + // $"UPDATE siteserver_Channel SET Taxis = {DatorySql.ColumnDecrement("Taxis", subtractNum)} WHERE Id = {channelId} OR ParentsPath = '{parentsPath}' OR ParentsPath like '{parentsPath},%'"; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + Decrement(Q + .Select(Attr.Taxis) + .Where(Attr.Id, channelId) + .OrWhere(Attr.ParentsPath, parentsPath) + .OrWhereStarts(Attr.ParentsPath, $"{parentsPath},"), subtractNum); + } + + private void UpdateIsLastNode(int parentId) + { + if (parentId <= 0) return; + + //var sqlString = "UPDATE siteserver_Channel SET IsLastNode = @IsLastNode WHERE ParentId = @ParentId"; + //IDataParameter[] parameters = + //{ + // GetParameter(ParamIsLastNode, false.ToString()), + // GetParameter(ParamParentId, parentId) + //}; + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Update(Q + .Set(Attr.IsLastNode, false.ToString()) + .Where(Attr.ParentId, parentId) + ); + + //sqlString = + // $"UPDATE siteserver_Channel SET IsLastNode = '{true}' WHERE (Id IN ({SqlUtils.ToInTopSqlString(TableName, new List { Attr.Id }, $"WHERE ParentId = {parentId}", "ORDER BY Taxis DESC", 1)}))"; + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + var topId = Get(Q + .Select(Attr.Id) + .Where(Attr.ParentId, parentId) + .OrderByDesc(Attr.Taxis)); + + if (topId > 0) + { + Update(Q + .Set(Attr.IsLastNode, true.ToString()) + .Where(Attr.Id, topId) + ); + } + } + + private int GetMaxTaxisByParentPath(string parentPath) + { + //var cmd = string.Concat("SELECT MAX(Taxis) AS MaxTaxis FROM siteserver_Channel WHERE (ParentsPath = '", parentPath, "') OR (ParentsPath like '", parentPath, ",%')"); + //var maxTaxis = 0; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, cmd)) + //{ + // if (rdr.Read()) + // { + // maxTaxis = DatabaseApi.GetInt(rdr, 0); + // } + // rdr.Close(); + //} + //return maxTaxis; + return Max(Q + .Select(Attr.Taxis) + .Where(Attr.ParentsPath, parentPath) + .OrWhereStarts(Attr.ParentsPath, $"{parentPath},") + ) ?? 0; + } + + private int GetParentId(int channelId) + { + //var parentId = 0; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamId, channelId) + //}; + + //"SELECT ParentId FROM siteserver_Channel WHERE Id = @Id" + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectParentId, parameters)) + //{ + // if (rdr.Read()) + // { + // parentId = DatabaseApi.GetInt(rdr, 0); + // } + // rdr.Close(); + //} + //return parentId; + + return Get(Q + .Select(Attr.ParentId) + .Where(Attr.Id, channelId)); + } + + private int GetIdByParentIdAndOrder(int parentId, int order) + { + //var channelId = parentId; + + //string cmd = $"SELECT Id FROM siteserver_Channel WHERE (ParentId = {parentId}) ORDER BY Taxis"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, cmd)) + //{ + // var index = 1; + // while (rdr.Read()) + // { + // channelId = DatabaseApi.GetInt(rdr, 0); + // if (index == order) + // break; + // index++; + // } + // rdr.Close(); + //} + //return channelId; + + var idList = GetAll(Q + .Select(Attr.Id) + .Where(Attr.ParentId, parentId) + .OrderBy(Attr.Taxis)); + + for (var i = 0; i < idList.Count; i++) + { + if (i + 1 == order) + { + return idList[i]; + } + } + + return parentId; + } + + public int Insert(int siteId, int parentId, string channelName, string indexName, string contentModelPluginId, string contentRelatedPluginIds, int channelTemplateId, int contentTemplateId) + { + if (siteId > 0 && parentId == 0) return 0; + + var defaultChannelTemplateInfo = TemplateManager.GetDefaultTemplateInfo(siteId, TemplateType.ChannelTemplate); + var defaultContentTemplateInfo = TemplateManager.GetDefaultTemplateInfo(siteId, TemplateType.ContentTemplate); + + var channelInfo = new ChannelInfo + { + ParentId = parentId, + SiteId = siteId, + ChannelName = channelName, + IndexName = indexName, + ContentModelPluginId = contentModelPluginId, + ContentRelatedPluginIds = contentRelatedPluginIds, + AddDate = DateTime.Now, + ChannelTemplateId = channelTemplateId > 0 ? channelTemplateId : defaultChannelTemplateInfo.Id, + ContentTemplateId = contentTemplateId > 0 ? contentTemplateId : defaultContentTemplateInfo.Id + }; + + var parentChannelInfo = ChannelManager.GetChannelInfo(siteId, parentId); + + InsertChannelInfo(parentChannelInfo, channelInfo); + + return channelInfo.Id; + + } + + public override int Insert(ChannelInfo channelInfo) + { + if (channelInfo.SiteId > 0 && channelInfo.ParentId == 0) return 0; + + var parentChannelInfo = ChannelManager.GetChannelInfo(channelInfo.SiteId, channelInfo.ParentId); + + InsertChannelInfo(parentChannelInfo, channelInfo); + + return channelInfo.Id; + } + + /// + /// 添加后台发布节点 + /// + public int InsertSiteInfo(ChannelInfo channelInfo, SiteInfo siteInfo, string administratorName) + { + InsertChannelInfo(null, channelInfo); + + siteInfo.Id = channelInfo.Id; + + DataProvider.Site.Insert(siteInfo); + + var adminInfo = AdminManager.GetAdminInfoByUserName(administratorName); + DataProvider.Administrator.UpdateSiteId(adminInfo, channelInfo.Id); + + //var sqlString = + // $"UPDATE siteserver_Channel SET SiteId = {channelInfo.Id} WHERE Id = {channelInfo.Id}"; + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + Update(Q + .Set(Attr.SiteId, channelInfo.Id) + .Where(Attr.Id, channelInfo.Id) + ); + + DataProvider.Template.CreateDefaultTemplateInfo(channelInfo.Id, administratorName); + return channelInfo.Id; + } + + public override bool Update(ChannelInfo channelInfo) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamChannelName, channelInfo.ChannelName), + // GetParameter(ParamContentModelPluginId, channelInfo.ContentModelPluginId), + // GetParameter(ParamContentRelatedPluginIds, channelInfo.ContentRelatedPluginIds), + // GetParameter(ParamParentsPath, channelInfo.ParentsPath), + // GetParameter(ParamParentsCount, channelInfo.ParentsCount), + // GetParameter(ParamChildrenCount, channelInfo.ChildrenCount), + // GetParameter(ParamIsLastNode, channelInfo.IsLastNode.ToString()), + // GetParameter(ParamIndexName, channelInfo.IndexName), + // GetParameter(ParamGroupNameCollection, channelInfo.GroupNameCollection), + // GetParameter(ParamImageUrl, channelInfo.ImageUrl), + // GetParameter(ParamContent,channelInfo.Content), + // GetParameter(ParamFilePath, channelInfo.FilePath), + // GetParameter(ParamChannelFilePathRule, channelInfo.ChannelFilePathRule), + // GetParameter(ParamContentFilePathRule, channelInfo.ContentFilePathRule), + // GetParameter(ParamLinkUrl, channelInfo.LinkUrl), + // GetParameter(ParamLinkType, channelInfo.LinkType), + // GetParameter(ParamChannelTemplateId, channelInfo.ChannelTemplateId), + // GetParameter(ParamContentTemplateId, channelInfo.ContentTemplateId), + // GetParameter(ParamKeywords, channelInfo.Keywords), + // GetParameter(ParamDescription, channelInfo.Description), + // GetParameter(ParamExtendValues,channelInfo.Attributes.ToString()), + // GetParameter(ParamId, channelInfo.Id) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdate, parameters); + var updated = base.Update(channelInfo); + + ChannelManager.UpdateCache(channelInfo.SiteId, channelInfo); + + return updated; + + //ChannelManager.RemoveCache(channelInfo.ParentId == 0 + // ? channelInfo.Id + // : channelInfo.SiteId); + } + + public void UpdateChannelTemplateId(ChannelInfo channelInfo) + { + //string sqlString = + // $"UPDATE siteserver_Channel SET ChannelTemplateId = {channelInfo.ChannelTemplateId} WHERE Id = {channelInfo.Id}"; + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + Update(Q + .Set(Attr.ChannelTemplateId, channelInfo.ChannelTemplateId) + .Where(Attr.Id, channelInfo.Id) + ); + + ChannelManager.UpdateCache(channelInfo.SiteId, channelInfo); + } + + public void UpdateContentTemplateId(ChannelInfo channelInfo) + { + //string sqlString = + // $"UPDATE siteserver_Channel SET ContentTemplateId = {channelInfo.ContentTemplateId} WHERE Id = {channelInfo.Id}"; + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + Update(Q + .Set(Attr.ContentTemplateId, channelInfo.ContentTemplateId) + .Where(Attr.Id, channelInfo.Id) + ); + + ChannelManager.UpdateCache(channelInfo.SiteId, channelInfo); + } + + public void UpdateExtend(ChannelInfo channelInfo) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamExtendValues,channelInfo.ToString()), + // GetParameter(ParamId, channelInfo.Id) + //}; + //"UPDATE siteserver_Channel SET ExtendValues = @ExtendValues WHERE Id = @Id" + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdateExtendValues, parameters); + + Update(Q + .Set(Attr.ExtendValues, channelInfo.ExtendValues) + .Where(Attr.Id, channelInfo.Id) + ); + + ChannelManager.UpdateCache(channelInfo.SiteId, channelInfo); + } + + /// + /// 修改排序 + /// + public void UpdateTaxis(int siteId, int selectedId, bool isSubtract) + { + if (isSubtract) + { + TaxisSubtract(siteId, selectedId); + } + else + { + TaxisAdd(siteId, selectedId); + } + ChannelManager.RemoveCacheBySiteId(siteId); + } + + public void AddGroupNameList(int siteId, int channelId, List groupList) + { + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return; + + var list = TranslateUtils.StringCollectionToStringList(channelInfo.GroupNameCollection); + foreach (var groupName in groupList) + { + if (!list.Contains(groupName)) list.Add(groupName); + } + + channelInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(list); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamGroupNameCollection, channelInfo.GroupNameCollection), + // GetParameter(ParamId, channelId) + //}; + //"UPDATE siteserver_Channel SET GroupNameCollection = @GroupNameCollection WHERE Id = @Id" + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdateGroupNameCollection, parameters); + + Update(Q + .Set(Attr.GroupNameCollection, channelInfo.GroupNameCollection) + .Where(Attr.Id, channelId) + ); + + ChannelManager.UpdateCache(siteId, channelInfo); + } + + public void DeleteAll(int siteId) + { + base.Delete(Q.Where(Attr.SiteId, siteId).OrWhere(Attr.Id, siteId)); + } + + public void Delete(int siteId, int channelId) + { + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return; + + var idList = new List(); + if (channelInfo.ChildrenCount > 0) + { + idList = ChannelManager.GetChannelIdList(channelInfo, EScopeType.Descendant, string.Empty, string.Empty, string.Empty); + } + idList.Add(channelId); + + //var siteInfo = SiteManager.GetSiteInfo(siteId); + + foreach (var i in idList) + { + var cInfo = ChannelManager.GetChannelInfo(siteId, i); + cInfo.ContentRepository.UpdateTrashContentsByChannelId(siteId, i); + } + + //DataProvider.ContentRepository.DeleteContentsByDeletedChannelIdList(siteInfo, idList); + + //var deleteCmd = + // $"DELETE FROM siteserver_Channel WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + //deletedNum = DatabaseApi.ExecuteNonQuery(trans, deleteCmd); + var deletedNum = Delete(Q + .WhereIn(Attr.Id, idList)); + + if (channelInfo.ParentId != 0) + { + //var taxisCmd = + // $"UPDATE siteserver_Channel SET Taxis = Taxis - {deletedNum} WHERE (Taxis > {channelInfo.Taxis}) AND (SiteId = {channelInfo.SiteId})"; + //DatabaseApi.ExecuteNonQuery(trans, taxisCmd); + Decrement(Q + .Select(Attr.Taxis) + .Where(Attr.SiteId, channelInfo.SiteId) + .Where(Attr.Taxis, ">", channelInfo.Taxis), deletedNum + ); + } + + UpdateIsLastNode(channelInfo.ParentId); + UpdateSubtractChildrenCount(channelInfo.ParentsPath, deletedNum); + + if (channelInfo.ParentId == 0) + { + DataProvider.Site.Delete(channelInfo.Id); + } + else + { + ChannelManager.RemoveCacheBySiteId(channelInfo.SiteId); + } + } + + /// + /// 得到最后一个添加的子节点 + /// + public ChannelInfo GetChannelInfoByLastAddDate(int channelId) + { + //ChannelInfo channelInfo = null; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamParentId, channelId) + //}; + //"SELECT Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues FROM siteserver_Channel WHERE ParentId = @ParentId ORDER BY AddDate Desc" + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectByLastAddDate, parameters)) + //{ + // if (rdr.Read()) + // { + // channelInfo = GetChannelInfo(rdr); + // } + // rdr.Close(); + //} + //return channelInfo; + return Get(Q + .Where(Attr.ParentId, channelId) + .OrderByDesc(Attr.AddDate)); + } + + /// + /// 得到第一个子节点 + /// + public ChannelInfo GetChannelInfoByTaxis(int channelId) + { + //ChannelInfo channelInfo = null; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamParentId, channelId) + //}; + //"SELECT Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues FROM siteserver_Channel WHERE ParentId = @ParentId ORDER BY Taxis" + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectByTaxis, parameters)) + //{ + // if (rdr.Read()) + // { + // channelInfo = GetChannelInfo(rdr); + // } + // rdr.Close(); + //} + //return channelInfo; + + return Get(Q + .Where(Attr.ParentId, channelId) + .OrderBy(Attr.Taxis)); + } + + public int GetIdByParentIdAndTaxis(int parentId, int taxis, bool isNextChannel) + { + //var channelId = 0; + + //var sqlString = isNextChannel ? $"SELECT TOP 1 Id FROM siteserver_Channel WHERE (ParentId = {parentId} AND Taxis > {taxis}) ORDER BY Taxis" : $"SELECT TOP 1 Id FROM siteserver_Channel WHERE (ParentId = {parentId} AND Taxis < {taxis}) ORDER BY Taxis DESC"; + //var sqlString = isNextChannel + // ? DatorySql.GetSqlString(TableName, new List + // { + // Attr.Id + // }, + // $"WHERE (ParentId = {parentId} AND Taxis > {taxis})", "ORDER BY Taxis", 1) + // : DatorySql.GetSqlString(TableName, new List + // { + // Attr.Id + // }, + // $"WHERE (ParentId = {parentId} AND Taxis < {taxis})", "ORDER BY Taxis DESC", 1); + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // if (rdr.Read()) + // { + // channelId = DatabaseApi.GetInt(rdr, 0); + // } + // rdr.Close(); + //} + //return channelId; + + int channelId; + if (isNextChannel) + { + channelId = Get(Q + .Select(Attr.Id) + .Where(Attr.ParentId, parentId) + .Where(Attr.Taxis, ">", taxis) + .OrderBy(Attr.Taxis)); + } + else + { + channelId = Get(Q + .Select(Attr.Id) + .Where(Attr.ParentId, parentId) + .Where(Attr.Taxis, "<", taxis) + .OrderByDesc(Attr.Taxis)); + } + + return channelId; + } + + public int GetId(int siteId, string orderString) + { + if (orderString == "1") + return siteId; + + var channelId = siteId; + + var orderArr = orderString.Split('_'); + for (var index = 1; index < orderArr.Length; index++) + { + var order = int.Parse(orderArr[index]); + channelId = GetIdByParentIdAndOrder(channelId, order); + } + return channelId; + } + + public int GetSiteId(int channelId) + { + //var siteId = 0; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamId, channelId) + //}; + //"SELECT SiteId FROM siteserver_Channel WHERE Id = @Id" + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectSiteIdById, parameters)) + //{ + // if (rdr.Read()) + // { + // siteId = DatabaseApi.GetInt(rdr, 0); + // if (siteId == 0) + // { + // siteId = channelId; + // } + // } + // rdr.Close(); + //} + //return siteId; + + var siteId = Get(Q + .Select(Attr.SiteId) + .Where(Attr.Id, channelId)); + + if (siteId == 0) + { + siteId = channelId; + } + + return siteId; + } + + /// + /// 在节点树中得到此节点的排序号,以“1_2_5_2”的形式表示 + /// + public string GetOrderStringInSite(int channelId) + { + var retVal = ""; + if (channelId != 0) + { + var parentId = GetParentId(channelId); + if (parentId != 0) + { + var orderString = GetOrderStringInSite(parentId); + retVal = orderString + "_" + GetOrderInSibling(channelId, parentId); + } + else + { + retVal = "1"; + } + } + return retVal; + } + + private int GetOrderInSibling(int channelId, int parentId) + { + //string cmd = $"SELECT Id FROM siteserver_Channel WHERE (ParentId = {parentId}) ORDER BY Taxis"; + //var idList = new List(); + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, cmd)) + //{ + // while (rdr.Read()) + // { + // idList.Add(DatabaseApi.GetInt(rdr, 0)); + // } + // rdr.Close(); + //} + var idList = GetAll(Q + .Select(Attr.Id) + .Where(Attr.ParentId, parentId) + .OrderBy(Attr.Taxis)); + + return idList.IndexOf(channelId) + 1; + } + + public IList GetIndexNameList(int siteId) + { + //var list = new List(); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamSiteId, siteId) + //}; + //"SELECT DISTINCT IndexName FROM siteserver_Channel WHERE SiteId = @SiteId" + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectIndexNameCollection, parameters)) + //{ + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetString(rdr, 0)); + // } + // rdr.Close(); + //} + + //return list; + + return GetAll(Q + .Select(Attr.IndexName) + .Where(Attr.SiteId, siteId) + .Distinct()); + } + + private static string GetGroupWhereString(string group, string groupNot) + { + var whereStringBuilder = new StringBuilder(); + if (!string.IsNullOrEmpty(group)) + { + group = group.Trim().Trim(','); + var groupArr = group.Split(','); + if (groupArr.Length > 0) + { + whereStringBuilder.Append(" AND ("); + foreach (var theGroup in groupArr) + { + var trimGroup = theGroup.Trim(); + + whereStringBuilder.Append( + $" (siteserver_Channel.GroupNameCollection = '{trimGroup}' OR {SqlUtils.GetInStr("siteserver_Channel.GroupNameCollection", trimGroup + ",")} OR {SqlUtils.GetInStr("siteserver_Channel.GroupNameCollection", "," + trimGroup + ",")} OR {SqlUtils.GetInStr("siteserver_Channel.GroupNameCollection", "," + trimGroup)}) OR "); + } + if (groupArr.Length > 0) + { + whereStringBuilder.Length = whereStringBuilder.Length - 3; + } + whereStringBuilder.Append(") "); + } + } + + if (!string.IsNullOrEmpty(groupNot)) + { + groupNot = groupNot.Trim().Trim(','); + var groupNotArr = groupNot.Split(','); + if (groupNotArr.Length > 0) + { + whereStringBuilder.Append(" AND ("); + foreach (var theGroupNot in groupNotArr) + { + var trimGroupNot = theGroupNot.Trim(); + + whereStringBuilder.Append( + $" (siteserver_Channel.GroupNameCollection <> '{trimGroupNot}' AND {SqlUtils.GetNotInStr("siteserver_Channel.GroupNameCollection", trimGroupNot + ",")} AND {SqlUtils.GetNotInStr("siteserver_Channel.GroupNameCollection", "," + trimGroupNot + ",")} AND {SqlUtils.GetNotInStr("siteserver_Channel.GroupNameCollection", "," + trimGroupNot)}) AND "); + } + if (groupNotArr.Length > 0) + { + whereStringBuilder.Length = whereStringBuilder.Length - 4; + } + whereStringBuilder.Append(") "); + } + } + return whereStringBuilder.ToString(); + } + + public string GetWhereString(string group, string groupNot, bool isImageExists, bool isImage, string where) + { + var whereStringBuilder = new StringBuilder(); + if (isImageExists) + { + whereStringBuilder.Append(isImage + ? " AND siteserver_Channel.ImageUrl <> '' " + : " AND siteserver_Channel.ImageUrl = '' "); + } + + whereStringBuilder.Append(GetGroupWhereString(group, groupNot)); + + if (!string.IsNullOrEmpty(where)) + { + whereStringBuilder.Append($" AND {where} "); + } + + return whereStringBuilder.ToString(); + } + + public int GetCount(int channelId) + { + //var count = 0; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamParentId, channelId) + //}; + //"SELECT COUNT(*) FROM siteserver_Channel WHERE ParentId = @ParentId" + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectCount, parameters)) + //{ + // if (rdr.Read()) + // { + // count = DatabaseApi.GetInt(rdr, 0); + // } + // rdr.Close(); + //} + //return count; + + return Count(Q + .Where(Attr.ParentId, channelId)); + } + + public int GetSequence(int siteId, int channelId) + { + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + + //string sqlString = + // $"SELECT COUNT(*) AS TotalNum FROM siteserver_Channel WHERE SiteId = {siteId} AND ParentId = {channelInfo.ParentId} AND Taxis > (SELECT Taxis FROM siteserver_Channel WHERE Id = {channelId})"; + + //return DatabaseApi.Instance.GetIntResult(sqlString) + 1; + + var taxis = Get(Q + .Select(Attr.Taxis) + .Where(Attr.Id, channelId)); + return Count(Q + .Where(Attr.SiteId, siteId) + .Where(Attr.ParentId, channelInfo.ParentId) + .Where(Attr.Taxis, ">", taxis) + ) + 1; + } + + public List GetIdListByTotalNum(List channelIdList, int totalNum, string orderByString, string whereString) + { + if (channelIdList == null || channelIdList.Count == 0) + { + return channelIdList; + } + + string sqlString; + if (totalNum > 0) + { + // sqlString = $@"SELECT TOP {totalNum} Id + //FROM siteserver_Channel + //WHERE (Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) {whereString}) {orderByString} + //"; + //var where = + // $"WHERE (Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) {whereString})"; + var where = + $"WHERE {SqlUtils.GetSqlColumnInList("Id", channelIdList)} {whereString})"; + sqlString = DataProvider.DatabaseApi.GetSqlString(DatabaseType, ConnectionString, TableName, new List + { + Attr.Id + }, + where, + orderByString, + totalNum); + } + else + { + // sqlString = $@"SELECT Id + //FROM siteserver_Channel + //WHERE (Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) {whereString}) {orderByString} + //"; + sqlString = $@"SELECT Id +FROM siteserver_Channel +WHERE {SqlUtils.GetSqlColumnInList("Id", channelIdList)} {whereString} {orderByString} +"; + } + + var list = new List(); + + using (var rdr = DataProvider.DatabaseApi.ExecuteReader(WebConfigUtils.ConnectionString, sqlString)) + { + while (rdr.Read()) + { + list.Add(DataProvider.DatabaseApi.GetInt(rdr, 0)); + } + rdr.Close(); + } + return list; + } + + public Dictionary GetChannelInfoDictionaryBySiteId(int siteId) + { +// string sqlString = +// $@"SELECT Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues +//FROM siteserver_Channel +//WHERE (SiteId = {siteId} AND (Id = {siteId} OR ParentId > 0)) +//ORDER BY Taxis"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var channelInfo = GetChannelInfo(rdr); +// dict.Add(channelInfo.Id, channelInfo); +// } +// rdr.Close(); +// } + + var channelInfoList = GetAll(Q + .Where(Attr.SiteId, siteId) + .Where(q => q + .Where(Attr.Id, siteId) + .OrWhere(Attr.ParentId, ">", 0)) + .OrderBy(Attr.Taxis)); + + return channelInfoList.ToDictionary(channelInfo => channelInfo.Id); + } + + public DataSet GetStlDataSourceBySiteId(int siteId, int startNum, int totalNum, string whereString, string orderByString) + { + var sqlWhereString = $"WHERE (SiteId = {siteId} {whereString})"; + + //var sqlSelect = DatabaseApi.Instance.GetSelectSqlString(TableName, startNum, totalNum, SqlColumns, sqlWhereString, orderByString); + var sqlSelect = DataProvider.DatabaseApi.GetSqlString(DatabaseType, ConnectionString, TableName, SqlColumns, sqlWhereString, orderByString, startNum - 1, totalNum); + + return DataProvider.DatabaseApi.ExecuteDataset(WebConfigUtils.ConnectionString, sqlSelect); + } + + public DataSet GetStlDataSet(List channelIdList, int startNum, int totalNum, string whereString, string orderByString) + { + if (channelIdList == null || channelIdList.Count == 0) + { + return null; + } + + //var sqlWhereString = + // $"WHERE (Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) {whereString})"; + + var sqlWhereString = + $"WHERE {SqlUtils.GetSqlColumnInList("Id", channelIdList)} {whereString}"; + + //var sqlSelect = DatabaseApi.Instance.GetSelectSqlString(TableName, startNum, totalNum, SqlColumns, sqlWhereString, orderByString); + var sqlSelect = DataProvider.DatabaseApi.GetSqlString(DatabaseType, ConnectionString, TableName, SqlColumns, sqlWhereString, orderByString, startNum - 1, totalNum); + + return DataProvider.DatabaseApi.ExecuteDataset(WebConfigUtils.ConnectionString, sqlSelect); + } + + public DataSet GetStlDataSetBySiteId(int siteId, int startNum, int totalNum, string whereString, string orderByString) + { + var sqlWhereString = $"WHERE (SiteId = {siteId} {whereString})"; + + //var sqlSelect = DatabaseApi.Instance.GetSelectSqlString(TableName, startNum, totalNum, SqlColumns, sqlWhereString, orderByString); + var sqlSelect = DataProvider.DatabaseApi.GetSqlString(DatabaseType, ConnectionString, TableName, SqlColumns, sqlWhereString, orderByString, startNum - 1, totalNum); + + return DataProvider.DatabaseApi.ExecuteDataset(WebConfigUtils.ConnectionString, sqlSelect); + } + + public IList GetContentModelPluginIdList() + { + //var list = new List(); + + //const string sqlString = "SELECT DISTINCT ContentModelPluginId FROM siteserver_Channel"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetString(rdr, 0)); + // } + // rdr.Close(); + //} + //return list; + + return GetAll(Q + .Select(Attr.ContentModelPluginId) + .Distinct()); + } + + public IList GetAllFilePathBySiteId(int siteId) + { + //var list = new List(); + + //var sqlString = + // $"SELECT FilePath FROM siteserver_Channel WHERE FilePath <> '' AND SiteId = {siteId}"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetString(rdr, 0)); + // } + // rdr.Close(); + //} + //return list; + + return GetAll(Q + .Select(Attr.FilePath) + .Where(Attr.SiteId, siteId) + .WhereNotNull(Attr.FilePath) + .WhereNot(Attr.FilePath, string.Empty)); + } + + public int GetTemplateUseCount(int siteId, int templateId, TemplateType templateType, bool isDefault) + { + //var sqlString = string.Empty; + + if (templateType == TemplateType.IndexPageTemplate) + { + return isDefault ? 1 : 0; + } + + if (templateType == TemplateType.FileTemplate) + { + return 1; + } + + if (templateType == TemplateType.ChannelTemplate) + { + //sqlString = isDefault + // ? $"SELECT COUNT(*) FROM {TableName} WHERE ({Attr.ChannelTemplateId} = {templateId} OR {Attr.ChannelTemplateId} = 0) AND {Attr.SiteId} = {siteId}" + // : $"SELECT COUNT(*) FROM {TableName} WHERE {Attr.ChannelTemplateId} = {templateId} AND {Attr.SiteId} = {siteId}"; + + if (isDefault) + { + return Count(Q + .Where(Attr.SiteId, siteId) + .Where(q => q + .Where(Attr.ChannelTemplateId, templateId) + .OrWhere(Attr.ChannelTemplateId, 0) + .OrWhereNull(Attr.ChannelTemplateId) + )); + } + + return Count(Q + .Where(Attr.SiteId, siteId) + .Where(Attr.ChannelTemplateId, templateId)); + } + + if (templateType == TemplateType.ContentTemplate) + { + //sqlString = isDefault + // ? $"SELECT COUNT(*) FROM {TableName} WHERE ({Attr.ContentTemplateId} = {templateId} OR {Attr.ContentTemplateId} = 0) AND {Attr.SiteId} = {siteId}" + // : $"SELECT COUNT(*) FROM {TableName} WHERE {Attr.ContentTemplateId} = {templateId} AND {Attr.SiteId} = {siteId}"; + + if (isDefault) + { + return Count(Q + .Where(Attr.SiteId, siteId) + .Where(q => q.Where(Attr.ContentTemplateId, templateId) + .OrWhere(Attr.ContentTemplateId, 0) + .OrWhereNull(Attr.ContentTemplateId)) + ); + } + + return Count(Q + .Where(Attr.SiteId, siteId) + .Where(Attr.ContentTemplateId, templateId)); + } + + return 0; + + //return DatabaseApi.Instance.GetIntResult(sqlString); + } + + public IList GetChannelIdList(TemplateInfo templateInfo) + { + var list = new List(); + //var sqlString = string.Empty; + + if (templateInfo.Type == TemplateType.ChannelTemplate) + { + //sqlString = templateInfo.IsDefault + // ? $"SELECT {Attr.Id} FROM {TableName} WHERE ({Attr.ChannelTemplateId} = {templateInfo.Id} OR {Attr.ChannelTemplateId} = 0) AND {Attr.SiteId} = {templateInfo.SiteId}" + // : $"SELECT {Attr.Id} FROM {TableName} WHERE {Attr.ChannelTemplateId} = {templateInfo.Id} AND {Attr.SiteId} = {templateInfo.SiteId}"; + + if (templateInfo.Default) + { + return GetAll(Q + .Select(Attr.Id) + .Where(Attr.SiteId, templateInfo.SiteId) + .OrWhere(Attr.ChannelTemplateId, templateInfo.Id) + .OrWhere(Attr.ChannelTemplateId, 0) + .OrWhereNull(Attr.ChannelTemplateId)); + } + + return GetAll(Q + .Select(Attr.Id) + .Where(Attr.SiteId, templateInfo.SiteId) + .Where(Attr.ChannelTemplateId, templateInfo.Id)); + } + + if (templateInfo.Type == TemplateType.ContentTemplate) + { + //sqlString = templateInfo.IsDefault + // ? $"SELECT {Attr.Id} FROM {TableName} WHERE ({Attr.ContentTemplateId} = {templateInfo.Id} OR {Attr.ContentTemplateId} = 0) AND {Attr.SiteId} = {templateInfo.SiteId}" + // : $"SELECT {Attr.Id} FROM {TableName} WHERE {Attr.ContentTemplateId} = {templateInfo.Id} AND {Attr.SiteId} = {templateInfo.SiteId}"; + + if (templateInfo.Default) + { + return GetAll(Q + .Select(Attr.Id) + .Where(Attr.SiteId, templateInfo.SiteId) + .OrWhere(Attr.ContentTemplateId, templateInfo.Id) + .OrWhere(Attr.ContentTemplateId, 0) + .OrWhereNull(Attr.ContentTemplateId)); + } + + return GetAll(Q + .Select(Attr.Id) + .Where(Attr.SiteId, templateInfo.SiteId) + .Where(Attr.ContentTemplateId, templateInfo.Id)); + } + + //if (!string.IsNullOrEmpty(sqlString)) + //{ + // list = DatabaseApi.Instance.GetIntList(sqlString); + //} + + return list; + } + + //private ChannelInfo GetChannelInfo(IDataReader rdr) + //{ + // var i = 0; + // return new ChannelInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), + // DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), + // TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetDateTime(rdr, i++), + // DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), + // DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), ELinkTypeUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), + // DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i)); + //} + } +} + +//using System; +//using System.Collections.Generic; +//using System.Data; +//using System.Text; +//using SiteServer.CMS.Core.Attributes; +//using SiteServer.CMS.Core.Enumerations; +//using SiteServer.CMS.Database.Caches; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.CMS.Plugin.Impl; +//using SiteServer.Plugin; +//using SiteServer.Utils; +//using SiteServer.Utils.Enumerations; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class ChannelRepository : DataProviderBase +// { +// private static readonly List SqlColumns = new List +// { +// ChannelAttribute.Id, +// ChannelAttribute.AddDate, +// ChannelAttribute.Taxis +// }; + +// public override string TableName => "siteserver_Channel"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.ChannelName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.SiteId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.ContentModelPluginId), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.ContentRelatedPluginIds), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.ParentId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.ParentsPath), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.ParentsCount), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.ChildrenCount), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.IsLastNode), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.IndexName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.GroupNameCollection), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.Taxis), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.AddDate), +// DataType = DataType.DateTime +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.ImageUrl), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.Content), +// DataType = DataType.Text +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.FilePath), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.ChannelFilePathRule), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.ContentFilePathRule), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.LinkUrl), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.LinkType), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.ChannelTemplateId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.ContentTemplateId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.Keywords), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ChannelInfo.Description), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = "ExtendValues", +// DataType = DataType.Text +// } +// }; + +// private const string SqlSelectByLastAddDate = "SELECT Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues FROM siteserver_Channel WHERE ParentId = @ParentId ORDER BY AddDate Desc"; + +// private const string SqlSelectByTaxis = "SELECT Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues FROM siteserver_Channel WHERE ParentId = @ParentId ORDER BY Taxis"; + +// private const string SqlSelectParentId = "SELECT ParentId FROM siteserver_Channel WHERE Id = @Id"; + +// private const string SqlSelectCount = "SELECT COUNT(*) FROM siteserver_Channel WHERE ParentId = @ParentId"; + +// private const string SqlSelectSiteIdById = "SELECT SiteId FROM siteserver_Channel WHERE Id = @Id"; + +// private const string SqlSelectIndexNameCollection = "SELECT DISTINCT IndexName FROM siteserver_Channel WHERE SiteId = @SiteId"; + +// private const string SqlUpdate = "UPDATE siteserver_Channel SET ChannelName = @ChannelName, ContentModelPluginId = @ContentModelPluginId, ContentRelatedPluginIds = @ContentRelatedPluginIds, ParentsPath = @ParentsPath, ParentsCount = @ParentsCount, ChildrenCount = @ChildrenCount, IsLastNode = @IsLastNode, IndexName = @IndexName, GroupNameCollection = @GroupNameCollection, ImageUrl = @ImageUrl, Content = @Content, FilePath = @FilePath, ChannelFilePathRule = @ChannelFilePathRule, ContentFilePathRule = @ContentFilePathRule, LinkUrl = @LinkUrl,LinkType = @LinkType, ChannelTemplateId = @ChannelTemplateId, ContentTemplateId = @ContentTemplateId, Keywords = @Keywords, Description = @Description, ExtendValues = @ExtendValues WHERE Id = @Id"; + +// private const string SqlUpdateExtendValues = "UPDATE siteserver_Channel SET ExtendValues = @ExtendValues WHERE Id = @Id"; + +// private const string SqlUpdateGroupNameCollection = "UPDATE siteserver_Channel SET GroupNameCollection = @GroupNameCollection WHERE Id = @Id"; + +// private const string ParamId = "@Id"; +// private const string ParamChannelName = "@ChannelName"; +// private const string ParamSiteId = "@SiteId"; +// private const string ParamContentModelPluginId = "@ContentModelPluginId"; +// private const string ParamContentRelatedPluginIds = "@ContentRelatedPluginIds"; +// private const string ParamParentId = "@ParentId"; +// private const string ParamParentsPath = "@ParentsPath"; +// private const string ParamParentsCount = "@ParentsCount"; +// private const string ParamChildrenCount = "@ChildrenCount"; +// private const string ParamIsLastNode = "@IsLastNode"; +// private const string ParamIndexName = "@IndexName"; +// private const string ParamGroupNameCollection = "@GroupNameCollection"; +// private const string ParamTaxis = "@Taxis"; +// private const string ParamAddDate = "@AddDate"; +// private const string ParamImageUrl = "@ImageUrl"; +// private const string ParamContent = "@Content"; +// private const string ParamFilePath = "@FilePath"; +// private const string ParamChannelFilePathRule = "@ChannelFilePathRule"; +// private const string ParamContentFilePathRule = "@ContentFilePathRule"; +// private const string ParamLinkUrl = "@LinkUrl"; +// private const string ParamLinkType = "@LinkType"; +// private const string ParamChannelTemplateId = "@ChannelTemplateId"; +// private const string ParamContentTemplateId = "@ContentTemplateId"; +// private const string ParamKeywords = "@Keywords"; +// private const string ParamDescription = "@Description"; +// private const string ParamExtendValues = "@ExtendValues"; + +// private void InsertChannelInfoWithTrans(IChannelInfo parentChannelInfo, IChannelInfo channelInfo, IDbTransaction trans) +// { +// if (parentChannelInfo != null) +// { +// channelInfo.SiteId = parentChannelInfo.SiteId; +// if (parentChannelInfo.ParentsPath.Length == 0) +// { +// channelInfo.ParentsPath = parentChannelInfo.Id.ToString(); +// } +// else +// { +// channelInfo.ParentsPath = parentChannelInfo.ParentsPath + "," + parentChannelInfo.Id; +// } +// channelInfo.ParentsCount = parentChannelInfo.ParentsCount + 1; + +// var maxTaxis = GetMaxTaxisByParentPath(channelInfo.ParentsPath); +// if (maxTaxis == 0) +// { +// maxTaxis = parentChannelInfo.Taxis; +// } +// channelInfo.Taxis = maxTaxis + 1; +// } +// else +// { +// channelInfo.Taxis = 1; +// } + +// const string sqlInsertNode = "INSERT INTO siteserver_Channel (ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues) VALUES (@ChannelName, @SiteId, @ContentModelPluginId, @ContentRelatedPluginIds, @ParentId, @ParentsPath, @ParentsCount, @ChildrenCount, @IsLastNode, @IndexName, @GroupNameCollection, @Taxis, @AddDate, @ImageUrl, @Content, @FilePath, @ChannelFilePathRule, @ContentFilePathRule, @LinkUrl, @LinkType, @ChannelTemplateId, @ContentTemplateId, @Keywords, @Description, @ExtendValues)"; + +// IDataParameter[] insertParams = +// { +// GetParameter(ParamChannelName, channelInfo.ChannelName), +// GetParameter(ParamSiteId, channelInfo.SiteId), +// GetParameter(ParamContentModelPluginId, channelInfo.ContentModelPluginId), +// GetParameter(ParamContentRelatedPluginIds, channelInfo.ContentRelatedPluginIds), +// GetParameter(ParamParentId, channelInfo.ParentId), +// GetParameter(ParamParentsPath, channelInfo.ParentsPath), +// GetParameter(ParamParentsCount, channelInfo.ParentsCount), +// GetParameter(ParamChildrenCount, 0), +// GetParameter(ParamIsLastNode, true.ToString()), +// GetParameter(ParamIndexName, channelInfo.IndexName), +// GetParameter(ParamGroupNameCollection, channelInfo.GroupNameCollection), +// GetParameter(ParamTaxis, channelInfo.Taxis), +// GetParameter(ParamAddDate, channelInfo.AddDate), +// GetParameter(ParamImageUrl, channelInfo.ImageUrl), +// GetParameter(ParamContent, channelInfo.Content), +// GetParameter(ParamFilePath, channelInfo.FilePath), +// GetParameter(ParamChannelFilePathRule, channelInfo.ChannelFilePathRule), +// GetParameter(ParamContentFilePathRule, channelInfo.ContentFilePathRule), +// GetParameter(ParamLinkUrl, channelInfo.LinkUrl), +// GetParameter(ParamLinkType, channelInfo.LinkType), +// GetParameter(ParamChannelTemplateId, channelInfo.ChannelTemplateId), +// GetParameter(ParamContentTemplateId, channelInfo.ContentTemplateId), +// GetParameter(ParamKeywords, channelInfo.Keywords), +// GetParameter(ParamDescription, channelInfo.Description), +// GetParameter(ParamExtendValues, channelInfo.Attributes.ToString()) +// }; + +// if (channelInfo.SiteId != 0) +// { +// string sqlString = +// $"UPDATE siteserver_Channel SET Taxis = {DatorySql.ColumnIncrement("Taxis")} WHERE (Taxis >= {channelInfo.Taxis}) AND (SiteId = {channelInfo.SiteId})"; +// DatabaseApi.ExecuteNonQuery(trans, sqlString); +// } +// channelInfo.Id = DatabaseApi.ExecuteNonQueryAndReturnId(TableName, nameof(ChannelInfo.Id), trans, sqlInsertNode, insertParams); + +// if (!string.IsNullOrEmpty(channelInfo.ParentsPath)) +// { +// var sqlString = $"UPDATE siteserver_Channel SET ChildrenCount = {DatorySql.ColumnIncrement("ChildrenCount")} WHERE Id IN ({channelInfo.ParentsPath})"; + +// DatabaseApi.ExecuteNonQuery(trans, sqlString); +// } + +// var sqlUpdateIsLastNode = "UPDATE siteserver_Channel SET IsLastNode = @IsLastNode WHERE ParentId = @ParentId"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamIsLastNode, false.ToString()), +// GetParameter(ParamParentId, channelInfo.ParentId) +// }; + +// DatabaseApi.ExecuteNonQuery(trans, sqlUpdateIsLastNode, parameters); + +// sqlUpdateIsLastNode = +// $"UPDATE siteserver_Channel SET IsLastNode = '{true}' WHERE (Id IN ({SqlUtils.ToInTopSqlString(TableName, new List { nameof(ChannelInfo.Id) }, $"WHERE ParentId = {channelInfo.ParentId}", "ORDER BY Taxis DESC", 1)}))"; + +// DatabaseApi.ExecuteNonQuery(trans, sqlUpdateIsLastNode); + +// //OwningIdCache.IsChanged = true; +// ChannelManager.RemoveCacheBySiteId(channelInfo.SiteId); +// PermissionsImpl.ClearAllCache(); +// } + +// /// +// /// 将节点数减1 +// /// +// /// +// /// +// private void UpdateSubtractChildrenCount(string parentsPath, int subtractNum) +// { +// if (!string.IsNullOrEmpty(parentsPath)) +// { +// var sqlString = string.Concat("UPDATE siteserver_Channel SET ChildrenCount = ChildrenCount - ", subtractNum, " WHERE Id in (", parentsPath, ")"); +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } +// } + +// /// +// /// Change The Taxis To Lower Level +// /// +// private void TaxisSubtract(int siteId, int selectedId) +// { +// var channelInfo = ChannelManager.GetChannelInfo(siteId, selectedId); +// if (channelInfo == null || channelInfo.ParentId == 0 || channelInfo.SiteId == 0) return; +// //UpdateWholeTaxisBySiteId(channelInfo.SiteId); +// //Get Lower Taxis and Id +// int lowerId; +// int lowerChildrenCount; +// string lowerParentsPath; + +// var sqlString = DatorySql.GetSqlString(TableName, new List +// { +// nameof(ChannelInfo.Id), +// nameof(ChannelInfo.ChildrenCount), +// nameof(ChannelInfo.ParentsPath) +// }, "WHERE (ParentId = @ParentId) AND (Id <> @Id) AND (Taxis < @Taxis) AND (SiteId = @SiteId)", "ORDER BY Taxis DESC", 1); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamParentId, channelInfo.ParentId), +// GetParameter(ParamId, channelInfo.Id), +// GetParameter(ParamTaxis, channelInfo.Taxis), +// GetParameter(ParamSiteId, channelInfo.SiteId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// lowerId = DatabaseApi.GetInt(rdr, 0); +// lowerChildrenCount = DatabaseApi.GetInt(rdr, 1); +// lowerParentsPath = DatabaseApi.GetString(rdr, 2); +// } +// else +// { +// return; +// } +// rdr.Close(); +// } + +// var lowerPath = lowerParentsPath == "" ? lowerId.ToString() : string.Concat(lowerParentsPath, ",", lowerId); +// var selectedPath = channelInfo.ParentsPath == "" ? channelInfo.Id.ToString() : string.Concat(channelInfo.ParentsPath, ",", channelInfo.Id); + +// SetTaxisSubtract(selectedId, selectedPath, lowerChildrenCount + 1); +// SetTaxisAdd(lowerId, lowerPath, channelInfo.ChildrenCount + 1); + +// UpdateIsLastNode(channelInfo.ParentId); +// } + +// /// +// /// Change The Taxis To Higher Level +// /// +// private void TaxisAdd(int siteId, int selectedId) +// { +// var channelInfo = ChannelManager.GetChannelInfo(siteId, selectedId); +// if (channelInfo == null || channelInfo.ParentId == 0 || channelInfo.SiteId == 0) return; +// //UpdateWholeTaxisBySiteId(channelInfo.SiteId); +// //Get Higher Taxis and Id +// int higherId; +// int higherChildrenCount; +// string higherParentsPath; + +// var sqlString = DatorySql.GetSqlString(TableName, new List +// { +// nameof(ChannelInfo.Id), +// nameof(ChannelInfo.ChildrenCount), +// nameof(ChannelInfo.ParentsPath) +// }, "WHERE (ParentId = @ParentId) AND (Id <> @Id) AND (Taxis > @Taxis) AND (SiteId = @SiteId)", "ORDER BY Taxis", 1); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamParentId, channelInfo.ParentId), +// GetParameter(ParamId, channelInfo.Id), +// GetParameter(ParamTaxis, channelInfo.Taxis), +// GetParameter(ParamSiteId, channelInfo.SiteId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// higherId = DatabaseApi.GetInt(rdr, 0); +// higherChildrenCount = DatabaseApi.GetInt(rdr, 1); +// higherParentsPath = DatabaseApi.GetString(rdr, 2); +// } +// else +// { +// return; +// } +// rdr.Close(); +// } + + +// var higherPath = higherParentsPath == string.Empty ? higherId.ToString() : string.Concat(higherParentsPath, ",", higherId); +// var selectedPath = channelInfo.ParentsPath == string.Empty ? channelInfo.Id.ToString() : String.Concat(channelInfo.ParentsPath, ",", channelInfo.Id); + +// SetTaxisAdd(selectedId, selectedPath, higherChildrenCount + 1); +// SetTaxisSubtract(higherId, higherPath, channelInfo.ChildrenCount + 1); + +// UpdateIsLastNode(channelInfo.ParentId); +// } + +// private void SetTaxisAdd(int channelId, string parentsPath, int addNum) +// { +// string sqlString = +// $"UPDATE siteserver_Channel SET Taxis = {DatorySql.ColumnIncrement("Taxis", addNum)} WHERE Id = {channelId} OR ParentsPath = '{parentsPath}' OR ParentsPath like '{parentsPath},%'"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } + +// private void SetTaxisSubtract(int channelId, string parentsPath, int subtractNum) +// { +// string sqlString = +// $"UPDATE siteserver_Channel SET Taxis = {DatorySql.ColumnDecrement("Taxis", subtractNum)} WHERE Id = {channelId} OR ParentsPath = '{parentsPath}' OR ParentsPath like '{parentsPath},%'"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } + +// private void UpdateIsLastNode(int parentId) +// { +// if (parentId <= 0) return; + +// var sqlString = "UPDATE siteserver_Channel SET IsLastNode = @IsLastNode WHERE ParentId = @ParentId"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamIsLastNode, false.ToString()), +// GetParameter(ParamParentId, parentId) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// sqlString = +// $"UPDATE siteserver_Channel SET IsLastNode = '{true}' WHERE (Id IN ({SqlUtils.ToInTopSqlString(TableName, new List { nameof(ChannelInfo.Id) }, $"WHERE ParentId = {parentId}", "ORDER BY Taxis DESC", 1)}))"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } + +// private int GetMaxTaxisByParentPath(string parentPath) +// { +// var cmd = string.Concat("SELECT MAX(Taxis) AS MaxTaxis FROM siteserver_Channel WHERE (ParentsPath = '", parentPath, "') OR (ParentsPath like '", parentPath, ",%')"); +// var maxTaxis = 0; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, cmd)) +// { +// if (rdr.Read()) +// { +// maxTaxis = DatabaseApi.GetInt(rdr, 0); +// } +// rdr.Close(); +// } +// return maxTaxis; +// } + +// private int GetParentId(int channelId) +// { +// var parentId = 0; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamId, channelId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectParentId, parameters)) +// { +// if (rdr.Read()) +// { +// parentId = DatabaseApi.GetInt(rdr, 0); +// } +// rdr.Close(); +// } +// return parentId; +// } + +// private int GetIdByParentIdAndOrder(int parentId, int order) +// { +// var channelId = parentId; + +// string cmd = $"SELECT Id FROM siteserver_Channel WHERE (ParentId = {parentId}) ORDER BY Taxis"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, cmd)) +// { +// var index = 1; +// while (rdr.Read()) +// { +// channelId = DatabaseApi.GetInt(rdr, 0); +// if (index == order) +// break; +// index++; +// } +// rdr.Close(); +// } +// return channelId; +// } + +// public int InsertObject(int siteId, int parentId, string channelName, string indexName, string contentModelPluginId, string contentRelatedPluginIds, int channelTemplateId, int contentTemplateId) +// { +// if (siteId > 0 && parentId == 0) return 0; + +// var defaultChannelTemplateInfo = TemplateManager.GetDefaultTemplateInfo(siteId, TemplateType.ChannelTemplate); +// var defaultContentTemplateInfo = TemplateManager.GetDefaultTemplateInfo(siteId, TemplateType.ContentTemplate); + +// var channelInfo = new ChannelInfo +// { +// ParentId = parentId, +// SiteId = siteId, +// ChannelName = channelName, +// IndexName = indexName, +// ContentModelPluginId = contentModelPluginId, +// ContentRelatedPluginIds = contentRelatedPluginIds, +// AddDate = DateTime.Now, +// ChannelTemplateId = channelTemplateId > 0 ? channelTemplateId : defaultChannelTemplateInfo.Id, +// ContentTemplateId = contentTemplateId > 0 ? contentTemplateId : defaultContentTemplateInfo.Id +// }; + +// var parentChannelInfo = ChannelManager.GetChannelInfo(siteId, parentId); + +// using (var conn = GetConnection()) +// { +// conn.Open(); +// using (var trans = conn.BeginTransaction()) +// { +// try +// { +// InsertChannelInfoWithTrans(parentChannelInfo, channelInfo, trans); + +// trans.Commit(); +// } +// catch +// { +// trans.Rollback(); +// throw; +// } +// } +// } + +// return channelInfo.Id; + +// } + +// public int InsertObject(IChannelInfo channelInfo) +// { +// if (channelInfo.SiteId > 0 && channelInfo.ParentId == 0) return 0; + +// using (var conn = GetConnection()) +// { +// conn.Open(); +// using (var trans = conn.BeginTransaction()) +// { +// try +// { +// var parentChannelInfo = ChannelManager.GetChannelInfo(channelInfo.SiteId, channelInfo.ParentId); + +// InsertChannelInfoWithTrans(parentChannelInfo, channelInfo, trans); + +// trans.Commit(); +// } +// catch +// { +// trans.Rollback(); +// throw; +// } +// } +// } + +// return channelInfo.Id; +// } + +// /// +// /// 添加后台发布节点 +// /// +// public int InsertSiteInfo(ChannelInfo channelInfo, SiteInfo siteInfo, string administratorName) +// { +// using (var conn = GetConnection()) +// { +// conn.Open(); +// using (var trans = conn.BeginTransaction()) +// { +// try +// { +// InsertChannelInfoWithTrans(null, channelInfo, trans); + +// siteInfo.Id = channelInfo.Id; + +// DataProvider.Site.InsertWithTrans(siteInfo, trans); + +// trans.Commit(); +// } +// catch +// { +// trans.Rollback(); +// throw; +// } +// } +// } + +// var adminInfo = AdminManager.GetAdminInfoByUserName(administratorName); +// DataProvider.Administrator.UpdateSiteId(adminInfo, channelInfo.Id); + +// var sqlString = +// $"UPDATE siteserver_Channel SET SiteId = {channelInfo.Id} WHERE Id = {channelInfo.Id}"; +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + +// DataProvider.Template.CreateDefaultTemplateInfo(channelInfo.Id, administratorName); +// return channelInfo.Id; +// } + +// public void UpdateObject(ChannelInfo channelInfo) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamChannelName, channelInfo.ChannelName), +// GetParameter(ParamContentModelPluginId, channelInfo.ContentModelPluginId), +// GetParameter(ParamContentRelatedPluginIds, channelInfo.ContentRelatedPluginIds), +// GetParameter(ParamParentsPath, channelInfo.ParentsPath), +// GetParameter(ParamParentsCount, channelInfo.ParentsCount), +// GetParameter(ParamChildrenCount, channelInfo.ChildrenCount), +// GetParameter(ParamIsLastNode, channelInfo.IsLastNode.ToString()), +// GetParameter(ParamIndexName, channelInfo.IndexName), +// GetParameter(ParamGroupNameCollection, channelInfo.GroupNameCollection), +// GetParameter(ParamImageUrl, channelInfo.ImageUrl), +// GetParameter(ParamContent,channelInfo.Content), +// GetParameter(ParamFilePath, channelInfo.FilePath), +// GetParameter(ParamChannelFilePathRule, channelInfo.ChannelFilePathRule), +// GetParameter(ParamContentFilePathRule, channelInfo.ContentFilePathRule), +// GetParameter(ParamLinkUrl, channelInfo.LinkUrl), +// GetParameter(ParamLinkType, channelInfo.LinkType), +// GetParameter(ParamChannelTemplateId, channelInfo.ChannelTemplateId), +// GetParameter(ParamContentTemplateId, channelInfo.ContentTemplateId), +// GetParameter(ParamKeywords, channelInfo.Keywords), +// GetParameter(ParamDescription, channelInfo.Description), +// GetParameter(ParamExtendValues,channelInfo.Attributes.ToString()), +// GetParameter(ParamId, channelInfo.Id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdate, parameters); + +// ChannelManager.UpdateCache(channelInfo.SiteId, channelInfo); + +// //ChannelManager.RemoveCache(channelInfo.ParentId == 0 +// // ? channelInfo.Id +// // : channelInfo.SiteId); +// } + +// public void UpdateChannelTemplateId(ChannelInfo channelInfo) +// { +// string sqlString = +// $"UPDATE siteserver_Channel SET ChannelTemplateId = {channelInfo.ChannelTemplateId} WHERE Id = {channelInfo.Id}"; +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + +// ChannelManager.UpdateCache(channelInfo.SiteId, channelInfo); +// } + +// public void UpdateContentTemplateId(ChannelInfo channelInfo) +// { +// string sqlString = +// $"UPDATE siteserver_Channel SET ContentTemplateId = {channelInfo.ContentTemplateId} WHERE Id = {channelInfo.Id}"; +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + +// ChannelManager.UpdateCache(channelInfo.SiteId, channelInfo); +// } + +// public void UpdateAdditional(ChannelInfo channelInfo) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamExtendValues,channelInfo.ToString()), +// GetParameter(ParamId, channelInfo.Id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdateExtendValues, parameters); + +// ChannelManager.UpdateCache(channelInfo.SiteId, channelInfo); +// } + +// /// +// /// 修改排序 +// /// +// public void UpdateTaxis(int siteId, int selectedId, bool isSubtract) +// { +// if (isSubtract) +// { +// TaxisSubtract(siteId, selectedId); +// } +// else +// { +// TaxisAdd(siteId, selectedId); +// } +// ChannelManager.RemoveCacheBySiteId(siteId); +// } + +// public void AddGroupNameList(int siteId, int channelId, List groupList) +// { +// var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); +// if (channelInfo == null) return; + +// var list = TranslateUtils.StringCollectionToStringList(channelInfo.GroupNameCollection); +// foreach (var groupName in groupList) +// { +// if (!list.Contains(groupName)) list.Add(groupName); +// } + +// channelInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(list); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamGroupNameCollection, channelInfo.GroupNameCollection), +// GetParameter(ParamId, channelId) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdateGroupNameCollection, parameters); + +// ChannelManager.UpdateCache(siteId, channelInfo); +// } + +// public void DeleteById(int siteId, int channelId) +// { +// var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); +// if (channelInfo == null) return; + +// var idList = new List(); +// if (channelInfo.ChildrenCount > 0) +// { +// idList = ChannelManager.GetChannelIdList(channelInfo, EScopeType.Descendant, string.Empty, string.Empty, string.Empty); +// } +// idList.Add(channelId); + +// var deleteCmd = +// $"DELETE FROM siteserver_Channel WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + +// int deletedNum; + +// var siteInfo = SiteManager.GetSiteInfo(siteId); + +// using (var conn = GetConnection()) +// { +// conn.Open(); +// using (var trans = conn.BeginTransaction()) +// { +// try +// { +// DataProvider.ContentRepository.DeleteContentsByDeletedChannelIdList(trans, siteInfo, idList); + +// deletedNum = DatabaseApi.ExecuteNonQuery(trans, deleteCmd); + +// if (channelInfo.ParentId != 0) +// { +// string taxisCmd = +// $"UPDATE siteserver_Channel SET Taxis = Taxis - {deletedNum} WHERE (Taxis > {channelInfo.Taxis}) AND (SiteId = {channelInfo.SiteId})"; +// DatabaseApi.ExecuteNonQuery(trans, taxisCmd); +// } + +// trans.Commit(); +// } +// catch +// { +// trans.Rollback(); +// throw; +// } +// } +// } +// UpdateIsLastNode(channelInfo.ParentId); +// UpdateSubtractChildrenCount(channelInfo.ParentsPath, deletedNum); + +// if (channelInfo.ParentId == 0) +// { +// DataProvider.Site.DeleteById(channelInfo.Id); +// } +// else +// { +// ChannelManager.RemoveCacheBySiteId(channelInfo.SiteId); +// } +// } + +// /// +// /// 得到最后一个添加的子节点 +// /// +// public ChannelInfo GetChannelInfoByLastAddDate(int channelId) +// { +// ChannelInfo channelInfo = null; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamParentId, channelId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectByLastAddDate, parameters)) +// { +// if (rdr.Read()) +// { +// channelInfo = GetChannelInfo(rdr); +// } +// rdr.Close(); +// } +// return channelInfo; +// } + +// /// +// /// 得到第一个子节点 +// /// +// public ChannelInfo GetChannelInfoByTaxis(int channelId) +// { +// ChannelInfo channelInfo = null; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamParentId, channelId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectByTaxis, parameters)) +// { +// if (rdr.Read()) +// { +// channelInfo = GetChannelInfo(rdr); +// } +// rdr.Close(); +// } +// return channelInfo; +// } + +// public int GetIdByParentIdAndTaxis(int parentId, int taxis, bool isNextChannel) +// { +// var channelId = 0; + +// //var sqlString = isNextChannel ? $"SELECT TOP 1 Id FROM siteserver_Channel WHERE (ParentId = {parentId} AND Taxis > {taxis}) ORDER BY Taxis" : $"SELECT TOP 1 Id FROM siteserver_Channel WHERE (ParentId = {parentId} AND Taxis < {taxis}) ORDER BY Taxis DESC"; +// var sqlString = isNextChannel +// ? DatorySql.GetSqlString(TableName, new List +// { +// nameof(ChannelInfo.Id) +// }, +// $"WHERE (ParentId = {parentId} AND Taxis > {taxis})", "ORDER BY Taxis", 1) +// : DatorySql.GetSqlString(TableName, new List +// { +// nameof(ChannelInfo.Id) +// }, +// $"WHERE (ParentId = {parentId} AND Taxis < {taxis})", "ORDER BY Taxis DESC", 1); + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// if (rdr.Read()) +// { +// channelId = DatabaseApi.GetInt(rdr, 0); +// } +// rdr.Close(); +// } +// return channelId; +// } + +// public int GetId(int siteId, string orderString) +// { +// if (orderString == "1") +// return siteId; + +// var channelId = siteId; + +// var orderArr = orderString.Split('_'); +// for (var index = 1; index < orderArr.Length; index++) +// { +// var order = int.Parse(orderArr[index]); +// channelId = GetIdByParentIdAndOrder(channelId, order); +// } +// return channelId; +// } + +// public int GetSiteId(int channelId) +// { +// var siteId = 0; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamId, channelId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectSiteIdById, parameters)) +// { +// if (rdr.Read()) +// { +// siteId = DatabaseApi.GetInt(rdr, 0); +// if (siteId == 0) +// { +// siteId = channelId; +// } +// } +// rdr.Close(); +// } +// return siteId; +// } + +// /// +// /// 在节点树中得到此节点的排序号,以“1_2_5_2”的形式表示 +// /// +// public string GetOrderStringInSite(int channelId) +// { +// var retVal = ""; +// if (channelId != 0) +// { +// var parentId = GetParentId(channelId); +// if (parentId != 0) +// { +// var orderString = GetOrderStringInSite(parentId); +// retVal = orderString + "_" + GetOrderInSibling(channelId, parentId); +// } +// else +// { +// retVal = "1"; +// } +// } +// return retVal; +// } + +// private int GetOrderInSibling(int channelId, int parentId) +// { +// string cmd = $"SELECT Id FROM siteserver_Channel WHERE (ParentId = {parentId}) ORDER BY Taxis"; +// var idList = new List(); +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, cmd)) +// { +// while (rdr.Read()) +// { +// idList.Add(DatabaseApi.GetInt(rdr, 0)); +// } +// rdr.Close(); +// } +// return idList.IndexOf(channelId) + 1; +// } + +// public List GetIndexNameList(int siteId) +// { +// var list = new List(); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamSiteId, siteId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectIndexNameCollection, parameters)) +// { +// while (rdr.Read()) +// { +// list.Add(DatabaseApi.GetString(rdr, 0)); +// } +// rdr.Close(); +// } + +// return list; +// } + +// private static string GetGroupWhereString(string group, string groupNot) +// { +// var whereStringBuilder = new StringBuilder(); +// if (!string.IsNullOrEmpty(group)) +// { +// group = group.Trim().Trim(','); +// var groupArr = group.Split(','); +// if (groupArr.Length > 0) +// { +// whereStringBuilder.Append(" AND ("); +// foreach (var theGroup in groupArr) +// { +// var trimGroup = theGroup.Trim(); + +// whereStringBuilder.Append( +// $" (siteserver_Channel.GroupNameCollection = '{trimGroup}' OR {SqlUtils.GetInStr("siteserver_Channel.GroupNameCollection", trimGroup + ",")} OR {SqlUtils.GetInStr("siteserver_Channel.GroupNameCollection", "," + trimGroup + ",")} OR {SqlUtils.GetInStr("siteserver_Channel.GroupNameCollection", "," + trimGroup)}) OR "); +// } +// if (groupArr.Length > 0) +// { +// whereStringBuilder.Length = whereStringBuilder.Length - 3; +// } +// whereStringBuilder.Append(") "); +// } +// } + +// if (!string.IsNullOrEmpty(groupNot)) +// { +// groupNot = groupNot.Trim().Trim(','); +// var groupNotArr = groupNot.Split(','); +// if (groupNotArr.Length > 0) +// { +// whereStringBuilder.Append(" AND ("); +// foreach (var theGroupNot in groupNotArr) +// { +// var trimGroupNot = theGroupNot.Trim(); + +// whereStringBuilder.Append( +// $" (siteserver_Channel.GroupNameCollection <> '{trimGroupNot}' AND {SqlUtils.GetNotInStr("siteserver_Channel.GroupNameCollection", trimGroupNot + ",")} AND {SqlUtils.GetNotInStr("siteserver_Channel.GroupNameCollection", "," + trimGroupNot + ",")} AND {SqlUtils.GetNotInStr("siteserver_Channel.GroupNameCollection", "," + trimGroupNot)}) AND "); +// } +// if (groupNotArr.Length > 0) +// { +// whereStringBuilder.Length = whereStringBuilder.Length - 4; +// } +// whereStringBuilder.Append(") "); +// } +// } +// return whereStringBuilder.ToString(); +// } + +// public string GetWhereString(string group, string groupNot, bool isImageExists, bool isImage, string where) +// { +// var whereStringBuilder = new StringBuilder(); +// if (isImageExists) +// { +// whereStringBuilder.Append(isImage +// ? " AND siteserver_Channel.ImageUrl <> '' " +// : " AND siteserver_Channel.ImageUrl = '' "); +// } + +// whereStringBuilder.Append(GetGroupWhereString(group, groupNot)); + +// if (!string.IsNullOrEmpty(where)) +// { +// whereStringBuilder.Append($" AND {where} "); +// } + +// return whereStringBuilder.ToString(); +// } + +// public int GetCount(int channelId) +// { +// var count = 0; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamParentId, channelId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectCount, parameters)) +// { +// if (rdr.Read()) +// { +// count = DatabaseApi.GetInt(rdr, 0); +// } +// rdr.Close(); +// } +// return count; +// } + +// public int GetSequence(int siteId, int channelId) +// { +// var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); +// string sqlString = +// $"SELECT COUNT(*) AS TotalNum FROM siteserver_Channel WHERE SiteId = {siteId} AND ParentId = {channelInfo.ParentId} AND Taxis > (SELECT Taxis FROM siteserver_Channel WHERE Id = {channelId})"; + +// return DatabaseApi.Instance.GetIntResult(sqlString) + 1; +// } + +// public List GetIdListByTotalNum(List channelIdList, int totalNum, string orderByString, string whereString) +// { +// if (channelIdList == null || channelIdList.Count == 0) +// { +// return channelIdList; +// } + +// string sqlString; +// if (totalNum > 0) +// { +// // sqlString = $@"SELECT TOP {totalNum} Id +// //FROM siteserver_Channel +// //WHERE (Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) {whereString}) {orderByString} +// //"; +// //var where = +// // $"WHERE (Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) {whereString})"; +// var where = +// $"WHERE {SqlUtils.GetSqlColumnInList("Id", channelIdList)} {whereString})"; +// sqlString = DatorySql.GetSqlString(TableName, new List +// { +// nameof(ChannelInfo.Id) +// }, +// where, +// orderByString, +// totalNum); +// } +// else +// { +// // sqlString = $@"SELECT Id +// //FROM siteserver_Channel +// //WHERE (Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) {whereString}) {orderByString} +// //"; +// sqlString = $@"SELECT Id +//FROM siteserver_Channel +//WHERE {SqlUtils.GetSqlColumnInList("Id", channelIdList)} {whereString} {orderByString} +//"; +// } + +// var list = new List(); + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// list.Add(DatabaseApi.GetInt(rdr, 0)); +// } +// rdr.Close(); +// } +// return list; +// } + +// public Dictionary GetChannelInfoDictionaryBySiteId(int siteId) +// { +// var dic = new Dictionary(); +// string sqlString = +// $@"SELECT Id, ChannelName, SiteId, ContentModelPluginId, ContentRelatedPluginIds, ParentId, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, IndexName, GroupNameCollection, Taxis, AddDate, ImageUrl, Content, FilePath, ChannelFilePathRule, ContentFilePathRule, LinkUrl, LinkType, ChannelTemplateId, ContentTemplateId, Keywords, Description, ExtendValues +//FROM siteserver_Channel +//WHERE (SiteId = {siteId} AND (Id = {siteId} OR ParentId > 0)) +//ORDER BY Taxis"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var channelInfo = GetChannelInfo(rdr); +// dic.Add(channelInfo.Id, channelInfo); +// } +// rdr.Close(); +// } + +// return dic; +// } + +// public DataSet GetStlDataSourceBySiteId(int siteId, int startNum, int totalNum, string whereString, string orderByString) +// { +// var sqlWhereString = $"WHERE (SiteId = {siteId} {whereString})"; + +// //var sqlSelect = DatabaseApi.Instance.GetSelectSqlString(TableName, startNum, totalNum, SqlColumns, sqlWhereString, orderByString); +// var sqlSelect = DatorySql.GetSqlString(TableName, SqlColumns, sqlWhereString, orderByString, startNum - 1, totalNum); + +// return DatabaseApi.ExecuteDataset(ConnectionString, sqlSelect); +// } + +// public DataSet GetStlDataSet(List channelIdList, int startNum, int totalNum, string whereString, string orderByString) +// { +// if (channelIdList == null || channelIdList.Count == 0) +// { +// return null; +// } + +// //var sqlWhereString = +// // $"WHERE (Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) {whereString})"; + +// var sqlWhereString = +// $"WHERE {SqlUtils.GetSqlColumnInList("Id", channelIdList)} {whereString}"; + +// //var sqlSelect = DatabaseApi.Instance.GetSelectSqlString(TableName, startNum, totalNum, SqlColumns, sqlWhereString, orderByString); +// var sqlSelect = DatorySql.GetSqlString(TableName, SqlColumns, sqlWhereString, orderByString, startNum - 1, totalNum); + +// return DatabaseApi.ExecuteDataset(ConnectionString, sqlSelect); +// } + +// public DataSet GetStlDataSetBySiteId(int siteId, int startNum, int totalNum, string whereString, string orderByString) +// { +// var sqlWhereString = $"WHERE (SiteId = {siteId} {whereString})"; + +// //var sqlSelect = DatabaseApi.Instance.GetSelectSqlString(TableName, startNum, totalNum, SqlColumns, sqlWhereString, orderByString); +// var sqlSelect = DatorySql.GetSqlString(TableName, SqlColumns, sqlWhereString, orderByString, startNum - 1, totalNum); + +// return DatabaseApi.ExecuteDataset(ConnectionString, sqlSelect); +// } + +// public List GetContentModelPluginIdList() +// { +// var list = new List(); + +// const string sqlString = "SELECT DISTINCT ContentModelPluginId FROM siteserver_Channel"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// list.Add(DatabaseApi.GetString(rdr, 0)); +// } +// rdr.Close(); +// } +// return list; +// } + +// public List GetAllFilePathBySiteId(int siteId) +// { +// var list = new List(); + +// var sqlString = +// $"SELECT FilePath FROM siteserver_Channel WHERE FilePath <> '' AND SiteId = {siteId}"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// list.Add(DatabaseApi.GetString(rdr, 0)); +// } +// rdr.Close(); +// } +// return list; +// } + +// public int GetTemplateUseCount(int siteId, int templateId, TemplateType templateType, bool isDefault) +// { +// var sqlString = string.Empty; + +// if (templateType == TemplateType.IndexPageTemplate) +// { +// if (isDefault) +// { +// return 1; +// } +// return 0; +// } +// if (templateType == TemplateType.FileTemplate) +// { +// return 1; +// } +// if (templateType == TemplateType.ChannelTemplate) +// { +// sqlString = isDefault +// ? $"SELECT COUNT(*) FROM {TableName} WHERE ({nameof(ChannelInfo.ChannelTemplateId)} = {templateId} OR {nameof(ChannelInfo.ChannelTemplateId)} = 0) AND {nameof(ChannelInfo.SiteId)} = {siteId}" +// : $"SELECT COUNT(*) FROM {TableName} WHERE {nameof(ChannelInfo.ChannelTemplateId)} = {templateId} AND {nameof(ChannelInfo.SiteId)} = {siteId}"; +// } +// else if (templateType == TemplateType.ContentTemplate) +// { +// sqlString = isDefault +// ? $"SELECT COUNT(*) FROM {TableName} WHERE ({nameof(ChannelInfo.ContentTemplateId)} = {templateId} OR {nameof(ChannelInfo.ContentTemplateId)} = 0) AND {nameof(ChannelInfo.SiteId)} = {siteId}" +// : $"SELECT COUNT(*) FROM {TableName} WHERE {nameof(ChannelInfo.ContentTemplateId)} = {templateId} AND {nameof(ChannelInfo.SiteId)} = {siteId}"; +// } + +// return DatabaseApi.Instance.GetIntResult(sqlString); +// } + +// public List GetChannelIdList(TemplateInfo templateInfo) +// { +// var list = new List(); +// var sqlString = string.Empty; + +// if (templateInfo.TemplateType == TemplateType.ChannelTemplate) +// { +// sqlString = templateInfo.IsDefault +// ? $"SELECT {nameof(ChannelInfo.Id)} FROM {TableName} WHERE ({nameof(ChannelInfo.ChannelTemplateId)} = {templateInfo.Id} OR {nameof(ChannelInfo.ChannelTemplateId)} = 0) AND {nameof(ChannelInfo.SiteId)} = {templateInfo.SiteId}" +// : $"SELECT {nameof(ChannelInfo.Id)} FROM {TableName} WHERE {nameof(ChannelInfo.ChannelTemplateId)} = {templateInfo.Id} AND {nameof(ChannelInfo.SiteId)} = {templateInfo.SiteId}"; +// } +// else if (templateInfo.TemplateType == TemplateType.ContentTemplate) +// { +// sqlString = templateInfo.IsDefault +// ? $"SELECT {nameof(ChannelInfo.Id)} FROM {TableName} WHERE ({nameof(ChannelInfo.ContentTemplateId)} = {templateInfo.Id} OR {nameof(ChannelInfo.ContentTemplateId)} = 0) AND {nameof(ChannelInfo.SiteId)} = {templateInfo.SiteId}" +// : $"SELECT {nameof(ChannelInfo.Id)} FROM {TableName} WHERE {nameof(ChannelInfo.ContentTemplateId)} = {templateInfo.Id} AND {nameof(ChannelInfo.SiteId)} = {templateInfo.SiteId}"; +// } + +// if (!string.IsNullOrEmpty(sqlString)) +// { +// list = DatabaseApi.Instance.GetIntList(sqlString); +// } + +// return list; +// } + +// private ChannelInfo GetChannelInfo(IDataReader rdr) +// { +// var i = 0; +// return new ChannelInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), +// DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), +// TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetDateTime(rdr, i++), +// DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), +// DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), ELinkTypeUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), +// DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i)); +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/ConfigRepository.cs b/net452/SiteServer.CMS/Database/Repositories/ConfigRepository.cs new file mode 100644 index 000000000..5a15b435a --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/ConfigRepository.cs @@ -0,0 +1,285 @@ +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class ConfigRepository : Repository + { + public ConfigRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(ConfigInfo.Id); + public const string IsInitialized = "IsInitialized"; + } + + public override int Insert(ConfigInfo configInfo) + { + //var sqlString = + // $"INSERT INTO {TableName} ({nameof(ConfigInfo.IsInitialized)}, {nameof(ConfigInfo.DatabaseVersion)}, {nameof(ConfigInfo.UpdateDate)}, {nameof(ConfigInfo.SystemConfig)}) VALUES (@{nameof(ConfigInfo.IsInitialized)}, @{nameof(ConfigInfo.DatabaseVersion)}, @{nameof(ConfigInfo.UpdateDate)}, @{nameof(ConfigInfo.SystemConfig)})"; + + //IDataParameter[] parameters = + //{ + // GetParameter($"@{nameof(ConfigInfo.IsInitialized)}", info.IsInitialized.ToString()), + // GetParameter($"@{nameof(ConfigInfo.DatabaseVersion)}", info.DatabaseVersion), + // GetParameter($"@{nameof(ConfigInfo.UpdateDate)}",info.UpdateDate), + // GetParameter($"@{nameof(ConfigInfo.SystemConfig)}",info.SystemConfigInfo.ToString()) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + configInfo.Id = base.Insert(configInfo); + if (configInfo.Id > 0) + { + ConfigManager.IsChanged = true; + } + + return configInfo.Id; + } + + public override bool Update(ConfigInfo configInfo) + { + //var sqlString = + // $"UPDATE {TableName} SET {nameof(ConfigInfo.IsInitialized)} = @{nameof(ConfigInfo.IsInitialized)}, {nameof(ConfigInfo.DatabaseVersion)}= @{nameof(ConfigInfo.DatabaseVersion)}, {nameof(ConfigInfo.UpdateDate)}= @{nameof(ConfigInfo.UpdateDate)}, {nameof(ConfigInfo.SystemConfig)}= @{nameof(ConfigInfo.SystemConfig)} WHERE {nameof(ConfigInfo.Id)} = @{nameof(ConfigInfo.Id)}"; + + //IDataParameter[] parameters = + //{ + // GetParameter($"@{nameof(ConfigInfo.IsInitialized)}", info.IsInitialized.ToString()), + // GetParameter($"@{nameof(ConfigInfo.DatabaseVersion)}", info.DatabaseVersion), + // GetParameter($"@{nameof(ConfigInfo.UpdateDate)}",info.UpdateDate), + // GetParameter($"@{nameof(ConfigInfo.SystemConfig)}",info.SystemConfigInfo.ToString()), + // GetParameter($"@{nameof(ConfigInfo.Id)}", info.Id) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + var updated = base.Update(configInfo); + if (updated) + { + ConfigManager.IsChanged = true; + } + + return updated; + } + + public bool IsInitialized() + { + try + { + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, $"SELECT {nameof(ConfigInfo.IsInitialized)} FROM {TableName} ORDER BY {nameof(ConfigInfo.Id)}")) + //{ + // if (rdr.Read()) + // { + // isInitialized = TranslateUtils.ToBool(DatabaseApi.GetString(rdr, 0)); + // } + // rdr.Close(); + //} + + var isInitialized = Get(Q + .Select(Attr.IsInitialized) + .OrderBy(Attr.Id)); + + return TranslateUtils.ToBool(isInitialized); + } + catch + { + // ignored + } + + return false; + } + + //public string GetDatabaseVersion() + //{ + // try + // { + // //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, $"SELECT {nameof(ConfigInfo.DatabaseVersion)} FROM {TableName} ORDER BY {nameof(ConfigInfo.Id)}")) + // //{ + // // if (rdr.Read()) + // // { + // // databaseVersion = DatabaseApi.GetString(rdr, 0); + // // } + // // rdr.Close(); + // //} + // return GetValue(Q + // .Select(Attr.DatabaseVersion) + // .OrderBy(Attr.Id)); + // } + // catch + // { + // // ignored + // } + + // return string.Empty; + //} + + public ConfigInfo GetConfigInfo() + { + //ConfigInfo info = null; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, $"SELECT {nameof(ConfigInfo.Id)}, {nameof(ConfigInfo.IsInitialized)}, {nameof(ConfigInfo.DatabaseVersion)}, {nameof(ConfigInfo.UpdateDate)}, {nameof(ConfigInfo.SystemConfig)} FROM {TableName} ORDER BY {nameof(ConfigInfo.Id)}")) + //{ + // if (rdr.Read()) + // { + // var i = 0; + // info = new ConfigInfo(DatabaseApi.GetInt(rdr, i++), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetDateTime(rdr, i++), DatabaseApi.GetString(rdr, i)); + // } + // rdr.Close(); + //} + + //return info; + + return Get(Q.OrderBy(Attr.Id)); + + //return Get(new GenericQuery().OrderBy(Attr.Id)); + } + } +} + + +//using System.Collections.Generic; +//using System.Data; +//using SiteServer.CMS.Database.Caches; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class ConfigDao : DataProviderBase +// { +// public override string TableName => "siteserver_Config"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(ConfigInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(ConfigInfo.IsInitialized), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ConfigInfo.DatabaseVersion), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ConfigInfo.UpdateDate), +// DataType = DataType.DateTime +// }, +// new TableColumn +// { +// AttributeName = nameof(ConfigInfo.SystemConfig), +// DataType = DataType.Text +// } +// }; + +// public void InsertObject(ConfigInfo info) +// { +// var sqlString = +// $"INSERT INTO {TableName} ({nameof(ConfigInfo.IsInitialized)}, {nameof(ConfigInfo.DatabaseVersion)}, {nameof(ConfigInfo.UpdateDate)}, {nameof(ConfigInfo.SystemConfig)}) VALUES (@{nameof(ConfigInfo.IsInitialized)}, @{nameof(ConfigInfo.DatabaseVersion)}, @{nameof(ConfigInfo.UpdateDate)}, @{nameof(ConfigInfo.SystemConfig)})"; + +// IDataParameter[] parameters = +// { +// GetParameter($"@{nameof(ConfigInfo.IsInitialized)}", info.IsInitialized.ToString()), +// GetParameter($"@{nameof(ConfigInfo.DatabaseVersion)}", info.DatabaseVersion), +// GetParameter($"@{nameof(ConfigInfo.UpdateDate)}",info.UpdateDate), +// GetParameter($"@{nameof(ConfigInfo.SystemConfig)}",info.SystemConfigInfo.ToString()) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// ConfigManager.IsChanged = true; +// } + +// public void UpdateObject(ConfigInfo info) +// { +// var sqlString = +// $"UPDATE {TableName} SET {nameof(ConfigInfo.IsInitialized)} = @{nameof(ConfigInfo.IsInitialized)}, {nameof(ConfigInfo.DatabaseVersion)}= @{nameof(ConfigInfo.DatabaseVersion)}, {nameof(ConfigInfo.UpdateDate)}= @{nameof(ConfigInfo.UpdateDate)}, {nameof(ConfigInfo.SystemConfig)}= @{nameof(ConfigInfo.SystemConfig)} WHERE {nameof(ConfigInfo.Id)} = @{nameof(ConfigInfo.Id)}"; + +// IDataParameter[] parameters = +// { +// GetParameter($"@{nameof(ConfigInfo.IsInitialized)}", info.IsInitialized.ToString()), +// GetParameter($"@{nameof(ConfigInfo.DatabaseVersion)}", info.DatabaseVersion), +// GetParameter($"@{nameof(ConfigInfo.UpdateDate)}",info.UpdateDate), +// GetParameter($"@{nameof(ConfigInfo.SystemConfig)}",info.SystemConfigInfo.ToString()), +// GetParameter($"@{nameof(ConfigInfo.Id)}", info.Id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// ConfigManager.IsChanged = true; +// } + +// public bool IsInitialized() +// { +// var isInitialized = false; + +// try +// { +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, $"SELECT {nameof(ConfigInfo.IsInitialized)} FROM {TableName} ORDER BY {nameof(ConfigInfo.Id)}")) +// { +// if (rdr.Read()) +// { +// isInitialized = TranslateUtils.ToBool(DatabaseApi.GetString(rdr, 0)); +// } +// rdr.Close(); +// } +// } +// catch +// { +// // ignored +// } + +// return isInitialized; +// } + +// public string GetDatabaseVersion() +// { +// var databaseVersion = string.Empty; + +// try +// { +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, $"SELECT {nameof(ConfigInfo.DatabaseVersion)} FROM {TableName} ORDER BY {nameof(ConfigInfo.Id)}")) +// { +// if (rdr.Read()) +// { +// databaseVersion = DatabaseApi.GetString(rdr, 0); +// } +// rdr.Close(); +// } +// } +// catch +// { +// // ignored +// } + +// return databaseVersion; +// } + +// public ConfigInfo GetConfigInfo() +// { +// ConfigInfo info = null; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, $"SELECT {nameof(ConfigInfo.Id)}, {nameof(ConfigInfo.IsInitialized)}, {nameof(ConfigInfo.DatabaseVersion)}, {nameof(ConfigInfo.UpdateDate)}, {nameof(ConfigInfo.SystemConfig)} FROM {TableName} ORDER BY {nameof(ConfigInfo.Id)}")) +// { +// if (rdr.Read()) +// { +// var i = 0; +// info = new ConfigInfo(DatabaseApi.GetInt(rdr, i++), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetDateTime(rdr, i++), DatabaseApi.GetString(rdr, i)); +// } +// rdr.Close(); +// } + +// return info; +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/ContentCheckRepository.cs b/net452/SiteServer.CMS/Database/Repositories/ContentCheckRepository.cs new file mode 100644 index 000000000..59c6c01f8 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/ContentCheckRepository.cs @@ -0,0 +1,221 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class ContentCheckRepository : Repository + { + public ContentCheckRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(ContentCheckInfo.Id); + public const string TableName = nameof(ContentCheckInfo.TableName); + public const string ChannelId = nameof(ContentCheckInfo.ChannelId); + } + + public override int Insert(ContentCheckInfo checkInfo) + { + //const string sqlString = "INSERT INTO siteserver_ContentCheck (TableName, SiteId, ChannelId, ContentId, UserName, IsChecked, CheckedLevel, CheckDate, Reasons) VALUES (@TableName, @SiteId, @ChannelId, @ContentId, @UserName, @IsChecked, @CheckedLevel, @CheckDate, @Reasons)"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamTableName, checkInfo.TableName), + // GetParameter(ParamSiteId, checkInfo.SiteId), + // GetParameter(ParamChannelId, checkInfo.ChannelId), + // GetParameter(ParamContentId, checkInfo.ContentId), + // GetParameter(ParamUserName, checkInfo.UserName), + // GetParameter(ParamIsChecked, checkInfo.IsChecked.ToString()), + // GetParameter(ParamCheckedLevel, checkInfo.CheckedLevel), + // GetParameter(ParamCheckDate,checkInfo.CheckDate), + // GetParameter(ParamReasons, checkInfo.Reasons), + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + checkInfo.Id = base.Insert(checkInfo); + return checkInfo.Id; + } + + //public void Delete(int checkId) + //{ + // //IDataParameter[] parameters = + // //{ + // // GetParameter(ParamId, checkId) + // //}; + // //"DELETE FROM siteserver_ContentCheck WHERE Id = @Id" + // //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDelete, parameters); + // DeleteById(checkId); + //} + + public IList GetCheckInfoList(string tableName, int contentId) + { + //var list = new List(); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamTableName, tableName), + // GetParameter(ParamContentId, contentId) + //}; + //"SELECT Id, TableName, SiteId, ChannelId, ContentId, UserName, IsChecked, CheckedLevel, CheckDate, Reasons FROM siteserver_ContentCheck WHERE TableName = @TableName AND ContentId = @ContentId ORDER BY Id DESC" + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAll, parameters)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // list.Add(new ContentCheckInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetDateTime(rdr, i++), DatabaseApi.GetString(rdr, i))); + // } + // rdr.Close(); + //} + + //return list; + + return GetAll(Q + .Where(Attr.TableName, tableName) + .Where(Attr.ChannelId, contentId) + .OrderByDesc(Attr.Id)); + } + } +} + +//using System.Collections.Generic; + //using System.Data; + //using SiteServer.CMS.Database.Core; + //using SiteServer.CMS.Database.Models; + //using SiteServer.Plugin; + //using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class ContentCheck : DataProviderBase +// { +// public override string TableName => "siteserver_ContentCheck"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(ContentCheckInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(ContentCheckInfo.TableName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ContentCheckInfo.SiteId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(ContentCheckInfo.ChannelId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(ContentCheckInfo.ContentId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(ContentCheckInfo.UserName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ContentCheckInfo.IsChecked), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ContentCheckInfo.CheckedLevel), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(ContentCheckInfo.CheckDate), +// DataType = DataType.DateTime +// }, +// new TableColumn +// { +// AttributeName = nameof(ContentCheckInfo.Reasons), +// DataType = DataType.VarChar +// } +// }; + +// private const string SqlSelectAll = "SELECT Id, TableName, SiteId, ChannelId, ContentId, UserName, IsChecked, CheckedLevel, CheckDate, Reasons FROM siteserver_ContentCheck WHERE TableName = @TableName AND ContentId = @ContentId ORDER BY Id DESC"; + +// private const string SqlDelete = "DELETE FROM siteserver_ContentCheck WHERE Id = @Id"; + +// private const string ParamId = "@Id"; +// private const string ParamTableName = "@TableName"; +// private const string ParamSiteId = "@SiteId"; +// private const string ParamChannelId = "@ChannelId"; +// private const string ParamContentId = "@ContentId"; +// private const string ParamUserName = "@UserName"; +// private const string ParamIsChecked = "@IsChecked"; +// private const string ParamCheckedLevel = "@CheckedLevel"; +// private const string ParamCheckDate = "@CheckDate"; +// private const string ParamReasons = "@Reasons"; + +// public void InsertObject(ContentCheckInfo checkInfo) +// { +// const string sqlString = "INSERT INTO siteserver_ContentCheck (TableName, SiteId, ChannelId, ContentId, UserName, IsChecked, CheckedLevel, CheckDate, Reasons) VALUES (@TableName, @SiteId, @ChannelId, @ContentId, @UserName, @IsChecked, @CheckedLevel, @CheckDate, @Reasons)"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamTableName, checkInfo.TableName), +// GetParameter(ParamSiteId, checkInfo.SiteId), +// GetParameter(ParamChannelId, checkInfo.ChannelId), +// GetParameter(ParamContentId, checkInfo.ContentId), +// GetParameter(ParamUserName, checkInfo.UserName), +// GetParameter(ParamIsChecked, checkInfo.IsChecked.ToString()), +// GetParameter(ParamCheckedLevel, checkInfo.CheckedLevel), +// GetParameter(ParamCheckDate,checkInfo.CheckDate), +// GetParameter(ParamReasons, checkInfo.Reasons), +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// public void DeleteById(int checkId) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamId, checkId) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDelete, parameters); +// } + +// public List GetCheckInfoList(string tableName, int contentId) +// { +// var list = new List(); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamTableName, tableName), +// GetParameter(ParamContentId, contentId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAll, parameters)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// list.Add(new ContentCheckInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetDateTime(rdr, i++), DatabaseApi.GetString(rdr, i))); +// } +// rdr.Close(); +// } + +// return list; +// } +// } +//} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Database/Repositories/ContentGroupRepository.cs b/net452/SiteServer.CMS/Database/Repositories/ContentGroupRepository.cs new file mode 100644 index 000000000..2c21f1f45 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/ContentGroupRepository.cs @@ -0,0 +1,567 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class ContentGroupRepository : Repository + { + public ContentGroupRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string GroupName = nameof(ContentGroupInfo.GroupName); + public const string SiteId = nameof(ContentGroupInfo.SiteId); + public const string Taxis = nameof(ContentGroupInfo.Taxis); + } + + public override int Insert(ContentGroupInfo groupInfo) + { + var maxTaxis = GetMaxTaxis(groupInfo.SiteId); + groupInfo.Taxis = maxTaxis + 1; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamGroupName, contentGroup.GroupName), + // GetParameter(ParamSiteId, contentGroup.SiteId), + // GetParameter(ParamTaxis, contentGroup.Taxis), + // GetParameter(ParamDescription,contentGroup.Description) + //}; + //"INSERT INTO siteserver_ContentGroup (GroupName, SiteId, Taxis, Description) VALUES (@GroupName, @SiteId, @Taxis, @Description)" + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlInsert, parameters); + + groupInfo.Id = base.Insert(groupInfo); + + if (groupInfo.Id > 0) + { + ContentGroupManager.ClearCache(); + } + + return groupInfo.Id; + } + + public override bool Update(ContentGroupInfo groupInfo) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamDescription,contentGroup.Description), + // GetParameter(ParamGroupName, contentGroup.GroupName), + // GetParameter(ParamSiteId, contentGroup.SiteId) + //}; + //"UPDATE siteserver_ContentGroup SET Description = @Description WHERE GroupName = @GroupName AND SiteId = @SiteId" + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdate, parameters); + + var success = base.Update(groupInfo); + + if (success) + { + ContentGroupManager.ClearCache(); + } + + return success; + } + + public void Delete(int siteId, string groupName) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamGroupName, groupName), + // GetParameter(ParamSiteId, siteId) + //}; + //"DELETE FROM siteserver_ContentGroup WHERE GroupName = @GroupName AND SiteId = @SiteId" + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDelete, parameters); + + Delete(Q + .Where(Attr.SiteId, siteId) + .Where(Attr.GroupName, groupName)); + + ContentGroupManager.ClearCache(); + } + + private int GetTaxis(int siteId, string groupName) + { + //var sqlString = + // $"SELECT Taxis FROM siteserver_ContentGroup WHERE (GroupName = @GroupName AND SiteId = {siteId})"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamGroupName, groupName) + //}; + + //return DatabaseApi.Instance.GetIntResult(sqlString, parameters); + + return Get(Q + .Select(Attr.Taxis) + .Where(Attr.SiteId, siteId) + .Where(Attr.GroupName, groupName)); + } + + private void SetTaxis(int siteId, string groupName, int taxis) + { + //var sqlString = + // $"UPDATE {TableName} SET Taxis = {taxis} WHERE (GroupName = @GroupName AND SiteId = {siteId})"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamGroupName, groupName) + //}; + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Update(Q + .Set(Attr.Taxis, taxis) + .Where(Attr.SiteId, siteId) + .Where(Attr.GroupName, groupName) + ); + + ContentGroupManager.ClearCache(); + } + + private int GetMaxTaxis(int siteId) + { + //var sqlString = + // $"SELECT MAX(Taxis) FROM siteserver_ContentGroup WHERE (SiteId = {siteId})"; + //var maxTaxis = 0; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // if (rdr.Read()) + // { + // maxTaxis = DatabaseApi.GetInt(rdr, 0); + // } + // rdr.Close(); + //} + //return maxTaxis; + + return Max(Q + .Select(Attr.Taxis) + .Where(Attr.SiteId, siteId) + ) ?? 0; + } + + public void UpdateTaxisToUp(int siteId, string groupName) + { + //var sqlString = SqlDifferences.GetSqlString("siteserver_ContentGroup", new List + // { + // nameof(ContentGroupInfo.GroupName), + // nameof(ContentGroupInfo.Taxis) + // }, + // $"WHERE (Taxis > (SELECT Taxis FROM siteserver_ContentGroup WHERE GroupName = @GroupName AND SiteId = {siteId}) AND SiteId = {siteId})", + // "ORDER BY Taxis", 1); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamGroupName, groupName) + //}; + //var higherGroupName = string.Empty; + //var higherTaxis = 0; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // higherGroupName = DatabaseApi.GetString(rdr, 0); + // higherTaxis = DatabaseApi.GetInt(rdr, 1); + // } + // rdr.Close(); + //} + + var taxis = GetTaxis(siteId, groupName); + var result = Get<(string GroupName, int Taxis)?> (Q + .Select(Attr.GroupName, Attr.Taxis) + .Where(Attr.SiteId, siteId) + .Where(Attr.Taxis, ">", taxis) + .OrderBy(Attr.Taxis)); + + var higherGroupName = string.Empty; + var higherTaxis = 0; + if (result != null) + { + higherGroupName = result.Value.GroupName; + higherTaxis = result.Value.Taxis; + } + + if (!string.IsNullOrEmpty(higherGroupName)) + { + //Get Taxis Of Selected ID + var selectedTaxis = GetTaxis(siteId, groupName); + + //Set The Selected Class Taxis To Higher Level + SetTaxis(siteId, groupName, higherTaxis); + //Set The Higher Class Taxis To Lower Level + SetTaxis(siteId, higherGroupName, selectedTaxis); + } + + ContentGroupManager.ClearCache(); + } + + public void UpdateTaxisToDown(int siteId, string groupName) + { + //var sqlString = SqlDifferences.GetSqlString("siteserver_ContentGroup", new List + // { + // nameof(ContentGroupInfo.GroupName), + // nameof(ContentGroupInfo.Taxis) + // }, + // $"WHERE (Taxis < (SELECT Taxis FROM siteserver_ContentGroup WHERE GroupName = @GroupName AND SiteId = {siteId}) AND SiteId = {siteId})", + // "ORDER BY Taxis DESC", 1); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamGroupName, groupName) + //}; + //var lowerGroupName = string.Empty; + //var lowerTaxis = 0; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // lowerGroupName = DatabaseApi.GetString(rdr, 0); + // lowerTaxis = DatabaseApi.GetInt(rdr, 1); + // } + // rdr.Close(); + //} + + var taxis = GetTaxis(siteId, groupName); + var result = Get<(string GroupName, int Taxis)?>(Q + .Select(Attr.GroupName, Attr.Taxis) + .Where(Attr.SiteId, siteId) + .Where(Attr.Taxis, "<", taxis) + .OrderByDesc(Attr.Taxis)); + + var lowerGroupName = string.Empty; + var lowerTaxis = 0; + if (result != null) + { + lowerGroupName = result.Value.GroupName; + lowerTaxis = result.Value.Taxis; + } + + if (!string.IsNullOrEmpty(lowerGroupName)) + { + //Get Taxis Of Selected Class + var selectedTaxis = GetTaxis(siteId, groupName); + + //Set The Selected Class Taxis To Lower Level + SetTaxis(siteId, groupName, lowerTaxis); + //Set The Lower Class Taxis To Higher Level + SetTaxis(siteId, lowerGroupName, selectedTaxis); + } + + ContentGroupManager.ClearCache(); + } + + public Dictionary> GetAllContentGroups() + { + var allDict = new Dictionary>(); + + //var sqlString = + // $"SELECT GroupName, SiteId, Taxis, Description FROM {TableName} ORDER BY Taxis DESC, GroupName"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var group = new ContentGroupInfo(DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), + // DatabaseApi.GetString(rdr, i)); + + // allDict.TryGetValue(group.SiteId, out var list); + + // if (list == null) + // { + // list = new List(); + // } + + // list.Add(group); + + // allDict[group.SiteId] = list; + // } + // rdr.Close(); + //} + + var groupList = GetAll(Q + .OrderByDesc(Attr.Taxis) + .OrderBy(Attr.GroupName)); + + foreach (var group in groupList) + { + allDict.TryGetValue(group.SiteId, out var list); + + if (list == null) + { + list = new List(); + } + + list.Add(group); + + allDict[group.SiteId] = list; + } + + return allDict; + } + } +} + +//using System.Collections.Generic; + //using System.Data; + //using SiteServer.CMS.Database.Caches; + //using SiteServer.CMS.Database.Core; + //using SiteServer.CMS.Database.Models; + //using SiteServer.Plugin; + //using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class ContentGroupDao : DataProviderBase +// { +// public override string TableName => "siteserver_ContentGroup"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(ContentGroupInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(ContentGroupInfo.GroupName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ContentGroupInfo.SiteId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(ContentGroupInfo.Taxis), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(ContentGroupInfo.Description), +// DataType = DataType.Text +// } +// }; + +// private const string SqlInsert = "INSERT INTO siteserver_ContentGroup (GroupName, SiteId, Taxis, Description) VALUES (@GroupName, @SiteId, @Taxis, @Description)"; +// private const string SqlUpdate = "UPDATE siteserver_ContentGroup SET Description = @Description WHERE GroupName = @GroupName AND SiteId = @SiteId"; +// private const string SqlDelete = "DELETE FROM siteserver_ContentGroup WHERE GroupName = @GroupName AND SiteId = @SiteId"; + +// private const string ParamGroupName = "@GroupName"; +// private const string ParamSiteId = "@SiteId"; +// private const string ParamTaxis = "@Taxis"; +// private const string ParamDescription = "@Description"; + +// public void InsertObject(ContentGroupInfo contentGroup) +// { +// var maxTaxis = GetMaxTaxis(contentGroup.SiteId); +// contentGroup.Taxis = maxTaxis + 1; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamGroupName, contentGroup.GroupName), +// GetParameter(ParamSiteId, contentGroup.SiteId), +// GetParameter(ParamTaxis, contentGroup.Taxis), +// GetParameter(ParamDescription,contentGroup.Description) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlInsert, parameters); + +// ContentGroupManager.ClearCache(); +// } + +// public void UpdateObject(ContentGroupInfo contentGroup) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamDescription,contentGroup.Description), +// GetParameter(ParamGroupName, contentGroup.GroupName), +// GetParameter(ParamSiteId, contentGroup.SiteId) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdate, parameters); + +// ContentGroupManager.ClearCache(); +// } + +// public void DeleteById(string groupName, int siteId) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamGroupName, groupName), +// GetParameter(ParamSiteId, siteId) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDelete, parameters); + +// ContentGroupManager.ClearCache(); +// } + +// private void SetTaxis(int siteId, string groupName, int taxis) +// { +// var sqlString = +// $"UPDATE {TableName} SET Taxis = {taxis} WHERE (GroupName = @GroupName AND SiteId = {siteId})"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamGroupName, groupName) +// }; +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// ContentGroupManager.ClearCache(); +// } + +// public void UpdateTaxisToUp(int siteId, string groupName) +// { +// var sqlString = SqlDifferences.GetSqlString("siteserver_ContentGroup", new List +// { +// nameof(ContentGroupInfo.GroupName), +// nameof(ContentGroupInfo.Taxis) +// }, +// $"WHERE (Taxis > (SELECT Taxis FROM siteserver_ContentGroup WHERE GroupName = @GroupName AND SiteId = {siteId}) AND SiteId = {siteId})", +// "ORDER BY Taxis", 1); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamGroupName, groupName) +// }; +// var higherGroupName = string.Empty; +// var higherTaxis = 0; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// higherGroupName = DatabaseApi.GetString(rdr, 0); +// higherTaxis = DatabaseApi.GetInt(rdr, 1); +// } +// rdr.Close(); +// } + +// if (!string.IsNullOrEmpty(higherGroupName)) +// { +// //Get Taxis Of Selected ID +// var selectedTaxis = GetTaxis(siteId, groupName); + +// //Set The Selected Class Taxis To Higher Level +// SetTaxis(siteId, groupName, higherTaxis); +// //Set The Higher Class Taxis To Lower Level +// SetTaxis(siteId, higherGroupName, selectedTaxis); +// } + +// ContentGroupManager.ClearCache(); +// } + +// public void UpdateTaxisToDown(int siteId, string groupName) +// { +// var sqlString = SqlDifferences.GetSqlString("siteserver_ContentGroup", new List +// { +// nameof(ContentGroupInfo.GroupName), +// nameof(ContentGroupInfo.Taxis) +// }, +// $"WHERE (Taxis < (SELECT Taxis FROM siteserver_ContentGroup WHERE GroupName = @GroupName AND SiteId = {siteId}) AND SiteId = {siteId})", +// "ORDER BY Taxis DESC", 1); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamGroupName, groupName) +// }; +// var lowerGroupName = string.Empty; +// var lowerTaxis = 0; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// lowerGroupName = DatabaseApi.GetString(rdr, 0); +// lowerTaxis = DatabaseApi.GetInt(rdr, 1); +// } +// rdr.Close(); +// } + +// if (!string.IsNullOrEmpty(lowerGroupName)) +// { +// //Get Taxis Of Selected Class +// var selectedTaxis = GetTaxis(siteId, groupName); + +// //Set The Selected Class Taxis To Lower Level +// SetTaxis(siteId, groupName, lowerTaxis); +// //Set The Lower Class Taxis To Higher Level +// SetTaxis(siteId, lowerGroupName, selectedTaxis); +// } + +// ContentGroupManager.ClearCache(); +// } + +// public Dictionary> GetAllContentGroups() +// { +// var allDict = new Dictionary>(); + +// var sqlString = +// $"SELECT GroupName, SiteId, Taxis, Description FROM {TableName} ORDER BY Taxis DESC, GroupName"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var group = new ContentGroupInfo(DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), +// DatabaseApi.GetString(rdr, i)); + +// allDict.TryGetValue(group.SiteId, out var list); + +// if (list == null) +// { +// list = new List(); +// } + +// list.Add(group); + +// allDict[group.SiteId] = list; +// } +// rdr.Close(); +// } + +// return allDict; +// } + +// private int GetTaxis(int siteId, string groupName) +// { +// var sqlString = +// $"SELECT Taxis FROM siteserver_ContentGroup WHERE (GroupName = @GroupName AND SiteId = {siteId})"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamGroupName, groupName) +// }; + +// return DatabaseApi.Instance.GetIntResult(sqlString, parameters); +// } + +// private int GetMaxTaxis(int siteId) +// { +// var sqlString = +// $"SELECT MAX(Taxis) FROM siteserver_ContentGroup WHERE (SiteId = {siteId})"; +// var maxTaxis = 0; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// if (rdr.Read()) +// { +// maxTaxis = DatabaseApi.GetInt(rdr, 0); +// } +// rdr.Close(); +// } +// return maxTaxis; +// } + +// } +//} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Database/Repositories/ContentTagRepository.cs b/net452/SiteServer.CMS/Database/Repositories/ContentTagRepository.cs new file mode 100644 index 000000000..38282594c --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/ContentTagRepository.cs @@ -0,0 +1,250 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class ContentTagRepository : Repository + { + public ContentTagRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string TagName = nameof(ContentTagInfo.TagName); + public const string SiteId = nameof(ContentTagInfo.SiteId); + public const string UseNum = nameof(ContentTagInfo.UseNum); + } + + public override int Insert(ContentTagInfo tagInfo) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamTagName, contentTag.TagName), + // GetParameter(ParamSiteId, contentTag.SiteId), + // GetParameter(ParamUseNum, contentTag.UseNum) + //}; + //var SqlInsert = + // "INSERT INTO siteserver_ContentTag (TagName, SiteId, UseNum) VALUES (@TagName, @SiteId, @UseNum)"; + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlInsert, parameters); + + tagInfo.Id = Insert(tagInfo); + if (tagInfo.Id > 0) + { + ContentTagManager.ClearCache(); + } + + return tagInfo.Id; + } + + public override bool Update(ContentTagInfo tagInfo) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamUseNum, contentTag.UseNum), + // GetParameter(ParamTagName, contentTag.TagName), + // GetParameter(ParamSiteId, contentTag.SiteId) + //}; + //string SqlUpdate = "UPDATE siteserver_ContentTag SET UseNum = @UseNum WHERE TagName = @TagName AND SiteId = @SiteId"; + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdate, parameters); + + var updated = base.Update(tagInfo); + if (updated) + { + ContentTagManager.ClearCache(); + } + + return updated; + } + + public void Delete(int siteId, string tagName) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamTagName, tagName), + // GetParameter(ParamSiteId, siteId) + //}; + //string SqlDelete = "DELETE FROM siteserver_ContentTag WHERE TagName = @TagName AND SiteId = @SiteId"; + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDelete, parameters); + + Delete(Q + .Where(Attr.SiteId, siteId) + .Where(Attr.TagName, tagName)); + + ContentTagManager.ClearCache(); + } + + public Dictionary> GetAllContentTags() + { + var allDict = new Dictionary>(); + + //var sqlString = + // $"SELECT Id, TagName, SiteId, UseNum FROM {TableName} ORDER BY UseNum DESC, TagName"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var tag = new ContentTagInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i)); + + // allDict.TryGetValue(tag.SiteId, out var list); + + // if (list == null) + // { + // list = new List(); + // } + + // list.Add(tag); + + // allDict[tag.SiteId] = list; + // } + // rdr.Close(); + //} + + var tagList = GetAll(Q + .OrderByDesc(Attr.UseNum) + .OrderBy(Attr.TagName)); + + foreach (var tag in tagList) + { + allDict.TryGetValue(tag.SiteId, out var list); + + if (list == null) + { + list = new List(); + } + + list.Add(tag); + + allDict[tag.SiteId] = list; + } + + return allDict; + } + } +} + +//using System.Collections.Generic; + //using System.Data; + //using SiteServer.CMS.Database.Caches; + //using SiteServer.CMS.Database.Core; + //using SiteServer.CMS.Database.Models; + //using SiteServer.Plugin; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class ContentTagDao : DataProviderBase +// { +// public override string TableName => "siteserver_ContentTag"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(ContentTagInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(ContentTagInfo.TagName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ContentTagInfo.SiteId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(ContentTagInfo.UseNum), +// DataType = DataType.Integer +// } +// }; + +// private const string SqlInsert = "INSERT INTO siteserver_ContentTag (TagName, SiteId, UseNum) VALUES (@TagName, @SiteId, @UseNum)"; +// private const string SqlUpdate = "UPDATE siteserver_ContentTag SET UseNum = @UseNum WHERE TagName = @TagName AND SiteId = @SiteId"; +// private const string SqlDelete = "DELETE FROM siteserver_ContentTag WHERE TagName = @TagName AND SiteId = @SiteId"; + +// private const string ParamTagName = "@TagName"; +// private const string ParamSiteId = "@SiteId"; +// private const string ParamUseNum = "@UseNum"; + +// public void InsertObject(ContentTagInfo contentTag) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamTagName, contentTag.TagName), +// GetParameter(ParamSiteId, contentTag.SiteId), +// GetParameter(ParamUseNum, contentTag.UseNum) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlInsert, parameters); + +// ContentTagManager.ClearCache(); +// } + +// public void UpdateObject(ContentTagInfo contentTag) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamUseNum, contentTag.UseNum), +// GetParameter(ParamTagName, contentTag.TagName), +// GetParameter(ParamSiteId, contentTag.SiteId) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdate, parameters); + +// ContentTagManager.ClearCache(); +// } + +// public void DeleteById(string tagName, int siteId) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamTagName, tagName), +// GetParameter(ParamSiteId, siteId) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDelete, parameters); + +// ContentTagManager.ClearCache(); +// } + +// public Dictionary> GetAllContentTags() +// { +// var allDict = new Dictionary>(); + +// var sqlString = +// $"SELECT Id, TagName, SiteId, UseNum FROM {TableName} ORDER BY UseNum DESC, TagName"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var tag = new ContentTagInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i)); + +// allDict.TryGetValue(tag.SiteId, out var list); + +// if (list == null) +// { +// list = new List(); +// } + +// list.Add(tag); + +// allDict[tag.SiteId] = list; +// } +// rdr.Close(); +// } + +// return allDict; +// } +// } +//} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Database/Repositories/Contents/ContentRepository.cs b/net452/SiteServer.CMS/Database/Repositories/Contents/ContentRepository.cs new file mode 100644 index 000000000..4943c19be --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/Contents/ContentRepository.cs @@ -0,0 +1,2554 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Data; +using System.Linq; +using System.Text; +using Dapper; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Core.RestRoutes.V1; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; +using Attr = SiteServer.CMS.Database.Attributes.ContentAttribute; + +namespace SiteServer.CMS.Database.Repositories.Contents +{ + public class ContentRepository + { + protected virtual string ConnectionString => WebConfigUtils.ConnectionString; + + protected IDbConnection GetConnection() + { + return DatoryUtils.GetConnection(WebConfigUtils.DatabaseType, ConnectionString); + } + + protected IDataParameter GetParameter(string name, object value) + { + return DataProvider.DatabaseApi.GetParameter(name, value); + } + + private const int TaxisIsTopStartValue = 2000000000; + + private static readonly List MinListColumns = new List + { + Attr.Id, + Attr.ChannelId, + Attr.IsTop, + Attr.AddDate, + Attr.LastEditDate, + Attr.Taxis, + Attr.Hits, + Attr.HitsByDay, + Attr.HitsByWeek, + Attr.HitsByMonth + }; + + public static string GetContentTableName(int siteId) + { + return $"siteserver_Content_{siteId}"; + } + + public List TableColumns => DatoryUtils.GetTableColumns(); + + public List TableColumnsDefault + { + get + { + var tableColumns = new List(); + tableColumns.AddRange(TableColumns); + tableColumns.Add(new TableColumn + { + AttributeName = Attr.SubTitle, + DataType = DataType.VarChar + }); + tableColumns.Add(new TableColumn + { + AttributeName = Attr.ImageUrl, + DataType = DataType.VarChar + }); + tableColumns.Add(new TableColumn + { + AttributeName = Attr.VideoUrl, + DataType = DataType.VarChar + }); + tableColumns.Add(new TableColumn + { + AttributeName = Attr.FileUrl, + DataType = DataType.VarChar + }); + tableColumns.Add(new TableColumn + { + AttributeName = Attr.Content, + DataType = DataType.Text + }); + tableColumns.Add(new TableColumn + { + AttributeName = Attr.Summary, + DataType = DataType.Text + }); + tableColumns.Add(new TableColumn + { + AttributeName = Attr.Author, + DataType = DataType.VarChar + }); + tableColumns.Add(new TableColumn + { + AttributeName = Attr.Source, + DataType = DataType.VarChar + }); + + return tableColumns; + } + } + + public int GetContentId(string tableName, int channelId, string orderByString) + { + var contentId = 0; + var sqlString = DataProvider.DatabaseApi.GetSqlString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, new List + { + Attr.Id + }, $"WHERE (ChannelId = {channelId})", orderByString, 1); + + using (var rdr = DataProvider.DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + { + if (rdr.Read()) + { + contentId = DataProvider.DatabaseApi.GetInt(rdr, 0); + } + rdr.Close(); + } + return contentId; + } + + public List GetValueListByStartString(string tableName, int channelId, string name, string startString, int totalNum) + { + var inStr = SqlUtils.GetInStr(name, startString); + var sqlString = DataProvider.DatabaseApi.GetSqlString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, new List { name }, $"WHERE ChannelId = {channelId} AND {inStr}", string.Empty, 0, totalNum, true); + return DataProvider.DatabaseApi.GetStringList(sqlString); + } + + public int GetChannelId(string tableName, int contentId) + { + var channelId = 0; + var sqlString = $"SELECT {Attr.ChannelId} FROM {tableName} WHERE (Id = {contentId})"; + + using (var rdr = DataProvider.DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + { + if (rdr.Read()) + { + channelId = DataProvider.DatabaseApi.GetInt(rdr, 0); + } + rdr.Close(); + } + return channelId; + } + + public List GetChannelIdListCheckedByLastEditDateHour(string tableName, int siteId, int hour) + { + var list = new List(); + + var sqlString = + $"SELECT DISTINCT ChannelId FROM {tableName} WHERE (SiteId = {siteId}) AND (IsChecked = '{true}') AND (LastEditDate BETWEEN {SqlUtils.GetComparableDateTime(DateTime.Now.AddHours(-hour))} AND {SqlUtils.GetComparableNow()})"; + + using (var rdr = DataProvider.DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + { + while (rdr.Read()) + { + var channelId = DataProvider.DatabaseApi.GetInt(rdr, 0); + list.Add(channelId); + } + rdr.Close(); + } + return list; + } + + //public override List TableColumns => new List + //{ + // new TableColumn + // { + // AttributeName = Attr.Id), + // DataType = DataType.Integer, + // IsIdentity = true, + // IsPrimaryKey = true + // }, + // new TableColumn + // { + // AttributeName = Attr.ChannelId), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = Attr.SiteId), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = Attr.AddUserName), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = Attr.LastEditUserName), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = Attr.LastEditDate), + // DataType = DataType.DateTime + // }, + // new TableColumn + // { + // AttributeName = Attr.AdminId), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = Attr.UserId), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = Attr.Taxis), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = Attr.GroupNameCollection), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = Attr.Tags), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = Attr.SourceId), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = Attr.ReferenceId), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = Attr.IsChecked), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = Attr.CheckedLevel), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = Attr.Hits), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = Attr.HitsByDay), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = Attr.HitsByWeek), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = Attr.HitsByMonth), + // DataType = DataType.Integer + // }, + // new TableColumn + // { + // AttributeName = Attr.LastHitsDate), + // DataType = DataType.DateTime + // }, + // new TableColumn + // { + // AttributeName = Attr.SettingsXml), + // DataType = DataType.Text + // }, + // new TableColumn + // { + // AttributeName = Attr.Title), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = Attr.IsTop), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = Attr.IsRecommend), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = Attr.IsHot), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = Attr.IsColor), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = Attr.LinkUrl), + // DataType = DataType.VarChar + // }, + // new TableColumn + // { + // AttributeName = Attr.AddDate), + // DataType = DataType.DateTime + // } + //}; + + //private void UpdateTaxis(int channelId, int id, int taxis, string tableName) + //{ + // var sqlString = $"UPDATE {tableName} SET Taxis = {taxis} WHERE Id = {id}"; + // DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + // ContentManager.RemoveCache(tableName, channelId); + //} + + //public void DeleteContentsByTrash(int siteId, int channelId, string tableName) + //{ + // if (string.IsNullOrEmpty(tableName)) return; + + // var contentIdList = GetContentIdListByTrash(siteId, tableName); + // TagUtils.RemoveTags(siteId, contentIdList); + + // var sqlString = + // $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND ChannelId < 0"; + // DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + // ContentManager.RemoveCache(tableName, channelId); + //} + + //public void SetAutoPageContentToSite(SiteInfo siteInfo) + //{ + // if (!siteInfo.IsAutoPageInTextEditor) return; + + // var sqlString = + // $"SELECT Id, {Attr.ChannelId)}, {Attr.Content)} FROM {siteInfo.TableName} WHERE SiteId = {siteInfo.Id}"; + + // using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + // { + // while (rdr.Read()) + // { + // var contentId = DatabaseApi.GetInt(rdr, 0); + // var channelId = DatabaseApi.GetInt(rdr, 1); + // var content = DatabaseApi.GetString(rdr, 2); + + // if (!string.IsNullOrEmpty(content)) + // { + // content = ContentUtility.GetAutoPageContent(content, siteInfo.AutoPageWordNum); + + // Update(siteInfo.TableName, channelId, contentId, Attr.Content), content); + // } + // } + + // rdr.Close(); + // } + //} + + //public void UpdateTrashContents(int siteId, int channelId, string tableName, List contentIdList) + //{ + // if (string.IsNullOrEmpty(tableName)) return; + + // var referenceIdList = GetReferenceIdList(tableName, contentIdList); + // if (referenceIdList.Count > 0) + // { + // DeleteContents(siteId, channelId, tableName, referenceIdList); + // } + + // var updateNum = 0; + + // if (!string.IsNullOrEmpty(tableName) && contentIdList != null && contentIdList.Count > 0) + // { + // var sqlString = + // $"UPDATE {tableName} SET ChannelId = -ChannelId, LastEditDate = {SqlUtils.GetComparableNow()} WHERE SiteId = {siteId} AND Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; + // updateNum = DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + // } + + // if (updateNum <= 0) return; + + // ContentManager.RemoveCache(tableName, channelId); + //} + + //public void UpdateTrashContentsByChannelId(int siteId, int channelId, string tableName) + //{ + // if (string.IsNullOrEmpty(tableName)) return; + + // var contentIdList = GetContentIdList(tableName, channelId); + // var referenceIdList = GetReferenceIdList(tableName, contentIdList); + // if (referenceIdList.Count > 0) + // { + // DeleteContents(siteId, channelId, tableName, referenceIdList); + // } + // var updateNum = 0; + + // if (!string.IsNullOrEmpty(tableName)) + // { + // var sqlString = + // $"UPDATE {tableName} SET ChannelId = -ChannelId, LastEditDate = {SqlUtils.GetComparableNow()} WHERE SiteId = {siteId} AND ChannelId = {siteId}"; + // updateNum = DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + // } + + // if (updateNum <= 0) return; + + // ContentManager.RemoveCache(tableName, channelId); + //} + + //public void DeleteContent(string tableName, SiteInfo siteInfo, int channelId, int contentId) + //{ + // if (string.IsNullOrEmpty(tableName)) return; + + // if (!string.IsNullOrEmpty(tableName) && contentId > 0) + // { + // TagUtils.RemoveTags(siteInfo.Id, contentId); + + // var sqlString = + // $"DELETE FROM {tableName} WHERE SiteId = {siteInfo.Id} AND Id = {contentId}"; + // DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + // } + + // if (channelId <= 0) return; + + // ContentManager.RemoveCache(tableName, channelId); + //} + + //public void DeleteContents(int siteId, string tableName, List contentIdList, int channelId) + //{ + // if (string.IsNullOrEmpty(tableName)) return; + + // var deleteNum = 0; + + // if (!string.IsNullOrEmpty(tableName) && contentIdList != null && contentIdList.Count > 0) + // { + // TagUtils.RemoveTags(siteId, contentIdList); + + // var sqlString = + // $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; + // deleteNum = DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + // } + + // if (channelId <= 0 || deleteNum <= 0) return; + + // ContentManager.RemoveCache(tableName, channelId); + //} + + //public void DeleteContentsByChannelId(int siteId, string tableName, int channelId) + //{ + // if (string.IsNullOrEmpty(tableName)) return; + + // var contentIdList = GetContentIdListChecked(tableName, channelId, string.Empty); + + // TagUtils.RemoveTags(siteId, contentIdList); + + // var sqlString = + // $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelId}"; + // var deleteNum = DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + // if (channelId <= 0 || deleteNum <= 0) return; + + // ContentManager.RemoveCache(tableName, channelId); + //} + + //public void DeleteContentsByDeletedChannelIdList(SiteInfo siteInfo, List channelIdList) + //{ + // foreach (var channelId in channelIdList) + // { + // var tableName = ChannelManager.GetTableName(siteInfo, channelId); + // if (string.IsNullOrEmpty(tableName)) continue; + + // DatabaseApi.ExecuteNonQuery(ConnectionString, $"DELETE FROM {tableName} WHERE SiteId = {siteInfo.Id} AND {Attr.ChannelId)} = {channelId}"); + + // ContentManager.RemoveCache(tableName, channelId); + // } + //} + + //public void UpdateRestoreContentsByTrash(int siteId, int channelId, string tableName) + //{ + // var updateNum = 0; + + // if (!string.IsNullOrEmpty(tableName)) + // { + // var sqlString = + // $"UPDATE {tableName} SET ChannelId = -ChannelId, LastEditDate = {SqlUtils.GetComparableNow()} WHERE SiteId = {siteId} AND ChannelId < 0"; + // updateNum = DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + // } + + // if (updateNum <= 0) return; + + // ContentManager.RemoveCache(tableName, channelId); + //} + + //private void DeleteContents(int siteId, int channelId, string tableName, List contentIdList) + //{ + // if (string.IsNullOrEmpty(tableName)) return; + + // var deleteNum = 0; + + // if (!string.IsNullOrEmpty(tableName) && contentIdList != null && contentIdList.Count > 0) + // { + // TagUtils.RemoveTags(siteId, contentIdList); + + // var sqlString = + // $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; + // deleteNum = DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + // } + + // if (deleteNum <= 0) return; + + // ContentManager.RemoveCache(tableName, channelId); + //} + + //public void DeletePreviewContents(int siteId, string tableName, ChannelInfo channelInfo) + //{ + // if (string.IsNullOrEmpty(tableName)) return; + + // channelInfo.IsPreviewContentsExists = false; + // DataProvider.Channel.UpdateExtend(channelInfo); + + // var sqlString = + // $"DELETE FROM {tableName} WHERE {Attr.SiteId)} = @{Attr.SiteId)} AND {Attr.ChannelId)} = @{Attr.ChannelId)} AND {Attr.SourceId)} = @{Attr.SourceId)}"; + + // using (var connection = GetConnection()) + // { + // connection.Execute(sqlString, new + // { + // SiteId = siteId, + // ChannelId = channelInfo.Id, + // SourceId = SourceManager.Preview + // } + // ); + // } + //} + + //private List GetReferenceIdList(string tableName, List contentIdList) + //{ + // var list = new List(); + // var sqlString = + // $"SELECT Id FROM {tableName} WHERE ChannelId > 0 AND ReferenceId IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; + + // using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + // { + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetInt(rdr, 0)); + // } + // rdr.Close(); + // } + + // return list; + //} + + //public List GetContentIdList(string tableName, int channelId) + //{ + // var list = new List(); + + // var sqlString = $"SELECT Id FROM {tableName} WHERE ChannelId = {channelId}"; + // using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + // { + // while (rdr.Read()) + // { + // var contentId = DatabaseApi.GetInt(rdr, 0); + // list.Add(contentId); + // } + // rdr.Close(); + // } + // return list; + //} + + //public int GetTotalHits(string tableName, int siteId) + //{ + // return DatabaseApi.GetIntResult($"SELECT SUM(Hits) FROM {tableName} WHERE IsChecked='{true}' AND SiteId = {siteId} AND Hits > 0"); + //} + + //public int GetFirstContentId(string tableName, int channelId) + //{ + // var sqlString = $"SELECT Id FROM {tableName} WHERE ChannelId = {channelId} ORDER BY Taxis DESC, Id DESC"; + // return DatabaseApi.GetIntResult(sqlString); + //} + + //public List GetCacheContentInfoList(SiteInfo siteInfo, ChannelInfo channelInfo, int offset, int limit) + //{ + // var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + + // return GetContentInfoList(tableName, GetCacheWhereString(siteInfo, channelInfo), + // GetOrderString(channelInfo, string.Empty), offset, limit); + //} + + //public List GetCacheContentIdList(SiteInfo siteInfo, ChannelInfo channelInfo, int offset, int limit) + //{ + // var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + + // return GetCacheContentIdList(tableName, GetCacheWhereString(siteInfo, channelInfo), + // GetOrderString(channelInfo, string.Empty), offset, limit); + //} + + //public bool SetTaxisToUp(string tableName, int channelId, int contentId, bool isTop) + //{ + // //Get Higher Taxis and Id + // var sqlString = DatorySql.GetSqlString(tableName, new List + // { + // Attr.Id, + // Attr.Taxis + // }, + // isTop + // ? $"WHERE (Taxis > (SELECT Taxis FROM {tableName} WHERE Id = {contentId}) AND Taxis >= {TaxisIsTopStartValue} AND ChannelId = {channelId})" + // : $"WHERE (Taxis > (SELECT Taxis FROM {tableName} WHERE Id = {contentId}) AND Taxis < {TaxisIsTopStartValue} AND ChannelId = {channelId})", + // "ORDER BY Taxis", 1); + // var higherId = 0; + // var higherTaxis = 0; + + // using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + // { + // if (rdr.Read()) + // { + // higherId = DatabaseApi.GetInt(rdr, 0); + // higherTaxis = DatabaseApi.GetInt(rdr, 1); + // } + // rdr.Close(); + // } + + // if (higherId != 0) + // { + // //Get Taxis Of Selected Id + // var selectedTaxis = GetTaxis(contentId, tableName); + + // //Set The Selected Class Taxis To Higher Level + // UpdateTaxis(channelId, contentId, higherTaxis, tableName); + // //Set The Higher Class Taxis To Lower Level + // UpdateTaxis(channelId, higherId, selectedTaxis, tableName); + // return true; + // } + // return false; + //} + + //public bool SetTaxisToDown(string tableName, int channelId, int contentId, bool isTop) + //{ + // //Get Lower Taxis and Id + // var sqlString = DatorySql.GetSqlString(tableName, new List + // { + // Attr.Id, + // Attr.Taxis + // }, + // isTop + // ? $"WHERE (Taxis < (SELECT Taxis FROM {tableName} WHERE Id = {contentId}) AND Taxis >= {TaxisIsTopStartValue} AND ChannelId = {channelId})" + // : $"WHERE (Taxis < (SELECT Taxis FROM {tableName} WHERE Id = {contentId}) AND Taxis < {TaxisIsTopStartValue} AND ChannelId = {channelId})", + // "ORDER BY Taxis DESC", 1); + // var lowerId = 0; + // var lowerTaxis = 0; + + // using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + // { + // if (rdr.Read()) + // { + // lowerId = DatabaseApi.GetInt(rdr, 0); + // lowerTaxis = DatabaseApi.GetInt(rdr, 1); + // } + // rdr.Close(); + // } + + // if (lowerId != 0) + // { + // //Get Taxis Of Selected Class + // var selectedTaxis = GetTaxis(contentId, tableName); + + // //Set The Selected Class Taxis To Lower Level + // UpdateTaxis(channelId, contentId, lowerTaxis, tableName); + // //Set The Lower Class Taxis To Higher Level + // UpdateTaxis(channelId, lowerId, selectedTaxis, tableName); + // return true; + // } + // return false; + //} + + //public int GetMaxTaxis(string tableName, int channelId, bool isTop) + //{ + // var maxTaxis = 0; + // if (isTop) + // { + // maxTaxis = TaxisIsTopStartValue; + + // var sqlString = + // $"SELECT MAX(Taxis) FROM {tableName} WHERE ChannelId = {channelId} AND Taxis >= {TaxisIsTopStartValue}"; + + // using (var conn = GetConnection()) + // { + // conn.Open(); + // using (var rdr = DatabaseApi.ExecuteReader(conn, sqlString)) + // { + // if (rdr.Read()) + // { + // maxTaxis = DatabaseApi.GetInt(rdr, 0); + // } + // rdr.Close(); + // } + // } + + // if (maxTaxis < TaxisIsTopStartValue) + // { + // maxTaxis = TaxisIsTopStartValue; + // } + // } + // else + // { + // var sqlString = + // $"SELECT MAX(Taxis) FROM {tableName} WHERE ChannelId = {channelId} AND Taxis < {TaxisIsTopStartValue}"; + // using (var conn = GetConnection()) + // { + // conn.Open(); + // using (var rdr = DatabaseApi.ExecuteReader(conn, sqlString)) + // { + // if (rdr.Read()) + // { + // maxTaxis = DatabaseApi.GetInt(rdr, 0); + // } + // rdr.Close(); + // } + // } + // } + // return maxTaxis; + //} + + //public Tuple GetValue(string tableName, int contentId, string name) + //{ + // Tuple tuple = null; + + // try + // { + // var sqlString = $"SELECT {Attr.ChannelId}, {name} FROM {tableName} WHERE Id = {contentId}"; + + // using (var conn = GetConnection()) + // { + // conn.Open(); + // using (var rdr = DatabaseApi.ExecuteReader(conn, sqlString)) + // { + // if (rdr.Read()) + // { + // var channelId = DatabaseApi.GetInt(rdr, 0); + // var value = DatabaseApi.GetString(rdr, 1); + + // tuple = new Tuple(channelId, value); + // } + + // rdr.Close(); + // } + // } + // } + // catch + // { + // // ignored + // } + + // return tuple; + //} + + //public void AddContentGroupList(string tableName, int contentId, List contentGroupList) + //{ + // var tuple = GetValue(tableName, contentId, Attr.GroupNameCollection); + + // if (tuple != null) + // { + // var list = TranslateUtils.StringCollectionToStringList(tuple.Item2); + // foreach (var groupName in contentGroupList) + // { + // if (!list.Contains(groupName)) list.Add(groupName); + // } + // Update(tableName, tuple.Item1, contentId, Attr.GroupNameCollection, TranslateUtils.ObjectCollectionToString(list)); + // } + //} + + + //public List GetContentIdList(string tableName, int channelId, bool isPeriods, string dateFrom, string dateTo, ETriState checkedState) + //{ + // var list = new List(); + + // var sqlString = $"SELECT Id FROM {tableName} WHERE ChannelId = {channelId}"; + // if (isPeriods) + // { + // var dateString = string.Empty; + // if (!string.IsNullOrEmpty(dateFrom)) + // { + // dateString = $" AND AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))} "; + // } + // if (!string.IsNullOrEmpty(dateTo)) + // { + // dateString += $" AND AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo).AddDays(1))} "; + // } + // sqlString += dateString; + // } + + // if (checkedState != ETriState.All) + // { + // sqlString += $" AND IsChecked = '{ETriStateUtils.GetValue(checkedState)}'"; + // } + + // sqlString += " ORDER BY Taxis DESC, Id DESC"; + + // using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + // { + // while (rdr.Read()) + // { + // var contentId = DatabaseApi.GetInt(rdr, 0); + // list.Add(contentId); + // } + // rdr.Close(); + // } + // return list; + //} + + //public List GetContentIdListCheckedByChannelId(string tableName, int siteId, int channelId) + //{ + // var list = new List(); + + // var sqlString = $"SELECT Id FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelId} AND IsChecked = '{true}'"; + // using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + // { + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetInt(rdr, 0)); + // } + // rdr.Close(); + // } + // return list; + //} + + //public int GetContentId(string tableName, int channelId, int taxis, bool isNextContent) + //{ + // var contentId = 0; + // var sqlString = DatorySql.GetSqlString(tableName, new List + // { + // Attr.Id + // }, $"WHERE (ChannelId = {channelId} AND Taxis > {taxis} AND IsChecked = 'True')", "ORDER BY Taxis", 1); + // if (isNextContent) + // { + // sqlString = DatorySql.GetSqlString(tableName, new List + // { + // Attr.Id + // }, + // $"WHERE (ChannelId = {channelId} AND Taxis < {taxis} AND IsChecked = 'True')", "ORDER BY Taxis DESC", 1); + // } + + // using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + // { + // if (rdr.Read()) + // { + // contentId = DatabaseApi.GetInt(rdr, 0); + // } + // rdr.Close(); + // } + // return contentId; + //} + + + + + + + + //public int GetSequence(string tableName, int channelId, int contentId) + //{ + // var sqlString = + // $"SELECT COUNT(*) FROM {tableName} WHERE {Attr.ChannelId} = {channelId} AND {Attr.IsChecked} = '{true}' AND Taxis < (SELECT Taxis FROM {tableName} WHERE Id = {contentId}) AND {Attr.SourceId} != {SourceManager.Preview}"; + + // return DatabaseApi.GetIntResult(sqlString) + 1; + //} + + //public List GetIdListBySameTitle(string tableName, int channelId, string title) + //{ + // var list = new List(); + // var sql = $"SELECT Id FROM {tableName} WHERE ChannelId = {channelId} AND Title = '{title}'"; + // using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sql)) + // { + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetInt(rdr, 0)); + // } + // rdr.Close(); + // } + // return list; + //} + + //public void Update(string tableName, int channelId, int contentId, string name, string value) + //{ + // var sqlString = $"UPDATE {tableName} SET {name} = @{name} WHERE Id = @Id"; + + // var parameters = new DynamicParameters(); + // parameters.Add($"@{name}", value); + // parameters.Add("@Id", contentId); + + // using (var connection = GetConnection()) + // { + // connection.Execute(sqlString, parameters); + // } + + // ContentManager.RemoveCache(tableName, channelId); + //} + + //public int GetCountCheckedImage(int siteId, int channelId) + //{ + // var tableName = SiteManager.GetSiteInfo(siteId).TableName; + // var sqlString = + // $"SELECT COUNT(*) FROM {tableName} WHERE {Attr.ChannelId} = {channelId} AND {Attr.ImageUrl} != '' AND {Attr.IsChecked} = '{true}' AND {Attr.SourceId} != {SourceManager.Preview}"; + + // return DatabaseApi.GetIntResult(sqlString); + //} + + //private int GetTaxis(int selectedId, string tableName) + //{ + // var sqlString = $"SELECT Taxis FROM {tableName} WHERE (Id = {selectedId})"; + + // return DatabaseApi.GetIntResult(sqlString); + //} + + //private List GetContentIdListByTrash(int siteId, string tableName) + //{ + // var sqlString = + // $"SELECT Id FROM {tableName} WHERE SiteId = {siteId} AND ChannelId < 0"; + // return DatabaseApi.GetIntList(sqlString); + //} + + //private int GetTaxisToInsert(string tableName, int channelId, bool isTop) + //{ + // int taxis; + + // if (isTop) + // { + // taxis = GetMaxTaxis(tableName, channelId, true) + 1; + // } + // else + // { + // taxis = GetMaxTaxis(tableName, channelId, false) + 1; + // } + + // return taxis; + //} + + public DataSet GetDataSetOfAdminExcludeRecycle(string tableName, int siteId, DateTime begin, DateTime end) + { + var sqlString = GetSqlStringOfAdminExcludeRecycle(tableName, siteId, begin, end); + + return DataProvider.DatabaseApi.ExecuteDataset(ConnectionString, sqlString); + } + + public int Insert(string tableName, SiteInfo siteInfo, ChannelInfo channelInfo, ContentInfo contentInfo) + { + var taxis = 0; + if (contentInfo.SourceId == SourceManager.Preview) + { + channelInfo.IsPreviewContentsExists = true; + DataProvider.Channel.UpdateExtend(channelInfo); + } + else + { + taxis = channelInfo.ContentRepository.GetTaxisToInsert(contentInfo.ChannelId, contentInfo.Top); + } + return InsertWithTaxis(tableName, siteInfo, channelInfo, contentInfo, taxis); + } + + public int InsertPreview(string tableName, SiteInfo siteInfo, ChannelInfo channelInfo, ContentInfo contentInfo) + { + channelInfo.IsPreviewContentsExists = true; + DataProvider.Channel.UpdateExtend(channelInfo); + + contentInfo.SourceId = SourceManager.Preview; + return InsertWithTaxis(tableName, siteInfo, channelInfo, contentInfo, 0); + } + + public int InsertWithTaxis(string tableName, SiteInfo siteInfo, ChannelInfo channelInfo, ContentInfo contentInfo, int taxis) + { + if (string.IsNullOrEmpty(tableName)) return 0; + + if (siteInfo.IsAutoPageInTextEditor && contentInfo.ContainsKey(Attr.Content)) + { + contentInfo.Content = ContentUtility.GetAutoPageContent(contentInfo.Content, siteInfo.AutoPageWordNum); + } + + contentInfo.Taxis = taxis; + + var contentId = InsertInner(tableName, siteInfo, channelInfo, contentInfo); + + return contentId; + } + + private int InsertInner(string tableName, SiteInfo siteInfo, ChannelInfo channelInfo, ContentInfo contentInfo) + { + if (string.IsNullOrEmpty(tableName) || contentInfo == null) return 0; + + contentInfo.LastEditDate = DateTime.Now; + + var columnInfoList = TableColumnManager.GetTableColumnInfoList(tableName, Attr.AllAttributes.Value); + + var names = new StringBuilder(); + var values = new StringBuilder(); + var paras = new List(); + var excludeAttributesNames = new List(Attr.AllAttributes.Value); + foreach (var columnInfo in columnInfoList) + { + excludeAttributesNames.Add(columnInfo.AttributeName); + names.Append($",{columnInfo.AttributeName}").AppendLine(); + values.Append($",@{columnInfo.AttributeName}").AppendLine(); + if (columnInfo.DataType == DataType.Integer) + { + paras.Add(GetParameter(columnInfo.AttributeName, contentInfo.Get(columnInfo.AttributeName))); + } + else if (columnInfo.DataType == DataType.Decimal) + { + paras.Add(GetParameter(columnInfo.AttributeName, contentInfo.Get(columnInfo.AttributeName))); + } + else if (columnInfo.DataType == DataType.Boolean) + { + paras.Add(GetParameter(columnInfo.AttributeName, contentInfo.Get(columnInfo.AttributeName))); + } + else if (columnInfo.DataType == DataType.DateTime) + { + paras.Add(GetParameter(columnInfo.AttributeName, contentInfo.Get(columnInfo.AttributeName))); + } + else + { + paras.Add(GetParameter(columnInfo.AttributeName, contentInfo.Get(columnInfo.AttributeName, string.Empty))); + } + } + + var sqlString = $@" +INSERT INTO {tableName} ( + {Attr.ChannelId}, + {Attr.SiteId}, + {Attr.AddUserName}, + {Attr.LastEditUserName}, + {Attr.LastEditDate}, + {Attr.AdminId}, + {Attr.UserId}, + {Attr.Taxis}, + {Attr.GroupNameCollection}, + {Attr.Tags}, + {Attr.SourceId}, + {Attr.ReferenceId}, + {Attr.IsChecked}, + {Attr.CheckedLevel}, + {Attr.Hits}, + {Attr.HitsByDay}, + {Attr.HitsByWeek}, + {Attr.HitsByMonth}, + {Attr.LastHitsDate}, + {Attr.Downloads}, + {Attr.SettingsXml}, + {Attr.Title}, + {Attr.IsTop}, + {Attr.IsRecommend}, + {Attr.IsHot}, + {Attr.IsColor}, + {Attr.LinkUrl}, + {Attr.AddDate} + {names} +) VALUES ( + @{Attr.ChannelId}, + @{Attr.SiteId}, + @{Attr.AddUserName}, + @{Attr.LastEditUserName}, + @{Attr.LastEditDate}, + @{Attr.AdminId}, + @{Attr.UserId}, + @{Attr.Taxis}, + @{Attr.GroupNameCollection}, + @{Attr.Tags}, + @{Attr.SourceId}, + @{Attr.ReferenceId}, + @{Attr.IsChecked}, + @{Attr.CheckedLevel}, + @{Attr.Hits}, + @{Attr.HitsByDay}, + @{Attr.HitsByWeek}, + @{Attr.HitsByMonth}, + @{Attr.LastHitsDate}, + @{Attr.Downloads}, + @{Attr.SettingsXml}, + @{Attr.Title}, + @{Attr.IsTop}, + @{Attr.IsRecommend}, + @{Attr.IsHot}, + @{Attr.IsColor}, + @{Attr.LinkUrl}, + @{Attr.AddDate} + {values} +)"; + + var parameters = new List + { + GetParameter(Attr.ChannelId, contentInfo.ChannelId), + GetParameter(Attr.SiteId, contentInfo.SiteId), + GetParameter(Attr.AddUserName, contentInfo.AddUserName), + GetParameter(Attr.LastEditUserName, contentInfo.LastEditUserName), + GetParameter(Attr.LastEditDate,contentInfo.LastEditDate), + GetParameter(Attr.AdminId, contentInfo.AdminId), + GetParameter(Attr.UserId, contentInfo.UserId), + GetParameter(Attr.Taxis, contentInfo.Taxis), + GetParameter(Attr.GroupNameCollection, contentInfo.GroupNameCollection), + GetParameter(Attr.Tags, contentInfo.Tags), + GetParameter(Attr.SourceId, contentInfo.SourceId), + GetParameter(Attr.ReferenceId, contentInfo.ReferenceId), + GetParameter(Attr.IsChecked, contentInfo.Checked.ToString()), + GetParameter(Attr.CheckedLevel, contentInfo.CheckedLevel), + GetParameter(Attr.Hits, contentInfo.Hits), + GetParameter(Attr.HitsByDay, contentInfo.HitsByDay), + GetParameter(Attr.HitsByWeek, contentInfo.HitsByWeek), + GetParameter(Attr.HitsByMonth, contentInfo.HitsByMonth), + GetParameter(Attr.LastHitsDate,contentInfo.LastHitsDate), + GetParameter(Attr.Downloads, contentInfo.Downloads), + GetParameter(Attr.SettingsXml,contentInfo.SettingsXml), + GetParameter(Attr.Title, contentInfo.Title), + GetParameter(Attr.IsTop, contentInfo.Top.ToString()), + GetParameter(Attr.IsRecommend, contentInfo.Recommend.ToString()), + GetParameter(Attr.IsHot, contentInfo.Hot.ToString()), + GetParameter(Attr.IsColor, contentInfo.Color.ToString()), + GetParameter(Attr.LinkUrl, contentInfo.LinkUrl), + GetParameter(Attr.AddDate,contentInfo.AddDate) + }; + parameters.AddRange(paras); + + contentInfo.Id = DataProvider.DatabaseApi.ExecuteNonQueryAndReturnId(tableName, Attr.Id, ConnectionString, sqlString, parameters.ToArray()); + + ContentManager.InsertCache(siteInfo, channelInfo, contentInfo); + + return contentInfo.Id; + } + + public void Update(SiteInfo siteInfo, ChannelInfo channelInfo, ContentInfo contentInfo) + { + if (contentInfo == null) return; + + if (siteInfo.IsAutoPageInTextEditor && + contentInfo.ContainsKey(Attr.Content)) + { + contentInfo.Content = ContentUtility.GetAutoPageContent(contentInfo.Content, + siteInfo.AutoPageWordNum); + } + + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + + //出现IsTop与Taxis不同步情况 + if (contentInfo.Top == false && contentInfo.Taxis >= TaxisIsTopStartValue) + { + contentInfo.Taxis = channelInfo.ContentRepository.GetMaxTaxis(contentInfo.ChannelId, false) + 1; + } + else if (contentInfo.Top && contentInfo.Taxis < TaxisIsTopStartValue) + { + contentInfo.Taxis = channelInfo.ContentRepository.GetMaxTaxis(contentInfo.ChannelId, true) + 1; + } + + contentInfo.LastEditDate = DateTime.Now; + + var columnInfoList = + TableColumnManager.GetTableColumnInfoList(tableName, Attr.AllAttributes.Value); + + var sets = new StringBuilder(); + var paras = new List(); + var excludeAttributesNames = new List(Attr.AllAttributes.Value); + foreach (var columnInfo in columnInfoList) + { + excludeAttributesNames.Add(columnInfo.AttributeName); + sets.Append($",{columnInfo.AttributeName} = @{columnInfo.AttributeName}").AppendLine(); + if (columnInfo.DataType == DataType.Integer) + { + paras.Add(GetParameter(columnInfo.AttributeName, + contentInfo.Get(columnInfo.AttributeName))); + } + else if (columnInfo.DataType == DataType.Decimal) + { + paras.Add(GetParameter(columnInfo.AttributeName, + contentInfo.Get(columnInfo.AttributeName))); + } + else if (columnInfo.DataType == DataType.Boolean) + { + paras.Add(GetParameter(columnInfo.AttributeName, + contentInfo.Get(columnInfo.AttributeName))); + } + else if (columnInfo.DataType == DataType.DateTime) + { + paras.Add(GetParameter(columnInfo.AttributeName, + contentInfo.Get(columnInfo.AttributeName))); + } + else + { + paras.Add(GetParameter(columnInfo.AttributeName, + contentInfo.Get(columnInfo.AttributeName, string.Empty))); + } + } + + var sqlString = $@" +UPDATE {tableName} SET +{Attr.ChannelId} = @{Attr.ChannelId}, +{Attr.SiteId} = @{Attr.SiteId}, +{Attr.AddUserName} = @{Attr.AddUserName}, +{Attr.LastEditUserName} = @{Attr.LastEditUserName}, +{Attr.LastEditDate} = @{Attr.LastEditDate}, +{Attr.AdminId} = @{Attr.AdminId}, +{Attr.UserId} = @{Attr.UserId}, +{Attr.Taxis} = @{Attr.Taxis}, +{Attr.GroupNameCollection} = @{Attr.GroupNameCollection}, +{Attr.Tags} = @{Attr.Tags}, +{Attr.SourceId} = @{Attr.SourceId}, +{Attr.ReferenceId} = @{Attr.ReferenceId},"; + + if (contentInfo.CheckedLevel != CheckManager.LevelInt.NotChange) + { + sqlString += $@" +{Attr.IsChecked} = @{Attr.IsChecked}, +{Attr.CheckedLevel} = @{Attr.CheckedLevel},"; + } + + sqlString += $@" +{Attr.Hits} = @{Attr.Hits}, +{Attr.HitsByDay} = @{Attr.HitsByDay}, +{Attr.HitsByWeek} = @{Attr.HitsByWeek}, +{Attr.HitsByMonth} = @{Attr.HitsByMonth}, +{Attr.LastHitsDate} = @{Attr.LastHitsDate}, +{Attr.Downloads} = @{Attr.Downloads}, +{Attr.SettingsXml} = @{Attr.SettingsXml}, +{Attr.Title} = @{Attr.Title}, +{Attr.IsTop} = @{Attr.IsTop}, +{Attr.IsRecommend} = @{Attr.IsRecommend}, +{Attr.IsHot} = @{Attr.IsHot}, +{Attr.IsColor} = @{Attr.IsColor}, +{Attr.LinkUrl} = @{Attr.LinkUrl}, +{Attr.AddDate} = @{Attr.AddDate} +{sets} +WHERE {Attr.Id} = @{Attr.Id}"; + + var parameters = new List + { + GetParameter(Attr.ChannelId, channelInfo.Id), + GetParameter(Attr.SiteId, siteInfo.Id), + GetParameter(Attr.AddUserName, contentInfo.AddUserName), + GetParameter(Attr.LastEditUserName, contentInfo.LastEditUserName), + GetParameter(Attr.LastEditDate, contentInfo.LastEditDate), + GetParameter(Attr.AdminId, contentInfo.AdminId), + GetParameter(Attr.UserId, contentInfo.UserId), + GetParameter(Attr.Taxis, contentInfo.Taxis), + GetParameter(Attr.GroupNameCollection, contentInfo.GroupNameCollection), + GetParameter(Attr.Tags, contentInfo.Tags), + GetParameter(Attr.SourceId, contentInfo.SourceId), + GetParameter(Attr.ReferenceId, contentInfo.ReferenceId), + }; + if (contentInfo.CheckedLevel != CheckManager.LevelInt.NotChange) + { + parameters.Add(GetParameter(Attr.IsChecked, contentInfo.Checked.ToString())); + parameters.Add(GetParameter(Attr.CheckedLevel, contentInfo.CheckedLevel)); + } + + parameters.Add(GetParameter(Attr.Hits, contentInfo.Hits)); + parameters.Add(GetParameter(Attr.HitsByDay, contentInfo.HitsByDay)); + parameters.Add(GetParameter(Attr.HitsByWeek, contentInfo.HitsByWeek)); + parameters.Add(GetParameter(Attr.HitsByMonth, contentInfo.HitsByMonth)); + parameters.Add(GetParameter(Attr.LastHitsDate, contentInfo.LastHitsDate)); + parameters.Add(GetParameter(Attr.Downloads, contentInfo.Downloads)); + parameters.Add(GetParameter(Attr.SettingsXml, contentInfo.SettingsXml)); + parameters.Add(GetParameter(Attr.Title, contentInfo.Title)); + parameters.Add(GetParameter(Attr.IsTop, contentInfo.Top.ToString())); + parameters.Add(GetParameter(Attr.IsRecommend, contentInfo.Recommend.ToString())); + parameters.Add(GetParameter(Attr.IsHot, contentInfo.Hot.ToString())); + parameters.Add(GetParameter(Attr.IsColor, contentInfo.Color.ToString())); + parameters.Add(GetParameter(Attr.LinkUrl, contentInfo.LinkUrl)); + parameters.Add(GetParameter(Attr.AddDate, contentInfo.AddDate)); + + parameters.AddRange(paras); + parameters.Add(GetParameter(Attr.Id, contentInfo.Id)); + + DataProvider.DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters.ToArray()); + + ContentManager.UpdateCache(siteInfo, channelInfo, contentInfo); + } + + + + public int GetCountOfContentAdd(string tableName, int siteId, int channelId, EScopeType scope, DateTime begin, DateTime end, string userName, ETriState checkedState) + { + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + var channelIdList = ChannelManager.GetChannelIdList(channelInfo, scope, string.Empty, string.Empty, string.Empty); + return GetCountOfContentAdd(tableName, siteId, channelIdList, begin, end, userName, checkedState); + } + + public List GetContentIdListChecked(string tableName, int channelId, string orderByFormatString) + { + return GetContentIdListChecked(tableName, channelId, orderByFormatString, string.Empty); + } + + public int GetCountOfContentUpdate(string tableName, int siteId, int channelId, EScopeType scope, DateTime begin, DateTime end, string userName) + { + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + var channelIdList = ChannelManager.GetChannelIdList(channelInfo, scope, string.Empty, string.Empty, string.Empty); + return GetCountOfContentUpdate(tableName, siteId, channelIdList, begin, end, userName); + } + + private int GetCountOfContentUpdate(string tableName, int siteId, List channelIdList, DateTime begin, DateTime end, string userName) + { + string sqlString; + if (string.IsNullOrEmpty(userName)) + { + sqlString = channelIdList.Count == 1 + ? $"SELECT COUNT(Id) AS Num FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelIdList[0]} AND (LastEditDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))}) AND (LastEditDate <> AddDate)" + : $"SELECT COUNT(Id) AS Num FROM {tableName} WHERE SiteId = {siteId} AND ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND (LastEditDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))}) AND (LastEditDate <> AddDate)"; + } + else + { + sqlString = channelIdList.Count == 1 + ? $"SELECT COUNT(Id) AS Num FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelIdList[0]} AND (LastEditDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))}) AND (LastEditDate <> AddDate) AND (AddUserName = '{userName}')" + : $"SELECT COUNT(Id) AS Num FROM {tableName} WHERE SiteId = {siteId} AND ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND (LastEditDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))}) AND (LastEditDate <> AddDate) AND (AddUserName = '{userName}')"; + } + + return DataProvider.DatabaseApi.GetIntResult(sqlString); + } + + public DataSet GetStlDataSourceChecked(List channelIdList, string tableName, int startNum, int totalNum, string orderByString, string whereString, NameValueCollection others) + { + return GetStlDataSourceChecked(tableName, channelIdList, startNum, totalNum, orderByString, whereString, others); + } + + + + public int GetCount(string tableName, string whereString) + { + if (!string.IsNullOrEmpty(whereString)) + { + whereString = whereString.Replace("WHERE ", string.Empty).Replace("where ", string.Empty); + } + whereString = string.IsNullOrEmpty(whereString) ? string.Empty : $"WHERE {whereString}"; + + var sqlString = $"SELECT COUNT(*) FROM {tableName} {whereString}"; + + return DataProvider.DatabaseApi.GetIntResult(sqlString); + } + + public List GetContentCountInfoList(string tableName) + { + List list; + + var sqlString = + $@"SELECT {Attr.SiteId}, {Attr.ChannelId}, {Attr.IsChecked}, {Attr.CheckedLevel}, {Attr.AdminId}, COUNT(*) AS {nameof(ContentCountInfo.Count)} FROM {tableName} WHERE {Attr.ChannelId} > 0 AND {Attr.SourceId} != {SourceManager.Preview} GROUP BY {Attr.SiteId}, {Attr.ChannelId}, {Attr.IsChecked}, {Attr.CheckedLevel}, {Attr.AdminId}"; + + using (var connection = GetConnection()) + { + list = connection.Query(sqlString).ToList(); + } + + return list; + } + + private DataSet GetStlDataSourceChecked(string tableName, List channelIdList, int startNum, int totalNum, string orderByString, string whereString, NameValueCollection others) + { + if (channelIdList == null || channelIdList.Count == 0) + { + return null; + } + var sqlWhereString = channelIdList.Count == 1 ? $"WHERE (ChannelId = {channelIdList[0]} AND IsChecked = '{true}' {whereString})" : $"WHERE (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND IsChecked = '{true}' {whereString})"; + + if (others != null && others.Count > 0) + { + var columnNameList = TableColumnManager.GetTableColumnNameList(tableName); + + foreach (var attributeName in others.AllKeys) + { + if (StringUtils.ContainsIgnoreCase(columnNameList, attributeName)) + { + var value = others.Get(attributeName); + if (!string.IsNullOrEmpty(value)) + { + value = value.Trim(); + if (StringUtils.StartsWithIgnoreCase(value, "not:")) + { + value = value.Substring("not:".Length); + if (value.IndexOf(',') == -1) + { + sqlWhereString += $" AND ({attributeName} <> '{value}')"; + } + else + { + var collection = TranslateUtils.StringCollectionToStringList(value); + foreach (var val in collection) + { + sqlWhereString += $" AND ({attributeName} <> '{val}')"; + } + } + } + else if (StringUtils.StartsWithIgnoreCase(value, "contains:")) + { + value = value.Substring("contains:".Length); + if (value.IndexOf(',') == -1) + { + sqlWhereString += $" AND ({attributeName} LIKE '%{value}%')"; + } + else + { + var builder = new StringBuilder(" AND ("); + var collection = TranslateUtils.StringCollectionToStringList(value); + foreach (var val in collection) + { + builder.Append($" {attributeName} LIKE '%{val}%' OR "); + } + builder.Length -= 3; + + builder.Append(")"); + + sqlWhereString += builder.ToString(); + } + } + else if (StringUtils.StartsWithIgnoreCase(value, "start:")) + { + value = value.Substring("start:".Length); + if (value.IndexOf(',') == -1) + { + sqlWhereString += $" AND ({attributeName} LIKE '{value}%')"; + } + else + { + var builder = new StringBuilder(" AND ("); + var collection = TranslateUtils.StringCollectionToStringList(value); + foreach (var val in collection) + { + builder.Append($" {attributeName} LIKE '{val}%' OR "); + } + builder.Length -= 3; + + builder.Append(")"); + + sqlWhereString += builder.ToString(); + } + } + else if (StringUtils.StartsWithIgnoreCase(value, "end:")) + { + value = value.Substring("end:".Length); + if (value.IndexOf(',') == -1) + { + sqlWhereString += $" AND ({attributeName} LIKE '%{value}')"; + } + else + { + var builder = new StringBuilder(" AND ("); + var collection = TranslateUtils.StringCollectionToStringList(value); + foreach (var val in collection) + { + builder.Append($" {attributeName} LIKE '%{val}' OR "); + } + builder.Length -= 3; + + builder.Append(")"); + + sqlWhereString += builder.ToString(); + } + } + else + { + if (value.IndexOf(',') == -1) + { + sqlWhereString += $" AND ({attributeName} = '{value}')"; + } + else + { + var builder = new StringBuilder(" AND ("); + var collection = TranslateUtils.StringCollectionToStringList(value); + foreach (var val in collection) + { + builder.Append($" {attributeName} = '{val}' OR "); + } + builder.Length -= 3; + + builder.Append(")"); + + sqlWhereString += builder.ToString(); + } + } + } + } + } + } + + return startNum <= 1 ? GetStlDataSourceByContentNumAndWhereString(tableName, totalNum, sqlWhereString, orderByString) : GetStlDataSourceByStartNum(tableName, startNum, totalNum, sqlWhereString, orderByString); + } + + private DataSet GetStlDataSourceByContentNumAndWhereString(string tableName, int totalNum, string whereString, string orderByString) + { + DataSet dataSet = null; + if (!string.IsNullOrEmpty(tableName)) + { + var sqlSelect = DataProvider.DatabaseApi.GetSelectSqlString(tableName, totalNum, MinListColumns, whereString, orderByString); + dataSet = DataProvider.DatabaseApi.ExecuteDataset(ConnectionString, sqlSelect); + } + return dataSet; + } + + private DataSet GetStlDataSourceByStartNum(string tableName, int startNum, int totalNum, string whereString, string orderByString) + { + DataSet dataSet = null; + if (!string.IsNullOrEmpty(tableName)) + { + var sqlSelect = DataProvider.DatabaseApi.GetSqlString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, MinListColumns, whereString, orderByString, startNum - 1, totalNum); + dataSet = DataProvider.DatabaseApi.ExecuteDataset(ConnectionString, sqlSelect); + } + return dataSet; + } + + private int GetCountOfContentAdd(string tableName, int siteId, List channelIdList, DateTime begin, DateTime end, string userName, ETriState checkedState) + { + string sqlString; + if (string.IsNullOrEmpty(userName)) + { + sqlString = channelIdList.Count == 1 + ? $"SELECT COUNT(Id) AS Num FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelIdList[0]} AND (AddDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))})" + : $"SELECT COUNT(Id) AS Num FROM {tableName} WHERE SiteId = {siteId} AND ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND (AddDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))})"; + } + else + { + sqlString = channelIdList.Count == 1 + ? $"SELECT COUNT(Id) AS Num FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelIdList[0]} AND (AddDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))}) AND (AddUserName = '{userName}')" + : $"SELECT COUNT(Id) AS Num FROM {tableName} WHERE SiteId = {siteId} AND ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND (AddDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))}) AND (AddUserName = '{userName}')"; + } + + if (checkedState != ETriState.All) + { + sqlString += $" AND {Attr.IsChecked} = '{ETriStateUtils.GetValue(checkedState)}'"; + } + + return DataProvider.DatabaseApi.GetIntResult(sqlString); + } + + private List GetContentIdListChecked(string tableName, int channelId, int totalNum, string orderByFormatString, string whereString) + { + var channelIdList = new List + { + channelId + }; + return GetContentIdListChecked(tableName, channelIdList, totalNum, orderByFormatString, whereString); + } + + private List GetContentIdListChecked(string tableName, List channelIdList, int totalNum, string orderString, string whereString) + { + var list = new List(); + + if (channelIdList == null || channelIdList.Count == 0) + { + return list; + } + + string sqlString; + + if (totalNum > 0) + { + sqlString = DataProvider.DatabaseApi.GetSqlString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, new List + { + Attr.Id + }, + channelIdList.Count == 1 + ? $"WHERE (ChannelId = {channelIdList[0]} AND IsChecked = '{true}' {whereString})" + : $"WHERE (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND IsChecked = '{true}' {whereString})", orderString, + totalNum); + } + else + { + sqlString = channelIdList.Count == 1 + ? $"SELECT Id FROM {tableName} WHERE (ChannelId = {channelIdList[0]} AND IsChecked = '{true}' {whereString}) {orderString}" + : $"SELECT Id FROM {tableName} WHERE (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND IsChecked = '{true}' {whereString}) {orderString}"; + } + + using (var rdr = DataProvider.DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + { + while (rdr.Read()) + { + var contentId = DataProvider.DatabaseApi.GetInt(rdr, 0); + list.Add(contentId); + } + rdr.Close(); + } + return list; + } + + private List GetContentIdListChecked(string tableName, int channelId, string orderByFormatString, string whereString) + { + return GetContentIdListChecked(tableName, channelId, 0, orderByFormatString, whereString); + } + + public IList<(int, int)> ApiGetContentIdListBySiteId(string tableName, int siteId, ApiContentsParameters parameters, out int totalCount) + { + totalCount = 0; + var retVal = new List<(int, int)>(); + + var whereString = $"WHERE {Attr.SiteId} = {siteId} AND {Attr.ChannelId} > 0 AND {Attr.IsChecked} = '{true}'"; + if (parameters.ChannelIds.Count > 0) + { + whereString += $" AND {Attr.ChannelId} IN ({TranslateUtils.ObjectCollectionToString(parameters.ChannelIds)})"; + } + if (!string.IsNullOrEmpty(parameters.ChannelGroup)) + { + var channelIdList = ChannelManager.GetChannelIdList(siteId, parameters.ChannelGroup); + if (channelIdList.Count > 0) + { + whereString += $" AND {Attr.ChannelId} IN ({TranslateUtils.ObjectCollectionToString(channelIdList)})"; + } + } + if (!string.IsNullOrEmpty(parameters.ContentGroup)) + { + whereString += $" AND ({Attr.GroupNameCollection} = '{parameters.ContentGroup}' OR {SqlUtils.GetInStr(Attr.GroupNameCollection, parameters.ContentGroup + ",")} OR {SqlUtils.GetInStr(Attr.GroupNameCollection, "," + parameters.ContentGroup + ",")} OR {SqlUtils.GetInStr(Attr.GroupNameCollection, "," + parameters.ContentGroup)})"; + } + if (!string.IsNullOrEmpty(parameters.Tag)) + { + whereString += $" AND ({Attr.Tags} = '{parameters.Tag}' OR {SqlUtils.GetInStr(Attr.Tags, parameters.Tag + ",")} OR {SqlUtils.GetInStr(Attr.Tags, "," + parameters.Tag + ",")} OR {SqlUtils.GetInStr(Attr.Tags, "," + parameters.Tag)})"; + } + + var channelInfo = ChannelManager.GetChannelInfo(siteId, siteId); + var orderString = GetOrderString(channelInfo, AttackUtils.FilterSql(parameters.OrderBy)); + var dbArgs = new Dictionary(); + + if (parameters.QueryString != null && parameters.QueryString.Count > 0) + { + var columnNameList = TableColumnManager.GetTableColumnNameList(tableName); + + foreach (var attributeName in parameters.QueryString.Keys) + { + if (!StringUtils.ContainsIgnoreCase(columnNameList, attributeName)) continue; + + var value = parameters.QueryString[attributeName]; + + if (StringUtils.EqualsIgnoreCase(attributeName, Attr.IsChecked) || StringUtils.EqualsIgnoreCase(attributeName, Attr.IsColor) || StringUtils.EqualsIgnoreCase(attributeName, Attr.IsHot) || StringUtils.EqualsIgnoreCase(attributeName, Attr.IsRecommend) || StringUtils.EqualsIgnoreCase(attributeName, Attr.IsTop)) + { + whereString += $" AND {attributeName} = '{TranslateUtils.ToBool(value)}'"; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, Attr.Id) || StringUtils.EqualsIgnoreCase(attributeName, Attr.ReferenceId) || StringUtils.EqualsIgnoreCase(attributeName, Attr.SourceId) || StringUtils.EqualsIgnoreCase(attributeName, Attr.CheckedLevel)) + { + whereString += $" AND {attributeName} = {TranslateUtils.ToInt(value)}"; + } + else if (parameters.Likes.Contains(attributeName)) + { + whereString += $" AND {attributeName} LIKE '%{AttackUtils.FilterSql(value)}%'"; + } + else + { + whereString += $" AND {attributeName} = @{attributeName}"; + dbArgs.Add(attributeName, value); + } + } + } + + totalCount = DataProvider.DatabaseApi.GetPageTotalCount(tableName, whereString, dbArgs); + if (totalCount > 0 && parameters.Skip < totalCount) + { + var sqlString = DataProvider.DatabaseApi.GetSqlString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, MinListColumns, whereString, orderString, parameters.Skip, parameters.Top); + + using (var connection = GetConnection()) + { + retVal = connection.Query(sqlString, dbArgs).Select(o => (o.ChannelId, o.Id)).ToList(); + } + } + + return retVal; + } + + public IList<(int, int)> ApiGetContentIdListByChannelId(string tableName, int siteId, int channelId, int top, int skip, string like, string orderBy, NameValueCollection queryString, out int totalCount) + { + var retVal = new List<(int, int)>(); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + var channelIdList = ChannelManager.GetChannelIdList(channelInfo, EScopeType.All, string.Empty, string.Empty, string.Empty); + var whereString = $"WHERE {Attr.SiteId} = {siteId} AND {Attr.ChannelId} IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND {Attr.IsChecked} = '{true}'"; + + var likeList = TranslateUtils.StringCollectionToStringList(StringUtils.TrimAndToLower(like)); + var orderString = GetOrderString(channelInfo, AttackUtils.FilterSql(orderBy)); + var dbArgs = new Dictionary(); + + if (queryString != null && queryString.Count > 0) + { + var columnNameList = TableColumnManager.GetTableColumnNameList(tableName); + + foreach (string attributeName in queryString) + { + if (!StringUtils.ContainsIgnoreCase(columnNameList, attributeName)) continue; + + var value = queryString[attributeName]; + + if (StringUtils.EqualsIgnoreCase(attributeName, Attr.IsChecked) || StringUtils.EqualsIgnoreCase(attributeName, Attr.IsColor) || StringUtils.EqualsIgnoreCase(attributeName, Attr.IsHot) || StringUtils.EqualsIgnoreCase(attributeName, Attr.IsRecommend) || StringUtils.EqualsIgnoreCase(attributeName, Attr.IsTop)) + { + whereString += $" AND {attributeName} = '{TranslateUtils.ToBool(value)}'"; + } + else if (StringUtils.EqualsIgnoreCase(attributeName, Attr.Id) || StringUtils.EqualsIgnoreCase(attributeName, Attr.ReferenceId) || StringUtils.EqualsIgnoreCase(attributeName, Attr.SourceId) || StringUtils.EqualsIgnoreCase(attributeName, Attr.CheckedLevel)) + { + whereString += $" AND {attributeName} = {TranslateUtils.ToInt(value)}"; + } + else if (likeList.Contains(attributeName)) + { + whereString += $" AND {attributeName} LIKE '%{AttackUtils.FilterSql(value)}%'"; + } + else + { + whereString += $" AND {attributeName} = @{attributeName}"; + dbArgs.Add(attributeName, value); + } + } + } + + totalCount = DataProvider.DatabaseApi.GetPageTotalCount(tableName, whereString, dbArgs); + if (totalCount > 0 && skip < totalCount) + { + var sqlString = DataProvider.DatabaseApi.GetSqlString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, MinListColumns, whereString, orderString, skip, top); + + using (var connection = GetConnection()) + { + retVal = connection.Query(sqlString, dbArgs).Select(o => (o.ChannelId, o.Id)).ToList(); + } + } + + return retVal; + } + + #region Table + + public string GetSelectCommandByHitsAnalysis(string tableName, int siteId) + { + var orderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByTaxisDesc); + + var whereString = new StringBuilder(); + whereString.Append($"AND IsChecked = '{true}' AND SiteId = {siteId} AND Hits > 0"); + whereString.Append(orderByString); + + return DataProvider.DatabaseApi.GetSelectSqlString(tableName, whereString.ToString()); + } + + public string GetSqlStringOfAdminExcludeRecycle(string tableName, int siteId, DateTime begin, DateTime end) + { + var sqlString = $@"select userName,SUM(addCount) as addCount, SUM(updateCount) as updateCount from( +SELECT AddUserName as userName, Count(AddUserName) as addCount, 0 as updateCount FROM {tableName} +INNER JOIN {DataProvider.Administrator.TableName} ON AddUserName = {DataProvider.Administrator.TableName}.UserName +WHERE {tableName}.SiteId = {siteId} AND (({tableName}.ChannelId > 0)) +AND LastEditDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))} +GROUP BY AddUserName +Union +SELECT LastEditUserName as userName,0 as addCount, Count(LastEditUserName) as updateCount FROM {tableName} +INNER JOIN {DataProvider.Administrator.TableName} ON LastEditUserName = {DataProvider.Administrator.TableName}.UserName +WHERE {tableName}.SiteId = {siteId} AND (({tableName}.ChannelId > 0)) +AND LastEditDate BETWEEN {SqlUtils.GetComparableDate(begin)} AND {SqlUtils.GetComparableDate(end.AddDays(1))} +AND LastEditDate != AddDate +GROUP BY LastEditUserName +) as tmp +group by tmp.userName"; + + + return sqlString; + } + + public string GetStlWhereString(int siteId, string group, string groupNot, string tags, bool isTopExists, bool isTop, string where) + { + var whereStringBuilder = new StringBuilder(); + + if (isTopExists) + { + whereStringBuilder.Append($" AND IsTop = '{isTop}' "); + } + + if (!string.IsNullOrEmpty(group)) + { + group = group.Trim().Trim(','); + var groupArr = group.Split(','); + if (groupArr.Length > 0) + { + whereStringBuilder.Append(" AND ("); + foreach (var theGroup in groupArr) + { + whereStringBuilder.Append( + $" ({Attr.GroupNameCollection} = '{theGroup.Trim()}' OR {SqlUtils.GetInStr(Attr.GroupNameCollection, theGroup.Trim() + ",")} OR {SqlUtils.GetInStr(Attr.GroupNameCollection, "," + theGroup.Trim() + ",")} OR {SqlUtils.GetInStr(Attr.GroupNameCollection, "," + theGroup.Trim())}) OR "); + } + if (groupArr.Length > 0) + { + whereStringBuilder.Length = whereStringBuilder.Length - 3; + } + whereStringBuilder.Append(") "); + } + } + + if (!string.IsNullOrEmpty(groupNot)) + { + groupNot = groupNot.Trim().Trim(','); + var groupNotArr = groupNot.Split(','); + if (groupNotArr.Length > 0) + { + whereStringBuilder.Append(" AND ("); + foreach (var theGroupNot in groupNotArr) + { + whereStringBuilder.Append( + $" ({Attr.GroupNameCollection} <> '{theGroupNot.Trim()}' AND {SqlUtils.GetNotInStr(Attr.GroupNameCollection, theGroupNot.Trim() + ",")} AND {SqlUtils.GetNotInStr(Attr.GroupNameCollection, "," + theGroupNot.Trim() + ",")} AND {SqlUtils.GetNotInStr(Attr.GroupNameCollection, "," + theGroupNot.Trim())}) AND "); + } + if (groupNotArr.Length > 0) + { + whereStringBuilder.Length = whereStringBuilder.Length - 4; + } + whereStringBuilder.Append(") "); + } + } + + if (!string.IsNullOrEmpty(tags)) + { + var tagCollection = TagUtils.ParseTagsString(tags); + var contentIdList = DataProvider.Tag.GetContentIdListByTagCollection(tagCollection, siteId); + if (contentIdList.Count > 0) + { + var inString = TranslateUtils.ToSqlInStringWithoutQuote(contentIdList.ToList()); + whereStringBuilder.Append($" AND (Id IN ({inString}))"); + } + } + + if (!string.IsNullOrEmpty(where)) + { + whereStringBuilder.Append($" AND ({where}) "); + } + + return whereStringBuilder.ToString(); + } + + public string GetWhereStringByStlSearch(bool isAllSites, string siteName, string siteDir, string siteIds, string channelIndex, string channelName, string channelIds, string type, string word, string dateAttribute, string dateFrom, string dateTo, string since, int siteId, List excludeAttributes, NameValueCollection form) + { + var whereBuilder = new StringBuilder(); + + SiteInfo siteInfo = null; + if (!string.IsNullOrEmpty(siteName)) + { + siteInfo = SiteManager.GetSiteInfoBySiteName(siteName); + } + else if (!string.IsNullOrEmpty(siteDir)) + { + siteInfo = SiteManager.GetSiteInfoByDirectory(siteDir); + } + if (siteInfo == null) + { + siteInfo = SiteManager.GetSiteInfo(siteId); + } + + var channelId = ChannelManager.GetChannelId(siteId, siteId, channelIndex, channelName); + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + + if (isAllSites) + { + whereBuilder.Append("(SiteId > 0) "); + } + else if (!string.IsNullOrEmpty(siteIds)) + { + whereBuilder.Append($"(SiteId IN ({TranslateUtils.ToSqlInStringWithoutQuote(TranslateUtils.StringCollectionToIntList(siteIds))})) "); + } + else + { + whereBuilder.Append($"(SiteId = {siteInfo.Id}) "); + } + + if (!string.IsNullOrEmpty(channelIds)) + { + whereBuilder.Append(" AND "); + var channelIdList = new List(); + foreach (var theChannelId in TranslateUtils.StringCollectionToIntList(channelIds)) + { + var theSiteId = DataProvider.Channel.GetSiteId(theChannelId); + channelIdList.AddRange( + ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(theSiteId, theChannelId), + EScopeType.All, string.Empty, string.Empty, string.Empty)); + } + whereBuilder.Append(channelIdList.Count == 1 + ? $"(ChannelId = {channelIdList[0]}) " + : $"(ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)})) "); + } + else if (channelId != siteId) + { + whereBuilder.Append(" AND "); + + var theSiteId = DataProvider.Channel.GetSiteId(channelId); + var channelIdList = ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(theSiteId, channelId), + EScopeType.All, string.Empty, string.Empty, string.Empty); + + whereBuilder.Append(channelIdList.Count == 1 + ? $"(ChannelId = {channelIdList[0]}) " + : $"(ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)})) "); + } + + var typeList = new List(); + if (string.IsNullOrEmpty(type)) + { + typeList.Add(Attr.Title); + } + else + { + typeList = TranslateUtils.StringCollectionToStringList(type); + } + + if (!string.IsNullOrEmpty(word)) + { + whereBuilder.Append(" AND ("); + foreach (var attributeName in typeList) + { + whereBuilder.Append($"[{attributeName}] LIKE '%{AttackUtils.FilterSql(word)}%' OR "); + } + whereBuilder.Length = whereBuilder.Length - 3; + whereBuilder.Append(")"); + } + + if (string.IsNullOrEmpty(dateAttribute)) + { + dateAttribute = Attr.AddDate; + } + + if (!string.IsNullOrEmpty(dateFrom)) + { + whereBuilder.Append(" AND "); + whereBuilder.Append($" {dateAttribute} >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))} "); + } + if (!string.IsNullOrEmpty(dateTo)) + { + whereBuilder.Append(" AND "); + whereBuilder.Append($" {dateAttribute} <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo))} "); + } + if (!string.IsNullOrEmpty(since)) + { + var sinceDate = DateTime.Now.AddHours(-DateUtils.GetSinceHours(since)); + whereBuilder.Append($" AND {dateAttribute} BETWEEN {SqlUtils.GetComparableDateTime(sinceDate)} AND {SqlUtils.GetComparableNow()} "); + } + + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + //var styleInfoList = RelatedIdentities.GetTableStyleInfoList(siteInfo, channelInfo.Id); + + foreach (string key in form.Keys) + { + if (excludeAttributes.Contains(key.ToLower())) continue; + if (string.IsNullOrEmpty(form[key])) continue; + + var value = StringUtils.Trim(form[key]); + if (string.IsNullOrEmpty(value)) continue; + + var columnInfo = TableColumnManager.GetTableColumnInfo(tableName, key); + + if (columnInfo != null && (columnInfo.DataType == DataType.VarChar || columnInfo.DataType == DataType.Text)) + { + whereBuilder.Append(" AND "); + whereBuilder.Append($"({key} LIKE '%{value}%')"); + } + //else + //{ + // foreach (var tableStyleInfo in styleInfoList) + // { + // if (StringUtils.EqualsIgnoreCase(tableStyleInfo.AttributeName, key)) + // { + // whereBuilder.Append(" AND "); + // whereBuilder.Append($"({Attr.SettingsXml} LIKE '%{key}={value}%')"); + // break; + // } + // } + //} + } + + return whereBuilder.ToString(); + } + + public string GetSqlString(string tableName, int siteId, int channelId, bool isSystemAdministrator, List owningChannelIdList, string searchType, string keyword, string dateFrom, string dateTo, bool isSearchChildren, ETriState checkedState, bool isTrashContent) + { + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + var channelIdList = ChannelManager.GetChannelIdList(channelInfo, + isSearchChildren ? EScopeType.All : EScopeType.Self, string.Empty, string.Empty, channelInfo.ContentModelPluginId); + + var list = new List(); + if (isSystemAdministrator) + { + list = channelIdList; + } + else + { + foreach (var theChannelId in channelIdList) + { + if (owningChannelIdList.Contains(theChannelId)) + { + list.Add(theChannelId); + } + } + } + + return GetSqlStringByCondition(tableName, siteId, list, searchType, keyword, dateFrom, dateTo, checkedState, isTrashContent); + } + + public string GetSqlStringByContentGroup(string tableName, string contentGroupName, int siteId) + { + contentGroupName = AttackUtils.FilterSql(contentGroupName); + var sqlString = + $"SELECT * FROM {tableName} WHERE SiteId = {siteId} AND ChannelId > 0 AND (GroupNameCollection LIKE '{contentGroupName},%' OR GroupNameCollection LIKE '%,{contentGroupName}' OR GroupNameCollection LIKE '%,{contentGroupName},%' OR GroupNameCollection='{contentGroupName}')"; + return sqlString; + } + + public string GetStlSqlStringChecked(List channelIdList, string tableName, int siteId, int channelId, int startNum, int totalNum, string orderByString, string whereString, EScopeType scopeType, string groupChannel, string groupChannelNot) + { + string sqlWhereString; + + if (siteId == channelId && scopeType == EScopeType.All && string.IsNullOrEmpty(groupChannel) && string.IsNullOrEmpty(groupChannelNot)) + { + sqlWhereString = + $"WHERE (SiteId = {siteId} AND ChannelId > 0 AND IsChecked = '{true}' {whereString})"; + } + else + { + if (channelIdList == null || channelIdList.Count == 0) + { + return string.Empty; + } + sqlWhereString = channelIdList.Count == 1 ? $"WHERE (ChannelId = {channelIdList[0]} AND IsChecked = '{true}' {whereString})" : $"WHERE (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND IsChecked = '{true}' {whereString})"; + } + + if (!string.IsNullOrEmpty(tableName)) + { + //return DatabaseApi.GetSelectSqlString(tableName, startNum, totalNum, MinListColumns, sqlWhereString, orderByString); + return DataProvider.DatabaseApi.GetSqlString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, MinListColumns, sqlWhereString, orderByString, startNum - 1, totalNum); + } + return string.Empty; + } + + public string GetStlSqlStringCheckedBySearch(string tableName, int startNum, int totalNum, string orderByString, string whereString) + { + var sqlWhereString = + $"WHERE (ChannelId > 0 AND IsChecked = '{true}' {whereString})"; + + if (!string.IsNullOrEmpty(tableName)) + { + //return DatabaseApi.GetSelectSqlString(tableName, startNum, totalNum, TranslateUtils.ObjectCollectionToString(Attr.AllAttributes.Value), sqlWhereString, orderByString); + return DataProvider.DatabaseApi.GetSqlString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, Attr.AllAttributes.Value, sqlWhereString, orderByString, startNum - 1, totalNum); + } + return string.Empty; + } + + public string GetStlWhereString(int siteId, string group, string groupNot, string tags, bool isImageExists, bool isImage, bool isVideoExists, bool isVideo, bool isFileExists, bool isFile, bool isTopExists, bool isTop, bool isRecommendExists, bool isRecommend, bool isHotExists, bool isHot, bool isColorExists, bool isColor, string where) + { + var whereBuilder = new StringBuilder(); + whereBuilder.Append($" AND SiteId = {siteId} "); + + if (isImageExists) + { + whereBuilder.Append(isImage + ? $" AND {Attr.ImageUrl} <> '' " + : $" AND {Attr.ImageUrl} = '' "); + } + + if (isVideoExists) + { + whereBuilder.Append(isVideo + ? $" AND {Attr.VideoUrl} <> '' " + : $" AND {Attr.VideoUrl} = '' "); + } + + if (isFileExists) + { + whereBuilder.Append(isFile + ? $" AND {Attr.FileUrl} <> '' " + : $" AND {Attr.FileUrl} = '' "); + } + + if (isTopExists) + { + whereBuilder.Append($" AND {Attr.IsTop} = '{isTop}' "); + } + + if (isRecommendExists) + { + whereBuilder.Append($" AND {Attr.IsRecommend} = '{isRecommend}' "); + } + + if (isHotExists) + { + whereBuilder.Append($" AND {Attr.IsHot} = '{isHot}' "); + } + + if (isColorExists) + { + whereBuilder.Append($" AND {Attr.IsColor} = '{isColor}' "); + } + + if (!string.IsNullOrEmpty(group)) + { + group = group.Trim().Trim(','); + var groupArr = group.Split(','); + if (groupArr != null && groupArr.Length > 0) + { + whereBuilder.Append(" AND ("); + foreach (var theGroup in groupArr) + { + var trimGroup = theGroup.Trim(); + + whereBuilder.Append( + $" ({Attr.GroupNameCollection} = '{trimGroup}' OR {SqlUtils.GetInStr(Attr.GroupNameCollection, trimGroup + ",")} OR {SqlUtils.GetInStr(Attr.GroupNameCollection, "," + trimGroup + ",")} OR {SqlUtils.GetInStr(Attr.GroupNameCollection, "," + trimGroup)}) OR "); + } + if (groupArr.Length > 0) + { + whereBuilder.Length = whereBuilder.Length - 3; + } + whereBuilder.Append(") "); + } + } + + if (!string.IsNullOrEmpty(groupNot)) + { + groupNot = groupNot.Trim().Trim(','); + var groupNotArr = groupNot.Split(','); + if (groupNotArr != null && groupNotArr.Length > 0) + { + whereBuilder.Append(" AND ("); + foreach (var theGroupNot in groupNotArr) + { + var trimGroup = theGroupNot.Trim(); + + whereBuilder.Append( + $" ({Attr.GroupNameCollection} <> '{trimGroup}' AND {SqlUtils.GetNotInStr(Attr.GroupNameCollection, trimGroup + ",")} AND {SqlUtils.GetNotInStr(Attr.GroupNameCollection, "," + trimGroup + ",")} AND {SqlUtils.GetNotInStr(Attr.GroupNameCollection, "," + trimGroup)}) AND "); + } + if (groupNotArr.Length > 0) + { + whereBuilder.Length = whereBuilder.Length - 4; + } + whereBuilder.Append(") "); + } + } + + if (!string.IsNullOrEmpty(tags)) + { + var tagCollection = TagUtils.ParseTagsString(tags); + var contentIdArrayList = DataProvider.Tag.GetContentIdListByTagCollection(tagCollection, siteId); + if (contentIdArrayList.Count > 0) + { + whereBuilder.Append( + $" AND (ID IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdArrayList.ToList())}))"); + } + } + + if (!string.IsNullOrEmpty(where)) + { + whereBuilder.Append($" AND ({where}) "); + } + + return whereBuilder.ToString(); + } + + public string GetStlWhereStringBySearch(string group, string groupNot, bool isImageExists, bool isImage, bool isVideoExists, bool isVideo, bool isFileExists, bool isFile, bool isTopExists, bool isTop, bool isRecommendExists, bool isRecommend, bool isHotExists, bool isHot, bool isColorExists, bool isColor, string where) + { + var whereBuilder = new StringBuilder(); + + if (isImageExists) + { + whereBuilder.Append(isImage + ? $" AND {Attr.ImageUrl} <> '' " + : $" AND {Attr.ImageUrl} = '' "); + } + + if (isVideoExists) + { + whereBuilder.Append(isVideo + ? $" AND {Attr.VideoUrl} <> '' " + : $" AND {Attr.VideoUrl} = '' "); + } + + if (isFileExists) + { + whereBuilder.Append(isFile + ? $" AND {Attr.FileUrl} <> '' " + : $" AND {Attr.FileUrl} = '' "); + } + + if (isTopExists) + { + whereBuilder.Append($" AND {Attr.IsTop} = '{isTop}' "); + } + + if (isRecommendExists) + { + whereBuilder.Append($" AND {Attr.IsRecommend} = '{isRecommend}' "); + } + + if (isHotExists) + { + whereBuilder.Append($" AND {Attr.IsHot} = '{isHot}' "); + } + + if (isColorExists) + { + whereBuilder.Append($" AND {Attr.IsColor} = '{isColor}' "); + } + + if (!string.IsNullOrEmpty(group)) + { + group = group.Trim().Trim(','); + var groupArr = group.Split(','); + if (groupArr != null && groupArr.Length > 0) + { + whereBuilder.Append(" AND ("); + foreach (var theGroup in groupArr) + { + var trimGroup = theGroup.Trim(); + + whereBuilder.Append( + $" ({Attr.GroupNameCollection} = '{trimGroup}' OR {SqlUtils.GetInStr(Attr.GroupNameCollection, trimGroup + ",")} OR {SqlUtils.GetInStr(Attr.GroupNameCollection, "," + trimGroup + ",")} OR {SqlUtils.GetInStr(Attr.GroupNameCollection, "," + trimGroup)}) OR "); + } + if (groupArr.Length > 0) + { + whereBuilder.Length = whereBuilder.Length - 3; + } + whereBuilder.Append(") "); + } + } + + if (!string.IsNullOrEmpty(groupNot)) + { + groupNot = groupNot.Trim().Trim(','); + var groupNotArr = groupNot.Split(','); + if (groupNotArr != null && groupNotArr.Length > 0) + { + whereBuilder.Append(" AND ("); + foreach (var theGroupNot in groupNotArr) + { + var trimGroup = theGroupNot.Trim(); + + whereBuilder.Append( + $" ({Attr.GroupNameCollection} <> '{trimGroup}' AND {SqlUtils.GetNotInStr(Attr.GroupNameCollection, trimGroup + ",")} AND {SqlUtils.GetNotInStr(Attr.GroupNameCollection, "," + trimGroup + ",")} AND {SqlUtils.GetNotInStr(Attr.GroupNameCollection, "," + trimGroup)}) AND "); + } + if (groupNotArr.Length > 0) + { + whereBuilder.Length = whereBuilder.Length - 4; + } + whereBuilder.Append(") "); + } + } + + if (!string.IsNullOrEmpty(where)) + { + whereBuilder.Append($" AND ({where}) "); + } + + return whereBuilder.ToString(); + } + + private string GetSqlStringByCondition(string tableName, int siteId, List channelIdList, string searchType, string keyword, string dateFrom, string dateTo, ETriState checkedState, bool isTrashContent) + { + return GetSqlStringByCondition(tableName, siteId, channelIdList, searchType, keyword, dateFrom, dateTo, checkedState, isTrashContent, false, string.Empty); + } + + private string GetSqlStringByCondition(string tableName, int siteId, List channelIdList, string searchType, string keyword, string dateFrom, string dateTo, ETriState checkedState, bool isTrashContent, bool isWritingOnly, string userNameOnly) + { + if (channelIdList == null || channelIdList.Count == 0) + { + return null; + } + + var orderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByTaxisDesc); + + var dateString = string.Empty; + if (!string.IsNullOrEmpty(dateFrom)) + { + dateString = $" AND AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))} "; + } + if (!string.IsNullOrEmpty(dateTo)) + { + dateString += $" AND AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo).AddDays(1))} "; + } + var whereString = new StringBuilder($"WHERE {nameof(Attr.SourceId)} != {SourceManager.Preview} AND "); + + if (isTrashContent) + { + for (var i = 0; i < channelIdList.Count; i++) + { + var theChannelId = channelIdList[i]; + channelIdList[i] = -theChannelId; + } + } + + whereString.Append(channelIdList.Count == 1 + ? $"SiteId = {siteId} AND (ChannelId = {channelIdList[0]}) " + : $"SiteId = {siteId} AND (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)})) "); + + if (StringUtils.EqualsIgnoreCase(searchType, Attr.IsTop) || StringUtils.EqualsIgnoreCase(searchType, Attr.IsRecommend) || StringUtils.EqualsIgnoreCase(searchType, Attr.IsColor) || StringUtils.EqualsIgnoreCase(searchType, Attr.IsHot)) + { + if (!string.IsNullOrEmpty(keyword)) + { + whereString.Append($"AND ({Attr.Title} LIKE '%{keyword}%') "); + } + whereString.Append($" AND {searchType} = '{true}'"); + } + else if (!string.IsNullOrEmpty(keyword)) + { + var columnNameList = TableColumnManager.GetTableColumnNameList(tableName); + + if (StringUtils.ContainsIgnoreCase(columnNameList, searchType)) + { + whereString.Append($"AND ({searchType} LIKE '%{keyword}%') "); + } + } + + whereString.Append(dateString); + + if (checkedState == ETriState.True) + { + whereString.Append("AND IsChecked='True' "); + } + else if (checkedState == ETriState.False) + { + whereString.Append("AND IsChecked='False' "); + } + + if (!string.IsNullOrEmpty(userNameOnly)) + { + whereString.Append($" AND {Attr.AddUserName} = '{userNameOnly}' "); + } + if (isWritingOnly) + { + whereString.Append($" AND {Attr.UserId} > 0 "); + } + + whereString.Append(" ").Append(orderByString); + + return DataProvider.DatabaseApi.GetSelectSqlString(tableName, whereString.ToString()); + } + + public string GetPagerWhereSqlString(SiteInfo siteInfo, ChannelInfo channelInfo, string searchType, string keyword, string dateFrom, string dateTo, int checkLevel, bool isCheckOnly, bool isSelfOnly, bool isTrashOnly, bool isWritingOnly, int? onlyAdminId, PermissionsImpl adminPermissions, List allAttributeNameList) + { + var isAllChannels = false; + var searchChannelIdList = new List(); + + if (isSelfOnly) + { + searchChannelIdList = new List + { + channelInfo.Id + }; + } + else + { + var channelIdList = ChannelManager.GetChannelIdList(channelInfo, EScopeType.All, string.Empty, string.Empty, channelInfo.ContentModelPluginId); + + if (adminPermissions.IsSystemAdministrator) + { + if (channelInfo.Id == siteInfo.Id) + { + isAllChannels = true; + } + + searchChannelIdList = channelIdList; + } + else + { + foreach (var theChannelId in channelIdList) + { + if (adminPermissions.ChannelIdList.Contains(theChannelId)) + { + searchChannelIdList.Add(theChannelId); + } + } + } + } + if (isTrashOnly) + { + searchChannelIdList = searchChannelIdList.Select(i => -i).ToList(); + } + + var whereList = new List + { + $"{nameof(Attr.SiteId)} = {siteInfo.Id}", + $"{nameof(Attr.SourceId)} != {SourceManager.Preview}" + }; + + if (!string.IsNullOrEmpty(dateFrom)) + { + whereList.Add($"{nameof(Attr.AddDate)} >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))}"); + } + if (!string.IsNullOrEmpty(dateTo)) + { + whereList.Add($"{nameof(Attr.AddDate)} <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo).AddDays(1))}"); + } + + if (isAllChannels) + { + whereList.Add(isTrashOnly + ? $"{nameof(Attr.ChannelId)} < 0" + : $"{nameof(Attr.ChannelId)} > 0"); + } + else if (searchChannelIdList.Count == 0) + { + whereList.Add($"{nameof(Attr.ChannelId)} = 0"); + } + else if (searchChannelIdList.Count == 1) + { + whereList.Add($"{nameof(Attr.ChannelId)} = {channelInfo.Id}"); + } + else + { + whereList.Add($"{nameof(Attr.ChannelId)} IN ({TranslateUtils.ToSqlInStringWithoutQuote(searchChannelIdList)})"); + } + + if (StringUtils.EqualsIgnoreCase(searchType, Attr.IsTop) || StringUtils.EqualsIgnoreCase(searchType, Attr.IsRecommend) || StringUtils.EqualsIgnoreCase(searchType, Attr.IsColor) || StringUtils.EqualsIgnoreCase(searchType, Attr.IsHot)) + { + if (!string.IsNullOrEmpty(keyword)) + { + whereList.Add($"{Attr.Title} LIKE '%{keyword}%'"); + } + whereList.Add($"{searchType} = '{true}'"); + } + else if (!string.IsNullOrEmpty(keyword)) + { + if (StringUtils.ContainsIgnoreCase(allAttributeNameList, searchType)) + { + whereList.Add($"{searchType} LIKE '%{keyword}%'"); + } + //whereList.Add(allLowerAttributeNameList.Contains(searchType.ToLower()) + // ? $"{searchType} LIKE '%{keyword}%'" + // : $"{nameof(Attr.SettingsXml)} LIKE '%{searchType}={keyword}%'"); + } + + if (isCheckOnly) + { + whereList.Add(checkLevel == CheckManager.LevelInt.All + ? $"{nameof(Attr.IsChecked)} = '{false}'" + : $"{nameof(Attr.IsChecked)} = '{false}' AND {nameof(Attr.CheckedLevel)} = {checkLevel}"); + } + else + { + if (checkLevel != CheckManager.LevelInt.All) + { + whereList.Add(checkLevel == siteInfo.CheckContentLevel + ? $"{nameof(Attr.IsChecked)} = '{true}'" + : $"{nameof(Attr.IsChecked)} = '{false}' AND {nameof(Attr.CheckedLevel)} = {checkLevel}"); + } + } + + if (onlyAdminId.HasValue) + { + whereList.Add($"{nameof(Attr.AdminId)} = {onlyAdminId.Value}"); + } + + if (isWritingOnly) + { + whereList.Add($"{nameof(Attr.UserId)} > 0"); + } + + return $"WHERE {string.Join(" AND ", whereList)}"; + } + + public string GetPagerWhereSqlString(int channelId, ETriState checkedState, string userNameOnly) + { + var whereString = new StringBuilder(); + whereString.Append($"WHERE {nameof(Attr.ChannelId)} = {channelId} AND {nameof(Attr.SourceId)} != {SourceManager.Preview} "); + + if (checkedState == ETriState.True) + { + whereString.Append($"AND IsChecked='{true}' "); + } + else if (checkedState == ETriState.False) + { + whereString.Append($"AND IsChecked='{false}'"); + } + + if (!string.IsNullOrEmpty(userNameOnly)) + { + whereString.Append($" AND AddUserName = '{userNameOnly}' "); + } + + return whereString.ToString(); + } + + #endregion + + #region Cache + + public string GetCacheWhereString(SiteInfo siteInfo, ChannelInfo channelInfo, int? onlyAdminId) + { + var whereString = $"WHERE {Attr.SiteId} = {siteInfo.Id} AND {Attr.ChannelId} = {channelInfo.Id} AND {nameof(Attr.SourceId)} != {SourceManager.Preview}"; + if (onlyAdminId.HasValue) + { + whereString += $" AND {nameof(Attr.AdminId)} = {onlyAdminId.Value}"; + } + + return whereString; + } + + public string GetOrderString(ChannelInfo channelInfo, string orderBy) + { + return ETaxisTypeUtils.GetContentOrderByString(ETaxisTypeUtils.GetEnumType(channelInfo.DefaultTaxisType), orderBy); + } + + public List GetContentInfoList(string tableName, string whereString, string orderString, int offset, int limit) + { + var list = new List(); + + var sqlString = DataProvider.DatabaseApi.GetSqlString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, null, whereString, orderString, offset, limit); + + using (var rdr = DataProvider.DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + { + while (rdr.Read()) + { + var dict = TranslateUtils.ToDictionary(rdr); + if (dict != null) + { + var contentInfo = new ContentInfo(dict); + list.Add(contentInfo); + } + } + rdr.Close(); + } + + return list; + } + + + + public List GetCacheContentIdList(string tableName, string whereString, string orderString, int offset, int limit) + { + var list = new List(); + + var sqlString = DataProvider.DatabaseApi.GetSqlString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, MinListColumns, whereString, orderString, offset, limit); + + using (var rdr = DataProvider.DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + { + while (rdr.Read()) + { + var contentId = DataProvider.DatabaseApi.GetInt(rdr, 0); + + list.Add(contentId); + } + rdr.Close(); + } + + return list; + } + + public ContentInfo GetCacheContentInfo(string tableName, int channelId, int contentId) + { + if (string.IsNullOrEmpty(tableName) || contentId <= 0) return null; + + ContentInfo contentInfo = null; + + var sqlWhere = $"WHERE {Attr.ChannelId} = {channelId} AND {Attr.Id} = {contentId}"; + var sqlSelect = DataProvider.DatabaseApi.GetSelectSqlString(tableName, sqlWhere); + + using (var rdr = DataProvider.DatabaseApi.ExecuteReader(ConnectionString, sqlSelect)) + { + if (rdr.Read()) + { + var dict = TranslateUtils.ToDictionary(rdr); + if (dict != null) + { + contentInfo = new ContentInfo(dict); + } + } + rdr.Close(); + } + + return contentInfo; + } + + #endregion + } +} diff --git a/net452/SiteServer.CMS/Database/Repositories/Contents/ContentTableRepository.Delete.cs b/net452/SiteServer.CMS/Database/Repositories/Contents/ContentTableRepository.Delete.cs new file mode 100644 index 000000000..8570f2f02 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/Contents/ContentTableRepository.Delete.cs @@ -0,0 +1,159 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using Attr = SiteServer.CMS.Database.Attributes.ContentAttribute; + +namespace SiteServer.CMS.Database.Repositories.Contents +{ + public partial class ContentTableRepository + { + public void Delete(int siteId, int contentId) + { + if (siteId <= 0 || contentId <= 0) return; + + Delete(Q + .Where(Attr.SiteId, siteId) + .Where(Attr.Id, contentId) + ); + } + + private void DeleteReferenceContents(int siteId, int channelId, IList contentIdList) + { + var deleteNum = 0; + + if (contentIdList != null && contentIdList.Count > 0) + { + TagUtils.RemoveTags(siteId, contentIdList); + + //var sqlString = + // $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND {ContentAttribute.ReferenceId} > 0 AND Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; + + //deleteNum = ExecuteNonQuery(sqlString); + + deleteNum = Delete(Q + .Where(Attr.SiteId, siteId) + .Where(Attr.ReferenceId, ">", 0) + .WhereIn(Attr.Id, contentIdList)); + } + + if (deleteNum <= 0) return; + + ContentManager.RemoveCache(TableName, channelId); + } + + //public void DeleteContentsByTrash() + //{ + // //var sqlString = + // // $"SELECT Id FROM {tableName} WHERE SiteId = {siteId} AND ChannelId < 0"; + // //return DatabaseApi.GetIntList(sqlString); + + // var contentIdList = GetValueList(Q + // .Select(Attr.Id) + // .Where(Attr.SiteId, SiteId) + // .Where(Attr.ChannelId, "<", 0) + // ); + // TagUtils.RemoveTags(SiteId, contentIdList); + + // //var sqlString = + // // $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND ChannelId < 0"; + // //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + // //ContentManager.RemoveCache(tableName, channelId); + + // DeleteAll(Q + // .Where(Attr.SiteId, SiteId) + // .Where(Attr.ChannelId, "<", 0) + // ); + + // ContentManager.RemoveCacheBySiteId(TableName, SiteId); + //} + + //private void DeleteContents(int siteId, int channelId, IList contentIdList) + //{ + // var deleteNum = 0; + + // if (contentIdList != null && contentIdList.Count > 0) + // { + // TagUtils.RemoveTags(siteId, contentIdList); + + // //var sqlString = + // // $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; + // //deleteNum = DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + // deleteNum = DeleteAll(Q + // .Where(Attr.SiteId, siteId) + // .WhereIn(Attr.Id, contentIdList) + // ); + // } + + // if (deleteNum <= 0) return; + + // ContentManager.RemoveCache(TableName, channelId); + //} + + //public void DeleteContent(int siteId, int channelId, int contentId) + //{ + // if (contentId > 0) + // { + // TagUtils.RemoveTags(siteId, contentId); + + // //var sqlString = + // // $"DELETE FROM {tableName} WHERE SiteId = {siteInfo.Id} AND Id = {contentId}"; + // //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + // DeleteAll(Q + // .Where(Attr.SiteId, siteId) + // .Where(Attr.Id, contentId) + // ); + // } + + // if (channelId <= 0) return; + + // ContentManager.RemoveCache(TableName, channelId); + //} + + //public void DeleteContents(int siteId, IList contentIdList, int channelId) + //{ + // var deleteNum = 0; + + // if (contentIdList != null && contentIdList.Count > 0) + // { + // TagUtils.RemoveTags(siteId, contentIdList); + + // //var sqlString = + // // $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; + // //deleteNum = DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + // deleteNum = DeleteAll(Q + // .Where(Attr.SiteId, siteId) + // .WhereIn(Attr.Id, contentIdList) + // ); + // } + + // if (channelId <= 0 || deleteNum <= 0) return; + + // ContentManager.RemoveCache(TableName, channelId); + //} + + //public void DeleteContentsByChannelId(int siteId, int channelId) + //{ + // var contentIdList = GetContentIdListChecked(channelId); + + // TagUtils.RemoveTags(siteId, contentIdList); + + // //var sqlString = + // // $"DELETE FROM {tableName} WHERE SiteId = {siteId} AND ChannelId = {channelId}"; + // //var deleteNum = DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + // var deleteNum = base.DeleteAll(Q + // .Where(Attr.SiteId, siteId) + // .Where(Attr.ChannelId, channelId) + // ); + + // if (channelId <= 0 || deleteNum <= 0) return; + + // ContentManager.RemoveCache(TableName, channelId); + //} + } +} diff --git a/net452/SiteServer.CMS/Database/Repositories/Contents/ContentTableRepository.Select.cs b/net452/SiteServer.CMS/Database/Repositories/Contents/ContentTableRepository.Select.cs new file mode 100644 index 000000000..2d21584a3 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/Contents/ContentTableRepository.Select.cs @@ -0,0 +1,408 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using Datory; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; +using Attr = SiteServer.CMS.Database.Attributes.ContentAttribute; + +namespace SiteServer.CMS.Database.Repositories.Contents +{ + public partial class ContentTableRepository + { + public IList<(int, int)> GetContentIdListByTrash(int siteId) + { + + var list = GetAll(Q + .Select(Attr.Id, Attr.ChannelId) + .Where(Attr.SiteId, siteId) + .Where(Attr.ChannelId, "<", 0)); + + return list.Select(o => (Math.Abs(o.ChannelId), o.Id)).ToList(); + } + + private IList GetReferenceIdList(IList contentIdList) + { + //var list = new List(); + //var sqlString = + // $"SELECT Id FROM {tableName} WHERE ChannelId > 0 AND ReferenceId IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetInt(rdr, 0)); + // } + // rdr.Close(); + //} + + //return list; + + return GetAll(Q + .Select(Attr.Id) + .Where(Attr.ChannelId, ">", 0) + .WhereIn(Attr.ReferenceId, contentIdList) + ); + } + + public IList GetContentIdList(int channelId) + { + //var list = new List(); + + //var sqlString = $"SELECT Id FROM {tableName} WHERE ChannelId = {channelId}"; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // var contentId = DatabaseApi.GetInt(rdr, 0); + // list.Add(contentId); + // } + // rdr.Close(); + //} + //return list; + + return GetAll(Q + .Select(Attr.Id) + .Where(Attr.ChannelId, channelId) + ); + } + + private IList GetContentIdListChecked(ICollection channelIdList, int totalNum = 0) + { + var list = new List(); + + if (channelIdList == null || channelIdList.Count == 0) + { + return list; + } + + var query = Q + .Select(Attr.Id) + .Where(Attr.IsChecked, true.ToString()) + .WhereIn(Attr.ChannelId, channelIdList); + + if (totalNum > 0) + { + query.Limit(totalNum); + } + + return GetAll(query); + + //string sqlString; + + //if (totalNum > 0) + //{ + // sqlString = SqlDifferences.GetSqlString(tableName, new List + // { + // Attr.Id + // }, + // channelIdList.Count == 1 + // ? $"WHERE (ChannelId = {channelIdList[0]} AND IsChecked = '{true}' {whereString})" + // : $"WHERE (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND IsChecked = '{true}' {whereString})", orderString, + // totalNum); + //} + //else + //{ + // sqlString = channelIdList.Count == 1 + // ? $"SELECT Id FROM {tableName} WHERE (ChannelId = {channelIdList[0]} AND IsChecked = '{true}' {whereString}) {orderString}" + // : $"SELECT Id FROM {tableName} WHERE (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND IsChecked = '{true}' {whereString}) {orderString}"; + //} + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // var contentId = DatabaseApi.GetInt(rdr, 0); + // list.Add(contentId); + // } + // rdr.Close(); + //} + //return list; + } + + private IList GetContentIdListChecked(int channelId, int totalNum = 0) + { + var query = Q + .Select(Attr.Id) + .Where(Attr.IsChecked, true.ToString()) + .Where(Attr.ChannelId, channelId); + + if (totalNum > 0) + { + query.Limit(totalNum); + } + return GetAll(query); + + //string sqlString; + + //if (totalNum > 0) + //{ + // sqlString = SqlDifferences.GetSqlString(tableName, new List + // { + // Attr.Id + // }, + // channelIdList.Count == 1 + // ? $"WHERE (ChannelId = {channelIdList[0]} AND IsChecked = '{true}' {whereString})" + // : $"WHERE (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND IsChecked = '{true}' {whereString})", orderString, + // totalNum); + //} + //else + //{ + // sqlString = channelIdList.Count == 1 + // ? $"SELECT Id FROM {tableName} WHERE (ChannelId = {channelIdList[0]} AND IsChecked = '{true}' {whereString}) {orderString}" + // : $"SELECT Id FROM {tableName} WHERE (ChannelId IN ({TranslateUtils.ToSqlInStringWithoutQuote(channelIdList)}) AND IsChecked = '{true}' {whereString}) {orderString}"; + //} + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // var contentId = DatabaseApi.GetInt(rdr, 0); + // list.Add(contentId); + // } + // rdr.Close(); + //} + //return list; + } + + public int GetTotalHits(int siteId) + { + //return DatabaseApi.GetIntResult($"SELECT SUM(Hits) FROM {tableName} WHERE IsChecked='{true}' AND SiteId = {siteId} AND Hits > 0"); + + return Sum(Q + .Select(Attr.Hits) + .Where(Attr.SiteId, siteId) + .Where(Attr.IsChecked, true.ToString()) + .Where(Attr.Hits, ">", 0) + ); + } + + public int GetFirstContentId(int siteId, int channelId) + { + //var sqlString = $"SELECT Id FROM {tableName} WHERE ChannelId = {channelId} ORDER BY Taxis DESC, Id DESC"; + //return DatabaseApi.GetIntResult(sqlString); + + return Get(Q + .Select(Attr.Id) + .Where(Attr.SiteId, siteId) + .Where(Attr.ChannelId, channelId) + .OrderByDesc(Attr.Taxis, Attr.Id) + ); + } + + private int GetTaxis(int contentId) + { + return Get(Q + .Select(Attr.Taxis) + .Where(Attr.Id, contentId) + ); + + //var sqlString = $"SELECT Taxis FROM {tableName} WHERE (Id = {selectedId})"; + + //return DatabaseApi.GetIntResult(sqlString); + } + + public int GetTaxisToInsert(int channelId, bool isTop) + { + int taxis; + + if (isTop) + { + taxis = GetMaxTaxis(channelId, true) + 1; + } + else + { + taxis = GetMaxTaxis(channelId, false) + 1; + } + + return taxis; + } + + public int GetMaxTaxis(int channelId, bool isTop) + { + var maxTaxis = 0; + + if (isTop) + { + maxTaxis = TaxisIsTopStartValue; + + var max = Max(Q + .Select(Attr.Taxis) + .Where(Attr.ChannelId, channelId) + .Where(Attr.Taxis, ">=", TaxisIsTopStartValue) + ); + + if (max != null) + { + maxTaxis = max.Value; + } + + if (maxTaxis < TaxisIsTopStartValue) + { + maxTaxis = TaxisIsTopStartValue; + } + } + else + { + var max = Max(Q + .Select(Attr.Taxis) + .Where(Attr.ChannelId, channelId) + .Where(Attr.Taxis, "<", TaxisIsTopStartValue) + ); + + if (max != null) + { + maxTaxis = max.Value; + } + } + + return maxTaxis; + } + + public bool GetChanelIdAndValue(int contentId, string name, out int channelId, out T value) + { + channelId = 0; + value = default(T); + + var tuple = Get<(int ChannelId, T Result)?>(Q + .Select(Attr.ChannelId, name) + .Where(Attr.Id, contentId) + ); + if (tuple == null) return false; + + channelId = tuple.Value.ChannelId; + value = tuple.Value.Result; + + return true; + //Tuple tuple = null; + + //try + //{ + // var sqlString = $"SELECT {Attr.ChannelId}, {name} FROM {tableName} WHERE Id = {contentId}"; + + // using (var conn = GetConnection()) + // { + // conn.Open(); + // using (var rdr = DatabaseApi.ExecuteReader(conn, sqlString)) + // { + // if (rdr.Read()) + // { + // var channelId = DatabaseApi.GetInt(rdr, 0); + // var value = DatabaseApi.GetString(rdr, 1); + + // tuple = new Tuple(channelId, value); + // } + + // rdr.Close(); + // } + // } + //} + //catch + //{ + // // ignored + //} + + //return tuple; + } + + public T GetValue(int contentId, string name) + { + return Get(Q + .Select(name) + .Where(Attr.Id, contentId) + ); + } + + public IList GetContentIdList(int channelId, bool isPeriods, string dateFrom, string dateTo, ETriState checkedState) + { + var query = Q + .Select(Attr.Id) + .Where(Attr.ChannelId, channelId) + .OrderByDesc(Attr.Taxis, Attr.Id); + + if (isPeriods) + { + if (!string.IsNullOrEmpty(dateFrom)) + { + query.Where(Attr.AddDate, ">=", SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))); + } + if (!string.IsNullOrEmpty(dateTo)) + { + query.Where(Attr.AddDate, "<=", SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo).AddDays(1))); + } + } + + if (checkedState != ETriState.All) + { + query.Where(Attr.IsChecked, ETriStateUtils.GetValue(checkedState)); + } + + return GetAll(query); + } + + public IList GetContentIdListCheckedByChannelId(int siteId, int channelId) + { + return GetAll(Q + .Select(Attr.Id) + .Where(Attr.SiteId, siteId) + .Where(Attr.ChannelId, channelId) + .Where(Attr.IsChecked, true.ToString()) + ); + } + + public int GetContentId(int channelId, int taxis, bool isNextContent) + { + if (isNextContent) + { + return Get(Q + .Select(Attr.Id) + .Where(Attr.ChannelId, channelId) + .Where(Attr.Taxis, "<", taxis) + .Where(Attr.IsChecked, true.ToString()) + .OrderByDesc(Attr.Taxis)); + } + + return Get(Q + .Select(Attr.Id) + .Where(Attr.ChannelId, channelId) + .Where(Attr.Taxis, ">", taxis) + .Where(Attr.IsChecked, true.ToString()) + .OrderBy(Attr.Taxis)); + } + + public int GetSequence(int channelId, int contentId) + { + var taxis = GetTaxis(contentId); + + return Count(Q + .Where(Attr.ChannelId, channelId) + .Where(Attr.IsChecked, true.ToString()) + .Where(Attr.Taxis, "<", taxis) + .Where(Attr.SourceId, "!=", SourceManager.Preview) + ) + 1; + } + + public IList GetIdListBySameTitle(int channelId, string title) + { + return GetAll(Q + .Select(Attr.Id) + .Where(Attr.ChannelId, channelId) + .Where(Attr.Title, title) + ); + } + + public int GetCountCheckedImage(int siteId, int channelId) + { + return Count(Q + .Where(Attr.ChannelId, channelId) + .WhereNotNull(Attr.ImageUrl) + .Where(Attr.ImageUrl, "!=", string.Empty) + .Where(Attr.IsChecked, true.ToString()) + .Where(Attr.SourceId, "!=", SourceManager.Preview) + ); + } + } +} diff --git a/net452/SiteServer.CMS/Database/Repositories/Contents/ContentTableRepository.Update.cs b/net452/SiteServer.CMS/Database/Repositories/Contents/ContentTableRepository.Update.cs new file mode 100644 index 000000000..743a14234 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/Contents/ContentTableRepository.Update.cs @@ -0,0 +1,402 @@ +using System; +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; +using Attr = SiteServer.CMS.Database.Attributes.ContentAttribute; + +namespace SiteServer.CMS.Database.Repositories.Contents +{ + public partial class ContentTableRepository + { + public void UpdateIsChecked(int channelId, List contentIdList, int translateChannelId, string userName, bool isChecked, int checkedLevel, string reasons) + { + //if (isChecked) + //{ + // checkedLevel = 0; + //} + + //var checkDate = DateTime.Now; + + //foreach (var contentId in contentIdList) + //{ + // var tuple = GetValue(tableName, contentId, Attr.SettingsXml); + // if (tuple == null) continue; + + // var attributes = new AttributesImpl(tuple.Item2); + // attributes.Set(Attr.CheckUserName, userName); + // attributes.Set(Attr.CheckDate, DateUtils.GetDateAndTimeString(checkDate)); + // attributes.Set(Attr.CheckReasons, reasons); + + // var sqlString = + // $"UPDATE {tableName} SET {ContentAttribute.IsChecked)} = '{isChecked}', {ContentAttribute.CheckedLevel)} = {checkedLevel}, {ContentAttribute.SettingsXml)} = '{attributes}' WHERE {ContentAttribute.Id)} = {contentId}"; + // if (translateChannelId > 0) + // { + // sqlString = + // $"UPDATE {tableName} SET {ContentAttribute.IsChecked)} = '{isChecked}', {ContentAttribute.CheckedLevel)} = {checkedLevel}, {ContentAttribute.SettingsXml)} = '{attributes}', {ContentAttribute.ChannelId)} = {translateChannelId} WHERE {ContentAttribute.Id)} = {contentId}"; + // } + // DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + // var checkInfo = new ContentCheckInfo + // { + // TableName = tableName, + // SiteId = siteId, + // ChannelId = channelId, + // ContentId = contentId, + // UserName = userName, + // Checked = isChecked, + // CheckedLevel = checkedLevel, + // CheckDate = checkDate, + // Reasons = reasons + // }; + // DataProvider.ContentCheck.Insert(checkInfo); + //} + + //ContentManager.RemoveCache(tableName, channelId); + + if (isChecked) + { + checkedLevel = 0; + } + + var checkDate = DateTime.Now; + + foreach (var contentId in contentIdList) + { + var settingsXml = Get(Q + .Select(Attr.SettingsXml) + .Where(Attr.Id, contentId)); + + var attributes = TranslateUtils.JsonDeserialize(settingsXml, new Dictionary(StringComparer.OrdinalIgnoreCase)); + + attributes[Attr.CheckUserName] = userName; + attributes[Attr.CheckDate] = DateUtils.GetDateAndTimeString(checkDate); + attributes[Attr.CheckReasons] = reasons; + + settingsXml = TranslateUtils.JsonSerialize(attributes); + + if (translateChannelId > 0) + { + Update(Q + .Set(Attr.IsChecked, isChecked.ToString()) + .Set(Attr.CheckedLevel, checkedLevel) + .Set(Attr.SettingsXml, settingsXml) + .Set(Attr.ChannelId, translateChannelId) + .Where(Attr.Id, contentId) + ); + } + else + { + Update(Q + .Set(Attr.IsChecked, isChecked.ToString()) + .Set(Attr.CheckedLevel, checkedLevel) + .Set(Attr.SettingsXml, settingsXml) + .Where(Attr.Id, contentId) + ); + } + + DataProvider.ContentCheck.Insert(new ContentCheckInfo + { + TableName = TableName, + SiteId = SiteId, + ChannelId = channelId, + ContentId = contentId, + UserName = userName, + Checked = isChecked, + CheckedLevel = checkedLevel, + CheckDate = checkDate, + Reasons = reasons + }); + } + + ContentManager.RemoveCache(TableName, channelId); + } + + public void UpdateArrangeTaxis(int channelId, string attributeName, bool isDesc) + { + //var taxisDirection = isDesc ? "ASC" : "DESC";//升序,但由于页面排序是按Taxis的Desc排序的,所以这里sql里面的ASC/DESC取反 + + //var sqlString = + // $"SELECT Id, IsTop FROM {tableName} WHERE ChannelId = {channelId} OR ChannelId = -{channelId} ORDER BY {attributeName} {taxisDirection}"; + //var sqlList = new List(); + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // var taxis = 1; + // while (rdr.Read()) + // { + // var id = DatabaseApi.GetInt(rdr, 0); + // var isTop = TranslateUtils.ToBool(DatabaseApi.GetString(rdr, 1)); + + // sqlList.Add( + // $"UPDATE {tableName} SET Taxis = {taxis++}, IsTop = '{isTop}' WHERE Id = {id}"); + // } + // rdr.Close(); + //} + + //DatabaseApi.ExecuteSql(sqlList); + + //ContentManager.RemoveCache(tableName, channelId); + + var query = Q + .Select(Attr.Id) + .Where(Attr.ChannelId, channelId) + .OrWhere(Attr.ChannelId, -channelId); + if (isDesc) + { + query.OrderBy(attributeName); + } + else + { + query.OrderByDesc(attributeName); + } + + var idList = GetAll(query); + + var taxis = 1; + foreach (var contentId in idList) + { + Update(Q + .Set(Attr.Taxis, taxis++) + .Where(Attr.Id, contentId) + ); + } + } + + public void SetAutoPageContentToSite() + { + var siteInfo = SiteManager.GetSiteInfo(SiteId); + if (!siteInfo.IsAutoPageInTextEditor) return; + + //var sqlString = + // $"SELECT Id, {ContentAttribute.ChannelId)}, {ContentAttribute.Content)} FROM {siteInfo.TableName} WHERE SiteId = {siteInfo.Id}"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // var contentId = DatabaseApi.GetInt(rdr, 0); + // var channelId = DatabaseApi.GetInt(rdr, 1); + // var content = DatabaseApi.GetString(rdr, 2); + + // if (!string.IsNullOrEmpty(content)) + // { + // content = ContentUtility.GetAutoPageContent(content, siteInfo.AutoPageWordNum); + + // Update(siteInfo.TableName, channelId, contentId, ContentAttribute.Content), content); + // } + // } + + // rdr.Close(); + //} + + var resultList = GetAll<(int Id, int ChannelId, string Content)>(Q.Where(Attr.SiteId, SiteId)); + + foreach (var result in resultList) + { + + if (!string.IsNullOrEmpty(result.Content)) + { + var content = ContentUtility.GetAutoPageContent(result.Content, siteInfo.AutoPageWordNum); + + Update(result.ChannelId, result.Id, Attr.Content, content); + } + } + } + + public void AddContentGroupList(int contentId, List contentGroupList) + { + if (!GetChanelIdAndValue(contentId, Attr.GroupNameCollection, out var channelId, out var value)) return; + + var list = TranslateUtils.StringCollectionToStringList(value); + foreach (var groupName in contentGroupList) + { + if (!list.Contains(groupName)) list.Add(groupName); + } + Update(channelId, contentId, Attr.GroupNameCollection, TranslateUtils.ObjectCollectionToString(list)); + } + + public void Update(int channelId, int contentId, string name, string value) + { + //var sqlString = $"UPDATE {tableName} SET {name} = @{name} WHERE Id = @Id"; + + //var parameters = new DynamicParameters(); + //parameters.Add($"@{name}", value); + //parameters.Add("@Id", contentId); + + //using (var connection = GetConnection()) + //{ + // connection.Execute(sqlString, parameters); + //} + + //ContentManager.RemoveCache(tableName, channelId); + + var updateNum = Update(Q + .Set(name, value) + .Where(Attr.Id, contentId) + ); + + if (updateNum <= 0) return; + + ContentManager.RemoveCache(TableName, channelId); + } + + public void UpdateTrashContents(int siteId, int channelId, IList contentIdList) + { + var referenceIdList = GetReferenceIdList(contentIdList); + if (referenceIdList.Count > 0) + { + DeleteReferenceContents(siteId, channelId, referenceIdList); + //DeleteContents(siteId, channelId, referenceIdList); + } + + var updateNum = 0; + + if (contentIdList != null && contentIdList.Count > 0) + { + //var sqlString = + // $"UPDATE {tableName} SET ChannelId = -ChannelId, LastEditDate = {SqlUtils.GetComparableNow()} WHERE SiteId = {siteId} AND Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList)})"; + //updateNum = DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + updateNum = Update(Q + .SetRaw($"{Attr.ChannelId} = -{Attr.ChannelId}") + .Set(Attr.LastEditDate, DateTime.Now) + .Where(Attr.SiteId, siteId) + .WhereIn(Attr.Id, contentIdList) + ); + } + + if (updateNum <= 0) return; + + ContentManager.RemoveCache(TableName, channelId); + } + + public void UpdateTrashContentsByChannelId(int siteId, int channelId) + { + var contentIdList = GetContentIdList(channelId); + var referenceIdList = GetReferenceIdList(contentIdList); + if (referenceIdList.Count > 0) + { + DeleteReferenceContents(siteId, channelId, referenceIdList); + //DeleteContents(siteId, channelId, referenceIdList); + } + + //var sqlString = + // $"UPDATE {tableName} SET ChannelId = -ChannelId, LastEditDate = {SqlUtils.GetComparableNow()} WHERE SiteId = {siteId} AND ChannelId = {siteId}"; + //updateNum = DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + var updateNum = Update(Q + .SetRaw($"{Attr.ChannelId} = -{Attr.ChannelId}") + .Set(Attr.LastEditDate, DateTime.Now) + .Where(Attr.SiteId, siteId) + .Where(Attr.ChannelId, channelId) + ); + + if (updateNum <= 0) return; + + ContentManager.RemoveCache(TableName, channelId); + } + + public void UpdateRestoreContentsByTrash(int siteId, int channelId) + { + //var sqlString = + // $"UPDATE {tableName} SET ChannelId = -ChannelId, LastEditDate = {SqlUtils.GetComparableNow()} WHERE SiteId = {siteId} AND ChannelId < 0"; + //var updateNum = DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + var updateNum = Update(Q + .SetRaw($"{Attr.ChannelId} = -{Attr.ChannelId}") + .Set(Attr.LastEditDate, DateTime.Now) + .Where(Attr.SiteId, siteId) + .Where(Attr.ChannelId, "<", 0) + ); + + if (updateNum <= 0) return; + + ContentManager.RemoveCache(TableName, channelId); + } + + public void AddDownloads(int channelId, int contentId) + { + Increment(Q + .Select(Attr.Downloads) + .Where(Attr.Id, contentId)); + + ContentManager.RemoveCache(TableName, channelId); + } + + private void UpdateTaxis(int channelId, int contentId, int taxis) + { + var updateNum = Update(Q + .Set(Attr.Taxis, taxis) + .Where(Attr.Id, contentId) + ); + + if (updateNum <= 0) return; + + ContentManager.RemoveCache(TableName, channelId); + + //var sqlString = $"UPDATE {tableName} SET Taxis = {taxis} WHERE Id = {id}"; + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + //ContentManager.RemoveCache(tableName, channelId); + } + + public bool SetTaxisToUp(int channelId, int contentId, bool isTop) + { + var taxis = GetTaxis(contentId); + + var result = Get<(int HigherId, int HigherTaxis)?>(Q + .Select(Attr.Id, Attr.Taxis) + .Where(Attr.ChannelId, channelId) + .Where(Attr.Taxis, ">", taxis) + .Where(Attr.Taxis, isTop ? ">=" : "<", TaxisIsTopStartValue) + .OrderBy(Attr.Taxis)); + + var higherId = 0; + var higherTaxis = 0; + if (result != null) + { + higherId = result.Value.HigherId; + higherTaxis = result.Value.HigherTaxis; + } + + if (higherId == 0) return false; + + UpdateTaxis(channelId, contentId, higherTaxis); + UpdateTaxis(channelId, higherId, taxis); + + return true; + } + + public bool SetTaxisToDown(int channelId, int contentId, bool isTop) + { + var taxis = GetTaxis(contentId); + + var result = Get<(int LowerId, int LowerTaxis)?>(Q + .Select(Attr.Id, Attr.Taxis) + .Where(Attr.ChannelId, channelId) + .Where(Attr.Taxis, "<", taxis) + .Where(Attr.Taxis, isTop ? ">=" : "<", TaxisIsTopStartValue) + .OrderByDesc(Attr.Taxis)); + + var lowerId = 0; + var lowerTaxis = 0; + if (result != null) + { + lowerId = result.Value.LowerId; + lowerTaxis = result.Value.LowerTaxis; + } + + if (lowerId == 0) return false; + + UpdateTaxis(channelId, contentId, lowerTaxis); + UpdateTaxis(channelId, lowerId, taxis); + + return true; + } + } +} diff --git a/net452/SiteServer.CMS/Database/Repositories/Contents/ContentTableRepository.cs b/net452/SiteServer.CMS/Database/Repositories/Contents/ContentTableRepository.cs new file mode 100644 index 000000000..71699ded9 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/Contents/ContentTableRepository.cs @@ -0,0 +1,190 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories.Contents +{ + public partial class ContentTableRepository : Repository + { + private const int TaxisIsTopStartValue = 2000000000; + + //public override DatabaseType DatabaseType => WebConfigUtils.DatabaseType; + //public override string ConnectionString => WebConfigUtils.ConnectionString; + //public override string TableName { get; } + //public override List TableColumns { get; } + + public int SiteId { get; } + + public ContentTableRepository(int siteId, string tableName) : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName) + { + SiteId = siteId; + } + + public static List GetContentRepositoryList(SiteInfo siteInfo) + { + var list = new List(); + + foreach (var tableName in SiteManager.GetTableNameList(siteInfo)) + { + list.Add(new ContentTableRepository(siteInfo.Id, tableName)); + } + + return list; + } + + //private ContentTableRepository(int siteId, string tableName) + //{ + // SiteId = siteId; + // TableName = tableName; + // TableColumns = DatoryUtils.GetTableColumns(); + + // //TableColumns = new List + // //{ + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.Id), + // // DataType = DataType.Integer, + // // IsIdentity = true, + // // IsPrimaryKey = true + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.ChannelId), + // // DataType = DataType.Integer + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.SiteId), + // // DataType = DataType.Integer + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.AddUserName), + // // DataType = DataType.VarChar + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.LastEditUserName), + // // DataType = DataType.VarChar + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.LastEditDate), + // // DataType = DataType.DateTime + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.AdminId), + // // DataType = DataType.Integer + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.UserId), + // // DataType = DataType.Integer + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.Taxis), + // // DataType = DataType.Integer + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.GroupNameCollection), + // // DataType = DataType.VarChar + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.Tags), + // // DataType = DataType.VarChar + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.SourceId), + // // DataType = DataType.Integer + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.ReferenceId), + // // DataType = DataType.Integer + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.IsChecked), + // // DataType = DataType.VarChar + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.CheckedLevel), + // // DataType = DataType.Integer + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.Hits), + // // DataType = DataType.Integer + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.HitsByDay), + // // DataType = DataType.Integer + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.HitsByWeek), + // // DataType = DataType.Integer + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.HitsByMonth), + // // DataType = DataType.Integer + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.LastHitsDate), + // // DataType = DataType.DateTime + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.SettingsXml), + // // DataType = DataType.Text + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.Title), + // // DataType = DataType.VarChar + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.IsTop), + // // DataType = DataType.VarChar + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.IsRecommend), + // // DataType = DataType.VarChar + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.IsHot), + // // DataType = DataType.VarChar + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.IsColor), + // // DataType = DataType.VarChar + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.LinkUrl), + // // DataType = DataType.VarChar + // // }, + // // new TableColumn + // // { + // // AttributeName = ContentAttribute.AddDate), + // // DataType = DataType.DateTime + // // } + // //}; + //} + } +} diff --git a/net452/SiteServer.CMS/Database/Repositories/DbCacheRepository.cs b/net452/SiteServer.CMS/Database/Repositories/DbCacheRepository.cs new file mode 100644 index 000000000..322490daf --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/DbCacheRepository.cs @@ -0,0 +1,363 @@ +using System; +using Datory; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class DbCacheRepository : Repository + { + public DbCacheRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string CacheKey = nameof(DbCacheInfo.CacheKey); + public const string CacheValue = nameof(DbCacheInfo.CacheValue); + public const string AddDate = nameof(DbCacheInfo.AddDate); + } + + public void RemoveAndInsert(string cacheKey, string cacheValue) + { + if (string.IsNullOrEmpty(cacheKey)) return; + + DeleteExcess90Days(); + + Delete(Q + .Where(Attr.CacheKey, cacheKey)); + + Insert(new DbCacheInfo + { + CacheKey = cacheKey, + CacheValue = cacheValue, + AddDate = DateTime.Now + }); + + //using (var conn = GetConnection()) + //{ + // conn.Open(); + // using (var trans = conn.BeginTransaction()) + // { + // try + // { + // IDataParameter[] parameters = + // { + // GetParameter(ParamCacheKey, cacheKey) + // }; + + // DatabaseApi.ExecuteNonQuery(trans, SqlDelete, parameters); + + // parameters = new[] + // { + // GetParameter(ParamCacheKey, cacheKey), + // GetParameter(ParamCacheValue, cacheValue), + // GetParameter(ParamAddDate,DateTime.Now) + // }; + + // DatabaseApi.ExecuteNonQuery(trans, SqlInsert, parameters); + + // trans.Commit(); + // } + // catch + // { + // trans.Rollback(); + // throw; + // } + // } + //} + } + + public void Clear() + { + Delete(); + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDeleteAll); + } + + public bool IsExists(string cacheKey) + { + return Exists(Q.Where(Attr.CacheKey, cacheKey)); + //var retVal = false; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamCacheKey, cacheKey) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectValue, parameters)) + //{ + // if (rdr.Read()) + // { + // retVal = true; + // } + // rdr.Close(); + //} + //return retVal; + } + + public string GetValue(string cacheKey) + { + //var retVal = string.Empty; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamCacheKey, cacheKey) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectValue, parameters)) + //{ + // if (rdr.Read()) + // { + // retVal = DatabaseApi.GetString(rdr, 0); + // } + // rdr.Close(); + //} + //return retVal; + return base.Get(Q + .Select(Attr.CacheValue) + .Where(Attr.CacheKey, cacheKey)); + } + + public string GetValueAndRemove(string cacheKey) + { + var retVal = base.Get(Q + .Select(Attr.CacheValue) + .Where(Attr.CacheKey, cacheKey)); + + Delete(Q + .Where(Attr.CacheKey, cacheKey)); + + return retVal; + } + + public int GetCount() + { + //var count = 0; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectCount)) + //{ + // if (rdr.Read()) + // { + // count = DatabaseApi.GetInt(rdr, 0); + // } + // rdr.Close(); + //} + //return count; + + return Count(); + } + + public void DeleteExcess90Days() + { + //DatabaseApi.ExecuteNonQuery(ConnectionString, "DELETE FROM siteserver_DbCache WHERE " + SqlUtils.GetDateDiffGreatThanDays("AddDate", 90.ToString())); + + Delete(Q + .Where(Attr.AddDate, "<", DateTime.Now.AddDays(-90))); + } + } +} + + +//using System; +//using System.Collections.Generic; +//using System.Data; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class DbCache : DataProviderBase +// { +// public override string TableName => "siteserver_DbCache"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(DbCacheInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(DbCacheInfo.CacheKey), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(DbCacheInfo.CacheValue), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(DbCacheInfo.AddDate), +// DataType = DataType.DateTime +// } +// }; + +// private const string SqlSelectValue = "SELECT CacheValue FROM siteserver_DbCache WHERE CacheKey = @CacheKey"; + +// private const string SqlSelectCount = "SELECT COUNT(*) FROM siteserver_DbCache"; + +// private const string SqlInsert = "INSERT INTO siteserver_DbCache (CacheKey, CacheValue, AddDate) VALUES (@CacheKey, @CacheValue, @AddDate)"; + +// private const string SqlDelete = "DELETE FROM siteserver_DbCache WHERE CacheKey = @CacheKey"; + +// private const string SqlDeleteAll = "DELETE FROM siteserver_DbCache"; + +// private const string ParamCacheKey = "@CacheKey"; +// private const string ParamCacheValue = "@CacheValue"; +// private const string ParamAddDate = "@AddDate"; + +// public void RemoveAndInsert(string cacheKey, string cacheValue) +// { +// if (string.IsNullOrEmpty(cacheKey)) return; + +// DeleteExcess90Days(); + +// using (var conn = GetConnection()) +// { +// conn.Open(); +// using (var trans = conn.BeginTransaction()) +// { +// try +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamCacheKey, cacheKey) +// }; + +// DatabaseApi.ExecuteNonQuery(trans, SqlDelete, parameters); + +// parameters = new [] +// { +// GetParameter(ParamCacheKey, cacheKey), +// GetParameter(ParamCacheValue, cacheValue), +// GetParameter(ParamAddDate,DateTime.Now) +// }; + +// DatabaseApi.ExecuteNonQuery(trans, SqlInsert, parameters); + +// trans.Commit(); +// } +// catch +// { +// trans.Rollback(); +// throw; +// } +// } +// } +// } + +// public void Clear() +// { +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDeleteAll); +// } + +// public bool IsExists(string cacheKey) +// { +// var retVal = false; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamCacheKey, cacheKey) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectValue, parameters)) +// { +// if (rdr.Read()) +// { +// retVal = true; +// } +// rdr.Close(); +// } +// return retVal; +// } + +// public string GetValueById(string cacheKey) +// { +// var retVal = string.Empty; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamCacheKey, cacheKey) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectValue, parameters)) +// { +// if (rdr.Read()) +// { +// retVal = DatabaseApi.GetString(rdr, 0); +// } +// rdr.Close(); +// } +// return retVal; +// } + +// public string GetValueAndRemove(string cacheKey) +// { +// var retVal = string.Empty; + +// using (var conn = GetConnection()) +// { +// conn.Open(); +// using (var trans = conn.BeginTransaction()) +// { +// try +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamCacheKey, cacheKey) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(trans, SqlSelectValue, parameters)) +// { +// if (rdr.Read()) +// { +// retVal = DatabaseApi.GetString(rdr, 0); +// } +// rdr.Close(); +// } + +// parameters = new[] +// { +// GetParameter(ParamCacheKey, cacheKey) +// }; + +// DatabaseApi.ExecuteNonQuery(trans, SqlDelete, parameters); + +// trans.Commit(); +// } +// catch +// { +// trans.Rollback(); +// throw; +// } +// } +// } + +// return retVal; +// } + +// public int GetCount() +// { +// var count = 0; +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectCount)) +// { +// if (rdr.Read()) +// { +// count = DatabaseApi.GetInt(rdr, 0); +// } +// rdr.Close(); +// } +// return count; +// } + +// public void DeleteExcess90Days() +// { +// DatabaseApi.ExecuteNonQuery(ConnectionString, "DELETE FROM siteserver_DbCache WHERE " + SqlUtils.GetDateDiffGreatThanDays("AddDate", 90.ToString())); +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/DepartmentRepository.cs b/net452/SiteServer.CMS/Database/Repositories/DepartmentRepository.cs new file mode 100644 index 000000000..ac49d7e0b --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/DepartmentRepository.cs @@ -0,0 +1,1140 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class DepartmentRepository : Repository + { + public DepartmentRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(DepartmentInfo.Id); + public const string ParentId = nameof(DepartmentInfo.ParentId); + public const string ParentsPath = nameof(DepartmentInfo.ParentsPath); + public const string ChildrenCount = nameof(DepartmentInfo.ChildrenCount); + public const string Taxis = nameof(DepartmentInfo.Taxis); + public const string IsLastNode = "IsLastNode"; + public const string CountOfAdmin = nameof(DepartmentInfo.CountOfAdmin); + } + + private int Insert(DepartmentInfo parentInfo, DepartmentInfo departmentInfo) + { + if (parentInfo != null) + { + departmentInfo.ParentsPath = parentInfo.ParentsPath + "," + parentInfo.Id; + departmentInfo.ParentsCount = parentInfo.ParentsCount + 1; + + var maxTaxis = GetMaxTaxisByParentPath(departmentInfo.ParentsPath); + if (maxTaxis == 0) + { + maxTaxis = parentInfo.Taxis; + } + departmentInfo.Taxis = maxTaxis + 1; + } + else + { + departmentInfo.ParentsPath = "0"; + departmentInfo.ParentsCount = 0; + var maxTaxis = GetMaxTaxisByParentPath("0"); + departmentInfo.Taxis = maxTaxis + 1; + } + + departmentInfo.ChildrenCount = 0; + departmentInfo.LastNode = true; + + //string sqlString = + // $"UPDATE siteserver_Department SET Taxis = {SqlDifferences.ColumnIncrement("Taxis")} WHERE (Taxis >= {departmentInfo.Taxis})"; + //DatabaseApi.Instance.ExecuteNonQuery(trans, sqlString); + + Increment(Q + .Select(Attr.Taxis) + .Where(Attr.Taxis, ">=", departmentInfo.Taxis)); + + //var sqlInsert = "INSERT INTO siteserver_Department (DepartmentName, Code, ParentID, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, Taxis, AddDate, Summary, CountOfAdmin) VALUES (@DepartmentName, @Code, @ParentID, @ParentsPath, @ParentsCount, @ChildrenCount, @IsLastNode, @Taxis, @AddDate, @Summary, @CountOfAdmin)"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamName, departmentInfo.DepartmentName), + // GetParameter(ParamCode, departmentInfo.Code), + // GetParameter(ParamParentId, departmentInfo.ParentId), + // GetParameter(ParamParentsPath, departmentInfo.ParentsPath), + // GetParameter(ParamParentsCount, departmentInfo.ParentsCount), + // GetParameter(ParamChildrenCount, 0), + // GetParameter(ParamIsLastNode, true.ToString()), + // GetParameter(ParamTaxis, departmentInfo.Taxis), + // GetParameter(ParamAddDate,departmentInfo.AddDate), + // GetParameter(ParamSummary, departmentInfo.Summary), + // GetParameter(ParamCountOfAdmin, departmentInfo.CountOfAdmin) + //}; + + //departmentInfo.Id = DatabaseApi.Instance.ExecuteNonQueryAndReturnId(TableName, nameof(DepartmentInfo.Id), trans, sqlInsert, parameters); + + departmentInfo.Id = base.Insert(departmentInfo); + + if (!string.IsNullOrEmpty(departmentInfo.ParentsPath)) + { + //sqlString = $"UPDATE siteserver_Department SET ChildrenCount = {SqlDifferences.ColumnIncrement("ChildrenCount")} WHERE Id IN ({AttackUtils.FilterSql(departmentInfo.ParentsPath)})"; + + //DatabaseApi.Instance.ExecuteNonQuery(trans, sqlString); + + Increment(Q + .Select(Attr.ChildrenCount) + .WhereIn(Attr.Id, TranslateUtils.StringCollectionToIntList(departmentInfo.ParentsPath))); + } + + //sqlString = $"UPDATE siteserver_Department SET IsLastNode = '{false}' WHERE ParentID = {departmentInfo.ParentId}"; + + //DatabaseApi.Instance.ExecuteNonQuery(trans, sqlString); + + Update(Q + .Set(Attr.IsLastNode, false.ToString()) + .Where(Attr.ParentId, departmentInfo.ParentId) + ); + + //sqlString = + // $"UPDATE siteserver_Department SET IsLastNode = '{true}' WHERE (Id IN (SELECT TOP 1 Id FROM siteserver_Department WHERE ParentID = {departmentInfo.ParentId} ORDER BY Taxis DESC))"; + + //sqlString = + // $"UPDATE siteserver_Department SET IsLastNode = '{true}' WHERE (Id IN ({SqlUtils.ToInTopSqlString("siteserver_Department", new List { nameof(DepartmentInfo.Id) }, $"WHERE ParentID = {departmentInfo.ParentId}", "ORDER BY Taxis DESC", 1)}))"; + + //DatabaseApi.Instance.ExecuteNonQuery(trans, sqlString); + + var topId = Get(Q + .Select(Attr.Id) + .Where(Attr.ParentId, departmentInfo.ParentId) + .OrderByDesc(Attr.Taxis)); + + if (topId > 0) + { + Update(Q + .Set(Attr.IsLastNode, true.ToString()) + .Where(Attr.Id, topId) + ); + } + + DepartmentManager.ClearCache(); + + return departmentInfo.Id; + } + + private void UpdateSubtractChildrenCount(string parentsPath, int subtractNum) + { + if (!string.IsNullOrEmpty(parentsPath)) + { + //var sqlString = string.Concat("UPDATE siteserver_Department SET ChildrenCount = ChildrenCount - ", subtractNum, " WHERE Id IN (", AttackUtils.FilterSql(parentsPath), ")"); + //DatabaseApi.Instance.ExecuteNonQuery(ConnectionString, sqlString); + + Decrement(Q + .Select(Attr.ChildrenCount) + .WhereIn(Attr.Id, TranslateUtils.StringCollectionToIntList(parentsPath)), subtractNum); + + DepartmentManager.ClearCache(); + } + } + + private void TaxisSubtract(int selectedId) + { + var departmentInfo = GetDepartmentInfo(selectedId); + if (departmentInfo == null) return; + + //Get Lower Taxis and Id + //int lowerId; + //int lowerChildrenCount; + //string lowerParentsPath; + + //var sqlString = SqlDifferences.GetSqlString("siteserver_Department", new List + // { + // nameof(DepartmentInfo.Id), + // nameof(DepartmentInfo.ChildrenCount), + // nameof(DepartmentInfo.ParentsPath) + // }, + // "WHERE (ParentID = @ParentID) AND (Id <> @Id) AND (Taxis < @Taxis)", + // "ORDER BY Taxis DESC", 1); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamParentId, departmentInfo.ParentId), + // GetParameter(ParamId, departmentInfo.Id), + // GetParameter(ParamTaxis, departmentInfo.Taxis), + //}; + + //using (var rdr = DatabaseApi.Instance.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // lowerId = DatabaseApi.Instance.GetInt(rdr, 0); + // lowerChildrenCount = DatabaseApi.Instance.GetInt(rdr, 1); + // lowerParentsPath = DatabaseApi.Instance.GetString(rdr, 2); + // } + // else + // { + // return; + // } + // rdr.Close(); + //} + + var result = Get<(int Id, int ChildrenCount, string ParentsPath)?>(Q + .Select( + Attr.Id, + Attr.ChildrenCount, + Attr.ParentsPath) + .Where(Attr.ParentId, departmentInfo.ParentId) + .WhereNot(Attr.Id, departmentInfo.Id) + .Where(Attr.Taxis, "<", departmentInfo.Taxis) + .OrderByDesc(Attr.Taxis)); + + if (result == null) return; + + var lowerId = result.Value.Id; + var lowerChildrenCount = result.Value.ChildrenCount; + var lowerParentsPath = result.Value.ParentsPath; + + var lowerNodePath = string.Concat(lowerParentsPath, ",", lowerId); + var selectedNodePath = string.Concat(departmentInfo.ParentsPath, ",", departmentInfo.Id); + + SetTaxisSubtract(selectedId, selectedNodePath, lowerChildrenCount + 1); + SetTaxisAdd(lowerId, lowerNodePath, departmentInfo.ChildrenCount + 1); + + UpdateIsLastNode(departmentInfo.ParentId); + } + + private void TaxisAdd(int selectedId) + { + var departmentInfo = GetDepartmentInfo(selectedId); + if (departmentInfo == null) return; + //Get Higher Taxis and Id + //int higherId; + //int higherChildrenCount; + //string higherParentsPath; + + //var sqlString = SqlDifferences.GetSqlString("siteserver_Department", new List + // { + // nameof(DepartmentInfo.Id), + // nameof(DepartmentInfo.ChildrenCount), + // nameof(DepartmentInfo.ParentsPath) + // }, + // "WHERE (ParentID = @ParentID) AND (Id <> @Id) AND (Taxis > @Taxis)", + // "ORDER BY Taxis", 1); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamParentId, departmentInfo.ParentId), + // GetParameter(ParamId, departmentInfo.Id), + // GetParameter(ParamTaxis, departmentInfo.Taxis) + //}; + + //using (var rdr = DatabaseApi.Instance.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // higherId = DatabaseApi.Instance.GetInt(rdr, 0); + // higherChildrenCount = DatabaseApi.Instance.GetInt(rdr, 1); + // higherParentsPath = DatabaseApi.Instance.GetString(rdr, 2); + // } + // else + // { + // return; + // } + // rdr.Close(); + //} + + var dataInfo = Get(Q + .Select(Attr.Id, Attr.ChildrenCount, Attr.ParentsPath) + .Where(Attr.ParentId, departmentInfo.ParentId) + .WhereNot(Attr.Id, departmentInfo.Id) + .Where(Attr.Taxis, ">", departmentInfo.Taxis) + .OrderBy(Attr.Taxis)); + + if (dataInfo == null) return; + + var higherId = dataInfo.Id; + var higherChildrenCount = dataInfo.ChildrenCount; + var higherParentsPath = dataInfo.ParentsPath; + + var higherNodePath = string.Concat(higherParentsPath, ",", higherId); + var selectedNodePath = string.Concat(departmentInfo.ParentsPath, ",", departmentInfo.Id); + + SetTaxisAdd(selectedId, selectedNodePath, higherChildrenCount + 1); + SetTaxisSubtract(higherId, higherNodePath, departmentInfo.ChildrenCount + 1); + + UpdateIsLastNode(departmentInfo.ParentId); + } + + private void SetTaxisAdd(int id, string parentsPath, int addNum) + { + //var path = AttackUtils.FilterSql(parentsPath); + //var sqlString = + // $"UPDATE siteserver_Department SET Taxis = Taxis + {addNum} WHERE Id = {id} OR ParentsPath = '{path}' OR ParentsPath LIKE '{path},%'"; + + //DatabaseApi.Instance.ExecuteNonQuery(ConnectionString, sqlString); + + Increment(Q + .Select(Attr.Taxis) + .Where(Attr.Id, id) + .OrWhere(Attr.ParentsPath, parentsPath) + .OrWhereStarts(Attr.ParentsPath, $"{parentsPath},"), addNum); + + DepartmentManager.ClearCache(); + } + + private void SetTaxisSubtract(int id, string parentsPath, int subtractNum) + { + //var path = AttackUtils.FilterSql(parentsPath); + //var sqlString = + // $"UPDATE siteserver_Department SET Taxis = Taxis - {subtractNum} WHERE Id = {id} OR ParentsPath = '{path}' OR ParentsPath LIKE '{path},%'"; + + //DatabaseApi.Instance.ExecuteNonQuery(ConnectionString, sqlString); + + Decrement(Q + .Select(Attr.Taxis) + .Where(Attr.Id, id) + .OrWhere(Attr.ParentsPath, parentsPath) + .OrWhereStarts(Attr.ParentsPath, $"{parentsPath},"), subtractNum); + + DepartmentManager.ClearCache(); + } + + private void UpdateIsLastNode(int parentId) + { + if (parentId <= 0) return; + + //var sqlString = "UPDATE siteserver_Department SET IsLastNode = @IsLastNode WHERE ParentID = @ParentID"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamIsLastNode, false.ToString()), + // GetParameter(ParamParentId, parentId) + //}; + + //DatabaseApi.Instance.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Update(Q + .Set(Attr.IsLastNode, false.ToString()) + .Where(Attr.ParentId, parentId) + ); + + //sqlString = + // $"UPDATE siteserver_Department SET IsLastNode = '{true}' WHERE (Id IN ({SqlUtils.ToInTopSqlString("siteserver_Department", new List { nameof(DepartmentInfo.Id) }, $"WHERE ParentID = {parentId}", "ORDER BY Taxis DESC", 1)}))"; + + //DatabaseApi.Instance.ExecuteNonQuery(ConnectionString, sqlString); + + var topId = Get(Q + .Select(Attr.Id) + .Where(Attr.ParentId, parentId) + .OrderByDesc(Attr.Taxis)); + + if (topId > 0) + { + Update(Q + .Set(Attr.IsLastNode, true.ToString()) + .Where(Attr.Id, topId) + ); + } + } + + private int GetMaxTaxisByParentPath(string parentPath) + { + //parentPath = AttackUtils.FilterSql(parentPath); + //var sqlString = string.Concat("SELECT MAX(Taxis) AS MaxTaxis FROM siteserver_Department WHERE (ParentsPath = '", parentPath, "') OR (ParentsPath LIKE '", parentPath, ",%')"); + //var maxTaxis = 0; + + //using (var rdr = DatabaseApi.Instance.ExecuteReader(ConnectionString, sqlString)) + //{ + // if (rdr.Read()) + // { + // maxTaxis = DatabaseApi.Instance.GetInt(rdr, 0); + // } + // rdr.Close(); + //} + //return maxTaxis; + + return Max(Q + .Select(Attr.Taxis) + .Where(Attr.ParentsPath, parentPath) + .OrWhereStarts(Attr.ParentsPath, $"{parentPath},") + ) ?? 0; + } + + public override int Insert(DepartmentInfo departmentInfo) + { + var parentDepartmentInfo = GetDepartmentInfo(departmentInfo.ParentId); + + departmentInfo.Id = Insert(parentDepartmentInfo, departmentInfo); + + DepartmentManager.ClearCache(); + + return departmentInfo.Id; + } + + public override bool Update(DepartmentInfo departmentInfo) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamName, departmentInfo.DepartmentName), + // GetParameter(ParamCode, departmentInfo.Code), + // GetParameter(ParamParentsPath, departmentInfo.ParentsPath), + // GetParameter(ParamParentsCount, departmentInfo.ParentsCount), + // GetParameter(ParamChildrenCount, departmentInfo.ChildrenCount), + // GetParameter(ParamIsLastNode, departmentInfo.IsLastNode.ToString()), + // GetParameter(ParamSummary, departmentInfo.Summary), + // GetParameter(ParamCountOfAdmin, departmentInfo.CountOfAdmin), + // GetParameter(ParamId, departmentInfo.Id) + //}; + + //string SqlUpdate = "UPDATE siteserver_Department SET DepartmentName = @DepartmentName, Code = @Code, ParentsPath = @ParentsPath, ParentsCount = @ParentsCount, ChildrenCount = @ChildrenCount, IsLastNode = @IsLastNode, Summary = @Summary, CountOfAdmin = @CountOfAdmin WHERE Id = @Id"; + //DatabaseApi.Instance.ExecuteNonQuery(ConnectionString, SqlUpdate, parameters); + + var updated= base.Update(departmentInfo); + if (updated) + { + DepartmentManager.ClearCache(); + } + + return updated; + } + + public void UpdateTaxis(int selectedId, bool isSubtract) + { + if (isSubtract) + { + TaxisSubtract(selectedId); + } + else + { + TaxisAdd(selectedId); + } + } + + public void UpdateCountOfAdmin() + { + var idList = DepartmentManager.GetDepartmentIdList(); + foreach (var departmentId in idList) + { + var count = DataProvider.Administrator.GetCountByDepartmentId(departmentId); + //string sqlString = $"UPDATE {TableName} SET CountOfAdmin = {count} WHERE Id = {departmentId}"; + //DatabaseApi.Instance.ExecuteNonQuery(ConnectionString, sqlString); + + Update(Q + .Set(Attr.CountOfAdmin, count) + .Where(Attr.Id, departmentId) + ); + } + DepartmentManager.ClearCache(); + } + + public override bool Delete(int id) + { + var departmentInfo = GetDepartmentInfo(id); + if (departmentInfo == null) return false; + + IList idList = new List(); + if (departmentInfo.ChildrenCount > 0) + { + idList = GetIdListForDescendant(id); + } + idList.Add(id); + + //string sqlString = + // $"DELETE FROM siteserver_Department WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + + //deletedNum = DatabaseApi.Instance.ExecuteNonQuery(trans, sqlString); + + var deletedNum = Delete(Q + .WhereIn(Attr.Id, idList)); + + if (deletedNum > 0) + { + //string sqlStringTaxis = + // $"UPDATE siteserver_Department SET Taxis = Taxis - {deletedNum} WHERE (Taxis > {departmentInfo.Taxis})"; + //DatabaseApi.Instance.ExecuteNonQuery(trans, sqlStringTaxis); + + Decrement(Q + .Select(Attr.Taxis) + .Where(Attr.Taxis, ">", departmentInfo.Taxis), deletedNum); + } + + UpdateIsLastNode(departmentInfo.ParentId); + UpdateSubtractChildrenCount(departmentInfo.ParentsPath, deletedNum); + + DepartmentManager.ClearCache(); + + return true; + } + + private DepartmentInfo GetDepartmentInfo(int id) + { + //DepartmentInfo departmentInfo = null; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamId, id) + //}; + + //string SqlSelect = "SELECT Id, DepartmentName, Code, ParentID, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, Taxis, AddDate, Summary, CountOfAdmin FROM siteserver_Department WHERE Id = @Id"; + //using (var rdr = DatabaseApi.Instance.ExecuteReader(ConnectionString, SqlSelect, parameters)) + //{ + // if (rdr.Read()) + // { + // var i = 0; + // departmentInfo = new DepartmentInfo(DatabaseApi.Instance.GetInt(rdr, i++), DatabaseApi.Instance.GetString(rdr, i++), DatabaseApi.Instance.GetString(rdr, i++), DatabaseApi.Instance.GetInt(rdr, i++), DatabaseApi.Instance.GetString(rdr, i++), DatabaseApi.Instance.GetInt(rdr, i++), DatabaseApi.Instance.GetInt(rdr, i++), TranslateUtils.ToBool(DatabaseApi.Instance.GetString(rdr, i++)), DatabaseApi.Instance.GetInt(rdr, i++), DatabaseApi.Instance.GetDateTime(rdr, i++), DatabaseApi.Instance.GetString(rdr, i++), DatabaseApi.Instance.GetInt(rdr, i)); + // } + // rdr.Close(); + //} + //return departmentInfo; + + return Get(id); + } + + private IList GetDepartmentInfoList() + { + //var list = new List(); + + //string SqlSelectAll = "SELECT Id, DepartmentName, Code, ParentID, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, Taxis, AddDate, Summary, CountOfAdmin FROM siteserver_Department ORDER BY TAXIS"; + //using (var rdr = DatabaseApi.Instance.ExecuteReader(ConnectionString, SqlSelectAll)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var departmentInfo = new DepartmentInfo(DatabaseApi.Instance.GetInt(rdr, i++), DatabaseApi.Instance.GetString(rdr, i++), DatabaseApi.Instance.GetString(rdr, i++), DatabaseApi.Instance.GetInt(rdr, i++), DatabaseApi.Instance.GetString(rdr, i++), DatabaseApi.Instance.GetInt(rdr, i++), DatabaseApi.Instance.GetInt(rdr, i++), TranslateUtils.ToBool(DatabaseApi.Instance.GetString(rdr, i++)), DatabaseApi.Instance.GetInt(rdr, i++), DatabaseApi.Instance.GetDateTime(rdr, i++), DatabaseApi.Instance.GetString(rdr, i++), DatabaseApi.Instance.GetInt(rdr, i)); + // list.Add(departmentInfo); + // } + // rdr.Close(); + //} + //return list; + + return GetAll(Q + .OrderBy(Attr.Taxis)); + } + + public IList GetIdListByParentId(int parentId) + { + //var sqlString = + // $@"SELECT Id FROM siteserver_Department WHERE ParentID = '{parentId}' ORDER BY Taxis"; + //var list = new List(); + + //using (var rdr = DatabaseApi.Instance.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // var theId = DatabaseApi.Instance.GetInt(rdr, 0); + // list.Add(theId); + // } + // rdr.Close(); + //} + + //return list; + + return GetAll(Q + .Select(Attr.Id) + .Where(Attr.ParentId, parentId) + .OrderBy(Attr.Taxis)); + } + + private IList GetIdListForDescendant(int id) + { +// string sqlString = $@"SELECT Id +//FROM siteserver_Department +//WHERE (ParentsPath LIKE '{id},%') OR +// (ParentsPath LIKE '%,{id},%') OR +// (ParentsPath LIKE '%,{id}') OR +// (ParentID = {id}) +//"; +// var list = new List(); + +// using (var rdr = DatabaseApi.Instance.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var theId = DatabaseApi.Instance.GetInt(rdr, 0); +// list.Add(theId); +// } +// rdr.Close(); +// } + +// return list; + + return GetAll(Q + .Select(Attr.Id) + .Where(Attr.ParentId, id) + .OrWhereStarts(Attr.ParentsPath, $"{id},") + .OrWhereContains(Attr.ParentsPath, $",{id},") + .OrWhereEnds(Attr.ParentsPath, $",{id}")); + } + + public List> GetDepartmentInfoKeyValuePair() + { + var list = new List>(); + + var departmentInfoList = GetDepartmentInfoList(); + foreach (var departmentInfo in departmentInfoList) + { + var pair = new KeyValuePair(departmentInfo.Id, departmentInfo); + list.Add(pair); + } + + return list; + } + } +} + + +//using System.Collections.Generic; +//using System.Data; +//using SiteServer.CMS.Database.Caches; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class Department : DataProviderBase +// { +// public override string TableName => "siteserver_Department"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(DepartmentInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(DepartmentInfo.DepartmentName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(DepartmentInfo.Code), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(DepartmentInfo.ParentId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(DepartmentInfo.ParentsPath), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(DepartmentInfo.ParentsCount), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(DepartmentInfo.ChildrenCount), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(DepartmentInfo.IsLastNode), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(DepartmentInfo.Taxis), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(DepartmentInfo.AddDate), +// DataType = DataType.DateTime +// }, +// new TableColumn +// { +// AttributeName = nameof(DepartmentInfo.Summary), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(DepartmentInfo.CountOfAdmin), +// DataType = DataType.Integer +// } +// }; + +// private const string SqlSelect = "SELECT Id, DepartmentName, Code, ParentID, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, Taxis, AddDate, Summary, CountOfAdmin FROM siteserver_Department WHERE Id = @Id"; + +// private const string SqlSelectAll = "SELECT Id, DepartmentName, Code, ParentID, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, Taxis, AddDate, Summary, CountOfAdmin FROM siteserver_Department ORDER BY TAXIS"; + +// private const string SqlUpdate = "UPDATE siteserver_Department SET DepartmentName = @DepartmentName, Code = @Code, ParentsPath = @ParentsPath, ParentsCount = @ParentsCount, ChildrenCount = @ChildrenCount, IsLastNode = @IsLastNode, Summary = @Summary, CountOfAdmin = @CountOfAdmin WHERE Id = @Id"; + +// private const string ParamId = "@Id"; +// private const string ParamName = "@DepartmentName"; +// private const string ParamCode = "@Code"; +// private const string ParamParentId = "@ParentID"; +// private const string ParamParentsPath = "@ParentsPath"; +// private const string ParamParentsCount = "@ParentsCount"; +// private const string ParamChildrenCount = "@ChildrenCount"; +// private const string ParamIsLastNode = "@IsLastNode"; +// private const string ParamTaxis = "@Taxis"; +// private const string ParamAddDate = "@AddDate"; +// private const string ParamSummary = "@Summary"; +// private const string ParamCountOfAdmin = "@CountOfAdmin"; + +// private void InsertWithTrans(DepartmentInfo parentInfo, DepartmentInfo departmentInfo, IDbTransaction trans) +// { +// if (parentInfo != null) +// { +// departmentInfo.ParentsPath = parentInfo.ParentsPath + "," + parentInfo.Id; +// departmentInfo.ParentsCount = parentInfo.ParentsCount + 1; + +// var maxTaxis = GetMaxTaxisByParentPath(departmentInfo.ParentsPath); +// if (maxTaxis == 0) +// { +// maxTaxis = parentInfo.Taxis; +// } +// departmentInfo.Taxis = maxTaxis + 1; +// } +// else +// { +// departmentInfo.ParentsPath = "0"; +// departmentInfo.ParentsCount = 0; +// var maxTaxis = GetMaxTaxisByParentPath("0"); +// departmentInfo.Taxis = maxTaxis + 1; +// } + +// var sqlInsert = "INSERT INTO siteserver_Department (DepartmentName, Code, ParentID, ParentsPath, ParentsCount, ChildrenCount, IsLastNode, Taxis, AddDate, Summary, CountOfAdmin) VALUES (@DepartmentName, @Code, @ParentID, @ParentsPath, @ParentsCount, @ChildrenCount, @IsLastNode, @Taxis, @AddDate, @Summary, @CountOfAdmin)"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamName, departmentInfo.DepartmentName), +// GetParameter(ParamCode, departmentInfo.Code), +// GetParameter(ParamParentId, departmentInfo.ParentId), +// GetParameter(ParamParentsPath, departmentInfo.ParentsPath), +// GetParameter(ParamParentsCount, departmentInfo.ParentsCount), +// GetParameter(ParamChildrenCount, 0), +// GetParameter(ParamIsLastNode, true.ToString()), +// GetParameter(ParamTaxis, departmentInfo.Taxis), +// GetParameter(ParamAddDate,departmentInfo.AddDate), +// GetParameter(ParamSummary, departmentInfo.Summary), +// GetParameter(ParamCountOfAdmin, departmentInfo.CountOfAdmin) +// }; + +// string sqlString = +// $"UPDATE siteserver_Department SET Taxis = {SqlDifferences.ColumnIncrement("Taxis")} WHERE (Taxis >= {departmentInfo.Taxis})"; +// DatabaseApi.Instance.ExecuteNonQuery(trans, sqlString); + +// departmentInfo.Id = DatabaseApi.Instance.ExecuteNonQueryAndReturnId(TableName, nameof(DepartmentInfo.Id), trans, sqlInsert, parameters); + +// if (!string.IsNullOrEmpty(departmentInfo.ParentsPath)) +// { +// sqlString = $"UPDATE siteserver_Department SET ChildrenCount = {SqlDifferences.ColumnIncrement("ChildrenCount")} WHERE Id IN ({AttackUtils.FilterSql(departmentInfo.ParentsPath)})"; + +// DatabaseApi.Instance.ExecuteNonQuery(trans, sqlString); +// } + +// sqlString = $"UPDATE siteserver_Department SET IsLastNode = '{false}' WHERE ParentID = {departmentInfo.ParentId}"; + +// DatabaseApi.Instance.ExecuteNonQuery(trans, sqlString); + +// //sqlString = +// // $"UPDATE siteserver_Department SET IsLastNode = '{true}' WHERE (Id IN (SELECT TOP 1 Id FROM siteserver_Department WHERE ParentID = {departmentInfo.ParentId} ORDER BY Taxis DESC))"; + +// sqlString = +// $"UPDATE siteserver_Department SET IsLastNode = '{true}' WHERE (Id IN ({SqlUtils.ToInTopSqlString("siteserver_Department", new List { nameof(DepartmentInfo.Id) }, $"WHERE ParentID = {departmentInfo.ParentId}", "ORDER BY Taxis DESC", 1)}))"; + +// DatabaseApi.Instance.ExecuteNonQuery(trans, sqlString); + +// DepartmentManager.ClearCache(); +// } + +// private void UpdateSubtractChildrenCount(string parentsPath, int subtractNum) +// { +// if (!string.IsNullOrEmpty(parentsPath)) +// { +// var sqlString = string.Concat("UPDATE siteserver_Department SET ChildrenCount = ChildrenCount - ", subtractNum, " WHERE Id IN (", AttackUtils.FilterSql(parentsPath) , ")"); +// DatabaseApi.Instance.ExecuteNonQuery(ConnectionString, sqlString); + +// DepartmentManager.ClearCache(); +// } +// } + +// private void TaxisSubtract(int selectedId) +// { +// var departmentInfo = GetDepartmentInfo(selectedId); +// if (departmentInfo == null) return; +// //Get Lower Taxis and Id +// int lowerId; +// int lowerChildrenCount; +// string lowerParentsPath; + +// var sqlString = SqlDifferences.GetSqlString("siteserver_Department", new List +// { +// nameof(DepartmentInfo.Id), +// nameof(DepartmentInfo.ChildrenCount), +// nameof(DepartmentInfo.ParentsPath) +// }, +// "WHERE (ParentID = @ParentID) AND (Id <> @Id) AND (Taxis < @Taxis)", +// "ORDER BY Taxis DESC", 1); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamParentId, departmentInfo.ParentId), +// GetParameter(ParamId, departmentInfo.Id), +// GetParameter(ParamTaxis, departmentInfo.Taxis), +// }; + +// using (var rdr = DatabaseApi.Instance.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// lowerId = DatabaseApi.Instance.GetInt(rdr, 0); +// lowerChildrenCount = DatabaseApi.Instance.GetInt(rdr, 1); +// lowerParentsPath = DatabaseApi.Instance.GetString(rdr, 2); +// } +// else +// { +// return; +// } +// rdr.Close(); +// } + + +// var lowerNodePath = string.Concat(lowerParentsPath, ",", lowerId); +// var selectedNodePath = string.Concat(departmentInfo.ParentsPath, ",", departmentInfo.Id); + +// SetTaxisSubtract(selectedId, selectedNodePath, lowerChildrenCount + 1); +// SetTaxisAdd(lowerId, lowerNodePath, departmentInfo.ChildrenCount + 1); + +// UpdateIsLastNode(departmentInfo.ParentId); +// } + +// private void TaxisAdd(int selectedId) +// { +// var departmentInfo = GetDepartmentInfo(selectedId); +// if (departmentInfo == null) return; +// //Get Higher Taxis and Id +// int higherId; +// int higherChildrenCount; +// string higherParentsPath; + +// var sqlString = SqlDifferences.GetSqlString("siteserver_Department", new List +// { +// nameof(DepartmentInfo.Id), +// nameof(DepartmentInfo.ChildrenCount), +// nameof(DepartmentInfo.ParentsPath) +// }, +// "WHERE (ParentID = @ParentID) AND (Id <> @Id) AND (Taxis > @Taxis)", +// "ORDER BY Taxis", 1); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamParentId, departmentInfo.ParentId), +// GetParameter(ParamId, departmentInfo.Id), +// GetParameter(ParamTaxis, departmentInfo.Taxis) +// }; + +// using (var rdr = DatabaseApi.Instance.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// higherId = DatabaseApi.Instance.GetInt(rdr, 0); +// higherChildrenCount = DatabaseApi.Instance.GetInt(rdr, 1); +// higherParentsPath = DatabaseApi.Instance.GetString(rdr, 2); +// } +// else +// { +// return; +// } +// rdr.Close(); +// } + + +// var higherNodePath = string.Concat(higherParentsPath, ",", higherId); +// var selectedNodePath = string.Concat(departmentInfo.ParentsPath, ",", departmentInfo.Id); + +// SetTaxisAdd(selectedId, selectedNodePath, higherChildrenCount + 1); +// SetTaxisSubtract(higherId, higherNodePath, departmentInfo.ChildrenCount + 1); + +// UpdateIsLastNode(departmentInfo.ParentId); +// } + +// private void SetTaxisAdd(int id, string parentsPath, int addNum) +// { +// var path = AttackUtils.FilterSql(parentsPath); +// var sqlString = +// $"UPDATE siteserver_Department SET Taxis = Taxis + {addNum} WHERE Id = {id} OR ParentsPath = '{path}' OR ParentsPath LIKE '{path},%'"; + +// DatabaseApi.Instance.ExecuteNonQuery(ConnectionString, sqlString); + +// DepartmentManager.ClearCache(); +// } + +// private void SetTaxisSubtract(int id, string parentsPath, int subtractNum) +// { +// var path = AttackUtils.FilterSql(parentsPath); +// var sqlString = +// $"UPDATE siteserver_Department SET Taxis = Taxis - {subtractNum} WHERE Id = {id} OR ParentsPath = '{path}' OR ParentsPath LIKE '{path},%'"; + +// DatabaseApi.Instance.ExecuteNonQuery(ConnectionString, sqlString); + +// DepartmentManager.ClearCache(); +// } + +// private void UpdateIsLastNode(int parentId) +// { +// if (parentId <= 0) return; + +// var sqlString = "UPDATE siteserver_Department SET IsLastNode = @IsLastNode WHERE ParentID = @ParentID"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamIsLastNode, false.ToString()), +// GetParameter(ParamParentId, parentId) +// }; + +// DatabaseApi.Instance.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// sqlString = +// $"UPDATE siteserver_Department SET IsLastNode = '{true}' WHERE (Id IN ({SqlUtils.ToInTopSqlString("siteserver_Department", new List{ nameof(DepartmentInfo.Id) }, $"WHERE ParentID = {parentId}", "ORDER BY Taxis DESC", 1)}))"; + +// DatabaseApi.Instance.ExecuteNonQuery(ConnectionString, sqlString); +// } + +// private int GetMaxTaxisByParentPath(string parentPath) +// { +// parentPath = AttackUtils.FilterSql(parentPath); +// var sqlString = string.Concat("SELECT MAX(Taxis) AS MaxTaxis FROM siteserver_Department WHERE (ParentsPath = '", parentPath, "') OR (ParentsPath LIKE '", parentPath, ",%')"); +// var maxTaxis = 0; + +// using (var rdr = DatabaseApi.Instance.ExecuteReader(ConnectionString, sqlString)) +// { +// if (rdr.Read()) +// { +// maxTaxis = DatabaseApi.Instance.GetInt(rdr, 0); +// } +// rdr.Close(); +// } +// return maxTaxis; +// } + +// public int InsertObject(DepartmentInfo departmentInfo) +// { +// using (var conn = GetConnection()) +// { +// conn.Open(); +// using (var trans = conn.BeginTransaction()) +// { +// try +// { +// var parentDepartmentInfo = GetDepartmentInfo(departmentInfo.ParentId); + +// InsertWithTrans(parentDepartmentInfo, departmentInfo, trans); + +// trans.Commit(); +// } +// catch +// { +// trans.Rollback(); +// throw; +// } +// } +// } + +// DepartmentManager.ClearCache(); + +// return departmentInfo.Id; +// } + +// public void UpdateObject(DepartmentInfo departmentInfo) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamName, departmentInfo.DepartmentName), +// GetParameter(ParamCode, departmentInfo.Code), +// GetParameter(ParamParentsPath, departmentInfo.ParentsPath), +// GetParameter(ParamParentsCount, departmentInfo.ParentsCount), +// GetParameter(ParamChildrenCount, departmentInfo.ChildrenCount), +// GetParameter(ParamIsLastNode, departmentInfo.IsLastNode.ToString()), +// GetParameter(ParamSummary, departmentInfo.Summary), +// GetParameter(ParamCountOfAdmin, departmentInfo.CountOfAdmin), +// GetParameter(ParamId, departmentInfo.Id) +// }; + +// DatabaseApi.Instance.ExecuteNonQuery(ConnectionString, SqlUpdate, parameters); + +// DepartmentManager.ClearCache(); +// } + +// public void UpdateTaxis(int selectedId, bool isSubtract) +// { +// if (isSubtract) +// { +// TaxisSubtract(selectedId); +// } +// else +// { +// TaxisAdd(selectedId); +// } +// } + +// public void UpdateCountOfAdmin() +// { +// var idList = DepartmentManager.GetDepartmentIdList(); +// foreach (var departmentId in idList) +// { +// var count = DataProvider.Administrator.GetCountByDepartmentId(departmentId); +// string sqlString = $"UPDATE {TableName} SET CountOfAdmin = {count} WHERE Id = {departmentId}"; +// DatabaseApi.Instance.ExecuteNonQuery(ConnectionString, sqlString); +// } +// DepartmentManager.ClearCache(); +// } + +// public void DeleteById(int id) +// { +// var departmentInfo = GetDepartmentInfo(id); +// if (departmentInfo != null) +// { +// var idList = new List(); +// if (departmentInfo.ChildrenCount > 0) +// { +// idList = GetIdListForDescendant(id); +// } +// idList.Add(id); + +// string sqlString = +// $"DELETE FROM siteserver_Department WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + +// int deletedNum; + +// using (var conn = GetConnection()) +// { +// conn.Open(); +// using (var trans = conn.BeginTransaction()) +// { +// try +// { +// deletedNum = DatabaseApi.Instance.ExecuteNonQuery(trans, sqlString); + +// if (deletedNum > 0) +// { +// string sqlStringTaxis = +// $"UPDATE siteserver_Department SET Taxis = Taxis - {deletedNum} WHERE (Taxis > {departmentInfo.Taxis})"; +// DatabaseApi.Instance.ExecuteNonQuery(trans, sqlStringTaxis); +// } + +// trans.Commit(); +// } +// catch +// { +// trans.Rollback(); +// throw; +// } +// } +// } +// UpdateIsLastNode(departmentInfo.ParentId); +// UpdateSubtractChildrenCount(departmentInfo.ParentsPath, deletedNum); +// } + +// DepartmentManager.ClearCache(); +// } + +// private DepartmentInfo GetDepartmentInfo(int id) +// { +// DepartmentInfo departmentInfo = null; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamId, id) +// }; + +// using (var rdr = DatabaseApi.Instance.ExecuteReader(ConnectionString, SqlSelect, parameters)) +// { +// if (rdr.Read()) +// { +// var i = 0; +// departmentInfo = new DepartmentInfo(DatabaseApi.Instance.GetInt(rdr, i++), DatabaseApi.Instance.GetString(rdr, i++), DatabaseApi.Instance.GetString(rdr, i++), DatabaseApi.Instance.GetInt(rdr, i++), DatabaseApi.Instance.GetString(rdr, i++), DatabaseApi.Instance.GetInt(rdr, i++), DatabaseApi.Instance.GetInt(rdr, i++), TranslateUtils.ToBool(DatabaseApi.Instance.GetString(rdr, i++)), DatabaseApi.Instance.GetInt(rdr, i++), DatabaseApi.Instance.GetDateTime(rdr, i++), DatabaseApi.Instance.GetString(rdr, i++), DatabaseApi.Instance.GetInt(rdr, i)); +// } +// rdr.Close(); +// } +// return departmentInfo; +// } + +// private List GetDepartmentInfoList() +// { +// var list = new List(); + +// using (var rdr = DatabaseApi.Instance.ExecuteReader(ConnectionString, SqlSelectAll)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var departmentInfo = new DepartmentInfo(DatabaseApi.Instance.GetInt(rdr, i++), DatabaseApi.Instance.GetString(rdr, i++), DatabaseApi.Instance.GetString(rdr, i++), DatabaseApi.Instance.GetInt(rdr, i++), DatabaseApi.Instance.GetString(rdr, i++), DatabaseApi.Instance.GetInt(rdr, i++), DatabaseApi.Instance.GetInt(rdr, i++), TranslateUtils.ToBool(DatabaseApi.Instance.GetString(rdr, i++)), DatabaseApi.Instance.GetInt(rdr, i++), DatabaseApi.Instance.GetDateTime(rdr, i++), DatabaseApi.Instance.GetString(rdr, i++), DatabaseApi.Instance.GetInt(rdr, i)); +// list.Add(departmentInfo); +// } +// rdr.Close(); +// } +// return list; +// } + +// public List GetIdListByParentId(int parentId) +// { +// var sqlString = +// $@"SELECT Id FROM siteserver_Department WHERE ParentID = '{parentId}' ORDER BY Taxis"; +// var list = new List(); + +// using (var rdr = DatabaseApi.Instance.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var theId = DatabaseApi.Instance.GetInt(rdr, 0); +// list.Add(theId); +// } +// rdr.Close(); +// } + +// return list; +// } + +// public List GetIdListForDescendant(int id) +// { +// string sqlString = $@"SELECT Id +//FROM siteserver_Department +//WHERE (ParentsPath LIKE '{id},%') OR +// (ParentsPath LIKE '%,{id},%') OR +// (ParentsPath LIKE '%,{id}') OR +// (ParentID = {id}) +//"; +// var list = new List(); + +// using (var rdr = DatabaseApi.Instance.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var theId = DatabaseApi.Instance.GetInt(rdr, 0); +// list.Add(theId); +// } +// rdr.Close(); +// } + +// return list; +// } + +// public List> GetDepartmentInfoKeyValuePair() +// { +// var list = new List>(); + +// var departmentInfoList = GetDepartmentInfoList(); +// foreach (var departmentInfo in departmentInfoList) +// { +// var pair = new KeyValuePair(departmentInfo.Id, departmentInfo); +// list.Add(pair); +// } + +// return list; +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/ErrorLogRepository.cs b/net452/SiteServer.CMS/Database/Repositories/ErrorLogRepository.cs new file mode 100644 index 000000000..c2e82c6ef --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/ErrorLogRepository.cs @@ -0,0 +1,343 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class ErrorLogRepository : Repository + { + public ErrorLogRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(ErrorLogInfo.Id); + public const string AddDate = nameof(ErrorLogInfo.AddDate); + } + + public override int Insert(ErrorLogInfo logInfo) + { + //var sqlString = $"INSERT INTO {TableName} (Category, PluginId, Message, Stacktrace, Summary, AddDate) VALUES (@Category, @PluginId, @Message, @Stacktrace, @Summary, @AddDate)"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamCategory, logInfo.Category), + // GetParameter(ParamPluginId, logInfo.PluginId), + // GetParameter(ParamMessage, logInfo.Message), + // GetParameter(ParamStacktrace,logInfo.Stacktrace), + // GetParameter(ParamSummary,logInfo.Summary), + // GetParameter(ParamAddDate,logInfo.AddDate), + //}; + + //return DatabaseApi.ExecuteNonQueryAndReturnId(ConnectionString, TableName, nameof(ErrorLogInfo.Id), sqlString, parameters); + + logInfo.Id = base.Insert(logInfo); + + return logInfo.Id; + } + + public void Delete(List idList) + { + if (idList == null || idList.Count <= 0) return; + + //var sqlString = + // $"DELETE FROM {TableName} WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + Delete(Q + .WhereIn(Attr.Id, idList) + ); + } + + public void DeleteIfThreshold() + { + if (!ConfigManager.Instance.IsTimeThreshold) return; + + var days = ConfigManager.Instance.TimeThreshold; + if (days <= 0) return; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, $@"DELETE FROM {TableName} WHERE AddDate < {SqlUtils.GetComparableDateTime(DateTime.Now.AddDays(-days))}"); + + Delete(Q + .Where(Attr.AddDate, "<", DateTime.Now.AddDays(-days))); + } + + //public void DeleteAll() + //{ + // var sqlString = $"DELETE FROM {TableName}"; + + // DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + //} + + public ErrorLogInfo GetErrorLogInfo(int logId) + { + //if (logId <= 0) return null; + //ErrorLogInfo logInfo = null; + + //var sqlString = $"SELECT Id, Category, PluginId, Message, Stacktrace, Summary, AddDate FROM {TableName} WHERE Id = @Id"; + + //IDataParameter[] parameters = + //{ + // GetParameter("@Id", logId) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // var i = 0; + // logInfo = new ErrorLogInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetDateTime(rdr, i)); + // } + // rdr.Close(); + //} + + //return logInfo; + + return Get(logId); + } + + public string GetSelectCommend(string category, string pluginId, string keyword, string dateFrom, string dateTo) + { + var whereString = new StringBuilder(); + + if (!string.IsNullOrEmpty(category)) + { + whereString.Append($"Category = '{AttackUtils.FilterSql(category)}'"); + } + + if (!string.IsNullOrEmpty(pluginId)) + { + whereString.Append($"PluginId = '{AttackUtils.FilterSql(pluginId)}'"); + } + + if (!string.IsNullOrEmpty(keyword)) + { + if (whereString.Length > 0) + { + whereString.Append(" AND "); + } + var filterKeyword = AttackUtils.FilterSql(keyword); + var keywordId = TranslateUtils.ToInt(keyword); + whereString.Append(keywordId > 0 + ? $"Id = {keywordId}" + : $"(Message LIKE '%{filterKeyword}%' OR Stacktrace LIKE '%{filterKeyword}%' OR Summary LIKE '%{filterKeyword}%')"); + } + if (!string.IsNullOrEmpty(dateFrom)) + { + if (whereString.Length > 0) + { + whereString.Append(" AND "); + } + whereString.Append($"AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))}"); + } + if (!string.IsNullOrEmpty(dateTo)) + { + if (whereString.Length > 0) + { + whereString.Append(" AND "); + } + whereString.Append($"AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo))}"); + } + + return whereString.Length > 0 + ? $"SELECT Id, Category, PluginId, Message, Stacktrace, Summary, AddDate FROM {TableName} WHERE {whereString}" + : $"SELECT Id, Category, PluginId, Message, Stacktrace, Summary, AddDate FROM {TableName}"; + } + + public void DeleteAll() + { + base.Delete(); + } + } +} + + +//using System; +//using System.Collections.Generic; +//using System.Data; +//using System.Text; +//using SiteServer.CMS.Database.Caches; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class ErrorLog : DataProviderBase +// { +// public override string TableName => "siteserver_ErrorLog"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(ErrorLogInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(ErrorLogInfo.Category), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ErrorLogInfo.PluginId), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ErrorLogInfo.Message), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(ErrorLogInfo.Stacktrace), +// DataType = DataType.Text +// }, +// new TableColumn +// { +// AttributeName = nameof(ErrorLogInfo.Summary), +// DataType = DataType.Text +// }, +// new TableColumn +// { +// AttributeName = nameof(ErrorLogInfo.AddDate), +// DataType = DataType.DateTime +// } +// }; + +// private const string ParamCategory = "@Category"; +// private const string ParamPluginId = "@PluginId"; +// private const string ParamMessage = "@Message"; +// private const string ParamStacktrace = "@Stacktrace"; +// private const string ParamSummary = "@Summary"; +// private const string ParamAddDate = "@AddDate"; + +// public int InsertObject(ErrorLogInfo logInfo) +// { +// var sqlString = $"INSERT INTO {TableName} (Category, PluginId, Message, Stacktrace, Summary, AddDate) VALUES (@Category, @PluginId, @Message, @Stacktrace, @Summary, @AddDate)"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamCategory, logInfo.Category), +// GetParameter(ParamPluginId, logInfo.PluginId), +// GetParameter(ParamMessage, logInfo.Message), +// GetParameter(ParamStacktrace,logInfo.Stacktrace), +// GetParameter(ParamSummary,logInfo.Summary), +// GetParameter(ParamAddDate,logInfo.AddDate), +// }; + +// return DatabaseApi.ExecuteNonQueryAndReturnId(ConnectionString, TableName, nameof(ErrorLogInfo.Id), sqlString, parameters); +// } + +// public void DeleteById(List idList) +// { +// if (idList == null || idList.Count <= 0) return; + +// var sqlString = +// $"DELETE FROM {TableName} WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } + +// public void DeleteIfThreshold() +// { +// if (!ConfigManager.Instance.IsTimeThreshold) return; + +// var days = ConfigManager.Instance.TimeThreshold; +// if (days <= 0) return; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, $@"DELETE FROM {TableName} WHERE AddDate < {SqlUtils.GetComparableDateTime(DateTime.Now.AddDays(-days))}"); +// } + +// public void DeleteAll() +// { +// var sqlString = $"DELETE FROM {TableName}"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } + +// public ErrorLogInfo GetErrorLogInfo(int logId) +// { +// if (logId <= 0) return null; +// ErrorLogInfo logInfo = null; + +// var sqlString = $"SELECT Id, Category, PluginId, Message, Stacktrace, Summary, AddDate FROM {TableName} WHERE Id = @Id"; + +// IDataParameter[] parameters = +// { +// GetParameter("@Id", logId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// var i = 0; +// logInfo = new ErrorLogInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetDateTime(rdr, i)); +// } +// rdr.Close(); +// } + +// return logInfo; +// } + +// public string GetSelectCommend(string category, string pluginId, string keyword, string dateFrom, string dateTo) +// { +// var whereString = new StringBuilder(); + +// if (!string.IsNullOrEmpty(category)) +// { +// whereString.Append($"Category = '{AttackUtils.FilterSql(category)}'"); +// } + +// if (!string.IsNullOrEmpty(pluginId)) +// { +// whereString.Append($"PluginId = '{AttackUtils.FilterSql(pluginId)}'"); +// } + +// if (!string.IsNullOrEmpty(keyword)) +// { +// if (whereString.Length > 0) +// { +// whereString.Append(" AND "); +// } +// var filterKeyword = AttackUtils.FilterSql(keyword); +// var keywordId = TranslateUtils.ToInt(keyword); +// whereString.Append(keywordId > 0 +// ? $"Id = {keywordId}" +// : $"(Message LIKE '%{filterKeyword}%' OR Stacktrace LIKE '%{filterKeyword}%' OR Summary LIKE '%{filterKeyword}%')"); +// } +// if (!string.IsNullOrEmpty(dateFrom)) +// { +// if (whereString.Length > 0) +// { +// whereString.Append(" AND "); +// } +// whereString.Append($"AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))}"); +// } +// if (!string.IsNullOrEmpty(dateTo)) +// { +// if (whereString.Length > 0) +// { +// whereString.Append(" AND "); +// } +// whereString.Append($"AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo))}"); +// } + +// return whereString.Length > 0 +// ? $"SELECT Id, Category, PluginId, Message, Stacktrace, Summary, AddDate FROM {TableName} WHERE {whereString}" +// : $"SELECT Id, Category, PluginId, Message, Stacktrace, Summary, AddDate FROM {TableName}"; +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/KeywordRepository.cs b/net452/SiteServer.CMS/Database/Repositories/KeywordRepository.cs new file mode 100644 index 000000000..9b71f7b6b --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/KeywordRepository.cs @@ -0,0 +1,469 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class KeywordRepository : Repository + { + public KeywordRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Keyword = nameof(KeywordInfo.Keyword); + } + + public override int Insert(KeywordInfo keywordInfo) + { + //const string sqlString = "INSERT INTO siteserver_Keyword(Keyword, Alternative, Grade) VALUES(@Keyword, @Alternative, @Grade)"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamKeyword, keywordInfo.Keyword), + // GetParameter(ParamAlternative, keywordInfo.Alternative), + // GetParameter(ParamGrade, EKeywordGradeUtils.GetValueById(keywordInfo.Grade)) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + keywordInfo.Id = base.Insert(keywordInfo); + return keywordInfo.Id; + } + + public int GetCount() + { + //var sqlString = "SELECT COUNT(*) AS TotalNum FROM siteserver_Keyword"; + //return DatabaseApi.Instance.GetIntResult(sqlString); + + return Count(); + } + + public override bool Update(KeywordInfo keywordInfo) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamKeyword, keywordInfo.Keyword), + // GetParameter(ParamAlternative, keywordInfo.Alternative), + // GetParameter(ParamGrade, EKeywordGradeUtils.GetValueById(keywordInfo.Grade)), + // GetParameter(ParamId, keywordInfo.Id) + //}; + //string SqlUpdate = "UPDATE siteserver_Keyword SET Keyword = @Keyword, Alternative = @Alternative, Grade = @Grade WHERE Id=@Id"; + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdate, parameters); + + var updated = base.Update(keywordInfo); + return updated; + } + + //public KeywordInfo Get(int id) + //{ + // //var keywordInfo = new KeywordInfo(); + + // //IDataParameter[] parameters = + // //{ + // // GetParameter(ParamId, id) + // //}; + // //string SqlSelect = "SELECT Id, Keyword, Alternative, Grade FROM siteserver_Keyword WHERE Id=@Id"; + // //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelect, parameters)) + // //{ + // // if (rdr.Read()) + // // { + // // var i = 0; + // // keywordInfo = new KeywordInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), EKeywordGradeUtils.GetEnumType(DatabaseApi.GetString(rdr, i))); + // // } + // // rdr.Close(); + // //} + // //return keywordInfo; + + // return GetObjectById(id); + //} + + //public void Delete(int id) + //{ + // //IDataParameter[] parameters = + // //{ + // // GetParameter(ParamId, id) + // //}; + // //string SqlDelete = "DELETE FROM siteserver_Keyword WHERE Id = @Id"; + // //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDelete, parameters); + + // DeleteById(id); + //} + + public string GetSelectCommand() + { + string SqlSelectAll = "SELECT Id, Keyword, Alternative, Grade FROM siteserver_Keyword"; + return SqlSelectAll; + } + + public bool IsExists(string keyword) + { + //var isExists = false; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamKeyword, keyword) + //}; + //string SqlSelectKeyword = "SELECT Id, Keyword, Alternative, Grade FROM siteserver_Keyword WHERE Keyword = @Keyword"; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectKeyword, parameters)) + //{ + // if (rdr.Read()) + // { + // isExists = true; + // } + // rdr.Close(); + //} + //return isExists; + + return Exists(Q.Where(Attr.Keyword, keyword)); + } + + public IList GetKeywordInfoList() + { + //var list = new List(); + //string SqlSelectAll = "SELECT Id, Keyword, Alternative, Grade FROM siteserver_Keyword"; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAll)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var keywordInfo = new KeywordInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), EKeywordGradeUtils.GetEnumType(DatabaseApi.GetString(rdr, i))); + // list.Add(keywordInfo); + // } + // rdr.Close(); + //} + //return list; + + return GetAll(); + } + + public IList GetKeywordInfoList(IList keywords) + { + if (keywords == null || keywords.Count == 0) return new List(); + + //var list = new List(); + //string sqlSelectKeywords = + // $"SELECT Id, Keyword, Alternative, Grade FROM siteserver_Keyword WHERE Keyword IN ({TranslateUtils.ToSqlInStringWithQuote(keywords)})"; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlSelectKeywords)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var keywordInfo = new KeywordInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), EKeywordGradeUtils.GetEnumType(DatabaseApi.GetString(rdr, i))); + // list.Add(keywordInfo); + // } + // rdr.Close(); + //} + //return list; + + return GetAll(Q + .WhereIn(Attr.Keyword, keywords)); + } + + //todo: 实现INSTR函数 + public IList GetKeywordListByContent(string content) + { + //var sqlString = $"SELECT Keyword FROM siteserver_Keyword WHERE {SqlUtils.GetInStrReverse(AttackUtils.FilterSql(content), nameof(KeywordInfo.Keyword))}"; + //return DatabaseApi.Instance.GetStringList(sqlString); + + return GetAll(Q + .Select(Attr.Keyword) + .WhereContains(Attr.Keyword, content)); + } + + //public GenericQuery InStr(string name, string value, bool reverse = false) + //{ + // var paramKey = GetParameterKey(name); + + // var retVal = string.Empty; + // if (reverse) + // { + // if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + // { + // retVal = $"INSTR(@{paramKey}, {name}) > 0"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + // { + // retVal = $"CHARINDEX({name}, @{paramKey}) > 0"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + // { + // retVal = $"POSITION({name} IN @{paramKey}) > 0"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + // { + // retVal = $"INSTR(@{paramKey}, {name}) > 0"; + // } + // } + // else + // { + // if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + // { + // retVal = $"INSTR({name}, @{paramKey}) > 0"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + // { + // retVal = $"CHARINDEX(@{paramKey}, {name}) > 0"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + // { + // retVal = $"POSITION(@{paramKey} IN {name}) > 0"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + // { + // retVal = $"INSTR({name} @{paramKey}) > 0"; + // } + // } + + // _whereList.Add(retVal); + // SqlParameters.Add(paramKey, value); + + // return this; + //} + + //public GenericQuery NotInStr(string name, string value, bool reverse = false) + //{ + // var paramKey = GetParameterKey(name); + + // var retVal = string.Empty; + // if (reverse) + // { + // if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + // { + // retVal = $"INSTR(@{paramKey}, {name}) = 0"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + // { + // retVal = $"CHARINDEX({name}, @{paramKey}) = 0"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + // { + // retVal = $"POSITION({name} IN @{paramKey}) = 0"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + // { + // retVal = $"INSTR(@{paramKey}, {name}) = 0"; + // } + // } + // else + // { + // if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + // { + // retVal = $"INSTR({name}, @{paramKey}) = 0"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + // { + // retVal = $"CHARINDEX(@{paramKey}, {name}) = 0"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + // { + // retVal = $"POSITION(@{paramKey} IN {name}) = 0"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + // { + // retVal = $"INSTR({name}, @{paramKey}) = 0"; + // } + // } + + // _whereList.Add(retVal); + // SqlParameters.Add(paramKey, value); + + // return this; + //} + } +} + + +//using System.Collections.Generic; +//using System.Data; +//using SiteServer.CMS.Core.Enumerations; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class Keyword : DataProviderBase +// { +// public override string TableName => "siteserver_Keyword"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(KeywordInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(KeywordInfo.Keyword), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(KeywordInfo.Alternative), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(KeywordInfo.Grade), +// DataType = DataType.VarChar +// } +// }; + +// private const string ParamId = "@Id"; +// private const string ParamKeyword = "@Keyword"; +// private const string ParamAlternative = "@Alternative"; +// private const string ParamGrade = "@Grade"; + +// private const string SqlUpdate = "UPDATE siteserver_Keyword SET Keyword = @Keyword, Alternative = @Alternative, Grade = @Grade WHERE Id=@Id"; + +// private const string SqlDelete = "DELETE FROM siteserver_Keyword WHERE Id = @Id"; + +// private const string SqlSelect = "SELECT Id, Keyword, Alternative, Grade FROM siteserver_Keyword WHERE Id=@Id"; + +// private const string SqlSelectAll = "SELECT Id, Keyword, Alternative, Grade FROM siteserver_Keyword"; + +// private const string SqlSelectKeyword = "SELECT Id, Keyword, Alternative, Grade FROM siteserver_Keyword WHERE Keyword = @Keyword"; + +// public void InsertObject(KeywordInfo keywordInfo) +// { +// const string sqlString = "INSERT INTO siteserver_Keyword(Keyword, Alternative, Grade) VALUES(@Keyword, @Alternative, @Grade)"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamKeyword, keywordInfo.Keyword), +// GetParameter(ParamAlternative, keywordInfo.Alternative), +// GetParameter(ParamGrade, EKeywordGradeUtils.GetValueById(keywordInfo.Grade)) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// public int GetCount() +// { +// var sqlString = "SELECT COUNT(*) AS TotalNum FROM siteserver_Keyword"; +// return DatabaseApi.Instance.GetIntResult(sqlString); +// } + +// public void UpdateObject(KeywordInfo keywordInfo) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamKeyword, keywordInfo.Keyword), +// GetParameter(ParamAlternative, keywordInfo.Alternative), +// GetParameter(ParamGrade, EKeywordGradeUtils.GetValueById(keywordInfo.Grade)), +// GetParameter(ParamId, keywordInfo.Id) +// }; +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdate, parameters); +// } + +// public KeywordInfo GetKeywordInfo(int id) +// { +// var keywordInfo = new KeywordInfo(); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamId, id) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelect, parameters)) +// { +// if (rdr.Read()) +// { +// var i = 0; +// keywordInfo = new KeywordInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), EKeywordGradeUtils.GetEnumType(DatabaseApi.GetString(rdr, i))); +// } +// rdr.Close(); +// } +// return keywordInfo; +// } + +// public void DeleteById(int id) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamId, id) +// }; +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDelete, parameters); +// } + +// public void DeleteById(List idList) +// { +// string sqlString = +// $@"DELETE FROM siteserver_Keyword WHERE Id IN ({TranslateUtils.ObjectCollectionToString(idList)})"; +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } + +// public string GetSelectCommand() +// { +// return SqlSelectAll; +// } + +// public bool IsExists(string keyword) +// { +// var isExists = false; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamKeyword, keyword) +// }; +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectKeyword, parameters)) +// { +// if (rdr.Read()) +// { +// isExists = true; +// } +// rdr.Close(); +// } +// return isExists; +// } + +// public List GetKeywordInfoList() +// { +// var list = new List(); +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAll)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var keywordInfo = new KeywordInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), EKeywordGradeUtils.GetEnumType(DatabaseApi.GetString(rdr, i))); +// list.Add(keywordInfo); +// } +// rdr.Close(); +// } +// return list; +// } + +// public List GetKeywordInfoList(List keywords) +// { +// if (keywords == null || keywords.Count == 0) return new List(); + +// var list = new List(); +// string sqlSelectKeywords = +// $"SELECT Id, Keyword, Alternative, Grade FROM siteserver_Keyword WHERE Keyword IN ({TranslateUtils.ToSqlInStringWithQuote(keywords)})"; +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlSelectKeywords)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var keywordInfo = new KeywordInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), EKeywordGradeUtils.GetEnumType(DatabaseApi.GetString(rdr, i))); +// list.Add(keywordInfo); +// } +// rdr.Close(); +// } +// return list; +// } + +// public List GetKeywordListByContent(string content) +// { +// var sqlString = $"SELECT Keyword FROM siteserver_Keyword WHERE {SqlUtils.GetInStrReverse(AttackUtils.FilterSql(content), nameof(KeywordInfo.Keyword))}"; +// return DatabaseApi.Instance.GetStringList(sqlString); +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/LogRepository.cs b/net452/SiteServer.CMS/Database/Repositories/LogRepository.cs new file mode 100644 index 000000000..4c9782843 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/LogRepository.cs @@ -0,0 +1,634 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Datory; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Database.Repositories +{ + public class LogRepository : Repository + { + public LogRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(LogInfo.Id); + public const string AddDate = nameof(LogInfo.AddDate); + public const string Action = nameof(LogInfo.Action); + } + + public override int Insert(LogInfo log) + { + //const string sqlString = "INSERT INTO siteserver_Log(UserName, IPAddress, AddDate, Action, Summary) VALUES (@UserName, @IPAddress, @AddDate, @Action, @Summary)"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamUserName, log.UserName), + // GetParameter(ParamIpAddress, log.IpAddress), + // GetParameter(ParamAddDate,log.AddDate), + // GetParameter(ParamAction, log.Action), + // GetParameter(ParamSummary, log.Summary) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + log.Id = base.Insert(log); + return log.Id; + } + + public void Delete(List idList) + { + if (idList == null || idList.Count <= 0) return; + + //string sqlString = + // $"DELETE FROM siteserver_Log WHERE ID IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + Delete(Q + .WhereIn(Attr.Id, idList)); + } + + public void DeleteIfThreshold() + { + if (!ConfigManager.Instance.IsTimeThreshold) return; + + var days = ConfigManager.Instance.TimeThreshold; + if (days <= 0) return; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, $@"DELETE FROM siteserver_Log WHERE AddDate < {SqlUtils.GetComparableDateTime(DateTime.Now.AddDays(-days))}"); + + Delete(Q + .Where(Attr.AddDate, "<", DateTime.Now.AddDays(-days))); + } + + public void DeleteAll() + { + //const string sqlString = "DELETE FROM siteserver_Log"; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + base.Delete(); + } + + public int GetCount() + { + //var count = 0; + //const string sqlString = "SELECT Count(*) FROM siteserver_Log"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // if (rdr.Read() && !rdr.IsDBNull(0)) + // { + // count = DatabaseApi.GetInt(rdr, 0); + // } + // rdr.Close(); + //} + + //return count; + + return Count(); + } + + public string GetSelectCommend() + { + return "SELECT ID, UserName, IPAddress, AddDate, Action, Summary FROM siteserver_Log"; + } + + public string GetSelectCommend(string userName, string keyword, string dateFrom, string dateTo) + { + if (string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(keyword) && string.IsNullOrEmpty(dateFrom) && string.IsNullOrEmpty(dateTo)) + { + return GetSelectCommend(); + } + + var whereString = new StringBuilder("WHERE "); + + var isWhere = false; + + if (!string.IsNullOrEmpty(userName)) + { + isWhere = true; + whereString.AppendFormat("(UserName = '{0}')", AttackUtils.FilterSql(userName)); + } + + if (!string.IsNullOrEmpty(keyword)) + { + if (isWhere) + { + whereString.Append(" AND "); + } + isWhere = true; + whereString.AppendFormat("(Action LIKE '%{0}%' OR Summary LIKE '%{0}%')", AttackUtils.FilterSql(keyword)); + } + + if (!string.IsNullOrEmpty(dateFrom)) + { + if (isWhere) + { + whereString.Append(" AND "); + } + isWhere = true; + whereString.Append($"(AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))})"); + } + if (!string.IsNullOrEmpty(dateTo)) + { + if (isWhere) + { + whereString.Append(" AND "); + } + whereString.Append($"(AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo))})"); + } + + return "SELECT ID, UserName, IPAddress, AddDate, Action, Summary FROM siteserver_Log " + whereString; + } + + public DateTime GetLastRemoveLogDate() + { + //var retVal = DateTime.MinValue; + //var sqlString = SqlDifferences.GetSqlString("siteserver_Log", new List + // { + // nameof(LogInfo.AddDate) + // }, + // "WHERE Action = '清空数据库日志'", "ORDER BY ID DESC", 1); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamUserName, userName) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // retVal = DatabaseApi.GetDateTime(rdr, 0); + // } + // rdr.Close(); + //} + //return retVal; + + var addDate = Get(Q + .Select(Attr.AddDate) + .Where(Attr.Action, "清空数据库日志") + .OrderByDesc(Attr.Id)); + + return addDate ?? DateTime.MinValue; + } + + /// + /// 统计管理员actionType的操作次数 + /// + /// + /// + /// + /// + /// + public Dictionary GetAdminLoginDictionaryByDate(DateTime dateFrom, DateTime dateTo, string xType, string actionType) + { + var dict = new Dictionary(); + if (string.IsNullOrEmpty(xType)) + { + xType = EStatictisXTypeUtils.GetValue(EStatictisXType.Day); + } + + var builder = new StringBuilder(); + if (dateFrom > DateUtils.SqlMinValue) + { + builder.Append($" AND AddDate >= {SqlUtils.GetComparableDate(dateFrom)}"); + } + if (dateTo != DateUtils.SqlMinValue) + { + builder.Append($" AND AddDate < {SqlUtils.GetComparableDate(dateTo)}"); + } + + string sqlSelectTrackingDay = $@" +SELECT COUNT(*) AS AddNum, AddYear, AddMonth, AddDay FROM ( + SELECT {SqlUtils.GetDatePartYear("AddDate")} AS AddYear, {SqlUtils.GetDatePartMonth("AddDate")} AS AddMonth, {SqlUtils.GetDatePartDay("AddDate")} AS AddDay + FROM siteserver_Log + WHERE {SqlUtils.GetDateDiffLessThanDays("AddDate", 30.ToString())} {builder} +) DERIVEDTBL GROUP BY AddYear, AddMonth, AddDay ORDER BY AddNum DESC";//添加日统计 + + if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Month)) + { + sqlSelectTrackingDay = $@" +SELECT COUNT(*) AS AddNum, AddYear, AddMonth FROM ( + SELECT {SqlUtils.GetDatePartYear("AddDate")} AS AddYear, {SqlUtils.GetDatePartMonth("AddDate")} AS AddMonth + FROM siteserver_Log + WHERE {SqlUtils.GetDateDiffLessThanMonths("AddDate", 12.ToString())} {builder} +) DERIVEDTBL GROUP BY AddYear, AddMonth ORDER BY AddNum DESC";//添加月统计 + } + else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Year)) + { + sqlSelectTrackingDay = $@" +SELECT COUNT(*) AS AddNum, AddYear FROM ( + SELECT {SqlUtils.GetDatePartYear("AddDate")} AS AddYear + FROM siteserver_Log + WHERE {SqlUtils.GetDateDiffLessThanYears("AddDate", 10.ToString())} {builder} +) DERIVEDTBL GROUP BY AddYear ORDER BY AddNum DESC +";//添加年统计 + } + + using (var rdr = DataProvider.DatabaseApi.ExecuteReader(WebConfigUtils.ConnectionString, sqlSelectTrackingDay)) + { + while (rdr.Read()) + { + var accessNum = DataProvider.DatabaseApi.GetInt(rdr, 0); + if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Day)) + { + var year = DataProvider.DatabaseApi.GetString(rdr, 1); + var month = DataProvider.DatabaseApi.GetString(rdr, 2); + var day = DataProvider.DatabaseApi.GetString(rdr, 3); + var dateTime = TranslateUtils.ToDateTime($"{year}-{month}-{day}"); + dict.Add(dateTime, accessNum); + } + else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Month)) + { + var year = DataProvider.DatabaseApi.GetString(rdr, 1); + var month = DataProvider.DatabaseApi.GetString(rdr, 2); + + var dateTime = TranslateUtils.ToDateTime($"{year}-{month}-1"); + dict.Add(dateTime, accessNum); + } + else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Year)) + { + var year = DataProvider.DatabaseApi.GetString(rdr, 1); + var dateTime = TranslateUtils.ToDateTime($"{year}-1-1"); + dict.Add(dateTime, accessNum); + } + } + rdr.Close(); + } + return dict; + } + + /// + /// 统计管理员actionType的操作次数 + /// + public Dictionary GetAdminLoginDictionaryByName(DateTime dateFrom, DateTime dateTo, string actionType) + { + var dict = new Dictionary(); + + var builder = new StringBuilder(); + if (dateFrom > DateUtils.SqlMinValue) + { + builder.Append($" AND AddDate >= {SqlUtils.GetComparableDate(dateFrom)}"); + } + if (dateTo != DateUtils.SqlMinValue) + { + builder.Append($" AND AddDate < {SqlUtils.GetComparableDate(dateTo)}"); + } + + string sqlSelectTrackingDay = $@" +SELECT COUNT(*) AS AddNum, UserName FROM ( + SELECT {SqlUtils.GetDatePartYear("AddDate")} AS AddYear, {SqlUtils.GetDatePartMonth("AddDate")} AS AddMonth, {SqlUtils.GetDatePartDay("AddDate")} AS AddDay, UserName + FROM siteserver_Log + WHERE {SqlUtils.GetDateDiffLessThanDays("AddDate", 30.ToString())} {builder} +) DERIVEDTBL GROUP BY UserName ORDER BY AddNum DESC";//添加日统计 + + + using (var rdr = DataProvider.DatabaseApi.ExecuteReader(WebConfigUtils.ConnectionString, sqlSelectTrackingDay)) + { + while (rdr.Read()) + { + var accessNum = DataProvider.DatabaseApi.GetInt(rdr, 0); + var userName = DataProvider.DatabaseApi.GetString(rdr, 1); + dict.Add(userName, accessNum); + } + rdr.Close(); + } + return dict; + } + } +} + + +//using System; +//using System.Collections.Generic; +//using System.Data; +//using System.Text; +//using SiteServer.CMS.Database.Caches; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; +//using SiteServer.Utils.Enumerations; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class Log : DataProviderBase +// { +// public override string TableName => "siteserver_Log"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(LogInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(LogInfo.UserName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(LogInfo.IpAddress), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(LogInfo.AddDate), +// DataType = DataType.DateTime +// }, +// new TableColumn +// { +// AttributeName = nameof(LogInfo.Action), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(LogInfo.Summary), +// DataType = DataType.VarChar +// } +// }; + +// private const string ParamUserName = "@UserName"; +// private const string ParamIpAddress = "@IPAddress"; +// private const string ParamAddDate = "@AddDate"; +// private const string ParamAction = "@Action"; +// private const string ParamSummary = "@Summary"; + +// public void InsertObject(LogInfo log) +// { +// const string sqlString = "INSERT INTO siteserver_Log(UserName, IPAddress, AddDate, Action, Summary) VALUES (@UserName, @IPAddress, @AddDate, @Action, @Summary)"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamUserName, log.UserName), +// GetParameter(ParamIpAddress, log.IpAddress), +// GetParameter(ParamAddDate,log.AddDate), +// GetParameter(ParamAction, log.Action), +// GetParameter(ParamSummary, log.Summary) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// public void DeleteById(List idList) +// { +// if (idList != null && idList.Count > 0) +// { +// string sqlString = +// $"DELETE FROM siteserver_Log WHERE ID IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } +// } + +// public void DeleteIfThreshold() +// { +// if (!ConfigManager.Instance.IsTimeThreshold) return; + +// var days = ConfigManager.Instance.TimeThreshold; +// if (days <= 0) return; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, $@"DELETE FROM siteserver_Log WHERE AddDate < {SqlUtils.GetComparableDateTime(DateTime.Now.AddDays(-days))}"); +// } + +// public void DeleteAll() +// { +// const string sqlString = "DELETE FROM siteserver_Log"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } + +// public int GetCount() +// { +// var count = 0; +// const string sqlString = "SELECT Count(*) FROM siteserver_Log"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// if (rdr.Read() && !rdr.IsDBNull(0)) +// { +// count = DatabaseApi.GetInt(rdr, 0); +// } +// rdr.Close(); +// } + +// return count; +// } + +// public string GetSelectCommend() +// { +// return "SELECT ID, UserName, IPAddress, AddDate, Action, Summary FROM siteserver_Log"; +// } + +// public string GetSelectCommend(string userName, string keyword, string dateFrom, string dateTo) +// { +// if (string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(keyword) && string.IsNullOrEmpty(dateFrom) && string.IsNullOrEmpty(dateTo)) +// { +// return GetSelectCommend(); +// } + +// var whereString = new StringBuilder("WHERE "); + +// var isWhere = false; + +// if (!string.IsNullOrEmpty(userName)) +// { +// isWhere = true; +// whereString.AppendFormat("(UserName = '{0}')", AttackUtils.FilterSql(userName)); +// } + +// if (!string.IsNullOrEmpty(keyword)) +// { +// if (isWhere) +// { +// whereString.Append(" AND "); +// } +// isWhere = true; +// whereString.AppendFormat("(Action LIKE '%{0}%' OR Summary LIKE '%{0}%')", AttackUtils.FilterSql(keyword)); +// } + +// if (!string.IsNullOrEmpty(dateFrom)) +// { +// if (isWhere) +// { +// whereString.Append(" AND "); +// } +// isWhere = true; +// whereString.Append($"(AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))})"); +// } +// if (!string.IsNullOrEmpty(dateTo)) +// { +// if (isWhere) +// { +// whereString.Append(" AND "); +// } +// whereString.Append($"(AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo))})"); +// } + +// return "SELECT ID, UserName, IPAddress, AddDate, Action, Summary FROM siteserver_Log " + whereString; +// } + +// public DateTime GetLastRemoveLogDate(string userName) +// { +// var retVal = DateTime.MinValue; +// var sqlString = SqlDifferences.GetSqlString("siteserver_Log", new List +// { +// nameof(LogInfo.AddDate) +// }, +// "WHERE Action = '清空数据库日志'", "ORDER BY ID DESC", 1); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamUserName, userName) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// retVal = DatabaseApi.GetDateTime(rdr, 0); +// } +// rdr.Close(); +// } +// return retVal; +// } + +// /// +// /// 统计管理员actionType的操作次数 +// /// +// /// +// /// +// /// +// /// +// /// +// public Dictionary GetAdminLoginDictionaryByDate(DateTime dateFrom, DateTime dateTo, string xType, string actionType) +// { +// var dict = new Dictionary(); +// if (string.IsNullOrEmpty(xType)) +// { +// xType = EStatictisXTypeUtils.GetValueById(EStatictisXType.Day); +// } + +// var builder = new StringBuilder(); +// if (dateFrom > DateUtils.SqlMinValue) +// { +// builder.Append($" AND AddDate >= {SqlUtils.GetComparableDate(dateFrom)}"); +// } +// if (dateTo != DateUtils.SqlMinValue) +// { +// builder.Append($" AND AddDate < {SqlUtils.GetComparableDate(dateTo)}"); +// } + +// string sqlSelectTrackingDay = $@" +//SELECT COUNT(*) AS AddNum, AddYear, AddMonth, AddDay FROM ( +// SELECT {SqlUtils.GetDatePartYear("AddDate")} AS AddYear, {SqlUtils.GetDatePartMonth("AddDate")} AS AddMonth, {SqlUtils.GetDatePartDay("AddDate")} AS AddDay +// FROM siteserver_Log +// WHERE {SqlUtils.GetDateDiffLessThanDays("AddDate", 30.ToString())} {builder} +//) DERIVEDTBL GROUP BY AddYear, AddMonth, AddDay ORDER BY AddNum DESC";//添加日统计 + +// if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Month)) +// { +// sqlSelectTrackingDay = $@" +//SELECT COUNT(*) AS AddNum, AddYear, AddMonth FROM ( +// SELECT {SqlUtils.GetDatePartYear("AddDate")} AS AddYear, {SqlUtils.GetDatePartMonth("AddDate")} AS AddMonth +// FROM siteserver_Log +// WHERE {SqlUtils.GetDateDiffLessThanMonths("AddDate", 12.ToString())} {builder} +//) DERIVEDTBL GROUP BY AddYear, AddMonth ORDER BY AddNum DESC";//添加月统计 +// } +// else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Year)) +// { +// sqlSelectTrackingDay = $@" +//SELECT COUNT(*) AS AddNum, AddYear FROM ( +// SELECT {SqlUtils.GetDatePartYear("AddDate")} AS AddYear +// FROM siteserver_Log +// WHERE {SqlUtils.GetDateDiffLessThanYears("AddDate", 10.ToString())} {builder} +//) DERIVEDTBL GROUP BY AddYear ORDER BY AddNum DESC +//";//添加年统计 +// } + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlSelectTrackingDay)) +// { +// while (rdr.Read()) +// { +// var accessNum = DatabaseApi.GetInt(rdr, 0); +// if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Day)) +// { +// var year = DatabaseApi.GetString(rdr, 1); +// var month = DatabaseApi.GetString(rdr, 2); +// var day = DatabaseApi.GetString(rdr, 3); +// var dateTime = TranslateUtils.ToDateTime($"{year}-{month}-{day}"); +// dict.Add(dateTime, accessNum); +// } +// else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Month)) +// { +// var year = DatabaseApi.GetString(rdr, 1); +// var month = DatabaseApi.GetString(rdr, 2); + +// var dateTime = TranslateUtils.ToDateTime($"{year}-{month}-1"); +// dict.Add(dateTime, accessNum); +// } +// else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Year)) +// { +// var year = DatabaseApi.GetString(rdr, 1); +// var dateTime = TranslateUtils.ToDateTime($"{year}-1-1"); +// dict.Add(dateTime, accessNum); +// } +// } +// rdr.Close(); +// } +// return dict; +// } + +// /// +// /// 统计管理员actionType的操作次数 +// /// +// public Dictionary GetAdminLoginDictionaryByName(DateTime dateFrom, DateTime dateTo, string actionType) +// { +// var dict = new Dictionary(); + +// var builder = new StringBuilder(); +// if (dateFrom > DateUtils.SqlMinValue) +// { +// builder.Append($" AND AddDate >= {SqlUtils.GetComparableDate(dateFrom)}"); +// } +// if (dateTo != DateUtils.SqlMinValue) +// { +// builder.Append($" AND AddDate < {SqlUtils.GetComparableDate(dateTo)}"); +// } + +// string sqlSelectTrackingDay = $@" +//SELECT COUNT(*) AS AddNum, UserName FROM ( +// SELECT {SqlUtils.GetDatePartYear("AddDate")} AS AddYear, {SqlUtils.GetDatePartMonth("AddDate")} AS AddMonth, {SqlUtils.GetDatePartDay("AddDate")} AS AddDay, UserName +// FROM siteserver_Log +// WHERE {SqlUtils.GetDateDiffLessThanDays("AddDate", 30.ToString())} {builder} +//) DERIVEDTBL GROUP BY UserName ORDER BY AddNum DESC";//添加日统计 + + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlSelectTrackingDay)) +// { +// while (rdr.Read()) +// { +// var accessNum = DatabaseApi.GetInt(rdr, 0); +// var userName = DatabaseApi.GetString(rdr, 1); +// dict.Add(userName, accessNum); +// } +// rdr.Close(); +// } +// return dict; +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/PermissionsInRolesRepository.cs b/net452/SiteServer.CMS/Database/Repositories/PermissionsInRolesRepository.cs new file mode 100644 index 000000000..836238dbd --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/PermissionsInRolesRepository.cs @@ -0,0 +1,252 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class PermissionsInRolesRepository : Repository + { + public PermissionsInRolesRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string RoleName = nameof(PermissionsInRolesInfo.RoleName); + } + + //public override void Insert(PermissionsInRolesInfo info) + //{ + // //IDataParameter[] parameters = + // //{ + // // GetParameter(ParamRoleRoleName, info.RoleName), + // // GetParameter(ParamGeneralPermissions,info.GeneralPermissions) + // //}; + // //string SqlInsert = "INSERT INTO siteserver_PermissionsInRoles (RoleName, GeneralPermissions) VALUES (@RoleName, @GeneralPermissions)"; + // //DatabaseApi.ExecuteNonQuery(trans, SqlInsert, parameters); + + // InsertObject(info); + //} + + public override bool Delete(string roleName) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamRoleRoleName, roleName) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDelete, parameters); + + return base.Delete(Q + .Where(Attr.RoleName, roleName)) == 1; + } + + public void UpdateRoleAndGeneralPermissions(string roleName, string description, List generalPermissionList) + { + Delete(roleName); + if (generalPermissionList != null && generalPermissionList.Count > 0) + { + var permissionsInRolesInfo = new PermissionsInRolesInfo + { + RoleName = roleName, + GeneralPermissionList = generalPermissionList + }; + Insert(permissionsInRolesInfo); + } + + DataProvider.Role.UpdateRole(roleName, description); + } + + private PermissionsInRolesInfo GetPermissionsInRolesInfo(string roleName) + { + //PermissionsInRolesInfo info = null; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamRoleRoleName, roleName) + //}; + //string SqlSelect = "SELECT Id, RoleName, GeneralPermissions FROM siteserver_PermissionsInRoles WHERE RoleName = @RoleName"; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelect, parameters)) + //{ + // if (rdr.Read()) + // { + // var i = 0; + // info = new PermissionsInRolesInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i)); + // } + // rdr.Close(); + //} + //return info; + + return Get(Q.Where(Attr.RoleName, roleName)); + } + + public List GetGeneralPermissionList(IEnumerable roles) + { + var list = new List(); + if (roles == null) return list; + + foreach (var roleName in roles) + { + var permissionsInRolesInfo = GetPermissionsInRolesInfo(roleName); + if (permissionsInRolesInfo != null) + { + foreach (var permission in permissionsInRolesInfo.GeneralPermissionList) + { + if (!list.Contains(permission)) list.Add(permission); + } + } + } + + return list; + } + } +} + + +//using System.Collections.Generic; +//using System.Data; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class PermissionsInRoles : DataProviderBase +// { +// public override string TableName => "siteserver_PermissionsInRoles"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(PermissionsInRolesInfo.Id), +// DataType = DataType.Integer, +// IsPrimaryKey = true, +// IsIdentity = true +// }, +// new TableColumn +// { +// AttributeName = nameof(PermissionsInRolesInfo.RoleName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(PermissionsInRolesInfo.GeneralPermissions), +// DataType = DataType.Text +// } +// }; + +// private const string SqlSelect = "SELECT Id, RoleName, GeneralPermissions FROM siteserver_PermissionsInRoles WHERE RoleName = @RoleName"; + +// private const string SqlInsert = "INSERT INTO siteserver_PermissionsInRoles (RoleName, GeneralPermissions) VALUES (@RoleName, @GeneralPermissions)"; +// private const string SqlDelete = "DELETE FROM siteserver_PermissionsInRoles WHERE RoleName = @RoleName"; + +// private const string ParamRoleRoleName = "@RoleName"; +// private const string ParamGeneralPermissions = "@GeneralPermissions"; + +// public void InsertWithTrans(PermissionsInRolesInfo info, IDbTransaction trans) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamRoleRoleName, info.RoleName), +// GetParameter(ParamGeneralPermissions,info.GeneralPermissions) +// }; + +// DatabaseApi.ExecuteNonQuery(trans, SqlInsert, parameters); +// } + +// public void DeleteWithTrans(string roleName, IDbTransaction trans) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamRoleRoleName, roleName) +// }; + +// DatabaseApi.ExecuteNonQuery(trans, SqlDelete, parameters); +// } + +// public void DeleteById(string roleName) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamRoleRoleName, roleName) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDelete, parameters); +// } + +// public void UpdateRoleAndGeneralPermissions(string roleName, string description, List generalPermissionList) +// { +// using (var conn = GetConnection()) +// { +// conn.Open(); +// using (var trans = conn.BeginTransaction()) +// { +// try +// { +// DataProvider.PermissionsInRoles.DeleteWithTrans(roleName, trans); +// if (generalPermissionList != null && generalPermissionList.Count > 0) +// { +// var permissionsInRolesInfo = new PermissionsInRolesInfo(0, roleName, TranslateUtils.ObjectCollectionToString(generalPermissionList)); +// DataProvider.PermissionsInRoles.InsertWithTrans(permissionsInRolesInfo, trans); +// } + +// trans.Commit(); +// } +// catch +// { +// trans.Rollback(); +// throw; +// } +// } +// } + +// DataProvider.Role.UpdateRole(roleName, description); +// } + +// private PermissionsInRolesInfo GetPermissionsInRolesInfo(string roleName) +// { +// PermissionsInRolesInfo info = null; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamRoleRoleName, roleName) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelect, parameters)) +// { +// if (rdr.Read()) +// { +// var i = 0; +// info = new PermissionsInRolesInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i)); +// } +// rdr.Close(); +// } +// return info; +// } + +// public List GetGeneralPermissionList(IEnumerable roles) +// { +// var list = new List(); +// if (roles == null) return list; + +// foreach (var roleName in roles) +// { +// var permissionsInRolesInfo = GetPermissionsInRolesInfo(roleName); +// if (permissionsInRolesInfo != null) +// { +// var permissionList = TranslateUtils.StringCollectionToStringList(permissionsInRolesInfo.GeneralPermissions); +// foreach (var permission in permissionList) +// { +// if (!list.Contains(permission)) list.Add(permission); +// } +// } +// } + +// return list; +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/PluginConfigRepository.cs b/net452/SiteServer.CMS/Database/Repositories/PluginConfigRepository.cs new file mode 100644 index 000000000..fa4b604d0 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/PluginConfigRepository.cs @@ -0,0 +1,278 @@ +using Datory; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class PluginConfigRepository : Repository + { + public PluginConfigRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string PluginId = nameof(PluginConfigInfo.PluginId); + public const string SiteId = nameof(PluginConfigInfo.SiteId); + public const string ConfigName = nameof(PluginConfigInfo.ConfigName); + public const string ConfigValue = nameof(PluginConfigInfo.ConfigValue); + } + + //public void Insert(PluginConfigInfo configInfo) + //{ + // //const string sqlString = "INSERT INTO siteserver_PluginConfig(PluginId, SiteId, ConfigName, ConfigValue) VALUES (@PluginId, @SiteId, @ConfigName, @ConfigValue)"; + + // //IDataParameter[] parameters = + // //{ + // // GetParameter(ParamPluginId, configInfo.PluginId), + // // GetParameter(ParamSiteId, configInfo.SiteId), + // // GetParameter(ParamConfigName, configInfo.ConfigName), + // // GetParameter(ParamConfigValue,configInfo.ConfigValue) + // //}; + + // //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + // InsertObject(configInfo); + //} + + public void Delete(string pluginId, int siteId, string configName) + { + //const string sqlString = "DELETE FROM siteserver_PluginConfig WHERE PluginId = @PluginId AND SiteId = @SiteId AND ConfigName = @ConfigName"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamPluginId, pluginId), + // GetParameter(ParamSiteId, siteId), + // GetParameter(ParamConfigName, configName) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Delete(Q + .Where(Attr.SiteId, siteId) + .Where(Attr.PluginId, pluginId) + .Where(Attr.ConfigName, configName)); + } + + //public void Update(PluginConfigInfo configInfo) + //{ + // //const string sqlString = "UPDATE siteserver_PluginConfig SET ConfigValue = @ConfigValue WHERE PluginId = @PluginId AND SiteId = @SiteId AND ConfigName = @ConfigName"; + + // //IDataParameter[] parameters = + // //{ + // // GetParameter(ParamConfigValue,configInfo.ConfigValue), + // // GetParameter(ParamPluginId, configInfo.PluginId), + // // GetParameter(ParamSiteId, configInfo.SiteId), + // // GetParameter(ParamConfigName, configInfo.ConfigName) + // //}; + // //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + // UpdateObject(configInfo); + //} + + public string GetValue(string pluginId, int siteId, string configName) + { + //var value = string.Empty; + + //const string sqlString = "SELECT ConfigValue FROM siteserver_PluginConfig WHERE PluginId = @PluginId AND SiteId = @SiteId AND ConfigName = @ConfigName"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamPluginId, pluginId), + // GetParameter(ParamSiteId, siteId), + // GetParameter(ParamConfigName, configName) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read() && !rdr.IsDBNull(0)) + // { + // value = rdr.GetString(0); + // } + // rdr.Close(); + //} + + //return value; + + return Get(Q + .Select(Attr.ConfigValue) + .Where(Attr.SiteId, siteId) + .Where(Attr.PluginId, pluginId) + .Where(Attr.ConfigName, configName)); + } + + public bool IsExists(string pluginId, int siteId, string configName) + { + //var exists = false; + + //const string sqlString = "SELECT Id FROM siteserver_PluginConfig WHERE PluginId = @PluginId AND SiteId = @SiteId AND ConfigName = @ConfigName"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamPluginId, pluginId), + // GetParameter(ParamSiteId, siteId), + // GetParameter(ParamConfigName, configName) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read() && !rdr.IsDBNull(0)) + // { + // exists = true; + // } + // rdr.Close(); + //} + + //return exists; + + return Exists(Q + .Where(Attr.SiteId, siteId) + .Where(Attr.PluginId, pluginId) + .Where(Attr.ConfigName, configName)); + } + } +} + + +//using System.Collections.Generic; +//using System.Data; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class PluginConfig : DataProviderBase +// { +// public override string TableName => "siteserver_PluginConfig"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(PluginConfigInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(PluginConfigInfo.PluginId), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(PluginConfigInfo.SiteId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(PluginConfigInfo.ConfigName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(PluginConfigInfo.ConfigValue), +// DataType = DataType.Text +// } +// }; + +// private const string ParamPluginId = "@PluginId"; +// private const string ParamSiteId = "@SiteId"; +// private const string ParamConfigName = "@ConfigName"; +// private const string ParamConfigValue = "@ConfigValue"; + +// public void InsertObject(PluginConfigInfo configInfo) +// { +// const string sqlString = "INSERT INTO siteserver_PluginConfig(PluginId, SiteId, ConfigName, ConfigValue) VALUES (@PluginId, @SiteId, @ConfigName, @ConfigValue)"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamPluginId, configInfo.PluginId), +// GetParameter(ParamSiteId, configInfo.SiteId), +// GetParameter(ParamConfigName, configInfo.ConfigName), +// GetParameter(ParamConfigValue,configInfo.ConfigValue) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// public void DeleteById(string pluginId, int siteId, string configName) +// { +// const string sqlString = "DELETE FROM siteserver_PluginConfig WHERE PluginId = @PluginId AND SiteId = @SiteId AND ConfigName = @ConfigName"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamPluginId, pluginId), +// GetParameter(ParamSiteId, siteId), +// GetParameter(ParamConfigName, configName) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// public void UpdateObject(PluginConfigInfo configInfo) +// { +// const string sqlString = "UPDATE siteserver_PluginConfig SET ConfigValue = @ConfigValue WHERE PluginId = @PluginId AND SiteId = @SiteId AND ConfigName = @ConfigName"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamConfigValue,configInfo.ConfigValue), +// GetParameter(ParamPluginId, configInfo.PluginId), +// GetParameter(ParamSiteId, configInfo.SiteId), +// GetParameter(ParamConfigName, configInfo.ConfigName) +// }; +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// public string GetValueById(string pluginId, int siteId, string configName) +// { +// var value = string.Empty; + +// const string sqlString = "SELECT ConfigValue FROM siteserver_PluginConfig WHERE PluginId = @PluginId AND SiteId = @SiteId AND ConfigName = @ConfigName"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamPluginId, pluginId), +// GetParameter(ParamSiteId, siteId), +// GetParameter(ParamConfigName, configName) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read() && !rdr.IsDBNull(0)) +// { +// value = rdr.GetString(0); +// } +// rdr.Close(); +// } + +// return value; +// } + +// public bool IsExists(string pluginId, int siteId, string configName) +// { +// var exists = false; + +// const string sqlString = "SELECT Id FROM siteserver_PluginConfig WHERE PluginId = @PluginId AND SiteId = @SiteId AND ConfigName = @ConfigName"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamPluginId, pluginId), +// GetParameter(ParamSiteId, siteId), +// GetParameter(ParamConfigName, configName) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read() && !rdr.IsDBNull(0)) +// { +// exists = true; +// } +// rdr.Close(); +// } + +// return exists; +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/PluginRepository.cs b/net452/SiteServer.CMS/Database/Repositories/PluginRepository.cs new file mode 100644 index 000000000..c999356e7 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/PluginRepository.cs @@ -0,0 +1,280 @@ +using Datory; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class PluginRepository : Repository + { + public PluginRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string PluginId = nameof(PluginInfo.PluginId); + public const string IsDisabled = "IsDisabled"; + public const string Taxis = nameof(PluginInfo.Taxis); + } + + //public void DeleteById(string pluginId) + //{ + // //const string sqlString = "DELETE FROM siteserver_Plugin WHERE PluginId = @PluginId"; + + // //IDataParameter[] parameters = + // //{ + // // GetParameter(nameof(PluginConfigInfo.PluginId), pluginId) + // //}; + + // //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + // DeleteAll(new Query().Equal(Attr.PluginId, pluginId)); + //} + + public void UpdateIsDisabled(string pluginId, bool isDisabled) + { + //const string sqlString = "UPDATE siteserver_Plugin SET IsDisabled = @IsDisabled WHERE PluginId = @PluginId"; + + //IDataParameter[] parameters = + //{ + // GetParameter(nameof(PluginInstance.IsDisabled), isDisabled.ToString()), + // GetParameter(nameof(PluginConfigInfo.PluginId), pluginId) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Update(Q + .Set(Attr.IsDisabled, isDisabled.ToString()) + .Where(Attr.PluginId, pluginId) + ); + } + + public void UpdateTaxis(string pluginId, int taxis) + { + //const string sqlString = "UPDATE siteserver_Plugin SET Taxis = @Taxis WHERE PluginId = @PluginId"; + + //IDataParameter[] parameters = + //{ + // GetParameter(nameof(PluginInstance.Taxis), taxis), + // GetParameter(nameof(PluginConfigInfo.PluginId), pluginId) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Update(Q + .Set(Attr.Taxis, taxis) + .Where(Attr.PluginId, pluginId) + ); + } + + public void SetIsDisabledAndTaxis(string pluginId, out bool isDisabled, out int taxis) + { + isDisabled = false; + taxis = 0; + + //var exists = false; + + //var sqlString = "SELECT Id FROM siteserver_Plugin WHERE PluginId = @PluginId"; + + //IDataParameter[] parameters = + //{ + // GetParameter(nameof(PluginConfigInfo.PluginId), pluginId) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read() && !rdr.IsDBNull(0)) + // { + // exists = true; + // } + // rdr.Close(); + //} + + var exists = Exists(Q + .Where(Attr.PluginId, pluginId)); + + if (!exists) + { + //sqlString = "INSERT INTO siteserver_Plugin(PluginId, IsDisabled, Taxis) VALUES (@PluginId, @IsDisabled, @Taxis)"; + + //parameters = new[] + //{ + // GetParameter(nameof(PluginConfigInfo.PluginId), pluginId), + // GetParameter(nameof(PluginInstance.IsDisabled), false.ToString()), + // GetParameter(nameof(PluginInstance.Taxis), 0) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + base.Insert(new PluginInfo + { + PluginId = pluginId, + Disabled = false, + Taxis = 0 + }); + } + + //sqlString = "SELECT IsDisabled, Taxis FROM siteserver_Plugin WHERE PluginId = @PluginId"; + + //parameters = new[] + //{ + // GetParameter(nameof(PluginConfigInfo.PluginId), pluginId) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read() && !rdr.IsDBNull(0)) + // { + // isDisabled = TranslateUtils.ToBool(rdr.GetString(0)); + // taxis = rdr.GetInt32(1); + // } + // rdr.Close(); + //} + + var result = Get<(string IsDisabled, int Taxis)?> (Q + .Select(Attr.IsDisabled, Attr.Taxis) + .Where(Attr.PluginId, pluginId)); + + if (result == null) return; + + isDisabled = TranslateUtils.ToBool(result.Value.IsDisabled); + taxis = result.Value.Taxis; + } + } +} + + +//using System.Collections.Generic; +//using System.Data; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.CMS.Plugin; +//using SiteServer.Plugin; +//using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class PluginDao : DataProviderBase +// { +// public override string TableName => "siteserver_Plugin"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(PluginInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(PluginInfo.PluginId), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(PluginInfo.IsDisabled), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(PluginInfo.Taxis), +// DataType = DataType.Integer +// } +// }; + +// public void DeleteById(string pluginId) +// { +// const string sqlString = "DELETE FROM siteserver_Plugin WHERE PluginId = @PluginId"; + +// IDataParameter[] parameters = +// { +// GetParameter(nameof(PluginConfigInfo.PluginId), pluginId) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// public void UpdateIsDisabled(string pluginId, bool isDisabled) +// { +// const string sqlString = "UPDATE siteserver_Plugin SET IsDisabled = @IsDisabled WHERE PluginId = @PluginId"; + +// IDataParameter[] parameters = +// { +// GetParameter(nameof(PluginInstance.IsDisabled), isDisabled.ToString()), +// GetParameter(nameof(PluginConfigInfo.PluginId), pluginId) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// public void UpdateTaxis(string pluginId, int taxis) +// { +// const string sqlString = "UPDATE siteserver_Plugin SET Taxis = @Taxis WHERE PluginId = @PluginId"; + +// IDataParameter[] parameters = +// { +// GetParameter(nameof(PluginInstance.Taxis), taxis), +// GetParameter(nameof(PluginConfigInfo.PluginId), pluginId) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// public void SetIsDisabledAndTaxis(string pluginId, out bool isDisabled, out int taxis) +// { +// isDisabled = false; +// taxis = 0; + +// var exists = false; + +// var sqlString = "SELECT Id FROM siteserver_Plugin WHERE PluginId = @PluginId"; + +// IDataParameter[] parameters = +// { +// GetParameter(nameof(PluginConfigInfo.PluginId), pluginId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read() && !rdr.IsDBNull(0)) +// { +// exists = true; +// } +// rdr.Close(); +// } + +// if (!exists) +// { +// sqlString = "INSERT INTO siteserver_Plugin(PluginId, IsDisabled, Taxis) VALUES (@PluginId, @IsDisabled, @Taxis)"; + +// parameters = new[] +// { +// GetParameter(nameof(PluginConfigInfo.PluginId), pluginId), +// GetParameter(nameof(PluginInstance.IsDisabled), false.ToString()), +// GetParameter(nameof(PluginInstance.Taxis), 0) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// sqlString = "SELECT IsDisabled, Taxis FROM siteserver_Plugin WHERE PluginId = @PluginId"; + +// parameters = new [] +// { +// GetParameter(nameof(PluginConfigInfo.PluginId), pluginId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read() && !rdr.IsDBNull(0)) +// { +// isDisabled = TranslateUtils.ToBool(rdr.GetString(0)); +// taxis = rdr.GetInt32(1); +// } +// rdr.Close(); +// } +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/RelatedFieldItemRepository.cs b/net452/SiteServer.CMS/Database/Repositories/RelatedFieldItemRepository.cs new file mode 100644 index 000000000..5f60cb443 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/RelatedFieldItemRepository.cs @@ -0,0 +1,528 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class RelatedFieldItemRepository : Repository + { + public RelatedFieldItemRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(RelatedFieldItemInfo.Id); + public const string RelatedFieldId = nameof(RelatedFieldItemInfo.RelatedFieldId); + public const string ParentId = nameof(RelatedFieldItemInfo.ParentId); + public const string Taxis = nameof(RelatedFieldItemInfo.Taxis); + } + + public override int Insert(RelatedFieldItemInfo info) + { + info.Taxis = GetMaxTaxis(info.ParentId) + 1; + + //const string sqlString = "INSERT INTO siteserver_RelatedFieldItem (RelatedFieldID, ItemName, ItemValue, ParentID, Taxis) VALUES (@RelatedFieldID, @ItemName, @ItemValue, @ParentID, @Taxis)"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamRelatedFieldId, info.RelatedFieldId), + // GetParameter(ParamItemName, info.ItemName), + // GetParameter(ParamItemValue, info.ItemValue), + // GetParameter(ParamParentId, info.ParentId), + // GetParameter(ParamTaxis, info.Taxis) + //}; + + //return DatabaseApi.ExecuteNonQueryAndReturnId(ConnectionString, TableName, nameof(RelatedFieldItemInfo.Id), sqlString, parameters); + + info.Id = base.Insert(info); + return info.Id; + + //RelatedFieldManager.ClearCache(); + } + + //public override bool Update(RelatedFieldItemInfo info) + //{ + // //IDataParameter[] parameters = + // //{ + // // GetParameter(ParamItemName, info.ItemName), + // // GetParameter(ParamItemValue, info.ItemValue), + // // GetParameter(ParamId, info.Id) + // //}; + // //string SqlUpdate = "UPDATE siteserver_RelatedFieldItem SET ItemName = @ItemName, ItemValue = @ItemValue WHERE ID = @ID"; + // //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdate, parameters); + + // UpdateObject(info); + + // //RelatedFieldManager.ClearCache(); + //} + + //public void Delete(int id) + //{ + // //if (id > 0) + // //{ + // // string sqlString = $"DELETE FROM siteserver_RelatedFieldItem WHERE ID = {id} OR ParentID = {id}"; + // // DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + // //} + + // DeleteById(id); + + // //RelatedFieldManager.ClearCache(); + //} + + public IList GetRelatedFieldItemInfoList(int relatedFieldId, int parentId) + { + //var list = new List(); + + //string sqlString = + // $"SELECT ID, RelatedFieldID, ItemName, ItemValue, ParentID, Taxis FROM siteserver_RelatedFieldItem WHERE RelatedFieldID = {relatedFieldId} AND ParentID = {parentId} ORDER BY Taxis"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var info = new RelatedFieldItemInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i)); + // list.Add(info); + // } + // rdr.Close(); + //} + + //return list; + + return GetAll(Q + .Where(Attr.RelatedFieldId, relatedFieldId) + .Where(Attr.ParentId, parentId) + .OrderBy(Attr.Taxis)); + } + + public void UpdateTaxisToUp(int id, int parentId) + { + //Get Higher Taxis and ClassID + //string sqlString = + // $"SELECT TOP 1 ID, Taxis FROM siteserver_RelatedFieldItem WHERE ((Taxis > (SELECT Taxis FROM siteserver_RelatedFieldItem WHERE ID = {id})) AND ParentID = {parentId}) ORDER BY Taxis"; + //var sqlString = SqlDifferences.GetSqlString("siteserver_RelatedFieldItem", new List + //{ + // nameof(RelatedFieldItemInfo.Id), + // nameof(RelatedFieldItemInfo.Taxis) + //}, $"WHERE ((Taxis > (SELECT Taxis FROM siteserver_RelatedFieldItem WHERE ID = {id})) AND ParentID = {parentId})", "ORDER BY Taxis", 1); + + //var higherId = 0; + //var higherTaxis = 0; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // if (rdr.Read()) + // { + // higherId = DatabaseApi.GetInt(rdr, 0); + // higherTaxis = DatabaseApi.GetInt(rdr, 1); + // } + // rdr.Close(); + //} + + var selectedTaxis = GetTaxis(id); + var result = Get<(int Id, int Taxis)?>(Q + .Select(Attr.Id, Attr.Taxis) + .Where(Attr.Taxis, ">", selectedTaxis) + .Where(Attr.ParentId, parentId) + .OrderBy(Attr.Taxis)); + + if (result == null) return; + + var higherId = result.Value.Id; + var higherTaxis = result.Value.Taxis; + + ////Get Taxis Of Selected Class + //var selectedTaxis = GetTaxis(id); + + if (higherId != 0) + { + //Set The Selected Class Taxis To Higher Level + SetTaxis(id, higherTaxis); + //Set The Higher Class Taxis To Lower Level + SetTaxis(higherId, selectedTaxis); + } + + //RelatedFieldManager.ClearCache(); + } + + public void UpdateTaxisToDown(int id, int parentId) + { + //Get Lower Taxis and ClassID + //string sqlString = + // $"SELECT TOP 1 ID, Taxis FROM siteserver_RelatedFieldItem WHERE ((Taxis < (SELECT Taxis FROM siteserver_RelatedFieldItem WHERE (ID = {id}))) AND ParentID = {parentId}) ORDER BY Taxis DESC"; + //var sqlString = SqlDifferences.GetSqlString("siteserver_RelatedFieldItem", new List + //{ + // nameof(RelatedFieldItemInfo.Id), + // nameof(RelatedFieldItemInfo.Taxis) + //}, $"WHERE ((Taxis < (SELECT Taxis FROM siteserver_RelatedFieldItem WHERE (ID = {id}))) AND ParentID = {parentId})", "ORDER BY Taxis DESC", 1); + + //var lowerId = 0; + //var lowerTaxis = 0; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // if (rdr.Read()) + // { + // lowerId = DatabaseApi.GetInt(rdr, 0); + // lowerTaxis = DatabaseApi.GetInt(rdr, 1); + // } + // rdr.Close(); + //} + + var selectedTaxis = GetTaxis(id); + var result = Get<(int Id, int Taxis)?> (Q + .Select(Attr.Id, Attr.Taxis) + .Where(Attr.Taxis, "<", selectedTaxis) + .Where(Attr.ParentId, parentId) + .OrderByDesc(Attr.Taxis)); + + if (result == null) return; + + var lowerId = result.Value.Id; + var lowerTaxis = result.Value.Taxis; + + if (lowerId != 0) + { + //Set The Selected Class Taxis To Lower Level + SetTaxis(id, lowerTaxis); + //Set The Lower Class Taxis To Higher Level + SetTaxis(lowerId, selectedTaxis); + } + + //RelatedFieldManager.ClearCache(); + } + + private int GetTaxis(int id) + { + //string cmd = $"SELECT Taxis FROM siteserver_RelatedFieldItem WHERE (ID = {id})"; + //var taxis = 0; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, cmd)) + //{ + // if (rdr.Read()) + // { + // taxis = DatabaseApi.GetInt(rdr, 0); + // } + // rdr.Close(); + //} + //return taxis; + + return Get(Q + .Select(Attr.Taxis) + .Where(Attr.Id, id)); + } + + private void SetTaxis(int id, int taxis) + { + //string cmd = $"UPDATE siteserver_RelatedFieldItem SET Taxis = {taxis} WHERE ID = {id}"; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, cmd); + + Update(Q + .Set(Attr.Taxis, taxis) + .Where(Attr.Id, id) + ); + } + + private int GetMaxTaxis(int parentId) + { + //int maxTaxis; + //var cmd = + // $"SELECT MAX(Taxis) FROM siteserver_RelatedFieldItem WHERE ParentID = {parentId} AND Taxis <> {int.MaxValue}"; + //using (var conn = GetConnection()) + //{ + // conn.Open(); + // var o = DatabaseApi.ExecuteScalar(conn, cmd); + // maxTaxis = o is System.DBNull ? 0 : int.Parse(o.ToString()); + //} + //return maxTaxis; + + return Max(Q + .Select(Attr.Taxis) + .Where(Attr.ParentId, parentId)) ?? 0; + } + + public RelatedFieldItemInfo GetRelatedFieldItemInfo(int id) + { + //RelatedFieldItemInfo info = null; + + //string sqlString = + // $"SELECT ID, RelatedFieldID, ItemName, ItemValue, ParentID, Taxis FROM siteserver_RelatedFieldItem WHERE ID = {id}"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // if (rdr.Read()) + // { + // var i = 0; + // info = new RelatedFieldItemInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i)); + // } + // rdr.Close(); + //} + + //return info; + return Get(id); + } + } +} + +//using System.Collections.Generic; + //using System.Data; + //using SiteServer.CMS.Database.Core; + //using SiteServer.CMS.Database.Models; + //using SiteServer.Plugin; + //using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class RelatedFieldItem : DataProviderBase +// { +// public override string TableName => "siteserver_RelatedFieldItem"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(RelatedFieldItemInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(RelatedFieldItemInfo.RelatedFieldId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(RelatedFieldItemInfo.ItemName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(RelatedFieldItemInfo.ItemValue), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(RelatedFieldItemInfo.ParentId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(RelatedFieldItemInfo.Taxis), +// DataType = DataType.Integer +// } +// }; + +// private const string SqlUpdate = "UPDATE siteserver_RelatedFieldItem SET ItemName = @ItemName, ItemValue = @ItemValue WHERE ID = @ID"; + +// private const string ParamId = "@ID"; +// private const string ParamRelatedFieldId = "@RelatedFieldID"; +// private const string ParamItemName = "@ItemName"; +// private const string ParamItemValue = "@ItemValue"; +// private const string ParamParentId = "@ParentID"; +// private const string ParamTaxis = "@Taxis"; + +// public int InsertObject(RelatedFieldItemInfo info) +// { +// info.Taxis = GetMaxTaxis(info.ParentId) + 1; + +// const string sqlString = "INSERT INTO siteserver_RelatedFieldItem (RelatedFieldID, ItemName, ItemValue, ParentID, Taxis) VALUES (@RelatedFieldID, @ItemName, @ItemValue, @ParentID, @Taxis)"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamRelatedFieldId, info.RelatedFieldId), +// GetParameter(ParamItemName, info.ItemName), +// GetParameter(ParamItemValue, info.ItemValue), +// GetParameter(ParamParentId, info.ParentId), +// GetParameter(ParamTaxis, info.Taxis) +// }; + +// return DatabaseApi.ExecuteNonQueryAndReturnId(ConnectionString, TableName, nameof(RelatedFieldItemInfo.Id), sqlString, parameters); + +// //RelatedFieldManager.ClearCache(); +// } + +// public void UpdateObject(RelatedFieldItemInfo info) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamItemName, info.ItemName), +// GetParameter(ParamItemValue, info.ItemValue), +// GetParameter(ParamId, info.Id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdate, parameters); + +// //RelatedFieldManager.ClearCache(); +// } + +// public void DeleteById(int id) +// { +// if (id > 0) +// { +// string sqlString = $"DELETE FROM siteserver_RelatedFieldItem WHERE ID = {id} OR ParentID = {id}"; +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } +// //RelatedFieldManager.ClearCache(); +// } + +// public List GetRelatedFieldItemInfoList(int relatedFieldId, int parentId) +// { +// var list = new List(); + +// string sqlString = +// $"SELECT ID, RelatedFieldID, ItemName, ItemValue, ParentID, Taxis FROM siteserver_RelatedFieldItem WHERE RelatedFieldID = {relatedFieldId} AND ParentID = {parentId} ORDER BY Taxis"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var info = new RelatedFieldItemInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i)); +// list.Add(info); +// } +// rdr.Close(); +// } + +// return list; +// } + +// public void UpdateTaxisToUp(int id, int parentId) +// { +// //Get Higher Taxis and ClassID +// //string sqlString = +// // $"SELECT TOP 1 ID, Taxis FROM siteserver_RelatedFieldItem WHERE ((Taxis > (SELECT Taxis FROM siteserver_RelatedFieldItem WHERE ID = {id})) AND ParentID = {parentId}) ORDER BY Taxis"; +// var sqlString = SqlDifferences.GetSqlString("siteserver_RelatedFieldItem", new List +// { +// nameof(RelatedFieldItemInfo.Id), +// nameof(RelatedFieldItemInfo.Taxis) +// }, $"WHERE ((Taxis > (SELECT Taxis FROM siteserver_RelatedFieldItem WHERE ID = {id})) AND ParentID = {parentId})", "ORDER BY Taxis", 1); + +// var higherId = 0; +// var higherTaxis = 0; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// if (rdr.Read()) +// { +// higherId = DatabaseApi.GetInt(rdr, 0); +// higherTaxis = DatabaseApi.GetInt(rdr, 1); +// } +// rdr.Close(); +// } + +// //Get Taxis Of Selected Class +// var selectedTaxis = GetTaxis(id); + +// if (higherId != 0) +// { +// //Set The Selected Class Taxis To Higher Level +// SetTaxis(id, higherTaxis); +// //Set The Higher Class Taxis To Lower Level +// SetTaxis(higherId, selectedTaxis); +// } + +// //RelatedFieldManager.ClearCache(); +// } + +// public void UpdateTaxisToDown(int id, int parentId) +// { +// //Get Lower Taxis and ClassID +// //string sqlString = +// // $"SELECT TOP 1 ID, Taxis FROM siteserver_RelatedFieldItem WHERE ((Taxis < (SELECT Taxis FROM siteserver_RelatedFieldItem WHERE (ID = {id}))) AND ParentID = {parentId}) ORDER BY Taxis DESC"; +// var sqlString = SqlDifferences.GetSqlString("siteserver_RelatedFieldItem", new List +// { +// nameof(RelatedFieldItemInfo.Id), +// nameof(RelatedFieldItemInfo.Taxis) +// }, $"WHERE ((Taxis < (SELECT Taxis FROM siteserver_RelatedFieldItem WHERE (ID = {id}))) AND ParentID = {parentId})", "ORDER BY Taxis DESC", 1); + +// var lowerId = 0; +// var lowerTaxis = 0; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// if (rdr.Read()) +// { +// lowerId = DatabaseApi.GetInt(rdr, 0); +// lowerTaxis = DatabaseApi.GetInt(rdr, 1); +// } +// rdr.Close(); +// } + +// //Get Taxis Of Selected Class +// var selectedTaxis = GetTaxis(id); + +// if (lowerId != 0) +// { +// //Set The Selected Class Taxis To Lower Level +// SetTaxis(id, lowerTaxis); +// //Set The Lower Class Taxis To Higher Level +// SetTaxis(lowerId, selectedTaxis); +// } + +// //RelatedFieldManager.ClearCache(); +// } + +// private int GetTaxis(int id) +// { +// string cmd = $"SELECT Taxis FROM siteserver_RelatedFieldItem WHERE (ID = {id})"; +// var taxis = 0; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, cmd)) +// { +// if (rdr.Read()) +// { +// taxis = DatabaseApi.GetInt(rdr, 0); +// } +// rdr.Close(); +// } +// return taxis; +// } + +// private void SetTaxis(int id, int taxis) +// { +// string cmd = $"UPDATE siteserver_RelatedFieldItem SET Taxis = {taxis} WHERE ID = {id}"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, cmd); +// } + +// public int GetMaxTaxis(int parentId) +// { +// int maxTaxis; +// var cmd = +// $"SELECT MAX(Taxis) FROM siteserver_RelatedFieldItem WHERE ParentID = {parentId} AND Taxis <> {int.MaxValue}"; +// using (var conn = GetConnection()) +// { +// conn.Open(); +// var o = DatabaseApi.ExecuteScalar(conn, cmd); +// maxTaxis = o is System.DBNull ? 0 : int.Parse(o.ToString()); +// } +// return maxTaxis; +// } + +// public RelatedFieldItemInfo GetRelatedFieldItemInfo(int id) +// { +// RelatedFieldItemInfo info = null; + +// string sqlString = +// $"SELECT ID, RelatedFieldID, ItemName, ItemValue, ParentID, Taxis FROM siteserver_RelatedFieldItem WHERE ID = {id}"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// if (rdr.Read()) +// { +// var i = 0; +// info = new RelatedFieldItemInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i)); +// } +// rdr.Close(); +// } + +// return info; +// } + + +// } +//} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Database/Repositories/RelatedFieldRepository.cs b/net452/SiteServer.CMS/Database/Repositories/RelatedFieldRepository.cs new file mode 100644 index 000000000..fc3797914 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/RelatedFieldRepository.cs @@ -0,0 +1,457 @@ +using System; +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class RelatedFieldRepository : Repository + { + public RelatedFieldRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(RelatedFieldInfo.Id); + public const string Title = nameof(RelatedFieldInfo.Title); + public const string SiteId = nameof(RelatedFieldInfo.SiteId); + } + + //public int Insert(RelatedFieldInfo relatedFieldInfo) + //{ + // //const string sqlString = "INSERT INTO siteserver_RelatedField (Title, SiteId, TotalLevel, Prefixes, Suffixes) VALUES (@Title, @SiteId, @TotalLevel, @Prefixes, @Suffixes)"; + + // //IDataParameter[] parameters = + // //{ + // // GetParameter(ParamTitle, relatedFieldInfo.Title), + // // GetParameter(ParamSiteId, relatedFieldInfo.SiteId), + // // GetParameter(ParamTotalLevel, relatedFieldInfo.TotalLevel), + // // GetParameter(ParamPrefixes, relatedFieldInfo.Prefixes), + // // GetParameter(ParamSuffixes, relatedFieldInfo.Suffixes), + // //}; + + // //return DatabaseApi.ExecuteNonQueryAndReturnId(ConnectionString, TableName, nameof(RelatedFieldInfo.Id), sqlString, parameters); + + // return InsertObject(relatedFieldInfo); + //} + + //public void Update(RelatedFieldInfo relatedFieldInfo) + //{ + // //IDataParameter[] parameters = + // //{ + // // GetParameter(ParamTitle, relatedFieldInfo.Title), + // // GetParameter(ParamTotalLevel, relatedFieldInfo.TotalLevel), + // // GetParameter(ParamPrefixes, relatedFieldInfo.Prefixes), + // // GetParameter(ParamSuffixes, relatedFieldInfo.Suffixes), + // // GetParameter(ParamId, relatedFieldInfo.Id) + // //}; + // //string SqlUpdate = "UPDATE siteserver_RelatedField SET Title = @Title, TotalLevel = @TotalLevel, Prefixes = @Prefixes, Suffixes = @Suffixes WHERE Id = @Id"; + // //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdate, parameters); + + // UpdateObject(relatedFieldInfo); + //} + + //public void Delete(int id) + //{ + // //IDataParameter[] parameters = + // //{ + // // GetParameter(ParamId, id) + // //}; + // //string SqlDelete = "DELETE FROM siteserver_RelatedField WHERE Id = @Id"; + // //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDelete, parameters); + + // DeleteById(id); + //} + + //public RelatedFieldInfo Get(int id) + //{ + // return id <= 0 ? null : Get(id); + + // //RelatedFieldInfo relatedFieldInfo = null; + + // //var sqlString = + // // $"SELECT Id, Title, SiteId, TotalLevel, Prefixes, Suffixes FROM siteserver_RelatedField WHERE Id = {id}"; + + // //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + // //{ + // // if (rdr.Read()) + // // { + // // var i = 0; + // // relatedFieldInfo = new RelatedFieldInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i)); + // // } + // // rdr.Close(); + // //} + + // //return relatedFieldInfo; + //} + + public RelatedFieldInfo GetRelatedFieldInfo(int siteId, string title) + { + //RelatedFieldInfo relatedFieldInfo = null; + + //var sqlString = + // $"SELECT Id, Title, SiteId, TotalLevel, Prefixes, Suffixes FROM siteserver_RelatedField WHERE SiteId = {siteId} AND Title = @Title"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamTitle, relatedFieldName) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // var i = 0; + // relatedFieldInfo = new RelatedFieldInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i)); + // } + // rdr.Close(); + //} + + //return relatedFieldInfo; + return Get(Q + .Where(Attr.SiteId, siteId) + .Where(Attr.Title, title)); + } + + public string GetTitle(int id) + { + //var relatedFieldName = string.Empty; + + //var sqlString = + // $"SELECT Title FROM siteserver_RelatedField WHERE Id = {id}"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // if (rdr.Read()) + // { + // relatedFieldName = DatabaseApi.GetString(rdr, 0); + // } + // rdr.Close(); + //} + + //return relatedFieldName; + + return Get(Q + .Select(Attr.Title) + .Where(Attr.Id, id)); + } + + public IList GetRelatedFieldInfoList(int siteId) + { + //var list = new List(); + //var sqlString = + // $"SELECT Id, Title, SiteId, TotalLevel, Prefixes, Suffixes FROM siteserver_RelatedField WHERE SiteId = {siteId} ORDER BY Id"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // list.Add(new RelatedFieldInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i))); + // } + // rdr.Close(); + //} + + //return list; + + return GetAll(Q + .Where(Attr.SiteId, siteId) + .OrderBy(Attr.Id)); + } + + public IList GetTitleList(int siteId) + { + //var list = new List(); + //var sqlString = + // $"SELECT Title FROM siteserver_RelatedField WHERE SiteId = {siteId} ORDER BY Id"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetString(rdr, 0)); + // } + // rdr.Close(); + //} + + //return list; + + return GetAll(Q + .Select(Attr.Title) + .Where(Attr.SiteId, siteId) + .OrderBy(Attr.Id)); + } + + public string GetImportTitle(int siteId, string relatedFieldName) + { + string importName; + if (relatedFieldName.IndexOf("_", StringComparison.Ordinal) != -1) + { + var relatedFieldNameCount = 0; + var lastName = relatedFieldName.Substring(relatedFieldName.LastIndexOf("_", StringComparison.Ordinal) + 1); + var firstName = relatedFieldName.Substring(0, relatedFieldName.Length - lastName.Length); + try + { + relatedFieldNameCount = int.Parse(lastName); + } + catch + { + // ignored + } + relatedFieldNameCount++; + importName = firstName + relatedFieldNameCount; + } + else + { + importName = relatedFieldName + "_1"; + } + + var relatedFieldInfo = GetRelatedFieldInfo(siteId, relatedFieldName); + if (relatedFieldInfo != null) + { + importName = GetImportTitle(siteId, importName); + } + + return importName; + } + } +} + +//using System; + //using System.Collections.Generic; + //using System.Data; + //using SiteServer.CMS.Database.Core; + //using SiteServer.CMS.Database.Models; + //using SiteServer.Plugin; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class RelatedField : DataProviderBase +// { +// public override string TableName => "siteserver_RelatedField"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(RelatedFieldInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(RelatedFieldInfo.Title), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(RelatedFieldInfo.SiteId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(RelatedFieldInfo.TotalLevel), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(RelatedFieldInfo.Prefixes), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(RelatedFieldInfo.Suffixes), +// DataType = DataType.VarChar +// } +// }; + +// private const string SqlUpdate = "UPDATE siteserver_RelatedField SET Title = @Title, TotalLevel = @TotalLevel, Prefixes = @Prefixes, Suffixes = @Suffixes WHERE Id = @Id"; +// private const string SqlDelete = "DELETE FROM siteserver_RelatedField WHERE Id = @Id"; + +// private const string ParamId = "@Id"; +// private const string ParamTitle = "@Title"; +// private const string ParamSiteId = "@SiteId"; +// private const string ParamTotalLevel = "@TotalLevel"; +// private const string ParamPrefixes = "@Prefixes"; +// private const string ParamSuffixes = "@Suffixes"; + +// public int InsertObject(RelatedFieldInfo relatedFieldInfo) +// { +// const string sqlString = "INSERT INTO siteserver_RelatedField (Title, SiteId, TotalLevel, Prefixes, Suffixes) VALUES (@Title, @SiteId, @TotalLevel, @Prefixes, @Suffixes)"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamTitle, relatedFieldInfo.Title), +// GetParameter(ParamSiteId, relatedFieldInfo.SiteId), +// GetParameter(ParamTotalLevel, relatedFieldInfo.TotalLevel), +// GetParameter(ParamPrefixes, relatedFieldInfo.Prefixes), +// GetParameter(ParamSuffixes, relatedFieldInfo.Suffixes), +// }; + +// return DatabaseApi.ExecuteNonQueryAndReturnId(ConnectionString, TableName, nameof(RelatedFieldInfo.Id), sqlString, parameters); +// } + +// public void UpdateObject(RelatedFieldInfo relatedFieldInfo) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamTitle, relatedFieldInfo.Title), +// GetParameter(ParamTotalLevel, relatedFieldInfo.TotalLevel), +// GetParameter(ParamPrefixes, relatedFieldInfo.Prefixes), +// GetParameter(ParamSuffixes, relatedFieldInfo.Suffixes), +// GetParameter(ParamId, relatedFieldInfo.Id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdate, parameters); +// } + +// public void DeleteById(int id) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamId, id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDelete, parameters); +// } + +// public RelatedFieldInfo GetRelatedFieldInfo(int id) +// { +// if (id <= 0) return null; + +// RelatedFieldInfo relatedFieldInfo = null; + +// var sqlString = +// $"SELECT Id, Title, SiteId, TotalLevel, Prefixes, Suffixes FROM siteserver_RelatedField WHERE Id = {id}"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// if (rdr.Read()) +// { +// var i = 0; +// relatedFieldInfo = new RelatedFieldInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i)); +// } +// rdr.Close(); +// } + +// return relatedFieldInfo; +// } + +// public RelatedFieldInfo GetRelatedFieldInfo(int siteId, string relatedFieldName) +// { +// RelatedFieldInfo relatedFieldInfo = null; + +// var sqlString = +// $"SELECT Id, Title, SiteId, TotalLevel, Prefixes, Suffixes FROM siteserver_RelatedField WHERE SiteId = {siteId} AND Title = @Title"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamTitle, relatedFieldName) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// var i = 0; +// relatedFieldInfo = new RelatedFieldInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i)); +// } +// rdr.Close(); +// } + +// return relatedFieldInfo; +// } + +// public string GetTitle(int id) +// { +// var relatedFieldName = string.Empty; + +// var sqlString = +// $"SELECT Title FROM siteserver_RelatedField WHERE Id = {id}"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// if (rdr.Read()) +// { +// relatedFieldName = DatabaseApi.GetString(rdr, 0); +// } +// rdr.Close(); +// } + +// return relatedFieldName; +// } + +// public List GetRelatedFieldInfoList(int siteId) +// { +// var list = new List(); +// var sqlString = +// $"SELECT Id, Title, SiteId, TotalLevel, Prefixes, Suffixes FROM siteserver_RelatedField WHERE SiteId = {siteId} ORDER BY Id"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// list.Add(new RelatedFieldInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i))); +// } +// rdr.Close(); +// } + +// return list; +// } + +// public List GetTitleList(int siteId) +// { +// var list = new List(); +// var sqlString = +// $"SELECT Title FROM siteserver_RelatedField WHERE SiteId = {siteId} ORDER BY Id"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// list.Add(DatabaseApi.GetString(rdr, 0)); +// } +// rdr.Close(); +// } + +// return list; +// } + +// public string GetImportTitle(int siteId, string relatedFieldName) +// { +// string importName; +// if (relatedFieldName.IndexOf("_", StringComparison.Ordinal) != -1) +// { +// var relatedFieldNameCount = 0; +// var lastName = relatedFieldName.Substring(relatedFieldName.LastIndexOf("_", StringComparison.Ordinal) + 1); +// var firstName = relatedFieldName.Substring(0, relatedFieldName.Length - lastName.Length); +// try +// { +// relatedFieldNameCount = int.Parse(lastName); +// } +// catch +// { +// // ignored +// } +// relatedFieldNameCount++; +// importName = firstName + relatedFieldNameCount; +// } +// else +// { +// importName = relatedFieldName + "_1"; +// } + +// var relatedFieldInfo = GetRelatedFieldInfo(siteId, relatedFieldName); +// if (relatedFieldInfo != null) +// { +// importName = GetImportTitle(siteId, importName); +// } + +// return importName; +// } +// } +//} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Database/Repositories/RoleRepository.cs b/net452/SiteServer.CMS/Database/Repositories/RoleRepository.cs new file mode 100644 index 000000000..6813b9058 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/RoleRepository.cs @@ -0,0 +1,362 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Database.Repositories +{ + public class RoleRepository : Repository + { + public RoleRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string RoleName = nameof(RoleInfo.RoleName); + public const string CreatorUserName = nameof(RoleInfo.CreatorUserName); + public const string Description = nameof(RoleInfo.Description); + } + + public string GetRoleDescription(string roleName) + { + //var roleDescription = string.Empty; + //const string sqlString = "SELECT Description FROM siteserver_Role WHERE RoleName = @RoleName"; + //IDataParameter[] parameters = + //{ + // GetParameter(ParamRoleName, roleName) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // roleDescription = DatabaseApi.GetString(rdr, 0); + // } + // rdr.Close(); + //} + //return roleDescription; + + return Get(Q + .Select(Attr.Description) + .Where(Attr.RoleName, roleName)); + } + + public IList GetRoleNameList() + { + //var list = new List(); + //const string sqlSelect = "SELECT RoleName FROM siteserver_Role ORDER BY RoleName"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlSelect)) + //{ + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetString(rdr, 0)); + // } + // rdr.Close(); + //} + + //return list; + + return GetAll(Q + .Select(Attr.RoleName) + .OrderBy(Attr.RoleName)); + } + + public IList GetRoleNameListByCreatorUserName(string creatorUserName) + { + //var list = new List(); + + //if (string.IsNullOrEmpty(creatorUserName)) return list; + + //const string sqlString = "SELECT RoleName FROM siteserver_Role WHERE CreatorUserName = @CreatorUserName"; + //IDataParameter[] parameters = + //{ + // GetParameter(ParamCreatorUsername, creatorUserName) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetString(rdr, 0)); + // } + // rdr.Close(); + //} + //return list; + + if (string.IsNullOrEmpty(creatorUserName)) return new List(); + + return GetAll(Q + .Select(Attr.RoleName) + .Where(Attr.CreatorUserName, creatorUserName) + .OrderBy(Attr.RoleName)); + } + + public void InsertRole(RoleInfo roleInfo) + { + if (EPredefinedRoleUtils.IsPredefinedRole(roleInfo.RoleName)) return; + + //const string sqlString = "INSERT INTO siteserver_Role (RoleName, CreatorUserName, Description) VALUES (@RoleName, @CreatorUserName, @Description)"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamRoleName, roleInfo.RoleName), + // GetParameter(ParamCreatorUsername, roleInfo.CreatorUserName), + // GetParameter(ParamDescription, roleInfo.Description) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Insert(roleInfo); + } + + public void UpdateRole(string roleName, string description) + { + //const string sqlString = "UPDATE siteserver_Role SET Description = @Description WHERE RoleName = @RoleName"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamDescription, description), + // GetParameter(ParamRoleName, roleName) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Update(Q + .Set(Attr.Description, description) + .Where(Attr.RoleName, roleName) + ); + } + + + public void DeleteRole(string roleName) + { + //var isSuccess = false; + //try + //{ + // const string sqlString = "DELETE FROM siteserver_Role WHERE RoleName = @RoleName"; + + // IDataParameter[] parameters = + // { + // GetParameter(ParamRoleName, roleName) + // }; + + // DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + // isSuccess = true; + //} + //catch + //{ + // // ignored + //} + //return isSuccess; + + Delete(Q.Where(Attr.RoleName, roleName)); + } + + public bool IsRoleExists(string roleName) + { + //var exists = false; + //const string sqlString = "SELECT RoleName FROM siteserver_Role WHERE RoleName = @RoleName"; + //IDataParameter[] parameters = + //{ + // GetParameter("@RoleName", roleName) + //}; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // if (!rdr.IsDBNull(0)) + // { + // exists = true; + // } + // } + // rdr.Close(); + //} + //return exists; + + return Exists(Q.Where(Attr.RoleName, roleName)); + } + } +} + + +//using System.Collections.Generic; +//using System.Data; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils.Enumerations; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class Role : DataProviderBase +// { +// public override string TableName => "siteserver_Role"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(RoleInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(RoleInfo.RoleName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(RoleInfo.CreatorUserName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(RoleInfo.Description), +// DataType = DataType.VarChar +// } +// }; + +// private const string ParamRoleName = "@RoleName"; +// private const string ParamCreatorUsername= "@CreatorUserName"; +// private const string ParamDescription = "@Description"; + +// public string GetRoleDescription(string roleName) +// { +// var roleDescription = string.Empty; +// const string sqlString = "SELECT Description FROM siteserver_Role WHERE RoleName = @RoleName"; +// IDataParameter[] parameters = +// { +// GetParameter(ParamRoleName, roleName) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// roleDescription = DatabaseApi.GetString(rdr, 0); +// } +// rdr.Close(); +// } +// return roleDescription; +// } + +// public List GetRoleNameList() +// { +// var list = new List(); +// const string sqlSelect = "SELECT RoleName FROM siteserver_Role ORDER BY RoleName"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlSelect)) +// { +// while (rdr.Read()) +// { +// list.Add(DatabaseApi.GetString(rdr, 0)); +// } +// rdr.Close(); +// } + +// return list; +// } + +// public List GetRoleNameListByCreatorUserName(string creatorUserName) +// { +// var list = new List(); + +// if (string.IsNullOrEmpty(creatorUserName)) return list; + +// const string sqlString = "SELECT RoleName FROM siteserver_Role WHERE CreatorUserName = @CreatorUserName"; +// IDataParameter[] parameters = +// { +// GetParameter(ParamCreatorUsername, creatorUserName) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// while (rdr.Read()) +// { +// list.Add(DatabaseApi.GetString(rdr, 0)); +// } +// rdr.Close(); +// } +// return list; +// } + +// public void InsertRole(RoleInfo roleInfo) +// { +// if (EPredefinedRoleUtils.IsPredefinedRole(roleInfo.RoleName)) return; + +// const string sqlString = "INSERT INTO siteserver_Role (RoleName, CreatorUserName, Description) VALUES (@RoleName, @CreatorUserName, @Description)"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamRoleName, roleInfo.RoleName), +// GetParameter(ParamCreatorUsername, roleInfo.CreatorUserName), +// GetParameter(ParamDescription, roleInfo.Description) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// public virtual void UpdateRole(string roleName, string description) +// { +// const string sqlString = "UPDATE siteserver_Role SET Description = @Description WHERE RoleName = @RoleName"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamDescription, description), +// GetParameter(ParamRoleName, roleName) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + + +// public bool DeleteRole(string roleName) +// { +// var isSuccess = false; +// try +// { +// const string sqlString = "DELETE FROM siteserver_Role WHERE RoleName = @RoleName"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamRoleName, roleName) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// isSuccess = true; +// } +// catch +// { +// // ignored +// } +// return isSuccess; +// } + +// public bool IsRoleExists(string roleName) +// { +// var exists = false; +// const string sqlString = "SELECT RoleName FROM siteserver_Role WHERE RoleName = @RoleName"; +// IDataParameter[] parameters = +// { +// GetParameter("@RoleName", roleName) +// }; +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// if (!rdr.IsDBNull(0)) +// { +// exists = true; +// } +// } +// rdr.Close(); +// } +// return exists; +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/SiteLogRepository.cs b/net452/SiteServer.CMS/Database/Repositories/SiteLogRepository.cs new file mode 100644 index 000000000..1e4f41d32 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/SiteLogRepository.cs @@ -0,0 +1,365 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class SiteLogRepository : Repository + { + public SiteLogRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(SiteLogInfo.Id); + public const string AddDate = nameof(SiteLogInfo.AddDate); + } + + //public void Insert(SiteLogInfo logInfo) + //{ + // //const string sqlString = "INSERT INTO siteserver_SiteLog(SiteId, ChannelId, ContentId, UserName, IpAddress, AddDate, Action, Summary) VALUES (@SiteId, @ChannelId, @ContentId, @UserName, @IpAddress, @AddDate, @Action, @Summary)"; + + // //IDataParameter[] parameters = + // //{ + // // GetParameter(ParamSiteId, logInfo.SiteId), + // // GetParameter(ParamChannelId, logInfo.ChannelId), + // // GetParameter(ParamContentId, logInfo.ContentId), + // // GetParameter(ParamUserName, logInfo.UserName), + // // GetParameter(ParamIpAddress, logInfo.IpAddress), + // // GetParameter(ParamAddDate,logInfo.AddDate), + // // GetParameter(ParamAction, logInfo.Action), + // // GetParameter(ParamSummary, logInfo.Summary) + // //}; + + // //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + // InsertObject(logInfo); + //} + + public void DeleteIfThreshold() + { + if (!ConfigManager.Instance.IsTimeThreshold) return; + + var days = ConfigManager.Instance.TimeThreshold; + if (days <= 0) return; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, $@"DELETE FROM siteserver_SiteLog WHERE AddDate < {SqlUtils.GetComparableDateTime(DateTime.Now.AddDays(-days))}"); + + Delete(Q.Where(Attr.AddDate, "<", DateTime.Now.AddDays(-days))); + } + + public void Delete(List idList) + { + if (idList == null || idList.Count <= 0) return; + + //var sqlString = + // $"DELETE FROM siteserver_SiteLog WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + Delete(Q.WhereIn(Attr.Id, idList)); + } + + public void DeleteAll() + { + //const string sqlString = "DELETE FROM siteserver_SiteLog"; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + base.Delete(); + } + + public string GetSelectCommend() + { + return "SELECT Id, SiteId, ChannelId, ContentId, UserName, IpAddress, AddDate, Action, Summary FROM siteserver_SiteLog"; + } + + public string GetSelectCommend(int siteId, string logType, string userName, string keyword, string dateFrom, string dateTo) + { + if (siteId == 0 && (string.IsNullOrEmpty(logType) || StringUtils.EqualsIgnoreCase(logType, "All")) && string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(keyword) && string.IsNullOrEmpty(dateFrom) && string.IsNullOrEmpty(dateTo)) + { + return GetSelectCommend(); + } + + var whereString = new StringBuilder("WHERE "); + + var isWhere = false; + + if (siteId > 0) + { + isWhere = true; + whereString.AppendFormat("(SiteId = {0})", siteId); + } + + if (!string.IsNullOrEmpty(logType) && !StringUtils.EqualsIgnoreCase(logType, "All")) + { + if (isWhere) + { + whereString.Append(" AND "); + } + isWhere = true; + + if (StringUtils.EqualsIgnoreCase(logType, "Channel")) + { + whereString.Append("(ChannelId > 0 AND ContentId = 0)"); + } + else if (StringUtils.EqualsIgnoreCase(logType, "Content")) + { + whereString.Append("(ChannelId > 0 AND ContentId > 0)"); + } + } + + if (!string.IsNullOrEmpty(userName)) + { + if (isWhere) + { + whereString.Append(" AND "); + } + isWhere = true; + whereString.AppendFormat("(UserName = '{0}')", userName); + } + + if (!string.IsNullOrEmpty(keyword)) + { + if (isWhere) + { + whereString.Append(" AND "); + } + isWhere = true; + whereString.AppendFormat("(Action LIKE '%{0}%' OR Summary LIKE '%{0}%')", AttackUtils.FilterSql(keyword)); + } + + if (!string.IsNullOrEmpty(dateFrom)) + { + if (isWhere) + { + whereString.Append(" AND "); + } + isWhere = true; + whereString.Append($"(AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))})"); + } + if (!string.IsNullOrEmpty(dateTo)) + { + if (isWhere) + { + whereString.Append(" AND "); + } + whereString.Append($"(AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo))})"); + } + + return "SELECT Id, SiteId, ChannelId, ContentId, UserName, IpAddress, AddDate, Action, Summary FROM siteserver_SiteLog " + whereString; + } + } +} + + +//using System; +//using System.Collections.Generic; +//using System.Data; +//using System.Text; +//using SiteServer.CMS.Database.Caches; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class SiteLog : DataProviderBase +// { +// public override string TableName => "siteserver_SiteLog"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(SiteLogInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(SiteLogInfo.SiteId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(SiteLogInfo.ChannelId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(SiteLogInfo.ContentId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(SiteLogInfo.UserName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(SiteLogInfo.IpAddress), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(SiteLogInfo.AddDate), +// DataType = DataType.DateTime +// }, +// new TableColumn +// { +// AttributeName = nameof(SiteLogInfo.Action), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(SiteLogInfo.Summary), +// DataType = DataType.VarChar +// } +// }; + +// private const string ParamSiteId = "@SiteId"; +// private const string ParamChannelId = "@ChannelId"; +// private const string ParamContentId = "@ContentId"; +// private const string ParamUserName = "@UserName"; +// private const string ParamIpAddress = "@IpAddress"; +// private const string ParamAddDate = "@AddDate"; +// private const string ParamAction = "@Action"; +// private const string ParamSummary = "@Summary"; + +// public void InsertObject(SiteLogInfo logInfo) +// { +// const string sqlString = "INSERT INTO siteserver_SiteLog(SiteId, ChannelId, ContentId, UserName, IpAddress, AddDate, Action, Summary) VALUES (@SiteId, @ChannelId, @ContentId, @UserName, @IpAddress, @AddDate, @Action, @Summary)"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamSiteId, logInfo.SiteId), +// GetParameter(ParamChannelId, logInfo.ChannelId), +// GetParameter(ParamContentId, logInfo.ContentId), +// GetParameter(ParamUserName, logInfo.UserName), +// GetParameter(ParamIpAddress, logInfo.IpAddress), +// GetParameter(ParamAddDate,logInfo.AddDate), +// GetParameter(ParamAction, logInfo.Action), +// GetParameter(ParamSummary, logInfo.Summary) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// public void DeleteIfThreshold() +// { +// if (!ConfigManager.Instance.IsTimeThreshold) return; + +// var days = ConfigManager.Instance.TimeThreshold; +// if (days <= 0) return; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, $@"DELETE FROM siteserver_SiteLog WHERE AddDate < {SqlUtils.GetComparableDateTime(DateTime.Now.AddDays(-days))}"); +// } + +// public void DeleteById(List idList) +// { +// if (idList == null || idList.Count <= 0) return; + +// var sqlString = +// $"DELETE FROM siteserver_SiteLog WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } + +// public void DeleteAll() +// { +// const string sqlString = "DELETE FROM siteserver_SiteLog"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } + +// public string GetSelectCommend() +// { +// return "SELECT Id, SiteId, ChannelId, ContentId, UserName, IpAddress, AddDate, Action, Summary FROM siteserver_SiteLog"; +// } + +// public string GetSelectCommend(int siteId, string logType, string userName, string keyword, string dateFrom, string dateTo) +// { +// if (siteId == 0 && (string.IsNullOrEmpty(logType) || StringUtils.EqualsIgnoreCase(logType, "All")) && string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(keyword) && string.IsNullOrEmpty(dateFrom) && string.IsNullOrEmpty(dateTo)) +// { +// return GetSelectCommend(); +// } + +// var whereString = new StringBuilder("WHERE "); + +// var isWhere = false; + +// if (siteId > 0) +// { +// isWhere = true; +// whereString.AppendFormat("(SiteId = {0})", siteId); +// } + +// if (!string.IsNullOrEmpty(logType) && !StringUtils.EqualsIgnoreCase(logType, "All")) +// { +// if (isWhere) +// { +// whereString.Append(" AND "); +// } +// isWhere = true; + +// if (StringUtils.EqualsIgnoreCase(logType, "Channel")) +// { +// whereString.Append("(ChannelId > 0 AND ContentId = 0)"); +// } +// else if (StringUtils.EqualsIgnoreCase(logType, "Content")) +// { +// whereString.Append("(ChannelId > 0 AND ContentId > 0)"); +// } +// } + +// if (!string.IsNullOrEmpty(userName)) +// { +// if (isWhere) +// { +// whereString.Append(" AND "); +// } +// isWhere = true; +// whereString.AppendFormat("(UserName = '{0}')", userName); +// } + +// if (!string.IsNullOrEmpty(keyword)) +// { +// if (isWhere) +// { +// whereString.Append(" AND "); +// } +// isWhere = true; +// whereString.AppendFormat("(Action LIKE '%{0}%' OR Summary LIKE '%{0}%')", AttackUtils.FilterSql(keyword)); +// } + +// if (!string.IsNullOrEmpty(dateFrom)) +// { +// if (isWhere) +// { +// whereString.Append(" AND "); +// } +// isWhere = true; +// whereString.Append($"(AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))})"); +// } +// if (!string.IsNullOrEmpty(dateTo)) +// { +// if (isWhere) +// { +// whereString.Append(" AND "); +// } +// whereString.Append($"(AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo))})"); +// } + +// return "SELECT Id, SiteId, ChannelId, ContentId, UserName, IpAddress, AddDate, Action, Summary FROM siteserver_SiteLog " + whereString; +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/SitePermissionsRepository.cs b/net452/SiteServer.CMS/Database/Repositories/SitePermissionsRepository.cs new file mode 100644 index 000000000..a4b7777a7 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/SitePermissionsRepository.cs @@ -0,0 +1,571 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class SitePermissionsRepository : Repository + { + public SitePermissionsRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string RoleName = nameof(SitePermissionsInfo.RoleName); + public const string SiteId = nameof(SitePermissionsInfo.SiteId); + } + + public override int Insert(SitePermissionsInfo permissionsInfo) + { + if (IsExists(permissionsInfo.RoleName, permissionsInfo.SiteId)) + { + Delete(permissionsInfo.RoleName, permissionsInfo.SiteId); + } + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamRoleRoleName, permissionsInfo.RoleName), + // GetParameter(ParamSiteId, permissionsInfo.SiteId), + // GetParameter(ParamChannelIdCollection,permissionsInfo.ChannelIdCollection), + // GetParameter(ParamChannelPermissions,permissionsInfo.ChannelPermissions), + // GetParameter(ParamWebsitePermissions,permissionsInfo.WebsitePermissions) + //}; + //string SqlInsert = "INSERT INTO siteserver_SitePermissions (RoleName, SiteId, ChannelIdCollection, ChannelPermissions, WebsitePermissions) VALUES (@RoleName, @SiteId, @ChannelIdCollection, @ChannelPermissions, @WebsitePermissions)"; + //DatabaseApi.ExecuteNonQuery(WebConfigUtils.ConnectionString, SqlInsert, parameters); + + return base.Insert(permissionsInfo); + } + + + public override bool Delete(string roleName) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamRoleRoleName, roleName) + //}; + //string SqlDelete = "DELETE FROM siteserver_SitePermissions WHERE RoleName = @RoleName"; + //DatabaseApi.ExecuteNonQuery(WebConfigUtils.ConnectionString, SqlDelete, parameters); + + return Delete(Q.Where(Attr.RoleName, roleName)) == 1; + } + + private void Delete(string roleName, int siteId) + { + //const string sqlString = "DELETE FROM siteserver_SitePermissions WHERE RoleName = @RoleName AND SiteId = @SiteId"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamRoleRoleName, roleName), + // GetParameter(ParamSiteId, siteId) + //}; + + //DatabaseApi.ExecuteNonQuery(WebConfigUtils.ConnectionString, sqlString, parameters); + + Delete(Q.Where(Attr.RoleName, roleName).Where(Attr.SiteId, siteId)); + } + + private bool IsExists(string roleName, int siteId) + { + //var isExists = false; + + //const string sqlString = "SELECT RoleName FROM siteserver_SitePermissions WHERE RoleName = @RoleName AND SiteId = @SiteId"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamRoleRoleName, roleName), + // GetParameter(ParamSiteId, siteId) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(WebConfigUtils.ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // isExists = true; + // } + // rdr.Close(); + //} + + //return isExists; + + return Exists(Q.Where(Attr.RoleName, roleName).Where(Attr.SiteId, siteId)); + } + + public IList GetSystemPermissionsInfoList(string roleName) + { + //var list = new List(); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamRoleRoleName, roleName) + //}; + //string SqlSelectAllByRoleName = "SELECT RoleName, SiteId, ChannelIdCollection, ChannelPermissions, WebsitePermissions FROM siteserver_SitePermissions WHERE RoleName = @RoleName ORDER BY SiteId DESC"; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAllByRoleName, parameters)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var permissionsInfo = new SitePermissionsInfo(DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i)); + // list.Add(permissionsInfo); + // } + // rdr.Close(); + //} + + //return list; + + return GetAll(Q.Where(Attr.RoleName, roleName).OrderByDesc(Attr.SiteId)); + } + + public Dictionary> GetWebsitePermissionSortedList(IEnumerable roles) + { + var sortedList = new Dictionary>(); + if (roles == null) return sortedList; + + foreach (var roleName in roles) + { + var systemPermissionsList = GetSystemPermissionsInfoList(roleName); + foreach (var systemPermissionsInfo in systemPermissionsList) + { + var list = new List(); + var websitePermissionList = TranslateUtils.StringCollectionToStringList(systemPermissionsInfo.WebsitePermissions); + foreach (var websitePermission in websitePermissionList) + { + if (!list.Contains(websitePermission)) list.Add(websitePermission); + } + sortedList[systemPermissionsInfo.SiteId] = list; + } + } + + return sortedList; + } + + public Dictionary> GetChannelPermissionSortedList(IList roles) + { + var dict = new Dictionary>(); + if (roles == null) return dict; + + foreach (var roleName in roles) + { + var systemPermissionsInfoList = GetSystemPermissionsInfoList(roleName); + foreach (var systemPermissionsInfo in systemPermissionsInfoList) + { + var channelIdList = TranslateUtils.StringCollectionToIntList(systemPermissionsInfo.ChannelIdCollection); + foreach (var channelId in channelIdList) + { + var key = PermissionsImpl.GetChannelPermissionDictKey(systemPermissionsInfo.SiteId, channelId); + + if (!dict.TryGetValue(key, out var list)) + { + list = new List(); + dict[key] = list; + } + + var channelPermissionList = TranslateUtils.StringCollectionToStringList(systemPermissionsInfo.ChannelPermissions); + foreach (var channelPermission in channelPermissionList) + { + if (!list.Contains(channelPermission)) list.Add(channelPermission); + } + } + } + } + + return dict; + } + + public List GetChannelPermissionListIgnoreChannelId(IList roles) + { + var list = new List(); + if (roles == null) return list; + + foreach (var roleName in roles) + { + var systemPermissionsInfoList = GetSystemPermissionsInfoList(roleName); + foreach (var systemPermissionsInfo in systemPermissionsInfoList) + { + var channelPermissionList = TranslateUtils.StringCollectionToStringList(systemPermissionsInfo.ChannelPermissions); + foreach (var channelPermission in channelPermissionList) + { + if (!list.Contains(channelPermission)) + { + list.Add(channelPermission); + } + } + } + } + + return list; + } + + //public new void UpdateObject(SitePermissionsInfo permissionsInfo) + //{ + // //IDataParameter[] parameters = + // //{ + // // GetParameter(ParamRoleRoleName, permissionsInfo.RoleName), + // // GetParameter(ParamSiteId, permissionsInfo.SiteId), + // // GetParameter(ParamChannelIdCollection,permissionsInfo.ChannelIdCollection), + // // GetParameter(ParamChannelPermissions,permissionsInfo.ChannelPermissions), + // // GetParameter(ParamWebsitePermissions,permissionsInfo.WebsitePermissions) + // //}; + // //string SqlUpdate = "UPDATE siteserver_SitePermissions SET ChannelIdCollection = @ChannelIdCollection, ChannelPermissions = @ChannelPermissions, WebsitePermissions = @WebsitePermissions WHERE RoleName = @RoleName AND SiteId = @SiteId"; + // //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdate, parameters); + + // base.UpdateObject(permissionsInfo); + //} + + public void InsertRoleAndPermissions(string roleName, string creatorUserName, string description, List generalPermissionList, List systemPermissionsInfoList) + { + if (generalPermissionList != null && generalPermissionList.Count > 0) + { + var permissionsInRolesInfo = new PermissionsInRolesInfo + { + RoleName = roleName, + GeneralPermissionList = generalPermissionList + }; + + DataProvider.PermissionsInRoles.Insert(permissionsInRolesInfo); + } + + foreach (var systemPermissionsInfo in systemPermissionsInfoList) + { + systemPermissionsInfo.RoleName = roleName; + Insert(systemPermissionsInfo); + } + + DataProvider.Role.InsertRole(new RoleInfo + { + RoleName = roleName, + CreatorUserName = creatorUserName, + Description = description + }); + } + + public void UpdateSitePermissions(string roleName, List sitePermissionsInfoList) + { + Delete(roleName); + foreach (var sitePermissionsInfo in sitePermissionsInfoList) + { + sitePermissionsInfo.RoleName = roleName; + Insert(sitePermissionsInfo); + } + } + } +} + + +//using System.Collections.Generic; +//using System.Data; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.CMS.Plugin.Impl; +//using SiteServer.Plugin; +//using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class SitePermissions : DataProviderBase +// { +// public override string TableName => "siteserver_SitePermissions"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(SitePermissionsInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(SitePermissionsInfo.RoleName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(SitePermissionsInfo.SiteId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(SitePermissionsInfo.ChannelIdCollection), +// DataType = DataType.Text +// }, +// new TableColumn +// { +// AttributeName = nameof(SitePermissionsInfo.ChannelPermissions), +// DataType = DataType.Text +// }, +// new TableColumn +// { +// AttributeName = nameof(SitePermissionsInfo.WebsitePermissions), +// DataType = DataType.Text +// } +// }; + +// private const string SqlSelectAllByRoleName = "SELECT RoleName, SiteId, ChannelIdCollection, ChannelPermissions, WebsitePermissions FROM siteserver_SitePermissions WHERE RoleName = @RoleName ORDER BY SiteId DESC"; + +// private const string SqlInsert = "INSERT INTO siteserver_SitePermissions (RoleName, SiteId, ChannelIdCollection, ChannelPermissions, WebsitePermissions) VALUES (@RoleName, @SiteId, @ChannelIdCollection, @ChannelPermissions, @WebsitePermissions)"; + +// private const string SqlDelete = "DELETE FROM siteserver_SitePermissions WHERE RoleName = @RoleName"; + +// private const string SqlUpdate = "UPDATE siteserver_SitePermissions SET ChannelIdCollection = @ChannelIdCollection, ChannelPermissions = @ChannelPermissions, WebsitePermissions = @WebsitePermissions WHERE RoleName = @RoleName AND SiteId = @SiteId"; + +// private const string ParamRoleRoleName = "@RoleName"; +// private const string ParamSiteId = "@SiteId"; +// private const string ParamChannelIdCollection = "@ChannelIdCollection"; +// private const string ParamChannelPermissions = "@ChannelPermissions"; +// private const string ParamWebsitePermissions = "@WebsitePermissions"; + +// public void InsertWithTrans(SitePermissionsInfo permissionsInfo, IDbTransaction trans) +// { +// if (IsExists(permissionsInfo.RoleName, permissionsInfo.SiteId, trans)) +// { +// DeleteWithTrans(permissionsInfo.RoleName, permissionsInfo.SiteId, trans); +// } + +// IDataParameter[] parameters = +// { +// GetParameter(ParamRoleRoleName, permissionsInfo.RoleName), +// GetParameter(ParamSiteId, permissionsInfo.SiteId), +// GetParameter(ParamChannelIdCollection,permissionsInfo.ChannelIdCollection), +// GetParameter(ParamChannelPermissions,permissionsInfo.ChannelPermissions), +// GetParameter(ParamWebsitePermissions,permissionsInfo.WebsitePermissions) +// }; + +// DatabaseApi.ExecuteNonQuery(trans, SqlInsert, parameters); +// } + + +// public void DeleteWithTrans(string roleName, IDbTransaction trans) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamRoleRoleName, roleName) +// }; + +// DatabaseApi.ExecuteNonQuery(trans, SqlDelete, parameters); +// } + +// private void DeleteWithTrans(string roleName, int siteId, IDbTransaction trans) +// { +// const string sqlString = "DELETE FROM siteserver_SitePermissions WHERE RoleName = @RoleName AND SiteId = @SiteId"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamRoleRoleName, roleName), +// GetParameter(ParamSiteId, siteId) +// }; + +// DatabaseApi.ExecuteNonQuery(trans, sqlString, parameters); +// } + +// private bool IsExists(string roleName, int siteId, IDbTransaction trans) +// { +// var isExists = false; + +// const string sqlString = "SELECT RoleName FROM siteserver_SitePermissions WHERE RoleName = @RoleName AND SiteId = @SiteId"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamRoleRoleName, roleName), +// GetParameter(ParamSiteId, siteId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(trans, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// isExists = true; +// } +// rdr.Close(); +// } + +// return isExists; +// } + +// public List GetSystemPermissionsInfoList(string roleName) +// { +// var list = new List(); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamRoleRoleName, roleName) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAllByRoleName, parameters)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var permissionsInfo = new SitePermissionsInfo(DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i)); +// list.Add(permissionsInfo); +// } +// rdr.Close(); +// } + +// return list; +// } + +// public Dictionary> GetWebsitePermissionSortedList(IEnumerable roles) +// { +// var sortedList = new Dictionary>(); +// if (roles == null) return sortedList; + +// foreach (var roleName in roles) +// { +// var systemPermissionsList = GetSystemPermissionsInfoList(roleName); +// foreach (var systemPermissionsInfo in systemPermissionsList) +// { +// var list = new List(); +// var websitePermissionList = TranslateUtils.StringCollectionToStringList(systemPermissionsInfo.WebsitePermissions); +// foreach (var websitePermission in websitePermissionList) +// { +// if (!list.Contains(websitePermission)) list.Add(websitePermission); +// } +// sortedList[systemPermissionsInfo.SiteId] = list; +// } +// } + +// return sortedList; +// } + +// public Dictionary> GetChannelPermissionSortedList(IList roles) +// { +// var dict = new Dictionary>(); +// if (roles == null) return dict; + +// foreach (var roleName in roles) +// { +// var systemPermissionsInfoList = GetSystemPermissionsInfoList(roleName); +// foreach (var systemPermissionsInfo in systemPermissionsInfoList) +// { +// var channelIdList = TranslateUtils.StringCollectionToIntList(systemPermissionsInfo.ChannelIdCollection); +// foreach (var channelId in channelIdList) +// { +// var key = PermissionsImpl.GetChannelPermissionDictKey(systemPermissionsInfo.SiteId, channelId); + +// if (!dict.TryGetValue(key, out var list)) +// { +// list = new List(); +// dict[key] = list; +// } + +// var channelPermissionList = TranslateUtils.StringCollectionToStringList(systemPermissionsInfo.ChannelPermissions); +// foreach (var channelPermission in channelPermissionList) +// { +// if (!list.Contains(channelPermission)) list.Add(channelPermission); +// } +// } +// } +// } + +// return dict; +// } + +// public List GetChannelPermissionListIgnoreChannelId(IList roles) +// { +// var list = new List(); +// if (roles == null) return list; + +// foreach (var roleName in roles) +// { +// var systemPermissionsInfoList = GetSystemPermissionsInfoList(roleName); +// foreach (var systemPermissionsInfo in systemPermissionsInfoList) +// { +// var channelPermissionList = TranslateUtils.StringCollectionToStringList(systemPermissionsInfo.ChannelPermissions); +// foreach (var channelPermission in channelPermissionList) +// { +// if (!list.Contains(channelPermission)) +// { +// list.Add(channelPermission); +// } +// } +// } +// } + +// return list; +// } + +// public void UpdateObject(SitePermissionsInfo permissionsInfo) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamRoleRoleName, permissionsInfo.RoleName), +// GetParameter(ParamSiteId, permissionsInfo.SiteId), +// GetParameter(ParamChannelIdCollection,permissionsInfo.ChannelIdCollection), +// GetParameter(ParamChannelPermissions,permissionsInfo.ChannelPermissions), +// GetParameter(ParamWebsitePermissions,permissionsInfo.WebsitePermissions) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdate, parameters); +// } + +// public void InsertRoleAndPermissions(string roleName, string creatorUserName, string description, List generalPermissionList, List systemPermissionsInfoList) +// { +// using (var conn = GetConnection()) +// { +// conn.Open(); +// using (var trans = conn.BeginTransaction()) +// { +// try +// { +// if (generalPermissionList != null && generalPermissionList.Count > 0) +// { +// var permissionsInRolesInfo = new PermissionsInRolesInfo(0, roleName, TranslateUtils.ObjectCollectionToString(generalPermissionList)); +// DataProvider.PermissionsInRoles.InsertWithTrans(permissionsInRolesInfo, trans); +// } + +// foreach (var systemPermissionsInfo in systemPermissionsInfoList) +// { +// systemPermissionsInfo.RoleName = roleName; +// InsertWithTrans(systemPermissionsInfo, trans); +// } + +// trans.Commit(); +// } +// catch +// { +// trans.Rollback(); +// throw; +// } +// } +// } +// DataProvider.Role.InsertRole(new RoleInfo +// { +// RoleName = roleName, +// CreatorUserName = creatorUserName, +// Description = description +// }); +// } + +// public void UpdateSitePermissions(string roleName, List sitePermissionsInfoList) +// { +// using (var conn = GetConnection()) +// { +// conn.Open(); +// using (var trans = conn.BeginTransaction()) +// { +// try +// { +// DeleteWithTrans(roleName, trans); +// foreach (var sitePermissionsInfo in sitePermissionsInfoList) +// { +// sitePermissionsInfo.RoleName = roleName; +// InsertWithTrans(sitePermissionsInfo, trans); +// } + +// trans.Commit(); +// } +// catch +// { +// trans.Rollback(); +// throw; +// } +// } +// } +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/SiteRepository.cs b/net452/SiteServer.CMS/Database/Repositories/SiteRepository.cs new file mode 100644 index 000000000..9d8185723 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/SiteRepository.cs @@ -0,0 +1,766 @@ +using System.Collections.Generic; +using System.Data; +using System.Linq; +using Datory; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Database.Repositories +{ + public class SiteRepository : Repository + { + public SiteRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(SiteInfo.Id); + public const string SiteDir = nameof(SiteInfo.SiteDir); + public const string TableName = nameof(SiteInfo.TableName); + public const string IsRoot = "IsRoot"; + public const string ParentId = nameof(SiteInfo.ParentId); + public const string Taxis = nameof(SiteInfo.Taxis); + } + + public override int Insert(SiteInfo siteInfo) + { + //var sqlString = $"INSERT INTO {TableName} (Id, SiteName, SiteDir, TableName, IsRoot, ParentId, Taxis, SettingsXML) VALUES (@Id, @SiteName, @SiteDir, @TableName, @IsRoot, @ParentId, @Taxis, @SettingsXML)"; + + ////获取排序值 + //siteInfo.Taxis = GetMaxTaxis() + 1; + //IDataParameter[] parameters = + //{ + // GetParameter(ParamId, siteInfo.Id), + // GetParameter(ParamSiteName, siteInfo.SiteName), + // GetParameter(ParamSiteDir, siteInfo.SiteDir), + // GetParameter(ParamTableName, siteInfo.TableName), + // GetParameter(ParamIsRoot, siteInfo.IsRoot.ToString()), + // GetParameter(ParamParentId, siteInfo.ParentId), + // GetParameter(ParamTaxis, taxis), + // GetParameter(ParamSettingsXml,siteInfo.ToString()) + //}; + + //DatabaseApi.ExecuteNonQuery(WebConfigUtils.ConnectionString, sqlString, parameters); + + siteInfo.Taxis = GetMaxTaxis() + 1; + siteInfo.Id = Insert(siteInfo); + + SiteManager.ClearCache(); + + return siteInfo.Id; + } + + public override bool Delete(int siteId) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + var list = ChannelManager.GetChannelIdList(siteId); + DataProvider.TableStyle.Delete(list, siteInfo.TableName); + + DataProvider.Tag.DeleteTags(siteId); + + DataProvider.Channel.DeleteAll(siteId); + + UpdateParentIdToZero(siteId); + + //DatabaseApi.ExecuteNonQuery(ConnectionString, $"DELETE FROM siteserver_Site WHERE Id = {siteId}"); + + base.Delete(siteId); + + SiteManager.ClearCache(); + ChannelManager.RemoveCacheBySiteId(siteId); + PermissionsImpl.ClearAllCache(); + + return true; + } + + public override bool Update(SiteInfo siteInfo) + { + //var sqlString = $"UPDATE {TableName} SET SiteName = @SiteName, SiteDir = @SiteDir, TableName = @TableName, IsRoot = @IsRoot, ParentId = @ParentId, Taxis = @Taxis, SettingsXML = @SettingsXML WHERE Id = @Id"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamSiteName, siteInfo.SiteName), + // GetParameter(ParamSiteDir, siteInfo.SiteDir), + // GetParameter(ParamTableName, siteInfo.TableName), + // GetParameter(ParamIsRoot, siteInfo.IsRoot.ToString()), + // GetParameter(ParamParentId, siteInfo.ParentId), + // GetParameter(ParamTaxis, siteInfo.Taxis), + // GetParameter(ParamSettingsXml,siteInfo.ToString()), + // GetParameter(ParamId, siteInfo.Id) + //}; + + if (siteInfo.Root) + { + UpdateAllIsRoot(); + } + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + var updated = base.Update(siteInfo); + + SiteManager.ClearCache(); + + return updated; + } + + public void UpdateTableName(int siteId, string tableName) + { + //var sqlString = $"UPDATE {TableName} SET TableName = @TableName WHERE Id = @Id"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamTableName, tableName), + // GetParameter(ParamId, siteId) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Update(Q + .Set(Attr.TableName, tableName) + .Where(Attr.Id, siteId) + ); + + SiteManager.ClearCache(); + } + + public void UpdateParentIdToZero(int parentId) + { + //var sqlString = "UPDATE siteserver_Site SET ParentId = 0 WHERE ParentId = " + parentId; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + Update(Q + .Set(Attr.ParentId, 0) + .Where(Attr.ParentId, parentId) + ); + + SiteManager.ClearCache(); + } + + public IList GetLowerSiteDirListThatNotIsRoot() + { + //var list = new List(); + + //var sqlString = $"SELECT SiteDir FROM {TableName} WHERE IsRoot = @IsRoot"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamIsRoot, false.ToString()) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetString(rdr, 0).ToLower()); + // } + // rdr.Close(); + //} + //return list; + + var list = GetAll(Q + .Select(Attr.SiteDir) + .WhereNot(Attr.IsRoot, true.ToString())); + + return list.Select(x => x.ToLower()).ToList(); + } + + private void UpdateAllIsRoot() + { + //var sqlString = $"UPDATE {TableName} SET IsRoot = @IsRoot"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamIsRoot, false.ToString()) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Update(Q + .Set(Attr.IsRoot, false.ToString()) + ); + + SiteManager.ClearCache(); + } + + public List> GetSiteInfoKeyValuePairList() + { + var list = new List>(); + + var siteInfoList = GetSiteInfoList(); + foreach (var siteInfo in siteInfoList) + { + var entry = new KeyValuePair(siteInfo.Id, siteInfo); + list.Add(entry); + } + + return list; + } + + private IList GetSiteInfoList() + { + //var list = new List(); + + //var sqlString = $"SELECT Id, SiteName, SiteDir, TableName, IsRoot, ParentId, Taxis, SettingsXML FROM {TableName} ORDER BY Taxis, Id"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var siteInfo = new SiteInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i)); + // list.Add(siteInfo); + // } + // rdr.Close(); + //} + //return list; + + return GetAll(Q.OrderBy(Attr.Taxis, Attr.Id)); + } + + public bool IsTableUsed(string tableName) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamTableName, tableName) + //}; + + //const string sqlString = "SELECT COUNT(*) FROM siteserver_Site WHERE TableName = @TableName"; + //var count = DatabaseApi.GetIntResult(sqlString, parameters); + + var count = Count(Q.Where(Attr.TableName, tableName)); + + if (count > 0) return true; + + var contentModelPluginIdList = DataProvider.Channel.GetContentModelPluginIdList(); + foreach (var pluginId in contentModelPluginIdList) + { + var service = PluginManager.GetService(pluginId); + if (service != null && PluginContentTableManager.IsContentTable(service) && service.ContentTableName == tableName) + { + return true; + } + } + + return false; + } + + public int GetIdByIsRoot() + { + //var siteId = 0; + + //var sqlString = $"SELECT Id FROM {TableName} WHERE IsRoot = @IsRoot"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamIsRoot, true.ToString()) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // siteId = DatabaseApi.GetInt(rdr, 0); + // } + // rdr.Close(); + //} + //return siteId; + + return Get(Q + .Select(Attr.Id) + .Where(Attr.IsRoot, true.ToString())); + } + + public int GetIdBySiteDir(string siteDir) + { + //var siteId = 0; + + //var sqlString = $"SELECT Id FROM {TableName} WHERE SiteDir = @SiteDir"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamSiteDir, siteDir) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // siteId = DatabaseApi.GetInt(rdr, 0); + // } + // rdr.Close(); + //} + //return siteId; + + return Get(Q + .Select(Attr.Id) + .Where(Attr.SiteDir, siteDir)); + } + + /// + /// 得到所有系统文件夹的列表,以小写表示。 + /// + public List GetLowerSiteDirList(int parentId) + { + //var list = new List(); + //var sqlString = "SELECT SiteDir FROM siteserver_Site WHERE ParentId = " + parentId; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetString(rdr, 0).ToLower()); + // } + // rdr.Close(); + //} + + //return list; + + return GetAll(Q + .Select(Attr.SiteDir) + .Where(Attr.ParentId, parentId)) + .Select(x => x.ToLower()) + .ToList(); + } + + public IDataReader GetStlDataSource(string siteName, string siteDir, int startNum, int totalNum, string whereString, EScopeType scopeType, string orderByString) + { + IDataReader ie = null; + + var sqlWhereString = string.Empty; + + SiteInfo siteInfo = null; + if (!string.IsNullOrEmpty(siteName)) + { + siteInfo = SiteManager.GetSiteInfoBySiteName(siteName); + } + else if (!string.IsNullOrEmpty(siteDir)) + { + siteInfo = SiteManager.GetSiteInfoByDirectory(siteDir); + } + + if (siteInfo != null) + { + sqlWhereString = $"WHERE (ParentId = {siteInfo.Id})"; + } + else + { + if (scopeType == EScopeType.Children) + { + sqlWhereString = "WHERE (ParentId = 0 AND IsRoot = 'False')"; + } + else if (scopeType == EScopeType.Descendant) + { + sqlWhereString = "WHERE (IsRoot = 'False')"; + } + } + + if (!string.IsNullOrEmpty(whereString)) + { + sqlWhereString = string.IsNullOrEmpty(sqlWhereString) ? $"WHERE ({whereString})" : $"{sqlWhereString} AND ({whereString})"; + } + + if (string.IsNullOrEmpty(orderByString) || StringUtils.EqualsIgnoreCase(orderByString, "default")) + { + orderByString = "ORDER BY IsRoot DESC, ParentId, Taxis DESC, Id"; + + //var sqlSelect = DatabaseApi.Instance.GetSelectSqlString(TableName, startNum, totalNum, SqlUtils.Asterisk, sqlWhereString, orderByString); + var sqlSelect = DataProvider.DatabaseApi.GetSqlString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, TableName, null, sqlWhereString, orderByString, startNum - 1, totalNum); + + ie = DataProvider.DatabaseApi.ExecuteReader(WebConfigUtils.ConnectionString, sqlSelect); + } + + return ie; + } + + private int GetMaxTaxis() + { + //const string sqlString = "SELECT MAX(Taxis) FROM siteserver_Site"; + //return DatabaseApi.GetIntResult(sqlString); + return Max(Q.Select(Attr.Taxis)) ?? 0; + } + } +} + + +//using System.Collections.Generic; +//using System.Data; +//using SiteServer.CMS.Database.Caches; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.CMS.Plugin; +//using SiteServer.CMS.Plugin.Impl; +//using SiteServer.Plugin; +//using SiteServer.Utils; +//using SiteServer.Utils.Enumerations; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class Site : DataProviderBase +// { +// public override string TableName => "siteserver_Site"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(SiteInfo.Id), +// DataType = DataType.Integer, +// IsPrimaryKey = true, +// IsIdentity = false +// }, +// new TableColumn +// { +// AttributeName = nameof(SiteInfo.SiteName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(SiteInfo.SiteDir), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(SiteInfo.TableName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(SiteInfo.IsRoot), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(SiteInfo.ParentId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(SiteInfo.Taxis), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(SiteInfo.SettingsXml), +// DataType = DataType.Text +// } +// }; + +// private const string ParamId = "@Id"; +// private const string ParamSiteName = "@SiteName"; +// private const string ParamSiteDir = "@SiteDir"; +// private const string ParamTableName = "@TableName"; +// private const string ParamIsRoot = "@IsRoot"; +// private const string ParamParentId = "@ParentId"; +// private const string ParamTaxis = "@Taxis"; +// private const string ParamSettingsXml = "@SettingsXML"; + +// public void InsertWithTrans(SiteInfo siteInfo, IDbTransaction trans) +// { +// var sqlString = $"INSERT INTO {TableName} (Id, SiteName, SiteDir, TableName, IsRoot, ParentId, Taxis, SettingsXML) VALUES (@Id, @SiteName, @SiteDir, @TableName, @IsRoot, @ParentId, @Taxis, @SettingsXML)"; + +// //获取排序值 +// var taxis = GetMaxTaxis() + 1; +// IDataParameter[] parameters = +// { +// GetParameter(ParamId, siteInfo.Id), +// GetParameter(ParamSiteName, siteInfo.SiteName), +// GetParameter(ParamSiteDir, siteInfo.SiteDir), +// GetParameter(ParamTableName, siteInfo.TableName), +// GetParameter(ParamIsRoot, siteInfo.IsRoot.ToString()), +// GetParameter(ParamParentId, siteInfo.ParentId), +// GetParameter(ParamTaxis, taxis), +// GetParameter(ParamSettingsXml,siteInfo.ToString()) +// }; + +// DatabaseApi.ExecuteNonQuery(trans, sqlString, parameters); +// SiteManager.ClearCache(); +// } + +// public void DeleteById(int siteId) +// { +// var siteInfo = SiteManager.GetSiteInfo(siteId); +// var list = ChannelManager.GetChannelIdList(siteId); +// DataProvider.TableStyle.DeleteById(list, siteInfo.TableName); + +// DataProvider.Tag.DeleteTags(siteId); + +// DataProvider.Channel.DeleteById(siteId, siteId); + +// UpdateParentIdToZero(siteId); + +// DatabaseApi.ExecuteNonQuery(ConnectionString, $"DELETE FROM siteserver_Site WHERE Id = {siteId}"); + +// SiteManager.ClearCache(); +// ChannelManager.RemoveCacheBySiteId(siteId); +// PermissionsImpl.ClearAllCache(); +// } + +// public void UpdateObject(SiteInfo siteInfo) +// { +// var sqlString = $"UPDATE {TableName} SET SiteName = @SiteName, SiteDir = @SiteDir, TableName = @TableName, IsRoot = @IsRoot, ParentId = @ParentId, Taxis = @Taxis, SettingsXML = @SettingsXML WHERE Id = @Id"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamSiteName, siteInfo.SiteName), +// GetParameter(ParamSiteDir, siteInfo.SiteDir), +// GetParameter(ParamTableName, siteInfo.TableName), +// GetParameter(ParamIsRoot, siteInfo.IsRoot.ToString()), +// GetParameter(ParamParentId, siteInfo.ParentId), +// GetParameter(ParamTaxis, siteInfo.Taxis), +// GetParameter(ParamSettingsXml,siteInfo.ToString()), +// GetParameter(ParamId, siteInfo.Id) +// }; + +// if (siteInfo.IsRoot) +// { +// UpdateAllIsRoot(); +// } + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// SiteManager.ClearCache(); +// } + +// public void UpdateTableName(int siteId, string tableName) +// { +// var sqlString = $"UPDATE {TableName} SET TableName = @TableName WHERE Id = @Id"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamTableName, tableName), +// GetParameter(ParamId, siteId) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// SiteManager.ClearCache(); +// } + +// public void UpdateParentIdToZero(int parentId) +// { +// var sqlString = "UPDATE siteserver_Site SET ParentId = 0 WHERE ParentId = " + parentId; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// SiteManager.ClearCache(); +// } + +// public List GetLowerSiteDirListThatNotIsRoot() +// { +// var list = new List(); + +// var sqlString = $"SELECT SiteDir FROM {TableName} WHERE IsRoot = @IsRoot"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamIsRoot, false.ToString()) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// while (rdr.Read()) +// { +// list.Add(DatabaseApi.GetString(rdr, 0).ToLower()); +// } +// rdr.Close(); +// } +// return list; +// } + +// private void UpdateAllIsRoot() +// { +// var sqlString = $"UPDATE {TableName} SET IsRoot = @IsRoot"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamIsRoot, false.ToString()) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// SiteManager.ClearCache(); +// } + +// public List> GetSiteInfoKeyValuePairList() +// { +// var list = new List>(); + +// var siteInfoList = GetSiteInfoList(); +// foreach (var siteInfo in siteInfoList) +// { +// var entry = new KeyValuePair(siteInfo.Id, siteInfo); +// list.Add(entry); +// } + +// return list; +// } + +// private List GetSiteInfoList() +// { +// var list = new List(); + +// var sqlString = $"SELECT Id, SiteName, SiteDir, TableName, IsRoot, ParentId, Taxis, SettingsXML FROM {TableName} ORDER BY Taxis, Id"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var siteInfo = new SiteInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i)); +// list.Add(siteInfo); +// } +// rdr.Close(); +// } +// return list; +// } + +// public bool IsTableUsed(string tableName) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamTableName, tableName) +// }; + +// const string sqlString = "SELECT COUNT(*) FROM siteserver_Site WHERE TableName = @TableName"; +// var count = DatabaseApi.Instance.GetIntResult(sqlString, parameters); + +// if (count > 0) return true; + +// var contentModelPluginIdList = DataProvider.Channel.GetContentModelPluginIdList(); +// foreach (var pluginId in contentModelPluginIdList) +// { +// var service = PluginManager.GetService(pluginId); +// if (service != null && PluginContentTableManager.IsContentTable(service) && service.ContentTableName == tableName) +// { +// return true; +// } +// } + +// return false; +// } + +// public int GetIdByIsRoot() +// { +// var siteId = 0; + +// var sqlString = $"SELECT Id FROM {TableName} WHERE IsRoot = @IsRoot"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamIsRoot, true.ToString()) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// siteId = DatabaseApi.GetInt(rdr, 0); +// } +// rdr.Close(); +// } +// return siteId; +// } + +// public int GetIdBySiteDir(string siteDir) +// { +// var siteId = 0; + +// var sqlString = $"SELECT Id FROM {TableName} WHERE SiteDir = @SiteDir"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamSiteDir, siteDir) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// siteId = DatabaseApi.GetInt(rdr, 0); +// } +// rdr.Close(); +// } +// return siteId; +// } + +// /// +// /// 得到所有系统文件夹的列表,以小写表示。 +// /// +// public List GetLowerSiteDirList(int parentId) +// { +// var list = new List(); +// var sqlString = "SELECT SiteDir FROM siteserver_Site WHERE ParentId = " + parentId; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// list.Add(DatabaseApi.GetString(rdr, 0).ToLower()); +// } +// rdr.Close(); +// } + +// return list; +// } + +// public IDataReader GetStlDataSource(string siteName, string siteDir, int startNum, int totalNum, string whereString, EScopeType scopeType, string orderByString) +// { +// IDataReader ie = null; + +// var sqlWhereString = string.Empty; + +// SiteInfo siteInfo = null; +// if (!string.IsNullOrEmpty(siteName)) +// { +// siteInfo = SiteManager.GetSiteInfoBySiteName(siteName); +// } +// else if (!string.IsNullOrEmpty(siteDir)) +// { +// siteInfo = SiteManager.GetSiteInfoByDirectory(siteDir); +// } + +// if (siteInfo != null) +// { +// sqlWhereString = $"WHERE (ParentId = {siteInfo.Id})"; +// } +// else +// { +// if (scopeType == EScopeType.Children) +// { +// sqlWhereString = "WHERE (ParentId = 0 AND IsRoot = 'False')"; +// } +// else if (scopeType == EScopeType.Descendant) +// { +// sqlWhereString = "WHERE (IsRoot = 'False')"; +// } +// } + +// if (!string.IsNullOrEmpty(whereString)) +// { +// sqlWhereString = string.IsNullOrEmpty(sqlWhereString) ? $"WHERE ({whereString})" : $"{sqlWhereString} AND ({whereString})"; +// } + +// if (string.IsNullOrEmpty(orderByString) || StringUtils.EqualsIgnoreCase(orderByString, "default")) +// { +// orderByString = "ORDER BY IsRoot DESC, ParentId, Taxis DESC, Id"; + +// //var sqlSelect = DatabaseApi.Instance.GetSelectSqlString(TableName, startNum, totalNum, SqlUtils.Asterisk, sqlWhereString, orderByString); +// var sqlSelect = DatorySql.GetSqlString(TableName, null, sqlWhereString, orderByString, startNum - 1, totalNum); + +// ie = DatabaseApi.ExecuteReader(ConnectionString, sqlSelect); +// } + +// return ie; +// } + +// private static int GetMaxTaxis() +// { +// const string sqlString = "SELECT MAX(Taxis) FROM siteserver_Site"; +// return DatabaseApi.Instance.GetIntResult(sqlString); +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/SpecialRepository.cs b/net452/SiteServer.CMS/Database/Repositories/SpecialRepository.cs new file mode 100644 index 000000000..8df6cee09 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/SpecialRepository.cs @@ -0,0 +1,498 @@ +using System.Collections.Generic; +using System.Linq; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class SpecialRepository : Repository + { + public SpecialRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(SpecialInfo.Id); + public const string SiteId = nameof(SpecialInfo.SiteId); + public const string Title = nameof(SpecialInfo.Title); + public const string Url = nameof(SpecialInfo.Url); + } + + public override int Insert(SpecialInfo specialInfo) + { + // var sqlString = $@"INSERT INTO {TableName} + // ({nameof(SpecialInfo.SiteId)}, + // {nameof(SpecialInfo.Title)}, + // {nameof(SpecialInfo.Url)}, + // {nameof(SpecialInfo.AddDate)}) + //VALUES + // (@{nameof(SpecialInfo.SiteId)}, + // @{nameof(SpecialInfo.Title)}, + // @{nameof(SpecialInfo.Url)}, + // @{nameof(SpecialInfo.AddDate)})"; + + // IDataParameter[] parameters = + // { + // GetParameter(nameof(specialInfo.SiteId), specialInfo.SiteId), + // GetParameter(nameof(specialInfo.Title), specialInfo.Title), + // GetParameter(nameof(specialInfo.Url), specialInfo.Url), + // GetParameter(nameof(specialInfo.AddDate),specialInfo.AddDate) + // }; + + // DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + specialInfo.Id = Insert(specialInfo); + + SpecialManager.RemoveCache(specialInfo.SiteId); + + return specialInfo.Id; + } + + public override bool Update(SpecialInfo specialInfo) + { + //var sqlString = $@"UPDATE {TableName} SET + // {nameof(SpecialInfo.SiteId)} = @{nameof(SpecialInfo.SiteId)}, + // {nameof(SpecialInfo.Title)} = @{nameof(SpecialInfo.Title)}, + // {nameof(SpecialInfo.Url)} = @{nameof(SpecialInfo.Url)}, + // {nameof(SpecialInfo.AddDate)} = @{nameof(SpecialInfo.AddDate)} + //WHERE {nameof(SpecialInfo.Id)} = @{nameof(SpecialInfo.Id)}"; + + //IDataParameter[] parameters = + //{ + // GetParameter(nameof(specialInfo.SiteId), specialInfo.SiteId), + // GetParameter(nameof(specialInfo.Title), specialInfo.Title), + // GetParameter(nameof(specialInfo.Url), specialInfo.Url), + // GetParameter(nameof(specialInfo.AddDate),specialInfo.AddDate), + // GetParameter(nameof(specialInfo.Id), specialInfo.Id) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + var updated = base.Update(specialInfo); + + SpecialManager.RemoveCache(specialInfo.SiteId); + + return updated; + } + + public void Delete(int siteId, int specialId) + { + if (specialId <= 0) return; + + //var sqlString = $"DELETE FROM {TableName} WHERE {nameof(SpecialInfo.Id)} = {specialId}"; + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + Delete(specialId); + + SpecialManager.RemoveCache(siteId); + } + + public bool IsTitleExists(int siteId, string title) + { + // var exists = false; + + // var sqlString = $@"SELECT {nameof(SpecialInfo.Id)} FROM {TableName} WHERE + //{nameof(SpecialInfo.SiteId)} = @{nameof(SpecialInfo.SiteId)} AND {nameof(SpecialInfo.Title)} = @{nameof(SpecialInfo.Title)}"; + + // IDataParameter[] parameters = + // { + // GetParameter(nameof(SpecialInfo.SiteId), siteId), + // GetParameter(nameof(SpecialInfo.Title), title) + // }; + + // using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + // { + // if (rdr.Read() && !rdr.IsDBNull(0)) + // { + // exists = true; + // } + // rdr.Close(); + // } + + // return exists; + + return Exists(Q.Where(Attr.SiteId, siteId).Where(Attr.Title, title)); + } + + public bool IsUrlExists(int siteId, string url) + { + // var exists = false; + + // var sqlString = $@"SELECT {nameof(SpecialInfo.Id)} FROM {TableName} WHERE + //{nameof(SpecialInfo.SiteId)} = @{nameof(SpecialInfo.SiteId)} AND {nameof(SpecialInfo.Url)} = @{nameof(SpecialInfo.Url)}"; + + // IDataParameter[] parameters = + // { + // GetParameter(nameof(SpecialInfo.SiteId), siteId), + // GetParameter(nameof(SpecialInfo.Url), url) + // }; + + // using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + // { + // if (rdr.Read() && !rdr.IsDBNull(0)) + // { + // exists = true; + // } + // rdr.Close(); + // } + + // return exists; + + return Exists(Q.Where(Attr.SiteId, siteId).Where(Attr.Url, url)); + } + + public IList GetSpecialInfoList(int siteId) + { + //var list = new List(); + + //var sqlString = $@"SELECT {nameof(SpecialInfo.Id)}, + // {nameof(SpecialInfo.SiteId)}, + // {nameof(SpecialInfo.Title)}, + // {nameof(SpecialInfo.Url)}, + // {nameof(SpecialInfo.AddDate)} + //FROM {TableName} WHERE {nameof(SpecialInfo.SiteId)} = {siteId} ORDER BY {nameof(SpecialInfo.Id)} DESC"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // list.Add(GetSpecialInfo(rdr)); + // } + // rdr.Close(); + //} + + //return list; + + return GetAll(Q.Where(Attr.SiteId, siteId).OrderByDesc(Attr.Id)); + } + + public IList GetSpecialInfoList(int siteId, string keyword) + { + //var list = new List(); + + //keyword = AttackUtils.FilterSql(keyword); + + //var sqlString = $@"SELECT {nameof(SpecialInfo.Id)}, + // {nameof(SpecialInfo.SiteId)}, + // {nameof(SpecialInfo.Title)}, + // {nameof(SpecialInfo.Url)}, + // {nameof(SpecialInfo.AddDate)} + //FROM {TableName} WHERE {nameof(SpecialInfo.SiteId)} = {siteId} AND ({nameof(SpecialInfo.Title)} LIKE '%{keyword}%' OR {nameof(SpecialInfo.Url)} LIKE '%{keyword}%') ORDER BY {nameof(SpecialInfo.Id)} DESC"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // list.Add(GetSpecialInfo(rdr)); + // } + // rdr.Close(); + //} + + //return list; + + return GetAll(Q + .Where(Attr.SiteId, siteId) + .OrWhereContains(Attr.Title, keyword) + .OrWhereContains(Attr.Url, keyword) + .OrderByDesc(Attr.Id)); + } + + public Dictionary GetSpecialInfoDictionaryBySiteId(int siteId) + { + //var sqlString = $@"SELECT {nameof(SpecialInfo.Id)}, + //{nameof(SpecialInfo.SiteId)}, + //{nameof(SpecialInfo.Title)}, + //{nameof(SpecialInfo.Url)}, + //{nameof(SpecialInfo.AddDate)} + //FROM {TableName} WHERE {nameof(SpecialInfo.SiteId)} = {siteId}"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // var specialInfo = GetSpecialInfo(rdr); + // dictionary.Add(specialInfo.Id, specialInfo); + // } + // rdr.Close(); + //} + + var specialInfoList = GetSpecialInfoList(siteId); + + return specialInfoList.ToDictionary(specialInfo => specialInfo.Id); + } + + //private static SpecialInfo GetSpecialInfo(IDataRecord rdr) + //{ + // if (rdr == null) return null; + + // var specialInfo = new SpecialInfo(); + + // var i = 0; + // specialInfo.Id = rdr.IsDBNull(i) ? 0 : rdr.GetInt32(i); + // i++; + // specialInfo.SiteId = rdr.IsDBNull(i) ? 0 : rdr.GetInt32(i); + // i++; + // specialInfo.Title = rdr.IsDBNull(i) ? string.Empty : rdr.GetString(i); + // i++; + // specialInfo.Url = rdr.IsDBNull(i) ? string.Empty : rdr.GetString(i); + // i++; + // specialInfo.AddDate = rdr.IsDBNull(i) ? DateTime.Now : rdr.GetDateTime(i); + + // return specialInfo; + //} + } +} + + +//using System; +//using System.Collections.Generic; +//using System.Data; +//using SiteServer.CMS.Database.Caches; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class Special : DataProviderBase +// { +// public override string TableName => "siteserver_Special"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(SpecialInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(SpecialInfo.SiteId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(SpecialInfo.Title), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(SpecialInfo.Url), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(SpecialInfo.AddDate), +// DataType = DataType.DateTime +// } +// }; + +// public void InsertObject(SpecialInfo specialInfo) +// { +// var sqlString = $@"INSERT INTO {TableName} +// ({nameof(SpecialInfo.SiteId)}, +// {nameof(SpecialInfo.Title)}, +// {nameof(SpecialInfo.Url)}, +// {nameof(SpecialInfo.AddDate)}) +// VALUES +// (@{nameof(SpecialInfo.SiteId)}, +// @{nameof(SpecialInfo.Title)}, +// @{nameof(SpecialInfo.Url)}, +// @{nameof(SpecialInfo.AddDate)})"; + +// IDataParameter[] parameters = +// { +// GetParameter(nameof(specialInfo.SiteId), specialInfo.SiteId), +// GetParameter(nameof(specialInfo.Title), specialInfo.Title), +// GetParameter(nameof(specialInfo.Url), specialInfo.Url), +// GetParameter(nameof(specialInfo.AddDate),specialInfo.AddDate) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// SpecialManager.RemoveCache(specialInfo.SiteId); +// } + +// public void UpdateObject(SpecialInfo specialInfo) +// { +// var sqlString = $@"UPDATE {TableName} SET +// {nameof(SpecialInfo.SiteId)} = @{nameof(SpecialInfo.SiteId)}, +// {nameof(SpecialInfo.Title)} = @{nameof(SpecialInfo.Title)}, +// {nameof(SpecialInfo.Url)} = @{nameof(SpecialInfo.Url)}, +// {nameof(SpecialInfo.AddDate)} = @{nameof(SpecialInfo.AddDate)} +// WHERE {nameof(SpecialInfo.Id)} = @{nameof(SpecialInfo.Id)}"; + +// IDataParameter[] parameters = +// { +// GetParameter(nameof(specialInfo.SiteId), specialInfo.SiteId), +// GetParameter(nameof(specialInfo.Title), specialInfo.Title), +// GetParameter(nameof(specialInfo.Url), specialInfo.Url), +// GetParameter(nameof(specialInfo.AddDate),specialInfo.AddDate), +// GetParameter(nameof(specialInfo.Id), specialInfo.Id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// SpecialManager.RemoveCache(specialInfo.SiteId); +// } + +// public void DeleteById(int siteId, int specialId) +// { +// if (specialId <= 0) return; + +// var sqlString = $"DELETE FROM {TableName} WHERE {nameof(SpecialInfo.Id)} = {specialId}"; +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + +// SpecialManager.RemoveCache(siteId); +// } + +// public bool IsTitleExists(int siteId, string title) +// { +// var exists = false; + +// var sqlString = $@"SELECT {nameof(SpecialInfo.Id)} FROM {TableName} WHERE +// {nameof(SpecialInfo.SiteId)} = @{nameof(SpecialInfo.SiteId)} AND {nameof(SpecialInfo.Title)} = @{nameof(SpecialInfo.Title)}"; + +// IDataParameter[] parameters = +// { +// GetParameter(nameof(SpecialInfo.SiteId), siteId), +// GetParameter(nameof(SpecialInfo.Title), title) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read() && !rdr.IsDBNull(0)) +// { +// exists = true; +// } +// rdr.Close(); +// } + +// return exists; +// } + +// public bool IsUrlExists(int siteId, string url) +// { +// var exists = false; + +// var sqlString = $@"SELECT {nameof(SpecialInfo.Id)} FROM {TableName} WHERE +// {nameof(SpecialInfo.SiteId)} = @{nameof(SpecialInfo.SiteId)} AND {nameof(SpecialInfo.Url)} = @{nameof(SpecialInfo.Url)}"; + +// IDataParameter[] parameters = +// { +// GetParameter(nameof(SpecialInfo.SiteId), siteId), +// GetParameter(nameof(SpecialInfo.Url), url) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read() && !rdr.IsDBNull(0)) +// { +// exists = true; +// } +// rdr.Close(); +// } + +// return exists; +// } + +// public List GetSpecialInfoList(int siteId) +// { +// var list = new List(); + +// var sqlString = $@"SELECT {nameof(SpecialInfo.Id)}, +// {nameof(SpecialInfo.SiteId)}, +// {nameof(SpecialInfo.Title)}, +// {nameof(SpecialInfo.Url)}, +// {nameof(SpecialInfo.AddDate)} +// FROM {TableName} WHERE {nameof(SpecialInfo.SiteId)} = {siteId} ORDER BY {nameof(SpecialInfo.Id)} DESC"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// list.Add(GetSpecialInfo(rdr)); +// } +// rdr.Close(); +// } + +// return list; +// } + +// public List GetSpecialInfoList(int siteId, string keyword) +// { +// var list = new List(); + +// keyword = AttackUtils.FilterSql(keyword); + +// var sqlString = $@"SELECT {nameof(SpecialInfo.Id)}, +// {nameof(SpecialInfo.SiteId)}, +// {nameof(SpecialInfo.Title)}, +// {nameof(SpecialInfo.Url)}, +// {nameof(SpecialInfo.AddDate)} +// FROM {TableName} WHERE {nameof(SpecialInfo.SiteId)} = {siteId} AND ({nameof(SpecialInfo.Title)} LIKE '%{keyword}%' OR {nameof(SpecialInfo.Url)} LIKE '%{keyword}%') ORDER BY {nameof(SpecialInfo.Id)} DESC"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// list.Add(GetSpecialInfo(rdr)); +// } +// rdr.Close(); +// } + +// return list; +// } + +// public Dictionary GetSpecialInfoDictionaryBySiteId(int siteId) +// { +// var dictionary = new Dictionary(); + +// var sqlString = $@"SELECT {nameof(SpecialInfo.Id)}, +// {nameof(SpecialInfo.SiteId)}, +// {nameof(SpecialInfo.Title)}, +// {nameof(SpecialInfo.Url)}, +// {nameof(SpecialInfo.AddDate)} +// FROM {TableName} WHERE {nameof(SpecialInfo.SiteId)} = {siteId}"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var specialInfo = GetSpecialInfo(rdr); +// dictionary.Add(specialInfo.Id, specialInfo); +// } +// rdr.Close(); +// } + +// return dictionary; +// } + +// private static SpecialInfo GetSpecialInfo(IDataRecord rdr) +// { +// if (rdr == null) return null; + +// var specialInfo = new SpecialInfo(); + +// var i = 0; +// specialInfo.Id = rdr.IsDBNull(i) ? 0 : rdr.GetInt32(i); +// i++; +// specialInfo.SiteId = rdr.IsDBNull(i) ? 0 : rdr.GetInt32(i); +// i++; +// specialInfo.Title = rdr.IsDBNull(i) ? string.Empty : rdr.GetString(i); +// i++; +// specialInfo.Url = rdr.IsDBNull(i) ? string.Empty : rdr.GetString(i); +// i++; +// specialInfo.AddDate = rdr.IsDBNull(i) ? DateTime.Now : rdr.GetDateTime(i); + +// return specialInfo; +// } + +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/TableStyleItemRepository.cs b/net452/SiteServer.CMS/Database/Repositories/TableStyleItemRepository.cs new file mode 100644 index 000000000..f190d6e9d --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/TableStyleItemRepository.cs @@ -0,0 +1,258 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class TableStyleItemRepository : Repository + { + public TableStyleItemRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string TableStyleId = nameof(TableStyleItemInfo.TableStyleId); + } + + public void Insert(int tableStyleId, List styleItems) + { + if (styleItems == null || styleItems.Count <= 0) return; + + //var sqlString = + // $"INSERT INTO {TableName} ({nameof(TableStyleItemInfo.TableStyleId)}, {nameof(TableStyleItemInfo.ItemTitle)}, {nameof(TableStyleItemInfo.ItemValue)}, {nameof(TableStyleItemInfo.IsSelected)}) VALUES (@{nameof(TableStyleItemInfo.TableStyleId)}, @{nameof(TableStyleItemInfo.ItemTitle)}, @{nameof(TableStyleItemInfo.ItemValue)}, @{nameof(TableStyleItemInfo.IsSelected)})"; + + foreach (var itemInfo in styleItems) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamTableStyleId, tableStyleId), + // GetParameter(ParamItemTitle, itemInfo.ItemTitle), + // GetParameter(ParamItemValue, itemInfo.ItemValue), + // GetParameter(ParamIsSelected, itemInfo.IsSelected.ToString()) + //}; + + //DatabaseApi.ExecuteNonQuery(WebConfigUtils.ConnectionString, sqlString, parameters); + itemInfo.TableStyleId = tableStyleId; + base.Insert(itemInfo); + } + + TableStyleManager.ClearCache(); + } + + public void DeleteAndInsertStyleItems(int tableStyleId, List styleItems) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamTableStyleId, tableStyleId) + //}; + //var sqlString = $"DELETE FROM {TableName} WHERE {nameof(TableStyleItemInfo.TableStyleId)} = @{nameof(TableStyleItemInfo.TableStyleId)}"; + + //DatabaseApi.ExecuteNonQuery(WebConfigUtils.ConnectionString, sqlString, parameters); + + Delete(Q.Where(Attr.TableStyleId, tableStyleId)); + + if (styleItems == null || styleItems.Count == 0) return; + + //sqlString = + // $"INSERT INTO {TableName} ({nameof(TableStyleItemInfo.TableStyleId)}, {nameof(TableStyleItemInfo.ItemTitle)}, {nameof(TableStyleItemInfo.ItemValue)}, {nameof(TableStyleItemInfo.IsSelected)}) VALUES (@{nameof(TableStyleItemInfo.TableStyleId)}, @{nameof(TableStyleItemInfo.ItemTitle)}, @{nameof(TableStyleItemInfo.ItemValue)}, @{nameof(TableStyleItemInfo.IsSelected)})"; + + foreach (var itemInfo in styleItems) + { + // parameters = new[] + //{ + // GetParameter(ParamTableStyleId, itemInfo.TableStyleId), + // GetParameter(ParamItemTitle, itemInfo.ItemTitle), + // GetParameter(ParamItemValue, itemInfo.ItemValue), + // GetParameter(ParamIsSelected, itemInfo.IsSelected.ToString()) + // }; + + // DatabaseApi.ExecuteNonQuery(WebConfigUtils.ConnectionString, sqlString, parameters); + + base.Insert(itemInfo); + } + + TableStyleManager.ClearCache(); + } + + public Dictionary> GetAllTableStyleItems() + { + var allDict = new Dictionary>(); + + var itemInfoList = GetAll(); + foreach (var itemInfo in itemInfoList) + { + allDict.TryGetValue(itemInfo.TableStyleId, out var list); + + if (list == null) + { + list = new List(); + } + + list.Add(itemInfo); + + allDict[itemInfo.TableStyleId] = list; + } + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, "SELECT Id, TableStyleID, ItemTitle, ItemValue, IsSelected FROM siteserver_TableStyleItem")) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var item = new TableStyleItemInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i))); + + // allDict.TryGetValue(item.TableStyleId, out var list); + + // if (list == null) + // { + // list = new List(); + // } + + // list.Add(item); + + // allDict[item.TableStyleId] = list; + // } + // rdr.Close(); + //} + + return allDict; + } + } +} + + +//using System.Collections.Generic; +//using System.Data; +//using SiteServer.CMS.Database.Caches; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class TableStyleItem : DataProviderBase +// { +// public override string TableName => "siteserver_TableStyleItem"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(TableStyleItemInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(TableStyleItemInfo.TableStyleId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(TableStyleItemInfo.ItemTitle), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TableStyleItemInfo.ItemValue), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TableStyleItemInfo.IsSelected), +// DataType = DataType.VarChar +// } +// }; + +// private const string ParamTableStyleId = "@TableStyleID"; +// private const string ParamItemTitle = "@ItemTitle"; +// private const string ParamItemValue = "@ItemValue"; +// private const string ParamIsSelected = "@IsSelected"; + +// public void InsertObject(IDbTransaction trans, int tableStyleId, List styleItems) +// { +// if (styleItems == null || styleItems.Count <= 0) return; + +// var sqlString = +// $"INSERT INTO {TableName} ({nameof(TableStyleItemInfo.TableStyleId)}, {nameof(TableStyleItemInfo.ItemTitle)}, {nameof(TableStyleItemInfo.ItemValue)}, {nameof(TableStyleItemInfo.IsSelected)}) VALUES (@{nameof(TableStyleItemInfo.TableStyleId)}, @{nameof(TableStyleItemInfo.ItemTitle)}, @{nameof(TableStyleItemInfo.ItemValue)}, @{nameof(TableStyleItemInfo.IsSelected)})"; + +// foreach (var itemInfo in styleItems) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamTableStyleId, tableStyleId), +// GetParameter(ParamItemTitle, itemInfo.ItemTitle), +// GetParameter(ParamItemValue, itemInfo.ItemValue), +// GetParameter(ParamIsSelected, itemInfo.IsSelected.ToString()) +// }; + +// DatabaseApi.ExecuteNonQuery(trans, sqlString, parameters); +// } + +// TableStyleManager.ClearCache(); +// } + +// public void DeleteAndInsertStyleItems(IDbTransaction trans, int tableStyleId, List styleItems) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamTableStyleId, tableStyleId) +// }; +// var sqlString = $"DELETE FROM {TableName} WHERE {nameof(TableStyleItemInfo.TableStyleId)} = @{nameof(TableStyleItemInfo.TableStyleId)}"; + +// DatabaseApi.ExecuteNonQuery(trans, sqlString, parameters); + +// if (styleItems == null || styleItems.Count == 0) return; + +// sqlString = +// $"INSERT INTO {TableName} ({nameof(TableStyleItemInfo.TableStyleId)}, {nameof(TableStyleItemInfo.ItemTitle)}, {nameof(TableStyleItemInfo.ItemValue)}, {nameof(TableStyleItemInfo.IsSelected)}) VALUES (@{nameof(TableStyleItemInfo.TableStyleId)}, @{nameof(TableStyleItemInfo.ItemTitle)}, @{nameof(TableStyleItemInfo.ItemValue)}, @{nameof(TableStyleItemInfo.IsSelected)})"; + +// foreach (var itemInfo in styleItems) +// { +// parameters = new [] +// { +// GetParameter(ParamTableStyleId, itemInfo.TableStyleId), +// GetParameter(ParamItemTitle, itemInfo.ItemTitle), +// GetParameter(ParamItemValue, itemInfo.ItemValue), +// GetParameter(ParamIsSelected, itemInfo.IsSelected.ToString()) +// }; + +// DatabaseApi.ExecuteNonQuery(trans, sqlString, parameters); +// } + +// TableStyleManager.ClearCache(); +// } + +// public Dictionary> GetAllTableStyleItems() +// { +// var allDict = new Dictionary>(); + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, "SELECT Id, TableStyleID, ItemTitle, ItemValue, IsSelected FROM siteserver_TableStyleItem")) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var item = new TableStyleItemInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i))); + +// allDict.TryGetValue(item.TableStyleId, out var list); + +// if (list == null) +// { +// list = new List(); +// } + +// list.Add(item); + +// allDict[item.TableStyleId] = list; +// } +// rdr.Close(); +// } + +// return allDict; +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/TableStyleRepository.cs b/net452/SiteServer.CMS/Database/Repositories/TableStyleRepository.cs new file mode 100644 index 000000000..fd94178e0 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/TableStyleRepository.cs @@ -0,0 +1,494 @@ +using System.Collections.Generic; +using System.Linq; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class TableStyleRepository : Repository + { + public TableStyleRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(TableStyleInfo.Id); + public const string RelatedIdentity = nameof(TableStyleInfo.RelatedIdentity); + public const string TableName = nameof(TableStyleInfo.TableName); + public const string AttributeName = nameof(TableStyleInfo.AttributeName); + public const string Taxis = nameof(TableStyleInfo.Taxis); + } + + public override int Insert(TableStyleInfo styleInfo) + { + //int id; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamRelatedIdentity, styleInfo.RelatedIdentity), + // GetParameter(ParamTableName, styleInfo.TableName), + // GetParameter(ParamAttributeName, styleInfo.AttributeName), + // GetParameter(ParamTaxis, styleInfo.Taxis), + // GetParameter(ParamDisplayName, styleInfo.DisplayName), + // GetParameter(ParamHelpText, styleInfo.HelpText), + // GetParameter(ParamIsVisibleInList, styleInfo.IsVisibleInList.ToString()), + // GetParameter(ParamInputType, styleInfo.InputType.Value), + // GetParameter(ParamDefaultValue, styleInfo.DefaultValue), + // GetParameter(ParamIsHorizontal, styleInfo.IsHorizontal.ToString()), + // GetParameter(ParamExtendValues,styleInfo.ToString()) + //}; + + //using (var conn = GetConnection()) + //{ + // conn.Open(); + // using (var trans = conn.BeginTransaction()) + // { + // try + // { + // string SqlInsertTableStyle = "INSERT INTO siteserver_TableStyle (RelatedIdentity, TableName, AttributeName, Taxis, DisplayName, HelpText, IsVisibleInList, InputType, DefaultValue, IsHorizontal, ExtendValues) VALUES (@RelatedIdentity, @TableName, @AttributeName, @Taxis, @DisplayName, @HelpText, @IsVisibleInList, @InputType, @DefaultValue, @IsHorizontal, @ExtendValues)"; + // id = DatabaseApi.ExecuteNonQueryAndReturnId(TableName, nameof(TableStyleInfo.Id), trans, SqlInsertTableStyle, parameters); + + // DataProvider.TableStyleItem.InsertObject(trans, id, styleInfo.StyleItems); + + // trans.Commit(); + // } + // catch + // { + // trans.Rollback(); + // throw; + // } + // } + //} + + var id = base.Insert(styleInfo); + DataProvider.TableStyleItem.Insert(id, styleInfo.StyleItems); + + TableStyleManager.ClearCache(); + + return id; + } + + public void Update(TableStyleInfo info, bool deleteAndInsertStyleItems = true) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamAttributeName, info.AttributeName), + // GetParameter(ParamTaxis, info.Taxis), + // GetParameter(ParamDisplayName, info.DisplayName), + // GetParameter(ParamHelpText, info.HelpText), + // GetParameter(ParamIsVisibleInList, info.IsVisibleInList.ToString()), + // GetParameter(ParamInputType, info.InputType.Value), + // GetParameter(ParamDefaultValue, info.DefaultValue), + // GetParameter(ParamIsHorizontal, info.IsHorizontal.ToString()), + // GetParameter(ParamExtendValues,info.ToString()), + // GetParameter(ParamId, info.Id) + //}; + + //using (var conn = GetConnection()) + //{ + // conn.Open(); + // using (var trans = conn.BeginTransaction()) + // { + // try + // { + // string SqlUpdateTableStyle = "UPDATE siteserver_TableStyle SET AttributeName = @AttributeName, Taxis = @Taxis, DisplayName = @DisplayName, HelpText = @HelpText, IsVisibleInList = @IsVisibleInList, InputType = @InputType, DefaultValue = @DefaultValue, IsHorizontal = @IsHorizontal, ExtendValues = @ExtendValues WHERE Id = @Id"; + // DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdateTableStyle, parameters); + + // if (deleteAndInsertStyleItems) + // { + // DataProvider.TableStyleItem.DeleteAndInsertStyleItems(trans, info.Id, info.StyleItems); + // } + + // trans.Commit(); + // } + // catch + // { + // trans.Rollback(); + // throw; + // } + // } + //} + + Update(info); + if (deleteAndInsertStyleItems) + { + DataProvider.TableStyleItem.DeleteAndInsertStyleItems(info.Id, info.StyleItems); + } + + TableStyleManager.ClearCache(); + } + + public void Delete(int relatedIdentity, string tableName, string attributeName) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamRelatedIdentity, relatedIdentity), + // GetParameter(ParamTableName, tableName), + // GetParameter(ParamAttributeName, attributeName) + //}; + //string SqlDeleteTableStyle = "DELETE FROM siteserver_TableStyle WHERE RelatedIdentity = @RelatedIdentity AND TableName = @TableName AND AttributeName = @AttributeName"; + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDeleteTableStyle, parameters); + + Delete(Q + .Where(Attr.RelatedIdentity, relatedIdentity) + .Where(Attr.TableName, tableName) + .Where(Attr.AttributeName, attributeName)); + + TableStyleManager.ClearCache(); + } + + public void Delete(List relatedIdentities, string tableName) + { + if (relatedIdentities == null || relatedIdentities.Count <= 0) return; + + //var sqlString = + // $"DELETE FROM siteserver_TableStyle WHERE RelatedIdentity IN ({TranslateUtils.ToSqlInStringWithoutQuote(relatedIdentities)}) AND TableName = '{AttackUtils.FilterSql(tableName)}'"; + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + Delete(Q + .WhereIn(Attr.RelatedIdentity, relatedIdentities) + .Where(Attr.TableName, tableName)); + + TableStyleManager.ClearCache(); + } + + //private TableStyleInfo GetTableStyleInfoByReader(IDataReader rdr) + //{ + // var i = 0; + // var id = DatabaseApi.GetInt(rdr, i++); + // var relatedIdentity = DatabaseApi.GetInt(rdr, i++); + // var tableName = DatabaseApi.GetString(rdr, i++); + // var attributeName = DatabaseApi.GetString(rdr, i++); + // var taxis = DatabaseApi.GetInt(rdr, i++); + // var displayName = DatabaseApi.GetString(rdr, i++); + // var helpText = DatabaseApi.GetString(rdr, i++); + // var isVisibleInList = TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)); + // var inputType = DatabaseApi.GetString(rdr, i++); + // var defaultValue = DatabaseApi.GetString(rdr, i++); + // var isHorizontal = TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)); + // var extendValues = DatabaseApi.GetString(rdr, i); + + // var styleInfo = new TableStyleInfo(id, relatedIdentity, tableName, attributeName, taxis, displayName, helpText, isVisibleInList, InputTypeUtils.GetEnumType(inputType), defaultValue, isHorizontal, extendValues); + + // return styleInfo; + //} + + public List> GetAllTableStyles() + { + var pairs = new List>(); + + var allItemsDict = DataProvider.TableStyleItem.GetAllTableStyleItems(); + + var styleInfoList = GetAll(Q.OrderByDesc(Attr.Taxis, Attr.Id)); + foreach (var styleInfo in styleInfoList) + { + allItemsDict.TryGetValue(styleInfo.Id, out var items); + styleInfo.StyleItems = items; + + var key = TableStyleManager.GetKey(styleInfo.RelatedIdentity, styleInfo.TableName, styleInfo.AttributeName); + + if (pairs.All(pair => pair.Key != key)) + { + var pair = new KeyValuePair(key, styleInfo); + pairs.Add(pair); + } + } + + //string SqlSelectAllTableStyle = "SELECT Id, RelatedIdentity, TableName, AttributeName, Taxis, DisplayName, HelpText, IsVisibleInList, InputType, DefaultValue, IsHorizontal, ExtendValues FROM siteserver_TableStyle ORDER BY Taxis DESC, Id DESC"; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAllTableStyle)) + //{ + // while (rdr.Read()) + // { + // var styleInfo = GetTableStyleInfoByReader(rdr); + + // allItemsDict.TryGetValue(styleInfo.Id, out var items); + // styleInfo.StyleItems = items; + + // var key = TableStyleManager.GetKey(styleInfo.RelatedIdentity, styleInfo.TableName, styleInfo.AttributeName); + + // if (pairs.All(pair => pair.Key != key)) + // { + // var pair = new KeyValuePair(key, styleInfo); + // pairs.Add(pair); + // } + // } + // rdr.Close(); + //} + + return pairs; + } + } +} + + +//using System.Collections.Generic; +//using System.Data; +//using System.Linq; +//using SiteServer.CMS.Core; +//using SiteServer.CMS.Database.Caches; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class TableStyle : DataProviderBase +// { +// public override string TableName => "siteserver_TableStyle"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(TableStyleInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(TableStyleInfo.RelatedIdentity), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(TableStyleInfo.TableName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TableStyleInfo.AttributeName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TableStyleInfo.Taxis), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(TableStyleInfo.DisplayName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TableStyleInfo.HelpText), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TableStyleInfo.IsVisibleInList), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TableStyleInfo.InputType), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TableStyleInfo.DefaultValue), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TableStyleInfo.IsHorizontal), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TableStyleInfo.ExtendValues), +// DataType = DataType.Text +// } +// }; + +// private const string SqlSelectAllTableStyle = "SELECT Id, RelatedIdentity, TableName, AttributeName, Taxis, DisplayName, HelpText, IsVisibleInList, InputType, DefaultValue, IsHorizontal, ExtendValues FROM siteserver_TableStyle ORDER BY Taxis DESC, Id DESC"; + +// private const string SqlUpdateTableStyle = "UPDATE siteserver_TableStyle SET AttributeName = @AttributeName, Taxis = @Taxis, DisplayName = @DisplayName, HelpText = @HelpText, IsVisibleInList = @IsVisibleInList, InputType = @InputType, DefaultValue = @DefaultValue, IsHorizontal = @IsHorizontal, ExtendValues = @ExtendValues WHERE Id = @Id"; + +// private const string SqlDeleteTableStyle = "DELETE FROM siteserver_TableStyle WHERE RelatedIdentity = @RelatedIdentity AND TableName = @TableName AND AttributeName = @AttributeName"; + +// private const string SqlInsertTableStyle = "INSERT INTO siteserver_TableStyle (RelatedIdentity, TableName, AttributeName, Taxis, DisplayName, HelpText, IsVisibleInList, InputType, DefaultValue, IsHorizontal, ExtendValues) VALUES (@RelatedIdentity, @TableName, @AttributeName, @Taxis, @DisplayName, @HelpText, @IsVisibleInList, @InputType, @DefaultValue, @IsHorizontal, @ExtendValues)"; + +// private const string ParamId = "@Id"; +// private const string ParamRelatedIdentity = "@RelatedIdentity"; +// private const string ParamTableName = "@TableName"; +// private const string ParamAttributeName = "@AttributeName"; +// private const string ParamTaxis = "@Taxis"; +// private const string ParamDisplayName = "@DisplayName"; +// private const string ParamHelpText = "@HelpText"; +// private const string ParamIsVisibleInList = "@IsVisibleInList"; +// private const string ParamInputType = "@InputType"; +// private const string ParamDefaultValue = "@DefaultValue"; +// private const string ParamIsHorizontal = "@IsHorizontal"; +// private const string ParamExtendValues = "@ExtendValues"; + +// public int InsertObject(TableStyleInfo styleInfo) +// { +// int id; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamRelatedIdentity, styleInfo.RelatedIdentity), +// GetParameter(ParamTableName, styleInfo.TableName), +// GetParameter(ParamAttributeName, styleInfo.AttributeName), +// GetParameter(ParamTaxis, styleInfo.Taxis), +// GetParameter(ParamDisplayName, styleInfo.DisplayName), +// GetParameter(ParamHelpText, styleInfo.HelpText), +// GetParameter(ParamIsVisibleInList, styleInfo.IsVisibleInList.ToString()), +// GetParameter(ParamInputType, styleInfo.InputType.Value), +// GetParameter(ParamDefaultValue, styleInfo.DefaultValue), +// GetParameter(ParamIsHorizontal, styleInfo.IsHorizontal.ToString()), +// GetParameter(ParamExtendValues,styleInfo.ToString()) +// }; + +// using (var conn = GetConnection()) +// { +// conn.Open(); +// using (var trans = conn.BeginTransaction()) +// { +// try +// { +// id = DatabaseApi.ExecuteNonQueryAndReturnId(TableName, nameof(TableStyleInfo.Id), trans, SqlInsertTableStyle, parameters); + +// DataProvider.TableStyleItem.InsertObject(trans, id, styleInfo.StyleItems); + +// trans.Commit(); +// } +// catch +// { +// trans.Rollback(); +// throw; +// } +// } +// } + +// TableStyleManager.ClearCache(); + +// return id; +// } + +// public void UpdateObject(TableStyleInfo info, bool deleteAndInsertStyleItems = true) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamAttributeName, info.AttributeName), +// GetParameter(ParamTaxis, info.Taxis), +// GetParameter(ParamDisplayName, info.DisplayName), +// GetParameter(ParamHelpText, info.HelpText), +// GetParameter(ParamIsVisibleInList, info.IsVisibleInList.ToString()), +// GetParameter(ParamInputType, info.InputType.Value), +// GetParameter(ParamDefaultValue, info.DefaultValue), +// GetParameter(ParamIsHorizontal, info.IsHorizontal.ToString()), +// GetParameter(ParamExtendValues,info.ToString()), +// GetParameter(ParamId, info.Id) +// }; + +// using (var conn = GetConnection()) +// { +// conn.Open(); +// using (var trans = conn.BeginTransaction()) +// { +// try +// { +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdateTableStyle, parameters); + +// if (deleteAndInsertStyleItems) +// { +// DataProvider.TableStyleItem.DeleteAndInsertStyleItems(trans, info.Id, info.StyleItems); +// } + +// trans.Commit(); +// } +// catch +// { +// trans.Rollback(); +// throw; +// } +// } +// } + +// TableStyleManager.ClearCache(); +// } + +// public void DeleteById(int relatedIdentity, string tableName, string attributeName) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamRelatedIdentity, relatedIdentity), +// GetParameter(ParamTableName, tableName), +// GetParameter(ParamAttributeName, attributeName) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDeleteTableStyle, parameters); + +// TableStyleManager.ClearCache(); +// } + +// public void DeleteById(List relatedIdentities, string tableName) +// { +// if (relatedIdentities == null || relatedIdentities.Count <= 0) return; + +// var sqlString = +// $"DELETE FROM siteserver_TableStyle WHERE RelatedIdentity IN ({TranslateUtils.ToSqlInStringWithoutQuote(relatedIdentities)}) AND TableName = '{AttackUtils.FilterSql(tableName)}'"; +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + +// TableStyleManager.ClearCache(); +// } + +// private TableStyleInfo GetTableStyleInfoByReader(IDataReader rdr) +// { +// var i = 0; +// var id = DatabaseApi.GetInt(rdr, i++); +// var relatedIdentity = DatabaseApi.GetInt(rdr, i++); +// var tableName = DatabaseApi.GetString(rdr, i++); +// var attributeName = DatabaseApi.GetString(rdr, i++); +// var taxis = DatabaseApi.GetInt(rdr, i++); +// var displayName = DatabaseApi.GetString(rdr, i++); +// var helpText = DatabaseApi.GetString(rdr, i++); +// var isVisibleInList = TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)); +// var inputType = DatabaseApi.GetString(rdr, i++); +// var defaultValue = DatabaseApi.GetString(rdr, i++); +// var isHorizontal = TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i++)); +// var extendValues = DatabaseApi.GetString(rdr, i); + +// var styleInfo = new TableStyleInfo(id, relatedIdentity, tableName, attributeName, taxis, displayName, helpText, isVisibleInList, InputTypeUtils.GetEnumType(inputType), defaultValue, isHorizontal, extendValues); + +// return styleInfo; +// } + +// public List> GetAllTableStyles() +// { +// var pairs = new List>(); + +// var allItemsDict = DataProvider.TableStyleItem.GetAllTableStyleItems(); + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAllTableStyle)) +// { +// while (rdr.Read()) +// { +// var styleInfo = GetTableStyleInfoByReader(rdr); + +// allItemsDict.TryGetValue(styleInfo.Id, out var items); +// styleInfo.StyleItems = items; + +// var key = TableStyleManager.GetKey(styleInfo.RelatedIdentity, styleInfo.TableName, styleInfo.AttributeName); + +// if (pairs.All(pair => pair.Key != key)) +// { +// var pair = new KeyValuePair(key, styleInfo); +// pairs.Add(pair); +// } +// } +// rdr.Close(); +// } + +// return pairs; +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/TagRepository.cs b/net452/SiteServer.CMS/Database/Repositories/TagRepository.cs new file mode 100644 index 000000000..bb31a262f --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/TagRepository.cs @@ -0,0 +1,712 @@ +using System.Collections.Generic; +using System.Text; +using Datory; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; +using SqlKata; + +namespace SiteServer.CMS.Database.Repositories +{ + public class TagRepository : Repository + { + public TagRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string SiteId = nameof(TagInfo.SiteId); + public const string ContentIdCollection = nameof(TagInfo.ContentIdCollection); + public const string Tag = nameof(TagInfo.Tag); + public const string UseNum = nameof(TagInfo.UseNum); + } + + //public void Insert(TagInfo tagInfo) + //{ + // //const string sqlString = "INSERT INTO siteserver_Tag (SiteId, ContentIdCollection, Tag, UseNum) VALUES (@SiteId, @ContentIdCollection, @Tag, @UseNum)"; + + // //IDataParameter[] parameters = + // //{ + // // GetParameter(ParamSiteId, tagInfo.SiteId), + // // GetParameter(ParamContentIdCollection, tagInfo.ContentIdCollection), + // // GetParameter(ParamTag, tagInfo.Tag), + // // GetParameter(ParamUseNum, tagInfo.UseNum) + // //}; + + // //return DatabaseApi.ExecuteNonQueryAndReturnId(ConnectionString, TableName, nameof(TagInfo.Id), sqlString, parameters); + + // InsertO(tagInfo); + //} + + //public void Update(TagInfo tagInfo) + //{ + // //const string sqlString = "UPDATE siteserver_Tag SET ContentIdCollection = @ContentIdCollection, UseNum = @UseNum WHERE Id = @Id"; + + // //IDataParameter[] parameters = + // //{ + // // GetParameter(ParamContentIdCollection, tagInfo.ContentIdCollection), + // // GetParameter(ParamUseNum, tagInfo.UseNum), + // // GetParameter(ParamId, tagInfo.Id) + // //}; + + // //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + // UpdateObject(tagInfo); + //} + + public TagInfo GetTagInfo(int siteId, string tag) + { + //TagInfo tagInfo = null; + + //const string sqlString = "SELECT Id, SiteId, ContentIdCollection, Tag, UseNum FROM siteserver_Tag WHERE SiteId = @SiteId AND Tag = @Tag"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamSiteId, siteId), + // GetParameter(ParamTag, tag) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // var i = 0; + // tagInfo = new TagInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i)); + // } + // rdr.Close(); + //} + //return tagInfo; + + return Get(Q.Where(Attr.SiteId, siteId).Where(Attr.Tag, tag)); + } + + public IList GetTagInfoList(int siteId, int contentId) + { + //var list = new List(); + + //var whereString = GetWhereString(null, siteId, contentId); + //var sqlString = + // $"SELECT Id, SiteId, ContentIdCollection, Tag, UseNum FROM siteserver_Tag {whereString}"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var tagInfo = new TagInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i)); + // list.Add(tagInfo); + // } + // rdr.Close(); + //} + //return list; + + var query = GetQuery(null, siteId, contentId); + return GetAll(query); + } + + public string GetSqlString(int siteId, int contentId, bool isOrderByCount, int totalNum) + { + var whereString = GetWhereString(null, siteId, contentId); + var orderString = string.Empty; + if (isOrderByCount) + { + orderString = "ORDER BY UseNum DESC"; + } + + return DataProvider.DatabaseApi.GetSqlString(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, "siteserver_Tag", new List + { + nameof(TagInfo.Id), + nameof(TagInfo.SiteId), + nameof(TagInfo.ContentIdCollection), + nameof(TagInfo.Tag), + nameof(TagInfo.UseNum) + }, whereString, orderString, totalNum); + } + + public IList GetTagInfoList(int siteId, int contentId, bool isOrderByCount, int totalNum) + { + //var list = new List(); + + //var whereString = GetWhereString(null, siteId, contentId); + //var orderString = string.Empty; + //if (isOrderByCount) + //{ + // orderString = "ORDER BY UseNum DESC"; + //} + + //var sqlString = DatorySql.GetSqlString("siteserver_Tag", new List + //{ + // nameof(TagInfo.Id), + // nameof(TagInfo.SiteId), + // nameof(TagInfo.ContentIdCollection), + // nameof(TagInfo.Tag), + // nameof(TagInfo.UseNum) + //}, whereString, orderString, totalNum); + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var tagInfo = new TagInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i)); + // list.Add(tagInfo); + // } + // rdr.Close(); + //} + //return list; + + var query = GetQuery(null, siteId, contentId).Limit(totalNum); + if (isOrderByCount) + { + query.OrderByDesc(Attr.UseNum); + } + + return GetAll(query); + } + + public IList GetTagListByStartString(int siteId, string startString, int totalNum) + { + //var sqlString = DatorySql.GetSqlString("siteserver_Tag", new List + // { + // nameof(TagInfo.Tag), + // nameof(TagInfo.UseNum) + // }, + // $"WHERE SiteId = {siteId} AND {SqlUtils.GetInStr("Tag", AttackUtils.FilterSql(startString))}", + // "ORDER BY UseNum DESC", 0, totalNum, true); + //return DatabaseApi.GetStringList(sqlString); + + return GetAll(Q + .Select(Attr.Tag) + .Where(Attr.SiteId, siteId) + .WhereContains(Attr.Tag, startString) + .OrderByDesc(Attr.UseNum) + .Distinct() + .Limit(totalNum)); + } + + public IList GetTagList(int siteId) + { + //var sqlString = + // $"SELECT Tag FROM siteserver_Tag WHERE SiteId = {siteId} ORDER BY UseNum DESC"; + //return DatabaseApi.GetStringList(sqlString); + + return GetAll(Q + .Select(Attr.Tag) + .Where(Attr.SiteId, siteId) + .Distinct() + .OrderByDesc(Attr.UseNum)); + } + + public void DeleteTags(int siteId) + { + //var whereString = GetWhereString(null, siteId, 0); + //var sqlString = $"DELETE FROM siteserver_Tag {whereString}"; + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + var query = GetQuery(null, siteId, 0); + Delete(query); + } + + public void DeleteTag(string tag, int siteId) + { + //var whereString = GetWhereString(tag, siteId, 0); + //var sqlString = $"DELETE FROM siteserver_Tag {whereString}"; + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + var query = GetQuery(tag, siteId, 0); + Delete(query); + } + + public int GetTagCount(string tag, int siteId) + { + var contentIdList = GetContentIdListByTag(tag, siteId); + return contentIdList.Count; + } + + private string GetWhereString(string tag, int siteId, int contentId) + { + var builder = new StringBuilder(); + builder.Append($" WHERE SiteId = {siteId} "); + if (!string.IsNullOrEmpty(tag)) + { + builder.Append($"AND Tag = '{AttackUtils.FilterSql(tag)}' "); + } + if (contentId > 0) + { + builder.Append( + $"AND (ContentIdCollection = '{contentId}' OR ContentIdCollection LIKE '{contentId},%' OR ContentIdCollection LIKE '%,{contentId},%' OR ContentIdCollection LIKE '%,{contentId}')"); + } + + return builder.ToString(); + } + + private Query GetQuery(string tag, int siteId, int contentId) + { + var query = Q.Where(Attr.SiteId, siteId); + if (!string.IsNullOrEmpty(tag)) + { + query.Where(Attr.Tag, tag); + } + if (contentId > 0) + { + query.Where(q => q + .Where(Attr.ContentIdCollection, contentId.ToString()) + .OrWhereStarts(Attr.ContentIdCollection, $"{contentId},") + .OrWhereContains(Attr.ContentIdCollection, $",{contentId},") + .OrWhereEnds(Attr.ContentIdCollection, $",{contentId}")); + } + + return query; + } + + public List GetContentIdListByTag(string tag, int siteId) + { + //var idList = new List(); + //if (string.IsNullOrEmpty(tag)) return idList; + + //var whereString = GetWhereString(tag, siteId, 0); + //var sqlString = "SELECT ContentIdCollection FROM siteserver_Tag" + whereString; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // if (rdr.Read()) + // { + // var contentIdCollection = DatabaseApi.GetString(rdr, 0); + // var contentIdList = TranslateUtils.StringCollectionToIntList(contentIdCollection); + // foreach (var contentId in contentIdList) + // { + // if (contentId > 0 && !idList.Contains(contentId)) + // { + // idList.Add(contentId); + // } + // } + // } + // rdr.Close(); + //} + //return idList; + + var idList = new List(); + if (string.IsNullOrEmpty(tag)) return idList; + + var query = GetQuery(tag, siteId, 0); + var contentIdCollectionList = GetAll(query.Select(Attr.ContentIdCollection)); + foreach (var contentIdCollection in contentIdCollectionList) + { + var contentIdList = TranslateUtils.StringCollectionToIntList(contentIdCollection); + foreach (var contentId in contentIdList) + { + if (contentId > 0 && !idList.Contains(contentId)) + { + idList.Add(contentId); + } + } + } + + return idList; + } + + //private List GetInParameterList(string parameterName, ICollection valueCollection, out string parameterNameList) + //{ + // parameterNameList = string.Empty; + // if (valueCollection == null || valueCollection.Count <= 0) return new List(); + + // var parameterList = new List(); + + // var sbCondition = new StringBuilder(); + // var i = 0; + // foreach (var obj in valueCollection) + // { + // i++; + + // var value = obj.ToString(); + // var name = parameterName + "_" + i; + + // sbCondition.Append(name + ","); + + // parameterList.Add(GetParameter(name, value)); + // } + + // parameterNameList = sbCondition.ToString().TrimEnd(','); + + // return parameterList; + //} + + public IList GetContentIdListByTagCollection(List tagCollection, int siteId) + { + var contentIdList = new List(); + if (tagCollection.Count <= 0) return contentIdList; + + var contentIdCollectionList = GetAll(Q + .Select(Attr.ContentIdCollection) + .Where(Attr.SiteId, siteId) + .WhereIn(Attr.Tag, tagCollection)); + + foreach (var contentIdCollection in contentIdCollectionList) + { + var list = TranslateUtils.StringCollectionToIntList(contentIdCollection); + foreach (var contentId in list) + { + if (contentId > 0 && !contentIdList.Contains(contentId)) + { + contentIdList.Add(contentId); + } + } + } + + return contentIdList; + + //var parameterList = GetInParameterList(ParamTag, tagCollection, out var parameterNameList); + + //var sqlString = + // $"SELECT ContentIdCollection FROM siteserver_Tag WHERE Tag IN ({parameterNameList}) AND SiteId = @SiteId"; + + //var paramList = new List(); + //paramList.AddRange(parameterList); + //paramList.Add(GetParameter(ParamSiteId, siteId)); + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, paramList.ToArray())) + //{ + // while (rdr.Read()) + // { + // var contentIdCollection = DatabaseApi.GetString(rdr, 0); + // var list = TranslateUtils.StringCollectionToIntList(contentIdCollection); + // foreach (var contentId in list) + // { + // if (contentId > 0 && !contentIdList.Contains(contentId)) + // { + // contentIdList.Add(contentId); + // } + // } + // } + // rdr.Close(); + //} + //return contentIdList; + } + } +} + + +//using System.Collections; +//using System.Collections.Generic; +//using System.Collections.Specialized; +//using System.Data; +//using System.Text; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class TagDao : DataProviderBase +// { +// public override string TableName => "siteserver_Tag"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(TagInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(TagInfo.SiteId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(TagInfo.ContentIdCollection), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TagInfo.Tag), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TagInfo.UseNum), +// DataType = DataType.Integer +// } +// }; + +// private const string ParamId = "@Id"; +// private const string ParamSiteId = "@SiteId"; +// private const string ParamContentIdCollection = "@ContentIdCollection"; +// private const string ParamTag = "@Tag"; +// private const string ParamUseNum = "@UseNum"; + +// public int InsertObject(TagInfo tagInfo) +// { +// const string sqlString = "INSERT INTO siteserver_Tag (SiteId, ContentIdCollection, Tag, UseNum) VALUES (@SiteId, @ContentIdCollection, @Tag, @UseNum)"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamSiteId, tagInfo.SiteId), +// GetParameter(ParamContentIdCollection, tagInfo.ContentIdCollection), +// GetParameter(ParamTag, tagInfo.Tag), +// GetParameter(ParamUseNum, tagInfo.UseNum) +// }; + +// return DatabaseApi.ExecuteNonQueryAndReturnId(ConnectionString, TableName, nameof(TagInfo.Id), sqlString, parameters); +// } + +// public void UpdateObject(TagInfo tagInfo) +// { +// const string sqlString = "UPDATE siteserver_Tag SET ContentIdCollection = @ContentIdCollection, UseNum = @UseNum WHERE Id = @Id"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamContentIdCollection, tagInfo.ContentIdCollection), +// GetParameter(ParamUseNum, tagInfo.UseNum), +// GetParameter(ParamId, tagInfo.Id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// public TagInfo GetTagInfo(int siteId, string tag) +// { +// TagInfo tagInfo = null; + +// const string sqlString = "SELECT Id, SiteId, ContentIdCollection, Tag, UseNum FROM siteserver_Tag WHERE SiteId = @SiteId AND Tag = @Tag"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamSiteId, siteId), +// GetParameter(ParamTag, tag) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// var i = 0; +// tagInfo = new TagInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i)); +// } +// rdr.Close(); +// } +// return tagInfo; +// } + +// public List GetTagInfoList(int siteId, int contentId) +// { +// var list = new List(); + +// var whereString = GetWhereString(null, siteId, contentId); +// var sqlString = +// $"SELECT Id, SiteId, ContentIdCollection, Tag, UseNum FROM siteserver_Tag {whereString}"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var tagInfo = new TagInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i)); +// list.Add(tagInfo); +// } +// rdr.Close(); +// } +// return list; +// } + +// public string GetSqlString(int siteId, int contentId, bool isOrderByCount, int totalNum) +// { +// var whereString = GetWhereString(null, siteId, contentId); +// var orderString = string.Empty; +// if (isOrderByCount) +// { +// orderString = "ORDER BY UseNum DESC"; +// } + +// return DatorySql.GetSqlString("siteserver_Tag", new List +// { +// nameof(TagInfo.Id), +// nameof(TagInfo.SiteId), +// nameof(TagInfo.ContentIdCollection), +// nameof(TagInfo.Tag), +// nameof(TagInfo.UseNum) +// }, whereString, orderString, totalNum); +// } + +// public List GetTagInfoList(int siteId, int contentId, bool isOrderByCount, int totalNum) +// { +// var list = new List(); + +// var whereString = GetWhereString(null, siteId, contentId); +// var orderString = string.Empty; +// if (isOrderByCount) +// { +// orderString = "ORDER BY UseNum DESC"; +// } + +// var sqlString = DatorySql.GetSqlString("siteserver_Tag", new List +// { +// nameof(TagInfo.Id), +// nameof(TagInfo.SiteId), +// nameof(TagInfo.ContentIdCollection), +// nameof(TagInfo.Tag), +// nameof(TagInfo.UseNum) +// }, whereString, orderString, totalNum); + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var tagInfo = new TagInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetInt(rdr, i)); +// list.Add(tagInfo); +// } +// rdr.Close(); +// } +// return list; +// } + +// public List GetTagListByStartString(int siteId, string startString, int totalNum) +// { +// var sqlString = DatorySql.GetSqlString("siteserver_Tag", new List +// { +// nameof(TagInfo.Tag), +// nameof(TagInfo.UseNum) +// }, +// $"WHERE SiteId = {siteId} AND {SqlUtils.GetInStr("Tag", AttackUtils.FilterSql(startString))}", +// "ORDER BY UseNum DESC", 0, totalNum, true); +// return DatabaseApi.GetStringList(sqlString); +// } + +// public List GetTagList(int siteId) +// { +// var sqlString = +// $"SELECT Tag FROM siteserver_Tag WHERE SiteId = {siteId} ORDER BY UseNum DESC"; +// return DatabaseApi.GetStringList(sqlString); +// } + +// public void DeleteTags(int siteId) +// { +// var whereString = GetWhereString(null, siteId, 0); +// var sqlString = $"DELETE FROM siteserver_Tag {whereString}"; +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } + +// public void DeleteTag(string tag, int siteId) +// { +// var whereString = GetWhereString(tag, siteId, 0); +// var sqlString = $"DELETE FROM siteserver_Tag {whereString}"; +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } + +// public int GetTagCount(string tag, int siteId) +// { +// var contentIdList = GetContentIdListByTag(tag, siteId); +// return contentIdList.Count; +// } + +// private string GetWhereString(string tag, int siteId, int contentId) +// { +// var builder = new StringBuilder(); +// builder.Append($" WHERE SiteId = {siteId} "); +// if (!string.IsNullOrEmpty(tag)) +// { +// builder.Append($"AND Tag = '{AttackUtils.FilterSql(tag)}' "); +// } +// if (contentId > 0) +// { +// builder.Append( +// $"AND (ContentIdCollection = '{contentId}' OR ContentIdCollection LIKE '{contentId},%' OR ContentIdCollection LIKE '%,{contentId},%' OR ContentIdCollection LIKE '%,{contentId}')"); +// } + +// return builder.ToString(); +// } + +// public List GetContentIdListByTag(string tag, int siteId) +// { +// var idList = new List(); +// if (string.IsNullOrEmpty(tag)) return idList; + +// var whereString = GetWhereString(tag, siteId, 0); +// var sqlString = "SELECT ContentIdCollection FROM siteserver_Tag" + whereString; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// if (rdr.Read()) +// { +// var contentIdCollection = DatabaseApi.GetString(rdr, 0); +// var contentIdList = TranslateUtils.StringCollectionToIntList(contentIdCollection); +// foreach (var contentId in contentIdList) +// { +// if (contentId > 0 && !idList.Contains(contentId)) +// { +// idList.Add(contentId); +// } +// } +// } +// rdr.Close(); +// } +// return idList; +// } + +// private List GetInParameterList(string parameterName, ICollection valueCollection, out string parameterNameList) +// { +// parameterNameList = string.Empty; +// if (valueCollection == null || valueCollection.Count <= 0) return new List(); + +// var parameterList = new List(); + +// var sbCondition = new StringBuilder(); +// var i = 0; +// foreach (var obj in valueCollection) +// { +// i++; + +// var value = obj.ToString(); +// var name = parameterName + "_" + i; + +// sbCondition.Append(name + ","); + +// parameterList.Add(GetParameter(name, value)); +// } + +// parameterNameList = sbCondition.ToString().TrimEnd(','); + +// return parameterList; +// } + +// public List GetContentIdListByTagCollection(StringCollection tagCollection, int siteId) +// { +// var contentIdList = new List(); +// if (tagCollection.Count <= 0) return contentIdList; + +// var parameterList = GetInParameterList(ParamTag, tagCollection, out var parameterNameList); + +// var sqlString = +// $"SELECT ContentIdCollection FROM siteserver_Tag WHERE Tag IN ({parameterNameList}) AND SiteId = @SiteId"; + +// var paramList = new List(); +// paramList.AddRange(parameterList); +// paramList.Add(GetParameter(ParamSiteId, siteId)); + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, paramList.ToArray())) +// { +// while (rdr.Read()) +// { +// var contentIdCollection = DatabaseApi.GetString(rdr, 0); +// var list = TranslateUtils.StringCollectionToIntList(contentIdCollection); +// foreach (var contentId in list) +// { +// if (contentId > 0 && !contentIdList.Contains(contentId)) +// { +// contentIdList.Add(contentId); +// } +// } +// } +// rdr.Close(); +// } +// return contentIdList; +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/TemplateLogRepository.cs b/net452/SiteServer.CMS/Database/Repositories/TemplateLogRepository.cs new file mode 100644 index 000000000..3071c7ec0 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/TemplateLogRepository.cs @@ -0,0 +1,272 @@ +using System; +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class TemplateLogRepository : Repository + { + public TemplateLogRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(TemplateLogInfo.Id); + public const string TemplateId = nameof(TemplateLogInfo.TemplateId); + public const string AddDate = nameof(TemplateLogInfo.AddDate); + public const string AddUserName = nameof(TemplateLogInfo.AddUserName); + public const string ContentLength = nameof(TemplateLogInfo.ContentLength); + public const string TemplateContent = nameof(TemplateLogInfo.TemplateContent); + } + + //public void Insert(TemplateLogInfo logInfo) + //{ + // //var sqlString = "INSERT INTO siteserver_TemplateLog(TemplateId, SiteId, AddDate, AddUserName, ContentLength, TemplateContent) VALUES (@TemplateId, @SiteId, @AddDate, @AddUserName, @ContentLength, @TemplateContent)"; + + // //IDataParameter[] parameters = + // //{ + // // GetParameter(ParamTemplateId, logInfo.TemplateId), + // // GetParameter(ParamSiteId, logInfo.SiteId), + // // GetParameter(ParamAddDate,logInfo.AddDate), + // // GetParameter(ParamAddUserName, logInfo.AddUserName), + // // GetParameter(ParamContentLength, logInfo.ContentLength), + // // GetParameter(ParamTemplateContent,logInfo.TemplateContent) + // //}; + + // //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + // InsertObject(logInfo); + //} + + public string GetSelectCommend(int siteId, int templateId) + { + return + $"SELECT ID, TemplateId, SiteId, AddDate, AddUserName, ContentLength, TemplateContent FROM siteserver_TemplateLog WHERE SiteId = {siteId} AND TemplateId = {templateId}"; + } + + public string GetTemplateContent(int logId) + { + //var templateContent = string.Empty; + + //var sqlString = $"SELECT TemplateContent FROM siteserver_TemplateLog WHERE ID = {logId}"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // if (rdr.Read()) + // { + // templateContent = DatabaseApi.GetString(rdr, 0); + // } + // rdr.Close(); + //} + + //return templateContent; + + return Get(Q + .Select(Attr.TemplateContent) + .Where(Attr.Id, logId)); + } + + public Dictionary GetLogIdWithNameDictionary(int templateId) + { + var dictionary = new Dictionary(); + + var dataList = GetAll<(int Id, DateTime? AddDate, string AddUserName, int ContentLength)>(Q + .Select(Attr.Id, Attr.AddDate, Attr.AddUserName, Attr.ContentLength) + .Where(Attr.TemplateId, templateId)); + + foreach (var result in dataList) + { + var id = result.Id; + var addDate = result.AddDate; + var addUserName = result.AddUserName; + var contentLength = result.ContentLength; + + var name = + $"修订时间:{DateUtils.GetDateAndTimeString(addDate)},修订人:{addUserName},字符数:{contentLength}"; + + dictionary.Add(id, name); + } + + //string sqlString = + // $"SELECT ID, AddDate, AddUserName, ContentLength FROM siteserver_TemplateLog WHERE TemplateId = {templateId}"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // var id = DatabaseApi.GetInt(rdr, 0); + // var addDate = DatabaseApi.GetDateTime(rdr, 1); + // var addUserName = DatabaseApi.GetString(rdr, 2); + // var contentLength = DatabaseApi.GetInt(rdr, 3); + + // string name = + // $"修订时间:{DateUtils.GetDateAndTimeString(addDate)},修订人:{addUserName},字符数:{contentLength}"; + + // dictionary.Add(id, name); + // } + // rdr.Close(); + //} + + return dictionary; + } + + public void Delete(List idList) + { + //string sqlString = + // $"DELETE FROM siteserver_TemplateLog WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + if (idList != null && idList.Count > 0) + { + Delete(Q.WhereIn(Attr.Id, idList)); + } + } + } +} + + +//using System.Collections.Generic; +//using System.Data; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class TemplateLog : DataProviderBase +// { +// public override string TableName => "siteserver_TemplateLog"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(TemplateLogInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(TemplateLogInfo.TemplateId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(TemplateLogInfo.SiteId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(TemplateLogInfo.AddDate), +// DataType = DataType.DateTime +// }, +// new TableColumn +// { +// AttributeName = nameof(TemplateLogInfo.AddUserName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TemplateLogInfo.ContentLength), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(TemplateLogInfo.TemplateContent), +// DataType = DataType.Text +// } +// }; + +// private const string ParamTemplateId = "@TemplateId"; +// private const string ParamSiteId = "@SiteId"; +// private const string ParamAddDate = "@AddDate"; +// private const string ParamAddUserName = "@AddUserName"; +// private const string ParamContentLength = "@ContentLength"; +// private const string ParamTemplateContent = "@TemplateContent"; + +// public void InsertObject(TemplateLogInfo logInfo) +// { +// var sqlString = "INSERT INTO siteserver_TemplateLog(TemplateId, SiteId, AddDate, AddUserName, ContentLength, TemplateContent) VALUES (@TemplateId, @SiteId, @AddDate, @AddUserName, @ContentLength, @TemplateContent)"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamTemplateId, logInfo.TemplateId), +// GetParameter(ParamSiteId, logInfo.SiteId), +// GetParameter(ParamAddDate,logInfo.AddDate), +// GetParameter(ParamAddUserName, logInfo.AddUserName), +// GetParameter(ParamContentLength, logInfo.ContentLength), +// GetParameter(ParamTemplateContent,logInfo.TemplateContent) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// public string GetSelectCommend(int siteId, int templateId) +// { +// return +// $"SELECT ID, TemplateId, SiteId, AddDate, AddUserName, ContentLength, TemplateContent FROM siteserver_TemplateLog WHERE SiteId = {siteId} AND TemplateId = {templateId}"; +// } + +// public string GetTemplateContent(int logId) +// { +// var templateContent = string.Empty; + +// string sqlString = $"SELECT TemplateContent FROM siteserver_TemplateLog WHERE ID = {logId}"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// if (rdr.Read()) +// { +// templateContent = DatabaseApi.GetString(rdr, 0); +// } +// rdr.Close(); +// } + +// return templateContent; +// } + +// public Dictionary GetLogIdWithNameDictionary(int siteId, int templateId) +// { +// var dictionary = new Dictionary(); + +// string sqlString = +// $"SELECT ID, AddDate, AddUserName, ContentLength FROM siteserver_TemplateLog WHERE TemplateId = {templateId}"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var id = DatabaseApi.GetInt(rdr, 0); +// var addDate = DatabaseApi.GetDateTime(rdr, 1); +// var addUserName = DatabaseApi.GetString(rdr, 2); +// var contentLength = DatabaseApi.GetInt(rdr, 3); + +// string name = +// $"修订时间:{DateUtils.GetDateAndTimeString(addDate)},修订人:{addUserName},字符数:{contentLength}"; + +// dictionary.Add(id, name); +// } +// rdr.Close(); +// } + +// return dictionary; +// } + +// public void DeleteById(List idList) +// { +// if (idList != null && idList.Count > 0) +// { +// string sqlString = +// $"DELETE FROM siteserver_TemplateLog WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/TemplateRepository.cs b/net452/SiteServer.CMS/Database/Repositories/TemplateRepository.cs new file mode 100644 index 000000000..d05be9c5b --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/TemplateRepository.cs @@ -0,0 +1,959 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using Datory; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class TemplateRepository : Repository + { + public TemplateRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(TemplateInfo.Id); + public const string SiteId = nameof(TemplateInfo.SiteId); + public const string TemplateName = nameof(TemplateInfo.TemplateName); + public const string TemplateType = "TemplateType"; + public const string RelatedFileName = nameof(TemplateInfo.RelatedFileName); + public const string IsDefault = "IsDefault"; + } + + public int Insert(TemplateInfo templateInfo, string templateContent, string administratorName) + { + if (templateInfo.Default) + { + SetAllTemplateDefaultToFalse(templateInfo.SiteId, templateInfo.Type); + } + + //const string sqlInsertTemplate = "INSERT INTO siteserver_Template (SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault) VALUES (@SiteId, @TemplateName, @TemplateType, @RelatedFileName, @CreatedFileFullName, @CreatedFileExtName, @Charset, @IsDefault)"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamSiteId, templateInfo.SiteId), + // GetParameter(ParamTemplateName, templateInfo.TemplateName), + // GetParameter(ParamTemplateType, templateInfo.TemplateType.Value), + // GetParameter(ParamRelatedFileName, templateInfo.RelatedFileName), + // GetParameter(ParamCreatedFileFullName, templateInfo.CreatedFileFullName), + // GetParameter(ParamCreatedFileExtName, templateInfo.CreatedFileExtName), + // GetParameter(ParamCharset, ECharsetUtils.GetValueById(templateInfo.Charset)), + // GetParameter(ParamIsDefault, templateInfo.IsDefault.ToString()) + //}; + + //var id = DatabaseApi.ExecuteNonQueryAndReturnId(ConnectionString, TableName, nameof(TemplateInfo.Id), sqlInsertTemplate, parameters); + + var id = base.Insert(templateInfo); + + var siteInfo = SiteManager.GetSiteInfo(templateInfo.SiteId); + TemplateManager.WriteContentToTemplateFile(siteInfo, templateInfo, templateContent, administratorName); + + TemplateManager.RemoveCache(templateInfo.SiteId); + + return id; + } + + public void Update(SiteInfo siteInfo, TemplateInfo templateInfo, string templateContent, string administratorName) + { + if (templateInfo.Default) + { + SetAllTemplateDefaultToFalse(siteInfo.Id, templateInfo.Type); + } + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamTemplateName, templateInfo.TemplateName), + // GetParameter(ParamTemplateType, templateInfo.TemplateType.Value), + // GetParameter(ParamRelatedFileName, templateInfo.RelatedFileName), + // GetParameter(ParamCreatedFileFullName, templateInfo.CreatedFileFullName), + // GetParameter(ParamCreatedFileExtName, templateInfo.CreatedFileExtName), + // GetParameter(ParamCharset, ECharsetUtils.GetValueById(templateInfo.Charset)), + // GetParameter(ParamIsDefault, templateInfo.IsDefault.ToString()), + // GetParameter(ParamId, templateInfo.Id) + //}; + //string SqlUpdateTemplate = "UPDATE siteserver_Template SET TemplateName = @TemplateName, TemplateType = @TemplateType, RelatedFileName = @RelatedFileName, CreatedFileFullName = @CreatedFileFullName, CreatedFileExtName = @CreatedFileExtName, Charset = @Charset, IsDefault = @IsDefault WHERE Id = @Id"; + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdateTemplate, parameters); + + Update(templateInfo); + + TemplateManager.WriteContentToTemplateFile(siteInfo, templateInfo, templateContent, administratorName); + + TemplateManager.RemoveCache(templateInfo.SiteId); + } + + private void SetAllTemplateDefaultToFalse(int siteId, TemplateType templateType) + { + //var sqlString = "UPDATE siteserver_Template SET IsDefault = @IsDefault WHERE SiteId = @SiteId AND TemplateType = @TemplateType"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamIsDefault, false.ToString()), + // GetParameter(ParamSiteId, siteId), + // GetParameter(ParamTemplateType, templateType.Value) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Update(Q + .Set(Attr.IsDefault, false.ToString()) + .Where(Attr.SiteId, siteId) + .Where(Attr.TemplateType, templateType.Value) + ); + } + + public void SetDefault(int siteId, int id) + { + var info = TemplateManager.GetTemplateInfo(siteId, id); + SetAllTemplateDefaultToFalse(info.SiteId, info.Type); + + //const string sqlString = "UPDATE siteserver_Template SET IsDefault = @IsDefault WHERE Id = @Id"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamIsDefault, true.ToString()), + // GetParameter(ParamId, id) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Update(Q + .Set(Attr.IsDefault, true.ToString()) + .Where(Attr.Id, id) + ); + + TemplateManager.RemoveCache(siteId); + } + + public void Delete(int siteId, int id) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + var templateInfo = TemplateManager.GetTemplateInfo(siteId, id); + var filePath = TemplateManager.GetTemplateFilePath(siteInfo, templateInfo); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamId, id) + //}; + //string SqlDeleteTemplate = "DELETE FROM siteserver_Template WHERE Id = @Id"; + //DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDeleteTemplate, parameters); + + Delete(id); + + FileUtils.DeleteFileIfExists(filePath); + + TemplateManager.RemoveCache(siteId); + } + + public string GetImportTemplateName(int siteId, string templateName) + { + string importTemplateName; + if (templateName.IndexOf("_", StringComparison.Ordinal) != -1) + { + var templateNameCount = 0; + var lastTemplateName = templateName.Substring(templateName.LastIndexOf("_", StringComparison.Ordinal) + 1); + var firstTemplateName = templateName.Substring(0, templateName.Length - lastTemplateName.Length); + try + { + templateNameCount = int.Parse(lastTemplateName); + } + catch + { + // ignored + } + templateNameCount++; + importTemplateName = firstTemplateName + templateNameCount; + } + else + { + importTemplateName = templateName + "_1"; + } + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamSiteId, siteId), + // GetParameter(ParamTemplateName, importTemplateName) + //}; + //string SqlSelectTemplateByTemplateName = "SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = @SiteId AND TemplateType = @TemplateType AND TemplateName = @TemplateName"; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectTemplateByTemplateName, parameters)) + //{ + // if (rdr.Read()) + // { + // importTemplateName = GetImportTemplateName(siteId, importTemplateName); + // } + // rdr.Close(); + //} + + var isExists = Exists(Q.Where(Attr.SiteId, siteId).Where(Attr.TemplateName, importTemplateName)); + if (isExists) + { + importTemplateName = GetImportTemplateName(siteId, importTemplateName); + } + + return importTemplateName; + } + + public Dictionary GetCountDictionary(int siteId) + { + var dictionary = new Dictionary(); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamSiteId, siteId) + //}; + //string SqlSelectTemplateCount = "SELECT TemplateType, COUNT(*) FROM siteserver_Template WHERE SiteId = @SiteId GROUP BY TemplateType"; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectTemplateCount, parameters)) + //{ + // while (rdr.Read()) + // { + // var templateType = TemplateTypeUtils.GetEnumType(DatabaseApi.GetString(rdr, 0)); + // var count = DatabaseApi.GetInt(rdr, 1); + + // dictionary.Add(templateType, count); + // } + // rdr.Close(); + //} + + var dataList = GetAll<(string TemplateType, int Count)>(Q + .Select(Attr.TemplateType) + .SelectRaw("COUNT(*) as Count") + .Where(Attr.SiteId, siteId) + .GroupBy(Attr.TemplateType)); + + foreach (var data in dataList) + { + var templateType = TemplateTypeUtils.GetEnumType(data.TemplateType); + var count = data.Count; + + if (dictionary.ContainsKey(templateType)) + { + dictionary[templateType] += count; + } + else + { + dictionary[templateType] = count; + } + } + + return dictionary; + } + + public IDataReader GetDataSourceByType(int siteId, TemplateType type) + { + IDataParameter[] parameters = + { + DataProvider.DatabaseApi.GetParameter("@SiteId", siteId), + DataProvider.DatabaseApi.GetParameter("@TemplateType", type.Value) + }; + var sqlString = "SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = @SiteId AND TemplateType = @TemplateType ORDER BY RelatedFileName"; + return DataProvider.DatabaseApi.ExecuteReader(WebConfigUtils.ConnectionString, sqlString, parameters); + } + + public IDataReader GetDataSource(int siteId, string searchText, string templateTypeString) + { + if (string.IsNullOrEmpty(searchText) && string.IsNullOrEmpty(templateTypeString)) + { + IDataParameter[] parameters = + { + DataProvider.DatabaseApi.GetParameter("@SiteId", siteId) + }; + string SqlSelectAllTemplateBySiteId = "SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = @SiteId ORDER BY TemplateType, RelatedFileName"; + var enumerable = DataProvider.DatabaseApi.ExecuteReader(WebConfigUtils.ConnectionString, SqlSelectAllTemplateBySiteId, parameters); + return enumerable; + } + if (!string.IsNullOrEmpty(searchText)) + { + var whereString = (string.IsNullOrEmpty(templateTypeString)) ? string.Empty : + $"AND TemplateType = '{templateTypeString}' "; + searchText = AttackUtils.FilterSql(searchText); + whereString += + $"AND (TemplateName LIKE '%{searchText}%' OR RelatedFileName LIKE '%{searchText}%' OR CreatedFileFullName LIKE '%{searchText}%' OR CreatedFileExtName LIKE '%{searchText}%')"; + var sqlString = + $"SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = {siteId} {whereString} ORDER BY TemplateType, RelatedFileName"; + + var enumerable = DataProvider.DatabaseApi.ExecuteReader(WebConfigUtils.ConnectionString, sqlString); + return enumerable; + } + + return GetDataSourceByType(siteId, TemplateTypeUtils.GetEnumType(templateTypeString)); + } + + public IList GetTemplateInfoListByType(int siteId, TemplateType type) + { + //var list = new List(); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamSiteId, siteId), + // GetParameter(ParamTemplateType, type.Value) + //}; + //string SqlSelectAllTemplateByType = "SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = @SiteId AND TemplateType = @TemplateType ORDER BY RelatedFileName"; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAllTemplateByType, parameters)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var info = new TemplateInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), TemplateTypeUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), ECharsetUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i))); + // list.Add(info); + // } + // rdr.Close(); + //} + //return list; + + return GetAll(Q + .Where(Attr.SiteId, siteId) + .Where(Attr.TemplateType, type.Value) + .OrderBy(Attr.RelatedFileName)); + } + + public IList GetTemplateInfoListOfFile(int siteId) + { + //var list = new List(); + + //string sqlString = + // $"SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = {siteId} AND TemplateType = '{TemplateType.FileTemplate.Value}' ORDER BY RelatedFileName"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var info = new TemplateInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), TemplateTypeUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), ECharsetUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i))); + // list.Add(info); + // } + // rdr.Close(); + //} + //return list; + + return GetAll(Q + .Where(Attr.SiteId, siteId) + .Where(Attr.TemplateType, TemplateType.FileTemplate.Value) + .OrderBy(Attr.RelatedFileName)); + } + + public IList GetTemplateInfoListBySiteId(int siteId) + { + //var list = new List(); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamSiteId, siteId) + //}; + //string SqlSelectAllTemplateBySiteId = "SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = @SiteId ORDER BY TemplateType, RelatedFileName"; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAllTemplateBySiteId, parameters)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var info = new TemplateInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), TemplateTypeUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), ECharsetUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i))); + // list.Add(info); + // } + // rdr.Close(); + //} + //return list; + + return GetAll(Q + .Where(Attr.SiteId, siteId) + .OrderBy(Attr.TemplateType, Attr.RelatedFileName)); + } + + public IList GetTemplateNameList(int siteId, TemplateType templateType) + { + //var list = new List(); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamSiteId, siteId), + // GetParameter(ParamTemplateType, templateType.Value) + //}; + //string SqlSelectTemplateNames = "SELECT TemplateName FROM siteserver_Template WHERE SiteId = @SiteId AND TemplateType = @TemplateType"; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectTemplateNames, parameters)) + //{ + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetString(rdr, 0)); + // } + // rdr.Close(); + //} + + //return list; + + return GetAll(Q + .Select(Attr.TemplateName) + .Where(Attr.SiteId, siteId) + .Where(Attr.TemplateType, templateType.Value)); + } + + public IList GetLowerRelatedFileNameList(int siteId, TemplateType templateType) + { + //var list = new List(); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamSiteId, siteId), + // GetParameter(ParamTemplateType, templateType.Value) + //}; + //string SqlSelectRelatedFileNameByTemplateType = "SELECT RelatedFileName FROM siteserver_Template WHERE SiteId = @SiteId AND TemplateType = @TemplateType"; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectRelatedFileNameByTemplateType, parameters)) + //{ + // while (rdr.Read()) + // { + // list.Add(DatabaseApi.GetString(rdr, 0).ToLower()); + // } + // rdr.Close(); + //} + + //return list; + + return GetAll(Q + .Select(Attr.RelatedFileName) + .Where(Attr.SiteId, siteId) + .Where(Attr.TemplateType, templateType.Value)); + } + + public void CreateDefaultTemplateInfo(int siteId, string administratorName) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + + var templateInfoList = new List(); + + var templateInfo = new TemplateInfo + { + SiteId = siteInfo.Id, + TemplateName = "系统首页模板", + Type = TemplateType.IndexPageTemplate, + RelatedFileName = "T_系统首页模板.html", + CreatedFileFullName = "@/index.html", + CreatedFileExtName = ".html", + Default = true + }; + templateInfoList.Add(templateInfo); + + templateInfo = new TemplateInfo + { + SiteId = siteInfo.Id, + TemplateName = "系统栏目模板", + Type = TemplateType.ChannelTemplate, + RelatedFileName = "T_系统栏目模板.html", + CreatedFileFullName = "index.html", + CreatedFileExtName = ".html", + Default = true + }; + templateInfoList.Add(templateInfo); + + templateInfo = new TemplateInfo + { + SiteId = siteInfo.Id, + TemplateName = "系统内容模板", + Type = TemplateType.ContentTemplate, + RelatedFileName = "T_系统内容模板.html", + CreatedFileFullName = "index.html", + CreatedFileExtName = ".html", + Default = true + }; + templateInfoList.Add(templateInfo); + + foreach (var theTemplateInfo in templateInfoList) + { + Insert(theTemplateInfo, theTemplateInfo.Content, administratorName); + } + } + + public Dictionary GetTemplateInfoDictionaryBySiteId(int siteId) + { + //IDataParameter[] parameters = + //{ + // GetParameter(ParamSiteId, siteId) + //}; + //string SqlSelectAllTemplateBySiteId = "SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = @SiteId ORDER BY TemplateType, RelatedFileName"; + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAllTemplateBySiteId, parameters)) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var info = new TemplateInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), TemplateTypeUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), ECharsetUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i))); + // dictionary.Add(info.Id, info); + // } + // rdr.Close(); + //} + + var templateInfoList = GetAll(Q + .Where(Attr.SiteId, siteId) + .OrderBy(Attr.TemplateType, Attr.RelatedFileName)); + + return templateInfoList.ToDictionary(templateInfo => templateInfo.Id); + } + } +} + + +//using System; +//using System.Collections.Generic; +//using System.Data; +//using SiteServer.CMS.Core; +//using SiteServer.CMS.Database.Caches; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; +//using SiteServer.Utils.Enumerations; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class Template : DataProviderBase +// { +// public override string TableName => "siteserver_Template"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(TemplateInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(TemplateInfo.SiteId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(TemplateInfo.TemplateName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TemplateInfo.TemplateType), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TemplateInfo.RelatedFileName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TemplateInfo.CreatedFileFullName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TemplateInfo.CreatedFileExtName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TemplateInfo.Charset), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(TemplateInfo.IsDefault), +// DataType = DataType.VarChar +// } +// }; + +// private const string SqlSelectTemplateByTemplateName = "SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = @SiteId AND TemplateType = @TemplateType AND TemplateName = @TemplateName"; + +// private const string SqlSelectAllTemplateByType = "SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = @SiteId AND TemplateType = @TemplateType ORDER BY RelatedFileName"; + +// private const string SqlSelectAllTemplateBySiteId = "SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = @SiteId ORDER BY TemplateType, RelatedFileName"; + +// private const string SqlSelectTemplateNames = "SELECT TemplateName FROM siteserver_Template WHERE SiteId = @SiteId AND TemplateType = @TemplateType"; + +// private const string SqlSelectTemplateCount = "SELECT TemplateType, COUNT(*) FROM siteserver_Template WHERE SiteId = @SiteId GROUP BY TemplateType"; + +// private const string SqlSelectRelatedFileNameByTemplateType = "SELECT RelatedFileName FROM siteserver_Template WHERE SiteId = @SiteId AND TemplateType = @TemplateType"; + +// private const string SqlUpdateTemplate = "UPDATE siteserver_Template SET TemplateName = @TemplateName, TemplateType = @TemplateType, RelatedFileName = @RelatedFileName, CreatedFileFullName = @CreatedFileFullName, CreatedFileExtName = @CreatedFileExtName, Charset = @Charset, IsDefault = @IsDefault WHERE Id = @Id"; + +// private const string SqlDeleteTemplate = "DELETE FROM siteserver_Template WHERE Id = @Id"; + +// private const string ParamId = "@Id"; +// private const string ParamSiteId = "@SiteId"; +// private const string ParamTemplateName = "@TemplateName"; +// private const string ParamTemplateType = "@TemplateType"; +// private const string ParamRelatedFileName = "@RelatedFileName"; +// private const string ParamCreatedFileFullName = "@CreatedFileFullName"; +// private const string ParamCreatedFileExtName = "@CreatedFileExtName"; +// private const string ParamCharset = "@Charset"; +// private const string ParamIsDefault = "@IsDefault"; + +// public int InsertObject(TemplateInfo templateInfo, string templateContent, string administratorName) +// { +// if (templateInfo.IsDefault) +// { +// SetAllTemplateDefaultToFalse(templateInfo.SiteId, templateInfo.TemplateType); +// } + +// const string sqlInsertTemplate = "INSERT INTO siteserver_Template (SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault) VALUES (@SiteId, @TemplateName, @TemplateType, @RelatedFileName, @CreatedFileFullName, @CreatedFileExtName, @Charset, @IsDefault)"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamSiteId, templateInfo.SiteId), +// GetParameter(ParamTemplateName, templateInfo.TemplateName), +// GetParameter(ParamTemplateType, templateInfo.TemplateType.Value), +// GetParameter(ParamRelatedFileName, templateInfo.RelatedFileName), +// GetParameter(ParamCreatedFileFullName, templateInfo.CreatedFileFullName), +// GetParameter(ParamCreatedFileExtName, templateInfo.CreatedFileExtName), +// GetParameter(ParamCharset, ECharsetUtils.GetValueById(templateInfo.Charset)), +// GetParameter(ParamIsDefault, templateInfo.IsDefault.ToString()) +// }; + +// var id = DatabaseApi.ExecuteNonQueryAndReturnId(ConnectionString, TableName, nameof(TemplateInfo.Id), sqlInsertTemplate, parameters); + +// var siteInfo = SiteManager.GetSiteInfo(templateInfo.SiteId); +// TemplateManager.WriteContentToTemplateFile(siteInfo, templateInfo, templateContent, administratorName); + +// TemplateManager.RemoveCache(templateInfo.SiteId); + +// return id; +// } + +// public void UpdateObject(SiteInfo siteInfo, TemplateInfo templateInfo, string templateContent, string administratorName) +// { +// if (templateInfo.IsDefault) +// { +// SetAllTemplateDefaultToFalse(siteInfo.Id, templateInfo.TemplateType); +// } + +// IDataParameter[] parameters = +// { +// GetParameter(ParamTemplateName, templateInfo.TemplateName), +// GetParameter(ParamTemplateType, templateInfo.TemplateType.Value), +// GetParameter(ParamRelatedFileName, templateInfo.RelatedFileName), +// GetParameter(ParamCreatedFileFullName, templateInfo.CreatedFileFullName), +// GetParameter(ParamCreatedFileExtName, templateInfo.CreatedFileExtName), +// GetParameter(ParamCharset, ECharsetUtils.GetValueById(templateInfo.Charset)), +// GetParameter(ParamIsDefault, templateInfo.IsDefault.ToString()), +// GetParameter(ParamId, templateInfo.Id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlUpdateTemplate, parameters); + +// TemplateManager.WriteContentToTemplateFile(siteInfo, templateInfo, templateContent, administratorName); + +// TemplateManager.RemoveCache(templateInfo.SiteId); +// } + +// private void SetAllTemplateDefaultToFalse(int siteId, TemplateType templateType) +// { +// var sqlString = "UPDATE siteserver_Template SET IsDefault = @IsDefault WHERE SiteId = @SiteId AND TemplateType = @TemplateType"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamIsDefault, false.ToString()), +// GetParameter(ParamSiteId, siteId), +// GetParameter(ParamTemplateType, templateType.Value) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// public void SetDefault(int siteId, int id) +// { +// var info = TemplateManager.GetTemplateInfo(siteId, id); +// SetAllTemplateDefaultToFalse(info.SiteId, info.TemplateType); + +// const string sqlString = "UPDATE siteserver_Template SET IsDefault = @IsDefault WHERE Id = @Id"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamIsDefault, true.ToString()), +// GetParameter(ParamId, id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// TemplateManager.RemoveCache(siteId); +// } + +// public void DeleteById(int siteId, int id) +// { +// var siteInfo = SiteManager.GetSiteInfo(siteId); +// var templateInfo = TemplateManager.GetTemplateInfo(siteId, id); +// var filePath = TemplateManager.GetTemplateFilePath(siteInfo, templateInfo); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamId, id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, SqlDeleteTemplate, parameters); +// FileUtils.DeleteFileIfExists(filePath); + +// TemplateManager.RemoveCache(siteId); +// } + +// public string GetImportTemplateName(int siteId, string templateName) +// { +// string importTemplateName; +// if (templateName.IndexOf("_", StringComparison.Ordinal) != -1) +// { +// var templateNameCount = 0; +// var lastTemplateName = templateName.Substring(templateName.LastIndexOf("_", StringComparison.Ordinal) + 1); +// var firstTemplateName = templateName.Substring(0, templateName.Length - lastTemplateName.Length); +// try +// { +// templateNameCount = int.Parse(lastTemplateName); +// } +// catch +// { +// // ignored +// } +// templateNameCount++; +// importTemplateName = firstTemplateName + templateNameCount; +// } +// else +// { +// importTemplateName = templateName + "_1"; +// } + +// IDataParameter[] parameters = +// { +// GetParameter(ParamSiteId, siteId), +// GetParameter(ParamTemplateName, importTemplateName) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectTemplateByTemplateName, parameters)) +// { +// if (rdr.Read()) +// { +// importTemplateName = GetImportTemplateName(siteId, importTemplateName); +// } +// rdr.Close(); +// } + +// return importTemplateName; +// } + +// public Dictionary GetCountDictionary(int siteId) +// { +// var dictionary = new Dictionary(); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamSiteId, siteId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectTemplateCount, parameters)) +// { +// while (rdr.Read()) +// { +// var templateType = TemplateTypeUtils.GetEnumType(DatabaseApi.GetString(rdr, 0)); +// var count = DatabaseApi.GetInt(rdr, 1); + +// dictionary.Add(templateType, count); +// } +// rdr.Close(); +// } + +// return dictionary; +// } + +// public IDataReader GetDataSourceByType(int siteId, TemplateType type) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamSiteId, siteId), +// GetParameter(ParamTemplateType, type.Value) +// }; + +// var enumerable = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAllTemplateByType, parameters); +// return enumerable; +// } + +// public IDataReader GetDataSource(int siteId, string searchText, string templateTypeString) +// { +// if (string.IsNullOrEmpty(searchText) && string.IsNullOrEmpty(templateTypeString)) +// { +// IDataParameter[] parameters = +// { +// GetParameter(ParamSiteId, siteId) +// }; + +// var enumerable = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAllTemplateBySiteId, parameters); +// return enumerable; +// } +// if (!string.IsNullOrEmpty(searchText)) +// { +// var whereString = (string.IsNullOrEmpty(templateTypeString)) ? string.Empty : +// $"AND TemplateType = '{templateTypeString}' "; +// searchText = AttackUtils.FilterSql(searchText); +// whereString += +// $"AND (TemplateName LIKE '%{searchText}%' OR RelatedFileName LIKE '%{searchText}%' OR CreatedFileFullName LIKE '%{searchText}%' OR CreatedFileExtName LIKE '%{searchText}%')"; +// var sqlString = +// $"SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = {siteId} {whereString} ORDER BY TemplateType, RelatedFileName"; + +// var enumerable = DatabaseApi.ExecuteReader(ConnectionString, sqlString); +// return enumerable; +// } + +// return GetDataSourceByType(siteId, TemplateTypeUtils.GetEnumType(templateTypeString)); +// } + +// public List GetTemplateInfoListByType(int siteId, TemplateType type) +// { +// var list = new List(); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamSiteId, siteId), +// GetParameter(ParamTemplateType, type.Value) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAllTemplateByType, parameters)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var info = new TemplateInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), TemplateTypeUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), ECharsetUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i))); +// list.Add(info); +// } +// rdr.Close(); +// } +// return list; +// } + +// public List GetTemplateInfoListOfFile(int siteId) +// { +// var list = new List(); + +// string sqlString = +// $"SELECT Id, SiteId, TemplateName, TemplateType, RelatedFileName, CreatedFileFullName, CreatedFileExtName, Charset, IsDefault FROM siteserver_Template WHERE SiteId = {siteId} AND TemplateType = '{TemplateType.FileTemplate.Value}' ORDER BY RelatedFileName"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var info = new TemplateInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), TemplateTypeUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), ECharsetUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i))); +// list.Add(info); +// } +// rdr.Close(); +// } +// return list; +// } + +// public List GetTemplateInfoListBySiteId(int siteId) +// { +// var list = new List(); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamSiteId, siteId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAllTemplateBySiteId, parameters)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var info = new TemplateInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), TemplateTypeUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), ECharsetUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i))); +// list.Add(info); +// } +// rdr.Close(); +// } +// return list; +// } + +// public List GetTemplateNameList(int siteId, TemplateType templateType) +// { +// var list = new List(); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamSiteId, siteId), +// GetParameter(ParamTemplateType, templateType.Value) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectTemplateNames, parameters)) +// { +// while (rdr.Read()) +// { +// list.Add(DatabaseApi.GetString(rdr, 0)); +// } +// rdr.Close(); +// } + +// return list; +// } + +// public List GetLowerRelatedFileNameList(int siteId, TemplateType templateType) +// { +// var list = new List(); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamSiteId, siteId), +// GetParameter(ParamTemplateType, templateType.Value) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectRelatedFileNameByTemplateType, parameters)) +// { +// while (rdr.Read()) +// { +// list.Add(DatabaseApi.GetString(rdr, 0).ToLower()); +// } +// rdr.Close(); +// } + +// return list; +// } + +// public void CreateDefaultTemplateInfo(int siteId, string administratorName) +// { +// var siteInfo = SiteManager.GetSiteInfo(siteId); + +// var templateInfoList = new List(); +// var charset = ECharsetUtils.GetEnumType(siteInfo.Charset); + +// var templateInfo = new TemplateInfo(0, siteInfo.Id, "系统首页模板", TemplateType.IndexPageTemplate, "T_系统首页模板.html", "@/index.html", ".html", charset, true); +// templateInfoList.Add(templateInfo); + +// templateInfo = new TemplateInfo(0, siteInfo.Id, "系统栏目模板", TemplateType.ChannelTemplate, "T_系统栏目模板.html", "index.html", ".html", charset, true); +// templateInfoList.Add(templateInfo); + +// templateInfo = new TemplateInfo(0, siteInfo.Id, "系统内容模板", TemplateType.ContentTemplate, "T_系统内容模板.html", "index.html", ".html", charset, true); +// templateInfoList.Add(templateInfo); + +// foreach (var theTemplateInfo in templateInfoList) +// { +// InsertObject(theTemplateInfo, theTemplateInfo.Content, administratorName); +// } +// } + +// public Dictionary GetTemplateInfoDictionaryBySiteId(int siteId) +// { +// var dictionary = new Dictionary(); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamSiteId, siteId) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, SqlSelectAllTemplateBySiteId, parameters)) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var info = new TemplateInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), TemplateTypeUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), ECharsetUtils.GetEnumType(DatabaseApi.GetString(rdr, i++)), TranslateUtils.ToBool(DatabaseApi.GetString(rdr, i))); +// dictionary.Add(info.Id, info); +// } +// rdr.Close(); +// } + +// return dictionary; +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/UserGroupRepository.cs b/net452/SiteServer.CMS/Database/Repositories/UserGroupRepository.cs new file mode 100644 index 000000000..203feca7a --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/UserGroupRepository.cs @@ -0,0 +1,220 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class UserGroupRepository : Repository + { + public UserGroupRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(UserGroupInfo.Id); + } + + public override int Insert(UserGroupInfo groupInfo) + { +// var sqlString = +// $@" +//INSERT INTO {TableName} ( +// {nameof(UserGroupInfo.GroupName)}, +// {nameof(UserGroupInfo.AdminName)} +//) VALUES ( +// @{nameof(UserGroupInfo.GroupName)}, +// @{nameof(UserGroupInfo.AdminName)} +//)"; + +// IDataParameter[] parameters = +// { +// GetParameter($"@{nameof(UserGroupInfo.GroupName)}", groupInfo.GroupName), +// GetParameter($"@{nameof(UserGroupInfo.AdminName)}", groupInfo.AdminName) +// }; + +// var groupId = DatabaseApi.ExecuteNonQueryAndReturnId(ConnectionString, TableName, nameof(UserGroupInfo.Id), sqlString, parameters); + + groupInfo.Id = base.Insert(groupInfo); + + UserGroupManager.ClearCache(); + + return groupInfo.Id; + } + + public override bool Update(UserGroupInfo groupInfo) + { + //var sqlString = $@"UPDATE {TableName} SET + // {nameof(UserGroupInfo.GroupName)} = @{nameof(UserGroupInfo.GroupName)}, + // {nameof(UserGroupInfo.AdminName)} = @{nameof(UserGroupInfo.AdminName)} + //WHERE {nameof(UserGroupInfo.Id)} = @{nameof(UserGroupInfo.Id)}"; + + //IDataParameter[] parameters = + //{ + // GetParameter(nameof(UserGroupInfo.GroupName), groupInfo.GroupName), + // GetParameter(nameof(UserGroupInfo.AdminName), groupInfo.AdminName), + // GetParameter(nameof(UserGroupInfo.Id), groupInfo.Id) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + var updated = base.Update(groupInfo); + + UserGroupManager.ClearCache(); + + return updated; + } + + public override bool Delete(int groupId) + { + //var sqlString = $"DELETE FROM {TableName} WHERE Id = @Id"; + + //IDataParameter[] parameters = + //{ + // GetParameter("@Id", groupId) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + var deleted = base.Delete(groupId); + + UserGroupManager.ClearCache(); + + return deleted; + } + + public IList GetUserGroupInfoList() + { + //List list; + + //var sqlString = $"SELECT * FROM {TableName} ORDER BY Id"; + //using (var connection = GetConnection()) + //{ + // list = connection.Query(sqlString).ToList(); + //} + + return GetAll(Q.OrderBy(Attr.Id)); + } + } +} + + +//using System.Collections.Generic; +//using System.Data; +//using System.Linq; +//using Dapper; +//using SiteServer.CMS.Database.Caches; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class UserGroup : DataProviderBase +// { +// public const string DatabaseTableName = "siteserver_UserGroup"; + +// public override string TableName => DatabaseTableName; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(UserGroupInfo.Id), +// DataType = DataType.Integer, +// IsPrimaryKey = true, +// IsIdentity = true +// }, +// new TableColumn +// { +// AttributeName = nameof(UserGroupInfo.GroupName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserGroupInfo.AdminName), +// DataType = DataType.VarChar +// } +// }; + +// public int InsertObject(UserGroupInfo groupInfo) +// { +// var sqlString = +// $@" +//INSERT INTO {TableName} ( +// {nameof(UserGroupInfo.GroupName)}, +// {nameof(UserGroupInfo.AdminName)} +//) VALUES ( +// @{nameof(UserGroupInfo.GroupName)}, +// @{nameof(UserGroupInfo.AdminName)} +//)"; + +// IDataParameter[] parameters = +// { +// GetParameter($"@{nameof(UserGroupInfo.GroupName)}", groupInfo.GroupName), +// GetParameter($"@{nameof(UserGroupInfo.AdminName)}", groupInfo.AdminName) +// }; + +// var groupId = DatabaseApi.ExecuteNonQueryAndReturnId(ConnectionString, TableName, nameof(UserGroupInfo.Id), sqlString, parameters); + +// UserGroupManager.ClearCache(); + +// return groupId; +// } + +// public void UpdateObject(UserGroupInfo groupInfo) +// { +// var sqlString = $@"UPDATE {TableName} SET +// {nameof(UserGroupInfo.GroupName)} = @{nameof(UserGroupInfo.GroupName)}, +// {nameof(UserGroupInfo.AdminName)} = @{nameof(UserGroupInfo.AdminName)} +// WHERE {nameof(UserGroupInfo.Id)} = @{nameof(UserGroupInfo.Id)}"; + +// IDataParameter[] parameters = +// { +// GetParameter(nameof(UserGroupInfo.GroupName), groupInfo.GroupName), +// GetParameter(nameof(UserGroupInfo.AdminName), groupInfo.AdminName), +// GetParameter(nameof(UserGroupInfo.Id), groupInfo.Id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// UserGroupManager.ClearCache(); +// } + +// public void DeleteById(int groupId) +// { +// var sqlString = $"DELETE FROM {TableName} WHERE Id = @Id"; + +// IDataParameter[] parameters = +// { +// GetParameter("@Id", groupId) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// UserGroupManager.ClearCache(); +// } + +// public List GetUserGroupInfoList() +// { +// List list; + +// var sqlString = $"SELECT * FROM {TableName} ORDER BY Id"; +// using (var connection = GetConnection()) +// { +// list = connection.Query(sqlString).ToList(); +// } + +// list.InsertObject(0, new UserGroupInfo +// { +// Id = 0, +// GroupName = "默认用户组", +// AdminName = ConfigManager.Instance.UserDefaultGroupAdminName +// }); + +// return list; +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/UserLogRepository.cs b/net452/SiteServer.CMS/Database/Repositories/UserLogRepository.cs new file mode 100644 index 000000000..fe39f461e --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/UserLogRepository.cs @@ -0,0 +1,492 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Datory; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class UserLogRepository : Repository + { + public UserLogRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(UserLogInfo.Id); + public const string UserName = nameof(UserLogInfo.UserName); + public const string AddDate = nameof(UserLogInfo.AddDate); + public const string Action = nameof(UserLogInfo.Action); + } + + //public void Insert(UserLogInfo logInfo) + //{ + // //const string sqlString = "INSERT INTO siteserver_UserLog(UserName, IPAddress, AddDate, Action, Summary) VALUES (@UserName, @IPAddress, @AddDate, @Action, @Summary)"; + + // //IDataParameter[] parameters = + // //{ + // // GetParameter(ParamUserName, logInfo.UserName), + // // GetParameter(ParamIpAddress, logInfo.IpAddress), + // // GetParameter(ParamAddDate,logInfo.AddDate), + // // GetParameter(ParamAction, logInfo.Action), + // // GetParameter(ParamSummary, logInfo.Summary) + // //}; + + // //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + // InsertObject(logInfo); + //} + + public UserLogInfo Insert(string userName, UserLogInfo logInfo) + { + logInfo.UserName = userName; + logInfo.IpAddress = FxUtils.GetIpAddress(); + logInfo.AddDate = DateTime.Now; + + //using (var connection = GetConnection()) + //{ + // var identity = connection.InsertObject(logInfo); + // if (identity > 0) + // { + // logInfo.Id = Convert.ToInt32(identity); + // } + //} + + logInfo.Id = Insert(logInfo); + + return logInfo; + } + + public void DeleteIfThreshold() + { + if (!ConfigManager.Instance.IsTimeThreshold) return; + + var days = ConfigManager.Instance.TimeThreshold; + if (days <= 0) return; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, $@"DELETE FROM siteserver_UserLog WHERE AddDate < {SqlUtils.GetComparableDateTime(DateTime.Now.AddDays(-days))}"); + + base.Delete(Q.Where(Attr.AddDate, "<", DateTime.Now.AddDays(-days))); + } + + public void Delete(List idList) + { + if (idList == null || idList.Count <= 0) return; + + //var sqlString = + // $"DELETE FROM siteserver_UserLog WHERE ID IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + base.Delete(Q.WhereIn(Attr.Id, idList)); + } + + public void DeleteAll() + { + //const string sqlString = "DELETE FROM siteserver_UserLog"; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + base.Delete(); + } + + public int GetCount() + { + //var count = 0; + //const string sqlString = "SELECT Count(ID) FROM siteserver_UserLog"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) + //{ + // if (rdr.Read()) + // { + // count = DatabaseApi.GetInt(rdr, 0); + // } + // rdr.Close(); + //} + + //return count; + + return Count(); + } + + public string GetSelectCommend() + { + return "SELECT ID, UserName, IPAddress, AddDate, Action, Summary FROM siteserver_UserLog"; + } + + public string GetSelectCommend(string userName, string keyword, string dateFrom, string dateTo) + { + if (string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(keyword) && string.IsNullOrEmpty(dateFrom) && string.IsNullOrEmpty(dateTo)) + { + return GetSelectCommend(); + } + + var whereString = new StringBuilder("WHERE "); + + var isWhere = false; + + if (!string.IsNullOrEmpty(userName)) + { + isWhere = true; + whereString.AppendFormat("(UserName = '{0}')", AttackUtils.FilterSql(userName)); + } + + if (!string.IsNullOrEmpty(keyword)) + { + if (isWhere) + { + whereString.Append(" AND "); + } + isWhere = true; + whereString.AppendFormat("(Action LIKE '%{0}%' OR Summary LIKE '%{0}%')", AttackUtils.FilterSql(keyword)); + } + + if (!string.IsNullOrEmpty(dateFrom)) + { + if (isWhere) + { + whereString.Append(" AND "); + } + isWhere = true; + whereString.Append($"(AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))})"); + } + if (!string.IsNullOrEmpty(dateTo)) + { + if (isWhere) + { + whereString.Append(" AND "); + } + whereString.Append($"(AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo))})"); + } + + return "SELECT ID, UserName, IPAddress, AddDate, Action, Summary FROM siteserver_UserLog " + whereString; + } + + public List List(string userName, int totalNum, string action) + { + //var list = new List(); + //var sqlString = "SELECT * FROM siteserver_UserLog WHERE UserName = @UserName"; + + //if (!string.IsNullOrEmpty(action)) + //{ + // sqlString += " And Action = @Action"; + //} + //sqlString += " ORDER BY ID DESC"; + + //var parameters = new List + //{ + // GetParameter(ParamUserName, userName) + //}; + //if (!string.IsNullOrEmpty(action)) + //{ + // parameters.Add(GetParameter(ParamAction, action)); + //} + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters.ToArray())) + //{ + // while (rdr.Read()) + // { + // var i = 0; + // var info = new UserLogInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetDateTime(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i)); + // list.Add(info); + // } + //} + + //return list; + + var query = Q.Where(Attr.UserName, userName); + if (!string.IsNullOrEmpty(action)) + { + query.Where(Attr.Action, action); + } + + query.Limit(totalNum); + query.OrderByDesc(Attr.Id); + + return GetAll(query).Select(x => (ILogInfo)x).ToList(); + } + + public IList ApiGetLogs(string userName, int offset, int limit) + { + //var sqlString = + // SqlDifferences.GetSqlString(TableName, null, $"WHERE {nameof(UserLogInfo.UserName)} = @{nameof(UserLogInfo.UserName)}", "ORDER BY Id DESC", offset, limit); + + //using (var connection = GetConnection()) + //{ + // return connection.Query(sqlString, new { UserName = userName }).ToList(); + //} + + return GetAll(Q + .Where(Attr.UserName, userName) + .Offset(offset) + .Limit(limit) + .OrderByDesc(Attr.Id)); + } + } +} + + +//using System; +//using System.Collections.Generic; +//using System.Data; +//using System.Linq; +//using System.Text; +//using Dapper; +//using Dapper.Contrib.Extensions; +//using SiteServer.CMS.Database.Caches; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class UserLog : DataProviderBase +// { +// public override string TableName => "siteserver_UserLog"; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(UserLogInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(UserLogInfo.UserName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserLogInfo.IpAddress), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserLogInfo.AddDate), +// DataType = DataType.DateTime +// }, +// new TableColumn +// { +// AttributeName = nameof(UserLogInfo.Action), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserLogInfo.Summary), +// DataType = DataType.VarChar +// } +// }; + +// private const string ParamUserName = "@UserName"; +// private const string ParamIpAddress = "@IPAddress"; +// private const string ParamAddDate = "@AddDate"; +// private const string ParamAction = "@Action"; +// private const string ParamSummary = "@Summary"; + +// public void InsertObject(UserLogInfo logInfo) +// { +// const string sqlString = "INSERT INTO siteserver_UserLog(UserName, IPAddress, AddDate, Action, Summary) VALUES (@UserName, @IPAddress, @AddDate, @Action, @Summary)"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamUserName, logInfo.UserName), +// GetParameter(ParamIpAddress, logInfo.IpAddress), +// GetParameter(ParamAddDate,logInfo.AddDate), +// GetParameter(ParamAction, logInfo.Action), +// GetParameter(ParamSummary, logInfo.Summary) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// } + +// public void DeleteIfThreshold() +// { +// if (!ConfigManager.Instance.IsTimeThreshold) return; + +// var days = ConfigManager.Instance.TimeThreshold; +// if (days <= 0) return; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, $@"DELETE FROM siteserver_UserLog WHERE AddDate < {SqlUtils.GetComparableDateTime(DateTime.Now.AddDays(-days))}"); +// } + +// public void DeleteById(List idList) +// { +// if (idList == null || idList.Count <= 0) return; + +// var sqlString = +// $"DELETE FROM siteserver_UserLog WHERE ID IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } + +// public void DeleteAll() +// { +// const string sqlString = "DELETE FROM siteserver_UserLog"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); +// } + +// public int GetCount() +// { +// var count = 0; +// const string sqlString = "SELECT Count(ID) FROM siteserver_UserLog"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// if (rdr.Read()) +// { +// count = DatabaseApi.GetInt(rdr, 0); +// } +// rdr.Close(); +// } + +// return count; +// } + +// public int GetCount(string where) +// { +// var count = 0; +// var sqlString = "SELECT Count(ID) FROM siteserver_UserLog"; +// if (!string.IsNullOrEmpty(where)) +// sqlString += " WHERE " + where; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// if (rdr.Read()) +// { +// count = DatabaseApi.GetInt(rdr, 0); +// } +// rdr.Close(); +// } + +// return count; +// } + +// public string GetSelectCommend() +// { +// return "SELECT ID, UserName, IPAddress, AddDate, Action, Summary FROM siteserver_UserLog"; +// } + +// public string GetSelectCommend(string userName, string keyword, string dateFrom, string dateTo) +// { +// if (string.IsNullOrEmpty(userName) && string.IsNullOrEmpty(keyword) && string.IsNullOrEmpty(dateFrom) && string.IsNullOrEmpty(dateTo)) +// { +// return GetSelectCommend(); +// } + +// var whereString = new StringBuilder("WHERE "); + +// var isWhere = false; + +// if (!string.IsNullOrEmpty(userName)) +// { +// isWhere = true; +// whereString.AppendFormat("(UserName = '{0}')", AttackUtils.FilterSql(userName)); +// } + +// if (!string.IsNullOrEmpty(keyword)) +// { +// if (isWhere) +// { +// whereString.Append(" AND "); +// } +// isWhere = true; +// whereString.AppendFormat("(Action LIKE '%{0}%' OR Summary LIKE '%{0}%')", AttackUtils.FilterSql(keyword)); +// } + +// if (!string.IsNullOrEmpty(dateFrom)) +// { +// if (isWhere) +// { +// whereString.Append(" AND "); +// } +// isWhere = true; +// whereString.Append($"(AddDate >= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateFrom))})"); +// } +// if (!string.IsNullOrEmpty(dateTo)) +// { +// if (isWhere) +// { +// whereString.Append(" AND "); +// } +// whereString.Append($"(AddDate <= {SqlUtils.GetComparableDate(TranslateUtils.ToDateTime(dateTo))})"); +// } + +// return "SELECT ID, UserName, IPAddress, AddDate, Action, Summary FROM siteserver_UserLog " + whereString; +// } + +// public List List(string userName, int totalNum, string action) +// { +// var list = new List(); +// var sqlString = "SELECT * FROM siteserver_UserLog WHERE UserName = @UserName"; + +// if (!string.IsNullOrEmpty(action)) +// { +// sqlString += " And Action = @Action"; +// } +// sqlString += " ORDER BY ID DESC"; + +// var parameters = new List +// { +// GetParameter(ParamUserName, userName) +// }; +// if (!string.IsNullOrEmpty(action)) +// { +// parameters.Add(GetParameter(ParamAction, action)); +// } + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters.ToArray())) +// { +// while (rdr.Read()) +// { +// var i = 0; +// var info = new UserLogInfo(DatabaseApi.GetInt(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetDateTime(rdr, i++), DatabaseApi.GetString(rdr, i++), DatabaseApi.GetString(rdr, i)); +// list.Add(info); +// } +// } + +// return list; +// } + +// public List ApiGetLogs(string userName, int offset, int limit) +// { +// var sqlString = +// SqlDifferences.GetSqlString(TableName, null, $"WHERE {nameof(UserLogInfo.UserName)} = @{nameof(UserLogInfo.UserName)}", "ORDER BY Id DESC", offset, limit); + +// using (var connection = GetConnection()) +// { +// return connection.Query(sqlString, new {UserName = userName}).ToList(); +// } +// } + +// public UserLogInfo ApiInsert(string userName, UserLogInfo logInfo) +// { +// logInfo.UserName = userName; +// logInfo.IpAddress = PageUtils.GetIpAddress(); +// logInfo.AddDate = DateTime.Now; + +// using (var connection = GetConnection()) +// { +// var identity = connection.InsertObject(logInfo); +// if (identity > 0) +// { +// logInfo.Id = Convert.ToInt32(identity); +// } +// } + +// return logInfo; +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/UserMenuRepository.cs b/net452/SiteServer.CMS/Database/Repositories/UserMenuRepository.cs new file mode 100644 index 000000000..eb7d48629 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/UserMenuRepository.cs @@ -0,0 +1,384 @@ +using System.Collections.Generic; +using System.Linq; +using Datory; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Repositories +{ + public class UserMenuRepository : Repository + { + public UserMenuRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private static class Attr + { + public const string Id = nameof(UserMenuInfo.Id); + public const string ParentId = nameof(UserMenuInfo.ParentId); + } + + public override int Insert(UserMenuInfo menuInfo) + { + // var sqlString = + // $@" + //INSERT INTO {TableName} ( + // {nameof(UserMenuInfo.SystemId)}, + // {nameof(UserMenuInfo.GroupIdCollection)}, + // {nameof(UserMenuInfo.IsDisabled)}, + // {nameof(UserMenuInfo.ParentId)}, + // {nameof(UserMenuInfo.Taxis)}, + // {nameof(UserMenuInfo.Text)}, + // {nameof(UserMenuInfo.IconClass)}, + // {nameof(UserMenuInfo.Href)}, + // {nameof(UserMenuInfo.Target)} + //) VALUES ( + // @{nameof(UserMenuInfo.SystemId)}, + // @{nameof(UserMenuInfo.GroupIdCollection)}, + // @{nameof(UserMenuInfo.IsDisabled)}, + // @{nameof(UserMenuInfo.ParentId)}, + // @{nameof(UserMenuInfo.Taxis)}, + // @{nameof(UserMenuInfo.Text)}, + // @{nameof(UserMenuInfo.IconClass)}, + // @{nameof(UserMenuInfo.Href)}, + // @{nameof(UserMenuInfo.Target)} + //)"; + + // IDataParameter[] parameters = + // { + // GetParameter($"@{nameof(UserMenuInfo.SystemId)}", menuInfo.SystemId), + // GetParameter($"@{nameof(UserMenuInfo.GroupIdCollection)}", menuInfo.GroupIdCollection), + // GetParameter($"@{nameof(UserMenuInfo.IsDisabled)}", menuInfo.IsDisabled), + // GetParameter($"@{nameof(UserMenuInfo.ParentId)}", menuInfo.ParentId), + // GetParameter($"@{nameof(UserMenuInfo.Taxis)}", menuInfo.Taxis), + // GetParameter($"@{nameof(UserMenuInfo.Text)}", menuInfo.Text), + // GetParameter($"@{nameof(UserMenuInfo.IconClass)}", menuInfo.IconClass), + // GetParameter($"@{nameof(UserMenuInfo.Href)}", menuInfo.Href), + // GetParameter($"@{nameof(UserMenuInfo.Target)}", menuInfo.Target) + // }; + + // var menuId = DatabaseApi.ExecuteNonQueryAndReturnId(ConnectionString, TableName, nameof(UserMenuInfo.Id), sqlString, parameters); + + menuInfo.Id = base.Insert(menuInfo); + + UserMenuManager.ClearCache(); + + return menuInfo.Id; + } + + public override bool Update(UserMenuInfo menuInfo) + { + //var sqlString = $@"UPDATE {TableName} SET + // {nameof(UserMenuInfo.SystemId)} = @{nameof(UserMenuInfo.SystemId)}, + // {nameof(UserMenuInfo.GroupIdCollection)} = @{nameof(UserMenuInfo.GroupIdCollection)}, + // {nameof(UserMenuInfo.IsDisabled)} = @{nameof(UserMenuInfo.IsDisabled)}, + // {nameof(UserMenuInfo.ParentId)} = @{nameof(UserMenuInfo.ParentId)}, + // {nameof(UserMenuInfo.Taxis)} = @{nameof(UserMenuInfo.Taxis)}, + // {nameof(UserMenuInfo.Text)} = @{nameof(UserMenuInfo.Text)}, + // {nameof(UserMenuInfo.IconClass)} = @{nameof(UserMenuInfo.IconClass)}, + // {nameof(UserMenuInfo.Href)} = @{nameof(UserMenuInfo.Href)}, + // {nameof(UserMenuInfo.Target)} = @{nameof(UserMenuInfo.Target)} + //WHERE {nameof(UserMenuInfo.Id)} = @{nameof(UserMenuInfo.Id)}"; + + //IDataParameter[] parameters = + //{ + // GetParameter(nameof(UserMenuInfo.SystemId), menuInfo.SystemId), + // GetParameter(nameof(UserMenuInfo.GroupIdCollection), menuInfo.GroupIdCollection), + // GetParameter(nameof(UserMenuInfo.IsDisabled), menuInfo.IsDisabled), + // GetParameter(nameof(UserMenuInfo.ParentId), menuInfo.ParentId), + // GetParameter(nameof(UserMenuInfo.Taxis), menuInfo.Taxis), + // GetParameter(nameof(UserMenuInfo.Text), menuInfo.Text), + // GetParameter(nameof(UserMenuInfo.IconClass), menuInfo.IconClass), + // GetParameter(nameof(UserMenuInfo.Href), menuInfo.Href), + // GetParameter(nameof(UserMenuInfo.Target), menuInfo.Target), + // GetParameter(nameof(UserMenuInfo.Id), menuInfo.Id) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + var updated = base.Update(menuInfo); + + UserMenuManager.ClearCache(); + + return updated; + } + + public override bool Delete(int menuId) + { + //var sqlString = $"DELETE FROM {TableName} WHERE {nameof(UserMenuInfo.Id)} = @{nameof(UserMenuInfo.Id)} OR {nameof(UserMenuInfo.ParentId)} = @{nameof(UserMenuInfo.ParentId)}"; + + //IDataParameter[] parameters = + //{ + // GetParameter($"@{nameof(UserMenuInfo.Id)}", menuId), + // GetParameter($"@{nameof(UserMenuInfo.ParentId)}", menuId) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Delete(Q.Where(Attr.Id, menuId).OrWhere(Attr.ParentId, menuId)); + + UserMenuManager.ClearCache(); + + return true; + } + + public List GetUserMenuInfoList() + { + //List list; + + //var sqlString = $"SELECT * FROM {TableName}"; + //using (var connection = GetConnection()) + //{ + // list = connection.Query(sqlString).ToList(); + //} + + var list = GetAll(); + + var systemMenus = UserMenuManager.SystemMenus.Value; + foreach (var kvp in systemMenus) + { + var parent = kvp.Key; + var children = kvp.Value; + + if (list.All(x => x.SystemId != parent.SystemId)) + { + parent.Id = Insert(parent); + list.Add(parent); + } + else + { + parent = list.First(x => x.SystemId == parent.SystemId); + } + + if (children != null) + { + foreach (var child in children) + { + if (list.All(x => x.SystemId != child.SystemId)) + { + child.ParentId = parent.Id; + child.Id = Insert(child); + list.Add(child); + } + } + } + } + + return list.OrderBy(menuInfo => menuInfo.Taxis == 0 ? int.MaxValue : menuInfo.Taxis).ToList(); + } + } +} + + +//using System.Collections.Generic; +//using System.Data; +//using System.Linq; +//using Dapper; +//using SiteServer.CMS.Database.Caches; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class UserMenu : DataProviderBase +// { +// public const string DatabaseTableName = "siteserver_UserMenu"; + +// public override string TableName => DatabaseTableName; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(UserMenuInfo.Id), +// DataType = DataType.Integer, +// IsPrimaryKey = true, +// IsIdentity = true +// }, +// new TableColumn +// { +// AttributeName = nameof(UserMenuInfo.SystemId), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserMenuInfo.GroupIdCollection), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserMenuInfo.IsDisabled), +// DataType = DataType.Boolean +// }, +// new TableColumn +// { +// AttributeName = nameof(UserMenuInfo.ParentId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(UserMenuInfo.Taxis), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(UserMenuInfo.Text), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserMenuInfo.IconClass), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserMenuInfo.Href), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserMenuInfo.Target), +// DataType = DataType.VarChar +// } +// }; + +// public int InsertObject(UserMenuInfo menuInfo) +// { +// var sqlString = +// $@" +//INSERT INTO {TableName} ( +// {nameof(UserMenuInfo.SystemId)}, +// {nameof(UserMenuInfo.GroupIdCollection)}, +// {nameof(UserMenuInfo.IsDisabled)}, +// {nameof(UserMenuInfo.ParentId)}, +// {nameof(UserMenuInfo.Taxis)}, +// {nameof(UserMenuInfo.Text)}, +// {nameof(UserMenuInfo.IconClass)}, +// {nameof(UserMenuInfo.Href)}, +// {nameof(UserMenuInfo.Target)} +//) VALUES ( +// @{nameof(UserMenuInfo.SystemId)}, +// @{nameof(UserMenuInfo.GroupIdCollection)}, +// @{nameof(UserMenuInfo.IsDisabled)}, +// @{nameof(UserMenuInfo.ParentId)}, +// @{nameof(UserMenuInfo.Taxis)}, +// @{nameof(UserMenuInfo.Text)}, +// @{nameof(UserMenuInfo.IconClass)}, +// @{nameof(UserMenuInfo.Href)}, +// @{nameof(UserMenuInfo.Target)} +//)"; + +// IDataParameter[] parameters = +// { +// GetParameter($"@{nameof(UserMenuInfo.SystemId)}", menuInfo.SystemId), +// GetParameter($"@{nameof(UserMenuInfo.GroupIdCollection)}", menuInfo.GroupIdCollection), +// GetParameter($"@{nameof(UserMenuInfo.IsDisabled)}", menuInfo.IsDisabled), +// GetParameter($"@{nameof(UserMenuInfo.ParentId)}", menuInfo.ParentId), +// GetParameter($"@{nameof(UserMenuInfo.Taxis)}", menuInfo.Taxis), +// GetParameter($"@{nameof(UserMenuInfo.Text)}", menuInfo.Text), +// GetParameter($"@{nameof(UserMenuInfo.IconClass)}", menuInfo.IconClass), +// GetParameter($"@{nameof(UserMenuInfo.Href)}", menuInfo.Href), +// GetParameter($"@{nameof(UserMenuInfo.Target)}", menuInfo.Target) +// }; + +// var menuId = DatabaseApi.ExecuteNonQueryAndReturnId(ConnectionString, TableName, nameof(UserMenuInfo.Id), sqlString, parameters); + +// UserMenuManager.ClearCache(); + +// return menuId; +// } + +// public void UpdateObject(UserMenuInfo menuInfo) +// { +// var sqlString = $@"UPDATE {TableName} SET +// {nameof(UserMenuInfo.SystemId)} = @{nameof(UserMenuInfo.SystemId)}, +// {nameof(UserMenuInfo.GroupIdCollection)} = @{nameof(UserMenuInfo.GroupIdCollection)}, +// {nameof(UserMenuInfo.IsDisabled)} = @{nameof(UserMenuInfo.IsDisabled)}, +// {nameof(UserMenuInfo.ParentId)} = @{nameof(UserMenuInfo.ParentId)}, +// {nameof(UserMenuInfo.Taxis)} = @{nameof(UserMenuInfo.Taxis)}, +// {nameof(UserMenuInfo.Text)} = @{nameof(UserMenuInfo.Text)}, +// {nameof(UserMenuInfo.IconClass)} = @{nameof(UserMenuInfo.IconClass)}, +// {nameof(UserMenuInfo.Href)} = @{nameof(UserMenuInfo.Href)}, +// {nameof(UserMenuInfo.Target)} = @{nameof(UserMenuInfo.Target)} +// WHERE {nameof(UserMenuInfo.Id)} = @{nameof(UserMenuInfo.Id)}"; + +// IDataParameter[] parameters = +// { +// GetParameter(nameof(UserMenuInfo.SystemId), menuInfo.SystemId), +// GetParameter(nameof(UserMenuInfo.GroupIdCollection), menuInfo.GroupIdCollection), +// GetParameter(nameof(UserMenuInfo.IsDisabled), menuInfo.IsDisabled), +// GetParameter(nameof(UserMenuInfo.ParentId), menuInfo.ParentId), +// GetParameter(nameof(UserMenuInfo.Taxis), menuInfo.Taxis), +// GetParameter(nameof(UserMenuInfo.Text), menuInfo.Text), +// GetParameter(nameof(UserMenuInfo.IconClass), menuInfo.IconClass), +// GetParameter(nameof(UserMenuInfo.Href), menuInfo.Href), +// GetParameter(nameof(UserMenuInfo.Target), menuInfo.Target), +// GetParameter(nameof(UserMenuInfo.Id), menuInfo.Id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// UserMenuManager.ClearCache(); +// } + +// public void DeleteById(int menuId) +// { +// var sqlString = $"DELETE FROM {TableName} WHERE {nameof(UserMenuInfo.Id)} = @{nameof(UserMenuInfo.Id)} OR {nameof(UserMenuInfo.ParentId)} = @{nameof(UserMenuInfo.ParentId)}"; + +// IDataParameter[] parameters = +// { +// GetParameter($"@{nameof(UserMenuInfo.Id)}", menuId), +// GetParameter($"@{nameof(UserMenuInfo.ParentId)}", menuId) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// UserMenuManager.ClearCache(); +// } + +// public List GetUserMenuInfoList() +// { +// List list; + +// var sqlString = $"SELECT * FROM {TableName}"; +// using (var connection = GetConnection()) +// { +// list = connection.Query(sqlString).ToList(); +// } + +// var systemMenus = UserMenuManager.SystemMenus.Value; +// foreach (var kvp in systemMenus) +// { +// var parent = kvp.Key; +// var children = kvp.Value; + +// if (list.All(x => x.SystemId != parent.SystemId)) +// { +// parent.Id = InsertObject(parent); +// list.Add(parent); +// } +// else +// { +// parent = list.GetObjectById(x => x.SystemId == parent.SystemId); +// } + +// if (children != null) +// { +// foreach (var child in children) +// { +// if (list.All(x => x.SystemId != child.SystemId)) +// { +// child.ParentId = parent.Id; +// child.Id = InsertObject(child); +// list.Add(child); +// } +// } +// } +// } + +// return list.OrderBy(menuInfo => menuInfo.Taxis == 0 ? int.MaxValue : menuInfo.Taxis).ToList(); +// } +// } +//} diff --git a/net452/SiteServer.CMS/Database/Repositories/UserRepository.cs b/net452/SiteServer.CMS/Database/Repositories/UserRepository.cs new file mode 100644 index 000000000..9b5206b0a --- /dev/null +++ b/net452/SiteServer.CMS/Database/Repositories/UserRepository.cs @@ -0,0 +1,2197 @@ +using System; +using System.Collections.Generic; +using System.Security.Cryptography; +using System.Text; +using Datory; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; +using SiteServer.Utils.Auth; +using SiteServer.Utils.Enumerations; +using Attr = SiteServer.CMS.Database.Attributes.UserAttribute; + +namespace SiteServer.CMS.Database.Repositories +{ + public class UserRepository : Repository + { + public UserRepository() : base(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString) + { + } + + private bool InsertValidate(string userName, string email, string mobile, string password, string ipAddress, out string errorMessage) + { + errorMessage = string.Empty; + + if (!UserManager.IsIpAddressCached(ipAddress)) + { + errorMessage = $"同一IP在{ConfigManager.Instance.UserRegistrationMinMinutes}分钟内只能注册一次"; + return false; + } + if (string.IsNullOrEmpty(password)) + { + errorMessage = "密码不能为空"; + return false; + } + if (password.Length < ConfigManager.Instance.UserPasswordMinLength) + { + errorMessage = $"密码长度必须大于等于{ConfigManager.Instance.UserPasswordMinLength}"; + return false; + } + if (!EUserPasswordRestrictionUtils.IsValid(password, ConfigManager.Instance.UserPasswordRestriction)) + { + errorMessage = + $"密码不符合规则,请包含{EUserPasswordRestrictionUtils.GetText(EUserPasswordRestrictionUtils.GetEnumType(ConfigManager.Instance.UserPasswordRestriction))}"; + return false; + } + if (string.IsNullOrEmpty(userName)) + { + errorMessage = "用户名为空,请填写用户名"; + return false; + } + if (!string.IsNullOrEmpty(userName) && IsUserNameExists(userName)) + { + errorMessage = "用户名已被注册,请更换用户名"; + return false; + } + if (!IsUserNameCompliant(userName.Replace("@", string.Empty).Replace(".", string.Empty))) + { + errorMessage = "用户名包含不规则字符,请更换用户名"; + return false; + } + + if (!string.IsNullOrEmpty(email) && IsEmailExists(email)) + { + errorMessage = "电子邮件地址已被注册,请更换邮箱"; + return false; + } + if (!string.IsNullOrEmpty(mobile) && IsMobileExists(mobile)) + { + errorMessage = "手机号码已被注册,请更换手机号码"; + return false; + } + + return true; + } + + private bool UpdateValidate(Dictionary body, string userName, string email, string mobile, out string errorMessage) + { + errorMessage = string.Empty; + + var bodyUserName = string.Empty; + if (body.ContainsKey("userName")) + { + bodyUserName = (string)body["userName"]; + } + + if (!string.IsNullOrEmpty(bodyUserName) && bodyUserName != userName) + { + if (!IsUserNameCompliant(bodyUserName.Replace("@", string.Empty).Replace(".", string.Empty))) + { + errorMessage = "用户名包含不规则字符,请更换用户名"; + return false; + } + if (!string.IsNullOrEmpty(bodyUserName) && IsUserNameExists(bodyUserName)) + { + errorMessage = "用户名已被注册,请更换用户名"; + return false; + } + } + + var bodyEmail = string.Empty; + if (body.ContainsKey("email")) + { + bodyEmail = (string)body["email"]; + } + + if (bodyEmail != null && bodyEmail != email) + { + if (!string.IsNullOrEmpty(bodyEmail) && IsEmailExists(bodyEmail)) + { + errorMessage = "电子邮件地址已被注册,请更换邮箱"; + return false; + } + } + + var bodyMobile = string.Empty; + if (body.ContainsKey("mobile")) + { + bodyMobile = (string)body["mobile"]; + } + + if (bodyMobile != null && bodyMobile != mobile) + { + if (!string.IsNullOrEmpty(bodyMobile) && IsMobileExists(bodyMobile)) + { + errorMessage = "手机号码已被注册,请更换手机号码"; + return false; + } + } + + return true; + } + + public int Insert(UserInfo userInfo, string password, string ipAddress, out string errorMessage) + { + errorMessage = string.Empty; + if (userInfo == null) return 0; + + if (!ConfigManager.Instance.IsUserRegistrationAllowed) + { + errorMessage = "对不起,系统已禁止新用户注册!"; + return 0; + } + + try + { + userInfo.Checked = ConfigManager.Instance.IsUserRegistrationChecked; + if (StringUtils.IsMobile(userInfo.UserName) && string.IsNullOrEmpty(userInfo.Mobile)) + { + userInfo.Mobile = userInfo.UserName; + } + + if (!InsertValidate(userInfo.UserName, userInfo.Email, userInfo.Mobile, password, ipAddress, out errorMessage)) return 0; + + var passwordSalt = GenerateSalt(); + password = EncodePassword(password, EPasswordFormat.Encrypted, passwordSalt); + userInfo.CreateDate = DateTime.Now; + userInfo.LastActivityDate = DateTime.Now; + userInfo.LastResetPasswordDate = DateTime.Now; + + userInfo.Id = InsertWithoutValidation(userInfo, password, EPasswordFormat.Encrypted, passwordSalt); + + UserManager.CacheIpAddress(ipAddress); + + return userInfo.Id; + } + catch (Exception ex) + { + errorMessage = ex.Message; + return 0; + } + } + + private int InsertWithoutValidation(UserInfo userInfo, string password, EPasswordFormat passwordFormat, string passwordSalt) + { + //var sqlString = $"INSERT INTO {TableName} (UserName, Password, PasswordFormat, PasswordSalt, CreateDate, LastResetPasswordDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, GroupId, IsChecked, IsLockedOut, DisplayName, Email, Mobile, AvatarUrl, Gender, Birthday, WeiXin, QQ, WeiBo, Bio, SettingsXml) VALUES (@UserName, @Password, @PasswordFormat, @PasswordSalt, @CreateDate, @LastResetPasswordDate, @LastActivityDate, @CountOfLogin, @CountOfFailedLogin, @GroupId, @IsChecked, @IsLockedOut, @DisplayName, @Email, @Mobile, @AvatarUrl, @Gender, @Birthday, @WeiXin, @QQ, @WeiBo, @Bio, @SettingsXml)"; + + //userInfo.CreateDate = DateTime.Now; + //userInfo.LastActivityDate = DateTime.Now; + //userInfo.LastResetPasswordDate = DateTime.Now; + + //userInfo.DisplayName = AttackUtils.FilterXss(userInfo.DisplayName); + //userInfo.Email = AttackUtils.FilterXss(userInfo.Email); + //userInfo.Mobile = AttackUtils.FilterXss(userInfo.Mobile); + //userInfo.AvatarUrl = AttackUtils.FilterXss(userInfo.AvatarUrl); + //userInfo.Gender = AttackUtils.FilterXss(userInfo.Gender); + //userInfo.Birthday = AttackUtils.FilterXss(userInfo.Birthday); + //userInfo.WeiXin = AttackUtils.FilterXss(userInfo.WeiXin); + //userInfo.Qq = AttackUtils.FilterXss(userInfo.Qq); + //userInfo.WeiBo = AttackUtils.FilterXss(userInfo.WeiBo); + //userInfo.Bio = AttackUtils.FilterXss(userInfo.Bio); + //var settingsXml = userInfo.ToString(UserAttribute.AllAttributes.Value); + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamUserName, userInfo.UserName), + // GetParameter(ParamPassword, password), + // GetParameter(ParamPasswordFormat, EPasswordFormatUtils.GetValueById(passwordFormat)), + // GetParameter(ParamPasswordSalt, passwordSalt), + // GetParameter(ParamCreateDate,userInfo.CreateDate), + // GetParameter(ParamLastResetPasswordDate,userInfo.LastResetPasswordDate), + // GetParameter(ParamLastActivityDate,userInfo.LastActivityDate), + // GetParameter(ParamCountOfLogin, userInfo.CountOfLogin), + // GetParameter(ParamCountOfFailedLogin, userInfo.CountOfFailedLogin), + // GetParameter(ParamGroupId, userInfo.GroupId), + // GetParameter(ParamIsChecked, userInfo.IsChecked.ToString()), + // GetParameter(ParamIsLockedOut, userInfo.IsLockedOut.ToString()), + // GetParameter(ParamDisplayName, userInfo.DisplayName), + // GetParameter(ParamEmail, userInfo.Email), + // GetParameter(ParamMobile, userInfo.Mobile), + // GetParameter(ParamAvatarUrl, userInfo.AvatarUrl), + // GetParameter(ParamGender, userInfo.Gender), + // GetParameter(ParamBirthday, userInfo.Birthday), + // GetParameter(ParamWeiXin, userInfo.WeiXin), + // GetParameter(ParamQq, userInfo.Qq), + // GetParameter(ParamWeiBo, userInfo.WeiBo), + // GetParameter(ParamBio,userInfo.Bio), + // GetParameter(ParamSettingsXml,settingsXml) + //}; + + //return DatabaseApi.ExecuteNonQueryAndReturnId(ConnectionString, TableName, UserAttribute.Id, sqlString, parameters); + + userInfo.Password = password; + userInfo.PasswordFormat = EPasswordFormatUtils.GetValue(passwordFormat); + userInfo.PasswordSalt = passwordSalt; + userInfo.CreateDate = DateTime.Now; + userInfo.LastActivityDate = DateTime.Now; + userInfo.LastResetPasswordDate = DateTime.Now; + + return Insert(userInfo); + } + + public bool IsPasswordCorrect(string password, out string errorMessage) + { + errorMessage = null; + if (string.IsNullOrEmpty(password)) + { + errorMessage = "密码不能为空"; + return false; + } + if (password.Length < ConfigManager.Instance.UserPasswordMinLength) + { + errorMessage = $"密码长度必须大于等于{ConfigManager.Instance.UserPasswordMinLength}"; + return false; + } + if (!EUserPasswordRestrictionUtils.IsValid(password, ConfigManager.Instance.UserPasswordRestriction)) + { + errorMessage = + $"密码不符合规则,请包含{EUserPasswordRestrictionUtils.GetText(EUserPasswordRestrictionUtils.GetEnumType(ConfigManager.Instance.UserPasswordRestriction))}"; + return false; + } + return true; + } + + public UserInfo Update(UserInfo userInfo, Dictionary body, out string errorMessage) + { + if (!UpdateValidate(body, userInfo.UserName, userInfo.Email, userInfo.Mobile, out errorMessage)) return null; + + foreach (var o in body) + { + userInfo.Set(o.Key, o.Value); + } + + Update(userInfo); + + return userInfo; + } + + public override bool Update(UserInfo userInfo) + { + //if (userInfo == null) return; + + //userInfo.DisplayName = AttackUtils.FilterXss(userInfo.DisplayName); + //userInfo.Email = AttackUtils.FilterXss(userInfo.Email); + //userInfo.Mobile = AttackUtils.FilterXss(userInfo.Mobile); + //userInfo.AvatarUrl = AttackUtils.FilterXss(userInfo.AvatarUrl); + //userInfo.Gender = AttackUtils.FilterXss(userInfo.Gender); + //userInfo.Birthday = AttackUtils.FilterXss(userInfo.Birthday); + //userInfo.WeiXin = AttackUtils.FilterXss(userInfo.WeiXin); + //userInfo.Qq = AttackUtils.FilterXss(userInfo.Qq); + //userInfo.WeiBo = AttackUtils.FilterXss(userInfo.WeiBo); + //userInfo.Bio = AttackUtils.FilterXss(userInfo.Bio); + + //var sqlString = $"UPDATE {TableName} SET UserName = @UserName, CreateDate = @CreateDate, LastResetPasswordDate = @LastResetPasswordDate, LastActivityDate = @LastActivityDate, CountOfLogin = @CountOfLogin, CountOfFailedLogin = @CountOfFailedLogin, GroupId = @GroupId, IsChecked = @IsChecked, IsLockedOut = @IsLockedOut, DisplayName = @DisplayName, Email = @Email, Mobile = @Mobile, AvatarUrl = @AvatarUrl, Gender = @Gender, Birthday = @Birthday, WeiXin = @WeiXin, QQ = @QQ, WeiBo = @WeiBo, Bio = @Bio, SettingsXml = @SettingsXml WHERE Id = @Id"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamUserName, userInfo.UserName), + // GetParameter(ParamCreateDate,userInfo.CreateDate), + // GetParameter(ParamLastResetPasswordDate,userInfo.LastResetPasswordDate), + // GetParameter(ParamLastActivityDate,userInfo.LastActivityDate), + // GetParameter(ParamCountOfLogin, userInfo.CountOfLogin), + // GetParameter(ParamCountOfFailedLogin, userInfo.CountOfFailedLogin), + // GetParameter(ParamGroupId, userInfo.GroupId), + // GetParameter(ParamIsChecked, userInfo.IsChecked.ToString()), + // GetParameter(ParamIsLockedOut, userInfo.IsLockedOut.ToString()), + // GetParameter(ParamDisplayName, userInfo.DisplayName), + // GetParameter(ParamEmail, userInfo.Email), + // GetParameter(ParamMobile, userInfo.Mobile), + // GetParameter(ParamAvatarUrl, userInfo.AvatarUrl), + // GetParameter(ParamGender, userInfo.Gender), + // GetParameter(ParamBirthday, userInfo.Birthday), + // GetParameter(ParamWeiXin, userInfo.WeiXin), + // GetParameter(ParamQq, userInfo.Qq), + // GetParameter(ParamWeiBo, userInfo.WeiBo), + // GetParameter(ParamBio,userInfo.Bio), + // GetParameter(ParamSettingsXml,userInfo.ToString(UserAttribute.AllAttributes.Value)), + // GetParameter(ParamId, userInfo.Id) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + var updated = base.Update(userInfo); + + UserManager.UpdateCache(userInfo); + + return updated; + } + + private void UpdateLastActivityDateAndCountOfFailedLogin(UserInfo userInfo) + { + if (userInfo == null) return; + + userInfo.LastActivityDate = DateTime.Now; + userInfo.CountOfFailedLogin += 1; + + //var sqlString = $"UPDATE {TableName} SET LastActivityDate = @LastActivityDate, CountOfFailedLogin = @CountOfFailedLogin WHERE Id = @Id"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamLastActivityDate, userInfo.LastActivityDate), + // GetParameter(ParamCountOfFailedLogin, userInfo.CountOfFailedLogin), + // GetParameter(ParamId, userInfo.Id) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Update(userInfo, Attr.LastActivityDate, Attr.CountOfFailedLogin); + + UserManager.UpdateCache(userInfo); + } + + public void UpdateLastActivityDateAndCountOfLogin(UserInfo userInfo) + { + if (userInfo == null) return; + + userInfo.LastActivityDate = DateTime.Now; + userInfo.CountOfLogin += 1; + userInfo.CountOfFailedLogin = 0; + + //var sqlString = $"UPDATE {TableName} SET LastActivityDate = @LastActivityDate, CountOfLogin = @CountOfLogin, CountOfFailedLogin = @CountOfFailedLogin WHERE Id = @Id"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamLastActivityDate, userInfo.LastActivityDate), + // GetParameter(ParamCountOfLogin, userInfo.CountOfLogin), + // GetParameter(ParamCountOfFailedLogin, userInfo.CountOfFailedLogin), + // GetParameter(ParamId, userInfo.Id) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Update(userInfo, Attr.LastActivityDate, Attr.CountOfLogin, Attr.CountOfFailedLogin); + + UserManager.UpdateCache(userInfo); + } + + private string EncodePassword(string password, EPasswordFormat passwordFormat, string passwordSalt) + { + var retVal = string.Empty; + + if (passwordFormat == EPasswordFormat.Clear) + { + retVal = password; + } + else if (passwordFormat == EPasswordFormat.Hashed) + { + var src = Encoding.Unicode.GetBytes(password); + var buffer2 = Convert.FromBase64String(passwordSalt); + var dst = new byte[buffer2.Length + src.Length]; + byte[] inArray = null; + Buffer.BlockCopy(buffer2, 0, dst, 0, buffer2.Length); + Buffer.BlockCopy(src, 0, dst, buffer2.Length, src.Length); + var algorithm = HashAlgorithm.Create("SHA1"); + if (algorithm != null) inArray = algorithm.ComputeHash(dst); + + if (inArray != null) retVal = Convert.ToBase64String(inArray); + } + else if (passwordFormat == EPasswordFormat.Encrypted) + { + var encrypt = new DesEncryptor + { + InputString = password, + EncryptKey = passwordSalt + }; + encrypt.DesEncrypt(); + + retVal = encrypt.OutString; + } + return retVal; + } + + private string DecodePassword(string password, EPasswordFormat passwordFormat, string passwordSalt) + { + var retVal = string.Empty; + if (passwordFormat == EPasswordFormat.Clear) + { + retVal = password; + } + else if (passwordFormat == EPasswordFormat.Hashed) + { + throw new Exception("can not decode hashed password"); + } + else if (passwordFormat == EPasswordFormat.Encrypted) + { + var encrypt = new DesEncryptor + { + InputString = password, + DecryptKey = passwordSalt + }; + encrypt.DesDecrypt(); + + retVal = encrypt.OutString; + } + return retVal; + } + + private static string GenerateSalt() + { + var data = new byte[0x10]; + new RNGCryptoServiceProvider().GetBytes(data); + return Convert.ToBase64String(data); + } + + public bool ChangePassword(string userName, string password, out string errorMessage) + { + errorMessage = null; + if (password.Length < ConfigManager.Instance.UserPasswordMinLength) + { + errorMessage = $"密码长度必须大于等于{ConfigManager.Instance.UserPasswordMinLength}"; + return false; + } + if (!EUserPasswordRestrictionUtils.IsValid(password, ConfigManager.Instance.UserPasswordRestriction)) + { + errorMessage = + $"密码不符合规则,请包含{EUserPasswordRestrictionUtils.GetText(EUserPasswordRestrictionUtils.GetEnumType(ConfigManager.Instance.UserPasswordRestriction))}"; + return false; + } + + const EPasswordFormat passwordFormat = EPasswordFormat.Encrypted; + var passwordSalt = GenerateSalt(); + password = EncodePassword(password, passwordFormat, passwordSalt); + ChangePassword(userName, passwordFormat, passwordSalt, password); + return true; + } + + private void ChangePassword(string userName, EPasswordFormat passwordFormat, string passwordSalt, string password) + { + var userInfo = UserManager.GetUserInfoByUserName(userName); + if (userInfo == null) return; + + userInfo.PasswordFormat = EPasswordFormatUtils.GetValue(passwordFormat); + userInfo.Password = password; + userInfo.PasswordSalt = passwordSalt; + userInfo.LastResetPasswordDate = DateTime.Now; + + //var sqlString = $"UPDATE {TableName} SET Password = @Password, PasswordFormat = @PasswordFormat, PasswordSalt = @PasswordSalt, LastResetPasswordDate = @LastResetPasswordDate WHERE UserName = @UserName"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamPassword, userInfo.Password), + // GetParameter(ParamPasswordFormat, userInfo.PasswordFormat), + // GetParameter(ParamPasswordSalt, userInfo.PasswordSalt), + // GetParameter(ParamLastResetPasswordDate,userInfo.LastResetPasswordDate), + // GetParameter(ParamUserName, userName) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Update(userInfo, Attr.PasswordFormat, Attr.Password, Attr.PasswordSalt, Attr.LastResetPasswordDate); + + LogUtils.AddUserLog(userName, "修改密码", string.Empty); + + UserManager.UpdateCache(userInfo); + } + + public void Check(List idList) + { + //var sqlString = + // $"UPDATE {TableName} SET IsChecked = '{true}' WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + Update(Q + .Set(Attr.IsChecked, true.ToString()) + .WhereIn(Attr.Id, idList) + ); + + UserManager.ClearCache(); + } + + public void Lock(List idList) + { + //var sqlString = + // $"UPDATE {TableName} SET IsLockedOut = '{true}' WHERE Id IN ({TranslateUtils.ToSqlInStringWithQuote(idList)})"; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + Update(Q + .Set(Attr.IsLockedOut, true.ToString()) + .WhereIn(Attr.Id, idList) + ); + + UserManager.ClearCache(); + } + + public void UnLock(List idList) + { + //var sqlString = + // $"UPDATE {TableName} SET IsLockedOut = '{false}', CountOfFailedLogin = 0 WHERE Id IN ({TranslateUtils.ToSqlInStringWithQuote(idList)})"; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + + Update(Q + .Set(Attr.IsLockedOut, false.ToString()) + .WhereIn(Attr.Id, idList) + ); + + UserManager.ClearCache(); + } + + private UserInfo GetByAccount(string account) + { + var userInfo = GetByUserName(account); + if (userInfo != null) return userInfo; + if (StringUtils.IsMobile(account)) return GetByMobile(account); + if (StringUtils.IsEmail(account)) return GetByEmail(account); + + return null; + } + + public UserInfo GetByUserName(string userName) + { + if (string.IsNullOrEmpty(userName)) return null; + + //UserInfo userInfo = null; + //var sqlString = $"SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreateDate, LastResetPasswordDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, GroupId, IsChecked, IsLockedOut, DisplayName, Email, Mobile, AvatarUrl, Gender, Birthday, WeiXin, QQ, WeiBo, Bio, SettingsXml FROM {TableName} WHERE UserName = @UserName"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamUserName, userName) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // userInfo = new UserInfo(rdr); + // } + // rdr.Close(); + //} + + var userInfo = Get(Q.Where(Attr.UserName, userName)); + + UserManager.UpdateCache(userInfo); + + return userInfo; + } + + public UserInfo GetByEmail(string email) + { + if (string.IsNullOrEmpty(email)) return null; + + //UserInfo userInfo = null; + //var sqlString = $"SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreateDate, LastResetPasswordDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, GroupId, IsChecked, IsLockedOut, DisplayName, Email, Mobile, AvatarUrl, Gender, Birthday, WeiXin, QQ, WeiBo, Bio, SettingsXml FROM {TableName} WHERE Email = @Email"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamEmail, email) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // userInfo = new UserInfo(rdr); + // } + // rdr.Close(); + //} + + var userInfo = Get(Q.Where(Attr.Email, email)); + + UserManager.UpdateCache(userInfo); + + return userInfo; + } + + public UserInfo GetByMobile(string mobile) + { + if (string.IsNullOrEmpty(mobile)) return null; + + //UserInfo userInfo = null; + //var sqlString = $"SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreateDate, LastResetPasswordDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, GroupId, IsChecked, IsLockedOut, DisplayName, Email, Mobile, AvatarUrl, Gender, Birthday, WeiXin, QQ, WeiBo, Bio, SettingsXml FROM {TableName} WHERE Mobile = @Mobile"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamMobile, mobile) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // userInfo = new UserInfo(rdr); + // } + // rdr.Close(); + //} + + var userInfo = Get(Q.Where(Attr.Mobile, mobile)); + + UserManager.UpdateCache(userInfo); + + return userInfo; + } + + public UserInfo GetByUserId(int id) + { + if (id <= 0) return null; + + //UserInfo userInfo = null; + //var sqlString = $"SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreateDate, LastResetPasswordDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, GroupId, IsChecked, IsLockedOut, DisplayName, Email, Mobile, AvatarUrl, Gender, Birthday, WeiXin, QQ, WeiBo, Bio, SettingsXml FROM {TableName} WHERE Id = @Id"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamId, id) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // userInfo = new UserInfo(rdr); + // } + // rdr.Close(); + //} + + var userInfo = Get(id); + + UserManager.UpdateCache(userInfo); + + return userInfo; + } + + public bool IsUserNameExists(string userName) + { + if (string.IsNullOrEmpty(userName)) return false; + + //var exists = false; + + //var sqlString = $"SELECT Id FROM {TableName} WHERE UserName = @UserName"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamUserName, userName) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read() && !rdr.IsDBNull(0)) + // { + // exists = true; + // } + // rdr.Close(); + //} + + //return exists; + + return Exists(Q.Where(Attr.UserName, userName)); + } + + private bool IsUserNameCompliant(string userName) + { + if (userName.IndexOf(" ", StringComparison.Ordinal) != -1 || userName.IndexOf(" ", StringComparison.Ordinal) != -1 || userName.IndexOf("'", StringComparison.Ordinal) != -1 || userName.IndexOf(":", StringComparison.Ordinal) != -1 || userName.IndexOf(".", StringComparison.Ordinal) != -1) + { + return false; + } + return DirectoryUtils.IsDirectoryNameCompliant(userName); + } + + public bool IsEmailExists(string email) + { + if (string.IsNullOrEmpty(email)) return false; + + var exists = IsUserNameExists(email); + if (exists) return true; + + //var sqlSelect = $"SELECT Email FROM {TableName} WHERE Email = @Email"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamEmail, email) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlSelect, parameters)) + //{ + // if (rdr.Read()) + // { + // exists = true; + // } + // rdr.Close(); + //} + + return Exists(Q.Where(Attr.Email, email)); + } + + public bool IsMobileExists(string mobile) + { + if (string.IsNullOrEmpty(mobile)) return false; + + var exists = IsUserNameExists(mobile); + if (exists) return true; + + //var sqlString = $"SELECT Mobile FROM {TableName} WHERE Mobile = @Mobile"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamMobile, mobile) + //}; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) + //{ + // if (rdr.Read()) + // { + // exists = true; + // } + // rdr.Close(); + //} + + //return exists; + + return Exists(Q.Where(Attr.Mobile, mobile)); + } + + public IList GetIdList(bool isChecked) + { + //var idList = new List(); + + //var sqlSelect = + // $"SELECT Id FROM {TableName} WHERE IsChecked = '{isChecked}' ORDER BY Id DESC"; + + //using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlSelect)) + //{ + // while (rdr.Read()) + // { + // idList.Add(DatabaseApi.GetInt(rdr, 0)); + // } + // rdr.Close(); + //} + + //return idList; + + return GetAll(Q + .Select(Attr.Id) + .Where(Attr.IsChecked, isChecked.ToString()) + .OrderByDesc(Attr.Id)); + } + + public string GetSelectCommand() + { + return DataProvider.DatabaseApi.GetSelectSqlString(TableName, string.Empty); + } + + public string GetSelectCommand(int groupId, string searchWord, int dayOfCreate, int dayOfLastActivity, int loginCount, string searchType) + { + var whereBuilder = new StringBuilder(); + + if (dayOfCreate > 0) + { + if (whereBuilder.Length > 0) whereBuilder.Append(" AND "); + var dateTime = DateTime.Now.AddDays(-dayOfCreate); + whereBuilder.Append($"(CreateDate >= {SqlUtils.GetComparableDate(dateTime)})"); + } + + if (dayOfLastActivity > 0) + { + if (whereBuilder.Length > 0) whereBuilder.Append(" AND "); + var dateTime = DateTime.Now.AddDays(-dayOfLastActivity); + whereBuilder.Append($"(LastActivityDate >= {SqlUtils.GetComparableDate(dateTime)}) "); + } + + if (groupId > -1) + { + if (whereBuilder.Length > 0) whereBuilder.Append(" AND "); + whereBuilder.Append(groupId == 0 ? "(GroupId = 0 OR GroupId IS NULL)" : $"GroupId = {groupId}"); + } + + searchWord = AttackUtils.FilterSql(searchWord); + + if (string.IsNullOrEmpty(searchType)) + { + if (whereBuilder.Length > 0) whereBuilder.Append(" AND "); + whereBuilder.Append( + $"(UserName LIKE '%{searchWord}%' OR EMAIL LIKE '%{searchWord}%')"); + } + else + { + if (whereBuilder.Length > 0) whereBuilder.Append(" AND "); + whereBuilder.Append($"({searchType} LIKE '%{searchWord}%') "); + } + + if (loginCount > 0) + { + if (whereBuilder.Length > 0) whereBuilder.Append(" AND "); + whereBuilder.Append($"(CountOfLogin > {loginCount})"); + } + + var whereString = string.Empty; + if (whereBuilder.Length > 0) + { + whereString = $"WHERE {whereBuilder}"; + } + + return DataProvider.DatabaseApi.GetSelectSqlString(TableName, whereString); + } + + public bool CheckPassword(string password, bool isPasswordMd5, string dbPassword, EPasswordFormat passwordFormat, string passwordSalt) + { + var decodePassword = DecodePassword(dbPassword, passwordFormat, passwordSalt); + if (isPasswordMd5) + { + return password == AuthUtils.Md5ByString(decodePassword); + } + return password == decodePassword; + } + + public UserInfo Validate(string account, string password, bool isPasswordMd5, out string userName, out string errorMessage) + { + userName = string.Empty; + errorMessage = string.Empty; + + if (string.IsNullOrEmpty(account)) + { + errorMessage = "账号不能为空"; + return null; + } + if (string.IsNullOrEmpty(password)) + { + errorMessage = "密码不能为空"; + return null; + } + + var userInfo = GetByAccount(account); + + if (string.IsNullOrEmpty(userInfo?.UserName)) + { + errorMessage = "帐号或密码错误"; + return null; + } + + userName = userInfo.UserName; + + if (!userInfo.Checked) + { + errorMessage = "此账号未审核,无法登录"; + return null; + } + + if (userInfo.Locked) + { + errorMessage = "此账号被锁定,无法登录"; + return null; + } + + if (ConfigManager.Instance.IsUserLockLogin) + { + if (userInfo.CountOfFailedLogin > 0 && userInfo.CountOfFailedLogin >= ConfigManager.Instance.UserLockLoginCount) + { + var lockType = EUserLockTypeUtils.GetEnumType(ConfigManager.Instance.UserLockLoginType); + if (lockType == EUserLockType.Forever) + { + errorMessage = "此账号错误登录次数过多,已被永久锁定"; + return null; + } + if (lockType == EUserLockType.Hours) + { + if (userInfo.LastActivityDate.HasValue) + { + var ts = new TimeSpan(DateTime.Now.Ticks - userInfo.LastActivityDate.Value.Ticks); + var hours = Convert.ToInt32(ConfigManager.Instance.UserLockLoginHours - ts.TotalHours); + if (hours > 0) + { + errorMessage = + $"此账号错误登录次数过多,已被锁定,请等待{hours}小时后重试"; + return null; + } + } + } + } + } + + if (!CheckPassword(password, isPasswordMd5, userInfo.Password, EPasswordFormatUtils.GetEnumType(userInfo.PasswordFormat), userInfo.PasswordSalt)) + { + DataProvider.User.UpdateLastActivityDateAndCountOfFailedLogin(userInfo); + LogUtils.AddUserLog(userInfo.UserName, "用户登录失败", "帐号或密码错误"); + errorMessage = "帐号或密码错误"; + return null; + } + + return userInfo; + } + + public Dictionary GetTrackingDictionary(DateTime dateFrom, DateTime dateTo, string xType) + { + var dict = new Dictionary(); + if (string.IsNullOrEmpty(xType)) + { + xType = EStatictisXTypeUtils.GetValue(EStatictisXType.Day); + } + + var builder = new StringBuilder(); + builder.Append($" AND CreateDate >= {SqlUtils.GetComparableDate(dateFrom)}"); + builder.Append($" AND CreateDate < {SqlUtils.GetComparableDate(dateTo)}"); + + string sqlString = $@" +SELECT COUNT(*) AS AddNum, AddYear, AddMonth, AddDay FROM ( + SELECT {SqlUtils.GetDatePartYear("CreateDate")} AS AddYear, {SqlUtils.GetDatePartMonth("CreateDate")} AS AddMonth, {SqlUtils.GetDatePartDay("CreateDate")} AS AddDay + FROM {TableName} + WHERE {SqlUtils.GetDateDiffLessThanDays("CreateDate", 30.ToString())} {builder} +) DERIVEDTBL GROUP BY AddYear, AddMonth, AddDay ORDER BY AddYear, AddMonth, AddDay +";//添加日统计 + + if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Month)) + { + sqlString = $@" +SELECT COUNT(*) AS AddNum, AddYear, AddMonth FROM ( + SELECT {SqlUtils.GetDatePartYear("CreateDate")} AS AddYear, {SqlUtils.GetDatePartMonth("CreateDate")} AS AddMonth + FROM {TableName} + WHERE {SqlUtils.GetDateDiffLessThanMonths("CreateDate", 12.ToString())} {builder} +) DERIVEDTBL GROUP BY AddYear, AddMonth ORDER BY AddYear, AddMonth +";//添加月统计 + } + else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Year)) + { + sqlString = $@" +SELECT COUNT(*) AS AddNum, AddYear FROM ( + SELECT {SqlUtils.GetDatePartYear("CreateDate")} AS AddYear + FROM {TableName} + WHERE {SqlUtils.GetDateDiffLessThanYears("CreateDate", 10.ToString())} {builder} +) DERIVEDTBL GROUP BY AddYear ORDER BY AddYear +";//添加年统计 + } + + using (var rdr = DataProvider.DatabaseApi.ExecuteReader(WebConfigUtils.ConnectionString, sqlString)) + { + while (rdr.Read()) + { + var accessNum = DataProvider.DatabaseApi.GetInt(rdr, 0); + if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Day)) + { + var year = DataProvider.DatabaseApi.GetString(rdr, 1); + var month = DataProvider.DatabaseApi.GetString(rdr, 2); + var day = DataProvider.DatabaseApi.GetString(rdr, 3); + var dateTime = TranslateUtils.ToDateTime($"{year}-{month}-{day}"); + dict.Add(dateTime, accessNum); + } + else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Month)) + { + var year = DataProvider.DatabaseApi.GetString(rdr, 1); + var month = DataProvider.DatabaseApi.GetString(rdr, 2); + + var dateTime = TranslateUtils.ToDateTime($"{year}-{month}-1"); + dict.Add(dateTime, accessNum); + } + else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Year)) + { + var year = DataProvider.DatabaseApi.GetString(rdr, 1); + var dateTime = TranslateUtils.ToDateTime($"{year}-1-1"); + dict.Add(dateTime, accessNum); + } + } + rdr.Close(); + } + return dict; + } + + public int GetCount() + { + //return DatabaseApi.GetCount(TableName); + return Count(); + } + + public IList GetUsers(int offset, int limit) + { + //var list = new List(); + //List dbList; + + //var sqlString = + // SqlDifferences.GetSqlString(TableName, new List + // { + // nameof(UserInfo.Id) + // }, string.Empty, "ORDER BY Id", offset, limit); + + //using (var connection = GetConnection()) + //{ + // dbList = connection.Query(sqlString).ToList(); + //} + + //if (dbList.Count > 0) + //{ + // foreach (var userId in dbList) + // { + // list.Add(UserManager.GetUserInfoByUserId(userId)); + // } + //} + + //return list; + + return GetAll(Q + .Offset(offset) + .Limit(limit) + .OrderBy(Attr.Id)); + } + + public bool IsExists(int id) + { + //var sqlString = $"SELECT COUNT(1) FROM {TableName} WHERE Id = @Id"; + + //using (var connection = GetConnection()) + //{ + // return connection.ExecuteScalar(sqlString, new { Id = id }); + //} + + return Exists(id); + } + + public void Delete(UserInfo userInfo) + { + //var sqlString = $"DELETE FROM {TableName} WHERE Id = @Id"; + + //IDataParameter[] parameters = + //{ + // GetParameter(ParamId, userInfo.Id) + //}; + + //DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + + Delete(userInfo.Id); + + UserManager.RemoveCache(userInfo); + } + } +} + + + +//using System; +//using System.Collections.Generic; +//using System.Data; +//using System.Linq; +//using System.Security.Cryptography; +//using System.Text; +//using Dapper; +//using SiteServer.CMS.Core; +//using SiteServer.CMS.Core.Attributes; +//using SiteServer.CMS.Database.Caches; +//using SiteServer.CMS.Database.Core; +//using SiteServer.CMS.Database.Models; +//using SiteServer.Plugin; +//using SiteServer.Utils; +//using SiteServer.Utils.Auth; +//using SiteServer.Utils.Enumerations; + +//namespace SiteServer.CMS.Database.Repositories +//{ +// public class User : DataProviderBase +// { +// public const string DatabaseTableName = "siteserver_User"; + +// public override string TableName => DatabaseTableName; + +// public override List TableColumns => new List +// { +// new TableColumn +// { +// AttributeName = nameof(UserInfo.Id), +// DataType = DataType.Integer, +// IsIdentity = true, +// IsPrimaryKey = true +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.UserName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.Password), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.PasswordFormat), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.PasswordSalt), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.CreateDate), +// DataType = DataType.DateTime +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.LastResetPasswordDate), +// DataType = DataType.DateTime +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.LastActivityDate), +// DataType = DataType.DateTime +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.CountOfLogin), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.CountOfFailedLogin), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.GroupId), +// DataType = DataType.Integer +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.IsChecked), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.IsLockedOut), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.DisplayName), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.Email), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.Mobile), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.AvatarUrl), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.Gender), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.Birthday), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.WeiXin), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.Qq), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.WeiBo), +// DataType = DataType.VarChar +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.Bio), +// DataType = DataType.Text +// }, +// new TableColumn +// { +// AttributeName = nameof(UserInfo.SettingsXml), +// DataType = DataType.Text +// } +// }; + +// private const string ParamId = "@Id"; +// private const string ParamUserName = "@UserName"; +// private const string ParamPassword = "@Password"; +// private const string ParamPasswordFormat = "@PasswordFormat"; +// private const string ParamPasswordSalt = "@PasswordSalt"; +// private const string ParamCreateDate = "@CreateDate"; +// private const string ParamLastResetPasswordDate = "@LastResetPasswordDate"; +// private const string ParamLastActivityDate = "@LastActivityDate"; +// private const string ParamCountOfLogin = "@CountOfLogin"; +// private const string ParamCountOfFailedLogin = "@CountOfFailedLogin"; +// private const string ParamGroupId = "@GroupId"; +// private const string ParamIsChecked = "@IsChecked"; +// private const string ParamIsLockedOut = "@IsLockedOut"; +// private const string ParamDisplayName = "@DisplayName"; +// private const string ParamEmail = "@Email"; +// private const string ParamMobile = "@Mobile"; +// private const string ParamAvatarUrl = "@AvatarUrl"; +// private const string ParamGender = "@Gender"; +// private const string ParamBirthday = "@Birthday"; +// private const string ParamWeiXin = "@WeiXin"; +// private const string ParamQq = "@QQ"; +// private const string ParamWeiBo = "@WeiBo"; +// private const string ParamBio = "@Bio"; +// private const string ParamSettingsXml = "@SettingsXml"; + +// private bool InsertValidate(string userName, string email, string mobile, string password, string ipAddress, out string errorMessage) +// { +// errorMessage = string.Empty; + +// if (!UserManager.IsIpAddressCached(ipAddress)) +// { +// errorMessage = $"同一IP在{ConfigManager.Instance.UserRegistrationMinMinutes}分钟内只能注册一次"; +// return false; +// } +// if (string.IsNullOrEmpty(password)) +// { +// errorMessage = "密码不能为空"; +// return false; +// } +// if (password.Length < ConfigManager.Instance.UserPasswordMinLength) +// { +// errorMessage = $"密码长度必须大于等于{ConfigManager.Instance.UserPasswordMinLength}"; +// return false; +// } +// if (!EUserPasswordRestrictionUtils.IsValid(password, ConfigManager.Instance.UserPasswordRestriction)) +// { +// errorMessage = +// $"密码不符合规则,请包含{EUserPasswordRestrictionUtils.GetText(EUserPasswordRestrictionUtils.GetEnumType(ConfigManager.Instance.UserPasswordRestriction))}"; +// return false; +// } +// if (string.IsNullOrEmpty(userName)) +// { +// errorMessage = "用户名为空,请填写用户名"; +// return false; +// } +// if (!string.IsNullOrEmpty(userName) && IsUserNameExists(userName)) +// { +// errorMessage = "用户名已被注册,请更换用户名"; +// return false; +// } +// if (!IsUserNameCompliant(userName.Replace("@", string.Empty).Replace(".", string.Empty))) +// { +// errorMessage = "用户名包含不规则字符,请更换用户名"; +// return false; +// } + +// if (!string.IsNullOrEmpty(email) && IsEmailExists(email)) +// { +// errorMessage = "电子邮件地址已被注册,请更换邮箱"; +// return false; +// } +// if (!string.IsNullOrEmpty(mobile) && IsMobileExists(mobile)) +// { +// errorMessage = "手机号码已被注册,请更换手机号码"; +// return false; +// } + +// return true; +// } + +// private bool UpdateValidate(Dictionary body, string userName, string email, string mobile, out string errorMessage) +// { +// errorMessage = string.Empty; + +// var bodyUserName = string.Empty; +// if (body.ContainsKey("userName")) +// { +// bodyUserName = (string) body["userName"]; +// } + +// if (!string.IsNullOrEmpty(bodyUserName) && bodyUserName != userName) +// { +// if (!IsUserNameCompliant(bodyUserName.Replace("@", string.Empty).Replace(".", string.Empty))) +// { +// errorMessage = "用户名包含不规则字符,请更换用户名"; +// return false; +// } +// if (!string.IsNullOrEmpty(bodyUserName) && IsUserNameExists(bodyUserName)) +// { +// errorMessage = "用户名已被注册,请更换用户名"; +// return false; +// } +// } + +// var bodyEmail = string.Empty; +// if (body.ContainsKey("email")) +// { +// bodyEmail = (string)body["email"]; +// } + +// if (bodyEmail != null && bodyEmail != email) +// { +// if (!string.IsNullOrEmpty(bodyEmail) && IsEmailExists(bodyEmail)) +// { +// errorMessage = "电子邮件地址已被注册,请更换邮箱"; +// return false; +// } +// } + +// var bodyMobile = string.Empty; +// if (body.ContainsKey("mobile")) +// { +// bodyMobile = (string)body["mobile"]; +// } + +// if (bodyMobile != null && bodyMobile != mobile) +// { +// if (!string.IsNullOrEmpty(bodyMobile) && IsMobileExists(bodyMobile)) +// { +// errorMessage = "手机号码已被注册,请更换手机号码"; +// return false; +// } +// } + +// return true; +// } + +// public int InsertObject(UserInfo userInfo, string password, string ipAddress, out string errorMessage) +// { +// errorMessage = string.Empty; +// if (userInfo == null) return 0; + +// if (!ConfigManager.Instance.IsUserRegistrationAllowed) +// { +// errorMessage = "对不起,系统已禁止新用户注册!"; +// return 0; +// } + +// try +// { +// userInfo.IsChecked = ConfigManager.Instance.IsUserRegistrationChecked; +// if (StringUtils.IsMobile(userInfo.UserName) && string.IsNullOrEmpty(userInfo.Mobile)) +// { +// userInfo.Mobile = userInfo.UserName; +// } + +// if (!InsertValidate(userInfo.UserName, userInfo.Email, userInfo.Mobile, password, ipAddress, out errorMessage)) return 0; + +// var passwordSalt = GenerateSalt(); +// password = EncodePassword(password, EPasswordFormat.Encrypted, passwordSalt); +// userInfo.CreateDate = DateTime.Now; +// userInfo.LastActivityDate = DateTime.Now; +// userInfo.LastResetPasswordDate = DateTime.Now; + +// userInfo.Id = InsertWithoutValidation(userInfo, password, EPasswordFormat.Encrypted, passwordSalt); + +// UserManager.CacheIpAddress(ipAddress); + +// return userInfo.Id; +// } +// catch (Exception ex) +// { +// errorMessage = ex.Message; +// return 0; +// } +// } + +// private int InsertWithoutValidation(UserInfo userInfo, string password, EPasswordFormat passwordFormat, string passwordSalt) +// { +// var sqlString = $"INSERT INTO {TableName} (UserName, Password, PasswordFormat, PasswordSalt, CreateDate, LastResetPasswordDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, GroupId, IsChecked, IsLockedOut, DisplayName, Email, Mobile, AvatarUrl, Gender, Birthday, WeiXin, QQ, WeiBo, Bio, SettingsXml) VALUES (@UserName, @Password, @PasswordFormat, @PasswordSalt, @CreateDate, @LastResetPasswordDate, @LastActivityDate, @CountOfLogin, @CountOfFailedLogin, @GroupId, @IsChecked, @IsLockedOut, @DisplayName, @Email, @Mobile, @AvatarUrl, @Gender, @Birthday, @WeiXin, @QQ, @WeiBo, @Bio, @SettingsXml)"; + +// userInfo.CreateDate = DateTime.Now; +// userInfo.LastActivityDate = DateTime.Now; +// userInfo.LastResetPasswordDate = DateTime.Now; + +// userInfo.DisplayName = AttackUtils.FilterXss(userInfo.DisplayName); +// userInfo.Email = AttackUtils.FilterXss(userInfo.Email); +// userInfo.Mobile = AttackUtils.FilterXss(userInfo.Mobile); +// userInfo.AvatarUrl = AttackUtils.FilterXss(userInfo.AvatarUrl); +// userInfo.Gender = AttackUtils.FilterXss(userInfo.Gender); +// userInfo.Birthday = AttackUtils.FilterXss(userInfo.Birthday); +// userInfo.WeiXin = AttackUtils.FilterXss(userInfo.WeiXin); +// userInfo.Qq = AttackUtils.FilterXss(userInfo.Qq); +// userInfo.WeiBo = AttackUtils.FilterXss(userInfo.WeiBo); +// userInfo.Bio = AttackUtils.FilterXss(userInfo.Bio); +// var settingsXml = userInfo.ToString(UserAttribute.AllAttributes.Value); + +// IDataParameter[] parameters = +// { +// GetParameter(ParamUserName, userInfo.UserName), +// GetParameter(ParamPassword, password), +// GetParameter(ParamPasswordFormat, EPasswordFormatUtils.GetValueById(passwordFormat)), +// GetParameter(ParamPasswordSalt, passwordSalt), +// GetParameter(ParamCreateDate,userInfo.CreateDate), +// GetParameter(ParamLastResetPasswordDate,userInfo.LastResetPasswordDate), +// GetParameter(ParamLastActivityDate,userInfo.LastActivityDate), +// GetParameter(ParamCountOfLogin, userInfo.CountOfLogin), +// GetParameter(ParamCountOfFailedLogin, userInfo.CountOfFailedLogin), +// GetParameter(ParamGroupId, userInfo.GroupId), +// GetParameter(ParamIsChecked, userInfo.IsChecked.ToString()), +// GetParameter(ParamIsLockedOut, userInfo.IsLockedOut.ToString()), +// GetParameter(ParamDisplayName, userInfo.DisplayName), +// GetParameter(ParamEmail, userInfo.Email), +// GetParameter(ParamMobile, userInfo.Mobile), +// GetParameter(ParamAvatarUrl, userInfo.AvatarUrl), +// GetParameter(ParamGender, userInfo.Gender), +// GetParameter(ParamBirthday, userInfo.Birthday), +// GetParameter(ParamWeiXin, userInfo.WeiXin), +// GetParameter(ParamQq, userInfo.Qq), +// GetParameter(ParamWeiBo, userInfo.WeiBo), +// GetParameter(ParamBio,userInfo.Bio), +// GetParameter(ParamSettingsXml,settingsXml) +// }; + +// return DatabaseApi.ExecuteNonQueryAndReturnId(ConnectionString, TableName, UserAttribute.Id, sqlString, parameters); +// } + +// public bool IsPasswordCorrect(string password, out string errorMessage) +// { +// errorMessage = null; +// if (string.IsNullOrEmpty(password)) +// { +// errorMessage = "密码不能为空"; +// return false; +// } +// if (password.Length < ConfigManager.Instance.UserPasswordMinLength) +// { +// errorMessage = $"密码长度必须大于等于{ConfigManager.Instance.UserPasswordMinLength}"; +// return false; +// } +// if (!EUserPasswordRestrictionUtils.IsValid(password, ConfigManager.Instance.UserPasswordRestriction)) +// { +// errorMessage = +// $"密码不符合规则,请包含{EUserPasswordRestrictionUtils.GetText(EUserPasswordRestrictionUtils.GetEnumType(ConfigManager.Instance.UserPasswordRestriction))}"; +// return false; +// } +// return true; +// } + +// public UserInfo UpdateObject(UserInfo userInfo, Dictionary body, out string errorMessage) +// { +// if (!UpdateValidate(body, userInfo.UserName, userInfo.Email, userInfo.Mobile, out errorMessage)) return null; + +// userInfo.Load(body); + +// UpdateObject(userInfo); + +// return userInfo; +// } + +// public void UpdateObject(UserInfo userInfo) +// { +// if (userInfo == null) return; + +// userInfo.DisplayName = AttackUtils.FilterXss(userInfo.DisplayName); +// userInfo.Email = AttackUtils.FilterXss(userInfo.Email); +// userInfo.Mobile = AttackUtils.FilterXss(userInfo.Mobile); +// userInfo.AvatarUrl = AttackUtils.FilterXss(userInfo.AvatarUrl); +// userInfo.Gender = AttackUtils.FilterXss(userInfo.Gender); +// userInfo.Birthday = AttackUtils.FilterXss(userInfo.Birthday); +// userInfo.WeiXin = AttackUtils.FilterXss(userInfo.WeiXin); +// userInfo.Qq = AttackUtils.FilterXss(userInfo.Qq); +// userInfo.WeiBo = AttackUtils.FilterXss(userInfo.WeiBo); +// userInfo.Bio = AttackUtils.FilterXss(userInfo.Bio); + +// var sqlString = $"UPDATE {TableName} SET UserName = @UserName, CreateDate = @CreateDate, LastResetPasswordDate = @LastResetPasswordDate, LastActivityDate = @LastActivityDate, CountOfLogin = @CountOfLogin, CountOfFailedLogin = @CountOfFailedLogin, GroupId = @GroupId, IsChecked = @IsChecked, IsLockedOut = @IsLockedOut, DisplayName = @DisplayName, Email = @Email, Mobile = @Mobile, AvatarUrl = @AvatarUrl, Gender = @Gender, Birthday = @Birthday, WeiXin = @WeiXin, QQ = @QQ, WeiBo = @WeiBo, Bio = @Bio, SettingsXml = @SettingsXml WHERE Id = @Id"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamUserName, userInfo.UserName), +// GetParameter(ParamCreateDate,userInfo.CreateDate), +// GetParameter(ParamLastResetPasswordDate,userInfo.LastResetPasswordDate), +// GetParameter(ParamLastActivityDate,userInfo.LastActivityDate), +// GetParameter(ParamCountOfLogin, userInfo.CountOfLogin), +// GetParameter(ParamCountOfFailedLogin, userInfo.CountOfFailedLogin), +// GetParameter(ParamGroupId, userInfo.GroupId), +// GetParameter(ParamIsChecked, userInfo.IsChecked.ToString()), +// GetParameter(ParamIsLockedOut, userInfo.IsLockedOut.ToString()), +// GetParameter(ParamDisplayName, userInfo.DisplayName), +// GetParameter(ParamEmail, userInfo.Email), +// GetParameter(ParamMobile, userInfo.Mobile), +// GetParameter(ParamAvatarUrl, userInfo.AvatarUrl), +// GetParameter(ParamGender, userInfo.Gender), +// GetParameter(ParamBirthday, userInfo.Birthday), +// GetParameter(ParamWeiXin, userInfo.WeiXin), +// GetParameter(ParamQq, userInfo.Qq), +// GetParameter(ParamWeiBo, userInfo.WeiBo), +// GetParameter(ParamBio,userInfo.Bio), +// GetParameter(ParamSettingsXml,userInfo.ToString(UserAttribute.AllAttributes.Value)), +// GetParameter(ParamId, userInfo.Id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// UserManager.UpdateCache(userInfo); +// } + +// private void UpdateLastActivityDateAndCountOfFailedLogin(UserInfo userInfo) +// { +// if (userInfo == null) return; + +// userInfo.LastActivityDate = DateTime.Now; +// userInfo.CountOfFailedLogin += 1; + +// var sqlString = $"UPDATE {TableName} SET LastActivityDate = @LastActivityDate, CountOfFailedLogin = @CountOfFailedLogin WHERE Id = @Id"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamLastActivityDate, userInfo.LastActivityDate), +// GetParameter(ParamCountOfFailedLogin, userInfo.CountOfFailedLogin), +// GetParameter(ParamId, userInfo.Id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// UserManager.UpdateCache(userInfo); +// } + +// public void UpdateLastActivityDateAndCountOfLogin(UserInfo userInfo) +// { +// if (userInfo == null) return; + +// userInfo.LastActivityDate = DateTime.Now; +// userInfo.CountOfLogin += 1; +// userInfo.CountOfFailedLogin = 0; + +// var sqlString = $"UPDATE {TableName} SET LastActivityDate = @LastActivityDate, CountOfLogin = @CountOfLogin, CountOfFailedLogin = @CountOfFailedLogin WHERE Id = @Id"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamLastActivityDate, userInfo.LastActivityDate), +// GetParameter(ParamCountOfLogin, userInfo.CountOfLogin), +// GetParameter(ParamCountOfFailedLogin, userInfo.CountOfFailedLogin), +// GetParameter(ParamId, userInfo.Id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// UserManager.UpdateCache(userInfo); +// } + +// private string EncodePassword(string password, EPasswordFormat passwordFormat, string passwordSalt) +// { +// var retVal = string.Empty; + +// if (passwordFormat == EPasswordFormat.Clear) +// { +// retVal = password; +// } +// else if (passwordFormat == EPasswordFormat.Hashed) +// { +// var src = Encoding.Unicode.GetBytes(password); +// var buffer2 = Convert.FromBase64String(passwordSalt); +// var dst = new byte[buffer2.Length + src.Length]; +// byte[] inArray = null; +// Buffer.BlockCopy(buffer2, 0, dst, 0, buffer2.Length); +// Buffer.BlockCopy(src, 0, dst, buffer2.Length, src.Length); +// var algorithm = HashAlgorithm.Create("SHA1"); +// if (algorithm != null) inArray = algorithm.ComputeHash(dst); + +// if (inArray != null) retVal = Convert.ToBase64String(inArray); +// } +// else if (passwordFormat == EPasswordFormat.Encrypted) +// { +// var encrypt = new DesEncryptor +// { +// InputString = password, +// EncryptKey = passwordSalt +// }; +// encrypt.DesEncrypt(); + +// retVal = encrypt.OutString; +// } +// return retVal; +// } + +// private string DecodePassword(string password, EPasswordFormat passwordFormat, string passwordSalt) +// { +// var retVal = string.Empty; +// if (passwordFormat == EPasswordFormat.Clear) +// { +// retVal = password; +// } +// else if (passwordFormat == EPasswordFormat.Hashed) +// { +// throw new Exception("can not decode hashed password"); +// } +// else if (passwordFormat == EPasswordFormat.Encrypted) +// { +// var encrypt = new DesEncryptor +// { +// InputString = password, +// DecryptKey = passwordSalt +// }; +// encrypt.DesDecrypt(); + +// retVal = encrypt.OutString; +// } +// return retVal; +// } + +// private static string GenerateSalt() +// { +// var data = new byte[0x10]; +// new RNGCryptoServiceProvider().GetBytes(data); +// return Convert.ToBase64String(data); +// } + +// public bool ChangePassword(string userName, string password, out string errorMessage) +// { +// errorMessage = null; +// if (password.Length < ConfigManager.Instance.UserPasswordMinLength) +// { +// errorMessage = $"密码长度必须大于等于{ConfigManager.Instance.UserPasswordMinLength}"; +// return false; +// } +// if (!EUserPasswordRestrictionUtils.IsValid(password, ConfigManager.Instance.UserPasswordRestriction)) +// { +// errorMessage = +// $"密码不符合规则,请包含{EUserPasswordRestrictionUtils.GetText(EUserPasswordRestrictionUtils.GetEnumType(ConfigManager.Instance.UserPasswordRestriction))}"; +// return false; +// } + +// var passwordFormat = EPasswordFormat.Encrypted; +// var passwordSalt = GenerateSalt(); +// password = EncodePassword(password, passwordFormat, passwordSalt); +// ChangePassword(userName, passwordFormat, passwordSalt, password); +// return true; +// } + +// private void ChangePassword(string userName, EPasswordFormat passwordFormat, string passwordSalt, string password) +// { +// var userInfo = UserManager.GetUserInfoByUserName(userName); +// if (userInfo == null) return; + +// userInfo.PasswordFormat = EPasswordFormatUtils.GetValueById(passwordFormat); +// userInfo.Password = password; +// userInfo.PasswordSalt = passwordSalt; +// userInfo.LastResetPasswordDate = DateTime.Now; + +// var sqlString = $"UPDATE {TableName} SET Password = @Password, PasswordFormat = @PasswordFormat, PasswordSalt = @PasswordSalt, LastResetPasswordDate = @LastResetPasswordDate WHERE UserName = @UserName"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamPassword, userInfo.Password), +// GetParameter(ParamPasswordFormat, userInfo.PasswordFormat), +// GetParameter(ParamPasswordSalt, userInfo.PasswordSalt), +// GetParameter(ParamLastResetPasswordDate,userInfo.LastResetPasswordDate), +// GetParameter(ParamUserName, userName) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); +// LogUtils.AddUserLog(userName, "修改密码", string.Empty); + +// UserManager.UpdateCache(userInfo); +// } + +// public void Check(List idList) +// { +// var sqlString = +// $"UPDATE {TableName} SET IsChecked = '{true}' WHERE Id IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + +// UserManager.ClearCache(); +// } + +// public void Lock(List idList) +// { +// var sqlString = +// $"UPDATE {TableName} SET IsLockedOut = '{true}' WHERE Id IN ({TranslateUtils.ToSqlInStringWithQuote(idList)})"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + +// UserManager.ClearCache(); +// } + +// public void UnLock(List idList) +// { +// var sqlString = +// $"UPDATE {TableName} SET IsLockedOut = '{false}', CountOfFailedLogin = 0 WHERE Id IN ({TranslateUtils.ToSqlInStringWithQuote(idList)})"; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString); + +// UserManager.ClearCache(); +// } + +// private UserInfo GetByAccount(string account) +// { +// var userInfo = GetByUserName(account); +// if (userInfo != null) return userInfo; +// if (StringUtils.IsMobile(account)) return GetByMobile(account); +// if (StringUtils.IsEmail(account)) return GetByEmail(account); + +// return null; +// } + +// public UserInfo GetByUserName(string userName) +// { +// if (string.IsNullOrEmpty(userName)) return null; + +// UserInfo userInfo = null; +// var sqlString = $"SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreateDate, LastResetPasswordDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, GroupId, IsChecked, IsLockedOut, DisplayName, Email, Mobile, AvatarUrl, Gender, Birthday, WeiXin, QQ, WeiBo, Bio, SettingsXml FROM {TableName} WHERE UserName = @UserName"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamUserName, userName) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// userInfo = new UserInfo(rdr); +// } +// rdr.Close(); +// } + +// UserManager.UpdateCache(userInfo); + +// return userInfo; +// } + +// public UserInfo GetByEmail(string email) +// { +// if (string.IsNullOrEmpty(email)) return null; + +// UserInfo userInfo = null; +// var sqlString = $"SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreateDate, LastResetPasswordDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, GroupId, IsChecked, IsLockedOut, DisplayName, Email, Mobile, AvatarUrl, Gender, Birthday, WeiXin, QQ, WeiBo, Bio, SettingsXml FROM {TableName} WHERE Email = @Email"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamEmail, email) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// userInfo = new UserInfo(rdr); +// } +// rdr.Close(); +// } + +// UserManager.UpdateCache(userInfo); + +// return userInfo; +// } + +// public UserInfo GetByMobile(string mobile) +// { +// if (string.IsNullOrEmpty(mobile)) return null; + +// UserInfo userInfo = null; +// var sqlString = $"SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreateDate, LastResetPasswordDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, GroupId, IsChecked, IsLockedOut, DisplayName, Email, Mobile, AvatarUrl, Gender, Birthday, WeiXin, QQ, WeiBo, Bio, SettingsXml FROM {TableName} WHERE Mobile = @Mobile"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamMobile, mobile) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// userInfo = new UserInfo(rdr); +// } +// rdr.Close(); +// } + +// UserManager.UpdateCache(userInfo); + +// return userInfo; +// } + +// public UserInfo GetByUserId(int id) +// { +// if (id <= 0) return null; + +// UserInfo userInfo = null; +// var sqlString = $"SELECT Id, UserName, Password, PasswordFormat, PasswordSalt, CreateDate, LastResetPasswordDate, LastActivityDate, CountOfLogin, CountOfFailedLogin, GroupId, IsChecked, IsLockedOut, DisplayName, Email, Mobile, AvatarUrl, Gender, Birthday, WeiXin, QQ, WeiBo, Bio, SettingsXml FROM {TableName} WHERE Id = @Id"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamId, id) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// userInfo = new UserInfo(rdr); +// } +// rdr.Close(); +// } + +// UserManager.UpdateCache(userInfo); + +// return userInfo; +// } + +// public bool IsUserNameExists(string userName) +// { +// if (string.IsNullOrEmpty(userName)) return false; + +// var exists = false; + +// var sqlString = $"SELECT Id FROM {TableName} WHERE UserName = @UserName"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamUserName, userName) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read() && !rdr.IsDBNull(0)) +// { +// exists = true; +// } +// rdr.Close(); +// } + +// return exists; +// } + +// private bool IsUserNameCompliant(string userName) +// { +// if (userName.IndexOf(" ", StringComparison.Ordinal) != -1 || userName.IndexOf(" ", StringComparison.Ordinal) != -1 || userName.IndexOf("'", StringComparison.Ordinal) != -1 || userName.IndexOf(":", StringComparison.Ordinal) != -1 || userName.IndexOf(".", StringComparison.Ordinal) != -1) +// { +// return false; +// } +// return DirectoryUtils.IsDirectoryNameCompliant(userName); +// } + +// public bool IsEmailExists(string email) +// { +// if (string.IsNullOrEmpty(email)) return false; + +// var exists = IsUserNameExists(email); +// if (exists) return true; + +// var sqlSelect = $"SELECT Email FROM {TableName} WHERE Email = @Email"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamEmail, email) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlSelect, parameters)) +// { +// if (rdr.Read()) +// { +// exists = true; +// } +// rdr.Close(); +// } + +// return exists; +// } + +// public bool IsMobileExists(string mobile) +// { +// if (string.IsNullOrEmpty(mobile)) return false; + +// var exists = IsUserNameExists(mobile); +// if (exists) return true; + +// var sqlString = $"SELECT Mobile FROM {TableName} WHERE Mobile = @Mobile"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamMobile, mobile) +// }; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString, parameters)) +// { +// if (rdr.Read()) +// { +// exists = true; +// } +// rdr.Close(); +// } + +// return exists; +// } + +// public List GetIdList(bool isChecked) +// { +// var idList = new List(); + +// var sqlSelect = +// $"SELECT Id FROM {TableName} WHERE IsChecked = '{isChecked}' ORDER BY Id DESC"; + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlSelect)) +// { +// while (rdr.Read()) +// { +// idList.Add(DatabaseApi.GetInt(rdr, 0)); +// } +// rdr.Close(); +// } + +// return idList; +// } + +// public string GetSelectCommand() +// { +// return DataProvider.DatabaseApi.GetSelectSqlString(TableName, string.Empty); +// } + +// public string GetSelectCommand(int groupId, string searchWord, int dayOfCreate, int dayOfLastActivity, int loginCount, string searchType) +// { +// var whereBuilder = new StringBuilder(); + +// if (dayOfCreate > 0) +// { +// if (whereBuilder.Length > 0) whereBuilder.Append(" AND "); +// var dateTime = DateTime.Now.AddDays(-dayOfCreate); +// whereBuilder.Append($"(CreateDate >= {SqlUtils.GetComparableDate(dateTime)})"); +// } + +// if (dayOfLastActivity > 0) +// { +// if (whereBuilder.Length > 0) whereBuilder.Append(" AND "); +// var dateTime = DateTime.Now.AddDays(-dayOfLastActivity); +// whereBuilder.Append($"(LastActivityDate >= {SqlUtils.GetComparableDate(dateTime)}) "); +// } + +// if (groupId > -1) +// { +// if (whereBuilder.Length > 0) whereBuilder.Append(" AND "); +// whereBuilder.Append(groupId == 0 ? "(GroupId = 0 OR GroupId IS NULL)" : $"GroupId = {groupId}"); +// } + +// searchWord = AttackUtils.FilterSql(searchWord); + +// if (string.IsNullOrEmpty(searchType)) +// { +// if (whereBuilder.Length > 0) whereBuilder.Append(" AND "); +// whereBuilder.Append( +// $"(UserName LIKE '%{searchWord}%' OR EMAIL LIKE '%{searchWord}%')"); +// } +// else +// { +// if (whereBuilder.Length > 0) whereBuilder.Append(" AND "); +// whereBuilder.Append($"({searchType} LIKE '%{searchWord}%') "); +// } + +// if (loginCount > 0) +// { +// if (whereBuilder.Length > 0) whereBuilder.Append(" AND "); +// whereBuilder.Append($"(CountOfLogin > {loginCount})"); +// } + +// var whereString = string.Empty; +// if (whereBuilder.Length > 0) +// { +// whereString = $"WHERE {whereBuilder}"; +// } + +// return DataProvider.DatabaseApi.GetSelectSqlString(TableName, whereString); +// } + +// public bool CheckPassword(string password, bool isPasswordMd5, string dbPassword, EPasswordFormat passwordFormat, string passwordSalt) +// { +// var decodePassword = DecodePassword(dbPassword, passwordFormat, passwordSalt); +// if (isPasswordMd5) +// { +// return password == AuthUtils.Md5ByString(decodePassword); +// } +// return password == decodePassword; +// } + +// public UserInfo Validate(string account, string password, bool isPasswordMd5, out string userName, out string errorMessage) +// { +// userName = string.Empty; +// errorMessage = string.Empty; + +// if (string.IsNullOrEmpty(account)) +// { +// errorMessage = "账号不能为空"; +// return null; +// } +// if (string.IsNullOrEmpty(password)) +// { +// errorMessage = "密码不能为空"; +// return null; +// } + +// var userInfo = GetByAccount(account); + +// if (string.IsNullOrEmpty(userInfo?.UserName)) +// { +// errorMessage = "帐号或密码错误"; +// return null; +// } + +// userName = userInfo.UserName; + +// if (!userInfo.IsChecked) +// { +// errorMessage = "此账号未审核,无法登录"; +// return null; +// } + +// if (userInfo.IsLockedOut) +// { +// errorMessage = "此账号被锁定,无法登录"; +// return null; +// } + +// if (ConfigManager.Instance.IsUserLockLogin) +// { +// if (userInfo.CountOfFailedLogin > 0 && userInfo.CountOfFailedLogin >= ConfigManager.Instance.UserLockLoginCount) +// { +// var lockType = EUserLockTypeUtils.GetEnumType(ConfigManager.Instance.UserLockLoginType); +// if (lockType == EUserLockType.Forever) +// { +// errorMessage = "此账号错误登录次数过多,已被永久锁定"; +// return null; +// } +// if (lockType == EUserLockType.Hours) +// { +// var ts = new TimeSpan(DateTime.Now.Ticks - userInfo.LastActivityDate.Ticks); +// var hours = Convert.ToInt32(ConfigManager.Instance.UserLockLoginHours - ts.TotalHours); +// if (hours > 0) +// { +// errorMessage = +// $"此账号错误登录次数过多,已被锁定,请等待{hours}小时后重试"; +// return null; +// } +// } +// } +// } + +// if (!CheckPassword(password, isPasswordMd5, userInfo.Password, EPasswordFormatUtils.GetEnumType(userInfo.PasswordFormat), userInfo.PasswordSalt)) +// { +// DataProvider.User.UpdateLastActivityDateAndCountOfFailedLogin(userInfo); +// LogUtils.AddUserLog(userInfo.UserName, "用户登录失败", "帐号或密码错误"); +// errorMessage = "帐号或密码错误"; +// return null; +// } + +// return userInfo; +// } + +// public Dictionary GetTrackingDictionary(DateTime dateFrom, DateTime dateTo, string xType) +// { +// var dict = new Dictionary(); +// if (string.IsNullOrEmpty(xType)) +// { +// xType = EStatictisXTypeUtils.GetValueById(EStatictisXType.Day); +// } + +// var builder = new StringBuilder(); +// builder.Append($" AND CreateDate >= {SqlUtils.GetComparableDate(dateFrom)}"); +// builder.Append($" AND CreateDate < {SqlUtils.GetComparableDate(dateTo)}"); + +// string sqlString = $@" +//SELECT COUNT(*) AS AddNum, AddYear, AddMonth, AddDay FROM ( +// SELECT {SqlUtils.GetDatePartYear("CreateDate")} AS AddYear, {SqlUtils.GetDatePartMonth("CreateDate")} AS AddMonth, {SqlUtils.GetDatePartDay("CreateDate")} AS AddDay +// FROM {TableName} +// WHERE {SqlUtils.GetDateDiffLessThanDays("CreateDate", 30.ToString())} {builder} +//) DERIVEDTBL GROUP BY AddYear, AddMonth, AddDay ORDER BY AddYear, AddMonth, AddDay +//";//添加日统计 + +// if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Month)) +// { +// sqlString = $@" +//SELECT COUNT(*) AS AddNum, AddYear, AddMonth FROM ( +// SELECT {SqlUtils.GetDatePartYear("CreateDate")} AS AddYear, {SqlUtils.GetDatePartMonth("CreateDate")} AS AddMonth +// FROM {TableName} +// WHERE {SqlUtils.GetDateDiffLessThanMonths("CreateDate", 12.ToString())} {builder} +//) DERIVEDTBL GROUP BY AddYear, AddMonth ORDER BY AddYear, AddMonth +//";//添加月统计 +// } +// else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Year)) +// { +// sqlString = $@" +//SELECT COUNT(*) AS AddNum, AddYear FROM ( +// SELECT {SqlUtils.GetDatePartYear("CreateDate")} AS AddYear +// FROM {TableName} +// WHERE {SqlUtils.GetDateDiffLessThanYears("CreateDate", 10.ToString())} {builder} +//) DERIVEDTBL GROUP BY AddYear ORDER BY AddYear +//";//添加年统计 +// } + +// using (var rdr = DatabaseApi.ExecuteReader(ConnectionString, sqlString)) +// { +// while (rdr.Read()) +// { +// var accessNum = DatabaseApi.GetInt(rdr, 0); +// if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Day)) +// { +// var year = DatabaseApi.GetString(rdr, 1); +// var month = DatabaseApi.GetString(rdr, 2); +// var day = DatabaseApi.GetString(rdr, 3); +// var dateTime = TranslateUtils.ToDateTime($"{year}-{month}-{day}"); +// dict.Add(dateTime, accessNum); +// } +// else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Month)) +// { +// var year = DatabaseApi.GetString(rdr, 1); +// var month = DatabaseApi.GetString(rdr, 2); + +// var dateTime = TranslateUtils.ToDateTime($"{year}-{month}-1"); +// dict.Add(dateTime, accessNum); +// } +// else if (EStatictisXTypeUtils.Equals(xType, EStatictisXType.Year)) +// { +// var year = DatabaseApi.GetString(rdr, 1); +// var dateTime = TranslateUtils.ToDateTime($"{year}-1-1"); +// dict.Add(dateTime, accessNum); +// } +// } +// rdr.Close(); +// } +// return dict; +// } + +// public int GetCount() +// { +// return DataProvider.DatabaseApi.GetCount(TableName); +// } + +// public List GetUsers(int offset, int limit) +// { +// var list = new List(); +// List dbList; + +// var sqlString = +// SqlDifferences.GetSqlString(TableName, new List +// { +// nameof(UserInfo.Id) +// }, string.Empty, "ORDER BY Id", offset, limit); + +// using (var connection = GetConnection()) +// { +// dbList = connection.Query(sqlString).ToList(); +// } + +// if (dbList.Count > 0) +// { +// foreach (var userId in dbList) +// { +// list.Add(UserManager.GetUserInfoByUserId(userId)); +// } +// } + +// return list; +// } + +// public bool IsExists(int id) +// { +// var sqlString = $"SELECT COUNT(1) FROM {TableName} WHERE Id = @Id"; + +// using (var connection = GetConnection()) +// { +// return connection.ExecuteScalar(sqlString, new { Id = id }); +// } +// } + +// public void DeleteById(UserInfo userInfo) +// { +// var sqlString = $"DELETE FROM {TableName} WHERE Id = @Id"; + +// IDataParameter[] parameters = +// { +// GetParameter(ParamId, userInfo.Id) +// }; + +// DatabaseApi.ExecuteNonQuery(ConnectionString, sqlString, parameters); + +// UserManager.RemoveCache(userInfo); +// } +// } +//} + diff --git a/net452/SiteServer.CMS/Database/RepositoryUtils.cs b/net452/SiteServer.CMS/Database/RepositoryUtils.cs new file mode 100644 index 000000000..7bd9b31ee --- /dev/null +++ b/net452/SiteServer.CMS/Database/RepositoryUtils.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using SiteServer.CMS.Database.Wrapper; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Core +{ + public static class RepositoryUtils + { + //public static List GetTableColumns(Type type) + //{ + // var tableColumns = new List(); + + // foreach (var propertyInfo in ReflectionUtils.GetTypeProperties(type)) + // { + // var attributes = propertyInfo.GetCustomAttributes(true); + + // if (attributes.Any(a => a is ComputedAttribute)) continue; + + // var dataType = DataType.VarChar; + // var dataLength = 0; + // if (propertyInfo.PropertyType == typeof(string)) + // { + // var isText = attributes.Any(a => a is TextAttribute); + // if (isText) + // { + // dataType = DataType.Text; + // } + // else + // { + // dataType = DataType.VarChar; + // var varCharAttribute = (VarCharAttribute)attributes.FirstOrDefault(a => a is VarCharAttribute); + // dataLength = varCharAttribute?.Length ?? 2000; + // } + // } + // else if (propertyInfo.PropertyType == typeof(int)) + // { + // dataType = DataType.Integer; + // } + // else if (propertyInfo.PropertyType == typeof(bool)) + // { + // dataType = DataType.Boolean; + // } + // else if (propertyInfo.PropertyType == typeof(DateTimeOffset) || propertyInfo.PropertyType == typeof(DateTime)) + // { + // dataType = DataType.DateTime; + // } + // else if (propertyInfo.PropertyType == typeof(double) || propertyInfo.PropertyType == typeof(decimal)) + // { + // dataType = DataType.Decimal; + // } + + // var tableColumn = new TableColumn + // { + // AttributeName = propertyInfo.Name, + // DataType = dataType, + // DataLength = dataLength + // }; + + // tableColumns.Add(tableColumn); + // } + + // return tableColumns; + //} + + //private static IDbConnection GetConnection() + //{ + // return SqlDifferences.GetIDbConnection(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString); + //} + + //public static IDictionary ObjToDict(IEntity dataInfo, IList columns, params string[] excludes) + //{ + // var excludesList = excludes != null ? excludes.ToList() : new List(); + // var values = new Dictionary(StringComparer.OrdinalIgnoreCase); + // foreach (var column in columns) + // { + // if (StringUtils.ContainsIgnoreCase(excludesList, column)) continue; + // if (ReflectionUtils.GetValue(dataInfo, column, out var val)) + // { + // values[column] = val; + // } + // } + + // return values; + //} + } +} diff --git a/net452/SiteServer.CMS/Database/SqlMapperExtensions.Async.cs b/net452/SiteServer.CMS/Database/SqlMapperExtensions.Async.cs new file mode 100644 index 000000000..e8ba25c34 --- /dev/null +++ b/net452/SiteServer.CMS/Database/SqlMapperExtensions.Async.cs @@ -0,0 +1,577 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using Dapper; + +namespace SiteServer.CMS.Database.Core +{ + public static partial class SqlMapperExtensions + { + /// + /// Returns a single entity by a single id from table "Ts" asynchronously using .NET 4.5 Task. T must be of interface type. + /// Id must be marked with [Key] attribute. + /// Created entity is tracked/intercepted for changes and used by the Update() extension. + /// + /// Interface type to create and populate + /// Open SqlConnection + /// Id of the entity to get, must be marked with [Key] attribute + /// The transaction to run under, null (the default) if none + /// Number of seconds before command execution timeout + /// Entity of T + public static async Task GetAsync(this IDbConnection connection, dynamic id, IDbTransaction transaction = null, int? commandTimeout = null) where T : class + { + var type = typeof(T); + if (!GetQueries.TryGetValue(type.TypeHandle, out string sql)) + { + var key = GetSingleKey(nameof(GetAsync)); + var name = GetTableName(type); + + sql = $"SELECT * FROM {name} WHERE {key.Name} = @id"; + GetQueries[type.TypeHandle] = sql; + } + + var dynParms = new DynamicParameters(); + dynParms.Add("@id", id); + + if (!type.IsInterface) + return (await connection.QueryAsync(sql, dynParms, transaction, commandTimeout).ConfigureAwait(false)).FirstOrDefault(); + + var res = (await connection.QueryAsync(sql, dynParms).ConfigureAwait(false)).FirstOrDefault() as IDictionary; + + if (res == null) + return null; + + var obj = ProxyGenerator.GetInterfaceProxy(); + + foreach (var property in TypePropertiesCache(type)) + { + var val = res[property.Name]; + if (val == null) continue; + if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + var genericType = Nullable.GetUnderlyingType(property.PropertyType); + if (genericType != null) property.SetValue(obj, Convert.ChangeType(val, genericType), null); + } + else + { + property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null); + } + } + + ((IProxy)obj).IsDirty = false; //reset change tracking and return + + return obj; + } + + /// + /// Returns a list of entites from table "Ts". + /// Id of T must be marked with [Key] attribute. + /// Entities created from interfaces are tracked/intercepted for changes and used by the Update() extension + /// for optimal performance. + /// + /// Interface or type to create and populate + /// Open SqlConnection + /// The transaction to run under, null (the default) if none + /// Number of seconds before command execution timeout + /// Entity of T + public static Task> GetAllAsync(this IDbConnection connection, IDbTransaction transaction = null, int? commandTimeout = null) where T : class + { + var type = typeof(T); + var cacheType = typeof(List); + + if (!GetQueries.TryGetValue(cacheType.TypeHandle, out string sql)) + { + GetSingleKey(nameof(GetAll)); + var name = GetTableName(type); + + sql = "SELECT * FROM " + name; + GetQueries[cacheType.TypeHandle] = sql; + } + + if (!type.IsInterface) + { + return connection.QueryAsync(sql, null, transaction, commandTimeout); + } + return GetAllAsyncImpl(connection, transaction, commandTimeout, sql, type); + } + + private static async Task> GetAllAsyncImpl(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string sql, Type type) where T : class + { + var result = await connection.QueryAsync(sql).ConfigureAwait(false); + var list = new List(); + foreach (IDictionary res in result) + { + var obj = ProxyGenerator.GetInterfaceProxy(); + foreach (var property in TypePropertiesCache(type)) + { + var val = res[property.Name]; + if (val == null) continue; + if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + var genericType = Nullable.GetUnderlyingType(property.PropertyType); + if (genericType != null) property.SetValue(obj, Convert.ChangeType(val, genericType), null); + } + else + { + property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null); + } + } + ((IProxy)obj).IsDirty = false; //reset change tracking and return + list.Add(obj); + } + return list; + } + + /// + /// Inserts an entity into table "Ts" asynchronously using .NET 4.5 Task and returns identity id. + /// + /// The type being inserted. + /// Open SqlConnection + /// Entity to insert + /// The transaction to run under, null (the default) if none + /// Number of seconds before command execution timeout + /// The specific ISqlAdapter to use, auto-detected based on connection if null + /// Identity of inserted entity + public static Task InsertAsync(this IDbConnection connection, T entityToInsert, IDbTransaction transaction = null, + int? commandTimeout = null, ISqlAdapter sqlAdapter = null) where T : class + { + var type = typeof(T); + sqlAdapter = sqlAdapter ?? GetFormatter(connection); + + var isList = false; + if (type.IsArray) + { + isList = true; + type = type.GetElementType(); + } + else if (type.IsGenericType) + { + var typeInfo = type.GetTypeInfo(); + bool implementsGenericIEnumerableOrIsGenericIEnumerable = + typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) || + typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>); + + if (implementsGenericIEnumerableOrIsGenericIEnumerable) + { + isList = true; + type = type.GetGenericArguments()[0]; + } + } + + var name = GetTableName(type); + var sbColumnList = new StringBuilder(null); + var allProperties = TypePropertiesCache(type); + var keyProperties = KeyPropertiesCache(type).ToList(); + var computedProperties = ComputedPropertiesCache(type); + var allPropertiesExceptKeyAndComputed = allProperties.Except(keyProperties.Union(computedProperties)).ToList(); + + for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++) + { + var property = allPropertiesExceptKeyAndComputed[i]; + sqlAdapter.AppendColumnName(sbColumnList, property.Name); + if (i < allPropertiesExceptKeyAndComputed.Count - 1) + sbColumnList.Append(", "); + } + + var sbParameterList = new StringBuilder(null); + for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++) + { + var property = allPropertiesExceptKeyAndComputed[i]; + sbParameterList.AppendFormat("@{0}", property.Name); + if (i < allPropertiesExceptKeyAndComputed.Count - 1) + sbParameterList.Append(", "); + } + + if (!isList) //single entity + { + return sqlAdapter.InsertAsync(connection, transaction, commandTimeout, name, sbColumnList.ToString(), + sbParameterList.ToString(), keyProperties, entityToInsert); + } + + //insert list of entities + var cmd = $"INSERT INTO {name} ({sbColumnList}) values ({sbParameterList})"; + return connection.ExecuteAsync(cmd, entityToInsert, transaction, commandTimeout); + } + + /// + /// Updates entity in table "Ts" asynchronously using .NET 4.5 Task, checks if the entity is modified if the entity is tracked by the Get() extension. + /// + /// Type to be updated + /// Open SqlConnection + /// Entity to be updated + /// The transaction to run under, null (the default) if none + /// Number of seconds before command execution timeout + /// true if updated, false if not found or not modified (tracked entities) + public static async Task UpdateAsync(this IDbConnection connection, T entityToUpdate, IDbTransaction transaction = null, int? commandTimeout = null) where T : class + { + if ((entityToUpdate is IProxy proxy) && !proxy.IsDirty) + { + return false; + } + + var type = typeof(T); + + if (type.IsArray) + { + type = type.GetElementType(); + } + else if (type.IsGenericType) + { + var typeInfo = type.GetTypeInfo(); + bool implementsGenericIEnumerableOrIsGenericIEnumerable = + typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) || + typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>); + + if (implementsGenericIEnumerableOrIsGenericIEnumerable) + { + type = type.GetGenericArguments()[0]; + } + } + + var keyProperties = KeyPropertiesCache(type).ToList(); + var explicitKeyProperties = ExplicitKeyPropertiesCache(type); + if (keyProperties.Count == 0 && explicitKeyProperties.Count == 0) + throw new ArgumentException("Entity must have at least one [Key] or [ExplicitKey] property"); + + var name = GetTableName(type); + + var sb = new StringBuilder(); + sb.AppendFormat("update {0} set ", name); + + var allProperties = TypePropertiesCache(type); + keyProperties.AddRange(explicitKeyProperties); + var computedProperties = ComputedPropertiesCache(type); + var nonIdProps = allProperties.Except(keyProperties.Union(computedProperties)).ToList(); + + var adapter = GetFormatter(connection); + + for (var i = 0; i < nonIdProps.Count; i++) + { + var property = nonIdProps[i]; + adapter.AppendColumnNameEqualsValue(sb, property.Name); + if (i < nonIdProps.Count - 1) + sb.Append(", "); + } + sb.Append(" where "); + for (var i = 0; i < keyProperties.Count; i++) + { + var property = keyProperties[i]; + adapter.AppendColumnNameEqualsValue(sb, property.Name); + if (i < keyProperties.Count - 1) + sb.Append(" and "); + } + var updated = await connection.ExecuteAsync(sb.ToString(), entityToUpdate, commandTimeout: commandTimeout, transaction: transaction).ConfigureAwait(false); + return updated > 0; + } + + /// + /// Delete entity in table "Ts" asynchronously using .NET 4.5 Task. + /// + /// Type of entity + /// Open SqlConnection + /// Entity to delete + /// The transaction to run under, null (the default) if none + /// Number of seconds before command execution timeout + /// true if deleted, false if not found + public static async Task DeleteAsync(this IDbConnection connection, T entityToDelete, IDbTransaction transaction = null, int? commandTimeout = null) where T : class + { + if (entityToDelete == null) + throw new ArgumentException("Cannot Delete null Object", nameof(entityToDelete)); + + var type = typeof(T); + + if (type.IsArray) + { + type = type.GetElementType(); + } + else if (type.IsGenericType) + { + var typeInfo = type.GetTypeInfo(); + bool implementsGenericIEnumerableOrIsGenericIEnumerable = + typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) || + typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>); + + if (implementsGenericIEnumerableOrIsGenericIEnumerable) + { + type = type.GetGenericArguments()[0]; + } + } + + var keyProperties = KeyPropertiesCache(type); + var explicitKeyProperties = ExplicitKeyPropertiesCache(type); + if (keyProperties.Count == 0 && explicitKeyProperties.Count == 0) + throw new ArgumentException("Entity must have at least one [Key] or [ExplicitKey] property"); + + var name = GetTableName(type); + keyProperties.AddRange(explicitKeyProperties); + + var sb = new StringBuilder(); + sb.AppendFormat("DELETE FROM {0} WHERE ", name); + + var adapter = GetFormatter(connection); + + for (var i = 0; i < keyProperties.Count; i++) + { + var property = keyProperties[i]; + adapter.AppendColumnNameEqualsValue(sb, property.Name); + if (i < keyProperties.Count - 1) + sb.Append(" AND "); + } + var deleted = await connection.ExecuteAsync(sb.ToString(), entityToDelete, transaction, commandTimeout).ConfigureAwait(false); + return deleted > 0; + } + + /// + /// Delete all entities in the table related to the type T asynchronously using .NET 4.5 Task. + /// + /// Type of entity + /// Open SqlConnection + /// The transaction to run under, null (the default) if none + /// Number of seconds before command execution timeout + /// true if deleted, false if none found + public static async Task DeleteAllAsync(this IDbConnection connection, IDbTransaction transaction = null, int? commandTimeout = null) where T : class + { + var type = typeof(T); + var statement = "DELETE FROM " + GetTableName(type); + var deleted = await connection.ExecuteAsync(statement, null, transaction, commandTimeout).ConfigureAwait(false); + return deleted > 0; + } + } +} + +public partial interface ISqlAdapter +{ + /// + /// Inserts into the database, returning the Id of the row created. + /// + /// The connection to use. + /// The transaction to use. + /// The command timeout to use. + /// The table to insert into. + /// The columns to set with this insert. + /// The parameters to set for this insert. + /// The key columns in this table. + /// The entity to insert. + /// The Id of the row created. + Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert); +} + +public partial class SqlServerAdapter +{ + /// + /// Inserts into the database, returning the Id of the row created. + /// + /// The connection to use. + /// The transaction to use. + /// The command timeout to use. + /// The table to insert into. + /// The columns to set with this insert. + /// The parameters to set for this insert. + /// The key columns in this table. + /// The entity to insert. + /// The Id of the row created. + public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert) + { + var cmd = $"INSERT INTO {tableName} ({columnList}) values ({parameterList}); SELECT SCOPE_IDENTITY() id"; + var multi = await connection.QueryMultipleAsync(cmd, entityToInsert, transaction, commandTimeout).ConfigureAwait(false); + + var first = multi.Read().FirstOrDefault(); + if (first == null || first.id == null) return 0; + + var id = (int)first.id; + var pi = keyProperties as PropertyInfo[] ?? keyProperties.ToArray(); + if (pi.Length == 0) return id; + + var idp = pi[0]; + idp.SetValue(entityToInsert, Convert.ChangeType(id, idp.PropertyType), null); + + return id; + } +} + +public partial class SqlCeServerAdapter +{ + /// + /// Inserts into the database, returning the Id of the row created. + /// + /// The connection to use. + /// The transaction to use. + /// The command timeout to use. + /// The table to insert into. + /// The columns to set with this insert. + /// The parameters to set for this insert. + /// The key columns in this table. + /// The entity to insert. + /// The Id of the row created. + public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert) + { + var cmd = $"INSERT INTO {tableName} ({columnList}) VALUES ({parameterList})"; + await connection.ExecuteAsync(cmd, entityToInsert, transaction, commandTimeout).ConfigureAwait(false); + var r = (await connection.QueryAsync("SELECT @@IDENTITY id", transaction: transaction, commandTimeout: commandTimeout).ConfigureAwait(false)).ToList(); + + if (r[0] == null || r[0].id == null) return 0; + var id = (int)r[0].id; + + var pi = keyProperties as PropertyInfo[] ?? keyProperties.ToArray(); + if (pi.Length == 0) return id; + + var idp = pi[0]; + idp.SetValue(entityToInsert, Convert.ChangeType(id, idp.PropertyType), null); + + return id; + } +} + +public partial class MySqlAdapter +{ + /// + /// Inserts into the database, returning the Id of the row created. + /// + /// The connection to use. + /// The transaction to use. + /// The command timeout to use. + /// The table to insert into. + /// The columns to set with this insert. + /// The parameters to set for this insert. + /// The key columns in this table. + /// The entity to insert. + /// The Id of the row created. + public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, + string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert) + { + var cmd = $"INSERT INTO {tableName} ({columnList}) VALUES ({parameterList})"; + await connection.ExecuteAsync(cmd, entityToInsert, transaction, commandTimeout).ConfigureAwait(false); + var r = await connection.QueryAsync("SELECT LAST_INSERT_ID() id", transaction: transaction, commandTimeout: commandTimeout).ConfigureAwait(false); + + var id = r.First().id; + if (id == null) return 0; + var pi = keyProperties as PropertyInfo[] ?? keyProperties.ToArray(); + if (pi.Length == 0) return Convert.ToInt32(id); + + var idp = pi[0]; + idp.SetValue(entityToInsert, Convert.ChangeType(id, idp.PropertyType), null); + + return Convert.ToInt32(id); + } +} + +public partial class PostgresAdapter +{ + /// + /// Inserts into the database, returning the Id of the row created. + /// + /// The connection to use. + /// The transaction to use. + /// The command timeout to use. + /// The table to insert into. + /// The columns to set with this insert. + /// The parameters to set for this insert. + /// The key columns in this table. + /// The entity to insert. + /// The Id of the row created. + public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert) + { + var sb = new StringBuilder(); + sb.AppendFormat("INSERT INTO {0} ({1}) VALUES ({2})", tableName, columnList, parameterList); + + // If no primary key then safe to assume a join table with not too much data to return + var propertyInfos = keyProperties as PropertyInfo[] ?? keyProperties.ToArray(); + if (propertyInfos.Length == 0) + { + sb.Append(" RETURNING *"); + } + else + { + sb.Append(" RETURNING "); + bool first = true; + foreach (var property in propertyInfos) + { + if (!first) + sb.Append(", "); + first = false; + sb.Append(property.Name); + } + } + + var results = await connection.QueryAsync(sb.ToString(), entityToInsert, transaction, commandTimeout).ConfigureAwait(false); + + // Return the key by assinging the corresponding property in the object - by product is that it supports compound primary keys + var id = 0; + foreach (var p in propertyInfos) + { + var value = ((IDictionary)results.First())[p.Name.ToLower()]; + p.SetValue(entityToInsert, value, null); + if (id == 0) + id = Convert.ToInt32(value); + } + return id; + } +} + +public partial class SQLiteAdapter +{ + /// + /// Inserts into the database, returning the Id of the row created. + /// + /// The connection to use. + /// The transaction to use. + /// The command timeout to use. + /// The table to insert into. + /// The columns to set with this insert. + /// The parameters to set for this insert. + /// The key columns in this table. + /// The entity to insert. + /// The Id of the row created. + public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert) + { + var cmd = $"INSERT INTO {tableName} ({columnList}) VALUES ({parameterList}); SELECT last_insert_rowid() id"; + var multi = await connection.QueryMultipleAsync(cmd, entityToInsert, transaction, commandTimeout).ConfigureAwait(false); + + var id = (int)multi.Read().First().id; + var pi = keyProperties as PropertyInfo[] ?? keyProperties.ToArray(); + if (pi.Length == 0) return id; + + var idp = pi[0]; + idp.SetValue(entityToInsert, Convert.ChangeType(id, idp.PropertyType), null); + + return id; + } +} + +public partial class FbAdapter +{ + /// + /// Inserts into the database, returning the Id of the row created. + /// + /// The connection to use. + /// The transaction to use. + /// The command timeout to use. + /// The table to insert into. + /// The columns to set with this insert. + /// The parameters to set for this insert. + /// The key columns in this table. + /// The entity to insert. + /// The Id of the row created. + public async Task InsertAsync(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, object entityToInsert) + { + var cmd = $"insert into {tableName} ({columnList}) values ({parameterList})"; + await connection.ExecuteAsync(cmd, entityToInsert, transaction, commandTimeout).ConfigureAwait(false); + + var propertyInfos = keyProperties as PropertyInfo[] ?? keyProperties.ToArray(); + var keyName = propertyInfos[0].Name; + var r = await connection.QueryAsync($"SELECT FIRST 1 {keyName} ID FROM {tableName} ORDER BY {keyName} DESC", transaction: transaction, commandTimeout: commandTimeout).ConfigureAwait(false); + + var id = r.First().ID; + if (id == null) return 0; + if (propertyInfos.Length == 0) return Convert.ToInt32(id); + + var idp = propertyInfos[0]; + idp.SetValue(entityToInsert, Convert.ChangeType(id, idp.PropertyType), null); + + return Convert.ToInt32(id); + } +} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Database/SqlMapperExtensions.cs b/net452/SiteServer.CMS/Database/SqlMapperExtensions.cs new file mode 100644 index 000000000..7b3b106a6 --- /dev/null +++ b/net452/SiteServer.CMS/Database/SqlMapperExtensions.cs @@ -0,0 +1,1173 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Linq; +using System.Reflection; +using System.Text; +using System.Collections.Concurrent; +using System.Reflection.Emit; + +using Dapper; +using SiteServer.Utils; +#if NETSTANDARD1_3 +using DataException = System.InvalidOperationException; +#else +using System.Threading; +#endif + +namespace SiteServer.CMS.Database.Core +{ + /// + /// The Dapper.Contrib extensions for Dapper + /// + public static partial class SqlMapperExtensions + { + /// + /// Defined a proxy object with a possibly dirty state. + /// + public interface IProxy //must be kept public + { + /// + /// Whether the object has been changed. + /// + bool IsDirty { get; set; } + } + + /// + /// Defines a table name mapper for getting table names from types. + /// + public interface ITableNameMapper + { + /// + /// Gets a table name from a given . + /// + /// The to get a name from. + /// The table name for the given . + string GetTableName(Type type); + } + + /// + /// The function to get a database type from the given . + /// + /// The connection to get a database type name from. + public delegate string GetDatabaseTypeDelegate(IDbConnection connection); + /// + /// The function to get a a table name from a given + /// + /// The to get a table name for. + public delegate string TableNameMapperDelegate(Type type); + + private static readonly ConcurrentDictionary> KeyProperties = new ConcurrentDictionary>(); + private static readonly ConcurrentDictionary> ExplicitKeyProperties = new ConcurrentDictionary>(); + private static readonly ConcurrentDictionary> TypeProperties = new ConcurrentDictionary>(); + private static readonly ConcurrentDictionary> ComputedProperties = new ConcurrentDictionary>(); + private static readonly ConcurrentDictionary GetQueries = new ConcurrentDictionary(); + private static readonly ConcurrentDictionary TypeTableName = new ConcurrentDictionary(); + + private static readonly ISqlAdapter DefaultAdapter = new SqlServerAdapter(); + private static readonly Dictionary AdapterDictionary + = new Dictionary + { + ["sqlconnection"] = new SqlServerAdapter(), + ["sqlceconnection"] = new SqlCeServerAdapter(), + ["npgsqlconnection"] = new PostgresAdapter(), + ["sqliteconnection"] = new SQLiteAdapter(), + ["mysqlconnection"] = new MySqlAdapter(), + ["fbconnection"] = new FbAdapter() + }; + + private static List ComputedPropertiesCache(Type type) + { + if (ComputedProperties.TryGetValue(type.TypeHandle, out IEnumerable pi)) + { + return pi.ToList(); + } + + var computedProperties = TypePropertiesCache(type).Where(p => p.GetCustomAttributes(true).Any(a => a is ComputedAttribute)).ToList(); + + ComputedProperties[type.TypeHandle] = computedProperties; + return computedProperties; + } + + private static List ExplicitKeyPropertiesCache(Type type) + { + if (ExplicitKeyProperties.TryGetValue(type.TypeHandle, out IEnumerable pi)) + { + return pi.ToList(); + } + + var explicitKeyProperties = TypePropertiesCache(type).Where(p => p.GetCustomAttributes(true).Any(a => a is ExplicitKeyAttribute)).ToList(); + + ExplicitKeyProperties[type.TypeHandle] = explicitKeyProperties; + return explicitKeyProperties; + } + + private static List KeyPropertiesCache(Type type) + { + if (KeyProperties.TryGetValue(type.TypeHandle, out IEnumerable pi)) + { + return pi.ToList(); + } + + var allProperties = TypePropertiesCache(type); + var keyProperties = allProperties.Where(p => p.GetCustomAttributes(true).Any(a => a is KeyAttribute)).ToList(); + + if (keyProperties.Count == 0) + { + var idProp = allProperties.Find(p => string.Equals(p.Name, "id", StringComparison.CurrentCultureIgnoreCase)); + if (idProp != null && !idProp.GetCustomAttributes(true).Any(a => a is ExplicitKeyAttribute)) + { + keyProperties.Add(idProp); + } + } + + KeyProperties[type.TypeHandle] = keyProperties; + return keyProperties; + } + + private static List TypePropertiesCache(Type type) + { + if (TypeProperties.TryGetValue(type.TypeHandle, out IEnumerable pis)) + { + return pis.ToList(); + } + + //changed + //var properties = type.GetProperties().Where(IsWriteable).ToArray(); + var properties = ReflectionUtils.GetAllInstancePropertyInfos(type).Where(IsWriteable).ToArray(); + + TypeProperties[type.TypeHandle] = properties; + return properties.ToList(); + } + + private static bool IsWriteable(PropertyInfo pi) + { + var attributes = pi.GetCustomAttributes(typeof(WriteAttribute), false).AsList(); + if (attributes.Count != 1) return true; + + var writeAttribute = (WriteAttribute)attributes[0]; + return writeAttribute.Write; + } + + private static PropertyInfo GetSingleKey(string method) + { + var type = typeof(T); + var keys = KeyPropertiesCache(type); + var explicitKeys = ExplicitKeyPropertiesCache(type); + var keyCount = keys.Count + explicitKeys.Count; + if (keyCount > 1) + throw new DataException($"{method} only supports an entity with a single [Key] or [ExplicitKey] property. [Key] Count: {keys.Count}, [ExplicitKey] Count: {explicitKeys.Count}"); + if (keyCount == 0) + throw new DataException($"{method} only supports an entity with a [Key] or an [ExplicitKey] property"); + + return keys.Count > 0 ? keys[0] : explicitKeys[0]; + } + + /// + /// Returns a single entity by a single id from table "Ts". + /// Id must be marked with [Key] attribute. + /// Entities created from interfaces are tracked/intercepted for changes and used by the Update() extension + /// for optimal performance. + /// + /// Interface or type to create and populate + /// Open SqlConnection + /// Id of the entity to get, must be marked with [Key] attribute + /// The transaction to run under, null (the default) if none + /// Number of seconds before command execution timeout + /// Entity of T + public static T Get(this IDbConnection connection, dynamic id, IDbTransaction transaction = null, int? commandTimeout = null) where T : class + { + var type = typeof(T); + + if (!GetQueries.TryGetValue(type.TypeHandle, out string sql)) + { + var key = GetSingleKey(nameof(Get)); + var name = GetTableName(type); + + sql = $"select * from {name} where {key.Name} = @id"; + GetQueries[type.TypeHandle] = sql; + } + + var dynParms = new DynamicParameters(); + dynParms.Add("@id", id); + + T obj; + + if (type.IsInterface) + { + var res = connection.Query(sql, dynParms).FirstOrDefault() as IDictionary; + + if (res == null) + return null; + + obj = ProxyGenerator.GetInterfaceProxy(); + + foreach (var property in TypePropertiesCache(type)) + { + var val = res[property.Name]; + if (val == null) continue; + if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + var genericType = Nullable.GetUnderlyingType(property.PropertyType); + if (genericType != null) property.SetValue(obj, Convert.ChangeType(val, genericType), null); + } + else + { + property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null); + } + } + + ((IProxy)obj).IsDirty = false; //reset change tracking and return + } + else + { + obj = connection.Query(sql, dynParms, transaction, commandTimeout: commandTimeout).FirstOrDefault(); + } + return obj; + } + + /// + /// Returns a list of entites from table "Ts". + /// Id of T must be marked with [Key] attribute. + /// Entities created from interfaces are tracked/intercepted for changes and used by the Update() extension + /// for optimal performance. + /// + /// Interface or type to create and populate + /// Open SqlConnection + /// The transaction to run under, null (the default) if none + /// Number of seconds before command execution timeout + /// Entity of T + public static IEnumerable GetAll(this IDbConnection connection, IDbTransaction transaction = null, int? commandTimeout = null) where T : class + { + var type = typeof(T); + var cacheType = typeof(List); + + if (!GetQueries.TryGetValue(cacheType.TypeHandle, out string sql)) + { + GetSingleKey(nameof(GetAll)); + var name = GetTableName(type); + + sql = "select * from " + name; + GetQueries[cacheType.TypeHandle] = sql; + } + + if (!type.IsInterface) return connection.Query(sql, null, transaction, commandTimeout: commandTimeout); + + var result = connection.Query(sql); + var list = new List(); + foreach (IDictionary res in result) + { + var obj = ProxyGenerator.GetInterfaceProxy(); + foreach (var property in TypePropertiesCache(type)) + { + var val = res[property.Name]; + if (val == null) continue; + if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)) + { + var genericType = Nullable.GetUnderlyingType(property.PropertyType); + if (genericType != null) property.SetValue(obj, Convert.ChangeType(val, genericType), null); + } + else + { + property.SetValue(obj, Convert.ChangeType(val, property.PropertyType), null); + } + } + ((IProxy)obj).IsDirty = false; //reset change tracking and return + list.Add(obj); + } + return list; + } + + /// + /// Specify a custom table name mapper based on the POCO type name + /// + public static TableNameMapperDelegate TableNameMapper; + + private static string GetTableName(Type type) + { + if (TypeTableName.TryGetValue(type.TypeHandle, out string name)) return name; + + if (TableNameMapper != null) + { + name = TableNameMapper(type); + } + else + { +#if NETSTANDARD1_3 + var info = type.GetTypeInfo(); +#else + var info = type; +#endif + //NOTE: This as dynamic trick falls back to handle both our own Table-attribute as well as the one in EntityFramework + var tableAttrName = + info.GetCustomAttribute(false)?.Name + ?? (info.GetCustomAttributes(false).FirstOrDefault(attr => attr.GetType().Name == "TableAttribute") as dynamic)?.Name; + + if (tableAttrName != null) + { + name = tableAttrName; + } + else + { + name = type.Name + "s"; + if (type.IsInterface && name.StartsWith("I")) + name = name.Substring(1); + } + } + + TypeTableName[type.TypeHandle] = name; + return name; + } + + /// + /// Inserts an entity into table "Ts" and returns identity id or number of inserted rows if inserting a list. + /// + /// The type to insert. + /// Open SqlConnection + /// Entity to insert, can be list of entities + /// The transaction to run under, null (the default) if none + /// Number of seconds before command execution timeout + /// Identity of inserted entity, or number of inserted rows if inserting a list + public static long Insert(this IDbConnection connection, T entityToInsert, IDbTransaction transaction = null, int? commandTimeout = null) where T : class + { + var isList = false; + + var type = typeof(T); + + if (type.IsArray) + { + isList = true; + type = type.GetElementType(); + } + else if (type.IsGenericType) + { + var typeInfo = type.GetTypeInfo(); + bool implementsGenericIEnumerableOrIsGenericIEnumerable = + typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) || + typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>); + + if (implementsGenericIEnumerableOrIsGenericIEnumerable) + { + isList = true; + type = type.GetGenericArguments()[0]; + } + } + + var name = GetTableName(type); + var sbColumnList = new StringBuilder(null); + var allProperties = TypePropertiesCache(type); + var keyProperties = KeyPropertiesCache(type); + var computedProperties = ComputedPropertiesCache(type); + var allPropertiesExceptKeyAndComputed = allProperties.Except(keyProperties.Union(computedProperties)).ToList(); + + var adapter = GetFormatter(connection); + + for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++) + { + var property = allPropertiesExceptKeyAndComputed[i]; + adapter.AppendColumnName(sbColumnList, property.Name); //fix for issue #336 + if (i < allPropertiesExceptKeyAndComputed.Count - 1) + sbColumnList.Append(", "); + } + + var sbParameterList = new StringBuilder(null); + for (var i = 0; i < allPropertiesExceptKeyAndComputed.Count; i++) + { + var property = allPropertiesExceptKeyAndComputed[i]; + sbParameterList.AppendFormat("@{0}", property.Name); + if (i < allPropertiesExceptKeyAndComputed.Count - 1) + sbParameterList.Append(", "); + } + + var dbParameters = new DynamicParameters(); + foreach (var property in allPropertiesExceptKeyAndComputed) + { + var value = ReflectionUtils.GetValue(entityToInsert, property.Name); + dbParameters.Add(property.Name, value); + } + + int returnVal; + var wasClosed = connection.State == ConnectionState.Closed; + if (wasClosed) connection.Open(); + + if (!isList) //single entity + { + returnVal = adapter.Insert(connection, transaction, commandTimeout, name, sbColumnList.ToString(), + sbParameterList.ToString(), keyProperties, dbParameters); + } + else + { + //insert list of entities + var cmd = $"insert into {name} ({sbColumnList}) values ({sbParameterList})"; + returnVal = connection.Execute(cmd, dbParameters, transaction, commandTimeout); + } + if (wasClosed) connection.Close(); + return returnVal; + } + + /// + /// Updates entity in table "Ts", checks if the entity is modified if the entity is tracked by the Get() extension. + /// + /// Type to be updated + /// Open SqlConnection + /// Entity to be updated + /// The transaction to run under, null (the default) if none + /// Number of seconds before command execution timeout + /// true if updated, false if not found or not modified (tracked entities) + public static bool Update(this IDbConnection connection, T entityToUpdate, IDbTransaction transaction = null, int? commandTimeout = null) where T : class + { + if (entityToUpdate is IProxy proxy && !proxy.IsDirty) + { + return false; + } + + var type = typeof(T); + + if (type.IsArray) + { + type = type.GetElementType(); + } + else if (type.IsGenericType) + { + var typeInfo = type.GetTypeInfo(); + bool implementsGenericIEnumerableOrIsGenericIEnumerable = + typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) || + typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>); + + if (implementsGenericIEnumerableOrIsGenericIEnumerable) + { + type = type.GetGenericArguments()[0]; + } + } + + var keyProperties = KeyPropertiesCache(type).ToList(); //added ToList() due to issue #418, must work on a list copy + var explicitKeyProperties = ExplicitKeyPropertiesCache(type); + if (keyProperties.Count == 0 && explicitKeyProperties.Count == 0) + throw new ArgumentException("Entity must have at least one [Key] or [ExplicitKey] property"); + + var name = GetTableName(type); + + var sb = new StringBuilder(); + sb.AppendFormat("update {0} set ", name); + + var allProperties = TypePropertiesCache(type); + keyProperties.AddRange(explicitKeyProperties); + var computedProperties = ComputedPropertiesCache(type); + var nonIdProps = allProperties.Except(keyProperties.Union(computedProperties)).ToList(); + + var adapter = GetFormatter(connection); + + for (var i = 0; i < nonIdProps.Count; i++) + { + var property = nonIdProps[i]; + adapter.AppendColumnNameEqualsValue(sb, property.Name); //fix for issue #336 + if (i < nonIdProps.Count - 1) + sb.Append(", "); + } + sb.Append(" where "); + for (var i = 0; i < keyProperties.Count; i++) + { + var property = keyProperties[i]; + adapter.AppendColumnNameEqualsValue(sb, property.Name); //fix for issue #336 + if (i < keyProperties.Count - 1) + sb.Append(" and "); + } + var updated = connection.Execute(sb.ToString(), entityToUpdate, commandTimeout: commandTimeout, transaction: transaction); + return updated > 0; + } + + /// + /// Delete entity in table "Ts". + /// + /// Type of entity + /// Open SqlConnection + /// Entity to delete + /// The transaction to run under, null (the default) if none + /// Number of seconds before command execution timeout + /// true if deleted, false if not found + public static bool Delete(this IDbConnection connection, T entityToDelete, IDbTransaction transaction = null, int? commandTimeout = null) where T : class + { + if (entityToDelete == null) + throw new ArgumentException("Cannot Delete null Object", nameof(entityToDelete)); + + var type = typeof(T); + + if (type.IsArray) + { + type = type.GetElementType(); + } + else if (type.IsGenericType) + { + var typeInfo = type.GetTypeInfo(); + bool implementsGenericIEnumerableOrIsGenericIEnumerable = + typeInfo.ImplementedInterfaces.Any(ti => ti.IsGenericType && ti.GetGenericTypeDefinition() == typeof(IEnumerable<>)) || + typeInfo.GetGenericTypeDefinition() == typeof(IEnumerable<>); + + if (implementsGenericIEnumerableOrIsGenericIEnumerable) + { + type = type.GetGenericArguments()[0]; + } + } + + var keyProperties = KeyPropertiesCache(type).ToList(); //added ToList() due to issue #418, must work on a list copy + var explicitKeyProperties = ExplicitKeyPropertiesCache(type); + if (keyProperties.Count == 0 && explicitKeyProperties.Count == 0) + throw new ArgumentException("Entity must have at least one [Key] or [ExplicitKey] property"); + + var name = GetTableName(type); + keyProperties.AddRange(explicitKeyProperties); + + var sb = new StringBuilder(); + sb.AppendFormat("delete from {0} where ", name); + + var adapter = GetFormatter(connection); + + for (var i = 0; i < keyProperties.Count; i++) + { + var property = keyProperties[i]; + adapter.AppendColumnNameEqualsValue(sb, property.Name); //fix for issue #336 + if (i < keyProperties.Count - 1) + sb.Append(" and "); + } + var deleted = connection.Execute(sb.ToString(), entityToDelete, transaction, commandTimeout); + return deleted > 0; + } + + /// + /// Delete all entities in the table related to the type T. + /// + /// Type of entity + /// Open SqlConnection + /// The transaction to run under, null (the default) if none + /// Number of seconds before command execution timeout + /// true if deleted, false if none found + public static bool DeleteAll(this IDbConnection connection, IDbTransaction transaction = null, int? commandTimeout = null) where T : class + { + var type = typeof(T); + var name = GetTableName(type); + var statement = $"delete from {name}"; + var deleted = connection.Execute(statement, null, transaction, commandTimeout); + return deleted > 0; + } + + /// + /// Specifies a custom callback that detects the database type instead of relying on the default strategy (the name of the connection type object). + /// Please note that this callback is global and will be used by all the calls that require a database specific adapter. + /// + public static GetDatabaseTypeDelegate GetDatabaseType; + + private static ISqlAdapter GetFormatter(IDbConnection connection) + { + var name = GetDatabaseType?.Invoke(connection).ToLower() + ?? connection.GetType().Name.ToLower(); + + return !AdapterDictionary.ContainsKey(name) + ? DefaultAdapter + : AdapterDictionary[name]; + } + + private static class ProxyGenerator + { + private static readonly Dictionary TypeCache = new Dictionary(); + + private static AssemblyBuilder GetAsmBuilder(string name) + { +#if NETSTANDARD1_3 || NETSTANDARD2_0 + return AssemblyBuilder.DefineDynamicAssembly(new AssemblyName { Name = name }, AssemblyBuilderAccess.Run); +#else + return Thread.GetDomain().DefineDynamicAssembly(new AssemblyName { Name = name }, AssemblyBuilderAccess.Run); +#endif + } + + public static T GetInterfaceProxy() + { + Type typeOfT = typeof(T); + + if (TypeCache.TryGetValue(typeOfT, out Type k)) + { + return (T)Activator.CreateInstance(k); + } + var assemblyBuilder = GetAsmBuilder(typeOfT.Name); + + var moduleBuilder = assemblyBuilder.DefineDynamicModule("SqlMapperExtensions." + typeOfT.Name); //NOTE: to save, add "asdasd.dll" parameter + + var interfaceType = typeof(IProxy); + var typeBuilder = moduleBuilder.DefineType(typeOfT.Name + "_" + Guid.NewGuid(), + TypeAttributes.Public | TypeAttributes.Class); + typeBuilder.AddInterfaceImplementation(typeOfT); + typeBuilder.AddInterfaceImplementation(interfaceType); + + //create our _isDirty field, which implements IProxy + var setIsDirtyMethod = CreateIsDirtyProperty(typeBuilder); + + // Generate a field for each property, which implements the T + //changed + //foreach (var property in typeof(T).GetProperties()) + foreach (var property in ReflectionUtils.GetAllInstancePropertyInfos(typeof(T))) + { + var isId = property.GetCustomAttributes(true).Any(a => a is KeyAttribute); + CreateProperty(typeBuilder, property.Name, property.PropertyType, setIsDirtyMethod, isId); + } + +#if NETSTANDARD1_3 || NETSTANDARD2_0 + var generatedType = typeBuilder.CreateTypeInfo().AsType(); +#else + var generatedType = typeBuilder.CreateType(); +#endif + + TypeCache.Add(typeOfT, generatedType); + return (T)Activator.CreateInstance(generatedType); + } + + private static MethodInfo CreateIsDirtyProperty(TypeBuilder typeBuilder) + { + var propType = typeof(bool); + var field = typeBuilder.DefineField("_" + nameof(IProxy.IsDirty), propType, FieldAttributes.Private); + var property = typeBuilder.DefineProperty(nameof(IProxy.IsDirty), + System.Reflection.PropertyAttributes.None, + propType, + new[] { propType }); + + const MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.NewSlot | MethodAttributes.SpecialName + | MethodAttributes.Final | MethodAttributes.Virtual | MethodAttributes.HideBySig; + + // Define the "get" and "set" accessor methods + var currGetPropMthdBldr = typeBuilder.DefineMethod("get_" + nameof(IProxy.IsDirty), + getSetAttr, + propType, + Type.EmptyTypes); + var currGetIl = currGetPropMthdBldr.GetILGenerator(); + currGetIl.Emit(OpCodes.Ldarg_0); + currGetIl.Emit(OpCodes.Ldfld, field); + currGetIl.Emit(OpCodes.Ret); + var currSetPropMthdBldr = typeBuilder.DefineMethod("set_" + nameof(IProxy.IsDirty), + getSetAttr, + null, + new[] { propType }); + var currSetIl = currSetPropMthdBldr.GetILGenerator(); + currSetIl.Emit(OpCodes.Ldarg_0); + currSetIl.Emit(OpCodes.Ldarg_1); + currSetIl.Emit(OpCodes.Stfld, field); + currSetIl.Emit(OpCodes.Ret); + + property.SetGetMethod(currGetPropMthdBldr); + property.SetSetMethod(currSetPropMthdBldr); + var getMethod = typeof(IProxy).GetMethod("get_" + nameof(IProxy.IsDirty)); + var setMethod = typeof(IProxy).GetMethod("set_" + nameof(IProxy.IsDirty)); + typeBuilder.DefineMethodOverride(currGetPropMthdBldr, getMethod); + typeBuilder.DefineMethodOverride(currSetPropMthdBldr, setMethod); + + return currSetPropMthdBldr; + } + + private static void CreateProperty(TypeBuilder typeBuilder, string propertyName, Type propType, MethodInfo setIsDirtyMethod, bool isIdentity) + { + //Define the field and the property + var field = typeBuilder.DefineField("_" + propertyName, propType, FieldAttributes.Private); + var property = typeBuilder.DefineProperty(propertyName, + System.Reflection.PropertyAttributes.None, + propType, + new[] { propType }); + + const MethodAttributes getSetAttr = MethodAttributes.Public + | MethodAttributes.Virtual + | MethodAttributes.HideBySig; + + // Define the "get" and "set" accessor methods + var currGetPropMthdBldr = typeBuilder.DefineMethod("get_" + propertyName, + getSetAttr, + propType, + Type.EmptyTypes); + + var currGetIl = currGetPropMthdBldr.GetILGenerator(); + currGetIl.Emit(OpCodes.Ldarg_0); + currGetIl.Emit(OpCodes.Ldfld, field); + currGetIl.Emit(OpCodes.Ret); + + var currSetPropMthdBldr = typeBuilder.DefineMethod("set_" + propertyName, + getSetAttr, + null, + new[] { propType }); + + //store value in private field and set the isdirty flag + var currSetIl = currSetPropMthdBldr.GetILGenerator(); + currSetIl.Emit(OpCodes.Ldarg_0); + currSetIl.Emit(OpCodes.Ldarg_1); + currSetIl.Emit(OpCodes.Stfld, field); + currSetIl.Emit(OpCodes.Ldarg_0); + currSetIl.Emit(OpCodes.Ldc_I4_1); + currSetIl.Emit(OpCodes.Call, setIsDirtyMethod); + currSetIl.Emit(OpCodes.Ret); + + //TODO: Should copy all attributes defined by the interface? + if (isIdentity) + { + var keyAttribute = typeof(KeyAttribute); + var myConstructorInfo = keyAttribute.GetConstructor(new Type[] { }); + var attributeBuilder = new CustomAttributeBuilder(myConstructorInfo, new object[] { }); + property.SetCustomAttribute(attributeBuilder); + } + + property.SetGetMethod(currGetPropMthdBldr); + property.SetSetMethod(currSetPropMthdBldr); + var getMethod = typeof(T).GetMethod("get_" + propertyName); + var setMethod = typeof(T).GetMethod("set_" + propertyName); + typeBuilder.DefineMethodOverride(currGetPropMthdBldr, getMethod); + typeBuilder.DefineMethodOverride(currSetPropMthdBldr, setMethod); + } + } + } + + /// + /// Defines the name of a table to use in Dapper.Contrib commands. + /// + [AttributeUsage(AttributeTargets.Class)] + public class TableAttribute : Attribute + { + /// + /// Creates a table mapping to a specific name for Dapper.Contrib commands + /// + /// The name of this table in the database. + public TableAttribute(string tableName) + { + Name = tableName; + } + + /// + /// The name of the table in the database + /// + public string Name { get; set; } + } + + /// + /// Specifies that this field is a primary key in the database + /// + [AttributeUsage(AttributeTargets.Property)] + public class KeyAttribute : Attribute + { + } + + /// + /// Specifies that this field is a explicitly set primary key in the database + /// + [AttributeUsage(AttributeTargets.Property)] + public class ExplicitKeyAttribute : Attribute + { + } + + /// + /// Specifies whether a field is writable in the database. + /// + [AttributeUsage(AttributeTargets.Property)] + public class WriteAttribute : Attribute + { + /// + /// Specifies whether a field is writable in the database. + /// + /// Whether a field is writable in the database. + public WriteAttribute(bool write) + { + Write = write; + } + + /// + /// Whether a field is writable in the database. + /// + public bool Write { get; } + } + + /// + /// Specifies that this is a computed column. + /// + [AttributeUsage(AttributeTargets.Property)] + public class ComputedAttribute : Attribute + { + } +} + +/// +/// The interface for all Dapper.Contrib database operations +/// Implementing this is each provider's model. +/// +public partial interface ISqlAdapter +{ + /// + /// Inserts into the database, returning the Id of the row created. + /// + /// The connection to use. + /// The transaction to use. + /// The command timeout to use. + /// The table to insert into. + /// The columns to set with this insert. + /// The parameters to set for this insert. + /// The key columns in this table. + /// The entity to insert. + /// The Id of the row created. + int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, DynamicParameters entityToInsert); + + /// + /// Adds the name of a column. + /// + /// The string builder to append to. + /// The column name. + void AppendColumnName(StringBuilder sb, string columnName); + /// + /// Adds a column equality to a parameter. + /// + /// The string builder to append to. + /// The column name. + void AppendColumnNameEqualsValue(StringBuilder sb, string columnName); +} + +/// +/// The SQL Server database adapter. +/// +public partial class SqlServerAdapter : ISqlAdapter +{ + /// + /// Inserts into the database, returning the Id of the row created. + /// + /// The connection to use. + /// The transaction to use. + /// The command timeout to use. + /// The table to insert into. + /// The columns to set with this insert. + /// The parameters to set for this insert. + /// The key columns in this table. + /// The entity to insert. + /// The Id of the row created. + public int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, DynamicParameters entityToInsert) + { + var cmd = $"insert into {tableName} ({columnList}) values ({parameterList});select SCOPE_IDENTITY() id"; + var multi = connection.QueryMultiple(cmd, entityToInsert, transaction, commandTimeout); + + var first = multi.Read().FirstOrDefault(); + if (first == null || first.id == null) return 0; + + var id = (int)first.id; + var propertyInfos = keyProperties as PropertyInfo[] ?? keyProperties.ToArray(); + if (propertyInfos.Length == 0) return id; + + var idProperty = propertyInfos[0]; + idProperty.SetValue(entityToInsert, Convert.ChangeType(id, idProperty.PropertyType), null); + + return id; + } + + /// + /// Adds the name of a column. + /// + /// The string builder to append to. + /// The column name. + public void AppendColumnName(StringBuilder sb, string columnName) + { + sb.AppendFormat("[{0}]", columnName); + } + + /// + /// Adds a column equality to a parameter. + /// + /// The string builder to append to. + /// The column name. + public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName) + { + sb.AppendFormat("[{0}] = @{1}", columnName, columnName); + } +} + +/// +/// The SQL Server Compact Edition database adapter. +/// +public partial class SqlCeServerAdapter : ISqlAdapter +{ + /// + /// Inserts into the database, returning the Id of the row created. + /// + /// The connection to use. + /// The transaction to use. + /// The command timeout to use. + /// The table to insert into. + /// The columns to set with this insert. + /// The parameters to set for this insert. + /// The key columns in this table. + /// The entity to insert. + /// The Id of the row created. + public int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, DynamicParameters entityToInsert) + { + var cmd = $"insert into {tableName} ({columnList}) values ({parameterList})"; + connection.Execute(cmd, entityToInsert, transaction, commandTimeout); + var r = connection.Query("select @@IDENTITY id", transaction: transaction, commandTimeout: commandTimeout).ToList(); + + if (r[0].id == null) return 0; + var id = (int)r[0].id; + + var propertyInfos = keyProperties as PropertyInfo[] ?? keyProperties.ToArray(); + if (propertyInfos.Length == 0) return id; + + var idProperty = propertyInfos[0]; + idProperty.SetValue(entityToInsert, Convert.ChangeType(id, idProperty.PropertyType), null); + + return id; + } + + /// + /// Adds the name of a column. + /// + /// The string builder to append to. + /// The column name. + public void AppendColumnName(StringBuilder sb, string columnName) + { + sb.AppendFormat("[{0}]", columnName); + } + + /// + /// Adds a column equality to a parameter. + /// + /// The string builder to append to. + /// The column name. + public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName) + { + sb.AppendFormat("[{0}] = @{1}", columnName, columnName); + } +} + +/// +/// The MySQL database adapter. +/// +public partial class MySqlAdapter : ISqlAdapter +{ + /// + /// Inserts into the database, returning the Id of the row created. + /// + /// The connection to use. + /// The transaction to use. + /// The command timeout to use. + /// The table to insert into. + /// The columns to set with this insert. + /// The parameters to set for this insert. + /// The key columns in this table. + /// The entity to insert. + /// The Id of the row created. + public int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, DynamicParameters entityToInsert) + { + var cmd = $"insert into {tableName} ({columnList}) values ({parameterList})"; + connection.Execute(cmd, entityToInsert, transaction, commandTimeout); + var r = connection.Query("Select LAST_INSERT_ID() id", transaction: transaction, commandTimeout: commandTimeout); + + var id = r.First().id; + if (id == null) return 0; + var propertyInfos = keyProperties as PropertyInfo[] ?? keyProperties.ToArray(); + if (propertyInfos.Length == 0) return Convert.ToInt32(id); + + var idp = propertyInfos[0]; + idp.SetValue(entityToInsert, Convert.ChangeType(id, idp.PropertyType), null); + + return Convert.ToInt32(id); + } + + /// + /// Adds the name of a column. + /// + /// The string builder to append to. + /// The column name. + public void AppendColumnName(StringBuilder sb, string columnName) + { + sb.AppendFormat("`{0}`", columnName); + } + + /// + /// Adds a column equality to a parameter. + /// + /// The string builder to append to. + /// The column name. + public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName) + { + sb.AppendFormat("`{0}` = @{1}", columnName, columnName); + } +} + +/// +/// The Postgres database adapter. +/// +public partial class PostgresAdapter : ISqlAdapter +{ + /// + /// Inserts into the database, returning the Id of the row created. + /// + /// The connection to use. + /// The transaction to use. + /// The command timeout to use. + /// The table to insert into. + /// The columns to set with this insert. + /// The parameters to set for this insert. + /// The key columns in this table. + /// The entity to insert. + /// The Id of the row created. + public int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, DynamicParameters entityToInsert) + { + var sb = new StringBuilder(); + sb.AppendFormat("insert into {0} ({1}) values ({2})", tableName, columnList, parameterList); + + // If no primary key then safe to assume a join table with not too much data to return + var propertyInfos = keyProperties as PropertyInfo[] ?? keyProperties.ToArray(); + if (propertyInfos.Length == 0) + { + sb.Append(" RETURNING *"); + } + else + { + sb.Append(" RETURNING "); + var first = true; + foreach (var property in propertyInfos) + { + if (!first) + sb.Append(", "); + first = false; + sb.Append(property.Name); + } + } + + var results = connection.Query(sb.ToString(), entityToInsert, transaction, commandTimeout: commandTimeout).ToList(); + + // Return the key by assinging the corresponding property in the object - by product is that it supports compound primary keys + var id = 0; + foreach (var p in propertyInfos) + { + var value = ((IDictionary)results[0])[p.Name.ToLower()]; + p.SetValue(entityToInsert, value, null); + if (id == 0) + id = Convert.ToInt32(value); + } + return id; + } + + /// + /// Adds the name of a column. + /// + /// The string builder to append to. + /// The column name. + public void AppendColumnName(StringBuilder sb, string columnName) + { + sb.AppendFormat("\"{0}\"", columnName); + } + + /// + /// Adds a column equality to a parameter. + /// + /// The string builder to append to. + /// The column name. + public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName) + { + sb.AppendFormat("\"{0}\" = @{1}", columnName, columnName); + } +} + +/// +/// The SQLite database adapter. +/// +public partial class SQLiteAdapter : ISqlAdapter +{ + /// + /// Inserts into the database, returning the Id of the row created. + /// + /// The connection to use. + /// The transaction to use. + /// The command timeout to use. + /// The table to insert into. + /// The columns to set with this insert. + /// The parameters to set for this insert. + /// The key columns in this table. + /// The entity to insert. + /// The Id of the row created. + public int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, DynamicParameters entityToInsert) + { + var cmd = $"INSERT INTO {tableName} ({columnList}) VALUES ({parameterList}); SELECT last_insert_rowid() id"; + var multi = connection.QueryMultiple(cmd, entityToInsert, transaction, commandTimeout); + + var id = (int)multi.Read().First().id; + var propertyInfos = keyProperties as PropertyInfo[] ?? keyProperties.ToArray(); + if (propertyInfos.Length == 0) return id; + + var idProperty = propertyInfos[0]; + idProperty.SetValue(entityToInsert, Convert.ChangeType(id, idProperty.PropertyType), null); + + return id; + } + + /// + /// Adds the name of a column. + /// + /// The string builder to append to. + /// The column name. + public void AppendColumnName(StringBuilder sb, string columnName) + { + sb.AppendFormat("\"{0}\"", columnName); + } + + /// + /// Adds a column equality to a parameter. + /// + /// The string builder to append to. + /// The column name. + public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName) + { + sb.AppendFormat("\"{0}\" = @{1}", columnName, columnName); + } +} + +/// +/// The Firebase SQL adapeter. +/// +public partial class FbAdapter : ISqlAdapter +{ + /// + /// Inserts into the database, returning the Id of the row created. + /// + /// The connection to use. + /// The transaction to use. + /// The command timeout to use. + /// The table to insert into. + /// The columns to set with this insert. + /// The parameters to set for this insert. + /// The key columns in this table. + /// The entity to insert. + /// The Id of the row created. + public int Insert(IDbConnection connection, IDbTransaction transaction, int? commandTimeout, string tableName, string columnList, string parameterList, IEnumerable keyProperties, DynamicParameters entityToInsert) + { + var cmd = $"insert into {tableName} ({columnList}) values ({parameterList})"; + connection.Execute(cmd, entityToInsert, transaction, commandTimeout); + + var propertyInfos = keyProperties as PropertyInfo[] ?? keyProperties.ToArray(); + var keyName = propertyInfos[0].Name; + var r = connection.Query($"SELECT FIRST 1 {keyName} ID FROM {tableName} ORDER BY {keyName} DESC", transaction: transaction, commandTimeout: commandTimeout); + + var id = r.First().ID; + if (id == null) return 0; + if (propertyInfos.Length == 0) return Convert.ToInt32(id); + + var idp = propertyInfos[0]; + idp.SetValue(entityToInsert, Convert.ChangeType(id, idp.PropertyType), null); + + return Convert.ToInt32(id); + } + + /// + /// Adds the name of a column. + /// + /// The string builder to append to. + /// The column name. + public void AppendColumnName(StringBuilder sb, string columnName) + { + sb.AppendFormat("{0}", columnName); + } + + /// + /// Adds a column equality to a parameter. + /// + /// The string builder to append to. + /// The column name. + public void AppendColumnNameEqualsValue(StringBuilder sb, string columnName) + { + sb.AppendFormat("{0} = @{1}", columnName, columnName); + } +} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Database/SqlServer.cs b/net452/SiteServer.CMS/Database/SqlServer.cs new file mode 100644 index 000000000..0daf5ec18 --- /dev/null +++ b/net452/SiteServer.CMS/Database/SqlServer.cs @@ -0,0 +1,485 @@ +using System; +using System.Collections; +using System.Data; +using System.Data.OleDb; +using System.Data.SqlClient; +using System.Xml; +using SiteServer.CMS.Apis; + +namespace SiteServer.CMS.Database.Core +{ + public class SqlServer : DatabaseApi + { + //public override IDataParameter[] GetDataParameters(int size) + //{ + // return new SqlParameter[size]; + //} + + + //public override IDbConnection GetConnection(string connectionString) + //{ + // return new SqlConnection(connectionString); + //} + + + + + //public override void DeriveParameters(IDbCommand cmd) + //{ + // var mustCloseConnection = false; + + // if (!(cmd is SqlCommand)) + // throw new ArgumentException("The command provided is not a SqlCommand instance.", "cmd"); + + // if (cmd.Connection.State != ConnectionState.Open) + // { + // cmd.Connection.Open(); + // mustCloseConnection = true; + // } + + // DeriveParameters((SqlCommand)cmd); + + // if (mustCloseConnection) + // { + // cmd.Connection.Close(); + // } + //} + + + //public override IDataParameter GetParameter() + //{ + // return new SqlParameter(); + //} + + + public override void ClearCommand(IDbCommand command) + { + // HACK: There is a problem here, the output parameter values are fletched + // when the reader is closed, so if the parameters are detached from the command + // then the IDataReader can磘 set its values. + // When this happen, the parameters can磘 be used again in other command. + var canClear = true; + + foreach (IDataParameter commandParameter in command.Parameters) + { + if (commandParameter.Direction != ParameterDirection.Input) + canClear = false; + + } + if (canClear) + { + command.Parameters.Clear(); + } + } + + + public override void CleanParameterSyntax(IDbCommand command) + { + // do nothing for SQL + } + + + public override XmlReader ExecuteXmlReader(IDbCommand command) + { + var mustCloseConnection = false; + + if (command.Connection.State != ConnectionState.Open) + { + command.Connection.Open(); + mustCloseConnection = true; + } + + CleanParameterSyntax(command); + // Create the DataAdapter & DataSet + var retval = ((SqlCommand)command).ExecuteXmlReader(); + + // Detach the SqlParameters from the command object, so they can be used again + // don't do this...screws up output parameters -- cjbreisch + // cmd.Parameters.Clear(); + + if (mustCloseConnection) + { + command.Connection.Close(); + } + + return retval; + } + + + + protected override IDataParameter GetBlobParameter(IDbConnection connection, IDataParameter p) + { + // do nothing special for BLOBs...as far as we know now. + return p; + } + + internal static void DeriveParameters(SqlCommand cmd) + { + string cmdText; + SqlCommand newCommand; + SqlDataReader reader; + ArrayList parameterList; + SqlParameter sqlParam; + CommandType cmdType; + string procedureSchema; + string procedureName; + int groupNumber; + var trnSql = cmd.Transaction; + + cmdType = cmd.CommandType; + + if ((cmdType == CommandType.Text)) + { + throw new InvalidOperationException(); + } + else if ((cmdType == CommandType.TableDirect)) + { + throw new InvalidOperationException(); + } + else if ((cmdType != CommandType.StoredProcedure)) + { + throw new InvalidOperationException(); + } + + procedureName = cmd.CommandText; + string server = null; + string database = null; + procedureSchema = null; + + // split out the procedure name to get the server, database, etc. + GetProcedureTokens(ref procedureName, ref server, ref database, ref procedureSchema); + + // look for group numbers + groupNumber = ParseGroupNumber(ref procedureName); + + newCommand = null; + + // set up the command string. We use sp_procuedure_params_rowset to get the parameters + if (database != null) + { + cmdText = string.Concat("[", database, "]..sp_procedure_params_rowset"); + if (server != null) + { + cmdText = string.Concat(server, ".", cmdText); + } + + // be careful of transactions + if (trnSql != null) + { + newCommand = new SqlCommand(cmdText, cmd.Connection, trnSql); + } + else + { + newCommand = new SqlCommand(cmdText, cmd.Connection); + } + } + else + { + // be careful of transactions + if (trnSql != null) + { + newCommand = new SqlCommand("sp_procedure_params_rowset", cmd.Connection, trnSql); + } + else + { + newCommand = new SqlCommand("sp_procedure_params_rowset", cmd.Connection); + } + } + + newCommand.CommandType = CommandType.StoredProcedure; + newCommand.Parameters.Add(new SqlParameter("@procedure_name", SqlDbType.NVarChar, 255)); + newCommand.Parameters[0].Value = procedureName; + + // make sure we specify + if (!IsEmptyString(procedureSchema)) + { + newCommand.Parameters.Add(new SqlParameter("@procedure_schema", SqlDbType.NVarChar, 255)); + newCommand.Parameters[1].Value = procedureSchema; + } + + // make sure we specify the groupNumber if we were given one + if (groupNumber != 0) + { + newCommand.Parameters.Add(new SqlParameter("@group_number", groupNumber)); + } + + reader = null; + parameterList = new ArrayList(); + + try + { + // get a reader full of our params + reader = newCommand.ExecuteReader(); + sqlParam = null; + + while (reader.Read()) + { + // get all the parameter properties that we can get, Name, type, length, direction, precision + sqlParam = new SqlParameter(); + sqlParam.ParameterName = (string)(reader["PARAMETER_NAME"]); + sqlParam.SqlDbType = GetSqlDbType((short)(reader["DATA_TYPE"]), (string)(reader["TYPE_NAME"])); + + if (reader["CHARACTER_MAXIMUM_LENGTH"] != DBNull.Value) + { + sqlParam.Size = (int)(reader["CHARACTER_MAXIMUM_LENGTH"]); + } + + sqlParam.Direction = GetParameterDirection((short)(reader["PARAMETER_TYPE"])); + + if ((sqlParam.SqlDbType == SqlDbType.Decimal)) + { + sqlParam.Scale = (byte)(((short)(reader["NUMERIC_SCALE"]) & 255)); + sqlParam.Precision = (byte)(((short)(reader["NUMERIC_PRECISION"]) & 255)); + } + parameterList.Add(sqlParam); + } + } + finally + { + // close our reader and connection when we're done + if (reader != null) + { + reader.Close(); + } + newCommand.Connection = null; + } + + // we didn't get any parameters + if ((parameterList.Count == 0)) + { + throw new InvalidOperationException(); + } + + cmd.Parameters.Clear(); + + // add the parameters to the command object + + foreach (var parameter in parameterList) + { + cmd.Parameters.Add(parameter); + } + } + + private static int ParseGroupNumber(ref string procedure) + { + string newProcName; + var groupPos = procedure.IndexOf(';'); + var groupIndex = 0; + + if (groupPos > 0) + { + newProcName = procedure.Substring(0, groupPos); + try + { + groupIndex = int.Parse(procedure.Substring(groupPos + 1)); + } + catch + { + throw new InvalidOperationException(); + } + } + else + { + newProcName = procedure; + groupIndex = 0; + } + + procedure = newProcName; + return groupIndex; + } + + private static void GetProcedureTokens(ref string procedure, ref string server, ref string database, ref string owner) + { + string[] spNameTokens; + int arrIndex; + int nextPos; + int currPos; + int tokenCount; + + server = null; + database = null; + owner = null; + + spNameTokens = new string[4]; + + if (!IsEmptyString(procedure)) + { + arrIndex = 0; + nextPos = 0; + currPos = 0; + + while ((arrIndex < 4)) + { + currPos = procedure.IndexOf('.', nextPos); + if ((-1 == currPos)) + { + spNameTokens[arrIndex] = procedure.Substring(nextPos); + break; + } + spNameTokens[arrIndex] = procedure.Substring(nextPos, (currPos - nextPos)); + nextPos = (currPos + 1); + if ((procedure.Length <= nextPos)) + { + break; + } + arrIndex = (arrIndex + 1); + } + + tokenCount = arrIndex + 1; + + // based on how many '.' we found, we know what tokens we found + switch (tokenCount) + { + case 1: + procedure = spNameTokens[0]; + break; + case 2: + procedure = spNameTokens[1]; + owner = spNameTokens[0]; + break; + case 3: + procedure = spNameTokens[2]; + owner = spNameTokens[1]; + database = spNameTokens[0]; + break; + case 4: + procedure = spNameTokens[3]; + owner = spNameTokens[2]; + database = spNameTokens[1]; + server = spNameTokens[0]; + break; + } + } + } + + private static bool IsEmptyString(string str) + { + if (str != null) + { + return (0 == str.Length); + } + return true; + } + + private static SqlDbType GetSqlDbType(short paramType, string typeName) + { + SqlDbType cmdType; + OleDbType oleDbType; + cmdType = SqlDbType.Variant; + oleDbType = (OleDbType)paramType; + + switch (oleDbType) + { + case OleDbType.SmallInt: + cmdType = SqlDbType.SmallInt; + break; + case OleDbType.Integer: + cmdType = SqlDbType.Int; + break; + case OleDbType.Single: + cmdType = SqlDbType.Real; + break; + case OleDbType.Double: + cmdType = SqlDbType.Float; + break; + case OleDbType.Currency: + cmdType = typeName == "money" ? SqlDbType.Money : SqlDbType.SmallMoney; + break; + case OleDbType.Date: + cmdType = typeName == "datetime" ? SqlDbType.DateTime : SqlDbType.SmallDateTime; + break; + case OleDbType.BSTR: + cmdType = typeName == "nchar" ? SqlDbType.NChar : SqlDbType.NVarChar; + break; + case OleDbType.Boolean: + cmdType = SqlDbType.Bit; + break; + case OleDbType.Variant: + cmdType = SqlDbType.Variant; + break; + case OleDbType.Decimal: + cmdType = SqlDbType.Decimal; + break; + case OleDbType.TinyInt: + cmdType = SqlDbType.TinyInt; + break; + case OleDbType.UnsignedTinyInt: + cmdType = SqlDbType.TinyInt; + break; + case OleDbType.UnsignedSmallInt: + cmdType = SqlDbType.SmallInt; + break; + case OleDbType.BigInt: + cmdType = SqlDbType.BigInt; + break; + case OleDbType.Filetime: + cmdType = typeName == "datetime" ? SqlDbType.DateTime : SqlDbType.SmallDateTime; + break; + case OleDbType.Guid: + cmdType = SqlDbType.UniqueIdentifier; + break; + case OleDbType.Binary: + cmdType = typeName == "binary" ? SqlDbType.Binary : SqlDbType.VarBinary; + break; + case OleDbType.Char: + cmdType = typeName == "char" ? SqlDbType.Char : SqlDbType.VarChar; + break; + case OleDbType.WChar: + cmdType = typeName == "nchar" ? SqlDbType.NChar : SqlDbType.NVarChar; + break; + case OleDbType.Numeric: + cmdType = SqlDbType.Decimal; + break; + case OleDbType.DBDate: + cmdType = typeName == "datetime" ? SqlDbType.DateTime : SqlDbType.SmallDateTime; + break; + case OleDbType.DBTime: + cmdType = typeName == "datetime" ? SqlDbType.DateTime : SqlDbType.SmallDateTime; + break; + case OleDbType.DBTimeStamp: + cmdType = typeName == "datetime" ? SqlDbType.DateTime : SqlDbType.SmallDateTime; + break; + case OleDbType.VarChar: + cmdType = typeName == "char" ? SqlDbType.Char : SqlDbType.VarChar; + break; + case OleDbType.LongVarChar: + cmdType = SqlDbType.Text; + break; + case OleDbType.VarWChar: + cmdType = typeName == "nchar" ? SqlDbType.NChar : SqlDbType.NVarChar; + break; + case OleDbType.LongVarWChar: + cmdType = SqlDbType.NText; + break; + case OleDbType.VarBinary: + cmdType = typeName == "binary" ? SqlDbType.Binary : SqlDbType.VarBinary; + break; + case OleDbType.LongVarBinary: + cmdType = SqlDbType.Image; + break; + } + return cmdType; + } + + private static ParameterDirection GetParameterDirection(short oledbDirection) + { + ParameterDirection pd; + switch (oledbDirection) + { + case 1: + pd = ParameterDirection.Input; + break; + case 2: + pd = ParameterDirection.Output; + break; + case 4: + pd = ParameterDirection.ReturnValue; + break; + default: + pd = ParameterDirection.InputOutput; + break; + } + return pd; + } + } +} diff --git a/net452/SiteServer.CMS/Database/SqlUtils.cs b/net452/SiteServer.CMS/Database/SqlUtils.cs new file mode 100644 index 000000000..7a523c01f --- /dev/null +++ b/net452/SiteServer.CMS/Database/SqlUtils.cs @@ -0,0 +1,837 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Data.SqlClient; +using System.Text; +using System.Web.UI; +using Datory; +using MySql.Data.MySqlClient; +using Npgsql; +using NpgsqlTypes; +using Oracle.ManagedDataAccess.Client; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Fx; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Core +{ + public static class SqlUtils + { + + + //public static IDbDataParameter GetIDbDataParameter(string parameterName, DataType dataType, int size, object value) + //{ + // IDbDataParameter parameter = null; + + // if (size == 0) + // { + // if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + // { + // parameter = new MySqlParameter(parameterName, ToMySqlDbType(dataType)) + // { + // Value = value + // }; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + // { + // parameter = new SqlParameter(parameterName, ToSqlServerDbType(dataType)) + // { + // Value = value + // }; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + // { + // parameter = new NpgsqlParameter(parameterName, ToNpgsqlDbType(dataType)) + // { + // Value = value + // }; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + // { + // parameter = new OracleParameter(parameterName, ToOracleDbType(dataType)) + // { + // Value = ToOracleDbValue(dataType, value) + // }; + // } + // } + // else + // { + // if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + // { + // parameter = new MySqlParameter(parameterName, ToMySqlDbType(dataType), size) + // { + // Value = value + // }; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + // { + // parameter = new SqlParameter(parameterName, ToSqlServerDbType(dataType), size) + // { + // Value = value + // }; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + // { + // parameter = new NpgsqlParameter(parameterName, ToNpgsqlDbType(dataType), size) + // { + // Value = value + // }; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + // { + // parameter = new OracleParameter(parameterName, ToOracleDbType(dataType), size) + // { + // Value = ToOracleDbValue(dataType, value) + // }; + // } + // } + + // return parameter; + //} + + //public static string GetInStrReverse(string inStr, string columnName) + //{ + // var retVal = string.Empty; + + // if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + // { + // retVal = $"INSTR('{inStr}', {columnName}) > 0"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + // { + // retVal = $"CHARINDEX({columnName}, '{inStr}') > 0"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + // { + // retVal = $"POSITION({columnName} IN '{inStr}') > 0"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + // { + // retVal = $"INSTR('{inStr}', {columnName}) > 0"; + // } + + // return retVal; + //} + + //public static string GetDistinctTopSqlString(string tableName, string columns, string whereString, string orderString, int topN) + //{ + // var retVal = $"SELECT DISTINCT {columns} FROM {tableName} {whereString} {orderString}"; + // if (topN <= 0) return retVal; + + // if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + // { + // retVal = $"SELECT DISTINCT {columns} FROM {tableName} {whereString} {orderString} LIMIT {topN}"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + // { + // retVal = $"SELECT DISTINCT TOP {topN} {columns} FROM {tableName} {whereString} {orderString}"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + // { + // retVal = $"SELECT DISTINCT {columns} FROM {tableName} {whereString} {orderString} LIMIT {topN}"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + // { + // retVal = $"SELECT DISTINCT {columns} FROM {tableName} {whereString} {orderString} FETCH FIRST {topN} ROWS ONLY"; + // } + + // return retVal; + //} + + //public static string ToInTopSqlString(string tableName, IList columns, string whereString, string orderString, int topN) + //{ + // var builder = new StringBuilder(); + // if (WebConfigUtils.DatabaseType != DatabaseType.Oracle) + // { + // foreach (var column in columns) + // { + // builder.Append($"T.{column}, "); + // } + // builder.Length = builder.Length - 2; + // return + // $"SELECT {builder} FROM ({DatorySql.GetSqlString(WebConfigUtils.DatabaseType, DatabaseApi.Instance.UseLegacyPagination, tableName, columns, whereString, orderString, topN)}) AS T"; + // } + + // foreach (var column in columns) + // { + // builder.Append($"{column}, "); + // } + // builder.Length = builder.Length - 2; + // return + // $"SELECT {builder} FROM ({DatorySql.GetSqlString(WebConfigUtils.DatabaseType, DatabaseApi.Instance.UseLegacyPagination, tableName, columns, whereString, orderString, topN)})"; + //} + + + //private static SqlDbType ToSqlServerDbType(DataType type) + //{ + // if (type == DataType.Boolean) + // { + // return SqlDbType.Bit; + // } + // if (type == DataType.DateTime) + // { + // return SqlDbType.DateTime; + // } + // if (type == DataType.Decimal) + // { + // return SqlDbType.Decimal; + // } + // if (type == DataType.Integer) + // { + // return SqlDbType.Int; + // } + // if (type == DataType.Text) + // { + // return SqlDbType.NText; + // } + // if (type == DataType.VarChar) + // { + // return SqlDbType.NVarChar; + // } + // return SqlDbType.VarChar; + //} + + //private static MySqlDbType ToMySqlDbType(DataType type) + //{ + // if (type == DataType.Boolean) + // { + // return MySqlDbType.Bit; + // } + // if (type == DataType.DateTime) + // { + // return MySqlDbType.DateTime; + // } + // if (type == DataType.Decimal) + // { + // return MySqlDbType.Decimal; + // } + // if (type == DataType.Integer) + // { + // return MySqlDbType.Int32; + // } + // if (type == DataType.Text) + // { + // return MySqlDbType.LongText; + // } + // if (type == DataType.VarChar) + // { + // return MySqlDbType.VarString; + // } + + // return MySqlDbType.VarString; + //} + + //private static NpgsqlDbType ToNpgsqlDbType(DataType type) + //{ + // if (type == DataType.Boolean) + // { + // return NpgsqlDbType.Boolean; + // } + // if (type == DataType.DateTime) + // { + // return NpgsqlDbType.TimestampTz; + // } + // if (type == DataType.Decimal) + // { + // return NpgsqlDbType.Numeric; + // } + // if (type == DataType.Integer) + // { + // return NpgsqlDbType.Integer; + // } + // if (type == DataType.Text) + // { + // return NpgsqlDbType.Text; + // } + // return NpgsqlDbType.Varchar; + //} + + //public static string ReadNextSqlString(StreamReader reader) + //{ + // try + // { + // var sb = new StringBuilder(); + + // while (true) + // { + // var lineOfText = reader.ReadLine(); + + // if (lineOfText == null) + // { + // return sb.Length > 0 ? sb.ToString() : null; + // } + + // if (lineOfText.StartsWith("--")) continue; + // lineOfText = lineOfText.Replace(")ENGINE=INNODB", ") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"); + + // if (lineOfText.TrimEnd().ToUpper() == "GO") + // { + // break; + // } + + // sb.Append(lineOfText + Environment.NewLine); + // } + + // return sb.ToString(); + // } + // catch + // { + // return null; + // } + //} + + //public static string ReadNextStatementFromStream(StringReader reader) + //{ + // try + // { + // var sb = new StringBuilder(); + + // while (true) + // { + // var lineOfText = reader.ReadLine(); + // if (lineOfText == null) + // { + // return sb.Length > 0 ? sb.ToString() : null; + // } + + // if (lineOfText.TrimEnd().ToUpper() == "GO") + // { + // break; + // } + + // sb.Append(lineOfText + Environment.NewLine); + // } + + // return sb.ToString(); + // } + // catch + // { + // return null; + // } + //} + + //public static string ToPlusSqlString(string fieldName, int plusNum = 1) + //{ + // var retVal = string.Empty; + + // if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + // { + // retVal = $"{fieldName} = IFNULL({fieldName}, 0) + {plusNum}"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + // { + // retVal = $"{fieldName} = ISNULL({fieldName}, 0) + {plusNum}"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + // { + // retVal = $"{fieldName} = COALESCE({fieldName}, 0) + {plusNum}"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + // { + // retVal = $"{fieldName} = COALESCE({fieldName}, 0) + {plusNum}"; + // } + + // return retVal; + //} + + //public static string ToMinusSqlString(string fieldName, int minusNum = 1) + //{ + // var retVal = string.Empty; + + // if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + // { + // retVal = $"{fieldName} = IFNULL({fieldName}, 0) - {minusNum}"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + // { + // retVal = $"{fieldName} = ISNULL({fieldName}, 0) - {minusNum}"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + // { + // retVal = $"{fieldName} = COALESCE({fieldName}, 0) - {minusNum}"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + // { + // retVal = $"{fieldName} = COALESCE({fieldName}, 0) - {minusNum}"; + // } + + // return retVal; + //} + + //private static OracleDbType ToOracleDbType(DataType type) + //{ + // if (type == DataType.Boolean) + // { + // return OracleDbType.Int32; + // } + // if (type == DataType.DateTime) + // { + // return OracleDbType.TimeStampTZ; + // } + // if (type == DataType.Decimal) + // { + // return OracleDbType.Decimal; + // } + // if (type == DataType.Integer) + // { + // return OracleDbType.Int32; + // } + // if (type == DataType.Text) + // { + // return OracleDbType.NClob; + // } + // return OracleDbType.NVarchar2; + //} + + //public static string GetDateDiffGreatThanDays(string fieldName, string days) + //{ + // return GetDateDiffGreatThan(fieldName, days, "DAY"); + //} + + //private static string GetDateDiffGreatThan(string fieldName, string fieldValue, string unit) + //{ + // var retVal = string.Empty; + + // if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + // { + // retVal = $"TIMESTAMPDIFF({unit}, {fieldName}, now()) > {fieldValue}"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + // { + // retVal = $"DATEDIFF({unit}, {fieldName}, getdate()) > {fieldValue}"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + // { + // retVal = $"EXTRACT(EPOCH FROM current_timestamp - {fieldName})/{GetSecondsByUnit(unit)} > {fieldValue}"; + // } + // else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + // { + // retVal = $"EXTRACT({unit} FROM CURRENT_TIMESTAMP - {fieldName}) > {fieldValue}"; + // } + + // return retVal; + //} + + public static string GetSqlColumnInList(string columnName, List idList) + { + if (idList == null || idList.Count == 0) return string.Empty; + + if (idList.Count < 1000) + { + return $"{columnName} IN ({TranslateUtils.ToSqlInStringWithoutQuote(idList)})"; + } + + var sql = new StringBuilder(); + sql.Append(" ").Append(columnName).Append(" IN ( "); + for (var i = 0; i < idList.Count; i++) + { + sql.Append(idList[i] + ","); + if ((i + 1) % 1000 == 0 && i + 1 < idList.Count) + { + sql.Length -= 1; + sql.Append(" ) OR ").Append(columnName).Append(" IN ("); + } + } + sql.Length -= 1; + sql.Append(" )"); + + return $"({sql})"; + } + + public static string GetInStr(string columnName, string inStr) + { + var retVal = string.Empty; + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + retVal = $"INSTR({columnName}, '{inStr}') > 0"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + retVal = $"CHARINDEX('{inStr}', {columnName}) > 0"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + retVal = $"POSITION('{inStr}' IN {columnName}) > 0"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + retVal = $"INSTR({columnName}, '{inStr}') > 0"; + } + + return retVal; + } + + + + public static string GetNotInStr(string columnName, string inStr) + { + var retVal = string.Empty; + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + retVal = $"INSTR({columnName}, '{inStr}') = 0"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + retVal = $"CHARINDEX('{inStr}', {columnName}) = 0"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + retVal = $"POSITION('{inStr}' IN {columnName}) = 0"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + retVal = $"INSTR({columnName}, '{inStr}') = 0"; + } + + return retVal; + } + + public static string ToTopSqlString(string sqlString, string orderString, int topN) + { + string retVal = $"SELECT * FROM ({sqlString}) temp {orderString}"; + if (topN <= 0) return retVal; + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + retVal = $"SELECT * FROM ({sqlString}) {orderString} LIMIT {topN}"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + retVal = $"SELECT TOP {topN} * FROM ({sqlString}) temp {orderString}"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + retVal = $"SELECT * FROM ({sqlString}) {orderString} LIMIT {topN}"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + retVal = $@"SELECT * FROM ({sqlString}) {orderString} FETCH FIRST {topN} ROWS ONLY"; + } + + return retVal; + } + + + + + + public static object ToOracleDbValue(DataType dataType, object value) + { + // Oracle internally changes empty string to NULL values. Oracle simply won't let insert an empty string. So we replace string.Empty value to placeholder _EMPTY_ + if ((dataType == DataType.Text || dataType == DataType.VarChar) && value != null && value.ToString() == string.Empty) + { + return Constants.OracleEmptyValue; + } + return value; + } + + + + + + public static string GetDateDiffLessThanYears(string fieldName, string years) + { + return GetDateDiffLessThan(fieldName, years, "YEAR"); + } + + public static string GetDateDiffLessThanMonths(string fieldName, string months) + { + return GetDateDiffLessThan(fieldName, months, "MONTH"); + } + + public static string GetDateDiffLessThanDays(string fieldName, string days) + { + return GetDateDiffLessThan(fieldName, days, "DAY"); + } + + private static int GetSecondsByUnit(string unit) + { + var seconds = 1; + if (unit == "MINUTE") + { + seconds = 60; + } + else if (unit == "HOUR") + { + seconds = 3600; + } + else if (unit == "DAY") + { + seconds = 86400; + } + else if (unit == "MONTH") + { + seconds = 2592000; + } + else if (unit == "YEAR") + { + seconds = 31536000; + } + return seconds; + } + + private static string GetDateDiffLessThan(string fieldName, string fieldValue, string unit) + { + var retVal = string.Empty; + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + retVal = $"TIMESTAMPDIFF({unit}, {fieldName}, now()) < {fieldValue}"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + retVal = $"DATEDIFF({unit}, {fieldName}, getdate()) < {fieldValue}"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + retVal = $"EXTRACT(EPOCH FROM current_timestamp - {fieldName})/{GetSecondsByUnit(unit)} < {fieldValue}"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + retVal = $"EXTRACT({unit} FROM CURRENT_TIMESTAMP - {fieldName}) < {fieldValue}"; + } + + return retVal; + } + + + + + + public static string GetDatePartYear(string fieldName) + { + var retVal = string.Empty; + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + retVal = $"DATE_FORMAT({fieldName}, '%Y')"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + retVal = $"DATEPART([YEAR], {fieldName})"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + retVal = $"date_part('year', {fieldName})"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + retVal = $"EXTRACT(year from {fieldName})"; + } + + return retVal; + } + + public static string GetDatePartMonth(string fieldName) + { + var retVal = string.Empty; + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + retVal = $"DATE_FORMAT({fieldName}, '%c')"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + retVal = $"DATEPART([MONTH], {fieldName})"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + retVal = $"date_part('month', {fieldName})"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + retVal = $"EXTRACT(month from {fieldName})"; + } + + return retVal; + } + + public static string GetDatePartDay(string fieldName) + { + var retVal = string.Empty; + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + retVal = $"DATE_FORMAT({fieldName}, '%e')"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + retVal = $"DATEPART([DAY], {fieldName})"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + retVal = $"date_part('day', {fieldName})"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + retVal = $"EXTRACT(day from {fieldName})"; + } + + return retVal; + } + + public static string GetComparableNow() + { + var retVal = string.Empty; + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + retVal = "now()"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + retVal = "getdate()"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + retVal = "current_timestamp"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + retVal = "sysdate"; + } + + return retVal; + } + + public static string GetComparableDate(DateTime dateTime) + { + var retVal = string.Empty; + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + retVal = $"'{dateTime:yyyy-MM-dd}'"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + retVal = $"'{dateTime:yyyy-MM-dd}'"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + retVal = $"'{dateTime:yyyy-MM-dd}'"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + retVal = $"to_date('{dateTime:yyyy-MM-dd}', 'yyyy-mm-dd')"; + } + + return retVal; + } + + public static string GetComparableDateTime(DateTime dateTime) + { + var retVal = string.Empty; + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + retVal = $"'{dateTime:yyyy-MM-dd HH:mm:ss}'"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + retVal = $"'{dateTime:yyyy-MM-dd HH:mm:ss}'"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + retVal = $"'{dateTime:yyyy-MM-dd HH:mm:ss}'"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + retVal = $"to_date('{dateTime:yyyy-MM-dd HH:mm:ss}', 'yyyy-mm-dd hh24:mi:ss')"; + } + + return retVal; + } + + + + public static string GetOrderByRandom() + { + var retVal = string.Empty; + + if (WebConfigUtils.DatabaseType == DatabaseType.MySql) + { + retVal = "ORDER BY RAND()"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.SqlServer) + { + retVal = "ORDER BY NEWID() DESC"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.PostgreSql) + { + retVal = "ORDER BY random()"; + } + else if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + retVal = "ORDER BY dbms_random.value()"; + } + + return retVal; + } + + public static string ToSqlString(string inputString) + { + return !string.IsNullOrEmpty(inputString) ? inputString.Replace("'", "''") : string.Empty; + } + + + + private static object Eval(object dataItem, string name) + { + object o = null; + try + { + o = DataBinder.Eval(dataItem, name); + } + catch + { + // ignored + } + if (o == DBNull.Value) + { + o = null; + } + return o; + } + + public static int EvalInt(object dataItem, string name) + { + var o = Eval(dataItem, name); + return o == null ? 0 : Convert.ToInt32(o); + } + + public static string EvalString(object dataItem, string name) + { + var o = Eval(dataItem, name); + var value = o?.ToString() ?? string.Empty; + + if (!string.IsNullOrEmpty(value)) + { + value = AttackUtils.UnFilterSql(value); + } + if (WebConfigUtils.DatabaseType == DatabaseType.Oracle && value == Constants.OracleEmptyValue) + { + value = string.Empty; + } + return value; + } + + public static DateTime EvalDateTime(object dataItem, string name) + { + var o = Eval(dataItem, name); + if (o == null) + { + return DateUtils.SqlMinValue; + } + return (DateTime)o; + } + + public static bool EvalBool(object dataItem, string name) + { + var o = Eval(dataItem, name); + return o != null && TranslateUtils.ToBool(o.ToString()); + } + + } +} diff --git a/net452/SiteServer.CMS/Database/Wrapper/AttributesImpl.cs b/net452/SiteServer.CMS/Database/Wrapper/AttributesImpl.cs new file mode 100644 index 000000000..e01d63640 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Wrapper/AttributesImpl.cs @@ -0,0 +1,322 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Data; +using System.Linq; +using SiteServer.CMS.Database.Core; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Wrapper +{ + [Serializable] + public class AttributesImpl : IAttributes + { + private const string SettingsXml = nameof(SettingsXml); + private const string ExtendedValues = nameof(ExtendedValues); + + private readonly Dictionary _dataDict = new Dictionary(StringComparer.OrdinalIgnoreCase); + + public AttributesImpl() + { + } + + public AttributesImpl(IDataReader reader) + { + Load(reader); + } + + public AttributesImpl(AttributesImpl attributes) + { + Load(attributes); + } + + public void Load(AttributesImpl attributes) + { + if (attributes == null) return; + foreach (var entry in attributes._dataDict) + { + _dataDict[entry.Key] = entry.Value; + } + } + + public void Load(IDataReader reader) + { + if (reader == null) return; + + for (var i = 0; i < reader.FieldCount; i++) + { + var name = reader.GetName(i); + var value = reader.GetValue(i); + + if (value is string && WebConfigUtils.DatabaseType == DatabaseType.Oracle && (string)value == StringUtils.Constants.OracleEmptyValue) + { + value = string.Empty; + } + Set(name, value); + } + } + + public AttributesImpl(IDataRecord record) + { + Load(record); + } + + public void Load(IDataRecord record) + { + if (record == null) return; + + for (var i = 0; i < record.FieldCount; i++) + { + var name = record.GetName(i); + var value = record.GetValue(i); + + if (value is string && WebConfigUtils.DatabaseType == DatabaseType.Oracle && (string)value == StringUtils.Constants.OracleEmptyValue) + { + value = string.Empty; + } + Set(name, value); + } + } + + public AttributesImpl(DataRowView view) + { + Load(view); + } + + public void Load(DataRowView rowView) + { + if (rowView == null) return; + + Load(rowView.Row); + } + + public AttributesImpl(DataRow row) + { + Load(row); + } + + public void Load(DataRow row) + { + if (row == null) return; + + var dict = row.Table.Columns + .Cast() + .ToDictionary(c => c.ColumnName, c => row[c]); + + Load(dict); + } + + public AttributesImpl(NameValueCollection attributes) + { + Load(attributes); + } + + public void Load(NameValueCollection attributes) + { + if (attributes == null) return; + + foreach (string name in attributes) + { + var value = attributes[name]; + Set(name, value); + } + } + + public AttributesImpl(Dictionary dict) + { + Load(dict); + } + + public void Load(Dictionary dict) + { + if (dict == null) return; + + foreach (var key in dict.Keys) + { + Set(key, dict[key]); + } + } + + public AttributesImpl(string json) + { + Load(json); + } + + public void Load(string json) + { + if (string.IsNullOrEmpty(json)) return; + + if (json.StartsWith("{") && json.EndsWith("}")) + { + var dict = TranslateUtils.JsonDeserialize>(json); + foreach (var key in dict.Keys) + { + _dataDict[key] = dict[key]; + } + } + else + { + json = json.Replace("/u0026", "&"); + + var attributes = new NameValueCollection(); + + var pairs = json.Split('&'); + foreach (var pair in pairs) + { + if (pair.IndexOf("=", StringComparison.Ordinal) == -1) continue; + var name = pair.Split('=')[0]; + if (string.IsNullOrEmpty(name)) continue; + + name = name.Replace("_equals_", "=").Replace("_and_", "&").Replace("_question_", "?").Replace("_quote_", "'").Replace("_add_", "+").Replace("_return_", "\r").Replace("_newline_", "\n"); + var value = pair.Split('=')[1]; + if (!string.IsNullOrEmpty(value)) + { + value = value.Replace("_equals_", "=").Replace("_and_", "&").Replace("_question_", "?").Replace("_quote_", "'").Replace("_add_", "+").Replace("_return_", "\r").Replace("_newline_", "\n"); + } + attributes.Add(name.ToLower(), value); + } + + foreach (string key in attributes.Keys) + { + Set(key, attributes[key]); + } + } + } + + public AttributesImpl(object anonymous) + { + Load(anonymous); + } + + public void Load(object anonymous) + { + if (anonymous == null) return; + + foreach (var p in anonymous.GetType().GetProperties()) + { + Set(p.Name.ToCamelCase(), p.GetValue(anonymous)); + } + } + + public object Get(string key) + { + if (string.IsNullOrEmpty(key)) return null; + + return _dataDict.TryGetValue(key, out var value) ? value : null; + } + + public string GetString(string key, string defaultValue = "") + { + var value = Get(key); + if (value == null) return defaultValue; + if (value is string) return (string)value; + return value.ToString(); + } + + public bool GetBool(string key, bool defaultValue = false) + { + var value = Get(key); + if (value == null) return defaultValue; + if (value is bool) return (bool)value; + return TranslateUtils.ToBool(value.ToString(), defaultValue); + } + + public int GetInt(string key, int defaultValue = 0) + { + var value = Get(key); + if (value == null) return defaultValue; + if (value is int) return (int)value; + return TranslateUtils.ToIntWithNegative(value.ToString(), defaultValue); + } + + public decimal GetDecimal(string key, decimal defaultValue = 0) + { + var value = Get(key); + if (value == null) return defaultValue; + if (value is decimal) return (decimal)value; + return TranslateUtils.ToDecimalWithNegative(value.ToString(), defaultValue); + } + + public DateTime GetDateTime(string key, DateTime defaultValue) + { + var value = Get(key); + if (value == null) return defaultValue; + if (value is DateTime) return (DateTime)value; + return TranslateUtils.ToDateTime(value.ToString(), defaultValue); + } + + public DateTime? GetDateTime(string key) + { + var value = Get(key); + if (value == null) return null; + if (value is DateTime) return (DateTime)value; + return TranslateUtils.ToDateTime(value.ToString()); + } + + public void Remove(string key) + { + if (string.IsNullOrEmpty(key)) return; + + _dataDict.Remove(key); + } + + public virtual void Set(string name, object value) + { + if (string.IsNullOrEmpty(name)) return; + + if (value == null) + { + _dataDict.Remove(name); + } + else + { + if (StringUtils.EqualsIgnoreCase(name, SettingsXml) || StringUtils.EqualsIgnoreCase(name, ExtendedValues)) + { + Load(value.ToString()); + } + else + { + _dataDict[name] = value; + } + } + } + + public bool ContainsKey(string key) + { + if (string.IsNullOrEmpty(key)) return false; + + return _dataDict.ContainsKey(key); + } + + public override string ToString() + { + return TranslateUtils.JsonSerialize(_dataDict); + } + + public string ToString(List excludeKeys) + { + if (excludeKeys == null || excludeKeys.Count == 0) return ToString(); + + var dict = new Dictionary(StringComparer.OrdinalIgnoreCase); + foreach (var key in _dataDict.Keys) + { + if (!StringUtils.ContainsIgnoreCase(excludeKeys, key)) + { + dict[key] = _dataDict[key]; + } + } + return TranslateUtils.JsonSerialize(dict); + } + + public virtual Dictionary ToDictionary() + { + var ret = new Dictionary(_dataDict.Count, _dataDict.Comparer); + foreach (KeyValuePair entry in _dataDict) + { + ret.Add(entry.Key, entry.Value); + } + return ret; + } + } +} diff --git a/net452/SiteServer.CMS/Database/Wrapper/DynamicEntity.cs b/net452/SiteServer.CMS/Database/Wrapper/DynamicEntity.cs new file mode 100644 index 000000000..91a75c2aa --- /dev/null +++ b/net452/SiteServer.CMS/Database/Wrapper/DynamicEntity.cs @@ -0,0 +1,266 @@ +using System; +using System.Collections.Generic; +using System.Dynamic; +using System.Linq; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Wrapper +{ + [JsonConverter(typeof(DynamicEntityConverter))] + public class DynamicEntity : DynamicObject + { + [TableColumn] + public int Id { get; set; } + + [TableColumn] + public string Guid { get; set; } + + [TableColumn] + public DateTime? LastModifiedDate { get; set; } + + private readonly List _propertyNames; + + private readonly List _columnNames; + + private readonly string _extendColumnName; + + private readonly Dictionary _extendDictionary; + + protected DynamicEntity() + { + var type = GetType(); + _propertyNames = ReflectionUtils.GetPropertyNames(type); + _columnNames = ReflectionUtils.GetColumnNames(type); + _extendColumnName = ReflectionUtils.GetTableExtendColumnName(type); + _extendDictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); + } + + protected DynamicEntity(IDictionary dict): this() + { + if (dict == null) return; + + foreach (var o in dict) + { + Set(o.Key, o.Value); + } + } + + public List GetPropertyNames() + { + return _propertyNames; + } + + public List GetColumnNames() + { + return _columnNames; + } + + public string GetExtendColumnName() + { + return _extendColumnName; + } + + public ICollection GetKeys(bool excludeProperties = false, bool excludeDatabase = false) + { + var keys = new List(); + keys.AddRange(_extendDictionary.Keys); + + if (!excludeProperties) + { + foreach (var key in _propertyNames) + { + if (keys.Contains(key, StringComparer.OrdinalIgnoreCase) || excludeDatabase && _columnNames.Contains(key, StringComparer.OrdinalIgnoreCase)) continue; + + keys.Add(key); + } + } + + return keys; + } + + public IDictionary ToDictionary(List excludeKeys = null) + { + var dict = new Dictionary(StringComparer.OrdinalIgnoreCase); + foreach (var key in _extendDictionary.Keys) + { + if (excludeKeys != null && excludeKeys.Contains(key, StringComparer.OrdinalIgnoreCase)) continue; + + dict[key] = Get(key); + } + foreach (var key in _propertyNames) + { + if (excludeKeys != null && excludeKeys.Contains(key, StringComparer.OrdinalIgnoreCase)) continue; + + dict[key] = Get(key); + } + + return dict; + } + + public bool ContainsKey(string key) + { + return _extendDictionary.ContainsKey(key) || _propertyNames.Contains(key, StringComparer.OrdinalIgnoreCase); + } + + public void Sync(string json) + { + var dict = TranslateUtils.ToDictionary(json); + foreach (var o in dict) + { + if (!_columnNames.Contains(o.Key, StringComparer.OrdinalIgnoreCase)) + { + Set(o.Key, o.Value); + } + } + } + + private bool ContainsIgnoreCase(IEnumerable list, string name, out string realName) + { + realName = null; + foreach (var x in list) + { + if (!StringComparer.OrdinalIgnoreCase.Equals(x, name)) continue; + + realName = x; + return true; + } + + return false; + } + + public void Set(string name, object value) + { + if (string.IsNullOrEmpty(name)) return; + + if (ContainsIgnoreCase(_propertyNames, name, out var realName)) + { + ReflectionUtils.SetValue(this, realName, value); + } + else + { + _extendDictionary[name] = value; + } + + + + //if (!string.IsNullOrEmpty(_extendAttribute)) + //{ + // ReflectionUtils.SetValue(this, _extendAttribute, TranslateUtils.JsonSerialize(Dictionary)); + //} + + //if (StringUtils.EqualsIgnoreCase(_extendAttribute, name)) + //{ + // var dict = GetExtendValue(value as string); + // if (dict != null) + // { + // foreach (var entry in dict) + // { + // if (!_entityAttributes.Contains(entry.Key, StringComparer.OrdinalIgnoreCase)) + // { + // Dictionary[entry.Key] = entry.Value; + // } + // } + // } + + // SetExtendValue(); + //} + //else if (!_entityAttributes.Contains(name, StringComparer.OrdinalIgnoreCase)) + //{ + // SetExtendValue(); + //} + + //if (_entityAttributes.Contains(name, StringComparer.OrdinalIgnoreCase)) + //{ + // ReflectionUtils.SetValue(this, name, value); + //} + //else + //{ + // _dictionary[name] = value; + // if (!string.IsNullOrEmpty(_extendAttribute)) + // { + // ReflectionUtils.SetValue(this, _extendAttribute, TranslateUtils.JsonSerialize(_dictionary)); + // } + //} + } + + public object Get(string name) + { + if (string.IsNullOrEmpty(name)) return null; + + return ContainsIgnoreCase(_propertyNames, name, out var realName) + ? ReflectionUtils.GetValue(this, realName) + : TranslateUtils.Get(_extendDictionary, name); + } + + public T Get(string name, T defaultValue = default(T)) + { + return TranslateUtils.Get(Get(name), defaultValue); + } + + #region DynamicObject + + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + result = Get(binder.Name); + return true; + } + + public override bool TrySetMember(SetMemberBinder binder, object value) + { + Set(binder.Name, value); + return true; + } + + #endregion + } + + public class DynamicEntityConverter : JsonConverter + { + public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) + { + throw new NotImplementedException(); + } + + /// + /// 确定此实例是否可以转换指定的对象类型。 + /// + /// 对象实例 + /// + /// true 如果这个实例可以转换指定的对象类型; 否则, false。 + /// + public override bool CanConvert(Type objectType) + { + return objectType.BaseType == typeof(DynamicEntity); + } + + /// + /// 编写对象的JSON表示。 + /// + /// JsonWriter + /// 值 + /// 序列化类 + public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) + { + var entity = value as DynamicEntity; + serializer.Serialize(writer, entity?.ToDictionary()); + } + + ///// + ///// 读取对象的JSON表示。 + ///// + ///// JsonReader + ///// 对象类型 + ///// 正在读取的对象的现有值 + ///// 序列化类 + ///// 返回对象 + //public override object ReadJson(JsonReader reader, Type objectType, object existingValue, + // JsonSerializer serializer) + //{ + // var value = (string)reader.Value; + // return string.IsNullOrEmpty(value) ? null : new DataType(value); + //} + } +} diff --git a/net452/SiteServer.CMS/Database/Wrapper/DynamicExtend.cs b/net452/SiteServer.CMS/Database/Wrapper/DynamicExtend.cs new file mode 100644 index 000000000..6adca0bf6 --- /dev/null +++ b/net452/SiteServer.CMS/Database/Wrapper/DynamicExtend.cs @@ -0,0 +1,110 @@ +using System; +using System.Collections.Generic; +using System.Dynamic; +using System.Linq; +using SiteServer.CMS.Database.Core; +using SiteServer.Utils; + +namespace SiteServer.CMS.Database.Wrapper +{ + public class DynamicExtend : DynamicObject where TEntity : class, IEntity, new() where TExtend : class, IExtend, new() + { + private const string AttrExtend1 = "SettingsXml"; + private const string AttrExtend2 = "ExtendValues"; + + public TEntity Entity { get; } + public TExtend Extend { get; } + private readonly List _entityAttributes = new List(); + private readonly List _extendAttributes = new List(); + + public DynamicExtend(TEntity obj) + { + if (obj == null) return; + + Entity = obj; + + _entityAttributes = ReflectionUtils.GetTypeProperties(typeof(TEntity)).Select(x => x.Name).ToList(); + _extendAttributes = ReflectionUtils.GetTypeProperties(typeof(TExtend)).Select(x => x.Name).ToList(); + + var extendAttributeName = _entityAttributes.FirstOrDefault(x => + StringUtils.EqualsIgnoreCase(x, AttrExtend1) || + StringUtils.EqualsIgnoreCase(x, AttrExtend2)); + if (!string.IsNullOrEmpty(extendAttributeName)) + { + var json = ReflectionUtils.GetValue(obj, extendAttributeName); + if (string.IsNullOrEmpty(json)) + { + var extendDictionary = TranslateUtils.JsonDeserialize>(json); + Extend = ReflectionUtils.ToObject(extendDictionary); + } + } + + //var tableColumns = ReflectionUtils.GetTableColumns(typeof(T)); + + //var extendColumn = tableColumns.FirstOrDefault(x => + // StringUtils.EqualsIgnoreCase(x.AttributeName, AttrExtend1) || + // StringUtils.EqualsIgnoreCase(x.AttributeName, AttrExtend2)); + //if (extendColumn != null) + //{ + // var json = ReflectionUtils.GetValue(obj, extendColumn.AttributeName); + // if (string.IsNullOrEmpty(json)) + // { + // var extendDictionary = TranslateUtils.JsonDeserialize>(json); + // Extend = ReflectionUtils.ToObject(extendDictionary); + // } + //} + } + + // If you try to get a value of a property + // not defined in the class, this method is called. + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + // Converting the property name to lowercase + // so that property names become case-insensitive. + var attributeName = binder.Name; + + if (_entityAttributes.Contains(attributeName, StringComparer.OrdinalIgnoreCase)) + { + return ReflectionUtils.GetValue(Entity, attributeName, out result); + + } + + if (_extendAttributes.Contains(attributeName, StringComparer.OrdinalIgnoreCase)) + { + return ReflectionUtils.GetValue(Extend, attributeName, out result); + } + + // If the property name is found in a dictionary, + // set the result parameter to the property value and return true. + // Otherwise, return false. + result = null; + return true; + } + + // If you try to set a value of a property that is + // not defined in the class, this method is called. + public override bool TrySetMember(SetMemberBinder binder, object value) + { + var attributeName = binder.Name; + + if (_entityAttributes.Contains(attributeName, StringComparer.OrdinalIgnoreCase)) + { + ReflectionUtils.SetValue(Entity, attributeName, value); + } + else if (_extendAttributes.Contains(attributeName, StringComparer.OrdinalIgnoreCase)) + { + ReflectionUtils.SetValue(Extend, attributeName, value); + } + //else + //{ + // // Converting the property name to lowercase + // // so that property names become case-insensitive. + // _dictionary[binder.Name] = value; + //} + + // You can always add a value to a dictionary, + // so this method always returns true. + return true; + } + } +} diff --git a/net452/SiteServer.CMS/Database/Wrapper/DynamicWrapper.cs b/net452/SiteServer.CMS/Database/Wrapper/DynamicWrapper.cs new file mode 100644 index 000000000..e813a940b --- /dev/null +++ b/net452/SiteServer.CMS/Database/Wrapper/DynamicWrapper.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Dynamic; +using System.Linq; +using Newtonsoft.Json; + +namespace SiteServer.CMS.Database.Wrapper +{ + public class DynamicWrapper : DynamicObject where T : class, new() + { + public DynamicWrapper(T obj, bool isJsonIgnore = false) + { + if (obj == null) return; + + foreach (var property in typeof(T).GetProperties()) + { + if (!property.CanRead) continue; + if (isJsonIgnore && property.GetCustomAttributes(true).Any(a => a is JsonIgnoreAttribute)) continue; + + Set(property.Name, property.GetValue(obj, null)); + } + } + + public DynamicWrapper(Dictionary dict) + { + if (dict == null) return; + + foreach (var key in dict.Keys) + { + Set(key, dict[key]); + } + } + + // The inner dictionary. + private readonly Dictionary _dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); + + public IDictionary ToDictionary() + { + var ret = new Dictionary(_dictionary.Count, _dictionary.Comparer); + foreach (var entry in _dictionary) + { + ret.Add(entry.Key, entry.Value); + } + return ret; + } + + public void Remove(string key) + { + if (string.IsNullOrEmpty(key)) return; + + _dictionary.Remove(key); + } + + public void Set(string name, object value) + { + if (string.IsNullOrEmpty(name)) return; + + _dictionary[name] = value; + } + + public bool ContainsKey(string key) + { + if (string.IsNullOrEmpty(key)) return false; + + return _dictionary.ContainsKey(key); + } + + public object Get(string key) + { + if (string.IsNullOrEmpty(key)) return null; + + return _dictionary.TryGetValue(key, out var value) ? value : null; + } + + // If you try to get a value of a property + // not defined in the class, this method is called. + public override bool TryGetMember(GetMemberBinder binder, out object result) + { + // Converting the property name to lowercase + // so that property names become case-insensitive. + var name = binder.Name; + + // If the property name is found in a dictionary, + // set the result parameter to the property value and return true. + // Otherwise, return false. + return _dictionary.TryGetValue(name, out result); + } + + // If you try to set a value of a property that is + // not defined in the class, this method is called. + public override bool TrySetMember(SetMemberBinder binder, object value) + { + // Converting the property name to lowercase + // so that property names become case-insensitive. + _dictionary[binder.Name] = value; + + // You can always add a value to a dictionary, + // so this method always returns true. + return true; + } + } +} diff --git a/net452/SiteServer.CMS/Env.cs b/net452/SiteServer.CMS/Env.cs new file mode 100644 index 000000000..5cc6b49a6 --- /dev/null +++ b/net452/SiteServer.CMS/Env.cs @@ -0,0 +1,17 @@ +using System; +using System.Net.Http; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Utils; + +namespace SiteServer.CMS +{ + public static class Env + { + public static string AdminUrl => PageUtils.Combine(FxUtils.ApplicationPath, WebConfigUtils.AdminDirectory).TrimEnd('/'); + + public static string ApiUrl => ApiManager.InnerApiUrl.TrimEnd('/'); + } +} diff --git a/SiteServer.Utils/CacheUtils.cs b/net452/SiteServer.CMS/Fx/CacheUtils.cs similarity index 82% rename from SiteServer.Utils/CacheUtils.cs rename to net452/SiteServer.CMS/Fx/CacheUtils.cs index bb2ff7f3a..7eda2057e 100644 --- a/SiteServer.Utils/CacheUtils.cs +++ b/net452/SiteServer.CMS/Fx/CacheUtils.cs @@ -4,12 +4,10 @@ using System.Web; using System.Web.Caching; -namespace SiteServer.Utils +namespace SiteServer.CMS.Fx { - public class CacheUtils + public static class CacheUtils { - private CacheUtils() { } - private static readonly Cache Cache; /// @@ -24,6 +22,8 @@ static CacheUtils() public static void ClearAll() { + if (Cache == null) return; + var cacheEnum = Cache.GetEnumerator(); var keys = new List(); while (cacheEnum.MoveNext()) @@ -45,8 +45,10 @@ public static void RemoveByStartString(string startString) } } - public static void RemoveByPattern(string pattern) + private static void RemoveByPattern(string pattern) { + if (Cache == null) return; + var cacheEnum = Cache.GetEnumerator(); var regex = new Regex(pattern, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled); while (cacheEnum.MoveNext()) @@ -64,7 +66,7 @@ public static void RemoveByPattern(string pattern) /// public static void Remove(string key) { - Cache.Remove(key); + Cache?.Remove(key); } public static void Insert(string key, object obj) @@ -72,9 +74,14 @@ public static void Insert(string key, object obj) InnerInsert(key, obj, null, Cache.NoSlidingExpiration); } - public static void InsertMinutes(string key, object obj, int minutes) + public static void Insert(string key, object obj, string filePath) { - InnerInsert(key, obj, null, TimeSpan.FromMinutes(minutes)); + InnerInsert(key, obj, filePath, Cache.NoSlidingExpiration); + } + + public static void Insert(string key, object obj, TimeSpan timeSpan, string filePath) + { + InnerInsert(key, obj, filePath, timeSpan); } public static void InsertHours(string key, object obj, int hours) @@ -82,18 +89,20 @@ public static void InsertHours(string key, object obj, int hours) InnerInsert(key, obj, null, TimeSpan.FromHours(hours)); } - public static void Insert(string key, object obj, string filePath) + public static void InsertMinutes(string key, object obj, int minutes) { - InnerInsert(key, obj, filePath, Cache.NoSlidingExpiration); + InnerInsert(key, obj, null, TimeSpan.FromMinutes(minutes)); } - public static void Insert(string key, object obj, TimeSpan timeSpan, string filePath) + public static void InsertSeconds(string key, object obj, int seconds) { - InnerInsert(key, obj, filePath, timeSpan); + InnerInsert(key, obj, null, TimeSpan.FromSeconds(seconds)); } private static void InnerInsert(string key, object obj, string filePath, TimeSpan timeSpan) { + if (Cache == null) return; + if (string.IsNullOrEmpty(key)) return; Cache.Remove(key); @@ -103,14 +112,9 @@ private static void InnerInsert(string key, object obj, string filePath, TimeSpa } } - public static bool IsCache(string key) - { - return Cache.Get(key) != null; - } - public static object Get(string key) { - return Cache.Get(key); + return Cache?.Get(key); } public static int GetInt(string key, int notFound) @@ -135,7 +139,19 @@ public static DateTime GetDateTime(string key, DateTime notFound) public static T Get(string key) where T : class { - return Cache.Get(key) as T; + return Cache?.Get(key) as T; + } + + public static bool Exists(string key) + { + var val = Cache?.Get(key); + return val != null; + } + + public static bool Exists(string key) where T : class + { + var val = Cache?.Get(key) as T; + return val != null; } public static List AllKeys @@ -144,6 +160,8 @@ public static List AllKeys { var keys = new List(); + if (Cache == null) return keys; + var cacheEnum = Cache.GetEnumerator(); while (cacheEnum.MoveNext()) { @@ -154,6 +172,6 @@ public static List AllKeys } } - public static int Count => Cache.Count; + public static int Count => Cache?.Count ?? 0; } } diff --git a/net452/SiteServer.CMS/Fx/ControlUtils.cs b/net452/SiteServer.CMS/Fx/ControlUtils.cs new file mode 100644 index 000000000..b5f8f2d60 --- /dev/null +++ b/net452/SiteServer.CMS/Fx/ControlUtils.cs @@ -0,0 +1,89 @@ +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Text; +using System.Web.UI; +using System.Web.UI.WebControls; +using SiteServer.Utils; + +namespace SiteServer.CMS.Fx +{ + /// + /// 对控件的帮助类 + /// + public class ControlUtils + { + private ControlUtils() + { + + } + + /// + /// 得到代表控件的HTML代码 + /// + /// 控件 + /// + public static string GetControlRenderHtml(Control control) + { + if (control == null) return string.Empty; + + var builder = new StringBuilder(); + var sw = new System.IO.StringWriter(builder); + var htw = new HtmlTextWriter(sw); + control.RenderControl(htw); + return builder.ToString(); + } + + /// + /// 如果此控件不存在此属性,将属性添加到控件中 + /// + /// 控件 + /// 属性集合 + public static void AddAttributesIfNotExists(IAttributeAccessor accessor, NameValueCollection attributes) + { + if (accessor == null || attributes == null) return; + + foreach (var key in attributes.AllKeys) + { + if (accessor.GetAttribute(key) == null) + { + accessor.SetAttribute(key, attributes[key]); + } + } + } + + /// + /// 如果此控件不存在此属性,将属性添加到控件中 + /// + /// + /// + /// + public static void AddAttributeIfNotExists(IAttributeAccessor accessor, string attributeName, string attributeValue) + { + if (accessor == null || attributeName == null) return; + + if (accessor.GetAttribute(attributeName) == null) + { + accessor.SetAttribute(attributeName, attributeValue); + } + } + + /// + /// 将属性添加到控件中 + /// + /// + /// + /// + public static void AddAttribute(IAttributeAccessor accessor, string attributeName, string attributeValue) + { + if (accessor != null && attributeName != null) + { + accessor.SetAttribute(attributeName, attributeValue); + } + } + + + + + } +} diff --git a/net452/SiteServer.CMS/Fx/CookieUtils.cs b/net452/SiteServer.CMS/Fx/CookieUtils.cs new file mode 100644 index 000000000..e20f35447 --- /dev/null +++ b/net452/SiteServer.CMS/Fx/CookieUtils.cs @@ -0,0 +1,61 @@ +using System; +using System.Web; +using SiteServer.Utils; + +namespace SiteServer.CMS.Fx +{ + public static class CookieUtils + { + public static void SetCookie(string name, string value, TimeSpan expiresAt, bool isEncrypt = true) + { + SetCookie(new HttpCookie(name) + { + Value = value, + Expires = DateUtils.GetExpiresAt(expiresAt), + Domain = FxUtils.HttpContextRootDomain + }, isEncrypt); + } + + public static void SetCookie(string name, string value, bool isEncrypt = true) + { + SetCookie(new HttpCookie(name) + { + Value = value, + Domain = FxUtils.HttpContextRootDomain + }, isEncrypt); + } + + private static void SetCookie(HttpCookie cookie, bool isEncrypt) + { + cookie.Value = isEncrypt ? TranslateUtils.EncryptStringBySecretKey(cookie.Value) : cookie.Value; + cookie.HttpOnly = false; + + if (HttpContext.Current.Request.Url.Scheme.Equals("https")) + { + cookie.Secure = true;//通过https传递cookie + } + HttpContext.Current.Response.Cookies.Add(cookie); + } + + public static string GetCookie(string name, bool isDecrypt = true) + { + if (HttpContext.Current.Request.Cookies[name] == null) return string.Empty; + + var value = HttpContext.Current.Request.Cookies[name].Value; + return isDecrypt ? TranslateUtils.DecryptStringBySecretKey(value) : value; + } + + public static bool IsExists(string name) + { + return HttpContext.Current.Request.Cookies[name] != null; + } + + public static void Erase(string name) + { + if (HttpContext.Current.Request.Cookies[name] != null) + { + SetCookie(name, string.Empty, TimeSpan.FromDays(-1)); + } + } + } +} diff --git a/SiteServer.Utils/DirectoryTreeItem.cs b/net452/SiteServer.CMS/Fx/DirectoryTreeItem.cs similarity index 99% rename from SiteServer.Utils/DirectoryTreeItem.cs rename to net452/SiteServer.CMS/Fx/DirectoryTreeItem.cs index 825fa2b1b..c81ea9080 100644 --- a/SiteServer.Utils/DirectoryTreeItem.cs +++ b/net452/SiteServer.CMS/Fx/DirectoryTreeItem.cs @@ -1,6 +1,8 @@ using System.Text; +using SiteServer.CMS.Core; +using SiteServer.Utils; -namespace SiteServer.Utils +namespace SiteServer.CMS.Fx { public class DirectoryTreeItem { diff --git a/SiteServer.Utils/IO/FileManager.cs b/net452/SiteServer.CMS/Fx/FileManager.cs similarity index 79% rename from SiteServer.Utils/IO/FileManager.cs rename to net452/SiteServer.CMS/Fx/FileManager.cs index 222cdf2f7..7adefb0e0 100644 --- a/SiteServer.Utils/IO/FileManager.cs +++ b/net452/SiteServer.CMS/Fx/FileManager.cs @@ -1,15 +1,16 @@ using System.IO; +using SiteServer.Utils.IO; -namespace SiteServer.Utils.IO +namespace SiteServer.CMS.Fx { - public class FileManager + public static class FileManager { public static FileSystemInfoExtendCollection GetFileSystemInfoExtendCollection(string rootPath, bool reflesh) { FileSystemInfoExtendCollection retval = null; if (Directory.Exists(rootPath)) { - string cacheKey = $"BaiRong.Core.IO.FileManagement.FileManager:{rootPath}"; + string cacheKey = $"SiteServer.Utils.IO.FileManager:{rootPath}"; if (CacheUtils.Get(cacheKey) == null || reflesh) { var currentRoot = new DirectoryInfo(rootPath); diff --git a/net452/SiteServer.CMS/Fx/FxUtils.cs b/net452/SiteServer.CMS/Fx/FxUtils.cs new file mode 100644 index 000000000..91dc7fe53 --- /dev/null +++ b/net452/SiteServer.CMS/Fx/FxUtils.cs @@ -0,0 +1,830 @@ +using System; +using System.Collections.Specialized; +using System.Text.RegularExpressions; +using System.Web; +using System.Web.UI.WebControls; +using Datory; +using SiteServer.CMS.Core; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Fx +{ + public static class FxUtils + { + public static HorizontalAlign ToHorizontalAlign(string typeStr) + { + return (HorizontalAlign)ToEnum(typeof(HorizontalAlign), typeStr, HorizontalAlign.Left); + } + + public static VerticalAlign ToVerticalAlign(string typeStr) + { + return (VerticalAlign)ToEnum(typeof(VerticalAlign), typeStr, VerticalAlign.Middle); + } + + public static GridLines ToGridLines(string typeStr) + { + return (GridLines)ToEnum(typeof(GridLines), typeStr, GridLines.None); + } + + public static RepeatDirection ToRepeatDirection(string typeStr) + { + return (RepeatDirection)ToEnum(typeof(RepeatDirection), typeStr, RepeatDirection.Vertical); + } + + public static RepeatLayout ToRepeatLayout(string typeStr) + { + return (RepeatLayout)ToEnum(typeof(RepeatLayout), typeStr, RepeatLayout.Table); + } + + public static object ToEnum(Type enumType, string value, object defaultType) + { + object retVal; + try + { + retVal = Enum.Parse(enumType, value, true); + } + catch + { + retVal = defaultType; + } + return retVal; + } + + public static Unit ToUnit(string unitStr) + { + var type = Unit.Empty; + try + { + type = Unit.Parse(unitStr.Trim()); + } + catch + { + // ignored + } + return type; + } + + public static ListItem GetListItem(DatabaseType type, bool selected) + { + var item = new ListItem(type.Value, type.Value); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddListItemsToDatabaseType(ListControl listControl) + { + if (listControl == null) return; + listControl.Items.Add(GetListItem(DatabaseType.MySql, false)); + listControl.Items.Add(GetListItem(DatabaseType.SqlServer, false)); + listControl.Items.Add(GetListItem(DatabaseType.PostgreSql, false)); + listControl.Items.Add(GetListItem(DatabaseType.Oracle, false)); + } + + public static string GetHost() + { + var host = string.Empty; + if (HttpContext.Current == null) return string.IsNullOrEmpty(host) ? string.Empty : host.Trim().ToLower(); + host = HttpContext.Current.Request.Headers["HOST"]; + if (string.IsNullOrEmpty(host)) + { + host = HttpContext.Current.Request.Url.Host; + } + + return string.IsNullOrEmpty(host) ? string.Empty : host.Trim().ToLower(); + } + + public static string GetScheme() + { + var scheme = string.Empty; + if (HttpContext.Current != null) + { + scheme = HttpContext.Current.Request.Headers["SCHEME"]; + if (string.IsNullOrEmpty(scheme)) + { + scheme = HttpContext.Current.Request.Url.Scheme; + } + } + + return string.IsNullOrEmpty(scheme) ? "http" : scheme.Trim().ToLower(); + } + + public static string ApplicationPath => HttpContext.Current != null && !string.IsNullOrEmpty(HttpContext.Current.Request.ApplicationPath) ? HttpContext.Current.Request.ApplicationPath : "/"; + + // 系统根目录访问地址 + public static string GetRootUrl(string relatedUrl) + { + return PageUtils.Combine(ApplicationPath, relatedUrl); + } + + public static string HttpContextRootDomain + { + get + { + var url = HttpContext.Current.Request.Url; + + if (url.HostNameType != UriHostNameType.Dns) return url.Host; + + var match = Regex.Match(url.Host, "([^.]+\\.[^.]{1,3}(\\.[^.]{1,3})?)$"); + return match.Groups[1].Success ? match.Groups[1].Value : null; + } + } + + public static string GetIpAddress() + { + var result = string.Empty; + + try + { + //取CDN用户真实IP的方法 + //当用户使用代理时,取到的是代理IP + result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; + if (!string.IsNullOrEmpty(result)) + { + //可能有代理 + if (result.IndexOf(".", StringComparison.Ordinal) == -1) + result = null; + else + { + if (result.IndexOf(",", StringComparison.Ordinal) != -1) + { + result = result.Replace(" ", "").Replace("'", ""); + var temparyip = result.Split(",;".ToCharArray()); + foreach (var t in temparyip) + { + if (PageUtils.IsIpAddress(t) && t.Substring(0, 3) != "10." && t.Substring(0, 7) != "192.168" && t.Substring(0, 7) != "172.16.") + { + result = t; + } + } + var str = result.Split(','); + if (str.Length > 0) + result = str[0].Trim(); + } + else if (PageUtils.IsIpAddress(result)) + return result; + } + } + + if (string.IsNullOrEmpty(result)) + result = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"]; + if (string.IsNullOrEmpty(result)) + result = HttpContext.Current.Request.UserHostAddress; + if (string.IsNullOrEmpty(result)) + result = "localhost"; + + if (result == "::1" || result == "127.0.0.1") + { + result = "localhost"; + } + } + catch + { + // ignored + } + + return result; + } + + public static string SessionId + { + get + { + var sessionId = CookieUtils.GetCookie("SiteServer.SessionID"); + if (!string.IsNullOrEmpty(sessionId)) return sessionId; + long i = 1; + foreach (var b in Guid.NewGuid().ToByteArray()) + { + i *= b + 1; + } + sessionId = $"{i - DateTime.Now.Ticks:x}"; + CookieUtils.SetCookie("SiteServer.SessionID", sessionId, TimeSpan.FromDays(100)); + return sessionId; + } + } + + public static string GetRefererUrl() + { + var url = HttpContext.Current.Request.ServerVariables["HTTP_REFERER"]; + return url; + } + + public static string GetReturnUrl() + { + return GetReturnUrl(true); + } + + public static string GetReturnUrl(bool toReferer) + { + var redirectUrl = string.Empty; + if (!string.IsNullOrEmpty(HttpContext.Current.Request.QueryString["ReturnUrl"])) + { + redirectUrl = ParseNavigationUrl(HttpContext.Current.Request.QueryString["ReturnUrl"]); + } + else if (toReferer) + { + var referer = GetRefererUrl(); + redirectUrl = !string.IsNullOrEmpty(referer) ? referer : GetHost(); + } + return redirectUrl; + } + + public static string GetAdminUrl(string relatedUrl) + { + return PageUtils.Combine(ApplicationPath, WebConfigUtils.AdminDirectory, relatedUrl); + } + + public static string GetHomeUrl(string relatedUrl) + { + return PageUtils.Combine(ApplicationPath, WebConfigUtils.HomeDirectory, relatedUrl); + } + + public static string GetSiteFilesUrl(string relatedUrl) + { + return PageUtils.Combine(ApplicationPath, DirectoryUtils.SiteFiles.DirectoryName, relatedUrl); + } + + public static string GetTemporaryFilesUrl(string relatedUrl) + { + return PageUtils.Combine(ApplicationPath, DirectoryUtils.SiteFiles.DirectoryName, DirectoryUtils.SiteFiles.TemporaryFiles, relatedUrl); + } + + public static string GetSiteTemplatesUrl(string relatedUrl) + { + return PageUtils.Combine(ApplicationPath, DirectoryUtils.SiteFiles.DirectoryName, DirectoryUtils.SiteTemplates.DirectoryName, relatedUrl); + } + + public static string GetSiteTemplateMetadataUrl(string siteTemplateUrl, string relatedUrl) + { + return PageUtils.Combine(siteTemplateUrl, DirectoryUtils.SiteTemplates.SiteTemplateMetadata, relatedUrl); + } + + public static string ParsePluginUrl(string pluginId, string url) + { + if (string.IsNullOrEmpty(url)) return string.Empty; + + if (PageUtils.IsProtocolUrl(url)) return url; + + if (StringUtils.StartsWith(url, "~/")) + { + return GetRootUrl(url.Substring(1)); + } + + if (StringUtils.StartsWith(url, "@/")) + { + return GetAdminUrl(url.Substring(1)); + } + + return GetSiteFilesUrl(PageUtils.Combine(DirectoryUtils.SiteFiles.Plugins, pluginId, url)); + } + + public static string GetSiteServerUrl(string className, NameValueCollection queryString) + { + return PageUtils.AddQueryString(GetAdminUrl(className.ToCamelCase() + ".aspx"), queryString); + } + + public static string GetSettingsUrl(string className, NameValueCollection queryString) + { + return PageUtils.AddQueryString(GetAdminUrl(PageUtils.Combine("Settings", className.ToCamelCase() + ".aspx")), queryString); + } + + public static string GetCmsUrl(int siteId, string className, NameValueCollection queryString) + { + queryString = queryString ?? new NameValueCollection(); + queryString.Remove("siteId"); + return PageUtils.AddQueryString(GetAdminUrl($"Cms/{className.ToCamelCase()}.aspx?siteId={siteId}"), queryString); + } + + public static string GetCmsWebHandlerUrl(int siteId, string className, NameValueCollection queryString) + { + queryString = queryString ?? new NameValueCollection(); + queryString.Remove("siteId"); + return PageUtils.AddQueryString(GetAdminUrl($"Cms/{className.ToCamelCase()}.ashx?siteId={siteId}"), queryString); + } + + public static string GetAjaxUrl(string className, NameValueCollection queryString) + { + return PageUtils.AddQueryString(GetAdminUrl(PageUtils.Combine("ajax", className.ToLower() + ".aspx")), queryString); + } + + public static string GetRootUrlByPhysicalPath(string physicalPath) + { + var requestPath = PathUtils.GetPathDifference(WebConfigUtils.PhysicalApplicationPath, physicalPath); + requestPath = requestPath.Replace(PathUtils.SeparatorChar, PageUtils.SeparatorChar); + return GetRootUrl(requestPath); + } + + public static string ParseNavigationUrl(string url) + { + if (string.IsNullOrEmpty(url)) return string.Empty; + + url = url.StartsWith("~") ? PageUtils.Combine(ApplicationPath, url.Substring(1)) : url; + url = url.Replace(PathUtils.SeparatorChar, PageUtils.SeparatorChar); + return url; + } + + /// + /// 按照给定的host,添加Protocol + /// Demo: 发送的邮件中,需要内容标题的链接为全连接,那么需要指定他的host + /// + /// + /// + /// + public static string AddProtocolToUrl(string url, string host) + { + if (url == PageUtils.UnClickedUrl) + { + return url; + } + var retval = string.Empty; + + if (!string.IsNullOrEmpty(url)) + { + url = url.Trim(); + if (PageUtils.IsProtocolUrl(url)) + { + retval = url; + } + else + { + if (string.IsNullOrEmpty(host)) + { + retval = url.StartsWith("/") ? GetScheme() + "://" + GetHost() + url : GetScheme() + "://" + url; + } + else + { + retval = url.StartsWith("/") ? host.TrimEnd('/') + url : host + url; + } + } + } + return retval; + } + + public static string AddProtocolToUrl(string url) + { + return AddProtocolToUrl(url, string.Empty); + } + + public static string GetUrlWithReturnUrl(string pageUrl, string returnUrl) + { + var retval = pageUrl; + returnUrl = $"ReturnUrl={returnUrl}"; + if (pageUrl.IndexOf("?", StringComparison.Ordinal) != -1) + { + if (pageUrl.EndsWith("&")) + { + retval += returnUrl; + } + else + { + retval += "&" + returnUrl; + } + } + else + { + retval += "?" + returnUrl; + } + return ParseNavigationUrl(retval); + } + + + + public static string GetUrlByBaseUrl(string rawUrl, string baseUrl) + { + var url = string.Empty; + if (!string.IsNullOrEmpty(rawUrl)) + { + rawUrl = rawUrl.Trim().TrimEnd('#'); + } + if (!string.IsNullOrEmpty(baseUrl)) + { + baseUrl = baseUrl.Trim(); + } + if (!string.IsNullOrEmpty(rawUrl)) + { + rawUrl = rawUrl.Trim(); + if (PageUtils.IsProtocolUrl(rawUrl)) + { + url = rawUrl; + } + else if (rawUrl.StartsWith("/")) + { + var domain = PageUtils.GetUrlWithoutPathInfo(baseUrl); + url = domain + rawUrl; + } + else if (rawUrl.StartsWith("../")) + { + var count = StringUtils.GetStartCount("../", rawUrl); + rawUrl = rawUrl.Remove(0, 3 * count); + baseUrl = PageUtils.GetUrlWithoutFileName(baseUrl).TrimEnd('/'); + baseUrl = PageUtils.RemoveProtocolFromUrl(baseUrl); + for (var i = 0; i < count; i++) + { + var j = baseUrl.LastIndexOf('/'); + if (j != -1) + { + baseUrl = StringUtils.Remove(baseUrl, j); + } + else + { + break; + } + } + url = PageUtils.Combine(AddProtocolToUrl(baseUrl), rawUrl); + } + else + { + if (baseUrl != null && baseUrl.EndsWith("/")) + { + url = baseUrl + rawUrl; + } + else + { + var urlWithoutFileName = PageUtils.GetUrlWithoutFileName(baseUrl); + if (!urlWithoutFileName.EndsWith("/")) + { + urlWithoutFileName += "/"; + } + url = urlWithoutFileName + rawUrl; + } + } + } + return url; + } + + public static string ParseConfigRootUrl(string url) + { + return ParseNavigationUrl(url); + } + + public static string GetMainUrl(int siteId, string pageUrl) + { + var queryString = new NameValueCollection(); + if (siteId > 0) + { + queryString.Add("siteId", siteId.ToString()); + } + if (!string.IsNullOrEmpty(pageUrl)) + { + queryString.Add("pageUrl", PageUtils.UrlEncode(pageUrl)); + } + return PageUtils.AddQueryString(AdminPagesUtils.MainUrl, queryString); + } + + public static string GetLoadingUrl(string url) + { + return $"{AdminPagesUtils.LoadingUrl}?encryptedUrl={TranslateUtils.EncryptStringBySecretKey(url)}"; + } + + public static string GetLoadingUrl(int siteId, int channelId, int contentId) + { + return $"{AdminPagesUtils.LoadingUrl}?siteId={siteId}&channelId={channelId}&contentId={contentId}"; + } + + public static string GetMenusPath(params string[] paths) + { + return PageUtils.Combine(SiteServerAssets.GetPath("menus"), PageUtils.Combine(paths)); + } + + public static ListItem GetListItem(EBoolean type, bool selected) + { + var item = new ListItem(EBooleanUtils.GetText(type), EBooleanUtils.GetValue(type)); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddListItems(ListControl listControl) + { + if (listControl != null) + { + listControl.Items.Add(GetListItem(EBoolean.True, false)); + listControl.Items.Add(GetListItem(EBoolean.False, false)); + } + } + + public static void AddListItems(ListControl listControl, string trueText, string falseText) + { + if (listControl != null) + { + var item = new ListItem(trueText, EBooleanUtils.GetValue(EBoolean.True)); + listControl.Items.Add(item); + item = new ListItem(falseText, EBooleanUtils.GetValue(EBoolean.False)); + listControl.Items.Add(item); + } + } + + public static ListItem GetListItem(ECharset type, bool selected) + { + var item = new ListItem(ECharsetUtils.GetText(type), ECharsetUtils.GetValue(type)); + if (selected) + { + item.Selected = true; + } + return item; + } + + + public static void AddListItemsToECharset(ListControl listControl) + { + if (listControl != null) + { + listControl.Items.Add(GetListItem(ECharset.utf_8, false)); + listControl.Items.Add(GetListItem(ECharset.gb2312, false)); + listControl.Items.Add(GetListItem(ECharset.big5, false)); + listControl.Items.Add(GetListItem(ECharset.iso_8859_1, false)); + listControl.Items.Add(GetListItem(ECharset.euc_kr, false)); + listControl.Items.Add(GetListItem(ECharset.euc_jp, false)); + listControl.Items.Add(GetListItem(ECharset.iso_8859_6, false)); + listControl.Items.Add(GetListItem(ECharset.windows_874, false)); + listControl.Items.Add(GetListItem(ECharset.iso_8859_9, false)); + listControl.Items.Add(GetListItem(ECharset.iso_8859_5, false)); + listControl.Items.Add(GetListItem(ECharset.iso_8859_8, false)); + listControl.Items.Add(GetListItem(ECharset.iso_8859_7, false)); + listControl.Items.Add(GetListItem(ECharset.windows_1258, false)); + listControl.Items.Add(GetListItem(ECharset.iso_8859_2, false)); + } + } + + public static ListItem GetListItem(EDataFormat type, bool selected) + { + var item = new ListItem(EDataFormatUtils.GetText(type), EDataFormatUtils.GetValue(type)); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddListItemsToEDataFormat(ListControl listControl) + { + if (listControl != null) + { + listControl.Items.Add(GetListItem(EDataFormat.String, false)); + listControl.Items.Add(GetListItem(EDataFormat.Json, false)); + listControl.Items.Add(GetListItem(EDataFormat.Xml, false)); + } + } + + public static ListItem GetListItem(EDateFormatType type, bool selected) + { + var item = new ListItem(EDateFormatTypeUtils.GetText(type), EDateFormatTypeUtils.GetValue(type)); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddListItemsToEDateFormatType(ListControl listControl) + { + if (listControl != null) + { + listControl.Items.Add(GetListItem(EDateFormatType.Month, false)); + listControl.Items.Add(GetListItem(EDateFormatType.Day, false)); + listControl.Items.Add(GetListItem(EDateFormatType.Year, false)); + listControl.Items.Add(GetListItem(EDateFormatType.Chinese, false)); + } + } + + public static ListItem GetListItem(EFileSystemType type, bool selected) + { + var item = new ListItem(EFileSystemTypeUtils.GetValue(type), EFileSystemTypeUtils.GetValue(type)); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddListItemsToEFileSystemType(ListControl listControl) + { + if (listControl != null) + { + listControl.Items.Add(GetListItem(EFileSystemType.Html, false)); + listControl.Items.Add(GetListItem(EFileSystemType.Htm, false)); + listControl.Items.Add(GetListItem(EFileSystemType.SHtml, false)); + listControl.Items.Add(GetListItem(EFileSystemType.Xml, false)); + listControl.Items.Add(GetListItem(EFileSystemType.Json, false)); + } + } + + public static ListItem GetListItem(EPredefinedRole type, bool selected) + { + var item = new ListItem(EPredefinedRoleUtils.GetText(type), EPredefinedRoleUtils.GetValue(type)); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static ListItem GetListItem(EScopeType type, bool selected) + { + var item = new ListItem(EScopeTypeUtils.GetValue(type) + " (" + EScopeTypeUtils.GetText(type) + ")", EScopeTypeUtils.GetValue(type)); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddListItemsToEScopeType(ListControl listControl) + { + if (listControl != null) + { + listControl.Items.Add(GetListItem(EScopeType.Self, false)); + listControl.Items.Add(GetListItem(EScopeType.Children, false)); + listControl.Items.Add(GetListItem(EScopeType.SelfAndChildren, false)); + listControl.Items.Add(GetListItem(EScopeType.Descendant, false)); + listControl.Items.Add(GetListItem(EScopeType.All, false)); + } + } + + public static ListItem GetListItem(EStatictisXType type, bool selected) + { + var item = new ListItem(EStatictisXTypeUtils.GetText(type), EStatictisXTypeUtils.GetValue(type)); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddListItemsToEStatictisXType(ListControl listControl) + { + if (listControl != null) + { + listControl.Items.Add(GetListItem(EStatictisXType.Day, false)); + listControl.Items.Add(GetListItem(EStatictisXType.Month, false)); + listControl.Items.Add(GetListItem(EStatictisXType.Year, false)); + } + } + + public static void AddListItemsToETriState(ListControl listControl, string allText, string trueText, string falseText) + { + if (listControl != null) + { + var item = new ListItem(allText, ETriStateUtils.GetValue(ETriState.All)); + listControl.Items.Add(item); + item = new ListItem(trueText, ETriStateUtils.GetValue(ETriState.True)); + listControl.Items.Add(item); + item = new ListItem(falseText, ETriStateUtils.GetValue(ETriState.False)); + listControl.Items.Add(item); + } + } + + public static ListItem GetListItem(EUserPasswordRestriction type, bool selected) + { + var item = new ListItem(EUserPasswordRestrictionUtils.GetText(type), EUserPasswordRestrictionUtils.GetValue(type)); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddListItemsToEUserPasswordRestriction(ListControl listControl) + { + if (listControl != null) + { + listControl.Items.Add(GetListItem(EUserPasswordRestriction.None, false)); + listControl.Items.Add(GetListItem(EUserPasswordRestriction.LetterAndDigit, false)); + listControl.Items.Add(GetListItem(EUserPasswordRestriction.LetterAndDigitAndSymbol, false)); + } + } + + public static string GetCurrentPagePath() + { + if (HttpContext.Current != null) + { + return HttpContext.Current.Request.PhysicalPath; + } + return string.Empty; + } + + public static string MapPath(string virtualPath) + { + virtualPath = PathUtils.RemovePathInvalidChar(virtualPath); + string retVal; + if (!string.IsNullOrEmpty(virtualPath)) + { + if (virtualPath.StartsWith("~")) + { + virtualPath = virtualPath.Substring(1); + } + virtualPath = PageUtils.Combine("~", virtualPath); + } + else + { + virtualPath = "~/"; + } + if (HttpContext.Current != null) + { + retVal = HttpContext.Current.Server.MapPath(virtualPath); + } + else + { + var rootPath = WebConfigUtils.PhysicalApplicationPath; + + virtualPath = !string.IsNullOrEmpty(virtualPath) ? virtualPath.Substring(2) : string.Empty; + retVal = PathUtils.Combine(rootPath, virtualPath); + } + + if (retVal == null) retVal = string.Empty; + return retVal.Replace("/", "\\"); + } + + public static string GetSiteFilesPath(params string[] paths) + { + return MapPath(PathUtils.Combine("~/" + DirectoryUtils.SiteFiles.DirectoryName, PathUtils.Combine(paths))); + } + + public static string PluginsPath => GetSiteFilesPath(DirectoryUtils.SiteFiles.Plugins); + + public static string GetPluginPath(string pluginId, params string[] paths) + { + return GetSiteFilesPath(DirectoryUtils.SiteFiles.Plugins, pluginId, PathUtils.Combine(paths)); + } + + public static string GetPluginNuspecPath(string pluginId) + { + return GetPluginPath(pluginId, pluginId + ".nuspec"); + } + + public static string GetPluginDllDirectoryPath(string pluginId) + { + var fileName = pluginId + ".dll"; + + if (FileUtils.IsFileExists(GetPluginPath(pluginId, "Bin", fileName))) + { + return GetPluginPath(pluginId, "Bin"); + } + if (FileUtils.IsFileExists(GetPluginPath(pluginId, "Bin", "Debug", fileName))) + { + return GetPluginPath(pluginId, "Bin", "Debug"); + } + if (FileUtils.IsFileExists(GetPluginPath(pluginId, "Bin", "Release", fileName))) + { + return GetPluginPath(pluginId, "Bin", "Release"); + } + + return string.Empty; + } + + public static string GetPackagesPath(params string[] paths) + { + return GetSiteFilesPath(DirectoryUtils.SiteFiles.Packages, PathUtils.Combine(paths)); + } + + public static void GetValidateAttributesForListItem(ListControl control, bool isValidate, string displayName, bool isRequire, int minNum, int maxNum, string validateType, string regExp, string errorMessage) + { + if (!isValidate) return; + + control.Attributes.Add("isValidate", true.ToString().ToLower()); + control.Attributes.Add("displayName", displayName); + control.Attributes.Add("isRequire", isRequire.ToString().ToLower()); + control.Attributes.Add("minNum", minNum.ToString()); + control.Attributes.Add("maxNum", maxNum.ToString()); + control.Attributes.Add("validateType", validateType); + control.Attributes.Add("regExp", regExp); + control.Attributes.Add("errorMessage", errorMessage); + control.Attributes.Add("isListItem", true.ToString().ToLower()); + } + + public static ListItem GetListItem(ValidateType type, bool selected) + { + var item = new ListItem(ValidateTypeUtils.GetText(type), type.Value); + if (selected) + { + item.Selected = true; + } + return item; + } + + public static void AddListItemsToValidateType(ListControl listControl) + { + if (listControl != null) + { + listControl.Items.Add(GetListItem(ValidateType.None, false)); + listControl.Items.Add(GetListItem(ValidateType.Chinese, false)); + listControl.Items.Add(GetListItem(ValidateType.English, false)); + listControl.Items.Add(GetListItem(ValidateType.Email, false)); + listControl.Items.Add(GetListItem(ValidateType.Url, false)); + listControl.Items.Add(GetListItem(ValidateType.Phone, false)); + listControl.Items.Add(GetListItem(ValidateType.Mobile, false)); + listControl.Items.Add(GetListItem(ValidateType.Integer, false)); + listControl.Items.Add(GetListItem(ValidateType.Currency, false)); + listControl.Items.Add(GetListItem(ValidateType.Zip, false)); + listControl.Items.Add(GetListItem(ValidateType.IdCard, false)); + listControl.Items.Add(GetListItem(ValidateType.RegExp, false)); + } + } + } +} diff --git a/net452/SiteServer.CMS/Fx/ImageUtils.cs b/net452/SiteServer.CMS/Fx/ImageUtils.cs new file mode 100644 index 000000000..3240c63cd --- /dev/null +++ b/net452/SiteServer.CMS/Fx/ImageUtils.cs @@ -0,0 +1,497 @@ +using System; +using System.Drawing; +using System.Drawing.Drawing2D; +using System.Drawing.Imaging; +using System.IO; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Fx +{ + public static class ImageUtils + { + public static Image GetImage(string imageFilePath) + { + var fs = new FileStream(imageFilePath, FileMode.Open); + var br = new BinaryReader(fs); + var bytes = br.ReadBytes((int)fs.Length); + br.Close(); + fs.Close(); + var ms = new MemoryStream(bytes); + + var image = Image.FromStream(ms, false); + + return image; + } + + public static ImageFormat GetImageFormat(string imagePath) + { + var extName = PathUtils.GetExtension(imagePath).ToLower(); + switch (extName) + { + case ".bmp": + return ImageFormat.Bmp; + case ".emf": + return ImageFormat.Emf; + case ".exif": + return ImageFormat.Exif; + case ".gif": + return ImageFormat.Gif; + case ".ico": + return ImageFormat.Icon; + case ".jpg": + case ".jpeg": + return ImageFormat.Jpeg; + case ".png": + return ImageFormat.Png; + case ".tiff": + return ImageFormat.Tiff; + case ".wmf": + return ImageFormat.Wmf; + } + return ImageFormat.Png; + } + + private static PointF GetWaterMarkPointF(Image image, int waterMarkPosition, float waterMarkWidth, float waterMarkHeight, bool textMark) + { + float x; + float y; + switch(waterMarkPosition) + { + case 1: + if (textMark) + { + x = waterMarkWidth / 2; + } + else + { + x = 0; + } + y = 0; + break; + case 2 : + if (textMark) + { + x = image.Width / 2; + } + else + { + x = image.Width / 2 - waterMarkWidth / 2; + } + y = 0; + break; + case 3 : + if (textMark) + { + x = image.Width - waterMarkWidth / 2; + } + else + { + x = image.Width - waterMarkWidth; + } + y = 0; + break; + case 4 : + if (textMark) + { + x = waterMarkWidth / 2; + } + else + { + x = 0; + } + y = image.Height / 2 - waterMarkHeight / 2; + break; + case 5 : + if (textMark) + { + x = image.Width / 2; + } + else + { + x= image.Width / 2 - waterMarkWidth / 2; + } + y = image.Height / 2 - waterMarkHeight / 2; + break; + case 6 : + if (textMark) + { + x = image.Width - waterMarkWidth / 2; + } + else + { + x = image.Width - waterMarkWidth; + } + y = image.Height / 2 - waterMarkHeight / 2; + break; + case 7 : + if (textMark) + { + x = waterMarkWidth / 2; + } + else + { + x = 0; + } + y = image.Height - waterMarkHeight; + break; + case 8 : + if (textMark) + { + x = image.Width / 2; + } + else + { + x = image.Width / 2 - waterMarkWidth / 2; + } + y = image.Height - waterMarkHeight; + break; + default : + + if (textMark) + { + x = image.Width - waterMarkWidth / 2; + } + else + { + x = image.Width - waterMarkWidth; + } + y = image.Height - waterMarkHeight; + break; + } + return new PointF(x, y); + } + + public static void AddTextWaterMark(string imagePath, string waterMarkText, string fontName, int fontSize, int waterMarkPosition, int waterMarkTransparency, int minWidth, int minHeight) + { + try + { + var image = GetImage(imagePath); + + if (minWidth > 0) + { + if (image.Width < minWidth) + { + image.Dispose(); + return; + } + } + if (minHeight > 0) + { + if (image.Height < minHeight) + { + image.Dispose(); + return; + } + } + + var b = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb); + var picture = Graphics.FromImage(b); + picture.Clear(Color.White); + picture.SmoothingMode = SmoothingMode.Default; + picture.InterpolationMode = InterpolationMode.Default; + + picture.DrawImage(image, 0, 0, image.Width, image.Height); + + var sizes = new[] { fontSize, 16, 14, 12, 10, 8, 6, 4 }; + Font crFont = null; + var crSize = new SizeF(); + for (var i = 0; i < 8; i++) + { + crFont = new Font(fontName, sizes[i], FontStyle.Bold); + crSize = picture.MeasureString(waterMarkText, crFont); + + if ((ushort)crSize.Width < (ushort)image.Width && (ushort)crSize.Height < (ushort)image.Height) break; + } + + if (image.Width <= Convert.ToInt32(crSize.Width) || image.Height <= Convert.ToInt32(crSize.Height)) return; + var pointF = GetWaterMarkPointF(image, waterMarkPosition, crSize.Width, crSize.Height,true); + + if (pointF.X < 0 || pointF.X >= image.Width || pointF.Y < 0 || pointF.Y >= image.Height) return; + + var strFormat = new StringFormat {Alignment = StringAlignment.Center}; + + var alphaRate = (255 * waterMarkTransparency) / 10; + if (alphaRate <= 0 || alphaRate > 255) alphaRate = 153; + + var semiTransBrush2 = new SolidBrush(Color.FromArgb(alphaRate, 0, 0, 0)); + picture.DrawString(waterMarkText, crFont, semiTransBrush2, pointF.X + 1, pointF.Y + 1, strFormat); + + var semiTransBrush = new SolidBrush(Color.FromArgb(alphaRate, 255, 255, 255)); + // + picture.DrawString(waterMarkText, crFont, semiTransBrush, pointF.X, pointF.Y, strFormat); + + semiTransBrush2.Dispose(); + semiTransBrush.Dispose(); + + var fileType = EFileSystemTypeUtils.GetEnumType(PathUtils.GetExtension(imagePath)); + var imageFormat = ImageFormat.Jpeg; + if (fileType == EFileSystemType.Bmp) + { + imageFormat = ImageFormat.Bmp; + } + else if (fileType == EFileSystemType.Gif) + { + imageFormat = ImageFormat.Gif; + } + else if (fileType == EFileSystemType.Png) + { + imageFormat = ImageFormat.Png; + } + + b.Save(imagePath, imageFormat); + b.Dispose(); + image.Dispose(); + + } + catch + { + // ignored + } + } + + public static void AddImageWaterMark(string imagePath, string waterMarkImagePath, int waterMarkPosition, int waterMarkTransparency, int minWidth, int minHeight) + { + try + { + var image = GetImage(imagePath); + + if (minWidth > 0) + { + if (image.Width < minWidth) + { + image.Dispose(); + return; + } + } + if (minHeight > 0) + { + if (image.Height < minHeight) + { + image.Dispose(); + return; + } + } + + var b = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb); + var picture = Graphics.FromImage(b); + picture.Clear(Color.White); + picture.SmoothingMode = SmoothingMode.Default; + picture.InterpolationMode = InterpolationMode.Default; + + picture.DrawImage(image, 0, 0, image.Width, image.Height); + + var waterMark = GetImage(waterMarkImagePath); + + if (image.Width <= waterMark.Width || image.Height <= waterMark.Height) return; + var pointF = GetWaterMarkPointF(image, waterMarkPosition, waterMark.Width, waterMark.Height, false); + var xpos = Convert.ToInt32(pointF.X); + var ypos = Convert.ToInt32(pointF.Y); + + if (xpos < 0 || xpos >= image.Width || ypos < 0 || ypos >= image.Height) return; + + var alphaRate = (255 * waterMarkTransparency) / 10; + if (alphaRate <= 0 || alphaRate > 255) alphaRate = 153; + + var bmWaterMark = new Bitmap(waterMark); + for (var ix = 0; ix < waterMark.Width; ix++) + { + for (var iy = 0; iy < waterMark.Height; iy++) + { + int ir = bmWaterMark.GetPixel(ix, iy).R; + int ig = bmWaterMark.GetPixel(ix, iy).G; + int ib = bmWaterMark.GetPixel(ix, iy).B; + + if (!(ir == 0 && ig == 0 && ib == 0)) + { + picture.DrawEllipse(new Pen(new SolidBrush(Color.FromArgb(alphaRate, ir, ig, ib))), xpos + ix, ypos + iy, 1, 1); + } + } + } + + waterMark.Dispose(); + + b.Save(imagePath); + b.Dispose(); + image.Dispose(); + + } + catch + { + // ignored + } + } + + public static bool MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, bool isLessSizeNotThumb, out Size originalSize) + { + originalSize = new Size(); + + if (width == 0 && height == 0) + { + FileUtils.CopyFile(originalImagePath, thumbnailPath); + return true; + } + DirectoryUtils.CreateDirectoryIfNotExists(thumbnailPath); + if (!FileUtils.IsFileExists(originalImagePath)) return false; + + var originalImage = Image.FromFile(originalImagePath); + originalSize = originalImage.Size; + + if (width == 0) + { + if (isLessSizeNotThumb && originalImage.Height < height) + { + FileUtils.CopyFile(originalImagePath, thumbnailPath); + return true; + } + return MakeThumbnail(originalImage, originalImagePath, thumbnailPath, width, height, "H"); + } + if (height == 0) + { + if (isLessSizeNotThumb && originalImage.Width < width) + { + FileUtils.CopyFile(originalImagePath, thumbnailPath); + return true; + } + return MakeThumbnail(originalImage, originalImagePath, thumbnailPath, width, height, "W"); + } + if (isLessSizeNotThumb && originalImage.Height < height && originalImage.Width < width) + { + FileUtils.CopyFile(originalImagePath, thumbnailPath); + return true; + } + return MakeThumbnail(originalImage, originalImagePath, thumbnailPath, width, height, "HW"); + } + + public static bool MakeThumbnail(string originalImagePath, string thumbnailPath, int width, int height, bool isLessSizeNotThumb) + { + Size originalSize; + return MakeThumbnail(originalImagePath, thumbnailPath, width, height, isLessSizeNotThumb, out originalSize); + } + + private static bool MakeThumbnail(Image originalImage, string originalImagePath, string thumbnailPath, int width, int height, string mode) + { + var created = false; + + if (FileUtils.IsFileExists(originalImagePath)) + { + var towidth = width; + var toheight = height; + var x = 0; + var y = 0; + var ow = originalImage.Width; + var oh = originalImage.Height; + switch (mode) + { + case "HW": + break; + case "W": + toheight = originalImage.Height * width / originalImage.Width; + break; + case "H": + towidth = originalImage.Width * height / originalImage.Height; + break; + case "Cut": + if ((double)originalImage.Width / originalImage.Height > towidth / (double)toheight) + { + oh = originalImage.Height; + ow = originalImage.Height * towidth / toheight; + y = 0; + x = (originalImage.Width - ow) / 2; + } + else + { + ow = originalImage.Width; + oh = originalImage.Width * height / towidth; + x = 0; + y = (originalImage.Height - oh) / 2; + } + break; + } + Image bitmap = new Bitmap(towidth, toheight); + var g = Graphics.FromImage(bitmap); + g.InterpolationMode = InterpolationMode.Default; + g.SmoothingMode = SmoothingMode.Default; + g.Clear(Color.Transparent); + g.DrawImage(originalImage, new Rectangle(0, 0, towidth, toheight), + new Rectangle(x, y, ow, oh), GraphicsUnit.Pixel); + try + { + bitmap.Save(thumbnailPath, GetImageFormat(originalImagePath)); + created = true; + } + catch + { + FileUtils.CopyFile(originalImagePath, thumbnailPath); + created = true; + } + finally + { + originalImage.Dispose(); bitmap.Dispose(); g.Dispose(); + } + } + + return created; + } + + public static bool CropImage(string originalImagePath, string thumbnailPath, int xPosition, int yPosition, int width, int height) + { + DirectoryUtils.CreateDirectoryIfNotExists(thumbnailPath); + if (!FileUtils.IsFileExists(originalImagePath)) return false; + + var originalImage = Image.FromFile(originalImagePath); + + var towidth = width; + var toheight = height; + var x = xPosition; + var y = yPosition; + Image bitmap = new Bitmap(towidth, toheight); + var g = Graphics.FromImage(bitmap); + g.InterpolationMode = InterpolationMode.Default; + g.SmoothingMode = SmoothingMode.Default; + g.Clear(Color.Transparent); + + var section = new Rectangle(new Point(x, y), new Size(width, height)); + g.DrawImage(originalImage, 0, 0, section, GraphicsUnit.Pixel); + try + { + bitmap.Save(thumbnailPath, GetImageFormat(originalImagePath)); + } + catch + { + FileUtils.CopyFile(originalImagePath, thumbnailPath); + } + finally + { + originalImage.Dispose(); bitmap.Dispose(); g.Dispose(); + } + + return true; + } + + public static bool RotateFlipImage(string originalImagePath, string thumbnailPath, RotateFlipType rotateFlipType) + { + DirectoryUtils.CreateDirectoryIfNotExists(thumbnailPath); + if (!FileUtils.IsFileExists(originalImagePath)) return false; + + var originalImage = Image.FromFile(originalImagePath); + + originalImage.RotateFlip(rotateFlipType); + + try + { + originalImage.Save(thumbnailPath, GetImageFormat(originalImagePath)); + } + catch + { + FileUtils.CopyFile(originalImagePath, thumbnailPath); + } + finally + { + originalImage.Dispose(); + } + + return true; + } + } +} diff --git a/SiteServer.Utils/WebClientUtils.cs b/net452/SiteServer.CMS/Fx/WebClientUtils.cs similarity index 95% rename from SiteServer.Utils/WebClientUtils.cs rename to net452/SiteServer.CMS/Fx/WebClientUtils.cs index 3c1ffb7cc..e289d1e79 100644 --- a/SiteServer.Utils/WebClientUtils.cs +++ b/net452/SiteServer.CMS/Fx/WebClientUtils.cs @@ -2,9 +2,10 @@ using System.Collections.Specialized; using System.Net; using System.Text; +using SiteServer.Utils; using SiteServer.Utils.Enumerations; -namespace SiteServer.Utils +namespace SiteServer.CMS.Fx { public class WebClientUtils { @@ -14,7 +15,7 @@ public static string GetRemoteFileSource(string url, ECharset charset, string co try { string retval; - var uri = new Uri(PageUtils.AddProtocolToUrl(url.Trim())); + var uri = new Uri(FxUtils.AddProtocolToUrl(url.Trim())); var hwReq = (HttpWebRequest)WebRequest.Create(uri); if (!string.IsNullOrEmpty(cookieString)) { @@ -45,7 +46,7 @@ public static string GetRemoteFileSource(string url, ECharset charset) public static HttpStatusCode GetRemoteUrlStatusCode(string url) { - var uri = new Uri(PageUtils.AddProtocolToUrl(url.Trim())); + var uri = new Uri(FxUtils.AddProtocolToUrl(url.Trim())); var req = (HttpWebRequest)WebRequest.Create(uri); req.Method = "HEAD"; //设置请求方式为请求头,这样就不需要把整个网页下载下来 req.KeepAlive = false; diff --git a/SiteServer.CMS/ImportExport/AtomUtility.cs b/net452/SiteServer.CMS/ImportExport/AtomUtility.cs similarity index 96% rename from SiteServer.CMS/ImportExport/AtomUtility.cs rename to net452/SiteServer.CMS/ImportExport/AtomUtility.cs index 9b5597623..2b5b330fd 100644 --- a/SiteServer.CMS/ImportExport/AtomUtility.cs +++ b/net452/SiteServer.CMS/ImportExport/AtomUtility.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; using System.Collections.Specialized; -using Atom.AdditionalElements; -using Atom.AdditionalElements.DublinCore; -using Atom.Core; using SiteServer.Utils; +using SiteServer.Utils.Atom.Atom.AdditionalElements; +using SiteServer.Utils.Atom.Atom.AdditionalElements.DublinCore; +using SiteServer.Utils.Atom.Atom.Core; using SiteServer.Utils.Auth; namespace SiteServer.CMS.ImportExport diff --git a/SiteServer.CMS/ImportExport/BackupUtility.cs b/net452/SiteServer.CMS/ImportExport/BackupUtility.cs similarity index 90% rename from SiteServer.CMS/ImportExport/BackupUtility.cs rename to net452/SiteServer.CMS/ImportExport/BackupUtility.cs index d9b1ba19d..aae4b1911 100644 --- a/SiteServer.CMS/ImportExport/BackupUtility.cs +++ b/net452/SiteServer.CMS/ImportExport/BackupUtility.cs @@ -1,8 +1,11 @@ using System.Collections; using System.Collections.Generic; +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; -using SiteServer.CMS.Model.Enumerations; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.CMS.ImportExport @@ -60,9 +63,9 @@ public static void BackupSite(int siteId, string filePath, string adminName) exportObject.ExportTablesAndStyles(tableDirectoryPath); var configurationFilePath = PathUtils.Combine(metadataPath, DirectoryUtils.SiteTemplates.FileConfiguration); exportObject.ExportConfiguration(configurationFilePath); - exportObject.ExportMetadata(siteInfo.SiteName, siteInfo.Additional.WebUrl, string.Empty, string.Empty, metadataPath); + exportObject.ExportMetadata(siteInfo.SiteName, siteInfo.WebUrl, string.Empty, string.Empty, metadataPath); - ZipUtils.PackFiles(filePath, siteTemplatePath); + ZipUtils.CreateZip(filePath, siteTemplatePath); DirectoryUtils.DeleteDirectoryIfExists(siteTemplatePath); } @@ -80,7 +83,7 @@ public static void RecoverySite(int siteId, bool isDeleteChannels, bool isDelete DirectoryUtils.DeleteDirectoryIfExists(siteTemplatePath); DirectoryUtils.CreateDirectoryIfNotExists(siteTemplatePath); - ZipUtils.UnpackFiles(path, siteTemplatePath); + ZipUtils.ExtractZip(path, siteTemplatePath); } var siteTemplateMetadataPath = PathUtils.Combine(siteTemplatePath, DirectoryUtils.SiteTemplates.SiteTemplateMetadata); @@ -89,18 +92,18 @@ public static void RecoverySite(int siteId, bool isDeleteChannels, bool isDelete var channelIdList = ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(siteId, siteId), EScopeType.Children, string.Empty, string.Empty, string.Empty); foreach (var channelId in channelIdList) { - DataProvider.ChannelDao.Delete(siteId, channelId); + DataProvider.Channel.Delete(siteId, channelId); } } if (isDeleteTemplates) { var templateInfoList = - DataProvider.TemplateDao.GetTemplateInfoListBySiteId(siteId); + DataProvider.Template.GetTemplateInfoListBySiteId(siteId); foreach (var templateInfo in templateInfoList) { - if (templateInfo.IsDefault == false) + if (templateInfo.Default == false) { - DataProvider.TemplateDao.Delete(siteId, templateInfo.Id); + DataProvider.Template.Delete(siteId, templateInfo.Id); } } } @@ -118,7 +121,6 @@ public static void RecoverySite(int siteId, bool isDeleteChannels, bool isDelete //导入辅助表 var tableDirectoryPath = PathUtils.Combine(siteTemplateMetadataPath, DirectoryUtils.SiteTemplates.Table); - importObject.ImportAuxiliaryTables(tableDirectoryPath, isUseTable); //导入站点设置 var configurationFilePath = PathUtils.Combine(siteTemplateMetadataPath, DirectoryUtils.SiteTemplates.FileConfiguration); @@ -128,8 +130,6 @@ public static void RecoverySite(int siteId, bool isDeleteChannels, bool isDelete var siteContentDirectoryPath = PathUtils.Combine(siteTemplateMetadataPath, DirectoryUtils.SiteTemplates.SiteContent); importObject.ImportChannelsAndContents(0, siteContentDirectoryPath, isOverride); - DataProvider.ChannelDao.UpdateContentNum(siteInfo); - //导入表样式及清除缓存 if (isUseTable) { diff --git a/SiteServer.CMS/ImportExport/Components/ChannelGroupIe.cs b/net452/SiteServer.CMS/ImportExport/Components/ChannelGroupIe.cs similarity index 75% rename from SiteServer.CMS/ImportExport/Components/ChannelGroupIe.cs rename to net452/SiteServer.CMS/ImportExport/Components/ChannelGroupIe.cs index 4fff27f04..96d613f98 100644 --- a/SiteServer.CMS/ImportExport/Components/ChannelGroupIe.cs +++ b/net452/SiteServer.CMS/ImportExport/Components/ChannelGroupIe.cs @@ -1,12 +1,13 @@ using System.Collections.Generic; -using Atom.Core; +using SiteServer.CMS.Caches; using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils.Atom.Atom.Core; namespace SiteServer.CMS.ImportExport.Components { - public class ChannelGroupIe + public static class ChannelGroupIe { public static AtomEntry Export(ChannelGroupInfo groupInfo) { @@ -27,11 +28,17 @@ public static bool Import(AtomEntry entry, int siteId) var groupName = AtomUtility.GetDcElementContent(entry.AdditionalElements, new List { nameof(ChannelGroupInfo.GroupName), "NodeGroupName" }); if (string.IsNullOrEmpty(groupName)) return true; - if (DataProvider.ChannelGroupDao.IsExists(siteId, groupName)) return true; + if (ChannelGroupManager.IsExists(siteId, groupName)) return true; var taxis = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(ChannelGroupInfo.Taxis))); var description = AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(ChannelGroupInfo.Description)); - DataProvider.ChannelGroupDao.Insert(new ChannelGroupInfo(groupName, siteId, taxis, description)); + DataProvider.ChannelGroup.Insert(new ChannelGroupInfo + { + GroupName = groupName, + SiteId = siteId, + Taxis = taxis, + Description = description + }); return true; } diff --git a/net452/SiteServer.CMS/ImportExport/Components/ChannelIe.cs b/net452/SiteServer.CMS/ImportExport/Components/ChannelIe.cs new file mode 100644 index 000000000..f5e311f7b --- /dev/null +++ b/net452/SiteServer.CMS/ImportExport/Components/ChannelIe.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Models; +using SiteServer.Plugin; +using SiteServer.Utils.Atom.Atom.AdditionalElements; +using SiteServer.Utils.Atom.Atom.Core; + +namespace SiteServer.CMS.ImportExport.Components +{ + internal class ChannelIe + { + private readonly SiteInfo _siteInfo; + + //保存除内容表本身字段外的属性 + private const string ChannelTemplateName = "ChannelTemplateName"; + private const string ContentTemplateName = "ContentTemplateName"; + + public ChannelIe(SiteInfo siteInfo) + { + _siteInfo = siteInfo; + } + + public void ImportNodeInfo(ChannelInfo nodeInfo, ScopedElementCollection additionalElements, int parentId, IList indexNameList) + { + nodeInfo.ChannelName = AtomUtility.GetDcElementContent(additionalElements, new List{ ChannelAttribute.ChannelName, "NodeName" }); + nodeInfo.SiteId = _siteInfo.Id; + var contentModelPluginId = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.ContentModelPluginId); + if (!string.IsNullOrEmpty(contentModelPluginId)) + { + nodeInfo.ContentModelPluginId = contentModelPluginId; + } + var contentRelatedPluginIds = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.ContentRelatedPluginIds); + if (!string.IsNullOrEmpty(contentRelatedPluginIds)) + { + nodeInfo.ContentRelatedPluginIds = contentRelatedPluginIds; + } + nodeInfo.ParentId = parentId; + var indexName = AtomUtility.GetDcElementContent(additionalElements, new List { ChannelAttribute.IndexName, "NodeIndexName" }); + if (!string.IsNullOrEmpty(indexName) && indexNameList.IndexOf(indexName) == -1) + { + nodeInfo.IndexName = indexName; + indexNameList.Add(indexName); + } + nodeInfo.GroupNameCollection = AtomUtility.GetDcElementContent(additionalElements, new List { ChannelAttribute.GroupNameCollection, "NodeGroupNameCollection" }); + nodeInfo.AddDate = DateTime.Now; + nodeInfo.ImageUrl = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.ImageUrl); + nodeInfo.Content = AtomUtility.Decrypt(AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.Content)); + nodeInfo.FilePath = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.FilePath); + nodeInfo.ChannelFilePathRule = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.ChannelFilePathRule); + nodeInfo.ContentFilePathRule = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.ContentFilePathRule); + + nodeInfo.LinkUrl = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.LinkUrl); + nodeInfo.LinkType = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.LinkType); + + var channelTemplateName = AtomUtility.GetDcElementContent(additionalElements, ChannelTemplateName); + if (!string.IsNullOrEmpty(channelTemplateName)) + { + nodeInfo.ChannelTemplateId = TemplateManager.GetTemplateIdByTemplateName(_siteInfo.Id, TemplateType.ChannelTemplate, channelTemplateName); + } + var contentTemplateName = AtomUtility.GetDcElementContent(additionalElements, ContentTemplateName); + if (!string.IsNullOrEmpty(contentTemplateName)) + { + nodeInfo.ContentTemplateId = TemplateManager.GetTemplateIdByTemplateName(_siteInfo.Id, TemplateType.ContentTemplate, contentTemplateName); + } + + nodeInfo.Keywords = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.Keywords); + nodeInfo.Description = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.Description); + + nodeInfo.ExtendValues = AtomUtility.GetDcElementContent(additionalElements, ChannelAttribute.ExtendValues); + } + + public AtomFeed ExportNodeInfo(ChannelInfo channelInfo) + { + var feed = AtomUtility.GetEmptyFeed(); + + AtomUtility.AddDcElement(feed.AdditionalElements, new List{ ChannelAttribute.Id, "NodeId" }, channelInfo.Id.ToString()); + AtomUtility.AddDcElement(feed.AdditionalElements, new List { ChannelAttribute.ChannelName, "NodeName" }, channelInfo.ChannelName); + AtomUtility.AddDcElement(feed.AdditionalElements, new List { ChannelAttribute.SiteId, "PublishmentSystemId" }, channelInfo.SiteId.ToString()); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ContentModelPluginId, channelInfo.ContentModelPluginId); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ContentRelatedPluginIds, channelInfo.ContentRelatedPluginIds); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ParentId, channelInfo.ParentId.ToString()); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ParentsPath, channelInfo.ParentsPath); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ParentsCount, channelInfo.ParentsCount.ToString()); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ChildrenCount, channelInfo.ChildrenCount.ToString()); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.LastNode, channelInfo.LastNode.ToString()); + AtomUtility.AddDcElement(feed.AdditionalElements, new List { ChannelAttribute.IndexName, "NodeIndexName" }, channelInfo.IndexName); + AtomUtility.AddDcElement(feed.AdditionalElements, new List { ChannelAttribute.GroupNameCollection, "NodeGroupNameCollection" }, channelInfo.GroupNameCollection); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.Taxis, channelInfo.Taxis.ToString()); + if (channelInfo.AddDate != null) + { + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.AddDate, + channelInfo.AddDate.Value.ToLongDateString()); + } + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ImageUrl, channelInfo.ImageUrl); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.Content, AtomUtility.Encrypt(channelInfo.Content)); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.FilePath, channelInfo.FilePath); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ChannelFilePathRule, channelInfo.ChannelFilePathRule); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ContentFilePathRule, channelInfo.ContentFilePathRule); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.LinkUrl, channelInfo.LinkUrl); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.LinkType, channelInfo.LinkType); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ChannelTemplateId, channelInfo.ChannelTemplateId.ToString()); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ContentTemplateId, channelInfo.ContentTemplateId.ToString()); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.Keywords, channelInfo.Keywords); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.Description, channelInfo.Description); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelAttribute.ExtendValues, channelInfo.ExtendValues); + + if (channelInfo.ChannelTemplateId != 0) + { + var channelTemplateName = TemplateManager.GetTemplateName(channelInfo.SiteId, channelInfo.ChannelTemplateId); + AtomUtility.AddDcElement(feed.AdditionalElements, ChannelTemplateName, channelTemplateName); + } + + if (channelInfo.ContentTemplateId != 0) + { + var contentTemplateName = TemplateManager.GetTemplateName(channelInfo.SiteId, channelInfo.ContentTemplateId); + AtomUtility.AddDcElement(feed.AdditionalElements, ContentTemplateName, contentTemplateName); + } + + return feed; + } + } +} diff --git a/net452/SiteServer.CMS/ImportExport/Components/ConfigurationIe.cs b/net452/SiteServer.CMS/ImportExport/Components/ConfigurationIe.cs new file mode 100644 index 000000000..82bee3ef3 --- /dev/null +++ b/net452/SiteServer.CMS/ImportExport/Components/ConfigurationIe.cs @@ -0,0 +1,193 @@ +using System; +using System.Collections.Generic; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Attributes; +using SiteServer.Utils; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Plugin; +using SiteServer.Utils.Atom.Atom.Core; + +namespace SiteServer.CMS.ImportExport.Components +{ + public class ConfigurationIe + { + private readonly int _siteId; + private readonly string _filePath; + + private const string DefaultIndexTemplateName = "DefaultIndexTemplateName"; + private const string DefaultChannelTemplateName = "DefaultChannelTemplateName"; + private const string DefaultContentTemplateName = "DefaultContentTemplateName"; + private const string DefaultFileTemplateName = "DefaultFileTemplateName"; + + public ConfigurationIe(int siteId, string filePath) + { + _siteId = siteId; + _filePath = filePath; + } + + public void Export() + { + var siteInfo = SiteManager.GetSiteInfo(_siteId); + + var feed = AtomUtility.GetEmptyFeed(); + + AtomUtility.AddDcElement(feed.AdditionalElements, new List { SiteAttribute.Id, "PublishmentSystemId" }, siteInfo.Id.ToString()); + AtomUtility.AddDcElement(feed.AdditionalElements, new List { SiteAttribute.SiteName, "PublishmentSystemName" }, siteInfo.SiteName); + AtomUtility.AddDcElement(feed.AdditionalElements, new List { SiteAttribute.SiteDir, "PublishmentSystemDir" }, siteInfo.SiteDir); + AtomUtility.AddDcElement(feed.AdditionalElements, new List { SiteAttribute.TableName, "AuxiliaryTableForContent" }, siteInfo.TableName); + AtomUtility.AddDcElement(feed.AdditionalElements, new List { SiteAttribute.Root, "IsHeadquarters" }, siteInfo.Root.ToString()); + AtomUtility.AddDcElement(feed.AdditionalElements, new List { SiteAttribute.ParentId, "ParentPublishmentSystemId" }, siteInfo.ParentId.ToString()); + AtomUtility.AddDcElement(feed.AdditionalElements, SiteAttribute.Taxis, siteInfo.Taxis.ToString()); + AtomUtility.AddDcElement(feed.AdditionalElements, SiteAttribute.SettingsXml, siteInfo.ToString()); + + var indexTemplateId = TemplateManager.GetDefaultTemplateId(siteInfo.Id, TemplateType.IndexPageTemplate); + if (indexTemplateId != 0) + { + var indexTemplateName = TemplateManager.GetTemplateName(_siteId, indexTemplateId); + AtomUtility.AddDcElement(feed.AdditionalElements, DefaultIndexTemplateName, indexTemplateName); + } + + var channelTemplateId = TemplateManager.GetDefaultTemplateId(siteInfo.Id, TemplateType.ChannelTemplate); + if (channelTemplateId != 0) + { + var channelTemplateName = TemplateManager.GetTemplateName(_siteId, channelTemplateId); + AtomUtility.AddDcElement(feed.AdditionalElements, DefaultChannelTemplateName, channelTemplateName); + } + + var contentTemplateId = TemplateManager.GetDefaultTemplateId(siteInfo.Id, TemplateType.ContentTemplate); + if (contentTemplateId != 0) + { + var contentTemplateName = TemplateManager.GetTemplateName(_siteId, contentTemplateId); + AtomUtility.AddDcElement(feed.AdditionalElements, DefaultContentTemplateName, contentTemplateName); + } + + var fileTemplateId = TemplateManager.GetDefaultTemplateId(siteInfo.Id, TemplateType.FileTemplate); + if (fileTemplateId != 0) + { + var fileTemplateName = TemplateManager.GetTemplateName(siteInfo.Id, fileTemplateId); + AtomUtility.AddDcElement(feed.AdditionalElements, DefaultFileTemplateName, fileTemplateName); + } + + var channelGroupInfoList = ChannelGroupManager.GetChannelGroupInfoList(siteInfo.Id); + channelGroupInfoList.Reverse(); + + foreach (var channelGroupInfo in channelGroupInfoList) + { + var entry = ChannelGroupIe.Export(channelGroupInfo); + feed.Entries.Add(entry); + } + + var contentGroupInfoList = ContentGroupManager.GetContentGroupInfoList(siteInfo.Id); + contentGroupInfoList.Reverse(); + + foreach (var contentGroupInfo in contentGroupInfoList) + { + var entry = ContentGroupIe.Export(contentGroupInfo); + feed.Entries.Add(entry); + } + + feed.Save(_filePath); + } + + public static SiteInfo GetSiteInfo(string filePath) + { + var siteInfo = new SiteInfo(); + if (!FileUtils.IsFileExists(filePath)) return siteInfo; + + var feed = AtomFeed.Load(FileUtils.GetFileStreamReadOnly(filePath)); + + siteInfo.SiteName = AtomUtility.GetDcElementContent(feed.AdditionalElements, new List { SiteAttribute.SiteName, "PublishmentSystemName" }); + siteInfo.SiteDir = AtomUtility.GetDcElementContent(feed.AdditionalElements, new List { SiteAttribute.SiteDir, "PublishmentSystemDir" }); + if (siteInfo.SiteDir != null && siteInfo.SiteDir.IndexOf("\\", StringComparison.Ordinal) != -1) + { + siteInfo.SiteDir = siteInfo.SiteDir.Substring(siteInfo.SiteDir.LastIndexOf("\\", StringComparison.Ordinal) + 1); + } + var settingsXml = AtomUtility.GetDcElementContent(feed.AdditionalElements, SiteAttribute.SettingsXml); + if (string.IsNullOrEmpty(settingsXml)) + { + var dict = TranslateUtils.JsonDeserialize>(settingsXml); + foreach (var item in dict) + { + siteInfo.Set(item.Key, item.Value); + } + } + + siteInfo.IsCreateDoubleClick = false; + return siteInfo; + } + + public void Import() + { + if (!FileUtils.IsFileExists(_filePath)) return; + + var feed = AtomFeed.Load(FileUtils.GetFileStreamReadOnly(_filePath)); + + var siteInfo = SiteManager.GetSiteInfo(_siteId); + + var settingsXml = AtomUtility.GetDcElementContent(feed.AdditionalElements, SiteAttribute.SettingsXml); + if (string.IsNullOrEmpty(settingsXml)) + { + var dict = TranslateUtils.JsonDeserialize>(settingsXml); + foreach (var item in dict) + { + siteInfo.Set(item.Key, item.Value); + } + } + + siteInfo.IsSeparatedWeb = false; + siteInfo.IsCreateDoubleClick = false; + + DataProvider.Site.Update(siteInfo); + + var indexTemplateName = AtomUtility.GetDcElementContent(feed.AdditionalElements, DefaultIndexTemplateName); + if (!string.IsNullOrEmpty(indexTemplateName)) + { + var indexTemplateId = TemplateManager.GetTemplateIdByTemplateName(siteInfo.Id, TemplateType.IndexPageTemplate, indexTemplateName); + if (indexTemplateId != 0) + { + DataProvider.Template.SetDefault(siteInfo.Id, indexTemplateId); + } + } + + var channelTemplateName = AtomUtility.GetDcElementContent(feed.AdditionalElements, DefaultChannelTemplateName); + if (!string.IsNullOrEmpty(channelTemplateName)) + { + var channelTemplateId = TemplateManager.GetTemplateIdByTemplateName(siteInfo.Id, TemplateType.ChannelTemplate, channelTemplateName); + if (channelTemplateId != 0) + { + DataProvider.Template.SetDefault(siteInfo.Id, channelTemplateId); + } + } + + var contentTemplateName = AtomUtility.GetDcElementContent(feed.AdditionalElements, DefaultContentTemplateName); + if (!string.IsNullOrEmpty(contentTemplateName)) + { + var contentTemplateId = TemplateManager.GetTemplateIdByTemplateName(siteInfo.Id, TemplateType.ContentTemplate, contentTemplateName); + if (contentTemplateId != 0) + { + DataProvider.Template.SetDefault(siteInfo.Id, contentTemplateId); + } + } + + var fileTemplateName = AtomUtility.GetDcElementContent(feed.AdditionalElements, DefaultFileTemplateName); + if (!string.IsNullOrEmpty(fileTemplateName)) + { + var fileTemplateId = TemplateManager.GetTemplateIdByTemplateName(siteInfo.Id, TemplateType.FileTemplate, fileTemplateName); + if (fileTemplateId != 0) + { + DataProvider.Template.SetDefault(siteInfo.Id, fileTemplateId); + } + } + + foreach (AtomEntry entry in feed.Entries) + { + if (!ChannelGroupIe.Import(entry, siteInfo.Id)) + { + ContentGroupIe.Import(entry, siteInfo.Id); + } + } + } + + } +} diff --git a/SiteServer.CMS/ImportExport/Components/ContentGroupIe.cs b/net452/SiteServer.CMS/ImportExport/Components/ContentGroupIe.cs similarity index 75% rename from SiteServer.CMS/ImportExport/Components/ContentGroupIe.cs rename to net452/SiteServer.CMS/ImportExport/Components/ContentGroupIe.cs index e646e00a4..4dc01dbda 100644 --- a/SiteServer.CMS/ImportExport/Components/ContentGroupIe.cs +++ b/net452/SiteServer.CMS/ImportExport/Components/ContentGroupIe.cs @@ -1,12 +1,13 @@ using System.Collections.Generic; -using Atom.Core; +using SiteServer.CMS.Caches; using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils.Atom.Atom.Core; namespace SiteServer.CMS.ImportExport.Components { - public class ContentGroupIe + public static class ContentGroupIe { public static AtomEntry Export(ContentGroupInfo groupInfo) { @@ -27,12 +28,17 @@ public static bool Import(AtomEntry entry, int siteId) var groupName = AtomUtility.GetDcElementContent(entry.AdditionalElements, new List { nameof(ContentGroupInfo.GroupName), "ContentGroupName" }); if (string.IsNullOrEmpty(groupName)) return true; - if (DataProvider.ContentGroupDao.IsExists(groupName, siteId)) return true; + if (ContentGroupManager.IsExists(siteId, groupName)) return true; var taxis = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(ContentGroupInfo.Taxis))); var description = AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(ContentGroupInfo.Description)); - DataProvider.ContentGroupDao.Insert(new ContentGroupInfo(groupName, siteId, taxis, description)); - + DataProvider.ContentGroup.Insert(new ContentGroupInfo + { + GroupName = groupName, + SiteId = siteId, + Taxis = taxis, + Description = description + }); return true; } } diff --git a/net452/SiteServer.CMS/ImportExport/Components/ContentIe.cs b/net452/SiteServer.CMS/ImportExport/Components/ContentIe.cs new file mode 100644 index 000000000..0c44b4ac9 --- /dev/null +++ b/net452/SiteServer.CMS/ImportExport/Components/ContentIe.cs @@ -0,0 +1,447 @@ +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Globalization; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils.Atom.Atom.Core; +using SiteServer.Utils.Atom.Atom.Core.Collections; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.ImportExport.Components +{ + internal class ContentIe + { + private readonly SiteInfo _siteInfo; + private readonly string _siteContentDirectoryPath; + + public ContentIe(SiteInfo siteInfo, string siteContentDirectoryPath) + { + _siteContentDirectoryPath = siteContentDirectoryPath; + _siteInfo = siteInfo; + } + + public void ImportContents(string filePath, bool isOverride, ChannelInfo nodeInfo, int taxis, int importStart, int importCount, bool isChecked, int checkedLevel, string adminName) + { + if (!FileUtils.IsFileExists(filePath)) return; + var feed = AtomFeed.Load(FileUtils.GetFileStreamReadOnly(filePath)); + + ImportContents(feed.Entries, nodeInfo, taxis, importStart, importCount, false, isChecked, checkedLevel, isOverride, adminName); + } + + public void ImportContents(string filePath, bool isOverride, ChannelInfo nodeInfo, int taxis, bool isChecked, int checkedLevel, int adminId, int userId, int sourceId) + { + if (!FileUtils.IsFileExists(filePath)) return; + var feed = AtomFeed.Load(FileUtils.GetFileStreamReadOnly(filePath)); + + ImportContents(feed.Entries, nodeInfo, taxis, false, isChecked, checkedLevel, isOverride, adminId, userId, sourceId); + } + + public void ImportContents(AtomEntryCollection entries, ChannelInfo channelInfo, int taxis, bool isOverride, string adminName) + { + ImportContents(entries, channelInfo, taxis, 0, 0, true, true, 0, isOverride, adminName); + } + + // 内部消化掉错误 + private void ImportContents(AtomEntryCollection entries, ChannelInfo channelInfo, int taxis, int importStart, int importCount, bool isCheckedBySettings, bool isChecked, int checkedLevel, bool isOverride, string adminName) + { + if (importStart > 1 || importCount > 0) + { + var theEntries = new AtomEntryCollection(); + + if (importStart == 0) + { + importStart = 1; + } + if (importCount == 0) + { + importCount = entries.Count; + } + + var firstIndex = entries.Count - importStart - importCount + 1; + if (firstIndex <= 0) + { + firstIndex = 0; + } + + var addCount = 0; + for (var i = 0; i < entries.Count; i++) + { + if (addCount >= importCount) break; + if (i >= firstIndex) + { + theEntries.Add(entries[i]); + addCount++; + } + } + + entries = theEntries; + } + + var tableName = ChannelManager.GetTableName(_siteInfo, channelInfo); + + foreach (AtomEntry entry in entries) + { + try + { + taxis++; + var lastEditDate = AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.LastEditDate); + var groupNameCollection = AtomUtility.GetDcElementContent(entry.AdditionalElements, new List{ ContentAttribute.GroupNameCollection , "ContentGroupNameCollection" }); + if (isCheckedBySettings) + { + isChecked = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.IsChecked)); + checkedLevel = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.CheckedLevel)); + } + var hits = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.Hits)); + var hitsByDay = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.HitsByDay)); + var hitsByWeek = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.HitsByWeek)); + var hitsByMonth = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.HitsByMonth)); + var lastHitsDate = AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.LastHitsDate); + var downloads = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.Downloads)); + var title = AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.Title); + var isTop = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.IsTop)); + var isRecommend = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.IsRecommend)); + var isHot = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.IsHot)); + var isColor = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.IsColor)); + var linkUrl = AtomUtility.Decrypt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.LinkUrl)); + var addDate = AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.AddDate); + + var topTaxis = 0; + if (isTop) + { + topTaxis = taxis - 1; + taxis = channelInfo.ContentRepository.GetMaxTaxis(channelInfo.Id, true) + 1; + } + var tags = AtomUtility.Decrypt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.Tags)); + + var dict = new Dictionary + { + {ContentAttribute.SiteId, _siteInfo.Id}, + {ContentAttribute.ChannelId, channelInfo.Id}, + {ContentAttribute.AddUserName, adminName}, + {ContentAttribute.AddDate, TranslateUtils.ToDateTime(addDate)} + }; + var contentInfo = new ContentInfo(dict); + + contentInfo.LastEditUserName = contentInfo.AddUserName; + contentInfo.LastEditDate = TranslateUtils.ToDateTime(lastEditDate); + contentInfo.GroupNameCollection = groupNameCollection; + contentInfo.Tags = tags; + contentInfo.Checked = isChecked; + contentInfo.CheckedLevel = checkedLevel; + contentInfo.Hits = hits; + contentInfo.HitsByDay = hitsByDay; + contentInfo.HitsByWeek = hitsByWeek; + contentInfo.HitsByMonth = hitsByMonth; + contentInfo.LastHitsDate = TranslateUtils.ToDateTime(lastHitsDate); + contentInfo.Downloads = downloads; + contentInfo.Title = AtomUtility.Decrypt(title); + contentInfo.Top = isTop; + contentInfo.Recommend = isRecommend; + contentInfo.Hot = isHot; + contentInfo.Color = isColor; + contentInfo.LinkUrl = linkUrl; + + var attributes = AtomUtility.GetDcElementNameValueCollection(entry.AdditionalElements); + foreach (string attributeName in attributes.Keys) + { + if (!contentInfo.ContainsKey(attributeName)) + { + contentInfo.Set(attributeName, AtomUtility.Decrypt(attributes[attributeName])); + } + } + + var isInsert = false; + if (isOverride) + { + var existsIDs = channelInfo.ContentRepository.GetIdListBySameTitle(contentInfo.ChannelId, contentInfo.Title); + if (existsIDs.Count > 0) + { + foreach (int id in existsIDs) + { + contentInfo.Id = id; + DataProvider.ContentRepository.Update(_siteInfo, channelInfo, contentInfo); + } + } + else + { + isInsert = true; + } + } + else + { + isInsert = true; + } + + if (isInsert) + { + var contentId = DataProvider.ContentRepository.InsertWithTaxis(tableName, _siteInfo, channelInfo, contentInfo, taxis); + + if (!string.IsNullOrEmpty(tags)) + { + var tagCollection = TagUtils.ParseTagsString(tags); + TagUtils.AddTags(tagCollection, _siteInfo.Id, contentId); + } + } + + if (isTop) + { + taxis = topTaxis; + } + } + catch + { + // ignored + } + } + } + + private void ImportContents(AtomEntryCollection entries, ChannelInfo channelInfo, int taxis, bool isCheckedBySettings, bool isChecked, int checkedLevel, bool isOverride, int adminId, int userId, int sourceId) + { + var tableName = ChannelManager.GetTableName(_siteInfo, channelInfo); + + foreach (AtomEntry entry in entries) + { + try + { + taxis++; + var lastEditDate = AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.LastEditDate); + var groupNameCollection = AtomUtility.GetDcElementContent(entry.AdditionalElements, new List { ContentAttribute.GroupNameCollection, "ContentGroupNameCollection" }); + if (isCheckedBySettings) + { + isChecked = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.IsChecked)); + checkedLevel = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.CheckedLevel)); + } + var hits = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.Hits)); + var hitsByDay = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.HitsByDay)); + var hitsByWeek = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.HitsByWeek)); + var hitsByMonth = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.HitsByMonth)); + var lastHitsDate = AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.LastHitsDate); + var downloads = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.Downloads)); + var title = AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.Title); + var isTop = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.IsTop)); + var isRecommend = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.IsRecommend)); + var isHot = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.IsHot)); + var isColor = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.IsColor)); + var linkUrl = AtomUtility.Decrypt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.LinkUrl)); + var addDate = AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.AddDate); + + var topTaxis = 0; + if (isTop) + { + topTaxis = taxis - 1; + taxis = channelInfo.ContentRepository.GetMaxTaxis(channelInfo.Id, true) + 1; + } + var tags = AtomUtility.Decrypt(AtomUtility.GetDcElementContent(entry.AdditionalElements, ContentAttribute.Tags)); + + var dict = new Dictionary + { + {ContentAttribute.SiteId, _siteInfo.Id}, + {ContentAttribute.ChannelId, channelInfo.Id}, + {ContentAttribute.AdminId, adminId}, + {ContentAttribute.UserId, userId}, + {ContentAttribute.SourceId, sourceId}, + {ContentAttribute.AddDate, TranslateUtils.ToDateTime(addDate)} + }; + var contentInfo = new ContentInfo(dict); + + contentInfo.LastEditUserName = contentInfo.AddUserName; + contentInfo.LastEditDate = TranslateUtils.ToDateTime(lastEditDate); + contentInfo.GroupNameCollection = groupNameCollection; + contentInfo.Tags = tags; + contentInfo.Checked = isChecked; + contentInfo.CheckedLevel = checkedLevel; + contentInfo.Hits = hits; + contentInfo.HitsByDay = hitsByDay; + contentInfo.HitsByWeek = hitsByWeek; + contentInfo.HitsByMonth = hitsByMonth; + contentInfo.LastHitsDate = TranslateUtils.ToDateTime(lastHitsDate); + contentInfo.Downloads = downloads; + contentInfo.Title = AtomUtility.Decrypt(title); + contentInfo.Top = isTop; + contentInfo.Recommend = isRecommend; + contentInfo.Hot = isHot; + contentInfo.Color = isColor; + contentInfo.LinkUrl = linkUrl; + + var attributes = AtomUtility.GetDcElementNameValueCollection(entry.AdditionalElements); + foreach (string attributeName in attributes.Keys) + { + if (!contentInfo.ContainsKey(attributeName.ToLower())) + { + contentInfo.Set(attributeName, AtomUtility.Decrypt(attributes[attributeName])); + } + } + + var isInsert = false; + if (isOverride) + { + var existsIds = channelInfo.ContentRepository.GetIdListBySameTitle(contentInfo.ChannelId, contentInfo.Title); + if (existsIds.Count > 0) + { + foreach (var id in existsIds) + { + contentInfo.Id = id; + DataProvider.ContentRepository.Update(_siteInfo, channelInfo, contentInfo); + } + } + else + { + isInsert = true; + } + } + else + { + isInsert = true; + } + + if (isInsert) + { + var contentId = DataProvider.ContentRepository.InsertWithTaxis(tableName, _siteInfo, channelInfo, contentInfo, taxis); + + if (!string.IsNullOrEmpty(tags)) + { + var tagCollection = TagUtils.ParseTagsString(tags); + TagUtils.AddTags(tagCollection, _siteInfo.Id, contentId); + } + } + + if (isTop) + { + taxis = topTaxis; + } + } + catch + { + // ignored + } + } + } + + public bool ExportContents(SiteInfo siteInfo, int channelId, IList contentIdList, bool isPeriods, string dateFrom, string dateTo, ETriState checkedState) + { + var filePath = _siteContentDirectoryPath + PathUtils.SeparatorChar + "contents.xml"; + var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + var feed = AtomUtility.GetEmptyFeed(); + + if (contentIdList == null || contentIdList.Count == 0) + { + contentIdList = channelInfo.ContentRepository.GetContentIdList(channelId, isPeriods, dateFrom, dateTo, checkedState); + } + if (contentIdList.Count == 0) return false; + + var collection = new NameValueCollection(); + + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + try + { + ContentUtility.PutImagePaths(siteInfo, contentInfo, collection); + } + catch + { + // ignored + } + var entry = ExportContentInfo(contentInfo); + feed.Entries.Add(entry); + } + feed.Save(filePath); + + foreach (string imageUrl in collection.Keys) + { + var sourceFilePath = collection[imageUrl]; + var destFilePath = PathUtility.MapPath(_siteContentDirectoryPath, imageUrl); + DirectoryUtils.CreateDirectoryIfNotExists(destFilePath); + FileUtils.MoveFile(sourceFilePath, destFilePath, true); + } + + return true; + } + + public bool ExportContents(SiteInfo siteInfo, List contentInfoList) + { + var filePath = _siteContentDirectoryPath + PathUtils.SeparatorChar + "contents.xml"; + var feed = AtomUtility.GetEmptyFeed(); + + var collection = new NameValueCollection(); + + foreach (var contentInfo in contentInfoList) + { + try + { + ContentUtility.PutImagePaths(siteInfo, contentInfo, collection); + } + catch + { + // ignored + } + var entry = ExportContentInfo(contentInfo); + feed.Entries.Add(entry); + } + feed.Save(filePath); + + foreach (string imageUrl in collection.Keys) + { + var sourceFilePath = collection[imageUrl]; + var destFilePath = PathUtility.MapPath(_siteContentDirectoryPath, imageUrl); + DirectoryUtils.CreateDirectoryIfNotExists(destFilePath); + FileUtils.MoveFile(sourceFilePath, destFilePath, true); + } + + return true; + } + + public AtomEntry ExportContentInfo(ContentInfo contentInfo) + { + var entry = AtomUtility.GetEmptyEntry(); + + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.Id, contentInfo.Id.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, new List{ ContentAttribute.ChannelId, "NodeId" }, contentInfo.ChannelId.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, new List { ContentAttribute.SiteId, "PublishmentSystemId" }, contentInfo.SiteId.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.AddUserName, contentInfo.AddUserName); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.LastEditUserName, contentInfo.LastEditUserName); + if (contentInfo.LastEditDate.HasValue) + { + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.LastEditDate, contentInfo.LastEditDate.Value.ToString(CultureInfo.InvariantCulture)); + } + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.Taxis, contentInfo.Taxis.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, new List{ ContentAttribute.GroupNameCollection, "ContentGroupNameCollection" }, contentInfo.GroupNameCollection); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.Tags, AtomUtility.Encrypt(contentInfo.Tags)); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.SourceId, contentInfo.SourceId.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.ReferenceId, contentInfo.ReferenceId.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.IsChecked, contentInfo.Checked.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.CheckedLevel, contentInfo.CheckedLevel.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.Hits, contentInfo.Hits.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.HitsByDay, contentInfo.HitsByDay.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.HitsByWeek, contentInfo.HitsByWeek.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.HitsByMonth, contentInfo.HitsByMonth.ToString()); + if (contentInfo.LastHitsDate.HasValue) + { + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.LastHitsDate, contentInfo.LastHitsDate.Value.ToString(CultureInfo.InvariantCulture)); + } + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.Downloads, contentInfo.Downloads.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.Title, AtomUtility.Encrypt(contentInfo.Title)); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.IsTop, contentInfo.Top.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.IsRecommend, contentInfo.Recommend.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.IsHot, contentInfo.Hot.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.IsColor, contentInfo.Color.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.LinkUrl, AtomUtility.Encrypt(contentInfo.LinkUrl)); + if (contentInfo.AddDate.HasValue) + { + AtomUtility.AddDcElement(entry.AdditionalElements, ContentAttribute.AddDate, contentInfo.AddDate.Value.ToString(CultureInfo.InvariantCulture)); + } + + foreach (var attributeName in contentInfo.GetKeys(true)) + { + AtomUtility.AddDcElement(entry.AdditionalElements, attributeName, AtomUtility.Encrypt(contentInfo.Get(attributeName))); + } + + return entry; + } + } +} diff --git a/SiteServer.CMS/ImportExport/Components/RelatedFieldIe.cs b/net452/SiteServer.CMS/ImportExport/Components/RelatedFieldIe.cs similarity index 84% rename from SiteServer.CMS/ImportExport/Components/RelatedFieldIe.cs rename to net452/SiteServer.CMS/ImportExport/Components/RelatedFieldIe.cs index f8ed15a5f..fccd42c74 100644 --- a/SiteServer.CMS/ImportExport/Components/RelatedFieldIe.cs +++ b/net452/SiteServer.CMS/ImportExport/Components/RelatedFieldIe.cs @@ -1,8 +1,8 @@ using System.Collections.Generic; -using Atom.Core; using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils.Atom.Atom.Core; namespace SiteServer.CMS.ImportExport.Components { @@ -23,7 +23,7 @@ public void ExportRelatedField(RelatedFieldInfo relatedFieldInfo) var feed = ExportRelatedFieldInfo(relatedFieldInfo); - var relatedFieldItemInfoList = DataProvider.RelatedFieldItemDao.GetRelatedFieldItemInfoList(relatedFieldInfo.Id, 0); + var relatedFieldItemInfoList = DataProvider.RelatedFieldItem.GetRelatedFieldItemInfoList(relatedFieldInfo.Id, 0); foreach (var relatedFieldItemInfo in relatedFieldItemInfoList) { @@ -60,7 +60,7 @@ private static void AddAtomEntry(AtomFeed feed, RelatedFieldItemInfo relatedFiel feed.Entries.Add(entry); - var relatedFieldItemInfoList = DataProvider.RelatedFieldItemDao.GetRelatedFieldItemInfoList(relatedFieldItemInfo.RelatedFieldId, relatedFieldItemInfo.Id); + var relatedFieldItemInfoList = DataProvider.RelatedFieldItem.GetRelatedFieldItemInfoList(relatedFieldItemInfo.RelatedFieldId, relatedFieldItemInfo.Id); foreach (var itemInfo in relatedFieldItemInfoList) { @@ -82,22 +82,29 @@ public void ImportRelatedField(bool overwrite) var prefixes = AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(RelatedFieldInfo.Prefixes)); var suffixes = AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(RelatedFieldInfo.Suffixes)); - var relatedFieldInfo = new RelatedFieldInfo(0, title, _siteId, totalLevel, prefixes, suffixes); + var relatedFieldInfo = new RelatedFieldInfo + { + Title = title, + SiteId = _siteId, + TotalLevel = totalLevel, + Prefixes = suffixes, + Suffixes = suffixes + }; - var srcRelatedFieldInfo = DataProvider.RelatedFieldDao.GetRelatedFieldInfo(_siteId, title); + var srcRelatedFieldInfo = DataProvider.RelatedField.GetRelatedFieldInfo(_siteId, title); if (srcRelatedFieldInfo != null) { if (overwrite) { - DataProvider.RelatedFieldDao.Delete(srcRelatedFieldInfo.Id); + DataProvider.RelatedField.Delete(srcRelatedFieldInfo.Id); } else { - relatedFieldInfo.Title = DataProvider.RelatedFieldDao.GetImportTitle(_siteId, relatedFieldInfo.Title); + relatedFieldInfo.Title = DataProvider.RelatedField.GetImportTitle(_siteId, relatedFieldInfo.Title); } } - var relatedFieldId = DataProvider.RelatedFieldDao.Insert(relatedFieldInfo); + var relatedFieldId = DataProvider.RelatedField.Insert(relatedFieldInfo); var lastInertedLevel = 1; var lastInsertedParentId = 0; @@ -113,8 +120,14 @@ public void ImportRelatedField(bool overwrite) parentId = level != lastInertedLevel ? lastInsertedId : lastInsertedParentId; } - var relatedFieldItemInfo = new RelatedFieldItemInfo(0, relatedFieldId, itemName, itemValue, parentId, 0); - lastInsertedId = DataProvider.RelatedFieldItemDao.Insert(relatedFieldItemInfo); + var relatedFieldItemInfo = new RelatedFieldItemInfo + { + RelatedFieldId = relatedFieldId, + ItemName = itemName, + ItemValue = itemValue, + ParentId = parentId + }; + lastInsertedId = DataProvider.RelatedFieldItem.Insert(relatedFieldItemInfo); lastInsertedParentId = parentId; lastInertedLevel = level; } diff --git a/SiteServer.CMS/ImportExport/Components/SiteIe.cs b/net452/SiteServer.CMS/ImportExport/Components/SiteIe.cs similarity index 77% rename from SiteServer.CMS/ImportExport/Components/SiteIe.cs rename to net452/SiteServer.CMS/ImportExport/Components/SiteIe.cs index b0fd22281..422ef551f 100644 --- a/SiteServer.CMS/ImportExport/Components/SiteIe.cs +++ b/net452/SiteServer.CMS/ImportExport/Components/SiteIe.cs @@ -1,9 +1,12 @@ using System; -using Atom.Core; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.Utils.Enumerations; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils.Atom.Atom.Core; namespace SiteServer.CMS.ImportExport.Components { @@ -24,8 +27,8 @@ public SiteIe(SiteInfo siteInfo, string siteContentDirectoryPath) public int ImportChannelsAndContents(string filePath, bool isImportContents, bool isOverride, int theParentId, string adminName) { - var psChildCount = DataProvider.ChannelDao.GetCount(_siteInfo.Id); - var indexNameList = DataProvider.ChannelDao.GetIndexNameList(_siteInfo.Id); + var psChildCount = DataProvider.Channel.GetCount(_siteInfo.Id); + var indexNameList = DataProvider.Channel.GetIndexNameList(_siteInfo.Id); if (!FileUtils.IsFileExists(filePath)) return 0; var feed = AtomFeed.Load(FileUtils.GetFileStreamReadOnly(filePath)); @@ -54,7 +57,7 @@ public int ImportChannelsAndContents(string filePath, bool isImportContents, boo orderString = orderString.Substring(0, orderString.LastIndexOf("_", StringComparison.Ordinal)); } - var parentId = DataProvider.ChannelDao.GetId(_siteInfo.Id, orderString); + var parentId = DataProvider.Channel.GetId(_siteInfo.Id, orderString); if (theParentId != 0) { parentId = theParentId; @@ -68,7 +71,7 @@ public int ImportChannelsAndContents(string filePath, bool isImportContents, boo var nodeInfo = ChannelManager.GetChannelInfo(_siteInfo.Id, _siteInfo.Id); _channelIe.ImportNodeInfo(nodeInfo, feed.AdditionalElements, parentId, indexNameList); - DataProvider.ChannelDao.Update(nodeInfo); + DataProvider.Channel.Update(nodeInfo); if (isImportContents) { @@ -85,7 +88,7 @@ public int ImportChannelsAndContents(string filePath, bool isImportContents, boo var theSameNameChannelId = 0; if (isOverride) { - theSameNameChannelId = DataProvider.ChannelDao.GetIdByParentIdAndChannelName(_siteInfo.Id, parentId, nodeInfo.ChannelName, false); + theSameNameChannelId = ChannelManager.GetChannelIdByParentIdAndChannelName(_siteInfo.Id, parentId, nodeInfo.ChannelName, false); if (theSameNameChannelId != 0) { isUpdate = true; @@ -93,18 +96,17 @@ public int ImportChannelsAndContents(string filePath, bool isImportContents, boo } if (!isUpdate) { - channelId = DataProvider.ChannelDao.Insert(nodeInfo); + channelId = DataProvider.Channel.Insert(nodeInfo); } else { channelId = theSameNameChannelId; nodeInfo = ChannelManager.GetChannelInfo(_siteInfo.Id, theSameNameChannelId); - var tableName = ChannelManager.GetTableName(_siteInfo, nodeInfo); _channelIe.ImportNodeInfo(nodeInfo, feed.AdditionalElements, parentId, indexNameList); - DataProvider.ChannelDao.Update(nodeInfo); + DataProvider.Channel.Update(nodeInfo); - DataProvider.ContentDao.DeleteContentsByChannelId(_siteInfo.Id, tableName, theSameNameChannelId); + //nodeInfo.ContentRepository.DeleteContentsByChannelId(_siteInfo.Id, theSameNameChannelId); } if (isImportContents) @@ -118,25 +120,25 @@ public int ImportChannelsAndContents(string filePath, bool isImportContents, boo public void Export(int siteId, int channelId, bool isSaveContents) { - var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); - if (nodeInfo == null) return; + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return; var siteInfo = SiteManager.GetSiteInfo(siteId); - var tableName = ChannelManager.GetTableName(siteInfo, nodeInfo); + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); - var fileName = DataProvider.ChannelDao.GetOrderStringInSite(channelId); + var fileName = DataProvider.Channel.GetOrderStringInSite(channelId); var filePath = _siteContentDirectoryPath + PathUtils.SeparatorChar + fileName + ".xml"; - var feed = _channelIe.ExportNodeInfo(nodeInfo); + var feed = _channelIe.ExportNodeInfo(channelInfo); if (isSaveContents) { var orderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByTaxis); - var contentIdList = DataProvider.ContentDao.GetContentIdListChecked(tableName, channelId, orderByString); + var contentIdList = DataProvider.ContentRepository.GetContentIdListChecked(tableName, channelId, orderByString); foreach (var contentId in contentIdList) { - var contentInfo = DataProvider.ContentDao.GetContentInfo(tableName, contentId); + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); //ContentUtility.PutImagePaths(siteInfo, contentInfo as BackgroundContentInfo, collection); var entry = _contentIe.ExportContentInfo(contentInfo); feed.Entries.Add(entry); diff --git a/SiteServer.CMS/ImportExport/Components/TableStyleIe.cs b/net452/SiteServer.CMS/ImportExport/Components/TableStyleIe.cs similarity index 78% rename from SiteServer.CMS/ImportExport/Components/TableStyleIe.cs rename to net452/SiteServer.CMS/ImportExport/Components/TableStyleIe.cs index 4367d6f77..06e4d292f 100644 --- a/SiteServer.CMS/ImportExport/Components/TableStyleIe.cs +++ b/net452/SiteServer.CMS/ImportExport/Components/TableStyleIe.cs @@ -1,8 +1,10 @@ using System.Collections.Generic; -using Atom.Core; +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils.Atom.Atom.Core; namespace SiteServer.CMS.ImportExport.Components { @@ -21,7 +23,7 @@ public void ExportTableStyles(int siteId, string tableName) { var allRelatedIdentities = ChannelManager.GetChannelIdList(siteId); allRelatedIdentities.Insert(0, 0); - var tableStyleInfoWithItemsDict = TableStyleManager.GetTableStyleInfoWithItemsDictinary(tableName, allRelatedIdentities); + var tableStyleInfoWithItemsDict = TableStyleManager.GetTableStyleInfoWithItemsDictionary(tableName, allRelatedIdentities); if (tableStyleInfoWithItemsDict == null || tableStyleInfoWithItemsDict.Count <= 0) return; var styleDirectoryPath = PathUtils.Combine(_directoryPath, tableName); @@ -71,10 +73,10 @@ private static AtomFeed ExportTableStyleInfo(TableStyleInfo tableStyleInfo) AtomUtility.AddDcElement(feed.AdditionalElements, nameof(TableStyleInfo.Taxis), tableStyleInfo.Taxis.ToString()); AtomUtility.AddDcElement(feed.AdditionalElements, nameof(TableStyleInfo.DisplayName), tableStyleInfo.DisplayName); AtomUtility.AddDcElement(feed.AdditionalElements, nameof(TableStyleInfo.HelpText), tableStyleInfo.HelpText); - AtomUtility.AddDcElement(feed.AdditionalElements, nameof(TableStyleInfo.IsVisibleInList), tableStyleInfo.IsVisibleInList.ToString()); - AtomUtility.AddDcElement(feed.AdditionalElements, nameof(TableStyleInfo.InputType), tableStyleInfo.InputType.Value); + AtomUtility.AddDcElement(feed.AdditionalElements, nameof(TableStyleInfo.VisibleInList), tableStyleInfo.VisibleInList.ToString()); + AtomUtility.AddDcElement(feed.AdditionalElements, nameof(TableStyleInfo.Type), tableStyleInfo.Type.Value); AtomUtility.AddDcElement(feed.AdditionalElements, nameof(TableStyleInfo.DefaultValue), tableStyleInfo.DefaultValue); - AtomUtility.AddDcElement(feed.AdditionalElements, nameof(TableStyleInfo.IsHorizontal), tableStyleInfo.IsHorizontal.ToString()); + AtomUtility.AddDcElement(feed.AdditionalElements, nameof(TableStyleInfo.Horizontal), tableStyleInfo.Horizontal.ToString()); //SettingsXML AtomUtility.AddDcElement(feed.AdditionalElements, nameof(TableStyleInfo.ExtendValues), tableStyleInfo.ExtendValues); @@ -82,7 +84,7 @@ private static AtomFeed ExportTableStyleInfo(TableStyleInfo tableStyleInfo) var orderString = string.Empty; if (tableStyleInfo.RelatedIdentity != 0) { - orderString = DataProvider.ChannelDao.GetOrderStringInSite(tableStyleInfo.RelatedIdentity); + orderString = DataProvider.Channel.GetOrderStringInSite(tableStyleInfo.RelatedIdentity); } AtomUtility.AddDcElement(feed.AdditionalElements, "OrderString", orderString); @@ -98,24 +100,25 @@ private static AtomEntry ExportTableStyleItemInfo(TableStyleItemInfo styleItemIn AtomUtility.AddDcElement(entry.AdditionalElements, new List { nameof(TableStyleItemInfo.TableStyleId), "TableStyleID" }, styleItemInfo.TableStyleId.ToString()); AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TableStyleItemInfo.ItemTitle), styleItemInfo.ItemTitle); AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TableStyleItemInfo.ItemValue), styleItemInfo.ItemValue); - AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TableStyleItemInfo.IsSelected), styleItemInfo.IsSelected.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TableStyleItemInfo.Selected), styleItemInfo.Selected.ToString()); return entry; } public static void SingleExportTableStyles(string tableName, int siteId, int relatedIdentity, string styleDirectoryPath) { - var relatedIdentities = RelatedIdentities.GetRelatedIdentities(siteId, relatedIdentity); + var channelInfo = ChannelManager.GetChannelInfo(siteId, relatedIdentity); + var relatedIdentities = TableStyleManager.GetRelatedIdentities(channelInfo); DirectoryUtils.DeleteDirectoryIfExists(styleDirectoryPath); DirectoryUtils.CreateDirectoryIfNotExists(styleDirectoryPath); - var styleInfoList = TableStyleManager.GetTableStyleInfoList(tableName, relatedIdentities); + var styleInfoList = TableStyleManager.GetStyleInfoList(tableName, relatedIdentities); foreach (var tableStyleInfo in styleInfoList) { var filePath = PathUtils.Combine(styleDirectoryPath, tableStyleInfo.AttributeName + ".xml"); var feed = ExportTableStyleInfo(tableStyleInfo); - var styleItems = DataProvider.TableStyleItemDao.GetStyleItemInfoList(tableStyleInfo.Id); + var styleItems = tableStyleInfo.StyleItems; if (styleItems != null && styleItems.Count > 0) { foreach (var styleItemInfo in styleItems) @@ -135,12 +138,12 @@ public static void SingleExportTableStyles(string tableName, string styleDirecto DirectoryUtils.DeleteDirectoryIfExists(styleDirectoryPath); DirectoryUtils.CreateDirectoryIfNotExists(styleDirectoryPath); - var styleInfoList = TableStyleManager.GetTableStyleInfoList(tableName, relatedIdentities); + var styleInfoList = TableStyleManager.GetStyleInfoList(tableName, relatedIdentities); foreach (var tableStyleInfo in styleInfoList) { var filePath = PathUtils.Combine(styleDirectoryPath, tableStyleInfo.AttributeName + ".xml"); var feed = ExportTableStyleInfo(tableStyleInfo); - var styleItems = DataProvider.TableStyleItemDao.GetStyleItemInfoList(tableStyleInfo.Id); + var styleItems = tableStyleInfo.StyleItems; if (styleItems != null && styleItems.Count > 0) { foreach (var styleItemInfo in styleItems) @@ -163,26 +166,44 @@ public static void SingleImportTableStyle(string tableName, string styleDirector var feed = AtomFeed.Load(FileUtils.GetFileStreamReadOnly(filePath)); var attributeName = AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.AttributeName)); - var taxis = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.Taxis)), 0); + var taxis = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.Taxis))); var displayName = AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.DisplayName)); var helpText = AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.HelpText)); - var isVisibleInList = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.IsVisibleInList))); - var inputType = InputTypeUtils.GetEnumType(AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.InputType))); + var isVisibleInList = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.VisibleInList))); + var inputType = InputTypeUtils.GetEnumType(AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.Type))); var defaultValue = AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.DefaultValue)); - var isHorizontal = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.IsHorizontal))); + var isHorizontal = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.Horizontal))); //SettingsXML var extendValues = AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.ExtendValues)); - var styleInfo = new TableStyleInfo(0, relatedIdentity, tableName, attributeName, taxis, displayName, helpText, isVisibleInList, inputType, defaultValue, isHorizontal, extendValues); + var styleInfo = new TableStyleInfo + { + RelatedIdentity = relatedIdentity, + TableName = tableName, + AttributeName = attributeName, + Taxis = taxis, + DisplayName = displayName, + HelpText = helpText, + VisibleInList = isVisibleInList, + Type = inputType, + DefaultValue = defaultValue, + Horizontal = isHorizontal, + ExtendValues = extendValues + }; var styleItems = new List(); foreach (AtomEntry entry in feed.Entries) { var itemTitle = AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TableStyleItemInfo.ItemTitle)); var itemValue = AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TableStyleItemInfo.ItemValue)); - var isSelected = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TableStyleItemInfo.IsSelected))); + var isSelected = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TableStyleItemInfo.Selected))); - styleItems.Add(new TableStyleItemInfo(0, 0, itemTitle, itemValue, isSelected)); + styleItems.Add(new TableStyleItemInfo + { + ItemTitle = itemTitle, + ItemValue = itemValue, + Selected = isSelected + }); } if (styleItems.Count > 0) @@ -192,9 +213,9 @@ public static void SingleImportTableStyle(string tableName, string styleDirector if (TableStyleManager.IsExists(relatedIdentity, tableName, attributeName)) { - TableStyleManager.Delete(relatedIdentity, tableName, attributeName); + DataProvider.TableStyle.Delete(relatedIdentity, tableName, attributeName); } - TableStyleManager.Insert(styleInfo); + DataProvider.TableStyle.Insert(styleInfo); } } @@ -212,7 +233,7 @@ public void ImportTableStyles(int siteId) var tableName = PathUtils.GetDirectoryName(styleDirectoryPath, false); if (tableName == "siteserver_PublishmentSystem") { - tableName = DataProvider.SiteDao.TableName; + tableName = DataProvider.Site.TableName; } if (!string.IsNullOrEmpty(tableNameCollection?[tableName])) { @@ -228,31 +249,49 @@ public void ImportTableStyles(int siteId) { var feed = AtomFeed.Load(FileUtils.GetFileStreamReadOnly(filePath)); - var taxis = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.Taxis)), 0); + var taxis = TranslateUtils.ToInt(AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.Taxis))); var displayName = AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.DisplayName)); var helpText = AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.HelpText)); - var isVisibleInList = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.IsVisibleInList))); - var inputType = InputTypeUtils.GetEnumType(AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.InputType))); + var isVisibleInList = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.VisibleInList))); + var inputType = InputTypeUtils.GetEnumType(AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.Type))); var defaultValue = AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.DefaultValue)); - var isHorizontal = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.IsHorizontal))); + var isHorizontal = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.Horizontal))); var extendValues = AtomUtility.GetDcElementContent(feed.AdditionalElements, nameof(TableStyleInfo.ExtendValues)); var orderString = AtomUtility.GetDcElementContent(feed.AdditionalElements, "OrderString"); - var relatedIdentity = !string.IsNullOrEmpty(orderString) ? DataProvider.ChannelDao.GetId(siteId, orderString) : siteId; + var relatedIdentity = !string.IsNullOrEmpty(orderString) ? DataProvider.Channel.GetId(siteId, orderString) : siteId; if (relatedIdentity <= 0 || TableStyleManager.IsExists(relatedIdentity, tableName, attributeName)) continue; - var styleInfo = new TableStyleInfo(0, relatedIdentity, tableName, attributeName, taxis, displayName, helpText, isVisibleInList, inputType, defaultValue, isHorizontal, extendValues); + var styleInfo = new TableStyleInfo + { + RelatedIdentity = relatedIdentity, + TableName = tableName, + AttributeName = attributeName, + Taxis = taxis, + DisplayName = displayName, + HelpText = helpText, + VisibleInList = isVisibleInList, + Type = inputType, + DefaultValue = defaultValue, + Horizontal = isHorizontal, + ExtendValues = extendValues + }; var styleItems = new List(); foreach (AtomEntry entry in feed.Entries) { var itemTitle = AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TableStyleItemInfo.ItemTitle)); var itemValue = AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TableStyleItemInfo.ItemValue)); - var isSelected = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TableStyleItemInfo.IsSelected))); - - styleItems.Add(new TableStyleItemInfo(0, 0, itemTitle, itemValue, isSelected)); + var isSelected = TranslateUtils.ToBool(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TableStyleItemInfo.Selected))); + + styleItems.Add(new TableStyleItemInfo + { + ItemTitle = itemTitle, + ItemValue = itemValue, + Selected = isSelected + }); } if (styleItems.Count > 0) @@ -260,7 +299,7 @@ public void ImportTableStyles(int siteId) styleInfo.StyleItems = styleItems; } - TableStyleManager.Insert(styleInfo); + DataProvider.TableStyle.Insert(styleInfo); } } } diff --git a/SiteServer.CMS/ImportExport/Components/TemplateIe.cs b/net452/SiteServer.CMS/ImportExport/Components/TemplateIe.cs similarity index 75% rename from SiteServer.CMS/ImportExport/Components/TemplateIe.cs rename to net452/SiteServer.CMS/ImportExport/Components/TemplateIe.cs index 541fffa07..da4948240 100644 --- a/SiteServer.CMS/ImportExport/Components/TemplateIe.cs +++ b/net452/SiteServer.CMS/ImportExport/Components/TemplateIe.cs @@ -1,11 +1,12 @@ using System.Collections.Generic; -using Atom.Core; +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; using SiteServer.CMS.Core.Create; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; using SiteServer.Plugin; -using SiteServer.Utils.Enumerations; +using SiteServer.Utils.Atom.Atom.Core; namespace SiteServer.CMS.ImportExport.Components { @@ -24,7 +25,7 @@ public void ExportTemplates() { var feed = AtomUtility.GetEmptyFeed(); - var templateInfoList = DataProvider.TemplateDao.GetTemplateInfoListBySiteId(_siteId); + var templateInfoList = DataProvider.Template.GetTemplateInfoListBySiteId(_siteId); foreach (var templateInfo in templateInfoList) { @@ -38,7 +39,7 @@ public void ExportTemplates(List templateIdList) { var feed = AtomUtility.GetEmptyFeed(); - var templateInfoList = DataProvider.TemplateDao.GetTemplateInfoListBySiteId(_siteId); + var templateInfoList = DataProvider.Template.GetTemplateInfoListBySiteId(_siteId); foreach (var templateInfo in templateInfoList) { @@ -60,12 +61,11 @@ private AtomEntry ExportTemplateInfo(TemplateInfo templateInfo) AtomUtility.AddDcElement(entry.AdditionalElements, new List{ nameof(TemplateInfo.Id), "TemplateID" }, templateInfo.Id.ToString()); AtomUtility.AddDcElement(entry.AdditionalElements, new List { nameof(TemplateInfo.SiteId), "PublishmentSystemID" }, templateInfo.SiteId.ToString()); AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TemplateInfo.TemplateName), templateInfo.TemplateName); - AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TemplateInfo.TemplateType), templateInfo.TemplateType.Value); + AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TemplateInfo.Type), templateInfo.Type.Value); AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TemplateInfo.RelatedFileName), templateInfo.RelatedFileName); AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TemplateInfo.CreatedFileFullName), templateInfo.CreatedFileFullName); AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TemplateInfo.CreatedFileExtName), templateInfo.CreatedFileExtName); - AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TemplateInfo.Charset), ECharsetUtils.GetValue(templateInfo.Charset)); - AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TemplateInfo.IsDefault), templateInfo.IsDefault.ToString()); + AtomUtility.AddDcElement(entry.AdditionalElements, nameof(TemplateInfo.Default), templateInfo.Default.ToString()); var templateContent = TemplateManager.GetTemplateContent(siteInfo, templateInfo); AtomUtility.AddDcElement(entry.AdditionalElements, "Content", AtomUtility.Encrypt(templateContent)); @@ -88,18 +88,17 @@ public void ImportTemplates(bool overwrite, string administratorName) { SiteId = _siteId, TemplateName = templateName, - TemplateType = - TemplateTypeUtils.GetEnumType(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TemplateInfo.TemplateType))), + Type = + TemplateTypeUtils.GetEnumType(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TemplateInfo.Type))), RelatedFileName = AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TemplateInfo.RelatedFileName)), CreatedFileFullName = AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TemplateInfo.CreatedFileFullName)), CreatedFileExtName = AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TemplateInfo.CreatedFileExtName)), - Charset = ECharsetUtils.GetEnumType(AtomUtility.GetDcElementContent(entry.AdditionalElements, nameof(TemplateInfo.Charset))), - IsDefault = false + Default = false }; var templateContent = AtomUtility.Decrypt(AtomUtility.GetDcElementContent(entry.AdditionalElements, "Content")); - var srcTemplateInfo = TemplateManager.GetTemplateInfoByTemplateName(_siteId, templateInfo.TemplateType, templateInfo.TemplateName); + var srcTemplateInfo = TemplateManager.GetTemplateInfoByTemplateName(_siteId, templateInfo.Type, templateInfo.TemplateName); int templateId; @@ -108,25 +107,24 @@ public void ImportTemplates(bool overwrite, string administratorName) if (overwrite) { srcTemplateInfo.RelatedFileName = templateInfo.RelatedFileName; - srcTemplateInfo.TemplateType = templateInfo.TemplateType; + srcTemplateInfo.Type = templateInfo.Type; srcTemplateInfo.CreatedFileFullName = templateInfo.CreatedFileFullName; srcTemplateInfo.CreatedFileExtName = templateInfo.CreatedFileExtName; - srcTemplateInfo.Charset = templateInfo.Charset; - DataProvider.TemplateDao.Update(siteInfo, srcTemplateInfo, templateContent, administratorName); + DataProvider.Template.Update(siteInfo, srcTemplateInfo, templateContent, administratorName); templateId = srcTemplateInfo.Id; } else { - templateInfo.TemplateName = DataProvider.TemplateDao.GetImportTemplateName(_siteId, templateInfo.TemplateName); - templateId = DataProvider.TemplateDao.Insert(templateInfo, templateContent, administratorName); + templateInfo.TemplateName = DataProvider.Template.GetImportTemplateName(_siteId, templateInfo.TemplateName); + templateId = DataProvider.Template.Insert(templateInfo, templateContent, administratorName); } } else { - templateId = DataProvider.TemplateDao.Insert(templateInfo, templateContent, administratorName); + templateId = DataProvider.Template.Insert(templateInfo, templateContent, administratorName); } - if (templateInfo.TemplateType == TemplateType.FileTemplate) + if (templateInfo.Type == TemplateType.FileTemplate) { CreateManager.CreateFile(_siteId, templateId); } diff --git a/SiteServer.CMS/ImportExport/ExportObject.cs b/net452/SiteServer.CMS/ImportExport/ExportObject.cs similarity index 85% rename from SiteServer.CMS/ImportExport/ExportObject.cs rename to net452/SiteServer.CMS/ImportExport/ExportObject.cs index 19cd1dca5..bc464fae2 100644 --- a/SiteServer.CMS/ImportExport/ExportObject.cs +++ b/net452/SiteServer.CMS/ImportExport/ExportObject.cs @@ -1,10 +1,14 @@ using System.Collections; using System.Collections.Generic; +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.CMS.ImportExport.Components; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; +using SiteServer.Utils.Atom.Atom.Core; using SiteServer.Utils.Enumerations; using SiteServer.Utils.IO; @@ -30,7 +34,7 @@ public void ExportFilesToSite(string siteTemplatePath, bool isSaveAll, ArrayList { DirectoryUtils.CreateDirectoryIfNotExists(siteTemplatePath); - var siteDirList = DataProvider.SiteDao.GetLowerSiteDirListThatNotIsRoot(); + var siteDirList = DataProvider.Site.GetLowerSiteDirListThatNotIsRoot(); var fileSystems = FileManager.GetFileSystemInfoExtendCollection(PathUtility.GetSitePath(_siteInfo), true); foreach (FileSystemInfoExtend fileSystem in fileSystems) @@ -44,7 +48,7 @@ public void ExportFilesToSite(string siteTemplatePath, bool isSaveAll, ArrayList { var isSiteDirectory = false; - if (_siteInfo.IsRoot) + if (_siteInfo.Root) { foreach (var siteDir in siteDirList) { @@ -86,7 +90,7 @@ public void ExportFiles(string filePath) DirectoryUtils.Copy(_sitePath, filesDirectoryPath); - ZipUtils.PackFiles(filePath, filesDirectoryPath); + ZipUtils.CreateZip(filePath, filesDirectoryPath); DirectoryUtils.DeleteDirectoryIfExists(filesDirectoryPath); } @@ -96,7 +100,7 @@ public string ExportSingleTableStyle(string tableName, int relatedIdentity) var filePath = PathUtils.GetTemporaryFilesPath("tableStyle.zip"); var styleDirectoryPath = PathUtils.GetTemporaryFilesPath("TableStyle"); TableStyleIe.SingleExportTableStyles(tableName, _siteInfo.Id, relatedIdentity, styleDirectoryPath); - ZipUtils.PackFiles(filePath, styleDirectoryPath); + ZipUtils.CreateZip(filePath, styleDirectoryPath); DirectoryUtils.DeleteDirectoryIfExists(styleDirectoryPath); @@ -108,7 +112,7 @@ public static string ExportRootSingleTableStyle(string tableName) var filePath = PathUtils.GetTemporaryFilesPath("tableStyle.zip"); var styleDirectoryPath = PathUtils.GetTemporaryFilesPath("TableStyle"); TableStyleIe.SingleExportTableStyles(tableName, styleDirectoryPath); - ZipUtils.PackFiles(filePath, styleDirectoryPath); + ZipUtils.CreateZip(filePath, styleDirectoryPath); DirectoryUtils.DeleteDirectoryIfExists(styleDirectoryPath); @@ -142,7 +146,7 @@ public void ExportRelatedField(string relatedFieldDirectoryPath) DirectoryUtils.CreateDirectoryIfNotExists(relatedFieldDirectoryPath); var relatedFieldIe = new RelatedFieldIe(_siteInfo.Id, relatedFieldDirectoryPath); - var relatedFieldInfoList = DataProvider.RelatedFieldDao.GetRelatedFieldInfoList(_siteInfo.Id); + var relatedFieldInfoList = DataProvider.RelatedField.GetRelatedFieldInfoList(_siteInfo.Id); foreach (var relatedFieldInfo in relatedFieldInfoList) { relatedFieldIe.ExportRelatedField(relatedFieldInfo); @@ -158,12 +162,12 @@ public string ExportRelatedField(int relatedFieldId) DirectoryUtils.DeleteDirectoryIfExists(directoryPath); DirectoryUtils.CreateDirectoryIfNotExists(directoryPath); - var relatedFieldInfo = DataProvider.RelatedFieldDao.GetRelatedFieldInfo(relatedFieldId); + var relatedFieldInfo = DataProvider.RelatedField.Get(relatedFieldId); var relatedFieldIe = new RelatedFieldIe(_siteInfo.Id, directoryPath); relatedFieldIe.ExportRelatedField(relatedFieldInfo); - ZipUtils.PackFiles(filePath, directoryPath); + ZipUtils.CreateZip(filePath, directoryPath); DirectoryUtils.DeleteDirectoryIfExists(directoryPath); @@ -175,7 +179,6 @@ public string ExportRelatedField(int relatedFieldId) public void ExportTablesAndStyles(string tableDirectoryPath) { DirectoryUtils.CreateDirectoryIfNotExists(tableDirectoryPath); - var tableIe = new TableIe(tableDirectoryPath); var styleIe = new TableStyleIe(tableDirectoryPath, _adminName); var siteInfo = SiteManager.GetSiteInfo(_siteInfo.Id); @@ -183,12 +186,11 @@ public void ExportTablesAndStyles(string tableDirectoryPath) foreach (var tableName in tableNameList) { - tableIe.ExportAuxiliaryTable(tableName); styleIe.ExportTableStyles(siteInfo.Id, tableName); } - styleIe.ExportTableStyles(siteInfo.Id, DataProvider.ChannelDao.TableName); - styleIe.ExportTableStyles(siteInfo.Id, DataProvider.SiteDao.TableName); + styleIe.ExportTableStyles(siteInfo.Id, DataProvider.Channel.TableName); + styleIe.ExportTableStyles(siteInfo.Id, DataProvider.Site.TableName); } @@ -277,23 +279,23 @@ public string ExportChannels(List channelIdList, string filePath) siteIe.Export(_siteInfo.Id, channelId, true); } - var imageUploadDirectoryPath = PathUtils.Combine(siteContentDirectoryPath, _siteInfo.Additional.ImageUploadDirectoryName); + var imageUploadDirectoryPath = PathUtils.Combine(siteContentDirectoryPath, _siteInfo.ImageUploadDirectoryName); DirectoryUtils.DeleteDirectoryIfExists(imageUploadDirectoryPath); - DirectoryUtils.Copy(PathUtils.Combine(_sitePath, _siteInfo.Additional.ImageUploadDirectoryName), imageUploadDirectoryPath); + DirectoryUtils.Copy(PathUtils.Combine(_sitePath, _siteInfo.ImageUploadDirectoryName), imageUploadDirectoryPath); - var videoUploadDirectoryPath = PathUtils.Combine(siteContentDirectoryPath, _siteInfo.Additional.VideoUploadDirectoryName); + var videoUploadDirectoryPath = PathUtils.Combine(siteContentDirectoryPath, _siteInfo.VideoUploadDirectoryName); DirectoryUtils.DeleteDirectoryIfExists(videoUploadDirectoryPath); - DirectoryUtils.Copy(PathUtils.Combine(_sitePath, _siteInfo.Additional.VideoUploadDirectoryName), videoUploadDirectoryPath); + DirectoryUtils.Copy(PathUtils.Combine(_sitePath, _siteInfo.VideoUploadDirectoryName), videoUploadDirectoryPath); - var fileUploadDirectoryPath = PathUtils.Combine(siteContentDirectoryPath, _siteInfo.Additional.FileUploadDirectoryName); + var fileUploadDirectoryPath = PathUtils.Combine(siteContentDirectoryPath, _siteInfo.FileUploadDirectoryName); DirectoryUtils.DeleteDirectoryIfExists(fileUploadDirectoryPath); - DirectoryUtils.Copy(PathUtils.Combine(_sitePath, _siteInfo.Additional.FileUploadDirectoryName), fileUploadDirectoryPath); + DirectoryUtils.Copy(PathUtils.Combine(_sitePath, _siteInfo.FileUploadDirectoryName), fileUploadDirectoryPath); - Atom.Core.AtomFeed feed = AtomUtility.GetEmptyFeed(); + AtomFeed feed = AtomUtility.GetEmptyFeed(); var entry = AtomUtility.GetEmptyEntry(); - AtomUtility.AddDcElement(entry.AdditionalElements, "ImageUploadDirectoryName", _siteInfo.Additional.ImageUploadDirectoryName); - AtomUtility.AddDcElement(entry.AdditionalElements, "VideoUploadDirectoryName", _siteInfo.Additional.VideoUploadDirectoryName); - AtomUtility.AddDcElement(entry.AdditionalElements, "FileUploadDirectoryName", _siteInfo.Additional.FileUploadDirectoryName); + AtomUtility.AddDcElement(entry.AdditionalElements, "ImageUploadDirectoryName", _siteInfo.ImageUploadDirectoryName); + AtomUtility.AddDcElement(entry.AdditionalElements, "VideoUploadDirectoryName", _siteInfo.VideoUploadDirectoryName); + AtomUtility.AddDcElement(entry.AdditionalElements, "FileUploadDirectoryName", _siteInfo.FileUploadDirectoryName); feed.Entries.Add(entry); var uploadFolderPath = PathUtils.Combine(siteContentDirectoryPath, BackupUtility.UploadFolderName); @@ -301,7 +303,7 @@ public string ExportChannels(List channelIdList, string filePath) var uploadFilePath = PathUtils.Combine(uploadFolderPath, BackupUtility.UploadFileName); feed.Save(uploadFilePath); - ZipUtils.PackFiles(filePath, siteContentDirectoryPath); + ZipUtils.CreateZip(filePath, siteContentDirectoryPath); DirectoryUtils.DeleteDirectoryIfExists(siteContentDirectoryPath); @@ -320,7 +322,25 @@ public bool ExportContents(string filePath, int channelId, List contentIdAr var isExport = contentIe.ExportContents(_siteInfo, channelId, contentIdArrayList, isPeriods, dateFrom, dateTo, checkedState); if (isExport) { - ZipUtils.PackFiles(filePath, siteContentDirectoryPath); + ZipUtils.CreateZip(filePath, siteContentDirectoryPath); + DirectoryUtils.DeleteDirectoryIfExists(siteContentDirectoryPath); + } + return isExport; + } + + public bool ExportContents(string filePath, List contentInfoList) + { + var siteContentDirectoryPath = PathUtils.Combine(DirectoryUtils.GetDirectoryPath(filePath), PathUtils.GetFileNameWithoutExtension(filePath)); + + FileUtils.DeleteFileIfExists(filePath); + DirectoryUtils.DeleteDirectoryIfExists(siteContentDirectoryPath); + DirectoryUtils.CreateDirectoryIfNotExists(siteContentDirectoryPath); + + var contentIe = new ContentIe(_siteInfo, siteContentDirectoryPath); + var isExport = contentIe.ExportContents(_siteInfo, contentInfoList); + if (isExport) + { + ZipUtils.CreateZip(filePath, siteContentDirectoryPath); DirectoryUtils.DeleteDirectoryIfExists(siteContentDirectoryPath); } return isExport; diff --git a/net452/SiteServer.CMS/ImportExport/ImportObject.cs b/net452/SiteServer.CMS/ImportExport/ImportObject.cs new file mode 100644 index 000000000..d005895e8 --- /dev/null +++ b/net452/SiteServer.CMS/ImportExport/ImportObject.cs @@ -0,0 +1,672 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Text; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Core.Office; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.ImportExport.Components; +using SiteServer.Utils.Atom.Atom.Core; + +namespace SiteServer.CMS.ImportExport +{ + public class ImportObject + { + private readonly SiteInfo _siteInfo; + private readonly string _sitePath; + private readonly string _adminName; + + public ImportObject(int siteId, string adminName) + { + _siteInfo = SiteManager.GetSiteInfo(siteId); + _sitePath = PathUtils.Combine(WebConfigUtils.PhysicalApplicationPath, _siteInfo.SiteDir); + _adminName = adminName; + } + + //获取保存辅助表名称对应集合数据库缓存键 + private string GetTableNameNameValueCollectionDbCacheKey() + { + return "SiteServer.CMS.Core.ImportObject.TableNameNameValueCollection_" + _siteInfo.Id; + } + + public NameValueCollection GetTableNameCache() + { + NameValueCollection nameValueCollection = null; + var cacheValue = CacheDbUtils.GetValue(GetTableNameNameValueCollectionDbCacheKey()); + if (!string.IsNullOrEmpty(cacheValue)) + { + nameValueCollection = TranslateUtils.ToNameValueCollection(cacheValue); + } + return nameValueCollection; + } + + //public void SaveTableNameCache(NameValueCollection nameValueCollection) + //{ + // if (nameValueCollection != null && nameValueCollection.Count > 0) + // { + // var cacheKey = GetTableNameNameValueCollectionDbCacheKey(); + // var cacheValue = TranslateUtils.NameValueCollectionToString(nameValueCollection); + // CacheDbUtils.RemoveAndInsert(cacheKey, cacheValue); + // } + //} + + public void RemoveDbCache() + { + var cacheKey = GetTableNameNameValueCollectionDbCacheKey(); + CacheDbUtils.GetValueAndRemove(cacheKey); + } + + public void ImportFiles(string siteTemplatePath, bool isOverride) + { + //if (this.FSO.IsRoot) + //{ + // string[] filePaths = DirectoryUtils.GetFilePaths(siteTemplatePath); + // foreach (string filePath in filePaths) + // { + // string fileName = PathUtils.GetFileName(filePath); + // if (!PathUtility.IsSystemFile(fileName)) + // { + // string destFilePath = PathUtils.Combine(FSO.SitePath, fileName); + // FileUtils.MoveFile(filePath, destFilePath, isOverride); + // } + // } + + // ArrayList siteDirArrayList = DataProvider.SiteDAO.GetLowerSiteDirArrayListThatNotIsRoot(); + + // string[] directoryPaths = DirectoryUtils.GetDirectoryPaths(siteTemplatePath); + // foreach (string subDirectoryPath in directoryPaths) + // { + // string directoryName = PathUtils.GetDirectoryName(subDirectoryPath); + // if (!PathUtility.IsSystemDirectory(directoryName) && !siteDirArrayList.Contains(directoryName.ToLower())) + // { + // string destDirectoryPath = PathUtils.Combine(FSO.SitePath, directoryName); + // DirectoryUtils.MoveDirectory(subDirectoryPath, destDirectoryPath, isOverride); + // } + // } + //} + //else + //{ + // DirectoryUtils.MoveDirectory(siteTemplatePath, FSO.SitePath, isOverride); + //} + //string siteTemplateMetadataPath = PathUtils.Combine(FSO.SitePath, DirectoryUtility.SiteTemplates.SiteTemplateMetadata); + //DirectoryUtils.DeleteDirectoryIfExists(siteTemplateMetadataPath); + DirectoryUtility.ImportSiteFiles(_siteInfo, siteTemplatePath, isOverride); + } + + public void ImportSiteContent(string siteContentDirectoryPath, string filePath, bool isImportContents) + { + var siteIe = new SiteIe(_siteInfo, siteContentDirectoryPath); + siteIe.ImportChannelsAndContents(filePath, isImportContents, false, 0, _adminName); + } + + + /// + /// 从指定的地址导入网站模板至站点中 + /// + public void ImportTemplates(string filePath, bool overwrite, string administratorName) + { + var templateIe = new TemplateIe(_siteInfo.Id, filePath); + templateIe.ImportTemplates(overwrite, administratorName); + } + + public void ImportRelatedFieldByZipFile(string zipFilePath, bool overwrite) + { + var directoryPath = PathUtils.GetTemporaryFilesPath("RelatedField"); + DirectoryUtils.DeleteDirectoryIfExists(directoryPath); + DirectoryUtils.CreateDirectoryIfNotExists(directoryPath); + + ZipUtils.ExtractZip(zipFilePath, directoryPath); + + var relatedFieldIe = new RelatedFieldIe(_siteInfo.Id, directoryPath); + relatedFieldIe.ImportRelatedField(overwrite); + } + + public void ImportTableStyles(string tableDirectoryPath) + { + if (DirectoryUtils.IsDirectoryExists(tableDirectoryPath)) + { + var tableStyleIe = new TableStyleIe(tableDirectoryPath, _adminName); + tableStyleIe.ImportTableStyles(_siteInfo.Id); + } + } + + public static void ImportTableStyleByZipFile(string tableName, int channelId, string zipFilePath) + { + var styleDirectoryPath = PathUtils.GetTemporaryFilesPath("TableStyle"); + DirectoryUtils.DeleteDirectoryIfExists(styleDirectoryPath); + DirectoryUtils.CreateDirectoryIfNotExists(styleDirectoryPath); + + ZipUtils.ExtractZip(zipFilePath, styleDirectoryPath); + + TableStyleIe.SingleImportTableStyle(tableName, styleDirectoryPath, channelId); + } + + public void ImportConfiguration(string configurationFilePath) + { + var configIe = new ConfigurationIe(_siteInfo.Id, configurationFilePath); + configIe.Import(); + } + + + public void ImportChannelsAndContentsByZipFile(int parentId, string zipFilePath, bool isOverride) + { + var siteContentDirectoryPath = PathUtils.GetTemporaryFilesPath(EBackupTypeUtils.GetValue(EBackupType.ChannelsAndContents)); + DirectoryUtils.DeleteDirectoryIfExists(siteContentDirectoryPath); + DirectoryUtils.CreateDirectoryIfNotExists(siteContentDirectoryPath); + + ZipUtils.ExtractZip(zipFilePath, siteContentDirectoryPath); + + ImportChannelsAndContentsFromZip(parentId, siteContentDirectoryPath, isOverride); + + var uploadFolderPath = PathUtils.Combine(siteContentDirectoryPath, BackupUtility.UploadFolderName); + var uploadFilePath = PathUtils.Combine(uploadFolderPath, BackupUtility.UploadFileName); + if (!FileUtils.IsFileExists(uploadFilePath)) + { + return; + } + var feed = AtomFeed.Load(FileUtils.GetFileStreamReadOnly(uploadFilePath)); + if (feed != null) + { + AtomEntry entry = feed.Entries[0]; + string imageUploadDirectoryPath = AtomUtility.GetDcElementContent(entry.AdditionalElements, "ImageUploadDirectoryName"); + if(imageUploadDirectoryPath != null) + { + DirectoryUtils.MoveDirectory(PathUtils.Combine(siteContentDirectoryPath, imageUploadDirectoryPath), PathUtils.Combine(_sitePath, _siteInfo.ImageUploadDirectoryName), isOverride); + } + string videoUploadDirectoryPath = AtomUtility.GetDcElementContent(entry.AdditionalElements, "VideoUploadDirectoryName"); + if (videoUploadDirectoryPath != null) + { + DirectoryUtils.MoveDirectory(PathUtils.Combine(siteContentDirectoryPath, videoUploadDirectoryPath), PathUtils.Combine(_sitePath, _siteInfo.VideoUploadDirectoryName), isOverride); + } + string fileUploadDirectoryPath = AtomUtility.GetDcElementContent(entry.AdditionalElements, "FileUploadDirectoryName"); + if (fileUploadDirectoryPath != null) + { + DirectoryUtils.MoveDirectory(PathUtils.Combine(siteContentDirectoryPath, fileUploadDirectoryPath), PathUtils.Combine(_sitePath, _siteInfo.FileUploadDirectoryName), isOverride); + } + } + } + + private void ImportChannelsAndContentsFromZip(int parentId, string siteContentDirectoryPath, bool isOverride) + { + var filePathList = GetSiteContentFilePathList(siteContentDirectoryPath); + + var siteIe = new SiteIe(_siteInfo, siteContentDirectoryPath); + + Hashtable levelHashtable = null; + foreach (var filePath in filePathList) + { + var firstIndex = filePath.LastIndexOf(PathUtils.SeparatorChar) + 1; + var lastIndex = filePath.LastIndexOf(".", StringComparison.Ordinal); + var orderString = filePath.Substring(firstIndex, lastIndex - firstIndex); + + var level = StringUtils.GetCount("_", orderString); + + if (levelHashtable == null) + { + levelHashtable = new Hashtable + { + [level] = parentId + }; + } + + var insertChannelId = siteIe.ImportChannelsAndContents(filePath, true, isOverride, (int)levelHashtable[level], _adminName); + levelHashtable[level + 1] = insertChannelId; + } + } + + public void ImportChannelsAndContents(int parentId, string siteContentDirectoryPath, bool isOverride) + { + var filePathList = GetSiteContentFilePathList(siteContentDirectoryPath); + + var siteIe = new SiteIe(_siteInfo, siteContentDirectoryPath); + + var parentOrderString = "none"; + //int parentID = 0; + foreach (var filePath in filePathList) + { + var firstIndex = filePath.LastIndexOf(PathUtils.SeparatorChar) + 1; + var lastIndex = filePath.LastIndexOf(".", StringComparison.Ordinal); + var orderString = filePath.Substring(firstIndex, lastIndex - firstIndex); + + if (StringUtils.StartsWithIgnoreCase(orderString, parentOrderString)) + { + parentId = siteIe.ImportChannelsAndContents(filePath, true, isOverride, parentId, _adminName); + parentOrderString = orderString; + } + else + { + siteIe.ImportChannelsAndContents(filePath, true, isOverride, parentId, _adminName); + } + } + } + + public void ImportContentsByZipFile(ChannelInfo channelInfo, string zipFilePath, bool isOverride, int importStart, int importCount, bool isChecked, int checkedLevel) + { + var siteContentDirectoryPath = PathUtils.GetTemporaryFilesPath("contents"); + DirectoryUtils.DeleteDirectoryIfExists(siteContentDirectoryPath); + DirectoryUtils.CreateDirectoryIfNotExists(siteContentDirectoryPath); + + ZipUtils.ExtractZip(zipFilePath, siteContentDirectoryPath); + + var taxis = channelInfo.ContentRepository.GetMaxTaxis(channelInfo.Id, false); + + ImportContents(channelInfo, siteContentDirectoryPath, isOverride, taxis, importStart, importCount, isChecked, checkedLevel); + } + + public void ImportContentsByZipFile(ChannelInfo channelInfo, string zipFilePath, bool isOverride, bool isChecked, int checkedLevel, int adminId, int userId, int sourceId) + { + var siteContentDirectoryPath = PathUtils.GetTemporaryFilesPath("contents"); + DirectoryUtils.DeleteDirectoryIfExists(siteContentDirectoryPath); + DirectoryUtils.CreateDirectoryIfNotExists(siteContentDirectoryPath); + + ZipUtils.ExtractZip(zipFilePath, siteContentDirectoryPath); + + var taxis = channelInfo.ContentRepository.GetMaxTaxis(channelInfo.Id, false); + + ImportContents(channelInfo, siteContentDirectoryPath, isOverride, taxis, isChecked, checkedLevel, adminId, userId, sourceId); + } + + public void ImportContentsByAccessFile(int channelId, string excelFilePath, bool isOverride, int importStart, int importCount, bool isChecked, int checkedLevel) + { + var channelInfo = ChannelManager.GetChannelInfo(_siteInfo.Id, channelId); + var contentInfoList = AccessObject.GetContentsByAccessFile(excelFilePath, _siteInfo, channelInfo); + + if (importStart > 1 || importCount > 0) + { + var theList = new List(); + + if (importStart == 0) + { + importStart = 1; + } + if (importCount == 0) + { + importCount = contentInfoList.Count; + } + + var firstIndex = contentInfoList.Count - importStart - importCount + 1; + if (firstIndex <= 0) + { + firstIndex = 0; + } + + var addCount = 0; + for (var i = 0; i < contentInfoList.Count; i++) + { + if (addCount >= importCount) break; + if (i >= firstIndex) + { + theList.Add(contentInfoList[i]); + addCount++; + } + } + + contentInfoList = theList; + } + + var tableName = ChannelManager.GetTableName(_siteInfo, channelInfo); + + foreach (var contentInfo in contentInfoList) + { + contentInfo.Checked = isChecked; + contentInfo.CheckedLevel = checkedLevel; + + //contentInfo.ID = DataProvider.ContentDAO.InsertObject(tableName, this.FSO.SiteInfo, contentInfo); + if (isOverride) + { + var existsIds = channelInfo.ContentRepository.GetIdListBySameTitle(contentInfo.ChannelId, contentInfo.Title); + if (existsIds.Count > 0) + { + foreach (int id in existsIds) + { + contentInfo.Id = id; + DataProvider.ContentRepository.Update(_siteInfo, channelInfo, contentInfo); + } + } + else + { + contentInfo.Id = DataProvider.ContentRepository.Insert(tableName, _siteInfo, channelInfo, contentInfo); + } + } + else + { + contentInfo.Id = DataProvider.ContentRepository.Insert(tableName, _siteInfo, channelInfo, contentInfo); + } + } + } + + public void ImportContentsByCsvFile(int channelId, string csvFilePath, bool isOverride, int importStart, int importCount, bool isChecked, int checkedLevel) + { + var channelInfo = ChannelManager.GetChannelInfo(_siteInfo.Id, channelId); + var contentInfoList = ExcelObject.GetContentsByCsvFile(csvFilePath, _siteInfo, channelInfo); + contentInfoList.Reverse(); + + if (importStart > 1 || importCount > 0) + { + var theList = new List(); + + if (importStart == 0) + { + importStart = 1; + } + if (importCount == 0) + { + importCount = contentInfoList.Count; + } + + var firstIndex = contentInfoList.Count - importStart - importCount + 1; + if (firstIndex <= 0) + { + firstIndex = 0; + } + + var addCount = 0; + for (var i = 0; i < contentInfoList.Count; i++) + { + if (addCount >= importCount) break; + if (i >= firstIndex) + { + theList.Add(contentInfoList[i]); + addCount++; + } + } + + contentInfoList = theList; + } + + var tableName = ChannelManager.GetTableName(_siteInfo, channelInfo); + + foreach (var contentInfo in contentInfoList) + { + contentInfo.Checked = isChecked; + contentInfo.CheckedLevel = checkedLevel; + if (isOverride) + { + var existsIds = channelInfo.ContentRepository.GetIdListBySameTitle(contentInfo.ChannelId, contentInfo.Title); + if (existsIds.Count > 0) + { + foreach (var id in existsIds) + { + contentInfo.Id = id; + DataProvider.ContentRepository.Update(_siteInfo, channelInfo, contentInfo); + } + } + else + { + contentInfo.Id = DataProvider.ContentRepository.Insert(tableName, _siteInfo, channelInfo, contentInfo); + } + } + else + { + contentInfo.Id = DataProvider.ContentRepository.Insert(tableName, _siteInfo, channelInfo, contentInfo); + } + //this.FSO.AddContentToWaitingCreate(contentInfo.ChannelId, contentID); + } + } + + public void ImportContentsByCsvFile(ChannelInfo channelInfo, string csvFilePath, bool isOverride, bool isChecked, int checkedLevel, int adminId, int userId, int sourceId) + { + var contentInfoList = ExcelObject.GetContentsByCsvFile(csvFilePath, _siteInfo, channelInfo); + contentInfoList.Reverse(); + + var tableName = ChannelManager.GetTableName(_siteInfo, channelInfo); + + foreach (var contentInfo in contentInfoList) + { + contentInfo.Checked = isChecked; + contentInfo.CheckedLevel = checkedLevel; + contentInfo.AddDate = DateTime.Now; + contentInfo.LastEditDate = DateTime.Now; + contentInfo.AdminId = adminId; + contentInfo.UserId = userId; + contentInfo.SourceId = sourceId; + + if (isOverride) + { + var existsIds = channelInfo.ContentRepository.GetIdListBySameTitle(contentInfo.ChannelId, contentInfo.Title); + if (existsIds.Count > 0) + { + foreach (var id in existsIds) + { + contentInfo.Id = id; + DataProvider.ContentRepository.Update(_siteInfo, channelInfo, contentInfo); + } + } + else + { + contentInfo.Id = DataProvider.ContentRepository.Insert(tableName, _siteInfo, channelInfo, contentInfo); + } + } + else + { + contentInfo.Id = DataProvider.ContentRepository.Insert(tableName, _siteInfo, channelInfo, contentInfo); + } + } + } + + public void ImportContentsByTxtZipFile(int channelId, string zipFilePath, bool isOverride, int importStart, int importCount, bool isChecked, int checkedLevel) + { + var directoryPath = PathUtils.GetTemporaryFilesPath("contents"); + DirectoryUtils.DeleteDirectoryIfExists(directoryPath); + DirectoryUtils.CreateDirectoryIfNotExists(directoryPath); + + ZipUtils.ExtractZip(zipFilePath, directoryPath); + + var channelInfo = ChannelManager.GetChannelInfo(_siteInfo.Id, channelId); + + var contentInfoList = TxtObject.GetContentListByTxtFile(directoryPath, _siteInfo, channelInfo); + + if (importStart > 1 || importCount > 0) + { + var theList = new List(); + + if (importStart == 0) + { + importStart = 1; + } + if (importCount == 0) + { + importCount = contentInfoList.Count; + } + + var firstIndex = contentInfoList.Count - importStart - importCount + 1; + if (firstIndex <= 0) + { + firstIndex = 0; + } + + var addCount = 0; + for (var i = 0; i < contentInfoList.Count; i++) + { + if (addCount >= importCount) break; + if (i >= firstIndex) + { + theList.Add(contentInfoList[i]); + addCount++; + } + } + + contentInfoList = theList; + } + + var tableName = ChannelManager.GetTableName(_siteInfo, channelInfo); + + foreach (var contentInfo in contentInfoList) + { + contentInfo.Checked = isChecked; + contentInfo.CheckedLevel = checkedLevel; + + //int contentID = DataProvider.ContentDAO.InsertObject(tableName, this.FSO.SiteInfo, contentInfo); + + if (isOverride) + { + var existsIds = channelInfo.ContentRepository.GetIdListBySameTitle(contentInfo.ChannelId, contentInfo.Title); + if (existsIds.Count > 0) + { + foreach (var id in existsIds) + { + contentInfo.Id = id; + DataProvider.ContentRepository.Update(_siteInfo, channelInfo, contentInfo); + } + } + else + { + contentInfo.Id = DataProvider.ContentRepository.Insert(tableName, _siteInfo, channelInfo, contentInfo); + } + } + else + { + contentInfo.Id = DataProvider.ContentRepository.Insert(tableName, _siteInfo, channelInfo, contentInfo); + } + + //this.FSO.AddContentToWaitingCreate(contentInfo.ChannelId, contentID); + } + } + + public void ImportContentsByTxtFile(ChannelInfo channelInfo, string txtFilePath, bool isOverride, bool isChecked, int checkedLevel, int adminId, int userId, int sourceId) + { + var tableName = ChannelManager.GetTableName(_siteInfo, channelInfo); + + var contentInfo = new ContentInfo + { + SiteId = channelInfo.SiteId, + ChannelId = channelInfo.Id, + Title = PathUtils.GetFileNameWithoutExtension(txtFilePath), + Content = StringUtils.ReplaceNewlineToBr(FileUtils.ReadText(txtFilePath, Encoding.UTF8)), + Checked = isChecked, + CheckedLevel = checkedLevel, + AddDate = DateTime.Now, + LastEditDate = DateTime.Now, + AdminId = adminId, + UserId = userId, + SourceId = sourceId + }; + + if (isOverride) + { + var existsIds = channelInfo.ContentRepository.GetIdListBySameTitle(contentInfo.ChannelId, contentInfo.Title); + if (existsIds.Count > 0) + { + foreach (var id in existsIds) + { + contentInfo.Id = id; + DataProvider.ContentRepository.Update(_siteInfo, channelInfo, contentInfo); + } + } + else + { + contentInfo.Id = DataProvider.ContentRepository.Insert(tableName, _siteInfo, channelInfo, contentInfo); + } + } + else + { + contentInfo.Id = DataProvider.ContentRepository.Insert(tableName, _siteInfo, channelInfo, contentInfo); + } + } + + private void ImportContents(ChannelInfo nodeInfo, string siteContentDirectoryPath, bool isOverride, int taxis, int importStart, int importCount, bool isChecked, int checkedLevel) + { + var filePath = PathUtils.Combine(siteContentDirectoryPath, "contents.xml"); + + var contentIe = new ContentIe(_siteInfo, siteContentDirectoryPath); + + contentIe.ImportContents(filePath, isOverride, nodeInfo, taxis, importStart, importCount, isChecked, checkedLevel, _adminName); + + FileUtils.DeleteFileIfExists(filePath); + + DirectoryUtils.MoveDirectory(siteContentDirectoryPath, _sitePath, isOverride); + } + + private void ImportContents(ChannelInfo nodeInfo, string siteContentDirectoryPath, bool isOverride, int taxis, bool isChecked, int checkedLevel, int adminId, int userId, int sourceId) + { + var filePath = PathUtils.Combine(siteContentDirectoryPath, "contents.xml"); + + var contentIe = new ContentIe(_siteInfo, siteContentDirectoryPath); + + contentIe.ImportContents(filePath, isOverride, nodeInfo, taxis, isChecked, checkedLevel, adminId, userId, sourceId); + + FileUtils.DeleteFileIfExists(filePath); + + DirectoryUtils.MoveDirectory(siteContentDirectoryPath, _sitePath, isOverride); + } + + //public void ImportInputContentsByCsvFile(InputInfo inputInfo, string excelFilePath, int importStart, int importCount, bool isChecked) + //{ + // var contentInfoList = ExcelObject.GetInputContentsByCsvFile(excelFilePath, _siteInfo, inputInfo); + // contentInfoList.Reverse(); + + // if (importStart > 1 || importCount > 0) + // { + // var theList = new List(); + + // if (importStart == 0) + // { + // importStart = 1; + // } + // if (importCount == 0) + // { + // importCount = contentInfoList.Count; + // } + + // var firstIndex = contentInfoList.Count - importStart - importCount + 1; + // if (firstIndex <= 0) + // { + // firstIndex = 0; + // } + + // var addCount = 0; + // for (var i = 0; i < contentInfoList.Count; i++) + // { + // if (addCount >= importCount) break; + // if (i >= firstIndex) + // { + // theList.Add(contentInfoList[i]); + // addCount++; + // } + // } + + // contentInfoList = theList; + // } + + // foreach (var contentInfo in contentInfoList) + // { + // contentInfo.IsChecked = isChecked; + // DataProvider.InputContentDao.InsertObject(contentInfo); + // } + //} + + public static IList GetSiteContentFilePathList(string siteContentDirectoryPath) + { + var filePaths = DirectoryUtils.GetFilePaths(siteContentDirectoryPath); + var filePathSortedList = new SortedList(); + foreach (var filePath in filePaths) + { + var keyBuilder = new StringBuilder(); + var fileName = PathUtils.GetFileName(filePath).ToLower().Replace(".xml", ""); + var numArr = fileName.Split('_'); + foreach (var numStr in numArr) + { + var count = 7 - numStr.Length; + if (count > 0) + { + for (var i = 0; i < count; i++) + { + keyBuilder.Append("0"); + } + } + keyBuilder.Append(numStr); + keyBuilder.Append("_"); + } + if (keyBuilder.Length > 0) keyBuilder.Remove(keyBuilder.Length - 1, 1); + filePathSortedList.Add(keyBuilder.ToString(), filePath); + } + return filePathSortedList.Values; + } + + } +} diff --git a/SiteServer.CMS/Packaging/PackageMetadata.cs b/net452/SiteServer.CMS/Packaging/PackageMetadata.cs similarity index 100% rename from SiteServer.CMS/Packaging/PackageMetadata.cs rename to net452/SiteServer.CMS/Packaging/PackageMetadata.cs diff --git a/SiteServer.CMS/Packaging/PackageMetadataStrings.cs b/net452/SiteServer.CMS/Packaging/PackageMetadataStrings.cs similarity index 100% rename from SiteServer.CMS/Packaging/PackageMetadataStrings.cs rename to net452/SiteServer.CMS/Packaging/PackageMetadataStrings.cs diff --git a/SiteServer.CMS/Packaging/PackageType.cs b/net452/SiteServer.CMS/Packaging/PackageType.cs similarity index 100% rename from SiteServer.CMS/Packaging/PackageType.cs rename to net452/SiteServer.CMS/Packaging/PackageType.cs diff --git a/SiteServer.CMS/Packaging/PackageUtils.cs b/net452/SiteServer.CMS/Packaging/PackageUtils.cs similarity index 89% rename from SiteServer.CMS/Packaging/PackageUtils.cs rename to net452/SiteServer.CMS/Packaging/PackageUtils.cs index 088de5005..df53c5208 100644 --- a/SiteServer.CMS/Packaging/PackageUtils.cs +++ b/net452/SiteServer.CMS/Packaging/PackageUtils.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using NuGet.Packaging; +using SiteServer.CMS.Fx; using SiteServer.CMS.Plugin; using SiteServer.Utils; @@ -14,8 +15,11 @@ namespace SiteServer.CMS.Packaging public class PackageUtils { public const string PackageIdSsCms = "SS.CMS"; + public const string PackageIdSiteServerPlugin = "SiteServer.Plugin"; public const string VersionDev = "0.0.0"; + public const string CacheKeySsCmsIsDownload = nameof(CacheKeySsCmsIsDownload); + //private const string NuGetPackageSource = "https://packages.nuget.org/api/v2"; //private const string MyGetPackageSource = "https://www.myget.org/F/siteserver/api/v2"; @@ -52,7 +56,7 @@ public class PackageUtils public static void DownloadPackage(string packageId, string version) { - var packagesPath = PathUtils.GetPackagesPath(); + var packagesPath = FxUtils.GetPackagesPath(); var idWithVersion = $"{packageId}.{version}"; var directoryPath = PathUtils.Combine(packagesPath, idWithVersion); @@ -71,12 +75,11 @@ public static void DownloadPackage(string packageId, string version) Directory.CreateDirectory(directoryPath); } - var localFilePath = PathUtils.Combine(directoryPath, idWithVersion + ".nupkg"); - + var localFilePath = PathUtils.Combine(directoryPath, idWithVersion + ".nupkg"); WebClientUtils.SaveRemoteFileToLocal( - $"http://api.siteserver.cn/downloads/update/{version}", localFilePath); + $"https://api.siteserver.cn/downloads/update/{version}", localFilePath); - ZipUtils.UnpackFiles(localFilePath, directoryPath); + ZipUtils.ExtractZip(localFilePath, directoryPath); } else { @@ -88,9 +91,9 @@ public static void DownloadPackage(string packageId, string version) var localFilePath = PathUtils.Combine(directoryPath, idWithVersion + ".nupkg"); WebClientUtils.SaveRemoteFileToLocal( - $"http://api.siteserver.cn/downloads/package/{packageId}/{version}", localFilePath); + $"https://api.siteserver.cn/downloads/package/{packageId}/{version}", localFilePath); - ZipUtils.UnpackFiles(localFilePath, directoryPath); + ZipUtils.ExtractZip(localFilePath, directoryPath); //var repo = PackageRepositoryFactory.Default.CreateRepository(WebConfigUtils.IsNightlyUpdate //? MyGetPackageSource @@ -129,7 +132,7 @@ public static bool UpdatePackage(string idWithVersion, PackageType packageType, { try { - var packagePath = PathUtils.GetPackagesPath(idWithVersion); + var packagePath = FxUtils.GetPackagesPath(idWithVersion); string nuspecPath; string dllDirectoryPath; @@ -149,7 +152,7 @@ public static bool UpdatePackage(string idWithVersion, PackageType packageType, } WebConfigUtils.UpdateWebConfig(packageWebConfigPath, WebConfigUtils.IsProtectData, - WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, WebConfigUtils.AdminDirectory, + WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, WebConfigUtils.ApiPrefix, WebConfigUtils.AdminDirectory, WebConfigUtils.HomeDirectory, WebConfigUtils.SecretKey, WebConfigUtils.IsNightlyUpdate); //DirectoryUtils.Copy(PathUtils.Combine(packagePath, DirectoryUtils.SiteFiles.DirectoryName), @@ -164,7 +167,7 @@ public static bool UpdatePackage(string idWithVersion, PackageType packageType, } else if (packageType == PackageType.Plugin) { - var pluginPath = PathUtils.GetPluginPath(metadata.Id); + var pluginPath = FxUtils.GetPluginPath(metadata.Id); DirectoryUtils.CreateDirectoryIfNotExists(pluginPath); DirectoryUtils.Copy(PathUtils.Combine(packagePath, "content"), pluginPath, true); @@ -187,12 +190,20 @@ public static bool UpdatePackage(string idWithVersion, PackageType packageType, } else if (packageType == PackageType.Library) { - var sourceDllPath = PathUtils.Combine(dllDirectoryPath, $"{metadata.Id}.dll"); - var destDllPath = PathUtils.GetBinDirectoryPath($"{metadata.Id}.dll"); - if (FileUtils.IsFileExists(sourceDllPath) && !FileUtils.IsFileExists(destDllPath)) + var fileNames = DirectoryUtils.GetFileNames(dllDirectoryPath); + foreach (var fileName in fileNames) { - FileUtils.CopyFile(sourceDllPath, destDllPath, false); + if (StringUtils.EndsWithIgnoreCase(fileName, ".dll")) + { + var sourceDllPath = PathUtils.Combine(dllDirectoryPath, fileName); + var destDllPath = PathUtils.GetBinDirectoryPath(fileName); + if (!FileUtils.IsFileExists(destDllPath)) + { + FileUtils.CopyFile(sourceDllPath, destDllPath, false); + } + } } + } } catch (Exception ex) @@ -207,7 +218,7 @@ public static bool UpdatePackage(string idWithVersion, PackageType packageType, public static PackageMetadata GetPackageMetadataFromPlugins(string directoryName, out string errorMessage) { - var nuspecPath = PathUtils.GetPluginNuspecPath(directoryName); + var nuspecPath = FxUtils.GetPluginNuspecPath(directoryName); if (!File.Exists(nuspecPath)) { errorMessage = $"插件配置文件 {directoryName}.nuspec 不存在"; @@ -241,7 +252,7 @@ public static PackageMetadata GetPackageMetadataFromPackages(string directoryNam dllDirectoryPath = string.Empty; errorMessage = string.Empty; - var directoryPath = PathUtils.GetPackagesPath(directoryName); + var directoryPath = FxUtils.GetPackagesPath(directoryName); foreach (var filePath in DirectoryUtils.GetFilePaths(directoryPath)) { @@ -254,7 +265,7 @@ public static PackageMetadata GetPackageMetadataFromPackages(string directoryNam if (string.IsNullOrEmpty(nuspecPath)) { - errorMessage = "插件配置文件不存在"; + errorMessage = "配置文件不存在"; return null; } @@ -273,7 +284,7 @@ public static PackageMetadata GetPackageMetadataFromPackages(string directoryNam if (string.IsNullOrEmpty(packageId)) { - errorMessage = $"插件配置文件 {nuspecPath} 不正确"; + errorMessage = $"配置文件 {nuspecPath} 不正确"; return null; } @@ -281,13 +292,13 @@ public static PackageMetadata GetPackageMetadataFromPackages(string directoryNam { dllDirectoryPath = FindDllDirectoryPath(directoryPath); - if (!FileUtils.IsFileExists(PathUtils.Combine(dllDirectoryPath, packageId + ".dll"))) - { - errorMessage = $"插件可执行文件 {packageId}.dll 不存在"; - return null; - } + //if (!FileUtils.IsFileExists(PathUtils.Combine(dllDirectoryPath, packageId + ".dll"))) + //{ + // errorMessage = $"插件可执行文件 {packageId}.dll 不存在"; + // return null; + //} } - + return metadata; } diff --git a/net452/SiteServer.CMS/Plugin/Impl/AccessTokenImpl.cs b/net452/SiteServer.CMS/Plugin/Impl/AccessTokenImpl.cs new file mode 100644 index 000000000..8e55b6dcb --- /dev/null +++ b/net452/SiteServer.CMS/Plugin/Impl/AccessTokenImpl.cs @@ -0,0 +1,14 @@ +using System; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Plugin.Impl +{ + public class AccessTokenImpl: IAccessToken + { + public int UserId { get; set; } + + public string UserName { get; set; } + + public DateTime ExpiresAt { get; set; } + } +} \ No newline at end of file diff --git a/net452/SiteServer.CMS/Plugin/Impl/ApiCollectionImpl.cs b/net452/SiteServer.CMS/Plugin/Impl/ApiCollectionImpl.cs new file mode 100644 index 000000000..1c24ff348 --- /dev/null +++ b/net452/SiteServer.CMS/Plugin/Impl/ApiCollectionImpl.cs @@ -0,0 +1,27 @@ +using SiteServer.Plugin; + +namespace SiteServer.CMS.Plugin.Impl +{ + public class ApiCollectionImpl: IApiCollection + { + public IAdminApi AdminApi { get; set; } + + public IConfigApi ConfigApi { get; set; } + + public IContentApi ContentApi { get; set; } + + //public IDatabaseApi DatabaseApi { get; set; } + + public IChannelApi ChannelApi { get; set; } + + public IParseApi ParseApi { get; set; } + + public IPluginApi PluginApi { get; set; } + + public ISiteApi SiteApi { get; set; } + + public IUserApi UserApi { get; set; } + + public IUtilsApi UtilsApi { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Plugin/Impl/ContentContextImpl.cs b/net452/SiteServer.CMS/Plugin/Impl/ContentContextImpl.cs new file mode 100644 index 000000000..7c42b8a67 --- /dev/null +++ b/net452/SiteServer.CMS/Plugin/Impl/ContentContextImpl.cs @@ -0,0 +1,13 @@ +using SiteServer.Plugin; + +namespace SiteServer.CMS.Plugin.Impl +{ + public class ContentContextImpl: IContentContext + { + public int SiteId { get; set; } + + public int ChannelId { get; set; } + + public int ContentId { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Plugin/Impl/EnvironmentImpl.cs b/net452/SiteServer.CMS/Plugin/Impl/EnvironmentImpl.cs new file mode 100644 index 000000000..76faccb11 --- /dev/null +++ b/net452/SiteServer.CMS/Plugin/Impl/EnvironmentImpl.cs @@ -0,0 +1,24 @@ +using Datory; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Plugin.Impl +{ + public class EnvironmentImpl: IEnvironment + { + public EnvironmentImpl(DatabaseType databaseType, string connectionString, string adminDirectory, string physicalApplicationPath) + { + DatabaseType = databaseType; + ConnectionString = connectionString; + AdminDirectory = adminDirectory; + PhysicalApplicationPath = physicalApplicationPath; + } + + public DatabaseType DatabaseType { get; } + + public string ConnectionString { get; } + + public string AdminDirectory { get; } + + public string PhysicalApplicationPath { get; } + } +} diff --git a/net452/SiteServer.CMS/Plugin/Impl/ParseContextImpl.cs b/net452/SiteServer.CMS/Plugin/Impl/ParseContextImpl.cs new file mode 100644 index 000000000..4647ab8f8 --- /dev/null +++ b/net452/SiteServer.CMS/Plugin/Impl/ParseContextImpl.cs @@ -0,0 +1,80 @@ +using System.Collections.Generic; +using System.Collections.Specialized; +using SiteServer.CMS.StlParser.Model; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Plugin.Impl +{ + public class ParseContextImpl: IParseContext + { + public ParseContextImpl(string stlOuterHtml, string stlInnerHtml, NameValueCollection stlAttributes, PageInfo pageInfo, ContextInfo contextInfo) + { + SiteId = contextInfo.SiteInfo.Id; + ChannelId = contextInfo.ChannelId; + ContentId = contextInfo.ContentId; + ContentInfo = contextInfo.ContentInfo; + TemplateType = pageInfo.TemplateInfo.Type; + TemplateId = pageInfo.TemplateInfo.Id; + + HeadCodes = pageInfo.HeadCodes; + BodyCodes = pageInfo.BodyCodes; + FootCodes = pageInfo.FootCodes; + StlOuterHtml = stlOuterHtml; + StlInnerHtml = stlInnerHtml; + StlAttributes = stlAttributes; + + IsStlElement = !contextInfo.IsStlEntity; + PluginItems = pageInfo.PluginItems; + } + + public Dictionary PluginItems { get; } + + public void Set(string key, T objectValue) + { + if (PluginItems != null && !string.IsNullOrEmpty(key)) + { + PluginItems[key] = objectValue; + } + } + + public T Get(string key) + { + object objectValue; + if (PluginItems.TryGetValue(key, out objectValue)) + { + if (objectValue is T) + { + return (T) objectValue; + } + } + + return default(T); + } + + public int SiteId { get; } + + public int ChannelId { get; } + + public int ContentId { get; } + + public IContentInfo ContentInfo { get; } + + public TemplateType TemplateType { get; } + + public int TemplateId { get; } + + public SortedDictionary HeadCodes { get; } + + public SortedDictionary BodyCodes { get; } + + public SortedDictionary FootCodes { get; } + + public string StlOuterHtml { get; } + + public string StlInnerHtml { get; } + + public NameValueCollection StlAttributes { get; } + + public bool IsStlElement { get; } + } +} diff --git a/net452/SiteServer.CMS/Plugin/Impl/PermissionsImpl.cs b/net452/SiteServer.CMS/Plugin/Impl/PermissionsImpl.cs new file mode 100644 index 000000000..e203502bd --- /dev/null +++ b/net452/SiteServer.CMS/Plugin/Impl/PermissionsImpl.cs @@ -0,0 +1,567 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.Plugin.Impl +{ + public class PermissionsImpl: IPermissions + { + private readonly AdministratorInfo _adminInfo; + private readonly string _rolesKey; + private readonly string _permissionListKey; + private readonly string _websitePermissionDictKey; + private readonly string _channelPermissionDictKey; + private readonly string _channelPermissionListIgnoreChannelIdKey; + private readonly string _channelIdListKey; + + private IList _roles; + private List _permissionList; + private Dictionary> _websitePermissionDict; + private Dictionary> _channelPermissionDict; + private List _channelPermissionListIgnoreChannelId; + private List _channelIdList; + + public PermissionsImpl(AdministratorInfo adminInfo) + { + if (adminInfo == null || adminInfo.Locked) return; + + _adminInfo = adminInfo; + + _rolesKey = GetRolesCacheKey(adminInfo.UserName); + _permissionListKey = GetPermissionListCacheKey(adminInfo.UserName); + _websitePermissionDictKey = GetWebsitePermissionDictCacheKey(adminInfo.UserName); + _channelPermissionDictKey = GetChannelPermissionDictCacheKey(adminInfo.UserName); + _channelPermissionListIgnoreChannelIdKey = GetChannelPermissionListIgnoreChannelIdCacheKey(adminInfo.UserName); + _channelIdListKey = GetChannelIdListCacheKey(adminInfo.UserName); + } + + public List ChannelIdList + { + get + { + if (_channelIdList != null) return _channelIdList; + if (_adminInfo == null || _adminInfo.Locked) return new List(); + + _channelIdList = DataCacheManager.Get>(_channelIdListKey); + + if (_channelIdList == null) + { + _channelIdList = new List(); + + if (!IsSystemAdministrator) + { + foreach (var dictKey in ChannelPermissionDict.Keys) + { + var kvp = ParseChannelPermissionDictKey(dictKey); + var channelInfo = ChannelManager.GetChannelInfo(kvp.Key, kvp.Value); + _channelIdList.AddRange(ChannelManager.GetChannelIdList(channelInfo, EScopeType.All, string.Empty, string.Empty, string.Empty)); + } + } + + DataCacheManager.InsertMinutes(_channelIdListKey, _channelIdList, 30); + } + return _channelIdList ?? (_channelIdList = new List()); + } + } + + public bool IsSuperAdmin() + { + return IsConsoleAdministrator; + } + + public bool IsSiteAdmin(int siteId) + { + return IsSystemAdministrator && GetSiteIdList().Contains(siteId); + } + + public string GetAdminLevel() + { + if (IsConsoleAdministrator) + { + return "超级管理员"; + } + + return IsSystemAdministrator ? "站点总管理员" : "普通管理员"; + } + + public List GetSiteIdList() + { + var siteIdList = new List(); + + if (IsConsoleAdministrator) + { + siteIdList = SiteManager.GetSiteIdList(); + } + else if (IsSystemAdministrator) + { + if (_adminInfo != null) + { + foreach (var siteId in TranslateUtils.StringCollectionToIntList(_adminInfo.SiteIdCollection)) + { + if (!siteIdList.Contains(siteId)) + { + siteIdList.Add(siteId); + } + } + } + } + else + { + var dict = WebsitePermissionDict; + + foreach (var siteId in dict.Keys) + { + if (!siteIdList.Contains(siteId)) + { + siteIdList.Add(siteId); + } + } + } + + return siteIdList; + } + + public List GetChannelIdList(int siteId, params string[] permissions) + { + if (IsSystemAdministrator) + { + return ChannelManager.GetChannelIdList(siteId); + } + + var siteChannelIdList = new List(); + var dict = ChannelPermissionDict; + foreach (var dictKey in dict.Keys) + { + var kvp = ParseChannelPermissionDictKey(dictKey); + var dictPermissions = dict[dictKey]; + if (kvp.Key == siteId && dictPermissions.Any(permissions.Contains)) + { + var channelInfo = ChannelManager.GetChannelInfo(kvp.Key, kvp.Value); + + var channelIdList = ChannelManager.GetChannelIdList(channelInfo, EScopeType.All); + + foreach (var channelId in channelIdList) + { + if (!siteChannelIdList.Contains(channelId)) + { + siteChannelIdList.Add(channelId); + } + } + } + } + + return siteChannelIdList; + } + + public bool HasSystemPermissions(params string[] permissions) + { + if (IsSystemAdministrator) return true; + + var permissionList = PermissionList; + return permissions.Any(permission => permissionList.Contains(permission)); + } + + public bool HasSitePermissions(int siteId, params string[] permissions) + { + if (IsSystemAdministrator) return true; + if (!WebsitePermissionDict.ContainsKey(siteId)) return false; + + var websitePermissionList = WebsitePermissionDict[siteId]; + if (websitePermissionList != null && websitePermissionList.Count > 0) + { + return permissions.Any(sitePermission => websitePermissionList.Contains(sitePermission)); + } + + return false; + } + + public bool HasChannelPermissions(int siteId, int channelId, params string[] permissions) + { + while (true) + { + if (channelId == 0) return false; + if (IsSystemAdministrator) return true; + var dictKey = GetChannelPermissionDictKey(siteId, channelId); + if (ChannelPermissionDict.ContainsKey(dictKey) && HasChannelPermissions(ChannelPermissionDict[dictKey], permissions)) return true; + + var parentChannelId = ChannelManager.GetParentId(siteId, channelId); + channelId = parentChannelId; + } + } + + public bool IsConsoleAdministrator => EPredefinedRoleUtils.IsConsoleAdministrator(Roles); + + public bool IsSystemAdministrator => EPredefinedRoleUtils.IsSystemAdministrator(Roles); + + //public bool IsSuperAdmin(string userName) + //{ + // var adminPermissionsImpl = new PermissionsImpl(userName); + // return adminPermissionsImpl.IsConsoleAdministrator; + //} + + //public bool IsSiteAdmin(string userName, int siteId) + //{ + // var adminPermissionsImpl = new PermissionsImpl(userName); + // return adminPermissionsImpl.IsSystemAdministrator && adminPermissionsImpl.HasSitePermissions(siteId); + //} + + public List PermissionList + { + get + { + if (_permissionList != null) return _permissionList; + if (_adminInfo == null || _adminInfo.Locked) return new List(); + + _permissionList = DataCacheManager.Get>(_permissionListKey); + + if (_permissionList == null) + { + if (EPredefinedRoleUtils.IsConsoleAdministrator(Roles)) + { + _permissionList = new List(); + foreach (var permission in PermissionConfigManager.Instance.GeneralPermissions) + { + _permissionList.Add(permission.Name); + } + } + else if (EPredefinedRoleUtils.IsSystemAdministrator(Roles)) + { + _permissionList = new List + { + ConfigManager.SettingsPermissions.Admin + }; + } + else + { + _permissionList = DataProvider.PermissionsInRoles.GetGeneralPermissionList(Roles); + } + + DataCacheManager.InsertMinutes(_permissionListKey, _permissionList, 30); + } + return _permissionList ?? (_permissionList = new List()); + } + } + + private IList Roles + { + get + { + if (_roles != null) return _roles; + if (_adminInfo == null || _adminInfo.Locked) + return new List { EPredefinedRoleUtils.GetValue(EPredefinedRole.Administrator) }; + + _roles = DataCacheManager.Get>(_rolesKey); + if (_roles == null) + { + _roles = DataProvider.AdministratorsInRoles.GetRolesForUser(_adminInfo.UserName); + DataCacheManager.InsertMinutes(_rolesKey, _roles, 30); + } + + return _roles ?? new List {EPredefinedRoleUtils.GetValue(EPredefinedRole.Administrator)}; + } + } + + private Dictionary> WebsitePermissionDict + { + get + { + if (_websitePermissionDict != null) return _websitePermissionDict; + if (_adminInfo == null || _adminInfo.Locked) return new Dictionary>(); + + _websitePermissionDict = DataCacheManager.Get>>(_websitePermissionDictKey); + + if (_websitePermissionDict == null) + { + if (IsSystemAdministrator) + { + var allWebsitePermissionList = new List(); + foreach (var permission in PermissionConfigManager.Instance.WebsitePermissions) + { + allWebsitePermissionList.Add(permission.Name); + } + + var siteIdList = GetSiteIdList(); + + _websitePermissionDict = new Dictionary>(); + foreach (var siteId in siteIdList) + { + _websitePermissionDict[siteId] = allWebsitePermissionList; + } + } + else + { + _websitePermissionDict = DataProvider.SitePermissions.GetWebsitePermissionSortedList(Roles); + } + DataCacheManager.InsertMinutes(_websitePermissionDictKey, _websitePermissionDict, 30); + } + return _websitePermissionDict ?? (_websitePermissionDict = new Dictionary>()); + } + } + + private Dictionary> ChannelPermissionDict + { + get + { + if (_channelPermissionDict != null) return _channelPermissionDict; + if (_adminInfo == null || _adminInfo.Locked) return new Dictionary>(); + + _channelPermissionDict = DataCacheManager.Get>>(_channelPermissionDictKey); + + if (_channelPermissionDict == null) + { + if (EPredefinedRoleUtils.IsSystemAdministrator(Roles)) + { + var allChannelPermissionList = new List(); + foreach (var permission in PermissionConfigManager.Instance.ChannelPermissions) + { + allChannelPermissionList.Add(permission.Name); + } + + _channelPermissionDict = new Dictionary>(); + + var siteIdList = GetSiteIdList(); + + foreach (var siteId in siteIdList) + { + _channelPermissionDict[GetChannelPermissionDictKey(siteId, siteId)] = allChannelPermissionList; + } + } + else + { + _channelPermissionDict = DataProvider.SitePermissions.GetChannelPermissionSortedList(Roles); + } + DataCacheManager.InsertMinutes(_channelPermissionDictKey, _channelPermissionDict, 30); + } + + return _channelPermissionDict ?? (_channelPermissionDict = new Dictionary>()); + } + } + + private List ChannelPermissionListIgnoreChannelId + { + get + { + if (_channelPermissionListIgnoreChannelId != null) return _channelPermissionListIgnoreChannelId; + if (_adminInfo == null || _adminInfo.Locked) return new List(); + + _channelPermissionListIgnoreChannelId = DataCacheManager.Get>(_channelPermissionListIgnoreChannelIdKey); + if (_channelPermissionListIgnoreChannelId == null) + { + if (EPredefinedRoleUtils.IsSystemAdministrator(Roles)) + { + _channelPermissionListIgnoreChannelId = new List(); + foreach (var permission in PermissionConfigManager.Instance.ChannelPermissions) + { + _channelPermissionListIgnoreChannelId.Add(permission.Name); + } + } + else + { + _channelPermissionListIgnoreChannelId = DataProvider.SitePermissions.GetChannelPermissionListIgnoreChannelId(Roles); + } + DataCacheManager.InsertMinutes(_channelPermissionListIgnoreChannelIdKey, _channelPermissionListIgnoreChannelId, 30); + } + + return _channelPermissionListIgnoreChannelId ?? (_channelPermissionListIgnoreChannelId = new List()); + } + } + + public List ChannelPermissionChannelIdList + { + get + { + var list = new List(); + foreach (var dictKey in ChannelPermissionDict.Keys) + { + var kvp = ParseChannelPermissionDictKey(dictKey); + if (!list.Contains(kvp.Value)) + { + list.Add(kvp.Value); + } + } + return list; + } + } + + public bool HasSitePermissions(int siteId) + { + return IsSystemAdministrator || WebsitePermissionDict.ContainsKey(siteId); + } + + public List GetSitePermissions(int siteId) + { + return WebsitePermissionDict.TryGetValue(siteId, out var list) ? list : new List(); + } + + private bool HasChannelPermissions(List channelPermissionList, params string[] channelPermissions) + { + if (IsSystemAdministrator) + { + return true; + } + foreach (var channelPermission in channelPermissions) + { + if (channelPermissionList.Contains(channelPermission)) + { + return true; + } + } + return false; + } + + public bool HasChannelPermissions(int siteId, int channelId) + { + if (channelId == 0) return false; + if (IsSystemAdministrator) + { + return true; + } + var dictKey = GetChannelPermissionDictKey(siteId, channelId); + if (ChannelPermissionDict.ContainsKey(dictKey)) + { + return true; + } + + var parentChannelId = ChannelManager.GetParentId(siteId, channelId); + return HasChannelPermissions(siteId, parentChannelId); + } + + public List GetChannelPermissions(int siteId, int channelId) + { + var dictKey = GetChannelPermissionDictKey(siteId, channelId); + return ChannelPermissionDict.TryGetValue(dictKey, out var list) ? list : new List(); + } + + public List GetChannelPermissions(int siteId) + { + var list = new List(); + foreach (var dictKey in ChannelPermissionDict.Keys) + { + var kvp = ParseChannelPermissionDictKey(dictKey); + if (kvp.Key == siteId) + { + foreach (var permission in ChannelPermissionDict[dictKey]) + { + if (!list.Contains(permission)) + { + list.Add(permission); + } + } + } + } + + return list; + } + + public bool HasChannelPermissionsIgnoreChannelId(params string[] channelPermissions) + { + if (IsSystemAdministrator) + { + return true; + } + if (HasChannelPermissions(ChannelPermissionListIgnoreChannelId, channelPermissions)) + { + return true; + } + return false; + } + + public bool IsOwningChannelId(int channelId) + { + if (IsSystemAdministrator) + { + return true; + } + if (ChannelIdList.Contains(channelId)) + { + return true; + } + return false; + } + + public bool IsDescendantOwningChannelId(int siteId, int channelId) + { + if (IsSystemAdministrator) + { + return true; + } + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + var channelIdList = ChannelManager.GetChannelIdList(channelInfo, EScopeType.Descendant, string.Empty, string.Empty, string.Empty); + foreach (var theChannelId in channelIdList) + { + if (IsOwningChannelId(theChannelId)) + { + return true; + } + } + return false; + } + + public int? GetOnlyAdminId(int siteId, int channelId) + { + if (!ConfigManager.Instance.IsViewContentOnlySelf + || IsConsoleAdministrator + || IsSystemAdministrator + || HasChannelPermissions(siteId, channelId, ConfigManager.ChannelPermissions.ContentCheck)) + { + return null; + } + return _adminInfo.Id; + } + + public static string GetChannelPermissionDictKey(int siteId, int channelId) + { + return $"{siteId}_{channelId}"; + } + + private static KeyValuePair ParseChannelPermissionDictKey(string dictKey) + { + if (string.IsNullOrEmpty(dictKey) || dictKey.IndexOf("_", StringComparison.Ordinal) == -1) return new KeyValuePair(0, 0); + + return new KeyValuePair(TranslateUtils.ToInt(dictKey.Split('_')[0]), TranslateUtils.ToInt(dictKey.Split('_')[1])); + } + + private static string GetRolesCacheKey(string userName) + { + return DataCacheManager.GetCacheKey(nameof(PermissionsImpl), nameof(GetRolesCacheKey), userName); + } + + private static string GetPermissionListCacheKey(string userName) + { + return DataCacheManager.GetCacheKey(nameof(PermissionsImpl), nameof(GetPermissionListCacheKey), userName); + } + + private static string GetWebsitePermissionDictCacheKey(string userName) + { + return DataCacheManager.GetCacheKey(nameof(PermissionsImpl), nameof(GetWebsitePermissionDictCacheKey), userName); + } + + private static string GetChannelPermissionDictCacheKey(string userName) + { + return DataCacheManager.GetCacheKey(nameof(PermissionsImpl), nameof(GetChannelPermissionDictCacheKey), userName); + } + + private static string GetChannelPermissionListIgnoreChannelIdCacheKey(string userName) + { + return DataCacheManager.GetCacheKey(nameof(PermissionsImpl), nameof(GetChannelPermissionListIgnoreChannelIdCacheKey), userName); + } + + private static string GetChannelIdListCacheKey(string userName) + { + return DataCacheManager.GetCacheKey(nameof(PermissionsImpl), nameof(GetChannelIdListCacheKey), userName); + } + + public static void ClearAllCache() + { + DataCacheManager.RemoveByClassName(nameof(PermissionsImpl)); + } + } +} diff --git a/net452/SiteServer.CMS/Plugin/Impl/ServiceImpl.cs b/net452/SiteServer.CMS/Plugin/Impl/ServiceImpl.cs new file mode 100644 index 000000000..0f8a0c88f --- /dev/null +++ b/net452/SiteServer.CMS/Plugin/Impl/ServiceImpl.cs @@ -0,0 +1,207 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Datory; +using SiteServer.Plugin; +using Menu = SiteServer.Plugin.Menu; + +namespace SiteServer.CMS.Plugin.Impl +{ + public class ServiceImpl: IService + { + public string PluginId { get; } + + public IMetadata Metadata { get; } + + public string SystemDefaultPageUrl { get; private set; } + public string HomeDefaultPageUrl { get; private set; } + + public List> SystemMenuFuncs { get; private set; } + public List> SiteMenuFuncs { get; private set; } + public List> HomeMenuFuncs { get; private set; } + public List> ContentMenuFuncs { get; private set; } + + public string ContentTableName { get; private set; } + public bool IsApiAuthorization { get; private set; } + + public List ContentTableColumns { get; private set; } + public Dictionary> DatabaseTables { get; private set; } + + public event EventHandler ContentAddCompleted; + + public void OnContentAddCompleted(ContentEventArgs e) + { + ContentAddCompleted?.Invoke(this, e); + } + + public event EventHandler ContentDeleteCompleted; + + public void OnContentDeleteCompleted(ContentEventArgs e) + { + ContentDeleteCompleted?.Invoke(this, e); + } + + public event EventHandler ContentTranslateCompleted; + + public void OnContentTranslateCompleted(ContentTranslateEventArgs e) + { + ContentTranslateCompleted?.Invoke(this, e); + } + + public event ContentFormLoadEventHandler ContentFormLoad; + + public string OnContentFormLoad(ContentFormLoadEventArgs e) + { + return ContentFormLoad?.Invoke(this, e); + } + + public event EventHandler ContentFormSubmit; + + public void OnContentFormSubmit(ContentFormSubmitEventArgs e) + { + ContentFormSubmit?.Invoke(this, e); + } + + public Dictionary> StlElementsToParse { get; private set; } + + public Dictionary> Jobs { get; private set; } + + public Dictionary> ContentColumns { get; private set; } + + public ServiceImpl(IMetadata metadata) + { + PluginId = metadata.Id; + Metadata = metadata; + } + + public IService SetSystemDefaultPage(string pageUrl) + { + SystemDefaultPageUrl = pageUrl; + return this; + } + + public IService SetHomeDefaultPage(string pageUrl) + { + HomeDefaultPageUrl = pageUrl; + return this; + } + + public IService AddSystemMenu(Func menu) + { + if (SystemMenuFuncs == null) + { + SystemMenuFuncs = new List>(); + } + SystemMenuFuncs.Add(menu); + return this; + } + + public IService AddSiteMenu(Func menuFunc) + { + if (SiteMenuFuncs == null) + { + SiteMenuFuncs = new List>(); + } + SiteMenuFuncs.Add(menuFunc); + return this; + } + + public IService AddHomeMenu(Func menu) + { + if (HomeMenuFuncs == null) + { + HomeMenuFuncs = new List>(); + } + HomeMenuFuncs.Add(menu); + return this; + } + + public IService AddContentMenu(Func menuFunc) + { + if (ContentMenuFuncs == null) + { + ContentMenuFuncs = new List>(); + } + + ContentMenuFuncs.Add(menuFunc); + + return this; + } + + public IService AddContentModel(string tableName, List tableColumns) + { + ContentTableName = tableName; + ContentTableColumns = tableColumns; + + return this; + } + + public IService AddDatabaseTable(string tableName, List tableColumns) + { + if (DatabaseTables == null) + { + DatabaseTables = new Dictionary>(); + } + + DatabaseTables[tableName] = tableColumns; + + return this; + } + + public IService AddContentColumn(string columnName, Func columnFunc) + { + if (ContentColumns == null) + { + ContentColumns = new Dictionary>(); + } + + ContentColumns[columnName] = columnFunc; + + return this; + } + + public IService AddStlElementParser(string elementName, Func parse) + { + if (StlElementsToParse == null) + { + StlElementsToParse = new Dictionary>(); + } + + StlElementsToParse[elementName] = parse; + + return this; + } + + public IService AddJob(string command, Func job) + { + if (Jobs == null) + { + Jobs = new Dictionary>(StringComparer.CurrentCultureIgnoreCase); + } + + Jobs[command] = job; + + return this; + } + + public IService AddApiAuthorization() + { + IsApiAuthorization = true; + + return this; + } + + public event EventHandler BeforeStlParse; + public event EventHandler AfterStlParse; + + public void OnBeforeStlParse(ParseEventArgs e) + { + BeforeStlParse?.Invoke(this, e); + } + + public void OnAfterStlParse(ParseEventArgs e) + { + AfterStlParse?.Invoke(this, e); + } + } +} diff --git a/net452/SiteServer.CMS/Plugin/PluginContentManager.cs b/net452/SiteServer.CMS/Plugin/PluginContentManager.cs new file mode 100644 index 000000000..955e7ff5d --- /dev/null +++ b/net452/SiteServer.CMS/Plugin/PluginContentManager.cs @@ -0,0 +1,125 @@ +using System; +using System.Collections.Generic; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Plugin +{ + public static class PluginContentManager + { + public static List GetContentModelPlugins() + { + var list = new List(); + + foreach (var service in PluginManager.Services) + { + if (PluginContentTableManager.IsContentTable(service)) + { + list.Add(service.Metadata); + } + } + + return list; + } + + public static List GetContentTableNameList() + { + var list = new List(); + + foreach (var service in PluginManager.Services) + { + if (PluginContentTableManager.IsContentTable(service)) + { + if (!StringUtils.ContainsIgnoreCase(list, service.ContentTableName)) + { + list.Add(service.ContentTableName); + } + } + } + + return list; + } + + public static List GetAllContentRelatedPlugins(bool includeContentTable) + { + var list = new List(); + + foreach (var service in PluginManager.Services) + { + var isContentModel = PluginContentTableManager.IsContentTable(service); + + if (!includeContentTable && isContentModel) continue; + + if (isContentModel) + { + list.Add(service.Metadata); + } + else if (service.ContentMenuFuncs != null) + { + list.Add(service.Metadata); + } + else if (service.ContentColumns != null && service.ContentColumns.Count > 0) + { + list.Add(service.Metadata); + } + } + + return list; + } + + public static List GetContentPlugins(ChannelInfo channelInfo, bool includeContentTable) + { + var list = new List(); + var pluginIds = TranslateUtils.StringCollectionToStringList(channelInfo.ContentRelatedPluginIds); + if (!string.IsNullOrEmpty(channelInfo.ContentModelPluginId)) + { + pluginIds.Add(channelInfo.ContentModelPluginId); + } + + foreach (var service in PluginManager.Services) + { + if (!pluginIds.Contains(service.PluginId)) continue; + + if (!includeContentTable && PluginContentTableManager.IsContentTable(service)) continue; + + list.Add(service); + } + + return list; + } + + public static List GetContentPluginIds(ChannelInfo channelInfo) + { + if (string.IsNullOrEmpty(channelInfo.ContentRelatedPluginIds) && + string.IsNullOrEmpty(channelInfo.ContentModelPluginId)) + { + return null; + } + + var pluginIds = TranslateUtils.StringCollectionToStringList(channelInfo.ContentRelatedPluginIds); + if (!string.IsNullOrEmpty(channelInfo.ContentModelPluginId)) + { + pluginIds.Add(channelInfo.ContentModelPluginId); + } + + return pluginIds; + } + + public static Dictionary>> GetContentColumns(List pluginIds) + { + var dict = new Dictionary>>(); + if (pluginIds == null || pluginIds.Count == 0) return dict; + + foreach (var service in PluginManager.Services) + { + if (!pluginIds.Contains(service.PluginId) || service.ContentColumns == null || service.ContentColumns.Count == 0) continue; + + dict[service.PluginId] = service.ContentColumns; + } + + return dict; + } + } +} diff --git a/net452/SiteServer.CMS/Plugin/PluginContentTableManager.cs b/net452/SiteServer.CMS/Plugin/PluginContentTableManager.cs new file mode 100644 index 000000000..973562419 --- /dev/null +++ b/net452/SiteServer.CMS/Plugin/PluginContentTableManager.cs @@ -0,0 +1,217 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using TableColumn = Datory.TableColumn; + +namespace SiteServer.CMS.Plugin +{ + public static class PluginContentTableManager + { + public static bool IsContentTable(ServiceImpl service) + { + return !string.IsNullOrEmpty(service.ContentTableName) && + service.ContentTableColumns != null && service.ContentTableColumns.Count > 0; + } + + public static string GetTableName(string pluginId) + { + foreach (var service in PluginManager.Services) + { + if (service.PluginId == pluginId && IsContentTable(service)) + { + return service.ContentTableName; + } + } + + return string.Empty; + } + + public static void SyncContentTable(ServiceImpl service) + { + if (!IsContentTable(service)) return; + + var tableName = service.ContentTableName; + + var tableColumns = new List(); + tableColumns.AddRange(DataProvider.ContentRepository.TableColumns); + tableColumns.AddRange(service.ContentTableColumns); + + if (!DatoryUtils.IsTableExists(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName)) + { + TableColumnManager.CreateTable(tableName, tableColumns, service.PluginId, true, out _); + } + else + { + TableColumnManager.AlterTable(tableName, tableColumns, service.PluginId, ContentAttribute.DropAttributes.Value); + } + + //ContentTableCreateOrUpdateStyles(tableName, service.ContentTableColumns); + } + + //private static void ContentTableCreateOrUpdateStyles(string tableName, List tableColumns) + //{ + // var styleInfoList = new List(); + // var columnTaxis = 0; + // foreach (var tableColumn in tableColumns) + // { + // var inputStyle = new InputStyle + // { + // InputType = InputType.Hidden + // }; + + // columnTaxis++; + // var styleInfo = TableStyleManager.GetTableStyleInfo(tableName, tableColumn.AttributeName, new List { 0 }); + + // var isEquals = true; + + // if (styleInfo.Type != inputStyle.InputType) + // { + // isEquals = false; + // styleInfo.Type = inputStyle.InputType; + // } + + // if (!StringUtils.EqualsIgnoreNull(styleInfo.DisplayName, inputStyle.DisplayName)) + // { + // isEquals = false; + // styleInfo.DisplayName = inputStyle.DisplayName; + // } + + // if (!StringUtils.EqualsIgnoreNull(styleInfo.HelpText, inputStyle.HelpText)) + // { + // isEquals = false; + // styleInfo.HelpText = inputStyle.HelpText; + // } + + // if (!StringUtils.EqualsIgnoreNull(styleInfo.DefaultValue, inputStyle.DefaultValue)) + // { + // isEquals = false; + // styleInfo.DefaultValue = inputStyle.DefaultValue; + // } + + // if (styleInfo.Taxis != columnTaxis) + // { + // isEquals = false; + // styleInfo.Taxis = columnTaxis; + // } + + // if (styleInfo.Required != inputStyle.IsRequired) + // { + // isEquals = false; + // styleInfo.Required = inputStyle.IsRequired; + // } + + // if (!ValidateTypeUtils.Equals(inputStyle.ValidateType, styleInfo.ValidateType)) + // { + // isEquals = false; + // styleInfo.ValidateType = inputStyle.ValidateType.Value; + // } + + // if (styleInfo.MinNum != inputStyle.MinNum) + // { + // isEquals = false; + // styleInfo.MinNum = inputStyle.MinNum; + // } + + // if (styleInfo.MaxNum != inputStyle.MaxNum) + // { + // isEquals = false; + // styleInfo.MaxNum = inputStyle.MaxNum; + // } + + // if (!StringUtils.EqualsIgnoreNull(styleInfo.RegExp, inputStyle.RegExp)) + // { + // isEquals = false; + // styleInfo.RegExp = inputStyle.RegExp; + // } + + // if (!StringUtils.EqualsIgnoreNull(styleInfo.Width, inputStyle.Width)) + // { + // isEquals = false; + // styleInfo.Width = inputStyle.Width; + // } + + // if (!(styleInfo.Height == 0 && string.IsNullOrEmpty(inputStyle.Height)) && styleInfo.Height != TranslateUtils.ToInt(inputStyle.Height)) + // { + // isEquals = false; + // styleInfo.Height = TranslateUtils.ToInt(inputStyle.Height); + // } + + // if (!(styleInfo.StyleItems == null && inputStyle.ListItems == null)) + // { + // var styleItems = styleInfo.StyleItems ?? new List(); + // var listItems = inputStyle.ListItems ?? new List(); + + // if (styleItems.Count > listItems.Count) + // { + // isEquals = false; + // styleItems.RemoveRange(listItems.Count, styleItems.Count - listItems.Count); + // } + + // for (var i = 0; i < listItems.Count; i++) + // { + // var listItem = listItems[i]; + // if (styleItems.Count < i + 1) + // { + // isEquals = false; + // styleItems.Add(new TableStyleItemInfo + // { + // TableStyleId = styleInfo.Id, + // ItemTitle = listItem.Text, + // ItemValue = listItem.Value, + // Selected = listItem.Selected + // }); + // } + // else + // { + // var styleItem = styleItems[i]; + + // if (!StringUtils.EqualsIgnoreNull(styleItem.ItemTitle, listItem.Text)) + // { + // isEquals = false; + // styleItem.ItemTitle = listItem.Text; + // } + + // if (!StringUtils.EqualsIgnoreNull(styleItem.ItemValue, listItem.Value)) + // { + // isEquals = false; + // styleItem.ItemValue = listItem.Value; + // } + + // if (styleItem.Selected != listItem.Selected) + // { + // isEquals = false; + // styleItem.Selected = listItem.Selected; + // } + // } + // } + // } + + // if (isEquals) continue; + + // styleInfo.VisibleInList = false; + // styleInfo.Validate = true; + // styleInfoList.Add(styleInfo); + // } + + // foreach (var styleInfo in styleInfoList) + // { + // if (styleInfo.Id == 0) + // { + // DataProvider.TableStyle.Insert(styleInfo); + // } + // else + // { + // DataProvider.TableStyle.Update(styleInfo); + // } + // } + //} + } +} diff --git a/net452/SiteServer.CMS/Plugin/PluginDatabaseTableManager.cs b/net452/SiteServer.CMS/Plugin/PluginDatabaseTableManager.cs new file mode 100644 index 000000000..8563b5920 --- /dev/null +++ b/net452/SiteServer.CMS/Plugin/PluginDatabaseTableManager.cs @@ -0,0 +1,36 @@ +using System.Linq; +using Datory; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Utils; + +namespace SiteServer.CMS.Plugin +{ + public static class PluginDatabaseTableManager + { + public static void SyncTable(ServiceImpl service) + { + if (service.DatabaseTables == null || service.DatabaseTables.Count <= 0) return; + + foreach (var tableName in service.DatabaseTables.Keys) + { + var tableColumns = service.DatabaseTables[tableName]; + if (tableColumns == null || tableColumns.Count == 0) continue; + + var datoryColumns = tableColumns.Select(x => (TableColumn) x).ToList(); + + if (!DatoryUtils.IsTableExists(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName)) + { + TableColumnManager.CreateTable(tableName, datoryColumns, service.PluginId, false, out _); + } + else + { + TableColumnManager.AlterTable(tableName, datoryColumns, service.PluginId); + } + } + } + } +} diff --git a/SiteServer.CMS/Plugin/PluginDebugger.cs b/net452/SiteServer.CMS/Plugin/PluginDebugger.cs similarity index 95% rename from SiteServer.CMS/Plugin/PluginDebugger.cs rename to net452/SiteServer.CMS/Plugin/PluginDebugger.cs index e9f264a9f..38e72630b 100644 --- a/SiteServer.CMS/Plugin/PluginDebugger.cs +++ b/net452/SiteServer.CMS/Plugin/PluginDebugger.cs @@ -1,4 +1,5 @@ using System.IO; +using SiteServer.CMS.Fx; using SiteServer.Utils; namespace SiteServer.CMS.Plugin @@ -18,7 +19,7 @@ public void Run() _watcher = new FileSystemWatcher { - Path = PathUtils.PluginsPath, + Path = FxUtils.PluginsPath, NotifyFilter = NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName, IncludeSubdirectories = true }; diff --git a/net452/SiteServer.CMS/Plugin/PluginInstance.cs b/net452/SiteServer.CMS/Plugin/PluginInstance.cs new file mode 100644 index 000000000..ab7f7b395 --- /dev/null +++ b/net452/SiteServer.CMS/Plugin/PluginInstance.cs @@ -0,0 +1,63 @@ +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Packaging; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Plugin +{ + public class PluginInstance + { + public PluginInstance(string directoryName, PackageMetadata metadata, string errorMessage) + { + if (metadata != null) + { + Id = metadata.Id; + Metadata = metadata; + } + else + { + Id = directoryName; + } + IsRunnable = false; + ErrorMessage = errorMessage; + } + + public PluginInstance(PackageMetadata metadata, ServiceImpl service, PluginBase plugin, long initTime) + { + Id = plugin.Id; + Metadata = metadata; + Plugin = plugin; + Service = service; + InitTime = initTime; + + bool isDisabled; + int taxis; + DataProvider.Plugin.SetIsDisabledAndTaxis(Id, out isDisabled, out taxis); + + IsRunnable = plugin != null; + IsDisabled = isDisabled; + Taxis = taxis; + } + + public string Id { get; } + + public PackageMetadata Metadata { get; } + + [JsonIgnore] + public PluginBase Plugin { get; } + + [JsonIgnore] + public ServiceImpl Service { get; } + + public long InitTime { get; } + + public string ErrorMessage { get; } + + public bool IsRunnable { get; set; } + + public bool IsDisabled { get; set; } + + public int Taxis { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Plugin/PluginJobManager.cs b/net452/SiteServer.CMS/Plugin/PluginJobManager.cs new file mode 100644 index 000000000..38c5ec80e --- /dev/null +++ b/net452/SiteServer.CMS/Plugin/PluginJobManager.cs @@ -0,0 +1,28 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using SiteServer.Plugin; + +namespace SiteServer.CMS.Plugin +{ + public static class PluginJobManager + { + public static Dictionary> GetJobs() + { + var jobs = new Dictionary>(StringComparer.CurrentCultureIgnoreCase); + + foreach (var service in PluginManager.Services) + { + if (service.Jobs != null && service.Jobs.Count > 0) + { + foreach (var command in service.Jobs.Keys) + { + jobs[command] = service.Jobs[command]; + } + } + } + + return jobs; + } + } +} diff --git a/SiteServer.CMS/Plugin/PluginManager.cs b/net452/SiteServer.CMS/Plugin/PluginManager.cs similarity index 85% rename from SiteServer.CMS/Plugin/PluginManager.cs rename to net452/SiteServer.CMS/Plugin/PluginManager.cs index d0660e738..036889425 100644 --- a/SiteServer.CMS/Plugin/PluginManager.cs +++ b/net452/SiteServer.CMS/Plugin/PluginManager.cs @@ -5,11 +5,13 @@ using System.Linq; using System.Reflection; using System.Threading; +using SiteServer.CMS.Apis; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; using SiteServer.CMS.Packaging; -using SiteServer.CMS.Plugin.Apis; -using SiteServer.CMS.Plugin.Model; +using SiteServer.CMS.Plugin.Impl; using SiteServer.Plugin; namespace SiteServer.CMS.Plugin @@ -24,16 +26,15 @@ private static class PluginManagerCache private static readonly object LockObject = new object(); private const string CacheKey = "SiteServer.CMS.Plugin.PluginCache"; - private static SortedList Load() + private static SortedList Load() { - Environment = new PluginEnvironment(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, WebConfigUtils.AdminDirectory, WebConfigUtils.PhysicalApplicationPath); - var dict = new SortedList(); + var dict = new SortedList(); Thread.Sleep(2000); try { - var pluginsPath = PathUtils.PluginsPath; + var pluginsPath = FxUtils.PluginsPath; if (!Directory.Exists(pluginsPath)) { return dict; @@ -63,7 +64,7 @@ private static SortedList Load() return dict; } - private static PluginInfo ActivePlugin(string directoryName) + private static PluginInstance ActivePlugin(string directoryName) { PackageMetadata metadata = null; string errorMessage; @@ -72,7 +73,7 @@ private static PluginInfo ActivePlugin(string directoryName) { metadata = PackageUtils.GetPackageMetadataFromPlugins(directoryName, out errorMessage); - var dllDirectoryPath = PathUtils.GetPluginDllDirectoryPath(directoryName); + var dllDirectoryPath = FxUtils.GetPluginDllDirectoryPath(directoryName); if (string.IsNullOrEmpty(dllDirectoryPath)) { throw new Exception($"插件可执行文件 {directoryName}.dll 不存在"); @@ -96,7 +97,9 @@ private static PluginInfo ActivePlugin(string directoryName) //var assembly = Assembly.Load(File.ReadAllBytes(PathUtils.Combine(WebConfigUtils.PhysicalApplicationPath, "Bin", PathUtils.GetFileName(metadata.ExecuteFilePath)))); var assembly = Assembly.Load(metadata.Id); // load the dll from bin directory - var type = assembly.GetTypes().First(o => o.IsClass && !o.IsAbstract && o.IsSubclassOf(typeof(PluginBase))); + var type = assembly.GetExportedTypes().FirstOrDefault(exportedType => typeof(PluginBase).IsAssignableFrom(exportedType)); + + //var type = assembly.GetTypes().GetObjectById(o => o.IsClass && !o.IsAbstract && o.IsSubclassOf(typeof(PluginBase))); return ActiveAndAdd(metadata, type); } @@ -106,7 +109,7 @@ private static PluginInfo ActivePlugin(string directoryName) LogUtils.AddErrorLog(ex, $"插件加载:{directoryName}"); } - return new PluginInfo(directoryName, metadata, errorMessage); + return new PluginInstance(directoryName, metadata, errorMessage); } private static void CopyDllsToBin(string pluginId, string pluginDllDirectoryPath) @@ -132,38 +135,27 @@ private static void CopyDllsToBin(string pluginId, string pluginDllDirectoryPath } } - // TODO: 增加SINGLETON约束 - private static PluginInfo ActiveAndAdd(PackageMetadata metadata, Type type) + private static PluginInstance ActiveAndAdd(PackageMetadata metadata, Type type) { if (metadata == null || type == null) return null; + if (StringUtils.EqualsIgnoreCase(metadata.Id, "SS.Home")) return null; + var s = Stopwatch.StartNew(); //var plugin = (IPlugin)Activator.CreateInstance(type); var plugin = (PluginBase)Activator.CreateInstance(type); - plugin.Initialize(metadata, Environment, new PluginApiCollection - { - AdminApi = new AdminApi(metadata), - ConfigApi = new ConfigApi(metadata), - ContentApi = ContentApi.Instance, - DataApi = DataProvider.DataApi, - FilesApi = FilesApi.Instance, - ChannelApi = ChannelApi.Instance, - ParseApi = ParseApi.Instance, - PluginApi = new PluginApi(metadata), - SiteApi = SiteApi.Instance, - UserApi = UserApi.Instance - }); - - var service = new PluginService(metadata); + plugin.Initialize(metadata); + + var service = new ServiceImpl(metadata); plugin.Startup(service); PluginContentTableManager.SyncContentTable(service); PluginDatabaseTableManager.SyncTable(service); - return new PluginInfo(metadata, service, plugin, s.ElapsedMilliseconds); + return new PluginInstance(metadata, service, plugin, s.ElapsedMilliseconds); } public static void Clear() @@ -171,14 +163,14 @@ public static void Clear() CacheUtils.Remove(CacheKey); } - public static SortedList GetPluginSortedList() + public static SortedList GetPluginSortedList() { - var retval = CacheUtils.Get>(CacheKey); + var retval = CacheUtils.Get>(CacheKey); if (retval != null) return retval; lock (LockObject) { - retval = CacheUtils.Get>(CacheKey); + retval = CacheUtils.Get>(CacheKey); if (retval == null) { retval = Load(); @@ -190,7 +182,27 @@ public static SortedList GetPluginSortedList() } } - public static PluginEnvironment Environment { get; private set; } + private static List _pluginInfoListRunnable; + + public static void LoadPlugins(string applicationPhysicalPath) + { + WebConfigUtils.Load(applicationPhysicalPath, PathUtils.Combine(applicationPhysicalPath, WebConfigUtils.WebConfigFileName)); + + Context.Initialize(new EnvironmentImpl(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, WebConfigUtils.AdminDirectory, WebConfigUtils.PhysicalApplicationPath), new ApiCollectionImpl + { + AdminApi = AdminApi.Instance, + ConfigApi = ConfigApi.Instance, + ContentApi = ContentApi.Instance, + ChannelApi = ChannelApi.Instance, + ParseApi = ParseApi.Instance, + PluginApi = PluginApi.Instance, + SiteApi = SiteApi.Instance, + UserApi = UserApi.Instance, + UtilsApi = UtilsApi.Instance + }); + + _pluginInfoListRunnable = PluginInfoListRunnable; + } public static void ClearCache() { @@ -200,7 +212,7 @@ public static void ClearCache() public static IMetadata GetMetadata(string pluginId) { var dict = PluginManagerCache.GetPluginSortedList(); - PluginInfo pluginInfo; + PluginInstance pluginInfo; if (dict.TryGetValue(pluginId, out pluginInfo)) { return pluginInfo.Plugin; @@ -217,7 +229,7 @@ public static bool IsExists(string pluginId) return dict.ContainsKey(pluginId); } - public static List PluginInfoListRunnable + public static List PluginInfoListRunnable { get { @@ -226,7 +238,7 @@ public static List PluginInfoListRunnable } } - public static List AllPluginInfoList + public static List AllPluginInfoList { get { @@ -235,7 +247,7 @@ public static List AllPluginInfoList } } - public static List GetEnabledPluginInfoList() where T : PluginBase + public static List GetEnabledPluginInfoList() where T : PluginBase { var dict = PluginManagerCache.GetPluginSortedList(); return @@ -247,7 +259,7 @@ pluginInfo.Plugin is T .ToList(); } - public static List Services + public static List Services { get { @@ -260,18 +272,19 @@ public static List Services } } - public static PluginInfo GetPluginInfo(string pluginId) + public static PluginInstance GetPluginInfo(string pluginId) { if (string.IsNullOrEmpty(pluginId)) return null; var dict = PluginManagerCache.GetPluginSortedList(); - PluginInfo pluginInfo; - if (dict.TryGetValue(pluginId, out pluginInfo)) - { - return pluginInfo; - } - return null; + return dict.TryGetValue(pluginId, out var pluginInfo) ? pluginInfo : null; + } + + public static PluginInstance GetPluginInfo() where T : PluginBase + { + var dict = PluginManagerCache.GetPluginSortedList(); + return dict.Values.Where(instance => instance.Plugin is T).FirstOrDefault(instance => instance.IsRunnable && !instance.IsDisabled); } public static Dictionary GetPluginIdAndVersionDict() @@ -300,7 +313,7 @@ public static List PackagesIdAndVersionList { get { - var packagesPath = PathUtils.GetPackagesPath(); + var packagesPath = FxUtils.GetPackagesPath(); DirectoryUtils.CreateDirectoryIfNotExists(packagesPath); return DirectoryUtils.GetDirectoryNames(packagesPath).ToList(); } @@ -312,7 +325,7 @@ public static PluginBase GetPlugin(string pluginId) var dict = PluginManagerCache.GetPluginSortedList(); - PluginInfo pluginInfo; + PluginInstance pluginInfo; if (dict.TryGetValue(pluginId, out pluginInfo)) { return pluginInfo.Plugin; @@ -320,13 +333,13 @@ public static PluginBase GetPlugin(string pluginId) return null; } - public static PluginInfo GetEnabledPluginInfo(string pluginId) where T : PluginBase + public static PluginInstance GetEnabledPluginInfo(string pluginId) where T : PluginBase { if (string.IsNullOrEmpty(pluginId)) return null; var dict = PluginManagerCache.GetPluginSortedList(); - PluginInfo pluginInfo; + PluginInstance pluginInfo; var isGet = dict.TryGetValue(pluginId, out pluginInfo); if (isGet && pluginInfo.Plugin != null && !pluginInfo.IsDisabled && pluginInfo.Plugin is T) @@ -336,7 +349,7 @@ public static PluginInfo GetEnabledPluginInfo(string pluginId) where T : Plug return null; } - public static List GetEnabledPluginInfoList() + public static List GetEnabledPluginInfoList() { var dict = PluginManagerCache.GetPluginSortedList(); @@ -365,7 +378,7 @@ public static IMetadata GetEnabledPluginMetadata(string pluginId) where T : P var dict = PluginManagerCache.GetPluginSortedList(); - PluginInfo pluginInfo; + PluginInstance pluginInfo; var isGet = dict.TryGetValue(pluginId, out pluginInfo); if (isGet && pluginInfo.Plugin != null && !pluginInfo.IsDisabled && pluginInfo.Plugin is T) @@ -381,7 +394,7 @@ public static T GetEnabledFeature(string pluginId) where T : PluginBase var dict = PluginManagerCache.GetPluginSortedList(); - PluginInfo pluginInfo; + PluginInstance pluginInfo; var isGet = dict.TryGetValue(pluginId, out pluginInfo); if (isGet && pluginInfo.Plugin != null && !pluginInfo.IsDisabled && pluginInfo.Plugin is T) @@ -404,13 +417,13 @@ pluginInfo.Plugin is T return pluginInfos.Select(pluginInfo => (T)pluginInfo.Plugin).ToList(); } - public static PluginService GetService(string pluginId) + public static ServiceImpl GetService(string pluginId) { if (string.IsNullOrEmpty(pluginId)) return null; foreach (var service in Services) { - if (service.PluginId == pluginId) + if (StringUtils.EqualsIgnoreCase(service.PluginId, pluginId)) { return service; } @@ -601,7 +614,7 @@ public static PluginService GetService(string pluginId) public static void Delete(string pluginId) { - DirectoryUtils.DeleteDirectoryIfExists(PathUtils.GetPluginPath(pluginId)); + DirectoryUtils.DeleteDirectoryIfExists(FxUtils.GetPluginPath(pluginId)); ClearCache(); } @@ -611,7 +624,7 @@ public static void UpdateDisabled(string pluginId, bool isDisabled) if (pluginInfo != null) { pluginInfo.IsDisabled = isDisabled; - DataProvider.PluginDao.UpdateIsDisabled(pluginId, isDisabled); + DataProvider.Plugin.UpdateIsDisabled(pluginId, isDisabled); ClearCache(); } } @@ -622,7 +635,7 @@ public static void UpdateTaxis(string pluginId, int taxis) if (pluginInfo != null) { pluginInfo.Taxis = taxis; - DataProvider.PluginDao.UpdateTaxis(pluginId, taxis); + DataProvider.Plugin.UpdateTaxis(pluginId, taxis); ClearCache(); } } @@ -727,7 +740,7 @@ public static string GetPluginIconUrl(string pluginId) return string.Empty; } - public static string GetPluginIconUrl(PluginService service) + public static string GetPluginIconUrl(ServiceImpl service) { var url = string.Empty; if (service.Metadata.IconUrl != null) diff --git a/net452/SiteServer.CMS/Plugin/PluginMenu.cs b/net452/SiteServer.CMS/Plugin/PluginMenu.cs new file mode 100644 index 000000000..8a09250f1 --- /dev/null +++ b/net452/SiteServer.CMS/Plugin/PluginMenu.cs @@ -0,0 +1,9 @@ +using SiteServer.Plugin; + +namespace SiteServer.CMS.Plugin +{ + public class PluginMenu : Menu + { + public string PluginId { get; set; } + } +} diff --git a/net452/SiteServer.CMS/Plugin/PluginMenuManager.cs b/net452/SiteServer.CMS/Plugin/PluginMenuManager.cs new file mode 100644 index 000000000..9a5259b2f --- /dev/null +++ b/net452/SiteServer.CMS/Plugin/PluginMenuManager.cs @@ -0,0 +1,315 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.CMS.Plugin +{ + public static class PluginMenuManager + { + public static string GetSystemDefaultPageUrl(int siteId) + { + string pageUrl = null; + + foreach (var service in PluginManager.Services) + { + if (service.SystemDefaultPageUrl == null) continue; + + try + { + pageUrl = GetMenuHref(service.PluginId, service.SystemDefaultPageUrl, siteId, 0, 0); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(service.PluginId, ex); + } + } + + return pageUrl; + } + + public static string GetHomeDefaultPageUrl() + { + string pageUrl = null; + + foreach (var service in PluginManager.Services) + { + if (service.HomeDefaultPageUrl == null) continue; + + try + { + pageUrl = GetMenuHref(service.PluginId, service.HomeDefaultPageUrl, 0, 0, 0); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(service.PluginId, ex); + } + } + + return pageUrl; + } + + public static List GetTopMenus() + { + var menus = new List(); + + foreach (var service in PluginManager.Services) + { + if (service.SystemMenuFuncs == null) continue; + + try + { + var metadataMenus = new List(); + + foreach (var menuFunc in service.SystemMenuFuncs) + { + var metadataMenu = menuFunc.Invoke(); + if (metadataMenu != null) + { + metadataMenus.Add(metadataMenu); + } + } + + if (metadataMenus.Count == 0) continue; + + var i = 0; + foreach (var metadataMenu in metadataMenus) + { + var pluginMenu = GetMenu(service.PluginId, 0, 0, 0, metadataMenu, ++i); + menus.Add(pluginMenu); + } + } + catch (Exception ex) + { + LogUtils.AddErrorLog(service.PluginId, ex); + } + } + + return menus; + } + + public static List GetSiteMenus(int siteId) + { + var menus = new List(); + + foreach (var service in PluginManager.Services) + { + if (service.SiteMenuFuncs == null) continue; + + try + { + var metadataMenus = new List(); + + foreach (var menuFunc in service.SiteMenuFuncs) + { + var metadataMenu = menuFunc.Invoke(siteId); + if (metadataMenu != null) + { + metadataMenus.Add(metadataMenu); + } + } + + if (metadataMenus.Count == 0) continue; + + var i = 0; + foreach (var metadataMenu in metadataMenus) + { + var pluginMenu = GetMenu(service.PluginId, siteId, 0, 0, metadataMenu, ++i); + menus.Add(pluginMenu); + } + } + catch (Exception ex) + { + LogUtils.AddErrorLog(service.PluginId, ex); + } + } + + return menus; + } + + public static List GetContentMenus(List pluginIds, ContentInfo contentInfo) + { + var menus = new List(); + if (pluginIds == null || pluginIds.Count == 0) return menus; + + foreach (var service in PluginManager.Services) + { + if (!pluginIds.Contains(service.PluginId)) continue; + + if (service.ContentMenuFuncs == null) continue; + + try + { + var metadataMenus = new List(); + + foreach (var menuFunc in service.ContentMenuFuncs) + { + var metadataMenu = menuFunc.Invoke(contentInfo); + if (metadataMenu != null) + { + metadataMenus.Add(metadataMenu); + } + } + + if (metadataMenus.Count == 0) continue; + + var i = 0; + foreach (var metadataMenu in metadataMenus) + { + var pluginMenu = GetMenu(service.PluginId, contentInfo.SiteId, contentInfo.ChannelId, contentInfo.Id, metadataMenu, ++i); + menus.Add(pluginMenu); + } + } + catch (Exception ex) + { + LogUtils.AddErrorLog(service.PluginId, ex); + } + } + + return menus; + } + + private static string GetMenuHref(string pluginId, string href, int siteId, int channelId, int contentId) + { + if (PageUtils.IsAbsoluteUrl(href)) + { + return href; + } + + var url = PageUtils.AddQueryStringIfNotExists(FxUtils.ParsePluginUrl(pluginId, href), new NameValueCollection + { + {"v", StringUtils.GetRandomInt(1, 1000).ToString()}, + {"apiUrl", ApiManager.InnerApiUrl} + }); + if (siteId > 0) + { + url = PageUtils.AddQueryStringIfNotExists(url, new NameValueCollection + { + {"siteId", siteId.ToString()} + }); + } + if (channelId > 0) + { + url = PageUtils.AddQueryStringIfNotExists(url, new NameValueCollection + { + {"channelId", channelId.ToString()} + }); + } + if (contentId > 0) + { + url = PageUtils.AddQueryStringIfNotExists(url, new NameValueCollection + { + {"contentId", contentId.ToString()} + }); + } + return url; + } + + //public static string GetMenuContentHref(string pluginId, string href, int siteId, int channelId, int contentId, string returnUrl) + //{ + // if (PageUtils.IsAbsoluteUrl(href)) + // { + // return href; + // } + // return PageUtils.AddQueryStringIfNotExists(PageUtils.ParsePluginUrl(pluginId, href), new NameValueCollection + // { + // {"siteId", siteId.ToString()}, + // {"channelId", channelId.ToString()}, + // {"contentId", contentId.ToString()}, + // {"apiUrl", ApiManager.ApiUrl}, + // {"returnUrl", returnUrl}, + // {"v", StringUtils.GetRandomInt(1, 1000).ToString()} + // }); + //} + + //public static string GetMenuContentHrefPrefix(string pluginId, string href) + //{ + // if (PageUtils.IsAbsoluteUrl(href)) + // { + // return href; + // } + // return PageUtils.AddQueryStringIfNotExists(PageUtils.ParsePluginUrl(pluginId, href), new NameValueCollection + // { + // {"apiUrl", ApiManager.ApiUrl}, + // {"v", StringUtils.GetRandomInt(1, 1000).ToString()} + // }); + //} + + private static PluginMenu GetMenu(string pluginId, int siteId, int channelId, int contentId, Menu metadataMenu, int i) + { + var menu = new PluginMenu + { + Id = metadataMenu.Id, + Text = metadataMenu.Text, + Href = metadataMenu.Href, + Target = metadataMenu.Target, + IconClass = metadataMenu.IconClass, + PluginId = pluginId + }; + + if (string.IsNullOrEmpty(menu.Id)) + { + menu.Id = pluginId + i; + } + if (!string.IsNullOrEmpty(menu.Href)) + { + menu.Href = GetMenuHref(pluginId, menu.Href, siteId, channelId, contentId); + } + if (channelId == 0 && contentId == 0 && string.IsNullOrEmpty(menu.Target)) + { + menu.Target = "right"; + } + + if (metadataMenu.Menus != null && metadataMenu.Menus.Count > 0) + { + var chlildren = new List(); + var j = i * 100; + foreach (var childMetadataMenu in metadataMenu.Menus) + { + var child = GetMenu(pluginId, siteId, channelId, contentId, childMetadataMenu, ++j); + + chlildren.Add(child); + } + menu.Menus = chlildren; + } + + return menu; + } + + public static List GetTopPermissions() + { + var permissions = new List(); + + foreach (var service in PluginManager.Services) + { + if (service.SystemMenuFuncs != null) + { + permissions.Add(new PermissionConfigManager.PermissionConfig(service.PluginId, $"系统管理 -> {service.Metadata.Title}(插件)")); + } + } + + return permissions; + } + + public static List GetSitePermissions(int siteId) + { + var permissions = new List(); + + foreach (var service in PluginManager.Services) + { + if (service.SiteMenuFuncs != null) + { + permissions.Add(new PermissionConfigManager.PermissionConfig(service.PluginId, $"{service.Metadata.Title}")); + } + } + + return permissions; + } + } +} diff --git a/net452/SiteServer.CMS/Plugin/PluginStlParserManager.cs b/net452/SiteServer.CMS/Plugin/PluginStlParserManager.cs new file mode 100644 index 000000000..0a667c396 --- /dev/null +++ b/net452/SiteServer.CMS/Plugin/PluginStlParserManager.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using SiteServer.CMS.Plugin.Impl; + +namespace SiteServer.CMS.Plugin +{ + public static class PluginStlParserContentManager + { + public static Dictionary> GetParses() + { + var elementsToParse = new Dictionary>(); + + foreach (var service in PluginManager.Services) + { + if (service.StlElementsToParse != null && service.StlElementsToParse.Count > 0) + { + foreach (var elementName in service.StlElementsToParse.Keys) + { + elementsToParse[elementName.ToLower()] = service.StlElementsToParse[elementName]; + } + } + } + + return elementsToParse; + } + } +} diff --git a/net452/SiteServer.CMS/Properties/AssemblyInfo.cs b/net452/SiteServer.CMS/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..2eccf8c4f --- /dev/null +++ b/net452/SiteServer.CMS/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +// 有关程序集的一般信息由以下 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("SiteServer.CMS")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SiteServer.CMS")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型 +//请将此类型的 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID +[assembly: Guid("55efd315-e628-4293-9505-d1f919ade339")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 生成号 +// 修订号 +// +// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号 +//通过使用 "*",如下所示: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("0.0.0")] +[assembly: AssemblyFileVersion("0.0.0")] +[assembly: AssemblyInformationalVersion("0.0.0-dev")] diff --git a/net452/SiteServer.CMS/SiteServer.CMS.csproj b/net452/SiteServer.CMS/SiteServer.CMS.csproj new file mode 100644 index 000000000..83805063d --- /dev/null +++ b/net452/SiteServer.CMS/SiteServer.CMS.csproj @@ -0,0 +1,498 @@ + + + + + + Debug + AnyCPU + {944127C3-915D-4F02-A534-64EC668C46EC} + Library + Properties + SiteServer.CMS + SiteServer.CMS + v4.5.2 + 512 + + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + ..\..\packages\Dapper.1.60.6\lib\net451\Dapper.dll + + + ..\..\packages\Datory.0.1.7\lib\net452\Datory.dll + + + ..\..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll + + + ..\..\packages\HtmlAgilityPack.1.11.2\lib\Net45\HtmlAgilityPack.dll + + + ..\..\packages\Microsoft.Web.Xdt.2.1.1\lib\net40\Microsoft.Web.XmlTransform.dll + + + ..\..\packages\MySql.Data.8.0.15\lib\net452\MySql.Data.dll + + + ..\..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll + + + ..\..\packages\Npgsql.4.0.5\lib\net451\Npgsql.dll + + + ..\..\packages\NuGet.Common.4.5.0\lib\net45\NuGet.Common.dll + + + ..\..\packages\NuGet.Core.2.14.0\lib\net40-Client\NuGet.Core.dll + + + ..\..\packages\NuGet.Frameworks.4.5.0\lib\net45\NuGet.Frameworks.dll + + + ..\..\packages\NuGet.Packaging.4.5.0\lib\net45\NuGet.Packaging.dll + + + ..\..\packages\NuGet.Packaging.Core.4.5.0\lib\net45\NuGet.Packaging.Core.dll + + + ..\..\packages\NuGet.Versioning.4.5.0\lib\net45\NuGet.Versioning.dll + + + ..\..\packages\Oracle.ManagedDataAccess.18.6.0\lib\net40\Oracle.ManagedDataAccess.dll + + + ..\..\packages\SqlKata.1.1.7\lib\net45\QueryBuilder.dll + + + ..\..\packages\SiteServer.Plugin.2.2.14-beta\lib\net452\SiteServer.Plugin.dll + + + + ..\..\packages\System.Buffers.4.4.0\lib\netstandard2.0\System.Buffers.dll + + + + + + + + + ..\..\packages\System.Data.Common.4.3.0\lib\net451\System.Data.Common.dll + + + + ..\..\packages\System.Data.SqlClient.4.6.0\lib\net451\System.Data.SqlClient.dll + + + + + + + ..\..\packages\System.Memory.4.5.2\lib\netstandard2.0\System.Memory.dll + + + ..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll + + + + ..\..\packages\System.Numerics.Vectors.4.4.0\lib\net46\System.Numerics.Vectors.dll + + + + ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard1.0\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll + + + + ..\..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll + + + + ..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.7\lib\net45\System.Web.Http.dll + + + + + + + + + ..\ref\WordPlugin.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {059e3927-37e1-4f6f-b525-fef40c54906b} + SiteServer.Utils + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + \ No newline at end of file diff --git a/net452/SiteServer.CMS/StlParser/FileSystemObjectAsync.cs b/net452/SiteServer.CMS/StlParser/FileSystemObjectAsync.cs new file mode 100644 index 000000000..60c5b1c61 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/FileSystemObjectAsync.cs @@ -0,0 +1,484 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Caches.Stl; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.StlElement; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Plugin; + +namespace SiteServer.CMS.StlParser +{ + public static class FileSystemObjectAsync + { + public static async Task ExecuteAsync(int siteId, ECreateType createType, int channelId, int contentId, + int fileTemplateId, int specialId) + { + if (createType == ECreateType.Channel) + { + await CreateChannelAsync(siteId, channelId); + } + else if (createType == ECreateType.Content) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + await CreateContentAsync(siteInfo, channelInfo, contentId); + } + else if (createType == ECreateType.AllContent) + { + await CreateContentsAsync(siteId, channelId); + } + else if (createType == ECreateType.File) + { + await CreateFileAsync(siteId, fileTemplateId); + } + else if (createType == ECreateType.Special) + { + await CreateSpecialAsync(siteId, specialId); + } + } + + private static async Task CreateContentsAsync(int siteId, int channelId) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + var orderByString = ETaxisTypeUtils.GetContentOrderByString(ETaxisType.OrderByTaxisDesc); + var contentIdList = StlContentCache.GetContentIdListChecked(tableName, channelId, orderByString); + + foreach (var contentId in contentIdList) + { + await CreateContentAsync(siteInfo, channelInfo, contentId); + } + } + + private static async Task CreateChannelAsync(int siteId, int channelId) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + + if (!ChannelManager.IsCreatable(siteInfo, channelInfo)) return; + + var templateInfo = channelId == siteId + ? TemplateManager.GetIndexPageTemplateInfo(siteId) + : TemplateManager.GetChannelTemplateInfo(siteId, channelId); + var filePath = PathUtility.GetChannelPageFilePath(siteInfo, channelId, 0); + var pageInfo = new PageInfo(channelId, 0, siteInfo, templateInfo, new Dictionary()); + var contextInfo = new ContextInfo(pageInfo) + { + ContextType = EContextType.Channel + }; + var contentBuilder = new StringBuilder(TemplateManager.GetTemplateContent(siteInfo, templateInfo)); + + var stlLabelList = StlParserUtility.GetStlLabelList(contentBuilder.ToString()); + + //如果标签中存在 + if (StlParserUtility.IsStlChannelElementWithTypePageContent(stlLabelList)) //内容存在 + { + var stlElement = StlParserUtility.GetStlChannelElementWithTypePageContent(stlLabelList); + var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); + contentBuilder.Replace(stlElement, stlElementTranslated); + + var innerBuilder = new StringBuilder(stlElement); + StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); + var pageContentHtml = innerBuilder.ToString(); + var pageCount = StringUtils.GetCount(ContentUtility.PagePlaceHolder, pageContentHtml) + 1; //一共需要的页数 + + Parser.Parse(pageInfo, contextInfo, contentBuilder, filePath, false); + + for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) + { + var thePageInfo = pageInfo.Clone(); + + var index = pageContentHtml.IndexOf(ContentUtility.PagePlaceHolder, StringComparison.Ordinal); + var length = index == -1 ? pageContentHtml.Length : index; + + var pageHtml = pageContentHtml.Substring(0, length); + var pagedBuilder = + new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); + StlParserManager.ReplacePageElementsInChannelPage(pagedBuilder, thePageInfo, stlLabelList, + thePageInfo.PageChannelId, currentPageIndex, pageCount, 0); + + filePath = PathUtility.GetChannelPageFilePath(siteInfo, thePageInfo.PageChannelId, + currentPageIndex); + await GenerateFileAsync(filePath, pagedBuilder); + + if (index != -1) + { + pageContentHtml = pageContentHtml.Substring(length + ContentUtility.PagePlaceHolder.Length); + } + } + } + //如果标签中存在 + else if (StlParserUtility.IsStlElementExists(StlPageContents.ElementName, stlLabelList)) + { + var stlElement = StlParserUtility.GetStlElement(StlPageContents.ElementName, stlLabelList); + var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); + + var pageContentsElementParser = new StlPageContents(stlElement, pageInfo, contextInfo); + var pageCount = pageContentsElementParser.GetPageCount(out var totalNum); + + pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.Jquery); + Parser.Parse(pageInfo, contextInfo, contentBuilder, filePath, false); + + for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) + { + var thePageInfo = pageInfo.Clone(); + var pageHtml = pageContentsElementParser.Parse(totalNum, currentPageIndex, pageCount, true); + var pagedBuilder = + new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); + + StlParserManager.ReplacePageElementsInChannelPage(pagedBuilder, thePageInfo, stlLabelList, + thePageInfo.PageChannelId, currentPageIndex, pageCount, totalNum); + + filePath = PathUtility.GetChannelPageFilePath(siteInfo, thePageInfo.PageChannelId, + currentPageIndex); + thePageInfo.AddLastPageScript(pageInfo); + + await GenerateFileAsync(filePath, pagedBuilder); + + thePageInfo.ClearLastPageScript(pageInfo); + pageInfo.ClearLastPageScript(); + } + } + //如果标签中存在 + else if (StlParserUtility.IsStlElementExists(StlPageChannels.ElementName, stlLabelList)) + { + var stlElement = StlParserUtility.GetStlElement(StlPageChannels.ElementName, stlLabelList); + var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); + + var pageChannelsElementParser = new StlPageChannels(stlElement, pageInfo, contextInfo); + var pageCount = pageChannelsElementParser.GetPageCount(out var totalNum); + + pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.Jquery); + Parser.Parse(pageInfo, contextInfo, contentBuilder, filePath, false); + + for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) + { + var thePageInfo = pageInfo.Clone(); + var pageHtml = pageChannelsElementParser.Parse(currentPageIndex, pageCount); + var pagedBuilder = + new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); + + StlParserManager.ReplacePageElementsInChannelPage(pagedBuilder, thePageInfo, stlLabelList, + thePageInfo.PageChannelId, currentPageIndex, pageCount, totalNum); + + filePath = PathUtility.GetChannelPageFilePath(siteInfo, thePageInfo.PageChannelId, + currentPageIndex); + await GenerateFileAsync(filePath, pagedBuilder); + } + } + //如果标签中存在 + else if (StlParserUtility.IsStlElementExists(StlPageSqlContents.ElementName, stlLabelList)) + { + var stlElement = StlParserUtility.GetStlElement(StlPageSqlContents.ElementName, stlLabelList); + var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); + + var pageSqlContentsElementParser = new StlPageSqlContents(stlElement, pageInfo, contextInfo); + var pageCount = pageSqlContentsElementParser.GetPageCount(out var totalNum); + + pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.Jquery); + Parser.Parse(pageInfo, contextInfo, contentBuilder, filePath, false); + + for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) + { + var thePageInfo = pageInfo.Clone(); + var pageHtml = pageSqlContentsElementParser.Parse(totalNum, currentPageIndex, pageCount, true); + var pagedBuilder = + new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); + + StlParserManager.ReplacePageElementsInChannelPage(pagedBuilder, thePageInfo, stlLabelList, + thePageInfo.PageChannelId, currentPageIndex, pageCount, totalNum); + + filePath = PathUtility.GetChannelPageFilePath(siteInfo, thePageInfo.PageChannelId, + currentPageIndex); + await GenerateFileAsync(filePath, pagedBuilder); + } + } + else + { + Parser.Parse(pageInfo, contextInfo, contentBuilder, filePath, false); + await GenerateFileAsync(filePath, contentBuilder); + } + } + + private static async Task CreateContentAsync(SiteInfo siteInfo, ChannelInfo channelInfo, int contentId) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + + if (contentInfo == null) + { + return; + } + + if (!contentInfo.Checked) + { + DeleteManager.DeleteContent(siteInfo, channelInfo.Id, contentId); + return; + } + + + if (!ContentManager.IsCreatable(channelInfo, contentInfo)) return; + + + if (siteInfo.IsCreateStaticContentByAddDate && + contentInfo.AddDate < siteInfo.CreateStaticContentAddDate) + { + return; + } + + var templateInfo = TemplateManager.GetContentTemplateInfo(siteInfo.Id, channelInfo.Id); + var pageInfo = new PageInfo(channelInfo.Id, contentId, siteInfo, templateInfo, + new Dictionary()); + var contextInfo = new ContextInfo(pageInfo) + { + ContextType = EContextType.Content, + ContentInfo = contentInfo + }; + var filePath = PathUtility.GetContentPageFilePath(siteInfo, pageInfo.PageChannelId, contentInfo, 0); + var contentBuilder = new StringBuilder(TemplateManager.GetTemplateContent(siteInfo, templateInfo)); + + var stlLabelList = StlParserUtility.GetStlLabelList(contentBuilder.ToString()); + + //如果标签中存在 + if (StlParserUtility.IsStlContentElementWithTypePageContent(stlLabelList)) //内容存在 + { + var stlElement = StlParserUtility.GetStlContentElementWithTypePageContent(stlLabelList); + var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); + contentBuilder.Replace(stlElement, stlElementTranslated); + + var innerBuilder = new StringBuilder(stlElement); + StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); + var pageContentHtml = innerBuilder.ToString(); + var pageCount = StringUtils.GetCount(ContentUtility.PagePlaceHolder, pageContentHtml) + 1; //一共需要的页数 + + Parser.Parse(pageInfo, contextInfo, contentBuilder, filePath, false); + + for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) + { + var thePageInfo = pageInfo.Clone(); + + var index = pageContentHtml.IndexOf(ContentUtility.PagePlaceHolder, StringComparison.Ordinal); + var length = index == -1 ? pageContentHtml.Length : index; + + var pageHtml = pageContentHtml.Substring(0, length); + var pagedBuilder = + new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); + StlParserManager.ReplacePageElementsInContentPage(pagedBuilder, thePageInfo, stlLabelList, + channelInfo.Id, contentId, currentPageIndex, pageCount); + + filePath = PathUtility.GetContentPageFilePath(siteInfo, thePageInfo.PageChannelId, contentInfo, + currentPageIndex); + await GenerateFileAsync(filePath, pagedBuilder); + + if (index != -1) + { + pageContentHtml = pageContentHtml.Substring(length + ContentUtility.PagePlaceHolder.Length); + } + } + } + //如果标签中存在 + else if (StlParserUtility.IsStlChannelElementWithTypePageContent(stlLabelList)) //内容存在 + { + var stlElement = StlParserUtility.GetStlChannelElementWithTypePageContent(stlLabelList); + var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); + contentBuilder.Replace(stlElement, stlElementTranslated); + + var innerBuilder = new StringBuilder(stlElement); + StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); + var pageContentHtml = innerBuilder.ToString(); + var pageCount = StringUtils.GetCount(ContentUtility.PagePlaceHolder, pageContentHtml) + 1; //一共需要的页数 + + Parser.Parse(pageInfo, contextInfo, contentBuilder, filePath, false); + + for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) + { + var thePageInfo = pageInfo.Clone(); + + var index = pageContentHtml.IndexOf(ContentUtility.PagePlaceHolder, StringComparison.Ordinal); + var length = index == -1 ? pageContentHtml.Length : index; + + var pageHtml = pageContentHtml.Substring(0, length); + var pagedBuilder = + new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); + StlParserManager.ReplacePageElementsInContentPage(pagedBuilder, thePageInfo, stlLabelList, + channelInfo.Id, contentId, currentPageIndex, pageCount); + + filePath = PathUtility.GetContentPageFilePath(siteInfo, thePageInfo.PageChannelId, contentInfo, + currentPageIndex); + await GenerateFileAsync(filePath, pagedBuilder); + + if (index != -1) + { + pageContentHtml = pageContentHtml.Substring(length + ContentUtility.PagePlaceHolder.Length); + } + } + } + //如果标签中存在 + else if (StlParserUtility.IsStlElementExists(StlPageContents.ElementName, stlLabelList)) + { + var stlElement = StlParserUtility.GetStlElement(StlPageContents.ElementName, stlLabelList); + var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); + + var pageContentsElementParser = new StlPageContents(stlElement, pageInfo, contextInfo); + var pageCount = pageContentsElementParser.GetPageCount(out var totalNum); + + Parser.Parse(pageInfo, contextInfo, contentBuilder, filePath, false); + + for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) + { + var thePageInfo = pageInfo.Clone(); + var pageHtml = pageContentsElementParser.Parse(totalNum, currentPageIndex, pageCount, true); + var pagedBuilder = + new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); + + StlParserManager.ReplacePageElementsInContentPage(pagedBuilder, thePageInfo, stlLabelList, + channelInfo.Id, contentId, currentPageIndex, pageCount); + + filePath = PathUtility.GetContentPageFilePath(siteInfo, thePageInfo.PageChannelId, contentInfo, + currentPageIndex); + await GenerateFileAsync(filePath, pagedBuilder); + } + } + //如果标签中存在 + else if (StlParserUtility.IsStlElementExists(StlPageChannels.ElementName, stlLabelList)) + { + var stlElement = StlParserUtility.GetStlElement(StlPageChannels.ElementName, stlLabelList); + var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); + + var pageChannelsElementParser = new StlPageChannels(stlElement, pageInfo, contextInfo); + var pageCount = pageChannelsElementParser.GetPageCount(out _); + + Parser.Parse(pageInfo, contextInfo, contentBuilder, filePath, false); + + for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) + { + var thePageInfo = pageInfo.Clone(); + var pageHtml = pageChannelsElementParser.Parse(currentPageIndex, pageCount); + var pagedBuilder = + new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); + + StlParserManager.ReplacePageElementsInContentPage(pagedBuilder, thePageInfo, stlLabelList, + channelInfo.Id, contentId, currentPageIndex, pageCount); + + filePath = PathUtility.GetContentPageFilePath(siteInfo, thePageInfo.PageChannelId, contentInfo, + currentPageIndex); + await GenerateFileAsync(filePath, pagedBuilder); + } + } + //如果标签中存在 + else if (StlParserUtility.IsStlElementExists(StlPageSqlContents.ElementName, stlLabelList)) + { + var stlElement = StlParserUtility.GetStlElement(StlPageSqlContents.ElementName, stlLabelList); + var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); + + var pageSqlContentsElementParser = new StlPageSqlContents(stlElement, pageInfo, contextInfo); + var pageCount = pageSqlContentsElementParser.GetPageCount(out var totalNum); + + Parser.Parse(pageInfo, contextInfo, contentBuilder, filePath, false); + + for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) + { + var thePageInfo = pageInfo.Clone(); + var pageHtml = pageSqlContentsElementParser.Parse(totalNum, currentPageIndex, pageCount, true); + var pagedBuilder = + new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); + + StlParserManager.ReplacePageElementsInContentPage(pagedBuilder, thePageInfo, stlLabelList, + channelInfo.Id, contentId, currentPageIndex, pageCount); + + filePath = PathUtility.GetContentPageFilePath(siteInfo, thePageInfo.PageChannelId, contentInfo, + currentPageIndex); + await GenerateFileAsync(filePath, pagedBuilder); + } + } + else //无翻页 + { + Parser.Parse(pageInfo, contextInfo, contentBuilder, filePath, false); + await GenerateFileAsync(filePath, contentBuilder); + } + } + + private static async Task CreateFileAsync(int siteId, int fileTemplateId) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + var templateInfo = TemplateManager.GetTemplateInfo(siteId, fileTemplateId); + if (templateInfo == null || templateInfo.Type != TemplateType.FileTemplate) + { + return; + } + + var pageInfo = new PageInfo(siteId, 0, siteInfo, templateInfo, new Dictionary()); + var contextInfo = new ContextInfo(pageInfo); + var filePath = PathUtility.MapPath(siteInfo, templateInfo.CreatedFileFullName); + + var contentBuilder = new StringBuilder(TemplateManager.GetTemplateContent(siteInfo, templateInfo)); + Parser.Parse(pageInfo, contextInfo, contentBuilder, filePath, false); + await GenerateFileAsync(filePath, contentBuilder); + } + + private static async Task CreateSpecialAsync(int siteId, int specialId) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + var templateInfoList = SpecialManager.GetTemplateInfoList(siteInfo, specialId); + foreach (var templateInfo in templateInfoList) + { + var pageInfo = new PageInfo(siteId, 0, siteInfo, templateInfo, new Dictionary()); + var contextInfo = new ContextInfo(pageInfo); + var filePath = PathUtility.MapPath(siteInfo, templateInfo.CreatedFileFullName); + + var contentBuilder = new StringBuilder(templateInfo.Content); + Parser.Parse(pageInfo, contextInfo, contentBuilder, filePath, false); + await GenerateFileAsync(filePath, contentBuilder); + } + } + + //private string CreateIncludeFile(string virtualUrl, bool isCreateIfExists) + //{ + // var templateInfo = new TemplateInfo(0, SiteId, string.Empty, TemplateType.FileTemplate, string.Empty, string.Empty, string.Empty, ECharsetUtils.GetEnumType(SiteInfo.Charset), false); + // var pageInfo = new PageInfo(SiteId, 0, SiteInfo, templateInfo, null); + // var contextInfo = new ContextInfo(pageInfo); + + // var parsedVirtualUrl = virtualUrl.Substring(0, virtualUrl.LastIndexOf('.')) + "_parsed" + virtualUrl.Substring(virtualUrl.LastIndexOf('.')); + // var filePath = PathUtility.MapPath(SiteInfo, parsedVirtualUrl); + // if (!isCreateIfExists && FileUtils.IsFileExists(filePath)) return parsedVirtualUrl; + + // var contentBuilder = new StringBuilder(StlCacheManager.FileContent.GetIncludeContent(SiteInfo, virtualUrl, pageInfo.TemplateInfo.Charset)); + // StlParserManager.ParseTemplateContent(contentBuilder, pageInfo, contextInfo); + // var pageAfterBodyScripts = StlParserManager.GetPageInfoScript(pageInfo, true); + // var pageBeforeBodyScripts = StlParserManager.GetPageInfoScript(pageInfo, false); + // contentBuilder.InsertObject(0, pageBeforeBodyScripts); + // contentBuilder.Append(pageAfterBodyScripts); + // GenerateFile(filePath, pageInfo.TemplateInfo.Charset, contentBuilder); + // return parsedVirtualUrl; + //} + + /// + /// 在操作系统中创建文件,如果文件存在,重新创建此文件 + /// + private static async Task GenerateFileAsync(string filePath, StringBuilder contentBuilder) + { + if (string.IsNullOrEmpty(filePath)) return; + + try + { + await FileUtils.WriteTextAsync(filePath, contentBuilder.ToString()); + } + catch + { + FileUtils.RemoveReadOnlyAndHiddenIfExists(filePath); + await FileUtils.WriteTextAsync(filePath, contentBuilder.ToString()); + } + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.CMS/StlParser/Model/ChannelIdContentId.cs b/net452/SiteServer.CMS/StlParser/Model/ChannelIdContentId.cs new file mode 100644 index 000000000..ab798e78e --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/Model/ChannelIdContentId.cs @@ -0,0 +1,9 @@ +namespace SiteServer.CMS.StlParser.Model +{ + public class MinContentInfo + { + public int Id { get; set; } + + public int ChannelId { get; set; } + } +} diff --git a/SiteServer.CMS/StlParser/Model/ChannelItemInfo.cs b/net452/SiteServer.CMS/StlParser/Model/ChannelItemInfo.cs similarity index 100% rename from SiteServer.CMS/StlParser/Model/ChannelItemInfo.cs rename to net452/SiteServer.CMS/StlParser/Model/ChannelItemInfo.cs diff --git a/SiteServer.CMS/StlParser/Model/ContentItemInfo.cs b/net452/SiteServer.CMS/StlParser/Model/ContentItemInfo.cs similarity index 100% rename from SiteServer.CMS/StlParser/Model/ContentItemInfo.cs rename to net452/SiteServer.CMS/StlParser/Model/ContentItemInfo.cs diff --git a/net452/SiteServer.CMS/StlParser/Model/ContextInfo.cs b/net452/SiteServer.CMS/StlParser/Model/ContextInfo.cs new file mode 100644 index 000000000..cd5d7e3b2 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/Model/ContextInfo.cs @@ -0,0 +1,105 @@ +using System.Collections.Specialized; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.CMS.StlParser.Model +{ + public class ContextInfo + { + public ContextInfo(PageInfo pageInfo) + { + SiteInfo = pageInfo.SiteInfo; + ChannelId = pageInfo.PageChannelId; + ContentId = pageInfo.PageContentId; + } + + //用于clone + private ContextInfo(ContextInfo contextInfo) + { + ContextType = contextInfo.ContextType; + SiteInfo = contextInfo.SiteInfo; + ChannelId = contextInfo.ChannelId; + ContentId = contextInfo.ContentId; + _channelInfo = contextInfo._channelInfo; + _contentInfo = contextInfo._contentInfo; + + IsInnerElement = contextInfo.IsInnerElement; + IsStlEntity = contextInfo.IsStlEntity; + PageItemIndex = contextInfo.PageItemIndex; + ItemContainer = contextInfo.ItemContainer; + ContainerClientId = contextInfo.ContainerClientId; + + OuterHtml = contextInfo.OuterHtml; + InnerHtml = contextInfo.InnerHtml; + Attributes = contextInfo.Attributes; + } + + public ContextInfo Clone(string outerHtml, string innerHtml, NameValueCollection attributes) + { + var contextInfo = new ContextInfo(this) + { + OuterHtml = outerHtml, + InnerHtml = innerHtml, + Attributes = attributes + }; + return contextInfo; + } + + public ContextInfo Clone() + { + var contextInfo = new ContextInfo(this); + return contextInfo; + } + + public EContextType ContextType { get; set; } = EContextType.Undefined; + + public SiteInfo SiteInfo { get; set; } + + public int ChannelId { get; set; } + + public int ContentId { get; set; } + + public string OuterHtml { get; set; } + + public string InnerHtml { get; set; } + + public NameValueCollection Attributes { get; set; } + + private ChannelInfo _channelInfo; + public ChannelInfo ChannelInfo + { + get + { + if (_channelInfo != null) return _channelInfo; + if (ChannelId <= 0) return null; + _channelInfo = ChannelManager.GetChannelInfo(SiteInfo.Id, ChannelId); + return _channelInfo; + } + set { _channelInfo = value; } + } + + private ContentInfo _contentInfo; + public ContentInfo ContentInfo + { + get + { + if (_contentInfo != null) return _contentInfo; + if (ContentId <= 0) return null; + _contentInfo = ContentManager.GetContentInfo(SiteInfo, ChannelId, ContentId); + return _contentInfo; + } + set { _contentInfo = value; } + } + + public bool IsInnerElement { get; set; } + + public bool IsStlEntity { get; set; } + + public int PageItemIndex { get; set; } + + public DbItemContainer ItemContainer { get; set; } + + public string ContainerClientId { get; set; } + } +} diff --git a/SiteServer.CMS/StlParser/Model/DbItemContainer.cs b/net452/SiteServer.CMS/StlParser/Model/DbItemContainer.cs similarity index 100% rename from SiteServer.CMS/StlParser/Model/DbItemContainer.cs rename to net452/SiteServer.CMS/StlParser/Model/DbItemContainer.cs diff --git a/SiteServer.CMS/StlParser/Model/DbItemInfo.cs b/net452/SiteServer.CMS/StlParser/Model/DbItemInfo.cs similarity index 100% rename from SiteServer.CMS/StlParser/Model/DbItemInfo.cs rename to net452/SiteServer.CMS/StlParser/Model/DbItemInfo.cs diff --git a/SiteServer.CMS/StlParser/Model/EContextType.cs b/net452/SiteServer.CMS/StlParser/Model/EContextType.cs similarity index 98% rename from SiteServer.CMS/StlParser/Model/EContextType.cs rename to net452/SiteServer.CMS/StlParser/Model/EContextType.cs index 8d491c072..0abe929ba 100644 --- a/SiteServer.CMS/StlParser/Model/EContextType.cs +++ b/net452/SiteServer.CMS/StlParser/Model/EContextType.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Generic; namespace SiteServer.CMS.StlParser.Model { diff --git a/SiteServer.CMS/StlParser/Model/EStlEntityType.cs b/net452/SiteServer.CMS/StlParser/Model/EStlEntityType.cs similarity index 98% rename from SiteServer.CMS/StlParser/Model/EStlEntityType.cs rename to net452/SiteServer.CMS/StlParser/Model/EStlEntityType.cs index 0d551b21f..176430727 100644 --- a/SiteServer.CMS/StlParser/Model/EStlEntityType.cs +++ b/net452/SiteServer.CMS/StlParser/Model/EStlEntityType.cs @@ -1,6 +1,5 @@ namespace SiteServer.CMS.StlParser.Model { - public enum EStlEntityType { Stl, //通用实体 @@ -14,7 +13,7 @@ public enum EStlEntityType Unkown } - public class EStlEntityTypeUtils + public static class EStlEntityTypeUtils { public const string RegexStringAll = @"{stl\.[^{}]*}|{stl:[^{}]*}|{content\.[^{}]*}|{channel\.[^{}]*}|{comment\.[^{}]*}|{request\.[^{}]*}|{sql\.[^{}]*}|{user\.[^{}]*}|{navigation\.[^{}]*}|{photo\.[^{}]*}"; diff --git a/SiteServer.CMS/StlParser/Model/ListInfo.cs b/net452/SiteServer.CMS/StlParser/Model/ListInfo.cs similarity index 77% rename from SiteServer.CMS/StlParser/Model/ListInfo.cs rename to net452/SiteServer.CMS/StlParser/Model/ListInfo.cs index 3cf7bdcca..6be385af6 100644 --- a/SiteServer.CMS/StlParser/Model/ListInfo.cs +++ b/net452/SiteServer.CMS/StlParser/Model/ListInfo.cs @@ -1,13 +1,14 @@ -using System.Collections; -using System.Text; +using System.Text; using System.Web.UI.WebControls; using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model.Enumerations; using SiteServer.CMS.StlParser.Parsers; using SiteServer.CMS.StlParser.StlElement; using SiteServer.CMS.StlParser.Utility; using SiteServer.Utils.Enumerations; +using System.Collections.Generic; +using System.Collections.Specialized; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Fx; namespace SiteServer.CMS.StlParser.Model { @@ -28,34 +29,34 @@ public class ListInfo private bool _isVideo; private bool _isFile; - public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo contextInfo, EContextType contextType) + public static ListInfo GetListInfo(PageInfo pageInfo, ContextInfo contextInfo, EContextType contextType) { var listInfo = new ListInfo { _contextType = contextType }; - var innerXml = contextInfo.InnerXml; + var innerHtml = contextInfo.InnerHtml; var itemTemplate = string.Empty; - if (!string.IsNullOrEmpty(innerXml)) + if (!string.IsNullOrEmpty(innerHtml)) { - var stlElementList = StlParserUtility.GetStlElementList(innerXml); + var stlElementList = StlParserUtility.GetStlElementList(innerHtml); if (stlElementList.Count > 0) { foreach (var theStlElement in stlElementList) { if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlItemTemplate.ElementName)) { - var attributes = new LowerNameValueCollection(); - var templateString = StlParserUtility.GetInnerXml(theStlElement, true, attributes); + var attributes = TranslateUtils.NewIgnoreCaseNameValueCollection(); + var templateString = StlParserUtility.GetInnerHtml(theStlElement, attributes); if (!string.IsNullOrEmpty(templateString)) { - foreach (var key in attributes.Keys) + foreach (var key in attributes.AllKeys) { - if (!StringUtils.EqualsIgnoreCase(key, StlItemTemplate.Type.Name)) continue; + if (!StringUtils.EqualsIgnoreCase(key, StlItemTemplate.Type)) continue; - var type = attributes.Get(key); + var type = attributes[key]; if (StringUtils.EqualsIgnoreCase(type, StlItemTemplate.TypeItem)) { itemTemplate = templateString; @@ -74,13 +75,13 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte } else if (StringUtils.EqualsIgnoreCase(type, StlItemTemplate.TypeSelectedItem)) { - if (!string.IsNullOrEmpty(attributes.Get(StlItemTemplate.Selected.Name))) + if (!string.IsNullOrEmpty(attributes[StlItemTemplate.Selected])) { - var selected = attributes.Get(StlItemTemplate.Selected.Name); - var arraylist = new ArrayList(); + var selected = attributes[StlItemTemplate.Selected]; + var list = new List(); if (selected.IndexOf(',') != -1) { - arraylist.AddRange(selected.Split(',')); + list.AddRange(selected.Split(',')); } else { @@ -90,28 +91,28 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte var second = TranslateUtils.ToInt(selected.Split('-')[1]); for (var i = first; i <= second; i++) { - arraylist.Add(i.ToString()); + list.Add(i.ToString()); } } else { - arraylist.Add(selected); + list.Add(selected); } } - foreach (string val in arraylist) + foreach (string val in list) { listInfo.SelectedItems.Set(val, templateString); } - if (!string.IsNullOrEmpty(attributes.Get(StlItemTemplate.SelectedValue.Name))) + if (!string.IsNullOrEmpty(attributes[StlItemTemplate.SelectedValue])) { - var selectedValue = attributes.Get(StlItemTemplate.SelectedValue.Name); + var selectedValue = attributes[StlItemTemplate.SelectedValue]; listInfo.SelectedValues.Set(selectedValue, templateString); } } } else if (StringUtils.EqualsIgnoreCase(type, StlItemTemplate.TypeSeparator)) { - var selectedValue = TranslateUtils.ToInt(attributes.Get(StlItemTemplate.SelectedValue.Name), 1); + var selectedValue = TranslateUtils.ToInt(attributes[StlItemTemplate.SelectedValue], 1); if (selectedValue <= 1) { listInfo.SeparatorTemplate = templateString; @@ -124,23 +125,21 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte } } } - innerXml = innerXml.Replace(theStlElement, string.Empty); + innerHtml = innerHtml.Replace(theStlElement, string.Empty); } else if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlLoading.ElementName)) { - var innerBuilder = new StringBuilder(StlParserUtility.GetInnerXml(theStlElement, true)); + var innerBuilder = new StringBuilder(StlParserUtility.GetInnerHtml(theStlElement)); StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); - StlParserUtility.XmlToHtml(innerBuilder); listInfo.LoadingTemplate = innerBuilder.ToString(); - innerXml = innerXml.Replace(theStlElement, string.Empty); + innerHtml = innerHtml.Replace(theStlElement, string.Empty); } else if (contextType == EContextType.SqlContent && StlParserUtility.IsSpecifiedStlElement(theStlElement, StlQueryString.ElementName)) { - var innerBuilder = new StringBuilder(StlParserUtility.GetInnerXml(theStlElement, true)); + var innerBuilder = new StringBuilder(StlParserUtility.GetInnerHtml(theStlElement)); StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); - StlParserUtility.XmlToHtml(innerBuilder); listInfo.QueryString = innerBuilder.ToString(); - innerXml = innerXml.Replace(theStlElement, string.Empty); + innerHtml = innerHtml.Replace(theStlElement, string.Empty); } } } @@ -148,7 +147,7 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte if (string.IsNullOrEmpty(itemTemplate)) { - listInfo.ItemTemplate = !string.IsNullOrEmpty(innerXml) ? innerXml : ""; + listInfo.ItemTemplate = !string.IsNullOrEmpty(innerHtml) ? innerHtml : ""; } else { @@ -157,75 +156,79 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte var isSetDirection = false;//是否设置了direction属性 - foreach (var name in contextInfo.Attributes.Keys) + foreach (var name in contextInfo.Attributes.AllKeys) { var value = contextInfo.Attributes[name]; - if (StringUtils.EqualsIgnoreCase(name, StlContents.ChannelIndex.Name)) + if (StringUtils.EqualsIgnoreCase(name, StlListBase.ChannelIndex)) { listInfo.ChannelIndex = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.ChannelName.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.ChannelName)) { listInfo.ChannelName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.UpLevel.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.Parent)) + { + listInfo.UpLevel = 1; + } + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.UpLevel)) { listInfo.UpLevel = TranslateUtils.ToInt(value); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.TopLevel.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.TopLevel)) { listInfo.TopLevel = TranslateUtils.ToInt(value); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.Scope.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.Scope)) { listInfo.Scope = EScopeTypeUtils.GetEnumType(value); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.IsTop.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.IsTop)) { listInfo.IsTop = TranslateUtils.ToBool(value); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.IsRecommend.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.IsRecommend)) { listInfo.IsRecommend = TranslateUtils.ToBool(value); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.IsHot.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.IsHot)) { listInfo.IsHot = TranslateUtils.ToBool(value); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.IsColor.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.IsColor)) { listInfo.IsColor = TranslateUtils.ToBool(value); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.Where.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.Where)) { listInfo.Where = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.TotalNum.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.TotalNum)) { listInfo.TotalNum = TranslateUtils.ToInt(StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo)); } - else if (StringUtils.EqualsIgnoreCase(name, StlPageContents.PageNum.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlPageContents.PageNum)) { - listInfo.PageNum = TranslateUtils.ToInt(StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo)); + listInfo.PageNum = TranslateUtils.ToInt(StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo), Constants.PageSize); } - else if (StringUtils.EqualsIgnoreCase(name, StlPageContents.MaxPage.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlPageContents.MaxPage)) { listInfo.MaxPage = TranslateUtils.ToInt(StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo)); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.StartNum.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.StartNum)) { listInfo.StartNum = TranslateUtils.ToInt(StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo)); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.Order.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.Order)) { if (contextType == EContextType.Content) { - listInfo.OrderByString = StlDataUtility.GetContentOrderByString(pageInfo.SiteId, value, ETaxisType.OrderByTaxisDesc); + listInfo.OrderByString = StlDataUtility.GetContentOrderByString(value, ETaxisType.OrderByTaxisDesc); } else if (contextType == EContextType.Channel) { - listInfo.OrderByString = StlDataUtility.GetChannelOrderByString(pageInfo.SiteId, value, ETaxisType.OrderByTaxis); + listInfo.OrderByString = StlDataUtility.GetChannelOrderByString(value, ETaxisType.OrderByTaxis); } //else if (contextType == EContextType.InputContent) //{ @@ -236,7 +239,7 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte listInfo.OrderByString = value; } } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.GroupChannel.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.GroupChannel)) { listInfo.GroupChannel = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); if (string.IsNullOrEmpty(listInfo.GroupChannel)) @@ -244,7 +247,7 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte listInfo.GroupChannel = "__Empty__"; } } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.GroupChannelNot.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.GroupChannelNot)) { listInfo.GroupChannelNot = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); if (string.IsNullOrEmpty(listInfo.GroupChannelNot)) @@ -252,7 +255,7 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte listInfo.GroupChannelNot = "__Empty__"; } } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.GroupContent.Name) || StringUtils.EqualsIgnoreCase(name, StlContents.Group.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.GroupContent) || StringUtils.EqualsIgnoreCase(name, "group")) { listInfo.GroupContent = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); if (string.IsNullOrEmpty(listInfo.GroupContent)) @@ -260,7 +263,7 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte listInfo.GroupContent = "__Empty__"; } } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.GroupContentNot.Name) || StringUtils.EqualsIgnoreCase(name, StlContents.GroupNot.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.GroupContentNot) || StringUtils.EqualsIgnoreCase(name, "groupNot")) { listInfo.GroupContentNot = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); if (string.IsNullOrEmpty(listInfo.GroupContentNot)) @@ -268,11 +271,11 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte listInfo.GroupContentNot = "__Empty__"; } } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.Tags.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.Tags)) { listInfo.Tags = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.Columns.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.Columns)) { listInfo.Columns = TranslateUtils.ToInt(value); listInfo.Layout = ELayout.Table; @@ -281,13 +284,13 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte listInfo.Direction = RepeatDirection.Horizontal; } } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.Direction.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.Direction)) { listInfo.Layout = ELayout.Table; - listInfo.Direction = Converter.ToRepeatDirection(value); + listInfo.Direction = FxUtils.ToRepeatDirection(value); isSetDirection = true; } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.Height.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.Height)) { try { @@ -298,7 +301,7 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte // ignored } } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.Width.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.Width)) { try { @@ -309,11 +312,11 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte // ignored } } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.Align.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.Align)) { listInfo.Align = value; } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.ItemHeight.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.ItemHeight)) { try { @@ -324,7 +327,7 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte // ignored } } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.ItemWidth.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.ItemWidth)) { try { @@ -335,47 +338,43 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte // ignored } } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.ItemAlign.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.ItemAlign)) { listInfo.ItemAlign = value; } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.ItemVerticalAlign.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.ItemVerticalAlign)) { listInfo.ItemVerticalAlign = value; } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.ItemClass.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.ItemClass)) { listInfo.ItemClass = value; } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.IsImage.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.IsImage)) { listInfo.IsImage = TranslateUtils.ToBool(value); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.IsVideo.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.IsVideo)) { listInfo.IsVideo = TranslateUtils.ToBool(value); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.IsFile.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.IsFile)) { listInfo.IsFile = TranslateUtils.ToBool(value); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.IsNoDup.Name)) - { - listInfo.IsNoDup = TranslateUtils.ToBool(value); - } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.IsRelatedContents.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.IsRelatedContents)) { listInfo.IsRelatedContents = TranslateUtils.ToBool(value); } - else if (StringUtils.EqualsIgnoreCase(name, StlContents.Layout.Name)) + else if (StringUtils.EqualsIgnoreCase(name, StlListBase.Layout)) { listInfo.Layout = ELayoutUtils.GetEnumType(value); } - else if (contextType == EContextType.SqlContent && StringUtils.EqualsIgnoreCase(name, StlSqlContents.ConnectionString.Name)) + else if (contextType == EContextType.SqlContent && StringUtils.EqualsIgnoreCase(name, StlSqlContents.ConnectionString)) { listInfo.ConnectionString = value; } - else if (contextType == EContextType.SqlContent && StringUtils.EqualsIgnoreCase(name, StlSqlContents.ConnectionStringName.Name)) + else if (contextType == EContextType.SqlContent && StringUtils.EqualsIgnoreCase(name, StlSqlContents.ConnectionStringName)) { listInfo.ConnectionString = WebConfigUtils.GetConnectionStringByName(value); if (string.IsNullOrEmpty(listInfo.ConnectionString)) @@ -383,6 +382,10 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte listInfo.ConnectionString = WebConfigUtils.ConnectionString; } } + else if (contextType == EContextType.SqlContent && StringUtils.EqualsIgnoreCase(name, StlSqlContents.QueryString)) + { + listInfo.QueryString = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } else { listInfo.Others.Set(name, value); @@ -405,9 +408,9 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte public string AlternatingItemTemplate { get; private set; } = string.Empty; - public LowerNameValueCollection SelectedItems { get; } = new LowerNameValueCollection(); + public NameValueCollection SelectedItems { get; } = TranslateUtils.NewIgnoreCaseNameValueCollection(); - public LowerNameValueCollection SelectedValues { get; } = new LowerNameValueCollection(); + public NameValueCollection SelectedValues { get; } = TranslateUtils.NewIgnoreCaseNameValueCollection(); public string SeparatorRepeatTemplate { get; private set; } = string.Empty; @@ -415,7 +418,7 @@ public static ListInfo GetListInfoByXmlNode(PageInfo pageInfo, ContextInfo conte public int TotalNum { get; private set; } - public int PageNum { get; set; } + public int PageNum { get; set; } = Constants.PageSize; public int MaxPage { get; private set; } @@ -520,8 +523,6 @@ public bool IsFile public bool IsFileExists { get; private set; } - public bool IsNoDup { get; set; } - public bool IsRelatedContents { get; set; } public ELayout Layout { get; set; } = ELayout.None; @@ -609,6 +610,6 @@ public bool IsColor public string Where { get; set; } = string.Empty; - public LowerNameValueCollection Others { get; set; } = new LowerNameValueCollection(); + public NameValueCollection Others { get; } = TranslateUtils.NewIgnoreCaseNameValueCollection(); } } diff --git a/SiteServer.CMS/StlParser/Model/PageInfo.cs b/net452/SiteServer.CMS/StlParser/Model/PageInfo.cs similarity index 91% rename from SiteServer.CMS/StlParser/Model/PageInfo.cs rename to net452/SiteServer.CMS/StlParser/Model/PageInfo.cs index aa87bf37c..309c4d1ae 100644 --- a/SiteServer.CMS/StlParser/Model/PageInfo.cs +++ b/net452/SiteServer.CMS/StlParser/Model/PageInfo.cs @@ -1,10 +1,12 @@ using System.Collections; using System.Collections.Generic; using SiteServer.Utils; -using SiteServer.CMS.Model; using SiteServer.Plugin; using System.Text; -using SiteServer.CMS.Api; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; namespace SiteServer.CMS.StlParser.Model { @@ -24,7 +26,7 @@ public class PageInfo public TemplateInfo TemplateInfo { get; } - public IUserInfo UserInfo { get; set; } + public UserInfo UserInfo { get; set; } public int SiteId { get; private set; } @@ -50,14 +52,8 @@ public class PageInfo public int UniqueId { - get - { - return _uniqueId++; - } - set - { - _uniqueId = value; - } + get => _uniqueId++; + set => _uniqueId = value; } public PageInfo Clone() @@ -78,7 +74,7 @@ public PageInfo(int pageChannelId, int pageContentId, SiteInfo siteInfo, Templat SiteInfo = siteInfo; UserInfo = null; _uniqueId = 1; - ApiUrl = ApiManager.OuterApiUrl; + ApiUrl = ApiManager.ApiUrl; ChannelItems = new Stack(5); ContentItems = new Stack(5); @@ -209,7 +205,6 @@ public class Const public const string JsAcAudioJs = "Js_Ac_AudioJs"; //audio.js public const string JsAcVideoJs = "Js_Ac_VideoJs"; //video.js - public const string JsAdStlCountHits = "Js_Ad_StlCountHits"; //统计访问量 public const string JsAeStlZoom = "Js_Ae_StlZoom"; //文字缩放 public const string JsAfStlPrinter = "Js_Af_StlPrinter"; //打印 public const string JsAgStlTreeNotAjax = "Js_Ag_StlTreeNotAjax"; //树状导航 @@ -229,13 +224,16 @@ private string GetJsCode(string pageJsName) if (pageJsName == Const.Jquery) { - retval = - $""; + if (SiteInfo.IsCreateWithJQuery) + { + retval = + $@""; + } } else if (pageJsName == Const.Vue) { retval = - $""; + $@""; } else if (pageJsName == Const.JsCookie) { @@ -250,17 +248,17 @@ private string GetJsCode(string pageJsName) else if (pageJsName == Const.BAjaxUpload) { retval = - $""; + $@""; } else if (pageJsName == Const.BQueryString) { retval = - $""; + $@""; } else if (pageJsName == Const.BjQueryForm) { retval = - $""; + $@""; } else if (pageJsName == Const.BShowLoading) { @@ -346,7 +344,7 @@ function stlOpenWindow(pageUrl,width,height) { retval = $@" - + "; } else if (pageJsName == Const.JsInnerCalendar) @@ -373,7 +371,7 @@ public string HeadCodesHtml var builder = new StringBuilder(); //builder.Append( - //$@"").AppendLine(); + //$@"").AppendLine(); foreach (var key in HeadCodes.Keys) { diff --git a/SiteServer.CMS/StlParser/Model/ParsedDataList.cs b/net452/SiteServer.CMS/StlParser/Model/ParsedDataList.cs similarity index 95% rename from SiteServer.CMS/StlParser/Model/ParsedDataList.cs rename to net452/SiteServer.CMS/StlParser/Model/ParsedDataList.cs index 280679899..6e8061564 100644 --- a/SiteServer.CMS/StlParser/Model/ParsedDataList.cs +++ b/net452/SiteServer.CMS/StlParser/Model/ParsedDataList.cs @@ -1,8 +1,8 @@ using System.Collections.Specialized; using System.Drawing; using System.Web.UI.WebControls; +using SiteServer.CMS.Fx; using SiteServer.Utils; -using SiteServer.CMS.Core; namespace SiteServer.CMS.StlParser.Model { @@ -283,7 +283,7 @@ public void AddAttribute(string attributeName, string attributeValue) } else if (attributeName.Equals("borderwidth") || attributeName.Equals("border")) { - BorderWidth = TranslateUtils.ToUnit(attributeValue); + BorderWidth = FxUtils.ToUnit(attributeValue); } else if (attributeName.Equals("cellpadding")) { @@ -307,11 +307,11 @@ public void AddAttribute(string attributeName, string attributeValue) } else if (attributeName.Equals("gridlines")) { - GridLines = Converter.ToGridLines(attributeValue); + GridLines = FxUtils.ToGridLines(attributeValue); } else if (attributeName.Equals("horizontalalign")) { - HorizontalAlign = Converter.ToHorizontalAlign(attributeValue); + HorizontalAlign = FxUtils.ToHorizontalAlign(attributeValue); } else if (attributeName.Equals("repeatcolumns") || attributeName.Equals("columns")) { @@ -319,11 +319,11 @@ public void AddAttribute(string attributeName, string attributeValue) } else if (attributeName.Equals("repeatdirection") || attributeName.Equals("direction")) { - RepeatDirection = Converter.ToRepeatDirection(attributeValue); + RepeatDirection = FxUtils.ToRepeatDirection(attributeValue); } else if (attributeName.Equals("repeatlayout")) { - RepeatLayout = Converter.ToRepeatLayout(attributeValue); + RepeatLayout = FxUtils.ToRepeatLayout(attributeValue); } else if (attributeName.Equals("tooltip")) { diff --git a/SiteServer.CMS/StlParser/Model/StlAll.cs b/net452/SiteServer.CMS/StlParser/Model/StlAll.cs similarity index 99% rename from SiteServer.CMS/StlParser/Model/StlAll.cs rename to net452/SiteServer.CMS/StlParser/Model/StlAll.cs index 406b2644d..a3a92a209 100644 --- a/SiteServer.CMS/StlParser/Model/StlAll.cs +++ b/net452/SiteServer.CMS/StlParser/Model/StlAll.cs @@ -28,10 +28,6 @@ public static class StlAll StlChannels.ElementName, typeof(StlChannels) }, - { - StlCode.ElementName, - typeof(StlCode) - }, { StlContainer.ElementName, typeof(StlContainer) @@ -64,6 +60,10 @@ public static class StlAll StlFlash.ElementName, typeof(StlFlash) }, + { + StlFocusViewer.ElementName, + typeof(StlFocusViewer) + }, { StlIf.ElementName, typeof(StlIf) @@ -132,10 +132,6 @@ public static class StlAll StlQueryString.ElementName, typeof(StlQueryString) }, - { - StlRss.ElementName, - typeof(StlRss) - }, { StlSearch.ElementName, typeof(StlSearch) diff --git a/net452/SiteServer.CMS/StlParser/Model/StlAttributeAttribute.cs b/net452/SiteServer.CMS/StlParser/Model/StlAttributeAttribute.cs new file mode 100644 index 000000000..500bd0530 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/Model/StlAttributeAttribute.cs @@ -0,0 +1,10 @@ +using System; + +namespace SiteServer.CMS.StlParser.Model +{ + [AttributeUsage(AttributeTargets.Field)] + public class StlAttributeAttribute : Attribute + { + public string Title { get; set; } + } +} diff --git a/net452/SiteServer.CMS/StlParser/Model/StlElementAttribute.cs b/net452/SiteServer.CMS/StlParser/Model/StlElementAttribute.cs new file mode 100644 index 000000000..f693500a0 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/Model/StlElementAttribute.cs @@ -0,0 +1,11 @@ +using System; + +namespace SiteServer.CMS.StlParser.Model +{ + [AttributeUsage(AttributeTargets.Class)] + public class StlElementAttribute : Attribute + { + public string Title { get; set; } + public string Description { get; set; } + } +} diff --git a/net452/SiteServer.CMS/StlParser/Model/StlElementInfo.cs b/net452/SiteServer.CMS/StlParser/Model/StlElementInfo.cs new file mode 100644 index 000000000..fce5c1299 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/Model/StlElementInfo.cs @@ -0,0 +1,30 @@ +using System.Collections.Specialized; +using SiteServer.Utils; + +namespace SiteServer.CMS.StlParser.Model +{ + public class StlElementInfo + { + public StlElementInfo(string name, NameValueCollection attributes, string outerHtml, string innerHtml) + { + Name = name; + Attributes = attributes; + OuterHtml = outerHtml; + InnerHtml = innerHtml; + + IsDynamic = TranslateUtils.ToBool(Attributes["isDynamic"]); + } + + public bool IsDynamic { get; } + + // name is always lowerCase + public string Name { get; } + + // attributesIgnoreCase is always not null + public NameValueCollection Attributes { get; } + + public string OuterHtml { get; } + + public string InnerHtml { get; } + } +} diff --git a/net452/SiteServer.CMS/StlParser/Model/StlListBase.cs b/net452/SiteServer.CMS/StlParser/Model/StlListBase.cs new file mode 100644 index 000000000..89a31bd7b --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/Model/StlListBase.cs @@ -0,0 +1,107 @@ +namespace SiteServer.CMS.StlParser.Model +{ + public class StlListBase + { + [StlAttribute(Title = "栏目索引")] + public const string ChannelIndex = nameof(ChannelIndex); + + [StlAttribute(Title = "栏目名称")] + public const string ChannelName = nameof(ChannelName); + + [StlAttribute(Title = "上级栏目")] + public const string Parent = nameof(Parent); + + [StlAttribute(Title = "上级栏目的级别")] + public const string UpLevel = nameof(UpLevel); + + [StlAttribute(Title = "从首页向下的栏目级别")] + public const string TopLevel = nameof(TopLevel); + + [StlAttribute(Title = "范围")] + public const string Scope = nameof(Scope); + + [StlAttribute(Title = "指定栏目组")] + public const string GroupChannel = nameof(GroupChannel); + + [StlAttribute(Title = "排除栏目组")] + public const string GroupChannelNot = nameof(GroupChannelNot); + + [StlAttribute(Title = "指定内容组")] + public const string GroupContent = nameof(GroupContent); + + [StlAttribute(Title = "排除内容组")] + public const string GroupContentNot = nameof(GroupContentNot); + + [StlAttribute(Title = "指定标签")] + public const string Tags = nameof(Tags); + + [StlAttribute(Title = "仅显示置顶内容")] + public const string IsTop = nameof(IsTop); + + [StlAttribute(Title = "仅显示推荐内容")] + public const string IsRecommend = nameof(IsRecommend); + + [StlAttribute(Title = "仅显示热点内容")] + public const string IsHot = nameof(IsHot); + + [StlAttribute(Title = "仅显示醒目内容")] + public const string IsColor = nameof(IsColor); + + [StlAttribute(Title = "显示信息总数")] + public const string TotalNum = nameof(TotalNum); + + [StlAttribute(Title = "从第几条信息开始显示")] + public const string StartNum = nameof(StartNum); + + [StlAttribute(Title = "排序")] + public const string Order = nameof(Order); + + [StlAttribute(Title = "仅显示图片内容")] + public const string IsImage = nameof(IsImage); + + [StlAttribute(Title = "仅显示视频内容")] + public const string IsVideo = nameof(IsVideo); + + [StlAttribute(Title = "仅显示附件内容")] + public const string IsFile = nameof(IsFile); + + [StlAttribute(Title = "显示相关内容列表")] + public const string IsRelatedContents = nameof(IsRelatedContents); + + [StlAttribute(Title = "条件判断")] + public const string Where = nameof(Where); + + [StlAttribute(Title = "布局")] + public const string Layout = nameof(Layout); + + [StlAttribute(Title = "列数")] + public const string Columns = nameof(Columns); + + [StlAttribute(Title = "方向")] + public const string Direction = nameof(Direction); + + [StlAttribute(Title = "整体高度")] + public const string Height = nameof(Height); + + [StlAttribute(Title = "整体宽度")] + public const string Width = nameof(Width); + + [StlAttribute(Title = "整体对齐")] + public const string Align = nameof(Align); + + [StlAttribute(Title = "项高度")] + public const string ItemHeight = nameof(ItemHeight); + + [StlAttribute(Title = "项宽度")] + public const string ItemWidth = nameof(ItemWidth); + + [StlAttribute(Title = "项水平对齐")] + public const string ItemAlign = nameof(ItemAlign); + + [StlAttribute(Title = "项垂直对齐")] + public const string ItemVerticalAlign = nameof(ItemVerticalAlign); + + [StlAttribute(Title = "项Css类")] + public const string ItemClass = nameof(ItemClass); + } +} diff --git a/net452/SiteServer.CMS/StlParser/Parser.cs b/net452/SiteServer.CMS/StlParser/Parser.cs new file mode 100644 index 000000000..c9e2bb57e --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/Parser.cs @@ -0,0 +1,166 @@ +using System; +using System.Text; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Plugin; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.StlParser +{ + public static class Parser + { + public static void Parse(PageInfo pageInfo, ContextInfo contextInfo, StringBuilder contentBuilder, string filePath, bool isDynamic) + { + foreach (var service in PluginManager.Services) + { + try + { + service.OnBeforeStlParse(new ParseEventArgs + ( + pageInfo.SiteId, + pageInfo.PageChannelId, + pageInfo.PageContentId, + contextInfo.ContentInfo, + pageInfo.TemplateInfo.Type, + pageInfo.TemplateInfo.Id, + filePath, + pageInfo.HeadCodes, + pageInfo.BodyCodes, + pageInfo.FootCodes, + contentBuilder + )); + } + catch (Exception ex) + { + LogUtils.AddStlErrorLog(pageInfo, service.PluginId, nameof(service.OnBeforeStlParse), ex); + } + } + + if (contentBuilder.Length > 0) + { + StlParserManager.ParseTemplateContent(contentBuilder, pageInfo, contextInfo); + } + + foreach (var service in PluginManager.Services) + { + try + { + service.OnAfterStlParse(new ParseEventArgs(pageInfo.SiteId, pageInfo.PageChannelId, pageInfo.PageContentId, contextInfo.ContentInfo, pageInfo.TemplateInfo.Type, pageInfo.TemplateInfo.Id, filePath, pageInfo.HeadCodes, pageInfo.BodyCodes, pageInfo.FootCodes, contentBuilder)); + } + catch (Exception ex) + { + LogUtils.AddStlErrorLog(pageInfo, service.PluginId, nameof(service.OnAfterStlParse), ex); + } + } + + if (EFileSystemTypeUtils.IsHtml(PathUtils.GetExtension(filePath))) + { + if (isDynamic) + { + var pageUrl = FxUtils.AddProtocolToUrl(FxUtils.ParseNavigationUrl($"~/{PathUtils.GetPathDifference(WebConfigUtils.PhysicalApplicationPath, filePath)}")); + string templateString = $@" +"; + StringUtils.InsertAfter(new[] { "", "" }, contentBuilder, templateString); + } + + if (pageInfo.SiteInfo.IsCreateBrowserNoCache) + { + const string templateString = @" + +"; + StringUtils.InsertAfter(new[] { "", "" }, contentBuilder, templateString); + } + + if (pageInfo.SiteInfo.IsCreateIe8Compatible) + { + const string templateString = @" +"; + StringUtils.InsertAfter(new[] { "", "" }, contentBuilder, templateString); + } + + if (pageInfo.SiteInfo.IsCreateJsIgnoreError) + { + const string templateString = @" +"; + StringUtils.InsertAfter(new[] { "", "" }, contentBuilder, templateString); + } + + var isShowPageInfo = pageInfo.SiteInfo.IsCreateShowPageInfo; + + if (!pageInfo.IsLocal) + { + if (pageInfo.SiteInfo.IsCreateDoubleClick) + { + var fileTemplateId = 0; + if (pageInfo.TemplateInfo.Type == TemplateType.FileTemplate) + { + fileTemplateId = pageInfo.TemplateInfo.Id; + } + + var apiUrl = pageInfo.ApiUrl; + var ajaxUrl = ApiRouteActionsTrigger.GetUrl(apiUrl, pageInfo.SiteId, contextInfo.ChannelId, + contextInfo.ContentId, fileTemplateId, true); + if (!pageInfo.FootCodes.ContainsKey("CreateDoubleClick")) + { + pageInfo.FootCodes.Add("CreateDoubleClick", $@" +"); + } + } + } + else + { + isShowPageInfo = true; + } + + if (isShowPageInfo) + { + contentBuilder.Append($@" +"); + } + + var headCodesHtml = pageInfo.HeadCodesHtml; + if (!string.IsNullOrEmpty(headCodesHtml)) + { + if (contentBuilder.ToString().IndexOf("", StringComparison.Ordinal) != -1 || contentBuilder.ToString().IndexOf("", StringComparison.Ordinal) != -1) + { + StringUtils.InsertBefore(new[] { "", "" }, contentBuilder, headCodesHtml); + } + else + { + contentBuilder.Insert(0, headCodesHtml); + } + } + + var bodyCodesHtml = pageInfo.BodyCodesHtml; + if (!string.IsNullOrEmpty(bodyCodesHtml)) + { + if (contentBuilder.ToString().IndexOf("", index, StringComparison.Ordinal); + contentBuilder.Insert(index + 1, Constants.ReturnAndNewline + bodyCodesHtml + Constants.ReturnAndNewline); + } + else + { + contentBuilder.Insert(0, bodyCodesHtml); + } + } + + var footCodesHtml = pageInfo.FootCodesHtml; + if (!string.IsNullOrEmpty(footCodesHtml)) + { + contentBuilder.Append(footCodesHtml + Constants.ReturnAndNewline); + } + } + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/Parsers/StlElementParser.cs b/net452/SiteServer.CMS/StlParser/Parsers/StlElementParser.cs new file mode 100644 index 000000000..ba210af35 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/Parsers/StlElementParser.cs @@ -0,0 +1,174 @@ +using System; +using System.Collections.Generic; +using System.Text; +using SiteServer.CMS.Core; +using SiteServer.Utils; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.StlElement; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.Parsers +{ + /// + /// Stl元素解析器 + /// + public static class StlElementParser + { + /// + /// 将原始内容中的STL元素替换为实际内容 + /// + public static void ReplaceStlElements(StringBuilder parsedBuilder, PageInfo pageInfo, ContextInfo contextInfo) + { + var stlElements = StlParserUtility.GetStlElementList(parsedBuilder.ToString()); + foreach (var stlElement in stlElements) + { + try + { + var startIndex = parsedBuilder.ToString().IndexOf(stlElement, StringComparison.Ordinal); + if (startIndex == -1) continue; + + var parsedContent = ParseStlElement(stlElement, pageInfo, contextInfo); + parsedBuilder.Replace(stlElement, parsedContent, startIndex, stlElement.Length); + } + catch + { + // ignored + } + } + } + + public static readonly Dictionary> ElementsToParseDic = new Dictionary> + { + {StlA.ElementName.ToLower(), StlA.Parse}, + {StlAction.ElementName.ToLower(), StlAction.Parse}, + {StlAudio.ElementName.ToLower(), StlAudio.Parse}, + {StlChannel.ElementName.ToLower(), StlChannel.Parse}, + {StlChannels.ElementName.ToLower(), StlChannels.Parse}, + {StlContainer.ElementName.ToLower(), StlContainer.Parse}, + {StlContent.ElementName.ToLower(), StlContent.Parse}, + {StlContents.ElementName.ToLower(), StlContents.Parse}, + {StlCount.ElementName.ToLower(), StlCount.Parse}, + {StlDynamic.ElementName.ToLower(), StlDynamic.Parse}, + {StlEach.ElementName.ToLower(), StlEach.Parse}, + {StlFile.ElementName.ToLower(), StlFile.Parse}, + {StlFlash.ElementName.ToLower(), StlFlash.Parse}, + {StlFocusViewer.ElementName.ToLower(), StlFocusViewer.Parse}, + {StlIf.ElementName.ToLower(), StlIf.Parse}, + {StlImage.ElementName.ToLower(), StlImage.Parse}, + {StlInclude.ElementName.ToLower(), StlInclude.Parse}, + {StlLocation.ElementName.ToLower(), StlLocation.Parse}, + {StlMarquee.ElementName.ToLower(), StlMarquee.Parse}, + {StlNavigation.ElementName.ToLower(), StlNavigation.Parse}, + {StlPlayer.ElementName.ToLower(), StlPlayer.Parse}, + {StlPrinter.ElementName.ToLower(), StlPrinter.Parse}, + {StlSearch.ElementName.ToLower(), StlSearch.Parse}, + {StlSearch.ElementName2.ToLower(), StlSearch.Parse}, + {StlSelect.ElementName.ToLower(), StlSelect.Parse}, + {StlSite.ElementName.ToLower(), StlSite.Parse}, + {StlSites.ElementName.ToLower(), StlSites.Parse}, + {StlSqlContent.ElementName.ToLower(), StlSqlContent.Parse}, + {StlSqlContents.ElementName.ToLower(), StlSqlContents.Parse}, + {StlTabs.ElementName.ToLower(), StlTabs.Parse}, + {StlTags.ElementName.ToLower(), StlTags.Parse}, + {StlTree.ElementName.ToLower(), StlTree.Parse}, + {StlValue.ElementName.ToLower(), StlValue.Parse}, + {StlVideo.ElementName.ToLower(), StlVideo.Parse}, + {StlZoom.ElementName.ToLower(), StlZoom.Parse} + }; + + private static readonly Dictionary> ElementsToTranslateDic = new Dictionary> + { + {StlPageContents.ElementName.ToLower(), StlParserManager.StlEncrypt}, + {StlPageChannels.ElementName.ToLower(), StlParserManager.StlEncrypt}, + {StlPageSqlContents.ElementName.ToLower(), StlParserManager.StlEncrypt}, + //{StlPageInputContents.ElementName.ToLower(), StlParserManager.StlEncrypt}, + {StlPageItems.ElementName.ToLower(), StlParserManager.StlEncrypt} + }; + + private static string ParseStlElement(string stlElement, PageInfo pageInfo, ContextInfo contextInfo) + { + string parsedContent = null; + + var stlElementInfo = StlParserUtility.ParseStlElement(stlElement); + + if (stlElementInfo != null) + { + var elementName = stlElementInfo.Name; + + if (ElementsToTranslateDic.ContainsKey(elementName)) + { + if (ElementsToTranslateDic.TryGetValue(elementName, out var func)) + { + parsedContent = func(stlElement); + } + } + else if (ElementsToParseDic.ContainsKey(elementName)) + { + if (stlElementInfo.IsDynamic) + { + parsedContent = StlDynamic.ParseDynamicElement(stlElement, pageInfo, contextInfo); + } + else + { + try + { + if (ElementsToParseDic.TryGetValue(elementName, out var func)) + { + var contextInfoClone = contextInfo.Clone(stlElement, stlElementInfo.InnerHtml, stlElementInfo.Attributes); + + var obj = func(pageInfo, contextInfoClone); + + if (obj == null) + { + parsedContent = string.Empty; + } + else if (obj is string) + { + parsedContent = (string)obj; + } + else + { + parsedContent = TranslateUtils.JsonSerialize(obj); + } + } + } + catch (Exception ex) + { + parsedContent = LogUtils.AddStlErrorLog(pageInfo, elementName, stlElement, ex); + } + } + } + else + { + var parsers = PluginStlParserContentManager.GetParses(); + if (parsers.ContainsKey(elementName)) + { + if (stlElementInfo.IsDynamic) + { + parsedContent = StlDynamic.ParseDynamicElement(stlElement, pageInfo, contextInfo); + } + else + { + try + { + if (parsers.TryGetValue(elementName, out var func)) + { + var context = new ParseContextImpl(stlElementInfo.OuterHtml, stlElementInfo.InnerHtml, stlElementInfo.Attributes, pageInfo, contextInfo); + parsedContent = func(context); + } + } + catch (Exception ex) + { + parsedContent = LogUtils.AddStlErrorLog(pageInfo, elementName, stlElement, ex); + } + } + } + } + } + + return parsedContent ?? stlElement; + } + } +} diff --git a/SiteServer.CMS/StlParser/Parsers/StlEntityParser.cs b/net452/SiteServer.CMS/StlParser/Parsers/StlEntityParser.cs similarity index 98% rename from SiteServer.CMS/StlParser/Parsers/StlEntityParser.cs rename to net452/SiteServer.CMS/StlParser/Parsers/StlEntityParser.cs index 21f3a0462..c6ea28195 100644 --- a/SiteServer.CMS/StlParser/Parsers/StlEntityParser.cs +++ b/net452/SiteServer.CMS/StlParser/Parsers/StlEntityParser.cs @@ -46,7 +46,7 @@ public static void ReplaceStlEntities(StringBuilder parsedBuilder, PageInfo page // var entityType = EStlEntityTypeUtils.GetEntityType(stlEntity); // if (entityType != EStlEntityType.User) continue; // var resultContent = StlUserEntities.Parse(stlEntity, null); - // parsedBuilder.Replace(stlEntity, resultContent, startIndex, stlEntity.Length); + // parsedBuilder.Replace(stlEntity, resultContent, startIndex, stlEntity.DataLength); // } // return parsedBuilder.ToString(); //} @@ -75,7 +75,7 @@ internal static string ParseStlEntity(string stlEntity, PageInfo pageInfo, Conte } else if (entityType == EStlEntityType.Request) { - parsedContent = StlRequestEntities.Parse(stlEntity, pageInfo, contextInfo); + parsedContent = StlRequestEntities.Parse(stlEntity, pageInfo); } else if (entityType == EStlEntityType.Navigation) { diff --git a/SiteServer.CMS/StlParser/Parsers/StlPageElementParser.cs b/net452/SiteServer.CMS/StlParser/Parsers/StlPageElementParser.cs similarity index 92% rename from SiteServer.CMS/StlParser/Parsers/StlPageElementParser.cs rename to net452/SiteServer.CMS/StlParser/Parsers/StlPageElementParser.cs index b8740e11b..01a15d052 100644 --- a/SiteServer.CMS/StlParser/Parsers/StlPageElementParser.cs +++ b/net452/SiteServer.CMS/StlParser/Parsers/StlPageElementParser.cs @@ -44,7 +44,7 @@ public static string ParseStlPageItems(string htmlInStlPageElement, PageInfo pag for (var i = 0; i < mc.Count; i++) { var stlEntity = mc[i].Value; - var pageHtml = StlPageItem.ParseEntity(stlEntity, pageInfo, channelId, contentId, currentPageIndex, pageCount, totalNum, isXmlContent, contextType); + var pageHtml = StlPageItem.ParseEntity(stlEntity, pageInfo, channelId, contentId, currentPageIndex, pageCount, totalNum, contextType); html = html.Replace(stlEntity, pageHtml); } @@ -52,7 +52,7 @@ public static string ParseStlPageItems(string htmlInStlPageElement, PageInfo pag for (var i = 0; i < mc.Count; i++) { var stlElement = mc[i].Value; - var pageHtml = StlPageItem.ParseElement(stlElement, pageInfo, channelId, contentId, currentPageIndex, pageCount, totalNum, isXmlContent, contextType); + var pageHtml = StlPageItem.ParseElement(stlElement, pageInfo, channelId, contentId, currentPageIndex, pageCount, totalNum, contextType); html = html.Replace(stlElement, pageHtml); } @@ -75,7 +75,7 @@ public static string ParseStlPageItemsInSearchPage(string htmlInStlPageElement, for (var i = 0; i < mc.Count; i++) { var stlElement = mc[i].Value; - var pageHtml = StlPageItem.ParseElementInSearchPage(stlElement, pageInfo, ajaxDivId, channelId, currentPageIndex, pageCount, totalNum); + var pageHtml = StlPageItem.ParseElementInSearchPage(stlElement, pageInfo, ajaxDivId, currentPageIndex, pageCount, totalNum); html = html.Replace(stlElement, pageHtml); } @@ -109,18 +109,18 @@ public static string ParseStlPageItemsInDynamicPage(string htmlInStlPageElement, //在内容页中对“翻页”(stl:pageItem)元素进行解析,此元素在生成页面时单独解析,不包含在ParseStlElement方法中。 public static string ParseStlPageItemInContentPage(string stlElement, PageInfo pageInfo, int channelId, int contentId, int currentPageIndex, int pageCount, int totalNum) { - return StlPageItem.ParseElement(stlElement, pageInfo, channelId, contentId, currentPageIndex, pageCount, totalNum, false, EContextType.Content); + return StlPageItem.ParseElement(stlElement, pageInfo, channelId, contentId, currentPageIndex, pageCount, totalNum, EContextType.Content); } //在栏目页中对“翻页”(stl:pageItem)元素进行解析,此元素在生成页面时单独解析,不包含在ParseStlElement方法中。 public static string ParseStlPageItemInChannelPage(string stlElement, PageInfo pageInfo, int channelId, int currentPageIndex, int pageCount, int totalNum) { - return StlPageItem.ParseElement(stlElement, pageInfo, channelId, 0, currentPageIndex, pageCount, totalNum, false, EContextType.Channel); + return StlPageItem.ParseElement(stlElement, pageInfo, channelId, 0, currentPageIndex, pageCount, totalNum, EContextType.Channel); } - public static string ParseStlPageItemInSearchPage(string stlElement, PageInfo pageInfo, string ajaxDivId, int channelId, int currentPageIndex, int pageCount, int totalNum) + public static string ParseStlPageItemInSearchPage(string stlElement, PageInfo pageInfo, string ajaxDivId, int currentPageIndex, int pageCount, int totalNum) { - return StlPageItem.ParseElementInSearchPage(stlElement, pageInfo, ajaxDivId, channelId, currentPageIndex, pageCount, totalNum); + return StlPageItem.ParseElementInSearchPage(stlElement, pageInfo, ajaxDivId, currentPageIndex, pageCount, totalNum); } public static string ParseStlPageItemInDynamicPage(string stlElement, PageInfo pageInfo, string pageUrl, int channelId, int currentPageIndex, int pageCount, int totalNum, bool isPageRefresh, string ajaxDivId) diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlA.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlA.cs new file mode 100644 index 000000000..c9f293237 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlA.cs @@ -0,0 +1,258 @@ +using System.Collections.Generic; +using System.Text; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Parsers; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "获取链接")] + public static class StlA + { + public const string ElementName = "stl:a"; + + [StlAttribute(Title = "栏目索引")] + private const string ChannelIndex = nameof(ChannelIndex); + + [StlAttribute(Title = "栏目名称")] + private const string ChannelName = nameof(ChannelName); + + [StlAttribute(Title = "显示父栏目")] + private const string Parent = nameof(Parent); + + [StlAttribute(Title = "上级栏目的级别")] + private const string UpLevel = nameof(UpLevel); + + [StlAttribute(Title = "从首页向下的栏目级别")] + private const string TopLevel = nameof(TopLevel); + + [StlAttribute(Title = "所处上下文")] + private const string Context = nameof(Context); + + [StlAttribute(Title = "链接地址")] + private const string Href = nameof(Href); + + [StlAttribute(Title = "链接域名")] + private const string Host = nameof(Host); + + [StlAttribute(Title = "链接参数")] + private const string QueryString = nameof(QueryString); + + public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var attributes = new Dictionary(); + var channelIndex = string.Empty; + var channelName = string.Empty; + var upLevel = 0; + var topLevel = -1; + const bool removeTarget = false; + var href = string.Empty; + var queryString = string.Empty; + var host = string.Empty; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + if (StringUtils.EqualsIgnoreCase(name, ChannelIndex)) + { + channelIndex = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + if (!string.IsNullOrEmpty(channelIndex)) + { + contextInfo.ContextType = EContextType.Channel; + } + } + else if (StringUtils.EqualsIgnoreCase(name, ChannelName)) + { + channelName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + if (!string.IsNullOrEmpty(channelName)) + { + contextInfo.ContextType = EContextType.Channel; + } + } + else if (StringUtils.EqualsIgnoreCase(name, Parent)) + { + if (TranslateUtils.ToBool(value)) + { + upLevel = 1; + contextInfo.ContextType = EContextType.Channel; + } + } + else if (StringUtils.EqualsIgnoreCase(name, UpLevel)) + { + upLevel = TranslateUtils.ToInt(value); + if (upLevel > 0) + { + contextInfo.ContextType = EContextType.Channel; + } + } + else if (StringUtils.EqualsIgnoreCase(name, TopLevel)) + { + topLevel = TranslateUtils.ToInt(value); + if (topLevel >= 0) + { + contextInfo.ContextType = EContextType.Channel; + } + } + else if (StringUtils.EqualsIgnoreCase(name, Context)) + { + contextInfo.ContextType = EContextTypeUtils.GetEnumType(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Href)) + { + href = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, QueryString)) + { + queryString = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, Host)) + { + host = value; + } + else + { + attributes[name] = value; + } + } + + var parsedContent = ParseImpl(pageInfo, contextInfo, channelIndex, channelName, upLevel, topLevel, + removeTarget, href, queryString, host, attributes); + + return parsedContent; + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string channelIndex, + string channelName, int upLevel, int topLevel, bool removeTarget, string href, string queryString, + string host, Dictionary attributes) + { + string htmlId; + attributes.TryGetValue("id", out htmlId); + + if (!string.IsNullOrEmpty(htmlId) && !string.IsNullOrEmpty(contextInfo.ContainerClientId)) + { + htmlId = contextInfo.ContainerClientId + "_" + htmlId; + } + + if (!string.IsNullOrEmpty(htmlId)) + { + attributes["id"] = htmlId; + } + + var innerHtml = string.Empty; + + var url = string.Empty; + var onclick = string.Empty; + if (!string.IsNullOrEmpty(href)) + { + url = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, href, pageInfo.IsLocal); + + var innerBuilder = new StringBuilder(contextInfo.InnerHtml); + StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); + innerHtml = innerBuilder.ToString(); + } + else + { + if (contextInfo.ContextType == EContextType.Undefined) + { + contextInfo.ContextType = contextInfo.ContentId != 0 ? EContextType.Content : EContextType.Channel; + } + + if (contextInfo.ContextType == EContextType.Content) //获取内容Url + { + if (contextInfo.ContentInfo != null) + { + url = PageUtility.GetContentUrl(pageInfo.SiteInfo, contextInfo.ContentInfo, pageInfo.IsLocal); + } + else + { + var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + url = PageUtility.GetContentUrl(pageInfo.SiteInfo, nodeInfo, contextInfo.ContentId, + pageInfo.IsLocal); + } + + if (string.IsNullOrEmpty(contextInfo.InnerHtml)) + { + var title = contextInfo.ContentInfo?.Title; + title = ContentUtility.FormatTitle( + contextInfo.ContentInfo?.Get("ContentAttribute.TitleFormatString"), title); + + if (pageInfo.SiteInfo.IsContentTitleBreakLine) + { + title = title.Replace(" ", string.Empty); + } + + innerHtml = title; + } + else + { + var innerBuilder = new StringBuilder(contextInfo.InnerHtml); + StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); + innerHtml = innerBuilder.ToString(); + } + } + else if (contextInfo.ContextType == EContextType.Channel) //获取栏目Url + { + contextInfo.ChannelId = + StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); + contextInfo.ChannelId = + ChannelManager.GetChannelId(pageInfo.SiteId, + contextInfo.ChannelId, channelIndex, channelName); + var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + + url = PageUtility.GetChannelUrl(pageInfo.SiteInfo, channel, pageInfo.IsLocal); + if (string.IsNullOrWhiteSpace(contextInfo.InnerHtml)) + { + innerHtml = channel.ChannelName; + } + else + { + var innerBuilder = new StringBuilder(contextInfo.InnerHtml); + StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); + innerHtml = innerBuilder.ToString(); + } + } + } + + if (url.Equals(PageUtils.UnClickedUrl)) + { + removeTarget = true; + } + else + { + if (!string.IsNullOrEmpty(host)) + { + url = FxUtils.AddProtocolToUrl(url, host); + } + + if (!string.IsNullOrEmpty(queryString)) + { + url = PageUtils.AddQueryString(url, queryString); + } + } + + attributes["href"] = url; + + if (!string.IsNullOrEmpty(onclick)) + { + attributes["onclick"] = onclick; + } + + if (removeTarget) + { + attributes["target"] = string.Empty; + } + + // 如果是实体标签,则只返回url + if (contextInfo.IsStlEntity) + { + return url; + } + + return $@"{innerHtml}"; + } + } +} diff --git a/SiteServer.CMS/StlParser/StlElement/StlAction.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlAction.cs similarity index 80% rename from SiteServer.CMS/StlParser/StlElement/StlAction.cs rename to net452/SiteServer.CMS/StlParser/StlElement/StlAction.cs index 6c6c41687..b6c7d9037 100644 --- a/SiteServer.CMS/StlParser/StlElement/StlAction.cs +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlAction.cs @@ -1,36 +1,35 @@ using System; -using System.Collections.Generic; using System.Text; using System.Web.UI.HtmlControls; +using SiteServer.CMS.Fx; using SiteServer.Utils; using SiteServer.CMS.StlParser.Model; using SiteServer.CMS.StlParser.Utility; namespace SiteServer.CMS.StlParser.StlElement { - [StlClass(Usage = "执行动作", Description = "通过 stl:action 标签在模板中创建链接,点击链接后将执行相应的动作")] + [StlElement(Title = "执行动作", Description = "通过 stl:action 标签在模板中创建链接,点击链接后将执行相应的动作")] public class StlAction { private StlAction() { } public const string ElementName = "stl:action"; - private static readonly AttrEnum TypeTranslate = new AttrEnum("Translate", "繁体/简体转换"); - private static readonly AttrEnum TypeClose = new AttrEnum("Close", "关闭页面"); + //繁体/简体转换 + private const string TypeTranslate = "Translate"; + //关闭页面 + private const string TypeClose = "Close"; - private static readonly Attr Type = new Attr("type", "动作类型", AttrType.Enum, new List - { - TypeTranslate, - TypeClose - }); + [StlAttribute(Title = "动作类型")] + private const string Type = nameof(Type); public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) { var type = string.Empty; - foreach (var name in contextInfo.Attributes.Keys) + foreach (var name in contextInfo.Attributes.AllKeys) { var value = contextInfo.Attributes[name]; - if (StringUtils.EqualsIgnoreCase(name, Type.Name)) + if (StringUtils.EqualsIgnoreCase(name, Type)) { type = value; } @@ -43,22 +42,22 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, stri { var stlAnchor = new HtmlAnchor(); - foreach (var attributeName in contextInfo.Attributes.Keys) + foreach (var attributeName in contextInfo.Attributes.AllKeys) { stlAnchor.Attributes.Add(attributeName, contextInfo.Attributes[attributeName]); } - var url = PageUtils.UnclickedUrl; + var url = PageUtils.UnClickedUrl; var onclick = string.Empty; - var innerBuilder = new StringBuilder(contextInfo.InnerXml); + var innerBuilder = new StringBuilder(contextInfo.InnerHtml); StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); stlAnchor.InnerHtml = innerBuilder.ToString(); //计算动作开始 if (!string.IsNullOrEmpty(type)) { - if (StringUtils.EqualsIgnoreCase(type, TypeTranslate.Name)) + if (StringUtils.EqualsIgnoreCase(type, TypeTranslate)) { pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.JsAhTranslate); @@ -83,7 +82,7 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, stri stlAnchor.ID = "translateLink"; } - pageInfo.FootCodes[TypeTranslate.Name] = $@" + pageInfo.FootCodes[TypeTranslate] = $@" "; } - else if (StringUtils.EqualsIgnoreCase(type, TypeClose.Name)) + else if (StringUtils.EqualsIgnoreCase(type, TypeClose)) { url = "javascript:window.close()"; } diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlAudio.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlAudio.cs new file mode 100644 index 000000000..5d0d6c5f7 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlAudio.cs @@ -0,0 +1,139 @@ +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Stl; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Fx; +using SiteServer.CMS.StlParser.Model; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "播放音频", Description = "通过 stl:audio 标签在模板中显示并播放音频文件")] + public class StlAudio + { + private StlAudio() { } + public const string ElementName = "stl:audio"; + + [StlAttribute(Title = "指定存储音频地址的内容字段,默认为VideoUrl")] + private const string Type = nameof(Type); + + [StlAttribute(Title = "音频地址,优先级高于type属性")] + private const string PlayUrl = nameof(PlayUrl); + + [StlAttribute(Title = "是否自动播放")] + private const string IsAutoPlay = nameof(IsAutoPlay); + + [StlAttribute(Title = "是否预载入")] + private const string IsPreload = nameof(IsPreload); + + [StlAttribute(Title = "是否循环播放")] + private const string IsLoop = nameof(IsLoop); + + public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var type = ContentAttribute.VideoUrl; + var playUrl = string.Empty; + var isAutoPlay = false; + var isPreLoad = true; + var isLoop = false; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value; + } + else if (StringUtils.EqualsIgnoreCase(name, PlayUrl) || StringUtils.EqualsIgnoreCase(name, "src")) + { + playUrl = value; + } + else if (StringUtils.EqualsIgnoreCase(name, IsAutoPlay) || StringUtils.EqualsIgnoreCase(name, "play")) + { + isAutoPlay = TranslateUtils.ToBool(value, false); + } + else if (StringUtils.EqualsIgnoreCase(name, IsPreload)) + { + isPreLoad = TranslateUtils.ToBool(value, true); + } + else if (StringUtils.EqualsIgnoreCase(name, IsLoop) || StringUtils.EqualsIgnoreCase(name, "loop")) + { + isLoop = TranslateUtils.ToBool(value, false); + } + } + + return ParseImpl(pageInfo, contextInfo, type, playUrl, isAutoPlay, isPreLoad, isLoop); + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string type, string playUrl, bool isAutoPlay, bool isPreLoad, bool isLoop) + { + var contentId = contextInfo.ContentId; + + if (string.IsNullOrEmpty(playUrl)) + { + if (contentId != 0)//获取内容视频 + { + if (contextInfo.ContentInfo == null) + { + //playUrl = DataProvider.ContentRepository.GetValueById(pageInfo.SiteInfo.AuxiliaryTableForContent, contentId, type); + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteInfo.Id, pageInfo.SiteInfo.Id); + playUrl = StlContentCache.GetValue(channelInfo, contentId, type); + if (string.IsNullOrEmpty(playUrl)) + { + if (!StringUtils.EqualsIgnoreCase(type, ContentAttribute.VideoUrl)) + { + //playUrl = DataProvider.ContentRepository.GetValueById(pageInfo.SiteInfo.AuxiliaryTableForContent, contentId, ContentAttribute.VideoUrl); + playUrl = StlContentCache.GetValue(channelInfo, contentId, ContentAttribute.VideoUrl); + } + } + if (string.IsNullOrEmpty(playUrl)) + { + if (!StringUtils.EqualsIgnoreCase(type, ContentAttribute.FileUrl)) + { + //playUrl = DataProvider.ContentRepository.GetValueById(pageInfo.SiteInfo.AuxiliaryTableForContent, contentId, ContentAttribute.FileUrl); + playUrl = StlContentCache.GetValue(channelInfo, contentId, ContentAttribute.FileUrl); + } + } + } + else + { + playUrl = contextInfo.ContentInfo.Get(type); + if (string.IsNullOrEmpty(playUrl)) + { + playUrl = contextInfo.ContentInfo.Get(ContentAttribute.VideoUrl); + } + if (string.IsNullOrEmpty(playUrl)) + { + playUrl = contextInfo.ContentInfo.Get(ContentAttribute.FileUrl); + } + } + } + } + + if (string.IsNullOrEmpty(playUrl)) return string.Empty; + + playUrl = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, playUrl, pageInfo.IsLocal); + + // 如果是实体标签,则只返回数字 + if (contextInfo.IsStlEntity) + { + return playUrl; + } + else + { + pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.Jquery); + pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.JsAcMediaElement); + + return $@" + +"; + } + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlChannel.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlChannel.cs new file mode 100644 index 000000000..75554a27d --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlChannel.cs @@ -0,0 +1,456 @@ +using System.Text; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Caches.Stl; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Parsers; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Plugin; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "获取栏目值", Description = "通过 stl:channel 标签在模板中显示指定栏目的属性值")] + public class StlChannel + { + private StlChannel() { } + public const string ElementName = "stl:channel"; + + [StlAttribute(Title = "栏目索引")] + private const string ChannelIndex = nameof(ChannelIndex); + + [StlAttribute(Title = "栏目名称")] + private const string ChannelName = nameof(ChannelName); + + [StlAttribute(Title = "显示父栏目属性")] + private const string Parent = nameof(Parent); + + [StlAttribute(Title = "上级栏目的级别")] + private const string UpLevel = nameof(UpLevel); + + [StlAttribute(Title = "从首页向下的栏目级别")] + private const string TopLevel = nameof(TopLevel); + + [StlAttribute(Title = "显示的类型")] + private const string Type = nameof(Type); + + [StlAttribute(Title = "显示在信息前的文字")] + private const string LeftText = nameof(LeftText); + + [StlAttribute(Title = "显示在信息后的文字")] + private const string RightText = nameof(RightText); + + [StlAttribute(Title = "显示的格式")] + private const string FormatString = nameof(FormatString); + + [StlAttribute(Title = "显示多项时的分割字符串")] + private const string Separator = nameof(Separator); + + [StlAttribute(Title = "字符开始位置")] + private const string StartIndex = nameof(StartIndex); + + [StlAttribute(Title = "指定字符长度")] + private const string Length = nameof(Length); + + [StlAttribute(Title = "显示字符的数目")] + private const string WordNum = nameof(WordNum); + + [StlAttribute(Title = "文字超出部分显示的文字")] + private const string Ellipsis = nameof(Ellipsis); + + [StlAttribute(Title = "需要替换的文字,可以是正则表达式")] + private const string Replace = nameof(Replace); + + [StlAttribute(Title = "替换replace的文字信息")] + private const string To = nameof(To); + + [StlAttribute(Title = "是否清除HTML标签")] + private const string IsClearTags = nameof(IsClearTags); + + [StlAttribute(Title = "是否将回车替换为HTML换行标签")] + private const string IsReturnToBr = nameof(IsReturnToBr); + + [StlAttribute(Title = "是否转换为小写")] + private const string IsLower = nameof(IsLower); + + [StlAttribute(Title = "是否转换为大写")] + private const string IsUpper = nameof(IsUpper); + + public static object Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var leftText = string.Empty; + var rightText = string.Empty; + var channelIndex = string.Empty; + var channelName = string.Empty; + var upLevel = 0; + var topLevel = -1; + var type = string.Empty; + var formatString = string.Empty; + string separator = null; + var startIndex = 0; + var length = 0; + var wordNum = 0; + var ellipsis = Constants.Ellipsis; + var replace = string.Empty; + var to = string.Empty; + var isClearTags = false; + var isReturnToBr = false; + var isLower = false; + var isUpper = false; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, ChannelIndex)) + { + channelIndex = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, ChannelName)) + { + channelName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, Parent)) + { + if (TranslateUtils.ToBool(value)) + { + upLevel = 1; + } + } + else if (StringUtils.EqualsIgnoreCase(name, UpLevel)) + { + upLevel = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, TopLevel)) + { + topLevel = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value; + } + else if (StringUtils.EqualsIgnoreCase(name, LeftText)) + { + leftText = value; + } + else if (StringUtils.EqualsIgnoreCase(name, RightText)) + { + rightText = value; + } + else if (StringUtils.EqualsIgnoreCase(name, FormatString)) + { + formatString = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Separator)) + { + separator = value; + } + else if (StringUtils.EqualsIgnoreCase(name, StartIndex)) + { + startIndex = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Length)) + { + length = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, WordNum)) + { + wordNum = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Ellipsis)) + { + ellipsis = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Replace)) + { + replace = value; + } + else if (StringUtils.EqualsIgnoreCase(name, To)) + { + to = value; + } + else if (StringUtils.EqualsIgnoreCase(name, IsClearTags)) + { + isClearTags = TranslateUtils.ToBool(value, false); + } + else if (StringUtils.EqualsIgnoreCase(name, IsReturnToBr)) + { + isReturnToBr = TranslateUtils.ToBool(value, false); + } + else if (StringUtils.EqualsIgnoreCase(name, IsLower)) + { + isLower = TranslateUtils.ToBool(value, true); + } + else if (StringUtils.EqualsIgnoreCase(name, IsUpper)) + { + isUpper = TranslateUtils.ToBool(value, true); + } + } + + var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); + + channelId = ChannelManager.GetChannelId(pageInfo.SiteId, channelId, channelIndex, channelName); + var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); + + if (contextInfo.IsStlEntity && string.IsNullOrEmpty(type)) + { + return channel; + } + + var parsedContent = ParseImpl(pageInfo, contextInfo, leftText, rightText, type, formatString, separator, startIndex, length, wordNum, ellipsis, replace, to, isClearTags, isReturnToBr, isLower, isUpper, channel, channelId); + + var innerBuilder = new StringBuilder(parsedContent); + StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); + parsedContent = innerBuilder.ToString(); + + if (!StringUtils.EqualsIgnoreCase(type, ChannelAttribute.PageContent)) + { + parsedContent = parsedContent.Replace(ContentUtility.PagePlaceHolder, string.Empty); + } + + return parsedContent; + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string leftText, string rightText, string type, string formatString, string separator, int startIndex, int length, int wordNum, string ellipsis, string replace, string to, bool isClearTags, bool isReturnToBr, bool isLower, bool isUpper, ChannelInfo channel, int channelId) + { + if (string.IsNullOrEmpty(type)) + { + type = ChannelAttribute.Title; + } + type = type.ToLower(); + + var parsedContent = string.Empty; + + if (!string.IsNullOrEmpty(formatString)) + { + formatString = formatString.Trim(); + if (!formatString.StartsWith("{0")) + { + formatString = "{0:" + formatString; + } + if (!formatString.EndsWith("}")) + { + formatString = formatString + "}"; + } + } + var inputType = InputType.Text; + + if (type.Equals(ChannelAttribute.Id.ToLower())) + { + parsedContent = channelId.ToString(); + } + else if (type.Equals(ChannelAttribute.SiteId.ToLower())) + { + parsedContent = channel.SiteId.ToString(); + } + else if (type.Equals(ChannelAttribute.ContentModelPluginId.ToLower())) + { + parsedContent = channel.ContentModelPluginId; + } + else if (type.Equals(ChannelAttribute.ContentRelatedPluginIds.ToLower())) + { + parsedContent = channel.ContentRelatedPluginIds; + } + else if (type.Equals(ChannelAttribute.ParentId.ToLower())) + { + parsedContent = channel.ParentId.ToString(); + } + else if (type.Equals(ChannelAttribute.ParentsPath.ToLower())) + { + parsedContent = channel.ParentsPath; + } + else if (type.Equals(ChannelAttribute.ParentsCount.ToLower())) + { + parsedContent = channel.ParentsCount.ToString(); + } + else if (type.Equals(ChannelAttribute.ChildrenCount.ToLower())) + { + parsedContent = channel.ChildrenCount.ToString(); + } + else if (type.Equals(ChannelAttribute.LastNode.ToLower())) + { + parsedContent = channel.LastNode.ToString(); + } + else if (type.Equals(ChannelAttribute.ChannelIndex.ToLower()) || type.Equals(ChannelAttribute.IndexName.ToLower())) + { + parsedContent = channel.IndexName; + + if (!string.IsNullOrEmpty(replace)) + { + parsedContent = StringUtils.Replace(replace, parsedContent, to); + } + + if (!string.IsNullOrEmpty(parsedContent) && wordNum > 0) + { + parsedContent = StringUtils.MaxLengthText(parsedContent, wordNum, ellipsis); + } + } + else if (type.Equals(ChannelAttribute.GroupNameCollection.ToLower())) + { + parsedContent = channel.GroupNameCollection; + } + else if (type.Equals(ChannelAttribute.Taxis.ToLower())) + { + parsedContent = channel.Taxis.ToString(); + } + else if (type.Equals(ChannelAttribute.AddDate.ToLower())) + { + inputType = InputType.DateTime; + parsedContent = DateUtils.Format(channel.AddDate, formatString); + } + else if (type.Equals(ChannelAttribute.ImageUrl.ToLower())) + { + inputType = InputType.Image; + parsedContent = InputParserUtility.GetImageOrFlashHtml(pageInfo.SiteInfo, channel.ImageUrl, contextInfo.Attributes, contextInfo.IsStlEntity); // contextInfo.IsStlEntity = true 表示实体标签 + } + else if (type.Equals(ChannelAttribute.Content.ToLower())) + { + parsedContent = ContentUtility.TextEditorContentDecode(pageInfo.SiteInfo, channel.Content, pageInfo.IsLocal); + + if (isClearTags) + { + parsedContent = StringUtils.StripTags(parsedContent); + } + + if (!string.IsNullOrEmpty(replace)) + { + parsedContent = StringUtils.Replace(replace, parsedContent, to); + } + + if (!string.IsNullOrEmpty(parsedContent) && wordNum > 0) + { + parsedContent = StringUtils.MaxLengthText(parsedContent, wordNum, ellipsis); + } + } + else if (type.Equals(ChannelAttribute.FilePath.ToLower())) + { + parsedContent = channel.FilePath; + } + else if (type.Equals(ChannelAttribute.ChannelFilePathRule.ToLower())) + { + parsedContent = channel.ChannelFilePathRule; + } + else if (type.Equals(ChannelAttribute.ContentFilePathRule.ToLower())) + { + parsedContent = channel.ContentFilePathRule; + } + else if (type.Equals(ChannelAttribute.LinkUrl.ToLower())) + { + parsedContent = channel.LinkUrl; + } + else if (type.Equals(ChannelAttribute.LinkType.ToLower())) + { + parsedContent = channel.LinkType; + } + else if (type.Equals(ChannelAttribute.ChannelTemplateId.ToLower())) + { + parsedContent = channel.ChannelTemplateId.ToString(); + } + else if (type.Equals(ChannelAttribute.ContentTemplateId.ToLower())) + { + parsedContent = channel.ContentTemplateId.ToString(); + } + else if (type.Equals(ChannelAttribute.Keywords.ToLower())) + { + parsedContent = channel.Keywords; + } + else if (type.Equals(ChannelAttribute.Description.ToLower())) + { + parsedContent = channel.Description; + } + else if (type.Equals(ChannelAttribute.ExtendValues.ToLower())) + { + parsedContent = channel.ExtendValues; + } + else if (type.Equals(ChannelAttribute.Title.ToLower()) || type.Equals(ChannelAttribute.ChannelName.ToLower())) + { + parsedContent = channel.ChannelName; + + if (isClearTags) + { + parsedContent = StringUtils.StripTags(parsedContent); + } + + if (!string.IsNullOrEmpty(replace)) + { + parsedContent = StringUtils.Replace(replace, parsedContent, to); + } + + if (!string.IsNullOrEmpty(parsedContent) && wordNum > 0) + { + parsedContent = StringUtils.MaxLengthText(parsedContent, wordNum, ellipsis); + } + } + else if (type.Equals(ChannelAttribute.PageContent.ToLower())) + { + if (contextInfo.IsInnerElement || pageInfo.TemplateInfo.Type != TemplateType.ChannelTemplate) + { + parsedContent = ContentUtility.TextEditorContentDecode(pageInfo.SiteInfo, channel.Content, pageInfo.IsLocal); + + if (isClearTags) + { + parsedContent = StringUtils.StripTags(parsedContent); + } + + if (!string.IsNullOrEmpty(replace)) + { + parsedContent = StringUtils.Replace(replace, parsedContent, to); + } + + if (!string.IsNullOrEmpty(parsedContent) && wordNum > 0) + { + parsedContent = StringUtils.MaxLengthText(parsedContent, wordNum, ellipsis); + } + } + else + { + return contextInfo.OuterHtml; + } + } + else if (StringUtils.StartsWithIgnoreCase(type, ChannelAttribute.ItemIndex) && contextInfo.ItemContainer?.ChannelItem != null) + { + var itemIndex = StlParserUtility.ParseItemIndex(contextInfo.ItemContainer.ChannelItem.ItemIndex, type, contextInfo); + parsedContent = !string.IsNullOrEmpty(formatString) ? string.Format(formatString, itemIndex) : itemIndex.ToString(); + } + else if (type.Equals(ChannelAttribute.CountOfChannels.ToLower())) + { + parsedContent = channel.ChildrenCount.ToString(); + } + else if (type.Equals(ChannelAttribute.CountOfContents.ToLower())) + { + var count = ContentManager.GetCount(pageInfo.SiteInfo, channel, true); + parsedContent = count.ToString(); + } + else if (type.Equals(ChannelAttribute.CountOfImageContents.ToLower())) + { + var count = StlContentCache.GetCountCheckedImage(pageInfo.SiteId, channel); + parsedContent = count.ToString(); + } + else + { + var attributeName = type; + + var styleInfo = TableStyleManager.GetTableStyleInfo(DataProvider.Channel.TableName, attributeName, TableStyleManager.GetRelatedIdentities(channel)); + // 如果 styleInfo.TableStyleId <= 0,表示此字段已经被删除了,不需要再显示值了 ekun008 + if (styleInfo.Id > 0) + { + parsedContent = channel.Get(attributeName, styleInfo.DefaultValue); + if (!string.IsNullOrEmpty(parsedContent)) + { + parsedContent = InputParserUtility.GetContentByTableStyle(parsedContent, separator, pageInfo.SiteInfo, styleInfo, formatString, contextInfo.Attributes, contextInfo.InnerHtml, false, isLower, isUpper); + inputType = styleInfo.Type; + } + } + } + + if (string.IsNullOrEmpty(parsedContent)) return string.Empty; + + parsedContent = InputTypeUtils.ParseString(inputType, parsedContent, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); + return leftText + parsedContent + rightText; + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlChannels.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlChannels.cs new file mode 100644 index 000000000..b2c1a3993 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlChannels.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "栏目列表", Description = "通过 stl:channels 标签在模板中显示栏目列表")] + public class StlChannels : StlListBase + { + public const string ElementName = "stl:channels"; + + [StlAttribute(Title = "是否从所有栏目中选择")] + public const string IsTotal = nameof(IsTotal); + + [StlAttribute(Title = "是否显示所有级别的子栏目")] + public const string IsAllChildren = nameof(IsAllChildren); + + public static object Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var listInfo = ListInfo.GetListInfo(pageInfo, contextInfo, EContextType.Channel); + + var dataSource = GetDataSource(pageInfo, contextInfo, listInfo); + + if (contextInfo.IsStlEntity) + { + return ParseEntity(pageInfo, dataSource); + } + + return ParseElement(pageInfo, contextInfo, listInfo, dataSource); + } + + public static DataSet GetDataSource(PageInfo pageInfo, ContextInfo contextInfo, ListInfo listInfo) + { + var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, listInfo.UpLevel, listInfo.TopLevel); + + channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, listInfo.ChannelIndex, listInfo.ChannelName); + + var isTotal = TranslateUtils.ToBool(listInfo.Others.Get(IsTotal)); + + if (TranslateUtils.ToBool(listInfo.Others.Get(IsAllChildren))) + { + listInfo.Scope = EScopeType.Descendant; + } + + return StlDataUtility.GetChannelsDataSource(pageInfo.SiteId, channelId, listInfo.GroupChannel, listInfo.GroupChannelNot, listInfo.IsImageExists, listInfo.IsImage, listInfo.StartNum, listInfo.TotalNum, listInfo.OrderByString, listInfo.Scope, isTotal, listInfo.Where); + } + + private static string ParseElement(PageInfo pageInfo, ContextInfo contextInfo, ListInfo listInfo, DataSet dataSource) + { + var parsedContent = string.Empty; + + if (listInfo.Layout == ELayout.None) + { + var rptContents = new Repeater(); + + if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) + { + rptContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); + } + if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) + { + rptContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); + } + if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) + { + rptContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); + } + if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) + { + rptContents.AlternatingItemTemplate = new RepeaterTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Channel, contextInfo); + } + + rptContents.ItemTemplate = new RepeaterTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, + listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, + pageInfo, EContextType.Channel, contextInfo); + + rptContents.DataSource = dataSource; + rptContents.DataBind(); + + if (rptContents.Items.Count > 0) + { + parsedContent = ControlUtils.GetControlRenderHtml(rptContents); + } + } + else + { + var pdlContents = new ParsedDataList(); + + //设置显示属性 + TemplateUtility.PutListInfoToMyDataList(pdlContents, listInfo); + + //设置列表模板 + pdlContents.ItemTemplate = new DataListTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Channel, contextInfo); + if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) + { + pdlContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); + } + if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) + { + pdlContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); + } + if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) + { + pdlContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); + } + if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) + { + pdlContents.AlternatingItemTemplate = new DataListTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Channel, contextInfo); + } + + pdlContents.DataSource = dataSource; + pdlContents.DataKeyField = ChannelAttribute.Id; + pdlContents.DataBind(); + + if (pdlContents.Items.Count > 0) + { + parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); + } + } + + return parsedContent; + } + + private static object ParseEntity(PageInfo pageInfo, DataSet dataSource) + { + var channelInfoList = new List>(); + var table = dataSource.Tables[0]; + foreach (DataRow row in table.Rows) + { + var channelId = Convert.ToInt32(row[nameof(ContentAttribute.Id)]); + + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); + if (channelInfo != null) + { + channelInfoList.Add(channelInfo.ToDictionary()); + } + } + + return channelInfoList; + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlContainer.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlContainer.cs new file mode 100644 index 000000000..6545125b9 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlContainer.cs @@ -0,0 +1,91 @@ +using System.Text; +using SiteServer.Utils; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Parsers; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "容器", Description = "通过 stl:container 标签在模板中定义容器,切换上下文")] + public class StlContainer + { + private StlContainer() { } + public const string ElementName = "stl:container"; + + [StlAttribute(Title = "栏目索引")] + private const string ChannelIndex = nameof(ChannelIndex); + + [StlAttribute(Title = "栏目名称")] + private const string ChannelName = nameof(ChannelName); + + [StlAttribute(Title = "父栏目")] + private const string Parent = nameof(Parent); + + [StlAttribute(Title = "上级栏目的级别")] + private const string UpLevel = nameof(UpLevel); + + [StlAttribute(Title = "从首页向下的栏目级别")] + private const string TopLevel = nameof(TopLevel); + + [StlAttribute(Title = "所处上下文")] + private const string Context = nameof(Context); + + public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + if (contextInfo.IsStlEntity || string.IsNullOrWhiteSpace(contextInfo.InnerHtml)) return string.Empty; + + var channelIndex = string.Empty; + var channelName = string.Empty; + var upLevel = 0; + var topLevel = -1; + var context = contextInfo.ContextType; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, ChannelIndex)) + { + channelIndex = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, ChannelName)) + { + channelName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, Parent)) + { + if (TranslateUtils.ToBool(value)) + { + upLevel = 1; + } + } + else if (StringUtils.EqualsIgnoreCase(name, UpLevel)) + { + upLevel = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, TopLevel)) + { + topLevel = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Context)) + { + context = EContextTypeUtils.GetEnumType(value); + } + } + + var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); + + channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, channelIndex, channelName); + + contextInfo.ContextType = context; + contextInfo.ChannelId = channelId; + + var innerHtml = RegexUtils.GetInnerContent(ElementName, contextInfo.OuterHtml); + + var builder = new StringBuilder(innerHtml); + StlParserManager.ParseInnerContent(builder, pageInfo, contextInfo); + + return builder.ToString(); + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlContent.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlContent.cs new file mode 100644 index 000000000..5c0df2e74 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlContent.cs @@ -0,0 +1,596 @@ +using System.Text; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Caches.Stl; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Plugin; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "获取内容值", Description = "通过 stl:content 标签在模板中显示指定内容的属性值")] + public class StlContent + { + private StlContent() { } + public const string ElementName = "stl:content"; + + [StlAttribute(Title = "显示的类型")] + private const string Type = nameof(Type); + + [StlAttribute(Title = "显示在信息前的文字")] + private const string LeftText = nameof(LeftText); + + [StlAttribute(Title = "显示在信息后的文字")] + private const string RightText = nameof(RightText); + + [StlAttribute(Title = "显示的格式")] + private const string FormatString = nameof(FormatString); + + [StlAttribute(Title = "显示第几项")] + private const string No = nameof(No); + + [StlAttribute(Title = "显示多项时的分割字符串")] + private const string Separator = nameof(Separator); + + [StlAttribute(Title = "字符开始位置")] + private const string StartIndex = nameof(StartIndex); + + [StlAttribute(Title = "指定字符长度")] + private const string Length = nameof(Length); + + [StlAttribute(Title = "显示字符的数目")] + private const string WordNum = nameof(WordNum); + + [StlAttribute(Title = "文字超出部分显示的文字")] + private const string Ellipsis = nameof(Ellipsis); + + [StlAttribute(Title = "需要替换的文字,可以是正则表达式")] + private const string Replace = nameof(Replace); + + [StlAttribute(Title = "替换replace的文字信息")] + private const string To = nameof(To); + + [StlAttribute(Title = "是否清除HTML标签")] + private const string IsClearTags = nameof(IsClearTags); + + [StlAttribute(Title = "是否将回车替换为HTML换行标签")] + private const string IsReturnToBr = nameof(IsReturnToBr); + + [StlAttribute(Title = "是否转换为小写")] + private const string IsLower = nameof(IsLower); + + [StlAttribute(Title = "是否转换为大写")] + private const string IsUpper = nameof(IsUpper); + + [StlAttribute(Title = "如果是引用内容,是否获取所引用内容的值")] + private const string IsOriginal = nameof(IsOriginal); + + public static object Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var leftText = string.Empty; + var rightText = string.Empty; + var formatString = string.Empty; + var no = "0"; + string separator = null; + var startIndex = 0; + var length = 0; + var wordNum = 0; + var ellipsis = Constants.Ellipsis; + var replace = string.Empty; + var to = string.Empty; + var isClearTags = false; + var isReturnToBrStr = string.Empty; + var isLower = false; + var isUpper = false; + var isOriginal = true;//引用的时候,默认使用原来的数据 + var type = string.Empty; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value.ToLower(); + } + else if (StringUtils.EqualsIgnoreCase(name, LeftText)) + { + leftText = value; + } + else if (StringUtils.EqualsIgnoreCase(name, RightText)) + { + rightText = value; + } + else if (StringUtils.EqualsIgnoreCase(name, FormatString)) + { + formatString = value; + } + else if (StringUtils.EqualsIgnoreCase(name, No)) + { + no = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Separator)) + { + separator = value; + } + else if (StringUtils.EqualsIgnoreCase(name, StartIndex)) + { + startIndex = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Length)) + { + length = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, WordNum)) + { + wordNum = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Ellipsis)) + { + ellipsis = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Replace)) + { + replace = value; + } + else if (StringUtils.EqualsIgnoreCase(name, To)) + { + to = value; + } + else if (StringUtils.EqualsIgnoreCase(name, IsClearTags)) + { + isClearTags = TranslateUtils.ToBool(value, true); + } + else if (StringUtils.EqualsIgnoreCase(name, IsReturnToBr)) + { + isReturnToBrStr = value; + } + else if (StringUtils.EqualsIgnoreCase(name, IsLower)) + { + isLower = TranslateUtils.ToBool(value, true); + } + else if (StringUtils.EqualsIgnoreCase(name, IsUpper)) + { + isUpper = TranslateUtils.ToBool(value, true); + } + else if (StringUtils.EqualsIgnoreCase(name, IsOriginal)) + { + isOriginal = TranslateUtils.ToBool(value, true); + } + } + + var contentId = contextInfo.ContentId; + var contentInfo = contextInfo.ContentInfo; + + if (contextInfo.IsStlEntity && string.IsNullOrEmpty(type)) + { + return contentInfo; + } + + var parsedContent = ParseImpl(pageInfo, contextInfo, leftText, rightText, formatString, no, separator, startIndex, length, wordNum, ellipsis, replace, to, isClearTags, isReturnToBrStr, isLower, isUpper, isOriginal, type, contentInfo, contentId); + + var innerBuilder = new StringBuilder(parsedContent); + StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); + parsedContent = innerBuilder.ToString(); + + if (!StringUtils.EqualsIgnoreCase(type, ContentAttribute.PageContent)) + { + parsedContent = parsedContent.Replace(ContentUtility.PagePlaceHolder, string.Empty); + } + + return parsedContent; + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string leftText, string rightText, string formatString, string no, string separator, int startIndex, int length, int wordNum, string ellipsis, string replace, string to, bool isClearTags, string isReturnToBrStr, bool isLower, bool isUpper, bool isOriginal, string type, ContentInfo contentInfo, int contentId) + { + if (contentInfo == null) return string.Empty; + + var parsedContent = string.Empty; + + if (string.IsNullOrEmpty(type)) + { + type = ContentAttribute.Title.ToLower(); + } + + var isReturnToBr = false; + if (string.IsNullOrEmpty(isReturnToBrStr)) + { + if (ContentAttribute.Summary.ToLower().Equals(type)) + { + isReturnToBr = true; + } + } + else + { + isReturnToBr = TranslateUtils.ToBool(isReturnToBrStr, true); + } + + if (isOriginal) + { + if (contentInfo.ReferenceId > 0 && contentInfo.SourceId > 0 && contentInfo.Get(ContentAttribute.TranslateContentType) == ETranslateContentType.Reference.ToString()) + { + var targetChannelId = contentInfo.SourceId; + //var targetSiteId = DataProvider.Channel.GetSiteId(targetChannelId); + var targetSiteId = StlChannelCache.GetSiteId(targetChannelId); + var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); + var targetNodeInfo = ChannelManager.GetChannelInfo(targetSiteId, targetChannelId); + + //var targetContentInfo = DataProvider.ContentRepository.GetContentInfo(tableStyle, tableName, contentInfo.ReferenceId); + var targetContentInfo = ContentManager.GetContentInfo(targetSiteInfo, targetNodeInfo, contentInfo.ReferenceId); + if (targetContentInfo != null && targetContentInfo.ChannelId > 0) + { + //标题可以使用自己的 + targetContentInfo.Title = contentInfo.Title; + contentInfo = targetContentInfo; + } + } + } + + if (!string.IsNullOrEmpty(formatString)) + { + formatString = formatString.Trim(); + if (!formatString.StartsWith("{0")) + { + formatString = "{0:" + formatString; + } + if (!formatString.EndsWith("}")) + { + formatString = formatString + "}"; + } + } + + if (contentId != 0) + { + if (ContentAttribute.Title.ToLower().Equals(type)) + { + var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contentInfo.ChannelId); + var relatedIdentities = TableStyleManager.GetRelatedIdentities(nodeInfo); + var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, nodeInfo); + + var styleInfo = TableStyleManager.GetTableStyleInfo(tableName, type, relatedIdentities); + parsedContent = InputParserUtility.GetContentByTableStyle(contentInfo.Title, separator, pageInfo.SiteInfo, styleInfo, formatString, contextInfo.Attributes, contextInfo.InnerHtml, false, isLower, isUpper); + parsedContent = InputTypeUtils.ParseString(styleInfo.Type, parsedContent, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); + + if (!isClearTags && !string.IsNullOrEmpty(contentInfo.Get(ContentAttribute.GetFormatStringAttributeName(ContentAttribute.Title)))) + { + parsedContent = ContentUtility.FormatTitle(contentInfo.Get(ContentAttribute.GetFormatStringAttributeName(ContentAttribute.Title)), parsedContent); + } + + if (pageInfo.SiteInfo.IsContentTitleBreakLine) + { + parsedContent = parsedContent.Replace(" ", !contextInfo.IsInnerElement ? "
    " : string.Empty); + } + } + else if (ContentAttribute.Summary.ToLower().Equals(type)) + { + parsedContent = InputTypeUtils.ParseString(InputType.TextArea, contentInfo.Get(ContentAttribute.Summary), replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); + } + else if (ContentAttribute.Content.ToLower().Equals(type)) + { + parsedContent = ContentUtility.TextEditorContentDecode(pageInfo.SiteInfo, contentInfo.Get(ContentAttribute.Content), pageInfo.IsLocal); + + if (isClearTags) + { + parsedContent = StringUtils.StripTags(parsedContent); + } + + if (!string.IsNullOrEmpty(replace)) + { + parsedContent = StringUtils.Replace(replace, parsedContent, to); + } + + if (wordNum > 0 && !string.IsNullOrEmpty(parsedContent)) + { + parsedContent = StringUtils.MaxLengthText(parsedContent, wordNum, ellipsis); + } + + if (!string.IsNullOrEmpty(formatString)) + { + parsedContent = string.Format(formatString, parsedContent); + } + } + else if (ContentAttribute.PageContent.ToLower().Equals(type)) + { + //if (contextInfo.IsInnerElement) + // { + parsedContent = ContentUtility.TextEditorContentDecode(pageInfo.SiteInfo, contentInfo.Get(ContentAttribute.Content), pageInfo.IsLocal); + + if (isClearTags) + { + parsedContent = StringUtils.StripTags(parsedContent); + } + + if (!string.IsNullOrEmpty(replace)) + { + parsedContent = StringUtils.Replace(replace, parsedContent, to); + } + + if (wordNum > 0 && !string.IsNullOrEmpty(parsedContent)) + { + parsedContent = StringUtils.MaxLengthText(parsedContent, wordNum, ellipsis); + } + + if (!string.IsNullOrEmpty(formatString)) + { + parsedContent = string.Format(formatString, parsedContent); + } + } + else if (ContentAttribute.AddDate.ToLower().Equals(type)) + { + parsedContent = DateUtils.Format(contentInfo.AddDate, formatString); + } + else if (ContentAttribute.LastEditDate.ToLower().Equals(type)) + { + parsedContent = DateUtils.Format(contentInfo.LastEditDate, formatString); + } + else if (ContentAttribute.ImageUrl.ToLower().Equals(type)) + { + if (no == "all") + { + var sbParsedContent = new StringBuilder(); + //第一条 + sbParsedContent.Append(contextInfo.IsStlEntity + ? PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, + contentInfo.Get(ContentAttribute.ImageUrl), pageInfo.IsLocal) + : InputParserUtility.GetImageOrFlashHtml(pageInfo.SiteInfo, + contentInfo.Get(ContentAttribute.ImageUrl), + contextInfo.Attributes, false)); + //第n条 + var extendAttributeName = ContentAttribute.GetExtendAttributeName(ContentAttribute.ImageUrl); + var extendValues = contentInfo.Get(extendAttributeName); + if (!string.IsNullOrEmpty(extendValues)) + { + foreach (var extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) + { + var newExtendValue = extendValue; + sbParsedContent.Append(contextInfo.IsStlEntity + ? PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, newExtendValue, pageInfo.IsLocal) + : InputParserUtility.GetImageOrFlashHtml(pageInfo.SiteInfo, + newExtendValue, contextInfo.Attributes, false)); + } + } + + parsedContent = sbParsedContent.ToString(); + } + else + { + var num = TranslateUtils.ToInt(no); + if (num <= 1) + { + parsedContent = contextInfo.IsStlEntity ? PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, contentInfo.Get(ContentAttribute.ImageUrl), pageInfo.IsLocal) : InputParserUtility.GetImageOrFlashHtml(pageInfo.SiteInfo, contentInfo.Get(ContentAttribute.ImageUrl), contextInfo.Attributes, false); + } + else + { + var extendAttributeName = ContentAttribute.GetExtendAttributeName(ContentAttribute.ImageUrl); + var extendValues = contentInfo.Get(extendAttributeName); + if (!string.IsNullOrEmpty(extendValues)) + { + var index = 2; + foreach (var extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) + { + var newExtendValue = extendValue; + if (index == num) + { + parsedContent = contextInfo.IsStlEntity ? PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, newExtendValue, pageInfo.IsLocal) : InputParserUtility.GetImageOrFlashHtml(pageInfo.SiteInfo, newExtendValue, contextInfo.Attributes, false); + break; + } + index++; + } + } + } + } + } + else if (ContentAttribute.VideoUrl.ToLower().Equals(type)) + { + if (no == "all") + { + var sbParsedContent = new StringBuilder(); + //第一条 + sbParsedContent.Append(InputParserUtility.GetVideoHtml(pageInfo.SiteInfo, contentInfo.Get(ContentAttribute.VideoUrl), contextInfo.Attributes, contextInfo.IsStlEntity)); + + //第n条 + var extendAttributeName = ContentAttribute.GetExtendAttributeName(ContentAttribute.VideoUrl); + var extendValues = contentInfo.Get(extendAttributeName); + if (!string.IsNullOrEmpty(extendValues)) + { + foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) + { + + sbParsedContent.Append(InputParserUtility.GetVideoHtml(pageInfo.SiteInfo, extendValue, contextInfo.Attributes, contextInfo.IsStlEntity)); + + } + } + + parsedContent = sbParsedContent.ToString(); + } + else + { + var num = TranslateUtils.ToInt(no); + if (num <= 1) + { + parsedContent = InputParserUtility.GetVideoHtml(pageInfo.SiteInfo, contentInfo.Get(ContentAttribute.VideoUrl), contextInfo.Attributes, contextInfo.IsStlEntity); + } + else + { + var extendAttributeName = ContentAttribute.GetExtendAttributeName(ContentAttribute.VideoUrl); + var extendValues = contentInfo.Get(extendAttributeName); + if (!string.IsNullOrEmpty(extendValues)) + { + var index = 2; + foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) + { + if (index == num) + { + parsedContent = InputParserUtility.GetVideoHtml(pageInfo.SiteInfo, extendValue, contextInfo.Attributes, contextInfo.IsStlEntity); + break; + } + index++; + } + } + } + } + + } + else if (ContentAttribute.FileUrl.ToLower().Equals(type)) + { + + if (no == "all") + { + var sbParsedContent = new StringBuilder(); + if (contextInfo.IsStlEntity) + { + //第一条 + sbParsedContent.Append(contentInfo.Get(ContentAttribute.FileUrl)); + //第n条 + var extendAttributeName = ContentAttribute.GetExtendAttributeName(ContentAttribute.FileUrl); + var extendValues = contentInfo.Get(extendAttributeName); + if (!string.IsNullOrEmpty(extendValues)) + { + foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) + { + sbParsedContent.Append(extendValue); + } + } + } + else + { + //第一条 + sbParsedContent.Append(InputParserUtility.GetFileHtmlWithCount(pageInfo.SiteInfo, contentInfo.ChannelId, contentInfo.Id, contentInfo.Get(ContentAttribute.FileUrl), contextInfo.Attributes, contextInfo.InnerHtml, false, isLower, isUpper)); + //第n条 + var extendAttributeName = ContentAttribute.GetExtendAttributeName(ContentAttribute.FileUrl); + var extendValues = contentInfo.Get(extendAttributeName); + if (!string.IsNullOrEmpty(extendValues)) + { + foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) + { + sbParsedContent.Append(InputParserUtility.GetFileHtmlWithCount(pageInfo.SiteInfo, contentInfo.ChannelId, contentInfo.Id, extendValue, contextInfo.Attributes, contextInfo.InnerHtml, false, isLower, isUpper)); + } + } + + } + + parsedContent = sbParsedContent.ToString(); + + } + else + { + var num = TranslateUtils.ToInt(no); + if (contextInfo.IsStlEntity) + { + if (num <= 1) + { + parsedContent = contentInfo.Get(ContentAttribute.FileUrl); + } + else + { + var extendAttributeName = ContentAttribute.GetExtendAttributeName(ContentAttribute.FileUrl); + var extendValues = contentInfo.Get(extendAttributeName); + if (!string.IsNullOrEmpty(extendValues)) + { + var index = 2; + foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) + { + if (index == num) + { + parsedContent = extendValue; + break; + } + index++; + } + } + } + + if (!string.IsNullOrEmpty(parsedContent)) + { + parsedContent = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); + } + } + else + { + if (num <= 1) + { + parsedContent = InputParserUtility.GetFileHtmlWithCount(pageInfo.SiteInfo, contentInfo.ChannelId, contentInfo.Id, contentInfo.Get(ContentAttribute.FileUrl), contextInfo.Attributes, contextInfo.InnerHtml, false, isLower, isUpper); + } + else + { + var extendAttributeName = ContentAttribute.GetExtendAttributeName(ContentAttribute.FileUrl); + var extendValues = contentInfo.Get(extendAttributeName); + if (!string.IsNullOrEmpty(extendValues)) + { + var index = 2; + foreach (string extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) + { + if (index == num) + { + parsedContent = InputParserUtility.GetFileHtmlWithCount(pageInfo.SiteInfo, contentInfo.ChannelId, contentInfo.Id, extendValue, contextInfo.Attributes, contextInfo.InnerHtml, false, isLower, isUpper); + break; + } + index++; + } + } + } + } + } + + + } + else if (ContentAttribute.NavigationUrl.ToLower().Equals(type)) + { + parsedContent = PageUtility.GetContentUrl(pageInfo.SiteInfo, contentInfo, pageInfo.IsLocal); + } + else if (ContentAttribute.Tags.ToLower().Equals(type)) + { + parsedContent = contentInfo.Tags; + } + else if (StringUtils.StartsWithIgnoreCase(type, StlParserUtility.ItemIndex) && contextInfo.ItemContainer?.ContentItem != null) + { + var itemIndex = StlParserUtility.ParseItemIndex(contextInfo.ItemContainer.ContentItem.ItemIndex, type, contextInfo); + parsedContent = !string.IsNullOrEmpty(formatString) ? string.Format(formatString, itemIndex) : itemIndex.ToString(); + } + else if (ContentAttribute.AddUserName.ToLower().Equals(type)) + { + if (!string.IsNullOrEmpty(contentInfo.AddUserName)) + { + parsedContent = contentInfo.AddUserName; + } + } + else + { + var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contentInfo.ChannelId); + + if (contentInfo.ContainsKey(type)) + { + if (!StringUtils.ContainsIgnoreCase(ContentAttribute.AllAttributes.Value, type)) + { + var relatedIdentities = TableStyleManager.GetRelatedIdentities(nodeInfo); + var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, nodeInfo); + var styleInfo = TableStyleManager.GetTableStyleInfo(tableName, type, relatedIdentities); + + //styleInfo.IsVisible = false 表示此字段不需要显示 styleInfo.TableStyleId = 0 不能排除,因为有可能是直接辅助表字段没有添加显示样式 + var num = TranslateUtils.ToInt(no); + parsedContent = InputParserUtility.GetContentByTableStyle(contentInfo, separator, pageInfo.SiteInfo, styleInfo, formatString, num, contextInfo.Attributes, contextInfo.InnerHtml, false, isLower, isUpper); + parsedContent = InputTypeUtils.ParseString(styleInfo.Type, parsedContent, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); + } + else + { + parsedContent = contentInfo.Get(type); + parsedContent = InputTypeUtils.ParseString(InputType.Text, parsedContent, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); + } + } + } + + if (!string.IsNullOrEmpty(parsedContent)) + { + parsedContent = leftText + parsedContent + rightText; + } + } + + return parsedContent; + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlContents.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlContents.cs new file mode 100644 index 000000000..08a6f16d7 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlContents.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.Data; +using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "内容列表", Description = "通过 stl:contents 标签在模板中显示内容列表")] + public class StlContents : StlListBase + { + public const string ElementName = "stl:contents"; + + public static object Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var listInfo = ListInfo.GetListInfo(pageInfo, contextInfo, EContextType.Content); + var dataSource = GetDataSource(pageInfo, contextInfo, listInfo); + + return contextInfo.IsStlEntity + ? ParseEntity(pageInfo, dataSource) + : ParseElement(pageInfo, contextInfo, listInfo, dataSource); + } + + private static DataSet GetDataSource(PageInfo pageInfo, ContextInfo contextInfo, ListInfo listInfo) + { + var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, listInfo.UpLevel, listInfo.TopLevel); + + channelId = ChannelManager.GetChannelId(pageInfo.SiteId, channelId, listInfo.ChannelIndex, listInfo.ChannelName); + + return StlDataUtility.GetContentsDataSource(pageInfo.SiteInfo, channelId, contextInfo.ContentId, listInfo.GroupContent, listInfo.GroupContentNot, listInfo.Tags, listInfo.IsImageExists, listInfo.IsImage, listInfo.IsVideoExists, listInfo.IsVideo, listInfo.IsFileExists, listInfo.IsFile, listInfo.IsRelatedContents, listInfo.StartNum, listInfo.TotalNum, listInfo.OrderByString, listInfo.IsTopExists, listInfo.IsTop, listInfo.IsRecommendExists, listInfo.IsRecommend, listInfo.IsHotExists, listInfo.IsHot, listInfo.IsColorExists, listInfo.IsColor, listInfo.Where, listInfo.Scope, listInfo.GroupChannel, listInfo.GroupChannelNot, listInfo.Others); + } + + private static string ParseElement(PageInfo pageInfo, ContextInfo contextInfo, ListInfo listInfo, DataSet dataSource) + { + var parsedContent = string.Empty; + + if (listInfo.Layout == ELayout.None) + { + var rptContents = new Repeater + { + ItemTemplate = + new RepeaterTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, + listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, + pageInfo, EContextType.Content, contextInfo) + }; + + if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) + { + rptContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); + } + if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) + { + rptContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); + } + if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) + { + rptContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); + } + if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) + { + rptContents.AlternatingItemTemplate = new RepeaterTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Content, contextInfo); + } + + rptContents.DataSource = dataSource; + rptContents.DataBind(); + + if (rptContents.Items.Count > 0) + { + parsedContent = ControlUtils.GetControlRenderHtml(rptContents); + } + } + else + { + var pdlContents = new ParsedDataList(); + + TemplateUtility.PutListInfoToMyDataList(pdlContents, listInfo); + + pdlContents.ItemTemplate = new DataListTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Content, contextInfo); + if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) + { + pdlContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); + } + if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) + { + pdlContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); + } + if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) + { + pdlContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); + } + if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) + { + pdlContents.AlternatingItemTemplate = new DataListTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Content, contextInfo); + } + + pdlContents.DataSource = dataSource; + pdlContents.DataKeyField = ContentAttribute.Id; + pdlContents.DataBind(); + + if (pdlContents.Items.Count > 0) + { + parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); + } + } + + return parsedContent; + } + + private static object ParseEntity(PageInfo pageInfo, DataSet dataSource) + { + var contentInfoList = new List>(); + + var table = dataSource.Tables[0]; + foreach (DataRow row in table.Rows) + { + var contentId = Convert.ToInt32(row[nameof(ContentAttribute.Id)]); + var channelId = Convert.ToInt32(row[nameof(ContentAttribute.ChannelId)]); + + var contentInfo = ContentManager.GetContentInfo(pageInfo.SiteInfo, channelId, contentId); + + if (contentInfo != null) + { + contentInfoList.Add(contentInfo.ToDictionary()); + } + } + + return contentInfoList; + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlCount.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlCount.cs new file mode 100644 index 000000000..b804beffc --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlCount.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Stl; +using SiteServer.Utils; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "显示数值", Description = "通过 stl:count 标签在模板中显示统计数字")] + public class StlCount + { + private StlCount() { } + public const string ElementName = "stl:count"; + + [StlAttribute(Title = "需要获取值的类型")] + private const string Type = nameof(Type); + + [StlAttribute(Title = "栏目索引")] + private const string ChannelIndex = nameof(ChannelIndex); + + [StlAttribute(Title = "栏目名称")] + private const string ChannelName = nameof(ChannelName); + + [StlAttribute(Title = "上级栏目的级别")] + private const string UpLevel = nameof(UpLevel); + + [StlAttribute(Title = "从首页向下的栏目级别")] + private const string TopLevel = nameof(TopLevel); + + [StlAttribute(Title = "内容范围")] + private const string Scope = nameof(Scope); + + [StlAttribute(Title = "时间段")] + private const string Since = nameof(Since); + + + public const string TypeChannels = "Channels"; + public const string TypeContents = "Contents"; + + public static SortedList TypeList => new SortedList + { + {TypeChannels, "栏目数"}, + {TypeContents, "内容数"} + }; + + public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var type = string.Empty; + var channelIndex = string.Empty; + var channelName = string.Empty; + var upLevel = 0; + var topLevel = -1; + var scope = EScopeType.Self; + var since = string.Empty; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value; + } + else if (StringUtils.EqualsIgnoreCase(name, ChannelIndex)) + { + channelIndex = value; + } + else if (StringUtils.EqualsIgnoreCase(name, ChannelName)) + { + channelName = value; + } + else if (StringUtils.EqualsIgnoreCase(name, UpLevel)) + { + upLevel = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, TopLevel)) + { + topLevel = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Scope)) + { + scope = EScopeTypeUtils.GetEnumType(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Since)) + { + since = value; + } + } + + return ParseImpl(pageInfo, contextInfo, type, channelIndex, channelName, upLevel, topLevel, scope, since); + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string type, string channelIndex, string channelName, int upLevel, int topLevel, EScopeType scope, string since) + { + var count = 0; + + var sinceDate = DateUtils.SqlMinValue; + if (!string.IsNullOrEmpty(since)) + { + sinceDate = DateTime.Now.AddHours(-DateUtils.GetSinceHours(since)); + } + + if (string.IsNullOrEmpty(type) || StringUtils.EqualsIgnoreCase(type, TypeContents)) + { + var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); + channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, channelIndex, channelName); + + var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); + var channelIdList = ChannelManager.GetChannelIdList(nodeInfo, scope, string.Empty, string.Empty, string.Empty); + foreach (var theChannelId in channelIdList) + { + var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, theChannelId); + count += StlContentCache.GetCountOfContentAdd(tableName, pageInfo.SiteId, theChannelId, EScopeType.Self, sinceDate, DateTime.Now.AddDays(1), string.Empty, ETriState.True); + } + } + else if (StringUtils.EqualsIgnoreCase(type, TypeChannels)) + { + var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); + channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, channelIndex, channelName); + + var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); + count = nodeInfo.ChildrenCount; + } + + return count.ToString(); + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlDynamic.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlDynamic.cs new file mode 100644 index 000000000..db946d196 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlDynamic.cs @@ -0,0 +1,260 @@ +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Text; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Core; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Parsers; +using SiteServer.CMS.StlParser.StlEntity; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Plugin; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "动态显示", Description = "通过 stl:dynamic 标签在模板中实现动态显示功能")] + public class StlDynamic + { + private StlDynamic() { } + public const string ElementName = "stl:dynamic"; + + [StlAttribute(Title = "所处上下文")] + private const string Context = nameof(Context); + + [StlAttribute(Title = "翻页时是否刷新页面")] + private const string IsPageRefresh = nameof(IsPageRefresh); + + [StlAttribute(Title = "请求前触发事件")] + private const string OnBeforeSend = nameof(OnBeforeSend); + + [StlAttribute(Title = "请求成功后触发事件")] + private const string OnSuccess = nameof(OnSuccess); + + [StlAttribute(Title = "请求结束后触发事件")] + private const string OnComplete = nameof(OnComplete); + + [StlAttribute(Title = "请求失败后触发事件")] + private const string OnError = nameof(OnError); + + internal static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + // 如果是实体标签则返回空 + if (contextInfo.IsStlEntity) + { + return string.Empty; + } + + var isPageRefresh = false; + var onBeforeSend = string.Empty; + var onSuccess = string.Empty; + var onComplete = string.Empty; + var onError = string.Empty; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, Context)) + { + contextInfo.ContextType = EContextTypeUtils.GetEnumType(value); + } + else if (StringUtils.EqualsIgnoreCase(name, IsPageRefresh)) + { + isPageRefresh = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, OnBeforeSend)) + { + onBeforeSend = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, OnSuccess)) + { + onSuccess = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, OnComplete)) + { + onComplete = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, OnError)) + { + onError = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + } + + return ParseImpl(pageInfo, contextInfo, contextInfo.InnerHtml, isPageRefresh, onBeforeSend, onSuccess, onComplete, onError); + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string templateContent, bool isPageRefresh, string onBeforeSend, string onSuccess, string onComplete, string onError) + { + pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.StlClient); + + var ajaxDivId = StlParserUtility.GetAjaxDivId(pageInfo.UniqueId); + + var functionName = $"stlDynamic_{ajaxDivId}"; + + if (string.IsNullOrEmpty(templateContent)) + { + return string.Empty; + } + + StlParserManager.ParseInnerContent(new StringBuilder(templateContent), pageInfo, contextInfo); + + var apiUrl = ApiRouteActionsDynamic.GetUrl(pageInfo.ApiUrl); + var currentPageUrl = StlParserUtility.GetStlCurrentUrl(pageInfo.SiteInfo, contextInfo.ChannelId, contextInfo.ContentId, contextInfo.ContentInfo, pageInfo.TemplateInfo.Type, pageInfo.TemplateInfo.Id, pageInfo.IsLocal); + currentPageUrl = PageUtils.AddQuestionOrAndToUrl(currentPageUrl); + var apiParameters = ApiRouteActionsDynamic.GetParameters(pageInfo.SiteId, contextInfo.ChannelId, contextInfo.ContentId, pageInfo.TemplateInfo.Id, currentPageUrl, ajaxDivId, isPageRefresh, templateContent); + + var builder = new StringBuilder(); + builder.Append($@""); + + builder.Append($@" + +"); + + return builder.ToString(); + } + + internal static string ParseDynamicElement(string stlElement, PageInfo pageInfo, ContextInfo contextInfo) + { + stlElement = StringUtils.ReplaceIgnoreCase(stlElement, "isdynamic=\"true\"", string.Empty); + return ParseImpl(pageInfo, contextInfo, stlElement, false, string.Empty, string.Empty, string.Empty, string.Empty); + } + + public static string ParseDynamicContent(int siteId, int channelId, int contentId, int templateId, bool isPageRefresh, string templateContent, string pageUrl, int pageIndex, string ajaxDivId, NameValueCollection queryString, UserInfo userInfo) + { + StlCacheManager.ClearAll(); + + var templateInfo = TemplateManager.GetTemplateInfo(siteId, templateId); + //TemplateManager.GetTemplateInfo(siteID, channelID, templateType); + var siteInfo = SiteManager.GetSiteInfo(siteId); + var pageInfo = new PageInfo(channelId, contentId, siteInfo, templateInfo, new Dictionary()) + { + UniqueId = 1000, + UserInfo = userInfo + }; + var contextInfo = new ContextInfo(pageInfo); + + templateContent = StlRequestEntities.ParseRequestEntities(queryString, templateContent); + var contentBuilder = new StringBuilder(templateContent); + var stlElementList = StlParserUtility.GetStlElementList(contentBuilder.ToString()); + + //如果标签中存在 + if (StlParserUtility.IsStlElementExists(StlPageContents.ElementName, stlElementList)) + { + var stlElement = StlParserUtility.GetStlElement(StlPageContents.ElementName, stlElementList); + var stlPageContentsElement = stlElement; + var stlPageContentsElementReplaceString = stlElement; + + var pageContentsElementParser = new StlPageContents(stlPageContentsElement, pageInfo, contextInfo); + var pageCount = pageContentsElementParser.GetPageCount(out var totalNum); + + for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) + { + if (currentPageIndex == pageIndex) + { + var pageHtml = pageContentsElementParser.Parse(totalNum, currentPageIndex, pageCount, false); + contentBuilder.Replace(stlPageContentsElementReplaceString, pageHtml); + + StlParserManager.ReplacePageElementsInDynamicPage(contentBuilder, pageInfo, stlElementList, pageUrl, pageInfo.PageChannelId, currentPageIndex, pageCount, totalNum, isPageRefresh, ajaxDivId); + + break; + } + } + } + //如果标签中存在 + else if (StlParserUtility.IsStlElementExists(StlPageChannels.ElementName, stlElementList)) + { + var stlElement = StlParserUtility.GetStlElement(StlPageChannels.ElementName, stlElementList); + var stlPageChannelsElement = stlElement; + var stlPageChannelsElementReplaceString = stlElement; + + var pageChannelsElementParser = new StlPageChannels(stlPageChannelsElement, pageInfo, contextInfo); + var pageCount = pageChannelsElementParser.GetPageCount(out var totalNum); + + for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) + { + if (currentPageIndex == pageIndex) + { + var pageHtml = pageChannelsElementParser.Parse(currentPageIndex, pageCount); + contentBuilder.Replace(stlPageChannelsElementReplaceString, pageHtml); + + StlParserManager.ReplacePageElementsInDynamicPage(contentBuilder, pageInfo, stlElementList, pageUrl, pageInfo.PageChannelId, currentPageIndex, pageCount, totalNum, isPageRefresh, ajaxDivId); + + break; + } + } + } + //如果标签中存在 + else if (StlParserUtility.IsStlElementExists(StlPageSqlContents.ElementName, stlElementList)) + { + var stlElement = StlParserUtility.GetStlElement(StlPageSqlContents.ElementName, stlElementList); + var stlPageSqlContentsElement = stlElement; + var stlPageSqlContentsElementReplaceString = stlElement; + + var pageSqlContentsElementParser = new StlPageSqlContents(stlPageSqlContentsElement, pageInfo, contextInfo); + var pageCount = pageSqlContentsElementParser.GetPageCount(out var totalNum); + + for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) + { + if (currentPageIndex == pageIndex) + { + var pageHtml = pageSqlContentsElementParser.Parse(totalNum, currentPageIndex, pageCount, false); + contentBuilder.Replace(stlPageSqlContentsElementReplaceString, pageHtml); + + StlParserManager.ReplacePageElementsInDynamicPage(contentBuilder, pageInfo, stlElementList, pageUrl, pageInfo.PageChannelId, currentPageIndex, pageCount, totalNum, isPageRefresh, ajaxDivId); + + break; + } + } + } + + else if (StlParserUtility.IsStlElementExists(StlPageItems.ElementName, stlElementList)) + { + var pageCount = TranslateUtils.ToInt(queryString["pageCount"]); + var totalNum = TranslateUtils.ToInt(queryString["totalNum"]); + var pageContentsAjaxDivId = queryString["pageContentsAjaxDivId"]; + + for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) + { + if (currentPageIndex == pageIndex) + { + StlParserManager.ReplacePageElementsInDynamicPage(contentBuilder, pageInfo, stlElementList, pageUrl, pageInfo.PageChannelId, currentPageIndex, pageCount, totalNum, isPageRefresh, pageContentsAjaxDivId); + + break; + } + } + } + + StlParserManager.ParseInnerContent(contentBuilder, pageInfo, contextInfo); + + //var parsedContent = StlParserUtility.GetBackHtml(contentBuilder.ToString(), pageInfo); + //return pageInfo.HeadCodesHtml + pageInfo.BodyCodesHtml + parsedContent + pageInfo.FootCodesHtml; + return contentBuilder.ToString(); + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlEach.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlEach.cs new file mode 100644 index 000000000..118363909 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlEach.cs @@ -0,0 +1,165 @@ +using System.Collections; +using System.Collections.Generic; +using System.Web.UI.WebControls; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "列表项循环", Description = "通过 stl:each 标签在模板中遍历指定的列表项")] + public class StlEach + { + public const string ElementName = "stl:each"; + + [StlAttribute(Title = "循环类型")] + private const string Type = nameof(Type); + + public static SortedList TypeList => new SortedList + { + {ContentAttribute.ImageUrl, "遍历内容的图片字段"}, + {ContentAttribute.VideoUrl, "遍历内容的视频字段"}, + {ContentAttribute.FileUrl, "遍历内容的附件字段"} + }; + + public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var listInfo = ListInfo.GetListInfo(pageInfo, contextInfo, EContextType.Content); + + return ParseImpl(pageInfo, contextInfo, listInfo); + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, ListInfo listInfo) + { + var parsedContent = string.Empty; + + var type = listInfo.Others.Get(Type); + if (string.IsNullOrEmpty(type)) + { + type = ContentAttribute.ImageUrl; + } + + var contextType = EContextType.Each; + IEnumerable dataSource = null; + var contentInfo = contextInfo.ContentInfo; + if (contentInfo != null) + { + var eachList = new List(); + + var value = contentInfo.Get(type); + if (!string.IsNullOrEmpty(value)) + { + eachList.Add(value); + } + + var extendAttributeName = ContentAttribute.GetExtendAttributeName(type); + var extendValues = contentInfo.Get(extendAttributeName); + if (!string.IsNullOrEmpty(extendValues)) + { + foreach (var extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) + { + eachList.Add(extendValue); + } + } + + if (listInfo.StartNum > 1 || listInfo.TotalNum > 0) + { + if (listInfo.StartNum > 1) + { + var count = listInfo.StartNum - 1; + if (count > eachList.Count) + { + count = eachList.Count; + } + eachList.RemoveRange(0, count); + } + + if (listInfo.TotalNum > 0) + { + if (listInfo.TotalNum < eachList.Count) + { + eachList.RemoveRange(listInfo.TotalNum, eachList.Count - listInfo.TotalNum); + } + } + } + + dataSource = eachList; + } + + if (listInfo.Layout == ELayout.None) + { + var rptContents = new Repeater + { + ItemTemplate = + new RepeaterTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, + listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, + pageInfo, contextType, contextInfo) + }; + + if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) + { + rptContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); + } + if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) + { + rptContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); + } + if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) + { + rptContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); + } + if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) + { + rptContents.AlternatingItemTemplate = new RepeaterTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, contextType, contextInfo); + } + + rptContents.DataSource = dataSource; + + rptContents.DataBind(); + + if (rptContents.Items.Count > 0) + { + parsedContent = ControlUtils.GetControlRenderHtml(rptContents); + } + } + else + { + var pdlContents = new ParsedDataList(); + + TemplateUtility.PutListInfoToMyDataList(pdlContents, listInfo); + + pdlContents.ItemTemplate = new DataListTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, contextType, contextInfo); + if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) + { + pdlContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); + } + if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) + { + pdlContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); + } + if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) + { + pdlContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); + } + if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) + { + pdlContents.AlternatingItemTemplate = new DataListTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, contextType, contextInfo); + } + + pdlContents.DataSource = dataSource; + + pdlContents.DataBind(); + + if (pdlContents.Items.Count > 0) + { + parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); + } + } + + return parsedContent; + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlFile.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlFile.cs new file mode 100644 index 000000000..af738b3a2 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlFile.cs @@ -0,0 +1,233 @@ +using System.Text; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "文件下载链接", Description = "通过 stl:file 标签在模板中显示文件下载链接")] + public class StlFile + { + private StlFile() { } + + public const string ElementName = "stl:file"; + + [StlAttribute(Title = "指定存储附件的字段")] + private const string Type = nameof(Type); + + [StlAttribute(Title = "显示字段的顺序")] + private const string No = nameof(No); + + [StlAttribute(Title = "需要下载的文件地址")] + private const string Src = nameof(Src); + + [StlAttribute(Title = "仅显示文件名称")] + private const string IsFileName = nameof(IsFileName); + + [StlAttribute(Title = "仅显示文件类型")] + private const string IsFileType = nameof(IsFileType); + + [StlAttribute(Title = "仅显示文件大小")] + private const string IsFileSize = nameof(IsFileSize); + + [StlAttribute(Title = "仅显示下载次数")] + private const string IsCount = nameof(IsCount); + + [StlAttribute(Title = "是否转换为小写")] + private const string IsLower = nameof(IsLower); + + [StlAttribute(Title = "是否转换为大写")] + private const string IsUpper = nameof(IsUpper); + + [StlAttribute(Title = "显示在信息前的文字")] + private const string LeftText = nameof(LeftText); + + [StlAttribute(Title = "显示在信息后的文字")] + private const string RightText = nameof(RightText); + + public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var type = ContentAttribute.FileUrl; + var no = 0; + var src = string.Empty; + var isFileName = false; + var isFileType = false; + var isFileSize = false; + var isCount = false; + var isLower = false; + var isUpper = false; + var leftText = string.Empty; + var rightText = string.Empty; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value; + } + else if (StringUtils.EqualsIgnoreCase(name, No)) + { + no = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Src)) + { + src = value; + } + else if (StringUtils.EqualsIgnoreCase(name, IsFileName)) + { + isFileName = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, IsFileType)) + { + isFileType = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, IsFileSize)) + { + isFileSize = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, IsCount)) + { + isCount = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, IsLower)) + { + isLower = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, IsUpper)) + { + isUpper = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, LeftText)) + { + leftText = value; + } + else if (StringUtils.EqualsIgnoreCase(name, RightText)) + { + rightText = value; + } + } + + return ParseImpl(pageInfo, contextInfo, type, no, src, isFileName, isFileType, isFileSize, isCount, isLower, isUpper, leftText, rightText); + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string type, int no, string src, bool isFileName, bool isFileType, bool isFileSize, bool isCount, bool isLower, bool isUpper, string leftText, string rightText) + { + if (!string.IsNullOrEmpty(contextInfo.InnerHtml)) + { + var innerBuilder = new StringBuilder(contextInfo.InnerHtml); + StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); + contextInfo.InnerHtml = innerBuilder.ToString(); + } + + var fileUrl = string.Empty; + if (!string.IsNullOrEmpty(src)) + { + fileUrl = src; + } + else + { + if (contextInfo.ContextType == EContextType.Undefined) + { + contextInfo.ContextType = EContextType.Content; + } + if (contextInfo.ContextType == EContextType.Content) + { + if (contextInfo.ContentId != 0) + { + var contentInfo = contextInfo.ContentInfo; + + var value = contentInfo?.Get(type); + + if (!string.IsNullOrEmpty(value)) + { + if (no <= 1) + { + fileUrl = value; + } + else + { + var extendAttributeName = ContentAttribute.GetExtendAttributeName(type); + var extendValues = contentInfo.Get(extendAttributeName); + if (!string.IsNullOrEmpty(extendValues)) + { + var index = 2; + foreach (var extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) + { + if (index == no) + { + fileUrl = extendValue; + + break; + } + index++; + } + } + } + } + } + } + else if (contextInfo.ContextType == EContextType.Each) + { + fileUrl = contextInfo.ItemContainer.EachItem.DataItem as string; + } + } + + string parsedContent; + + if (isFileName) + { + parsedContent = PathUtils.RemoveExtension(PageUtils.GetFileNameFromUrl(fileUrl)); + if (isLower) + { + parsedContent = parsedContent.ToLower(); + } + if (isUpper) + { + parsedContent = parsedContent.ToUpper(); + } + } + else if (isFileType) + { + var filePath = PathUtility.MapPath(pageInfo.SiteInfo, fileUrl); + parsedContent = PathUtils.GetExtension(filePath).Trim('.'); + if (isLower) + { + parsedContent = parsedContent.ToLower(); + } + if (isUpper) + { + parsedContent = parsedContent.ToUpper(); + } + } + else if (isFileSize) + { + var filePath = PathUtility.MapPath(pageInfo.SiteInfo, fileUrl); + parsedContent = FileUtils.GetFileSizeByFilePath(filePath); + } + else if (isCount) + { + parsedContent = (contextInfo.ContentInfo?.Downloads ?? 0).ToString(); + } + else + { + parsedContent = contextInfo.ContentInfo != null + ? InputParserUtility.GetFileHtmlWithCount(pageInfo.SiteInfo, contextInfo.ContentInfo.ChannelId, + contextInfo.ContentInfo.Id, fileUrl, contextInfo.Attributes, contextInfo.InnerHtml, + contextInfo.IsStlEntity, isLower, isUpper) + : InputParserUtility.GetFileHtmlWithoutCount(pageInfo.SiteInfo, fileUrl, contextInfo.Attributes, + contextInfo.InnerHtml, contextInfo.IsStlEntity, isLower, isUpper); + } + + if (!string.IsNullOrEmpty(parsedContent)) + { + parsedContent = leftText + parsedContent + rightText; + } + + return parsedContent; + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlFlash.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlFlash.cs new file mode 100644 index 000000000..0de25372e --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlFlash.cs @@ -0,0 +1,428 @@ +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Stl; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Parsers; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "显示Flash", Description = "通过 stl:flash 标签在模板中获取并显示栏目或内容的Flash")] + public class StlFlash + { + private StlFlash() { } + public const string ElementName = "stl:flash"; + + [StlAttribute(Title = "栏目索引")] + private const string ChannelIndex = nameof(ChannelIndex); + + [StlAttribute(Title = "栏目名称")] + private const string ChannelName = nameof(ChannelName); + + [StlAttribute(Title = "显示父栏目")] + private const string Parent = nameof(Parent); + + [StlAttribute(Title = "上级栏目的级别")] + private const string UpLevel = nameof(UpLevel); + + [StlAttribute(Title = "从首页向下的栏目级别")] + private const string TopLevel = nameof(TopLevel); + + [StlAttribute(Title = "指定存储flash的字段")] + private const string Type = nameof(Type); + + [StlAttribute(Title = "显示的flash地址")] + private const string Src = nameof(Src); + + [StlAttribute(Title = "当指定的flash不存在时显示的flash地址")] + private const string AltSrc = nameof(AltSrc); + + [StlAttribute(Title = "宽度")] + private const string Width = nameof(Width); + + [StlAttribute(Title = "高度")] + private const string Height = nameof(Height); + + public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var isGetPicUrlFromAttribute = false; + var channelIndex = string.Empty; + var channelName = string.Empty; + var upLevel = 0; + var topLevel = -1; + var type = ContentAttribute.ImageUrl; + var src = string.Empty; + var altSrc = string.Empty; + var width = "100%"; + var height = "180"; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, ChannelIndex)) + { + channelIndex = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + if (!string.IsNullOrEmpty(channelIndex)) + { + isGetPicUrlFromAttribute = true; + } + } + else if (StringUtils.EqualsIgnoreCase(name, ChannelName)) + { + channelName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + if (!string.IsNullOrEmpty(channelName)) + { + isGetPicUrlFromAttribute = true; + } + } + else if (StringUtils.EqualsIgnoreCase(name, Parent)) + { + if (TranslateUtils.ToBool(value)) + { + upLevel = 1; + isGetPicUrlFromAttribute = true; + } + } + else if (StringUtils.EqualsIgnoreCase(name, UpLevel)) + { + upLevel = TranslateUtils.ToInt(value); + if (upLevel > 0) + { + isGetPicUrlFromAttribute = true; + } + } + else if (StringUtils.EqualsIgnoreCase(name, TopLevel)) + { + topLevel = TranslateUtils.ToInt(value); + if (topLevel >= 0) + { + isGetPicUrlFromAttribute = true; + } + } + else if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Src)) + { + src = value; + } + else if (StringUtils.EqualsIgnoreCase(name, AltSrc)) + { + altSrc = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Width)) + { + width = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Height)) + { + height = value; + } + } + + return ParseImpl(pageInfo, contextInfo, isGetPicUrlFromAttribute, channelIndex, channelName, upLevel, topLevel, type, src, altSrc, width, height); + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, bool isGetPicUrlFromAttribute, string channelIndex, string channelName, int upLevel, int topLevel, string type, string src, string altSrc, string width, string height) + { + var parsedContent = string.Empty; + + var contentId = 0; + //判断是否图片地址由标签属性获得 + if (!isGetPicUrlFromAttribute) + { + contentId = contextInfo.ContentId; + } + var contentInfo = contextInfo.ContentInfo; + + string flashUrl; + if (!string.IsNullOrEmpty(src)) + { + flashUrl = src; + } + else + { + if (contentId != 0)//获取内容Flash + { + if (contentInfo == null) + { + var channelInfo = ChannelManager.GetChannelInfo(contextInfo.SiteInfo.Id, contextInfo.ChannelId); + + //picUrl = DataProvider.ContentRepository.GetValueById(tableName, contentId, type); + flashUrl = StlContentCache.GetValue(channelInfo, contentId, type); + } + else + { + flashUrl = contextInfo.ContentInfo.Get(type); + } + } + else//获取栏目Flash + { + var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); + + channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, channelIndex, channelName); + var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); + + flashUrl = channel.ImageUrl; + } + } + + if (string.IsNullOrEmpty(flashUrl)) + { + flashUrl = altSrc; + } + + // 如果是实体标签则返回空 + if (contextInfo.IsStlEntity) + { + return flashUrl; + } + + if (!string.IsNullOrEmpty(flashUrl)) + { + var extension = PathUtils.GetExtension(flashUrl); + if (EFileSystemTypeUtils.IsImage(extension)) + { + parsedContent = StlImage.Parse(pageInfo, contextInfo); + } + else if (EFileSystemTypeUtils.IsPlayer(extension)) + { + parsedContent = StlPlayer.Parse(pageInfo, contextInfo); + } + else + { + flashUrl = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, flashUrl, pageInfo.IsLocal); + + parsedContent = $@" + +"; + } + } + + return parsedContent; + } + } +} + + +//using System.Text; +//using SiteServer.Utils; +//using SiteServer.CMS.Core; +//using SiteServer.CMS.Model.Attributes; +//using SiteServer.CMS.StlParser.Cache; +//using SiteServer.CMS.StlParser.Model; +//using SiteServer.CMS.StlParser.Parsers; +//using SiteServer.CMS.StlParser.Utility; +//using SiteServer.Utils.Enumerations; + +//namespace SiteServer.CMS.StlParser.StlElement +//{ +// [StlClass(Usage = "显示Flash", Description = "通过 stl:flash 标签在模板中获取并显示栏目或内容的Flash")] +// public class StlFlash +// { +// private StlFlash() { } +// public const string ElementName = "stl:flash"; + +// private static readonly Attr ChannelIndex = new Attr("channelIndex", "栏目索引"); +// private static readonly Attr ChannelName = new Attr("channelName", "栏目名称"); +// private static readonly Attr Parent = new Attr("parent", "显示父栏目"); +// private static readonly Attr UpLevel = new Attr("upLevel", "上级栏目的级别"); +// private static readonly Attr TopLevel = new Attr("topLevel", "从首页向下的栏目级别"); +// private static readonly Attr Type = new Attr("type", "指定存储flash的字段"); +// private static readonly Attr Src = new Attr("src", "显示的flash地址"); +// private static readonly Attr AltSrc = new Attr("altSrc", "当指定的flash不存在时显示的flash地址"); +// private static readonly Attr Width = new Attr("width", "宽度"); +// private static readonly Attr Height = new Attr("height", "高度"); + +// public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) +// { +// var isGetPicUrlFromAttribute = false; +// var channelIndex = string.Empty; +// var channelName = string.Empty; +// var upLevel = 0; +// var topLevel = -1; +// var type = ContentAttribute.ImageUrl; +// var src = string.Empty; +// var altSrc = string.Empty; +// var width = "100%"; +// var height = "180"; + +// foreach (var name in contextInfo.Attributes.AllKeys) +// { +// var value = contextInfo.Attributes[name]; + +// if (StringUtils.EqualsIgnoreCase(name, ChannelIndex)) +// { +// channelIndex = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); +// if (!string.IsNullOrEmpty(channelIndex)) +// { +// isGetPicUrlFromAttribute = true; +// } +// } +// else if (StringUtils.EqualsIgnoreCase(name, ChannelName)) +// { +// channelName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); +// if (!string.IsNullOrEmpty(channelName)) +// { +// isGetPicUrlFromAttribute = true; +// } +// } +// else if (StringUtils.EqualsIgnoreCase(name, Parent)) +// { +// if (TranslateUtils.ToBool(value)) +// { +// upLevel = 1; +// isGetPicUrlFromAttribute = true; +// } +// } +// else if (StringUtils.EqualsIgnoreCase(name, UpLevel)) +// { +// upLevel = TranslateUtils.ToInt(value); +// if (upLevel > 0) +// { +// isGetPicUrlFromAttribute = true; +// } +// } +// else if (StringUtils.EqualsIgnoreCase(name, TopLevel)) +// { +// topLevel = TranslateUtils.ToInt(value); +// if (topLevel >= 0) +// { +// isGetPicUrlFromAttribute = true; +// } +// } +// else if (StringUtils.EqualsIgnoreCase(name, Type)) +// { +// type = value; +// } +// else if (StringUtils.EqualsIgnoreCase(name, Src)) +// { +// src = value; +// } +// else if (StringUtils.EqualsIgnoreCase(name, AltSrc)) +// { +// altSrc = value; +// } +// else if (StringUtils.EqualsIgnoreCase(name, Width)) +// { +// width = value; +// } +// else if (StringUtils.EqualsIgnoreCase(name, Height)) +// { +// height = value; +// } +// } + +// return ParseImpl(pageInfo, contextInfo, isGetPicUrlFromAttribute, channelIndex, channelName, upLevel, topLevel, type, src, altSrc, width, height); +// } + +// private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, bool isGetPicUrlFromAttribute, string channelIndex, string channelName, int upLevel, int topLevel, string type, string src, string altSrc, string width, string height) +// { +// var parsedContent = string.Empty; + +// var contentId = 0; +// //判断是否图片地址由标签属性获得 +// if (!isGetPicUrlFromAttribute) +// { +// contentId = contextInfo.ContentId; +// } +// var contentInfo = contextInfo.ContentInfo; + +// string picUrl; +// if (!string.IsNullOrEmpty(src)) +// { +// picUrl = src; +// } +// else +// { +// if (contentId != 0)//获取内容Flash +// { +// if (contentInfo == null) +// { +// var nodeInfo = ChannelManager.GetChannelInfo(contextInfo.SiteInfo.Id, contextInfo.ChannelId); +// var tableName = ChannelManager.GetTableName(contextInfo.SiteInfo, nodeInfo); + +// //picUrl = DataProvider.ContentRepository.GetValueById(tableName, contentId, type); +// picUrl = Content.GetValueById(tableName, contentId, type); +// } +// else +// { +// picUrl = contextInfo.ContentInfo.GetString(type); +// } +// } +// else//获取栏目Flash +// { +// var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); + +// channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, channelIndex, channelName); +// var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); + +// picUrl = channel.ImageUrl; +// } +// } + +// if (string.IsNullOrEmpty(picUrl)) +// { +// picUrl = altSrc; +// } + +// // 如果是实体标签则返回空 +// if (contextInfo.IsStlEntity) +// { +// return picUrl; +// } + +// if (!string.IsNullOrEmpty(picUrl)) +// { +// var extension = PathUtils.GetExtension(picUrl); +// if (EFileSystemTypeUtils.IsImage(extension)) +// { +// parsedContent = StlImage.Parse(pageInfo, contextInfo); +// } +// else if (EFileSystemTypeUtils.IsPlayer(extension)) +// { +// parsedContent = StlPlayer.Parse(pageInfo, contextInfo); +// } +// else +// { +// pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.JsAcSwfObject); + +// picUrl = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, picUrl, pageInfo.IsLocal); + +// if (string.IsNullOrEmpty(contextInfo.Attributes["quality"])) +// { +// contextInfo.Attributes["quality"] = "high"; +// } +// if (string.IsNullOrEmpty(contextInfo.Attributes["wmode"])) +// { +// contextInfo.Attributes["wmode"] = "transparent"; +// } +// var paramBuilder = new StringBuilder(); +// var uniqueId = pageInfo.UniqueId; +// foreach (var key in contextInfo.Attributes.AllKeys) +// { +// paramBuilder.Append($@" so_{uniqueId}.addParam(""{key}"", ""{contextInfo.Attributes[key]}"");").Append(Constants.ReturnAndNewline); +// } + +// parsedContent = $@" +//
    +// +//"; +// } +// } + +// return parsedContent; +// } +// } +//} diff --git a/SiteServer.CMS/StlParser/StlElement/StlFocusViewer.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlFocusViewer.cs similarity index 79% rename from SiteServer.CMS/StlParser/StlElement/StlFocusViewer.cs rename to net452/SiteServer.CMS/StlParser/StlElement/StlFocusViewer.cs index dc790ba82..6e8e5c61b 100644 --- a/SiteServer.CMS/StlParser/StlElement/StlFocusViewer.cs +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlFocusViewer.cs @@ -1,10 +1,13 @@ -using System.Collections.Generic; -using System.Collections.Specialized; +using System.Collections.Specialized; using System.Text; using System.Web.UI.HtmlControls; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; using SiteServer.Utils; using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Fx; using SiteServer.CMS.StlParser.Model; using SiteServer.CMS.StlParser.Parsers; using SiteServer.CMS.StlParser.Utility; @@ -12,48 +15,41 @@ namespace SiteServer.CMS.StlParser.StlElement { - [StlClass(Usage = "滚动焦点图", Description = "通过 stl:focusviewer 标签在模板中实现由 FLASH 显示的图片轮播效果", Obsolete = true)] - public static class StlFocusViewer + [StlElement(Title = "滚动焦点图")] + public class StlFocusViewer { + private StlFocusViewer() { } public const string ElementName = "stl:focusViewer"; - private static readonly Attr ChannelIndex = new Attr("channelIndex", "栏目索引"); - private static readonly Attr ChannelName = new Attr("channelName", "栏目名称"); - private static readonly Attr Scope = new Attr("scope", "范围"); - private static readonly Attr GroupChannel = new Attr("groupChannel", "指定显示的内容组"); - private static readonly Attr GroupChannelNot = new Attr("groupChannelNot", "指定不显示的内容组"); - private static readonly Attr GroupContent = new Attr("groupContent", "指定显示的内容组"); - private static readonly Attr GroupContentNot = new Attr("groupContentNot", "指定不显示的内容组"); - private static readonly Attr Tags = new Attr("tags", "指定标签"); - private static readonly Attr Order = new Attr("order", "排序"); - private static readonly Attr StartNum = new Attr("startNum", "从第几条信息开始显示"); - private static readonly Attr TotalNum = new Attr("totalNum", "标题文字数量"); - private static readonly Attr TitleWordNum = new Attr("titleWordNum", "标题文字数量"); - private static readonly Attr Where = new Attr("where", "获取滚动焦点图的条件判断"); - private static readonly Attr IsTop = new Attr("isTop", "仅显示置顶内容"); - private static readonly Attr IsRecommend = new Attr("isRecommend", "仅显示推荐内容"); - private static readonly Attr IsHot = new Attr("isHot", "仅显示热点内容"); - private static readonly Attr IsColor = new Attr("isColor", "仅显示醒目内容"); - private static readonly Attr Theme = new Attr("theme", "主题样式"); - private static readonly Attr Width = new Attr("width", "图片宽度"); - private static readonly Attr Height = new Attr("height", "图片高度"); - private static readonly Attr BgColor = new Attr("bgColor", "背景色"); - private static readonly Attr IsShowText = new Attr("isShowText", "是否显示文字标题"); - private static readonly Attr IsTopText = new Attr("isTopText", "是否文字显示在顶端"); + public const string AttributeChannelIndex = "channelIndex"; + public const string AttributeChannelName = "channelName"; + public const string AttributeScope = "scope"; + public const string AttributeGroupChannel = "groupChannel"; + public const string AttributeGroupChannelNot = "groupChannelNot"; + public const string AttributeGroupContent = "groupContent"; + public const string AttributeGroupContentNot = "groupContentNot"; + public const string AttributeTags = "tags"; + public const string AttributeOrder = "order"; + public const string AttributeStartNum = "startNum"; + public const string AttributeTotalNum = "totalNum"; + public const string AttributeTitleWordNum = "titleWordNum"; + public const string AttributeWhere = "where"; + public const string AttributeIsTop = "isTop"; + public const string AttributeIsRecommend = "isRecommend"; + public const string AttributeIsHot = "isHot"; + public const string AttributeIsColor = "isColor"; + public const string AttributeTheme = "theme"; + public const string AttributeWidth = "width"; + public const string AttributeHeight = "height"; + public const string AttributeBgColor = "bgColor"; + public const string AttributeIsShowText = "isShowText"; + public const string AttributeIsTopText = "isTopText"; public const string ThemeStyle1 = "Style1"; public const string ThemeStyle2 = "Style2"; public const string ThemeStyle3 = "Style3"; public const string ThemeStyle4 = "Style4"; - public static SortedList ThemeList => new SortedList - { - {ThemeStyle1, "样式1"}, - {ThemeStyle2, "样式2"}, - {ThemeStyle3, "样式3"}, - {ThemeStyle4, "样式4"}, - }; - //对“flash滚动焦点图”(stl:focusViewer)元素进行解析 public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) { @@ -95,87 +91,87 @@ public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) var bgColor = string.Empty; var genericControl = new HtmlGenericControl("div"); - foreach (var name in contextInfo.Attributes.Keys) + foreach (var name in contextInfo.Attributes.AllKeys) { var value = contextInfo.Attributes[name]; - if (StringUtils.EqualsIgnoreCase(name, ChannelIndex.Name)) + if (StringUtils.EqualsIgnoreCase(name, AttributeChannelIndex)) { channelIndex = value; } - else if (StringUtils.EqualsIgnoreCase(name, ChannelName.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeChannelName)) { channelName = value; } - else if (StringUtils.EqualsIgnoreCase(name, Scope.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeScope)) { scopeType = EScopeTypeUtils.GetEnumType(value); } - else if (StringUtils.EqualsIgnoreCase(name, GroupChannel.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeGroupChannel)) { groupChannel = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); } - else if (StringUtils.EqualsIgnoreCase(name, GroupChannelNot.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeGroupChannelNot)) { groupChannelNot = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); } - else if (StringUtils.EqualsIgnoreCase(name, GroupContent.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeGroupContent)) { groupContent = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); } - else if (StringUtils.EqualsIgnoreCase(name, GroupContentNot.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeGroupContentNot)) { groupContentNot = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); } - else if (StringUtils.EqualsIgnoreCase(name, Tags.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeTags)) { tags = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); } - else if (StringUtils.EqualsIgnoreCase(name, Order.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeOrder)) { - orderByString = StlDataUtility.GetContentOrderByString(pageInfo.SiteId, value, ETaxisType.OrderByTaxisDesc); + orderByString = StlDataUtility.GetContentOrderByString(value, ETaxisType.OrderByTaxisDesc); } - else if (StringUtils.EqualsIgnoreCase(name, StartNum.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeStartNum)) { startNum = TranslateUtils.ToInt(value, 1); } - else if (StringUtils.EqualsIgnoreCase(name, TotalNum.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeTotalNum)) { totalNum = TranslateUtils.ToInt(value); } - else if (StringUtils.EqualsIgnoreCase(name, TitleWordNum.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeTitleWordNum)) { titleWordNum = TranslateUtils.ToInt(value); } - else if (StringUtils.EqualsIgnoreCase(name, Where.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeWhere)) { where = value; } - else if (StringUtils.EqualsIgnoreCase(name, IsTop.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeIsTop)) { isTopExists = true; isTop = TranslateUtils.ToBool(value); } - else if (StringUtils.EqualsIgnoreCase(name, IsRecommend.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeIsRecommend)) { isRecommendExists = true; isRecommend = TranslateUtils.ToBool(value); } - else if (StringUtils.EqualsIgnoreCase(name, IsHot.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeIsHot)) { isHotExists = true; isHot = TranslateUtils.ToBool(value); } - else if (StringUtils.EqualsIgnoreCase(name, IsColor.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeIsColor)) { isColorExists = true; isColor = TranslateUtils.ToBool(value); } - else if (StringUtils.EqualsIgnoreCase(name, Theme.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeTheme)) { theme = value; } - else if (StringUtils.EqualsIgnoreCase(name, Width.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeWidth)) { if (StringUtils.EndsWithIgnoreCase(value, "px")) { @@ -183,7 +179,7 @@ public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) } imageWidth = TranslateUtils.ToInt(value); } - else if (StringUtils.EqualsIgnoreCase(name, Height.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeHeight)) { if (StringUtils.EndsWithIgnoreCase(value, "px")) { @@ -191,15 +187,15 @@ public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) } imageHeight = TranslateUtils.ToInt(value); } - else if (StringUtils.EqualsIgnoreCase(name, BgColor.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeBgColor)) { bgColor = value; } - else if (StringUtils.EqualsIgnoreCase(name, IsShowText.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeIsShowText)) { isShowText = TranslateUtils.ToBool(value, true); } - else if (StringUtils.EqualsIgnoreCase(name, IsTopText.Name)) + else if (StringUtils.EqualsIgnoreCase(name, AttributeIsTopText)) { isTopText = value; } @@ -218,9 +214,9 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, Html var channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, contextInfo.ChannelId, channelIndex, channelName); - var dataSource = StlDataUtility.GetContentsDataSource(pageInfo.SiteInfo, channelId, 0, groupContent, groupContentNot, tags, true, true, false, false, false, false, false, false, startNum, totalNum, orderByString, isTopExists, isTop, isRecommendExists, isRecommend, isHotExists, isHot, isColorExists, isColor, where, scopeType, groupChannel, groupChannelNot, null); + var minContentInfoList = StlDataUtility.GetMinContentInfoList(pageInfo.SiteInfo, channelId, 0, groupContent, groupContentNot, tags, true, true, false, false, false, false, false, startNum, totalNum, orderByString, isTopExists, isTop, isRecommendExists, isRecommend, isHotExists, isHot, isColorExists, isColor, where, scopeType, groupChannel, groupChannelNot, null); - if (dataSource != null) + if (minContentInfoList != null) { if (StringUtils.EqualsIgnoreCase(theme, ThemeStyle2)) { @@ -230,10 +226,10 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, Html var navigationUrls = new StringCollection(); var titleCollection = new StringCollection(); - foreach (var dataItem in dataSource.Tables[0].Rows) + foreach (var minContentInfo in minContentInfoList) { - var contentInfo = new ContentInfo(dataItem); - var imageUrl = contentInfo.GetString(BackgroundContentAttribute.ImageUrl); + var contentInfo = ContentManager.GetContentInfo(pageInfo.SiteInfo, minContentInfo.ChannelId, minContentInfo.Id); + var imageUrl = contentInfo.ImageUrl; if (!string.IsNullOrEmpty(imageUrl)) { @@ -285,13 +281,13 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, Html var uniqueId = "FocusViewer_" + pageInfo.UniqueId; var paramBuilder = new StringBuilder(); paramBuilder.Append( - $@"so_{uniqueId}.addParam(""quality"", ""high"");").Append(StringUtils.Constants.ReturnAndNewline); + $@"so_{uniqueId}.addParam(""quality"", ""high"");").Append(Constants.ReturnAndNewline); paramBuilder.Append( - $@"so_{uniqueId}.addParam(""wmode"", ""transparent"");").Append(StringUtils.Constants.ReturnAndNewline); + $@"so_{uniqueId}.addParam(""wmode"", ""transparent"");").Append(Constants.ReturnAndNewline); paramBuilder.Append( - $@"so_{uniqueId}.addParam(""menu"", ""false"");").Append(StringUtils.Constants.ReturnAndNewline); + $@"so_{uniqueId}.addParam(""menu"", ""false"");").Append(Constants.ReturnAndNewline); paramBuilder.Append( - $@"so_{uniqueId}.addParam(""FlashVars"", ""bcastr_file=""+files_uniqueID+""&bcastr_link=""+links_uniqueID+""&bcastr_title=""+texts_uniqueID+""&AutoPlayTime=5&TitleBgPosition={isTopText}&TitleBgColor={bgColor}&BtnDefaultColor={bgColor}"");").Append(StringUtils.Constants.ReturnAndNewline); + $@"so_{uniqueId}.addParam(""FlashVars"", ""bcastr_file=""+files_uniqueID+""&bcastr_link=""+links_uniqueID+""&bcastr_title=""+texts_uniqueID+""&AutoPlayTime=5&TitleBgPosition={isTopText}&TitleBgColor={bgColor}&BtnDefaultColor={bgColor}"");").Append(Constants.ReturnAndNewline); string scriptHtml = $@"
    @@ -317,10 +313,10 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, Html var navigationUrls = new StringCollection(); var titleCollection = new StringCollection(); - foreach (var dataItem in dataSource.Tables[0].Rows) + foreach (var minContentInfo in minContentInfoList) { - var contentInfo = new ContentInfo(dataItem); - var imageUrl = contentInfo.GetString(BackgroundContentAttribute.ImageUrl); + var contentInfo = ContentManager.GetContentInfo(pageInfo.SiteInfo, minContentInfo.ChannelId, minContentInfo.Id); + var imageUrl = contentInfo.Get(ContentAttribute.ImageUrl); if (!string.IsNullOrEmpty(imageUrl)) { @@ -349,13 +345,13 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, Html var uniqueId = "FocusViewer_" + pageInfo.UniqueId; var paramBuilder = new StringBuilder(); - paramBuilder.Append($@"so_{uniqueId}.addParam(""quality"", ""high"");").Append(StringUtils.Constants.ReturnAndNewline); - paramBuilder.Append($@"so_{uniqueId}.addParam(""wmode"", ""transparent"");").Append(StringUtils.Constants.ReturnAndNewline); - paramBuilder.Append($@"so_{uniqueId}.addParam(""allowFullScreen"", ""true"");").Append(StringUtils.Constants.ReturnAndNewline); - paramBuilder.Append($@"so_{uniqueId}.addParam(""allowScriptAccess"", ""always"");").Append(StringUtils.Constants.ReturnAndNewline); - paramBuilder.Append($@"so_{uniqueId}.addParam(""menu"", ""false"");").Append(StringUtils.Constants.ReturnAndNewline); + paramBuilder.Append($@"so_{uniqueId}.addParam(""quality"", ""high"");").Append(Constants.ReturnAndNewline); + paramBuilder.Append($@"so_{uniqueId}.addParam(""wmode"", ""transparent"");").Append(Constants.ReturnAndNewline); + paramBuilder.Append($@"so_{uniqueId}.addParam(""allowFullScreen"", ""true"");").Append(Constants.ReturnAndNewline); + paramBuilder.Append($@"so_{uniqueId}.addParam(""allowScriptAccess"", ""always"");").Append(Constants.ReturnAndNewline); + paramBuilder.Append($@"so_{uniqueId}.addParam(""menu"", ""false"");").Append(Constants.ReturnAndNewline); paramBuilder.Append( - $@"so_{uniqueId}.addParam(""flashvars"", ""pw={imageWidth}&ph={imageHeight}&Times=4000&sizes=14&umcolor=16777215&btnbg=12189697&txtcolor=16777215&urls=""+urls_uniqueID+""&imgs=""+imgs_uniqueID+""&titles=""+titles_uniqueID);").Append(StringUtils.Constants.ReturnAndNewline); + $@"so_{uniqueId}.addParam(""flashvars"", ""pw={imageWidth}&ph={imageHeight}&Times=4000&sizes=14&umcolor=16777215&btnbg=12189697&txtcolor=16777215&urls=""+urls_uniqueID+""&imgs=""+imgs_uniqueID+""&titles=""+titles_uniqueID);").Append(Constants.ReturnAndNewline); string scriptHtml = $@"
    @@ -378,10 +374,10 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, Html var imageUrls = new StringCollection(); var navigationUrls = new StringCollection(); - foreach (var dataItem in dataSource.Tables[0].Rows) + foreach (var minContentInfo in minContentInfoList) { - var contentInfo = new ContentInfo(dataItem); - var imageUrl = contentInfo.GetString(BackgroundContentAttribute.ImageUrl); + var contentInfo = ContentManager.GetContentInfo(pageInfo.SiteInfo, minContentInfo.ChannelId, minContentInfo.Id); + var imageUrl = contentInfo.Get(ContentAttribute.ImageUrl); if (!string.IsNullOrEmpty(imageUrl)) { @@ -497,10 +493,10 @@ function auto(){{ var navigationUrls = new StringCollection(); var titleCollection = new StringCollection(); - foreach (var dataItem in dataSource.Tables[0].Rows) + foreach (var minContentInfo in minContentInfoList) { - var contentInfo = new ContentInfo(dataItem); - var imageUrl = contentInfo.GetString(BackgroundContentAttribute.ImageUrl); + var contentInfo = ContentManager.GetContentInfo(pageInfo.SiteInfo, minContentInfo.ChannelId, minContentInfo.Id); + var imageUrl = contentInfo.ImageUrl; if (!string.IsNullOrEmpty(imageUrl)) { @@ -550,9 +546,7 @@ function auto(){{ var divHtml = ControlUtils.GetControlRenderHtml(genericControl); string scriptHtml = $@" - + "; scriptHtml = scriptHtml.Replace("uniqueID", uniqueId); @@ -587,4 +579,4 @@ function auto(){{ return parsedContent; } } -} +} \ No newline at end of file diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlIf.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlIf.cs new file mode 100644 index 000000000..dd97357ee --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlIf.cs @@ -0,0 +1,965 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Web.UI; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Caches.Stl; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Database.Attributes; +using SiteServer.Utils; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "条件判断", Description = "通过 stl:if 标签在模板中根据条件判断显示内容")] + public class StlIf + { + private StlIf() { } + public const string ElementName = "stl:if"; + + [StlAttribute(Title = "测试类型")] + private const string Type = nameof(Type); + + [StlAttribute(Title = "测试操作")] + private const string Op = nameof(Op); + + [StlAttribute(Title = "测试值")] + private const string Value = nameof(Value); + + [StlAttribute(Title = "所处上下文")] + private const string Context = nameof(Context); + + public const string TypeIsUserLoggin = "IsUserLoggin"; //用户是否已登录 + public const string TypeIsAdministratorLoggin = "IsAdministratorLoggin"; //管理员是否已登录 + public const string TypeIsUserOrAdministratorLoggin = "IsUserOrAdministratorLoggin"; //用户或管理员是否已登录 + private const string TypeChannelName = "ChannelName"; //栏目名称 + private const string TypeChannelIndex = "ChannelIndex"; //栏目索引 + private const string TypeTemplateName = "TemplateName"; //模板名称 + private const string TypTemplateType = "TemplateType"; //模板类型 + private const string TypeTopLevel = "TopLevel"; //栏目级别 + private const string TypeUpChannel = "UpChannel"; //上级栏目 + private const string TypeUpChannelOrSelf = "UpChannelOrSelf"; //当前栏目或上级栏目 + private const string TypeSelfChannel = "SelfChannel"; //当前栏目 + private const string TypeGroupChannel = "GroupChannel"; //栏目组名称 + private const string TypeGroupContent = "GroupContent"; //内容组名称 + private const string TypeAddDate = "AddDate"; //添加时间 + private const string TypeLastEditDate = "LastEditDate"; //最后编辑时间(仅用于判断内容) + private const string TypeItemIndex = "ItemIndex"; //当前项序号 + private const string TypeOddItem = "OddItem"; //奇数项 + + public static SortedList TypeList => new SortedList + { + {TypeIsUserLoggin, "用户是否已登录"}, + {TypeIsAdministratorLoggin, "管理员是否已登录"}, + {TypeIsUserOrAdministratorLoggin, "用户或管理员是否已登录"}, + {TypeChannelName, "栏目名称"}, + {TypeChannelIndex, "栏目索引"}, + {TypeTemplateName, "模板名称"}, + {TypTemplateType, "模板类型"}, + {TypeTopLevel, "栏目级别"}, + {TypeUpChannel, "上级栏目"}, + {TypeUpChannelOrSelf, "当前栏目或上级栏目"}, + {TypeSelfChannel, "当前栏目"}, + {TypeGroupChannel, "栏目组名称"}, + {TypeGroupContent, "内容组名称"}, + {TypeAddDate, "添加时间"}, + {TypeLastEditDate, "最后编辑时间(仅用于判断内容)"}, + {TypeItemIndex, "当前项序号"}, + {TypeOddItem, "奇数项"} + }; + + public const string OperateEmpty = "Empty"; + public const string OperateNotEmpty = "NotEmpty"; //值不为空 + public const string OperateEquals = "Equals"; //值等于 + public const string OperateNotEquals = "NotEquals"; //值不等于 + public const string OperateGreatThan = "GreatThan"; //值大于 + public const string OperateLessThan = "LessThan"; //值小于 + public const string OperateIn = "In"; //值属于 + public const string OperateNotIn = "NotIn"; //值不属于 + + public static SortedList OperateList => new SortedList + { + {OperateEmpty, "值为空"}, + {OperateNotEmpty, "值不为空"}, + {OperateEquals, "值等于"}, + {OperateNotEquals, "值不等于"}, + {OperateGreatThan, "值大于"}, + {OperateLessThan, "值小于"}, + {OperateIn, "值属于"}, + {OperateNotIn, "值不属于"} + }; + + + internal static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var testTypeStr = string.Empty; + var testOperate = string.Empty; + var testValue = string.Empty; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, Type) || StringUtils.EqualsIgnoreCase(name, "testType")) + { + testTypeStr = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Op) || StringUtils.EqualsIgnoreCase(name, "operate") || StringUtils.EqualsIgnoreCase(name, "testOperate")) + { + testOperate = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Value) || StringUtils.EqualsIgnoreCase(name, "testValue")) + { + testValue = value; + if (string.IsNullOrEmpty(testOperate)) + { + testOperate = OperateEquals; + } + } + else if (StringUtils.EqualsIgnoreCase(name, Context)) + { + contextInfo.ContextType = EContextTypeUtils.GetEnumType(value); + } + } + + if (string.IsNullOrEmpty(testOperate)) + { + testOperate = OperateNotEmpty; + } + + return ParseImpl(pageInfo, contextInfo, testTypeStr, testOperate, testValue); + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string testType, string testOperate, string testValue) + { + string successTemplateString; + string failureTemplateString; + + StlParserUtility.GetYesNo(contextInfo.InnerHtml, out successTemplateString, out failureTemplateString); + + if (StringUtils.EqualsIgnoreCase(testType, TypeIsUserLoggin) || + StringUtils.EqualsIgnoreCase(testType, TypeIsAdministratorLoggin) || + StringUtils.EqualsIgnoreCase(testType, TypeIsUserOrAdministratorLoggin)) + { + StlParserManager.ParseInnerContent(new StringBuilder(successTemplateString), pageInfo, contextInfo); + StlParserManager.ParseInnerContent(new StringBuilder(failureTemplateString), pageInfo, contextInfo); + + return TestTypeDynamic(pageInfo, contextInfo, testType, testValue, testOperate, successTemplateString, + failureTemplateString); + } + + var isSuccess = false; + if (StringUtils.EqualsIgnoreCase(testType, TypeChannelName)) + { + var channelName = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId).ChannelName; + isSuccess = TestTypeValue(testOperate, testValue, channelName); + } + else if (StringUtils.EqualsIgnoreCase(testType, TypeChannelIndex)) + { + var channelIndex = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId).IndexName; + isSuccess = TestTypeValue(testOperate, testValue, channelIndex); + } + else if (StringUtils.EqualsIgnoreCase(testType, TypeTemplateName)) + { + isSuccess = TestTypeValue(testOperate, testValue, pageInfo.TemplateInfo.TemplateName); + } + else if (StringUtils.EqualsIgnoreCase(testType, TypTemplateType)) + { + isSuccess = TestTypeValue(testOperate, testValue, pageInfo.TemplateInfo.Type.Value); + } + else if (StringUtils.EqualsIgnoreCase(testType, TypeTopLevel)) + { + var topLevel = ChannelManager.GetTopLevel(pageInfo.SiteId, contextInfo.ChannelId); + isSuccess = IsNumber(topLevel, testOperate, testValue); + } + else if (StringUtils.EqualsIgnoreCase(testType, TypeUpChannel)) + { + isSuccess = TestTypeUpChannel(pageInfo, contextInfo, testOperate, testValue); + } + else if (StringUtils.EqualsIgnoreCase(testType, TypeUpChannelOrSelf)) + { + isSuccess = TestTypeUpChannelOrSelf(pageInfo, contextInfo, testOperate, testValue); + } + else if (StringUtils.EqualsIgnoreCase(testType, TypeSelfChannel)) + { + isSuccess = pageInfo.PageChannelId == contextInfo.ChannelId; + } + else if (StringUtils.EqualsIgnoreCase(testType, TypeGroupChannel)) + { + var groupChannels = + TranslateUtils.StringCollectionToStringList( + ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId).GroupNameCollection); + isSuccess = TestTypeValues(testOperate, testValue, groupChannels); + } + else if (StringUtils.EqualsIgnoreCase(testType, TypeGroupContent)) + { + if (contextInfo.ContextType == EContextType.Content) + { + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + //var groupContents = TranslateUtils.StringCollectionToStringList(DataProvider.ContentRepository.GetValueById(tableName, contextInfo.ContentId, ContentAttribute.ContentGroupNameCollection)); + var groupContents = TranslateUtils.StringCollectionToStringList(StlContentCache.GetValue(channelInfo, contextInfo.ContentId, ContentAttribute.GroupNameCollection)); + isSuccess = TestTypeValues(testOperate, testValue, groupContents); + } + } + else if (StringUtils.EqualsIgnoreCase(testType, TypeAddDate)) + { + var addDate = GetAddDateByContext(pageInfo, contextInfo); + isSuccess = IsDateTime(addDate, testOperate, testValue); + } + else if (StringUtils.EqualsIgnoreCase(testType, TypeLastEditDate)) + { + var lastEditDate = GetLastEditDateByContext(contextInfo); + isSuccess = IsDateTime(lastEditDate, testOperate, testValue); + } + else if (StringUtils.EqualsIgnoreCase(testType, TypeItemIndex)) + { + var itemIndex = StlParserUtility.GetItemIndex(contextInfo); + isSuccess = IsNumber(itemIndex, testOperate, testValue); + } + else if (StringUtils.EqualsIgnoreCase(testType, TypeOddItem)) + { + var itemIndex = StlParserUtility.GetItemIndex(contextInfo); + isSuccess = itemIndex % 2 == 1; + } + else + { + isSuccess = TestTypeDefault(pageInfo, contextInfo, testType, testOperate, testValue); + } + + var parsedContent = isSuccess ? successTemplateString : failureTemplateString; + + if (string.IsNullOrEmpty(parsedContent)) return string.Empty; + + var innerBuilder = new StringBuilder(parsedContent); + StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); + + parsedContent = innerBuilder.ToString(); + + return parsedContent; + } + + private static bool TestTypeDefault(PageInfo pageInfo, ContextInfo contextInfo, string testType, string testOperate, + string testValue) + { + var isSuccess = false; + + var theValue = GetAttributeValueByContext(pageInfo, contextInfo, testType); + + if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotEmpty)) + { + if (!string.IsNullOrEmpty(theValue)) + { + isSuccess = true; + } + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateEmpty)) + { + if (string.IsNullOrEmpty(theValue)) + { + isSuccess = true; + } + } + else + { + if (StringUtils.IsDateTime(theValue)) + { + var dateTime = TranslateUtils.ToDateTime(theValue); + isSuccess = IsDateTime(dateTime, testOperate, testValue); + } + else if (StringUtils.IsNumber(theValue)) + { + var number = TranslateUtils.ToInt(theValue); + isSuccess = IsNumber(number, testOperate, testValue); + } + else + { + if (StringUtils.EqualsIgnoreCase(testOperate, OperateEquals)) + { + if (StringUtils.EqualsIgnoreCase(theValue, testValue)) + { + isSuccess = true; + } + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotEquals)) + { + if (!StringUtils.EqualsIgnoreCase(theValue, testValue)) + { + isSuccess = true; + } + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateGreatThan)) + { + if (StringUtils.Contains(theValue, "-")) + { + if (TranslateUtils.ToDateTime(theValue) > TranslateUtils.ToDateTime(testValue)) + { + isSuccess = true; + } + } + else + { + if (TranslateUtils.ToInt(theValue) > TranslateUtils.ToInt(testValue)) + { + isSuccess = true; + } + } + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateLessThan)) + { + if (StringUtils.Contains(theValue, "-")) + { + if (TranslateUtils.ToDateTime(theValue) < TranslateUtils.ToDateTime(testValue)) + { + isSuccess = true; + } + } + else + { + if (TranslateUtils.ToInt(theValue) < TranslateUtils.ToInt(testValue)) + { + isSuccess = true; + } + } + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateIn)) + { + var stringList = TranslateUtils.StringCollectionToStringList(testValue); + + foreach (var str in stringList) + { + if (StringUtils.EndsWithIgnoreCase(str, "*")) + { + var theStr = str.Substring(0, str.Length - 1); + if (StringUtils.StartsWithIgnoreCase(theValue, theStr)) + { + isSuccess = true; + break; + } + } + else + { + if (StringUtils.EqualsIgnoreCase(theValue, str)) + { + isSuccess = true; + break; + } + } + } + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotIn)) + { + var stringList = TranslateUtils.StringCollectionToStringList(testValue); + + var isIn = false; + foreach (var str in stringList) + { + if (StringUtils.EndsWithIgnoreCase(str, "*")) + { + var theStr = str.Substring(0, str.Length - 1); + if (StringUtils.StartsWithIgnoreCase(theValue, theStr)) + { + isIn = true; + break; + } + } + else + { + if (StringUtils.EqualsIgnoreCase(theValue, str)) + { + isIn = true; + break; + } + } + } + if (!isIn) + { + isSuccess = true; + } + } + } + } + + return isSuccess; + } + + private static string TestTypeDynamic(PageInfo pageInfo, ContextInfo contextInfo, string testType, string testValue, string testOperate, string successTemplateString, string failureTemplateString) + { + pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.StlClient); + + var ajaxDivId = StlParserUtility.GetAjaxDivId(pageInfo.UniqueId); + + var functionName = $"stlIf_{ajaxDivId}"; + + if (string.IsNullOrEmpty(successTemplateString) && string.IsNullOrEmpty(failureTemplateString)) + { + return string.Empty; + } + + var pageUrl = StlParserUtility.GetStlCurrentUrl(pageInfo.SiteInfo, contextInfo.ChannelId, contextInfo.ContentId, contextInfo.ContentInfo, pageInfo.TemplateInfo.Type, pageInfo.TemplateInfo.Id, pageInfo.IsLocal); + + var ifApiUrl = ApiRouteActionsIf.GetUrl(pageInfo.ApiUrl); + var ifApiParms = ApiRouteActionsIf.GetParameters(pageInfo.SiteId, contextInfo.ChannelId, contextInfo.ContentId, pageInfo.TemplateInfo.Id, ajaxDivId, pageUrl, testType, testValue, testOperate, successTemplateString, failureTemplateString); + + var builder = new StringBuilder(); + builder.Append($@""); + + builder.Append($@" + +"); + + return builder.ToString(); + } + + private static bool TestTypeValues(string testOperate, string testValue, List actualValues) + { + var isSuccess = false; + + if (StringUtils.EqualsIgnoreCase(testOperate, OperateEquals) || + StringUtils.EqualsIgnoreCase(testOperate, OperateIn)) + { + var stringArrayList = TranslateUtils.StringCollectionToStringList(testValue); + + foreach (string str in stringArrayList) + { + if (actualValues.Contains(str)) + { + isSuccess = true; + break; + } + } + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotEquals) || + StringUtils.EqualsIgnoreCase(testOperate, OperateNotIn)) + { + var stringArrayList = TranslateUtils.StringCollectionToStringList(testValue); + + var isIn = false; + foreach (string str in stringArrayList) + { + if (actualValues.Contains(str)) + { + isIn = true; + break; + } + } + if (!isIn) + { + isSuccess = true; + } + } + return isSuccess; + } + + private static bool TestTypeUpChannelOrSelf(PageInfo pageInfo, ContextInfo contextInfo, string testOperate, + string testValue) + { + var isSuccess = false; + + if (StringUtils.EqualsIgnoreCase(testOperate, OperateIn)) + { + var channelIndexes = TranslateUtils.StringCollectionToStringList(testValue); + var isIn = false; + foreach (var channelIndex in channelIndexes) + { + //var parentId = DataProvider.Channel.GetIdByIndexName(pageInfo.SiteId, channelIndex); + var parentId = ChannelManager.GetChannelIdByIndexName(pageInfo.SiteId, channelIndex); + if (ChannelManager.IsAncestorOrSelf(pageInfo.SiteId, parentId, pageInfo.PageChannelId)) + { + isIn = true; + break; + } + } + if (isIn) + { + isSuccess = true; + } + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotIn)) + { + var channelIndexes = TranslateUtils.StringCollectionToStringList(testValue); + var isIn = false; + foreach (var channelIndex in channelIndexes) + { + //var parentId = DataProvider.Channel.GetIdByIndexName(pageInfo.SiteId, channelIndex); + var parentId = ChannelManager.GetChannelIdByIndexName(pageInfo.SiteId, channelIndex); + if (ChannelManager.IsAncestorOrSelf(pageInfo.SiteId, parentId, pageInfo.PageChannelId)) + { + isIn = true; + break; + } + } + if (!isIn) + { + isSuccess = true; + } + } + else + { + if (string.IsNullOrEmpty(testValue)) + { + if (ChannelManager.IsAncestorOrSelf(pageInfo.SiteId, contextInfo.ChannelId, pageInfo.PageChannelId)) + { + isSuccess = true; + } + } + else + { + var channelIndexes = TranslateUtils.StringCollectionToStringList(testValue); + foreach (var channelIndex in channelIndexes) + { + //var parentId = DataProvider.Channel.GetIdByIndexName(pageInfo.SiteId, channelIndex); + var parentId = ChannelManager.GetChannelIdByIndexName(pageInfo.SiteId, channelIndex); + if (ChannelManager.IsAncestorOrSelf(pageInfo.SiteId, parentId, pageInfo.PageChannelId)) + { + isSuccess = true; + break; + } + } + } + } + return isSuccess; + } + + private static bool TestTypeUpChannel(PageInfo pageInfo, ContextInfo contextInfo, string testOperate, string testValue) + { + var isSuccess = false; + + if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotIn)) + { + var channelIndexes = TranslateUtils.StringCollectionToStringList(testValue); + var isIn = false; + foreach (var channelIndex in channelIndexes) + { + //var parentId = DataProvider.Channel.GetIdByIndexName(pageInfo.SiteId, channelIndex); + var parentId = ChannelManager.GetChannelIdByIndexName(pageInfo.SiteId, channelIndex); + if (parentId != pageInfo.PageChannelId && + ChannelManager.IsAncestorOrSelf(pageInfo.SiteId, parentId, pageInfo.PageChannelId)) + { + isIn = true; + break; + } + } + if (!isIn) + { + isSuccess = true; + } + } + else + { + if (string.IsNullOrEmpty(testValue)) + { + if (contextInfo.ChannelId != pageInfo.PageChannelId && + ChannelManager.IsAncestorOrSelf(pageInfo.SiteId, contextInfo.ChannelId, pageInfo.PageChannelId)) + { + isSuccess = true; + } + } + else + { + var channelIndexes = TranslateUtils.StringCollectionToStringList(testValue); + foreach (var channelIndex in channelIndexes) + { + //var parentId = DataProvider.Channel.GetIdByIndexName(pageInfo.SiteId, channelIndex); + var parentId = ChannelManager.GetChannelIdByIndexName(pageInfo.SiteId, channelIndex); + if (parentId != pageInfo.PageChannelId && + ChannelManager.IsAncestorOrSelf(pageInfo.SiteId, parentId, pageInfo.PageChannelId)) + { + isSuccess = true; + break; + } + } + } + } + return isSuccess; + } + + private static bool TestTypeValue(string testOperate, string testValue, string actualValue) + { + var isSuccess = false; + if (StringUtils.EqualsIgnoreCase(testOperate, OperateEquals)) + { + if (StringUtils.EndsWithIgnoreCase(testValue, "*")) + { + var theStr = testValue.Substring(0, testValue.Length - 1); + if (StringUtils.StartsWithIgnoreCase(actualValue, theStr)) + { + isSuccess = true; + } + } + else + { + if (StringUtils.EqualsIgnoreCase(actualValue, testValue)) + { + isSuccess = true; + } + } + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotEquals)) + { + if (!StringUtils.EqualsIgnoreCase(actualValue, testValue)) + { + isSuccess = true; + } + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateIn)) + { + var stringList = TranslateUtils.StringCollectionToStringList(testValue); + + foreach (var str in stringList) + { + if (StringUtils.EndsWithIgnoreCase(str, "*")) + { + var theStr = str.Substring(0, str.Length - 1); + if (StringUtils.StartsWithIgnoreCase(actualValue, theStr)) + { + isSuccess = true; + break; + } + } + else + { + if (StringUtils.EqualsIgnoreCase(actualValue, str)) + { + isSuccess = true; + break; + } + } + } + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotIn)) + { + var stringList = TranslateUtils.StringCollectionToStringList(testValue); + + var isIn = false; + foreach (var str in stringList) + { + if (StringUtils.EndsWithIgnoreCase(str, "*")) + { + var theStr = str.Substring(0, str.Length - 1); + if (StringUtils.StartsWithIgnoreCase(actualValue, theStr)) + { + isIn = true; + break; + } + } + else + { + if (StringUtils.EqualsIgnoreCase(actualValue, str)) + { + isIn = true; + break; + } + } + } + if (!isIn) + { + isSuccess = true; + } + } + return isSuccess; + } + + private static string GetAttributeValueByContext(PageInfo pageInfo, ContextInfo contextInfo, string testTypeStr) + { + string theValue = null; + if (contextInfo.ContextType == EContextType.Content) + { + theValue = GetValueFromContent(pageInfo, contextInfo, testTypeStr); + } + else if (contextInfo.ContextType == EContextType.Channel) + { + theValue = GetValueFromChannel(pageInfo, contextInfo, testTypeStr); + } + else if (contextInfo.ContextType == EContextType.SqlContent) + { + if (contextInfo.ItemContainer.SqlItem != null) + { + theValue = DataBinder.Eval(contextInfo.ItemContainer.SqlItem.DataItem, testTypeStr, "{0}"); + } + } + else if (contextInfo.ContextType == EContextType.Site) + { + if (contextInfo.ItemContainer.SiteItem != null) + { + theValue = DataBinder.Eval(contextInfo.ItemContainer.SiteItem.DataItem, testTypeStr, "{0}"); + } + } + else + { + if (contextInfo.ItemContainer != null) + { + //else if (contextInfo.ItemContainer.InputItem != null) + //{ + // theValue = DataBinder.Eval(contextInfo.ItemContainer.InputItem.DataItem, testTypeStr, "{0}"); + //} + //else if (contextInfo.ItemContainer.ContentItem != null) + //{ + // theValue = DataBinder.Eval(contextInfo.ItemContainer.ContentItem.DataItem, testTypeStr, "{0}"); + //} + //else if (contextInfo.ItemContainer.ChannelItem != null) + //{ + // theValue = DataBinder.Eval(contextInfo.ItemContainer.ChannelItem.DataItem, testTypeStr, "{0}"); + //} + if (contextInfo.ItemContainer.SqlItem != null) + { + theValue = DataBinder.Eval(contextInfo.ItemContainer.SqlItem.DataItem, testTypeStr, "{0}"); + } + } + else if (contextInfo.ContentId != 0)//获取内容 + { + theValue = GetValueFromContent(pageInfo, contextInfo, testTypeStr); + } + else if (contextInfo.ChannelId != 0)//获取栏目 + { + theValue = GetValueFromChannel(pageInfo, contextInfo, testTypeStr); + } + } + + return theValue ?? string.Empty; + } + + private static string GetValueFromChannel(PageInfo pageInfo, ContextInfo contextInfo, string testTypeStr) + { + string theValue; + + var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + + if (StringUtils.EqualsIgnoreCase(ChannelAttribute.AddDate, testTypeStr)) + { + theValue = DateUtils.GetDateAndTimeString(channel.AddDate); + } + else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.Title, testTypeStr)) + { + theValue = channel.ChannelName; + } + else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.ImageUrl, testTypeStr)) + { + theValue = channel.ImageUrl; + } + else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.Content, testTypeStr)) + { + theValue = channel.Content; + } + else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.CountOfChannels, testTypeStr)) + { + theValue = channel.ChildrenCount.ToString(); + } + else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.CountOfContents, testTypeStr)) + { + var count = ContentManager.GetCount(pageInfo.SiteInfo, channel, true); + theValue = count.ToString(); + } + else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.CountOfImageContents, testTypeStr)) + { + //var count = DataProvider.BackgroundContentDao.GetCountCheckedImage(pageInfo.SiteId, channel.ChannelId); + var count = StlContentCache.GetCountCheckedImage(pageInfo.SiteId, channel); + theValue = count.ToString(); + } + else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.LinkUrl, testTypeStr)) + { + theValue = channel.LinkUrl; + } + else + { + theValue = channel.Get(testTypeStr, string.Empty); + } + return theValue; + } + + private static string GetValueFromContent(PageInfo pageInfo, ContextInfo contextInfo, string testTypeStr) + { + string theValue; + + if (contextInfo.ContentInfo == null) + { + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + //theValue = DataProvider.ContentRepository.GetValueById(tableName, contextInfo.ContentId, testTypeStr); + theValue = StlContentCache.GetValue(channelInfo, contextInfo.ContentId, testTypeStr); + } + else + { + theValue = contextInfo.ContentInfo.Get(testTypeStr); + } + + return theValue; + } + + private static DateTime? GetAddDateByContext(PageInfo pageInfo, ContextInfo contextInfo) + { + DateTime? addDate = null; + + if (contextInfo.ContextType == EContextType.Content) + { + addDate = contextInfo.ContentInfo.AddDate; + } + else if (contextInfo.ContextType == EContextType.Channel) + { + var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + if (channel.AddDate != null) addDate = channel.AddDate.Value; + } + else + { + if (contextInfo.ItemContainer != null) + { + //else if (contextInfo.ItemContainer.InputItem != null) + //{ + // addDate = (DateTime)DataBinder.Eval(contextInfo.ItemContainer.InputItem.DataItem, InputContentAttribute.AddDate); + //} + //else if (contextInfo.ItemContainer.ContentItem != null) + //{ + // addDate = (DateTime)DataBinder.Eval(contextInfo.ItemContainer.ContentItem.DataItem, ContentAttribute.AddDate); + //} + //else if (contextInfo.ItemContainer.ChannelItem != null) + //{ + // addDate = (DateTime)DataBinder.Eval(contextInfo.ItemContainer.ChannelItem.DataItem, NodeAttribute.AddDate); + //} + if (contextInfo.ItemContainer.SqlItem != null) + { + addDate = (DateTime)DataBinder.Eval(contextInfo.ItemContainer.SqlItem.DataItem, "AddDate"); + } + } + else if (contextInfo.ContentId != 0)//获取内容 + { + addDate = contextInfo.ContentInfo.AddDate; + } + else if (contextInfo.ChannelId != 0)//获取栏目 + { + var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + if (channel.AddDate != null) addDate = channel.AddDate.Value; + } + } + + return addDate; + } + + private static DateTime? GetLastEditDateByContext(ContextInfo contextInfo) + { + DateTime? lastEditDate = null; + + if (contextInfo.ContextType == EContextType.Content) + { + lastEditDate = contextInfo.ContentInfo.LastEditDate; + } + + return lastEditDate; + } + + private static bool IsNumber(int number, string testOperate, string testValue) + { + var isSuccess = false; + + if (StringUtils.EqualsIgnoreCase(testOperate, OperateEquals)) + { + if (number == TranslateUtils.ToInt(testValue)) + { + isSuccess = true; + } + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotEquals)) + { + if (number != TranslateUtils.ToInt(testValue)) + { + isSuccess = true; + } + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateGreatThan)) + { + if (number > TranslateUtils.ToInt(testValue)) + { + isSuccess = true; + } + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateLessThan)) + { + if (number < TranslateUtils.ToInt(testValue)) + { + isSuccess = true; + } + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateIn)) + { + var intArrayList = TranslateUtils.StringCollectionToIntList(testValue); + foreach (int i in intArrayList) + { + if (i == number) + { + isSuccess = true; + break; + } + } + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotIn)) + { + var intArrayList = TranslateUtils.StringCollectionToIntList(testValue); + var isIn = false; + foreach (int i in intArrayList) + { + if (i == number) + { + isIn = true; + break; + } + } + if (!isIn) + { + isSuccess = true; + } + } + return isSuccess; + } + + private static bool IsDateTime(DateTime? dateTime, string testOperate, string testValue) + { + var isSuccess = false; + + DateTime dateTimeToTest; + + if (StringUtils.EqualsIgnoreCase("now", testValue)) + { + dateTimeToTest = DateTime.Now; + } + else if (DateUtils.IsSince(testValue)) + { + var hours = DateUtils.GetSinceHours(testValue); + dateTimeToTest = DateTime.Now.AddHours(-hours); + } + else + { + dateTimeToTest = TranslateUtils.ToDateTime(testValue); + } + + if (StringUtils.EqualsIgnoreCase(testOperate, OperateEquals) || StringUtils.EqualsIgnoreCase(testOperate, OperateIn)) + { + isSuccess = dateTime.HasValue && dateTime.Value.Date == dateTimeToTest.Date; + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateGreatThan)) + { + isSuccess = dateTime > dateTimeToTest; + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateLessThan)) + { + isSuccess = dateTime < dateTimeToTest; + } + else if (StringUtils.EqualsIgnoreCase(testOperate, OperateNotEquals) || StringUtils.EqualsIgnoreCase(testOperate, OperateNotIn)) + { + isSuccess = dateTime.HasValue && dateTime.Value.Date != dateTimeToTest.Date; + } + + return isSuccess; + } + } +} + diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlImage.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlImage.cs new file mode 100644 index 000000000..137c11601 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlImage.cs @@ -0,0 +1,259 @@ +using System.Web.UI.HtmlControls; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Caches.Stl; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Fx; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Parsers; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "显示图片", Description = "通过 stl:image 标签在模板中显示栏目或内容的图片")] + public class StlImage + { + private StlImage(){} + public const string ElementName = "stl:image"; + + [StlAttribute(Title = "栏目索引")] + private const string ChannelIndex = nameof(ChannelIndex); + + [StlAttribute(Title = "栏目名称")] + private const string ChannelName = nameof(ChannelName); + + [StlAttribute(Title = "显示父栏目")] + private const string Parent = nameof(Parent); + + [StlAttribute(Title = "上级栏目的级别")] + private const string UpLevel = nameof(UpLevel); + + [StlAttribute(Title = "从首页向下的栏目级别")] + private const string TopLevel = nameof(TopLevel); + + [StlAttribute(Title = "指定存储图片的字段")] + private const string Type = nameof(Type); + + [StlAttribute(Title = "显示字段存储的第几幅图片,默认为 1")] + private const string No = nameof(No); + + [StlAttribute(Title = "如果是引用内容,是否获取所引用内容的值")] + private const string IsOriginal = nameof(IsOriginal); + + [StlAttribute(Title = "显示的图片地址")] + private const string Src = nameof(Src); + + [StlAttribute(Title = "当指定的图片不存在时显示的图片地址")] + private const string AltSrc = nameof(AltSrc); + + public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var isGetPicUrlFromAttribute = false; + var channelIndex = string.Empty; + var channelName = string.Empty; + var upLevel = 0; + var topLevel = -1; + var type = ContentAttribute.ImageUrl; + var no = 0; + var isOriginal = false; + var src = string.Empty; + var altSrc = string.Empty; + var stlImage = new HtmlImage(); + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, ChannelIndex)) + { + channelIndex = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + if (!string.IsNullOrEmpty(channelIndex)) + { + isGetPicUrlFromAttribute = true; + } + } + else if (StringUtils.EqualsIgnoreCase(name, ChannelName)) + { + channelName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + if (!string.IsNullOrEmpty(channelName)) + { + isGetPicUrlFromAttribute = true; + } + } + else if (StringUtils.EqualsIgnoreCase(name, Parent)) + { + if (TranslateUtils.ToBool(value)) + { + upLevel = 1; + isGetPicUrlFromAttribute = true; + } + } + else if (StringUtils.EqualsIgnoreCase(name, UpLevel)) + { + upLevel = TranslateUtils.ToInt(value); + if (upLevel > 0) + { + isGetPicUrlFromAttribute = true; + } + } + else if (StringUtils.EqualsIgnoreCase(name, TopLevel)) + { + topLevel = TranslateUtils.ToInt(value); + if (topLevel >= 0) + { + isGetPicUrlFromAttribute = true; + } + } + else if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value; + } + else if (StringUtils.EqualsIgnoreCase(name, No)) + { + no = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, IsOriginal)) + { + isOriginal = TranslateUtils.ToBool(value, true); + } + else if (StringUtils.EqualsIgnoreCase(name, Src)) + { + src = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, AltSrc)) + { + altSrc = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else + { + stlImage.Attributes[name] = value; + } + } + + return ParseImpl(pageInfo, contextInfo, stlImage, isGetPicUrlFromAttribute, channelIndex, channelName, upLevel, topLevel, type, no, isOriginal, src, altSrc); + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, HtmlImage stlImage, bool isGetPicUrlFromAttribute, string channelIndex, string channelName, int upLevel, int topLevel, string type, int no, bool isOriginal, string src, string altSrc) + { + var parsedContent = string.Empty; + + var contentId = 0; + //判断是否图片地址由标签属性获得 + if (!isGetPicUrlFromAttribute) + { + contentId = contextInfo.ContentId; + } + var contextType = contextInfo.ContextType; + + var picUrl = string.Empty; + if (!string.IsNullOrEmpty(src)) + { + picUrl = src; + } + else + { + if (contextType == EContextType.Undefined) + { + contextType = contentId != 0 ? EContextType.Content : EContextType.Channel; + } + + if (contextType == EContextType.Content)//获取内容图片 + { + var contentInfo = contextInfo.ContentInfo; + + if (isOriginal) + { + if (contentInfo != null && contentInfo.ReferenceId > 0 && contentInfo.SourceId > 0) + { + var targetChannelId = contentInfo.SourceId; + //var targetSiteId = DataProvider.Channel.GetSiteId(targetChannelId); + var targetSiteId = StlChannelCache.GetSiteId(targetChannelId); + var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); + var targetNodeInfo = ChannelManager.GetChannelInfo(targetSiteId, targetChannelId); + + //var targetContentInfo = DataProvider.ContentRepository.GetContentInfo(tableStyle, tableName, contentInfo.ReferenceId); + var targetContentInfo = ContentManager.GetContentInfo(targetSiteInfo, targetNodeInfo, contentInfo.ReferenceId); + if (targetContentInfo != null && targetContentInfo.ChannelId > 0) + { + contentInfo = targetContentInfo; + } + } + } + + if (contentInfo == null) + { + contentInfo = ContentManager.GetContentInfo(pageInfo.SiteInfo, contextInfo.ChannelId, contentId); + } + + if (contentInfo != null) + { + if (no <= 1) + { + picUrl = contentInfo.Get(type); + } + else + { + var extendAttributeName = ContentAttribute.GetExtendAttributeName(type); + var extendValues = contentInfo.Get(extendAttributeName); + if (!string.IsNullOrEmpty(extendValues)) + { + var index = 2; + foreach (var extendValue in TranslateUtils.StringCollectionToStringList(extendValues)) + { + if (index == no) + { + picUrl = extendValue; + break; + } + index++; + } + } + } + } + } + else if (contextType == EContextType.Channel)//获取栏目图片 + { + var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); + + channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, channelIndex, channelName); + + var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); + + picUrl = channel.ImageUrl; + } + else if (contextType == EContextType.Each) + { + picUrl = contextInfo.ItemContainer.EachItem.DataItem as string; + } + } + + if (string.IsNullOrEmpty(picUrl)) + { + picUrl = altSrc; + } + + if (!string.IsNullOrEmpty(picUrl)) + { + var extension = PathUtils.GetExtension(picUrl); + if (EFileSystemTypeUtils.IsFlash(extension)) + { + parsedContent = StlFlash.Parse(pageInfo, contextInfo); + } + else if (EFileSystemTypeUtils.IsPlayer(extension)) + { + parsedContent = StlPlayer.Parse(pageInfo, contextInfo); + } + else + { + stlImage.Src = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, picUrl, pageInfo.IsLocal); + parsedContent = ControlUtils.GetControlRenderHtml(stlImage); + } + } + + return parsedContent; + } + } +} diff --git a/SiteServer.CMS/StlParser/StlElement/StlInclude.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlInclude.cs similarity index 79% rename from SiteServer.CMS/StlParser/StlElement/StlInclude.cs rename to net452/SiteServer.CMS/StlParser/StlElement/StlInclude.cs index 99cdd75a3..37aec691f 100644 --- a/SiteServer.CMS/StlParser/StlElement/StlInclude.cs +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlInclude.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Text; +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; using SiteServer.CMS.StlParser.Model; @@ -8,24 +9,25 @@ namespace SiteServer.CMS.StlParser.StlElement { - [StlClass(Usage = "包含文件", Description = "通过 stl:include 标签在模板中包含另一个文件,作为模板的一部分")] + [StlElement(Title = "包含文件", Description = "通过 stl:include 标签在模板中包含另一个文件,作为模板的一部分")] public class StlInclude { private StlInclude(){} public const string ElementName = "stl:include"; - private static readonly Attr File = new Attr("file", "文件路径"); + [StlAttribute(Title = "文件路径")] + private const string File = nameof(File); public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) { var file = string.Empty; var parameters = new Dictionary(); - foreach (var name in contextInfo.Attributes.Keys) + foreach (var name in contextInfo.Attributes.AllKeys) { var value = contextInfo.Attributes[name]; - if (StringUtils.EqualsIgnoreCase(name, File.Name)) + if (StringUtils.EqualsIgnoreCase(name, File)) { file = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); file = PageUtility.AddVirtualToUrl(file); @@ -46,8 +48,7 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, stri var pageParameters = pageInfo.Parameters; pageInfo.Parameters = parameters; - var content = TemplateManager.GetIncludeContent(pageInfo.SiteInfo, file, pageInfo.TemplateInfo.Charset); - content = StlParserUtility.Amp(content); + var content = TemplateManager.GetIncludeContent(pageInfo.SiteInfo, file); var contentBuilder = new StringBuilder(content); StlParserManager.ParseTemplateContent(contentBuilder, pageInfo, contextInfo); var parsedContent = contentBuilder.ToString(); diff --git a/SiteServer.CMS/StlParser/StlElement/StlItemTemplate.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlItemTemplate.cs similarity index 83% rename from SiteServer.CMS/StlParser/StlElement/StlItemTemplate.cs rename to net452/SiteServer.CMS/StlParser/StlElement/StlItemTemplate.cs index 4b0ff274e..fb31a2b7e 100644 --- a/SiteServer.CMS/StlParser/StlElement/StlItemTemplate.cs +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlItemTemplate.cs @@ -3,14 +3,19 @@ namespace SiteServer.CMS.StlParser.StlElement { - [StlClass(Usage = "列表项", Description = "通过 stl:itemTemplate 标签在模板中控制列表中每一项的显示内容及样式")] + [StlElement(Title = "列表项", Description = "通过 stl:itemTemplate 标签在模板中控制列表中每一项的显示内容及样式")] public class StlItemTemplate { public const string ElementName = "stl:itemTemplate"; - public static readonly Attr Type = new Attr("type", "列表项类型"); - public static readonly Attr Selected = new Attr("selected", "列表当前选定项类型"); - public static readonly Attr SelectedValue = new Attr("selectedValue", "当前选定项的值"); + [StlAttribute(Title = "列表项类型")] + public const string Type = nameof(Type); + + [StlAttribute(Title = "列表当前选定项类型")] + public const string Selected = nameof(Selected); + + [StlAttribute(Title = "当前选定项的值")] + public const string SelectedValue = nameof(SelectedValue); public const string TypeHeader = "header"; public const string TypeFooter = "footer"; diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlLoading.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlLoading.cs new file mode 100644 index 000000000..b3c455b80 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlLoading.cs @@ -0,0 +1,10 @@ +using SiteServer.CMS.StlParser.Model; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "载入模板", Description = "通过 stl:loading 标签在模板中创建载入中显示的内容")] + public sealed class StlLoading + { + public const string ElementName = "stl:loading"; + } +} diff --git a/SiteServer.CMS/StlParser/StlElement/StlLocation.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlLocation.cs similarity index 84% rename from SiteServer.CMS/StlParser/StlElement/StlLocation.cs rename to net452/SiteServer.CMS/StlParser/StlElement/StlLocation.cs index 847c7805b..69c8798a3 100644 --- a/SiteServer.CMS/StlParser/StlElement/StlLocation.cs +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlLocation.cs @@ -1,22 +1,33 @@ using System.Text; using System.Web.UI.HtmlControls; +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; using SiteServer.CMS.StlParser.Model; namespace SiteServer.CMS.StlParser.StlElement { - [StlClass(Usage = "当前位置", Description = "通过 stl:location 标签在模板中插入页面的当前位置")] + [StlElement(Title = "当前位置", Description = "通过 stl:location 标签在模板中插入页面的当前位置")] public class StlLocation { private StlLocation() { } public const string ElementName = "stl:location"; - private static readonly Attr Separator = new Attr("separator", "当前位置分隔符"); - private static readonly Attr Target = new Attr("target", "打开窗口的目标"); - private static readonly Attr LinkClass = new Attr("linkClass", "链接CSS样式"); - private static readonly Attr WordNum = new Attr("wordNum", "链接字数"); - private static readonly Attr IsContainSelf = new Attr("isContainSelf", "是否包含当前栏目"); + [StlAttribute(Title = "当前位置分隔符")] + private const string Separator = nameof(Separator); + + [StlAttribute(Title = "打开窗口的目标")] + private const string Target = nameof(Target); + + [StlAttribute(Title = "链接CSS样式")] + private const string LinkClass = nameof(LinkClass); + + [StlAttribute(Title = "链接字数")] + private const string WordNum = nameof(WordNum); + + [StlAttribute(Title = "是否包含当前栏目")] + private const string IsContainSelf = nameof(IsContainSelf); //对“当前位置”(stl:location)元素进行解析 public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) @@ -27,27 +38,27 @@ public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) var wordNum = 0; var isContainSelf = true; - foreach (var name in contextInfo.Attributes.Keys) + foreach (var name in contextInfo.Attributes.AllKeys) { var value = contextInfo.Attributes[name]; - if (StringUtils.EqualsIgnoreCase(name, Separator.Name)) + if (StringUtils.EqualsIgnoreCase(name, Separator)) { separator = value; } - else if (StringUtils.EqualsIgnoreCase(name, Target.Name)) + else if (StringUtils.EqualsIgnoreCase(name, Target)) { target = value; } - else if (StringUtils.EqualsIgnoreCase(name, LinkClass.Name)) + else if (StringUtils.EqualsIgnoreCase(name, LinkClass)) { linkClass = value; } - else if (StringUtils.EqualsIgnoreCase(name, WordNum.Name)) + else if (StringUtils.EqualsIgnoreCase(name, WordNum)) { wordNum = TranslateUtils.ToInt(value); } - else if (StringUtils.EqualsIgnoreCase(name, IsContainSelf.Name)) + else if (StringUtils.EqualsIgnoreCase(name, IsContainSelf)) { isContainSelf = TranslateUtils.ToBool(value); } @@ -58,9 +69,9 @@ public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string separator, string target, string linkClass, int wordNum, bool isContainSelf) { - if (!string.IsNullOrEmpty(contextInfo.InnerXml)) + if (!string.IsNullOrEmpty(contextInfo.InnerHtml)) { - separator = contextInfo.InnerXml; + separator = contextInfo.InnerHtml; } var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); @@ -93,7 +104,7 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, stri stlAnchor.Attributes.Add("class", linkClass); } var url = PageUtility.GetIndexPageUrl(pageInfo.SiteInfo, pageInfo.IsLocal); - if (url.Equals(PageUtils.UnclickedUrl)) + if (url.Equals(PageUtils.UnClickedUrl)) { stlAnchor.Target = string.Empty; } @@ -121,7 +132,7 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, stri stlAnchor.Attributes.Add("class", linkClass); } var url = PageUtility.GetChannelUrl(pageInfo.SiteInfo, currentNodeInfo, pageInfo.IsLocal); - if (url.Equals(PageUtils.UnclickedUrl)) + if (url.Equals(PageUtils.UnClickedUrl)) { stlAnchor.Target = string.Empty; } @@ -144,7 +155,7 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, stri stlAnchor.Attributes.Add("class", linkClass); } var url = PageUtility.GetChannelUrl(pageInfo.SiteInfo, currentNodeInfo, pageInfo.IsLocal); - if (url.Equals(PageUtils.UnclickedUrl)) + if (url.Equals(PageUtils.UnClickedUrl)) { stlAnchor.Target = string.Empty; } diff --git a/SiteServer.CMS/StlParser/StlElement/StlMarquee.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlMarquee.cs similarity index 90% rename from SiteServer.CMS/StlParser/StlElement/StlMarquee.cs rename to net452/SiteServer.CMS/StlParser/StlElement/StlMarquee.cs index cac9ca3db..57670edc6 100644 --- a/SiteServer.CMS/StlParser/StlElement/StlMarquee.cs +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlMarquee.cs @@ -6,16 +6,23 @@ namespace SiteServer.CMS.StlParser.StlElement { - [StlClass(Usage = "无间隔滚动", Description = "通过 stl:marquee 标签在模板中创建一个能够无间隔滚动的内容块")] + [StlElement(Title = "无间隔滚动", Description = "通过 stl:marquee 标签在模板中创建一个能够无间隔滚动的内容块")] public class StlMarquee { private StlMarquee(){} public const string ElementName = "stl:marquee"; - private static readonly Attr ScrollDelay = new Attr("scrollDelay", "滚动延迟时间(毫秒)"); - private static readonly Attr Direction = new Attr("direction", "滚动方向"); - private static readonly Attr Width = new Attr("width", "宽度"); - private static readonly Attr Height = new Attr("height", "高度"); + [StlAttribute(Title = "滚动延迟时间(毫秒)")] + private const string ScrollDelay = nameof(ScrollDelay); + + [StlAttribute(Title = "滚动方向")] + private const string Direction = nameof(Direction); + + [StlAttribute(Title = "宽度")] + private const string Width = nameof(Width); + + [StlAttribute(Title = "高度")] + private const string Height = nameof(Height); public const string DirectionVertical = "vertical"; //垂直 public const string DirectionHorizontal = "horizontal"; //水平 @@ -28,9 +35,9 @@ private StlMarquee(){} internal static string Parse(PageInfo pageInfo, ContextInfo contextInfo) { - if (string.IsNullOrEmpty(contextInfo.InnerXml)) return string.Empty; + if (string.IsNullOrEmpty(contextInfo.InnerHtml)) return string.Empty; - var innerBuilder = new StringBuilder(contextInfo.InnerXml); + var innerBuilder = new StringBuilder(contextInfo.InnerHtml); StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); var scrollHtml = innerBuilder.ToString(); @@ -39,22 +46,22 @@ internal static string Parse(PageInfo pageInfo, ContextInfo contextInfo) var width = "width:100%;"; var height = string.Empty; - foreach (var name in contextInfo.Attributes.Keys) + foreach (var name in contextInfo.Attributes.AllKeys) { var value = contextInfo.Attributes[name]; - if (StringUtils.EqualsIgnoreCase(name, ScrollDelay.Name)) + if (StringUtils.EqualsIgnoreCase(name, ScrollDelay)) { scrollDelay = TranslateUtils.ToInt(value, 40); } - else if (StringUtils.EqualsIgnoreCase(name, Direction.Name)) + else if (StringUtils.EqualsIgnoreCase(name, Direction)) { if (value.ToLower().Equals(DirectionHorizontal.ToLower())) { direction = DirectionHorizontal; } } - else if (StringUtils.EqualsIgnoreCase(name, Width.Name)) + else if (StringUtils.EqualsIgnoreCase(name, Width)) { value = value.Trim(); if (!string.IsNullOrEmpty(value)) @@ -69,7 +76,7 @@ internal static string Parse(PageInfo pageInfo, ContextInfo contextInfo) } } } - else if (StringUtils.EqualsIgnoreCase(name, Height.Name)) + else if (StringUtils.EqualsIgnoreCase(name, Height)) { value = value.Trim(); if (!string.IsNullOrEmpty(value)) diff --git a/SiteServer.CMS/StlParser/StlElement/StlNavigation.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlNavigation.cs similarity index 78% rename from SiteServer.CMS/StlParser/StlElement/StlNavigation.cs rename to net452/SiteServer.CMS/StlParser/StlElement/StlNavigation.cs index b09ded9b3..cd8fe0d41 100644 --- a/SiteServer.CMS/StlParser/StlElement/StlNavigation.cs +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlNavigation.cs @@ -1,25 +1,37 @@ using System.Collections.Generic; using System.Text; using System.Web.UI.HtmlControls; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Caches.Stl; using SiteServer.Utils; using SiteServer.CMS.Core; -using SiteServer.CMS.StlParser.Cache; +using SiteServer.CMS.Fx; using SiteServer.CMS.StlParser.Model; using SiteServer.CMS.StlParser.Utility; namespace SiteServer.CMS.StlParser.StlElement { - [StlClass(Usage = "显示导航", Description = "通过 stl:navigation 标签在模板中显示链接导航")] + [StlElement(Title = "显示导航", Description = "通过 stl:navigation 标签在模板中显示链接导航")] public class StlNavigation { private StlNavigation() { } public const string ElementName = "stl:navigation"; - private static readonly Attr Type = new Attr("type", "类型"); - private static readonly Attr EmptyText = new Attr("emptyText", "当无内容时显示的信息"); - private static readonly Attr TipText = new Attr("tipText", "导航提示信息"); - private static readonly Attr WordNum = new Attr("wordNum", "显示字数"); - private static readonly Attr IsKeyboard = new Attr("isKeyboard", "是否开启键盘,↑↓←→键分别为上下左右"); + [StlAttribute(Title = "类型")] + private const string Type = nameof(Type); + + [StlAttribute(Title = "当无内容时显示的信息")] + private const string EmptyText = nameof(EmptyText); + + [StlAttribute(Title = "导航提示信息")] + private const string TipText = nameof(TipText); + + [StlAttribute(Title = "显示字数")] + private const string WordNum = nameof(WordNum); + + [StlAttribute(Title = "是否开启键盘,↑↓←→键分别为上下左右")] + private const string IsKeyboard = nameof(IsKeyboard); public const string TypePreviousChannel = "PreviousChannel"; public const string TypeNextChannel = "NextChannel"; @@ -43,27 +55,27 @@ public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) var wordNum = 0; var isKeyboard = false; - foreach (var name in contextInfo.Attributes.Keys) + foreach (var name in contextInfo.Attributes.AllKeys) { var value = contextInfo.Attributes[name]; - if (StringUtils.EqualsIgnoreCase(name, Type.Name)) + if (StringUtils.EqualsIgnoreCase(name, Type)) { type = value; } - else if (StringUtils.EqualsIgnoreCase(name, EmptyText.Name)) + else if (StringUtils.EqualsIgnoreCase(name, EmptyText)) { emptyText = value; } - else if (StringUtils.EqualsIgnoreCase(name, TipText.Name)) + else if (StringUtils.EqualsIgnoreCase(name, TipText)) { tipText = value; } - else if (StringUtils.EqualsIgnoreCase(name, WordNum.Name)) + else if (StringUtils.EqualsIgnoreCase(name, WordNum)) { wordNum = TranslateUtils.ToInt(value); } - else if (StringUtils.EqualsIgnoreCase(name, IsKeyboard.Name)) + else if (StringUtils.EqualsIgnoreCase(name, IsKeyboard)) { isKeyboard = TranslateUtils.ToBool(value); } @@ -82,7 +94,7 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, Html string successTemplateString; string failureTemplateString; - StlInnerUtility.GetYesNo(contextInfo.InnerXml, out successTemplateString, out failureTemplateString); + StlParserUtility.GetYesNo(contextInfo.InnerHtml, out successTemplateString, out failureTemplateString); if (string.IsNullOrEmpty(successTemplateString)) { @@ -92,19 +104,19 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, Html { var taxis = nodeInfo.Taxis; var isNextChannel = !StringUtils.EqualsIgnoreCase(type, TypePreviousChannel); - //var siblingChannelId = DataProvider.ChannelDao.GetIdByParentIdAndTaxis(nodeInfo.ParentId, taxis, isNextChannel); - var siblingChannelId = Node.GetIdByParentIdAndTaxis(nodeInfo.ParentId, taxis, isNextChannel); + //var siblingChannelId = DataProvider.Channel.GetIdByParentIdAndTaxis(nodeInfo.ParentId, taxis, isNextChannel); + var siblingChannelId = StlChannelCache.GetIdByParentIdAndTaxis(nodeInfo.ParentId, taxis, isNextChannel); if (siblingChannelId != 0) { var siblingNodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, siblingChannelId); var url = PageUtility.GetChannelUrl(pageInfo.SiteInfo, siblingNodeInfo, pageInfo.IsLocal); - if (url.Equals(PageUtils.UnclickedUrl)) + if (url.Equals(PageUtils.UnClickedUrl)) { stlAnchor.Target = string.Empty; } stlAnchor.HRef = url; - if (string.IsNullOrEmpty(contextInfo.InnerXml)) + if (string.IsNullOrEmpty(contextInfo.InnerHtml)) { stlAnchor.InnerHtml = ChannelManager.GetChannelName(pageInfo.SiteId, siblingChannelId); if (wordNum > 0) @@ -115,7 +127,7 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, Html else { contextInfo.ChannelId = siblingChannelId; - var innerBuilder = new StringBuilder(contextInfo.InnerXml); + var innerBuilder = new StringBuilder(contextInfo.InnerHtml); StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); stlAnchor.InnerHtml = innerBuilder.ToString(); } @@ -127,15 +139,15 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, Html { var taxis = contextInfo.ContentInfo.Taxis; var isNextContent = !StringUtils.EqualsIgnoreCase(type, TypePreviousContent); - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, contextInfo.ChannelId); - //var siblingContentId = DataProvider.ContentDao.GetContentId(tableName, contextInfo.ChannelId, taxis, isNextContent); - var siblingContentId = Content.GetContentId(tableName, contextInfo.ChannelId, taxis, isNextContent); + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + //var siblingContentId = DataProvider.ContentRepository.GetContentId(tableName, contextInfo.ChannelId, taxis, isNextContent); + var siblingContentId = StlContentCache.GetContentId(channelInfo, taxis, isNextContent); if (siblingContentId != 0) { - //var siblingContentInfo = DataProvider.ContentDao.GetContentInfo(tableStyle, tableName, siblingContentId); - var siblingContentInfo = Content.GetContentInfo(tableName, siblingContentId); + //var siblingContentInfo = DataProvider.ContentRepository.GetContentInfo(tableStyle, tableName, siblingContentId); + var siblingContentInfo = ContentManager.GetContentInfo(pageInfo.SiteInfo, contextInfo.ChannelId, siblingContentId); var url = PageUtility.GetContentUrl(pageInfo.SiteInfo, siblingContentInfo, pageInfo.IsLocal); - if (url.Equals(PageUtils.UnclickedUrl)) + if (url.Equals(PageUtils.UnClickedUrl)) { stlAnchor.Target = string.Empty; } @@ -157,7 +169,7 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, Html pageInfo.BodyCodes[nextOrPrevious] = scriptContent.ToString(); } - if (string.IsNullOrEmpty(contextInfo.InnerXml)) + if (string.IsNullOrEmpty(contextInfo.InnerHtml)) { stlAnchor.InnerHtml = siblingContentInfo.Title; if (wordNum > 0) @@ -167,7 +179,7 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, Html } else { - var innerBuilder = new StringBuilder(contextInfo.InnerXml); + var innerBuilder = new StringBuilder(contextInfo.InnerHtml); contextInfo.ContentId = siblingContentId; StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); stlAnchor.InnerHtml = innerBuilder.ToString(); @@ -189,8 +201,8 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, Html { var taxis = nodeInfo.Taxis; var isNextChannel = !StringUtils.EqualsIgnoreCase(type, TypePreviousChannel); - //var siblingChannelId = DataProvider.ChannelDao.GetIdByParentIdAndTaxis(nodeInfo.ParentId, taxis, isNextChannel); - var siblingChannelId = Node.GetIdByParentIdAndTaxis(nodeInfo.ParentId, taxis, isNextChannel); + //var siblingChannelId = DataProvider.Channel.GetIdByParentIdAndTaxis(nodeInfo.ParentId, taxis, isNextChannel); + var siblingChannelId = StlChannelCache.GetIdByParentIdAndTaxis(nodeInfo.ParentId, taxis, isNextChannel); if (siblingChannelId != 0) { isSuccess = true; @@ -204,9 +216,9 @@ private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, Html { var taxis = contextInfo.ContentInfo.Taxis; var isNextContent = !StringUtils.EqualsIgnoreCase(type, TypePreviousContent); - var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, contextInfo.ChannelId); - //var siblingContentId = DataProvider.ContentDao.GetContentId(tableName, contextInfo.ChannelId, taxis, isNextContent); - var siblingContentId = Content.GetContentId(tableName, contextInfo.ChannelId, taxis, isNextContent); + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + //var siblingContentId = DataProvider.ContentRepository.GetContentId(tableName, contextInfo.ChannelId, taxis, isNextContent); + var siblingContentId = StlContentCache.GetContentId(channelInfo, taxis, isNextContent); if (siblingContentId != 0) { isSuccess = true; diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlNo.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlNo.cs new file mode 100644 index 000000000..8c039c66c --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlNo.cs @@ -0,0 +1,11 @@ +using SiteServer.CMS.StlParser.Model; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "失败模板", Description = "通过 stl:no 标签在模板中显示失败模板")] + public sealed class StlNo + { + public const string ElementName = "stl:no"; + public const string ElementName2 = "stl:failuretemplate"; + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlPageChannels.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlPageChannels.cs new file mode 100644 index 000000000..f7c34693b --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlPageChannels.cs @@ -0,0 +1,180 @@ +using System; +using System.Data; +using System.Web.UI.WebControls; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "翻页栏目列表", Description = "通过 stl:pageChannels 标签在模板中显示翻页栏目列表")] + public class StlPageChannels : StlChannels + { + public new const string ElementName = "stl:pageChannels"; + + [StlAttribute(Title = "每页显示的栏目数目")] + private const string PageNum = nameof(PageNum); + + private readonly string _stlPageChannelsElement; + private readonly PageInfo _pageInfo; + private readonly ContextInfo _contextInfo; + private readonly DataSet _dataSet; + + public StlPageChannels(string stlPageChannelsElement, PageInfo pageInfo, ContextInfo contextInfo) + { + _stlPageChannelsElement = stlPageChannelsElement; + + _stlPageChannelsElement = stlPageChannelsElement; + _pageInfo = pageInfo; + var stlElementInfo = StlParserUtility.ParseStlElement(stlPageChannelsElement); + + _contextInfo = contextInfo.Clone(stlPageChannelsElement, stlElementInfo.InnerHtml, stlElementInfo.Attributes); + + DisplayInfo = ListInfo.GetListInfo(pageInfo, _contextInfo, EContextType.Channel); + + var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, _contextInfo.ChannelId, DisplayInfo.UpLevel, DisplayInfo.TopLevel); + + channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, DisplayInfo.ChannelIndex, DisplayInfo.ChannelName); + + var isTotal = TranslateUtils.ToBool(DisplayInfo.Others.Get(IsTotal)); + + if (TranslateUtils.ToBool(DisplayInfo.Others.Get(IsAllChildren))) + { + DisplayInfo.Scope = EScopeType.Descendant; + } + + _dataSet = StlDataUtility.GetPageChannelsDataSet(pageInfo.SiteId, channelId, DisplayInfo.GroupChannel, DisplayInfo.GroupChannelNot, DisplayInfo.IsImageExists, DisplayInfo.IsImage, DisplayInfo.StartNum, DisplayInfo.TotalNum, DisplayInfo.OrderByString, DisplayInfo.Scope, isTotal, DisplayInfo.Where); + } + + + public int GetPageCount(out int totalNum) + { + var pageCount = 1; + totalNum = 0;//数据库中实际的内容数目 + if (_dataSet == null) return pageCount; + + totalNum = _dataSet.Tables[0].DefaultView.Count; + if (DisplayInfo.PageNum != 0 && DisplayInfo.PageNum < totalNum)//需要翻页 + { + pageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(totalNum) / Convert.ToDouble(DisplayInfo.PageNum)));//需要生成的总页数 + } + return pageCount; + } + + public ListInfo DisplayInfo { get; } + + public string Parse(int currentPageIndex, int pageCount) + { + var parsedContent = string.Empty; + + _contextInfo.PageItemIndex = currentPageIndex * DisplayInfo.PageNum; + + try + { + if (_dataSet != null) + { + var objPage = new PagedDataSource { DataSource = _dataSet.Tables[0].DefaultView }; //分页类 + + if (pageCount > 1) + { + objPage.AllowPaging = true; + objPage.PageSize = DisplayInfo.PageNum;//每页显示的项数 + } + else + { + objPage.AllowPaging = false; + } + + objPage.CurrentPageIndex = currentPageIndex;//当前页的索引 + + + if (DisplayInfo.Layout == ELayout.None) + { + var rptContents = new Repeater + { + ItemTemplate = + new RepeaterTemplate(DisplayInfo.ItemTemplate, DisplayInfo.SelectedItems, + DisplayInfo.SelectedValues, DisplayInfo.SeparatorRepeatTemplate, + DisplayInfo.SeparatorRepeat, _pageInfo, EContextType.Channel, _contextInfo) + }; + + if (!string.IsNullOrEmpty(DisplayInfo.HeaderTemplate)) + { + rptContents.HeaderTemplate = new SeparatorTemplate(DisplayInfo.HeaderTemplate); + } + if (!string.IsNullOrEmpty(DisplayInfo.FooterTemplate)) + { + rptContents.FooterTemplate = new SeparatorTemplate(DisplayInfo.FooterTemplate); + } + if (!string.IsNullOrEmpty(DisplayInfo.SeparatorTemplate)) + { + rptContents.SeparatorTemplate = new SeparatorTemplate(DisplayInfo.SeparatorTemplate); + } + if (!string.IsNullOrEmpty(DisplayInfo.AlternatingItemTemplate)) + { + rptContents.AlternatingItemTemplate = new RepeaterTemplate(DisplayInfo.AlternatingItemTemplate, DisplayInfo.SelectedItems, DisplayInfo.SelectedValues, DisplayInfo.SeparatorRepeatTemplate, DisplayInfo.SeparatorRepeat, _pageInfo, EContextType.Channel, _contextInfo); + } + + rptContents.DataSource = objPage; + rptContents.DataBind(); + + if (rptContents.Items.Count > 0) + { + parsedContent = ControlUtils.GetControlRenderHtml(rptContents); + } + } + else + { + var pdlContents = new ParsedDataList(); + + //设置显示属性 + TemplateUtility.PutListInfoToMyDataList(pdlContents, DisplayInfo); + + //设置列表模板 + pdlContents.ItemTemplate = new DataListTemplate(DisplayInfo.ItemTemplate, DisplayInfo.SelectedItems, DisplayInfo.SelectedValues, DisplayInfo.SeparatorRepeatTemplate, DisplayInfo.SeparatorRepeat, _pageInfo, EContextType.Channel, _contextInfo); + if (!string.IsNullOrEmpty(DisplayInfo.HeaderTemplate)) + { + pdlContents.HeaderTemplate = new SeparatorTemplate(DisplayInfo.HeaderTemplate); + } + if (!string.IsNullOrEmpty(DisplayInfo.FooterTemplate)) + { + pdlContents.FooterTemplate = new SeparatorTemplate(DisplayInfo.FooterTemplate); + } + if (!string.IsNullOrEmpty(DisplayInfo.SeparatorTemplate)) + { + pdlContents.SeparatorTemplate = new SeparatorTemplate(DisplayInfo.SeparatorTemplate); + } + if (!string.IsNullOrEmpty(DisplayInfo.AlternatingItemTemplate)) + { + pdlContents.AlternatingItemTemplate = new DataListTemplate(DisplayInfo.AlternatingItemTemplate, DisplayInfo.SelectedItems, DisplayInfo.SelectedValues, DisplayInfo.SeparatorRepeatTemplate, DisplayInfo.SeparatorRepeat, _pageInfo, EContextType.Channel, _contextInfo); + } + + pdlContents.DataSource = objPage; + pdlContents.DataKeyField = ChannelAttribute.Id; + pdlContents.DataBind(); + + if (pdlContents.Items.Count > 0) + { + parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); + } + } + } + } + catch (Exception ex) + { + parsedContent = LogUtils.AddStlErrorLog(_pageInfo, ElementName, _stlPageChannelsElement, ex); + } + + //还原翻页为0,使得其他列表能够正确解析ItemIndex + _contextInfo.PageItemIndex = 0; + + return parsedContent; + } + } + +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlPageContents.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlPageContents.cs new file mode 100644 index 000000000..89eed7f64 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlPageContents.cs @@ -0,0 +1,262 @@ +using System; +using System.Text; +using System.Web.UI.WebControls; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches.Stl; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "翻页内容列表", Description = "通过 stl:pageContents 标签在模板中显示翻页内容列表")] + public class StlPageContents : StlContents + { + public new const string ElementName = "stl:pageContents"; + + [StlAttribute(Title = "每页显示的内容数目")] + public const string PageNum = nameof(PageNum); + + [StlAttribute(Title = "翻页中生成的静态页面最大数,剩余页面将动态获取")] + public const string MaxPage = nameof(MaxPage); + + private readonly string _stlPageContentsElement; + private readonly PageInfo _pageInfo; + private readonly ContextInfo _contextInfo; + private readonly ListInfo _listInfo; + private readonly string _sqlString; + + public StlPageContents(string stlPageContentsElement, PageInfo pageInfo, ContextInfo contextInfo) + { + _stlPageContentsElement = stlPageContentsElement; + _pageInfo = pageInfo; + _contextInfo = contextInfo; + + var stlElementInfo = StlParserUtility.ParseStlElement(stlPageContentsElement); + + _contextInfo = contextInfo.Clone(stlPageContentsElement, stlElementInfo.InnerHtml, stlElementInfo.Attributes); + + _listInfo = ListInfo.GetListInfo(_pageInfo, _contextInfo, EContextType.Content); + + var channelId = StlDataUtility.GetChannelIdByLevel(_pageInfo.SiteId, _contextInfo.ChannelId, _listInfo.UpLevel, _listInfo.TopLevel); + + channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(_pageInfo.SiteId, channelId, _listInfo.ChannelIndex, _listInfo.ChannelName); + + _sqlString = StlDataUtility.GetStlPageContentsSqlString(_pageInfo.SiteInfo, channelId, _listInfo); + } + + //API StlActionsSearchController调用 + public StlPageContents(string stlPageContentsElement, PageInfo pageInfo, ContextInfo contextInfo, int pageNum, string tableName, string whereString) + { + _pageInfo = pageInfo; + _contextInfo = contextInfo; + + var stlElementInfo = StlParserUtility.ParseStlElement(stlPageContentsElement); + _contextInfo = contextInfo.Clone(stlPageContentsElement, stlElementInfo.InnerHtml, stlElementInfo.Attributes); + + _listInfo = ListInfo.GetListInfo(_pageInfo, _contextInfo, EContextType.Content); + + _listInfo.Scope = EScopeType.All; + + _listInfo.Where += whereString; + if (pageNum > 0) + { + _listInfo.PageNum = pageNum; + } + + _sqlString = StlDataUtility.GetPageContentsSqlStringBySearch(tableName, _listInfo.GroupContent, _listInfo.GroupContentNot, _listInfo.IsImageExists, _listInfo.IsImage, _listInfo.IsVideoExists, _listInfo.IsVideo, _listInfo.IsFileExists, _listInfo.IsFile, _listInfo.StartNum, _listInfo.TotalNum, _listInfo.OrderByString, _listInfo.IsTopExists, _listInfo.IsTop, _listInfo.IsRecommendExists, _listInfo.IsRecommend, _listInfo.IsHotExists, _listInfo.IsHot, _listInfo.IsColorExists, _listInfo.IsColor, _listInfo.Where); + } + + public int GetPageCount(out int totalNum) + { + totalNum = 0; + var pageCount = 1; + try + { + //totalNum = DatabaseApi.Instance.GetPageTotalCount(SqlString); + totalNum = StlDatabaseCache.GetPageTotalCount(_sqlString); + if (_listInfo.PageNum != 0 && _listInfo.PageNum < totalNum)//需要翻页 + { + pageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(totalNum) / Convert.ToDouble(_listInfo.PageNum)));//需要生成的总页数 + } + } + catch + { + // ignored + } + return pageCount; + } + + public string Parse(int totalNum, int currentPageIndex, int pageCount, bool isStatic) + { + if (isStatic) + { + var maxPage = _listInfo.MaxPage; + if (maxPage == 0) + { + maxPage = _pageInfo.SiteInfo.CreateStaticMaxPage; + } + if (maxPage > 0 && currentPageIndex + 1 > maxPage) + { + return ParseDynamic(totalNum, currentPageIndex, pageCount); + } + } + + var parsedContent = string.Empty; + + _contextInfo.PageItemIndex = currentPageIndex * _listInfo.PageNum; + + try + { + if (!string.IsNullOrEmpty(_sqlString)) + { + //var pageSqlString = DatabaseApi.Instance.GetPageSqlString(SqlString, ListInfo.OrderByString, totalNum, ListInfo.PageNum, currentPageIndex); + var pageSqlString = StlDatabaseCache.GetStlPageSqlString(_sqlString, _listInfo.OrderByString, totalNum, _listInfo.PageNum, currentPageIndex); + + var dataSource = DataProvider.DatabaseApi.GetDataSource(pageSqlString); + + if (_listInfo.Layout == ELayout.None) + { + var rptContents = new Repeater(); + + if (!string.IsNullOrEmpty(_listInfo.HeaderTemplate)) + { + rptContents.HeaderTemplate = new SeparatorTemplate(_listInfo.HeaderTemplate); + } + if (!string.IsNullOrEmpty(_listInfo.FooterTemplate)) + { + rptContents.FooterTemplate = new SeparatorTemplate(_listInfo.FooterTemplate); + } + if (!string.IsNullOrEmpty(_listInfo.SeparatorTemplate)) + { + rptContents.SeparatorTemplate = new SeparatorTemplate(_listInfo.SeparatorTemplate); + } + if (!string.IsNullOrEmpty(_listInfo.AlternatingItemTemplate)) + { + rptContents.AlternatingItemTemplate = new RepeaterTemplate(_listInfo.AlternatingItemTemplate, _listInfo.SelectedItems, _listInfo.SelectedValues, _listInfo.SeparatorRepeatTemplate, _listInfo.SeparatorRepeat, _pageInfo, EContextType.Content, _contextInfo); + } + + rptContents.ItemTemplate = new RepeaterTemplate(_listInfo.ItemTemplate, _listInfo.SelectedItems, _listInfo.SelectedValues, _listInfo.SeparatorRepeatTemplate, _listInfo.SeparatorRepeat, _pageInfo, EContextType.Content, _contextInfo); + + rptContents.DataSource = dataSource; + rptContents.DataBind(); + + if (rptContents.Items.Count > 0) + { + parsedContent = ControlUtils.GetControlRenderHtml(rptContents); + } + } + else + { + var pdlContents = new ParsedDataList(); + + //设置显示属性 + TemplateUtility.PutListInfoToMyDataList(pdlContents, _listInfo); + + pdlContents.ItemTemplate = new DataListTemplate(_listInfo.ItemTemplate, _listInfo.SelectedItems, _listInfo.SelectedValues, _listInfo.SeparatorRepeatTemplate, _listInfo.SeparatorRepeat, _pageInfo, EContextType.Content, _contextInfo); + if (!string.IsNullOrEmpty(_listInfo.HeaderTemplate)) + { + pdlContents.HeaderTemplate = new SeparatorTemplate(_listInfo.HeaderTemplate); + } + if (!string.IsNullOrEmpty(_listInfo.FooterTemplate)) + { + pdlContents.FooterTemplate = new SeparatorTemplate(_listInfo.FooterTemplate); + } + if (!string.IsNullOrEmpty(_listInfo.SeparatorTemplate)) + { + pdlContents.SeparatorTemplate = new SeparatorTemplate(_listInfo.SeparatorTemplate); + } + if (!string.IsNullOrEmpty(_listInfo.AlternatingItemTemplate)) + { + pdlContents.AlternatingItemTemplate = new DataListTemplate(_listInfo.AlternatingItemTemplate, _listInfo.SelectedItems, _listInfo.SelectedValues, _listInfo.SeparatorRepeatTemplate, _listInfo.SeparatorRepeat, _pageInfo, EContextType.Content, _contextInfo); + } + + pdlContents.DataSource = dataSource; + pdlContents.DataKeyField = ContentAttribute.Id; + pdlContents.DataBind(); + + if (pdlContents.Items.Count > 0) + { + parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); + } + } + } + } + catch (Exception ex) + { + parsedContent = LogUtils.AddStlErrorLog(_pageInfo, ElementName, _stlPageContentsElement, ex); + } + + //还原翻页为0,使得其他列表能够正确解析ItemIndex + _contextInfo.PageItemIndex = 0; + return parsedContent; + } + + private string ParseDynamic(int totalNum, int currentPageIndex, int pageCount) + { + var loading = _listInfo.LoadingTemplate; + if (string.IsNullOrEmpty(loading)) + { + loading = @"
    + 载入中,请稍后... +
    "; + } + + _pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.Jquery); + + var ajaxDivId = StlParserUtility.GetAjaxDivId(_pageInfo.UniqueId); + var apiUrl = ApiRouteActionsPageContents.GetUrl(_pageInfo.ApiUrl); + var apiParameters = ApiRouteActionsPageContents.GetParameters(_pageInfo.SiteId, _pageInfo.PageChannelId, _pageInfo.TemplateInfo.Id, totalNum, pageCount, currentPageIndex, _stlPageContentsElement); + + var builder = new StringBuilder(); + builder.Append($@"
    "); + builder.Append($@"
    {loading}
    "); + builder.Append($@"
    {string.Empty}
    "); + builder.Append("
    "); + + builder.Append($@" + +"); + + return builder.ToString(); + } + } +} \ No newline at end of file diff --git a/SiteServer.CMS/StlParser/StlElement/StlPageItem.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlPageItem.cs similarity index 81% rename from SiteServer.CMS/StlParser/StlElement/StlPageItem.cs rename to net452/SiteServer.CMS/StlParser/StlElement/StlPageItem.cs index cb07b7cbf..8eacad018 100644 --- a/SiteServer.CMS/StlParser/StlElement/StlPageItem.cs +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlPageItem.cs @@ -3,31 +3,51 @@ using System.Text; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; -using System.Xml; -using SiteServer.Utils; +using SiteServer.CMS.Caches; using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Utils; using SiteServer.CMS.StlParser.Model; using SiteServer.CMS.StlParser.Utility; namespace SiteServer.CMS.StlParser.StlElement { - [StlClass(Usage = "翻页项", Description = "通过 stl:pageItem 标签在模板中显示翻页项(上一页、下一页、当前页、页跳转、页导航等)")] + [StlElement(Title = "翻页项", Description = "通过 stl:pageItem 标签在模板中显示翻页项(上一页、下一页、当前页、页跳转、页导航等)")] public class StlPageItem { private StlPageItem() { } public const string ElementName = "stl:pageItem"; - private static readonly Attr Type = new Attr("type", "类型"); - private static readonly Attr Text = new Attr("text", "显示的文字"); - private static readonly Attr LinkClass = new Attr("linkClass", "链接CSS样式"); - private static readonly Attr TextClass = new Attr("textClass", "文字CSS样式"); - private static readonly Attr ListNum = new Attr("listNum", "页导航或页跳转显示链接数"); - private static readonly Attr ListEllipsis = new Attr("listEllipsis", "页导航或页跳转链接太多时显示的省略号"); - private static readonly Attr HasLr = new Attr("hasLr", "页码导航是否包含左右字符"); - private static readonly Attr LStr = new Attr("lStr", "页面左字符"); - private static readonly Attr RStr = new Attr("rStr", "页面右字符"); - private static readonly Attr AlwaysA = new Attr("alwaysA", "页码总是超链接,包括无连接时"); + [StlAttribute(Title = "类型")] + private const string Type = nameof(Type); + + [StlAttribute(Title = "显示的文字")] + private const string Text = nameof(Text); + + [StlAttribute(Title = "链接CSS样式")] + private const string LinkClass = nameof(LinkClass); + + [StlAttribute(Title = "文字CSS样式")] + private const string TextClass = nameof(TextClass); + + [StlAttribute(Title = "页导航或页跳转显示链接数")] + private const string ListNum = nameof(ListNum); + + [StlAttribute(Title = "页导航或页跳转链接太多时显示的省略号")] + private const string ListEllipsis = nameof(ListEllipsis); + + [StlAttribute(Title = "页码导航是否包含左右字符")] + private const string HasLr = nameof(HasLr); + + [StlAttribute(Title = "页面左字符")] + private const string LStr = nameof(LStr); + + [StlAttribute(Title = "页面右字符")] + private const string RStr = nameof(RStr); + + [StlAttribute(Title = "页码总是超链接,包括无连接时")] + private const string AlwaysA = nameof(AlwaysA); public const string TypePreviousPage = "PreviousPage"; //上一页 public const string TypeNextPage = "NextPage"; //下一页 @@ -53,16 +73,14 @@ private StlPageItem() { } }; //对“翻页项”(pageItem)元素进行解析,此元素在生成页面时单独解析,不包含在ParseStlElement方法中。 - public static string ParseElement(string stlElement, PageInfo pageInfo, int channelId, int contentId, int currentPageIndex, int pageCount, int totalNum, bool isXmlContent, EContextType contextType) + public static string ParseElement(string stlElement, PageInfo pageInfo, int channelId, int contentId, int currentPageIndex, int pageCount, int totalNum, EContextType contextType) { var parsedContent = string.Empty; try { - var xmlDocument = StlParserUtility.GetXmlDocument(stlElement, isXmlContent); - XmlNode node = xmlDocument.DocumentElement; - node = node?.FirstChild; - var label = node?.Name; - if (!StringUtils.EqualsIgnoreCase(label, ElementName)) return string.Empty; + var stlElementInfo = StlParserUtility.ParseStlElement(stlElement); + + if (!StringUtils.EqualsIgnoreCase(stlElementInfo.Name, ElementName)) return string.Empty; var text = string.Empty; var type = string.Empty; @@ -75,79 +93,72 @@ public static string ParseElement(string stlElement, PageInfo pageInfo, int chan var lStr = string.Empty; var rStr = string.Empty; var alwaysA = true; - var attributes = new Dictionary(); + var attributes = TranslateUtils.NewIgnoreCaseNameValueCollection(); - var ie = node?.Attributes?.GetEnumerator(); - if (ie != null) + foreach (var name in stlElementInfo.Attributes.AllKeys) { - while (ie.MoveNext()) - { - var attr = (XmlAttribute)ie.Current; - var name = attr.Name; + var value = stlElementInfo.Attributes[name]; - if (StringUtils.EqualsIgnoreCase(name, Type.Name)) - { - type = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, Text.Name)) - { - text = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, ListNum.Name)) - { - listNum = TranslateUtils.ToInt(attr.Value, 9); - } - else if (StringUtils.EqualsIgnoreCase(name, ListEllipsis.Name)) - { - listEllipsis = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, LinkClass.Name)) - { - linkClass = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, TextClass.Name)) - { - textClass = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, HasLr.Name)) - { - hasLr = TranslateUtils.ToBool(attr.Value); - } - else if (StringUtils.EqualsIgnoreCase(name, LStr.Name)) - { - lStr = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, RStr.Name)) - { - rStr = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, AlwaysA.Name)) - { - alwaysA = TranslateUtils.ToBool(attr.Value); - } - else - { - attributes[name] = attr.Value; - } + if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Text)) + { + text = value; + } + else if (StringUtils.EqualsIgnoreCase(name, ListNum)) + { + listNum = TranslateUtils.ToInt(value, 9); + } + else if (StringUtils.EqualsIgnoreCase(name, ListEllipsis)) + { + listEllipsis = value; + } + else if (StringUtils.EqualsIgnoreCase(name, LinkClass)) + { + linkClass = value; + } + else if (StringUtils.EqualsIgnoreCase(name, TextClass)) + { + textClass = value; + } + else if (StringUtils.EqualsIgnoreCase(name, HasLr)) + { + hasLr = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, LStr)) + { + lStr = value; + } + else if (StringUtils.EqualsIgnoreCase(name, RStr)) + { + rStr = value; + } + else if (StringUtils.EqualsIgnoreCase(name, AlwaysA)) + { + alwaysA = TranslateUtils.ToBool(value); + } + else + { + attributes[name] = value; } } - string successTemplateString; - string failureTemplateString; - StlInnerUtility.GetYesNo(node.InnerXml, out successTemplateString, out failureTemplateString); - if (!string.IsNullOrEmpty(node.InnerXml) && string.IsNullOrEmpty(failureTemplateString)) + StlParserUtility.GetYesNo(stlElementInfo.InnerHtml, out var successTemplateString, out var failureTemplateString); + if (!string.IsNullOrEmpty(stlElementInfo.InnerHtml) && string.IsNullOrEmpty(failureTemplateString)) { failureTemplateString = successTemplateString; } //以下三个对象仅isChannelPage=true时需要 - ChannelInfo nodeInfo = null; + ChannelInfo channelInfo = null; string pageUrl; if (contextType == EContextType.Channel) { - nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); - pageUrl = PagerUtility.GetUrlInChannelPage(type, pageInfo.SiteInfo, nodeInfo, 0, currentPageIndex, pageCount, pageInfo.IsLocal); + channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); + pageUrl = PagerUtility.GetUrlInChannelPage(type, pageInfo.SiteInfo, channelInfo, 0, currentPageIndex, pageCount, pageInfo.IsLocal); } else { @@ -171,7 +182,7 @@ public static string ParseElement(string stlElement, PageInfo pageInfo, int chan } else { - pageUrl = PageUtils.UnclickedUrl; + pageUrl = PageUtils.UnClickedUrl; } } else if (StringUtils.EqualsIgnoreCase(type, TypeLastPage)) @@ -186,7 +197,7 @@ public static string ParseElement(string stlElement, PageInfo pageInfo, int chan } else { - pageUrl = PageUtils.UnclickedUrl; + pageUrl = PageUtils.UnClickedUrl; } } else if (StringUtils.EqualsIgnoreCase(type, TypePreviousPage)) @@ -201,7 +212,7 @@ public static string ParseElement(string stlElement, PageInfo pageInfo, int chan } else { - pageUrl = PageUtils.UnclickedUrl; + pageUrl = PageUtils.UnClickedUrl; } } else if (StringUtils.EqualsIgnoreCase(type, TypeNextPage)) @@ -216,7 +227,7 @@ public static string ParseElement(string stlElement, PageInfo pageInfo, int chan } else { - pageUrl = PageUtils.UnclickedUrl; + pageUrl = PageUtils.UnClickedUrl; } } @@ -340,7 +351,7 @@ public static string ParseElement(string stlElement, PageInfo pageInfo, int chan //pre ellipsis if (index + pageLength < currentPageIndex + 1 && !string.IsNullOrEmpty(listEllipsis)) { - pageUrl = contextType == EContextType.Channel ? PagerUtility.GetUrlInChannelPage(type, pageInfo.SiteInfo, nodeInfo, index, currentPageIndex, pageCount, pageInfo.IsLocal) : PagerUtility.GetUrlInContentPage(type, pageInfo.SiteInfo, channelId, contentId, index, currentPageIndex, pageCount, pageInfo.IsLocal); + pageUrl = contextType == EContextType.Channel ? PagerUtility.GetUrlInChannelPage(type, pageInfo.SiteInfo, channelInfo, index, currentPageIndex, pageCount, pageInfo.IsLocal) : PagerUtility.GetUrlInContentPage(type, pageInfo.SiteInfo, channelId, contentId, index, currentPageIndex, pageCount, pageInfo.IsLocal); pageBuilder.Append(!string.IsNullOrEmpty(successTemplateString) ? GetParsedContent(successTemplateString, pageUrl, listEllipsis, pageInfo) @@ -351,7 +362,7 @@ public static string ParseElement(string stlElement, PageInfo pageInfo, int chan { if (currentPageIndex + 1 != index) { - pageUrl = contextType == EContextType.Channel ? PagerUtility.GetUrlInChannelPage(type, pageInfo.SiteInfo, nodeInfo, index, currentPageIndex, pageCount, pageInfo.IsLocal) : PagerUtility.GetUrlInContentPage(type, pageInfo.SiteInfo, channelId, contentId, index, currentPageIndex, pageCount, pageInfo.IsLocal); + pageUrl = contextType == EContextType.Channel ? PagerUtility.GetUrlInChannelPage(type, pageInfo.SiteInfo, channelInfo, index, currentPageIndex, pageCount, pageInfo.IsLocal) : PagerUtility.GetUrlInContentPage(type, pageInfo.SiteInfo, channelId, contentId, index, currentPageIndex, pageCount, pageInfo.IsLocal); if (!string.IsNullOrEmpty(successTemplateString)) { @@ -390,7 +401,7 @@ public static string ParseElement(string stlElement, PageInfo pageInfo, int chan //pre ellipsis if (index < pageCount && !string.IsNullOrEmpty(listEllipsis)) { - pageUrl = contextType == EContextType.Channel ? PagerUtility.GetUrlInChannelPage(type, pageInfo.SiteInfo, nodeInfo, index, currentPageIndex, pageCount, pageInfo.IsLocal) : PagerUtility.GetUrlInContentPage(type, pageInfo.SiteInfo, channelId, contentId, index, currentPageIndex, pageCount, pageInfo.IsLocal); + pageUrl = contextType == EContextType.Channel ? PagerUtility.GetUrlInChannelPage(type, pageInfo.SiteInfo, channelInfo, index, currentPageIndex, pageCount, pageInfo.IsLocal) : PagerUtility.GetUrlInContentPage(type, pageInfo.SiteInfo, channelId, contentId, index, currentPageIndex, pageCount, pageInfo.IsLocal); pageBuilder.Append(!string.IsNullOrEmpty(successTemplateString) ? GetParsedContent(successTemplateString, pageUrl, listEllipsis, pageInfo) @@ -414,7 +425,7 @@ public static string ParseElement(string stlElement, PageInfo pageInfo, int chan var uniqueId = "PageSelect_" + pageInfo.UniqueId; selectControl.ID = uniqueId; - string scriptHtml = + var scriptHtml = $""; selectControl.Attributes.Add("onChange", $"{uniqueId}_jumpMenu('self',this,0)"); @@ -422,7 +433,7 @@ public static string ParseElement(string stlElement, PageInfo pageInfo, int chan { if (currentPageIndex + 1 != index) { - pageUrl = contextType == EContextType.Channel ? PagerUtility.GetUrlInChannelPage(type, pageInfo.SiteInfo, nodeInfo, index, currentPageIndex, pageCount, pageInfo.IsLocal) : PagerUtility.GetUrlInContentPage(type, pageInfo.SiteInfo, channelId, contentId, index, currentPageIndex, pageCount, pageInfo.IsLocal); + pageUrl = contextType == EContextType.Channel ? PagerUtility.GetUrlInChannelPage(type, pageInfo.SiteInfo, channelInfo, index, currentPageIndex, pageCount, pageInfo.IsLocal) : PagerUtility.GetUrlInContentPage(type, pageInfo.SiteInfo, channelId, contentId, index, currentPageIndex, pageCount, pageInfo.IsLocal); var listitem = new ListItem(index.ToString(), pageUrl); selectControl.Items.Add(listitem); @@ -444,15 +455,15 @@ public static string ParseElement(string stlElement, PageInfo pageInfo, int chan } catch (Exception ex) { - parsedContent = StlParserUtility.GetStlErrorMessage(ElementName, stlElement, ex); + parsedContent = LogUtils.AddStlErrorLog(pageInfo, ElementName, stlElement, ex); } - return StlParserUtility.GetBackHtml(parsedContent, pageInfo); + return parsedContent; //return parsedContent; } - public static string ParseEntity(string stlEntity, PageInfo pageInfo, int channelId, int contentId, int currentPageIndex, int pageCount, int totalNum, bool isXmlContent, EContextType contextType) + public static string ParseEntity(string stlEntity, PageInfo pageInfo, int channelId, int contentId, int currentPageIndex, int pageCount, int totalNum, EContextType contextType) { var parsedContent = string.Empty; try @@ -509,7 +520,7 @@ public static string ParseEntity(string stlEntity, PageInfo pageInfo, int channe } } - parsedContent = isHyperlink ? pageUrl : PageUtils.UnclickedUrl; + parsedContent = isHyperlink ? pageUrl : PageUtils.UnClickedUrl; } else if (type.ToLower().Equals(TypeCurrentPageIndex.ToLower()))//当前页索引 { @@ -526,22 +537,20 @@ public static string ParseEntity(string stlEntity, PageInfo pageInfo, int channe } catch (Exception ex) { - parsedContent = StlParserUtility.GetStlErrorMessage(ElementName, stlEntity, ex); + parsedContent = LogUtils.AddStlErrorLog(pageInfo, ElementName, stlEntity, ex); } return parsedContent; } - public static string ParseElementInSearchPage(string stlElement, PageInfo pageInfo, string ajaxDivId, int channelId, int currentPageIndex, int pageCount, int totalNum) + public static string ParseElementInSearchPage(string stlElement, PageInfo pageInfo, string ajaxDivId, int currentPageIndex, int pageCount, int totalNum) { var parsedContent = string.Empty; try { - var xmlDocument = StlParserUtility.GetXmlDocument(stlElement, true); - XmlNode node = xmlDocument.DocumentElement; - node = node?.FirstChild; - var label = node?.Name; - if (!StringUtils.EqualsIgnoreCase(label, ElementName)) return string.Empty; + var stlElementInfo = StlParserUtility.ParseStlElement(stlElement); + + if (!StringUtils.EqualsIgnoreCase(stlElementInfo.Name, ElementName)) return string.Empty; var text = string.Empty; var type = string.Empty; @@ -554,86 +563,81 @@ public static string ParseElementInSearchPage(string stlElement, PageInfo pageIn var lStr = string.Empty; var rStr = string.Empty; var alwaysA = true; - var attributes = new Dictionary(); + var attributes = TranslateUtils.NewIgnoreCaseNameValueCollection(); - var ie = node?.Attributes?.GetEnumerator(); - if (ie != null) + foreach (var name in stlElementInfo.Attributes.AllKeys) { - while (ie.MoveNext()) - { - var attr = (XmlAttribute)ie.Current; - var name = attr.Name; + var value = stlElementInfo.Attributes[name]; - if (StringUtils.EqualsIgnoreCase(name, Type.Name)) - { - type = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, Text.Name)) - { - text = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, ListNum.Name)) - { - listNum = TranslateUtils.ToInt(attr.Value, 9); - } - else if (StringUtils.EqualsIgnoreCase(name, ListEllipsis.Name)) - { - listEllipsis = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, LinkClass.Name)) - { - linkClass = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, TextClass.Name)) - { - textClass = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, HasLr.Name)) - { - hasLr = TranslateUtils.ToBool(attr.Value); - } - else if (StringUtils.EqualsIgnoreCase(name, LStr.Name)) - { - lStr = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, RStr.Name)) - { - rStr = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, AlwaysA.Name)) - { - alwaysA = TranslateUtils.ToBool(attr.Value); - } - else - { - attributes[name] = attr.Value; - } + if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Text)) + { + text = value; + } + else if (StringUtils.EqualsIgnoreCase(name, ListNum)) + { + listNum = TranslateUtils.ToInt(value, 9); + } + else if (StringUtils.EqualsIgnoreCase(name, ListEllipsis)) + { + listEllipsis = value; + } + else if (StringUtils.EqualsIgnoreCase(name, LinkClass)) + { + linkClass = value; + } + else if (StringUtils.EqualsIgnoreCase(name, TextClass)) + { + textClass = value; + } + else if (StringUtils.EqualsIgnoreCase(name, HasLr)) + { + hasLr = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, LStr)) + { + lStr = value; + } + else if (StringUtils.EqualsIgnoreCase(name, RStr)) + { + rStr = value; + } + else if (StringUtils.EqualsIgnoreCase(name, AlwaysA)) + { + alwaysA = TranslateUtils.ToBool(value); + } + else + { + attributes[name] = value; } } var successTemplateString = string.Empty; var failureTemplateString = string.Empty; - if (!string.IsNullOrEmpty(node.InnerXml)) + if (!string.IsNullOrEmpty(stlElementInfo.InnerHtml)) { - var stlElementList = StlParserUtility.GetStlElementList(node.InnerXml); + var stlElementList = StlParserUtility.GetStlElementList(stlElementInfo.InnerHtml); if (stlElementList.Count > 0) { foreach (var theStlElement in stlElementList) { if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlYes.ElementName) || StlParserUtility.IsSpecifiedStlElement(theStlElement, StlYes.ElementName2)) { - successTemplateString = StlParserUtility.GetInnerXml(theStlElement, true); + successTemplateString = StlParserUtility.GetInnerHtml(theStlElement); } else if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlNo.ElementName) || StlParserUtility.IsSpecifiedStlElement(theStlElement, StlNo.ElementName2)) { - failureTemplateString = StlParserUtility.GetInnerXml(theStlElement, true); + failureTemplateString = StlParserUtility.GetInnerHtml(theStlElement); } } } if (string.IsNullOrEmpty(successTemplateString) && string.IsNullOrEmpty(failureTemplateString)) { - successTemplateString = failureTemplateString = node.InnerXml; + successTemplateString = failureTemplateString = stlElementInfo.InnerHtml; } } @@ -716,7 +720,7 @@ public static string ParseElementInSearchPage(string stlElement, PageInfo pageIn { var pageHyperLink = new HyperLink(); ControlUtils.AddAttributesIfNotExists(pageHyperLink, attributes); - pageHyperLink.NavigateUrl = PageUtils.UnclickedUrl; + pageHyperLink.NavigateUrl = PageUtils.UnClickedUrl; pageHyperLink.Attributes.Add("onclick", clickString); pageHyperLink.Text = text; if (!string.IsNullOrEmpty(linkClass)) @@ -730,7 +734,7 @@ public static string ParseElementInSearchPage(string stlElement, PageInfo pageIn { if (!string.IsNullOrEmpty(failureTemplateString)) { - parsedContent = GetParsedContent(failureTemplateString, PageUtils.UnclickedUrl, Convert.ToString(currentPageIndex + 1), pageInfo); + parsedContent = GetParsedContent(failureTemplateString, PageUtils.UnClickedUrl, Convert.ToString(currentPageIndex + 1), pageInfo); } else { @@ -836,7 +840,7 @@ public static string ParseElementInSearchPage(string stlElement, PageInfo pageIn else { pageBuilder.Append( - $@"{listEllipsis}"); } } @@ -853,7 +857,7 @@ public static string ParseElementInSearchPage(string stlElement, PageInfo pageIn } else { - var pageHyperLink = new HyperLink {NavigateUrl = PageUtils.UnclickedUrl}; + var pageHyperLink = new HyperLink {NavigateUrl = PageUtils.UnClickedUrl}; pageHyperLink.Attributes.Add("onclick", clickString); pageHyperLink.Text = $"{leftText}{index}{rightText}"; if (!string.IsNullOrEmpty(linkClass)) @@ -867,7 +871,7 @@ public static string ParseElementInSearchPage(string stlElement, PageInfo pageIn { if (!string.IsNullOrEmpty(failureTemplateString)) { - pageBuilder.Append(GetParsedContent(failureTemplateString, PageUtils.UnclickedUrl, index.ToString(), pageInfo)); + pageBuilder.Append(GetParsedContent(failureTemplateString, PageUtils.UnClickedUrl, index.ToString(), pageInfo)); } else { @@ -892,7 +896,7 @@ public static string ParseElementInSearchPage(string stlElement, PageInfo pageIn else { pageBuilder.Append( - $@"{listEllipsis}"); } } @@ -938,7 +942,7 @@ public static string ParseElementInSearchPage(string stlElement, PageInfo pageIn } catch (Exception ex) { - parsedContent = StlParserUtility.GetStlErrorMessage(ElementName, stlElement, ex); + parsedContent = LogUtils.AddStlErrorLog(pageInfo, ElementName, stlElement, ex); } return parsedContent; @@ -989,7 +993,7 @@ public static string ParseEntityInSearchPage(string stlEntity, PageInfo pageInfo } } - parsedContent = isHyperlink ? $"javascript:{clickString}" : PageUtils.UnclickedUrl; + parsedContent = isHyperlink ? $"javascript:{clickString}" : PageUtils.UnClickedUrl; } else if (type.ToLower().Equals(TypeCurrentPageIndex.ToLower()))//当前页索引 { @@ -1006,7 +1010,7 @@ public static string ParseEntityInSearchPage(string stlEntity, PageInfo pageInfo } catch (Exception ex) { - parsedContent = StlParserUtility.GetStlErrorMessage(ElementName, stlEntity, ex); + parsedContent = LogUtils.AddStlErrorLog(pageInfo, ElementName, stlEntity, ex); } return parsedContent; @@ -1020,11 +1024,9 @@ public static string ParseElementInDynamicPage(string stlElement, PageInfo pageI { var contextInfo = new ContextInfo(pageInfo); - var xmlDocument = StlParserUtility.GetXmlDocument(stlElement, true); - XmlNode node = xmlDocument.DocumentElement; - node = node?.FirstChild; - var label = node?.Name; - if (!StringUtils.EqualsIgnoreCase(label, ElementName)) return string.Empty; + var stlElementInfo = StlParserUtility.ParseStlElement(stlElement); + + if (!StringUtils.EqualsIgnoreCase(stlElementInfo.Name, ElementName)) return string.Empty; var text = string.Empty; var type = string.Empty; @@ -1037,86 +1039,81 @@ public static string ParseElementInDynamicPage(string stlElement, PageInfo pageI var lStr = string.Empty; var rStr = string.Empty; var alwaysA = true; - var attributes = new Dictionary(); + var attributes = TranslateUtils.NewIgnoreCaseNameValueCollection(); - var ie = node?.Attributes?.GetEnumerator(); - if (ie != null) + foreach (var name in stlElementInfo.Attributes.AllKeys) { - while (ie.MoveNext()) - { - var attr = (XmlAttribute)ie.Current; - var name = attr.Name; + var value = stlElementInfo.Attributes[name]; - if (StringUtils.EqualsIgnoreCase(name, Type.Name)) - { - type = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, Text.Name)) - { - text = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, ListNum.Name)) - { - listNum = TranslateUtils.ToInt(attr.Value, 9); - } - else if (StringUtils.EqualsIgnoreCase(name, ListEllipsis.Name)) - { - listEllipsis = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, LinkClass.Name)) - { - linkClass = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, TextClass.Name)) - { - textClass = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, HasLr.Name)) - { - hasLr = TranslateUtils.ToBool(attr.Value); - } - else if (StringUtils.EqualsIgnoreCase(name, LStr.Name)) - { - lStr = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, RStr.Name)) - { - rStr = attr.Value; - } - else if (StringUtils.EqualsIgnoreCase(name, AlwaysA.Name)) - { - alwaysA = TranslateUtils.ToBool(attr.Value); - } - else - { - attributes[name] = attr.Value; - } + if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Text)) + { + text = value; + } + else if (StringUtils.EqualsIgnoreCase(name, ListNum)) + { + listNum = TranslateUtils.ToInt(value, 9); + } + else if (StringUtils.EqualsIgnoreCase(name, ListEllipsis)) + { + listEllipsis = value; + } + else if (StringUtils.EqualsIgnoreCase(name, LinkClass)) + { + linkClass = value; + } + else if (StringUtils.EqualsIgnoreCase(name, TextClass)) + { + textClass = value; + } + else if (StringUtils.EqualsIgnoreCase(name, HasLr)) + { + hasLr = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, LStr)) + { + lStr = value; + } + else if (StringUtils.EqualsIgnoreCase(name, RStr)) + { + rStr = value; + } + else if (StringUtils.EqualsIgnoreCase(name, AlwaysA)) + { + alwaysA = TranslateUtils.ToBool(value); + } + else + { + attributes[name] = value; } } var successTemplateString = string.Empty; var failureTemplateString = string.Empty; - if (!string.IsNullOrEmpty(node.InnerXml)) + if (!string.IsNullOrEmpty(stlElementInfo.InnerHtml)) { - var stlElementList = StlParserUtility.GetStlElementList(node.InnerXml); + var stlElementList = StlParserUtility.GetStlElementList(stlElementInfo.InnerHtml); if (stlElementList.Count > 0) { foreach (var theStlElement in stlElementList) { if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlYes.ElementName) || StlParserUtility.IsSpecifiedStlElement(theStlElement, StlYes.ElementName2)) { - successTemplateString = StlParserUtility.GetInnerXml(theStlElement, true); + successTemplateString = StlParserUtility.GetInnerHtml(theStlElement); } else if (StlParserUtility.IsSpecifiedStlElement(theStlElement, StlNo.ElementName) || StlParserUtility.IsSpecifiedStlElement(theStlElement, StlNo.ElementName2)) { - failureTemplateString = StlParserUtility.GetInnerXml(theStlElement, true); + failureTemplateString = StlParserUtility.GetInnerHtml(theStlElement); } } } if (string.IsNullOrEmpty(successTemplateString) && string.IsNullOrEmpty(failureTemplateString)) { - successTemplateString = failureTemplateString = node.InnerXml; + successTemplateString = failureTemplateString = stlElementInfo.InnerHtml; } } @@ -1198,7 +1195,7 @@ public static string ParseElementInDynamicPage(string stlElement, PageInfo pageI { var pageHyperLink = new HyperLink(); ControlUtils.AddAttributesIfNotExists(pageHyperLink, attributes); - pageHyperLink.NavigateUrl = PageUtils.UnclickedUrl; + pageHyperLink.NavigateUrl = PageUtils.UnClickedUrl; pageHyperLink.Attributes.Add("onclick", jsMethod + ";return false;"); pageHyperLink.Text = text; if (!string.IsNullOrEmpty(linkClass)) @@ -1212,7 +1209,7 @@ public static string ParseElementInDynamicPage(string stlElement, PageInfo pageI { if (!string.IsNullOrEmpty(failureTemplateString)) { - parsedContent = GetParsedContent(failureTemplateString, PageUtils.UnclickedUrl, Convert.ToString(currentPageIndex + 1), pageInfo); + parsedContent = GetParsedContent(failureTemplateString, PageUtils.UnClickedUrl, Convert.ToString(currentPageIndex + 1), pageInfo); } else { @@ -1316,7 +1313,7 @@ public static string ParseElementInDynamicPage(string stlElement, PageInfo pageI else { pageBuilder.Append( - $@"{listEllipsis}"); } } @@ -1334,7 +1331,7 @@ public static string ParseElementInDynamicPage(string stlElement, PageInfo pageI } else { - var pageHyperLink = new HyperLink {NavigateUrl = PageUtils.UnclickedUrl}; + var pageHyperLink = new HyperLink {NavigateUrl = PageUtils.UnClickedUrl}; pageHyperLink.Attributes.Add("onclick", jsMethod + ";return false;"); pageHyperLink.Text = $"{leftText}{index}{rightText}"; if (!string.IsNullOrEmpty(linkClass)) @@ -1348,7 +1345,7 @@ public static string ParseElementInDynamicPage(string stlElement, PageInfo pageI { if (!string.IsNullOrEmpty(failureTemplateString)) { - pageBuilder.Append(GetParsedContent(failureTemplateString, PageUtils.UnclickedUrl, Convert.ToString(currentPageIndex + 1), pageInfo)); + pageBuilder.Append(GetParsedContent(failureTemplateString, PageUtils.UnClickedUrl, Convert.ToString(currentPageIndex + 1), pageInfo)); } else { @@ -1372,7 +1369,7 @@ public static string ParseElementInDynamicPage(string stlElement, PageInfo pageI else { pageBuilder.Append( - $@"{listEllipsis}"); } } @@ -1395,12 +1392,12 @@ public static string ParseElementInDynamicPage(string stlElement, PageInfo pageI for (var index = 1; index <= pageCount; index++) { - var listitem = new ListItem(index.ToString(), index.ToString()); + var listItem = new ListItem(index.ToString(), index.ToString()); if (currentPageIndex + 1 == index) { - listitem.Selected = true; + listItem.Selected = true; } - selectControl.Items.Add(listitem); + selectControl.Items.Add(listItem); } parsedContent = ControlUtils.GetControlRenderHtml(selectControl); @@ -1413,7 +1410,7 @@ public static string ParseElementInDynamicPage(string stlElement, PageInfo pageI } catch (Exception ex) { - parsedContent = StlParserUtility.GetStlErrorMessage(ElementName, stlElement, ex); + parsedContent = LogUtils.AddStlErrorLog(pageInfo, ElementName, stlElement, ex); } return parsedContent; @@ -1466,7 +1463,7 @@ public static string ParseEntityInDynamicPage(string stlEntity, PageInfo pageInf } } - parsedContent = isHyperlink ? $"javascript:{jsMethod}" : PageUtils.UnclickedUrl; + parsedContent = isHyperlink ? $"javascript:{jsMethod}" : PageUtils.UnClickedUrl; } else if (type.ToLower().Equals(TypeCurrentPageIndex.ToLower()))//当前页索引 { @@ -1483,7 +1480,7 @@ public static string ParseEntityInDynamicPage(string stlEntity, PageInfo pageInf } catch (Exception ex) { - parsedContent = StlParserUtility.GetStlErrorMessage(ElementName, stlEntity, ex); + parsedContent = LogUtils.AddStlErrorLog(pageInfo, ElementName, stlEntity, ex); } return parsedContent; diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlPageItems.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlPageItems.cs new file mode 100644 index 000000000..0effa03c1 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlPageItems.cs @@ -0,0 +1,130 @@ +using System; +using SiteServer.CMS.Core; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Parsers; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "翻页项容器", Description = "通过 stl:pageItems 标签在模板中插入翻页项的容器,当不需要翻页时容器内的内容不显示")] + public class StlPageItems + { + private StlPageItems() { } + public const string ElementName = "stl:pageItems"; + + [StlAttribute(Title = "所处上下文")] + private const string Context = nameof(Context); + + //对“翻页项容器”(stl:pageItems)元素进行解析,此元素在生成页面时单独解析,不包含在ParseStlElement方法中。 + public static string Parse(string stlElement, PageInfo pageInfo, int channelId, int contentId, int currentPageIndex, int pageCount, int totalNum, EContextType contextType) + { + pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.Jquery); + string parsedContent; + try + { + var stlElementInfo = StlParserUtility.ParseStlElement(stlElement); + if (stlElementInfo.Attributes[Context] != null) + { + contextType = EContextTypeUtils.GetEnumType(stlElementInfo.Attributes[Context]); + } + + if (pageCount <= 1) + { + return string.Empty; + } + + bool isXmlContent; + var index = stlElement.IndexOf(">", StringComparison.Ordinal) + 1; + var length = stlElement.LastIndexOf("<", StringComparison.Ordinal) - index; + if (index <= 0 || length <= 0) + { + stlElement = stlElementInfo.InnerHtml; + isXmlContent = true; + } + else + { + stlElement = stlElement.Substring(index, length); + isXmlContent = false; + } + + parsedContent = StlPageElementParser.ParseStlPageItems(stlElement, pageInfo, channelId, contentId, currentPageIndex, pageCount, totalNum, isXmlContent, contextType); + } + catch (Exception ex) + { + parsedContent = + LogUtils.AddStlErrorLog(pageInfo, ElementName, stlElement, ex); + } + + return parsedContent; + } + + public static string ParseInSearchPage(string stlElement, PageInfo pageInfo, string ajaxDivId, int channelId, int currentPageIndex, int pageCount, int totalNum) + { + string parsedContent; + try + { + var stlElementInfo = StlParserUtility.ParseStlElement(stlElement); + + if (pageCount <= 1) + { + return string.Empty; + } + + //bool isXmlContent; + var index = stlElement.IndexOf(">", StringComparison.Ordinal) + 1; + var length = stlElement.LastIndexOf("<", StringComparison.Ordinal) - index; + if (index <= 0 || length <= 0) + { + stlElement = stlElementInfo.InnerHtml; + //isXmlContent = true; + } + else + { + stlElement = stlElement.Substring(index, length); + //isXmlContent = false; + } + + parsedContent = StlPageElementParser.ParseStlPageItemsInSearchPage(stlElement, pageInfo, ajaxDivId, channelId, currentPageIndex, pageCount, totalNum); + } + catch (Exception ex) + { + parsedContent = LogUtils.AddStlErrorLog(pageInfo, ElementName, stlElement, ex); + } + + return parsedContent; + } + + public static string ParseInDynamicPage(string stlElement, PageInfo pageInfo, string pageUrl, int channelId, int currentPageIndex, int pageCount, int totalNum, bool isPageRefresh, string ajaxDivId) + { + string parsedContent; + try + { + var stlElementInfo = StlParserUtility.ParseStlElement(stlElement); + + if (pageCount <= 1) + { + return string.Empty; + } + + var index = stlElement.IndexOf(">", StringComparison.Ordinal) + 1; + var length = stlElement.LastIndexOf("<", StringComparison.Ordinal) - index; + if (index <= 0 || length <= 0) + { + stlElement = stlElementInfo.InnerHtml; + } + else + { + stlElement = stlElement.Substring(index, length); + } + + parsedContent = StlPageElementParser.ParseStlPageItemsInDynamicPage(stlElement, pageInfo, pageUrl, channelId, currentPageIndex, pageCount, totalNum, isPageRefresh, ajaxDivId); + } + catch (Exception ex) + { + parsedContent = LogUtils.AddStlErrorLog(pageInfo, ElementName, stlElement, ex); + } + + return parsedContent; + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlPageSqlContents.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlPageSqlContents.cs new file mode 100644 index 000000000..180714d16 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlPageSqlContents.cs @@ -0,0 +1,362 @@ +using System; +using System.Text; +using System.Web.UI.WebControls; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches.Stl; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "翻页数据库列表", Description = "通过 stl:pageSqlContents 标签在模板中显示能够翻页的数据库列表")] + public class StlPageSqlContents : StlSqlContents + { + public new const string ElementName = "stl:pageSqlContents"; + + [StlAttribute(Title = "每页显示的内容数目")] + public const string PageNum = nameof(PageNum); + + [StlAttribute(Title = "翻页中生成的静态页面最大数,剩余页面将动态获取")] + public const string MaxPage = nameof(MaxPage); + + private readonly string _stlPageSqlContentsElement; + private readonly PageInfo _pageInfo; + private readonly ContextInfo _contextInfo; + private readonly ListInfo _listInfo; + private readonly string _sqlString; + //private readonly DataSet _dataSet; + + public StlPageSqlContents(string stlPageSqlContentsElement, PageInfo pageInfo, ContextInfo contextInfo) + { + _stlPageSqlContentsElement = stlPageSqlContentsElement; + _pageInfo = pageInfo; + try + { + var stlElementInfo = StlParserUtility.ParseStlElement(stlPageSqlContentsElement); + + _contextInfo = contextInfo.Clone(stlPageSqlContentsElement, stlElementInfo.InnerHtml, stlElementInfo.Attributes); + + _listInfo = ListInfo.GetListInfo(_pageInfo, _contextInfo, EContextType.SqlContent); + + _sqlString = _listInfo.QueryString; + if (string.IsNullOrWhiteSpace(_listInfo.OrderByString)) + { + var pos = _sqlString.LastIndexOf(" ORDER BY ", StringComparison.OrdinalIgnoreCase); + if (pos > -1) + { + _sqlString = _sqlString.Substring(0, pos); + _listInfo.OrderByString = _sqlString.Substring(pos); + } + } + else + { + if (_listInfo.OrderByString.IndexOf("ORDER BY", StringComparison.OrdinalIgnoreCase) == -1) + { + _listInfo.OrderByString = $"ORDER BY {_listInfo.OrderByString}"; + } + } + + //_dataSet = StlDataUtility.GetPageSqlContentsDataSet(_listInfo.ConnectionString, _listInfo.QueryString, _listInfo.StartNum, _listInfo.PageNum, _listInfo.OrderByString); + } + catch(Exception ex) + { + LogUtils.AddStlErrorLog(pageInfo, ElementName, stlPageSqlContentsElement, ex); + _listInfo = new ListInfo(); + } + } + + public int GetPageCount(out int totalNum) + { + totalNum = 0; + var pageCount = 1; + try + { + //totalNum = DatabaseApi.Instance.GetPageTotalCount(SqlString); + totalNum = StlDatabaseCache.GetPageTotalCount(_sqlString); + if (_listInfo.PageNum != 0 && _listInfo.PageNum < totalNum)//需要翻页 + { + pageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(totalNum) / Convert.ToDouble(_listInfo.PageNum)));//需要生成的总页数 + } + } + catch + { + // ignored + } + return pageCount; + } + + //public int GetPageCount(out int contentNum) + //{ + // var pageCount = 1; + // contentNum = 0;//数据库中实际的内容数目 + // if (_dataSet == null) return pageCount; + + // contentNum = _dataSet.Tables[0].DefaultView.Count; + // if (_listInfo.PageNum != 0 && _listInfo.PageNum < contentNum)//需要翻页 + // { + // pageCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(contentNum) / Convert.ToDouble(_listInfo.PageNum)));//需要生成的总页数 + // } + // return pageCount; + //} + + public string Parse(int totalNum, int currentPageIndex, int pageCount, bool isStatic) + { + if (isStatic) + { + var maxPage = _listInfo.MaxPage; + if (maxPage == 0) + { + maxPage = _pageInfo.SiteInfo.CreateStaticMaxPage; + } + if (maxPage > 0 && currentPageIndex + 1 > maxPage) + { + return ParseDynamic(totalNum, currentPageIndex, pageCount); + } + } + + var parsedContent = string.Empty; + + _contextInfo.PageItemIndex = currentPageIndex * _listInfo.PageNum; + + try + { + if (!string.IsNullOrEmpty(_sqlString)) + { + //var pageSqlString = DatabaseApi.Instance.GetPageSqlString(SqlString, ListInfo.OrderByString, totalNum, ListInfo.PageNum, currentPageIndex); + var pageSqlString = StlDatabaseCache.GetStlPageSqlString(_sqlString, _listInfo.OrderByString, totalNum, _listInfo.PageNum, currentPageIndex); + + var dataSource = DataProvider.DatabaseApi.GetDataSource(pageSqlString); + + if (_listInfo.Layout == ELayout.None) + { + var rptContents = new Repeater(); + + if (!string.IsNullOrEmpty(_listInfo.HeaderTemplate)) + { + rptContents.HeaderTemplate = new SeparatorTemplate(_listInfo.HeaderTemplate); + } + if (!string.IsNullOrEmpty(_listInfo.FooterTemplate)) + { + rptContents.FooterTemplate = new SeparatorTemplate(_listInfo.FooterTemplate); + } + if (!string.IsNullOrEmpty(_listInfo.SeparatorTemplate)) + { + rptContents.SeparatorTemplate = new SeparatorTemplate(_listInfo.SeparatorTemplate); + } + if (!string.IsNullOrEmpty(_listInfo.AlternatingItemTemplate)) + { + rptContents.AlternatingItemTemplate = new RepeaterTemplate(_listInfo.AlternatingItemTemplate, _listInfo.SelectedItems, _listInfo.SelectedValues, _listInfo.SeparatorRepeatTemplate, _listInfo.SeparatorRepeat, _pageInfo, EContextType.SqlContent, _contextInfo); + } + + rptContents.ItemTemplate = new RepeaterTemplate(_listInfo.ItemTemplate, _listInfo.SelectedItems, _listInfo.SelectedValues, _listInfo.SeparatorRepeatTemplate, _listInfo.SeparatorRepeat, _pageInfo, EContextType.SqlContent, _contextInfo); + + rptContents.DataSource = dataSource; + rptContents.DataBind(); + + if (rptContents.Items.Count > 0) + { + parsedContent = ControlUtils.GetControlRenderHtml(rptContents); + } + } + else + { + var pdlContents = new ParsedDataList(); + + //设置显示属性 + TemplateUtility.PutListInfoToMyDataList(pdlContents, _listInfo); + + pdlContents.ItemTemplate = new DataListTemplate(_listInfo.ItemTemplate, _listInfo.SelectedItems, _listInfo.SelectedValues, _listInfo.SeparatorRepeatTemplate, _listInfo.SeparatorRepeat, _pageInfo, EContextType.SqlContent, _contextInfo); + if (!string.IsNullOrEmpty(_listInfo.HeaderTemplate)) + { + pdlContents.HeaderTemplate = new SeparatorTemplate(_listInfo.HeaderTemplate); + } + if (!string.IsNullOrEmpty(_listInfo.FooterTemplate)) + { + pdlContents.FooterTemplate = new SeparatorTemplate(_listInfo.FooterTemplate); + } + if (!string.IsNullOrEmpty(_listInfo.SeparatorTemplate)) + { + pdlContents.SeparatorTemplate = new SeparatorTemplate(_listInfo.SeparatorTemplate); + } + if (!string.IsNullOrEmpty(_listInfo.AlternatingItemTemplate)) + { + pdlContents.AlternatingItemTemplate = new DataListTemplate(_listInfo.AlternatingItemTemplate, _listInfo.SelectedItems, _listInfo.SelectedValues, _listInfo.SeparatorRepeatTemplate, _listInfo.SeparatorRepeat, _pageInfo, EContextType.SqlContent, _contextInfo); + } + + pdlContents.DataSource = dataSource; + pdlContents.DataKeyField = ContentAttribute.Id; + pdlContents.DataBind(); + + if (pdlContents.Items.Count > 0) + { + parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); + } + } + } + + //if (_dataSet != null) + //{ + // var dataSource = new PagedDataSource { DataSource = _dataSet.Tables[0].DefaultView }; //分页类 + + // if (pageCount > 1) + // { + // dataSource.AllowPaging = true; + // dataSource.PageSize = _listInfo.PageNum;//每页显示的项数 + // } + // else + // { + // dataSource.AllowPaging = false; + // } + + // dataSource.CurrentPageIndex = currentPageIndex;//当前页的索引 + + // if (_listInfo.Layout == ELayout.None) + // { + // var rptContents = new Repeater + // { + // ItemTemplate = + // new RepeaterTemplate(_listInfo.ItemTemplate, _listInfo.SelectedItems, + // _listInfo.SelectedValues, _listInfo.SeparatorRepeatTemplate, + // _listInfo.SeparatorRepeat, _pageInfo, EContextType.SqlContent, _contextInfo) + // }; + + // if (!string.IsNullOrEmpty(_listInfo.HeaderTemplate)) + // { + // rptContents.HeaderTemplate = new SeparatorTemplate(_listInfo.HeaderTemplate); + // } + // if (!string.IsNullOrEmpty(_listInfo.FooterTemplate)) + // { + // rptContents.FooterTemplate = new SeparatorTemplate(_listInfo.FooterTemplate); + // } + // if (!string.IsNullOrEmpty(_listInfo.SeparatorTemplate)) + // { + // rptContents.SeparatorTemplate = new SeparatorTemplate(_listInfo.SeparatorTemplate); + // } + // if (!string.IsNullOrEmpty(_listInfo.AlternatingItemTemplate)) + // { + // rptContents.AlternatingItemTemplate = new RepeaterTemplate(_listInfo.AlternatingItemTemplate, _listInfo.SelectedItems, _listInfo.SelectedValues, _listInfo.SeparatorRepeatTemplate, _listInfo.SeparatorRepeat, _pageInfo, EContextType.SqlContent, _contextInfo); + // } + + // rptContents.DataSource = dataSource; + // rptContents.DataBind(); + + // if (rptContents.Items.Count > 0) + // { + // parsedContent = ControlUtils.GetControlRenderHtml(rptContents); + // } + // } + // else + // { + // var pdlContents = new ParsedDataList(); + + // //设置显示属性 + // TemplateUtility.PutListInfoToMyDataList(pdlContents, _listInfo); + + // pdlContents.ItemTemplate = new DataListTemplate(_listInfo.ItemTemplate, _listInfo.SelectedItems, _listInfo.SelectedValues, _listInfo.SeparatorRepeatTemplate, _listInfo.SeparatorRepeat, _pageInfo, EContextType.SqlContent, _contextInfo); + // if (!string.IsNullOrEmpty(_listInfo.HeaderTemplate)) + // { + // pdlContents.HeaderTemplate = new SeparatorTemplate(_listInfo.HeaderTemplate); + // } + // if (!string.IsNullOrEmpty(_listInfo.FooterTemplate)) + // { + // pdlContents.FooterTemplate = new SeparatorTemplate(_listInfo.FooterTemplate); + // } + // if (!string.IsNullOrEmpty(_listInfo.SeparatorTemplate)) + // { + // pdlContents.SeparatorTemplate = new SeparatorTemplate(_listInfo.SeparatorTemplate); + // } + // if (!string.IsNullOrEmpty(_listInfo.AlternatingItemTemplate)) + // { + // pdlContents.AlternatingItemTemplate = new DataListTemplate(_listInfo.AlternatingItemTemplate, _listInfo.SelectedItems, _listInfo.SelectedValues, _listInfo.SeparatorRepeatTemplate, _listInfo.SeparatorRepeat, _pageInfo, EContextType.SqlContent, _contextInfo); + // } + + // pdlContents.DataSource = dataSource; + // pdlContents.DataBind(); + + // if (pdlContents.Items.Count > 0) + // { + // parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); + // } + // } + //} + } + catch (Exception ex) + { + parsedContent = LogUtils.AddStlErrorLog(_pageInfo, ElementName, _stlPageSqlContentsElement, ex); + } + + //还原翻页为0,使得其他列表能够正确解析ItemIndex + _contextInfo.PageItemIndex = 0; + + return parsedContent; + } + + private string ParseDynamic(int totalNum, int currentPageIndex, int pageCount) + { + var loading = _listInfo.LoadingTemplate; + if (string.IsNullOrEmpty(loading)) + { + loading = @"
    + 载入中,请稍后... +
    "; + } + + _pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.Jquery); + + var ajaxDivId = StlParserUtility.GetAjaxDivId(_pageInfo.UniqueId); + var apiUrl = ApiRouteActionsPageContents.GetUrl(_pageInfo.ApiUrl); + var apiParameters = ApiRouteActionsPageContents.GetParameters(_pageInfo.SiteId, _pageInfo.PageChannelId, _pageInfo.TemplateInfo.Id, totalNum, pageCount, currentPageIndex, _stlPageSqlContentsElement); + + var builder = new StringBuilder(); + builder.Append($@"
    "); + builder.Append($@"
    {loading}
    "); + builder.Append($@"
    {string.Empty}
    "); + builder.Append("
    "); + + builder.Append($@" + +"); + + return builder.ToString(); + } + } + +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlPlayer.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlPlayer.cs new file mode 100644 index 000000000..fc3c5837b --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlPlayer.cs @@ -0,0 +1,374 @@ +using System.Collections.Generic; +using System.Text; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Stl; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Fx; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "播放视频", Description = "通过 stl:player 标签在模板中播放视频")] + public class StlPlayer + { + private StlPlayer() { } + public const string ElementName = "stl:player"; + + [StlAttribute(Title = "指定存储媒体的字段")] + public const string Type = nameof(Type); + + [StlAttribute(Title = "视频地址")] + public const string PlayUrl = nameof(PlayUrl); + + [StlAttribute(Title = "图片地址")] + public const string ImageUrl = nameof(ImageUrl); + + [StlAttribute(Title = "指定播放器")] + public const string PlayBy = nameof(PlayBy); + + [StlAttribute(Title = "宽度")] + public const string Width = nameof(Width); + + [StlAttribute(Title = "高度")] + public const string Height = nameof(Height); + + [StlAttribute(Title = "是否自动播放")] + public const string IsAutoPlay = nameof(IsAutoPlay); + + private const string PlayByHtml5 = "Html5"; + private const string PlayByFlowPlayer = "FlowPlayer"; + private const string PlayByJwPlayer = "JWPlayer"; + + public static List PlayByList => new List + { + PlayByHtml5, + PlayByFlowPlayer, + PlayByJwPlayer + }; + + public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var type = ContentAttribute.VideoUrl; + var playUrl = string.Empty; + var imageUrl = string.Empty; + var playBy = string.Empty; + var width = 450; + var height = 350; + var isAutoPlay = true; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value; + } + else if (StringUtils.EqualsIgnoreCase(name, PlayUrl) || StringUtils.EqualsIgnoreCase(name, "src")) + { + playUrl = value; + } + else if (StringUtils.EqualsIgnoreCase(name, ImageUrl)) + { + imageUrl = value; + } + else if (StringUtils.EqualsIgnoreCase(name, PlayBy)) + { + playBy = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Width)) + { + width = TranslateUtils.ToInt(value, width); + } + else if (StringUtils.EqualsIgnoreCase(name, Height)) + { + height = TranslateUtils.ToInt(value, height); + } + else if (StringUtils.EqualsIgnoreCase(name, IsAutoPlay) || StringUtils.EqualsIgnoreCase(name, "play")) + { + isAutoPlay = TranslateUtils.ToBool(value, true); + } + } + + return ParseImpl(pageInfo, contextInfo, playUrl, imageUrl, playBy, width, height, type, isAutoPlay); + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string playUrl, string imageUrl, string playBy, int width, int height, string type, bool isAutoPlay) + { + if (string.IsNullOrEmpty(playUrl)) + { + var contentId = contextInfo.ContentId; + if (contentId != 0)//获取内容视频 + { + if (contextInfo.ContentInfo == null) + { + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, pageInfo.SiteId); + playUrl = StlContentCache.GetValue(channelInfo, contentId, type); + if (string.IsNullOrEmpty(playUrl)) + { + if (!StringUtils.EqualsIgnoreCase(type, ContentAttribute.VideoUrl)) + { + playUrl = StlContentCache.GetValue(channelInfo, contentId, ContentAttribute.VideoUrl); + } + } + } + else + { + playUrl = contextInfo.ContentInfo.Get(type); + if (string.IsNullOrEmpty(playUrl)) + { + playUrl = contextInfo.ContentInfo.Get(ContentAttribute.VideoUrl); + } + } + } + } + + if (string.IsNullOrEmpty(playUrl)) return string.Empty; + + playUrl = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, playUrl, pageInfo.IsLocal); + imageUrl = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, imageUrl, pageInfo.IsLocal); + + var extension = PathUtils.GetExtension(playUrl); + var uniqueId = pageInfo.UniqueId; + + var fileType = EFileSystemTypeUtils.GetEnumType(extension); + + if (EFileSystemTypeUtils.IsFlash(extension)) + { + return StlFlash.Parse(pageInfo, contextInfo); + } + + if (EFileSystemTypeUtils.IsImage(extension)) + { + return StlImage.Parse(pageInfo, contextInfo); + } + + if (fileType == EFileSystemType.Avi) + { + return ParseAvi(uniqueId, width, height, isAutoPlay, playUrl); + } + + if (fileType == EFileSystemType.Mpg) + { + return ParseMpg(uniqueId, width, height, isAutoPlay, playUrl); + } + + if (fileType == EFileSystemType.Rm || fileType == EFileSystemType.Rmb || fileType == EFileSystemType.Rmvb) + { + return ParseRm(contextInfo, uniqueId, width, height, isAutoPlay, playUrl); + } + + if (fileType == EFileSystemType.Wmv) + { + return ParseWmv(uniqueId, width, height, isAutoPlay, playUrl); + } + + if (fileType == EFileSystemType.Wma) + { + return ParseWma(uniqueId, isAutoPlay, playUrl); + } + + if (StringUtils.EqualsIgnoreCase(playBy, PlayByJwPlayer)) + { + pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.JsAcJwPlayer6); + var ajaxElementId = StlParserUtility.GetAjaxDivId(pageInfo.UniqueId); + return $@" +
    + +"; + } + + if (StringUtils.EqualsIgnoreCase(playBy, PlayByFlowPlayer)) + { + var ajaxElementId = StlParserUtility.GetAjaxDivId(pageInfo.UniqueId); + pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.JsAcFlowPlayer); + + var imageHtml = string.Empty; + if (!string.IsNullOrEmpty(imageUrl)) + { + imageHtml = $@" 0 ? $"width:{width}px;" : string.Empty)}{(height > 0 ? $"height:{height}px;" : string.Empty)}"" />"; + } + + var swfUrl = SiteFilesAssets.GetUrl(pageInfo.ApiUrl, SiteFilesAssets.FlowPlayer.Swf); + return $@" + 0 ? $"width:{width}px;" : string.Empty)}{(height > 0 ? $"height:{height}px;" : string.Empty)}"" id=""player_{ajaxElementId}"">{imageHtml} + +"; + } + + return StlVideo.Parse(pageInfo, contextInfo); + } + + private static string ParseAvi(int uniqueId, int width, int height, bool isAutoPlay, string playUrl) + { + return $@" + + + + + + + + + + + + + + +"; + } + + private static string ParseMpg(int uniqueId, int width, int height, bool isAutoPlay, string playUrl) + { + return $@" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +"; + } + + private static string ParseRm(ContextInfo contextInfo, int uniqueId, int width, int height, bool isAutoPlay, string playUrl) + { + if (string.IsNullOrEmpty(contextInfo.Attributes["ShowDisplay"])) + { + contextInfo.Attributes["ShowDisplay"] = "0"; + } + if (string.IsNullOrEmpty(contextInfo.Attributes["ShowControls"])) + { + contextInfo.Attributes["ShowControls"] = "1"; + } + contextInfo.Attributes["AutoStart"] = isAutoPlay ? "1" : "0"; + if (string.IsNullOrEmpty(contextInfo.Attributes["AutoRewind"])) + { + contextInfo.Attributes["AutoRewind"] = "0"; + } + if (string.IsNullOrEmpty(contextInfo.Attributes["PlayCount"])) + { + contextInfo.Attributes["PlayCount"] = "0"; + } + if (string.IsNullOrEmpty(contextInfo.Attributes["Appearance"])) + { + contextInfo.Attributes["Appearance"] = "0"; + } + if (string.IsNullOrEmpty(contextInfo.Attributes["BorderStyle"])) + { + contextInfo.Attributes["BorderStyle"] = "0"; + } + if (string.IsNullOrEmpty(contextInfo.Attributes["Controls"])) + { + contextInfo.Attributes["ImageWindow"] = "0"; + } + contextInfo.Attributes["moviewindowheight"] = height.ToString(); + contextInfo.Attributes["moviewindowwidth"] = width.ToString(); + contextInfo.Attributes["filename"] = playUrl; + contextInfo.Attributes["src"] = playUrl; + + var paramBuilder = new StringBuilder(); + var embedBuilder = new StringBuilder(); + foreach (string key in contextInfo.Attributes.Keys) + { + paramBuilder.Append($@"").Append(Constants.ReturnAndNewline); + embedBuilder.Append($@" {key}=""{contextInfo.Attributes[key]}"""); + } + + return $@" + +{paramBuilder} + + + +"; + } + + private static string ParseWmv(int uniqueId, int width, int height, bool isAutoPlay, string playUrl) + { + return $@" + + + + + + + + + + + + + + + + + + + + +"; + } + + private static string ParseWma(int uniqueId, bool isAutoPlay, string playUrl) + { + return $@" + + + + + + + + + + + +"; + } + } +} diff --git a/SiteServer.CMS/StlParser/StlElement/StlPrinter.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlPrinter.cs similarity index 82% rename from SiteServer.CMS/StlParser/StlElement/StlPrinter.cs rename to net452/SiteServer.CMS/StlParser/StlElement/StlPrinter.cs index 19886fe8a..874407807 100644 --- a/SiteServer.CMS/StlParser/StlElement/StlPrinter.cs +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlPrinter.cs @@ -1,22 +1,30 @@ using System.Text; using System.Web.UI.HtmlControls; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; using SiteServer.Utils; using SiteServer.CMS.StlParser.Model; using SiteServer.CMS.StlParser.Utility; -using SiteServer.Utils.Enumerations; namespace SiteServer.CMS.StlParser.StlElement { - [StlClass(Usage = "打印", Description = "通过 stl:printer 标签在模板中实现打印功能")] + [StlElement(Title = "打印", Description = "通过 stl:printer 标签在模板中实现打印功能")] public class StlPrinter { private StlPrinter() { } public const string ElementName = "stl:printer"; - private static readonly Attr TitleId = new Attr("titleId", "页面HTML中打印标题的ID属性"); - private static readonly Attr BodyId = new Attr("bodyId", "页面HTML中打印正文的ID属性"); - private static readonly Attr LogoId = new Attr("logoId", "页面LOGO的ID属性"); - private static readonly Attr LocationId = new Attr("locationId", "页面当前位置的ID属性"); + [StlAttribute(Title = "页面Html 中打印标题的 Id 属性")] + private const string TitleId = nameof(TitleId); + + [StlAttribute(Title = "页面Html 中打印正文的 Id 属性")] + private const string BodyId = nameof(BodyId); + + [StlAttribute(Title = "页面Logo 的 Id 属性")] + private const string LogoId = nameof(LogoId); + + [StlAttribute(Title = "页面当前位置的 Id 属性")] + private const string LocationId = nameof(LocationId); public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) { @@ -26,23 +34,23 @@ public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) var locationId = string.Empty; var stlAnchor = new HtmlAnchor(); - foreach (var name in contextInfo.Attributes.Keys) + foreach (var name in contextInfo.Attributes.AllKeys) { var value = contextInfo.Attributes[name]; - if (StringUtils.EqualsIgnoreCase(name, TitleId.Name)) + if (StringUtils.EqualsIgnoreCase(name, TitleId)) { titleId = value; } - else if (StringUtils.EqualsIgnoreCase(name, BodyId.Name)) + else if (StringUtils.EqualsIgnoreCase(name, BodyId)) { bodyId = value; } - else if (StringUtils.EqualsIgnoreCase(name, LogoId.Name)) + else if (StringUtils.EqualsIgnoreCase(name, LogoId)) { logoId = value; } - else if (StringUtils.EqualsIgnoreCase(name, LocationId.Name)) + else if (StringUtils.EqualsIgnoreCase(name, LocationId)) { locationId = value; } @@ -57,7 +65,7 @@ public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, HtmlAnchor stlAnchor, string titleId, string bodyId, string logoId, string locationId) { - var jsUrl = SiteFilesAssets.GetUrl(pageInfo.ApiUrl, pageInfo.TemplateInfo.Charset == ECharset.gb2312 ? SiteFilesAssets.Print.JsGb2312 : SiteFilesAssets.Print.JsUtf8); + var jsUrl = SiteFilesAssets.GetUrl(pageInfo.ApiUrl, SiteFilesAssets.Print.JsUtf8); var iconUrl = SiteFilesAssets.GetUrl(pageInfo.ApiUrl, SiteFilesAssets.Print.IconUrl); if (!pageInfo.BodyCodes.ContainsKey(PageInfo.Const.JsAfStlPrinter)) @@ -129,13 +137,13 @@ function stlLoadPrintJs() "); } - if (string.IsNullOrEmpty(contextInfo.InnerXml)) + if (string.IsNullOrEmpty(contextInfo.InnerHtml)) { stlAnchor.InnerHtml = "打印"; } else { - var innerBuilder = new StringBuilder(contextInfo.InnerXml); + var innerBuilder = new StringBuilder(contextInfo.InnerHtml); StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); stlAnchor.InnerHtml = innerBuilder.ToString(); } diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlQueryString.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlQueryString.cs new file mode 100644 index 000000000..c0002cd9f --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlQueryString.cs @@ -0,0 +1,10 @@ +using SiteServer.CMS.StlParser.Model; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "SQL查询语句", Description = "通过 stl:queryString 标签在模板中定义SQL查询语句")] + public class StlQueryString + { + public const string ElementName = "stl:queryString"; + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlSearch.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlSearch.cs new file mode 100644 index 000000000..84e53a035 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlSearch.cs @@ -0,0 +1,260 @@ +using System.Text; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "搜索", Description = "通过 stl:search 标签在模板中显示搜索结果")] + public class StlSearch + { + private StlSearch() { } + public const string ElementName = "stl:search"; + public const string ElementName2 = "stl:searchOutput"; + + [StlAttribute(Title = "是否对全部站点进行搜索")] + public const string IsAllSites = nameof(IsAllSites); + + [StlAttribute(Title = "站点名称")] + public const string SiteName = nameof(SiteName); + + [StlAttribute(Title = "站点文件夹")] + public const string SiteDir = nameof(SiteDir); + + [StlAttribute(Title = "站点Id列表")] + public const string SiteIds = nameof(SiteIds); + + [StlAttribute(Title = "栏目索引")] + public const string ChannelIndex = nameof(ChannelIndex); + + [StlAttribute(Title = "栏目名称")] + public const string ChannelName = nameof(ChannelName); + + [StlAttribute(Title = "栏目Id列表")] + public const string ChannelIds = nameof(ChannelIds); + + [StlAttribute(Title = "搜索类型")] + public const string Type = nameof(Type); + + [StlAttribute(Title = "搜索关键词")] + public const string Word = nameof(Word); + + [StlAttribute(Title = "搜索时间字段")] + public const string DateAttribute = nameof(DateAttribute); + + [StlAttribute(Title = "搜索开始时间")] + public const string DateFrom = nameof(DateFrom); + + [StlAttribute(Title = "搜索结束时间")] + public const string DateTo = nameof(DateTo); + + [StlAttribute(Title = "搜索时间段")] + public const string Since = nameof(Since); + + [StlAttribute(Title = "每页显示的内容数目")] + public const string PageNum = nameof(PageNum); + + [StlAttribute(Title = "是否关键字高亮")] + public const string IsHighlight = nameof(IsHighlight); + + public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var isAllSites = false; + var siteName = string.Empty; + var siteDir = string.Empty; + var siteIds = string.Empty; + var channelIndex = string.Empty; + var channelName = string.Empty; + var channelIds = string.Empty; + var type = ContentAttribute.Title; + var word = string.Empty; + var dateAttribute = ContentAttribute.AddDate; + var dateFrom = string.Empty; + var dateTo = string.Empty; + var since = string.Empty; + var pageNum = 0; + var isHighlight = false; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, IsAllSites)) + { + isAllSites = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, SiteName)) + { + siteName = value; + } + else if (StringUtils.EqualsIgnoreCase(name, SiteDir)) + { + siteDir = value; + } + else if (StringUtils.EqualsIgnoreCase(name, SiteIds)) + { + siteIds = value; + } + else if (StringUtils.EqualsIgnoreCase(name, ChannelIndex)) + { + channelIndex = value; + } + else if (StringUtils.EqualsIgnoreCase(name, ChannelName)) + { + channelName = value; + } + else if (StringUtils.EqualsIgnoreCase(name, ChannelIds)) + { + channelIds = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Word)) + { + word = value; + } + else if (StringUtils.EqualsIgnoreCase(name, DateAttribute)) + { + dateAttribute = value; + } + else if (StringUtils.EqualsIgnoreCase(name, DateFrom)) + { + dateFrom = value; + } + else if (StringUtils.EqualsIgnoreCase(name, DateTo)) + { + dateTo = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Since)) + { + since = value; + } + else if (StringUtils.EqualsIgnoreCase(name, PageNum)) + { + pageNum = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, IsHighlight)) + { + isHighlight = TranslateUtils.ToBool(value); + } + } + + StlParserUtility.GetLoadingYesNo(contextInfo.InnerHtml, out var loading, out var yes, out var no); + + if (string.IsNullOrEmpty(loading)) + { + loading = TemplateManager.GetContentByFilePath(SiteFilesAssets.Search.LoadingTemplatePath); + } + if (string.IsNullOrEmpty(yes)) + { + yes = TemplateManager.GetContentByFilePath(SiteFilesAssets.Search.YesTemplatePath); + } + if (string.IsNullOrEmpty(no)) + { + no = TemplateManager.GetContentByFilePath(SiteFilesAssets.Search.NoTemplatePath); + } + + pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.Jquery); + + var ajaxDivId = StlParserUtility.GetAjaxDivId(pageInfo.UniqueId); + var apiUrl = ApiRouteActionsSearch.GetUrl(pageInfo.ApiUrl); + var apiParameters = ApiRouteActionsSearch.GetParameters(isAllSites, siteName, siteDir, siteIds, channelIndex, channelName, channelIds, type, word, dateAttribute, dateFrom, dateTo, since, pageNum, isHighlight, pageInfo.SiteId, ajaxDivId, yes); + + var builder = new StringBuilder(); + builder.Append($@" +
    +
    {loading}
    +
    +
    {no}
    +
    +"); + + builder.Append($@" + +"); + + return builder.ToString(); + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlSelect.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlSelect.cs new file mode 100644 index 000000000..ae4837fda --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlSelect.cs @@ -0,0 +1,340 @@ +using System.Web.UI.HtmlControls; +using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Fx; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Parsers; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "下拉列表", Description = "通过 stl:select 标签在模板中显示栏目或内容下拉列表")] + public class StlSelect + { + private StlSelect() { } + public const string ElementName = "stl:select"; + + [StlAttribute(Title = "是否显示栏目下拉列表")] + private const string IsChannel = nameof(IsChannel); + + [StlAttribute(Title = "栏目索引")] + private const string ChannelIndex = nameof(ChannelIndex); + + [StlAttribute(Title = "栏目名称")] + private const string ChannelName = nameof(ChannelName); + + [StlAttribute(Title = "上级栏目的级别")] + private const string UpLevel = nameof(UpLevel); + + [StlAttribute(Title = "从首页向下的栏目级别")] + private const string TopLevel = nameof(TopLevel); + + [StlAttribute(Title = "选择的范围")] + private const string Scope = nameof(Scope); + + [StlAttribute(Title = "指定显示的栏目组")] + private const string GroupChannel = nameof(GroupChannel); + + [StlAttribute(Title = "指定不显示的栏目组")] + private const string GroupChannelNot = nameof(GroupChannelNot); + + [StlAttribute(Title = "指定显示的内容组")] + private const string GroupContent = nameof(GroupContent); + + [StlAttribute(Title = "指定不显示的内容组")] + private const string GroupContentNot = nameof(GroupContentNot); + + [StlAttribute(Title = "指定标签")] + private const string Tags = nameof(Tags); + + [StlAttribute(Title = "排序")] + private const string Order = nameof(Order); + + [StlAttribute(Title = "显示数目")] + private const string TotalNum = nameof(TotalNum); + + [StlAttribute(Title = "标题文字数量")] + private const string TitleWordNum = nameof(TitleWordNum); + + [StlAttribute(Title = "获取下拉列表的条件判断")] + private const string Where = nameof(Where); + + [StlAttribute(Title = "链接参数")] + private const string QueryString = nameof(QueryString); + + [StlAttribute(Title = "仅显示置顶内容")] + private const string IsTop = nameof(IsTop); + + [StlAttribute(Title = "仅显示推荐内容")] + private const string IsRecommend = nameof(IsRecommend); + + [StlAttribute(Title = "仅显示热点内容")] + private const string IsHot = nameof(IsHot); + + [StlAttribute(Title = "仅显示醒目内容")] + private const string IsColor = nameof(IsColor); + + [StlAttribute(Title = "下拉列表提示标题")] + private const string Title = nameof(Title); + + [StlAttribute(Title = "选择是否新窗口打开链接")] + private const string OpenWin = nameof(OpenWin); + + public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var selectControl = new HtmlSelect(); + + var isChannel = true; + var channelIndex = string.Empty; + var channelName = string.Empty; + var upLevel = 0; + var topLevel = -1; + var scopeTypeString = string.Empty; + var groupChannel = string.Empty; + var groupChannelNot = string.Empty; + var groupContent = string.Empty; + var groupContentNot = string.Empty; + var tags = string.Empty; + var order = string.Empty; + var totalNum = 0; + var titleWordNum = 0; + var where = string.Empty; + var queryString = string.Empty; + + var isTop = false; + var isTopExists = false; + var isRecommend = false; + var isRecommendExists = false; + var isHot = false; + var isHotExists = false; + var isColor = false; + var isColorExists = false; + + var displayTitle = string.Empty; + var openWin = true; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, IsChannel)) + { + isChannel = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, ChannelIndex)) + { + channelIndex = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, ChannelName)) + { + channelName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, UpLevel)) + { + upLevel = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, TopLevel)) + { + topLevel = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Scope)) + { + scopeTypeString = value; + } + else if (StringUtils.EqualsIgnoreCase(name, GroupChannel)) + { + groupChannel = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, GroupChannelNot)) + { + groupChannelNot = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, GroupContent)) + { + groupContent = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, GroupContentNot)) + { + groupContentNot = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, Tags)) + { + tags = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, Order)) + { + order = value; + } + else if (StringUtils.EqualsIgnoreCase(name, TotalNum)) + { + totalNum = TranslateUtils.ToInt(value, totalNum); + } + else if (StringUtils.EqualsIgnoreCase(name, Where)) + { + where = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, QueryString)) + { + queryString = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, IsTop)) + { + isTopExists = true; + isTop = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, IsRecommend)) + { + isRecommendExists = true; + isRecommend = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, IsHot)) + { + isHotExists = true; + isHot = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, IsColor)) + { + isColorExists = true; + isColor = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, TitleWordNum)) + { + titleWordNum = TranslateUtils.ToInt(value, titleWordNum); + } + else if (StringUtils.EqualsIgnoreCase(name, Title)) + { + displayTitle = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, OpenWin)) + { + openWin = TranslateUtils.ToBool(value); + } + else + { + selectControl.Attributes[name] = value; + } + } + + return ParseImpl(pageInfo, contextInfo, selectControl, isChannel, channelIndex, channelName, upLevel, topLevel, scopeTypeString, groupChannel, groupChannelNot, groupContent, groupContentNot, tags, order, totalNum, titleWordNum, where, queryString, isTop, isTopExists, isRecommend, isRecommendExists, isHot, isHotExists, isColor, isColorExists, displayTitle, openWin); + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, HtmlSelect selectControl, bool isChannel, string channelIndex, string channelName, int upLevel, int topLevel, string scopeTypeString, string groupChannel, string groupChannelNot, string groupContent, string groupContentNot, string tags, string order, int totalNum, int titleWordNum, string where, string queryString, bool isTop, bool isTopExists, bool isRecommend, bool isRecommendExists, bool isHot, bool isHotExists, bool isColor, bool isColorExists, string displayTitle, bool openWin) + { + EScopeType scopeType; + if (!string.IsNullOrEmpty(scopeTypeString)) + { + scopeType = EScopeTypeUtils.GetEnumType(scopeTypeString); + } + else + { + scopeType = isChannel ? EScopeType.Children : EScopeType.Self; + } + + var orderByString = isChannel + ? StlDataUtility.GetChannelOrderByString(order, ETaxisType.OrderByTaxis) + : StlDataUtility.GetContentOrderByString(order, ETaxisType.OrderByTaxisDesc); + + var channelId = StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, contextInfo.ChannelId, upLevel, topLevel); + + channelId = StlDataUtility.GetChannelIdByChannelIdOrChannelIndexOrChannelName(pageInfo.SiteId, channelId, channelIndex, channelName); + + var channel = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); + + var uniqueId = "Select_" + pageInfo.UniqueId; + selectControl.ID = uniqueId; + + string scriptHtml; + if (openWin) + { + scriptHtml = $@" +"; + selectControl.Attributes.Add("onChange", $"{uniqueId}_jumpMenu('parent',this)"); + } + else + { + scriptHtml = + $""; + selectControl.Attributes.Add("onChange", $"{uniqueId}_jumpMenu('self',this,0)"); + } + if (!string.IsNullOrEmpty(displayTitle)) + { + var listitem = new ListItem(displayTitle, PageUtils.UnClickedUrl) {Selected = true}; + selectControl.Items.Add(listitem); + } + + if (isChannel) + { + var channelIdList = StlDataUtility.GetChannelIdList(pageInfo.SiteId, channel.Id, orderByString, scopeType, groupChannel, groupChannelNot, false, false, totalNum, where); + + if (channelIdList != null && channelIdList.Count > 0) + { + foreach (var channelIdInSelect in channelIdList) + { + var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelIdInSelect); + + if (nodeInfo != null) + { + var title = StringUtils.MaxLengthText(nodeInfo.ChannelName, titleWordNum); + var url = PageUtility.GetChannelUrl(pageInfo.SiteInfo, nodeInfo, pageInfo.IsLocal); + if (!string.IsNullOrEmpty(queryString)) + { + url = PageUtils.AddQueryString(url, queryString); + } + var listitem = new ListItem(title, url); + selectControl.Items.Add(listitem); + } + } + } + } + else + { + var minContentInfoList = StlDataUtility.GetMinContentInfoList(pageInfo.SiteInfo, channelId, contextInfo.ContentId, groupContent, groupContentNot, tags, false, false, false, false, false, false, false, 1, totalNum, orderByString, isTopExists, isTop, isRecommendExists, isRecommend, isHotExists, isHot, isColorExists, isColor, where, scopeType, groupChannel, groupChannelNot, null); + + if (minContentInfoList != null) + { + foreach (var minContentInfo in minContentInfoList) + { + var contentInfo = ContentManager.GetContentInfo(pageInfo.SiteInfo, minContentInfo.ChannelId, minContentInfo.Id); + var title = StringUtils.MaxLengthText(contentInfo.Title, titleWordNum); + var url = PageUtility.GetContentUrl(pageInfo.SiteInfo, contentInfo, false); + if (!string.IsNullOrEmpty(queryString)) + { + url = PageUtils.AddQueryString(url, queryString); + } + selectControl.Items.Add(new ListItem(title, url)); + } + //foreach (var dataItem in dataSource) + //{ + // var contentInfo = new BackgroundContentInfo(dataItem); + // if (contentInfo != null) + // { + // var title = StringUtils.MaxLengthText(contentInfo.Title, titleWordNum); + // var url = PageUtility.GetContentUrl(pageInfo.SiteInfo, contentInfo); + // if (!string.IsNullOrEmpty(queryString)) + // { + // url = PageUtils.AddQueryString(url, queryString); + // } + // var listitem = new ListItem(title, url); + // selectControl.Items.Add(listitem); + // } + //} + } + } + + return scriptHtml + ControlUtils.GetControlRenderHtml(selectControl); + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlSite.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlSite.cs new file mode 100644 index 000000000..9bf3fffeb --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlSite.cs @@ -0,0 +1,247 @@ +using System.Collections.Generic; +using System.Text; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Parsers; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Plugin; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "获取站点值", Description = "通过 stl:site 标签在模板中显示站点值")] + public class StlSite + { + private StlSite() { } + public const string ElementName = "stl:site"; + + [StlAttribute(Title = "站点名称")] + private const string SiteName = nameof(SiteName); + + [StlAttribute(Title = "站点文件夹")] + private const string SiteDir = nameof(SiteDir); + + [StlAttribute(Title = "类型")] + private const string Type = nameof(Type); + + [StlAttribute(Title = "显示的格式")] + private const string FormatString = nameof(FormatString); + + [StlAttribute(Title = "显示多项时的分割字符串")] + private const string Separator = nameof(Separator); + + [StlAttribute(Title = "字符开始位置")] + private const string StartIndex = nameof(StartIndex); + + [StlAttribute(Title = "指定字符长度")] + private const string Length = nameof(Length); + + [StlAttribute(Title = "显示字符的数目")] + private const string WordNum = nameof(WordNum); + + [StlAttribute(Title = "文字超出部分显示的文字")] + private const string Ellipsis = nameof(Ellipsis); + + [StlAttribute(Title = "需要替换的文字,可以是正则表达式")] + private const string Replace = nameof(Replace); + + [StlAttribute(Title = "替换replace的文字信息")] + private const string To = nameof(To); + + [StlAttribute(Title = "是否清除标签信息")] + private const string IsClearTags = nameof(IsClearTags); + + [StlAttribute(Title = "是否将回车替换为HTML换行标签")] + private const string IsReturnToBr = nameof(IsReturnToBr); + + [StlAttribute(Title = "是否转换为小写")] + private const string IsLower = nameof(IsLower); + + [StlAttribute(Title = "是否转换为大写")] + private const string IsUpper = nameof(IsUpper); + + public const string TypeSiteName = "SiteName"; + public const string TypeSiteUrl = "SiteUrl"; + + public static SortedList TypeList => new SortedList + { + {TypeSiteName, "站点名称"}, + {TypeSiteUrl, "站点的域名地址"} + }; + + internal static object Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var siteName = string.Empty; + var siteDir = string.Empty; + + var type = string.Empty; + var formatString = string.Empty; + string separator = null; + var startIndex = 0; + var length = 0; + var wordNum = 0; + var ellipsis = Constants.Ellipsis; + var replace = string.Empty; + var to = string.Empty; + var isClearTags = false; + var isReturnToBr = false; + var isLower = false; + var isUpper = false; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, SiteName)) + { + siteName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, SiteDir)) + { + siteDir = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value; + } + else if (StringUtils.EqualsIgnoreCase(name, FormatString)) + { + formatString = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Separator)) + { + separator = value; + } + else if (StringUtils.EqualsIgnoreCase(name, StartIndex)) + { + startIndex = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Length)) + { + length = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, WordNum)) + { + wordNum = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Ellipsis)) + { + ellipsis = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Replace)) + { + replace = value; + } + else if (StringUtils.EqualsIgnoreCase(name, To)) + { + to = value; + } + else if (StringUtils.EqualsIgnoreCase(name, IsClearTags)) + { + isClearTags = TranslateUtils.ToBool(value, false); + } + else if (StringUtils.EqualsIgnoreCase(name, IsReturnToBr)) + { + isReturnToBr = TranslateUtils.ToBool(value, false); + } + else if (StringUtils.EqualsIgnoreCase(name, IsLower)) + { + isLower = TranslateUtils.ToBool(value, true); + } + else if (StringUtils.EqualsIgnoreCase(name, IsUpper)) + { + isUpper = TranslateUtils.ToBool(value, true); + } + } + + var siteInfo = contextInfo.SiteInfo; + + if (!string.IsNullOrEmpty(siteName)) + { + siteInfo = SiteManager.GetSiteInfoBySiteName(siteName); + } + else if (!string.IsNullOrEmpty(siteDir)) + { + siteInfo = SiteManager.GetSiteInfoByDirectory(siteDir); + } + + if (contextInfo.IsStlEntity && string.IsNullOrEmpty(type)) + { + return siteInfo; + } + + return ParseImpl(pageInfo, contextInfo, siteInfo, type, formatString, separator, startIndex, length, wordNum, ellipsis, replace, to, isClearTags, isReturnToBr, isLower, isUpper); + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, SiteInfo siteInfo, string type, string formatString, string separator, int startIndex, int length, int wordNum, string ellipsis, string replace, string to, bool isClearTags, bool isReturnToBr, bool isLower, bool isUpper) + { + if (siteInfo == null) return string.Empty; + + var parsedContent = string.Empty; + + if (!string.IsNullOrEmpty(contextInfo.InnerHtml)) + { + var preSiteInfo = pageInfo.SiteInfo; + var prePageChannelId = pageInfo.PageChannelId; + var prePageContentId = pageInfo.PageContentId; + + pageInfo.ChangeSite(siteInfo, siteInfo.Id, 0, contextInfo); + + var innerBuilder = new StringBuilder(contextInfo.InnerHtml); + StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); + parsedContent = innerBuilder.ToString(); + + pageInfo.ChangeSite(preSiteInfo, prePageChannelId, prePageContentId, contextInfo); + + return parsedContent; + } + + var inputType = InputType.Text; + + if (type.ToLower().Equals(TypeSiteName.ToLower())) + { + parsedContent = pageInfo.SiteInfo.SiteName; + } + else if (type.ToLower().Equals(TypeSiteUrl.ToLower())) + { + parsedContent = pageInfo.SiteInfo.WebUrl; + } + else if (pageInfo.SiteInfo.ContainsKey(type)) + { + parsedContent = pageInfo.SiteInfo.Get(type); + if (!string.IsNullOrEmpty(parsedContent)) + { + var styleInfo = TableStyleManager.GetTableStyleInfo(DataProvider.Site.TableName, type, TableStyleManager.GetRelatedIdentities(pageInfo.SiteId)); + + // 如果 styleInfo.TableStyleId <= 0,表示此字段已经被删除了,不需要再显示值了 ekun008 + if (styleInfo.Id > 0) + { + if (isClearTags && InputTypeUtils.EqualsAny(styleInfo.Type, InputType.Image, InputType.File)) + { + parsedContent = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); + } + else + { + parsedContent = InputParserUtility.GetContentByTableStyle(parsedContent, separator, pageInfo.SiteInfo, styleInfo, formatString, contextInfo.Attributes, contextInfo.InnerHtml, false, isLower, isUpper); + + inputType = styleInfo.Type; + + //parsedContent = StringUtils.ParseString(styleInfo.InputType, parsedContent, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); + } + } + else + { // 如果字段已经被删除或不再显示了,则此字段的值为空。有时虚拟字段值不会清空 + parsedContent = string.Empty; + } + } + } + + if (string.IsNullOrEmpty(parsedContent)) return string.Empty; + + return InputTypeUtils.ParseString(inputType, parsedContent, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlSites.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlSites.cs new file mode 100644 index 000000000..5f9ad5b16 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlSites.cs @@ -0,0 +1,134 @@ +using System.Collections.Generic; +using System.Data; +using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "站点列表", Description = "通过 stl:sites 标签在模板中显示站点列表")] + public class StlSites + { + public const string ElementName = "stl:sites"; + + [StlAttribute(Title = "站点名称")] + private const string SiteName = nameof(SiteName); + + [StlAttribute(Title = "站点文件夹")] + private const string SiteDir = nameof(SiteDir); + + public static object Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var listInfo = ListInfo.GetListInfo(pageInfo, contextInfo, EContextType.Site); + var siteName = listInfo.Others.Get(SiteName); + var siteDir = listInfo.Others.Get(SiteDir); + + var dataSource = StlDataUtility.GetSitesDataSource(siteName, siteDir, listInfo.StartNum, listInfo.TotalNum, listInfo.Where, listInfo.Scope, listInfo.OrderByString); + + if (contextInfo.IsStlEntity) + { + return ParseEntity(dataSource); + } + + return ParseElement(pageInfo, contextInfo, listInfo, dataSource); + } + + private static string ParseElement(PageInfo pageInfo, ContextInfo contextInfo, ListInfo listInfo, IDataReader dataSource) + { + var parsedContent = string.Empty; + + if (listInfo.Layout == ELayout.None) + { + var rptContents = new Repeater + { + ItemTemplate = + new RepeaterTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, + listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, + pageInfo, EContextType.Site, contextInfo) + }; + + if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) + { + rptContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); + } + if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) + { + rptContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); + } + if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) + { + rptContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); + } + if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) + { + rptContents.AlternatingItemTemplate = new RepeaterTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Site, contextInfo); + } + + rptContents.DataSource = dataSource; + rptContents.DataBind(); + + if (rptContents.Items.Count > 0) + { + parsedContent = ControlUtils.GetControlRenderHtml(rptContents); + } + } + else + { + var pdlContents = new ParsedDataList(); + + TemplateUtility.PutListInfoToMyDataList(pdlContents, listInfo); + + pdlContents.ItemTemplate = new DataListTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Site, contextInfo); + if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) + { + pdlContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); + } + if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) + { + pdlContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); + } + if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) + { + pdlContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); + } + if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) + { + pdlContents.AlternatingItemTemplate = new DataListTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.Site, contextInfo); + } + + pdlContents.DataSource = dataSource; + pdlContents.DataBind(); + + if (pdlContents.Items.Count > 0) + { + parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); + } + } + + return parsedContent; + } + + private static List ParseEntity(IDataReader dataSource) + { + var siteInfoList = new List(); + + while (dataSource.Read()) + { + var siteId = dataSource.GetInt32(0); + var siteInfo = SiteManager.GetSiteInfo(siteId); + + if (siteInfo != null) + { + siteInfoList.Add(siteInfo); + } + } + + return siteInfoList; + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlSqlContent.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlSqlContent.cs new file mode 100644 index 000000000..df00a46d8 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlSqlContent.cs @@ -0,0 +1,248 @@ +using System.Web.UI; +using SiteServer.CMS.Caches.Stl; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Parsers; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Plugin; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "数据库值", Description = "通过 stl:sqlContent 标签在模板中显示数据库值")] + public class StlSqlContent + { + private StlSqlContent() { } + public const string ElementName = "stl:sqlContent"; + + [StlAttribute(Title = "数据库链接字符串名称")] + private const string ConnectionStringName = nameof(ConnectionStringName); + + [StlAttribute(Title = "数据库链接字符串")] + private const string ConnectionString = nameof(ConnectionString); + + [StlAttribute(Title = "数据库查询语句")] + private const string QueryString = nameof(QueryString); + + [StlAttribute(Title = "显示的类型")] + private const string Type = nameof(Type); + + [StlAttribute(Title = "显示在信息前的文字")] + private const string LeftText = nameof(LeftText); + + [StlAttribute(Title = "显示在信息后的文字")] + private const string RightText = nameof(RightText); + + [StlAttribute(Title = "显示的格式")] + private const string FormatString = nameof(FormatString); + + [StlAttribute(Title = "字符开始位置")] + private const string StartIndex = nameof(StartIndex); + + [StlAttribute(Title = "指定字符长度")] + private const string Length = nameof(Length); + + [StlAttribute(Title = "显示字符的数目")] + private const string WordNum = nameof(WordNum); + + [StlAttribute(Title = "文字超出部分显示的文字")] + private const string Ellipsis = nameof(Ellipsis); + + [StlAttribute(Title = "需要替换的文字,可以是正则表达式")] + private const string Replace = nameof(Replace); + + [StlAttribute(Title = "替换replace的文字信息")] + private const string To = nameof(To); + + [StlAttribute(Title = "是否清除标签信息")] + private const string IsClearTags = nameof(IsClearTags); + + [StlAttribute(Title = "是否将回车替换为HTML换行标签")] + private const string IsReturnToBr = nameof(IsReturnToBr); + + [StlAttribute(Title = "是否转换为小写")] + private const string IsLower = nameof(IsLower); + + [StlAttribute(Title = "是否转换为大写")] + private const string IsUpper = nameof(IsUpper); + + public static object Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var connectionString = string.Empty; + var queryString = string.Empty; + + var leftText = string.Empty; + var rightText = string.Empty; + var formatString = string.Empty; + var startIndex = 0; + var length = 0; + var wordNum = 0; + var ellipsis = Constants.Ellipsis; + var replace = string.Empty; + var to = string.Empty; + var isClearTags = false; + var isReturnToBr = false; + var isLower = false; + var isUpper = false; + var type = string.Empty; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, ConnectionString)) + { + connectionString = value; + } + else if (StringUtils.EqualsIgnoreCase(name, ConnectionStringName)) + { + if (string.IsNullOrEmpty(connectionString)) + { + connectionString = WebConfigUtils.ConnectionString; + } + } + else if (StringUtils.EqualsIgnoreCase(name, QueryString)) + { + queryString = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); + } + else if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value.ToLower(); + } + else if (StringUtils.EqualsIgnoreCase(name, LeftText)) + { + leftText = value; + } + else if (StringUtils.EqualsIgnoreCase(name, RightText)) + { + rightText = value; + } + else if (StringUtils.EqualsIgnoreCase(name, FormatString)) + { + formatString = value; + } + else if (StringUtils.EqualsIgnoreCase(name, StartIndex)) + { + startIndex = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Length)) + { + length = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, WordNum)) + { + wordNum = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Ellipsis)) + { + ellipsis = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Replace)) + { + replace = value; + } + else if (StringUtils.EqualsIgnoreCase(name, To)) + { + to = value; + } + else if (StringUtils.EqualsIgnoreCase(name, IsClearTags)) + { + isClearTags = TranslateUtils.ToBool(value, false); + } + else if (StringUtils.EqualsIgnoreCase(name, IsReturnToBr)) + { + isReturnToBr = TranslateUtils.ToBool(value, false); + } + else if (StringUtils.EqualsIgnoreCase(name, IsLower)) + { + isLower = TranslateUtils.ToBool(value, true); + } + else if (StringUtils.EqualsIgnoreCase(name, IsUpper)) + { + isUpper = TranslateUtils.ToBool(value, true); + } + } + + if (contextInfo.IsStlEntity && string.IsNullOrEmpty(type)) + { + object dataItem = null; + if (contextInfo.ItemContainer?.SqlItem != null) + { + dataItem = contextInfo.ItemContainer?.SqlItem.DataItem; + } + else if (!string.IsNullOrEmpty(queryString)) + { + var dataTable = StlDatabaseCache.GetDataTable(connectionString, queryString); + var dictList = TranslateUtils.DataTableToDictionaryList(dataTable); + if (dictList != null && dictList.Count >= 1) + { + dataItem = dictList[0]; + } + } + + return dataItem; + } + + return ParseImpl(contextInfo, connectionString, queryString, leftText, rightText, formatString, startIndex, length, wordNum, ellipsis, replace, to, isClearTags, isReturnToBr, isLower, isUpper, type); + } + + private static string ParseImpl(ContextInfo contextInfo, string connectionString, string queryString, string leftText, string rightText, string formatString, int startIndex, int length, int wordNum, string ellipsis, string replace, string to, bool isClearTags, bool isReturnToBr, bool isLower, bool isUpper, string type) + { + var parsedContent = string.Empty; + + if (!string.IsNullOrEmpty(type) && contextInfo.ItemContainer?.SqlItem != null) + { + if (!string.IsNullOrEmpty(formatString)) + { + formatString = formatString.Trim(); + if (!formatString.StartsWith("{0")) + { + formatString = "{0:" + formatString; + } + if (!formatString.EndsWith("}")) + { + formatString = formatString + "}"; + } + } + else + { + formatString = "{0}"; + } + + if (StringUtils.StartsWithIgnoreCase(type, StlParserUtility.ItemIndex)) + { + var itemIndex = StlParserUtility.ParseItemIndex(contextInfo.ItemContainer.SqlItem.ItemIndex, type, contextInfo); + + parsedContent = !string.IsNullOrEmpty(formatString) ? string.Format(formatString, itemIndex) : itemIndex.ToString(); + } + else + { + parsedContent = DataBinder.Eval(contextInfo.ItemContainer.SqlItem.DataItem, type, formatString); + } + } + else if (!string.IsNullOrEmpty(queryString)) + { + if (string.IsNullOrEmpty(connectionString)) + { + connectionString = WebConfigUtils.ConnectionString; + } + + //parsedContent = DatabaseApi.Instance.GetString(connectionString, queryString); + parsedContent = StlDatabaseCache.GetString(connectionString, queryString); + } + + if (!string.IsNullOrEmpty(parsedContent)) + { + parsedContent = InputTypeUtils.ParseString(InputType.Text, parsedContent, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); + + if (!string.IsNullOrEmpty(parsedContent)) + { + parsedContent = leftText + parsedContent + rightText; + } + } + + return parsedContent; + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlSqlContents.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlSqlContents.cs new file mode 100644 index 000000000..6fd03bb64 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlSqlContents.cs @@ -0,0 +1,119 @@ +using System.Data; +using System.Web.UI.WebControls; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Fx; +using SiteServer.Utils; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "数据库列表", Description = "通过 stl:sqlContents 标签在模板中显示数据库列表")] + public class StlSqlContents + { + public const string ElementName = "stl:sqlContents"; + + [StlAttribute(Title = "数据库链接字符串名称")] + public const string ConnectionStringName = nameof(ConnectionStringName); + + [StlAttribute(Title = "数据库链接字符串")] + public const string ConnectionString = nameof(ConnectionString); + + [StlAttribute(Title = "数据库查询语句")] + public const string QueryString = nameof(QueryString); + + public static object Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var listInfo = ListInfo.GetListInfo(pageInfo, contextInfo, EContextType.SqlContent); + var dataSource = StlDataUtility.GetSqlContentsDataSource(listInfo.ConnectionString, listInfo.QueryString, listInfo.StartNum, listInfo.TotalNum, listInfo.OrderByString); + + if (contextInfo.IsStlEntity) + { + return ParseEntity(dataSource); + } + + return ParseElement(pageInfo, contextInfo, listInfo, dataSource); + } + + private static string ParseElement(PageInfo pageInfo, ContextInfo contextInfo, ListInfo listInfo, DataSet dataSource) + { + var parsedContent = string.Empty; + + if (listInfo.Layout == ELayout.None) + { + var rptContents = new Repeater + { + ItemTemplate = + new RepeaterTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, + listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, + EContextType.SqlContent, contextInfo) + }; + + if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) + { + rptContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); + } + if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) + { + rptContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); + } + if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) + { + rptContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); + } + if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) + { + rptContents.AlternatingItemTemplate = new RepeaterTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.SqlContent, contextInfo); + } + + rptContents.DataSource = dataSource; + rptContents.DataBind(); + + if (rptContents.Items.Count > 0) + { + parsedContent = ControlUtils.GetControlRenderHtml(rptContents); + } + } + else + { + var pdlContents = new ParsedDataList(); + + TemplateUtility.PutListInfoToMyDataList(pdlContents, listInfo); + + pdlContents.ItemTemplate = new DataListTemplate(listInfo.ItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.SqlContent, contextInfo); + if (!string.IsNullOrEmpty(listInfo.HeaderTemplate)) + { + pdlContents.HeaderTemplate = new SeparatorTemplate(listInfo.HeaderTemplate); + } + if (!string.IsNullOrEmpty(listInfo.FooterTemplate)) + { + pdlContents.FooterTemplate = new SeparatorTemplate(listInfo.FooterTemplate); + } + if (!string.IsNullOrEmpty(listInfo.SeparatorTemplate)) + { + pdlContents.SeparatorTemplate = new SeparatorTemplate(listInfo.SeparatorTemplate); + } + if (!string.IsNullOrEmpty(listInfo.AlternatingItemTemplate)) + { + pdlContents.AlternatingItemTemplate = new DataListTemplate(listInfo.AlternatingItemTemplate, listInfo.SelectedItems, listInfo.SelectedValues, listInfo.SeparatorRepeatTemplate, listInfo.SeparatorRepeat, pageInfo, EContextType.SqlContent, contextInfo); + } + + pdlContents.DataSource = dataSource; + pdlContents.DataBind(); + + if (pdlContents.Items.Count > 0) + { + parsedContent = ControlUtils.GetControlRenderHtml(pdlContents); + } + } + + return parsedContent; + } + + private static object ParseEntity(DataSet dataSource) + { + var table = dataSource.Tables[0]; + return TranslateUtils.DataTableToDictionaryList(table); + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlTabs.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlTabs.cs new file mode 100644 index 000000000..a67e3d4ec --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlTabs.cs @@ -0,0 +1,202 @@ +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Text; +using HtmlAgilityPack; +using SiteServer.Utils; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "页签切换", Description = "通过 stl:tabs 标签在模板中显示页签切换")] + public class StlTabs + { + private StlTabs() { } + public const string ElementName = "stl:tabs"; + + [StlAttribute(Title = "页签名称")] + private const string TabName = nameof(TabName); + + [StlAttribute(Title = "页签类型(head,body)")] + private const string Type = nameof(Type); + + [StlAttribute(Title = "页签切换方式")] + private const string Action = nameof(Action); + + [StlAttribute(Title = "当前显示页签头部的CSS类")] + private const string ClassActive = nameof(ClassActive); + + [StlAttribute(Title = "当前隐藏页签头部的CSS类")] + private const string ClassNormal = nameof(ClassNormal); + + [StlAttribute(Title = "当前页签")] + private const string Current = nameof(Current); + + public const string TypeHead = "Head"; + public const string TypeBody = "Body"; + + public const string ActionClick = "Click"; + public const string ActionMouseOver = "MouseOver"; + + public static SortedList ActionList => new SortedList + { + {ActionClick, "点击"}, + {ActionMouseOver, "鼠标移动"} + }; + + internal static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var tabName = string.Empty; + var type = string.Empty; + var action = ActionMouseOver; + var classActive = "active"; + var classNormal = string.Empty; + var current = 0; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, TabName)) + { + tabName = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Action)) + { + action = value; + } + else if (StringUtils.EqualsIgnoreCase(name, ClassActive)) + { + classActive = value; + } + else if (StringUtils.EqualsIgnoreCase(name, ClassNormal)) + { + classNormal = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Current)) + { + current = TranslateUtils.ToInt(value, 1); + } + } + + return ParseImpl(pageInfo, contextInfo, tabName, type, action, classActive, classNormal, current); + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string tabName, string type, string action, string classActive, string classNormal, int current) + { + pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.Jquery); + + var builder = new StringBuilder(); + var uniqueId = pageInfo.UniqueId; + var isHeader = StringUtils.EqualsIgnoreCase(type, TypeHead); + + var htmlDoc = new HtmlDocument(); + htmlDoc.LoadHtml(contextInfo.InnerHtml); + + var htmlNodes = htmlDoc.DocumentNode.ChildNodes; + if (htmlNodes != null && htmlNodes.Count > 0) + { + if (isHeader) + { + builder.Append($@" + +"); + } + + var count = 0; + foreach (var htmlNode in htmlNodes) + { + if (htmlNode.NodeType != HtmlNodeType.Element) continue; + + var attributes = new NameValueCollection(); + if (htmlNode.Attributes != null) + { + foreach (var attr in htmlNode.Attributes) + { + if (attr == null) continue; + + var attributeName = attr.Name.ToLower(); + if (!StringUtils.EqualsIgnoreCase(attr.Name, "id") && !StringUtils.EqualsIgnoreCase(attr.Name, "onmouseover") && !StringUtils.EqualsIgnoreCase(attr.Name, "onclick")) + { + attributes[attributeName] = attr.Value; + } + } + } + + count++; + if (isHeader) + { + attributes["id"] = $"{tabName}_tabHeader_{count}"; + if (StringUtils.EqualsIgnoreCase(action, ActionMouseOver)) + { + attributes["onmouseover"] = $"stl_tab_{uniqueId}('{tabName}', {count});return false;"; + } + else + { + attributes["onclick"] = $"stl_tab_{uniqueId}('{tabName}', {count});return false;"; + } + if (current != 0) + { + if (count == current) + { + attributes["class"] = classActive; + } + else + { + attributes["class"] = classNormal; + } + } + } + else + { + attributes["id"] = $"{tabName}_tabContent_{count}"; + if (current != 0) + { + if (count != current) + { + attributes["style"] = $"display:none;{attributes["style"]}"; + } + } + } + + var innerHtml = string.Empty; + if (!string.IsNullOrEmpty(htmlNode.InnerHtml)) + { + var innerBuilder = new StringBuilder(htmlNode.InnerHtml); + StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); + innerHtml = innerBuilder.ToString(); + } + + builder.Append( + $"<{htmlNode.Name} {TranslateUtils.ToAttributesString(attributes)}>{innerHtml}"); + } + } + + return builder.ToString(); + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlTags.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlTags.cs new file mode 100644 index 000000000..5da00f881 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlTags.cs @@ -0,0 +1,164 @@ +using System.Collections.Generic; +using System.Text; +using SiteServer.CMS.Caches.Stl; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "标签", Description = "通过 stl:tags 标签在模板中显示内容标签")] + public class StlTags + { + private StlTags() { } + public const string ElementName = "stl:tags"; + + [StlAttribute(Title = "标签级别")] + private const string TagLevel = nameof(TagLevel); + + [StlAttribute(Title = "显示标签数目")] + private const string TotalNum = nameof(TotalNum); + + [StlAttribute(Title = "是否按引用次数排序")] + private const string IsOrderByCount = nameof(IsOrderByCount); + + [StlAttribute(Title = "主题样式")] + private const string Theme = nameof(Theme); + + [StlAttribute(Title = "所处上下文")] + private const string Context = nameof(Context); + + + public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var tagLevel = 1; + var totalNum = 0; + var isOrderByCount = false; + var theme = "default"; + var isInnerHtml = !string.IsNullOrEmpty(contextInfo.InnerHtml); + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, TagLevel)) + { + tagLevel = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, TotalNum)) + { + totalNum = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, IsOrderByCount)) + { + isOrderByCount = TranslateUtils.ToBool(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Theme)) + { + theme = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Context)) + { + contextInfo.ContextType = EContextTypeUtils.GetEnumType(value); + } + } + + return ParseImpl(isInnerHtml, pageInfo, contextInfo, tagLevel, totalNum, isOrderByCount, theme); + } + + private static string ParseImpl(bool isInnerHtml, PageInfo pageInfo, ContextInfo contextInfo, int tagLevel, int totalNum, bool isOrderByCount, string theme) + { + var innerHtml = string.Empty; + if (isInnerHtml) + { + innerHtml = StringUtils.StripTags(contextInfo.OuterHtml, ElementName); + } + + var tagsBuilder = new StringBuilder(); + if (!isInnerHtml) + { + tagsBuilder.Append($@" + +"); + tagsBuilder.Append(@"
      "); + } + + if (contextInfo.ContextType == EContextType.Undefined) + { + contextInfo.ContextType = contextInfo.ContentId != 0 ? EContextType.Content : EContextType.Channel; + } + var contentId = 0; + if (contextInfo.ContextType == EContextType.Content) + { + contentId = contextInfo.ContentId; + } + + var tagInfoList = StlTagCache.GetTagInfoList(pageInfo.SiteId, contentId, isOrderByCount, totalNum); + tagInfoList = TagUtils.GetTagInfoList(tagInfoList, totalNum, tagLevel); + if (contextInfo.ContextType == EContextType.Content && contextInfo.ContentInfo != null) + { + var tagInfoList2 = new List(); + var tagNameList = TranslateUtils.StringCollectionToStringList(contextInfo.ContentInfo.Tags.Trim().Replace(" ", ",")); + foreach (var tagName in tagNameList) + { + if (!string.IsNullOrEmpty(tagName)) + { + var isAdd = false; + foreach (var tagInfo in tagInfoList) + { + if (tagInfo.Tag == tagName) + { + isAdd = true; + tagInfoList2.Add(tagInfo); + break; + } + } + if (!isAdd) + { + var tagInfo = new TagInfo + { + SiteId = pageInfo.SiteId, + ContentIdCollection = contentId.ToString(), + Tag = tagName, + UseNum = 1 + }; + tagInfoList2.Add(tagInfo); + } + } + } + tagInfoList = tagInfoList2; + } + + foreach (var tagInfo in tagInfoList) + { + if (isInnerHtml) + { + var tagHtml = innerHtml; + tagHtml = StringUtils.ReplaceIgnoreCase(tagHtml, "{Tag.Name}", tagInfo.Tag); + tagHtml = StringUtils.ReplaceIgnoreCase(tagHtml, "{Tag.Count}", tagInfo.UseNum.ToString()); + tagHtml = StringUtils.ReplaceIgnoreCase(tagHtml, "{Tag.Level}", tagInfo.Level.ToString()); + var innerBuilder = new StringBuilder(tagHtml); + StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); + tagsBuilder.Append(innerBuilder); + } + else + { + var url = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, + $"@/utils/tags.html?tagName={PageUtils.UrlEncode(tagInfo.Tag)}", pageInfo.IsLocal); + tagsBuilder.Append($@" +
    • {tagInfo.Tag}
    • +"); + } + } + + if (!isInnerHtml) + { + tagsBuilder.Append("
    "); + } + return tagsBuilder.ToString(); + } + } +} diff --git a/SiteServer.CMS/StlParser/StlElement/StlTree.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlTree.cs similarity index 91% rename from SiteServer.CMS/StlParser/StlElement/StlTree.cs rename to net452/SiteServer.CMS/StlParser/StlElement/StlTree.cs index c3beeb862..af1ead823 100644 --- a/SiteServer.CMS/StlParser/StlElement/StlTree.cs +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlTree.cs @@ -1,11 +1,14 @@ using System; using System.Collections.Generic; using System.Text; -using SiteServer.CMS.Api; -using SiteServer.CMS.Api.Sys.Stl; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; using SiteServer.Utils; using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Core.RestRoutes; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.CMS.StlParser.Model; using SiteServer.CMS.StlParser.Parsers; using SiteServer.CMS.StlParser.Utility; @@ -14,24 +17,47 @@ namespace SiteServer.CMS.StlParser.StlElement { - [StlClass(Usage = "树状导航", Description = "通过 stl:tree 标签在模板中显示树状导航")] + [StlElement(Title = "树状导航", Description = "通过 stl:tree 标签在模板中显示树状导航")] public class StlTree { private StlTree() { } public const string ElementName = "stl:tree"; - private static readonly Attr ChannelIndex = new Attr("channelIndex", "栏目索引"); - private static readonly Attr ChannelName = new Attr("channelName", "栏目名称"); - private static readonly Attr UpLevel = new Attr("upLevel", "上级栏目的级别"); - private static readonly Attr TopLevel = new Attr("topLevel", "从首页向下的栏目级别"); - private static readonly Attr GroupChannel = new Attr("groupChannel", "指定显示的栏目组"); - private static readonly Attr GroupChannelNot = new Attr("groupChannelNot", "指定不显示的栏目组"); - private static readonly Attr Title = new Attr("title", "根节点显示名称"); - private static readonly Attr IsLoading = new Attr("isLoading", "是否AJAX方式即时载入"); - private static readonly Attr IsShowContentNum = new Attr("isShowContentNum", "是否显示栏目内容数"); - private static readonly Attr IsShowTreeLine = new Attr("isShowTreeLine", "是否显示树状线"); - private static readonly Attr CurrentFormatString = new Attr("currentFormatString", "当前项格式化字符串"); - private static readonly Attr Target = new Attr("target", "打开窗口目标"); + [StlAttribute(Title = "栏目索引")] + private const string ChannelIndex = nameof(ChannelIndex); + + [StlAttribute(Title = "栏目名称")] + private const string ChannelName = nameof(ChannelName); + + [StlAttribute(Title = "上级栏目的级别")] + private const string UpLevel = nameof(UpLevel); + + [StlAttribute(Title = "从首页向下的栏目级别")] + private const string TopLevel = nameof(TopLevel); + + [StlAttribute(Title = "指定显示的栏目组")] + private const string GroupChannel = nameof(GroupChannel); + + [StlAttribute(Title = "指定不显示的栏目组")] + private const string GroupChannelNot = nameof(GroupChannelNot); + + [StlAttribute(Title = "根节点显示名称")] + private const string Title = nameof(Title); + + [StlAttribute(Title = "是否AJAX方式即时载入")] + private const string IsLoading = nameof(IsLoading); + + [StlAttribute(Title = "是否显示栏目内容数")] + private const string IsShowContentNum = nameof(IsShowContentNum); + + [StlAttribute(Title = "是否显示树状线")] + private const string IsShowTreeLine = nameof(IsShowTreeLine); + + [StlAttribute(Title = "当前项格式化字符串")] + private const string CurrentFormatString = nameof(CurrentFormatString); + + [StlAttribute(Title = "打开窗口目标")] + private const string Target = nameof(Target); public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) { @@ -47,52 +73,52 @@ public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) var isShowTreeLine = true; var currentFormatString = "{0}"; - foreach (var name in contextInfo.Attributes.Keys) + foreach (var name in contextInfo.Attributes.AllKeys) { var value = contextInfo.Attributes[name]; - if (StringUtils.EqualsIgnoreCase(name, ChannelIndex.Name)) + if (StringUtils.EqualsIgnoreCase(name, ChannelIndex)) { channelIndex = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); } - else if (StringUtils.EqualsIgnoreCase(name, ChannelName.Name)) + else if (StringUtils.EqualsIgnoreCase(name, ChannelName)) { channelName = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); } - else if (StringUtils.EqualsIgnoreCase(name, UpLevel.Name)) + else if (StringUtils.EqualsIgnoreCase(name, UpLevel)) { upLevel = TranslateUtils.ToInt(value); } - else if (StringUtils.EqualsIgnoreCase(name, TopLevel.Name)) + else if (StringUtils.EqualsIgnoreCase(name, TopLevel)) { topLevel = TranslateUtils.ToInt(value); } - else if (StringUtils.EqualsIgnoreCase(name, GroupChannel.Name)) + else if (StringUtils.EqualsIgnoreCase(name, GroupChannel)) { groupChannel = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); } - else if (StringUtils.EqualsIgnoreCase(name, GroupChannelNot.Name)) + else if (StringUtils.EqualsIgnoreCase(name, GroupChannelNot)) { groupChannelNot = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); } - else if (StringUtils.EqualsIgnoreCase(name, Title.Name)) + else if (StringUtils.EqualsIgnoreCase(name, Title)) { title = StlEntityParser.ReplaceStlEntitiesForAttributeValue(value, pageInfo, contextInfo); } - else if (StringUtils.EqualsIgnoreCase(name, IsLoading.Name)) + else if (StringUtils.EqualsIgnoreCase(name, IsLoading)) { isLoading = TranslateUtils.ToBool(value, false); } - else if (StringUtils.EqualsIgnoreCase(name, IsShowContentNum.Name)) + else if (StringUtils.EqualsIgnoreCase(name, IsShowContentNum)) { isShowContentNum = TranslateUtils.ToBool(value, false); } - else if (StringUtils.EqualsIgnoreCase(name, IsShowTreeLine.Name)) + else if (StringUtils.EqualsIgnoreCase(name, IsShowTreeLine)) { isShowTreeLine = TranslateUtils.ToBool(value, true); } - else if (StringUtils.EqualsIgnoreCase(name, CurrentFormatString.Name)) + else if (StringUtils.EqualsIgnoreCase(name, CurrentFormatString)) { currentFormatString = value; if (!StringUtils.Contains(currentFormatString, "{0}")) @@ -119,7 +145,7 @@ private static string ParseImplNotAjax(PageInfo pageInfo, ContextInfo contextInf htmlBuilder.Append(@""); - //var theChannelIdList = DataProvider.ChannelDao.GetIdListByScopeType(channel.ChannelId, channel.ChildrenCount, EScopeType.All, groupChannel, groupChannelNot); + //var theChannelIdList = DataProvider.Channel.GetIdListByScopeType(channel.ChannelId, channel.ChildrenCount, EScopeType.All, groupChannel, groupChannelNot); var theChannelIdList = ChannelManager.GetChannelIdList(channel, EScopeType.All, groupChannel, groupChannelNot, string.Empty); var isLastNodeArray = new bool[theChannelIdList.Count]; var channelIdList = new List(); @@ -134,7 +160,7 @@ private static string ParseImplNotAjax(PageInfo pageInfo, ContextInfo contextInf foreach (var theChannelId in theChannelIdList) { var theChannelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, theChannelId); - var nodeInfo = new ChannelInfo(theChannelInfo); + var nodeInfo = (ChannelInfo)theChannelInfo.Clone(); if (theChannelId == pageInfo.SiteId && !string.IsNullOrEmpty(title)) { nodeInfo.ChannelName = title; @@ -216,7 +242,7 @@ public StlTreeItemNotAjax(bool isDisplay, bool selected, PageInfo pageInfo, Chan public string GetTrHtml() { - var displayHtml = (_isDisplay) ? StringUtils.Constants.ShowElementStyle : StringUtils.Constants.HideElementStyle; + var displayHtml = (_isDisplay) ? Constants.ShowElementStyle : Constants.HideElementStyle; string trElementHtml = $@" ' ); + + tempIndex === 2 && tmpl.push(''); + + } + + return '
    ' + + '
    ' + + '
    @@ -235,9 +261,9 @@ private string GetItemHtml() { if (_topChannelId == _nodeInfo.Id) { - _nodeInfo.IsLastNode = true; + _nodeInfo.LastNode = true; } - if (_nodeInfo.IsLastNode == false) + if (_nodeInfo.LastNode == false) { _isLastNodeArray[_level] = false; } @@ -264,7 +290,7 @@ private string GetItemHtml() { if (_isShowTreeLine) { - if (_nodeInfo.IsLastNode) + if (_nodeInfo.LastNode) { if (_hasChildren) { @@ -314,7 +340,7 @@ private string GetItemHtml() { if (_isShowTreeLine) { - if (_nodeInfo.IsLastNode) + if (_nodeInfo.LastNode) { htmlBuilder.Append( _hasChildren @@ -346,7 +372,7 @@ private string GetItemHtml() htmlBuilder.Append(" "); var nodeName = _nodeInfo.ChannelName; - if ((_pageInfo.TemplateInfo.TemplateType == TemplateType.ChannelTemplate || _pageInfo.TemplateInfo.TemplateType == TemplateType.ContentTemplate) && _pageInfo.PageChannelId == _nodeInfo.Id) + if ((_pageInfo.TemplateInfo.Type == TemplateType.ChannelTemplate || _pageInfo.TemplateInfo.Type == TemplateType.ContentTemplate) && _pageInfo.PageChannelId == _nodeInfo.Id) { nodeName = string.Format(_currentFormatString, nodeName); } @@ -364,10 +390,11 @@ private string GetItemHtml() htmlBuilder.Append(nodeName); } - if (_isShowContentNum && _nodeInfo.ContentNum >= 0) + if (_isShowContentNum) { + var count = ContentManager.GetCount(_pageInfo.SiteInfo, _nodeInfo, true); htmlBuilder.Append(" "); - htmlBuilder.Append($"({_nodeInfo.ContentNum})"); + htmlBuilder.Append($"({count})"); } return htmlBuilder.ToString(); @@ -567,13 +594,13 @@ private static string ParseImplAjax(PageInfo pageInfo, ContextInfo contextInfo, htmlBuilder.Append(@""); - //var theChannelIdList = DataProvider.ChannelDao.GetIdListByScopeType(channel.ChannelId, channel.ChildrenCount, EScopeType.SelfAndChildren, groupChannel, groupChannelNot); + //var theChannelIdList = DataProvider.Channel.GetIdListByScopeType(channel.ChannelId, channel.ChildrenCount, EScopeType.SelfAndChildren, groupChannel, groupChannelNot); var theChannelIdList = ChannelManager.GetChannelIdList(channel, EScopeType.SelfAndChildren, groupChannel, groupChannelNot, string.Empty); foreach (var theChannelId in theChannelIdList) { var theChannelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, theChannelId); - var nodeInfo = new ChannelInfo(theChannelInfo); + var nodeInfo = (ChannelInfo)theChannelInfo.Clone(); if (theChannelId == pageInfo.SiteId && !string.IsNullOrEmpty(title)) { nodeInfo.ChannelName = title; @@ -617,6 +644,7 @@ private class StlTreeItemAjax private readonly string _iconMinusUrl; private readonly string _iconPlusUrl; + private readonly SiteInfo _siteInfo; private readonly ChannelInfo _nodeInfo; private readonly bool _hasChildren; private readonly string _linkUrl; @@ -629,6 +657,7 @@ private class StlTreeItemAjax public StlTreeItemAjax(SiteInfo siteInfo, ChannelInfo nodeInfo, string target, bool isShowContentNum, string currentFormatString, int topChannelId, int topParentsCount, int currentChannelId, bool isLocal) { + _siteInfo = siteInfo; _nodeInfo = nodeInfo; _hasChildren = nodeInfo.ChildrenCount != 0; _linkUrl = PageUtility.GetChannelUrl(siteInfo, nodeInfo, isLocal); @@ -639,7 +668,7 @@ public StlTreeItemAjax(SiteInfo siteInfo, ChannelInfo nodeInfo, string target, b _level = nodeInfo.ParentsCount - topParentsCount; _currentChannelId = currentChannelId; - var treeDirectoryUrl = SiteFilesAssets.GetUrl(ApiManager.OuterApiUrl, "tree"); + var treeDirectoryUrl = SiteFilesAssets.GetUrl(ApiManager.ApiUrl, "tree"); _iconFolderUrl = PageUtils.Combine(treeDirectoryUrl, "folder.gif"); _iconEmptyUrl = PageUtils.Combine(treeDirectoryUrl, "empty.gif"); _iconMinusUrl = PageUtils.Combine(treeDirectoryUrl, "minus.png"); @@ -691,10 +720,11 @@ public string GetItemHtml() htmlBuilder.Append(nodeName); } - if (_isShowContentNum && _nodeInfo.ContentNum >= 0) + if (_isShowContentNum) { + var count = ContentManager.GetCount(_siteInfo, _nodeInfo, true); htmlBuilder.Append(" "); - htmlBuilder.Append($"({_nodeInfo.ContentNum})"); + htmlBuilder.Append($"({count})"); } return htmlBuilder.ToString(); diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlValue.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlValue.cs new file mode 100644 index 000000000..6a19e6c89 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlValue.cs @@ -0,0 +1,224 @@ +using System.Collections.Generic; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.StlParser.Model; +using SiteServer.Plugin; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "获取值", Description = "通过 stl:value 标签在模板中获取值")] + public class StlValue + { + private StlValue(){} + public const string ElementName = "stl:value"; + + [StlAttribute(Title = "类型")] + private const string Type = nameof(Type); + + [StlAttribute(Title = "显示的格式")] + private const string FormatString = nameof(FormatString); + + [StlAttribute(Title = "显示多项时的分割字符串")] + private const string Separator = nameof(Separator); + + [StlAttribute(Title = "字符开始位置")] + private const string StartIndex = nameof(StartIndex); + + [StlAttribute(Title = "指定字符长度")] + private const string Length = nameof(Length); + + [StlAttribute(Title = "显示字符的数目")] + private const string WordNum = nameof(WordNum); + + [StlAttribute(Title = "文字超出部分显示的文字")] + private const string Ellipsis = nameof(Ellipsis); + + [StlAttribute(Title = "需要替换的文字,可以是正则表达式")] + private const string Replace = nameof(Replace); + + [StlAttribute(Title = "替换replace的文字信息")] + private const string To = nameof(To); + + [StlAttribute(Title = "是否清除标签信息")] + private const string IsClearTags = nameof(IsClearTags); + + [StlAttribute(Title = "是否将回车替换为HTML换行标签")] + private const string IsReturnToBr = nameof(IsReturnToBr); + + [StlAttribute(Title = "是否转换为小写")] + private const string IsLower = nameof(IsLower); + + [StlAttribute(Title = "是否转换为大写")] + private const string IsUpper = nameof(IsUpper); + + public const string TypeSiteName = "SiteName"; + public const string TypeSiteUrl = "SiteUrl"; + public const string TypeDate = "Date"; + public const string TypeDateOfTraditional = "DateOfTraditional"; + + public static SortedList TypeList => new SortedList + { + {TypeSiteName, "站点名称"}, + {TypeSiteUrl, "站点的域名地址"}, + {TypeDate, "当前日期"}, + {TypeDateOfTraditional, "带农历的当前日期"} + }; + + public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var type = string.Empty; + var formatString = string.Empty; + string separator = null; + var startIndex = 0; + var length = 0; + var wordNum = 0; + var ellipsis = Constants.Ellipsis; + var replace = string.Empty; + var to = string.Empty; + var isClearTags = false; + var isReturnToBr = false; + var isLower = false; + var isUpper = false; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value; + } + else if (StringUtils.EqualsIgnoreCase(name, FormatString)) + { + formatString = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Separator)) + { + separator = value; + } + else if (StringUtils.EqualsIgnoreCase(name, StartIndex)) + { + startIndex = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Length)) + { + length = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, WordNum)) + { + wordNum = TranslateUtils.ToInt(value); + } + else if (StringUtils.EqualsIgnoreCase(name, Ellipsis)) + { + ellipsis = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Replace)) + { + replace = value; + } + else if (StringUtils.EqualsIgnoreCase(name, To)) + { + to = value; + } + else if (StringUtils.EqualsIgnoreCase(name, IsClearTags)) + { + isClearTags = TranslateUtils.ToBool(value, false); + } + else if (StringUtils.EqualsIgnoreCase(name, IsReturnToBr)) + { + isReturnToBr = TranslateUtils.ToBool(value, false); + } + else if (StringUtils.EqualsIgnoreCase(name, IsLower)) + { + isLower = TranslateUtils.ToBool(value, true); + } + else if (StringUtils.EqualsIgnoreCase(name, IsUpper)) + { + isUpper = TranslateUtils.ToBool(value, true); + } + } + + return ParseImpl(pageInfo, contextInfo, type, formatString, separator, startIndex, length, wordNum, ellipsis, replace, to, isClearTags, isReturnToBr, isLower, isUpper); + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string type, string formatString, string separator, int startIndex, int length, int wordNum, string ellipsis, string replace, string to, bool isClearTags, bool isReturnToBr, bool isLower, bool isUpper) + { + if (string.IsNullOrEmpty(type)) return string.Empty; + + var parsedContent = string.Empty; + + if (contextInfo.ContextType == EContextType.Each) + { + parsedContent = contextInfo.ItemContainer.EachItem.DataItem as string; + return parsedContent; + } + + if (type.ToLower().Equals(TypeSiteName.ToLower())) + { + parsedContent = pageInfo.SiteInfo.SiteName; + } + else if (type.ToLower().Equals(TypeSiteUrl.ToLower())) + { + parsedContent = pageInfo.SiteInfo.WebUrl; + } + else if (type.ToLower().Equals(TypeDate.ToLower())) + { + if (!pageInfo.BodyCodes.ContainsKey("datestring.js")) + { + pageInfo.BodyCodes.Add("datestring.js", $@""); + } + + parsedContent = @""; + } + else if (type.ToLower().Equals(TypeDateOfTraditional.ToLower())) + { + if (!pageInfo.BodyCodes.ContainsKey("datestring")) + { + pageInfo.BodyCodes.Add("datestring", $@""); + } + + parsedContent = @""; + } + else if (pageInfo.Parameters != null && pageInfo.Parameters.ContainsKey(type)) + { + pageInfo.Parameters.TryGetValue(type, out parsedContent); + parsedContent = InputTypeUtils.ParseString(InputType.Text, parsedContent, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); + } + else + { + if (pageInfo.SiteInfo.ContainsKey(type)) + { + parsedContent = pageInfo.SiteInfo.Get(type); + if (!string.IsNullOrEmpty(parsedContent)) + { + var styleInfo = TableStyleManager.GetTableStyleInfo(DataProvider.Site.TableName, type, TableStyleManager.GetRelatedIdentities(pageInfo.SiteId)); + + // 如果 styleInfo.TableStyleId <= 0,表示此字段已经被删除了,不需要再显示值了 ekun008 + if (styleInfo.Id > 0) + { + if (isClearTags && InputTypeUtils.EqualsAny(styleInfo.Type, InputType.Image, InputType.File)) + { + parsedContent = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); + } + else + { + parsedContent = InputParserUtility.GetContentByTableStyle(parsedContent, separator, pageInfo.SiteInfo, styleInfo, formatString, contextInfo.Attributes, contextInfo.InnerHtml, false, isLower, isUpper); + parsedContent = InputTypeUtils.ParseString(styleInfo.Type, parsedContent, replace, to, startIndex, length, wordNum, ellipsis, isClearTags, isReturnToBr, isLower, isUpper, formatString); + } + } + else + { // 如果字段已经被删除或不再显示了,则此字段的值为空。有时虚拟字段值不会清空 + parsedContent = string.Empty; + } + } + } + } + return parsedContent; + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlVideo.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlVideo.cs new file mode 100644 index 000000000..5a429daeb --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlVideo.cs @@ -0,0 +1,177 @@ +using System.Collections.Generic; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Stl; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.StlParser.Model; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "播放视频", Description = "通过 stl:video 标签在模板中显示视频播放器")] + public class StlVideo + { + private StlVideo() { } + public const string ElementName = "stl:video"; + + [StlAttribute(Title = "指定视频的字段")] + private const string Type = nameof(Type); + + [StlAttribute(Title = "视频地址")] + private const string PlayUrl = nameof(PlayUrl); + + [StlAttribute(Title = "图片地址")] + private const string ImageUrl = nameof(ImageUrl); + + [StlAttribute(Title = "宽度")] + private const string Width = nameof(Width); + + [StlAttribute(Title = "高度")] + private const string Height = nameof(Height); + + [StlAttribute(Title = "是否自动播放")] + private const string IsAutoPlay = nameof(IsAutoPlay); + + [StlAttribute(Title = "是否显示播放控件")] + private const string IsControls = nameof(IsControls); + + [StlAttribute(Title = "是否循环播放")] + private const string IsLoop = nameof(IsLoop); + + public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) + { + var type = ContentAttribute.VideoUrl; + var playUrl = string.Empty; + var imageUrl = string.Empty; + var width = 0; + var height = 280; + var isAutoPlay = true; + var isControls = true; + var isLoop = false; + + foreach (var name in contextInfo.Attributes.AllKeys) + { + var value = contextInfo.Attributes[name]; + + if (StringUtils.EqualsIgnoreCase(name, Type)) + { + type = value; + } + else if (StringUtils.EqualsIgnoreCase(name, PlayUrl)) + { + playUrl = value; + } + else if (StringUtils.EqualsIgnoreCase(name, ImageUrl)) + { + imageUrl = value; + } + else if (StringUtils.EqualsIgnoreCase(name, Width)) + { + width = TranslateUtils.ToInt(value, width); + } + else if (StringUtils.EqualsIgnoreCase(name, Height)) + { + height = TranslateUtils.ToInt(value, height); + } + else if (StringUtils.EqualsIgnoreCase(name, IsAutoPlay)) + { + isAutoPlay = TranslateUtils.ToBool(value, true); + } + else if (StringUtils.EqualsIgnoreCase(name, IsControls)) + { + isControls = TranslateUtils.ToBool(value, true); + } + else if (StringUtils.EqualsIgnoreCase(name, IsLoop)) + { + isLoop = TranslateUtils.ToBool(value, false); + } + } + + return ParseImpl(pageInfo, contextInfo, type, playUrl, imageUrl, width, height, isAutoPlay, isControls, isLoop); + } + + private static string ParseImpl(PageInfo pageInfo, ContextInfo contextInfo, string type, string playUrl, string imageUrl, int width, int height, bool isAutoPlay, bool isControls, bool isLoop) + { + + + var videoUrl = string.Empty; + if (!string.IsNullOrEmpty(playUrl)) + { + videoUrl = playUrl; + } + else + { + var contentId = contextInfo.ContentId; + if (contextInfo.ContextType == EContextType.Content) + { + if (contentId != 0)//获取内容视频 + { + if (contextInfo.ContentInfo == null) + { + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, pageInfo.SiteId); + videoUrl = StlContentCache.GetValue(channelInfo, contentId, type); + if (string.IsNullOrEmpty(videoUrl)) + { + if (!StringUtils.EqualsIgnoreCase(type, ContentAttribute.VideoUrl)) + { + videoUrl = StlContentCache.GetValue(channelInfo, contentId, ContentAttribute.VideoUrl); + } + } + } + else + { + videoUrl = contextInfo.ContentInfo.Get(type); + if (string.IsNullOrEmpty(videoUrl)) + { + videoUrl = contextInfo.ContentInfo.Get(ContentAttribute.VideoUrl); + } + } + } + } + else if (contextInfo.ContextType == EContextType.Each) + { + videoUrl = contextInfo.ItemContainer.EachItem.DataItem as string; + } + } + + if (string.IsNullOrEmpty(videoUrl)) return string.Empty; + + videoUrl = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, videoUrl, pageInfo.IsLocal); + imageUrl = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, imageUrl, pageInfo.IsLocal); + + pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.JsAcVideoJs); + + var dict = new Dictionary + { + {"class", "video-js vjs-default-skin"}, + {"src", videoUrl} + }; + if (isAutoPlay) + { + dict.Add("autoplay", null); + } + if (isControls) + { + dict.Add("controls", null); + } + if (isLoop) + { + dict.Add("loop", null); + } + if (!string.IsNullOrEmpty(imageUrl)) + { + dict.Add("poster", imageUrl); + } + if (width > 0) + { + dict.Add("width", width.ToString()); + } + if (height > 0) + { + dict.Add("height", height.ToString()); + } + + return $@""; + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlElement/StlYes.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlYes.cs new file mode 100644 index 000000000..0d7520212 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlYes.cs @@ -0,0 +1,11 @@ +using SiteServer.CMS.StlParser.Model; + +namespace SiteServer.CMS.StlParser.StlElement +{ + [StlElement(Title = "成功模板", Description = "通过 stl:yes 标签在模板中显示成功模板")] + public sealed class StlYes + { + public const string ElementName = "stl:yes"; + public const string ElementName2 = "stl:successtemplate"; + } +} diff --git a/SiteServer.CMS/StlParser/StlElement/StlZoom.cs b/net452/SiteServer.CMS/StlParser/StlElement/StlZoom.cs similarity index 80% rename from SiteServer.CMS/StlParser/StlElement/StlZoom.cs rename to net452/SiteServer.CMS/StlParser/StlElement/StlZoom.cs index 259114489..ce45e0b87 100644 --- a/SiteServer.CMS/StlParser/StlElement/StlZoom.cs +++ b/net452/SiteServer.CMS/StlParser/StlElement/StlZoom.cs @@ -1,19 +1,23 @@ using System.Text; using System.Web.UI.HtmlControls; +using SiteServer.CMS.Fx; using SiteServer.Utils; using SiteServer.CMS.StlParser.Model; using SiteServer.CMS.StlParser.Utility; namespace SiteServer.CMS.StlParser.StlElement { - [StlClass(Usage = "文字缩放", Description = "通过 stl:zoom 标签在模板中实现文字缩放功能")] + [StlElement(Title = "文字缩放", Description = "通过 stl:zoom 标签在模板中实现文字缩放功能")] public class StlZoom { private StlZoom() { } public const string ElementName = "stl:zoom"; - private static readonly Attr ZoomId = new Attr("zoomId", "页面HTML中缩放对象的ID属性"); - private static readonly Attr FontSize = new Attr("fontSize", "缩放字体大小"); + [StlAttribute(Title = "页面Html 中缩放对象的 Id 属性")] + private const string ZoomId = nameof(ZoomId); + + [StlAttribute(Title = "缩放字体大小")] + private const string FontSize = nameof(FontSize); public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) { @@ -21,15 +25,15 @@ public static string Parse(PageInfo pageInfo, ContextInfo contextInfo) var fontSize = 16; var stlAnchor = new HtmlAnchor(); - foreach (var name in contextInfo.Attributes.Keys) + foreach (var name in contextInfo.Attributes.AllKeys) { var value = contextInfo.Attributes[name]; - if (StringUtils.EqualsIgnoreCase(name, ZoomId.Name)) + if (StringUtils.EqualsIgnoreCase(name, ZoomId)) { zoomId = value; } - else if (StringUtils.EqualsIgnoreCase(name, FontSize.Name)) + else if (StringUtils.EqualsIgnoreCase(name, FontSize)) { fontSize = TranslateUtils.ToInt(value, 16); } @@ -70,13 +74,13 @@ function stlDoZoom(zoomId, size){ "); } - if (string.IsNullOrEmpty(contextInfo.InnerXml)) + if (string.IsNullOrEmpty(contextInfo.InnerHtml)) { stlAnchor.InnerHtml = "缩放"; } else { - var innerBuilder = new StringBuilder(contextInfo.InnerXml); + var innerBuilder = new StringBuilder(contextInfo.InnerHtml); StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); stlAnchor.InnerHtml = innerBuilder.ToString(); } diff --git a/net452/SiteServer.CMS/StlParser/StlEntity/StlChannelEntities.cs b/net452/SiteServer.CMS/StlParser/StlEntity/StlChannelEntities.cs new file mode 100644 index 000000000..5e4d5e8dd --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlEntity/StlChannelEntities.cs @@ -0,0 +1,185 @@ +using System; +using System.Collections.Generic; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Plugin; + +namespace SiteServer.CMS.StlParser.StlEntity +{ + [StlElement(Title = "栏目实体", Description = "通过 {channel.} 实体在模板中显示栏目值")] + public static class StlChannelEntities + { + public const string EntityName = "channel"; + + private const string ChannelId = nameof(ChannelId); + private const string ChannelName = nameof(ChannelName); + private const string ChannelIndex = nameof(ChannelIndex); + private const string Title = nameof(Title); + private const string Content = nameof(Content); + private const string NavigationUrl = nameof(NavigationUrl); + private const string ImageUrl = nameof(ImageUrl); + private const string AddDate = nameof(AddDate); + private const string DirectoryName = nameof(DirectoryName); + private const string Group = nameof(Group); + private const string ItemIndex = nameof(ItemIndex); + + public static SortedList AttributeList => new SortedList + { + {ChannelId, "栏目ID"}, + {Title, "栏目名称"}, + {ChannelName, "栏目名称"}, + {ChannelIndex, "栏目索引"}, + {Content, "栏目正文"}, + {NavigationUrl, "栏目链接地址"}, + {ImageUrl, "栏目图片地址"}, + {AddDate, "栏目添加日期"}, + {DirectoryName, "生成文件夹名称"}, + {Group, "栏目组别"}, + {ItemIndex, "栏目排序"} + }; + + internal static string Parse(string stlEntity, PageInfo pageInfo, ContextInfo contextInfo) + { + var parsedContent = string.Empty; + + try + { + var entityName = StlParserUtility.GetNameFromEntity(stlEntity); + var channelIndex = StlParserUtility.GetValueFromEntity(stlEntity); + var attributeName = entityName.Substring(9, entityName.Length - 10); + + var upLevel = 0; + var topLevel = -1; + var channelId = contextInfo.ChannelId; + if (!string.IsNullOrEmpty(channelIndex)) + { + //channelId = DataProvider.Channel.GetIdByIndexName(pageInfo.SiteId, channelIndex); + channelId = ChannelManager.GetChannelIdByIndexName(pageInfo.SiteId, channelIndex); + if (channelId == 0) + { + channelId = contextInfo.ChannelId; + } + } + + if (attributeName.ToLower().StartsWith("up") && attributeName.IndexOf(".", StringComparison.Ordinal) != -1) + { + if (attributeName.ToLower().StartsWith("up.")) + { + upLevel = 1; + } + else + { + var upLevelStr = attributeName.Substring(2, attributeName.IndexOf(".", StringComparison.Ordinal) - 2); + upLevel = TranslateUtils.ToInt(upLevelStr); + } + topLevel = -1; + attributeName = attributeName.Substring(attributeName.IndexOf(".", StringComparison.Ordinal) + 1); + } + else if (attributeName.ToLower().StartsWith("top") && attributeName.IndexOf(".", StringComparison.Ordinal) != -1) + { + if (attributeName.ToLower().StartsWith("top.")) + { + topLevel = 1; + } + else + { + var topLevelStr = attributeName.Substring(3, attributeName.IndexOf(".", StringComparison.Ordinal) - 3); + topLevel = TranslateUtils.ToInt(topLevelStr); + } + upLevel = 0; + attributeName = attributeName.Substring(attributeName.IndexOf(".", StringComparison.Ordinal) + 1); + } + + var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, StlDataUtility.GetChannelIdByLevel(pageInfo.SiteId, channelId, upLevel, topLevel)); + + if (StringUtils.EqualsIgnoreCase(ChannelId, attributeName))//栏目ID + { + parsedContent = nodeInfo.Id.ToString(); + } + else if (StringUtils.EqualsIgnoreCase(Title, attributeName) || StringUtils.EqualsIgnoreCase(ChannelName, attributeName))//栏目名称 + { + parsedContent = nodeInfo.ChannelName; + } + else if (StringUtils.EqualsIgnoreCase(ChannelIndex, attributeName))//栏目索引 + { + parsedContent = nodeInfo.IndexName; + } + else if (StringUtils.EqualsIgnoreCase(Content, attributeName))//栏目正文 + { + parsedContent = ContentUtility.TextEditorContentDecode(pageInfo.SiteInfo, nodeInfo.Content, pageInfo.IsLocal); + } + else if (StringUtils.EqualsIgnoreCase(NavigationUrl, attributeName))//栏目链接地址 + { + parsedContent = PageUtility.GetChannelUrl(pageInfo.SiteInfo, nodeInfo, pageInfo.IsLocal); + } + else if (StringUtils.EqualsIgnoreCase(ImageUrl, attributeName))//栏目图片地址 + { + parsedContent = nodeInfo.ImageUrl; + + if (!string.IsNullOrEmpty(parsedContent)) + { + parsedContent = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); + } + } + else if (StringUtils.EqualsIgnoreCase(AddDate, attributeName))//栏目添加日期 + { + parsedContent = DateUtils.Format(nodeInfo.AddDate, string.Empty); + } + else if (StringUtils.EqualsIgnoreCase(DirectoryName, attributeName))//生成文件夹名称 + { + parsedContent = PathUtils.GetDirectoryName(nodeInfo.FilePath, true); + } + else if (StringUtils.EqualsIgnoreCase(Group, attributeName))//栏目组别 + { + parsedContent = nodeInfo.GroupNameCollection; + } + else if (StringUtils.StartsWithIgnoreCase(attributeName, StlParserUtility.ItemIndex) && contextInfo.ItemContainer?.ChannelItem != null) + { + parsedContent = StlParserUtility.ParseItemIndex(contextInfo.ItemContainer.ChannelItem.ItemIndex, attributeName, contextInfo).ToString(); + } + else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.Keywords, attributeName))//栏目组别 + { + parsedContent = nodeInfo.Keywords; + } + else if (StringUtils.EqualsIgnoreCase(ChannelAttribute.Description, attributeName))//栏目组别 + { + parsedContent = nodeInfo.Description; + } + else + { + //var styleInfo = TableStyleManager.GetTableStyleInfo(ETableStyle.Channel, DataProvider.Channel.TableName, attributeName, RelatedIdentities.GetChannelRelatedIdentities(pageInfo.SiteId, nodeInfo.ChannelId)); + //parsedContent = InputParserUtility.GetContentByTableStyle(parsedContent, ",", pageInfo.SiteInfo, ETableStyle.Channel, styleInfo, string.Empty, null, string.Empty, true); + + var styleInfo = TableStyleManager.GetTableStyleInfo(DataProvider.Channel.TableName, attributeName, TableStyleManager.GetRelatedIdentities(nodeInfo)); + // 如果 styleInfo.TableStyleId <= 0,表示此字段已经被删除了,不需要再显示值了 ekun008 + if (styleInfo.Id > 0) + { + parsedContent = nodeInfo.Get(attributeName, styleInfo.DefaultValue); + if (!string.IsNullOrEmpty(parsedContent)) + { + if (InputTypeUtils.EqualsAny(styleInfo.Type, InputType.Image, InputType.File)) + { + parsedContent = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); + } + else + { + parsedContent = InputParserUtility.GetContentByTableStyle(parsedContent, null, pageInfo.SiteInfo, styleInfo, string.Empty, null, string.Empty, true, false, false); + } + } + } + } + } + catch + { + // ignored + } + + return parsedContent; + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlEntity/StlContentEntities.cs b/net452/SiteServer.CMS/StlParser/StlEntity/StlContentEntities.cs new file mode 100644 index 000000000..0a46e3853 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlEntity/StlContentEntities.cs @@ -0,0 +1,321 @@ +using System.Collections.Generic; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Caches.Stl; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.StlEntity +{ + [StlElement(Title = "内容实体", Description = "通过 {content.} 实体在模板中显示内容值")] + public class StlContentEntities + { + private StlContentEntities() + { + } + + public const string EntityName = "content"; + + public const string Id = "Id"; + public const string Title = "Title"; + public const string FullTitle = "FullTitle"; + public const string NavigationUrl = "NavigationUrl"; + public const string ImageUrl = "ImageUrl"; + public const string VideoUrl = "VideoUrl"; + public const string FileUrl = "FileUrl"; + public const string DownloadUrl = "DownloadUrl"; + public const string AddDate = "AddDate"; + public const string LastEditDate = "LastEditDate"; + public const string Content = "Content"; + public const string Group = "Group"; + public const string Tags = "Tags"; + public const string AddUserName = "AddUserName"; + public const string ItemIndex = "ItemIndex"; + + public static SortedList AttributeList => new SortedList + { + {Id, "内容ID"}, + {Title, "内容标题"}, + {FullTitle, "内容标题全称"}, + {Content, "内容正文"}, + {NavigationUrl, "内容链接地址"}, + {ImageUrl, "内容图片地址"}, + {VideoUrl, "内容视频地址"}, + {FileUrl, "内容附件地址"}, + {DownloadUrl, "内容附件地址(可统计下载量)"}, + {AddDate, "内容添加日期"}, + {LastEditDate, "内容最后修改日期"}, + {Group, "内容组别"}, + {Tags, "内容标签"}, + {AddUserName, "内容添加人"}, + {ItemIndex, "内容排序"} + }; + + internal static string Parse(string stlEntity, PageInfo pageInfo, ContextInfo contextInfo) + { + var parsedContent = string.Empty; + + if (contextInfo.ContentId != 0) + { + try + { + if (contextInfo.ContentInfo != null && contextInfo.ContentInfo.ReferenceId > 0 && contextInfo.ContentInfo.SourceId > 0 && contextInfo.ContentInfo.Get(ContentAttribute.TranslateContentType) != ETranslateContentType.ReferenceContent.ToString()) + { + var targetChannelId = contextInfo.ContentInfo.SourceId; + var targetSiteId = StlChannelCache.GetSiteId(targetChannelId); + var targetSiteInfo = SiteManager.GetSiteInfo(targetSiteId); + var targetNodeInfo = ChannelManager.GetChannelInfo(targetSiteId, targetChannelId); + + var targetContentInfo = ContentManager.GetContentInfo(targetSiteInfo, targetNodeInfo, contextInfo.ContentInfo.ReferenceId); + if (targetContentInfo != null && targetContentInfo.ChannelId > 0) + { + //标题可以使用自己的 + targetContentInfo.Title = contextInfo.ContentInfo.Title; + + contextInfo.ContentInfo = targetContentInfo; + } + } + + var entityName = StlParserUtility.GetNameFromEntity(stlEntity); + var attributeName = entityName.Substring(9, entityName.Length - 10); + + if (StringUtils.EqualsIgnoreCase(ContentAttribute.Id, attributeName))//内容ID + { + if (contextInfo.ContentInfo != null) + { + parsedContent = contextInfo.ContentInfo.ReferenceId > 0 ? contextInfo.ContentInfo.ReferenceId.ToString() : contextInfo.ContentInfo.Id.ToString(); + } + else + { + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + //parsedContent = DataProvider.ContentRepository.GetValueById(tableName, contextInfo.ContentId, ContentAttribute.Id); + parsedContent = StlContentCache.GetValue(channelInfo, contextInfo.ContentId, ContentAttribute.Id); + } + } + else if (StringUtils.EqualsIgnoreCase(Title, attributeName))//内容标题 + { + if (contextInfo.ContentInfo != null) + { + parsedContent = contextInfo.ContentInfo.Title; + } + else + { + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); //parsedContent = DataProvider.ContentRepository.GetValueById(tableName, contextInfo.ContentId, ContentAttribute.Title); + parsedContent = StlContentCache.GetValue(channelInfo, contextInfo.ContentId, ContentAttribute.Title); + } + } + else if (StringUtils.EqualsIgnoreCase(FullTitle, attributeName))//内容标题全称 + { + if (contextInfo.ContentInfo != null) + { + parsedContent = contextInfo.ContentInfo.Title; + } + else + { + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + //parsedContent = DataProvider.ContentRepository.GetValueById(tableName, contextInfo.ContentId, ContentAttribute.Title); + parsedContent = StlContentCache.GetValue(channelInfo, contextInfo.ContentId, ContentAttribute.Title); + } + } + else if (StringUtils.EqualsIgnoreCase(NavigationUrl, attributeName))//内容链接地址 + { + if (contextInfo.ContentInfo != null) + { + parsedContent = PageUtility.GetContentUrl(pageInfo.SiteInfo, contextInfo.ContentInfo, pageInfo.IsLocal); + } + else + { + var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + parsedContent = PageUtility.GetContentUrl(pageInfo.SiteInfo, nodeInfo, contextInfo.ContentId, pageInfo.IsLocal); + } + } + else if (StringUtils.EqualsIgnoreCase(ImageUrl, attributeName))//内容图片地址 + { + if (contextInfo.ContentInfo != null) + { + parsedContent = contextInfo.ContentInfo.Get(ContentAttribute.ImageUrl); + } + else + { + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + parsedContent = StlContentCache.GetValue(channelInfo, contextInfo.ContentId, ContentAttribute.ImageUrl); + } + + if (!string.IsNullOrEmpty(parsedContent)) + { + parsedContent = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); + } + } + else if (StringUtils.EqualsIgnoreCase(VideoUrl, attributeName))//内容视频地址 + { + if (contextInfo.ContentInfo != null) + { + parsedContent = contextInfo.ContentInfo.Get(ContentAttribute.VideoUrl); + } + else + { + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + parsedContent = StlContentCache.GetValue(channelInfo, contextInfo.ContentId, ContentAttribute.VideoUrl); + } + + if (!string.IsNullOrEmpty(parsedContent)) + { + parsedContent = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); + } + } + else if (StringUtils.EqualsIgnoreCase(FileUrl, attributeName))//内容附件地址 + { + if (contextInfo.ContentInfo != null) + { + parsedContent = contextInfo.ContentInfo.Get(ContentAttribute.FileUrl); + } + else + { + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + parsedContent = StlContentCache.GetValue(channelInfo, contextInfo.ContentId, ContentAttribute.FileUrl); + } + + if (!string.IsNullOrEmpty(parsedContent)) + { + parsedContent = PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); + } + } + else if (StringUtils.EqualsIgnoreCase(DownloadUrl, attributeName))//内容附件地址(可统计下载量) + { + if (contextInfo.ContentInfo != null) + { + parsedContent = contextInfo.ContentInfo.Get(ContentAttribute.FileUrl); + } + else + { + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + parsedContent = StlContentCache.GetValue(channelInfo, contextInfo.ContentId, ContentAttribute.FileUrl); + } + + if (!string.IsNullOrEmpty(parsedContent)) + { + parsedContent = ApiRouteActionsDownload.GetUrl(pageInfo.ApiUrl, pageInfo.SiteId, contextInfo.ChannelId, contextInfo.ContentId, parsedContent); + } + } + else if (StringUtils.EqualsIgnoreCase(AddDate, attributeName))//内容添加日期 + { + if (contextInfo.ContentInfo != null) + { + parsedContent = DateUtils.Format(contextInfo.ContentInfo.AddDate, string.Empty); + } + } + else if (StringUtils.EqualsIgnoreCase(LastEditDate, attributeName))//替换最后修改日期 + { + if (contextInfo.ContentInfo != null) + { + parsedContent = DateUtils.Format(contextInfo.ContentInfo.LastEditDate, string.Empty); + } + } + else if (StringUtils.EqualsIgnoreCase(Content, attributeName))//内容正文 + { + if (contextInfo.ContentInfo != null) + { + parsedContent = contextInfo.ContentInfo.Get(ContentAttribute.Content); + } + else + { + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + parsedContent = StlContentCache.GetValue(channelInfo, contextInfo.ContentId, ContentAttribute.Content); + } + parsedContent = ContentUtility.TextEditorContentDecode(pageInfo.SiteInfo, parsedContent, pageInfo.IsLocal); + } + else if (StringUtils.EqualsIgnoreCase(Group, attributeName))//内容组别 + { + if (contextInfo.ContentInfo != null) + { + parsedContent = contextInfo.ContentInfo.GroupNameCollection; + } + else + { + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + parsedContent = StlContentCache.GetValue(channelInfo, contextInfo.ContentId, ContentAttribute.GroupNameCollection); + } + } + else if (StringUtils.EqualsIgnoreCase(Tags, attributeName))//标签 + { + if (contextInfo.ContentInfo != null) + { + parsedContent = contextInfo.ContentInfo.Tags; + } + else + { + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + parsedContent = StlContentCache.GetValue(channelInfo, contextInfo.ContentId, ContentAttribute.Tags); + } + } + else if (StringUtils.EqualsIgnoreCase(AddUserName, attributeName)) + { + string addUserName; + if (contextInfo.ContentInfo != null) + { + addUserName = contextInfo.ContentInfo.AddUserName; + } + else + { + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + addUserName = StlContentCache.GetValue(channelInfo, contextInfo.ContentId, ContentAttribute.AddUserName); + } + if (!string.IsNullOrEmpty(addUserName)) + { + parsedContent = addUserName; + } + } + else if (StringUtils.StartsWithIgnoreCase(attributeName, StlParserUtility.ItemIndex) && contextInfo.ItemContainer?.ContentItem != null) + { + parsedContent = StlParserUtility.ParseItemIndex(contextInfo.ItemContainer.ContentItem.ItemIndex, attributeName, contextInfo).ToString(); + } + else + { + int contentChannelId; + if (contextInfo.ContentInfo != null) + { + contentChannelId = contextInfo.ContentInfo.ChannelId; + if (contextInfo.ContentInfo.ContainsKey(attributeName)) + { + parsedContent = contextInfo.ContentInfo.Get(attributeName); + } + } + else + { + var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, contextInfo.ChannelId); + //contentChannelId = DataProvider.ContentRepository.GetChannelId(tableName, contextInfo.ContentId); + contentChannelId = StlContentCache.GetChannelId(tableName, contextInfo.ContentId); + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contentChannelId); + parsedContent = StlContentCache.GetValue(channelInfo, contextInfo.ContentId, attributeName); + } + + if (!string.IsNullOrEmpty(parsedContent)) + { + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contentChannelId); + var tableName = ChannelManager.GetTableName(pageInfo.SiteInfo, channelInfo); + var relatedIdentities = TableStyleManager.GetRelatedIdentities(channelInfo); + var styleInfo = TableStyleManager.GetTableStyleInfo(tableName, attributeName, relatedIdentities); + + //styleInfo.IsVisible = false 表示此字段不需要显示 styleInfo.TableStyleId = 0 不能排除,因为有可能是直接辅助表字段没有添加显示样式 + parsedContent = InputParserUtility.GetContentByTableStyle(parsedContent, ",", pageInfo.SiteInfo, styleInfo, string.Empty, null, string.Empty, true, false, false); + } + + } + } + catch + { + // ignored + } + } + + parsedContent = parsedContent.Replace(ContentUtility.PagePlaceHolder, string.Empty); + + return parsedContent; + } + } +} diff --git a/SiteServer.CMS/StlParser/StlEntity/StlElementEntities.cs b/net452/SiteServer.CMS/StlParser/StlEntity/StlElementEntities.cs similarity index 83% rename from SiteServer.CMS/StlParser/StlEntity/StlElementEntities.cs rename to net452/SiteServer.CMS/StlParser/StlEntity/StlElementEntities.cs index 9ed37f5f1..c87ae2f09 100644 --- a/SiteServer.CMS/StlParser/StlEntity/StlElementEntities.cs +++ b/net452/SiteServer.CMS/StlParser/StlEntity/StlElementEntities.cs @@ -5,7 +5,7 @@ namespace SiteServer.CMS.StlParser.StlEntity { - [StlClass(Usage = "STL标签实体", Description = "通过 {stl:} 实体在模板中实现STL标签")] + [StlElement(Title = "STL标签实体", Description = "通过 {stl:} 实体在模板中实现STL标签")] public class StlElementEntities { private StlElementEntities() @@ -23,7 +23,7 @@ internal static string Parse(string stlEntity, PageInfo pageInfo, ContextInfo co contextInfo.IsStlEntity = true; try { - var stlElement = StlParserUtility.HtmlToXml($"<{stlEntity.Trim(' ', '{', '}')} />"); + var stlElement = $"<{stlEntity.Trim(' ', '{', '}')} />"; var innerBuilder = new StringBuilder(stlElement); StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); diff --git a/net452/SiteServer.CMS/StlParser/StlEntity/StlNavigationEntities.cs b/net452/SiteServer.CMS/StlParser/StlEntity/StlNavigationEntities.cs new file mode 100644 index 000000000..5120cc1da --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlEntity/StlNavigationEntities.cs @@ -0,0 +1,85 @@ +using System.Collections.Generic; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Caches.Stl; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.StlEntity +{ + [StlElement(Title = "导航实体", Description = "通过 {navigation.} 实体在模板中显示导航链接")] + public class StlNavigationEntities + { + private StlNavigationEntities() + { + } + + public const string EntityName = "navigation"; + + public static string PreviousChannel = "PreviousChannel"; + public static string NextChannel = "NextChannel"; + public static string PreviousContent = "PreviousContent"; + public static string NextContent = "NextContent"; + + public static SortedList AttributeList => new SortedList + { + {PreviousChannel, "上一栏目链接"}, + {NextChannel, "下一栏目链接"}, + {PreviousContent, "上一内容链接"}, + {NextContent, "下一内容链接"} + }; + + internal static string Parse(string stlEntity, PageInfo pageInfo, ContextInfo contextInfo) + { + var parsedContent = string.Empty; + try + { + var entityName = StlParserUtility.GetNameFromEntity(stlEntity); + var attributeName = entityName.Substring(12, entityName.Length - 13); + + var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + + if (StringUtils.EqualsIgnoreCase(PreviousChannel, attributeName) || StringUtils.EqualsIgnoreCase(NextChannel, attributeName)) + { + var taxis = nodeInfo.Taxis; + var isNextChannel = !StringUtils.EqualsIgnoreCase(attributeName, PreviousChannel); + //var siblingChannelId = DataProvider.Channel.GetIdByParentIdAndTaxis(nodeInfo.ParentId, taxis, isNextChannel); + var siblingChannelId = StlChannelCache.GetIdByParentIdAndTaxis(nodeInfo.ParentId, taxis, isNextChannel); + if (siblingChannelId != 0) + { + var siblingNodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, siblingChannelId); + parsedContent = PageUtility.GetChannelUrl(pageInfo.SiteInfo, siblingNodeInfo, pageInfo.IsLocal); + } + } + else if (StringUtils.EqualsIgnoreCase(PreviousContent, attributeName) || StringUtils.EqualsIgnoreCase(NextContent, attributeName)) + { + if (contextInfo.ContentId != 0) + { + var taxis = contextInfo.ContentInfo.Taxis; + var isNextContent = !StringUtils.EqualsIgnoreCase(attributeName, PreviousContent); + var channelInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId); + var siblingContentId = StlContentCache.GetContentId(channelInfo, taxis, isNextContent); + if (siblingContentId != 0) + { + var contentInfo = ContentManager.GetContentInfo(pageInfo.SiteInfo, contextInfo.ChannelId, siblingContentId); + parsedContent = PageUtility.GetContentUrl(pageInfo.SiteInfo, contentInfo, pageInfo.IsLocal); + } + } + } + } + catch + { + // ignored + } + + if (string.IsNullOrEmpty(parsedContent)) + { + parsedContent = PageUtils.UnClickedUrl; + } + + return parsedContent; + } + } +} diff --git a/SiteServer.CMS/StlParser/StlEntity/StlRequestEntities.cs b/net452/SiteServer.CMS/StlParser/StlEntity/StlRequestEntities.cs similarity index 77% rename from SiteServer.CMS/StlParser/StlEntity/StlRequestEntities.cs rename to net452/SiteServer.CMS/StlParser/StlEntity/StlRequestEntities.cs index a063efdd8..491f0a01c 100644 --- a/SiteServer.CMS/StlParser/StlEntity/StlRequestEntities.cs +++ b/net452/SiteServer.CMS/StlParser/StlEntity/StlRequestEntities.cs @@ -1,5 +1,4 @@ -using System.Collections.Generic; -using System.Collections.Specialized; +using System.Collections.Specialized; using System.Text; using SiteServer.Utils; using SiteServer.CMS.StlParser.Model; @@ -7,28 +6,22 @@ namespace SiteServer.CMS.StlParser.StlEntity { - [StlClass(Usage = "请求实体", Description = "通过 {request.} 实体在模板中显示地址栏请求参数")] - public class StlRequestEntities + [StlElement(Title = "请求实体", Description = "通过 {request.} 实体在模板中显示地址栏请求参数")] + public static class StlRequestEntities { - private StlRequestEntities() - { - } - - public const string EntityName = "request"; - - public static SortedList AttributeList => null; - - internal static string Parse(string stlEntity, PageInfo pageInfo, ContextInfo contextInfo) + internal static string Parse(string stlEntity, PageInfo pageInfo) { var parsedContent = string.Empty; try { + pageInfo.AddPageBodyCodeIfNotExists(PageInfo.Const.Jquery); + var entityName = StlParserUtility.GetNameFromEntity(stlEntity); var entityValue = StlParserUtility.GetValueFromEntity(stlEntity); var attributeName = entityName.Substring(9, entityName.Length - 10); var ajaxDivId = StlParserUtility.GetAjaxDivId(pageInfo.UniqueId); - string functionName = $"stlRequest_{ajaxDivId}"; + var functionName = $"stlRequest_{ajaxDivId}"; parsedContent = $@""; var builder = new StringBuilder(); @@ -42,7 +35,7 @@ internal static string Parse(string stlEntity, PageInfo pageInfo, ContextInfo co var reg = new RegExp(""(^|&){attributeName}=([^&]*)(&|$)""); var r = queryString.substring(1).match(reg); var v = decodeURI(decodeURI(r[2])); - if (r) $(""#{ajaxDivId}"").html(v);"); + if (r) $(""#{ajaxDivId}"").text(v);"); if (!string.IsNullOrEmpty(entityValue)) { @@ -51,8 +44,8 @@ internal static string Parse(string stlEntity, PageInfo pageInfo, ContextInfo co } builder.Append(@" - }}catch(e){{}} -}}); + }catch(e){} +}); "); @@ -75,7 +68,7 @@ public static string ParseRequestEntities(NameValueCollection queryString, strin { foreach (string key in queryString.Keys) { - templateContent = StringUtils.ReplaceIgnoreCase(templateContent, $"{{Request.{key}}}", queryString[key]); + templateContent = StringUtils.ReplaceIgnoreCase(templateContent, $"{{Request.{key}}}", AttackUtils.FilterSqlAndXss(queryString[key])); } } return RegexUtils.Replace("{Request.[^}]+}", templateContent, string.Empty); diff --git a/SiteServer.CMS/StlParser/StlEntity/StlSqlEntities.cs b/net452/SiteServer.CMS/StlParser/StlEntity/StlSqlEntities.cs similarity index 91% rename from SiteServer.CMS/StlParser/StlEntity/StlSqlEntities.cs rename to net452/SiteServer.CMS/StlParser/StlEntity/StlSqlEntities.cs index 2e84e5afb..005a426e9 100644 --- a/SiteServer.CMS/StlParser/StlEntity/StlSqlEntities.cs +++ b/net452/SiteServer.CMS/StlParser/StlEntity/StlSqlEntities.cs @@ -6,7 +6,7 @@ namespace SiteServer.CMS.StlParser.StlEntity { - [StlClass(Usage = "数据库实体", Description = "通过 {sql.} 实体在模板中显示数据库值")] + [StlElement(Title = "数据库实体", Description = "通过 {sql.} 实体在模板中显示数据库值")] public class StlSqlEntities { private StlSqlEntities() diff --git a/net452/SiteServer.CMS/StlParser/StlEntity/StlStlEntities.cs b/net452/SiteServer.CMS/StlParser/StlEntity/StlStlEntities.cs new file mode 100644 index 000000000..b7406c2e8 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlEntity/StlStlEntities.cs @@ -0,0 +1,172 @@ +using System.Collections.Generic; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Plugin; + +namespace SiteServer.CMS.StlParser.StlEntity +{ + [StlElement(Title = "通用实体", Description = "通过 {stl.} 实体在模板中显示对应数据")] + public class StlStlEntities + { + private StlStlEntities() + { + } + + public const string EntityName = "stl"; + + public static string PoweredBy = "PoweredBy"; + public static string SiteName = "SiteName"; + public static string SiteId = "SiteId"; + public static string SiteDir = "SiteDir"; + public static string SiteUrl = "SiteUrl"; + public static string RootUrl = "RootUrl"; + public static string ApiUrl = "ApiUrl"; + public static string CurrentUrl = "CurrentUrl"; + public static string ChannelUrl = "ChannelUrl"; + public static string HomeUrl = "HomeUrl"; + public static string LoginUrl = "LoginUrl"; + public static string RegisterUrl = "RegisterUrl"; + public static string LogoutUrl = "LogoutUrl"; + + public static SortedList AttributeList => new SortedList + { + {PoweredBy, "PoweredBy 链接"}, + {SiteName, "站点名称"}, + {SiteId, "站点ID"}, + {SiteDir, "站点文件夹"}, + {SiteUrl, "站点根目录地址"}, + {RootUrl, "系统根目录地址"}, + {ApiUrl, "Api地址"}, + {CurrentUrl, "当前页地址"}, + {ChannelUrl, "栏目页地址"}, + {HomeUrl, "用户中心地址"}, + {LoginUrl, "用户中心登录页地址"}, + {RegisterUrl, "用户中心注册页地址"}, + {LogoutUrl, "退出登录页地址"} + }; + + internal static string Parse(string stlEntity, PageInfo pageInfo, ContextInfo contextInfo) + { + var parsedContent = string.Empty; + try + { + var entityName = StlParserUtility.GetNameFromEntity(stlEntity); + var attributeName = entityName.Substring(5, entityName.Length - 6); + + if (StringUtils.EqualsIgnoreCase(PoweredBy, attributeName))//支持信息 + { + parsedContent = @"Powered by SiteServer CMS"; + } + else if (StringUtils.EqualsIgnoreCase(RootUrl, attributeName))//系统根目录地址 + { + parsedContent = FxUtils.ParseConfigRootUrl("~"); + if (!string.IsNullOrEmpty(parsedContent)) + { + parsedContent = parsedContent.TrimEnd('/'); + } + } + else if (StringUtils.EqualsIgnoreCase(ApiUrl, attributeName))//API地址 + { + parsedContent = pageInfo.ApiUrl.TrimEnd('/'); + } + else if (StringUtils.EqualsIgnoreCase(SiteId, attributeName))//ID + { + parsedContent = pageInfo.SiteId.ToString(); + } + else if (StringUtils.EqualsIgnoreCase(SiteName, attributeName))//名称 + { + parsedContent = pageInfo.SiteInfo.SiteName; + } + else if (StringUtils.EqualsIgnoreCase(SiteUrl, attributeName))//域名地址 + { + parsedContent = PageUtility.GetSiteUrl(pageInfo.SiteInfo, pageInfo.IsLocal).TrimEnd('/'); + } + else if (StringUtils.EqualsIgnoreCase(SiteDir, attributeName))//文件夹 + { + parsedContent = pageInfo.SiteInfo.SiteDir; + } + else if (StringUtils.EqualsIgnoreCase(CurrentUrl, attributeName))//当前页地址 + { + parsedContent = StlParserUtility.GetStlCurrentUrl(pageInfo.SiteInfo, contextInfo.ChannelId, contextInfo.ContentId, contextInfo.ContentInfo, pageInfo.TemplateInfo.Type, pageInfo.TemplateInfo.Id, pageInfo.IsLocal); + } + else if (StringUtils.EqualsIgnoreCase(ChannelUrl, attributeName))//栏目页地址 + { + parsedContent = PageUtility.GetChannelUrl(pageInfo.SiteInfo, ChannelManager.GetChannelInfo(pageInfo.SiteId, contextInfo.ChannelId), pageInfo.IsLocal); + } + else if (StringUtils.EqualsIgnoreCase(HomeUrl, attributeName))//用户中心地址 + { + parsedContent = FxUtils.GetHomeUrl(string.Empty).TrimEnd('/'); + } + else if (StringUtils.EqualsIgnoreCase(LoginUrl, attributeName)) + { + var returnUrl = StlParserUtility.GetStlCurrentUrl(pageInfo.SiteInfo, contextInfo.ChannelId, contextInfo.ContentId, contextInfo.ContentInfo, pageInfo.TemplateInfo.Type, pageInfo.TemplateInfo.Id, pageInfo.IsLocal); + parsedContent = FxUtils.GetHomeUrl($"pages/login.html?returnUrl={PageUtils.UrlEncode(returnUrl)}"); + } + else if (StringUtils.EqualsIgnoreCase(LogoutUrl, attributeName)) + { + var returnUrl = StlParserUtility.GetStlCurrentUrl(pageInfo.SiteInfo, contextInfo.ChannelId, contextInfo.ContentId, contextInfo.ContentInfo, pageInfo.TemplateInfo.Type, pageInfo.TemplateInfo.Id, pageInfo.IsLocal); + parsedContent = FxUtils.GetHomeUrl($"pages/logout.html?returnUrl={PageUtils.UrlEncode(returnUrl)}"); + } + else if (StringUtils.EqualsIgnoreCase(RegisterUrl, attributeName)) + { + var returnUrl = StlParserUtility.GetStlCurrentUrl(pageInfo.SiteInfo, contextInfo.ChannelId, contextInfo.ContentId, contextInfo.ContentInfo, pageInfo.TemplateInfo.Type, pageInfo.TemplateInfo.Id, pageInfo.IsLocal); + parsedContent = FxUtils.GetHomeUrl($"pages/register.html?returnUrl={PageUtils.UrlEncode(returnUrl)}"); + } + else if (StringUtils.StartsWithIgnoreCase(attributeName, "TableFor"))// + { + if (StringUtils.EqualsIgnoreCase(attributeName, "TableForContent")) + { + parsedContent = pageInfo.SiteInfo.TableName; + } + } + else if (StringUtils.StartsWithIgnoreCase(attributeName, "Site"))// + { + parsedContent = pageInfo.SiteInfo.Get(attributeName.Substring(4)); + } + else if (pageInfo.Parameters != null && pageInfo.Parameters.ContainsKey(attributeName)) + { + pageInfo.Parameters.TryGetValue(attributeName, out parsedContent); + } + else + { + if (pageInfo.SiteInfo.ContainsKey(attributeName)) + { + parsedContent = pageInfo.SiteInfo.Get(attributeName); + + if (!string.IsNullOrEmpty(parsedContent)) + { + var styleInfo = TableStyleManager.GetTableStyleInfo(DataProvider.Site.TableName, attributeName, TableStyleManager.GetRelatedIdentities(pageInfo.SiteId)); + + // 如果 styleInfo.TableStyleId <= 0,表示此字段已经被删除了,不需要再显示值了 ekun008 + if (styleInfo.Id > 0) + { + parsedContent = InputTypeUtils.EqualsAny(styleInfo.Type, InputType.Image, + InputType.File) + ? PageUtility.ParseNavigationUrl(pageInfo.SiteInfo, parsedContent, + pageInfo.IsLocal) + : InputParserUtility.GetContentByTableStyle(parsedContent, string.Empty, + pageInfo.SiteInfo, styleInfo, string.Empty, null, string.Empty, + true, false, false); + } + else + { // 如果字段已经被删除或不再显示了,则此字段的值为空。有时虚拟字段值不会清空 + parsedContent = string.Empty; + } + } + } + } + } + catch + { + // ignored + } + + return parsedContent; + } + } +} diff --git a/net452/SiteServer.CMS/StlParser/StlEntity/StlUserEntities.cs b/net452/SiteServer.CMS/StlParser/StlEntity/StlUserEntities.cs new file mode 100644 index 000000000..c7024a46a --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/StlEntity/StlUserEntities.cs @@ -0,0 +1,104 @@ +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Attributes; +using SiteServer.Utils; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Utility; + +namespace SiteServer.CMS.StlParser.StlEntity +{ + [StlElement(Title = "用户实体", Description = "通过 {user.} 实体在模板中显示用户值")] + public class StlUserEntities + { + private StlUserEntities() + { + } + + public const string EntityName = "user"; + + internal static string Parse(string stlEntity, PageInfo pageInfo) + { + var parsedContent = string.Empty; + if (pageInfo?.UserInfo == null) return string.Empty; + + try + { + var entityName = StlParserUtility.GetNameFromEntity(stlEntity); + var attributeName = entityName.Substring(6, entityName.Length - 7); + + if (StringUtils.EqualsIgnoreCase(UserAttribute.Id, attributeName)) + { + parsedContent = pageInfo.UserInfo.Id.ToString(); + } + else if (StringUtils.EqualsIgnoreCase(UserAttribute.UserName, attributeName)) + { + parsedContent = pageInfo.UserInfo.UserName; + } + else if (StringUtils.EqualsIgnoreCase(UserAttribute.CreateDate, attributeName)) + { + parsedContent = DateUtils.Format(pageInfo.UserInfo.CreateDate, string.Empty); + } + else if (StringUtils.EqualsIgnoreCase(UserAttribute.LastActivityDate, attributeName)) + { + parsedContent = DateUtils.Format(pageInfo.UserInfo.LastActivityDate, string.Empty); + } + else if (StringUtils.EqualsIgnoreCase(UserAttribute.CountOfLogin, attributeName)) + { + parsedContent = pageInfo.UserInfo.CountOfLogin.ToString(); + } + else if (StringUtils.EqualsIgnoreCase(UserAttribute.DisplayName, attributeName)) + { + parsedContent = pageInfo.UserInfo.DisplayName; + } + else if (StringUtils.EqualsIgnoreCase(UserAttribute.Email, attributeName)) + { + parsedContent = pageInfo.UserInfo.Email; + } + else if (StringUtils.EqualsIgnoreCase(UserAttribute.Mobile, attributeName)) + { + parsedContent = pageInfo.UserInfo.Mobile; + } + else if (StringUtils.EqualsIgnoreCase(UserAttribute.AvatarUrl, attributeName)) + { + parsedContent = UserManager.GetUserAvatarUrl(pageInfo.UserInfo); + } + else if (StringUtils.EqualsIgnoreCase(UserAttribute.Gender, attributeName)) + { + parsedContent = pageInfo.UserInfo.Gender; + } + else if (StringUtils.EqualsIgnoreCase(UserAttribute.Birthday, attributeName)) + { + parsedContent = pageInfo.UserInfo.Birthday; + } + else if (StringUtils.EqualsIgnoreCase(UserAttribute.WeiXin, attributeName)) + { + parsedContent = pageInfo.UserInfo.WeiXin; + } + else if (StringUtils.EqualsIgnoreCase(UserAttribute.Qq, attributeName)) + { + parsedContent = pageInfo.UserInfo.Qq; + } + else if (StringUtils.EqualsIgnoreCase(UserAttribute.WeiBo, attributeName)) + { + parsedContent = pageInfo.UserInfo.WeiBo; + } + else if (StringUtils.EqualsIgnoreCase(UserAttribute.Bio, attributeName)) + { + parsedContent = pageInfo.UserInfo.Bio; + } + else + { + if (pageInfo.UserInfo.ContainsKey(attributeName)) + { + parsedContent = pageInfo.UserInfo.Get(attributeName); + } + } + } + catch + { + // ignored + } + + return parsedContent; + } + } +} diff --git a/SiteServer.CMS/StlParser/Utility/DataListTemplate.cs b/net452/SiteServer.CMS/StlParser/Utility/DataListTemplate.cs similarity index 87% rename from SiteServer.CMS/StlParser/Utility/DataListTemplate.cs rename to net452/SiteServer.CMS/StlParser/Utility/DataListTemplate.cs index 635e690ae..f980d6510 100644 --- a/SiteServer.CMS/StlParser/Utility/DataListTemplate.cs +++ b/net452/SiteServer.CMS/StlParser/Utility/DataListTemplate.cs @@ -1,17 +1,18 @@ using System; +using System.Collections.Specialized; using System.Web.UI; using System.Web.UI.WebControls; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; using SiteServer.CMS.StlParser.Model; -using SiteServer.Utils; namespace SiteServer.CMS.StlParser.Utility { public class DataListTemplate : ITemplate { private readonly string _templateString; - private readonly LowerNameValueCollection _selectedItems; - private readonly LowerNameValueCollection _selectedValues; + private readonly NameValueCollection _selectedItems; + private readonly NameValueCollection _selectedValues; private readonly string _separatorRepeatTemplate; private readonly int _separatorRepeat; private readonly EContextType _contextType; @@ -19,7 +20,7 @@ public class DataListTemplate : ITemplate private readonly PageInfo _pageInfo; private int _i; - public DataListTemplate(string templateString, LowerNameValueCollection selectedItems, LowerNameValueCollection selectedValues, string separatorRepeatTemplate, int separatorRepeat, PageInfo pageInfo, EContextType contextType, ContextInfo contextInfo) + public DataListTemplate(string templateString, NameValueCollection selectedItems, NameValueCollection selectedValues, string separatorRepeatTemplate, int separatorRepeat, PageInfo pageInfo, EContextType contextType, ContextInfo contextInfo) { _templateString = templateString; _selectedItems = selectedItems; diff --git a/SiteServer.CMS/StlParser/Utility/PagerUtility.cs b/net452/SiteServer.CMS/StlParser/Utility/PagerUtility.cs similarity index 98% rename from SiteServer.CMS/StlParser/Utility/PagerUtility.cs rename to net452/SiteServer.CMS/StlParser/Utility/PagerUtility.cs index c04196309..e4a8e50be 100644 --- a/SiteServer.CMS/StlParser/Utility/PagerUtility.cs +++ b/net452/SiteServer.CMS/StlParser/Utility/PagerUtility.cs @@ -1,5 +1,6 @@ -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Models; using SiteServer.CMS.StlParser.StlElement; namespace SiteServer.CMS.StlParser.Utility diff --git a/SiteServer.CMS/StlParser/Utility/RepeaterTemplate.cs b/net452/SiteServer.CMS/StlParser/Utility/RepeaterTemplate.cs similarity index 87% rename from SiteServer.CMS/StlParser/Utility/RepeaterTemplate.cs rename to net452/SiteServer.CMS/StlParser/Utility/RepeaterTemplate.cs index eb43e53dd..8c2ff14a5 100644 --- a/SiteServer.CMS/StlParser/Utility/RepeaterTemplate.cs +++ b/net452/SiteServer.CMS/StlParser/Utility/RepeaterTemplate.cs @@ -1,17 +1,18 @@ using System; +using System.Collections.Specialized; using System.Web.UI; using System.Web.UI.WebControls; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; using SiteServer.CMS.StlParser.Model; -using SiteServer.Utils; namespace SiteServer.CMS.StlParser.Utility { public class RepeaterTemplate : ITemplate { private readonly string _templateString; - private readonly LowerNameValueCollection _selectedItems; - private readonly LowerNameValueCollection _selectedValues; + private readonly NameValueCollection _selectedItems; + private readonly NameValueCollection _selectedValues; private readonly string _separatorRepeatTemplate; private readonly int _separatorRepeat; private readonly PageInfo _pageInfo; @@ -19,7 +20,7 @@ public class RepeaterTemplate : ITemplate private readonly ContextInfo _contextInfo; private int _i; - public RepeaterTemplate(string templateString, LowerNameValueCollection selectedItems, LowerNameValueCollection selectedValues, string separatorRepeatTemplate, int separatorRepeat, PageInfo pageInfo, EContextType contextType, ContextInfo contextInfo) + public RepeaterTemplate(string templateString, NameValueCollection selectedItems, NameValueCollection selectedValues, string separatorRepeatTemplate, int separatorRepeat, PageInfo pageInfo, EContextType contextType, ContextInfo contextInfo) { _templateString = templateString; _selectedItems = selectedItems; diff --git a/SiteServer.CMS/StlParser/Utility/SeparatorTemplate.cs b/net452/SiteServer.CMS/StlParser/Utility/SeparatorTemplate.cs similarity index 100% rename from SiteServer.CMS/StlParser/Utility/SeparatorTemplate.cs rename to net452/SiteServer.CMS/StlParser/Utility/SeparatorTemplate.cs diff --git a/SiteServer.CMS/StlParser/Utility/StlAjaxLoading.cs b/net452/SiteServer.CMS/StlParser/Utility/StlAjaxLoading.cs similarity index 95% rename from SiteServer.CMS/StlParser/Utility/StlAjaxLoading.cs rename to net452/SiteServer.CMS/StlParser/Utility/StlAjaxLoading.cs index 24df541c0..624a0cdc4 100644 --- a/SiteServer.CMS/StlParser/Utility/StlAjaxLoading.cs +++ b/net452/SiteServer.CMS/StlParser/Utility/StlAjaxLoading.cs @@ -1,4 +1,5 @@ -using SiteServer.Utils; +using SiteServer.CMS.Fx; +using SiteServer.Utils; namespace SiteServer.CMS.StlParser.Utility { @@ -56,7 +57,7 @@ public string GetScript() { if (!string.IsNullOrEmpty(AjaxUrl)) { - var ajaxUrl = PageUtils.ParseNavigationUrl(AjaxUrl); + var ajaxUrl = FxUtils.ParseNavigationUrl(AjaxUrl); string updateScript = $"{ScriptName}();"; if (!string.IsNullOrEmpty(Updater) && !string.IsNullOrEmpty(Event)) diff --git a/net452/SiteServer.CMS/StlParser/Utility/StlDataUtility.cs b/net452/SiteServer.CMS/StlParser/Utility/StlDataUtility.cs new file mode 100644 index 000000000..08821c231 --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/Utility/StlDataUtility.cs @@ -0,0 +1,385 @@ +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Data; +using System.Linq; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Stl; +using SiteServer.Utils; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.Plugin; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.CMS.StlParser.Utility +{ + public static class StlDataUtility + { + public static int GetChannelIdByChannelIdOrChannelIndexOrChannelName(int siteId, int channelId, string channelIndex, string channelName) + { + var retVal = channelId; + + if (!string.IsNullOrEmpty(channelIndex)) + { + var theChannelId = ChannelManager.GetChannelIdByIndexName(siteId, channelIndex); + if (theChannelId != 0) + { + retVal = theChannelId; + } + } + if (!string.IsNullOrEmpty(channelName)) + { + var theChannelId = ChannelManager.GetChannelIdByParentIdAndChannelName(siteId, retVal, channelName, true); + if (theChannelId == 0) + { + theChannelId = ChannelManager.GetChannelIdByParentIdAndChannelName(siteId, siteId, channelName, true); + } + if (theChannelId != 0) + { + retVal = theChannelId; + } + } + + return retVal; + } + + public static int GetChannelIdByLevel(int siteId, int channelId, int upLevel, int topLevel) + { + var theChannelId = channelId; + var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (nodeInfo != null) + { + if (topLevel >= 0) + { + if (topLevel > 0) + { + if (topLevel < nodeInfo.ParentsCount) + { + var parentIdStrList = TranslateUtils.StringCollectionToStringList(nodeInfo.ParentsPath); + if (parentIdStrList[topLevel] != null) + { + var parentIdStr = parentIdStrList[topLevel]; + theChannelId = int.Parse(parentIdStr); + } + } + } + else + { + theChannelId = siteId; + } + } + else if (upLevel > 0) + { + if (upLevel < nodeInfo.ParentsCount) + { + var parentIdStrList = TranslateUtils.StringCollectionToStringList(nodeInfo.ParentsPath); + if (parentIdStrList[upLevel] != null) + { + var parentIdStr = parentIdStrList[nodeInfo.ParentsCount - upLevel]; + theChannelId = int.Parse(parentIdStr); + } + } + else + { + theChannelId = siteId; + } + } + } + return theChannelId; + } + + public static List GetChannelIdList(int siteId, int channelId, string orderByString, EScopeType scopeType, string groupChannel, string groupChannelNot, bool isImageExists, bool isImage, int totalNum, string where) + { + var whereString = StlChannelCache.GetWhereString(siteId, groupChannel, groupChannelNot, isImageExists, isImage, where); + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + var channelIdList = ChannelManager.GetChannelIdList(channelInfo, scopeType, groupChannel, groupChannelNot, string.Empty); + return StlChannelCache.GetIdListByTotalNum(channelIdList, totalNum, orderByString, whereString); + } + + //public static int GetChannelIdByChannelIDOrChannelIndexOrChannelName(int siteID, int channelID, string channelIndex, string channelName) + //{ + // int retVal = channelID; + // if (!string.IsNullOrEmpty(channelIndex)) + // { + // int theChannelId = DataProvider.NodeDAO.GetChannelIdByNodeIndexName(siteID, channelIndex); + // if (theChannelId != 0) + // { + // retVal = theChannelId; + // } + // } + // if (!string.IsNullOrEmpty(channelName)) + // { + // int theChannelId = DataProvider.NodeDAO.GetChannelIdByParentIDAndNodeName(retVal, channelName, true); + // if (theChannelId == 0) + // { + // theChannelId = DataProvider.NodeDAO.GetChannelIdByParentIDAndNodeName(siteID, channelName, true); + // } + // if (theChannelId != 0) + // { + // retVal = theChannelId; + // } + // } + // return retVal; + //} + + + public static string GetChannelOrderByString(string orderValue, ETaxisType defaultType) + { + var taxisType = defaultType; + var orderByString = string.Empty; + if (!string.IsNullOrEmpty(orderValue)) + { + if (orderValue.ToLower().Equals(StlParserUtility.OrderDefault.ToLower())) + { + taxisType = ETaxisType.OrderByTaxis; + } + else if (orderValue.ToLower().Equals(StlParserUtility.OrderBack.ToLower())) + { + taxisType = ETaxisType.OrderByTaxisDesc; + } + else if (orderValue.ToLower().Equals(StlParserUtility.OrderAddDate.ToLower())) + { + taxisType = ETaxisType.OrderByAddDateDesc; + } + else if (orderValue.ToLower().Equals(StlParserUtility.OrderAddDateBack.ToLower())) + { + taxisType = ETaxisType.OrderByAddDate; + } + else if (orderValue.ToLower().Equals(StlParserUtility.OrderHits.ToLower())) + { + taxisType = ETaxisType.OrderByHits; + } + else if (orderValue.ToLower().Equals(StlParserUtility.OrderRandom.ToLower())) + { + taxisType = ETaxisType.OrderByRandom; + } + else + { + orderByString = orderValue; + } + } + + return ETaxisTypeUtils.GetChannelOrderByString(taxisType, orderByString, null); + } + + public static string GetContentOrderByString(string orderValue, ETaxisType defaultType) + { + var taxisType = defaultType; + var orderByString = string.Empty; + if (!string.IsNullOrEmpty(orderValue)) + { + if (orderValue.ToLower().Equals(StlParserUtility.OrderDefault.ToLower())) + { + taxisType = ETaxisType.OrderByTaxisDesc; + } + else if (orderValue.ToLower().Equals(StlParserUtility.OrderBack.ToLower())) + { + taxisType = ETaxisType.OrderByTaxis; + } + else if (orderValue.ToLower().Equals(StlParserUtility.OrderAddDate.ToLower())) + { + taxisType = ETaxisType.OrderByAddDateDesc; + } + else if (orderValue.ToLower().Equals(StlParserUtility.OrderAddDateBack.ToLower())) + { + taxisType = ETaxisType.OrderByAddDate; + } + else if (orderValue.ToLower().Equals(StlParserUtility.OrderLastEditDate.ToLower())) + { + taxisType = ETaxisType.OrderByLastEditDateDesc; + } + else if (orderValue.ToLower().Equals(StlParserUtility.OrderLastEditDateBack.ToLower())) + { + taxisType = ETaxisType.OrderByLastEditDate; + } + else if (orderValue.ToLower().Equals(StlParserUtility.OrderHits.ToLower())) + { + taxisType = ETaxisType.OrderByHits; + } + else if (orderValue.ToLower().Equals(StlParserUtility.OrderHitsByDay.ToLower())) + { + taxisType = ETaxisType.OrderByHitsByDay; + } + else if (orderValue.ToLower().Equals(StlParserUtility.OrderHitsByWeek.ToLower())) + { + taxisType = ETaxisType.OrderByHitsByWeek; + } + else if (orderValue.ToLower().Equals(StlParserUtility.OrderHitsByMonth.ToLower())) + { + taxisType = ETaxisType.OrderByHitsByMonth; + } + else if (orderValue.ToLower().Equals(StlParserUtility.OrderRandom.ToLower())) + { + taxisType = ETaxisType.OrderByRandom; + } + else + { + orderByString = orderValue; + } + } + + return ETaxisTypeUtils.GetContentOrderByString(taxisType, orderByString); + } + + public static string GetStlPageContentsSqlString(SiteInfo siteInfo, int channelId, ListInfo listInfo) + { + if (!ChannelManager.IsExists(siteInfo.Id, channelId)) return string.Empty; + + var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + + var sqlWhereString = ChannelManager.IsContentModelPlugin(channelInfo) + ? StlContentCache.GetStlWhereString(siteInfo.Id, listInfo.GroupContent, listInfo.GroupContentNot, + listInfo.Tags, listInfo.IsTopExists, listInfo.IsTop, listInfo.Where) + : StlContentCache.GetStlWhereString(siteInfo.Id, listInfo.GroupContent, + listInfo.GroupContentNot, listInfo.Tags, listInfo.IsImageExists, listInfo.IsImage, listInfo.IsVideoExists, listInfo.IsVideo, listInfo.IsFileExists, listInfo.IsFile, + listInfo.IsTopExists, listInfo.IsTop, listInfo.IsRecommendExists, listInfo.IsRecommend, listInfo.IsHotExists, listInfo.IsHot, listInfo.IsColorExists, listInfo.IsColor, + listInfo.Where); + + return StlContentCache.GetStlSqlStringChecked(tableName, siteInfo.Id, channelId, listInfo.StartNum, listInfo.TotalNum, listInfo.OrderByString, sqlWhereString, listInfo.Scope, listInfo.GroupChannel, listInfo.GroupChannelNot); + } + + public static string GetPageContentsSqlStringBySearch(string tableName, string groupContent, string groupContentNot, bool isImageExists, bool isImage, bool isVideoExists, bool isVideo, bool isFileExists, bool isFile, int startNum, int totalNum, string orderByString, bool isTopExists, bool isTop, bool isRecommendExists, bool isRecommend, bool isHotExists, bool isHot, bool isColorExists, bool isColor, string where) + { + var sqlWhereString = StlContentCache.GetStlWhereStringBySearch(groupContent, groupContentNot, isImageExists, isImage, isVideoExists, isVideo, isFileExists, isFile, isTopExists, isTop, isRecommendExists, isRecommend, isHotExists, isHot, isColorExists, isColor, where); + var sqlString = StlContentCache.GetStlSqlStringCheckedBySearch(tableName, startNum, totalNum, orderByString, sqlWhereString); + + return sqlString; + } + + public static DataSet GetContentsDataSource(SiteInfo siteInfo, int channelId, int contentId, string groupContent, string groupContentNot, string tags, bool isImageExists, bool isImage, bool isVideoExists, bool isVideo, bool isFileExists, bool isFile, bool isRelatedContents, int startNum, int totalNum, string orderByString, bool isTopExists, bool isTop, bool isRecommendExists, bool isRecommend, bool isHotExists, bool isHot, bool isColorExists, bool isColor, string where, EScopeType scopeType, string groupChannel, string groupChannelNot, NameValueCollection others) + { + if (!ChannelManager.IsExists(siteInfo.Id, channelId)) return null; + + var channelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + + if (isRelatedContents && contentId > 0) + { + var isTags = false; + var tagCollection = StlContentCache.GetValue(channelInfo, contentId, ContentAttribute.Tags); + if (!string.IsNullOrEmpty(tagCollection)) + { + var contentIdList = StlTagCache.GetContentIdListByTagCollection(TranslateUtils.StringCollectionToStringList(tagCollection), siteInfo.Id); + if (contentIdList.Count > 0) + { + contentIdList.Remove(contentId); + isTags = true; + if (string.IsNullOrEmpty(where)) + { + where = + $"ID IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList.ToList())})"; + } + else + { + where += + $" AND (ID IN ({TranslateUtils.ToSqlInStringWithoutQuote(contentIdList.ToList())}))"; + } + } + } + + if (!isTags) + { + if (string.IsNullOrEmpty(where)) + { + where = $"ID <> {contentId}"; + } + else + { + where += $" AND (ID <> {contentId})"; + } + } + } + + var sqlWhereString = PluginManager.IsExists(channelInfo.ContentModelPluginId) + ? StlContentCache.GetStlWhereString(siteInfo.Id, groupContent, groupContentNot, + tags, isTopExists, isTop, where) + : StlContentCache.GetStlWhereString(siteInfo.Id, groupContent, + groupContentNot, tags, isImageExists, isImage, isVideoExists, isVideo, isFileExists, isFile, + isTopExists, isTop, isRecommendExists, isRecommend, isHotExists, isHot, isColorExists, isColor, + where); + + var channelIdList = ChannelManager.GetChannelIdList(channelInfo, scopeType, groupChannel, groupChannelNot, string.Empty); + return StlContentCache.GetStlDataSourceChecked(channelIdList, tableName, startNum, totalNum, orderByString, sqlWhereString, others); + } + + public static List GetMinContentInfoList(SiteInfo siteInfo, int channelId, int contentId, string groupContent, string groupContentNot, string tags, bool isImageExists, bool isImage, bool isVideoExists, bool isVideo, bool isFileExists, bool isFile, bool isRelatedContents, int startNum, int totalNum, string orderByString, bool isTopExists, bool isTop, bool isRecommendExists, bool isRecommend, bool isHotExists, bool isHot, bool isColorExists, bool isColor, string where, EScopeType scopeType, string groupChannel, string groupChannelNot, NameValueCollection others) + { + var dataSource = GetContentsDataSource(siteInfo, channelId, contentId, groupContent, groupContentNot, tags, + isImageExists, isImage, isVideoExists, isVideo, isFileExists, isFile, isRelatedContents, startNum, + totalNum, orderByString, isTopExists, isTop, isRecommendExists, isRecommend, isHotExists, isHot, + isColorExists, isColor, where, scopeType, groupChannel, groupChannelNot, others); + + var list = new List(); + + foreach (DataRow dataItem in dataSource.Tables[0].Rows) + { + var minContentInfo = new MinContentInfo + { + Id = (int) dataItem[ContentAttribute.Id], + ChannelId = (int) dataItem[ContentAttribute.ChannelId] + }; + list.Add(minContentInfo); + } + + return list; + } + + public static DataSet GetChannelsDataSource(int siteId, int channelId, string group, string groupNot, bool isImageExists, bool isImage, int startNum, int totalNum, string orderByString, EScopeType scopeType, bool isTotal, string where) + { + DataSet ie; + + if (isTotal)//从所有栏目中选择 + { + var sqlWhereString = StlChannelCache.GetWhereString(siteId, group, groupNot, isImageExists, isImage, where); + ie = StlChannelCache.GetStlDataSourceBySiteId(siteId, startNum, totalNum, sqlWhereString, orderByString); + } + else + { + var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (nodeInfo == null) return null; + + var sqlWhereString = StlChannelCache.GetWhereString(siteId, group, groupNot, isImageExists, isImage, where); + var channelIdList = ChannelManager.GetChannelIdList(nodeInfo, scopeType, string.Empty, string.Empty, string.Empty); + //ie = DataProvider.Channel.GetStlDataSource(channelIdList, startNum, totalNum, sqlWhereString, orderByString); + ie = StlChannelCache.GetStlDataSet(channelIdList, startNum, totalNum, sqlWhereString, orderByString); + } + + return ie; + } + + public static DataSet GetPageChannelsDataSet(int siteId, int channelId, string group, string groupNot, bool isImageExists, bool isImage, int startNum, int totalNum, string orderByString, EScopeType scopeType, bool isTotal, string where) + { + DataSet dataSet; + + if (isTotal)//从所有栏目中选择 + { + var sqlWhereString = StlChannelCache.GetWhereString(siteId, group, groupNot, isImageExists, isImage, where); + dataSet = DataProvider.Channel.GetStlDataSetBySiteId(siteId, startNum, totalNum, sqlWhereString, orderByString); + } + else + { + var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (nodeInfo == null) return null; + + var sqlWhereString = StlChannelCache.GetWhereString(siteId, group, groupNot, isImageExists, isImage, where); + var channelIdList = ChannelManager.GetChannelIdList(nodeInfo, scopeType, string.Empty, string.Empty, string.Empty); + dataSet = DataProvider.Channel.GetStlDataSet(channelIdList, startNum, totalNum, sqlWhereString, orderByString); + } + return dataSet; + } + + public static DataSet GetSqlContentsDataSource(string connectionString, string queryString, int startNum, int totalNum, string orderByString) + { + var sqlString = StlSqlContentsCache.GetSelectSqlStringByQueryString(connectionString, queryString, startNum, totalNum, orderByString); + return StlDatabaseCache.GetDataSet(connectionString, sqlString); + } + + public static IDataReader GetSitesDataSource(string siteName, string siteDir, int startNum, int totalNum, string whereString, EScopeType scopeType, string orderByString) + { + return DataProvider.Site.GetStlDataSource(siteName, siteDir, startNum, totalNum, whereString, scopeType, orderByString); + } + } +} diff --git a/SiteServer.CMS/StlParser/Utility/StlParserManager.cs b/net452/SiteServer.CMS/StlParser/Utility/StlParserManager.cs similarity index 95% rename from SiteServer.CMS/StlParser/Utility/StlParserManager.cs rename to net452/SiteServer.CMS/StlParser/Utility/StlParserManager.cs index 8f1fbb5b7..f9bade4b3 100644 --- a/SiteServer.CMS/StlParser/Utility/StlParserManager.cs +++ b/net452/SiteServer.CMS/StlParser/Utility/StlParserManager.cs @@ -1,8 +1,9 @@ using System.Collections.Generic; using System.Text; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Database.Models; using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Plugin.Impl; using SiteServer.CMS.StlParser.Model; using SiteServer.CMS.StlParser.Parsers; using SiteServer.CMS.StlParser.StlElement; @@ -10,12 +11,8 @@ namespace SiteServer.CMS.StlParser.Utility { - public class StlParserManager + public static class StlParserManager { - private StlParserManager() - { - } - public static void ParseTemplateContent(StringBuilder parsedBuilder, PageInfo pageInfo, ContextInfo contextInfo) { var isInnerElement = contextInfo.IsInnerElement; @@ -32,7 +29,7 @@ public static string ParseTemplatePreview(SiteInfo siteInfo, TemplateType templa var templateInfo = new TemplateInfo { - TemplateType = templateType + Type = templateType }; var pageInfo = new PageInfo(channelId, contentId, siteInfo, templateInfo, new Dictionary()); var contextInfo = new ContextInfo(pageInfo); @@ -64,7 +61,7 @@ public static string ParseInnerContent(string template, PageInfo pageInfo, Conte return builder.ToString(); } - public static string ParseInnerContent(string template, IParseContext context) + public static string ParseInnerContent(string template, ParseContextImpl context) { if (string.IsNullOrEmpty(template)) return string.Empty; @@ -73,9 +70,9 @@ public static string ParseInnerContent(string template, IParseContext context) var templateInfo = new TemplateInfo { Id = context.TemplateId, - TemplateType = context.TemplateType + Type = context.TemplateType }; - var pageInfo = new PageInfo(context.ChannelId, context.ContentId, siteInfo, templateInfo, context.StlItems); + var pageInfo = new PageInfo(context.ChannelId, context.ContentId, siteInfo, templateInfo, context.PluginItems); var contextInfo = new ContextInfo(pageInfo); ParseInnerContent(builder, pageInfo, contextInfo); return builder.ToString(); @@ -148,7 +145,7 @@ public static void ReplacePageElementsInSearchPage(StringBuilder parsedBuilder, else if (StlParserUtility.IsSpecifiedStlElement(labelString, StlPageItem.ElementName)) { var stlElement = labelString; - var pageHtml = StlPageElementParser.ParseStlPageItemInSearchPage(stlElement, pageInfo, ajaxDivId, channelId, currentPageIndex, pageCount, totalNum); + var pageHtml = StlPageElementParser.ParseStlPageItemInSearchPage(stlElement, pageInfo, ajaxDivId, currentPageIndex, pageCount, totalNum); parsedBuilder.Replace(stlElement, pageHtml); } } diff --git a/net452/SiteServer.CMS/StlParser/Utility/StlParserUtility.cs b/net452/SiteServer.CMS/StlParser/Utility/StlParserUtility.cs new file mode 100644 index 000000000..9ec92fbfb --- /dev/null +++ b/net452/SiteServer.CMS/StlParser/Utility/StlParserUtility.cs @@ -0,0 +1,521 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Text.RegularExpressions; +using HtmlAgilityPack; +using SiteServer.CMS.Caches; +using SiteServer.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.StlElement; +using SiteServer.Plugin; + +namespace SiteServer.CMS.StlParser.Utility +{ + public static class StlParserUtility + { + public const string OrderDefault = "Default"; //默认排序 + public const string OrderBack = "Back"; //默认排序的相反方向 + public const string OrderAddDate = "AddDate"; //添加时间 + public const string OrderAddDateBack = "AddDateBack"; //添加时间的相反方向 + public const string OrderLastEditDate = "LastEditDate"; //最后更改时间(只可用于内容列表) + public const string OrderLastEditDateBack = "LastEditDateBack"; //最后更改时间的相反方向(只可用于内容列表) + public const string OrderHits = "Hits"; //点击量 + public const string OrderHitsByDay = "HitsByDay"; //日点击量 + public const string OrderHitsByWeek = "HitsByWeek"; //周点击量 + public const string OrderHitsByMonth = "HitsByMonth"; //月点击量 + public const string OrderRandom = "Random"; //随机 + + //http://weblogs.asp.net/whaggard/archive/2005/02/20/377025.aspx + // public static Regex REGEX_STL_ELEMENT = new Regex(@" + //]*> + // (?> + // ]*> (?) + // | + // ]*> (?<-LEVEL>) + // | + // (?! ]*> | ]*> ). + // )* + // (?(LEVEL)(?!)) + //]*> + //", ((RegexOptions.Singleline | RegexOptions.IgnoreCase) | RegexOptions.IgnorePatternWhitespace) | RegexOptions.Compiled); + public static readonly Regex RegexStlElement = new Regex(@" +]*> + (?> + ]*> (?) + | + ]*> (?<-LEVEL>) + | + (?! ]*> | ]*> ). + )* + (?(LEVEL)(?!)) +]*>|]*/> +", ((RegexOptions.Singleline | RegexOptions.IgnoreCase) | RegexOptions.IgnorePatternWhitespace) | RegexOptions.Compiled); + + public static List GetStlLabelList(string templateContent) + { + var stlElementList = GetStlElementList(templateContent); + var stlEntityList = GetStlEntityList(templateContent); + stlElementList.AddRange(stlEntityList); + return stlElementList; + } + + //需要修改 + public static bool IsStlElementExists(string stlElementName, List list) + { + var exists = false; + foreach (var label in list) + { + if (label.ToLower().StartsWith($"<{stlElementName.ToLower()} ") || label.ToLower().StartsWith( + $"<{stlElementName.ToLower()}>")) + { + exists = true; + break; + } + } + return exists; + } + + public static bool IsStlChannelElementWithTypePageContent(List list) + { + foreach (var label in list) + { + if (!IsStlChannelElement(label, ChannelAttribute.PageContent)) continue; + return true; + } + return false; + } + + public static string GetStlChannelElementWithTypePageContent(List labelList) + { + var stlPageChannelElement = string.Empty; + foreach (var label in labelList) + { + if (!IsStlChannelElement(label, ChannelAttribute.PageContent)) continue; + stlPageChannelElement = label; + break; + } + return stlPageChannelElement; + } + + public static bool IsStlContentElementWithTypePageContent(List list) + { + foreach (var label in list) + { + if (!IsStlContentElement(label, ContentAttribute.PageContent)) continue; + return true; + } + return false; + } + + public static string GetStlContentElementWithTypePageContent(List labelList) + { + var stlPageContentElement = string.Empty; + foreach (var label in labelList) + { + if (!IsStlContentElement(label, ContentAttribute.PageContent)) continue; + stlPageContentElement = label; + break; + } + return stlPageContentElement; + } + + public static string GetStlElement(string stlElementName, List labelList) + { + var stlElement = string.Empty; + foreach (var labelWithDisplayModeEnNameAndChannelId in labelList) + { + if (labelWithDisplayModeEnNameAndChannelId.ToLower().StartsWith($"<{stlElementName.ToLower()} ") || labelWithDisplayModeEnNameAndChannelId.ToLower().StartsWith( + $"<{stlElementName.ToLower()}>")) + { + stlElement = labelWithDisplayModeEnNameAndChannelId; + break; + } + } + return stlElement; + } + + public static string GetNameFromEntity(string stlEntity) + { + var name = stlEntity; + if (stlEntity.IndexOf("_", StringComparison.Ordinal) != -1) + { + name = stlEntity.Substring(0, stlEntity.IndexOf("_", StringComparison.Ordinal)); + name = name + "}"; + } + return name; + } + + public static string GetValueFromEntity(string stlEntity) + { + if (stlEntity.IndexOf("_", StringComparison.Ordinal) == -1) return string.Empty; + + var value = string.Empty; + try + { + var length = stlEntity.LastIndexOf("}", StringComparison.Ordinal) - stlEntity.LastIndexOf("_", StringComparison.Ordinal) - 1; + value = stlEntity.Substring(stlEntity.LastIndexOf("_", StringComparison.Ordinal) + 1, length); + } + catch + { + // ignored + } + return value; + } + + public static bool IsStlEntityInclude(string content) + { + if (content == null) return false; + content = content.ToLower(); + return StringUtils.Contains(content, "}") && (StringUtils.Contains(content, "{stl.") || StringUtils.Contains(content, "{content.") || StringUtils.Contains(content, "{channel.")); + } + + public static bool IsSpecifiedStlElement(string stlElement, string elementName) + { + if (stlElement == null) return false; + return (StringUtils.StartsWithIgnoreCase(stlElement, $"<{elementName} ") || + StringUtils.StartsWithIgnoreCase(stlElement, $"<{elementName}>")) && + (StringUtils.EndsWithIgnoreCase(stlElement, $"") || + StringUtils.EndsWithIgnoreCase(stlElement, "/>")); + } + + public static Regex GetStlEntityRegex(string entityName) + { + return new Regex($@"{{{entityName}.[^{{}}]*}}", RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.Compiled); + } + + /// + /// 得到内容中的STL元素列表 + /// + public static List GetStlElementList(string templateContent) + { + var stlElementList = new List(); + + var mc = RegexStlElement.Matches(templateContent); + for (var i = 0; i < mc.Count; i++) + { + var stlElement = mc[i].Value; + stlElementList.Add(stlElement); + } + + return stlElementList; + } + + /// + /// 得到内容中的STL实体列表 + /// + /// 需要解析的内容 + /// + public static List GetStlEntityList(string content) + { + //首先需要去除]*>.*?<\/stl:\1>", content, string.Empty); + content = RegexStlElement.Replace(content, string.Empty); + + var stlEntityList = new List(); + + //Regex regex = new Regex(@"{[^{}]*}", RegexOptions.Singleline | RegexOptions.IgnoreCase); + //Regex regex = new Regex(@"{stl\.[^{}]*}|{content\.[^{}]*}|{channel\.[^{}]*}|{comment\.[^{}]*}|{request\.[^{}]*}|{sql\.[^{}]*}|{navigation\.[^{}]*}", RegexOptions.Singleline | RegexOptions.IgnoreCase); + var regex = new Regex(EStlEntityTypeUtils.RegexStringAll, RegexOptions.Singleline | RegexOptions.IgnoreCase); + var mc = regex.Matches(content); + for (var i = 0; i < mc.Count; i++) + { + var stlEntity = mc[i].Value; + stlEntityList.Add(stlEntity); + } + + return stlEntityList; + } + + //判断属于某种类型(type)的元素是否存在 + public static bool IsStlContentElement(string labelString, string type) + { + return RegexUtils.IsMatch($@"]+type=""{type}""[^>]*>", labelString); + } + + //判断属于某种类型(type)的元素是否存在 + public static bool IsStlChannelElement(string labelString, string type) + { + return RegexUtils.IsMatch($@"]+type=""{type}""[^>]*>", labelString); + } + + public static string GetInnerHtml(string stlElement) + { + var retval = string.Empty; + + try + { + var htmlDoc = new HtmlDocument(); + htmlDoc.LoadHtml(stlElement); + var docNode = htmlDoc.DocumentNode; + if (docNode?.FirstChild != null) + { + var stlNode = docNode.FirstChild; + + retval = stlNode.InnerHtml; + } + } + catch + { + // ignored + } + + return retval; + } + + public static string GetInnerHtml(string stlElement, NameValueCollection attributes) + { + var retval = string.Empty; + + try + { + var htmlDoc = new HtmlDocument(); + htmlDoc.LoadHtml(stlElement); + var docNode = htmlDoc.DocumentNode; + if (docNode?.FirstChild != null) + { + var stlNode = docNode.FirstChild; + + retval = stlNode.InnerHtml; + + if (attributes != null && stlNode.Attributes != null) + { + foreach (var attribute in stlNode.Attributes) + { + attributes[attribute.Name] = attribute.Value; + } + } + } + } + catch + { + // ignored + } + + return retval; + } + + public static StlElementInfo ParseStlElement(string stlElement) + { + StlElementInfo retval = null; + + try + { + var htmlDoc = new HtmlDocument(); + htmlDoc.LoadHtml(stlElement); + var docNode = htmlDoc.DocumentNode; + if (docNode?.FirstChild != null) + { + var stlNode = docNode.FirstChild; + + var name = stlNode.Name; + var outerHtml = stlNode.OuterHtml; + var innerHtml = stlNode.InnerHtml; + var attributesIgnoreCase = TranslateUtils.NewIgnoreCaseNameValueCollection(); + + if (attributesIgnoreCase != null && stlNode.Attributes != null) + { + foreach (var attribute in stlNode.Attributes) + { + attributesIgnoreCase[attribute.Name] = attribute.Value; + } + } + + if (!string.IsNullOrEmpty(name)) + { + retval = new StlElementInfo(name.ToLower(), attributesIgnoreCase, outerHtml, innerHtml); + } + } + } + catch + { + // ignored + } + + return retval; + } + + public const string ItemIndex = "ItemIndex"; + + public static int ParseItemIndex(int dbItemIndex, string attributeName, ContextInfo contextInfo) + { + var itemIndex = contextInfo.PageItemIndex + dbItemIndex + 1; + if (attributeName.IndexOf('+') == -1 && attributeName.IndexOf('-') == -1) return itemIndex; + + var array = attributeName.Split('+'); + if (array.Length == 2) + { + var addNum = TranslateUtils.ToInt(array[1].Trim(), 1); + return itemIndex + addNum; + } + + array = attributeName.Split('-'); + if (array.Length != 2) return itemIndex; + + var substractNum = TranslateUtils.ToInt(array[1].Trim(), 1); + return itemIndex - substractNum; + } + + public static int GetItemIndex(ContextInfo contextInfo) + { + var dbItemIndex = 0; + if (contextInfo.ContextType == EContextType.Channel) + { + dbItemIndex = contextInfo.ItemContainer.ChannelItem.ItemIndex; + } + else if (contextInfo.ContextType == EContextType.Content) + { + dbItemIndex = contextInfo.ItemContainer.ContentItem.ItemIndex; + } + else if (contextInfo.ContextType == EContextType.SqlContent) + { + dbItemIndex = contextInfo.ItemContainer.SqlItem.ItemIndex; + } + else if (contextInfo.ContextType == EContextType.Site) + { + dbItemIndex = contextInfo.ItemContainer.SiteItem.ItemIndex; + } + else if (contextInfo.ContextType == EContextType.Each) + { + dbItemIndex = contextInfo.ItemContainer.EachItem.ItemIndex; + } + + return contextInfo.PageItemIndex + dbItemIndex + 1; + } + + public static string GetAjaxDivId(int updaterId) + { + return "ajaxElement_" + updaterId + "_" + StringUtils.GetRandomInt(100, 1000); + } + + public static string GetStlCurrentUrl(SiteInfo siteInfo, int channelId, int contentId, ContentInfo contentInfo, TemplateType templateType, int templateId, bool isLocal) + { + var currentUrl = string.Empty; + if (templateType == TemplateType.IndexPageTemplate) + { + currentUrl = siteInfo.WebUrl; + } + else if (templateType == TemplateType.ContentTemplate) + { + if (contentInfo == null) + { + var nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, channelId); + currentUrl = PageUtility.GetContentUrl(siteInfo, nodeInfo, contentId, isLocal); + } + else + { + currentUrl = PageUtility.GetContentUrl(siteInfo, contentInfo, isLocal); + } + } + else if (templateType == TemplateType.ChannelTemplate) + { + currentUrl = PageUtility.GetChannelUrl(siteInfo, ChannelManager.GetChannelInfo(siteInfo.Id, channelId), isLocal); + } + else if (templateType == TemplateType.FileTemplate) + { + currentUrl = PageUtility.GetFileUrl(siteInfo, templateId, isLocal); + } + //currentUrl是当前页面的地址,前后台分离的时候,不允许带上protocol + //return PageUtils.AddProtocolToUrl(currentUrl); + return currentUrl; + } + + public static void GetYesNo(string innerHtml, out string yes, out string no) + { + yes = string.Empty; + no = string.Empty; + if (string.IsNullOrEmpty(innerHtml)) return; + + var stlElementList = GetStlElementList(innerHtml); + if (stlElementList.Count > 0) + { + foreach (var theStlElement in stlElementList) + { + if (IsSpecifiedStlElement(theStlElement, StlYes.ElementName) || IsSpecifiedStlElement(theStlElement, StlYes.ElementName2)) + { + yes = GetInnerHtml(theStlElement); + } + else if (IsSpecifiedStlElement(theStlElement, StlNo.ElementName) || IsSpecifiedStlElement(theStlElement, StlNo.ElementName2)) + { + no = GetInnerHtml(theStlElement); + } + } + } + + if (string.IsNullOrEmpty(yes) && string.IsNullOrEmpty(no)) + { + yes = innerHtml; + } + + yes = StringUtils.Trim(yes); + no = StringUtils.Trim(no); + } + + public static void GetLoadingYesNo(string innerHtml, out string loading, out string yes, out string no) + { + loading = string.Empty; + yes = string.Empty; + no = string.Empty; + if (string.IsNullOrEmpty(innerHtml)) return; + + var stlElementList = GetStlElementList(innerHtml); + if (stlElementList.Count > 0) + { + foreach (var theStlElement in stlElementList) + { + if (IsSpecifiedStlElement(theStlElement, StlLoading.ElementName)) + { + loading = GetInnerHtml(theStlElement); + } + else if (IsSpecifiedStlElement(theStlElement, StlYes.ElementName) || IsSpecifiedStlElement(theStlElement, StlYes.ElementName2)) + { + yes = GetInnerHtml(theStlElement); + } + else if (IsSpecifiedStlElement(theStlElement, StlNo.ElementName) || IsSpecifiedStlElement(theStlElement, StlNo.ElementName2)) + { + no = GetInnerHtml(theStlElement); + } + } + } + + if (string.IsNullOrEmpty(loading) && string.IsNullOrEmpty(yes) && string.IsNullOrEmpty(no)) + { + yes = innerHtml; + } + + loading = StringUtils.Trim(loading); + yes = StringUtils.Trim(yes); + no = StringUtils.Trim(no); + } + + public static Dictionary GetStlElements(string innerHtml, List stlElementNames) + { + var dic = new Dictionary(); + foreach (var stlElementName in stlElementNames) + { + dic[stlElementName] = string.Empty; + } + if (string.IsNullOrEmpty(innerHtml)) return dic; + + var stlElementList = GetStlElementList(innerHtml); + if (stlElementList.Count > 0) + { + foreach (var theStlElement in stlElementList) + { + foreach (var stlElementName in stlElementNames) + { + if (IsSpecifiedStlElement(theStlElement, stlElementName)) + { + var template = GetInnerHtml(theStlElement); + dic[stlElementName] = template; + } + } + } + } + + return dic; + } + } +} diff --git a/SiteServer.CMS/StlParser/Utility/StlScriptUtility.cs b/net452/SiteServer.CMS/StlParser/Utility/StlScriptUtility.cs similarity index 100% rename from SiteServer.CMS/StlParser/Utility/StlScriptUtility.cs rename to net452/SiteServer.CMS/StlParser/Utility/StlScriptUtility.cs diff --git a/SiteServer.CMS/StlParser/Utility/StlTemplateManager.cs b/net452/SiteServer.CMS/StlParser/Utility/StlTemplateManager.cs similarity index 100% rename from SiteServer.CMS/StlParser/Utility/StlTemplateManager.cs rename to net452/SiteServer.CMS/StlParser/Utility/StlTemplateManager.cs diff --git a/SiteServer.CMS/StlParser/Utility/TemplateUtility.cs b/net452/SiteServer.CMS/StlParser/Utility/TemplateUtility.cs similarity index 87% rename from SiteServer.CMS/StlParser/Utility/TemplateUtility.cs rename to net452/SiteServer.CMS/StlParser/Utility/TemplateUtility.cs index b9efbf2e9..2b2920926 100644 --- a/SiteServer.CMS/StlParser/Utility/TemplateUtility.cs +++ b/net452/SiteServer.CMS/StlParser/Utility/TemplateUtility.cs @@ -1,21 +1,21 @@ -using System.Text; +using System.Collections.Specialized; +using System.Text; using System.Web.UI.WebControls; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; using SiteServer.Utils; -using SiteServer.CMS.Core; -using SiteServer.CMS.Model; -using SiteServer.CMS.Model.Enumerations; using SiteServer.CMS.StlParser.Model; using SiteServer.CMS.StlParser.StlElement; namespace SiteServer.CMS.StlParser.Utility { - public class TemplateUtility + public static class TemplateUtility { - private TemplateUtility() - { - } - - public static string GetContentsItemTemplateString(string templateString, LowerNameValueCollection selectedItems, LowerNameValueCollection selectedValues, string containerClientId, PageInfo pageInfo, EContextType contextType, ContextInfo contextInfoRef) + public static string GetContentsItemTemplateString(string templateString, NameValueCollection selectedItems, NameValueCollection selectedValues, string containerClientId, PageInfo pageInfo, EContextType contextType, ContextInfo contextInfoRef) { var itemContainer = DbItemContainer.GetItemContainer(pageInfo); //var contentInfo = new BackgroundContentInfo(itemContainer.ContentItem.DataItem); @@ -26,7 +26,7 @@ public static string GetContentsItemTemplateString(string templateString, LowerN contentItemInfo = pageInfo.ContentItems.Peek(); } if (contentItemInfo == null) return string.Empty; - var contentInfo = Cache.Content.GetContentInfo(pageInfo.SiteId, contentItemInfo.ChannelId, + var contentInfo = ContentManager.GetContentInfo(pageInfo.SiteInfo, contentItemInfo.ChannelId, contentItemInfo.ContentId); var contextInfo = contextInfoRef.Clone(); @@ -51,7 +51,7 @@ public static string GetContentsItemTemplateString(string templateString, LowerN if (selectedItems != null && selectedItems.Count > 0) { - foreach (var itemTypes in selectedItems.Keys) + foreach (var itemTypes in selectedItems.AllKeys) { var itemTypeArrayList = TranslateUtils.StringCollectionToStringList(itemTypes); var isTrue = true; @@ -88,7 +88,7 @@ public static string GetContentsItemTemplateString(string templateString, LowerN return innerBuilder.ToString(); } - private static bool IsContentTemplateString(string itemType, string itemTypes, ref string templateString, LowerNameValueCollection selectedItems, LowerNameValueCollection selectedValues, PageInfo pageInfo, ContextInfo contextInfo) + private static bool IsContentTemplateString(string itemType, string itemTypes, ref string templateString, NameValueCollection selectedItems, NameValueCollection selectedValues, PageInfo pageInfo, ContextInfo contextInfo) { if (StringUtils.EqualsIgnoreCase(itemType, StlItemTemplate.SelectedCurrent))//当前内容 { @@ -100,7 +100,7 @@ private static bool IsContentTemplateString(string itemType, string itemTypes, r } else if (StringUtils.EqualsIgnoreCase(itemType, StlItemTemplate.SelectedIsTop))//置顶内容 { - if (contextInfo.ContentInfo.IsTop) + if (contextInfo.ContentInfo.Top) { templateString = selectedItems.Get(itemTypes); return true; @@ -108,7 +108,7 @@ private static bool IsContentTemplateString(string itemType, string itemTypes, r } else if (StringUtils.EqualsIgnoreCase(itemType, StlItemTemplate.SelectedImage))//带图片的内容 { - if (!string.IsNullOrEmpty(contextInfo.ContentInfo.GetString(BackgroundContentAttribute.ImageUrl))) + if (!string.IsNullOrEmpty(contextInfo.ContentInfo.Get(ContentAttribute.ImageUrl))) { templateString = selectedItems.Get(itemTypes); return true; @@ -116,7 +116,7 @@ private static bool IsContentTemplateString(string itemType, string itemTypes, r } else if (StringUtils.EqualsIgnoreCase(itemType, StlItemTemplate.SelectedVideo))//带视频的内容 { - if (!string.IsNullOrEmpty(contextInfo.ContentInfo.GetString(BackgroundContentAttribute.VideoUrl))) + if (!string.IsNullOrEmpty(contextInfo.ContentInfo.Get(ContentAttribute.VideoUrl))) { templateString = selectedItems.Get(itemTypes); return true; @@ -124,7 +124,7 @@ private static bool IsContentTemplateString(string itemType, string itemTypes, r } else if (StringUtils.EqualsIgnoreCase(itemType, StlItemTemplate.SelectedFile))//带附件的内容 { - if (!string.IsNullOrEmpty(contextInfo.ContentInfo.GetString(BackgroundContentAttribute.FileUrl))) + if (!string.IsNullOrEmpty(contextInfo.ContentInfo.Get(ContentAttribute.FileUrl))) { templateString = selectedItems.Get(itemTypes); return true; @@ -132,7 +132,7 @@ private static bool IsContentTemplateString(string itemType, string itemTypes, r } else if (StringUtils.EqualsIgnoreCase(itemType, StlItemTemplate.SelectedIsRecommend))//推荐的内容 { - if (TranslateUtils.ToBool(contextInfo.ContentInfo.GetString(ContentAttribute.IsRecommend))) + if (TranslateUtils.ToBool(contextInfo.ContentInfo.Get(ContentAttribute.IsRecommend))) { templateString = selectedItems.Get(itemTypes); return true; @@ -140,7 +140,7 @@ private static bool IsContentTemplateString(string itemType, string itemTypes, r } else if (StringUtils.EqualsIgnoreCase(itemType, StlItemTemplate.SelectedIsHot))//热点内容 { - if (TranslateUtils.ToBool(contextInfo.ContentInfo.GetString(ContentAttribute.IsHot))) + if (TranslateUtils.ToBool(contextInfo.ContentInfo.Get(ContentAttribute.IsHot))) { templateString = selectedItems.Get(itemTypes); return true; @@ -148,7 +148,7 @@ private static bool IsContentTemplateString(string itemType, string itemTypes, r } else if (StringUtils.EqualsIgnoreCase(itemType, StlItemTemplate.SelectedIsColor))//醒目内容 { - if (TranslateUtils.ToBool(contextInfo.ContentInfo.GetString(ContentAttribute.IsColor))) + if (TranslateUtils.ToBool(contextInfo.ContentInfo.Get(ContentAttribute.IsColor))) { templateString = selectedItems.Get(itemTypes); return true; @@ -177,7 +177,7 @@ private static bool IsContentTemplateString(string itemType, string itemTypes, r return false; } - public static string GetChannelsItemTemplateString(string templateString, LowerNameValueCollection selectedItems, LowerNameValueCollection selectedValues, string containerClientId, PageInfo pageInfo, EContextType contextType, ContextInfo contextInfoRef) + public static string GetChannelsItemTemplateString(string templateString, NameValueCollection selectedItems, NameValueCollection selectedValues, string containerClientId, PageInfo pageInfo, EContextType contextType, ContextInfo contextInfoRef) { var itemContainer = DbItemContainer.GetItemContainer(pageInfo); @@ -192,7 +192,7 @@ public static string GetChannelsItemTemplateString(string templateString, LowerN var nodeInfo = ChannelManager.GetChannelInfo(pageInfo.SiteId, channelId); if (selectedItems != null && selectedItems.Count > 0) { - foreach (var itemType in selectedItems.Keys) + foreach (var itemType in selectedItems.AllKeys) { if (StringUtils.EqualsIgnoreCase(itemType, StlItemTemplate.SelectedCurrent))//当前栏目 { @@ -252,7 +252,7 @@ public static string GetChannelsItemTemplateString(string templateString, LowerN return innerBuilder.ToString(); } - public static string GetSqlContentsTemplateString(string templateString, LowerNameValueCollection selectedItems, LowerNameValueCollection selectedValues, string containerClientId, PageInfo pageInfo, EContextType contextType, ContextInfo contextInfoRef) + public static string GetSqlContentsTemplateString(string templateString, NameValueCollection selectedItems, NameValueCollection selectedValues, string containerClientId, PageInfo pageInfo, EContextType contextType, ContextInfo contextInfoRef) { var itemContainer = DbItemContainer.GetItemContainer(pageInfo); @@ -263,7 +263,7 @@ public static string GetSqlContentsTemplateString(string templateString, LowerNa if (selectedItems != null && selectedItems.Count > 0) { - foreach (var itemType in selectedItems.Keys) + foreach (var itemType in selectedItems.AllKeys) { if (IsNumberInRange(itemContainer.SqlItem.ItemIndex + 1, itemType)) { @@ -308,7 +308,7 @@ public static string GetSitesTemplateString(string templateString, string contai return innerBuilder.ToString(); } - public static string GetEachsTemplateString(string templateString, LowerNameValueCollection selectedItems, LowerNameValueCollection selectedValues, string containerClientId, PageInfo pageInfo, EContextType contextType, ContextInfo contextInfoRef) + public static string GetEachsTemplateString(string templateString, NameValueCollection selectedItems, NameValueCollection selectedValues, string containerClientId, PageInfo pageInfo, EContextType contextType, ContextInfo contextInfoRef) { var itemContainer = DbItemContainer.GetItemContainer(pageInfo); @@ -319,7 +319,7 @@ public static string GetEachsTemplateString(string templateString, LowerNameValu if (selectedItems != null && selectedItems.Count > 0) { - foreach (var itemType in selectedItems.Keys) + foreach (var itemType in selectedItems.AllKeys) { if (IsNumberInRange(itemContainer.SqlItem.ItemIndex + 1, itemType)) { @@ -345,19 +345,19 @@ public static void PutListInfoToMyDataList(ParsedDataList myDataList, ListInfo l myDataList.Width = listInfo.Width; if (!string.IsNullOrEmpty(listInfo.Align)) { - myDataList.HorizontalAlign = Converter.ToHorizontalAlign(listInfo.Align); + myDataList.HorizontalAlign = FxUtils.ToHorizontalAlign(listInfo.Align); } myDataList.ItemStyle.Height = listInfo.ItemHeight; myDataList.ItemStyle.Width = listInfo.ItemWidth; myDataList.ItemStyle.HorizontalAlign = HorizontalAlign.Left; if (!string.IsNullOrEmpty(listInfo.ItemAlign)) { - myDataList.ItemStyle.HorizontalAlign = Converter.ToHorizontalAlign(listInfo.ItemAlign); + myDataList.ItemStyle.HorizontalAlign = FxUtils.ToHorizontalAlign(listInfo.ItemAlign); } myDataList.ItemStyle.VerticalAlign = VerticalAlign.Top; if (!string.IsNullOrEmpty(listInfo.ItemVerticalAlign)) { - myDataList.ItemStyle.VerticalAlign = Converter.ToVerticalAlign(listInfo.ItemVerticalAlign); + myDataList.ItemStyle.VerticalAlign = FxUtils.ToVerticalAlign(listInfo.ItemVerticalAlign); } if (!string.IsNullOrEmpty(listInfo.ItemClass)) { @@ -373,9 +373,9 @@ public static void PutListInfoToMyDataList(ParsedDataList myDataList, ListInfo l myDataList.RepeatLayout = RepeatLayout.Flow; } - foreach (var attributeName in listInfo.Others.Keys) + foreach (var attributeName in listInfo.Others.AllKeys) { - myDataList.AddAttribute(attributeName, listInfo.Others.Get(attributeName)); + myDataList.AddAttribute(attributeName, listInfo.Others[attributeName]); } } diff --git a/SiteServer.CMS/UEditor/Config.cs b/net452/SiteServer.CMS/UEditor/Config.cs similarity index 91% rename from SiteServer.CMS/UEditor/Config.cs rename to net452/SiteServer.CMS/UEditor/Config.cs index e6bfeec3a..2d03e7b5e 100644 --- a/SiteServer.CMS/UEditor/Config.cs +++ b/net452/SiteServer.CMS/UEditor/Config.cs @@ -1,8 +1,9 @@ using Newtonsoft.Json.Linq; using System; using System.Linq; -using SiteServer.CMS.Core; -using SiteServer.CMS.Plugin; +using System.Web; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; namespace SiteServer.CMS.UEditor { @@ -14,16 +15,13 @@ public static class Config private static bool noCache = true; private static JObject BuildItems() { - var request = new AuthRequest(); - if (!request.IsAdminLoggin) return new JObject(); - - var json = @"/* 前后端通信相关的配置,注释只允许使用多行方式 */ + var json = @"/* 前后端通信相关的配置,注释只允许使用多行方式 */ { /* 上传图片配置项 */ ""imageActionName"": ""uploadimage"", /* 执行上传图片的action名称 */ ""imageFieldName"": ""upfile"", /* 提交的图片表单名称 */ ""imageMaxSize"": 2048000, /* 上传大小限制,单位B */ - ""imageAllowFiles"": ["".png"", "".jpg"", "".jpeg"", "".gif"", "".bmp""], /* 上传图片格式显示 */ + ""imageAllowFiles"": ["".png"", "".webp"", "".jpg"", "".jpeg"", "".gif"", "".bmp""], /* 上传图片格式显示 */ ""imageCompressEnable"": true, /* 是否压缩图片,默认是true */ ""imageCompressBorder"": 1600, /* 图片压缩最长边限制 */ ""imageInsertAlign"": ""none"", /* 插入的图片浮动方式 */ @@ -63,7 +61,7 @@ private static JObject BuildItems() ""catcherPathFormat"": ""upload/image/{yyyy}{mm}{dd}/{time}{rand:6}"", /* 上传保存路径,可以自定义保存路径和文件名格式 */ ""catcherUrlPrefix"": """", /* 图片访问路径前缀 */ ""catcherMaxSize"": 2048000, /* 上传大小限制,单位B */ - ""catcherAllowFiles"": ["".png"", "".jpg"", "".jpeg"", "".gif"", "".bmp""], /* 抓取图片格式显示 */ + ""catcherAllowFiles"": ["".png"", "".webp"", "".jpg"", "".jpeg"", "".gif"", "".bmp""], /* 抓取图片格式显示 */ /* 上传视频配置 */ ""videoActionName"": ""uploadvideo"", /* 执行上传视频的action名称 */ @@ -82,7 +80,7 @@ private static JObject BuildItems() ""fileUrlPrefix"": """", /* 文件访问路径前缀 */ ""fileMaxSize"": 51200000, /* 上传大小限制,单位B,默认50MB */ ""fileAllowFiles"": [ - "".png"", "".jpg"", "".jpeg"", "".gif"", "".bmp"", + "".png"", "".webp"", "".jpg"", "".jpeg"", "".gif"", "".bmp"", "".flv"", "".swf"", "".mkv"", "".avi"", "".rm"", "".rmvb"", "".mpeg"", "".mpg"", "".ogg"", "".ogv"", "".mov"", "".wmv"", "".mp4"", "".webm"", "".mp3"", "".wav"", "".mid"", "".rar"", "".zip"", "".tar"", "".gz"", "".7z"", "".bz2"", "".cab"", "".iso"", @@ -95,7 +93,7 @@ private static JObject BuildItems() ""imageManagerListSize"": 20, /* 每次列出文件数量 */ ""imageManagerUrlPrefix"": """", /* 图片访问路径前缀 */ ""imageManagerInsertAlign"": ""none"", /* 插入的图片浮动方式 */ - ""imageManagerAllowFiles"": ["".png"", "".jpg"", "".jpeg"", "".gif"", "".bmp""], /* 列出的文件类型 */ + ""imageManagerAllowFiles"": ["".png"", "".webp"", "".jpg"", "".jpeg"", "".gif"", "".bmp""], /* 列出的文件类型 */ /* 列出指定目录下的文件 */ ""fileManagerActionName"": ""listfile"", /* 执行文件管理的action名称 */ @@ -103,7 +101,7 @@ private static JObject BuildItems() ""fileManagerUrlPrefix"": """", /* 文件访问路径前缀 */ ""fileManagerListSize"": 20, /* 每次列出文件数量 */ ""fileManagerAllowFiles"": [ - "".png"", "".jpg"", "".jpeg"", "".gif"", "".bmp"", + "".png"", "".webp"", "".jpg"", "".jpeg"", "".gif"", "".bmp"", "".flv"", "".swf"", "".mkv"", "".avi"", "".rm"", "".rmvb"", "".mpeg"", "".mpg"", "".ogg"", "".ogv"", "".mov"", "".wmv"", "".mp4"", "".webm"", "".mp3"", "".wav"", "".mid"", "".rar"", "".zip"", "".tar"", "".gz"", "".7z"", "".bz2"", "".cab"", "".iso"", diff --git a/SiteServer.CMS/UEditor/ConfigHandler.cs b/net452/SiteServer.CMS/UEditor/ConfigHandler.cs similarity index 100% rename from SiteServer.CMS/UEditor/ConfigHandler.cs rename to net452/SiteServer.CMS/UEditor/ConfigHandler.cs diff --git a/SiteServer.CMS/UEditor/CrawlerHandler.cs b/net452/SiteServer.CMS/UEditor/CrawlerHandler.cs similarity index 99% rename from SiteServer.CMS/UEditor/CrawlerHandler.cs rename to net452/SiteServer.CMS/UEditor/CrawlerHandler.cs index 8202d7e78..12a3b4ed1 100644 --- a/SiteServer.CMS/UEditor/CrawlerHandler.cs +++ b/net452/SiteServer.CMS/UEditor/CrawlerHandler.cs @@ -3,10 +3,10 @@ using System.Linq; using System.Net; using System.Web; - +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Database.Models; using SiteServer.Utils.Enumerations; namespace SiteServer.CMS.UEditor diff --git a/SiteServer.CMS/UEditor/Handler.cs b/net452/SiteServer.CMS/UEditor/Handler.cs similarity index 100% rename from SiteServer.CMS/UEditor/Handler.cs rename to net452/SiteServer.CMS/UEditor/Handler.cs diff --git a/SiteServer.CMS/UEditor/ListFileHandler.cs b/net452/SiteServer.CMS/UEditor/ListFileHandler.cs similarity index 95% rename from SiteServer.CMS/UEditor/ListFileHandler.cs rename to net452/SiteServer.CMS/UEditor/ListFileHandler.cs index 5bda17a0f..da6c45667 100644 --- a/SiteServer.CMS/UEditor/ListFileHandler.cs +++ b/net452/SiteServer.CMS/UEditor/ListFileHandler.cs @@ -3,9 +3,10 @@ using System.IO; using System.Linq; using System.Web; - +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; using SiteServer.Utils.Enumerations; namespace SiteServer.CMS.UEditor @@ -65,11 +66,11 @@ public override void Process() var applicationPath = WebConfigUtils.PhysicalApplicationPath.ToLower().Trim(' ', '/', '\\'); // 系统物理路径 if (UploadType == EUploadType.Image) { - PathToList = siteInfo.Additional.ImageUploadDirectoryName; + PathToList = siteInfo.ImageUploadDirectoryName; } else if(UploadType == EUploadType.File) { - PathToList = siteInfo.Additional.FileUploadDirectoryName; + PathToList = siteInfo.FileUploadDirectoryName; } //var localPath = Server.MapPath(PathToList); diff --git a/SiteServer.CMS/UEditor/NotSupportedHandler.cs b/net452/SiteServer.CMS/UEditor/NotSupportedHandler.cs similarity index 100% rename from SiteServer.CMS/UEditor/NotSupportedHandler.cs rename to net452/SiteServer.CMS/UEditor/NotSupportedHandler.cs diff --git a/SiteServer.CMS/UEditor/PathFormater.cs b/net452/SiteServer.CMS/UEditor/PathFormater.cs similarity index 100% rename from SiteServer.CMS/UEditor/PathFormater.cs rename to net452/SiteServer.CMS/UEditor/PathFormater.cs diff --git a/SiteServer.CMS/UEditor/UploadHandler.cs b/net452/SiteServer.CMS/UEditor/UploadHandler.cs similarity index 99% rename from SiteServer.CMS/UEditor/UploadHandler.cs rename to net452/SiteServer.CMS/UEditor/UploadHandler.cs index 0aa81c95c..02f1bfe5a 100644 --- a/SiteServer.CMS/UEditor/UploadHandler.cs +++ b/net452/SiteServer.CMS/UEditor/UploadHandler.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Web; +using SiteServer.CMS.Caches; using SiteServer.Utils.Enumerations; namespace SiteServer.CMS.UEditor diff --git a/net452/SiteServer.CMS/app.config b/net452/SiteServer.CMS/app.config new file mode 100644 index 000000000..44b709f20 --- /dev/null +++ b/net452/SiteServer.CMS/app.config @@ -0,0 +1,41 @@ + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/net452/SiteServer.CMS/packages.config b/net452/SiteServer.CMS/packages.config new file mode 100644 index 000000000..7d612eee2 --- /dev/null +++ b/net452/SiteServer.CMS/packages.config @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Cli/Core/CliUtils.cs b/net452/SiteServer.Cli/Core/CliUtils.cs new file mode 100644 index 000000000..dc9dc24c0 --- /dev/null +++ b/net452/SiteServer.Cli/Core/CliUtils.cs @@ -0,0 +1,144 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using NDesk.Options; +using SiteServer.CMS.Fx; +using SiteServer.Utils; + +namespace SiteServer.Cli.Core +{ + public static class CliUtils + { + public const int PageSize = 500; + + public static readonly string PhysicalApplicationPath = Environment.CurrentDirectory; + + private const int ConsoleTableWidth = 77; + + private static string AlignCentre(string text, int width) + { + text = text.Length > width ? text.Substring(0, width - 3) + "..." : text; + + return string.IsNullOrEmpty(text) + ? new string(' ', width) + : text.PadRight(width - (width - text.Length) / 2).PadLeft(width); + } + + // https://stackoverflow.com/questions/491595/best-way-to-parse-command-line-arguments-in-c + public static bool ParseArgs(OptionSet options, string[] args) + { + try + { + options.Parse(args); + return true; + } + catch + { + return false; + } + } + + public static async Task PrintRowLineAsync() + { + await Console.Out.WriteLineAsync(new string('-', ConsoleTableWidth)); + } + + public static async Task PrintRowAsync(params string[] columns) + { + int width = (ConsoleTableWidth - columns.Length) / columns.Length; + string row = "|"; + + foreach (string column in columns) + { + row += AlignCentre(column, width) + "|"; + } + + await Console.Out.WriteLineAsync(row); + } + + public static async Task PrintErrorAsync(string errorMessage) + { + await Console.Out.WriteLineAsync(); + await Console.Out.WriteLineAsync(errorMessage); + } + + public static async Task PrintRowLine() + { + await Console.Out.WriteLineAsync(new string('-', ConsoleTableWidth)); + } + + public static async Task PrintRow(params string[] columns) + { + int width = (ConsoleTableWidth - columns.Length) / columns.Length; + string row = "|"; + + foreach (string column in columns) + { + row += AlignCentre(column, width) + "|"; + } + + await Console.Out.WriteLineAsync(row); + } + + public static async Task PrintError(string errorMessage) + { + await Console.Out.WriteLineAsync(); + await Console.Out.WriteLineAsync(errorMessage); + } + + public static string CreateErrorLogFile(string commandName) + { + var filePath = PathUtils.Combine(PhysicalApplicationPath, $"{commandName}.error.log"); + FileUtils.DeleteFileIfExists(filePath); + return filePath; + } + + public static async Task AppendErrorLogsAsync(string filePath, List logs) + { + if (logs == null || logs.Count <= 0) return; + + if (!FileUtils.IsFileExists(filePath)) + { + await FileUtils.WriteTextAsync(filePath, string.Empty); + } + + var builder = new StringBuilder(); + + foreach (var log in logs) + { + builder.AppendLine(); + builder.Append(log); + builder.AppendLine(); + } + + await FileUtils.AppendTextAsync(filePath, builder.ToString()); + } + + public static async Task AppendErrorLogAsync(string filePath, TextLogInfo log) + { + if (log == null) return; + + if (!FileUtils.IsFileExists(filePath)) + { + await FileUtils.WriteTextAsync(filePath, string.Empty); + } + + var builder = new StringBuilder(); + + builder.AppendLine(); + builder.Append(log); + builder.AppendLine(); + + await FileUtils.AppendTextAsync(filePath, builder.ToString()); + } + + public static string GetWebConfigPath(string configFile) + { + return PathUtils.IsFilePath(configFile) + ? configFile + : PathUtils.Combine(PhysicalApplicationPath, + !string.IsNullOrEmpty(configFile) ? configFile : WebConfigUtils.WebConfigFileName); + } + } +} diff --git a/net452/SiteServer.Cli/Core/JobContextImpl.cs b/net452/SiteServer.Cli/Core/JobContextImpl.cs new file mode 100644 index 000000000..022d9972e --- /dev/null +++ b/net452/SiteServer.Cli/Core/JobContextImpl.cs @@ -0,0 +1,37 @@ +using System; +using Quartz; +using SiteServer.Plugin; + +namespace SiteServer.Cli.Core +{ + public class JobContextImpl : IJobContext + { + public JobContextImpl(string command, string[] args, IJobExecutionContext context) + { + Command = command; + Args = args; + if (context != null) + { + FireTime = context.FireTimeUtc.LocalDateTime; + if (context.ScheduledFireTimeUtc != null) + ScheduledFireTime = context.ScheduledFireTimeUtc.Value.LocalDateTime; + if (context.PreviousFireTimeUtc != null) PreviousFireTime = context.PreviousFireTimeUtc.Value.LocalDateTime; + if (context.NextFireTimeUtc != null) NextFireTime = context.NextFireTimeUtc.Value.LocalDateTime; + JobRunTime = context.JobRunTime; + } + else + { + FireTime = DateTime.Now; + JobRunTime = new TimeSpan(0); + } + } + + public string Command { get; } + public string[] Args { get; } + public DateTime FireTime { get; } + public DateTime? ScheduledFireTime { get; } + public DateTime? PreviousFireTime { get; } + public DateTime? NextFireTime { get; } + public TimeSpan JobRunTime { get; } + } +} diff --git a/net452/SiteServer.Cli/Core/ProgressBar.cs b/net452/SiteServer.Cli/Core/ProgressBar.cs new file mode 100644 index 000000000..581e93b9c --- /dev/null +++ b/net452/SiteServer.Cli/Core/ProgressBar.cs @@ -0,0 +1,104 @@ +using System; +using System.Text; +using System.Threading; + +namespace SiteServer.Cli.Core +{ + /// + /// https://gist.github.com/DanielSWolf/0ab6a96899cc5377bf54 + /// + public class ProgressBar : IDisposable, IProgress + { + private const int blockCount = 67; + private readonly TimeSpan animationInterval = TimeSpan.FromSeconds(1.0 / 8); + private const string animation = @"|/-\"; + + private readonly Timer timer; + + private double currentProgress = 0; + private string currentText = string.Empty; + private bool disposed = false; + private int animationIndex = 0; + + public ProgressBar() + { + timer = new Timer(TimerHandler); + + // A progress bar is only for temporary display in a console window. + // If the console output is redirected to a file, draw nothing. + // Otherwise, we'll end up with a lot of garbage in the target file. + if (!Console.IsOutputRedirected) + { + ResetTimer(); + } + } + + public void Report(double value) + { + // Make sure value is in [0..1] range + value = Math.Max(0, Math.Min(1, value)); + Interlocked.Exchange(ref currentProgress, value); + } + + private void TimerHandler(object state) + { + lock (timer) + { + if (disposed) return; + + int progressBlockCount = (int) (currentProgress * blockCount); + int percent = (int) (currentProgress * 100); + string text = string.Format("[{0}{1}] {2,3}% {3}", + new string('#', progressBlockCount), new string('-', blockCount - progressBlockCount), + percent, + animation[animationIndex++ % animation.Length]); + UpdateText(text); + + ResetTimer(); + } + } + + private void UpdateText(string text) + { + // Get length of common portion + int commonPrefixLength = 0; + int commonLength = Math.Min(currentText.Length, text.Length); + while (commonPrefixLength < commonLength && text[commonPrefixLength] == currentText[commonPrefixLength]) + { + commonPrefixLength++; + } + + // Backtrack to the first differing character + StringBuilder outputBuilder = new StringBuilder(); + outputBuilder.Append('\b', currentText.Length - commonPrefixLength); + + // Output new suffix + outputBuilder.Append(text.Substring(commonPrefixLength)); + + // If the new text is shorter than the old one: delete overlapping characters + int overlapCount = currentText.Length - text.Length; + if (overlapCount > 0) + { + outputBuilder.Append(' ', overlapCount); + outputBuilder.Append('\b', overlapCount); + } + + Console.Write(outputBuilder); + currentText = text; + } + + private void ResetTimer() + { + timer.Change(animationInterval, TimeSpan.FromMilliseconds(-1)); + } + + public void Dispose() + { + lock (timer) + { + disposed = true; + UpdateText(string.Empty); + } + } + } +} diff --git a/net452/SiteServer.Cli/Core/SchedJob.cs b/net452/SiteServer.Cli/Core/SchedJob.cs new file mode 100644 index 000000000..9f46b3538 --- /dev/null +++ b/net452/SiteServer.Cli/Core/SchedJob.cs @@ -0,0 +1,25 @@ +using System; +using System.Threading.Tasks; +using Quartz; + +namespace SiteServer.Cli.Core +{ + internal class SchedJob : IJob + { + public async Task Execute(IJobExecutionContext context) + { + await Program.RunExecuteAsync(Program.CommandName, Program.CommandArgs, context); + + if (context.NextFireTimeUtc != null) + { + await Console.Out.WriteLineAsync(); + await CliUtils.PrintRowLineAsync(); + await CliUtils.PrintRowAsync("Fire Time", "Next Fire Time"); + await CliUtils.PrintRowLineAsync(); + await CliUtils.PrintRowAsync($"{context.FireTimeUtc.ToLocalTime():yyyy-MM-dd HH:mm:ss}", $"{context.NextFireTimeUtc.Value.ToLocalTime():yyyy-MM-dd HH:mm:ss}"); + await CliUtils.PrintRowLineAsync(); + await Console.Out.WriteLineAsync(); + } + } + } +} diff --git a/net452/SiteServer.Cli/Core/TableInfo.cs b/net452/SiteServer.Cli/Core/TableInfo.cs new file mode 100644 index 000000000..649f44510 --- /dev/null +++ b/net452/SiteServer.Cli/Core/TableInfo.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using Datory; +using SiteServer.Plugin; +using TableColumn = Datory.TableColumn; + +namespace SiteServer.Cli.Core +{ + public class TableInfo + { + public List Columns { get; set; } + public int TotalCount { get; set; } + public List RowFiles { get; set; } + } +} diff --git a/net452/SiteServer.Cli/Core/TextLogInfo.cs b/net452/SiteServer.Cli/Core/TextLogInfo.cs new file mode 100644 index 000000000..7b98565d4 --- /dev/null +++ b/net452/SiteServer.Cli/Core/TextLogInfo.cs @@ -0,0 +1,23 @@ +using System; +using SiteServer.Utils; + +namespace SiteServer.Cli.Core +{ + public class TextLogInfo + { + public DateTime DateTime { private get; set; } + public string Detail { private get; set; } + public Exception Exception { private get; set; } + + public override string ToString() + { + return TranslateUtils.JsonSerialize(new + { + DateTime, + Detail, + Exception?.Message, + Exception?.StackTrace + }); + } + } +} diff --git a/net452/SiteServer.Cli/Core/TreeInfo.cs b/net452/SiteServer.Cli/Core/TreeInfo.cs new file mode 100644 index 000000000..73291a2fa --- /dev/null +++ b/net452/SiteServer.Cli/Core/TreeInfo.cs @@ -0,0 +1,26 @@ +using SiteServer.Utils; + +namespace SiteServer.Cli.Core +{ + public class TreeInfo + { + public string DirectoryPath { get; } + + public TreeInfo(string directory) + { + DirectoryPath = PathUtils.Combine(CliUtils.PhysicalApplicationPath, directory); + } + + public string TablesFilePath => PathUtils.Combine(DirectoryPath, "_tables.json"); + + public string GetTableMetadataFilePath(string tableName) + { + return PathUtils.Combine(DirectoryPath, tableName, "_metadata.json"); + } + + public string GetTableContentFilePath(string tableName, string fileName) + { + return PathUtils.Combine(DirectoryPath, tableName, fileName); + } + } +} diff --git a/net452/SiteServer.Cli/FodyWeavers.xml b/net452/SiteServer.Cli/FodyWeavers.xml new file mode 100644 index 000000000..a5dcf04fd --- /dev/null +++ b/net452/SiteServer.Cli/FodyWeavers.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/net452/SiteServer.Cli/FodyWeavers.xsd b/net452/SiteServer.Cli/FodyWeavers.xsd new file mode 100644 index 000000000..44a53744f --- /dev/null +++ b/net452/SiteServer.Cli/FodyWeavers.xsd @@ -0,0 +1,111 @@ + + + + + + + + + + + + A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with line breaks + + + + + A list of assembly names to include from the default action of "embed all Copy Local references", delimited with line breaks. + + + + + A list of unmanaged 32 bit assembly names to include, delimited with line breaks. + + + + + A list of unmanaged 64 bit assembly names to include, delimited with line breaks. + + + + + The order of preloaded assemblies, delimited with line breaks. + + + + + + This will copy embedded files to disk before loading them into memory. This is helpful for some scenarios that expected an assembly to be loaded from a physical file. + + + + + Controls if .pdbs for reference assemblies are also embedded. + + + + + Embedded assemblies are compressed by default, and uncompressed when they are loaded. You can turn compression off with this option. + + + + + As part of Costura, embedded assemblies are no longer included as part of the build. This cleanup can be turned off. + + + + + Costura by default will load as part of the module initialization. This flag disables that behavior. Make sure you call CosturaUtility.Initialize() somewhere in your code. + + + + + Costura will by default use assemblies with a name like 'resources.dll' as a satellite resource and prepend the output path. This flag disables that behavior. + + + + + A list of assembly names to exclude from the default action of "embed all Copy Local references", delimited with | + + + + + A list of assembly names to include from the default action of "embed all Copy Local references", delimited with |. + + + + + A list of unmanaged 32 bit assembly names to include, delimited with |. + + + + + A list of unmanaged 64 bit assembly names to include, delimited with |. + + + + + The order of preloaded assemblies, delimited with |. + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Cli/Jobs/BackupJob.cs b/net452/SiteServer.Cli/Jobs/BackupJob.cs new file mode 100644 index 000000000..9430983ef --- /dev/null +++ b/net452/SiteServer.Cli/Jobs/BackupJob.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Datory; +using NDesk.Options; +using SiteServer.Cli.Core; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.Cli.Jobs +{ + public static class BackupJob + { + public const string CommandName = "backup"; + + private static string _directory; + private static string _configFile; + private static List _includes; + private static List _excludes; + private static int _maxRows; + private static bool _isHelp; + + private static readonly OptionSet Options = new OptionSet() { + { "d|directory=", "指定保存备份文件的文件夹名称", + v => _directory = v }, + { "c|config-file=", "指定配置文件Web.config路径或文件名", + v => _configFile = v }, + { "includes=", "指定需要备份的表,多个表用英文逗号隔开,默认备份所有表", + v => _includes = v == null ? null : TranslateUtils.StringCollectionToStringList(v) }, + { "excludes=", "指定需要排除的表,多个表用英文逗号隔开", + v => _excludes = v == null ? null : TranslateUtils.StringCollectionToStringList(v) }, + { "max-rows=", "指定需要备份的表的最大行数", + v => _maxRows = v == null ? 0 : TranslateUtils.ToInt(v) }, + { "h|help", "命令说明", + v => _isHelp = v != null } + }; + + public static void PrintUsage() + { + Console.WriteLine("数据库备份: siteserver backup"); + Options.WriteOptionDescriptions(Console.Out); + Console.WriteLine(); + } + + public static async Task Execute(IJobContext context) + { + if (!CliUtils.ParseArgs(Options, context.Args)) return; + + if (_isHelp) + { + PrintUsage(); + return; + } + + if (string.IsNullOrEmpty(_directory)) + { + _directory = $"backup/{DateTime.Now:yyyy-MM-dd}"; + } + + var treeInfo = new TreeInfo(_directory); + DirectoryUtils.CreateDirectoryIfNotExists(treeInfo.DirectoryPath); + + var webConfigPath = CliUtils.GetWebConfigPath(_configFile); + if (!FileUtils.IsFileExists(webConfigPath)) + { + await CliUtils.PrintErrorAsync($"系统配置文件不存在:{webConfigPath}!"); + return; + } + + WebConfigUtils.Load(CliUtils.PhysicalApplicationPath, webConfigPath); + + if (string.IsNullOrEmpty(WebConfigUtils.ConnectionString)) + { + await CliUtils.PrintErrorAsync($"{webConfigPath} 中数据库连接字符串 connectionString 未设置"); + return; + } + + await Console.Out.WriteLineAsync($"数据库类型: {WebConfigUtils.DatabaseType.Value}"); + await Console.Out.WriteLineAsync($"连接字符串: {WebConfigUtils.ConnectionString}"); + await Console.Out.WriteLineAsync($"备份文件夹: {treeInfo.DirectoryPath}"); + + if (!DataProvider.DatabaseApi.IsConnectionStringWork(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString)) + { + await CliUtils.PrintErrorAsync($"系统无法连接到 {webConfigPath} 中设置的数据库"); + return; + } + + if (_excludes == null) + { + _excludes = new List(); + } + _excludes.Add("bairong_Log"); + _excludes.Add("bairong_ErrorLog"); + _excludes.Add("siteserver_ErrorLog"); + _excludes.Add("siteserver_Log"); + _excludes.Add("siteserver_Tracking"); + + var allTableNames = DatoryUtils.GetTableNames(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString); + var tableNames = new List(); + + foreach (var tableName in allTableNames) + { + if (_includes != null && !StringUtils.ContainsIgnoreCase(_includes, tableName)) continue; + if (StringUtils.ContainsIgnoreCase(_excludes, tableName)) continue; + if (StringUtils.ContainsIgnoreCase(tableNames, tableName)) continue; + tableNames.Add(tableName); + } + + await FileUtils.WriteTextAsync(treeInfo.TablesFilePath, TranslateUtils.JsonSerialize(tableNames)); + + await CliUtils.PrintRowLineAsync(); + await CliUtils.PrintRowAsync("备份表名称", "总条数"); + await CliUtils.PrintRowLineAsync(); + + foreach (var tableName in tableNames) + { + var tableInfo = new TableInfo + { + Columns = DatoryUtils.GetTableColumns(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName), + TotalCount = DataProvider.DatabaseApi.GetCount(tableName), + RowFiles = new List() + }; + + if (_maxRows > 0 && tableInfo.TotalCount > _maxRows) + { + tableInfo.TotalCount = _maxRows; + } + + await CliUtils.PrintRowAsync(tableName, tableInfo.TotalCount.ToString("#,0")); + + var identityColumnName = DatoryUtils.AddIdentityColumnIdIfNotExists(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName, tableInfo.Columns); + + if (tableInfo.TotalCount > 0) + { + var current = 1; + if (tableInfo.TotalCount > CliUtils.PageSize) + { + var pageCount = (int)Math.Ceiling((double)tableInfo.TotalCount / CliUtils.PageSize); + + using (var progress = new ProgressBar()) + { + for (; current <= pageCount; current++) + { + progress.Report((double)(current - 1) / pageCount); + + var fileName = $"{current}.json"; + tableInfo.RowFiles.Add(fileName); + var offset = (current - 1) * CliUtils.PageSize; + var limit = tableInfo.TotalCount - offset < CliUtils.PageSize ? tableInfo.TotalCount - offset : CliUtils.PageSize; + + var rows = DataProvider.DatabaseApi.GetPageObjects(tableName, identityColumnName, offset, limit); + + await FileUtils.WriteTextAsync(treeInfo.GetTableContentFilePath(tableName, fileName), TranslateUtils.JsonSerialize(rows)); + } + } + } + else + { + var fileName = $"{current}.json"; + tableInfo.RowFiles.Add(fileName); + var rows = DataProvider.DatabaseApi.GetObjects(tableName); + + await FileUtils.WriteTextAsync(treeInfo.GetTableContentFilePath(tableName, fileName), TranslateUtils.JsonSerialize(rows)); + } + } + + await FileUtils.WriteTextAsync(treeInfo.GetTableMetadataFilePath(tableName), TranslateUtils.JsonSerialize(tableInfo)); + } + + await CliUtils.PrintRowLineAsync(); + await Console.Out.WriteLineAsync($"恭喜,成功备份数据库至文件夹:{treeInfo.DirectoryPath}!"); + } + } +} diff --git a/net452/SiteServer.Cli/Jobs/InstallJob.cs b/net452/SiteServer.Cli/Jobs/InstallJob.cs new file mode 100644 index 000000000..f9961ecb7 --- /dev/null +++ b/net452/SiteServer.Cli/Jobs/InstallJob.cs @@ -0,0 +1,122 @@ +using System; +using System.Threading.Tasks; +using NDesk.Options; +using SiteServer.Cli.Core; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.Cli.Jobs +{ + public static class InstallJob + { + public const string CommandName = "install"; + + private static string _configFile; + private static string _userName; + private static string _password; + private static bool _isHelp; + + private static readonly OptionSet Options = new OptionSet { + { "c|config-file=", "指定配置文件Web.config路径或文件名", + v => _configFile = v }, + { "u|userName=", "超级管理员用户名", + v => _userName = v }, + { "p|password=", "超级管理员密码", + v => _password = v }, + { "h|help", "命令说明", + v => _isHelp = v != null } + }; + + public static void PrintUsage() + { + Console.WriteLine("安装系统: siteserver install"); + Options.WriteOptionDescriptions(Console.Out); + Console.WriteLine(); + } + + public static async Task Execute(IJobContext context) + { + if (!CliUtils.ParseArgs(Options, context.Args)) return; + + if (_isHelp) + { + PrintUsage(); + return; + } + + var webConfigPath = CliUtils.GetWebConfigPath(_configFile); + if (!FileUtils.IsFileExists(webConfigPath)) + { + await CliUtils.PrintErrorAsync($"系统配置文件不存在:{webConfigPath}!"); + return; + } + + if (string.IsNullOrEmpty(WebConfigUtils.ConnectionString)) + { + await CliUtils.PrintErrorAsync($"{webConfigPath} 中数据库连接字符串 connectionString 未设置"); + return; + } + + if (string.IsNullOrEmpty(_userName)) + { + await CliUtils.PrintErrorAsync("未设置参数管理员用户名:{userName} !"); + return; + } + + if (string.IsNullOrEmpty(_password)) + { + await CliUtils.PrintErrorAsync("未设置参数管理员密码:{password} !"); + return; + } + + if (_password.Length < 6) + { + await CliUtils.PrintErrorAsync("管理员密码必须大于6位 !"); + return; + } + + if (!EUserPasswordRestrictionUtils.IsValid(_password, EUserPasswordRestrictionUtils.GetValue(EUserPasswordRestriction.LetterAndDigit))) + { + await CliUtils.PrintErrorAsync($"管理员密码不符合规则,请包含{EUserPasswordRestrictionUtils.GetText(EUserPasswordRestriction.LetterAndDigit)}"); + return; + } + + if (string.IsNullOrEmpty(WebConfigUtils.ConnectionString)) + { + await CliUtils.PrintErrorAsync("web.config 中数据库连接字符串 connectionString 未设置"); + return; + } + + WebConfigUtils.Load(CliUtils.PhysicalApplicationPath, webConfigPath); + + await Console.Out.WriteLineAsync($"数据库类型: {WebConfigUtils.DatabaseType.Value}"); + await Console.Out.WriteLineAsync($"连接字符串: {WebConfigUtils.ConnectionString}"); + await Console.Out.WriteLineAsync($"系统文件夹: {CliUtils.PhysicalApplicationPath}"); + + if (!DataProvider.DatabaseApi.IsConnectionStringWork(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString)) + { + await CliUtils.PrintErrorAsync("系统无法连接到 web.config 中设置的数据库"); + return; + } + + if (!SystemManager.IsNeedInstall()) + { + await CliUtils.PrintErrorAsync("系统已安装在 web.config 指定的数据库中,命令执行失败"); + return; + } + + WebConfigUtils.UpdateWebConfig(WebConfigUtils.IsProtectData, WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, WebConfigUtils.ApiPrefix, WebConfigUtils.AdminDirectory, WebConfigUtils.HomeDirectory, StringUtils.GetShortGuid(), false); + + DataProvider.Reset(); + + SystemManager.InstallDatabase(_userName, _password); + + await Console.Out.WriteLineAsync("恭喜,系统安装成功!"); + } + } +} diff --git a/net452/SiteServer.Cli/Jobs/RestoreJob.cs b/net452/SiteServer.Cli/Jobs/RestoreJob.cs new file mode 100644 index 000000000..1f5a946a1 --- /dev/null +++ b/net452/SiteServer.Cli/Jobs/RestoreJob.cs @@ -0,0 +1,239 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Datory; +using NDesk.Options; +using Newtonsoft.Json.Linq; +using SiteServer.Cli.Core; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.Cli.Jobs +{ + public static class RestoreJob + { + public const string CommandName = "restore"; + + private static string _directory; + private static string _configFile; + private static List _includes; + private static List _excludes; + private static bool _dataOnly; + private static bool _isHelp; + + private static readonly OptionSet Options = new OptionSet { + { "d|directory=", "从指定的文件夹中恢复数据", + v => _directory = v }, + { "c|config-file=", "指定配置文件Web.config路径或文件名", + v => _configFile = v }, + { "includes=", "指定需要还原的表,多个表用英文逗号隔开", + v => _includes = v == null ? null : TranslateUtils.StringCollectionToStringList(v) }, + { "excludes=", "指定需要排除的表,多个表用英文逗号隔开", + v => _excludes = v == null ? null : TranslateUtils.StringCollectionToStringList(v) }, + { "data-only", "仅恢复数据", + v => _dataOnly = v != null }, + { "h|help", "命令说明", + v => _isHelp = v != null } + }; + + public static void PrintUsage() + { + Console.WriteLine("数据库恢复: siteserver restore"); + Options.WriteOptionDescriptions(Console.Out); + Console.WriteLine(); + } + + public static async Task Execute(IJobContext context) + { + if (!CliUtils.ParseArgs(Options, context.Args)) return; + + if (_isHelp) + { + PrintUsage(); + return; + } + + if (string.IsNullOrEmpty(_directory)) + { + await CliUtils.PrintErrorAsync("需要指定恢复数据的文件夹名称:directory"); + return; + } + + var treeInfo = new TreeInfo(_directory); + + if (!DirectoryUtils.IsDirectoryExists(treeInfo.DirectoryPath)) + { + await CliUtils.PrintErrorAsync($"恢复数据的文件夹 {treeInfo.DirectoryPath} 不存在"); + return; + } + + var tablesFilePath = treeInfo.TablesFilePath; + if (!FileUtils.IsFileExists(tablesFilePath)) + { + await CliUtils.PrintErrorAsync($"恢复文件 {treeInfo.TablesFilePath} 不存在"); + return; + } + + var webConfigPath = CliUtils.GetWebConfigPath(_configFile); + if (!FileUtils.IsFileExists(webConfigPath)) + { + await CliUtils.PrintErrorAsync($"系统配置文件不存在:{webConfigPath}!"); + return; + } + + WebConfigUtils.Load(CliUtils.PhysicalApplicationPath, webConfigPath); + + if (string.IsNullOrEmpty(WebConfigUtils.ConnectionString)) + { + await CliUtils.PrintErrorAsync($"{webConfigPath} 中数据库连接字符串 connectionString 未设置"); + return; + } + + await Console.Out.WriteLineAsync($"数据库类型: {WebConfigUtils.DatabaseType.Value}"); + await Console.Out.WriteLineAsync($"连接字符串: {WebConfigUtils.ConnectionString}"); + await Console.Out.WriteLineAsync($"恢复文件夹: {treeInfo.DirectoryPath}"); + + if (!DataProvider.DatabaseApi.IsConnectionStringWork(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString)) + { + await CliUtils.PrintErrorAsync($"系统无法连接到 {webConfigPath} 中设置的数据库"); + return; + } + + if (!_dataOnly) + { + if (!SystemManager.IsNeedInstall()) + { + await CliUtils.PrintErrorAsync("数据无法在已安装系统的数据库中恢复,命令执行失败"); + return; + } + + // 恢复前先创建表,确保系统在恢复的数据库中能够使用 + SystemManager.SyncSystemTables(); + } + + var tableNames = TranslateUtils.JsonDeserialize>(await FileUtils.ReadTextAsync(tablesFilePath, Encoding.UTF8)); + + await CliUtils.PrintRowLineAsync(); + await CliUtils.PrintRowAsync("恢复表名称", "总条数"); + await CliUtils.PrintRowLineAsync(); + + var errorLogFilePath = CliUtils.CreateErrorLogFile(CommandName); + + foreach (var tableName in tableNames) + { + try + { + if (_includes != null) + { + if (!StringUtils.ContainsIgnoreCase(_includes, tableName)) continue; + } + if (_excludes != null) + { + if (StringUtils.ContainsIgnoreCase(_excludes, tableName)) continue; + } + + var metadataFilePath = treeInfo.GetTableMetadataFilePath(tableName); + + if (!FileUtils.IsFileExists(metadataFilePath)) continue; + + var tableInfo = TranslateUtils.JsonDeserialize(await FileUtils.ReadTextAsync(metadataFilePath, Encoding.UTF8)); + + await CliUtils.PrintRowAsync(tableName, tableInfo.TotalCount.ToString("#,0")); + + if (!DatoryUtils.IsTableExists(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName)) + { + if (!TableColumnManager.CreateTable(tableName, tableInfo.Columns, string.Empty, false, out var ex)) + { + await CliUtils.AppendErrorLogAsync(errorLogFilePath, new TextLogInfo + { + DateTime = DateTime.Now, + Detail = $"创建表 {tableName}", + Exception = ex + }); + + continue; + } + } + else + { + TableColumnManager.AlterTable(tableName, tableInfo.Columns, string.Empty); + } + + if (tableInfo.RowFiles.Count > 0) + { + using (var progress = new ProgressBar()) + { + for (var i = 0; i < tableInfo.RowFiles.Count; i++) + { + progress.Report((double)i / tableInfo.RowFiles.Count); + + var fileName = tableInfo.RowFiles[i]; + + var objects = TranslateUtils.JsonDeserialize>( + await FileUtils.ReadTextAsync(treeInfo.GetTableContentFilePath(tableName, fileName), + Encoding.UTF8)); + + try + { + DataProvider.DatabaseApi.InsertMultiple(tableName, objects, tableInfo.Columns); + } + catch (Exception ex) + { + await CliUtils.AppendErrorLogAsync(errorLogFilePath, new TextLogInfo + { + DateTime = DateTime.Now, + Detail = $"插入表 {tableName}, 文件名 {fileName}", + Exception = ex + }); + } + } + } + } + } + catch (Exception ex) + { + await CliUtils.AppendErrorLogAsync(errorLogFilePath, new TextLogInfo + { + DateTime = DateTime.Now, + Detail = $"插入表 {tableName}", + Exception = ex + }); + } + } + + await CliUtils.PrintRowLineAsync(); + + if (WebConfigUtils.DatabaseType == DatabaseType.Oracle) + { + var tableNameList = DatoryUtils.GetTableNames(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString); + + foreach (var tableName in tableNameList) + { + try + { + var sqlString = + $"ALTER TABLE {tableName} MODIFY Id GENERATED ALWAYS AS IDENTITY(START WITH LIMIT VALUE)"; + DataProvider.DatabaseApi.Execute(sqlString); + } + catch + { + // ignored + } + } + } + + if (!_dataOnly) + { + // 恢复后同步表,确保内容辅助表字段与系统一致 + SystemManager.SyncContentTables(); + SystemManager.UpdateConfigVersion(); + } + + await Console.Out.WriteLineAsync($"恭喜,成功从文件夹:{treeInfo.DirectoryPath} 恢复数据!"); + } + } +} diff --git a/net452/SiteServer.Cli/Jobs/TestJob.cs b/net452/SiteServer.Cli/Jobs/TestJob.cs new file mode 100644 index 000000000..c15ffab95 --- /dev/null +++ b/net452/SiteServer.Cli/Jobs/TestJob.cs @@ -0,0 +1,45 @@ +using System; +using System.Reflection; +using System.Threading.Tasks; +using NDesk.Options; +using SiteServer.Cli.Core; +using SiteServer.Plugin; + +namespace SiteServer.Cli.Jobs +{ + public static class TestJob + { + public const string CommandName = "test add"; + + private static bool _isHelp; + private static string _webConfigFileName; + + private static readonly OptionSet Options = new OptionSet() + { + { + "c|config=", "the {web.config} file name.", + v => _webConfigFileName = v + }, + { + "h|help", "命令说明", + v => _isHelp = v != null + } + }; + + public static async Task Execute(IJobContext context) + { + if (!CliUtils.ParseArgs(Options, context.Args)) return; + + if (_isHelp) + { + return; + } + + var version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + await Console.Out.WriteLineAsync($"SiteServer CLI Version: {version.Substring(0, version.Length - 2)}"); + await Console.Out.WriteLineAsync($"Work Directory: {CliUtils.PhysicalApplicationPath}"); + await Console.Out.WriteLineAsync($"siteserver.exe Path: {Assembly.GetExecutingAssembly().Location}"); + await Console.Out.WriteLineAsync(); + } + } +} diff --git a/net452/SiteServer.Cli/Jobs/UpdateJob.cs b/net452/SiteServer.Cli/Jobs/UpdateJob.cs new file mode 100644 index 000000000..5dea08b78 --- /dev/null +++ b/net452/SiteServer.Cli/Jobs/UpdateJob.cs @@ -0,0 +1,163 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using NDesk.Options; +using SiteServer.Cli.Core; +using SiteServer.Cli.Updater; +using SiteServer.CMS.Database.Repositories.Contents; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.Cli.Jobs +{ + public static class UpdateJob + { + public const string CommandName = "update"; + private const string Folder = "update"; + + private static string _directory; + private static bool _contentSplit; + private static bool _isHelp; + + private static readonly OptionSet Options = new OptionSet() { + { "d|directory=", "指定需要转换至最新版本的备份数据文件夹", + v => _directory = v }, + { "content-split", "拆分内容表", + v => _contentSplit = v != null }, + { "h|help", "命令说明", + v => _isHelp = v != null } + }; + + public static void PrintUsage() + { + Console.WriteLine("升级备份数据: siteserver update"); + Options.WriteOptionDescriptions(Console.Out); + Console.WriteLine(); + } + + public static async Task Execute(IJobContext context) + { + if (!CliUtils.ParseArgs(Options, context.Args)) return; + + if (_isHelp) + { + PrintUsage(); + return; + } + + if (string.IsNullOrEmpty(_directory)) + { + await CliUtils.PrintErrorAsync("未指定需要转换至最新版本的备份数据文件夹:directory"); + return; + } + + var oldTreeInfo = new TreeInfo(_directory); + var newTreeInfo = new TreeInfo(Folder); + + if (!DirectoryUtils.IsDirectoryExists(oldTreeInfo.DirectoryPath)) + { + await CliUtils.PrintErrorAsync($"备份数据的文件夹 {oldTreeInfo.DirectoryPath} 不存在"); + return; + } + DirectoryUtils.CreateDirectoryIfNotExists(newTreeInfo.DirectoryPath); + + var updater = new UpdaterManager(oldTreeInfo, newTreeInfo); + + var version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + await Console.Out.WriteLineAsync($"备份数据文件夹: {oldTreeInfo.DirectoryPath},升级数据文件夹: {newTreeInfo.DirectoryPath},升级版本: {version.Substring(0, version.Length - 2)}"); + + var oldTableNames = TranslateUtils.JsonDeserialize>(await FileUtils.ReadTextAsync(oldTreeInfo.TablesFilePath, Encoding.UTF8)); + var newTableNames = new List(); + + await CliUtils.PrintRowLineAsync(); + await CliUtils.PrintRowAsync("备份表名称", "升级表名称", "总条数"); + await CliUtils.PrintRowLineAsync(); + + var siteIdList = new List(); + var tableNameListForContent = new List(); + var tableNameListForGovPublic = new List(); + var tableNameListForGovInteract = new List(); + var tableNameListForJob = new List(); + + UpdateUtils.LoadSites(oldTreeInfo, siteIdList, + tableNameListForContent, tableNameListForGovPublic, tableNameListForGovInteract, tableNameListForJob); + + var splitSiteTableDict = new Dictionary(); + if (_contentSplit) + { + var converter = ContentConverter.GetSplitConverter(); + foreach (var siteId in siteIdList) + { + splitSiteTableDict.Add(siteId, new TableInfo + { + Columns = converter.NewColumns, + TotalCount = 0, + RowFiles = new List() + }); + } + } + + foreach (var oldTableName in oldTableNames) + { + var oldMetadataFilePath = oldTreeInfo.GetTableMetadataFilePath(oldTableName); + + if (!FileUtils.IsFileExists(oldMetadataFilePath)) continue; + + var oldTableInfo = TranslateUtils.JsonDeserialize(await FileUtils.ReadTextAsync(oldMetadataFilePath, Encoding.UTF8)); + + if (StringUtils.ContainsIgnoreCase(tableNameListForContent, oldTableName)) + { + if (_contentSplit) + { + var converter = ContentConverter.GetConverter(oldTableName, oldTableInfo.Columns); + + await updater.UpdateSplitContentsTableInfoAsync(splitSiteTableDict, siteIdList, oldTableName, + oldTableInfo, converter); + } + else + { + var converter = ContentConverter.GetConverter(oldTableName, oldTableInfo.Columns); + var tuple = await updater.GetNewTableInfoAsync(oldTableName, oldTableInfo, converter); + if (tuple != null) + { + newTableNames.Add(tuple.Item1); + + await FileUtils.WriteTextAsync(newTreeInfo.GetTableMetadataFilePath(tuple.Item1), TranslateUtils.JsonSerialize(tuple.Item2)); + } + } + } + else + { + var tuple = await updater.UpdateTableInfoAsync(oldTableName, oldTableInfo, tableNameListForGovPublic, tableNameListForGovInteract, tableNameListForJob); + if (tuple != null) + { + newTableNames.Add(tuple.Item1); + + await FileUtils.WriteTextAsync(newTreeInfo.GetTableMetadataFilePath(tuple.Item1), TranslateUtils.JsonSerialize(tuple.Item2)); + } + } + } + + if (_contentSplit) + { + foreach (var siteId in siteIdList) + { + var siteTableInfo = splitSiteTableDict[siteId]; + var siteTableName = ContentRepository.GetContentTableName(siteId); + newTableNames.Add(siteTableName); + + await FileUtils.WriteTextAsync(newTreeInfo.GetTableMetadataFilePath(siteTableName), TranslateUtils.JsonSerialize(siteTableInfo)); + } + + await UpdateUtils.UpdateSitesSplitTableNameAsync(newTreeInfo, splitSiteTableDict); + } + + await FileUtils.WriteTextAsync(newTreeInfo.TablesFilePath, TranslateUtils.JsonSerialize(newTableNames)); + + await CliUtils.PrintRowLineAsync(); + await Console.Out.WriteLineAsync($"恭喜,成功从备份文件夹:{oldTreeInfo.DirectoryPath} 升级至新版本:{newTreeInfo.DirectoryPath} !"); + } + } +} diff --git a/net452/SiteServer.Cli/Jobs/VersionJob.cs b/net452/SiteServer.Cli/Jobs/VersionJob.cs new file mode 100644 index 000000000..15fd541a7 --- /dev/null +++ b/net452/SiteServer.Cli/Jobs/VersionJob.cs @@ -0,0 +1,71 @@ +using System; +using System.Diagnostics; +using System.Reflection; +using System.Threading.Tasks; +using NDesk.Options; +using SiteServer.Cli.Core; +using SiteServer.CMS.Fx; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.Cli.Jobs +{ + public static class VersionJob + { + public const string CommandName = "version"; + + private static string _configFile; + private static bool _isHelp; + + private static readonly OptionSet Options = new OptionSet { + { "c|config-file=", "指定配置文件Web.config路径或文件名", + v => _configFile = v }, + { "h|help", "命令说明", + v => _isHelp = v != null } + }; + + public static void PrintUsage() + { + Console.WriteLine("当前版本: siteserver version"); + Options.WriteOptionDescriptions(Console.Out); + Console.WriteLine(); + } + + public static async Task Execute(IJobContext context) + { + if (!CliUtils.ParseArgs(Options, context.Args)) return; + + if (_isHelp) + { + PrintUsage(); + return; + } + + var version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + await Console.Out.WriteLineAsync($"SiteServer CLI 版本号: {version.Substring(0, version.Length - 2)}"); + await Console.Out.WriteLineAsync($"当前文件夹: {CliUtils.PhysicalApplicationPath}"); + await Console.Out.WriteLineAsync(); + + var webConfigPath = CliUtils.GetWebConfigPath(_configFile); + + if (FileUtils.IsFileExists(webConfigPath)) + { + WebConfigUtils.Load(CliUtils.PhysicalApplicationPath, webConfigPath); + + try + { + var cmsVersion = FileVersionInfo.GetVersionInfo(PathUtils.Combine(CliUtils.PhysicalApplicationPath, "Bin", "SiteServer.CMS.dll")).ProductVersion; + await Console.Out.WriteLineAsync($"SitServer CMS 版本号: {cmsVersion}"); + } + catch + { + // ignored + } + + await Console.Out.WriteLineAsync($"数据库类型: {WebConfigUtils.DatabaseType.Value}"); + await Console.Out.WriteLineAsync($"连接字符串: {WebConfigUtils.ConnectionString}"); + await Console.Out.WriteLineAsync($"连接字符串(加密): {TranslateUtils.EncryptStringBySecretKey(WebConfigUtils.ConnectionString, WebConfigUtils.SecretKey)}"); + } + } + } +} diff --git a/net452/SiteServer.Cli/Program.cs b/net452/SiteServer.Cli/Program.cs new file mode 100644 index 000000000..e50559aa3 --- /dev/null +++ b/net452/SiteServer.Cli/Program.cs @@ -0,0 +1,208 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Reflection; +using System.Text; +using System.Threading.Tasks; +using NDesk.Options; +using Quartz; +using Quartz.Impl; +using SiteServer.Cli.Core; +using SiteServer.Cli.Jobs; +using SiteServer.CMS.Plugin; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.Cli +{ + internal static class Program + { + private static bool IsHelp { get; set; } + private static string Repeat { get; set; } + private static Dictionary> Jobs { get; set; } + public static string CommandName { get; private set; } + public static string[] CommandArgs { get; private set; } + + private static readonly OptionSet Options = new OptionSet { + { "r|repeat=", "schedule CRON expression", + v => Repeat = v }, + { "h|help", "命令说明", + v => IsHelp = v != null } + }; + + private static void Main(string[] args) + { + try + { + Console.OutputEncoding = Encoding.GetEncoding(936); + } + catch + { + try + { + Console.OutputEncoding = Encoding.UTF8; + } + catch + { + // ignored + } + } + + if (!CliUtils.ParseArgs(Options, args)) return; + + var commandNames = new List(); + var commandArgs = new List(); + if (args.Length >= 1) + { + var isCommand = true; + foreach (var arg in args) + { + if (isCommand && !StringUtils.StartsWith(arg, "-")) + { + commandNames.Add(StringUtils.Trim(arg)); + } + else + { + isCommand = false; + commandArgs.Add(StringUtils.Trim(arg)); + } + } + } + CommandName = string.Join(" ", commandNames); + CommandArgs = commandArgs.ToArray(); + + Console.WriteLine("欢迎使用 SiteServer Cli 命令行工具"); + Console.WriteLine(); + + Jobs = new Dictionary>(StringComparer.CurrentCultureIgnoreCase) + { + {BackupJob.CommandName, BackupJob.Execute}, + {InstallJob.CommandName, InstallJob.Execute}, + {RestoreJob.CommandName, RestoreJob.Execute}, + {UpdateJob.CommandName, UpdateJob.Execute}, + {VersionJob.CommandName, VersionJob.Execute}, + {TestJob.CommandName, TestJob.Execute} + }; + + PluginManager.LoadPlugins(CliUtils.PhysicalApplicationPath); + var pluginJobs = PluginJobManager.GetJobs(); + if (pluginJobs != null && pluginJobs.Count > 0) + { + foreach (var command in pluginJobs.Keys) + { + if (!Jobs.ContainsKey(command)) + { + Jobs.Add(command, pluginJobs[command]); + } + } + } + + if (!Jobs.ContainsKey(CommandName)) + { + RunHelpAsync(IsHelp, CommandName).GetAwaiter().GetResult(); + } + else if (!string.IsNullOrEmpty(Repeat)) + { + RunRepeatAsync(Repeat).GetAwaiter().GetResult(); + } + else + { + RunExecuteAsync(CommandName, CommandArgs, null).GetAwaiter().GetResult(); + } + } + + private static async Task RunHelpAsync(bool isHelp, string commandName) + { + if (isHelp || string.IsNullOrEmpty(commandName)) + { + var version = Assembly.GetExecutingAssembly().GetName().Version.ToString(); + await Console.Out.WriteLineAsync($"Cli 命令行版本: {version.Substring(0, version.Length - 2)}"); + await Console.Out.WriteLineAsync($"当前文件夹: {CliUtils.PhysicalApplicationPath}"); + await Console.Out.WriteLineAsync($"Cli 命令行文件夹: {Assembly.GetExecutingAssembly().Location}"); + await Console.Out.WriteLineAsync(); + + await CliUtils.PrintRowLine(); + await CliUtils.PrintRow("Usage"); + await CliUtils.PrintRowLine(); + BackupJob.PrintUsage(); + InstallJob.PrintUsage(); + RestoreJob.PrintUsage(); + UpdateJob.PrintUsage(); + VersionJob.PrintUsage(); + await CliUtils.PrintRowLine(); + await CliUtils.PrintRow("https://www.siteserver.cn/docs/cli"); + await CliUtils.PrintRowLine(); + Console.ReadLine(); + } + else + { + Console.WriteLine($"'{commandName}' is not a siteserver command. See 'sitserver --help'"); + } + } + + private static async Task RunRepeatAsync(string schedule) + { + try + { + var factory = new StdSchedulerFactory(new NameValueCollection + { + { "quartz.serializer.type", "binary" } + }); + var sched = await factory.GetScheduler(); + + await sched.Start(); + + var job = JobBuilder.Create() + .WithIdentity("job1", "group1") + .Build(); + + var trigger = TriggerBuilder.Create() + .WithIdentity("trigger1", "group1") + .StartNow() + .WithCronSchedule(schedule) + .WithPriority(1) + .Build(); + + await sched.ScheduleJob(job, trigger); + await Task.Delay(-1); + await sched.Shutdown(); + } + catch (Exception ex) + { + await CliUtils.PrintErrorAsync(ex.Message); + } + } + + public static async Task RunExecuteAsync(string commandName, string[] commandArgs, IJobExecutionContext jobContext) + { + try + { + Func job; + if (Jobs.TryGetValue(commandName, out job)) + { + if (job != null) + { + var context = new JobContextImpl(commandName, commandArgs, jobContext); + await job(context); + } + } + } + catch (Exception ex) + { + await CliUtils.PrintErrorAsync(ex.Message); + + var errorLogFilePath = CliUtils.CreateErrorLogFile("siteserver"); + + await CliUtils.AppendErrorLogsAsync(errorLogFilePath, new List + { + new TextLogInfo + { + DateTime = DateTime.Now, + Detail = "Console Error", + Exception = ex + } + }); + } + } + } +} diff --git a/net452/SiteServer.Cli/Properties/AssemblyInfo.cs b/net452/SiteServer.Cli/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..981d56dfd --- /dev/null +++ b/net452/SiteServer.Cli/Properties/AssemblyInfo.cs @@ -0,0 +1,10 @@ +using System.Reflection; +using System.Runtime.InteropServices; + +[assembly: AssemblyTitle("SiteServer.Cli")] +[assembly: AssemblyDescription("SiteServer Cli Tool")] +[assembly: AssemblyCopyright("Copyright © SiteServer CMS 2018")] +[assembly: Guid("8a918b36-20c3-49ef-8787-2250170e0576")] +[assembly: AssemblyVersion("0.0.0")] +[assembly: AssemblyFileVersion("0.0.0")] +[assembly: AssemblyInformationalVersion("0.0.0-dev")] diff --git a/net452/SiteServer.Cli/README.md b/net452/SiteServer.Cli/README.md new file mode 100644 index 000000000..f1898205e --- /dev/null +++ b/net452/SiteServer.Cli/README.md @@ -0,0 +1,2 @@ +# cli +SiteServer CMS 命令行(CLI)工具(备份、恢复、升级、同步……) \ No newline at end of file diff --git a/net452/SiteServer.Cli/SiteServer.Cli.csproj b/net452/SiteServer.Cli/SiteServer.Cli.csproj new file mode 100644 index 000000000..aa2d55529 --- /dev/null +++ b/net452/SiteServer.Cli/SiteServer.Cli.csproj @@ -0,0 +1,217 @@ + + + + + + + Debug + AnyCPU + {A7E4D925-AACF-4782-8B9A-C10B9F527A0C} + Exe + SiteServer.Cli + siteserver + v4.5.2 + 512 + true + + + + + + AnyCPU + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + Auto + + + AnyCPU + pdbonly + true + ..\ + TRACE + prompt + 4 + + + SiteServer.Cli.Program + + + logo.ico + + + + ..\..\packages\Costura.Fody.3.3.3\lib\net40\Costura.dll + + + ..\..\packages\Dapper.1.60.6\lib\net451\Dapper.dll + + + ..\..\packages\Datory.0.1.7\lib\net452\Datory.dll + + + ..\..\packages\Google.Protobuf.3.5.1\lib\net45\Google.Protobuf.dll + + + ..\..\packages\Microsoft.Web.Xdt.2.1.1\lib\net40\Microsoft.Web.XmlTransform.dll + + + ..\..\packages\MySql.Data.8.0.15\lib\net452\MySql.Data.dll + + + ..\..\packages\NDesk.Options.0.2.1\lib\NDesk.Options.dll + + + ..\..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll + + + ..\..\packages\Npgsql.4.0.5\lib\net451\Npgsql.dll + + + ..\..\packages\Oracle.ManagedDataAccess.18.6.0\lib\net40\Oracle.ManagedDataAccess.dll + + + ..\..\packages\Quartz.3.0.7\lib\net452\Quartz.dll + + + ..\..\packages\SqlKata.1.1.7\lib\net45\QueryBuilder.dll + + + ..\..\packages\SiteServer.Plugin.2.2.14-beta\lib\net452\SiteServer.Plugin.dll + + + + ..\..\packages\System.Buffers.4.4.0\lib\netstandard1.1\System.Buffers.dll + + + + + + + + + + + + + ..\..\packages\System.Memory.4.5.2\lib\netstandard1.1\System.Memory.dll + + + ..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll + + + + ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard1.0\System.Runtime.CompilerServices.Unsafe.dll + + + + ..\..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll + + + + ..\..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll + + + ..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.7\lib\net45\System.Web.Http.dll + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {059e3927-37e1-4f6f-b525-fef40c54906b} + SiteServer.Utils + + + {944127c3-915d-4f02-a534-64ec668c46ec} + SiteServer.CMS + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Cli/Updater/ContentConverter.cs b/net452/SiteServer.Cli/Updater/ContentConverter.cs new file mode 100644 index 000000000..b4a1c7b92 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/ContentConverter.cs @@ -0,0 +1,184 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.Cli.Updater +{ + public partial class ContentConverter + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("nodeID")] + public long NodeId { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("addUserName")] + public string AddUserName { get; set; } + + [JsonProperty("lastEditUserName")] + public string LastEditUserName { get; set; } + + [JsonProperty("lastEditDate")] + public DateTimeOffset LastEditDate { get; set; } + + [JsonProperty("taxis")] + public long Taxis { get; set; } + + [JsonProperty("contentGroupNameCollection")] + public string ContentGroupNameCollection { get; set; } + + [JsonProperty("tags")] + public string Tags { get; set; } + + [JsonProperty("sourceID")] + public long SourceId { get; set; } + + [JsonProperty("referenceID")] + public long ReferenceId { get; set; } + + [JsonProperty("isChecked")] + public string IsChecked { get; set; } + + [JsonProperty("checkedLevel")] + public long CheckedLevel { get; set; } + + [JsonProperty("comments")] + public long Comments { get; set; } + + [JsonProperty("hits")] + public long Hits { get; set; } + + [JsonProperty("hitsByDay")] + public long HitsByDay { get; set; } + + [JsonProperty("hitsByWeek")] + public long HitsByWeek { get; set; } + + [JsonProperty("hitsByMonth")] + public long HitsByMonth { get; set; } + + [JsonProperty("lastHitsDate")] + public DateTimeOffset LastHitsDate { get; set; } + + [JsonProperty("settingsXML")] + public string SettingsXml { get; set; } + + [JsonProperty("title")] + public string Title { get; set; } + + [JsonProperty("subTitle")] + public string SubTitle { get; set; } + + [JsonProperty("imageUrl")] + public string ImageUrl { get; set; } + + [JsonProperty("videoUrl")] + public string VideoUrl { get; set; } + + [JsonProperty("fileUrl")] + public string FileUrl { get; set; } + + [JsonProperty("linkUrl")] + public string LinkUrl { get; set; } + + [JsonProperty("content")] + public string Content { get; set; } + + [JsonProperty("summary")] + public string Summary { get; set; } + + [JsonProperty("author")] + public string Author { get; set; } + + [JsonProperty("source")] + public string Source { get; set; } + + [JsonProperty("isRecommend")] + public string IsRecommend { get; set; } + + [JsonProperty("isHot")] + public string IsHot { get; set; } + + [JsonProperty("isColor")] + public string IsColor { get; set; } + + [JsonProperty("isTop")] + public string IsTop { get; set; } + + [JsonProperty("addDate")] + public DateTimeOffset AddDate { get; set; } + } + + public partial class ContentConverter + { + public static ConvertInfo GetSplitConverter() + { + return new ConvertInfo + { + NewColumns = GetNewColumns(null), + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + } + + public static ConvertInfo GetConverter(string oldTableName, List oldColumns) + { + return new ConvertInfo + { + NewTableName = oldTableName, + NewColumns = GetNewColumns(oldColumns), + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + } + + private static List GetNewColumns(List oldColumns) + { + var columns = new List(); + columns.AddRange(DataProvider.ContentRepository.TableColumns); + + if (oldColumns != null && oldColumns.Count > 0) + { + foreach (var tableColumnInfo in oldColumns) + { + if (StringUtils.EqualsIgnoreCase(tableColumnInfo.AttributeName, nameof(NodeId))) + { + tableColumnInfo.AttributeName = nameof(ContentInfo.ChannelId); + } + else if (StringUtils.EqualsIgnoreCase(tableColumnInfo.AttributeName, nameof(PublishmentSystemId))) + { + tableColumnInfo.AttributeName = nameof(ContentInfo.SiteId); + } + else if (StringUtils.EqualsIgnoreCase(tableColumnInfo.AttributeName, nameof(ContentGroupNameCollection))) + { + tableColumnInfo.AttributeName = nameof(ContentInfo.GroupNameCollection); + } + + if (!columns.Exists(c => StringUtils.EqualsIgnoreCase(c.AttributeName, tableColumnInfo.AttributeName))) + { + columns.Add(tableColumnInfo); + } + } + } + + return columns; + } + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(ContentInfo.ChannelId), nameof(NodeId)}, + {nameof(ContentInfo.SiteId), nameof(PublishmentSystemId)}, + {nameof(ContentInfo.GroupNameCollection), nameof(ContentGroupNameCollection)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/ConvertInfo.cs b/net452/SiteServer.Cli/Updater/ConvertInfo.cs new file mode 100644 index 000000000..4e8885e83 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/ConvertInfo.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using Datory; + +namespace SiteServer.Cli.Updater +{ + public class ConvertInfo + { + public bool IsAbandon { get; set; } + + public string NewTableName { get; set; } + + public List NewColumns { get; set; } + + public Dictionary ConvertKeyDict { get; set; } + + public Dictionary ConvertValueDict { get; set; } + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractChannel.cs b/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractChannel.cs new file mode 100644 index 000000000..6b71cef03 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractChannel.cs @@ -0,0 +1,97 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.Plugin; +using TableColumn = Datory.TableColumn; + +namespace SiteServer.Cli.Updater.Tables.GovInteract +{ + public partial class TableGovInteractChannel + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("nodeID")] + public long NodeId { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("applyStyleID")] + public long ApplyStyleId { get; set; } + + [JsonProperty("queryStyleID")] + public long QueryStyleId { get; set; } + + [JsonProperty("departmentIDCollection")] + public string DepartmentIdCollection { get; set; } + + [JsonProperty("summary")] + public string Summary { get; set; } + } + + public partial class TableGovInteractChannel + { + public const string OldTableName = "wcm_GovInteractChannel"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = "ss_govinteract_channel"; + + private static readonly List NewColumns = new List + { + new TableColumn + { + AttributeName = "Id", + DataType = DataType.Integer, + IsPrimaryKey = true, + IsIdentity = true + }, + new TableColumn + { + AttributeName = "ChannelId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "SiteId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "ApplyStyleId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "QueryStyleId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "DepartmentIdCollection", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "Summary", + DataType = DataType.VarChar + } + }; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {"ChannelId", nameof(NodeId)}, + {"SiteId", nameof(PublishmentSystemId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractContent.cs b/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractContent.cs new file mode 100644 index 000000000..ff0d012c8 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractContent.cs @@ -0,0 +1,499 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.Cli.Updater.Tables.GovInteract +{ + public partial class TableGovInteractContent + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("nodeID")] + public long NodeId { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("addUserName")] + public string AddUserName { get; set; } + + [JsonProperty("lastEditUserName")] + public string LastEditUserName { get; set; } + + [JsonProperty("lastEditDate")] + public DateTimeOffset LastEditDate { get; set; } + + [JsonProperty("taxis")] + public long Taxis { get; set; } + + [JsonProperty("contentGroupNameCollection")] + public string ContentGroupNameCollection { get; set; } + + [JsonProperty("tags")] + public string Tags { get; set; } + + [JsonProperty("sourceID")] + public long SourceId { get; set; } + + [JsonProperty("referenceID")] + public long ReferenceId { get; set; } + + [JsonProperty("isChecked")] + public string IsChecked { get; set; } + + [JsonProperty("checkedLevel")] + public long CheckedLevel { get; set; } + + [JsonProperty("comments")] + public long Comments { get; set; } + + [JsonProperty("hits")] + public long Hits { get; set; } + + [JsonProperty("hitsByDay")] + public long HitsByDay { get; set; } + + [JsonProperty("hitsByWeek")] + public long HitsByWeek { get; set; } + + [JsonProperty("hitsByMonth")] + public long HitsByMonth { get; set; } + + [JsonProperty("lastHitsDate")] + public DateTimeOffset LastHitsDate { get; set; } + + [JsonProperty("settingsXML")] + public string SettingsXml { get; set; } + + [JsonProperty("title")] + public string Title { get; set; } + + [JsonProperty("subTitle")] + public string SubTitle { get; set; } + + [JsonProperty("imageUrl")] + public string ImageUrl { get; set; } + + [JsonProperty("videoUrl")] + public string VideoUrl { get; set; } + + [JsonProperty("fileUrl")] + public string FileUrl { get; set; } + + [JsonProperty("linkUrl")] + public string LinkUrl { get; set; } + + [JsonProperty("content")] + public string Content { get; set; } + + [JsonProperty("summary")] + public string Summary { get; set; } + + [JsonProperty("author")] + public string Author { get; set; } + + [JsonProperty("source")] + public string Source { get; set; } + + [JsonProperty("isRecommend")] + public string IsRecommend { get; set; } + + [JsonProperty("isHot")] + public string IsHot { get; set; } + + [JsonProperty("isColor")] + public string IsColor { get; set; } + + [JsonProperty("isTop")] + public string IsTop { get; set; } + + [JsonProperty("addDate")] + public DateTimeOffset AddDate { get; set; } + } + + public partial class TableGovInteractContent + { + public const string NewTableName = "ss_govinteract_content"; + + private static List NewColumns => new List + { + new TableColumn + { + AttributeName = "RealName", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Text, + // DisplayName = "姓名" + //} + }, + new TableColumn + { + AttributeName = "Organization", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Text, + // DisplayName = "工作单位" + //} + }, + new TableColumn + { + AttributeName = "CardType", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.SelectOne, + // DisplayName = "证件名称", + // IsRequired = true, + // ListItems = new List + // { + // new InputListItem + // { + // Text = "身份证", + // Value = "身份证", + // Selected = true + // }, + // new InputListItem + // { + // Text = "学生证", + // Value = "学生证", + // Selected = false + // }, + // new InputListItem + // { + // Text = "军官证", + // Value = "军官证", + // Selected = false + // }, + // new InputListItem + // { + // Text = "工作证", + // Value = "工作证", + // Selected = false + // } + // } + //} + }, + new TableColumn + { + AttributeName = "CardNo", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Text, + // DisplayName = "证件号码" + //} + }, + new TableColumn + { + AttributeName = "Phone", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Text, + // DisplayName = "联系电话" + //} + }, + new TableColumn + { + AttributeName = "PostCode", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Text, + // DisplayName = "邮政编码" + //} + }, + new TableColumn + { + AttributeName = "Address", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Text, + // DisplayName = "联系地址" + //} + }, + new TableColumn + { + AttributeName = "Email", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Text, + // DisplayName = "电子邮件" + //} + }, + new TableColumn + { + AttributeName = "Fax", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Text, + // DisplayName = "传真" + //} + }, + new TableColumn + { + AttributeName = "TypeId", + DataType = DataType.Integer, + + //InputStyle = new InputStyle + //{ + // InputType = InputType.SelectOne, + // DisplayName = "类型", + // IsRequired = true, + // ListItems = new List + // { + // new InputListItem + // { + // Text = "求决", + // Value = "15", + // Selected = false + // }, + // new InputListItem + // { + // Text = "举报", + // Value = "16", + // Selected = false + // }, + // new InputListItem + // { + // Text = "投诉", + // Value = "17", + // Selected = false + // }, + // new InputListItem + // { + // Text = "咨询", + // Value = "18", + // Selected = true + // }, + // new InputListItem + // { + // Text = "建议", + // Value = "19", + // Selected = false + // }, + // new InputListItem + // { + // Text = "感谢", + // Value = "20", + // Selected = false + // }, + // new InputListItem + // { + // Text = "其他", + // Value = "21", + // Selected = false + // } + // } + //} + }, + new TableColumn + { + AttributeName = "IsPublic", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Radio, + // DisplayName = "是否公开", + // IsRequired = true, + // ListItems = new List + // { + // new InputListItem + // { + // Text = "公开", + // Value = true.ToString(), + // Selected = true + // }, + // new InputListItem + // { + // Text = "不公开", + // Value = false.ToString(), + // Selected = false + // } + // } + //} + }, + new TableColumn + { + AttributeName = "Content", + DataType = DataType.Text, + //InputStyle = new InputStyle + //{ + // InputType = InputType.TextEditor, + // DisplayName = "内容" + //} + }, + new TableColumn + { + AttributeName = "FileUrl", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.File, + // DisplayName = "附件" + //} + }, + new TableColumn + { + AttributeName = "DepartmentId", + DataType = DataType.Integer, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Customize, + // DisplayName = "提交部门" + //} + }, + new TableColumn + { + AttributeName = "DepartmentName", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Hidden, + // DisplayName = "提交部门" + //} + }, + new TableColumn + { + AttributeName = "QueryCode", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Hidden, + // DisplayName = "查询码" + //} + }, + new TableColumn + { + AttributeName = "State", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Hidden, + // DisplayName = "状态" + //} + }, + new TableColumn + { + AttributeName = "IpAddress", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Hidden, + // DisplayName = "IP地址" + //} + }, + new TableColumn + { + AttributeName = "ReplyContent", + DataType = DataType.Text, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Hidden, + // DisplayName = "回复内容" + //} + }, + new TableColumn + { + AttributeName = "ReplyFileUrl", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Hidden, + // DisplayName = "回复附件" + //} + }, + new TableColumn + { + AttributeName = "ReplyDepartmentName", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Hidden, + // DisplayName = "回复部门" + //} + }, + new TableColumn + { + AttributeName = "ReplyUserName", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Hidden, + // DisplayName = "回复人" + //} + }, + new TableColumn + { + AttributeName = "ReplyAddDate", + DataType = DataType.DateTime, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Hidden, + // DisplayName = "回复时间" + //} + } + }; + + private static List GetNewColumns(List oldColumns) + { + var columns = new List(); + columns.AddRange(DataProvider.ContentRepository.TableColumns); + columns.AddRange(NewColumns); + + foreach (var tableColumnInfo in oldColumns) + { + if (StringUtils.EqualsIgnoreCase(tableColumnInfo.AttributeName, nameof(NodeId))) + { + tableColumnInfo.AttributeName = nameof(ContentInfo.ChannelId); + } + else if (StringUtils.EqualsIgnoreCase(tableColumnInfo.AttributeName, nameof(PublishmentSystemId))) + { + tableColumnInfo.AttributeName = nameof(ContentInfo.SiteId); + } + else if (StringUtils.EqualsIgnoreCase(tableColumnInfo.AttributeName, nameof(ContentGroupNameCollection))) + { + tableColumnInfo.AttributeName = nameof(ContentInfo.GroupNameCollection); + } + + if (!columns.Exists(c => StringUtils.EqualsIgnoreCase(c.AttributeName, tableColumnInfo.AttributeName))) + { + columns.Add(tableColumnInfo); + } + } + + return columns; + } + + public static ConvertInfo GetConverter(List oldColumns) + { + return new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = GetNewColumns(oldColumns), + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + } + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(ContentInfo.ChannelId), nameof(NodeId)}, + {nameof(ContentInfo.SiteId), nameof(PublishmentSystemId)}, + {nameof(ContentInfo.GroupNameCollection), nameof(ContentGroupNameCollection)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} \ No newline at end of file diff --git a/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractLog.cs b/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractLog.cs new file mode 100644 index 000000000..6b719e7c3 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractLog.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; + +namespace SiteServer.Cli.Updater.Tables.GovInteract +{ + public partial class TableGovInteractLog + { + [JsonProperty("logID")] + public long LogId { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("nodeID")] + public long NodeId { get; set; } + + [JsonProperty("contentID")] + public object ContentId { get; set; } + + [JsonProperty("departmentID")] + public long DepartmentId { get; set; } + + [JsonProperty("userName")] + public string UserName { get; set; } + + [JsonProperty("logType")] + public string LogType { get; set; } + + [JsonProperty("ipAddress")] + public string IpAddress { get; set; } + + [JsonProperty("addDate")] + public DateTimeOffset AddDate { get; set; } + + [JsonProperty("summary")] + public string Summary { get; set; } + } + + public partial class TableGovInteractLog + { + public const string OldTableName = "wcm_GovInteractLog"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = "ss_govinteract_log"; + + private static readonly List NewColumns = new List + { + new TableColumn + { + AttributeName = "Id", + DataType = DataType.Integer, + IsPrimaryKey = true, + IsIdentity = true + }, + new TableColumn + { + AttributeName = "SiteId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "ChannelId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "ContentId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "DepartmentId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "UserName", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "LogType", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "IpAddress", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "AddDate", + DataType = DataType.DateTime + }, + new TableColumn + { + AttributeName = "Summary", + DataType = DataType.VarChar + } + }; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {"Id", nameof(LogId)}, + {"SiteId", nameof(PublishmentSystemId)}, + {"ChannelId", nameof(NodeId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractPermissions.cs b/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractPermissions.cs new file mode 100644 index 000000000..f1087e4be --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractPermissions.cs @@ -0,0 +1,70 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; + +namespace SiteServer.Cli.Updater.Tables.GovInteract +{ + public partial class TableGovInteractPermissions + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("userName")] + public string UserName { get; set; } + + [JsonProperty("nodeID")] + public long NodeId { get; set; } + + [JsonProperty("permissions")] + public string Permissions { get; set; } + } + + public partial class TableGovInteractPermissions + { + public const string OldTableName = "wcm_GovInteractPermissions"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = "ss_govinteract_permissions"; + + private static readonly List NewColumns = new List + { + new TableColumn + { + AttributeName = "Id", + DataType = DataType.Integer, + IsPrimaryKey = true, + IsIdentity = true + }, + new TableColumn + { + AttributeName = "UserName", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "ChannelId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "Permissions", + DataType = DataType.Text + } + }; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {"ChannelId", nameof(NodeId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractRemark.cs b/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractRemark.cs new file mode 100644 index 000000000..39775a34a --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractRemark.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; + +namespace SiteServer.Cli.Updater.Tables.GovInteract +{ + public partial class TableGovInteractRemark + { + [JsonProperty("remarkID")] + public long RemarkId { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("nodeID")] + public long NodeId { get; set; } + + [JsonProperty("contentID")] + public object ContentId { get; set; } + + [JsonProperty("remarkType")] + public string RemarkType { get; set; } + + [JsonProperty("remark")] + public string Remark { get; set; } + + [JsonProperty("departmentID")] + public long DepartmentId { get; set; } + + [JsonProperty("userName")] + public string UserName { get; set; } + + [JsonProperty("addDate")] + public DateTimeOffset AddDate { get; set; } + } + + public partial class TableGovInteractRemark + { + public const string OldTableName = "wcm_GovInteractRemark"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = "ss_govinteract_remark"; + + private static readonly List NewColumns = new List + { + new TableColumn + { + AttributeName = "Id", + DataType = DataType.Integer, + IsPrimaryKey = true, + IsIdentity = true + }, + new TableColumn + { + AttributeName = "SiteId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "ChannelId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "ContentId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "RemarkType", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "Remark", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "DepartmentId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "UserName", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "AddDate", + DataType = DataType.DateTime + } + }; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {"Id", nameof(RemarkId)}, + {"SiteId", nameof(PublishmentSystemId)}, + {"ChannelId", nameof(NodeId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractReply.cs b/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractReply.cs new file mode 100644 index 000000000..0bac5dffe --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractReply.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; + +namespace SiteServer.Cli.Updater.Tables.GovInteract +{ + public partial class TableGovInteractReply + { + [JsonProperty("replyID")] + public long ReplyId { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("nodeID")] + public long NodeId { get; set; } + + [JsonProperty("contentID")] + public object ContentId { get; set; } + + [JsonProperty("reply")] + public string Reply { get; set; } + + [JsonProperty("fileUrl")] + public string FileUrl { get; set; } + + [JsonProperty("departmentID")] + public long DepartmentId { get; set; } + + [JsonProperty("userName")] + public string UserName { get; set; } + + [JsonProperty("addDate")] + public DateTimeOffset AddDate { get; set; } + } + + public partial class TableGovInteractReply + { + public const string OldTableName = "wcm_GovInteractReply"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = "ss_govinteract_reply"; + + private static readonly List NewColumns = new List + { + new TableColumn + { + AttributeName = "Id", + DataType = DataType.Integer, + IsPrimaryKey = true, + IsIdentity = true + }, + new TableColumn + { + AttributeName = "SiteId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "ChannelId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "ContentId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "Reply", + DataType = DataType.Text + }, + new TableColumn + { + AttributeName = "FileUrl", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "DepartmentId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "UserName", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "AddDate", + DataType = DataType.DateTime + } + }; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {"Id", nameof(ReplyId)}, + {"SiteId", nameof(PublishmentSystemId)}, + {"ChannelId", nameof(NodeId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractType.cs b/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractType.cs new file mode 100644 index 000000000..0310004f2 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/GovInteract/TableGovInteractType.cs @@ -0,0 +1,80 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; + +namespace SiteServer.Cli.Updater.Tables.GovInteract +{ + public partial class TableGovInteractType + { + [JsonProperty("typeID")] + public long TypeId { get; set; } + + [JsonProperty("typeName")] + public string TypeName { get; set; } + + [JsonProperty("nodeID")] + public long NodeId { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("taxis")] + public long Taxis { get; set; } + } + + public partial class TableGovInteractType + { + public const string OldTableName = "wcm_GovInteractType"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = "ss_govinteract_type"; + + private static readonly List NewColumns = new List + { + new TableColumn + { + AttributeName = "Id", + DataType = DataType.Integer, + IsPrimaryKey = true, + IsIdentity = true + }, + new TableColumn + { + AttributeName = "TypeName", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "ChannelId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "SiteId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "Taxis", + DataType = DataType.Integer + } + }; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {"Id", nameof(TypeId)}, + {"ChannelId", nameof(NodeId)}, + {"SiteId", nameof(PublishmentSystemId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/GovPublic/TableGovPublicCategory.cs b/net452/SiteServer.Cli/Updater/Tables/GovPublic/TableGovPublicCategory.cs new file mode 100644 index 000000000..f23657e92 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/GovPublic/TableGovPublicCategory.cs @@ -0,0 +1,152 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; + +namespace SiteServer.Cli.Updater.Tables.GovPublic +{ + public partial class TableGovPublicCategory + { + [JsonProperty("categoryID")] + public long CategoryId { get; set; } + + [JsonProperty("classCode")] + public string ClassCode { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("categoryName")] + public string CategoryName { get; set; } + + [JsonProperty("categoryCode")] + public string CategoryCode { get; set; } + + [JsonProperty("parentID")] + public long ParentId { get; set; } + + [JsonProperty("parentsPath")] + public string ParentsPath { get; set; } + + [JsonProperty("parentsCount")] + public long ParentsCount { get; set; } + + [JsonProperty("childrenCount")] + public long ChildrenCount { get; set; } + + [JsonProperty("isLastNode")] + public string IsLastNode { get; set; } + + [JsonProperty("taxis")] + public long Taxis { get; set; } + + [JsonProperty("addDate")] + public DateTimeOffset AddDate { get; set; } + + [JsonProperty("summary")] + public string Summary { get; set; } + + [JsonProperty("contentNum")] + public long ContentNum { get; set; } + } + + public partial class TableGovPublicCategory + { + public const string OldTableName = "wcm_GovPublicCategory"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = "ss_govpublic_category"; + + private static readonly List NewColumns = new List + { + new TableColumn + { + AttributeName = "Id", + DataType = DataType.Integer, + IsPrimaryKey = true, + IsIdentity = true + }, + new TableColumn + { + AttributeName = "SiteId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "ClassCode", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "CategoryName", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "CategoryCode", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "ParentId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "ParentsPath", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "ParentsCount", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "ChildrenCount", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "IsLastNode", + DataType = DataType.Boolean + }, + new TableColumn + { + AttributeName = "Taxis", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "AddDate", + DataType = DataType.DateTime + }, + new TableColumn + { + AttributeName = "Summary", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "ContentNum", + DataType = DataType.Integer + } + }; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {"Id", nameof(CategoryId)}, + {"SiteId", nameof(PublishmentSystemId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/GovPublic/TableGovPublicCategoryClass.cs b/net452/SiteServer.Cli/Updater/Tables/GovPublic/TableGovPublicCategoryClass.cs new file mode 100644 index 000000000..217ec8eb5 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/GovPublic/TableGovPublicCategoryClass.cs @@ -0,0 +1,110 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; + +namespace SiteServer.Cli.Updater.Tables.GovPublic +{ + public partial class TableGovPublicCategoryClass + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("classCode")] + public string ClassCode { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("className")] + public string ClassName { get; set; } + + [JsonProperty("isSystem")] + public string IsSystem { get; set; } + + [JsonProperty("isEnabled")] + public string IsEnabled { get; set; } + + [JsonProperty("contentAttributeName")] + public string ContentAttributeName { get; set; } + + [JsonProperty("taxis")] + public long Taxis { get; set; } + + [JsonProperty("description")] + public string Description { get; set; } + } + + public partial class TableGovPublicCategoryClass + { + public const string OldTableName = "wcm_GovPublicCategoryClass"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = "ss_govpublic_category_class"; + + private static readonly List NewColumns = new List + { + new TableColumn + { + AttributeName = "Id", + DataType = DataType.Integer, + IsPrimaryKey = true, + IsIdentity = true + }, + new TableColumn + { + AttributeName = "SiteId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "ClassCode", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "ClassName", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "IsSystem", + DataType = DataType.Boolean + }, + new TableColumn + { + AttributeName = "IsEnabled", + DataType = DataType.Boolean + }, + new TableColumn + { + AttributeName = "ContentAttributeName", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "Taxis", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "Description", + DataType = DataType.VarChar + } + }; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {"SiteId", nameof(PublishmentSystemId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/GovPublic/TableGovPublicContent.cs b/net452/SiteServer.Cli/Updater/Tables/GovPublic/TableGovPublicContent.cs new file mode 100644 index 000000000..0e2fb114b --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/GovPublic/TableGovPublicContent.cs @@ -0,0 +1,352 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.Cli.Updater.Tables.GovPublic +{ + public partial class TableGovPublicContent + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("nodeID")] + public long NodeId { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("addUserName")] + public string AddUserName { get; set; } + + [JsonProperty("lastEditUserName")] + public string LastEditUserName { get; set; } + + [JsonProperty("lastEditDate")] + public DateTime LastEditDate { get; set; } + + [JsonProperty("taxis")] + public long Taxis { get; set; } + + [JsonProperty("contentGroupNameCollection")] + public string ContentGroupNameCollection { get; set; } + + [JsonProperty("tags")] + public string Tags { get; set; } + + [JsonProperty("sourceID")] + public long SourceId { get; set; } + + [JsonProperty("referenceID")] + public long ReferenceId { get; set; } + + [JsonProperty("isChecked")] + public string IsChecked { get; set; } + + [JsonProperty("checkedLevel")] + public long CheckedLevel { get; set; } + + [JsonProperty("comments")] + public long Comments { get; set; } + + [JsonProperty("hits")] + public long Hits { get; set; } + + [JsonProperty("hitsByDay")] + public long HitsByDay { get; set; } + + [JsonProperty("hitsByWeek")] + public long HitsByWeek { get; set; } + + [JsonProperty("hitsByMonth")] + public long HitsByMonth { get; set; } + + [JsonProperty("lastHitsDate")] + public DateTime LastHitsDate { get; set; } + + [JsonProperty("settingsXML")] + public string SettingsXml { get; set; } + + [JsonProperty("departmentID")] + public long DepartmentId { get; set; } + + [JsonProperty("category1ID")] + public long Category1Id { get; set; } + + [JsonProperty("category2ID")] + public long Category2Id { get; set; } + + [JsonProperty("category3ID")] + public long Category3Id { get; set; } + + [JsonProperty("category4ID")] + public long Category4Id { get; set; } + + [JsonProperty("category5ID")] + public long Category5Id { get; set; } + + [JsonProperty("category6ID")] + public long Category6Id { get; set; } + + [JsonProperty("title")] + public string Title { get; set; } + + [JsonProperty("identifier")] + public string Identifier { get; set; } + + [JsonProperty("description")] + public string Description { get; set; } + + [JsonProperty("publishDate")] + public DateTime PublishDate { get; set; } + + [JsonProperty("effectDate")] + public DateTime EffectDate { get; set; } + + [JsonProperty("isAbolition")] + public string IsAbolition { get; set; } + + [JsonProperty("abolitionDate")] + public DateTime AbolitionDate { get; set; } + + [JsonProperty("documentNo")] + public string DocumentNo { get; set; } + + [JsonProperty("publisher")] + public string Publisher { get; set; } + + [JsonProperty("keywords")] + public string Keywords { get; set; } + + [JsonProperty("fileUrl")] + public string FileUrl { get; set; } + + [JsonProperty("isRecommend")] + public string IsRecommend { get; set; } + + [JsonProperty("isTop")] + public string IsTop { get; set; } + + [JsonProperty("content")] + public string Content { get; set; } + + [JsonProperty("addDate")] + public DateTime AddDate { get; set; } + } + + public partial class TableGovPublicContent + { + public static readonly string NewTableName = "ss_govpublic_content"; + + private static List NewColumns => new List + { + new TableColumn + { + AttributeName = "Identifier", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Customize, + // DisplayName = "索引号" + //} + }, + new TableColumn + { + AttributeName = "DocumentNo", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Text, + // DisplayName = "文号", + // IsRequired = true + //} + }, + new TableColumn + { + AttributeName = "DepartmentId", + DataType = DataType.Integer, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Hidden, + // DisplayName = "部门", + //} + }, + new TableColumn + { + AttributeName = "Publisher", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Text, + // DisplayName = "发布机构" + //} + }, + new TableColumn + { + AttributeName = "Keywords", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Text, + // DisplayName = "关键词" + //} + }, + new TableColumn + { + AttributeName = "PublishDate", + DataType = DataType.DateTime, + //InputStyle = new InputStyle + //{ + // InputType = InputType.DateTime, + // DisplayName = "发文日期", + // IsRequired = true, + // DefaultValue = "{Current}" + //} + }, + new TableColumn + { + AttributeName = "EffectDate", + DataType = DataType.DateTime, + //InputStyle = new InputStyle + //{ + // InputType = InputType.DateTime, + // DisplayName = "生效日期", + // IsRequired = true, + // DefaultValue = "{Current}" + //} + }, + new TableColumn + { + AttributeName = "IsAbolition", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Radio, + // DisplayName = "是否废止", + // IsRequired = true, + // ListItems = new List + // { + // new InputListItem + // { + // Text = "是", + // Value = true.ToString(), + // Selected = false + // }, + // new InputListItem + // { + // Text = "否", + // Value = false.ToString(), + // Selected = true + // }, + // } + //} + }, + new TableColumn + { + AttributeName = "AbolitionDate", + DataType = DataType.DateTime, + //InputStyle = new InputStyle + //{ + // InputType = InputType.DateTime, + // DisplayName = "废止日期", + // IsRequired = true, + // DefaultValue = "{Current}" + //} + }, + new TableColumn + { + AttributeName = "Description", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.TextArea, + // DisplayName = "内容概述" + //} + }, + new TableColumn + { + AttributeName = "ImageUrl", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Image, + // DisplayName = "图片" + //} + }, + new TableColumn + { + AttributeName = "FileUrl", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.File, + // DisplayName = "附件", + //} + }, + new TableColumn + { + AttributeName = "Content", + DataType = DataType.Text, + //InputStyle = new InputStyle + //{ + // InputType = InputType.TextEditor, + // DisplayName = "内容" + //} + } + }; + + private static List GetNewColumns(List oldColumns) + { + var columns = new List(); + columns.AddRange(DataProvider.ContentRepository.TableColumns); + columns.AddRange(NewColumns); + + foreach (var tableColumnInfo in oldColumns) + { + if (StringUtils.EqualsIgnoreCase(tableColumnInfo.AttributeName, nameof(NodeId))) + { + tableColumnInfo.AttributeName = nameof(ContentInfo.ChannelId); + } + else if (StringUtils.EqualsIgnoreCase(tableColumnInfo.AttributeName, nameof(PublishmentSystemId))) + { + tableColumnInfo.AttributeName = nameof(ContentInfo.SiteId); + } + else if (StringUtils.EqualsIgnoreCase(tableColumnInfo.AttributeName, nameof(ContentGroupNameCollection))) + { + tableColumnInfo.AttributeName = nameof(ContentInfo.GroupNameCollection); + } + + if (!columns.Exists(c => StringUtils.EqualsIgnoreCase(c.AttributeName, tableColumnInfo.AttributeName))) + { + columns.Add(tableColumnInfo); + } + } + + return columns; + } + + public static ConvertInfo GetConverter(List oldColumns) + { + return new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = GetNewColumns(oldColumns), + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + } + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(ContentInfo.ChannelId), nameof(NodeId)}, + {nameof(ContentInfo.SiteId), nameof(PublishmentSystemId)}, + {nameof(ContentInfo.GroupNameCollection), nameof(ContentGroupNameCollection)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/GovPublic/TableGovPublicIdentifierRule.cs b/net452/SiteServer.Cli/Updater/Tables/GovPublic/TableGovPublicIdentifierRule.cs new file mode 100644 index 000000000..a7f2b69e8 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/GovPublic/TableGovPublicIdentifierRule.cs @@ -0,0 +1,137 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; + +namespace SiteServer.Cli.Updater.Tables.GovPublic +{ + public partial class TableGovPublicIdentifierRule + { + [JsonProperty("ruleID")] + public long RuleId { get; set; } + + [JsonProperty("ruleName")] + public string RuleName { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("identifierType")] + public string IdentifierType { get; set; } + + [JsonProperty("minLength")] + public long MinLength { get; set; } + + [JsonProperty("suffix")] + public string Suffix { get; set; } + + [JsonProperty("formatString")] + public string FormatString { get; set; } + + [JsonProperty("attributeName")] + public string AttributeName { get; set; } + + [JsonProperty("sequence")] + public long Sequence { get; set; } + + [JsonProperty("taxis")] + public long Taxis { get; set; } + + [JsonProperty("settingsXML")] + public string SettingsXml { get; set; } + } + + public partial class TableGovPublicIdentifierRule + { + public const string OldTableName = "wcm_GovPublicIdentifierRule"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = "ss_govpublic_identifier_rule"; + + private static readonly List NewColumns = new List + { + new TableColumn + { + AttributeName = "Id", + DataType = DataType.Integer, + IsPrimaryKey = true, + IsIdentity = true + }, + new TableColumn + { + AttributeName = "SiteId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "RuleName", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "IdentifierType", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "MinLength", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "Suffix", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "FormatString", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "AttributeName", + DataType = DataType.VarChar + }, + new TableColumn + { + AttributeName = "Sequence", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "Taxis", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "IsSequenceChannelZero", + DataType = DataType.Boolean + }, + new TableColumn + { + AttributeName = "IsSequenceDepartmentZero", + DataType = DataType.Boolean + }, + new TableColumn + { + AttributeName = "IsSequenceYearZero", + DataType = DataType.Boolean + } + }; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {"Id", nameof(RuleId)}, + {"SiteId", nameof(PublishmentSystemId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/GovPublic/TableGovPublicIdentifierSeq.cs b/net452/SiteServer.Cli/Updater/Tables/GovPublic/TableGovPublicIdentifierSeq.cs new file mode 100644 index 000000000..16943f686 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/GovPublic/TableGovPublicIdentifierSeq.cs @@ -0,0 +1,88 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; + +namespace SiteServer.Cli.Updater.Tables.GovPublic +{ + public partial class TableGovPublicIdentifierSeq + { + [JsonProperty("seqID")] + public long SeqId { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("nodeID")] + public long NodeId { get; set; } + + [JsonProperty("departmentID")] + public long DepartmentId { get; set; } + + [JsonProperty("addYear")] + public long AddYear { get; set; } + + [JsonProperty("sequence")] + public long Sequence { get; set; } + } + + public partial class TableGovPublicIdentifierSeq + { + public const string OldTableName = "wcm_GovPublicIdentifierSeq"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = "ss_govpublic_identifier_seq"; + + private static readonly List NewColumns = new List + { + new TableColumn + { + AttributeName = "Id", + DataType = DataType.Integer, + IsPrimaryKey = true, + IsIdentity = true + }, + new TableColumn + { + AttributeName = "SiteId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "ChannelId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "DepartmentId", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "AddYear", + DataType = DataType.Integer + }, + new TableColumn + { + AttributeName = "Sequence", + DataType = DataType.Integer + } + }; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {"Id", nameof(SeqId)}, + {"SiteId", nameof(PublishmentSystemId)}, + {"ChannelId", nameof(NodeId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/Jobs/TableJobsContent.cs b/net452/SiteServer.Cli/Updater/Tables/Jobs/TableJobsContent.cs new file mode 100644 index 000000000..c8a2aa867 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/Jobs/TableJobsContent.cs @@ -0,0 +1,234 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.Cli.Updater.Tables.Jobs +{ + public partial class TableJobsContent + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("nodeID")] + public long NodeId { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("addUserName")] + public string AddUserName { get; set; } + + [JsonProperty("lastEditUserName")] + public string LastEditUserName { get; set; } + + [JsonProperty("lastEditDate")] + public DateTimeOffset LastEditDate { get; set; } + + [JsonProperty("taxis")] + public long Taxis { get; set; } + + [JsonProperty("contentGroupNameCollection")] + public string ContentGroupNameCollection { get; set; } + + [JsonProperty("tags")] + public string Tags { get; set; } + + [JsonProperty("sourceID")] + public long SourceId { get; set; } + + [JsonProperty("referenceID")] + public long ReferenceId { get; set; } + + [JsonProperty("isChecked")] + public string IsChecked { get; set; } + + [JsonProperty("checkedLevel")] + public long CheckedLevel { get; set; } + + [JsonProperty("comments")] + public long Comments { get; set; } + + [JsonProperty("hits")] + public long Hits { get; set; } + + [JsonProperty("hitsByDay")] + public long HitsByDay { get; set; } + + [JsonProperty("hitsByWeek")] + public long HitsByWeek { get; set; } + + [JsonProperty("hitsByMonth")] + public long HitsByMonth { get; set; } + + [JsonProperty("lastHitsDate")] + public DateTimeOffset LastHitsDate { get; set; } + + [JsonProperty("settingsXML")] + public string SettingsXml { get; set; } + + [JsonProperty("title")] + public string Title { get; set; } + + [JsonProperty("subTitle")] + public string SubTitle { get; set; } + + [JsonProperty("imageUrl")] + public string ImageUrl { get; set; } + + [JsonProperty("videoUrl")] + public string VideoUrl { get; set; } + + [JsonProperty("fileUrl")] + public string FileUrl { get; set; } + + [JsonProperty("linkUrl")] + public string LinkUrl { get; set; } + + [JsonProperty("content")] + public string Content { get; set; } + + [JsonProperty("summary")] + public string Summary { get; set; } + + [JsonProperty("author")] + public string Author { get; set; } + + [JsonProperty("source")] + public string Source { get; set; } + + [JsonProperty("isRecommend")] + public string IsRecommend { get; set; } + + [JsonProperty("isHot")] + public string IsHot { get; set; } + + [JsonProperty("isColor")] + public string IsColor { get; set; } + + [JsonProperty("isTop")] + public string IsTop { get; set; } + + [JsonProperty("addDate")] + public DateTimeOffset AddDate { get; set; } + } + + public partial class TableJobsContent + { + public static readonly string NewTableName = "ss_jobs"; + + private static List NewColumns => new List + { + new TableColumn + { + AttributeName = "Department", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Text, + // DisplayName = "所属部门", + // IsRequired = true + //} + }, + new TableColumn + { + AttributeName = "Location", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Text, + // DisplayName = "工作地点", + // IsRequired = true + //} + }, + new TableColumn + { + AttributeName = "NumberOfPeople", + DataType = DataType.VarChar, + //InputStyle = new InputStyle + //{ + // InputType = InputType.Text, + // DisplayName = "招聘人数", + // IsRequired = true, + // DefaultValue = "不限" + //} + }, + new TableColumn + { + AttributeName = "Responsibility", + DataType = DataType.Text, + //InputStyle = new InputStyle + //{ + // InputType = InputType.TextEditor, + // DisplayName = "工作职责", + // IsRequired = true + //} + }, + new TableColumn + { + AttributeName = "Requirement", + DataType = DataType.Text, + //InputStyle = new InputStyle + //{ + // InputType = InputType.TextEditor, + // DisplayName = "工作要求", + // IsRequired = true + //} + } + }; + + private static List GetNewColumns(List oldColumns) + { + var columns = new List(); + columns.AddRange(DataProvider.ContentRepository.TableColumns); + columns.AddRange(NewColumns); + + foreach (var tableColumnInfo in oldColumns) + { + if (StringUtils.EqualsIgnoreCase(tableColumnInfo.AttributeName, nameof(NodeId))) + { + tableColumnInfo.AttributeName = nameof(ContentInfo.ChannelId); + } + else if (StringUtils.EqualsIgnoreCase(tableColumnInfo.AttributeName, nameof(PublishmentSystemId))) + { + tableColumnInfo.AttributeName = nameof(ContentInfo.SiteId); + } + else if (StringUtils.EqualsIgnoreCase(tableColumnInfo.AttributeName, nameof(ContentGroupNameCollection))) + { + tableColumnInfo.AttributeName = nameof(ContentInfo.GroupNameCollection); + } + + if (!columns.Exists(c => StringUtils.EqualsIgnoreCase(c.AttributeName, tableColumnInfo.AttributeName))) + { + columns.Add(tableColumnInfo); + } + } + + return columns; + } + + public static ConvertInfo GetConverter(List oldColumns) + { + return new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = GetNewColumns(oldColumns), + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + } + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(ContentInfo.ChannelId), nameof(NodeId)}, + {nameof(ContentInfo.SiteId), nameof(PublishmentSystemId)}, + {nameof(ContentInfo.GroupNameCollection), nameof(ContentGroupNameCollection)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} \ No newline at end of file diff --git a/net452/SiteServer.Cli/Updater/Tables/TableAdministrator.cs b/net452/SiteServer.Cli/Updater/Tables/TableAdministrator.cs new file mode 100644 index 000000000..59327d9a4 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableAdministrator.cs @@ -0,0 +1,103 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableAdministrator + { + [JsonProperty("id")] + public int Id { get; set; } + + [JsonProperty("userName")] + public string UserName { get; set; } + + [JsonProperty("password")] + public string Password { get; set; } + + [JsonProperty("passwordFormat")] + public string PasswordFormat { get; set; } + + [JsonProperty("passwordSalt")] + public string PasswordSalt { get; set; } + + [JsonProperty("creationDate")] + public DateTime CreationDate { get; set; } + + [JsonProperty("lastActivityDate")] + public DateTime LastActivityDate { get; set; } + + [JsonProperty("lastModuleID")] + public string LastModuleId { get; set; } + + [JsonProperty("countOfLogin")] + public int CountOfLogin { get; set; } + + [JsonProperty("creatorUserName")] + public string CreatorUserName { get; set; } + + [JsonProperty("isChecked")] + public string IsChecked { get; set; } + + [JsonProperty("isLockedOut")] + public string IsLockedOut { get; set; } + + [JsonProperty("publishmentSystemID")] + public int PublishmentSystemId { get; set; } + + [JsonProperty("departmentID")] + public int DepartmentId { get; set; } + + [JsonProperty("areaID")] + public int AreaId { get; set; } + + [JsonProperty("displayName")] + public string DisplayName { get; set; } + + [JsonProperty("question")] + public string Question { get; set; } + + [JsonProperty("answer")] + public string Answer { get; set; } + + [JsonProperty("email")] + public string Email { get; set; } + + [JsonProperty("mobile")] + public string Mobile { get; set; } + + [JsonProperty("theme")] + public string Theme { get; set; } + + [JsonProperty("language")] + public string Language { get; set; } + } + + public partial class TableAdministrator + { + public const string OldTableName = "bairong_Administrator"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.Administrator.TableName; + + private static readonly List NewColumns = DataProvider.Administrator.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(AdministratorInfo.SiteId), nameof(PublishmentSystemId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableAdministratorsInRoles.cs b/net452/SiteServer.Cli/Updater/Tables/TableAdministratorsInRoles.cs new file mode 100644 index 000000000..c14b7ac03 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableAdministratorsInRoles.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableAdministratorsInRoles + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("roleName")] + public string RoleName { get; set; } + + [JsonProperty("userName")] + public string UserName { get; set; } + } + + public partial class TableAdministratorsInRoles + { + public const string OldTableName = "bairong_AdministratorsInRoles"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.AdministratorsInRoles.TableName; + + private static readonly List NewColumns = DataProvider.AdministratorsInRoles.TableColumns; + + private static readonly Dictionary ConvertKeyDict = null; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableArea.cs b/net452/SiteServer.Cli/Updater/Tables/TableArea.cs new file mode 100644 index 000000000..c50578569 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableArea.cs @@ -0,0 +1,66 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableArea + { + [JsonProperty("areaID")] + public long AreaId { get; set; } + + [JsonProperty("areaName")] + public string AreaName { get; set; } + + [JsonProperty("parentID")] + public long ParentId { get; set; } + + [JsonProperty("parentsPath")] + public string ParentsPath { get; set; } + + [JsonProperty("parentsCount")] + public long ParentsCount { get; set; } + + [JsonProperty("childrenCount")] + public long ChildrenCount { get; set; } + + [JsonProperty("isLastNode")] + public string IsLastNode { get; set; } + + [JsonProperty("taxis")] + public long Taxis { get; set; } + + [JsonProperty("countOfAdmin")] + public long CountOfAdmin { get; set; } + + [JsonProperty("countOfUser")] + public long CountOfUser { get; set; } + } + + public partial class TableArea + { + public const string OldTableName = "bairong_Area"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.Area.TableName; + + private static readonly List NewColumns = DataProvider.Area.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(AreaInfo.Id), nameof(AreaId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableChannel.cs b/net452/SiteServer.Cli/Updater/Tables/TableChannel.cs new file mode 100644 index 000000000..ad9efedc1 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableChannel.cs @@ -0,0 +1,135 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableChannel + { + [JsonProperty("nodeID")] + public long NodeId { get; set; } + + [JsonProperty("nodeName")] + public string NodeName { get; set; } + + [JsonProperty("nodeType")] + public string NodeType { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("contentModelID")] + public string ContentModelId { get; set; } + + [JsonProperty("parentID")] + public long ParentId { get; set; } + + [JsonProperty("parentsPath")] + public string ParentsPath { get; set; } + + [JsonProperty("parentsCount")] + public long ParentsCount { get; set; } + + [JsonProperty("childrenCount")] + public long ChildrenCount { get; set; } + + [JsonProperty("isLastNode")] + public string IsLastNode { get; set; } + + [JsonProperty("nodeIndexName")] + public string NodeIndexName { get; set; } + + [JsonProperty("nodeGroupNameCollection")] + public string NodeGroupNameCollection { get; set; } + + [JsonProperty("taxis")] + public long Taxis { get; set; } + + [JsonProperty("addDate")] + public DateTimeOffset AddDate { get; set; } + + [JsonProperty("imageUrl")] + public string ImageUrl { get; set; } + + [JsonProperty("content")] + public string Content { get; set; } + + [JsonProperty("contentNum")] + public long ContentNum { get; set; } + + [JsonProperty("commentNum")] + public long CommentNum { get; set; } + + [JsonProperty("filePath")] + public string FilePath { get; set; } + + [JsonProperty("channelFilePathRule")] + public string ChannelFilePathRule { get; set; } + + [JsonProperty("contentFilePathRule")] + public string ContentFilePathRule { get; set; } + + [JsonProperty("linkUrl")] + public string LinkUrl { get; set; } + + [JsonProperty("linkType")] + public string LinkType { get; set; } + + [JsonProperty("channelTemplateID")] + public long ChannelTemplateId { get; set; } + + [JsonProperty("contentTemplateID")] + public long ContentTemplateId { get; set; } + + [JsonProperty("keywords")] + public string Keywords { get; set; } + + [JsonProperty("description")] + public string Description { get; set; } + + [JsonProperty("extendValues")] + public string ExtendValues { get; set; } + } + + public partial class TableChannel + { + public static readonly List OldTableNames = new List + { + "siteserver_Node", + "wcm_Node" + }; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.Channel.TableName; + + private static readonly List NewColumns = DataProvider.Channel.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(ChannelInfo.Id), nameof(NodeId)}, + {nameof(ChannelInfo.ChannelName), nameof(NodeName)}, + {nameof(ChannelInfo.SiteId), nameof(PublishmentSystemId)}, + {nameof(ChannelInfo.IndexName), nameof(NodeIndexName)}, + {nameof(ChannelInfo.GroupNameCollection), nameof(NodeGroupNameCollection)}, + {nameof(ChannelInfo.ContentModelPluginId), nameof(ContentModelId)} + }; + + private static readonly Dictionary ConvertValueDict = new Dictionary + { + {UpdateUtils.GetConvertValueDictKey(nameof(ChannelInfo.ContentModelPluginId), "GovInteract"), "SS.GovInteract"}, + {UpdateUtils.GetConvertValueDictKey(nameof(ChannelInfo.ContentModelPluginId), "GovPublic"), "SS.GovPublic"}, + {UpdateUtils.GetConvertValueDictKey(nameof(ChannelInfo.ContentModelPluginId), "Job"), "SS.Jobs"}, + }; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableChannelGroup.cs b/net452/SiteServer.Cli/Updater/Tables/TableChannelGroup.cs new file mode 100644 index 000000000..965b07a16 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableChannelGroup.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableChannelGroup + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("nodeGroupName")] + public string NodeGroupName { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("taxis")] + public long Taxis { get; set; } + + [JsonProperty("description")] + public string Description { get; set; } + } + + public partial class TableChannelGroup + { + public static readonly List OldTableNames = new List + { + "siteserver_NodeGroup", + "wcm_NodeGroup" + }; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.ChannelGroup.TableName; + + private static readonly List NewColumns = DataProvider.ChannelGroup.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(ChannelGroupInfo.GroupName), nameof(NodeGroupName)}, + {nameof(ChannelGroupInfo.SiteId), nameof(PublishmentSystemId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableConfig.cs b/net452/SiteServer.Cli/Updater/Tables/TableConfig.cs new file mode 100644 index 000000000..f2da8e954 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableConfig.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableConfig + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("isInitialized")] + public string IsInitialized { get; set; } + + [JsonProperty("databaseVersion")] + public string DatabaseVersion { get; set; } + + [JsonProperty("restrictionBlackList")] + public string RestrictionBlackList { get; set; } + + [JsonProperty("restrictionWhiteList")] + public string RestrictionWhiteList { get; set; } + + [JsonProperty("isRelatedUrl")] + public string IsRelatedUrl { get; set; } + + [JsonProperty("rootUrl")] + public string RootUrl { get; set; } + + [JsonProperty("updateDate")] + public DateTimeOffset UpdateDate { get; set; } + + [JsonProperty("settingsXML")] + public string SettingsXml { get; set; } + } + + public partial class TableConfig + { + public const string OldTableName = "bairong_Config"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.Config.TableName; + + private static readonly List NewColumns = DataProvider.Config.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {"SystemConfig", nameof(SettingsXml)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableContentCheck.cs b/net452/SiteServer.Cli/Updater/Tables/TableContentCheck.cs new file mode 100644 index 000000000..f266263b3 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableContentCheck.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableContentCheck + { + [JsonProperty("checkID")] + public long CheckId { get; set; } + + [JsonProperty("tableName")] + public string TableName { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("nodeID")] + public long NodeId { get; set; } + + [JsonProperty("contentID")] + public long ContentId { get; set; } + + [JsonProperty("isAdmin")] + public string IsAdmin { get; set; } + + [JsonProperty("userName")] + public string UserName { get; set; } + + [JsonProperty("isChecked")] + public string IsChecked { get; set; } + + [JsonProperty("checkedLevel")] + public long CheckedLevel { get; set; } + + [JsonProperty("checkDate")] + public DateTimeOffset CheckDate { get; set; } + + [JsonProperty("reasons")] + public string Reasons { get; set; } + } + + public partial class TableContentCheck + { + public const string OldTableName = "bairong_ContentCheck"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.ContentCheck.TableName; + + private static readonly List NewColumns = DataProvider.ContentCheck.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(ContentCheckInfo.Id), nameof(CheckId)}, + {nameof(ContentCheckInfo.SiteId), nameof(PublishmentSystemId)}, + {nameof(ContentCheckInfo.ChannelId), nameof(NodeId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableContentGroup.cs b/net452/SiteServer.Cli/Updater/Tables/TableContentGroup.cs new file mode 100644 index 000000000..635591a77 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableContentGroup.cs @@ -0,0 +1,56 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableContentGroup + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("contentGroupName")] + public string ContentGroupName { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("taxis")] + public long Taxis { get; set; } + + [JsonProperty("description")] + public string Description { get; set; } + } + + public partial class TableContentGroup + { + public static readonly List OldTableNames = new List + { + "siteserver_ContentGroup", + "wcm_ContentGroup" + }; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.ContentGroup.TableName; + + private static readonly List NewColumns = DataProvider.ContentGroup.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(ContentGroupInfo.GroupName), nameof(ContentGroupName)}, + {nameof(ContentGroupInfo.SiteId), nameof(PublishmentSystemId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableDbCache.cs b/net452/SiteServer.Cli/Updater/Tables/TableDbCache.cs new file mode 100644 index 000000000..83fb0ba31 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableDbCache.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableDbCache + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("cacheKey")] + public string CacheKey { get; set; } + + [JsonProperty("cacheValue")] + public string CacheValue { get; set; } + } + + public partial class TableDbCache + { + public const string OldTableName = "bairong_Cache"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.DbCache.TableName; + + private static readonly List NewColumns = DataProvider.DbCache.TableColumns; + + private static readonly Dictionary ConvertKeyDict = null; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableDepartment.cs b/net452/SiteServer.Cli/Updater/Tables/TableDepartment.cs new file mode 100644 index 000000000..f4626440f --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableDepartment.cs @@ -0,0 +1,76 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableDepartment + { + [JsonProperty("departmentID")] + public long DepartmentId { get; set; } + + [JsonProperty("departmentName")] + public string DepartmentName { get; set; } + + [JsonProperty("code")] + public string Code { get; set; } + + [JsonProperty("parentID")] + public long ParentId { get; set; } + + [JsonProperty("parentsPath")] + public string ParentsPath { get; set; } + + [JsonProperty("parentsCount")] + public long ParentsCount { get; set; } + + [JsonProperty("childrenCount")] + public long ChildrenCount { get; set; } + + [JsonProperty("isLastNode")] + public string IsLastNode { get; set; } + + [JsonProperty("taxis")] + public long Taxis { get; set; } + + [JsonProperty("addDate")] + public DateTimeOffset AddDate { get; set; } + + [JsonProperty("summary")] + public string Summary { get; set; } + + [JsonProperty("countOfAdmin")] + public long CountOfAdmin { get; set; } + + [JsonProperty("countOfUser")] + public long CountOfUser { get; set; } + } + + public partial class TableDepartment + { + public const string OldTableName = "bairong_Department"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.Department.TableName; + + private static readonly List NewColumns = DataProvider.Department.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(DepartmentInfo.Id), nameof(DepartmentId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableErrorLog.cs b/net452/SiteServer.Cli/Updater/Tables/TableErrorLog.cs new file mode 100644 index 000000000..a74409982 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableErrorLog.cs @@ -0,0 +1,12 @@ +namespace SiteServer.Cli.Updater.Tables +{ + public static class TableErrorLog + { + public const string OldTableName = "bairong_ErrorLog"; + + public static ConvertInfo Converter => new ConvertInfo + { + IsAbandon = true + }; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableKeyword.cs b/net452/SiteServer.Cli/Updater/Tables/TableKeyword.cs new file mode 100644 index 000000000..5b270cf4f --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableKeyword.cs @@ -0,0 +1,53 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableKeyword + { + [JsonProperty("keywordID")] + public long KeywordId { get; set; } + + [JsonProperty("keyword")] + public string Keyword { get; set; } + + [JsonProperty("alternative")] + public string Alternative { get; set; } + + [JsonProperty("grade")] + public string Grade { get; set; } + } + + public partial class TableKeyword + { + public static readonly List OldTableNames = new List + { + "siteserver_Keyword", + "wcm_Keyword" + }; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.Keyword.TableName; + + private static readonly List NewColumns = DataProvider.Keyword.TableColumns; + + private static readonly Dictionary ConvertKeyDict + = + new Dictionary + { + {nameof(KeywordInfo.Id), nameof(KeywordId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableLog.cs b/net452/SiteServer.Cli/Updater/Tables/TableLog.cs new file mode 100644 index 000000000..134fdbea5 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableLog.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableLog + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("userName")] + public string UserName { get; set; } + + [JsonProperty("ipAddress")] + public string IpAddress { get; set; } + + [JsonProperty("addDate")] + public DateTimeOffset AddDate { get; set; } + + [JsonProperty("action")] + public string Action { get; set; } + + [JsonProperty("summary")] + public string Summary { get; set; } + } + + public partial class TableLog + { + public const string OldTableName = "bairong_Log"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.Log.TableName; + + private static readonly List NewColumns = DataProvider.Log.TableColumns; + + private static readonly Dictionary ConvertKeyDict = null; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TablePermissionsInRoles.cs b/net452/SiteServer.Cli/Updater/Tables/TablePermissionsInRoles.cs new file mode 100644 index 000000000..4b421f893 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TablePermissionsInRoles.cs @@ -0,0 +1,40 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TablePermissionsInRoles + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("roleName")] + public string RoleName { get; set; } + + [JsonProperty("generalPermissions")] + public string GeneralPermissions { get; set; } + } + + public partial class TablePermissionsInRoles + { + public const string OldTableName = "bairong_PermissionsInRoles"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.PermissionsInRoles.TableName; + + private static readonly List NewColumns = DataProvider.PermissionsInRoles.TableColumns; + + private static readonly Dictionary ConvertKeyDict = null; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableRelatedField.cs b/net452/SiteServer.Cli/Updater/Tables/TableRelatedField.cs new file mode 100644 index 000000000..6aa16fda6 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableRelatedField.cs @@ -0,0 +1,60 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableRelatedField + { + [JsonProperty("relatedFieldID")] + public long RelatedFieldId { get; set; } + + [JsonProperty("relatedFieldName")] + public string RelatedFieldName { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("totalLevel")] + public long TotalLevel { get; set; } + + [JsonProperty("prefixes")] + public string Prefixes { get; set; } + + [JsonProperty("suffixes")] + public string Suffixes { get; set; } + } + + public partial class TableRelatedField + { + public static readonly List OldTableNames = new List + { + "siteserver_RelatedField", + "wcm_RelatedField" + }; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.RelatedField.TableName; + + private static readonly List NewColumns = DataProvider.RelatedField.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(RelatedFieldInfo.Id), nameof(RelatedFieldId)}, + {nameof(RelatedFieldInfo.Title), nameof(RelatedFieldName)}, + {nameof(RelatedFieldInfo.SiteId), nameof(PublishmentSystemId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableRelatedFieldItem.cs b/net452/SiteServer.Cli/Updater/Tables/TableRelatedFieldItem.cs new file mode 100644 index 000000000..c5e30cea7 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableRelatedFieldItem.cs @@ -0,0 +1,53 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableRelatedFieldItem + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("relatedFieldID")] + public long RelatedFieldId { get; set; } + + [JsonProperty("itemName")] + public string ItemName { get; set; } + + [JsonProperty("itemValue")] + public string ItemValue { get; set; } + + [JsonProperty("parentID")] + public long ParentId { get; set; } + + [JsonProperty("taxis")] + public long Taxis { get; set; } + } + + public partial class TableRelatedFieldItem + { + public static readonly List OldTableNames = new List + { + "siteserver_RelatedFieldItem", + "wcm_RelatedFieldItem" + }; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.RelatedFieldItem.TableName; + + private static readonly List NewColumns = DataProvider.RelatedFieldItem.TableColumns; + + private static readonly Dictionary ConvertKeyDict = null; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableRole.cs b/net452/SiteServer.Cli/Updater/Tables/TableRole.cs new file mode 100644 index 000000000..013840f54 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableRole.cs @@ -0,0 +1,46 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableRole + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("roleName")] + public string RoleName { get; set; } + + [JsonProperty("modules")] + public string Modules { get; set; } + + [JsonProperty("creatorUserName")] + public string CreatorUserName { get; set; } + + [JsonProperty("description")] + public string Description { get; set; } + } + + public partial class TableRole + { + public const string OldTableName = "bairong_Roles"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.Role.TableName; + + private static readonly List NewColumns = DataProvider.Role.TableColumns; + + private static readonly Dictionary ConvertKeyDict = null; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableSite.cs b/net452/SiteServer.Cli/Updater/Tables/TableSite.cs new file mode 100644 index 000000000..6de989112 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableSite.cs @@ -0,0 +1,93 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableSite + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("publishmentSystemName")] + public string PublishmentSystemName { get; set; } + + [JsonProperty("auxiliaryTableForContent")] + public string AuxiliaryTableForContent { get; set; } + + [JsonProperty("auxiliaryTableForGovPublic")] + public string AuxiliaryTableForGovPublic { get; set; } + + [JsonProperty("auxiliaryTableForGovInteract")] + public string AuxiliaryTableForGovInteract { get; set; } + + [JsonProperty("auxiliaryTableForVote")] + public string AuxiliaryTableForVote { get; set; } + + [JsonProperty("auxiliaryTableForJob")] + public string AuxiliaryTableForJob { get; set; } + + [JsonProperty("isCheckContentUseLevel")] + public string IsCheckContentUseLevel { get; set; } + + [JsonProperty("checkContentLevel")] + public long CheckContentLevel { get; set; } + + [JsonProperty("publishmentSystemDir")] + public string PublishmentSystemDir { get; set; } + + [JsonProperty("publishmentSystemUrl")] + public string PublishmentSystemUrl { get; set; } + + [JsonProperty("isHeadquarters")] + public string IsHeadquarters { get; set; } + + [JsonProperty("parentPublishmentSystemID")] + public long ParentPublishmentSystemId { get; set; } + + [JsonProperty("taxis")] + public long Taxis { get; set; } + + [JsonProperty("settingsXML")] + public string SettingsXml { get; set; } + } + + public partial class TableSite + { + public static readonly List OldTableNames = new List + { + "siteserver_PublishmentSystem", + "wcm_PublishmentSystem" + }; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.Site.TableName; + + private static readonly List NewColumns = DataProvider.Site.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(SiteInfo.Id), nameof(PublishmentSystemId)}, + {nameof(SiteInfo.SiteName), nameof(PublishmentSystemName)}, + {nameof(SiteInfo.TableName), nameof(AuxiliaryTableForContent)}, + {nameof(SiteInfo.SiteDir), nameof(PublishmentSystemDir)}, + {nameof(SiteInfo.Root), nameof(IsHeadquarters)}, + {nameof(SiteInfo.ParentId), nameof(ParentPublishmentSystemId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableSiteLog.cs b/net452/SiteServer.Cli/Updater/Tables/TableSiteLog.cs new file mode 100644 index 000000000..fdc648037 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableSiteLog.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableSiteLog + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("channelID")] + public long ChannelId { get; set; } + + [JsonProperty("contentID")] + public long ContentId { get; set; } + + [JsonProperty("userName")] + public string UserName { get; set; } + + [JsonProperty("ipAddress")] + public string IpAddress { get; set; } + + [JsonProperty("addDate")] + public DateTimeOffset AddDate { get; set; } + + [JsonProperty("action")] + public string Action { get; set; } + + [JsonProperty("summary")] + public string Summary { get; set; } + } + + public partial class TableSiteLog + { + public static readonly List OldTableNames = new List + { + "siteserver_Log", + "wcm_Log" + }; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.SiteLog.TableName; + + private static readonly List NewColumns = DataProvider.SiteLog.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(SiteLogInfo.SiteId), nameof(PublishmentSystemId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableSitePermissions.cs b/net452/SiteServer.Cli/Updater/Tables/TableSitePermissions.cs new file mode 100644 index 000000000..1c3aa8c00 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableSitePermissions.cs @@ -0,0 +1,59 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableSitePermissions + { + [JsonProperty("roleName")] + public string RoleName { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("nodeIDCollection")] + public string NodeIdCollection { get; set; } + + [JsonProperty("channelPermissions")] + public string ChannelPermissions { get; set; } + + [JsonProperty("websitePermissions")] + public string WebsitePermissions { get; set; } + + [JsonProperty("id")] + public long Id { get; set; } + } + + public partial class TableSitePermissions + { + public static readonly List OldTableNames = new List + { + "siteserver_SystemPermissions", + "wcm_SystemPermissions" + }; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.SitePermissions.TableName; + + private static readonly List NewColumns = DataProvider.SitePermissions.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(SitePermissionsInfo.SiteId), nameof(PublishmentSystemId)}, + {nameof(SitePermissionsInfo.ChannelIdCollection), nameof(NodeIdCollection)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableTableStyle.cs b/net452/SiteServer.Cli/Updater/Tables/TableTableStyle.cs new file mode 100644 index 000000000..35c0250ae --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableTableStyle.cs @@ -0,0 +1,79 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableTableStyle + { + [JsonProperty("tableStyleID")] + public long TableStyleId { get; set; } + + [JsonProperty("relatedIdentity")] + public long RelatedIdentity { get; set; } + + [JsonProperty("tableName")] + public string TableName { get; set; } + + [JsonProperty("attributeName")] + public string AttributeName { get; set; } + + [JsonProperty("taxis")] + public long Taxis { get; set; } + + [JsonProperty("displayName")] + public string DisplayName { get; set; } + + [JsonProperty("helpText")] + public string HelpText { get; set; } + + [JsonProperty("isVisible")] + public string IsVisible { get; set; } + + [JsonProperty("isVisibleInList")] + public string IsVisibleInList { get; set; } + + [JsonProperty("isSingleLine")] + public string IsSingleLine { get; set; } + + [JsonProperty("inputType")] + public string InputType { get; set; } + + [JsonProperty("isRequired")] + public string IsRequired { get; set; } + + [JsonProperty("defaultValue")] + public string DefaultValue { get; set; } + + [JsonProperty("isHorizontal")] + public string IsHorizontal { get; set; } + + [JsonProperty("extendValues")] + public string ExtendValues { get; set; } + } + + public partial class TableTableStyle + { + public const string OldTableName = "bairong_TableStyle"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict + }; + + private static readonly string NewTableName = DataProvider.TableStyle.TableName; + + private static readonly List NewColumns = DataProvider.TableStyle.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(TableStyleInfo.Id), nameof(TableStyleId)}, + {nameof(TableStyleInfo.TableName), nameof(TableName)} + }; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableTableStyleItem.cs b/net452/SiteServer.Cli/Updater/Tables/TableTableStyleItem.cs new file mode 100644 index 000000000..7444c0ad1 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableTableStyleItem.cs @@ -0,0 +1,51 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableTableStyleItem + { + [JsonProperty("tableStyleItemID")] + public long TableStyleItemId { get; set; } + + [JsonProperty("tableStyleID")] + public long TableStyleId { get; set; } + + [JsonProperty("itemTitle")] + public string ItemTitle { get; set; } + + [JsonProperty("itemValue")] + public string ItemValue { get; set; } + + [JsonProperty("isSelected")] + public string IsSelected { get; set; } + } + + public partial class TableTableStyleItem + { + public const string OldTableName = "bairong_TableStyleItem"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.TableStyleItem.TableName; + + private static readonly List NewColumns = DataProvider.TableStyleItem.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(TableStyleItemInfo.Id), nameof(TableStyleItemId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableTag.cs b/net452/SiteServer.Cli/Updater/Tables/TableTag.cs new file mode 100644 index 000000000..7e3ad5a48 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableTag.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableTag + { + [JsonProperty("tagID")] + public long TagId { get; set; } + + [JsonProperty("productID")] + public string ProductId { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("contentIDCollection")] + public string ContentIdCollection { get; set; } + + [JsonProperty("tag")] + public string Tag { get; set; } + + [JsonProperty("useNum")] + public long UseNum { get; set; } + } + + public partial class TableTag + { + public const string OldTableName = "bairong_Tags"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.Tag.TableName; + + private static readonly List NewColumns = DataProvider.Tag.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(TagInfo.Id), nameof(TagId)}, + {nameof(TagInfo.SiteId), nameof(PublishmentSystemId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableTemplate.cs b/net452/SiteServer.Cli/Updater/Tables/TableTemplate.cs new file mode 100644 index 000000000..61097e0f8 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableTemplate.cs @@ -0,0 +1,71 @@ +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableTemplate + { + [JsonProperty("templateID")] + public long TemplateId { get; set; } + + [JsonProperty("publishmentSystemID")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("templateName")] + public string TemplateName { get; set; } + + [JsonProperty("templateType")] + public string TemplateType { get; set; } + + [JsonProperty("relatedFileName")] + public string RelatedFileName { get; set; } + + [JsonProperty("createdFileFullName")] + public string CreatedFileFullName { get; set; } + + [JsonProperty("createdFileExtName")] + public string CreatedFileExtName { get; set; } + + [JsonProperty("ruleID")] + public long RuleId { get; set; } + + [JsonProperty("charset")] + public string Charset { get; set; } + + [JsonProperty("isDefault")] + public string IsDefault { get; set; } + } + + public partial class TableTemplate + { + public static readonly List OldTableNames = new List + { + "siteserver_Template", + "wcm_Template" + }; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.Template.TableName; + + private static readonly List NewColumns = DataProvider.Template.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(TemplateInfo.Id), nameof(TemplateId)}, + {nameof(TemplateInfo.SiteId), nameof(PublishmentSystemId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableTemplateLog.cs b/net452/SiteServer.Cli/Updater/Tables/TableTemplateLog.cs new file mode 100644 index 000000000..7c2374a6c --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableTemplateLog.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableTemplateLog + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("templateId")] + public long TemplateId { get; set; } + + [JsonProperty("publishmentSystemId")] + public long PublishmentSystemId { get; set; } + + [JsonProperty("addDate")] + public DateTimeOffset AddDate { get; set; } + + [JsonProperty("addUserName")] + public string AddUserName { get; set; } + + [JsonProperty("contentLength")] + public long ContentLength { get; set; } + + [JsonProperty("templateContent")] + public string TemplateContent { get; set; } + } + + public partial class TableTemplateLog + { + public static readonly List OldTableNames = new List + { + "siteserver_TemplateLog", + "wcm_TemplateLog" + }; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.TemplateLog.TableName; + + private static readonly List NewColumns = DataProvider.TemplateLog.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(TemplateLogInfo.SiteId), nameof(PublishmentSystemId)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableUser.cs b/net452/SiteServer.Cli/Updater/Tables/TableUser.cs new file mode 100644 index 000000000..c3d757251 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableUser.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableUser + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("userName")] + public string UserName { get; set; } + + [JsonProperty("password")] + public string Password { get; set; } + + [JsonProperty("passwordFormat")] + public string PasswordFormat { get; set; } + + [JsonProperty("passwordSalt")] + public string PasswordSalt { get; set; } + + [JsonProperty("createDate")] + public DateTimeOffset CreateDate { get; set; } + + [JsonProperty("createIPAddress")] + public string CreateIpAddress { get; set; } + + [JsonProperty("createUserName")] + public string CreateUserName { get; set; } + + [JsonProperty("pointCount")] + public long PointCount { get; set; } + + [JsonProperty("lastActivityDate")] + public DateTimeOffset LastActivityDate { get; set; } + + [JsonProperty("isChecked")] + public string IsChecked { get; set; } + + [JsonProperty("isLockedOut")] + public string IsLockedOut { get; set; } + + [JsonProperty("isTemporary")] + public string IsTemporary { get; set; } + + [JsonProperty("displayName")] + public string DisplayName { get; set; } + + [JsonProperty("email")] + public string Email { get; set; } + + [JsonProperty("mobile")] + public string Mobile { get; set; } + + [JsonProperty("typeID")] + public long TypeId { get; set; } + + [JsonProperty("departmentID")] + public long DepartmentId { get; set; } + + [JsonProperty("areaID")] + public long AreaId { get; set; } + + [JsonProperty("onlineSeconds")] + public long OnlineSeconds { get; set; } + + [JsonProperty("avatarLarge")] + public string AvatarLarge { get; set; } + + [JsonProperty("avatarMiddle")] + public string AvatarMiddle { get; set; } + + [JsonProperty("avatarSmall")] + public string AvatarSmall { get; set; } + + [JsonProperty("signature")] + public string Signature { get; set; } + + [JsonProperty("settingsXML")] + public string SettingsXml { get; set; } + } + + public partial class TableUser + { + public const string OldTableName = "bairong_Users"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.User.TableName; + + private static readonly List NewColumns = DataProvider.User.TableColumns; + + private static readonly Dictionary ConvertKeyDict = + new Dictionary + { + {nameof(UserInfo.AvatarUrl), nameof(AvatarLarge)} + }; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/Tables/TableUserLog.cs b/net452/SiteServer.Cli/Updater/Tables/TableUserLog.cs new file mode 100644 index 000000000..1eaaefc14 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/Tables/TableUserLog.cs @@ -0,0 +1,52 @@ +using System; +using System.Collections.Generic; +using Datory; +using Newtonsoft.Json; +using SiteServer.CMS.Database.Core; +using SiteServer.Plugin; +using TableColumn = Datory.TableColumn; + +namespace SiteServer.Cli.Updater.Tables +{ + public partial class TableUserLog + { + [JsonProperty("id")] + public long Id { get; set; } + + [JsonProperty("userName")] + public string UserName { get; set; } + + [JsonProperty("ipaddress")] + public string IpAddress { get; set; } + + [JsonProperty("adddate")] + public DateTimeOffset Adddate { get; set; } + + [JsonProperty("action")] + public string Action { get; set; } + + [JsonProperty("summary")] + public long Summary { get; set; } + } + + public partial class TableUserLog + { + public const string OldTableName = "bairong_UserLog"; + + public static ConvertInfo Converter => new ConvertInfo + { + NewTableName = NewTableName, + NewColumns = NewColumns, + ConvertKeyDict = ConvertKeyDict, + ConvertValueDict = ConvertValueDict + }; + + private static readonly string NewTableName = DataProvider.UserLog.TableName; + + private static readonly List NewColumns = DataProvider.UserLog.TableColumns; + + private static readonly Dictionary ConvertKeyDict = null; + + private static readonly Dictionary ConvertValueDict = null; + } +} diff --git a/net452/SiteServer.Cli/Updater/UpdateUtils.cs b/net452/SiteServer.Cli/Updater/UpdateUtils.cs new file mode 100644 index 000000000..fc4151349 --- /dev/null +++ b/net452/SiteServer.Cli/Updater/UpdateUtils.cs @@ -0,0 +1,171 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json.Linq; +using SiteServer.Cli.Core; +using SiteServer.Cli.Updater.Tables; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Database.Repositories; +using SiteServer.CMS.Database.Repositories.Contents; +using SiteServer.Utils; +using TableInfo = SiteServer.Cli.Core.TableInfo; + +namespace SiteServer.Cli.Updater +{ + public static class UpdateUtils + { + public static string GetConvertValueDictKey(string key, object oldValue) + { + return $"{key}${oldValue}"; + } + + public static List> UpdateRows(List oldRows, Dictionary convertKeyDict, Dictionary convertValueDict) + { + var newRows = new List>(); + + foreach (var oldRow in oldRows) + { + var newRow = TranslateUtils.JsonGetDictionaryIgnoreCase(oldRow); + foreach (var key in convertKeyDict.Keys) + { + var convertKey = convertKeyDict[key]; + object value; + if (newRow.TryGetValue(convertKey, out value)) + { + var valueDictKey = GetConvertValueDictKey(key, value); + if (convertValueDict != null && convertValueDict.ContainsKey(valueDictKey)) + { + value = convertValueDict[valueDictKey]; + } + + newRow[key] = value; + } + //var value = newRow [convertKeyDict[key]]; + + //var valueDictKey = GetConvertValueDictKey(key, value); + //if (convertValueDict != null && convertValueDict.ContainsKey(valueDictKey)) + //{ + // value = convertValueDict[valueDictKey]; + //} + + //newRow[key] = value; + } + + newRows.Add(newRow); + } + + return newRows; + } + + public static void LoadSites(TreeInfo oldTreeInfo, List siteIdList, List tableNameListForContent, List tableNameListForGovPublic, List tableNameListForGovInteract, List tableNameListForJob) + { + foreach(string oldSiteTableName in TableSite.OldTableNames) + { + var siteMetadataFilePath = oldTreeInfo.GetTableMetadataFilePath(oldSiteTableName); + if (FileUtils.IsFileExists(siteMetadataFilePath)) + { + var siteTableInfo = TranslateUtils.JsonDeserialize(FileUtils.ReadText(siteMetadataFilePath, Encoding.UTF8)); + foreach (var fileName in siteTableInfo.RowFiles) + { + var filePath = oldTreeInfo.GetTableContentFilePath(oldSiteTableName, fileName); + var rows = TranslateUtils.JsonDeserialize>(FileUtils.ReadText(filePath, Encoding.UTF8)); + foreach (var row in rows) + { + var dict = TranslateUtils.JsonGetDictionaryIgnoreCase(row); + if (dict.ContainsKey(nameof(TableSite.PublishmentSystemId))) + { + var value = Convert.ToInt32(dict[nameof(TableSite.PublishmentSystemId)]); + if (value > 0 && !siteIdList.Contains(value)) + { + siteIdList.Add(value); + } + } + if (dict.ContainsKey(nameof(TableSite.AuxiliaryTableForContent))) + { + var value = Convert.ToString(dict[nameof(TableSite.AuxiliaryTableForContent)]); + if (!string.IsNullOrEmpty(value) && !tableNameListForContent.Contains(value)) + { + tableNameListForContent.Add(value); + } + } + if (dict.ContainsKey(nameof(TableSite.AuxiliaryTableForGovInteract))) + { + var value = Convert.ToString(dict[nameof(TableSite.AuxiliaryTableForGovInteract)]); + if (!string.IsNullOrEmpty(value) && !tableNameListForGovInteract.Contains(value)) + { + tableNameListForGovInteract.Add(value); + } + } + if (dict.ContainsKey(nameof(TableSite.AuxiliaryTableForGovPublic))) + { + var value = Convert.ToString(dict[nameof(TableSite.AuxiliaryTableForGovPublic)]); + if (!string.IsNullOrEmpty(value) && !tableNameListForGovPublic.Contains(value)) + { + tableNameListForGovPublic.Add(value); + } + } + if (dict.ContainsKey(nameof(TableSite.AuxiliaryTableForJob))) + { + var value = Convert.ToString(dict[nameof(TableSite.AuxiliaryTableForJob)]); + if (!string.IsNullOrEmpty(value) && !tableNameListForJob.Contains(value)) + { + tableNameListForJob.Add(value); + } + } + } + } + } + } + } + + public static async Task UpdateSitesSplitTableNameAsync(TreeInfo newTreeInfo, Dictionary splitSiteTableDict) + { + var siteMetadataFilePath = newTreeInfo.GetTableMetadataFilePath(DataProvider.Site.TableName); + if (FileUtils.IsFileExists(siteMetadataFilePath)) + { + var siteTableInfo = TranslateUtils.JsonDeserialize(FileUtils.ReadText(siteMetadataFilePath, Encoding.UTF8)); + foreach (var fileName in siteTableInfo.RowFiles) + { + var filePath = newTreeInfo.GetTableContentFilePath(DataProvider.Site.TableName, fileName); + var oldRows = TranslateUtils.JsonDeserialize>(FileUtils.ReadText(filePath, Encoding.UTF8)); + var newRows = new List>(); + foreach (var row in oldRows) + { + var dict = TranslateUtils.JsonGetDictionaryIgnoreCase(row); + if (dict.ContainsKey(nameof(SiteInfo.Id))) + { + var siteId = Convert.ToInt32(dict[nameof(SiteInfo.Id)]); + dict[nameof(SiteInfo.TableName)] = ContentRepository.GetContentTableName(siteId); + } + + newRows.Add(dict); + } + + await FileUtils.WriteTextAsync(filePath, TranslateUtils.JsonSerialize(newRows)); + } + } + + //foreach (var siteId in splitSiteTableDict.Keys) + //{ + // var siteTableInfo = splitSiteTableDict[siteId]; + // var siteTableName = UpdateUtils.GetSplitContentTableName(siteId); + + // siteTableInfo.Columns + //} + + //var tableFilePath = newTreeInfo.GetTableMetadataFilePath(DataProvider.TableDao.TableName); + //if (FileUtils.IsFileExists(tableFilePath)) + //{ + // var siteTableInfo = TranslateUtils.JsonDeserialize(FileUtils.ReadText(tableFilePath, Encoding.UTF8)); + // var filePath = newTreeInfo.GetTableContentFilePath(DataProvider.Site.TableName, siteTableInfo.RowFiles[siteTableInfo.RowFiles.Count]); + // var tableInfoList = TranslateUtils.JsonDeserialize>(FileUtils.ReadText(filePath, Encoding.UTF8)); + + + + // await FileUtils.WriteTextAsync(filePath, Encoding.UTF8, TranslateUtils.JsonSerialize(tableInfoList)); + //} + } + } +} diff --git a/net452/SiteServer.Cli/Updater/UpdaterManager.cs b/net452/SiteServer.Cli/Updater/UpdaterManager.cs new file mode 100644 index 000000000..f897cc82c --- /dev/null +++ b/net452/SiteServer.Cli/Updater/UpdaterManager.cs @@ -0,0 +1,348 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Newtonsoft.Json.Linq; +using SiteServer.Cli.Core; +using SiteServer.Cli.Updater.Tables; +using SiteServer.Cli.Updater.Tables.GovInteract; +using SiteServer.Cli.Updater.Tables.GovPublic; +using SiteServer.Cli.Updater.Tables.Jobs; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Database.Repositories; +using SiteServer.CMS.Database.Repositories.Contents; +using SiteServer.Utils; +using TableInfo = SiteServer.Cli.Core.TableInfo; + +namespace SiteServer.Cli.Updater +{ + public class UpdaterManager + { + public UpdaterManager(TreeInfo oldTreeInfo, TreeInfo newTreeInfo) + { + OldTreeInfo = oldTreeInfo; + NewTreeInfo = newTreeInfo; + } + + protected TreeInfo OldTreeInfo { get; } + + protected TreeInfo NewTreeInfo { get; } + + public async Task> GetNewTableInfoAsync(string oldTableName, TableInfo oldTableInfo, ConvertInfo converter) + { + if (converter == null) + { + converter = new ConvertInfo(); + } + + if (converter.IsAbandon) + { + await CliUtils.PrintRowAsync(oldTableName, "Abandon", "--"); + return null; + } + + if (string.IsNullOrEmpty(converter.NewTableName)) + { + converter.NewTableName = oldTableName; + } + if (converter.NewColumns == null || converter.NewColumns.Count == 0) + { + converter.NewColumns = oldTableInfo.Columns; + } + + var newTableInfo = new TableInfo + { + Columns = converter.NewColumns, + TotalCount = oldTableInfo.TotalCount, + RowFiles = oldTableInfo.RowFiles + }; + + await CliUtils.PrintRowAsync(oldTableName, converter.NewTableName, oldTableInfo.TotalCount.ToString("#,0")); + + if (oldTableInfo.RowFiles.Count > 0) + { + var i = 0; + using (var progress = new ProgressBar()) + { + foreach (var fileName in oldTableInfo.RowFiles) + { + progress.Report((double)i++ / oldTableInfo.RowFiles.Count); + + var oldFilePath = OldTreeInfo.GetTableContentFilePath(oldTableName, fileName); + var newFilePath = NewTreeInfo.GetTableContentFilePath(converter.NewTableName, fileName); + + if (converter.ConvertKeyDict != null) + { + var oldRows = + TranslateUtils.JsonDeserialize>(await FileUtils.ReadTextAsync(oldFilePath, Encoding.UTF8)); + + var newRows = UpdateUtils.UpdateRows(oldRows, converter.ConvertKeyDict, converter.ConvertValueDict); + + await FileUtils.WriteTextAsync(newFilePath, TranslateUtils.JsonSerialize(newRows)); + } + else + { + FileUtils.CopyFile(oldFilePath, newFilePath); + } + } + } + } + + return new Tuple(converter.NewTableName, newTableInfo); + } + + public async Task UpdateSplitContentsTableInfoAsync(Dictionary splitSiteTableDict, List siteIdList, string oldTableName, TableInfo oldTableInfo, ConvertInfo converter) + { + if (converter == null) + { + converter = new ConvertInfo(); + } + + if (converter.IsAbandon) + { + await CliUtils.PrintRowAsync(oldTableName, "Abandon", "--"); + return; + } + + if (converter.NewColumns == null || converter.NewColumns.Count == 0) + { + converter.NewColumns = oldTableInfo.Columns; + } + + await CliUtils.PrintRowAsync(oldTableName, "#split-content#", oldTableInfo.TotalCount.ToString("#,0")); + + if (oldTableInfo.RowFiles.Count > 0) + { + var i = 0; + using (var progress = new ProgressBar()) + { + foreach (var fileName in oldTableInfo.RowFiles) + { + progress.Report((double)i++ / oldTableInfo.RowFiles.Count); + + var newRows = new List>(); + + var oldFilePath = OldTreeInfo.GetTableContentFilePath(oldTableName, fileName); + + var oldRows = + TranslateUtils.JsonDeserialize>(await FileUtils.ReadTextAsync(oldFilePath, Encoding.UTF8)); + + newRows.AddRange(UpdateUtils.UpdateRows(oldRows, converter.ConvertKeyDict, converter.ConvertValueDict)); + + var siteIdWithRows = new Dictionary>>(); + foreach (var siteId in siteIdList) + { + siteIdWithRows.Add(siteId, new List>()); + } + + foreach (var newRow in newRows) + { + if (newRow.ContainsKey(nameof(ContentInfo.SiteId))) + { + var siteId = Convert.ToInt32(newRow[nameof(ContentInfo.SiteId)]); + if (siteIdList.Contains(siteId)) + { + var rows = siteIdWithRows[siteId]; + rows.Add(newRow); + } + } + } + + foreach (var siteId in siteIdList) + { + var siteRows = siteIdWithRows[siteId]; + var siteTableName = ContentRepository.GetContentTableName(siteId); + var siteTableInfo = splitSiteTableDict[siteId]; + siteTableInfo.TotalCount += siteRows.Count; + + foreach(var tableColumn in converter.NewColumns) + { + if (!siteTableInfo.Columns.Any(t => StringUtils.EqualsIgnoreCase(t.AttributeName, tableColumn.AttributeName))) + { + siteTableInfo.Columns.Add(tableColumn); + } + } + + if (siteRows.Count > 0) + { + var siteTableFileName = $"{siteTableInfo.RowFiles.Count + 1}.json"; + siteTableInfo.RowFiles.Add(siteTableFileName); + var filePath = NewTreeInfo.GetTableContentFilePath(siteTableName, siteTableFileName); + await FileUtils.WriteTextAsync(filePath, TranslateUtils.JsonSerialize(siteRows)); + } + } + } + } + } + } + + public async Task> UpdateTableInfoAsync(string oldTableName, TableInfo oldTableInfo, List tableNameListForGovPublic, List tableNameListForGovInteract, List tableNameListForJob) + { + ConvertInfo converter = null; + + if (StringUtils.EqualsIgnoreCase(TableAdministrator.OldTableName, oldTableName)) + { + converter = TableAdministrator.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableAdministratorsInRoles.OldTableName, oldTableName)) + { + converter = TableAdministratorsInRoles.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableArea.OldTableName, oldTableName)) + { + converter = TableArea.Converter; + } + else if (StringUtils.ContainsIgnoreCase(TableChannel.OldTableNames, oldTableName)) + { + converter = TableChannel.Converter; + } + else if (StringUtils.ContainsIgnoreCase(TableChannelGroup.OldTableNames, oldTableName)) + { + converter = TableChannelGroup.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableConfig.OldTableName, oldTableName)) + { + converter = TableConfig.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableContentCheck.OldTableName, oldTableName)) + { + converter = TableContentCheck.Converter; + } + else if (StringUtils.ContainsIgnoreCase(TableContentGroup.OldTableNames, oldTableName)) + { + converter = TableContentGroup.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableDbCache.OldTableName, oldTableName)) + { + converter = TableDbCache.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableDepartment.OldTableName, oldTableName)) + { + converter = TableDepartment.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableErrorLog.OldTableName, oldTableName)) + { + converter = TableErrorLog.Converter; + } + else if (StringUtils.ContainsIgnoreCase(TableKeyword.OldTableNames, oldTableName)) + { + converter = TableKeyword.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableLog.OldTableName, oldTableName)) + { + converter = TableLog.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TablePermissionsInRoles.OldTableName, oldTableName)) + { + converter = TablePermissionsInRoles.Converter; + } + else if (StringUtils.ContainsIgnoreCase(TableRelatedField.OldTableNames, oldTableName)) + { + converter = TableRelatedField.Converter; + } + else if (StringUtils.ContainsIgnoreCase(TableRelatedFieldItem.OldTableNames, oldTableName)) + { + converter = TableRelatedFieldItem.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableRole.OldTableName, oldTableName)) + { + converter = TableRole.Converter; + } + else if (StringUtils.ContainsIgnoreCase(TableSite.OldTableNames, oldTableName)) + { + converter = TableSite.Converter; + } + else if (StringUtils.ContainsIgnoreCase(TableSiteLog.OldTableNames, oldTableName)) + { + converter = TableSiteLog.Converter; + } + else if (StringUtils.ContainsIgnoreCase(TableSitePermissions.OldTableNames, oldTableName)) + { + converter = TableSitePermissions.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableTableStyle.OldTableName, oldTableName)) + { + converter = TableTableStyle.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableTableStyleItem.OldTableName, oldTableName)) + { + converter = TableTableStyleItem.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableTag.OldTableName, oldTableName)) + { + converter = TableTag.Converter; + } + else if (StringUtils.ContainsIgnoreCase(TableTemplate.OldTableNames, oldTableName)) + { + converter = TableTemplate.Converter; + } + else if (StringUtils.ContainsIgnoreCase(TableTemplateLog.OldTableNames, oldTableName)) + { + converter = TableTemplateLog.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableUser.OldTableName, oldTableName)) + { + converter = TableUser.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableUserLog.OldTableName, oldTableName)) + { + converter = TableUserLog.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableGovInteractChannel.OldTableName, oldTableName)) + { + converter = TableGovInteractChannel.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableGovInteractLog.OldTableName, oldTableName)) + { + converter = TableGovInteractLog.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableGovInteractPermissions.OldTableName, oldTableName)) + { + converter = TableGovInteractPermissions.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableGovInteractRemark.OldTableName, oldTableName)) + { + converter = TableGovInteractRemark.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableGovInteractReply.OldTableName, oldTableName)) + { + converter = TableGovInteractReply.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableGovInteractType.OldTableName, oldTableName)) + { + converter = TableGovInteractType.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableGovPublicCategory.OldTableName, oldTableName)) + { + converter = TableGovPublicCategory.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableGovPublicCategoryClass.OldTableName, oldTableName)) + { + converter = TableGovPublicCategoryClass.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableGovPublicIdentifierRule.OldTableName, oldTableName)) + { + converter = TableGovPublicIdentifierRule.Converter; + } + else if (StringUtils.EqualsIgnoreCase(TableGovPublicIdentifierSeq.OldTableName, oldTableName)) + { + converter = TableGovPublicIdentifierSeq.Converter; + } + else if (StringUtils.ContainsIgnoreCase(tableNameListForGovPublic, oldTableName)) + { + converter = TableGovPublicContent.GetConverter(oldTableInfo.Columns); + } + else if (StringUtils.ContainsIgnoreCase(tableNameListForGovInteract, oldTableName)) + { + converter = TableGovInteractContent.GetConverter(oldTableInfo.Columns); + } + else if (StringUtils.ContainsIgnoreCase(tableNameListForJob, oldTableName)) + { + converter = TableJobsContent.GetConverter(oldTableInfo.Columns); + } + + return await GetNewTableInfoAsync(oldTableName, oldTableInfo, converter); + } + } +} diff --git a/net452/SiteServer.Cli/app.config b/net452/SiteServer.Cli/app.config new file mode 100644 index 000000000..b39077523 --- /dev/null +++ b/net452/SiteServer.Cli/app.config @@ -0,0 +1,45 @@ + + + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/net452/SiteServer.Cli/logo.ico b/net452/SiteServer.Cli/logo.ico new file mode 100644 index 000000000..8d2d1a8bf Binary files /dev/null and b/net452/SiteServer.Cli/logo.ico differ diff --git a/net452/SiteServer.Cli/packages.config b/net452/SiteServer.Cli/packages.config new file mode 100644 index 000000000..ff25b69e9 --- /dev/null +++ b/net452/SiteServer.Cli/packages.config @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/.gitignore b/net452/SiteServer.Web/.gitignore new file mode 100644 index 000000000..8da7b4f89 --- /dev/null +++ b/net452/SiteServer.Web/.gitignore @@ -0,0 +1,68 @@ +bin/ +obj/ +/channels/ +/contents/ +SiteFiles/BackupFiles/ +SiteFiles/Plugins/ +SiteFiles/packages/ +SiteFiles/SiteTemplates/ +SiteFiles/TemporaryFiles/ +SiteFiles/UserFiles/ +SiteFiles/Administrators/ +Template +/sapprft/ +/Mullen/ +Web.config + +test/ +## sqlserver +test1/ +test2/ +test3/ +test4/ +test5/ +test6/ +test7/ +test8/ +test9/ + +## mysql +test10/ +test11/ +test12/ +test13/ +test14/ +test15/ +test16/ +test17/ +test18/ +test19/ + +## postgresql +test20/ +test21/ +test22/ +test23/ +test24/ +test25/ +test26/ +test27/ +test28/ +test29/ + +## oracle +test30/ +test31/ +test32/ +test33/ +test34/ +test35/ +test36/ +test37/ +test38/ +test39/ + +upload +T_*.html +index.html +index.shtml \ No newline at end of file diff --git a/net452/SiteServer.Web/CentralizedPrefixProvider.cs b/net452/SiteServer.Web/CentralizedPrefixProvider.cs new file mode 100644 index 000000000..629a3d672 --- /dev/null +++ b/net452/SiteServer.Web/CentralizedPrefixProvider.cs @@ -0,0 +1,30 @@ +using System.Web.Http.Controllers; +using System.Web.Http.Routing; + +namespace SiteServer.API +{ + //https://www.strathweb.com/2015/10/global-route-prefixes-with-attribute-routing-in-asp-net-web-api/ + public class CentralizedPrefixProvider : DefaultDirectRouteProvider + { + private readonly string _centralizedPrefix; + + public CentralizedPrefixProvider(string centralizedPrefix) + { + _centralizedPrefix = centralizedPrefix; + } + + protected override string GetRoutePrefix(HttpControllerDescriptor controllerDescriptor) + { + var prefix = _centralizedPrefix; + + var dllName = controllerDescriptor.ControllerType.Assembly.GetName().Name.ToLower(); + if (dllName != "siteserver.api") + { + prefix += "/" + dllName; + } + + var existingPrefix = base.GetRoutePrefix(controllerDescriptor); + return existingPrefix == null ? prefix : $"{prefix}/{existingPrefix}"; + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Controllers/Backend/AdminUtils.cs b/net452/SiteServer.Web/Controllers/Backend/AdminUtils.cs new file mode 100644 index 000000000..6ce789bb7 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Backend/AdminUtils.cs @@ -0,0 +1,80 @@ +using System.Collections.Specialized; +using System.Linq; +using System.Web; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Backend +{ + public static class AdminUtils + { + public static string IndexUrl => GetAdminUrl(""); + public static string DashboardUrl => GetAdminUrl("dashboard"); + public static string ErrorUrl => GetAdminUrl("error"); + public static string LoginUrl => GetAdminUrl("login"); + public static string LogoutUrl => GetAdminUrl("logout"); + public static string UpdateUrl => GetAdminUrl("update"); + public static string UpgradeUrl => GetAdminUrl("upgrade"); + public static string LoadingUrl => GetAdminUrl("loading"); + + public static string ApplicationPath => HttpContext.Current != null && !string.IsNullOrEmpty(HttpContext.Current.Request.ApplicationPath) ? HttpContext.Current.Request.ApplicationPath : "/"; + + public static string GetAdminUrl(string relatedUrl) + { + return PageUtils.Combine(ApplicationPath, relatedUrl); + } + + public static string GetIndexUrl(int siteId, string pageUrl) + { + var queryString = new NameValueCollection(); + if (siteId > 0) + { + queryString.Add("siteId", siteId.ToString()); + } + if (!string.IsNullOrEmpty(pageUrl)) + { + queryString.Add("pageUrl", PageUtils.UrlEncode(pageUrl)); + } + return PageUtils.AddQueryString(IndexUrl, queryString); + } + + public static class Plugins + { + private const string DirectoryName = nameof(Plugins); + + public static string ManageUrl => GetAdminUrl(PageUtils.Combine(DirectoryName, "manage.cshtml")); + } + + public static class Settings + { + private const string DirectoryName = nameof(Settings); + + public static string AdministratorsUrl => GetAdminUrl(PageUtils.Combine(DirectoryName, "administrators.cshtml")); + + public static string SiteAddUrl => GetAdminUrl(PageUtils.Combine(DirectoryName, "siteAdd.cshtml")); + } + + public static class Cms + { + private const string DirectoryName = nameof(Cms); + + private static string GetUrl(string pageName, int siteId, object param = null) + { + var url = GetAdminUrl(PageUtils.Combine(DirectoryName, $"{pageName}?siteId={siteId}")); + return param == null ? url : param.GetType().GetProperties().Aggregate(url, (current, p) => current + $"&{p.Name.ToCamelCase()}={p.GetValue(param)}"); + } + + public static string GetContentsUrl(int siteId, int channelId) + { + return GetUrl("contents.cshtml", siteId, new + { + channelId + }); + } + + public static string GetCreateStatusUrl(int siteId) + { + return GetUrl("createStatus.cshtml", siteId); + } + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Controllers/Backend/Create/CreateStatusController.cs b/net452/SiteServer.Web/Controllers/Backend/Create/CreateStatusController.cs new file mode 100644 index 000000000..5c58cb999 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Backend/Create/CreateStatusController.cs @@ -0,0 +1,72 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Backend.Create +{ + [RoutePrefix("backend/create/status")] + public class CreateStatusController : ApiController + { + private const string Route = ""; + private const string RouteActionsCancel = "actions/cancel"; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var siteId = Request.GetQueryInt("siteId"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSitePermissions(siteId, ConfigManager.WebSitePermissions.Create)) + { + return Unauthorized(); + } + + var summary = CreateTaskManager.GetTaskSummary(siteId); + + return Ok(new + { + Value = summary + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteActionsCancel)] + public IHttpActionResult Cancel() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var siteId = Request.GetPostInt("siteId"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSitePermissions(siteId, ConfigManager.WebSitePermissions.Create)) + { + return Unauthorized(); + } + + CreateTaskManager.ClearAllTask(siteId); + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Controllers/Backend/IndexController.cs b/net452/SiteServer.Web/Controllers/Backend/IndexController.cs new file mode 100644 index 000000000..f14a15e8f --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Backend/IndexController.cs @@ -0,0 +1,90 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.BackgroundPages.Cms; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Packaging; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.API.Controllers.Backend +{ + [RoutePrefix("backend/index")] + public class IndexController : ApiController + { + private const string Route = ""; + private const string RouteUnCheckedList = "unCheckedList"; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin) + { + return Unauthorized(); + } + + var adminInfo = AdminManager.GetAdminInfoByUserId(rest.AdminId); + + return Ok(new + { + Value = new + { + Version = SystemManager.Version == PackageUtils.VersionDev ? "dev" : SystemManager.Version, + LastActivityDate = DateUtils.GetDateString(adminInfo.LastActivityDate, EDateFormatType.Chinese), + UpdateDate = DateUtils.GetDateString(ConfigManager.Instance.UpdateDate, EDateFormatType.Chinese) + } + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpGet, Route(RouteUnCheckedList)] + public IHttpActionResult GetUnCheckedList() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin) + { + return Unauthorized(); + } + + var unCheckedList = new List(); + + foreach (var siteInfo in SiteManager.GetSiteInfoList()) + { + if (!rest.AdminPermissions.IsSiteAdmin(siteInfo.Id)) continue; + + var count = ContentManager.GetCount(siteInfo, false); + if (count > 0) + { + unCheckedList.Add(new + { + Url = PageContentSearch.GetRedirectUrlCheck(siteInfo.Id), + siteInfo.SiteName, + Count = count + }); + } + } + + return Ok(new + { + Value = unCheckedList + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Controllers/Backend/LoginController.cs b/net452/SiteServer.Web/Controllers/Backend/LoginController.cs new file mode 100644 index 000000000..26d9e9f87 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Backend/LoginController.cs @@ -0,0 +1,205 @@ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Web; +using System.Web.Http; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Backend +{ + [RoutePrefix("backend/login")] + public class LoginController : ApiController + { + private const string Route = ""; + private const string RouteCaptcha = "captcha"; + + private static readonly Color[] Colors = { Color.FromArgb(37, 72, 91), Color.FromArgb(68, 24, 25), Color.FromArgb(17, 46, 2), Color.FromArgb(70, 16, 100), Color.FromArgb(24, 88, 74) }; + + public static object AdminRedirectCheck(IAuthenticatedRequest request, bool checkInstall = false, bool checkDatabaseVersion = false, + bool checkLogin = false) + { + var redirect = false; + var redirectUrl = string.Empty; + + if (checkInstall && string.IsNullOrWhiteSpace(WebConfigUtils.ConnectionString)) + { + redirect = true; + redirectUrl = FxUtils.GetAdminUrl("installer/default.aspx"); + } + else if (checkDatabaseVersion && ConfigManager.Instance.Initialized && + ConfigManager.Instance.DatabaseVersion != SystemManager.Version) + { + redirect = true; + redirectUrl = AdminPagesUtils.UpdateUrl; + } + else if (checkLogin && !request.IsAdminLoggin) + { + redirect = true; + redirectUrl = AdminPagesUtils.LoginUrl; + } + + if (redirect) + { + return new + { + Value = false, + RedirectUrl = redirectUrl + }; + } + + return null; + } + + [HttpGet, Route(Route)] + public IHttpActionResult GetStatus() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var redirect = AdminRedirectCheck(rest, checkInstall: true, checkDatabaseVersion: true); + if (redirect != null) return Ok(redirect); + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpGet, Route(RouteCaptcha)] + public void GetCaptcha() + { + var response = HttpContext.Current.Response; + + var code = VcManager.CreateValidateCode(); + if (CacheUtils.Exists($"SiteServer.API.Controllers.Admin.LoginController.{code}")) + { + code = VcManager.CreateValidateCode(); + } + + CookieUtils.SetCookie("SS-" + nameof(LoginController), code, TimeSpan.FromMinutes(10)); + + response.BufferOutput = true; //特别注意 + response.Cache.SetExpires(DateTime.Now.AddMilliseconds(-1));//特别注意 + response.Cache.SetCacheability(HttpCacheability.NoCache);//特别注意 + response.AppendHeader("Pragma", "No-Cache"); //特别注意 + response.ContentType = "image/png"; + + byte[] buffer; + + using (var image = new Bitmap(130, 53, PixelFormat.Format32bppRgb)) + { + var r = new Random(); + var colors = Colors[r.Next(0, 5)]; + + using (var g = Graphics.FromImage(image)) + { + g.FillRectangle(new SolidBrush(Color.FromArgb(240, 243, 248)), 0, 0, 200, 200); //矩形框 + g.DrawString(code, new Font(FontFamily.GenericSerif, 28, FontStyle.Bold | FontStyle.Italic), new SolidBrush(colors), new PointF(14, 3));//字体/颜色 + + var random = new Random(); + + for (var i = 0; i < 25; i++) + { + var x1 = random.Next(image.Width); + var x2 = random.Next(image.Width); + var y1 = random.Next(image.Height); + var y2 = random.Next(image.Height); + + g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2); + } + + for (var i = 0; i < 100; i++) + { + var x = random.Next(image.Width); + var y = random.Next(image.Height); + + image.SetPixel(x, y, Color.FromArgb(random.Next())); + } + + g.Save(); + } + + using (var ms = new MemoryStream()) + { + image.Save(ms, ImageFormat.Png); + buffer = ms.ToArray(); + } + } + + response.ClearContent(); + response.BinaryWrite(buffer); + response.End(); + } + + [HttpPost, Route(Route)] + public IHttpActionResult Login() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var account = Request.GetPostString("account"); + var password = Request.GetPostString("password"); + var captcha = Request.GetPostString("captcha"); + var isAutoLogin = Request.GetPostBool("isAutoLogin"); + + var code = CookieUtils.GetCookie("SS-" + nameof(LoginController)); + + if (string.IsNullOrEmpty(code) || CacheUtils.Exists($"SiteServer.API.Controllers.Admin.LoginController.{code}")) + { + return BadRequest("验证码已超时,请点击刷新验证码!"); + } + + CookieUtils.Erase("SS-" + nameof(LoginController)); + CacheUtils.InsertMinutes($"SiteServer.API.Controllers.Admin.LoginController.{code}", true, 10); + + if (!StringUtils.EqualsIgnoreCase(code, captcha)) + { + return BadRequest("验证码不正确,请重新输入!"); + } + + AdministratorInfo adminInfo; + + if (!DataProvider.Administrator.Validate(account, password, true, out var userName, out var errorMessage)) + { + adminInfo = AdminManager.GetAdminInfoByUserName(userName); + if (adminInfo != null) + { + DataProvider.Administrator.UpdateLastActivityDateAndCountOfFailedLogin(adminInfo); // 记录最后登录时间、失败次数+1 + } + return BadRequest(errorMessage); + } + + adminInfo = AdminManager.GetAdminInfoByUserName(userName); + DataProvider.Administrator.UpdateLastActivityDateAndCountOfLogin(adminInfo); // 记录最后登录时间、失败次数清零 + var accessToken = rest.AdminLogin(adminInfo.UserName, isAutoLogin); + var expiresAt = DateTime.Now.AddDays(Constants.AccessTokenExpireDays); + + return Ok(new + { + Value = adminInfo, + AccessToken = accessToken, + ExpiresAt = expiresAt + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Controllers/Backend/MainController.cs b/net452/SiteServer.Web/Controllers/Backend/MainController.cs new file mode 100644 index 000000000..e97e84af3 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Backend/MainController.cs @@ -0,0 +1,389 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Threading.Tasks; +using System.Web.Http; +using SiteServer.BackgroundPages.Cms; +using SiteServer.BackgroundPages.Settings; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.RestRoutes; +using SiteServer.CMS.Core.RestRoutes.Preview; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Packaging; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.CMS.StlParser; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Backend +{ + [RoutePrefix("backend")] + public class MainController : ApiController + { + private const string Route = ""; + private const string RouteActionsDownload = "actions/download"; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var redirect = LoginController.AdminRedirectCheck(rest, checkInstall: true, checkDatabaseVersion: true); + if (redirect != null) return Ok(redirect); + + var siteId = Request.GetQueryInt("siteId"); + var pageUrl = Request.GetQueryString("pageUrl"); + + if (!rest.IsAdminLoggin) + { + return Ok(new + { + Value = false, + RedirectUrl = $"{AdminUtils.LoginUrl}?redirectUrl={PageUtils.UrlEncode(AdminUtils.GetIndexUrl(siteId, pageUrl))}" + }); + } + + var adminInfo = AdminManager.GetAdminInfoByUserId(rest.AdminId); + + if (adminInfo.Locked) + { + return Ok(new + { + Value = false, + RedirectUrl = $"{AdminUtils.ErrorUrl}?message={PageUtils.UrlEncode("管理员账号已被锁定,请联系超级管理员协助解决")}" + }); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + var permissions = (PermissionsImpl)rest.AdminPermissions; + var isSuperAdmin = permissions.IsSuperAdmin(); + var siteIdListWithPermissions = permissions.GetSiteIdList(); + + if (siteInfo == null || !siteIdListWithPermissions.Contains(siteInfo.Id)) + { + if (siteIdListWithPermissions.Contains(adminInfo.SiteId)) + { + return Ok(new + { + Value = false, + RedirectUrl = AdminUtils.GetIndexUrl(adminInfo.SiteId, pageUrl) + }); + } + + if (siteIdListWithPermissions.Count > 0) + { + return Ok(new + { + Value = false, + RedirectUrl = AdminUtils.GetIndexUrl(siteIdListWithPermissions[0], pageUrl) + }); + } + + if (isSuperAdmin) + { + return Ok(new + { + Value = false, + RedirectUrl = PageSiteAdd.GetRedirectUrl() + }); + } + + return Ok(new + { + Value = false, + RedirectUrl = $"{AdminUtils.ErrorUrl}?message={PageUtils.UrlEncode("您没有可以管理的站点,请联系超级管理员协助解决")}" + }); + } + + var packageIds = new List + { + PackageUtils.PackageIdSsCms + }; + var packageList = new List(); + var dict = PluginManager.GetPluginIdAndVersionDict(); + foreach (var id in dict.Keys) + { + packageIds.Add(id); + var version = dict[id]; + packageList.Add(new + { + id, + version + }); + } + + var siteIdListLatestAccessed = DataProvider.Administrator.UpdateSiteId(adminInfo, siteInfo.Id); + + var permissionList = new List(permissions.PermissionList); + if (permissions.HasSitePermissions(siteInfo.Id)) + { + var websitePermissionList = permissions.GetSitePermissions(siteInfo.Id); + if (websitePermissionList != null) + { + permissionList.AddRange(websitePermissionList); + } + } + var channelPermissions = permissions.GetChannelPermissions(siteInfo.Id); + if (channelPermissions.Count > 0) + { + permissionList.AddRange(channelPermissions); + } + + var topMenus = GetTopMenus(siteInfo, isSuperAdmin, siteIdListLatestAccessed, siteIdListWithPermissions); + var siteMenus = + GetLeftMenus(siteInfo, ConfigManager.TopMenu.IdSite, isSuperAdmin, permissionList); + var pluginMenus = GetLeftMenus(siteInfo, string.Empty, isSuperAdmin, permissionList); + + var adminInfoToReturn = new + { + adminInfo.Id, + adminInfo.UserName, + adminInfo.AvatarUrl, + Level = permissions.GetAdminLevel() + }; + + var defaultPageUrl = PageUtils.UrlDecode(pageUrl); + if (string.IsNullOrEmpty(defaultPageUrl)) + { + defaultPageUrl = PluginMenuManager.GetSystemDefaultPageUrl(siteId); + } + if (string.IsNullOrEmpty(defaultPageUrl)) + { + defaultPageUrl = AdminUtils.DashboardUrl; + } + + return Ok(new + { + Value = true, + DefaultPageUrl = defaultPageUrl, + WebConfigUtils.IsNightlyUpdate, + SystemManager.PluginVersion, + IsSuperAdmin = isSuperAdmin, + PackageList = packageList, + PackageIds = packageIds, + CmsVersion = SystemManager.Version, + ApiManager.ApiPrefix, + WebConfigUtils.AdminDirectory, + WebConfigUtils.HomeDirectory, + TopMenus = topMenus, + SiteMenus = siteMenus, + PluginMenus = pluginMenus, + AdminInfo = adminInfoToReturn + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + private static List GetTopMenus(SiteInfo siteInfo, bool isSuperAdmin, List siteIdListLatestAccessed, List siteIdListWithPermissions) + { + var menus = new List(); + + if (siteInfo != null && siteIdListWithPermissions.Contains(siteInfo.Id)) + { + var siteMenus = new List(); + if (siteIdListWithPermissions.Count == 1) + { + menus.Add(new Tab + { + Text = siteInfo.SiteName, + Children = siteMenus.ToArray() + }); + } + else + { + var siteIdList = AdminManager.GetLatestTop10SiteIdList(siteIdListLatestAccessed, siteIdListWithPermissions); + foreach (var siteId in siteIdList) + { + var site = SiteManager.GetSiteInfo(siteId); + if (site == null) continue; + + siteMenus.Add(new Tab + { + Href = AdminUtils.GetIndexUrl(site.Id, string.Empty), + Target = "_top", + Text = site.SiteName + }); + } + siteMenus.Add(new Tab + { + Href = ModalSiteSelect.GetRedirectUrl(siteInfo.Id), + Target = "_layer", + Text = "全部站点..." + }); + menus.Add(new Tab + { + Text = siteInfo.SiteName, + Href = ModalSiteSelect.GetRedirectUrl(siteInfo.Id), + Target = "_layer", + Children = siteMenus.ToArray() + }); + } + + var linkMenus = new List + { + new Tab {Href = PageUtility.GetSiteUrl(siteInfo, false), Target = "_blank", Text = "访问站点"}, + new Tab {Href = ApiRoutePreview.GetSiteUrl(siteInfo.Id), Target = "_blank", Text = "预览站点"} + }; + menus.Add(new Tab {Text = "站点链接", Children = linkMenus.ToArray()}); + } + + if (isSuperAdmin) + { + foreach (var tab in TabManager.GetTopMenuTabs()) + { + var tabs = TabManager.GetTabList(tab.Id, 0); + tab.Children = tabs.ToArray(); + + menus.Add(tab); + } + } + + return menus; + } + + private static List GetLeftMenus(SiteInfo siteInfo, string topId, bool isSuperAdmin, List permissionList) + { + var menus = new List(); + + var tabs = TabManager.GetTabList(topId, siteInfo.Id); + foreach (var parent in tabs) + { + if (!isSuperAdmin && !TabManager.IsValid(parent, permissionList)) continue; + + var children = new List(); + if (parent.Children != null && parent.Children.Length > 0) + { + var tabCollection = new TabCollection(parent.Children); + if (tabCollection.Tabs != null && tabCollection.Tabs.Length > 0) + { + foreach (var childTab in tabCollection.Tabs) + { + if (!isSuperAdmin && !TabManager.IsValid(childTab, permissionList)) continue; + + children.Add(new Tab + { + Id = childTab.Id, + Href = GetHref(childTab, siteInfo.Id), + Text = childTab.Text, + Target = childTab.Target, + IconClass = childTab.IconClass + }); + } + } + } + + menus.Add(new Tab + { + Id = parent.Id, + Href = GetHref(parent, siteInfo.Id), + Text = parent.Text, + Target = parent.Target, + IconClass = parent.IconClass, + Selected = parent.Selected, + Children = children.ToArray() + }); + } + + return menus; + } + + private static string GetHref(Tab tab, int siteId) + { + var href = tab.Href; + if (!PageUtils.IsAbsoluteUrl(href)) + { + href = PageUtils.AddQueryString(href, + new NameValueCollection { { "siteId", siteId.ToString() } }); + } + + return href; + } + + [HttpPost, Route(Route)] + public async Task Create() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin) + { + return Unauthorized(); + } + + var count = CreateTaskManager.PendingTaskCount; + + var pendingTask = CreateTaskManager.GetFirstPendingTask(); + if (pendingTask != null) + { + try + { + var start = DateTime.Now; + await FileSystemObjectAsync.ExecuteAsync(pendingTask.SiteId, pendingTask.CreateType, + pendingTask.ChannelId, + pendingTask.ContentId, pendingTask.FileTemplateId, pendingTask.SpecialId); + var timeSpan = DateUtils.GetRelatedDateTimeString(start); + CreateTaskManager.AddSuccessLog(pendingTask, timeSpan); + } + catch (Exception ex) + { + CreateTaskManager.AddFailureLog(pendingTask, ex); + } + finally + { + CreateTaskManager.RemovePendingTask(pendingTask); + } + } + + return Ok(new + { + Value = count + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteActionsDownload)] + public IHttpActionResult Download() + { + var rest = Request.GetAuthenticatedRequest(); + + if (!rest.IsAdminLoggin) + { + return Unauthorized(); + } + + var packageId = Request.GetPostString("packageId"); + var version = Request.GetPostString("version"); + + try + { + PackageUtils.DownloadPackage(packageId, version); + } + catch + { + PackageUtils.DownloadPackage(packageId, version); + } + + if (StringUtils.EqualsIgnoreCase(packageId, PackageUtils.PackageIdSsCms)) + { + CacheDbUtils.RemoveAndInsert(PackageUtils.CacheKeySsCmsIsDownload, true.ToString()); + } + + return Ok(new + { + Value = true + }); + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Controllers/Home/HomeContentAddLayerImageController.cs b/net452/SiteServer.Web/Controllers/Home/HomeContentAddLayerImageController.cs new file mode 100644 index 000000000..89735db80 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeContentAddLayerImageController.cs @@ -0,0 +1,265 @@ +using System; +using System.Collections.Generic; +using System.Web; +using System.Web.Http; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home/contentAddLayerImage")] + public class HomeContentAddLayerImageController : ApiController + { + private const string Route = ""; + private const string RouteUpload = "actions/upload"; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + return Ok(new + { + Value = siteInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteUpload)] + public IHttpActionResult Upload() + { + try + { +#pragma warning disable CS0612 // '“RequestImpl”已过时 + var request = new RequestImpl(HttpContext.Current.Request); +#pragma warning restore CS0612 // '“RequestImpl”已过时 + + var siteId = request.GetQueryInt("siteId"); + var channelId = request.GetQueryInt("channelId"); + + if (!request.IsUserLoggin || + !request.UserPermissionsImpl.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var path = string.Empty; + var url = string.Empty; + var contentLength = 0; + + if (request.HttpRequest.Files.Count > 0) + { + var file = request.HttpRequest.Files[0]; + + var filePath = file.FileName; + var fileExtName = PathUtils.GetExtension(filePath).ToLower(); + var localDirectoryPath = PathUtility.GetUploadDirectoryPath(siteInfo, fileExtName); + var localFileName = PathUtility.GetUploadFileName(siteInfo, filePath); + path = PathUtils.Combine(localDirectoryPath, localFileName); + contentLength = file.ContentLength; + + if (!PathUtility.IsImageExtenstionAllowed(siteInfo, fileExtName)) + { + return BadRequest("上传失败,上传图片格式不正确!"); + } + if (!PathUtility.IsImageSizeAllowed(siteInfo, contentLength)) + { + return BadRequest("上传失败,上传图片超出规定文件大小!"); + } + + file.SaveAs(path); + FileUtility.AddWaterMark(siteInfo, path); + + url = PageUtility.GetSiteUrlByPhysicalPath(siteInfo, path, true); + } + + return Ok(new + { + Path = path, + Url = url, + ContentLength = contentLength + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var isFix = Request.GetPostBool("isFix"); + var fixWidth = Request.GetPostString("fixWidth"); + var fixHeight = Request.GetPostString("fixHeight"); + var isEditor = Request.GetPostBool("isEditor"); + var editorIsFix = Request.GetPostBool("editorIsFix"); + var editorFixWidth = Request.GetPostString("editorFixWidth"); + var editorFixHeight = Request.GetPostString("editorFixHeight"); + var editorIsLinkToOriginal = Request.GetPostBool("editorIsLinkToOriginal"); + var filePaths = TranslateUtils.StringCollectionToStringList(Request.GetPostString("filePaths")); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var retval = new List(); + var editors = new List(); + + foreach (var filePath in filePaths) + { + if (string.IsNullOrEmpty(filePath)) continue; + + var fileExtName = PathUtils.GetExtension(filePath).ToLower(); + var fileName = PathUtility.GetUploadFileName(siteInfo, filePath); + + var directoryPath = PathUtility.GetUploadDirectoryPath(siteInfo, fileExtName); + var fixFilePath = PathUtils.Combine(directoryPath, Constants.TitleImageAppendix + fileName); + var editorFixFilePath = PathUtils.Combine(directoryPath, Constants.SmallImageAppendix + fileName); + + var isImage = EFileSystemTypeUtils.IsImage(fileExtName); + + if (isImage) + { + if (isFix) + { + var width = TranslateUtils.ToInt(fixWidth); + var height = TranslateUtils.ToInt(fixHeight); + ImageUtils.MakeThumbnail(filePath, fixFilePath, width, height, true); + } + + if (isEditor) + { + if (editorIsFix) + { + var width = TranslateUtils.ToInt(editorFixWidth); + var height = TranslateUtils.ToInt(editorFixHeight); + ImageUtils.MakeThumbnail(filePath, editorFixFilePath, width, height, true); + } + } + } + + var imageUrl = PageUtility.GetSiteUrlByPhysicalPath(siteInfo, filePath, true); + var fixImageUrl = PageUtility.GetSiteUrlByPhysicalPath(siteInfo, fixFilePath, true); + var editorFixImageUrl = PageUtility.GetSiteUrlByPhysicalPath(siteInfo, editorFixFilePath, true); + + retval.Add(isFix ? fixImageUrl : imageUrl); + + editors.Add(new + { + ImageUrl = isFix ? editorFixImageUrl : imageUrl, + OriginalUrl = imageUrl + }); + } + + var changed = false; + if (siteInfo.ConfigImageIsFix != isFix) + { + changed = true; + siteInfo.ConfigImageIsFix = isFix; + } + if (siteInfo.ConfigImageFixWidth != fixWidth) + { + changed = true; + siteInfo.ConfigImageFixWidth = fixWidth; + } + if (siteInfo.ConfigImageFixHeight != fixHeight) + { + changed = true; + siteInfo.ConfigImageFixHeight = fixHeight; + } + if (siteInfo.ConfigImageIsEditor != isEditor) + { + changed = true; + siteInfo.ConfigImageIsEditor = isEditor; + } + if (siteInfo.ConfigImageEditorIsFix != editorIsFix) + { + changed = true; + siteInfo.ConfigImageEditorIsFix = editorIsFix; + } + if (siteInfo.ConfigImageEditorFixWidth != editorFixWidth) + { + changed = true; + siteInfo.ConfigImageEditorFixWidth = editorFixWidth; + } + if (siteInfo.ConfigImageEditorFixHeight != editorFixHeight) + { + changed = true; + siteInfo.ConfigImageEditorFixHeight = editorFixHeight; + } + if (siteInfo.ConfigImageEditorIsLinkToOriginal != editorIsLinkToOriginal) + { + changed = true; + siteInfo.ConfigImageEditorIsLinkToOriginal = editorIsLinkToOriginal; + } + + if (changed) + { + DataProvider.Site.Update(siteInfo); + } + + return Ok(new + { + Value = retval, + Editors = editors + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Home/HomeContentsController.cs b/net452/SiteServer.Web/Controllers/Home/HomeContentsController.cs new file mode 100644 index 000000000..fae99eafb --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeContentsController.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home/contents")] + public class HomeContentsController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult List() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + var page = Request.GetQueryInt("page"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentView)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var onlyAdminId = ((PermissionsImpl)rest.AdminPermissions).GetOnlyAdminId(siteId, channelId); + + var columns = ContentManager.GetContentColumns(siteInfo, channelInfo, false); + var pluginIds = PluginContentManager.GetContentPluginIds(channelInfo); + var pluginColumns = PluginContentManager.GetContentColumns(pluginIds); + + var pageContentInfoList = new List>(); + var count = ContentManager.GetCount(siteInfo, channelInfo, onlyAdminId); + + var pages = Convert.ToInt32(Math.Ceiling((double)count / siteInfo.PageSize)); + if (pages == 0) pages = 1; + + if (count > 0) + { + var offset = siteInfo.PageSize * (page - 1); + var limit = siteInfo.PageSize; + + var pageContentIds = ContentManager.GetContentIdList(siteInfo, channelInfo, onlyAdminId, offset, limit); + + var sequence = offset + 1; + foreach (var contentId in pageContentIds) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + pageContentInfoList.Add(ContentManager.Calculate(sequence++, contentInfo, columns, pluginColumns)); + } + } + + var permissions = new + { + IsAdd = rest.UserPermissions.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentAdd) && channelInfo.IsContentAddable, + IsDelete = rest.UserPermissions.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentDelete), + IsEdit = rest.UserPermissions.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentEdit), + IsTranslate = rest.UserPermissions.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentTranslate), + IsCheck = rest.UserPermissions.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentCheck), + IsCreate = rest.UserPermissions.HasSitePermissions(siteInfo.Id, ConfigManager.WebSitePermissions.Create) || rest.UserPermissions.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.CreatePage), + IsChannelEdit = rest.UserPermissions.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ChannelEdit) + }; + + return Ok(new + { + Value = pageContentInfoList, + Count = count, + Pages = pages, + Permissions = permissions, + Columns = columns + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerArrangeController.cs b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerArrangeController.cs new file mode 100644 index 000000000..d7fa74298 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerArrangeController.cs @@ -0,0 +1,56 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home/contentsLayerArrange")] + public class HomeContentsLayerArrangeController : ApiController + { + private const string Route = ""; + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var attributeName = Request.GetPostString("attributeName"); + var isDesc = Request.GetPostBool("isDesc"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentEdit)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + channelInfo.ContentRepository.UpdateArrangeTaxis(channelId, attributeName, isDesc); + + LogUtils.AddSiteLog(siteId, rest.AdminName, "批量整理", string.Empty); + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerAttributesController.cs b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerAttributesController.cs new file mode 100644 index 000000000..4412871c3 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerAttributesController.cs @@ -0,0 +1,136 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home/contentsLayerAttributes")] + public class HomeContentsLayerAttributesController : ApiController + { + private const string Route = ""; + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("contentIds")); + var pageType = Request.GetPostString("pageType"); + var isRecommend = Request.GetPostBool("isRecommend"); + var isHot = Request.GetPostBool("isHot"); + var isColor = Request.GetPostBool("isColor"); + var isTop = Request.GetPostBool("isTop"); + var hits = Request.GetPostInt("hits"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentEdit)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + if (pageType == "setAttributes") + { + if (isRecommend || isHot || isColor || isTop) + { + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + if (isRecommend) + { + contentInfo.Recommend = true; + } + if (isHot) + { + contentInfo.Hot = true; + } + if (isColor) + { + contentInfo.Color = true; + } + if (isTop) + { + contentInfo.Top = true; + } + DataProvider.ContentRepository.Update(siteInfo, channelInfo, contentInfo); + } + + LogUtils.AddSiteLog(siteId, rest.AdminName, "设置内容属性"); + } + } + else if(pageType == "cancelAttributes") + { + if (isRecommend || isHot || isColor || isTop) + { + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + if (isRecommend) + { + contentInfo.Recommend = false; + } + if (isHot) + { + contentInfo.Hot = false; + } + if (isColor) + { + contentInfo.Color = false; + } + if (isTop) + { + contentInfo.Top = false; + } + DataProvider.ContentRepository.Update(siteInfo, channelInfo, contentInfo); + } + + LogUtils.AddSiteLog(siteId, rest.AdminName, "取消内容属性"); + } + } + else if (pageType == "setHits") + { + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + contentInfo.Hits = hits; + DataProvider.ContentRepository.Update(siteInfo, channelInfo, contentInfo); + } + + LogUtils.AddSiteLog(siteId, rest.AdminName, "设置内容点击量"); + } + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerCheckController.cs b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerCheckController.cs new file mode 100644 index 000000000..171c29159 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerCheckController.cs @@ -0,0 +1,188 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home/contentsLayerCheck")] + public class HomeContentsLayerCheckController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetQueryString("contentIds")); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentCheck)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var retVal = new List>(); + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var dict = new Dictionary(contentInfo.ToDictionary()) + { + ["checkState"] = CheckManager.GetCheckState(siteInfo, contentInfo) + }; + retVal.Add(dict); + } + + var isChecked = CheckManager.GetUserCheckLevel(rest.AdminPermissions, siteInfo, siteId, out var checkedLevel); + var checkedLevels = CheckManager.GetCheckedLevels(siteInfo, isChecked, checkedLevel, true); + + var allChannels = + ChannelManager.GetChannels(siteId, rest.AdminPermissions, ConfigManager.ChannelPermissions.ContentAdd); + + return Ok(new + { + Value = retVal, + CheckedLevels = checkedLevels, + CheckedLevel = checkedLevel, + AllChannels = allChannels + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("contentIds")); + var checkedLevel = Request.GetPostInt("checkedLevel"); + var isTranslate = Request.GetPostBool("isTranslate"); + var translateChannelId = Request.GetPostInt("translateChannelId"); + var reasons = Request.GetPostString("reasons"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentCheck)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var isChecked = checkedLevel >= siteInfo.CheckContentLevel; + if (isChecked) + { + checkedLevel = 0; + } + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + + var contentInfoList = new List(); + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + contentInfo.Set(ContentAttribute.CheckUserName, rest.AdminName); + contentInfo.Set(ContentAttribute.CheckDate, DateTime.Now); + contentInfo.Set(ContentAttribute.CheckReasons, reasons); + + contentInfo.Checked = isChecked; + contentInfo.CheckedLevel = checkedLevel; + + if (isTranslate && translateChannelId > 0) + { + var translateChannelInfo = ChannelManager.GetChannelInfo(siteId, translateChannelId); + contentInfo.ChannelId = translateChannelInfo.Id; + DataProvider.ContentRepository.Update(siteInfo, translateChannelInfo, contentInfo); + } + else + { + DataProvider.ContentRepository.Update(siteInfo, channelInfo, contentInfo); + } + + contentInfoList.Add(contentInfo); + + var checkInfo = new ContentCheckInfo + { + TableName = tableName, + SiteId = siteId, + ChannelId = contentInfo.ChannelId, + ContentId = contentInfo.Id, + UserName = rest.AdminName, + Checked = isChecked, + CheckedLevel = checkedLevel, + CheckDate = DateTime.Now, + Reasons = reasons + }; + + DataProvider.ContentCheck.Insert(checkInfo); + } + + if (isTranslate && translateChannelId > 0) + { + ContentManager.RemoveCache(tableName, channelId); + var translateTableName = ChannelManager.GetTableName(siteInfo, translateChannelId); + ContentManager.RemoveCache(translateTableName, translateChannelId); + } + + LogUtils.AddSiteLog(siteId, rest.AdminName, "批量审核内容"); + + foreach (var contentInfo in contentInfoList) + { + CreateManager.CreateContent(siteId, contentInfo.ChannelId, contentInfo.Id); + } + CreateManager.TriggerContentChangedEvent(siteId, channelId); + if (isTranslate && translateChannelId > 0) + { + CreateManager.TriggerContentChangedEvent(siteId, translateChannelId); + } + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerColumnsController.cs b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerColumnsController.cs new file mode 100644 index 000000000..37423ead5 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerColumnsController.cs @@ -0,0 +1,96 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home/contentsLayerColumns")] + public class HomeContentsLayerColumnsController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ChannelEdit)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var attributes = ChannelManager.GetContentsColumns(siteInfo, channelInfo, true); + + return Ok(new + { + Value = attributes + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var attributeNames = Request.GetPostString("attributeNames"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ChannelEdit)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + channelInfo.ContentAttributesOfDisplay = attributeNames; + + DataProvider.Channel.Update(channelInfo); + + LogUtils.AddSiteLog(siteId, rest.AdminName, "设置内容显示项", $"显示项:{attributeNames}"); + + return Ok(new + { + Value = attributeNames + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerCopyController.cs b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerCopyController.cs new file mode 100644 index 000000000..4aaa6cdc1 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerCopyController.cs @@ -0,0 +1,180 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home/contentsLayerCopy")] + public class HomeContentsLayerCopyController : ApiController + { + private const string Route = ""; + private const string RouteGetChannels = "actions/getChannels"; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetQueryString("contentIds")); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentTranslate)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var retVal = new List>(); + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var dict = new Dictionary(contentInfo.ToDictionary()) + { + {"checkState", CheckManager.GetCheckState(siteInfo, contentInfo)} + }; + retVal.Add(dict); + } + + var sites = new List(); + var channels = new List(); + + var siteIdList = rest.UserPermissions.GetSiteIdList(); + foreach (var permissionSiteId in siteIdList) + { + var permissionSiteInfo = SiteManager.GetSiteInfo(permissionSiteId); + sites.Add(new + { + permissionSiteInfo.Id, + permissionSiteInfo.SiteName + }); + } + + var channelIdList = rest.UserPermissions.GetChannelIdList(siteInfo.Id, + ConfigManager.ChannelPermissions.ContentAdd); + foreach (var permissionChannelId in channelIdList) + { + var permissionChannelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, permissionChannelId); + channels.Add(new + { + permissionChannelInfo.Id, + ChannelName = ChannelManager.GetChannelNameNavigation(siteInfo.Id, permissionChannelId) + }); + } + + return Ok(new + { + Value = retVal, + Sites = sites, + Channels = channels, + Site = siteInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpGet, Route(RouteGetChannels)] + public IHttpActionResult GetChannels() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + + var channels = new List(); + var channelIdList = rest.UserPermissions.GetChannelIdList(siteId, + ConfigManager.ChannelPermissions.ContentAdd); + foreach (var permissionChannelId in channelIdList) + { + var permissionChannelInfo = ChannelManager.GetChannelInfo(siteId, permissionChannelId); + channels.Add(new + { + permissionChannelInfo.Id, + ChannelName = ChannelManager.GetChannelNameNavigation(siteId, permissionChannelId) + }); + } + + return Ok(new + { + Value = channels + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("contentIds")); + var targetSiteId = Request.GetPostInt("targetSiteId"); + var targetChannelId = Request.GetPostInt("targetChannelId"); + var copyType = Request.GetPostString("copyType"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentTranslate)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + foreach (var contentId in contentIdList) + { + ContentManager.Translate(siteInfo, channelId, contentId, targetSiteId, targetChannelId, ETranslateContentTypeUtils.GetEnumType(copyType)); + } + + LogUtils.AddSiteLog(siteId, channelId, rest.AdminName, "复制内容", string.Empty); + + CreateManager.TriggerContentChangedEvent(siteId, channelId); + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerCutController.cs b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerCutController.cs new file mode 100644 index 000000000..3cf95ec7e --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerCutController.cs @@ -0,0 +1,180 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home/contentsLayerCut")] + public class HomeContentsLayerCutController : ApiController + { + private const string Route = ""; + private const string RouteGetChannels = "actions/getChannels"; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetQueryString("contentIds")); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentTranslate)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var retVal = new List>(); + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var dict = new Dictionary(contentInfo.ToDictionary()) + { + {"checkState", CheckManager.GetCheckState(siteInfo, contentInfo)} + }; + retVal.Add(dict); + } + + var sites = new List(); + var channels = new List(); + + var siteIdList = rest.UserPermissions.GetSiteIdList(); + foreach (var permissionSiteId in siteIdList) + { + var permissionSiteInfo = SiteManager.GetSiteInfo(permissionSiteId); + sites.Add(new + { + permissionSiteInfo.Id, + permissionSiteInfo.SiteName + }); + } + + var channelIdList = rest.UserPermissions.GetChannelIdList(siteInfo.Id, + ConfigManager.ChannelPermissions.ContentAdd); + foreach (var permissionChannelId in channelIdList) + { + var permissionChannelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, permissionChannelId); + channels.Add(new + { + permissionChannelInfo.Id, + ChannelName = ChannelManager.GetChannelNameNavigation(siteInfo.Id, permissionChannelId) + }); + } + + return Ok(new + { + Value = retVal, + Sites = sites, + Channels = channels, + Site = siteInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpGet, Route(RouteGetChannels)] + public IHttpActionResult GetChannels() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + + var channels = new List(); + var channelIdList = rest.UserPermissions.GetChannelIdList(siteId, + ConfigManager.ChannelPermissions.ContentAdd); + foreach (var permissionChannelId in channelIdList) + { + var permissionChannelInfo = ChannelManager.GetChannelInfo(siteId, permissionChannelId); + channels.Add(new + { + permissionChannelInfo.Id, + ChannelName = ChannelManager.GetChannelNameNavigation(siteId, permissionChannelId) + }); + } + + return Ok(new + { + Value = channels + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("contentIds")); + var targetSiteId = Request.GetPostInt("targetSiteId"); + var targetChannelId = Request.GetPostInt("targetChannelId"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentTranslate)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + foreach (var contentId in contentIdList) + { + ContentManager.Translate(siteInfo, channelId, contentId, targetSiteId, targetChannelId, ETranslateContentType.Cut); + } + + LogUtils.AddSiteLog(siteId, channelId, rest.AdminName, "转移内容", string.Empty); + + CreateManager.TriggerContentChangedEvent(siteId, channelId); + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerDeleteController.cs b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerDeleteController.cs new file mode 100644 index 000000000..b99e53e94 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerDeleteController.cs @@ -0,0 +1,134 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home/contentsLayerDelete")] + public class HomeContentsLayerDeleteController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetQueryString("contentIds")); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentDelete)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var retVal = new List>(); + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var dict = new Dictionary(contentInfo.ToDictionary()) + { + {"checkState", CheckManager.GetCheckState(siteInfo, contentInfo)} + }; + retVal.Add(dict); + } + + return Ok(new + { + Value = retVal + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("contentIds")); + var isRetainFiles = Request.GetPostBool("isRetainFiles"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentDelete)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + if (!isRetainFiles) + { + DeleteManager.DeleteContents(siteInfo, channelId, contentIdList); + } + + //var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + + if (contentIdList.Count == 1) + { + var contentId = contentIdList[0]; + + if (channelInfo.ContentRepository.GetChanelIdAndValue(contentId, ContentAttribute.Title, + out var contentChannelId, out var contentTitle)) + { + LogUtils.AddSiteLog(siteId, contentChannelId, contentId, rest.AdminName, "删除内容", + $"栏目:{ChannelManager.GetChannelNameNavigation(siteId, contentChannelId)},内容标题:{contentTitle}"); + } + } + else + { + LogUtils.AddSiteLog(siteId, rest.AdminName, "批量删除内容", + $"栏目:{ChannelManager.GetChannelNameNavigation(siteId, channelId)},内容条数:{contentIdList.Count}"); + } + + channelInfo.ContentRepository.UpdateTrashContents(siteId, channelId, contentIdList); + + CreateManager.TriggerContentChangedEvent(siteId, channelId); + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerExportController.cs b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerExportController.cs new file mode 100644 index 000000000..f8fc0818b --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerExportController.cs @@ -0,0 +1,186 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Office; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.ImportExport; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home/contentsLayerExport")] + public class HomeContentsLayerExportController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentView)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var columns = ContentManager.GetContentColumns(siteInfo, channelInfo, true); + + var isChecked = CheckManager.GetUserCheckLevel(rest.AdminPermissions, siteInfo, siteId, out var checkedLevel); + var checkedLevels = CheckManager.GetCheckedLevels(siteInfo, isChecked, checkedLevel, true); + + return Ok(new + { + Value = columns, + CheckedLevels = checkedLevels, + CheckedLevel = checkedLevel + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var downloadUrl = string.Empty; + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var exportType = Request.GetPostString("exportType"); + var isAllCheckedLevel = Request.GetPostBool("isAllCheckedLevel"); + var checkedLevelKeys = Request.GetPostObject>("checkedLevelKeys"); + var isAllDate = Request.GetPostBool("isAllDate"); + var startDate = TranslateUtils.ToDateTime(Request.GetPostString("startDate"), DateTime.Now); + var endDate = TranslateUtils.ToDateTime(Request.GetPostString("endDate"), DateTime.Now); + var columnNames = Request.GetPostObject>("columnNames"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ChannelEdit)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var onlyAdminId = ((PermissionsImpl)rest.AdminPermissions).GetOnlyAdminId(siteId, channelId); + + var columns = ContentManager.GetContentColumns(siteInfo, channelInfo, true); + var pluginIds = PluginContentManager.GetContentPluginIds(channelInfo); + var pluginColumns = PluginContentManager.GetContentColumns(pluginIds); + + var contentInfoList = new List(); + var count = ContentManager.GetCount(siteInfo, channelInfo, onlyAdminId); + var pages = Convert.ToInt32(Math.Ceiling((double)count / siteInfo.PageSize)); + if (pages == 0) pages = 1; + + if (count > 0) + { + for (var page = 1; page <= pages; page++) + { + var offset = siteInfo.PageSize * (page - 1); + var limit = siteInfo.PageSize; + + var pageContentIds = ContentManager.GetContentIdList(siteInfo, channelInfo, onlyAdminId, offset, limit); + + var sequence = offset + 1; + + foreach (var contentId in pageContentIds) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + if (!isAllCheckedLevel) + { + var checkedLevel = contentInfo.CheckedLevel; + if (contentInfo.Checked) + { + checkedLevel = siteInfo.CheckContentLevel; + } + if (!checkedLevelKeys.Contains(checkedLevel)) + { + continue; + } + } + + if (!isAllDate) + { + if (contentInfo.AddDate < startDate || contentInfo.AddDate > endDate) + { + continue; + } + } + + //contentInfoList.Add(ContentManager.Calculate(sequence++, contentInfo, columns, pluginColumns)); + contentInfoList.Add(contentInfo); + } + } + + if (contentInfoList.Count > 0) + { + if (exportType == "zip") + { + var fileName = $"{channelInfo.ChannelName}.zip"; + var filePath = PathUtils.GetTemporaryFilesPath(fileName); + var exportObject = new ExportObject(siteId, rest.AdminName); + contentInfoList.Reverse(); + if (exportObject.ExportContents(filePath, contentInfoList)) + { + downloadUrl = FxUtils.GetTemporaryFilesUrl(fileName); + } + } + else if (exportType == "excel") + { + var fileName = $"{channelInfo.ChannelName}.csv"; + var filePath = PathUtils.GetTemporaryFilesPath(fileName); + ExcelObject.CreateExcelFileForContents(filePath, siteInfo, channelInfo, contentInfoList, columnNames); + downloadUrl = FxUtils.GetTemporaryFilesUrl(fileName); + } + } + } + + return Ok(new + { + Value = downloadUrl, + IsSuccess = !string.IsNullOrEmpty(downloadUrl) + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerGroupController.cs b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerGroupController.cs new file mode 100644 index 000000000..e36cbff42 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerGroupController.cs @@ -0,0 +1,169 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home/contentsLayerGroup")] + public class HomeContentsLayerGroupController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentDelete)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var contentGroupNameList = ContentGroupManager.GetGroupNameList(siteId); + + return Ok(new + { + Value = contentGroupNameList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("contentIds")); + var pageType = Request.GetPostString("pageType"); + var groupNames = TranslateUtils.StringCollectionToStringList(Request.GetPostString("groupNames")); + var groupName = Request.GetPostString("groupName"); + var description = Request.GetPostString("description"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentEdit)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + if (pageType == "setGroup") + { + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var list = TranslateUtils.StringCollectionToStringList(contentInfo.GroupNameCollection); + foreach (var name in groupNames) + { + if (!list.Contains(name)) list.Add(name); + } + contentInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(list); + + DataProvider.ContentRepository.Update(siteInfo, channelInfo, contentInfo); + } + + LogUtils.AddSiteLog(siteId, rest.AdminName, "批量设置内容组", $"内容组:{TranslateUtils.ObjectCollectionToString(groupNames)}"); + } + else if(pageType == "cancelGroup") + { + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var list = TranslateUtils.StringCollectionToStringList(contentInfo.GroupNameCollection); + foreach (var name in groupNames) + { + if (list.Contains(name)) list.Remove(name); + } + contentInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(list); + + DataProvider.ContentRepository.Update(siteInfo, channelInfo, contentInfo); + } + + LogUtils.AddSiteLog(siteId, rest.AdminName, "批量取消内容组", $"内容组:{TranslateUtils.ObjectCollectionToString(groupNames)}"); + } + else if (pageType == "addGroup") + { + var groupInfo = new ContentGroupInfo + { + GroupName = AttackUtils.FilterXss(groupName), + SiteId = siteId, + Description = AttackUtils.FilterXss(description) + }; + + if (ContentGroupManager.IsExists(siteId, groupInfo.GroupName)) + { + DataProvider.ContentGroup.Update(groupInfo); + LogUtils.AddSiteLog(siteId, rest.AdminName, "修改内容组", $"内容组:{groupInfo.GroupName}"); + } + else + { + DataProvider.ContentGroup.Insert(groupInfo); + LogUtils.AddSiteLog(siteId, rest.AdminName, "添加内容组", $"内容组:{groupInfo.GroupName}"); + } + + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var list = TranslateUtils.StringCollectionToStringList(contentInfo.GroupNameCollection); + if (!list.Contains(groupInfo.GroupName)) list.Add(groupInfo.GroupName); + contentInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(list); + + DataProvider.ContentRepository.Update(siteInfo, channelInfo, contentInfo); + } + + LogUtils.AddSiteLog(siteId, rest.AdminName, "批量设置内容组", $"内容组:{groupInfo.GroupName}"); + } + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerImportController.cs b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerImportController.cs new file mode 100644 index 000000000..4d08a4a29 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerImportController.cs @@ -0,0 +1,211 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Web; +using System.Web.Http; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.ImportExport; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home/contentsLayerImport")] + public class HomeContentsLayerImportController : ApiController + { + private const string Route = ""; + private const string RouteUpload = "actions/upload"; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var isChecked = CheckManager.GetUserCheckLevel(rest.AdminPermissions, siteInfo, siteId, out var checkedLevel); + var checkedLevels = CheckManager.GetCheckedLevels(siteInfo, isChecked, checkedLevel, true); + + return Ok(new + { + Value = checkedLevel, + CheckedLevels = checkedLevels + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteUpload)] + public IHttpActionResult Upload() + { + try + { +#pragma warning disable CS0612 // '“RequestImpl”已过时 + var request = new RequestImpl(HttpContext.Current.Request); +#pragma warning restore CS0612 // '“RequestImpl”已过时 + + var siteId = request.GetQueryInt("siteId"); + var channelId = request.GetQueryInt("channelId"); + + if (!request.IsUserLoggin || + !request.UserPermissionsImpl.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd)) + { + return Unauthorized(); + } + + var fileName = request.HttpRequest["fileName"]; + var fileCount = request.HttpRequest.Files.Count; + string filePath = null; + + if (fileCount > 0) + { + var file = request.HttpRequest.Files[0]; + + if (string.IsNullOrEmpty(fileName)) fileName = Path.GetFileName(file.FileName); + + var extendName = fileName.Substring(fileName.LastIndexOf(".", StringComparison.Ordinal)).ToLower(); + if (extendName == ".zip" || extendName == ".csv" || extendName == ".txt") + { + filePath = PathUtils.GetTemporaryFilesPath(fileName); + DirectoryUtils.CreateDirectoryIfNotExists(filePath); + file.SaveAs(filePath); + } + } + + FileInfo fileInfo = null; + if (!string.IsNullOrEmpty(filePath)) + { + fileInfo = new FileInfo(filePath); + } + if (fileInfo != null) + { + return Ok(new + { + fileName, + length = fileInfo.Length, + ret = 1 + }); + } + + return Ok(new + { + ret = 0 + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var importType = Request.GetPostString("importType"); + var checkedLevel = Request.GetPostInt("checkedLevel"); + var isOverride = Request.GetPostBool("isOverride"); + var fileNames = Request.GetPostObject>("fileNames"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var isChecked = checkedLevel >= siteInfo.CheckContentLevel; + + if (importType == "zip") + { + foreach (var fileName in fileNames) + { + var localFilePath = PathUtils.GetTemporaryFilesPath(fileName); + + if (!EFileSystemTypeUtils.Equals(EFileSystemType.Zip, PathUtils.GetExtension(localFilePath))) + continue; + + var importObject = new ImportObject(siteId, rest.AdminName); + importObject.ImportContentsByZipFile(channelInfo, localFilePath, isOverride, isChecked, checkedLevel, rest.AdminId, rest.UserId, SourceManager.User); + } + } + + else if (importType == "csv") + { + foreach (var fileName in fileNames) + { + var localFilePath = PathUtils.GetTemporaryFilesPath(fileName); + + if (!EFileSystemTypeUtils.Equals(EFileSystemType.Csv, PathUtils.GetExtension(localFilePath))) + continue; + + var importObject = new ImportObject(siteId, rest.AdminName); + importObject.ImportContentsByCsvFile(channelInfo, localFilePath, isOverride, isChecked, checkedLevel, rest.AdminId, rest.UserId, SourceManager.User); + } + } + else if (importType == "txt") + { + foreach (var fileName in fileNames) + { + var localFilePath = PathUtils.GetTemporaryFilesPath(fileName); + if (!EFileSystemTypeUtils.Equals(EFileSystemType.Txt, PathUtils.GetExtension(localFilePath))) + continue; + + var importObject = new ImportObject(siteId, rest.AdminName); + importObject.ImportContentsByTxtFile(channelInfo, localFilePath, isOverride, isChecked, checkedLevel, rest.AdminId, rest.UserId, SourceManager.User); + } + } + + LogUtils.AddSiteLog(siteId, channelId, rest.AdminName, "导入内容", string.Empty); + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerStateController.cs b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerStateController.cs new file mode 100644 index 000000000..ae0bf8a2c --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerStateController.cs @@ -0,0 +1,66 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home/contentsLayerState")] + public class HomeContentsLayerStateController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + var contentId = Request.GetQueryInt("contentId"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentView)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) return BadRequest("无法确定对应的内容"); + + var title = contentInfo.Title; + var checkState = + CheckManager.GetCheckState(siteInfo, contentInfo); + + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + var contentChecks = DataProvider.ContentCheck.GetCheckInfoList(tableName, contentId); + + return Ok(new + { + Value = contentChecks, + Title = title, + CheckState = checkState + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerTaxisController.cs b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerTaxisController.cs new file mode 100644 index 000000000..3aa8e8a21 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerTaxisController.cs @@ -0,0 +1,96 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home/contentsLayerTaxis")] + public class HomeContentsLayerTaxisController : ApiController + { + private const string Route = ""; + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("contentIds")); + var isUp = Request.GetPostBool("isUp"); + var taxis = Request.GetPostInt("taxis"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentEdit)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + if (ETaxisTypeUtils.Equals(channelInfo.DefaultTaxisType, ETaxisType.OrderByTaxis)) + { + isUp = !isUp; + } + + if (isUp == false) + { + contentIdList.Reverse(); + } + + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var isTop = contentInfo.Top; + for (var i = 1; i <= taxis; i++) + { + if (isUp) + { + if (channelInfo.ContentRepository.SetTaxisToUp(channelId, contentId, isTop) == false) + { + break; + } + } + else + { + if (channelInfo.ContentRepository.SetTaxisToDown(channelId, contentId, isTop) == false) + { + break; + } + } + } + } + + CreateManager.TriggerContentChangedEvent(siteId, channelId); + + LogUtils.AddSiteLog(siteId, channelId, rest.AdminName, "对内容排序", string.Empty); + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerViewController.cs b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerViewController.cs new file mode 100644 index 000000000..35c2bb3e9 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerViewController.cs @@ -0,0 +1,68 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home/contentsLayerView")] + public class HomeContentsLayerViewController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + var contentId = Request.GetQueryInt("contentId"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentView)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) return BadRequest("无法确定对应的内容"); + + var dict = new Dictionary(contentInfo.ToDictionary()) + { + {"checkState", CheckManager.GetCheckState(siteInfo, contentInfo)} + }; + + var channelName = ChannelManager.GetChannelNameNavigation(siteId, channelId); + + var attributes = ChannelManager.GetContentsColumns(siteInfo, channelInfo, true); + + return Ok(new + { + Value = dict, + ChannelName = channelName, + Attributes = attributes + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerWordController.cs b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerWordController.cs new file mode 100644 index 000000000..c0805b4c2 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeContentsLayerWordController.cs @@ -0,0 +1,226 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Web; +using System.Web.Http; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.Office; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home/contentsLayerWord")] + public class HomeContentsLayerWordController : ApiController + { + private const string Route = ""; + private const string RouteUpload = "actions/upload"; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var isChecked = CheckManager.GetUserCheckLevel(rest.AdminPermissions, siteInfo, siteId, out var checkedLevel); + var checkedLevels = CheckManager.GetCheckedLevels(siteInfo, isChecked, checkedLevel, false); + + return Ok(new + { + Value = checkedLevels, + CheckedLevel = CheckManager.LevelInt.CaoGao + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteUpload)] + public IHttpActionResult Upload() + { + try + { +#pragma warning disable CS0612 // '“RequestImpl”已过时 + var request = new RequestImpl(HttpContext.Current.Request); +#pragma warning restore CS0612 // '“RequestImpl”已过时 + + var siteId = request.GetQueryInt("siteId"); + var channelId = request.GetQueryInt("channelId"); + + if (!request.IsUserLoggin || + !request.UserPermissionsImpl.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd)) + { + return Unauthorized(); + } + + var fileName = request.HttpRequest["fileName"]; + + var fileCount = request.HttpRequest.Files.Count; + + string filePath = null; + + if (fileCount > 0) + { + var file = request.HttpRequest.Files[0]; + + if (string.IsNullOrEmpty(fileName)) fileName = Path.GetFileName(file.FileName); + + var extendName = fileName.Substring(fileName.LastIndexOf(".", StringComparison.Ordinal)).ToLower(); + if (extendName == ".doc" || extendName == ".docx") + { + filePath = PathUtils.GetTemporaryFilesPath(fileName); + DirectoryUtils.CreateDirectoryIfNotExists(filePath); + file.SaveAs(filePath); + } + } + + FileInfo fileInfo = null; + if (!string.IsNullOrEmpty(filePath)) + { + fileInfo = new FileInfo(filePath); + } + if (fileInfo != null) + { + return Ok(new + { + fileName, + length = fileInfo.Length, + ret = 1 + }); + } + + return Ok(new + { + ret = 0 + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var isFirstLineTitle = Request.GetPostBool("isFirstLineTitle"); + var isFirstLineRemove = Request.GetPostBool("isFirstLineRemove"); + var isClearFormat = Request.GetPostBool("isClearFormat"); + var isFirstLineIndent = Request.GetPostBool("isFirstLineIndent"); + var isClearFontSize = Request.GetPostBool("isClearFontSize"); + var isClearFontFamily = Request.GetPostBool("isClearFontFamily"); + var isClearImages = Request.GetPostBool("isClearImages"); + var checkedLevel = Request.GetPostInt("checkedLevel"); + var fileNames = TranslateUtils.StringCollectionToStringList(Request.GetPostString("fileNames")); + + if (!rest.IsUserLoggin || + !rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + var styleInfoList = TableStyleManager.GetContentStyleInfoList(siteInfo, channelInfo); + var isChecked = checkedLevel >= siteInfo.CheckContentLevel; + + var contentIdList = new List(); + + foreach (var fileName in fileNames) + { + if (string.IsNullOrEmpty(fileName)) continue; + + var formCollection = WordUtils.GetWordNameValueCollection(siteId, isFirstLineTitle, isFirstLineRemove, isClearFormat, isFirstLineIndent, isClearFontSize, isClearFontFamily, isClearImages, fileName); + + if (string.IsNullOrEmpty(formCollection[ContentAttribute.Title])) continue; + + var dict = BackgroundInputTypeParser.SaveAttributes(siteInfo, styleInfoList, formCollection, ContentAttribute.AllAttributes.Value); + + var contentInfo = new ContentInfo(dict) + { + ChannelId = channelInfo.Id, + SiteId = siteId, + AddUserName = rest.AdminName, + AddDate = DateTime.Now, + SourceId = SourceManager.User, + AdminId = rest.AdminId, + UserId = rest.UserId, + Checked = isChecked, + CheckedLevel = checkedLevel + }; + + contentInfo.LastEditUserName = contentInfo.AddUserName; + contentInfo.LastEditDate = contentInfo.AddDate; + + contentInfo.Title = formCollection[ContentAttribute.Title]; + + contentInfo.Id = DataProvider.ContentRepository.Insert(tableName, siteInfo, channelInfo, contentInfo); + + contentIdList.Add(contentInfo.Id); + } + + if (isChecked) + { + foreach (var contentId in contentIdList) + { + CreateManager.CreateContent(siteId, channelInfo.Id, contentId); + } + CreateManager.TriggerContentChangedEvent(siteId, channelInfo.Id); + } + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Home/HomeController.cs b/net452/SiteServer.Web/Controllers/Home/HomeController.cs new file mode 100644 index 000000000..6ba1aac53 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Home/HomeController.cs @@ -0,0 +1,356 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Home +{ + [RoutePrefix("home")] + public class HomeController : ApiController + { + private const string Route = ""; + + private const string PageNameRegister = "register"; + private const string PageNameIndex = "index"; + private const string PageNameProfile = "profile"; + private const string PageNameContents = "contents"; + private const string PageNameContentAdd = "contentAdd"; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var pageName = Request.GetQueryString("pageName"); + + if (pageName == PageNameRegister) + { + return Ok(GetRegister(rest)); + } + if (pageName == PageNameIndex) + { + return Ok(GetIndex(rest)); + } + if (pageName == PageNameProfile) + { + return Ok(GetProfile(rest)); + } + if (pageName == PageNameContents) + { + return Ok(GetContents(rest)); + } + if (pageName == PageNameContentAdd) + { + return Ok(GetContentAdd(rest)); + } + + var userInfo = UserManager.GetUserInfoByUserId(rest.UserId); + return Ok(new + { + Value = userInfo, + Config = ConfigManager.Instance + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + public object GetRegister(IAuthenticatedRequest rest) + { + var userInfo = UserManager.GetUserInfoByUserId(rest.UserId); + return new + { + Value = userInfo, + Config = ConfigManager.Instance, + Styles = TableStyleManager.GetUserStyleInfoList(), + Groups = UserGroupManager.GetUserGroupInfoList() + }; + } + + public object GetIndex(IAuthenticatedRequest rest) + { + var menus = new List(); + var defaultPageUrl = string.Empty; + IUserInfo userInfo = null; + + if (rest.IsUserLoggin) + { + userInfo = UserManager.GetUserInfoByUserId(rest.UserId); + + var userMenus = UserMenuManager.GetAllUserMenuInfoList(); + foreach (var menuInfo1 in userMenus) + { + if (menuInfo1.Disabled || menuInfo1.ParentId != 0 || + !string.IsNullOrEmpty(menuInfo1.GroupIdCollection) && + !StringUtils.In(menuInfo1.GroupIdCollection, userInfo.GroupId)) continue; + var children = new List(); + foreach (var menuInfo2 in userMenus) + { + if (menuInfo2.Disabled || menuInfo2.ParentId != menuInfo1.Id || + !string.IsNullOrEmpty(menuInfo2.GroupIdCollection) && + !StringUtils.In(menuInfo2.GroupIdCollection, userInfo.GroupId)) continue; + + children.Add(new + { + menuInfo2.Text, + menuInfo2.IconClass, + menuInfo2.Href, + menuInfo2.Target + }); + } + + menus.Add(new + { + menuInfo1.Text, + menuInfo1.IconClass, + menuInfo1.Href, + menuInfo1.Target, + Menus = children + }); + } + + defaultPageUrl = PluginMenuManager.GetHomeDefaultPageUrl(); + } + + return new + { + Value = userInfo, + Config = ConfigManager.Instance, + Menus = menus, + DefaultPageUrl = defaultPageUrl + }; + } + + public object GetProfile(IAuthenticatedRequest rest) + { + var userInfo = UserManager.GetUserInfoByUserId(rest.UserId); + + return new + { + Value = userInfo, + Config = ConfigManager.Instance, + Styles = TableStyleManager.GetUserStyleInfoList() + }; + } + + public object GetContents(IAuthenticatedRequest rest) + { + var requestSiteId = Request.GetQueryInt("siteId"); + var requestChannelId = Request.GetQueryInt("channelId"); + + var sites = new List(); + var channels = new List(); + object site = null; + object channel = null; + + IUserInfo userInfo = null; + if (rest.IsUserLoggin) + { + userInfo = UserManager.GetUserInfoByUserId(rest.UserId); + SiteInfo siteInfo = null; + ChannelInfo channelInfo = null; + var siteIdList = rest.UserPermissions.GetSiteIdList(); + foreach (var siteId in siteIdList) + { + var permissionSiteInfo = SiteManager.GetSiteInfo(siteId); + if (requestSiteId == siteId) + { + siteInfo = permissionSiteInfo; + } + sites.Add(new + { + permissionSiteInfo.Id, + permissionSiteInfo.SiteName + }); + } + + if (siteInfo == null && siteIdList.Count > 0) + { + siteInfo = SiteManager.GetSiteInfo(siteIdList[0]); + } + + if (siteInfo != null) + { + var channelIdList = rest.UserPermissions.GetChannelIdList(siteInfo.Id, + ConfigManager.ChannelPermissions.ContentAdd); + foreach (var permissionChannelId in channelIdList) + { + var permissionChannelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, permissionChannelId); + if (channelInfo == null || requestChannelId == permissionChannelId) + { + channelInfo = permissionChannelInfo; + } + channels.Add(new + { + permissionChannelInfo.Id, + ChannelName = ChannelManager.GetChannelNameNavigation(siteInfo.Id, permissionChannelId) + }); + } + + site = new + { + siteInfo.Id, + siteInfo.SiteName, + SiteUrl = PageUtility.GetSiteUrl(siteInfo, false) + }; + } + + if (channelInfo != null) + { + channel = new + { + channelInfo.Id, + ChannelName = ChannelManager.GetChannelNameNavigation(siteInfo.Id, channelInfo.Id) + }; + } + } + + return new + { + Value = userInfo, + Config = ConfigManager.Instance, + Sites = sites, + Channels = channels, + Site = site, + Channel = channel + }; + } + + public object GetContentAdd(IAuthenticatedRequest rest) + { + var requestSiteId = Request.GetQueryInt("siteId"); + var requestChannelId = Request.GetQueryInt("channelId"); + var requestContentId = Request.GetQueryInt("contentId"); + + var sites = new List(); + var channels = new List(); + object site = null; + object channel = null; + List groupNames = null; + List tagNames = null; + ContentInfo contentInfo = null; + List styles = null; + List> checkedLevels = null; + var checkedLevel = 0; + + IUserInfo userInfo = null; + if (rest.IsUserLoggin) + { + userInfo = UserManager.GetUserInfoByUserId(rest.UserId); + SiteInfo siteInfo = null; + ChannelInfo channelInfo = null; + var siteIdList = rest.UserPermissions.GetSiteIdList(); + foreach (var siteId in siteIdList) + { + var permissionSiteInfo = SiteManager.GetSiteInfo(siteId); + if (requestSiteId == siteId) + { + siteInfo = permissionSiteInfo; + } + sites.Add(new + { + permissionSiteInfo.Id, + permissionSiteInfo.SiteName + }); + } + + if (siteInfo == null && siteIdList.Count > 0) + { + siteInfo = SiteManager.GetSiteInfo(siteIdList[0]); + } + + if (siteInfo != null) + { + var channelIdList = rest.UserPermissions.GetChannelIdList(siteInfo.Id, + ConfigManager.ChannelPermissions.ContentAdd); + foreach (var permissionChannelId in channelIdList) + { + var permissionChannelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, permissionChannelId); + if (channelInfo == null || permissionChannelInfo.Id == requestChannelId) + { + channelInfo = permissionChannelInfo; + } + channels.Add(new + { + permissionChannelInfo.Id, + ChannelName = ChannelManager.GetChannelNameNavigation(siteInfo.Id, permissionChannelId) + }); + } + + site = new + { + siteInfo.Id, + siteInfo.SiteName, + SiteUrl = PageUtility.GetSiteUrl(siteInfo, false) + }; + + groupNames = ContentGroupManager.GetGroupNameList(siteInfo.Id); + tagNames = ContentTagManager.GetTagNameList(siteInfo.Id); + } + + if (channelInfo != null) + { + channel = new + { + channelInfo.Id, + ChannelName = ChannelManager.GetChannelNameNavigation(siteInfo.Id, channelInfo.Id) + }; + + styles = TableStyleManager.GetContentStyleInfoList(siteInfo, channelInfo); + + var checkKeyValuePair = CheckManager.GetUserCheckLevel(rest.AdminPermissions, siteInfo, siteInfo.Id); + checkedLevels = CheckManager.GetCheckedLevels(siteInfo, checkKeyValuePair.Key, checkedLevel, true); + + if (requestContentId != 0) + { + checkedLevels.Insert(0, new KeyValuePair(CheckManager.LevelInt.NotChange, CheckManager.Level.NotChange)); + checkedLevel = CheckManager.LevelInt.NotChange; + + contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, requestContentId); + if (contentInfo != null && + (contentInfo.SiteId != siteInfo.Id || contentInfo.ChannelId != channelInfo.Id)) + { + contentInfo = null; + } + } + else + { + contentInfo = new ContentInfo + { + Id = 0, + SiteId = siteInfo.Id, + ChannelId = channelInfo.Id, + AddDate = DateTime.Now + }; + } + } + } + + return new + { + Value = userInfo, + Config = ConfigManager.Instance, + Sites = sites, + Channels = channels, + Site = site, + Channel = channel, + AllGroupNames = groupNames, + AllTagNames = tagNames, + Styles = styles, + CheckedLevels = checkedLevels, + CheckedLevel = checkedLevel, + Content = contentInfo, + }; + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsController.cs new file mode 100644 index 000000000..18f848a87 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsController.cs @@ -0,0 +1,147 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/contents")] + public class PagesContentsController : ApiController + { + private const string Route = ""; + private const string RouteCreate = "actions/create"; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + var page = Request.GetQueryInt("page"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentView)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var onlyAdminId = ((PermissionsImpl)rest.AdminPermissions).GetOnlyAdminId(siteId, channelId); + + var pluginIds = PluginContentManager.GetContentPluginIds(channelInfo); + var pluginColumns = PluginContentManager.GetContentColumns(pluginIds); + + var columns = ContentManager.GetContentColumns(siteInfo, channelInfo, false); + + var pageContentInfoList = new List>(); + var count = ContentManager.GetCount(siteInfo, channelInfo, onlyAdminId); + + var pages = Convert.ToInt32(Math.Ceiling((double)count / siteInfo.PageSize)); + if (pages == 0) pages = 1; + + if (count > 0) + { + var offset = siteInfo.PageSize * (page - 1); + var limit = siteInfo.PageSize; + + var pageContentIds = ContentManager.GetContentIdList(siteInfo, channelInfo, onlyAdminId, offset, limit); + + var sequence = offset + 1; + foreach (var contentId in pageContentIds) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var menus = PluginMenuManager.GetContentMenus(pluginIds, contentInfo); + contentInfo.Set("PluginMenus", menus); + + pageContentInfoList.Add(ContentManager.Calculate(sequence++, contentInfo, columns, pluginColumns)); + } + } + + var permissions = new + { + IsAdd = rest.AdminPermissions.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentAdd) && channelInfo.IsContentAddable, + IsDelete = rest.AdminPermissions.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentDelete), + IsEdit = rest.AdminPermissions.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentEdit), + IsTranslate = rest.AdminPermissions.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentTranslate), + IsCheck = rest.AdminPermissions.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ContentCheck), + IsCreate = rest.AdminPermissions.HasSitePermissions(siteInfo.Id, ConfigManager.WebSitePermissions.Create) || rest.AdminPermissions.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.CreatePage), + IsChannelEdit = rest.AdminPermissions.HasChannelPermissions(siteInfo.Id, channelInfo.Id, ConfigManager.ChannelPermissions.ChannelEdit) + }; + + return Ok(new + { + Value = pageContentInfoList, + Count = count, + Pages = pages, + Permissions = permissions, + Columns = columns + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteCreate)] + public IHttpActionResult Create() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("contentIds")); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentDelete)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + foreach (var contentId in contentIdList) + { + CreateManager.CreateContent(siteId, channelInfo.Id, contentId); + } + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerArrangeController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerArrangeController.cs new file mode 100644 index 000000000..90805f50d --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerArrangeController.cs @@ -0,0 +1,58 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Repositories.Contents; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/contentsLayerArrange")] + public class PagesContentsLayerArrangeController : ApiController + { + private const string Route = ""; + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var attributeName = Request.GetPostString("attributeName"); + var isDesc = Request.GetPostBool("isDesc"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentEdit)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + channelInfo.ContentRepository.UpdateArrangeTaxis(channelId, attributeName, isDesc); + + LogUtils.AddSiteLog(siteId, rest.AdminName, "批量整理", string.Empty); + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerAttributesController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerAttributesController.cs new file mode 100644 index 000000000..64195233f --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerAttributesController.cs @@ -0,0 +1,135 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/contentsLayerAttributes")] + public class PagesContentsLayerAttributesController : ApiController + { + private const string Route = ""; + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("contentIds")); + var pageType = Request.GetPostString("pageType"); + var isRecommend = Request.GetPostBool("isRecommend"); + var isHot = Request.GetPostBool("isHot"); + var isColor = Request.GetPostBool("isColor"); + var isTop = Request.GetPostBool("isTop"); + var hits = Request.GetPostInt("hits"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentEdit)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + if (pageType == "setAttributes") + { + if (isRecommend || isHot || isColor || isTop) + { + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + if (isRecommend) + { + contentInfo.Recommend = true; + } + if (isHot) + { + contentInfo.Hot = true; + } + if (isColor) + { + contentInfo.Color = true; + } + if (isTop) + { + contentInfo.Top = true; + } + DataProvider.ContentRepository.Update(siteInfo, channelInfo, contentInfo); + } + + LogUtils.AddSiteLog(siteId, rest.AdminName, "设置内容属性"); + } + } + else if(pageType == "cancelAttributes") + { + if (isRecommend || isHot || isColor || isTop) + { + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + if (isRecommend) + { + contentInfo.Recommend = false; + } + if (isHot) + { + contentInfo.Hot = false; + } + if (isColor) + { + contentInfo.Color = false; + } + if (isTop) + { + contentInfo.Top = false; + } + DataProvider.ContentRepository.Update(siteInfo, channelInfo, contentInfo); + } + + LogUtils.AddSiteLog(siteId, rest.AdminName, "取消内容属性"); + } + } + else if (pageType == "setHits") + { + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + contentInfo.Hits = hits; + DataProvider.ContentRepository.Update(siteInfo, channelInfo, contentInfo); + } + + LogUtils.AddSiteLog(siteId, rest.AdminName, "设置内容点击量"); + } + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerCheckController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerCheckController.cs new file mode 100644 index 000000000..7bdb403e3 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerCheckController.cs @@ -0,0 +1,190 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/contentsLayerCheck")] + public class PagesContentsLayerCheckController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetQueryString("contentIds")); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentCheck)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var retVal = new List>(); + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var dict = new Dictionary(contentInfo.ToDictionary()) + { + {"title", WebUtils.GetContentTitle(siteInfo, contentInfo, string.Empty)}, + {"checkState", CheckManager.GetCheckState(siteInfo, contentInfo)} + }; + retVal.Add(dict); + } + + var isChecked = CheckManager.GetUserCheckLevel(rest.AdminPermissions, siteInfo, siteId, out var checkedLevel); + var checkedLevels = CheckManager.GetCheckedLevels(siteInfo, isChecked, checkedLevel, true); + + var allChannels = + ChannelManager.GetChannels(siteId, rest.AdminPermissions, ConfigManager.ChannelPermissions.ContentAdd); + + return Ok(new + { + Value = retVal, + CheckedLevels = checkedLevels, + CheckedLevel = checkedLevel, + AllChannels = allChannels + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("contentIds")); + var checkedLevel = Request.GetPostInt("checkedLevel"); + var isTranslate = Request.GetPostBool("isTranslate"); + var translateChannelId = Request.GetPostInt("translateChannelId"); + var reasons = Request.GetPostString("reasons"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentCheck)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var isChecked = checkedLevel >= siteInfo.CheckContentLevel; + if (isChecked) + { + checkedLevel = 0; + } + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + + var contentInfoList = new List(); + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + contentInfo.Set(ContentAttribute.CheckUserName, rest.AdminName); + contentInfo.Set(ContentAttribute.CheckDate, DateTime.Now); + contentInfo.Set(ContentAttribute.CheckReasons, reasons); + + contentInfo.Checked = isChecked; + contentInfo.CheckedLevel = checkedLevel; + + if (isTranslate && translateChannelId > 0) + { + var translateChannelInfo = ChannelManager.GetChannelInfo(siteId, translateChannelId); + contentInfo.ChannelId = translateChannelInfo.Id; + DataProvider.ContentRepository.Update(siteInfo, translateChannelInfo, contentInfo); + } + else + { + DataProvider.ContentRepository.Update(siteInfo, channelInfo, contentInfo); + } + + contentInfoList.Add(contentInfo); + + var checkInfo = new ContentCheckInfo + { + TableName = tableName, + SiteId = siteId, + ChannelId = contentInfo.ChannelId, + ContentId = contentInfo.Id, + UserName = rest.AdminName, + Checked = isChecked, + CheckedLevel = checkedLevel, + CheckDate = DateTime.Now, + Reasons = reasons + }; + + DataProvider.ContentCheck.Insert(checkInfo); + } + + if (isTranslate && translateChannelId > 0) + { + ContentManager.RemoveCache(tableName, channelId); + var translateTableName = ChannelManager.GetTableName(siteInfo, translateChannelId); + ContentManager.RemoveCache(translateTableName, translateChannelId); + } + + LogUtils.AddSiteLog(siteId, rest.AdminName, "批量审核内容"); + + foreach (var contentInfo in contentInfoList) + { + CreateManager.CreateContent(siteId, contentInfo.ChannelId, contentInfo.Id); + } + CreateManager.TriggerContentChangedEvent(siteId, channelId); + if (isTranslate && translateChannelId > 0) + { + CreateManager.TriggerContentChangedEvent(siteId, translateChannelId); + } + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerColumnsController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerColumnsController.cs new file mode 100644 index 000000000..085d2c18f --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerColumnsController.cs @@ -0,0 +1,96 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/contentsLayerColumns")] + public class PagesContentsLayerColumnsController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ChannelEdit)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var attributes = ChannelManager.GetContentsColumns(siteInfo, channelInfo, true); + + return Ok(new + { + Value = attributes + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var attributeNames = Request.GetPostString("attributeNames"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ChannelEdit)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + channelInfo.ContentAttributesOfDisplay = attributeNames; + + DataProvider.Channel.Update(channelInfo); + + LogUtils.AddSiteLog(siteId, rest.AdminName, "设置内容显示项", $"显示项:{attributeNames}"); + + return Ok(new + { + Value = attributeNames + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerCopyController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerCopyController.cs new file mode 100644 index 000000000..5b1439aad --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerCopyController.cs @@ -0,0 +1,181 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/contentsLayerCopy")] + public class PagesContentsLayerCopyController : ApiController + { + private const string Route = ""; + private const string RouteGetChannels = "actions/getChannels"; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetQueryString("contentIds")); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentTranslate)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var retVal = new List>(); + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var dict = new Dictionary(contentInfo.ToDictionary()) + { + {"checkState", CheckManager.GetCheckState(siteInfo, contentInfo)} + }; + retVal.Add(dict); + } + + var sites = new List(); + var channels = new List(); + + var siteIdList = rest.AdminPermissions.GetSiteIdList(); + foreach (var permissionSiteId in siteIdList) + { + var permissionSiteInfo = SiteManager.GetSiteInfo(permissionSiteId); + sites.Add(new + { + permissionSiteInfo.Id, + permissionSiteInfo.SiteName + }); + } + + var channelIdList = rest.AdminPermissions.GetChannelIdList(siteInfo.Id, + ConfigManager.ChannelPermissions.ContentAdd); + foreach (var permissionChannelId in channelIdList) + { + var permissionChannelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, permissionChannelId); + channels.Add(new + { + permissionChannelInfo.Id, + ChannelName = ChannelManager.GetChannelNameNavigation(siteInfo.Id, permissionChannelId) + }); + } + + return Ok(new + { + Value = retVal, + Sites = sites, + Channels = channels, + Site = siteInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpGet, Route(RouteGetChannels)] + public IHttpActionResult GetChannels() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + + var channels = new List(); + var channelIdList = rest.AdminPermissions.GetChannelIdList(siteId, + ConfigManager.ChannelPermissions.ContentAdd); + foreach (var permissionChannelId in channelIdList) + { + var permissionChannelInfo = ChannelManager.GetChannelInfo(siteId, permissionChannelId); + channels.Add(new + { + permissionChannelInfo.Id, + ChannelName = ChannelManager.GetChannelNameNavigation(siteId, permissionChannelId) + }); + } + + return Ok(new + { + Value = channels + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("contentIds")); + var targetSiteId = Request.GetPostInt("targetSiteId"); + var targetChannelId = Request.GetPostInt("targetChannelId"); + var copyType = Request.GetPostString("copyType"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentTranslate)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + foreach (var contentId in contentIdList) + { + ContentManager.Translate(siteInfo, channelId, contentId, targetSiteId, targetChannelId, ETranslateContentTypeUtils.GetEnumType(copyType)); + } + + LogUtils.AddSiteLog(siteId, channelId, rest.AdminName, "复制内容", string.Empty); + + CreateManager.TriggerContentChangedEvent(siteId, channelId); + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerCutController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerCutController.cs new file mode 100644 index 000000000..6e3f0fe87 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerCutController.cs @@ -0,0 +1,180 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/contentsLayerCut")] + public class PagesContentsLayerCutController : ApiController + { + private const string Route = ""; + private const string RouteGetChannels = "actions/getChannels"; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetQueryString("contentIds")); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentTranslate)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var retVal = new List>(); + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var dict = new Dictionary(contentInfo.ToDictionary()) + { + {"checkState", CheckManager.GetCheckState(siteInfo, contentInfo)} + }; + retVal.Add(dict); + } + + var sites = new List(); + var channels = new List(); + + var siteIdList = rest.AdminPermissions.GetSiteIdList(); + foreach (var permissionSiteId in siteIdList) + { + var permissionSiteInfo = SiteManager.GetSiteInfo(permissionSiteId); + sites.Add(new + { + permissionSiteInfo.Id, + permissionSiteInfo.SiteName + }); + } + + var channelIdList = rest.AdminPermissions.GetChannelIdList(siteInfo.Id, + ConfigManager.ChannelPermissions.ContentAdd); + foreach (var permissionChannelId in channelIdList) + { + var permissionChannelInfo = ChannelManager.GetChannelInfo(siteInfo.Id, permissionChannelId); + channels.Add(new + { + permissionChannelInfo.Id, + ChannelName = ChannelManager.GetChannelNameNavigation(siteInfo.Id, permissionChannelId) + }); + } + + return Ok(new + { + Value = retVal, + Sites = sites, + Channels = channels, + Site = siteInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpGet, Route(RouteGetChannels)] + public IHttpActionResult GetChannels() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + + var channels = new List(); + var channelIdList = rest.AdminPermissions.GetChannelIdList(siteId, + ConfigManager.ChannelPermissions.ContentAdd); + foreach (var permissionChannelId in channelIdList) + { + var permissionChannelInfo = ChannelManager.GetChannelInfo(siteId, permissionChannelId); + channels.Add(new + { + permissionChannelInfo.Id, + ChannelName = ChannelManager.GetChannelNameNavigation(siteId, permissionChannelId) + }); + } + + return Ok(new + { + Value = channels + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("contentIds")); + var targetSiteId = Request.GetPostInt("targetSiteId"); + var targetChannelId = Request.GetPostInt("targetChannelId"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentTranslate)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + foreach (var contentId in contentIdList) + { + ContentManager.Translate(siteInfo, channelId, contentId, targetSiteId, targetChannelId, ETranslateContentType.Cut); + } + + LogUtils.AddSiteLog(siteId, channelId, rest.AdminName, "转移内容", string.Empty); + + CreateManager.TriggerContentChangedEvent(siteId, channelId); + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerDeleteController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerDeleteController.cs new file mode 100644 index 000000000..0581f07cb --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerDeleteController.cs @@ -0,0 +1,136 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/contentsLayerDelete")] + public class PagesContentsLayerDeleteController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetQueryString("contentIds")); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentDelete)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var retVal = new List>(); + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var dict = new Dictionary(contentInfo.ToDictionary()) + { + {"title", WebUtils.GetContentTitle(siteInfo, contentInfo, string.Empty)}, + {"checkState", CheckManager.GetCheckState(siteInfo, contentInfo)} + }; + retVal.Add(dict); + } + + return Ok(new + { + Value = retVal + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("contentIds")); + var isRetainFiles = Request.GetPostBool("isRetainFiles"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentDelete)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + if (!isRetainFiles) + { + DeleteManager.DeleteContents(siteInfo, channelId, contentIdList); + } + + //var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + + if (contentIdList.Count == 1) + { + var contentId = contentIdList[0]; + + if (channelInfo.ContentRepository.GetChanelIdAndValue(contentId, ContentAttribute.Title, + out var contentChannelId, out var contentTitle)) + { + LogUtils.AddSiteLog(siteId, contentChannelId, contentId, rest.AdminName, "删除内容", + $"栏目:{ChannelManager.GetChannelNameNavigation(siteId, contentChannelId)},内容标题:{contentTitle}"); + } + } + else + { + LogUtils.AddSiteLog(siteId, rest.AdminName, "批量删除内容", + $"栏目:{ChannelManager.GetChannelNameNavigation(siteId, channelId)},内容条数:{contentIdList.Count}"); + } + + channelInfo.ContentRepository.UpdateTrashContents(siteId, channelId, contentIdList); + + CreateManager.TriggerContentChangedEvent(siteId, channelId); + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerExportController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerExportController.cs new file mode 100644 index 000000000..e07b79acc --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerExportController.cs @@ -0,0 +1,186 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Office; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.ImportExport; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/contentsLayerExport")] + public class PagesContentsLayerExportController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentView)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var columns = ContentManager.GetContentColumns(siteInfo, channelInfo, true); + + var isChecked = CheckManager.GetUserCheckLevel(rest.AdminPermissions, siteInfo, siteId, out var checkedLevel); + var checkedLevels = CheckManager.GetCheckedLevels(siteInfo, isChecked, checkedLevel, true); + + return Ok(new + { + Value = columns, + CheckedLevels = checkedLevels, + CheckedLevel = checkedLevel + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var downloadUrl = string.Empty; + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var exportType = Request.GetPostString("exportType"); + var isAllCheckedLevel = Request.GetPostBool("isAllCheckedLevel"); + var checkedLevelKeys = Request.GetPostObject>("checkedLevelKeys"); + var isAllDate = Request.GetPostBool("isAllDate"); + var startDate = TranslateUtils.ToDateTime(Request.GetPostString("startDate"), DateTime.Now); + var endDate = TranslateUtils.ToDateTime(Request.GetPostString("endDate"), DateTime.Now); + var columnNames = Request.GetPostObject>("columnNames"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ChannelEdit)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var onlyAdminId = ((PermissionsImpl)rest.AdminPermissions).GetOnlyAdminId(siteId, channelId); + + var columns = ContentManager.GetContentColumns(siteInfo, channelInfo, true); + var pluginIds = PluginContentManager.GetContentPluginIds(channelInfo); + var pluginColumns = PluginContentManager.GetContentColumns(pluginIds); + + var contentInfoList = new List(); + var count = ContentManager.GetCount(siteInfo, channelInfo, onlyAdminId); + var pages = Convert.ToInt32(Math.Ceiling((double)count / siteInfo.PageSize)); + if (pages == 0) pages = 1; + + if (count > 0) + { + for (var page = 1; page <= pages; page++) + { + var offset = siteInfo.PageSize * (page - 1); + var limit = siteInfo.PageSize; + + var pageContentIds = ContentManager.GetContentIdList(siteInfo, channelInfo, onlyAdminId, offset, limit); + + var sequence = offset + 1; + + foreach (var contentId in pageContentIds) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + if (!isAllCheckedLevel) + { + var checkedLevel = contentInfo.CheckedLevel; + if (contentInfo.Checked) + { + checkedLevel = siteInfo.CheckContentLevel; + } + if (!checkedLevelKeys.Contains(checkedLevel)) + { + continue; + } + } + + if (!isAllDate) + { + if (contentInfo.AddDate < startDate || contentInfo.AddDate > endDate) + { + continue; + } + } + + //contentInfoList.Add(ContentManager.Calculate(sequence++, contentInfo, columns, pluginColumns)); + contentInfoList.Add(contentInfo); + } + } + + if (contentInfoList.Count > 0) + { + if (exportType == "zip") + { + var fileName = $"{channelInfo.ChannelName}.zip"; + var filePath = PathUtils.GetTemporaryFilesPath(fileName); + var exportObject = new ExportObject(siteId, rest.AdminName); + contentInfoList.Reverse(); + if (exportObject.ExportContents(filePath, contentInfoList)) + { + downloadUrl = FxUtils.GetTemporaryFilesUrl(fileName); + } + } + else if (exportType == "excel") + { + var fileName = $"{channelInfo.ChannelName}.csv"; + var filePath = PathUtils.GetTemporaryFilesPath(fileName); + ExcelObject.CreateExcelFileForContents(filePath, siteInfo, channelInfo, contentInfoList, columnNames); + downloadUrl = FxUtils.GetTemporaryFilesUrl(fileName); + } + } + } + + return Ok(new + { + Value = downloadUrl, + IsSuccess = !string.IsNullOrEmpty(downloadUrl) + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerGroupController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerGroupController.cs new file mode 100644 index 000000000..d937aff8c --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerGroupController.cs @@ -0,0 +1,169 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/contentsLayerGroup")] + public class PagesContentsLayerGroupController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentDelete)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var contentGroupNameList = ContentGroupManager.GetGroupNameList(siteId); + + return Ok(new + { + Value = contentGroupNameList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("contentIds")); + var pageType = Request.GetPostString("pageType"); + var groupNames = TranslateUtils.StringCollectionToStringList(Request.GetPostString("groupNames")); + var groupName = Request.GetPostString("groupName"); + var description = Request.GetPostString("description"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentEdit)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + if (pageType == "setGroup") + { + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var list = TranslateUtils.StringCollectionToStringList(contentInfo.GroupNameCollection); + foreach (var name in groupNames) + { + if (!list.Contains(name)) list.Add(name); + } + contentInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(list); + + DataProvider.ContentRepository.Update(siteInfo, channelInfo, contentInfo); + } + + LogUtils.AddSiteLog(siteId, rest.AdminName, "批量设置内容组", $"内容组:{TranslateUtils.ObjectCollectionToString(groupNames)}"); + } + else if(pageType == "cancelGroup") + { + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var list = TranslateUtils.StringCollectionToStringList(contentInfo.GroupNameCollection); + foreach (var name in groupNames) + { + if (list.Contains(name)) list.Remove(name); + } + contentInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(list); + + DataProvider.ContentRepository.Update(siteInfo, channelInfo, contentInfo); + } + + LogUtils.AddSiteLog(siteId, rest.AdminName, "批量取消内容组", $"内容组:{TranslateUtils.ObjectCollectionToString(groupNames)}"); + } + else if (pageType == "addGroup") + { + var groupInfo = new ContentGroupInfo + { + GroupName = AttackUtils.FilterXss(groupName), + SiteId = siteId, + Description = AttackUtils.FilterXss(description) + }; + + if (ContentGroupManager.IsExists(siteId, groupInfo.GroupName)) + { + DataProvider.ContentGroup.Update(groupInfo); + LogUtils.AddSiteLog(siteId, rest.AdminName, "修改内容组", $"内容组:{groupInfo.GroupName}"); + } + else + { + DataProvider.ContentGroup.Insert(groupInfo); + LogUtils.AddSiteLog(siteId, rest.AdminName, "添加内容组", $"内容组:{groupInfo.GroupName}"); + } + + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var list = TranslateUtils.StringCollectionToStringList(contentInfo.GroupNameCollection); + if (!list.Contains(groupInfo.GroupName)) list.Add(groupInfo.GroupName); + contentInfo.GroupNameCollection = TranslateUtils.ObjectCollectionToString(list); + + DataProvider.ContentRepository.Update(siteInfo, channelInfo, contentInfo); + } + + LogUtils.AddSiteLog(siteId, rest.AdminName, "批量设置内容组", $"内容组:{groupInfo.GroupName}"); + } + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerImportController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerImportController.cs new file mode 100644 index 000000000..6875034e0 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerImportController.cs @@ -0,0 +1,213 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Web; +using System.Web.Http; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.ImportExport; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/contentsLayerImport")] + public class PagesContentsLayerImportController : ApiController + { + private const string Route = ""; + private const string RouteUpload = "actions/upload"; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var isChecked = CheckManager.GetUserCheckLevel(rest.AdminPermissions, siteInfo, siteId, out var checkedLevel); + var checkedLevels = CheckManager.GetCheckedLevels(siteInfo, isChecked, checkedLevel, true); + + return Ok(new + { + Value = checkedLevel, + CheckedLevels = checkedLevels + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteUpload)] + public IHttpActionResult Upload() + { + try + { +#pragma warning disable CS0612 // '“RequestImpl”已过时 + var request = new RequestImpl(HttpContext.Current.Request); +#pragma warning restore CS0612 // '“RequestImpl”已过时 + + var siteId = request.GetQueryInt("siteId"); + var channelId = request.GetQueryInt("channelId"); + + if (!request.IsAdminLoggin || + !request.AdminPermissionsImpl.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd)) + { + return Unauthorized(); + } + + var fileName = request.HttpRequest["fileName"]; + + var fileCount = request.HttpRequest.Files.Count; + + string filePath = null; + + if (fileCount > 0) + { + var file = request.HttpRequest.Files[0]; + + if (string.IsNullOrEmpty(fileName)) fileName = Path.GetFileName(file.FileName); + + var extendName = fileName.Substring(fileName.LastIndexOf(".", StringComparison.Ordinal)).ToLower(); + if (extendName == ".zip" || extendName == ".csv" || extendName == ".txt") + { + filePath = PathUtils.GetTemporaryFilesPath(fileName); + DirectoryUtils.CreateDirectoryIfNotExists(filePath); + file.SaveAs(filePath); + } + } + + FileInfo fileInfo = null; + if (!string.IsNullOrEmpty(filePath)) + { + fileInfo = new FileInfo(filePath); + } + if (fileInfo != null) + { + return Ok(new + { + fileName, + length = fileInfo.Length, + ret = 1 + }); + } + + return Ok(new + { + ret = 0 + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var importType = Request.GetPostString("importType"); + var checkedLevel = Request.GetPostInt("checkedLevel"); + var isOverride = Request.GetPostBool("isOverride"); + var fileNames = Request.GetPostObject>("fileNames"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var isChecked = checkedLevel >= siteInfo.CheckContentLevel; + + if (importType == "zip") + { + foreach (var fileName in fileNames) + { + var localFilePath = PathUtils.GetTemporaryFilesPath(fileName); + + if (!EFileSystemTypeUtils.Equals(EFileSystemType.Zip, PathUtils.GetExtension(localFilePath))) + continue; + + var importObject = new ImportObject(siteId, rest.AdminName); + importObject.ImportContentsByZipFile(channelInfo, localFilePath, isOverride, isChecked, checkedLevel, rest.AdminId, 0, SourceManager.Default); + } + } + + else if (importType == "csv") + { + foreach (var fileName in fileNames) + { + var localFilePath = PathUtils.GetTemporaryFilesPath(fileName); + + if (!EFileSystemTypeUtils.Equals(EFileSystemType.Csv, PathUtils.GetExtension(localFilePath))) + continue; + + var importObject = new ImportObject(siteId, rest.AdminName); + importObject.ImportContentsByCsvFile(channelInfo, localFilePath, isOverride, isChecked, checkedLevel, rest.AdminId, 0, SourceManager.Default); + } + } + else if (importType == "txt") + { + foreach (var fileName in fileNames) + { + var localFilePath = PathUtils.GetTemporaryFilesPath(fileName); + if (!EFileSystemTypeUtils.Equals(EFileSystemType.Txt, PathUtils.GetExtension(localFilePath))) + continue; + + var importObject = new ImportObject(siteId, rest.AdminName); + importObject.ImportContentsByTxtFile(channelInfo, localFilePath, isOverride, isChecked, checkedLevel, rest.AdminId, 0, SourceManager.Default); + } + } + + LogUtils.AddSiteLog(siteId, channelId, rest.AdminName, "导入内容", string.Empty); + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerStateController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerStateController.cs new file mode 100644 index 000000000..9833c75c6 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerStateController.cs @@ -0,0 +1,67 @@ +using System; +using System.Web.Http; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/contentsLayerState")] + public class PagesContentsLayerStateController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + var contentId = Request.GetQueryInt("contentId"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentView)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) return BadRequest("无法确定对应的内容"); + + var title = WebUtils.GetContentTitle(siteInfo, contentInfo, string.Empty); + var checkState = + CheckManager.GetCheckState(siteInfo, contentInfo); + + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + var contentChecks = DataProvider.ContentCheck.GetCheckInfoList(tableName, contentId); + + return Ok(new + { + Value = contentChecks, + Title = title, + CheckState = checkState + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerTaxisController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerTaxisController.cs new file mode 100644 index 000000000..1b3ce6556 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerTaxisController.cs @@ -0,0 +1,96 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/contentsLayerTaxis")] + public class PagesContentsLayerTaxisController : ApiController + { + private const string Route = ""; + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("contentIds")); + var isUp = Request.GetPostBool("isUp"); + var taxis = Request.GetPostInt("taxis"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentEdit)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + if (ETaxisTypeUtils.Equals(channelInfo.DefaultTaxisType, ETaxisType.OrderByTaxis)) + { + isUp = !isUp; + } + + if (isUp == false) + { + contentIdList.Reverse(); + } + + foreach (var contentId in contentIdList) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) continue; + + var isTop = contentInfo.Top; + for (var i = 1; i <= taxis; i++) + { + if (isUp) + { + if (channelInfo.ContentRepository.SetTaxisToUp(channelId, contentId, isTop) == false) + { + break; + } + } + else + { + if (channelInfo.ContentRepository.SetTaxisToDown(channelId, contentId, isTop) == false) + { + break; + } + } + } + } + + CreateManager.TriggerContentChangedEvent(siteId, channelId); + + LogUtils.AddSiteLog(siteId, channelId, rest.AdminName, "对内容排序", string.Empty); + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerViewController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerViewController.cs new file mode 100644 index 000000000..c6427b8a1 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerViewController.cs @@ -0,0 +1,69 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/contentsLayerView")] + public class PagesContentsLayerViewController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + var contentId = Request.GetQueryInt("contentId"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentView)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + if (contentInfo == null) return BadRequest("无法确定对应的内容"); + + var dict = new Dictionary(contentInfo.ToDictionary()) + { + {"checkState", CheckManager.GetCheckState(siteInfo, contentInfo)} + }; + + var channelName = ChannelManager.GetChannelNameNavigation(siteId, channelId); + + var attributes = ChannelManager.GetContentsColumns(siteInfo, channelInfo, true); + + return Ok(new + { + Value = dict, + ChannelName = channelName, + Attributes = attributes + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerWordController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerWordController.cs new file mode 100644 index 000000000..24f630f8d --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesContentsLayerWordController.cs @@ -0,0 +1,223 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Web; +using System.Web.Http; +using SiteServer.BackgroundPages.Core; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.Office; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/contentsLayerWord")] + public class PagesContentsLayerWordController : ApiController + { + private const string Route = ""; + private const string RouteUpload = "actions/upload"; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var isChecked = CheckManager.GetUserCheckLevel(rest.AdminPermissions, siteInfo, siteId, out var checkedLevel); + var checkedLevels = CheckManager.GetCheckedLevels(siteInfo, isChecked, checkedLevel, false); + + return Ok(new + { + Value = checkedLevels, + CheckedLevel = CheckManager.LevelInt.CaoGao + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteUpload)] + public IHttpActionResult Upload() + { + try + { +#pragma warning disable CS0612 // '“RequestImpl”已过时 + var request = new RequestImpl(HttpContext.Current.Request); +#pragma warning restore CS0612 // '“RequestImpl”已过时 + + var siteId = request.GetQueryInt("siteId"); + var channelId = request.GetQueryInt("channelId"); + + if (!request.IsAdminLoggin || + !request.AdminPermissionsImpl.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd)) + { + return Unauthorized(); + } + + var fileName = request.HttpRequest["fileName"]; + + var fileCount = request.HttpRequest.Files.Count; + + string filePath = null; + + if (fileCount > 0) + { + var file = request.HttpRequest.Files[0]; + + if (string.IsNullOrEmpty(fileName)) fileName = Path.GetFileName(file.FileName); + + var extendName = fileName.Substring(fileName.LastIndexOf(".", StringComparison.Ordinal)).ToLower(); + if (extendName == ".doc" || extendName == ".docx") + { + filePath = PathUtils.GetTemporaryFilesPath(fileName); + DirectoryUtils.CreateDirectoryIfNotExists(filePath); + file.SaveAs(filePath); + } + } + + FileInfo fileInfo = null; + if (!string.IsNullOrEmpty(filePath)) + { + fileInfo = new FileInfo(filePath); + } + if (fileInfo != null) + { + return Ok(new + { + fileName, + length = fileInfo.Length, + ret = 1 + }); + } + + return Ok(new + { + ret = 0 + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var isFirstLineTitle = Request.GetPostBool("isFirstLineTitle"); + var isFirstLineRemove = Request.GetPostBool("isFirstLineRemove"); + var isClearFormat = Request.GetPostBool("isClearFormat"); + var isFirstLineIndent = Request.GetPostBool("isFirstLineIndent"); + var isClearFontSize = Request.GetPostBool("isClearFontSize"); + var isClearFontFamily = Request.GetPostBool("isClearFontFamily"); + var isClearImages = Request.GetPostBool("isClearImages"); + var checkedLevel = Request.GetPostInt("checkedLevel"); + var fileNames = TranslateUtils.StringCollectionToStringList(Request.GetPostString("fileNames")); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd)) + { + return Unauthorized(); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + var styleInfoList = TableStyleManager.GetContentStyleInfoList(siteInfo, channelInfo); + var isChecked = checkedLevel >= siteInfo.CheckContentLevel; + + var contentIdList = new List(); + + foreach (var fileName in fileNames) + { + if (string.IsNullOrEmpty(fileName)) continue; + + var formCollection = WordUtils.GetWordNameValueCollection(siteId, isFirstLineTitle, isFirstLineRemove, isClearFormat, isFirstLineIndent, isClearFontSize, isClearFontFamily, isClearImages, fileName); + + if (string.IsNullOrEmpty(formCollection[ContentAttribute.Title])) continue; + + var dict = BackgroundInputTypeParser.SaveAttributes(siteInfo, styleInfoList, formCollection, ContentAttribute.AllAttributes.Value); + + var contentInfo = new ContentInfo(dict) + { + ChannelId = channelInfo.Id, + SiteId = siteId, + AddUserName = rest.AdminName, + AddDate = DateTime.Now + }; + + contentInfo.LastEditUserName = contentInfo.AddUserName; + contentInfo.LastEditDate = contentInfo.AddDate; + contentInfo.Checked = isChecked; + contentInfo.CheckedLevel = checkedLevel; + + contentInfo.Title = formCollection[ContentAttribute.Title]; + + contentInfo.Id = DataProvider.ContentRepository.Insert(tableName, siteInfo, channelInfo, contentInfo); + + contentIdList.Add(contentInfo.Id); + } + + if (isChecked) + { + foreach (var contentId in contentIdList) + { + CreateManager.CreateContent(siteId, channelInfo.Id, contentId); + } + CreateManager.TriggerContentChangedEvent(siteId, channelInfo.Id); + } + + return Ok(new + { + Value = contentIdList + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesCreateController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesCreateController.cs new file mode 100644 index 000000000..06daa4896 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesCreateController.cs @@ -0,0 +1,220 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/create")] + public class PagesCreateController : ApiController + { + private const string Route = ""; + private const string RouteAll = "all"; + + [HttpGet, Route(Route)] + public IHttpActionResult GetList() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var siteId = Request.GetQueryInt("siteId"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSitePermissions(siteId, ConfigManager.WebSitePermissions.Create)) + { + return Unauthorized(); + } + + var parentId = Request.GetQueryInt("parentId"); + var siteInfo = SiteManager.GetSiteInfo(siteId); + var parent = ChannelManager.GetChannelInfo(siteId, parentId); + var countDict = new Dictionary + { + [parent.Id] = ContentManager.GetCount(siteInfo, parent, true) + }; + + var channelInfoList = new List(); + + var channelIdList = + ChannelManager.GetChannelIdList(parent, EScopeType.Children, string.Empty, string.Empty, string.Empty); + + var adminPermissions = (PermissionsImpl) rest.AdminPermissions; + + foreach (var channelId in channelIdList) + { + var enabled = adminPermissions.IsOwningChannelId(channelId); + + if (!enabled) + { + if (!adminPermissions.IsDescendantOwningChannelId(siteId, channelId)) continue; + } + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + channelInfoList.Add(channelInfo); + countDict[channelInfo.Id] = ContentManager.GetCount(siteInfo, channelInfo, true); + } + + return Ok(new + { + Value = channelInfoList, + Parent = parent, + CountDict = countDict + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + public class CreateParameter + { + public int SiteId { get; set; } + public IEnumerable ChannelIdList { get; set; } + public bool IsAllChecked { get; set; } + public bool IsDescendent { get; set; } + public bool IsChannelPage { get; set; } + public bool IsContentPage { get; set; } + public string Scope { get; set; } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Create([FromBody] CreateParameter parameter) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSitePermissions(parameter.SiteId, ConfigManager.WebSitePermissions.Create)) + { + return Unauthorized(); + } + + var selectedChannelIdList = new List(); + + if (parameter.IsAllChecked) + { + selectedChannelIdList = ChannelManager.GetChannelIdList(parameter.SiteId); + } + else if (parameter.IsDescendent) + { + foreach (var channelId in parameter.ChannelIdList) + { + selectedChannelIdList.Add(channelId); + + var channelInfo = ChannelManager.GetChannelInfo(parameter.SiteId, channelId); + if (channelInfo.ChildrenCount > 0) + { + var descendentIdList = ChannelManager.GetChannelIdList(channelInfo, EScopeType.Descendant); + foreach (var descendentId in descendentIdList) + { + if (selectedChannelIdList.Contains(descendentId)) continue; + + selectedChannelIdList.Add(descendentId); + } + } + } + } + else + { + selectedChannelIdList.AddRange(parameter.ChannelIdList); + } + + var channelIdList = new List(); + + if (parameter.Scope == "1month" || parameter.Scope == "1day" || parameter.Scope == "2hours") + { + var siteInfo = SiteManager.GetSiteInfo(parameter.SiteId); + var tableName = siteInfo.TableName; + + if (parameter.Scope == "1month") + { + var lastEditList = DataProvider.ContentRepository.GetChannelIdListCheckedByLastEditDateHour(tableName, parameter.SiteId, 720); + foreach (var channelId in lastEditList) + { + if (selectedChannelIdList.Contains(channelId)) + { + channelIdList.Add(channelId); + } + } + } + else if (parameter.Scope == "1day") + { + var lastEditList = DataProvider.ContentRepository.GetChannelIdListCheckedByLastEditDateHour(tableName, parameter.SiteId, 24); + foreach (var channelId in lastEditList) + { + if (selectedChannelIdList.Contains(channelId)) + { + channelIdList.Add(channelId); + } + } + } + else if (parameter.Scope == "2hours") + { + var lastEditList = DataProvider.ContentRepository.GetChannelIdListCheckedByLastEditDateHour(tableName, parameter.SiteId, 2); + foreach (var channelId in lastEditList) + { + if (selectedChannelIdList.Contains(channelId)) + { + channelIdList.Add(channelId); + } + } + } + } + else + { + channelIdList = selectedChannelIdList; + } + + foreach (var channelId in channelIdList) + { + if (parameter.IsChannelPage) + { + CreateManager.CreateChannel(parameter.SiteId, channelId); + } + if (parameter.IsContentPage) + { + CreateManager.CreateAllContent(parameter.SiteId, channelId); + } + } + + return Ok(new { }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteAll)] + public IHttpActionResult CreateAll([FromBody] CreateParameter parameter) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSitePermissions(parameter.SiteId, ConfigManager.WebSitePermissions.Create)) + { + return Unauthorized(); + } + + CreateManager.CreateByAll(parameter.SiteId); + + return Ok(new { }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Cms/PagesCreateStatusController.cs b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesCreateStatusController.cs new file mode 100644 index 000000000..e3b456095 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Cms/PagesCreateStatusController.cs @@ -0,0 +1,71 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cms +{ + [RoutePrefix("pages/cms/createStatus")] + public class PagesCreateStatusController : ApiController + { + private const string Route = ""; + private const string RouteActionsCancel = "actions/cancel"; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var siteId = Request.GetQueryInt("siteId"); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSitePermissions(siteId, ConfigManager.WebSitePermissions.Create)) + { + return Unauthorized(); + } + + var summary = CreateTaskManager.GetTaskSummary(siteId); + + return Ok(new + { + Value = summary + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteActionsCancel)] + public IHttpActionResult Cancel() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var siteId = Request.GetPostInt("siteId"); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSitePermissions(siteId, ConfigManager.WebSitePermissions.Create)) + { + return Unauthorized(); + } + + CreateTaskManager.ClearAllTask(siteId); + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Controllers/Pages/Connect/PagesAuthorizeController.cs b/net452/SiteServer.Web/Controllers/Pages/Connect/PagesAuthorizeController.cs new file mode 100644 index 000000000..bab84f409 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Connect/PagesAuthorizeController.cs @@ -0,0 +1,52 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cloud +{ + [RoutePrefix("pages/cloud/authorize")] + public class PagesAuthorizeController : ApiController + { + private const string Route = ""; + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.IsSuperAdmin()) + { + return Unauthorized(); + } + + var userName = Request.GetPostString("userName"); + var accessToken = Request.GetPostString("accessToken"); + var expiresAt = TranslateUtils.ToDateTime(Request.GetPostString("expiresAt"), DateTime.Now); + + //ConfigManager.SystemConfigInfo.IsCloudLoggin = true; ConfigManager.SystemConfigInfo.CloudUserName = userName; + //ConfigManager.SystemConfigInfo.CloudAccessToken = accessToken; + //ConfigManager.SystemConfigInfo.CloudExpiresAt = expiresAt; + + DataProvider.Config.Update(ConfigManager.Instance); + + LogUtils.AddAdminLog(rest.AdminName, "云服务账号登录", $"UserName:{userName}"); + + return Ok(new + { + Value = userName + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Connect/PagesDashboardController.cs b/net452/SiteServer.Web/Controllers/Pages/Connect/PagesDashboardController.cs new file mode 100644 index 000000000..b59bbdcea --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Connect/PagesDashboardController.cs @@ -0,0 +1,47 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; + +namespace SiteServer.API.Controllers.Pages.Cloud +{ + [RoutePrefix("pages/cloud/dashboard")] + public class PagesDashboardController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || !rest.AdminPermissions.IsSuperAdmin()) + { + return Unauthorized(); + } + + //if (!ConfigManager.SystemConfigInfo.IsCloudLoggin || ConfigManager.SystemConfigInfo.CloudExpiresAt < DateTime.Now) + //{ + // return Unauthorized(); + //} + + //return Ok(new + //{ + // Value = ConfigManager.SystemConfigInfo.CloudUserName, + // AccessToken = ConfigManager.SystemConfigInfo.CloudAccessToken + //}); + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Connect/PagesIndexController.cs b/net452/SiteServer.Web/Controllers/Pages/Connect/PagesIndexController.cs new file mode 100644 index 000000000..23ed744fe --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Connect/PagesIndexController.cs @@ -0,0 +1,110 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Connect +{ + [RoutePrefix("pages/connect/index")] + public class PagesIndexController : ApiController + { + private const string RouteActionsLogin = "actions/login"; + private const string RouteActionsConnect = "actions/connect"; + + [HttpPost, Route(RouteActionsLogin)] + public IHttpActionResult Login() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var account = Request.GetPostString("account"); + var password = Request.GetPostString("password"); + + AdministratorInfo adminInfo; + + if (!DataProvider.Administrator.Validate(account, password, true, out var userName, out var errorMessage)) + { + adminInfo = AdminManager.GetAdminInfoByUserName(userName); + if (adminInfo != null) + { + DataProvider.Administrator.UpdateLastActivityDateAndCountOfFailedLogin(adminInfo); // 记录最后登录时间、失败次数+1 + } + return BadRequest(errorMessage); + } + + adminInfo = AdminManager.GetAdminInfoByUserName(userName); + DataProvider.Administrator.UpdateLastActivityDateAndCountOfLogin(adminInfo); // 记录最后登录时间、失败次数清零 + if (!AdminManager.IsSuperAdmin(userName)) + { + return BadRequest($"管理员{userName}不是超级管理员,请使用超级管理员账号登录"); + } + + + var isNightlyUpdate = WebConfigUtils.IsNightlyUpdate; + var apiPrefix = WebConfigUtils.ApiPrefix; + var adminDirectory = WebConfigUtils.AdminDirectory; + var homeDirectory = WebConfigUtils.HomeDirectory; + var secretKey = WebConfigUtils.SecretKey; + var cmsVersion = SystemManager.Version; + var pluginVersion = SystemManager.PluginVersion; + var apiVersion = SystemManager.ApiVersion; + var adminName = adminInfo.UserName; + var adminToken = AdminApi.Instance.GetAccessToken(adminInfo.Id, adminInfo.UserName, TimeSpan.FromDays(3650)); + + return Ok(new + { + Value = true, + IsNightlyUpdate = isNightlyUpdate, + ApiPrefix = apiPrefix, + AdminDirectory = adminDirectory, + HomeDirectory = homeDirectory, + SecretKey = secretKey, + CmsVersion = cmsVersion, + PluginVersion = pluginVersion, + ApiVersion = apiVersion, + AdminName = adminName, + AdminToken = adminToken + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteActionsConnect)] + public IHttpActionResult Connect() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var repositoryOwner = Request.GetPostString("repositoryOwner"); + var repositoryName = Request.GetPostString("repositoryName"); + var repositoryToken = Request.GetPostString("repositoryToken"); + + ConfigManager.Instance.RepositoryOwner = repositoryOwner; + ConfigManager.Instance.RepositoryName = repositoryName; + ConfigManager.Instance.RepositoryToken = repositoryToken; + DataProvider.Config.Update(ConfigManager.Instance); + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Connect/PagesLayerLoginController.cs b/net452/SiteServer.Web/Controllers/Pages/Connect/PagesLayerLoginController.cs new file mode 100644 index 000000000..ec752f2eb --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Connect/PagesLayerLoginController.cs @@ -0,0 +1,52 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Cloud +{ + [RoutePrefix("pages/cloud/layerLogin")] + public class PagesLayerLoginController : ApiController + { + private const string Route = ""; + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.IsSuperAdmin()) + { + return Unauthorized(); + } + + var userName = Request.GetPostString("userName"); + var accessToken = Request.GetPostString("accessToken"); + var expiresAt = TranslateUtils.ToDateTime(Request.GetPostString("expiresAt"), DateTime.Now); + + //ConfigManager.SystemConfigInfo.IsCloudLoggin = true; ConfigManager.SystemConfigInfo.CloudUserName = userName; + //ConfigManager.SystemConfigInfo.CloudAccessToken = accessToken; + //ConfigManager.SystemConfigInfo.CloudExpiresAt = expiresAt; + + DataProvider.Config.Update(ConfigManager.Instance); + + LogUtils.AddAdminLog(rest.AdminName, "云服务账号登录", $"UserName:{userName}"); + + return Ok(new + { + Value = userName + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Connect/PagesLogoutController.cs b/net452/SiteServer.Web/Controllers/Pages/Connect/PagesLogoutController.cs new file mode 100644 index 000000000..2ed093b20 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Connect/PagesLogoutController.cs @@ -0,0 +1,45 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; + +namespace SiteServer.API.Controllers.Pages.Cloud +{ + [RoutePrefix("pages/cloud/logout")] + public class PagesLogoutController : ApiController + { + private const string Route = ""; + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.IsSuperAdmin()) + { + return Unauthorized(); + } + + //ConfigManager.SystemConfigInfo.IsCloudLoggin = false; ConfigManager.SystemConfigInfo.CloudUserName = string.Empty; + //ConfigManager.SystemConfigInfo.CloudAccessToken = string.Empty; + //ConfigManager.SystemConfigInfo.CloudExpiresAt = DateTime.Now; + + //DataProvider.ConfigDao.UpdateObject(ConfigManager.Instance); + + LogUtils.AddAdminLog(rest.AdminName, "云服务账号登出"); + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/PagesDashboardController.cs b/net452/SiteServer.Web/Controllers/Pages/PagesDashboardController.cs new file mode 100644 index 000000000..80d7dab28 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/PagesDashboardController.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.BackgroundPages.Cms; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Packaging; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.API.Controllers.Pages +{ + [RoutePrefix("pages/dashboard")] + public class PagesDashboardController : ApiController + { + private const string Route = ""; + private const string RouteUnCheckedList = "unCheckedList"; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin) + { + return Unauthorized(); + } + + var adminInfo = AdminManager.GetAdminInfoByUserId(rest.AdminId); + + return Ok(new + { + Value = new + { + Version = SystemManager.Version == PackageUtils.VersionDev ? "dev" : SystemManager.Version, + LastActivityDate = DateUtils.GetDateString(adminInfo.LastActivityDate, EDateFormatType.Chinese), + UpdateDate = DateUtils.GetDateString(ConfigManager.Instance.UpdateDate, EDateFormatType.Chinese) + } + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpGet, Route(RouteUnCheckedList)] + public IHttpActionResult GetUnCheckedList() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin) + { + return Unauthorized(); + } + + var unCheckedList = new List(); + + foreach (var siteInfo in SiteManager.GetSiteInfoList()) + { + if (!rest.AdminPermissions.IsSiteAdmin(siteInfo.Id)) continue; + + var count = ContentManager.GetCount(siteInfo, false); + if (count > 0) + { + unCheckedList.Add(new + { + Url = PageContentSearch.GetRedirectUrlCheck(siteInfo.Id), + siteInfo.SiteName, + Count = count + }); + } + } + + return Ok(new + { + Value = unCheckedList + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Controllers/Pages/PagesErrorController.cs b/net452/SiteServer.Web/Controllers/Pages/PagesErrorController.cs new file mode 100644 index 000000000..e800e52e2 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/PagesErrorController.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages +{ + [RoutePrefix("pages/error")] + public class PagesErrorController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin) + { + return Unauthorized(); + } + + var logId = Request.GetQueryInt("logId"); + var logInfo = DataProvider.ErrorLog.GetErrorLogInfo(logId); + if (logInfo == null) return NotFound(); + var retVal = logInfo.ToDictionary(); + + return Ok(new + { + LogInfo = logInfo, + SystemManager.Version + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Controllers/Pages/PagesLoadingController.cs b/net452/SiteServer.Web/Controllers/Pages/PagesLoadingController.cs new file mode 100644 index 000000000..bd224262f --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/PagesLoadingController.cs @@ -0,0 +1,131 @@ +using System; +using System.Web; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes.Preview; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages +{ + [RoutePrefix("pages/loading")] + public class PagesLoadingController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public void Redirect() + { + var rest = Request.GetAuthenticatedRequest(); + + var redirectUrl = Request.GetQueryString("redirectUrl"); + var encryptedUrl = Request.GetQueryString("encryptedUrl"); + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + var contentId = Request.GetQueryInt("contentId"); + var fileTemplateId = Request.GetQueryInt("fileTemplateId"); + var specialId = Request.GetQueryInt("specialId"); + + var url = GetUrl(redirectUrl, encryptedUrl, siteId, channelId, contentId, fileTemplateId, + specialId); + + HttpContext.Current.Response.Redirect(url); + } + + private static string GetUrl(string redirectUrl, string encryptedUrl, int siteId, int channelId, int contentId, int fileTemplateId, int specialId) + { + if (!string.IsNullOrEmpty(redirectUrl)) + { + return redirectUrl; + } + + if (!string.IsNullOrEmpty(encryptedUrl)) + { + return TranslateUtils.DecryptStringBySecretKey(encryptedUrl); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + + var isLocal = siteInfo.IsSeparatedWeb || siteInfo.IsSeparatedAssets; + + if (siteId > 0 && channelId > 0 && contentId > 0) + { + var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); + redirectUrl = PageUtility.GetContentUrl(siteInfo, nodeInfo, contentId, isLocal); + } + else if (siteId > 0 && channelId > 0) + { + var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); + redirectUrl = PageUtility.GetChannelUrl(siteInfo, nodeInfo, isLocal); + } + else if (siteId > 0 && fileTemplateId > 0) + { + redirectUrl = PageUtility.GetFileUrl(siteInfo, fileTemplateId, isLocal); + } + else if (siteId > 0 && specialId > 0) + { + redirectUrl = PageUtility.GetSpecialUrl(siteInfo, specialId, isLocal); + } + else if (siteId > 0) + { + var nodeInfo = ChannelManager.GetChannelInfo(siteId, siteId); + redirectUrl = PageUtility.GetChannelUrl(siteInfo, nodeInfo, isLocal); + } + + if (string.IsNullOrEmpty(redirectUrl) || StringUtils.EqualsIgnoreCase(redirectUrl, PageUtils.UnClickedUrl)) + { + if (siteId == 0) + { + siteId = DataProvider.Site.GetIdByIsRoot(); + } + + if (siteId == 0) + { + redirectUrl = FxUtils.ApplicationPath; + } + else + { + var redirectSiteInfo = SiteManager.GetSiteInfo(siteId); + redirectUrl = redirectSiteInfo.IsSeparatedWeb + ? ApiRoutePreview.GetSiteUrl(siteId) + : redirectSiteInfo.WebUrl; + } + } + + return redirectUrl; + } + + [HttpPost, Route(Route)] + public IHttpActionResult Load() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var redirectUrl = Request.GetPostString("redirectUrl"); + var encryptedUrl = Request.GetPostString("encryptedUrl"); + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentId = Request.GetPostInt("contentId"); + var fileTemplateId = Request.GetPostInt("fileTemplateId"); + var specialId = Request.GetPostInt("specialId"); + + var url = GetUrl(redirectUrl, encryptedUrl, siteId, channelId, contentId, fileTemplateId, + specialId); + + return Ok(new + { + Value = url + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Controllers/Pages/PagesLoginController.cs b/net452/SiteServer.Web/Controllers/Pages/PagesLoginController.cs new file mode 100644 index 000000000..ad4c4edec --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/PagesLoginController.cs @@ -0,0 +1,35 @@ +using System; +using System.Web.Http; +using SiteServer.API.Controllers.Backend; +using SiteServer.CMS.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; + +namespace SiteServer.API.Controllers.Pages +{ + [RoutePrefix("pages/login")] + public class PagesLoginController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var redirect = LoginController.AdminRedirectCheck(rest, checkInstall: true, checkDatabaseVersion: true); + if (redirect != null) return Ok(redirect); + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Controllers/Pages/PagesMainController.cs b/net452/SiteServer.Web/Controllers/Pages/PagesMainController.cs new file mode 100644 index 000000000..fd95707ec --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/PagesMainController.cs @@ -0,0 +1,392 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Threading.Tasks; +using System.Web.Http; +using SiteServer.API.Controllers.Backend; +using SiteServer.BackgroundPages.Cms; +using SiteServer.BackgroundPages.Settings; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.RestRoutes; +using SiteServer.CMS.Core.RestRoutes.Preview; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Packaging; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.CMS.StlParser; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages +{ + [RoutePrefix("pages/main")] + public class PagesMainController : ApiController + { + private const string Route = ""; + private const string RouteActionsCreate = "actions/create"; + private const string RouteActionsDownload = "actions/download"; + + [HttpPost, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var redirect = LoginController.AdminRedirectCheck(rest, checkInstall: true, checkDatabaseVersion: true); + if (redirect != null) return Ok(redirect); + + var siteId = Request.GetPostInt("siteId"); + var pageUrl = Request.GetPostString("pageUrl"); + + if (!rest.IsAdminLoggin) + { + return Ok(new + { + Value = false, + RedirectUrl = $"{AdminPagesUtils.LoginUrl}?redirectUrl={PageUtils.UrlEncode(FxUtils.GetMainUrl(siteId, pageUrl))}" + }); + } + + var adminInfo = AdminManager.GetAdminInfoByUserId(rest.AdminId); + + if (adminInfo.Locked) + { + return Ok(new + { + Value = false, + RedirectUrl = $"{AdminPagesUtils.ErrorUrl}?message={PageUtils.UrlEncode("管理员账号已被锁定,请联系超级管理员协助解决")}" + }); + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + var permissions = (PermissionsImpl)rest.AdminPermissions; + var isSuperAdmin = permissions.IsSuperAdmin(); + var siteIdListWithPermissions = permissions.GetSiteIdList(); + + if (siteInfo == null || !siteIdListWithPermissions.Contains(siteInfo.Id)) + { + if (siteIdListWithPermissions.Contains(adminInfo.SiteId)) + { + return Ok(new + { + Value = false, + RedirectUrl = FxUtils.GetMainUrl(adminInfo.SiteId, pageUrl) + }); + } + + if (siteIdListWithPermissions.Count > 0) + { + return Ok(new + { + Value = false, + RedirectUrl = FxUtils.GetMainUrl(siteIdListWithPermissions[0], pageUrl) + }); + } + + if (isSuperAdmin) + { + return Ok(new + { + Value = false, + RedirectUrl = PageSiteAdd.GetRedirectUrl() + }); + } + + return Ok(new + { + Value = false, + RedirectUrl = $"{AdminPagesUtils.ErrorUrl}?message={PageUtils.UrlEncode("您没有可以管理的站点,请联系超级管理员协助解决")}" + }); + } + + var packageIds = new List + { + PackageUtils.PackageIdSsCms + }; + var packageList = new List(); + var dict = PluginManager.GetPluginIdAndVersionDict(); + foreach (var id in dict.Keys) + { + packageIds.Add(id); + var version = dict[id]; + packageList.Add(new + { + id, + version + }); + } + + var siteIdListLatestAccessed = DataProvider.Administrator.UpdateSiteId(adminInfo, siteInfo.Id); + + var permissionList = new List(permissions.PermissionList); + if (permissions.HasSitePermissions(siteInfo.Id)) + { + var websitePermissionList = permissions.GetSitePermissions(siteInfo.Id); + if (websitePermissionList != null) + { + permissionList.AddRange(websitePermissionList); + } + } + var channelPermissions = permissions.GetChannelPermissions(siteInfo.Id); + if (channelPermissions.Count > 0) + { + permissionList.AddRange(channelPermissions); + } + + var topMenus = GetTopMenus(siteInfo, isSuperAdmin, siteIdListLatestAccessed, siteIdListWithPermissions); + var siteMenus = + GetLeftMenus(siteInfo, ConfigManager.TopMenu.IdSite, isSuperAdmin, permissionList); + var pluginMenus = GetLeftMenus(siteInfo, string.Empty, isSuperAdmin, permissionList); + + var adminInfoToReturn = new + { + adminInfo.Id, + adminInfo.UserName, + adminInfo.AvatarUrl, + Level = permissions.GetAdminLevel() + }; + + var defaultPageUrl = PageUtils.UrlDecode(pageUrl); + if (string.IsNullOrEmpty(defaultPageUrl)) + { + defaultPageUrl = PluginMenuManager.GetSystemDefaultPageUrl(siteId); + } + if (string.IsNullOrEmpty(defaultPageUrl)) + { + defaultPageUrl = AdminPagesUtils.DashboardUrl; + } + + return Ok(new + { + Value = true, + DefaultPageUrl = defaultPageUrl, + WebConfigUtils.IsNightlyUpdate, + SystemManager.PluginVersion, + IsSuperAdmin = isSuperAdmin, + PackageList = packageList, + PackageIds = packageIds, + CmsVersion = SystemManager.Version, + ApiManager.ApiPrefix, + WebConfigUtils.AdminDirectory, + WebConfigUtils.HomeDirectory, + TopMenus = topMenus, + SiteMenus = siteMenus, + PluginMenus = pluginMenus, + AdminInfo = adminInfoToReturn + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + private static List GetTopMenus(SiteInfo siteInfo, bool isSuperAdmin, List siteIdListLatestAccessed, List siteIdListWithPermissions) + { + var menus = new List(); + + if (siteInfo != null && siteIdListWithPermissions.Contains(siteInfo.Id)) + { + var siteMenus = new List(); + if (siteIdListWithPermissions.Count == 1) + { + menus.Add(new Tab + { + Text = siteInfo.SiteName, + Children = siteMenus.ToArray() + }); + } + else + { + var siteIdList = AdminManager.GetLatestTop10SiteIdList(siteIdListLatestAccessed, siteIdListWithPermissions); + foreach (var siteId in siteIdList) + { + var site = SiteManager.GetSiteInfo(siteId); + if (site == null) continue; + + siteMenus.Add(new Tab + { + Href = FxUtils.GetMainUrl(site.Id, string.Empty), + Target = "_top", + Text = site.SiteName + }); + } + siteMenus.Add(new Tab + { + Href = ModalSiteSelect.GetRedirectUrl(siteInfo.Id), + Target = "_layer", + Text = "全部站点..." + }); + menus.Add(new Tab + { + Text = siteInfo.SiteName, + Href = ModalSiteSelect.GetRedirectUrl(siteInfo.Id), + Target = "_layer", + Children = siteMenus.ToArray() + }); + } + + var linkMenus = new List + { + new Tab {Href = PageUtility.GetSiteUrl(siteInfo, false), Target = "_blank", Text = "访问站点"}, + new Tab {Href = ApiRoutePreview.GetSiteUrl(siteInfo.Id), Target = "_blank", Text = "预览站点"} + }; + menus.Add(new Tab {Text = "站点链接", Children = linkMenus.ToArray()}); + } + + if (isSuperAdmin) + { + foreach (var tab in TabManager.GetTopMenuTabs()) + { + var tabs = TabManager.GetTabList(tab.Id, 0); + tab.Children = tabs.ToArray(); + + menus.Add(tab); + } + } + + return menus; + } + + private static List GetLeftMenus(SiteInfo siteInfo, string topId, bool isSuperAdmin, List permissionList) + { + var menus = new List(); + + var tabs = TabManager.GetTabList(topId, siteInfo.Id); + foreach (var parent in tabs) + { + if (!isSuperAdmin && !TabManager.IsValid(parent, permissionList)) continue; + + var children = new List(); + if (parent.Children != null && parent.Children.Length > 0) + { + var tabCollection = new TabCollection(parent.Children); + if (tabCollection.Tabs != null && tabCollection.Tabs.Length > 0) + { + foreach (var childTab in tabCollection.Tabs) + { + if (!isSuperAdmin && !TabManager.IsValid(childTab, permissionList)) continue; + + children.Add(new Tab + { + Id = childTab.Id, + Href = GetHref(childTab, siteInfo.Id), + Text = childTab.Text, + Target = childTab.Target, + IconClass = childTab.IconClass + }); + } + } + } + + menus.Add(new Tab + { + Id = parent.Id, + Href = GetHref(parent, siteInfo.Id), + Text = parent.Text, + Target = parent.Target, + IconClass = parent.IconClass, + Selected = parent.Selected, + Children = children.ToArray() + }); + } + + return menus; + } + + public static string GetHref(Tab tab, int siteId) + { + var href = tab.Href; + if (!PageUtils.IsAbsoluteUrl(href)) + { + href = PageUtils.AddQueryString(href, + new NameValueCollection { { "siteId", siteId.ToString() } }); + } + + return href; + } + + [HttpPost, Route(RouteActionsCreate)] + public async Task Create() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin) + { + return Unauthorized(); + } + + var count = CreateTaskManager.PendingTaskCount; + + var pendingTask = CreateTaskManager.GetFirstPendingTask(); + if (pendingTask != null) + { + try + { + var start = DateTime.Now; + await FileSystemObjectAsync.ExecuteAsync(pendingTask.SiteId, pendingTask.CreateType, + pendingTask.ChannelId, + pendingTask.ContentId, pendingTask.FileTemplateId, pendingTask.SpecialId); + var timeSpan = DateUtils.GetRelatedDateTimeString(start); + CreateTaskManager.AddSuccessLog(pendingTask, timeSpan); + } + catch (Exception ex) + { + CreateTaskManager.AddFailureLog(pendingTask, ex); + } + finally + { + CreateTaskManager.RemovePendingTask(pendingTask); + } + } + + return Ok(new + { + Value = count + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteActionsDownload)] + public IHttpActionResult Download() + { + var rest = Request.GetAuthenticatedRequest(); + + if (!rest.IsAdminLoggin) + { + return Unauthorized(); + } + + var packageId = Request.GetPostString("packageId"); + var version = Request.GetPostString("version"); + + try + { + PackageUtils.DownloadPackage(packageId, version); + } + catch + { + PackageUtils.DownloadPackage(packageId, version); + } + + if (StringUtils.EqualsIgnoreCase(packageId, PackageUtils.PackageIdSsCms)) + { + CacheDbUtils.RemoveAndInsert(PackageUtils.CacheKeySsCmsIsDownload, true.ToString()); + } + + return Ok(new + { + Value = true + }); + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Controllers/Pages/PagesUpdateController.cs b/net452/SiteServer.Web/Controllers/Pages/PagesUpdateController.cs new file mode 100644 index 000000000..d1c0fd3c0 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/PagesUpdateController.cs @@ -0,0 +1,55 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Packaging; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages +{ + [RoutePrefix("pages/update")] + public class PagesUpdateController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + if (SystemManager.IsNeedInstall()) + { + return BadRequest("系统未安装,向导被禁用"); + } + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Update() + { + var idWithVersion = $"{PackageUtils.PackageIdSsCms}.{SystemManager.Version}"; + var packagePath = FxUtils.GetPackagesPath(idWithVersion); + var homeDirectory = PathUtils.GetHomeDirectoryPath(string.Empty); + if (!DirectoryUtils.IsDirectoryExists(homeDirectory) || !FileUtils.IsFileExists(PathUtils.Combine(homeDirectory, "config.js"))) + { + DirectoryUtils.Copy(PathUtils.Combine(packagePath, DirectoryUtils.Home.DirectoryName), homeDirectory, true); + } + + SystemManager.SyncDatabase(); + + return Ok(new + { + SystemManager.Version + }); + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Controllers/Pages/PagesUpgradeController.cs b/net452/SiteServer.Web/Controllers/Pages/PagesUpgradeController.cs new file mode 100644 index 000000000..97217ecef --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/PagesUpgradeController.cs @@ -0,0 +1,98 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Packaging; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages +{ + [RoutePrefix("pages/upgrade")] + public class PagesUpgradeController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || !rest.AdminPermissions.IsSuperAdmin()) + { + return Unauthorized(); + } + + if (SystemManager.IsNeedInstall()) + { + return BadRequest("系统未安装,向导被禁用"); + } + + //var installedVersion = SystemManager.Version; + + //var AdminUrl = PageUtils.GetAdminUrl(string.Empty); + + //var DownloadApiUrl = ApiRouteDownload.GetUrl(ApiManager.InnerApiUrl); + + //var UpdateApiUrl = ApiRouteUpdate.GetUrl(ApiManager.InnerApiUrl); + + //var UpdateSsCmsApiUrl = ApiRouteUpdateSsCms.GetUrl(ApiManager.InnerApiUrl); + + return Ok(new + { + Value = true, + InstalledVersion = SystemManager.Version, + IsNightly = WebConfigUtils.IsNightlyUpdate, + Version = SystemManager.PluginVersion + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Upgrade() + { + var rest = Request.GetAuthenticatedRequest(); + + var isDownload = TranslateUtils.ToBool(CacheDbUtils.GetValueAndRemove(PackageUtils.CacheKeySsCmsIsDownload)); + + if (!isDownload) + { + return Unauthorized(); + } + + var version = Request.GetPostString("version"); + + var idWithVersion = $"{PackageUtils.PackageIdSsCms}.{version}"; + var packagePath = FxUtils.GetPackagesPath(idWithVersion); + var packageWebConfigPath = PathUtils.Combine(packagePath, WebConfigUtils.WebConfigFileName); + + if (!FileUtils.IsFileExists(packageWebConfigPath)) + { + return BadRequest($"升级包 {WebConfigUtils.WebConfigFileName} 文件不存在"); + } + + WebConfigUtils.UpdateWebConfig(packageWebConfigPath, WebConfigUtils.IsProtectData, + WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, WebConfigUtils.ApiPrefix, WebConfigUtils.AdminDirectory, WebConfigUtils.HomeDirectory, + WebConfigUtils.SecretKey, WebConfigUtils.IsNightlyUpdate); + + DirectoryUtils.Copy(PathUtils.Combine(packagePath, DirectoryUtils.SiteFiles.DirectoryName), FxUtils.GetSiteFilesPath(string.Empty), true); + DirectoryUtils.Copy(PathUtils.Combine(packagePath, DirectoryUtils.SiteServer.DirectoryName), PathUtils.GetAdminDirectoryPath(string.Empty), true); + DirectoryUtils.Copy(PathUtils.Combine(packagePath, DirectoryUtils.Home.DirectoryName), PathUtils.GetHomeDirectoryPath(string.Empty), true); + DirectoryUtils.Copy(PathUtils.Combine(packagePath, DirectoryUtils.Bin.DirectoryName), PathUtils.GetBinDirectoryPath(string.Empty), true); + var isCopyFiles = FileUtils.CopyFile(packageWebConfigPath, PathUtils.Combine(WebConfigUtils.PhysicalApplicationPath, WebConfigUtils.WebConfigFileName), true); + + //SystemManager.SyncDatabase(); + + return Ok(new + { + isCopyFiles + }); + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Controllers/Pages/Plugins/PagesAddController.cs b/net452/SiteServer.Web/Controllers/Pages/Plugins/PagesAddController.cs new file mode 100644 index 000000000..6c1740cdd --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Plugins/PagesAddController.cs @@ -0,0 +1,48 @@ +using System; +using System.Linq; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Plugins +{ + [RoutePrefix("pages/plugins/add")] + public class PagesAddController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.PluginsPermissions.Add)) + { + return Unauthorized(); + } + + var dict = PluginManager.GetPluginIdAndVersionDict(); + var list = dict.Keys.ToList(); + var packageIds = TranslateUtils.ObjectCollectionToString(list); + + return Ok(new + { + IsNightly = WebConfigUtils.IsNightlyUpdate, + SystemManager.PluginVersion, + PackageIds = packageIds + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Plugins/PagesAddLayerUploadController.cs b/net452/SiteServer.Web/Controllers/Pages/Plugins/PagesAddLayerUploadController.cs new file mode 100644 index 000000000..75d2f6402 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Plugins/PagesAddLayerUploadController.cs @@ -0,0 +1,145 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Web; +using System.Web.Http; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Plugins +{ + [RoutePrefix("pages/plugins/addLayerUpload")] + public class PagesAddLayerUploadController : ApiController + { + private const string Route = ""; + private const string RouteUpload = "actions/upload"; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.PluginsPermissions.Add)) + { + return Unauthorized(); + } + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteUpload)] + public IHttpActionResult Upload() + { + try + { +#pragma warning disable CS0612 // '“RequestImpl”已过时 + var request = new RequestImpl(HttpContext.Current.Request); +#pragma warning restore CS0612 // '“RequestImpl”已过时 + + if (!request.IsAdminLoggin || + !request.AdminPermissionsImpl.HasSystemPermissions(ConfigManager.PluginsPermissions.Add)) + { + return Unauthorized(); + } + + var fileName = request.HttpRequest["fileName"]; + + var fileCount = request.HttpRequest.Files.Count; + + string filePath = null; + + if (fileCount > 0) + { + var file = request.HttpRequest.Files[0]; + + if (string.IsNullOrEmpty(fileName)) fileName = Path.GetFileName(file.FileName); + + var extendName = fileName.Substring(fileName.LastIndexOf(".", StringComparison.Ordinal)).ToLower(); + if (extendName == ".nupkg") + { + filePath = PathUtils.GetTemporaryFilesPath(fileName); + DirectoryUtils.CreateDirectoryIfNotExists(filePath); + file.SaveAs(filePath); + } + } + + FileInfo fileInfo = null; + if (!string.IsNullOrEmpty(filePath)) + { + fileInfo = new FileInfo(filePath); + } + if (fileInfo != null) + { + return Ok(new + { + fileName, + length = fileInfo.Length, + ret = 1 + }); + } + + return Ok(new + { + ret = 0 + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.PluginsPermissions.Add)) + { + return Unauthorized(); + } + + var fileNames = Request.GetPostObject>("fileNames"); + + foreach (var fileName in fileNames) + { + var localFilePath = PathUtils.GetTemporaryFilesPath(fileName); + + //var importObject = new ImportObject(siteId, rest.AdminName); + //importObject.ImportContentsByZipFile(channelInfo, localFilePath, isOverride, isChecked, checkedLevel, rest.AdminId, 0, SourceManager.Default); + } + + LogUtils.AddAdminLog(rest.AdminName, "安装离线插件", string.Empty); + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Plugins/PagesInstallController.cs b/net452/SiteServer.Web/Controllers/Pages/Plugins/PagesInstallController.cs new file mode 100644 index 000000000..9fa4759cf --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Plugins/PagesInstallController.cs @@ -0,0 +1,140 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Packaging; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Plugins +{ + [RoutePrefix("pages/plugins/install")] + public class PagesInstallController : ApiController + { + private const string RouteConfig = "config"; + private const string RouteDownload = "download"; + private const string RouteUpdate = "update"; + private const string RouteCache = "cache"; + + [HttpGet, Route(RouteConfig)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.PluginsPermissions.Add)) + { + return Unauthorized(); + } + + return Ok(new + { + IsNightly = WebConfigUtils.IsNightlyUpdate, + SystemManager.PluginVersion, + DownloadPlugins = PluginManager.PackagesIdAndVersionList + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteDownload)] + public IHttpActionResult Download() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.PluginsPermissions.Add)) + { + return Unauthorized(); + } + + var packageId = Request.GetPostString("packageId"); + var version = Request.GetPostString("version"); + + if (!StringUtils.EqualsIgnoreCase(packageId, PackageUtils.PackageIdSiteServerPlugin)) + { + try + { + PackageUtils.DownloadPackage(packageId, version); + } + catch + { + PackageUtils.DownloadPackage(packageId, version); + } + } + + return Ok(); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteUpdate)] + public IHttpActionResult Update() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.PluginsPermissions.Add)) + { + return Unauthorized(); + } + + var packageId = Request.GetPostString("packageId"); + var version = Request.GetPostString("version"); + var packageType = Request.GetPostString("packageType"); + + if (!StringUtils.EqualsIgnoreCase(packageId, PackageUtils.PackageIdSiteServerPlugin)) + { + string errorMessage; + var idWithVersion = $"{packageId}.{version}"; + if (!PackageUtils.UpdatePackage(idWithVersion, PackageType.Parse(packageType), out errorMessage)) + { + return BadRequest(errorMessage); + } + } + + return Ok(); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + + [HttpPost, Route(RouteCache)] + public IHttpActionResult Cache() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.PluginsPermissions.Add)) + { + return Unauthorized(); + } + + CacheUtils.ClearAll(); + CacheDbUtils.Clear(); + + return Ok(new { }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Plugins/PagesManageController.cs b/net452/SiteServer.Web/Controllers/Pages/Plugins/PagesManageController.cs new file mode 100644 index 000000000..9e3a3b1d9 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Plugins/PagesManageController.cs @@ -0,0 +1,135 @@ +using System; +using System.Linq; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Plugins +{ + [RoutePrefix("pages/plugins/manage")] + public class PagesManageController : ApiController + { + private const string Route = ""; + private const string RoutePluginId = "{pluginId}"; + private const string RouteActionsReload = "actions/reload"; + private const string RoutePluginIdEnable = "{pluginId}/actions/enable"; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.PluginsPermissions.Add)) + { + return Unauthorized(); + } + + var dict = PluginManager.GetPluginIdAndVersionDict(); + var list = dict.Keys.ToList(); + var packageIds = TranslateUtils.ObjectCollectionToString(list); + + return Ok(new + { + IsNightly = WebConfigUtils.IsNightlyUpdate, + SystemManager.PluginVersion, + AllPackages = PluginManager.AllPluginInfoList, + PackageIds = packageIds + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpDelete, Route(RoutePluginId)] + public IHttpActionResult Delete(string pluginId) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.PluginsPermissions.Add)) + { + return Unauthorized(); + } + + PluginManager.Delete(pluginId); + LogUtils.AddAdminLog(rest.AdminName, "删除插件", $"插件:{pluginId}"); + + CacheUtils.ClearAll(); + CacheDbUtils.Clear(); + + return Ok(); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteActionsReload)] + public IHttpActionResult Reload() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.PluginsPermissions.Add)) + { + return Unauthorized(); + } + + CacheUtils.ClearAll(); + CacheDbUtils.Clear(); + + return Ok(); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(RoutePluginIdEnable)] + public IHttpActionResult Enable(string pluginId) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.PluginsPermissions.Add)) + { + return Unauthorized(); + } + + var pluginInfo = PluginManager.GetPluginInfo(pluginId); + if (pluginInfo != null) + { + pluginInfo.IsDisabled = !pluginInfo.IsDisabled; + DataProvider.Plugin.UpdateIsDisabled(pluginId, pluginInfo.IsDisabled); + PluginManager.ClearCache(); + + LogUtils.AddAdminLog(rest.AdminName, !pluginInfo.IsDisabled ? "禁用插件" : "启用插件", $"插件:{pluginId}"); + } + + CacheUtils.ClearAll(); + CacheDbUtils.Clear(); + + return Ok(); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Plugins/PagesViewController.cs b/net452/SiteServer.Web/Controllers/Pages/Plugins/PagesViewController.cs new file mode 100644 index 000000000..8f54518d5 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Plugins/PagesViewController.cs @@ -0,0 +1,47 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Plugins +{ + [RoutePrefix("pages/plugins/view")] + public class PagesViewController : ApiController + { + private const string Route = "{pluginId}"; + + [HttpGet, Route(Route)] + public IHttpActionResult Get(string pluginId) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.PluginsPermissions.Add)) + { + return Unauthorized(); + } + + var plugin = PluginManager.GetPlugin(pluginId); + + return Ok(new + { + IsNightly = WebConfigUtils.IsNightlyUpdate, + SystemManager.PluginVersion, + Installed = plugin != null, + InstalledVersion = plugin != null ? plugin.Version : string.Empty, + Package = plugin + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdminAccessTokensController.cs b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdminAccessTokensController.cs new file mode 100644 index 000000000..376aab368 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdminAccessTokensController.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Settings +{ + [RoutePrefix("pages/settings/adminAccessTokens")] + public class PagesAdminAccessTokensController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult GetList() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + var adminNames = new List(); + + if (rest.AdminPermissions.IsSuperAdmin()) + { + adminNames = DataProvider.Administrator.GetUserNameList().ToList(); + } + else + { + adminNames.Add(rest.AdminName); + } + + var scopes = new List(AccessTokenManager.ScopeList); + + foreach (var service in PluginManager.Services) + { + if (service.IsApiAuthorization) + { + scopes.Add(service.PluginId); + } + } + + return Ok(new + { + Value = DataProvider.AccessToken.GetAll(), + adminNames, + scopes, + rest.AdminName + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpDelete, Route(Route)] + public IHttpActionResult Delete() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + var id = Request.GetQueryInt("id"); + DataProvider.AccessToken.Delete(id); + + return Ok(new + { + Value = DataProvider.AccessToken.GetAll() + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit([FromBody] AccessTokenInfo itemObj) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + if (itemObj.Id > 0) + { + var tokenInfo = DataProvider.AccessToken.Get(itemObj.Id); + + if (tokenInfo.Title != itemObj.Title && DataProvider.AccessToken.IsTitleExists(itemObj.Title)) + { + return BadRequest("保存失败,已存在相同标题的API密钥!"); + } + + tokenInfo.Title = itemObj.Title; + tokenInfo.AdminName = itemObj.AdminName; + tokenInfo.Scopes = itemObj.Scopes; + + DataProvider.AccessToken.Update(tokenInfo); + + LogUtils.AddAdminLog(rest.AdminName, "修改API密钥", $"Access Token:{tokenInfo.Title}"); + } + else + { + if (DataProvider.AccessToken.IsTitleExists(itemObj.Title)) + { + return BadRequest("保存失败,已存在相同标题的API密钥!"); + } + + var tokenInfo = new AccessTokenInfo + { + Title = itemObj.Title, + AdminName = itemObj.AdminName, + Scopes = itemObj.Scopes + }; + + DataProvider.AccessToken.Insert(tokenInfo); + + LogUtils.AddAdminLog(rest.AdminName, "新增API密钥", $"Access Token:{tokenInfo.Title}"); + } + + return Ok(new + { + Value = DataProvider.AccessToken.GetAll() + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdminAccessTokensViewLayerController.cs b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdminAccessTokensViewLayerController.cs new file mode 100644 index 000000000..3c2dba8e9 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdminAccessTokensViewLayerController.cs @@ -0,0 +1,74 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Settings +{ + [RoutePrefix("pages/settings/adminAccessTokensViewLayer")] + public class PagesAdminAccessTokensViewLayerController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + var id = Request.GetQueryInt("id"); + + var tokenInfo = DataProvider.AccessToken.Get(id); + var accessToken = TranslateUtils.DecryptStringBySecretKey(tokenInfo.Token); + + return Ok(new + { + tokenInfo, + accessToken + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Regenerate() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + var id = Request.GetPostInt("id"); + var accessTokenInfo = DataProvider.AccessToken.Get(id); + + var accessToken = TranslateUtils.DecryptStringBySecretKey(DataProvider.AccessToken.Regenerate(accessTokenInfo)); + + return Ok(new + { + Value = accessToken + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdminPasswordController.cs b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdminPasswordController.cs new file mode 100644 index 000000000..ed6740229 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdminPasswordController.cs @@ -0,0 +1,80 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Settings +{ + [RoutePrefix("pages/settings/adminPassword")] + public class PagesAdminPasswordController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var userId = Request.GetQueryInt("userId"); + if (!rest.IsAdminLoggin) return Unauthorized(); + var adminInfo = AdminManager.GetAdminInfoByUserId(userId); + if (adminInfo == null) return NotFound(); + if (rest.AdminId != userId && + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + return Ok(new + { + Value = adminInfo + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var userId = Request.GetQueryInt("userId"); + if (!rest.IsAdminLoggin) return Unauthorized(); + var adminInfo = AdminManager.GetAdminInfoByUserId(userId); + if (adminInfo == null) return NotFound(); + if (rest.AdminId != userId && + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + var password = Request.GetPostString("password"); + + if (!DataProvider.Administrator.ChangePassword(adminInfo, password, out var errorMessage)) + { + return BadRequest($"更改密码失败:{errorMessage}"); + } + + LogUtils.AddAdminLog(rest.AdminName, "重设管理员密码", $"管理员:{adminInfo.UserName}"); + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdminProfileController.cs b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdminProfileController.cs new file mode 100644 index 000000000..7a077dcc7 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdminProfileController.cs @@ -0,0 +1,269 @@ +using System; +using System.Collections.Generic; +using System.Web; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.API.Controllers.Pages.Settings +{ + [RoutePrefix("pages/settings/adminProfile")] + public class PagesAdminProfileController : ApiController + { + private const string Route = ""; + private const string RouteUpload = "upload"; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var userId = Request.GetQueryInt("userId"); + if (!rest.IsAdminLoggin) return Unauthorized(); + if (rest.AdminId != userId && + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + AdministratorInfo adminInfo; + if (userId > 0) + { + adminInfo = AdminManager.GetAdminInfoByUserId(userId); + if (adminInfo == null) return NotFound(); + } + else + { + adminInfo = new AdministratorInfo(); + } + + var departments = new List> + { + new KeyValuePair(0, "<无所属部门>") + }; + var departmentIdList = DepartmentManager.GetDepartmentIdList(); + var isLastNodeArrayOfDepartment = new bool[departmentIdList.Count]; + foreach (var departmentId in departmentIdList) + { + var departmentInfo = DepartmentManager.GetDepartmentInfo(departmentId); + departments.Add(new KeyValuePair(departmentId, + GetDepartment(isLastNodeArrayOfDepartment, departmentInfo.DepartmentName, + departmentInfo.ParentsCount, departmentInfo.LastNode))); + } + + var areas = new List> + { + new KeyValuePair(0, "<无所在区域>") + }; + var areaIdList = AreaManager.GetAreaIdList(); + var isLastNodeArrayOfArea = new bool[areaIdList.Count]; + foreach (var areaId in areaIdList) + { + var areaInfo = AreaManager.GetAreaInfo(areaId); + areas.Add(new KeyValuePair(areaId, + GetArea(isLastNodeArrayOfArea, areaInfo.AreaName, areaInfo.ParentsCount, areaInfo.LastNode))); + } + + return Ok(new + { + Value = adminInfo, + Departments = departments, + Areas = areas, + AdminToken = Request.GetAdminToken() + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + private static string GetDepartment(IList isLastNodeArrayOfDepartment, string departmentName, int parentsCount, bool isLastNode) + { + var str = ""; + if (isLastNode == false) + { + isLastNodeArrayOfDepartment[parentsCount] = false; + } + else + { + isLastNodeArrayOfDepartment[parentsCount] = true; + } + for (var i = 0; i < parentsCount; i++) + { + str = string.Concat(str, isLastNodeArrayOfDepartment[i] ? " " : "│"); + } + str = string.Concat(str, isLastNode ? "└" : "├"); + str = string.Concat(str, departmentName); + return str; + } + + private static string GetArea(IList isLastNodeArrayOfArea, string areaName, int parentsCount, bool isLastNode) + { + var str = ""; + if (isLastNode == false) + { + isLastNodeArrayOfArea[parentsCount] = false; + } + else + { + isLastNodeArrayOfArea[parentsCount] = true; + } + for (var i = 0; i < parentsCount; i++) + { + str = string.Concat(str, isLastNodeArrayOfArea[i] ? " " : "│"); + } + str = string.Concat(str, isLastNode ? "└" : "├"); + str = string.Concat(str, areaName); + return str; + } + + [HttpPost, Route(RouteUpload)] + public IHttpActionResult Upload() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var userId = Request.GetQueryInt("userId"); + if (!rest.IsAdminLoggin) return Unauthorized(); + var adminInfo = AdminManager.GetAdminInfoByUserId(userId); + if (adminInfo == null) return NotFound(); + if (rest.AdminId != userId && + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + var avatarUrl = string.Empty; + + foreach (string name in HttpContext.Current.Request.Files) + { + var postFile = HttpContext.Current.Request.Files[name]; + + if (postFile == null) + { + return BadRequest("Could not read image from body"); + } + + var fileName = AdminManager.GetUserUploadFileName(postFile.FileName); + var filePath = AdminManager.GetUserUploadPath(userId, fileName); + + if (!EFileSystemTypeUtils.IsImage(PathUtils.GetExtension(fileName))) + { + return BadRequest("image file extension is not correct"); + } + + postFile.SaveAs(filePath); + + avatarUrl = AdminManager.GetUserUploadUrl(userId, fileName); + } + + return Ok(new + { + Value = avatarUrl + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var userId = Request.GetQueryInt("userId"); + if (!rest.IsAdminLoggin) return Unauthorized(); + if (rest.AdminId != userId && + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + AdministratorInfo adminInfo; + if (userId > 0) + { + adminInfo = AdminManager.GetAdminInfoByUserId(userId); + if (adminInfo == null) return NotFound(); + } + else + { + adminInfo = new AdministratorInfo(); + } + + var userName = Request.GetPostString("userName"); + var password = Request.GetPostString("password"); + var displayName = Request.GetPostString("displayName"); + var avatarUrl = Request.GetPostString("avatarUrl"); + var mobile = Request.GetPostString("mobile"); + var email = Request.GetPostString("email"); + var departmentId = Request.GetPostInt("departmentId"); + var areaId = Request.GetPostInt("areaId"); + + if (adminInfo.Id == 0) + { + adminInfo.UserName = userName; + adminInfo.Password = password; + adminInfo.CreatorUserName = rest.AdminName; + adminInfo.CreationDate = DateTime.Now; + } + else + { + if (adminInfo.Mobile != mobile && !string.IsNullOrEmpty(mobile) && DataProvider.Administrator.IsMobileExists(mobile)) + { + return BadRequest("资料修改失败,手机号码已存在"); + } + + if (adminInfo.Email != email && !string.IsNullOrEmpty(email) && DataProvider.Administrator.IsEmailExists(email)) + { + return BadRequest("资料修改失败,邮箱地址已存在"); + } + } + + adminInfo.DisplayName = displayName; + adminInfo.AvatarUrl = avatarUrl; + adminInfo.Mobile = mobile; + adminInfo.Email = email; + adminInfo.DepartmentId = departmentId; + adminInfo.AreaId = areaId; + + if (adminInfo.Id == 0) + { + if (DataProvider.Administrator.Insert(adminInfo, out var errorMessage) == 0) + { + return BadRequest(errorMessage); + } + LogUtils.AddAdminLog(rest.AdminName, "添加管理员", $"管理员:{adminInfo.UserName}"); + } + else + { + if (!DataProvider.Administrator.Update(adminInfo, out var errorMessage)) + { + return BadRequest(errorMessage); + } + LogUtils.AddAdminLog(rest.AdminName, "修改管理员属性", $"管理员:{adminInfo.UserName}"); + } + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdminViewController.cs b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdminViewController.cs new file mode 100644 index 000000000..8fd1e7aa3 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdminViewController.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Settings +{ + [RoutePrefix("pages/settings/adminView")] + public class PagesAdminViewController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var userId = Request.GetQueryInt("userId"); + if (!rest.IsAdminLoggin) return Unauthorized(); + var adminInfo = AdminManager.GetAdminInfoByUserId(userId); + if (adminInfo == null) return NotFound(); + if (rest.AdminId != userId && + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + var departmentName = DepartmentManager.GetDepartmentName(adminInfo.DepartmentId); + var areaName = AreaManager.GetAreaName(adminInfo.AreaId); + + var permissions = new PermissionsImpl(adminInfo); + var level = permissions.GetAdminLevel(); + var isSuperAdmin = permissions.IsConsoleAdministrator; + var siteNames = new List(); + if (!isSuperAdmin) + { + var siteIdListWithPermissions = permissions.GetSiteIdList(); + foreach (var siteId in siteIdListWithPermissions) + { + siteNames.Add(SiteManager.GetSiteName(SiteManager.GetSiteInfo(siteId))); + } + } + var isOrdinaryAdmin = !permissions.IsSystemAdministrator; + var roleNames = string.Empty; + if (isOrdinaryAdmin) + { + roleNames = AdminManager.GetRoleNames(adminInfo.UserName); + } + + return Ok(new + { + Value = adminInfo, + DepartmentName = departmentName, + AreaName = areaName, + Level = level, + IsSuperAdmin = isSuperAdmin, + SiteNames = TranslateUtils.ObjectCollectionToString(siteNames, "
    "), + IsOrdinaryAdmin = isOrdinaryAdmin, + RoleNames = roleNames + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdministratorsController.cs b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdministratorsController.cs new file mode 100644 index 000000000..646210f68 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesAdministratorsController.cs @@ -0,0 +1,288 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; +using SqlKata; + +namespace SiteServer.API.Controllers.Pages.Settings +{ + [RoutePrefix("pages/settings/administrators")] + public class PagesAdministratorsController : ApiController + { + private const string Route = ""; + private const string RouteActionsLock = "actions/lock"; + private const string RouteActionsUnLock = "actions/unlock"; + private const string RouteActionsDelete = "actions/delete"; + + [HttpGet, Route(Route)] + public IHttpActionResult GetList() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + const int pageSize = Constants.PageSize; + var page = Request.GetQueryInt("page", 1); + + var keyword = Request.GetQueryString("keyword"); + var roleName = Request.GetQueryString("roleName"); + var order = Request.GetQueryString("order"); + var departmentId = Request.GetQueryInt("departmentId"); + var areaId = Request.GetQueryInt("areaId"); + + var query = new Query(); + + if (!string.IsNullOrEmpty(keyword)) + { + query.Where(q => q + .WhereLike(nameof(AdministratorInfo.UserName), keyword) + .OrWhereLike(nameof(AdministratorInfo.Email), keyword) + .OrWhereLike(nameof(AdministratorInfo.Mobile), keyword) + .OrWhereLike(nameof(AdministratorInfo.DisplayName), keyword) + ); + } + + if (!rest.AdminPermissions.IsSuperAdmin()) + { + query.Where(nameof(AdministratorInfo.CreatorUserName), rest.AdminName); + } + + if (departmentId != 0) + { + query.Where(nameof(AdministratorInfo.DepartmentId), departmentId); + } + + if (areaId != 0) + { + query.Where(nameof(AdministratorInfo.AreaId), areaId); + } + + if (!string.IsNullOrEmpty(roleName)) + { + var userNameList = DataProvider.AdministratorsInRoles.GetUserNameListByRoleName(roleName); + + query.WhereIn(nameof(AdministratorInfo.UserName), userNameList); + } + + var count = DataProvider.Administrator.GetCount(query); + var pages = Convert.ToInt32(Math.Ceiling((double)count / pageSize)); + if (pages == 0) pages = 1; + + var administratorInfoList = new List(); + + if (count > 0) + { + var offset = pageSize * (page - 1); + var tableColumns = DataProvider.Administrator.TableColumns; + + var columnNames = tableColumns.Where(x => + x.AttributeName != nameof(AdministratorInfo.Password) && + x.AttributeName != nameof(AdministratorInfo.PasswordFormat) && + x.AttributeName != nameof(AdministratorInfo.PasswordSalt)).Select(x => x.AttributeName); + + query.Select(columnNames.ToArray()).Offset(offset).Limit(pageSize); + if (string.IsNullOrEmpty(order)) + { + query.OrderBy(nameof(AdministratorInfo.Id)); + } + else + { + if (StringUtils.EndsWithIgnoreCase(order, " DESC")) + { + query.OrderByDesc(StringUtils.ReplaceEndsWithIgnoreCase(order, " DESC", string.Empty)); + } + else + { + query.OrderBy(order); + } + } + + administratorInfoList = DataProvider.Administrator.GetAll(query).ToList(); + } + + var roles = RoleManager.GetRestRoles(rest.AdminPermissions.IsSuperAdmin(), rest.AdminName); + + var departments = DepartmentManager.GetRestDepartments(); + var areas = AreaManager.GetRestAreas(); + + var adminLockLoginType = + EUserLockTypeUtils.GetEnumType(ConfigManager.Instance.AdminLockLoginType); + var isAdminLockLogin = ConfigManager.Instance.IsAdminLockLogin; + var adminLockLoginCount = ConfigManager.Instance.AdminLockLoginCount; + var adminLockLoginHours = ConfigManager.Instance.AdminLockLoginHours; + + var pageContents = new List>(); + + foreach (var administratorInfo in administratorInfoList) + { + dynamic dynamicObj = administratorInfo; + + var state = string.Empty; + if (administratorInfo.Locked) + { + state = "[已被锁定]"; + } + else if (isAdminLockLogin && adminLockLoginCount <= administratorInfo.CountOfFailedLogin) + { + if (adminLockLoginType == EUserLockType.Forever) + { + state = @"[已被锁定]"; + } + else if (administratorInfo.LastActivityDate.HasValue) + { + var ts = new TimeSpan(DateTime.Now.Ticks - administratorInfo.LastActivityDate.Value.Ticks); + var hours = Convert.ToInt32(adminLockLoginHours - ts.TotalHours); + if (hours > 0) + { + state = $@"[错误登录次数过多,已被锁定{hours}小时]"; + } + } + } + + dynamicObj.State = state; + dynamicObj.DepartmentName = + DepartmentManager.GetDepartmentName(administratorInfo.DepartmentId); + dynamicObj.AreaName = + AreaManager.GetAreaName(administratorInfo.AreaId); + if (administratorInfo.LastActivityDate.HasValue) + { + dynamicObj.LastLoginDate = DateUtils.ParseThisMoment(administratorInfo.LastActivityDate.Value); + } + + dynamicObj.RoleName = AdminManager.GetRoleNames(administratorInfo.UserName); + + dynamicObj.NotMe = administratorInfo.Id != rest.AdminId; + + pageContents.Add((IDictionary)dynamicObj); + } + + + return Ok(new + { + Value = pageContents, + Count = count, + Pages = pages, + Roles = roles, + Departments = departments, + Areas = areas + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteActionsDelete)] + public IHttpActionResult Delete() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + var adminIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("adminIds")); + adminIdList.Remove(rest.AdminId); + + foreach (var adminId in adminIdList) + { + var adminInfo = AdminManager.GetAdminInfoByUserId(adminId); + DataProvider.Administrator.Delete(adminInfo); + + LogUtils.AddAdminLog(rest.AdminName, "删除管理员", $"管理员:{adminInfo.UserName}"); + } + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteActionsLock)] + public IHttpActionResult Lock() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + var adminIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("adminIds")); + adminIdList.Remove(rest.AdminId); + + DataProvider.Administrator.Lock(adminIdList); + LogUtils.AddAdminLog(rest.AdminName, "锁定管理员"); + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteActionsUnLock)] + public IHttpActionResult UnLock() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + var adminIdList = TranslateUtils.StringCollectionToIntList(Request.GetPostString("adminIds")); + adminIdList.Remove(rest.AdminId); + + DataProvider.Administrator.UnLock(adminIdList); + LogUtils.AddAdminLog(rest.AdminName, "解锁管理员"); + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Settings/PagesSiteAddController.cs b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesSiteAddController.cs new file mode 100644 index 000000000..9856db1ba --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesSiteAddController.cs @@ -0,0 +1,243 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using Datory; +using SiteServer.BackgroundPages.Cms; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Database.Repositories.Contents; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.API.Controllers.Pages.Settings +{ + [RoutePrefix("pages/settings/siteAdd")] + public class PagesSiteAddController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.SiteAdd)) + { + return Unauthorized(); + } + + var siteTemplates = SiteTemplateManager.Instance.GetSiteTemplateSortedList(); + + var siteList = new List> + { + new KeyValuePair(0, "<无上级站点>") + }; + + var siteIdList = SiteManager.GetSiteIdList(); + var siteInfoList = new List(); + var parentWithChildren = new Dictionary>(); + foreach (var siteId in siteIdList) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo.Root == false) + { + if (siteInfo.ParentId == 0) + { + siteInfoList.Add(siteInfo); + } + else + { + var children = new List(); + if (parentWithChildren.ContainsKey(siteInfo.ParentId)) + { + children = parentWithChildren[siteInfo.ParentId]; + } + children.Add(siteInfo); + parentWithChildren[siteInfo.ParentId] = children; + } + } + } + foreach (SiteInfo siteInfo in siteInfoList) + { + AddSite(siteList, siteInfo, parentWithChildren, 0); + } + + var tableNameList = SiteManager.GetSiteTableNames(); + + var isRootExists = SiteManager.GetSiteInfoByIsRoot() != null; + + return Ok(new + { + Value = siteTemplates.Values, + IsRootExists = isRootExists, + SiteList = siteList, + TableNameList = tableNameList + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + private static void AddSite(List> siteList, SiteInfo siteInfo, Dictionary> parentWithChildren, int level) + { + if (level > 1) return; + var padding = string.Empty; + for (var i = 0; i < level; i++) + { + padding += " "; + } + if (level > 0) + { + padding += "└ "; + } + + if (parentWithChildren.ContainsKey(siteInfo.Id)) + { + var children = parentWithChildren[siteInfo.Id]; + siteList.Add(new KeyValuePair(siteInfo.Id, padding + siteInfo.SiteName + $"({children.Count})")); + level++; + foreach (var subSiteInfo in children) + { + AddSite(siteList, subSiteInfo, parentWithChildren, level); + } + } + else + { + siteList.Add(new KeyValuePair(siteInfo.Id, padding + siteInfo.SiteName)); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.SiteAdd)) + { + return Unauthorized(); + } + + var createType = Request.GetPostString("createType"); + var createTemplateId = Request.GetPostString("createTemplateId"); + var siteName = Request.GetPostString("siteName"); + var isRoot = Request.GetPostBool("isRoot"); + var parentId = Request.GetPostInt("parentId"); + var siteDir = Request.GetPostString("siteDir"); + var tableRule = ETableRuleUtils.GetEnumType(Request.GetPostString("tableRule")); + var tableChoose = Request.GetPostString("tableChoose"); + var tableHandWrite = Request.GetPostString("tableHandWrite"); + var isImportContents = Request.GetPostBool("isImportContents"); + var isImportTableStyles = Request.GetPostBool("isImportTableStyles"); + + if (!isRoot) + { + if (DirectoryUtils.IsSystemDirectory(siteDir)) + { + return BadRequest("文件夹名称不能为系统文件夹名称,请更改文件夹名称!"); + } + if (!DirectoryUtils.IsDirectoryNameCompliant(siteDir)) + { + return BadRequest("文件夹名称不符合系统要求,请更改文件夹名称!"); + } + var list = DataProvider.Site.GetLowerSiteDirList(parentId); + if (list.IndexOf(siteDir.ToLower()) != -1) + { + return BadRequest("已存在相同的发布路径,请更改文件夹名称!"); + } + } + + var channelInfo = new ChannelInfo(); + + channelInfo.ChannelName = channelInfo.IndexName = "首页"; + channelInfo.ParentId = 0; + channelInfo.ContentModelPluginId = string.Empty; + + var tableName = string.Empty; + if (tableRule == ETableRule.Choose) + { + tableName = tableChoose; + } + else if (tableRule == ETableRule.HandWrite) + { + tableName = tableHandWrite; + if (!DatoryUtils.IsTableExists(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName)) + { + TableColumnManager.CreateTable(tableName, DataProvider.ContentRepository.TableColumnsDefault, string.Empty, true, out _); + } + else + { + TableColumnManager.AlterTable(tableName, DataProvider.ContentRepository.TableColumnsDefault, string.Empty); + } + } + + var siteInfo = new SiteInfo + { + SiteName = AttackUtils.FilterXss(siteName), + SiteDir = siteDir, + TableName = tableName, + ParentId = parentId, + Root = isRoot + }; + + siteInfo.IsCheckContentLevel = false; + siteInfo.Charset = ECharsetUtils.GetValue(ECharset.utf_8); + + var siteId = DataProvider.Channel.InsertSiteInfo(channelInfo, siteInfo, rest.AdminName); + + if (string.IsNullOrEmpty(tableName)) + { + tableName = ContentRepository.GetContentTableName(siteId); + if (!DatoryUtils.IsTableExists(WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, tableName)) + { + TableColumnManager.CreateTable(tableName, DataProvider.ContentRepository.TableColumnsDefault, string.Empty, true, out _); + } + DataProvider.Site.UpdateTableName(siteId, tableName); + } + + if (!rest.AdminPermissions.IsSuperAdmin()) + { + var siteIdList = rest.AdminPermissions.GetSiteIdList() ?? new List(); + siteIdList.Add(siteId); + var adminInfo = AdminManager.GetAdminInfoByUserId(rest.AdminId); + DataProvider.Administrator.UpdateSiteIdCollection(adminInfo, TranslateUtils.ObjectCollectionToString(siteIdList)); + } + + var siteTemplateDir = string.Empty; + var onlineTemplateName = string.Empty; + if (StringUtils.EqualsIgnoreCase(createType, "local")) + { + siteTemplateDir = createTemplateId; + } + else if (StringUtils.EqualsIgnoreCase(createType, "cloud")) + { + onlineTemplateName = createTemplateId; + } + + var redirectUrl = PageProgressBar.GetCreateSiteUrl(siteId, + isImportContents, isImportTableStyles, siteTemplateDir, onlineTemplateName, StringUtils.GetGuid()); + + return Ok(new + { + Value = redirectUrl + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Settings/PagesSiteTableController.cs b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesSiteTableController.cs new file mode 100644 index 000000000..5f28a63c3 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesSiteTableController.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Apis; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Settings +{ + [RoutePrefix("pages/settings/siteTables")] + public class PagesSiteTablesController : ApiController + { + private const string Route = ""; + private const string RouteActionsGetColumns = "actions/getColumns"; + private const string RouteActionsRemoveCache = "actions/removeCache"; + + [HttpGet, Route(Route)] + public IHttpActionResult GetTables() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Site)) + { + return Unauthorized(); + } + + var nameDict = new Dictionary>(StringComparer.OrdinalIgnoreCase); + + foreach (var siteInfo in SiteManager.GetSiteInfoList()) + { + if (nameDict.ContainsKey(siteInfo.TableName)) + { + var list = nameDict[siteInfo.TableName]; + list.Add(siteInfo.SiteName); + } + else + { + nameDict[siteInfo.TableName] = new List { siteInfo.SiteName }; + } + } + + return Ok(new + { + Value = nameDict.Keys, + nameDict + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteActionsGetColumns)] + public IHttpActionResult GetColumns() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Site)) + { + return Unauthorized(); + } + + var tableName = Request.GetPostString("tableName"); + + var columns = TableColumnManager.GetTableColumnInfoList(tableName, ContentAttribute.MetadataAttributes.Value); + + return Ok(new + { + Value = columns, + Count = DataProvider.DatabaseApi.GetCount(tableName) + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteActionsRemoveCache)] + public IHttpActionResult RemoveCache() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Site)) + { + return Unauthorized(); + } + + var tableName = Request.GetPostString("tableName"); + + TableColumnManager.ClearCache(); + + var columns = TableColumnManager.GetTableColumnInfoList(tableName, ContentAttribute.MetadataAttributes.Value); + + return Ok(new + { + Value = columns, + Count = DataProvider.DatabaseApi.GetCount(tableName) + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Settings/PagesUserConfigController.cs b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesUserConfigController.cs new file mode 100644 index 000000000..0194acc59 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesUserConfigController.cs @@ -0,0 +1,78 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Settings +{ + [RoutePrefix("pages/settings/userConfig")] + public class PagesUserConfigController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User)) + { + return Unauthorized(); + } + + return Ok(new + { + Value = ConfigManager.Instance + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User)) + { + return Unauthorized(); + } + + ConfigManager.Instance.IsUserRegistrationAllowed = Request.GetPostBool("isUserRegistrationAllowed"); + ConfigManager.Instance.IsUserRegistrationChecked = Request.GetPostBool("isUserRegistrationChecked"); + ConfigManager.Instance.IsUserUnRegistrationAllowed = Request.GetPostBool("isUserUnRegistrationAllowed"); + ConfigManager.Instance.UserPasswordMinLength = Request.GetPostInt("userPasswordMinLength"); + ConfigManager.Instance.UserPasswordRestriction = Request.GetPostString("userPasswordRestriction"); + ConfigManager.Instance.UserRegistrationMinMinutes = Request.GetPostInt("userRegistrationMinMinutes"); + ConfigManager.Instance.IsUserLockLogin = Request.GetPostBool("isUserLockLogin"); + ConfigManager.Instance.UserLockLoginCount = Request.GetPostInt("userLockLoginCount"); + ConfigManager.Instance.UserLockLoginType = Request.GetPostString("userLockLoginType"); + ConfigManager.Instance.UserLockLoginHours = Request.GetPostInt("userLockLoginHours"); + + DataProvider.Config.Update(ConfigManager.Instance); + + LogUtils.AddAdminLog(rest.AdminName, "修改用户设置"); + + return Ok(new + { + Value = ConfigManager.Instance + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Settings/PagesUserGroupController.cs b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesUserGroupController.cs new file mode 100644 index 000000000..23a075054 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesUserGroupController.cs @@ -0,0 +1,143 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Settings +{ + [RoutePrefix("pages/settings/userGroup")] + public class PagesUserGroupController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User)) + { + return Unauthorized(); + } + + var adminNames = DataProvider.Administrator.GetUserNameList(); + adminNames.Insert(0, string.Empty); + + return Ok(new + { + Value = UserGroupManager.GetUserGroupInfoList(), + AdminNames = adminNames + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpDelete, Route(Route)] + public IHttpActionResult Delete() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User)) + { + return Unauthorized(); + } + + var id = Request.GetQueryInt("id"); + + DataProvider.UserGroup.Delete(id); + + return Ok(new + { + Value = UserGroupManager.GetUserGroupInfoList() + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User)) + { + return Unauthorized(); + } + + var id = Request.GetPostInt("id"); + var groupName = Request.GetPostString("groupName"); + var adminName = Request.GetPostString("adminName"); + + if (id == -1) + { + if (UserGroupManager.IsExists(groupName)) + { + return BadRequest("保存失败,已存在相同名称的用户组!"); + } + + var groupInfo = new UserGroupInfo + { + GroupName = groupName, + AdminName = adminName + }; + + DataProvider.UserGroup.Insert(groupInfo); + + LogUtils.AddAdminLog(rest.AdminName, "新增用户组", $"用户组:{groupInfo.GroupName}"); + } + else if (id == 0) + { + ConfigManager.Instance.UserDefaultGroupAdminName = adminName; + + DataProvider.Config.Update(ConfigManager.Instance); + + UserGroupManager.ClearCache(); + + LogUtils.AddAdminLog(rest.AdminName, "修改用户组", "用户组:默认用户组"); + } + else if (id > 0) + { + var groupInfo = UserGroupManager.GetUserGroupInfo(id); + + if (groupInfo.GroupName != groupName && UserGroupManager.IsExists(groupName)) + { + return BadRequest("保存失败,已存在相同名称的用户组!"); + } + + groupInfo.GroupName = groupName; + groupInfo.AdminName = adminName; + + DataProvider.UserGroup.Update(groupInfo); + + LogUtils.AddAdminLog(rest.AdminName, "修改用户组", $"用户组:{groupInfo.GroupName}"); + } + + return Ok(new + { + Value = UserGroupManager.GetUserGroupInfoList() + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Settings/PagesUserHomeController.cs b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesUserHomeController.cs new file mode 100644 index 000000000..ba9dcff37 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesUserHomeController.cs @@ -0,0 +1,134 @@ +using System; +using System.Web; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.API.Controllers.Pages.Settings +{ + [RoutePrefix("pages/settings/userHome")] + public class PagesUserHomeController : ApiController + { + private const string Route = ""; + private const string RouteUpload = "upload"; + + [HttpGet, Route(Route)] + public IHttpActionResult GetConfig() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User)) + { + return Unauthorized(); + } + + return Ok(new + { + Value = ConfigManager.Instance, + WebConfigUtils.HomeDirectory, + AdminToken = Request.GetAdminToken(), + Styles = TableStyleManager.GetUserStyleInfoList() + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User)) + { + return Unauthorized(); + } + + ConfigManager.Instance.IsHomeClosed = Request.GetPostBool(nameof(ConfigManager.Instance.IsHomeClosed).ToCamelCase()); + ConfigManager.Instance.HomeTitle = Request.GetPostString(nameof(ConfigManager.Instance.HomeTitle).ToCamelCase()); + ConfigManager.Instance.IsHomeLogo = Request.GetPostBool(nameof(ConfigManager.Instance.IsHomeLogo).ToCamelCase()); + ConfigManager.Instance.HomeLogoUrl = Request.GetPostString(nameof(ConfigManager.Instance.HomeLogoUrl).ToCamelCase()); + ConfigManager.Instance.IsHomeBackground = Request.GetPostBool(nameof(ConfigManager.Instance.IsHomeBackground).ToCamelCase()); + ConfigManager.Instance.HomeBackgroundUrl = Request.GetPostString(nameof(ConfigManager.Instance.HomeBackgroundUrl).ToCamelCase()); + ConfigManager.Instance.HomeDefaultAvatarUrl = Request.GetPostString(nameof(ConfigManager.Instance.HomeDefaultAvatarUrl).ToCamelCase()); + ConfigManager.Instance.UserRegistrationAttributes = Request.GetPostString(nameof(ConfigManager.Instance.UserRegistrationAttributes).ToCamelCase()); + ConfigManager.Instance.IsUserRegistrationGroup = Request.GetPostBool(nameof(ConfigManager.Instance.IsUserRegistrationGroup).ToCamelCase()); + ConfigManager.Instance.IsHomeAgreement = Request.GetPostBool(nameof(ConfigManager.Instance.IsHomeAgreement).ToCamelCase()); + ConfigManager.Instance.HomeAgreementHtml = Request.GetPostString(nameof(ConfigManager.Instance.HomeAgreementHtml).ToCamelCase()); + + DataProvider.Config.Update(ConfigManager.Instance); + + LogUtils.AddAdminLog(rest.AdminName, "修改用户中心设置"); + + return Ok(new + { + Value = ConfigManager.Instance + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteUpload)] + public IHttpActionResult Upload() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User)) + { + return Unauthorized(); + } + + var homeLogoUrl = string.Empty; + + foreach (string name in HttpContext.Current.Request.Files) + { + var postFile = HttpContext.Current.Request.Files[name]; + + if (postFile == null) + { + return BadRequest("Could not read image from body"); + } + + var fileName = postFile.FileName; + var filePath = UserManager.GetHomeUploadPath(fileName); + + if (!EFileSystemTypeUtils.IsImage(PathUtils.GetExtension(fileName))) + { + return BadRequest("image file extension is not correct"); + } + + postFile.SaveAs(filePath); + + homeLogoUrl = FxUtils.AddProtocolToUrl(UserManager.GetHomeUploadUrl(fileName)); + } + + return Ok(new + { + Value = homeLogoUrl + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Settings/PagesUserMenuController.cs b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesUserMenuController.cs new file mode 100644 index 000000000..9a2c0d7f1 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesUserMenuController.cs @@ -0,0 +1,136 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Settings +{ + [RoutePrefix("pages/settings/userMenu")] + public class PagesUserMenuController : ApiController + { + private const string Route = ""; + private const string RouteReset = "actions/reset"; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User)) + { + return Unauthorized(); + } + + return Ok(new + { + Value = UserMenuManager.GetAllUserMenuInfoList(), + Groups = UserGroupManager.GetUserGroupInfoList() + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpDelete, Route(Route)] + public IHttpActionResult Delete() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User)) + { + return Unauthorized(); + } + + var id = Request.GetQueryInt("id"); + + DataProvider.UserMenu.Delete(id); + + return Ok(new + { + Value = UserMenuManager.GetAllUserMenuInfoList() + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit([FromBody] UserMenuInfo menuInfo) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User)) + { + return Unauthorized(); + } + + if (menuInfo.Id == 0) + { + DataProvider.UserMenu.Insert(menuInfo); + + LogUtils.AddAdminLog(rest.AdminName, "新增用户菜单", $"用户菜单:{menuInfo.Text}"); + } + else if (menuInfo.Id > 0) + { + DataProvider.UserMenu.Update(menuInfo); + + LogUtils.AddAdminLog(rest.AdminName, "修改用户菜单", $"用户菜单:{menuInfo.Text}"); + } + + return Ok(new + { + Value = UserMenuManager.GetAllUserMenuInfoList() + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteReset)] + public IHttpActionResult Reset() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User)) + { + return Unauthorized(); + } + + foreach (var userMenuInfo in UserMenuManager.GetAllUserMenuInfoList()) + { + DataProvider.UserMenu.Delete(userMenuInfo.Id); + } + + LogUtils.AddAdminLog(rest.AdminName, "重置用户菜单"); + + return Ok(new + { + Value = UserMenuManager.GetAllUserMenuInfoList() + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Settings/PagesUserStyleController.cs b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesUserStyleController.cs new file mode 100644 index 000000000..d5e8bf6a8 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Settings/PagesUserStyleController.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Settings +{ + [RoutePrefix("pages/settings/userStyle")] + public class PagesUserStyleController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User)) + { + return Unauthorized(); + } + + var list = new List(); + foreach (var styleInfo in TableStyleManager.GetUserStyleInfoList()) + { + list.Add(new + { + styleInfo.Id, + styleInfo.AttributeName, + styleInfo.DisplayName, + InputType = InputTypeUtils.GetText(styleInfo.Type), + Validate = styleInfo.VeeValidate, + styleInfo.Taxis, + IsSystem = StringUtils.ContainsIgnoreCase(UserAttribute.AllAttributes.Value, styleInfo.AttributeName) + }); + } + + return Ok(new + { + Value = list, + DataProvider.User.TableName, + RelatedIdentities = TableStyleManager.EmptyRelatedIdentities + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpDelete, Route(Route)] + public IHttpActionResult Delete() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + var attributeName = Request.GetQueryString("attributeName"); + + DataProvider.TableStyle.Delete(0, DataProvider.User.TableName, attributeName); + + var list = new List(); + foreach (var styleInfo in TableStyleManager.GetUserStyleInfoList()) + { + list.Add(new + { + styleInfo.Id, + styleInfo.AttributeName, + styleInfo.DisplayName, + InputType = InputTypeUtils.GetText(styleInfo.Type), + Validate = TableStyleManager.GetValidateInfo(styleInfo), + styleInfo.Taxis, + IsSystem = StringUtils.ContainsIgnoreCase(UserAttribute.AllAttributes.Value, styleInfo.AttributeName) + }); + } + + return Ok(new + { + Value = list + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Shared/PagesTableStyleController.cs b/net452/SiteServer.Web/Controllers/Pages/Shared/PagesTableStyleController.cs new file mode 100644 index 000000000..9649e4797 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Shared/PagesTableStyleController.cs @@ -0,0 +1,269 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Shared +{ + [RoutePrefix("pages/shared/tableStyle")] + public class PagesTableStyleController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin) return Unauthorized(); + + var tableName = Request.GetQueryString("tableName"); + var attributeName = Request.GetQueryString("attributeName"); + var relatedIdentities = TranslateUtils.StringCollectionToIntList(Request.GetQueryString("relatedIdentities")); + + var styleInfo = TableStyleManager.GetTableStyleInfo(tableName, attributeName, relatedIdentities) ?? new TableStyleInfo + { + Type = InputType.Text + }; + if (styleInfo.StyleItems == null) + { + styleInfo.StyleItems = new List(); + } + + var isRapid = true; + var rapidValues = string.Empty; + if (styleInfo.StyleItems.Count == 0) + { + styleInfo.StyleItems.Add(new TableStyleItemInfo + { + ItemTitle = string.Empty, + ItemValue = string.Empty, + Selected = false + }); + } + else + { + var isSelected = false; + var isNotEquals = false; + var list = new List(); + foreach (var item in styleInfo.StyleItems) + { + list.Add(item.ItemValue); + if (item.Selected) + { + isSelected = true; + } + if (item.ItemValue != item.ItemTitle) + { + isNotEquals = true; + } + } + + isRapid = !isSelected && !isNotEquals; + rapidValues = string.Join(",", list); + } + + return Ok(new + { + Value = styleInfo, + InputTypes = InputTypeUtils.GetInputTypes(tableName), + IsRapid = isRapid, + RapidValues = rapidValues + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin) return Unauthorized(); + + var tableName = Request.GetPostString("tableName"); + var attributeName = Request.GetPostString("attributeName"); + var relatedIdentities = TranslateUtils.StringCollectionToIntList(Request.GetPostString("relatedIdentities")); + var isRapid = Request.GetPostBool("isRapid"); + var rapidValues = TranslateUtils.StringCollectionToStringList(Request.GetPostString("rapidValues")); + var body = Request.GetPostObject("styleInfo"); + + var styleInfoDatabase = + TableStyleManager.GetTableStyleInfo(tableName, attributeName, relatedIdentities) ?? + new TableStyleInfo(); + + bool isSuccess; + string errorMessage; + + //数据库中没有此项及父项的表样式 or 数据库中没有此项的表样式,但是有父项的表样式 + if (styleInfoDatabase.Id == 0 && styleInfoDatabase.RelatedIdentity == 0 || styleInfoDatabase.RelatedIdentity != relatedIdentities[0]) + { + isSuccess = InsertTableStyleInfo(tableName, relatedIdentities, body, isRapid, rapidValues, out errorMessage); + LogUtils.AddAdminLog(rest.AdminName, "添加表单显示样式", $"字段名:{body.AttributeName}"); + } + //数据库中有此项的表样式 + else + { + isSuccess = UpdateTableStyleInfo(styleInfoDatabase, body, isRapid, rapidValues, out errorMessage); + LogUtils.AddAdminLog(rest.AdminName, "修改表单显示样式", $"字段名:{body.AttributeName}"); + } + + if (!isSuccess) + { + return BadRequest(errorMessage); + } + + return Ok(new{}); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + private bool InsertTableStyleInfo(string tableName, List relatedIdentities, TableStyleInfo body, bool isRapid, List rapidValues, out string errorMessage) + { + errorMessage = string.Empty; + + var relatedIdentity = relatedIdentities[0]; + + if (string.IsNullOrEmpty(body.AttributeName)) + { + errorMessage = "操作失败,字段名不能为空!"; + return false; + } + + if (TableStyleManager.IsExists(relatedIdentity, tableName, body.AttributeName)) + { + errorMessage = $@"显示样式添加失败:字段名""{body.AttributeName}""已存在"; + return false; + } + + var styleInfo = TableColumnManager.IsAttributeNameExists(tableName, body.AttributeName) ? TableStyleManager.GetTableStyleInfo(tableName, body.AttributeName, relatedIdentities) : new TableStyleInfo(); + + styleInfo.RelatedIdentity = relatedIdentity; + styleInfo.TableName = tableName; + styleInfo.AttributeName = body.AttributeName; + styleInfo.DisplayName = AttackUtils.FilterXss(body.DisplayName); + styleInfo.HelpText = body.HelpText; + styleInfo.Taxis = body.Taxis; + styleInfo.Type = body.Type; + styleInfo.DefaultValue = body.DefaultValue; + styleInfo.Horizontal = body.Horizontal; + styleInfo.ExtendValues = body.ExtendValues; + styleInfo.StyleItems = new List(); + + if (body.Type == InputType.CheckBox || body.Type == InputType.Radio || body.Type == InputType.SelectMultiple || body.Type == InputType.SelectOne) + { + if (isRapid) + { + foreach (var rapidValue in rapidValues) + { + var itemInfo = new TableStyleItemInfo + { + ItemTitle = rapidValue, + ItemValue = rapidValue, + Selected = false + }; + styleInfo.StyleItems.Add(itemInfo); + } + } + else + { + var isHasSelected = false; + foreach (var styleItem in body.StyleItems) + { + if (body.Type != InputType.SelectMultiple && body.Type != InputType.CheckBox && isHasSelected && styleItem.Selected) + { + errorMessage = "操作失败,只能有一个初始化时选定项!"; + return false; + } + if (styleItem.Selected) isHasSelected = true; + + var itemInfo = new TableStyleItemInfo + { + ItemTitle = styleItem.ItemTitle, + ItemValue = styleItem.ItemValue, + Selected = styleItem.Selected + }; + styleInfo.StyleItems.Add(itemInfo); + } + } + } + + DataProvider.TableStyle.Insert(styleInfo); + + return true; + } + + private bool UpdateTableStyleInfo(TableStyleInfo styleInfo, TableStyleInfo body, bool isRapid, List rapidValues, out string errorMessage) + { + errorMessage = string.Empty; + + styleInfo.AttributeName = body.AttributeName; + styleInfo.DisplayName = AttackUtils.FilterXss(body.DisplayName); + styleInfo.HelpText = body.HelpText; + styleInfo.Taxis = body.Taxis; + styleInfo.Type = body.Type; + styleInfo.DefaultValue = body.DefaultValue; + styleInfo.Horizontal = body.Horizontal; + styleInfo.ExtendValues = body.ExtendValues; + styleInfo.StyleItems = new List(); + + if (body.Type == InputType.CheckBox || body.Type == InputType.Radio || body.Type == InputType.SelectMultiple || body.Type == InputType.SelectOne) + { + if (isRapid) + { + foreach (var rapidValue in rapidValues) + { + var itemInfo = new TableStyleItemInfo + { + TableStyleId = styleInfo.Id, + ItemTitle = rapidValue, + ItemValue = rapidValue, + Selected = false + }; + styleInfo.StyleItems.Add(itemInfo); + } + } + else + { + var isHasSelected = false; + foreach (var styleItem in body.StyleItems) + { + if (body.Type != InputType.SelectMultiple && body.Type != InputType.CheckBox && isHasSelected && styleItem.Selected) + { + errorMessage = "操作失败,只能有一个初始化时选定项!"; + return false; + } + if (styleItem.Selected) isHasSelected = true; + + var itemInfo = new TableStyleItemInfo + { + TableStyleId = styleInfo.Id, + ItemTitle = styleItem.ItemTitle, + ItemValue = styleItem.ItemValue, + Selected = styleItem.Selected + }; + styleInfo.StyleItems.Add(itemInfo); + } + } + } + + DataProvider.TableStyle.Update(styleInfo); + + return true; + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Pages/Shared/PagesTableValidateController.cs b/net452/SiteServer.Web/Controllers/Pages/Shared/PagesTableValidateController.cs new file mode 100644 index 000000000..743a1302b --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Pages/Shared/PagesTableValidateController.cs @@ -0,0 +1,86 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Pages.Shared +{ + [RoutePrefix("pages/shared/tableValidate")] + public class PagesTableValidateController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult Get() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin) return Unauthorized(); + + var tableName = Request.GetQueryString("tableName"); + var attributeName = Request.GetQueryString("attributeName"); + var relatedIdentities = TranslateUtils.StringCollectionToIntList(Request.GetQueryString("relatedIdentities")); + + var styleInfo = TableStyleManager.GetTableStyleInfo(tableName, attributeName, relatedIdentities); + + var veeValidate = string.Empty; + if (styleInfo != null) + { + veeValidate = styleInfo.VeeValidate; + } + + return Ok(new + { + Value = veeValidate + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + [HttpPost, Route(Route)] + public IHttpActionResult Submit() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + if (!rest.IsAdminLoggin) return Unauthorized(); + + var tableName = Request.GetPostString("tableName"); + var attributeName = Request.GetPostString("attributeName"); + var relatedIdentities = TranslateUtils.StringCollectionToIntList(Request.GetPostString("relatedIdentities")); + var value = Request.GetPostString("value"); + + var styleInfo = + TableStyleManager.GetTableStyleInfo(tableName, attributeName, relatedIdentities); + styleInfo.VeeValidate = value; + + //数据库中没有此项及父项的表样式 or 数据库中没有此项的表样式,但是有父项的表样式 + if (styleInfo.Id == 0 && styleInfo.RelatedIdentity == 0 || styleInfo.RelatedIdentity != relatedIdentities[0]) + { + DataProvider.TableStyle.Insert(styleInfo); + LogUtils.AddAdminLog(rest.AdminName, "添加表单显示样式", $"字段名:{styleInfo.AttributeName}"); + } + //数据库中有此项的表样式 + else + { + DataProvider.TableStyle.Update(styleInfo, false); + LogUtils.AddAdminLog(rest.AdminName, "修改表单显示样式", $"字段名:{styleInfo.AttributeName}"); + } + + return Ok(new{}); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/SiteServer.Web/Controllers/Preview/PreviewController.cs b/net452/SiteServer.Web/Controllers/Preview/PreviewController.cs similarity index 85% rename from SiteServer.Web/Controllers/Preview/PreviewController.cs rename to net452/SiteServer.Web/Controllers/Preview/PreviewController.cs index d850fb426..ba096105a 100644 --- a/SiteServer.Web/Controllers/Preview/PreviewController.cs +++ b/net452/SiteServer.Web/Controllers/Preview/PreviewController.cs @@ -5,10 +5,14 @@ using System.Text; using System.Web; using System.Web.Http; -using SiteServer.CMS.Api.Preview; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; using SiteServer.Utils; using SiteServer.CMS.Core; -using SiteServer.CMS.Model; +using SiteServer.CMS.Core.RestRoutes.Preview; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; using SiteServer.CMS.StlParser; using SiteServer.CMS.StlParser.Model; using SiteServer.CMS.StlParser.StlElement; @@ -17,7 +21,6 @@ namespace SiteServer.API.Controllers.Preview { - [RoutePrefix("api")] public class PreviewController : ApiController { [HttpGet, Route(ApiRoutePreview.Route)] @@ -32,7 +35,7 @@ public HttpResponseMessage Get(int siteId) } catch (Exception ex) { - LogUtils.AddErrorLogAndRedirect(ex); + WebPageUtils.AddErrorLogAndRedirect(ex); } return Request.CreateResponse(HttpStatusCode.NotFound); @@ -50,7 +53,7 @@ public HttpResponseMessage GetChannel(int siteId, int channelId) } catch (Exception ex) { - LogUtils.AddErrorLogAndRedirect(ex); + WebPageUtils.AddErrorLogAndRedirect(ex); } return Request.CreateResponse(HttpStatusCode.NotFound); @@ -69,7 +72,7 @@ public HttpResponseMessage GetContent(int siteId, int channelId, int contentId) } catch (Exception ex) { - LogUtils.AddErrorLogAndRedirect(ex); + WebPageUtils.AddErrorLogAndRedirect(ex); } return Request.CreateResponse(HttpStatusCode.NotFound); @@ -87,7 +90,7 @@ public HttpResponseMessage GetFile(int siteId, int fileTemplateId) } catch (Exception ex) { - LogUtils.AddErrorLogAndRedirect(ex); + WebPageUtils.AddErrorLogAndRedirect(ex); } return Request.CreateResponse(HttpStatusCode.NotFound); @@ -99,7 +102,7 @@ private HttpResponseMessage Response(string html, SiteInfo siteInfo) { Content = new StringContent(html, - Encoding.GetEncoding(siteInfo.Additional.Charset), "text/html") + Encoding.GetEncoding(siteInfo.Charset), "text/html") }; } @@ -123,13 +126,12 @@ private HttpResponseMessage GetResponseMessage(VisualInfo visualInfo) var contentBuilder = new StringBuilder(TemplateManager.GetTemplateContent(siteInfo, templateInfo)); //需要完善,考虑单页模板、内容正文、翻页及外部链接 - if (templateInfo.TemplateType == TemplateType.FileTemplate) //单页 + if (templateInfo.Type == TemplateType.FileTemplate) //单页 { - var fileContentBuilder = new StringBuilder(TemplateManager.GetTemplateContent(siteInfo, templateInfo)); - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); - return Response(fileContentBuilder.ToString(), siteInfo); + Parser.Parse(pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); + return Response(contentBuilder.ToString(), siteInfo); } - if (templateInfo.TemplateType == TemplateType.IndexPageTemplate || templateInfo.TemplateType == TemplateType.ChannelTemplate) //栏目页面 + if (templateInfo.Type == TemplateType.IndexPageTemplate || templateInfo.Type == TemplateType.ChannelTemplate) //栏目页面 { var nodeInfo = ChannelManager.GetChannelInfo(siteInfo.Id, visualInfo.ChannelId); if (nodeInfo == null) return null; @@ -138,7 +140,7 @@ private HttpResponseMessage GetResponseMessage(VisualInfo visualInfo) { if (!string.IsNullOrEmpty(nodeInfo.LinkUrl)) { - PageUtils.Redirect(nodeInfo.LinkUrl); + WebPageUtils.Redirect(nodeInfo.LinkUrl); return null; } } @@ -165,7 +167,7 @@ private HttpResponseMessage GetResponseMessage(VisualInfo visualInfo) var pageCount = StringUtils.GetCount(ContentUtility.PagePlaceHolder, contentAttributeHtml) + 1;//一共需要的页数 if (pageCount > 1) { - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); + Parser.Parse(pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) { @@ -199,11 +201,10 @@ private HttpResponseMessage GetResponseMessage(VisualInfo visualInfo) var stlElement = StlParserUtility.GetStlElement(StlPageContents.ElementName, stlLabelList); var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); - var pageContentsElementParser = new StlPageContents(stlElement, pageInfo, contextInfo, false); - int totalNum; - var pageCount = pageContentsElementParser.GetPageCount(out totalNum); + var pageContentsElementParser = new StlPageContents(stlElement, pageInfo, contextInfo); + var pageCount = pageContentsElementParser.GetPageCount(out var totalNum); - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); + Parser.Parse(pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) { @@ -226,11 +227,10 @@ private HttpResponseMessage GetResponseMessage(VisualInfo visualInfo) var stlElement = StlParserUtility.GetStlElement(StlPageChannels.ElementName, stlLabelList); var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); - var pageChannelsElementParser = new StlPageChannels(stlElement, pageInfo, contextInfo, false); - int totalNum; - var pageCount = pageChannelsElementParser.GetPageCount(out totalNum); + var pageChannelsElementParser = new StlPageChannels(stlElement, pageInfo, contextInfo); + var pageCount = pageChannelsElementParser.GetPageCount(out var totalNum); - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); + Parser.Parse(pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) { @@ -253,11 +253,10 @@ private HttpResponseMessage GetResponseMessage(VisualInfo visualInfo) var stlElement = StlParserUtility.GetStlElement(StlPageSqlContents.ElementName, stlLabelList); var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); - var pageSqlContentsElementParser = new StlPageSqlContents(stlElement, pageInfo, contextInfo, false); - int totalNum; - var pageCount = pageSqlContentsElementParser.GetPageCount(out totalNum); + var pageSqlContentsElementParser = new StlPageSqlContents(stlElement, pageInfo, contextInfo); + var pageCount = pageSqlContentsElementParser.GetPageCount(out var totalNum); - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); + Parser.Parse(pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) { @@ -266,7 +265,7 @@ private HttpResponseMessage GetResponseMessage(VisualInfo visualInfo) var thePageInfo = pageInfo.Clone(); thePageInfo.IsLocal = true; - var pageHtml = pageSqlContentsElementParser.Parse(currentPageIndex, pageCount); + var pageHtml = pageSqlContentsElementParser.Parse(totalNum, currentPageIndex, pageCount, false); var pagedBuilder = new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); StlParserManager.ReplacePageElementsInChannelPage(pagedBuilder, thePageInfo, stlLabelList, thePageInfo.PageChannelId, currentPageIndex, pageCount, totalNum); @@ -276,16 +275,17 @@ private HttpResponseMessage GetResponseMessage(VisualInfo visualInfo) } } - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); + Parser.Parse(pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); return Response(contentBuilder.ToString(), siteInfo); } - if (templateInfo.TemplateType == TemplateType.ContentTemplate) //内容页面 + if (templateInfo.Type == TemplateType.ContentTemplate) //内容页面 { if (contextInfo.ContentInfo == null) return null; - if (!string.IsNullOrEmpty(contextInfo.ContentInfo.GetString(ContentAttribute.LinkUrl))) + var linkUrl = contextInfo.ContentInfo.Get(ContentAttribute.LinkUrl); + if (!string.IsNullOrEmpty(linkUrl)) { - PageUtils.Redirect(contextInfo.ContentInfo.GetString(ContentAttribute.LinkUrl)); + WebPageUtils.Redirect(linkUrl); return null; } @@ -301,7 +301,7 @@ private HttpResponseMessage GetResponseMessage(VisualInfo visualInfo) StlParserManager.ParseInnerContent(innerBuilder, pageInfo, contextInfo); var pageContentHtml = innerBuilder.ToString(); var pageCount = StringUtils.GetCount(ContentUtility.PagePlaceHolder, pageContentHtml) + 1;//一共需要的页数 - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); + Parser.Parse(pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) { @@ -334,11 +334,10 @@ private HttpResponseMessage GetResponseMessage(VisualInfo visualInfo) var stlElement = StlParserUtility.GetStlElement(StlPageContents.ElementName, stlLabelList); var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); - var pageContentsElementParser = new StlPageContents(stlElement, pageInfo, contextInfo, false); - int totalNum; - var pageCount = pageContentsElementParser.GetPageCount(out totalNum); + var pageContentsElementParser = new StlPageContents(stlElement, pageInfo, contextInfo); + var pageCount = pageContentsElementParser.GetPageCount(out var totalNum); - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); + Parser.Parse(pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) { @@ -361,11 +360,10 @@ private HttpResponseMessage GetResponseMessage(VisualInfo visualInfo) var stlElement = StlParserUtility.GetStlElement(StlPageChannels.ElementName, stlLabelList); var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); - var pageChannelsElementParser = new StlPageChannels(stlElement, pageInfo, contextInfo, false); - int totalNum; - var pageCount = pageChannelsElementParser.GetPageCount(out totalNum); + var pageChannelsElementParser = new StlPageChannels(stlElement, pageInfo, contextInfo); + var pageCount = pageChannelsElementParser.GetPageCount(out _); - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); + Parser.Parse(pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) { @@ -388,11 +386,10 @@ private HttpResponseMessage GetResponseMessage(VisualInfo visualInfo) var stlElement = StlParserUtility.GetStlElement(StlPageSqlContents.ElementName, stlLabelList); var stlElementTranslated = StlParserManager.StlEncrypt(stlElement); - var pageSqlContentsElementParser = new StlPageSqlContents(stlElement, pageInfo, contextInfo, false); - int totalNum; - var pageCount = pageSqlContentsElementParser.GetPageCount(out totalNum); + var pageSqlContentsElementParser = new StlPageSqlContents(stlElement, pageInfo, contextInfo); + var pageCount = pageSqlContentsElementParser.GetPageCount(out var totalNum); - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); + Parser.Parse(pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) { @@ -401,7 +398,7 @@ private HttpResponseMessage GetResponseMessage(VisualInfo visualInfo) var thePageInfo = pageInfo.Clone(); thePageInfo.IsLocal = true; - var pageHtml = pageSqlContentsElementParser.Parse(currentPageIndex, pageCount); + var pageHtml = pageSqlContentsElementParser.Parse(totalNum, currentPageIndex, pageCount, false); var pagedBuilder = new StringBuilder(contentBuilder.ToString().Replace(stlElementTranslated, pageHtml)); StlParserManager.ReplacePageElementsInContentPage(pagedBuilder, thePageInfo, stlLabelList, visualInfo.ChannelId, visualInfo.ContentId, currentPageIndex, pageCount); @@ -411,7 +408,7 @@ private HttpResponseMessage GetResponseMessage(VisualInfo visualInfo) } } - Parser.Parse(siteInfo, pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); + Parser.Parse(pageInfo, contextInfo, contentBuilder, visualInfo.FilePath, true); StlParserManager.ReplacePageElementsInContentPage(contentBuilder, pageInfo, stlLabelList, contextInfo.ContentInfo.ChannelId, contextInfo.ContentInfo.Id, 0, 1); return Response(contentBuilder.ToString(), siteInfo); } diff --git a/net452/SiteServer.Web/Controllers/Sys/SysPackagingClearCacheController.cs b/net452/SiteServer.Web/Controllers/Sys/SysPackagingClearCacheController.cs new file mode 100644 index 000000000..c0ea2cf05 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Sys/SysPackagingClearCacheController.cs @@ -0,0 +1,27 @@ +using System.Web.Http; +using SiteServer.CMS.Api.Sys.Packaging; +using SiteServer.CMS.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Sys +{ + public class SysPackagesClearCacheController : ApiController + { + [HttpPost, Route(ApiRouteClearCache.Route)] + public IHttpActionResult Main() + { + var request = new RequestImpl(); + + if (!request.IsAdminLoggin) + { + return Unauthorized(); + } + + CacheUtils.ClearAll(); + CacheDbUtils.Clear(); + + return Ok(new {}); + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Sys/SysPackagingDownloadController.cs b/net452/SiteServer.Web/Controllers/Sys/SysPackagingDownloadController.cs new file mode 100644 index 000000000..18f74368e --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Sys/SysPackagingDownloadController.cs @@ -0,0 +1,42 @@ +using System.Web.Http; +using SiteServer.CMS.Api.Sys.Packaging; +using SiteServer.CMS.Core; +using SiteServer.CMS.Packaging; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Sys +{ + public class SysPackagesDownloadController : ApiController + { + [HttpPost, Route(ApiRouteDownload.Route)] + public IHttpActionResult Main() + { + var request = new RequestImpl(); + + if (!request.IsAdminLoggin) + { + return Unauthorized(); + } + + var packageId = request.GetPostString("packageId"); + var version = request.GetPostString("version"); + + try + { + PackageUtils.DownloadPackage(packageId, version); + } + catch + { + PackageUtils.DownloadPackage(packageId, version); + } + + if (StringUtils.EqualsIgnoreCase(packageId, PackageUtils.PackageIdSsCms)) + { + CacheDbUtils.RemoveAndInsert(PackageUtils.CacheKeySsCmsIsDownload, true.ToString()); + } + + return Ok(); + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Sys/SysPackagingSyncDatabaseController.cs b/net452/SiteServer.Web/Controllers/Sys/SysPackagingSyncDatabaseController.cs new file mode 100644 index 000000000..8eb97af43 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Sys/SysPackagingSyncDatabaseController.cs @@ -0,0 +1,30 @@ +using System.Web.Http; +using SiteServer.CMS.Api.Sys.Packaging; +using SiteServer.CMS.Core; +using SiteServer.CMS.Packaging; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Sys +{ + public class SysPackagesSyncDatabaseController : ApiController + { + [HttpPost, Route(ApiRouteSyncDatabase.Route)] + public IHttpActionResult Main() + { + var idWithVersion = $"{PackageUtils.PackageIdSsCms}.{SystemManager.Version}"; + var packagePath = PathUtils.GetPackagesPath(idWithVersion); + var homeDirectory = PathUtils.GetHomeDirectoryPath(string.Empty); + if (!DirectoryUtils.IsDirectoryExists(homeDirectory) || !FileUtils.IsFileExists(PathUtils.Combine(homeDirectory, "config.js"))) + { + DirectoryUtils.Copy(PathUtils.Combine(packagePath, DirectoryUtils.Home.DirectoryName), homeDirectory, true); + } + + SystemManager.SyncDatabase(); + + return Ok(new + { + SystemManager.Version + }); + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Sys/SysPackagingUpdateController.cs b/net452/SiteServer.Web/Controllers/Sys/SysPackagingUpdateController.cs new file mode 100644 index 000000000..1d8cf8423 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Sys/SysPackagingUpdateController.cs @@ -0,0 +1,39 @@ +using System.Web.Http; +using SiteServer.CMS.Api.Sys.Packaging; +using SiteServer.CMS.Packaging; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Sys +{ + public class SysPackagesUpdateController : ApiController + { + [HttpPost, Route(ApiRouteUpdate.Route)] + public IHttpActionResult Main() + { + var request = new RequestImpl(); + + if (!request.IsAdminLoggin) + { + return Unauthorized(); + } + + var packageId = request.GetPostString("packageId"); + var version = request.GetPostString("version"); + var packageType = request.GetPostString("packageType"); + if (StringUtils.EqualsIgnoreCase(packageId, PackageUtils.PackageIdSsCms)) + { + packageType = PackageType.SsCms.Value; + } + + string errorMessage; + var idWithVersion = $"{packageId}.{version}"; + if (!PackageUtils.UpdatePackage(idWithVersion, PackageType.Parse(packageType), out errorMessage)) + { + return BadRequest(errorMessage); + } + + return Ok(); + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Sys/SysPackagingUpdateSsCmsController.cs b/net452/SiteServer.Web/Controllers/Sys/SysPackagingUpdateSsCmsController.cs new file mode 100644 index 000000000..ca91a2276 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Sys/SysPackagingUpdateSsCmsController.cs @@ -0,0 +1,53 @@ +using System.Web.Http; +using SiteServer.CMS.Api.Sys.Packaging; +using SiteServer.CMS.Core; +using SiteServer.CMS.Packaging; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Sys +{ + public class SysPackagesUpdateSsCmsController : ApiController + { + [HttpPost, Route(ApiRouteUpdateSsCms.Route)] + public IHttpActionResult Main() + { + var request = new RequestImpl(); + + var isDownload = TranslateUtils.ToBool(CacheDbUtils.GetValueAndRemove(PackageUtils.CacheKeySsCmsIsDownload)); + + if (!isDownload) + { + return Unauthorized(); + } + + var version = request.GetPostString("version"); + + var idWithVersion = $"{PackageUtils.PackageIdSsCms}.{version}"; + var packagePath = PathUtils.GetPackagesPath(idWithVersion); + var packageWebConfigPath = PathUtils.Combine(packagePath, WebConfigUtils.WebConfigFileName); + + if (!FileUtils.IsFileExists(packageWebConfigPath)) + { + return BadRequest($"升级包 {WebConfigUtils.WebConfigFileName} 文件不存在"); + } + + WebConfigUtils.UpdateWebConfig(packageWebConfigPath, WebConfigUtils.IsProtectData, + WebConfigUtils.DatabaseType, WebConfigUtils.ConnectionString, WebConfigUtils.ApiPrefix, WebConfigUtils.AdminDirectory, WebConfigUtils.HomeDirectory, + WebConfigUtils.SecretKey, WebConfigUtils.IsNightlyUpdate); + + DirectoryUtils.Copy(PathUtils.Combine(packagePath, DirectoryUtils.SiteFiles.DirectoryName), PathUtils.GetSiteFilesPath(string.Empty), true); + DirectoryUtils.Copy(PathUtils.Combine(packagePath, DirectoryUtils.SiteServer.DirectoryName), PathUtils.GetAdminDirectoryPath(string.Empty), true); + DirectoryUtils.Copy(PathUtils.Combine(packagePath, DirectoryUtils.Home.DirectoryName), PathUtils.GetHomeDirectoryPath(string.Empty), true); + DirectoryUtils.Copy(PathUtils.Combine(packagePath, DirectoryUtils.Bin.DirectoryName), PathUtils.GetBinDirectoryPath(string.Empty), true); + var isCopyFiles = FileUtils.CopyFile(packageWebConfigPath, PathUtils.Combine(WebConfigUtils.PhysicalApplicationPath, WebConfigUtils.WebConfigFileName), true); + + //SystemManager.SyncDatabase(); + + return Ok(new + { + isCopyFiles + }); + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Sys/SysStlActionsDownloadController.cs b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsDownloadController.cs new file mode 100644 index 000000000..ccd58ec5d --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsDownloadController.cs @@ -0,0 +1,120 @@ +using System.Web; +using System.Web.Http; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.API.Controllers.Sys +{ + public class SysStlActionsDownloadController : ApiController + { + [HttpGet] + [Route(ApiRouteActionsDownload.Route)] + public void Main() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + if (!string.IsNullOrEmpty(Request.GetQueryString("siteId")) && !string.IsNullOrEmpty(Request.GetQueryString("fileUrl")) && string.IsNullOrEmpty(Request.GetQueryString("contentId"))) + { + var siteId = Request.GetQueryInt("siteId"); + var fileUrl = TranslateUtils.DecryptStringBySecretKey(Request.GetQueryString("fileUrl")); + + if (PageUtils.IsProtocolUrl(fileUrl)) + { + WebPageUtils.Redirect(fileUrl); + return; + } + + var siteInfo = SiteManager.GetSiteInfo(siteId); + var filePath = PathUtility.MapPath(siteInfo, fileUrl); + var fileType = EFileSystemTypeUtils.GetEnumType(PathUtils.GetExtension(filePath)); + if (EFileSystemTypeUtils.IsDownload(fileType)) + { + if (FileUtils.IsFileExists(filePath)) + { + WebPageUtils.Download(HttpContext.Current.Response, filePath); + return; + } + } + else + { + WebPageUtils.Redirect(PageUtility.ParseNavigationUrl(siteInfo, fileUrl, false)); + return; + } + } + else if (!string.IsNullOrEmpty(Request.GetQueryString("filePath"))) + { + var filePath = TranslateUtils.DecryptStringBySecretKey(Request.GetQueryString("filePath")); + var fileType = EFileSystemTypeUtils.GetEnumType(PathUtils.GetExtension(filePath)); + if (EFileSystemTypeUtils.IsDownload(fileType)) + { + if (FileUtils.IsFileExists(filePath)) + { + WebPageUtils.Download(HttpContext.Current.Response, filePath); + return; + } + } + else + { + var fileUrl = FxUtils.GetRootUrlByPhysicalPath(filePath); + WebPageUtils.Redirect(FxUtils.ParseNavigationUrl(fileUrl)); + return; + } + } + else if (!string.IsNullOrEmpty(Request.GetQueryString("siteId")) && !string.IsNullOrEmpty(Request.GetQueryString("channelId")) && !string.IsNullOrEmpty(Request.GetQueryString("contentId")) && !string.IsNullOrEmpty(Request.GetQueryString("fileUrl"))) + { + var siteId = Request.GetQueryInt("siteId"); + var channelId = Request.GetQueryInt("channelId"); + var contentId = Request.GetQueryInt("contentId"); + var fileUrl = TranslateUtils.DecryptStringBySecretKey(Request.GetQueryString("fileUrl")); + var siteInfo = SiteManager.GetSiteInfo(siteId); + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + + channelInfo.ContentRepository.AddDownloads(channelId, contentId); + + if (!string.IsNullOrEmpty(contentInfo?.Get(ContentAttribute.FileUrl))) + { + if (PageUtils.IsProtocolUrl(fileUrl)) + { + WebPageUtils.Redirect(fileUrl); + return; + } + + var filePath = PathUtility.MapPath(siteInfo, fileUrl, true); + var fileType = EFileSystemTypeUtils.GetEnumType(PathUtils.GetExtension(filePath)); + if (EFileSystemTypeUtils.IsDownload(fileType)) + { + if (FileUtils.IsFileExists(filePath)) + { + WebPageUtils.Download(HttpContext.Current.Response, filePath); + return; + } + } + else + { + WebPageUtils.Redirect(PageUtility.ParseNavigationUrl(siteInfo, fileUrl, false)); + return; + } + } + } + } + catch + { + // ignored + } + + HttpContext.Current.Response.Write("下载失败,不存在此文件!"); + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Sys/SysStlActionsDynamicController.cs b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsDynamicController.cs new file mode 100644 index 000000000..7b276dd5b --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsDynamicController.cs @@ -0,0 +1,69 @@ +using System; +using System.Web; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.CMS.StlParser.StlElement; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Sys +{ + public class SysStlActionsDynamicController : ApiController + { + [HttpPost, Route(ApiRouteActionsDynamic.Route)] + public IHttpActionResult Main() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var pageChannelId = Request.GetPostInt("pageChannelId"); + if (pageChannelId == 0) + { + pageChannelId = siteId; + } + var pageContentId = Request.GetPostInt("pageContentId"); + var pageTemplateId = Request.GetPostInt("pageTemplateId"); + var isPageRefresh = Request.GetPostBool("isPageRefresh"); + var templateContent = TranslateUtils.DecryptStringBySecretKey(Request.GetPostString("templateContent")); + var ajaxDivId = AttackUtils.FilterSqlAndXss(Request.GetPostString("ajaxDivId")); + + var channelId = Request.GetPostInt("channelId"); + if (channelId == 0) + { + channelId = pageChannelId; + } + var contentId = Request.GetPostInt("contentId"); + if (contentId == 0) + { + contentId = pageContentId; + } + + var pageUrl = TranslateUtils.DecryptStringBySecretKey(Request.GetPostString("pageUrl")); + var pageIndex = Request.GetPostInt("pageNum"); + if (pageIndex > 0) + { + pageIndex--; + } + + var queryString = PageUtils.GetQueryStringFilterXss(PageUtils.UrlDecode(HttpContext.Current.Request.RawUrl)); + queryString.Remove("siteId"); + + var userInfo = UserManager.GetUserInfoByUserId(rest.UserId); + + return Ok(new + { + Html = StlDynamic.ParseDynamicContent(siteId, channelId, contentId, pageTemplateId, isPageRefresh, templateContent, pageUrl, pageIndex, ajaxDivId, queryString, userInfo) + }); + } + catch(Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Sys/SysStlActionsIfController.cs b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsIfController.cs new file mode 100644 index 000000000..fb34a7239 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsIfController.cs @@ -0,0 +1,61 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.CMS.StlParser.StlElement; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Sys +{ + public class SysStlActionsIfController : ApiController + { + [HttpPost, Route(ApiRouteActionsIf.Route)] + public IHttpActionResult Main() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var channelId = Request.GetPostInt("channelId"); + var contentId = Request.GetPostInt("contentId"); + var templateId = Request.GetPostInt("templateId"); + var ajaxDivId = AttackUtils.FilterSqlAndXss(Request.GetPostString("ajaxDivId")); + var pageUrl = TranslateUtils.DecryptStringBySecretKey(Request.GetPostString("pageUrl")); + var testType = AttackUtils.FilterSqlAndXss(Request.GetPostString("testType")); + //var testValue = PageUtils.FilterSqlAndXss(Request.GetPostString("testValue")); + //var testOperate = PageUtils.FilterSqlAndXss(Request.GetPostString("testOperate")); + var successTemplate = TranslateUtils.DecryptStringBySecretKey(Request.GetPostString("successTemplate")); + var failureTemplate = TranslateUtils.DecryptStringBySecretKey(Request.GetPostString("failureTemplate")); + + var isSuccess = false; + if (StringUtils.EqualsIgnoreCase(testType, StlIf.TypeIsUserLoggin)) + { + isSuccess = rest.IsUserLoggin; + } + else if (StringUtils.EqualsIgnoreCase(testType, StlIf.TypeIsAdministratorLoggin)) + { + isSuccess = rest.IsAdminLoggin; + } + else if (StringUtils.EqualsIgnoreCase(testType, StlIf.TypeIsUserOrAdministratorLoggin)) + { + isSuccess = rest.IsUserLoggin || rest.IsAdminLoggin; + } + + var userInfo = UserManager.GetUserInfoByUserId(rest.UserId); + + return Ok(new + { + Html = StlDynamic.ParseDynamicContent(siteId, channelId, contentId, templateId, false, isSuccess ? successTemplate : failureTemplate, pageUrl, 0, ajaxDivId, null, userInfo) + }); + } + catch(Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Sys/SysStlActionsLoadingChannelsController.cs b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsLoadingChannelsController.cs new file mode 100644 index 000000000..c15704a69 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsLoadingChannelsController.cs @@ -0,0 +1,51 @@ +using System.Text; +using System.Web; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.StlParser.StlElement; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.API.Controllers.Sys +{ + public class SysStlActionsLoadingChannelsController : ApiController + { + [HttpPost, Route(ApiRouteActionsLoadingChannels.Route)] + public void Main() + { + var builder = new StringBuilder(); + + try + { + var form = HttpContext.Current.Request.Form; + var siteId = TranslateUtils.ToInt(form["siteId"]); + var parentId = TranslateUtils.ToInt(form["parentId"]); + var target = form["target"]; + var isShowTreeLine = TranslateUtils.ToBool(form["isShowTreeLine"]); + var isShowContentNum = TranslateUtils.ToBool(form["isShowContentNum"]); + var currentFormatString = form["currentFormatString"]; + var topChannelId = TranslateUtils.ToInt(form["topChannelId"]); + var topParentsCount = TranslateUtils.ToInt(form["topParentsCount"]); + var currentChannelId = TranslateUtils.ToInt(form["currentChannelId"]); + + var siteInfo = SiteManager.GetSiteInfo(siteId); + var channelIdList = ChannelManager.GetChannelIdList(ChannelManager.GetChannelInfo(siteId, parentId == 0 ? siteId : parentId), EScopeType.Children, string.Empty, string.Empty, string.Empty); + + foreach (var channelId in channelIdList) + { + var nodeInfo = ChannelManager.GetChannelInfo(siteId, channelId); + + builder.Append(StlTree.GetChannelRowHtml(siteInfo, nodeInfo, target, isShowTreeLine, isShowContentNum, TranslateUtils.DecryptStringBySecretKey(currentFormatString), topChannelId, topParentsCount, currentChannelId, false)); + } + } + catch + { + // ignored + } + + HttpContext.Current.Response.Write(builder); + HttpContext.Current.Response.End(); + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Sys/SysStlActionsPageContentsController.cs b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsPageContentsController.cs new file mode 100644 index 000000000..ee6f0b98c --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsPageContentsController.cs @@ -0,0 +1,55 @@ +using System; +using System.Collections.Generic; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.StlElement; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Sys +{ + public class SysStlActionsPageContentsController : ApiController + { + [HttpPost, Route(ApiRouteActionsPageContents.Route)] + public IHttpActionResult Main() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetPostInt("siteId"); + var siteInfo = SiteManager.GetSiteInfo(siteId); + var pageChannelId = Request.GetPostInt("pageChannelId"); + var templateId = Request.GetPostInt("templateId"); + var totalNum = Request.GetPostInt("totalNum"); + var pageCount = Request.GetPostInt("pageCount"); + var currentPageIndex = Request.GetPostInt("currentPageIndex"); + var stlPageContentsElement = TranslateUtils.DecryptStringBySecretKey(Request.GetPostString("stlPageContentsElement")); + + var userInfo = UserManager.GetUserInfoByUserId(rest.UserId); + + var nodeInfo = ChannelManager.GetChannelInfo(siteId, pageChannelId); + var templateInfo = TemplateManager.GetTemplateInfo(siteId, templateId); + var pageInfo = new PageInfo(nodeInfo.Id, 0, siteInfo, templateInfo, new Dictionary()) + { + UserInfo = userInfo + }; + var contextInfo = new ContextInfo(pageInfo); + + var stlPageContents = new StlPageContents(stlPageContentsElement, pageInfo, contextInfo); + + var pageHtml = stlPageContents.Parse(totalNum, currentPageIndex, pageCount, false); + + return Ok(pageHtml); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Sys/SysStlActionsRelatedFieldController.cs b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsRelatedFieldController.cs new file mode 100644 index 000000000..fcf8e700f --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsRelatedFieldController.cs @@ -0,0 +1,50 @@ +using System.Text; +using System.Web; +using System.Web.Http; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Sys +{ + public class SysStlActionsRelatedFieldController : ApiController + { + [HttpPost, Route(ApiRouteActionsRelatedField.Route)] + public void Main(int siteId) + { + var rest = Request.GetAuthenticatedRequest(); + + var callback = Request.GetQueryString("callback"); + var relatedFieldId = Request.GetQueryInt("relatedFieldId"); + var parentId = Request.GetQueryInt("parentId"); + var jsonString = GetRelatedField(relatedFieldId, parentId); + var call = callback + "(" + jsonString + ")"; + + HttpContext.Current.Response.Write(call); + HttpContext.Current.Response.End(); + } + + public string GetRelatedField(int relatedFieldId, int parentId) + { + var jsonString = new StringBuilder(); + + jsonString.Append("["); + + var list = DataProvider.RelatedFieldItem.GetRelatedFieldItemInfoList(relatedFieldId, parentId); + if (list.Count > 0) + { + foreach (var itemInfo in list) + { + jsonString.AppendFormat(@"{{""id"":""{0}"",""name"":""{1}"",""value"":""{2}""}},", itemInfo.Id, StringUtils.ToJsString(itemInfo.ItemName), StringUtils.ToJsString(itemInfo.ItemValue)); + } + jsonString.Length -= 1; + } + + jsonString.Append("]"); + return jsonString.ToString(); + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Sys/SysStlActionsSearchController.cs b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsSearchController.cs new file mode 100644 index 000000000..92b501359 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsSearchController.cs @@ -0,0 +1,170 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Text; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.CMS.StlParser; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.StlElement; +using SiteServer.CMS.StlParser.StlEntity; +using SiteServer.CMS.StlParser.Utility; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Sys +{ + public class SysStlActionsSearchController : ApiController + { + public NameValueCollection GetPostCollection() + { + var formCollection = new NameValueCollection(); + foreach (var item in Request.GetPostDictionary()) + { + formCollection[item.Key] = item.Value.ToString(); + } + + return formCollection; + } + + [HttpPost, Route(ApiRouteActionsSearch.Route)] + public IHttpActionResult Main() + { + PageInfo pageInfo = null; + var template = string.Empty; + try + { + var rest = Request.GetAuthenticatedRequest(); + var form = GetPostCollection(); + + var isAllSites = Request.GetPostBool(StlSearch.IsAllSites.ToLower()); + var siteName = AttackUtils.FilterSqlAndXss(Request.GetPostString(StlSearch.SiteName.ToLower())); + var siteDir = AttackUtils.FilterSqlAndXss(Request.GetPostString(StlSearch.SiteDir.ToLower())); + var siteIds = AttackUtils.FilterSqlAndXss(Request.GetPostString(StlSearch.SiteIds.ToLower())); + var channelIndex = AttackUtils.FilterSqlAndXss(Request.GetPostString(StlSearch.ChannelIndex.ToLower())); + var channelName = AttackUtils.FilterSqlAndXss(Request.GetPostString(StlSearch.ChannelName.ToLower())); + var channelIds = AttackUtils.FilterSqlAndXss(Request.GetPostString(StlSearch.ChannelIds.ToLower())); + var type = AttackUtils.FilterSqlAndXss(Request.GetPostString(StlSearch.Type.ToLower())); + var word = AttackUtils.FilterSqlAndXss(Request.GetPostString(StlSearch.Word.ToLower())); + var dateAttribute = AttackUtils.FilterSqlAndXss(Request.GetPostString(StlSearch.DateAttribute.ToLower())); + var dateFrom = AttackUtils.FilterSqlAndXss(Request.GetPostString(StlSearch.DateFrom.ToLower())); + var dateTo = AttackUtils.FilterSqlAndXss(Request.GetPostString(StlSearch.DateTo.ToLower())); + var since = AttackUtils.FilterSqlAndXss(Request.GetPostString(StlSearch.Since.ToLower())); + var pageNum = Request.GetPostInt(StlSearch.PageNum.ToLower()); + var isHighlight = Request.GetPostBool(StlSearch.IsHighlight.ToLower()); + var siteId = Request.GetPostInt("siteid"); + var ajaxDivId = AttackUtils.FilterSqlAndXss(Request.GetPostString("ajaxdivid")); + template = TranslateUtils.DecryptStringBySecretKey(Request.GetPostString("template")); + var pageIndex = Request.GetPostInt("page", 1) - 1; + + var templateInfo = new TemplateInfo + { + SiteId = siteId, + TemplateName = string.Empty, + Type = TemplateType.FileTemplate, + RelatedFileName = string.Empty, + CreatedFileFullName = string.Empty, + CreatedFileExtName = string.Empty, + Default = false + }; + var siteInfo = SiteManager.GetSiteInfo(siteId); + + var userInfo = UserManager.GetUserInfoByUserId(rest.UserId); + + pageInfo = new PageInfo(siteId, 0, siteInfo, templateInfo, new Dictionary()) + { + UserInfo = userInfo + }; + var contextInfo = new ContextInfo(pageInfo); + var contentBuilder = new StringBuilder(StlRequestEntities.ParseRequestEntities(form, template)); + + var stlLabelList = StlParserUtility.GetStlLabelList(contentBuilder.ToString()); + + if (StlParserUtility.IsStlElementExists(StlPageContents.ElementName, stlLabelList)) + { + var stlElement = StlParserUtility.GetStlElement(StlPageContents.ElementName, stlLabelList); + var stlPageContentsElement = stlElement; + var stlPageContentsElementReplaceString = stlElement; + + var whereString = DataProvider.ContentRepository.GetWhereStringByStlSearch(isAllSites, siteName, siteDir, siteIds, channelIndex, channelName, channelIds, type, word, dateAttribute, dateFrom, dateTo, since, siteId, ApiRouteActionsSearch.ExlcudeAttributeNames, form); + + var stlPageContents = new StlPageContents(stlPageContentsElement, pageInfo, contextInfo, pageNum, siteInfo.TableName, whereString); + var pageCount = stlPageContents.GetPageCount(out var totalNum); + if (totalNum == 0) + { + return NotFound(); + } + + for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) + { + if (currentPageIndex != pageIndex) continue; + + var pageHtml = stlPageContents.Parse(totalNum, currentPageIndex, pageCount, false); + var pagedBuilder = new StringBuilder(contentBuilder.ToString().Replace(stlPageContentsElementReplaceString, pageHtml)); + + StlParserManager.ReplacePageElementsInSearchPage(pagedBuilder, pageInfo, stlLabelList, ajaxDivId, pageInfo.PageChannelId, currentPageIndex, pageCount, totalNum); + + if (isHighlight && !string.IsNullOrEmpty(word)) + { + var pagedContents = pagedBuilder.ToString(); + pagedBuilder = new StringBuilder(); + pagedBuilder.Append(RegexUtils.Replace( + $"({word.Replace(" ", "\\s")})(?!)(?![^><]*>)", pagedContents, + $"{word}")); + } + + Parser.Parse(pageInfo, contextInfo, pagedBuilder, string.Empty, false); + return Ok(pagedBuilder.ToString()); + } + } + else if (StlParserUtility.IsStlElementExists(StlPageSqlContents.ElementName, stlLabelList)) + { + var stlElement = StlParserUtility.GetStlElement(StlPageSqlContents.ElementName, stlLabelList); + + var stlPageSqlContents = new StlPageSqlContents(stlElement, pageInfo, contextInfo); + + var pageCount = stlPageSqlContents.GetPageCount(out var totalNum); + if (totalNum == 0) + { + return NotFound(); + } + + for (var currentPageIndex = 0; currentPageIndex < pageCount; currentPageIndex++) + { + if (currentPageIndex != pageIndex) continue; + + var pageHtml = stlPageSqlContents.Parse(totalNum, currentPageIndex, pageCount, false); + var pagedBuilder = new StringBuilder(contentBuilder.ToString().Replace(stlElement, pageHtml)); + + StlParserManager.ReplacePageElementsInSearchPage(pagedBuilder, pageInfo, stlLabelList, ajaxDivId, pageInfo.PageChannelId, currentPageIndex, pageCount, totalNum); + + if (isHighlight && !string.IsNullOrEmpty(word)) + { + var pagedContents = pagedBuilder.ToString(); + pagedBuilder = new StringBuilder(); + pagedBuilder.Append(RegexUtils.Replace( + $"({word.Replace(" ", "\\s")})(?!)(?![^><]*>)", pagedContents, + $"{word}")); + } + + Parser.Parse(pageInfo, contextInfo, pagedBuilder, string.Empty, false); + return Ok(pagedBuilder.ToString()); + } + } + + Parser.Parse(pageInfo, contextInfo, contentBuilder, string.Empty, false); + return Ok(contentBuilder.ToString()); + } + catch (Exception ex) + { + var message = LogUtils.AddStlErrorLog(pageInfo, StlSearch.ElementName, template, ex); + return BadRequest(message); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Sys/SysStlActionsTriggerController.cs b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsTriggerController.cs new file mode 100644 index 000000000..da2483246 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsTriggerController.cs @@ -0,0 +1,117 @@ +using System.Collections.Specialized; +using System.Threading.Tasks; +using System.Web; +using System.Web.Http; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Enumerations; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.CMS.StlParser; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Sys +{ + public class SysStlActionsTriggerController : ApiController + { + [HttpGet] + [Route(ApiRouteActionsTrigger.Route)] + public async Task Main() + { + var rest = Request.GetAuthenticatedRequest(); + + var siteId = Request.GetQueryInt("siteId"); + var siteInfo = SiteManager.GetSiteInfo(siteId); + + try + { + var channelId = Request.GetQueryInt("channelId"); + if (channelId == 0) + { + channelId = siteId; + } + var contentId = Request.GetQueryInt("contentId"); + var fileTemplateId = Request.GetQueryInt("fileTemplateId"); + var specialId = Request.GetQueryInt("specialId"); + var isRedirect = TranslateUtils.ToBool(Request.GetQueryString("isRedirect")); + + if (specialId != 0) + { + await FileSystemObjectAsync.ExecuteAsync(siteId, ECreateType.Special, 0, 0, 0, specialId); + } + else if (fileTemplateId != 0) + { + await FileSystemObjectAsync.ExecuteAsync(siteId, ECreateType.File, 0, 0, fileTemplateId, 0); + } + else if (contentId != 0) + { + await FileSystemObjectAsync.ExecuteAsync(siteId, ECreateType.Content, channelId, contentId, 0, 0); + } + else if (channelId != 0) + { + await FileSystemObjectAsync.ExecuteAsync(siteId, ECreateType.Channel, channelId, 0, 0, 0); + } + else if (siteId != 0) + { + await FileSystemObjectAsync.ExecuteAsync(siteId, ECreateType.Channel, siteId, 0, 0, 0); + } + + if (isRedirect) + { + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + + var redirectUrl = string.Empty; + if (specialId != 0) + { + redirectUrl = PageUtility.GetFileUrl(siteInfo, specialId, false); + } + else if (fileTemplateId != 0) + { + redirectUrl = PageUtility.GetFileUrl(siteInfo, fileTemplateId, false); + } + else if (contentId != 0) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, contentId); + redirectUrl = PageUtility.GetContentUrl(siteInfo, contentInfo, false); + } + else if (channelId != 0) + { + redirectUrl = PageUtility.GetChannelUrl(siteInfo, channelInfo, false); + } + else if (siteId != 0) + { + redirectUrl = PageUtility.GetIndexPageUrl(siteInfo, false); + } + + if (!string.IsNullOrEmpty(redirectUrl)) + { + var parameters = new NameValueCollection(); + var returnUrl = Request.GetQueryString("returnUrl"); + if (!string.IsNullOrEmpty(returnUrl) && returnUrl.StartsWith("?")) + { + parameters = TranslateUtils.ToNameValueCollection(returnUrl.Substring(1)); + } + + parameters["__r"] = StringUtils.GetRandomInt(1, 10000).ToString(); + + WebPageUtils.Redirect(PageUtils.AddQueryString(redirectUrl, parameters)); + return; + } + } + } + catch + { + var redirectUrl = PageUtility.GetIndexPageUrl(siteInfo, false); + WebPageUtils.Redirect(redirectUrl); + return; + } + + HttpContext.Current.Response.Write(string.Empty); + HttpContext.Current.Response.End(); + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Sys/SysStlActionsUploadController.cs b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsUploadController.cs new file mode 100644 index 000000000..cdf23cf2d --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Sys/SysStlActionsUploadController.cs @@ -0,0 +1,112 @@ +using System; +using System.Collections.Specialized; +using System.Web; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes.Sys.Stl; +using SiteServer.CMS.Database.Models; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.Sys +{ + public class SysStlActionsUploadController : ApiController + { + [HttpPost, Route(ApiRouteActionsUpload.Route)] + public IHttpActionResult Main(int siteId) + { + var siteInfo = SiteManager.GetSiteInfo(siteId); + var type = HttpContext.Current.Request.QueryString["type"]; + + var jsonAttributes = new NameValueCollection(); + + var success = false; + var message = string.Empty; + var url = string.Empty; + var value = string.Empty; + + if (type == ApiRouteActionsUpload.TypeResume) + { + success = UploadResumeImage(siteInfo, out message, out url, out value); + } + else if (type == ApiRouteActionsUpload.TypeGovPublicApply) + { + success = UploadGovPublicApply(siteInfo, out message, out url, out value); + } + + jsonAttributes.Add("success", success.ToString().ToLower()); + jsonAttributes.Add("message", message); + jsonAttributes.Add("url", url); + jsonAttributes.Add("value", value); + + return Ok(jsonAttributes); + } + + public bool UploadResumeImage(SiteInfo siteInfo, out string message, out string url, out string value) + { + message = url = value = string.Empty; + + if (HttpContext.Current.Request.Files["ImageUrl"] == null) return false; + var postedFile = HttpContext.Current.Request.Files["ImageUrl"]; + + var filePath = postedFile.FileName; + try + { + var fileExtName = PathUtils.GetExtension(filePath).ToLower(); + var localDirectoryPath = PathUtility.GetUploadDirectoryPath(siteInfo, fileExtName); + var localFileName = PathUtility.GetUploadFileName(siteInfo, filePath); + var localFilePath = PathUtils.Combine(localDirectoryPath, localFileName); + + if (!PathUtility.IsImageExtenstionAllowed(siteInfo, fileExtName)) + { + message = "上传失败,上传图片格式不正确!"; + return false; + } + if (!PathUtility.IsImageSizeAllowed(siteInfo, postedFile.ContentLength)) + { + message = "上传失败,上传图片超出规定文件大小!"; + return false; + } + + postedFile.SaveAs(localFilePath); + + url = PageUtility.GetSiteUrlByPhysicalPath(siteInfo, localFilePath, false); + value = PageUtility.GetVirtualUrl(siteInfo, url); + return true; + } + catch (Exception ex) + { + message = ex.Message; + } + return false; + } + + public bool UploadGovPublicApply(SiteInfo siteInfo, out string message, out string url, out string value) + { + message = url = value = string.Empty; + + if (HttpContext.Current.Request.Files.Count == 0) return false; + var postedFile = HttpContext.Current.Request.Files[0]; + + var filePath = postedFile.FileName; + try + { + var fileExtName = PathUtils.GetExtension(filePath).ToLower(); + var localDirectoryPath = PathUtility.GetUploadDirectoryPath(siteInfo, fileExtName); + var localFileName = PathUtility.GetUploadFileName(siteInfo, filePath); + var localFilePath = PathUtils.Combine(localDirectoryPath, localFileName); + + postedFile.SaveAs(localFilePath); + + url = PageUtility.GetSiteUrlByPhysicalPath(siteInfo, localFilePath, false); + value = PageUtility.GetVirtualUrl(siteInfo, url); + return true; + } + catch (Exception ex) + { + message = ex.Message; + } + return false; + } + } +} diff --git a/net452/SiteServer.Web/Controllers/Sys/SysUEditorController.cs b/net452/SiteServer.Web/Controllers/Sys/SysUEditorController.cs new file mode 100644 index 000000000..6bab12e84 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/Sys/SysUEditorController.cs @@ -0,0 +1,87 @@ +using System.Web; +using System.Web.Http; +using SiteServer.CMS.Core.RestRoutes.Sys.Editors; +using SiteServer.CMS.UEditor; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.API.Controllers.Sys +{ + public class SysUEditorController : ApiController + { + [HttpGet, Route(ApiRouteUEditor.Route)] + public void GetMain(int siteId) + { + Main(siteId); + } + + [HttpPost, Route(ApiRouteUEditor.Route)] + public void PostMain(int siteId) + { + Main(siteId); + } + + public void Main(int siteId) + { + var queryString = HttpContext.Current.Request.QueryString; + + Handler action; + switch (queryString["action"]) + { + case "config": + action = new ConfigHandler(HttpContext.Current); + break; + case "uploadimage": + action = new UploadHandler(HttpContext.Current, new UploadConfig + { + AllowExtensions = Config.GetStringList("imageAllowFiles"), + PathFormat = Config.GetString("imagePathFormat"), + SizeLimit = Config.GetInt("imageMaxSize"), + UploadFieldName = Config.GetString("imageFieldName") + }, siteId, EUploadType.Image); + break; + case "uploadscrawl": + action = new UploadHandler(HttpContext.Current, new UploadConfig + { + AllowExtensions = new[] { ".png" }, + PathFormat = Config.GetString("scrawlPathFormat"), + SizeLimit = Config.GetInt("scrawlMaxSize"), + UploadFieldName = Config.GetString("scrawlFieldName"), + Base64 = true, + Base64Filename = "scrawl.png" + }, siteId, EUploadType.Image); + break; + case "uploadvideo": + action = new UploadHandler(HttpContext.Current, new UploadConfig + { + AllowExtensions = Config.GetStringList("videoAllowFiles"), + PathFormat = Config.GetString("videoPathFormat"), + SizeLimit = Config.GetInt("videoMaxSize"), + UploadFieldName = Config.GetString("videoFieldName") + }, siteId, EUploadType.Video); + break; + case "uploadfile": + action = new UploadHandler(HttpContext.Current, new UploadConfig + { + AllowExtensions = Config.GetStringList("fileAllowFiles"), + PathFormat = Config.GetString("filePathFormat"), + SizeLimit = Config.GetInt("fileMaxSize"), + UploadFieldName = Config.GetString("fileFieldName") + }, siteId, EUploadType.File); + break; + case "listimage": + action = new ListFileManager(HttpContext.Current, Config.GetString("imageManagerListPath"), Config.GetStringList("imageManagerAllowFiles"), siteId, EUploadType.Image); + break; + case "listfile": + action = new ListFileManager(HttpContext.Current, Config.GetString("fileManagerListPath"), Config.GetStringList("fileManagerAllowFiles"), siteId, EUploadType.File); + break; + case "catchimage": + action = new CrawlerHandler(HttpContext.Current, siteId); + break; + default: + action = new NotSupportedHandler(HttpContext.Current); + break; + } + action.Process(); + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Controllers/TestController.cs b/net452/SiteServer.Web/Controllers/TestController.cs new file mode 100644 index 000000000..ee6bc0108 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/TestController.cs @@ -0,0 +1,96 @@ +using System; +using System.CodeDom.Compiler; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; + +namespace SiteServer.API.Controllers +{ + [RoutePrefix("test")] + public class TestController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public IHttpActionResult GetAdminOnly() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + if (!rest.IsAdminLoggin || + !rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.Admin)) + { + return Unauthorized(); + } + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + return InternalServerError(ex); + } + } + + //[HttpGet] + //public IHttpActionResult Get() + //{ + // var pluginIds = new List(); + // foreach (var pluginInfo in PluginManager.PluginInfoListRunnable) + // { + // if (!pluginInfo.IsDisabled) + // { + // pluginIds.Add(pluginInfo.Id); + // } + // } + // return Ok(new + // { + // DateTime = DateTime.Now, + // Plugins = pluginIds + // }); + //} + + //[HttpGet, Route("any")] + //public HttpResponseMessage GetAny() + //{ + // //return Content(HttpStatusCode.Created, new + // //{ + // // IsOk = true + // //}); + + // //var content = ; + + // var response = Request.CreateResponse(HttpStatusCode.NotFound); + + // response.Content = new StringContent("yes, yes", Encoding.UTF8); + + // return response; + //} + + //[HttpGet, Route("string")] + //public IHttpActionResult GetString() + //{ + // return Ok("Hello"); + //} + + //private readonly HttpClient _httpClient = new HttpClient(); + + //[HttpGet, Route("test/count")] + //public async Task GetDotNetCountAsync() + //{ + // // Suspends GetDotNetCountAsync() to allow the caller (the web server) + // // to accept another rest, rather than blocking on this one. + // var html = await _httpClient.GetStringAsync("http://dotnetfoundation.org"); + + // return Ok(new + // { + // Regex.Matches(html, @"\.NET").Count + // }); + //} + } +} diff --git a/net452/SiteServer.Web/Controllers/V1/V1AdministratorsController.cs b/net452/SiteServer.Web/Controllers/V1/V1AdministratorsController.cs new file mode 100644 index 000000000..9d842e8d6 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/V1/V1AdministratorsController.cs @@ -0,0 +1,341 @@ +using System; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes.V1; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SqlKata; + +namespace SiteServer.API.Controllers.V1 +{ + [RoutePrefix("v1/administrators")] + public class V1AdministratorsController : ApiController + { + private const string Route = ""; + private const string RouteMe = "me"; + private const string RouteActionsLogin = "actions/login"; + private const string RouteActionsLogout = "actions/logout"; + private const string RouteActionsResetPassword = "actions/resetPassword"; + private const string RouteAdministrator = "{id:int}"; + + [HttpPost, Route(Route)] + public IHttpActionResult Create() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var isApiAuthorized = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeAdministrators); + if (!isApiAuthorized) return Unauthorized(); + + var adminInfo = new AdministratorInfo + { + UserName = Request.GetPostString(nameof(AdministratorInfo.UserName)), + Password = Request.GetPostString(nameof(AdministratorInfo.Password)), + CreationDate = DateTime.Now, + CreatorUserName = rest.UserName, + Locked = Request.GetPostBool(nameof(AdministratorInfo.Locked)), + SiteIdCollection = Request.GetPostString(nameof(AdministratorInfo.SiteIdCollection)), + SiteId = Request.GetPostInt(nameof(AdministratorInfo.SiteId)), + DepartmentId = Request.GetPostInt(nameof(AdministratorInfo.DepartmentId)), + AreaId = Request.GetPostInt(nameof(AdministratorInfo.AreaId)), + DisplayName = Request.GetPostString(nameof(AdministratorInfo.DisplayName)), + Mobile = Request.GetPostString(nameof(AdministratorInfo.Mobile)), + Email = Request.GetPostString(nameof(AdministratorInfo.Email)), + AvatarUrl = Request.GetPostString(nameof(AdministratorInfo.AvatarUrl)) + }; + + var id = DataProvider.Administrator.Insert(adminInfo, out var errorMessage); + if (id == 0) + { + return BadRequest(errorMessage); + } + + return Ok(new + { + Value = adminInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPut, Route(RouteAdministrator)] + public IHttpActionResult Update(int id) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var isApiAuthorized = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeAdministrators); + if (!isApiAuthorized) return Unauthorized(); + + var adminInfo = AdminManager.GetAdminInfoByUserId(id); + + if (adminInfo == null) return NotFound(); + + if (Request.IsPostExists(nameof(AdministratorInfo.UserName))) + { + adminInfo.UserName = Request.GetPostString(nameof(AdministratorInfo.UserName)); + } + if (Request.IsPostExists(nameof(AdministratorInfo.Locked))) + { + adminInfo.Locked = Request.GetPostBool(nameof(AdministratorInfo.Locked)); + } + if (Request.IsPostExists(nameof(AdministratorInfo.SiteIdCollection))) + { + adminInfo.SiteIdCollection = Request.GetPostString(nameof(AdministratorInfo.SiteIdCollection)); + } + if (Request.IsPostExists(nameof(AdministratorInfo.SiteId))) + { + adminInfo.SiteId = Request.GetPostInt(nameof(AdministratorInfo.SiteId)); + } + if (Request.IsPostExists(nameof(AdministratorInfo.DepartmentId))) + { + adminInfo.DepartmentId = Request.GetPostInt(nameof(AdministratorInfo.DepartmentId)); + } + if (Request.IsPostExists(nameof(AdministratorInfo.AreaId))) + { + adminInfo.AreaId = Request.GetPostInt(nameof(AdministratorInfo.AreaId)); + } + if (Request.IsPostExists(nameof(AdministratorInfo.DisplayName))) + { + adminInfo.DisplayName = Request.GetPostString(nameof(AdministratorInfo.DisplayName)); + } + if (Request.IsPostExists(nameof(AdministratorInfo.Mobile))) + { + adminInfo.Mobile = Request.GetPostString(nameof(AdministratorInfo.Mobile)); + } + if (Request.IsPostExists(nameof(AdministratorInfo.Email))) + { + adminInfo.Email = Request.GetPostString(nameof(AdministratorInfo.Email)); + } + if (Request.IsPostExists(nameof(AdministratorInfo.AvatarUrl))) + { + adminInfo.AvatarUrl = Request.GetPostString(nameof(AdministratorInfo.AvatarUrl)); + } + + var updated = DataProvider.Administrator.Update(adminInfo, out var errorMessage); + if (!updated) + { + return BadRequest(errorMessage); + } + + return Ok(new + { + Value = adminInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpDelete, Route(RouteAdministrator)] + public IHttpActionResult Delete(int id) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var isApiAuthorized = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeAdministrators); + if (!isApiAuthorized) return Unauthorized(); + + var adminInfo = AdminManager.GetAdminInfoByUserId(id); + if (adminInfo == null) return NotFound(); + + DataProvider.Administrator.Delete(adminInfo); + + return Ok(new + { + Value = adminInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpGet, Route(RouteAdministrator)] + public IHttpActionResult Get(int id) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var isApiAuthorized = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeAdministrators); + if (!isApiAuthorized) return Unauthorized(); + + var adminInfo = AdminManager.GetAdminInfoByUserId(id); + + if (adminInfo == null) return NotFound(); + + return Ok(new + { + Value = adminInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpGet, Route(RouteMe)] + public IHttpActionResult GetSelf() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + if (!rest.IsAdminLoggin) return Unauthorized(); + + var adminInfo = AdminManager.GetAdminInfoByUserId(rest.AdminId); + + return Ok(new + { + Value = adminInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpGet, Route(Route)] + public IHttpActionResult List() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var isApiAuthorized = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeAdministrators); + if (!isApiAuthorized) return Unauthorized(); + + var top = Request.GetQueryInt("top", 20); + var skip = Request.GetQueryInt("skip"); + + var query = new Query().Limit(top).Offset(skip); + var administrators = DataProvider.Administrator.GetAll(query); + var count = DataProvider.Administrator.GetCount(); + + return Ok(new PageResponse(administrators, top, skip, Request.RequestUri.AbsoluteUri) { Count = count }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteActionsLogin)] + public IHttpActionResult Login() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var account = Request.GetPostString("account"); + var password = Request.GetPostString("password"); + var isAutoLogin = Request.GetPostBool("isAutoLogin"); + + AdministratorInfo adminInfo; + + if (!DataProvider.Administrator.Validate(account, password, true, out var userName, out var errorMessage)) + { + adminInfo = AdminManager.GetAdminInfoByUserName(userName); + if (adminInfo != null) + { + DataProvider.Administrator.UpdateLastActivityDateAndCountOfFailedLogin(adminInfo); // 记录最后登录时间、失败次数+1 + } + return BadRequest(errorMessage); + } + + adminInfo = AdminManager.GetAdminInfoByUserName(userName); + DataProvider.Administrator.UpdateLastActivityDateAndCountOfLogin(adminInfo); // 记录最后登录时间、失败次数清零 + var accessToken = rest.AdminLogin(adminInfo.UserName, isAutoLogin); + var expiresAt = DateTime.Now.AddDays(Constants.AccessTokenExpireDays); + + return Ok(new + { + Value = adminInfo, + AccessToken = accessToken, + ExpiresAt = expiresAt + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteActionsLogout)] + public IHttpActionResult Logout() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var adminInfo = AdminManager.GetAdminInfoByUserId(rest.AdminId); + + return Ok(new + { + Value = adminInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteActionsResetPassword)] + public IHttpActionResult ResetPassword() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var isApiAuthorized = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeAdministrators); + if (!isApiAuthorized) return Unauthorized(); + + var account = Request.GetPostString("account"); + var password = Request.GetPostString("password"); + var newPassword = Request.GetPostString("newPassword"); + + if (!DataProvider.Administrator.Validate(account, password, true, out var userName, out var errorMessage)) + { + return BadRequest(errorMessage); + } + + var adminInfo = AdminManager.GetAdminInfoByUserName(userName); + + if (!DataProvider.Administrator.ChangePassword(adminInfo, newPassword, out errorMessage)) + { + return BadRequest(errorMessage); + } + + return Ok(new + { + Value = adminInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/V1/V1CaptchaController.cs b/net452/SiteServer.Web/Controllers/V1/V1CaptchaController.cs new file mode 100644 index 000000000..d6138d75a --- /dev/null +++ b/net452/SiteServer.Web/Controllers/V1/V1CaptchaController.cs @@ -0,0 +1,125 @@ +using System; +using System.Drawing; +using System.Drawing.Imaging; +using System.IO; +using System.Web; +using System.Web.Http; +using SiteServer.BackgroundPages.Core; +using SiteServer.CMS.Core; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.V1 +{ + [RoutePrefix("v1/captcha")] + public class V1CaptchaController : ApiController + { + private const string ApiRoute = "{name}"; + private const string ApiRouteActionsCheck = "{name}/actions/check"; + + private static readonly Color[] Colors = { Color.FromArgb(37, 72, 91), Color.FromArgb(68, 24, 25), Color.FromArgb(17, 46, 2), Color.FromArgb(70, 16, 100), Color.FromArgb(24, 88, 74) }; + + [HttpGet, Route(ApiRoute)] + public void Get(string name) + { + var response = HttpContext.Current.Response; + + var code = VcManager.CreateValidateCode(); + if (CacheUtils.Exists($"SiteServer.API.Controllers.V1.CaptchaController.{code}")) + { + code = VcManager.CreateValidateCode(); + } + + CookieUtils.SetCookie("SS-" + name, code, TimeSpan.FromMinutes(10)); + + response.BufferOutput = true; //特别注意 + response.Cache.SetExpires(DateTime.Now.AddMilliseconds(-1));//特别注意 + response.Cache.SetCacheability(HttpCacheability.NoCache);//特别注意 + response.AppendHeader("Pragma", "No-Cache"); //特别注意 + response.ContentType = "image/png"; + + byte[] buffer; + + using (var image = new Bitmap(130, 53, PixelFormat.Format32bppRgb)) + { + var r = new Random(); + var colors = Colors[r.Next(0, 5)]; + + using (var g = Graphics.FromImage(image)) + { + g.FillRectangle(new SolidBrush(Color.FromArgb(240, 243, 248)), 0, 0, 200, 200); //矩形框 + g.DrawString(code, new Font(FontFamily.GenericSerif, 28, FontStyle.Bold | FontStyle.Italic), new SolidBrush(colors), new PointF(14, 3));//字体/颜色 + + var random = new Random(); + + for (var i = 0; i < 25; i++) + { + var x1 = random.Next(image.Width); + var x2 = random.Next(image.Width); + var y1 = random.Next(image.Height); + var y2 = random.Next(image.Height); + + g.DrawLine(new Pen(Color.Silver), x1, y1, x2, y2); + } + + for (var i = 0; i < 100; i++) + { + var x = random.Next(image.Width); + var y = random.Next(image.Height); + + image.SetPixel(x, y, Color.FromArgb(random.Next())); + } + + g.Save(); + } + + using (var ms = new MemoryStream()) + { + image.Save(ms, ImageFormat.Png); + buffer = ms.ToArray(); + } + } + + response.ClearContent(); + response.BinaryWrite(buffer); + response.End(); + } + + [HttpPost, Route(ApiRouteActionsCheck)] + public IHttpActionResult Check(string name) + { + var rest = Request.GetAuthenticatedRequest(); + var captcha = Request.GetPostString("captcha"); + + try + { + var code = CookieUtils.GetCookie("SS-" + name); + + if (string.IsNullOrEmpty(code) || CacheUtils.Exists($"SiteServer.API.Controllers.V1.CaptchaController.{code}")) + { + return BadRequest("验证码已超时,请点击刷新验证码!"); + } + + CookieUtils.Erase("SS-" + name); + CacheUtils.InsertMinutes($"SiteServer.API.Controllers.V1.CaptchaController.{code}", true, 10); + + if (!StringUtils.EqualsIgnoreCase(code, captcha)) + { + return BadRequest("验证码不正确,请重新输入!"); + } + + return Ok(new + { + Value = true + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/V1/V1ContentsController.cs b/net452/SiteServer.Web/Controllers/V1/V1ContentsController.cs new file mode 100644 index 000000000..a61cdf28f --- /dev/null +++ b/net452/SiteServer.Web/Controllers/V1/V1ContentsController.cs @@ -0,0 +1,453 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Net.Http; +using System.Web; +using System.Web.Http; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Caches.Content; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.Create; +using SiteServer.CMS.Core.RestRoutes.V1; +using SiteServer.CMS.Database.Attributes; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; + +namespace SiteServer.API.Controllers.V1 +{ + [RoutePrefix("v1/contents")] + public class V1ContentsController : ApiController + { + private const string RouteSite = "{siteId:int}"; + private const string RouteChannel = "{siteId:int}/{channelId:int}"; + private const string RouteContent = "{siteId:int}/{channelId:int}/{id:int}"; + + [HttpPost, Route(RouteChannel)] + public IHttpActionResult Create(int siteId, int channelId) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var sourceId = Request.GetPostInt(ContentAttribute.SourceId.ToCamelCase()); + bool isAuth; + if (sourceId == SourceManager.User) + { + isAuth = rest.IsUserLoggin && rest.UserPermissions.HasChannelPermissions(siteId, channelId, ConfigManager.ChannelPermissions.ContentAdd); + } + else + { + isAuth = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeContents) || + rest.IsUserLoggin && + rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd) || + rest.IsAdminLoggin && + rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentAdd); + } + if (!isAuth) return Unauthorized(); + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + if (!channelInfo.IsContentAddable) return BadRequest("此栏目不能添加内容"); + + var attributes = Request.GetPostObject>(); + if (attributes == null) return BadRequest("无法从body中获取内容实体"); + var checkedLevel = Request.GetPostInt("checkedLevel"); + + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + var adminName = rest.AdminName; + + var isChecked = checkedLevel >= siteInfo.CheckContentLevel; + if (isChecked) + { + if (sourceId == SourceManager.User || rest.IsUserLoggin) + { + isChecked = rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentCheck); + } + else if (rest.IsAdminLoggin) + { + isChecked = rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentCheck); + } + } + + var contentInfo = new ContentInfo(attributes) + { + SiteId = siteId, + ChannelId = channelId, + AddUserName = adminName, + LastEditDate = DateTime.Now, + LastEditUserName = adminName, + AdminId = rest.AdminId, + UserId = rest.UserId, + SourceId = sourceId, + Checked = isChecked, + CheckedLevel = checkedLevel + }; + + contentInfo.Id = DataProvider.ContentRepository.Insert(tableName, siteInfo, channelInfo, contentInfo); + + foreach (var service in PluginManager.Services) + { + try + { + service.OnContentFormSubmit(new ContentFormSubmitEventArgs(siteId, channelId, contentInfo.Id, attributes, contentInfo)); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(service.PluginId, ex, nameof(IService.ContentFormSubmit)); + } + } + + if (contentInfo.Checked) + { + CreateManager.CreateContent(siteId, channelId, contentInfo.Id); + CreateManager.TriggerContentChangedEvent(siteId, channelId); + } + + LogUtils.AddSiteLog(siteId, channelId, contentInfo.Id, rest.AdminName, "添加内容", + $"栏目:{ChannelManager.GetChannelNameNavigation(siteId, contentInfo.ChannelId)},内容标题:{contentInfo.Title}"); + + return Ok(new + { + Value = contentInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPut, Route(RouteContent)] + public IHttpActionResult Update(int siteId, int channelId, int id) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var sourceId = Request.GetPostInt(ContentAttribute.SourceId.ToCamelCase()); + bool isAuth; + if (sourceId == SourceManager.User) + { + isAuth = rest.IsUserLoggin && rest.UserPermissions.HasChannelPermissions(siteId, channelId, ConfigManager.ChannelPermissions.ContentEdit); + } + else + { + isAuth = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeContents) || + rest.IsUserLoggin && + rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentEdit) || + rest.IsAdminLoggin && + rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentEdit); + } + if (!isAuth) return Unauthorized(); + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + var attributes = Request.GetPostObject>(); + if (attributes == null) return BadRequest("无法从body中获取内容实体"); + + var adminName = rest.AdminName; + + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, id); + if (contentInfo == null) return NotFound(); + var isChecked = contentInfo.Checked; + var checkedLevel = contentInfo.CheckedLevel; + + foreach (var attribute in attributes) + { + contentInfo.Set(attribute.Key, attribute.Value); + } + + contentInfo.SiteId = siteId; + contentInfo.ChannelId = channelId; + contentInfo.AddUserName = adminName; + contentInfo.LastEditDate = DateTime.Now; + contentInfo.LastEditUserName = adminName; + contentInfo.SourceId = sourceId; + + var postCheckedLevel = Request.GetPostInt(ContentAttribute.CheckedLevel.ToCamelCase()); + if (postCheckedLevel != CheckManager.LevelInt.NotChange) + { + isChecked = postCheckedLevel >= siteInfo.CheckContentLevel; + checkedLevel = postCheckedLevel; + } + + contentInfo.Checked = isChecked; + contentInfo.CheckedLevel = checkedLevel; + + DataProvider.ContentRepository.Update(siteInfo, channelInfo, contentInfo); + + foreach (var service in PluginManager.Services) + { + try + { + service.OnContentFormSubmit(new ContentFormSubmitEventArgs(siteId, channelId, contentInfo.Id, attributes, contentInfo)); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(service.PluginId, ex, nameof(IService.ContentFormSubmit)); + } + } + + if (contentInfo.Checked) + { + CreateManager.CreateContent(siteId, channelId, contentInfo.Id); + CreateManager.TriggerContentChangedEvent(siteId, channelId); + } + + LogUtils.AddSiteLog(siteId, channelId, contentInfo.Id, rest.AdminName, "修改内容", + $"栏目:{ChannelManager.GetChannelNameNavigation(siteId, contentInfo.ChannelId)},内容标题:{contentInfo.Title}"); + + return Ok(new + { + Value = contentInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpDelete, Route(RouteContent)] + public IHttpActionResult Delete(int siteId, int channelId, int id) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var sourceId = Request.GetPostInt(ContentAttribute.SourceId.ToCamelCase()); + bool isAuth; + if (sourceId == SourceManager.User) + { + isAuth = rest.IsUserLoggin && rest.UserPermissions.HasChannelPermissions(siteId, channelId, ConfigManager.ChannelPermissions.ContentDelete); + } + else + { + isAuth = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeContents) || + rest.IsUserLoggin && + rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentDelete) || + rest.IsAdminLoggin && + rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentDelete); + } + if (!isAuth) return Unauthorized(); + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + if (!rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentDelete)) return Unauthorized(); + + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, id); + if (contentInfo == null) return NotFound(); + + //channelInfo.ContentRepository.DeleteContent(siteId, channelId, id); + + ContentManager.Delete(siteInfo, channelInfo, id); + + return Ok(new + { + Value = contentInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpGet, Route(RouteContent)] + public IHttpActionResult Get(int siteId, int channelId, int id) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var sourceId = Request.GetPostInt(ContentAttribute.SourceId.ToCamelCase()); + bool isAuth; + if (sourceId == SourceManager.User) + { + isAuth = rest.IsUserLoggin && rest.UserPermissions.HasChannelPermissions(siteId, channelId, ConfigManager.ChannelPermissions.ContentView); + } + else + { + isAuth = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeContents) || + rest.IsUserLoggin && + rest.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentView) || + rest.IsAdminLoggin && + rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentView); + } + if (!isAuth) return Unauthorized(); + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + if (!rest.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentView)) return Unauthorized(); + + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelInfo, id); + if (contentInfo == null) return NotFound(); + + return Ok(new + { + Value = contentInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpGet, Route(RouteSite)] + public IHttpActionResult GetSiteContents(int siteId) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var sourceId = Request.GetPostInt(ContentAttribute.SourceId.ToCamelCase()); + bool isAuth; + if (sourceId == SourceManager.User) + { + isAuth = rest.IsUserLoggin && rest.UserPermissions.HasChannelPermissions(siteId, siteId, ConfigManager.ChannelPermissions.ContentView); + } + else + { + isAuth = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeContents) || + rest.IsUserLoggin && + rest.UserPermissions.HasChannelPermissions(siteId, siteId, + ConfigManager.ChannelPermissions.ContentView) || + rest.IsAdminLoggin && + rest.AdminPermissions.HasChannelPermissions(siteId, siteId, + ConfigManager.ChannelPermissions.ContentView); + } + if (!isAuth) return Unauthorized(); + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + if (!rest.AdminPermissions.HasChannelPermissions(siteId, siteId, + ConfigManager.ChannelPermissions.ContentView)) return Unauthorized(); + + var tableName = siteInfo.TableName; + + var parameters = new ApiContentsParameters(Request); + + var list = DataProvider.ContentRepository.ApiGetContentIdListBySiteId(tableName, siteId, parameters, out var count); + + var retVal = new List>(); + foreach (var (channelId, contentId) in list) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, channelId, contentId); + if (contentInfo != null) + { + retVal.Add(contentInfo.ToDictionary()); + } + } + + return Ok(new PageResponse(retVal, parameters.Top, parameters.Skip, Request.RequestUri.AbsoluteUri) {Count = count}); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpGet, Route(RouteChannel)] + public IHttpActionResult GetChannelContents(int siteId, int channelId) + { + try + { +#pragma warning disable CS0612 // '“RequestImpl”已过时 + var request = new RequestImpl(HttpContext.Current.Request); +#pragma warning restore CS0612 // '“RequestImpl”已过时 + + var sourceId = request.GetPostInt(ContentAttribute.SourceId.ToCamelCase()); + bool isAuth; + if (sourceId == SourceManager.User) + { + isAuth = request.IsUserLoggin && request.UserPermissions.HasChannelPermissions(siteId, channelId, ConfigManager.ChannelPermissions.ContentView); + } + else + { + isAuth = request.IsApiAuthenticated && + AccessTokenManager.IsScope(request.ApiToken, AccessTokenManager.ScopeContents) || + request.IsUserLoggin && + request.UserPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentView) || + request.IsAdminLoggin && + request.AdminPermissions.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentView); + } + if (!isAuth) return Unauthorized(); + + var siteInfo = SiteManager.GetSiteInfo(siteId); + if (siteInfo == null) return BadRequest("无法确定内容对应的站点"); + + var channelInfo = ChannelManager.GetChannelInfo(siteId, channelId); + if (channelInfo == null) return BadRequest("无法确定内容对应的栏目"); + + if (!request.AdminPermissionsImpl.HasChannelPermissions(siteId, channelId, + ConfigManager.ChannelPermissions.ContentView)) return Unauthorized(); + + var tableName = ChannelManager.GetTableName(siteInfo, channelInfo); + + var top = request.GetQueryInt("top", 20); + var skip = request.GetQueryInt("skip"); + var like = request.GetQueryString("like"); + var orderBy = request.GetQueryString("orderBy"); + + var list = DataProvider.ContentRepository.ApiGetContentIdListByChannelId(tableName, siteId, channelId, top, skip, like, orderBy, request.QueryString, out var count); + + var retVal = new List>(); + foreach (var (contentChannelId, contentId) in list) + { + var contentInfo = ContentManager.GetContentInfo(siteInfo, contentChannelId, contentId); + if (contentInfo != null) + { + retVal.Add(contentInfo.ToDictionary()); + } + } + + return Ok(new PageResponse(retVal, top, skip, request.HttpRequest.Url.AbsoluteUri) { Count = count }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/V1/V1PingController.cs b/net452/SiteServer.Web/Controllers/V1/V1PingController.cs new file mode 100644 index 000000000..6a50211fb --- /dev/null +++ b/net452/SiteServer.Web/Controllers/V1/V1PingController.cs @@ -0,0 +1,28 @@ +using System.Net; +using System.Net.Http; +using System.Text; +using System.Web.Http; + +namespace SiteServer.API.Controllers.V1 +{ + [RoutePrefix("v1/ping")] + public class V1PingController : ApiController + { + private const string Route = ""; + + [HttpGet, Route(Route)] + public HttpResponseMessage Get() + { + //var response = Request.CreateResponse(HttpStatusCode.OK); + + //response.Content = new StringContent("pong", Encoding.UTF8); + + var response = new HttpResponseMessage(HttpStatusCode.OK) + { + Content = new StringContent("pong", Encoding.UTF8) + }; + + return response; + } + } +} diff --git a/net452/SiteServer.Web/Controllers/V1/V1StlController.cs b/net452/SiteServer.Web/Controllers/V1/V1StlController.cs new file mode 100644 index 000000000..1a3f8ad32 --- /dev/null +++ b/net452/SiteServer.Web/Controllers/V1/V1StlController.cs @@ -0,0 +1,73 @@ +using System; +using System.Web; +using System.Web.Http; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes.V1; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.CMS.StlParser.Model; +using SiteServer.CMS.StlParser.Parsers; +using SiteServer.Plugin; + +namespace SiteServer.API.Controllers.V1 +{ + [RoutePrefix("v1/stl")] + public class V1StlController : ApiController + { + private const string Route = "{elementName}"; + + [HttpGet, Route(Route)] + public IHttpActionResult Get(string elementName) + { + try + { + var stlRequest = new StlRequest(Request); + + if (!stlRequest.IsApiAuthorized) + { + return Unauthorized(); + } + + var siteInfo = stlRequest.SiteInfo; + + if (siteInfo == null) + { + return NotFound(); + } + + elementName = $"stl:{elementName.ToLower()}"; + + object value = null; + + if (StlElementParser.ElementsToParseDic.ContainsKey(elementName)) + { + Func func; + if (StlElementParser.ElementsToParseDic.TryGetValue(elementName, out func)) + { + var obj = func(stlRequest.PageInfo, stlRequest.ContextInfo); + + if (obj is string) + { + value = (string)obj; + } + else + { + value = obj; + } + } + } + + return Ok(new + { + Value = value + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/Controllers/V1/V1UsersController.cs b/net452/SiteServer.Web/Controllers/V1/V1UsersController.cs new file mode 100644 index 000000000..ca29cf4ba --- /dev/null +++ b/net452/SiteServer.Web/Controllers/V1/V1UsersController.cs @@ -0,0 +1,414 @@ +using System; +using System.Collections.Generic; +using System.Web; +using System.Web.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Core.RestRoutes.V1; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.API.Controllers.V1 +{ + [RoutePrefix("v1/users")] + public class V1UsersController : ApiController + { + private const string Route = ""; + private const string RouteActionsLogin = "actions/login"; + private const string RouteActionsLogout = "actions/logout"; + private const string RouteUser = "{id:int}"; + private const string RouteUserAvatar = "{id:int}/avatar"; + private const string RouteUserLogs = "{id:int}/logs"; + private const string RouteUserResetPassword = "{id:int}/actions/resetPassword"; + + [HttpPost, Route(Route)] + public IHttpActionResult Create() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var dict = Request.GetPostObject>(); + + var userInfo = new UserInfo(); + foreach (var o in dict) + { + userInfo.Set(o.Key, o.Value); + } + + if (!ConfigManager.Instance.IsUserRegistrationGroup) + { + userInfo.GroupId = 0; + } + var password = Request.GetPostString("password"); + + var userId = DataProvider.User.Insert(userInfo, password, FxUtils.GetIpAddress(), out var errorMessage); + if (userId == 0) + { + return BadRequest(errorMessage); + } + + return Ok(new + { + Value = UserManager.GetUserInfoByUserId(userId) + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPut, Route(RouteUser)] + public IHttpActionResult Update(int id) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var isAuth = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeUsers) || + rest.IsUserLoggin && + rest.UserId == id || + rest.IsAdminLoggin && + rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User); + if (!isAuth) return Unauthorized(); + + var body = Request.GetPostObject>(); + + if (body == null) return BadRequest("Could not read user from body"); + + var userInfo = UserManager.GetUserInfoByUserId(id); + if (userInfo == null) return NotFound(); + + var retval = DataProvider.User.Update(userInfo, body, out var errorMessage); + if (retval == null) + { + return BadRequest(errorMessage); + } + + return Ok(new + { + Value = retval + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpDelete, Route(RouteUser)] + public IHttpActionResult Delete(int id) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var isAuth = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeUsers) || + rest.IsUserLoggin && + rest.UserId == id || + rest.IsAdminLoggin && + rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User); + if (!isAuth) return Unauthorized(); + + var userInfo = UserManager.GetUserInfoByUserId(id); + if (userInfo == null) return NotFound(); + + rest.UserLogout(); + DataProvider.User.Delete(userInfo); + + return Ok(new + { + Value = userInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpGet, Route(RouteUser)] + public IHttpActionResult Get(int id) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var isAuth = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeUsers) || + rest.IsUserLoggin && + rest.UserId == id || + rest.IsAdminLoggin && + rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User); + if (!isAuth) return Unauthorized(); + + if (!DataProvider.User.IsExists(id)) return NotFound(); + + var user = UserManager.GetUserInfoByUserId(id); + + return Ok(new + { + Value = user + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpGet, Route(RouteUserAvatar)] + public IHttpActionResult GetAvatar(int id) + { + var userInfo = UserManager.GetUserInfoByUserId(id); + + var avatarUrl = !string.IsNullOrEmpty(userInfo?.AvatarUrl) ? userInfo.AvatarUrl : UserManager.DefaultAvatarUrl; + avatarUrl = FxUtils.AddProtocolToUrl(avatarUrl); + + return Ok(new + { + Value = avatarUrl + }); + } + + [HttpPost, Route(RouteUserAvatar)] + public IHttpActionResult UploadAvatar(int id) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var isAuth = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeUsers) || + rest.IsUserLoggin && + rest.UserId == id || + rest.IsAdminLoggin && + rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User); + if (!isAuth) return Unauthorized(); + + var userInfo = UserManager.GetUserInfoByUserId(id); + if (userInfo == null) return NotFound(); + + foreach (string name in HttpContext.Current.Request.Files) + { + var postFile = HttpContext.Current.Request.Files[name]; + + if (postFile == null) + { + return BadRequest("Could not read image from body"); + } + + var fileName = UserManager.GetUserUploadFileName(postFile.FileName); + var filePath = UserManager.GetUserUploadPath(userInfo.Id, fileName); + + if (!EFileSystemTypeUtils.IsImage(PathUtils.GetExtension(fileName))) + { + return BadRequest("image file extension is not correct"); + } + + DirectoryUtils.CreateDirectoryIfNotExists(filePath); + postFile.SaveAs(filePath); + + userInfo.AvatarUrl = UserManager.GetUserUploadUrl(userInfo.Id, fileName); + + DataProvider.User.Update(userInfo); + } + + return Ok(new + { + Value = userInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpGet, Route(Route)] + public IHttpActionResult List() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var isAuth = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeUsers) || + rest.IsAdminLoggin && + rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User); + if (!isAuth) return Unauthorized(); + + var top = Request.GetQueryInt("top", 20); + var skip = Request.GetQueryInt("skip"); + + var users = DataProvider.User.GetUsers(skip, top); + var count = DataProvider.User.GetCount(); + + return Ok(new PageResponse(users, top, skip, Request.RequestUri.AbsoluteUri) { Count = count }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteActionsLogin)] + public IHttpActionResult Login() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + + var account = Request.GetPostString("account"); + var password = Request.GetPostString("password"); + var isAutoLogin = Request.GetPostBool("isAutoLogin"); + + var userInfo = DataProvider.User.Validate(account, password, true, out var _, out var errorMessage); + if (userInfo == null) + { + return BadRequest(errorMessage); + } + + var accessToken = rest.UserLogin(userInfo.UserName, isAutoLogin); + var expiresAt = DateTime.Now.AddDays(Constants.AccessTokenExpireDays); + + return Ok(new + { + Value = userInfo, + AccessToken = accessToken, + ExpiresAt = expiresAt + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteActionsLogout)] + public IHttpActionResult Logout() + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var userInfo = UserManager.GetUserInfoByUserId(rest.UserId); + rest.UserLogout(); + + return Ok(new + { + Value = userInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteUserLogs)] + public IHttpActionResult CreateLog(int id, [FromBody] UserLogInfo logInfo) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var isAuth = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeUsers) || + rest.IsUserLoggin && + rest.UserId == id || + rest.IsAdminLoggin && + rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User); + if (!isAuth) return Unauthorized(); + + var userInfo = UserManager.GetUserInfoByUserId(id); + if (userInfo == null) return NotFound(); + + var retval = DataProvider.UserLog.Insert(userInfo.UserName, logInfo); + + return Ok(new + { + Value = retval + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpGet, Route(RouteUserLogs)] + public IHttpActionResult GetLogs(int id) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var isAuth = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeUsers) || + rest.IsUserLoggin && + rest.UserId == id || + rest.IsAdminLoggin && + rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User); + if (!isAuth) return Unauthorized(); + + var userInfo = UserManager.GetUserInfoByUserId(id); + if (userInfo == null) return NotFound(); + + var top = Request.GetQueryInt("top", 20); + var skip = Request.GetQueryInt("skip"); + + var logs = DataProvider.UserLog.ApiGetLogs(userInfo.UserName, skip, top); + + return Ok(new PageResponse(logs, top, skip, Request.RequestUri.AbsoluteUri) { Count = DataProvider.User.GetCount() }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + + [HttpPost, Route(RouteUserResetPassword)] + public IHttpActionResult ResetPassword(int id) + { + try + { + var rest = Request.GetAuthenticatedRequest(); + var isAuth = AccessTokenManager.IsScope(Request.GetApiToken(), AccessTokenManager.ScopeUsers) || + rest.IsUserLoggin && + rest.UserId == id || + rest.IsAdminLoggin && + rest.AdminPermissions.HasSystemPermissions(ConfigManager.SettingsPermissions.User); + if (!isAuth) return Unauthorized(); + + var userInfo = UserManager.GetUserInfoByUserId(id); + if (userInfo == null) return NotFound(); + + var password = Request.GetPostString("password"); + var newPassword = Request.GetPostString("newPassword"); + + if (!DataProvider.User.CheckPassword(password, false, userInfo.Password, EPasswordFormatUtils.GetEnumType(userInfo.PasswordFormat), userInfo.PasswordSalt)) + { + return BadRequest("原密码不正确,请重新输入"); + } + + if (!DataProvider.User.ChangePassword(userInfo.UserName, newPassword, out string errorMessage)) + { + return BadRequest(errorMessage); + } + + return Ok(new + { + Value = userInfo + }); + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + return InternalServerError(ex); + } + } + } +} diff --git a/net452/SiteServer.Web/ErrorRedirectModule.cs b/net452/SiteServer.Web/ErrorRedirectModule.cs new file mode 100644 index 000000000..70184b170 --- /dev/null +++ b/net452/SiteServer.Web/ErrorRedirectModule.cs @@ -0,0 +1,93 @@ +using System; +using System.Web; +using SiteServer.BackgroundPages.Utils; +using SiteServer.CMS.Core; + +namespace SiteServer.API +{ + public class ErrorRedirectModule : IHttpModule + { + public string ModuleName => "ErrorRedirectModule"; + + public void Init(HttpApplication app) + { + app.Error += Application_Error; + } + + private static void Application_Error(object sender, EventArgs e) + { + try + { + var lastError = HttpContext.Current.Server.GetLastError(); + if (lastError != null) + { + var httpError = lastError as HttpException; + if (httpError != null) + { + //ASP.NET的400与404错误不记录日志,并都以自定义404页面响应 + var httpCode = httpError.GetHttpCode(); + if (httpCode == 400 || httpCode == 404) + { + HttpContext.Current.Response.TrySkipIisCustomErrors = true; + HttpContext.Current.Response.StatusCode = 404;//在IIS中配置自定义404页面 + HttpContext.Current.Server.ClearError(); + return; + } + } + + //对于路径错误不记录日志,并都以自定义404页面响应 + if (lastError.TargetSite.ReflectedType == typeof(System.IO.Path)) + { + HttpContext.Current.Response.TrySkipIisCustomErrors = true; + HttpContext.Current.Response.StatusCode = 404; + HttpContext.Current.Server.ClearError(); + return; + } + + if (lastError.InnerException != null) + { + lastError = lastError.InnerException; + } + HttpContext.Current.Server.ClearError(); + + WebPageUtils.AddErrorLogAndRedirect(lastError, "Server Error in Application"); + } + + + //var ex = HttpContext.Current.Server.GetLastError(); + + //if (ex != null) + //{ + // var httpError = ex as HttpException; + // if (httpError != null && httpError.ErrorCode == 404) + // { + // var response = HttpContext.Current.Response; + // response.TrySkipIisCustomErrors = true; // For IIS 7 Integrated Pipeline - see previous post + // response.Status = "404 Not Found"; + // response.StatusCode = 404; + + // HttpContext.Current.Server.ClearError(); + // return; + // } + + // if (ex.InnerException != null) + // { + // ex = ex.InnerException; + // } + // HttpContext.Current.Server.ClearError(); + + // LogUtils.AddErrorLogAndRedirect(ex, "Server Error in Application"); + //} + } + catch + { + // ignored + } + } + + public void Dispose() + { + } + } + +} diff --git a/net452/SiteServer.Web/Home/assets/css/bootstrap-4.1.0.min.css b/net452/SiteServer.Web/Home/assets/css/bootstrap-4.1.0.min.css new file mode 100644 index 000000000..e490fd02e --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/css/bootstrap-4.1.0.min.css @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.1.0 (https://getbootstrap.com/) + * Copyright 2011-2018 The Bootstrap Authors + * Copyright 2011-2018 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.2;color:inherit}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014 \00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;max-width:100%;margin-bottom:1rem;background-color:transparent}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:not([size]):not([multiple]){height:calc(2.25rem + 2px)}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm,.input-group-lg>.form-control-plaintext.form-control,.input-group-lg>.input-group-append>.form-control-plaintext.btn,.input-group-lg>.input-group-append>.form-control-plaintext.input-group-text,.input-group-lg>.input-group-prepend>.form-control-plaintext.btn,.input-group-lg>.input-group-prepend>.form-control-plaintext.input-group-text,.input-group-sm>.form-control-plaintext.form-control,.input-group-sm>.input-group-append>.form-control-plaintext.btn,.input-group-sm>.input-group-append>.form-control-plaintext.input-group-text,.input-group-sm>.input-group-prepend>.form-control-plaintext.btn,.input-group-sm>.input-group-prepend>.form-control-plaintext.input-group-text{padding-right:0;padding-left:0}.form-control-sm,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-sm>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-sm>select.form-control:not([size]):not([multiple]),select.form-control-sm:not([size]):not([multiple]){height:calc(1.8125rem + 2px)}.form-control-lg,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-lg>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-lg>select.form-control:not([size]):not([multiple]),select.form-control-lg:not([size]):not([multiple]){height:calc(2.875rem + 2px)}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(40,167,69,.8);border-radius:.2rem}.custom-select.is-valid,.form-control.is-valid,.was-validated .custom-select:valid,.was-validated .form-control:valid{border-color:#28a745}.custom-select.is-valid:focus,.form-control.is-valid:focus,.was-validated .custom-select:valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{background-color:#71dd8a}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(40,167,69,.25)}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label::before,.was-validated .custom-file-input:valid~.custom-file-label::before{border-color:inherit}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(220,53,69,.8);border-radius:.2rem}.custom-select.is-invalid,.form-control.is-invalid,.was-validated .custom-select:invalid,.was-validated .form-control:invalid{border-color:#dc3545}.custom-select.is-invalid:focus,.form-control.is-invalid:focus,.was-validated .custom-select:invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{background-color:#efa2a9}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(220,53,69,.25)}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label::before,.was-validated .custom-file-input:invalid~.custom-file-label::before{border-color:inherit}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:focus,.btn:hover{text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}.btn:not(:disabled):not(.disabled).active,.btn:not(:disabled):not(.disabled):active{background-image:none}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-primary{color:#007bff;background-color:transparent;background-image:none;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;background-color:transparent;background-image:none;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;background-color:transparent;background-image:none;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;background-color:transparent;background-image:none;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;background-color:transparent;background-image:none;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;background-color:transparent;background-image:none;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;background-color:transparent;background-image:none;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;background-color:transparent;background-image:none;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;background-color:transparent}.btn-link:hover{color:#0056b3;text-decoration:underline;background-color:transparent;border-color:transparent}.btn-link.focus,.btn-link:focus{text-decoration:underline;border-color:transparent;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media screen and (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media screen and (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-right{right:0;left:auto}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;width:0;height:0;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:0 1 auto;flex:0 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical .btn,.btn-group-vertical .btn-group{width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file:focus,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control{margin-left:-1px}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label,.input-group>.custom-file:not(:first-child) .custom-file-label::after{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:active~.custom-control-label::before{color:#fff;background-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{margin-bottom:0}.custom-control-label::before{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;pointer-events:none;content:"";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#dee2e6}.custom-control-label::after{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;content:"";background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center;background-size:8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:inset 0 1px 2px rgba(0,0,0,.075),0 0 5px rgba(128,189,255,.5)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{opacity:0}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:125%}.custom-file{position:relative;display:inline-block;width:100%;height:calc(2.25rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(2.25rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:focus~.custom-file-label::after{border-color:#80bdff}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(2.25rem + 2px);padding:.375rem .75rem;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(calc(2.25rem + 2px) - 1px * 2);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:1px solid #ced4da;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;padding-left:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-appearance:none;appearance:none}.custom-range::-webkit-slider-thumb:focus{outline:0;box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-appearance:none;appearance:none}.custom-range::-moz-range-thumb:focus{outline:0;box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;appearance:none}.custom-range::-ms-thumb:focus{outline:0;box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler:not(:disabled):not(.disabled){cursor:pointer}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-ms-flexbox;display:flex;-ms-flex:1 0 0%;flex:1 0 0%;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-header,.card-group>.card:first-child .card-img-top{border-top-right-radius:0}.card-group>.card:first-child .card-footer,.card-group>.card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-header,.card-group>.card:last-child .card-img-top{border-top-left-radius:0}.card-group>.card:last-child .card-footer,.card-group>.card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:.25rem}.card-group>.card:only-child .card-header,.card-group>.card:only-child .card-img-top{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-group>.card:only-child .card-footer,.card-group>.card:only-child .card-img-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-group>.card:not(:first-child):not(:last-child):not(:only-child){border-radius:0}.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top{border-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion .card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion .card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion .card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion .card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-link:not(:disabled):not(.disabled){cursor:pointer}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}.badge-primary[href]:focus,.badge-primary[href]:hover{color:#fff;text-decoration:none;background-color:#0062cc}.badge-secondary{color:#fff;background-color:#6c757d}.badge-secondary[href]:focus,.badge-secondary[href]:hover{color:#fff;text-decoration:none;background-color:#545b62}.badge-success{color:#fff;background-color:#28a745}.badge-success[href]:focus,.badge-success[href]:hover{color:#fff;text-decoration:none;background-color:#1e7e34}.badge-info{color:#fff;background-color:#17a2b8}.badge-info[href]:focus,.badge-info[href]:hover{color:#fff;text-decoration:none;background-color:#117a8b}.badge-warning{color:#212529;background-color:#ffc107}.badge-warning[href]:focus,.badge-warning[href]:hover{color:#212529;text-decoration:none;background-color:#d39e00}.badge-danger{color:#fff;background-color:#dc3545}.badge-danger[href]:focus,.badge-danger[href]:hover{color:#fff;text-decoration:none;background-color:#bd2130}.badge-light{color:#212529;background-color:#f8f9fa}.badge-light[href]:focus,.badge-light[href]:hover{color:#212529;text-decoration:none;background-color:#dae0e5}.badge-dark{color:#fff;background-color:#343a40}.badge-dark[href]:focus,.badge-dark[href]:hover{color:#fff;text-decoration:none;background-color:#1d2124}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media screen and (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item:focus,.list-group-item:hover{z-index:1;text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:focus,.close:hover{color:#000;text-decoration:none;opacity:.75}.close:not(:disabled):not(.disabled){cursor:pointer}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-25%);transform:translate(0,-25%)}@media screen and (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:translate(0,0);transform:translate(0,0)}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - (.5rem * 2))}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem;border-bottom:1px solid #e9ecef;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #e9ecef}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-centered{min-height:calc(100% - (1.75rem * 2))}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg{max-width:800px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top] .arrow,.bs-popover-top .arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-top .arrow::before{border-width:.5rem .5rem 0}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{bottom:0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-top .arrow::after{bottom:1px;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right] .arrow,.bs-popover-right .arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-right .arrow::before{border-width:.5rem .5rem .5rem 0}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{left:0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-right .arrow::after{left:1px;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom] .arrow,.bs-popover-bottom .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-bottom .arrow::before{border-width:0 .5rem .5rem .5rem}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{top:0;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-bottom .arrow::after{top:1px;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left] .arrow,.bs-popover-left .arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-left .arrow::before{border-width:.5rem 0 .5rem .5rem}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{right:0;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-left .arrow::after{right:1px;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-item{position:relative;display:none;-ms-flex-align:center;align-items:center;width:100%;transition:-webkit-transform .6s ease;transition:transform .6s ease;transition:transform .6s ease,-webkit-transform .6s ease;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}@media screen and (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.carousel-item-next,.carousel-item-prev{position:absolute;top:0}.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.active.carousel-item-right,.carousel-item-next{-webkit-transform:translateX(100%);transform:translateX(100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-right,.carousel-item-next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translateX(-100%);transform:translateX(-100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.carousel-fade .carousel-item{opacity:0;transition-duration:.6s;transition-property:opacity}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{opacity:0}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev,.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev,.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{position:absolute;right:0;bottom:10px;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{position:relative;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;background-color:rgba(255,255,255,.5)}.carousel-indicators li::before{position:absolute;top:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators li::after{position:absolute;bottom:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-circle{border-radius:50%!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0062cc!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#545b62!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#1e7e34!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#117a8b!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#d39e00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#bd2130!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#dae0e5!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#1d2124!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/assets/css/font-awesome-4.7.0.min.css b/net452/SiteServer.Web/Home/assets/css/font-awesome-4.7.0.min.css new file mode 100644 index 000000000..540440ce8 --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/css/font-awesome-4.7.0.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/net452/SiteServer.Web/Home/assets/css/ionicons-2.0.0.min.css b/net452/SiteServer.Web/Home/assets/css/ionicons-2.0.0.min.css new file mode 100644 index 000000000..1c27b785f --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/css/ionicons-2.0.0.min.css @@ -0,0 +1 @@ +@charset "UTF-8";@font-face{font-family:Ionicons;src:url(../fonts/ionicons.eot?v=2.0.0);src:url(../fonts/ionicons.eot?v=2.0.0#iefix) format("embedded-opentype"),url(../fonts/ionicons.ttf?v=2.0.0) format("truetype"),url(../fonts/ionicons.woff?v=2.0.0) format("woff"),url(../fonts/ionicons.svg?v=2.0.0#Ionicons) format("svg");font-weight:400;font-style:normal}.ion,.ion-alert-circled:before,.ion-alert:before,.ion-android-add-circle:before,.ion-android-add:before,.ion-android-alarm-clock:before,.ion-android-alert:before,.ion-android-apps:before,.ion-android-archive:before,.ion-android-arrow-back:before,.ion-android-arrow-down:before,.ion-android-arrow-dropdown-circle:before,.ion-android-arrow-dropdown:before,.ion-android-arrow-dropleft-circle:before,.ion-android-arrow-dropleft:before,.ion-android-arrow-dropright-circle:before,.ion-android-arrow-dropright:before,.ion-android-arrow-dropup-circle:before,.ion-android-arrow-dropup:before,.ion-android-arrow-forward:before,.ion-android-arrow-up:before,.ion-android-attach:before,.ion-android-bar:before,.ion-android-bicycle:before,.ion-android-boat:before,.ion-android-bookmark:before,.ion-android-bulb:before,.ion-android-bus:before,.ion-android-calendar:before,.ion-android-call:before,.ion-android-camera:before,.ion-android-cancel:before,.ion-android-car:before,.ion-android-cart:before,.ion-android-chat:before,.ion-android-checkbox-blank:before,.ion-android-checkbox-outline-blank:before,.ion-android-checkbox-outline:before,.ion-android-checkbox:before,.ion-android-checkmark-circle:before,.ion-android-clipboard:before,.ion-android-close:before,.ion-android-cloud-circle:before,.ion-android-cloud-done:before,.ion-android-cloud-outline:before,.ion-android-cloud:before,.ion-android-color-palette:before,.ion-android-compass:before,.ion-android-contact:before,.ion-android-contacts:before,.ion-android-contract:before,.ion-android-create:before,.ion-android-delete:before,.ion-android-desktop:before,.ion-android-document:before,.ion-android-done-all:before,.ion-android-done:before,.ion-android-download:before,.ion-android-drafts:before,.ion-android-exit:before,.ion-android-expand:before,.ion-android-favorite-outline:before,.ion-android-favorite:before,.ion-android-film:before,.ion-android-folder-open:before,.ion-android-folder:before,.ion-android-funnel:before,.ion-android-globe:before,.ion-android-hand:before,.ion-android-hangout:before,.ion-android-happy:before,.ion-android-home:before,.ion-android-image:before,.ion-android-laptop:before,.ion-android-list:before,.ion-android-locate:before,.ion-android-lock:before,.ion-android-mail:before,.ion-android-map:before,.ion-android-menu:before,.ion-android-microphone-off:before,.ion-android-microphone:before,.ion-android-more-horizontal:before,.ion-android-more-vertical:before,.ion-android-navigate:before,.ion-android-notifications-none:before,.ion-android-notifications-off:before,.ion-android-notifications:before,.ion-android-open:before,.ion-android-options:before,.ion-android-people:before,.ion-android-person-add:before,.ion-android-person:before,.ion-android-phone-landscape:before,.ion-android-phone-portrait:before,.ion-android-pin:before,.ion-android-plane:before,.ion-android-playstore:before,.ion-android-print:before,.ion-android-radio-button-off:before,.ion-android-radio-button-on:before,.ion-android-refresh:before,.ion-android-remove-circle:before,.ion-android-remove:before,.ion-android-restaurant:before,.ion-android-sad:before,.ion-android-search:before,.ion-android-send:before,.ion-android-settings:before,.ion-android-share-alt:before,.ion-android-share:before,.ion-android-star-half:before,.ion-android-star-outline:before,.ion-android-star:before,.ion-android-stopwatch:before,.ion-android-subway:before,.ion-android-sunny:before,.ion-android-sync:before,.ion-android-textsms:before,.ion-android-time:before,.ion-android-train:before,.ion-android-unlock:before,.ion-android-upload:before,.ion-android-volume-down:before,.ion-android-volume-mute:before,.ion-android-volume-off:before,.ion-android-volume-up:before,.ion-android-walk:before,.ion-android-warning:before,.ion-android-watch:before,.ion-android-wifi:before,.ion-aperture:before,.ion-archive:before,.ion-arrow-down-a:before,.ion-arrow-down-b:before,.ion-arrow-down-c:before,.ion-arrow-expand:before,.ion-arrow-graph-down-left:before,.ion-arrow-graph-down-right:before,.ion-arrow-graph-up-left:before,.ion-arrow-graph-up-right:before,.ion-arrow-left-a:before,.ion-arrow-left-b:before,.ion-arrow-left-c:before,.ion-arrow-move:before,.ion-arrow-resize:before,.ion-arrow-return-left:before,.ion-arrow-return-right:before,.ion-arrow-right-a:before,.ion-arrow-right-b:before,.ion-arrow-right-c:before,.ion-arrow-shrink:before,.ion-arrow-swap:before,.ion-arrow-up-a:before,.ion-arrow-up-b:before,.ion-arrow-up-c:before,.ion-asterisk:before,.ion-at:before,.ion-backspace-outline:before,.ion-backspace:before,.ion-bag:before,.ion-battery-charging:before,.ion-battery-empty:before,.ion-battery-full:before,.ion-battery-half:before,.ion-battery-low:before,.ion-beaker:before,.ion-beer:before,.ion-bluetooth:before,.ion-bonfire:before,.ion-bookmark:before,.ion-bowtie:before,.ion-briefcase:before,.ion-bug:before,.ion-calculator:before,.ion-calendar:before,.ion-camera:before,.ion-card:before,.ion-cash:before,.ion-chatbox-working:before,.ion-chatbox:before,.ion-chatboxes:before,.ion-chatbubble-working:before,.ion-chatbubble:before,.ion-chatbubbles:before,.ion-checkmark-circled:before,.ion-checkmark-round:before,.ion-checkmark:before,.ion-chevron-down:before,.ion-chevron-left:before,.ion-chevron-right:before,.ion-chevron-up:before,.ion-clipboard:before,.ion-clock:before,.ion-close-circled:before,.ion-close-round:before,.ion-close:before,.ion-closed-captioning:before,.ion-cloud:before,.ion-code-download:before,.ion-code-working:before,.ion-code:before,.ion-coffee:before,.ion-compass:before,.ion-compose:before,.ion-connection-bars:before,.ion-contrast:before,.ion-crop:before,.ion-cube:before,.ion-disc:before,.ion-document-text:before,.ion-document:before,.ion-drag:before,.ion-earth:before,.ion-easel:before,.ion-edit:before,.ion-egg:before,.ion-eject:before,.ion-email-unread:before,.ion-email:before,.ion-erlenmeyer-flask-bubbles:before,.ion-erlenmeyer-flask:before,.ion-eye-disabled:before,.ion-eye:before,.ion-female:before,.ion-filing:before,.ion-film-marker:before,.ion-fireball:before,.ion-flag:before,.ion-flame:before,.ion-flash-off:before,.ion-flash:before,.ion-folder:before,.ion-fork-repo:before,.ion-fork:before,.ion-forward:before,.ion-funnel:before,.ion-gear-a:before,.ion-gear-b:before,.ion-grid:before,.ion-hammer:before,.ion-happy-outline:before,.ion-happy:before,.ion-headphone:before,.ion-heart-broken:before,.ion-heart:before,.ion-help-buoy:before,.ion-help-circled:before,.ion-help:before,.ion-home:before,.ion-icecream:before,.ion-image:before,.ion-images:before,.ion-information-circled:before,.ion-information:before,.ion-ionic:before,.ion-ios-alarm-outline:before,.ion-ios-alarm:before,.ion-ios-albums-outline:before,.ion-ios-albums:before,.ion-ios-americanfootball-outline:before,.ion-ios-americanfootball:before,.ion-ios-analytics-outline:before,.ion-ios-analytics:before,.ion-ios-arrow-back:before,.ion-ios-arrow-down:before,.ion-ios-arrow-forward:before,.ion-ios-arrow-left:before,.ion-ios-arrow-right:before,.ion-ios-arrow-thin-down:before,.ion-ios-arrow-thin-left:before,.ion-ios-arrow-thin-right:before,.ion-ios-arrow-thin-up:before,.ion-ios-arrow-up:before,.ion-ios-at-outline:before,.ion-ios-at:before,.ion-ios-barcode-outline:before,.ion-ios-barcode:before,.ion-ios-baseball-outline:before,.ion-ios-baseball:before,.ion-ios-basketball-outline:before,.ion-ios-basketball:before,.ion-ios-bell-outline:before,.ion-ios-bell:before,.ion-ios-body-outline:before,.ion-ios-body:before,.ion-ios-bolt-outline:before,.ion-ios-bolt:before,.ion-ios-book-outline:before,.ion-ios-book:before,.ion-ios-bookmarks-outline:before,.ion-ios-bookmarks:before,.ion-ios-box-outline:before,.ion-ios-box:before,.ion-ios-briefcase-outline:before,.ion-ios-briefcase:before,.ion-ios-browsers-outline:before,.ion-ios-browsers:before,.ion-ios-calculator-outline:before,.ion-ios-calculator:before,.ion-ios-calendar-outline:before,.ion-ios-calendar:before,.ion-ios-camera-outline:before,.ion-ios-camera:before,.ion-ios-cart-outline:before,.ion-ios-cart:before,.ion-ios-chatboxes-outline:before,.ion-ios-chatboxes:before,.ion-ios-chatbubble-outline:before,.ion-ios-chatbubble:before,.ion-ios-checkmark-empty:before,.ion-ios-checkmark-outline:before,.ion-ios-checkmark:before,.ion-ios-circle-filled:before,.ion-ios-circle-outline:before,.ion-ios-clock-outline:before,.ion-ios-clock:before,.ion-ios-close-empty:before,.ion-ios-close-outline:before,.ion-ios-close:before,.ion-ios-cloud-download-outline:before,.ion-ios-cloud-download:before,.ion-ios-cloud-outline:before,.ion-ios-cloud-upload-outline:before,.ion-ios-cloud-upload:before,.ion-ios-cloud:before,.ion-ios-cloudy-night-outline:before,.ion-ios-cloudy-night:before,.ion-ios-cloudy-outline:before,.ion-ios-cloudy:before,.ion-ios-cog-outline:before,.ion-ios-cog:before,.ion-ios-color-filter-outline:before,.ion-ios-color-filter:before,.ion-ios-color-wand-outline:before,.ion-ios-color-wand:before,.ion-ios-compose-outline:before,.ion-ios-compose:before,.ion-ios-contact-outline:before,.ion-ios-contact:before,.ion-ios-copy-outline:before,.ion-ios-copy:before,.ion-ios-crop-strong:before,.ion-ios-crop:before,.ion-ios-download-outline:before,.ion-ios-download:before,.ion-ios-drag:before,.ion-ios-email-outline:before,.ion-ios-email:before,.ion-ios-eye-outline:before,.ion-ios-eye:before,.ion-ios-fastforward-outline:before,.ion-ios-fastforward:before,.ion-ios-filing-outline:before,.ion-ios-filing:before,.ion-ios-film-outline:before,.ion-ios-film:before,.ion-ios-flag-outline:before,.ion-ios-flag:before,.ion-ios-flame-outline:before,.ion-ios-flame:before,.ion-ios-flask-outline:before,.ion-ios-flask:before,.ion-ios-flower-outline:before,.ion-ios-flower:before,.ion-ios-folder-outline:before,.ion-ios-folder:before,.ion-ios-football-outline:before,.ion-ios-football:before,.ion-ios-game-controller-a-outline:before,.ion-ios-game-controller-a:before,.ion-ios-game-controller-b-outline:before,.ion-ios-game-controller-b:before,.ion-ios-gear-outline:before,.ion-ios-gear:before,.ion-ios-glasses-outline:before,.ion-ios-glasses:before,.ion-ios-grid-view-outline:before,.ion-ios-grid-view:before,.ion-ios-heart-outline:before,.ion-ios-heart:before,.ion-ios-help-empty:before,.ion-ios-help-outline:before,.ion-ios-help:before,.ion-ios-home-outline:before,.ion-ios-home:before,.ion-ios-infinite-outline:before,.ion-ios-infinite:before,.ion-ios-information-empty:before,.ion-ios-information-outline:before,.ion-ios-information:before,.ion-ios-ionic-outline:before,.ion-ios-keypad-outline:before,.ion-ios-keypad:before,.ion-ios-lightbulb-outline:before,.ion-ios-lightbulb:before,.ion-ios-list-outline:before,.ion-ios-list:before,.ion-ios-location-outline:before,.ion-ios-location:before,.ion-ios-locked-outline:before,.ion-ios-locked:before,.ion-ios-loop-strong:before,.ion-ios-loop:before,.ion-ios-medical-outline:before,.ion-ios-medical:before,.ion-ios-medkit-outline:before,.ion-ios-medkit:before,.ion-ios-mic-off:before,.ion-ios-mic-outline:before,.ion-ios-mic:before,.ion-ios-minus-empty:before,.ion-ios-minus-outline:before,.ion-ios-minus:before,.ion-ios-monitor-outline:before,.ion-ios-monitor:before,.ion-ios-moon-outline:before,.ion-ios-moon:before,.ion-ios-more-outline:before,.ion-ios-more:before,.ion-ios-musical-note:before,.ion-ios-musical-notes:before,.ion-ios-navigate-outline:before,.ion-ios-navigate:before,.ion-ios-nutrition-outline:before,.ion-ios-nutrition:before,.ion-ios-paper-outline:before,.ion-ios-paper:before,.ion-ios-paperplane-outline:before,.ion-ios-paperplane:before,.ion-ios-partlysunny-outline:before,.ion-ios-partlysunny:before,.ion-ios-pause-outline:before,.ion-ios-pause:before,.ion-ios-paw-outline:before,.ion-ios-paw:before,.ion-ios-people-outline:before,.ion-ios-people:before,.ion-ios-person-outline:before,.ion-ios-person:before,.ion-ios-personadd-outline:before,.ion-ios-personadd:before,.ion-ios-photos-outline:before,.ion-ios-photos:before,.ion-ios-pie-outline:before,.ion-ios-pie:before,.ion-ios-pint-outline:before,.ion-ios-pint:before,.ion-ios-play-outline:before,.ion-ios-play:before,.ion-ios-plus-empty:before,.ion-ios-plus-outline:before,.ion-ios-plus:before,.ion-ios-pricetag-outline:before,.ion-ios-pricetag:before,.ion-ios-pricetags-outline:before,.ion-ios-pricetags:before,.ion-ios-printer-outline:before,.ion-ios-printer:before,.ion-ios-pulse-strong:before,.ion-ios-pulse:before,.ion-ios-rainy-outline:before,.ion-ios-rainy:before,.ion-ios-recording-outline:before,.ion-ios-recording:before,.ion-ios-redo-outline:before,.ion-ios-redo:before,.ion-ios-refresh-empty:before,.ion-ios-refresh-outline:before,.ion-ios-refresh:before,.ion-ios-reload:before,.ion-ios-reverse-camera-outline:before,.ion-ios-reverse-camera:before,.ion-ios-rewind-outline:before,.ion-ios-rewind:before,.ion-ios-rose-outline:before,.ion-ios-rose:before,.ion-ios-search-strong:before,.ion-ios-search:before,.ion-ios-settings-strong:before,.ion-ios-settings:before,.ion-ios-shuffle-strong:before,.ion-ios-shuffle:before,.ion-ios-skipbackward-outline:before,.ion-ios-skipbackward:before,.ion-ios-skipforward-outline:before,.ion-ios-skipforward:before,.ion-ios-snowy:before,.ion-ios-speedometer-outline:before,.ion-ios-speedometer:before,.ion-ios-star-half:before,.ion-ios-star-outline:before,.ion-ios-star:before,.ion-ios-stopwatch-outline:before,.ion-ios-stopwatch:before,.ion-ios-sunny-outline:before,.ion-ios-sunny:before,.ion-ios-telephone-outline:before,.ion-ios-telephone:before,.ion-ios-tennisball-outline:before,.ion-ios-tennisball:before,.ion-ios-thunderstorm-outline:before,.ion-ios-thunderstorm:before,.ion-ios-time-outline:before,.ion-ios-time:before,.ion-ios-timer-outline:before,.ion-ios-timer:before,.ion-ios-toggle-outline:before,.ion-ios-toggle:before,.ion-ios-trash-outline:before,.ion-ios-trash:before,.ion-ios-undo-outline:before,.ion-ios-undo:before,.ion-ios-unlocked-outline:before,.ion-ios-unlocked:before,.ion-ios-upload-outline:before,.ion-ios-upload:before,.ion-ios-videocam-outline:before,.ion-ios-videocam:before,.ion-ios-volume-high:before,.ion-ios-volume-low:before,.ion-ios-wineglass-outline:before,.ion-ios-wineglass:before,.ion-ios-world-outline:before,.ion-ios-world:before,.ion-ipad:before,.ion-iphone:before,.ion-ipod:before,.ion-jet:before,.ion-key:before,.ion-knife:before,.ion-laptop:before,.ion-leaf:before,.ion-levels:before,.ion-lightbulb:before,.ion-link:before,.ion-load-a:before,.ion-load-b:before,.ion-load-c:before,.ion-load-d:before,.ion-location:before,.ion-lock-combination:before,.ion-locked:before,.ion-log-in:before,.ion-log-out:before,.ion-loop:before,.ion-magnet:before,.ion-male:before,.ion-man:before,.ion-map:before,.ion-medkit:before,.ion-merge:before,.ion-mic-a:before,.ion-mic-b:before,.ion-mic-c:before,.ion-minus-circled:before,.ion-minus-round:before,.ion-minus:before,.ion-model-s:before,.ion-monitor:before,.ion-more:before,.ion-mouse:before,.ion-music-note:before,.ion-navicon-round:before,.ion-navicon:before,.ion-navigate:before,.ion-network:before,.ion-no-smoking:before,.ion-nuclear:before,.ion-outlet:before,.ion-paintbrush:before,.ion-paintbucket:before,.ion-paper-airplane:before,.ion-paperclip:before,.ion-pause:before,.ion-person-add:before,.ion-person-stalker:before,.ion-person:before,.ion-pie-graph:before,.ion-pin:before,.ion-pinpoint:before,.ion-pizza:before,.ion-plane:before,.ion-planet:before,.ion-play:before,.ion-playstation:before,.ion-plus-circled:before,.ion-plus-round:before,.ion-plus:before,.ion-podium:before,.ion-pound:before,.ion-power:before,.ion-pricetag:before,.ion-pricetags:before,.ion-printer:before,.ion-pull-request:before,.ion-qr-scanner:before,.ion-quote:before,.ion-radio-waves:before,.ion-record:before,.ion-refresh:before,.ion-reply-all:before,.ion-reply:before,.ion-ribbon-a:before,.ion-ribbon-b:before,.ion-sad-outline:before,.ion-sad:before,.ion-scissors:before,.ion-search:before,.ion-settings:before,.ion-share:before,.ion-shuffle:before,.ion-skip-backward:before,.ion-skip-forward:before,.ion-social-android-outline:before,.ion-social-android:before,.ion-social-angular-outline:before,.ion-social-angular:before,.ion-social-apple-outline:before,.ion-social-apple:before,.ion-social-bitcoin-outline:before,.ion-social-bitcoin:before,.ion-social-buffer-outline:before,.ion-social-buffer:before,.ion-social-chrome-outline:before,.ion-social-chrome:before,.ion-social-codepen-outline:before,.ion-social-codepen:before,.ion-social-css3-outline:before,.ion-social-css3:before,.ion-social-designernews-outline:before,.ion-social-designernews:before,.ion-social-dribbble-outline:before,.ion-social-dribbble:before,.ion-social-dropbox-outline:before,.ion-social-dropbox:before,.ion-social-euro-outline:before,.ion-social-euro:before,.ion-social-facebook-outline:before,.ion-social-facebook:before,.ion-social-foursquare-outline:before,.ion-social-foursquare:before,.ion-social-freebsd-devil:before,.ion-social-github-outline:before,.ion-social-github:before,.ion-social-google-outline:before,.ion-social-google:before,.ion-social-googleplus-outline:before,.ion-social-googleplus:before,.ion-social-hackernews-outline:before,.ion-social-hackernews:before,.ion-social-html5-outline:before,.ion-social-html5:before,.ion-social-instagram-outline:before,.ion-social-instagram:before,.ion-social-javascript-outline:before,.ion-social-javascript:before,.ion-social-linkedin-outline:before,.ion-social-linkedin:before,.ion-social-markdown:before,.ion-social-nodejs:before,.ion-social-octocat:before,.ion-social-pinterest-outline:before,.ion-social-pinterest:before,.ion-social-python:before,.ion-social-reddit-outline:before,.ion-social-reddit:before,.ion-social-rss-outline:before,.ion-social-rss:before,.ion-social-sass:before,.ion-social-skype-outline:before,.ion-social-skype:before,.ion-social-snapchat-outline:before,.ion-social-snapchat:before,.ion-social-tumblr-outline:before,.ion-social-tumblr:before,.ion-social-tux:before,.ion-social-twitch-outline:before,.ion-social-twitch:before,.ion-social-twitter-outline:before,.ion-social-twitter:before,.ion-social-usd-outline:before,.ion-social-usd:before,.ion-social-vimeo-outline:before,.ion-social-vimeo:before,.ion-social-whatsapp-outline:before,.ion-social-whatsapp:before,.ion-social-windows-outline:before,.ion-social-windows:before,.ion-social-wordpress-outline:before,.ion-social-wordpress:before,.ion-social-yahoo-outline:before,.ion-social-yahoo:before,.ion-social-yen-outline:before,.ion-social-yen:before,.ion-social-youtube-outline:before,.ion-social-youtube:before,.ion-soup-can-outline:before,.ion-soup-can:before,.ion-speakerphone:before,.ion-speedometer:before,.ion-spoon:before,.ion-star:before,.ion-stats-bars:before,.ion-steam:before,.ion-stop:before,.ion-thermometer:before,.ion-thumbsdown:before,.ion-thumbsup:before,.ion-toggle-filled:before,.ion-toggle:before,.ion-transgender:before,.ion-trash-a:before,.ion-trash-b:before,.ion-trophy:before,.ion-tshirt-outline:before,.ion-tshirt:before,.ion-umbrella:before,.ion-university:before,.ion-unlocked:before,.ion-upload:before,.ion-usb:before,.ion-videocamera:before,.ion-volume-high:before,.ion-volume-low:before,.ion-volume-medium:before,.ion-volume-mute:before,.ion-wand:before,.ion-waterdrop:before,.ion-wifi:before,.ion-wineglass:before,.ion-woman:before,.ion-wrench:before,.ion-xbox:before,.ionicons{display:inline-block;font-family:Ionicons;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;text-rendering:auto;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ion-alert:before{content:"\f101"}.ion-alert-circled:before{content:"\f100"}.ion-android-add:before{content:"\f2c7"}.ion-android-add-circle:before{content:"\f359"}.ion-android-alarm-clock:before{content:"\f35a"}.ion-android-alert:before{content:"\f35b"}.ion-android-apps:before{content:"\f35c"}.ion-android-archive:before{content:"\f2c9"}.ion-android-arrow-back:before{content:"\f2ca"}.ion-android-arrow-down:before{content:"\f35d"}.ion-android-arrow-dropdown:before{content:"\f35f"}.ion-android-arrow-dropdown-circle:before{content:"\f35e"}.ion-android-arrow-dropleft:before{content:"\f361"}.ion-android-arrow-dropleft-circle:before{content:"\f360"}.ion-android-arrow-dropright:before{content:"\f363"}.ion-android-arrow-dropright-circle:before{content:"\f362"}.ion-android-arrow-dropup:before{content:"\f365"}.ion-android-arrow-dropup-circle:before{content:"\f364"}.ion-android-arrow-forward:before{content:"\f30f"}.ion-android-arrow-up:before{content:"\f366"}.ion-android-attach:before{content:"\f367"}.ion-android-bar:before{content:"\f368"}.ion-android-bicycle:before{content:"\f369"}.ion-android-boat:before{content:"\f36a"}.ion-android-bookmark:before{content:"\f36b"}.ion-android-bulb:before{content:"\f36c"}.ion-android-bus:before{content:"\f36d"}.ion-android-calendar:before{content:"\f2d1"}.ion-android-call:before{content:"\f2d2"}.ion-android-camera:before{content:"\f2d3"}.ion-android-cancel:before{content:"\f36e"}.ion-android-car:before{content:"\f36f"}.ion-android-cart:before{content:"\f370"}.ion-android-chat:before{content:"\f2d4"}.ion-android-checkbox:before{content:"\f374"}.ion-android-checkbox-blank:before{content:"\f371"}.ion-android-checkbox-outline:before{content:"\f373"}.ion-android-checkbox-outline-blank:before{content:"\f372"}.ion-android-checkmark-circle:before{content:"\f375"}.ion-android-clipboard:before{content:"\f376"}.ion-android-close:before{content:"\f2d7"}.ion-android-cloud:before{content:"\f37a"}.ion-android-cloud-circle:before{content:"\f377"}.ion-android-cloud-done:before{content:"\f378"}.ion-android-cloud-outline:before{content:"\f379"}.ion-android-color-palette:before{content:"\f37b"}.ion-android-compass:before{content:"\f37c"}.ion-android-contact:before{content:"\f2d8"}.ion-android-contacts:before{content:"\f2d9"}.ion-android-contract:before{content:"\f37d"}.ion-android-create:before{content:"\f37e"}.ion-android-delete:before{content:"\f37f"}.ion-android-desktop:before{content:"\f380"}.ion-android-document:before{content:"\f381"}.ion-android-done:before{content:"\f383"}.ion-android-done-all:before{content:"\f382"}.ion-android-download:before{content:"\f2dd"}.ion-android-drafts:before{content:"\f384"}.ion-android-exit:before{content:"\f385"}.ion-android-expand:before{content:"\f386"}.ion-android-favorite:before{content:"\f388"}.ion-android-favorite-outline:before{content:"\f387"}.ion-android-film:before{content:"\f389"}.ion-android-folder:before{content:"\f2e0"}.ion-android-folder-open:before{content:"\f38a"}.ion-android-funnel:before{content:"\f38b"}.ion-android-globe:before{content:"\f38c"}.ion-android-hand:before{content:"\f2e3"}.ion-android-hangout:before{content:"\f38d"}.ion-android-happy:before{content:"\f38e"}.ion-android-home:before{content:"\f38f"}.ion-android-image:before{content:"\f2e4"}.ion-android-laptop:before{content:"\f390"}.ion-android-list:before{content:"\f391"}.ion-android-locate:before{content:"\f2e9"}.ion-android-lock:before{content:"\f392"}.ion-android-mail:before{content:"\f2eb"}.ion-android-map:before{content:"\f393"}.ion-android-menu:before{content:"\f394"}.ion-android-microphone:before{content:"\f2ec"}.ion-android-microphone-off:before{content:"\f395"}.ion-android-more-horizontal:before{content:"\f396"}.ion-android-more-vertical:before{content:"\f397"}.ion-android-navigate:before{content:"\f398"}.ion-android-notifications:before{content:"\f39b"}.ion-android-notifications-none:before{content:"\f399"}.ion-android-notifications-off:before{content:"\f39a"}.ion-android-open:before{content:"\f39c"}.ion-android-options:before{content:"\f39d"}.ion-android-people:before{content:"\f39e"}.ion-android-person:before{content:"\f3a0"}.ion-android-person-add:before{content:"\f39f"}.ion-android-phone-landscape:before{content:"\f3a1"}.ion-android-phone-portrait:before{content:"\f3a2"}.ion-android-pin:before{content:"\f3a3"}.ion-android-plane:before{content:"\f3a4"}.ion-android-playstore:before{content:"\f2f0"}.ion-android-print:before{content:"\f3a5"}.ion-android-radio-button-off:before{content:"\f3a6"}.ion-android-radio-button-on:before{content:"\f3a7"}.ion-android-refresh:before{content:"\f3a8"}.ion-android-remove:before{content:"\f2f4"}.ion-android-remove-circle:before{content:"\f3a9"}.ion-android-restaurant:before{content:"\f3aa"}.ion-android-sad:before{content:"\f3ab"}.ion-android-search:before{content:"\f2f5"}.ion-android-send:before{content:"\f2f6"}.ion-android-settings:before{content:"\f2f7"}.ion-android-share:before{content:"\f2f8"}.ion-android-share-alt:before{content:"\f3ac"}.ion-android-star:before{content:"\f2fc"}.ion-android-star-half:before{content:"\f3ad"}.ion-android-star-outline:before{content:"\f3ae"}.ion-android-stopwatch:before{content:"\f2fd"}.ion-android-subway:before{content:"\f3af"}.ion-android-sunny:before{content:"\f3b0"}.ion-android-sync:before{content:"\f3b1"}.ion-android-textsms:before{content:"\f3b2"}.ion-android-time:before{content:"\f3b3"}.ion-android-train:before{content:"\f3b4"}.ion-android-unlock:before{content:"\f3b5"}.ion-android-upload:before{content:"\f3b6"}.ion-android-volume-down:before{content:"\f3b7"}.ion-android-volume-mute:before{content:"\f3b8"}.ion-android-volume-off:before{content:"\f3b9"}.ion-android-volume-up:before{content:"\f3ba"}.ion-android-walk:before{content:"\f3bb"}.ion-android-warning:before{content:"\f3bc"}.ion-android-watch:before{content:"\f3bd"}.ion-android-wifi:before{content:"\f305"}.ion-aperture:before{content:"\f313"}.ion-archive:before{content:"\f102"}.ion-arrow-down-a:before{content:"\f103"}.ion-arrow-down-b:before{content:"\f104"}.ion-arrow-down-c:before{content:"\f105"}.ion-arrow-expand:before{content:"\f25e"}.ion-arrow-graph-down-left:before{content:"\f25f"}.ion-arrow-graph-down-right:before{content:"\f260"}.ion-arrow-graph-up-left:before{content:"\f261"}.ion-arrow-graph-up-right:before{content:"\f262"}.ion-arrow-left-a:before{content:"\f106"}.ion-arrow-left-b:before{content:"\f107"}.ion-arrow-left-c:before{content:"\f108"}.ion-arrow-move:before{content:"\f263"}.ion-arrow-resize:before{content:"\f264"}.ion-arrow-return-left:before{content:"\f265"}.ion-arrow-return-right:before{content:"\f266"}.ion-arrow-right-a:before{content:"\f109"}.ion-arrow-right-b:before{content:"\f10a"}.ion-arrow-right-c:before{content:"\f10b"}.ion-arrow-shrink:before{content:"\f267"}.ion-arrow-swap:before{content:"\f268"}.ion-arrow-up-a:before{content:"\f10c"}.ion-arrow-up-b:before{content:"\f10d"}.ion-arrow-up-c:before{content:"\f10e"}.ion-asterisk:before{content:"\f314"}.ion-at:before{content:"\f10f"}.ion-backspace:before{content:"\f3bf"}.ion-backspace-outline:before{content:"\f3be"}.ion-bag:before{content:"\f110"}.ion-battery-charging:before{content:"\f111"}.ion-battery-empty:before{content:"\f112"}.ion-battery-full:before{content:"\f113"}.ion-battery-half:before{content:"\f114"}.ion-battery-low:before{content:"\f115"}.ion-beaker:before{content:"\f269"}.ion-beer:before{content:"\f26a"}.ion-bluetooth:before{content:"\f116"}.ion-bonfire:before{content:"\f315"}.ion-bookmark:before{content:"\f26b"}.ion-bowtie:before{content:"\f3c0"}.ion-briefcase:before{content:"\f26c"}.ion-bug:before{content:"\f2be"}.ion-calculator:before{content:"\f26d"}.ion-calendar:before{content:"\f117"}.ion-camera:before{content:"\f118"}.ion-card:before{content:"\f119"}.ion-cash:before{content:"\f316"}.ion-chatbox:before{content:"\f11b"}.ion-chatbox-working:before{content:"\f11a"}.ion-chatboxes:before{content:"\f11c"}.ion-chatbubble:before{content:"\f11e"}.ion-chatbubble-working:before{content:"\f11d"}.ion-chatbubbles:before{content:"\f11f"}.ion-checkmark:before{content:"\f122"}.ion-checkmark-circled:before{content:"\f120"}.ion-checkmark-round:before{content:"\f121"}.ion-chevron-down:before{content:"\f123"}.ion-chevron-left:before{content:"\f124"}.ion-chevron-right:before{content:"\f125"}.ion-chevron-up:before{content:"\f126"}.ion-clipboard:before{content:"\f127"}.ion-clock:before{content:"\f26e"}.ion-close:before{content:"\f12a"}.ion-close-circled:before{content:"\f128"}.ion-close-round:before{content:"\f129"}.ion-closed-captioning:before{content:"\f317"}.ion-cloud:before{content:"\f12b"}.ion-code:before{content:"\f271"}.ion-code-download:before{content:"\f26f"}.ion-code-working:before{content:"\f270"}.ion-coffee:before{content:"\f272"}.ion-compass:before{content:"\f273"}.ion-compose:before{content:"\f12c"}.ion-connection-bars:before{content:"\f274"}.ion-contrast:before{content:"\f275"}.ion-crop:before{content:"\f3c1"}.ion-cube:before{content:"\f318"}.ion-disc:before{content:"\f12d"}.ion-document:before{content:"\f12f"}.ion-document-text:before{content:"\f12e"}.ion-drag:before{content:"\f130"}.ion-earth:before{content:"\f276"}.ion-easel:before{content:"\f3c2"}.ion-edit:before{content:"\f2bf"}.ion-egg:before{content:"\f277"}.ion-eject:before{content:"\f131"}.ion-email:before{content:"\f132"}.ion-email-unread:before{content:"\f3c3"}.ion-erlenmeyer-flask:before{content:"\f3c5"}.ion-erlenmeyer-flask-bubbles:before{content:"\f3c4"}.ion-eye:before{content:"\f133"}.ion-eye-disabled:before{content:"\f306"}.ion-female:before{content:"\f278"}.ion-filing:before{content:"\f134"}.ion-film-marker:before{content:"\f135"}.ion-fireball:before{content:"\f319"}.ion-flag:before{content:"\f279"}.ion-flame:before{content:"\f31a"}.ion-flash:before{content:"\f137"}.ion-flash-off:before{content:"\f136"}.ion-folder:before{content:"\f139"}.ion-fork:before{content:"\f27a"}.ion-fork-repo:before{content:"\f2c0"}.ion-forward:before{content:"\f13a"}.ion-funnel:before{content:"\f31b"}.ion-gear-a:before{content:"\f13d"}.ion-gear-b:before{content:"\f13e"}.ion-grid:before{content:"\f13f"}.ion-hammer:before{content:"\f27b"}.ion-happy:before{content:"\f31c"}.ion-happy-outline:before{content:"\f3c6"}.ion-headphone:before{content:"\f140"}.ion-heart:before{content:"\f141"}.ion-heart-broken:before{content:"\f31d"}.ion-help:before{content:"\f143"}.ion-help-buoy:before{content:"\f27c"}.ion-help-circled:before{content:"\f142"}.ion-home:before{content:"\f144"}.ion-icecream:before{content:"\f27d"}.ion-image:before{content:"\f147"}.ion-images:before{content:"\f148"}.ion-information:before{content:"\f14a"}.ion-information-circled:before{content:"\f149"}.ion-ionic:before{content:"\f14b"}.ion-ios-alarm:before{content:"\f3c8"}.ion-ios-alarm-outline:before{content:"\f3c7"}.ion-ios-albums:before{content:"\f3ca"}.ion-ios-albums-outline:before{content:"\f3c9"}.ion-ios-americanfootball:before{content:"\f3cc"}.ion-ios-americanfootball-outline:before{content:"\f3cb"}.ion-ios-analytics:before{content:"\f3ce"}.ion-ios-analytics-outline:before{content:"\f3cd"}.ion-ios-arrow-back:before{content:"\f3cf"}.ion-ios-arrow-down:before{content:"\f3d0"}.ion-ios-arrow-forward:before{content:"\f3d1"}.ion-ios-arrow-left:before{content:"\f3d2"}.ion-ios-arrow-right:before{content:"\f3d3"}.ion-ios-arrow-thin-down:before{content:"\f3d4"}.ion-ios-arrow-thin-left:before{content:"\f3d5"}.ion-ios-arrow-thin-right:before{content:"\f3d6"}.ion-ios-arrow-thin-up:before{content:"\f3d7"}.ion-ios-arrow-up:before{content:"\f3d8"}.ion-ios-at:before{content:"\f3da"}.ion-ios-at-outline:before{content:"\f3d9"}.ion-ios-barcode:before{content:"\f3dc"}.ion-ios-barcode-outline:before{content:"\f3db"}.ion-ios-baseball:before{content:"\f3de"}.ion-ios-baseball-outline:before{content:"\f3dd"}.ion-ios-basketball:before{content:"\f3e0"}.ion-ios-basketball-outline:before{content:"\f3df"}.ion-ios-bell:before{content:"\f3e2"}.ion-ios-bell-outline:before{content:"\f3e1"}.ion-ios-body:before{content:"\f3e4"}.ion-ios-body-outline:before{content:"\f3e3"}.ion-ios-bolt:before{content:"\f3e6"}.ion-ios-bolt-outline:before{content:"\f3e5"}.ion-ios-book:before{content:"\f3e8"}.ion-ios-book-outline:before{content:"\f3e7"}.ion-ios-bookmarks:before{content:"\f3ea"}.ion-ios-bookmarks-outline:before{content:"\f3e9"}.ion-ios-box:before{content:"\f3ec"}.ion-ios-box-outline:before{content:"\f3eb"}.ion-ios-briefcase:before{content:"\f3ee"}.ion-ios-briefcase-outline:before{content:"\f3ed"}.ion-ios-browsers:before{content:"\f3f0"}.ion-ios-browsers-outline:before{content:"\f3ef"}.ion-ios-calculator:before{content:"\f3f2"}.ion-ios-calculator-outline:before{content:"\f3f1"}.ion-ios-calendar:before{content:"\f3f4"}.ion-ios-calendar-outline:before{content:"\f3f3"}.ion-ios-camera:before{content:"\f3f6"}.ion-ios-camera-outline:before{content:"\f3f5"}.ion-ios-cart:before{content:"\f3f8"}.ion-ios-cart-outline:before{content:"\f3f7"}.ion-ios-chatboxes:before{content:"\f3fa"}.ion-ios-chatboxes-outline:before{content:"\f3f9"}.ion-ios-chatbubble:before{content:"\f3fc"}.ion-ios-chatbubble-outline:before{content:"\f3fb"}.ion-ios-checkmark:before{content:"\f3ff"}.ion-ios-checkmark-empty:before{content:"\f3fd"}.ion-ios-checkmark-outline:before{content:"\f3fe"}.ion-ios-circle-filled:before{content:"\f400"}.ion-ios-circle-outline:before{content:"\f401"}.ion-ios-clock:before{content:"\f403"}.ion-ios-clock-outline:before{content:"\f402"}.ion-ios-close:before{content:"\f406"}.ion-ios-close-empty:before{content:"\f404"}.ion-ios-close-outline:before{content:"\f405"}.ion-ios-cloud:before{content:"\f40c"}.ion-ios-cloud-download:before{content:"\f408"}.ion-ios-cloud-download-outline:before{content:"\f407"}.ion-ios-cloud-outline:before{content:"\f409"}.ion-ios-cloud-upload:before{content:"\f40b"}.ion-ios-cloud-upload-outline:before{content:"\f40a"}.ion-ios-cloudy:before{content:"\f410"}.ion-ios-cloudy-night:before{content:"\f40e"}.ion-ios-cloudy-night-outline:before{content:"\f40d"}.ion-ios-cloudy-outline:before{content:"\f40f"}.ion-ios-cog:before{content:"\f412"}.ion-ios-cog-outline:before{content:"\f411"}.ion-ios-color-filter:before{content:"\f414"}.ion-ios-color-filter-outline:before{content:"\f413"}.ion-ios-color-wand:before{content:"\f416"}.ion-ios-color-wand-outline:before{content:"\f415"}.ion-ios-compose:before{content:"\f418"}.ion-ios-compose-outline:before{content:"\f417"}.ion-ios-contact:before{content:"\f41a"}.ion-ios-contact-outline:before{content:"\f419"}.ion-ios-copy:before{content:"\f41c"}.ion-ios-copy-outline:before{content:"\f41b"}.ion-ios-crop:before{content:"\f41e"}.ion-ios-crop-strong:before{content:"\f41d"}.ion-ios-download:before{content:"\f420"}.ion-ios-download-outline:before{content:"\f41f"}.ion-ios-drag:before{content:"\f421"}.ion-ios-email:before{content:"\f423"}.ion-ios-email-outline:before{content:"\f422"}.ion-ios-eye:before{content:"\f425"}.ion-ios-eye-outline:before{content:"\f424"}.ion-ios-fastforward:before{content:"\f427"}.ion-ios-fastforward-outline:before{content:"\f426"}.ion-ios-filing:before{content:"\f429"}.ion-ios-filing-outline:before{content:"\f428"}.ion-ios-film:before{content:"\f42b"}.ion-ios-film-outline:before{content:"\f42a"}.ion-ios-flag:before{content:"\f42d"}.ion-ios-flag-outline:before{content:"\f42c"}.ion-ios-flame:before{content:"\f42f"}.ion-ios-flame-outline:before{content:"\f42e"}.ion-ios-flask:before{content:"\f431"}.ion-ios-flask-outline:before{content:"\f430"}.ion-ios-flower:before{content:"\f433"}.ion-ios-flower-outline:before{content:"\f432"}.ion-ios-folder:before{content:"\f435"}.ion-ios-folder-outline:before{content:"\f434"}.ion-ios-football:before{content:"\f437"}.ion-ios-football-outline:before{content:"\f436"}.ion-ios-game-controller-a:before{content:"\f439"}.ion-ios-game-controller-a-outline:before{content:"\f438"}.ion-ios-game-controller-b:before{content:"\f43b"}.ion-ios-game-controller-b-outline:before{content:"\f43a"}.ion-ios-gear:before{content:"\f43d"}.ion-ios-gear-outline:before{content:"\f43c"}.ion-ios-glasses:before{content:"\f43f"}.ion-ios-glasses-outline:before{content:"\f43e"}.ion-ios-grid-view:before{content:"\f441"}.ion-ios-grid-view-outline:before{content:"\f440"}.ion-ios-heart:before{content:"\f443"}.ion-ios-heart-outline:before{content:"\f442"}.ion-ios-help:before{content:"\f446"}.ion-ios-help-empty:before{content:"\f444"}.ion-ios-help-outline:before{content:"\f445"}.ion-ios-home:before{content:"\f448"}.ion-ios-home-outline:before{content:"\f447"}.ion-ios-infinite:before{content:"\f44a"}.ion-ios-infinite-outline:before{content:"\f449"}.ion-ios-information:before{content:"\f44d"}.ion-ios-information-empty:before{content:"\f44b"}.ion-ios-information-outline:before{content:"\f44c"}.ion-ios-ionic-outline:before{content:"\f44e"}.ion-ios-keypad:before{content:"\f450"}.ion-ios-keypad-outline:before{content:"\f44f"}.ion-ios-lightbulb:before{content:"\f452"}.ion-ios-lightbulb-outline:before{content:"\f451"}.ion-ios-list:before{content:"\f454"}.ion-ios-list-outline:before{content:"\f453"}.ion-ios-location:before{content:"\f456"}.ion-ios-location-outline:before{content:"\f455"}.ion-ios-locked:before{content:"\f458"}.ion-ios-locked-outline:before{content:"\f457"}.ion-ios-loop:before{content:"\f45a"}.ion-ios-loop-strong:before{content:"\f459"}.ion-ios-medical:before{content:"\f45c"}.ion-ios-medical-outline:before{content:"\f45b"}.ion-ios-medkit:before{content:"\f45e"}.ion-ios-medkit-outline:before{content:"\f45d"}.ion-ios-mic:before{content:"\f461"}.ion-ios-mic-off:before{content:"\f45f"}.ion-ios-mic-outline:before{content:"\f460"}.ion-ios-minus:before{content:"\f464"}.ion-ios-minus-empty:before{content:"\f462"}.ion-ios-minus-outline:before{content:"\f463"}.ion-ios-monitor:before{content:"\f466"}.ion-ios-monitor-outline:before{content:"\f465"}.ion-ios-moon:before{content:"\f468"}.ion-ios-moon-outline:before{content:"\f467"}.ion-ios-more:before{content:"\f46a"}.ion-ios-more-outline:before{content:"\f469"}.ion-ios-musical-note:before{content:"\f46b"}.ion-ios-musical-notes:before{content:"\f46c"}.ion-ios-navigate:before{content:"\f46e"}.ion-ios-navigate-outline:before{content:"\f46d"}.ion-ios-nutrition:before{content:"\f470"}.ion-ios-nutrition-outline:before{content:"\f46f"}.ion-ios-paper:before{content:"\f472"}.ion-ios-paper-outline:before{content:"\f471"}.ion-ios-paperplane:before{content:"\f474"}.ion-ios-paperplane-outline:before{content:"\f473"}.ion-ios-partlysunny:before{content:"\f476"}.ion-ios-partlysunny-outline:before{content:"\f475"}.ion-ios-pause:before{content:"\f478"}.ion-ios-pause-outline:before{content:"\f477"}.ion-ios-paw:before{content:"\f47a"}.ion-ios-paw-outline:before{content:"\f479"}.ion-ios-people:before{content:"\f47c"}.ion-ios-people-outline:before{content:"\f47b"}.ion-ios-person:before{content:"\f47e"}.ion-ios-person-outline:before{content:"\f47d"}.ion-ios-personadd:before{content:"\f480"}.ion-ios-personadd-outline:before{content:"\f47f"}.ion-ios-photos:before{content:"\f482"}.ion-ios-photos-outline:before{content:"\f481"}.ion-ios-pie:before{content:"\f484"}.ion-ios-pie-outline:before{content:"\f483"}.ion-ios-pint:before{content:"\f486"}.ion-ios-pint-outline:before{content:"\f485"}.ion-ios-play:before{content:"\f488"}.ion-ios-play-outline:before{content:"\f487"}.ion-ios-plus:before{content:"\f48b"}.ion-ios-plus-empty:before{content:"\f489"}.ion-ios-plus-outline:before{content:"\f48a"}.ion-ios-pricetag:before{content:"\f48d"}.ion-ios-pricetag-outline:before{content:"\f48c"}.ion-ios-pricetags:before{content:"\f48f"}.ion-ios-pricetags-outline:before{content:"\f48e"}.ion-ios-printer:before{content:"\f491"}.ion-ios-printer-outline:before{content:"\f490"}.ion-ios-pulse:before{content:"\f493"}.ion-ios-pulse-strong:before{content:"\f492"}.ion-ios-rainy:before{content:"\f495"}.ion-ios-rainy-outline:before{content:"\f494"}.ion-ios-recording:before{content:"\f497"}.ion-ios-recording-outline:before{content:"\f496"}.ion-ios-redo:before{content:"\f499"}.ion-ios-redo-outline:before{content:"\f498"}.ion-ios-refresh:before{content:"\f49c"}.ion-ios-refresh-empty:before{content:"\f49a"}.ion-ios-refresh-outline:before{content:"\f49b"}.ion-ios-reload:before{content:"\f49d"}.ion-ios-reverse-camera:before{content:"\f49f"}.ion-ios-reverse-camera-outline:before{content:"\f49e"}.ion-ios-rewind:before{content:"\f4a1"}.ion-ios-rewind-outline:before{content:"\f4a0"}.ion-ios-rose:before{content:"\f4a3"}.ion-ios-rose-outline:before{content:"\f4a2"}.ion-ios-search:before{content:"\f4a5"}.ion-ios-search-strong:before{content:"\f4a4"}.ion-ios-settings:before{content:"\f4a7"}.ion-ios-settings-strong:before{content:"\f4a6"}.ion-ios-shuffle:before{content:"\f4a9"}.ion-ios-shuffle-strong:before{content:"\f4a8"}.ion-ios-skipbackward:before{content:"\f4ab"}.ion-ios-skipbackward-outline:before{content:"\f4aa"}.ion-ios-skipforward:before{content:"\f4ad"}.ion-ios-skipforward-outline:before{content:"\f4ac"}.ion-ios-snowy:before{content:"\f4ae"}.ion-ios-speedometer:before{content:"\f4b0"}.ion-ios-speedometer-outline:before{content:"\f4af"}.ion-ios-star:before{content:"\f4b3"}.ion-ios-star-half:before{content:"\f4b1"}.ion-ios-star-outline:before{content:"\f4b2"}.ion-ios-stopwatch:before{content:"\f4b5"}.ion-ios-stopwatch-outline:before{content:"\f4b4"}.ion-ios-sunny:before{content:"\f4b7"}.ion-ios-sunny-outline:before{content:"\f4b6"}.ion-ios-telephone:before{content:"\f4b9"}.ion-ios-telephone-outline:before{content:"\f4b8"}.ion-ios-tennisball:before{content:"\f4bb"}.ion-ios-tennisball-outline:before{content:"\f4ba"}.ion-ios-thunderstorm:before{content:"\f4bd"}.ion-ios-thunderstorm-outline:before{content:"\f4bc"}.ion-ios-time:before{content:"\f4bf"}.ion-ios-time-outline:before{content:"\f4be"}.ion-ios-timer:before{content:"\f4c1"}.ion-ios-timer-outline:before{content:"\f4c0"}.ion-ios-toggle:before{content:"\f4c3"}.ion-ios-toggle-outline:before{content:"\f4c2"}.ion-ios-trash:before{content:"\f4c5"}.ion-ios-trash-outline:before{content:"\f4c4"}.ion-ios-undo:before{content:"\f4c7"}.ion-ios-undo-outline:before{content:"\f4c6"}.ion-ios-unlocked:before{content:"\f4c9"}.ion-ios-unlocked-outline:before{content:"\f4c8"}.ion-ios-upload:before{content:"\f4cb"}.ion-ios-upload-outline:before{content:"\f4ca"}.ion-ios-videocam:before{content:"\f4cd"}.ion-ios-videocam-outline:before{content:"\f4cc"}.ion-ios-volume-high:before{content:"\f4ce"}.ion-ios-volume-low:before{content:"\f4cf"}.ion-ios-wineglass:before{content:"\f4d1"}.ion-ios-wineglass-outline:before{content:"\f4d0"}.ion-ios-world:before{content:"\f4d3"}.ion-ios-world-outline:before{content:"\f4d2"}.ion-ipad:before{content:"\f1f9"}.ion-iphone:before{content:"\f1fa"}.ion-ipod:before{content:"\f1fb"}.ion-jet:before{content:"\f295"}.ion-key:before{content:"\f296"}.ion-knife:before{content:"\f297"}.ion-laptop:before{content:"\f1fc"}.ion-leaf:before{content:"\f1fd"}.ion-levels:before{content:"\f298"}.ion-lightbulb:before{content:"\f299"}.ion-link:before{content:"\f1fe"}.ion-load-a:before{content:"\f29a"}.ion-load-b:before{content:"\f29b"}.ion-load-c:before{content:"\f29c"}.ion-load-d:before{content:"\f29d"}.ion-location:before{content:"\f1ff"}.ion-lock-combination:before{content:"\f4d4"}.ion-locked:before{content:"\f200"}.ion-log-in:before{content:"\f29e"}.ion-log-out:before{content:"\f29f"}.ion-loop:before{content:"\f201"}.ion-magnet:before{content:"\f2a0"}.ion-male:before{content:"\f2a1"}.ion-man:before{content:"\f202"}.ion-map:before{content:"\f203"}.ion-medkit:before{content:"\f2a2"}.ion-merge:before{content:"\f33f"}.ion-mic-a:before{content:"\f204"}.ion-mic-b:before{content:"\f205"}.ion-mic-c:before{content:"\f206"}.ion-minus:before{content:"\f209"}.ion-minus-circled:before{content:"\f207"}.ion-minus-round:before{content:"\f208"}.ion-model-s:before{content:"\f2c1"}.ion-monitor:before{content:"\f20a"}.ion-more:before{content:"\f20b"}.ion-mouse:before{content:"\f340"}.ion-music-note:before{content:"\f20c"}.ion-navicon:before{content:"\f20e"}.ion-navicon-round:before{content:"\f20d"}.ion-navigate:before{content:"\f2a3"}.ion-network:before{content:"\f341"}.ion-no-smoking:before{content:"\f2c2"}.ion-nuclear:before{content:"\f2a4"}.ion-outlet:before{content:"\f342"}.ion-paintbrush:before{content:"\f4d5"}.ion-paintbucket:before{content:"\f4d6"}.ion-paper-airplane:before{content:"\f2c3"}.ion-paperclip:before{content:"\f20f"}.ion-pause:before{content:"\f210"}.ion-person:before{content:"\f213"}.ion-person-add:before{content:"\f211"}.ion-person-stalker:before{content:"\f212"}.ion-pie-graph:before{content:"\f2a5"}.ion-pin:before{content:"\f2a6"}.ion-pinpoint:before{content:"\f2a7"}.ion-pizza:before{content:"\f2a8"}.ion-plane:before{content:"\f214"}.ion-planet:before{content:"\f343"}.ion-play:before{content:"\f215"}.ion-playstation:before{content:"\f30a"}.ion-plus:before{content:"\f218"}.ion-plus-circled:before{content:"\f216"}.ion-plus-round:before{content:"\f217"}.ion-podium:before{content:"\f344"}.ion-pound:before{content:"\f219"}.ion-power:before{content:"\f2a9"}.ion-pricetag:before{content:"\f2aa"}.ion-pricetags:before{content:"\f2ab"}.ion-printer:before{content:"\f21a"}.ion-pull-request:before{content:"\f345"}.ion-qr-scanner:before{content:"\f346"}.ion-quote:before{content:"\f347"}.ion-radio-waves:before{content:"\f2ac"}.ion-record:before{content:"\f21b"}.ion-refresh:before{content:"\f21c"}.ion-reply:before{content:"\f21e"}.ion-reply-all:before{content:"\f21d"}.ion-ribbon-a:before{content:"\f348"}.ion-ribbon-b:before{content:"\f349"}.ion-sad:before{content:"\f34a"}.ion-sad-outline:before{content:"\f4d7"}.ion-scissors:before{content:"\f34b"}.ion-search:before{content:"\f21f"}.ion-settings:before{content:"\f2ad"}.ion-share:before{content:"\f220"}.ion-shuffle:before{content:"\f221"}.ion-skip-backward:before{content:"\f222"}.ion-skip-forward:before{content:"\f223"}.ion-social-android:before{content:"\f225"}.ion-social-android-outline:before{content:"\f224"}.ion-social-angular:before{content:"\f4d9"}.ion-social-angular-outline:before{content:"\f4d8"}.ion-social-apple:before{content:"\f227"}.ion-social-apple-outline:before{content:"\f226"}.ion-social-bitcoin:before{content:"\f2af"}.ion-social-bitcoin-outline:before{content:"\f2ae"}.ion-social-buffer:before{content:"\f229"}.ion-social-buffer-outline:before{content:"\f228"}.ion-social-chrome:before{content:"\f4db"}.ion-social-chrome-outline:before{content:"\f4da"}.ion-social-codepen:before{content:"\f4dd"}.ion-social-codepen-outline:before{content:"\f4dc"}.ion-social-css3:before{content:"\f4df"}.ion-social-css3-outline:before{content:"\f4de"}.ion-social-designernews:before{content:"\f22b"}.ion-social-designernews-outline:before{content:"\f22a"}.ion-social-dribbble:before{content:"\f22d"}.ion-social-dribbble-outline:before{content:"\f22c"}.ion-social-dropbox:before{content:"\f22f"}.ion-social-dropbox-outline:before{content:"\f22e"}.ion-social-euro:before{content:"\f4e1"}.ion-social-euro-outline:before{content:"\f4e0"}.ion-social-facebook:before{content:"\f231"}.ion-social-facebook-outline:before{content:"\f230"}.ion-social-foursquare:before{content:"\f34d"}.ion-social-foursquare-outline:before{content:"\f34c"}.ion-social-freebsd-devil:before{content:"\f2c4"}.ion-social-github:before{content:"\f233"}.ion-social-github-outline:before{content:"\f232"}.ion-social-google:before{content:"\f34f"}.ion-social-google-outline:before{content:"\f34e"}.ion-social-googleplus:before{content:"\f235"}.ion-social-googleplus-outline:before{content:"\f234"}.ion-social-hackernews:before{content:"\f237"}.ion-social-hackernews-outline:before{content:"\f236"}.ion-social-html5:before{content:"\f4e3"}.ion-social-html5-outline:before{content:"\f4e2"}.ion-social-instagram:before{content:"\f351"}.ion-social-instagram-outline:before{content:"\f350"}.ion-social-javascript:before{content:"\f4e5"}.ion-social-javascript-outline:before{content:"\f4e4"}.ion-social-linkedin:before{content:"\f239"}.ion-social-linkedin-outline:before{content:"\f238"}.ion-social-markdown:before{content:"\f4e6"}.ion-social-nodejs:before{content:"\f4e7"}.ion-social-octocat:before{content:"\f4e8"}.ion-social-pinterest:before{content:"\f2b1"}.ion-social-pinterest-outline:before{content:"\f2b0"}.ion-social-python:before{content:"\f4e9"}.ion-social-reddit:before{content:"\f23b"}.ion-social-reddit-outline:before{content:"\f23a"}.ion-social-rss:before{content:"\f23d"}.ion-social-rss-outline:before{content:"\f23c"}.ion-social-sass:before{content:"\f4ea"}.ion-social-skype:before{content:"\f23f"}.ion-social-skype-outline:before{content:"\f23e"}.ion-social-snapchat:before{content:"\f4ec"}.ion-social-snapchat-outline:before{content:"\f4eb"}.ion-social-tumblr:before{content:"\f241"}.ion-social-tumblr-outline:before{content:"\f240"}.ion-social-tux:before{content:"\f2c5"}.ion-social-twitch:before{content:"\f4ee"}.ion-social-twitch-outline:before{content:"\f4ed"}.ion-social-twitter:before{content:"\f243"}.ion-social-twitter-outline:before{content:"\f242"}.ion-social-usd:before{content:"\f353"}.ion-social-usd-outline:before{content:"\f352"}.ion-social-vimeo:before{content:"\f245"}.ion-social-vimeo-outline:before{content:"\f244"}.ion-social-whatsapp:before{content:"\f4f0"}.ion-social-whatsapp-outline:before{content:"\f4ef"}.ion-social-windows:before{content:"\f247"}.ion-social-windows-outline:before{content:"\f246"}.ion-social-wordpress:before{content:"\f249"}.ion-social-wordpress-outline:before{content:"\f248"}.ion-social-yahoo:before{content:"\f24b"}.ion-social-yahoo-outline:before{content:"\f24a"}.ion-social-yen:before{content:"\f4f2"}.ion-social-yen-outline:before{content:"\f4f1"}.ion-social-youtube:before{content:"\f24d"}.ion-social-youtube-outline:before{content:"\f24c"}.ion-soup-can:before{content:"\f4f4"}.ion-soup-can-outline:before{content:"\f4f3"}.ion-speakerphone:before{content:"\f2b2"}.ion-speedometer:before{content:"\f2b3"}.ion-spoon:before{content:"\f2b4"}.ion-star:before{content:"\f24e"}.ion-stats-bars:before{content:"\f2b5"}.ion-steam:before{content:"\f30b"}.ion-stop:before{content:"\f24f"}.ion-thermometer:before{content:"\f2b6"}.ion-thumbsdown:before{content:"\f250"}.ion-thumbsup:before{content:"\f251"}.ion-toggle:before{content:"\f355"}.ion-toggle-filled:before{content:"\f354"}.ion-transgender:before{content:"\f4f5"}.ion-trash-a:before{content:"\f252"}.ion-trash-b:before{content:"\f253"}.ion-trophy:before{content:"\f356"}.ion-tshirt:before{content:"\f4f7"}.ion-tshirt-outline:before{content:"\f4f6"}.ion-umbrella:before{content:"\f2b7"}.ion-university:before{content:"\f357"}.ion-unlocked:before{content:"\f254"}.ion-upload:before{content:"\f255"}.ion-usb:before{content:"\f2b8"}.ion-videocamera:before{content:"\f256"}.ion-volume-high:before{content:"\f257"}.ion-volume-low:before{content:"\f258"}.ion-volume-medium:before{content:"\f259"}.ion-volume-mute:before{content:"\f25a"}.ion-wand:before{content:"\f358"}.ion-waterdrop:before{content:"\f25b"}.ion-wifi:before{content:"\f25c"}.ion-wineglass:before{content:"\f2b9"}.ion-woman:before{content:"\f25d"}.ion-wrench:before{content:"\f2ba"}.ion-xbox:before{content:"\f30c"} \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/assets/css/siteserver.min.css b/net452/SiteServer.Web/Home/assets/css/siteserver.min.css new file mode 100644 index 000000000..989ab5a70 --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/css/siteserver.min.css @@ -0,0 +1,12 @@ +/*! + * SiteServer UI v1.0.7 (https://www.siteserver.cn) + * Copyright 2013-2018 SiteServer CMS. + * Licensed under GPL-3.0 (https://github.com/siteserver/siteserver-ui/blob/master/LICENSE) + */@charset "UTF-8";.gal-detail h4,.icon-list-demo div,.notification-list .notify-item .notify-details,.user-list .user-list-item .user-desc span.desc,.user-list .user-list-item .user-desc span.name,.widget-user .wid-u-info p{white-space:nowrap;text-overflow:ellipsis}.wrapper{padding-top:120px}.page-title-box{padding:22px 0}.page-title-box .page-title{font-size:20px;margin-bottom:0;margin-top:0;font-weight:600}#topnav{position:fixed;right:0;left:0;top:0;z-index:1030;background-color:transparent;border:0;-webkit-transition:all .5s ease;transition:all .5s ease;min-height:62px}#topnav .has-submenu.active .submenu li.active>a,#topnav .has-submenu.active a,#topnav .has-submenu.active a i{color:#00b19d}#topnav .topbar-main{background-color:#00b19d}#topnav .topbar-main .logo{color:#fff!important;font-size:20px;font-weight:700;letter-spacing:1px;line-height:58px;text-transform:uppercase;float:left}#topnav .topbar-main .logo-small{display:none}#topnav .topbar-main .badge-topbar{position:absolute;top:7px;right:7px;z-index:99}#topnav .topbar-main .nav>li>a{height:36px;width:36px;padding:0;font-size:24px;line-height:35px;text-align:center;border-radius:50%;margin:12px 8px;color:rgba(42,49,66,.7)}#topnav .topbar-main .dropdown-menu-lg .list-group,#topnav .topbar-main .dropdown-menu-lg .media-heading{margin-bottom:0}#topnav .topbar-main .nav>li>a:focus,#topnav .topbar-main .nav>li>a:hover{background-color:rgba(42,49,66,.1);color:#2a3142}#topnav .topbar-main .navbar-nav>.open>a{background-color:rgba(42,49,66,.1)!important}#topnav .topbar-main .profile img{height:34px;width:34px;display:block}#topnav .topbar-main .dropdown-menu-lg .list-group-item{border:none;padding:10px 20px}#topnav .topbar-main .dropdown-menu-lg .media-body p{color:#828282}#topnav .topbar-main .navbar-nav{margin:0}#topnav .app-search{position:relative;margin-top:14px}#topnav .app-search a{position:absolute;top:7px;right:26px;color:rgba(42,49,66,.7)}#topnav .app-search a:hover{color:rgba(42,49,66,.9)}#topnav .app-search .form-control,#topnav .app-search .form-control:focus{border-color:transparent;height:34px;color:#2a3142;border-radius:30px;padding:7px 40px 7px 20px;margin:0 12px 0 5px;background:rgba(42,49,66,.1);box-shadow:none;width:190px}#topnav .app-search input::-webkit-input-placeholder{color:rgba(42,49,66,.8)}#topnav .app-search input:-moz-placeholder{color:rgba(42,49,66,.8)}#topnav .app-search input::-moz-placeholder{color:rgba(42,49,66,.8)}#topnav .app-search input:-ms-input-placeholder{color:rgba(42,49,66,.8)}#topnav .navbar-custom{background-color:#fff;box-shadow:0 1px 1px rgba(0,0,0,.1)}#topnav .navbar-toggle{border:0;position:relative;padding:0;margin:0;cursor:pointer}#topnav .navbar-toggle:hover{background-color:transparent}#topnav .navbar-toggle:hover span{background-color:#fff}#topnav .navbar-toggle:focus{background-color:transparent}#topnav .navbar-toggle:focus span{background-color:#fff}#topnav .navbar-toggle .lines{width:25px;display:block;position:relative;margin:0 10px 0 0;padding-top:13px;height:23px;-webkit-transition:all .5s ease;transition:all .5s ease}#topnav .navbar-toggle span{height:2px;width:100%;background-color:rgba(255,255,255,.8);display:block;margin-bottom:5px;-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease}#topnav .navbar-toggle.open span{position:absolute}#topnav .navbar-toggle.open span:first-child{top:18px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}#topnav .navbar-toggle.open span:nth-child(2){visibility:hidden}#topnav .navbar-toggle.open span:last-child{width:100%;top:18px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}#topnav .navigation-menu{list-style:none;margin:0;padding:0}#topnav .navigation-menu>li{display:inline-block;position:relative}#topnav .navigation-menu>li>a{display:block;color:rgba(42,49,66,.7);font-weight:500;font-size:15px;-webkit-transition:all .5s ease;transition:all .5s ease;line-height:20px;padding-left:25px;padding-right:25px}#topnav .navigation-menu>li>a:active,#topnav .navigation-menu>li>a:focus,#topnav .navigation-menu>li>a:hover{color:#2a3142}#topnav .navigation-menu>li>a i{font-size:16px;margin-right:5px;-webkit-transition:all .5s ease;transition:all .5s ease}#topnav .navigation-menu>li>a:focus,#topnav .navigation-menu>li>a:hover{background-color:transparent}@media (min-width:992px){#topnav .navigation-menu>li>a{padding-top:20px;padding-bottom:20px}#topnav .navigation-menu>li:first-of-type>a{padding-left:0}#topnav .navigation-menu>li.last-elements .submenu{left:auto;right:0}#topnav .navigation-menu>li.last-elements .submenu>li.has-submenu .submenu{left:auto;right:100%;margin-left:0;margin-right:10px}#topnav .navigation-menu>li:hover a,#topnav .navigation-menu>li:hover a i,#topnav .navigation-menu>li>ul>li.has-submenu:active>a,#topnav .navigation-menu>li>ul>li.has-submenu:hover>a{color:#00b19d}#topnav .navigation-menu>li .submenu{position:absolute;top:100%;left:0;z-index:1000;border:1px solid #e7e7e7;padding:15px 0;list-style:none;min-width:200px;text-align:left;visibility:hidden;opacity:0;margin-top:10px;-webkit-transition:all .2s ease;transition:all .2s ease;background-color:#fff;box-shadow:0 2px 6px rgba(0,0,0,.05)}#topnav .navigation-menu>li .submenu.megamenu{white-space:nowrap;width:auto}#topnav .navigation-menu>li .submenu.megamenu>li{overflow:hidden;width:200px;display:inline-block;vertical-align:top}#topnav .navigation-menu>li .submenu>li.has-submenu>a:after{content:"\e649";font-family:themify;position:absolute;right:20px;top:13px;font-size:10px}#topnav .navigation-menu>li .submenu>li .submenu{left:100%;top:0;margin-left:10px;margin-top:-1px}#topnav .navigation-menu>li .submenu li{position:relative}#topnav .navigation-menu>li .submenu li ul{list-style:none;padding-left:0;margin:0}#topnav .navigation-menu>li .submenu li a{display:block;padding:8px 25px;clear:both;white-space:nowrap;font-size:15px;color:#2a3142;-webkit-transition:all .35s ease;transition:all .35s ease}#topnav .navigation-menu>li .submenu li a:hover{color:#00b19d}#topnav .navigation-menu>li .submenu li span{display:block;padding:8px 25px;clear:both;line-height:1.42857143;white-space:nowrap;font-size:10px;text-transform:uppercase;letter-spacing:2px;font-weight:500;color:#2a3142}#topnav .navbar-toggle{display:none}#topnav #navigation{display:block!important}}@media (max-width:991px){.wrapper{padding-top:60px}.container{width:auto!important}#topnav .navigation-menu{float:none;max-height:400px;text-align:left}#topnav .navigation-menu>li{display:block}#topnav .navigation-menu>li>a{color:#2a3142;padding:15px}#topnav .navigation-menu>li>a i{display:inline-block;margin-right:10px;margin-bottom:0;vertical-align:inherit}#topnav .navigation-menu>li>a:after{position:absolute;right:15px}#topnav .navigation-menu>li .submenu{display:none;list-style:none;padding-left:20px;margin:0}#topnav .navigation-menu>li .submenu li a{display:block;position:relative;padding:7px 20px;color:#2a3142}#topnav .navigation-menu>li .submenu li a:hover{color:#00b19d}#topnav .navigation-menu>li .submenu li.has-submenu>a:after{content:"\e64b";font-family:themify;position:absolute;right:30px;font-size:10px}#topnav .navigation-menu>li .submenu.open{display:block}#topnav .navigation-menu>li .submenu .submenu{display:none;list-style:none}#topnav .navigation-menu>li .submenu .submenu.open{display:block}#topnav .navigation-menu>li .submenu.megamenu>li>ul{list-style:none;padding-left:0}#topnav .navigation-menu>li .submenu.megamenu>li>ul>li>span{display:block;position:relative;padding:15px;text-transform:uppercase;font-size:11px;letter-spacing:2px;color:#2a3142}#topnav .has-submenu.active a,#topnav .has-submenu.active a i,#topnav .has-submenu.active a:active,#topnav .has-submenu.active a:focus,#topnav .navigation-menu>li.has-submenu.open>a{color:#00b19d}#topnav .navbar-header{float:left}#navigation{position:absolute;top:60px;left:0;width:100%;display:none;height:auto;padding-bottom:0;overflow:auto;border-top:1px solid #e7e7e7;border-bottom:1px solid #e7e7e7;background-color:#fff}#navigation.open{display:block;overflow-y:auto}}.profile-dropdown i,.profile-dropdown span,.waves-effect{vertical-align:middle}@media (min-width:768px){#topnav .navigation-menu>li.has-submenu:hover>.submenu{visibility:visible;opacity:1;margin-top:0}#topnav .navigation-menu>li.has-submenu:hover>.submenu>li.has-submenu:hover>.submenu{visibility:visible;opacity:1;margin-left:0;margin-right:0}.navbar-toggle{display:block}}.topbar-custom{border-radius:0;margin-bottom:0}.topbar-custom .nav-link{padding:0;line-height:60px;color:rgba(255,255,255,.6)}.topbar-custom .dropdown-toggle:after{content:initial}.topbar-custom .menu-left{overflow:hidden}.footer{border-top:1px solid rgba(0,0,0,.1);text-align:left!important}.footer ul li{padding-left:10px;padding-right:10px}.footer ul li a{color:#98a6ad}.footer ul li a:hover{color:#00b19d}.user-list .user-list-item{padding:10px 12px!important;border-bottom:1px solid #EEE!important}.user-list .user-list-item .avatar{float:left;margin-right:5px;width:30px;height:30px}.user-list .user-list-item .avatar img{border-radius:50%;width:100%}.user-list .user-list-item .icon{float:left;margin-right:5px;height:30px;width:30px;border-radius:50%;text-align:center}.user-list .user-list-item .icon i{color:#fff;line-height:30px;font-size:16px}.user-list .user-list-item .user-desc{margin-left:40px}.user-list .user-list-item .user-desc span.name{color:#2a3142;display:block;width:100%;overflow:hidden;font-size:13px}.user-list .user-list-item .user-desc span.desc{color:#98a6ad;display:block;width:100%;overflow:hidden;font-size:12px}.user-list .user-list-item .user-desc span.time{font-size:11px}.notification-list{margin-left:0!important}.notification-list .noti-title{border-radius:.25rem .25rem 0 0;margin:-6px 0 0;background-color:#fff;width:auto;padding:12px 20px}.notification-list .noti-title h5{margin:0}.notification-list .noti-title h5 small{color:#2a3142!important}.notification-list .noti-title .label{float:right}.notification-list .noti-icon{font-size:22px;padding:0 12px;vertical-align:middle;color:rgba(255,255,255,.8)}.notification-list .noti-icon-badge{display:inline-block;position:absolute;top:14px;right:8px}.notification-list .notify-item{padding:10px 20px}.notification-list .notify-item .notify-icon{float:left;height:36px;width:36px;line-height:36px;text-align:center;margin-right:10px;border-radius:50%;color:#fff}.notification-list .notify-item .notify-icon img{margin-top:4px}.notification-list .notify-item .notify-details{margin-bottom:0;overflow:hidden;margin-left:45px}.notification-list .notify-item .notify-details b{font-weight:500}.notification-list .notify-item .notify-details small{display:block}.notification-list .notify-item .notify-details span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px}.notification-list .notify-all{border-radius:0 0 .25rem .25rem;margin:0 0 -5px;background-color:#eee}body,html{background:#f5f5f5}.notification-list .profile-dropdown .notify-item{padding:4px 20px}.profile-dropdown{width:170px}.profile-dropdown i{font-size:17px;margin-right:5px}.nav-user{padding:0 12px!important}.nav-user img{height:36px;width:36px}body{margin:0;color:#4c5667;overflow-x:hidden!important;font-size:.95rem;font-family:"Microsoft YaHei","微软雅黑",Arial,"黑体","宋体",sans-serif;padding-bottom:65px}html{overflow-x:hidden;position:relative;min-height:100%}*{outline:0!important}a:active,a:focus,a:hover{outline:0;text-decoration:none}.container-alt{margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px}.footer{background-color:#f9f9f9;bottom:0;color:#2a3142;padding:20px 30px;position:absolute;right:0;left:0}#wrapper{height:100%;overflow:hidden;width:100%}.page{bottom:0;left:0;right:0;top:0}.card-box{padding:20px;border:1px solid rgba(54,64,74,.08);-webkit-border-radius:5px;border-radius:5px;-moz-border-radius:5px;background-clip:padding-box;margin-bottom:20px;background-color:#fff}.header-title{letter-spacing:.02em;text-transform:uppercase;font-size:15px;font-weight:700;line-height:16px;margin-bottom:8px;margin-top:0}.social-links li a{-webkit-border-radius:50%;background:#EFF0F4;border-radius:50%;color:#7A7676;display:inline-block;height:30px;line-height:30px;text-align:center;width:30px}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}.container-fluid{max-width:95%}.row{margin-right:-10px;margin-left:-10px}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{padding-left:10px;padding-right:10px}.breadcrumb{background-color:transparent;margin-bottom:15px;margin-top:5px}.dropdown-menu{padding:4px 0;border:0;box-shadow:0 2px 5px 0 rgba(0,0,0,.26)}.dropdown-menu>li>a{padding:6px 20px}.dropdown-item.active,.dropdown-item:active{background-color:#f2f2f2;color:inherit}.dropdown-menu-lg{max-width:280px}code{color:#5d9cec;border-radius:4px}code,pre{background-color:#f4f8fb}.bg-empty{background:0 0!important}.bg-primary{background-color:#00b19d!important}.bg-success{background-color:#3bafda!important}.bg-info{background-color:#3ddcf7!important}.bg-warning{background-color:#fa0!important}.bg-danger{background-color:#ef5350!important}.bg-muted{background-color:#F5F5F5!important}.bg-inverse{background-color:#4c5667!important}.bg-purple{background-color:#7266ba!important}.bg-pink{background-color:#f76397!important}.bg-white{background-color:#fff!important}.text-white{color:#fff}.text-danger{color:#ef5350!important}.text-muted{color:#98a6ad!important}.text-primary{color:#00b19d!important}.text-warning{color:#fa0!important}.text-success{color:#3bafda!important}.text-info{color:#3ddcf7!important}.text-inverse{color:#4c5667!important}.text-pink{color:#f76397!important}.text-purple{color:#7266ba!important}.text-dark{color:#797979!important}.dropcap{font-size:3.1em}.dropcap,.dropcap-circle,.dropcap-square{display:block;float:left;font-weight:400;line-height:36px;margin-right:6px;text-shadow:none}.p-0{padding:0!important}.p-20{padding:20px}.p-t-10{padding-top:10px!important}.p-b-10{padding-bottom:10px!important}.m-0{margin:0!important}.m-r-5{margin-right:5px}.m-r-10{margin-right:10px}.m-r-15{margin-right:15px!important}.m-l-5{margin-left:5px}.m-l-10{margin-left:10px}.m-l-15{margin-left:15px}.m-t-5{margin-top:5px!important}.m-t-10{margin-top:10px!important}.m-t-15{margin-top:15px!important}.m-t-20{margin-top:20px!important}.m-t-30{margin-top:30px!important}.m-t-40{margin-top:40px!important}.m-t-50{margin-top:50px}.m-b-5{margin-bottom:5px}.m-b-10{margin-bottom:10px}.m-b-15{margin-bottom:15px}.m-b-20{margin-bottom:20px}.m-b-25{margin-bottom:25px}.m-b-30{margin-bottom:30px!important}.w-xs{min-width:80px}.w-sm{min-width:95px}.w-md{min-width:110px}.w-lg{min-width:140px}.m-h-50{min-height:50px}.l-h-34{line-height:34px!important}.font-light{font-weight:300}.font-normal{font-weight:400}.font-bold{font-weight:700}.font-13{font-size:13px}.font-14{font-size:14px}.font-15{font-size:15px}.font-16{font-size:16px}.font-18{font-size:18px}.wrapper-md{padding:20px}.pull-in{margin-left:-20px;margin-right:-20px}.b-0{border:none!important}.no-border{border:none}.center-page{float:none!important;margin:0 auto}.bx-s-0{box-shadow:none!important}.bx-shadow{-moz-box-shadow:0 1px 2px 0 rgba(0,0,0,.1);-webkit-box-shadow:0 1px 2px 0 rgba(0,0,0,.1);box-shadow:0 1px 2px 0 rgba(0,0,0,.1)}.mx-box{max-height:380px;min-height:380px}.thumb-sm{height:32px;width:32px}.thumb-md{height:48px;width:48px}.thumb-lg{height:88px;width:88px}/*! + * Waves v0.6.0 + * http://fian.my.id/Waves + * + * Copyright 2014 Alfiana E. Sibuea and other contributors + * Released under the MIT license + * https://github.com/fians/Waves/blob/master/LICENSE + */.waves-effect{position:relative;cursor:pointer;display:inline-block;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;z-index:1;will-change:opacity,transform;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-o-transition:all .3s ease-out;-ms-transition:all .3s ease-out;transition:all .3s ease-out}.waves-effect .waves-ripple{position:absolute;border-radius:50%;width:20px;height:20px;margin-top:-10px;margin-left:-10px;opacity:0;background:rgba(0,0,0,.2);-webkit-transition:all .7s ease-out;-moz-transition:all .7s ease-out;-o-transition:all .7s ease-out;-ms-transition:all .7s ease-out;transition:all .7s ease-out;-webkit-transition-property:-webkit-transform,opacity;-moz-transition-property:-moz-transform,opacity;-o-transition-property:-o-transform,opacity;transition-property:transform,opacity;-webkit-transform:scale(0);-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);transform:scale(0);pointer-events:none}.waves-effect.waves-light .waves-ripple{background-color:rgba(255,255,255,.45)}.waves-effect.waves-red .waves-ripple{background-color:rgba(244,67,54,.7)}.waves-effect.waves-yellow .waves-ripple{background-color:rgba(255,235,59,.7)}.waves-effect.waves-orange .waves-ripple{background-color:rgba(255,152,0,.7)}.waves-effect.waves-purple .waves-ripple{background-color:rgba(156,39,176,.7)}.waves-effect.waves-green .waves-ripple{background-color:rgba(76,175,80,.7)}.waves-effect.waves-teal .waves-ripple{background-color:rgba(0,150,136,.7)}.waves-effect.waves-primary .waves-ripple{background-color:fade(#00b19d,40%)}.waves-notransition{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}.waves-circle{-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0);text-align:center;width:2.5em;height:2.5em;line-height:2.5em;border-radius:50%;-webkit-mask-image:none}.waves-input-wrapper{border-radius:.2em;vertical-align:bottom}.waves-input-wrapper .waves-button-input{position:relative;top:0;left:0;z-index:1}.waves-block{display:block}@-webkit-keyframes cd-bounce-1{0%{opacity:0;-webkit-transform:scale(.5)}60%{opacity:1;-webkit-transform:scale(1.2)}100%{-webkit-transform:scale(1)}}@-moz-keyframes cd-bounce-1{0%{opacity:0;-moz-transform:scale(.5)}60%{opacity:1;-moz-transform:scale(1.2)}100%{-moz-transform:scale(1)}}@-o-keyframes cd-bounce-1{0%{opacity:0;-o-transform:scale(.5)}60%{opacity:1;-o-transform:scale(1.2)}100%{-o-transform:scale(1)}}@-webkit-keyframes cd-bounce-2{0%{opacity:0;-webkit-transform:translateX(-100px)}60%{opacity:1;-webkit-transform:translateX(20px)}100%{-webkit-transform:translateX(0)}}@-moz-keyframes cd-bounce-2{0%{opacity:0;-moz-transform:translateX(-100px)}60%{opacity:1;-moz-transform:translateX(20px)}100%{-moz-transform:translateX(0)}}@-o-keyframes cd-bounce-2{0%{opacity:0;-o-transform:translateX(-100px)}60%{opacity:1;-o-transform:translateX(20px)}100%{opacity:1;-o-transform:translateX(0)}}@-webkit-keyframes dropdownOpen{0%{opacity:0;-webkit-transform:scale(0)}100%{-webkit-transform:scale(1)}}@-moz-keyframes dropdownOpen{0%{opacity:0;-moz-transform:scale(0)}100%{-moz-transform:scale(1)}}@-o-keyframes dropdownOpen{0%{opacity:0;-o-transform:scale(0)}100%{-o-transform:scale(1)}}@-webkit-keyframes loaderAnimate{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(220deg)}}@-moz-keyframes loaderAnimate{0%{-moz-transform:rotate(0)}100%{-moz-transform:rotate(220deg)}}@-o-keyframes loaderAnimate{0%{-o-transform:rotate(0)}100%{-o-transform:rotate(220deg)}}@keyframes loaderAnimate{0%{transform:rotate(0)}100%{transform:rotate(220deg)}}@-webkit-keyframes loaderAnimate2{0%{box-shadow:inset #555 0 0 0 8px;-webkit-transform:rotate(-140deg)}50%{box-shadow:inset #555 0 0 0 2px}100%{box-shadow:inset #555 0 0 0 8px;-webkit-transform:rotate(140deg)}}@-moz-keyframes loaderAnimate2{0%{box-shadow:inset #555 0 0 0 8px;-moz-transform:rotate(-140deg)}50%{box-shadow:inset #555 0 0 0 2px}100%{box-shadow:inset #555 0 0 0 8px;-moz-transform:rotate(140deg)}}@-o-keyframes loaderAnimate2{0%{box-shadow:inset #555 0 0 0 8px;-o-transform:rotate(-140deg)}50%{box-shadow:inset #555 0 0 0 2px}100%{box-shadow:inset #555 0 0 0 8px;-o-transform:rotate(140deg)}}@keyframes loaderAnimate2{100%{-webkit-transform:rotate(140deg);-moz-transform:rotate(140deg);-ms-transform:rotate(140deg)}0%{-webkit-transform:rotate(-140deg);-moz-transform:rotate(-140deg);-ms-transform:rotate(-140deg);box-shadow:inset #999 0 0 0 17px;transform:rotate(-140deg)}50%{box-shadow:inset #999 0 0 0 2px}100%{box-shadow:inset #999 0 0 0 17px;transform:rotate(140deg)}}.badge{font-weight:600;padding:3px 5px;font-size:12px;margin-top:1px}.badge-xs{font-size:9px}.badge-sm,.badge-xs{-webkit-transform:translate(0,-2px);-ms-transform:translate(0,-2px);-o-transform:translate(0,-2px);transform:translate(0,-2px)}.badge-primary{background-color:#00b19d}.badge-success{background-color:#3bafda}.badge-info{background-color:#3ddcf7}.badge-warning{background-color:#fa0;color:#fff}.badge-danger{background-color:#ef5350}.badge-purple{background-color:#7266ba;color:#fff}.badge-pink{background-color:#f76397;color:#fff}.badge-inverse{background-color:#4c5667;color:#fff}.pagination>li:first-child>a,.pagination>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pagination>li>a,.pagination>li>span{color:#636e7b}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{background-color:#e4e7ea}.pagination-split li{margin-left:5px;display:inline-block;float:left}.pagination-split li:first-child{margin-left:0}.pagination-split li a{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.page-item.active .page-link,.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{background-color:#00b19d;border-color:#00b19d}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{opacity:.6}.pager li>a,.pager li>span{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;color:#4c5667}.icon-list-demo div{cursor:pointer;line-height:50px;overflow:hidden;color:#75798B;font-size:14px}.icon-list-demo div p{margin-bottom:0;line-height:inherit}.icon-list-demo i{-webkit-transition:all .2s;display:inline-block;font-size:20px;margin:0;text-align:center;transition:all .2s;vertical-align:middle;width:40px}.loader-1,.loader-1:after{clip:rect(0,30px,30px,15px);height:30px;width:30px}.icon-list-demo .col-md-4:hover{color:#00b19d}.icon-list-demo .col-md-4:hover i{-o-transform:scale(1.5);-webkit-transform:scale(1.5);-moz-transform:scale(1.5);transform:scale(1.5)}.ionicon-list i{font-size:16px}.ionicon-list .col-md-3:hover i{-o-transform:scale(2);-webkit-transform:scale(2);-moz-transform:scale(2);transform:scale(2)}.button-list{margin-left:-8px;margin-bottom:-12px}.button-list .btn{margin-bottom:12px;margin-left:8px}@media print{#topnav,.breadcrumb,.btn-group.pull-right.m-t-15,.footer,.logo,.page-title,.topbar{display:none;margin:0;padding:0}.left,.right-bar{display:none}.card-box,.content,.wrapper{margin:0!important;padding:0!important;border:none!important}.content-page{margin-left:0;margin-top:0!important}}.btn-danger,.btn-dark,.btn-info,.btn-primary,.btn-success,.btn-warning{color:#fff}.btn-primary{background-color:#00b19d;border:1px solid #00b19d}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.btn-primary:not([disabled]):not(.disabled).active,.btn-primary:not([disabled]):not(.disabled):active,.open>.dropdown-toggle.btn-primary,.show>.btn-primary.dropdown-toggle{background-color:#009886;border-color:#009886}.btn-outline-primary.focus,.btn-outline-primary:focus,.btn-primary.focus,.btn-primary:focus,.btn-primary:not([disabled]):not(.disabled).active,.btn-primary:not([disabled]):not(.disabled).active:focus,.btn-primary:not([disabled]):not(.disabled):active,.btn-primary:not([disabled]):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 2px rgba(0,177,157,.5)}.btn-light{border-color:#eee}.btn-light.active,.btn-light.focus,.btn-light:active,.btn-light:focus,.btn-light:hover,.open>.dropdown-toggle.btn-light{border-color:#bfbfbf}.btn-light.focus,.btn-light:focus,.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 2px #d9d9d9}.btn-success{background-color:#3bafda;border:1px solid #3bafda}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.btn-success:not([disabled]):not(.disabled).active,.btn-success:not([disabled]):not(.disabled):active,.open>.dropdown-toggle.btn-success,.show>.btn-success.dropdown-toggle{background-color:#28a5d4;border-color:#28a5d4}.btn-outline-success.focus,.btn-outline-success:focus,.btn-success.focus,.btn-success:focus,.btn-success:not([disabled]):not(.disabled).active,.btn-success:not([disabled]):not(.disabled).active:focus,.btn-success:not([disabled]):not(.disabled):active,.btn-success:not([disabled]):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 2px rgba(59,175,218,.5)}.btn-info{background-color:#3ddcf7;border:1px solid #3ddcf7}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.btn-info:not([disabled]):not(.disabled).active,.btn-info:not([disabled]):not(.disabled):active,.open>.dropdown-toggle.btn-info,.show>.btn-info.dropdown-toggle{background-color:#25d8f6;border-color:#25d8f6}.btn-info.focus,.btn-info:focus,.btn-info:not([disabled]):not(.disabled).active,.btn-info:not([disabled]):not(.disabled).active:focus,.btn-info:not([disabled]):not(.disabled):active,.btn-info:not([disabled]):not(.disabled):active:focus,.btn-outline-info.focus,.btn-outline-info:focus,.show>.btn-info.dropdown-toggle,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 2px rgba(61,220,247,.5)}.btn-warning{background-color:#fa0;border:1px solid #fa0;color:#fff}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.btn-warning:not([disabled]):not(.disabled).active,.btn-warning:not([disabled]):not(.disabled):active,.open>.dropdown-toggle.btn-warning,.show>.btn-warning.dropdown-toggle{background-color:#e69900;border-color:#e69900;color:#fff}.btn-outline-warning.focus,.btn-outline-warning:focus,.btn-warning.focus,.btn-warning:focus,.btn-warning:not([disabled]):not(.disabled).active,.btn-warning:not([disabled]):not(.disabled).active:focus,.btn-warning:not([disabled]):not(.disabled):active,.btn-warning:not([disabled]):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 2px rgba(255,170,0,.5)}.btn-danger{background-color:#ef5350;border:1px solid #ef5350}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.btn-danger:not([disabled]):not(.disabled).active,.btn-danger:not([disabled]):not(.disabled):active,.open>.dropdown-toggle.btn-danger,.show>.btn-danger.dropdown-toggle{background-color:#ed3c39;border-color:#ed3c39}.btn-danger.focus,.btn-danger:focus,.btn-danger:not([disabled]):not(.disabled).active,.btn-danger:not([disabled]):not(.disabled).active:focus,.btn-danger:not([disabled]):not(.disabled):active,.btn-danger:not([disabled]):not(.disabled):active:focus,.btn-outline-danger.focus,.btn-outline-danger:focus,.show>.btn-danger.dropdown-toggle,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 2px rgba(239,83,80,.5)}.btn-dark{background-color:#2a3142;border:1px solid #2a3142}.btn-dark.active,.btn-dark.focus,.btn-dark:active,.btn-dark:focus,.btn-dark:hover,.open>.dropdown-toggle.btn-dark{background-color:#202532;border-color:#202532}.btn-dark.focus,.btn-dark:focus,.btn-dark:not([disabled]):not(.disabled).active,.btn-dark:not([disabled]):not(.disabled):active,.btn-outline-dark.focus,.btn-outline-dark:focus,.show>.btn-dark.dropdown-toggle{box-shadow:0 0 0 2px rgba(42,49,66,.5)}.btn-link{color:#2a3142}.btn-link:hover{color:#00b19d}.btn-outline-primary{color:#00b19d;border-color:#00b19d}.btn-outline-primary:hover{background-color:#00b19d;border-color:#00b19d}.btn-outline-success{color:#3bafda;border-color:#3bafda}.btn-outline-success:hover{background-color:#3bafda;border-color:#3bafda}.btn-outline-info{color:#3ddcf7;border-color:#3ddcf7}.btn-outline-info:hover{background-color:#3ddcf7;border-color:#3ddcf7}.btn-outline-warning{color:#fa0;border-color:#fa0}.btn-outline-warning:hover{background-color:#fa0;border-color:#fa0;color:#fff}.btn-outline-danger{color:#ef5350;border-color:#ef5350}.btn-outline-danger:hover{background-color:#ef5350;border-color:#ef5350}.btn-outline-dark{color:#2a3142;border-color:#2a3142}.btn-outline-dark:hover{background-color:#2a3142;border-color:#2a3142}.btn-custom{border-bottom:3px solid transparent}.btn-custom.btn-default{background-color:#f3f3f3;border-bottom:2px solid #ccc!important}.btn-custom.btn-primary{border-bottom:2px solid #007e70!important}.btn-custom.btn-success{border-bottom:2px solid #2494be!important}.btn-custom.btn-info{border-bottom:2px solid #08aac6!important}.btn-custom.btn-warning{border-bottom:2px solid #c80!important}.btn-custom.btn-danger{border-bottom:2px solid #c71612!important}.btn-custom.btn-dark{border-bottom:2px solid #0b0c0f!important}.btn-rounded{border-radius:2em;padding:6px 18px}.fileupload{overflow:hidden;position:relative}.fileupload input.upload{cursor:pointer;filter:alpha(opacity=0);font-size:20px;margin:0;opacity:0;padding:0;position:absolute;right:0;top:0}.portlet{-moz-box-shadow:0 1px 2px 0 rgba(0,0,0,.1);-moz-transition:all .4s;-o-transition:all .4s;-webkit-box-shadow:0 1px 2px 0 rgba(0,0,0,.1);-webkit-transition:all .4s;background:#fff;box-shadow:0 1px 2px 0 rgba(0,0,0,.1);margin-bottom:20px;transition:all .4s}.portlet .portlet-heading{border-radius:3px;color:#fff;padding:12px 20px}.portlet .portlet-heading .portlet-title{color:#fff;float:left;font-size:16px;font-weight:600;margin-bottom:0;margin-top:6px;letter-spacing:.03em}.checkbox label,.radio label{font-weight:500;display:inline-block}.portlet .portlet-heading .portlet-widgets{display:inline-block;float:right;font-size:15px;line-height:30px;padding-left:15px;position:relative;text-align:right}.portlet .portlet-heading .portlet-widgets .divider{margin:0 5px}.portlet .portlet-heading a{color:#999}.portlet .portlet-body{-moz-border-radius-bottomleft:5px;-moz-border-radius-bottomright:5px;-webkit-border-bottom-left-radius:5px;-webkit-border-bottom-right-radius:5px;background:#fff;border-bottom-left-radius:5px;border-bottom-right-radius:5px;padding:15px}.portlet-default .portlet-title{color:#797979!important}.portlet .portlet-heading .portlet-widgets .collapsed .ion-minus-round:before{content:"\f217"!important}.portlet .portlet-heading.bg-danger a,.portlet .portlet-heading.bg-info a,.portlet .portlet-heading.bg-inverse a,.portlet .portlet-heading.bg-pink a,.portlet .portlet-heading.bg-primary a,.portlet .portlet-heading.bg-purple a,.portlet .portlet-heading.bg-success a,.portlet .portlet-heading.bg-warning a{color:#fff}.panel-disabled{background:rgba(243,242,241,.5);cursor:progress;bottom:15px;left:0;position:absolute;right:-5px;top:0}.loader-1{-moz-animation:loaderAnimate 1s linear infinite;-o-animation:loaderAnimate 1s linear infinite;-webkit-animation:loaderAnimate 1s linear infinite;animation:loaderAnimate 1s linear infinite;left:50%;margin-left:-15px;margin-top:-15px;position:absolute;top:50%}.checkbox.checkbox-inline,.radio.radio-inline{margin-top:0}.loader-1:after{-moz-animation:loaderAnimate2 1s ease-in-out infinite;-o-animation:loaderAnimate2 1s ease-in-out infinite;-webkit-animation:loaderAnimate2 1s ease-in-out infinite;animation:loaderAnimate2 1s ease-in-out infinite;border-radius:50%;content:'';position:absolute}.custom-checkbox .custom-control-input:checked~.custom-control-label::before,.custom-control-input:checked~.custom-control-label::before,.custom-radio .custom-control-input:checked~.custom-control-label::before{background-color:#00b19d}.checkbox label{padding-left:5px;position:relative;font-size:13px}.checkbox label::before{-o-transition:.3s ease-in-out;-webkit-transition:.3s ease-in-out;background-color:#fff;border-radius:3px;border:1px solid #98a6ad;content:"";display:inline-block;height:17px;left:0;margin-left:-17px;position:absolute;transition:.3s ease-in-out;width:17px;outline:0!important}.checkbox label::after{color:#333;display:inline-block;font-size:11px;height:16px;left:0;margin-left:-17px;padding-left:3px;padding-top:1px;position:absolute;top:0;width:16px}.checkbox-custom input[type=checkbox]:checked+label::after,.checkbox-danger input[type=checkbox]:checked+label::after,.checkbox-info input[type=checkbox]:checked+label::after,.checkbox-inverse input[type=checkbox]:checked+label::after,.checkbox-pink input[type=checkbox]:checked+label::after,.checkbox-primary input[type=checkbox]:checked+label::after,.checkbox-purple input[type=checkbox]:checked+label::after,.checkbox-success input[type=checkbox]:checked+label::after,.checkbox-warning input[type=checkbox]:checked+label::after{color:#fff}.checkbox input[type=checkbox]{cursor:pointer;opacity:0;z-index:1;outline:0!important}.checkbox input[type=checkbox]:disabled+label{opacity:.65}.checkbox input[type=checkbox]:focus+label::before{outline-offset:-2px;outline:0}.checkbox input[type=checkbox]:checked+label::after{content:"\f00c";font-family:FontAwesome}.checkbox input[type=checkbox]:disabled+label::before{background-color:#eee;cursor:not-allowed}.checkbox-custom input[type=checkbox]:checked+label::before,.checkbox-primary input[type=checkbox]:checked+label::before{background-color:#00b19d;border-color:#00b19d}.checkbox.checkbox-circle label::before{border-radius:50%}.checkbox.checkbox-single input{height:18px;width:18px;position:absolute}.checkbox.checkbox-single label{height:18px;width:18px}.checkbox.checkbox-single label:after,.checkbox.checkbox-single label:before{margin-left:0}.checkbox-danger input[type=checkbox]:checked+label::before{background-color:#ef5350;border-color:#ef5350}.checkbox-info input[type=checkbox]:checked+label::before{background-color:#3ddcf7;border-color:#3ddcf7}.checkbox-warning input[type=checkbox]:checked+label::before{background-color:#fa0;border-color:#fa0}.checkbox-success input[type=checkbox]:checked+label::before{background-color:#3bafda;border-color:#3bafda}.checkbox-purple input[type=checkbox]:checked+label::before{background-color:#7266ba;border-color:#7266ba}.checkbox-pink input[type=checkbox]:checked+label::before{background-color:#f76397;border-color:#f76397}.checkbox-inverse input[type=checkbox]:checked+label::before{background-color:#4c5667;border-color:#4c5667}.radio label{padding-left:5px;position:relative;font-size:13px}.radio label::before{-o-transition:border .5s ease-in-out;-webkit-transition:border .5s ease-in-out;background-color:#fff;border-radius:50%;border:1px solid #98a6ad;content:"";display:inline-block;height:17px;left:0;margin-left:-20px;position:absolute;transition:border .5s ease-in-out;width:17px;outline:0!important}.radio-custom input[type=radio]:checked+label::before,.radio-primary input[type=radio]:checked+label::before{border-color:#00b19d}.radio label::after{-moz-transition:-moz-transform .1s cubic-bezier(.8,-.33,.2,1.33);-ms-transform:scale(0,0);-o-transform:scale(0,0);-o-transition:-o-transform .1s cubic-bezier(.8,-.33,.2,1.33);-webkit-transform:scale(0,0);-webkit-transition:-webkit-transform .1s cubic-bezier(.8,-.33,.2,1.33);background-color:#333;border-radius:50%;content:" ";display:inline-block;height:11px;left:3px;margin-left:-20px;position:absolute;top:3px;transform:scale(0,0);transition:transform .1s cubic-bezier(.8,-.33,.2,1.33);width:11px}.radio-custom input[type=radio]+label::after,.radio-custom input[type=radio]:checked+label::after,.radio-primary input[type=radio]+label::after,.radio-primary input[type=radio]:checked+label::after{background-color:#00b19d}.radio input[type=radio]{cursor:pointer;opacity:0;z-index:1;outline:0!important}.radio input[type=radio]:disabled+label{opacity:.65}.radio input[type=radio]:focus+label::before{outline-offset:-2px;outline:dotted thin}.radio input[type=radio]:checked+label::after{-ms-transform:scale(1,1);-o-transform:scale(1,1);-webkit-transform:scale(1,1);transform:scale(1,1)}.radio input[type=radio]:disabled+label::before{cursor:not-allowed}.radio.radio-single label{height:17px}.radio-danger input[type=radio]+label::after,.radio-danger input[type=radio]:checked+label::after{background-color:#ef5350}.radio-danger input[type=radio]:checked+label::before{border-color:#ef5350}.radio-info input[type=radio]+label::after,.radio-info input[type=radio]:checked+label::after{background-color:#3ddcf7}.radio-info input[type=radio]:checked+label::before{border-color:#3ddcf7}.radio-warning input[type=radio]+label::after,.radio-warning input[type=radio]:checked+label::after{background-color:#fa0}.radio-warning input[type=radio]:checked+label::before{border-color:#fa0}.radio-success input[type=radio]+label::after,.radio-success input[type=radio]:checked+label::after{background-color:#3bafda}.radio-success input[type=radio]:checked+label::before{border-color:#3bafda}.radio-purple input[type=radio]+label::after,.radio-purple input[type=radio]:checked+label::after{background-color:#7266ba}.radio-purple input[type=radio]:checked+label::before{border-color:#7266ba}.radio-pink input[type=radio]+label::after,.radio-pink input[type=radio]:checked+label::after{background-color:#f76397}.radio-pink input[type=radio]:checked+label::before{border-color:#f76397}.tab-content{padding:20px 0 0}.nav-pills>li>a,.nav-tabs>li>a{color:#2a3142;font-weight:600}.nav-pills .nav-item.show .nav-link,.nav-pills .nav-link.active{background-color:#00b19d}.tabs-vertical-env .tab-content{background:#fff;display:table-cell;padding:0 0 0 20px;margin-bottom:0;vertical-align:top}.tabs-vertical-env .nav.tabs-vertical{display:table-cell;min-width:120px;vertical-align:top;width:150px}.tabs-vertical-env .nav.tabs-vertical li>a{color:#2a3142;white-space:nowrap;font-weight:600;border-radius:2px}.tabs-vertical-env .nav.tabs-vertical li>a.active{background-color:#00b19d;border:0;color:#fff}.tabs-vertical-env-right .tab-content{padding:0 20px 0 0}.tabs-bordered{border-bottom:2px solid rgba(152,166,173,.2)!important}.tabs-bordered .nav-item{margin-bottom:-2px}.tabs-bordered li a,.tabs-bordered li a:focus,.tabs-bordered li a:hover{border:0!important;padding:10px 20px!important}.tabs-bordered li a.active{border-bottom:2px solid #00b19d!important}.nav-pills>li>a{color:#2a3142}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{background-color:#00b19d}.modal .modal-dialog .close{top:0;position:absolute;right:0;height:36px;width:36px;background-color:#2a3142;opacity:1;border:2px solid #fff;text-shadow:none;color:#fff;border-radius:50%;padding:0;font-size:18px}.modal .modal-dialog .modal-title{margin:0}.modal .modal-dialog .modal-content{-moz-box-shadow:none;-webkit-box-shadow:none;border-color:#DDD;border-radius:2px;box-shadow:none}.modal .modal-dialog .modal-content .modal-header{border-bottom-width:2px;margin:0}.modal .modal-dialog .modal-content .modal-body{padding:20px}.modal-full{width:98%;max-width:100%}.modal-demo{background-color:#fff;width:600px;border-radius:4px;display:none}.modal-demo .close{position:absolute;top:12px;right:25px;color:#fff;opacity:.5;font-weight:400;font-size:26px}.modal-demo .close:hover{opacity:1}.custom-modal-title{padding:15px 25px;line-height:22px;font-size:18px;background-color:#00b19d;color:#fff;text-align:left;margin:0}.custom-modal-text{padding:20px}.custombox-modal-flash .close,.custombox-modal-rotatedown .close{top:20px;z-index:9999}.progress{-webkit-box-shadow:none!important;background-color:#f3f3f3;box-shadow:none!important;height:10px;margin-bottom:18px;overflow:hidden}.progress-bar{box-shadow:none;font-size:8px;font-weight:600;background-color:#00b19d;line-height:12px}.progress.progress-sm{height:5px!important}.progress.progress-sm .progress-bar{font-size:8px;line-height:5px}.progress.progress-md{height:15px!important}.progress.progress-md .progress-bar{font-size:10.8px;line-height:14.4px}.tooltip-inner{border-radius:1px;padding:6px 10px}.jqstooltip{width:auto!important;height:auto!important}.popover{font-family:inherit}.popover .popover-title{background-color:transparent;color:#00b19d;margin:0;font-weight:600}.alert-success{background-color:#e4fffc!important;border-color:#00e4ca!important;color:#00b19d}.alert-success .alert-link{color:#00b19d}.alert-info,.alert-info .alert-link{color:#3ddcf7}.alert-info{background-color:#d0f7fd!important;border-color:#6ee5f9!important}.alert-warning{background-color:#fff7e6!important;border-color:#fb3!important;color:#fa0}.alert-warning .alert-link{color:#fa0}.alert-danger,.alert-danger .alert-link{color:#ef5350}.alert-danger{background-color:#fef4f4!important;border-color:#f3817f!important}.carousel-control{width:10%}.carousel-control span{position:absolute;top:50%;z-index:5;display:inline-block;font-size:30px}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.inbox-widget .inbox-item{border-bottom:1px solid #fafafa;overflow:hidden;padding:10px 0;position:relative}.inbox-widget .inbox-item .inbox-item-img{display:block;float:left;margin-right:15px;width:40px}.inbox-widget .inbox-item img{width:40px}.inbox-widget .inbox-item .inbox-item-author{color:#2a3142;display:block;margin:0}.inbox-widget .inbox-item .inbox-item-text{color:#98a6ad;display:block;font-size:12px;margin:0}.inbox-widget .inbox-item .inbox-item-date{color:#98a6ad;font-size:11px;position:absolute;right:7px;top:2px}.conversation-list{list-style:none;max-height:330px;padding:0 20px}.conversation-list li{margin-bottom:24px}.conversation-list .chat-avatar{display:inline-block;float:left;text-align:center;width:40px}.conversation-list .chat-avatar img{border-radius:100%;width:100%}.conversation-list .chat-avatar i{font-size:12px;font-style:normal}.conversation-list .ctext-wrap{-moz-border-radius:3px;-webkit-border-radius:3px;background:#f5f5f5;border-radius:3px;display:inline-block;padding:10px;position:relative}.conversation-list .ctext-wrap i{color:#2a3142;display:block;font-size:12px;font-style:normal;font-weight:700;position:relative}.conversation-list .ctext-wrap p{margin:0;padding-top:3px}.conversation-list .ctext-wrap:after{right:100%;top:20%;border:5px solid rgba(213,242,239,0);content:" ";height:0;width:0;position:absolute;pointer-events:none;border-right-color:#f5f5f5;margin-top:-5px}.conversation-list .conversation-text{display:inline-block;float:left;font-size:12px;margin-left:12px;width:70%}.conversation-list .odd .chat-avatar{float:right!important}.conversation-list .odd .conversation-text{float:right!important;margin-right:12px;text-align:right;width:70%!important}.conversation-list .odd p{color:#f2f2f2}.conversation-list .odd .ctext-wrap{background:#00b19d!important}.conversation-list .odd .ctext-wrap i{color:#fff}.conversation-list .odd .ctext-wrap:after{border-color:rgba(238,238,242,0)!important;border-left-color:#00b19d!important;left:100%!important;top:20%!important}.chat-send{padding-left:0;padding-right:30px}.chat-send button{width:100%}.chat-inputbar{padding-left:30px}#todo-message{font-size:16px}.todo-list li{border:0;margin:0;padding:5px!important;background:0 0!important;display:block}.todo-send{padding-left:0}.widget-chart ul li{width:31.5%;display:inline-block;padding:0}.widget-panel{padding:30px 20px 30px 30px;border-radius:4px;position:relative;margin-bottom:20px}.widget-panel i{font-size:60px;padding:30px;background:rgba(255,255,255,.2);position:absolute;right:0;bottom:0;top:0;line-height:60px}.widget-user{min-height:112px}.widget-user img{height:72px;float:left}.widget-user .wid-u-info{margin-left:90px}.widget-user .wid-u-info p{display:block;overflow:hidden}.widget-simple-chart .circliful-chart{float:left;margin-top:-5px}.widget-icon i{float:left;font-size:48px}.widget-icon .wid-icon-info{margin-left:80px}.widget-bg-color-icon .bg-icon{height:80px;width:80px;text-align:center;border-radius:50%}.widget-bg-color-icon .bg-icon i{font-size:32px;color:#fff!important;line-height:68px}.widget-bg-color-icon .bg-icon-info{background-color:rgba(61,220,247,.75);border:6px solid rgba(61,220,247,.3)}.widget-bg-color-icon .bg-icon-primary{background-color:rgba(0,177,157,.75);border:6px solid rgba(0,177,157,.3)}.widget-bg-color-icon .bg-icon-pink{background-color:rgba(247,99,151,.75);border:6px solid rgba(247,99,151,.3)}.widget-bg-color-icon .bg-icon-purple{background-color:rgba(114,102,186,.75);border:6px solid rgba(114,102,186,.3)}.widget-bg-color-icon .bg-icon-success{background-color:rgba(59,175,218,.75);border:6px solid rgba(59,175,218,.3)}.widget-bg-color-icon .bg-icon-warning{background-color:rgba(255,170,0,.75);border:6px solid rgba(255,170,0,.3)}.widget-bg-color-icon .bg-icon-danger{background-color:rgba(239,83,80,.75);border:6px solid rgba(239,83,80,.3)}.widget-bg-color-icon .bg-icon-inverse{background-color:rgba(76,86,103,.75);border:6px solid rgba(76,86,103,.3)}label{font-weight:500}.form-control{border:1px solid #cfcfcf;box-shadow:none;color:rgba(0,0,0,.6)}.form-control:focus{background:#fff;border-color:#a2a2a2;box-shadow:none}.input-sm{height:30px}.input-group-btn .btn{padding:7px 14px}.has-success .form-control{border-color:#3bafda;box-shadow:none!important}.has-warning .form-control{border-color:#fa0;box-shadow:none!important}.has-error .form-control{border-color:#ef5350;box-shadow:none!important}.input-group-addon{border-radius:2px}.bootstrap-tagsinput{box-shadow:none;padding:3px 7px;border:1px solid #f3f3f3}.bootstrap-tagsinput .label-info{background-color:#00b19d!important;display:inline-block;padding:2px 10px;border-radius:3px;font-size:14px;margin:2px}.ms-container{background:url(../images/multiple-arrow.png) 50% 50% no-repeat}.ms-container .ms-list{box-shadow:none;border:1px solid #f3f3f3}.ms-container .ms-list.ms-focus{border:1px solid #aaa;box-shadow:none}.ms-container .ms-selectable li.ms-elem-selectable,.ms-container .ms-selection li.ms-elem-selection{border:none;padding:5px 10px}.search-input{margin-bottom:10px}.ms-selectable{box-shadow:none;outline:0!important}.ms-container .ms-selectable li.ms-hover,.ms-container .ms-selection li.ms-hover{background-color:#00b19d}.select2-container{width:100%!important}.select2-container .select2-selection--single{border:1px solid #ebebeb;height:38px}.select2-container .select2-selection--single .select2-selection__rendered{line-height:36px;padding-left:12px}.select2-container .select2-selection--single .select2-selection__arrow{height:34px;width:34px;right:3px}.select2-container .select2-selection--single .select2-selection__arrow b{border-color:#c8c8c8 transparent transparent;border-width:6px 6px 0}.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #c8c8c8!important;border-width:0 6px 6px!important}.select2-container--default .select2-search--dropdown .select2-search__field,.select2-dropdown{border:1px solid #e1e1e1}.select2-results__option{padding:6px 12px}.select2-container--default .select2-search--dropdown{padding:10px;background-color:#fbfbfb}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#00b19d}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#eee;color:#2a3142}.select2-container--default .select2-results__option[aria-selected=true]:hover{background-color:#00b19d;color:#fff}.select2-container .select2-selection--multiple{min-height:38px;border:1px solid #e1e1e1!important}.select2-container .select2-selection--multiple .select2-selection__rendered{padding:2px 10px}.select2-container .select2-selection--multiple .select2-search__field{margin-top:7px;border:0}.select2-container .select2-selection--multiple .select2-selection__choice{background-color:#00b19d;border:1px solid transparent;color:#fff;border-radius:3px;padding:0 7px}.select2-container .select2-selection--multiple .select2-selection__choice__remove{color:#fff;margin-right:5px}.select2-container .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.datepicker{padding:8px}.datepicker th{font-size:14px!important}.datepicker table tr td span.active,.datepicker table tr td span.active.disabled,.datepicker table tr td span.active.disabled:hover,.datepicker table tr td span.active:hover,.datepicker table tr td.selected,.datepicker table tr td.selected.disabled,.datepicker table tr td.selected.disabled:hover,.datepicker table tr td.selected:hover,.datepicker table tr td.today,.datepicker table tr td.today.disabled,.datepicker table tr td.today.disabled:hover,.datepicker table tr td.today:hover{background-image:none}.datepicker table tr td span.active.active,.datepicker table tr td span.active.disabled,.datepicker table tr td span.active.disabled.active,.datepicker table tr td span.active.disabled.disabled,.datepicker table tr td span.active.disabled:active,.datepicker table tr td span.active.disabled:hover,.datepicker table tr td span.active.disabled:hover.active,.datepicker table tr td span.active.disabled:hover.disabled,.datepicker table tr td span.active.disabled:hover:active,.datepicker table tr td span.active.disabled:hover:hover,.datepicker table tr td span.active.disabled:hover[disabled],.datepicker table tr td span.active.disabled[disabled],.datepicker table tr td span.active:active,.datepicker table tr td span.active:hover,.datepicker table tr td span.active:hover.active,.datepicker table tr td span.active:hover.disabled,.datepicker table tr td span.active:hover:active,.datepicker table tr td span.active:hover:hover,.datepicker table tr td span.active:hover[disabled],.datepicker table tr td span.active[disabled]{background-color:#00b19d}.datepicker tfoot tr th:hover,.datepicker thead tr:first-child th:hover{background-color:#fafafa}.datepicker-inline{border:2px solid #eee}.datepicker table tr td.active,.datepicker table tr td.active.disabled,.datepicker table tr td.active.disabled:hover,.datepicker table tr td.active:hover{text-shadow:none;background-color:#00b19d!important;background-image:none;box-shadow:none}.daterangepicker td.active,.daterangepicker td.active:hover{background-color:#00b19d;border-color:#00b19d}.daterangepicker .input-mini.active{border:1px solid #AAA}.daterangepicker .ranges li{border-radius:2px;color:#797979;font-weight:600;font-size:12px}.daterangepicker select.ampmselect,.daterangepicker select.hourselect,.daterangepicker select.minuteselect,.daterangepicker select.secondselect{border:1px solid #e3e3e3;padding:2px;width:60px}.daterangepicker .ranges li.active,.daterangepicker .ranges li:hover{background-color:#00b19d;border:1px solid #00b19d}.bootstrap-touchspin .input-group-addon{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.25;color:#2a3142;text-align:center;background-color:#eee;border:1px solid rgba(42,49,66,.15)}.bootstrap-touchspin .input-group-btn:not(:first-child)>.btn,.bootstrap-touchspin .input-group-btn:not(:first-child)>.btn-group{z-index:2;margin-left:-1px}.bootstrap-touchspin .input-group .form-control:not(:first-child),.bootstrap-touchspin .input-group-addon:not(:first-child),.bootstrap-touchspin .input-group-btn:not(:first-child)>.btn,.bootstrap-touchspin .input-group-btn:not(:first-child)>.btn-group>.btn,.bootstrap-touchspin .input-group-btn:not(:first-child)>.dropdown-toggle,.bootstrap-touchspin .input-group-btn:not(:last-child)>.btn-group:not(:first-child)>.btn,.bootstrap-touchspin .input-group-btn:not(:last-child)>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.bootstrap-touchspin .input-group .form-control:not(:last-child),.bootstrap-touchspin .input-group-addon:not(:last-child),.bootstrap-touchspin .input-group-btn:not(:first-child)>.btn-group:not(:last-child)>.btn,.bootstrap-touchspin .input-group-btn:not(:first-child)>.btn:not(:last-child):not(.dropdown-toggle),.bootstrap-touchspin .input-group-btn:not(:last-child)>.btn,.bootstrap-touchspin .input-group-btn:not(:last-child)>.btn-group>.btn,.bootstrap-touchspin .input-group-btn:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.wizard>.content{background:#fff;min-height:240px;padding:20px}.wizard>.content>.body{padding:0;position:relative}.wizard>.content>.body input{border:1px solid #f3f3f3}.wizard>.content>.body ul>li{display:block;line-height:30px}.wizard>.content>.body label.error{color:#ef5350;margin-left:0}.wizard>.content>.body label{display:inline-block;margin-top:10px}.wizard>.steps .number{border-radius:50%;background-color:rgba(255,255,255,.3);display:inline-block;line-height:30px;margin-right:10px;width:30px;text-align:center}.wizard>.steps .disabled a{background:#fff;color:#333;cursor:default;border:1px solid #eaeaea}.wizard>.steps .disabled a:active,.wizard>.steps .disabled a:hover{background:#f9f9f9;color:#333;cursor:default;border:1px solid #eaeaea}.wizard>.steps .current a,.wizard>.steps .current a:active,.wizard>.steps .current a:hover{background:#00b19d}.wizard>.steps .current a .number,.wizard>.steps .current a:active .number,.wizard>.steps .current a:hover .number{color:#fff}.wizard>.steps .done a,.wizard>.steps .done a:active,.wizard>.steps .done a:hover{background:#ddd}.wizard>.content,.wizard>.steps a,.wizard>.steps a:active,.wizard>.steps a:hover{border-radius:2px}.wizard>.actions a,.wizard>.actions a:active,.wizard>.actions a:hover{background:#00b19d;border-radius:2px;color:#fff}.wizard>.actions .disabled a{background:#fff;color:#333;cursor:default;border:1px solid #eaeaea}.wizard>.actions .disabled a:active,.wizard>.actions .disabled a:hover{background:#f9f9f9;color:#333;cursor:default;border:1px solid #eaeaea}@media (max-width:767px){.wizard.vertical>.content,.wizard.vertical>.steps{display:inline;float:none;width:100%}.wizard>.steps>ul>li{width:100%}.wizard>.content{padding:0!important}.wizard>.content>.body{float:none;position:relative;width:100%;height:100%;padding:0}.wizard.vertical>.content{margin:0}}.error{color:#ef5350;font-size:12px;font-weight:500}.parsley-error{border-color:#ef5350!important}.parsley-errors-list{display:none;margin:0;padding:0}.parsley-errors-list.filled{display:block}.parsley-errors-list>li{font-size:12px;list-style:none;color:#ef5350}.dropzone{min-height:230px;border:2px dashed rgba(0,0,0,.3);background:#fff;border-radius:6px}.dropzone .dz-message{font-size:30px}.mce-content-body p{color:#9398a0;font-size:14px;font-weight:300}.mce-popover .mce-arrow:after{border-bottom-color:red}.mce-popover .mce-colorbutton-grid{margin:0;border:1px solid #d7dce5!important;padding:4px}.mce-reset .mce-window-head{border-bottom:1px solid #d7dce5}.mce-reset .mce-window-head .mce-title{color:#707780;font-size:16px;font-weight:400}.mce-reset .mce-textbox{border-radius:0;box-shadow:none;outline:0;border-color:#d7dce5;height:30px;font-weight:300;line-height:30px;color:#aaa;font-size:14px}.mce-reset .mce-textbox:focus{box-shadow:none;border-color:#00b19d}.mce-reset .mce-checkbox .mce-ico{background-image:none;background-color:#fff;border-radius:0;border:1px solid #d7dce5}.mce-reset .mce-checkbox .mce-label{color:#707780;font-size:12px;font-weight:400}.mce-container{border-radius:0!important;border-width:0!important}.mce-container .mce-menubar{background-color:#f2f4f7!important;border:1px solid #d7dce5!important;padding:2px}.mce-container .mce-menubar .mce-btn button span{color:#707780;font-size:14px;font-weight:400;text-transform:capitalize}.mce-container .mce-btn button,.mce-container .mce-primary button{color:#fff;font-weight:400;font-size:14px;text-shadow:none}.mce-container .mce-menubar .mce-btn button .mce-caret{border-top-color:#707780}.mce-container .mce-menubar .mce-btn button:hover,.mce-container .mce-menubar .mce-btn.mce-active button{background-color:#e8ebf1}.mce-container .mce-btn{background-color:#d7dce5;background-image:none;outline:0;border:0;border-radius:0}.mce-container .mce-btn:hover{background-color:#b8c1d1;background-image:none}.mce-container .mce-primary{background-color:#00b19d;background-image:none;outline:0;border:0;border-radius:0}.mce-container .mce-primary:hover{background-color:#0c7cd5;background-image:none}.mce-container .mce-toolbar-grp{background-color:#f2f4f7!important;border:1px solid #d7dce5!important;border-top-width:0!important;padding:6px}.mce-container .mce-edit-area{border:1px solid #d7dce5!important;border-width:0 1px!important}.mce-container .mce-statusbar{background-color:#f2f4f7!important;border:1px solid #d7dce5!important}.mce-container .mce-btn-group .mce-btn,.mce-container .mce-btn-group .mce-btn:focus,.mce-container .mce-btn-group .mce-btn:hover{box-shadow:none;background-color:#fff;background-image:none}.mce-container .mce-statusbar .mce-path .mce-path-item{color:#707780;font-size:14px;font-weight:400}.mce-container .mce-widget{color:#9398a0;font-size:14px;font-weight:400;border-left:1px solid transparent}.mce-container .mce-btn-group{border:1px solid #e9ecf2!important}.mce-container .mce-btn-group .mce-btn{border-width:0;border-radius:0!important}.mce-container .mce-btn-group .mce-btn button span{color:#707780;font-size:14px;font-weight:300}.mce-container .mce-btn-group .mce-btn button .mce-caret,.mce-container .mce-ico{color:#707780;font-size:14px}.mce-container .mce-panel{background-image:none}.mce-container.mce-menu{border:1px solid #d7dce5!important}.mce-container.mce-menu .mce-menu-item{background-image:none}.mce-container.mce-menu .mce-menu-item .mce-ico{color:#00b19d;font-size:14px}.mce-container.mce-menu .mce-menu-item .mce-text{color:#707780;font-size:14px;font-weight:400;text-transform:capitalize}.mce-container.mce-menu .mce-menu-item .mce-menu-shortcut{color:#aaa;font-size:12px;font-weight:300;text-transform:capitalize}.mce-container.mce-menu .mce-menu-item.mce-selected,.mce-container.mce-menu .mce-menu-item:focus,.mce-container.mce-menu .mce-menu-item:hover{background-color:#00b19d}.mce-container.mce-menu .mce-menu-item-sep,.mce-container.mce-menu .mce-menu-item-sep:hover,.mce-container.mce-menu .mce-menu-item.mce-disabled.mce-selected,.mce-container.mce-menu .mce-menu-item.mce-disabled:focus,.mce-container.mce-menu .mce-menu-item.mce-disabled:hover{background-color:#d7dce5}.mce-container.mce-menu .mce-menu-item.mce-selected .mce-ico,.mce-container.mce-menu .mce-menu-item.mce-selected .mce-menu-shortcut,.mce-container.mce-menu .mce-menu-item.mce-selected .mce-text,.mce-container.mce-menu .mce-menu-item:focus .mce-ico,.mce-container.mce-menu .mce-menu-item:focus .mce-menu-shortcut,.mce-container.mce-menu .mce-menu-item:focus .mce-text,.mce-container.mce-menu .mce-menu-item:hover .mce-ico,.mce-container.mce-menu .mce-menu-item:hover .mce-menu-shortcut,.mce-container.mce-menu .mce-menu-item:hover .mce-text{color:#fff}.mce-container.mce-menu .mce-menu-item.mce-disabled .mce-ico,.mce-container.mce-menu .mce-menu-item.mce-disabled .mce-menu-shortcut,.mce-container.mce-menu .mce-menu-item.mce-disabled .mce-text{color:#aaa}.mce-container.mce-menu .mce-menu-item.mce-disabled.mce-selected .mce-ico,.mce-container.mce-menu .mce-menu-item.mce-disabled.mce-selected .mce-menu-shortcut,.mce-container.mce-menu .mce-menu-item.mce-disabled.mce-selected .mce-text,.mce-container.mce-menu .mce-menu-item.mce-disabled:focus .mce-ico,.mce-container.mce-menu .mce-menu-item.mce-disabled:focus .mce-menu-shortcut,.mce-container.mce-menu .mce-menu-item.mce-disabled:focus .mce-text,.mce-container.mce-menu .mce-menu-item.mce-disabled:hover .mce-ico,.mce-container.mce-menu .mce-menu-item.mce-disabled:hover .mce-menu-shortcut,.mce-container.mce-menu .mce-menu-item.mce-disabled:hover .mce-text{color:#fff}.mce-menubtn button{color:#797979!important}.mce-menu-item-normal.mce-active{background-color:#00b19d!important}.mce-menu-item-normal.mce-active .mce-text{color:#fff!important}.note-btn-group .dropdown-menu>li>a{display:block;padding:5px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.note-air-popover,.note-icon-caret,.note-image-popover,.note-link-popover{display:none}.note-btn-group .dropdown-menu>li>a:hover{background-color:#f3f3f3}.note-air-popover .dropdown-toggle::after,.note-image-popover .dropdown-toggle::after,.note-link-popover .dropdown-toggle::after{margin-left:0}.table-wrapper .btn-toolbar,.tablesaw-columntoggle-btnwrap .btn-group{display:block}.note-editor{position:relative}.note-editor .btn-default{background-color:transparent;border-color:transparent}.note-editor .btn-group-sm>.btn,.note-editor .btn-sm{padding:8px 12px}.note-editor .note-toolbar{background-color:#f3f3f3;border-bottom:1px solid #eee;margin:0}.note-editor .note-statusbar{background-color:#fff}.note-editor .note-statusbar .note-resizebar{border-top:none;height:15px;padding-top:3px}.note-editor.note-frame{border:1px solid #eee}.note-popover .popover .popover-content{padding:5px 0 10px 5px}.note-popover .btn-default{background-color:transparent;border-color:transparent}.note-popover .btn-group-sm>.btn,.note-popover .btn-sm{padding:8px 12px}.note-toolbar{padding:5px 0 10px 5px}.table{margin-bottom:10px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{border-color:1px solid #f3f3f3}.table>tbody>tr>td.middle-align,.table>thead>tr>td.middle-align{vertical-align:middle}.add-edit-table td,.add-edit-table th,.mails td{vertical-align:middle!important}.table>thead>tr>th{border-color:2px solid #f3f3f3}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.04)}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:fade(#3bafda,15%)}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:fade(#3ddcf7,15%)}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:fade(#fa0,15%)}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:fade(#ef5350,15%)}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e!important}.dataTables_wrapper.container-fluid{max-width:100%;padding:0}div.dataTables_paginate ul.pagination{margin-top:30px}div.dataTables_info{padding-top:38px}.dt-buttons,div#datatable-buttons_info{float:left}.table-wrapper .dropdown-menu{left:auto;right:0}table.dataTable td.focus,table.dataTable th.focus{outline:#00b19d solid 2px!important;outline-offset:-1px;background-color:rgba(0,177,157,.15)}table.dataTable tbody>tr.selected,table.dataTable tbody>tr>.selected{background-color:#00b19d}table.dataTable.dtr-inline.collapsed>tbody>tr>td:first-child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>th:first-child:before{box-shadow:0 0 3px rgba(67,89,102,.2);background-color:#3bafda}table.dataTable.dtr-inline.collapsed>tbody>tr.parent>td:first-child:before,table.dataTable.dtr-inline.collapsed>tbody>tr.parent>th:first-child:before{background-color:#ef5350}.table-rep-plugin .dropdown-menu li.checkbox-row{padding:2px 15px!important}.table-rep-plugin .table-responsive{border:none!important}.table-rep-plugin tbody th{font-size:14px;font-weight:400}.table-rep-plugin .checkbox-row{padding-left:40px}.table-rep-plugin .checkbox-row label{display:inline-block;padding-left:5px;position:relative}.table-rep-plugin .checkbox-row label::before{-o-transition:.3s ease-in-out;-webkit-transition:.3s ease-in-out;background-color:#fff;border-radius:3px;border:1px solid #98a6ad;content:"";display:inline-block;height:17px;left:0;margin-left:-20px;position:absolute;transition:.3s ease-in-out;width:17px;outline:0!important}.table-rep-plugin .checkbox-row label::after{color:#f3f3f3;display:inline-block;font-size:11px;height:16px;left:0;margin-left:-20px;padding-left:3px;padding-top:1px;position:absolute;top:-1px;width:16px}.table-rep-plugin .checkbox-row input[type=checkbox]{cursor:pointer;opacity:0;z-index:1;outline:0!important}.table-rep-plugin .checkbox-row input[type=checkbox]:disabled+label{opacity:.65}.table-rep-plugin .checkbox-row input[type=checkbox]:focus+label::before{outline-offset:-2px;outline:0}.table-rep-plugin .checkbox-row input[type=checkbox]:checked+label::after{content:"\f00c";font-family:FontAwesome;color:#00b19d}.table-rep-plugin .checkbox-row input[type=checkbox]:disabled+label::before{background-color:#eee;cursor:not-allowed}.table-rep-plugin .checkbox-row input[type=checkbox]:checked+label::before{background-color:#fff;border-color:#00b19d}.table-rep-plugin .sticky-table-header,.table-rep-plugin table.focus-on tbody tr.focused td,.table-rep-plugin table.focus-on tbody tr.focused th{background-color:#00b19d;color:#fff;border-color:#00b19d}.table-rep-plugin .sticky-table-header.fixed-solution{top:120px!important}.table-rep-plugin .btn-default{background-color:#fff;border:1px solid rgba(42,49,66,.3)}.table-rep-plugin .btn-default.btn-primary{background-color:#00b19d}.table-rep-plugin .btn-toolbar{display:block}.table-rep-plugin .btn-group.pull-right{float:right}.table-rep-plugin .btn-group.pull-right .dropdown-menu{left:auto;right:0}.add-edit-table td{border:0!important}#datatable-editable .actions a{padding:5px}#datatable-editable .form-control{background-color:#fff;width:auto;height:20px}#datatable-editable .fa-times,#datatable-editable .fa-trash-o{color:#ef5350}#datatable-editable .fa-pencil{color:#00b19d}#datatable-editable .fa-save{color:#3bafda}#datatable td{font-weight:400}.modal-block{background:0 0;margin:40px auto;max-width:600px;padding:0;position:relative;text-align:left}.tablesaw thead{background:#f5f5f5;border:none}.tablesaw thead th{text-shadow:none;letter-spacing:.06em}.home-text,.ribbon span{letter-spacing:1px}.tablesaw thead tr:first-child th{padding-top:1.1em;padding-bottom:.9em;font-weight:600;font-family:inherit;border:none}.tablesaw tbody th,.tablesaw td{font-size:inherit;line-height:inherit;padding:10px!important}.tablesaw tbody tr,.tablesaw-stack tbody tr{border-bottom:none}.tablesaw-sortable .tablesaw-sortable-head.tablesaw-sortable-ascending button:after,.tablesaw-sortable .tablesaw-sortable-head.tablesaw-sortable-descending button:after{font-family:FontAwesome;font-size:10px}.tablesaw-sortable .tablesaw-sortable-head.tablesaw-sortable-ascending button:after{content:"\f176"}.tablesaw-sortable .tablesaw-sortable-head.tablesaw-sortable-descending button:after{content:"\f175"}.timeline-item.alt:after,.timeline-item:before,.timeline:before{content:""}.tablesaw-bar .btn-select.btn-micro:after,.tablesaw-bar .btn-select.btn-small:after{font-size:8px;padding-right:10px}.tablesaw-swipe .tablesaw-cell-persist{box-shadow:none}.tablesaw-enhanced .tablesaw-bar .btn{text-shadow:none;background-image:none}.tablesaw-enhanced .tablesaw-bar .btn.btn-select:hover{background:#fff}.tablesaw-enhanced .tablesaw-bar .btn:active,.tablesaw-enhanced .tablesaw-bar .btn:focus,.tablesaw-enhanced .tablesaw-bar .btn:hover{color:#00b19d!important;background-color:#f5f5f5;outline:0!important;box-shadow:none!important;background-image:none}.footable-odd{background-color:#fff}.footable-detail-show{background-color:#e6e6e6}.footable>thead>tr>th>span.footable-sort-indicator{float:right}.footable-pagination li{margin-left:5px;display:inline-block;float:left}.footable-pagination li a{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#2a3142;background-color:#fff;border:1px solid #eee}.gmaps-overlay_arrow.above,.gmaps-overlay_arrow.below{border-left:16px solid transparent;border-right:16px solid transparent}.footable-pagination li.active a{color:#fff}.gmaps,.gmaps-panaroma{height:300px;background:#eee;border-radius:3px}.gmaps-overlay{display:block;text-align:center;color:#fff;font-size:16px;line-height:40px;background:#00b19d;border-radius:4px;padding:10px 20px}.gmaps-overlay_arrow{left:50%;margin-left:-16px;width:0;height:0;position:absolute}.gmaps-overlay_arrow.above{bottom:-15px;border-top:16px solid #00b19d}.gmaps-overlay_arrow.below{top:-15px;border-bottom:16px solid #00b19d}.mails a{color:#797979}.mails td{position:relative}.mails td:last-of-type{width:100px;padding-right:20px}.mails tr:hover .text-white{display:none}.mails .mail-select{padding:12px 20px;min-width:134px}.mails .checkbox{margin-bottom:0;margin-top:0;vertical-align:middle;display:inline-block;height:17px}.mails .checkbox label{min-height:16px}.mail-list .list-group-item{background-color:transparent;color:#2a3142;font-size:.95rem}.mail-list .list-group-item:focus,.mail-list .list-group-item:hover{background-color:#eee}.mail-list .list-group-item.active{color:#ef5350}.unread a{font-weight:600;color:#444}.calendar{float:left;margin-bottom:0}.none-border .modal-footer{border-top:none}.fc-button,.fc-widget-content,.fc-widget-header{border:1px solid #d5d5d5}.fc-toolbar{margin-bottom:5px}.fc-toolbar h2{font-size:18px;font-weight:600;line-height:30px;text-transform:uppercase}.fc-day{background:#fff}.fc-toolbar .fc-state-active,.fc-toolbar .ui-state-active,.fc-toolbar .ui-state-hover,.fc-toolbar button:focus,.fc-toolbar button:hover{z-index:0}.fc th.fc-widget-header{background:#ddd;font-size:14px;line-height:20px;padding:10px 0;text-transform:uppercase}.fc-button{background:#fff;color:#555;text-transform:capitalize}.external-event,.fc-event .fc-content,.timeline .time-show a{color:#fff}.fc-text-arrow{font-family:arial;font-size:16px}.fc-state-hover{background:#F5F5F5}.fc-cell-overlay,.fc-state-highlight{background:#f0f0f0}.fc-unthemed .fc-today{background:#fff}.fc-event{border-radius:2px;border:none;cursor:move;font-size:13px;margin:5px 7px;padding:5px;text-align:center}.external-event{cursor:move;margin:10px 0;padding:6px 10px}.fc-basic-view td.fc-day-number,.fc-basic-view td.fc-week-number span{padding-right:5px}.timeline{border-collapse:collapse;border-spacing:0;display:table;margin-bottom:50px;position:relative;table-layout:fixed;width:100%}.timeline .time-show{margin-bottom:30px;margin-right:-75px;margin-top:30px;position:relative}.timeline:before{background-color:#d8d9df;bottom:0;left:50%;position:absolute;top:30px;width:1px;z-index:0}.timeline .timeline-icon{-webkit-border-radius:50%;background:#d8d9df;border-radius:50%;border:1px solid #d8d9df;color:#fff;display:block;height:20px;left:-54px;margin-top:-10px;position:absolute;text-align:center;top:50%;width:20px}.timeline .timeline-icon i{margin-top:9px}.timeline .time-icon:before{font-size:16px;margin-top:5px}h3.timeline-title{color:#c8ccd7;font-size:20px;font-weight:400;margin:0 0 5px;text-transform:uppercase}.timeline-item .timeline-desk .arrow,.timeline-item.alt .timeline-desk .arrow-alt{border-bottom:8px solid transparent;border-top:8px solid transparent;height:0;margin-top:-10px;position:absolute;top:50%}.timeline-item{display:table-row}.timeline-item:before{display:block;width:50%}.timeline-item .timeline-desk .arrow{border-right:8px solid #fff!important;display:block;left:-7px;width:0}.timeline-item.alt:after{display:block;width:50%}.timeline-item.alt .timeline-desk .arrow-alt{border-left:8px solid #fff!important;display:block;left:auto;right:-7px;width:0}.timeline-item.alt .timeline-desk .album{float:right;margin-top:20px}.timeline-item.alt .timeline-desk .album a{float:right;margin-left:5px}.timeline-item.alt .timeline-icon{left:auto;right:-56px}.timeline-item.alt:before{display:none}.timeline-item.alt .panel{margin-left:0;margin-right:45px}.timeline-item.alt .panel .panel-body p+p{margin-top:10px!important}.timeline-item.alt .timeline-date,.timeline-item.alt h4,.timeline-item.alt p{text-align:right}.timeline-desk{display:table-cell;vertical-align:top;width:50%}.timeline-desk h4{font-size:16px;margin:0}.timeline-desk .panel{background:#fff;display:block;margin-bottom:5px;margin-left:45px;position:relative;text-align:left;padding:15px;border-radius:5px}.timeline-desk h5 span{color:#797979;display:block;font-size:12px;margin-bottom:4px}.timeline-desk p{color:#999;font-size:14px;margin-bottom:0}.timeline-desk .album{margin-top:12px}.timeline-desk .album a{float:left;margin-right:5px}.timeline-desk .album img{height:36px;width:auto;border-radius:3px}.timeline-desk .notification{background:#fff;margin-top:20px;padding:8px}.timeline-2{border-left:2px solid #00b19d;position:relative}.time-item:after,.timeline-2 .time-item:after{background-color:#fff;border-radius:10px;border-style:solid;border-width:2px;bottom:0;left:0;top:5px}.timeline-2 .time-item:after{border-color:#00b19d;content:'';height:10px;margin-left:-6px;position:absolute;width:10px}.time-item{border-color:#dee5e7;padding-bottom:10px;position:relative}.time-item:before{content:" ";display:table}.time-item:after{border-color:#00b19d;content:'';height:14px;margin-left:-8px;position:absolute;width:14px}.time-item-item:after{content:" ";display:table}.item-info{margin-bottom:15px;margin-left:15px}.item-info p{font-size:13px}.swal2-modal{font-family:"Microsoft YaHei","微软雅黑",Arial,"黑体","宋体",sans-serif;box-shadow:0 10px 33px rgba(0,0,0,.1)}.swal2-modal .swal2-title{font-size:28px}.swal2-modal .swal2-content{font-size:16px}.swal2-modal .swal2-spacer{margin:10px 0}.swal2-modal .swal2-file,.swal2-modal .swal2-input,.swal2-modal .swal2-textarea{border:2px solid #98a6ad;font-size:16px;box-shadow:none}.swal2-modal .swal2-confirm.btn-confirm{background-color:#00b19d!important}.swal2-modal .swal2-cancel.btn-cancel{background-color:#ef5350!important}.swal2-modal .swal2-styled:focus{box-shadow:none!important}.swal2-icon.swal2-question{color:#00b19d;border-color:#00b19d}.swal2-icon.swal2-success,.swal2-icon.swal2-success .placeholder,.swal2-icon.swal2-success .swal2-success-ring{border-color:#3bafda}.swal2-icon.swal2-success .line,.swal2-icon.swal2-success [class^=swal2-success-line],.swal2-icon.swal2-success [class^=swal2-success-line][class$=long]{background-color:#3bafda}.swal2-icon.swal2-warning{color:#fa0;border-color:#fa0}.swal2-icon.swal2-error{border-color:#ef5350}.swal2-icon.swal2-error .line{background-color:#ef5350}.swal2-modal .swal2-file:focus,.swal2-modal .swal2-input:focus,.swal2-modal .swal2-textarea:focus{outline:0;border:2px solid #00b19d}.swal2-container.swal2-shown{background-color:rgba(42,49,66,.9)}.notifyjs-metro-base{position:relative;min-height:52px;min-width:250px;color:#444;border-radius:3px;-webkit-border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2);-webkit-animation:dropdownOpen .3s ease-out;-o-animation:dropdownOpen .3s ease-out;animation:dropdownOpen .3s ease-out}.notifyjs-metro-base .image{display:table;position:absolute;height:auto;width:auto;left:25px;top:50%;font-size:24px;-moz-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);-o-transform:translate(-50%,-50%);-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.app-countdown div,.chart,.percent{display:inline-block}.notifyjs-metro-base .text-wrapper{display:inline-block;vertical-align:top;text-align:left;margin:10px 10px 10px 52px;clear:both}.app-countdown,.app-countdown>*,.chart{text-align:center}.notifyjs-metro-base .title{font-size:15px;line-height:20px;margin-bottom:5px;font-weight:700}.notifyjs-metro-base .text{font-size:12px;font-weight:400;max-width:360px;vertical-align:middle}.notifyjs-metro-cool{color:#fafafa!important;background-color:#4A525F;border:1px solid #4A525F}.custom-dd .dd-list .dd-item .dd-handle{background:rgba(152,166,173,.25)!important;border:none;padding:8px 16px;height:auto;font-weight:600;border-radius:3px}.custom-dd .dd-list .dd-item .dd-handle:hover{color:#00b19d}.custom-dd .dd-list .dd-item button{height:auto;font-size:17px;margin:8px auto;color:#555;width:30px}.custom-dd-empty .dd-list .dd3-handle{border:none;background:rgba(152,166,173,.25)!important;height:36px;width:36px}.custom-dd-empty .dd-list .dd3-handle:before{color:inherit;top:7px}.custom-dd-empty .dd-list .dd3-content:hover,.custom-dd-empty .dd-list .dd3-handle:hover{color:#00b19d}.custom-dd-empty .dd-list .dd3-content{height:auto;border:none;padding:8px 16px 8px 46px;background:rgba(152,166,173,.25)!important;font-weight:600}.custom-dd-empty .dd-list button{width:26px;height:26px;font-size:16px;font-weight:600}.morris-hover.morris-default-style{border-radius:5px;padding:10px 12px;background:#36404a;border:none;color:#fff!important}.chart-detail-list li{margin:0 10px}.chart-detail-list li h5{font-size:15px}.pieLabel div{font-size:14px!important}.chart{position:relative;width:110px;height:110px;margin-top:20px;margin-bottom:20px}.chart canvas{position:absolute;top:0;left:0}.chart.chart-widget-pie{margin-top:5px;margin-bottom:5px}.percent{line-height:110px;z-index:2;font-weight:600;font-size:18px;color:#797979}.percent:after{content:'%';margin-left:.1em;font-size:.8em}#flotTip{padding:8px 12px;background-color:#36404a;z-index:100;color:#fff;opacity:.9;font-size:13px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.legend tr{height:20px}.legendLabel{padding-left:10px!important;line-height:10px;padding-right:10px}.ct-golden-section:before{float:none}.ct-chart{max-height:300px}.ct-chart .ct-label{fill:#a3afb7;color:#a3afb7;font-size:12px;line-height:1}.ct-chart.simple-pie-chart-chartist .ct-label{color:#fff;fill:#fff;font-size:16px}.ct-chart .ct-series.ct-series-a .ct-bar,.ct-chart .ct-series.ct-series-a .ct-line,.ct-chart .ct-series.ct-series-a .ct-point,.ct-chart .ct-series.ct-series-a .ct-slice-donut{stroke:#00b19d}.ct-chart .ct-series.ct-series-b .ct-bar,.ct-chart .ct-series.ct-series-b .ct-line,.ct-chart .ct-series.ct-series-b .ct-point,.ct-chart .ct-series.ct-series-b .ct-slice-donut{stroke:#f76397}.ct-chart .ct-series.ct-series-c .ct-bar,.ct-chart .ct-series.ct-series-c .ct-line,.ct-chart .ct-series.ct-series-c .ct-point,.ct-chart .ct-series.ct-series-c .ct-slice-donut{stroke:#3bafda}.ct-chart .ct-series.ct-series-d .ct-bar,.ct-chart .ct-series.ct-series-d .ct-line,.ct-chart .ct-series.ct-series-d .ct-point,.ct-chart .ct-series.ct-series-d .ct-slice-donut{stroke:#3ddcf7}.ct-chart .ct-series.ct-series-e .ct-bar,.ct-chart .ct-series.ct-series-e .ct-line,.ct-chart .ct-series.ct-series-e .ct-point,.ct-chart .ct-series.ct-series-e .ct-slice-donut{stroke:#797979}.ct-chart .ct-series.ct-series-f .ct-bar,.ct-chart .ct-series.ct-series-f .ct-line,.ct-chart .ct-series.ct-series-f .ct-point,.ct-chart .ct-series.ct-series-f .ct-slice-donut{stroke:#7266ba}.ct-chart .ct-series.ct-series-g .ct-bar,.ct-chart .ct-series.ct-series-g .ct-line,.ct-chart .ct-series.ct-series-g .ct-point,.ct-chart .ct-series.ct-series-g .ct-slice-donut{stroke:#fa0}.ct-series-a .ct-area,.ct-series-a .ct-slice-pie{fill:#00b19d}.ct-series-b .ct-area,.ct-series-b .ct-slice-pie{fill:#f76397}.ct-series-c .ct-area,.ct-series-c .ct-slice-pie{fill:#3bafda}.ct-series-d .ct-area,.ct-series-d .ct-slice-pie{fill:#3ddcf7}.jqstooltip{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;background-color:#2a3142!important;padding:5px 10px!important;border-radius:3px;border-color:#2a3142!important}.jqsfield{font-size:12px!important;line-height:18px!important}.circliful-chart{margin:0 auto}.circle-info,.circle-info-half,.circle-text,.circle-text-half{font-size:12px;font-weight:600}.home-wrapper{margin:10% 0}.app-countdown{margin-top:40px}.app-countdown div span{display:block;width:150px}.app-countdown div span:first-child{font-size:3em;font-weight:700;height:48px;line-height:48px}.app-countdown div span:last-child{color:#333;font-size:.9em;height:25px;line-height:25px}.portfolioFilter a{-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out;color:#2a3142;padding:5px 10px;display:inline-block;font-size:14px;font-weight:500;border-radius:4px}.portfolioFilter a.current,.portfolioFilter a:hover{background-color:#00b19d;color:#fff}.thumb{background-color:#fff;border-radius:3px;box-shadow:0 1px 1px 0 rgba(0,0,0,.1);margin-top:30px;padding:10px;width:100%}.thumb-img{border-radius:2px;overflow:hidden;width:100%}.gal-detail h4{margin:16px auto 10px;width:80%;display:block;overflow:hidden;font-size:18px}.gal-detail p{margin-bottom:10px}.gal-detail .ga-border{height:3px;width:40px;background-color:#00b19d;margin:10px auto}.icon-main{font-size:60px}.maintenance-page{margin:10% 0}.wrapper-page{margin:7.5% auto;max-width:420px}.wrapper-page .form-control{height:40px}.logo-lg{font-size:25px!important;font-weight:700;color:#00b19d!important}.user-thumb img{height:88px;margin:0 auto;width:88px}.ex-page-content .svg-box{float:right}.message-box{margin:120px 50px}.message-box h1{color:#252932;font-size:98px;font-weight:700;line-height:98px;text-shadow:rgba(61,61,61,.3) 1px 1px,rgba(61,61,61,.2) 2px 2px,rgba(61,61,61,.3) 3px 3px}#Polygon-1,#Polygon-2,#Polygon-3,#Polygon-4,#Polygon-5{animation:float 1s infinite ease-in-out alternate}#Polygon-2{animation-delay:.2s}#Polygon-3{animation-delay:.4s}#Polygon-4{animation-delay:.6s}#Polygon-5{animation-delay:.8s}@keyframes float{100%{transform:translateY(20px)}}.jstree-default .jstree-clicked,.jstree-default .jstree-wholerow-clicked{background:rgba(0,177,157,.4);box-shadow:none}.jstree-default .jstree-hovered,.jstree-default .jstree-wholerow-hovered{background:rgba(0,177,157,.2);box-shadow:none}.pricing-column{position:relative;margin-bottom:40px}.pricing-column .inner-box{position:relative;padding:0 0 50px}.pricing-column .plan-header{position:relative;padding:30px 20px 25px}.pricing-column .plan-title{font-size:16px;margin-bottom:10px;color:#3bafda;text-transform:uppercase;letter-spacing:1px;font-weight:400}.pricing-column .plan-price{font-size:48px;margin-bottom:10px;color:#2a3142}.pricing-column .plan-duration{font-size:13px;color:#98a6ad}.pricing-column .plan-stats{position:relative;padding:30px 20px 15px}.pricing-column .plan-stats li{margin-bottom:15px;line-height:24px}.pricing-column .plan-stats li i{font-size:16px;vertical-align:middle;margin-right:5px}.ribbon{position:absolute;left:5px;top:-5px;z-index:1;overflow:hidden;width:75px;height:75px;text-align:right}.question-q-box,.ribbon span{color:#fff;text-align:center;font-weight:700}.ribbon span{font-size:10px;text-transform:uppercase;line-height:20px;transform:rotate(-45deg);-webkit-transform:rotate(-45deg);width:100px;display:block;box-shadow:0 0 8px 0 rgba(0,0,0,.06),0 1px 0 0 rgba(0,0,0,.02);background:#3bafda;background:linear-gradient(#3bafda 0,#3bafda 100%);position:absolute;top:19px;left:-21px}.ribbon span:after,.ribbon span:before{content:"";position:absolute;top:100%;z-index:-1;border-bottom:3px solid transparent;border-top:3px solid #2494be}.ribbon span:before{left:0;border-left:3px solid #2494be;border-right:3px solid transparent}.ribbon span:after{right:0;border-left:3px solid transparent;border-right:3px solid #2494be}.question-q-box{height:30px;width:30px;background-color:#ef5350;border-radius:50%;float:left;line-height:26px}.question{margin-top:0;margin-left:50px;font-size:16px}.answer{margin-left:50px;color:#98a6ad;margin-bottom:40px;line-height:26px}@media (min-width:768px) and (max-width:991px){body{overflow-x:hidden}.fixedHeader-floating{top:60px!important}}@media (max-width:768px){body{overflow-x:hidden}.container-fluid{max-width:100%}.topbar-left{width:70px!important}.topbar-left span{display:none!important}.topbar-left i{display:block!important;line-height:70px!important}.topbar .topbar-left{height:70px}.navbar-nav.navbar-right{float:right}.content-page{margin-left:0!important}.enlarged .left.side-menu{margin-left:-70px}.footer{left:0!important}.mobile-sidebar{left:0}.mobile-content{left:250px;right:-250px}.dataTables_wrapper .col-xs-6{width:100%;text-align:left}div#datatable-buttons_info{float:none}.ms-container{width:100%}.m-t-sm-50{margin-top:50px!important}.fixedHeader-floating{top:60px!important}}@media (max-width:767px){.navbar-nav .open .dropdown-menu{background-color:#fff;box-shadow:0 2px 5px 0 rgba(0,0,0,.26);left:auto;position:absolute;right:0}.navbar-nav .open .dropdown-menu li{display:block}.navbar-nav{margin:0;display:inline-block}.navbar-nav li{display:inline-block;line-height:1px}.dropdown-lg{width:200px!important}.user-box{float:right}.dataTables_length{float:none;margin-bottom:10px}.table-auto-res{display:block;width:100%;overflow-x:auto}}@media (max-width:480px){.side-menu{z-index:10!important}.button-menu-mobile{display:block}.search-bar{display:none!important}.logo-large{display:none}.logo-small{display:inline-block!important}.dropdown-menu-lg{max-width:230px}}@media (max-width:420px){.hide-phone{display:none!important}}@media (min-width:768px){.container-alt{width:750px}}@media (min-width:992px){.container-alt{width:970px}}@media (min-width:1200px){.container-alt{width:1170px}}@media (max-width:419px){.hidden-xxs,.page-title-box .breadcrumb,.topbar-left,.user-list .user-list-item .avatar,.user-list .user-list-item .icon{display:none}.topbar-left{width:70px!important}.content-page{margin-left:70px}.forced .side-menu.left{box-shadow:0 12px 12px rgba(0,0,0,.1)}.enlarged .side-menu.left{box-shadow:0 1px 1px rgba(0,0,0,.1)!important}.page-title{font-size:15px;max-width:250px;white-space:nowrap}.navbar-default{padding:0}.navbar-default .navbar-left{padding-left:0!important}.navbar-default .navbar-left li{padding:0 5px}.editable-responsive{overflow-x:auto}.navbar-nav .open .dropdown-menu{margin-right:-20px}.user-box .dropdown-menu{margin-right:0!important}.dropdown-lg{width:200px!important}.user-list .user-list-item .user-desc{margin-left:0}} \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/assets/fonts/FontAwesome.otf b/net452/SiteServer.Web/Home/assets/fonts/FontAwesome.otf new file mode 100644 index 000000000..401ec0f36 Binary files /dev/null and b/net452/SiteServer.Web/Home/assets/fonts/FontAwesome.otf differ diff --git a/net452/SiteServer.Web/Home/assets/fonts/fontawesome-webfont.eot b/net452/SiteServer.Web/Home/assets/fonts/fontawesome-webfont.eot new file mode 100644 index 000000000..e9f60ca95 Binary files /dev/null and b/net452/SiteServer.Web/Home/assets/fonts/fontawesome-webfont.eot differ diff --git a/net452/SiteServer.Web/Home/assets/fonts/fontawesome-webfont.svg b/net452/SiteServer.Web/Home/assets/fonts/fontawesome-webfont.svg new file mode 100644 index 000000000..855c845e5 --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/net452/SiteServer.Web/Home/assets/fonts/fontawesome-webfont.ttf b/net452/SiteServer.Web/Home/assets/fonts/fontawesome-webfont.ttf new file mode 100644 index 000000000..35acda2fa Binary files /dev/null and b/net452/SiteServer.Web/Home/assets/fonts/fontawesome-webfont.ttf differ diff --git a/net452/SiteServer.Web/Home/assets/fonts/fontawesome-webfont.woff b/net452/SiteServer.Web/Home/assets/fonts/fontawesome-webfont.woff new file mode 100644 index 000000000..400014a4b Binary files /dev/null and b/net452/SiteServer.Web/Home/assets/fonts/fontawesome-webfont.woff differ diff --git a/net452/SiteServer.Web/Home/assets/fonts/fontawesome-webfont.woff2 b/net452/SiteServer.Web/Home/assets/fonts/fontawesome-webfont.woff2 new file mode 100644 index 000000000..4d13fc604 Binary files /dev/null and b/net452/SiteServer.Web/Home/assets/fonts/fontawesome-webfont.woff2 differ diff --git a/SiteServer.Web/SiteServer/assets/fonts/ionicons.eot b/net452/SiteServer.Web/Home/assets/fonts/ionicons.eot similarity index 100% rename from SiteServer.Web/SiteServer/assets/fonts/ionicons.eot rename to net452/SiteServer.Web/Home/assets/fonts/ionicons.eot diff --git a/SiteServer.Web/SiteServer/assets/fonts/ionicons.svg b/net452/SiteServer.Web/Home/assets/fonts/ionicons.svg similarity index 100% rename from SiteServer.Web/SiteServer/assets/fonts/ionicons.svg rename to net452/SiteServer.Web/Home/assets/fonts/ionicons.svg diff --git a/SiteServer.Web/SiteServer/assets/fonts/ionicons.ttf b/net452/SiteServer.Web/Home/assets/fonts/ionicons.ttf similarity index 100% rename from SiteServer.Web/SiteServer/assets/fonts/ionicons.ttf rename to net452/SiteServer.Web/Home/assets/fonts/ionicons.ttf diff --git a/SiteServer.Web/SiteServer/assets/fonts/ionicons.woff b/net452/SiteServer.Web/Home/assets/fonts/ionicons.woff similarity index 100% rename from SiteServer.Web/SiteServer/assets/fonts/ionicons.woff rename to net452/SiteServer.Web/Home/assets/fonts/ionicons.woff diff --git a/SiteServer.Web/SiteFiles/UserFiles/default_avatar.png b/net452/SiteServer.Web/Home/assets/images/default_avatar.png similarity index 100% rename from SiteServer.Web/SiteFiles/UserFiles/default_avatar.png rename to net452/SiteServer.Web/Home/assets/images/default_avatar.png diff --git a/net452/SiteServer.Web/Home/assets/images/favicon.ico b/net452/SiteServer.Web/Home/assets/images/favicon.ico new file mode 100644 index 000000000..be4e31226 Binary files /dev/null and b/net452/SiteServer.Web/Home/assets/images/favicon.ico differ diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading1.gif b/net452/SiteServer.Web/Home/assets/images/loading.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading1.gif rename to net452/SiteServer.Web/Home/assets/images/loading.gif diff --git a/net452/SiteServer.Web/Home/assets/js/index.js b/net452/SiteServer.Web/Home/assets/js/index.js new file mode 100644 index 000000000..ef89de4e1 --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/js/index.js @@ -0,0 +1,85 @@ +new Vue({ + el: '#main', + data: { + pageUser: null, + pageConfig: null, + pageMenus: null, + defaultPageUrl: null, + + pageUrl: null, + elTopnav: null, + elFrmMain: null, + avatarUrl: null + }, + methods: { + load: function (pageUser, pageConfig, pageMenus, defaultPageUrl) { + var $this = this; + this.pageUser = pageUser; + this.pageConfig = pageConfig; + this.pageMenus = pageMenus; + this.defaultPageUrl = defaultPageUrl; + + this.avatarUrl = this.pageUser.avatarUrl || this.pageConfig.homeDefaultAvatarUrl || 'assets/images/default_avatar.png'; + this.pageUrl = this.getPageUrl(); + window.onresize = this.resize; + setTimeout(function () { + $this.ready(); + $this.resize(); + }, 100); + }, + ready: function () { + var $this = this; + this.elTopnav = $('#topnav'); + this.elFrmMain = $('#frmMain'); + + $('.navbar-toggle').on('click', function () { + $(this).toggleClass('open'); + $('#navigation').slideToggle(400); + }); + + $('.navigation-menu>li').slice(-2).addClass('last-elements'); + + $('.navigation-menu li.has-submenu a[href="#"]').on('click', function (e) { + if ($(window).width() < 992) { + e.preventDefault(); + $(this).parent('li').toggleClass('open').find('.submenu:first').toggleClass('open'); + } + }); + + $(window).on('hashchange', function () { + $this.pageUrl = $this.getPageUrl(); + }); + }, + resize: function () { + var topHeight = this.elTopnav.height(); + this.elFrmMain.css({ + top: topHeight + 'px', + minHeight: ($(window).height() - topHeight) + 'px', + display: 'block' + }).iFrameResize({ + log: false + }); + }, + getPageUrl: function () { + if (location.hash && location.hash.length > 1) { + return location.hash.substr(1, location.hash.length - 1); + } else { + return this.defaultPageUrl || 'pages/dashboard.html'; + } + } + }, + created: function () { + var $this = this; + utils.getConfig('index', function (res) { + if (res.value) { + $this.load(res.value, res.config, res.menus, res.defaultPageUrl); + } else { + location.href = 'pages/login.html?returnUrl=' + encodeURIComponent(location.href); + } + }, true); + } +}); + +var getContentWindow = function () { + return document.getElementById('frmMain').contentWindow; +}; \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/assets/js/utils.js b/net452/SiteServer.Web/Home/assets/js/utils.js new file mode 100644 index 000000000..7787b7480 --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/js/utils.js @@ -0,0 +1,364 @@ +var config = { + apiUrl: '../api' +}; + +var swal2 = swal.mixin({ + confirmButtonClass: 'btn btn-primary', + cancelButtonClass: 'btn btn-default ml-2', + buttonsStyling: false, +}); + +VeeValidate.Validator.localize('zh_CN'); +Vue.use(VeeValidate); +VeeValidate.Validator.localize({ + zh_CN: { + messages: { + required: function (name) { + return name + '不能为空'; + } + } + } +}); +VeeValidate.Validator.extend('mobile', { + getMessage: function () { + return ' 请输入正确的手机号码'; + }, + validate: function (value, args) { + return ( + value.length == 11 && + /^((13|14|15|16|17|18|19)[0-9]{1}\d{8})$/.test(value) + ); + } +}); + +var utils = { + Api: function (path, isRoot) { + this.apiUrl = utils.getApiUrl(path, isRoot); + + this._getURL = function (url, data, method) { + url += /\?/.test(url) ? '&' : '?'; + if (typeof data === 'object' && method === 'GET') { + var pairs = []; + for (var prop in data) { + if (data.hasOwnProperty(prop)) { + var k = encodeURIComponent(prop), + v = encodeURIComponent(data[prop]); + pairs.push(k + '=' + v); + } + } + url += '&' + pairs.join('&'); + } + return (url + '&' + new Date().getTime()).replace('?&', '?'); + }; + + this.request = function (method, path, data, cb) { + var xhr = new XMLHttpRequest(); + xhr.open(method, this._getURL(path, data, method), true); + xhr.withCredentials = true; + if (cb) { + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + if (xhr.status < 400) { + cb(null, utils.parse(xhr.responseText), xhr.status); + } else { + var err = utils.parse(xhr.responseText); + cb({ + status: xhr.status, + message: err.message || utils.errorCode(xhr.status) + }, + null, + xhr.status + ); + } + } + }; + } + + xhr.dataType = 'json'; + xhr.setRequestHeader( + 'Accept', + 'application/vnd.siteserver+json; version=1' + ); + xhr.setRequestHeader('Content-Type', 'application/json;charset=UTF-8'); + if (data) { + xhr.send(JSON.stringify(data)); + } else { + xhr.send(); + } + }; + + this.get = function (data, cb, path) { + var url = this.apiUrl; + if (path) { + url += '/' + path; + } + return this.request('GET', url, data, cb); + }; + + this.post = function (data, cb, path) { + var url = this.apiUrl; + if (path) { + url += '/' + path; + } + return this.request('POST', url, data, cb); + }; + + this.put = function (data, cb, path) { + var url = this.apiUrl; + if (path) { + url += '/' + path; + } + return this.request('PUT', url, data, cb); + }; + + this.delete = function (data, cb, path) { + var url = this.apiUrl; + if (path) { + url += '/' + path; + } + return this.request('DELETE', url, data, cb); + }; + + this.patch = function (data, cb, path) { + var url = this.apiUrl; + if (path) { + url += '/' + path; + } + return this.request('PATCH', url, data, cb); + }; + }, + + getApiUrl: function (path, isRoot) { + var apiUrl = _.trimEnd(config.apiUrl, '/'); + if (!isRoot && apiUrl.indexOf('..') !== -1) { + apiUrl = '../' + apiUrl; + } + if (!path) return apiUrl; + return apiUrl + '/' + _.trimStart(path, '/'); + }, + + getPageAlert: function (error) { + var message = error.message; + if (error.response) { + if (error.response.status === 401) { + message = '检测到用户未登录或者登录已超时,请重新登录'; + } else if (error.response.data) { + if (error.response.data.exceptionMessage) { + message = error.response.data.exceptionMessage; + } else if (error.response.data.message) { + message = error.response.data.message; + } + } + } + + return { + type: "danger", + html: message + }; + }, + + parse: function (responseText) { + try { + return responseText ? JSON.parse(responseText) : {}; + } catch (e) { + return {}; + } + }, + + errorCode: function (status) { + switch (status) { + case 400: + return 'Bad Request'; + case 401: + return 'Unauthorized'; + case 402: + return 'Payment Required'; + case 403: + return 'Forbidden'; + case 404: + return 'Not Found'; + case 405: + return 'Method Not Allowed'; + case 406: + return 'Not Acceptable'; + case 407: + return 'Proxy Authentication Required'; + case 408: + return 'Request Timeout'; + case 409: + return 'Conflict'; + case 410: + return 'Gone'; + case 411: + return 'Length Required'; + case 500: + return 'Internal Server Error'; + } + return 'Unknown Error'; + }, + + getQueryString: function (name) { + var result = location.search.match( + new RegExp('[?&]' + name + '=([^&]+)', 'i') + ); + if (!result || result.length < 1) { + return ''; + } + return decodeURIComponent(result[1]); + }, + + getToken: function () { + return Cookies.get('SS-USER-TOKEN-CLIENT'); + }, + + setToken: function (accessToken, expiresAt) { + Cookies.set('SS-USER-TOKEN-CLIENT', accessToken, { + expires: new Date(expiresAt) + }); + }, + + removeToken: function () { + Cookies.remove('SS-USER-TOKEN-CLIENT'); + }, + + redirectLogin: function () { + if (location.hash) { + location.href = 'pages/login.html'; + } else { + top.location.hash = 'pages/login.html'; + } + }, + + loading: function (isLoading) { + if (isLoading) { + return layer.load(1, { + shade: [0.2, '#000'] + }); + } else { + layer.close(layer.index); + } + }, + + scrollToTop: function () { + document.documentElement.scrollTop = document.body.scrollTop = 0; + }, + + closeLayer: function () { + parent.layer.closeAll(); + return false; + }, + + openLayer: function (config) { + if (!config || !config.url) return false; + + if (!config.width) { + config.width = $(window).width() - 50; + } + if (!config.height) { + config.height = $(window).height() - 50; + } + + if (config.full) { + config.width = $(window).width() - 50; + config.height = $(window).height() - 50; + } + + layer.open({ + type: 2, + btn: null, + title: config.title, + area: [config.width + 'px', config.height + 'px'], + maxmin: true, + resize: true, + shadeClose: true, + content: config.url + }); + + return false; + }, + + openImagesLayer: function (imageUrls) { + var data = []; + for (var i = 0; i < imageUrls.length; i++) { + var imageUrl = imageUrls[i]; + data.push({ + src: imageUrl, //原图地址 + thumb: imageUrl //缩略图地址 + }); + } + layer.photos({ + photos: { + data: data + }, + anim: 5 + }); + }, + + getConfig: function (params, callback, isRoot) { + var api = new utils.Api('/home', isRoot); + if (typeof params === 'string') { + params = { + pageName: params + }; + } + api.get(params, function (err, res) { + if (err) { + api.get(params, function (err, res) { + if (err) return utils.alertError(err); + if (res.config.isHomeClosed) { + swal2({ + title: '用户中心已关闭!', + type: 'error', + showConfirmButton: false, + allowOutsideClick: false, + allowEscapeKey: false + }); + } + callback(res); + }); + } + if (res.config.isHomeClosed) { + swal2({ + title: '用户中心已关闭!', + text: ' ', + type: 'error', + showConfirmButton: false, + allowOutsideClick: false, + allowEscapeKey: false + }); + } + callback(res); + }); + }, + + alertError: function (err) { + swal2({ + title: '系统错误!', + text: '请联系管理员协助解决', + type: 'error', + showConfirmButton: false, + allowOutsideClick: false, + allowEscapeKey: false + }); + }, + + alertDelete: function (config) { + if (!config) return false; + + swal2({ + title: config.title, + text: config.text, + type: 'question', + confirmButtonText: '确认删除', + confirmButtonClass: 'btn btn-danger', + showCancelButton: true, + cancelButtonText: '取 消' + }).then(function (result) { + if (result.value) { + config.callback(); + } + }); + + return false; + } +}; \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/assets/lib/axios-0.17.1.min.js b/net452/SiteServer.Web/Home/assets/lib/axios-0.17.1.min.js new file mode 100644 index 000000000..c27e70b23 --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/lib/axios-0.17.1.min.js @@ -0,0 +1,9 @@ +/* axios v0.17.1 | (c) 2017 by Matt Zabriskie */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.axios=t():e.axios=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";function r(e){var t=new s(e),n=i(s.prototype.request,t);return o.extend(n,s.prototype,t),o.extend(n,t),n}var o=n(2),i=n(3),s=n(5),u=n(6),a=r(u);a.Axios=s,a.create=function(e){return r(o.merge(u,e))},a.Cancel=n(23),a.CancelToken=n(24),a.isCancel=n(20),a.all=function(e){return Promise.all(e)},a.spread=n(25),e.exports=a,e.exports.default=a},function(e,t,n){"use strict";function r(e){return"[object Array]"===R.call(e)}function o(e){return"[object ArrayBuffer]"===R.call(e)}function i(e){return"undefined"!=typeof FormData&&e instanceof FormData}function s(e){var t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer}function u(e){return"string"==typeof e}function a(e){return"number"==typeof e}function c(e){return"undefined"==typeof e}function f(e){return null!==e&&"object"==typeof e}function p(e){return"[object Date]"===R.call(e)}function d(e){return"[object File]"===R.call(e)}function l(e){return"[object Blob]"===R.call(e)}function h(e){return"[object Function]"===R.call(e)}function m(e){return f(e)&&h(e.pipe)}function y(e){return"undefined"!=typeof URLSearchParams&&e instanceof URLSearchParams}function w(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}function g(){return("undefined"==typeof navigator||"ReactNative"!==navigator.product)&&("undefined"!=typeof window&&"undefined"!=typeof document)}function v(e,t){if(null!==e&&"undefined"!=typeof e)if("object"!=typeof e&&(e=[e]),r(e))for(var n=0,o=e.length;n + * @license MIT + */ +e.exports=function(e){return null!=e&&(n(e)||r(e)||!!e._isBuffer)}},function(e,t,n){"use strict";function r(e){this.defaults=e,this.interceptors={request:new s,response:new s}}var o=n(6),i=n(2),s=n(17),u=n(18);r.prototype.request=function(e){"string"==typeof e&&(e=i.merge({url:arguments[0]},arguments[1])),e=i.merge(o,this.defaults,{method:"get"},e),e.method=e.method.toLowerCase();var t=[u,void 0],n=Promise.resolve(e);for(this.interceptors.request.forEach(function(e){t.unshift(e.fulfilled,e.rejected)}),this.interceptors.response.forEach(function(e){t.push(e.fulfilled,e.rejected)});t.length;)n=n.then(t.shift(),t.shift());return n},i.forEach(["delete","get","head","options"],function(e){r.prototype[e]=function(t,n){return this.request(i.merge(n||{},{method:e,url:t}))}}),i.forEach(["post","put","patch"],function(e){r.prototype[e]=function(t,n,r){return this.request(i.merge(r||{},{method:e,url:t,data:n}))}}),e.exports=r},function(e,t,n){"use strict";function r(e,t){!i.isUndefined(e)&&i.isUndefined(e["Content-Type"])&&(e["Content-Type"]=t)}function o(){var e;return"undefined"!=typeof XMLHttpRequest?e=n(8):"undefined"!=typeof process&&(e=n(8)),e}var i=n(2),s=n(7),u={"Content-Type":"application/x-www-form-urlencoded"},a={adapter:o(),transformRequest:[function(e,t){return s(t,"Content-Type"),i.isFormData(e)||i.isArrayBuffer(e)||i.isBuffer(e)||i.isStream(e)||i.isFile(e)||i.isBlob(e)?e:i.isArrayBufferView(e)?e.buffer:i.isURLSearchParams(e)?(r(t,"application/x-www-form-urlencoded;charset=utf-8"),e.toString()):i.isObject(e)?(r(t,"application/json;charset=utf-8"),JSON.stringify(e)):e}],transformResponse:[function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(e){}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,validateStatus:function(e){return e>=200&&e<300}};a.headers={common:{Accept:"application/json, text/plain, */*"}},i.forEach(["delete","get","head"],function(e){a.headers[e]={}}),i.forEach(["post","put","patch"],function(e){a.headers[e]=i.merge(u)}),e.exports=a},function(e,t,n){"use strict";var r=n(2);e.exports=function(e,t){r.forEach(e,function(n,r){r!==t&&r.toUpperCase()===t.toUpperCase()&&(e[t]=n,delete e[r])})}},function(e,t,n){"use strict";var r=n(2),o=n(9),i=n(12),s=n(13),u=n(14),a=n(10),c="undefined"!=typeof window&&window.btoa&&window.btoa.bind(window)||n(15);e.exports=function(e){return new Promise(function(t,f){var p=e.data,d=e.headers;r.isFormData(p)&&delete d["Content-Type"];var l=new XMLHttpRequest,h="onreadystatechange",m=!1;if("undefined"==typeof window||!window.XDomainRequest||"withCredentials"in l||u(e.url)||(l=new window.XDomainRequest,h="onload",m=!0,l.onprogress=function(){},l.ontimeout=function(){}),e.auth){var y=e.auth.username||"",w=e.auth.password||"";d.Authorization="Basic "+c(y+":"+w)}if(l.open(e.method.toUpperCase(),i(e.url,e.params,e.paramsSerializer),!0),l.timeout=e.timeout,l[h]=function(){if(l&&(4===l.readyState||m)&&(0!==l.status||l.responseURL&&0===l.responseURL.indexOf("file:"))){var n="getAllResponseHeaders"in l?s(l.getAllResponseHeaders()):null,r=e.responseType&&"text"!==e.responseType?l.response:l.responseText,i={data:r,status:1223===l.status?204:l.status,statusText:1223===l.status?"No Content":l.statusText,headers:n,config:e,request:l};o(t,f,i),l=null}},l.onerror=function(){f(a("Network Error",e,null,l)),l=null},l.ontimeout=function(){f(a("timeout of "+e.timeout+"ms exceeded",e,"ECONNABORTED",l)),l=null},r.isStandardBrowserEnv()){var g=n(16),v=(e.withCredentials||u(e.url))&&e.xsrfCookieName?g.read(e.xsrfCookieName):void 0;v&&(d[e.xsrfHeaderName]=v)}if("setRequestHeader"in l&&r.forEach(d,function(e,t){"undefined"==typeof p&&"content-type"===t.toLowerCase()?delete d[t]:l.setRequestHeader(t,e)}),e.withCredentials&&(l.withCredentials=!0),e.responseType)try{l.responseType=e.responseType}catch(t){if("json"!==e.responseType)throw t}"function"==typeof e.onDownloadProgress&&l.addEventListener("progress",e.onDownloadProgress),"function"==typeof e.onUploadProgress&&l.upload&&l.upload.addEventListener("progress",e.onUploadProgress),e.cancelToken&&e.cancelToken.promise.then(function(e){l&&(l.abort(),f(e),l=null)}),void 0===p&&(p=null),l.send(p)})}},function(e,t,n){"use strict";var r=n(10);e.exports=function(e,t,n){var o=n.config.validateStatus;n.status&&o&&!o(n.status)?t(r("Request failed with status code "+n.status,n.config,null,n.request,n)):e(n)}},function(e,t,n){"use strict";var r=n(11);e.exports=function(e,t,n,o,i){var s=new Error(e);return r(s,t,n,o,i)}},function(e,t){"use strict";e.exports=function(e,t,n,r,o){return e.config=t,n&&(e.code=n),e.request=r,e.response=o,e}},function(e,t,n){"use strict";function r(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}var o=n(2);e.exports=function(e,t,n){if(!t)return e;var i;if(n)i=n(t);else if(o.isURLSearchParams(t))i=t.toString();else{var s=[];o.forEach(t,function(e,t){null!==e&&"undefined"!=typeof e&&(o.isArray(e)&&(t+="[]"),o.isArray(e)||(e=[e]),o.forEach(e,function(e){o.isDate(e)?e=e.toISOString():o.isObject(e)&&(e=JSON.stringify(e)),s.push(r(t)+"="+r(e))}))}),i=s.join("&")}return i&&(e+=(e.indexOf("?")===-1?"?":"&")+i),e}},function(e,t,n){"use strict";var r=n(2),o=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"];e.exports=function(e){var t,n,i,s={};return e?(r.forEach(e.split("\n"),function(e){if(i=e.indexOf(":"),t=r.trim(e.substr(0,i)).toLowerCase(),n=r.trim(e.substr(i+1)),t){if(s[t]&&o.indexOf(t)>=0)return;"set-cookie"===t?s[t]=(s[t]?s[t]:[]).concat([n]):s[t]=s[t]?s[t]+", "+n:n}}),s):s}},function(e,t,n){"use strict";var r=n(2);e.exports=r.isStandardBrowserEnv()?function(){function e(e){var t=e;return n&&(o.setAttribute("href",t),t=o.href),o.setAttribute("href",t),{href:o.href,protocol:o.protocol?o.protocol.replace(/:$/,""):"",host:o.host,search:o.search?o.search.replace(/^\?/,""):"",hash:o.hash?o.hash.replace(/^#/,""):"",hostname:o.hostname,port:o.port,pathname:"/"===o.pathname.charAt(0)?o.pathname:"/"+o.pathname}}var t,n=/(msie|trident)/i.test(navigator.userAgent),o=document.createElement("a");return t=e(window.location.href),function(n){var o=r.isString(n)?e(n):n;return o.protocol===t.protocol&&o.host===t.host}}():function(){return function(){return!0}}()},function(e,t){"use strict";function n(){this.message="String contains an invalid character"}function r(e){for(var t,r,i=String(e),s="",u=0,a=o;i.charAt(0|u)||(a="=",u%1);s+=a.charAt(63&t>>8-u%1*8)){if(r=i.charCodeAt(u+=.75),r>255)throw new n;t=t<<8|r}return s}var o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";n.prototype=new Error,n.prototype.code=5,n.prototype.name="InvalidCharacterError",e.exports=r},function(e,t,n){"use strict";var r=n(2);e.exports=r.isStandardBrowserEnv()?function(){return{write:function(e,t,n,o,i,s){var u=[];u.push(e+"="+encodeURIComponent(t)),r.isNumber(n)&&u.push("expires="+new Date(n).toGMTString()),r.isString(o)&&u.push("path="+o),r.isString(i)&&u.push("domain="+i),s===!0&&u.push("secure"),document.cookie=u.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}()},function(e,t,n){"use strict";function r(){this.handlers=[]}var o=n(2);r.prototype.use=function(e,t){return this.handlers.push({fulfilled:e,rejected:t}),this.handlers.length-1},r.prototype.eject=function(e){this.handlers[e]&&(this.handlers[e]=null)},r.prototype.forEach=function(e){o.forEach(this.handlers,function(t){null!==t&&e(t)})},e.exports=r},function(e,t,n){"use strict";function r(e){e.cancelToken&&e.cancelToken.throwIfRequested()}var o=n(2),i=n(19),s=n(20),u=n(6),a=n(21),c=n(22);e.exports=function(e){r(e),e.baseURL&&!a(e.url)&&(e.url=c(e.baseURL,e.url)),e.headers=e.headers||{},e.data=i(e.data,e.headers,e.transformRequest),e.headers=o.merge(e.headers.common||{},e.headers[e.method]||{},e.headers||{}),o.forEach(["delete","get","head","post","put","patch","common"],function(t){delete e.headers[t]});var t=e.adapter||u.adapter;return t(e).then(function(t){return r(e),t.data=i(t.data,t.headers,e.transformResponse),t},function(t){return s(t)||(r(e),t&&t.response&&(t.response.data=i(t.response.data,t.response.headers,e.transformResponse))),Promise.reject(t)})}},function(e,t,n){"use strict";var r=n(2);e.exports=function(e,t,n){return r.forEach(n,function(n){e=n(e,t)}),e}},function(e,t){"use strict";e.exports=function(e){return!(!e||!e.__CANCEL__)}},function(e,t){"use strict";e.exports=function(e){return/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(e)}},function(e,t){"use strict";e.exports=function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}},function(e,t){"use strict";function n(e){this.message=e}n.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},n.prototype.__CANCEL__=!0,e.exports=n},function(e,t,n){"use strict";function r(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise(function(e){t=e});var n=this;e(function(e){n.reason||(n.reason=new o(e),t(n.reason))})}var o=n(23);r.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},r.source=function(){var e,t=new r(function(t){e=t});return{token:t,cancel:e}},e.exports=r},function(e,t){"use strict";e.exports=function(e){return function(t){return e.apply(null,t)}}}])}); +//# sourceMappingURL=axios.min.map \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/assets/lib/bootstrap.min.js b/net452/SiteServer.Web/Home/assets/lib/bootstrap.min.js new file mode 100644 index 000000000..eac9842d7 --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/lib/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.1.0 (https://getbootstrap.com/) + * Copyright 2011-2018 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e(t.bootstrap={},t.jQuery,t.Popper)}(this,function(t,e,c){"use strict";function i(t,e){for(var n=0;nthis._items.length-1||t<0))if(this._isSliding)P(this._element).one(Q.SLID,function(){return e.to(t)});else{if(n===t)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},t._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},t._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right
    ',trigger:"hover focus",title:"",delay:0,html:!(_e={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"}),selector:!(de={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)"}),placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent"},pe="out",ve={HIDE:"hide"+he,HIDDEN:"hidden"+he,SHOW:(me="show")+he,SHOWN:"shown"+he,INSERTED:"inserted"+he,CLICK:"click"+he,FOCUSIN:"focusin"+he,FOCUSOUT:"focusout"+he,MOUSEENTER:"mouseenter"+he,MOUSELEAVE:"mouseleave"+he},Ee="fade",ye="show",Te=".tooltip-inner",Ce=".arrow",Ie="hover",Ae="focus",De="click",be="manual",Se=function(){function i(t,e){if("undefined"==typeof c)throw new TypeError("Bootstrap tooltips require Popper.js (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var t=i.prototype;return t.enable=function(){this._isEnabled=!0},t.disable=function(){this._isEnabled=!1},t.toggleEnabled=function(){this._isEnabled=!this._isEnabled},t.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=oe(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),oe(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(oe(this.getTipElement()).hasClass(ye))return void this._leave(null,this);this._enter(null,this)}},t.dispose=function(){clearTimeout(this._timeout),oe.removeData(this.element,this.constructor.DATA_KEY),oe(this.element).off(this.constructor.EVENT_KEY),oe(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&oe(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},t.show=function(){var e=this;if("none"===oe(this.element).css("display"))throw new Error("Please use show on visible elements");var t=oe.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){oe(this.element).trigger(t);var n=oe.contains(this.element.ownerDocument.documentElement,this.element);if(t.isDefaultPrevented()||!n)return;var i=this.getTipElement(),r=Cn.getUID(this.constructor.NAME);i.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&oe(i).addClass(Ee);var s="function"==typeof this.config.placement?this.config.placement.call(this,i,this.element):this.config.placement,o=this._getAttachment(s);this.addAttachmentClass(o);var a=!1===this.config.container?document.body:oe(this.config.container);oe(i).data(this.constructor.DATA_KEY,this),oe.contains(this.element.ownerDocument.documentElement,this.tip)||oe(i).appendTo(a),oe(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new c(this.element,i,{placement:o,modifiers:{offset:{offset:this.config.offset},flip:{behavior:this.config.fallbackPlacement},arrow:{element:Ce},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){e._handlePopperPlacementChange(t)}}),oe(i).addClass(ye),"ontouchstart"in document.documentElement&&oe(document.body).children().on("mouseover",null,oe.noop);var l=function(){e.config.animation&&e._fixTransition();var t=e._hoverState;e._hoverState=null,oe(e.element).trigger(e.constructor.Event.SHOWN),t===pe&&e._leave(null,e)};if(oe(this.tip).hasClass(Ee)){var h=Cn.getTransitionDurationFromElement(this.tip);oe(this.tip).one(Cn.TRANSITION_END,l).emulateTransitionEnd(h)}else l()}},t.hide=function(t){var e=this,n=this.getTipElement(),i=oe.Event(this.constructor.Event.HIDE),r=function(){e._hoverState!==me&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),oe(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(oe(this.element).trigger(i),!i.isDefaultPrevented()){if(oe(n).removeClass(ye),"ontouchstart"in document.documentElement&&oe(document.body).children().off("mouseover",null,oe.noop),this._activeTrigger[De]=!1,this._activeTrigger[Ae]=!1,this._activeTrigger[Ie]=!1,oe(this.tip).hasClass(Ee)){var s=Cn.getTransitionDurationFromElement(n);oe(n).one(Cn.TRANSITION_END,r).emulateTransitionEnd(s)}else r();this._hoverState=""}},t.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},t.isWithContent=function(){return Boolean(this.getTitle())},t.addAttachmentClass=function(t){oe(this.getTipElement()).addClass(ue+"-"+t)},t.getTipElement=function(){return this.tip=this.tip||oe(this.config.template)[0],this.tip},t.setContent=function(){var t=oe(this.getTipElement());this.setElementContent(t.find(Te),this.getTitle()),t.removeClass(Ee+" "+ye)},t.setElementContent=function(t,e){var n=this.config.html;"object"==typeof e&&(e.nodeType||e.jquery)?n?oe(e).parent().is(t)||t.empty().append(e):t.text(oe(e).text()):t[n?"html":"text"](e)},t.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},t._getAttachment=function(t){return _e[t.toUpperCase()]},t._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(t){if("click"===t)oe(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(t){return i.toggle(t)});else if(t!==be){var e=t===Ie?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=t===Ie?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;oe(i.element).on(e,i.config.selector,function(t){return i._enter(t)}).on(n,i.config.selector,function(t){return i._leave(t)})}oe(i.element).closest(".modal").on("hide.bs.modal",function(){return i.hide()})}),this.config.selector?this.config=h({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},t._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},t._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||oe(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),oe(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Ae:Ie]=!0),oe(e.getTipElement()).hasClass(ye)||e._hoverState===me?e._hoverState=me:(clearTimeout(e._timeout),e._hoverState=me,e.config.delay&&e.config.delay.show?e._timeout=setTimeout(function(){e._hoverState===me&&e.show()},e.config.delay.show):e.show())},t._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||oe(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),oe(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Ae:Ie]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=pe,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(function(){e._hoverState===pe&&e.hide()},e.config.delay.hide):e.hide())},t._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},t._getConfig=function(t){return"number"==typeof(t=h({},this.constructor.Default,oe(this.element).data(),t)).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),Cn.typeCheckConfig(ae,t,this.constructor.DefaultType),t},t._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},t._cleanTipClass=function(){var t=oe(this.getTipElement()),e=t.attr("class").match(fe);null!==e&&0

    '}),He=h({},Nn.DefaultType,{content:"(string|element|function)"}),We="fade",xe=".popover-header",Ue=".popover-body",Ke={HIDE:"hide"+ke,HIDDEN:"hidden"+ke,SHOW:(Me="show")+ke,SHOWN:"shown"+ke,INSERTED:"inserted"+ke,CLICK:"click"+ke,FOCUSIN:"focusin"+ke,FOCUSOUT:"focusout"+ke,MOUSEENTER:"mouseenter"+ke,MOUSELEAVE:"mouseleave"+ke},Fe=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),(e.prototype.constructor=e).__proto__=n;var r=i.prototype;return r.isWithContent=function(){return this.getTitle()||this._getContent()},r.addAttachmentClass=function(t){we(this.getTipElement()).addClass(Le+"-"+t)},r.getTipElement=function(){return this.tip=this.tip||we(this.config.template)[0],this.tip},r.setContent=function(){var t=we(this.getTipElement());this.setElementContent(t.find(xe),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(Ue),e),t.removeClass(We+" "+Me)},r._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},r._cleanTipClass=function(){var t=we(this.getTipElement()),e=t.attr("class").match(je);null!==e&&0=this._offsets[r]&&("undefined"==typeof this._offsets[r+1]||tt.width?3===e?r=t.height*h:s=t.width/h:3===e?s=t.width/h:r=t.height*h;var c={aspectRatio:h,naturalWidth:n,naturalHeight:o,width:r,height:s};c.left=(t.width-r)/2,c.top=(t.height-s)/2,c.oldLeft=c.left,c.oldTop=c.top,this.canvasData=c,this.limited=1===e||2===e,this.limitCanvas(!0,!0),this.initialImageData=_({},i),this.initialCanvasData=_({},c)},limitCanvas:function(t,i){var e=this.options,a=this.containerData,n=this.canvasData,o=this.cropBoxData,h=e.viewMode,r=n.aspectRatio,s=this.cropped&&o;if(t){var c=Number(e.minCanvasWidth)||0,d=Number(e.minCanvasHeight)||0;1=a.width&&(n.minLeft=Math.min(0,p),n.maxLeft=Math.max(0,p)),n.height>=a.height&&(n.minTop=Math.min(0,m),n.maxTop=Math.max(0,m))))}else n.minLeft=-n.width,n.minTop=-n.height,n.maxLeft=a.width,n.maxTop=a.height},renderCanvas:function(t,i){var e=this.canvasData,a=this.imageData;if(i){var n=function(t){var i=t.width,e=t.height,a=t.degree;if(90==(a=Math.abs(a)%180))return{width:e,height:i};var n=a%90*Math.PI/180,o=Math.sin(n),h=Math.cos(n),r=i*h+e*o,s=i*o+e*h;return 90e.maxWidth||e.widthe.maxHeight||e.heighti.width?n.height=n.width/e:n.width=n.height*e),this.cropBoxData=n,this.limitCropBox(!0,!0),n.width=Math.min(Math.max(n.width,n.minWidth),n.maxWidth),n.height=Math.min(Math.max(n.height,n.minHeight),n.maxHeight),n.width=Math.max(n.minWidth,n.width*a),n.height=Math.max(n.minHeight,n.height*a),n.left=i.left+(i.width-n.width)/2,n.top=i.top+(i.height-n.height)/2,n.oldLeft=n.left,n.oldTop=n.top,this.initialCropBoxData=_({},n)},limitCropBox:function(t,i){var e=this.options,a=this.containerData,n=this.canvasData,o=this.cropBoxData,h=this.limited,r=e.aspectRatio;if(t){var s=Number(e.minCropBoxWidth)||0,c=Number(e.minCropBoxHeight)||0,d=h?Math.min(a.width,n.width,n.width+n.left,a.width-n.left):a.width,l=h?Math.min(a.height,n.height,n.height+n.top,a.height-n.top):a.height;s=Math.min(s,a.width),c=Math.min(c,a.height),r&&(s&&c?se.maxWidth||e.widthe.maxHeight||e.height=i.width&&e.height>=i.height?T:k),et(this.cropBox,_({width:e.width,height:e.height},Ct({translateX:e.left,translateY:e.top}))),this.cropped&&this.limited&&this.limitCanvas(!0,!0),this.disabled||this.output()},output:function(){this.preview(),ut(this.element,a,this.getData())}},Ht={initPreview:function(){var e=this.crossOrigin,t=this.options.preview,a=e?this.crossOriginUrl:this.url,i=document.createElement("img");if(e&&(i.crossOrigin=e),i.src=a,this.viewBox.appendChild(i),this.viewBoxImage=i,t){var n=t;"string"==typeof t?n=this.element.ownerDocument.querySelectorAll(t):t.querySelector&&(n=[t]),J(this.previews=n,function(t){var i=document.createElement("img");ct(t,g,{width:t.offsetWidth,height:t.offsetHeight,html:t.innerHTML}),e&&(i.crossOrigin=e),i.src=a,i.style.cssText='display:block;width:100%;height:auto;min-width:0!important;min-height:0!important;max-width:none!important;max-height:none!important;image-orientation:0deg!important;"',t.innerHTML="",t.appendChild(i)})}},resetPreview:function(){J(this.previews,function(t){var i=st(t,g);et(t,{width:i.width,height:i.height}),t.innerHTML=i.html,dt(t,g)})},preview:function(){var r=this.imageData,t=this.canvasData,i=this.cropBoxData,s=i.width,c=i.height,d=r.width,l=r.height,p=i.left-t.left-r.left,m=i.top-t.top-r.top;this.cropped&&!this.disabled&&(et(this.viewBoxImage,_({width:d,height:l},Ct(_({translateX:-p,translateY:-m},r)))),J(this.previews,function(t){var i=st(t,g),e=i.width,a=i.height,n=e,o=a,h=1;s&&(o=c*(h=e/s)),c&&af&&(D.x=f-p);break;case H:s+D.xv&&(D.y=v-m)}};switch(h){case k:s+=D.x,c+=D.y;break;case N:if(0<=D.x&&(f<=p||r&&(c<=u||v<=m))){w=!1;break}B(N),(d+=D.x)<0&&(h=H,s-=d=-d),r&&(l=d/r,c+=(n.height-l)/2);break;case O:if(D.y<=0&&(c<=u||r&&(s<=g||f<=p))){w=!1;break}B(O),l-=D.y,c+=D.y,l<0&&(h=L,c-=l=-l),r&&(d=l*r,s+=(n.width-d)/2);break;case H:if(D.x<=0&&(s<=g||r&&(c<=u||v<=m))){w=!1;break}B(H),d-=D.x,s+=D.x,d<0&&(h=N,s-=d=-d),r&&(l=d/r,c+=(n.height-l)/2);break;case L:if(0<=D.y&&(v<=m||r&&(s<=g||f<=p))){w=!1;break}B(L),(l+=D.y)<0&&(h=O,c-=l=-l),r&&(d=l*r,s+=(n.width-d)/2);break;case z:if(r){if(D.y<=0&&(c<=u||f<=p)){w=!1;break}B(O),l-=D.y,c+=D.y,d=l*r}else B(O),B(N),0<=D.x?p or element.");this.element=t,this.options=_({},q,V(i)&&i),this.cropped=!1,this.disabled=!1,this.pointers={},this.ready=!1,this.reloading=!1,this.replaced=!1,this.sized=!1,this.sizing=!1,this.init()}return $(e,[{key:"init",value:function(){var t=this.element,i=t.tagName.toLowerCase(),e=void 0;if(!st(t,d)){if(ct(t,d,this),"img"===i){if(this.isImg=!0,e=t.getAttribute("src")||"",!(this.originalUrl=e))return;e=t.src}else"canvas"===i&&window.HTMLCanvasElement&&(e=t.toDataURL());this.load(e)}}},{key:"load",value:function(t){var i=this;if(t){this.url=t,this.imageData={};var e=this.element,a=this.options;if(a.rotatable||a.scalable||(a.checkOrientation=!1),a.checkOrientation&&window.ArrayBuffer)if(U.test(t))j.test(t)?this.read((n=t.replace(Tt,""),o=atob(n),h=new ArrayBuffer(o.length),J(r=new Uint8Array(h),function(t,i){r[i]=o.charCodeAt(i)}),h)):this.clone();else{var n,o,h,r,s=new XMLHttpRequest;this.reloading=!0,this.xhr=s;var c=function(){i.reloading=!1,i.xhr=null};s.ontimeout=c,s.onabort=c,s.onerror=function(){c(),i.clone()},s.onload=function(){c(),i.read(s.response)},a.checkCrossOrigin&&yt(t)&&e.crossOrigin&&(t=Mt(t)),s.open("get",t),s.responseType="arraybuffer",s.withCredentials="use-credentials"===e.crossOrigin,s.send()}else this.clone()}}},{key:"read",value:function(t){var i,e,a,n=this.options,o=this.imageData,h=Wt(t),r=0,s=1,c=1;if(1
    ';var o=n.querySelector("."+d+"-container"),h=o.querySelector("."+d+"-canvas"),r=o.querySelector("."+d+"-drag-box"),s=o.querySelector("."+d+"-crop-box"),c=s.querySelector("."+d+"-face");this.container=a,this.cropper=o,this.canvas=h,this.dragBox=r,this.cropBox=s,this.viewBox=o.querySelector("."+d+"-view-box"),this.face=c,h.appendChild(e),at(t,S),a.insertBefore(o,t.nextSibling),this.isImg||nt(e,l),this.initPreview(),this.bind(),i.initialAspectRatio=Math.max(0,i.initialAspectRatio)||NaN,i.aspectRatio=Math.max(0,i.aspectRatio)||NaN,i.viewMode=Math.max(0,Math.min(3,Math.round(i.viewMode)))||0,at(s,S),i.guides||at(s.getElementsByClassName(d+"-dashed"),S),i.center||at(s.getElementsByClassName(d+"-center"),S),i.background&&at(o,d+"-bg"),i.highlight||at(c,"cropper-invisible"),i.cropBoxMovable&&(at(c,p),ct(c,m,k)),i.cropBoxResizable||(at(s.getElementsByClassName(d+"-line"),S),at(s.getElementsByClassName(d+"-point"),S)),this.render(),this.ready=!0,this.setDragMode(i.dragMode),i.autoCrop&&this.crop(),this.setData(i.data),G(i.ready)&>(t,C,i.ready,{once:!0}),ut(t,C)}}},{key:"unbuild",value:function(){this.ready&&(this.ready=!1,this.unbind(),this.resetPreview(),this.cropper.parentNode.removeChild(this.cropper),nt(this.element,S))}},{key:"uncreate",value:function(){this.ready?(this.unbuild(),this.ready=!1,this.cropped=!1):this.sizing?(this.sizingImage.onload=null,this.sizing=!1,this.sized=!1):this.reloading?this.xhr.abort():this.image&&this.stop()}}],[{key:"noConflict",value:function(){return window.Cropper=Xt,e}},{key:"setDefaults",value:function(t){_(q,V(t)&&t)}}]),e}();return _(Rt.prototype,Nt,Ht,Lt,Ot,zt,Yt),Rt}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/assets/lib/es6-promise.auto.min.js b/net452/SiteServer.Web/Home/assets/lib/es6-promise.auto.min.js new file mode 100644 index 000000000..586ddb4bc --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/lib/es6-promise.auto.min.js @@ -0,0 +1 @@ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):t.ES6Promise=e()}(this,function(){"use strict";function t(t){var e=typeof t;return null!==t&&("object"===e||"function"===e)}function e(t){return"function"==typeof t}function n(t){B=t}function r(t){G=t}function o(){return function(){return process.nextTick(a)}}function i(){return"undefined"!=typeof z?function(){z(a)}:c()}function s(){var t=0,e=new J(a),n=document.createTextNode("");return e.observe(n,{characterData:!0}),function(){n.data=t=++t%2}}function u(){var t=new MessageChannel;return t.port1.onmessage=a,function(){return t.port2.postMessage(0)}}function c(){var t=setTimeout;return function(){return t(a,1)}}function a(){for(var t=0;t=i||i>ya?(e&&(clearTimeout(e),e=null),f=h,d=a.apply(b,c),e||(b=c=null)):e||(e=setTimeout(g,i)),d}}function g(a){return na+"["+pa+"] "+a}function h(a){ma&&"object"==typeof window.console&&console.log(g(a))}function i(a){"object"==typeof window.console&&console.warn(g(a))}function j(){k(),h("Initialising iFrame ("+location.href+")"),l(),o(),n("background",X),n("padding",_),B(),t(),u(),p(),D(),v(),ja=C(),O("init","Init message from host page"),Ea()}function k(){function b(a){return"true"===a?!0:!1}var c=ia.substr(oa).split(":");pa=c[0],Y=a!==c[1]?Number(c[1]):Y,aa=a!==c[2]?b(c[2]):aa,ma=a!==c[3]?b(c[3]):ma,ka=a!==c[4]?Number(c[4]):ka,V=a!==c[6]?b(c[6]):V,Z=c[7],ga=a!==c[8]?c[8]:ga,X=c[9],_=c[10],va=a!==c[11]?Number(c[11]):va,ja.enable=a!==c[12]?b(c[12]):!1,ra=a!==c[13]?c[13]:ra,Ba=a!==c[14]?c[14]:Ba}function l(){function a(){var a=window.iFrameResizer;h("Reading data from page: "+JSON.stringify(a)),Da="messageCallback"in a?a.messageCallback:Da,Ea="readyCallback"in a?a.readyCallback:Ea,ua="targetOrigin"in a?a.targetOrigin:ua,ga="heightCalculationMethod"in a?a.heightCalculationMethod:ga,Ba="widthCalculationMethod"in a?a.widthCalculationMethod:Ba}function b(a,b){return"function"==typeof a&&(h("Setup custom "+b+"CalcMethod"),Ga[b]=a,a="custom"),a}"iFrameResizer"in window&&Object===window.iFrameResizer.constructor&&(a(),ga=b(ga,"height"),Ba=b(Ba,"width")),h("TargetOrigin for parent set to: "+ua)}function m(a,b){return-1!==b.indexOf("-")&&(i("Negative CSS value ignored for "+a),b=""),b}function n(b,c){a!==c&&""!==c&&"null"!==c&&(document.body.style[b]=c,h("Body "+b+' set to "'+c+'"'))}function o(){a===Z&&(Z=Y+"px"),n("margin",m("margin",Z))}function p(){document.documentElement.style.height="",document.body.style.height="",h('HTML & body height set to "auto"')}function q(a){var b={add:function(b){function d(){O(a.eventName,a.eventType)}Ha[b]=d,c(window,b,d,{passive:!0})},remove:function(a){var b=Ha[a];delete Ha[a],d(window,a,b)}};a.eventNames&&Array.prototype.map?(a.eventName=a.eventNames[0],a.eventNames.map(b[a.method])):b[a.method](a.eventName),h(e(a.method)+" event listener: "+a.eventType)}function r(a){q({method:a,eventType:"Animation Start",eventNames:["animationstart","webkitAnimationStart"]}),q({method:a,eventType:"Animation Iteration",eventNames:["animationiteration","webkitAnimationIteration"]}),q({method:a,eventType:"Animation End",eventNames:["animationend","webkitAnimationEnd"]}),q({method:a,eventType:"Input",eventName:"input"}),q({method:a,eventType:"Mouse Up",eventName:"mouseup"}),q({method:a,eventType:"Mouse Down",eventName:"mousedown"}),q({method:a,eventType:"Orientation Change",eventName:"orientationchange"}),q({method:a,eventType:"Print",eventName:["afterprint","beforeprint"]}),q({method:a,eventType:"Ready State Change",eventName:"readystatechange"}),q({method:a,eventType:"Touch Start",eventName:"touchstart"}),q({method:a,eventType:"Touch End",eventName:"touchend"}),q({method:a,eventType:"Touch Cancel",eventName:"touchcancel"}),q({method:a,eventType:"Transition Start",eventNames:["transitionstart","webkitTransitionStart","MSTransitionStart","oTransitionStart","otransitionstart"]}),q({method:a,eventType:"Transition Iteration",eventNames:["transitioniteration","webkitTransitionIteration","MSTransitionIteration","oTransitionIteration","otransitioniteration"]}),q({method:a,eventType:"Transition End",eventNames:["transitionend","webkitTransitionEnd","MSTransitionEnd","oTransitionEnd","otransitionend"]}),"child"===ra&&q({method:a,eventType:"IFrame Resized",eventName:"resize"})}function s(a,b,c,d){return b!==a&&(a in c||(i(a+" is not a valid option for "+d+"CalculationMethod."),a=b),h(d+' calculation method set to "'+a+'"')),a}function t(){ga=s(ga,fa,Na,"height")}function u(){Ba=s(Ba,Aa,Oa,"width")}function v(){!0===V?(r("add"),G()):h("Auto Resize disabled")}function w(){h("Disable outgoing messages"),sa=!1}function x(){h("Remove event listener: Message"),d(window,"message",T)}function y(){null!==$&&$.disconnect()}function z(){r("remove"),y(),clearInterval(la)}function A(){w(),x(),!0===V&&z()}function B(){var a=document.createElement("div");a.style.clear="both",a.style.display="block",document.body.appendChild(a)}function C(){function b(){return{x:window.pageXOffset!==a?window.pageXOffset:document.documentElement.scrollLeft,y:window.pageYOffset!==a?window.pageYOffset:document.documentElement.scrollTop}}function d(a){var c=a.getBoundingClientRect(),d=b();return{x:parseInt(c.left,10)+parseInt(d.x,10),y:parseInt(c.top,10)+parseInt(d.y,10)}}function e(b){function c(a){var b=d(a);h("Moving to in page link (#"+e+") at x: "+b.x+" y: "+b.y),S(b.y,b.x,"scrollToOffset")}var e=b.split("#")[1]||b,f=decodeURIComponent(e),g=document.getElementById(f)||document.getElementsByName(f)[0];a!==g?c(g):(h("In page link (#"+e+") not found in iFrame, so sending to parent"),S(0,0,"inPageLink","#"+e))}function f(){""!==location.hash&&"#"!==location.hash&&e(location.href)}function g(){function a(a){function b(a){a.preventDefault(),e(this.getAttribute("href"))}"#"!==a.getAttribute("href")&&c(a,"click",b)}Array.prototype.forEach.call(document.querySelectorAll('a[href^="#"]'),a)}function j(){c(window,"hashchange",f)}function k(){setTimeout(f,ca)}function l(){Array.prototype.forEach&&document.querySelectorAll?(h("Setting up location.hash handlers"),g(),j(),k()):i("In page linking not fully supported in this browser! (See README.md for IE8 workaround)")}return ja.enable?l():h("In page linking not enabled"),{findTarget:e}}function D(){h("Enable public methods"),Ca.parentIFrame={autoResize:function(a){return!0===a&&!1===V?(V=!0,v()):!1===a&&!0===V&&(V=!1,z()),V},close:function(){S(0,0,"close"),A()},getId:function(){return pa},getPageInfo:function(a){"function"==typeof a?(Fa=a,S(0,0,"pageInfo")):(Fa=function(){},S(0,0,"pageInfoStop"))},moveToAnchor:function(a){ja.findTarget(a)},reset:function(){R("parentIFrame.reset")},scrollTo:function(a,b){S(b,a,"scrollTo")},scrollToOffset:function(a,b){S(b,a,"scrollToOffset")},sendMessage:function(a,b){S(0,0,"message",JSON.stringify(a),b)},setHeightCalculationMethod:function(a){ga=a,t()},setWidthCalculationMethod:function(a){Ba=a,u()},setTargetOrigin:function(a){h("Set targetOrigin: "+a),ua=a},size:function(a,b){var c=""+(a?a:"")+(b?","+b:"");O("size","parentIFrame.size("+c+")",a,b)}}}function E(){0!==ka&&(h("setInterval: "+ka+"ms"),la=setInterval(function(){O("interval","setInterval: "+ka)},Math.abs(ka)))}function F(){function b(a){function b(a){!1===a.complete&&(h("Attach listeners to "+a.src),a.addEventListener("load",f,!1),a.addEventListener("error",g,!1),k.push(a))}"attributes"===a.type&&"src"===a.attributeName?b(a.target):"childList"===a.type&&Array.prototype.forEach.call(a.target.querySelectorAll("img"),b)}function c(a){k.splice(k.indexOf(a),1)}function d(a){h("Remove listeners from "+a.src),a.removeEventListener("load",f,!1),a.removeEventListener("error",g,!1),c(a)}function e(b,c,e){d(b.target),O(c,e+": "+b.target.src,a,a)}function f(a){e(a,"imageLoad","Image loaded")}function g(a){e(a,"imageLoadFailed","Image load failed")}function i(a){O("mutationObserver","mutationObserver: "+a[0].target+" "+a[0].type),a.forEach(b)}function j(){var a=document.querySelector("body"),b={attributes:!0,attributeOldValue:!1,characterData:!0,characterDataOldValue:!1,childList:!0,subtree:!0};return m=new l(i),h("Create body MutationObserver"),m.observe(a,b),m}var k=[],l=window.MutationObserver||window.WebKitMutationObserver,m=j();return{disconnect:function(){"disconnect"in m&&(h("Disconnect body MutationObserver"),m.disconnect(),k.forEach(d))}}}function G(){var a=0>ka;window.MutationObserver||window.WebKitMutationObserver?a?E():$=F():(h("MutationObserver not supported in this browser!"),E())}function H(a,b){function c(a){var c=/^\d+(px)?$/i;if(c.test(a))return parseInt(a,W);var d=b.style.left,e=b.runtimeStyle.left;return b.runtimeStyle.left=b.currentStyle.left,b.style.left=a||0,a=b.style.pixelLeft,b.style.left=d,b.runtimeStyle.left=e,a}var d=0;return b=b||document.body,"defaultView"in document&&"getComputedStyle"in document.defaultView?(d=document.defaultView.getComputedStyle(b,null),d=null!==d?d[a]:0):d=c(b.currentStyle[a]),parseInt(d,W)}function I(a){a>ya/2&&(ya=2*a,h("Event throttle increased to "+ya+"ms"))}function J(a,b){for(var c=b.length,d=0,f=0,g=e(a),i=Ma(),j=0;c>j;j++)d=b[j].getBoundingClientRect()[a]+H("margin"+g,b[j]),d>f&&(f=d);return i=Ma()-i,h("Parsed "+c+" HTML elements"),h("Element position calculated in "+i+"ms"),I(i),f}function K(a){return[a.bodyOffset(),a.bodyScroll(),a.documentElementOffset(),a.documentElementScroll()]}function L(a,b){function c(){return i("No tagged elements ("+b+") found on page"),document.querySelectorAll("body *")}var d=document.querySelectorAll("["+b+"]");return 0===d.length&&c(),J(a,d)}function M(){return document.querySelectorAll("body *")}function N(b,c,d,e){function f(){ea=m,za=n,S(ea,za,b)}function g(){function b(a,b){var c=Math.abs(a-b)<=va;return!c}return m=a!==d?d:Na[ga](),n=a!==e?e:Oa[Ba](),b(ea,m)||aa&&b(za,n)}function i(){return!(b in{init:1,interval:1,size:1})}function j(){return ga in qa||aa&&Ba in qa}function k(){h("No change in size detected")}function l(){i()&&j()?R(c):b in{interval:1}||k()}var m,n;g()||"init"===b?(P(),f()):l()}function O(a,b,c,d){function e(){a in{reset:1,resetPage:1,init:1}||h("Trigger event: "+b)}function f(){return wa&&a in ba}f()?h("Trigger event cancelled: "+a):(e(),"init"===a?N(a,b,c,d):Pa(a,b,c,d))}function P(){wa||(wa=!0,h("Trigger event lock on")),clearTimeout(xa),xa=setTimeout(function(){wa=!1,h("Trigger event lock off"),h("--")},ca)}function Q(a){ea=Na[ga](),za=Oa[Ba](),S(ea,za,a)}function R(a){var b=ga;ga=fa,h("Reset trigger event: "+a),P(),Q("reset"),ga=b}function S(b,c,d,e,f){function g(){a===f?f=ua:h("Message targetOrigin: "+f)}function i(){var g=b+":"+c,i=pa+":"+g+":"+d+(a!==e?":"+e:"");h("Sending message to host page ("+i+")"),ta.postMessage(na+i,f)}!0===sa&&(g(),i())}function T(a){function b(){return na===(""+a.data).substr(0,oa)}function c(){return a.data.split("]")[1].split(":")[0]}function d(){return a.data.substr(a.data.indexOf(":")+1)}function e(){return!("undefined"!=typeof module&&module.exports)&&"iFrameResize"in window||"jQuery"in window&&"iFrameResize"in window.jQuery.prototype}function f(){return a.data.split(":")[2]in{"true":1,"false":1}}function g(){var b=c();b in l?l[b]():e()||f()||i("Unexpected message ("+a.data+")")}function k(){!1===da?g():f()?l.init():h('Ignored message of type "'+c()+'". Received before initialization.')}var l={init:function(){ia=a.data,ta=a.source,j(),da=!1,setTimeout(function(){ha=!1},ca)},reset:function(){ha?h("Page reset ignored by init"):(h("Page size reset by host page"),Q("resetPage"))},resize:function(){O("resizeParent","Parent window requested size check")},moveToAnchor:function(){ja.findTarget(d())},inPageLink:function(){this.moveToAnchor()},pageInfo:function(){var a=d();h("PageInfoFromParent called from parent: "+a),Fa(JSON.parse(a)),h(" --")},message:function(){var a=d();h("MessageCallback called from parent: "+a),Da(JSON.parse(a)),h(" --")}};b()&&k()}function U(){"loading"!==document.readyState&&window.parent.postMessage("[iFrameResizerChild]Ready","*")}if("undefined"!=typeof window){var V=!0,W=10,X="",Y=0,Z="",$=null,_="",aa=!1,ba={resize:1,click:1},ca=128,da=!0,ea=1,fa="bodyOffset",ga=fa,ha=!0,ia="",ja={},ka=32,la=null,ma=!1,na="[iFrameSizer]",oa=na.length,pa="",qa={max:1,min:1,bodyScroll:1,documentElementScroll:1},ra="child",sa=!0,ta=window.parent,ua="*",va=0,wa=!1,xa=null,ya=16,za=1,Aa="scroll",Ba=Aa,Ca=window,Da=function(){i("MessageCallback function not defined")},Ea=function(){},Fa=function(){},Ga={height:function(){return i("Custom height calculation function not defined"),document.documentElement.offsetHeight},width:function(){return i("Custom width calculation function not defined"),document.body.scrollWidth}},Ha={},Ia=!1,Ja=!1;try{var Ka=Object.create({},{passive:{get:function(){Ia=!0}},once:{get:function(){Ja=!0}}});window.addEventListener("test",b,Ka),window.removeEventListener("test",b,Ka)}catch(La){}var Ma=Date.now||function(){return(new Date).getTime()},Na={bodyOffset:function(){return document.body.offsetHeight+H("marginTop")+H("marginBottom")},offset:function(){return Na.bodyOffset()},bodyScroll:function(){return document.body.scrollHeight},custom:function(){return Ga.height()},documentElementOffset:function(){return document.documentElement.offsetHeight},documentElementScroll:function(){return document.documentElement.scrollHeight},max:function(){return Math.max.apply(null,K(Na))},min:function(){return Math.min.apply(null,K(Na))},grow:function(){return Na.max()},lowestElement:function(){return Math.max(Na.bodyOffset()||Na.documentElementOffset(),J("bottom",M()))},taggedElement:function(){return L("bottom","data-iframe-height")}},Oa={bodyScroll:function(){return document.body.scrollWidth},bodyOffset:function(){return document.body.offsetWidth},custom:function(){return Ga.width()},documentElementScroll:function(){return document.documentElement.scrollWidth},documentElementOffset:function(){return document.documentElement.offsetWidth},scroll:function(){return Math.max(Oa.bodyScroll(),Oa.documentElementScroll())},max:function(){return Math.max.apply(null,K(Oa))},min:function(){return Math.min.apply(null,K(Oa))},rightMostElement:function(){return J("right",M())},taggedElement:function(){return L("right","data-iframe-width")}},Pa=f(N);c(window,"message",T),c(window,"readystatechange",U),U()}}(); +//# sourceMappingURL=iframeResizer.contentWindow.map \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/assets/lib/iframe-resizer-3.6.2/iframeResizer.min.js b/net452/SiteServer.Web/Home/assets/lib/iframe-resizer-3.6.2/iframeResizer.min.js new file mode 100644 index 000000000..e95a0667f --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/lib/iframe-resizer-3.6.2/iframeResizer.min.js @@ -0,0 +1,9 @@ +/*! iFrame Resizer (iframeSizer.min.js ) - v3.6.2 - 2018-09-16 + * Desc: Force cross domain iframes to size to content. + * Requires: iframeResizer.contentWindow.min.js to be loaded into the target frame. + * Copyright: (c) 2018 David J. Bradshaw - dave@bradshaw.net + * License: MIT + */ + +!function(a){"use strict";function b(a,b,c){"addEventListener"in window?a.addEventListener(b,c,!1):"attachEvent"in window&&a.attachEvent("on"+b,c)}function c(a,b,c){"removeEventListener"in window?a.removeEventListener(b,c,!1):"detachEvent"in window&&a.detachEvent("on"+b,c)}function d(){var a,b=["moz","webkit","o","ms"];for(a=0;ae&&(e=c,h(V,"Set "+d+" to min value")),e>b&&(e=b,h(V,"Set "+d+" to max value")),U[d]=""+e}function g(){function b(){function a(){var a=0,b=!1;for(h(V,"Checking connection is from allowed list of origins: "+d);aR[y]["max"+a])throw new Error("Value for min"+a+" can not be greater than max"+a)}b("Height"),b("Width"),a("maxHeight"),a("minHeight"),a("maxWidth"),a("minWidth")}function f(){var a=d&&d.id||U.id+H++;return null!==document.getElementById(a)&&(a+=H++),a}function g(a){return T=a,""===a&&(c.id=a=f(),I=(d||{}).log,T=a,h(a,"Added missing iframe ID: "+a+" ("+c.src+")")),a}function i(){switch(h(y,"IFrame scrolling "+(R[y]&&R[y].scrolling?"enabled":"disabled")+" for "+y),c.style.overflow=!1===(R[y]&&R[y].scrolling)?"hidden":"auto",R[y]&&R[y].scrolling){case!0:c.scrolling="yes";break;case!1:c.scrolling="no";break;default:c.scrolling=R[y]?R[y].scrolling:"no"}}function k(){("number"==typeof(R[y]&&R[y].bodyMargin)||"0"===(R[y]&&R[y].bodyMargin))&&(R[y].bodyMarginV1=R[y].bodyMargin,R[y].bodyMargin=""+R[y].bodyMargin+"px")}function l(){var a=R[y]&&R[y].firstRun,b=R[y]&&R[y].heightCalculationMethod in Q;!a&&b&&s({iframe:c,height:0,width:0,type:"init"})}function m(){Function.prototype.bind&&R[y]&&(R[y].iframe.iFrameResizer={close:o.bind(null,R[y].iframe),removeListeners:n.bind(null,R[y].iframe),resize:v.bind(null,"Window resize","resize",R[y].iframe),moveToAnchor:function(a){v("Move to anchor","moveToAnchor:"+a,R[y].iframe,y)},sendMessage:function(a){a=JSON.stringify(a),v("Send Message","message:"+a,R[y].iframe,y)}})}function p(d){function e(){v("iFrame.onload",d,c,a,!0),l()}b(c,"load",e),v("init",d,c,a,!0)}function q(a){if("object"!=typeof a)throw new TypeError("Options is not an object")}function r(a){for(var b in U)U.hasOwnProperty(b)&&(R[y][b]=a.hasOwnProperty(b)?a[b]:U[b])}function t(a){return""===a||"file://"===a?"*":a}function u(a){a=a||{},R[y]={firstRun:!0,iframe:c,remoteHost:c.src.split("/").slice(0,3).join("/")},q(a),r(a),R[y]&&(R[y].targetOrigin=!0===R[y].checkOrigin?t(R[y].remoteHost):"*")}function x(){return y in R&&"iFrameResizer"in c}var y=g(c.id);x()?j(y,"Ignored iFrame, already setup."):(u(d),i(),e(),k(),p(w(y)),m())}function y(a,b){null===S&&(S=setTimeout(function(){S=null,a()},b))}function z(a,b,c){V[c]||(V[c]=setTimeout(function(){V[c]=null,a()},b))}function A(){function a(){function a(a){function b(b){return"0px"===(R[a]&&R[a].iframe.style[b])}function c(a){return null!==a.offsetParent}R[a]&&c(R[a].iframe)&&(b("height")||b("width"))&&v("Visibility change","resize",R[a].iframe,a)}for(var b in R)a(b)}function b(b){h("window","Mutation observed: "+b[0].target+" "+b[0].type),y(a,16)}function c(){var a=document.querySelector("body"),c={attributes:!0,attributeOldValue:!1,characterData:!0,characterDataOldValue:!1,childList:!0,subtree:!0},e=new d(b);e.observe(a,c)}var d=window.MutationObserver||window.WebKitMutationObserver;d&&c()}function B(a){function b(){D("Window "+a,"resize")}h("window","Trigger event: "+a),y(b,16)}function C(){function a(){D("Tab Visable","resize")}"hidden"!==document.visibilityState&&(h("document","Trigger event: Visiblity change"),y(a,16))}function D(a,b){function c(a){return R[a]&&"parent"===R[a].resizeFrom&&R[a].autoResize&&!R[a].firstRun}for(var d in R)c(d)&&v(a,b,document.getElementById(d),d)}function E(){b(window,"message",l),b(window,"resize",function(){B("resize")}),b(document,"visibilitychange",C),b(document,"-webkit-visibilitychange",C),b(window,"focusin",function(){B("focus")}),b(window,"focus",function(){B("focus")})}function F(){function b(a,b){function c(){if(!b.tagName)throw new TypeError("Object is not a valid DOM element");if("IFRAME"!==b.tagName.toUpperCase())throw new TypeError("Expected ';break;case 3:delete t.title,delete t.closeBtn,t.icon===-1&&0===t.icon,r.closeAll("loading");break;case 4:f||(t.content=[t.content,"body"]),t.follow=t.content[1],t.content=t.content[0]+'',delete t.title,t.tips="object"==typeof t.tips?t.tips:[t.tips,!0],t.tipsMore||r.closeAll("tips")}if(e.vessel(f,function(n,r,u){c.append(n[0]),f?function(){2==t.type||4==t.type?function(){i("body").append(n[1])}():function(){s.parents("."+l[0])[0]||(s.data("display",s.css("display")).show().addClass("layui-layer-wrap").wrap(n[1]),i("#"+l[0]+a).find("."+l[5]).before(r))}()}():c.append(n[1]),i(".layui-layer-move")[0]||c.append(o.moveElem=u),e.layero=i("#"+l[0]+a),t.scrollbar||l.html.css("overflow","hidden").attr("layer-full",a)}).auto(a),i("#layui-layer-shade"+e.index).css({"background-color":t.shade[1]||"#000",opacity:t.shade[0]||t.shade}),2==t.type&&6==r.ie&&e.layero.find("iframe").attr("src",s[0]),4==t.type?e.tips():e.offset(),t.fixed&&n.on("resize",function(){e.offset(),(/^\d+%$/.test(t.area[0])||/^\d+%$/.test(t.area[1]))&&e.auto(a),4==t.type&&e.tips()}),t.time<=0||setTimeout(function(){r.close(e.index)},t.time),e.move().callback(),l.anim[t.anim]){var u="layer-anim "+l.anim[t.anim];e.layero.addClass(u).one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",function(){i(this).removeClass(u)})}t.isOutAnim&&e.layero.data("isOutAnim",!0)}},s.pt.auto=function(e){var t=this,a=t.config,o=i("#"+l[0]+e);""===a.area[0]&&a.maxWidth>0&&(r.ie&&r.ie<8&&a.btn&&o.width(o.innerWidth()),o.outerWidth()>a.maxWidth&&o.width(a.maxWidth));var s=[o.innerWidth(),o.innerHeight()],f=o.find(l[1]).outerHeight()||0,c=o.find("."+l[6]).outerHeight()||0,u=function(e){e=o.find(e),e.height(s[1]-f-c-2*(0|parseFloat(e.css("padding-top"))))};switch(a.type){case 2:u("iframe");break;default:""===a.area[1]?a.maxHeight>0&&o.outerHeight()>a.maxHeight?(s[1]=a.maxHeight,u("."+l[5])):a.fixed&&s[1]>=n.height()&&(s[1]=n.height(),u("."+l[5])):u("."+l[5])}return t},s.pt.offset=function(){var e=this,t=e.config,i=e.layero,a=[i.outerWidth(),i.outerHeight()],o="object"==typeof t.offset;e.offsetTop=(n.height()-a[1])/2,e.offsetLeft=(n.width()-a[0])/2,o?(e.offsetTop=t.offset[0],e.offsetLeft=t.offset[1]||e.offsetLeft):"auto"!==t.offset&&("t"===t.offset?e.offsetTop=0:"r"===t.offset?e.offsetLeft=n.width()-a[0]:"b"===t.offset?e.offsetTop=n.height()-a[1]:"l"===t.offset?e.offsetLeft=0:"lt"===t.offset?(e.offsetTop=0,e.offsetLeft=0):"lb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=0):"rt"===t.offset?(e.offsetTop=0,e.offsetLeft=n.width()-a[0]):"rb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=n.width()-a[0]):e.offsetTop=t.offset),t.fixed||(e.offsetTop=/%$/.test(e.offsetTop)?n.height()*parseFloat(e.offsetTop)/100:parseFloat(e.offsetTop),e.offsetLeft=/%$/.test(e.offsetLeft)?n.width()*parseFloat(e.offsetLeft)/100:parseFloat(e.offsetLeft),e.offsetTop+=n.scrollTop(),e.offsetLeft+=n.scrollLeft()),i.attr("minLeft")&&(e.offsetTop=n.height()-(i.find(l[1]).outerHeight()||0),e.offsetLeft=i.css("left")),i.css({top:e.offsetTop,left:e.offsetLeft})},s.pt.tips=function(){var e=this,t=e.config,a=e.layero,o=[a.outerWidth(),a.outerHeight()],r=i(t.follow);r[0]||(r=i("body"));var s={width:r.outerWidth(),height:r.outerHeight(),top:r.offset().top,left:r.offset().left},f=a.find(".layui-layer-TipsG"),c=t.tips[0];t.tips[1]||f.remove(),s.autoLeft=function(){s.left+o[0]-n.width()>0?(s.tipLeft=s.left+s.width-o[0],f.css({right:12,left:"auto"})):s.tipLeft=s.left},s.where=[function(){s.autoLeft(),s.tipTop=s.top-o[1]-10,f.removeClass("layui-layer-TipsB").addClass("layui-layer-TipsT").css("border-right-color",t.tips[1])},function(){s.tipLeft=s.left+s.width+10,s.tipTop=s.top,f.removeClass("layui-layer-TipsL").addClass("layui-layer-TipsR").css("border-bottom-color",t.tips[1])},function(){s.autoLeft(),s.tipTop=s.top+s.height+10,f.removeClass("layui-layer-TipsT").addClass("layui-layer-TipsB").css("border-right-color",t.tips[1])},function(){s.tipLeft=s.left-o[0]-10,s.tipTop=s.top,f.removeClass("layui-layer-TipsR").addClass("layui-layer-TipsL").css("border-bottom-color",t.tips[1])}],s.where[c-1](),1===c?s.top-(n.scrollTop()+o[1]+16)<0&&s.where[2]():2===c?n.width()-(s.left+s.width+o[0]+16)>0||s.where[3]():3===c?s.top-n.scrollTop()+s.height+o[1]+16-n.height()>0&&s.where[0]():4===c&&o[0]+16-s.left>0&&s.where[1](),a.find("."+l[5]).css({"background-color":t.tips[1],"padding-right":t.closeBtn?"30px":""}),a.css({left:s.tipLeft-(t.fixed?n.scrollLeft():0),top:s.tipTop-(t.fixed?n.scrollTop():0)})},s.pt.move=function(){var e=this,t=e.config,a=i(document),s=e.layero,l=s.find(t.move),f=s.find(".layui-layer-resize"),c={};return t.move&&l.css("cursor","move"),l.on("mousedown",function(e){e.preventDefault(),t.move&&(c.moveStart=!0,c.offset=[e.clientX-parseFloat(s.css("left")),e.clientY-parseFloat(s.css("top"))],o.moveElem.css("cursor","move").show())}),f.on("mousedown",function(e){e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],c.area=[s.outerWidth(),s.outerHeight()],o.moveElem.css("cursor","se-resize").show()}),a.on("mousemove",function(i){if(c.moveStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1],l="fixed"===s.css("position");if(i.preventDefault(),c.stX=l?0:n.scrollLeft(),c.stY=l?0:n.scrollTop(),!t.moveOut){var f=n.width()-s.outerWidth()+c.stX,u=n.height()-s.outerHeight()+c.stY;af&&(a=f),ou&&(o=u)}s.css({left:a,top:o})}if(t.resize&&c.resizeStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1];i.preventDefault(),r.style(e.index,{width:c.area[0]+a,height:c.area[1]+o}),c.isResize=!0,t.resizing&&t.resizing(s)}}).on("mouseup",function(e){c.moveStart&&(delete c.moveStart,o.moveElem.hide(),t.moveEnd&&t.moveEnd(s)),c.resizeStart&&(delete c.resizeStart,o.moveElem.hide())}),e},s.pt.callback=function(){function e(){var e=a.cancel&&a.cancel(t.index,n);e===!1||r.close(t.index)}var t=this,n=t.layero,a=t.config;t.openLayer(),a.success&&(2==a.type?n.find("iframe").on("load",function(){a.success(n,t.index)}):a.success(n,t.index)),6==r.ie&&t.IE6(n),n.find("."+l[6]).children("a").on("click",function(){var e=i(this).index();if(0===e)a.yes?a.yes(t.index,n):a.btn1?a.btn1(t.index,n):r.close(t.index);else{var o=a["btn"+(e+1)]&&a["btn"+(e+1)](t.index,n);o===!1||r.close(t.index)}}),n.find("."+l[7]).on("click",e),a.shadeClose&&i("#layui-layer-shade"+t.index).on("click",function(){r.close(t.index)}),n.find(".layui-layer-min").on("click",function(){var e=a.min&&a.min(n);e===!1||r.min(t.index,a)}),n.find(".layui-layer-max").on("click",function(){i(this).hasClass("layui-layer-maxmin")?(r.restore(t.index),a.restore&&a.restore(n)):(r.full(t.index,a),setTimeout(function(){a.full&&a.full(n)},100))}),a.end&&(o.end[t.index]=a.end)},o.reselect=function(){i.each(i("select"),function(e,t){var n=i(this);n.parents("."+l[0])[0]||1==n.attr("layer")&&i("."+l[0]).length<1&&n.removeAttr("layer").show(),n=null})},s.pt.IE6=function(e){i("select").each(function(e,t){var n=i(this);n.parents("."+l[0])[0]||"none"===n.css("display")||n.attr({layer:"1"}).hide(),n=null})},s.pt.openLayer=function(){var e=this;r.zIndex=e.config.zIndex,r.setTop=function(e){var t=function(){r.zIndex++,e.css("z-index",r.zIndex+1)};return r.zIndex=parseInt(e[0].style.zIndex),e.on("mousedown",t),r.zIndex}},o.record=function(e){var t=[e.width(),e.height(),e.position().top,e.position().left+parseFloat(e.css("margin-left"))];e.find(".layui-layer-max").addClass("layui-layer-maxmin"),e.attr({area:t})},o.rescollbar=function(e){l.html.attr("layer-full")==e&&(l.html[0].style.removeProperty?l.html[0].style.removeProperty("overflow"):l.html[0].style.removeAttribute("overflow"),l.html.removeAttr("layer-full"))},e.layer=r,r.getChildFrame=function(e,t){return t=t||i("."+l[4]).attr("times"),i("#"+l[0]+t).find("iframe").contents().find(e)},r.getFrameIndex=function(e){return i("#"+e).parents("."+l[4]).attr("times")},r.iframeAuto=function(e){if(e){var t=r.getChildFrame("html",e).outerHeight(),n=i("#"+l[0]+e),a=n.find(l[1]).outerHeight()||0,o=n.find("."+l[6]).outerHeight()||0;n.css({height:t+a+o}),n.find("iframe").css({height:t})}},r.iframeSrc=function(e,t){i("#"+l[0]+e).find("iframe").attr("src",t)},r.style=function(e,t,n){var a=i("#"+l[0]+e),r=a.find(".layui-layer-content"),s=a.attr("type"),f=a.find(l[1]).outerHeight()||0,c=a.find("."+l[6]).outerHeight()||0;a.attr("minLeft");s!==o.type[3]&&s!==o.type[4]&&(n||(parseFloat(t.width)<=260&&(t.width=260),parseFloat(t.height)-f-c<=64&&(t.height=64+f+c)),a.css(t),c=a.find("."+l[6]).outerHeight(),s===o.type[2]?a.find("iframe").css({height:parseFloat(t.height)-f-c}):r.css({height:parseFloat(t.height)-f-c-parseFloat(r.css("padding-top"))-parseFloat(r.css("padding-bottom"))}))},r.min=function(e,t){var a=i("#"+l[0]+e),s=a.find(l[1]).outerHeight()||0,f=a.attr("minLeft")||181*o.minIndex+"px",c=a.css("position");o.record(a),o.minLeft[0]&&(f=o.minLeft[0],o.minLeft.shift()),a.attr("position",c),r.style(e,{width:180,height:s,left:f,top:n.height()-s,position:"fixed",overflow:"hidden"},!0),a.find(".layui-layer-min").hide(),"page"===a.attr("type")&&a.find(l[4]).hide(),o.rescollbar(e),a.attr("minLeft")||o.minIndex++,a.attr("minLeft",f)},r.restore=function(e){var t=i("#"+l[0]+e),n=t.attr("area").split(",");t.attr("type");r.style(e,{width:parseFloat(n[0]),height:parseFloat(n[1]),top:parseFloat(n[2]),left:parseFloat(n[3]),position:t.attr("position"),overflow:"visible"},!0),t.find(".layui-layer-max").removeClass("layui-layer-maxmin"),t.find(".layui-layer-min").show(),"page"===t.attr("type")&&t.find(l[4]).show(),o.rescollbar(e)},r.full=function(e){var t,a=i("#"+l[0]+e);o.record(a),l.html.attr("layer-full")||l.html.css("overflow","hidden").attr("layer-full",e),clearTimeout(t),t=setTimeout(function(){var t="fixed"===a.css("position");r.style(e,{top:t?0:n.scrollTop(),left:t?0:n.scrollLeft(),width:n.width(),height:n.height()},!0),a.find(".layui-layer-min").hide()},100)},r.title=function(e,t){var n=i("#"+l[0]+(t||r.index)).find(l[1]);n.html(e)},r.close=function(e){var t=i("#"+l[0]+e),n=t.attr("type"),a="layer-anim-close";if(t[0]){var s="layui-layer-wrap",f=function(){if(n===o.type[1]&&"object"===t.attr("conType")){t.children(":not(."+l[5]+")").remove();for(var a=t.find("."+s),r=0;r<2;r++)a.unwrap();a.css("display",a.data("display")).removeClass(s)}else{if(n===o.type[2])try{var f=i("#"+l[4]+e)[0];f.contentWindow.document.write(""),f.contentWindow.close(),t.find("."+l[5])[0].removeChild(f)}catch(c){}t[0].innerHTML="",t.remove()}"function"==typeof o.end[e]&&o.end[e](),delete o.end[e]};t.data("isOutAnim")&&t.addClass("layer-anim "+a),i("#layui-layer-moves, #layui-layer-shade"+e).remove(),6==r.ie&&o.reselect(),o.rescollbar(e),t.attr("minLeft")&&(o.minIndex--,o.minLeft.push(t.attr("minLeft"))),r.ie&&r.ie<10||!t.data("isOutAnim")?f():setTimeout(function(){f()},200)}},r.closeAll=function(e){i.each(i("."+l[0]),function(){var t=i(this),n=e?t.attr("type")===e:1;n&&r.close(t.attr("times")),n=null})};var f=r.cache||{},c=function(e){return f.skin?" "+f.skin+" "+f.skin+"-"+e:""};r.prompt=function(e,t){var a="";if(e=e||{},"function"==typeof e&&(t=e),e.area){var o=e.area;a='style="width: '+o[0]+"; height: "+o[1]+';"',delete e.area}var s,l=2==e.formType?'":function(){return''}(),f=e.success;return delete e.success,r.open(i.extend({type:1,btn:["确定","取消"],content:l,skin:"layui-layer-prompt"+c("prompt"),maxWidth:n.width(),success:function(e){s=e.find(".layui-layer-input"),s.focus(),"function"==typeof f&&f(e)},resize:!1,yes:function(i){var n=s.val();""===n?s.focus():n.length>(e.maxlength||500)?r.tips("最多输入"+(e.maxlength||500)+"个字数",s,{tips:1}):t&&t(n,i,s)}},e))},r.tab=function(e){e=e||{};var t=e.tab||{},n="layui-this",a=e.success;return delete e.success,r.open(i.extend({type:1,skin:"layui-layer-tab"+c("tab"),resize:!1,title:function(){var e=t.length,i=1,a="";if(e>0)for(a=''+t[0].title+"";i"+t[i].title+"";return a}(),content:'
      '+function(){var e=t.length,i=1,a="";if(e>0)for(a='
    • '+(t[0].content||"no content")+"
    • ";i'+(t[i].content||"no content")+"";return a}()+"
    ",success:function(t){var o=t.find(".layui-layer-title").children(),r=t.find(".layui-layer-tabmain").children();o.on("mousedown",function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0;var a=i(this),o=a.index();a.addClass(n).siblings().removeClass(n),r.eq(o).show().siblings().hide(),"function"==typeof e.change&&e.change(o)}),"function"==typeof a&&a(t)}},e))},r.photos=function(t,n,a){function o(e,t,i){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,i(e)}))}var s={};if(t=t||{},t.photos){var l=t.photos.constructor===Object,f=l?t.photos:{},u=f.data||[],d=f.start||0;s.imgIndex=(0|d)+1,t.img=t.img||"img";var y=t.success;if(delete t.success,l){if(0===u.length)return r.msg("没有图片")}else{var p=i(t.photos),h=function(){u=[],p.find(t.img).each(function(e){var t=i(this);t.attr("layer-index",e),u.push({alt:t.attr("alt"),pid:t.attr("layer-pid"),src:t.attr("layer-src")||t.attr("src"),thumb:t.attr("src")})})};if(h(),0===u.length)return;if(n||p.on("click",t.img,function(){var e=i(this),n=e.attr("layer-index");r.photos(i.extend(t,{photos:{start:n,data:u,tab:t.tab},full:t.full}),!0),h()}),!n)return}s.imgprev=function(e){s.imgIndex--,s.imgIndex<1&&(s.imgIndex=u.length),s.tabimg(e)},s.imgnext=function(e,t){s.imgIndex++,s.imgIndex>u.length&&(s.imgIndex=1,t)||s.tabimg(e)},s.keyup=function(e){if(!s.end){var t=e.keyCode;e.preventDefault(),37===t?s.imgprev(!0):39===t?s.imgnext(!0):27===t&&r.close(s.index)}},s.tabimg=function(e){if(!(u.length<=1))return f.start=s.imgIndex-1,r.close(s.index),r.photos(t,!0,e)},s.event=function(){s.bigimg.hover(function(){s.imgsee.show()},function(){s.imgsee.hide()}),s.bigimg.find(".layui-layer-imgprev").on("click",function(e){e.preventDefault(),s.imgprev()}),s.bigimg.find(".layui-layer-imgnext").on("click",function(e){e.preventDefault(),s.imgnext()}),i(document).on("keyup",s.keyup)},s.loadi=r.load(1,{shade:!("shade"in t)&&.9,scrollbar:!1}),o(u[d].src,function(n){r.close(s.loadi),s.index=r.open(i.extend({type:1,id:"layui-layer-photos",area:function(){var a=[n.width,n.height],o=[i(e).width()-100,i(e).height()-100];if(!t.full&&(a[0]>o[0]||a[1]>o[1])){var r=[a[0]/o[0],a[1]/o[1]];r[0]>r[1]?(a[0]=a[0]/r[0],a[1]=a[1]/r[0]):r[0]'+(u[d].alt||
    '+(u.length>1?'':"")+'
    '+(u[d].alt||"")+""+s.imgIndex+"/"+u.length+"
    ",success:function(e,i){s.bigimg=e.find(".layui-layer-phimg"),s.imgsee=e.find(".layui-layer-imguide,.layui-layer-imgbar"),s.event(e),t.tab&&t.tab(u[d],e),"function"==typeof y&&y(e)},end:function(){s.end=!0,i(document).off("keyup",s.keyup)}},t))},function(){r.close(s.loadi),r.msg("当前图片地址异常
    是否继续查看下一张?",{time:3e4,btn:["下一张","不看了"],yes:function(){u.length>1&&s.imgnext(!0,!0)}})})}},o.run=function(t){i=t,n=i(e),l.html=i("html"),r.open=function(e){var t=new s(e);return t.index}},e.layui&&layui.define?(r.ready(),layui.define("jquery",function(t){r.path=layui.cache.dir,o.run(layui.$),e.layer=r,t("layer",r)})):"function"==typeof define&&define.amd?define(["jquery"],function(){return o.run(e.jQuery),r}):function(){o.run(e.jQuery),r.ready()}()}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/mobile/layer.js b/net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/mobile/layer.js new file mode 100644 index 000000000..f9cf69313 --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/mobile/layer.js @@ -0,0 +1,2 @@ +/*! layer mobile-v2.0.0 Web弹层组件 MIT License http://layer.layui.com/mobile By 贤心 */ + ;!function(e){"use strict";var t=document,n="querySelectorAll",i="getElementsByClassName",a=function(e){return t[n](e)},s={type:0,shade:!0,shadeClose:!0,fixed:!0,anim:"scale"},l={extend:function(e){var t=JSON.parse(JSON.stringify(s));for(var n in e)t[n]=e[n];return t},timer:{},end:{}};l.touch=function(e,t){e.addEventListener("click",function(e){t.call(this,e)},!1)};var r=0,o=["layui-m-layer"],c=function(e){var t=this;t.config=l.extend(e),t.view()};c.prototype.view=function(){var e=this,n=e.config,s=t.createElement("div");e.id=s.id=o[0]+r,s.setAttribute("class",o[0]+" "+o[0]+(n.type||0)),s.setAttribute("index",r);var l=function(){var e="object"==typeof n.title;return n.title?'

    '+(e?n.title[0]:n.title)+"

    ":""}(),c=function(){"string"==typeof n.btn&&(n.btn=[n.btn]);var e,t=(n.btn||[]).length;return 0!==t&&n.btn?(e=''+n.btn[0]+"",2===t&&(e=''+n.btn[1]+""+e),'
    '+e+"
    "):""}();if(n.fixed||(n.top=n.hasOwnProperty("top")?n.top:100,n.style=n.style||"",n.style+=" top:"+(t.body.scrollTop+n.top)+"px"),2===n.type&&(n.content='

    '+(n.content||"")+"

    "),n.skin&&(n.anim="up"),"msg"===n.skin&&(n.shade=!1),s.innerHTML=(n.shade?"
    ':"")+'
    "+l+'
    '+n.content+"
    "+c+"
    ",!n.type||2===n.type){var d=t[i](o[0]+n.type),y=d.length;y>=1&&layer.close(d[0].getAttribute("index"))}document.body.appendChild(s);var u=e.elem=a("#"+e.id)[0];n.success&&n.success(u),e.index=r++,e.action(n,u)},c.prototype.action=function(e,t){var n=this;e.time&&(l.timer[n.index]=setTimeout(function(){layer.close(n.index)},1e3*e.time));var a=function(){var t=this.getAttribute("type");0==t?(e.no&&e.no(),layer.close(n.index)):e.yes?e.yes(n.index):layer.close(n.index)};if(e.btn)for(var s=t[i]("layui-m-layerbtn")[0].children,r=s.length,o=0;odiv{line-height:22px;padding-top:7px;margin-bottom:20px;font-size:14px}.layui-m-layerbtn{display:box;display:-moz-box;display:-webkit-box;width:100%;height:50px;line-height:50px;font-size:0;border-top:1px solid #D0D0D0;background-color:#F2F2F2}.layui-m-layerbtn span{display:block;-moz-box-flex:1;box-flex:1;-webkit-box-flex:1;font-size:14px;cursor:pointer}.layui-m-layerbtn span[yes]{color:#40AFFE}.layui-m-layerbtn span[no]{border-right:1px solid #D0D0D0;border-radius:0 0 0 5px}.layui-m-layerbtn span:active{background-color:#F6F6F6}.layui-m-layerend{position:absolute;right:7px;top:10px;width:30px;height:30px;border:0;font-weight:400;background:0 0;cursor:pointer;-webkit-appearance:none;font-size:30px}.layui-m-layerend::after,.layui-m-layerend::before{position:absolute;left:5px;top:15px;content:'';width:18px;height:1px;background-color:#999;transform:rotate(45deg);-webkit-transform:rotate(45deg);border-radius:3px}.layui-m-layerend::after{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}body .layui-m-layer .layui-m-layer-footer{position:fixed;width:95%;max-width:100%;margin:0 auto;left:0;right:0;bottom:10px;background:0 0}.layui-m-layer-footer .layui-m-layercont{padding:20px;border-radius:5px 5px 0 0;background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn{display:block;height:auto;background:0 0;border-top:none}.layui-m-layer-footer .layui-m-layerbtn span{background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn span[no]{color:#FD482C;border-top:1px solid #c2c2c2;border-radius:0 0 5px 5px}.layui-m-layer-footer .layui-m-layerbtn span[yes]{margin-top:10px;border-radius:5px}body .layui-m-layer .layui-m-layer-msg{width:auto;max-width:90%;margin:0 auto;bottom:-150px;background-color:rgba(0,0,0,.7);color:#fff}.layui-m-layer-msg .layui-m-layercont{padding:10px 20px} \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/theme/default/icon-ext.png b/net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/theme/default/icon-ext.png new file mode 100644 index 000000000..bbbb669bb Binary files /dev/null and b/net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/theme/default/icon-ext.png differ diff --git a/net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/theme/default/icon.png b/net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/theme/default/icon.png new file mode 100644 index 000000000..3e17da8b1 Binary files /dev/null and b/net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/theme/default/icon.png differ diff --git a/net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/theme/default/layer.css b/net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/theme/default/layer.css new file mode 100644 index 000000000..820b4a99b --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/theme/default/layer.css @@ -0,0 +1 @@ +.layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span,.layui-layer-title{text-overflow:ellipsis;white-space:nowrap}html #layuicss-layer{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+"px")}.layui-layer{-webkit-overflow-scrolling:touch;top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;border-radius:2px;box-shadow:1px 1px 50px rgba(0,0,0,.3)}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.1);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-load{background:url(loading-1.gif) center center no-repeat #eee}.layui-layer-ico{background:url(icon.png) no-repeat}.layui-layer-btn a,.layui-layer-dialog .layui-layer-ico,.layui-layer-setwin a{display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-move{display:none;position:fixed;*position:absolute;left:0;top:0;width:100%;height:100%;cursor:move;opacity:0;filter:alpha(opacity=0);background-color:#fff;z-index:2147483647}.layui-layer-resize{position:absolute;width:15px;height:15px;right:0;bottom:0;cursor:se-resize}.layer-anim{-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-00{-webkit-animation-name:layer-bounceIn;animation-name:layer-bounceIn}@-webkit-keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:layer-zoomInDown;animation-name:layer-zoomInDown}@-webkit-keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:layer-fadeInUpBig;animation-name:layer-fadeInUpBig}@-webkit-keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:layer-zoomInLeft;animation-name:layer-zoomInLeft}@-webkit-keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layer-anim-04{-webkit-animation-name:layer-rollIn;animation-name:layer-rollIn}@keyframes layer-fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:layer-fadeIn;animation-name:layer-fadeIn}@-webkit-keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:layer-shake;animation-name:layer-shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layui-layer-title{padding:0 80px 0 20px;height:42px;line-height:42px;border-bottom:1px solid #eee;font-size:14px;color:#333;overflow:hidden;background-color:#F8F8F8;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:15px;font-size:0;line-height:initial}.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:10px;font-size:12px;_overflow:hidden}.layui-layer-setwin .layui-layer-min cite{position:absolute;width:14px;height:2px;left:0;top:50%;margin-top:-1px;background-color:#2E2D3C;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA}.layui-layer-setwin .layui-layer-max{background-position:-32px -40px}.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px}.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px}.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px}.layui-layer-setwin .layui-layer-close1{background-position:1px -40px;cursor:pointer}.layui-layer-setwin .layui-layer-close1:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;width:30px;height:30px;margin-left:0;background-position:-149px -31px;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{background-position:-180px -31px}.layui-layer-btn{text-align:right;padding:0 15px 12px;pointer-events:auto;user-select:none;-webkit-user-select:none}.layui-layer-btn a{height:28px;line-height:28px;margin:5px 5px 0;padding:0 15px;border:1px solid #dedede;background-color:#fff;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.8}.layui-layer-btn .layui-layer-btn0{border-color:#1E9FFF;background-color:#1E9FFF;color:#fff}.layui-layer-btn-l{text-align:left}.layui-layer-btn-c{text-align:center}.layui-layer-dialog{min-width:260px}.layui-layer-dialog .layui-layer-content{position:relative;padding:20px;line-height:24px;word-break:break-all;overflow:hidden;font-size:14px;overflow-x:hidden;overflow-y:auto}.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute;top:16px;left:15px;_left:-40px;width:30px;height:30px}.layui-layer-ico1{background-position:-30px 0}.layui-layer-ico2{background-position:-60px 0}.layui-layer-ico3{background-position:-90px 0}.layui-layer-ico4{background-position:-120px 0}.layui-layer-ico5{background-position:-150px 0}.layui-layer-ico6{background-position:-180px 0}.layui-layer-rim{border:6px solid #8D8D8D;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #D3D4D3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-content{padding:12px 25px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:20px 20px 20px 55px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(loading-0.gif) no-repeat}.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(loading-1.gif) no-repeat}.layui-layer-ico16,.layui-layer-loading .layui-layer-loading2{width:32px;height:32px;background:url(loading-2.gif) no-repeat}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:8px 15px;font-size:12px;_float:left;border-radius:2px;box-shadow:1px 1px 3px rgba(0,0,0,.2);background-color:#000;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#000}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:5px;border-bottom-style:solid;border-bottom-color:#000}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan[type=dialog]{min-width:280px}.layui-layer-lan .layui-layer-title{background:#4476A7;color:#fff;border:none}.layui-layer-lan .layui-layer-btn{padding:5px 10px 10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#fff;border-color:#E9E7E7;color:#333}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95;border-color:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1}.layui-layer-iconext{background:url(icon-ext.png) no-repeat}.layui-layer-prompt .layui-layer-input{display:block;width:230px;height:36px;margin:0 auto;line-height:30px;padding-left:10px;border:1px solid #e6e6e6;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px;padding:6px 10px}.layui-layer-prompt .layui-layer-content{padding:20px}.layui-layer-prompt .layui-layer-btn{padding-top:0}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;float:left;min-width:80px;max-width:260px;padding:0 20px;text-align:center;overflow:hidden;cursor:pointer}.layui-layer-tab .layui-layer-title span.layui-this{height:43px;border-left:1px solid #eee;border-right:1px solid #eee;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left:none}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.layui-this{display:block}.layui-layer-photos{-webkit-animation-duration:.8s;animation-duration:.8s}.layui-layer-photos .layui-layer-content{overflow:hidden;text-align:center}.layui-layer-photos .layui-layer-phimg img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-imgbar,.layui-layer-imguide{display:none}.layui-layer-imgnext,.layui-layer-imgprev{position:absolute;top:50%;width:27px;_width:44px;height:44px;margin-top:-22px;outline:0;blr:expression(this.onFocus=this.blur())}.layui-layer-imgprev{left:10px;background-position:-5px -5px;_background-position:-70px -5px}.layui-layer-imgprev:hover{background-position:-33px -5px;_background-position:-120px -5px}.layui-layer-imgnext{right:10px;_right:8px;background-position:-5px -50px;_background-position:-70px -50px}.layui-layer-imgnext:hover{background-position:-33px -50px;_background-position:-120px -50px}.layui-layer-imgbar{position:absolute;left:0;bottom:0;width:100%;height:32px;line-height:32px;background-color:rgba(0,0,0,.8);background-color:#000\9;filter:Alpha(opacity=80);color:#fff;overflow:hidden;font-size:0}.layui-layer-imgtit *{display:inline-block;*display:inline;*zoom:1;vertical-align:top;font-size:12px}.layui-layer-imgtit a{max-width:65%;overflow:hidden;color:#fff}.layui-layer-imgtit a:hover{color:#fff;text-decoration:underline}.layui-layer-imgtit em{padding-left:10px;font-style:normal}@-webkit-keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);-ms-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-close{-webkit-animation-name:layer-bounceOut;animation-name:layer-bounceOut;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.2s;animation-duration:.2s}@media screen and (max-width:1100px){.layui-layer-iframe{overflow-y:auto;-webkit-overflow-scrolling:touch}} \ No newline at end of file diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading0.gif b/net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/theme/default/loading-0.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading0.gif rename to net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/theme/default/loading-0.gif diff --git a/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading1.gif b/net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/theme/default/loading-1.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading1.gif rename to net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/theme/default/loading-1.gif diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading2.gif b/net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/theme/default/loading-2.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading2.gif rename to net452/SiteServer.Web/Home/assets/lib/layer-3.1.1/theme/default/loading-2.gif diff --git a/net452/SiteServer.Web/Home/assets/lib/lodash-4.17.10.min.js b/net452/SiteServer.Web/Home/assets/lib/lodash-4.17.10.min.js new file mode 100644 index 000000000..fced00b39 --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/lib/lodash-4.17.10.min.js @@ -0,0 +1,137 @@ +/** + * @license + * Lodash lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE + */ +;(function(){function n(n,t,r){switch(r.length){case 0:return n.call(t);case 1:return n.call(t,r[0]);case 2:return n.call(t,r[0],r[1]);case 3:return n.call(t,r[0],r[1],r[2])}return n.apply(t,r)}function t(n,t,r,e){for(var u=-1,i=null==n?0:n.length;++u"']/g,G=RegExp(V.source),H=RegExp(K.source),J=/<%-([\s\S]+?)%>/g,Y=/<%([\s\S]+?)%>/g,Q=/<%=([\s\S]+?)%>/g,X=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,nn=/^\w*$/,tn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,rn=/[\\^$.*+?()[\]{}|]/g,en=RegExp(rn.source),un=/^\s+|\s+$/g,on=/^\s+/,fn=/\s+$/,cn=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,an=/\{\n\/\* \[wrapped with (.+)\] \*/,ln=/,? & /,sn=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,hn=/\\(\\)?/g,pn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,_n=/\w*$/,vn=/^[-+]0x[0-9a-f]+$/i,gn=/^0b[01]+$/i,dn=/^\[object .+?Constructor\]$/,yn=/^0o[0-7]+$/i,bn=/^(?:0|[1-9]\d*)$/,xn=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,jn=/($^)/,wn=/['\n\r\u2028\u2029\\]/g,mn="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?)*",An="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+mn,En="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]?|[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",kn=RegExp("['\u2019]","g"),Sn=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g"),On=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+En+mn,"g"),In=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:d|ll|m|re|s|t|ve))?|[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?|\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])|\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])|\\d+",An].join("|"),"g"),Rn=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]"),zn=/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Wn="Array Buffer DataView Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Promise RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),Bn={}; +Bn["[object Float32Array]"]=Bn["[object Float64Array]"]=Bn["[object Int8Array]"]=Bn["[object Int16Array]"]=Bn["[object Int32Array]"]=Bn["[object Uint8Array]"]=Bn["[object Uint8ClampedArray]"]=Bn["[object Uint16Array]"]=Bn["[object Uint32Array]"]=true,Bn["[object Arguments]"]=Bn["[object Array]"]=Bn["[object ArrayBuffer]"]=Bn["[object Boolean]"]=Bn["[object DataView]"]=Bn["[object Date]"]=Bn["[object Error]"]=Bn["[object Function]"]=Bn["[object Map]"]=Bn["[object Number]"]=Bn["[object Object]"]=Bn["[object RegExp]"]=Bn["[object Set]"]=Bn["[object String]"]=Bn["[object WeakMap]"]=false; +var Ln={};Ln["[object Arguments]"]=Ln["[object Array]"]=Ln["[object ArrayBuffer]"]=Ln["[object DataView]"]=Ln["[object Boolean]"]=Ln["[object Date]"]=Ln["[object Float32Array]"]=Ln["[object Float64Array]"]=Ln["[object Int8Array]"]=Ln["[object Int16Array]"]=Ln["[object Int32Array]"]=Ln["[object Map]"]=Ln["[object Number]"]=Ln["[object Object]"]=Ln["[object RegExp]"]=Ln["[object Set]"]=Ln["[object String]"]=Ln["[object Symbol]"]=Ln["[object Uint8Array]"]=Ln["[object Uint8ClampedArray]"]=Ln["[object Uint16Array]"]=Ln["[object Uint32Array]"]=true, +Ln["[object Error]"]=Ln["[object Function]"]=Ln["[object WeakMap]"]=false;var Un={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Cn=parseFloat,Dn=parseInt,Mn=typeof global=="object"&&global&&global.Object===Object&&global,Tn=typeof self=="object"&&self&&self.Object===Object&&self,$n=Mn||Tn||Function("return this")(),Fn=typeof exports=="object"&&exports&&!exports.nodeType&&exports,Nn=Fn&&typeof module=="object"&&module&&!module.nodeType&&module,Pn=Nn&&Nn.exports===Fn,Zn=Pn&&Mn.process,qn=function(){ +try{var n=Nn&&Nn.f&&Nn.f("util").types;return n?n:Zn&&Zn.binding&&Zn.binding("util")}catch(n){}}(),Vn=qn&&qn.isArrayBuffer,Kn=qn&&qn.isDate,Gn=qn&&qn.isMap,Hn=qn&&qn.isRegExp,Jn=qn&&qn.isSet,Yn=qn&&qn.isTypedArray,Qn=b("length"),Xn=x({"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I", +"\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a","\u0106":"C", +"\u0108":"C","\u010a":"C","\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I","\u0129":"i", +"\u012b":"i","\u012d":"i","\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r","\u0159":"r", +"\u015a":"S","\u015c":"S","\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ","\u0133":"ij", +"\u0152":"Oe","\u0153":"oe","\u0149":"'n","\u017f":"s"}),nt=x({"&":"&","<":"<",">":">",'"':""","'":"'"}),tt=x({"&":"&","<":"<",">":">",""":'"',"'":"'"}),rt=function x(mn){function An(n){if(du(n)&&!of(n)&&!(n instanceof Un)){if(n instanceof On)return n;if(ii.call(n,"__wrapped__"))return $e(n)}return new On(n)}function En(){}function On(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=T}function Un(n){this.__wrapped__=n, +this.__actions__=[],this.__dir__=1,this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Mn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t=t?n:t)),n}function _t(n,t,e,u,i,o){var f,c=1&t,a=2&t,l=4&t;if(e&&(f=i?e(n,u,i,o):e(n)),f!==T)return f;if(!gu(n))return n;if(u=of(n)){if(f=me(n),!c)return Ur(n,f)}else{var s=_o(n),h="[object Function]"==s||"[object GeneratorFunction]"==s;if(cf(n))return Ir(n,c);if("[object Object]"==s||"[object Arguments]"==s||h&&!i){if(f=a||h?{}:Ae(n),!c)return a?Mr(n,lt(f,n)):Dr(n,at(f,n))}else{if(!Ln[s])return i?n:{};f=Ee(n,s,c)}}if(o||(o=new Zn), +i=o.get(n))return i;if(o.set(n,f),hf(n))return n.forEach(function(r){f.add(_t(r,t,e,r,n,o))}),f;if(lf(n))return n.forEach(function(r,u){f.set(u,_t(r,t,e,u,n,o))}),f;var a=l?a?ve:_e:a?Wu:zu,p=u?T:a(n);return r(p||n,function(r,u){p&&(u=r,r=n[u]),ot(f,u,_t(r,t,e,u,n,o))}),f}function vt(n){var t=zu(n);return function(r){return gt(r,n,t)}}function gt(n,t,r){var e=r.length;if(null==n)return!e;for(n=Yu(n);e--;){var u=r[e],i=t[u],o=n[u];if(o===T&&!(u in n)||!i(o))return false}return true}function dt(n,t,r){if(typeof n!="function")throw new ni("Expected a function"); +return yo(function(){n.apply(T,r)},t)}function yt(n,t,r,e){var u=-1,i=o,a=true,l=n.length,s=[],h=t.length;if(!l)return s;r&&(t=c(t,k(r))),e?(i=f,a=false):200<=t.length&&(i=O,a=false,t=new Nn(t));n:for(;++ut}function Rt(n,t){return null!=n&&ii.call(n,t)}function zt(n,t){return null!=n&&t in Yu(n)}function Wt(n,t,r){for(var e=r?f:o,u=n[0].length,i=n.length,a=i,l=Vu(i),s=1/0,h=[];a--;){var p=n[a];a&&t&&(p=c(p,k(t))),s=Ui(p.length,s), +l[a]=!r&&(t||120<=u&&120<=p.length)?new Nn(a&&p):T}var p=n[0],_=-1,v=l[0];n:for(;++_r.length?t:kt(t,hr(r,0,-1)),r=null==t?t:t[De(qe(r))],null==r?T:n(r,t,e)}function Ut(n){return du(n)&&"[object Arguments]"==Ot(n)}function Ct(n){ +return du(n)&&"[object ArrayBuffer]"==Ot(n)}function Dt(n){return du(n)&&"[object Date]"==Ot(n)}function Mt(n,t,r,e,u){if(n===t)t=true;else if(null==n||null==t||!du(n)&&!du(t))t=n!==n&&t!==t;else n:{var i=of(n),o=of(t),f=i?"[object Array]":_o(n),c=o?"[object Array]":_o(t),f="[object Arguments]"==f?"[object Object]":f,c="[object Arguments]"==c?"[object Object]":c,a="[object Object]"==f,o="[object Object]"==c;if((c=f==c)&&cf(n)){if(!cf(t)){t=false;break n}i=true,a=false}if(c&&!a)u||(u=new Zn),t=i||pf(n)?se(n,t,r,e,Mt,u):he(n,t,f,r,e,Mt,u);else{ +if(!(1&r)&&(i=a&&ii.call(n,"__wrapped__"),f=o&&ii.call(t,"__wrapped__"),i||f)){n=i?n.value():n,t=f?t.value():t,u||(u=new Zn),t=Mt(n,t,r,e,u);break n}if(c)t:if(u||(u=new Zn),i=1&r,f=_e(n),o=f.length,c=_e(t).length,o==c||i){for(a=o;a--;){var l=f[a];if(!(i?l in t:ii.call(t,l))){t=false;break t}}if((c=u.get(n))&&u.get(t))t=c==t;else{c=true,u.set(n,t),u.set(t,n);for(var s=i;++at?r:0,Se(t,r)?n[t]:T}function Xt(n,t,r){var e=-1;return t=c(t.length?t:[Tu],k(ye())), +n=Gt(n,function(n){return{a:c(t,function(t){return t(n)}),b:++e,c:n}}),w(n,function(n,t){var e;n:{e=-1;for(var u=n.a,i=t.a,o=u.length,f=r.length;++e=f?c:c*("desc"==r[e]?-1:1);break n}}e=n.b-t.b}return e})}function nr(n,t){return tr(n,t,function(t,r){return Ru(n,r)})}function tr(n,t,r){for(var e=-1,u=t.length,i={};++et||9007199254740991t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Vu(u);++e=u){for(;e>>1,o=n[i];null!==o&&!ju(o)&&(r?o<=t:ot.length?n:kt(n,hr(t,0,-1)),null==n||delete n[De(qe(t))]}function jr(n,t,r,e){for(var u=n.length,i=e?u:-1;(e?i--:++ie)return e?br(n[0]):[];for(var u=-1,i=Vu(e);++u=e?n:hr(n,t,r)}function Ir(n,t){if(t)return n.slice();var r=n.length,r=vi?vi(r):new n.constructor(r);return n.copy(r),r}function Rr(n){var t=new n.constructor(n.byteLength);return new _i(t).set(new _i(n)), +t}function zr(n,t){return new n.constructor(t?Rr(n.buffer):n.buffer,n.byteOffset,n.length)}function Wr(n,t){if(n!==t){var r=n!==T,e=null===n,u=n===n,i=ju(n),o=t!==T,f=null===t,c=t===t,a=ju(t);if(!f&&!a&&!i&&n>t||i&&o&&c&&!f&&!a||e&&o&&c||!r&&c||!u)return 1;if(!e&&!i&&!a&&nu?T:i,u=1),t=Yu(t);++eo&&f[0]!==a&&f[o-1]!==a?[]:L(f,a), +o-=c.length,or?r?or(t,n):t:(r=or(t,Si(n/D(t))),Rn.test(t)?Or(M(r),0,n).join(""):r.slice(0,n))}function te(t,r,e,u){function i(){for(var r=-1,c=arguments.length,a=-1,l=u.length,s=Vu(l+c),h=this&&this!==$n&&this instanceof i?f:t;++at||e)&&(1&n&&(i[2]=h[2],t|=1&r?0:4),(r=h[3])&&(e=i[3],i[3]=e?Br(e,r,h[4]):r,i[4]=e?L(i[3],"__lodash_placeholder__"):h[4]),(r=h[5])&&(e=i[5],i[5]=e?Lr(e,r,h[6]):r,i[6]=e?L(i[5],"__lodash_placeholder__"):h[6]),(r=h[7])&&(i[7]=r),128&n&&(i[8]=null==i[8]?h[8]:Ui(i[8],h[8])),null==i[9]&&(i[9]=h[9]),i[0]=h[0],i[1]=t),n=i[0],t=i[1], +r=i[2],e=i[3],u=i[4],f=i[9]=i[9]===T?c?0:n.length:Li(i[9]-a,0),!f&&24&t&&(t&=-25),Le((h?fo:go)(t&&1!=t?8==t||16==t?Kr(n,t,f):32!=t&&33!=t||u.length?Jr.apply(T,i):te(n,t,r,e):Pr(n,t,r),i),n,t)}function ce(n,t,r,e){return n===T||au(n,ri[r])&&!ii.call(e,r)?t:n}function ae(n,t,r,e,u,i){return gu(n)&&gu(t)&&(i.set(t,n),Yt(n,t,T,ae,i),i.delete(t)),n}function le(n){return bu(n)?T:n}function se(n,t,r,e,u,i){var o=1&r,f=n.length,c=t.length;if(f!=c&&!(o&&c>f))return false;if((c=i.get(n))&&i.get(t))return c==t;var c=-1,a=true,l=2&r?new Nn:T; +for(i.set(n,t),i.set(t,n);++cr&&(r=Li(e+r,0)),_(n,ye(t,3),r)):-1}function Ne(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e-1;return r!==T&&(u=Au(r),u=0>r?Li(e+u,0):Ui(u,e-1)),_(n,ye(t,3),u,true)}function Pe(n){return(null==n?0:n.length)?wt(n,1):[]}function Ze(n){ +return n&&n.length?n[0]:T}function qe(n){var t=null==n?0:n.length;return t?n[t-1]:T}function Ve(n,t){return n&&n.length&&t&&t.length?er(n,t):n}function Ke(n){return null==n?n:Ti.call(n)}function Ge(n){if(!n||!n.length)return[];var t=0;return n=i(n,function(n){if(su(n))return t=Li(n.length,t),true}),A(t,function(t){return c(n,b(t))})}function He(t,r){if(!t||!t.length)return[];var e=Ge(t);return null==r?e:c(e,function(t){return n(r,T,t)})}function Je(n){return n=An(n),n.__chain__=true,n}function Ye(n,t){ +return t(n)}function Qe(){return this}function Xe(n,t){return(of(n)?r:eo)(n,ye(t,3))}function nu(n,t){return(of(n)?e:uo)(n,ye(t,3))}function tu(n,t){return(of(n)?c:Gt)(n,ye(t,3))}function ru(n,t,r){return t=r?T:t,t=n&&null==t?n.length:t,fe(n,128,T,T,T,T,t)}function eu(n,t){var r;if(typeof t!="function")throw new ni("Expected a function");return n=Au(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=T),r}}function uu(n,t,r){return t=r?T:t,n=fe(n,8,T,T,T,T,T,t),n.placeholder=uu.placeholder, +n}function iu(n,t,r){return t=r?T:t,n=fe(n,16,T,T,T,T,T,t),n.placeholder=iu.placeholder,n}function ou(n,t,r){function e(t){var r=c,e=a;return c=a=T,_=t,s=n.apply(e,r)}function u(n){var r=n-p;return n-=_,p===T||r>=t||0>r||g&&n>=l}function i(){var n=Ko();if(u(n))return o(n);var r,e=yo;r=n-_,n=t-(n-p),r=g?Ui(n,l-r):n,h=e(i,r)}function o(n){return h=T,d&&c?e(n):(c=a=T,s)}function f(){var n=Ko(),r=u(n);if(c=arguments,a=this,p=n,r){if(h===T)return _=n=p,h=yo(i,t),v?e(n):s;if(g)return h=yo(i,t),e(p)}return h===T&&(h=yo(i,t)), +s}var c,a,l,s,h,p,_=0,v=false,g=false,d=true;if(typeof n!="function")throw new ni("Expected a function");return t=ku(t)||0,gu(r)&&(v=!!r.leading,l=(g="maxWait"in r)?Li(ku(r.maxWait)||0,t):l,d="trailing"in r?!!r.trailing:d),f.cancel=function(){h!==T&&ao(h),_=0,c=p=a=h=T},f.flush=function(){return h===T?s:o(Ko())},f}function fu(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;return i.has(u)?i.get(u):(e=n.apply(this,e),r.cache=i.set(u,e)||i,e)}if(typeof n!="function"||null!=t&&typeof t!="function")throw new ni("Expected a function"); +return r.cache=new(fu.Cache||Fn),r}function cu(n){if(typeof n!="function")throw new ni("Expected a function");return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}function au(n,t){return n===t||n!==n&&t!==t}function lu(n){return null!=n&&vu(n.length)&&!pu(n)}function su(n){return du(n)&&lu(n)}function hu(n){if(!du(n))return false;var t=Ot(n);return"[object Error]"==t||"[object DOMException]"==t||typeof n.message=="string"&&typeof n.name=="string"&&!bu(n); +}function pu(n){return!!gu(n)&&(n=Ot(n),"[object Function]"==n||"[object GeneratorFunction]"==n||"[object AsyncFunction]"==n||"[object Proxy]"==n)}function _u(n){return typeof n=="number"&&n==Au(n)}function vu(n){return typeof n=="number"&&-1=n}function gu(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function du(n){return null!=n&&typeof n=="object"}function yu(n){return typeof n=="number"||du(n)&&"[object Number]"==Ot(n)}function bu(n){return!(!du(n)||"[object Object]"!=Ot(n))&&(n=gi(n), +null===n||(n=ii.call(n,"constructor")&&n.constructor,typeof n=="function"&&n instanceof n&&ui.call(n)==ai))}function xu(n){return typeof n=="string"||!of(n)&&du(n)&&"[object String]"==Ot(n)}function ju(n){return typeof n=="symbol"||du(n)&&"[object Symbol]"==Ot(n)}function wu(n){if(!n)return[];if(lu(n))return xu(n)?M(n):Ur(n);if(ji&&n[ji]){n=n[ji]();for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}return t=_o(n),("[object Map]"==t?W:"[object Set]"==t?U:Lu)(n)}function mu(n){return n?(n=ku(n), +n===$||n===-$?1.7976931348623157e308*(0>n?-1:1):n===n?n:0):0===n?n:0}function Au(n){n=mu(n);var t=n%1;return n===n?t?n-t:n:0}function Eu(n){return n?pt(Au(n),0,4294967295):0}function ku(n){if(typeof n=="number")return n;if(ju(n))return F;if(gu(n)&&(n=typeof n.valueOf=="function"?n.valueOf():n,n=gu(n)?n+"":n),typeof n!="string")return 0===n?n:+n;n=n.replace(un,"");var t=gn.test(n);return t||yn.test(n)?Dn(n.slice(2),t?2:8):vn.test(n)?F:+n}function Su(n){return Cr(n,Wu(n))}function Ou(n){return null==n?"":yr(n); +}function Iu(n,t,r){return n=null==n?T:kt(n,t),n===T?r:n}function Ru(n,t){return null!=n&&we(n,t,zt)}function zu(n){return lu(n)?qn(n):Vt(n)}function Wu(n){if(lu(n))n=qn(n,true);else if(gu(n)){var t,r=ze(n),e=[];for(t in n)("constructor"!=t||!r&&ii.call(n,t))&&e.push(t);n=e}else{if(t=[],null!=n)for(r in Yu(n))t.push(r);n=t}return n}function Bu(n,t){if(null==n)return{};var r=c(ve(n),function(n){return[n]});return t=ye(t),tr(n,r,function(n,r){return t(n,r[0])})}function Lu(n){return null==n?[]:S(n,zu(n)); +}function Uu(n){return Tf(Ou(n).toLowerCase())}function Cu(n){return(n=Ou(n))&&n.replace(xn,Xn).replace(Sn,"")}function Du(n,t,r){return n=Ou(n),t=r?T:t,t===T?zn.test(n)?n.match(In)||[]:n.match(sn)||[]:n.match(t)||[]}function Mu(n){return function(){return n}}function Tu(n){return n}function $u(n){return qt(typeof n=="function"?n:_t(n,1))}function Fu(n,t,e){var u=zu(t),i=Et(t,u);null!=e||gu(t)&&(i.length||!u.length)||(e=t,t=n,n=this,i=Et(t,zu(t)));var o=!(gu(e)&&"chain"in e&&!e.chain),f=pu(n);return r(i,function(r){ +var e=t[r];n[r]=e,f&&(n.prototype[r]=function(){var t=this.__chain__;if(o||t){var r=n(this.__wrapped__);return(r.__actions__=Ur(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,a([this.value()],arguments))})}),n}function Nu(){}function Pu(n){return Ie(n)?b(De(n)):rr(n)}function Zu(){return[]}function qu(){return false}mn=null==mn?$n:rt.defaults($n.Object(),mn,rt.pick($n,Wn));var Vu=mn.Array,Ku=mn.Date,Gu=mn.Error,Hu=mn.Function,Ju=mn.Math,Yu=mn.Object,Qu=mn.RegExp,Xu=mn.String,ni=mn.TypeError,ti=Vu.prototype,ri=Yu.prototype,ei=mn["__core-js_shared__"],ui=Hu.prototype.toString,ii=ri.hasOwnProperty,oi=0,fi=function(){ +var n=/[^.]+$/.exec(ei&&ei.keys&&ei.keys.IE_PROTO||"");return n?"Symbol(src)_1."+n:""}(),ci=ri.toString,ai=ui.call(Yu),li=$n._,si=Qu("^"+ui.call(ii).replace(rn,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),hi=Pn?mn.Buffer:T,pi=mn.Symbol,_i=mn.Uint8Array,vi=hi?hi.g:T,gi=B(Yu.getPrototypeOf,Yu),di=Yu.create,yi=ri.propertyIsEnumerable,bi=ti.splice,xi=pi?pi.isConcatSpreadable:T,ji=pi?pi.iterator:T,wi=pi?pi.toStringTag:T,mi=function(){try{var n=je(Yu,"defineProperty"); +return n({},"",{}),n}catch(n){}}(),Ai=mn.clearTimeout!==$n.clearTimeout&&mn.clearTimeout,Ei=Ku&&Ku.now!==$n.Date.now&&Ku.now,ki=mn.setTimeout!==$n.setTimeout&&mn.setTimeout,Si=Ju.ceil,Oi=Ju.floor,Ii=Yu.getOwnPropertySymbols,Ri=hi?hi.isBuffer:T,zi=mn.isFinite,Wi=ti.join,Bi=B(Yu.keys,Yu),Li=Ju.max,Ui=Ju.min,Ci=Ku.now,Di=mn.parseInt,Mi=Ju.random,Ti=ti.reverse,$i=je(mn,"DataView"),Fi=je(mn,"Map"),Ni=je(mn,"Promise"),Pi=je(mn,"Set"),Zi=je(mn,"WeakMap"),qi=je(Yu,"create"),Vi=Zi&&new Zi,Ki={},Gi=Me($i),Hi=Me(Fi),Ji=Me(Ni),Yi=Me(Pi),Qi=Me(Zi),Xi=pi?pi.prototype:T,no=Xi?Xi.valueOf:T,to=Xi?Xi.toString:T,ro=function(){ +function n(){}return function(t){return gu(t)?di?di(t):(n.prototype=t,t=new n,n.prototype=T,t):{}}}();An.templateSettings={escape:J,evaluate:Y,interpolate:Q,variable:"",imports:{_:An}},An.prototype=En.prototype,An.prototype.constructor=An,On.prototype=ro(En.prototype),On.prototype.constructor=On,Un.prototype=ro(En.prototype),Un.prototype.constructor=Un,Mn.prototype.clear=function(){this.__data__=qi?qi(null):{},this.size=0},Mn.prototype.delete=function(n){return n=this.has(n)&&delete this.__data__[n], +this.size-=n?1:0,n},Mn.prototype.get=function(n){var t=this.__data__;return qi?(n=t[n],"__lodash_hash_undefined__"===n?T:n):ii.call(t,n)?t[n]:T},Mn.prototype.has=function(n){var t=this.__data__;return qi?t[n]!==T:ii.call(t,n)},Mn.prototype.set=function(n,t){var r=this.__data__;return this.size+=this.has(n)?0:1,r[n]=qi&&t===T?"__lodash_hash_undefined__":t,this},Tn.prototype.clear=function(){this.__data__=[],this.size=0},Tn.prototype.delete=function(n){var t=this.__data__;return n=ft(t,n),!(0>n)&&(n==t.length-1?t.pop():bi.call(t,n,1), +--this.size,true)},Tn.prototype.get=function(n){var t=this.__data__;return n=ft(t,n),0>n?T:t[n][1]},Tn.prototype.has=function(n){return-1e?(++this.size,r.push([n,t])):r[e][1]=t,this},Fn.prototype.clear=function(){this.size=0,this.__data__={hash:new Mn,map:new(Fi||Tn),string:new Mn}},Fn.prototype.delete=function(n){return n=be(this,n).delete(n),this.size-=n?1:0,n},Fn.prototype.get=function(n){return be(this,n).get(n); +},Fn.prototype.has=function(n){return be(this,n).has(n)},Fn.prototype.set=function(n,t){var r=be(this,n),e=r.size;return r.set(n,t),this.size+=r.size==e?0:1,this},Nn.prototype.add=Nn.prototype.push=function(n){return this.__data__.set(n,"__lodash_hash_undefined__"),this},Nn.prototype.has=function(n){return this.__data__.has(n)},Zn.prototype.clear=function(){this.__data__=new Tn,this.size=0},Zn.prototype.delete=function(n){var t=this.__data__;return n=t.delete(n),this.size=t.size,n},Zn.prototype.get=function(n){ +return this.__data__.get(n)},Zn.prototype.has=function(n){return this.__data__.has(n)},Zn.prototype.set=function(n,t){var r=this.__data__;if(r instanceof Tn){var e=r.__data__;if(!Fi||199>e.length)return e.push([n,t]),this.size=++r.size,this;r=this.__data__=new Fn(e)}return r.set(n,t),this.size=r.size,this};var eo=Fr(mt),uo=Fr(At,true),io=Nr(),oo=Nr(true),fo=Vi?function(n,t){return Vi.set(n,t),n}:Tu,co=mi?function(n,t){return mi(n,"toString",{configurable:true,enumerable:false,value:Mu(t),writable:true})}:Tu,ao=Ai||function(n){ +return $n.clearTimeout(n)},lo=Pi&&1/U(new Pi([,-0]))[1]==$?function(n){return new Pi(n)}:Nu,so=Vi?function(n){return Vi.get(n)}:Nu,ho=Ii?function(n){return null==n?[]:(n=Yu(n),i(Ii(n),function(t){return yi.call(n,t)}))}:Zu,po=Ii?function(n){for(var t=[];n;)a(t,ho(n)),n=gi(n);return t}:Zu,_o=Ot;($i&&"[object DataView]"!=_o(new $i(new ArrayBuffer(1)))||Fi&&"[object Map]"!=_o(new Fi)||Ni&&"[object Promise]"!=_o(Ni.resolve())||Pi&&"[object Set]"!=_o(new Pi)||Zi&&"[object WeakMap]"!=_o(new Zi))&&(_o=function(n){ +var t=Ot(n);if(n=(n="[object Object]"==t?n.constructor:T)?Me(n):"")switch(n){case Gi:return"[object DataView]";case Hi:return"[object Map]";case Ji:return"[object Promise]";case Yi:return"[object Set]";case Qi:return"[object WeakMap]"}return t});var vo=ei?pu:qu,go=Ue(fo),yo=ki||function(n,t){return $n.setTimeout(n,t)},bo=Ue(co),xo=function(n){n=fu(n,function(n){return 500===t.size&&t.clear(),n});var t=n.cache;return n}(function(n){var t=[];return 46===n.charCodeAt(0)&&t.push(""),n.replace(tn,function(n,r,e,u){ +t.push(e?u.replace(hn,"$1"):r||n)}),t}),jo=fr(function(n,t){return su(n)?yt(n,wt(t,1,su,true)):[]}),wo=fr(function(n,t){var r=qe(t);return su(r)&&(r=T),su(n)?yt(n,wt(t,1,su,true),ye(r,2)):[]}),mo=fr(function(n,t){var r=qe(t);return su(r)&&(r=T),su(n)?yt(n,wt(t,1,su,true),T,r):[]}),Ao=fr(function(n){var t=c(n,Er);return t.length&&t[0]===n[0]?Wt(t):[]}),Eo=fr(function(n){var t=qe(n),r=c(n,Er);return t===qe(r)?t=T:r.pop(),r.length&&r[0]===n[0]?Wt(r,ye(t,2)):[]}),ko=fr(function(n){var t=qe(n),r=c(n,Er);return(t=typeof t=="function"?t:T)&&r.pop(), +r.length&&r[0]===n[0]?Wt(r,T,t):[]}),So=fr(Ve),Oo=pe(function(n,t){var r=null==n?0:n.length,e=ht(n,t);return ur(n,c(t,function(n){return Se(n,r)?+n:n}).sort(Wr)),e}),Io=fr(function(n){return br(wt(n,1,su,true))}),Ro=fr(function(n){var t=qe(n);return su(t)&&(t=T),br(wt(n,1,su,true),ye(t,2))}),zo=fr(function(n){var t=qe(n),t=typeof t=="function"?t:T;return br(wt(n,1,su,true),T,t)}),Wo=fr(function(n,t){return su(n)?yt(n,t):[]}),Bo=fr(function(n){return mr(i(n,su))}),Lo=fr(function(n){var t=qe(n);return su(t)&&(t=T), +mr(i(n,su),ye(t,2))}),Uo=fr(function(n){var t=qe(n),t=typeof t=="function"?t:T;return mr(i(n,su),T,t)}),Co=fr(Ge),Do=fr(function(n){var t=n.length,t=1=t}),uf=Ut(function(){return arguments}())?Ut:function(n){return du(n)&&ii.call(n,"callee")&&!yi.call(n,"callee")},of=Vu.isArray,ff=Vn?k(Vn):Ct,cf=Ri||qu,af=Kn?k(Kn):Dt,lf=Gn?k(Gn):Tt,sf=Hn?k(Hn):Nt,hf=Jn?k(Jn):Pt,pf=Yn?k(Yn):Zt,_f=ee(Kt),vf=ee(function(n,t){return n<=t}),gf=$r(function(n,t){ +if(ze(t)||lu(t))Cr(t,zu(t),n);else for(var r in t)ii.call(t,r)&&ot(n,r,t[r])}),df=$r(function(n,t){Cr(t,Wu(t),n)}),yf=$r(function(n,t,r,e){Cr(t,Wu(t),n,e)}),bf=$r(function(n,t,r,e){Cr(t,zu(t),n,e)}),xf=pe(ht),jf=fr(function(n,t){n=Yu(n);var r=-1,e=t.length,u=2--n)return t.apply(this,arguments)}},An.ary=ru,An.assign=gf,An.assignIn=df,An.assignInWith=yf,An.assignWith=bf,An.at=xf,An.before=eu,An.bind=Go,An.bindAll=Ff,An.bindKey=Ho,An.castArray=function(){if(!arguments.length)return[];var n=arguments[0];return of(n)?n:[n]},An.chain=Je,An.chunk=function(n,t,r){if(t=(r?Oe(n,t,r):t===T)?1:Li(Au(t),0),r=null==n?0:n.length,!r||1>t)return[];for(var e=0,u=0,i=Vu(Si(r/t));et?0:t,e)):[]},An.dropRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Au(t),t=e-t,hr(n,0,0>t?0:t)):[]},An.dropRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true,true):[]; +},An.dropWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true):[]},An.fill=function(n,t,r,e){var u=null==n?0:n.length;if(!u)return[];for(r&&typeof r!="number"&&Oe(n,t,r)&&(r=0,e=u),u=n.length,r=Au(r),0>r&&(r=-r>u?0:u+r),e=e===T||e>u?u:Au(e),0>e&&(e+=u),e=r>e?0:Eu(e);r>>0,r?(n=Ou(n))&&(typeof t=="string"||null!=t&&!sf(t))&&(t=yr(t),!t&&Rn.test(n))?Or(M(n),0,r):n.split(t,r):[]},An.spread=function(t,r){if(typeof t!="function")throw new ni("Expected a function");return r=null==r?0:Li(Au(r),0), +fr(function(e){var u=e[r];return e=Or(e,0,r),u&&a(e,u),n(t,this,e)})},An.tail=function(n){var t=null==n?0:n.length;return t?hr(n,1,t):[]},An.take=function(n,t,r){return n&&n.length?(t=r||t===T?1:Au(t),hr(n,0,0>t?0:t)):[]},An.takeRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Au(t),t=e-t,hr(n,0>t?0:t,e)):[]},An.takeRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),false,true):[]},An.takeWhile=function(n,t){return n&&n.length?jr(n,ye(t,3)):[]},An.tap=function(n,t){return t(n), +n},An.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new ni("Expected a function");return gu(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),ou(n,t,{leading:e,maxWait:t,trailing:u})},An.thru=Ye,An.toArray=wu,An.toPairs=Rf,An.toPairsIn=zf,An.toPath=function(n){return of(n)?c(n,De):ju(n)?[n]:Ur(xo(Ou(n)))},An.toPlainObject=Su,An.transform=function(n,t,e){var u=of(n),i=u||cf(n)||pf(n);if(t=ye(t,4),null==e){var o=n&&n.constructor;e=i?u?new o:[]:gu(n)&&pu(o)?ro(gi(n)):{}; +}return(i?r:mt)(n,function(n,r,u){return t(e,n,r,u)}),e},An.unary=function(n){return ru(n,1)},An.union=Io,An.unionBy=Ro,An.unionWith=zo,An.uniq=function(n){return n&&n.length?br(n):[]},An.uniqBy=function(n,t){return n&&n.length?br(n,ye(t,2)):[]},An.uniqWith=function(n,t){return t=typeof t=="function"?t:T,n&&n.length?br(n,T,t):[]},An.unset=function(n,t){return null==n||xr(n,t)},An.unzip=Ge,An.unzipWith=He,An.update=function(n,t,r){return null==n?n:lr(n,t,kr(r)(kt(n,t)),void 0)},An.updateWith=function(n,t,r,e){ +return e=typeof e=="function"?e:T,null!=n&&(n=lr(n,t,kr(r)(kt(n,t)),e)),n},An.values=Lu,An.valuesIn=function(n){return null==n?[]:S(n,Wu(n))},An.without=Wo,An.words=Du,An.wrap=function(n,t){return Xo(kr(t),n)},An.xor=Bo,An.xorBy=Lo,An.xorWith=Uo,An.zip=Co,An.zipObject=function(n,t){return Ar(n||[],t||[],ot)},An.zipObjectDeep=function(n,t){return Ar(n||[],t||[],lr)},An.zipWith=Do,An.entries=Rf,An.entriesIn=zf,An.extend=df,An.extendWith=yf,Fu(An,An),An.add=Yf,An.attempt=$f,An.camelCase=Wf,An.capitalize=Uu, +An.ceil=Qf,An.clamp=function(n,t,r){return r===T&&(r=t,t=T),r!==T&&(r=ku(r),r=r===r?r:0),t!==T&&(t=ku(t),t=t===t?t:0),pt(ku(n),t,r)},An.clone=function(n){return _t(n,4)},An.cloneDeep=function(n){return _t(n,5)},An.cloneDeepWith=function(n,t){return t=typeof t=="function"?t:T,_t(n,5,t)},An.cloneWith=function(n,t){return t=typeof t=="function"?t:T,_t(n,4,t)},An.conformsTo=function(n,t){return null==t||gt(n,t,zu(t))},An.deburr=Cu,An.defaultTo=function(n,t){return null==n||n!==n?t:n},An.divide=Xf,An.endsWith=function(n,t,r){ +n=Ou(n),t=yr(t);var e=n.length,e=r=r===T?e:pt(Au(r),0,e);return r-=t.length,0<=r&&n.slice(r,e)==t},An.eq=au,An.escape=function(n){return(n=Ou(n))&&H.test(n)?n.replace(K,nt):n},An.escapeRegExp=function(n){return(n=Ou(n))&&en.test(n)?n.replace(rn,"\\$&"):n},An.every=function(n,t,r){var e=of(n)?u:bt;return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.find=$o,An.findIndex=Fe,An.findKey=function(n,t){return p(n,ye(t,3),mt)},An.findLast=Fo,An.findLastIndex=Ne,An.findLastKey=function(n,t){return p(n,ye(t,3),At); +},An.floor=nc,An.forEach=Xe,An.forEachRight=nu,An.forIn=function(n,t){return null==n?n:io(n,ye(t,3),Wu)},An.forInRight=function(n,t){return null==n?n:oo(n,ye(t,3),Wu)},An.forOwn=function(n,t){return n&&mt(n,ye(t,3))},An.forOwnRight=function(n,t){return n&&At(n,ye(t,3))},An.get=Iu,An.gt=rf,An.gte=ef,An.has=function(n,t){return null!=n&&we(n,t,Rt)},An.hasIn=Ru,An.head=Ze,An.identity=Tu,An.includes=function(n,t,r,e){return n=lu(n)?n:Lu(n),r=r&&!e?Au(r):0,e=n.length,0>r&&(r=Li(e+r,0)),xu(n)?r<=e&&-1r&&(r=Li(e+r,0)),v(n,t,r)):-1},An.inRange=function(n,t,r){return t=mu(t),r===T?(r=t,t=0):r=mu(r),n=ku(n),n>=Ui(t,r)&&n=n},An.isSet=hf,An.isString=xu,An.isSymbol=ju,An.isTypedArray=pf,An.isUndefined=function(n){return n===T},An.isWeakMap=function(n){return du(n)&&"[object WeakMap]"==_o(n)},An.isWeakSet=function(n){return du(n)&&"[object WeakSet]"==Ot(n)},An.join=function(n,t){return null==n?"":Wi.call(n,t)},An.kebabCase=Bf,An.last=qe,An.lastIndexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;if(r!==T&&(u=Au(r),u=0>u?Li(e+u,0):Ui(u,e-1)), +t===t){for(r=u+1;r--&&n[r]!==t;);n=r}else n=_(n,d,u,true);return n},An.lowerCase=Lf,An.lowerFirst=Uf,An.lt=_f,An.lte=vf,An.max=function(n){return n&&n.length?xt(n,Tu,It):T},An.maxBy=function(n,t){return n&&n.length?xt(n,ye(t,2),It):T},An.mean=function(n){return y(n,Tu)},An.meanBy=function(n,t){return y(n,ye(t,2))},An.min=function(n){return n&&n.length?xt(n,Tu,Kt):T},An.minBy=function(n,t){return n&&n.length?xt(n,ye(t,2),Kt):T},An.stubArray=Zu,An.stubFalse=qu,An.stubObject=function(){return{}},An.stubString=function(){ +return""},An.stubTrue=function(){return true},An.multiply=tc,An.nth=function(n,t){return n&&n.length?Qt(n,Au(t)):T},An.noConflict=function(){return $n._===this&&($n._=li),this},An.noop=Nu,An.now=Ko,An.pad=function(n,t,r){n=Ou(n);var e=(t=Au(t))?D(n):0;return!t||e>=t?n:(t=(t-e)/2,ne(Oi(t),r)+n+ne(Si(t),r))},An.padEnd=function(n,t,r){n=Ou(n);var e=(t=Au(t))?D(n):0;return t&&et){var e=n;n=t,t=e}return r||n%1||t%1?(r=Mi(),Ui(n+r*(t-n+Cn("1e-"+((r+"").length-1))),t)):ir(n,t)},An.reduce=function(n,t,r){var e=of(n)?l:j,u=3>arguments.length;return e(n,ye(t,4),r,u,eo)},An.reduceRight=function(n,t,r){var e=of(n)?s:j,u=3>arguments.length; +return e(n,ye(t,4),r,u,uo)},An.repeat=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:Au(t),or(Ou(n),t)},An.replace=function(){var n=arguments,t=Ou(n[0]);return 3>n.length?t:t.replace(n[1],n[2])},An.result=function(n,t,r){t=Sr(t,n);var e=-1,u=t.length;for(u||(u=1,n=T);++en||9007199254740991=i)return n;if(i=r-D(e),1>i)return e;if(r=o?Or(o,0,i).join(""):n.slice(0,i),u===T)return r+e;if(o&&(i+=r.length-i),sf(u)){if(n.slice(i).search(u)){var f=r;for(u.global||(u=Qu(u.source,Ou(_n.exec(u))+"g")), +u.lastIndex=0;o=u.exec(f);)var c=o.index;r=r.slice(0,c===T?i:c)}}else n.indexOf(yr(u),i)!=i&&(u=r.lastIndexOf(u),-1e.__dir__?"Right":"")}),e},Un.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),r(["filter","map","takeWhile"],function(n,t){var r=t+1,e=1==r||3==r;Un.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({ +iteratee:ye(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),r(["head","last"],function(n,t){var r="take"+(t?"Right":"");Un.prototype[n]=function(){return this[r](1).value()[0]}}),r(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");Un.prototype[n]=function(){return this.__filtered__?new Un(this):this[r](1)}}),Un.prototype.compact=function(){return this.filter(Tu)},Un.prototype.find=function(n){return this.filter(n).head()},Un.prototype.findLast=function(n){return this.reverse().find(n); +},Un.prototype.invokeMap=fr(function(n,t){return typeof n=="function"?new Un(this):this.map(function(r){return Lt(r,n,t)})}),Un.prototype.reject=function(n){return this.filter(cu(ye(n)))},Un.prototype.slice=function(n,t){n=Au(n);var r=this;return r.__filtered__&&(0t)?new Un(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==T&&(t=Au(t),r=0>t?r.dropRight(-t):r.take(t-n)),r)},Un.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},Un.prototype.toArray=function(){return this.take(4294967295); +},mt(Un.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=An[e?"take"+("last"==t?"Right":""):t],i=e||/^find/.test(t);u&&(An.prototype[t]=function(){function t(n){return n=u.apply(An,a([n],f)),e&&h?n[0]:n}var o=this.__wrapped__,f=e?[1]:arguments,c=o instanceof Un,l=f[0],s=c||of(o);s&&r&&typeof l=="function"&&1!=l.length&&(c=s=false);var h=this.__chain__,p=!!this.__actions__.length,l=i&&!h,c=c&&!p;return!i&&s?(o=c?o:new Un(this),o=n.apply(o,f),o.__actions__.push({ +func:Ye,args:[t],thisArg:T}),new On(o,h)):l&&c?n.apply(this,f):(o=this.thru(t),l?e?o.value()[0]:o.value():o)})}),r("pop push shift sort splice unshift".split(" "),function(n){var t=ti[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);An.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var u=this.value();return t.apply(of(u)?u:[],n)}return this[r](function(r){return t.apply(of(r)?r:[],n)})}}),mt(Un.prototype,function(n,t){var r=An[t];if(r){var e=r.name+""; +(Ki[e]||(Ki[e]=[])).push({name:t,func:r})}}),Ki[Jr(T,2).name]=[{name:"wrapper",func:T}],Un.prototype.clone=function(){var n=new Un(this.__wrapped__);return n.__actions__=Ur(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Ur(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=Ur(this.__views__),n},Un.prototype.reverse=function(){if(this.__filtered__){var n=new Un(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n; +},Un.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=of(t),u=0>r,i=e?t.length:0;n=i;for(var o=this.__views__,f=0,c=-1,a=o.length;++c=this.__values__.length;return{done:n,value:n?T:this.__values__[this.__index__++]}},An.prototype.plant=function(n){for(var t,r=this;r instanceof En;){ +var e=$e(r);e.__index__=0,e.__values__=T,t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},An.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Un?(this.__actions__.length&&(n=new Un(this)),n=n.reverse(),n.__actions__.push({func:Ye,args:[Ke],thisArg:T}),new On(n,this.__chain__)):this.thru(Ke)},An.prototype.toJSON=An.prototype.valueOf=An.prototype.value=function(){return wr(this.__wrapped__,this.__actions__)},An.prototype.first=An.prototype.head,ji&&(An.prototype[ji]=Qe), +An}();typeof define=="function"&&typeof define.amd=="object"&&define.amd?($n._=rt, define(function(){return rt})):Nn?((Nn.exports=rt)._=rt,Fn._=rt):$n._=rt}).call(this); diff --git a/net452/SiteServer.Web/Home/assets/lib/md5-2.10.0.min.js b/net452/SiteServer.Web/Home/assets/lib/md5-2.10.0.min.js new file mode 100644 index 000000000..7d8a3f53c --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/lib/md5-2.10.0.min.js @@ -0,0 +1,2 @@ +!function(n){"use strict";function t(n,t){var r=(65535&n)+(65535&t);return(n>>16)+(t>>16)+(r>>16)<<16|65535&r}function r(n,t){return n<>>32-t}function e(n,e,o,u,c,f){return t(r(t(t(e,n),t(u,f)),c),o)}function o(n,t,r,o,u,c,f){return e(t&r|~t&o,n,t,u,c,f)}function u(n,t,r,o,u,c,f){return e(t&o|r&~o,n,t,u,c,f)}function c(n,t,r,o,u,c,f){return e(t^r^o,n,t,u,c,f)}function f(n,t,r,o,u,c,f){return e(r^(t|~o),n,t,u,c,f)}function i(n,r){n[r>>5]|=128<>>9<<4)]=r;var e,i,a,d,h,l=1732584193,g=-271733879,v=-1732584194,m=271733878;for(e=0;e>5]>>>t%32&255);return r}function d(n){var t,r=[];for(r[(n.length>>2)-1]=void 0,t=0;t>5]|=(255&n.charCodeAt(t/8))<16&&(o=i(o,8*n.length)),r=0;r<16;r+=1)u[r]=909522486^o[r],c[r]=1549556828^o[r];return e=i(u.concat(d(t)),512+8*t.length),a(i(c.concat(e),640))}function g(n){var t,r,e="";for(r=0;r>>4&15)+"0123456789abcdef".charAt(15&t);return e}function v(n){return unescape(encodeURIComponent(n))}function m(n){return h(v(n))}function p(n){return g(m(n))}function s(n,t){return l(v(n),v(t))}function C(n,t){return g(s(n,t))}function A(n,t,r){return t?r?s(t,n):C(t,n):r?m(n):p(n)}"function"==typeof define&&define.amd?define(function(){return A}):"object"==typeof module&&module.exports?module.exports=A:n.md5=A}(this); +//# sourceMappingURL=md5.min.js.map \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/assets/lib/modernizr.min.js b/net452/SiteServer.Web/Home/assets/lib/modernizr.min.js new file mode 100644 index 000000000..40dd2a9fe --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/lib/modernizr.min.js @@ -0,0 +1 @@ +window.Modernizr=function(e,t,n){function r(e){b.cssText=e}function o(e,t){return r(S.join(e+";")+(t||""))}function a(e,t){return typeof e===t}function i(e,t){return!!~(""+e).indexOf(t)}function c(e,t){for(var r in e){var o=e[r];if(!i(o,"-")&&b[o]!==n)return"pfx"==t?o:!0}return!1}function s(e,t,r){for(var o in e){var i=t[e[o]];if(i!==n)return r===!1?e[o]:a(i,"function")?i.bind(r||t):i}return!1}function u(e,t,n){var r=e.charAt(0).toUpperCase()+e.slice(1),o=(e+" "+k.join(r+" ")+r).split(" ");return a(t,"string")||a(t,"undefined")?c(o,t):(o=(e+" "+T.join(r+" ")+r).split(" "),s(o,t,n))}function l(){p.input=function(n){for(var r=0,o=n.length;o>r;r++)j[n[r]]=!!(n[r]in E);return j.list&&(j.list=!(!t.createElement("datalist")||!e.HTMLDataListElement)),j}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")),p.inputtypes=function(e){for(var r,o,a,i=0,c=e.length;c>i;i++)E.setAttribute("type",o=e[i]),r="text"!==E.type,r&&(E.value=x,E.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(o)&&E.style.WebkitAppearance!==n?(g.appendChild(E),a=t.defaultView,r=a.getComputedStyle&&"textfield"!==a.getComputedStyle(E,null).WebkitAppearance&&0!==E.offsetHeight,g.removeChild(E)):/^(search|tel)$/.test(o)||(r=/^(url|email)$/.test(o)?E.checkValidity&&E.checkValidity()===!1:E.value!=x)),P[e[i]]=!!r;return P}("search tel url email datetime date month week time datetime-local number range color".split(" "))}var d,f,m="2.8.3",p={},h=!0,g=t.documentElement,v="modernizr",y=t.createElement(v),b=y.style,E=t.createElement("input"),x=":)",w={}.toString,S=" -webkit- -moz- -o- -ms- ".split(" "),C="Webkit Moz O ms",k=C.split(" "),T=C.toLowerCase().split(" "),N={svg:"http://www.w3.org/2000/svg"},M={},P={},j={},$=[],D=$.slice,F=function(e,n,r,o){var a,i,c,s,u=t.createElement("div"),l=t.body,d=l||t.createElement("body");if(parseInt(r,10))for(;r--;)c=t.createElement("div"),c.id=o?o[r]:v+(r+1),u.appendChild(c);return a=["­",'"].join(""),u.id=v,(l?u:d).innerHTML+=a,d.appendChild(u),l||(d.style.background="",d.style.overflow="hidden",s=g.style.overflow,g.style.overflow="hidden",g.appendChild(d)),i=n(u,e),l?u.parentNode.removeChild(u):(d.parentNode.removeChild(d),g.style.overflow=s),!!i},z=function(t){var n=e.matchMedia||e.msMatchMedia;if(n)return n(t)&&n(t).matches||!1;var r;return F("@media "+t+" { #"+v+" { position: absolute; } }",function(t){r="absolute"==(e.getComputedStyle?getComputedStyle(t,null):t.currentStyle).position}),r},A=function(){function e(e,o){o=o||t.createElement(r[e]||"div"),e="on"+e;var i=e in o;return i||(o.setAttribute||(o=t.createElement("div")),o.setAttribute&&o.removeAttribute&&(o.setAttribute(e,""),i=a(o[e],"function"),a(o[e],"undefined")||(o[e]=n),o.removeAttribute(e))),o=null,i}var r={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return e}(),L={}.hasOwnProperty;f=a(L,"undefined")||a(L.call,"undefined")?function(e,t){return t in e&&a(e.constructor.prototype[t],"undefined")}:function(e,t){return L.call(e,t)},Function.prototype.bind||(Function.prototype.bind=function(e){var t=this;if("function"!=typeof t)throw new TypeError;var n=D.call(arguments,1),r=function(){if(this instanceof r){var o=function(){};o.prototype=t.prototype;var a=new o,i=t.apply(a,n.concat(D.call(arguments)));return Object(i)===i?i:a}return t.apply(e,n.concat(D.call(arguments)))};return r}),M.flexbox=function(){return u("flexWrap")},M.flexboxlegacy=function(){return u("boxDirection")},M.canvas=function(){var e=t.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))},M.canvastext=function(){return!(!p.canvas||!a(t.createElement("canvas").getContext("2d").fillText,"function"))},M.webgl=function(){return!!e.WebGLRenderingContext},M.touch=function(){var n;return"ontouchstart"in e||e.DocumentTouch&&t instanceof DocumentTouch?n=!0:F(["@media (",S.join("touch-enabled),("),v,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(e){n=9===e.offsetTop}),n},M.geolocation=function(){return"geolocation"in navigator},M.postmessage=function(){return!!e.postMessage},M.websqldatabase=function(){return!!e.openDatabase},M.indexedDB=function(){return!!u("indexedDB",e)},M.hashchange=function(){return A("hashchange",e)&&(t.documentMode===n||t.documentMode>7)},M.history=function(){return!(!e.history||!history.pushState)},M.draganddrop=function(){var e=t.createElement("div");return"draggable"in e||"ondragstart"in e&&"ondrop"in e},M.websockets=function(){return"WebSocket"in e||"MozWebSocket"in e},M.rgba=function(){return r("background-color:rgba(150,255,150,.5)"),i(b.backgroundColor,"rgba")},M.hsla=function(){return r("background-color:hsla(120,40%,100%,.5)"),i(b.backgroundColor,"rgba")||i(b.backgroundColor,"hsla")},M.multiplebgs=function(){return r("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(b.background)},M.backgroundsize=function(){return u("backgroundSize")},M.borderimage=function(){return u("borderImage")},M.borderradius=function(){return u("borderRadius")},M.boxshadow=function(){return u("boxShadow")},M.textshadow=function(){return""===t.createElement("div").style.textShadow},M.opacity=function(){return o("opacity:.55"),/^0.55$/.test(b.opacity)},M.cssanimations=function(){return u("animationName")},M.csscolumns=function(){return u("columnCount")},M.cssgradients=function(){var e="background-image:",t="gradient(linear,left top,right bottom,from(#9f9),to(white));",n="linear-gradient(left top,#9f9, white);";return r((e+"-webkit- ".split(" ").join(t+e)+S.join(n+e)).slice(0,-e.length)),i(b.backgroundImage,"gradient")},M.cssreflections=function(){return u("boxReflect")},M.csstransforms=function(){return!!u("transform")},M.csstransforms3d=function(){var e=!!u("perspective");return e&&"webkitPerspective"in g.style&&F("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(t){e=9===t.offsetLeft&&3===t.offsetHeight}),e},M.csstransitions=function(){return u("transition")},M.fontface=function(){var e;return F('@font-face {font-family:"font";src:url("https://")}',function(n,r){var o=t.getElementById("smodernizr"),a=o.sheet||o.styleSheet,i=a?a.cssRules&&a.cssRules[0]?a.cssRules[0].cssText:a.cssText||"":"";e=/src/i.test(i)&&0===i.indexOf(r.split(" ")[0])}),e},M.generatedcontent=function(){var e;return F(["#",v,"{font:0/0 a}#",v,':after{content:"',x,'";visibility:hidden;font:3px/1 a}'].join(""),function(t){e=t.offsetHeight>=3}),e},M.video=function(){var e=t.createElement("video"),n=!1;try{(n=!!e.canPlayType)&&(n=new Boolean(n),n.ogg=e.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),n.h264=e.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),n.webm=e.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,""))}catch(r){}return n},M.audio=function(){var e=t.createElement("audio"),n=!1;try{(n=!!e.canPlayType)&&(n=new Boolean(n),n.ogg=e.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),n.mp3=e.canPlayType("audio/mpeg;").replace(/^no$/,""),n.wav=e.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),n.m4a=(e.canPlayType("audio/x-m4a;")||e.canPlayType("audio/aac;")).replace(/^no$/,""))}catch(r){}return n},M.localstorage=function(){try{return localStorage.setItem(v,v),localStorage.removeItem(v),!0}catch(e){return!1}},M.sessionstorage=function(){try{return sessionStorage.setItem(v,v),sessionStorage.removeItem(v),!0}catch(e){return!1}},M.webworkers=function(){return!!e.Worker},M.applicationcache=function(){return!!e.applicationCache},M.svg=function(){return!!t.createElementNS&&!!t.createElementNS(N.svg,"svg").createSVGRect},M.inlinesvg=function(){var e=t.createElement("div");return e.innerHTML="",(e.firstChild&&e.firstChild.namespaceURI)==N.svg},M.smil=function(){return!!t.createElementNS&&/SVGAnimate/.test(w.call(t.createElementNS(N.svg,"animate")))},M.svgclippaths=function(){return!!t.createElementNS&&/SVGClipPath/.test(w.call(t.createElementNS(N.svg,"clipPath")))};for(var H in M)f(M,H)&&(d=H.toLowerCase(),p[d]=M[H](),$.push((p[d]?"":"no-")+d));return p.input||l(),p.addTest=function(e,t){if("object"==typeof e)for(var r in e)f(e,r)&&p.addTest(r,e[r]);else{if(e=e.toLowerCase(),p[e]!==n)return p;t="function"==typeof t?t():t,"undefined"!=typeof h&&h&&(g.className+=" "+(t?"":"no-")+e),p[e]=t}return p},r(""),y=E=null,function(e,t){function n(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x",r.insertBefore(n.lastChild,r.firstChild)}function r(){var e=y.elements;return"string"==typeof e?e.split(" "):e}function o(e){var t=v[e[h]];return t||(t={},g++,e[h]=g,v[g]=t),t}function a(e,n,r){if(n||(n=t),l)return n.createElement(e);r||(r=o(n));var a;return a=r.cache[e]?r.cache[e].cloneNode():p.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!a.canHaveChildren||m.test(e)||a.tagUrn?a:r.frag.appendChild(a)}function i(e,n){if(e||(e=t),l)return e.createDocumentFragment();n=n||o(e);for(var a=n.frag.cloneNode(),i=0,c=r(),s=c.length;s>i;i++)a.createElement(c[i]);return a}function c(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return y.shivMethods?a(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+r().join().replace(/[\w\-]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(y,t.frag)}function s(e){e||(e=t);var r=o(e);return!y.shivCSS||u||r.hasCSS||(r.hasCSS=!!n(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||c(e,r),e}var u,l,d="3.7.0",f=e.html5||{},m=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,h="_html5shiv",g=0,v={};!function(){try{var e=t.createElement("a");e.innerHTML="",u="hidden"in e,l=1==e.childNodes.length||function(){t.createElement("a");var e=t.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(n){u=!0,l=!0}}();var y={elements:f.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:d,shivCSS:f.shivCSS!==!1,supportsUnknownElements:l,shivMethods:f.shivMethods!==!1,type:"default",shivDocument:s,createElement:a,createDocumentFragment:i};e.html5=y,s(t)}(this,t),p._version=m,p._prefixes=S,p._domPrefixes=T,p._cssomPrefixes=k,p.mq=z,p.hasEvent=A,p.testProp=function(e){return c([e])},p.testAllProps=u,p.testStyles=F,p.prefixed=function(e,t,n){return t?u(e,t,n):u(e,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(h?" js "+$.join(" "):""),p}(this,this.document); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/assets/lib/popper.min.js b/net452/SiteServer.Web/Home/assets/lib/popper.min.js new file mode 100644 index 000000000..95e9ef5a2 --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/lib/popper.min.js @@ -0,0 +1,5 @@ +/* + Copyright (C) Federico Zivolo 2017 + Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). + */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=window.getComputedStyle(e,null);return t?o[t]:o}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e||-1!==['HTML','BODY','#document'].indexOf(e.nodeName))return window.document.body;var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll)/.test(r+s+p)?e:n(o(e))}function r(e){var o=e&&e.offsetParent,i=o&&o.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TD','TABLE'].indexOf(o.nodeName)&&'static'===t(o,'position')?r(o):o:window.document.documentElement}function p(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||r(e.firstElementChild)===e)}function s(e){return null===e.parentNode?e:s(e.parentNode)}function d(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return window.document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,i=o?e:t,n=o?t:e,a=document.createRange();a.setStart(i,0),a.setEnd(n,0);var f=a.commonAncestorContainer;if(e!==f&&t!==f||i.contains(n))return p(f)?f:r(f);var l=s(e);return l.host?d(l.host,t):d(e,s(t).host)}function a(e){var t=1=o.clientWidth&&i>=o.clientHeight}),f=0i[e]&&!t.escapeWithReference&&(n=z(p[o],i[e]-('right'===e?p.width:p.height))),pe({},o,n)}};return n.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';p=se({},p,s[t](e))}),e.offsets.popper=p,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,i=t.reference,n=e.placement.split('-')[0],r=V,p=-1!==['top','bottom'].indexOf(n),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]r(i[s])&&(e.offsets.popper[d]=r(i[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!F(e.instance.modifiers,'arrow','keepTogether'))return e;var o=t.element;if('string'==typeof o){if(o=e.instance.popper.querySelector(o),!o)return e;}else if(!e.instance.popper.contains(o))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var i=e.placement.split('-')[0],n=e.offsets,r=n.popper,p=n.reference,s=-1!==['left','right'].indexOf(i),d=s?'height':'width',a=s?'top':'left',f=s?'left':'top',l=s?'bottom':'right',m=O(o)[d];p[l]-mr[l]&&(e.offsets.popper[a]+=p[a]+m-r[l]);var h=p[a]+p[d]/2-m/2,g=h-c(e.offsets.popper)[a];return g=_(z(r[d]-m,g),0),e.arrowElement=o,e.offsets.arrow={},e.offsets.arrow[a]=Math.round(g),e.offsets.arrow[f]='',e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=w(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement),i=e.placement.split('-')[0],n=L(i),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case fe.FLIP:p=[i,n];break;case fe.CLOCKWISE:p=K(i);break;case fe.COUNTERCLOCKWISE:p=K(i,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(i!==s||p.length===d+1)return e;i=e.placement.split('-')[0],n=L(i);var a=e.offsets.popper,f=e.offsets.reference,l=V,m='left'===i&&l(a.right)>l(f.left)||'right'===i&&l(a.left)l(f.top)||'bottom'===i&&l(a.top)l(o.right),g=l(a.top)l(o.bottom),b='left'===i&&h||'right'===i&&c||'top'===i&&g||'bottom'===i&&u,y=-1!==['top','bottom'].indexOf(i),w=!!t.flipVariations&&(y&&'start'===r&&h||y&&'end'===r&&c||!y&&'start'===r&&g||!y&&'end'===r&&u);(m||b||w)&&(e.flipped=!0,(m||b)&&(i=p[d+1]),w&&(r=j(r)),e.placement=i+(r?'-'+r:''),e.offsets.popper=se({},e.offsets.popper,S(e.instance.popper,e.offsets.reference,e.placement)),e=N(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],i=e.offsets,n=i.popper,r=i.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return n[p?'left':'top']=r[t]-(s?n[p?'width':'height']:0),e.placement=L(t),e.offsets.popper=c(n),e}},hide:{order:800,enabled:!0,fn:function(e){if(!F(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=T(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottomo.right||t.top>o.bottom||t.right\n
    \n
      \n
      \n \n
      \n
      \n ?\n
      \n
      \n !\n
      \n
      \n i\n
      \n
      \n
      \n \n
      \n
      \n
      \n \n

      \n \n
      \n
      \n
      \n \n \n
      \n \n \n
      \n \n
      \n \n \n
      \n
      \n
      \n \n \n
      \n
      \n
      \n \n').replace(/(^|\n)\s*/g,""),X=function(e){var t=w();if(t&&(t.parentNode.removeChild(t),W([document.documentElement,document.body],[_["no-backdrop"],_["toast-shown"],_["has-column"]])),!j()){var n=document.createElement("div");n.className=_.container,n.innerHTML=M,("string"==typeof e.target?document.querySelector(e.target):e.target).appendChild(n);var o,i=k(),r=B(),a=z(r,_.input),s=z(r,_.file),c=r.querySelector(".".concat(_.range," input")),u=r.querySelector(".".concat(_.range," output")),l=z(r,_.select),d=r.querySelector(".".concat(_.checkbox," input")),p=z(r,_.textarea);i.setAttribute("role",e.toast?"alert":"dialog"),i.setAttribute("aria-live",e.toast?"polite":"assertive"),e.toast||i.setAttribute("aria-modal","true");var f=function(e){He.isVisible()&&o!==e.target.value&&He.resetValidationMessage(),o=e.target.value};return a.oninput=f,s.onchange=f,l.onchange=f,d.onchange=f,p.oninput=f,c.oninput=function(e){f(e),u.value=c.value},c.onchange=function(e){f(e),c.nextSibling.value=c.value},i}R("SweetAlert2 requires document to initialize")},G=function(e,t){if(!e)return K(t);if("object"===V(e))if(t.innerHTML="",0 in e)for(var n=0;n in e;n++)t.appendChild(e[n].cloneNode(!0));else t.appendChild(e.cloneNode(!0));else e&&(t.innerHTML=e);U(t)},ee=function(){if(j())return!1;var e=document.createElement("div"),t={WebkitAnimation:"webkitAnimationEnd",OAnimation:"oAnimationEnd oanimationend",animation:"animationend"};for(var n in t)if(t.hasOwnProperty(n)&&void 0!==e.style[n])return t[n];return!1}(),te=function(e){var t=Q(),n=E(),o=Z();if(e.showConfirmButton||e.showCancelButton?U(t):K(t),e.showCancelButton?o.style.display="inline-block":K(o),e.showConfirmButton?n.style.removeProperty("display"):K(n),n.innerHTML=e.confirmButtonText,o.innerHTML=e.cancelButtonText,n.setAttribute("aria-label",e.confirmButtonAriaLabel),o.setAttribute("aria-label",e.cancelButtonAriaLabel),n.className=_.confirm,N(n,e.confirmButtonClass),o.className=_.cancel,N(o,e.cancelButtonClass),e.buttonsStyling){N([n,o],_.styled),e.confirmButtonColor&&(n.style.backgroundColor=e.confirmButtonColor),e.cancelButtonColor&&(o.style.backgroundColor=e.cancelButtonColor);var i=window.getComputedStyle(n).getPropertyValue("background-color");n.style.borderLeftColor=i,n.style.borderRightColor=i}else W([n,o],_.styled),n.style.backgroundColor=n.style.borderLeftColor=n.style.borderRightColor="",o.style.backgroundColor=o.style.borderLeftColor=o.style.borderRightColor=""},ne=function(e){var t=B().querySelector("#"+_.content);e.html?G(e.html,t):e.text?(t.textContent=e.text,U(t)):K(t)},oe=function(e){for(var t=x(),n=0;n=i.progressSteps.length&&q("Invalid currentProgressStep parameter, it should be less than progressSteps.length (currentProgressStep like JS arrays starts from 0)"),i.progressSteps.forEach(function(e,t){var n=document.createElement("li");if(N(n,_.progresscircle),n.innerHTML=e,t===a&&N(n,_.activeprogressstep),r.appendChild(n),t!==i.progressSteps.length-1){var o=document.createElement("li");N(o,_.progressline),i.progressStepsDistance&&(o.style.width=i.progressStepsDistance),r.appendChild(o)}})):K(r)},ae=function(e){var t=A();e.titleText?t.innerText=e.titleText:e.title&&("string"==typeof e.title&&(e.title=e.title.split("\n").join("
      ")),G(e.title,t))},se=function(){null===b.previousBodyPadding&&document.body.scrollHeight>window.innerHeight&&(b.previousBodyPadding=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right")),document.body.style.paddingRight=b.previousBodyPadding+function(){if("ontouchstart"in window||navigator.msMaxTouchPoints)return 0;var e=document.createElement("div");e.style.width="50px",e.style.height="50px",e.style.overflow="scroll",document.body.appendChild(e);var t=e.offsetWidth-e.clientWidth;return document.body.removeChild(e),t}()+"px")},ce={},ue=function(e,t){var n=w(),o=k();if(o){null!==e&&"function"==typeof e&&e(o),W(o,_.show),N(o,_.hide);var i=function(){T()?le(t):(new Promise(function(e){var t=window.scrollX,n=window.scrollY;ce.restoreFocusTimeout=setTimeout(function(){ce.previousActiveElement&&ce.previousActiveElement.focus?(ce.previousActiveElement.focus(),ce.previousActiveElement=null):document.body&&document.body.focus(),e()},100),void 0!==t&&void 0!==n&&window.scrollTo(t,n)}).then(function(){return le(t)}),ce.keydownTarget.removeEventListener("keydown",ce.keydownHandler,{capture:ce.keydownListenerCapture}),ce.keydownHandlerAdded=!1),n.parentNode&&n.parentNode.removeChild(n),W([document.documentElement,document.body],[_.shown,_["height-auto"],_["no-backdrop"],_["toast-shown"],_["toast-column"]]),L()&&(null!==b.previousBodyPadding&&(document.body.style.paddingRight=b.previousBodyPadding,b.previousBodyPadding=null),function(){if(v(document.body,_.iosfix)){var e=parseInt(document.body.style.top,10);W(document.body,_.iosfix),document.body.style.top="",document.body.scrollTop=-1*e}}(),f(document.body.children).forEach(function(e){e.hasAttribute("data-previous-aria-hidden")?(e.setAttribute("aria-hidden",e.getAttribute("data-previous-aria-hidden")),e.removeAttribute("data-previous-aria-hidden")):e.removeAttribute("aria-hidden")}))};ee&&!v(o,_.noanimation)?o.addEventListener(ee,function e(){o.removeEventListener(ee,e),v(o,_.hide)&&i()}):i()}},le=function(e){null!==e&&"function"==typeof e&&setTimeout(function(){e()})};function de(e){var t=function e(){for(var t=arguments.length,n=new Array(t),o=0;o.swal2-modal{box-shadow:0 0 10px rgba(0,0,0,.4)}body.swal2-no-backdrop .swal2-shown.swal2-top{top:0;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}body.swal2-no-backdrop .swal2-shown.swal2-top-left,body.swal2-no-backdrop .swal2-shown.swal2-top-start{top:0;left:0}body.swal2-no-backdrop .swal2-shown.swal2-top-end,body.swal2-no-backdrop .swal2-shown.swal2-top-right{top:0;right:0}body.swal2-no-backdrop .swal2-shown.swal2-center{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}body.swal2-no-backdrop .swal2-shown.swal2-center-left,body.swal2-no-backdrop .swal2-shown.swal2-center-start{top:50%;left:0;-webkit-transform:translateY(-50%);transform:translateY(-50%)}body.swal2-no-backdrop .swal2-shown.swal2-center-end,body.swal2-no-backdrop .swal2-shown.swal2-center-right{top:50%;right:0;-webkit-transform:translateY(-50%);transform:translateY(-50%)}body.swal2-no-backdrop .swal2-shown.swal2-bottom{bottom:0;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}body.swal2-no-backdrop .swal2-shown.swal2-bottom-left,body.swal2-no-backdrop .swal2-shown.swal2-bottom-start{bottom:0;left:0}body.swal2-no-backdrop .swal2-shown.swal2-bottom-end,body.swal2-no-backdrop .swal2-shown.swal2-bottom-right{right:0;bottom:0}.swal2-container{display:flex;position:fixed;top:0;right:0;bottom:0;left:0;flex-direction:row;align-items:center;justify-content:center;padding:10px;background-color:transparent;z-index:1060;overflow-x:hidden;-webkit-overflow-scrolling:touch}.swal2-container.swal2-top{align-items:flex-start}.swal2-container.swal2-top-left,.swal2-container.swal2-top-start{align-items:flex-start;justify-content:flex-start}.swal2-container.swal2-top-end,.swal2-container.swal2-top-right{align-items:flex-start;justify-content:flex-end}.swal2-container.swal2-center{align-items:center}.swal2-container.swal2-center-left,.swal2-container.swal2-center-start{align-items:center;justify-content:flex-start}.swal2-container.swal2-center-end,.swal2-container.swal2-center-right{align-items:center;justify-content:flex-end}.swal2-container.swal2-bottom{align-items:flex-end}.swal2-container.swal2-bottom-left,.swal2-container.swal2-bottom-start{align-items:flex-end;justify-content:flex-start}.swal2-container.swal2-bottom-end,.swal2-container.swal2-bottom-right{align-items:flex-end;justify-content:flex-end}.swal2-container.swal2-grow-fullscreen>.swal2-modal{display:flex!important;flex:1;align-self:stretch;justify-content:center}.swal2-container.swal2-grow-row>.swal2-modal{display:flex!important;flex:1;align-content:center;justify-content:center}.swal2-container.swal2-grow-column{flex:1;flex-direction:column}.swal2-container.swal2-grow-column.swal2-bottom,.swal2-container.swal2-grow-column.swal2-center,.swal2-container.swal2-grow-column.swal2-top{align-items:center}.swal2-container.swal2-grow-column.swal2-bottom-left,.swal2-container.swal2-grow-column.swal2-bottom-start,.swal2-container.swal2-grow-column.swal2-center-left,.swal2-container.swal2-grow-column.swal2-center-start,.swal2-container.swal2-grow-column.swal2-top-left,.swal2-container.swal2-grow-column.swal2-top-start{align-items:flex-start}.swal2-container.swal2-grow-column.swal2-bottom-end,.swal2-container.swal2-grow-column.swal2-bottom-right,.swal2-container.swal2-grow-column.swal2-center-end,.swal2-container.swal2-grow-column.swal2-center-right,.swal2-container.swal2-grow-column.swal2-top-end,.swal2-container.swal2-grow-column.swal2-top-right{align-items:flex-end}.swal2-container.swal2-grow-column>.swal2-modal{display:flex!important;flex:1;align-content:center;justify-content:center}.swal2-container:not(.swal2-top):not(.swal2-top-start):not(.swal2-top-end):not(.swal2-top-left):not(.swal2-top-right):not(.swal2-center-start):not(.swal2-center-end):not(.swal2-center-left):not(.swal2-center-right):not(.swal2-bottom):not(.swal2-bottom-start):not(.swal2-bottom-end):not(.swal2-bottom-left):not(.swal2-bottom-right):not(.swal2-grow-fullscreen)>.swal2-modal{margin:auto}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.swal2-container .swal2-modal{margin:0!important}}.swal2-container.swal2-fade{transition:background-color .1s}.swal2-container.swal2-shown{background-color:rgba(0,0,0,.4)}.swal2-popup{display:none;position:relative;flex-direction:column;justify-content:center;width:32em;max-width:100%;padding:1.25em;border-radius:.3125em;background:#fff;font-family:inherit;font-size:1rem;box-sizing:border-box}.swal2-popup:focus{outline:0}.swal2-popup.swal2-loading{overflow-y:hidden}.swal2-popup .swal2-header{display:flex;flex-direction:column;align-items:center}.swal2-popup .swal2-title{display:block;position:relative;max-width:100%;margin:0 0 .4em;padding:0;color:#595959;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word}.swal2-popup .swal2-actions{flex-wrap:wrap;align-items:center;justify-content:center;margin:1.25em auto 0;z-index:1}.swal2-popup .swal2-actions:not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}.swal2-popup .swal2-actions:not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0,0,0,.1),rgba(0,0,0,.1))}.swal2-popup .swal2-actions:not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.2))}.swal2-popup .swal2-actions.swal2-loading .swal2-styled.swal2-confirm{width:2.5em;height:2.5em;margin:.46875em;padding:0;border:.25em solid transparent;border-radius:100%;border-color:transparent;background-color:transparent!important;color:transparent;cursor:default;box-sizing:border-box;-webkit-animation:swal2-rotate-loading 1.5s linear 0s infinite normal;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.swal2-popup .swal2-actions.swal2-loading .swal2-styled.swal2-cancel{margin-right:30px;margin-left:30px}.swal2-popup .swal2-actions.swal2-loading :not(.swal2-styled).swal2-confirm::after{display:inline-block;width:15px;height:15px;margin-left:5px;border:3px solid #999;border-radius:50%;border-right-color:transparent;box-shadow:1px 1px 1px #fff;content:'';-webkit-animation:swal2-rotate-loading 1.5s linear 0s infinite normal;animation:swal2-rotate-loading 1.5s linear 0s infinite normal}.swal2-popup .swal2-styled{margin:.3125em;padding:.625em 2em;font-weight:500;box-shadow:none}.swal2-popup .swal2-styled:not([disabled]){cursor:pointer}.swal2-popup .swal2-styled.swal2-confirm{border:0;border-radius:.25em;background:initial;background-color:#3085d6;color:#fff;font-size:1.0625em}.swal2-popup .swal2-styled.swal2-cancel{border:0;border-radius:.25em;background:initial;background-color:#aaa;color:#fff;font-size:1.0625em}.swal2-popup .swal2-styled:focus{outline:0;box-shadow:0 0 0 2px #fff,0 0 0 4px rgba(50,100,150,.4)}.swal2-popup .swal2-styled::-moz-focus-inner{border:0}.swal2-popup .swal2-footer{justify-content:center;margin:1.25em 0 0;padding:1em 0 0;border-top:1px solid #eee;color:#545454;font-size:1em}.swal2-popup .swal2-image{max-width:100%;margin:1.25em auto}.swal2-popup .swal2-close{position:absolute;top:0;right:0;justify-content:center;width:1.2em;height:1.2em;padding:0;transition:color .1s ease-out;border:none;border-radius:0;background:0 0;color:#ccc;font-family:serif;font-size:2.5em;line-height:1.2;cursor:pointer;overflow:hidden}.swal2-popup .swal2-close:hover{-webkit-transform:none;transform:none;color:#f27474}.swal2-popup>.swal2-checkbox,.swal2-popup>.swal2-file,.swal2-popup>.swal2-input,.swal2-popup>.swal2-radio,.swal2-popup>.swal2-select,.swal2-popup>.swal2-textarea{display:none}.swal2-popup .swal2-content{justify-content:center;margin:0;padding:0;color:#545454;font-size:1.125em;font-weight:300;line-height:normal;z-index:1;word-wrap:break-word}.swal2-popup #swal2-content{text-align:center}.swal2-popup .swal2-checkbox,.swal2-popup .swal2-file,.swal2-popup .swal2-input,.swal2-popup .swal2-radio,.swal2-popup .swal2-select,.swal2-popup .swal2-textarea{margin:1em auto}.swal2-popup .swal2-file,.swal2-popup .swal2-input,.swal2-popup .swal2-textarea{width:100%;transition:border-color .3s,box-shadow .3s;border:1px solid #d9d9d9;border-radius:.1875em;font-size:1.125em;box-shadow:inset 0 1px 1px rgba(0,0,0,.06);box-sizing:border-box}.swal2-popup .swal2-file.swal2-inputerror,.swal2-popup .swal2-input.swal2-inputerror,.swal2-popup .swal2-textarea.swal2-inputerror{border-color:#f27474!important;box-shadow:0 0 2px #f27474!important}.swal2-popup .swal2-file:focus,.swal2-popup .swal2-input:focus,.swal2-popup .swal2-textarea:focus{border:1px solid #b4dbed;outline:0;box-shadow:0 0 3px #c4e6f5}.swal2-popup .swal2-file::-webkit-input-placeholder,.swal2-popup .swal2-input::-webkit-input-placeholder,.swal2-popup .swal2-textarea::-webkit-input-placeholder{color:#ccc}.swal2-popup .swal2-file:-ms-input-placeholder,.swal2-popup .swal2-input:-ms-input-placeholder,.swal2-popup .swal2-textarea:-ms-input-placeholder{color:#ccc}.swal2-popup .swal2-file::-ms-input-placeholder,.swal2-popup .swal2-input::-ms-input-placeholder,.swal2-popup .swal2-textarea::-ms-input-placeholder{color:#ccc}.swal2-popup .swal2-file::placeholder,.swal2-popup .swal2-input::placeholder,.swal2-popup .swal2-textarea::placeholder{color:#ccc}.swal2-popup .swal2-range input{width:80%}.swal2-popup .swal2-range output{width:20%;font-weight:600;text-align:center}.swal2-popup .swal2-range input,.swal2-popup .swal2-range output{height:2.625em;margin:1em auto;padding:0;font-size:1.125em;line-height:2.625em}.swal2-popup .swal2-input{height:2.625em;padding:0 .75em}.swal2-popup .swal2-input[type=number]{max-width:10em}.swal2-popup .swal2-file{font-size:1.125em}.swal2-popup .swal2-textarea{height:6.75em;padding:.75em}.swal2-popup .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;color:#545454;font-size:1.125em}.swal2-popup .swal2-checkbox,.swal2-popup .swal2-radio{align-items:center;justify-content:center}.swal2-popup .swal2-checkbox label,.swal2-popup .swal2-radio label{margin:0 .6em;font-size:1.125em}.swal2-popup .swal2-checkbox input,.swal2-popup .swal2-radio input{margin:0 .4em}.swal2-popup .swal2-validation-message{display:none;align-items:center;justify-content:center;padding:.625em;background:#f0f0f0;color:#666;font-size:1em;font-weight:300;overflow:hidden}.swal2-popup .swal2-validation-message::before{display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center;content:'!';zoom:normal}@supports (-ms-accelerator:true){.swal2-range input{width:100%!important}.swal2-range output{display:none}}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.swal2-range input{width:100%!important}.swal2-range output{display:none}}@-moz-document url-prefix(){.swal2-close:focus{outline:2px solid rgba(50,100,150,.4)}}.swal2-icon{position:relative;justify-content:center;width:5em;height:5em;margin:1.25em auto 1.875em;border:.25em solid transparent;border-radius:50%;line-height:5em;cursor:default;box-sizing:content-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;zoom:normal}.swal2-icon-text{font-size:3.75em}.swal2-icon.swal2-error{border-color:#f27474}.swal2-icon.swal2-error .swal2-x-mark{position:relative;flex-grow:1}.swal2-icon.swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.swal2-icon.swal2-warning{border-color:#facea8;color:#f8bb86}.swal2-icon.swal2-info{border-color:#9de0f6;color:#3fc3ee}.swal2-icon.swal2-question{border-color:#c9dae1;color:#87adbd}.swal2-icon.swal2-success{border-color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;-webkit-transform:rotate(45deg);transform:rotate(45deg);border-radius:50%}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=left]{top:-.4375em;left:-2.0635em;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:3.75em 3.75em;transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=right]{top:-.6875em;left:1.875em;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:0 3.75em;transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}.swal2-icon.swal2-success .swal2-success-ring{position:absolute;top:-.25em;left:-.25em;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%;z-index:2;box-sizing:content-box}.swal2-icon.swal2-success .swal2-success-fix{position:absolute;top:.5em;left:1.625em;width:.4375em;height:5.625em;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);z-index:1}.swal2-icon.swal2-success [class^=swal2-success-line]{display:block;position:absolute;height:.3125em;border-radius:.125em;background-color:#a5dc86;z-index:2}.swal2-icon.swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.875em;width:1.5625em;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.swal2-icon.swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.swal2-progresssteps{align-items:center;margin:0 0 1.25em;padding:0;font-weight:600}.swal2-progresssteps li{display:inline-block;position:relative}.swal2-progresssteps .swal2-progresscircle{width:2em;height:2em;border-radius:2em;background:#3085d6;color:#fff;line-height:2em;text-align:center;z-index:20}.swal2-progresssteps .swal2-progresscircle:first-child{margin-left:0}.swal2-progresssteps .swal2-progresscircle:last-child{margin-right:0}.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep{background:#3085d6}.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep~.swal2-progresscircle{background:#add8e6}.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep~.swal2-progressline{background:#add8e6}.swal2-progresssteps .swal2-progressline{width:2.5em;height:.4em;margin:0 -1px;background:#3085d6;z-index:10}[class^=swal2]{-webkit-tap-highlight-color:transparent}.swal2-show{-webkit-animation:swal2-show .3s;animation:swal2-show .3s}.swal2-show.swal2-noanimation{-webkit-animation:none;animation:none}.swal2-hide{-webkit-animation:swal2-hide .15s forwards;animation:swal2-hide .15s forwards}.swal2-hide.swal2-noanimation{-webkit-animation:none;animation:none}[dir=rtl] .swal2-close{right:auto;left:0}.swal2-animate-success-icon .swal2-success-line-tip{-webkit-animation:swal2-animate-success-line-tip .75s;animation:swal2-animate-success-line-tip .75s}.swal2-animate-success-icon .swal2-success-line-long{-webkit-animation:swal2-animate-success-line-long .75s;animation:swal2-animate-success-line-long .75s}.swal2-animate-success-icon .swal2-success-circular-line-right{-webkit-animation:swal2-rotate-success-circular-line 4.25s ease-in;animation:swal2-rotate-success-circular-line 4.25s ease-in}.swal2-animate-error-icon{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-animate-error-icon .swal2-x-mark{-webkit-animation:swal2-animate-error-x-mark .5s;animation:swal2-animate-error-x-mark .5s}@-webkit-keyframes swal2-rotate-loading{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes swal2-rotate-loading{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@media print{body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow-y:scroll!important}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container{position:initial!important}}"); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/assets/lib/ueditor/audio-clip.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/audio-clip.png new file mode 100644 index 000000000..b466010c9 Binary files /dev/null and b/net452/SiteServer.Web/Home/assets/lib/ueditor/audio-clip.png differ diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/config.json b/net452/SiteServer.Web/Home/assets/lib/ueditor/config.json similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/config.json rename to net452/SiteServer.Web/Home/assets/lib/ueditor/config.json diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/anchor/anchor.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/anchor/anchor.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/anchor/anchor.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/anchor/anchor.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/attachment.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/attachment.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/attachment.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/attachment.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/attachment.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/attachment.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/attachment.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/attachment.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/attachment.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/attachment.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/attachment.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/attachment.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_chm.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_chm.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_chm.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_chm.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_default.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_default.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_default.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_default.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_doc.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_doc.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_doc.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_doc.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_exe.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_exe.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_exe.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_exe.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_jpg.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_jpg.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_jpg.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_jpg.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_mp3.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_mp3.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_mp3.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_mp3.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_mv.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_mv.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_mv.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_mv.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_pdf.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_pdf.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_pdf.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_pdf.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_ppt.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_ppt.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_ppt.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_ppt.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_psd.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_psd.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_psd.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_psd.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_rar.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_rar.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_rar.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_rar.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_txt.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_txt.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_txt.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_txt.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_xls.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_xls.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/fileTypeImages/icon_xls.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/fileTypeImages/icon_xls.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/alignicon.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/alignicon.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/alignicon.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/alignicon.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/alignicon.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/alignicon.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/alignicon.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/alignicon.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/bg.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/bg.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/bg.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/bg.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/file-icons.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/file-icons.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/file-icons.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/file-icons.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/file-icons.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/file-icons.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/file-icons.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/file-icons.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/icons.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/icons.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/icons.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/icons.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/icons.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/icons.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/icons.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/icons.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/image.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/image.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/image.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/image.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/progress.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/progress.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/progress.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/progress.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/success.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/success.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/success.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/success.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/success.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/success.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/attachment/images/success.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/attachment/images/success.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/background/background.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/background/background.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/background/background.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/background/background.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/background/background.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/background/background.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/background/background.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/background/background.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/background/background.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/background/background.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/background/background.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/background/background.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/background/images/bg.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/background/images/bg.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/background/images/bg.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/background/images/bg.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/background/images/success.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/background/images/success.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/background/images/success.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/background/images/success.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/chart.config.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/chart.config.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/chart.config.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/chart.config.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/charts.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/charts.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/charts.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/charts.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/charts.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/charts.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/charts.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/charts.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/charts.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/charts.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/charts.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/charts.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/images/charts0.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/images/charts0.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/images/charts0.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/images/charts0.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/images/charts1.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/images/charts1.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/images/charts1.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/images/charts1.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/images/charts2.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/images/charts2.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/images/charts2.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/images/charts2.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/images/charts3.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/images/charts3.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/images/charts3.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/images/charts3.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/images/charts4.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/images/charts4.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/images/charts4.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/images/charts4.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/images/charts5.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/images/charts5.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/charts/images/charts5.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/charts/images/charts5.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/emotion.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/emotion.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/emotion.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/emotion.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/emotion.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/emotion.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/emotion.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/emotion.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/emotion.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/emotion.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/emotion.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/emotion.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/0.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/0.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/0.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/0.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/bface.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/bface.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/bface.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/bface.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/cface.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/cface.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/cface.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/cface.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/fface.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/fface.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/fface.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/fface.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/jxface2.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/jxface2.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/jxface2.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/jxface2.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/neweditor-tab-bg.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/neweditor-tab-bg.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/neweditor-tab-bg.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/neweditor-tab-bg.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/tface.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/tface.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/tface.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/tface.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/wface.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/wface.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/wface.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/wface.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/yface.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/yface.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/emotion/images/yface.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/emotion/images/yface.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/gmap/gmap.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/gmap/gmap.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/gmap/gmap.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/gmap/gmap.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/help/help.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/help/help.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/help/help.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/help/help.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/help/help.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/help/help.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/help/help.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/help/help.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/help/help.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/help/help.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/help/help.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/help/help.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/image.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/image.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/image.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/image.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/image.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/image.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/image.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/image.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/image.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/image.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/image.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/image.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/images/alignicon.jpg b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/images/alignicon.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/images/alignicon.jpg rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/images/alignicon.jpg diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/images/bg.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/images/bg.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/images/bg.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/images/bg.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/images/icons.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/images/icons.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/images/icons.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/images/icons.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/images/icons.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/images/icons.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/images/icons.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/images/icons.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/images/image.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/images/image.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/images/image.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/images/image.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/images/progress.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/images/progress.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/images/progress.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/images/progress.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/images/success.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/images/success.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/images/success.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/images/success.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/images/success.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/images/success.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/image/images/success.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/image/images/success.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/insertframe/insertframe.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/insertframe/insertframe.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/insertframe/insertframe.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/insertframe/insertframe.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/internal.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/internal.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/internal.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/internal.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/link/link.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/link/link.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/link/link.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/link/link.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/map/map.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/map/map.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/map/map.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/map/map.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/map/show.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/map/show.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/map/show.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/map/show.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/music/music.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/music/music.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/music/music.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/music/music.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/music/music.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/music/music.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/music/music.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/music/music.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/music/music.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/music/music.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/music/music.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/music/music.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/preview/preview.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/preview/preview.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/preview/preview.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/preview/preview.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/addimg.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/addimg.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/addimg.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/addimg.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/brush.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/brush.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/brush.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/brush.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/delimg.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/delimg.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/delimg.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/delimg.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/delimgH.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/delimgH.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/delimgH.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/delimgH.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/empty.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/empty.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/empty.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/empty.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/emptyH.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/emptyH.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/emptyH.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/emptyH.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/eraser.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/eraser.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/eraser.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/eraser.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/redo.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/redo.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/redo.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/redo.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/redoH.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/redoH.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/redoH.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/redoH.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/scale.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/scale.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/scale.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/scale.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/scaleH.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/scaleH.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/scaleH.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/scaleH.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/size.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/size.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/size.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/size.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/undo.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/undo.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/undo.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/undo.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/undoH.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/undoH.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/images/undoH.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/images/undoH.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/scrawl.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/scrawl.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/scrawl.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/scrawl.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/scrawl.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/scrawl.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/scrawl.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/scrawl.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/scrawl.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/scrawl.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/scrawl/scrawl.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/scrawl/scrawl.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/searchreplace/searchreplace.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/searchreplace/searchreplace.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/searchreplace/searchreplace.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/searchreplace/searchreplace.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/searchreplace/searchreplace.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/searchreplace/searchreplace.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/searchreplace/searchreplace.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/searchreplace/searchreplace.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/snapscreen/snapscreen.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/snapscreen/snapscreen.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/snapscreen/snapscreen.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/snapscreen/snapscreen.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/spechars/spechars.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/spechars/spechars.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/spechars/spechars.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/spechars/spechars.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/spechars/spechars.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/spechars/spechars.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/spechars/spechars.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/spechars/spechars.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/table/dragicon.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/table/dragicon.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/table/dragicon.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/table/dragicon.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/table/edittable.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/table/edittable.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/table/edittable.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/table/edittable.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/table/edittable.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/table/edittable.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/table/edittable.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/table/edittable.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/table/edittable.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/table/edittable.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/table/edittable.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/table/edittable.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/table/edittd.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/table/edittd.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/table/edittd.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/table/edittd.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/table/edittip.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/table/edittip.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/table/edittip.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/table/edittip.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/bg.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/bg.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/bg.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/bg.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/center_focus.jpg b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/center_focus.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/center_focus.jpg rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/center_focus.jpg diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/file-icons.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/file-icons.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/file-icons.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/file-icons.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/file-icons.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/file-icons.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/file-icons.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/file-icons.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/icons.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/icons.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/icons.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/icons.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/icons.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/icons.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/icons.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/icons.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/image.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/image.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/image.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/image.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/left_focus.jpg b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/left_focus.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/left_focus.jpg rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/left_focus.jpg diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/none_focus.jpg b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/none_focus.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/none_focus.jpg rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/none_focus.jpg diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/progress.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/progress.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/progress.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/progress.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/right_focus.jpg b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/right_focus.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/right_focus.jpg rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/right_focus.jpg diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/success.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/success.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/success.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/success.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/success.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/success.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/images/success.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/images/success.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/video.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/video.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/video.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/video.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/video.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/video.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/video.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/video.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/video.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/video.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/video/video.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/video/video.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/wordimage/fClipboard_ueditor.swf b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/wordimage/fClipboard_ueditor.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/wordimage/fClipboard_ueditor.swf rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/wordimage/fClipboard_ueditor.swf diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/wordimage/imageUploader.swf b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/wordimage/imageUploader.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/wordimage/imageUploader.swf rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/wordimage/imageUploader.swf diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/wordimage/tangram.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/wordimage/tangram.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/wordimage/tangram.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/wordimage/tangram.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/wordimage/wordimage.html b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/wordimage/wordimage.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/wordimage/wordimage.html rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/wordimage/wordimage.html diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/dialogs/wordimage/wordimage.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/wordimage/wordimage.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/dialogs/wordimage/wordimage.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/dialogs/wordimage/wordimage.js diff --git a/net452/SiteServer.Web/Home/assets/lib/ueditor/editor_config.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/editor_config.js new file mode 100644 index 000000000..e0d6590e4 --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/lib/ueditor/editor_config.js @@ -0,0 +1,198 @@ +! function () { + function e(e, l) { + return t(e || self.document.URL || self.location.href, l || s()) + } + + function s() { + var e = document.getElementsByTagName("script"); + return e[e.length - 1].src + } + + function t(e, s) { + var t = s; + return /^(\/|\\\\)/.test(s) ? t = /^.+?\w(\/|\\\\)/.exec(e)[0] + s.replace(/^(\/|\\\\)/, "") : /^[a-z]+:/i.test(s) || (e = e.split("#")[0].split("?")[0].replace(/[^\\\/]+$/, ""), t = e + "" + s), l(t) + } + + function l(e) { + var s = /^[a-z]+:\/\//.exec(e)[0], + t = null, + l = []; + for (e = e.replace(s, "").split("?")[0].split("#")[0], e = e.replace(/\\/g, "/").split(/\//), e[e.length - 1] = ""; e.length;) ".." === (t = e.shift()) ? l.pop() : "." !== t && l.push(t); + return s + l.join("/") + } + var a = window.UEDITOR_HOME_URL || e(); + window.UEDITOR_CONFIG = { + UEDITOR_HOME_URL: a, + serverUrl: window.UEDITOR_CONTROLLER_URL, + toolbars: [ + ["fullscreen", + "source", + "|", + "undo", + "redo", + "|", + "bold", + "italic", + "underline", + "fontborder", + "strikethrough", + "superscript", + "subscript", + "removeformat", + "formatmatch", + "autotypeset", + "blockquote", + "pasteplain", + "|", + "forecolor", + "backcolor", + "insertorderedlist", + "insertunorderedlist", + "selectall", + "cleardoc", + "|", + "rowspacingtop", + "rowspacingbottom", + "lineheight", + "|", + "customstyle", + "paragraph", + "fontfamily", + "fontsize", + "|", + "directionalityltr", + "directionalityrtl", + "indent", + "|", + "justifyleft", + "justifycenter", + "justifyright", + "justifyjustify", + "|", + "touppercase", + "tolowercase", + "|", + "link", + "unlink", + "anchor", + "|", + "imagenone", + "imageleft", + "imageright", + "imagecenter", + "|", + "emotion", + "scrawl", + "attachment", + "map", + "insertframe", + "insertcode", + "template", + "background", + "|", + "horizontal", + "date", + "time", + "spechars", + "wordimage", + "|", + "inserttable", + "deletetable", + "insertparagraphbeforetable", + "insertrow", + "deleterow", + "insertcol", + "deletecol", + "mergecells", + "mergeright", + "mergedown", + "splittocells", + "splittorows", + "splittocols", + "charts", + "|", + "print", + "preview", + "searchreplace", + "pagebreak" + ] + ], + initialFrameHeight: 320, + enableAutoSave: !1, + saveInterval: 9999999999999, + allHtmlEnabled: !1, + pageBreakTag: "[SITESERVER_PAGE]", + xssFilterRules: false, + inputXssFilter: false, + outputXssFilter: false, + whitList: { + a: ["target", "href", "title", "class", "style", "name"], + abbr: ["title", "class", "style"], + address: ["class", "style"], + area: ["shape", "coords", "href", "alt"], + article: [], + aside: [], + audio: ["autoplay", "controls", "loop", "preload", "src", "class", "style"], + b: ["class", "style"], + bdi: ["dir"], + bdo: ["dir"], + big: [], + blockquote: ["cite", "class", "style"], + br: [], + caption: ["class", "style"], + center: [], + cite: [], + code: ["class", "style"], + col: ["align", "valign", "span", "width", "class", "style"], + colgroup: ["align", "valign", "span", "width", "class", "style"], + dd: ["class", "style"], + del: ["datetime"], + details: ["open"], + div: ["class", "style"], + dl: ["class", "style"], + dt: ["class", "style"], + em: ["class", "style"], + font: ["color", "size", "face"], + footer: [], + h1: ["class", "style"], + h2: ["class", "style"], + h3: ["class", "style"], + h4: ["class", "style"], + h5: ["class", "style"], + h6: ["class", "style"], + header: [], + hr: [], + i: ["class", "style"], + img: ["src", "alt", "title", "width", "height", "id", "_src", "_url", "loadingclass", "class", "data-latex", "word_img", "style", "anchorname"], + ins: ["datetime"], + li: ["class", "style"], + mark: [], + nav: [], + ol: ["class", "style"], + p: ["class", "style"], + pre: ["class", "style"], + s: [], + section: [], + small: [], + span: ["class", "style"], + sub: ["class", "style"], + sup: ["class", "style"], + strong: ["class", "style"], + table: ["width", "border", "align", "valign", "class", "style"], + tbody: ["align", "valign", "class", "style"], + td: ["width", "rowspan", "colspan", "align", "valign", "class", "style"], + tfoot: ["align", "valign", "class", "style"], + th: ["width", "rowspan", "colspan", "align", "valign", "class", "style"], + thead: ["align", "valign", "class", "style"], + tr: ["rowspan", "align", "valign", "class", "style"], + tt: [], + u: [], + ul: ["class", "style"], + video: ["autoplay", "controls", "loop", "preload", "src", "height", "width", "class", "style"], + source: ["src", "type"], + embed: ["type", "class", "pluginspage", "src", "width", "height", "align", "style", "wmode", "play", "loop", "menu", "allowscriptaccess", "allowfullscreen"] + } + }, window.UE = { + getUEBasePath: e + } +}(); \ No newline at end of file diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/en.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/en.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/en.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/en.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/addimage.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/addimage.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/addimage.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/addimage.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/alldeletebtnhoverskin.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/alldeletebtnhoverskin.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/alldeletebtnhoverskin.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/alldeletebtnhoverskin.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/alldeletebtnupskin.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/alldeletebtnupskin.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/alldeletebtnupskin.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/alldeletebtnupskin.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/background.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/background.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/background.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/background.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/button.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/button.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/button.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/button.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/copy.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/copy.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/copy.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/copy.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/deletedisable.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/deletedisable.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/deletedisable.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/deletedisable.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/deleteenable.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/deleteenable.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/deleteenable.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/deleteenable.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/listbackground.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/listbackground.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/listbackground.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/listbackground.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/localimage.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/localimage.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/localimage.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/localimage.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/music.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/music.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/music.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/music.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/rotateleftdisable.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/rotateleftdisable.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/rotateleftdisable.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/rotateleftdisable.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/rotateleftenable.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/rotateleftenable.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/rotateleftenable.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/rotateleftenable.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/rotaterightdisable.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/rotaterightdisable.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/rotaterightdisable.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/rotaterightdisable.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/rotaterightenable.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/rotaterightenable.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/rotaterightenable.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/rotaterightenable.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/upload.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/upload.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/en/images/upload.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/en/images/upload.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/zh-cn/images/copy.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/zh-cn/images/copy.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/zh-cn/images/copy.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/zh-cn/images/copy.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/zh-cn/images/localimage.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/zh-cn/images/localimage.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/zh-cn/images/localimage.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/zh-cn/images/localimage.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/zh-cn/images/music.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/zh-cn/images/music.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/zh-cn/images/music.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/zh-cn/images/music.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/zh-cn/images/upload.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/zh-cn/images/upload.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/zh-cn/images/upload.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/zh-cn/images/upload.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/lang/zh-cn/zh-cn.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/lang/zh-cn/zh-cn.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/lang/zh-cn/zh-cn.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/lang/zh-cn/zh-cn.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/css/ueditor.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/css/ueditor.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/css/ueditor.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/css/ueditor.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/css/ueditor.min.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/css/ueditor.min.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/css/ueditor.min.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/css/ueditor.min.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/dialogbase.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/dialogbase.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/dialogbase.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/dialogbase.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/anchor.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/anchor.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/anchor.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/anchor.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/arrow.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/arrow.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/arrow.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/arrow.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/arrow_down.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/arrow_down.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/arrow_down.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/arrow_down.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/arrow_up.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/arrow_up.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/arrow_up.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/arrow_up.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/button-bg.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/button-bg.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/button-bg.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/button-bg.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/cancelbutton.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/cancelbutton.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/cancelbutton.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/cancelbutton.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/charts.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/charts.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/charts.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/charts.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/cursor_h.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/cursor_h.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/cursor_h.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/cursor_h.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/cursor_h.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/cursor_h.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/cursor_h.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/cursor_h.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/cursor_v.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/cursor_v.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/cursor_v.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/cursor_v.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/cursor_v.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/cursor_v.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/cursor_v.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/cursor_v.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/dialog-title-bg.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/dialog-title-bg.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/dialog-title-bg.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/dialog-title-bg.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/filescan.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/filescan.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/filescan.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/filescan.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/highlighted.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/highlighted.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/highlighted.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/highlighted.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/icons-all.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/icons-all.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/icons-all.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/icons-all.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/icons.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/icons.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/icons.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/icons.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/icons.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/icons.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/icons.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/icons.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/loaderror.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/loaderror.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/loaderror.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/loaderror.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/loading.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/loading.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/loading.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/loading.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/lock.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/lock.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/lock.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/lock.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/neweditor-tab-bg.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/neweditor-tab-bg.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/neweditor-tab-bg.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/neweditor-tab-bg.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/pagebreak.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/pagebreak.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/pagebreak.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/pagebreak.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/scale.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/scale.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/scale.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/scale.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/sortable.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/sortable.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/sortable.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/sortable.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/spacer.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/spacer.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/spacer.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/spacer.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/sparator_v.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/sparator_v.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/sparator_v.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/sparator_v.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/table-cell-align.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/table-cell-align.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/table-cell-align.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/table-cell-align.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/tangram-colorpicker.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/tangram-colorpicker.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/tangram-colorpicker.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/tangram-colorpicker.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/toolbar_bg.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/toolbar_bg.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/toolbar_bg.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/toolbar_bg.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/unhighlighted.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/unhighlighted.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/unhighlighted.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/unhighlighted.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/upload.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/upload.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/upload.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/upload.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/videologo.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/videologo.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/videologo.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/videologo.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/word.gif b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/word.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/word.gif rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/word.gif diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/wordpaste.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/wordpaste.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/default/images/wordpaste.png rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/default/images/wordpaste.png diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/themes/iframe.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/themes/iframe.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/themes/iframe.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/themes/iframe.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/SyntaxHighlighter/shCore.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/SyntaxHighlighter/shCore.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/SyntaxHighlighter/shCore.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/SyntaxHighlighter/shCore.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/SyntaxHighlighter/shCoreDefault.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/SyntaxHighlighter/shCoreDefault.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/SyntaxHighlighter/shCoreDefault.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/SyntaxHighlighter/shCoreDefault.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/codemirror/codemirror.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/codemirror/codemirror.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/codemirror/codemirror.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/codemirror/codemirror.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/codemirror/codemirror.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/codemirror/codemirror.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/codemirror/codemirror.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/codemirror/codemirror.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/adapters/mootools-adapter.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/adapters/mootools-adapter.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/adapters/mootools-adapter.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/adapters/mootools-adapter.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/adapters/mootools-adapter.src.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/adapters/mootools-adapter.src.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/adapters/mootools-adapter.src.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/adapters/mootools-adapter.src.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/adapters/prototype-adapter.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/adapters/prototype-adapter.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/adapters/prototype-adapter.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/adapters/prototype-adapter.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/adapters/prototype-adapter.src.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/adapters/prototype-adapter.src.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/adapters/prototype-adapter.src.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/adapters/prototype-adapter.src.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/adapters/standalone-framework.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/adapters/standalone-framework.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/adapters/standalone-framework.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/adapters/standalone-framework.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/adapters/standalone-framework.src.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/adapters/standalone-framework.src.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/adapters/standalone-framework.src.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/adapters/standalone-framework.src.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/highcharts-more.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/highcharts-more.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/highcharts-more.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/highcharts-more.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/highcharts-more.src.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/highcharts-more.src.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/highcharts-more.src.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/highcharts-more.src.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/highcharts.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/highcharts.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/highcharts.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/highcharts.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/highcharts.src.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/highcharts.src.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/highcharts.src.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/highcharts.src.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/annotations.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/annotations.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/annotations.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/annotations.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/annotations.src.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/annotations.src.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/annotations.src.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/annotations.src.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/canvas-tools.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/canvas-tools.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/canvas-tools.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/canvas-tools.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/canvas-tools.src.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/canvas-tools.src.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/canvas-tools.src.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/canvas-tools.src.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/data.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/data.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/data.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/data.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/data.src.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/data.src.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/data.src.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/data.src.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/drilldown.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/drilldown.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/drilldown.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/drilldown.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/drilldown.src.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/drilldown.src.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/drilldown.src.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/drilldown.src.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/exporting.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/exporting.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/exporting.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/exporting.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/exporting.src.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/exporting.src.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/exporting.src.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/exporting.src.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/funnel.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/funnel.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/funnel.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/funnel.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/funnel.src.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/funnel.src.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/funnel.src.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/funnel.src.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/heatmap.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/heatmap.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/heatmap.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/heatmap.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/heatmap.src.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/heatmap.src.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/heatmap.src.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/heatmap.src.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/map.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/map.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/map.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/map.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/map.src.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/map.src.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/map.src.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/map.src.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/no-data-to-display.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/no-data-to-display.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/no-data-to-display.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/no-data-to-display.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/no-data-to-display.src.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/no-data-to-display.src.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/modules/no-data-to-display.src.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/modules/no-data-to-display.src.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/themes/dark-blue.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/themes/dark-blue.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/themes/dark-blue.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/themes/dark-blue.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/themes/dark-green.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/themes/dark-green.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/themes/dark-green.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/themes/dark-green.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/themes/gray.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/themes/gray.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/themes/gray.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/themes/gray.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/themes/grid.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/themes/grid.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/themes/grid.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/themes/grid.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/themes/skies.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/themes/skies.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/highcharts/themes/skies.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/highcharts/themes/skies.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/jquery-1.10.2.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/jquery-1.10.2.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/jquery-1.10.2.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/jquery-1.10.2.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/jquery-1.10.2.min.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/jquery-1.10.2.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/jquery-1.10.2.min.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/jquery-1.10.2.min.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/jquery-1.10.2.min.map b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/jquery-1.10.2.min.map similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/jquery-1.10.2.min.map rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/jquery-1.10.2.min.map diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/font/vjs.eot b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/font/vjs.eot similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/font/vjs.eot rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/font/vjs.eot diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/font/vjs.svg b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/font/vjs.svg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/font/vjs.svg rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/font/vjs.svg diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/font/vjs.ttf b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/font/vjs.ttf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/font/vjs.ttf rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/font/vjs.ttf diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/font/vjs.woff b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/font/vjs.woff similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/font/vjs.woff rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/font/vjs.woff diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/video-js.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/video-js.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/video-js.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/video-js.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/video-js.min.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/video-js.min.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/video-js.min.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/video-js.min.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/video-js.swf b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/video-js.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/video-js.swf rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/video-js.swf diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/video.dev.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/video.dev.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/video.dev.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/video.dev.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/video.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/video.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/video-js/video.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/video-js/video.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/Uploader.swf b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/Uploader.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/Uploader.swf rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/Uploader.swf diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.css b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.css rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.css diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.custom.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.custom.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.custom.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.custom.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.custom.min.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.custom.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.custom.min.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.custom.min.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.flashonly.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.flashonly.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.flashonly.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.flashonly.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.flashonly.min.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.flashonly.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.flashonly.min.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.flashonly.min.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.html5only.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.html5only.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.html5only.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.html5only.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.html5only.min.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.html5only.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.html5only.min.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.html5only.min.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.min.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.min.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.min.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.withoutimage.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.withoutimage.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.withoutimage.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.withoutimage.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.withoutimage.min.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.withoutimage.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/webuploader/webuploader.withoutimage.min.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/webuploader/webuploader.withoutimage.min.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/xss.min.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/xss.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/xss.min.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/xss.min.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/zeroclipboard/ZeroClipboard.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/zeroclipboard/ZeroClipboard.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/zeroclipboard/ZeroClipboard.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/zeroclipboard/ZeroClipboard.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/zeroclipboard/ZeroClipboard.min.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/zeroclipboard/ZeroClipboard.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/zeroclipboard/ZeroClipboard.min.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/zeroclipboard/ZeroClipboard.min.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/third-party/zeroclipboard/ZeroClipboard.swf b/net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/zeroclipboard/ZeroClipboard.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/third-party/zeroclipboard/ZeroClipboard.swf rename to net452/SiteServer.Web/Home/assets/lib/ueditor/third-party/zeroclipboard/ZeroClipboard.swf diff --git a/net452/SiteServer.Web/Home/assets/lib/ueditor/ueditor.all.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/ueditor.all.js new file mode 100644 index 000000000..6e1b096a5 --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/lib/ueditor/ueditor.all.js @@ -0,0 +1,29537 @@ +/*! + * UEditor + * version: ueditor + * build: Wed Aug 10 2016 11:05:20 GMT+0800 (CST) + */ + +(function(){ + +// editor.js +UEDITOR_CONFIG = window.UEDITOR_CONFIG || {}; + +var baidu = window.baidu || {}; + +window.baidu = baidu; + +window.UE = baidu.editor = window.UE || {}; + +UE.plugins = {}; + +UE.commands = {}; + +UE.instants = {}; + +UE.I18N = {}; + +UE._customizeUI = {}; + +UE.version = "1.4.3"; + +var dom = UE.dom = {}; + +// core/browser.js +/** + * 浏览器判断模块 + * @file + * @module UE.browser + * @since 1.2.6.1 + */ + +/** + * 提供浏览器检测的模块 + * @unfile + * @module UE.browser + */ +var browser = UE.browser = function(){ + var agent = navigator.userAgent.toLowerCase(), + opera = window.opera, + browser = { + /** + * @property {boolean} ie 检测当前浏览器是否为IE + * @example + * ```javascript + * if ( UE.browser.ie ) { + * console.log( '当前浏览器是IE' ); + * } + * ``` + */ + ie : /(msie\s|trident.*rv:)([\w.]+)/.test(agent), + + /** + * @property {boolean} opera 检测当前浏览器是否为Opera + * @example + * ```javascript + * if ( UE.browser.opera ) { + * console.log( '当前浏览器是Opera' ); + * } + * ``` + */ + opera : ( !!opera && opera.version ), + + /** + * @property {boolean} webkit 检测当前浏览器是否是webkit内核的浏览器 + * @example + * ```javascript + * if ( UE.browser.webkit ) { + * console.log( '当前浏览器是webkit内核浏览器' ); + * } + * ``` + */ + webkit : ( agent.indexOf( ' applewebkit/' ) > -1 ), + + /** + * @property {boolean} mac 检测当前浏览器是否是运行在mac平台下 + * @example + * ```javascript + * if ( UE.browser.mac ) { + * console.log( '当前浏览器运行在mac平台下' ); + * } + * ``` + */ + mac : ( agent.indexOf( 'macintosh' ) > -1 ), + + /** + * @property {boolean} quirks 检测当前浏览器是否处于“怪异模式”下 + * @example + * ```javascript + * if ( UE.browser.quirks ) { + * console.log( '当前浏览器运行处于“怪异模式”' ); + * } + * ``` + */ + quirks : ( document.compatMode == 'BackCompat' ) + }; + + /** + * @property {boolean} gecko 检测当前浏览器内核是否是gecko内核 + * @example + * ```javascript + * if ( UE.browser.gecko ) { + * console.log( '当前浏览器内核是gecko内核' ); + * } + * ``` + */ + browser.gecko =( navigator.product == 'Gecko' && !browser.webkit && !browser.opera && !browser.ie); + + var version = 0; + + // Internet Explorer 6.0+ + if ( browser.ie ){ + + var v1 = agent.match(/(?:msie\s([\w.]+))/); + var v2 = agent.match(/(?:trident.*rv:([\w.]+))/); + if(v1 && v2 && v1[1] && v2[1]){ + version = Math.max(v1[1]*1,v2[1]*1); + }else if(v1 && v1[1]){ + version = v1[1]*1; + }else if(v2 && v2[1]){ + version = v2[1]*1; + }else{ + version = 0; + } + + browser.ie11Compat = document.documentMode == 11; + /** + * @property { boolean } ie9Compat 检测浏览器模式是否为 IE9 兼容模式 + * @warning 如果浏览器不是IE, 则该值为undefined + * @example + * ```javascript + * if ( UE.browser.ie9Compat ) { + * console.log( '当前浏览器运行在IE9兼容模式下' ); + * } + * ``` + */ + browser.ie9Compat = document.documentMode == 9; + + /** + * @property { boolean } ie8 检测浏览器是否是IE8浏览器 + * @warning 如果浏览器不是IE, 则该值为undefined + * @example + * ```javascript + * if ( UE.browser.ie8 ) { + * console.log( '当前浏览器是IE8浏览器' ); + * } + * ``` + */ + browser.ie8 = !!document.documentMode; + + /** + * @property { boolean } ie8Compat 检测浏览器模式是否为 IE8 兼容模式 + * @warning 如果浏览器不是IE, 则该值为undefined + * @example + * ```javascript + * if ( UE.browser.ie8Compat ) { + * console.log( '当前浏览器运行在IE8兼容模式下' ); + * } + * ``` + */ + browser.ie8Compat = document.documentMode == 8; + + /** + * @property { boolean } ie7Compat 检测浏览器模式是否为 IE7 兼容模式 + * @warning 如果浏览器不是IE, 则该值为undefined + * @example + * ```javascript + * if ( UE.browser.ie7Compat ) { + * console.log( '当前浏览器运行在IE7兼容模式下' ); + * } + * ``` + */ + browser.ie7Compat = ( ( version == 7 && !document.documentMode ) + || document.documentMode == 7 ); + + /** + * @property { boolean } ie6Compat 检测浏览器模式是否为 IE6 模式 或者怪异模式 + * @warning 如果浏览器不是IE, 则该值为undefined + * @example + * ```javascript + * if ( UE.browser.ie6Compat ) { + * console.log( '当前浏览器运行在IE6模式或者怪异模式下' ); + * } + * ``` + */ + browser.ie6Compat = ( version < 7 || browser.quirks ); + + browser.ie9above = version > 8; + + browser.ie9below = version < 9; + + browser.ie11above = version > 10; + + browser.ie11below = version < 11; + + } + + // Gecko. + if ( browser.gecko ){ + var geckoRelease = agent.match( /rv:([\d\.]+)/ ); + if ( geckoRelease ) + { + geckoRelease = geckoRelease[1].split( '.' ); + version = geckoRelease[0] * 10000 + ( geckoRelease[1] || 0 ) * 100 + ( geckoRelease[2] || 0 ) * 1; + } + } + + /** + * @property { Number } chrome 检测当前浏览器是否为Chrome, 如果是,则返回Chrome的大版本号 + * @warning 如果浏览器不是chrome, 则该值为undefined + * @example + * ```javascript + * if ( UE.browser.chrome ) { + * console.log( '当前浏览器是Chrome' ); + * } + * ``` + */ + if (/chrome\/(\d+\.\d)/i.test(agent)) { + browser.chrome = + RegExp['\x241']; + } + + /** + * @property { Number } safari 检测当前浏览器是否为Safari, 如果是,则返回Safari的大版本号 + * @warning 如果浏览器不是safari, 则该值为undefined + * @example + * ```javascript + * if ( UE.browser.safari ) { + * console.log( '当前浏览器是Safari' ); + * } + * ``` + */ + if(/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(agent) && !/chrome/i.test(agent)){ + browser.safari = + (RegExp['\x241'] || RegExp['\x242']); + } + + + // Opera 9.50+ + if ( browser.opera ) + version = parseFloat( opera.version() ); + + // WebKit 522+ (Safari 3+) + if ( browser.webkit ) + version = parseFloat( agent.match( / applewebkit\/(\d+)/ )[1] ); + + /** + * @property { Number } version 检测当前浏览器版本号 + * @remind + *
        + *
      • IE系列返回值为5,6,7,8,9,10等
      • + *
      • gecko系列会返回10900,158900等
      • + *
      • webkit系列会返回其build号 (如 522等)
      • + *
      + * @example + * ```javascript + * console.log( '当前浏览器版本号是: ' + UE.browser.version ); + * ``` + */ + browser.version = version; + + /** + * @property { boolean } isCompatible 检测当前浏览器是否能够与UEditor良好兼容 + * @example + * ```javascript + * if ( UE.browser.isCompatible ) { + * console.log( '浏览器与UEditor能够良好兼容' ); + * } + * ``` + */ + browser.isCompatible = + !browser.mobile && ( + ( browser.ie && version >= 6 ) || + ( browser.gecko && version >= 10801 ) || + ( browser.opera && version >= 9.5 ) || + ( browser.air && version >= 1 ) || + ( browser.webkit && version >= 522 ) || + false ); + return browser; +}(); +//快捷方式 +var ie = browser.ie, + webkit = browser.webkit, + gecko = browser.gecko, + opera = browser.opera; + +// core/utils.js +/** + * 工具函数包 + * @file + * @module UE.utils + * @since 1.2.6.1 + */ + +/** + * UEditor封装使用的静态工具函数 + * @module UE.utils + * @unfile + */ + +var utils = UE.utils = { + + /** + * 用给定的迭代器遍历对象 + * @method each + * @param { Object } obj 需要遍历的对象 + * @param { Function } iterator 迭代器, 该方法接受两个参数, 第一个参数是当前所处理的value, 第二个参数是当前遍历对象的key + * @example + * ```javascript + * var demoObj = { + * key1: 1, + * key2: 2 + * }; + * + * //output: key1: 1, key2: 2 + * UE.utils.each( demoObj, funciton ( value, key ) { + * + * console.log( key + ":" + value ); + * + * } ); + * ``` + */ + + /** + * 用给定的迭代器遍历数组或类数组对象 + * @method each + * @param { Array } array 需要遍历的数组或者类数组 + * @param { Function } iterator 迭代器, 该方法接受两个参数, 第一个参数是当前所处理的value, 第二个参数是当前遍历对象的key + * @example + * ```javascript + * var divs = document.getElmentByTagNames( "div" ); + * + * //output: 0: DIV, 1: DIV ... + * UE.utils.each( divs, funciton ( value, key ) { + * + * console.log( key + ":" + value.tagName ); + * + * } ); + * ``` + */ + each : function(obj, iterator, context) { + if (obj == null) return; + if (obj.length === +obj.length) { + for (var i = 0, l = obj.length; i < l; i++) { + if(iterator.call(context, obj[i], i, obj) === false) + return false; + } + } else { + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + if(iterator.call(context, obj[key], key, obj) === false) + return false; + } + } + } + }, + + /** + * 以给定对象作为原型创建一个新对象 + * @method makeInstance + * @param { Object } protoObject 该对象将作为新创建对象的原型 + * @return { Object } 新的对象, 该对象的原型是给定的protoObject对象 + * @example + * ```javascript + * + * var protoObject = { sayHello: function () { console.log('Hello UEditor!'); } }; + * + * var newObject = UE.utils.makeInstance( protoObject ); + * //output: Hello UEditor! + * newObject.sayHello(); + * ``` + */ + makeInstance:function (obj) { + var noop = new Function(); + noop.prototype = obj; + obj = new noop; + noop.prototype = null; + return obj; + }, + + /** + * 将source对象中的属性扩展到target对象上 + * @method extend + * @remind 该方法将强制把source对象上的属性复制到target对象上 + * @see UE.utils.extend(Object,Object,Boolean) + * @param { Object } target 目标对象, 新的属性将附加到该对象上 + * @param { Object } source 源对象, 该对象的属性会被附加到target对象上 + * @return { Object } 返回target对象 + * @example + * ```javascript + * + * var target = { name: 'target', sex: 1 }, + * source = { name: 'source', age: 17 }; + * + * UE.utils.extend( target, source ); + * + * //output: { name: 'source', sex: 1, age: 17 } + * console.log( target ); + * + * ``` + */ + + /** + * 将source对象中的属性扩展到target对象上, 根据指定的isKeepTarget值决定是否保留目标对象中与 + * 源对象属性名相同的属性值。 + * @method extend + * @param { Object } target 目标对象, 新的属性将附加到该对象上 + * @param { Object } source 源对象, 该对象的属性会被附加到target对象上 + * @param { Boolean } isKeepTarget 是否保留目标对象中与源对象中属性名相同的属性 + * @return { Object } 返回target对象 + * @example + * ```javascript + * + * var target = { name: 'target', sex: 1 }, + * source = { name: 'source', age: 17 }; + * + * UE.utils.extend( target, source, true ); + * + * //output: { name: 'target', sex: 1, age: 17 } + * console.log( target ); + * + * ``` + */ + extend:function (t, s, b) { + if (s) { + for (var k in s) { + if (!b || !t.hasOwnProperty(k)) { + t[k] = s[k]; + } + } + } + return t; + }, + + /** + * 将给定的多个对象的属性复制到目标对象target上 + * @method extend2 + * @remind 该方法将强制把源对象上的属性复制到target对象上 + * @remind 该方法支持两个及以上的参数, 从第二个参数开始, 其属性都会被复制到第一个参数上。 如果遇到同名的属性, + * 将会覆盖掉之前的值。 + * @param { Object } target 目标对象, 新的属性将附加到该对象上 + * @param { Object... } source 源对象, 支持多个对象, 该对象的属性会被附加到target对象上 + * @return { Object } 返回target对象 + * @example + * ```javascript + * + * var target = {}, + * source1 = { name: 'source', age: 17 }, + * source2 = { title: 'dev' }; + * + * UE.utils.extend2( target, source1, source2 ); + * + * //output: { name: 'source', age: 17, title: 'dev' } + * console.log( target ); + * + * ``` + */ + extend2:function (t) { + var a = arguments; + for (var i = 1; i < a.length; i++) { + var x = a[i]; + for (var k in x) { + if (!t.hasOwnProperty(k)) { + t[k] = x[k]; + } + } + } + return t; + }, + + /** + * 模拟继承机制, 使得subClass继承自superClass + * @method inherits + * @param { Object } subClass 子类对象 + * @param { Object } superClass 超类对象 + * @warning 该方法只能让subClass继承超类的原型, subClass对象自身的属性和方法不会被继承 + * @return { Object } 继承superClass后的子类对象 + * @example + * ```javascript + * function SuperClass(){ + * this.name = "小李"; + * } + * + * SuperClass.prototype = { + * hello:function(str){ + * console.log(this.name + str); + * } + * } + * + * function SubClass(){ + * this.name = "小张"; + * } + * + * UE.utils.inherits(SubClass,SuperClass); + * + * var sub = new SubClass(); + * //output: '小张早上好! + * sub.hello("早上好!"); + * ``` + */ + inherits:function (subClass, superClass) { + var oldP = subClass.prototype, + newP = utils.makeInstance(superClass.prototype); + utils.extend(newP, oldP, true); + subClass.prototype = newP; + return (newP.constructor = subClass); + }, + + /** + * 用指定的context对象作为函数fn的上下文 + * @method bind + * @param { Function } fn 需要绑定上下文的函数对象 + * @param { Object } content 函数fn新的上下文对象 + * @return { Function } 一个新的函数, 该函数作为原始函数fn的代理, 将完成fn的上下文调换工作。 + * @example + * ```javascript + * + * var name = 'window', + * newTest = null; + * + * function test () { + * console.log( this.name ); + * } + * + * newTest = UE.utils.bind( test, { name: 'object' } ); + * + * //output: object + * newTest(); + * + * //output: window + * test(); + * + * ``` + */ + bind:function (fn, context) { + return function () { + return fn.apply(context, arguments); + }; + }, + + /** + * 创建延迟指定时间后执行的函数fn + * @method defer + * @param { Function } fn 需要延迟执行的函数对象 + * @param { int } delay 延迟的时间, 单位是毫秒 + * @warning 该方法的时间控制是不精确的,仅仅只能保证函数的执行是在给定的时间之后, + * 而不能保证刚好到达延迟时间时执行。 + * @return { Function } 目标函数fn的代理函数, 只有执行该函数才能起到延时效果 + * @example + * ```javascript + * var start = 0; + * + * function test(){ + * console.log( new Date() - start ); + * } + * + * var testDefer = UE.utils.defer( test, 1000 ); + * // + * start = new Date(); + * //output: (大约在1000毫秒之后输出) 1000 + * testDefer(); + * ``` + */ + + /** + * 创建延迟指定时间后执行的函数fn, 如果在延迟时间内再次执行该方法, 将会根据指定的exclusion的值, + * 决定是否取消前一次函数的执行, 如果exclusion的值为true, 则取消执行,反之,将继续执行前一个方法。 + * @method defer + * @param { Function } fn 需要延迟执行的函数对象 + * @param { int } delay 延迟的时间, 单位是毫秒 + * @param { Boolean } exclusion 如果在延迟时间内再次执行该函数,该值将决定是否取消执行前一次函数的执行, + * 值为true表示取消执行, 反之则将在执行前一次函数之后才执行本次函数调用。 + * @warning 该方法的时间控制是不精确的,仅仅只能保证函数的执行是在给定的时间之后, + * 而不能保证刚好到达延迟时间时执行。 + * @return { Function } 目标函数fn的代理函数, 只有执行该函数才能起到延时效果 + * @example + * ```javascript + * + * function test(){ + * console.log(1); + * } + * + * var testDefer = UE.utils.defer( test, 1000, true ); + * + * //output: (两次调用仅有一次输出) 1 + * testDefer(); + * testDefer(); + * ``` + */ + defer:function (fn, delay, exclusion) { + var timerID; + return function () { + if (exclusion) { + clearTimeout(timerID); + } + timerID = setTimeout(fn, delay); + }; + }, + + /** + * 获取元素item在数组array中首次出现的位置, 如果未找到item, 则返回-1 + * @method indexOf + * @remind 该方法的匹配过程使用的是恒等“===” + * @param { Array } array 需要查找的数组对象 + * @param { * } item 需要在目标数组中查找的值 + * @return { int } 返回item在目标数组array中首次出现的位置, 如果在数组中未找到item, 则返回-1 + * @example + * ```javascript + * var item = 1, + * arr = [ 3, 4, 6, 8, 1, 1, 2 ]; + * + * //output: 4 + * console.log( UE.utils.indexOf( arr, item ) ); + * ``` + */ + + /** + * 获取元素item数组array中首次出现的位置, 如果未找到item, 则返回-1。通过start的值可以指定搜索的起始位置。 + * @method indexOf + * @remind 该方法的匹配过程使用的是恒等“===” + * @param { Array } array 需要查找的数组对象 + * @param { * } item 需要在目标数组中查找的值 + * @param { int } start 搜索的起始位置 + * @return { int } 返回item在目标数组array中的start位置之后首次出现的位置, 如果在数组中未找到item, 则返回-1 + * @example + * ```javascript + * var item = 1, + * arr = [ 3, 4, 6, 8, 1, 2, 8, 3, 2, 1, 1, 4 ]; + * + * //output: 9 + * console.log( UE.utils.indexOf( arr, item, 5 ) ); + * ``` + */ + indexOf:function (array, item, start) { + var index = -1; + start = this.isNumber(start) ? start : 0; + this.each(array, function (v, i) { + if (i >= start && v === item) { + index = i; + return false; + } + }); + return index; + }, + + /** + * 移除数组array中所有的元素item + * @method removeItem + * @param { Array } array 要移除元素的目标数组 + * @param { * } item 将要被移除的元素 + * @remind 该方法的匹配过程使用的是恒等“===” + * @example + * ```javascript + * var arr = [ 4, 5, 7, 1, 3, 4, 6 ]; + * + * UE.utils.removeItem( arr, 4 ); + * //output: [ 5, 7, 1, 3, 6 ] + * console.log( arr ); + * + * ``` + */ + removeItem:function (array, item) { + for (var i = 0, l = array.length; i < l; i++) { + if (array[i] === item) { + array.splice(i, 1); + i--; + } + } + }, + + /** + * 删除字符串str的首尾空格 + * @method trim + * @param { String } str 需要删除首尾空格的字符串 + * @return { String } 删除了首尾的空格后的字符串 + * @example + * ```javascript + * + * var str = " UEdtior "; + * + * //output: 9 + * console.log( str.length ); + * + * //output: 7 + * console.log( UE.utils.trim( " UEdtior " ).length ); + * + * //output: 9 + * console.log( str.length ); + * + * ``` + */ + trim:function (str) { + return str.replace(/(^[ \t\n\r]+)|([ \t\n\r]+$)/g, ''); + }, + + /** + * 将字符串str以','分隔成数组后,将该数组转换成哈希对象, 其生成的hash对象的key为数组中的元素, value为1 + * @method listToMap + * @warning 该方法在生成的hash对象中,会为每一个key同时生成一个另一个全大写的key。 + * @param { String } str 该字符串将被以','分割为数组, 然后进行转化 + * @return { Object } 转化之后的hash对象 + * @example + * ```javascript + * + * //output: Object {UEdtior: 1, UEDTIOR: 1, Hello: 1, HELLO: 1} + * console.log( UE.utils.listToMap( 'UEdtior,Hello' ) ); + * + * ``` + */ + + /** + * 将字符串数组转换成哈希对象, 其生成的hash对象的key为数组中的元素, value为1 + * @method listToMap + * @warning 该方法在生成的hash对象中,会为每一个key同时生成一个另一个全大写的key。 + * @param { Array } arr 字符串数组 + * @return { Object } 转化之后的hash对象 + * @example + * ```javascript + * + * //output: Object {UEdtior: 1, UEDTIOR: 1, Hello: 1, HELLO: 1} + * console.log( UE.utils.listToMap( [ 'UEdtior', 'Hello' ] ) ); + * + * ``` + */ + listToMap:function (list) { + if (!list)return {}; + list = utils.isArray(list) ? list : list.split(','); + for (var i = 0, ci, obj = {}; ci = list[i++];) { + obj[ci.toUpperCase()] = obj[ci] = 1; + } + return obj; + }, + + /** + * 将str中的html符号转义,将转义“',&,<,",>”五个字符 + * @method unhtml + * @param { String } str 需要转义的字符串 + * @return { String } 转义后的字符串 + * @example + * ```javascript + * var html = '&'; + * + * //output: <body>&</body> + * console.log( UE.utils.unhtml( html ) ); + * + * ``` + */ + unhtml:function (str, reg) { + return str ? str.replace(reg || /[&<">'](?:(amp|lt|quot|gt|#39|nbsp|#\d+);)?/g, function (a, b) { + if (b) { + return a; + } else { + return { + '<':'<', + '&':'&', + '"':'"', + '>':'>', + "'":''' + }[a] + } + + }) : ''; + }, + /** + * 将url中的html字符转义, 仅转义 ', ", <, > 四个字符 + * @param { String } str 需要转义的字符串 + * @param { RegExp } reg 自定义的正则 + * @return { String } 转义后的字符串 + */ + unhtmlForUrl:function (str, reg) { + return str ? str.replace(reg || /[<">']/g, function (a) { + return { + '<':'<', + '&':'&', + '"':'"', + '>':'>', + "'":''' + }[a] + + }) : ''; + }, + + /** + * 将str中的转义字符还原成html字符 + * @see UE.utils.unhtml(String); + * @method html + * @param { String } str 需要逆转义的字符串 + * @return { String } 逆转义后的字符串 + * @example + * ```javascript + * + * var str = '<body>&</body>'; + * + * //output: & + * console.log( UE.utils.html( str ) ); + * + * ``` + */ + html:function (str) { + return str ? str.replace(/&((g|l|quo)t|amp|#39|nbsp);/g, function (m) { + return { + '<':'<', + '&':'&', + '"':'"', + '>':'>', + ''':"'", + ' ':' ' + }[m] + }) : ''; + }, + + /** + * 将css样式转换为驼峰的形式 + * @method cssStyleToDomStyle + * @param { String } cssName 需要转换的css样式名 + * @return { String } 转换成驼峰形式后的css样式名 + * @example + * ```javascript + * + * var str = 'border-top'; + * + * //output: borderTop + * console.log( UE.utils.cssStyleToDomStyle( str ) ); + * + * ``` + */ + cssStyleToDomStyle:function () { + var test = document.createElement('div').style, + cache = { + 'float':test.cssFloat != undefined ? 'cssFloat' : test.styleFloat != undefined ? 'styleFloat' : 'float' + }; + + return function (cssName) { + return cache[cssName] || (cache[cssName] = cssName.toLowerCase().replace(/-./g, function (match) { + return match.charAt(1).toUpperCase(); + })); + }; + }(), + + /** + * 动态加载文件到doc中 + * @method loadFile + * @param { DomDocument } document 需要加载资源文件的文档对象 + * @param { Object } options 加载资源文件的属性集合, 取值请参考代码示例 + * @example + * ```javascript + * + * UE.utils.loadFile( document, { + * src:"test.js", + * tag:"script", + * type:"text/javascript", + * defer:"defer" + * } ); + * + * ``` + */ + + /** + * 动态加载文件到doc中,加载成功后执行的回调函数fn + * @method loadFile + * @param { DomDocument } document 需要加载资源文件的文档对象 + * @param { Object } options 加载资源文件的属性集合, 该集合支持的值是script标签和style标签支持的所有属性。 + * @param { Function } fn 资源文件加载成功之后执行的回调 + * @warning 对于在同一个文档中多次加载同一URL的文件, 该方法会在第一次加载之后缓存该请求, + * 在此之后的所有同一URL的请求, 将会直接触发回调。 + * @example + * ```javascript + * + * UE.utils.loadFile( document, { + * src:"test.js", + * tag:"script", + * type:"text/javascript", + * defer:"defer" + * }, function () { + * console.log('加载成功'); + * } ); + * + * ``` + */ + loadFile:function () { + var tmpList = []; + + function getItem(doc, obj) { + try { + for (var i = 0, ci; ci = tmpList[i++];) { + if (ci.doc === doc && ci.url == (obj.src || obj.href)) { + return ci; + } + } + } catch (e) { + return null; + } + + } + + return function (doc, obj, fn) { + var item = getItem(doc, obj); + if (item) { + if (item.ready) { + fn && fn(); + } else { + item.funs.push(fn) + } + return; + } + tmpList.push({ + doc:doc, + url:obj.src || obj.href, + funs:[fn] + }); + if (!doc.body) { + var html = []; + for (var p in obj) { + if (p == 'tag')continue; + html.push(p + '="' + obj[p] + '"') + } + doc.write('<' + obj.tag + ' ' + html.join(' ') + ' >'); + return; + } + if (obj.id && doc.getElementById(obj.id)) { + return; + } + var element = doc.createElement(obj.tag); + delete obj.tag; + for (var p in obj) { + element.setAttribute(p, obj[p]); + } + element.onload = element.onreadystatechange = function () { + if (!this.readyState || /loaded|complete/.test(this.readyState)) { + item = getItem(doc, obj); + if (item.funs.length > 0) { + item.ready = 1; + for (var fi; fi = item.funs.pop();) { + fi(); + } + } + element.onload = element.onreadystatechange = null; + } + }; + element.onerror = function () { + throw Error('The load ' + (obj.href || obj.src) + ' fails,check the url settings of file ueditor.config.js ') + }; + doc.getElementsByTagName("head")[0].appendChild(element); + } + }(), + + /** + * 判断obj对象是否为空 + * @method isEmptyObject + * @param { * } obj 需要判断的对象 + * @remind 如果判断的对象是NULL, 将直接返回true, 如果是数组且为空, 返回true, 如果是字符串, 且字符串为空, + * 返回true, 如果是普通对象, 且该对象没有任何实例属性, 返回true + * @return { Boolean } 对象是否为空 + * @example + * ```javascript + * + * //output: true + * console.log( UE.utils.isEmptyObject( {} ) ); + * + * //output: true + * console.log( UE.utils.isEmptyObject( [] ) ); + * + * //output: true + * console.log( UE.utils.isEmptyObject( "" ) ); + * + * //output: false + * console.log( UE.utils.isEmptyObject( { key: 1 } ) ); + * + * //output: false + * console.log( UE.utils.isEmptyObject( [1] ) ); + * + * //output: false + * console.log( UE.utils.isEmptyObject( "1" ) ); + * + * ``` + */ + isEmptyObject:function (obj) { + if (obj == null) return true; + if (this.isArray(obj) || this.isString(obj)) return obj.length === 0; + for (var key in obj) if (obj.hasOwnProperty(key)) return false; + return true; + }, + + /** + * 把rgb格式的颜色值转换成16进制格式 + * @method fixColor + * @param { String } rgb格式的颜色值 + * @param { String } + * @example + * rgb(255,255,255) => "#ffffff" + */ + fixColor:function (name, value) { + if (/color/i.test(name) && /rgba?/.test(value)) { + var array = value.split(","); + if (array.length > 3) + return ""; + value = "#"; + for (var i = 0, color; color = array[i++];) { + color = parseInt(color.replace(/[^\d]/gi, ''), 10).toString(16); + value += color.length == 1 ? "0" + color : color; + } + value = value.toUpperCase(); + } + return value; + }, + /** + * 只针对border,padding,margin做了处理,因为性能问题 + * @public + * @function + * @param {String} val style字符串 + */ + optCss:function (val) { + var padding, margin, border; + val = val.replace(/(padding|margin|border)\-([^:]+):([^;]+);?/gi, function (str, key, name, val) { + if (val.split(' ').length == 1) { + switch (key) { + case 'padding': + !padding && (padding = {}); + padding[name] = val; + return ''; + case 'margin': + !margin && (margin = {}); + margin[name] = val; + return ''; + case 'border': + return val == 'initial' ? '' : str; + } + } + return str; + }); + + function opt(obj, name) { + if (!obj) { + return ''; + } + var t = obj.top , b = obj.bottom, l = obj.left, r = obj.right, val = ''; + if (!t || !l || !b || !r) { + for (var p in obj) { + val += ';' + name + '-' + p + ':' + obj[p] + ';'; + } + } else { + val += ';' + name + ':' + + (t == b && b == l && l == r ? t : + t == b && l == r ? (t + ' ' + l) : + l == r ? (t + ' ' + l + ' ' + b) : (t + ' ' + r + ' ' + b + ' ' + l)) + ';' + } + return val; + } + + val += opt(padding, 'padding') + opt(margin, 'margin'); + return val.replace(/^[ \n\r\t;]*|[ \n\r\t]*$/, '').replace(/;([ \n\r\t]+)|\1;/g, ';') + .replace(/(&((l|g)t|quot|#39))?;{2,}/g, function (a, b) { + return b ? b + ";;" : ';' + }); + }, + + /** + * 克隆对象 + * @method clone + * @param { Object } source 源对象 + * @return { Object } source的一个副本 + */ + + /** + * 深度克隆对象,将source的属性克隆到target对象, 会覆盖target重名的属性。 + * @method clone + * @param { Object } source 源对象 + * @param { Object } target 目标对象 + * @return { Object } 附加了source对象所有属性的target对象 + */ + clone:function (source, target) { + var tmp; + target = target || {}; + for (var i in source) { + if (source.hasOwnProperty(i)) { + tmp = source[i]; + if (typeof tmp == 'object') { + target[i] = utils.isArray(tmp) ? [] : {}; + utils.clone(source[i], target[i]) + } else { + target[i] = tmp; + } + } + } + return target; + }, + + /** + * 把cm/pt为单位的值转换为px为单位的值 + * @method transUnitToPx + * @param { String } 待转换的带单位的字符串 + * @return { String } 转换为px为计量单位的值的字符串 + * @example + * ```javascript + * + * //output: 500px + * console.log( UE.utils.transUnitToPx( '20cm' ) ); + * + * //output: 27px + * console.log( UE.utils.transUnitToPx( '20pt' ) ); + * + * ``` + */ + transUnitToPx:function (val) { + if (!/(pt|cm)/.test(val)) { + return val + } + var unit; + val.replace(/([\d.]+)(\w+)/, function (str, v, u) { + val = v; + unit = u; + }); + switch (unit) { + case 'cm': + val = parseFloat(val) * 25; + break; + case 'pt': + val = Math.round(parseFloat(val) * 96 / 72); + } + return val + (val ? 'px' : ''); + }, + + /** + * 在dom树ready之后执行给定的回调函数 + * @method domReady + * @remind 如果在执行该方法的时候, dom树已经ready, 那么回调函数将立刻执行 + * @param { Function } fn dom树ready之后的回调函数 + * @example + * ```javascript + * + * UE.utils.domReady( function () { + * + * console.log('123'); + * + * } ); + * + * ``` + */ + domReady:function () { + + var fnArr = []; + + function doReady(doc) { + //确保onready只执行一次 + doc.isReady = true; + for (var ci; ci = fnArr.pop(); ci()) { + } + } + + return function (onready, win) { + win = win || window; + var doc = win.document; + onready && fnArr.push(onready); + if (doc.readyState === "complete") { + doReady(doc); + } else { + doc.isReady && doReady(doc); + if (browser.ie && browser.version != 11) { + (function () { + if (doc.isReady) return; + try { + doc.documentElement.doScroll("left"); + } catch (error) { + setTimeout(arguments.callee, 0); + return; + } + doReady(doc); + })(); + win.attachEvent('onload', function () { + doReady(doc) + }); + } else { + doc.addEventListener("DOMContentLoaded", function () { + doc.removeEventListener("DOMContentLoaded", arguments.callee, false); + doReady(doc); + }, false); + win.addEventListener('load', function () { + doReady(doc) + }, false); + } + } + + } + }(), + + /** + * 动态添加css样式 + * @method cssRule + * @param { String } 节点名称 + * @grammar UE.utils.cssRule('添加的样式的节点名称',['样式','放到哪个document上']) + * @grammar UE.utils.cssRule('body','body{background:#ccc}') => null //给body添加背景颜色 + * @grammar UE.utils.cssRule('body') =>样式的字符串 //取得key值为body的样式的内容,如果没有找到key值先关的样式将返回空,例如刚才那个背景颜色,将返回 body{background:#ccc} + * @grammar UE.utils.cssRule('body',document) => 返回指定key的样式,并且指定是哪个document + * @grammar UE.utils.cssRule('body','') =>null //清空给定的key值的背景颜色 + */ + cssRule:browser.ie && browser.version != 11 ? function (key, style, doc) { + var indexList, index; + if(style === undefined || style && style.nodeType && style.nodeType == 9){ + //获取样式 + doc = style && style.nodeType && style.nodeType == 9 ? style : (doc || document); + indexList = doc.indexList || (doc.indexList = {}); + index = indexList[key]; + if(index !== undefined){ + return doc.styleSheets[index].cssText + } + return undefined; + } + doc = doc || document; + indexList = doc.indexList || (doc.indexList = {}); + index = indexList[key]; + //清除样式 + if(style === ''){ + if(index!== undefined){ + doc.styleSheets[index].cssText = ''; + delete indexList[key]; + return true + } + return false; + } + + //添加样式 + if(index!== undefined){ + sheetStyle = doc.styleSheets[index]; + }else{ + sheetStyle = doc.createStyleSheet('', index = doc.styleSheets.length); + indexList[key] = index; + } + sheetStyle.cssText = style; + }: function (key, style, doc) { + var head, node; + if(style === undefined || style && style.nodeType && style.nodeType == 9){ + //获取样式 + doc = style && style.nodeType && style.nodeType == 9 ? style : (doc || document); + node = doc.getElementById(key); + return node ? node.innerHTML : undefined; + } + doc = doc || document; + node = doc.getElementById(key); + + //清除样式 + if(style === ''){ + if(node){ + node.parentNode.removeChild(node); + return true + } + return false; + } + + //添加样式 + if(node){ + node.innerHTML = style; + }else{ + node = doc.createElement('style'); + node.id = key; + node.innerHTML = style; + doc.getElementsByTagName('head')[0].appendChild(node); + } + }, + sort:function(array,compareFn){ + compareFn = compareFn || function(item1, item2){ return item1.localeCompare(item2);}; + for(var i= 0,len = array.length; i 0){ + var t = array[i]; + array[i] = array[j]; + array[j] = t; + } + } + } + return array; + }, + serializeParam:function (json) { + var strArr = []; + for (var i in json) { + //忽略默认的几个参数 + if(i=="method" || i=="timeout" || i=="async") continue; + //传递过来的对象和函数不在提交之列 + if (!((typeof json[i]).toLowerCase() == "function" || (typeof json[i]).toLowerCase() == "object")) { + strArr.push( encodeURIComponent(i) + "="+encodeURIComponent(json[i]) ); + } else if (utils.isArray(json[i])) { + //支持传数组内容 + for(var j = 0; j < json[i].length; j++) { + strArr.push( encodeURIComponent(i) + "[]="+encodeURIComponent(json[i][j]) ); + } + } + } + return strArr.join("&"); + }, + formatUrl:function (url) { + var u = url.replace(/&&/g, '&'); + u = u.replace(/\?&/g, '?'); + u = u.replace(/&$/g, ''); + u = u.replace(/&#/g, '#'); + u = u.replace(/&+/g, '&'); + return u; + }, + isCrossDomainUrl:function (url) { + var a = document.createElement('a'); + a.href = url; + if (browser.ie) { + a.href = a.href; + } + return !(a.protocol == location.protocol && a.hostname == location.hostname && + (a.port == location.port || (a.port == '80' && location.port == '') || (a.port == '' && location.port == '80'))); + }, + clearEmptyAttrs : function(obj){ + for(var p in obj){ + if(obj[p] === ''){ + delete obj[p] + } + } + return obj; + }, + str2json : function(s){ + + if (!utils.isString(s)) return null; + if (window.JSON) { + return JSON.parse(s); + } else { + return (new Function("return " + utils.trim(s || '')))(); + } + + }, + json2str : (function(){ + + if (window.JSON) { + + return JSON.stringify; + + } else { + + var escapeMap = { + "\b": '\\b', + "\t": '\\t', + "\n": '\\n', + "\f": '\\f', + "\r": '\\r', + '"' : '\\"', + "\\": '\\\\' + }; + + function encodeString(source) { + if (/["\\\x00-\x1f]/.test(source)) { + source = source.replace( + /["\\\x00-\x1f]/g, + function (match) { + var c = escapeMap[match]; + if (c) { + return c; + } + c = match.charCodeAt(); + return "\\u00" + + Math.floor(c / 16).toString(16) + + (c % 16).toString(16); + }); + } + return '"' + source + '"'; + } + + function encodeArray(source) { + var result = ["["], + l = source.length, + preComma, i, item; + + for (i = 0; i < l; i++) { + item = source[i]; + + switch (typeof item) { + case "undefined": + case "function": + case "unknown": + break; + default: + if(preComma) { + result.push(','); + } + result.push(utils.json2str(item)); + preComma = 1; + } + } + result.push("]"); + return result.join(""); + } + + function pad(source) { + return source < 10 ? '0' + source : source; + } + + function encodeDate(source){ + return '"' + source.getFullYear() + "-" + + pad(source.getMonth() + 1) + "-" + + pad(source.getDate()) + "T" + + pad(source.getHours()) + ":" + + pad(source.getMinutes()) + ":" + + pad(source.getSeconds()) + '"'; + } + + return function (value) { + switch (typeof value) { + case 'undefined': + return 'undefined'; + + case 'number': + return isFinite(value) ? String(value) : "null"; + + case 'string': + return encodeString(value); + + case 'boolean': + return String(value); + + default: + if (value === null) { + return 'null'; + } else if (utils.isArray(value)) { + return encodeArray(value); + } else if (utils.isDate(value)) { + return encodeDate(value); + } else { + var result = ['{'], + encode = utils.json2str, + preComma, + item; + + for (var key in value) { + if (Object.prototype.hasOwnProperty.call(value, key)) { + item = value[key]; + switch (typeof item) { + case 'undefined': + case 'unknown': + case 'function': + break; + default: + if (preComma) { + result.push(','); + } + preComma = 1; + result.push(encode(key) + ':' + encode(item)); + } + } + } + result.push('}'); + return result.join(''); + } + } + }; + } + + })() + +}; +/** + * 判断给定的对象是否是字符串 + * @method isString + * @param { * } object 需要判断的对象 + * @return { Boolean } 给定的对象是否是字符串 + */ + +/** + * 判断给定的对象是否是数组 + * @method isArray + * @param { * } object 需要判断的对象 + * @return { Boolean } 给定的对象是否是数组 + */ + +/** + * 判断给定的对象是否是一个Function + * @method isFunction + * @param { * } object 需要判断的对象 + * @return { Boolean } 给定的对象是否是Function + */ + +/** + * 判断给定的对象是否是Number + * @method isNumber + * @param { * } object 需要判断的对象 + * @return { Boolean } 给定的对象是否是Number + */ + +/** + * 判断给定的对象是否是一个正则表达式 + * @method isRegExp + * @param { * } object 需要判断的对象 + * @return { Boolean } 给定的对象是否是正则表达式 + */ + +/** + * 判断给定的对象是否是一个普通对象 + * @method isObject + * @param { * } object 需要判断的对象 + * @return { Boolean } 给定的对象是否是普通对象 + */ +utils.each(['String', 'Function', 'Array', 'Number', 'RegExp', 'Object', 'Date'], function (v) { + UE.utils['is' + v] = function (obj) { + return Object.prototype.toString.apply(obj) == '[object ' + v + ']'; + } +}); + + +// core/EventBase.js +/** + * UE采用的事件基类 + * @file + * @module UE + * @class EventBase + * @since 1.2.6.1 + */ + +/** + * UEditor公用空间,UEditor所有的功能都挂载在该空间下 + * @unfile + * @module UE + */ + +/** + * UE采用的事件基类,继承此类的对应类将获取addListener,removeListener,fireEvent方法。 + * 在UE中,Editor以及所有ui实例都继承了该类,故可以在对应的ui对象以及editor对象上使用上述方法。 + * @unfile + * @module UE + * @class EventBase + */ + +/** + * 通过此构造器,子类可以继承EventBase获取事件监听的方法 + * @constructor + * @example + * ```javascript + * UE.EventBase.call(editor); + * ``` + */ +var EventBase = UE.EventBase = function () {}; + +EventBase.prototype = { + + /** + * 注册事件监听器 + * @method addListener + * @param { String } types 监听的事件名称,同时监听多个事件使用空格分隔 + * @param { Function } fn 监听的事件被触发时,会执行该回调函数 + * @waining 事件被触发时,监听的函数假如返回的值恒等于true,回调函数的队列中后面的函数将不执行 + * @example + * ```javascript + * editor.addListener('selectionchange',function(){ + * console.log("选区已经变化!"); + * }) + * editor.addListener('beforegetcontent aftergetcontent',function(type){ + * if(type == 'beforegetcontent'){ + * //do something + * }else{ + * //do something + * } + * console.log(this.getContent) // this是注册的事件的编辑器实例 + * }) + * ``` + * @see UE.EventBase:fireEvent(String) + */ + addListener:function (types, listener) { + types = utils.trim(types).split(/\s+/); + for (var i = 0, ti; ti = types[i++];) { + getListener(this, ti, true).push(listener); + } + }, + + on : function(types, listener){ + return this.addListener(types,listener); + }, + off : function(types, listener){ + return this.removeListener(types, listener) + }, + trigger:function(){ + return this.fireEvent.apply(this,arguments); + }, + /** + * 移除事件监听器 + * @method removeListener + * @param { String } types 移除的事件名称,同时移除多个事件使用空格分隔 + * @param { Function } fn 移除监听事件的函数引用 + * @example + * ```javascript + * //changeCallback为方法体 + * editor.removeListener("selectionchange",changeCallback); + * ``` + */ + removeListener:function (types, listener) { + types = utils.trim(types).split(/\s+/); + for (var i = 0, ti; ti = types[i++];) { + utils.removeItem(getListener(this, ti) || [], listener); + } + }, + + /** + * 触发事件 + * @method fireEvent + * @param { String } types 触发的事件名称,同时触发多个事件使用空格分隔 + * @remind 该方法会触发addListener + * @return { * } 返回触发事件的队列中,最后执行的回调函数的返回值 + * @example + * ```javascript + * editor.fireEvent("selectionchange"); + * ``` + */ + + /** + * 触发事件 + * @method fireEvent + * @param { String } types 触发的事件名称,同时触发多个事件使用空格分隔 + * @param { *... } options 可选参数,可以传入一个或多个参数,会传给事件触发的回调函数 + * @return { * } 返回触发事件的队列中,最后执行的回调函数的返回值 + * @example + * ```javascript + * + * editor.addListener( "selectionchange", function ( type, arg1, arg2 ) { + * + * console.log( arg1 + " " + arg2 ); + * + * } ); + * + * //触发selectionchange事件, 会执行上面的事件监听器 + * //output: Hello World + * editor.fireEvent("selectionchange", "Hello", "World"); + * ``` + */ + fireEvent:function () { + var types = arguments[0]; + types = utils.trim(types).split(' '); + for (var i = 0, ti; ti = types[i++];) { + var listeners = getListener(this, ti), + r, t, k; + if (listeners) { + k = listeners.length; + while (k--) { + if(!listeners[k])continue; + t = listeners[k].apply(this, arguments); + if(t === true){ + return t; + } + if (t !== undefined) { + r = t; + } + } + } + if (t = this['on' + ti.toLowerCase()]) { + r = t.apply(this, arguments); + } + } + return r; + } +}; +/** + * 获得对象所拥有监听类型的所有监听器 + * @unfile + * @module UE + * @since 1.2.6.1 + * @method getListener + * @public + * @param { Object } obj 查询监听器的对象 + * @param { String } type 事件类型 + * @param { Boolean } force 为true且当前所有type类型的侦听器不存在时,创建一个空监听器数组 + * @return { Array } 监听器数组 + */ +function getListener(obj, type, force) { + var allListeners; + type = type.toLowerCase(); + return ( ( allListeners = ( obj.__allListeners || force && ( obj.__allListeners = {} ) ) ) + && ( allListeners[type] || force && ( allListeners[type] = [] ) ) ); +} + + + +// core/dtd.js +///import editor.js +///import core/dom/dom.js +///import core/utils.js +/** + * dtd html语义化的体现类 + * @constructor + * @namespace dtd + */ +var dtd = dom.dtd = (function() { + function _( s ) { + for (var k in s) { + s[k.toUpperCase()] = s[k]; + } + return s; + } + var X = utils.extend2; + var A = _({isindex:1,fieldset:1}), + B = _({input:1,button:1,select:1,textarea:1,label:1}), + C = X( _({a:1}), B ), + D = X( {iframe:1}, C ), + E = _({hr:1,ul:1,menu:1,div:1,blockquote:1,noscript:1,table:1,center:1,address:1,dir:1,pre:1,h5:1,dl:1,h4:1,noframes:1,h6:1,ol:1,h1:1,h3:1,h2:1}), + F = _({ins:1,del:1,script:1,style:1}), + G = X( _({b:1,acronym:1,bdo:1,'var':1,'#':1,abbr:1,code:1,br:1,i:1,cite:1,kbd:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,dfn:1,span:1}), F ), + H = X( _({sub:1,img:1,embed:1,object:1,sup:1,basefont:1,map:1,applet:1,font:1,big:1,small:1}), G ), + I = X( _({p:1}), H ), + J = X( _({iframe:1}), H, B ), + K = _({img:1,embed:1,noscript:1,br:1,kbd:1,center:1,button:1,basefont:1,h5:1,h4:1,samp:1,h6:1,ol:1,h1:1,h3:1,h2:1,form:1,font:1,'#':1,select:1,menu:1,ins:1,abbr:1,label:1,code:1,table:1,script:1,cite:1,input:1,iframe:1,strong:1,textarea:1,noframes:1,big:1,small:1,span:1,hr:1,sub:1,bdo:1,'var':1,div:1,object:1,sup:1,strike:1,dir:1,map:1,dl:1,applet:1,del:1,isindex:1,fieldset:1,ul:1,b:1,acronym:1,a:1,blockquote:1,i:1,u:1,s:1,tt:1,address:1,q:1,pre:1,p:1,em:1,dfn:1}), + + L = X( _({a:0}), J ),//a不能被切开,所以把他 + M = _({tr:1}), + N = _({'#':1}), + O = X( _({param:1}), K ), + P = X( _({form:1}), A, D, E, I ), + Q = _({li:1,ol:1,ul:1}), + R = _({style:1,script:1}), + S = _({base:1,link:1,meta:1,title:1}), + T = X( S, R ), + U = _({head:1,body:1}), + V = _({html:1}); + + var block = _({address:1,blockquote:1,center:1,dir:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,isindex:1,menu:1,noframes:1,ol:1,p:1,pre:1,table:1,ul:1}), + + empty = _({area:1,base:1,basefont:1,br:1,col:1,command:1,dialog:1,embed:1,hr:1,img:1,input:1,isindex:1,keygen:1,link:1,meta:1,param:1,source:1,track:1,wbr:1}); + + return _({ + + // $ 表示自定的属性 + + // body外的元素列表. + $nonBodyContent: X( V, U, S ), + + //块结构元素列表 + $block : block, + + //内联元素列表 + $inline : L, + + $inlineWithA : X(_({a:1}),L), + + $body : X( _({script:1,style:1}), block ), + + $cdata : _({script:1,style:1}), + + //自闭和元素 + $empty : empty, + + //不是自闭合,但不能让range选中里边 + $nonChild : _({iframe:1,textarea:1}), + //列表元素列表 + $listItem : _({dd:1,dt:1,li:1}), + + //列表根元素列表 + $list: _({ul:1,ol:1,dl:1}), + + //不能认为是空的元素 + $isNotEmpty : _({table:1,ul:1,ol:1,dl:1,iframe:1,area:1,base:1,col:1,hr:1,img:1,embed:1,input:1,link:1,meta:1,param:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1}), + + //如果没有子节点就可以删除的元素列表,像span,a + $removeEmpty : _({a:1,abbr:1,acronym:1,address:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,s:1,samp:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,tt:1,u:1,'var':1}), + + $removeEmptyBlock : _({'p':1,'div':1}), + + //在table元素里的元素列表 + $tableContent : _({caption:1,col:1,colgroup:1,tbody:1,td:1,tfoot:1,th:1,thead:1,tr:1,table:1}), + //不转换的标签 + $notTransContent : _({pre:1,script:1,style:1,textarea:1}), + html: U, + head: T, + style: N, + script: N, + body: P, + base: {}, + link: {}, + meta: {}, + title: N, + col : {}, + tr : _({td:1,th:1}), + img : {}, + embed: {}, + colgroup : _({thead:1,col:1,tbody:1,tr:1,tfoot:1}), + noscript : P, + td : P, + br : {}, + th : P, + center : P, + kbd : L, + button : X( I, E ), + basefont : {}, + h5 : L, + h4 : L, + samp : L, + h6 : L, + ol : Q, + h1 : L, + h3 : L, + option : N, + h2 : L, + form : X( A, D, E, I ), + select : _({optgroup:1,option:1}), + font : L, + ins : L, + menu : Q, + abbr : L, + label : L, + table : _({thead:1,col:1,tbody:1,tr:1,colgroup:1,caption:1,tfoot:1}), + code : L, + tfoot : M, + cite : L, + li : P, + input : {}, + iframe : P, + strong : L, + textarea : N, + noframes : P, + big : L, + small : L, + //trace: + span :_({'#':1,br:1,b:1,strong:1,u:1,i:1,em:1,sub:1,sup:1,strike:1,span:1}), + hr : L, + dt : L, + sub : L, + optgroup : _({option:1}), + param : {}, + bdo : L, + 'var' : L, + div : P, + object : O, + sup : L, + dd : P, + strike : L, + area : {}, + dir : Q, + map : X( _({area:1,form:1,p:1}), A, F, E ), + applet : O, + dl : _({dt:1,dd:1}), + del : L, + isindex : {}, + fieldset : X( _({legend:1}), K ), + thead : M, + ul : Q, + acronym : L, + b : L, + a : X( _({a:1}), J ), + blockquote :X(_({td:1,tr:1,tbody:1,li:1}),P), + caption : L, + i : L, + u : L, + tbody : M, + s : L, + address : X( D, I ), + tt : L, + legend : L, + q : L, + pre : X( G, C ), + p : X(_({'a':1}),L), + em :L, + dfn : L + }); +})(); + + +// core/domUtils.js +/** + * Dom操作工具包 + * @file + * @module UE.dom.domUtils + * @since 1.2.6.1 + */ + +/** + * Dom操作工具包 + * @unfile + * @module UE.dom.domUtils + */ +function getDomNode(node, start, ltr, startFromChild, fn, guard) { + var tmpNode = startFromChild && node[start], + parent; + !tmpNode && (tmpNode = node[ltr]); + while (!tmpNode && (parent = (parent || node).parentNode)) { + if (parent.tagName == 'BODY' || guard && !guard(parent)) { + return null; + } + tmpNode = parent[ltr]; + } + if (tmpNode && fn && !fn(tmpNode)) { + return getDomNode(tmpNode, start, ltr, false, fn); + } + return tmpNode; +} +var attrFix = ie && browser.version < 9 ? { + tabindex:"tabIndex", + readonly:"readOnly", + "for":"htmlFor", + "class":"className", + maxlength:"maxLength", + cellspacing:"cellSpacing", + cellpadding:"cellPadding", + rowspan:"rowSpan", + colspan:"colSpan", + usemap:"useMap", + frameborder:"frameBorder" + } : { + tabindex:"tabIndex", + readonly:"readOnly" + }, + styleBlock = utils.listToMap([ + '-webkit-box', '-moz-box', 'block' , + 'list-item' , 'table' , 'table-row-group' , + 'table-header-group', 'table-footer-group' , + 'table-row' , 'table-column-group' , 'table-column' , + 'table-cell' , 'table-caption' + ]); +var domUtils = dom.domUtils = { + //节点常量 + NODE_ELEMENT:1, + NODE_DOCUMENT:9, + NODE_TEXT:3, + NODE_COMMENT:8, + NODE_DOCUMENT_FRAGMENT:11, + + //位置关系 + POSITION_IDENTICAL:0, + POSITION_DISCONNECTED:1, + POSITION_FOLLOWING:2, + POSITION_PRECEDING:4, + POSITION_IS_CONTAINED:8, + POSITION_CONTAINS:16, + //ie6使用其他的会有一段空白出现 + fillChar:ie && browser.version == '6' ? '\ufeff' : '\u200B', + //-------------------------Node部分-------------------------------- + keys:{ + /*Backspace*/ 8:1, /*Delete*/ 46:1, + /*Shift*/ 16:1, /*Ctrl*/ 17:1, /*Alt*/ 18:1, + 37:1, 38:1, 39:1, 40:1, + 13:1 /*enter*/ + }, + /** + * 获取节点A相对于节点B的位置关系 + * @method getPosition + * @param { Node } nodeA 需要查询位置关系的节点A + * @param { Node } nodeB 需要查询位置关系的节点B + * @return { Number } 节点A与节点B的关系 + * @example + * ```javascript + * //output: 20 + * var position = UE.dom.domUtils.getPosition( document.documentElement, document.body ); + * + * switch ( position ) { + * + * //0 + * case UE.dom.domUtils.POSITION_IDENTICAL: + * console.log('元素相同'); + * break; + * //1 + * case UE.dom.domUtils.POSITION_DISCONNECTED: + * console.log('两个节点在不同的文档中'); + * break; + * //2 + * case UE.dom.domUtils.POSITION_FOLLOWING: + * console.log('节点A在节点B之后'); + * break; + * //4 + * case UE.dom.domUtils.POSITION_PRECEDING; + * console.log('节点A在节点B之前'); + * break; + * //8 + * case UE.dom.domUtils.POSITION_IS_CONTAINED: + * console.log('节点A被节点B包含'); + * break; + * case 10: + * console.log('节点A被节点B包含且节点A在节点B之后'); + * break; + * //16 + * case UE.dom.domUtils.POSITION_CONTAINS: + * console.log('节点A包含节点B'); + * break; + * case 20: + * console.log('节点A包含节点B且节点A在节点B之前'); + * break; + * + * } + * ``` + */ + getPosition:function (nodeA, nodeB) { + // 如果两个节点是同一个节点 + if (nodeA === nodeB) { + // domUtils.POSITION_IDENTICAL + return 0; + } + var node, + parentsA = [nodeA], + parentsB = [nodeB]; + node = nodeA; + while (node = node.parentNode) { + // 如果nodeB是nodeA的祖先节点 + if (node === nodeB) { + // domUtils.POSITION_IS_CONTAINED + domUtils.POSITION_FOLLOWING + return 10; + } + parentsA.push(node); + } + node = nodeB; + while (node = node.parentNode) { + // 如果nodeA是nodeB的祖先节点 + if (node === nodeA) { + // domUtils.POSITION_CONTAINS + domUtils.POSITION_PRECEDING + return 20; + } + parentsB.push(node); + } + parentsA.reverse(); + parentsB.reverse(); + if (parentsA[0] !== parentsB[0]) { + // domUtils.POSITION_DISCONNECTED + return 1; + } + var i = -1; + while (i++, parentsA[i] === parentsB[i]) { + } + nodeA = parentsA[i]; + nodeB = parentsB[i]; + while (nodeA = nodeA.nextSibling) { + if (nodeA === nodeB) { + // domUtils.POSITION_PRECEDING + return 4 + } + } + // domUtils.POSITION_FOLLOWING + return 2; + }, + + /** + * 检测节点node在父节点中的索引位置 + * @method getNodeIndex + * @param { Node } node 需要检测的节点对象 + * @return { Number } 该节点在父节点中的位置 + * @see UE.dom.domUtils.getNodeIndex(Node,Boolean) + */ + + /** + * 检测节点node在父节点中的索引位置, 根据给定的mergeTextNode参数决定是否要合并多个连续的文本节点为一个节点 + * @method getNodeIndex + * @param { Node } node 需要检测的节点对象 + * @param { Boolean } mergeTextNode 是否合并多个连续的文本节点为一个节点 + * @return { Number } 该节点在父节点中的位置 + * @example + * ```javascript + * + * var node = document.createElement("div"); + * + * node.appendChild( document.createTextNode( "hello" ) ); + * node.appendChild( document.createTextNode( "world" ) ); + * node.appendChild( node = document.createElement( "div" ) ); + * + * //output: 2 + * console.log( UE.dom.domUtils.getNodeIndex( node ) ); + * + * //output: 1 + * console.log( UE.dom.domUtils.getNodeIndex( node, true ) ); + * + * ``` + */ + getNodeIndex:function (node, ignoreTextNode) { + var preNode = node, + i = 0; + while (preNode = preNode.previousSibling) { + if (ignoreTextNode && preNode.nodeType == 3) { + if(preNode.nodeType != preNode.nextSibling.nodeType ){ + i++; + } + continue; + } + i++; + } + return i; + }, + + /** + * 检测节点node是否在给定的document对象上 + * @method inDoc + * @param { Node } node 需要检测的节点对象 + * @param { DomDocument } doc 需要检测的document对象 + * @return { Boolean } 该节点node是否在给定的document的dom树上 + * @example + * ```javascript + * + * var node = document.createElement("div"); + * + * //output: false + * console.log( UE.do.domUtils.inDoc( node, document ) ); + * + * document.body.appendChild( node ); + * + * //output: true + * console.log( UE.do.domUtils.inDoc( node, document ) ); + * + * ``` + */ + inDoc:function (node, doc) { + return domUtils.getPosition(node, doc) == 10; + }, + /** + * 根据给定的过滤规则filterFn, 查找符合该过滤规则的node节点的第一个祖先节点, + * 查找的起点是给定node节点的父节点。 + * @method findParent + * @param { Node } node 需要查找的节点 + * @param { Function } filterFn 自定义的过滤方法。 + * @warning 查找的终点是到body节点为止 + * @remind 自定义的过滤方法filterFn接受一个Node对象作为参数, 该对象代表当前执行检测的祖先节点。 如果该 + * 节点满足过滤条件, 则要求返回true, 这时将直接返回该节点作为findParent()的结果, 否则, 请返回false。 + * @return { Node | Null } 如果找到符合过滤条件的节点, 就返回该节点, 否则返回NULL + * @example + * ```javascript + * var filterNode = UE.dom.domUtils.findParent( document.body.firstChild, function ( node ) { + * + * //由于查找的终点是body节点, 所以永远也不会匹配当前过滤器的条件, 即这里永远会返回false + * return node.tagName === "HTML"; + * + * } ); + * + * //output: true + * console.log( filterNode === null ); + * ``` + */ + + /** + * 根据给定的过滤规则filterFn, 查找符合该过滤规则的node节点的第一个祖先节点, + * 如果includeSelf的值为true,则查找的起点是给定的节点node, 否则, 起点是node的父节点 + * @method findParent + * @param { Node } node 需要查找的节点 + * @param { Function } filterFn 自定义的过滤方法。 + * @param { Boolean } includeSelf 查找过程是否包含自身 + * @warning 查找的终点是到body节点为止 + * @remind 自定义的过滤方法filterFn接受一个Node对象作为参数, 该对象代表当前执行检测的祖先节点。 如果该 + * 节点满足过滤条件, 则要求返回true, 这时将直接返回该节点作为findParent()的结果, 否则, 请返回false。 + * @remind 如果includeSelf为true, 则过滤器第一次执行时的参数会是节点本身。 + * 反之, 过滤器第一次执行时的参数将是该节点的父节点。 + * @return { Node | Null } 如果找到符合过滤条件的节点, 就返回该节点, 否则返回NULL + * @example + * ```html + * + * + *
      + *
      + * + * + * + * ``` + */ + findParent:function (node, filterFn, includeSelf) { + if (node && !domUtils.isBody(node)) { + node = includeSelf ? node : node.parentNode; + while (node) { + if (!filterFn || filterFn(node) || domUtils.isBody(node)) { + return filterFn && !filterFn(node) && domUtils.isBody(node) ? null : node; + } + node = node.parentNode; + } + } + return null; + }, + /** + * 查找node的节点名为tagName的第一个祖先节点, 查找的起点是node节点的父节点。 + * @method findParentByTagName + * @param { Node } node 需要查找的节点对象 + * @param { Array } tagNames 需要查找的父节点的名称数组 + * @warning 查找的终点是到body节点为止 + * @return { Node | NULL } 如果找到符合条件的节点, 则返回该节点, 否则返回NULL + * @example + * ```javascript + * var node = UE.dom.domUtils.findParentByTagName( document.getElementsByTagName("div")[0], [ "BODY" ] ); + * //output: BODY + * console.log( node.tagName ); + * ``` + */ + + /** + * 查找node的节点名为tagName的祖先节点, 如果includeSelf的值为true,则查找的起点是给定的节点node, + * 否则, 起点是node的父节点。 + * @method findParentByTagName + * @param { Node } node 需要查找的节点对象 + * @param { Array } tagNames 需要查找的父节点的名称数组 + * @param { Boolean } includeSelf 查找过程是否包含node节点自身 + * @warning 查找的终点是到body节点为止 + * @return { Node | NULL } 如果找到符合条件的节点, 则返回该节点, 否则返回NULL + * @example + * ```javascript + * var queryTarget = document.getElementsByTagName("div")[0]; + * var node = UE.dom.domUtils.findParentByTagName( queryTarget, [ "DIV" ], true ); + * //output: true + * console.log( queryTarget === node ); + * ``` + */ + findParentByTagName:function (node, tagNames, includeSelf, excludeFn) { + tagNames = utils.listToMap(utils.isArray(tagNames) ? tagNames : [tagNames]); + return domUtils.findParent(node, function (node) { + return tagNames[node.tagName] && !(excludeFn && excludeFn(node)); + }, includeSelf); + }, + /** + * 查找节点node的祖先节点集合, 查找的起点是给定节点的父节点,结果集中不包含给定的节点。 + * @method findParents + * @param { Node } node 需要查找的节点对象 + * @return { Array } 给定节点的祖先节点数组 + * @grammar UE.dom.domUtils.findParents(node) => Array //返回一个祖先节点数组集合,不包含自身 + * @grammar UE.dom.domUtils.findParents(node,includeSelf) => Array //返回一个祖先节点数组集合,includeSelf指定是否包含自身 + * @grammar UE.dom.domUtils.findParents(node,includeSelf,filterFn) => Array //返回一个祖先节点数组集合,filterFn指定过滤条件,返回true的node将被选取 + * @grammar UE.dom.domUtils.findParents(node,includeSelf,filterFn,closerFirst) => Array //返回一个祖先节点数组集合,closerFirst为true的话,node的直接父亲节点是数组的第0个 + */ + + /** + * 查找节点node的祖先节点集合, 如果includeSelf的值为true, + * 则返回的结果集中允许出现当前给定的节点, 否则, 该节点不会出现在其结果集中。 + * @method findParents + * @param { Node } node 需要查找的节点对象 + * @param { Boolean } includeSelf 查找的结果中是否允许包含当前查找的节点对象 + * @return { Array } 给定节点的祖先节点数组 + */ + findParents:function (node, includeSelf, filterFn, closerFirst) { + var parents = includeSelf && ( filterFn && filterFn(node) || !filterFn ) ? [node] : []; + while (node = domUtils.findParent(node, filterFn)) { + parents.push(node); + } + return closerFirst ? parents : parents.reverse(); + }, + + /** + * 在节点node后面插入新节点newNode + * @method insertAfter + * @param { Node } node 目标节点 + * @param { Node } newNode 新插入的节点, 该节点将置于目标节点之后 + * @return { Node } 新插入的节点 + */ + insertAfter:function (node, newNode) { + return node.nextSibling ? node.parentNode.insertBefore(newNode, node.nextSibling): + node.parentNode.appendChild(newNode); + }, + + /** + * 删除节点node及其下属的所有节点 + * @method remove + * @param { Node } node 需要删除的节点对象 + * @return { Node } 返回刚删除的节点对象 + * @example + * ```html + *
      + *
      你好
      + *
      + * + * ``` + */ + + /** + * 删除节点node,并根据keepChildren的值决定是否保留子节点 + * @method remove + * @param { Node } node 需要删除的节点对象 + * @param { Boolean } keepChildren 是否需要保留子节点 + * @return { Node } 返回刚删除的节点对象 + * @example + * ```html + *
      + *
      你好
      + *
      + * + * ``` + */ + remove:function (node, keepChildren) { + var parent = node.parentNode, + child; + if (parent) { + if (keepChildren && node.hasChildNodes()) { + while (child = node.firstChild) { + parent.insertBefore(child, node); + } + } + parent.removeChild(node); + } + return node; + }, + + /** + * 取得node节点的下一个兄弟节点, 如果该节点其后没有兄弟节点, 则递归查找其父节点之后的第一个兄弟节点, + * 直到找到满足条件的节点或者递归到BODY节点之后才会结束。 + * @method getNextDomNode + * @param { Node } node 需要获取其后的兄弟节点的节点对象 + * @return { Node | NULL } 如果找满足条件的节点, 则返回该节点, 否则返回NULL + * @example + * ```html + * + *
      + * + *
      + * xxx + * + * + * ``` + * @example + * ```html + * + *
      + * + * xxx + *
      + * xxx + * + * + * ``` + */ + + /** + * 取得node节点的下一个兄弟节点, 如果startFromChild的值为ture,则先获取其子节点, + * 如果有子节点则直接返回第一个子节点;如果没有子节点或者startFromChild的值为false, + * 则执行getNextDomNode(Node node)的查找过程。 + * @method getNextDomNode + * @param { Node } node 需要获取其后的兄弟节点的节点对象 + * @param { Boolean } startFromChild 查找过程是否从其子节点开始 + * @return { Node | NULL } 如果找满足条件的节点, 则返回该节点, 否则返回NULL + * @see UE.dom.domUtils.getNextDomNode(Node) + */ + getNextDomNode:function (node, startFromChild, filterFn, guard) { + return getDomNode(node, 'firstChild', 'nextSibling', startFromChild, filterFn, guard); + }, + getPreDomNode:function (node, startFromChild, filterFn, guard) { + return getDomNode(node, 'lastChild', 'previousSibling', startFromChild, filterFn, guard); + }, + /** + * 检测节点node是否属是UEditor定义的bookmark节点 + * @method isBookmarkNode + * @private + * @param { Node } node 需要检测的节点对象 + * @return { Boolean } 是否是bookmark节点 + * @example + * ```html + * + * + * ``` + */ + isBookmarkNode:function (node) { + return node.nodeType == 1 && node.id && /^_baidu_bookmark_/i.test(node.id); + }, + /** + * 获取节点node所属的window对象 + * @method getWindow + * @param { Node } node 节点对象 + * @return { Window } 当前节点所属的window对象 + * @example + * ```javascript + * //output: true + * console.log( UE.dom.domUtils.getWindow( document.body ) === window ); + * ``` + */ + getWindow:function (node) { + var doc = node.ownerDocument || node; + return doc.defaultView || doc.parentWindow; + }, + /** + * 获取离nodeA与nodeB最近的公共的祖先节点 + * @method getCommonAncestor + * @param { Node } nodeA 第一个节点 + * @param { Node } nodeB 第二个节点 + * @remind 如果给定的两个节点是同一个节点, 将直接返回该节点。 + * @return { Node | NULL } 如果未找到公共节点, 返回NULL, 否则返回最近的公共祖先节点。 + * @example + * ```javascript + * var commonAncestor = UE.dom.domUtils.getCommonAncestor( document.body, document.body.firstChild ); + * //output: true + * console.log( commonAncestor.tagName.toLowerCase() === 'body' ); + * ``` + */ + getCommonAncestor:function (nodeA, nodeB) { + if (nodeA === nodeB) + return nodeA; + var parentsA = [nodeA] , parentsB = [nodeB], parent = nodeA, i = -1; + while (parent = parent.parentNode) { + if (parent === nodeB) { + return parent; + } + parentsA.push(parent); + } + parent = nodeB; + while (parent = parent.parentNode) { + if (parent === nodeA) + return parent; + parentsB.push(parent); + } + parentsA.reverse(); + parentsB.reverse(); + while (i++, parentsA[i] === parentsB[i]) { + } + return i == 0 ? null : parentsA[i - 1]; + + }, + /** + * 清除node节点左右连续为空的兄弟inline节点 + * @method clearEmptySibling + * @param { Node } node 执行的节点对象, 如果该节点的左右连续的兄弟节点是空的inline节点, + * 则这些兄弟节点将被删除 + * @grammar UE.dom.domUtils.clearEmptySibling(node,ignoreNext) //ignoreNext指定是否忽略右边空节点 + * @grammar UE.dom.domUtils.clearEmptySibling(node,ignoreNext,ignorePre) //ignorePre指定是否忽略左边空节点 + * @example + * ```html + * + *
      + * + * + * + * xxx + * + * + * + * ``` + */ + + /** + * 清除node节点左右连续为空的兄弟inline节点, 如果ignoreNext的值为true, + * 则忽略对右边兄弟节点的操作。 + * @method clearEmptySibling + * @param { Node } node 执行的节点对象, 如果该节点的左右连续的兄弟节点是空的inline节点, + * @param { Boolean } ignoreNext 是否忽略忽略对右边的兄弟节点的操作 + * 则这些兄弟节点将被删除 + * @see UE.dom.domUtils.clearEmptySibling(Node) + */ + + /** + * 清除node节点左右连续为空的兄弟inline节点, 如果ignoreNext的值为true, + * 则忽略对右边兄弟节点的操作, 如果ignorePre的值为true,则忽略对左边兄弟节点的操作。 + * @method clearEmptySibling + * @param { Node } node 执行的节点对象, 如果该节点的左右连续的兄弟节点是空的inline节点, + * @param { Boolean } ignoreNext 是否忽略忽略对右边的兄弟节点的操作 + * @param { Boolean } ignorePre 是否忽略忽略对左边的兄弟节点的操作 + * 则这些兄弟节点将被删除 + * @see UE.dom.domUtils.clearEmptySibling(Node) + */ + clearEmptySibling:function (node, ignoreNext, ignorePre) { + function clear(next, dir) { + var tmpNode; + while (next && !domUtils.isBookmarkNode(next) && (domUtils.isEmptyInlineElement(next) + //这里不能把空格算进来会吧空格干掉,出现文字间的空格丢掉了 + || !new RegExp('[^\t\n\r' + domUtils.fillChar + ']').test(next.nodeValue) )) { + tmpNode = next[dir]; + domUtils.remove(next); + next = tmpNode; + } + } + !ignoreNext && clear(node.nextSibling, 'nextSibling'); + !ignorePre && clear(node.previousSibling, 'previousSibling'); + }, + /** + * 将一个文本节点textNode拆分成两个文本节点,offset指定拆分位置 + * @method split + * @param { Node } textNode 需要拆分的文本节点对象 + * @param { int } offset 需要拆分的位置, 位置计算从0开始 + * @return { Node } 拆分后形成的新节点 + * @example + * ```html + *
      abcdef
      + * + * ``` + */ + split:function (node, offset) { + var doc = node.ownerDocument; + if (browser.ie && offset == node.nodeValue.length) { + var next = doc.createTextNode(''); + return domUtils.insertAfter(node, next); + } + var retval = node.splitText(offset); + //ie8下splitText不会跟新childNodes,我们手动触发他的更新 + if (browser.ie8) { + var tmpNode = doc.createTextNode(''); + domUtils.insertAfter(retval, tmpNode); + domUtils.remove(tmpNode); + } + return retval; + }, + + /** + * 检测文本节点textNode是否为空节点(包括空格、换行、占位符等字符) + * @method isWhitespace + * @param { Node } node 需要检测的节点对象 + * @return { Boolean } 检测的节点是否为空 + * @example + * ```html + *
      + * + *
      + * + * ``` + */ + isWhitespace:function (node) { + return !new RegExp('[^ \t\n\r' + domUtils.fillChar + ']').test(node.nodeValue); + }, + /** + * 获取元素element相对于viewport的位置坐标 + * @method getXY + * @param { Node } element 需要计算位置的节点对象 + * @return { Object } 返回形如{x:left,y:top}的一个key-value映射对象, 其中键x代表水平偏移距离, + * y代表垂直偏移距离。 + * + * @example + * ```javascript + * var location = UE.dom.domUtils.getXY( document.getElementById("test") ); + * //output: test的坐标为: 12, 24 + * console.log( 'test的坐标为: ', location.x, ',', location.y ); + * ``` + */ + getXY:function (element) { + var x = 0, y = 0; + while (element.offsetParent) { + y += element.offsetTop; + x += element.offsetLeft; + element = element.offsetParent; + } + return { 'x':x, 'y':y}; + }, + /** + * 为元素element绑定原生DOM事件,type为事件类型,handler为处理函数 + * @method on + * @param { Node } element 需要绑定事件的节点对象 + * @param { String } type 绑定的事件类型 + * @param { Function } handler 事件处理器 + * @example + * ```javascript + * UE.dom.domUtils.on(document.body,"click",function(e){ + * //e为事件对象,this为被点击元素对戏那个 + * }); + * ``` + */ + + /** + * 为元素element绑定原生DOM事件,type为事件类型,handler为处理函数 + * @method on + * @param { Node } element 需要绑定事件的节点对象 + * @param { Array } type 绑定的事件类型数组 + * @param { Function } handler 事件处理器 + * @example + * ```javascript + * UE.dom.domUtils.on(document.body,["click","mousedown"],function(evt){ + * //evt为事件对象,this为被点击元素对象 + * }); + * ``` + */ + on:function (element, type, handler) { + + var types = utils.isArray(type) ? type : utils.trim(type).split(/\s+/), + k = types.length; + if (k) while (k--) { + type = types[k]; + if (element.addEventListener) { + element.addEventListener(type, handler, false); + } else { + if (!handler._d) { + handler._d = { + els : [] + }; + } + var key = type + handler.toString(),index = utils.indexOf(handler._d.els,element); + if (!handler._d[key] || index == -1) { + if(index == -1){ + handler._d.els.push(element); + } + if(!handler._d[key]){ + handler._d[key] = function (evt) { + return handler.call(evt.srcElement, evt || window.event); + }; + } + + + element.attachEvent('on' + type, handler._d[key]); + } + } + } + element = null; + }, + /** + * 解除DOM事件绑定 + * @method un + * @param { Node } element 需要解除事件绑定的节点对象 + * @param { String } type 需要接触绑定的事件类型 + * @param { Function } handler 对应的事件处理器 + * @example + * ```javascript + * UE.dom.domUtils.un(document.body,"click",function(evt){ + * //evt为事件对象,this为被点击元素对象 + * }); + * ``` + */ + + /** + * 解除DOM事件绑定 + * @method un + * @param { Node } element 需要解除事件绑定的节点对象 + * @param { Array } type 需要接触绑定的事件类型数组 + * @param { Function } handler 对应的事件处理器 + * @example + * ```javascript + * UE.dom.domUtils.un(document.body, ["click","mousedown"],function(evt){ + * //evt为事件对象,this为被点击元素对象 + * }); + * ``` + */ + un:function (element, type, handler) { + var types = utils.isArray(type) ? type : utils.trim(type).split(/\s+/), + k = types.length; + if (k) while (k--) { + type = types[k]; + if (element.removeEventListener) { + element.removeEventListener(type, handler, false); + } else { + var key = type + handler.toString(); + try{ + element.detachEvent('on' + type, handler._d ? handler._d[key] : handler); + }catch(e){} + if (handler._d && handler._d[key]) { + var index = utils.indexOf(handler._d.els,element); + if(index!=-1){ + handler._d.els.splice(index,1); + } + handler._d.els.length == 0 && delete handler._d[key]; + } + } + } + }, + + /** + * 比较节点nodeA与节点nodeB是否具有相同的标签名、属性名以及属性值 + * @method isSameElement + * @param { Node } nodeA 需要比较的节点 + * @param { Node } nodeB 需要比较的节点 + * @return { Boolean } 两个节点是否具有相同的标签名、属性名以及属性值 + * @example + * ```html + * ssss + * bbbbb + * ssss + * bbbbb + * + * + * ``` + */ + isSameElement:function (nodeA, nodeB) { + if (nodeA.tagName != nodeB.tagName) { + return false; + } + var thisAttrs = nodeA.attributes, + otherAttrs = nodeB.attributes; + if (!ie && thisAttrs.length != otherAttrs.length) { + return false; + } + var attrA, attrB, al = 0, bl = 0; + for (var i = 0; attrA = thisAttrs[i++];) { + if (attrA.nodeName == 'style') { + if (attrA.specified) { + al++; + } + if (domUtils.isSameStyle(nodeA, nodeB)) { + continue; + } else { + return false; + } + } + if (ie) { + if (attrA.specified) { + al++; + attrB = otherAttrs.getNamedItem(attrA.nodeName); + } else { + continue; + } + } else { + attrB = nodeB.attributes[attrA.nodeName]; + } + if (!attrB.specified || attrA.nodeValue != attrB.nodeValue) { + return false; + } + } + // 有可能attrB的属性包含了attrA的属性之外还有自己的属性 + if (ie) { + for (i = 0; attrB = otherAttrs[i++];) { + if (attrB.specified) { + bl++; + } + } + if (al != bl) { + return false; + } + } + return true; + }, + + /** + * 判断节点nodeA与节点nodeB的元素的style属性是否一致 + * @method isSameStyle + * @param { Node } nodeA 需要比较的节点 + * @param { Node } nodeB 需要比较的节点 + * @return { Boolean } 两个节点是否具有相同的style属性值 + * @example + * ```html + * ssss + * bbbbb + * ssss + * bbbbb + * + * + * ``` + */ + isSameStyle:function (nodeA, nodeB) { + var styleA = nodeA.style.cssText.replace(/( ?; ?)/g, ';').replace(/( ?: ?)/g, ':'), + styleB = nodeB.style.cssText.replace(/( ?; ?)/g, ';').replace(/( ?: ?)/g, ':'); + if (browser.opera) { + styleA = nodeA.style; + styleB = nodeB.style; + if (styleA.length != styleB.length) + return false; + for (var p in styleA) { + if (/^(\d+|csstext)$/i.test(p)) { + continue; + } + if (styleA[p] != styleB[p]) { + return false; + } + } + return true; + } + if (!styleA || !styleB) { + return styleA == styleB; + } + styleA = styleA.split(';'); + styleB = styleB.split(';'); + if (styleA.length != styleB.length) { + return false; + } + for (var i = 0, ci; ci = styleA[i++];) { + if (utils.indexOf(styleB, ci) == -1) { + return false; + } + } + return true; + }, + /** + * 检查节点node是否为block元素 + * @method isBlockElm + * @param { Node } node 需要检测的节点对象 + * @return { Boolean } 是否是block元素节点 + * @warning 该方法的判断规则如下: 如果该元素原本是block元素, 则不论该元素当前的css样式是什么都会返回true; + * 否则,检测该元素的css样式, 如果该元素当前是block元素, 则返回true。 其余情况下都返回false。 + * @example + * ```html + * + * + *
      + * + * + * ``` + */ + isBlockElm:function (node) { + return node.nodeType == 1 && (dtd.$block[node.tagName] || styleBlock[domUtils.getComputedStyle(node, 'display')]) && !dtd.$nonChild[node.tagName]; + }, + /** + * 检测node节点是否为body节点 + * @method isBody + * @param { Element } node 需要检测的dom元素 + * @return { Boolean } 给定的元素是否是body元素 + * @example + * ```javascript + * //output: true + * console.log( UE.dom.domUtils.isBody( document.body ) ); + * ``` + */ + isBody:function (node) { + return node && node.nodeType == 1 && node.tagName.toLowerCase() == 'body'; + }, + /** + * 以node节点为分界,将该节点的指定祖先节点parent拆分成两个独立的节点, + * 拆分形成的两个节点之间是node节点 + * @method breakParent + * @param { Node } node 作为分界的节点对象 + * @param { Node } parent 该节点必须是node节点的祖先节点, 且是block节点。 + * @return { Node } 给定的node分界节点 + * @example + * ```javascript + * + * var node = document.createElement("span"), + * wrapNode = document.createElement( "div" ), + * parent = document.createElement("p"); + * + * parent.appendChild( node ); + * wrapNode.appendChild( parent ); + * + * //拆分前 + * //output:

      + * console.log( wrapNode.innerHTML ); + * + * + * UE.dom.domUtils.breakParent( node, parent ); + * //拆分后 + * //output:

      + * console.log( wrapNode.innerHTML ); + * + * ``` + */ + breakParent:function (node, parent) { + var tmpNode, + parentClone = node, + clone = node, + leftNodes, + rightNodes; + do { + parentClone = parentClone.parentNode; + if (leftNodes) { + tmpNode = parentClone.cloneNode(false); + tmpNode.appendChild(leftNodes); + leftNodes = tmpNode; + tmpNode = parentClone.cloneNode(false); + tmpNode.appendChild(rightNodes); + rightNodes = tmpNode; + } else { + leftNodes = parentClone.cloneNode(false); + rightNodes = leftNodes.cloneNode(false); + } + while (tmpNode = clone.previousSibling) { + leftNodes.insertBefore(tmpNode, leftNodes.firstChild); + } + while (tmpNode = clone.nextSibling) { + rightNodes.appendChild(tmpNode); + } + clone = parentClone; + } while (parent !== parentClone); + tmpNode = parent.parentNode; + tmpNode.insertBefore(leftNodes, parent); + tmpNode.insertBefore(rightNodes, parent); + tmpNode.insertBefore(node, rightNodes); + domUtils.remove(parent); + return node; + }, + /** + * 检查节点node是否是空inline节点 + * @method isEmptyInlineElement + * @param { Node } node 需要检测的节点对象 + * @return { Number } 如果给定的节点是空的inline节点, 则返回1, 否则返回0。 + * @example + * ```html + * => 1 + * => 1 + * => 1 + * xx => 0 + * ``` + */ + isEmptyInlineElement:function (node) { + if (node.nodeType != 1 || !dtd.$removeEmpty[ node.tagName ]) { + return 0; + } + node = node.firstChild; + while (node) { + //如果是创建的bookmark就跳过 + if (domUtils.isBookmarkNode(node)) { + return 0; + } + if (node.nodeType == 1 && !domUtils.isEmptyInlineElement(node) || + node.nodeType == 3 && !domUtils.isWhitespace(node) + ) { + return 0; + } + node = node.nextSibling; + } + return 1; + + }, + + /** + * 删除node节点下首尾两端的空白文本子节点 + * @method trimWhiteTextNode + * @param { Element } node 需要执行删除操作的元素对象 + * @example + * ```javascript + * var node = document.createElement("div"); + * + * node.appendChild( document.createTextNode( "" ) ); + * + * node.appendChild( document.createElement("div") ); + * + * node.appendChild( document.createTextNode( "" ) ); + * + * //3 + * console.log( node.childNodes.length ); + * + * UE.dom.domUtils.trimWhiteTextNode( node ); + * + * //1 + * console.log( node.childNodes.length ); + * ``` + */ + trimWhiteTextNode:function (node) { + function remove(dir) { + var child; + while ((child = node[dir]) && child.nodeType == 3 && domUtils.isWhitespace(child)) { + node.removeChild(child); + } + } + remove('firstChild'); + remove('lastChild'); + }, + + /** + * 合并node节点下相同的子节点 + * @name mergeChild + * @desc + * UE.dom.domUtils.mergeChild(node,tagName) //tagName要合并的子节点的标签 + * @example + *

      xxaaxx

      + * ==> UE.dom.domUtils.mergeChild(node,'span') + *

      xxaaxx

      + */ + mergeChild:function (node, tagName, attrs) { + var list = domUtils.getElementsByTagName(node, node.tagName.toLowerCase()); + for (var i = 0, ci; ci = list[i++];) { + if (!ci.parentNode || domUtils.isBookmarkNode(ci)) { + continue; + } + //span单独处理 + if (ci.tagName.toLowerCase() == 'span') { + if (node === ci.parentNode) { + domUtils.trimWhiteTextNode(node); + if (node.childNodes.length == 1) { + node.style.cssText = ci.style.cssText + ";" + node.style.cssText; + domUtils.remove(ci, true); + continue; + } + } + ci.style.cssText = node.style.cssText + ';' + ci.style.cssText; + if (attrs) { + var style = attrs.style; + if (style) { + style = style.split(';'); + for (var j = 0, s; s = style[j++];) { + ci.style[utils.cssStyleToDomStyle(s.split(':')[0])] = s.split(':')[1]; + } + } + } + if (domUtils.isSameStyle(ci, node)) { + domUtils.remove(ci, true); + } + continue; + } + if (domUtils.isSameElement(node, ci)) { + domUtils.remove(ci, true); + } + } + }, + + /** + * 原生方法getElementsByTagName的封装 + * @method getElementsByTagName + * @param { Node } node 目标节点对象 + * @param { String } tagName 需要查找的节点的tagName, 多个tagName以空格分割 + * @return { Array } 符合条件的节点集合 + */ + getElementsByTagName:function (node, name,filter) { + if(filter && utils.isString(filter)){ + var className = filter; + filter = function(node){return domUtils.hasClass(node,className)} + } + name = utils.trim(name).replace(/[ ]{2,}/g,' ').split(' '); + var arr = []; + for(var n = 0,ni;ni=name[n++];){ + var list = node.getElementsByTagName(ni); + for (var i = 0, ci; ci = list[i++];) { + if(!filter || filter(ci)) + arr.push(ci); + } + } + + return arr; + }, + /** + * 将节点node提取到父节点上 + * @method mergeToParent + * @param { Element } node 需要提取的元素对象 + * @example + * ```html + *
      + *
      + * + *
      + *
      + * + * + * ``` + */ + mergeToParent:function (node) { + var parent = node.parentNode; + while (parent && dtd.$removeEmpty[parent.tagName]) { + if (parent.tagName == node.tagName || parent.tagName == 'A') {//针对a标签单独处理 + domUtils.trimWhiteTextNode(parent); + //span需要特殊处理 不处理这样的情况 xxxxxxxxx + if (parent.tagName == 'SPAN' && !domUtils.isSameStyle(parent, node) + || (parent.tagName == 'A' && node.tagName == 'SPAN')) { + if (parent.childNodes.length > 1 || parent !== node.parentNode) { + node.style.cssText = parent.style.cssText + ";" + node.style.cssText; + parent = parent.parentNode; + continue; + } else { + parent.style.cssText += ";" + node.style.cssText; + //trace:952 a标签要保持下划线 + if (parent.tagName == 'A') { + parent.style.textDecoration = 'underline'; + } + } + } + if (parent.tagName != 'A') { + parent === node.parentNode && domUtils.remove(node, true); + break; + } + } + parent = parent.parentNode; + } + }, + /** + * 合并节点node的左右兄弟节点 + * @method mergeSibling + * @param { Element } node 需要合并的目标节点 + * @example + * ```html + * xxxxoooxxxx + * + * + * ``` + */ + + /** + * 合并节点node的左右兄弟节点, 可以根据给定的条件选择是否忽略合并左节点。 + * @method mergeSibling + * @param { Element } node 需要合并的目标节点 + * @param { Boolean } ignorePre 是否忽略合并左节点 + * @example + * ```html + * xxxxoooxxxx + * + * + * ``` + */ + + /** + * 合并节点node的左右兄弟节点,可以根据给定的条件选择是否忽略合并左右节点。 + * @method mergeSibling + * @param { Element } node 需要合并的目标节点 + * @param { Boolean } ignorePre 是否忽略合并左节点 + * @param { Boolean } ignoreNext 是否忽略合并右节点 + * @remind 如果同时忽略左右节点, 则该操作什么也不会做 + * @example + * ```html + * xxxxoooxxxx + * + * + * ``` + */ + mergeSibling:function (node, ignorePre, ignoreNext) { + function merge(rtl, start, node) { + var next; + if ((next = node[rtl]) && !domUtils.isBookmarkNode(next) && next.nodeType == 1 && domUtils.isSameElement(node, next)) { + while (next.firstChild) { + if (start == 'firstChild') { + node.insertBefore(next.lastChild, node.firstChild); + } else { + node.appendChild(next.firstChild); + } + } + domUtils.remove(next); + } + } + !ignorePre && merge('previousSibling', 'firstChild', node); + !ignoreNext && merge('nextSibling', 'lastChild', node); + }, + + /** + * 设置节点node及其子节点不会被选中 + * @method unSelectable + * @param { Element } node 需要执行操作的dom元素 + * @remind 执行该操作后的节点, 将不能被鼠标选中 + * @example + * ```javascript + * UE.dom.domUtils.unSelectable( document.body ); + * ``` + */ + unSelectable:ie && browser.ie9below || browser.opera ? function (node) { + //for ie9 + node.onselectstart = function () { + return false; + }; + node.onclick = node.onkeyup = node.onkeydown = function () { + return false; + }; + node.unselectable = 'on'; + node.setAttribute("unselectable", "on"); + for (var i = 0, ci; ci = node.all[i++];) { + switch (ci.tagName.toLowerCase()) { + case 'iframe' : + case 'textarea' : + case 'input' : + case 'select' : + break; + default : + ci.unselectable = 'on'; + node.setAttribute("unselectable", "on"); + } + } + } : function (node) { + node.style.MozUserSelect = + node.style.webkitUserSelect = + node.style.msUserSelect = + node.style.KhtmlUserSelect = 'none'; + }, + /** + * 删除节点node上的指定属性名称的属性 + * @method removeAttributes + * @param { Node } node 需要删除属性的节点对象 + * @param { String } attrNames 可以是空格隔开的多个属性名称,该操作将会依次删除相应的属性 + * @example + * ```html + *
      + * xxxxx + *
      + * + * + * ``` + */ + + /** + * 删除节点node上的指定属性名称的属性 + * @method removeAttributes + * @param { Node } node 需要删除属性的节点对象 + * @param { Array } attrNames 需要删除的属性名数组 + * @example + * ```html + *
      + * xxxxx + *
      + * + * + * ``` + */ + removeAttributes:function (node, attrNames) { + attrNames = utils.isArray(attrNames) ? attrNames : utils.trim(attrNames).replace(/[ ]{2,}/g,' ').split(' '); + for (var i = 0, ci; ci = attrNames[i++];) { + ci = attrFix[ci] || ci; + switch (ci) { + case 'className': + node[ci] = ''; + break; + case 'style': + node.style.cssText = ''; + var val = node.getAttributeNode('style'); + !browser.ie && val && node.removeAttributeNode(val); + } + node.removeAttribute(ci); + } + }, + /** + * 在doc下创建一个标签名为tag,属性为attrs的元素 + * @method createElement + * @param { DomDocument } doc 新创建的元素属于该document节点创建 + * @param { String } tagName 需要创建的元素的标签名 + * @param { Object } attrs 新创建的元素的属性key-value集合 + * @return { Element } 新创建的元素对象 + * @example + * ```javascript + * var ele = UE.dom.domUtils.createElement( document, 'div', { + * id: 'test' + * } ); + * + * //output: DIV + * console.log( ele.tagName ); + * + * //output: test + * console.log( ele.id ); + * + * ``` + */ + createElement:function (doc, tag, attrs) { + return domUtils.setAttributes(doc.createElement(tag), attrs) + }, + /** + * 为节点node添加属性attrs,attrs为属性键值对 + * @method setAttributes + * @param { Element } node 需要设置属性的元素对象 + * @param { Object } attrs 需要设置的属性名-值对 + * @return { Element } 设置属性的元素对象 + * @example + * ```html + * + * + * + * + */ + setAttributes:function (node, attrs) { + for (var attr in attrs) { + if(attrs.hasOwnProperty(attr)){ + var value = attrs[attr]; + switch (attr) { + case 'class': + //ie下要这样赋值,setAttribute不起作用 + node.className = value; + break; + case 'style' : + node.style.cssText = node.style.cssText + ";" + value; + break; + case 'innerHTML': + node[attr] = value; + break; + case 'value': + node.value = value; + break; + default: + node.setAttribute(attrFix[attr] || attr, value); + } + } + } + return node; + }, + + /** + * 获取元素element经过计算后的样式值 + * @method getComputedStyle + * @param { Element } element 需要获取样式的元素对象 + * @param { String } styleName 需要获取的样式名 + * @return { String } 获取到的样式值 + * @example + * ```html + * + * + * + * + * + * ``` + */ + getComputedStyle:function (element, styleName) { + //一下的属性单独处理 + var pros = 'width height top left'; + + if(pros.indexOf(styleName) > -1){ + return element['offset' + styleName.replace(/^\w/,function(s){return s.toUpperCase()})] + 'px'; + } + //忽略文本节点 + if (element.nodeType == 3) { + element = element.parentNode; + } + //ie下font-size若body下定义了font-size,则从currentStyle里会取到这个font-size. 取不到实际值,故此修改. + if (browser.ie && browser.version < 9 && styleName == 'font-size' && !element.style.fontSize && + !dtd.$empty[element.tagName] && !dtd.$nonChild[element.tagName]) { + var span = element.ownerDocument.createElement('span'); + span.style.cssText = 'padding:0;border:0;font-family:simsun;'; + span.innerHTML = '.'; + element.appendChild(span); + var result = span.offsetHeight; + element.removeChild(span); + span = null; + return result + 'px'; + } + try { + var value = domUtils.getStyle(element, styleName) || + (window.getComputedStyle ? domUtils.getWindow(element).getComputedStyle(element, '').getPropertyValue(styleName) : + ( element.currentStyle || element.style )[utils.cssStyleToDomStyle(styleName)]); + + } catch (e) { + return ""; + } + return utils.transUnitToPx(utils.fixColor(styleName, value)); + }, + /** + * 删除元素element指定的className + * @method removeClasses + * @param { Element } ele 需要删除class的元素节点 + * @param { String } classNames 需要删除的className, 多个className之间以空格分开 + * @example + * ```html + * xxx + * + * + * ``` + */ + + /** + * 删除元素element指定的className + * @method removeClasses + * @param { Element } ele 需要删除class的元素节点 + * @param { Array } classNames 需要删除的className数组 + * @example + * ```html + * xxx + * + * + * ``` + */ + removeClasses:function (elm, classNames) { + classNames = utils.isArray(classNames) ? classNames : + utils.trim(classNames).replace(/[ ]{2,}/g,' ').split(' '); + for(var i = 0,ci,cls = elm.className;ci=classNames[i++];){ + cls = cls.replace(new RegExp('\\b' + ci + '\\b'),'') + } + cls = utils.trim(cls).replace(/[ ]{2,}/g,' '); + if(cls){ + elm.className = cls; + }else{ + domUtils.removeAttributes(elm,['class']); + } + }, + /** + * 给元素element添加className + * @method addClass + * @param { Node } ele 需要增加className的元素 + * @param { String } classNames 需要添加的className, 多个className之间以空格分割 + * @remind 相同的类名不会被重复添加 + * @example + * ```html + * + * + * + * ``` + */ + + /** + * 判断元素element是否包含给定的样式类名className + * @method hasClass + * @param { Node } ele 需要检测的元素 + * @param { Array } classNames 需要检测的className数组 + * @return { Boolean } 元素是否包含所有给定的className + * @example + * ```html + * + * + * + * ``` + */ + hasClass:function (element, className) { + if(utils.isRegExp(className)){ + return className.test(element.className) + } + className = utils.trim(className).replace(/[ ]{2,}/g,' ').split(' '); + for(var i = 0,ci,cls = element.className;ci=className[i++];){ + if(!new RegExp('\\b' + ci + '\\b','i').test(cls)){ + return false; + } + } + return i - 1 == className.length; + }, + + /** + * 阻止事件默认行为 + * @method preventDefault + * @param { Event } evt 需要阻止默认行为的事件对象 + * @example + * ```javascript + * UE.dom.domUtils.preventDefault( evt ); + * ``` + */ + preventDefault:function (evt) { + evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false); + }, + /** + * 删除元素element指定的样式 + * @method removeStyle + * @param { Element } element 需要删除样式的元素 + * @param { String } styleName 需要删除的样式名 + * @example + * ```html + * + * + * + * ``` + */ + removeStyle:function (element, name) { + if(browser.ie ){ + //针对color先单独处理一下 + if(name == 'color'){ + name = '(^|;)' + name; + } + element.style.cssText = element.style.cssText.replace(new RegExp(name + '[^:]*:[^;]+;?','ig'),'') + }else{ + if (element.style.removeProperty) { + element.style.removeProperty (name); + }else { + element.style.removeAttribute (utils.cssStyleToDomStyle(name)); + } + } + + + if (!element.style.cssText) { + domUtils.removeAttributes(element, ['style']); + } + }, + /** + * 获取元素element的style属性的指定值 + * @method getStyle + * @param { Element } element 需要获取属性值的元素 + * @param { String } styleName 需要获取的style的名称 + * @warning 该方法仅获取元素style属性中所标明的值 + * @return { String } 该元素包含指定的style属性值 + * @example + * ```html + *
      + * + * + * ``` + */ + getStyle:function (element, name) { + var value = element.style[ utils.cssStyleToDomStyle(name) ]; + return utils.fixColor(name, value); + }, + /** + * 为元素element设置样式属性值 + * @method setStyle + * @param { Element } element 需要设置样式的元素 + * @param { String } styleName 样式名 + * @param { String } styleValue 样式值 + * @example + * ```html + *
      + * + * + * ``` + */ + setStyle:function (element, name, value) { + element.style[utils.cssStyleToDomStyle(name)] = value; + if(!utils.trim(element.style.cssText)){ + this.removeAttributes(element,'style') + } + }, + /** + * 为元素element设置多个样式属性值 + * @method setStyles + * @param { Element } element 需要设置样式的元素 + * @param { Object } styles 样式名值对 + * @example + * ```html + *
      + * + * + * ``` + */ + setStyles:function (element, styles) { + for (var name in styles) { + if (styles.hasOwnProperty(name)) { + domUtils.setStyle(element, name, styles[name]); + } + } + }, + /** + * 删除_moz_dirty属性 + * @private + * @method removeDirtyAttr + */ + removeDirtyAttr:function (node) { + for (var i = 0, ci, nodes = node.getElementsByTagName('*'); ci = nodes[i++];) { + ci.removeAttribute('_moz_dirty'); + } + node.removeAttribute('_moz_dirty'); + }, + /** + * 获取子节点的数量 + * @method getChildCount + * @param { Element } node 需要检测的元素 + * @return { Number } 给定的node元素的子节点数量 + * @example + * ```html + *
      + * + *
      + * + * + * ``` + */ + + /** + * 根据给定的过滤规则, 获取符合条件的子节点的数量 + * @method getChildCount + * @param { Element } node 需要检测的元素 + * @param { Function } fn 过滤器, 要求对符合条件的子节点返回true, 反之则要求返回false + * @return { Number } 符合过滤条件的node元素的子节点数量 + * @example + * ```html + *
      + * + *
      + * + * + * ``` + */ + getChildCount:function (node, fn) { + var count = 0, first = node.firstChild; + fn = fn || function () { + return 1; + }; + while (first) { + if (fn(first)) { + count++; + } + first = first.nextSibling; + } + return count; + }, + + /** + * 判断给定节点是否为空节点 + * @method isEmptyNode + * @param { Node } node 需要检测的节点对象 + * @return { Boolean } 节点是否为空 + * @example + * ```javascript + * UE.dom.domUtils.isEmptyNode( document.body ); + * ``` + */ + isEmptyNode:function (node) { + return !node.firstChild || domUtils.getChildCount(node, function (node) { + return !domUtils.isBr(node) && !domUtils.isBookmarkNode(node) && !domUtils.isWhitespace(node) + }) == 0 + }, + clearSelectedArr:function (nodes) { + var node; + while (node = nodes.pop()) { + domUtils.removeAttributes(node, ['class']); + } + }, + /** + * 将显示区域滚动到指定节点的位置 + * @method scrollToView + * @param {Node} node 节点 + * @param {window} win window对象 + * @param {Number} offsetTop 距离上方的偏移量 + */ + scrollToView:function (node, win, offsetTop) { + var getViewPaneSize = function () { + var doc = win.document, + mode = doc.compatMode == 'CSS1Compat'; + return { + width:( mode ? doc.documentElement.clientWidth : doc.body.clientWidth ) || 0, + height:( mode ? doc.documentElement.clientHeight : doc.body.clientHeight ) || 0 + }; + }, + getScrollPosition = function (win) { + if ('pageXOffset' in win) { + return { + x:win.pageXOffset || 0, + y:win.pageYOffset || 0 + }; + } + else { + var doc = win.document; + return { + x:doc.documentElement.scrollLeft || doc.body.scrollLeft || 0, + y:doc.documentElement.scrollTop || doc.body.scrollTop || 0 + }; + } + }; + var winHeight = getViewPaneSize().height, offset = winHeight * -1 + offsetTop; + offset += (node.offsetHeight || 0); + var elementPosition = domUtils.getXY(node); + offset += elementPosition.y; + var currentScroll = getScrollPosition(win).y; + // offset += 50; + if (offset > currentScroll || offset < currentScroll - winHeight) { + win.scrollTo(0, offset + (offset < 0 ? -20 : 20)); + } + }, + /** + * 判断给定节点是否为br + * @method isBr + * @param { Node } node 需要判断的节点对象 + * @return { Boolean } 给定的节点是否是br节点 + */ + isBr:function (node) { + return node.nodeType == 1 && node.tagName == 'BR'; + }, + /** + * 判断给定的节点是否是一个“填充”节点 + * @private + * @method isFillChar + * @param { Node } node 需要判断的节点 + * @param { Boolean } isInStart 是否从节点内容的开始位置匹配 + * @returns { Boolean } 节点是否是填充节点 + */ + isFillChar:function (node,isInStart) { + if(node.nodeType != 3) + return false; + var text = node.nodeValue; + if(isInStart){ + return new RegExp('^' + domUtils.fillChar).test(text) + } + return !text.replace(new RegExp(domUtils.fillChar,'g'), '').length + }, + isStartInblock:function (range) { + var tmpRange = range.cloneRange(), + flag = 0, + start = tmpRange.startContainer, + tmp; + if(start.nodeType == 1 && start.childNodes[tmpRange.startOffset]){ + start = start.childNodes[tmpRange.startOffset]; + var pre = start.previousSibling; + while(pre && domUtils.isFillChar(pre)){ + start = pre; + pre = pre.previousSibling; + } + } + if(this.isFillChar(start,true) && tmpRange.startOffset == 1){ + tmpRange.setStartBefore(start); + start = tmpRange.startContainer; + } + + while (start && domUtils.isFillChar(start)) { + tmp = start; + start = start.previousSibling + } + if (tmp) { + tmpRange.setStartBefore(tmp); + start = tmpRange.startContainer; + } + if (start.nodeType == 1 && domUtils.isEmptyNode(start) && tmpRange.startOffset == 1) { + tmpRange.setStart(start, 0).collapse(true); + } + while (!tmpRange.startOffset) { + start = tmpRange.startContainer; + if (domUtils.isBlockElm(start) || domUtils.isBody(start)) { + flag = 1; + break; + } + var pre = tmpRange.startContainer.previousSibling, + tmpNode; + if (!pre) { + tmpRange.setStartBefore(tmpRange.startContainer); + } else { + while (pre && domUtils.isFillChar(pre)) { + tmpNode = pre; + pre = pre.previousSibling; + } + if (tmpNode) { + tmpRange.setStartBefore(tmpNode); + } else { + tmpRange.setStartBefore(tmpRange.startContainer); + } + } + } + return flag && !domUtils.isBody(tmpRange.startContainer) ? 1 : 0; + }, + + /** + * 判断给定的元素是否是一个空元素 + * @method isEmptyBlock + * @param { Element } node 需要判断的元素 + * @return { Boolean } 是否是空元素 + * @example + * ```html + *
      + * + * + * ``` + */ + + /** + * 根据指定的判断规则判断给定的元素是否是一个空元素 + * @method isEmptyBlock + * @param { Element } node 需要判断的元素 + * @param { RegExp } reg 对内容执行判断的正则表达式对象 + * @return { Boolean } 是否是空元素 + */ + isEmptyBlock:function (node,reg) { + if(node.nodeType != 1) + return 0; + reg = reg || new RegExp('[ \xa0\t\r\n' + domUtils.fillChar + ']', 'g'); + + if (node[browser.ie ? 'innerText' : 'textContent'].replace(reg, '').length > 0) { + return 0; + } + for (var n in dtd.$isNotEmpty) { + if (node.getElementsByTagName(n).length) { + return 0; + } + } + return 1; + }, + + /** + * 移动元素使得该元素的位置移动指定的偏移量的距离 + * @method setViewportOffset + * @param { Element } element 需要设置偏移量的元素 + * @param { Object } offset 偏移量, 形如{ left: 100, top: 50 }的一个键值对, 表示该元素将在 + * 现有的位置上向水平方向偏移offset.left的距离, 在竖直方向上偏移 + * offset.top的距离 + * @example + * ```html + *
      + * + * + * ``` + */ + setViewportOffset:function (element, offset) { + var left = parseInt(element.style.left) | 0; + var top = parseInt(element.style.top) | 0; + var rect = element.getBoundingClientRect(); + var offsetLeft = offset.left - rect.left; + var offsetTop = offset.top - rect.top; + if (offsetLeft) { + element.style.left = left + offsetLeft + 'px'; + } + if (offsetTop) { + element.style.top = top + offsetTop + 'px'; + } + }, + + /** + * 用“填充字符”填充节点 + * @method fillNode + * @private + * @param { DomDocument } doc 填充的节点所在的docment对象 + * @param { Node } node 需要填充的节点对象 + * @example + * ```html + *
      + * + * + * ``` + */ + fillNode:function (doc, node) { + var tmpNode = browser.ie ? doc.createTextNode(domUtils.fillChar) : doc.createElement('br'); + node.innerHTML = ''; + node.appendChild(tmpNode); + }, + + /** + * 把节点src的所有子节点追加到另一个节点tag上去 + * @method moveChild + * @param { Node } src 源节点, 该节点下的所有子节点将被移除 + * @param { Node } tag 目标节点, 从源节点移除的子节点将被追加到该节点下 + * @example + * ```html + *
      + * + *
      + *
      + *
      + *
      + * + * + * ``` + */ + + /** + * 把节点src的所有子节点移动到另一个节点tag上去, 可以通过dir参数控制附加的行为是“追加”还是“插入顶部” + * @method moveChild + * @param { Node } src 源节点, 该节点下的所有子节点将被移除 + * @param { Node } tag 目标节点, 从源节点移除的子节点将被附加到该节点下 + * @param { Boolean } dir 附加方式, 如果为true, 则附加进去的节点将被放到目标节点的顶部, 反之,则放到末尾 + * @example + * ```html + *
      + * + *
      + *
      + *
      + *
      + * + * + * ``` + */ + moveChild:function (src, tag, dir) { + while (src.firstChild) { + if (dir && tag.firstChild) { + tag.insertBefore(src.lastChild, tag.firstChild); + } else { + tag.appendChild(src.firstChild); + } + } + }, + + /** + * 判断节点的标签上是否不存在任何属性 + * @method hasNoAttributes + * @private + * @param { Node } node 需要检测的节点对象 + * @return { Boolean } 节点是否不包含任何属性 + * @example + * ```html + *
      xxxx
      + * + * + * ``` + */ + hasNoAttributes:function (node) { + return browser.ie ? /^<\w+\s*?>/.test(node.outerHTML) : node.attributes.length == 0; + }, + + /** + * 检测节点是否是UEditor所使用的辅助节点 + * @method isCustomeNode + * @private + * @param { Node } node 需要检测的节点 + * @remind 辅助节点是指编辑器要完成工作临时添加的节点, 在输出的时候将会从编辑器内移除, 不会影响最终的结果。 + * @return { Boolean } 给定的节点是否是一个辅助节点 + */ + isCustomeNode:function (node) { + return node.nodeType == 1 && node.getAttribute('_ue_custom_node_'); + }, + + /** + * 检测节点的标签是否是给定的标签 + * @method isTagNode + * @param { Node } node 需要检测的节点对象 + * @param { String } tagName 标签 + * @return { Boolean } 节点的标签是否是给定的标签 + * @example + * ```html + *
      + * + * + * ``` + */ + isTagNode:function (node, tagNames) { + return node.nodeType == 1 && new RegExp('\\b' + node.tagName + '\\b','i').test(tagNames) + }, + + /** + * 给定一个节点数组,在通过指定的过滤器过滤后, 获取其中满足过滤条件的第一个节点 + * @method filterNodeList + * @param { Array } nodeList 需要过滤的节点数组 + * @param { Function } fn 过滤器, 对符合条件的节点, 执行结果返回true, 反之则返回false + * @return { Node | NULL } 如果找到符合过滤条件的节点, 则返回该节点, 否则返回NULL + * @example + * ```javascript + * var divNodes = document.getElementsByTagName("div"); + * divNodes = [].slice.call( divNodes, 0 ); + * + * //output: null + * console.log( UE.dom.domUtils.filterNodeList( divNodes, function ( node ) { + * return node.tagName.toLowerCase() !== 'div'; + * } ) ); + * ``` + */ + + /** + * 给定一个节点数组nodeList和一组标签名tagNames, 获取其中能够匹配标签名的节点集合中的第一个节点 + * @method filterNodeList + * @param { Array } nodeList 需要过滤的节点数组 + * @param { String } tagNames 需要匹配的标签名, 多个标签名之间用空格分割 + * @return { Node | NULL } 如果找到标签名匹配的节点, 则返回该节点, 否则返回NULL + * @example + * ```javascript + * var divNodes = document.getElementsByTagName("div"); + * divNodes = [].slice.call( divNodes, 0 ); + * + * //output: null + * console.log( UE.dom.domUtils.filterNodeList( divNodes, 'a span' ) ); + * ``` + */ + + /** + * 给定一个节点数组,在通过指定的过滤器过滤后, 如果参数forAll为true, 则会返回所有满足过滤 + * 条件的节点集合, 否则, 返回满足条件的节点集合中的第一个节点 + * @method filterNodeList + * @param { Array } nodeList 需要过滤的节点数组 + * @param { Function } fn 过滤器, 对符合条件的节点, 执行结果返回true, 反之则返回false + * @param { Boolean } forAll 是否返回整个节点数组, 如果该参数为false, 则返回节点集合中的第一个节点 + * @return { Array | Node | NULL } 如果找到符合过滤条件的节点, 则根据参数forAll的值决定返回满足 + * 过滤条件的节点数组或第一个节点, 否则返回NULL + * @example + * ```javascript + * var divNodes = document.getElementsByTagName("div"); + * divNodes = [].slice.call( divNodes, 0 ); + * + * //output: 3(假定有3个div) + * console.log( divNodes.length ); + * + * var nodes = UE.dom.domUtils.filterNodeList( divNodes, function ( node ) { + * return node.tagName.toLowerCase() === 'div'; + * }, true ); + * + * //output: 3 + * console.log( nodes.length ); + * + * var node = UE.dom.domUtils.filterNodeList( divNodes, function ( node ) { + * return node.tagName.toLowerCase() === 'div'; + * }, false ); + * + * //output: div + * console.log( node.nodeName ); + * ``` + */ + filterNodeList : function(nodelist,filter,forAll){ + var results = []; + if(!utils .isFunction(filter)){ + var str = filter; + filter = function(n){ + return utils.indexOf(utils.isArray(str) ? str:str.split(' '), n.tagName.toLowerCase()) != -1 + }; + } + utils.each(nodelist,function(n){ + filter(n) && results.push(n) + }); + return results.length == 0 ? null : results.length == 1 || !forAll ? results[0] : results + }, + + /** + * 查询给定的range选区是否在给定的node节点内,且在该节点的最末尾 + * @method isInNodeEndBoundary + * @param { UE.dom.Range } rng 需要判断的range对象, 该对象的startContainer不能为NULL + * @param node 需要检测的节点对象 + * @return { Number } 如果给定的选取range对象是在node内部的最末端, 则返回1, 否则返回0 + */ + isInNodeEndBoundary : function (rng,node){ + var start = rng.startContainer; + if(start.nodeType == 3 && rng.startOffset != start.nodeValue.length){ + return 0; + } + if(start.nodeType == 1 && rng.startOffset != start.childNodes.length){ + return 0; + } + while(start !== node){ + if(start.nextSibling){ + return 0 + }; + start = start.parentNode; + } + return 1; + }, + isBoundaryNode : function (node,dir){ + var tmp; + while(!domUtils.isBody(node)){ + tmp = node; + node = node.parentNode; + if(tmp !== node[dir]){ + return false; + } + } + return true; + }, + fillHtml : browser.ie11below ? ' ' : '
      ' +}; +var fillCharReg = new RegExp(domUtils.fillChar, 'g'); + +// core/Range.js +/** + * Range封装 + * @file + * @module UE.dom + * @class Range + * @since 1.2.6.1 + */ + +/** + * dom操作封装 + * @unfile + * @module UE.dom + */ + +/** + * Range实现类,本类是UEditor底层核心类,封装不同浏览器之间的Range操作。 + * @unfile + * @module UE.dom + * @class Range + */ + + +(function () { + var guid = 0, + fillChar = domUtils.fillChar, + fillData; + + /** + * 更新range的collapse状态 + * @param {Range} range range对象 + */ + function updateCollapse(range) { + range.collapsed = + range.startContainer && range.endContainer && + range.startContainer === range.endContainer && + range.startOffset == range.endOffset; + } + + function selectOneNode(rng){ + return !rng.collapsed && rng.startContainer.nodeType == 1 && rng.startContainer === rng.endContainer && rng.endOffset - rng.startOffset == 1 + } + function setEndPoint(toStart, node, offset, range) { + //如果node是自闭合标签要处理 + if (node.nodeType == 1 && (dtd.$empty[node.tagName] || dtd.$nonChild[node.tagName])) { + offset = domUtils.getNodeIndex(node) + (toStart ? 0 : 1); + node = node.parentNode; + } + if (toStart) { + range.startContainer = node; + range.startOffset = offset; + if (!range.endContainer) { + range.collapse(true); + } + } else { + range.endContainer = node; + range.endOffset = offset; + if (!range.startContainer) { + range.collapse(false); + } + } + updateCollapse(range); + return range; + } + + function execContentsAction(range, action) { + //调整边界 + //range.includeBookmark(); + var start = range.startContainer, + end = range.endContainer, + startOffset = range.startOffset, + endOffset = range.endOffset, + doc = range.document, + frag = doc.createDocumentFragment(), + tmpStart, tmpEnd; + if (start.nodeType == 1) { + start = start.childNodes[startOffset] || (tmpStart = start.appendChild(doc.createTextNode(''))); + } + if (end.nodeType == 1) { + end = end.childNodes[endOffset] || (tmpEnd = end.appendChild(doc.createTextNode(''))); + } + if (start === end && start.nodeType == 3) { + frag.appendChild(doc.createTextNode(start.substringData(startOffset, endOffset - startOffset))); + //is not clone + if (action) { + start.deleteData(startOffset, endOffset - startOffset); + range.collapse(true); + } + return frag; + } + var current, currentLevel, clone = frag, + startParents = domUtils.findParents(start, true), endParents = domUtils.findParents(end, true); + for (var i = 0; startParents[i] == endParents[i];) { + i++; + } + for (var j = i, si; si = startParents[j]; j++) { + current = si.nextSibling; + if (si == start) { + if (!tmpStart) { + if (range.startContainer.nodeType == 3) { + clone.appendChild(doc.createTextNode(start.nodeValue.slice(startOffset))); + //is not clone + if (action) { + start.deleteData(startOffset, start.nodeValue.length - startOffset); + } + } else { + clone.appendChild(!action ? start.cloneNode(true) : start); + } + } + } else { + currentLevel = si.cloneNode(false); + clone.appendChild(currentLevel); + } + while (current) { + if (current === end || current === endParents[j]) { + break; + } + si = current.nextSibling; + clone.appendChild(!action ? current.cloneNode(true) : current); + current = si; + } + clone = currentLevel; + } + clone = frag; + if (!startParents[i]) { + clone.appendChild(startParents[i - 1].cloneNode(false)); + clone = clone.firstChild; + } + for (var j = i, ei; ei = endParents[j]; j++) { + current = ei.previousSibling; + if (ei == end) { + if (!tmpEnd && range.endContainer.nodeType == 3) { + clone.appendChild(doc.createTextNode(end.substringData(0, endOffset))); + //is not clone + if (action) { + end.deleteData(0, endOffset); + } + } + } else { + currentLevel = ei.cloneNode(false); + clone.appendChild(currentLevel); + } + //如果两端同级,右边第一次已经被开始做了 + if (j != i || !startParents[i]) { + while (current) { + if (current === start) { + break; + } + ei = current.previousSibling; + clone.insertBefore(!action ? current.cloneNode(true) : current, clone.firstChild); + current = ei; + } + } + clone = currentLevel; + } + if (action) { + range.setStartBefore(!endParents[i] ? endParents[i - 1] : !startParents[i] ? startParents[i - 1] : endParents[i]).collapse(true); + } + tmpStart && domUtils.remove(tmpStart); + tmpEnd && domUtils.remove(tmpEnd); + return frag; + } + + /** + * 创建一个跟document绑定的空的Range实例 + * @constructor + * @param { Document } document 新建的选区所属的文档对象 + */ + + /** + * @property { Node } startContainer 当前Range的开始边界的容器节点, 可以是一个元素节点或者是文本节点 + */ + + /** + * @property { Node } startOffset 当前Range的开始边界容器节点的偏移量, 如果是元素节点, + * 该值就是childNodes中的第几个节点, 如果是文本节点就是文本内容的第几个字符 + */ + + /** + * @property { Node } endContainer 当前Range的结束边界的容器节点, 可以是一个元素节点或者是文本节点 + */ + + /** + * @property { Node } endOffset 当前Range的结束边界容器节点的偏移量, 如果是元素节点, + * 该值就是childNodes中的第几个节点, 如果是文本节点就是文本内容的第几个字符 + */ + + /** + * @property { Boolean } collapsed 当前Range是否闭合 + * @default true + * @remind Range是闭合的时候, startContainer === endContainer && startOffset === endOffset + */ + + /** + * @property { Document } document 当前Range所属的Document对象 + * @remind 不同range的的document属性可以是不同的 + */ + var Range = dom.Range = function (document) { + var me = this; + me.startContainer = + me.startOffset = + me.endContainer = + me.endOffset = null; + me.document = document; + me.collapsed = true; + }; + + /** + * 删除fillData + * @param doc + * @param excludeNode + */ + function removeFillData(doc, excludeNode) { + try { + if (fillData && domUtils.inDoc(fillData, doc)) { + if (!fillData.nodeValue.replace(fillCharReg, '').length) { + var tmpNode = fillData.parentNode; + domUtils.remove(fillData); + while (tmpNode && domUtils.isEmptyInlineElement(tmpNode) && + //safari的contains有bug + (browser.safari ? !(domUtils.getPosition(tmpNode,excludeNode) & domUtils.POSITION_CONTAINS) : !tmpNode.contains(excludeNode)) + ) { + fillData = tmpNode.parentNode; + domUtils.remove(tmpNode); + tmpNode = fillData; + } + } else { + fillData.nodeValue = fillData.nodeValue.replace(fillCharReg, ''); + } + } + } catch (e) { + } + } + + /** + * @param node + * @param dir + */ + function mergeSibling(node, dir) { + var tmpNode; + node = node[dir]; + while (node && domUtils.isFillChar(node)) { + tmpNode = node[dir]; + domUtils.remove(node); + node = tmpNode; + } + } + + Range.prototype = { + + /** + * 克隆选区的内容到一个DocumentFragment里 + * @method cloneContents + * @return { DocumentFragment | NULL } 如果选区是闭合的将返回null, 否则, 返回包含所clone内容的DocumentFragment元素 + * @example + * ```html + * + * + * xx[xxx]x + * + * + * + * ``` + */ + cloneContents:function () { + return this.collapsed ? null : execContentsAction(this, 0); + }, + + /** + * 删除当前选区范围中的所有内容 + * @method deleteContents + * @remind 执行完该操作后, 当前Range对象变成了闭合状态 + * @return { UE.dom.Range } 当前操作的Range对象 + * @example + * ```html + * + * + * xx[xxx]x + * + * + * + * ``` + */ + deleteContents:function () { + var txt; + if (!this.collapsed) { + execContentsAction(this, 1); + } + if (browser.webkit) { + txt = this.startContainer; + if (txt.nodeType == 3 && !txt.nodeValue.length) { + this.setStartBefore(txt).collapse(true); + domUtils.remove(txt); + } + } + return this; + }, + + /** + * 将当前选区的内容提取到一个DocumentFragment里 + * @method extractContents + * @remind 执行该操作后, 选区将变成闭合状态 + * @warning 执行该操作后, 原来选区所选中的内容将从dom树上剥离出来 + * @return { DocumentFragment } 返回包含所提取内容的DocumentFragment对象 + * @example + * ```html + * + * + * xx[xxx]x + * + * + * + */ + extractContents:function () { + return this.collapsed ? null : execContentsAction(this, 2); + }, + + /** + * 设置Range的开始容器节点和偏移量 + * @method setStart + * @remind 如果给定的节点是元素节点,那么offset指的是其子元素中索引为offset的元素, + * 如果是文本节点,那么offset指的是其文本内容的第offset个字符 + * @remind 如果提供的容器节点是一个不能包含子元素的节点, 则该选区的开始容器将被设置 + * 为该节点的父节点, 此时, 其距离开始容器的偏移量也变成了该节点在其父节点 + * 中的索引 + * @param { Node } node 将被设为当前选区开始边界容器的节点对象 + * @param { int } offset 选区的开始位置偏移量 + * @return { UE.dom.Range } 当前range对象 + * @example + * ```html + * + * xxxxxxxxxxxxx[xxx] + * + * + * ``` + * @example + * ```html + * + * xxx[xx]x + * + * + * ``` + */ + setStart:function (node, offset) { + return setEndPoint(true, node, offset, this); + }, + + /** + * 设置Range的结束容器和偏移量 + * @method setEnd + * @param { Node } node 作为当前选区结束边界容器的节点对象 + * @param { int } offset 结束边界的偏移量 + * @see UE.dom.Range:setStart(Node,int) + * @return { UE.dom.Range } 当前range对象 + */ + setEnd:function (node, offset) { + return setEndPoint(false, node, offset, this); + }, + + /** + * 将Range开始位置设置到node节点之后 + * @method setStartAfter + * @remind 该操作将会把给定节点的父节点作为range的开始容器, 且偏移量是该节点在其父节点中的位置索引+1 + * @param { Node } node 选区的开始边界将紧接着该节点之后 + * @return { UE.dom.Range } 当前range对象 + * @example + * ```html + * + * xxxxxxx[xxxx] + * + * + * ``` + */ + setStartAfter:function (node) { + return this.setStart(node.parentNode, domUtils.getNodeIndex(node) + 1); + }, + + /** + * 将Range开始位置设置到node节点之前 + * @method setStartBefore + * @remind 该操作将会把给定节点的父节点作为range的开始容器, 且偏移量是该节点在其父节点中的位置索引 + * @param { Node } node 新的选区开始位置在该节点之前 + * @see UE.dom.Range:setStartAfter(Node) + * @return { UE.dom.Range } 当前range对象 + */ + setStartBefore:function (node) { + return this.setStart(node.parentNode, domUtils.getNodeIndex(node)); + }, + + /** + * 将Range结束位置设置到node节点之后 + * @method setEndAfter + * @remind 该操作将会把给定节点的父节点作为range的结束容器, 且偏移量是该节点在其父节点中的位置索引+1 + * @param { Node } node 目标节点 + * @see UE.dom.Range:setStartAfter(Node) + * @return { UE.dom.Range } 当前range对象 + * @example + * ```html + * + * [xxxxxxx]xxxx + * + * + * ``` + */ + setEndAfter:function (node) { + return this.setEnd(node.parentNode, domUtils.getNodeIndex(node) + 1); + }, + + /** + * 将Range结束位置设置到node节点之前 + * @method setEndBefore + * @remind 该操作将会把给定节点的父节点作为range的结束容器, 且偏移量是该节点在其父节点中的位置索引 + * @param { Node } node 目标节点 + * @see UE.dom.Range:setEndAfter(Node) + * @return { UE.dom.Range } 当前range对象 + */ + setEndBefore:function (node) { + return this.setEnd(node.parentNode, domUtils.getNodeIndex(node)); + }, + + /** + * 设置Range的开始位置到node节点内的第一个子节点之前 + * @method setStartAtFirst + * @remind 选区的开始容器将变成给定的节点, 且偏移量为0 + * @remind 如果给定的节点是元素节点, 则该节点必须是允许包含子节点的元素。 + * @param { Node } node 目标节点 + * @see UE.dom.Range:setStartBefore(Node) + * @return { UE.dom.Range } 当前range对象 + * @example + * ```html + * + * xxxxx[xx]xxxx + * + * + * ``` + */ + setStartAtFirst:function (node) { + return this.setStart(node, 0); + }, + + /** + * 设置Range的开始位置到node节点内的最后一个节点之后 + * @method setStartAtLast + * @remind 选区的开始容器将变成给定的节点, 且偏移量为该节点的子节点数 + * @remind 如果给定的节点是元素节点, 则该节点必须是允许包含子节点的元素。 + * @param { Node } node 目标节点 + * @see UE.dom.Range:setStartAtFirst(Node) + * @return { UE.dom.Range } 当前range对象 + */ + setStartAtLast:function (node) { + return this.setStart(node, node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length); + }, + + /** + * 设置Range的结束位置到node节点内的第一个节点之前 + * @method setEndAtFirst + * @param { Node } node 目标节点 + * @remind 选区的结束容器将变成给定的节点, 且偏移量为0 + * @remind node必须是一个元素节点, 且必须是允许包含子节点的元素。 + * @see UE.dom.Range:setStartAtFirst(Node) + * @return { UE.dom.Range } 当前range对象 + */ + setEndAtFirst:function (node) { + return this.setEnd(node, 0); + }, + + /** + * 设置Range的结束位置到node节点内的最后一个节点之后 + * @method setEndAtLast + * @param { Node } node 目标节点 + * @remind 选区的结束容器将变成给定的节点, 且偏移量为该节点的子节点数量 + * @remind node必须是一个元素节点, 且必须是允许包含子节点的元素。 + * @see UE.dom.Range:setStartAtFirst(Node) + * @return { UE.dom.Range } 当前range对象 + */ + setEndAtLast:function (node) { + return this.setEnd(node, node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length); + }, + + /** + * 选中给定节点 + * @method selectNode + * @remind 此时, 选区的开始容器和结束容器都是该节点的父节点, 其startOffset是该节点在父节点中的位置索引, + * 而endOffset为startOffset+1 + * @param { Node } node 需要选中的节点 + * @return { UE.dom.Range } 当前range对象,此时的range仅包含当前给定的节点对象 + * @example + * ```html + * + * xxxxx[xx]xxxx + * + * + * ``` + */ + selectNode:function (node) { + return this.setStartBefore(node).setEndAfter(node); + }, + + /** + * 选中给定节点内部的所有节点 + * @method selectNodeContents + * @remind 此时, 选区的开始容器和结束容器都是该节点, 其startOffset为0, + * 而endOffset是该节点的子节点数。 + * @param { Node } node 目标节点, 当前range将包含该节点内的所有节点 + * @return { UE.dom.Range } 当前range对象, 此时range仅包含给定节点的所有子节点 + * @example + * ```html + * + * xxxxx[xx]xxxx + * + * + * ``` + */ + selectNodeContents:function (node) { + return this.setStart(node, 0).setEndAtLast(node); + }, + + /** + * clone当前Range对象 + * @method cloneRange + * @remind 返回的range是一个全新的range对象, 其内部所有属性与当前被clone的range相同。 + * @return { UE.dom.Range } 当前range对象的一个副本 + */ + cloneRange:function () { + var me = this; + return new Range(me.document).setStart(me.startContainer, me.startOffset).setEnd(me.endContainer, me.endOffset); + + }, + + /** + * 向当前选区的结束处闭合选区 + * @method collapse + * @return { UE.dom.Range } 当前range对象 + * @example + * ```html + * + * xxxxx[xx]xxxx + * + * + * ``` + */ + + /** + * 闭合当前选区,根据给定的toStart参数项决定是向当前选区开始处闭合还是向结束处闭合, + * 如果toStart的值为true,则向开始位置闭合, 反之,向结束位置闭合。 + * @method collapse + * @param { Boolean } toStart 是否向选区开始处闭合 + * @return { UE.dom.Range } 当前range对象,此时range对象处于闭合状态 + * @see UE.dom.Range:collapse() + * @example + * ```html + * + * xxxxx[xx]xxxx + * + * + * ``` + */ + collapse:function (toStart) { + var me = this; + if (toStart) { + me.endContainer = me.startContainer; + me.endOffset = me.startOffset; + } else { + me.startContainer = me.endContainer; + me.startOffset = me.endOffset; + } + me.collapsed = true; + return me; + }, + + /** + * 调整range的开始位置和结束位置,使其"收缩"到最小的位置 + * @method shrinkBoundary + * @return { UE.dom.Range } 当前range对象 + * @example + * ```html + * xxxx[xxxxx] => xxxx[xxxxx] + * ``` + * + * @example + * ```html + * + * x[xx]xxx + * + * + * ``` + * + * @example + * ```html + * [xxxxxxxxxxx] => [xxxxxxxxxxx] + * ``` + */ + + /** + * 调整range的开始位置和结束位置,使其"收缩"到最小的位置, + * 如果ignoreEnd的值为true,则忽略对结束位置的调整 + * @method shrinkBoundary + * @param { Boolean } ignoreEnd 是否忽略对结束位置的调整 + * @return { UE.dom.Range } 当前range对象 + * @see UE.dom.domUtils.Range:shrinkBoundary() + */ + shrinkBoundary:function (ignoreEnd) { + var me = this, child, + collapsed = me.collapsed; + function check(node){ + return node.nodeType == 1 && !domUtils.isBookmarkNode(node) && !dtd.$empty[node.tagName] && !dtd.$nonChild[node.tagName] + } + while (me.startContainer.nodeType == 1 //是element + && (child = me.startContainer.childNodes[me.startOffset]) //子节点也是element + && check(child)) { + me.setStart(child, 0); + } + if (collapsed) { + return me.collapse(true); + } + if (!ignoreEnd) { + while (me.endContainer.nodeType == 1//是element + && me.endOffset > 0 //如果是空元素就退出 endOffset=0那么endOffst-1为负值,childNodes[endOffset]报错 + && (child = me.endContainer.childNodes[me.endOffset - 1]) //子节点也是element + && check(child)) { + me.setEnd(child, child.childNodes.length); + } + } + return me; + }, + + /** + * 获取离当前选区内包含的所有节点最近的公共祖先节点, + * @method getCommonAncestor + * @remind 返回的公共祖先节点一定不是range自身的容器节点, 但有可能是一个文本节点 + * @return { Node } 当前range对象内所有节点的公共祖先节点 + * @example + * ```html + * //选区示例 + * xxxx[xxx]xxxxxx + * + * ``` + */ + + /** + * 获取当前选区所包含的所有节点的公共祖先节点, 可以根据给定的参数 includeSelf 决定获取到 + * 的公共祖先节点是否可以是当前选区的startContainer或endContainer节点, 如果 includeSelf + * 的取值为true, 则返回的节点可以是自身的容器节点, 否则, 则不能是容器节点 + * @method getCommonAncestor + * @param { Boolean } includeSelf 是否允许获取到的公共祖先节点是当前range对象的容器节点 + * @return { Node } 当前range对象内所有节点的公共祖先节点 + * @see UE.dom.Range:getCommonAncestor() + * @example + * ```html + * + * + * + * xxxxxxxxx[xxx]xxxxxxxx + * + * + * + * + * ``` + */ + + /** + * 获取当前选区所包含的所有节点的公共祖先节点, 可以根据给定的参数 includeSelf 决定获取到 + * 的公共祖先节点是否可以是当前选区的startContainer或endContainer节点, 如果 includeSelf + * 的取值为true, 则返回的节点可以是自身的容器节点, 否则, 则不能是容器节点; 同时可以根据 + * ignoreTextNode 参数的取值决定是否忽略类型为文本节点的祖先节点。 + * @method getCommonAncestor + * @param { Boolean } includeSelf 是否允许获取到的公共祖先节点是当前range对象的容器节点 + * @param { Boolean } ignoreTextNode 获取祖先节点的过程中是否忽略类型为文本节点的祖先节点 + * @return { Node } 当前range对象内所有节点的公共祖先节点 + * @see UE.dom.Range:getCommonAncestor() + * @see UE.dom.Range:getCommonAncestor(Boolean) + * @example + * ```html + * + * + * + * xxxxxxxx[x]xxxxxxxxxxx + * + * + * + * + * ``` + */ + getCommonAncestor:function (includeSelf, ignoreTextNode) { + var me = this, + start = me.startContainer, + end = me.endContainer; + if (start === end) { + if (includeSelf && selectOneNode(this)) { + start = start.childNodes[me.startOffset]; + if(start.nodeType == 1) + return start; + } + //只有在上来就相等的情况下才会出现是文本的情况 + return ignoreTextNode && start.nodeType == 3 ? start.parentNode : start; + } + return domUtils.getCommonAncestor(start, end); + }, + + /** + * 调整当前Range的开始和结束边界容器,如果是容器节点是文本节点,就调整到包含该文本节点的父节点上 + * @method trimBoundary + * @remind 该操作有可能会引起文本节点被切开 + * @return { UE.dom.Range } 当前range对象 + * @example + * ```html + * + * //选区示例 + * xxx[xxxxx]xxx + * + * + * ``` + */ + + /** + * 调整当前Range的开始和结束边界容器,如果是容器节点是文本节点,就调整到包含该文本节点的父节点上, + * 可以根据 ignoreEnd 参数的值决定是否调整对结束边界的调整 + * @method trimBoundary + * @param { Boolean } ignoreEnd 是否忽略对结束边界的调整 + * @return { UE.dom.Range } 当前range对象 + * @example + * ```html + * + * //选区示例 + * xxx[xxxxx]xxx + * + * + * ``` + */ + trimBoundary:function (ignoreEnd) { + this.txtToElmBoundary(); + var start = this.startContainer, + offset = this.startOffset, + collapsed = this.collapsed, + end = this.endContainer; + if (start.nodeType == 3) { + if (offset == 0) { + this.setStartBefore(start); + } else { + if (offset >= start.nodeValue.length) { + this.setStartAfter(start); + } else { + var textNode = domUtils.split(start, offset); + //跟新结束边界 + if (start === end) { + this.setEnd(textNode, this.endOffset - offset); + } else if (start.parentNode === end) { + this.endOffset += 1; + } + this.setStartBefore(textNode); + } + } + if (collapsed) { + return this.collapse(true); + } + } + if (!ignoreEnd) { + offset = this.endOffset; + end = this.endContainer; + if (end.nodeType == 3) { + if (offset == 0) { + this.setEndBefore(end); + } else { + offset < end.nodeValue.length && domUtils.split(end, offset); + this.setEndAfter(end); + } + } + } + return this; + }, + + /** + * 如果选区在文本的边界上,就扩展选区到文本的父节点上, 如果当前选区是闭合的, 则什么也不做 + * @method txtToElmBoundary + * @remind 该操作不会修改dom节点 + * @return { UE.dom.Range } 当前range对象 + */ + + /** + * 如果选区在文本的边界上,就扩展选区到文本的父节点上, 如果当前选区是闭合的, 则根据参数项 + * ignoreCollapsed 的值决定是否执行该调整 + * @method txtToElmBoundary + * @param { Boolean } ignoreCollapsed 是否忽略选区的闭合状态, 如果该参数取值为true, 则 + * 不论选区是否闭合, 都会执行该操作, 反之, 则不会对闭合的选区执行该操作 + * @return { UE.dom.Range } 当前range对象 + */ + txtToElmBoundary:function (ignoreCollapsed) { + function adjust(r, c) { + var container = r[c + 'Container'], + offset = r[c + 'Offset']; + if (container.nodeType == 3) { + if (!offset) { + r['set' + c.replace(/(\w)/, function (a) { + return a.toUpperCase(); + }) + 'Before'](container); + } else if (offset >= container.nodeValue.length) { + r['set' + c.replace(/(\w)/, function (a) { + return a.toUpperCase(); + }) + 'After' ](container); + } + } + } + + if (ignoreCollapsed || !this.collapsed) { + adjust(this, 'start'); + adjust(this, 'end'); + } + return this; + }, + + /** + * 在当前选区的开始位置前插入节点,新插入的节点会被该range包含 + * @method insertNode + * @param { Node } node 需要插入的节点 + * @remind 插入的节点可以是一个DocumentFragment依次插入多个节点 + * @return { UE.dom.Range } 当前range对象 + */ + insertNode:function (node) { + var first = node, length = 1; + if (node.nodeType == 11) { + first = node.firstChild; + length = node.childNodes.length; + } + this.trimBoundary(true); + var start = this.startContainer, + offset = this.startOffset; + var nextNode = start.childNodes[ offset ]; + if (nextNode) { + start.insertBefore(node, nextNode); + } else { + start.appendChild(node); + } + if (first.parentNode === this.endContainer) { + this.endOffset = this.endOffset + length; + } + return this.setStartBefore(first); + }, + + /** + * 闭合选区到当前选区的开始位置, 并且定位光标到闭合后的位置 + * @method setCursor + * @return { UE.dom.Range } 当前range对象 + * @see UE.dom.Range:collapse() + */ + + /** + * 闭合选区,可以根据参数toEnd的值控制选区是向前闭合还是向后闭合, 并且定位光标到闭合后的位置。 + * @method setCursor + * @param { Boolean } toEnd 是否向后闭合, 如果为true, 则闭合选区时, 将向结束容器方向闭合, + * 反之,则向开始容器方向闭合 + * @return { UE.dom.Range } 当前range对象 + * @see UE.dom.Range:collapse(Boolean) + */ + setCursor:function (toEnd, noFillData) { + return this.collapse(!toEnd).select(noFillData); + }, + + /** + * 创建当前range的一个书签,记录下当前range的位置,方便当dom树改变时,还能找回原来的选区位置 + * @method createBookmark + * @param { Boolean } serialize 控制返回的标记位置是对当前位置的引用还是ID,如果该值为true,则 + * 返回标记位置的ID, 反之则返回标记位置节点的引用 + * @return { Object } 返回一个书签记录键值对, 其包含的key有: start => 开始标记的ID或者引用, + * end => 结束标记的ID或引用, id => 当前标记的类型, 如果为true,则表示 + * 返回的记录的类型为ID, 反之则为引用 + */ + createBookmark:function (serialize, same) { + var endNode, + startNode = this.document.createElement('span'); + startNode.style.cssText = 'display:none;line-height:0px;'; + startNode.appendChild(this.document.createTextNode('\u200D')); + startNode.id = '_baidu_bookmark_start_' + (same ? '' : guid++); + + if (!this.collapsed) { + endNode = startNode.cloneNode(true); + endNode.id = '_baidu_bookmark_end_' + (same ? '' : guid++); + } + this.insertNode(startNode); + if (endNode) { + this.collapse().insertNode(endNode).setEndBefore(endNode); + } + this.setStartAfter(startNode); + return { + start:serialize ? startNode.id : startNode, + end:endNode ? serialize ? endNode.id : endNode : null, + id:serialize + } + }, + + /** + * 调整当前range的边界到书签位置,并删除该书签对象所标记的位置内的节点 + * @method moveToBookmark + * @param { BookMark } bookmark createBookmark所创建的标签对象 + * @return { UE.dom.Range } 当前range对象 + * @see UE.dom.Range:createBookmark(Boolean) + */ + moveToBookmark:function (bookmark) { + var start = bookmark.id ? this.document.getElementById(bookmark.start) : bookmark.start, + end = bookmark.end && bookmark.id ? this.document.getElementById(bookmark.end) : bookmark.end; + this.setStartBefore(start); + domUtils.remove(start); + if (end) { + this.setEndBefore(end); + domUtils.remove(end); + } else { + this.collapse(true); + } + return this; + }, + + /** + * 调整range的边界,使其"放大"到最近的父节点 + * @method enlarge + * @remind 会引起选区的变化 + * @return { UE.dom.Range } 当前range对象 + */ + + /** + * 调整range的边界,使其"放大"到最近的父节点,根据参数 toBlock 的取值, 可以 + * 要求扩大之后的父节点是block节点 + * @method enlarge + * @param { Boolean } toBlock 是否要求扩大之后的父节点必须是block节点 + * @return { UE.dom.Range } 当前range对象 + */ + enlarge:function (toBlock, stopFn) { + var isBody = domUtils.isBody, + pre, node, tmp = this.document.createTextNode(''); + if (toBlock) { + node = this.startContainer; + if (node.nodeType == 1) { + if (node.childNodes[this.startOffset]) { + pre = node = node.childNodes[this.startOffset] + } else { + node.appendChild(tmp); + pre = node = tmp; + } + } else { + pre = node; + } + while (1) { + if (domUtils.isBlockElm(node)) { + node = pre; + while ((pre = node.previousSibling) && !domUtils.isBlockElm(pre)) { + node = pre; + } + this.setStartBefore(node); + break; + } + pre = node; + node = node.parentNode; + } + node = this.endContainer; + if (node.nodeType == 1) { + if (pre = node.childNodes[this.endOffset]) { + node.insertBefore(tmp, pre); + } else { + node.appendChild(tmp); + } + pre = node = tmp; + } else { + pre = node; + } + while (1) { + if (domUtils.isBlockElm(node)) { + node = pre; + while ((pre = node.nextSibling) && !domUtils.isBlockElm(pre)) { + node = pre; + } + this.setEndAfter(node); + break; + } + pre = node; + node = node.parentNode; + } + if (tmp.parentNode === this.endContainer) { + this.endOffset--; + } + domUtils.remove(tmp); + } + + // 扩展边界到最大 + if (!this.collapsed) { + while (this.startOffset == 0) { + if (stopFn && stopFn(this.startContainer)) { + break; + } + if (isBody(this.startContainer)) { + break; + } + this.setStartBefore(this.startContainer); + } + while (this.endOffset == (this.endContainer.nodeType == 1 ? this.endContainer.childNodes.length : this.endContainer.nodeValue.length)) { + if (stopFn && stopFn(this.endContainer)) { + break; + } + if (isBody(this.endContainer)) { + break; + } + this.setEndAfter(this.endContainer); + } + } + return this; + }, + enlargeToBlockElm:function(ignoreEnd){ + while(!domUtils.isBlockElm(this.startContainer)){ + this.setStartBefore(this.startContainer); + } + if(!ignoreEnd){ + while(!domUtils.isBlockElm(this.endContainer)){ + this.setEndAfter(this.endContainer); + } + } + return this; + }, + /** + * 调整Range的边界,使其"缩小"到最合适的位置 + * @method adjustmentBoundary + * @return { UE.dom.Range } 当前range对象 + * @see UE.dom.Range:shrinkBoundary() + */ + adjustmentBoundary:function () { + if (!this.collapsed) { + while (!domUtils.isBody(this.startContainer) && + this.startOffset == this.startContainer[this.startContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length && + this.startContainer[this.startContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length + ) { + + this.setStartAfter(this.startContainer); + } + while (!domUtils.isBody(this.endContainer) && !this.endOffset && + this.endContainer[this.endContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length + ) { + this.setEndBefore(this.endContainer); + } + } + return this; + }, + + /** + * 给range选区中的内容添加给定的inline标签 + * @method applyInlineStyle + * @param { String } tagName 需要添加的标签名 + * @example + * ```html + *

      xxxx[xxxx]x

      ==> range.applyInlineStyle("strong") ==>

      xxxx[xxxx]x

      + * ``` + */ + + /** + * 给range选区中的内容添加给定的inline标签, 并且为标签附加上一些初始化属性。 + * @method applyInlineStyle + * @param { String } tagName 需要添加的标签名 + * @param { Object } attrs 跟随新添加的标签的属性 + * @return { UE.dom.Range } 当前选区 + * @example + * ```html + *

      xxxx[xxxx]x

      + * + * ==> + * + * + * range.applyInlineStyle("strong",{"style":"font-size:12px"}) + * + * ==> + * + *

      xxxx[xxxx]x

      + * ``` + */ + applyInlineStyle:function (tagName, attrs, list) { + if (this.collapsed)return this; + this.trimBoundary().enlarge(false, + function (node) { + return node.nodeType == 1 && domUtils.isBlockElm(node) + }).adjustmentBoundary(); + var bookmark = this.createBookmark(), + end = bookmark.end, + filterFn = function (node) { + return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' : !domUtils.isWhitespace(node); + }, + current = domUtils.getNextDomNode(bookmark.start, false, filterFn), + node, + pre, + range = this.cloneRange(); + while (current && (domUtils.getPosition(current, end) & domUtils.POSITION_PRECEDING)) { + if (current.nodeType == 3 || dtd[tagName][current.tagName]) { + range.setStartBefore(current); + node = current; + while (node && (node.nodeType == 3 || dtd[tagName][node.tagName]) && node !== end) { + pre = node; + node = domUtils.getNextDomNode(node, node.nodeType == 1, null, function (parent) { + return dtd[tagName][parent.tagName]; + }); + } + var frag = range.setEndAfter(pre).extractContents(), elm; + if (list && list.length > 0) { + var level, top; + top = level = list[0].cloneNode(false); + for (var i = 1, ci; ci = list[i++];) { + level.appendChild(ci.cloneNode(false)); + level = level.firstChild; + } + elm = level; + } else { + elm = range.document.createElement(tagName); + } + if (attrs) { + domUtils.setAttributes(elm, attrs); + } + elm.appendChild(frag); + range.insertNode(list ? top : elm); + //处理下滑线在a上的情况 + var aNode; + if (tagName == 'span' && attrs.style && /text\-decoration/.test(attrs.style) && (aNode = domUtils.findParentByTagName(elm, 'a', true))) { + domUtils.setAttributes(aNode, attrs); + domUtils.remove(elm, true); + elm = aNode; + } else { + domUtils.mergeSibling(elm); + domUtils.clearEmptySibling(elm); + } + //去除子节点相同的 + domUtils.mergeChild(elm, attrs); + current = domUtils.getNextDomNode(elm, false, filterFn); + domUtils.mergeToParent(elm); + if (node === end) { + break; + } + } else { + current = domUtils.getNextDomNode(current, true, filterFn); + } + } + return this.moveToBookmark(bookmark); + }, + + /** + * 移除当前选区内指定的inline标签,但保留其中的内容 + * @method removeInlineStyle + * @param { String } tagName 需要移除的标签名 + * @return { UE.dom.Range } 当前的range对象 + * @example + * ```html + * xx[xxxxyyyzz]z => range.removeInlineStyle(["em"]) => xx[xxxxyyyzz]z + * ``` + */ + + /** + * 移除当前选区内指定的一组inline标签,但保留其中的内容 + * @method removeInlineStyle + * @param { Array } tagNameArr 需要移除的标签名的数组 + * @return { UE.dom.Range } 当前的range对象 + * @see UE.dom.Range:removeInlineStyle(String) + */ + removeInlineStyle:function (tagNames) { + if (this.collapsed)return this; + tagNames = utils.isArray(tagNames) ? tagNames : [tagNames]; + this.shrinkBoundary().adjustmentBoundary(); + var start = this.startContainer, end = this.endContainer; + while (1) { + if (start.nodeType == 1) { + if (utils.indexOf(tagNames, start.tagName.toLowerCase()) > -1) { + break; + } + if (start.tagName.toLowerCase() == 'body') { + start = null; + break; + } + } + start = start.parentNode; + } + while (1) { + if (end.nodeType == 1) { + if (utils.indexOf(tagNames, end.tagName.toLowerCase()) > -1) { + break; + } + if (end.tagName.toLowerCase() == 'body') { + end = null; + break; + } + } + end = end.parentNode; + } + var bookmark = this.createBookmark(), + frag, + tmpRange; + if (start) { + tmpRange = this.cloneRange().setEndBefore(bookmark.start).setStartBefore(start); + frag = tmpRange.extractContents(); + tmpRange.insertNode(frag); + domUtils.clearEmptySibling(start, true); + start.parentNode.insertBefore(bookmark.start, start); + } + if (end) { + tmpRange = this.cloneRange().setStartAfter(bookmark.end).setEndAfter(end); + frag = tmpRange.extractContents(); + tmpRange.insertNode(frag); + domUtils.clearEmptySibling(end, false, true); + end.parentNode.insertBefore(bookmark.end, end.nextSibling); + } + var current = domUtils.getNextDomNode(bookmark.start, false, function (node) { + return node.nodeType == 1; + }), next; + while (current && current !== bookmark.end) { + next = domUtils.getNextDomNode(current, true, function (node) { + return node.nodeType == 1; + }); + if (utils.indexOf(tagNames, current.tagName.toLowerCase()) > -1) { + domUtils.remove(current, true); + } + current = next; + } + return this.moveToBookmark(bookmark); + }, + + /** + * 获取当前选中的自闭合的节点 + * @method getClosedNode + * @return { Node | NULL } 如果当前选中的是自闭合节点, 则返回该节点, 否则返回NULL + */ + getClosedNode:function () { + var node; + if (!this.collapsed) { + var range = this.cloneRange().adjustmentBoundary().shrinkBoundary(); + if (selectOneNode(range)) { + var child = range.startContainer.childNodes[range.startOffset]; + if (child && child.nodeType == 1 && (dtd.$empty[child.tagName] || dtd.$nonChild[child.tagName])) { + node = child; + } + } + } + return node; + }, + + /** + * 在页面上高亮range所表示的选区 + * @method select + * @return { UE.dom.Range } 返回当前Range对象 + */ + //这里不区分ie9以上,trace:3824 + select:browser.ie ? function (noFillData, textRange) { + var nativeRange; + if (!this.collapsed) + this.shrinkBoundary(); + var node = this.getClosedNode(); + if (node && !textRange) { + try { + nativeRange = this.document.body.createControlRange(); + nativeRange.addElement(node); + nativeRange.select(); + } catch (e) {} + return this; + } + var bookmark = this.createBookmark(), + start = bookmark.start, + end; + nativeRange = this.document.body.createTextRange(); + nativeRange.moveToElementText(start); + nativeRange.moveStart('character', 1); + if (!this.collapsed) { + var nativeRangeEnd = this.document.body.createTextRange(); + end = bookmark.end; + nativeRangeEnd.moveToElementText(end); + nativeRange.setEndPoint('EndToEnd', nativeRangeEnd); + } else { + if (!noFillData && this.startContainer.nodeType != 3) { + //使用|x固定住光标 + var tmpText = this.document.createTextNode(fillChar), + tmp = this.document.createElement('span'); + tmp.appendChild(this.document.createTextNode(fillChar)); + start.parentNode.insertBefore(tmp, start); + start.parentNode.insertBefore(tmpText, start); + //当点b,i,u时,不能清除i上边的b + removeFillData(this.document, tmpText); + fillData = tmpText; + mergeSibling(tmp, 'previousSibling'); + mergeSibling(start, 'nextSibling'); + nativeRange.moveStart('character', -1); + nativeRange.collapse(true); + } + } + this.moveToBookmark(bookmark); + tmp && domUtils.remove(tmp); + //IE在隐藏状态下不支持range操作,catch一下 + try { + nativeRange.select(); + } catch (e) { + } + return this; + } : function (notInsertFillData) { + function checkOffset(rng){ + + function check(node,offset,dir){ + if(node.nodeType == 3 && node.nodeValue.length < offset){ + rng[dir + 'Offset'] = node.nodeValue.length + } + } + check(rng.startContainer,rng.startOffset,'start'); + check(rng.endContainer,rng.endOffset,'end'); + } + var win = domUtils.getWindow(this.document), + sel = win.getSelection(), + txtNode; + //FF下关闭自动长高时滚动条在关闭dialog时会跳 + //ff下如果不body.focus将不能定位闭合光标到编辑器内 + browser.gecko ? this.document.body.focus() : win.focus(); + if (sel) { + sel.removeAllRanges(); + // trace:870 chrome/safari后边是br对于闭合得range不能定位 所以去掉了判断 + // this.startContainer.nodeType != 3 &&! ((child = this.startContainer.childNodes[this.startOffset]) && child.nodeType == 1 && child.tagName == 'BR' + if (this.collapsed && !notInsertFillData) { +// //opear如果没有节点接着,原生的不能够定位,不能在body的第一级插入空白节点 +// if (notInsertFillData && browser.opera && !domUtils.isBody(this.startContainer) && this.startContainer.nodeType == 1) { +// var tmp = this.document.createTextNode(''); +// this.insertNode(tmp).setStart(tmp, 0).collapse(true); +// } +// + //处理光标落在文本节点的情况 + //处理以下的情况 + //|xxxx + //xxxx|xxxx + //xxxx| + var start = this.startContainer,child = start; + if(start.nodeType == 1){ + child = start.childNodes[this.startOffset]; + + } + if( !(start.nodeType == 3 && this.startOffset) && + (child ? + (!child.previousSibling || child.previousSibling.nodeType != 3) + : + (!start.lastChild || start.lastChild.nodeType != 3) + ) + ){ + txtNode = this.document.createTextNode(fillChar); + //跟着前边走 + this.insertNode(txtNode); + removeFillData(this.document, txtNode); + mergeSibling(txtNode, 'previousSibling'); + mergeSibling(txtNode, 'nextSibling'); + fillData = txtNode; + this.setStart(txtNode, browser.webkit ? 1 : 0).collapse(true); + } + } + var nativeRange = this.document.createRange(); + if(this.collapsed && browser.opera && this.startContainer.nodeType == 1){ + var child = this.startContainer.childNodes[this.startOffset]; + if(!child){ + //往前靠拢 + child = this.startContainer.lastChild; + if( child && domUtils.isBr(child)){ + this.setStartBefore(child).collapse(true); + } + }else{ + //向后靠拢 + while(child && domUtils.isBlockElm(child)){ + if(child.nodeType == 1 && child.childNodes[0]){ + child = child.childNodes[0] + }else{ + break; + } + } + child && this.setStartBefore(child).collapse(true) + } + + } + //是createAddress最后一位算的不准,现在这里进行微调 + checkOffset(this); + nativeRange.setStart(this.startContainer, this.startOffset); + nativeRange.setEnd(this.endContainer, this.endOffset); + sel.addRange(nativeRange); + } + return this; + }, + + /** + * 滚动到当前range开始的位置 + * @method scrollToView + * @param { Window } win 当前range对象所属的window对象 + * @return { UE.dom.Range } 当前Range对象 + */ + + /** + * 滚动到距离当前range开始位置 offset 的位置处 + * @method scrollToView + * @param { Window } win 当前range对象所属的window对象 + * @param { Number } offset 距离range开始位置处的偏移量, 如果为正数, 则向下偏移, 反之, 则向上偏移 + * @return { UE.dom.Range } 当前Range对象 + */ + scrollToView:function (win, offset) { + win = win ? window : domUtils.getWindow(this.document); + var me = this, + span = me.document.createElement('span'); + //trace:717 + span.innerHTML = ' '; + me.cloneRange().insertNode(span); + domUtils.scrollToView(span, win, offset); + domUtils.remove(span); + return me; + }, + + /** + * 判断当前选区内容是否占位符 + * @private + * @method inFillChar + * @return { Boolean } 如果是占位符返回true,否则返回false + */ + inFillChar : function(){ + var start = this.startContainer; + if(this.collapsed && start.nodeType == 3 + && start.nodeValue.replace(new RegExp('^' + domUtils.fillChar),'').length + 1 == start.nodeValue.length + ){ + return true; + } + return false; + }, + + /** + * 保存 + * @method createAddress + * @private + * @return { Boolean } 返回开始和结束的位置 + * @example + * ```html + * + *

      + * aaaa + * + * + * bbbb + * + * + *

      + * + * + * + * ``` + */ + createAddress : function(ignoreEnd,ignoreTxt){ + var addr = {},me = this; + + function getAddress(isStart){ + var node = isStart ? me.startContainer : me.endContainer; + var parents = domUtils.findParents(node,true,function(node){return !domUtils.isBody(node)}), + addrs = []; + for(var i = 0,ci;ci = parents[i++];){ + addrs.push(domUtils.getNodeIndex(ci,ignoreTxt)); + } + var firstIndex = 0; + + if(ignoreTxt){ + if(node.nodeType == 3){ + var tmpNode = node.previousSibling; + while(tmpNode && tmpNode.nodeType == 3){ + firstIndex += tmpNode.nodeValue.replace(fillCharReg,'').length; + tmpNode = tmpNode.previousSibling; + } + firstIndex += (isStart ? me.startOffset : me.endOffset)// - (fillCharReg.test(node.nodeValue) ? 1 : 0 ) + }else{ + node = node.childNodes[ isStart ? me.startOffset : me.endOffset]; + if(node){ + firstIndex = domUtils.getNodeIndex(node,ignoreTxt); + }else{ + node = isStart ? me.startContainer : me.endContainer; + var first = node.firstChild; + while(first){ + if(domUtils.isFillChar(first)){ + first = first.nextSibling; + continue; + } + firstIndex++; + if(first.nodeType == 3){ + while( first && first.nodeType == 3){ + first = first.nextSibling; + } + }else{ + first = first.nextSibling; + } + } + } + } + + }else{ + firstIndex = isStart ? domUtils.isFillChar(node) ? 0 : me.startOffset : me.endOffset + } + if(firstIndex < 0){ + firstIndex = 0; + } + addrs.push(firstIndex); + return addrs; + } + addr.startAddress = getAddress(true); + if(!ignoreEnd){ + addr.endAddress = me.collapsed ? [].concat(addr.startAddress) : getAddress(); + } + return addr; + }, + + /** + * 保存 + * @method createAddress + * @private + * @return { Boolean } 返回开始和结束的位置 + * @example + * ```html + * + *

      + * aaaa + * + * + * bbbb + * + * + *

      + * + * + * + * ``` + */ + moveToAddress : function(addr,ignoreEnd){ + var me = this; + function getNode(address,isStart){ + var tmpNode = me.document.body, + parentNode,offset; + for(var i= 0,ci,l=address.length;i + * + * + * + * + * + * + * + * + * ``` + */ + + /** + * 遍历range内的节点。 + * 每当遍历一个节点时, 都会执行参数项 doFn 指定的函数, 该函数的接受当前遍历的节点 + * 作为其参数。 + * 可以通过参数项 filterFn 来指定一个过滤器, 只有符合该过滤器过滤规则的节点才会触 + * 发doFn函数的执行 + * @method traversal + * @param { Function } doFn 对每个遍历的节点要执行的方法, 该方法接受当前遍历的节点作为其参数 + * @param { Function } filterFn 过滤器, 该函数接受当前遍历的节点作为参数, 如果该节点满足过滤 + * 规则, 请返回true, 该节点会触发doFn, 否则, 请返回false, 则该节点不 + * 会触发doFn。 + * @return { UE.dom.Range } 当前range对象 + * @see UE.dom.Range:traversal(Function) + * @example + * ```html + * + * + * + * + * + * + * + * + * + * + * ``` + */ + traversal:function(doFn,filterFn){ + if (this.collapsed) + return this; + var bookmark = this.createBookmark(), + end = bookmark.end, + current = domUtils.getNextDomNode(bookmark.start, false, filterFn); + while (current && current !== end && (domUtils.getPosition(current, end) & domUtils.POSITION_PRECEDING)) { + var tmpNode = domUtils.getNextDomNode(current,false,filterFn); + doFn(current); + current = tmpNode; + } + return this.moveToBookmark(bookmark); + } + }; +})(); + +// core/Selection.js +/** + * 选集 + * @file + * @module UE.dom + * @class Selection + * @since 1.2.6.1 + */ + +/** + * 选区集合 + * @unfile + * @module UE.dom + * @class Selection + */ +(function () { + + function getBoundaryInformation( range, start ) { + var getIndex = domUtils.getNodeIndex; + range = range.duplicate(); + range.collapse( start ); + var parent = range.parentElement(); + //如果节点里没有子节点,直接退出 + if ( !parent.hasChildNodes() ) { + return {container:parent, offset:0}; + } + var siblings = parent.children, + child, + testRange = range.duplicate(), + startIndex = 0, endIndex = siblings.length - 1, index = -1, + distance; + while ( startIndex <= endIndex ) { + index = Math.floor( (startIndex + endIndex) / 2 ); + child = siblings[index]; + testRange.moveToElementText( child ); + var position = testRange.compareEndPoints( 'StartToStart', range ); + if ( position > 0 ) { + endIndex = index - 1; + } else if ( position < 0 ) { + startIndex = index + 1; + } else { + //trace:1043 + return {container:parent, offset:getIndex( child )}; + } + } + if ( index == -1 ) { + testRange.moveToElementText( parent ); + testRange.setEndPoint( 'StartToStart', range ); + distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length; + siblings = parent.childNodes; + if ( !distance ) { + child = siblings[siblings.length - 1]; + return {container:child, offset:child.nodeValue.length}; + } + + var i = siblings.length; + while ( distance > 0 ){ + distance -= siblings[ --i ].nodeValue.length; + } + return {container:siblings[i], offset:-distance}; + } + testRange.collapse( position > 0 ); + testRange.setEndPoint( position > 0 ? 'StartToStart' : 'EndToStart', range ); + distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length; + if ( !distance ) { + return dtd.$empty[child.tagName] || dtd.$nonChild[child.tagName] ? + {container:parent, offset:getIndex( child ) + (position > 0 ? 0 : 1)} : + {container:child, offset:position > 0 ? 0 : child.childNodes.length} + } + while ( distance > 0 ) { + try { + var pre = child; + child = child[position > 0 ? 'previousSibling' : 'nextSibling']; + distance -= child.nodeValue.length; + } catch ( e ) { + return {container:parent, offset:getIndex( pre )}; + } + } + return {container:child, offset:position > 0 ? -distance : child.nodeValue.length + distance} + } + + /** + * 将ieRange转换为Range对象 + * @param {Range} ieRange ieRange对象 + * @param {Range} range Range对象 + * @return {Range} range 返回转换后的Range对象 + */ + function transformIERangeToRange( ieRange, range ) { + if ( ieRange.item ) { + range.selectNode( ieRange.item( 0 ) ); + } else { + var bi = getBoundaryInformation( ieRange, true ); + range.setStart( bi.container, bi.offset ); + if ( ieRange.compareEndPoints( 'StartToEnd', ieRange ) != 0 ) { + bi = getBoundaryInformation( ieRange, false ); + range.setEnd( bi.container, bi.offset ); + } + } + return range; + } + + /** + * 获得ieRange + * @param {Selection} sel Selection对象 + * @return {ieRange} 得到ieRange + */ + function _getIERange( sel ) { + var ieRange; + //ie下有可能报错 + try { + ieRange = sel.getNative().createRange(); + } catch ( e ) { + return null; + } + var el = ieRange.item ? ieRange.item( 0 ) : ieRange.parentElement(); + if ( ( el.ownerDocument || el ) === sel.document ) { + return ieRange; + } + return null; + } + + var Selection = dom.Selection = function ( doc ) { + var me = this, iframe; + me.document = doc; + if ( browser.ie9below ) { + iframe = domUtils.getWindow( doc ).frameElement; + domUtils.on( iframe, 'beforedeactivate', function () { + me._bakIERange = me.getIERange(); + } ); + domUtils.on( iframe, 'activate', function () { + try { + if ( !_getIERange( me ) && me._bakIERange ) { + me._bakIERange.select(); + } + } catch ( ex ) { + } + me._bakIERange = null; + } ); + } + iframe = doc = null; + }; + + Selection.prototype = { + + rangeInBody : function(rng,txtRange){ + var node = browser.ie9below || txtRange ? rng.item ? rng.item() : rng.parentElement() : rng.startContainer; + + return node === this.document.body || domUtils.inDoc(node,this.document); + }, + + /** + * 获取原生seleciton对象 + * @method getNative + * @return { Object } 获得selection对象 + * @example + * ```javascript + * editor.selection.getNative(); + * ``` + */ + getNative:function () { + var doc = this.document; + try { + return !doc ? null : browser.ie9below ? doc.selection : domUtils.getWindow( doc ).getSelection(); + } catch ( e ) { + return null; + } + }, + + /** + * 获得ieRange + * @method getIERange + * @return { Object } 返回ie原生的Range + * @example + * ```javascript + * editor.selection.getIERange(); + * ``` + */ + getIERange:function () { + var ieRange = _getIERange( this ); + if ( !ieRange ) { + if ( this._bakIERange ) { + return this._bakIERange; + } + } + return ieRange; + }, + + /** + * 缓存当前选区的range和选区的开始节点 + * @method cache + */ + cache:function () { + this.clear(); + this._cachedRange = this.getRange(); + this._cachedStartElement = this.getStart(); + this._cachedStartElementPath = this.getStartElementPath(); + }, + + /** + * 获取选区开始位置的父节点到body + * @method getStartElementPath + * @return { Array } 返回父节点集合 + * @example + * ```javascript + * editor.selection.getStartElementPath(); + * ``` + */ + getStartElementPath:function () { + if ( this._cachedStartElementPath ) { + return this._cachedStartElementPath; + } + var start = this.getStart(); + if ( start ) { + return domUtils.findParents( start, true, null, true ) + } + return []; + }, + + /** + * 清空缓存 + * @method clear + */ + clear:function () { + this._cachedStartElementPath = this._cachedRange = this._cachedStartElement = null; + }, + + /** + * 编辑器是否得到了选区 + * @method isFocus + */ + isFocus:function () { + try { + if(browser.ie9below){ + + var nativeRange = _getIERange(this); + return !!(nativeRange && this.rangeInBody(nativeRange)); + }else{ + return !!this.getNative().rangeCount; + } + } catch ( e ) { + return false; + } + + }, + + /** + * 获取选区对应的Range + * @method getRange + * @return { Object } 得到Range对象 + * @example + * ```javascript + * editor.selection.getRange(); + * ``` + */ + getRange:function () { + var me = this; + function optimze( range ) { + var child = me.document.body.firstChild, + collapsed = range.collapsed; + while ( child && child.firstChild ) { + range.setStart( child, 0 ); + child = child.firstChild; + } + if ( !range.startContainer ) { + range.setStart( me.document.body, 0 ) + } + if ( collapsed ) { + range.collapse( true ); + } + } + + if ( me._cachedRange != null ) { + return this._cachedRange; + } + var range = new baidu.editor.dom.Range( me.document ); + + if ( browser.ie9below ) { + var nativeRange = me.getIERange(); + if ( nativeRange ) { + //备份的_bakIERange可能已经实效了,dom树发生了变化比如从源码模式切回来,所以try一下,实效就放到body开始位置 + try{ + transformIERangeToRange( nativeRange, range ); + }catch(e){ + optimze( range ); + } + + } else { + optimze( range ); + } + } else { + var sel = me.getNative(); + if ( sel && sel.rangeCount ) { + var firstRange = sel.getRangeAt( 0 ); + var lastRange = sel.getRangeAt( sel.rangeCount - 1 ); + range.setStart( firstRange.startContainer, firstRange.startOffset ).setEnd( lastRange.endContainer, lastRange.endOffset ); + if ( range.collapsed && domUtils.isBody( range.startContainer ) && !range.startOffset ) { + optimze( range ); + } + } else { + //trace:1734 有可能已经不在dom树上了,标识的节点 + if ( this._bakRange && domUtils.inDoc( this._bakRange.startContainer, this.document ) ){ + return this._bakRange; + } + optimze( range ); + } + } + return this._bakRange = range; + }, + + /** + * 获取开始元素,用于状态反射 + * @method getStart + * @return { Element } 获得开始元素 + * @example + * ```javascript + * editor.selection.getStart(); + * ``` + */ + getStart:function () { + if ( this._cachedStartElement ) { + return this._cachedStartElement; + } + var range = browser.ie9below ? this.getIERange() : this.getRange(), + tmpRange, + start, tmp, parent; + if ( browser.ie9below ) { + if ( !range ) { + //todo 给第一个值可能会有问题 + return this.document.body.firstChild; + } + //control元素 + if ( range.item ){ + return range.item( 0 ); + } + tmpRange = range.duplicate(); + //修正ie下x[xx] 闭合后 x|xx + tmpRange.text.length > 0 && tmpRange.moveStart( 'character', 1 ); + tmpRange.collapse( 1 ); + start = tmpRange.parentElement(); + parent = tmp = range.parentElement(); + while ( tmp = tmp.parentNode ) { + if ( tmp == start ) { + start = parent; + break; + } + } + } else { + range.shrinkBoundary(); + start = range.startContainer; + if ( start.nodeType == 1 && start.hasChildNodes() ){ + start = start.childNodes[Math.min( start.childNodes.length - 1, range.startOffset )]; + } + if ( start.nodeType == 3 ){ + return start.parentNode; + } + } + return start; + }, + + /** + * 得到选区中的文本 + * @method getText + * @return { String } 选区中包含的文本 + * @example + * ```javascript + * editor.selection.getText(); + * ``` + */ + getText:function () { + var nativeSel, nativeRange; + if ( this.isFocus() && (nativeSel = this.getNative()) ) { + nativeRange = browser.ie9below ? nativeSel.createRange() : nativeSel.getRangeAt( 0 ); + return browser.ie9below ? nativeRange.text : nativeRange.toString(); + } + return ''; + }, + + /** + * 清除选区 + * @method clearRange + * @example + * ```javascript + * editor.selection.clearRange(); + * ``` + */ + clearRange : function(){ + this.getNative()[browser.ie9below ? 'empty' : 'removeAllRanges'](); + } + }; +})(); + +// core/Editor.js +/** + * 编辑器主类,包含编辑器提供的大部分公用接口 + * @file + * @module UE + * @class Editor + * @since 1.2.6.1 + */ + +/** + * UEditor公用空间,UEditor所有的功能都挂载在该空间下 + * @unfile + * @module UE + */ + +/** + * UEditor的核心类,为用户提供与编辑器交互的接口。 + * @unfile + * @module UE + * @class Editor + */ + +(function () { + var uid = 0, _selectionChangeTimer; + + /** + * 获取编辑器的html内容,赋值到编辑器所在表单的textarea文本域里面 + * @private + * @method setValue + * @param { UE.Editor } editor 编辑器事例 + */ + function setValue(form, editor) { + var textarea; + if (editor.textarea) { + if (utils.isString(editor.textarea)) { + for (var i = 0, ti, tis = domUtils.getElementsByTagName(form, 'textarea'); ti = tis[i++];) { + if (ti.id == 'ueditor_textarea_' + editor.options.textarea) { + textarea = ti; + break; + } + } + } else { + textarea = editor.textarea; + } + } + if (!textarea) { + form.appendChild(textarea = domUtils.createElement(document, 'textarea', { + 'name': editor.options.textarea, + 'id': 'ueditor_textarea_' + editor.options.textarea, + 'style': "display:none" + })); + //不要产生多个textarea + editor.textarea = textarea; + } + !textarea.getAttribute('name') && textarea.setAttribute('name', editor.options.textarea ); + textarea.value = editor.hasContents() ? + (editor.options.allHtmlEnabled ? editor.getAllHtml() : editor.getContent(null, null, true)) : + '' + } + function loadPlugins(me){ + //初始化插件 + for (var pi in UE.plugins) { + UE.plugins[pi].call(me); + } + + } + function checkCurLang(I18N){ + for(var lang in I18N){ + return lang + } + } + + function langReadied(me){ + me.langIsReady = true; + + me.fireEvent("langReady"); + } + + /** + * 编辑器准备就绪后会触发该事件 + * @module UE + * @class Editor + * @event ready + * @remind render方法执行完成之后,会触发该事件 + * @remind + * @example + * ```javascript + * editor.addListener( 'ready', function( editor ) { + * editor.execCommand( 'focus' ); //编辑器家在完成后,让编辑器拿到焦点 + * } ); + * ``` + */ + /** + * 执行destroy方法,会触发该事件 + * @module UE + * @class Editor + * @event destroy + * @see UE.Editor:destroy() + */ + /** + * 执行reset方法,会触发该事件 + * @module UE + * @class Editor + * @event reset + * @see UE.Editor:reset() + */ + /** + * 执行focus方法,会触发该事件 + * @module UE + * @class Editor + * @event focus + * @see UE.Editor:focus(Boolean) + */ + /** + * 语言加载完成会触发该事件 + * @module UE + * @class Editor + * @event langReady + */ + /** + * 运行命令之后会触发该命令 + * @module UE + * @class Editor + * @event beforeExecCommand + */ + /** + * 运行命令之后会触发该命令 + * @module UE + * @class Editor + * @event afterExecCommand + */ + /** + * 运行命令之前会触发该命令 + * @module UE + * @class Editor + * @event firstBeforeExecCommand + */ + /** + * 在getContent方法执行之前会触发该事件 + * @module UE + * @class Editor + * @event beforeGetContent + * @see UE.Editor:getContent() + */ + /** + * 在getContent方法执行之后会触发该事件 + * @module UE + * @class Editor + * @event afterGetContent + * @see UE.Editor:getContent() + */ + /** + * 在getAllHtml方法执行时会触发该事件 + * @module UE + * @class Editor + * @event getAllHtml + * @see UE.Editor:getAllHtml() + */ + /** + * 在setContent方法执行之前会触发该事件 + * @module UE + * @class Editor + * @event beforeSetContent + * @see UE.Editor:setContent(String) + */ + /** + * 在setContent方法执行之后会触发该事件 + * @module UE + * @class Editor + * @event afterSetContent + * @see UE.Editor:setContent(String) + */ + /** + * 每当编辑器内部选区发生改变时,将触发该事件 + * @event selectionchange + * @warning 该事件的触发非常频繁,不建议在该事件的处理过程中做重量级的处理 + * @example + * ```javascript + * editor.addListener( 'selectionchange', function( editor ) { + * console.log('选区发生改变'); + * } + */ + /** + * 在所有selectionchange的监听函数执行之前,会触发该事件 + * @module UE + * @class Editor + * @event beforeSelectionChange + * @see UE.Editor:selectionchange + */ + /** + * 在所有selectionchange的监听函数执行完之后,会触发该事件 + * @module UE + * @class Editor + * @event afterSelectionChange + * @see UE.Editor:selectionchange + */ + /** + * 编辑器内容发生改变时会触发该事件 + * @module UE + * @class Editor + * @event contentChange + */ + + + /** + * 以默认参数构建一个编辑器实例 + * @constructor + * @remind 通过 改构造方法实例化的编辑器,不带ui层.需要render到一个容器,编辑器实例才能正常渲染到页面 + * @example + * ```javascript + * var editor = new UE.Editor(); + * editor.execCommand('blod'); + * ``` + * @see UE.Config + */ + + /** + * 以给定的参数集合创建一个编辑器实例,对于未指定的参数,将应用默认参数。 + * @constructor + * @remind 通过 改构造方法实例化的编辑器,不带ui层.需要render到一个容器,编辑器实例才能正常渲染到页面 + * @param { Object } setting 创建编辑器的参数 + * @example + * ```javascript + * var editor = new UE.Editor(); + * editor.execCommand('blod'); + * ``` + * @see UE.Config + */ + var Editor = UE.Editor = function (options) { + var me = this; + me.uid = uid++; + EventBase.call(me); + me.commands = {}; + me.options = utils.extend(utils.clone(options || {}), UEDITOR_CONFIG, true); + me.shortcutkeys = {}; + me.inputRules = []; + me.outputRules = []; + //设置默认的常用属性 + me.setOpt(Editor.defaultOptions(me)); + + /* 尝试异步加载后台配置 */ + me.loadServerConfig(); + + if(!utils.isEmptyObject(UE.I18N)){ + //修改默认的语言类型 + me.options.lang = checkCurLang(UE.I18N); + UE.plugin.load(me); + langReadied(me); + + }else{ + utils.loadFile(document, { + src: me.options.langPath + me.options.lang + "/" + me.options.lang + ".js", + tag: "script", + type: "text/javascript", + defer: "defer" + }, function () { + UE.plugin.load(me); + langReadied(me); + }); + } + + UE.instants['ueditorInstant' + me.uid] = me; + }; + Editor.prototype = { + registerCommand : function(name,obj){ + this.commands[name] = obj; + }, + /** + * 编辑器对外提供的监听ready事件的接口, 通过调用该方法,达到的效果与监听ready事件是一致的 + * @method ready + * @param { Function } fn 编辑器ready之后所执行的回调, 如果在注册事件之前编辑器已经ready,将会 + * 立即触发该回调。 + * @remind 需要等待编辑器加载完成后才能执行的代码,可以使用该方法传入 + * @example + * ```javascript + * editor.ready( function( editor ) { + * editor.setContent('初始化完毕'); + * } ); + * ``` + * @see UE.Editor.event:ready + */ + ready: function (fn) { + var me = this; + if (fn) { + me.isReady ? fn.apply(me) : me.addListener('ready', fn); + } + }, + + /** + * 该方法是提供给插件里面使用,设置配置项默认值 + * @method setOpt + * @warning 三处设置配置项的优先级: 实例化时传入参数 > setOpt()设置 > config文件里设置 + * @warning 该方法仅供编辑器插件内部和编辑器初始化时调用,其他地方不能调用。 + * @param { String } key 编辑器的可接受的选项名称 + * @param { * } val 该选项可接受的值 + * @example + * ```javascript + * editor.setOpt( 'initContent', '欢迎使用编辑器' ); + * ``` + */ + + /** + * 该方法是提供给插件里面使用,以{key:value}集合的方式设置插件内用到的配置项默认值 + * @method setOpt + * @warning 三处设置配置项的优先级: 实例化时传入参数 > setOpt()设置 > config文件里设置 + * @warning 该方法仅供编辑器插件内部和编辑器初始化时调用,其他地方不能调用。 + * @param { Object } options 将要设置的选项的键值对对象 + * @example + * ```javascript + * editor.setOpt( { + * 'initContent': '欢迎使用编辑器' + * } ); + * ``` + */ + setOpt: function (key, val) { + var obj = {}; + if (utils.isString(key)) { + obj[key] = val + } else { + obj = key; + } + utils.extend(this.options, obj, true); + }, + getOpt:function(key){ + return this.options[key] + }, + /** + * 销毁编辑器实例,使用textarea代替 + * @method destroy + * @example + * ```javascript + * editor.destroy(); + * ``` + */ + destroy: function () { + + var me = this; + me.fireEvent('destroy'); + var container = me.container.parentNode; + var textarea = me.textarea; + if (!textarea) { + textarea = document.createElement('textarea'); + container.parentNode.insertBefore(textarea, container); + } else { + textarea.style.display = '' + } + + textarea.style.width = me.iframe.offsetWidth + 'px'; + textarea.style.height = me.iframe.offsetHeight + 'px'; + textarea.value = me.getContent(); + textarea.id = me.key; + container.innerHTML = ''; + domUtils.remove(container); + var key = me.key; + //trace:2004 + for (var p in me) { + if (me.hasOwnProperty(p)) { + delete this[p]; + } + } + UE.delEditor(key); + }, + + /** + * 渲染编辑器的DOM到指定容器 + * @method render + * @param { String } containerId 指定一个容器ID + * @remind 执行该方法,会触发ready事件 + * @warning 必须且只能调用一次 + */ + + /** + * 渲染编辑器的DOM到指定容器 + * @method render + * @param { Element } containerDom 直接指定容器对象 + * @remind 执行该方法,会触发ready事件 + * @warning 必须且只能调用一次 + */ + render: function (container) { + var me = this, + options = me.options, + getStyleValue=function(attr){ + return parseInt(domUtils.getComputedStyle(container,attr)); + }; + if (utils.isString(container)) { + container = document.getElementById(container); + } + if (container) { + if(options.initialFrameWidth){ + options.minFrameWidth = options.initialFrameWidth + }else{ + options.minFrameWidth = options.initialFrameWidth = container.offsetWidth; + } + if(options.initialFrameHeight){ + options.minFrameHeight = options.initialFrameHeight + }else{ + options.initialFrameHeight = options.minFrameHeight = container.offsetHeight; + } + + container.style.width = /%$/.test(options.initialFrameWidth) ? '100%' : options.initialFrameWidth- + getStyleValue("padding-left")- getStyleValue("padding-right") +'px'; + container.style.height = /%$/.test(options.initialFrameHeight) ? '100%' : options.initialFrameHeight - + getStyleValue("padding-top")- getStyleValue("padding-bottom") +'px'; + + container.style.zIndex = options.zIndex; + + var html = ( ie && browser.version < 9 ? '' : '') + + '' + + '' + + ( options.iframeCssUrl ? '' : '' ) + + (options.initialStyle ? '' : '') + + '' + + ''; + container.appendChild(domUtils.createElement(document, 'iframe', { + id: 'ueditor_' + me.uid, + width: "100%", + height: "100%", + frameborder: "0", + //先注释掉了,加的原因忘记了,但开启会直接导致全屏模式下内容多时不会出现滚动条 +// scrolling :'no', + src: 'javascript:void(function(){document.open();' + (options.customDomain && document.domain != location.hostname ? 'document.domain="' + document.domain + '";' : '') + + 'document.write("' + html + '");document.close();}())' + })); + container.style.overflow = 'hidden'; + //解决如果是给定的百分比,会导致高度算不对的问题 + setTimeout(function(){ + if( /%$/.test(options.initialFrameWidth)){ + options.minFrameWidth = options.initialFrameWidth = container.offsetWidth; + //如果这里给定宽度,会导致ie在拖动窗口大小时,编辑区域不随着变化 +// container.style.width = options.initialFrameWidth + 'px'; + } + if(/%$/.test(options.initialFrameHeight)){ + options.minFrameHeight = options.initialFrameHeight = container.offsetHeight; + container.style.height = options.initialFrameHeight + 'px'; + } + }) + } + }, + + /** + * 编辑器初始化 + * @method _setup + * @private + * @param { Element } doc 编辑器Iframe中的文档对象 + */ + _setup: function (doc) { + + var me = this, + options = me.options; + if (ie) { + doc.body.disabled = true; + doc.body.contentEditable = true; + doc.body.disabled = false; + } else { + doc.body.contentEditable = true; + } + doc.body.spellcheck = false; + me.document = doc; + me.window = doc.defaultView || doc.parentWindow; + me.iframe = me.window.frameElement; + me.body = doc.body; + me.selection = new dom.Selection(doc); + //gecko初始化就能得到range,无法判断isFocus了 + var geckoSel; + if (browser.gecko && (geckoSel = this.selection.getNative())) { + geckoSel.removeAllRanges(); + } + this._initEvents(); + //为form提交提供一个隐藏的textarea + for (var form = this.iframe.parentNode; !domUtils.isBody(form); form = form.parentNode) { + if (form.tagName == 'FORM') { + me.form = form; + if(me.options.autoSyncData){ + domUtils.on(me.window,'blur',function(){ + setValue(form,me); + }); + }else{ + domUtils.on(form, 'submit', function () { + setValue(this, me); + }); + } + break; + } + } + if (options.initialContent) { + if (options.autoClearinitialContent) { + var oldExecCommand = me.execCommand; + me.execCommand = function () { + me.fireEvent('firstBeforeExecCommand'); + return oldExecCommand.apply(me, arguments); + }; + this._setDefaultContent(options.initialContent); + } else + this.setContent(options.initialContent, false, true); + } + + //编辑器不能为空内容 + + if (domUtils.isEmptyNode(me.body)) { + me.body.innerHTML = '

      ' + (browser.ie ? '' : '
      ') + '

      '; + } + //如果要求focus, 就把光标定位到内容开始 + if (options.focus) { + setTimeout(function () { + me.focus(me.options.focusInEnd); + //如果自动清除开着,就不需要做selectionchange; + !me.options.autoClearinitialContent && me._selectionChange(); + }, 0); + } + if (!me.container) { + me.container = this.iframe.parentNode; + } + if (options.fullscreen && me.ui) { + me.ui.setFullScreen(true); + } + + try { + me.document.execCommand('2D-position', false, false); + } catch (e) { + } + try { + me.document.execCommand('enableInlineTableEditing', false, false); + } catch (e) { + } + try { + me.document.execCommand('enableObjectResizing', false, false); + } catch (e) { + } + + //挂接快捷键 + me._bindshortcutKeys(); + me.isReady = 1; + me.fireEvent('ready'); + options.onready && options.onready.call(me); + if (!browser.ie9below) { + domUtils.on(me.window, ['blur', 'focus'], function (e) { + //chrome下会出现alt+tab切换时,导致选区位置不对 + if (e.type == 'blur') { + me._bakRange = me.selection.getRange(); + try { + me._bakNativeRange = me.selection.getNative().getRangeAt(0); + me.selection.getNative().removeAllRanges(); + } catch (e) { + me._bakNativeRange = null; + } + + } else { + try { + me._bakRange && me._bakRange.select(); + } catch (e) { + } + } + }); + } + //trace:1518 ff3.6body不够寛,会导致点击空白处无法获得焦点 + if (browser.gecko && browser.version <= 10902) { + //修复ff3.6初始化进来,不能点击获得焦点 + me.body.contentEditable = false; + setTimeout(function () { + me.body.contentEditable = true; + }, 100); + setInterval(function () { + me.body.style.height = me.iframe.offsetHeight - 20 + 'px' + }, 100) + } + + !options.isShow && me.setHide(); + options.readonly && me.setDisabled(); + }, + + /** + * 同步数据到编辑器所在的form + * 从编辑器的容器节点向上查找form元素,若找到,就同步编辑内容到找到的form里,为提交数据做准备,主要用于是手动提交的情况 + * 后台取得数据的键值,使用你容器上的name属性,如果没有就使用参数里的textarea项 + * @method sync + * @example + * ```javascript + * editor.sync(); + * form.sumbit(); //form变量已经指向了form元素 + * ``` + */ + + /** + * 根据传入的formId,在页面上查找要同步数据的表单,若找到,就同步编辑内容到找到的form里,为提交数据做准备 + * 后台取得数据的键值,该键值默认使用给定的编辑器容器的name属性,如果没有name属性则使用参数项里给定的“textarea”项 + * @method sync + * @param { String } formID 指定一个要同步数据的form的id,编辑器的数据会同步到你指定form下 + */ + sync: function (formId) { + var me = this, + form = formId ? document.getElementById(formId) : + domUtils.findParent(me.iframe.parentNode, function (node) { + return node.tagName == 'FORM' + }, true); + form && setValue(form, me); + }, + + /** + * 设置编辑器高度 + * @method setHeight + * @remind 当配置项autoHeightEnabled为真时,该方法无效 + * @param { Number } number 设置的高度值,纯数值,不带单位 + * @example + * ```javascript + * editor.setHeight(number); + * ``` + */ + setHeight: function (height,notSetHeight) { + if (height !== parseInt(this.iframe.parentNode.style.height)) { + this.iframe.parentNode.style.height = height + 'px'; + } + !notSetHeight && (this.options.minFrameHeight = this.options.initialFrameHeight = height); + this.body.style.height = height + 'px'; + !notSetHeight && this.trigger('setHeight') + }, + + /** + * 为编辑器的编辑命令提供快捷键 + * 这个接口是为插件扩展提供的接口,主要是为新添加的插件,如果需要添加快捷键,所提供的接口 + * @method addshortcutkey + * @param { Object } keyset 命令名和快捷键键值对对象,多个按钮的快捷键用“+”分隔 + * @example + * ```javascript + * editor.addshortcutkey({ + * "Bold" : "ctrl+66",//^B + * "Italic" : "ctrl+73", //^I + * }); + * ``` + */ + /** + * 这个接口是为插件扩展提供的接口,主要是为新添加的插件,如果需要添加快捷键,所提供的接口 + * @method addshortcutkey + * @param { String } cmd 触发快捷键时,响应的命令 + * @param { String } keys 快捷键的字符串,多个按钮用“+”分隔 + * @example + * ```javascript + * editor.addshortcutkey("Underline", "ctrl+85"); //^U + * ``` + */ + addshortcutkey: function (cmd, keys) { + var obj = {}; + if (keys) { + obj[cmd] = keys + } else { + obj = cmd; + } + utils.extend(this.shortcutkeys, obj) + }, + + /** + * 对编辑器设置keydown事件监听,绑定快捷键和命令,当快捷键组合触发成功,会响应对应的命令 + * @method _bindshortcutKeys + * @private + */ + _bindshortcutKeys: function () { + var me = this, shortcutkeys = this.shortcutkeys; + me.addListener('keydown', function (type, e) { + var keyCode = e.keyCode || e.which; + for (var i in shortcutkeys) { + var tmp = shortcutkeys[i].split(','); + for (var t = 0, ti; ti = tmp[t++];) { + ti = ti.split(':'); + var key = ti[0], param = ti[1]; + if (/^(ctrl)(\+shift)?\+(\d+)$/.test(key.toLowerCase()) || /^(\d+)$/.test(key)) { + if (( (RegExp.$1 == 'ctrl' ? (e.ctrlKey || e.metaKey) : 0) + && (RegExp.$2 != "" ? e[RegExp.$2.slice(1) + "Key"] : 1) + && keyCode == RegExp.$3 + ) || + keyCode == RegExp.$1 + ) { + if (me.queryCommandState(i,param) != -1) + me.execCommand(i, param); + domUtils.preventDefault(e); + } + } + } + + } + }); + }, + + /** + * 获取编辑器的内容 + * @method getContent + * @warning 该方法获取到的是经过编辑器内置的过滤规则进行过滤后得到的内容 + * @return { String } 编辑器的内容字符串, 如果编辑器的内容为空,或者是空的标签内容(如:”<p><br/></p>“), 则返回空字符串 + * @example + * ```javascript + * //编辑器html内容:

      123456

      + * var content = editor.getContent(); //返回值:

      123456

      + * ``` + */ + + /** + * 获取编辑器的内容。 可以通过参数定义编辑器内置的判空规则 + * @method getContent + * @param { Function } fn 自定的判空规则, 要求该方法返回一个boolean类型的值, + * 代表当前编辑器的内容是否空, + * 如果返回true, 则该方法将直接返回空字符串;如果返回false,则编辑器将返回 + * 经过内置过滤规则处理后的内容。 + * @remind 该方法在处理包含有初始化内容的时候能起到很好的作用。 + * @warning 该方法获取到的是经过编辑器内置的过滤规则进行过滤后得到的内容 + * @return { String } 编辑器的内容字符串 + * @example + * ```javascript + * // editor 是一个编辑器的实例 + * var content = editor.getContent( function ( editor ) { + * return editor.body.innerHTML === '欢迎使用UEditor'; //返回空字符串 + * } ); + * ``` + */ + getContent: function (cmd, fn,notSetCursor,ignoreBlank,formatter) { + var me = this; + if (cmd && utils.isFunction(cmd)) { + fn = cmd; + cmd = ''; + } + if (fn ? !fn() : !this.hasContents()) { + return ''; + } + me.fireEvent('beforegetcontent'); + var root = UE.htmlparser(me.body.innerHTML,ignoreBlank); + me.filterOutputRule(root); + me.fireEvent('aftergetcontent', cmd,root); + return root.toHtml(formatter); + }, + + /** + * 取得完整的html代码,可以直接显示成完整的html文档 + * @method getAllHtml + * @return { String } 编辑器的内容html文档字符串 + * @eaxmple + * ```javascript + * editor.getAllHtml(); //返回格式大致是: ...... + * ``` + */ + getAllHtml: function () { + var me = this, + headHtml = [], + html = ''; + me.fireEvent('getAllHtml', headHtml); + if (browser.ie && browser.version > 8) { + var headHtmlForIE9 = ''; + utils.each(me.document.styleSheets, function (si) { + headHtmlForIE9 += ( si.href ? '' : ''); + }); + utils.each(me.document.getElementsByTagName('script'), function (si) { + headHtmlForIE9 += si.outerHTML; + }); + + } + return '' + (me.options.charset ? '' : '') + + (headHtmlForIE9 || me.document.getElementsByTagName('head')[0].innerHTML) + headHtml.join('\n') + '' + + '' + me.getContent(null, null, true) + ''; + }, + + /** + * 得到编辑器的纯文本内容,但会保留段落格式 + * @method getPlainTxt + * @return { String } 编辑器带段落格式的纯文本内容字符串 + * @example + * ```javascript + * //编辑器html内容:

      1

      2

      + * console.log(editor.getPlainTxt()); //输出:"1\n2\n + * ``` + */ + getPlainTxt: function () { + var reg = new RegExp(domUtils.fillChar, 'g'), + html = this.body.innerHTML.replace(/[\n\r]/g, '');//ie要先去了\n在处理 + html = html.replace(/<(p|div)[^>]*>(| )<\/\1>/gi, '\n') + .replace(//gi, '\n') + .replace(/<[^>/]+>/g, '') + .replace(/(\n)?<\/([^>]+)>/g, function (a, b, c) { + return dtd.$block[c] ? '\n' : b ? b : ''; + }); + //取出来的空格会有c2a0会变成乱码,处理这种情况\u00a0 + return html.replace(reg, '').replace(/\u00a0/g, ' ').replace(/ /g, ' '); + }, + + /** + * 获取编辑器中的纯文本内容,没有段落格式 + * @method getContentTxt + * @return { String } 编辑器不带段落格式的纯文本内容字符串 + * @example + * ```javascript + * //编辑器html内容:

      1

      2

      + * console.log(editor.getPlainTxt()); //输出:"12 + * ``` + */ + getContentTxt: function () { + var reg = new RegExp(domUtils.fillChar, 'g'); + //取出来的空格会有c2a0会变成乱码,处理这种情况\u00a0 + return this.body[browser.ie ? 'innerText' : 'textContent'].replace(reg, '').replace(/\u00a0/g, ' '); + }, + + /** + * 设置编辑器的内容,可修改编辑器当前的html内容 + * @method setContent + * @warning 通过该方法插入的内容,是经过编辑器内置的过滤规则进行过滤后得到的内容 + * @warning 该方法会触发selectionchange事件 + * @param { String } html 要插入的html内容 + * @example + * ```javascript + * editor.getContent('

      test

      '); + * ``` + */ + + /** + * 设置编辑器的内容,可修改编辑器当前的html内容 + * @method setContent + * @warning 通过该方法插入的内容,是经过编辑器内置的过滤规则进行过滤后得到的内容 + * @warning 该方法会触发selectionchange事件 + * @param { String } html 要插入的html内容 + * @param { Boolean } isAppendTo 若传入true,不清空原来的内容,在最后插入内容,否则,清空内容再插入 + * @example + * ```javascript + * //假设设置前的编辑器内容是

      old text

      + * editor.setContent('

      new text

      ', true); //插入的结果是

      old text

      new text

      + * ``` + */ + setContent: function (html, isAppendTo, notFireSelectionchange) { + var me = this; + + me.fireEvent('beforesetcontent', html); + var root = UE.htmlparser(html); + me.filterInputRule(root); + html = root.toHtml(); + + me.body.innerHTML = (isAppendTo ? me.body.innerHTML : '') + html; + + + function isCdataDiv(node){ + return node.tagName == 'DIV' && node.getAttribute('cdata_tag'); + } + //给文本或者inline节点套p标签 + if (me.options.enterTag == 'p') { + + var child = this.body.firstChild, tmpNode; + if (!child || child.nodeType == 1 && + (dtd.$cdata[child.tagName] || isCdataDiv(child) || + domUtils.isCustomeNode(child) + ) + && child === this.body.lastChild) { + this.body.innerHTML = '

      ' + (browser.ie ? ' ' : '
      ') + '

      ' + this.body.innerHTML; + + } else { + var p = me.document.createElement('p'); + while (child) { + while (child && (child.nodeType == 3 || child.nodeType == 1 && dtd.p[child.tagName] && !dtd.$cdata[child.tagName])) { + tmpNode = child.nextSibling; + p.appendChild(child); + child = tmpNode; + } + if (p.firstChild) { + if (!child) { + me.body.appendChild(p); + break; + } else { + child.parentNode.insertBefore(p, child); + p = me.document.createElement('p'); + } + } + child = child.nextSibling; + } + } + } + me.fireEvent('aftersetcontent'); + me.fireEvent('contentchange'); + + !notFireSelectionchange && me._selectionChange(); + //清除保存的选区 + me._bakRange = me._bakIERange = me._bakNativeRange = null; + //trace:1742 setContent后gecko能得到焦点问题 + var geckoSel; + if (browser.gecko && (geckoSel = this.selection.getNative())) { + geckoSel.removeAllRanges(); + } + if(me.options.autoSyncData){ + me.form && setValue(me.form,me); + } + }, + + /** + * 让编辑器获得焦点,默认focus到编辑器头部 + * @method focus + * @example + * ```javascript + * editor.focus() + * ``` + */ + + /** + * 让编辑器获得焦点,toEnd确定focus位置 + * @method focus + * @param { Boolean } toEnd 默认focus到编辑器头部,toEnd为true时focus到内容尾部 + * @example + * ```javascript + * editor.focus(true) + * ``` + */ + focus: function (toEnd) { + try { + var me = this, + rng = me.selection.getRange(); + if (toEnd) { + var node = me.body.lastChild; + if(node && node.nodeType == 1 && !dtd.$empty[node.tagName]){ + if(domUtils.isEmptyBlock(node)){ + rng.setStartAtFirst(node) + }else{ + rng.setStartAtLast(node) + } + rng.collapse(true); + } + rng.setCursor(true); + } else { + if(!rng.collapsed && domUtils.isBody(rng.startContainer) && rng.startOffset == 0){ + + var node = me.body.firstChild; + if(node && node.nodeType == 1 && !dtd.$empty[node.tagName]){ + rng.setStartAtFirst(node).collapse(true); + } + } + + rng.select(true); + + } + this.fireEvent('focus selectionchange'); + } catch (e) { + } + + }, + isFocus:function(){ + return this.selection.isFocus(); + }, + blur:function(){ + var sel = this.selection.getNative(); + if(sel.empty && browser.ie){ + var nativeRng = document.body.createTextRange(); + nativeRng.moveToElementText(document.body); + nativeRng.collapse(true); + nativeRng.select(); + sel.empty() + }else{ + sel.removeAllRanges() + } + + //this.fireEvent('blur selectionchange'); + }, + /** + * 初始化UE事件及部分事件代理 + * @method _initEvents + * @private + */ + _initEvents: function () { + var me = this, + doc = me.document, + win = me.window; + me._proxyDomEvent = utils.bind(me._proxyDomEvent, me); + domUtils.on(doc, ['click', 'contextmenu', 'mousedown', 'keydown', 'keyup', 'keypress', 'mouseup', 'mouseover', 'mouseout', 'selectstart'], me._proxyDomEvent); + domUtils.on(win, ['focus', 'blur'], me._proxyDomEvent); + domUtils.on(me.body,'drop',function(e){ + //阻止ff下默认的弹出新页面打开图片 + if(browser.gecko && e.stopPropagation) { e.stopPropagation(); } + me.fireEvent('contentchange') + }); + domUtils.on(doc, ['mouseup', 'keydown'], function (evt) { + //特殊键不触发selectionchange + if (evt.type == 'keydown' && (evt.ctrlKey || evt.metaKey || evt.shiftKey || evt.altKey)) { + return; + } + if (evt.button == 2)return; + me._selectionChange(250, evt); + }); + }, + /** + * 触发事件代理 + * @method _proxyDomEvent + * @private + * @return { * } fireEvent的返回值 + * @see UE.EventBase:fireEvent(String) + */ + _proxyDomEvent: function (evt) { + if(this.fireEvent('before' + evt.type.replace(/^on/, '').toLowerCase()) === false){ + return false; + } + if(this.fireEvent(evt.type.replace(/^on/, ''), evt) === false){ + return false; + } + return this.fireEvent('after' + evt.type.replace(/^on/, '').toLowerCase()) + }, + /** + * 变化选区 + * @method _selectionChange + * @private + */ + _selectionChange: function (delay, evt) { + var me = this; + //有光标才做selectionchange 为了解决未focus时点击source不能触发更改工具栏状态的问题(source命令notNeedUndo=1) +// if ( !me.selection.isFocus() ){ +// return; +// } + + + var hackForMouseUp = false; + var mouseX, mouseY; + if (browser.ie && browser.version < 9 && evt && evt.type == 'mouseup') { + var range = this.selection.getRange(); + if (!range.collapsed) { + hackForMouseUp = true; + mouseX = evt.clientX; + mouseY = evt.clientY; + } + } + clearTimeout(_selectionChangeTimer); + _selectionChangeTimer = setTimeout(function () { + if (!me.selection || !me.selection.getNative()) { + return; + } + //修复一个IE下的bug: 鼠标点击一段已选择的文本中间时,可能在mouseup后的一段时间内取到的range是在selection的type为None下的错误值. + //IE下如果用户是拖拽一段已选择文本,则不会触发mouseup事件,所以这里的特殊处理不会对其有影响 + var ieRange; + if (hackForMouseUp && me.selection.getNative().type == 'None') { + ieRange = me.document.body.createTextRange(); + try { + ieRange.moveToPoint(mouseX, mouseY); + } catch (ex) { + ieRange = null; + } + } + var bakGetIERange; + if (ieRange) { + bakGetIERange = me.selection.getIERange; + me.selection.getIERange = function () { + return ieRange; + }; + } + me.selection.cache(); + if (bakGetIERange) { + me.selection.getIERange = bakGetIERange; + } + if (me.selection._cachedRange && me.selection._cachedStartElement) { + me.fireEvent('beforeselectionchange'); + // 第二个参数causeByUi为true代表由用户交互造成的selectionchange. + me.fireEvent('selectionchange', !!evt); + me.fireEvent('afterselectionchange'); + me.selection.clear(); + } + }, delay || 50); + }, + + /** + * 执行编辑命令 + * @method _callCmdFn + * @private + * @param { String } fnName 函数名称 + * @param { * } args 传给命令函数的参数 + * @return { * } 返回命令函数运行的返回值 + */ + _callCmdFn: function (fnName, args) { + var cmdName = args[0].toLowerCase(), + cmd, cmdFn; + cmd = this.commands[cmdName] || UE.commands[cmdName]; + cmdFn = cmd && cmd[fnName]; + //没有querycommandstate或者没有command的都默认返回0 + if ((!cmd || !cmdFn) && fnName == 'queryCommandState') { + return 0; + } else if (cmdFn) { + return cmdFn.apply(this, args); + } + }, + + /** + * 执行编辑命令cmdName,完成富文本编辑效果 + * @method execCommand + * @param { String } cmdName 需要执行的命令 + * @remind 具体命令的使用请参考命令列表 + * @return { * } 返回命令函数运行的返回值 + * @example + * ```javascript + * editor.execCommand(cmdName); + * ``` + */ + execCommand: function (cmdName) { + cmdName = cmdName.toLowerCase(); + var me = this, + result, + cmd = me.commands[cmdName] || UE.commands[cmdName]; + if (!cmd || !cmd.execCommand) { + return null; + } + if (!cmd.notNeedUndo && !me.__hasEnterExecCommand) { + me.__hasEnterExecCommand = true; + if (me.queryCommandState.apply(me,arguments) != -1) { + me.fireEvent('saveScene'); + me.fireEvent.apply(me, ['beforeexeccommand', cmdName].concat(arguments)); + result = this._callCmdFn('execCommand', arguments); + //保存场景时,做了内容对比,再看是否进行contentchange触发,这里多触发了一次,去掉 +// (!cmd.ignoreContentChange && !me._ignoreContentChange) && me.fireEvent('contentchange'); + me.fireEvent.apply(me, ['afterexeccommand', cmdName].concat(arguments)); + me.fireEvent('saveScene'); + } + me.__hasEnterExecCommand = false; + } else { + result = this._callCmdFn('execCommand', arguments); + (!me.__hasEnterExecCommand && !cmd.ignoreContentChange && !me._ignoreContentChange) && me.fireEvent('contentchange') + } + (!me.__hasEnterExecCommand && !cmd.ignoreContentChange && !me._ignoreContentChange) && me._selectionChange(); + return result; + }, + + /** + * 根据传入的command命令,查选编辑器当前的选区,返回命令的状态 + * @method queryCommandState + * @param { String } cmdName 需要查询的命令名称 + * @remind 具体命令的使用请参考命令列表 + * @return { Number } number 返回放前命令的状态,返回值三种情况:(-1|0|1) + * @example + * ```javascript + * editor.queryCommandState(cmdName) => (-1|0|1) + * ``` + * @see COMMAND.LIST + */ + queryCommandState: function (cmdName) { + return this._callCmdFn('queryCommandState', arguments); + }, + + /** + * 根据传入的command命令,查选编辑器当前的选区,根据命令返回相关的值 + * @method queryCommandValue + * @param { String } cmdName 需要查询的命令名称 + * @remind 具体命令的使用请参考命令列表 + * @remind 只有部分插件有此方法 + * @return { * } 返回每个命令特定的当前状态值 + * @grammar editor.queryCommandValue(cmdName) => {*} + * @see COMMAND.LIST + */ + queryCommandValue: function (cmdName) { + return this._callCmdFn('queryCommandValue', arguments); + }, + + /** + * 检查编辑区域中是否有内容 + * @method hasContents + * @remind 默认有文本内容,或者有以下节点都不认为是空 + * table,ul,ol,dl,iframe,area,base,col,hr,img,embed,input,link,meta,param + * @return { Boolean } 检查有内容返回true,否则返回false + * @example + * ```javascript + * editor.hasContents() + * ``` + */ + + /** + * 检查编辑区域中是否有内容,若包含参数tags中的节点类型,直接返回true + * @method hasContents + * @param { Array } tags 传入数组判断时用到的节点类型 + * @return { Boolean } 若文档中包含tags数组里对应的tag,返回true,否则返回false + * @example + * ```javascript + * editor.hasContents(['span']); + * ``` + */ + hasContents: function (tags) { + if (tags) { + for (var i = 0, ci; ci = tags[i++];) { + if (this.document.getElementsByTagName(ci).length > 0) { + return true; + } + } + } + if (!domUtils.isEmptyBlock(this.body)) { + return true + } + //随时添加,定义的特殊标签如果存在,不能认为是空 + tags = ['div']; + for (i = 0; ci = tags[i++];) { + var nodes = domUtils.getElementsByTagName(this.document, ci); + for (var n = 0, cn; cn = nodes[n++];) { + if (domUtils.isCustomeNode(cn)) { + return true; + } + } + } + return false; + }, + + /** + * 重置编辑器,可用来做多个tab使用同一个编辑器实例 + * @method reset + * @remind 此方法会清空编辑器内容,清空回退列表,会触发reset事件 + * @example + * ```javascript + * editor.reset() + * ``` + */ + reset: function () { + this.fireEvent('reset'); + }, + + /** + * 设置当前编辑区域可以编辑 + * @method setEnabled + * @example + * ```javascript + * editor.setEnabled() + * ``` + */ + setEnabled: function () { + var me = this, range; + if (me.body.contentEditable == 'false') { + me.body.contentEditable = true; + range = me.selection.getRange(); + //有可能内容丢失了 + try { + range.moveToBookmark(me.lastBk); + delete me.lastBk + } catch (e) { + range.setStartAtFirst(me.body).collapse(true) + } + range.select(true); + if (me.bkqueryCommandState) { + me.queryCommandState = me.bkqueryCommandState; + delete me.bkqueryCommandState; + } + if (me.bkqueryCommandValue) { + me.queryCommandValue = me.bkqueryCommandValue; + delete me.bkqueryCommandValue; + } + me.fireEvent('selectionchange'); + } + }, + enable: function () { + return this.setEnabled(); + }, + + /** 设置当前编辑区域不可编辑 + * @method setDisabled + */ + + /** 设置当前编辑区域不可编辑,except中的命令除外 + * @method setDisabled + * @param { String } except 例外命令的字符串 + * @remind 即使设置了disable,此处配置的例外命令仍然可以执行 + * @example + * ```javascript + * editor.setDisabled('bold'); //禁用工具栏中除加粗之外的所有功能 + * ``` + */ + + /** 设置当前编辑区域不可编辑,except中的命令除外 + * @method setDisabled + * @param { Array } except 例外命令的字符串数组,数组中的命令仍然可以执行 + * @remind 即使设置了disable,此处配置的例外命令仍然可以执行 + * @example + * ```javascript + * editor.setDisabled(['bold','insertimage']); //禁用工具栏中除加粗和插入图片之外的所有功能 + * ``` + */ + setDisabled: function (except) { + var me = this; + except = except ? utils.isArray(except) ? except : [except] : []; + if (me.body.contentEditable == 'true') { + if (!me.lastBk) { + me.lastBk = me.selection.getRange().createBookmark(true); + } + me.body.contentEditable = false; + me.bkqueryCommandState = me.queryCommandState; + me.bkqueryCommandValue = me.queryCommandValue; + me.queryCommandState = function (type) { + if (utils.indexOf(except, type) != -1) { + return me.bkqueryCommandState.apply(me, arguments); + } + return -1; + }; + me.queryCommandValue = function (type) { + if (utils.indexOf(except, type) != -1) { + return me.bkqueryCommandValue.apply(me, arguments); + } + return null; + }; + me.fireEvent('selectionchange'); + } + }, + disable: function (except) { + return this.setDisabled(except); + }, + + /** + * 设置默认内容 + * @method _setDefaultContent + * @private + * @param { String } cont 要存入的内容 + */ + _setDefaultContent: function () { + function clear() { + var me = this; + if (me.document.getElementById('initContent')) { + me.body.innerHTML = '

      ' + (ie ? '' : '
      ') + '

      '; + me.removeListener('firstBeforeExecCommand focus', clear); + setTimeout(function () { + me.focus(); + me._selectionChange(); + }, 0) + } + } + + return function (cont) { + var me = this; + me.body.innerHTML = '

      ' + cont + '

      '; + + me.addListener('firstBeforeExecCommand focus', clear); + } + }(), + + /** + * 显示编辑器 + * @method setShow + * @example + * ```javascript + * editor.setShow() + * ``` + */ + setShow: function () { + var me = this, range = me.selection.getRange(); + if (me.container.style.display == 'none') { + //有可能内容丢失了 + try { + range.moveToBookmark(me.lastBk); + delete me.lastBk + } catch (e) { + range.setStartAtFirst(me.body).collapse(true) + } + //ie下focus实效,所以做了个延迟 + setTimeout(function () { + range.select(true); + }, 100); + me.container.style.display = ''; + } + + }, + show: function () { + return this.setShow(); + }, + /** + * 隐藏编辑器 + * @method setHide + * @example + * ```javascript + * editor.setHide() + * ``` + */ + setHide: function () { + var me = this; + if (!me.lastBk) { + me.lastBk = me.selection.getRange().createBookmark(true); + } + me.container.style.display = 'none' + }, + hide: function () { + return this.setHide(); + }, + + /** + * 根据指定的路径,获取对应的语言资源 + * @method getLang + * @param { String } path 路径根据的是lang目录下的语言文件的路径结构 + * @return { Object | String } 根据路径返回语言资源的Json格式对象或者语言字符串 + * @example + * ```javascript + * editor.getLang('contextMenu.delete'); //如果当前是中文,那返回是的是'删除' + * ``` + */ + getLang: function (path) { + var lang = UE.I18N[this.options.lang]; + if (!lang) { + throw Error("not import language file"); + } + path = (path || "").split("."); + for (var i = 0, ci; ci = path[i++];) { + lang = lang[ci]; + if (!lang)break; + } + return lang; + }, + + /** + * 计算编辑器html内容字符串的长度 + * @method getContentLength + * @return { Number } 返回计算的长度 + * @example + * ```javascript + * //编辑器html内容

      132

      + * editor.getContentLength() //返回27 + * ``` + */ + /** + * 计算编辑器当前纯文本内容的长度 + * @method getContentLength + * @param { Boolean } ingoneHtml 传入true时,只按照纯文本来计算 + * @return { Number } 返回计算的长度,内容中有hr/img/iframe标签,长度加1 + * @example + * ```javascript + * //编辑器html内容

      132

      + * editor.getContentLength() //返回3 + * ``` + */ + getContentLength: function (ingoneHtml, tagNames) { + var count = this.getContent(false,false,true).length; + if (ingoneHtml) { + tagNames = (tagNames || []).concat([ 'hr', 'img', 'iframe']); + count = this.getContentTxt().replace(/[\t\r\n]+/g, '').length; + for (var i = 0, ci; ci = tagNames[i++];) { + count += this.document.getElementsByTagName(ci).length; + } + } + return count; + }, + + /** + * 注册输入过滤规则 + * @method addInputRule + * @param { Function } rule 要添加的过滤规则 + * @example + * ```javascript + * editor.addInputRule(function(root){ + * $.each(root.getNodesByTagName('div'),function(i,node){ + * node.tagName="p"; + * }); + * }); + * ``` + */ + addInputRule: function (rule) { + this.inputRules.push(rule); + }, + + /** + * 执行注册的过滤规则 + * @method filterInputRule + * @param { UE.uNode } root 要过滤的uNode节点 + * @remind 执行editor.setContent方法和执行'inserthtml'命令后,会运行该过滤函数 + * @example + * ```javascript + * editor.filterInputRule(editor.body); + * ``` + * @see UE.Editor:addInputRule + */ + filterInputRule: function (root) { + for (var i = 0, ci; ci = this.inputRules[i++];) { + ci.call(this, root) + } + }, + + /** + * 注册输出过滤规则 + * @method addOutputRule + * @param { Function } rule 要添加的过滤规则 + * @example + * ```javascript + * editor.addOutputRule(function(root){ + * $.each(root.getNodesByTagName('p'),function(i,node){ + * node.tagName="div"; + * }); + * }); + * ``` + */ + addOutputRule: function (rule) { + this.outputRules.push(rule) + }, + + /** + * 根据输出过滤规则,过滤编辑器内容 + * @method filterOutputRule + * @remind 执行editor.getContent方法的时候,会先运行该过滤函数 + * @param { UE.uNode } root 要过滤的uNode节点 + * @example + * ```javascript + * editor.filterOutputRule(editor.body); + * ``` + * @see UE.Editor:addOutputRule + */ + filterOutputRule: function (root) { + for (var i = 0, ci; ci = this.outputRules[i++];) { + ci.call(this, root) + } + }, + + /** + * 根据action名称获取请求的路径 + * @method getActionUrl + * @remind 假如没有设置serverUrl,会根据imageUrl设置默认的controller路径 + * @param { String } action action名称 + * @example + * ```javascript + * editor.getActionUrl('config'); //返回 "/ueditor/php/controller.php?action=config" + * editor.getActionUrl('image'); //返回 "/ueditor/php/controller.php?action=uplaodimage" + * editor.getActionUrl('scrawl'); //返回 "/ueditor/php/controller.php?action=uplaodscrawl" + * editor.getActionUrl('imageManager'); //返回 "/ueditor/php/controller.php?action=listimage" + * ``` + */ + getActionUrl: function(action){ + var actionName = this.getOpt(action) || action, + imageUrl = this.getOpt('imageUrl'), + serverUrl = this.getOpt('serverUrl'); + + if(!serverUrl && imageUrl) { + serverUrl = imageUrl.replace(/^(.*[\/]).+([\.].+)$/, '$1controller$2'); + } + + if(serverUrl) { + serverUrl = serverUrl + (serverUrl.indexOf('?') == -1 ? '?':'&') + 'action=' + (actionName || ''); + return utils.formatUrl(serverUrl); + } else { + return ''; + } + } + }; + utils.inherits(Editor, EventBase); +})(); + + +// core/Editor.defaultoptions.js +//维护编辑器一下默认的不在插件中的配置项 +UE.Editor.defaultOptions = function(editor){ + + var _url = editor.options.UEDITOR_HOME_URL; + return { + isShow: true, + initialContent: '', + initialStyle:'', + autoClearinitialContent: false, + iframeCssUrl: _url + 'themes/iframe.css', + textarea: 'editorValue', + focus: false, + focusInEnd: true, + autoClearEmptyNode: true, + fullscreen: false, + readonly: false, + zIndex: 999, + imagePopup: true, + enterTag: 'p', + customDomain: false, + lang: 'zh-cn', + langPath: _url + 'lang/', + theme: 'default', + themePath: _url + 'themes/', + allHtmlEnabled: false, + scaleEnabled: false, + tableNativeEditInFF: false, + autoSyncData : true, + fileNameFormat: '{time}{rand:6}' + } +}; + +// core/loadconfig.js +(function(){ + + UE.Editor.prototype.loadServerConfig = function(){ + var me = this; + setTimeout(function(){ + try{ + me.options.imageUrl && me.setOpt('serverUrl', me.options.imageUrl.replace(/^(.*[\/]).+([\.].+)$/, '$1controller$2')); + + var configUrl = me.getActionUrl('config'), + isJsonp = utils.isCrossDomainUrl(configUrl); + + /* 发出ajax请求 */ + me._serverConfigLoaded = false; + + configUrl && UE.ajax.request(configUrl,{ + 'method': 'GET', + 'dataType': isJsonp ? 'jsonp':'', + 'onsuccess':function(r){ + try { + var config = isJsonp ? r:eval("("+r.responseText+")"); + utils.extend(me.options, config); + me.fireEvent('serverConfigLoaded'); + me._serverConfigLoaded = true; + } catch (e) { + showErrorMsg(me.getLang('loadconfigFormatError')); + } + }, + 'onerror':function(){ + showErrorMsg(me.getLang('loadconfigHttpError')); + } + }); + } catch(e){ + showErrorMsg(me.getLang('loadconfigError')); + } + }); + + function showErrorMsg(msg) { + console && console.error(msg); + //me.fireEvent('showMessage', { + // 'title': msg, + // 'type': 'error' + //}); + } + }; + + UE.Editor.prototype.isServerConfigLoaded = function(){ + var me = this; + return me._serverConfigLoaded || false; + }; + + UE.Editor.prototype.afterConfigReady = function(handler){ + if (!handler || !utils.isFunction(handler)) return; + var me = this; + var readyHandler = function(){ + handler.apply(me, arguments); + me.removeListener('serverConfigLoaded', readyHandler); + }; + + if (me.isServerConfigLoaded()) { + handler.call(me, 'serverConfigLoaded'); + } else { + me.addListener('serverConfigLoaded', readyHandler); + } + }; + +})(); + + +// core/ajax.js +/** + * @file + * @module UE.ajax + * @since 1.2.6.1 + */ + +/** + * 提供对ajax请求的支持 + * @module UE.ajax + */ +UE.ajax = function() { + + //创建一个ajaxRequest对象 + var fnStr = 'XMLHttpRequest()'; + try { + new ActiveXObject("Msxml2.XMLHTTP"); + fnStr = 'ActiveXObject(\'Msxml2.XMLHTTP\')'; + } catch (e) { + try { + new ActiveXObject("Microsoft.XMLHTTP"); + fnStr = 'ActiveXObject(\'Microsoft.XMLHTTP\')' + } catch (e) { + } + } + var creatAjaxRequest = new Function('return new ' + fnStr); + + + /** + * 将json参数转化成适合ajax提交的参数列表 + * @param json + */ + function json2str(json) { + var strArr = []; + for (var i in json) { + //忽略默认的几个参数 + if(i=="method" || i=="timeout" || i=="async" || i=="dataType" || i=="callback") continue; + //忽略控制 + if(json[i] == undefined || json[i] == null) continue; + //传递过来的对象和函数不在提交之列 + if (!((typeof json[i]).toLowerCase() == "function" || (typeof json[i]).toLowerCase() == "object")) { + strArr.push( encodeURIComponent(i) + "="+encodeURIComponent(json[i]) ); + } else if (utils.isArray(json[i])) { + //支持传数组内容 + for(var j = 0; j < json[i].length; j++) { + strArr.push( encodeURIComponent(i) + "[]="+encodeURIComponent(json[i][j]) ); + } + } + } + return strArr.join("&"); + } + + function doAjax(url, ajaxOptions) { + var xhr = creatAjaxRequest(), + //是否超时 + timeIsOut = false, + //默认参数 + defaultAjaxOptions = { + method:"POST", + timeout:5000, + async:true, + data:{},//需要传递对象的话只能覆盖 + onsuccess:function() { + }, + onerror:function() { + } + }; + + if (typeof url === "object") { + ajaxOptions = url; + url = ajaxOptions.url; + } + if (!xhr || !url) return; + var ajaxOpts = ajaxOptions ? utils.extend(defaultAjaxOptions,ajaxOptions) : defaultAjaxOptions; + + var submitStr = json2str(ajaxOpts); // { name:"Jim",city:"Beijing" } --> "name=Jim&city=Beijing" + //如果用户直接通过data参数传递json对象过来,则也要将此json对象转化为字符串 + if (!utils.isEmptyObject(ajaxOpts.data)){ + submitStr += (submitStr? "&":"") + json2str(ajaxOpts.data); + } + //超时检测 + var timerID = setTimeout(function() { + if (xhr.readyState != 4) { + timeIsOut = true; + xhr.abort(); + clearTimeout(timerID); + } + }, ajaxOpts.timeout); + + var method = ajaxOpts.method.toUpperCase(); + var str = url + (url.indexOf("?")==-1?"?":"&") + (method=="POST"?"":submitStr+ "&noCache=" + +new Date); + xhr.open(method, str, ajaxOpts.async); + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + if (!timeIsOut && xhr.status == 200) { + ajaxOpts.onsuccess(xhr); + } else { + ajaxOpts.onerror(xhr); + } + } + }; + if (method == "POST") { + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + xhr.send(submitStr); + } else { + xhr.send(null); + } + } + + function doJsonp(url, opts) { + + var successhandler = opts.onsuccess || function(){}, + scr = document.createElement('SCRIPT'), + options = opts || {}, + charset = options['charset'], + callbackField = options['jsonp'] || 'callback', + callbackFnName, + timeOut = options['timeOut'] || 0, + timer, + reg = new RegExp('(\\?|&)' + callbackField + '=([^&]*)'), + matches; + + if (utils.isFunction(successhandler)) { + callbackFnName = 'bd__editor__' + Math.floor(Math.random() * 2147483648).toString(36); + window[callbackFnName] = getCallBack(0); + } else if(utils.isString(successhandler)){ + callbackFnName = successhandler; + } else { + if (matches = reg.exec(url)) { + callbackFnName = matches[2]; + } + } + + url = url.replace(reg, '\x241' + callbackField + '=' + callbackFnName); + + if (url.search(reg) < 0) { + url += (url.indexOf('?') < 0 ? '?' : '&') + callbackField + '=' + callbackFnName; + } + + var queryStr = json2str(opts); // { name:"Jim",city:"Beijing" } --> "name=Jim&city=Beijing" + //如果用户直接通过data参数传递json对象过来,则也要将此json对象转化为字符串 + if (!utils.isEmptyObject(opts.data)){ + queryStr += (queryStr? "&":"") + json2str(opts.data); + } + if (queryStr) { + url = url.replace(/\?/, '?' + queryStr + '&'); + } + + scr.onerror = getCallBack(1); + if( timeOut ){ + timer = setTimeout(getCallBack(1), timeOut); + } + createScriptTag(scr, url, charset); + + function createScriptTag(scr, url, charset) { + scr.setAttribute('type', 'text/javascript'); + scr.setAttribute('defer', 'defer'); + charset && scr.setAttribute('charset', charset); + scr.setAttribute('src', url); + document.getElementsByTagName('head')[0].appendChild(scr); + } + + function getCallBack(onTimeOut){ + return function(){ + try { + if(onTimeOut){ + options.onerror && options.onerror(); + }else{ + try{ + clearTimeout(timer); + successhandler.apply(window, arguments); + } catch (e){} + } + } catch (exception) { + options.onerror && options.onerror.call(window, exception); + } finally { + options.oncomplete && options.oncomplete.apply(window, arguments); + scr.parentNode && scr.parentNode.removeChild(scr); + window[callbackFnName] = null; + try { + delete window[callbackFnName]; + }catch(e){} + } + } + } + } + + return { + /** + * 根据给定的参数项,向指定的url发起一个ajax请求。 ajax请求完成后,会根据请求结果调用相应回调: 如果请求 + * 成功, 则调用onsuccess回调, 失败则调用 onerror 回调 + * @method request + * @param { URLString } url ajax请求的url地址 + * @param { Object } ajaxOptions ajax请求选项的键值对,支持的选项如下: + * @example + * ```javascript + * //向sayhello.php发起一个异步的Ajax GET请求, 请求超时时间为10s, 请求完成后执行相应的回调。 + * UE.ajax.requeset( 'sayhello.php', { + * + * //请求方法。可选值: 'GET', 'POST',默认值是'POST' + * method: 'GET', + * + * //超时时间。 默认为5000, 单位是ms + * timeout: 10000, + * + * //是否是异步请求。 true为异步请求, false为同步请求 + * async: true, + * + * //请求携带的数据。如果请求为GET请求, data会经过stringify后附加到请求url之后。 + * data: { + * name: 'ueditor' + * }, + * + * //请求成功后的回调, 该回调接受当前的XMLHttpRequest对象作为参数。 + * onsuccess: function ( xhr ) { + * console.log( xhr.responseText ); + * }, + * + * //请求失败或者超时后的回调。 + * onerror: function ( xhr ) { + * alert( 'Ajax请求失败' ); + * } + * + * } ); + * ``` + */ + + /** + * 根据给定的参数项发起一个ajax请求, 参数项里必须包含一个url地址。 ajax请求完成后,会根据请求结果调用相应回调: 如果请求 + * 成功, 则调用onsuccess回调, 失败则调用 onerror 回调。 + * @method request + * @warning 如果在参数项里未提供一个key为“url”的地址值,则该请求将直接退出。 + * @param { Object } ajaxOptions ajax请求选项的键值对,支持的选项如下: + * @example + * ```javascript + * + * //向sayhello.php发起一个异步的Ajax POST请求, 请求超时时间为5s, 请求完成后不执行任何回调。 + * UE.ajax.requeset( 'sayhello.php', { + * + * //请求的地址, 该项是必须的。 + * url: 'sayhello.php' + * + * } ); + * ``` + */ + request:function(url, opts) { + if (opts && opts.dataType == 'jsonp') { + doJsonp(url, opts); + } else { + doAjax(url, opts); + } + }, + getJSONP:function(url, data, fn) { + var opts = { + 'data': data, + 'oncomplete': fn + }; + doJsonp(url, opts); + } + }; + + +}(); + + +// core/filterword.js +/** + * UE过滤word的静态方法 + * @file + */ + +/** + * UEditor公用空间,UEditor所有的功能都挂载在该空间下 + * @module UE + */ + + +/** + * 根据传入html字符串过滤word + * @module UE + * @since 1.2.6.1 + * @method filterWord + * @param { String } html html字符串 + * @return { String } 已过滤后的结果字符串 + * @example + * ```javascript + * UE.filterWord(html); + * ``` + */ +var filterWord = UE.filterWord = function () { + + //是否是word过来的内容 + function isWordDocument( str ) { + return /(class="?Mso|style="[^"]*\bmso\-|w:WordDocument|<(v|o):|lang=)/ig.test( str ); + } + //去掉小数 + function transUnit( v ) { + v = v.replace( /[\d.]+\w+/g, function ( m ) { + return utils.transUnitToPx(m); + } ); + return v; + } + + function filterPasteWord( str ) { + return str.replace(/[\t\r\n]+/g,' ') + .replace( //ig, "" ) + //转换图片 + .replace(/]*>[\s\S]*?.<\/v:shape>/gi,function(str){ + //opera能自己解析出image所这里直接返回空 + if(browser.opera){ + return ''; + } + try{ + //有可能是bitmap占为图,无用,直接过滤掉,主要体现在粘贴excel表格中 + if(/Bitmap/i.test(str)){ + return ''; + } + var width = str.match(/width:([ \d.]*p[tx])/i)[1], + height = str.match(/height:([ \d.]*p[tx])/i)[1], + src = str.match(/src=\s*"([^"]*)"/i)[1]; + return ''; + } catch(e){ + return ''; + } + }) + //针对wps添加的多余标签处理 + .replace(/<\/?div[^>]*>/g,'') + //去掉多余的属性 + .replace( /v:\w+=(["']?)[^'"]+\1/g, '' ) + .replace( /<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|xml|meta|link|style|\w+:\w+)(?=[\s\/>]))[^>]*>/gi, "" ) + .replace( /

      ]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi, "

      $1

      " ) + //去掉多余的属性 + .replace( /\s+(class|lang|align)\s*=\s*(['"]?)([\w-]+)\2/ig, function(str,name,marks,val){ + //保留list的标示 + return name == 'class' && val == 'MsoListParagraph' ? str : '' + }) + //清除多余的font/span不能匹配 有可能是空格 + .replace( /<(font|span)[^>]*>(\s*)<\/\1>/gi, function(a,b,c){ + return c.replace(/[\t\r\n ]+/g,' ') + }) + //处理style的问题 + .replace( /(<[a-z][^>]*)\sstyle=(["'])([^\2]*?)\2/gi, function( str, tag, tmp, style ) { + var n = [], + s = style.replace( /^\s+|\s+$/, '' ) + .replace(/'/g,'\'') + .replace( /"/gi, "'" ) + .replace(/[\d.]+(cm|pt)/g,function(str){ + return utils.transUnitToPx(str) + }) + .split( /;\s*/g ); + + for ( var i = 0,v; v = s[i];i++ ) { + + var name, value, + parts = v.split( ":" ); + + if ( parts.length == 2 ) { + name = parts[0].toLowerCase(); + value = parts[1].toLowerCase(); + if(/^(background)\w*/.test(name) && value.replace(/(initial|\s)/g,'').length == 0 + || + /^(margin)\w*/.test(name) && /^0\w+$/.test(value) + ){ + continue; + } + + switch ( name ) { + case "mso-padding-alt": + case "mso-padding-top-alt": + case "mso-padding-right-alt": + case "mso-padding-bottom-alt": + case "mso-padding-left-alt": + case "mso-margin-alt": + case "mso-margin-top-alt": + case "mso-margin-right-alt": + case "mso-margin-bottom-alt": + case "mso-margin-left-alt": + //ie下会出现挤到一起的情况 + //case "mso-table-layout-alt": + case "mso-height": + case "mso-width": + case "mso-vertical-align-alt": + //trace:1819 ff下会解析出padding在table上 + if(!/
      ]/.test(html)) { + return UE.htmlparser(html).children[0] + } else { + return new uNode({ + type:'element', + children:[], + tagName:html + }) + } + }; + uNode.createText = function (data,noTrans) { + return new UE.uNode({ + type:'text', + 'data':noTrans ? data : utils.unhtml(data || '') + }) + }; + function nodeToHtml(node, arr, formatter, current) { + switch (node.type) { + case 'root': + for (var i = 0, ci; ci = node.children[i++];) { + //插入新行 + if (formatter && ci.type == 'element' && !dtd.$inlineWithA[ci.tagName] && i > 1) { + insertLine(arr, current, true); + insertIndent(arr, current) + } + nodeToHtml(ci, arr, formatter, current) + } + break; + case 'text': + isText(node, arr); + break; + case 'element': + isElement(node, arr, formatter, current); + break; + case 'comment': + isComment(node, arr, formatter); + } + return arr; + } + + function isText(node, arr) { + if(node.parentNode.tagName == 'pre'){ + //源码模式下输入html标签,不能做转换处理,直接输出 + arr.push(node.data) + }else{ + arr.push(notTransTagName[node.parentNode.tagName] ? utils.html(node.data) : node.data.replace(/[ ]{2}/g,'  ')) + } + + } + + function isElement(node, arr, formatter, current) { + var attrhtml = ''; + if (node.attrs) { + attrhtml = []; + var attrs = node.attrs; + for (var a in attrs) { + //这里就针对 + //

      '

      + //这里边的\"做转换,要不用innerHTML直接被截断了,属性src + //有可能做的不够 + attrhtml.push(a + (attrs[a] !== undefined ? '="' + (notTransAttrs[a] ? utils.html(attrs[a]).replace(/["]/g, function (a) { + return '"' + }) : utils.unhtml(attrs[a])) + '"' : '')) + } + attrhtml = attrhtml.join(' '); + } + arr.push('<' + node.tagName + + (attrhtml ? ' ' + attrhtml : '') + + (dtd.$empty[node.tagName] ? '\/' : '' ) + '>' + ); + //插入新行 + if (formatter && !dtd.$inlineWithA[node.tagName] && node.tagName != 'pre') { + if(node.children && node.children.length){ + current = insertLine(arr, current, true); + insertIndent(arr, current) + } + + } + if (node.children && node.children.length) { + for (var i = 0, ci; ci = node.children[i++];) { + if (formatter && ci.type == 'element' && !dtd.$inlineWithA[ci.tagName] && i > 1) { + insertLine(arr, current); + insertIndent(arr, current) + } + nodeToHtml(ci, arr, formatter, current) + } + } + if (!dtd.$empty[node.tagName]) { + if (formatter && !dtd.$inlineWithA[node.tagName] && node.tagName != 'pre') { + + if(node.children && node.children.length){ + current = insertLine(arr, current); + insertIndent(arr, current) + } + } + arr.push('<\/' + node.tagName + '>'); + } + + } + + function isComment(node, arr) { + arr.push(''); + } + + function getNodeById(root, id) { + var node; + if (root.type == 'element' && root.getAttr('id') == id) { + return root; + } + if (root.children && root.children.length) { + for (var i = 0, ci; ci = root.children[i++];) { + if (node = getNodeById(ci, id)) { + return node; + } + } + } + } + + function getNodesByTagName(node, tagName, arr) { + if (node.type == 'element' && node.tagName == tagName) { + arr.push(node); + } + if (node.children && node.children.length) { + for (var i = 0, ci; ci = node.children[i++];) { + getNodesByTagName(ci, tagName, arr) + } + } + } + function nodeTraversal(root,fn){ + if(root.children && root.children.length){ + for(var i= 0,ci;ci=root.children[i];){ + nodeTraversal(ci,fn); + //ci被替换的情况,这里就不再走 fn了 + if(ci.parentNode ){ + if(ci.children && ci.children.length){ + fn(ci) + } + if(ci.parentNode) i++ + } + } + }else{ + fn(root) + } + + } + uNode.prototype = { + + /** + * 当前节点对象,转换成html文本 + * @method toHtml + * @return { String } 返回转换后的html字符串 + * @example + * ```javascript + * node.toHtml(); + * ``` + */ + + /** + * 当前节点对象,转换成html文本 + * @method toHtml + * @param { Boolean } formatter 是否格式化返回值 + * @return { String } 返回转换后的html字符串 + * @example + * ```javascript + * node.toHtml( true ); + * ``` + */ + toHtml:function (formatter) { + var arr = []; + nodeToHtml(this, arr, formatter, 0); + return arr.join('') + }, + + /** + * 获取节点的html内容 + * @method innerHTML + * @warning 假如节点的type不是'element',或节点的标签名称不在dtd列表里,直接返回当前节点 + * @return { String } 返回节点的html内容 + * @example + * ```javascript + * var htmlstr = node.innerHTML(); + * ``` + */ + + /** + * 设置节点的html内容 + * @method innerHTML + * @warning 假如节点的type不是'element',或节点的标签名称不在dtd列表里,直接返回当前节点 + * @param { String } htmlstr 传入要设置的html内容 + * @return { UE.uNode } 返回节点本身 + * @example + * ```javascript + * node.innerHTML('text'); + * ``` + */ + innerHTML:function (htmlstr) { + if (this.type != 'element' || dtd.$empty[this.tagName]) { + return this; + } + if (utils.isString(htmlstr)) { + if(this.children){ + for (var i = 0, ci; ci = this.children[i++];) { + ci.parentNode = null; + } + } + this.children = []; + var tmpRoot = UE.htmlparser(htmlstr); + for (var i = 0, ci; ci = tmpRoot.children[i++];) { + this.children.push(ci); + ci.parentNode = this; + } + return this; + } else { + var tmpRoot = new UE.uNode({ + type:'root', + children:this.children + }); + return tmpRoot.toHtml(); + } + }, + + /** + * 获取节点的纯文本内容 + * @method innerText + * @warning 假如节点的type不是'element',或节点的标签名称不在dtd列表里,直接返回当前节点 + * @return { String } 返回节点的存文本内容 + * @example + * ```javascript + * var textStr = node.innerText(); + * ``` + */ + + /** + * 设置节点的纯文本内容 + * @method innerText + * @warning 假如节点的type不是'element',或节点的标签名称不在dtd列表里,直接返回当前节点 + * @param { String } textStr 传入要设置的文本内容 + * @return { UE.uNode } 返回节点本身 + * @example + * ```javascript + * node.innerText('text'); + * ``` + */ + innerText:function (textStr,noTrans) { + if (this.type != 'element' || dtd.$empty[this.tagName]) { + return this; + } + if (textStr) { + if(this.children){ + for (var i = 0, ci; ci = this.children[i++];) { + ci.parentNode = null; + } + } + this.children = []; + this.appendChild(uNode.createText(textStr,noTrans)); + return this; + } else { + return this.toHtml().replace(/<[^>]+>/g, ''); + } + }, + + /** + * 获取当前对象的data属性 + * @method getData + * @return { Object } 若节点的type值是elemenet,返回空字符串,否则返回节点的data属性 + * @example + * ```javascript + * node.getData(); + * ``` + */ + getData:function () { + if (this.type == 'element') + return ''; + return this.data + }, + + /** + * 获取当前节点下的第一个子节点 + * @method firstChild + * @return { UE.uNode } 返回第一个子节点 + * @example + * ```javascript + * node.firstChild(); //返回第一个子节点 + * ``` + */ + firstChild:function () { +// if (this.type != 'element' || dtd.$empty[this.tagName]) { +// return this; +// } + return this.children ? this.children[0] : null; + }, + + /** + * 获取当前节点下的最后一个子节点 + * @method lastChild + * @return { UE.uNode } 返回最后一个子节点 + * @example + * ```javascript + * node.lastChild(); //返回最后一个子节点 + * ``` + */ + lastChild:function () { +// if (this.type != 'element' || dtd.$empty[this.tagName] ) { +// return this; +// } + return this.children ? this.children[this.children.length - 1] : null; + }, + + /** + * 获取和当前节点有相同父亲节点的前一个节点 + * @method previousSibling + * @return { UE.uNode } 返回前一个节点 + * @example + * ```javascript + * node.children[2].previousSibling(); //返回子节点node.children[1] + * ``` + */ + previousSibling : function(){ + var parent = this.parentNode; + for (var i = 0, ci; ci = parent.children[i]; i++) { + if (ci === this) { + return i == 0 ? null : parent.children[i-1]; + } + } + + }, + + /** + * 获取和当前节点有相同父亲节点的后一个节点 + * @method nextSibling + * @return { UE.uNode } 返回后一个节点,找不到返回null + * @example + * ```javascript + * node.children[2].nextSibling(); //如果有,返回子节点node.children[3] + * ``` + */ + nextSibling : function(){ + var parent = this.parentNode; + for (var i = 0, ci; ci = parent.children[i++];) { + if (ci === this) { + return parent.children[i]; + } + } + }, + + /** + * 用新的节点替换当前节点 + * @method replaceChild + * @param { UE.uNode } target 要替换成该节点参数 + * @param { UE.uNode } source 要被替换掉的节点 + * @return { UE.uNode } 返回替换之后的节点对象 + * @example + * ```javascript + * node.replaceChild(newNode, childNode); //用newNode替换childNode,childNode是node的子节点 + * ``` + */ + replaceChild:function (target, source) { + if (this.children) { + if(target.parentNode){ + target.parentNode.removeChild(target); + } + for (var i = 0, ci; ci = this.children[i]; i++) { + if (ci === source) { + this.children.splice(i, 1, target); + source.parentNode = null; + target.parentNode = this; + return target; + } + } + } + }, + + /** + * 在节点的子节点列表最后位置插入一个节点 + * @method appendChild + * @param { UE.uNode } node 要插入的节点 + * @return { UE.uNode } 返回刚插入的子节点 + * @example + * ```javascript + * node.appendChild( newNode ); //在node内插入子节点newNode + * ``` + */ + appendChild:function (node) { + if (this.type == 'root' || (this.type == 'element' && !dtd.$empty[this.tagName])) { + if (!this.children) { + this.children = [] + } + if(node.parentNode){ + node.parentNode.removeChild(node); + } + for (var i = 0, ci; ci = this.children[i]; i++) { + if (ci === node) { + this.children.splice(i, 1); + break; + } + } + this.children.push(node); + node.parentNode = this; + return node; + } + + + }, + + /** + * 在传入节点的前面插入一个节点 + * @method insertBefore + * @param { UE.uNode } target 要插入的节点 + * @param { UE.uNode } source 在该参数节点前面插入 + * @return { UE.uNode } 返回刚插入的子节点 + * @example + * ```javascript + * node.parentNode.insertBefore(newNode, node); //在node节点后面插入newNode + * ``` + */ + insertBefore:function (target, source) { + if (this.children) { + if(target.parentNode){ + target.parentNode.removeChild(target); + } + for (var i = 0, ci; ci = this.children[i]; i++) { + if (ci === source) { + this.children.splice(i, 0, target); + target.parentNode = this; + return target; + } + } + + } + }, + + /** + * 在传入节点的后面插入一个节点 + * @method insertAfter + * @param { UE.uNode } target 要插入的节点 + * @param { UE.uNode } source 在该参数节点后面插入 + * @return { UE.uNode } 返回刚插入的子节点 + * @example + * ```javascript + * node.parentNode.insertAfter(newNode, node); //在node节点后面插入newNode + * ``` + */ + insertAfter:function (target, source) { + if (this.children) { + if(target.parentNode){ + target.parentNode.removeChild(target); + } + for (var i = 0, ci; ci = this.children[i]; i++) { + if (ci === source) { + this.children.splice(i + 1, 0, target); + target.parentNode = this; + return target; + } + + } + } + }, + + /** + * 从当前节点的子节点列表中,移除节点 + * @method removeChild + * @param { UE.uNode } node 要移除的节点引用 + * @param { Boolean } keepChildren 是否保留移除节点的子节点,若传入true,自动把移除节点的子节点插入到移除的位置 + * @return { * } 返回刚移除的子节点 + * @example + * ```javascript + * node.removeChild(childNode,true); //在node的子节点列表中移除child节点,并且吧child的子节点插入到移除的位置 + * ``` + */ + removeChild:function (node,keepChildren) { + if (this.children) { + for (var i = 0, ci; ci = this.children[i]; i++) { + if (ci === node) { + this.children.splice(i, 1); + ci.parentNode = null; + if(keepChildren && ci.children && ci.children.length){ + for(var j= 0,cj;cj=ci.children[j];j++){ + this.children.splice(i+j,0,cj); + cj.parentNode = this; + + } + } + return ci; + } + } + } + }, + + /** + * 获取当前节点所代表的元素属性,即获取attrs对象下的属性值 + * @method getAttr + * @param { String } attrName 要获取的属性名称 + * @return { * } 返回attrs对象下的属性值 + * @example + * ```javascript + * node.getAttr('title'); + * ``` + */ + getAttr:function (attrName) { + return this.attrs && this.attrs[attrName.toLowerCase()] + }, + + /** + * 设置当前节点所代表的元素属性,即设置attrs对象下的属性值 + * @method setAttr + * @param { String } attrName 要设置的属性名称 + * @param { * } attrVal 要设置的属性值,类型视设置的属性而定 + * @return { * } 返回attrs对象下的属性值 + * @example + * ```javascript + * node.setAttr('title','标题'); + * ``` + */ + setAttr:function (attrName, attrVal) { + if (!attrName) { + delete this.attrs; + return; + } + if(!this.attrs){ + this.attrs = {}; + } + if (utils.isObject(attrName)) { + for (var a in attrName) { + if (!attrName[a]) { + delete this.attrs[a] + } else { + this.attrs[a.toLowerCase()] = attrName[a]; + } + } + } else { + if (!attrVal) { + delete this.attrs[attrName] + } else { + this.attrs[attrName.toLowerCase()] = attrVal; + } + + } + }, + + /** + * 获取当前节点在父节点下的位置索引 + * @method getIndex + * @return { Number } 返回索引数值,如果没有父节点,返回-1 + * @example + * ```javascript + * node.getIndex(); + * ``` + */ + getIndex:function(){ + var parent = this.parentNode; + for(var i= 0,ci;ci=parent.children[i];i++){ + if(ci === this){ + return i; + } + } + return -1; + }, + + /** + * 在当前节点下,根据id查找节点 + * @method getNodeById + * @param { String } id 要查找的id + * @return { UE.uNode } 返回找到的节点 + * @example + * ```javascript + * node.getNodeById('textId'); + * ``` + */ + getNodeById:function (id) { + var node; + if (this.children && this.children.length) { + for (var i = 0, ci; ci = this.children[i++];) { + if (node = getNodeById(ci, id)) { + return node; + } + } + } + }, + + /** + * 在当前节点下,根据元素名称查找节点列表 + * @method getNodesByTagName + * @param { String } tagNames 要查找的元素名称 + * @return { Array } 返回找到的节点列表 + * @example + * ```javascript + * node.getNodesByTagName('span'); + * ``` + */ + getNodesByTagName:function (tagNames) { + tagNames = utils.trim(tagNames).replace(/[ ]{2,}/g, ' ').split(' '); + var arr = [], me = this; + utils.each(tagNames, function (tagName) { + if (me.children && me.children.length) { + for (var i = 0, ci; ci = me.children[i++];) { + getNodesByTagName(ci, tagName, arr) + } + } + }); + return arr; + }, + + /** + * 根据样式名称,获取节点的样式值 + * @method getStyle + * @param { String } name 要获取的样式名称 + * @return { String } 返回样式值 + * @example + * ```javascript + * node.getStyle('font-size'); + * ``` + */ + getStyle:function (name) { + var cssStyle = this.getAttr('style'); + if (!cssStyle) { + return '' + } + var reg = new RegExp('(^|;)\\s*' + name + ':([^;]+)','i'); + var match = cssStyle.match(reg); + if (match && match[0]) { + return match[2] + } + return ''; + }, + + /** + * 给节点设置样式 + * @method setStyle + * @param { String } name 要设置的的样式名称 + * @param { String } val 要设置的的样值 + * @example + * ```javascript + * node.setStyle('font-size', '12px'); + * ``` + */ + setStyle:function (name, val) { + function exec(name, val) { + var reg = new RegExp('(^|;)\\s*' + name + ':([^;]+;?)', 'gi'); + cssStyle = cssStyle.replace(reg, '$1'); + if (val) { + cssStyle = name + ':' + utils.unhtml(val) + ';' + cssStyle + } + + } + + var cssStyle = this.getAttr('style'); + if (!cssStyle) { + cssStyle = ''; + } + if (utils.isObject(name)) { + for (var a in name) { + exec(a, name[a]) + } + } else { + exec(name, val) + } + this.setAttr('style', utils.trim(cssStyle)) + }, + + /** + * 传入一个函数,递归遍历当前节点下的所有节点 + * @method traversal + * @param { Function } fn 遍历到节点的时,传入节点作为参数,运行此函数 + * @example + * ```javascript + * traversal(node, function(){ + * console.log(node.type); + * }); + * ``` + */ + traversal:function(fn){ + if(this.children && this.children.length){ + nodeTraversal(this,fn); + } + return this; + } + } +})(); + + +// core/htmlparser.js +/** + * html字符串转换成uNode节点 + * @file + * @module UE + * @since 1.2.6.1 + */ + +/** + * UEditor公用空间,UEditor所有的功能都挂载在该空间下 + * @unfile + * @module UE + */ + +/** + * html字符串转换成uNode节点的静态方法 + * @method htmlparser + * @param { String } htmlstr 要转换的html代码 + * @param { Boolean } ignoreBlank 若设置为true,转换的时候忽略\n\r\t等空白字符 + * @return { uNode } 给定的html片段转换形成的uNode对象 + * @example + * ```javascript + * var root = UE.htmlparser('

      htmlparser

      ', true); + * ``` + */ + +var htmlparser = UE.htmlparser = function (htmlstr,ignoreBlank) { + //todo 原来的方式 [^"'<>\/] 有\/就不能配对上 ') + } + html.push('') + } + //禁止指定table-width + return '
      这样的标签了 + //先去掉了,加上的原因忘了,这里先记录 + var re_tag = /<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\s\/<>]+)\s*((?:(?:"[^"]*")|(?:'[^']*')|[^"'<>])*)\/?>))/g, + re_attr = /([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g; + + //ie下取得的html可能会有\n存在,要去掉,在处理replace(/[\t\r\n]*/g,'');代码高量的\n不能去除 + var allowEmptyTags = { + b:1,code:1,i:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,span:1, + sub:1,img:1,sup:1,font:1,big:1,small:1,iframe:1,a:1,br:1,pre:1 + }; + htmlstr = htmlstr.replace(new RegExp(domUtils.fillChar, 'g'), ''); + if(!ignoreBlank){ + htmlstr = htmlstr.replace(new RegExp('[\\r\\t\\n'+(ignoreBlank?'':' ')+']*<\/?(\\w+)\\s*(?:[^>]*)>[\\r\\t\\n'+(ignoreBlank?'':' ')+']*','g'), function(a,b){ + //br暂时单独处理 + if(b && allowEmptyTags[b.toLowerCase()]){ + return a.replace(/(^[\n\r]+)|([\n\r]+$)/g,''); + } + return a.replace(new RegExp('^[\\r\\n'+(ignoreBlank?'':' ')+']+'),'').replace(new RegExp('[\\r\\n'+(ignoreBlank?'':' ')+']+$'),''); + }); + } + + var notTransAttrs = { + 'href':1, + 'src':1 + }; + + var uNode = UE.uNode, + needParentNode = { + 'td':'tr', + 'tr':['tbody','thead','tfoot'], + 'tbody':'table', + 'th':'tr', + 'thead':'table', + 'tfoot':'table', + 'caption':'table', + 'li':['ul', 'ol'], + 'dt':'dl', + 'dd':'dl', + 'option':'select' + }, + needChild = { + 'ol':'li', + 'ul':'li' + }; + + function text(parent, data) { + + if(needChild[parent.tagName]){ + var tmpNode = uNode.createElement(needChild[parent.tagName]); + parent.appendChild(tmpNode); + tmpNode.appendChild(uNode.createText(data)); + parent = tmpNode; + }else{ + + parent.appendChild(uNode.createText(data)); + } + } + + function element(parent, tagName, htmlattr) { + var needParentTag; + if (needParentTag = needParentNode[tagName]) { + var tmpParent = parent,hasParent; + while(tmpParent.type != 'root'){ + if(utils.isArray(needParentTag) ? utils.indexOf(needParentTag, tmpParent.tagName) != -1 : needParentTag == tmpParent.tagName){ + parent = tmpParent; + hasParent = true; + break; + } + tmpParent = tmpParent.parentNode; + } + if(!hasParent){ + parent = element(parent, utils.isArray(needParentTag) ? needParentTag[0] : needParentTag) + } + } + //按dtd处理嵌套 +// if(parent.type != 'root' && !dtd[parent.tagName][tagName]) +// parent = parent.parentNode; + var elm = new uNode({ + parentNode:parent, + type:'element', + tagName:tagName.toLowerCase(), + //是自闭合的处理一下 + children:dtd.$empty[tagName] ? null : [] + }); + //如果属性存在,处理属性 + if (htmlattr) { + var attrs = {}, match; + while (match = re_attr.exec(htmlattr)) { + attrs[match[1].toLowerCase()] = notTransAttrs[match[1].toLowerCase()] ? (match[2] || match[3] || match[4]) : utils.unhtml(match[2] || match[3] || match[4]) + } + elm.attrs = attrs; + } + //trace:3970 +// //如果parent下不能放elm +// if(dtd.$inline[parent.tagName] && dtd.$block[elm.tagName] && !dtd[parent.tagName][elm.tagName]){ +// parent = parent.parentNode; +// elm.parentNode = parent; +// } + parent.children.push(elm); + //如果是自闭合节点返回父亲节点 + return dtd.$empty[tagName] ? parent : elm + } + + function comment(parent, data) { + parent.children.push(new uNode({ + type:'comment', + data:data, + parentNode:parent + })); + } + + var match, currentIndex = 0, nextIndex = 0; + //设置根节点 + var root = new uNode({ + type:'root', + children:[] + }); + var currentParent = root; + + while (match = re_tag.exec(htmlstr)) { + currentIndex = match.index; + try{ + if (currentIndex > nextIndex) { + //text node + text(currentParent, htmlstr.slice(nextIndex, currentIndex)); + } + if (match[3]) { + + if(dtd.$cdata[currentParent.tagName]){ + text(currentParent, match[0]); + }else{ + //start tag + currentParent = element(currentParent, match[3].toLowerCase(), match[4]); + } + + + } else if (match[1]) { + if(currentParent.type != 'root'){ + if(dtd.$cdata[currentParent.tagName] && !dtd.$cdata[match[1]]){ + text(currentParent, match[0]); + }else{ + var tmpParent = currentParent; + while(currentParent.type == 'element' && currentParent.tagName != match[1].toLowerCase()){ + currentParent = currentParent.parentNode; + if(currentParent.type == 'root'){ + currentParent = tmpParent; + throw 'break' + } + } + //end tag + currentParent = currentParent.parentNode; + } + + } + + } else if (match[2]) { + //comment + comment(currentParent, match[2]) + } + }catch(e){} + + nextIndex = re_tag.lastIndex; + + } + //如果结束是文本,就有可能丢掉,所以这里手动判断一下 + //例如
    • sdfsdfsdf
    • sdfsdfsdfsdf + if (nextIndex < htmlstr.length) { + text(currentParent, htmlstr.slice(nextIndex)); + } + return root; +}; + + +// core/filternode.js +/** + * UE过滤节点的静态方法 + * @file + */ + +/** + * UEditor公用空间,UEditor所有的功能都挂载在该空间下 + * @module UE + */ + + +/** + * 根据传入节点和过滤规则过滤相应节点 + * @module UE + * @since 1.2.6.1 + * @method filterNode + * @param { Object } root 指定root节点 + * @param { Object } rules 过滤规则json对象 + * @example + * ```javascript + * UE.filterNode(root,editor.options.filterRules); + * ``` + */ +var filterNode = UE.filterNode = function () { + function filterNode(node,rules){ + switch (node.type) { + case 'text': + break; + case 'element': + var val; + if(val = rules[node.tagName]){ + if(val === '-'){ + node.parentNode.removeChild(node) + }else if(utils.isFunction(val)){ + var parentNode = node.parentNode, + index = node.getIndex(); + val(node); + if(node.parentNode){ + if(node.children){ + for(var i = 0,ci;ci=node.children[i];){ + filterNode(ci,rules); + if(ci.parentNode){ + i++; + } + } + } + }else{ + for(var i = index,ci;ci=parentNode.children[i];){ + filterNode(ci,rules); + if(ci.parentNode){ + i++; + } + } + } + + + }else{ + var attrs = val['$']; + if(attrs && node.attrs){ + var tmpAttrs = {},tmpVal; + for(var a in attrs){ + tmpVal = node.getAttr(a); + //todo 只先对style单独处理 + if(a == 'style' && utils.isArray(attrs[a])){ + var tmpCssStyle = []; + utils.each(attrs[a],function(v){ + var tmp; + if(tmp = node.getStyle(v)){ + tmpCssStyle.push(v + ':' + tmp); + } + }); + tmpVal = tmpCssStyle.join(';') + } + if(tmpVal){ + tmpAttrs[a] = tmpVal; + } + + } + node.attrs = tmpAttrs; + } + if(node.children){ + for(var i = 0,ci;ci=node.children[i];){ + filterNode(ci,rules); + if(ci.parentNode){ + i++; + } + } + } + } + }else{ + //如果不在名单里扣出子节点并删除该节点,cdata除外 + if(dtd.$cdata[node.tagName]){ + node.parentNode.removeChild(node) + }else{ + var parentNode = node.parentNode, + index = node.getIndex(); + node.parentNode.removeChild(node,true); + for(var i = index,ci;ci=parentNode.children[i];){ + filterNode(ci,rules); + if(ci.parentNode){ + i++; + } + } + } + } + break; + case 'comment': + node.parentNode.removeChild(node) + } + + } + return function(root,rules){ + if(utils.isEmptyObject(rules)){ + return root; + } + var val; + if(val = rules['-']){ + utils.each(val.split(' '),function(k){ + rules[k] = '-' + }) + } + for(var i= 0,ci;ci=root.children[i];){ + filterNode(ci,rules); + if(ci.parentNode){ + i++; + } + } + return root; + } +}(); + +// core/plugin.js +/** + * Created with JetBrains PhpStorm. + * User: campaign + * Date: 10/8/13 + * Time: 6:15 PM + * To change this template use File | Settings | File Templates. + */ +UE.plugin = function(){ + var _plugins = {}; + return { + register : function(pluginName,fn,oldOptionName,afterDisabled){ + if(oldOptionName && utils.isFunction(oldOptionName)){ + afterDisabled = oldOptionName; + oldOptionName = null + } + _plugins[pluginName] = { + optionName : oldOptionName || pluginName, + execFn : fn, + //当插件被禁用时执行 + afterDisabled : afterDisabled + } + }, + load : function(editor){ + utils.each(_plugins,function(plugin){ + var _export = plugin.execFn.call(editor); + if(editor.options[plugin.optionName] !== false){ + if(_export){ + //后边需要再做扩展 + utils.each(_export,function(v,k){ + switch(k.toLowerCase()){ + case 'shortcutkey': + editor.addshortcutkey(v); + break; + case 'bindevents': + utils.each(v,function(fn,eventName){ + editor.addListener(eventName,fn); + }); + break; + case 'bindmultievents': + utils.each(utils.isArray(v) ? v:[v],function(event){ + var types = utils.trim(event.type).split(/\s+/); + utils.each(types,function(eventName){ + editor.addListener(eventName, event.handler); + }); + }); + break; + case 'commands': + utils.each(v,function(execFn,execName){ + editor.commands[execName] = execFn + }); + break; + case 'outputrule': + editor.addOutputRule(v); + break; + case 'inputrule': + editor.addInputRule(v); + break; + case 'defaultoptions': + editor.setOpt(v) + } + }) + } + + }else if(plugin.afterDisabled){ + plugin.afterDisabled.call(editor) + } + + }); + //向下兼容 + utils.each(UE.plugins,function(plugin){ + plugin.call(editor); + }); + }, + run : function(pluginName,editor){ + var plugin = _plugins[pluginName]; + if(plugin){ + plugin.exeFn.call(editor) + } + } + } +}(); + +// core/keymap.js +var keymap = UE.keymap = { + 'Backspace' : 8, + 'Tab' : 9, + 'Enter' : 13, + + 'Shift':16, + 'Control':17, + 'Alt':18, + 'CapsLock':20, + + 'Esc':27, + + 'Spacebar':32, + + 'PageUp':33, + 'PageDown':34, + 'End':35, + 'Home':36, + + 'Left':37, + 'Up':38, + 'Right':39, + 'Down':40, + + 'Insert':45, + + 'Del':46, + + 'NumLock':144, + + 'Cmd':91, + + '=':187, + '-':189, + + "b":66, + 'i':73, + //回退 + 'z':90, + 'y':89, + //粘贴 + 'v' : 86, + 'x' : 88, + + 's' : 83, + + 'n' : 78 +}; + +// core/localstorage.js +//存储媒介封装 +var LocalStorage = UE.LocalStorage = (function () { + + var storage = window.localStorage || getUserData() || null, + LOCAL_FILE = 'localStorage'; + + return { + + saveLocalData: function (key, data) { + + if (storage && data) { + storage.setItem(key, data); + return true; + } + + return false; + + }, + + getLocalData: function (key) { + + if (storage) { + return storage.getItem(key); + } + + return null; + + }, + + removeItem: function (key) { + + storage && storage.removeItem(key); + + } + + }; + + function getUserData() { + + var container = document.createElement("div"); + container.style.display = "none"; + + if (!container.addBehavior) { + return null; + } + + container.addBehavior("#default#userdata"); + + return { + + getItem: function (key) { + + var result = null; + + try { + document.body.appendChild(container); + container.load(LOCAL_FILE); + result = container.getAttribute(key); + document.body.removeChild(container); + } catch (e) { + } + + return result; + + }, + + setItem: function (key, value) { + + document.body.appendChild(container); + container.setAttribute(key, value); + container.save(LOCAL_FILE); + document.body.removeChild(container); + + }, + + //// 暂时没有用到 + //clear: function () { + // + // var expiresTime = new Date(); + // expiresTime.setFullYear(expiresTime.getFullYear() - 1); + // document.body.appendChild(container); + // container.expires = expiresTime.toUTCString(); + // container.save(LOCAL_FILE); + // document.body.removeChild(container); + // + //}, + + removeItem: function (key) { + + document.body.appendChild(container); + container.removeAttribute(key); + container.save(LOCAL_FILE); + document.body.removeChild(container); + + } + + }; + + } + +})(); + +(function () { + + var ROOTKEY = 'ueditor_preference'; + + UE.Editor.prototype.setPreferences = function(key,value){ + var obj = {}; + if (utils.isString(key)) { + obj[ key ] = value; + } else { + obj = key; + } + var data = LocalStorage.getLocalData(ROOTKEY); + if (data && (data = utils.str2json(data))) { + utils.extend(data, obj); + } else { + data = obj; + } + data && LocalStorage.saveLocalData(ROOTKEY, utils.json2str(data)); + }; + + UE.Editor.prototype.getPreferences = function(key){ + var data = LocalStorage.getLocalData(ROOTKEY); + if (data && (data = utils.str2json(data))) { + return key ? data[key] : data + } + return null; + }; + + UE.Editor.prototype.removePreferences = function (key) { + var data = LocalStorage.getLocalData(ROOTKEY); + if (data && (data = utils.str2json(data))) { + data[key] = undefined; + delete data[key] + } + data && LocalStorage.saveLocalData(ROOTKEY, utils.json2str(data)); + }; + +})(); + + +// plugins/defaultfilter.js +///import core +///plugin 编辑器默认的过滤转换机制 + +UE.plugins['defaultfilter'] = function () { + var me = this; + me.setOpt({ + 'allowDivTransToP':true, + 'disabledTableInTable':true + }); + //默认的过滤处理 + //进入编辑器的内容处理 + me.addInputRule(function (root) { + var allowDivTransToP = this.options.allowDivTransToP; + var val; + function tdParent(node){ + while(node && node.type == 'element'){ + if(node.tagName == 'td'){ + return true; + } + node = node.parentNode; + } + return false; + } + //进行默认的处理 + root.traversal(function (node) { + if (node.type == 'element') { + if (!dtd.$cdata[node.tagName] && me.options.autoClearEmptyNode && dtd.$inline[node.tagName] && !dtd.$empty[node.tagName] && (!node.attrs || utils.isEmptyObject(node.attrs))) { + if (!node.firstChild()) node.parentNode.removeChild(node); + else if (node.tagName == 'span' && (!node.attrs || utils.isEmptyObject(node.attrs))) { + node.parentNode.removeChild(node, true) + } + return; + } + switch (node.tagName) { + case 'style': + case 'script': + node.setAttr({ + cdata_tag: node.tagName, + cdata_data: (node.innerHTML() || ''), + '_ue_custom_node_':'true' + }); + node.tagName = 'div'; + node.innerHTML(''); + break; + case 'a': + if (val = node.getAttr('href')) { + node.setAttr('_href', val) + } + break; + case 'img': + //todo base64暂时去掉,后边做远程图片上传后,干掉这个 + if (val = node.getAttr('src')) { + if (/^data:/.test(val)) { + node.parentNode.removeChild(node); + break; + } + } + node.setAttr('_src', node.getAttr('src')); + break; + case 'span': + if (browser.webkit && (val = node.getStyle('white-space'))) { + if (/nowrap|normal/.test(val)) { + node.setStyle('white-space', ''); + if (me.options.autoClearEmptyNode && utils.isEmptyObject(node.attrs)) { + node.parentNode.removeChild(node, true) + } + } + } + val = node.getAttr('id'); + if(val && /^_baidu_bookmark_/i.test(val)){ + node.parentNode.removeChild(node) + } + break; + case 'p': + if (val = node.getAttr('align')) { + node.setAttr('align'); + node.setStyle('text-align', val) + } + //trace:3431 +// var cssStyle = node.getAttr('style'); +// if (cssStyle) { +// cssStyle = cssStyle.replace(/(margin|padding)[^;]+/g, ''); +// node.setAttr('style', cssStyle) +// +// } + //p标签不允许嵌套 + utils.each(node.children,function(n){ + if(n.type == 'element' && n.tagName == 'p'){ + var next = n.nextSibling(); + node.parentNode.insertAfter(n,node); + var last = n; + while(next){ + var tmp = next.nextSibling(); + node.parentNode.insertAfter(next,last); + last = next; + next = tmp; + } + return false; + } + }); + if (!node.firstChild()) { + node.innerHTML(browser.ie ? ' ' : '
      ') + } + break; + case 'div': + if(node.getAttr('cdata_tag')){ + break; + } + //针对代码这里不处理插入代码的div + val = node.getAttr('class'); + if(val && /^line number\d+/.test(val)){ + break; + } + if(!allowDivTransToP){ + break; + } + var tmpNode, p = UE.uNode.createElement('p'); + while (tmpNode = node.firstChild()) { + if (tmpNode.type == 'text' || !UE.dom.dtd.$block[tmpNode.tagName]) { + p.appendChild(tmpNode); + } else { + if (p.firstChild()) { + node.parentNode.insertBefore(p, node); + p = UE.uNode.createElement('p'); + } else { + node.parentNode.insertBefore(tmpNode, node); + } + } + } + if (p.firstChild()) { + node.parentNode.insertBefore(p, node); + } + node.parentNode.removeChild(node); + break; + case 'dl': + node.tagName = 'ul'; + break; + case 'dt': + case 'dd': + node.tagName = 'li'; + break; + case 'li': + var className = node.getAttr('class'); + if (!className || !/list\-/.test(className)) { + node.setAttr() + } + var tmpNodes = node.getNodesByTagName('ol ul'); + UE.utils.each(tmpNodes, function (n) { + node.parentNode.insertAfter(n, node); + }); + break; + case 'td': + case 'th': + case 'caption': + if(!node.children || !node.children.length){ + node.appendChild(browser.ie11below ? UE.uNode.createText(' ') : UE.uNode.createElement('br')) + } + break; + case 'table': + if(me.options.disabledTableInTable && tdParent(node)){ + node.parentNode.insertBefore(UE.uNode.createText(node.innerText()),node); + node.parentNode.removeChild(node) + } + } + + } +// if(node.type == 'comment'){ +// node.parentNode.removeChild(node); +// } + }) + + }); + + //从编辑器出去的内容处理 + me.addOutputRule(function (root) { + + var val; + root.traversal(function (node) { + if (node.type == 'element') { + + if (me.options.autoClearEmptyNode && dtd.$inline[node.tagName] && !dtd.$empty[node.tagName] && (!node.attrs || utils.isEmptyObject(node.attrs))) { + + if (!node.firstChild()) node.parentNode.removeChild(node); + else if (node.tagName == 'span' && (!node.attrs || utils.isEmptyObject(node.attrs))) { + node.parentNode.removeChild(node, true) + } + return; + } + switch (node.tagName) { + case 'div': + if (val = node.getAttr('cdata_tag')) { + node.tagName = val; + node.appendChild(UE.uNode.createText(node.getAttr('cdata_data'))); + node.setAttr({cdata_tag: '', cdata_data: '','_ue_custom_node_':''}); + } + break; + case 'a': + if (val = node.getAttr('_href')) { + node.setAttr({ + 'href': utils.html(val), + '_href': '' + }) + } + break; + break; + case 'span': + val = node.getAttr('id'); + if(val && /^_baidu_bookmark_/i.test(val)){ + node.parentNode.removeChild(node) + } + break; + case 'img': + if (val = node.getAttr('_src')) { + node.setAttr({ + 'src': node.getAttr('_src'), + '_src': '' + }) + } + + + } + } + + }) + + + }); +}; + + +// plugins/inserthtml.js +/** + * 插入html字符串插件 + * @file + * @since 1.2.6.1 + */ + +/** + * 插入html代码 + * @command inserthtml + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } html 插入的html字符串 + * @remaind 插入的标签内容是在当前的选区位置上插入,如果当前是闭合状态,那直接插入内容, 如果当前是选中状态,将先清除当前选中内容后,再做插入 + * @warning 注意:该命令会对当前选区的位置,对插入的内容进行过滤转换处理。 过滤的规则遵循html语意化的原则。 + * @example + * ```javascript + * //xxx[BB]xxx 当前选区为非闭合选区,选中BB这两个文本 + * //执行命令,插入CC + * //插入后的效果 xxxCCxxx + * //

      xx|xxx

      当前选区为闭合状态 + * //插入

      CC

      + * //结果

      xx

      CC

      xxx

      + * //

      xxxx

      |

      xxx

      当前选区在两个p标签之间 + * //插入 xxxx + * //结果

      xxxx

      xxxx

      xxx

      + * ``` + */ + +UE.commands['inserthtml'] = { + execCommand: function (command,html,notNeedFilter){ + var me = this, + range, + div; + if(!html){ + return; + } + if(me.fireEvent('beforeinserthtml',html) === true){ + return; + } + range = me.selection.getRange(); + div = range.document.createElement( 'div' ); + div.style.display = 'inline'; + + if (!notNeedFilter) { + var root = UE.htmlparser(html); + //如果给了过滤规则就先进行过滤 + if(me.options.filterRules){ + UE.filterNode(root,me.options.filterRules); + } + //执行默认的处理 + me.filterInputRule(root); + html = root.toHtml() + } + div.innerHTML = utils.trim( html ); + + if ( !range.collapsed ) { + var tmpNode = range.startContainer; + if(domUtils.isFillChar(tmpNode)){ + range.setStartBefore(tmpNode) + } + tmpNode = range.endContainer; + if(domUtils.isFillChar(tmpNode)){ + range.setEndAfter(tmpNode) + } + range.txtToElmBoundary(); + //结束边界可能放到了br的前边,要把br包含进来 + // x[xxx]
      + if(range.endContainer && range.endContainer.nodeType == 1){ + tmpNode = range.endContainer.childNodes[range.endOffset]; + if(tmpNode && domUtils.isBr(tmpNode)){ + range.setEndAfter(tmpNode); + } + } + if(range.startOffset == 0){ + tmpNode = range.startContainer; + if(domUtils.isBoundaryNode(tmpNode,'firstChild') ){ + tmpNode = range.endContainer; + if(range.endOffset == (tmpNode.nodeType == 3 ? tmpNode.nodeValue.length : tmpNode.childNodes.length) && domUtils.isBoundaryNode(tmpNode,'lastChild')){ + me.body.innerHTML = '

      '+(browser.ie ? '' : '
      ')+'

      '; + range.setStart(me.body.firstChild,0).collapse(true) + + } + } + } + !range.collapsed && range.deleteContents(); + if(range.startContainer.nodeType == 1){ + var child = range.startContainer.childNodes[range.startOffset],pre; + if(child && domUtils.isBlockElm(child) && (pre = child.previousSibling) && domUtils.isBlockElm(pre)){ + range.setEnd(pre,pre.childNodes.length).collapse(); + while(child.firstChild){ + pre.appendChild(child.firstChild); + } + domUtils.remove(child); + } + } + + } + + + var child,parent,pre,tmp,hadBreak = 0, nextNode; + //如果当前位置选中了fillchar要干掉,要不会产生空行 + if(range.inFillChar()){ + child = range.startContainer; + if(domUtils.isFillChar(child)){ + range.setStartBefore(child).collapse(true); + domUtils.remove(child); + }else if(domUtils.isFillChar(child,true)){ + child.nodeValue = child.nodeValue.replace(fillCharReg,''); + range.startOffset--; + range.collapsed && range.collapse(true) + } + } + //列表单独处理 + var li = domUtils.findParentByTagName(range.startContainer,'li',true); + if(li){ + var next,last; + while(child = div.firstChild){ + //针对hr单独处理一下先 + while(child && (child.nodeType == 3 || !domUtils.isBlockElm(child) || child.tagName=='HR' )){ + next = child.nextSibling; + range.insertNode( child).collapse(); + last = child; + child = next; + + } + if(child){ + if(/^(ol|ul)$/i.test(child.tagName)){ + while(child.firstChild){ + last = child.firstChild; + domUtils.insertAfter(li,child.firstChild); + li = li.nextSibling; + } + domUtils.remove(child) + }else{ + var tmpLi; + next = child.nextSibling; + tmpLi = me.document.createElement('li'); + domUtils.insertAfter(li,tmpLi); + tmpLi.appendChild(child); + last = child; + child = next; + li = tmpLi; + } + } + } + li = domUtils.findParentByTagName(range.startContainer,'li',true); + if(domUtils.isEmptyBlock(li)){ + domUtils.remove(li) + } + if(last){ + + range.setStartAfter(last).collapse(true).select(true) + } + }else{ + while ( child = div.firstChild ) { + if(hadBreak){ + var p = me.document.createElement('p'); + while(child && (child.nodeType == 3 || !dtd.$block[child.tagName])){ + nextNode = child.nextSibling; + p.appendChild(child); + child = nextNode; + } + if(p.firstChild){ + + child = p + } + } + range.insertNode( child ); + nextNode = child.nextSibling; + if ( !hadBreak && child.nodeType == domUtils.NODE_ELEMENT && domUtils.isBlockElm( child ) ){ + + parent = domUtils.findParent( child,function ( node ){ return domUtils.isBlockElm( node ); } ); + if ( parent && parent.tagName.toLowerCase() != 'body' && !(dtd[parent.tagName][child.nodeName] && child.parentNode === parent)){ + if(!dtd[parent.tagName][child.nodeName]){ + pre = parent; + }else{ + tmp = child.parentNode; + while (tmp !== parent){ + pre = tmp; + tmp = tmp.parentNode; + + } + } + + + domUtils.breakParent( child, pre || tmp ); + //去掉break后前一个多余的节点

      |<[p> ==>

      |

      + var pre = child.previousSibling; + domUtils.trimWhiteTextNode(pre); + if(!pre.childNodes.length){ + domUtils.remove(pre); + } + //trace:2012,在非ie的情况,切开后剩下的节点有可能不能点入光标添加br占位 + + if(!browser.ie && + (next = child.nextSibling) && + domUtils.isBlockElm(next) && + next.lastChild && + !domUtils.isBr(next.lastChild)){ + next.appendChild(me.document.createElement('br')); + } + hadBreak = 1; + } + } + var next = child.nextSibling; + if(!div.firstChild && next && domUtils.isBlockElm(next)){ + + range.setStart(next,0).collapse(true); + break; + } + range.setEndAfter( child ).collapse(); + + } + + child = range.startContainer; + + if(nextNode && domUtils.isBr(nextNode)){ + domUtils.remove(nextNode) + } + //用chrome可能有空白展位符 + if(domUtils.isBlockElm(child) && domUtils.isEmptyNode(child)){ + if(nextNode = child.nextSibling){ + domUtils.remove(child); + if(nextNode.nodeType == 1 && dtd.$block[nextNode.tagName]){ + + range.setStart(nextNode,0).collapse(true).shrinkBoundary() + } + }else{ + + try{ + child.innerHTML = browser.ie ? domUtils.fillChar : '
      '; + }catch(e){ + range.setStartBefore(child); + domUtils.remove(child) + } + + } + + } + //加上true因为在删除表情等时会删两次,第一次是删的fillData + try{ + range.select(true); + }catch(e){} + + } + + + + setTimeout(function(){ + range = me.selection.getRange(); + range.scrollToView(me.autoHeightEnabled,me.autoHeightEnabled ? domUtils.getXY(me.iframe).y:0); + me.fireEvent('afterinserthtml', html); + },200); + } +}; + + +// plugins/autotypeset.js +/** + * 自动排版 + * @file + * @since 1.2.6.1 + */ + +/** + * 对当前编辑器的内容执行自动排版, 排版的行为根据config配置文件里的“autotypeset”选项进行控制。 + * @command autotypeset + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'autotypeset' ); + * ``` + */ + +UE.plugins['autotypeset'] = function(){ + + this.setOpt({'autotypeset': { + mergeEmptyline: true, //合并空行 + removeClass: true, //去掉冗余的class + removeEmptyline: false, //去掉空行 + textAlign:"left", //段落的排版方式,可以是 left,right,center,justify 去掉这个属性表示不执行排版 + imageBlockLine: 'center', //图片的浮动方式,独占一行剧中,左右浮动,默认: center,left,right,none 去掉这个属性表示不执行排版 + pasteFilter: false, //根据规则过滤没事粘贴进来的内容 + clearFontSize: false, //去掉所有的内嵌字号,使用编辑器默认的字号 + clearFontFamily: false, //去掉所有的内嵌字体,使用编辑器默认的字体 + removeEmptyNode: false, // 去掉空节点 + //可以去掉的标签 + removeTagNames: utils.extend({div:1},dtd.$removeEmpty), + indent: false, // 行首缩进 + indentValue : '2em', //行首缩进的大小 + bdc2sb: false, + tobdc: false + }}); + + var me = this, + opt = me.options.autotypeset, + remainClass = { + 'selectTdClass':1, + 'pagebreak':1, + 'anchorclass':1 + }, + remainTag = { + 'li':1 + }, + tags = { + div:1, + p:1, + //trace:2183 这些也认为是行 + blockquote:1,center:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1, + span:1 + }, + highlightCont; + //升级了版本,但配置项目里没有autotypeset + if(!opt){ + return; + } + + readLocalOpts(); + + function isLine(node,notEmpty){ + if(!node || node.nodeType == 3) + return 0; + if(domUtils.isBr(node)) + return 1; + if(node && node.parentNode && tags[node.tagName.toLowerCase()]){ + if(highlightCont && highlightCont.contains(node) + || + node.getAttribute('pagebreak') + ){ + return 0; + } + + return notEmpty ? !domUtils.isEmptyBlock(node) : domUtils.isEmptyBlock(node,new RegExp('[\\s'+domUtils.fillChar + +']','g')); + } + } + + function removeNotAttributeSpan(node){ + if(!node.style.cssText){ + domUtils.removeAttributes(node,['style']); + if(node.tagName.toLowerCase() == 'span' && domUtils.hasNoAttributes(node)){ + domUtils.remove(node,true); + } + } + } + function autotype(type,html){ + + var me = this,cont; + if(html){ + if(!opt.pasteFilter){ + return; + } + cont = me.document.createElement('div'); + cont.innerHTML = html.html; + }else{ + cont = me.document.body; + } + var nodes = domUtils.getElementsByTagName(cont,'*'); + + // 行首缩进,段落方向,段间距,段内间距 + for(var i=0,ci;ci=nodes[i++];){ + + if(me.fireEvent('excludeNodeinautotype',ci) === true){ + continue; + } + //font-size + if(opt.clearFontSize && ci.style.fontSize){ + domUtils.removeStyle(ci,'font-size'); + + removeNotAttributeSpan(ci); + + } + //font-family + if(opt.clearFontFamily && ci.style.fontFamily){ + domUtils.removeStyle(ci,'font-family'); + removeNotAttributeSpan(ci); + } + + if(isLine(ci)){ + //合并空行 + if(opt.mergeEmptyline ){ + var next = ci.nextSibling,tmpNode,isBr = domUtils.isBr(ci); + while(isLine(next)){ + tmpNode = next; + next = tmpNode.nextSibling; + if(isBr && (!next || next && !domUtils.isBr(next))){ + break; + } + domUtils.remove(tmpNode); + } + + } + //去掉空行,保留占位的空行 + if(opt.removeEmptyline && domUtils.inDoc(ci,cont) && !remainTag[ci.parentNode.tagName.toLowerCase()] ){ + if(domUtils.isBr(ci)){ + next = ci.nextSibling; + if(next && !domUtils.isBr(next)){ + continue; + } + } + domUtils.remove(ci); + continue; + + } + + } + if(isLine(ci,true) && ci.tagName != 'SPAN'){ + if(opt.indent){ + ci.style.textIndent = opt.indentValue; + } + if(opt.textAlign){ + ci.style.textAlign = opt.textAlign; + } + // if(opt.lineHeight) + // ci.style.lineHeight = opt.lineHeight + 'cm'; + + } + + //去掉class,保留的class不去掉 + if(opt.removeClass && ci.className && !remainClass[ci.className.toLowerCase()]){ + + if(highlightCont && highlightCont.contains(ci)){ + continue; + } + domUtils.removeAttributes(ci,['class']); + } + + //表情不处理 + if(opt.imageBlockLine && ci.tagName.toLowerCase() == 'img' && !ci.getAttribute('emotion')){ + if(html){ + var img = ci; + switch (opt.imageBlockLine){ + case 'left': + case 'right': + case 'none': + var pN = img.parentNode,tmpNode,pre,next; + while(dtd.$inline[pN.tagName] || pN.tagName == 'A'){ + pN = pN.parentNode; + } + tmpNode = pN; + if(tmpNode.tagName == 'P' && domUtils.getStyle(tmpNode,'text-align') == 'center'){ + if(!domUtils.isBody(tmpNode) && domUtils.getChildCount(tmpNode,function(node){return !domUtils.isBr(node) && !domUtils.isWhitespace(node)}) == 1){ + pre = tmpNode.previousSibling; + next = tmpNode.nextSibling; + if(pre && next && pre.nodeType == 1 && next.nodeType == 1 && pre.tagName == next.tagName && domUtils.isBlockElm(pre)){ + pre.appendChild(tmpNode.firstChild); + while(next.firstChild){ + pre.appendChild(next.firstChild); + } + domUtils.remove(tmpNode); + domUtils.remove(next); + }else{ + domUtils.setStyle(tmpNode,'text-align',''); + } + + + } + + + } + domUtils.setStyle(img,'float', opt.imageBlockLine); + break; + case 'center': + if(me.queryCommandValue('imagefloat') != 'center'){ + pN = img.parentNode; + domUtils.setStyle(img,'float','none'); + tmpNode = img; + while(pN && domUtils.getChildCount(pN,function(node){return !domUtils.isBr(node) && !domUtils.isWhitespace(node)}) == 1 + && (dtd.$inline[pN.tagName] || pN.tagName == 'A')){ + tmpNode = pN; + pN = pN.parentNode; + } + var pNode = me.document.createElement('p'); + domUtils.setAttributes(pNode,{ + + style:'text-align:center' + }); + tmpNode.parentNode.insertBefore(pNode,tmpNode); + pNode.appendChild(tmpNode); + domUtils.setStyle(tmpNode,'float',''); + + } + + + } + } else { + var range = me.selection.getRange(); + range.selectNode(ci).select(); + me.execCommand('imagefloat', opt.imageBlockLine); + } + + } + + //去掉冗余的标签 + if(opt.removeEmptyNode){ + if(opt.removeTagNames[ci.tagName.toLowerCase()] && domUtils.hasNoAttributes(ci) && domUtils.isEmptyBlock(ci)){ + domUtils.remove(ci); + } + } + } + if(opt.tobdc){ + var root = UE.htmlparser(cont.innerHTML); + root.traversal(function(node){ + if(node.type == 'text'){ + node.data = ToDBC(node.data) + } + }); + cont.innerHTML = root.toHtml() + } + if(opt.bdc2sb){ + var root = UE.htmlparser(cont.innerHTML); + root.traversal(function(node){ + if(node.type == 'text'){ + node.data = DBC2SB(node.data) + } + }); + cont.innerHTML = root.toHtml() + } + if(html){ + html.html = cont.innerHTML; + } + } + if(opt.pasteFilter){ + me.addListener('beforepaste',autotype); + } + + function DBC2SB(str) { + var result = ''; + for (var i = 0; i < str.length; i++) { + var code = str.charCodeAt(i); //获取当前字符的unicode编码 + if (code >= 65281 && code <= 65373)//在这个unicode编码范围中的是所有的英文字母已经各种字符 + { + result += String.fromCharCode(str.charCodeAt(i) - 65248); //把全角字符的unicode编码转换为对应半角字符的unicode码 + } else if (code == 12288)//空格 + { + result += String.fromCharCode(str.charCodeAt(i) - 12288 + 32); + } else { + result += str.charAt(i); + } + } + return result; + } + function ToDBC(txtstring) { + txtstring = utils.html(txtstring); + var tmp = ""; + var mark = "";/*用于判断,如果是html尖括里的标记,则不进行全角的转换*/ + for (var i = 0; i < txtstring.length; i++) { + if (txtstring.charCodeAt(i) == 32) { + tmp = tmp + String.fromCharCode(12288); + } + else if (txtstring.charCodeAt(i) < 127) { + tmp = tmp + String.fromCharCode(txtstring.charCodeAt(i) + 65248); + } + else { + tmp += txtstring.charAt(i); + } + } + return tmp; + } + + function readLocalOpts() { + var cookieOpt = me.getPreferences('autotypeset'); + utils.extend(me.options.autotypeset, cookieOpt); + } + + me.commands['autotypeset'] = { + execCommand:function () { + me.removeListener('beforepaste',autotype); + if(opt.pasteFilter){ + me.addListener('beforepaste',autotype); + } + autotype.call(me) + } + + }; + +}; + + + +// plugins/autosubmit.js +/** + * 快捷键提交 + * @file + * @since 1.2.6.1 + */ + +/** + * 提交表单 + * @command autosubmit + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'autosubmit' ); + * ``` + */ + +UE.plugin.register('autosubmit',function(){ + return { + shortcutkey:{ + "autosubmit":"ctrl+13" //手动提交 + }, + commands:{ + 'autosubmit':{ + execCommand:function () { + var me=this, + form = domUtils.findParentByTagName(me.iframe,"form", false); + if (form){ + if(me.fireEvent("beforesubmit")===false){ + return; + } + me.sync(); + form.submit(); + } + } + } + } + } +}); + +// plugins/background.js +/** + * 背景插件,为UEditor提供设置背景功能 + * @file + * @since 1.2.6.1 + */ +UE.plugin.register('background', function () { + var me = this, + cssRuleId = 'editor_background', + isSetColored, + reg = new RegExp('body[\\s]*\\{(.+)\\}', 'i'); + + function stringToObj(str) { + var obj = {}, styles = str.split(';'); + utils.each(styles, function (v) { + var index = v.indexOf(':'), + key = utils.trim(v.substr(0, index)).toLowerCase(); + key && (obj[key] = utils.trim(v.substr(index + 1) || '')); + }); + return obj; + } + + function setBackground(obj) { + if (obj) { + var styles = []; + for (var name in obj) { + if (obj.hasOwnProperty(name)) { + styles.push(name + ":" + obj[name] + '; '); + } + } + utils.cssRule(cssRuleId, styles.length ? ('body{' + styles.join("") + '}') : '', me.document); + } else { + utils.cssRule(cssRuleId, '', me.document) + } + } + //重写editor.hasContent方法 + + var orgFn = me.hasContents; + me.hasContents = function(){ + if(me.queryCommandValue('background')){ + return true + } + return orgFn.apply(me,arguments); + }; + return { + bindEvents: { + 'getAllHtml': function (type, headHtml) { + var body = this.body, + su = domUtils.getComputedStyle(body, "background-image"), + url = ""; + if (su.indexOf(me.options.imagePath) > 0) { + url = su.substring(su.indexOf(me.options.imagePath), su.length - 1).replace(/"|\(|\)/ig, ""); + } else { + url = su != "none" ? su.replace(/url\("?|"?\)/ig, "") : ""; + } + var html = ' '; + headHtml.push(html); + }, + 'aftersetcontent': function () { + if(isSetColored == false) setBackground(); + } + }, + inputRule: function (root) { + isSetColored = false; + utils.each(root.getNodesByTagName('p'), function (p) { + var styles = p.getAttr('data-background'); + if (styles) { + isSetColored = true; + setBackground(stringToObj(styles)); + p.parentNode.removeChild(p); + } + }) + }, + outputRule: function (root) { + var me = this, + styles = (utils.cssRule(cssRuleId, me.document) || '').replace(/[\n\r]+/g, '').match(reg); + if (styles) { + root.appendChild(UE.uNode.createElement('


      ')); + } + }, + commands: { + 'background': { + execCommand: function (cmd, obj) { + setBackground(obj); + }, + queryCommandValue: function () { + var me = this, + styles = (utils.cssRule(cssRuleId, me.document) || '').replace(/[\n\r]+/g, '').match(reg); + return styles ? stringToObj(styles[1]) : null; + }, + notNeedUndo: true + } + } + } +}); + +// plugins/image.js +/** + * 图片插入、排版插件 + * @file + * @since 1.2.6.1 + */ + +/** + * 图片对齐方式 + * @command imagefloat + * @method execCommand + * @remind 值center为独占一行居中 + * @param { String } cmd 命令字符串 + * @param { String } align 对齐方式,可传left、right、none、center + * @remaind center表示图片独占一行 + * @example + * ```javascript + * editor.execCommand( 'imagefloat', 'center' ); + * ``` + */ + +/** + * 如果选区所在位置是图片区域 + * @command imagefloat + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回图片对齐方式 + * @example + * ```javascript + * editor.queryCommandValue( 'imagefloat' ); + * ``` + */ + +UE.commands['imagefloat'] = { + execCommand:function (cmd, align) { + var me = this, + range = me.selection.getRange(); + if (!range.collapsed) { + var img = range.getClosedNode(); + if (img && img.tagName == 'IMG') { + switch (align) { + case 'left': + case 'right': + case 'none': + var pN = img.parentNode, tmpNode, pre, next; + while (dtd.$inline[pN.tagName] || pN.tagName == 'A') { + pN = pN.parentNode; + } + tmpNode = pN; + if (tmpNode.tagName == 'P' && domUtils.getStyle(tmpNode, 'text-align') == 'center') { + if (!domUtils.isBody(tmpNode) && domUtils.getChildCount(tmpNode, function (node) { + return !domUtils.isBr(node) && !domUtils.isWhitespace(node); + }) == 1) { + pre = tmpNode.previousSibling; + next = tmpNode.nextSibling; + if (pre && next && pre.nodeType == 1 && next.nodeType == 1 && pre.tagName == next.tagName && domUtils.isBlockElm(pre)) { + pre.appendChild(tmpNode.firstChild); + while (next.firstChild) { + pre.appendChild(next.firstChild); + } + domUtils.remove(tmpNode); + domUtils.remove(next); + } else { + domUtils.setStyle(tmpNode, 'text-align', ''); + } + + + } + + range.selectNode(img).select(); + } + domUtils.setStyle(img, 'float', align == 'none' ? '' : align); + if(align == 'none'){ + domUtils.removeAttributes(img,'align'); + } + + break; + case 'center': + if (me.queryCommandValue('imagefloat') != 'center') { + pN = img.parentNode; + domUtils.setStyle(img, 'float', ''); + domUtils.removeAttributes(img,'align'); + tmpNode = img; + while (pN && domUtils.getChildCount(pN, function (node) { + return !domUtils.isBr(node) && !domUtils.isWhitespace(node); + }) == 1 + && (dtd.$inline[pN.tagName] || pN.tagName == 'A')) { + tmpNode = pN; + pN = pN.parentNode; + } + range.setStartBefore(tmpNode).setCursor(false); + pN = me.document.createElement('div'); + pN.appendChild(tmpNode); + domUtils.setStyle(tmpNode, 'float', ''); + + me.execCommand('insertHtml', '

      ' + pN.innerHTML + '

      '); + + tmpNode = me.document.getElementById('_img_parent_tmp'); + tmpNode.removeAttribute('id'); + tmpNode = tmpNode.firstChild; + range.selectNode(tmpNode).select(); + //去掉后边多余的元素 + next = tmpNode.parentNode.nextSibling; + if (next && domUtils.isEmptyNode(next)) { + domUtils.remove(next); + } + + } + + break; + } + + } + } + }, + queryCommandValue:function () { + var range = this.selection.getRange(), + startNode, floatStyle; + if (range.collapsed) { + return 'none'; + } + startNode = range.getClosedNode(); + if (startNode && startNode.nodeType == 1 && startNode.tagName == 'IMG') { + floatStyle = domUtils.getComputedStyle(startNode, 'float') || startNode.getAttribute('align'); + + if (floatStyle == 'none') { + floatStyle = domUtils.getComputedStyle(startNode.parentNode, 'text-align') == 'center' ? 'center' : floatStyle; + } + return { + left:1, + right:1, + center:1 + }[floatStyle] ? floatStyle : 'none'; + } + return 'none'; + + + }, + queryCommandState:function () { + var range = this.selection.getRange(), + startNode; + + if (range.collapsed) return -1; + + startNode = range.getClosedNode(); + if (startNode && startNode.nodeType == 1 && startNode.tagName == 'IMG') { + return 0; + } + return -1; + } +}; + + +/** + * 插入图片 + * @command insertimage + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { Object } opt 属性键值对,这些属性都将被复制到当前插入图片 + * @remind 该命令第二个参数可接受一个图片配置项对象的数组,可以插入多张图片, + * 此时数组的每一个元素都是一个Object类型的图片属性集合。 + * @example + * ```javascript + * editor.execCommand( 'insertimage', { + * src:'a/b/c.jpg', + * width:'100', + * height:'100' + * } ); + * ``` + * @example + * ```javascript + * editor.execCommand( 'insertimage', [{ + * src:'a/b/c.jpg', + * width:'100', + * height:'100' + * },{ + * src:'a/b/d.jpg', + * width:'100', + * height:'100' + * }] ); + * ``` + */ + +UE.commands['insertimage'] = { + execCommand:function (cmd, opt) { + + opt = utils.isArray(opt) ? opt : [opt]; + if (!opt.length) { + return; + } + var me = this, + range = me.selection.getRange(), + img = range.getClosedNode(); + + if(me.fireEvent('beforeinsertimage', opt) === true){ + return; + } + + function unhtmlData(imgCi) { + + utils.each('width,height,border,hspace,vspace'.split(','), function (item) { + + if (imgCi[item]) { + imgCi[item] = parseInt(imgCi[item], 10) || 0; + } + }); + + utils.each('src,_src'.split(','), function (item) { + + if (imgCi[item]) { + imgCi[item] = utils.unhtmlForUrl(imgCi[item]); + } + }); + utils.each('title,alt'.split(','), function (item) { + + if (imgCi[item]) { + imgCi[item] = utils.unhtml(imgCi[item]); + } + }); + } + + if (img && /img/i.test(img.tagName) && (img.className != "edui-faked-video" || img.className.indexOf("edui-upload-video")!=-1) && !img.getAttribute("word_img")) { + var first = opt.shift(); + var floatStyle = first['floatStyle']; + delete first['floatStyle']; +//// img.style.border = (first.border||0) +"px solid #000"; +//// img.style.margin = (first.margin||0) +"px"; +// img.style.cssText += ';margin:' + (first.margin||0) +"px;" + 'border:' + (first.border||0) +"px solid #000"; + domUtils.setAttributes(img, first); + me.execCommand('imagefloat', floatStyle); + if (opt.length > 0) { + range.setStartAfter(img).setCursor(false, true); + me.execCommand('insertimage', opt); + } + + } else { + var html = [], str = '', ci; + ci = opt[0]; + if (opt.length == 1) { + unhtmlData(ci); + + str = '' + ci.alt + ''; + if (ci['floatStyle'] == 'center') { + str = '

      ' + str + '

      '; + } + html.push(str); + + } else { + for (var i = 0; ci = opt[i++];) { + unhtmlData(ci); + str = '

      '; + html.push(str); + } + } + + me.execCommand('insertHtml', html.join('')); + } + + me.fireEvent('afterinsertimage', opt) + } +}; + + +// plugins/justify.js +/** + * 段落格式 + * @file + * @since 1.2.6.1 + */ + +/** + * 段落对齐方式 + * @command justify + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } align 对齐方式:left => 居左,right => 居右,center => 居中,justify => 两端对齐 + * @example + * ```javascript + * editor.execCommand( 'justify', 'center' ); + * ``` + */ +/** + * 如果选区所在位置是段落区域,返回当前段落对齐方式 + * @command justify + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回段落对齐方式 + * @example + * ```javascript + * editor.queryCommandValue( 'justify' ); + * ``` + */ + +UE.plugins['justify']=function(){ + var me=this, + block = domUtils.isBlockElm, + defaultValue = { + left:1, + right:1, + center:1, + justify:1 + }, + doJustify = function (range, style) { + var bookmark = range.createBookmark(), + filterFn = function (node) { + return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' && !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace(node); + }; + + range.enlarge(true); + var bookmark2 = range.createBookmark(), + current = domUtils.getNextDomNode(bookmark2.start, false, filterFn), + tmpRange = range.cloneRange(), + tmpNode; + while (current && !(domUtils.getPosition(current, bookmark2.end) & domUtils.POSITION_FOLLOWING)) { + if (current.nodeType == 3 || !block(current)) { + tmpRange.setStartBefore(current); + while (current && current !== bookmark2.end && !block(current)) { + tmpNode = current; + current = domUtils.getNextDomNode(current, false, null, function (node) { + return !block(node); + }); + } + tmpRange.setEndAfter(tmpNode); + var common = tmpRange.getCommonAncestor(); + if (!domUtils.isBody(common) && block(common)) { + domUtils.setStyles(common, utils.isString(style) ? {'text-align':style} : style); + current = common; + } else { + var p = range.document.createElement('p'); + domUtils.setStyles(p, utils.isString(style) ? {'text-align':style} : style); + var frag = tmpRange.extractContents(); + p.appendChild(frag); + tmpRange.insertNode(p); + current = p; + } + current = domUtils.getNextDomNode(current, false, filterFn); + } else { + current = domUtils.getNextDomNode(current, true, filterFn); + } + } + return range.moveToBookmark(bookmark2).moveToBookmark(bookmark); + }; + + UE.commands['justify'] = { + execCommand:function (cmdName, align) { + var range = this.selection.getRange(), + txt; + + //闭合时单独处理 + if (range.collapsed) { + txt = this.document.createTextNode('p'); + range.insertNode(txt); + } + doJustify(range, align); + if (txt) { + range.setStartBefore(txt).collapse(true); + domUtils.remove(txt); + } + + range.select(); + + + return true; + }, + queryCommandValue:function () { + var startNode = this.selection.getStart(), + value = domUtils.getComputedStyle(startNode, 'text-align'); + return defaultValue[value] ? value : 'left'; + }, + queryCommandState:function () { + var start = this.selection.getStart(), + cell = start && domUtils.findParentByTagName(start, ["td", "th","caption"], true); + + return cell? -1:0; + } + + }; +}; + + +// plugins/font.js +/** + * 字体颜色,背景色,字号,字体,下划线,删除线 + * @file + * @since 1.2.6.1 + */ + +/** + * 字体颜色 + * @command forecolor + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } value 色值(必须十六进制) + * @example + * ```javascript + * editor.execCommand( 'forecolor', '#000' ); + * ``` + */ +/** + * 返回选区字体颜色 + * @command forecolor + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回字体颜色 + * @example + * ```javascript + * editor.queryCommandValue( 'forecolor' ); + * ``` + */ + +/** + * 字体背景颜色 + * @command backcolor + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } value 色值(必须十六进制) + * @example + * ```javascript + * editor.execCommand( 'backcolor', '#000' ); + * ``` + */ +/** + * 返回选区字体颜色 + * @command backcolor + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回字体背景颜色 + * @example + * ```javascript + * editor.queryCommandValue( 'backcolor' ); + * ``` + */ + +/** + * 字体大小 + * @command fontsize + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } value 字体大小 + * @example + * ```javascript + * editor.execCommand( 'fontsize', '14px' ); + * ``` + */ +/** + * 返回选区字体大小 + * @command fontsize + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回字体大小 + * @example + * ```javascript + * editor.queryCommandValue( 'fontsize' ); + * ``` + */ + +/** + * 字体样式 + * @command fontfamily + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } value 字体样式 + * @example + * ```javascript + * editor.execCommand( 'fontfamily', '微软雅黑' ); + * ``` + */ +/** + * 返回选区字体样式 + * @command fontfamily + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回字体样式 + * @example + * ```javascript + * editor.queryCommandValue( 'fontfamily' ); + * ``` + */ + +/** + * 字体下划线,与删除线互斥 + * @command underline + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'underline' ); + * ``` + */ + +/** + * 字体删除线,与下划线互斥 + * @command strikethrough + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'strikethrough' ); + * ``` + */ + +/** + * 字体边框 + * @command fontborder + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'fontborder' ); + * ``` + */ + +UE.plugins['font'] = function () { + var me = this, + fonts = { + 'forecolor': 'color', + 'backcolor': 'background-color', + 'fontsize': 'font-size', + 'fontfamily': 'font-family', + 'underline': 'text-decoration', + 'strikethrough': 'text-decoration', + 'fontborder': 'border' + }, + needCmd = {'underline': 1, 'strikethrough': 1, 'fontborder': 1}, + needSetChild = { + 'forecolor': 'color', + 'backcolor': 'background-color', + 'fontsize': 'font-size', + 'fontfamily': 'font-family' + + }; + me.setOpt({ + 'fontfamily': [ + { name: 'songti', val: '宋体,SimSun'}, + { name: 'yahei', val: '微软雅黑,Microsoft YaHei'}, + { name: 'kaiti', val: '楷体,楷体_GB2312, SimKai'}, + { name: 'heiti', val: '黑体, SimHei'}, + { name: 'lishu', val: '隶书, SimLi'}, + { name: 'andaleMono', val: 'andale mono'}, + { name: 'arial', val: 'arial, helvetica,sans-serif'}, + { name: 'arialBlack', val: 'arial black,avant garde'}, + { name: 'comicSansMs', val: 'comic sans ms'}, + { name: 'impact', val: 'impact,chicago'}, + { name: 'timesNewRoman', val: 'times new roman'} + ], + 'fontsize': [10, 11, 12, 14, 16, 18, 20, 24, 36] + }); + + function mergeWithParent(node){ + var parent; + while(parent = node.parentNode){ + if(parent.tagName == 'SPAN' && domUtils.getChildCount(parent,function(child){ + return !domUtils.isBookmarkNode(child) && !domUtils.isBr(child) + }) == 1) { + parent.style.cssText += node.style.cssText; + domUtils.remove(node,true); + node = parent; + + }else{ + break; + } + } + + } + function mergeChild(rng,cmdName,value){ + if(needSetChild[cmdName]){ + rng.adjustmentBoundary(); + if(!rng.collapsed && rng.startContainer.nodeType == 1){ + var start = rng.startContainer.childNodes[rng.startOffset]; + if(start && domUtils.isTagNode(start,'span')){ + var bk = rng.createBookmark(); + utils.each(domUtils.getElementsByTagName(start, 'span'), function (span) { + if (!span.parentNode || domUtils.isBookmarkNode(span))return; + if(cmdName == 'backcolor' && domUtils.getComputedStyle(span,'background-color').toLowerCase() === value){ + return; + } + domUtils.removeStyle(span,needSetChild[cmdName]); + if(span.style.cssText.replace(/^\s+$/,'').length == 0){ + domUtils.remove(span,true) + } + }); + rng.moveToBookmark(bk) + } + } + } + + } + function mergesibling(rng,cmdName,value) { + var collapsed = rng.collapsed, + bk = rng.createBookmark(), common; + if (collapsed) { + common = bk.start.parentNode; + while (dtd.$inline[common.tagName]) { + common = common.parentNode; + } + } else { + common = domUtils.getCommonAncestor(bk.start, bk.end); + } + utils.each(domUtils.getElementsByTagName(common, 'span'), function (span) { + if (!span.parentNode || domUtils.isBookmarkNode(span))return; + if (/\s*border\s*:\s*none;?\s*/i.test(span.style.cssText)) { + if(/^\s*border\s*:\s*none;?\s*$/.test(span.style.cssText)){ + domUtils.remove(span, true); + }else{ + domUtils.removeStyle(span,'border'); + } + return + } + if (/border/i.test(span.style.cssText) && span.parentNode.tagName == 'SPAN' && /border/i.test(span.parentNode.style.cssText)) { + span.style.cssText = span.style.cssText.replace(/border[^:]*:[^;]+;?/gi, ''); + } + if(!(cmdName=='fontborder' && value=='none')){ + var next = span.nextSibling; + while (next && next.nodeType == 1 && next.tagName == 'SPAN' ) { + if(domUtils.isBookmarkNode(next) && cmdName == 'fontborder') { + span.appendChild(next); + next = span.nextSibling; + continue; + } + if (next.style.cssText == span.style.cssText) { + domUtils.moveChild(next, span); + domUtils.remove(next); + } + if (span.nextSibling === next) + break; + next = span.nextSibling; + } + } + + + mergeWithParent(span); + if(browser.ie && browser.version > 8 ){ + //拷贝父亲们的特别的属性,这里只做背景颜色的处理 + var parent = domUtils.findParent(span,function(n){return n.tagName == 'SPAN' && /background-color/.test(n.style.cssText)}); + if(parent && !/background-color/.test(span.style.cssText)){ + span.style.backgroundColor = parent.style.backgroundColor; + } + } + + }); + rng.moveToBookmark(bk); + mergeChild(rng,cmdName,value) + } + + me.addInputRule(function (root) { + utils.each(root.getNodesByTagName('u s del font strike'), function (node) { + if (node.tagName == 'font') { + var cssStyle = []; + for (var p in node.attrs) { + switch (p) { + case 'size': + cssStyle.push('font-size:' + + ({ + '1':'10', + '2':'12', + '3':'16', + '4':'18', + '5':'24', + '6':'32', + '7':'48' + }[node.attrs[p]] || node.attrs[p]) + 'px'); + break; + case 'color': + cssStyle.push('color:' + node.attrs[p]); + break; + case 'face': + cssStyle.push('font-family:' + node.attrs[p]); + break; + case 'style': + cssStyle.push(node.attrs[p]); + } + } + node.attrs = { + 'style': cssStyle.join(';') + }; + } else { + var val = node.tagName == 'u' ? 'underline' : 'line-through'; + node.attrs = { + 'style': (node.getAttr('style') || '') + 'text-decoration:' + val + ';' + } + } + node.tagName = 'span'; + }); +// utils.each(root.getNodesByTagName('span'), function (node) { +// var val; +// if(val = node.getAttr('class')){ +// if(/fontstrikethrough/.test(val)){ +// node.setStyle('text-decoration','line-through'); +// if(node.attrs['class']){ +// node.attrs['class'] = node.attrs['class'].replace(/fontstrikethrough/,''); +// }else{ +// node.setAttr('class') +// } +// } +// if(/fontborder/.test(val)){ +// node.setStyle('border','1px solid #000'); +// if(node.attrs['class']){ +// node.attrs['class'] = node.attrs['class'].replace(/fontborder/,''); +// }else{ +// node.setAttr('class') +// } +// } +// } +// }); + }); +// me.addOutputRule(function(root){ +// utils.each(root.getNodesByTagName('span'), function (node) { +// var val; +// if(val = node.getStyle('text-decoration')){ +// if(/line-through/.test(val)){ +// if(node.attrs['class']){ +// node.attrs['class'] += ' fontstrikethrough'; +// }else{ +// node.setAttr('class','fontstrikethrough') +// } +// } +// +// node.setStyle('text-decoration') +// } +// if(val = node.getStyle('border')){ +// if(/1px/.test(val) && /solid/.test(val)){ +// if(node.attrs['class']){ +// node.attrs['class'] += ' fontborder'; +// +// }else{ +// node.setAttr('class','fontborder') +// } +// } +// node.setStyle('border') +// +// } +// }); +// }); + for (var p in fonts) { + (function (cmd, style) { + UE.commands[cmd] = { + execCommand: function (cmdName, value) { + value = value || (this.queryCommandState(cmdName) ? 'none' : cmdName == 'underline' ? 'underline' : + cmdName == 'fontborder' ? '1px solid #000' : + 'line-through'); + var me = this, + range = this.selection.getRange(), + text; + + if (value == 'default') { + + if (range.collapsed) { + text = me.document.createTextNode('font'); + range.insertNode(text).select(); + + } + me.execCommand('removeFormat', 'span,a', style); + if (text) { + range.setStartBefore(text).collapse(true); + domUtils.remove(text); + } + mergesibling(range,cmdName,value); + range.select() + } else { + if (!range.collapsed) { + if (needCmd[cmd] && me.queryCommandValue(cmd)) { + me.execCommand('removeFormat', 'span,a', style); + } + range = me.selection.getRange(); + + range.applyInlineStyle('span', {'style': style + ':' + value}); + mergesibling(range, cmdName,value); + range.select(); + } else { + + var span = domUtils.findParentByTagName(range.startContainer, 'span', true); + text = me.document.createTextNode('font'); + if (span && !span.children.length && !span[browser.ie ? 'innerText' : 'textContent'].replace(fillCharReg, '').length) { + //for ie hack when enter + range.insertNode(text); + if (needCmd[cmd]) { + range.selectNode(text).select(); + me.execCommand('removeFormat', 'span,a', style, null); + + span = domUtils.findParentByTagName(text, 'span', true); + range.setStartBefore(text); + + } + span && (span.style.cssText += ';' + style + ':' + value); + range.collapse(true).select(); + + + } else { + range.insertNode(text); + range.selectNode(text).select(); + span = range.document.createElement('span'); + + if (needCmd[cmd]) { + //a标签内的不处理跳过 + if (domUtils.findParentByTagName(text, 'a', true)) { + range.setStartBefore(text).setCursor(); + domUtils.remove(text); + return; + } + me.execCommand('removeFormat', 'span,a', style); + } + + span.style.cssText = style + ':' + value; + + + text.parentNode.insertBefore(span, text); + //修复,span套span 但样式不继承的问题 + if (!browser.ie || browser.ie && browser.version == 9) { + var spanParent = span.parentNode; + while (!domUtils.isBlockElm(spanParent)) { + if (spanParent.tagName == 'SPAN') { + //opera合并style不会加入";" + span.style.cssText = spanParent.style.cssText + ";" + span.style.cssText; + } + spanParent = spanParent.parentNode; + } + } + + + if (opera) { + setTimeout(function () { + range.setStart(span, 0).collapse(true); + mergesibling(range, cmdName,value); + range.select(); + }); + } else { + range.setStart(span, 0).collapse(true); + mergesibling(range,cmdName,value); + range.select(); + } + + //trace:981 + //domUtils.mergeToParent(span) + } + domUtils.remove(text); + } + + + } + return true; + }, + queryCommandValue: function (cmdName) { + var startNode = this.selection.getStart(); + + //trace:946 + if (cmdName == 'underline' || cmdName == 'strikethrough') { + var tmpNode = startNode, value; + while (tmpNode && !domUtils.isBlockElm(tmpNode) && !domUtils.isBody(tmpNode)) { + if (tmpNode.nodeType == 1) { + value = domUtils.getComputedStyle(tmpNode, style); + if (value != 'none') { + return value; + } + } + + tmpNode = tmpNode.parentNode; + } + return 'none'; + } + if (cmdName == 'fontborder') { + var tmp = startNode, val; + while (tmp && dtd.$inline[tmp.tagName]) { + if (val = domUtils.getComputedStyle(tmp, 'border')) { + + if (/1px/.test(val) && /solid/.test(val)) { + return val; + } + } + tmp = tmp.parentNode; + } + return '' + } + + if( cmdName == 'FontSize' ) { + var styleVal = domUtils.getComputedStyle(startNode, style), + tmp = /^([\d\.]+)(\w+)$/.exec( styleVal ); + + if( tmp ) { + + return Math.floor( tmp[1] ) + tmp[2]; + + } + + return styleVal; + + } + + return domUtils.getComputedStyle(startNode, style); + }, + queryCommandState: function (cmdName) { + if (!needCmd[cmdName]) + return 0; + var val = this.queryCommandValue(cmdName); + if (cmdName == 'fontborder') { + return /1px/.test(val) && /solid/.test(val) + } else { + return cmdName == 'underline' ? /underline/.test(val) : /line\-through/.test(val); + + } + + } + }; + })(p, fonts[p]); + } +}; + +// plugins/link.js +/** + * 超链接 + * @file + * @since 1.2.6.1 + */ + +/** + * 插入超链接 + * @command link + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { Object } options 设置自定义属性,例如:url、title、target + * @example + * ```javascript + * editor.execCommand( 'link', '{ + * url:'ueditor.baidu.com', + * title:'ueditor', + * target:'_blank' + * }' ); + * ``` + */ +/** + * 返回当前选中的第一个超链接节点 + * @command link + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { Element } 超链接节点 + * @example + * ```javascript + * editor.queryCommandValue( 'link' ); + * ``` + */ + +/** + * 取消超链接 + * @command unlink + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'unlink'); + * ``` + */ + +UE.plugins['link'] = function(){ + function optimize( range ) { + var start = range.startContainer,end = range.endContainer; + + if ( start = domUtils.findParentByTagName( start, 'a', true ) ) { + range.setStartBefore( start ); + } + if ( end = domUtils.findParentByTagName( end, 'a', true ) ) { + range.setEndAfter( end ); + } + } + + + UE.commands['unlink'] = { + execCommand : function() { + var range = this.selection.getRange(), + bookmark; + if(range.collapsed && !domUtils.findParentByTagName( range.startContainer, 'a', true )){ + return; + } + bookmark = range.createBookmark(); + optimize( range ); + range.removeInlineStyle( 'a' ).moveToBookmark( bookmark ).select(); + }, + queryCommandState : function(){ + return !this.highlight && this.queryCommandValue('link') ? 0 : -1; + } + + }; + function doLink(range,opt,me){ + var rngClone = range.cloneRange(), + link = me.queryCommandValue('link'); + optimize( range = range.adjustmentBoundary() ); + var start = range.startContainer; + if(start.nodeType == 1 && link){ + start = start.childNodes[range.startOffset]; + if(start && start.nodeType == 1 && start.tagName == 'A' && /^(?:https?|ftp|file)\s*:\s*\/\//.test(start[browser.ie?'innerText':'textContent'])){ + start[browser.ie ? 'innerText' : 'textContent'] = utils.html(opt.textValue||opt.href); + + } + } + if( !rngClone.collapsed || link){ + range.removeInlineStyle( 'a' ); + rngClone = range.cloneRange(); + } + + if ( rngClone.collapsed ) { + var a = range.document.createElement( 'a'), + text = ''; + if(opt.textValue){ + + text = utils.html(opt.textValue); + delete opt.textValue; + }else{ + text = utils.html(opt.href); + + } + domUtils.setAttributes( a, opt ); + start = domUtils.findParentByTagName( rngClone.startContainer, 'a', true ); + if(start && domUtils.isInNodeEndBoundary(rngClone,start)){ + range.setStartAfter(start).collapse(true); + + } + a[browser.ie ? 'innerText' : 'textContent'] = text; + range.insertNode(a).selectNode( a ); + } else { + range.applyInlineStyle( 'a', opt ); + + } + } + UE.commands['link'] = { + execCommand : function( cmdName, opt ) { + var range; + opt._href && (opt._href = utils.unhtml(opt._href,/[<">]/g)); + opt.href && (opt.href = utils.unhtml(opt.href,/[<">]/g)); + opt.textValue && (opt.textValue = utils.unhtml(opt.textValue,/[<">]/g)); + doLink(range=this.selection.getRange(),opt,this); + //闭合都不加占位符,如果加了会在a后边多个占位符节点,导致a是图片背景组成的列表,出现空白问题 + range.collapse().select(true); + + }, + queryCommandValue : function() { + var range = this.selection.getRange(), + node; + if ( range.collapsed ) { +// node = this.selection.getStart(); + //在ie下getstart()取值偏上了 + node = range.startContainer; + node = node.nodeType == 1 ? node : node.parentNode; + + if ( node && (node = domUtils.findParentByTagName( node, 'a', true )) && ! domUtils.isInNodeEndBoundary(range,node)) { + + return node; + } + } else { + //trace:1111 如果是

      xx

      startContainer是p就会找不到a + range.shrinkBoundary(); + var start = range.startContainer.nodeType == 3 || !range.startContainer.childNodes[range.startOffset] ? range.startContainer : range.startContainer.childNodes[range.startOffset], + end = range.endContainer.nodeType == 3 || range.endOffset == 0 ? range.endContainer : range.endContainer.childNodes[range.endOffset-1], + common = range.getCommonAncestor(); + node = domUtils.findParentByTagName( common, 'a', true ); + if ( !node && common.nodeType == 1){ + + var as = common.getElementsByTagName( 'a' ), + ps,pe; + + for ( var i = 0,ci; ci = as[i++]; ) { + ps = domUtils.getPosition( ci, start ),pe = domUtils.getPosition( ci,end); + if ( (ps & domUtils.POSITION_FOLLOWING || ps & domUtils.POSITION_CONTAINS) + && + (pe & domUtils.POSITION_PRECEDING || pe & domUtils.POSITION_CONTAINS) + ) { + node = ci; + break; + } + } + } + return node; + } + + }, + queryCommandState : function() { + //判断如果是视频的话连接不可用 + //fix 853 + var img = this.selection.getRange().getClosedNode(), + flag = img && (img.className == "edui-faked-video" || img.className.indexOf("edui-upload-video")!=-1); + return flag ? -1 : 0; + } + }; +}; + +// plugins/iframe.js +///import core +///import plugins\inserthtml.js +///commands 插入框架 +///commandsName InsertFrame +///commandsTitle 插入Iframe +///commandsDialog dialogs\insertframe + +UE.plugins['insertframe'] = function() { + var me =this; + function deleteIframe(){ + me._iframe && delete me._iframe; + } + + me.addListener("selectionchange",function(){ + deleteIframe(); + }); + +}; + + + +// plugins/scrawl.js +///import core +///commands 涂鸦 +///commandsName Scrawl +///commandsTitle 涂鸦 +///commandsDialog dialogs\scrawl +UE.commands['scrawl'] = { + queryCommandState : function(){ + return ( browser.ie && browser.version <= 8 ) ? -1 :0; + } +}; + + +// plugins/removeformat.js +/** + * 清除格式 + * @file + * @since 1.2.6.1 + */ + +/** + * 清除文字样式 + * @command removeformat + * @method execCommand + * @param { String } cmd 命令字符串 + * @param {String} tags 以逗号隔开的标签。如:strong + * @param {String} style 样式如:color + * @param {String} attrs 属性如:width + * @example + * ```javascript + * editor.execCommand( 'removeformat', 'strong','color','width' ); + * ``` + */ + +UE.plugins['removeformat'] = function(){ + var me = this; + me.setOpt({ + 'removeFormatTags': 'b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var', + 'removeFormatAttributes':'class,style,lang,width,height,align,hspace,valign' + }); + me.commands['removeformat'] = { + execCommand : function( cmdName, tags, style, attrs,notIncludeA ) { + + var tagReg = new RegExp( '^(?:' + (tags || this.options.removeFormatTags).replace( /,/g, '|' ) + ')$', 'i' ) , + removeFormatAttributes = style ? [] : (attrs || this.options.removeFormatAttributes).split( ',' ), + range = new dom.Range( this.document ), + bookmark,node,parent, + filter = function( node ) { + return node.nodeType == 1; + }; + + function isRedundantSpan (node) { + if (node.nodeType == 3 || node.tagName.toLowerCase() != 'span'){ + return 0; + } + if (browser.ie) { + //ie 下判断实效,所以只能简单用style来判断 + //return node.style.cssText == '' ? 1 : 0; + var attrs = node.attributes; + if ( attrs.length ) { + for ( var i = 0,l = attrs.length; i + var node = range.startContainer, + tmp, + collapsed = range.collapsed; + while(node.nodeType == 1 && domUtils.isEmptyNode(node) && dtd.$removeEmpty[node.tagName]){ + tmp = node.parentNode; + range.setStartBefore(node); + //trace:937 + //更新结束边界 + if(range.startContainer === range.endContainer){ + range.endOffset--; + } + domUtils.remove(node); + node = tmp; + } + + if(!collapsed){ + node = range.endContainer; + while(node.nodeType == 1 && domUtils.isEmptyNode(node) && dtd.$removeEmpty[node.tagName]){ + tmp = node.parentNode; + range.setEndBefore(node); + domUtils.remove(node); + + node = tmp; + } + + + } + } + + + + range = this.selection.getRange(); + doRemove( range ); + range.select(); + + } + + }; + +}; + + +// plugins/blockquote.js +/** + * 添加引用 + * @file + * @since 1.2.6.1 + */ + +/** + * 添加引用 + * @command blockquote + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'blockquote' ); + * ``` + */ + +/** + * 添加引用 + * @command blockquote + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { Object } attrs 节点属性 + * @example + * ```javascript + * editor.execCommand( 'blockquote',{ + * style: "color: red;" + * } ); + * ``` + */ + + +UE.plugins['blockquote'] = function(){ + var me = this; + function getObj(editor){ + return domUtils.filterNodeList(editor.selection.getStartElementPath(),'blockquote'); + } + me.commands['blockquote'] = { + execCommand : function( cmdName, attrs ) { + var range = this.selection.getRange(), + obj = getObj(this), + blockquote = dtd.blockquote, + bookmark = range.createBookmark(); + + if ( obj ) { + + var start = range.startContainer, + startBlock = domUtils.isBlockElm(start) ? start : domUtils.findParent(start,function(node){return domUtils.isBlockElm(node)}), + + end = range.endContainer, + endBlock = domUtils.isBlockElm(end) ? end : domUtils.findParent(end,function(node){return domUtils.isBlockElm(node)}); + + //处理一下li + startBlock = domUtils.findParentByTagName(startBlock,'li',true) || startBlock; + endBlock = domUtils.findParentByTagName(endBlock,'li',true) || endBlock; + + + if(startBlock.tagName == 'LI' || startBlock.tagName == 'TD' || startBlock === obj || domUtils.isBody(startBlock)){ + domUtils.remove(obj,true); + }else{ + domUtils.breakParent(startBlock,obj); + } + + if(startBlock !== endBlock){ + obj = domUtils.findParentByTagName(endBlock,'blockquote'); + if(obj){ + if(endBlock.tagName == 'LI' || endBlock.tagName == 'TD'|| domUtils.isBody(endBlock)){ + obj.parentNode && domUtils.remove(obj,true); + }else{ + domUtils.breakParent(endBlock,obj); + } + + } + } + + var blockquotes = domUtils.getElementsByTagName(this.document,'blockquote'); + for(var i=0,bi;bi=blockquotes[i++];){ + if(!bi.childNodes.length){ + domUtils.remove(bi); + }else if(domUtils.getPosition(bi,startBlock)&domUtils.POSITION_FOLLOWING && domUtils.getPosition(bi,endBlock)&domUtils.POSITION_PRECEDING){ + domUtils.remove(bi,true); + } + } + + + + + } else { + + var tmpRange = range.cloneRange(), + node = tmpRange.startContainer.nodeType == 1 ? tmpRange.startContainer : tmpRange.startContainer.parentNode, + preNode = node, + doEnd = 1; + + //调整开始 + while ( 1 ) { + if ( domUtils.isBody(node) ) { + if ( preNode !== node ) { + if ( range.collapsed ) { + tmpRange.selectNode( preNode ); + doEnd = 0; + } else { + tmpRange.setStartBefore( preNode ); + } + }else{ + tmpRange.setStart(node,0); + } + + break; + } + if ( !blockquote[node.tagName] ) { + if ( range.collapsed ) { + tmpRange.selectNode( preNode ); + } else{ + tmpRange.setStartBefore( preNode); + } + break; + } + + preNode = node; + node = node.parentNode; + } + + //调整结束 + if ( doEnd ) { + preNode = node = node = tmpRange.endContainer.nodeType == 1 ? tmpRange.endContainer : tmpRange.endContainer.parentNode; + while ( 1 ) { + + if ( domUtils.isBody( node ) ) { + if ( preNode !== node ) { + + tmpRange.setEndAfter( preNode ); + + } else { + tmpRange.setEnd( node, node.childNodes.length ); + } + + break; + } + if ( !blockquote[node.tagName] ) { + tmpRange.setEndAfter( preNode ); + break; + } + + preNode = node; + node = node.parentNode; + } + + } + + + node = range.document.createElement( 'blockquote' ); + domUtils.setAttributes( node, attrs ); + node.appendChild( tmpRange.extractContents() ); + tmpRange.insertNode( node ); + //去除重复的 + var childs = domUtils.getElementsByTagName(node,'blockquote'); + for(var i=0,ci;ci=childs[i++];){ + if(ci.parentNode){ + domUtils.remove(ci,true); + } + } + + } + range.moveToBookmark( bookmark ).select(); + }, + queryCommandState : function() { + return getObj(this) ? 1 : 0; + } + }; +}; + + + +// plugins/convertcase.js +/** + * 大小写转换 + * @file + * @since 1.2.6.1 + */ + +/** + * 把选区内文本变大写,与“tolowercase”命令互斥 + * @command touppercase + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'touppercase' ); + * ``` + */ + +/** + * 把选区内文本变小写,与“touppercase”命令互斥 + * @command tolowercase + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'tolowercase' ); + * ``` + */ +UE.commands['touppercase'] = +UE.commands['tolowercase'] = { + execCommand:function (cmd) { + var me = this; + var rng = me.selection.getRange(); + if(rng.collapsed){ + return rng; + } + var bk = rng.createBookmark(), + bkEnd = bk.end, + filterFn = function( node ) { + return !domUtils.isBr(node) && !domUtils.isWhitespace( node ); + }, + curNode = domUtils.getNextDomNode( bk.start, false, filterFn ); + while ( curNode && (domUtils.getPosition( curNode, bkEnd ) & domUtils.POSITION_PRECEDING) ) { + + if ( curNode.nodeType == 3 ) { + curNode.nodeValue = curNode.nodeValue[cmd == 'touppercase' ? 'toUpperCase' : 'toLowerCase'](); + } + curNode = domUtils.getNextDomNode( curNode, true, filterFn ); + if(curNode === bkEnd){ + break; + } + + } + rng.moveToBookmark(bk).select(); + } +}; + + + +// plugins/indent.js +/** + * 首行缩进 + * @file + * @since 1.2.6.1 + */ + +/** + * 缩进 + * @command indent + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'indent' ); + * ``` + */ +UE.commands['indent'] = { + execCommand : function() { + var me = this,value = me.queryCommandState("indent") ? "0em" : (me.options.indentValue || '2em'); + me.execCommand('Paragraph','p',{style:'text-indent:'+ value}); + }, + queryCommandState : function() { + var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),'p h1 h2 h3 h4 h5 h6'); + return pN && pN.style.textIndent && parseInt(pN.style.textIndent) ? 1 : 0; + } + +}; + + +// plugins/print.js +/** + * 打印 + * @file + * @since 1.2.6.1 + */ + +/** + * 打印 + * @command print + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'print' ); + * ``` + */ +UE.commands['print'] = { + execCommand : function(){ + this.window.print(); + }, + notNeedUndo : 1 +}; + + + +// plugins/preview.js +/** + * 预览 + * @file + * @since 1.2.6.1 + */ + +/** + * 预览 + * @command preview + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'preview' ); + * ``` + */ +UE.commands['preview'] = { + execCommand : function(){ + var w = window.open('', '_blank', ''), + d = w.document; + d.open(); + d.write('
      '+this.getContent(null,null,true)+'
      '); + d.close(); + }, + notNeedUndo : 1 +}; + + +// plugins/selectall.js +/** + * 全选 + * @file + * @since 1.2.6.1 + */ + +/** + * 选中所有内容 + * @command selectall + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'selectall' ); + * ``` + */ +UE.plugins['selectall'] = function(){ + var me = this; + me.commands['selectall'] = { + execCommand : function(){ + //去掉了原生的selectAll,因为会出现报错和当内容为空时,不能出现闭合状态的光标 + var me = this,body = me.body, + range = me.selection.getRange(); + range.selectNodeContents(body); + if(domUtils.isEmptyBlock(body)){ + //opera不能自动合并到元素的里边,要手动处理一下 + if(browser.opera && body.firstChild && body.firstChild.nodeType == 1){ + range.setStartAtFirst(body.firstChild); + } + range.collapse(true); + } + range.select(true); + }, + notNeedUndo : 1 + }; + + + //快捷键 + me.addshortcutkey({ + "selectAll" : "ctrl+65" + }); +}; + + +// plugins/paragraph.js +/** + * 段落样式 + * @file + * @since 1.2.6.1 + */ + +/** + * 段落格式 + * @command paragraph + * @method execCommand + * @param { String } cmd 命令字符串 + * @param {String} style 标签值为:'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' + * @param {Object} attrs 标签的属性 + * @example + * ```javascript + * editor.execCommand( 'Paragraph','h1','{ + * class:'test' + * }' ); + * ``` + */ + +/** + * 返回选区内节点标签名 + * @command paragraph + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 节点标签名 + * @example + * ```javascript + * editor.queryCommandValue( 'Paragraph' ); + * ``` + */ + +UE.plugins['paragraph'] = function() { + var me = this, + block = domUtils.isBlockElm, + notExchange = ['TD','LI','PRE'], + + doParagraph = function(range,style,attrs,sourceCmdName){ + var bookmark = range.createBookmark(), + filterFn = function( node ) { + return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' && !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace( node ); + }, + para; + + range.enlarge( true ); + var bookmark2 = range.createBookmark(), + current = domUtils.getNextDomNode( bookmark2.start, false, filterFn ), + tmpRange = range.cloneRange(), + tmpNode; + while ( current && !(domUtils.getPosition( current, bookmark2.end ) & domUtils.POSITION_FOLLOWING) ) { + if ( current.nodeType == 3 || !block( current ) ) { + tmpRange.setStartBefore( current ); + while ( current && current !== bookmark2.end && !block( current ) ) { + tmpNode = current; + current = domUtils.getNextDomNode( current, false, null, function( node ) { + return !block( node ); + } ); + } + tmpRange.setEndAfter( tmpNode ); + + para = range.document.createElement( style ); + if(attrs){ + domUtils.setAttributes(para,attrs); + if(sourceCmdName && sourceCmdName == 'customstyle' && attrs.style){ + para.style.cssText = attrs.style; + } + } + para.appendChild( tmpRange.extractContents() ); + //需要内容占位 + if(domUtils.isEmptyNode(para)){ + domUtils.fillChar(range.document,para); + + } + + tmpRange.insertNode( para ); + + var parent = para.parentNode; + //如果para上一级是一个block元素且不是body,td就删除它 + if ( block( parent ) && !domUtils.isBody( para.parentNode ) && utils.indexOf(notExchange,parent.tagName)==-1) { + //存储dir,style + if(!(sourceCmdName && sourceCmdName == 'customstyle')){ + parent.getAttribute('dir') && para.setAttribute('dir',parent.getAttribute('dir')); + //trace:1070 + parent.style.cssText && (para.style.cssText = parent.style.cssText + ';' + para.style.cssText); + //trace:1030 + parent.style.textAlign && !para.style.textAlign && (para.style.textAlign = parent.style.textAlign); + parent.style.textIndent && !para.style.textIndent && (para.style.textIndent = parent.style.textIndent); + parent.style.padding && !para.style.padding && (para.style.padding = parent.style.padding); + } + + //trace:1706 选择的就是h1-6要删除 + if(attrs && /h\d/i.test(parent.tagName) && !/h\d/i.test(para.tagName) ){ + domUtils.setAttributes(parent,attrs); + if(sourceCmdName && sourceCmdName == 'customstyle' && attrs.style){ + parent.style.cssText = attrs.style; + } + domUtils.remove(para,true); + para = parent; + }else{ + domUtils.remove( para.parentNode, true ); + } + + } + if( utils.indexOf(notExchange,parent.tagName)!=-1){ + current = parent; + }else{ + current = para; + } + + + current = domUtils.getNextDomNode( current, false, filterFn ); + } else { + current = domUtils.getNextDomNode( current, true, filterFn ); + } + } + return range.moveToBookmark( bookmark2 ).moveToBookmark( bookmark ); + }; + me.setOpt('paragraph',{'p':'', 'h1':'', 'h2':'', 'h3':'', 'h4':'', 'h5':'', 'h6':''}); + me.commands['paragraph'] = { + execCommand : function( cmdName, style,attrs,sourceCmdName ) { + var range = this.selection.getRange(); + //闭合时单独处理 + if(range.collapsed){ + var txt = this.document.createTextNode('p'); + range.insertNode(txt); + //去掉冗余的fillchar + if(browser.ie){ + var node = txt.previousSibling; + if(node && domUtils.isWhitespace(node)){ + domUtils.remove(node); + } + node = txt.nextSibling; + if(node && domUtils.isWhitespace(node)){ + domUtils.remove(node); + } + } + + } + range = doParagraph(range,style,attrs,sourceCmdName); + if(txt){ + range.setStartBefore(txt).collapse(true); + pN = txt.parentNode; + + domUtils.remove(txt); + + if(domUtils.isBlockElm(pN)&&domUtils.isEmptyNode(pN)){ + domUtils.fillNode(this.document,pN); + } + + } + + if(browser.gecko && range.collapsed && range.startContainer.nodeType == 1){ + var child = range.startContainer.childNodes[range.startOffset]; + if(child && child.nodeType == 1 && child.tagName.toLowerCase() == style){ + range.setStart(child,0).collapse(true); + } + } + //trace:1097 原来有true,原因忘了,但去了就不能清除多余的占位符了 + range.select(); + + + return true; + }, + queryCommandValue : function() { + var node = domUtils.filterNodeList(this.selection.getStartElementPath(),'p h1 h2 h3 h4 h5 h6'); + return node ? node.tagName.toLowerCase() : ''; + } + }; +}; + + +// plugins/directionality.js +/** + * 设置文字输入的方向的插件 + * @file + * @since 1.2.6.1 + */ +(function() { + var block = domUtils.isBlockElm , + getObj = function(editor){ +// var startNode = editor.selection.getStart(), +// parents; +// if ( startNode ) { +// //查找所有的是block的父亲节点 +// parents = domUtils.findParents( startNode, true, block, true ); +// for ( var i = 0,ci; ci = parents[i++]; ) { +// if ( ci.getAttribute( 'dir' ) ) { +// return ci; +// } +// } +// } + return domUtils.filterNodeList(editor.selection.getStartElementPath(),function(n){return n && n.nodeType == 1 && n.getAttribute('dir')}); + + }, + doDirectionality = function(range,editor,forward){ + + var bookmark, + filterFn = function( node ) { + return node.nodeType == 1 ? !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace(node); + }, + + obj = getObj( editor ); + + if ( obj && range.collapsed ) { + obj.setAttribute( 'dir', forward ); + return range; + } + bookmark = range.createBookmark(); + range.enlarge( true ); + var bookmark2 = range.createBookmark(), + current = domUtils.getNextDomNode( bookmark2.start, false, filterFn ), + tmpRange = range.cloneRange(), + tmpNode; + while ( current && !(domUtils.getPosition( current, bookmark2.end ) & domUtils.POSITION_FOLLOWING) ) { + if ( current.nodeType == 3 || !block( current ) ) { + tmpRange.setStartBefore( current ); + while ( current && current !== bookmark2.end && !block( current ) ) { + tmpNode = current; + current = domUtils.getNextDomNode( current, false, null, function( node ) { + return !block( node ); + } ); + } + tmpRange.setEndAfter( tmpNode ); + var common = tmpRange.getCommonAncestor(); + if ( !domUtils.isBody( common ) && block( common ) ) { + //遍历到了block节点 + common.setAttribute( 'dir', forward ); + current = common; + } else { + //没有遍历到,添加一个block节点 + var p = range.document.createElement( 'p' ); + p.setAttribute( 'dir', forward ); + var frag = tmpRange.extractContents(); + p.appendChild( frag ); + tmpRange.insertNode( p ); + current = p; + } + + current = domUtils.getNextDomNode( current, false, filterFn ); + } else { + current = domUtils.getNextDomNode( current, true, filterFn ); + } + } + return range.moveToBookmark( bookmark2 ).moveToBookmark( bookmark ); + }; + + /** + * 文字输入方向 + * @command directionality + * @method execCommand + * @param { String } cmdName 命令字符串 + * @param { String } forward 传入'ltr'表示从左向右输入,传入'rtl'表示从右向左输入 + * @example + * ```javascript + * editor.execCommand( 'directionality', 'ltr'); + * ``` + */ + + /** + * 查询当前选区的文字输入方向 + * @command directionality + * @method queryCommandValue + * @param { String } cmdName 命令字符串 + * @return { String } 返回'ltr'表示从左向右输入,返回'rtl'表示从右向左输入 + * @example + * ```javascript + * editor.queryCommandValue( 'directionality'); + * ``` + */ + UE.commands['directionality'] = { + execCommand : function( cmdName,forward ) { + var range = this.selection.getRange(); + //闭合时单独处理 + if(range.collapsed){ + var txt = this.document.createTextNode('d'); + range.insertNode(txt); + } + doDirectionality(range,this,forward); + if(txt){ + range.setStartBefore(txt).collapse(true); + domUtils.remove(txt); + } + + range.select(); + return true; + }, + queryCommandValue : function() { + var node = getObj(this); + return node ? node.getAttribute('dir') : 'ltr'; + } + }; +})(); + + + +// plugins/horizontal.js +/** + * 插入分割线插件 + * @file + * @since 1.2.6.1 + */ + +/** + * 插入分割线 + * @command horizontal + * @method execCommand + * @param { String } cmdName 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'horizontal' ); + * ``` + */ +UE.plugins['horizontal'] = function(){ + var me = this; + me.commands['horizontal'] = { + execCommand : function( cmdName ) { + var me = this; + if(me.queryCommandState(cmdName)!==-1){ + me.execCommand('insertHtml','
      '); + var range = me.selection.getRange(), + start = range.startContainer; + if(start.nodeType == 1 && !start.childNodes[range.startOffset] ){ + + var tmp; + if(tmp = start.childNodes[range.startOffset - 1]){ + if(tmp.nodeType == 1 && tmp.tagName == 'HR'){ + if(me.options.enterTag == 'p'){ + tmp = me.document.createElement('p'); + range.insertNode(tmp); + range.setStart(tmp,0).setCursor(); + + }else{ + tmp = me.document.createElement('br'); + range.insertNode(tmp); + range.setStartBefore(tmp).setCursor(); + } + } + } + + } + return true; + } + + }, + //边界在table里不能加分隔线 + queryCommandState : function() { + return domUtils.filterNodeList(this.selection.getStartElementPath(),'table') ? -1 : 0; + } + }; +// me.addListener('delkeyup',function(){ +// var rng = this.selection.getRange(); +// if(browser.ie && browser.version > 8){ +// rng.txtToElmBoundary(true); +// if(domUtils.isStartInblock(rng)){ +// var tmpNode = rng.startContainer; +// var pre = tmpNode.previousSibling; +// if(pre && domUtils.isTagNode(pre,'hr')){ +// domUtils.remove(pre); +// rng.select(); +// return; +// } +// } +// } +// if(domUtils.isBody(rng.startContainer)){ +// var hr = rng.startContainer.childNodes[rng.startOffset -1]; +// if(hr && hr.nodeName == 'HR'){ +// var next = hr.nextSibling; +// if(next){ +// rng.setStart(next,0) +// }else if(hr.previousSibling){ +// rng.setStartAtLast(hr.previousSibling) +// }else{ +// var p = this.document.createElement('p'); +// hr.parentNode.insertBefore(p,hr); +// domUtils.fillNode(this.document,p); +// rng.setStart(p,0); +// } +// domUtils.remove(hr); +// rng.setCursor(false,true); +// } +// } +// }) + me.addListener('delkeydown',function(name,evt){ + var rng = this.selection.getRange(); + rng.txtToElmBoundary(true); + if(domUtils.isStartInblock(rng)){ + var tmpNode = rng.startContainer; + var pre = tmpNode.previousSibling; + if(pre && domUtils.isTagNode(pre,'hr')){ + domUtils.remove(pre); + rng.select(); + domUtils.preventDefault(evt); + return true; + + } + } + + }) +}; + + + +// plugins/time.js +/** + * 插入时间和日期 + * @file + * @since 1.2.6.1 + */ + +/** + * 插入时间,默认格式:12:59:59 + * @command time + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'time'); + * ``` + */ + +/** + * 插入日期,默认格式:2013-08-30 + * @command date + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'date'); + * ``` + */ +UE.commands['time'] = UE.commands["date"] = { + execCommand : function(cmd, format){ + var date = new Date; + + function formatTime(date, format) { + var hh = ('0' + date.getHours()).slice(-2), + ii = ('0' + date.getMinutes()).slice(-2), + ss = ('0' + date.getSeconds()).slice(-2); + format = format || 'hh:ii:ss'; + return format.replace(/hh/ig, hh).replace(/ii/ig, ii).replace(/ss/ig, ss); + } + function formatDate(date, format) { + var yyyy = ('000' + date.getFullYear()).slice(-4), + yy = yyyy.slice(-2), + mm = ('0' + (date.getMonth()+1)).slice(-2), + dd = ('0' + date.getDate()).slice(-2); + format = format || 'yyyy-mm-dd'; + return format.replace(/yyyy/ig, yyyy).replace(/yy/ig, yy).replace(/mm/ig, mm).replace(/dd/ig, dd); + } + + this.execCommand('insertHtml',cmd == "time" ? formatTime(date, format):formatDate(date, format) ); + } +}; + + +// plugins/rowspacing.js +/** + * 段前段后间距插件 + * @file + * @since 1.2.6.1 + */ + +/** + * 设置段间距 + * @command rowspacing + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } value 段间距的值,以px为单位 + * @param { String } dir 间距位置,top或bottom,分别表示段前和段后 + * @example + * ```javascript + * editor.execCommand( 'rowspacing', '10', 'top' ); + * ``` + */ + +UE.plugins['rowspacing'] = function(){ + var me = this; + me.setOpt({ + 'rowspacingtop':['5', '10', '15', '20', '25'], + 'rowspacingbottom':['5', '10', '15', '20', '25'] + + }); + me.commands['rowspacing'] = { + execCommand : function( cmdName,value,dir ) { + this.execCommand('paragraph','p',{style:'margin-'+dir+':'+value + 'px'}); + return true; + }, + queryCommandValue : function(cmdName,dir) { + var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),function(node){return domUtils.isBlockElm(node) }), + value; + //trace:1026 + if(pN){ + value = domUtils.getComputedStyle(pN,'margin-'+dir).replace(/[^\d]/g,''); + return !value ? 0 : value; + } + return 0; + + } + }; +}; + + + + +// plugins/lineheight.js +/** + * 设置行内间距 + * @file + * @since 1.2.6.1 + */ +UE.plugins['lineheight'] = function(){ + var me = this; + me.setOpt({'lineheight':['1', '1.5','1.75','2', '3', '4', '5']}); + + /** + * 行距 + * @command lineheight + * @method execCommand + * @param { String } cmdName 命令字符串 + * @param { String } value 传入的行高值, 该值是当前字体的倍数, 例如: 1.5, 1.75 + * @example + * ```javascript + * editor.execCommand( 'lineheight', 1.5); + * ``` + */ + /** + * 查询当前选区内容的行高大小 + * @command lineheight + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回当前行高大小 + * @example + * ```javascript + * editor.queryCommandValue( 'lineheight' ); + * ``` + */ + + me.commands['lineheight'] = { + execCommand : function( cmdName,value ) { + this.execCommand('paragraph','p',{style:'line-height:'+ (value == "1" ? "normal" : value + 'em') }); + return true; + }, + queryCommandValue : function() { + var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),function(node){return domUtils.isBlockElm(node)}); + if(pN){ + var value = domUtils.getComputedStyle(pN,'line-height'); + return value == 'normal' ? 1 : value.replace(/[^\d.]*/ig,""); + } + } + }; +}; + + + + +// plugins/insertcode.js +/** + * 插入代码插件 + * @file + * @since 1.2.6.1 + */ + +UE.plugins['insertcode'] = function() { + var me = this; + me.ready(function(){ + utils.cssRule('pre','pre{margin:.5em 0;padding:.4em .6em;border-radius:8px;background:#f8f8f8;}', + me.document) + }); + me.setOpt('insertcode',{ + 'as3':'ActionScript3', + 'bash':'Bash/Shell', + 'cpp':'C/C++', + 'css':'Css', + 'cf':'CodeFunction', + 'c#':'C#', + 'delphi':'Delphi', + 'diff':'Diff', + 'erlang':'Erlang', + 'groovy':'Groovy', + 'html':'Html', + 'java':'Java', + 'jfx':'JavaFx', + 'js':'Javascript', + 'pl':'Perl', + 'php':'Php', + 'plain':'Plain Text', + 'ps':'PowerShell', + 'python':'Python', + 'ruby':'Ruby', + 'scala':'Scala', + 'sql':'Sql', + 'vb':'Vb', + 'xml':'Xml' + }); + + /** + * 插入代码 + * @command insertcode + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } lang 插入代码的语言 + * @example + * ```javascript + * editor.execCommand( 'insertcode', 'javascript' ); + * ``` + */ + + /** + * 如果选区所在位置是插入插入代码区域,返回代码的语言 + * @command insertcode + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回代码的语言 + * @example + * ```javascript + * editor.queryCommandValue( 'insertcode' ); + * ``` + */ + + me.commands['insertcode'] = { + execCommand : function(cmd,lang){ + var me = this, + rng = me.selection.getRange(), + pre = domUtils.findParentByTagName(rng.startContainer,'pre',true); + if(pre){ + pre.className = 'brush:'+lang+';toolbar:false;'; + }else{ + var code = ''; + if(rng.collapsed){ + code = browser.ie && browser.ie11below ? (browser.version <= 8 ? ' ':''):'
      '; + }else{ + var frag = rng.extractContents(); + var div = me.document.createElement('div'); + div.appendChild(frag); + + utils.each(UE.filterNode(UE.htmlparser(div.innerHTML.replace(/[\r\t]/g,'')),me.options.filterTxtRules).children,function(node){ + if(browser.ie && browser.ie11below && browser.version > 8){ + + if(node.type =='element'){ + if(node.tagName == 'br'){ + code += '\n' + }else if(!dtd.$empty[node.tagName]){ + utils.each(node.children,function(cn){ + if(cn.type =='element'){ + if(cn.tagName == 'br'){ + code += '\n' + }else if(!dtd.$empty[node.tagName]){ + code += cn.innerText(); + } + }else{ + code += cn.data + } + }) + if(!/\n$/.test(code)){ + code += '\n'; + } + } + }else{ + code += node.data + '\n' + } + if(!node.nextSibling() && /\n$/.test(code)){ + code = code.replace(/\n$/,''); + } + }else{ + if(browser.ie && browser.ie11below){ + + if(node.type =='element'){ + if(node.tagName == 'br'){ + code += '
      ' + }else if(!dtd.$empty[node.tagName]){ + utils.each(node.children,function(cn){ + if(cn.type =='element'){ + if(cn.tagName == 'br'){ + code += '
      ' + }else if(!dtd.$empty[node.tagName]){ + code += cn.innerText(); + } + }else{ + code += cn.data + } + }); + if(!/br>$/.test(code)){ + code += '
      '; + } + } + }else{ + code += node.data + '
      ' + } + if(!node.nextSibling() && /
      $/.test(code)){ + code = code.replace(/
      $/,''); + } + + }else{ + code += (node.type == 'element' ? (dtd.$empty[node.tagName] ? '' : node.innerText()) : node.data); + if(!/br\/?\s*>$/.test(code)){ + if(!node.nextSibling()) + return; + code += '
      ' + } + } + + } + + }); + } + me.execCommand('inserthtml','
      '+code+'
      ',true); + + pre = me.document.getElementById('coder'); + domUtils.removeAttributes(pre,'id'); + var tmpNode = pre.previousSibling; + + if(tmpNode && (tmpNode.nodeType == 3 && tmpNode.nodeValue.length == 1 && browser.ie && browser.version == 6 || domUtils.isEmptyBlock(tmpNode))){ + + domUtils.remove(tmpNode) + } + var rng = me.selection.getRange(); + if(domUtils.isEmptyBlock(pre)){ + rng.setStart(pre,0).setCursor(false,true) + }else{ + rng.selectNodeContents(pre).select() + } + } + + + + }, + queryCommandValue : function(){ + var path = this.selection.getStartElementPath(); + var lang = ''; + utils.each(path,function(node){ + if(node.nodeName =='PRE'){ + var match = node.className.match(/brush:([^;]+)/); + lang = match && match[1] ? match[1] : ''; + return false; + } + }); + return lang; + } + }; + + me.addInputRule(function(root){ + utils.each(root.getNodesByTagName('pre'),function(pre){ + var brs = pre.getNodesByTagName('br'); + if(brs.length){ + browser.ie && browser.ie11below && browser.version > 8 && utils.each(brs,function(br){ + var txt = UE.uNode.createText('\n'); + br.parentNode.insertBefore(txt,br); + br.parentNode.removeChild(br); + }); + return; + } + if(browser.ie && browser.ie11below && browser.version > 8) + return; + var code = pre.innerText().split(/\n/); + pre.innerHTML(''); + utils.each(code,function(c){ + if(c.length){ + pre.appendChild(UE.uNode.createText(c)); + } + pre.appendChild(UE.uNode.createElement('br')) + }) + }) + }); + me.addOutputRule(function(root){ + utils.each(root.getNodesByTagName('pre'),function(pre){ + var code = ''; + utils.each(pre.children,function(n){ + if(n.type == 'text'){ + //在ie下文本内容有可能末尾带有\n要去掉 + //trace:3396 + code += n.data.replace(/[ ]/g,' ').replace(/\n$/,''); + }else{ + if(n.tagName == 'br'){ + code += '\n' + }else{ + code += (!dtd.$empty[n.tagName] ? '' : n.innerText()); + } + + } + + }); + + pre.innerText(code.replace(/( |\n)+$/,'')) + }) + }); + //不需要判断highlight的command列表 + me.notNeedCodeQuery ={ + help:1, + undo:1, + redo:1, + source:1, + print:1, + searchreplace:1, + fullscreen:1, + preview:1, + insertparagraph:1, + elementpath:1, + insertcode:1, + inserthtml:1, + selectall:1 + }; + //将queyCommamndState重置 + var orgQuery = me.queryCommandState; + me.queryCommandState = function(cmd){ + var me = this; + + if(!me.notNeedCodeQuery[cmd.toLowerCase()] && me.selection && me.queryCommandValue('insertcode')){ + return -1; + } + return UE.Editor.prototype.queryCommandState.apply(this,arguments) + }; + me.addListener('beforeenterkeydown',function(){ + var rng = me.selection.getRange(); + var pre = domUtils.findParentByTagName(rng.startContainer,'pre',true); + if(pre){ + me.fireEvent('saveScene'); + if(!rng.collapsed){ + rng.deleteContents(); + } + if(!browser.ie || browser.ie9above){ + var tmpNode = me.document.createElement('br'),pre; + rng.insertNode(tmpNode).setStartAfter(tmpNode).collapse(true); + var next = tmpNode.nextSibling; + if(!next && (!browser.ie || browser.version > 10)){ + rng.insertNode(tmpNode.cloneNode(false)); + }else{ + rng.setStartAfter(tmpNode); + } + pre = tmpNode.previousSibling; + var tmp; + while(pre ){ + tmp = pre; + pre = pre.previousSibling; + if(!pre || pre.nodeName == 'BR'){ + pre = tmp; + break; + } + } + if(pre){ + var str = ''; + while(pre && pre.nodeName != 'BR' && new RegExp('^[\\s'+domUtils.fillChar+']*$').test(pre.nodeValue)){ + str += pre.nodeValue; + pre = pre.nextSibling; + } + if(pre.nodeName != 'BR'){ + var match = pre.nodeValue.match(new RegExp('^([\\s'+domUtils.fillChar+']+)')); + if(match && match[1]){ + str += match[1] + } + + } + if(str){ + str = me.document.createTextNode(str); + rng.insertNode(str).setStartAfter(str); + } + } + rng.collapse(true).select(true); + }else{ + if(browser.version > 8){ + + var txt = me.document.createTextNode('\n'); + var start = rng.startContainer; + if(rng.startOffset == 0){ + var preNode = start.previousSibling; + if(preNode){ + rng.insertNode(txt); + var fillchar = me.document.createTextNode(' '); + rng.setStartAfter(txt).insertNode(fillchar).setStart(fillchar,0).collapse(true).select(true) + } + }else{ + rng.insertNode(txt).setStartAfter(txt); + var fillchar = me.document.createTextNode(' '); + start = rng.startContainer.childNodes[rng.startOffset]; + if(start && !/^\n/.test(start.nodeValue)){ + rng.setStartBefore(txt) + } + rng.insertNode(fillchar).setStart(fillchar,0).collapse(true).select(true) + } + + }else{ + var tmpNode = me.document.createElement('br'); + rng.insertNode(tmpNode); + rng.insertNode(me.document.createTextNode(domUtils.fillChar)); + rng.setStartAfter(tmpNode); + pre = tmpNode.previousSibling; + var tmp; + while(pre ){ + tmp = pre; + pre = pre.previousSibling; + if(!pre || pre.nodeName == 'BR'){ + pre = tmp; + break; + } + } + if(pre){ + var str = ''; + while(pre && pre.nodeName != 'BR' && new RegExp('^[ '+domUtils.fillChar+']*$').test(pre.nodeValue)){ + str += pre.nodeValue; + pre = pre.nextSibling; + } + if(pre.nodeName != 'BR'){ + var match = pre.nodeValue.match(new RegExp('^([ '+domUtils.fillChar+']+)')); + if(match && match[1]){ + str += match[1] + } + + } + + str = me.document.createTextNode(str); + rng.insertNode(str).setStartAfter(str); + } + rng.collapse(true).select(); + } + + + } + me.fireEvent('saveScene'); + return true; + } + + + }); + + me.addListener('tabkeydown',function(cmd,evt){ + var rng = me.selection.getRange(); + var pre = domUtils.findParentByTagName(rng.startContainer,'pre',true); + if(pre){ + me.fireEvent('saveScene'); + if(evt.shiftKey){ + + }else{ + if(!rng.collapsed){ + var bk = rng.createBookmark(); + var start = bk.start.previousSibling; + + while(start){ + if(pre.firstChild === start && !domUtils.isBr(start)){ + pre.insertBefore(me.document.createTextNode(' '),start); + + break; + } + if(domUtils.isBr(start)){ + pre.insertBefore(me.document.createTextNode(' '),start.nextSibling); + + break; + } + start = start.previousSibling; + } + var end = bk.end; + start = bk.start.nextSibling; + if(pre.firstChild === bk.start){ + pre.insertBefore(me.document.createTextNode(' '),start.nextSibling) + + } + while(start && start !== end){ + if(domUtils.isBr(start) && start.nextSibling){ + if(start.nextSibling === end){ + break; + } + pre.insertBefore(me.document.createTextNode(' '),start.nextSibling) + } + + start = start.nextSibling; + } + rng.moveToBookmark(bk).select(); + }else{ + var tmpNode = me.document.createTextNode(' '); + rng.insertNode(tmpNode).setStartAfter(tmpNode).collapse(true).select(true); + } + } + + + me.fireEvent('saveScene'); + return true; + } + + + }); + + + me.addListener('beforeinserthtml',function(evtName,html){ + var me = this, + rng = me.selection.getRange(), + pre = domUtils.findParentByTagName(rng.startContainer,'pre',true); + if(pre){ + if(!rng.collapsed){ + rng.deleteContents() + } + var htmlstr = ''; + if(browser.ie && browser.version > 8){ + + utils.each(UE.filterNode(UE.htmlparser(html),me.options.filterTxtRules).children,function(node){ + if(node.type =='element'){ + if(node.tagName == 'br'){ + htmlstr += '\n' + }else if(!dtd.$empty[node.tagName]){ + utils.each(node.children,function(cn){ + if(cn.type =='element'){ + if(cn.tagName == 'br'){ + htmlstr += '\n' + }else if(!dtd.$empty[node.tagName]){ + htmlstr += cn.innerText(); + } + }else{ + htmlstr += cn.data + } + }) + if(!/\n$/.test(htmlstr)){ + htmlstr += '\n'; + } + } + }else{ + htmlstr += node.data + '\n' + } + if(!node.nextSibling() && /\n$/.test(htmlstr)){ + htmlstr = htmlstr.replace(/\n$/,''); + } + }); + var tmpNode = me.document.createTextNode(utils.html(htmlstr.replace(/ /g,' '))); + rng.insertNode(tmpNode).selectNode(tmpNode).select(); + }else{ + var frag = me.document.createDocumentFragment(); + + utils.each(UE.filterNode(UE.htmlparser(html),me.options.filterTxtRules).children,function(node){ + if(node.type =='element'){ + if(node.tagName == 'br'){ + frag.appendChild(me.document.createElement('br')) + }else if(!dtd.$empty[node.tagName]){ + utils.each(node.children,function(cn){ + if(cn.type =='element'){ + if(cn.tagName == 'br'){ + + frag.appendChild(me.document.createElement('br')) + }else if(!dtd.$empty[node.tagName]){ + frag.appendChild(me.document.createTextNode(utils.html(cn.innerText().replace(/ /g,' ')))); + + } + }else{ + frag.appendChild(me.document.createTextNode(utils.html( cn.data.replace(/ /g,' ')))); + + } + }) + if(frag.lastChild.nodeName != 'BR'){ + frag.appendChild(me.document.createElement('br')) + } + } + }else{ + frag.appendChild(me.document.createTextNode(utils.html( node.data.replace(/ /g,' ')))); + } + if(!node.nextSibling() && frag.lastChild.nodeName == 'BR'){ + frag.removeChild(frag.lastChild) + } + + + }); + rng.insertNode(frag).select(); + + } + + return true; + } + }); + //方向键的处理 + me.addListener('keydown',function(cmd,evt){ + var me = this,keyCode = evt.keyCode || evt.which; + if(keyCode == 40){ + var rng = me.selection.getRange(),pre,start = rng.startContainer; + if(rng.collapsed && (pre = domUtils.findParentByTagName(rng.startContainer,'pre',true)) && !pre.nextSibling){ + var last = pre.lastChild + while(last && last.nodeName == 'BR'){ + last = last.previousSibling; + } + if(last === start || rng.startContainer === pre && rng.startOffset == pre.childNodes.length){ + me.execCommand('insertparagraph'); + domUtils.preventDefault(evt) + } + + } + } + }); + //trace:3395 + me.addListener('delkeydown',function(type,evt){ + var rng = this.selection.getRange(); + rng.txtToElmBoundary(true); + var start = rng.startContainer; + if(domUtils.isTagNode(start,'pre') && rng.collapsed && domUtils.isStartInblock(rng)){ + var p = me.document.createElement('p'); + domUtils.fillNode(me.document,p); + start.parentNode.insertBefore(p,start); + domUtils.remove(start); + rng.setStart(p,0).setCursor(false,true); + domUtils.preventDefault(evt); + return true; + } + }) +}; + + +// plugins/cleardoc.js +/** + * 清空文档插件 + * @file + * @since 1.2.6.1 + */ + +/** + * 清空文档 + * @command cleardoc + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * //editor 是编辑器实例 + * editor.execCommand('cleardoc'); + * ``` + */ + +UE.commands['cleardoc'] = { + execCommand : function( cmdName) { + var me = this, + enterTag = me.options.enterTag, + range = me.selection.getRange(); + if(enterTag == "br"){ + me.body.innerHTML = "
      "; + range.setStart(me.body,0).setCursor(); + }else{ + me.body.innerHTML = "

      "+(ie ? "" : "
      ")+"

      "; + range.setStart(me.body.firstChild,0).setCursor(false,true); + } + setTimeout(function(){ + me.fireEvent("clearDoc"); + },0); + + } +}; + + + +// plugins/anchor.js +/** + * 锚点插件,为UEditor提供插入锚点支持 + * @file + * @since 1.2.6.1 + */ +UE.plugin.register('anchor', function (){ + + return { + bindEvents:{ + 'ready':function(){ + utils.cssRule('anchor', + '.anchorclass{background: url(\'' + + this.options.themePath + + this.options.theme +'/images/anchor.gif\') no-repeat scroll left center transparent;cursor: auto;display: inline-block;height: 16px;width: 15px;}', + this.document); + } + }, + outputRule: function(root){ + utils.each(root.getNodesByTagName('img'),function(a){ + var val; + if(val = a.getAttr('anchorname')){ + a.tagName = 'a'; + a.setAttr({ + anchorname : '', + name : val, + 'class' : '' + }) + } + }) + }, + inputRule:function(root){ + utils.each(root.getNodesByTagName('a'),function(a){ + var val; + if((val = a.getAttr('name')) && !a.getAttr('href')){ + a.tagName = 'img'; + a.setAttr({ + anchorname :a.getAttr('name'), + 'class' : 'anchorclass' + }); + a.setAttr('name') + + } + }) + + }, + commands:{ + /** + * 插入锚点 + * @command anchor + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } name 锚点名称字符串 + * @example + * ```javascript + * //editor 是编辑器实例 + * editor.execCommand('anchor', 'anchor1'); + * ``` + */ + 'anchor':{ + execCommand:function (cmd, name) { + var range = this.selection.getRange(),img = range.getClosedNode(); + if (img && img.getAttribute('anchorname')) { + if (name) { + img.setAttribute('anchorname', name); + } else { + range.setStartBefore(img).setCursor(); + domUtils.remove(img); + } + } else { + if (name) { + //只在选区的开始插入 + var anchor = this.document.createElement('img'); + range.collapse(true); + domUtils.setAttributes(anchor,{ + 'anchorname':name, + 'class':'anchorclass' + }); + range.insertNode(anchor).setStartAfter(anchor).setCursor(false,true); + } + } + } + } + } + } +}); + + +// plugins/wordcount.js +///import core +///commands 字数统计 +///commandsName WordCount,wordCount +///commandsTitle 字数统计 +/* + * Created by JetBrains WebStorm. + * User: taoqili + * Date: 11-9-7 + * Time: 下午8:18 + * To change this template use File | Settings | File Templates. + */ + +UE.plugins['wordcount'] = function(){ + var me = this; + me.setOpt('wordCount',true); + me.addListener('contentchange',function(){ + me.fireEvent('wordcount'); + }); + var timer; + me.addListener('ready',function(){ + var me = this; + domUtils.on(me.body,"keyup",function(evt){ + var code = evt.keyCode||evt.which, + //忽略的按键,ctr,alt,shift,方向键 + ignores = {"16":1,"18":1,"20":1,"37":1,"38":1,"39":1,"40":1}; + if(code in ignores) return; + clearTimeout(timer); + timer = setTimeout(function(){ + me.fireEvent('wordcount'); + },200) + }) + }); +}; + + +// plugins/pagebreak.js +/** + * 分页功能插件 + * @file + * @since 1.2.6.1 + */ +UE.plugins['pagebreak'] = function () { + var me = this, + notBreakTags = ['td']; + me.setOpt('pageBreakTag','_ueditor_page_break_tag_'); + + function fillNode(node){ + if(domUtils.isEmptyBlock(node)){ + var firstChild = node.firstChild,tmpNode; + + while(firstChild && firstChild.nodeType == 1 && domUtils.isEmptyBlock(firstChild)){ + tmpNode = firstChild; + firstChild = firstChild.firstChild; + } + !tmpNode && (tmpNode = node); + domUtils.fillNode(me.document,tmpNode); + } + } + //分页符样式添加 + + me.ready(function(){ + utils.cssRule('pagebreak','.pagebreak{display:block;clear:both !important;cursor:default !important;width: 100% !important;margin:0;}',me.document); + }); + function isHr(node){ + return node && node.nodeType == 1 && node.tagName == 'HR' && node.className == 'pagebreak'; + } + me.addInputRule(function(root){ + root.traversal(function(node){ + if(node.type == 'text' && node.data == me.options.pageBreakTag){ + var hr = UE.uNode.createElement('
      '); + node.parentNode.insertBefore(hr,node); + node.parentNode.removeChild(node) + } + }) + }); + me.addOutputRule(function(node){ + utils.each(node.getNodesByTagName('hr'),function(n){ + if(n.getAttr('class') == 'pagebreak'){ + var txt = UE.uNode.createText(me.options.pageBreakTag); + n.parentNode.insertBefore(txt,n); + n.parentNode.removeChild(n); + } + }) + + }); + + /** + * 插入分页符 + * @command pagebreak + * @method execCommand + * @param { String } cmd 命令字符串 + * @remind 在表格中插入分页符会把表格切分成两部分 + * @remind 获取编辑器内的数据时, 编辑器会把分页符转换成“_ueditor_page_break_tag_”字符串, + * 以便于提交数据到服务器端后处理分页。 + * @example + * ```javascript + * editor.execCommand( 'pagebreak'); //插入一个hr标签,带有样式类名pagebreak + * ``` + */ + + me.commands['pagebreak'] = { + execCommand:function () { + var range = me.selection.getRange(),hr = me.document.createElement('hr'); + domUtils.setAttributes(hr,{ + 'class' : 'pagebreak', + noshade:"noshade", + size:"5" + }); + domUtils.unSelectable(hr); + //table单独处理 + var node = domUtils.findParentByTagName(range.startContainer, notBreakTags, true), + + parents = [], pN; + if (node) { + switch (node.tagName) { + case 'TD': + pN = node.parentNode; + if (!pN.previousSibling) { + var table = domUtils.findParentByTagName(pN, 'table'); +// var tableWrapDiv = table.parentNode; +// if(tableWrapDiv && tableWrapDiv.nodeType == 1 +// && tableWrapDiv.tagName == 'DIV' +// && tableWrapDiv.getAttribute('dropdrag') +// ){ +// domUtils.remove(tableWrapDiv,true); +// } + table.parentNode.insertBefore(hr, table); + parents = domUtils.findParents(hr, true); + + } else { + pN.parentNode.insertBefore(hr, pN); + parents = domUtils.findParents(hr); + + } + pN = parents[1]; + if (hr !== pN) { + domUtils.breakParent(hr, pN); + + } + //table要重写绑定一下拖拽 + me.fireEvent('afteradjusttable',me.document); + } + + } else { + + if (!range.collapsed) { + range.deleteContents(); + var start = range.startContainer; + while ( !domUtils.isBody(start) && domUtils.isBlockElm(start) && domUtils.isEmptyNode(start)) { + range.setStartBefore(start).collapse(true); + domUtils.remove(start); + start = range.startContainer; + } + + } + range.insertNode(hr); + + var pN = hr.parentNode, nextNode; + while (!domUtils.isBody(pN)) { + domUtils.breakParent(hr, pN); + nextNode = hr.nextSibling; + if (nextNode && domUtils.isEmptyBlock(nextNode)) { + domUtils.remove(nextNode); + } + pN = hr.parentNode; + } + nextNode = hr.nextSibling; + var pre = hr.previousSibling; + if(isHr(pre)){ + domUtils.remove(pre); + }else{ + pre && fillNode(pre); + } + + if(!nextNode){ + var p = me.document.createElement('p'); + + hr.parentNode.appendChild(p); + domUtils.fillNode(me.document,p); + range.setStart(p,0).collapse(true); + }else{ + if(isHr(nextNode)){ + domUtils.remove(nextNode); + }else{ + fillNode(nextNode); + } + range.setEndAfter(hr).collapse(false); + } + + range.select(true); + + } + + } + }; +}; + +// plugins/wordimage.js +///import core +///commands 本地图片引导上传 +///commandsName WordImage +///commandsTitle 本地图片引导上传 +///commandsDialog dialogs\wordimage + +UE.plugin.register('wordimage',function(){ + var me = this, + images = []; + return { + commands : { + 'wordimage':{ + execCommand:function () { + var images = domUtils.getElementsByTagName(me.body, "img"); + var urlList = []; + for (var i = 0, ci; ci = images[i++];) { + var url = ci.getAttribute("word_img"); + url && urlList.push(url); + } + return urlList; + }, + queryCommandState:function () { + images = domUtils.getElementsByTagName(me.body, "img"); + for (var i = 0, ci; ci = images[i++];) { + if (ci.getAttribute("word_img")) { + return 1; + } + } + return -1; + }, + notNeedUndo:true + } + }, + inputRule : function (root) { + utils.each(root.getNodesByTagName('img'), function (img) { + var attrs = img.attrs, + flag = parseInt(attrs.width) < 128 || parseInt(attrs.height) < 43, + opt = me.options, + src = opt.UEDITOR_HOME_URL + 'themes/default/images/spacer.gif'; + if (attrs['src'] && /^(?:(file:\/+))/.test(attrs['src'])) { + img.setAttr({ + width:attrs.width, + height:attrs.height, + alt:attrs.alt, + word_img: attrs.src, + src:src, + 'style':'background:url(' + ( flag ? opt.themePath + opt.theme + '/images/word.gif' : opt.langPath + opt.lang + '/images/localimage.png') + ') no-repeat center center;border:1px solid #ddd' + }) + } + }) + } + } +}); + +// plugins/dragdrop.js +UE.plugins['dragdrop'] = function (){ + + var me = this; + me.ready(function(){ + domUtils.on(this.body,'dragend',function(){ + var rng = me.selection.getRange(); + var node = rng.getClosedNode()||me.selection.getStart(); + + if(node && node.tagName == 'IMG'){ + + var pre = node.previousSibling,next; + while(next = node.nextSibling){ + if(next.nodeType == 1 && next.tagName == 'SPAN' && !next.firstChild){ + domUtils.remove(next) + }else{ + break; + } + } + + + if((pre && pre.nodeType == 1 && !domUtils.isEmptyBlock(pre) || !pre) && (!next || next && !domUtils.isEmptyBlock(next))){ + if(pre && pre.tagName == 'P' && !domUtils.isEmptyBlock(pre)){ + pre.appendChild(node); + domUtils.moveChild(next,pre); + domUtils.remove(next); + }else if(next && next.tagName == 'P' && !domUtils.isEmptyBlock(next)){ + next.insertBefore(node,next.firstChild); + } + + if(pre && pre.tagName == 'P' && domUtils.isEmptyBlock(pre)){ + domUtils.remove(pre) + } + if(next && next.tagName == 'P' && domUtils.isEmptyBlock(next)){ + domUtils.remove(next) + } + rng.selectNode(node).select(); + me.fireEvent('saveScene'); + + } + + } + + }) + }); + me.addListener('keyup', function(type, evt) { + var keyCode = evt.keyCode || evt.which; + if (keyCode == 13) { + var rng = me.selection.getRange(),node; + if(node = domUtils.findParentByTagName(rng.startContainer,'p',true)){ + if(domUtils.getComputedStyle(node,'text-align') == 'center'){ + domUtils.removeStyle(node,'text-align') + } + } + } + }) +}; + + +// plugins/undo.js +/** + * undo redo + * @file + * @since 1.2.6.1 + */ + +/** + * 撤销上一次执行的命令 + * @command undo + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'undo' ); + * ``` + */ + +/** + * 重做上一次执行的命令 + * @command redo + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'redo' ); + * ``` + */ + +UE.plugins['undo'] = function () { + var saveSceneTimer; + var me = this, + maxUndoCount = me.options.maxUndoCount || 20, + maxInputCount = me.options.maxInputCount || 20, + fillchar = new RegExp(domUtils.fillChar + '|<\/hr>', 'gi');// ie会产生多余的 + var noNeedFillCharTags = { + ol:1,ul:1,table:1,tbody:1,tr:1,body:1 + }; + var orgState = me.options.autoClearEmptyNode; + function compareAddr(indexA, indexB) { + if (indexA.length != indexB.length) + return 0; + for (var i = 0, l = indexA.length; i < l; i++) { + if (indexA[i] != indexB[i]) + return 0 + } + return 1; + } + + function compareRangeAddress(rngAddrA, rngAddrB) { + if (rngAddrA.collapsed != rngAddrB.collapsed) { + return 0; + } + if (!compareAddr(rngAddrA.startAddress, rngAddrB.startAddress) || !compareAddr(rngAddrA.endAddress, rngAddrB.endAddress)) { + return 0; + } + return 1; + } + + function UndoManager() { + this.list = []; + this.index = 0; + this.hasUndo = false; + this.hasRedo = false; + this.undo = function () { + if (this.hasUndo) { + if (!this.list[this.index - 1] && this.list.length == 1) { + this.reset(); + return; + } + while (this.list[this.index].content == this.list[this.index - 1].content) { + this.index--; + if (this.index == 0) { + return this.restore(0); + } + } + this.restore(--this.index); + } + }; + this.redo = function () { + if (this.hasRedo) { + while (this.list[this.index].content == this.list[this.index + 1].content) { + this.index++; + if (this.index == this.list.length - 1) { + return this.restore(this.index); + } + } + this.restore(++this.index); + } + }; + + this.restore = function () { + var me = this.editor; + var scene = this.list[this.index]; + var root = UE.htmlparser(scene.content.replace(fillchar, '')); + me.options.autoClearEmptyNode = false; + me.filterInputRule(root); + me.options.autoClearEmptyNode = orgState; + //trace:873 + //去掉展位符 + me.document.body.innerHTML = root.toHtml(); + me.fireEvent('afterscencerestore'); + //处理undo后空格不展位的问题 + if (browser.ie) { + utils.each(domUtils.getElementsByTagName(me.document,'td th caption p'),function(node){ + if(domUtils.isEmptyNode(node)){ + domUtils.fillNode(me.document, node); + } + }) + } + + try{ + var rng = new dom.Range(me.document).moveToAddress(scene.address); + rng.select(noNeedFillCharTags[rng.startContainer.nodeName.toLowerCase()]); + }catch(e){} + + this.update(); + this.clearKey(); + //不能把自己reset了 + me.fireEvent('reset', true); + }; + + this.getScene = function () { + var me = this.editor; + var rng = me.selection.getRange(), + rngAddress = rng.createAddress(false,true); + me.fireEvent('beforegetscene'); + var root = UE.htmlparser(me.body.innerHTML); + me.options.autoClearEmptyNode = false; + me.filterOutputRule(root); + me.options.autoClearEmptyNode = orgState; + var cont = root.toHtml(); + //trace:3461 + //这个会引起回退时导致空格丢失的情况 +// browser.ie && (cont = cont.replace(/> <').replace(/\s*\s*/g, '>')); + me.fireEvent('aftergetscene'); + + return { + address:rngAddress, + content:cont + } + }; + this.save = function (notCompareRange,notSetCursor) { + clearTimeout(saveSceneTimer); + var currentScene = this.getScene(notSetCursor), + lastScene = this.list[this.index]; + + if(lastScene && lastScene.content != currentScene.content){ + me.trigger('contentchange') + } + //内容相同位置相同不存 + if (lastScene && lastScene.content == currentScene.content && + ( notCompareRange ? 1 : compareRangeAddress(lastScene.address, currentScene.address) ) + ) { + return; + } + this.list = this.list.slice(0, this.index + 1); + this.list.push(currentScene); + //如果大于最大数量了,就把最前的剔除 + if (this.list.length > maxUndoCount) { + this.list.shift(); + } + this.index = this.list.length - 1; + this.clearKey(); + //跟新undo/redo状态 + this.update(); + + }; + this.update = function () { + this.hasRedo = !!this.list[this.index + 1]; + this.hasUndo = !!this.list[this.index - 1]; + }; + this.reset = function () { + this.list = []; + this.index = 0; + this.hasUndo = false; + this.hasRedo = false; + this.clearKey(); + }; + this.clearKey = function () { + keycont = 0; + lastKeyCode = null; + }; + } + + me.undoManger = new UndoManager(); + me.undoManger.editor = me; + function saveScene() { + this.undoManger.save(); + } + + me.addListener('saveScene', function () { + var args = Array.prototype.splice.call(arguments,1); + this.undoManger.save.apply(this.undoManger,args); + }); + +// me.addListener('beforeexeccommand', saveScene); +// me.addListener('afterexeccommand', saveScene); + + me.addListener('reset', function (type, exclude) { + if (!exclude) { + this.undoManger.reset(); + } + }); + me.commands['redo'] = me.commands['undo'] = { + execCommand:function (cmdName) { + this.undoManger[cmdName](); + }, + queryCommandState:function (cmdName) { + return this.undoManger['has' + (cmdName.toLowerCase() == 'undo' ? 'Undo' : 'Redo')] ? 0 : -1; + }, + notNeedUndo:1 + }; + + var keys = { + // /*Backspace*/ 8:1, /*Delete*/ 46:1, + /*Shift*/ 16:1, /*Ctrl*/ 17:1, /*Alt*/ 18:1, + 37:1, 38:1, 39:1, 40:1 + + }, + keycont = 0, + lastKeyCode; + //输入法状态下不计算字符数 + var inputType = false; + me.addListener('ready', function () { + domUtils.on(this.body, 'compositionstart', function () { + inputType = true; + }); + domUtils.on(this.body, 'compositionend', function () { + inputType = false; + }) + }); + //快捷键 + me.addshortcutkey({ + "Undo":"ctrl+90", //undo + "Redo":"ctrl+89" //redo + + }); + var isCollapsed = true; + me.addListener('keydown', function (type, evt) { + + var me = this; + var keyCode = evt.keyCode || evt.which; + if (!keys[keyCode] && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey) { + if (inputType) + return; + + if(!me.selection.getRange().collapsed){ + me.undoManger.save(false,true); + isCollapsed = false; + return; + } + if (me.undoManger.list.length == 0) { + me.undoManger.save(true); + } + clearTimeout(saveSceneTimer); + function save(cont){ + cont.undoManger.save(false,true); + cont.fireEvent('selectionchange'); + } + saveSceneTimer = setTimeout(function(){ + if(inputType){ + var interalTimer = setInterval(function(){ + if(!inputType){ + save(me); + clearInterval(interalTimer) + } + },300) + return; + } + save(me); + },200); + + lastKeyCode = keyCode; + keycont++; + if (keycont >= maxInputCount ) { + save(me) + } + } + }); + me.addListener('keyup', function (type, evt) { + var keyCode = evt.keyCode || evt.which; + if (!keys[keyCode] && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey) { + if (inputType) + return; + if(!isCollapsed){ + this.undoManger.save(false,true); + isCollapsed = true; + } + } + }); + //扩展实例,添加关闭和开启命令undo + me.stopCmdUndo = function(){ + me.__hasEnterExecCommand = true; + }; + me.startCmdUndo = function(){ + me.__hasEnterExecCommand = false; + } +}; + + +// plugins/copy.js +UE.plugin.register('copy', function () { + + var me = this; + + function initZeroClipboard() { + + ZeroClipboard.config({ + debug: false, + swfPath: me.options.UEDITOR_HOME_URL + 'third-party/zeroclipboard/ZeroClipboard.swf' + }); + + var client = me.zeroclipboard = new ZeroClipboard(); + + // 复制内容 + client.on('copy', function (e) { + var client = e.client, + rng = me.selection.getRange(), + div = document.createElement('div'); + + div.appendChild(rng.cloneContents()); + client.setText(div.innerText || div.textContent); + client.setHtml(div.innerHTML); + rng.select(); + }); + // hover事件传递到target + client.on('mouseover mouseout', function (e) { + var target = e.target; + if (e.type == 'mouseover') { + domUtils.addClass(target, 'edui-state-hover'); + } else if (e.type == 'mouseout') { + domUtils.removeClasses(target, 'edui-state-hover'); + } + }); + // flash加载不成功 + client.on('wrongflash noflash', function () { + ZeroClipboard.destroy(); + }); + } + + return { + bindEvents: { + 'ready': function () { + if (!browser.ie) { + if (window.ZeroClipboard) { + initZeroClipboard(); + } else { + utils.loadFile(document, { + src: me.options.UEDITOR_HOME_URL + "third-party/zeroclipboard/ZeroClipboard.js", + tag: "script", + type: "text/javascript", + defer: "defer" + }, function () { + initZeroClipboard(); + }); + } + } + } + }, + commands: { + 'copy': { + execCommand: function (cmd) { + if (!me.document.execCommand('copy')) { + alert(me.getLang('copymsg')); + } + } + } + } + } +}); + + +// plugins/paste.js +///import core +///import plugins/inserthtml.js +///import plugins/undo.js +///import plugins/serialize.js +///commands 粘贴 +///commandsName PastePlain +///commandsTitle 纯文本粘贴模式 +/** + * @description 粘贴 + * @author zhanyi + */ +UE.plugins['paste'] = function () { + function getClipboardData(callback) { + var doc = this.document; + if (doc.getElementById('baidu_pastebin')) { + return; + } + var range = this.selection.getRange(), + bk = range.createBookmark(), + //创建剪贴的容器div + pastebin = doc.createElement('div'); + pastebin.id = 'baidu_pastebin'; + // Safari 要求div必须有内容,才能粘贴内容进来 + browser.webkit && pastebin.appendChild(doc.createTextNode(domUtils.fillChar + domUtils.fillChar)); + doc.body.appendChild(pastebin); + //trace:717 隐藏的span不能得到top + //bk.start.innerHTML = ' '; + bk.start.style.display = ''; + pastebin.style.cssText = "position:absolute;width:1px;height:1px;overflow:hidden;left:-1000px;white-space:nowrap;top:" + + //要在现在光标平行的位置加入,否则会出现跳动的问题 + domUtils.getXY(bk.start).y + 'px'; + + range.selectNodeContents(pastebin).select(true); + + setTimeout(function () { + if (browser.webkit) { + for (var i = 0, pastebins = doc.querySelectorAll('#baidu_pastebin'), pi; pi = pastebins[i++];) { + if (domUtils.isEmptyNode(pi)) { + domUtils.remove(pi); + } else { + pastebin = pi; + break; + } + } + } + try { + pastebin.parentNode.removeChild(pastebin); + } catch (e) { + } + range.moveToBookmark(bk).select(true); + callback(pastebin); + }, 0); + } + + var me = this; + + me.setOpt({ + retainOnlyLabelPasted : false + }); + + var txtContent, htmlContent, address; + + function getPureHtml(html){ + return html.replace(/<(\/?)([\w\-]+)([^>]*)>/gi, function (a, b, tagName, attrs) { + tagName = tagName.toLowerCase(); + if ({img: 1}[tagName]) { + return a; + } + attrs = attrs.replace(/([\w\-]*?)\s*=\s*(("([^"]*)")|('([^']*)')|([^\s>]+))/gi, function (str, atr, val) { + if ({ + 'src': 1, + 'href': 1, + 'name': 1 + }[atr.toLowerCase()]) { + return atr + '=' + val + ' ' + } + return '' + }); + if ({ + 'span': 1, + 'div': 1 + }[tagName]) { + return '' + } else { + + return '<' + b + tagName + ' ' + utils.trim(attrs) + '>' + } + + }); + } + function filter(div) { + var html; + if (div.firstChild) { + //去掉cut中添加的边界值 + var nodes = domUtils.getElementsByTagName(div, 'span'); + for (var i = 0, ni; ni = nodes[i++];) { + if (ni.id == '_baidu_cut_start' || ni.id == '_baidu_cut_end') { + domUtils.remove(ni); + } + } + + if (browser.webkit) { + + var brs = div.querySelectorAll('div br'); + for (var i = 0, bi; bi = brs[i++];) { + var pN = bi.parentNode; + if (pN.tagName == 'DIV' && pN.childNodes.length == 1) { + pN.innerHTML = '


      '; + domUtils.remove(pN); + } + } + var divs = div.querySelectorAll('#baidu_pastebin'); + for (var i = 0, di; di = divs[i++];) { + var tmpP = me.document.createElement('p'); + di.parentNode.insertBefore(tmpP, di); + while (di.firstChild) { + tmpP.appendChild(di.firstChild); + } + domUtils.remove(di); + } + + var metas = div.querySelectorAll('meta'); + for (var i = 0, ci; ci = metas[i++];) { + domUtils.remove(ci); + } + + var brs = div.querySelectorAll('br'); + for (i = 0; ci = brs[i++];) { + if (/^apple-/i.test(ci.className)) { + domUtils.remove(ci); + } + } + } + if (browser.gecko) { + var dirtyNodes = div.querySelectorAll('[_moz_dirty]'); + for (i = 0; ci = dirtyNodes[i++];) { + ci.removeAttribute('_moz_dirty'); + } + } + if (!browser.ie) { + var spans = div.querySelectorAll('span.Apple-style-span'); + for (var i = 0, ci; ci = spans[i++];) { + domUtils.remove(ci, true); + } + } + + //ie下使用innerHTML会产生多余的\r\n字符,也会产生 这里过滤掉 + html = div.innerHTML;//.replace(/>(?:(\s| )*?)<'); + + //过滤word粘贴过来的冗余属性 + html = UE.filterWord(html); + //取消了忽略空白的第二个参数,粘贴过来的有些是有空白的,会被套上相关的标签 + var root = UE.htmlparser(html); + //如果给了过滤规则就先进行过滤 + if (me.options.filterRules) { + UE.filterNode(root, me.options.filterRules); + } + //执行默认的处理 + me.filterInputRule(root); + //针对chrome的处理 + if (browser.webkit) { + var br = root.lastChild(); + if (br && br.type == 'element' && br.tagName == 'br') { + root.removeChild(br) + } + utils.each(me.body.querySelectorAll('div'), function (node) { + if (domUtils.isEmptyBlock(node)) { + domUtils.remove(node,true) + } + }) + } + html = {'html': root.toHtml()}; + me.fireEvent('beforepaste', html, root); + //抢了默认的粘贴,那后边的内容就不执行了,比如表格粘贴 + if(!html.html){ + return; + } + root = UE.htmlparser(html.html,true); + //如果开启了纯文本模式 + if (me.queryCommandState('pasteplain') === 1) { + me.execCommand('insertHtml', UE.filterNode(root, me.options.filterTxtRules).toHtml(), true); + } else { + //文本模式 + UE.filterNode(root, me.options.filterTxtRules); + txtContent = root.toHtml(); + //完全模式 + htmlContent = html.html; + + address = me.selection.getRange().createAddress(true); + me.execCommand('insertHtml', me.getOpt('retainOnlyLabelPasted') === true ? getPureHtml(htmlContent) : htmlContent, true); + } + me.fireEvent("afterpaste", html); + } + } + + me.addListener('pasteTransfer', function (cmd, plainType) { + + if (address && txtContent && htmlContent && txtContent != htmlContent) { + var range = me.selection.getRange(); + range.moveToAddress(address, true); + + if (!range.collapsed) { + + while (!domUtils.isBody(range.startContainer) + ) { + var start = range.startContainer; + if(start.nodeType == 1){ + start = start.childNodes[range.startOffset]; + if(!start){ + range.setStartBefore(range.startContainer); + continue; + } + var pre = start.previousSibling; + + if(pre && pre.nodeType == 3 && new RegExp('^[\n\r\t '+domUtils.fillChar+']*$').test(pre.nodeValue)){ + range.setStartBefore(pre) + } + } + if(range.startOffset == 0){ + range.setStartBefore(range.startContainer); + }else{ + break; + } + + } + while (!domUtils.isBody(range.endContainer) + ) { + var end = range.endContainer; + if(end.nodeType == 1){ + end = end.childNodes[range.endOffset]; + if(!end){ + range.setEndAfter(range.endContainer); + continue; + } + var next = end.nextSibling; + if(next && next.nodeType == 3 && new RegExp('^[\n\r\t'+domUtils.fillChar+']*$').test(next.nodeValue)){ + range.setEndAfter(next) + } + } + if(range.endOffset == range.endContainer[range.endContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length){ + range.setEndAfter(range.endContainer); + }else{ + break; + } + + } + + } + + range.deleteContents(); + range.select(true); + me.__hasEnterExecCommand = true; + var html = htmlContent; + if (plainType === 2 ) { + html = getPureHtml(html); + } else if (plainType) { + html = txtContent; + } + me.execCommand('inserthtml', html, true); + me.__hasEnterExecCommand = false; + var rng = me.selection.getRange(); + while (!domUtils.isBody(rng.startContainer) && !rng.startOffset && + rng.startContainer[rng.startContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length + ) { + rng.setStartBefore(rng.startContainer); + } + var tmpAddress = rng.createAddress(true); + address.endAddress = tmpAddress.startAddress; + } + }); + + me.addListener('ready', function () { + domUtils.on(me.body, 'cut', function () { + var range = me.selection.getRange(); + if (!range.collapsed && me.undoManger) { + me.undoManger.save(); + } + }); + + //ie下beforepaste在点击右键时也会触发,所以用监控键盘才处理 + domUtils.on(me.body, browser.ie || browser.opera ? 'keydown' : 'paste', function (e) { + if ((browser.ie || browser.opera) && ((!e.ctrlKey && !e.metaKey) || e.keyCode != '86')) { + return; + } + getClipboardData.call(me, function (div) { + filter(div); + }); + }); + + }); + + me.commands['paste'] = { + execCommand: function (cmd) { + if (browser.ie) { + getClipboardData.call(me, function (div) { + filter(div); + }); + me.document.execCommand('paste'); + } else { + alert(me.getLang('pastemsg')); + } + } + } +}; + + + +// plugins/puretxtpaste.js +/** + * 纯文本粘贴插件 + * @file + * @since 1.2.6.1 + */ + +UE.plugins['pasteplain'] = function(){ + var me = this; + me.setOpt({ + 'pasteplain':false, + 'filterTxtRules' : function(){ + function transP(node){ + node.tagName = 'p'; + node.setStyle(); + } + function removeNode(node){ + node.parentNode.removeChild(node,true) + } + return { + //直接删除及其字节点内容 + '-' : 'script style object iframe embed input select', + 'p': {$:{}}, + 'br':{$:{}}, + div: function (node) { + var tmpNode, p = UE.uNode.createElement('p'); + while (tmpNode = node.firstChild()) { + if (tmpNode.type == 'text' || !UE.dom.dtd.$block[tmpNode.tagName]) { + p.appendChild(tmpNode); + } else { + if (p.firstChild()) { + node.parentNode.insertBefore(p, node); + p = UE.uNode.createElement('p'); + } else { + node.parentNode.insertBefore(tmpNode, node); + } + } + } + if (p.firstChild()) { + node.parentNode.insertBefore(p, node); + } + node.parentNode.removeChild(node); + }, + ol: removeNode, + ul: removeNode, + dl:removeNode, + dt:removeNode, + dd:removeNode, + 'li':removeNode, + 'caption':transP, + 'th':transP, + 'tr':transP, + 'h1':transP,'h2':transP,'h3':transP,'h4':transP,'h5':transP,'h6':transP, + 'td':function(node){ + //没有内容的td直接删掉 + var txt = !!node.innerText(); + if(txt){ + node.parentNode.insertAfter(UE.uNode.createText('    '),node); + } + node.parentNode.removeChild(node,node.innerText()) + } + } + }() + }); + //暂时这里支持一下老版本的属性 + var pasteplain = me.options.pasteplain; + + /** + * 启用或取消纯文本粘贴模式 + * @command pasteplain + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.queryCommandState( 'pasteplain' ); + * ``` + */ + + /** + * 查询当前是否处于纯文本粘贴模式 + * @command pasteplain + * @method queryCommandState + * @param { String } cmd 命令字符串 + * @return { int } 如果处于纯文本模式,返回1,否则,返回0 + * @example + * ```javascript + * editor.queryCommandState( 'pasteplain' ); + * ``` + */ + me.commands['pasteplain'] = { + queryCommandState: function (){ + return pasteplain ? 1 : 0; + }, + execCommand: function (){ + pasteplain = !pasteplain|0; + }, + notNeedUndo : 1 + }; +}; + +// plugins/list.js +/** + * 有序列表,无序列表插件 + * @file + * @since 1.2.6.1 + */ + +UE.plugins['list'] = function () { + var me = this, + notExchange = { + 'TD':1, + 'PRE':1, + 'BLOCKQUOTE':1 + }; + var customStyle = { + 'cn' : 'cn-1-', + 'cn1' : 'cn-2-', + 'cn2' : 'cn-3-', + 'num': 'num-1-', + 'num1' : 'num-2-', + 'num2' : 'num-3-', + 'dash' : 'dash', + 'dot':'dot' + }; + + me.setOpt( { + 'autoTransWordToList':false, + 'insertorderedlist':{ + 'num':'', + 'num1':'', + 'num2':'', + 'cn':'', + 'cn1':'', + 'cn2':'', + 'decimal':'', + 'lower-alpha':'', + 'lower-roman':'', + 'upper-alpha':'', + 'upper-roman':'' + }, + 'insertunorderedlist':{ + 'circle':'', + 'disc':'', + 'square':'', + 'dash' : '', + 'dot':'' + }, + listDefaultPaddingLeft : '30', + listiconpath : 'http://bs.baidu.com/listicon/', + maxListLevel : -1,//-1不限制 + disablePInList:false + } ); + function listToArray(list){ + var arr = []; + for(var p in list){ + arr.push(p) + } + return arr; + } + var listStyle = { + 'OL':listToArray(me.options.insertorderedlist), + 'UL':listToArray(me.options.insertunorderedlist) + }; + var liiconpath = me.options.listiconpath; + + //根据用户配置,调整customStyle + for(var s in customStyle){ + if(!me.options.insertorderedlist.hasOwnProperty(s) && !me.options.insertunorderedlist.hasOwnProperty(s)){ + delete customStyle[s]; + } + } + + me.ready(function () { + var customCss = []; + for(var p in customStyle){ + if(p == 'dash' || p == 'dot'){ + customCss.push('li.list-' + customStyle[p] + '{background-image:url(' + liiconpath +customStyle[p]+'.gif)}'); + customCss.push('ul.custom_'+p+'{list-style:none;}ul.custom_'+p+' li{background-position:0 3px;background-repeat:no-repeat}'); + }else{ + for(var i= 0;i<99;i++){ + customCss.push('li.list-' + customStyle[p] + i + '{background-image:url(' + liiconpath + 'list-'+customStyle[p] + i + '.gif)}') + } + customCss.push('ol.custom_'+p+'{list-style:none;}ol.custom_'+p+' li{background-position:0 3px;background-repeat:no-repeat}'); + } + switch(p){ + case 'cn': + customCss.push('li.list-'+p+'-paddingleft-1{padding-left:25px}'); + customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}'); + customCss.push('li.list-'+p+'-paddingleft-3{padding-left:55px}'); + break; + case 'cn1': + customCss.push('li.list-'+p+'-paddingleft-1{padding-left:30px}'); + customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}'); + customCss.push('li.list-'+p+'-paddingleft-3{padding-left:55px}'); + break; + case 'cn2': + customCss.push('li.list-'+p+'-paddingleft-1{padding-left:40px}'); + customCss.push('li.list-'+p+'-paddingleft-2{padding-left:55px}'); + customCss.push('li.list-'+p+'-paddingleft-3{padding-left:68px}'); + break; + case 'num': + case 'num1': + customCss.push('li.list-'+p+'-paddingleft-1{padding-left:25px}'); + break; + case 'num2': + customCss.push('li.list-'+p+'-paddingleft-1{padding-left:35px}'); + customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}'); + break; + case 'dash': + customCss.push('li.list-'+p+'-paddingleft{padding-left:35px}'); + break; + case 'dot': + customCss.push('li.list-'+p+'-paddingleft{padding-left:20px}'); + } + } + customCss.push('.list-paddingleft-1{padding-left:0}'); + customCss.push('.list-paddingleft-2{padding-left:'+me.options.listDefaultPaddingLeft+'px}'); + customCss.push('.list-paddingleft-3{padding-left:'+me.options.listDefaultPaddingLeft*2+'px}'); + //如果不给宽度会在自定应样式里出现滚动条 + utils.cssRule('list', 'ol,ul{margin:0;pading:0;'+(browser.ie ? '' : 'width:95%')+'}li{clear:both;}'+customCss.join('\n'), me.document); + }); + //单独处理剪切的问题 + me.ready(function(){ + domUtils.on(me.body,'cut',function(){ + setTimeout(function(){ + var rng = me.selection.getRange(),li; + //trace:3416 + if(!rng.collapsed){ + if(li = domUtils.findParentByTagName(rng.startContainer,'li',true)){ + if(!li.nextSibling && domUtils.isEmptyBlock(li)){ + var pn = li.parentNode,node; + if(node = pn.previousSibling){ + domUtils.remove(pn); + rng.setStartAtLast(node).collapse(true); + rng.select(true); + }else if(node = pn.nextSibling){ + domUtils.remove(pn); + rng.setStartAtFirst(node).collapse(true); + rng.select(true); + }else{ + var tmpNode = me.document.createElement('p'); + domUtils.fillNode(me.document,tmpNode); + pn.parentNode.insertBefore(tmpNode,pn); + domUtils.remove(pn); + rng.setStart(tmpNode,0).collapse(true); + rng.select(true); + } + } + } + } + + }) + }) + }); + + function getStyle(node){ + var cls = node.className; + if(domUtils.hasClass(node,/custom_/)){ + return cls.match(/custom_(\w+)/)[1] + } + return domUtils.getStyle(node, 'list-style-type') + + } + + me.addListener('beforepaste',function(type,html){ + var me = this, + rng = me.selection.getRange(),li; + var root = UE.htmlparser(html.html,true); + if(li = domUtils.findParentByTagName(rng.startContainer,'li',true)){ + var list = li.parentNode,tagName = list.tagName == 'OL' ? 'ul':'ol'; + utils.each(root.getNodesByTagName(tagName),function(n){ + n.tagName = list.tagName; + n.setAttr(); + if(n.parentNode === root){ + type = getStyle(list) || (list.tagName == 'OL' ? 'decimal' : 'disc') + }else{ + var className = n.parentNode.getAttr('class'); + if(className && /custom_/.test(className)){ + type = className.match(/custom_(\w+)/)[1] + }else{ + type = n.parentNode.getStyle('list-style-type'); + } + if(!type){ + type = list.tagName == 'OL' ? 'decimal' : 'disc'; + } + } + var index = utils.indexOf(listStyle[list.tagName], type); + if(n.parentNode !== root) + index = index + 1 == listStyle[list.tagName].length ? 0 : index + 1; + var currentStyle = listStyle[list.tagName][index]; + if(customStyle[currentStyle]){ + n.setAttr('class', 'custom_' + currentStyle) + + }else{ + n.setStyle('list-style-type',currentStyle) + } + }) + + } + + html.html = root.toHtml(); + }); + //导出时,去掉p标签 + me.getOpt('disablePInList') === true && me.addOutputRule(function(root){ + utils.each(root.getNodesByTagName('li'),function(li){ + var newChildrens = [],index=0; + utils.each(li.children,function(n){ + if(n.tagName == 'p'){ + var tmpNode; + while(tmpNode = n.children.pop()) { + newChildrens.splice(index,0,tmpNode); + tmpNode.parentNode = li; + lastNode = tmpNode; + } + tmpNode = newChildrens[newChildrens.length-1]; + if(!tmpNode || tmpNode.type != 'element' || tmpNode.tagName != 'br'){ + var br = UE.uNode.createElement('br'); + br.parentNode = li; + newChildrens.push(br); + } + + index = newChildrens.length; + } + }); + if(newChildrens.length){ + li.children = newChildrens; + } + }); + }); + //进入编辑器的li要套p标签 + me.addInputRule(function(root){ + utils.each(root.getNodesByTagName('li'),function(li){ + var tmpP = UE.uNode.createElement('p'); + for(var i= 0,ci;ci=li.children[i];){ + if(ci.type == 'text' || dtd.p[ci.tagName]){ + tmpP.appendChild(ci); + }else{ + if(tmpP.firstChild()){ + li.insertBefore(tmpP,ci); + tmpP = UE.uNode.createElement('p'); + i = i + 2; + }else{ + i++; + } + + } + } + if(tmpP.firstChild() && !tmpP.parentNode || !li.firstChild()){ + li.appendChild(tmpP); + } + //trace:3357 + //p不能为空 + if (!tmpP.firstChild()) { + tmpP.innerHTML(browser.ie ? ' ' : '
      ') + } + //去掉末尾的空白 + var p = li.firstChild(); + var lastChild = p.lastChild(); + if(lastChild && lastChild.type == 'text' && /^\s*$/.test(lastChild.data)){ + p.removeChild(lastChild) + } + }); + if(me.options.autoTransWordToList){ + var orderlisttype = { + 'num1':/^\d+\)/, + 'decimal':/^\d+\./, + 'lower-alpha':/^[a-z]+\)/, + 'upper-alpha':/^[A-Z]+\./, + 'cn':/^[\u4E00\u4E8C\u4E09\u56DB\u516d\u4e94\u4e03\u516b\u4e5d]+[\u3001]/, + 'cn2':/^\([\u4E00\u4E8C\u4E09\u56DB\u516d\u4e94\u4e03\u516b\u4e5d]+\)/ + }, + unorderlisttype = { + 'square':'n' + }; + function checkListType(content,container){ + var span = container.firstChild(); + if(span && span.type == 'element' && span.tagName == 'span' && /Wingdings|Symbol/.test(span.getStyle('font-family'))){ + for(var p in unorderlisttype){ + if(unorderlisttype[p] == span.data){ + return p + } + } + return 'disc' + } + for(var p in orderlisttype){ + if(orderlisttype[p].test(content)){ + return p; + } + } + + } + utils.each(root.getNodesByTagName('p'),function(node){ + if(node.getAttr('class') != 'MsoListParagraph'){ + return + } + + //word粘贴过来的会带有margin要去掉,但这样也可能会误命中一些央视 + node.setStyle('margin',''); + node.setStyle('margin-left',''); + node.setAttr('class',''); + + function appendLi(list,p,type){ + if(list.tagName == 'ol'){ + if(browser.ie){ + var first = p.firstChild(); + if(first.type =='element' && first.tagName == 'span' && orderlisttype[type].test(first.innerText())){ + p.removeChild(first); + } + }else{ + p.innerHTML(p.innerHTML().replace(orderlisttype[type],'')); + } + }else{ + p.removeChild(p.firstChild()) + } + + var li = UE.uNode.createElement('li'); + li.appendChild(p); + list.appendChild(li); + } + var tmp = node,type,cacheNode = node; + + if(node.parentNode.tagName != 'li' && (type = checkListType(node.innerText(),node))){ + + var list = UE.uNode.createElement(me.options.insertorderedlist.hasOwnProperty(type) ? 'ol' : 'ul'); + if(customStyle[type]){ + list.setAttr('class','custom_'+type) + }else{ + list.setStyle('list-style-type',type) + } + while(node && node.parentNode.tagName != 'li' && checkListType(node.innerText(),node)){ + tmp = node.nextSibling(); + if(!tmp){ + node.parentNode.insertBefore(list,node) + } + appendLi(list,node,type); + node = tmp; + } + if(!list.parentNode && node && node.parentNode){ + node.parentNode.insertBefore(list,node) + } + } + var span = cacheNode.firstChild(); + if(span && span.type == 'element' && span.tagName == 'span' && /^\s*( )+\s*$/.test(span.innerText())){ + span.parentNode.removeChild(span) + } + }) + } + + }); + + //调整索引标签 + me.addListener('contentchange',function(){ + adjustListStyle(me.document) + }); + + function adjustListStyle(doc,ignore){ + utils.each(domUtils.getElementsByTagName(doc,'ol ul'),function(node){ + + if(!domUtils.inDoc(node,doc)) + return; + + var parent = node.parentNode; + if(parent.tagName == node.tagName){ + var nodeStyleType = getStyle(node) || (node.tagName == 'OL' ? 'decimal' : 'disc'), + parentStyleType = getStyle(parent) || (parent.tagName == 'OL' ? 'decimal' : 'disc'); + if(nodeStyleType == parentStyleType){ + var styleIndex = utils.indexOf(listStyle[node.tagName], nodeStyleType); + styleIndex = styleIndex + 1 == listStyle[node.tagName].length ? 0 : styleIndex + 1; + setListStyle(node,listStyle[node.tagName][styleIndex]) + } + + } + var index = 0,type = 2; + if( domUtils.hasClass(node,/custom_/)){ + if(!(/[ou]l/i.test(parent.tagName) && domUtils.hasClass(parent,/custom_/))){ + type = 1; + } + }else{ + if(/[ou]l/i.test(parent.tagName) && domUtils.hasClass(parent,/custom_/)){ + type = 3; + } + } + + var style = domUtils.getStyle(node, 'list-style-type'); + style && (node.style.cssText = 'list-style-type:' + style); + node.className = utils.trim(node.className.replace(/list-paddingleft-\w+/,'')) + ' list-paddingleft-' + type; + utils.each(domUtils.getElementsByTagName(node,'li'),function(li){ + li.style.cssText && (li.style.cssText = ''); + if(!li.firstChild){ + domUtils.remove(li); + return; + } + if(li.parentNode !== node){ + return; + } + index++; + if(domUtils.hasClass(node,/custom_/) ){ + var paddingLeft = 1,currentStyle = getStyle(node); + if(node.tagName == 'OL'){ + if(currentStyle){ + switch(currentStyle){ + case 'cn' : + case 'cn1': + case 'cn2': + if(index > 10 && (index % 10 == 0 || index > 10 && index < 20)){ + paddingLeft = 2 + }else if(index > 20){ + paddingLeft = 3 + } + break; + case 'num2' : + if(index > 9){ + paddingLeft = 2 + } + } + } + li.className = 'list-'+customStyle[currentStyle]+ index + ' ' + 'list-'+currentStyle+'-paddingleft-' + paddingLeft; + }else{ + li.className = 'list-'+customStyle[currentStyle] + ' ' + 'list-'+currentStyle+'-paddingleft'; + } + }else{ + li.className = li.className.replace(/list-[\w\-]+/gi,''); + } + var className = li.getAttribute('class'); + if(className !== null && !className.replace(/\s/g,'')){ + domUtils.removeAttributes(li,'class') + } + }); + !ignore && adjustList(node,node.tagName.toLowerCase(),getStyle(node)||domUtils.getStyle(node, 'list-style-type'),true); + }) + } + function adjustList(list, tag, style,ignoreEmpty) { + var nextList = list.nextSibling; + if (nextList && nextList.nodeType == 1 && nextList.tagName.toLowerCase() == tag && (getStyle(nextList) || domUtils.getStyle(nextList, 'list-style-type') || (tag == 'ol' ? 'decimal' : 'disc')) == style) { + domUtils.moveChild(nextList, list); + if (nextList.childNodes.length == 0) { + domUtils.remove(nextList); + } + } + if(nextList && domUtils.isFillChar(nextList)){ + domUtils.remove(nextList); + } + var preList = list.previousSibling; + if (preList && preList.nodeType == 1 && preList.tagName.toLowerCase() == tag && (getStyle(preList) || domUtils.getStyle(preList, 'list-style-type') || (tag == 'ol' ? 'decimal' : 'disc')) == style) { + domUtils.moveChild(list, preList); + } + if(preList && domUtils.isFillChar(preList)){ + domUtils.remove(preList); + } + !ignoreEmpty && domUtils.isEmptyBlock(list) && domUtils.remove(list); + if(getStyle(list)){ + adjustListStyle(list.ownerDocument,true) + } + } + + function setListStyle(list,style){ + if(customStyle[style]){ + list.className = 'custom_' + style; + } + try{ + domUtils.setStyle(list, 'list-style-type', style); + }catch(e){} + } + function clearEmptySibling(node) { + var tmpNode = node.previousSibling; + if (tmpNode && domUtils.isEmptyBlock(tmpNode)) { + domUtils.remove(tmpNode); + } + tmpNode = node.nextSibling; + if (tmpNode && domUtils.isEmptyBlock(tmpNode)) { + domUtils.remove(tmpNode); + } + } + + me.addListener('keydown', function (type, evt) { + function preventAndSave() { + evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false); + me.fireEvent('contentchange'); + me.undoManger && me.undoManger.save(); + } + function findList(node,filterFn){ + while(node && !domUtils.isBody(node)){ + if(filterFn(node)){ + return null + } + if(node.nodeType == 1 && /[ou]l/i.test(node.tagName)){ + return node; + } + node = node.parentNode; + } + return null; + } + var keyCode = evt.keyCode || evt.which; + if (keyCode == 13 && !evt.shiftKey) {//回车 + var rng = me.selection.getRange(), + parent = domUtils.findParent(rng.startContainer,function(node){return domUtils.isBlockElm(node)},true), + li = domUtils.findParentByTagName(rng.startContainer,'li',true); + if(parent && parent.tagName != 'PRE' && !li){ + var html = parent.innerHTML.replace(new RegExp(domUtils.fillChar, 'g'),''); + if(/^\s*1\s*\.[^\d]/.test(html)){ + parent.innerHTML = html.replace(/^\s*1\s*\./,''); + rng.setStartAtLast(parent).collapse(true).select(); + me.__hasEnterExecCommand = true; + me.execCommand('insertorderedlist'); + me.__hasEnterExecCommand = false; + } + } + var range = me.selection.getRange(), + start = findList(range.startContainer,function (node) { + return node.tagName == 'TABLE'; + }), + end = range.collapsed ? start : findList(range.endContainer,function (node) { + return node.tagName == 'TABLE'; + }); + + if (start && end && start === end) { + + if (!range.collapsed) { + start = domUtils.findParentByTagName(range.startContainer, 'li', true); + end = domUtils.findParentByTagName(range.endContainer, 'li', true); + if (start && end && start === end) { + range.deleteContents(); + li = domUtils.findParentByTagName(range.startContainer, 'li', true); + if (li && domUtils.isEmptyBlock(li)) { + + pre = li.previousSibling; + next = li.nextSibling; + p = me.document.createElement('p'); + + domUtils.fillNode(me.document, p); + parentList = li.parentNode; + if (pre && next) { + range.setStart(next, 0).collapse(true).select(true); + domUtils.remove(li); + + } else { + if (!pre && !next || !pre) { + + parentList.parentNode.insertBefore(p, parentList); + + + } else { + li.parentNode.parentNode.insertBefore(p, parentList.nextSibling); + } + domUtils.remove(li); + if (!parentList.firstChild) { + domUtils.remove(parentList); + } + range.setStart(p, 0).setCursor(); + + + } + preventAndSave(); + return; + + } + } else { + var tmpRange = range.cloneRange(), + bk = tmpRange.collapse(false).createBookmark(); + + range.deleteContents(); + tmpRange.moveToBookmark(bk); + var li = domUtils.findParentByTagName(tmpRange.startContainer, 'li', true); + + clearEmptySibling(li); + tmpRange.select(); + preventAndSave(); + return; + } + } + + + li = domUtils.findParentByTagName(range.startContainer, 'li', true); + + if (li) { + if (domUtils.isEmptyBlock(li)) { + bk = range.createBookmark(); + var parentList = li.parentNode; + if (li !== parentList.lastChild) { + domUtils.breakParent(li, parentList); + clearEmptySibling(li); + } else { + + parentList.parentNode.insertBefore(li, parentList.nextSibling); + if (domUtils.isEmptyNode(parentList)) { + domUtils.remove(parentList); + } + } + //嵌套不处理 + if (!dtd.$list[li.parentNode.tagName]) { + + if (!domUtils.isBlockElm(li.firstChild)) { + p = me.document.createElement('p'); + li.parentNode.insertBefore(p, li); + while (li.firstChild) { + p.appendChild(li.firstChild); + } + domUtils.remove(li); + } else { + domUtils.remove(li, true); + } + } + range.moveToBookmark(bk).select(); + + + } else { + var first = li.firstChild; + if (!first || !domUtils.isBlockElm(first)) { + var p = me.document.createElement('p'); + + !li.firstChild && domUtils.fillNode(me.document, p); + while (li.firstChild) { + + p.appendChild(li.firstChild); + } + li.appendChild(p); + first = p; + } + + var span = me.document.createElement('span'); + + range.insertNode(span); + domUtils.breakParent(span, li); + + var nextLi = span.nextSibling; + first = nextLi.firstChild; + + if (!first) { + p = me.document.createElement('p'); + + domUtils.fillNode(me.document, p); + nextLi.appendChild(p); + first = p; + } + if (domUtils.isEmptyNode(first)) { + first.innerHTML = ''; + domUtils.fillNode(me.document, first); + } + + range.setStart(first, 0).collapse(true).shrinkBoundary().select(); + domUtils.remove(span); + var pre = nextLi.previousSibling; + if (pre && domUtils.isEmptyBlock(pre)) { + pre.innerHTML = '

      '; + domUtils.fillNode(me.document, pre.firstChild); + } + + } +// } + preventAndSave(); + } + + + } + + + } + if (keyCode == 8) { + //修中ie中li下的问题 + range = me.selection.getRange(); + if (range.collapsed && domUtils.isStartInblock(range)) { + tmpRange = range.cloneRange().trimBoundary(); + li = domUtils.findParentByTagName(range.startContainer, 'li', true); + //要在li的最左边,才能处理 + if (li && domUtils.isStartInblock(tmpRange)) { + start = domUtils.findParentByTagName(range.startContainer, 'p', true); + if (start && start !== li.firstChild) { + var parentList = domUtils.findParentByTagName(start,['ol','ul']); + domUtils.breakParent(start,parentList); + clearEmptySibling(start); + me.fireEvent('contentchange'); + range.setStart(start,0).setCursor(false,true); + me.fireEvent('saveScene'); + domUtils.preventDefault(evt); + return; + } + + if (li && (pre = li.previousSibling)) { + if (keyCode == 46 && li.childNodes.length) { + return; + } + //有可能上边的兄弟节点是个2级菜单,要追加到2级菜单的最后的li + if (dtd.$list[pre.tagName]) { + pre = pre.lastChild; + } + me.undoManger && me.undoManger.save(); + first = li.firstChild; + if (domUtils.isBlockElm(first)) { + if (domUtils.isEmptyNode(first)) { +// range.setEnd(pre, pre.childNodes.length).shrinkBoundary().collapse().select(true); + pre.appendChild(first); + range.setStart(first, 0).setCursor(false, true); + //first不是唯一的节点 + while (li.firstChild) { + pre.appendChild(li.firstChild); + } + } else { + + span = me.document.createElement('span'); + range.insertNode(span); + //判断pre是否是空的节点,如果是


      类型的空节点,干掉p标签防止它占位 + if (domUtils.isEmptyBlock(pre)) { + pre.innerHTML = ''; + } + domUtils.moveChild(li, pre); + range.setStartBefore(span).collapse(true).select(true); + + domUtils.remove(span); + + } + } else { + if (domUtils.isEmptyNode(li)) { + var p = me.document.createElement('p'); + pre.appendChild(p); + range.setStart(p, 0).setCursor(); +// range.setEnd(pre, pre.childNodes.length).shrinkBoundary().collapse().select(true); + } else { + range.setEnd(pre, pre.childNodes.length).collapse().select(true); + while (li.firstChild) { + pre.appendChild(li.firstChild); + } + } + } + domUtils.remove(li); + me.fireEvent('contentchange'); + me.fireEvent('saveScene'); + domUtils.preventDefault(evt); + return; + + } + //trace:980 + + if (li && !li.previousSibling) { + var parentList = li.parentNode; + var bk = range.createBookmark(); + if(domUtils.isTagNode(parentList.parentNode,'ol ul')){ + parentList.parentNode.insertBefore(li,parentList); + if(domUtils.isEmptyNode(parentList)){ + domUtils.remove(parentList) + } + }else{ + + while(li.firstChild){ + parentList.parentNode.insertBefore(li.firstChild,parentList); + } + + domUtils.remove(li); + if(domUtils.isEmptyNode(parentList)){ + domUtils.remove(parentList) + } + + } + range.moveToBookmark(bk).setCursor(false,true); + me.fireEvent('contentchange'); + me.fireEvent('saveScene'); + domUtils.preventDefault(evt); + return; + + } + + + } + + + } + + } + }); + + me.addListener('keyup',function(type, evt){ + var keyCode = evt.keyCode || evt.which; + if (keyCode == 8) { + var rng = me.selection.getRange(),list; + if(list = domUtils.findParentByTagName(rng.startContainer,['ol', 'ul'],true)){ + adjustList(list,list.tagName.toLowerCase(),getStyle(list)||domUtils.getComputedStyle(list,'list-style-type'),true) + } + } + }); + //处理tab键 + me.addListener('tabkeydown',function(){ + + var range = me.selection.getRange(); + + //控制级数 + function checkLevel(li){ + if(me.options.maxListLevel != -1){ + var level = li.parentNode,levelNum = 0; + while(/[ou]l/i.test(level.tagName)){ + levelNum++; + level = level.parentNode; + } + if(levelNum >= me.options.maxListLevel){ + return true; + } + } + } + //只以开始为准 + //todo 后续改进 + var li = domUtils.findParentByTagName(range.startContainer, 'li', true); + if(li){ + + var bk; + if(range.collapsed){ + if(checkLevel(li)) + return true; + var parentLi = li.parentNode, + list = me.document.createElement(parentLi.tagName), + index = utils.indexOf(listStyle[list.tagName], getStyle(parentLi)||domUtils.getComputedStyle(parentLi, 'list-style-type')); + index = index + 1 == listStyle[list.tagName].length ? 0 : index + 1; + var currentStyle = listStyle[list.tagName][index]; + setListStyle(list,currentStyle); + if(domUtils.isStartInblock(range)){ + me.fireEvent('saveScene'); + bk = range.createBookmark(); + parentLi.insertBefore(list, li); + list.appendChild(li); + adjustList(list,list.tagName.toLowerCase(),currentStyle); + me.fireEvent('contentchange'); + range.moveToBookmark(bk).select(true); + return true; + } + }else{ + me.fireEvent('saveScene'); + bk = range.createBookmark(); + for(var i= 0,closeList,parents = domUtils.findParents(li),ci;ci=parents[i++];){ + if(domUtils.isTagNode(ci,'ol ul')){ + closeList = ci; + break; + } + } + var current = li; + if(bk.end){ + while(current && !(domUtils.getPosition(current, bk.end) & domUtils.POSITION_FOLLOWING)){ + if(checkLevel(current)){ + current = domUtils.getNextDomNode(current,false,null,function(node){return node !== closeList}); + continue; + } + var parentLi = current.parentNode, + list = me.document.createElement(parentLi.tagName), + index = utils.indexOf(listStyle[list.tagName], getStyle(parentLi)||domUtils.getComputedStyle(parentLi, 'list-style-type')); + var currentIndex = index + 1 == listStyle[list.tagName].length ? 0 : index + 1; + var currentStyle = listStyle[list.tagName][currentIndex]; + setListStyle(list,currentStyle); + parentLi.insertBefore(list, current); + while(current && !(domUtils.getPosition(current, bk.end) & domUtils.POSITION_FOLLOWING)){ + li = current.nextSibling; + list.appendChild(current); + if(!li || domUtils.isTagNode(li,'ol ul')){ + if(li){ + while(li = li.firstChild){ + if(li.tagName == 'LI'){ + break; + } + } + }else{ + li = domUtils.getNextDomNode(current,false,null,function(node){return node !== closeList}); + } + break; + } + current = li; + } + adjustList(list,list.tagName.toLowerCase(),currentStyle); + current = li; + } + } + me.fireEvent('contentchange'); + range.moveToBookmark(bk).select(); + return true; + } + } + + }); + function getLi(start){ + while(start && !domUtils.isBody(start)){ + if(start.nodeName == 'TABLE'){ + return null; + } + if(start.nodeName == 'LI'){ + return start + } + start = start.parentNode; + } + } + + /** + * 有序列表,与“insertunorderedlist”命令互斥 + * @command insertorderedlist + * @method execCommand + * @param { String } command 命令字符串 + * @param { String } style 插入的有序列表类型,值为:decimal,lower-alpha,lower-roman,upper-alpha,upper-roman,cn,cn1,cn2,num,num1,num2 + * @example + * ```javascript + * editor.execCommand( 'insertorderedlist','decimal'); + * ``` + */ + /** + * 查询当前选区内容是否有序列表 + * @command insertorderedlist + * @method queryCommandState + * @param { String } cmd 命令字符串 + * @return { int } 如果当前选区是有序列表返回1,否则返回0 + * @example + * ```javascript + * editor.queryCommandState( 'insertorderedlist' ); + * ``` + */ + /** + * 查询当前选区内容是否有序列表 + * @command insertorderedlist + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回当前有序列表的类型,值为null或decimal,lower-alpha,lower-roman,upper-alpha,upper-roman,cn,cn1,cn2,num,num1,num2 + * @example + * ```javascript + * editor.queryCommandValue( 'insertorderedlist' ); + * ``` + */ + + /** + * 无序列表,与“insertorderedlist”命令互斥 + * @command insertunorderedlist + * @method execCommand + * @param { String } command 命令字符串 + * @param { String } style 插入的无序列表类型,值为:circle,disc,square,dash,dot + * @example + * ```javascript + * editor.execCommand( 'insertunorderedlist','circle'); + * ``` + */ + /** + * 查询当前是否有word文档粘贴进来的图片 + * @command insertunorderedlist + * @method insertunorderedlist + * @param { String } command 命令字符串 + * @return { int } 如果当前选区是无序列表返回1,否则返回0 + * @example + * ```javascript + * editor.queryCommandState( 'insertunorderedlist' ); + * ``` + */ + /** + * 查询当前选区内容是否有序列表 + * @command insertunorderedlist + * @method queryCommandValue + * @param { String } command 命令字符串 + * @return { String } 返回当前无序列表的类型,值为null或circle,disc,square,dash,dot + * @example + * ```javascript + * editor.queryCommandValue( 'insertunorderedlist' ); + * ``` + */ + + me.commands['insertorderedlist'] = + me.commands['insertunorderedlist'] = { + execCommand:function (command, style) { + + if (!style) { + style = command.toLowerCase() == 'insertorderedlist' ? 'decimal' : 'disc'; + } + var me = this, + range = this.selection.getRange(), + filterFn = function (node) { + return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' : !domUtils.isWhitespace(node); + }, + tag = command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul', + frag = me.document.createDocumentFragment(); + //去掉是因为会出现选到末尾,导致adjustmentBoundary缩到ol/ul的位置 + //range.shrinkBoundary();//.adjustmentBoundary(); + range.adjustmentBoundary().shrinkBoundary(); + var bko = range.createBookmark(true), + start = getLi(me.document.getElementById(bko.start)), + modifyStart = 0, + end = getLi(me.document.getElementById(bko.end)), + modifyEnd = 0, + startParent, endParent, + list, tmp; + + if (start || end) { + start && (startParent = start.parentNode); + if (!bko.end) { + end = start; + } + end && (endParent = end.parentNode); + + if (startParent === endParent) { + while (start !== end) { + tmp = start; + start = start.nextSibling; + if (!domUtils.isBlockElm(tmp.firstChild)) { + var p = me.document.createElement('p'); + while (tmp.firstChild) { + p.appendChild(tmp.firstChild); + } + tmp.appendChild(p); + } + frag.appendChild(tmp); + } + tmp = me.document.createElement('span'); + startParent.insertBefore(tmp, end); + if (!domUtils.isBlockElm(end.firstChild)) { + p = me.document.createElement('p'); + while (end.firstChild) { + p.appendChild(end.firstChild); + } + end.appendChild(p); + } + frag.appendChild(end); + domUtils.breakParent(tmp, startParent); + if (domUtils.isEmptyNode(tmp.previousSibling)) { + domUtils.remove(tmp.previousSibling); + } + if (domUtils.isEmptyNode(tmp.nextSibling)) { + domUtils.remove(tmp.nextSibling) + } + var nodeStyle = getStyle(startParent) || domUtils.getComputedStyle(startParent, 'list-style-type') || (command.toLowerCase() == 'insertorderedlist' ? 'decimal' : 'disc'); + if (startParent.tagName.toLowerCase() == tag && nodeStyle == style) { + for (var i = 0, ci, tmpFrag = me.document.createDocumentFragment(); ci = frag.firstChild;) { + if(domUtils.isTagNode(ci,'ol ul')){ +// 删除时,子列表不处理 +// utils.each(domUtils.getElementsByTagName(ci,'li'),function(li){ +// while(li.firstChild){ +// tmpFrag.appendChild(li.firstChild); +// } +// +// }); + tmpFrag.appendChild(ci); + }else{ + while (ci.firstChild) { + + tmpFrag.appendChild(ci.firstChild); + domUtils.remove(ci); + } + } + + } + tmp.parentNode.insertBefore(tmpFrag, tmp); + } else { + list = me.document.createElement(tag); + setListStyle(list,style); + list.appendChild(frag); + tmp.parentNode.insertBefore(list, tmp); + } + + domUtils.remove(tmp); + list && adjustList(list, tag, style); + range.moveToBookmark(bko).select(); + return; + } + //开始 + if (start) { + while (start) { + tmp = start.nextSibling; + if (domUtils.isTagNode(start, 'ol ul')) { + frag.appendChild(start); + } else { + var tmpfrag = me.document.createDocumentFragment(), + hasBlock = 0; + while (start.firstChild) { + if (domUtils.isBlockElm(start.firstChild)) { + hasBlock = 1; + } + tmpfrag.appendChild(start.firstChild); + } + if (!hasBlock) { + var tmpP = me.document.createElement('p'); + tmpP.appendChild(tmpfrag); + frag.appendChild(tmpP); + } else { + frag.appendChild(tmpfrag); + } + domUtils.remove(start); + } + + start = tmp; + } + startParent.parentNode.insertBefore(frag, startParent.nextSibling); + if (domUtils.isEmptyNode(startParent)) { + range.setStartBefore(startParent); + domUtils.remove(startParent); + } else { + range.setStartAfter(startParent); + } + modifyStart = 1; + } + + if (end && domUtils.inDoc(endParent, me.document)) { + //结束 + start = endParent.firstChild; + while (start && start !== end) { + tmp = start.nextSibling; + if (domUtils.isTagNode(start, 'ol ul')) { + frag.appendChild(start); + } else { + tmpfrag = me.document.createDocumentFragment(); + hasBlock = 0; + while (start.firstChild) { + if (domUtils.isBlockElm(start.firstChild)) { + hasBlock = 1; + } + tmpfrag.appendChild(start.firstChild); + } + if (!hasBlock) { + tmpP = me.document.createElement('p'); + tmpP.appendChild(tmpfrag); + frag.appendChild(tmpP); + } else { + frag.appendChild(tmpfrag); + } + domUtils.remove(start); + } + start = tmp; + } + var tmpDiv = domUtils.createElement(me.document, 'div', { + 'tmpDiv':1 + }); + domUtils.moveChild(end, tmpDiv); + + frag.appendChild(tmpDiv); + domUtils.remove(end); + endParent.parentNode.insertBefore(frag, endParent); + range.setEndBefore(endParent); + if (domUtils.isEmptyNode(endParent)) { + domUtils.remove(endParent); + } + + modifyEnd = 1; + } + + + } + + if (!modifyStart) { + range.setStartBefore(me.document.getElementById(bko.start)); + } + if (bko.end && !modifyEnd) { + range.setEndAfter(me.document.getElementById(bko.end)); + } + range.enlarge(true, function (node) { + return notExchange[node.tagName]; + }); + + frag = me.document.createDocumentFragment(); + + var bk = range.createBookmark(), + current = domUtils.getNextDomNode(bk.start, false, filterFn), + tmpRange = range.cloneRange(), + tmpNode, + block = domUtils.isBlockElm; + + while (current && current !== bk.end && (domUtils.getPosition(current, bk.end) & domUtils.POSITION_PRECEDING)) { + + if (current.nodeType == 3 || dtd.li[current.tagName]) { + if (current.nodeType == 1 && dtd.$list[current.tagName]) { + while (current.firstChild) { + frag.appendChild(current.firstChild); + } + tmpNode = domUtils.getNextDomNode(current, false, filterFn); + domUtils.remove(current); + current = tmpNode; + continue; + + } + tmpNode = current; + tmpRange.setStartBefore(current); + + while (current && current !== bk.end && (!block(current) || domUtils.isBookmarkNode(current) )) { + tmpNode = current; + current = domUtils.getNextDomNode(current, false, null, function (node) { + return !notExchange[node.tagName]; + }); + } + + if (current && block(current)) { + tmp = domUtils.getNextDomNode(tmpNode, false, filterFn); + if (tmp && domUtils.isBookmarkNode(tmp)) { + current = domUtils.getNextDomNode(tmp, false, filterFn); + tmpNode = tmp; + } + } + tmpRange.setEndAfter(tmpNode); + + current = domUtils.getNextDomNode(tmpNode, false, filterFn); + + var li = range.document.createElement('li'); + + li.appendChild(tmpRange.extractContents()); + if(domUtils.isEmptyNode(li)){ + var tmpNode = range.document.createElement('p'); + while(li.firstChild){ + tmpNode.appendChild(li.firstChild) + } + li.appendChild(tmpNode); + } + frag.appendChild(li); + } else { + current = domUtils.getNextDomNode(current, true, filterFn); + } + } + range.moveToBookmark(bk).collapse(true); + list = me.document.createElement(tag); + setListStyle(list,style); + list.appendChild(frag); + range.insertNode(list); + //当前list上下看能否合并 + adjustList(list, tag, style); + //去掉冗余的tmpDiv + for (var i = 0, ci, tmpDivs = domUtils.getElementsByTagName(list, 'div'); ci = tmpDivs[i++];) { + if (ci.getAttribute('tmpDiv')) { + domUtils.remove(ci, true) + } + } + range.moveToBookmark(bko).select(); + + }, + queryCommandState:function (command) { + var tag = command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul'; + var path = this.selection.getStartElementPath(); + for(var i= 0,ci;ci = path[i++];){ + if(ci.nodeName == 'TABLE'){ + return 0 + } + if(tag == ci.nodeName.toLowerCase()){ + return 1 + }; + } + return 0; + + }, + queryCommandValue:function (command) { + var tag = command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul'; + var path = this.selection.getStartElementPath(), + node; + for(var i= 0,ci;ci = path[i++];){ + if(ci.nodeName == 'TABLE'){ + node = null; + break; + } + if(tag == ci.nodeName.toLowerCase()){ + node = ci; + break; + }; + } + return node ? getStyle(node) || domUtils.getComputedStyle(node, 'list-style-type') : null; + } + }; +}; + + + +// plugins/source.js +/** + * 源码编辑插件 + * @file + * @since 1.2.6.1 + */ + +(function (){ + var sourceEditors = { + textarea: function (editor, holder){ + var textarea = holder.ownerDocument.createElement('textarea'); + textarea.style.cssText = 'position:absolute;resize:none;width:100%;height:100%;border:0;padding:0;margin:0;overflow-y:auto;'; + // todo: IE下只有onresize属性可用... 很纠结 + if (browser.ie && browser.version < 8) { + textarea.style.width = holder.offsetWidth + 'px'; + textarea.style.height = holder.offsetHeight + 'px'; + holder.onresize = function (){ + textarea.style.width = holder.offsetWidth + 'px'; + textarea.style.height = holder.offsetHeight + 'px'; + }; + } + holder.appendChild(textarea); + return { + setContent: function (content){ + textarea.value = content; + }, + getContent: function (){ + return textarea.value; + }, + select: function (){ + var range; + if (browser.ie) { + range = textarea.createTextRange(); + range.collapse(true); + range.select(); + } else { + //todo: chrome下无法设置焦点 + textarea.setSelectionRange(0, 0); + textarea.focus(); + } + }, + dispose: function (){ + holder.removeChild(textarea); + // todo + holder.onresize = null; + textarea = null; + holder = null; + } + }; + }, + codemirror: function (editor, holder){ + + var codeEditor = window.CodeMirror(holder, { + mode: "text/html", + tabMode: "indent", + lineNumbers: true, + lineWrapping:true + }); + var dom = codeEditor.getWrapperElement(); + dom.style.cssText = 'position:absolute;left:0;top:0;width:100%;height:100%;font-family:consolas,"Courier new",monospace;font-size:13px;'; + codeEditor.getScrollerElement().style.cssText = 'position:absolute;left:0;top:0;width:100%;height:100%;'; + codeEditor.refresh(); + return { + getCodeMirror:function(){ + return codeEditor; + }, + setContent: function (content){ + codeEditor.setValue(content); + }, + getContent: function (){ + return codeEditor.getValue(); + }, + select: function (){ + codeEditor.focus(); + }, + dispose: function (){ + holder.removeChild(dom); + dom = null; + codeEditor = null; + } + }; + } + }; + + UE.plugins['source'] = function (){ + var me = this; + var opt = this.options; + var sourceMode = false; + var sourceEditor; + var orgSetContent; + opt.sourceEditor = browser.ie ? 'textarea' : (opt.sourceEditor || 'codemirror'); + + me.setOpt({ + sourceEditorFirst:false + }); + function createSourceEditor(holder){ + return sourceEditors[opt.sourceEditor == 'codemirror' && window.CodeMirror ? 'codemirror' : 'textarea'](me, holder); + } + + var bakCssText; + //解决在源码模式下getContent不能得到最新的内容问题 + var oldGetContent, + bakAddress; + + /** + * 切换源码模式和编辑模式 + * @command source + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'source'); + * ``` + */ + + /** + * 查询当前编辑区域的状态是源码模式还是可视化模式 + * @command source + * @method queryCommandState + * @param { String } cmd 命令字符串 + * @return { int } 如果当前是源码编辑模式,返回1,否则返回0 + * @example + * ```javascript + * editor.queryCommandState( 'source' ); + * ``` + */ + + me.commands['source'] = { + execCommand: function (){ + + sourceMode = !sourceMode; + if (sourceMode) { + bakAddress = me.selection.getRange().createAddress(false,true); + me.undoManger && me.undoManger.save(true); + if(browser.gecko){ + me.body.contentEditable = false; + } + + bakCssText = me.iframe.style.cssText; + me.iframe.style.cssText += 'position:absolute;left:-32768px;top:-32768px;'; + + + me.fireEvent('beforegetcontent'); + var root = UE.htmlparser(me.body.innerHTML); + me.filterOutputRule(root); + root.traversal(function (node) { + if (node.type == 'element') { + switch (node.tagName) { + case 'td': + case 'th': + case 'caption': + if(node.children && node.children.length == 1){ + if(node.firstChild().tagName == 'br' ){ + node.removeChild(node.firstChild()) + } + }; + break; + case 'pre': + node.innerText(node.innerText().replace(/ /g,' ')) + + } + } + }); + + me.fireEvent('aftergetcontent'); + + var content = root.toHtml(true); + + sourceEditor = createSourceEditor(me.iframe.parentNode); + + sourceEditor.setContent(content); + + orgSetContent = me.setContent; + + me.setContent = function(html){ + //这里暂时不触发事件,防止报错 + var root = UE.htmlparser(html); + me.filterInputRule(root); + html = root.toHtml(); + sourceEditor.setContent(html); + }; + + setTimeout(function (){ + sourceEditor.select(); + me.addListener('fullscreenchanged', function(){ + try{ + sourceEditor.getCodeMirror().refresh() + }catch(e){} + }); + }); + + //重置getContent,源码模式下取值也能是最新的数据 + oldGetContent = me.getContent; + me.getContent = function (){ + return sourceEditor.getContent() || '

      ' + (browser.ie ? '' : '
      ')+'

      '; + }; + } else { + me.iframe.style.cssText = bakCssText; + var cont = sourceEditor.getContent() || '

      ' + (browser.ie ? '' : '
      ')+'

      '; + //处理掉block节点前后的空格,有可能会误命中,暂时不考虑 + cont = cont.replace(new RegExp('[\\r\\t\\n ]*<\/?(\\w+)\\s*(?:[^>]*)>','g'), function(a,b){ + if(b && !dtd.$inlineWithA[b.toLowerCase()]){ + return a.replace(/(^[\n\r\t ]*)|([\n\r\t ]*$)/g,''); + } + return a.replace(/(^[\n\r\t]*)|([\n\r\t]*$)/g,'') + }); + me.setContent = orgSetContent; + + me.setContent(cont); + sourceEditor.dispose(); + sourceEditor = null; + //还原getContent方法 + me.getContent = oldGetContent; + var first = me.body.firstChild; + //trace:1106 都删除空了,下边会报错,所以补充一个p占位 + if(!first){ + me.body.innerHTML = '

      '+(browser.ie?'':'
      ')+'

      '; + first = me.body.firstChild; + } + + + //要在ifm为显示时ff才能取到selection,否则报错 + //这里不能比较位置了 + me.undoManger && me.undoManger.save(true); + + if(browser.gecko){ + + var input = document.createElement('input'); + input.style.cssText = 'position:absolute;left:0;top:-32768px'; + + document.body.appendChild(input); + + me.body.contentEditable = false; + setTimeout(function(){ + domUtils.setViewportOffset(input, { left: -32768, top: 0 }); + input.focus(); + setTimeout(function(){ + me.body.contentEditable = true; + me.selection.getRange().moveToAddress(bakAddress).select(true); + domUtils.remove(input); + }); + + }); + }else{ + //ie下有可能报错,比如在代码顶头的情况 + try{ + me.selection.getRange().moveToAddress(bakAddress).select(true); + }catch(e){} + + } + } + this.fireEvent('sourcemodechanged', sourceMode); + }, + queryCommandState: function (){ + return sourceMode|0; + }, + notNeedUndo : 1 + }; + var oldQueryCommandState = me.queryCommandState; + + me.queryCommandState = function (cmdName){ + cmdName = cmdName.toLowerCase(); + if (sourceMode) { + //源码模式下可以开启的命令 + return cmdName in { + 'source' : 1, + 'fullscreen' : 1 + } ? 1 : -1 + } + return oldQueryCommandState.apply(this, arguments); + }; + + if(opt.sourceEditor == "codemirror"){ + + me.addListener("ready",function(){ + utils.loadFile(document,{ + src : opt.codeMirrorJsUrl || opt.UEDITOR_HOME_URL + "third-party/codemirror/codemirror.js", + tag : "script", + type : "text/javascript", + defer : "defer" + },function(){ + if(opt.sourceEditorFirst){ + setTimeout(function(){ + me.execCommand("source"); + },0); + } + }); + utils.loadFile(document,{ + tag : "link", + rel : "stylesheet", + type : "text/css", + href : opt.codeMirrorCssUrl || opt.UEDITOR_HOME_URL + "third-party/codemirror/codemirror.css" + }); + + }); + } + + }; + +})(); + +// plugins/enterkey.js +///import core +///import plugins/undo.js +///commands 设置回车标签p或br +///commandsName EnterKey +///commandsTitle 设置回车标签p或br +/** + * @description 处理回车 + * @author zhanyi + */ +UE.plugins['enterkey'] = function() { + var hTag, + me = this, + tag = me.options.enterTag; + me.addListener('keyup', function(type, evt) { + + var keyCode = evt.keyCode || evt.which; + if (keyCode == 13) { + var range = me.selection.getRange(), + start = range.startContainer, + doSave; + + //修正在h1-h6里边回车后不能嵌套p的问题 + if (!browser.ie) { + + if (/h\d/i.test(hTag)) { + if (browser.gecko) { + var h = domUtils.findParentByTagName(start, [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6','blockquote','caption','table'], true); + if (!h) { + me.document.execCommand('formatBlock', false, '

      '); + doSave = 1; + } + } else { + //chrome remove div + if (start.nodeType == 1) { + var tmp = me.document.createTextNode(''),div; + range.insertNode(tmp); + div = domUtils.findParentByTagName(tmp, 'div', true); + if (div) { + var p = me.document.createElement('p'); + while (div.firstChild) { + p.appendChild(div.firstChild); + } + div.parentNode.insertBefore(p, div); + domUtils.remove(div); + range.setStartBefore(tmp).setCursor(); + doSave = 1; + } + domUtils.remove(tmp); + + } + } + + if (me.undoManger && doSave) { + me.undoManger.save(); + } + } + //没有站位符,会出现多行的问题 + browser.opera && range.select(); + }else{ + me.fireEvent('saveScene',true,true) + } + } + }); + + me.addListener('keydown', function(type, evt) { + var keyCode = evt.keyCode || evt.which; + if (keyCode == 13) {//回车 + if(me.fireEvent('beforeenterkeydown')){ + domUtils.preventDefault(evt); + return; + } + me.fireEvent('saveScene',true,true); + hTag = ''; + + + var range = me.selection.getRange(); + + if (!range.collapsed) { + //跨td不能删 + var start = range.startContainer, + end = range.endContainer, + startTd = domUtils.findParentByTagName(start, 'td', true), + endTd = domUtils.findParentByTagName(end, 'td', true); + if (startTd && endTd && startTd !== endTd || !startTd && endTd || startTd && !endTd) { + evt.preventDefault ? evt.preventDefault() : ( evt.returnValue = false); + return; + } + } + if (tag == 'p') { + + + if (!browser.ie) { + + start = domUtils.findParentByTagName(range.startContainer, ['ol','ul','p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6','blockquote','caption'], true); + + //opera下执行formatblock会在table的场景下有问题,回车在opera原生支持很好,所以暂时在opera去掉调用这个原生的command + //trace:2431 + if (!start && !browser.opera) { + + me.document.execCommand('formatBlock', false, '

      '); + + if (browser.gecko) { + range = me.selection.getRange(); + start = domUtils.findParentByTagName(range.startContainer, 'p', true); + start && domUtils.removeDirtyAttr(start); + } + + + } else { + hTag = start.tagName; + start.tagName.toLowerCase() == 'p' && browser.gecko && domUtils.removeDirtyAttr(start); + } + + } + + } else { + evt.preventDefault ? evt.preventDefault() : ( evt.returnValue = false); + + if (!range.collapsed) { + range.deleteContents(); + start = range.startContainer; + if (start.nodeType == 1 && (start = start.childNodes[range.startOffset])) { + while (start.nodeType == 1) { + if (dtd.$empty[start.tagName]) { + range.setStartBefore(start).setCursor(); + if (me.undoManger) { + me.undoManger.save(); + } + return false; + } + if (!start.firstChild) { + var br = range.document.createElement('br'); + start.appendChild(br); + range.setStart(start, 0).setCursor(); + if (me.undoManger) { + me.undoManger.save(); + } + return false; + } + start = start.firstChild; + } + if (start === range.startContainer.childNodes[range.startOffset]) { + br = range.document.createElement('br'); + range.insertNode(br).setCursor(); + + } else { + range.setStart(start, 0).setCursor(); + } + + + } else { + br = range.document.createElement('br'); + range.insertNode(br).setStartAfter(br).setCursor(); + } + + + } else { + br = range.document.createElement('br'); + range.insertNode(br); + var parent = br.parentNode; + if (parent.lastChild === br) { + br.parentNode.insertBefore(br.cloneNode(true), br); + range.setStartBefore(br); + } else { + range.setStartAfter(br); + } + range.setCursor(); + + } + + } + + } + }); +}; + + +// plugins/keystrokes.js +/* 处理特殊键的兼容性问题 */ +UE.plugins['keystrokes'] = function() { + var me = this; + var collapsed = true; + me.addListener('keydown', function(type, evt) { + var keyCode = evt.keyCode || evt.which, + rng = me.selection.getRange(); + + //处理全选的情况 + if(!rng.collapsed && !(evt.ctrlKey || evt.shiftKey || evt.altKey || evt.metaKey) && (keyCode >= 65 && keyCode <=90 + || keyCode >= 48 && keyCode <= 57 || + keyCode >= 96 && keyCode <= 111 || { + 13:1, + 8:1, + 46:1 + }[keyCode]) + ){ + + var tmpNode = rng.startContainer; + if(domUtils.isFillChar(tmpNode)){ + rng.setStartBefore(tmpNode) + } + tmpNode = rng.endContainer; + if(domUtils.isFillChar(tmpNode)){ + rng.setEndAfter(tmpNode) + } + rng.txtToElmBoundary(); + //结束边界可能放到了br的前边,要把br包含进来 + // x[xxx]
      + if(rng.endContainer && rng.endContainer.nodeType == 1){ + tmpNode = rng.endContainer.childNodes[rng.endOffset]; + if(tmpNode && domUtils.isBr(tmpNode)){ + rng.setEndAfter(tmpNode); + } + } + if(rng.startOffset == 0){ + tmpNode = rng.startContainer; + if(domUtils.isBoundaryNode(tmpNode,'firstChild') ){ + tmpNode = rng.endContainer; + if(rng.endOffset == (tmpNode.nodeType == 3 ? tmpNode.nodeValue.length : tmpNode.childNodes.length) && domUtils.isBoundaryNode(tmpNode,'lastChild')){ + me.fireEvent('saveScene'); + me.body.innerHTML = '

      '+(browser.ie ? '' : '
      ')+'

      '; + rng.setStart(me.body.firstChild,0).setCursor(false,true); + me._selectionChange(); + return; + } + } + } + } + + //处理backspace + if (keyCode == keymap.Backspace) { + rng = me.selection.getRange(); + collapsed = rng.collapsed; + if(me.fireEvent('delkeydown',evt)){ + return; + } + var start,end; + //避免按两次删除才能生效的问题 + if(rng.collapsed && rng.inFillChar()){ + start = rng.startContainer; + + if(domUtils.isFillChar(start)){ + rng.setStartBefore(start).shrinkBoundary(true).collapse(true); + domUtils.remove(start) + }else{ + start.nodeValue = start.nodeValue.replace(new RegExp('^' + domUtils.fillChar ),''); + rng.startOffset--; + rng.collapse(true).select(true) + } + } + + //解决选中control元素不能删除的问题 + if (start = rng.getClosedNode()) { + me.fireEvent('saveScene'); + rng.setStartBefore(start); + domUtils.remove(start); + rng.setCursor(); + me.fireEvent('saveScene'); + domUtils.preventDefault(evt); + return; + } + //阻止在table上的删除 + if (!browser.ie) { + start = domUtils.findParentByTagName(rng.startContainer, 'table', true); + end = domUtils.findParentByTagName(rng.endContainer, 'table', true); + if (start && !end || !start && end || start !== end) { + evt.preventDefault(); + return; + } + } + + } + //处理tab键的逻辑 + if (keyCode == keymap.Tab) { + //不处理以下标签 + var excludeTagNameForTabKey = { + 'ol' : 1, + 'ul' : 1, + 'table':1 + }; + //处理组件里的tab按下事件 + if(me.fireEvent('tabkeydown',evt)){ + domUtils.preventDefault(evt); + return; + } + var range = me.selection.getRange(); + me.fireEvent('saveScene'); + for (var i = 0,txt = '',tabSize = me.options.tabSize|| 4,tabNode = me.options.tabNode || ' '; i < tabSize; i++) { + txt += tabNode; + } + var span = me.document.createElement('span'); + span.innerHTML = txt + domUtils.fillChar; + if (range.collapsed) { + range.insertNode(span.cloneNode(true).firstChild).setCursor(true); + } else { + var filterFn = function(node) { + return domUtils.isBlockElm(node) && !excludeTagNameForTabKey[node.tagName.toLowerCase()] + + }; + //普通的情况 + start = domUtils.findParent(range.startContainer, filterFn,true); + end = domUtils.findParent(range.endContainer, filterFn,true); + if (start && end && start === end) { + range.deleteContents(); + range.insertNode(span.cloneNode(true).firstChild).setCursor(true); + } else { + var bookmark = range.createBookmark(); + range.enlarge(true); + var bookmark2 = range.createBookmark(), + current = domUtils.getNextDomNode(bookmark2.start, false, filterFn); + while (current && !(domUtils.getPosition(current, bookmark2.end) & domUtils.POSITION_FOLLOWING)) { + current.insertBefore(span.cloneNode(true).firstChild, current.firstChild); + current = domUtils.getNextDomNode(current, false, filterFn); + } + range.moveToBookmark(bookmark2).moveToBookmark(bookmark).select(); + } + } + domUtils.preventDefault(evt) + } + //trace:1634 + //ff的del键在容器空的时候,也会删除 + if(browser.gecko && keyCode == 46){ + range = me.selection.getRange(); + if(range.collapsed){ + start = range.startContainer; + if(domUtils.isEmptyBlock(start)){ + var parent = start.parentNode; + while(domUtils.getChildCount(parent) == 1 && !domUtils.isBody(parent)){ + start = parent; + parent = parent.parentNode; + } + if(start === parent.lastChild) + evt.preventDefault(); + return; + } + } + } + }); + me.addListener('keyup', function(type, evt) { + var keyCode = evt.keyCode || evt.which, + rng,me = this; + if(keyCode == keymap.Backspace){ + if(me.fireEvent('delkeyup')){ + return; + } + rng = me.selection.getRange(); + if(rng.collapsed){ + var tmpNode, + autoClearTagName = ['h1','h2','h3','h4','h5','h6']; + if(tmpNode = domUtils.findParentByTagName(rng.startContainer,autoClearTagName,true)){ + if(domUtils.isEmptyBlock(tmpNode)){ + var pre = tmpNode.previousSibling; + if(pre && pre.nodeName != 'TABLE'){ + domUtils.remove(tmpNode); + rng.setStartAtLast(pre).setCursor(false,true); + return; + }else{ + var next = tmpNode.nextSibling; + if(next && next.nodeName != 'TABLE'){ + domUtils.remove(tmpNode); + rng.setStartAtFirst(next).setCursor(false,true); + return; + } + } + } + } + //处理当删除到body时,要重新给p标签展位 + if(domUtils.isBody(rng.startContainer)){ + var tmpNode = domUtils.createElement(me.document,'p',{ + 'innerHTML' : browser.ie ? domUtils.fillChar : '
      ' + }); + rng.insertNode(tmpNode).setStart(tmpNode,0).setCursor(false,true); + } + } + + + //chrome下如果删除了inline标签,浏览器会有记忆,在输入文字还是会套上刚才删除的标签,所以这里再选一次就不会了 + if( !collapsed && (rng.startContainer.nodeType == 3 || rng.startContainer.nodeType == 1 && domUtils.isEmptyBlock(rng.startContainer))){ + if(browser.ie){ + var span = rng.document.createElement('span'); + rng.insertNode(span).setStartBefore(span).collapse(true); + rng.select(); + domUtils.remove(span) + }else{ + rng.select() + } + + } + } + + + }) +}; + +// plugins/fiximgclick.js +///import core +///commands 修复chrome下图片不能点击的问题,出现八个角可改变大小 +///commandsName FixImgClick +///commandsTitle 修复chrome下图片不能点击的问题,出现八个角可改变大小 +//修复chrome下图片不能点击的问题,出现八个角可改变大小 + +UE.plugins['fiximgclick'] = (function () { + + var elementUpdated = false; + function Scale() { + this.editor = null; + this.resizer = null; + this.cover = null; + this.doc = document; + this.prePos = {x: 0, y: 0}; + this.startPos = {x: 0, y: 0}; + } + + (function () { + var rect = [ + //[left, top, width, height] + [0, 0, -1, -1], + [0, 0, 0, -1], + [0, 0, 1, -1], + [0, 0, -1, 0], + [0, 0, 1, 0], + [0, 0, -1, 1], + [0, 0, 0, 1], + [0, 0, 1, 1] + ]; + + Scale.prototype = { + init: function (editor) { + var me = this; + me.editor = editor; + me.startPos = this.prePos = {x: 0, y: 0}; + me.dragId = -1; + + var hands = [], + cover = me.cover = document.createElement('div'), + resizer = me.resizer = document.createElement('div'); + + cover.id = me.editor.ui.id + '_imagescale_cover'; + cover.style.cssText = 'position:absolute;display:none;z-index:' + (me.editor.options.zIndex) + ';filter:alpha(opacity=0); opacity:0;background:#CCC;'; + domUtils.on(cover, 'mousedown click', function () { + me.hide(); + }); + + for (i = 0; i < 8; i++) { + hands.push(''); + } + resizer.id = me.editor.ui.id + '_imagescale'; + resizer.className = 'edui-editor-imagescale'; + resizer.innerHTML = hands.join(''); + resizer.style.cssText += ';display:none;border:1px solid #3b77ff;z-index:' + (me.editor.options.zIndex) + ';'; + + me.editor.ui.getDom().appendChild(cover); + me.editor.ui.getDom().appendChild(resizer); + + me.initStyle(); + me.initEvents(); + }, + initStyle: function () { + utils.cssRule('imagescale', '.edui-editor-imagescale{display:none;position:absolute;border:1px solid #38B2CE;cursor:hand;-webkit-box-sizing: content-box;-moz-box-sizing: content-box;box-sizing: content-box;}' + + '.edui-editor-imagescale span{position:absolute;width:6px;height:6px;overflow:hidden;font-size:0px;display:block;background-color:#3C9DD0;}' + + '.edui-editor-imagescale .edui-editor-imagescale-hand0{cursor:nw-resize;top:0;margin-top:-4px;left:0;margin-left:-4px;}' + + '.edui-editor-imagescale .edui-editor-imagescale-hand1{cursor:n-resize;top:0;margin-top:-4px;left:50%;margin-left:-4px;}' + + '.edui-editor-imagescale .edui-editor-imagescale-hand2{cursor:ne-resize;top:0;margin-top:-4px;left:100%;margin-left:-3px;}' + + '.edui-editor-imagescale .edui-editor-imagescale-hand3{cursor:w-resize;top:50%;margin-top:-4px;left:0;margin-left:-4px;}' + + '.edui-editor-imagescale .edui-editor-imagescale-hand4{cursor:e-resize;top:50%;margin-top:-4px;left:100%;margin-left:-3px;}' + + '.edui-editor-imagescale .edui-editor-imagescale-hand5{cursor:sw-resize;top:100%;margin-top:-3px;left:0;margin-left:-4px;}' + + '.edui-editor-imagescale .edui-editor-imagescale-hand6{cursor:s-resize;top:100%;margin-top:-3px;left:50%;margin-left:-4px;}' + + '.edui-editor-imagescale .edui-editor-imagescale-hand7{cursor:se-resize;top:100%;margin-top:-3px;left:100%;margin-left:-3px;}'); + }, + initEvents: function () { + var me = this; + + me.startPos.x = me.startPos.y = 0; + me.isDraging = false; + }, + _eventHandler: function (e) { + var me = this; + switch (e.type) { + case 'mousedown': + var hand = e.target || e.srcElement, hand; + if (hand.className.indexOf('edui-editor-imagescale-hand') != -1 && me.dragId == -1) { + me.dragId = hand.className.slice(-1); + me.startPos.x = me.prePos.x = e.clientX; + me.startPos.y = me.prePos.y = e.clientY; + domUtils.on(me.doc,'mousemove', me.proxy(me._eventHandler, me)); + } + break; + case 'mousemove': + if (me.dragId != -1) { + me.updateContainerStyle(me.dragId, {x: e.clientX - me.prePos.x, y: e.clientY - me.prePos.y}); + me.prePos.x = e.clientX; + me.prePos.y = e.clientY; + elementUpdated = true; + me.updateTargetElement(); + + } + break; + case 'mouseup': + if (me.dragId != -1) { + me.updateContainerStyle(me.dragId, {x: e.clientX - me.prePos.x, y: e.clientY - me.prePos.y}); + me.updateTargetElement(); + if (me.target.parentNode) me.attachTo(me.target); + me.dragId = -1; + } + domUtils.un(me.doc,'mousemove', me.proxy(me._eventHandler, me)); + //修复只是点击挪动点,但没有改变大小,不应该触发contentchange + if(elementUpdated){ + elementUpdated = false; + me.editor.fireEvent('contentchange'); + } + + break; + default: + break; + } + }, + updateTargetElement: function () { + var me = this; + domUtils.setStyles(me.target, { + 'width': me.resizer.style.width, + 'height': me.resizer.style.height + }); + me.target.width = parseInt(me.resizer.style.width); + me.target.height = parseInt(me.resizer.style.height); + me.attachTo(me.target); + }, + updateContainerStyle: function (dir, offset) { + var me = this, + dom = me.resizer, tmp; + + if (rect[dir][0] != 0) { + tmp = parseInt(dom.style.left) + offset.x; + dom.style.left = me._validScaledProp('left', tmp) + 'px'; + } + if (rect[dir][1] != 0) { + tmp = parseInt(dom.style.top) + offset.y; + dom.style.top = me._validScaledProp('top', tmp) + 'px'; + } + if (rect[dir][2] != 0) { + tmp = dom.clientWidth + rect[dir][2] * offset.x; + dom.style.width = me._validScaledProp('width', tmp) + 'px'; + } + if (rect[dir][3] != 0) { + tmp = dom.clientHeight + rect[dir][3] * offset.y; + dom.style.height = me._validScaledProp('height', tmp) + 'px'; + } + }, + _validScaledProp: function (prop, value) { + var ele = this.resizer, + wrap = document; + + value = isNaN(value) ? 0 : value; + switch (prop) { + case 'left': + return value < 0 ? 0 : (value + ele.clientWidth) > wrap.clientWidth ? wrap.clientWidth - ele.clientWidth : value; + case 'top': + return value < 0 ? 0 : (value + ele.clientHeight) > wrap.clientHeight ? wrap.clientHeight - ele.clientHeight : value; + case 'width': + return value <= 0 ? 1 : (value + ele.offsetLeft) > wrap.clientWidth ? wrap.clientWidth - ele.offsetLeft : value; + case 'height': + return value <= 0 ? 1 : (value + ele.offsetTop) > wrap.clientHeight ? wrap.clientHeight - ele.offsetTop : value; + } + }, + hideCover: function () { + this.cover.style.display = 'none'; + }, + showCover: function () { + var me = this, + editorPos = domUtils.getXY(me.editor.ui.getDom()), + iframePos = domUtils.getXY(me.editor.iframe); + + domUtils.setStyles(me.cover, { + 'width': me.editor.iframe.offsetWidth + 'px', + 'height': me.editor.iframe.offsetHeight + 'px', + 'top': iframePos.y - editorPos.y + 'px', + 'left': iframePos.x - editorPos.x + 'px', + 'position': 'absolute', + 'display': '' + }) + }, + show: function (targetObj) { + var me = this; + me.resizer.style.display = 'block'; + if(targetObj) me.attachTo(targetObj); + + domUtils.on(this.resizer, 'mousedown', me.proxy(me._eventHandler, me)); + domUtils.on(me.doc, 'mouseup', me.proxy(me._eventHandler, me)); + + me.showCover(); + me.editor.fireEvent('afterscaleshow', me); + me.editor.fireEvent('saveScene'); + }, + hide: function () { + var me = this; + me.hideCover(); + me.resizer.style.display = 'none'; + + domUtils.un(me.resizer, 'mousedown', me.proxy(me._eventHandler, me)); + domUtils.un(me.doc, 'mouseup', me.proxy(me._eventHandler, me)); + me.editor.fireEvent('afterscalehide', me); + }, + proxy: function( fn, context ) { + return function(e) { + return fn.apply( context || this, arguments); + }; + }, + attachTo: function (targetObj) { + var me = this, + target = me.target = targetObj, + resizer = this.resizer, + imgPos = domUtils.getXY(target), + iframePos = domUtils.getXY(me.editor.iframe), + editorPos = domUtils.getXY(resizer.parentNode); + + domUtils.setStyles(resizer, { + 'width': target.width + 'px', + 'height': target.height + 'px', + 'left': iframePos.x + imgPos.x - me.editor.document.body.scrollLeft - editorPos.x - parseInt(resizer.style.borderLeftWidth) + 'px', + 'top': iframePos.y + imgPos.y - me.editor.document.body.scrollTop - editorPos.y - parseInt(resizer.style.borderTopWidth) + 'px' + }); + } + } + })(); + + return function () { + var me = this, + imageScale; + + me.setOpt('imageScaleEnabled', true); + + if ( !browser.ie && me.options.imageScaleEnabled) { + me.addListener('click', function (type, e) { + + var range = me.selection.getRange(), + img = range.getClosedNode(); + + if (img && img.tagName == 'IMG' && me.body.contentEditable!="false") { + + if (img.className.indexOf("edui-faked-music") != -1 || + img.getAttribute("anchorname") || + domUtils.hasClass(img, 'loadingclass') || + domUtils.hasClass(img, 'loaderrorclass')) { return } + + if (!imageScale) { + imageScale = new Scale(); + imageScale.init(me); + me.ui.getDom().appendChild(imageScale.resizer); + + var _keyDownHandler = function (e) { + imageScale.hide(); + if(imageScale.target) me.selection.getRange().selectNode(imageScale.target).select(); + }, _mouseDownHandler = function (e) { + var ele = e.target || e.srcElement; + if (ele && (ele.className===undefined || ele.className.indexOf('edui-editor-imagescale') == -1)) { + _keyDownHandler(e); + } + }, timer; + + me.addListener('afterscaleshow', function (e) { + me.addListener('beforekeydown', _keyDownHandler); + me.addListener('beforemousedown', _mouseDownHandler); + domUtils.on(document, 'keydown', _keyDownHandler); + domUtils.on(document,'mousedown', _mouseDownHandler); + me.selection.getNative().removeAllRanges(); + }); + me.addListener('afterscalehide', function (e) { + me.removeListener('beforekeydown', _keyDownHandler); + me.removeListener('beforemousedown', _mouseDownHandler); + domUtils.un(document, 'keydown', _keyDownHandler); + domUtils.un(document,'mousedown', _mouseDownHandler); + var target = imageScale.target; + if (target.parentNode) { + me.selection.getRange().selectNode(target).select(); + } + }); + //TODO 有iframe的情况,mousedown不能往下传。。 + domUtils.on(imageScale.resizer, 'mousedown', function (e) { + me.selection.getNative().removeAllRanges(); + var ele = e.target || e.srcElement; + if (ele && ele.className.indexOf('edui-editor-imagescale-hand') == -1) { + timer = setTimeout(function () { + imageScale.hide(); + if(imageScale.target) me.selection.getRange().selectNode(ele).select(); + }, 200); + } + }); + domUtils.on(imageScale.resizer, 'mouseup', function (e) { + var ele = e.target || e.srcElement; + if (ele && ele.className.indexOf('edui-editor-imagescale-hand') == -1) { + clearTimeout(timer); + } + }); + } + imageScale.show(img); + } else { + if (imageScale && imageScale.resizer.style.display != 'none') imageScale.hide(); + } + }); + } + + if (browser.webkit) { + me.addListener('click', function (type, e) { + if (e.target.tagName == 'IMG' && me.body.contentEditable!="false") { + var range = new dom.Range(me.document); + range.selectNode(e.target).select(); + } + }); + } + } +})(); + +// plugins/autolink.js +///import core +///commands 为非ie浏览器自动添加a标签 +///commandsName AutoLink +///commandsTitle 自动增加链接 +/** + * @description 为非ie浏览器自动添加a标签 + * @author zhanyi + */ + +UE.plugin.register('autolink',function(){ + var cont = 0; + + return !browser.ie ? { + + bindEvents:{ + 'reset' : function(){ + cont = 0; + }, + 'keydown':function(type, evt) { + var me = this; + var keyCode = evt.keyCode || evt.which; + + if (keyCode == 32 || keyCode == 13) { + + var sel = me.selection.getNative(), + range = sel.getRangeAt(0).cloneRange(), + offset, + charCode; + + var start = range.startContainer; + while (start.nodeType == 1 && range.startOffset > 0) { + start = range.startContainer.childNodes[range.startOffset - 1]; + if (!start){ + break; + } + range.setStart(start, start.nodeType == 1 ? start.childNodes.length : start.nodeValue.length); + range.collapse(true); + start = range.startContainer; + } + + do{ + if (range.startOffset == 0) { + start = range.startContainer.previousSibling; + + while (start && start.nodeType == 1) { + start = start.lastChild; + } + if (!start || domUtils.isFillChar(start)){ + break; + } + offset = start.nodeValue.length; + } else { + start = range.startContainer; + offset = range.startOffset; + } + range.setStart(start, offset - 1); + charCode = range.toString().charCodeAt(0); + } while (charCode != 160 && charCode != 32); + + if (range.toString().replace(new RegExp(domUtils.fillChar, 'g'), '').match(/(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i)) { + while(range.toString().length){ + if(/^(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i.test(range.toString())){ + break; + } + try{ + range.setStart(range.startContainer,range.startOffset+1); + }catch(e){ + //trace:2121 + var start = range.startContainer; + while(!(next = start.nextSibling)){ + if(domUtils.isBody(start)){ + return; + } + start = start.parentNode; + + } + range.setStart(next,0); + + } + + } + //range的开始边界已经在a标签里的不再处理 + if(domUtils.findParentByTagName(range.startContainer,'a',true)){ + return; + } + var a = me.document.createElement('a'),text = me.document.createTextNode(' '),href; + + me.undoManger && me.undoManger.save(); + a.appendChild(range.extractContents()); + a.href = a.innerHTML = a.innerHTML.replace(/<[^>]+>/g,''); + href = a.getAttribute("href").replace(new RegExp(domUtils.fillChar,'g'),''); + href = /^(?:https?:\/\/)/ig.test(href) ? href : "http://"+ href; + a.setAttribute('_src',utils.html(href)); + a.href = utils.html(href); + + range.insertNode(a); + a.parentNode.insertBefore(text, a.nextSibling); + range.setStart(text, 0); + range.collapse(true); + sel.removeAllRanges(); + sel.addRange(range); + me.undoManger && me.undoManger.save(); + } + } + } + } + }:{} + },function(){ + var keyCodes = { + 37:1, 38:1, 39:1, 40:1, + 13:1,32:1 + }; + function checkIsCludeLink(node){ + if(node.nodeType == 3){ + return null + } + if(node.nodeName == 'A'){ + return node; + } + var lastChild = node.lastChild; + + while(lastChild){ + if(lastChild.nodeName == 'A'){ + return lastChild; + } + if(lastChild.nodeType == 3){ + if(domUtils.isWhitespace(lastChild)){ + lastChild = lastChild.previousSibling; + continue; + } + return null + } + lastChild = lastChild.lastChild; + } + } + browser.ie && this.addListener('keyup',function(cmd,evt){ + var me = this,keyCode = evt.keyCode; + if(keyCodes[keyCode]){ + var rng = me.selection.getRange(); + var start = rng.startContainer; + + if(keyCode == 13){ + while(start && !domUtils.isBody(start) && !domUtils.isBlockElm(start)){ + start = start.parentNode; + } + if(start && !domUtils.isBody(start) && start.nodeName == 'P'){ + var pre = start.previousSibling; + if(pre && pre.nodeType == 1){ + var pre = checkIsCludeLink(pre); + if(pre && !pre.getAttribute('_href')){ + domUtils.remove(pre,true); + } + } + } + }else if(keyCode == 32 ){ + if(start.nodeType == 3 && /^\s$/.test(start.nodeValue)){ + start = start.previousSibling; + if(start && start.nodeName == 'A' && !start.getAttribute('_href')){ + domUtils.remove(start,true); + } + } + }else { + start = domUtils.findParentByTagName(start,'a',true); + if(start && !start.getAttribute('_href')){ + var bk = rng.createBookmark(); + + domUtils.remove(start,true); + rng.moveToBookmark(bk).select(true) + } + } + + } + + + }); + } +); + +// plugins/autoheight.js +///import core +///commands 当输入内容超过编辑器高度时,编辑器自动增高 +///commandsName AutoHeight,autoHeightEnabled +///commandsTitle 自动增高 +/** + * @description 自动伸展 + * @author zhanyi + */ +UE.plugins['autoheight'] = function () { + var me = this; + //提供开关,就算加载也可以关闭 + me.autoHeightEnabled = me.options.autoHeightEnabled !== false; + if (!me.autoHeightEnabled) { + return; + } + + var bakOverflow, + lastHeight = 0, + options = me.options, + currentHeight, + timer; + + function adjustHeight() { + var me = this; + clearTimeout(timer); + if(isFullscreen)return; + if (!me.queryCommandState || me.queryCommandState && me.queryCommandState('source') != 1) { + timer = setTimeout(function(){ + + var node = me.body.lastChild; + while(node && node.nodeType != 1){ + node = node.previousSibling; + } + if(node && node.nodeType == 1){ + node.style.clear = 'both'; + currentHeight = Math.max(domUtils.getXY(node).y + node.offsetHeight + 25 ,Math.max(options.minFrameHeight, options.initialFrameHeight)) ; + if (currentHeight != lastHeight) { + if (currentHeight !== parseInt(me.iframe.parentNode.style.height)) { + me.iframe.parentNode.style.height = currentHeight + 'px'; + } + me.body.style.height = currentHeight + 'px'; + lastHeight = currentHeight; + } + domUtils.removeStyle(node,'clear'); + } + + + },50) + } + } + var isFullscreen; + me.addListener('fullscreenchanged',function(cmd,f){ + isFullscreen = f + }); + me.addListener('destroy', function () { + me.removeListener('contentchange afterinserthtml keyup mouseup',adjustHeight) + }); + me.enableAutoHeight = function () { + var me = this; + if (!me.autoHeightEnabled) { + return; + } + var doc = me.document; + me.autoHeightEnabled = true; + bakOverflow = doc.body.style.overflowY; + doc.body.style.overflowY = 'hidden'; + me.addListener('contentchange afterinserthtml keyup mouseup',adjustHeight); + //ff不给事件算得不对 + + setTimeout(function () { + adjustHeight.call(me); + }, browser.gecko ? 100 : 0); + me.fireEvent('autoheightchanged', me.autoHeightEnabled); + }; + me.disableAutoHeight = function () { + + me.body.style.overflowY = bakOverflow || ''; + + me.removeListener('contentchange', adjustHeight); + me.removeListener('keyup', adjustHeight); + me.removeListener('mouseup', adjustHeight); + me.autoHeightEnabled = false; + me.fireEvent('autoheightchanged', me.autoHeightEnabled); + }; + + me.on('setHeight',function(){ + me.disableAutoHeight() + }); + me.addListener('ready', function () { + me.enableAutoHeight(); + //trace:1764 + var timer; + domUtils.on(browser.ie ? me.body : me.document, browser.webkit ? 'dragover' : 'drop', function () { + clearTimeout(timer); + timer = setTimeout(function () { + //trace:3681 + adjustHeight.call(me); + }, 100); + + }); + //修复内容过多时,回到顶部,顶部内容被工具栏遮挡问题 + var lastScrollY; + window.onscroll = function(){ + if(lastScrollY === null){ + lastScrollY = this.scrollY + }else if(this.scrollY == 0 && lastScrollY != 0){ + me.window.scrollTo(0,0); + lastScrollY = null; + } + } + }); + + +}; + + + +// plugins/autofloat.js +///import core +///commands 悬浮工具栏 +///commandsName AutoFloat,autoFloatEnabled +///commandsTitle 悬浮工具栏 +/** + * modified by chengchao01 + * 注意: 引入此功能后,在IE6下会将body的背景图片覆盖掉! + */ +UE.plugins['autofloat'] = function() { + var me = this, + lang = me.getLang(); + me.setOpt({ + topOffset:0 + }); + var optsAutoFloatEnabled = me.options.autoFloatEnabled !== false, + topOffset = me.options.topOffset; + + + //如果不固定toolbar的位置,则直接退出 + if(!optsAutoFloatEnabled){ + return; + } + var uiUtils = UE.ui.uiUtils, + LteIE6 = browser.ie && browser.version <= 6, + quirks = browser.quirks; + + function checkHasUI(){ + if(!UE.ui){ + alert(lang.autofloatMsg); + return 0; + } + return 1; + } + function fixIE6FixedPos(){ + var docStyle = document.body.style; + docStyle.backgroundImage = 'url("about:blank")'; + docStyle.backgroundAttachment = 'fixed'; + } + var bakCssText, + placeHolder = document.createElement('div'), + toolbarBox,orgTop, + getPosition, + flag =true; //ie7模式下需要偏移 + function setFloating(){ + var toobarBoxPos = domUtils.getXY(toolbarBox), + origalFloat = domUtils.getComputedStyle(toolbarBox,'position'), + origalLeft = domUtils.getComputedStyle(toolbarBox,'left'); + toolbarBox.style.width = toolbarBox.offsetWidth + 'px'; + toolbarBox.style.zIndex = me.options.zIndex * 1 + 1; + toolbarBox.parentNode.insertBefore(placeHolder, toolbarBox); + if (LteIE6 || (quirks && browser.ie)) { + if(toolbarBox.style.position != 'absolute'){ + toolbarBox.style.position = 'absolute'; + } + toolbarBox.style.top = (document.body.scrollTop||document.documentElement.scrollTop) - orgTop + topOffset + 'px'; + } else { + if (browser.ie7Compat && flag) { + flag = false; + toolbarBox.style.left = domUtils.getXY(toolbarBox).x - document.documentElement.getBoundingClientRect().left+2 + 'px'; + } + if(toolbarBox.style.position != 'fixed'){ + toolbarBox.style.position = 'fixed'; + toolbarBox.style.top = topOffset +"px"; + ((origalFloat == 'absolute' || origalFloat == 'relative') && parseFloat(origalLeft)) && (toolbarBox.style.left = toobarBoxPos.x + 'px'); + } + } + } + function unsetFloating(){ + flag = true; + if(placeHolder.parentNode){ + placeHolder.parentNode.removeChild(placeHolder); + } + + toolbarBox.style.cssText = bakCssText; + } + + function updateFloating(){ + var rect3 = getPosition(me.container); + var offset=me.options.toolbarTopOffset||0; + if (rect3.top < 0 && rect3.bottom - toolbarBox.offsetHeight > offset) { + setFloating(); + }else{ + unsetFloating(); + } + } + var defer_updateFloating = utils.defer(function(){ + updateFloating(); + },browser.ie ? 200 : 100,true); + + me.addListener('destroy',function(){ + domUtils.un(window, ['scroll','resize'], updateFloating); + me.removeListener('keydown', defer_updateFloating); + }); + + me.addListener('ready', function(){ + if(checkHasUI(me)){ + //加载了ui组件,但在new时,没有加载ui,导致编辑器实例上没有ui类,所以这里做判断 + if(!me.ui){ + return; + } + getPosition = uiUtils.getClientRect; + toolbarBox = me.ui.getDom('toolbarbox'); + orgTop = getPosition(toolbarBox).top; + bakCssText = toolbarBox.style.cssText; + placeHolder.style.height = toolbarBox.offsetHeight + 'px'; + if(LteIE6){ + fixIE6FixedPos(); + } + domUtils.on(window, ['scroll','resize'], updateFloating); + me.addListener('keydown', defer_updateFloating); + + me.addListener('beforefullscreenchange', function (t, enabled){ + if (enabled) { + unsetFloating(); + } + }); + me.addListener('fullscreenchanged', function (t, enabled){ + if (!enabled) { + updateFloating(); + } + }); + me.addListener('sourcemodechanged', function (t, enabled){ + setTimeout(function (){ + updateFloating(); + },0); + }); + me.addListener("clearDoc",function(){ + setTimeout(function(){ + updateFloating(); + },0); + + }) + } + }); +}; + + +// plugins/video.js +/** + * video插件, 为UEditor提供视频插入支持 + * @file + * @since 1.2.6.1 + */ + +UE.plugins['video'] = function (){ + var me =this; + + /** + * 创建插入视频字符窜 + * @param url 视频地址 + * @param width 视频宽度 + * @param height 视频高度 + * @param align 视频对齐 + * @param toEmbed 是否以flash代替显示 + * @param addParagraph 是否需要添加P 标签 + */ + function creatInsertStr(url,width,height,id,align,classname,type){ + + url = utils.unhtmlForUrl(url); + align = utils.unhtml(align); + classname = utils.unhtml(classname); + + width = parseInt(width, 10) || 0; + height = parseInt(height, 10) || 0; + + var str; + switch (type){ + case 'image': + str = '' + break; + case 'embed': + str = ''; + break; + case 'video': + var ext = url.substr(url.lastIndexOf('.') + 1); + if(ext == 'ogv') ext = 'ogg'; + str = '' + + ''; + break; + } + return str; + } + + function switchImgAndVideo(root,img2video){ + utils.each(root.getNodesByTagName(img2video ? 'img' : 'embed video'),function(node){ + var className = node.getAttr('class'); + if(className && className.indexOf('edui-faked-video') != -1){ + var html = creatInsertStr( img2video ? node.getAttr('_url') : node.getAttr('src'),node.getAttr('width'),node.getAttr('height'),null,node.getStyle('float') || '',className,img2video ? 'embed':'image'); + node.parentNode.replaceChild(UE.uNode.createElement(html),node); + } + if(className && className.indexOf('edui-upload-video') != -1){ + var html = creatInsertStr( img2video ? node.getAttr('_url') : node.getAttr('src'),node.getAttr('width'),node.getAttr('height'),null,node.getStyle('float') || '',className,img2video ? 'video':'image'); + node.parentNode.replaceChild(UE.uNode.createElement(html),node); + } + }) + } + + me.addOutputRule(function(root){ + switchImgAndVideo(root,true) + }); + me.addInputRule(function(root){ + switchImgAndVideo(root) + }); + + /** + * 插入视频 + * @command insertvideo + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { Object } videoAttr 键值对对象, 描述一个视频的所有属性 + * @example + * ```javascript + * + * var videoAttr = { + * //视频地址 + * url: 'http://www.youku.com/xxx', + * //视频宽高值, 单位px + * width: 200, + * height: 100 + * }; + * + * //editor 是编辑器实例 + * //向编辑器插入单个视频 + * editor.execCommand( 'insertvideo', videoAttr ); + * ``` + */ + + /** + * 插入视频 + * @command insertvideo + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { Array } videoArr 需要插入的视频的数组, 其中的每一个元素都是一个键值对对象, 描述了一个视频的所有属性 + * @example + * ```javascript + * + * var videoAttr1 = { + * //视频地址 + * url: 'http://www.youku.com/xxx', + * //视频宽高值, 单位px + * width: 200, + * height: 100 + * }, + * videoAttr2 = { + * //视频地址 + * url: 'http://www.youku.com/xxx', + * //视频宽高值, 单位px + * width: 200, + * height: 100 + * } + * + * //editor 是编辑器实例 + * //该方法将会向编辑器内插入两个视频 + * editor.execCommand( 'insertvideo', [ videoAttr1, videoAttr2 ] ); + * ``` + */ + + /** + * 查询当前光标所在处是否是一个视频 + * @command insertvideo + * @method queryCommandState + * @param { String } cmd 需要查询的命令字符串 + * @return { int } 如果当前光标所在处的元素是一个视频对象, 则返回1,否则返回0 + * @example + * ```javascript + * + * //editor 是编辑器实例 + * editor.queryCommandState( 'insertvideo' ); + * ``` + */ + me.commands["insertvideo"] = { + execCommand: function (cmd, videoObjs, type){ + videoObjs = utils.isArray(videoObjs)?videoObjs:[videoObjs]; + var html = [],id = 'tmpVedio', cl; + for(var i=0,vi,len = videoObjs.length;i 0) { + return 0; + } + for (var i in dtd.$isNotEmpty) if (dtd.$isNotEmpty.hasOwnProperty(i)) { + if (node.getElementsByTagName(i).length) { + return 0; + } + } + return 1; + }; + UETable.getWidth = function (cell) { + if (!cell)return 0; + return parseInt(domUtils.getComputedStyle(cell, "width"), 10); + }; + + /** + * 获取单元格或者单元格组的“对齐”状态。 如果当前的检测对象是一个单元格组, 只有在满足所有单元格的 水平和竖直 对齐属性都相同的 + * 条件时才会返回其状态值,否则将返回null; 如果当前只检测了一个单元格, 则直接返回当前单元格的对齐状态; + * @param table cell or table cells , 支持单个单元格dom对象 或者 单元格dom对象数组 + * @return { align: 'left' || 'right' || 'center', valign: 'top' || 'middle' || 'bottom' } 或者 null + */ + UETable.getTableCellAlignState = function ( cells ) { + + !utils.isArray( cells ) && ( cells = [cells] ); + + var result = {}, + status = ['align', 'valign'], + tempStatus = null, + isSame = true;//状态是否相同 + + utils.each( cells, function( cellNode ){ + + utils.each( status, function( currentState ){ + + tempStatus = cellNode.getAttribute( currentState ); + + if( !result[ currentState ] && tempStatus ) { + result[ currentState ] = tempStatus; + } else if( !result[ currentState ] || ( tempStatus !== result[ currentState ] ) ) { + isSame = false; + return false; + } + + } ); + + return isSame; + + }); + + return isSame ? result : null; + + }; + + /** + * 根据当前选区获取相关的table信息 + * @return {Object} + */ + UETable.getTableItemsByRange = function (editor) { + var start = editor.selection.getStart(); + + //ff下会选中bookmark + if( start && start.id && start.id.indexOf('_baidu_bookmark_start_') === 0 && start.nextSibling) { + start = start.nextSibling; + } + + //在table或者td边缘有可能存在选中tr的情况 + var cell = start && domUtils.findParentByTagName(start, ["td", "th"], true), + tr = cell && cell.parentNode, + caption = start && domUtils.findParentByTagName(start, 'caption', true), + table = caption ? caption.parentNode : tr && tr.parentNode.parentNode; + + return { + cell:cell, + tr:tr, + table:table, + caption:caption + } + }; + UETable.getUETableBySelected = function (editor) { + var table = UETable.getTableItemsByRange(editor).table; + if (table && table.ueTable && table.ueTable.selectedTds.length) { + return table.ueTable; + } + return null; + }; + + UETable.getDefaultValue = function (editor, table) { + var borderMap = { + thin:'0px', + medium:'1px', + thick:'2px' + }, + tableBorder, tdPadding, tdBorder, tmpValue; + if (!table) { + table = editor.document.createElement('table'); + table.insertRow(0).insertCell(0).innerHTML = 'xxx'; + editor.body.appendChild(table); + var td = table.getElementsByTagName('td')[0]; + tmpValue = domUtils.getComputedStyle(table, 'border-left-width'); + tableBorder = parseInt(borderMap[tmpValue] || tmpValue, 10); + tmpValue = domUtils.getComputedStyle(td, 'padding-left'); + tdPadding = parseInt(borderMap[tmpValue] || tmpValue, 10); + tmpValue = domUtils.getComputedStyle(td, 'border-left-width'); + tdBorder = parseInt(borderMap[tmpValue] || tmpValue, 10); + domUtils.remove(table); + return { + tableBorder:tableBorder, + tdPadding:tdPadding, + tdBorder:tdBorder + }; + } else { + td = table.getElementsByTagName('td')[0]; + tmpValue = domUtils.getComputedStyle(table, 'border-left-width'); + tableBorder = parseInt(borderMap[tmpValue] || tmpValue, 10); + tmpValue = domUtils.getComputedStyle(td, 'padding-left'); + tdPadding = parseInt(borderMap[tmpValue] || tmpValue, 10); + tmpValue = domUtils.getComputedStyle(td, 'border-left-width'); + tdBorder = parseInt(borderMap[tmpValue] || tmpValue, 10); + return { + tableBorder:tableBorder, + tdPadding:tdPadding, + tdBorder:tdBorder + }; + } + }; + /** + * 根据当前点击的td或者table获取索引对象 + * @param tdOrTable + */ + UETable.getUETable = function (tdOrTable) { + var tag = tdOrTable.tagName.toLowerCase(); + tdOrTable = (tag == "td" || tag == "th" || tag == 'caption') ? domUtils.findParentByTagName(tdOrTable, "table", true) : tdOrTable; + if (!tdOrTable.ueTable) { + tdOrTable.ueTable = new UETable(tdOrTable); + } + return tdOrTable.ueTable; + }; + + UETable.cloneCell = function(cell,ignoreMerge,keepPro){ + if (!cell || utils.isString(cell)) { + return this.table.ownerDocument.createElement(cell || 'td'); + } + var flag = domUtils.hasClass(cell, "selectTdClass"); + flag && domUtils.removeClasses(cell, "selectTdClass"); + var tmpCell = cell.cloneNode(true); + if (ignoreMerge) { + tmpCell.rowSpan = tmpCell.colSpan = 1; + } + //去掉宽高 + !keepPro && domUtils.removeAttributes(tmpCell,'width height'); + !keepPro && domUtils.removeAttributes(tmpCell,'style'); + + tmpCell.style.borderLeftStyle = ""; + tmpCell.style.borderTopStyle = ""; + tmpCell.style.borderLeftColor = cell.style.borderRightColor; + tmpCell.style.borderLeftWidth = cell.style.borderRightWidth; + tmpCell.style.borderTopColor = cell.style.borderBottomColor; + tmpCell.style.borderTopWidth = cell.style.borderBottomWidth; + flag && domUtils.addClass(cell, "selectTdClass"); + return tmpCell; + } + + UETable.prototype = { + getMaxRows:function () { + var rows = this.table.rows, maxLen = 1; + for (var i = 0, row; row = rows[i]; i++) { + var currentMax = 1; + for (var j = 0, cj; cj = row.cells[j++];) { + currentMax = Math.max(cj.rowSpan || 1, currentMax); + } + maxLen = Math.max(currentMax + i, maxLen); + } + return maxLen; + }, + /** + * 获取当前表格的最大列数 + */ + getMaxCols:function () { + var rows = this.table.rows, maxLen = 0, cellRows = {}; + for (var i = 0, row; row = rows[i]; i++) { + var cellsNum = 0; + for (var j = 0, cj; cj = row.cells[j++];) { + cellsNum += (cj.colSpan || 1); + if (cj.rowSpan && cj.rowSpan > 1) { + for (var k = 1; k < cj.rowSpan; k++) { + if (!cellRows['row_' + (i + k)]) { + cellRows['row_' + (i + k)] = (cj.colSpan || 1); + } else { + cellRows['row_' + (i + k)]++ + } + } + + } + } + cellsNum += cellRows['row_' + i] || 0; + maxLen = Math.max(cellsNum, maxLen); + } + return maxLen; + }, + getCellColIndex:function (cell) { + + }, + /** + * 获取当前cell旁边的单元格, + * @param cell + * @param right + */ + getHSideCell:function (cell, right) { + try { + var cellInfo = this.getCellInfo(cell), + previewRowIndex, previewColIndex; + var len = this.selectedTds.length, + range = this.cellsRange; + //首行或者首列没有前置单元格 + if ((!right && (!len ? !cellInfo.colIndex : !range.beginColIndex)) || (right && (!len ? (cellInfo.colIndex == (this.colsNum - 1)) : (range.endColIndex == this.colsNum - 1)))) return null; + + previewRowIndex = !len ? cellInfo.rowIndex : range.beginRowIndex; + previewColIndex = !right ? ( !len ? (cellInfo.colIndex < 1 ? 0 : (cellInfo.colIndex - 1)) : range.beginColIndex - 1) + : ( !len ? cellInfo.colIndex + 1 : range.endColIndex + 1); + return this.getCell(this.indexTable[previewRowIndex][previewColIndex].rowIndex, this.indexTable[previewRowIndex][previewColIndex].cellIndex); + } catch (e) { + showError(e); + } + }, + getTabNextCell:function (cell, preRowIndex) { + var cellInfo = this.getCellInfo(cell), + rowIndex = preRowIndex || cellInfo.rowIndex, + colIndex = cellInfo.colIndex + 1 + (cellInfo.colSpan - 1), + nextCell; + try { + nextCell = this.getCell(this.indexTable[rowIndex][colIndex].rowIndex, this.indexTable[rowIndex][colIndex].cellIndex); + } catch (e) { + try { + rowIndex = rowIndex * 1 + 1; + colIndex = 0; + nextCell = this.getCell(this.indexTable[rowIndex][colIndex].rowIndex, this.indexTable[rowIndex][colIndex].cellIndex); + } catch (e) { + } + } + return nextCell; + + }, + /** + * 获取视觉上的后置单元格 + * @param cell + * @param bottom + */ + getVSideCell:function (cell, bottom, ignoreRange) { + try { + var cellInfo = this.getCellInfo(cell), + nextRowIndex, nextColIndex; + var len = this.selectedTds.length && !ignoreRange, + range = this.cellsRange; + //末行或者末列没有后置单元格 + if ((!bottom && (cellInfo.rowIndex == 0)) || (bottom && (!len ? (cellInfo.rowIndex + cellInfo.rowSpan > this.rowsNum - 1) : (range.endRowIndex == this.rowsNum - 1)))) return null; + + nextRowIndex = !bottom ? ( !len ? cellInfo.rowIndex - 1 : range.beginRowIndex - 1) + : ( !len ? (cellInfo.rowIndex + cellInfo.rowSpan) : range.endRowIndex + 1); + nextColIndex = !len ? cellInfo.colIndex : range.beginColIndex; + return this.getCell(this.indexTable[nextRowIndex][nextColIndex].rowIndex, this.indexTable[nextRowIndex][nextColIndex].cellIndex); + } catch (e) { + showError(e); + } + }, + /** + * 获取相同结束位置的单元格,xOrY指代了是获取x轴相同还是y轴相同 + */ + getSameEndPosCells:function (cell, xOrY) { + try { + var flag = (xOrY.toLowerCase() === "x"), + end = domUtils.getXY(cell)[flag ? 'x' : 'y'] + cell["offset" + (flag ? 'Width' : 'Height')], + rows = this.table.rows, + cells = null, returns = []; + for (var i = 0; i < this.rowsNum; i++) { + cells = rows[i].cells; + for (var j = 0, tmpCell; tmpCell = cells[j++];) { + var tmpEnd = domUtils.getXY(tmpCell)[flag ? 'x' : 'y'] + tmpCell["offset" + (flag ? 'Width' : 'Height')]; + //对应行的td已经被上面行rowSpan了 + if (tmpEnd > end && flag) break; + if (cell == tmpCell || end == tmpEnd) { + //只获取单一的单元格 + //todo 仅获取单一单元格在特定情况下会造成returns为空,从而影响后续的拖拽实现,修正这个。需考虑性能 + if (tmpCell[flag ? "colSpan" : "rowSpan"] == 1) { + returns.push(tmpCell); + } + if (flag) break; + } + } + } + return returns; + } catch (e) { + showError(e); + } + }, + setCellContent:function (cell, content) { + cell.innerHTML = content || (browser.ie ? domUtils.fillChar : "
      "); + }, + cloneCell:UETable.cloneCell, + /** + * 获取跟当前单元格的右边竖线为左边的所有未合并单元格 + */ + getSameStartPosXCells:function (cell) { + try { + var start = domUtils.getXY(cell).x + cell.offsetWidth, + rows = this.table.rows, cells , returns = []; + for (var i = 0; i < this.rowsNum; i++) { + cells = rows[i].cells; + for (var j = 0, tmpCell; tmpCell = cells[j++];) { + var tmpStart = domUtils.getXY(tmpCell).x; + if (tmpStart > start) break; + if (tmpStart == start && tmpCell.colSpan == 1) { + returns.push(tmpCell); + break; + } + } + } + return returns; + } catch (e) { + showError(e); + } + }, + /** + * 更新table对应的索引表 + */ + update:function (table) { + this.table = table || this.table; + this.selectedTds = []; + this.cellsRange = {}; + this.indexTable = []; + var rows = this.table.rows, + rowsNum = this.getMaxRows(), + dNum = rowsNum - rows.length, + colsNum = this.getMaxCols(); + while (dNum--) { + this.table.insertRow(rows.length); + } + this.rowsNum = rowsNum; + this.colsNum = colsNum; + for (var i = 0, len = rows.length; i < len; i++) { + this.indexTable[i] = new Array(colsNum); + } + //填充索引表 + for (var rowIndex = 0, row; row = rows[rowIndex]; rowIndex++) { + for (var cellIndex = 0, cell, cells = row.cells; cell = cells[cellIndex]; cellIndex++) { + //修正整行被rowSpan时导致的行数计算错误 + if (cell.rowSpan > rowsNum) { + cell.rowSpan = rowsNum; + } + var colIndex = cellIndex, + rowSpan = cell.rowSpan || 1, + colSpan = cell.colSpan || 1; + //当已经被上一行rowSpan或者被前一列colSpan了,则跳到下一个单元格进行 + while (this.indexTable[rowIndex][colIndex]) colIndex++; + for (var j = 0; j < rowSpan; j++) { + for (var k = 0; k < colSpan; k++) { + this.indexTable[rowIndex + j][colIndex + k] = { + rowIndex:rowIndex, + cellIndex:cellIndex, + colIndex:colIndex, + rowSpan:rowSpan, + colSpan:colSpan + } + } + } + } + } + //修复残缺td + for (j = 0; j < rowsNum; j++) { + for (k = 0; k < colsNum; k++) { + if (this.indexTable[j][k] === undefined) { + row = rows[j]; + cell = row.cells[row.cells.length - 1]; + cell = cell ? cell.cloneNode(true) : this.table.ownerDocument.createElement("td"); + this.setCellContent(cell); + if (cell.colSpan !== 1)cell.colSpan = 1; + if (cell.rowSpan !== 1)cell.rowSpan = 1; + row.appendChild(cell); + this.indexTable[j][k] = { + rowIndex:j, + cellIndex:cell.cellIndex, + colIndex:k, + rowSpan:1, + colSpan:1 + } + } + } + } + //当框选后删除行或者列后撤销,需要重建选区。 + var tds = domUtils.getElementsByTagName(this.table, "td"), + selectTds = []; + utils.each(tds, function (td) { + if (domUtils.hasClass(td, "selectTdClass")) { + selectTds.push(td); + } + }); + if (selectTds.length) { + var start = selectTds[0], + end = selectTds[selectTds.length - 1], + startInfo = this.getCellInfo(start), + endInfo = this.getCellInfo(end); + this.selectedTds = selectTds; + this.cellsRange = { + beginRowIndex:startInfo.rowIndex, + beginColIndex:startInfo.colIndex, + endRowIndex:endInfo.rowIndex + endInfo.rowSpan - 1, + endColIndex:endInfo.colIndex + endInfo.colSpan - 1 + }; + } + //给第一行设置firstRow的样式名称,在排序图标的样式上使用到 + if(!domUtils.hasClass(this.table.rows[0], "firstRow")) { + domUtils.addClass(this.table.rows[0], "firstRow"); + for(var i = 1; i< this.table.rows.length; i++) { + domUtils.removeClasses(this.table.rows[i], "firstRow"); + } + } + }, + /** + * 获取单元格的索引信息 + */ + getCellInfo:function (cell) { + if (!cell) return; + var cellIndex = cell.cellIndex, + rowIndex = cell.parentNode.rowIndex, + rowInfo = this.indexTable[rowIndex], + numCols = this.colsNum; + for (var colIndex = cellIndex; colIndex < numCols; colIndex++) { + var cellInfo = rowInfo[colIndex]; + if (cellInfo.rowIndex === rowIndex && cellInfo.cellIndex === cellIndex) { + return cellInfo; + } + } + }, + /** + * 根据行列号获取单元格 + */ + getCell:function (rowIndex, cellIndex) { + return rowIndex < this.rowsNum && this.table.rows[rowIndex].cells[cellIndex] || null; + }, + /** + * 删除单元格 + */ + deleteCell:function (cell, rowIndex) { + rowIndex = typeof rowIndex == 'number' ? rowIndex : cell.parentNode.rowIndex; + var row = this.table.rows[rowIndex]; + row.deleteCell(cell.cellIndex); + }, + /** + * 根据始末两个单元格获取被框选的所有单元格范围 + */ + getCellsRange:function (cellA, cellB) { + function checkRange(beginRowIndex, beginColIndex, endRowIndex, endColIndex) { + var tmpBeginRowIndex = beginRowIndex, + tmpBeginColIndex = beginColIndex, + tmpEndRowIndex = endRowIndex, + tmpEndColIndex = endColIndex, + cellInfo, colIndex, rowIndex; + // 通过indexTable检查是否存在超出TableRange上边界的情况 + if (beginRowIndex > 0) { + for (colIndex = beginColIndex; colIndex < endColIndex; colIndex++) { + cellInfo = me.indexTable[beginRowIndex][colIndex]; + rowIndex = cellInfo.rowIndex; + if (rowIndex < beginRowIndex) { + tmpBeginRowIndex = Math.min(rowIndex, tmpBeginRowIndex); + } + } + } + // 通过indexTable检查是否存在超出TableRange右边界的情况 + if (endColIndex < me.colsNum) { + for (rowIndex = beginRowIndex; rowIndex < endRowIndex; rowIndex++) { + cellInfo = me.indexTable[rowIndex][endColIndex]; + colIndex = cellInfo.colIndex + cellInfo.colSpan - 1; + if (colIndex > endColIndex) { + tmpEndColIndex = Math.max(colIndex, tmpEndColIndex); + } + } + } + // 检查是否有超出TableRange下边界的情况 + if (endRowIndex < me.rowsNum) { + for (colIndex = beginColIndex; colIndex < endColIndex; colIndex++) { + cellInfo = me.indexTable[endRowIndex][colIndex]; + rowIndex = cellInfo.rowIndex + cellInfo.rowSpan - 1; + if (rowIndex > endRowIndex) { + tmpEndRowIndex = Math.max(rowIndex, tmpEndRowIndex); + } + } + } + // 检查是否有超出TableRange左边界的情况 + if (beginColIndex > 0) { + for (rowIndex = beginRowIndex; rowIndex < endRowIndex; rowIndex++) { + cellInfo = me.indexTable[rowIndex][beginColIndex]; + colIndex = cellInfo.colIndex; + if (colIndex < beginColIndex) { + tmpBeginColIndex = Math.min(cellInfo.colIndex, tmpBeginColIndex); + } + } + } + //递归调用直至所有完成所有框选单元格的扩展 + if (tmpBeginRowIndex != beginRowIndex || tmpBeginColIndex != beginColIndex || tmpEndRowIndex != endRowIndex || tmpEndColIndex != endColIndex) { + return checkRange(tmpBeginRowIndex, tmpBeginColIndex, tmpEndRowIndex, tmpEndColIndex); + } else { + // 不需要扩展TableRange的情况 + return { + beginRowIndex:beginRowIndex, + beginColIndex:beginColIndex, + endRowIndex:endRowIndex, + endColIndex:endColIndex + }; + } + } + + try { + var me = this, + cellAInfo = me.getCellInfo(cellA); + if (cellA === cellB) { + return { + beginRowIndex:cellAInfo.rowIndex, + beginColIndex:cellAInfo.colIndex, + endRowIndex:cellAInfo.rowIndex + cellAInfo.rowSpan - 1, + endColIndex:cellAInfo.colIndex + cellAInfo.colSpan - 1 + }; + } + var cellBInfo = me.getCellInfo(cellB); + // 计算TableRange的四个边 + var beginRowIndex = Math.min(cellAInfo.rowIndex, cellBInfo.rowIndex), + beginColIndex = Math.min(cellAInfo.colIndex, cellBInfo.colIndex), + endRowIndex = Math.max(cellAInfo.rowIndex + cellAInfo.rowSpan - 1, cellBInfo.rowIndex + cellBInfo.rowSpan - 1), + endColIndex = Math.max(cellAInfo.colIndex + cellAInfo.colSpan - 1, cellBInfo.colIndex + cellBInfo.colSpan - 1); + + return checkRange(beginRowIndex, beginColIndex, endRowIndex, endColIndex); + } catch (e) { + //throw e; + } + }, + /** + * 依据cellsRange获取对应的单元格集合 + */ + getCells:function (range) { + //每次获取cells之前必须先清除上次的选择,否则会对后续获取操作造成影响 + this.clearSelected(); + var beginRowIndex = range.beginRowIndex, + beginColIndex = range.beginColIndex, + endRowIndex = range.endRowIndex, + endColIndex = range.endColIndex, + cellInfo, rowIndex, colIndex, tdHash = {}, returnTds = []; + for (var i = beginRowIndex; i <= endRowIndex; i++) { + for (var j = beginColIndex; j <= endColIndex; j++) { + cellInfo = this.indexTable[i][j]; + rowIndex = cellInfo.rowIndex; + colIndex = cellInfo.colIndex; + // 如果Cells里已经包含了此Cell则跳过 + var key = rowIndex + '|' + colIndex; + if (tdHash[key]) continue; + tdHash[key] = 1; + if (rowIndex < i || colIndex < j || rowIndex + cellInfo.rowSpan - 1 > endRowIndex || colIndex + cellInfo.colSpan - 1 > endColIndex) { + return null; + } + returnTds.push(this.getCell(rowIndex, cellInfo.cellIndex)); + } + } + return returnTds; + }, + /** + * 清理已经选中的单元格 + */ + clearSelected:function () { + UETable.removeSelectedClass(this.selectedTds); + this.selectedTds = []; + this.cellsRange = {}; + }, + /** + * 根据range设置已经选中的单元格 + */ + setSelected:function (range) { + var cells = this.getCells(range); + UETable.addSelectedClass(cells); + this.selectedTds = cells; + this.cellsRange = range; + }, + isFullRow:function () { + var range = this.cellsRange; + return (range.endColIndex - range.beginColIndex + 1) == this.colsNum; + }, + isFullCol:function () { + var range = this.cellsRange, + table = this.table, + ths = table.getElementsByTagName("th"), + rows = range.endRowIndex - range.beginRowIndex + 1; + return !ths.length ? rows == this.rowsNum : rows == this.rowsNum || (rows == this.rowsNum - 1); + + }, + /** + * 获取视觉上的前置单元格,默认是左边,top传入时 + * @param cell + * @param top + */ + getNextCell:function (cell, bottom, ignoreRange) { + try { + var cellInfo = this.getCellInfo(cell), + nextRowIndex, nextColIndex; + var len = this.selectedTds.length && !ignoreRange, + range = this.cellsRange; + //末行或者末列没有后置单元格 + if ((!bottom && (cellInfo.rowIndex == 0)) || (bottom && (!len ? (cellInfo.rowIndex + cellInfo.rowSpan > this.rowsNum - 1) : (range.endRowIndex == this.rowsNum - 1)))) return null; + + nextRowIndex = !bottom ? ( !len ? cellInfo.rowIndex - 1 : range.beginRowIndex - 1) + : ( !len ? (cellInfo.rowIndex + cellInfo.rowSpan) : range.endRowIndex + 1); + nextColIndex = !len ? cellInfo.colIndex : range.beginColIndex; + return this.getCell(this.indexTable[nextRowIndex][nextColIndex].rowIndex, this.indexTable[nextRowIndex][nextColIndex].cellIndex); + } catch (e) { + showError(e); + } + }, + getPreviewCell:function (cell, top) { + try { + var cellInfo = this.getCellInfo(cell), + previewRowIndex, previewColIndex; + var len = this.selectedTds.length, + range = this.cellsRange; + //首行或者首列没有前置单元格 + if ((!top && (!len ? !cellInfo.colIndex : !range.beginColIndex)) || (top && (!len ? (cellInfo.rowIndex > (this.colsNum - 1)) : (range.endColIndex == this.colsNum - 1)))) return null; + + previewRowIndex = !top ? ( !len ? cellInfo.rowIndex : range.beginRowIndex ) + : ( !len ? (cellInfo.rowIndex < 1 ? 0 : (cellInfo.rowIndex - 1)) : range.beginRowIndex); + previewColIndex = !top ? ( !len ? (cellInfo.colIndex < 1 ? 0 : (cellInfo.colIndex - 1)) : range.beginColIndex - 1) + : ( !len ? cellInfo.colIndex : range.endColIndex + 1); + return this.getCell(this.indexTable[previewRowIndex][previewColIndex].rowIndex, this.indexTable[previewRowIndex][previewColIndex].cellIndex); + } catch (e) { + showError(e); + } + }, + /** + * 移动单元格中的内容 + */ + moveContent:function (cellTo, cellFrom) { + if (UETable.isEmptyBlock(cellFrom)) return; + if (UETable.isEmptyBlock(cellTo)) { + cellTo.innerHTML = cellFrom.innerHTML; + return; + } + var child = cellTo.lastChild; + if (child.nodeType == 3 || !dtd.$block[child.tagName]) { + cellTo.appendChild(cellTo.ownerDocument.createElement('br')) + } + while (child = cellFrom.firstChild) { + cellTo.appendChild(child); + } + }, + /** + * 向右合并单元格 + */ + mergeRight:function (cell) { + var cellInfo = this.getCellInfo(cell), + rightColIndex = cellInfo.colIndex + cellInfo.colSpan, + rightCellInfo = this.indexTable[cellInfo.rowIndex][rightColIndex], + rightCell = this.getCell(rightCellInfo.rowIndex, rightCellInfo.cellIndex); + //合并 + cell.colSpan = cellInfo.colSpan + rightCellInfo.colSpan; + //被合并的单元格不应存在宽度属性 + cell.removeAttribute("width"); + //移动内容 + this.moveContent(cell, rightCell); + //删掉被合并的Cell + this.deleteCell(rightCell, rightCellInfo.rowIndex); + this.update(); + }, + /** + * 向下合并单元格 + */ + mergeDown:function (cell) { + var cellInfo = this.getCellInfo(cell), + downRowIndex = cellInfo.rowIndex + cellInfo.rowSpan, + downCellInfo = this.indexTable[downRowIndex][cellInfo.colIndex], + downCell = this.getCell(downCellInfo.rowIndex, downCellInfo.cellIndex); + cell.rowSpan = cellInfo.rowSpan + downCellInfo.rowSpan; + cell.removeAttribute("height"); + this.moveContent(cell, downCell); + this.deleteCell(downCell, downCellInfo.rowIndex); + this.update(); + }, + /** + * 合并整个range中的内容 + */ + mergeRange:function () { + //由于合并操作可以在任意时刻进行,所以无法通过鼠标位置等信息实时生成range,只能通过缓存实例中的cellsRange对象来访问 + var range = this.cellsRange, + leftTopCell = this.getCell(range.beginRowIndex, this.indexTable[range.beginRowIndex][range.beginColIndex].cellIndex); + + if (leftTopCell.tagName == "TH" && range.endRowIndex !== range.beginRowIndex) { + var index = this.indexTable, + info = this.getCellInfo(leftTopCell); + leftTopCell = this.getCell(1, index[1][info.colIndex].cellIndex); + range = this.getCellsRange(leftTopCell, this.getCell(index[this.rowsNum - 1][info.colIndex].rowIndex, index[this.rowsNum - 1][info.colIndex].cellIndex)); + } + + // 删除剩余的Cells + var cells = this.getCells(range); + for(var i= 0,ci;ci=cells[i++];){ + if (ci !== leftTopCell) { + this.moveContent(leftTopCell, ci); + this.deleteCell(ci); + } + } + // 修改左上角Cell的rowSpan和colSpan,并调整宽度属性设置 + leftTopCell.rowSpan = range.endRowIndex - range.beginRowIndex + 1; + leftTopCell.rowSpan > 1 && leftTopCell.removeAttribute("height"); + leftTopCell.colSpan = range.endColIndex - range.beginColIndex + 1; + leftTopCell.colSpan > 1 && leftTopCell.removeAttribute("width"); + if (leftTopCell.rowSpan == this.rowsNum && leftTopCell.colSpan != 1) { + leftTopCell.colSpan = 1; + } + + if (leftTopCell.colSpan == this.colsNum && leftTopCell.rowSpan != 1) { + var rowIndex = leftTopCell.parentNode.rowIndex; + //解决IE下的表格操作问题 + if( this.table.deleteRow ) { + for (var i = rowIndex+ 1, curIndex=rowIndex+ 1, len=leftTopCell.rowSpan; i < len; i++) { + this.table.deleteRow(curIndex); + } + } else { + for (var i = 0, len=leftTopCell.rowSpan - 1; i < len; i++) { + var row = this.table.rows[rowIndex + 1]; + row.parentNode.removeChild(row); + } + } + leftTopCell.rowSpan = 1; + } + this.update(); + }, + /** + * 插入一行单元格 + */ + insertRow:function (rowIndex, sourceCell) { + var numCols = this.colsNum, + table = this.table, + row = table.insertRow(rowIndex), cell, + isInsertTitle = typeof sourceCell == 'string' && sourceCell.toUpperCase() == 'TH'; + + function replaceTdToTh(colIndex, cell, tableRow) { + if (colIndex == 0) { + var tr = tableRow.nextSibling || tableRow.previousSibling, + th = tr.cells[colIndex]; + if (th.tagName == 'TH') { + th = cell.ownerDocument.createElement("th"); + th.appendChild(cell.firstChild); + tableRow.insertBefore(th, cell); + domUtils.remove(cell) + } + }else{ + if (cell.tagName == 'TH') { + var td = cell.ownerDocument.createElement("td"); + td.appendChild(cell.firstChild); + tableRow.insertBefore(td, cell); + domUtils.remove(cell) + } + } + } + + //首行直接插入,无需考虑部分单元格被rowspan的情况 + if (rowIndex == 0 || rowIndex == this.rowsNum) { + for (var colIndex = 0; colIndex < numCols; colIndex++) { + cell = this.cloneCell(sourceCell, true); + this.setCellContent(cell); + cell.getAttribute('vAlign') && cell.setAttribute('vAlign', cell.getAttribute('vAlign')); + row.appendChild(cell); + if(!isInsertTitle) replaceTdToTh(colIndex, cell, row); + } + } else { + var infoRow = this.indexTable[rowIndex], + cellIndex = 0; + for (colIndex = 0; colIndex < numCols; colIndex++) { + var cellInfo = infoRow[colIndex]; + //如果存在某个单元格的rowspan穿过待插入行的位置,则修改该单元格的rowspan即可,无需插入单元格 + if (cellInfo.rowIndex < rowIndex) { + cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex); + cell.rowSpan = cellInfo.rowSpan + 1; + } else { + cell = this.cloneCell(sourceCell, true); + this.setCellContent(cell); + row.appendChild(cell); + } + if(!isInsertTitle) replaceTdToTh(colIndex, cell, row); + } + } + //框选时插入不触发contentchange,需要手动更新索引。 + this.update(); + return row; + }, + /** + * 删除一行单元格 + * @param rowIndex + */ + deleteRow:function (rowIndex) { + var row = this.table.rows[rowIndex], + infoRow = this.indexTable[rowIndex], + colsNum = this.colsNum, + count = 0; //处理计数 + for (var colIndex = 0; colIndex < colsNum;) { + var cellInfo = infoRow[colIndex], + cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex); + if (cell.rowSpan > 1) { + if (cellInfo.rowIndex == rowIndex) { + var clone = cell.cloneNode(true); + clone.rowSpan = cell.rowSpan - 1; + clone.innerHTML = ""; + cell.rowSpan = 1; + var nextRowIndex = rowIndex + 1, + nextRow = this.table.rows[nextRowIndex], + insertCellIndex, + preMerged = this.getPreviewMergedCellsNum(nextRowIndex, colIndex) - count; + if (preMerged < colIndex) { + insertCellIndex = colIndex - preMerged - 1; + //nextRow.insertCell(insertCellIndex); + domUtils.insertAfter(nextRow.cells[insertCellIndex], clone); + } else { + if (nextRow.cells.length) nextRow.insertBefore(clone, nextRow.cells[0]) + } + count += 1; + //cell.parentNode.removeChild(cell); + } + } + colIndex += cell.colSpan || 1; + } + var deleteTds = [], cacheMap = {}; + for (colIndex = 0; colIndex < colsNum; colIndex++) { + var tmpRowIndex = infoRow[colIndex].rowIndex, + tmpCellIndex = infoRow[colIndex].cellIndex, + key = tmpRowIndex + "_" + tmpCellIndex; + if (cacheMap[key])continue; + cacheMap[key] = 1; + cell = this.getCell(tmpRowIndex, tmpCellIndex); + deleteTds.push(cell); + } + var mergeTds = []; + utils.each(deleteTds, function (td) { + if (td.rowSpan == 1) { + td.parentNode.removeChild(td); + } else { + mergeTds.push(td); + } + }); + utils.each(mergeTds, function (td) { + td.rowSpan--; + }); + row.parentNode.removeChild(row); + //浏览器方法本身存在bug,采用自定义方法删除 + //this.table.deleteRow(rowIndex); + this.update(); + }, + insertCol:function (colIndex, sourceCell, defaultValue) { + var rowsNum = this.rowsNum, + rowIndex = 0, + tableRow, cell, + backWidth = parseInt((this.table.offsetWidth - (this.colsNum + 1) * 20 - (this.colsNum + 1)) / (this.colsNum + 1), 10), + isInsertTitleCol = typeof sourceCell == 'string' && sourceCell.toUpperCase() == 'TH'; + + function replaceTdToTh(rowIndex, cell, tableRow) { + if (rowIndex == 0) { + var th = cell.nextSibling || cell.previousSibling; + if (th.tagName == 'TH') { + th = cell.ownerDocument.createElement("th"); + th.appendChild(cell.firstChild); + tableRow.insertBefore(th, cell); + domUtils.remove(cell) + } + }else{ + if (cell.tagName == 'TH') { + var td = cell.ownerDocument.createElement("td"); + td.appendChild(cell.firstChild); + tableRow.insertBefore(td, cell); + domUtils.remove(cell) + } + } + } + + var preCell; + if (colIndex == 0 || colIndex == this.colsNum) { + for (; rowIndex < rowsNum; rowIndex++) { + tableRow = this.table.rows[rowIndex]; + preCell = tableRow.cells[colIndex == 0 ? colIndex : tableRow.cells.length]; + cell = this.cloneCell(sourceCell, true); //tableRow.insertCell(colIndex == 0 ? colIndex : tableRow.cells.length); + this.setCellContent(cell); + cell.setAttribute('vAlign', cell.getAttribute('vAlign')); + preCell && cell.setAttribute('width', preCell.getAttribute('width')); + if (!colIndex) { + tableRow.insertBefore(cell, tableRow.cells[0]); + } else { + domUtils.insertAfter(tableRow.cells[tableRow.cells.length - 1], cell); + } + if(!isInsertTitleCol) replaceTdToTh(rowIndex, cell, tableRow) + } + } else { + for (; rowIndex < rowsNum; rowIndex++) { + var cellInfo = this.indexTable[rowIndex][colIndex]; + if (cellInfo.colIndex < colIndex) { + cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex); + cell.colSpan = cellInfo.colSpan + 1; + } else { + tableRow = this.table.rows[rowIndex]; + preCell = tableRow.cells[cellInfo.cellIndex]; + + cell = this.cloneCell(sourceCell, true);//tableRow.insertCell(cellInfo.cellIndex); + this.setCellContent(cell); + cell.setAttribute('vAlign', cell.getAttribute('vAlign')); + preCell && cell.setAttribute('width', preCell.getAttribute('width')); + //防止IE下报错 + preCell ? tableRow.insertBefore(cell, preCell) : tableRow.appendChild(cell); + } + if(!isInsertTitleCol) replaceTdToTh(rowIndex, cell, tableRow); + } + } + //框选时插入不触发contentchange,需要手动更新索引 + this.update(); + this.updateWidth(backWidth, defaultValue || {tdPadding:10, tdBorder:1}); + }, + updateWidth:function (width, defaultValue) { + var table = this.table, + tmpWidth = UETable.getWidth(table) - defaultValue.tdPadding * 2 - defaultValue.tdBorder + width; + if (tmpWidth < table.ownerDocument.body.offsetWidth) { + table.setAttribute("width", tmpWidth); + return; + } + var tds = domUtils.getElementsByTagName(this.table, "td th"); + utils.each(tds, function (td) { + td.setAttribute("width", width); + }) + }, + deleteCol:function (colIndex) { + var indexTable = this.indexTable, + tableRows = this.table.rows, + backTableWidth = this.table.getAttribute("width"), + backTdWidth = 0, + rowsNum = this.rowsNum, + cacheMap = {}; + for (var rowIndex = 0; rowIndex < rowsNum;) { + var infoRow = indexTable[rowIndex], + cellInfo = infoRow[colIndex], + key = cellInfo.rowIndex + '_' + cellInfo.colIndex; + // 跳过已经处理过的Cell + if (cacheMap[key])continue; + cacheMap[key] = 1; + var cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex); + if (!backTdWidth) backTdWidth = cell && parseInt(cell.offsetWidth / cell.colSpan, 10).toFixed(0); + // 如果Cell的colSpan大于1, 就修改colSpan, 否则就删掉这个Cell + if (cell.colSpan > 1) { + cell.colSpan--; + } else { + tableRows[rowIndex].deleteCell(cellInfo.cellIndex); + } + rowIndex += cellInfo.rowSpan || 1; + } + this.table.setAttribute("width", backTableWidth - backTdWidth); + this.update(); + }, + splitToCells:function (cell) { + var me = this, + cells = this.splitToRows(cell); + utils.each(cells, function (cell) { + me.splitToCols(cell); + }) + }, + splitToRows:function (cell) { + var cellInfo = this.getCellInfo(cell), + rowIndex = cellInfo.rowIndex, + colIndex = cellInfo.colIndex, + results = []; + // 修改Cell的rowSpan + cell.rowSpan = 1; + results.push(cell); + // 补齐单元格 + for (var i = rowIndex, endRow = rowIndex + cellInfo.rowSpan; i < endRow; i++) { + if (i == rowIndex)continue; + var tableRow = this.table.rows[i], + tmpCell = tableRow.insertCell(colIndex - this.getPreviewMergedCellsNum(i, colIndex)); + tmpCell.colSpan = cellInfo.colSpan; + this.setCellContent(tmpCell); + tmpCell.setAttribute('vAlign', cell.getAttribute('vAlign')); + tmpCell.setAttribute('align', cell.getAttribute('align')); + if (cell.style.cssText) { + tmpCell.style.cssText = cell.style.cssText; + } + results.push(tmpCell); + } + this.update(); + return results; + }, + getPreviewMergedCellsNum:function (rowIndex, colIndex) { + var indexRow = this.indexTable[rowIndex], + num = 0; + for (var i = 0; i < colIndex;) { + var colSpan = indexRow[i].colSpan, + tmpRowIndex = indexRow[i].rowIndex; + num += (colSpan - (tmpRowIndex == rowIndex ? 1 : 0)); + i += colSpan; + } + return num; + }, + splitToCols:function (cell) { + var backWidth = (cell.offsetWidth / cell.colSpan - 22).toFixed(0), + + cellInfo = this.getCellInfo(cell), + rowIndex = cellInfo.rowIndex, + colIndex = cellInfo.colIndex, + results = []; + // 修改Cell的rowSpan + cell.colSpan = 1; + cell.setAttribute("width", backWidth); + results.push(cell); + // 补齐单元格 + for (var j = colIndex, endCol = colIndex + cellInfo.colSpan; j < endCol; j++) { + if (j == colIndex)continue; + var tableRow = this.table.rows[rowIndex], + tmpCell = tableRow.insertCell(this.indexTable[rowIndex][j].cellIndex + 1); + tmpCell.rowSpan = cellInfo.rowSpan; + this.setCellContent(tmpCell); + tmpCell.setAttribute('vAlign', cell.getAttribute('vAlign')); + tmpCell.setAttribute('align', cell.getAttribute('align')); + tmpCell.setAttribute('width', backWidth); + if (cell.style.cssText) { + tmpCell.style.cssText = cell.style.cssText; + } + //处理th的情况 + if (cell.tagName == 'TH') { + var th = cell.ownerDocument.createElement('th'); + th.appendChild(tmpCell.firstChild); + th.setAttribute('vAlign', cell.getAttribute('vAlign')); + th.rowSpan = tmpCell.rowSpan; + tableRow.insertBefore(th, tmpCell); + domUtils.remove(tmpCell); + } + results.push(tmpCell); + } + this.update(); + return results; + }, + isLastCell:function (cell, rowsNum, colsNum) { + rowsNum = rowsNum || this.rowsNum; + colsNum = colsNum || this.colsNum; + var cellInfo = this.getCellInfo(cell); + return ((cellInfo.rowIndex + cellInfo.rowSpan) == rowsNum) && + ((cellInfo.colIndex + cellInfo.colSpan) == colsNum); + }, + getLastCell:function (cells) { + cells = cells || this.table.getElementsByTagName("td"); + var firstInfo = this.getCellInfo(cells[0]); + var me = this, last = cells[0], + tr = last.parentNode, + cellsNum = 0, cols = 0, rows; + utils.each(cells, function (cell) { + if (cell.parentNode == tr)cols += cell.colSpan || 1; + cellsNum += cell.rowSpan * cell.colSpan || 1; + }); + rows = cellsNum / cols; + utils.each(cells, function (cell) { + if (me.isLastCell(cell, rows, cols)) { + last = cell; + return false; + } + }); + return last; + + }, + selectRow:function (rowIndex) { + var indexRow = this.indexTable[rowIndex], + start = this.getCell(indexRow[0].rowIndex, indexRow[0].cellIndex), + end = this.getCell(indexRow[this.colsNum - 1].rowIndex, indexRow[this.colsNum - 1].cellIndex), + range = this.getCellsRange(start, end); + this.setSelected(range); + }, + selectTable:function () { + var tds = this.table.getElementsByTagName("td"), + range = this.getCellsRange(tds[0], tds[tds.length - 1]); + this.setSelected(range); + }, + setBackground:function (cells, value) { + if (typeof value === "string") { + utils.each(cells, function (cell) { + cell.style.backgroundColor = value; + }) + } else if (typeof value === "object") { + value = utils.extend({ + repeat:true, + colorList:["#ddd", "#fff"] + }, value); + var rowIndex = this.getCellInfo(cells[0]).rowIndex, + count = 0, + colors = value.colorList, + getColor = function (list, index, repeat) { + return list[index] ? list[index] : repeat ? list[index % list.length] : ""; + }; + for (var i = 0, cell; cell = cells[i++];) { + var cellInfo = this.getCellInfo(cell); + cell.style.backgroundColor = getColor(colors, ((rowIndex + count) == cellInfo.rowIndex) ? count : ++count, value.repeat); + } + } + }, + removeBackground:function (cells) { + utils.each(cells, function (cell) { + cell.style.backgroundColor = ""; + }) + } + + + }; + function showError(e) { + } +})(); + +// plugins/table.cmds.js +/** + * Created with JetBrains PhpStorm. + * User: taoqili + * Date: 13-2-20 + * Time: 下午6:25 + * To change this template use File | Settings | File Templates. + */ +; +(function () { + var UT = UE.UETable, + getTableItemsByRange = function (editor) { + return UT.getTableItemsByRange(editor); + }, + getUETableBySelected = function (editor) { + return UT.getUETableBySelected(editor) + }, + getDefaultValue = function (editor, table) { + return UT.getDefaultValue(editor, table); + }, + getUETable = function (tdOrTable) { + return UT.getUETable(tdOrTable); + }; + + + UE.commands['inserttable'] = { + queryCommandState: function () { + return getTableItemsByRange(this).table ? -1 : 0; + }, + execCommand: function (cmd, opt) { + function createTable(opt, tdWidth) { + var html = [], + rowsNum = opt.numRows, + colsNum = opt.numCols; + for (var r = 0; r < rowsNum; r++) { + html.push(''); + for (var c = 0; c < colsNum; c++) { + html.push('
    • ' + (browser.ie && browser.version < 11 ? domUtils.fillChar : '
      ') + '
      ' + html.join('') + '
      ' + } + + if (!opt) { + opt = utils.extend({}, { + numCols: this.options.defaultCols, + numRows: this.options.defaultRows, + tdvalign: this.options.tdvalign + }) + } + var me = this; + var range = this.selection.getRange(), + start = range.startContainer, + firstParentBlock = domUtils.findParent(start, function (node) { + return domUtils.isBlockElm(node); + }, true) || me.body; + + var defaultValue = getDefaultValue(me), + tableWidth = firstParentBlock.offsetWidth, + tdWidth = Math.floor(tableWidth / opt.numCols - defaultValue.tdPadding * 2 - defaultValue.tdBorder); + + //todo其他属性 + !opt.tdvalign && (opt.tdvalign = me.options.tdvalign); + me.execCommand("inserthtml", createTable(opt, tdWidth)); + } + }; + + UE.commands['insertparagraphbeforetable'] = { + queryCommandState: function () { + return getTableItemsByRange(this).cell ? 0 : -1; + }, + execCommand: function () { + var table = getTableItemsByRange(this).table; + if (table) { + var p = this.document.createElement("p"); + p.innerHTML = browser.ie ? ' ' : '
      '; + table.parentNode.insertBefore(p, table); + this.selection.getRange().setStart(p, 0).setCursor(); + } + } + }; + + UE.commands['deletetable'] = { + queryCommandState: function () { + var rng = this.selection.getRange(); + return domUtils.findParentByTagName(rng.startContainer, 'table', true) ? 0 : -1; + }, + execCommand: function (cmd, table) { + var rng = this.selection.getRange(); + table = table || domUtils.findParentByTagName(rng.startContainer, 'table', true); + if (table) { + var next = table.nextSibling; + if (!next) { + next = domUtils.createElement(this.document, 'p', { + 'innerHTML': browser.ie ? domUtils.fillChar : '
      ' + }); + table.parentNode.insertBefore(next, table); + } + domUtils.remove(table); + rng = this.selection.getRange(); + if (next.nodeType == 3) { + rng.setStartBefore(next) + } else { + rng.setStart(next, 0) + } + rng.setCursor(false, true) + this.fireEvent("tablehasdeleted") + + } + + } + }; + UE.commands['cellalign'] = { + queryCommandState: function () { + return getSelectedArr(this).length ? 0 : -1 + }, + execCommand: function (cmd, align) { + var selectedTds = getSelectedArr(this); + if (selectedTds.length) { + for (var i = 0, ci; ci = selectedTds[i++];) { + ci.setAttribute('align', align); + } + } + } + }; + UE.commands['cellvalign'] = { + queryCommandState: function () { + return getSelectedArr(this).length ? 0 : -1; + }, + execCommand: function (cmd, valign) { + var selectedTds = getSelectedArr(this); + if (selectedTds.length) { + for (var i = 0, ci; ci = selectedTds[i++];) { + ci.setAttribute('vAlign', valign); + } + } + } + }; + UE.commands['insertcaption'] = { + queryCommandState: function () { + var table = getTableItemsByRange(this).table; + if (table) { + return table.getElementsByTagName('caption').length == 0 ? 1 : -1; + } + return -1; + }, + execCommand: function () { + var table = getTableItemsByRange(this).table; + if (table) { + var caption = this.document.createElement('caption'); + caption.innerHTML = browser.ie ? domUtils.fillChar : '
      '; + table.insertBefore(caption, table.firstChild); + var range = this.selection.getRange(); + range.setStart(caption, 0).setCursor(); + } + + } + }; + UE.commands['deletecaption'] = { + queryCommandState: function () { + var rng = this.selection.getRange(), + table = domUtils.findParentByTagName(rng.startContainer, 'table'); + if (table) { + return table.getElementsByTagName('caption').length == 0 ? -1 : 1; + } + return -1; + }, + execCommand: function () { + var rng = this.selection.getRange(), + table = domUtils.findParentByTagName(rng.startContainer, 'table'); + if (table) { + domUtils.remove(table.getElementsByTagName('caption')[0]); + var range = this.selection.getRange(); + range.setStart(table.rows[0].cells[0], 0).setCursor(); + } + + } + }; + UE.commands['inserttitle'] = { + queryCommandState: function () { + var table = getTableItemsByRange(this).table; + if (table) { + var firstRow = table.rows[0]; + return firstRow.cells[firstRow.cells.length-1].tagName.toLowerCase() != 'th' ? 0 : -1 + } + return -1; + }, + execCommand: function () { + var table = getTableItemsByRange(this).table; + if (table) { + getUETable(table).insertRow(0, 'th'); + } + var th = table.getElementsByTagName('th')[0]; + this.selection.getRange().setStart(th, 0).setCursor(false, true); + } + }; + UE.commands['deletetitle'] = { + queryCommandState: function () { + var table = getTableItemsByRange(this).table; + if (table) { + var firstRow = table.rows[0]; + return firstRow.cells[firstRow.cells.length-1].tagName.toLowerCase() == 'th' ? 0 : -1 + } + return -1; + }, + execCommand: function () { + var table = getTableItemsByRange(this).table; + if (table) { + domUtils.remove(table.rows[0]) + } + var td = table.getElementsByTagName('td')[0]; + this.selection.getRange().setStart(td, 0).setCursor(false, true); + } + }; + UE.commands['inserttitlecol'] = { + queryCommandState: function () { + var table = getTableItemsByRange(this).table; + if (table) { + var lastRow = table.rows[table.rows.length-1]; + return lastRow.getElementsByTagName('th').length ? -1 : 0; + } + return -1; + }, + execCommand: function (cmd) { + var table = getTableItemsByRange(this).table; + if (table) { + getUETable(table).insertCol(0, 'th'); + } + resetTdWidth(table, this); + var th = table.getElementsByTagName('th')[0]; + this.selection.getRange().setStart(th, 0).setCursor(false, true); + } + }; + UE.commands['deletetitlecol'] = { + queryCommandState: function () { + var table = getTableItemsByRange(this).table; + if (table) { + var lastRow = table.rows[table.rows.length-1]; + return lastRow.getElementsByTagName('th').length ? 0 : -1; + } + return -1; + }, + execCommand: function () { + var table = getTableItemsByRange(this).table; + if (table) { + for(var i = 0; i< table.rows.length; i++ ){ + domUtils.remove(table.rows[i].children[0]) + } + } + resetTdWidth(table, this); + var td = table.getElementsByTagName('td')[0]; + this.selection.getRange().setStart(td, 0).setCursor(false, true); + } + }; + + UE.commands["mergeright"] = { + queryCommandState: function (cmd) { + var tableItems = getTableItemsByRange(this), + table = tableItems.table, + cell = tableItems.cell; + + if (!table || !cell) return -1; + var ut = getUETable(table); + if (ut.selectedTds.length) return -1; + + var cellInfo = ut.getCellInfo(cell), + rightColIndex = cellInfo.colIndex + cellInfo.colSpan; + if (rightColIndex >= ut.colsNum) return -1; // 如果处于最右边则不能向右合并 + + var rightCellInfo = ut.indexTable[cellInfo.rowIndex][rightColIndex], + rightCell = table.rows[rightCellInfo.rowIndex].cells[rightCellInfo.cellIndex]; + if (!rightCell || cell.tagName != rightCell.tagName) return -1; // TH和TD不能相互合并 + + // 当且仅当两个Cell的开始列号和结束列号一致时能进行合并 + return (rightCellInfo.rowIndex == cellInfo.rowIndex && rightCellInfo.rowSpan == cellInfo.rowSpan) ? 0 : -1; + }, + execCommand: function (cmd) { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell); + ut.mergeRight(cell); + rng.moveToBookmark(bk).select(); + } + }; + UE.commands["mergedown"] = { + queryCommandState: function (cmd) { + var tableItems = getTableItemsByRange(this), + table = tableItems.table, + cell = tableItems.cell; + + if (!table || !cell) return -1; + var ut = getUETable(table); + if (ut.selectedTds.length)return -1; + + var cellInfo = ut.getCellInfo(cell), + downRowIndex = cellInfo.rowIndex + cellInfo.rowSpan; + if (downRowIndex >= ut.rowsNum) return -1; // 如果处于最下边则不能向下合并 + + var downCellInfo = ut.indexTable[downRowIndex][cellInfo.colIndex], + downCell = table.rows[downCellInfo.rowIndex].cells[downCellInfo.cellIndex]; + if (!downCell || cell.tagName != downCell.tagName) return -1; // TH和TD不能相互合并 + + // 当且仅当两个Cell的开始列号和结束列号一致时能进行合并 + return (downCellInfo.colIndex == cellInfo.colIndex && downCellInfo.colSpan == cellInfo.colSpan) ? 0 : -1; + }, + execCommand: function () { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell); + ut.mergeDown(cell); + rng.moveToBookmark(bk).select(); + } + }; + UE.commands["mergecells"] = { + queryCommandState: function () { + return getUETableBySelected(this) ? 0 : -1; + }, + execCommand: function () { + var ut = getUETableBySelected(this); + if (ut && ut.selectedTds.length) { + var cell = ut.selectedTds[0]; + ut.mergeRange(); + var rng = this.selection.getRange(); + if (domUtils.isEmptyBlock(cell)) { + rng.setStart(cell, 0).collapse(true) + } else { + rng.selectNodeContents(cell) + } + rng.select(); + } + + + } + }; + UE.commands["insertrow"] = { + queryCommandState: function () { + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell; + return cell && (cell.tagName == "TD" || (cell.tagName == 'TH' && tableItems.tr !== tableItems.table.rows[0])) && + getUETable(tableItems.table).rowsNum < this.options.maxRowNum ? 0 : -1; + }, + execCommand: function () { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell, + table = tableItems.table, + ut = getUETable(table), + cellInfo = ut.getCellInfo(cell); + //ut.insertRow(!ut.selectedTds.length ? cellInfo.rowIndex:ut.cellsRange.beginRowIndex,''); + if (!ut.selectedTds.length) { + ut.insertRow(cellInfo.rowIndex, cell); + } else { + var range = ut.cellsRange; + for (var i = 0, len = range.endRowIndex - range.beginRowIndex + 1; i < len; i++) { + ut.insertRow(range.beginRowIndex, cell); + } + } + rng.moveToBookmark(bk).select(); + if (table.getAttribute("interlaced") === "enabled")this.fireEvent("interlacetable", table); + } + }; + //后插入行 + UE.commands["insertrownext"] = { + queryCommandState: function () { + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell; + return cell && (cell.tagName == "TD") && getUETable(tableItems.table).rowsNum < this.options.maxRowNum ? 0 : -1; + }, + execCommand: function () { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell, + table = tableItems.table, + ut = getUETable(table), + cellInfo = ut.getCellInfo(cell); + //ut.insertRow(!ut.selectedTds.length? cellInfo.rowIndex + cellInfo.rowSpan : ut.cellsRange.endRowIndex + 1,''); + if (!ut.selectedTds.length) { + ut.insertRow(cellInfo.rowIndex + cellInfo.rowSpan, cell); + } else { + var range = ut.cellsRange; + for (var i = 0, len = range.endRowIndex - range.beginRowIndex + 1; i < len; i++) { + ut.insertRow(range.endRowIndex + 1, cell); + } + } + rng.moveToBookmark(bk).select(); + if (table.getAttribute("interlaced") === "enabled")this.fireEvent("interlacetable", table); + } + }; + UE.commands["deleterow"] = { + queryCommandState: function () { + var tableItems = getTableItemsByRange(this); + return tableItems.cell ? 0 : -1; + }, + execCommand: function () { + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell), + cellsRange = ut.cellsRange, + cellInfo = ut.getCellInfo(cell), + preCell = ut.getVSideCell(cell), + nextCell = ut.getVSideCell(cell, true), + rng = this.selection.getRange(); + if (utils.isEmptyObject(cellsRange)) { + ut.deleteRow(cellInfo.rowIndex); + } else { + for (var i = cellsRange.beginRowIndex; i < cellsRange.endRowIndex + 1; i++) { + ut.deleteRow(cellsRange.beginRowIndex); + } + } + var table = ut.table; + if (!table.getElementsByTagName('td').length) { + var nextSibling = table.nextSibling; + domUtils.remove(table); + if (nextSibling) { + rng.setStart(nextSibling, 0).setCursor(false, true); + } + } else { + if (cellInfo.rowSpan == 1 || cellInfo.rowSpan == cellsRange.endRowIndex - cellsRange.beginRowIndex + 1) { + if (nextCell || preCell) rng.selectNodeContents(nextCell || preCell).setCursor(false, true); + } else { + var newCell = ut.getCell(cellInfo.rowIndex, ut.indexTable[cellInfo.rowIndex][cellInfo.colIndex].cellIndex); + if (newCell) rng.selectNodeContents(newCell).setCursor(false, true); + } + } + if (table.getAttribute("interlaced") === "enabled")this.fireEvent("interlacetable", table); + } + }; + UE.commands["insertcol"] = { + queryCommandState: function (cmd) { + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell; + return cell && (cell.tagName == "TD" || (cell.tagName == 'TH' && cell !== tableItems.tr.cells[0])) && + getUETable(tableItems.table).colsNum < this.options.maxColNum ? 0 : -1; + }, + execCommand: function (cmd) { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + if (this.queryCommandState(cmd) == -1)return; + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell), + cellInfo = ut.getCellInfo(cell); + + //ut.insertCol(!ut.selectedTds.length ? cellInfo.colIndex:ut.cellsRange.beginColIndex); + if (!ut.selectedTds.length) { + ut.insertCol(cellInfo.colIndex, cell); + } else { + var range = ut.cellsRange; + for (var i = 0, len = range.endColIndex - range.beginColIndex + 1; i < len; i++) { + ut.insertCol(range.beginColIndex, cell); + } + } + rng.moveToBookmark(bk).select(true); + } + }; + UE.commands["insertcolnext"] = { + queryCommandState: function () { + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell; + return cell && getUETable(tableItems.table).colsNum < this.options.maxColNum ? 0 : -1; + }, + execCommand: function () { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell), + cellInfo = ut.getCellInfo(cell); + //ut.insertCol(!ut.selectedTds.length ? cellInfo.colIndex + cellInfo.colSpan:ut.cellsRange.endColIndex +1); + if (!ut.selectedTds.length) { + ut.insertCol(cellInfo.colIndex + cellInfo.colSpan, cell); + } else { + var range = ut.cellsRange; + for (var i = 0, len = range.endColIndex - range.beginColIndex + 1; i < len; i++) { + ut.insertCol(range.endColIndex + 1, cell); + } + } + rng.moveToBookmark(bk).select(); + } + }; + + UE.commands["deletecol"] = { + queryCommandState: function () { + var tableItems = getTableItemsByRange(this); + return tableItems.cell ? 0 : -1; + }, + execCommand: function () { + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell), + range = ut.cellsRange, + cellInfo = ut.getCellInfo(cell), + preCell = ut.getHSideCell(cell), + nextCell = ut.getHSideCell(cell, true); + if (utils.isEmptyObject(range)) { + ut.deleteCol(cellInfo.colIndex); + } else { + for (var i = range.beginColIndex; i < range.endColIndex + 1; i++) { + ut.deleteCol(range.beginColIndex); + } + } + var table = ut.table, + rng = this.selection.getRange(); + + if (!table.getElementsByTagName('td').length) { + var nextSibling = table.nextSibling; + domUtils.remove(table); + if (nextSibling) { + rng.setStart(nextSibling, 0).setCursor(false, true); + } + } else { + if (domUtils.inDoc(cell, this.document)) { + rng.setStart(cell, 0).setCursor(false, true); + } else { + if (nextCell && domUtils.inDoc(nextCell, this.document)) { + rng.selectNodeContents(nextCell).setCursor(false, true); + } else { + if (preCell && domUtils.inDoc(preCell, this.document)) { + rng.selectNodeContents(preCell).setCursor(true, true); + } + } + } + } + } + }; + UE.commands["splittocells"] = { + queryCommandState: function () { + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell; + if (!cell) return -1; + var ut = getUETable(tableItems.table); + if (ut.selectedTds.length > 0) return -1; + return cell && (cell.colSpan > 1 || cell.rowSpan > 1) ? 0 : -1; + }, + execCommand: function () { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell); + ut.splitToCells(cell); + rng.moveToBookmark(bk).select(); + } + }; + UE.commands["splittorows"] = { + queryCommandState: function () { + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell; + if (!cell) return -1; + var ut = getUETable(tableItems.table); + if (ut.selectedTds.length > 0) return -1; + return cell && cell.rowSpan > 1 ? 0 : -1; + }, + execCommand: function () { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell); + ut.splitToRows(cell); + rng.moveToBookmark(bk).select(); + } + }; + UE.commands["splittocols"] = { + queryCommandState: function () { + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell; + if (!cell) return -1; + var ut = getUETable(tableItems.table); + if (ut.selectedTds.length > 0) return -1; + return cell && cell.colSpan > 1 ? 0 : -1; + }, + execCommand: function () { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell); + ut.splitToCols(cell); + rng.moveToBookmark(bk).select(); + + } + }; + + UE.commands["adaptbytext"] = + UE.commands["adaptbywindow"] = { + queryCommandState: function () { + return getTableItemsByRange(this).table ? 0 : -1 + }, + execCommand: function (cmd) { + var tableItems = getTableItemsByRange(this), + table = tableItems.table; + if (table) { + if (cmd == 'adaptbywindow') { + resetTdWidth(table, this); + } else { + var cells = domUtils.getElementsByTagName(table, "td th"); + utils.each(cells, function (cell) { + cell.removeAttribute("width"); + }); + table.removeAttribute("width"); + } + } + } + }; + + //平均分配各列 + UE.commands['averagedistributecol'] = { + queryCommandState: function () { + var ut = getUETableBySelected(this); + if (!ut) return -1; + return ut.isFullRow() || ut.isFullCol() ? 0 : -1; + }, + execCommand: function (cmd) { + var me = this, + ut = getUETableBySelected(me); + + function getAverageWidth() { + var tb = ut.table, + averageWidth, sumWidth = 0, colsNum = 0, + tbAttr = getDefaultValue(me, tb); + + if (ut.isFullRow()) { + sumWidth = tb.offsetWidth; + colsNum = ut.colsNum; + } else { + var begin = ut.cellsRange.beginColIndex, + end = ut.cellsRange.endColIndex, + node; + for (var i = begin; i <= end;) { + node = ut.selectedTds[i]; + sumWidth += node.offsetWidth; + i += node.colSpan; + colsNum += 1; + } + } + averageWidth = Math.ceil(sumWidth / colsNum) - tbAttr.tdBorder * 2 - tbAttr.tdPadding * 2; + return averageWidth; + } + + function setAverageWidth(averageWidth) { + utils.each(domUtils.getElementsByTagName(ut.table, "th"), function (node) { + node.setAttribute("width", ""); + }); + var cells = ut.isFullRow() ? domUtils.getElementsByTagName(ut.table, "td") : ut.selectedTds; + + utils.each(cells, function (node) { + if (node.colSpan == 1) { + node.setAttribute("width", averageWidth); + } + }); + } + + if (ut && ut.selectedTds.length) { + setAverageWidth(getAverageWidth()); + } + } + }; + //平均分配各行 + UE.commands['averagedistributerow'] = { + queryCommandState: function () { + var ut = getUETableBySelected(this); + if (!ut) return -1; + if (ut.selectedTds && /th/ig.test(ut.selectedTds[0].tagName)) return -1; + return ut.isFullRow() || ut.isFullCol() ? 0 : -1; + }, + execCommand: function (cmd) { + var me = this, + ut = getUETableBySelected(me); + + function getAverageHeight() { + var averageHeight, rowNum, sumHeight = 0, + tb = ut.table, + tbAttr = getDefaultValue(me, tb), + tdpadding = parseInt(domUtils.getComputedStyle(tb.getElementsByTagName('td')[0], "padding-top")); + + if (ut.isFullCol()) { + var captionArr = domUtils.getElementsByTagName(tb, "caption"), + thArr = domUtils.getElementsByTagName(tb, "th"), + captionHeight, thHeight; + + if (captionArr.length > 0) { + captionHeight = captionArr[0].offsetHeight; + } + if (thArr.length > 0) { + thHeight = thArr[0].offsetHeight; + } + + sumHeight = tb.offsetHeight - (captionHeight || 0) - (thHeight || 0); + rowNum = thArr.length == 0 ? ut.rowsNum : (ut.rowsNum - 1); + } else { + var begin = ut.cellsRange.beginRowIndex, + end = ut.cellsRange.endRowIndex, + count = 0, + trs = domUtils.getElementsByTagName(tb, "tr"); + for (var i = begin; i <= end; i++) { + sumHeight += trs[i].offsetHeight; + count += 1; + } + rowNum = count; + } + //ie8下是混杂模式 + if (browser.ie && browser.version < 9) { + averageHeight = Math.ceil(sumHeight / rowNum); + } else { + averageHeight = Math.ceil(sumHeight / rowNum) - tbAttr.tdBorder * 2 - tdpadding * 2; + } + return averageHeight; + } + + function setAverageHeight(averageHeight) { + var cells = ut.isFullCol() ? domUtils.getElementsByTagName(ut.table, "td") : ut.selectedTds; + utils.each(cells, function (node) { + if (node.rowSpan == 1) { + node.setAttribute("height", averageHeight); + } + }); + } + + if (ut && ut.selectedTds.length) { + setAverageHeight(getAverageHeight()); + } + } + }; + + //单元格对齐方式 + UE.commands['cellalignment'] = { + queryCommandState: function () { + return getTableItemsByRange(this).table ? 0 : -1 + }, + execCommand: function (cmd, data) { + var me = this, + ut = getUETableBySelected(me); + + if (!ut) { + var start = me.selection.getStart(), + cell = start && domUtils.findParentByTagName(start, ["td", "th", "caption"], true); + if (!/caption/ig.test(cell.tagName)) { + domUtils.setAttributes(cell, data); + } else { + cell.style.textAlign = data.align; + cell.style.verticalAlign = data.vAlign; + } + me.selection.getRange().setCursor(true); + } else { + utils.each(ut.selectedTds, function (cell) { + domUtils.setAttributes(cell, data); + }); + } + }, + /** + * 查询当前点击的单元格的对齐状态, 如果当前已经选择了多个单元格, 则会返回所有单元格经过统一协调过后的状态 + * @see UE.UETable.getTableCellAlignState + */ + queryCommandValue: function (cmd) { + + var activeMenuCell = getTableItemsByRange( this).cell; + + if( !activeMenuCell ) { + activeMenuCell = getSelectedArr(this)[0]; + } + + if (!activeMenuCell) { + + return null; + + } else { + + //获取同时选中的其他单元格 + var cells = UE.UETable.getUETable(activeMenuCell).selectedTds; + + !cells.length && ( cells = activeMenuCell ); + + return UE.UETable.getTableCellAlignState(cells); + + } + + } + }; + //表格对齐方式 + UE.commands['tablealignment'] = { + queryCommandState: function () { + if (browser.ie && browser.version < 8) { + return -1; + } + return getTableItemsByRange(this).table ? 0 : -1 + }, + execCommand: function (cmd, value) { + var me = this, + start = me.selection.getStart(), + table = start && domUtils.findParentByTagName(start, ["table"], true); + + if (table) { + table.setAttribute("align",value); + } + } + }; + + //表格属性 + UE.commands['edittable'] = { + queryCommandState: function () { + return getTableItemsByRange(this).table ? 0 : -1 + }, + execCommand: function (cmd, color) { + var rng = this.selection.getRange(), + table = domUtils.findParentByTagName(rng.startContainer, 'table'); + if (table) { + var arr = domUtils.getElementsByTagName(table, "td").concat( + domUtils.getElementsByTagName(table, "th"), + domUtils.getElementsByTagName(table, "caption") + ); + utils.each(arr, function (node) { + node.style.borderColor = color; + }); + } + } + }; + //单元格属性 + UE.commands['edittd'] = { + queryCommandState: function () { + return getTableItemsByRange(this).table ? 0 : -1 + }, + execCommand: function (cmd, bkColor) { + var me = this, + ut = getUETableBySelected(me); + + if (!ut) { + var start = me.selection.getStart(), + cell = start && domUtils.findParentByTagName(start, ["td", "th", "caption"], true); + if (cell) { + cell.style.backgroundColor = bkColor; + } + } else { + utils.each(ut.selectedTds, function (cell) { + cell.style.backgroundColor = bkColor; + }); + } + } + }; + + UE.commands["settablebackground"] = { + queryCommandState: function () { + return getSelectedArr(this).length > 1 ? 0 : -1; + }, + execCommand: function (cmd, value) { + var cells, ut; + cells = getSelectedArr(this); + ut = getUETable(cells[0]); + ut.setBackground(cells, value); + } + }; + + UE.commands["cleartablebackground"] = { + queryCommandState: function () { + var cells = getSelectedArr(this); + if (!cells.length)return -1; + for (var i = 0, cell; cell = cells[i++];) { + if (cell.style.backgroundColor !== "") return 0; + } + return -1; + }, + execCommand: function () { + var cells = getSelectedArr(this), + ut = getUETable(cells[0]); + ut.removeBackground(cells); + } + }; + + UE.commands["interlacetable"] = UE.commands["uninterlacetable"] = { + queryCommandState: function (cmd) { + var table = getTableItemsByRange(this).table; + if (!table) return -1; + var interlaced = table.getAttribute("interlaced"); + if (cmd == "interlacetable") { + //TODO 待定 + //是否需要待定,如果设置,则命令只能单次执行成功,但反射具备toggle效果;否则可以覆盖前次命令,但反射将不存在toggle效果 + return (interlaced === "enabled") ? -1 : 0; + } else { + return (!interlaced || interlaced === "disabled") ? -1 : 0; + } + }, + execCommand: function (cmd, classList) { + var table = getTableItemsByRange(this).table; + if (cmd == "interlacetable") { + table.setAttribute("interlaced", "enabled"); + this.fireEvent("interlacetable", table, classList); + } else { + table.setAttribute("interlaced", "disabled"); + this.fireEvent("uninterlacetable", table); + } + } + }; + UE.commands["setbordervisible"] = { + queryCommandState: function (cmd) { + var table = getTableItemsByRange(this).table; + if (!table) return -1; + return 0; + }, + execCommand: function () { + var table = getTableItemsByRange(this).table; + utils.each(domUtils.getElementsByTagName(table,'td'),function(td){ + td.style.borderWidth = '1px'; + td.style.borderStyle = 'solid'; + }) + } + }; + function resetTdWidth(table, editor) { + var tds = domUtils.getElementsByTagName(table,'td th'); + utils.each(tds, function (td) { + td.removeAttribute("width"); + }); + table.setAttribute('width', getTableWidth(editor, true, getDefaultValue(editor, table))); + var tdsWidths = []; + setTimeout(function () { + utils.each(tds, function (td) { + (td.colSpan == 1) && tdsWidths.push(td.offsetWidth) + }) + utils.each(tds, function (td,i) { + (td.colSpan == 1) && td.setAttribute("width", tdsWidths[i] + ""); + }) + }, 0); + } + + function getTableWidth(editor, needIEHack, defaultValue) { + var body = editor.body; + return body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (editor.options.offsetWidth || 0); + } + + function getSelectedArr(editor) { + var cell = getTableItemsByRange(editor).cell; + if (cell) { + var ut = getUETable(cell); + return ut.selectedTds.length ? ut.selectedTds : [cell]; + } else { + return []; + } + } +})(); + + +// plugins/table.action.js +/** + * Created with JetBrains PhpStorm. + * User: taoqili + * Date: 12-10-12 + * Time: 上午10:05 + * To change this template use File | Settings | File Templates. + */ +UE.plugins['table'] = function () { + var me = this, + tabTimer = null, + //拖动计时器 + tableDragTimer = null, + //双击计时器 + tableResizeTimer = null, + //单元格最小宽度 + cellMinWidth = 5, + isInResizeBuffer = false, + //单元格边框大小 + cellBorderWidth = 5, + //鼠标偏移距离 + offsetOfTableCell = 10, + //记录在有限时间内的点击状态, 共有3个取值, 0, 1, 2。 0代表未初始化, 1代表单击了1次,2代表2次 + singleClickState = 0, + userActionStatus = null, + //双击允许的时间范围 + dblclickTime = 360, + UT = UE.UETable, + getUETable = function (tdOrTable) { + return UT.getUETable(tdOrTable); + }, + getUETableBySelected = function (editor) { + return UT.getUETableBySelected(editor); + }, + getDefaultValue = function (editor, table) { + return UT.getDefaultValue(editor, table); + }, + removeSelectedClass = function (cells) { + return UT.removeSelectedClass(cells); + }; + + function showError(e) { +// throw e; + } + me.ready(function(){ + var me = this; + var orgGetText = me.selection.getText; + me.selection.getText = function(){ + var table = getUETableBySelected(me); + if(table){ + var str = ''; + utils.each(table.selectedTds,function(td){ + str += td[browser.ie?'innerText':'textContent']; + }) + return str; + }else{ + return orgGetText.call(me.selection) + } + + } + }) + + //处理拖动及框选相关方法 + var startTd = null, //鼠标按下时的锚点td + currentTd = null, //当前鼠标经过时的td + onDrag = "", //指示当前拖动状态,其值可为"","h","v" ,分别表示未拖动状态,横向拖动状态,纵向拖动状态,用于鼠标移动过程中的判断 + onBorder = false, //检测鼠标按下时是否处在单元格边缘位置 + dragButton = null, + dragOver = false, + dragLine = null, //模拟的拖动线 + dragTd = null; //发生拖动的目标td + + var mousedown = false, + //todo 判断混乱模式 + needIEHack = true; + + me.setOpt({ + 'maxColNum':20, + 'maxRowNum':100, + 'defaultCols':5, + 'defaultRows':5, + 'tdvalign':'top', + 'cursorpath':me.options.UEDITOR_HOME_URL + "themes/default/images/cursor_", + 'tableDragable':false, + 'classList':["ue-table-interlace-color-single","ue-table-interlace-color-double"] + }); + me.getUETable = getUETable; + var commands = { + 'deletetable':1, + 'inserttable':1, + 'cellvalign':1, + 'insertcaption':1, + 'deletecaption':1, + 'inserttitle':1, + 'deletetitle':1, + "mergeright":1, + "mergedown":1, + "mergecells":1, + "insertrow":1, + "insertrownext":1, + "deleterow":1, + "insertcol":1, + "insertcolnext":1, + "deletecol":1, + "splittocells":1, + "splittorows":1, + "splittocols":1, + "adaptbytext":1, + "adaptbywindow":1, + "adaptbycustomer":1, + "insertparagraph":1, + "insertparagraphbeforetable":1, + "averagedistributecol":1, + "averagedistributerow":1 + }; + me.ready(function () { + utils.cssRule('table', + //选中的td上的样式 + '.selectTdClass{background-color:#edf5fa !important}' + + 'table.noBorderTable td,table.noBorderTable th,table.noBorderTable caption{border:1px dashed #ddd !important}' + + //插入的表格的默认样式 + 'table{margin-bottom:10px;border-collapse:collapse;display:table;}' + + 'td,th{padding: 5px 10px;border: 1px solid #DDD;}' + + 'caption{border:1px dashed #DDD;border-bottom:0;padding:3px;text-align:center;}' + + 'th{border-top:1px solid #BBB;background-color:#F7F7F7;}' + + 'table tr.firstRow th{border-top-width:2px;}' + + '.ue-table-interlace-color-single{ background-color: #fcfcfc; } .ue-table-interlace-color-double{ background-color: #f7faff; }' + + 'td p{margin:0;padding:0;}', me.document); + + var tableCopyList, isFullCol, isFullRow; + //注册del/backspace事件 + me.addListener('keydown', function (cmd, evt) { + var me = this; + var keyCode = evt.keyCode || evt.which; + + if (keyCode == 8) { + + var ut = getUETableBySelected(me); + if (ut && ut.selectedTds.length) { + + if (ut.isFullCol()) { + me.execCommand('deletecol') + } else if (ut.isFullRow()) { + me.execCommand('deleterow') + } else { + me.fireEvent('delcells'); + } + domUtils.preventDefault(evt); + } + + var caption = domUtils.findParentByTagName(me.selection.getStart(), 'caption', true), + range = me.selection.getRange(); + if (range.collapsed && caption && isEmptyBlock(caption)) { + me.fireEvent('saveScene'); + var table = caption.parentNode; + domUtils.remove(caption); + if (table) { + range.setStart(table.rows[0].cells[0], 0).setCursor(false, true); + } + me.fireEvent('saveScene'); + } + + } + + if (keyCode == 46) { + + ut = getUETableBySelected(me); + if (ut) { + me.fireEvent('saveScene'); + for (var i = 0, ci; ci = ut.selectedTds[i++];) { + domUtils.fillNode(me.document, ci) + } + me.fireEvent('saveScene'); + domUtils.preventDefault(evt); + + } + + } + if (keyCode == 13) { + + var rng = me.selection.getRange(), + caption = domUtils.findParentByTagName(rng.startContainer, 'caption', true); + if (caption) { + var table = domUtils.findParentByTagName(caption, 'table'); + if (!rng.collapsed) { + + rng.deleteContents(); + me.fireEvent('saveScene'); + } else { + if (caption) { + rng.setStart(table.rows[0].cells[0], 0).setCursor(false, true); + } + } + domUtils.preventDefault(evt); + return; + } + if (rng.collapsed) { + var table = domUtils.findParentByTagName(rng.startContainer, 'table'); + if (table) { + var cell = table.rows[0].cells[0], + start = domUtils.findParentByTagName(me.selection.getStart(), ['td', 'th'], true), + preNode = table.previousSibling; + if (cell === start && (!preNode || preNode.nodeType == 1 && preNode.tagName == 'TABLE' ) && domUtils.isStartInblock(rng)) { + var first = domUtils.findParent(me.selection.getStart(), function(n){return domUtils.isBlockElm(n)}, true); + if(first && ( /t(h|d)/i.test(first.tagName) || first === start.firstChild )){ + me.execCommand('insertparagraphbeforetable'); + domUtils.preventDefault(evt); + } + + } + } + } + } + + if ((evt.ctrlKey || evt.metaKey) && evt.keyCode == '67') { + tableCopyList = null; + var ut = getUETableBySelected(me); + if (ut) { + var tds = ut.selectedTds; + isFullCol = ut.isFullCol(); + isFullRow = ut.isFullRow(); + tableCopyList = [ + [ut.cloneCell(tds[0],null,true)] + ]; + for (var i = 1, ci; ci = tds[i]; i++) { + if (ci.parentNode !== tds[i - 1].parentNode) { + tableCopyList.push([ut.cloneCell(ci,null,true)]); + } else { + tableCopyList[tableCopyList.length - 1].push(ut.cloneCell(ci,null,true)); + } + + } + } + } + }); + me.addListener("tablehasdeleted",function(){ + toggleDraggableState(this, false, "", null); + if (dragButton)domUtils.remove(dragButton); + }); + + me.addListener('beforepaste', function (cmd, html) { + var me = this; + var rng = me.selection.getRange(); + if (domUtils.findParentByTagName(rng.startContainer, 'caption', true)) { + var div = me.document.createElement("div"); + div.innerHTML = html.html; + //trace:3729 + html.html = div[browser.ie9below ? 'innerText' : 'textContent']; + return; + } + var table = getUETableBySelected(me); + if (tableCopyList) { + me.fireEvent('saveScene'); + var rng = me.selection.getRange(); + var td = domUtils.findParentByTagName(rng.startContainer, ['td', 'th'], true), tmpNode, preNode; + if (td) { + var ut = getUETable(td); + if (isFullRow) { + var rowIndex = ut.getCellInfo(td).rowIndex; + if (td.tagName == 'TH') { + rowIndex++; + } + for (var i = 0, ci; ci = tableCopyList[i++];) { + var tr = ut.insertRow(rowIndex++, "td"); + for (var j = 0, cj; cj = ci[j]; j++) { + var cell = tr.cells[j]; + if (!cell) { + cell = tr.insertCell(j) + } + cell.innerHTML = cj.innerHTML; + cj.getAttribute('width') && cell.setAttribute('width', cj.getAttribute('width')); + cj.getAttribute('vAlign') && cell.setAttribute('vAlign', cj.getAttribute('vAlign')); + cj.getAttribute('align') && cell.setAttribute('align', cj.getAttribute('align')); + cj.style.cssText && (cell.style.cssText = cj.style.cssText) + } + for (var j = 0, cj; cj = tr.cells[j]; j++) { + if (!ci[j]) + break; + cj.innerHTML = ci[j].innerHTML; + ci[j].getAttribute('width') && cj.setAttribute('width', ci[j].getAttribute('width')); + ci[j].getAttribute('vAlign') && cj.setAttribute('vAlign', ci[j].getAttribute('vAlign')); + ci[j].getAttribute('align') && cj.setAttribute('align', ci[j].getAttribute('align')); + ci[j].style.cssText && (cj.style.cssText = ci[j].style.cssText) + } + } + } else { + if (isFullCol) { + cellInfo = ut.getCellInfo(td); + var maxColNum = 0; + for (var j = 0, ci = tableCopyList[0], cj; cj = ci[j++];) { + maxColNum += cj.colSpan || 1; + } + me.__hasEnterExecCommand = true; + for (i = 0; i < maxColNum; i++) { + me.execCommand('insertcol'); + } + me.__hasEnterExecCommand = false; + td = ut.table.rows[0].cells[cellInfo.cellIndex]; + if (td.tagName == 'TH') { + td = ut.table.rows[1].cells[cellInfo.cellIndex]; + } + } + for (var i = 0, ci; ci = tableCopyList[i++];) { + tmpNode = td; + for (var j = 0, cj; cj = ci[j++];) { + if (td) { + td.innerHTML = cj.innerHTML; + //todo 定制处理 + cj.getAttribute('width') && td.setAttribute('width', cj.getAttribute('width')); + cj.getAttribute('vAlign') && td.setAttribute('vAlign', cj.getAttribute('vAlign')); + cj.getAttribute('align') && td.setAttribute('align', cj.getAttribute('align')); + cj.style.cssText && (td.style.cssText = cj.style.cssText); + preNode = td; + td = td.nextSibling; + } else { + var cloneTd = cj.cloneNode(true); + domUtils.removeAttributes(cloneTd, ['class', 'rowSpan', 'colSpan']); + + preNode.parentNode.appendChild(cloneTd) + } + } + td = ut.getNextCell(tmpNode, true, true); + if (!tableCopyList[i]) + break; + if (!td) { + var cellInfo = ut.getCellInfo(tmpNode); + ut.table.insertRow(ut.table.rows.length); + ut.update(); + td = ut.getVSideCell(tmpNode, true); + } + } + } + ut.update(); + } else { + table = me.document.createElement('table'); + for (var i = 0, ci; ci = tableCopyList[i++];) { + var tr = table.insertRow(table.rows.length); + for (var j = 0, cj; cj = ci[j++];) { + cloneTd = UT.cloneCell(cj,null,true); + domUtils.removeAttributes(cloneTd, ['class']); + tr.appendChild(cloneTd) + } + if (j == 2 && cloneTd.rowSpan > 1) { + cloneTd.rowSpan = 1; + } + } + + var defaultValue = getDefaultValue(me), + width = me.body.offsetWidth - + (needIEHack ? parseInt(domUtils.getComputedStyle(me.body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (me.options.offsetWidth || 0); + me.execCommand('insertHTML', '' + table.innerHTML.replace(/>\s*<').replace(/\bth\b/gi, "td") + '
      ') + } + me.fireEvent('contentchange'); + me.fireEvent('saveScene'); + html.html = ''; + return true; + } else { + var div = me.document.createElement("div"), tables; + div.innerHTML = html.html; + tables = div.getElementsByTagName("table"); + if (domUtils.findParentByTagName(me.selection.getStart(), 'table')) { + utils.each(tables, function (t) { + domUtils.remove(t) + }); + if (domUtils.findParentByTagName(me.selection.getStart(), 'caption', true)) { + div.innerHTML = div[browser.ie ? 'innerText' : 'textContent']; + } + } else { + utils.each(tables, function (table) { + removeStyleSize(table, true); + domUtils.removeAttributes(table, ['style', 'border']); + utils.each(domUtils.getElementsByTagName(table, "td"), function (td) { + if (isEmptyBlock(td)) { + domUtils.fillNode(me.document, td); + } + removeStyleSize(td, true); +// domUtils.removeAttributes(td, ['style']) + }); + }); + } + html.html = div.innerHTML; + } + }); + + me.addListener('afterpaste', function () { + utils.each(domUtils.getElementsByTagName(me.body, "table"), function (table) { + if (table.offsetWidth > me.body.offsetWidth) { + var defaultValue = getDefaultValue(me, table); + table.style.width = me.body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(me.body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (me.options.offsetWidth || 0) + 'px' + } + }) + }); + me.addListener('blur', function () { + tableCopyList = null; + }); + var timer; + me.addListener('keydown', function () { + clearTimeout(timer); + timer = setTimeout(function () { + var rng = me.selection.getRange(), + cell = domUtils.findParentByTagName(rng.startContainer, ['th', 'td'], true); + if (cell) { + var table = cell.parentNode.parentNode.parentNode; + if (table.offsetWidth > table.getAttribute("width")) { + cell.style.wordBreak = "break-all"; + } + } + + }, 100); + }); + me.addListener("selectionchange", function () { + toggleDraggableState(me, false, "", null); + }); + + + //内容变化时触发索引更新 + //todo 可否考虑标记检测,如果不涉及表格的变化就不进行索引重建和更新 + me.addListener("contentchange", function () { + var me = this; + //尽可能排除一些不需要更新的状况 + hideDragLine(me); + if (getUETableBySelected(me))return; + var rng = me.selection.getRange(); + var start = rng.startContainer; + start = domUtils.findParentByTagName(start, ['td', 'th'], true); + utils.each(domUtils.getElementsByTagName(me.document, 'table'), function (table) { + if (me.fireEvent("excludetable", table) === true) return; + table.ueTable = new UT(table); + //trace:3742 +// utils.each(domUtils.getElementsByTagName(me.document, 'td'), function (td) { +// +// if (domUtils.isEmptyBlock(td) && td !== start) { +// domUtils.fillNode(me.document, td); +// if (browser.ie && browser.version == 6) { +// td.innerHTML = ' ' +// } +// } +// }); +// utils.each(domUtils.getElementsByTagName(me.document, 'th'), function (th) { +// if (domUtils.isEmptyBlock(th) && th !== start) { +// domUtils.fillNode(me.document, th); +// if (browser.ie && browser.version == 6) { +// th.innerHTML = ' ' +// } +// } +// }); + table.onmouseover = function () { + me.fireEvent('tablemouseover', table); + }; + table.onmousemove = function () { + me.fireEvent('tablemousemove', table); + me.options.tableDragable && toggleDragButton(true, this, me); + utils.defer(function(){ + me.fireEvent('contentchange',50) + },true) + }; + table.onmouseout = function () { + me.fireEvent('tablemouseout', table); + toggleDraggableState(me, false, "", null); + hideDragLine(me); + }; + table.onclick = function (evt) { + evt = me.window.event || evt; + var target = getParentTdOrTh(evt.target || evt.srcElement); + if (!target)return; + var ut = getUETable(target), + table = ut.table, + cellInfo = ut.getCellInfo(target), + cellsRange, + rng = me.selection.getRange(); +// if ("topLeft" == inPosition(table, mouseCoords(evt))) { +// cellsRange = ut.getCellsRange(ut.table.rows[0].cells[0], ut.getLastCell()); +// ut.setSelected(cellsRange); +// return; +// } +// if ("bottomRight" == inPosition(table, mouseCoords(evt))) { +// +// return; +// } + if (inTableSide(table, target, evt, true)) { + var endTdCol = ut.getCell(ut.indexTable[ut.rowsNum - 1][cellInfo.colIndex].rowIndex, ut.indexTable[ut.rowsNum - 1][cellInfo.colIndex].cellIndex); + if (evt.shiftKey && ut.selectedTds.length) { + if (ut.selectedTds[0] !== endTdCol) { + cellsRange = ut.getCellsRange(ut.selectedTds[0], endTdCol); + ut.setSelected(cellsRange); + } else { + rng && rng.selectNodeContents(endTdCol).select(); + } + } else { + if (target !== endTdCol) { + cellsRange = ut.getCellsRange(target, endTdCol); + ut.setSelected(cellsRange); + } else { + rng && rng.selectNodeContents(endTdCol).select(); + } + } + return; + } + if (inTableSide(table, target, evt)) { + var endTdRow = ut.getCell(ut.indexTable[cellInfo.rowIndex][ut.colsNum - 1].rowIndex, ut.indexTable[cellInfo.rowIndex][ut.colsNum - 1].cellIndex); + if (evt.shiftKey && ut.selectedTds.length) { + if (ut.selectedTds[0] !== endTdRow) { + cellsRange = ut.getCellsRange(ut.selectedTds[0], endTdRow); + ut.setSelected(cellsRange); + } else { + rng && rng.selectNodeContents(endTdRow).select(); + } + } else { + if (target !== endTdRow) { + cellsRange = ut.getCellsRange(target, endTdRow); + ut.setSelected(cellsRange); + } else { + rng && rng.selectNodeContents(endTdRow).select(); + } + } + } + }; + }); + + switchBorderColor(me, true); + }); + + domUtils.on(me.document, "mousemove", mouseMoveEvent); + + domUtils.on(me.document, "mouseout", function (evt) { + var target = evt.target || evt.srcElement; + if (target.tagName == "TABLE") { + toggleDraggableState(me, false, "", null); + } + }); + /** + * 表格隔行变色 + */ + me.addListener("interlacetable",function(type,table,classList){ + if(!table) return; + var me = this, + rows = table.rows, + len = rows.length, + getClass = function(list,index,repeat){ + return list[index] ? list[index] : repeat ? list[index % list.length]: ""; + }; + for(var i = 0;i 1 ? currentRowIndex : ua.getCellInfo(cell).rowIndex; + var nextCell = ua.getTabNextCell(cell, currentRowIndex); + if (nextCell) { + if (isEmptyBlock(nextCell)) { + range.setStart(nextCell, 0).setCursor(false, true) + } else { + range.selectNodeContents(nextCell).select() + } + } else { + me.fireEvent('saveScene'); + me.__hasEnterExecCommand = true; + this.execCommand('insertrownext'); + me.__hasEnterExecCommand = false; + range = this.selection.getRange(); + range.setStart(table.rows[table.rows.length - 1].cells[0], 0).setCursor(); + me.fireEvent('saveScene'); + } + } + return true; + } + + }); + browser.ie && me.addListener('selectionchange', function () { + toggleDraggableState(this, false, "", null); + }); + me.addListener("keydown", function (type, evt) { + var me = this; + //处理在表格的最后一个输入tab产生新的表格 + var keyCode = evt.keyCode || evt.which; + if (keyCode == 8 || keyCode == 46) { + return; + } + var notCtrlKey = !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey; + notCtrlKey && removeSelectedClass(domUtils.getElementsByTagName(me.body, "td")); + var ut = getUETableBySelected(me); + if (!ut) return; + notCtrlKey && ut.clearSelected(); + }); + + me.addListener("beforegetcontent", function () { + switchBorderColor(this, false); + browser.ie && utils.each(this.document.getElementsByTagName('caption'), function (ci) { + if (domUtils.isEmptyNode(ci)) { + ci.innerHTML = ' ' + } + }); + }); + me.addListener("aftergetcontent", function () { + switchBorderColor(this, true); + }); + me.addListener("getAllHtml", function () { + removeSelectedClass(me.document.getElementsByTagName("td")); + }); + //修正全屏状态下插入的表格宽度在非全屏状态下撑开编辑器的情况 + me.addListener("fullscreenchanged", function (type, fullscreen) { + if (!fullscreen) { + var ratio = this.body.offsetWidth / document.body.offsetWidth, + tables = domUtils.getElementsByTagName(this.body, "table"); + utils.each(tables, function (table) { + if (table.offsetWidth < me.body.offsetWidth) return false; + var tds = domUtils.getElementsByTagName(table, "td"), + backWidths = []; + utils.each(tds, function (td) { + backWidths.push(td.offsetWidth); + }); + for (var i = 0, td; td = tds[i]; i++) { + td.setAttribute("width", Math.floor(backWidths[i] * ratio)); + } + table.setAttribute("width", Math.floor(getTableWidth(me, needIEHack, getDefaultValue(me)))) + }); + } + }); + + //重写execCommand命令,用于处理框选时的处理 + var oldExecCommand = me.execCommand; + me.execCommand = function (cmd, datatat) { + + var me = this, + args = arguments; + + cmd = cmd.toLowerCase(); + var ut = getUETableBySelected(me), tds, + range = new dom.Range(me.document), + cmdFun = me.commands[cmd] || UE.commands[cmd], + result; + if (!cmdFun) return; + if (ut && !commands[cmd] && !cmdFun.notNeedUndo && !me.__hasEnterExecCommand) { + me.__hasEnterExecCommand = true; + me.fireEvent("beforeexeccommand", cmd); + tds = ut.selectedTds; + var lastState = -2, lastValue = -2, value, state; + for (var i = 0, td; td = tds[i]; i++) { + if (isEmptyBlock(td)) { + range.setStart(td, 0).setCursor(false, true) + } else { + range.selectNode(td).select(true); + } + state = me.queryCommandState(cmd); + value = me.queryCommandValue(cmd); + if (state != -1) { + if (lastState !== state || lastValue !== value) { + me._ignoreContentChange = true; + result = oldExecCommand.apply(me, arguments); + me._ignoreContentChange = false; + + } + lastState = me.queryCommandState(cmd); + lastValue = me.queryCommandValue(cmd); + if (domUtils.isEmptyBlock(td)) { + domUtils.fillNode(me.document, td) + } + } + } + range.setStart(tds[0], 0).shrinkBoundary(true).setCursor(false, true); + me.fireEvent('contentchange'); + me.fireEvent("afterexeccommand", cmd); + me.__hasEnterExecCommand = false; + me._selectionChange(); + } else { + result = oldExecCommand.apply(me, arguments); + } + return result; + }; + + + }); + /** + * 删除obj的宽高style,改成属性宽高 + * @param obj + * @param replaceToProperty + */ + function removeStyleSize(obj, replaceToProperty) { + removeStyle(obj, "width", true); + removeStyle(obj, "height", true); + } + + function removeStyle(obj, styleName, replaceToProperty) { + if (obj.style[styleName]) { + replaceToProperty && obj.setAttribute(styleName, parseInt(obj.style[styleName], 10)); + obj.style[styleName] = ""; + } + } + + function getParentTdOrTh(ele) { + if (ele.tagName == "TD" || ele.tagName == "TH") return ele; + var td; + if (td = domUtils.findParentByTagName(ele, "td", true) || domUtils.findParentByTagName(ele, "th", true)) return td; + return null; + } + + function isEmptyBlock(node) { + var reg = new RegExp(domUtils.fillChar, 'g'); + if (node[browser.ie ? 'innerText' : 'textContent'].replace(/^\s*$/, '').replace(reg, '').length > 0) { + return 0; + } + for (var n in dtd.$isNotEmpty) { + if (node.getElementsByTagName(n).length) { + return 0; + } + } + return 1; + } + + + function mouseCoords(evt) { + if (evt.pageX || evt.pageY) { + return { x:evt.pageX, y:evt.pageY }; + } + return { + x:evt.clientX + me.document.body.scrollLeft - me.document.body.clientLeft, + y:evt.clientY + me.document.body.scrollTop - me.document.body.clientTop + }; + } + + function mouseMoveEvent(evt) { + + if( isEditorDisabled() ) { + return; + } + + try { + + //普通状态下鼠标移动 + var target = getParentTdOrTh(evt.target || evt.srcElement), + pos; + + //区分用户的行为是拖动还是双击 + if( isInResizeBuffer ) { + + me.body.style.webkitUserSelect = 'none'; + + if( Math.abs( userActionStatus.x - evt.clientX ) > offsetOfTableCell || Math.abs( userActionStatus.y - evt.clientY ) > offsetOfTableCell ) { + clearTableDragTimer(); + isInResizeBuffer = false; + singleClickState = 0; + //drag action + tableBorderDrag(evt); + } + } + + //修改单元格大小时的鼠标移动 + if (onDrag && dragTd) { + singleClickState = 0; + me.body.style.webkitUserSelect = 'none'; + me.selection.getNative()[browser.ie9below ? 'empty' : 'removeAllRanges'](); + pos = mouseCoords(evt); + toggleDraggableState(me, true, onDrag, pos, target); + if (onDrag == "h") { + dragLine.style.left = getPermissionX(dragTd, evt) + "px"; + } else if (onDrag == "v") { + dragLine.style.top = getPermissionY(dragTd, evt) + "px"; + } + return; + } + //当鼠标处于table上时,修改移动过程中的光标状态 + if (target) { + //针对使用table作为容器的组件不触发拖拽效果 + if (me.fireEvent('excludetable', target) === true) + return; + pos = mouseCoords(evt); + var state = getRelation(target, pos), + table = domUtils.findParentByTagName(target, "table", true); + + if (inTableSide(table, target, evt, true)) { + if (me.fireEvent("excludetable", table) === true) return; + me.body.style.cursor = "url(" + me.options.cursorpath + "h.png),pointer"; + } else if (inTableSide(table, target, evt)) { + if (me.fireEvent("excludetable", table) === true) return; + me.body.style.cursor = "url(" + me.options.cursorpath + "v.png),pointer"; + } else { + me.body.style.cursor = "text"; + var curCell = target; + if (/\d/.test(state)) { + state = state.replace(/\d/, ''); + target = getUETable(target).getPreviewCell(target, state == "v"); + } + //位于第一行的顶部或者第一列的左边时不可拖动 + toggleDraggableState(me, target ? !!state : false, target ? state : '', pos, target); + + } + } else { + toggleDragButton(false, table, me); + } + + } catch (e) { + showError(e); + } + } + + var dragButtonTimer; + + function toggleDragButton(show, table, editor) { + if (!show) { + if (dragOver)return; + dragButtonTimer = setTimeout(function () { + !dragOver && dragButton && dragButton.parentNode && dragButton.parentNode.removeChild(dragButton); + }, 2000); + } else { + createDragButton(table, editor); + } + } + + function createDragButton(table, editor) { + var pos = domUtils.getXY(table), + doc = table.ownerDocument; + if (dragButton && dragButton.parentNode)return dragButton; + dragButton = doc.createElement("div"); + dragButton.contentEditable = false; + dragButton.innerHTML = ""; + dragButton.style.cssText = "width:15px;height:15px;background-image:url(" + editor.options.UEDITOR_HOME_URL + "dialogs/table/dragicon.png);position: absolute;cursor:move;top:" + (pos.y - 15) + "px;left:" + (pos.x) + "px;"; + domUtils.unSelectable(dragButton); + dragButton.onmouseover = function (evt) { + dragOver = true; + }; + dragButton.onmouseout = function (evt) { + dragOver = false; + }; + domUtils.on(dragButton, 'click', function (type, evt) { + doClick(evt, this); + }); + domUtils.on(dragButton, 'dblclick', function (type, evt) { + doDblClick(evt); + }); + domUtils.on(dragButton, 'dragstart', function (type, evt) { + domUtils.preventDefault(evt); + }); + var timer; + + function doClick(evt, button) { + // 部分浏览器下需要清理 + clearTimeout(timer); + timer = setTimeout(function () { + editor.fireEvent("tableClicked", table, button); + }, 300); + } + + function doDblClick(evt) { + clearTimeout(timer); + var ut = getUETable(table), + start = table.rows[0].cells[0], + end = ut.getLastCell(), + range = ut.getCellsRange(start, end); + editor.selection.getRange().setStart(start, 0).setCursor(false, true); + ut.setSelected(range); + } + + doc.body.appendChild(dragButton); + } + + +// function inPosition(table, pos) { +// var tablePos = domUtils.getXY(table), +// width = table.offsetWidth, +// height = table.offsetHeight; +// if (pos.x - tablePos.x < 5 && pos.y - tablePos.y < 5) { +// return "topLeft"; +// } else if (tablePos.x + width - pos.x < 5 && tablePos.y + height - pos.y < 5) { +// return "bottomRight"; +// } +// } + + function inTableSide(table, cell, evt, top) { + var pos = mouseCoords(evt), + state = getRelation(cell, pos); + + if (top) { + var caption = table.getElementsByTagName("caption")[0], + capHeight = caption ? caption.offsetHeight : 0; + return (state == "v1") && ((pos.y - domUtils.getXY(table).y - capHeight) < 8); + } else { + return (state == "h1") && ((pos.x - domUtils.getXY(table).x) < 8); + } + } + + /** + * 获取拖动时允许的X轴坐标 + * @param dragTd + * @param evt + */ + function getPermissionX(dragTd, evt) { + var ut = getUETable(dragTd); + if (ut) { + var preTd = ut.getSameEndPosCells(dragTd, "x")[0], + nextTd = ut.getSameStartPosXCells(dragTd)[0], + mouseX = mouseCoords(evt).x, + left = (preTd ? domUtils.getXY(preTd).x : domUtils.getXY(ut.table).x) + 20 , + right = nextTd ? domUtils.getXY(nextTd).x + nextTd.offsetWidth - 20 : (me.body.offsetWidth + 5 || parseInt(domUtils.getComputedStyle(me.body, "width"), 10)); + + left += cellMinWidth; + right -= cellMinWidth; + + return mouseX < left ? left : mouseX > right ? right : mouseX; + } + } + + /** + * 获取拖动时允许的Y轴坐标 + */ + function getPermissionY(dragTd, evt) { + try { + var top = domUtils.getXY(dragTd).y, + mousePosY = mouseCoords(evt).y; + return mousePosY < top ? top : mousePosY; + } catch (e) { + showError(e); + } + } + + /** + * 移动状态切换 + */ + function toggleDraggableState(editor, draggable, dir, mousePos, cell) { + try { + editor.body.style.cursor = dir == "h" ? "col-resize" : dir == "v" ? "row-resize" : "text"; + if (browser.ie) { + if (dir && !mousedown && !getUETableBySelected(editor)) { + getDragLine(editor, editor.document); + showDragLineAt(dir, cell); + } else { + hideDragLine(editor) + } + } + onBorder = draggable; + } catch (e) { + showError(e); + } + } + + /** + * 获取与UETable相关的resize line + * @param uetable UETable对象 + */ + function getResizeLineByUETable() { + + var lineId = '_UETableResizeLine', + line = this.document.getElementById( lineId ); + + if( !line ) { + line = this.document.createElement("div"); + line.id = lineId; + line.contnetEditable = false; + line.setAttribute("unselectable", "on"); + + var styles = { + width: 2*cellBorderWidth + 1 + 'px', + position: 'absolute', + 'z-index': 100000, + cursor: 'col-resize', + background: 'red', + display: 'none' + }; + + //切换状态 + line.onmouseout = function(){ + this.style.display = 'none'; + }; + + utils.extend( line.style, styles ); + + this.document.body.appendChild( line ); + + } + + return line; + + } + + /** + * 更新resize-line + */ + function updateResizeLine( cell, uetable ) { + + var line = getResizeLineByUETable.call( this ), + table = uetable.table, + styles = { + top: domUtils.getXY( table ).y + 'px', + left: domUtils.getXY( cell).x + cell.offsetWidth - cellBorderWidth + 'px', + display: 'block', + height: table.offsetHeight + 'px' + }; + + utils.extend( line.style, styles ); + + } + + /** + * 显示resize-line + */ + function showResizeLine( cell ) { + + var uetable = getUETable( cell ); + + updateResizeLine.call( this, cell, uetable ); + + } + + /** + * 获取鼠标与当前单元格的相对位置 + * @param ele + * @param mousePos + */ + function getRelation(ele, mousePos) { + var elePos = domUtils.getXY(ele); + + if( !elePos ) { + return ''; + } + + if (elePos.x + ele.offsetWidth - mousePos.x < cellBorderWidth) { + return "h"; + } + if (mousePos.x - elePos.x < cellBorderWidth) { + return 'h1' + } + if (elePos.y + ele.offsetHeight - mousePos.y < cellBorderWidth) { + return "v"; + } + if (mousePos.y - elePos.y < cellBorderWidth) { + return 'v1' + } + return ''; + } + + function mouseDownEvent(type, evt) { + + if( isEditorDisabled() ) { + return ; + } + + userActionStatus = { + x: evt.clientX, + y: evt.clientY + }; + + //右键菜单单独处理 + if (evt.button == 2) { + var ut = getUETableBySelected(me), + flag = false; + + if (ut) { + var td = getTargetTd(me, evt); + utils.each(ut.selectedTds, function (ti) { + if (ti === td) { + flag = true; + } + }); + if (!flag) { + removeSelectedClass(domUtils.getElementsByTagName(me.body, "th td")); + ut.clearSelected() + } else { + td = ut.selectedTds[0]; + setTimeout(function () { + me.selection.getRange().setStart(td, 0).setCursor(false, true); + }, 0); + + } + } + } else { + tableClickHander( evt ); + } + + } + + //清除表格的计时器 + function clearTableTimer() { + tabTimer && clearTimeout( tabTimer ); + tabTimer = null; + } + + //双击收缩 + function tableDbclickHandler(evt) { + singleClickState = 0; + evt = evt || me.window.event; + var target = getParentTdOrTh(evt.target || evt.srcElement); + if (target) { + var h; + if (h = getRelation(target, mouseCoords(evt))) { + + hideDragLine( me ); + + if (h == 'h1') { + h = 'h'; + if (inTableSide(domUtils.findParentByTagName(target, "table"), target, evt)) { + me.execCommand('adaptbywindow'); + } else { + target = getUETable(target).getPreviewCell(target); + if (target) { + var rng = me.selection.getRange(); + rng.selectNodeContents(target).setCursor(true, true) + } + } + } + if (h == 'h') { + var ut = getUETable(target), + table = ut.table, + cells = getCellsByMoveBorder( target, table, true ); + + cells = extractArray( cells, 'left' ); + + ut.width = ut.offsetWidth; + + var oldWidth = [], + newWidth = []; + + utils.each( cells, function( cell ){ + + oldWidth.push( cell.offsetWidth ); + + } ); + + utils.each( cells, function( cell ){ + + cell.removeAttribute("width"); + + } ); + + window.setTimeout( function(){ + + //是否允许改变 + var changeable = true; + + utils.each( cells, function( cell, index ){ + + var width = cell.offsetWidth; + + if( width > oldWidth[index] ) { + changeable = false; + return false; + } + + newWidth.push( width ); + + } ); + + var change = changeable ? newWidth : oldWidth; + + utils.each( cells, function( cell, index ){ + + cell.width = change[index] - getTabcellSpace(); + + } ); + + + }, 0 ); + +// minWidth -= cellMinWidth; +// +// table.removeAttribute("width"); +// utils.each(cells, function (cell) { +// cell.style.width = ""; +// cell.width -= minWidth; +// }); + + } + } + } + } + + function tableClickHander( evt ) { + + removeSelectedClass(domUtils.getElementsByTagName(me.body, "td th")); + //trace:3113 + //选中单元格,点击table外部,不会清掉table上挂的ueTable,会引起getUETableBySelected方法返回值 + utils.each(me.document.getElementsByTagName('table'), function (t) { + t.ueTable = null; + }); + startTd = getTargetTd(me, evt); + if( !startTd ) return; + var table = domUtils.findParentByTagName(startTd, "table", true); + ut = getUETable(table); + ut && ut.clearSelected(); + + //判断当前鼠标状态 + if (!onBorder) { + me.document.body.style.webkitUserSelect = ''; + mousedown = true; + me.addListener('mouseover', mouseOverEvent); + } else { + //边框上的动作处理 + borderActionHandler( evt ); + } + + + } + + //处理表格边框上的动作, 这里做延时处理,避免两种动作互相影响 + function borderActionHandler( evt ) { + + if ( browser.ie ) { + evt = reconstruct(evt ); + } + + clearTableDragTimer(); + + //是否正在等待resize的缓冲中 + isInResizeBuffer = true; + + tableDragTimer = setTimeout(function(){ + tableBorderDrag( evt ); + }, dblclickTime); + + } + + function extractArray( originArr, key ) { + + var result = [], + tmp = null; + + for( var i = 0, len = originArr.length; i 0 && singleClickState--; + }, dblclickTime ); + + if( singleClickState === 2 ) { + + singleClickState = 0; + tableDbclickHandler(evt); + return; + + } + + } + + if (evt.button == 2)return; + var me = this; + //清除表格上原生跨选问题 + var range = me.selection.getRange(), + start = domUtils.findParentByTagName(range.startContainer, 'table', true), + end = domUtils.findParentByTagName(range.endContainer, 'table', true); + + if (start || end) { + if (start === end) { + start = domUtils.findParentByTagName(range.startContainer, ['td', 'th', 'caption'], true); + end = domUtils.findParentByTagName(range.endContainer, ['td', 'th', 'caption'], true); + if (start !== end) { + me.selection.clearRange() + } + } else { + me.selection.clearRange() + } + } + mousedown = false; + me.document.body.style.webkitUserSelect = ''; + //拖拽状态下的mouseUP + if ( onDrag && dragTd ) { + + me.selection.getNative()[browser.ie9below ? 'empty' : 'removeAllRanges'](); + + singleClickState = 0; + dragLine = me.document.getElementById('ue_tableDragLine'); + + // trace 3973 + if (dragLine) { + var dragTdPos = domUtils.getXY(dragTd), + dragLinePos = domUtils.getXY(dragLine); + + switch (onDrag) { + case "h": + changeColWidth(dragTd, dragLinePos.x - dragTdPos.x); + break; + case "v": + changeRowHeight(dragTd, dragLinePos.y - dragTdPos.y - dragTd.offsetHeight); + break; + default: + } + onDrag = ""; + dragTd = null; + + hideDragLine(me); + me.fireEvent('saveScene'); + return; + } + } + //正常状态下的mouseup + if (!startTd) { + var target = domUtils.findParentByTagName(evt.target || evt.srcElement, "td", true); + if (!target) target = domUtils.findParentByTagName(evt.target || evt.srcElement, "th", true); + if (target && (target.tagName == "TD" || target.tagName == "TH")) { + if (me.fireEvent("excludetable", target) === true) return; + range = new dom.Range(me.document); + range.setStart(target, 0).setCursor(false, true); + } + } else { + var ut = getUETable(startTd), + cell = ut ? ut.selectedTds[0] : null; + if (cell) { + range = new dom.Range(me.document); + if (domUtils.isEmptyBlock(cell)) { + range.setStart(cell, 0).setCursor(false, true); + } else { + range.selectNodeContents(cell).shrinkBoundary().setCursor(false, true); + } + } else { + range = me.selection.getRange().shrinkBoundary(); + if (!range.collapsed) { + var start = domUtils.findParentByTagName(range.startContainer, ['td', 'th'], true), + end = domUtils.findParentByTagName(range.endContainer, ['td', 'th'], true); + //在table里边的不能清除 + if (start && !end || !start && end || start && end && start !== end) { + range.setCursor(false, true); + } + } + } + startTd = null; + me.removeListener('mouseover', mouseOverEvent); + } + me._selectionChange(250, evt); + } + + function mouseOverEvent(type, evt) { + + if( isEditorDisabled() ) { + return; + } + + var me = this, + tar = evt.target || evt.srcElement; + currentTd = domUtils.findParentByTagName(tar, "td", true) || domUtils.findParentByTagName(tar, "th", true); + //需要判断两个TD是否位于同一个表格内 + if (startTd && currentTd && + ((startTd.tagName == "TD" && currentTd.tagName == "TD") || (startTd.tagName == "TH" && currentTd.tagName == "TH")) && + domUtils.findParentByTagName(startTd, 'table') == domUtils.findParentByTagName(currentTd, 'table')) { + var ut = getUETable(currentTd); + if (startTd != currentTd) { + me.document.body.style.webkitUserSelect = 'none'; + me.selection.getNative()[browser.ie9below ? 'empty' : 'removeAllRanges'](); + var range = ut.getCellsRange(startTd, currentTd); + ut.setSelected(range); + } else { + me.document.body.style.webkitUserSelect = ''; + ut.clearSelected(); + } + + } + evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false); + } + + function setCellHeight(cell, height, backHeight) { + var lineHight = parseInt(domUtils.getComputedStyle(cell, "line-height"), 10), + tmpHeight = backHeight + height; + height = tmpHeight < lineHight ? lineHight : tmpHeight; + if (cell.style.height) cell.style.height = ""; + cell.rowSpan == 1 ? cell.setAttribute("height", height) : (cell.removeAttribute && cell.removeAttribute("height")); + } + + function getWidth(cell) { + if (!cell)return 0; + return parseInt(domUtils.getComputedStyle(cell, "width"), 10); + } + + function changeColWidth(cell, changeValue) { + + var ut = getUETable(cell); + if (ut) { + + //根据当前移动的边框获取相关的单元格 + var table = ut.table, + cells = getCellsByMoveBorder( cell, table ); + + table.style.width = ""; + table.removeAttribute("width"); + + //修正改变量 + changeValue = correctChangeValue( changeValue, cell, cells ); + + if (cell.nextSibling) { + + var i=0; + + utils.each( cells, function( cellGroup ){ + + cellGroup.left.width = (+cellGroup.left.width)+changeValue; + cellGroup.right && ( cellGroup.right.width = (+cellGroup.right.width)-changeValue ); + + } ); + + } else { + + utils.each( cells, function( cellGroup ){ + cellGroup.left.width -= -changeValue; + } ); + + } + } + + } + + function isEditorDisabled() { + return me.body.contentEditable === "false"; + } + + function changeRowHeight(td, changeValue) { + if (Math.abs(changeValue) < 10) return; + var ut = getUETable(td); + if (ut) { + var cells = ut.getSameEndPosCells(td, "y"), + //备份需要连带变化的td的原始高度,否则后期无法获取正确的值 + backHeight = cells[0] ? cells[0].offsetHeight : 0; + for (var i = 0, cell; cell = cells[i++];) { + setCellHeight(cell, changeValue, backHeight); + } + } + + } + + /** + * 获取调整单元格大小的相关单元格 + * @isContainMergeCell 返回的结果中是否包含发生合并后的单元格 + */ + function getCellsByMoveBorder( cell, table, isContainMergeCell ) { + + if( !table ) { + table = domUtils.findParentByTagName( cell, 'table' ); + } + + if( !table ) { + return null; + } + + //获取到该单元格所在行的序列号 + var index = domUtils.getNodeIndex( cell ), + temp = cell, + rows = table.rows, + colIndex = 0; + + while( temp ) { + //获取到当前单元格在未发生单元格合并时的序列 + if( temp.nodeType === 1 ) { + colIndex += (temp.colSpan || 1); + } + temp = temp.previousSibling; + } + + temp = null; + + //记录想关的单元格 + var borderCells = []; + + utils.each(rows, function( tabRow ){ + + var cells = tabRow.cells, + currIndex = 0; + + utils.each( cells, function( tabCell ){ + + currIndex += (tabCell.colSpan || 1); + + if( currIndex === colIndex ) { + + borderCells.push({ + left: tabCell, + right: tabCell.nextSibling || null + }); + + return false; + + } else if( currIndex > colIndex ) { + + if( isContainMergeCell ) { + borderCells.push({ + left: tabCell + }); + } + + return false; + } + + + } ); + + }); + + return borderCells; + + } + + + /** + * 通过给定的单元格集合获取最小的单元格width + */ + function getMinWidthByTableCells( cells ) { + + var minWidth = Number.MAX_VALUE; + + for( var i = 0, curCell; curCell = cells[ i ] ; i++ ) { + + minWidth = Math.min( minWidth, curCell.width || getTableCellWidth( curCell ) ); + + } + + return minWidth; + + } + + function correctChangeValue( changeValue, relatedCell, cells ) { + + //为单元格的paading预留空间 + changeValue -= getTabcellSpace(); + + if( changeValue < 0 ) { + return 0; + } + + changeValue -= getTableCellWidth( relatedCell ); + + //确定方向 + var direction = changeValue < 0 ? 'left':'right'; + + changeValue = Math.abs(changeValue); + + //只关心非最后一个单元格就可以 + utils.each( cells, function( cellGroup ){ + + var curCell = cellGroup[direction]; + + //为单元格保留最小空间 + if( curCell ) { + changeValue = Math.min( changeValue, getTableCellWidth( curCell )-cellMinWidth ); + } + + + } ); + + + //修正越界 + changeValue = changeValue < 0 ? 0 : changeValue; + + return direction === 'left' ? -changeValue : changeValue; + + } + + function getTableCellWidth( cell ) { + + var width = 0, + //偏移纠正量 + offset = 0, + width = cell.offsetWidth - getTabcellSpace(); + + //最后一个节点纠正一下 + if( !cell.nextSibling ) { + + width -= getTableCellOffset( cell ); + + } + + width = width < 0 ? 0 : width; + + try { + cell.width = width; + } catch(e) { + } + + return width; + + } + + /** + * 获取单元格所在表格的最末单元格的偏移量 + */ + function getTableCellOffset( cell ) { + + tab = domUtils.findParentByTagName( cell, "table", false); + + if( tab.offsetVal === undefined ) { + + var prev = cell.previousSibling; + + if( prev ) { + + //最后一个单元格和前一个单元格的width diff结果 如果恰好为一个border width, 则条件成立 + tab.offsetVal = cell.offsetWidth - prev.offsetWidth === UT.borderWidth ? UT.borderWidth : 0; + + } else { + tab.offsetVal = 0; + } + + } + + return tab.offsetVal; + + } + + function getTabcellSpace() { + + if( UT.tabcellSpace === undefined ) { + + var cell = null, + tab = me.document.createElement("table"), + tbody = me.document.createElement("tbody"), + trow = me.document.createElement("tr"), + tabcell = me.document.createElement("td"), + mirror = null; + + tabcell.style.cssText = 'border: 0;'; + tabcell.width = 1; + + trow.appendChild( tabcell ); + trow.appendChild( mirror = tabcell.cloneNode( false ) ); + + tbody.appendChild( trow ); + + tab.appendChild( tbody ); + + tab.style.cssText = "visibility: hidden;"; + + me.body.appendChild( tab ); + + UT.paddingSpace = tabcell.offsetWidth - 1; + + var tmpTabWidth = tab.offsetWidth; + + tabcell.style.cssText = ''; + mirror.style.cssText = ''; + + UT.borderWidth = ( tab.offsetWidth - tmpTabWidth ) / 3; + + UT.tabcellSpace = UT.paddingSpace + UT.borderWidth; + + me.body.removeChild( tab ); + + } + + getTabcellSpace = function(){ return UT.tabcellSpace; }; + + return UT.tabcellSpace; + + } + + function getDragLine(editor, doc) { + if (mousedown)return; + dragLine = editor.document.createElement("div"); + domUtils.setAttributes(dragLine, { + id:"ue_tableDragLine", + unselectable:'on', + contenteditable:false, + 'onresizestart':'return false', + 'ondragstart':'return false', + 'onselectstart':'return false', + style:"background-color:blue;position:absolute;padding:0;margin:0;background-image:none;border:0px none;opacity:0;filter:alpha(opacity=0)" + }); + editor.body.appendChild(dragLine); + } + + function hideDragLine(editor) { + if (mousedown)return; + var line; + while (line = editor.document.getElementById('ue_tableDragLine')) { + domUtils.remove(line) + } + } + + /** + * 依据state(v|h)在cell位置显示横线 + * @param state + * @param cell + */ + function showDragLineAt(state, cell) { + if (!cell) return; + var table = domUtils.findParentByTagName(cell, "table"), + caption = table.getElementsByTagName('caption'), + width = table.offsetWidth, + height = table.offsetHeight - (caption.length > 0 ? caption[0].offsetHeight : 0), + tablePos = domUtils.getXY(table), + cellPos = domUtils.getXY(cell), css; + switch (state) { + case "h": + css = 'height:' + height + 'px;top:' + (tablePos.y + (caption.length > 0 ? caption[0].offsetHeight : 0)) + 'px;left:' + (cellPos.x + cell.offsetWidth); + dragLine.style.cssText = css + 'px;position: absolute;display:block;background-color:blue;width:1px;border:0; color:blue;opacity:.3;filter:alpha(opacity=30)'; + break; + case "v": + css = 'width:' + width + 'px;left:' + tablePos.x + 'px;top:' + (cellPos.y + cell.offsetHeight ); + //必须加上border:0和color:blue,否则低版ie不支持背景色显示 + dragLine.style.cssText = css + 'px;overflow:hidden;position: absolute;display:block;background-color:blue;height:1px;border:0;color:blue;opacity:.2;filter:alpha(opacity=20)'; + break; + default: + } + } + + /** + * 当表格边框颜色为白色时设置为虚线,true为添加虚线 + * @param editor + * @param flag + */ + function switchBorderColor(editor, flag) { + var tableArr = domUtils.getElementsByTagName(editor.body, "table"), color; + for (var i = 0, node; node = tableArr[i++];) { + var td = domUtils.getElementsByTagName(node, "td"); + if (td[0]) { + if (flag) { + color = (td[0].style.borderColor).replace(/\s/g, ""); + if (/(#ffffff)|(rgb\(255,255,255\))/ig.test(color)) + domUtils.addClass(node, "noBorderTable") + } else { + domUtils.removeClasses(node, "noBorderTable") + } + } + + } + } + + function getTableWidth(editor, needIEHack, defaultValue) { + var body = editor.body; + return body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (editor.options.offsetWidth || 0); + } + + /** + * 获取当前拖动的单元格 + */ + function getTargetTd(editor, evt) { + + var target = domUtils.findParentByTagName(evt.target || evt.srcElement, ["td", "th"], true), + dir = null; + + if( !target ) { + return null; + } + + dir = getRelation( target, mouseCoords( evt ) ); + + //如果有前一个节点, 需要做一个修正, 否则可能会得到一个错误的td + + if( !target ) { + return null; + } + + if( dir === 'h1' && target.previousSibling ) { + + var position = domUtils.getXY( target), + cellWidth = target.offsetWidth; + + if( Math.abs( position.x + cellWidth - evt.clientX ) > cellWidth / 3 ) { + target = target.previousSibling; + } + + } else if( dir === 'v1' && target.parentNode.previousSibling ) { + + var position = domUtils.getXY( target), + cellHeight = target.offsetHeight; + + if( Math.abs( position.y + cellHeight - evt.clientY ) > cellHeight / 3 ) { + target = target.parentNode.previousSibling.firstChild; + } + + } + + + //排除了非td内部以及用于代码高亮部分的td + return target && !(editor.fireEvent("excludetable", target) === true) ? target : null; + } + +}; + + +// plugins/table.sort.js +/** + * Created with JetBrains PhpStorm. + * User: Jinqn + * Date: 13-10-12 + * Time: 上午10:20 + * To change this template use File | Settings | File Templates. + */ + +UE.UETable.prototype.sortTable = function (sortByCellIndex, compareFn) { + var table = this.table, + rows = table.rows, + trArray = [], + flag = rows[0].cells[0].tagName === "TH", + lastRowIndex = 0; + if(this.selectedTds.length){ + var range = this.cellsRange, + len = range.endRowIndex + 1; + for (var i = range.beginRowIndex; i < len; i++) { + trArray[i] = rows[i]; + } + trArray.splice(0,range.beginRowIndex); + lastRowIndex = (range.endRowIndex +1) === this.rowsNum ? 0 : range.endRowIndex +1; + }else{ + for (var i = 0,len = rows.length; i < len; i++) { + trArray[i] = rows[i]; + } + } + + var Fn = { + 'reversecurrent': function(td1,td2){ + return 1; + }, + 'orderbyasc': function(td1,td2){ + var value1 = td1.innerText||td1.textContent, + value2 = td2.innerText||td2.textContent; + return value1.localeCompare(value2); + }, + 'reversebyasc': function(td1,td2){ + var value1 = td1.innerHTML, + value2 = td2.innerHTML; + return value2.localeCompare(value1); + }, + 'orderbynum': function(td1,td2){ + var value1 = td1[browser.ie ? 'innerText':'textContent'].match(/\d+/), + value2 = td2[browser.ie ? 'innerText':'textContent'].match(/\d+/); + if(value1) value1 = +value1[0]; + if(value2) value2 = +value2[0]; + return (value1||0) - (value2||0); + }, + 'reversebynum': function(td1,td2){ + var value1 = td1[browser.ie ? 'innerText':'textContent'].match(/\d+/), + value2 = td2[browser.ie ? 'innerText':'textContent'].match(/\d+/); + if(value1) value1 = +value1[0]; + if(value2) value2 = +value2[0]; + return (value2||0) - (value1||0); + } + }; + + //对表格设置排序的标记data-sort-type + table.setAttribute('data-sort-type', compareFn && typeof compareFn === "string" && Fn[compareFn] ? compareFn:''); + + //th不参与排序 + flag && trArray.splice(0, 1); + trArray = utils.sort(trArray,function (tr1, tr2) { + var result; + if (compareFn && typeof compareFn === "function") { + result = compareFn.call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]); + } else if (compareFn && typeof compareFn === "number") { + result = 1; + } else if (compareFn && typeof compareFn === "string" && Fn[compareFn]) { + result = Fn[compareFn].call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]); + } else { + result = Fn['orderbyasc'].call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]); + } + return result; + }); + var fragment = table.ownerDocument.createDocumentFragment(); + for (var j = 0, len = trArray.length; j < len; j++) { + fragment.appendChild(trArray[j]); + } + var tbody = table.getElementsByTagName("tbody")[0]; + if(!lastRowIndex){ + tbody.appendChild(fragment); + }else{ + tbody.insertBefore(fragment,rows[lastRowIndex- range.endRowIndex + range.beginRowIndex - 1]) + } +}; + +UE.plugins['tablesort'] = function () { + var me = this, + UT = UE.UETable, + getUETable = function (tdOrTable) { + return UT.getUETable(tdOrTable); + }, + getTableItemsByRange = function (editor) { + return UT.getTableItemsByRange(editor); + }; + + + me.ready(function () { + //添加表格可排序的样式 + utils.cssRule('tablesort', + 'table.sortEnabled tr.firstRow th,table.sortEnabled tr.firstRow td{padding-right:20px;background-repeat: no-repeat;background-position: center right;' + + ' background-image:url(' + me.options.themePath + me.options.theme + '/images/sortable.png);}', + me.document); + + //做单元格合并操作时,清除可排序标识 + me.addListener("afterexeccommand", function (type, cmd) { + if( cmd == 'mergeright' || cmd == 'mergedown' || cmd == 'mergecells') { + this.execCommand('disablesort'); + } + }); + }); + + + + //表格排序 + UE.commands['sorttable'] = { + queryCommandState: function () { + var me = this, + tableItems = getTableItemsByRange(me); + if (!tableItems.cell) return -1; + var table = tableItems.table, + cells = table.getElementsByTagName("td"); + for (var i = 0, cell; cell = cells[i++];) { + if (cell.rowSpan != 1 || cell.colSpan != 1) return -1; + } + return 0; + }, + execCommand: function (cmd, fn) { + var me = this, + range = me.selection.getRange(), + bk = range.createBookmark(true), + tableItems = getTableItemsByRange(me), + cell = tableItems.cell, + ut = getUETable(tableItems.table), + cellInfo = ut.getCellInfo(cell); + ut.sortTable(cellInfo.cellIndex, fn); + range.moveToBookmark(bk); + try{ + range.select(); + }catch(e){} + } + }; + + //设置表格可排序,清除表格可排序 + UE.commands["enablesort"] = UE.commands["disablesort"] = { + queryCommandState: function (cmd) { + var table = getTableItemsByRange(this).table; + if(table && cmd=='enablesort') { + var cells = domUtils.getElementsByTagName(table, 'th td'); + for(var i = 0; i1 || cells[i].getAttribute('rowspan')>1) return -1; + } + } + + return !table ? -1: cmd=='enablesort' ^ table.getAttribute('data-sort')!='sortEnabled' ? -1:0; + }, + execCommand: function (cmd) { + var table = getTableItemsByRange(this).table; + table.setAttribute("data-sort", cmd == "enablesort" ? "sortEnabled" : "sortDisabled"); + cmd == "enablesort" ? domUtils.addClass(table,"sortEnabled"):domUtils.removeClasses(table,"sortEnabled"); + } + }; +}; + + +// plugins/contextmenu.js +///import core +///commands 右键菜单 +///commandsName ContextMenu +///commandsTitle 右键菜单 +/** + * 右键菜单 + * @function + * @name baidu.editor.plugins.contextmenu + * @author zhanyi + */ + +UE.plugins['contextmenu'] = function () { + var me = this; + me.setOpt('enableContextMenu',true); + if(me.getOpt('enableContextMenu') === false){ + return; + } + var lang = me.getLang( "contextMenu" ), + menu, + items = me.options.contextMenu || [ + {label:lang['selectall'], cmdName:'selectall'}, + { + label:lang.cleardoc, + cmdName:'cleardoc', + exec:function () { + if ( confirm( lang.confirmclear ) ) { + this.execCommand( 'cleardoc' ); + } + } + }, + '-', + { + label:lang.unlink, + cmdName:'unlink' + }, + '-', + { + group:lang.paragraph, + icon:'justifyjustify', + subMenu:[ + { + label:lang.justifyleft, + cmdName:'justify', + value:'left' + }, + { + label:lang.justifyright, + cmdName:'justify', + value:'right' + }, + { + label:lang.justifycenter, + cmdName:'justify', + value:'center' + }, + { + label:lang.justifyjustify, + cmdName:'justify', + value:'justify' + } + ] + }, + '-', + { + group:lang.table, + icon:'table', + subMenu:[ + { + label:lang.inserttable, + cmdName:'inserttable' + }, + { + label:lang.deletetable, + cmdName:'deletetable' + }, + '-', + { + label:lang.deleterow, + cmdName:'deleterow' + }, + { + label:lang.deletecol, + cmdName:'deletecol' + }, + { + label:lang.insertcol, + cmdName:'insertcol' + }, + { + label:lang.insertcolnext, + cmdName:'insertcolnext' + }, + { + label:lang.insertrow, + cmdName:'insertrow' + }, + { + label:lang.insertrownext, + cmdName:'insertrownext' + }, + '-', + { + label:lang.insertcaption, + cmdName:'insertcaption' + }, + { + label:lang.deletecaption, + cmdName:'deletecaption' + }, + { + label:lang.inserttitle, + cmdName:'inserttitle' + }, + { + label:lang.deletetitle, + cmdName:'deletetitle' + }, + { + label:lang.inserttitlecol, + cmdName:'inserttitlecol' + }, + { + label:lang.deletetitlecol, + cmdName:'deletetitlecol' + }, + '-', + { + label:lang.mergecells, + cmdName:'mergecells' + }, + { + label:lang.mergeright, + cmdName:'mergeright' + }, + { + label:lang.mergedown, + cmdName:'mergedown' + }, + '-', + { + label:lang.splittorows, + cmdName:'splittorows' + }, + { + label:lang.splittocols, + cmdName:'splittocols' + }, + { + label:lang.splittocells, + cmdName:'splittocells' + }, + '-', + { + label:lang.averageDiseRow, + cmdName:'averagedistributerow' + }, + { + label:lang.averageDisCol, + cmdName:'averagedistributecol' + }, + '-', + { + label:lang.edittd, + cmdName:'edittd', + exec:function () { + if ( UE.ui['edittd'] ) { + new UE.ui['edittd']( this ); + } + this.getDialog('edittd').open(); + } + }, + { + label:lang.edittable, + cmdName:'edittable', + exec:function () { + if ( UE.ui['edittable'] ) { + new UE.ui['edittable']( this ); + } + this.getDialog('edittable').open(); + } + }, + { + label:lang.setbordervisible, + cmdName:'setbordervisible' + } + ] + }, + { + group:lang.tablesort, + icon:'tablesort', + subMenu:[ + { + label:lang.enablesort, + cmdName:'enablesort' + }, + { + label:lang.disablesort, + cmdName:'disablesort' + }, + '-', + { + label:lang.reversecurrent, + cmdName:'sorttable', + value:'reversecurrent' + }, + { + label:lang.orderbyasc, + cmdName:'sorttable', + value:'orderbyasc' + }, + { + label:lang.reversebyasc, + cmdName:'sorttable', + value:'reversebyasc' + }, + { + label:lang.orderbynum, + cmdName:'sorttable', + value:'orderbynum' + }, + { + label:lang.reversebynum, + cmdName:'sorttable', + value:'reversebynum' + } + ] + }, + { + group:lang.borderbk, + icon:'borderBack', + subMenu:[ + { + label:lang.setcolor, + cmdName:"interlacetable", + exec:function(){ + this.execCommand("interlacetable"); + } + }, + { + label:lang.unsetcolor, + cmdName:"uninterlacetable", + exec:function(){ + this.execCommand("uninterlacetable"); + } + }, + { + label:lang.setbackground, + cmdName:"settablebackground", + exec:function(){ + this.execCommand("settablebackground",{repeat:true,colorList:["#bbb","#ccc"]}); + } + }, + { + label:lang.unsetbackground, + cmdName:"cleartablebackground", + exec:function(){ + this.execCommand("cleartablebackground"); + } + }, + { + label:lang.redandblue, + cmdName:"settablebackground", + exec:function(){ + this.execCommand("settablebackground",{repeat:true,colorList:["red","blue"]}); + } + }, + { + label:lang.threecolorgradient, + cmdName:"settablebackground", + exec:function(){ + this.execCommand("settablebackground",{repeat:true,colorList:["#aaa","#bbb","#ccc"]}); + } + } + ] + }, + { + group:lang.aligntd, + icon:'aligntd', + subMenu:[ + { + cmdName:'cellalignment', + value:{align:'left',vAlign:'top'} + }, + { + cmdName:'cellalignment', + value:{align:'center',vAlign:'top'} + }, + { + cmdName:'cellalignment', + value:{align:'right',vAlign:'top'} + }, + { + cmdName:'cellalignment', + value:{align:'left',vAlign:'middle'} + }, + { + cmdName:'cellalignment', + value:{align:'center',vAlign:'middle'} + }, + { + cmdName:'cellalignment', + value:{align:'right',vAlign:'middle'} + }, + { + cmdName:'cellalignment', + value:{align:'left',vAlign:'bottom'} + }, + { + cmdName:'cellalignment', + value:{align:'center',vAlign:'bottom'} + }, + { + cmdName:'cellalignment', + value:{align:'right',vAlign:'bottom'} + } + ] + }, + { + group:lang.aligntable, + icon:'aligntable', + subMenu:[ + { + cmdName:'tablealignment', + className: 'left', + label:lang.tableleft, + value:"left" + }, + { + cmdName:'tablealignment', + className: 'center', + label:lang.tablecenter, + value:"center" + }, + { + cmdName:'tablealignment', + className: 'right', + label:lang.tableright, + value:"right" + } + ] + }, + '-', + { + label:lang.insertparagraphbefore, + cmdName:'insertparagraph', + value:true + }, + { + label:lang.insertparagraphafter, + cmdName:'insertparagraph' + }, + { + label:lang['copy'], + cmdName:'copy' + }, + { + label:lang['paste'], + cmdName:'paste' + } + ]; + if ( !items.length ) { + return; + } + var uiUtils = UE.ui.uiUtils; + + me.addListener( 'contextmenu', function ( type, evt ) { + + var offset = uiUtils.getViewportOffsetByEvent( evt ); + me.fireEvent( 'beforeselectionchange' ); + if ( menu ) { + menu.destroy(); + } + for ( var i = 0, ti, contextItems = []; ti = items[i]; i++ ) { + var last; + (function ( item ) { + if ( item == '-' ) { + if ( (last = contextItems[contextItems.length - 1 ] ) && last !== '-' ) { + contextItems.push( '-' ); + } + } else if ( item.hasOwnProperty( "group" ) ) { + for ( var j = 0, cj, subMenu = []; cj = item.subMenu[j]; j++ ) { + (function ( subItem ) { + if ( subItem == '-' ) { + if ( (last = subMenu[subMenu.length - 1 ] ) && last !== '-' ) { + subMenu.push( '-' ); + }else{ + subMenu.splice(subMenu.length-1); + } + } else { + if ( (me.commands[subItem.cmdName] || UE.commands[subItem.cmdName] || subItem.query) && + (subItem.query ? subItem.query() : me.queryCommandState( subItem.cmdName )) > -1 ) { + subMenu.push( { + 'label':subItem.label || me.getLang( "contextMenu." + subItem.cmdName + (subItem.value || '') )||"", + 'className':'edui-for-' +subItem.cmdName + ( subItem.className ? ( ' edui-for-' + subItem.cmdName + '-' + subItem.className ) : '' ), + onclick:subItem.exec ? function () { + subItem.exec.call( me ); + } : function () { + me.execCommand( subItem.cmdName, subItem.value ); + } + } ); + } + } + })( cj ); + } + if ( subMenu.length ) { + function getLabel(){ + switch (item.icon){ + case "table": + return me.getLang( "contextMenu.table" ); + case "justifyjustify": + return me.getLang( "contextMenu.paragraph" ); + case "aligntd": + return me.getLang("contextMenu.aligntd"); + case "aligntable": + return me.getLang("contextMenu.aligntable"); + case "tablesort": + return lang.tablesort; + case "borderBack": + return lang.borderbk; + default : + return ''; + } + } + contextItems.push( { + //todo 修正成自动获取方式 + 'label':getLabel(), + className:'edui-for-' + item.icon, + 'subMenu':{ + items:subMenu, + editor:me + } + } ); + } + + } else { + //有可能commmand没有加载右键不能出来,或者没有command也想能展示出来添加query方法 + if ( (me.commands[item.cmdName] || UE.commands[item.cmdName] || item.query) && + (item.query ? item.query.call(me) : me.queryCommandState( item.cmdName )) > -1 ) { + + contextItems.push( { + 'label':item.label || me.getLang( "contextMenu." + item.cmdName ), + className:'edui-for-' + (item.icon ? item.icon : item.cmdName + (item.value || '')), + onclick:item.exec ? function () { + item.exec.call( me ); + } : function () { + me.execCommand( item.cmdName, item.value ); + } + } ); + } + + } + + })( ti ); + } + if ( contextItems[contextItems.length - 1] == '-' ) { + contextItems.pop(); + } + + menu = new UE.ui.Menu( { + items:contextItems, + className:"edui-contextmenu", + editor:me + } ); + menu.render(); + menu.showAt( offset ); + + me.fireEvent("aftershowcontextmenu",menu); + + domUtils.preventDefault( evt ); + if ( browser.ie ) { + var ieRange; + try { + ieRange = me.selection.getNative().createRange(); + } catch ( e ) { + return; + } + if ( ieRange.item ) { + var range = new dom.Range( me.document ); + range.selectNode( ieRange.item( 0 ) ).select( true, true ); + } + } + }); + + // 添加复制的flash按钮 + me.addListener('aftershowcontextmenu', function(type, menu) { + if (me.zeroclipboard) { + var items = menu.items; + for (var key in items) { + if (items[key].className == 'edui-for-copy') { + me.zeroclipboard.clip(items[key].getDom()); + } + } + } + }); + +}; + + +// plugins/shortcutmenu.js +///import core +///commands 弹出菜单 +// commandsName popupmenu +///commandsTitle 弹出菜单 +/** + * 弹出菜单 + * @function + * @name baidu.editor.plugins.popupmenu + * @author xuheng + */ + +UE.plugins['shortcutmenu'] = function () { + var me = this, + menu, + items = me.options.shortcutMenu || []; + + if (!items.length) { + return; + } + + me.addListener ('contextmenu mouseup' , function (type , e) { + var me = this, + customEvt = { + type : type , + target : e.target || e.srcElement , + screenX : e.screenX , + screenY : e.screenY , + clientX : e.clientX , + clientY : e.clientY + }; + + setTimeout (function () { + var rng = me.selection.getRange (); + if (rng.collapsed === false || type == "contextmenu") { + + if (!menu) { + menu = new baidu.editor.ui.ShortCutMenu ({ + editor : me , + items : items , + theme : me.options.theme , + className : 'edui-shortcutmenu' + }); + + menu.render (); + me.fireEvent ("afterrendershortcutmenu" , menu); + } + + menu.show (customEvt , !!UE.plugins['contextmenu']); + } + }); + + if (type == 'contextmenu') { + domUtils.preventDefault (e); + if (browser.ie9below) { + var ieRange; + try { + ieRange = me.selection.getNative().createRange(); + } catch (e) { + return; + } + if (ieRange.item) { + var range = new dom.Range (me.document); + range.selectNode (ieRange.item (0)).select (true , true); + + } + } + } + }); + + me.addListener ('keydown' , function (type) { + if (type == "keydown") { + menu && !menu.isHidden && menu.hide (); + } + + }); + +}; + + + + +// plugins/basestyle.js +/** + * B、I、sub、super命令支持 + * @file + * @since 1.2.6.1 + */ + +UE.plugins['basestyle'] = function(){ + + /** + * 字体加粗 + * @command bold + * @param { String } cmd 命令字符串 + * @remind 对已加粗的文本内容执行该命令, 将取消加粗 + * @method execCommand + * @example + * ```javascript + * //editor是编辑器实例 + * //对当前选中的文本内容执行加粗操作 + * //第一次执行, 文本内容加粗 + * editor.execCommand( 'bold' ); + * + * //第二次执行, 文本内容取消加粗 + * editor.execCommand( 'bold' ); + * ``` + */ + + + /** + * 字体倾斜 + * @command italic + * @method execCommand + * @param { String } cmd 命令字符串 + * @remind 对已倾斜的文本内容执行该命令, 将取消倾斜 + * @example + * ```javascript + * //editor是编辑器实例 + * //对当前选中的文本内容执行斜体操作 + * //第一次操作, 文本内容将变成斜体 + * editor.execCommand( 'italic' ); + * + * //再次对同一文本内容执行, 则文本内容将恢复正常 + * editor.execCommand( 'italic' ); + * ``` + */ + + /** + * 下标文本,与“superscript”命令互斥 + * @command subscript + * @method execCommand + * @remind 把选中的文本内容切换成下标文本, 如果当前选中的文本已经是下标, 则该操作会把文本内容还原成正常文本 + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * //editor是编辑器实例 + * //对当前选中的文本内容执行下标操作 + * //第一次操作, 文本内容将变成下标文本 + * editor.execCommand( 'subscript' ); + * + * //再次对同一文本内容执行, 则文本内容将恢复正常 + * editor.execCommand( 'subscript' ); + * ``` + */ + + /** + * 上标文本,与“subscript”命令互斥 + * @command superscript + * @method execCommand + * @remind 把选中的文本内容切换成上标文本, 如果当前选中的文本已经是上标, 则该操作会把文本内容还原成正常文本 + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * //editor是编辑器实例 + * //对当前选中的文本内容执行上标操作 + * //第一次操作, 文本内容将变成上标文本 + * editor.execCommand( 'superscript' ); + * + * //再次对同一文本内容执行, 则文本内容将恢复正常 + * editor.execCommand( 'superscript' ); + * ``` + */ + var basestyles = { + 'bold':['strong','b'], + 'italic':['em','i'], + 'subscript':['sub'], + 'superscript':['sup'] + }, + getObj = function(editor,tagNames){ + return domUtils.filterNodeList(editor.selection.getStartElementPath(),tagNames); + }, + me = this; + //添加快捷键 + me.addshortcutkey({ + "Bold" : "ctrl+66",//^B + "Italic" : "ctrl+73", //^I + "Underline" : "ctrl+85"//^U + }); + me.addInputRule(function(root){ + utils.each(root.getNodesByTagName('b i'),function(node){ + switch (node.tagName){ + case 'b': + node.tagName = 'strong'; + break; + case 'i': + node.tagName = 'em'; + } + }); + }); + for ( var style in basestyles ) { + (function( cmd, tagNames ) { + me.commands[cmd] = { + execCommand : function( cmdName ) { + var range = me.selection.getRange(),obj = getObj(this,tagNames); + if ( range.collapsed ) { + if ( obj ) { + var tmpText = me.document.createTextNode(''); + range.insertNode( tmpText ).removeInlineStyle( tagNames ); + range.setStartBefore(tmpText); + domUtils.remove(tmpText); + } else { + var tmpNode = range.document.createElement( tagNames[0] ); + if(cmdName == 'superscript' || cmdName == 'subscript'){ + tmpText = me.document.createTextNode(''); + range.insertNode(tmpText) + .removeInlineStyle(['sub','sup']) + .setStartBefore(tmpText) + .collapse(true); + } + range.insertNode( tmpNode ).setStart( tmpNode, 0 ); + } + range.collapse( true ); + } else { + if(cmdName == 'superscript' || cmdName == 'subscript'){ + if(!obj || obj.tagName.toLowerCase() != cmdName){ + range.removeInlineStyle(['sub','sup']); + } + } + obj ? range.removeInlineStyle( tagNames ) : range.applyInlineStyle( tagNames[0] ); + } + range.select(); + }, + queryCommandState : function() { + return getObj(this,tagNames) ? 1 : 0; + } + }; + })( style, basestyles[style] ); + } +}; + + + +// plugins/elementpath.js +/** + * 选取路径命令 + * @file + */ +UE.plugins['elementpath'] = function(){ + var currentLevel, + tagNames, + me = this; + me.setOpt('elementPathEnabled',true); + if(!me.options.elementPathEnabled){ + return; + } + me.commands['elementpath'] = { + execCommand : function( cmdName, level ) { + var start = tagNames[level], + range = me.selection.getRange(); + currentLevel = level*1; + range.selectNode(start).select(); + }, + queryCommandValue : function() { + //产生一个副本,不能修改原来的startElementPath; + var parents = [].concat(this.selection.getStartElementPath()).reverse(), + names = []; + tagNames = parents; + for(var i=0,ci;ci=parents[i];i++){ + if(ci.nodeType == 3) { + continue; + } + var name = ci.tagName.toLowerCase(); + if(name == 'img' && ci.getAttribute('anchorname')){ + name = 'anchor'; + } + names[i] = name; + if(currentLevel == i){ + currentLevel = -1; + break; + } + } + return names; + } + }; +}; + + + +// plugins/formatmatch.js +/** + * 格式刷,只格式inline的 + * @file + * @since 1.2.6.1 + */ + +/** + * 格式刷 + * @command formatmatch + * @method execCommand + * @remind 该操作不能复制段落格式 + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * //editor是编辑器实例 + * //获取格式刷 + * editor.execCommand( 'formatmatch' ); + * ``` + */ +UE.plugins['formatmatch'] = function(){ + + var me = this, + list = [],img, + flag = 0; + + me.addListener('reset',function(){ + list = []; + flag = 0; + }); + + function addList(type,evt){ + + if(browser.webkit){ + var target = evt.target.tagName == 'IMG' ? evt.target : null; + } + + function addFormat(range){ + + if(text){ + range.selectNode(text); + } + return range.applyInlineStyle(list[list.length-1].tagName,null,list); + + } + + me.undoManger && me.undoManger.save(); + + var range = me.selection.getRange(), + imgT = target || range.getClosedNode(); + if(img && imgT && imgT.tagName == 'IMG'){ + //trace:964 + + imgT.style.cssText += ';float:' + (img.style.cssFloat || img.style.styleFloat ||'none') + ';display:' + (img.style.display||'inline'); + + img = null; + }else{ + if(!img){ + var collapsed = range.collapsed; + if(collapsed){ + var text = me.document.createTextNode('match'); + range.insertNode(text).select(); + + + } + me.__hasEnterExecCommand = true; + //不能把block上的属性干掉 + //trace:1553 + var removeFormatAttributes = me.options.removeFormatAttributes; + me.options.removeFormatAttributes = ''; + me.execCommand('removeformat'); + me.options.removeFormatAttributes = removeFormatAttributes; + me.__hasEnterExecCommand = false; + //trace:969 + range = me.selection.getRange(); + if(list.length){ + addFormat(range); + } + if(text){ + range.setStartBefore(text).collapse(true); + + } + range.select(); + text && domUtils.remove(text); + } + + } + + + + + me.undoManger && me.undoManger.save(); + me.removeListener('mouseup',addList); + flag = 0; + } + + me.commands['formatmatch'] = { + execCommand : function( cmdName ) { + + if(flag){ + flag = 0; + list = []; + me.removeListener('mouseup',addList); + return; + } + + + + var range = me.selection.getRange(); + img = range.getClosedNode(); + if(!img || img.tagName != 'IMG'){ + range.collapse(true).shrinkBoundary(); + var start = range.startContainer; + list = domUtils.findParents(start,true,function(node){ + return !domUtils.isBlockElm(node) && node.nodeType == 1; + }); + //a不能加入格式刷, 并且克隆节点 + for(var i=0,ci;ci=list[i];i++){ + if(ci.tagName == 'A'){ + list.splice(i,1); + break; + } + } + + } + + me.addListener('mouseup',addList); + flag = 1; + + + }, + queryCommandState : function() { + return flag; + }, + notNeedUndo : 1 + }; +}; + + + +// plugins/searchreplace.js +///import core +///commands 查找替换 +///commandsName SearchReplace +///commandsTitle 查询替换 +///commandsDialog dialogs\searchreplace +/** + * @description 查找替换 + * @author zhanyi + */ + +UE.plugin.register('searchreplace',function(){ + var me = this; + + var _blockElm = {'table':1,'tbody':1,'tr':1,'ol':1,'ul':1}; + + function findTextInString(textContent,opt,currentIndex){ + var str = opt.searchStr; + if(opt.dir == -1){ + textContent = textContent.split('').reverse().join(''); + str = str.split('').reverse().join(''); + currentIndex = textContent.length - currentIndex; + + } + var reg = new RegExp(str,'g' + (opt.casesensitive ? '' : 'i')),match; + + while(match = reg.exec(textContent)){ + if(match.index >= currentIndex){ + return opt.dir == -1 ? textContent.length - match.index - opt.searchStr.length : match.index; + } + } + return -1 + } + function findTextBlockElm(node,currentIndex,opt){ + var textContent,index,methodName = opt.all || opt.dir == 1 ? 'getNextDomNode' : 'getPreDomNode'; + if(domUtils.isBody(node)){ + node = node.firstChild; + } + var first = 1; + while(node){ + textContent = node.nodeType == 3 ? node.nodeValue : node[browser.ie ? 'innerText' : 'textContent']; + index = findTextInString(textContent,opt,currentIndex ); + first = 0; + if(index!=-1){ + return { + 'node':node, + 'index':index + } + } + node = domUtils[methodName](node); + while(node && _blockElm[node.nodeName.toLowerCase()]){ + node = domUtils[methodName](node,true); + } + if(node){ + currentIndex = opt.dir == -1 ? (node.nodeType == 3 ? node.nodeValue : node[browser.ie ? 'innerText' : 'textContent']).length : 0; + } + + } + } + function findNTextInBlockElm(node,index,str){ + var currentIndex = 0, + currentNode = node.firstChild, + currentNodeLength = 0, + result; + while(currentNode){ + if(currentNode.nodeType == 3){ + currentNodeLength = currentNode.nodeValue.replace(/(^[\t\r\n]+)|([\t\r\n]+$)/,'').length; + currentIndex += currentNodeLength; + if(currentIndex >= index){ + return { + 'node':currentNode, + 'index': currentNodeLength - (currentIndex - index) + } + } + }else if(!dtd.$empty[currentNode.tagName]){ + currentNodeLength = currentNode[browser.ie ? 'innerText' : 'textContent'].replace(/(^[\t\r\n]+)|([\t\r\n]+$)/,'').length + currentIndex += currentNodeLength; + if(currentIndex >= index){ + result = findNTextInBlockElm(currentNode,currentNodeLength - (currentIndex - index),str); + if(result){ + return result; + } + } + } + currentNode = domUtils.getNextDomNode(currentNode); + + } + } + + function searchReplace(me,opt){ + + var rng = me.selection.getRange(), + startBlockNode, + searchStr = opt.searchStr, + span = me.document.createElement('span'); + span.innerHTML = '$$ueditor_searchreplace_key$$'; + + rng.shrinkBoundary(true); + + //判断是不是第一次选中 + if(!rng.collapsed){ + rng.select(); + var rngText = me.selection.getText(); + if(new RegExp('^' + opt.searchStr + '$',(opt.casesensitive ? '' : 'i')).test(rngText)){ + if(opt.replaceStr != undefined){ + replaceText(rng,opt.replaceStr); + rng.select(); + return true; + }else{ + rng.collapse(opt.dir == -1) + } + + } + } + + + rng.insertNode(span); + rng.enlargeToBlockElm(true); + startBlockNode = rng.startContainer; + var currentIndex = startBlockNode[browser.ie ? 'innerText' : 'textContent'].indexOf('$$ueditor_searchreplace_key$$'); + rng.setStartBefore(span); + domUtils.remove(span); + var result = findTextBlockElm(startBlockNode,currentIndex,opt); + if(result){ + var rngStart = findNTextInBlockElm(result.node,result.index,searchStr); + var rngEnd = findNTextInBlockElm(result.node,result.index + searchStr.length,searchStr); + rng.setStart(rngStart.node,rngStart.index).setEnd(rngEnd.node,rngEnd.index); + + if(opt.replaceStr !== undefined){ + replaceText(rng,opt.replaceStr) + } + rng.select(); + return true; + }else{ + rng.setCursor() + } + + } + function replaceText(rng,str){ + + str = me.document.createTextNode(str); + rng.deleteContents().insertNode(str); + + } + return { + commands:{ + 'searchreplace':{ + execCommand:function(cmdName,opt){ + utils.extend(opt,{ + all : false, + casesensitive : false, + dir : 1 + },true); + var num = 0; + if(opt.all){ + + var rng = me.selection.getRange(), + first = me.body.firstChild; + if(first && first.nodeType == 1){ + rng.setStart(first,0); + rng.shrinkBoundary(true); + }else if(first.nodeType == 3){ + rng.setStartBefore(first) + } + rng.collapse(true).select(true); + if(opt.replaceStr !== undefined){ + me.fireEvent('saveScene'); + } + while(searchReplace(this,opt)){ + num++; + } + if(num){ + me.fireEvent('saveScene'); + } + }else{ + if(opt.replaceStr !== undefined){ + me.fireEvent('saveScene'); + } + if(searchReplace(this,opt)){ + num++ + } + if(num){ + me.fireEvent('saveScene'); + } + + } + + return num; + }, + notNeedUndo:1 + } + } + } +}); + +// plugins/customstyle.js +/** + * 自定义样式 + * @file + * @since 1.2.6.1 + */ + +/** + * 根据config配置文件里“customstyle”选项的值对匹配的标签执行样式替换。 + * @command customstyle + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'customstyle' ); + * ``` + */ +UE.plugins['customstyle'] = function() { + var me = this; + me.setOpt({ 'customstyle':[ + {tag:'h1',name:'tc', style:'font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:center;margin:0 0 20px 0;'}, + {tag:'h1',name:'tl', style:'font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:left;margin:0 0 10px 0;'}, + {tag:'span',name:'im', style:'font-size:16px;font-style:italic;font-weight:bold;line-height:18px;'}, + {tag:'span',name:'hi', style:'font-size:16px;font-style:italic;font-weight:bold;color:rgb(51, 153, 204);line-height:18px;'} + ]}); + me.commands['customstyle'] = { + execCommand : function(cmdName, obj) { + var me = this, + tagName = obj.tag, + node = domUtils.findParent(me.selection.getStart(), function(node) { + return node.getAttribute('label'); + }, true), + range,bk,tmpObj = {}; + for (var p in obj) { + if(obj[p]!==undefined) + tmpObj[p] = obj[p]; + } + delete tmpObj.tag; + if (node && node.getAttribute('label') == obj.label) { + range = this.selection.getRange(); + bk = range.createBookmark(); + if (range.collapsed) { + //trace:1732 删掉自定义标签,要有p来回填站位 + if(dtd.$block[node.tagName]){ + var fillNode = me.document.createElement('p'); + domUtils.moveChild(node, fillNode); + node.parentNode.insertBefore(fillNode, node); + domUtils.remove(node); + }else{ + domUtils.remove(node,true); + } + + } else { + + var common = domUtils.getCommonAncestor(bk.start, bk.end), + nodes = domUtils.getElementsByTagName(common, tagName); + if(new RegExp(tagName,'i').test(common.tagName)){ + nodes.push(common); + } + for (var i = 0,ni; ni = nodes[i++];) { + if (ni.getAttribute('label') == obj.label) { + var ps = domUtils.getPosition(ni, bk.start),pe = domUtils.getPosition(ni, bk.end); + if ((ps & domUtils.POSITION_FOLLOWING || ps & domUtils.POSITION_CONTAINS) + && + (pe & domUtils.POSITION_PRECEDING || pe & domUtils.POSITION_CONTAINS) + ) + if (dtd.$block[tagName]) { + var fillNode = me.document.createElement('p'); + domUtils.moveChild(ni, fillNode); + ni.parentNode.insertBefore(fillNode, ni); + } + domUtils.remove(ni, true); + } + } + node = domUtils.findParent(common, function(node) { + return node.getAttribute('label') == obj.label; + }, true); + if (node) { + + domUtils.remove(node, true); + + } + + } + range.moveToBookmark(bk).select(); + } else { + if (dtd.$block[tagName]) { + this.execCommand('paragraph', tagName, tmpObj,'customstyle'); + range = me.selection.getRange(); + if (!range.collapsed) { + range.collapse(); + node = domUtils.findParent(me.selection.getStart(), function(node) { + return node.getAttribute('label') == obj.label; + }, true); + var pNode = me.document.createElement('p'); + domUtils.insertAfter(node, pNode); + domUtils.fillNode(me.document, pNode); + range.setStart(pNode, 0).setCursor(); + } + } else { + + range = me.selection.getRange(); + if (range.collapsed) { + node = me.document.createElement(tagName); + domUtils.setAttributes(node, tmpObj); + range.insertNode(node).setStart(node, 0).setCursor(); + + return; + } + + bk = range.createBookmark(); + range.applyInlineStyle(tagName, tmpObj).moveToBookmark(bk).select(); + } + } + + }, + queryCommandValue : function() { + var parent = domUtils.filterNodeList( + this.selection.getStartElementPath(), + function(node){return node.getAttribute('label')} + ); + return parent ? parent.getAttribute('label') : ''; + } + }; + //当去掉customstyle是,如果是块元素,用p代替 + me.addListener('keyup', function(type, evt) { + var keyCode = evt.keyCode || evt.which; + + if (keyCode == 32 || keyCode == 13) { + var range = me.selection.getRange(); + if (range.collapsed) { + var node = domUtils.findParent(me.selection.getStart(), function(node) { + return node.getAttribute('label'); + }, true); + if (node && dtd.$block[node.tagName] && domUtils.isEmptyNode(node)) { + var p = me.document.createElement('p'); + domUtils.insertAfter(node, p); + domUtils.fillNode(me.document, p); + domUtils.remove(node); + range.setStart(p, 0).setCursor(); + + + } + } + } + }); +}; + +// plugins/catchremoteimage.js +///import core +///commands 远程图片抓取 +///commandsName catchRemoteImage,catchremoteimageenable +///commandsTitle 远程图片抓取 +/** + * 远程图片抓取,当开启本插件时所有不符合本地域名的图片都将被抓取成为本地服务器上的图片 + */ +UE.plugins['catchremoteimage'] = function () { + var me = this, + ajax = UE.ajax; + + /* 设置默认值 */ + if (me.options.catchRemoteImageEnable === false) return; + me.setOpt({ + catchRemoteImageEnable: false + }); + + me.addListener("afterpaste", function () { + me.fireEvent("catchRemoteImage"); + }); + + me.addListener("catchRemoteImage", function () { + + var catcherLocalDomain = me.getOpt('catcherLocalDomain'), + catcherActionUrl = me.getActionUrl(me.getOpt('catcherActionName')), + catcherUrlPrefix = me.getOpt('catcherUrlPrefix'), + catcherFieldName = me.getOpt('catcherFieldName'); + + var remoteImages = [], + imgs = domUtils.getElementsByTagName(me.document, "img"), + test = function (src, urls) { + if (src.indexOf(location.host) != -1 || /(^\.)|(^\/)/.test(src)) { + return true; + } + if (urls) { + for (var j = 0, url; url = urls[j++];) { + if (src.indexOf(url) !== -1) { + return true; + } + } + } + return false; + }; + + for (var i = 0, ci; ci = imgs[i++];) { + if (ci.getAttribute("word_img")) { + continue; + } + var src = ci.getAttribute("_src") || ci.src || ""; + if (/^(https?|ftp):/i.test(src) && !test(src, catcherLocalDomain)) { + remoteImages.push(src); + } + } + + if (remoteImages.length) { + catchremoteimage(remoteImages, { + //成功抓取 + success: function (r) { + try { + var info = r.state !== undefined ? r:eval("(" + r.responseText + ")"); + } catch (e) { + return; + } + + /* 获取源路径和新路径 */ + var i, j, ci, cj, oldSrc, newSrc, list = info.list; + + for (i = 0; ci = imgs[i++];) { + oldSrc = ci.getAttribute("_src") || ci.src || ""; + for (j = 0; cj = list[j++];) { + if (oldSrc == cj.source && cj.state == "SUCCESS") { //抓取失败时不做替换处理 + newSrc = catcherUrlPrefix + cj.url; + domUtils.setAttributes(ci, { + "src": newSrc, + "_src": newSrc + }); + break; + } + } + } + me.fireEvent('catchremotesuccess') + }, + //回调失败,本次请求超时 + error: function () { + me.fireEvent("catchremoteerror"); + } + }); + } + + function catchremoteimage(imgs, callbacks) { + var params = utils.serializeParam(me.queryCommandValue('serverparam')) || '', + url = utils.formatUrl(catcherActionUrl + (catcherActionUrl.indexOf('?') == -1 ? '?':'&') + params), + isJsonp = utils.isCrossDomainUrl(url), + opt = { + 'method': 'POST', + 'dataType': isJsonp ? 'jsonp':'', + 'timeout': 60000, //单位:毫秒,回调请求超时设置。目标用户如果网速不是很快的话此处建议设置一个较大的数值 + 'onsuccess': callbacks["success"], + 'onerror': callbacks["error"] + }; + opt[catcherFieldName] = imgs; + ajax.request(url, opt); + } + + }); +}; + +// plugins/snapscreen.js +/** + * 截屏插件,为UEditor提供插入支持 + * @file + * @since 1.4.2 + */ +UE.plugin.register('snapscreen', function (){ + + var me = this; + var snapplugin; + + function getLocation(url){ + var search, + a = document.createElement('a'), + params = utils.serializeParam(me.queryCommandValue('serverparam')) || ''; + + a.href = url; + if (browser.ie) { + a.href = a.href; + } + + + search = a.search; + if (params) { + search = search + (search.indexOf('?') == -1 ? '?':'&')+ params; + search = search.replace(/[&]+/ig, '&'); + } + return { + 'port': a.port, + 'hostname': a.hostname, + 'path': a.pathname + search || + a.hash + } + } + + return { + commands:{ + /** + * 字体背景颜色 + * @command snapscreen + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand('snapscreen'); + * ``` + */ + 'snapscreen':{ + execCommand:function (cmd) { + var url, local, res; + var lang = me.getLang("snapScreen_plugin"); + + if(!snapplugin){ + var container = me.container; + var doc = me.container.ownerDocument || me.container.document; + snapplugin = doc.createElement("object"); + try{snapplugin.type = "application/x-pluginbaidusnap";}catch(e){ + return; + } + snapplugin.style.cssText = "position:absolute;left:-9999px;width:0;height:0;"; + snapplugin.setAttribute("width","0"); + snapplugin.setAttribute("height","0"); + container.appendChild(snapplugin); + } + + function onSuccess(rs){ + try{ + rs = eval("("+ rs +")"); + if(rs.state == 'SUCCESS'){ + var opt = me.options; + me.execCommand('insertimage', { + src: opt.snapscreenUrlPrefix + rs.url, + _src: opt.snapscreenUrlPrefix + rs.url, + alt: rs.title || '', + floatStyle: opt.snapscreenImgAlign + }); + } else { + alert(rs.state); + } + }catch(e){ + alert(lang.callBackErrorMsg); + } + } + url = me.getActionUrl(me.getOpt('snapscreenActionName')); + local = getLocation(url); + setTimeout(function () { + try{ + res =snapplugin.saveSnapshot(local.hostname, local.path, local.port); + }catch(e){ + me.ui._dialogs['snapscreenDialog'].open(); + return; + } + + onSuccess(res); + }, 50); + }, + queryCommandState: function(){ + return (navigator.userAgent.indexOf("Windows",0) != -1) ? 0:-1; + } + } + } + } +}); + + +// plugins/insertparagraph.js +/** + * 插入段落 + * @file + * @since 1.2.6.1 + */ + + +/** + * 插入段落 + * @command insertparagraph + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * //editor是编辑器实例 + * editor.execCommand( 'insertparagraph' ); + * ``` + */ + +UE.commands['insertparagraph'] = { + execCommand : function( cmdName,front) { + var me = this, + range = me.selection.getRange(), + start = range.startContainer,tmpNode; + while(start ){ + if(domUtils.isBody(start)){ + break; + } + tmpNode = start; + start = start.parentNode; + } + if(tmpNode){ + var p = me.document.createElement('p'); + if(front){ + tmpNode.parentNode.insertBefore(p,tmpNode) + }else{ + tmpNode.parentNode.insertBefore(p,tmpNode.nextSibling) + } + domUtils.fillNode(me.document,p); + range.setStart(p,0).setCursor(false,true); + } + } +}; + + + +// plugins/webapp.js +/** + * 百度应用 + * @file + * @since 1.2.6.1 + */ + + +/** + * 插入百度应用 + * @command webapp + * @method execCommand + * @remind 需要百度APPKey + * @remind 百度应用主页: http://app.baidu.com/ + * @param { Object } appOptions 应用所需的参数项, 支持的key有: title=>应用标题, width=>应用容器宽度, + * height=>应用容器高度,logo=>应用logo,url=>应用地址 + * @example + * ```javascript + * //editor是编辑器实例 + * //在编辑器里插入一个“植物大战僵尸”的APP + * editor.execCommand( 'webapp' , { + * title: '植物大战僵尸', + * width: 560, + * height: 465, + * logo: '应用展示的图片', + * url: '百度应用的地址' + * } ); + * ``` + */ + +//UE.plugins['webapp'] = function () { +// var me = this; +// function createInsertStr( obj, toIframe, addParagraph ) { +// return !toIframe ? +// (addParagraph ? '

      ' : '') + '' + +// (addParagraph ? '

      ' : '') +// : +// ''; +// } +// +// function switchImgAndIframe( img2frame ) { +// var tmpdiv, +// nodes = domUtils.getElementsByTagName( me.document, !img2frame ? "iframe" : "img" ); +// for ( var i = 0, node; node = nodes[i++]; ) { +// if ( node.className != "edui-faked-webapp" ){ +// continue; +// } +// tmpdiv = me.document.createElement( "div" ); +// tmpdiv.innerHTML = createInsertStr( img2frame ? {url:node.getAttribute( "_url" ), width:node.width, height:node.height,title:node.title,logo:node.style.backgroundImage.replace("url(","").replace(")","")} : {url:node.getAttribute( "src", 2 ),title:node.title, width:node.width, height:node.height,logo:node.getAttribute("logo_url")}, img2frame ? true : false,false ); +// node.parentNode.replaceChild( tmpdiv.firstChild, node ); +// } +// } +// +// me.addListener( "beforegetcontent", function () { +// switchImgAndIframe( true ); +// } ); +// me.addListener( 'aftersetcontent', function () { +// switchImgAndIframe( false ); +// } ); +// me.addListener( 'aftergetcontent', function ( cmdName ) { +// if ( cmdName == 'aftergetcontent' && me.queryCommandState( 'source' ) ){ +// return; +// } +// switchImgAndIframe( false ); +// } ); +// +// me.commands['webapp'] = { +// execCommand:function ( cmd, obj ) { +// me.execCommand( "inserthtml", createInsertStr( obj, false,true ) ); +// } +// }; +//}; + +UE.plugin.register('webapp', function (){ + var me = this; + function createInsertStr(obj,toEmbed){ + return !toEmbed ? + '' + : + '' + + } + return { + outputRule: function(root){ + utils.each(root.getNodesByTagName('img'),function(node){ + var html; + if(node.getAttr('class') == 'edui-faked-webapp'){ + html = createInsertStr({ + title:node.getAttr('title'), + 'width':node.getAttr('width'), + 'height':node.getAttr('height'), + 'align':node.getAttr('align'), + 'cssfloat':node.getStyle('float'), + 'url':node.getAttr("_url"), + 'logo':node.getAttr('_logo_url') + },true); + var embed = UE.uNode.createElement(html); + node.parentNode.replaceChild(embed,node); + } + }) + }, + inputRule:function(root){ + utils.each(root.getNodesByTagName('iframe'),function(node){ + if(node.getAttr('class') == 'edui-faked-webapp'){ + var img = UE.uNode.createElement(createInsertStr({ + title:node.getAttr('title'), + 'width':node.getAttr('width'), + 'height':node.getAttr('height'), + 'align':node.getAttr('align'), + 'cssfloat':node.getStyle('float'), + 'url':node.getAttr("src"), + 'logo':node.getAttr('logo_url') + })); + node.parentNode.replaceChild(img,node); + } + }) + + }, + commands:{ + /** + * 插入百度应用 + * @command webapp + * @method execCommand + * @remind 需要百度APPKey + * @remind 百度应用主页: http://app.baidu.com/ + * @param { Object } appOptions 应用所需的参数项, 支持的key有: title=>应用标题, width=>应用容器宽度, + * height=>应用容器高度,logo=>应用logo,url=>应用地址 + * @example + * ```javascript + * //editor是编辑器实例 + * //在编辑器里插入一个“植物大战僵尸”的APP + * editor.execCommand( 'webapp' , { + * title: '植物大战僵尸', + * width: 560, + * height: 465, + * logo: '应用展示的图片', + * url: '百度应用的地址' + * } ); + * ``` + */ + 'webapp':{ + execCommand:function (cmd, obj) { + + var me = this, + str = createInsertStr(utils.extend(obj,{ + align:'none' + }), false); + me.execCommand("inserthtml",str); + }, + queryCommandState:function () { + var me = this, + img = me.selection.getRange().getClosedNode(), + flag = img && (img.className == "edui-faked-webapp"); + return flag ? 1 : 0; + } + } + } + } +}); + +// plugins/template.js +///import core +///import plugins\inserthtml.js +///import plugins\cleardoc.js +///commands 模板 +///commandsName template +///commandsTitle 模板 +///commandsDialog dialogs\template +UE.plugins['template'] = function () { + UE.commands['template'] = { + execCommand:function (cmd, obj) { + obj.html && this.execCommand("inserthtml", obj.html); + } + }; + this.addListener("click", function (type, evt) { + var el = evt.target || evt.srcElement, + range = this.selection.getRange(); + var tnode = domUtils.findParent(el, function (node) { + if (node.className && domUtils.hasClass(node, "ue_t")) { + return node; + } + }, true); + tnode && range.selectNode(tnode).shrinkBoundary().select(); + }); + this.addListener("keydown", function (type, evt) { + var range = this.selection.getRange(); + if (!range.collapsed) { + if (!evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey) { + var tnode = domUtils.findParent(range.startContainer, function (node) { + if (node.className && domUtils.hasClass(node, "ue_t")) { + return node; + } + }, true); + if (tnode) { + domUtils.removeClasses(tnode, ["ue_t"]); + } + } + } + }); +}; + + +// plugins/music.js +/** + * 插入音乐命令 + * @file + */ +UE.plugin.register('music', function (){ + var me = this; + function creatInsertStr(url,width,height,align,cssfloat,toEmbed){ + return !toEmbed ? + '' + : + ''; + } + return { + outputRule: function(root){ + utils.each(root.getNodesByTagName('img'),function(node){ + var html; + if(node.getAttr('class') == 'edui-faked-music'){ + var cssfloat = node.getStyle('float'); + var align = node.getAttr('align'); + html = creatInsertStr(node.getAttr("_url"), node.getAttr('width'), node.getAttr('height'), align, cssfloat, true); + var embed = UE.uNode.createElement(html); + node.parentNode.replaceChild(embed,node); + } + }) + }, + inputRule:function(root){ + utils.each(root.getNodesByTagName('embed'),function(node){ + if(node.getAttr('class') == 'edui-faked-music'){ + var cssfloat = node.getStyle('float'); + var align = node.getAttr('align'); + html = creatInsertStr(node.getAttr("src"), node.getAttr('width'), node.getAttr('height'), align, cssfloat,false); + var img = UE.uNode.createElement(html); + node.parentNode.replaceChild(img,node); + } + }) + + }, + commands:{ + /** + * 插入音乐 + * @command music + * @method execCommand + * @param { Object } musicOptions 插入音乐的参数项, 支持的key有: url=>音乐地址; + * width=>音乐容器宽度;height=>音乐容器高度;align=>音乐文件的对齐方式, 可选值有: left, center, right, none + * @example + * ```javascript + * //editor是编辑器实例 + * //在编辑器里插入一个“植物大战僵尸”的APP + * editor.execCommand( 'music' , { + * width: 400, + * height: 95, + * align: "center", + * url: "音乐地址" + * } ); + * ``` + */ + 'music':{ + execCommand:function (cmd, musicObj) { + var me = this, + str = creatInsertStr(musicObj.url, musicObj.width || 400, musicObj.height || 95, "none", false); + me.execCommand("inserthtml",str); + }, + queryCommandState:function () { + var me = this, + img = me.selection.getRange().getClosedNode(), + flag = img && (img.className == "edui-faked-music"); + return flag ? 1 : 0; + } + } + } + } +}); + +// plugins/autoupload.js +/** + * @description + * 1.拖放文件到编辑区域,自动上传并插入到选区 + * 2.插入粘贴板的图片,自动上传并插入到选区 + * @author Jinqn + * @date 2013-10-14 + */ +UE.plugin.register('autoupload', function (){ + + function sendAndInsertFile(file, editor) { + var me = editor; + //模拟数据 + var fieldName, urlPrefix, maxSize, allowFiles, actionUrl, + loadingHtml, errorHandler, successHandler, + filetype = /image\/\w+/i.test(file.type) ? 'image':'file', + loadingId = 'loading_' + (+new Date()).toString(36); + + fieldName = me.getOpt(filetype + 'FieldName'); + urlPrefix = me.getOpt(filetype + 'UrlPrefix'); + maxSize = me.getOpt(filetype + 'MaxSize'); + allowFiles = me.getOpt(filetype + 'AllowFiles'); + actionUrl = me.getActionUrl(me.getOpt(filetype + 'ActionName')); + errorHandler = function(title) { + var loader = me.document.getElementById(loadingId); + loader && domUtils.remove(loader); + me.fireEvent('showmessage', { + 'id': loadingId, + 'content': title, + 'type': 'error', + 'timeout': 4000 + }); + }; + + if (filetype == 'image') { + loadingHtml = ''; + successHandler = function(data) { + var link = urlPrefix + data.url, + loader = me.document.getElementById(loadingId); + if (loader) { + loader.setAttribute('src', link); + loader.setAttribute('_src', link); + loader.setAttribute('title', data.title || ''); + loader.setAttribute('alt', data.original || ''); + loader.removeAttribute('id'); + domUtils.removeClasses(loader, 'loadingclass'); + } + }; + } else { + loadingHtml = '

      ' + + '' + + '

      '; + successHandler = function(data) { + var link = urlPrefix + data.url, + loader = me.document.getElementById(loadingId); + + var rng = me.selection.getRange(), + bk = rng.createBookmark(); + rng.selectNode(loader).select(); + me.execCommand('insertfile', {'url': link}); + rng.moveToBookmark(bk).select(); + }; + } + + /* 插入loading的占位符 */ + me.execCommand('inserthtml', loadingHtml); + + /* 判断后端配置是否没有加载成功 */ + if (!me.getOpt(filetype + 'ActionName')) { + errorHandler(me.getLang('autoupload.errorLoadConfig')); + return; + } + /* 判断文件大小是否超出限制 */ + if(file.size > maxSize) { + errorHandler(me.getLang('autoupload.exceedSizeError')); + return; + } + /* 判断文件格式是否超出允许 */ + var fileext = file.name ? file.name.substr(file.name.lastIndexOf('.')):''; + if ((fileext && filetype != 'image') || (allowFiles && (allowFiles.join('') + '.').indexOf(fileext.toLowerCase() + '.') == -1)) { + errorHandler(me.getLang('autoupload.exceedTypeError')); + return; + } + + /* 创建Ajax并提交 */ + var xhr = new XMLHttpRequest(), + fd = new FormData(), + params = utils.serializeParam(me.queryCommandValue('serverparam')) || '', + url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?':'&') + params); + + fd.append(fieldName, file, file.name || ('blob.' + file.type.substr('image/'.length))); + fd.append('type', 'ajax'); + xhr.open("post", url, true); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.addEventListener('load', function (e) { + try{ + var json = (new Function("return " + utils.trim(e.target.response)))(); + if (json.state == 'SUCCESS' && json.url) { + successHandler(json); + } else { + errorHandler(json.state); + } + }catch(er){ + errorHandler(me.getLang('autoupload.loadError')); + } + }); + xhr.send(fd); + } + + function getPasteImage(e){ + return e.clipboardData && e.clipboardData.items && e.clipboardData.items.length == 1 && /^image\//.test(e.clipboardData.items[0].type) ? e.clipboardData.items:null; + } + function getDropImage(e){ + return e.dataTransfer && e.dataTransfer.files ? e.dataTransfer.files:null; + } + + return { + outputRule: function(root){ + utils.each(root.getNodesByTagName('img'),function(n){ + if (/\b(loaderrorclass)|(bloaderrorclass)\b/.test(n.getAttr('class'))) { + n.parentNode.removeChild(n); + } + }); + utils.each(root.getNodesByTagName('p'),function(n){ + if (/\bloadpara\b/.test(n.getAttr('class'))) { + n.parentNode.removeChild(n); + } + }); + }, + bindEvents:{ + //插入粘贴板的图片,拖放插入图片 + 'ready':function(e){ + var me = this; + if(window.FormData && window.FileReader) { + domUtils.on(me.body, 'paste drop', function(e){ + var hasImg = false, + items; + //获取粘贴板文件列表或者拖放文件列表 + items = e.type == 'paste' ? getPasteImage(e):getDropImage(e); + if(items){ + var len = items.length, + file; + while (len--){ + file = items[len]; + if(file.getAsFile) file = file.getAsFile(); + if(file && file.size > 0) { + sendAndInsertFile(file, me); + hasImg = true; + } + } + hasImg && e.preventDefault(); + } + + }); + //取消拖放图片时出现的文字光标位置提示 + domUtils.on(me.body, 'dragover', function (e) { + if(e.dataTransfer.types[0] == 'Files') { + e.preventDefault(); + } + }); + + //设置loading的样式 + utils.cssRule('loading', + '.loadingclass{display:inline-block;cursor:default;background: url(\'' + + this.options.themePath + + this.options.theme +'/images/loading.gif\') no-repeat center center transparent;border:1px solid #cccccc;margin-left:1px;height: 22px;width: 22px;}\n' + + '.loaderrorclass{display:inline-block;cursor:default;background: url(\'' + + this.options.themePath + + this.options.theme +'/images/loaderror.png\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;' + + '}', + this.document); + } + } + } + } +}); + +// plugins/autosave.js +UE.plugin.register('autosave', function (){ + + var me = this, + //无限循环保护 + lastSaveTime = new Date(), + //最小保存间隔时间 + MIN_TIME = 20, + //auto save key + saveKey = null; + + function save ( editor ) { + + var saveData; + + if ( new Date() - lastSaveTime < MIN_TIME ) { + return; + } + + if ( !editor.hasContents() ) { + //这里不能调用命令来删除, 会造成事件死循环 + saveKey && me.removePreferences( saveKey ); + return; + } + + lastSaveTime = new Date(); + + editor._saveFlag = null; + + saveData = me.body.innerHTML; + + if ( editor.fireEvent( "beforeautosave", { + content: saveData + } ) === false ) { + return; + } + + me.setPreferences( saveKey, saveData ); + + editor.fireEvent( "afterautosave", { + content: saveData + } ); + + } + + return { + defaultOptions: { + //默认间隔时间 + saveInterval: 500 + }, + bindEvents:{ + 'ready':function(){ + + var _suffix = "-drafts-data", + key = null; + + if ( me.key ) { + key = me.key + _suffix; + } else { + key = ( me.container.parentNode.id || 'ue-common' ) + _suffix; + } + + //页面地址+编辑器ID 保持唯一 + saveKey = ( location.protocol + location.host + location.pathname ).replace( /[.:\/]/g, '_' ) + key; + + }, + + 'contentchange': function () { + + if ( !saveKey ) { + return; + } + + if ( me._saveFlag ) { + window.clearTimeout( me._saveFlag ); + } + + if ( me.options.saveInterval > 0 ) { + + me._saveFlag = window.setTimeout( function () { + + save( me ); + + }, me.options.saveInterval ); + + } else { + + save(me); + + } + + + } + }, + commands:{ + 'clearlocaldata':{ + execCommand:function (cmd, name) { + if ( saveKey && me.getPreferences( saveKey ) ) { + me.removePreferences( saveKey ) + } + }, + notNeedUndo: true, + ignoreContentChange:true + }, + + 'getlocaldata':{ + execCommand:function (cmd, name) { + return saveKey ? me.getPreferences( saveKey ) || '' : ''; + }, + notNeedUndo: true, + ignoreContentChange:true + }, + + 'drafts':{ + execCommand:function (cmd, name) { + if ( saveKey ) { + me.body.innerHTML = me.getPreferences( saveKey ) || '

      '+domUtils.fillHtml+'

      '; + me.focus(true); + } + }, + queryCommandState: function () { + return saveKey ? ( me.getPreferences( saveKey ) === null ? -1 : 0 ) : -1; + }, + notNeedUndo: true, + ignoreContentChange:true + } + } + } + +}); + +// plugins/charts.js +UE.plugin.register('charts', function (){ + + var me = this; + + return { + bindEvents: { + 'chartserror': function () { + } + }, + commands:{ + 'charts': { + execCommand: function ( cmd, data ) { + + var tableNode = domUtils.findParentByTagName(this.selection.getRange().startContainer, 'table', true), + flagText = [], + config = {}; + + if ( !tableNode ) { + return false; + } + + if ( !validData( tableNode ) ) { + me.fireEvent( "chartserror" ); + return false; + } + + config.title = data.title || ''; + config.subTitle = data.subTitle || ''; + config.xTitle = data.xTitle || ''; + config.yTitle = data.yTitle || ''; + config.suffix = data.suffix || ''; + config.tip = data.tip || ''; + //数据对齐方式 + config.dataFormat = data.tableDataFormat || ''; + //图表类型 + config.chartType = data.chartType || 0; + + for ( var key in config ) { + + if ( !config.hasOwnProperty( key ) ) { + continue; + } + + flagText.push( key+":"+config[ key ] ); + + } + + tableNode.setAttribute( "data-chart", flagText.join( ";" ) ); + domUtils.addClass( tableNode, "edui-charts-table" ); + + + + }, + queryCommandState: function ( cmd, name ) { + + var tableNode = domUtils.findParentByTagName(this.selection.getRange().startContainer, 'table', true); + return tableNode && validData( tableNode ) ? 0 : -1; + + } + } + }, + inputRule:function(root){ + utils.each(root.getNodesByTagName('table'),function( tableNode ){ + + if ( tableNode.getAttr("data-chart") !== undefined ) { + tableNode.setAttr("style"); + } + + }) + + }, + outputRule:function(root){ + utils.each(root.getNodesByTagName('table'),function( tableNode ){ + + if ( tableNode.getAttr("data-chart") !== undefined ) { + tableNode.setAttr("style", "display: none;"); + } + + }) + + } + } + + function validData ( table ) { + + var firstRows = null, + cellCount = 0; + + //行数不够 + if ( table.rows.length < 2 ) { + return false; + } + + //列数不够 + if ( table.rows[0].cells.length < 2 ) { + return false; + } + + //第一行所有cell必须是th + firstRows = table.rows[ 0 ].cells; + cellCount = firstRows.length; + + for ( var i = 0, cell; cell = firstRows[ i ]; i++ ) { + + if ( cell.tagName.toLowerCase() !== 'th' ) { + return false; + } + + } + + for ( var i = 1, row; row = table.rows[ i ]; i++ ) { + + //每行单元格数不匹配, 返回false + if ( row.cells.length != cellCount ) { + return false; + } + + //第一列不是th也返回false + if ( row.cells[0].tagName.toLowerCase() !== 'th' ) { + return false; + } + + for ( var j = 1, cell; cell = row.cells[ j ]; j++ ) { + + var value = utils.trim( ( cell.innerText || cell.textContent || '' ) ); + + value = value.replace( new RegExp( UE.dom.domUtils.fillChar, 'g' ), '' ).replace( /^\s+|\s+$/g, '' ); + + //必须是数字 + if ( !/^\d*\.?\d+$/.test( value ) ) { + return false; + } + + } + + } + + return true; + + } + +}); + +// plugins/section.js +/** + * 目录大纲支持插件 + * @file + * @since 1.3.0 + */ +UE.plugin.register('section', function (){ + /* 目录节点对象 */ + function Section(option){ + this.tag = ''; + this.level = -1, + this.dom = null; + this.nextSection = null; + this.previousSection = null; + this.parentSection = null; + this.startAddress = []; + this.endAddress = []; + this.children = []; + } + function getSection(option) { + var section = new Section(); + return utils.extend(section, option); + } + function getNodeFromAddress(startAddress, root) { + var current = root; + for(var i = 0;i < startAddress.length; i++) { + if(!current.childNodes) return null; + current = current.childNodes[startAddress[i]]; + } + return current; + } + + var me = this; + + return { + bindMultiEvents:{ + type: 'aftersetcontent afterscencerestore', + handler: function(){ + me.fireEvent('updateSections'); + } + }, + bindEvents:{ + /* 初始化、拖拽、粘贴、执行setcontent之后 */ + 'ready': function (){ + me.fireEvent('updateSections'); + domUtils.on(me.body, 'drop paste', function(){ + me.fireEvent('updateSections'); + }); + }, + /* 执行paragraph命令之后 */ + 'afterexeccommand': function (type, cmd) { + if(cmd == 'paragraph') { + me.fireEvent('updateSections'); + } + }, + /* 部分键盘操作,触发updateSections事件 */ + 'keyup': function (type, e) { + var me = this, + range = me.selection.getRange(); + if(range.collapsed != true) { + me.fireEvent('updateSections'); + } else { + var keyCode = e.keyCode || e.which; + if(keyCode == 13 || keyCode == 8 || keyCode == 46) { + me.fireEvent('updateSections'); + } + } + } + }, + commands:{ + 'getsections': { + execCommand: function (cmd, levels) { + var levelFn = levels || ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']; + + for (var i = 0; i < levelFn.length; i++) { + if (typeof levelFn[i] == 'string') { + levelFn[i] = function(fn){ + return function(node){ + return node.tagName == fn.toUpperCase() + }; + }(levelFn[i]); + } else if (typeof levelFn[i] != 'function') { + levelFn[i] = function (node) { + return null; + } + } + } + function getSectionLevel(node) { + for (var i = 0; i < levelFn.length; i++) { + if (levelFn[i](node)) return i; + } + return -1; + } + + var me = this, + Directory = getSection({'level':-1, 'title':'root'}), + previous = Directory; + + function traversal(node, Directory) { + var level, + tmpSection = null, + parent, + child, + children = node.childNodes; + for (var i = 0, len = children.length; i < len; i++) { + child = children[i]; + level = getSectionLevel(child); + if (level >= 0) { + var address = me.selection.getRange().selectNode(child).createAddress(true).startAddress, + current = getSection({ + 'tag': child.tagName, + 'title': child.innerText || child.textContent || '', + 'level': level, + 'dom': child, + 'startAddress': utils.clone(address, []), + 'endAddress': utils.clone(address, []), + 'children': [] + }); + previous.nextSection = current; + current.previousSection = previous; + parent = previous; + while(level <= parent.level){ + parent = parent.parentSection; + } + current.parentSection = parent; + parent.children.push(current); + tmpSection = previous = current; + } else { + child.nodeType === 1 && traversal(child, Directory); + tmpSection && tmpSection.endAddress[tmpSection.endAddress.length - 1] ++; + } + } + } + traversal(me.body, Directory); + return Directory; + }, + notNeedUndo: true + }, + 'movesection': { + execCommand: function (cmd, sourceSection, targetSection, isAfter) { + + var me = this, + targetAddress, + target; + + if(!sourceSection || !targetSection || targetSection.level == -1) return; + + targetAddress = isAfter ? targetSection.endAddress:targetSection.startAddress; + target = getNodeFromAddress(targetAddress, me.body); + + /* 判断目标地址是否被源章节包含 */ + if(!targetAddress || !target || isContainsAddress(sourceSection.startAddress, sourceSection.endAddress, targetAddress)) return; + + var startNode = getNodeFromAddress(sourceSection.startAddress, me.body), + endNode = getNodeFromAddress(sourceSection.endAddress, me.body), + current, + nextNode; + + if(isAfter) { + current = endNode; + while ( current && !(domUtils.getPosition( startNode, current ) & domUtils.POSITION_FOLLOWING) ) { + nextNode = current.previousSibling; + domUtils.insertAfter(target, current); + if(current == startNode) break; + current = nextNode; + } + } else { + current = startNode; + while ( current && !(domUtils.getPosition( current, endNode ) & domUtils.POSITION_FOLLOWING) ) { + nextNode = current.nextSibling; + target.parentNode.insertBefore(current, target); + if(current == endNode) break; + current = nextNode; + } + } + + me.fireEvent('updateSections'); + + /* 获取地址的包含关系 */ + function isContainsAddress(startAddress, endAddress, addressTarget){ + var isAfterStartAddress = false, + isBeforeEndAddress = false; + for(var i = 0; i< startAddress.length; i++){ + if(i >= addressTarget.length) break; + if(addressTarget[i] > startAddress[i]) { + isAfterStartAddress = true; + break; + } else if(addressTarget[i] < startAddress[i]) { + break; + } + } + for(var i = 0; i< endAddress.length; i++){ + if(i >= addressTarget.length) break; + if(addressTarget[i] < startAddress[i]) { + isBeforeEndAddress = true; + break; + } else if(addressTarget[i] > startAddress[i]) { + break; + } + } + return isAfterStartAddress && isBeforeEndAddress; + } + } + }, + 'deletesection': { + execCommand: function (cmd, section, keepChildren) { + var me = this; + + if(!section) return; + + function getNodeFromAddress(startAddress) { + var current = me.body; + for(var i = 0;i < startAddress.length; i++) { + if(!current.childNodes) return null; + current = current.childNodes[startAddress[i]]; + } + return current; + } + + var startNode = getNodeFromAddress(section.startAddress), + endNode = getNodeFromAddress(section.endAddress), + current = startNode, + nextNode; + + if(!keepChildren) { + while ( current && domUtils.inDoc(endNode, me.document) && !(domUtils.getPosition( current, endNode ) & domUtils.POSITION_FOLLOWING) ) { + nextNode = current.nextSibling; + domUtils.remove(current); + current = nextNode; + } + } else { + domUtils.remove(current); + } + + me.fireEvent('updateSections'); + } + }, + 'selectsection': { + execCommand: function (cmd, section) { + if(!section && !section.dom) return false; + var me = this, + range = me.selection.getRange(), + address = { + 'startAddress':utils.clone(section.startAddress, []), + 'endAddress':utils.clone(section.endAddress, []) + }; + address.endAddress[address.endAddress.length - 1]++; + range.moveToAddress(address).select().scrollToView(); + return true; + }, + notNeedUndo: true + }, + 'scrolltosection': { + execCommand: function (cmd, section) { + if(!section && !section.dom) return false; + var me = this, + range = me.selection.getRange(), + address = { + 'startAddress':section.startAddress, + 'endAddress':section.endAddress + }; + address.endAddress[address.endAddress.length - 1]++; + range.moveToAddress(address).scrollToView(); + return true; + }, + notNeedUndo: true + } + } + } +}); + +// plugins/simpleupload.js +/** + * @description + * 简单上传:点击按钮,直接选择文件上传 + * @author Jinqn + * @date 2014-03-31 + */ +UE.plugin.register('simpleupload', function (){ + var me = this, + isLoaded = false, + containerBtn; + + function initUploadBtn(){ + var w = containerBtn.offsetWidth || 20, + h = containerBtn.offsetHeight || 20, + btnIframe = document.createElement('iframe'), + btnStyle = 'display:block;width:' + w + 'px;height:' + h + 'px;overflow:hidden;border:0;margin:0;padding:0;position:absolute;top:0;left:0;filter:alpha(opacity=0);-moz-opacity:0;-khtml-opacity: 0;opacity: 0;cursor:pointer;'; + + domUtils.on(btnIframe, 'load', function(){ + + var timestrap = (+new Date()).toString(36), + wrapper, + btnIframeDoc, + btnIframeBody; + + btnIframeDoc = (btnIframe.contentDocument || btnIframe.contentWindow.document); + btnIframeBody = btnIframeDoc.body; + wrapper = btnIframeDoc.createElement('div'); + + wrapper.innerHTML = '
      ' + + '' + + '
      ' + + ''; + + wrapper.className = 'edui-' + me.options.theme; + wrapper.id = me.ui.id + '_iframeupload'; + btnIframeBody.style.cssText = btnStyle; + btnIframeBody.style.width = w + 'px'; + btnIframeBody.style.height = h + 'px'; + btnIframeBody.appendChild(wrapper); + + if (btnIframeBody.parentNode) { + btnIframeBody.parentNode.style.width = w + 'px'; + btnIframeBody.parentNode.style.height = w + 'px'; + } + + var form = btnIframeDoc.getElementById('edui_form_' + timestrap); + var input = btnIframeDoc.getElementById('edui_input_' + timestrap); + var iframe = btnIframeDoc.getElementById('edui_iframe_' + timestrap); + + domUtils.on(input, 'change', function(){ + if(!input.value) return; + var loadingId = 'loading_' + (+new Date()).toString(36); + var params = utils.serializeParam(me.queryCommandValue('serverparam')) || ''; + + var imageActionUrl = me.getActionUrl(me.getOpt('imageActionName')); + var allowFiles = me.getOpt('imageAllowFiles'); + + me.focus(); + me.execCommand('inserthtml', ''); + + function callback(){ + try{ + var link, json, loader, + body = (iframe.contentDocument || iframe.contentWindow.document).body, + result = body.innerText || body.textContent || ''; + json = (new Function("return " + result))(); + link = me.options.imageUrlPrefix + json.url; + if(json.state == 'SUCCESS' && json.url) { + loader = me.document.getElementById(loadingId); + loader.setAttribute('src', link); + loader.setAttribute('_src', link); + loader.setAttribute('title', json.title || ''); + loader.setAttribute('alt', json.original || ''); + loader.removeAttribute('id'); + domUtils.removeClasses(loader, 'loadingclass'); + } else { + showErrorLoader && showErrorLoader(json.state); + } + }catch(er){ + showErrorLoader && showErrorLoader(me.getLang('simpleupload.loadError')); + } + form.reset(); + domUtils.un(iframe, 'load', callback); + } + function showErrorLoader(title){ + if(loadingId) { + var loader = me.document.getElementById(loadingId); + loader && domUtils.remove(loader); + me.fireEvent('showmessage', { + 'id': loadingId, + 'content': title, + 'type': 'error', + 'timeout': 4000 + }); + } + } + + /* 判断后端配置是否没有加载成功 */ + if (!me.getOpt('imageActionName')) { + errorHandler(me.getLang('autoupload.errorLoadConfig')); + return; + } + // 判断文件格式是否错误 + var filename = input.value, + fileext = filename ? filename.substr(filename.lastIndexOf('.')):''; + if (!fileext || (allowFiles && (allowFiles.join('') + '.').indexOf(fileext.toLowerCase() + '.') == -1)) { + showErrorLoader(me.getLang('simpleupload.exceedTypeError')); + return; + } + + domUtils.on(iframe, 'load', callback); + form.action = utils.formatUrl(imageActionUrl + (imageActionUrl.indexOf('?') == -1 ? '?':'&') + params); + form.submit(); + }); + + var stateTimer; + me.addListener('selectionchange', function () { + clearTimeout(stateTimer); + stateTimer = setTimeout(function() { + var state = me.queryCommandState('simpleupload'); + if (state == -1) { + input.disabled = 'disabled'; + } else { + input.disabled = false; + } + }, 400); + }); + isLoaded = true; + }); + + btnIframe.style.cssText = btnStyle; + containerBtn.appendChild(btnIframe); + } + + return { + bindEvents:{ + 'ready': function() { + //设置loading的样式 + utils.cssRule('loading', + '.loadingclass{display:inline-block;cursor:default;background: url(\'' + + this.options.themePath + + this.options.theme +'/images/loading.gif\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;}\n' + + '.loaderrorclass{display:inline-block;cursor:default;background: url(\'' + + this.options.themePath + + this.options.theme +'/images/loaderror.png\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;' + + '}', + this.document); + }, + /* 初始化简单上传按钮 */ + 'simpleuploadbtnready': function(type, container) { + containerBtn = container; + me.afterConfigReady(initUploadBtn); + } + }, + outputRule: function(root){ + utils.each(root.getNodesByTagName('img'),function(n){ + if (/\b(loaderrorclass)|(bloaderrorclass)\b/.test(n.getAttr('class'))) { + n.parentNode.removeChild(n); + } + }); + }, + commands: { + 'simpleupload': { + queryCommandState: function () { + return isLoaded ? 0:-1; + } + } + } + } +}); + +// plugins/serverparam.js +/** + * 服务器提交的额外参数列表设置插件 + * @file + * @since 1.2.6.1 + */ +UE.plugin.register('serverparam', function (){ + + var me = this, + serverParam = {}; + + return { + commands:{ + /** + * 修改服务器提交的额外参数列表,清除所有项 + * @command serverparam + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand('serverparam'); + * editor.queryCommandValue('serverparam'); //返回空 + * ``` + */ + /** + * 修改服务器提交的额外参数列表,删除指定项 + * @command serverparam + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } key 要清除的属性 + * @example + * ```javascript + * editor.execCommand('serverparam', 'name'); //删除属性name + * ``` + */ + /** + * 修改服务器提交的额外参数列表,使用键值添加项 + * @command serverparam + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } key 要添加的属性 + * @param { String } value 要添加属性的值 + * @example + * ```javascript + * editor.execCommand('serverparam', 'name', 'hello'); + * editor.queryCommandValue('serverparam'); //返回对象 {'name': 'hello'} + * ``` + */ + /** + * 修改服务器提交的额外参数列表,传入键值对对象添加多项 + * @command serverparam + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { Object } key 传入的键值对对象 + * @example + * ```javascript + * editor.execCommand('serverparam', {'name': 'hello'}); + * editor.queryCommandValue('serverparam'); //返回对象 {'name': 'hello'} + * ``` + */ + /** + * 修改服务器提交的额外参数列表,使用自定义函数添加多项 + * @command serverparam + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { Function } key 自定义获取参数的函数 + * @example + * ```javascript + * editor.execCommand('serverparam', function(editor){ + * return {'key': 'value'}; + * }); + * editor.queryCommandValue('serverparam'); //返回对象 {'key': 'value'} + * ``` + */ + + /** + * 获取服务器提交的额外参数列表 + * @command serverparam + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.queryCommandValue( 'serverparam' ); //返回对象 {'key': 'value'} + * ``` + */ + 'serverparam':{ + execCommand:function (cmd, key, value) { + if (key === undefined || key === null) { //不传参数,清空列表 + serverParam = {}; + } else if (utils.isString(key)) { //传入键值 + if(value === undefined || value === null) { + delete serverParam[key]; + } else { + serverParam[key] = value; + } + } else if (utils.isObject(key)) { //传入对象,覆盖列表项 + utils.extend(serverParam, key, true); + } else if (utils.isFunction(key)){ //传入函数,添加列表项 + utils.extend(serverParam, key(), true); + } + }, + queryCommandValue: function(){ + return serverParam || {}; + } + } + } + } +}); + + +// plugins/insertfile.js +/** + * 插入附件 + */ +UE.plugin.register('insertfile', function (){ + + var me = this; + + function getFileIcon(url){ + var ext = url.substr(url.lastIndexOf('.') + 1).toLowerCase(), + maps = { + + }; + return maps[ext] ? maps[ext]:maps['txt']; + } + + return { + commands:{ + 'insertfile': { + execCommand: function (command, filelist){ + filelist = utils.isArray(filelist) ? filelist : [filelist]; + + var i, item, icon, title, + html = '', + URL = me.getOpt('UEDITOR_HOME_URL'); + for (i = 0; i < filelist.length; i++) { + item = filelist[i]; + title = item.title || item.url.substr(item.url.lastIndexOf('/') + 1); + html += '

      ' + + '' + title + '' + + '

      '; + } + me.execCommand('insertHtml', html); + } + } + } + } +}); + + + + +// plugins/xssFilter.js +/** + * @file xssFilter.js + * @desc xss过滤器 + * @author robbenmu + */ + +UE.plugins.xssFilter = function() { + + var config = UEDITOR_CONFIG; + var whitList = config.whitList; + + function filter(node) { + + var tagName = node.tagName; + var attrs = node.attrs; + + if (!whitList.hasOwnProperty(tagName)) { + node.parentNode.removeChild(node); + return false; + } + + UE.utils.each(attrs, function (val, key) { + + if (whitList[tagName].indexOf(key) === -1) { + node.setAttr(key); + } + }); + } + + // 添加inserthtml\paste等操作用的过滤规则 + if (whitList && config.xssFilterRules) { + this.options.filterRules = function () { + + var result = {}; + + UE.utils.each(whitList, function(val, key) { + result[key] = function (node) { + return filter(node); + }; + }); + + return result; + }(); + } + + var tagList = []; + + UE.utils.each(whitList, function (val, key) { + tagList.push(key); + }); + + // 添加input过滤规则 + // + if (whitList && config.inputXssFilter) { + this.addInputRule(function (root) { + + root.traversal(function(node) { + if (node.type !== 'element') { + return false; + } + filter(node); + }); + }); + } + // 添加output过滤规则 + // + if (whitList && config.outputXssFilter) { + this.addOutputRule(function (root) { + + root.traversal(function(node) { + if (node.type !== 'element') { + return false; + } + filter(node); + }); + }); + } + +}; + + +// ui/ui.js +var baidu = baidu || {}; +baidu.editor = baidu.editor || {}; +UE.ui = baidu.editor.ui = {}; + +// ui/uiutils.js +(function (){ + var browser = baidu.editor.browser, + domUtils = baidu.editor.dom.domUtils; + + var magic = '$EDITORUI'; + var root = window[magic] = {}; + var uidMagic = 'ID' + magic; + var uidCount = 0; + + var uiUtils = baidu.editor.ui.uiUtils = { + uid: function (obj){ + return (obj ? obj[uidMagic] || (obj[uidMagic] = ++ uidCount) : ++ uidCount); + }, + hook: function ( fn, callback ) { + var dg; + if (fn && fn._callbacks) { + dg = fn; + } else { + dg = function (){ + var q; + if (fn) { + q = fn.apply(this, arguments); + } + var callbacks = dg._callbacks; + var k = callbacks.length; + while (k --) { + var r = callbacks[k].apply(this, arguments); + if (q === undefined) { + q = r; + } + } + return q; + }; + dg._callbacks = []; + } + dg._callbacks.push(callback); + return dg; + }, + createElementByHtml: function (html){ + var el = document.createElement('div'); + el.innerHTML = html; + el = el.firstChild; + el.parentNode.removeChild(el); + return el; + }, + getViewportElement: function (){ + return (browser.ie && browser.quirks) ? + document.body : document.documentElement; + }, + getClientRect: function (element){ + var bcr; + //trace IE6下在控制编辑器显隐时可能会报错,catch一下 + try{ + bcr = element.getBoundingClientRect(); + }catch(e){ + bcr={left:0,top:0,height:0,width:0} + } + var rect = { + left: Math.round(bcr.left), + top: Math.round(bcr.top), + height: Math.round(bcr.bottom - bcr.top), + width: Math.round(bcr.right - bcr.left) + }; + var doc; + while ((doc = element.ownerDocument) !== document && + (element = domUtils.getWindow(doc).frameElement)) { + bcr = element.getBoundingClientRect(); + rect.left += bcr.left; + rect.top += bcr.top; + } + rect.bottom = rect.top + rect.height; + rect.right = rect.left + rect.width; + return rect; + }, + getViewportRect: function (){ + var viewportEl = uiUtils.getViewportElement(); + var width = (window.innerWidth || viewportEl.clientWidth) | 0; + var height = (window.innerHeight ||viewportEl.clientHeight) | 0; + return { + left: 0, + top: 0, + height: height, + width: width, + bottom: height, + right: width + }; + }, + setViewportOffset: function (element, offset){ + var rect; + var fixedLayer = uiUtils.getFixedLayer(); + if (element.parentNode === fixedLayer) { + element.style.left = offset.left + 'px'; + element.style.top = offset.top + 'px'; + } else { + domUtils.setViewportOffset(element, offset); + } + }, + getEventOffset: function (evt){ + var el = evt.target || evt.srcElement; + var rect = uiUtils.getClientRect(el); + var offset = uiUtils.getViewportOffsetByEvent(evt); + return { + left: offset.left - rect.left, + top: offset.top - rect.top + }; + }, + getViewportOffsetByEvent: function (evt){ + var el = evt.target || evt.srcElement; + var frameEl = domUtils.getWindow(el).frameElement; + var offset = { + left: evt.clientX, + top: evt.clientY + }; + if (frameEl && el.ownerDocument !== document) { + var rect = uiUtils.getClientRect(frameEl); + offset.left += rect.left; + offset.top += rect.top; + } + return offset; + }, + setGlobal: function (id, obj){ + root[id] = obj; + return magic + '["' + id + '"]'; + }, + unsetGlobal: function (id){ + delete root[id]; + }, + copyAttributes: function (tgt, src){ + var attributes = src.attributes; + var k = attributes.length; + while (k --) { + var attrNode = attributes[k]; + if ( attrNode.nodeName != 'style' && attrNode.nodeName != 'class' && (!browser.ie || attrNode.specified) ) { + tgt.setAttribute(attrNode.nodeName, attrNode.nodeValue); + } + } + if (src.className) { + domUtils.addClass(tgt,src.className); + } + if (src.style.cssText) { + tgt.style.cssText += ';' + src.style.cssText; + } + }, + removeStyle: function (el, styleName){ + if (el.style.removeProperty) { + el.style.removeProperty(styleName); + } else if (el.style.removeAttribute) { + el.style.removeAttribute(styleName); + } else throw ''; + }, + contains: function (elA, elB){ + return elA && elB && (elA === elB ? false : ( + elA.contains ? elA.contains(elB) : + elA.compareDocumentPosition(elB) & 16 + )); + }, + startDrag: function (evt, callbacks,doc){ + var doc = doc || document; + var startX = evt.clientX; + var startY = evt.clientY; + function handleMouseMove(evt){ + var x = evt.clientX - startX; + var y = evt.clientY - startY; + callbacks.ondragmove(x, y,evt); + if (evt.stopPropagation) { + evt.stopPropagation(); + } else { + evt.cancelBubble = true; + } + } + if (doc.addEventListener) { + function handleMouseUp(evt){ + doc.removeEventListener('mousemove', handleMouseMove, true); + doc.removeEventListener('mouseup', handleMouseUp, true); + window.removeEventListener('mouseup', handleMouseUp, true); + callbacks.ondragstop(); + } + doc.addEventListener('mousemove', handleMouseMove, true); + doc.addEventListener('mouseup', handleMouseUp, true); + window.addEventListener('mouseup', handleMouseUp, true); + + evt.preventDefault(); + } else { + var elm = evt.srcElement; + elm.setCapture(); + function releaseCaptrue(){ + elm.releaseCapture(); + elm.detachEvent('onmousemove', handleMouseMove); + elm.detachEvent('onmouseup', releaseCaptrue); + elm.detachEvent('onlosecaptrue', releaseCaptrue); + callbacks.ondragstop(); + } + elm.attachEvent('onmousemove', handleMouseMove); + elm.attachEvent('onmouseup', releaseCaptrue); + elm.attachEvent('onlosecaptrue', releaseCaptrue); + evt.returnValue = false; + } + callbacks.ondragstart(); + }, + getFixedLayer: function (){ + var layer = document.getElementById('edui_fixedlayer'); + if (layer == null) { + layer = document.createElement('div'); + layer.id = 'edui_fixedlayer'; + document.body.appendChild(layer); + if (browser.ie && browser.version <= 8) { + layer.style.position = 'absolute'; + bindFixedLayer(); + setTimeout(updateFixedOffset); + } else { + layer.style.position = 'fixed'; + } + layer.style.left = '0'; + layer.style.top = '0'; + layer.style.width = '0'; + layer.style.height = '0'; + } + return layer; + }, + makeUnselectable: function (element){ + if (browser.opera || (browser.ie && browser.version < 9)) { + element.unselectable = 'on'; + if (element.hasChildNodes()) { + for (var i=0; i'; + } + }; + utils.inherits(Separator, UIBase); + +})(); + + +// ui/mask.js +///import core +///import uicore +(function (){ + var utils = baidu.editor.utils, + domUtils = baidu.editor.dom.domUtils, + UIBase = baidu.editor.ui.UIBase, + uiUtils = baidu.editor.ui.uiUtils; + + var Mask = baidu.editor.ui.Mask = function (options){ + this.initOptions(options); + this.initUIBase(); + }; + Mask.prototype = { + getHtmlTpl: function (){ + return '
      '; + }, + postRender: function (){ + var me = this; + domUtils.on(window, 'resize', function (){ + setTimeout(function (){ + if (!me.isHidden()) { + me._fill(); + } + }); + }); + }, + show: function (zIndex){ + this._fill(); + this.getDom().style.display = ''; + this.getDom().style.zIndex = zIndex; + }, + hide: function (){ + this.getDom().style.display = 'none'; + this.getDom().style.zIndex = ''; + }, + isHidden: function (){ + return this.getDom().style.display == 'none'; + }, + _onMouseDown: function (){ + return false; + }, + _onClick: function (e, target){ + this.fireEvent('click', e, target); + }, + _fill: function (){ + var el = this.getDom(); + var vpRect = uiUtils.getViewportRect(); + el.style.width = vpRect.width + 'px'; + el.style.height = vpRect.height + 'px'; + } + }; + utils.inherits(Mask, UIBase); +})(); + + +// ui/popup.js +///import core +///import uicore +(function () { + var utils = baidu.editor.utils, + uiUtils = baidu.editor.ui.uiUtils, + domUtils = baidu.editor.dom.domUtils, + UIBase = baidu.editor.ui.UIBase, + Popup = baidu.editor.ui.Popup = function (options){ + this.initOptions(options); + this.initPopup(); + }; + + var allPopups = []; + function closeAllPopup( evt,el ){ + for ( var i = 0; i < allPopups.length; i++ ) { + var pop = allPopups[i]; + if (!pop.isHidden()) { + if (pop.queryAutoHide(el) !== false) { + if(evt&&/scroll/ig.test(evt.type)&&pop.className=="edui-wordpastepop") return; + pop.hide(); + } + } + } + + if(allPopups.length) + pop.editor.fireEvent("afterhidepop"); + } + + Popup.postHide = closeAllPopup; + + var ANCHOR_CLASSES = ['edui-anchor-topleft','edui-anchor-topright', + 'edui-anchor-bottomleft','edui-anchor-bottomright']; + Popup.prototype = { + SHADOW_RADIUS: 5, + content: null, + _hidden: false, + autoRender: true, + canSideLeft: true, + canSideUp: true, + initPopup: function (){ + this.initUIBase(); + allPopups.push( this ); + }, + getHtmlTpl: function (){ + return '
      ' + + '
      ' + + ' ' + + '
      ' + + '
      ' + + this.getContentHtmlTpl() + + '
      ' + + '
      ' + + '
      '; + }, + getContentHtmlTpl: function (){ + if(this.content){ + if (typeof this.content == 'string') { + return this.content; + } + return this.content.renderHtml(); + }else{ + return '' + } + + }, + _UIBase_postRender: UIBase.prototype.postRender, + postRender: function (){ + + + if (this.content instanceof UIBase) { + this.content.postRender(); + } + + //捕获鼠标滚轮 + if( this.captureWheel && !this.captured ) { + + this.captured = true; + + var winHeight = ( document.documentElement.clientHeight || document.body.clientHeight ) - 80, + _height = this.getDom().offsetHeight, + _top = uiUtils.getClientRect( this.combox.getDom() ).top, + content = this.getDom('content'), + ifr = this.getDom('body').getElementsByTagName('iframe'), + me = this; + + ifr.length && ( ifr = ifr[0] ); + + while( _top + _height > winHeight ) { + _height -= 30; + } + content.style.height = _height + 'px'; + //同步更改iframe高度 + ifr && ( ifr.style.height = _height + 'px' ); + + //阻止在combox上的鼠标滚轮事件, 防止用户的正常操作被误解 + if( window.XMLHttpRequest ) { + + domUtils.on( content, ( 'onmousewheel' in document.body ) ? 'mousewheel' :'DOMMouseScroll' , function(e){ + + if(e.preventDefault) { + e.preventDefault(); + } else { + e.returnValue = false; + } + + if( e.wheelDelta ) { + + content.scrollTop -= ( e.wheelDelta / 120 )*60; + + } else { + + content.scrollTop -= ( e.detail / -3 )*60; + + } + + }); + + } else { + + //ie6 + domUtils.on( this.getDom(), 'mousewheel' , function(e){ + + e.returnValue = false; + + me.getDom('content').scrollTop -= ( e.wheelDelta / 120 )*60; + + }); + + } + + } + this.fireEvent('postRenderAfter'); + this.hide(true); + this._UIBase_postRender(); + }, + _doAutoRender: function (){ + if (!this.getDom() && this.autoRender) { + this.render(); + } + }, + mesureSize: function (){ + var box = this.getDom('content'); + return uiUtils.getClientRect(box); + }, + fitSize: function (){ + if( this.captureWheel && this.sized ) { + return this.__size; + } + this.sized = true; + var popBodyEl = this.getDom('body'); + popBodyEl.style.width = ''; + popBodyEl.style.height = ''; + var size = this.mesureSize(); + if( this.captureWheel ) { + popBodyEl.style.width = -(-20 -size.width) + 'px'; + var height = parseInt( this.getDom('content').style.height, 10 ); + !window.isNaN( height ) && ( size.height = height ); + } else { + popBodyEl.style.width = size.width + 'px'; + } + popBodyEl.style.height = size.height + 'px'; + this.__size = size; + this.captureWheel && (this.getDom('content').style.overflow = 'auto'); + return size; + }, + showAnchor: function ( element, hoz ){ + this.showAnchorRect( uiUtils.getClientRect( element ), hoz ); + }, + showAnchorRect: function ( rect, hoz, adj ){ + this._doAutoRender(); + var vpRect = uiUtils.getViewportRect(); + this.getDom().style.visibility = 'hidden'; + this._show(); + var popSize = this.fitSize(); + + var sideLeft, sideUp, left, top; + if (hoz) { + sideLeft = this.canSideLeft && (rect.right + popSize.width > vpRect.right && rect.left > popSize.width); + sideUp = this.canSideUp && (rect.top + popSize.height > vpRect.bottom && rect.bottom > popSize.height); + left = (sideLeft ? rect.left - popSize.width : rect.right); + top = (sideUp ? rect.bottom - popSize.height : rect.top); + } else { + sideLeft = this.canSideLeft && (rect.right + popSize.width > vpRect.right && rect.left > popSize.width); + sideUp = this.canSideUp && (rect.top + popSize.height > vpRect.bottom && rect.bottom > popSize.height); + left = (sideLeft ? rect.right - popSize.width : rect.left); + top = (sideUp ? rect.top - popSize.height : rect.bottom); + } + + var popEl = this.getDom(); + uiUtils.setViewportOffset(popEl, { + left: left, + top: top + }); + domUtils.removeClasses(popEl, ANCHOR_CLASSES); + popEl.className += ' ' + ANCHOR_CLASSES[(sideUp ? 1 : 0) * 2 + (sideLeft ? 1 : 0)]; + if(this.editor){ + popEl.style.zIndex = this.editor.container.style.zIndex * 1 + 10; + baidu.editor.ui.uiUtils.getFixedLayer().style.zIndex = popEl.style.zIndex - 1; + } + this.getDom().style.visibility = 'visible'; + + }, + showAt: function (offset) { + var left = offset.left; + var top = offset.top; + var rect = { + left: left, + top: top, + right: left, + bottom: top, + height: 0, + width: 0 + }; + this.showAnchorRect(rect, false, true); + }, + _show: function (){ + if (this._hidden) { + var box = this.getDom(); + box.style.display = ''; + this._hidden = false; +// if (box.setActive) { +// box.setActive(); +// } + this.fireEvent('show'); + } + }, + isHidden: function (){ + return this._hidden; + }, + show: function (){ + this._doAutoRender(); + this._show(); + }, + hide: function (notNofity){ + if (!this._hidden && this.getDom()) { + this.getDom().style.display = 'none'; + this._hidden = true; + if (!notNofity) { + this.fireEvent('hide'); + } + } + }, + queryAutoHide: function (el){ + return !el || !uiUtils.contains(this.getDom(), el); + } + }; + utils.inherits(Popup, UIBase); + + domUtils.on( document, 'mousedown', function ( evt ) { + var el = evt.target || evt.srcElement; + closeAllPopup( evt,el ); + } ); + domUtils.on( window, 'scroll', function (evt,el) { + closeAllPopup( evt,el ); + } ); + +})(); + + +// ui/colorpicker.js +///import core +///import uicore +(function (){ + var utils = baidu.editor.utils, + UIBase = baidu.editor.ui.UIBase, + ColorPicker = baidu.editor.ui.ColorPicker = function (options){ + this.initOptions(options); + this.noColorText = this.noColorText || this.editor.getLang("clearColor"); + this.initUIBase(); + }; + + ColorPicker.prototype = { + getHtmlTpl: function (){ + return genColorPicker(this.noColorText,this.editor); + }, + _onTableClick: function (evt){ + var tgt = evt.target || evt.srcElement; + var color = tgt.getAttribute('data-color'); + if (color) { + this.fireEvent('pickcolor', color); + } + }, + _onTableOver: function (evt){ + var tgt = evt.target || evt.srcElement; + var color = tgt.getAttribute('data-color'); + if (color) { + this.getDom('preview').style.backgroundColor = color; + } + }, + _onTableOut: function (){ + this.getDom('preview').style.backgroundColor = ''; + }, + _onPickNoColor: function (){ + this.fireEvent('picknocolor'); + } + }; + utils.inherits(ColorPicker, UIBase); + + var COLORS = ( + 'ffffff,000000,eeece1,1f497d,4f81bd,c0504d,9bbb59,8064a2,4bacc6,f79646,' + + 'f2f2f2,7f7f7f,ddd9c3,c6d9f0,dbe5f1,f2dcdb,ebf1dd,e5e0ec,dbeef3,fdeada,' + + 'd8d8d8,595959,c4bd97,8db3e2,b8cce4,e5b9b7,d7e3bc,ccc1d9,b7dde8,fbd5b5,' + + 'bfbfbf,3f3f3f,938953,548dd4,95b3d7,d99694,c3d69b,b2a2c7,92cddc,fac08f,' + + 'a5a5a5,262626,494429,17365d,366092,953734,76923c,5f497a,31859b,e36c09,' + + '7f7f7f,0c0c0c,1d1b10,0f243e,244061,632423,4f6128,3f3151,205867,974806,' + + 'c00000,ff0000,ffc000,ffff00,92d050,00b050,00b0f0,0070c0,002060,7030a0,').split(','); + + function genColorPicker(noColorText,editor){ + var html = '
      ' + + '
      ' + + '
      ' + + '
      '+ noColorText +'
      ' + + '
      ' + + '' + + ''+ + ''; + for (var i=0; i':'')+''; + } + html += i<70 ? '':''; + } + html += '
      '+editor.getLang("themeColor")+'
      '+editor.getLang("standardColor")+'
      '; + return html; + } +})(); + + +// ui/tablepicker.js +///import core +///import uicore +(function (){ + var utils = baidu.editor.utils, + uiUtils = baidu.editor.ui.uiUtils, + UIBase = baidu.editor.ui.UIBase; + + var TablePicker = baidu.editor.ui.TablePicker = function (options){ + this.initOptions(options); + this.initTablePicker(); + }; + TablePicker.prototype = { + defaultNumRows: 10, + defaultNumCols: 10, + maxNumRows: 20, + maxNumCols: 20, + numRows: 10, + numCols: 10, + lengthOfCellSide: 22, + initTablePicker: function (){ + this.initUIBase(); + }, + getHtmlTpl: function (){ + var me = this; + return '
      ' + + '
      ' + + '
      ' + + '' + + '
      ' + + '
      ' + + '
      ' + + '
      ' + + '
      ' + + '
      '; + }, + _UIBase_render: UIBase.prototype.render, + render: function (holder){ + this._UIBase_render(holder); + this.getDom('label').innerHTML = '0'+this.editor.getLang("t_row")+' x 0'+this.editor.getLang("t_col"); + }, + _track: function (numCols, numRows){ + var style = this.getDom('overlay').style; + var sideLen = this.lengthOfCellSide; + style.width = numCols * sideLen + 'px'; + style.height = numRows * sideLen + 'px'; + var label = this.getDom('label'); + label.innerHTML = numCols +this.editor.getLang("t_col")+' x ' + numRows + this.editor.getLang("t_row"); + this.numCols = numCols; + this.numRows = numRows; + }, + _onMouseOver: function (evt, el){ + var rel = evt.relatedTarget || evt.fromElement; + if (!uiUtils.contains(el, rel) && el !== rel) { + this.getDom('label').innerHTML = '0'+this.editor.getLang("t_col")+' x 0'+this.editor.getLang("t_row"); + this.getDom('overlay').style.visibility = ''; + } + }, + _onMouseOut: function (evt, el){ + var rel = evt.relatedTarget || evt.toElement; + if (!uiUtils.contains(el, rel) && el !== rel) { + this.getDom('label').innerHTML = '0'+this.editor.getLang("t_col")+' x 0'+this.editor.getLang("t_row"); + this.getDom('overlay').style.visibility = 'hidden'; + } + }, + _onMouseMove: function (evt, el){ + var style = this.getDom('overlay').style; + var offset = uiUtils.getEventOffset(evt); + var sideLen = this.lengthOfCellSide; + var numCols = Math.ceil(offset.left / sideLen); + var numRows = Math.ceil(offset.top / sideLen); + this._track(numCols, numRows); + }, + _onClick: function (){ + this.fireEvent('picktable', this.numCols, this.numRows); + } + }; + utils.inherits(TablePicker, UIBase); +})(); + + +// ui/stateful.js +(function (){ + var browser = baidu.editor.browser, + domUtils = baidu.editor.dom.domUtils, + uiUtils = baidu.editor.ui.uiUtils; + + var TPL_STATEFUL = 'onmousedown="$$.Stateful_onMouseDown(event, this);"' + + ' onmouseup="$$.Stateful_onMouseUp(event, this);"' + + ( browser.ie ? ( + ' onmouseenter="$$.Stateful_onMouseEnter(event, this);"' + + ' onmouseleave="$$.Stateful_onMouseLeave(event, this);"' ) + : ( + ' onmouseover="$$.Stateful_onMouseOver(event, this);"' + + ' onmouseout="$$.Stateful_onMouseOut(event, this);"' )); + + baidu.editor.ui.Stateful = { + alwalysHoverable: false, + target:null,//目标元素和this指向dom不一样 + Stateful_init: function (){ + this._Stateful_dGetHtmlTpl = this.getHtmlTpl; + this.getHtmlTpl = this.Stateful_getHtmlTpl; + }, + Stateful_getHtmlTpl: function (){ + var tpl = this._Stateful_dGetHtmlTpl(); + // 使用function避免$转义 + return tpl.replace(/stateful/g, function (){ return TPL_STATEFUL; }); + }, + Stateful_onMouseEnter: function (evt, el){ + this.target=el; + if (!this.isDisabled() || this.alwalysHoverable) { + this.addState('hover'); + this.fireEvent('over'); + } + }, + Stateful_onMouseLeave: function (evt, el){ + if (!this.isDisabled() || this.alwalysHoverable) { + this.removeState('hover'); + this.removeState('active'); + this.fireEvent('out'); + } + }, + Stateful_onMouseOver: function (evt, el){ + var rel = evt.relatedTarget; + if (!uiUtils.contains(el, rel) && el !== rel) { + this.Stateful_onMouseEnter(evt, el); + } + }, + Stateful_onMouseOut: function (evt, el){ + var rel = evt.relatedTarget; + if (!uiUtils.contains(el, rel) && el !== rel) { + this.Stateful_onMouseLeave(evt, el); + } + }, + Stateful_onMouseDown: function (evt, el){ + if (!this.isDisabled()) { + this.addState('active'); + } + }, + Stateful_onMouseUp: function (evt, el){ + if (!this.isDisabled()) { + this.removeState('active'); + } + }, + Stateful_postRender: function (){ + if (this.disabled && !this.hasState('disabled')) { + this.addState('disabled'); + } + }, + hasState: function (state){ + return domUtils.hasClass(this.getStateDom(), 'edui-state-' + state); + }, + addState: function (state){ + if (!this.hasState(state)) { + this.getStateDom().className += ' edui-state-' + state; + } + }, + removeState: function (state){ + if (this.hasState(state)) { + domUtils.removeClasses(this.getStateDom(), ['edui-state-' + state]); + } + }, + getStateDom: function (){ + return this.getDom('state'); + }, + isChecked: function (){ + return this.hasState('checked'); + }, + setChecked: function (checked){ + if (!this.isDisabled() && checked) { + this.addState('checked'); + } else { + this.removeState('checked'); + } + }, + isDisabled: function (){ + return this.hasState('disabled'); + }, + setDisabled: function (disabled){ + if (disabled) { + this.removeState('hover'); + this.removeState('checked'); + this.removeState('active'); + this.addState('disabled'); + } else { + this.removeState('disabled'); + } + } + }; +})(); + + +// ui/button.js +///import core +///import uicore +///import ui/stateful.js +(function (){ + var utils = baidu.editor.utils, + UIBase = baidu.editor.ui.UIBase, + Stateful = baidu.editor.ui.Stateful, + Button = baidu.editor.ui.Button = function (options){ + if(options.name){ + var btnName = options.name; + var cssRules = options.cssRules; + if(!options.className){ + options.className = 'edui-for-' + btnName; + } + options.cssRules = '.edui-default .edui-for-'+ btnName +' .edui-icon {'+ cssRules +'}' + } + this.initOptions(options); + this.initButton(); + }; + Button.prototype = { + uiName: 'button', + label: '', + title: '', + showIcon: true, + showText: true, + cssRules:'', + initButton: function (){ + this.initUIBase(); + this.Stateful_init(); + if(this.cssRules){ + utils.cssRule('edui-customize-'+this.name+'-style',this.cssRules); + } + }, + getHtmlTpl: function (){ + return '
      ' + + '
      ' + + '
      ' + + (this.showIcon ? '
      ' : '') + + (this.showText ? '
      ' + this.label + '
      ' : '') + + '
      ' + + '
      ' + + '
      '; + }, + postRender: function (){ + this.Stateful_postRender(); + this.setDisabled(this.disabled) + }, + _onMouseDown: function (e){ + var target = e.target || e.srcElement, + tagName = target && target.tagName && target.tagName.toLowerCase(); + if (tagName == 'input' || tagName == 'object' || tagName == 'object') { + return false; + } + }, + _onClick: function (){ + if (!this.isDisabled()) { + this.fireEvent('click'); + } + }, + setTitle: function(text){ + var label = this.getDom('label'); + label.innerHTML = text; + } + }; + utils.inherits(Button, UIBase); + utils.extend(Button.prototype, Stateful); + +})(); + + +// ui/splitbutton.js +///import core +///import uicore +///import ui/stateful.js +(function (){ + var utils = baidu.editor.utils, + uiUtils = baidu.editor.ui.uiUtils, + domUtils = baidu.editor.dom.domUtils, + UIBase = baidu.editor.ui.UIBase, + Stateful = baidu.editor.ui.Stateful, + SplitButton = baidu.editor.ui.SplitButton = function (options){ + this.initOptions(options); + this.initSplitButton(); + }; + SplitButton.prototype = { + popup: null, + uiName: 'splitbutton', + title: '', + initSplitButton: function (){ + this.initUIBase(); + this.Stateful_init(); + var me = this; + if (this.popup != null) { + var popup = this.popup; + this.popup = null; + this.setPopup(popup); + } + }, + _UIBase_postRender: UIBase.prototype.postRender, + postRender: function (){ + this.Stateful_postRender(); + this._UIBase_postRender(); + }, + setPopup: function (popup){ + if (this.popup === popup) return; + if (this.popup != null) { + this.popup.dispose(); + } + popup.addListener('show', utils.bind(this._onPopupShow, this)); + popup.addListener('hide', utils.bind(this._onPopupHide, this)); + popup.addListener('postrender', utils.bind(function (){ + popup.getDom('body').appendChild( + uiUtils.createElementByHtml('
      ') + ); + popup.getDom().className += ' ' + this.className; + }, this)); + this.popup = popup; + }, + _onPopupShow: function (){ + this.addState('opened'); + }, + _onPopupHide: function (){ + this.removeState('opened'); + }, + getHtmlTpl: function (){ + return '
      ' + + '
      ' + + '
      ' + + '
      ' + + '
      ' + + '
      ' + + '
      ' + + '
      '; + }, + showPopup: function (){ + // 当popup往上弹出的时候,做特殊处理 + var rect = uiUtils.getClientRect(this.getDom()); + rect.top -= this.popup.SHADOW_RADIUS; + rect.height += this.popup.SHADOW_RADIUS; + this.popup.showAnchorRect(rect); + }, + _onArrowClick: function (event, el){ + if (!this.isDisabled()) { + this.showPopup(); + } + }, + _onButtonClick: function (){ + if (!this.isDisabled()) { + this.fireEvent('buttonclick'); + } + } + }; + utils.inherits(SplitButton, UIBase); + utils.extend(SplitButton.prototype, Stateful, true); + +})(); + + +// ui/colorbutton.js +///import core +///import uicore +///import ui/colorpicker.js +///import ui/popup.js +///import ui/splitbutton.js +(function (){ + var utils = baidu.editor.utils, + uiUtils = baidu.editor.ui.uiUtils, + ColorPicker = baidu.editor.ui.ColorPicker, + Popup = baidu.editor.ui.Popup, + SplitButton = baidu.editor.ui.SplitButton, + ColorButton = baidu.editor.ui.ColorButton = function (options){ + this.initOptions(options); + this.initColorButton(); + }; + ColorButton.prototype = { + initColorButton: function (){ + var me = this; + this.popup = new Popup({ + content: new ColorPicker({ + noColorText: me.editor.getLang("clearColor"), + editor:me.editor, + onpickcolor: function (t, color){ + me._onPickColor(color); + }, + onpicknocolor: function (t, color){ + me._onPickNoColor(color); + } + }), + editor:me.editor + }); + this.initSplitButton(); + }, + _SplitButton_postRender: SplitButton.prototype.postRender, + postRender: function (){ + this._SplitButton_postRender(); + this.getDom('button_body').appendChild( + uiUtils.createElementByHtml('
      ') + ); + this.getDom().className += ' edui-colorbutton'; + }, + setColor: function (color){ + this.getDom('colorlump').style.backgroundColor = color; + this.color = color; + }, + _onPickColor: function (color){ + if (this.fireEvent('pickcolor', color) !== false) { + this.setColor(color); + this.popup.hide(); + } + }, + _onPickNoColor: function (color){ + if (this.fireEvent('picknocolor') !== false) { + this.popup.hide(); + } + } + }; + utils.inherits(ColorButton, SplitButton); + +})(); + + +// ui/tablebutton.js +///import core +///import uicore +///import ui/popup.js +///import ui/tablepicker.js +///import ui/splitbutton.js +(function (){ + var utils = baidu.editor.utils, + Popup = baidu.editor.ui.Popup, + TablePicker = baidu.editor.ui.TablePicker, + SplitButton = baidu.editor.ui.SplitButton, + TableButton = baidu.editor.ui.TableButton = function (options){ + this.initOptions(options); + this.initTableButton(); + }; + TableButton.prototype = { + initTableButton: function (){ + var me = this; + this.popup = new Popup({ + content: new TablePicker({ + editor:me.editor, + onpicktable: function (t, numCols, numRows){ + me._onPickTable(numCols, numRows); + } + }), + 'editor':me.editor + }); + this.initSplitButton(); + }, + _onPickTable: function (numCols, numRows){ + if (this.fireEvent('picktable', numCols, numRows) !== false) { + this.popup.hide(); + } + } + }; + utils.inherits(TableButton, SplitButton); + +})(); + + +// ui/autotypesetpicker.js +///import core +///import uicore +(function () { + var utils = baidu.editor.utils, + UIBase = baidu.editor.ui.UIBase; + + var AutoTypeSetPicker = baidu.editor.ui.AutoTypeSetPicker = function (options) { + this.initOptions(options); + this.initAutoTypeSetPicker(); + }; + AutoTypeSetPicker.prototype = { + initAutoTypeSetPicker:function () { + this.initUIBase(); + }, + getHtmlTpl:function () { + var me = this.editor, + opt = me.options.autotypeset, + lang = me.getLang("autoTypeSet"); + + var textAlignInputName = 'textAlignValue' + me.uid, + imageBlockInputName = 'imageBlockLineValue' + me.uid, + symbolConverInputName = 'symbolConverValue' + me.uid; + + return '
      ' + + '
      ' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
      ' + lang.mergeLine + '' + lang.delLine + '
      ' + lang.removeFormat + '' + lang.indent + '
      ' + lang.alignment + '' + + '' + me.getLang("justifyleft") + + '' + me.getLang("justifycenter") + + '' + me.getLang("justifyright") + + '
      ' + lang.imageFloat + '' + + '' + me.getLang("default") + + '' + me.getLang("justifyleft") + + '' + me.getLang("justifycenter") + + '' + me.getLang("justifyright") + + '
      ' + lang.removeFontsize + '' + lang.removeFontFamily + '
      ' + lang.removeHtml + '
      ' + lang.pasteFilter + '
      ' + lang.symbol + '' + + '' + lang.bdc2sb + + '' + lang.tobdc + '' + + '
      ' + + '
      ' + + '
      '; + + + }, + _UIBase_render:UIBase.prototype.render + }; + utils.inherits(AutoTypeSetPicker, UIBase); +})(); + + +// ui/autotypesetbutton.js +///import core +///import uicore +///import ui/popup.js +///import ui/autotypesetpicker.js +///import ui/splitbutton.js +(function (){ + var utils = baidu.editor.utils, + Popup = baidu.editor.ui.Popup, + AutoTypeSetPicker = baidu.editor.ui.AutoTypeSetPicker, + SplitButton = baidu.editor.ui.SplitButton, + AutoTypeSetButton = baidu.editor.ui.AutoTypeSetButton = function (options){ + this.initOptions(options); + this.initAutoTypeSetButton(); + }; + function getPara(me){ + + var opt = {}, + cont = me.getDom(), + editorId = me.editor.uid, + inputType = null, + attrName = null, + ipts = domUtils.getElementsByTagName(cont,"input"); + for(var i=ipts.length-1,ipt;ipt=ipts[i--];){ + inputType = ipt.getAttribute("type"); + if(inputType=="checkbox"){ + attrName = ipt.getAttribute("name"); + opt[attrName] && delete opt[attrName]; + if(ipt.checked){ + var attrValue = document.getElementById( attrName + "Value" + editorId ); + if(attrValue){ + if(/input/ig.test(attrValue.tagName)){ + opt[attrName] = attrValue.value; + } else { + var iptChilds = attrValue.getElementsByTagName("input"); + for(var j=iptChilds.length-1,iptchild;iptchild=iptChilds[j--];){ + if(iptchild.checked){ + opt[attrName] = iptchild.value; + break; + } + } + } + } else { + opt[attrName] = true; + } + } else { + opt[attrName] = false; + } + } else { + opt[ipt.getAttribute("value")] = ipt.checked; + } + + } + + var selects = domUtils.getElementsByTagName(cont,"select"); + for(var i=0,si;si=selects[i++];){ + var attr = si.getAttribute('name'); + opt[attr] = opt[attr] ? si.value : ''; + } + + utils.extend(me.editor.options.autotypeset,opt); + + me.editor.setPreferences('autotypeset', opt); + } + + AutoTypeSetButton.prototype = { + initAutoTypeSetButton: function (){ + + var me = this; + this.popup = new Popup({ + //传入配置参数 + content: new AutoTypeSetPicker({editor:me.editor}), + 'editor':me.editor, + hide : function(){ + if (!this._hidden && this.getDom()) { + getPara(this); + this.getDom().style.display = 'none'; + this._hidden = true; + this.fireEvent('hide'); + } + } + }); + var flag = 0; + this.popup.addListener('postRenderAfter',function(){ + var popupUI = this; + if(flag)return; + var cont = this.getDom(), + btn = cont.getElementsByTagName('button')[0]; + + btn.onclick = function(){ + getPara(popupUI); + me.editor.execCommand('autotypeset'); + popupUI.hide() + }; + + domUtils.on(cont, 'click', function(e) { + var target = e.target || e.srcElement, + editorId = me.editor.uid; + if (target && target.tagName == 'INPUT') { + + // 点击图片浮动的checkbox,去除对应的radio + if (target.name == 'imageBlockLine' || target.name == 'textAlign' || target.name == 'symbolConver') { + var checked = target.checked, + radioTd = document.getElementById( target.name + 'Value' + editorId), + radios = radioTd.getElementsByTagName('input'), + defalutSelect = { + 'imageBlockLine': 'none', + 'textAlign': 'left', + 'symbolConver': 'tobdc' + }; + + for (var i = 0; i < radios.length; i++) { + if (checked) { + if (radios[i].value == defalutSelect[target.name]) { + radios[i].checked = 'checked'; + } + } else { + radios[i].checked = false; + } + } + } + // 点击radio,选中对应的checkbox + if (target.name == ('imageBlockLineValue' + editorId) || target.name == ('textAlignValue' + editorId) || target.name == 'bdc') { + var checkboxs = target.parentNode.previousSibling.getElementsByTagName('input'); + checkboxs && (checkboxs[0].checked = true); + } + + getPara(popupUI); + } + }); + + flag = 1; + }); + this.initSplitButton(); + } + }; + utils.inherits(AutoTypeSetButton, SplitButton); + +})(); + + +// ui/cellalignpicker.js +///import core +///import uicore +(function () { + var utils = baidu.editor.utils, + Popup = baidu.editor.ui.Popup, + Stateful = baidu.editor.ui.Stateful, + UIBase = baidu.editor.ui.UIBase; + + /** + * 该参数将新增一个参数: selected, 参数类型为一个Object, 形如{ 'align': 'center', 'valign': 'top' }, 表示单元格的初始 + * 对齐状态为: 竖直居上,水平居中; 其中 align的取值为:'center', 'left', 'right'; valign的取值为: 'top', 'middle', 'bottom' + * @update 2013/4/2 hancong03@baidu.com + */ + var CellAlignPicker = baidu.editor.ui.CellAlignPicker = function (options) { + this.initOptions(options); + this.initSelected(); + this.initCellAlignPicker(); + }; + CellAlignPicker.prototype = { + //初始化选中状态, 该方法将根据传递进来的参数获取到应该选中的对齐方式图标的索引 + initSelected: function(){ + + var status = { + + valign: { + top: 0, + middle: 1, + bottom: 2 + }, + align: { + left: 0, + center: 1, + right: 2 + }, + count: 3 + + }, + result = -1; + + if( this.selected ) { + this.selectedIndex = status.valign[ this.selected.valign ] * status.count + status.align[ this.selected.align ]; + } + + }, + initCellAlignPicker:function () { + this.initUIBase(); + this.Stateful_init(); + }, + getHtmlTpl:function () { + + var alignType = [ 'left', 'center', 'right' ], + COUNT = 9, + tempClassName = null, + tempIndex = -1, + tmpl = []; + + + for( var i= 0; i'); + + tmpl.push( '
      ' + + tmpl.join('') + + '
      ' + + '
      ' + + ''; + }, + getStateDom: function (){ + return this.target; + }, + _onClick: function (evt){ + var target= evt.target || evt.srcElement; + if(/icon/.test(target.className)){ + this.items[target.parentNode.getAttribute("index")].onclick(); + Popup.postHide(evt); + } + }, + _UIBase_render:UIBase.prototype.render + }; + utils.inherits(CellAlignPicker, UIBase); + utils.extend(CellAlignPicker.prototype, Stateful,true); +})(); + + + + + +// ui/pastepicker.js +///import core +///import uicore +(function () { + var utils = baidu.editor.utils, + Stateful = baidu.editor.ui.Stateful, + uiUtils = baidu.editor.ui.uiUtils, + UIBase = baidu.editor.ui.UIBase; + + var PastePicker = baidu.editor.ui.PastePicker = function (options) { + this.initOptions(options); + this.initPastePicker(); + }; + PastePicker.prototype = { + initPastePicker:function () { + this.initUIBase(); + this.Stateful_init(); + }, + getHtmlTpl:function () { + return '
      ' + + '
      ' + + '
      ' + this.editor.getLang("pasteOpt") + '
      ' + + '
      ' + + '
      ' + + '
      ' + + '
      ' + + '
      ' + + '
      ' + + '
      ' + + '
      ' + + '
      ' + + '' + }, + getStateDom:function () { + return this.target; + }, + format:function (param) { + this.editor.ui._isTransfer = true; + this.editor.fireEvent('pasteTransfer', param); + }, + _onClick:function (cur) { + var node = domUtils.getNextDomNode(cur), + screenHt = uiUtils.getViewportRect().height, + subPop = uiUtils.getClientRect(node); + + if ((subPop.top + subPop.height) > screenHt) + node.style.top = (-subPop.height - cur.offsetHeight) + "px"; + else + node.style.top = ""; + + if (/hidden/ig.test(domUtils.getComputedStyle(node, "visibility"))) { + node.style.visibility = "visible"; + domUtils.addClass(cur, "edui-state-opened"); + } else { + node.style.visibility = "hidden"; + domUtils.removeClasses(cur, "edui-state-opened") + } + }, + _UIBase_render:UIBase.prototype.render + }; + utils.inherits(PastePicker, UIBase); + utils.extend(PastePicker.prototype, Stateful, true); +})(); + + + + + + +// ui/toolbar.js +(function (){ + var utils = baidu.editor.utils, + uiUtils = baidu.editor.ui.uiUtils, + UIBase = baidu.editor.ui.UIBase, + Toolbar = baidu.editor.ui.Toolbar = function (options){ + this.initOptions(options); + this.initToolbar(); + }; + Toolbar.prototype = { + items: null, + initToolbar: function (){ + this.items = this.items || []; + this.initUIBase(); + }, + add: function (item,index){ + if(index === undefined){ + this.items.push(item); + }else{ + this.items.splice(index,0,item) + } + + }, + getHtmlTpl: function (){ + var buff = []; + for (var i=0; i' + + buff.join('') + + '' + }, + postRender: function (){ + var box = this.getDom(); + for (var i=0; i
      '; + }, + postRender:function () { + }, + queryAutoHide:function () { + return true; + } + }; + Menu.prototype = { + items:null, + uiName:'menu', + initMenu:function () { + this.items = this.items || []; + this.initPopup(); + this.initItems(); + }, + initItems:function () { + for (var i = 0; i < this.items.length; i++) { + var item = this.items[i]; + if (item == '-') { + this.items[i] = this.getSeparator(); + } else if (!(item instanceof MenuItem)) { + item.editor = this.editor; + item.theme = this.editor.options.theme; + this.items[i] = this.createItem(item); + } + } + }, + getSeparator:function () { + return menuSeparator; + }, + createItem:function (item) { + //新增一个参数menu, 该参数存储了menuItem所对应的menu引用 + item.menu = this; + return new MenuItem(item); + }, + _Popup_getContentHtmlTpl:Popup.prototype.getContentHtmlTpl, + getContentHtmlTpl:function () { + if (this.items.length == 0) { + return this._Popup_getContentHtmlTpl(); + } + var buff = []; + for (var i = 0; i < this.items.length; i++) { + var item = this.items[i]; + buff[i] = item.renderHtml(); + } + return ('
      ' + buff.join('') + '
      '); + }, + _Popup_postRender:Popup.prototype.postRender, + postRender:function () { + var me = this; + for (var i = 0; i < this.items.length; i++) { + var item = this.items[i]; + item.ownerMenu = this; + item.postRender(); + } + domUtils.on(this.getDom(), 'mouseover', function (evt) { + evt = evt || event; + var rel = evt.relatedTarget || evt.fromElement; + var el = me.getDom(); + if (!uiUtils.contains(el, rel) && el !== rel) { + me.fireEvent('over'); + } + }); + this._Popup_postRender(); + }, + queryAutoHide:function (el) { + if (el) { + if (uiUtils.contains(this.getDom(), el)) { + return false; + } + for (var i = 0; i < this.items.length; i++) { + var item = this.items[i]; + if (item.queryAutoHide(el) === false) { + return false; + } + } + } + }, + clearItems:function () { + for (var i = 0; i < this.items.length; i++) { + var item = this.items[i]; + clearTimeout(item._showingTimer); + clearTimeout(item._closingTimer); + if (item.subMenu) { + item.subMenu.destroy(); + } + } + this.items = []; + }, + destroy:function () { + if (this.getDom()) { + domUtils.remove(this.getDom()); + } + this.clearItems(); + }, + dispose:function () { + this.destroy(); + } + }; + utils.inherits(Menu, Popup); + + /** + * @update 2013/04/03 hancong03 新增一个参数menu, 该参数存储了menuItem所对应的menu引用 + * @type {Function} + */ + var MenuItem = baidu.editor.ui.MenuItem = function (options) { + this.initOptions(options); + this.initUIBase(); + this.Stateful_init(); + if (this.subMenu && !(this.subMenu instanceof Menu)) { + if (options.className && options.className.indexOf("aligntd") != -1) { + var me = this; + + //获取单元格对齐初始状态 + this.subMenu.selected = this.editor.queryCommandValue( 'cellalignment' ); + + this.subMenu = new Popup({ + content:new CellAlignPicker(this.subMenu), + parentMenu:me, + editor:me.editor, + destroy:function () { + if (this.getDom()) { + domUtils.remove(this.getDom()); + } + } + }); + this.subMenu.addListener("postRenderAfter", function () { + domUtils.on(this.getDom(), "mouseover", function () { + me.addState('opened'); + }); + }); + } else { + this.subMenu = new Menu(this.subMenu); + } + } + }; + MenuItem.prototype = { + label:'', + subMenu:null, + ownerMenu:null, + uiName:'menuitem', + alwalysHoverable:true, + getHtmlTpl:function () { + return '
      ' + + '
      ' + + this.renderLabelHtml() + + '
      ' + + '
      '; + }, + postRender:function () { + var me = this; + this.addListener('over', function () { + me.ownerMenu.fireEvent('submenuover', me); + if (me.subMenu) { + me.delayShowSubMenu(); + } + }); + if (this.subMenu) { + this.getDom().className += ' edui-hassubmenu'; + this.subMenu.render(); + this.addListener('out', function () { + me.delayHideSubMenu(); + }); + this.subMenu.addListener('over', function () { + clearTimeout(me._closingTimer); + me._closingTimer = null; + me.addState('opened'); + }); + this.ownerMenu.addListener('hide', function () { + me.hideSubMenu(); + }); + this.ownerMenu.addListener('submenuover', function (t, subMenu) { + if (subMenu !== me) { + me.delayHideSubMenu(); + } + }); + this.subMenu._bakQueryAutoHide = this.subMenu.queryAutoHide; + this.subMenu.queryAutoHide = function (el) { + if (el && uiUtils.contains(me.getDom(), el)) { + return false; + } + return this._bakQueryAutoHide(el); + }; + } + this.getDom().style.tabIndex = '-1'; + uiUtils.makeUnselectable(this.getDom()); + this.Stateful_postRender(); + }, + delayShowSubMenu:function () { + var me = this; + if (!me.isDisabled()) { + me.addState('opened'); + clearTimeout(me._showingTimer); + clearTimeout(me._closingTimer); + me._closingTimer = null; + me._showingTimer = setTimeout(function () { + me.showSubMenu(); + }, 250); + } + }, + delayHideSubMenu:function () { + var me = this; + if (!me.isDisabled()) { + me.removeState('opened'); + clearTimeout(me._showingTimer); + if (!me._closingTimer) { + me._closingTimer = setTimeout(function () { + if (!me.hasState('opened')) { + me.hideSubMenu(); + } + me._closingTimer = null; + }, 400); + } + } + }, + renderLabelHtml:function () { + return '
      ' + + '
      ' + + '
      ' + (this.label || '') + '
      '; + }, + getStateDom:function () { + return this.getDom(); + }, + queryAutoHide:function (el) { + if (this.subMenu && this.hasState('opened')) { + return this.subMenu.queryAutoHide(el); + } + }, + _onClick:function (event, this_) { + if (this.hasState('disabled')) return; + if (this.fireEvent('click', event, this_) !== false) { + if (this.subMenu) { + this.showSubMenu(); + } else { + Popup.postHide(event); + } + } + }, + showSubMenu:function () { + var rect = uiUtils.getClientRect(this.getDom()); + rect.right -= 5; + rect.left += 2; + rect.width -= 7; + rect.top -= 4; + rect.bottom += 4; + rect.height += 8; + this.subMenu.showAnchorRect(rect, true, true); + }, + hideSubMenu:function () { + this.subMenu.hide(); + } + }; + utils.inherits(MenuItem, UIBase); + utils.extend(MenuItem.prototype, Stateful, true); +})(); + + +// ui/combox.js +///import core +///import uicore +///import ui/menu.js +///import ui/splitbutton.js +(function (){ + // todo: menu和item提成通用list + var utils = baidu.editor.utils, + uiUtils = baidu.editor.ui.uiUtils, + Menu = baidu.editor.ui.Menu, + SplitButton = baidu.editor.ui.SplitButton, + Combox = baidu.editor.ui.Combox = function (options){ + this.initOptions(options); + this.initCombox(); + }; + Combox.prototype = { + uiName: 'combox', + onbuttonclick:function () { + this.showPopup(); + }, + initCombox: function (){ + var me = this; + this.items = this.items || []; + for (var i=0; i vpRect.right) { + left = vpRect.right - rect.width; + } + var top = offset.top; + if (top + rect.height > vpRect.bottom) { + top = vpRect.bottom - rect.height; + } + el.style.left = Math.max(left, 0) + 'px'; + el.style.top = Math.max(top, 0) + 'px'; + }, + showAtCenter: function (){ + + var vpRect = uiUtils.getViewportRect(); + + if ( !this.fullscreen ) { + this.getDom().style.display = ''; + var popSize = this.fitSize(); + var titleHeight = this.getDom('titlebar').offsetHeight | 0; + var left = vpRect.width / 2 - popSize.width / 2; + var top = vpRect.height / 2 - (popSize.height - titleHeight) / 2 - titleHeight; + var popEl = this.getDom(); + this.safeSetOffset({ + left: Math.max(left | 0, 0), + top: Math.max(top | 0, 0) + }); + if (!domUtils.hasClass(popEl, 'edui-state-centered')) { + popEl.className += ' edui-state-centered'; + } + } else { + var dialogWrapNode = this.getDom(), + contentNode = this.getDom('content'); + + dialogWrapNode.style.display = "block"; + + var wrapRect = UE.ui.uiUtils.getClientRect( dialogWrapNode ), + contentRect = UE.ui.uiUtils.getClientRect( contentNode ); + dialogWrapNode.style.left = "-100000px"; + + contentNode.style.width = ( vpRect.width - wrapRect.width + contentRect.width ) + "px"; + contentNode.style.height = ( vpRect.height - wrapRect.height + contentRect.height ) + "px"; + + dialogWrapNode.style.width = vpRect.width + "px"; + dialogWrapNode.style.height = vpRect.height + "px"; + dialogWrapNode.style.left = 0; + + //保存环境的overflow值 + this._originalContext = { + html: { + overflowX: document.documentElement.style.overflowX, + overflowY: document.documentElement.style.overflowY + }, + body: { + overflowX: document.body.style.overflowX, + overflowY: document.body.style.overflowY + } + }; + + document.documentElement.style.overflowX = 'hidden'; + document.documentElement.style.overflowY = 'hidden'; + document.body.style.overflowX = 'hidden'; + document.body.style.overflowY = 'hidden'; + + } + + this._show(); + }, + getContentHtml: function (){ + var contentHtml = ''; + if (typeof this.content == 'string') { + contentHtml = this.content; + } else if (this.iframeUrl) { + contentHtml = ''; + } + return contentHtml; + }, + getHtmlTpl: function (){ + var footHtml = ''; + + if (this.buttons) { + var buff = []; + for (var i=0; i' + buff.join('') + '' + + ''; + } + + return '
      ' + + '
      ' + + '
      ' + + '
      ' + + '' + (this.title || '') + '' + + '
      ' + + this.closeButton.renderHtml() + + '
      ' + + '
      '+ ( this.autoReset ? '' : this.getContentHtml()) +'
      ' + + footHtml + + '
      '; + }, + postRender: function (){ + // todo: 保持居中/记住上次关闭位置选项 + if (!this.modalMask.getDom()) { + this.modalMask.render(); + this.modalMask.hide(); + } + if (!this.dragMask.getDom()) { + this.dragMask.render(); + this.dragMask.hide(); + } + var me = this; + this.addListener('show', function (){ + me.modalMask.show(this.getDom().style.zIndex - 2); + }); + this.addListener('hide', function (){ + me.modalMask.hide(); + }); + if (this.buttons) { + for (var i=0; i'; + me.editor.container.style.zIndex && (this.getDom().style.zIndex = me.editor.container.style.zIndex * 1 + 1); + } + } + // canSideUp:false, + // canSideLeft:false + }); + this.onbuttonclick = function(){ + this.showPopup(); + }; + this.initSplitButton(); + } + + }; + + utils.inherits(MultiMenuPop, SplitButton); +})(); + + +// ui/shortcutmenu.js +(function () { + var UI = baidu.editor.ui, + UIBase = UI.UIBase, + uiUtils = UI.uiUtils, + utils = baidu.editor.utils, + domUtils = baidu.editor.dom.domUtils; + + var allMenus = [],//存储所有快捷菜单 + timeID, + isSubMenuShow = false;//是否有子pop显示 + + var ShortCutMenu = UI.ShortCutMenu = function (options) { + this.initOptions (options); + this.initShortCutMenu (); + }; + + ShortCutMenu.postHide = hideAllMenu; + + ShortCutMenu.prototype = { + isHidden : true , + SPACE : 5 , + initShortCutMenu : function () { + this.items = this.items || []; + this.initUIBase (); + this.initItems (); + this.initEvent (); + allMenus.push (this); + } , + initEvent : function () { + var me = this, + doc = me.editor.document; + + domUtils.on (doc , "mousemove" , function (e) { + if (me.isHidden === false) { + //有pop显示就不隐藏快捷菜单 + if (me.getSubMenuMark () || me.eventType == "contextmenu") return; + + + var flag = true, + el = me.getDom (), + wt = el.offsetWidth, + ht = el.offsetHeight, + distanceX = wt / 2 + me.SPACE,//距离中心X标准 + distanceY = ht / 2,//距离中心Y标准 + x = Math.abs (e.screenX - me.left),//离中心距离横坐标 + y = Math.abs (e.screenY - me.top);//离中心距离纵坐标 + + clearTimeout (timeID); + timeID = setTimeout (function () { + if (y > 0 && y < distanceY) { + me.setOpacity (el , "1"); + } else if (y > distanceY && y < distanceY + 70) { + me.setOpacity (el , "0.5"); + flag = false; + } else if (y > distanceY + 70 && y < distanceY + 140) { + me.hide (); + } + + if (flag && x > 0 && x < distanceX) { + me.setOpacity (el , "1") + } else if (x > distanceX && x < distanceX + 70) { + me.setOpacity (el , "0.5") + } else if (x > distanceX + 70 && x < distanceX + 140) { + me.hide (); + } + }); + } + }); + + //ie\ff下 mouseout不准 + if (browser.chrome) { + domUtils.on (doc , "mouseout" , function (e) { + var relatedTgt = e.relatedTarget || e.toElement; + + if (relatedTgt == null || relatedTgt.tagName == "HTML") { + me.hide (); + } + }); + } + + me.editor.addListener ("afterhidepop" , function () { + if (!me.isHidden) { + isSubMenuShow = true; + } + }); + + } , + initItems : function () { + if (utils.isArray (this.items)) { + for (var i = 0, len = this.items.length ; i < len ; i++) { + var item = this.items[i].toLowerCase (); + + if (UI[item]) { + this.items[i] = new UI[item] (this.editor); + this.items[i].className += " edui-shortcutsubmenu "; + } + } + } + } , + setOpacity : function (el , value) { + if (browser.ie && browser.version < 9) { + el.style.filter = "alpha(opacity = " + parseFloat (value) * 100 + ");" + } else { + el.style.opacity = value; + } + } , + getSubMenuMark : function () { + isSubMenuShow = false; + var layerEle = uiUtils.getFixedLayer (); + var list = domUtils.getElementsByTagName (layerEle , "div" , function (node) { + return domUtils.hasClass (node , "edui-shortcutsubmenu edui-popup") + }); + + for (var i = 0, node ; node = list[i++] ;) { + if (node.style.display != "none") { + isSubMenuShow = true; + } + } + return isSubMenuShow; + } , + show : function (e , hasContextmenu) { + var me = this, + offset = {}, + el = this.getDom (), + fixedlayer = uiUtils.getFixedLayer (); + + function setPos (offset) { + if (offset.left < 0) { + offset.left = 0; + } + if (offset.top < 0) { + offset.top = 0; + } + el.style.cssText = "position:absolute;left:" + offset.left + "px;top:" + offset.top + "px;"; + } + + function setPosByCxtMenu (menu) { + if (!menu.tagName) { + menu = menu.getDom (); + } + offset.left = parseInt (menu.style.left); + offset.top = parseInt (menu.style.top); + offset.top -= el.offsetHeight + 15; + setPos (offset); + } + + + me.eventType = e.type; + el.style.cssText = "display:block;left:-9999px"; + + if (e.type == "contextmenu" && hasContextmenu) { + var menu = domUtils.getElementsByTagName (fixedlayer , "div" , "edui-contextmenu")[0]; + if (menu) { + setPosByCxtMenu (menu) + } else { + me.editor.addListener ("aftershowcontextmenu" , function (type , menu) { + setPosByCxtMenu (menu); + }); + } + } else { + offset = uiUtils.getViewportOffsetByEvent (e); + offset.top -= el.offsetHeight + me.SPACE; + offset.left += me.SPACE + 20; + setPos (offset); + me.setOpacity (el , 0.2); + } + + + me.isHidden = false; + me.left = e.screenX + el.offsetWidth / 2 - me.SPACE; + me.top = e.screenY - (el.offsetHeight / 2) - me.SPACE; + + if (me.editor) { + el.style.zIndex = me.editor.container.style.zIndex * 1 + 10; + fixedlayer.style.zIndex = el.style.zIndex - 1; + } + } , + hide : function () { + if (this.getDom ()) { + this.getDom ().style.display = "none"; + } + this.isHidden = true; + } , + postRender : function () { + if (utils.isArray (this.items)) { + for (var i = 0, item ; item = this.items[i++] ;) { + item.postRender (); + } + } + } , + getHtmlTpl : function () { + var buff; + if (utils.isArray (this.items)) { + buff = []; + for (var i = 0 ; i < this.items.length ; i++) { + buff[i] = this.items[i].renderHtml (); + } + buff = buff.join (""); + } else { + buff = this.items; + } + + return '
      ' + + buff + + '
      '; + } + }; + + utils.inherits (ShortCutMenu , UIBase); + + function hideAllMenu (e) { + var tgt = e.target || e.srcElement, + cur = domUtils.findParent (tgt , function (node) { + return domUtils.hasClass (node , "edui-shortcutmenu") || domUtils.hasClass (node , "edui-popup"); + } , true); + + if (!cur) { + for (var i = 0, menu ; menu = allMenus[i++] ;) { + menu.hide () + } + } + } + + domUtils.on (document , 'mousedown' , function (e) { + hideAllMenu (e); + }); + + domUtils.on (window , 'scroll' , function (e) { + hideAllMenu (e); + }); + +}) (); + + +// ui/breakline.js +(function (){ + var utils = baidu.editor.utils, + UIBase = baidu.editor.ui.UIBase, + Breakline = baidu.editor.ui.Breakline = function (options){ + this.initOptions(options); + this.initSeparator(); + }; + Breakline.prototype = { + uiName: 'Breakline', + initSeparator: function (){ + this.initUIBase(); + }, + getHtmlTpl: function (){ + return '
      '; + } + }; + utils.inherits(Breakline, UIBase); + +})(); + + +// ui/message.js +///import core +///import uicore +(function () { + var utils = baidu.editor.utils, + domUtils = baidu.editor.dom.domUtils, + UIBase = baidu.editor.ui.UIBase, + Message = baidu.editor.ui.Message = function (options){ + this.initOptions(options); + this.initMessage(); + }; + + Message.prototype = { + initMessage: function (){ + this.initUIBase(); + }, + getHtmlTpl: function (){ + return '
      ' + + '
      ×
      ' + + '
      ' + + ' ' + + '
      ' + + '
      ' + + '
      ' + + '
      ' + + '
      '; + }, + reset: function(opt){ + var me = this; + if (!opt.keepshow) { + clearTimeout(this.timer); + me.timer = setTimeout(function(){ + me.hide(); + }, opt.timeout || 4000); + } + + opt.content !== undefined && me.setContent(opt.content); + opt.type !== undefined && me.setType(opt.type); + + me.show(); + }, + postRender: function(){ + var me = this, + closer = this.getDom('closer'); + closer && domUtils.on(closer, 'click', function(){ + me.hide(); + }); + }, + setContent: function(content){ + this.getDom('content').innerHTML = content; + }, + setType: function(type){ + type = type || 'info'; + var body = this.getDom('body'); + body.className = body.className.replace(/edui-message-type-[\w-]+/, 'edui-message-type-' + type); + }, + getContent: function(){ + return this.getDom('content').innerHTML; + }, + getType: function(){ + var arr = this.getDom('body').match(/edui-message-type-([\w-]+)/); + return arr ? arr[1]:''; + }, + show: function (){ + this.getDom().style.display = 'block'; + }, + hide: function (){ + var dom = this.getDom(); + if (dom) { + dom.style.display = 'none'; + dom.parentNode && dom.parentNode.removeChild(dom); + } + } + }; + + utils.inherits(Message, UIBase); + +})(); + + +// adapter/editorui.js +//ui跟编辑器的适配層 +//那个按钮弹出是dialog,是下拉筐等都是在这个js中配置 +//自己写的ui也要在这里配置,放到baidu.editor.ui下边,当编辑器实例化的时候会根据ueditor.config中的toolbars找到相应的进行实例化 +(function () { + var utils = baidu.editor.utils; + var editorui = baidu.editor.ui; + var _Dialog = editorui.Dialog; + editorui.buttons = {}; + + editorui.Dialog = function (options) { + var dialog = new _Dialog(options); + dialog.addListener('hide', function () { + + if (dialog.editor) { + var editor = dialog.editor; + try { + if (browser.gecko) { + var y = editor.window.scrollY, + x = editor.window.scrollX; + editor.body.focus(); + editor.window.scrollTo(x, y); + } else { + editor.focus(); + } + + + } catch (ex) { + } + } + }); + return dialog; + }; + + var iframeUrlMap = { + 'anchor':'~/dialogs/anchor/anchor.html', + 'insertimage':'~/dialogs/image/image.html', + 'link':'~/dialogs/link/link.html', + 'spechars':'~/dialogs/spechars/spechars.html', + 'searchreplace':'~/dialogs/searchreplace/searchreplace.html', + 'map':'~/dialogs/map/map.html', + 'gmap':'~/dialogs/gmap/gmap.html', + 'insertvideo':'~/dialogs/video/video.html', + 'help':'~/dialogs/help/help.html', + 'preview':'~/dialogs/preview/preview.html', + 'emotion':'~/dialogs/emotion/emotion.html', + 'wordimage':'~/dialogs/wordimage/wordimage.html', + 'attachment':'~/dialogs/attachment/attachment.html', + 'insertframe':'~/dialogs/insertframe/insertframe.html', + 'edittip':'~/dialogs/table/edittip.html', + 'edittable':'~/dialogs/table/edittable.html', + 'edittd':'~/dialogs/table/edittd.html', + 'webapp':'~/dialogs/webapp/webapp.html', + 'snapscreen':'~/dialogs/snapscreen/snapscreen.html', + 'scrawl':'~/dialogs/scrawl/scrawl.html', + 'music':'~/dialogs/music/music.html', + 'template':'~/dialogs/template/template.html', + 'background':'~/dialogs/background/background.html', + 'charts': '~/dialogs/charts/charts.html' + }; + //为工具栏添加按钮,以下都是统一的按钮触发命令,所以写在一起 + var btnCmds = ['undo', 'redo', 'formatmatch', + 'bold', 'italic', 'underline', 'fontborder', 'touppercase', 'tolowercase', + 'strikethrough', 'subscript', 'superscript', 'source', 'indent', 'outdent', + 'blockquote', 'pasteplain', 'pagebreak', + 'selectall', 'print','horizontal', 'removeformat', 'time', 'date', 'unlink', + 'insertparagraphbeforetable', 'insertrow', 'insertcol', 'mergeright', 'mergedown', 'deleterow', + 'deletecol', 'splittorows', 'splittocols', 'splittocells', 'mergecells', 'deletetable', 'drafts']; + + for (var i = 0, ci; ci = btnCmds[i++];) { + ci = ci.toLowerCase(); + editorui[ci] = function (cmd) { + return function (editor) { + var ui = new editorui.Button({ + className:'edui-for-' + cmd, + title:editor.options.labelMap[cmd] || editor.getLang("labelMap." + cmd) || '', + onclick:function () { + editor.execCommand(cmd); + }, + theme:editor.options.theme, + showText:false + }); + editorui.buttons[cmd] = ui; + editor.addListener('selectionchange', function (type, causeByUi, uiReady) { + var state = editor.queryCommandState(cmd); + if (state == -1) { + ui.setDisabled(true); + ui.setChecked(false); + } else { + if (!uiReady) { + ui.setDisabled(false); + ui.setChecked(state); + } + } + }); + return ui; + }; + }(ci); + } + + //清除文档 + editorui.cleardoc = function (editor) { + var ui = new editorui.Button({ + className:'edui-for-cleardoc', + title:editor.options.labelMap.cleardoc || editor.getLang("labelMap.cleardoc") || '', + theme:editor.options.theme, + onclick:function () { + if (confirm(editor.getLang("confirmClear"))) { + editor.execCommand('cleardoc'); + } + } + }); + editorui.buttons["cleardoc"] = ui; + editor.addListener('selectionchange', function () { + ui.setDisabled(editor.queryCommandState('cleardoc') == -1); + }); + return ui; + }; + + //排版,图片排版,文字方向 + var typeset = { + 'justify':['left', 'right', 'center', 'justify'], + 'imagefloat':['none', 'left', 'center', 'right'], + 'directionality':['ltr', 'rtl'] + }; + + for (var p in typeset) { + + (function (cmd, val) { + for (var i = 0, ci; ci = val[i++];) { + (function (cmd2) { + editorui[cmd.replace('float', '') + cmd2] = function (editor) { + var ui = new editorui.Button({ + className:'edui-for-' + cmd.replace('float', '') + cmd2, + title:editor.options.labelMap[cmd.replace('float', '') + cmd2] || editor.getLang("labelMap." + cmd.replace('float', '') + cmd2) || '', + theme:editor.options.theme, + onclick:function () { + editor.execCommand(cmd, cmd2); + } + }); + editorui.buttons[cmd] = ui; + editor.addListener('selectionchange', function (type, causeByUi, uiReady) { + ui.setDisabled(editor.queryCommandState(cmd) == -1); + ui.setChecked(editor.queryCommandValue(cmd) == cmd2 && !uiReady); + }); + return ui; + }; + })(ci) + } + })(p, typeset[p]) + } + + //字体颜色和背景颜色 + for (var i = 0, ci; ci = ['backcolor', 'forecolor'][i++];) { + editorui[ci] = function (cmd) { + return function (editor) { + var ui = new editorui.ColorButton({ + className:'edui-for-' + cmd, + color:'default', + title:editor.options.labelMap[cmd] || editor.getLang("labelMap." + cmd) || '', + editor:editor, + onpickcolor:function (t, color) { + editor.execCommand(cmd, color); + }, + onpicknocolor:function () { + editor.execCommand(cmd, 'default'); + this.setColor('transparent'); + this.color = 'default'; + }, + onbuttonclick:function () { + editor.execCommand(cmd, this.color); + } + }); + editorui.buttons[cmd] = ui; + editor.addListener('selectionchange', function () { + ui.setDisabled(editor.queryCommandState(cmd) == -1); + }); + return ui; + }; + }(ci); + } + + + var dialogBtns = { + noOk:['searchreplace', 'help', 'spechars', 'webapp','preview'], + ok:['attachment', 'anchor', 'link', 'insertimage', 'map', 'gmap', 'insertframe', 'wordimage', + 'insertvideo', 'insertframe', 'edittip', 'edittable', 'edittd', 'scrawl', 'template', 'music', 'background', 'charts'] + }; + + for (var p in dialogBtns) { + (function (type, vals) { + for (var i = 0, ci; ci = vals[i++];) { + //todo opera下存在问题 + if (browser.opera && ci === "searchreplace") { + continue; + } + (function (cmd) { + editorui[cmd] = function (editor, iframeUrl, title) { + iframeUrl = iframeUrl || (editor.options.iframeUrlMap || {})[cmd] || iframeUrlMap[cmd]; + title = editor.options.labelMap[cmd] || editor.getLang("labelMap." + cmd) || ''; + + var dialog; + //没有iframeUrl不创建dialog + if (iframeUrl) { + dialog = new editorui.Dialog(utils.extend({ + iframeUrl:editor.ui.mapUrl(iframeUrl), + editor:editor, + className:'edui-for-' + cmd, + title:title, + holdScroll: cmd === 'insertimage', + fullscreen: /charts|preview/.test(cmd), + closeDialog:editor.getLang("closeDialog") + }, type == 'ok' ? { + buttons:[ + { + className:'edui-okbutton', + label:editor.getLang("ok"), + editor:editor, + onclick:function () { + dialog.close(true); + } + }, + { + className:'edui-cancelbutton', + label:editor.getLang("cancel"), + editor:editor, + onclick:function () { + dialog.close(false); + } + } + ] + } : {})); + + editor.ui._dialogs[cmd + "Dialog"] = dialog; + } + + var ui = new editorui.Button({ + className:'edui-for-' + cmd, + title:title, + onclick:function () { + if (dialog) { + switch (cmd) { + case "wordimage": + var images = editor.execCommand("wordimage"); + if (images && images.length) { + dialog.render(); + dialog.open(); + } + break; + case "scrawl": + if (editor.queryCommandState("scrawl") != -1) { + dialog.render(); + dialog.open(); + } + + break; + default: + dialog.render(); + dialog.open(); + } + } + }, + theme:editor.options.theme, + disabled:(cmd == 'scrawl' && editor.queryCommandState("scrawl") == -1) || ( cmd == 'charts' ) + }); + editorui.buttons[cmd] = ui; + editor.addListener('selectionchange', function () { + //只存在于右键菜单而无工具栏按钮的ui不需要检测状态 + var unNeedCheckState = {'edittable':1}; + if (cmd in unNeedCheckState)return; + + var state = editor.queryCommandState(cmd); + if (ui.getDom()) { + ui.setDisabled(state == -1); + ui.setChecked(state); + } + + }); + + return ui; + }; + })(ci.toLowerCase()) + } + })(p, dialogBtns[p]); + } + + editorui.snapscreen = function (editor, iframeUrl, title) { + title = editor.options.labelMap['snapscreen'] || editor.getLang("labelMap.snapscreen") || ''; + var ui = new editorui.Button({ + className:'edui-for-snapscreen', + title:title, + onclick:function () { + editor.execCommand("snapscreen"); + }, + theme:editor.options.theme + + }); + editorui.buttons['snapscreen'] = ui; + iframeUrl = iframeUrl || (editor.options.iframeUrlMap || {})["snapscreen"] || iframeUrlMap["snapscreen"]; + if (iframeUrl) { + var dialog = new editorui.Dialog({ + iframeUrl:editor.ui.mapUrl(iframeUrl), + editor:editor, + className:'edui-for-snapscreen', + title:title, + buttons:[ + { + className:'edui-okbutton', + label:editor.getLang("ok"), + editor:editor, + onclick:function () { + dialog.close(true); + } + }, + { + className:'edui-cancelbutton', + label:editor.getLang("cancel"), + editor:editor, + onclick:function () { + dialog.close(false); + } + } + ] + + }); + dialog.render(); + editor.ui._dialogs["snapscreenDialog"] = dialog; + } + editor.addListener('selectionchange', function () { + ui.setDisabled(editor.queryCommandState('snapscreen') == -1); + }); + return ui; + }; + + editorui.insertcode = function (editor, list, title) { + list = editor.options['insertcode'] || []; + title = editor.options.labelMap['insertcode'] || editor.getLang("labelMap.insertcode") || ''; + // if (!list.length) return; + var items = []; + utils.each(list,function(key,val){ + items.push({ + label:key, + value:val, + theme:editor.options.theme, + renderLabelHtml:function () { + return '
      ' + (this.label || '') + '
      '; + } + }); + }); + + var ui = new editorui.Combox({ + editor:editor, + items:items, + onselect:function (t, index) { + editor.execCommand('insertcode', this.items[index].value); + }, + onbuttonclick:function () { + this.showPopup(); + }, + title:title, + initValue:title, + className:'edui-for-insertcode', + indexByValue:function (value) { + if (value) { + for (var i = 0, ci; ci = this.items[i]; i++) { + if (ci.value.indexOf(value) != -1) + return i; + } + } + + return -1; + } + }); + editorui.buttons['insertcode'] = ui; + editor.addListener('selectionchange', function (type, causeByUi, uiReady) { + if (!uiReady) { + var state = editor.queryCommandState('insertcode'); + if (state == -1) { + ui.setDisabled(true); + } else { + ui.setDisabled(false); + var value = editor.queryCommandValue('insertcode'); + if(!value){ + ui.setValue(title); + return; + } + //trace:1871 ie下从源码模式切换回来时,字体会带单引号,而且会有逗号 + value && (value = value.replace(/['"]/g, '').split(',')[0]); + ui.setValue(value); + + } + } + + }); + return ui; + }; + editorui.fontfamily = function (editor, list, title) { + + list = editor.options['fontfamily'] || []; + title = editor.options.labelMap['fontfamily'] || editor.getLang("labelMap.fontfamily") || ''; + if (!list.length) return; + for (var i = 0, ci, items = []; ci = list[i]; i++) { + var langLabel = editor.getLang('fontfamily')[ci.name] || ""; + (function (key, val) { + items.push({ + label:key, + value:val, + theme:editor.options.theme, + renderLabelHtml:function () { + return '
      ' + (this.label || '') + '
      '; + } + }); + })(ci.label || langLabel, ci.val) + } + var ui = new editorui.Combox({ + editor:editor, + items:items, + onselect:function (t, index) { + editor.execCommand('FontFamily', this.items[index].value); + }, + onbuttonclick:function () { + this.showPopup(); + }, + title:title, + initValue:title, + className:'edui-for-fontfamily', + indexByValue:function (value) { + if (value) { + for (var i = 0, ci; ci = this.items[i]; i++) { + if (ci.value.indexOf(value) != -1) + return i; + } + } + + return -1; + } + }); + editorui.buttons['fontfamily'] = ui; + editor.addListener('selectionchange', function (type, causeByUi, uiReady) { + if (!uiReady) { + var state = editor.queryCommandState('FontFamily'); + if (state == -1) { + ui.setDisabled(true); + } else { + ui.setDisabled(false); + var value = editor.queryCommandValue('FontFamily'); + //trace:1871 ie下从源码模式切换回来时,字体会带单引号,而且会有逗号 + value && (value = value.replace(/['"]/g, '').split(',')[0]); + ui.setValue(value); + + } + } + + }); + return ui; + }; + + editorui.fontsize = function (editor, list, title) { + title = editor.options.labelMap['fontsize'] || editor.getLang("labelMap.fontsize") || ''; + list = list || editor.options['fontsize'] || []; + if (!list.length) return; + var items = []; + for (var i = 0; i < list.length; i++) { + var size = list[i] + 'px'; + items.push({ + label:size, + value:size, + theme:editor.options.theme, + renderLabelHtml:function () { + return '
      ' + (this.label || '') + '
      '; + } + }); + } + var ui = new editorui.Combox({ + editor:editor, + items:items, + title:title, + initValue:title, + onselect:function (t, index) { + editor.execCommand('FontSize', this.items[index].value); + }, + onbuttonclick:function () { + this.showPopup(); + }, + className:'edui-for-fontsize' + }); + editorui.buttons['fontsize'] = ui; + editor.addListener('selectionchange', function (type, causeByUi, uiReady) { + if (!uiReady) { + var state = editor.queryCommandState('FontSize'); + if (state == -1) { + ui.setDisabled(true); + } else { + ui.setDisabled(false); + ui.setValue(editor.queryCommandValue('FontSize')); + } + } + + }); + return ui; + }; + + editorui.paragraph = function (editor, list, title) { + title = editor.options.labelMap['paragraph'] || editor.getLang("labelMap.paragraph") || ''; + list = editor.options['paragraph'] || []; + if (utils.isEmptyObject(list)) return; + var items = []; + for (var i in list) { + items.push({ + value:i, + label:list[i] || editor.getLang("paragraph")[i], + theme:editor.options.theme, + renderLabelHtml:function () { + return '
      ' + (this.label || '') + '
      '; + } + }) + } + var ui = new editorui.Combox({ + editor:editor, + items:items, + title:title, + initValue:title, + className:'edui-for-paragraph', + onselect:function (t, index) { + editor.execCommand('Paragraph', this.items[index].value); + }, + onbuttonclick:function () { + this.showPopup(); + } + }); + editorui.buttons['paragraph'] = ui; + editor.addListener('selectionchange', function (type, causeByUi, uiReady) { + if (!uiReady) { + var state = editor.queryCommandState('Paragraph'); + if (state == -1) { + ui.setDisabled(true); + } else { + ui.setDisabled(false); + var value = editor.queryCommandValue('Paragraph'); + var index = ui.indexByValue(value); + if (index != -1) { + ui.setValue(value); + } else { + ui.setValue(ui.initValue); + } + } + } + + }); + return ui; + }; + + + //自定义标题 + editorui.customstyle = function (editor) { + var list = editor.options['customstyle'] || [], + title = editor.options.labelMap['customstyle'] || editor.getLang("labelMap.customstyle") || ''; + if (!list.length)return; + var langCs = editor.getLang('customstyle'); + for (var i = 0, items = [], t; t = list[i++];) { + (function (t) { + var ck = {}; + ck.label = t.label ? t.label : langCs[t.name]; + ck.style = t.style; + ck.className = t.className; + ck.tag = t.tag; + items.push({ + label:ck.label, + value:ck, + theme:editor.options.theme, + renderLabelHtml:function () { + return '
      ' + '<' + ck.tag + ' ' + (ck.className ? ' class="' + ck.className + '"' : "") + + (ck.style ? ' style="' + ck.style + '"' : "") + '>' + ck.label + "<\/" + ck.tag + ">" + + '
      '; + } + }); + })(t); + } + + var ui = new editorui.Combox({ + editor:editor, + items:items, + title:title, + initValue:title, + className:'edui-for-customstyle', + onselect:function (t, index) { + editor.execCommand('customstyle', this.items[index].value); + }, + onbuttonclick:function () { + this.showPopup(); + }, + indexByValue:function (value) { + for (var i = 0, ti; ti = this.items[i++];) { + if (ti.label == value) { + return i - 1 + } + } + return -1; + } + }); + editorui.buttons['customstyle'] = ui; + editor.addListener('selectionchange', function (type, causeByUi, uiReady) { + if (!uiReady) { + var state = editor.queryCommandState('customstyle'); + if (state == -1) { + ui.setDisabled(true); + } else { + ui.setDisabled(false); + var value = editor.queryCommandValue('customstyle'); + var index = ui.indexByValue(value); + if (index != -1) { + ui.setValue(value); + } else { + ui.setValue(ui.initValue); + } + } + } + + }); + return ui; + }; + editorui.inserttable = function (editor, iframeUrl, title) { + title = editor.options.labelMap['inserttable'] || editor.getLang("labelMap.inserttable") || ''; + var ui = new editorui.TableButton({ + editor:editor, + title:title, + className:'edui-for-inserttable', + onpicktable:function (t, numCols, numRows) { + editor.execCommand('InsertTable', {numRows:numRows, numCols:numCols, border:1}); + }, + onbuttonclick:function () { + this.showPopup(); + } + }); + editorui.buttons['inserttable'] = ui; + editor.addListener('selectionchange', function () { + ui.setDisabled(editor.queryCommandState('inserttable') == -1); + }); + return ui; + }; + + editorui.lineheight = function (editor) { + var val = editor.options.lineheight || []; + if (!val.length)return; + for (var i = 0, ci, items = []; ci = val[i++];) { + items.push({ + //todo:写死了 + label:ci, + value:ci, + theme:editor.options.theme, + onclick:function () { + editor.execCommand("lineheight", this.value); + } + }) + } + var ui = new editorui.MenuButton({ + editor:editor, + className:'edui-for-lineheight', + title:editor.options.labelMap['lineheight'] || editor.getLang("labelMap.lineheight") || '', + items:items, + onbuttonclick:function () { + var value = editor.queryCommandValue('LineHeight') || this.value; + editor.execCommand("LineHeight", value); + } + }); + editorui.buttons['lineheight'] = ui; + editor.addListener('selectionchange', function () { + var state = editor.queryCommandState('LineHeight'); + if (state == -1) { + ui.setDisabled(true); + } else { + ui.setDisabled(false); + var value = editor.queryCommandValue('LineHeight'); + value && ui.setValue((value + '').replace(/cm/, '')); + ui.setChecked(state) + } + }); + return ui; + }; + + var rowspacings = ['top', 'bottom']; + for (var r = 0, ri; ri = rowspacings[r++];) { + (function (cmd) { + editorui['rowspacing' + cmd] = function (editor) { + var val = editor.options['rowspacing' + cmd] || []; + if (!val.length) return null; + for (var i = 0, ci, items = []; ci = val[i++];) { + items.push({ + label:ci, + value:ci, + theme:editor.options.theme, + onclick:function () { + editor.execCommand("rowspacing", this.value, cmd); + } + }) + } + var ui = new editorui.MenuButton({ + editor:editor, + className:'edui-for-rowspacing' + cmd, + title:editor.options.labelMap['rowspacing' + cmd] || editor.getLang("labelMap.rowspacing" + cmd) || '', + items:items, + onbuttonclick:function () { + var value = editor.queryCommandValue('rowspacing', cmd) || this.value; + editor.execCommand("rowspacing", value, cmd); + } + }); + editorui.buttons[cmd] = ui; + editor.addListener('selectionchange', function () { + var state = editor.queryCommandState('rowspacing', cmd); + if (state == -1) { + ui.setDisabled(true); + } else { + ui.setDisabled(false); + var value = editor.queryCommandValue('rowspacing', cmd); + value && ui.setValue((value + '').replace(/%/, '')); + ui.setChecked(state) + } + }); + return ui; + } + })(ri) + } + //有序,无序列表 + var lists = ['insertorderedlist', 'insertunorderedlist']; + for (var l = 0, cl; cl = lists[l++];) { + (function (cmd) { + editorui[cmd] = function (editor) { + var vals = editor.options[cmd], + _onMenuClick = function () { + editor.execCommand(cmd, this.value); + }, items = []; + for (var i in vals) { + items.push({ + label:vals[i] || editor.getLang()[cmd][i] || "", + value:i, + theme:editor.options.theme, + onclick:_onMenuClick + }) + } + var ui = new editorui.MenuButton({ + editor:editor, + className:'edui-for-' + cmd, + title:editor.getLang("labelMap." + cmd) || '', + 'items':items, + onbuttonclick:function () { + var value = editor.queryCommandValue(cmd) || this.value; + editor.execCommand(cmd, value); + } + }); + editorui.buttons[cmd] = ui; + editor.addListener('selectionchange', function () { + var state = editor.queryCommandState(cmd); + if (state == -1) { + ui.setDisabled(true); + } else { + ui.setDisabled(false); + var value = editor.queryCommandValue(cmd); + ui.setValue(value); + ui.setChecked(state) + } + }); + return ui; + }; + })(cl) + } + + editorui.fullscreen = function (editor, title) { + title = editor.options.labelMap['fullscreen'] || editor.getLang("labelMap.fullscreen") || ''; + var ui = new editorui.Button({ + className:'edui-for-fullscreen', + title:title, + theme:editor.options.theme, + onclick:function () { + if (editor.ui) { + editor.ui.setFullScreen(!editor.ui.isFullScreen()); + } + this.setChecked(editor.ui.isFullScreen()); + } + }); + editorui.buttons['fullscreen'] = ui; + editor.addListener('selectionchange', function () { + var state = editor.queryCommandState('fullscreen'); + ui.setDisabled(state == -1); + ui.setChecked(editor.ui.isFullScreen()); + }); + return ui; + }; + + // 表情 + editorui["emotion"] = function (editor, iframeUrl) { + var cmd = "emotion"; + var ui = new editorui.MultiMenuPop({ + title:editor.options.labelMap[cmd] || editor.getLang("labelMap." + cmd + "") || '', + editor:editor, + className:'edui-for-' + cmd, + iframeUrl:editor.ui.mapUrl(iframeUrl || (editor.options.iframeUrlMap || {})[cmd] || iframeUrlMap[cmd]) + }); + editorui.buttons[cmd] = ui; + + editor.addListener('selectionchange', function () { + ui.setDisabled(editor.queryCommandState(cmd) == -1) + }); + return ui; + }; + + editorui.autotypeset = function (editor) { + var ui = new editorui.AutoTypeSetButton({ + editor:editor, + title:editor.options.labelMap['autotypeset'] || editor.getLang("labelMap.autotypeset") || '', + className:'edui-for-autotypeset', + onbuttonclick:function () { + editor.execCommand('autotypeset') + } + }); + editorui.buttons['autotypeset'] = ui; + editor.addListener('selectionchange', function () { + ui.setDisabled(editor.queryCommandState('autotypeset') == -1); + }); + return ui; + }; + + /* 简单上传插件 */ + editorui["simpleupload"] = function (editor) { + var name = 'simpleupload', + ui = new editorui.Button({ + className:'edui-for-' + name, + title:editor.options.labelMap[name] || editor.getLang("labelMap." + name) || '', + onclick:function () {}, + theme:editor.options.theme, + showText:false + }); + editorui.buttons[name] = ui; + editor.addListener('ready', function() { + var b = ui.getDom('body'), + iconSpan = b.children[0]; + editor.fireEvent('simpleuploadbtnready', iconSpan); + }); + editor.addListener('selectionchange', function (type, causeByUi, uiReady) { + var state = editor.queryCommandState(name); + if (state == -1) { + ui.setDisabled(true); + ui.setChecked(false); + } else { + if (!uiReady) { + ui.setDisabled(false); + ui.setChecked(state); + } + } + }); + return ui; + }; + +})(); + + +// adapter/editor.js +///import core +///commands 全屏 +///commandsName FullScreen +///commandsTitle 全屏 +(function () { + var utils = baidu.editor.utils, + uiUtils = baidu.editor.ui.uiUtils, + UIBase = baidu.editor.ui.UIBase, + domUtils = baidu.editor.dom.domUtils; + var nodeStack = []; + + function EditorUI(options) { + this.initOptions(options); + this.initEditorUI(); + } + + EditorUI.prototype = { + uiName:'editor', + initEditorUI:function () { + this.editor.ui = this; + this._dialogs = {}; + this.initUIBase(); + this._initToolbars(); + var editor = this.editor, + me = this; + + editor.addListener('ready', function () { + //提供getDialog方法 + editor.getDialog = function (name) { + return editor.ui._dialogs[name + "Dialog"]; + }; + domUtils.on(editor.window, 'scroll', function (evt) { + baidu.editor.ui.Popup.postHide(evt); + }); + //提供编辑器实时宽高(全屏时宽高不变化) + editor.ui._actualFrameWidth = editor.options.initialFrameWidth; + + UE.browser.ie && UE.browser.version === 6 && editor.container.ownerDocument.execCommand("BackgroundImageCache", false, true); + + //display bottom-bar label based on config + if (editor.options.elementPathEnabled) { + editor.ui.getDom('elementpath').innerHTML = '
      ' + editor.getLang("elementPathTip") + ':
      '; + } + if (editor.options.wordCount) { + function countFn() { + setCount(editor,me); + domUtils.un(editor.document, "click", arguments.callee); + } + domUtils.on(editor.document, "click", countFn); + editor.ui.getDom('wordcount').innerHTML = editor.getLang("wordCountTip"); + } + editor.ui._scale(); + if (editor.options.scaleEnabled) { + if (editor.autoHeightEnabled) { + editor.disableAutoHeight(); + } + me.enableScale(); + } else { + me.disableScale(); + } + if (!editor.options.elementPathEnabled && !editor.options.wordCount && !editor.options.scaleEnabled) { + editor.ui.getDom('elementpath').style.display = "none"; + editor.ui.getDom('wordcount').style.display = "none"; + editor.ui.getDom('scale').style.display = "none"; + } + + if (!editor.selection.isFocus())return; + editor.fireEvent('selectionchange', false, true); + + + }); + + editor.addListener('mousedown', function (t, evt) { + var el = evt.target || evt.srcElement; + baidu.editor.ui.Popup.postHide(evt, el); + baidu.editor.ui.ShortCutMenu.postHide(evt); + + }); + editor.addListener("delcells", function () { + if (UE.ui['edittip']) { + new UE.ui['edittip'](editor); + } + editor.getDialog('edittip').open(); + }); + + var pastePop, isPaste = false, timer; + editor.addListener("afterpaste", function () { + if(editor.queryCommandState('pasteplain')) + return; + if(baidu.editor.ui.PastePicker){ + pastePop = new baidu.editor.ui.Popup({ + content:new baidu.editor.ui.PastePicker({editor:editor}), + editor:editor, + className:'edui-wordpastepop' + }); + pastePop.render(); + } + isPaste = true; + }); + + editor.addListener("afterinserthtml", function () { + clearTimeout(timer); + timer = setTimeout(function () { + if (pastePop && (isPaste || editor.ui._isTransfer)) { + if(pastePop.isHidden()){ + var span = domUtils.createElement(editor.document, 'span', { + 'style':"line-height:0px;", + 'innerHTML':'\ufeff' + }), + range = editor.selection.getRange(); + range.insertNode(span); + var tmp= getDomNode(span, 'firstChild', 'previousSibling'); + tmp && pastePop.showAnchor(tmp.nodeType == 3 ? tmp.parentNode : tmp); + domUtils.remove(span); + }else{ + pastePop.show(); + } + delete editor.ui._isTransfer; + isPaste = false; + } + }, 200) + }); + editor.addListener('contextmenu', function (t, evt) { + baidu.editor.ui.Popup.postHide(evt); + }); + editor.addListener('keydown', function (t, evt) { + if (pastePop) pastePop.dispose(evt); + var keyCode = evt.keyCode || evt.which; + if(evt.altKey&&keyCode==90){ + UE.ui.buttons['fullscreen'].onclick(); + } + }); + editor.addListener('wordcount', function (type) { + setCount(this,me); + }); + function setCount(editor,ui) { + editor.setOpt({ + wordCount:true, + maximumWords:10000, + wordCountMsg:editor.options.wordCountMsg || editor.getLang("wordCountMsg"), + wordOverFlowMsg:editor.options.wordOverFlowMsg || editor.getLang("wordOverFlowMsg") + }); + var opt = editor.options, + max = opt.maximumWords, + msg = opt.wordCountMsg , + errMsg = opt.wordOverFlowMsg, + countDom = ui.getDom('wordcount'); + if (!opt.wordCount) { + return; + } + var count = editor.getContentLength(true); + if (count > max) { + countDom.innerHTML = errMsg; + editor.fireEvent("wordcountoverflow"); + } else { + countDom.innerHTML = msg.replace("{#leave}", max - count).replace("{#count}", count); + } + } + + editor.addListener('selectionchange', function () { + if (editor.options.elementPathEnabled) { + me[(editor.queryCommandState('elementpath') == -1 ? 'dis' : 'en') + 'ableElementPath']() + } + if (editor.options.scaleEnabled) { + me[(editor.queryCommandState('scale') == -1 ? 'dis' : 'en') + 'ableScale'](); + + } + }); + var popup = new baidu.editor.ui.Popup({ + editor:editor, + content:'', + className:'edui-bubble', + _onEditButtonClick:function () { + this.hide(); + editor.ui._dialogs.linkDialog.open(); + }, + _onImgEditButtonClick:function (name) { + this.hide(); + editor.ui._dialogs[name] && editor.ui._dialogs[name].open(); + + }, + _onImgSetFloat:function (value) { + this.hide(); + editor.execCommand("imagefloat", value); + + }, + _setIframeAlign:function (value) { + var frame = popup.anchorEl; + var newFrame = frame.cloneNode(true); + switch (value) { + case -2: + newFrame.setAttribute("align", ""); + break; + case -1: + newFrame.setAttribute("align", "left"); + break; + case 1: + newFrame.setAttribute("align", "right"); + break; + } + frame.parentNode.insertBefore(newFrame, frame); + domUtils.remove(frame); + popup.anchorEl = newFrame; + popup.showAnchor(popup.anchorEl); + }, + _updateIframe:function () { + var frame = editor._iframe = popup.anchorEl; + if(domUtils.hasClass(frame, 'ueditor_baidumap')) { + editor.selection.getRange().selectNode(frame).select(); + editor.ui._dialogs.mapDialog.open(); + popup.hide(); + } else { + editor.ui._dialogs.insertframeDialog.open(); + popup.hide(); + } + }, + _onRemoveButtonClick:function (cmdName) { + editor.execCommand(cmdName); + this.hide(); + }, + queryAutoHide:function (el) { + if (el && el.ownerDocument == editor.document) { + if (el.tagName.toLowerCase() == 'img' || domUtils.findParentByTagName(el, 'a', true)) { + return el !== popup.anchorEl; + } + } + return baidu.editor.ui.Popup.prototype.queryAutoHide.call(this, el); + } + }); + popup.render(); + if (editor.options.imagePopup) { + editor.addListener('mouseover', function (t, evt) { + evt = evt || window.event; + var el = evt.target || evt.srcElement; + if (editor.ui._dialogs.insertframeDialog && /iframe/ig.test(el.tagName)) { + var html = popup.formatHtml( + '' + editor.getLang("property") + ': ' + editor.getLang("default") + '  ' + editor.getLang("justifyleft") + '  ' + editor.getLang("justifyright") + '  ' + + ' ' + editor.getLang("modify") + ''); + if (html) { + popup.getDom('content').innerHTML = html; + popup.anchorEl = el; + popup.showAnchor(popup.anchorEl); + } else { + popup.hide(); + } + } + }); + editor.addListener('selectionchange', function (t, causeByUi) { + if (!causeByUi) return; + var html = '', str = "", + img = editor.selection.getRange().getClosedNode(), + dialogs = editor.ui._dialogs; + if (img && img.tagName == 'IMG') { + var dialogName = 'insertimageDialog'; + if (img.className.indexOf("edui-faked-video") != -1 || img.className.indexOf("edui-upload-video") != -1) { + dialogName = "insertvideoDialog" + } + if (img.className.indexOf("edui-faked-webapp") != -1) { + dialogName = "webappDialog" + } + if (img.src.indexOf("http://api.map.baidu.com") != -1) { + dialogName = "mapDialog" + } + if (img.className.indexOf("edui-faked-music") != -1) { + dialogName = "musicDialog" + } + if (img.src.indexOf("http://maps.google.com/maps/api/staticmap") != -1) { + dialogName = "gmapDialog" + } + if (img.getAttribute("anchorname")) { + dialogName = "anchorDialog"; + html = popup.formatHtml( + '' + editor.getLang("property") + ': ' + editor.getLang("modify") + '  ' + + '' + editor.getLang("delete") + ''); + } + if (img.getAttribute("word_img")) { + //todo 放到dialog去做查询 + editor.word_img = [img.getAttribute("word_img")]; + dialogName = "wordimageDialog" + } + if(domUtils.hasClass(img, 'loadingclass') || domUtils.hasClass(img, 'loaderrorclass')) { + dialogName = ""; + } + if (!dialogs[dialogName]) { + return; + } + str = '' + editor.getLang("property") + ': '+ + '' + editor.getLang("default") + '  ' + + '' + editor.getLang("justifyleft") + '  ' + + '' + editor.getLang("justifyright") + '  ' + + '' + editor.getLang("justifycenter") + '  '+ + '' + editor.getLang("modify") + ''; + + !html && (html = popup.formatHtml(str)) + + } + if (editor.ui._dialogs.linkDialog) { + var link = editor.queryCommandValue('link'); + var url; + if (link && (url = (link.getAttribute('_href') || link.getAttribute('href', 2)))) { + var txt = url; + if (url.length > 30) { + txt = url.substring(0, 20) + "..."; + } + if (html) { + html += '
      ' + } + html += popup.formatHtml( + '' + editor.getLang("anthorMsg") + ': ' + txt + '' + + ' ' + editor.getLang("modify") + '' + + ' ' + editor.getLang("clear") + ''); + popup.showAnchor(link); + } + } + + if (html) { + popup.getDom('content').innerHTML = html; + popup.anchorEl = img || link; + popup.showAnchor(popup.anchorEl); + } else { + popup.hide(); + } + }); + } + + }, + _initToolbars:function () { + var editor = this.editor; + var toolbars = this.toolbars || []; + var toolbarUis = []; + for (var i = 0; i < toolbars.length; i++) { + var toolbar = toolbars[i]; + var toolbarUi = new baidu.editor.ui.Toolbar({theme:editor.options.theme}); + for (var j = 0; j < toolbar.length; j++) { + var toolbarItem = toolbar[j]; + var toolbarItemUi = null; + if (typeof toolbarItem == 'string') { + toolbarItem = toolbarItem.toLowerCase(); + if (toolbarItem == '|') { + toolbarItem = 'Separator'; + } + if(toolbarItem == '||'){ + toolbarItem = 'Breakline'; + } + if (baidu.editor.ui[toolbarItem]) { + toolbarItemUi = new baidu.editor.ui[toolbarItem](editor); + } + + //fullscreen这里单独处理一下,放到首行去 + if (toolbarItem == 'fullscreen') { + if (toolbarUis && toolbarUis[0]) { + toolbarUis[0].items.splice(0, 0, toolbarItemUi); + } else { + toolbarItemUi && toolbarUi.items.splice(0, 0, toolbarItemUi); + } + + continue; + + + } + } else { + toolbarItemUi = toolbarItem; + } + if (toolbarItemUi && toolbarItemUi.id) { + + toolbarUi.add(toolbarItemUi); + } + } + toolbarUis[i] = toolbarUi; + } + + //接受外部定制的UI + + utils.each(UE._customizeUI,function(obj,key){ + var itemUI,index; + if(obj.id && obj.id != editor.key){ + return false; + } + itemUI = obj.execFn.call(editor,editor,key); + if(itemUI){ + index = obj.index; + if(index === undefined){ + index = toolbarUi.items.length; + } + toolbarUi.add(itemUI,index) + } + }); + + this.toolbars = toolbarUis; + }, + getHtmlTpl:function () { + return '
      ' + + '
      ' + + (this.toolbars.length ? + '
      ' + + this.renderToolbarBoxHtml() + + '
      ' : '') + + '' + + '
      ' + + '
      ' + + '
      ' + + '
      ' + + //modify wdcount by matao + '
      ' + + '' + + '' + + '' + + '
      ' + + '
      ' + + '
      '; + }, + showWordImageDialog:function () { + this._dialogs['wordimageDialog'].open(); + }, + renderToolbarBoxHtml:function () { + var buff = []; + for (var i = 0; i < this.toolbars.length; i++) { + buff.push(this.toolbars[i].renderHtml()); + } + return buff.join(''); + }, + setFullScreen:function (fullscreen) { + + var editor = this.editor, + container = editor.container.parentNode.parentNode; + if (this._fullscreen != fullscreen) { + this._fullscreen = fullscreen; + this.editor.fireEvent('beforefullscreenchange', fullscreen); + if (baidu.editor.browser.gecko) { + var bk = editor.selection.getRange().createBookmark(); + } + if (fullscreen) { + while (container.tagName != "BODY") { + var position = baidu.editor.dom.domUtils.getComputedStyle(container, "position"); + nodeStack.push(position); + container.style.position = "static"; + container = container.parentNode; + } + this._bakHtmlOverflow = document.documentElement.style.overflow; + this._bakBodyOverflow = document.body.style.overflow; + this._bakAutoHeight = this.editor.autoHeightEnabled; + this._bakScrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop); + + this._bakEditorContaninerWidth = editor.iframe.parentNode.offsetWidth; + if (this._bakAutoHeight) { + //当全屏时不能执行自动长高 + editor.autoHeightEnabled = false; + this.editor.disableAutoHeight(); + } + + document.documentElement.style.overflow = 'hidden'; + //修复,滚动条不收起的问题 + + window.scrollTo(0,window.scrollY); + this._bakCssText = this.getDom().style.cssText; + this._bakCssText1 = this.getDom('iframeholder').style.cssText; + editor.iframe.parentNode.style.width = ''; + this._updateFullScreen(); + } else { + while (container.tagName != "BODY") { + container.style.position = nodeStack.shift(); + container = container.parentNode; + } + this.getDom().style.cssText = this._bakCssText; + this.getDom('iframeholder').style.cssText = this._bakCssText1; + if (this._bakAutoHeight) { + editor.autoHeightEnabled = true; + this.editor.enableAutoHeight(); + } + + document.documentElement.style.overflow = this._bakHtmlOverflow; + document.body.style.overflow = this._bakBodyOverflow; + editor.iframe.parentNode.style.width = this._bakEditorContaninerWidth + 'px'; + window.scrollTo(0, this._bakScrollTop); + } + if (browser.gecko && editor.body.contentEditable === 'true') { + var input = document.createElement('input'); + document.body.appendChild(input); + editor.body.contentEditable = false; + setTimeout(function () { + input.focus(); + setTimeout(function () { + editor.body.contentEditable = true; + editor.fireEvent('fullscreenchanged', fullscreen); + editor.selection.getRange().moveToBookmark(bk).select(true); + baidu.editor.dom.domUtils.remove(input); + fullscreen && window.scroll(0, 0); + }, 0) + }, 0) + } + + if(editor.body.contentEditable === 'true'){ + this.editor.fireEvent('fullscreenchanged', fullscreen); + this.triggerLayout(); + } + + } + }, + _updateFullScreen:function () { + if (this._fullscreen) { + var vpRect = uiUtils.getViewportRect(); + this.getDom().style.cssText = 'border:0;position:absolute;left:0;top:' + (this.editor.options.topOffset || 0) + 'px;width:' + vpRect.width + 'px;height:' + vpRect.height + 'px;z-index:' + (this.getDom().style.zIndex * 1 + 100); + uiUtils.setViewportOffset(this.getDom(), { left:0, top:this.editor.options.topOffset || 0 }); + this.editor.setHeight(vpRect.height - this.getDom('toolbarbox').offsetHeight - this.getDom('bottombar').offsetHeight - (this.editor.options.topOffset || 0),true); + //不手动调一下,会导致全屏失效 + if(browser.gecko){ + try{ + window.onresize(); + }catch(e){ + + } + + } + } + }, + _updateElementPath:function () { + var bottom = this.getDom('elementpath'), list; + if (this.elementPathEnabled && (list = this.editor.queryCommandValue('elementpath'))) { + + var buff = []; + for (var i = 0, ci; ci = list[i]; i++) { + buff[i] = this.formatHtml('' + ci + ''); + } + bottom.innerHTML = '
      ' + this.editor.getLang("elementPathTip") + ': ' + buff.join(' > ') + '
      '; + + } else { + bottom.style.display = 'none' + } + }, + disableElementPath:function () { + var bottom = this.getDom('elementpath'); + bottom.innerHTML = ''; + bottom.style.display = 'none'; + this.elementPathEnabled = false; + + }, + enableElementPath:function () { + var bottom = this.getDom('elementpath'); + bottom.style.display = ''; + this.elementPathEnabled = true; + this._updateElementPath(); + }, + _scale:function () { + var doc = document, + editor = this.editor, + editorHolder = editor.container, + editorDocument = editor.document, + toolbarBox = this.getDom("toolbarbox"), + bottombar = this.getDom("bottombar"), + scale = this.getDom("scale"), + scalelayer = this.getDom("scalelayer"); + + var isMouseMove = false, + position = null, + minEditorHeight = 0, + minEditorWidth = editor.options.minFrameWidth, + pageX = 0, + pageY = 0, + scaleWidth = 0, + scaleHeight = 0; + + function down() { + position = domUtils.getXY(editorHolder); + + if (!minEditorHeight) { + minEditorHeight = editor.options.minFrameHeight + toolbarBox.offsetHeight + bottombar.offsetHeight; + } + + scalelayer.style.cssText = "position:absolute;left:0;display:;top:0;background-color:#41ABFF;opacity:0.4;filter: Alpha(opacity=40);width:" + editorHolder.offsetWidth + "px;height:" + + editorHolder.offsetHeight + "px;z-index:" + (editor.options.zIndex + 1); + + domUtils.on(doc, "mousemove", move); + domUtils.on(editorDocument, "mouseup", up); + domUtils.on(doc, "mouseup", up); + } + + var me = this; + //by xuheng 全屏时关掉缩放 + this.editor.addListener('fullscreenchanged', function (e, fullScreen) { + if (fullScreen) { + me.disableScale(); + + } else { + if (me.editor.options.scaleEnabled) { + me.enableScale(); + var tmpNode = me.editor.document.createElement('span'); + me.editor.body.appendChild(tmpNode); + me.editor.body.style.height = Math.max(domUtils.getXY(tmpNode).y, me.editor.iframe.offsetHeight - 20) + 'px'; + domUtils.remove(tmpNode) + } + } + }); + function move(event) { + clearSelection(); + var e = event || window.event; + pageX = e.pageX || (doc.documentElement.scrollLeft + e.clientX); + pageY = e.pageY || (doc.documentElement.scrollTop + e.clientY); + scaleWidth = pageX - position.x; + scaleHeight = pageY - position.y; + + if (scaleWidth >= minEditorWidth) { + isMouseMove = true; + scalelayer.style.width = scaleWidth + 'px'; + } + if (scaleHeight >= minEditorHeight) { + isMouseMove = true; + scalelayer.style.height = scaleHeight + "px"; + } + } + + function up() { + if (isMouseMove) { + isMouseMove = false; + editor.ui._actualFrameWidth = scalelayer.offsetWidth - 2; + editorHolder.style.width = editor.ui._actualFrameWidth + 'px'; + + editor.setHeight(scalelayer.offsetHeight - bottombar.offsetHeight - toolbarBox.offsetHeight - 2,true); + } + if (scalelayer) { + scalelayer.style.display = "none"; + } + clearSelection(); + domUtils.un(doc, "mousemove", move); + domUtils.un(editorDocument, "mouseup", up); + domUtils.un(doc, "mouseup", up); + } + + function clearSelection() { + if (browser.ie) + doc.selection.clear(); + else + window.getSelection().removeAllRanges(); + } + + this.enableScale = function () { + //trace:2868 + if (editor.queryCommandState("source") == 1) return; + scale.style.display = ""; + this.scaleEnabled = true; + domUtils.on(scale, "mousedown", down); + }; + this.disableScale = function () { + scale.style.display = "none"; + this.scaleEnabled = false; + domUtils.un(scale, "mousedown", down); + }; + }, + isFullScreen:function () { + return this._fullscreen; + }, + postRender:function () { + UIBase.prototype.postRender.call(this); + for (var i = 0; i < this.toolbars.length; i++) { + this.toolbars[i].postRender(); + } + var me = this; + var timerId, + domUtils = baidu.editor.dom.domUtils, + updateFullScreenTime = function () { + clearTimeout(timerId); + timerId = setTimeout(function () { + me._updateFullScreen(); + }); + }; + domUtils.on(window, 'resize', updateFullScreenTime); + + me.addListener('destroy', function () { + domUtils.un(window, 'resize', updateFullScreenTime); + clearTimeout(timerId); + }) + }, + showToolbarMsg:function (msg, flag) { + this.getDom('toolbarmsg_label').innerHTML = msg; + this.getDom('toolbarmsg').style.display = ''; + // + if (!flag) { + var w = this.getDom('upload_dialog'); + w.style.display = 'none'; + } + }, + hideToolbarMsg:function () { + this.getDom('toolbarmsg').style.display = 'none'; + }, + mapUrl:function (url) { + return url ? url.replace('~/', this.editor.options.UEDITOR_HOME_URL || '') : '' + }, + triggerLayout:function () { + var dom = this.getDom(); + if (dom.style.zoom == '1') { + dom.style.zoom = '100%'; + } else { + dom.style.zoom = '1'; + } + } + }; + utils.inherits(EditorUI, baidu.editor.ui.UIBase); + + + var instances = {}; + + + UE.ui.Editor = function (options) { + var editor = new UE.Editor(options); + editor.options.editor = editor; + utils.loadFile(document, { + href:editor.options.themePath + editor.options.theme + "/css/ueditor.css", + tag:"link", + type:"text/css", + rel:"stylesheet" + }); + + var oldRender = editor.render; + editor.render = function (holder) { + if (holder.constructor === String) { + editor.key = holder; + instances[holder] = editor; + } + utils.domReady(function () { + editor.langIsReady ? renderUI() : editor.addListener("langReady", renderUI); + function renderUI() { + editor.setOpt({ + labelMap:editor.options.labelMap || editor.getLang('labelMap') + }); + new EditorUI(editor.options); + if (holder) { + if (holder.constructor === String) { + holder = document.getElementById(holder); + } + holder && holder.getAttribute('name') && ( editor.options.textarea = holder.getAttribute('name')); + if (holder && /script|textarea/ig.test(holder.tagName)) { + var newDiv = document.createElement('div'); + holder.parentNode.insertBefore(newDiv, holder); + var cont = holder.value || holder.innerHTML; + editor.options.initialContent = /^[\t\r\n ]*$/.test(cont) ? editor.options.initialContent : + cont.replace(/>[\n\r\t]+([ ]{4})+/g, '>') + .replace(/[\n\r\t]+([ ]{4})+[\n\r\t]+<'); + holder.className && (newDiv.className = holder.className); + holder.style.cssText && (newDiv.style.cssText = holder.style.cssText); + if (/textarea/i.test(holder.tagName)) { + editor.textarea = holder; + editor.textarea.style.display = 'none'; + + + } else { + holder.parentNode.removeChild(holder); + + + } + if(holder.id){ + newDiv.id = holder.id; + domUtils.removeAttributes(holder,'id'); + } + holder = newDiv; + holder.innerHTML = ''; + } + + } + domUtils.addClass(holder, "edui-" + editor.options.theme); + editor.ui.render(holder); + var opt = editor.options; + //给实例添加一个编辑器的容器引用 + editor.container = editor.ui.getDom(); + var parents = domUtils.findParents(holder,true); + var displays = []; + for(var i = 0 ,ci;ci=parents[i];i++){ + displays[i] = ci.style.display; + ci.style.display = 'block' + } + if (opt.initialFrameWidth) { + opt.minFrameWidth = opt.initialFrameWidth; + } else { + opt.minFrameWidth = opt.initialFrameWidth = holder.offsetWidth; + var styleWidth = holder.style.width; + if(/%$/.test(styleWidth)) { + opt.initialFrameWidth = styleWidth; + } + } + if (opt.initialFrameHeight) { + opt.minFrameHeight = opt.initialFrameHeight; + } else { + opt.initialFrameHeight = opt.minFrameHeight = holder.offsetHeight; + } + for(var i = 0 ,ci;ci=parents[i];i++){ + ci.style.display = displays[i] + } + //编辑器最外容器设置了高度,会导致,编辑器不占位 + //todo 先去掉,没有找到原因 + if(holder.style.height){ + holder.style.height = '' + } + editor.container.style.width = opt.initialFrameWidth + (/%$/.test(opt.initialFrameWidth) ? '' : 'px'); + editor.container.style.zIndex = opt.zIndex; + oldRender.call(editor, editor.ui.getDom('iframeholder')); + editor.fireEvent("afteruiready"); + } + }) + }; + return editor; + }; + + + /** + * @file + * @name UE + * @short UE + * @desc UEditor的顶部命名空间 + */ + /** + * @name getEditor + * @since 1.2.4+ + * @grammar UE.getEditor(id,[opt]) => Editor实例 + * @desc 提供一个全局的方法得到编辑器实例 + * + * * ''id'' 放置编辑器的容器id, 如果容器下的编辑器已经存在,就直接返回 + * * ''opt'' 编辑器的可选参数 + * @example + * UE.getEditor('containerId',{onready:function(){//创建一个编辑器实例 + * this.setContent('hello') + * }}); + * UE.getEditor('containerId'); //返回刚创建的实例 + * + */ + UE.getEditor = function (id, opt) { + var editor = instances[id]; + if (!editor) { + editor = instances[id] = new UE.ui.Editor(opt); + editor.render(id); + } + return editor; + }; + + + UE.delEditor = function (id) { + var editor; + if (editor = instances[id]) { + editor.key && editor.destroy(); + delete instances[id] + } + }; + + UE.registerUI = function(uiName,fn,index,editorId){ + utils.each(uiName.split(/\s+/), function (name) { + UE._customizeUI[name] = { + id : editorId, + execFn:fn, + index:index + }; + }) + + } + +})(); + +// adapter/message.js +UE.registerUI('message', function(editor) { + + var editorui = baidu.editor.ui; + var Message = editorui.Message; + var holder; + var _messageItems = []; + var me = editor; + + me.addListener('ready', function(){ + holder = document.getElementById(me.ui.id + '_message_holder'); + updateHolderPos(); + setTimeout(function(){ + updateHolderPos(); + }, 500); + }); + + me.addListener('showmessage', function(type, opt){ + opt = utils.isString(opt) ? { + 'content': opt + } : opt; + var message = new Message({ + 'timeout': opt.timeout, + 'type': opt.type, + 'content': opt.content, + 'keepshow': opt.keepshow, + 'editor': me + }), + mid = opt.id || ('msg_' + (+new Date()).toString(36)); + message.render(holder); + _messageItems[mid] = message; + message.reset(opt); + updateHolderPos(); + return mid; + }); + + me.addListener('updatemessage',function(type, id, opt){ + opt = utils.isString(opt) ? { + 'content': opt + } : opt; + var message = _messageItems[id]; + message.render(holder); + message && message.reset(opt); + }); + + me.addListener('hidemessage',function(type, id){ + var message = _messageItems[id]; + message && message.hide(); + }); + + function updateHolderPos(){ + var toolbarbox = me.ui.getDom('toolbarbox'); + if (toolbarbox) { + holder.style.top = toolbarbox.offsetHeight + 3 + 'px'; + } + holder.style.zIndex = Math.max(me.options.zIndex, me.iframe.style.zIndex) + 1; + } + +}); + + +// adapter/autosave.js +UE.registerUI('autosave', function(editor) { + var timer = null,uid = null; + editor.on('afterautosave',function(){ + clearTimeout(timer); + + timer = setTimeout(function(){ + if(uid){ + editor.trigger('hidemessage',uid); + } + uid = editor.trigger('showmessage',{ + content : editor.getLang('autosave.success'), + timeout : 2000 + }); + + },2000) + }) + +}); + + + +})(); diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/ueditor.parse.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/ueditor.parse.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/ueditor.parse.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/ueditor.parse.js diff --git a/SiteServer.Web/SiteFiles/assets/ueditor/ueditor.parse.min.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/ueditor.parse.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/ueditor/ueditor.parse.min.js rename to net452/SiteServer.Web/Home/assets/lib/ueditor/ueditor.parse.min.js diff --git a/net452/SiteServer.Web/Home/assets/lib/ueditor/ueditor_all_min.js b/net452/SiteServer.Web/Home/assets/lib/ueditor/ueditor_all_min.js new file mode 100644 index 000000000..3a50fd776 --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/lib/ueditor/ueditor_all_min.js @@ -0,0 +1,18 @@ +/*! + * UEditor + * version: ueditor + * build: Wed Aug 10 2016 11:05:21 GMT+0800 (CST) + */ + +!function(){function getListener(a,b,c){var d;return b=b.toLowerCase(),(d=a.__allListeners||c&&(a.__allListeners={}))&&(d[b]||c&&(d[b]=[]))}function getDomNode(a,b,c,d,e,f){var g,h=d&&a[b];for(!h&&(h=a[c]);!h&&(g=(g||a).parentNode);){if("BODY"==g.tagName||f&&!f(g))return null;h=g[c]}return h&&e&&!e(h)?getDomNode(h,b,c,!1,e):h}UEDITOR_CONFIG=window.UEDITOR_CONFIG||{};var baidu=window.baidu||{};window.baidu=baidu,window.UE=baidu.editor=window.UE||{},UE.plugins={},UE.commands={},UE.instants={},UE.I18N={},UE._customizeUI={},UE.version="1.4.3";var dom=UE.dom={},browser=UE.browser=function(){var a=navigator.userAgent.toLowerCase(),b=window.opera,c={ie:/(msie\s|trident.*rv:)([\w.]+)/.test(a),opera:!!b&&b.version,webkit:a.indexOf(" applewebkit/")>-1,mac:a.indexOf("macintosh")>-1,quirks:"BackCompat"==document.compatMode};c.gecko="Gecko"==navigator.product&&!c.webkit&&!c.opera&&!c.ie;var d=0;if(c.ie){var e=a.match(/(?:msie\s([\w.]+))/),f=a.match(/(?:trident.*rv:([\w.]+))/);d=e&&f&&e[1]&&f[1]?Math.max(1*e[1],1*f[1]):e&&e[1]?1*e[1]:f&&f[1]?1*f[1]:0,c.ie11Compat=11==document.documentMode,c.ie9Compat=9==document.documentMode,c.ie8=!!document.documentMode,c.ie8Compat=8==document.documentMode,c.ie7Compat=7==d&&!document.documentMode||7==document.documentMode,c.ie6Compat=d<7||c.quirks,c.ie9above=d>8,c.ie9below=d<9,c.ie11above=d>10,c.ie11below=d<11}if(c.gecko){var g=a.match(/rv:([\d\.]+)/);g&&(g=g[1].split("."),d=1e4*g[0]+100*(g[1]||0)+1*(g[2]||0))}return/chrome\/(\d+\.\d)/i.test(a)&&(c.chrome=+RegExp.$1),/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(a)&&!/chrome/i.test(a)&&(c.safari=+(RegExp.$1||RegExp.$2)),c.opera&&(d=parseFloat(b.version())),c.webkit&&(d=parseFloat(a.match(/ applewebkit\/(\d+)/)[1])),c.version=d,c.isCompatible=!c.mobile&&(c.ie&&d>=6||c.gecko&&d>=10801||c.opera&&d>=9.5||c.air&&d>=1||c.webkit&&d>=522||!1),c}(),ie=browser.ie,webkit=browser.webkit,gecko=browser.gecko,opera=browser.opera,utils=UE.utils={each:function(a,b,c){if(null!=a)if(a.length===+a.length){for(var d=0,e=a.length;d=c&&a===b)return d=e,!1}),d},removeItem:function(a,b){for(var c=0,d=a.length;c'](?:(amp|lt|quot|gt|#39|nbsp|#\d+);)?/g,function(a,b){return b?a:{"<":"<","&":"&",'"':""",">":">","'":"'"}[a]}):""},unhtmlForUrl:function(a,b){return a?a.replace(b||/[<">']/g,function(a){return{"<":"<","&":"&",'"':""",">":">","'":"'"}[a]}):""},html:function(a){return a?a.replace(/&((g|l|quo)t|amp|#39|nbsp);/g,function(a){return{"<":"<","&":"&",""":'"',">":">","'":"'"," ":" "}[a]}):""},cssStyleToDomStyle:function(){var a=document.createElement("div").style,b={"float":void 0!=a.cssFloat?"cssFloat":void 0!=a.styleFloat?"styleFloat":"float"};return function(a){return b[a]||(b[a]=a.toLowerCase().replace(/-./g,function(a){return a.charAt(1).toUpperCase()}))}}(),loadFile:function(){function a(a,c){try{for(var d,e=0;d=b[e++];)if(d.doc===a&&d.url==(c.src||c.href))return d}catch(f){return null}}var b=[];return function(c,d,e){var f=a(c,d);if(f)return void(f.ready?e&&e():f.funs.push(e));if(b.push({doc:c,url:d.src||d.href,funs:[e]}),!c.body){var g=[];for(var h in d)"tag"!=h&&g.push(h+'="'+d[h]+'"');return void c.write("<"+d.tag+" "+g.join(" ")+" >")}if(!d.id||!c.getElementById(d.id)){var i=c.createElement(d.tag);delete d.tag;for(var h in d)i.setAttribute(h,d[h]);i.onload=i.onreadystatechange=function(){if(!this.readyState||/loaded|complete/.test(this.readyState)){if(f=a(c,d),f.funs.length>0){f.ready=1;for(var b;b=f.funs.pop();)b()}i.onload=i.onreadystatechange=null}},i.onerror=function(){throw Error("The load "+(d.href||d.src)+" fails,check the url settings of file ueditor.config.js ")},c.getElementsByTagName("head")[0].appendChild(i)}}}(),isEmptyObject:function(a){if(null==a)return!0;if(this.isArray(a)||this.isString(a))return 0===a.length;for(var b in a)if(a.hasOwnProperty(b))return!1;return!0},fixColor:function(a,b){if(/color/i.test(a)&&/rgba?/.test(b)){var c=b.split(",");if(c.length>3)return"";b="#";for(var d,e=0;d=c[e++];)d=parseInt(d.replace(/[^\d]/gi,""),10).toString(16),b+=1==d.length?"0"+d:d;b=b.toUpperCase()}return b},optCss:function(a){function b(a,b){if(!a)return"";var c=a.top,d=a.bottom,e=a.left,f=a.right,g="";if(c&&e&&d&&f)g+=";"+b+":"+(c==d&&d==e&&e==f?c:c==d&&e==f?c+" "+e:e==f?c+" "+e+" "+d:c+" "+f+" "+d+" "+e)+";";else for(var h in a)g+=";"+b+"-"+h+":"+a[h]+";";return g}var c,d;return a=a.replace(/(padding|margin|border)\-([^:]+):([^;]+);?/gi,function(a,b,e,f){if(1==f.split(" ").length)switch(b){case"padding":return!c&&(c={}),c[e]=f,"";case"margin":return!d&&(d={}),d[e]=f,"";case"border":return"initial"==f?"":a}return a}),a+=b(c,"padding")+b(d,"margin"),a.replace(/^[ \n\r\t;]*|[ \n\r\t]*$/,"").replace(/;([ \n\r\t]+)|\1;/g,";").replace(/(&((l|g)t|quot|#39))?;{2,}/g,function(a,b){return b?b+";;":";"})},clone:function(a,b){var c;b=b||{};for(var d in a)a.hasOwnProperty(d)&&(c=a[d],"object"==typeof c?(b[d]=utils.isArray(c)?[]:{},utils.clone(a[d],b[d])):b[d]=c);return b},transUnitToPx:function(a){if(!/(pt|cm)/.test(a))return a;var b;switch(a.replace(/([\d.]+)(\w+)/,function(c,d,e){a=d,b=e}),b){case"cm":a=25*parseFloat(a);break;case"pt":a=Math.round(96*parseFloat(a)/72)}return a+(a?"px":"")},domReady:function(){function a(a){a.isReady=!0;for(var c;c=b.pop();c());}var b=[];return function(c,d){d=d||window;var e=d.document;c&&b.push(c),"complete"===e.readyState?a(e):(e.isReady&&a(e),browser.ie&&11!=browser.version?(!function(){if(!e.isReady){try{e.documentElement.doScroll("left")}catch(b){return void setTimeout(arguments.callee,0)}a(e)}}(),d.attachEvent("onload",function(){a(e)})):(e.addEventListener("DOMContentLoaded",function(){e.removeEventListener("DOMContentLoaded",arguments.callee,!1),a(e)},!1),d.addEventListener("load",function(){a(e)},!1)))}}(),cssRule:browser.ie&&11!=browser.version?function(a,b,c){var d,e;if(void 0===b||b&&b.nodeType&&9==b.nodeType){if(c=b&&b.nodeType&&9==b.nodeType?b:c||document,d=c.indexList||(c.indexList={}),e=d[a],void 0!==e)return c.styleSheets[e].cssText}else{if(c=c||document,d=c.indexList||(c.indexList={}),e=d[a],""===b)return void 0!==e&&(c.styleSheets[e].cssText="",delete d[a],!0);void 0!==e?sheetStyle=c.styleSheets[e]:(sheetStyle=c.createStyleSheet("",e=c.styleSheets.length),d[a]=e),sheetStyle.cssText=b}}:function(a,b,c){var d;return void 0===b||b&&b.nodeType&&9==b.nodeType?(c=b&&b.nodeType&&9==b.nodeType?b:c||document,d=c.getElementById(a),d?d.innerHTML:void 0):(c=c||document,d=c.getElementById(a),""===b?!!d&&(d.parentNode.removeChild(d),!0):void(d?d.innerHTML=b:(d=c.createElement("style"),d.id=a,d.innerHTML=b,c.getElementsByTagName("head")[0].appendChild(d))))},sort:function(a,b){b=b||function(a,b){return a.localeCompare(b)};for(var c=0,d=a.length;c0){var g=a[c];a[c]=a[e],a[e]=g}return a},serializeParam:function(a){var b=[];for(var c in a)if("method"!=c&&"timeout"!=c&&"async"!=c)if("function"!=(typeof a[c]).toLowerCase()&&"object"!=(typeof a[c]).toLowerCase())b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));else if(utils.isArray(a[c]))for(var d=0;d1||b!==a.parentNode){a.style.cssText=b.style.cssText+";"+a.style.cssText,b=b.parentNode;continue}b.style.cssText+=";"+a.style.cssText,"A"==b.tagName&&(b.style.textDecoration="underline")}if("A"!=b.tagName){b===a.parentNode&&domUtils.remove(a,!0);break}}b=b.parentNode}},mergeSibling:function(a,b,c){function d(a,b,c){var d;if((d=c[a])&&!domUtils.isBookmarkNode(d)&&1==d.nodeType&&domUtils.isSameElement(c,d)){for(;d.firstChild;)"firstChild"==b?c.insertBefore(d.lastChild,c.firstChild):c.appendChild(d.firstChild);domUtils.remove(d)}}!b&&d("previousSibling","firstChild",a),!c&&d("nextSibling","lastChild",a)},unSelectable:ie&&browser.ie9below||browser.opera?function(a){a.onselectstart=function(){return!1},a.onclick=a.onkeyup=a.onkeydown=function(){return!1},a.unselectable="on",a.setAttribute("unselectable","on");for(var b,c=0;b=a.all[c++];)switch(b.tagName.toLowerCase()){case"iframe":case"textarea":case"input":case"select":break;default:b.unselectable="on",a.setAttribute("unselectable","on")}}:function(a){a.style.MozUserSelect=a.style.webkitUserSelect=a.style.msUserSelect=a.style.KhtmlUserSelect="none"},removeAttributes:function(a,b){b=utils.isArray(b)?b:utils.trim(b).replace(/[ ]{2,}/g," ").split(" ");for(var c,d=0;c=b[d++];){switch(c=attrFix[c]||c){case"className":a[c]="";break;case"style":a.style.cssText="";var e=a.getAttributeNode("style");!browser.ie&&e&&a.removeAttributeNode(e)}a.removeAttribute(c)}},createElement:function(a,b,c){return domUtils.setAttributes(a.createElement(b),c)},setAttributes:function(a,b){for(var c in b)if(b.hasOwnProperty(c)){var d=b[c];switch(c){case"class":a.className=d;break;case"style":a.style.cssText=a.style.cssText+";"+d;break;case"innerHTML":a[c]=d;break;case"value":a.value=d;break;default:a.setAttribute(attrFix[c]||c,d)}}return a},getComputedStyle:function(a,b){var c="width height top left";if(c.indexOf(b)>-1)return a["offset"+b.replace(/^\w/,function(a){return a.toUpperCase()})]+"px";if(3==a.nodeType&&(a=a.parentNode),browser.ie&&browser.version<9&&"font-size"==b&&!a.style.fontSize&&!dtd.$empty[a.tagName]&&!dtd.$nonChild[a.tagName]){var d=a.ownerDocument.createElement("span");d.style.cssText="padding:0;border:0;font-family:simsun;",d.innerHTML=".",a.appendChild(d);var e=d.offsetHeight;return a.removeChild(d),d=null,e+"px"}try{var f=domUtils.getStyle(a,b)||(window.getComputedStyle?domUtils.getWindow(a).getComputedStyle(a,"").getPropertyValue(b):(a.currentStyle||a.style)[utils.cssStyleToDomStyle(b)])}catch(g){return""}return utils.transUnitToPx(utils.fixColor(b,f))},removeClasses:function(a,b){b=utils.isArray(b)?b:utils.trim(b).replace(/[ ]{2,}/g," ").split(" ");for(var c,d=0,e=a.className;c=b[d++];)e=e.replace(new RegExp("\\b"+c+"\\b"),"");e=utils.trim(e).replace(/[ ]{2,}/g," "),e?a.className=e:domUtils.removeAttributes(a,["class"])},addClass:function(a,b){if(a){b=utils.trim(b).replace(/[ ]{2,}/g," ").split(" ");for(var c,d=0,e=a.className;c=b[d++];)new RegExp("\\b"+c+"\\b").test(e)||(e+=" "+c);a.className=utils.trim(e)}},hasClass:function(a,b){if(utils.isRegExp(b))return b.test(a.className);b=utils.trim(b).replace(/[ ]{2,}/g," ").split(" ");for(var c,d=0,e=a.className;c=b[d++];)if(!new RegExp("\\b"+c+"\\b","i").test(e))return!1;return d-1==b.length},preventDefault:function(a){a.preventDefault?a.preventDefault():a.returnValue=!1},removeStyle:function(a,b){browser.ie?("color"==b&&(b="(^|;)"+b),a.style.cssText=a.style.cssText.replace(new RegExp(b+"[^:]*:[^;]+;?","ig"),"")):a.style.removeProperty?a.style.removeProperty(b):a.style.removeAttribute(utils.cssStyleToDomStyle(b)),a.style.cssText||domUtils.removeAttributes(a,["style"])},getStyle:function(a,b){var c=a.style[utils.cssStyleToDomStyle(b)];return utils.fixColor(b,c)},setStyle:function(a,b,c){a.style[utils.cssStyleToDomStyle(b)]=c,utils.trim(a.style.cssText)||this.removeAttributes(a,"style")},setStyles:function(a,b){for(var c in b)b.hasOwnProperty(c)&&domUtils.setStyle(a,c,b[c])},removeDirtyAttr:function(a){for(var b,c=0,d=a.getElementsByTagName("*");b=d[c++];)b.removeAttribute("_moz_dirty");a.removeAttribute("_moz_dirty")},getChildCount:function(a,b){var c=0,d=a.firstChild;for(b=b||function(){return 1};d;)b(d)&&c++,d=d.nextSibling;return c},isEmptyNode:function(a){return!a.firstChild||0==domUtils.getChildCount(a,function(a){return!domUtils.isBr(a)&&!domUtils.isBookmarkNode(a)&&!domUtils.isWhitespace(a)})},clearSelectedArr:function(a){for(var b;b=a.pop();)domUtils.removeAttributes(b,["class"])},scrollToView:function(a,b,c){var d=function(){var a=b.document,c="CSS1Compat"==a.compatMode;return{width:(c?a.documentElement.clientWidth:a.body.clientWidth)||0,height:(c?a.documentElement.clientHeight:a.body.clientHeight)||0}},e=function(a){if("pageXOffset"in a)return{x:a.pageXOffset||0,y:a.pageYOffset||0};var b=a.document;return{x:b.documentElement.scrollLeft||b.body.scrollLeft||0,y:b.documentElement.scrollTop||b.body.scrollTop||0}},f=d().height,g=f*-1+c;g+=a.offsetHeight||0;var h=domUtils.getXY(a);g+=h.y;var i=e(b).y;(g>i||g0)return 0;for(var c in dtd.$isNotEmpty)if(a.getElementsByTagName(c).length)return 0;return 1},setViewportOffset:function(a,b){var c=0|parseInt(a.style.left),d=0|parseInt(a.style.top),e=a.getBoundingClientRect(),f=b.left-e.left,g=b.top-e.top;f&&(a.style.left=c+f+"px"),g&&(a.style.top=d+g+"px")},fillNode:function(a,b){var c=browser.ie?a.createTextNode(domUtils.fillChar):a.createElement("br");b.innerHTML="",b.appendChild(c)},moveChild:function(a,b,c){for(;a.firstChild;)c&&b.firstChild?b.insertBefore(a.lastChild,b.firstChild):b.appendChild(a.firstChild)},hasNoAttributes:function(a){return browser.ie?/^<\w+\s*?>/.test(a.outerHTML):0==a.attributes.length},isCustomeNode:function(a){return 1==a.nodeType&&a.getAttribute("_ue_custom_node_")},isTagNode:function(a,b){return 1==a.nodeType&&new RegExp("\\b"+a.tagName+"\\b","i").test(b)},filterNodeList:function(a,b,c){var d=[];if(!utils.isFunction(b)){var e=b;b=function(a){return utils.indexOf(utils.isArray(e)?e:e.split(" "),a.tagName.toLowerCase())!=-1}}return utils.each(a,function(a){b(a)&&d.push(a)}),0==d.length?null:1!=d.length&&c?d:d[0]},isInNodeEndBoundary:function(a,b){var c=a.startContainer;if(3==c.nodeType&&a.startOffset!=c.nodeValue.length)return 0;if(1==c.nodeType&&a.startOffset!=c.childNodes.length)return 0;for(;c!==b;){if(c.nextSibling)return 0;c=c.parentNode}return 1},isBoundaryNode:function(a,b){for(var c;!domUtils.isBody(a);)if(c=a,a=a.parentNode,c!==a[b])return!1;return!0},fillHtml:browser.ie11below?" ":"
      "},fillCharReg=new RegExp(domUtils.fillChar,"g");!function(){function a(a){a.collapsed=a.startContainer&&a.endContainer&&a.startContainer===a.endContainer&&a.startOffset==a.endOffset}function b(a){return!a.collapsed&&1==a.startContainer.nodeType&&a.startContainer===a.endContainer&&a.endOffset-a.startOffset==1}function c(b,c,d,e){return 1==c.nodeType&&(dtd.$empty[c.tagName]||dtd.$nonChild[c.tagName])&&(d=domUtils.getNodeIndex(c)+(b?0:1),c=c.parentNode),b?(e.startContainer=c,e.startOffset=d,e.endContainer||e.collapse(!0)):(e.endContainer=c,e.endOffset=d,e.startContainer||e.collapse(!1)),a(e),e}function d(a,b){var c,d,e=a.startContainer,f=a.endContainer,g=a.startOffset,h=a.endOffset,i=a.document,j=i.createDocumentFragment();if(1==e.nodeType&&(e=e.childNodes[g]||(c=e.appendChild(i.createTextNode("")))),1==f.nodeType&&(f=f.childNodes[h]||(d=f.appendChild(i.createTextNode("")))),e===f&&3==e.nodeType)return j.appendChild(i.createTextNode(e.substringData(g,h-g))),b&&(e.deleteData(g,h-g),a.collapse(!0)),j;for(var k,l,m=j,n=domUtils.findParents(e,!0),o=domUtils.findParents(f,!0),p=0;n[p]==o[p];)p++;for(var q,r=p;q=n[r];r++){for(k=q.nextSibling,q==e?c||(3==a.startContainer.nodeType?(m.appendChild(i.createTextNode(e.nodeValue.slice(g))),b&&e.deleteData(g,e.nodeValue.length-g)):m.appendChild(b?e:e.cloneNode(!0))):(l=q.cloneNode(!1),m.appendChild(l));k&&k!==f&&k!==o[r];)q=k.nextSibling,m.appendChild(b?k:k.cloneNode(!0)),k=q;m=l}m=j,n[p]||(m.appendChild(n[p-1].cloneNode(!1)),m=m.firstChild);for(var s,r=p;s=o[r];r++){if(k=s.previousSibling,s==f?d||3!=a.endContainer.nodeType||(m.appendChild(i.createTextNode(f.substringData(0,h))),b&&f.deleteData(0,h)):(l=s.cloneNode(!1),m.appendChild(l)),r!=p||!n[p])for(;k&&k!==e;)s=k.previousSibling,m.insertBefore(b?k:k.cloneNode(!0),m.firstChild),k=s;m=l}return b&&a.setStartBefore(o[p]?n[p]?o[p]:n[p-1]:o[p-1]).collapse(!0),c&&domUtils.remove(c),d&&domUtils.remove(d),j}function e(a,b){try{if(g&&domUtils.inDoc(g,a))if(g.nodeValue.replace(fillCharReg,"").length)g.nodeValue=g.nodeValue.replace(fillCharReg,"");else{var c=g.parentNode;for(domUtils.remove(g);c&&domUtils.isEmptyInlineElement(c)&&(browser.safari?!(domUtils.getPosition(c,b)&domUtils.POSITION_CONTAINS):!c.contains(b));)g=c.parentNode,domUtils.remove(c),c=g}}catch(d){} +}function f(a,b){var c;for(a=a[b];a&&domUtils.isFillChar(a);)c=a[b],domUtils.remove(a),a=c}var g,h=0,i=domUtils.fillChar,j=dom.Range=function(a){var b=this;b.startContainer=b.startOffset=b.endContainer=b.endOffset=null,b.document=a,b.collapsed=!0};j.prototype={cloneContents:function(){return this.collapsed?null:d(this,0)},deleteContents:function(){var a;return this.collapsed||d(this,1),browser.webkit&&(a=this.startContainer,3!=a.nodeType||a.nodeValue.length||(this.setStartBefore(a).collapse(!0),domUtils.remove(a))),this},extractContents:function(){return this.collapsed?null:d(this,2)},setStart:function(a,b){return c(!0,a,b,this)},setEnd:function(a,b){return c(!1,a,b,this)},setStartAfter:function(a){return this.setStart(a.parentNode,domUtils.getNodeIndex(a)+1)},setStartBefore:function(a){return this.setStart(a.parentNode,domUtils.getNodeIndex(a))},setEndAfter:function(a){return this.setEnd(a.parentNode,domUtils.getNodeIndex(a)+1)},setEndBefore:function(a){return this.setEnd(a.parentNode,domUtils.getNodeIndex(a))},setStartAtFirst:function(a){return this.setStart(a,0)},setStartAtLast:function(a){return this.setStart(a,3==a.nodeType?a.nodeValue.length:a.childNodes.length)},setEndAtFirst:function(a){return this.setEnd(a,0)},setEndAtLast:function(a){return this.setEnd(a,3==a.nodeType?a.nodeValue.length:a.childNodes.length)},selectNode:function(a){return this.setStartBefore(a).setEndAfter(a)},selectNodeContents:function(a){return this.setStart(a,0).setEndAtLast(a)},cloneRange:function(){var a=this;return new j(a.document).setStart(a.startContainer,a.startOffset).setEnd(a.endContainer,a.endOffset)},collapse:function(a){var b=this;return a?(b.endContainer=b.startContainer,b.endOffset=b.startOffset):(b.startContainer=b.endContainer,b.startOffset=b.endOffset),b.collapsed=!0,b},shrinkBoundary:function(a){function b(a){return 1==a.nodeType&&!domUtils.isBookmarkNode(a)&&!dtd.$empty[a.tagName]&&!dtd.$nonChild[a.tagName]}for(var c,d=this,e=d.collapsed;1==d.startContainer.nodeType&&(c=d.startContainer.childNodes[d.startOffset])&&b(c);)d.setStart(c,0);if(e)return d.collapse(!0);if(!a)for(;1==d.endContainer.nodeType&&d.endOffset>0&&(c=d.endContainer.childNodes[d.endOffset-1])&&b(c);)d.setEnd(c,c.childNodes.length);return d},getCommonAncestor:function(a,c){var d=this,e=d.startContainer,f=d.endContainer;return e===f?a&&b(this)&&(e=e.childNodes[d.startOffset],1==e.nodeType)?e:c&&3==e.nodeType?e.parentNode:e:domUtils.getCommonAncestor(e,f)},trimBoundary:function(a){this.txtToElmBoundary();var b=this.startContainer,c=this.startOffset,d=this.collapsed,e=this.endContainer;if(3==b.nodeType){if(0==c)this.setStartBefore(b);else if(c>=b.nodeValue.length)this.setStartAfter(b);else{var f=domUtils.split(b,c);b===e?this.setEnd(f,this.endOffset-c):b.parentNode===e&&(this.endOffset+=1),this.setStartBefore(f)}if(d)return this.collapse(!0)}return a||(c=this.endOffset,e=this.endContainer,3==e.nodeType&&(0==c?this.setEndBefore(e):(c=c.nodeValue.length&&a["set"+b.replace(/(\w)/,function(a){return a.toUpperCase()})+"After"](c):a["set"+b.replace(/(\w)/,function(a){return a.toUpperCase()})+"Before"](c))}return!a&&this.collapsed||(b(this,"start"),b(this,"end")),this},insertNode:function(a){var b=a,c=1;11==a.nodeType&&(b=a.firstChild,c=a.childNodes.length),this.trimBoundary(!0);var d=this.startContainer,e=this.startOffset,f=d.childNodes[e];return f?d.insertBefore(a,f):d.appendChild(a),b.parentNode===this.endContainer&&(this.endOffset=this.endOffset+c),this.setStartBefore(b)},setCursor:function(a,b){return this.collapse(!a).select(b)},createBookmark:function(a,b){var c,d=this.document.createElement("span");return d.style.cssText="display:none;line-height:0px;",d.appendChild(this.document.createTextNode("‍")),d.id="_baidu_bookmark_start_"+(b?"":h++),this.collapsed||(c=d.cloneNode(!0),c.id="_baidu_bookmark_end_"+(b?"":h++)),this.insertNode(d),c&&this.collapse().insertNode(c).setEndBefore(c),this.setStartAfter(d),{start:a?d.id:d,end:c?a?c.id:c:null,id:a}},moveToBookmark:function(a){var b=a.id?this.document.getElementById(a.start):a.start,c=a.end&&a.id?this.document.getElementById(a.end):a.end;return this.setStartBefore(b),domUtils.remove(b),c?(this.setEndBefore(c),domUtils.remove(c)):this.collapse(!0),this},enlarge:function(a,b){var c,d,e=domUtils.isBody,f=this.document.createTextNode("");if(a){for(d=this.startContainer,1==d.nodeType?d.childNodes[this.startOffset]?c=d=d.childNodes[this.startOffset]:(d.appendChild(f),c=d=f):c=d;;){if(domUtils.isBlockElm(d)){for(d=c;(c=d.previousSibling)&&!domUtils.isBlockElm(c);)d=c;this.setStartBefore(d);break}c=d,d=d.parentNode}for(d=this.endContainer,1==d.nodeType?((c=d.childNodes[this.endOffset])?d.insertBefore(f,c):d.appendChild(f),c=d=f):c=d;;){if(domUtils.isBlockElm(d)){for(d=c;(c=d.nextSibling)&&!domUtils.isBlockElm(c);)d=c;this.setEndAfter(d);break}c=d,d=d.parentNode}f.parentNode===this.endContainer&&this.endOffset--,domUtils.remove(f)}if(!this.collapsed){for(;!(0!=this.startOffset||b&&b(this.startContainer)||e(this.startContainer));)this.setStartBefore(this.startContainer);for(;!(this.endOffset!=(1==this.endContainer.nodeType?this.endContainer.childNodes.length:this.endContainer.nodeValue.length)||b&&b(this.endContainer)||e(this.endContainer));)this.setEndAfter(this.endContainer)}return this},enlargeToBlockElm:function(a){for(;!domUtils.isBlockElm(this.startContainer);)this.setStartBefore(this.startContainer);if(!a)for(;!domUtils.isBlockElm(this.endContainer);)this.setEndAfter(this.endContainer);return this},adjustmentBoundary:function(){if(!this.collapsed){for(;!domUtils.isBody(this.startContainer)&&this.startOffset==this.startContainer[3==this.startContainer.nodeType?"nodeValue":"childNodes"].length&&this.startContainer[3==this.startContainer.nodeType?"nodeValue":"childNodes"].length;)this.setStartAfter(this.startContainer);for(;!domUtils.isBody(this.endContainer)&&!this.endOffset&&this.endContainer[3==this.endContainer.nodeType?"nodeValue":"childNodes"].length;)this.setEndBefore(this.endContainer)}return this},applyInlineStyle:function(a,b,c){if(this.collapsed)return this;this.trimBoundary().enlarge(!1,function(a){return 1==a.nodeType&&domUtils.isBlockElm(a)}).adjustmentBoundary();for(var d,e,f=this.createBookmark(),g=f.end,h=function(a){return 1==a.nodeType?"br"!=a.tagName.toLowerCase():!domUtils.isWhitespace(a)},i=domUtils.getNextDomNode(f.start,!1,h),j=this.cloneRange();i&&domUtils.getPosition(i,g)&domUtils.POSITION_PRECEDING;)if(3==i.nodeType||dtd[a][i.tagName]){for(j.setStartBefore(i),d=i;d&&(3==d.nodeType||dtd[a][d.tagName])&&d!==g;)e=d,d=domUtils.getNextDomNode(d,1==d.nodeType,null,function(b){return dtd[a][b.tagName]});var k,l=j.setEndAfter(e).extractContents();if(c&&c.length>0){var m,n;n=m=c[0].cloneNode(!1);for(var o,p=1;o=c[p++];)m.appendChild(o.cloneNode(!1)),m=m.firstChild;k=m}else k=j.document.createElement(a);b&&domUtils.setAttributes(k,b),k.appendChild(l),j.insertNode(c?n:k);var q;if("span"==a&&b.style&&/text\-decoration/.test(b.style)&&(q=domUtils.findParentByTagName(k,"a",!0))?(domUtils.setAttributes(q,b),domUtils.remove(k,!0),k=q):(domUtils.mergeSibling(k),domUtils.clearEmptySibling(k)),domUtils.mergeChild(k,b),i=domUtils.getNextDomNode(k,!1,h),domUtils.mergeToParent(k),d===g)break}else i=domUtils.getNextDomNode(i,!0,h);return this.moveToBookmark(f)},removeInlineStyle:function(a){if(this.collapsed)return this;a=utils.isArray(a)?a:[a],this.shrinkBoundary().adjustmentBoundary();for(var b=this.startContainer,c=this.endContainer;;){if(1==b.nodeType){if(utils.indexOf(a,b.tagName.toLowerCase())>-1)break;if("body"==b.tagName.toLowerCase()){b=null;break}}b=b.parentNode}for(;;){if(1==c.nodeType){if(utils.indexOf(a,c.tagName.toLowerCase())>-1)break;if("body"==c.tagName.toLowerCase()){c=null;break}}c=c.parentNode}var d,e,f=this.createBookmark();b&&(e=this.cloneRange().setEndBefore(f.start).setStartBefore(b),d=e.extractContents(),e.insertNode(d),domUtils.clearEmptySibling(b,!0),b.parentNode.insertBefore(f.start,b)),c&&(e=this.cloneRange().setStartAfter(f.end).setEndAfter(c),d=e.extractContents(),e.insertNode(d),domUtils.clearEmptySibling(c,!1,!0),c.parentNode.insertBefore(f.end,c.nextSibling));for(var g,h=domUtils.getNextDomNode(f.start,!1,function(a){return 1==a.nodeType});h&&h!==f.end;)g=domUtils.getNextDomNode(h,!0,function(a){return 1==a.nodeType}),utils.indexOf(a,h.tagName.toLowerCase())>-1&&domUtils.remove(h,!0),h=g;return this.moveToBookmark(f)},getClosedNode:function(){var a;if(!this.collapsed){var c=this.cloneRange().adjustmentBoundary().shrinkBoundary();if(b(c)){var d=c.startContainer.childNodes[c.startOffset];d&&1==d.nodeType&&(dtd.$empty[d.tagName]||dtd.$nonChild[d.tagName])&&(a=d)}}return a},select:browser.ie?function(a,b){var c;this.collapsed||this.shrinkBoundary();var d=this.getClosedNode();if(d&&!b){try{c=this.document.body.createControlRange(),c.addElement(d),c.select()}catch(h){}return this}var j,k=this.createBookmark(),l=k.start;if(c=this.document.body.createTextRange(),c.moveToElementText(l),c.moveStart("character",1),this.collapsed){if(!a&&3!=this.startContainer.nodeType){var m=this.document.createTextNode(i),n=this.document.createElement("span");n.appendChild(this.document.createTextNode(i)),l.parentNode.insertBefore(n,l),l.parentNode.insertBefore(m,l),e(this.document,m),g=m,f(n,"previousSibling"),f(l,"nextSibling"),c.moveStart("character",-1),c.collapse(!0)}}else{var o=this.document.body.createTextRange();j=k.end,o.moveToElementText(j),c.setEndPoint("EndToEnd",o)}this.moveToBookmark(k),n&&domUtils.remove(n);try{c.select()}catch(h){}return this}:function(a){function b(a){function b(b,c,d){3==b.nodeType&&b.nodeValue.length0)j=k-1;else{if(!(l<0))return{container:d,offset:c(e)};i=k+1}}if(k==-1){if(h.moveToElementText(d),h.setEndPoint("StartToStart",a),f=h.text.replace(/(\r\n|\r)/g,"\n").length,g=d.childNodes,!f)return e=g[g.length-1],{container:e,offset:e.nodeValue.length};for(var m=g.length;f>0;)f-=g[--m].nodeValue.length;return{container:g[m],offset:-f}}if(h.collapse(l>0),h.setEndPoint(l>0?"StartToStart":"EndToStart",a),f=h.text.replace(/(\r\n|\r)/g,"\n").length,!f)return dtd.$empty[e.tagName]||dtd.$nonChild[e.tagName]?{container:d,offset:c(e)+(l>0?0:1)}:{container:e,offset:l>0?0:e.childNodes.length};for(;f>0;)try{var n=e;e=e[l>0?"previousSibling":"nextSibling"],f-=e.nodeValue.length}catch(o){return{container:d,offset:c(n)}}return{container:e,offset:l>0?-f:e.nodeValue.length+f}}function b(b,c){if(b.item)c.selectNode(b.item(0));else{var d=a(b,!0);c.setStart(d.container,d.offset),0!=b.compareEndPoints("StartToEnd",b)&&(d=a(b,!1),c.setEnd(d.container,d.offset))}return c}function c(a){var b;try{b=a.getNative().createRange()}catch(c){return null}var d=b.item?b.item(0):b.parentElement();return(d.ownerDocument||d)===a.document?b:null}var d=dom.Selection=function(a){var b,d=this;d.document=a,browser.ie9below&&(b=domUtils.getWindow(a).frameElement,domUtils.on(b,"beforedeactivate",function(){d._bakIERange=d.getIERange()}),domUtils.on(b,"activate",function(){try{!c(d)&&d._bakIERange&&d._bakIERange.select()}catch(a){}d._bakIERange=null})),b=a=null};d.prototype={rangeInBody:function(a,b){var c=browser.ie9below||b?a.item?a.item():a.parentElement():a.startContainer;return c===this.document.body||domUtils.inDoc(c,this.document)},getNative:function(){var a=this.document;try{return a?browser.ie9below?a.selection:domUtils.getWindow(a).getSelection():null}catch(b){return null}},getIERange:function(){var a=c(this);return!a&&this._bakIERange?this._bakIERange:a},cache:function(){this.clear(),this._cachedRange=this.getRange(),this._cachedStartElement=this.getStart(),this._cachedStartElementPath=this.getStartElementPath()},getStartElementPath:function(){if(this._cachedStartElementPath)return this._cachedStartElementPath;var a=this.getStart();return a?domUtils.findParents(a,!0,null,!0):[]},clear:function(){this._cachedStartElementPath=this._cachedRange=this._cachedStartElement=null},isFocus:function(){try{if(browser.ie9below){var a=c(this);return!(!a||!this.rangeInBody(a))}return!!this.getNative().rangeCount}catch(b){return!1}},getRange:function(){function a(a){for(var b=c.document.body.firstChild,d=a.collapsed;b&&b.firstChild;)a.setStart(b,0),b=b.firstChild;a.startContainer||a.setStart(c.document.body,0),d&&a.collapse(!0)}var c=this;if(null!=c._cachedRange)return this._cachedRange;var d=new baidu.editor.dom.Range(c.document);if(browser.ie9below){var e=c.getIERange();if(e)try{b(e,d)}catch(f){a(d)}else a(d)}else{var g=c.getNative();if(g&&g.rangeCount){var h=g.getRangeAt(0),i=g.getRangeAt(g.rangeCount-1);d.setStart(h.startContainer,h.startOffset).setEnd(i.endContainer,i.endOffset),d.collapsed&&domUtils.isBody(d.startContainer)&&!d.startOffset&&a(d)}else{if(this._bakRange&&domUtils.inDoc(this._bakRange.startContainer,this.document))return this._bakRange;a(d)}}return this._bakRange=d},getStart:function(){if(this._cachedStartElement)return this._cachedStartElement;var a,b,c,d,e=browser.ie9below?this.getIERange():this.getRange();if(browser.ie9below){if(!e)return this.document.body.firstChild;if(e.item)return e.item(0);for(a=e.duplicate(),a.text.length>0&&a.moveStart("character",1),a.collapse(1),b=a.parentElement(),d=c=e.parentElement();c=c.parentNode;)if(c==b){b=d;break}}else if(e.shrinkBoundary(),b=e.startContainer,1==b.nodeType&&b.hasChildNodes()&&(b=b.childNodes[Math.min(b.childNodes.length-1,e.startOffset)]),3==b.nodeType)return b.parentNode;return b},getText:function(){var a,b;return this.isFocus()&&(a=this.getNative())?(b=browser.ie9below?a.createRange():a.getRangeAt(0),browser.ie9below?b.text:b.toString()):""},clearRange:function(){this.getNative()[browser.ie9below?"empty":"removeAllRanges"]()}}}(),function(){function a(a,b){var c;if(b.textarea)if(utils.isString(b.textarea)){for(var d,e=0,f=domUtils.getElementsByTagName(a,"textarea");d=f[e++];)if(d.id=="ueditor_textarea_"+b.options.textarea){c=d;break}}else c=b.textarea;c||(a.appendChild(c=domUtils.createElement(document,"textarea",{name:b.options.textarea,id:"ueditor_textarea_"+b.options.textarea,style:"display:none"})),b.textarea=c),!c.getAttribute("name")&&c.setAttribute("name",b.options.textarea),c.value=b.hasContents()?b.options.allHtmlEnabled?b.getAllHtml():b.getContent(null,null,!0):""}function b(a){for(var b in a)return b}function c(a){a.langIsReady=!0,a.fireEvent("langReady")}var d,e=0,f=UE.Editor=function(a){var d=this;d.uid=e++,EventBase.call(d),d.commands={},d.options=utils.extend(utils.clone(a||{}),UEDITOR_CONFIG,!0),d.shortcutkeys={},d.inputRules=[],d.outputRules=[],d.setOpt(f.defaultOptions(d)),d.loadServerConfig(),utils.isEmptyObject(UE.I18N)?utils.loadFile(document,{src:d.options.langPath+d.options.lang+"/"+d.options.lang+".js",tag:"script",type:"text/javascript",defer:"defer"},function(){UE.plugin.load(d),c(d)}):(d.options.lang=b(UE.I18N),UE.plugin.load(d),c(d)),UE.instants["ueditorInstant"+d.uid]=d};f.prototype={registerCommand:function(a,b){this.commands[a]=b},ready:function(a){var b=this;a&&(b.isReady?a.apply(b):b.addListener("ready",a))},setOpt:function(a,b){var c={};utils.isString(a)?c[a]=b:c=a,utils.extend(this.options,c,!0)},getOpt:function(a){return this.options[a]},destroy:function(){var a=this;a.fireEvent("destroy");var b=a.container.parentNode,c=a.textarea;c?c.style.display="":(c=document.createElement("textarea"),b.parentNode.insertBefore(c,b)),c.style.width=a.iframe.offsetWidth+"px",c.style.height=a.iframe.offsetHeight+"px",c.value=a.getContent(),c.id=a.key,b.innerHTML="",domUtils.remove(b);var d=a.key;for(var e in a)a.hasOwnProperty(e)&&delete this[e];UE.delEditor(d)},render:function(a){var b=this,c=b.options,d=function(b){return parseInt(domUtils.getComputedStyle(a,b))};if(utils.isString(a)&&(a=document.getElementById(a)),a){c.initialFrameWidth?c.minFrameWidth=c.initialFrameWidth:c.minFrameWidth=c.initialFrameWidth=a.offsetWidth,c.initialFrameHeight?c.minFrameHeight=c.initialFrameHeight:c.initialFrameHeight=c.minFrameHeight=a.offsetHeight,a.style.width=/%$/.test(c.initialFrameWidth)?"100%":c.initialFrameWidth-d("padding-left")-d("padding-right")+"px",a.style.height=/%$/.test(c.initialFrameHeight)?"100%":c.initialFrameHeight-d("padding-top")-d("padding-bottom")+"px",a.style.zIndex=c.zIndex;var e=(ie&&browser.version<9?"":"")+""+(c.iframeCssUrl?"":"")+(c.initialStyle?"":"")+"";a.appendChild(domUtils.createElement(document,"iframe",{id:"ueditor_"+b.uid,width:"100%",height:"100%",frameborder:"0",src:"javascript:void(function(){document.open();"+(c.customDomain&&document.domain!=location.hostname?'document.domain="'+document.domain+'";':"")+'document.write("'+e+'");document.close();}())'})),a.style.overflow="hidden",setTimeout(function(){/%$/.test(c.initialFrameWidth)&&(c.minFrameWidth=c.initialFrameWidth=a.offsetWidth),/%$/.test(c.initialFrameHeight)&&(c.minFrameHeight=c.initialFrameHeight=a.offsetHeight,a.style.height=c.initialFrameHeight+"px")})}},_setup:function(b){var c=this,d=c.options;ie?(b.body.disabled=!0,b.body.contentEditable=!0,b.body.disabled=!1):b.body.contentEditable=!0,b.body.spellcheck=!1,c.document=b,c.window=b.defaultView||b.parentWindow,c.iframe=c.window.frameElement,c.body=b.body,c.selection=new dom.Selection(b);var e;browser.gecko&&(e=this.selection.getNative())&&e.removeAllRanges(),this._initEvents();for(var f=this.iframe.parentNode;!domUtils.isBody(f);f=f.parentNode)if("FORM"==f.tagName){c.form=f,c.options.autoSyncData?domUtils.on(c.window,"blur",function(){a(f,c)}):domUtils.on(f,"submit",function(){a(this,c)});break}if(d.initialContent)if(d.autoClearinitialContent){var g=c.execCommand;c.execCommand=function(){return c.fireEvent("firstBeforeExecCommand"),g.apply(c,arguments)},this._setDefaultContent(d.initialContent)}else this.setContent(d.initialContent,!1,!0);domUtils.isEmptyNode(c.body)&&(c.body.innerHTML="

      "+(browser.ie?"":"
      ")+"

      "),d.focus&&setTimeout(function(){c.focus(c.options.focusInEnd),!c.options.autoClearinitialContent&&c._selectionChange()},0),c.container||(c.container=this.iframe.parentNode),d.fullscreen&&c.ui&&c.ui.setFullScreen(!0);try{c.document.execCommand("2D-position",!1,!1)}catch(h){}try{c.document.execCommand("enableInlineTableEditing",!1,!1)}catch(h){}try{c.document.execCommand("enableObjectResizing",!1,!1)}catch(h){}c._bindshortcutKeys(),c.isReady=1,c.fireEvent("ready"),d.onready&&d.onready.call(c),browser.ie9below||domUtils.on(c.window,["blur","focus"],function(a){if("blur"==a.type){c._bakRange=c.selection.getRange();try{c._bakNativeRange=c.selection.getNative().getRangeAt(0),c.selection.getNative().removeAllRanges()}catch(a){c._bakNativeRange=null}}else try{c._bakRange&&c._bakRange.select()}catch(a){}}),browser.gecko&&browser.version<=10902&&(c.body.contentEditable=!1,setTimeout(function(){c.body.contentEditable=!0},100),setInterval(function(){c.body.style.height=c.iframe.offsetHeight-20+"px"},100)),!d.isShow&&c.setHide(),d.readonly&&c.setDisabled()},sync:function(b){var c=this,d=b?document.getElementById(b):domUtils.findParent(c.iframe.parentNode,function(a){return"FORM"==a.tagName},!0);d&&a(d,c)},setHeight:function(a,b){a!==parseInt(this.iframe.parentNode.style.height)&&(this.iframe.parentNode.style.height=a+"px"),!b&&(this.options.minFrameHeight=this.options.initialFrameHeight=a),this.body.style.height=a+"px",!b&&this.trigger("setHeight")},addshortcutkey:function(a,b){var c={};b?c[a]=b:c=a,utils.extend(this.shortcutkeys,c)},_bindshortcutKeys:function(){var a=this,b=this.shortcutkeys;a.addListener("keydown",function(c,d){var e=d.keyCode||d.which;for(var f in b)for(var g,h=b[f].split(","),i=0;g=h[i++];){g=g.split(":");var j=g[0],k=g[1];(/^(ctrl)(\+shift)?\+(\d+)$/.test(j.toLowerCase())||/^(\d+)$/.test(j))&&(("ctrl"==RegExp.$1?d.ctrlKey||d.metaKey:0)&&(""!=RegExp.$2?d[RegExp.$2.slice(1)+"Key"]:1)&&e==RegExp.$3||e==RegExp.$1)&&(a.queryCommandState(f,k)!=-1&&a.execCommand(f,k),domUtils.preventDefault(d))}})},getContent:function(a,b,c,d,e){var f=this;if(a&&utils.isFunction(a)&&(b=a,a=""),b?!b():!this.hasContents())return"";f.fireEvent("beforegetcontent");var g=UE.htmlparser(f.body.innerHTML,d);return f.filterOutputRule(g),f.fireEvent("aftergetcontent",a,g),g.toHtml(e)},getAllHtml:function(){var a=this,b=[];if(a.fireEvent("getAllHtml",b),browser.ie&&browser.version>8){var c="";utils.each(a.document.styleSheets,function(a){c+=a.href?'':""}),utils.each(a.document.getElementsByTagName("script"),function(a){c+=a.outerHTML})}return""+(a.options.charset?'':"")+(c||a.document.getElementsByTagName("head")[0].innerHTML)+b.join("\n")+""+a.getContent(null,null,!0)+""},getPlainTxt:function(){var a=new RegExp(domUtils.fillChar,"g"),b=this.body.innerHTML.replace(/[\n\r]/g,"");return b=b.replace(/<(p|div)[^>]*>(| )<\/\1>/gi,"\n").replace(//gi,"\n").replace(/<[^>\/]+>/g,"").replace(/(\n)?<\/([^>]+)>/g,function(a,b,c){return dtd.$block[c]?"\n":b?b:""}),b.replace(a,"").replace(/\u00a0/g," ").replace(/ /g," ")},getContentTxt:function(){var a=new RegExp(domUtils.fillChar,"g");return this.body[browser.ie?"innerText":"textContent"].replace(a,"").replace(/\u00a0/g," ")},setContent:function(b,c,d){function e(a){return"DIV"==a.tagName&&a.getAttribute("cdata_tag")}var f=this;f.fireEvent("beforesetcontent",b);var g=UE.htmlparser(b);if(f.filterInputRule(g),b=g.toHtml(),f.body.innerHTML=(c?f.body.innerHTML:"")+b,"p"==f.options.enterTag){var h,i=this.body.firstChild;if(!i||1==i.nodeType&&(dtd.$cdata[i.tagName]||e(i)||domUtils.isCustomeNode(i))&&i===this.body.lastChild)this.body.innerHTML="

      "+(browser.ie?" ":"
      ")+"

      "+this.body.innerHTML;else for(var j=f.document.createElement("p");i;){for(;i&&(3==i.nodeType||1==i.nodeType&&dtd.p[i.tagName]&&!dtd.$cdata[i.tagName]);)h=i.nextSibling,j.appendChild(i),i=h;if(j.firstChild){if(!i){f.body.appendChild(j);break}i.parentNode.insertBefore(j,i),j=f.document.createElement("p")}i=i.nextSibling}}f.fireEvent("aftersetcontent"),f.fireEvent("contentchange"),!d&&f._selectionChange(),f._bakRange=f._bakIERange=f._bakNativeRange=null;var k;browser.gecko&&(k=this.selection.getNative())&&k.removeAllRanges(),f.options.autoSyncData&&f.form&&a(f.form,f)},focus:function(a){try{var b=this,c=b.selection.getRange();if(a){var d=b.body.lastChild;d&&1==d.nodeType&&!dtd.$empty[d.tagName]&&(domUtils.isEmptyBlock(d)?c.setStartAtFirst(d):c.setStartAtLast(d),c.collapse(!0)),c.setCursor(!0)}else{if(!c.collapsed&&domUtils.isBody(c.startContainer)&&0==c.startOffset){var d=b.body.firstChild;d&&1==d.nodeType&&!dtd.$empty[d.tagName]&&c.setStartAtFirst(d).collapse(!0)}c.select(!0)}this.fireEvent("focus selectionchange")}catch(e){}},isFocus:function(){return this.selection.isFocus()},blur:function(){var a=this.selection.getNative();if(a.empty&&browser.ie){var b=document.body.createTextRange();b.moveToElementText(document.body),b.collapse(!0),b.select(),a.empty()}else a.removeAllRanges()},_initEvents:function(){var a=this,b=a.document,c=a.window;a._proxyDomEvent=utils.bind(a._proxyDomEvent,a),domUtils.on(b,["click","contextmenu","mousedown","keydown","keyup","keypress","mouseup","mouseover","mouseout","selectstart"],a._proxyDomEvent),domUtils.on(c,["focus","blur"],a._proxyDomEvent),domUtils.on(a.body,"drop",function(b){browser.gecko&&b.stopPropagation&&b.stopPropagation(),a.fireEvent("contentchange")}),domUtils.on(b,["mouseup","keydown"],function(b){"keydown"==b.type&&(b.ctrlKey||b.metaKey||b.shiftKey||b.altKey)||2!=b.button&&a._selectionChange(250,b)})},_proxyDomEvent:function(a){return this.fireEvent("before"+a.type.replace(/^on/,"").toLowerCase())!==!1&&(this.fireEvent(a.type.replace(/^on/,""),a)!==!1&&this.fireEvent("after"+a.type.replace(/^on/,"").toLowerCase()))},_selectionChange:function(a,b){var c,e,f=this,g=!1;if(browser.ie&&browser.version<9&&b&&"mouseup"==b.type){var h=this.selection.getRange();h.collapsed||(g=!0,c=b.clientX,e=b.clientY)}clearTimeout(d),d=setTimeout(function(){if(f.selection&&f.selection.getNative()){var a;if(g&&"None"==f.selection.getNative().type){a=f.document.body.createTextRange();try{a.moveToPoint(c,e)}catch(d){a=null}}var h;a&&(h=f.selection.getIERange,f.selection.getIERange=function(){return a}),f.selection.cache(),h&&(f.selection.getIERange=h),f.selection._cachedRange&&f.selection._cachedStartElement&&(f.fireEvent("beforeselectionchange"),f.fireEvent("selectionchange",!!b),f.fireEvent("afterselectionchange"),f.selection.clear())}},a||50)},_callCmdFn:function(a,b){var c,d,e=b[0].toLowerCase();return c=this.commands[e]||UE.commands[e],d=c&&c[a],c&&d||"queryCommandState"!=a?d?d.apply(this,b):void 0:0},execCommand:function(a){a=a.toLowerCase();var b,c=this,d=c.commands[a]||UE.commands[a];return d&&d.execCommand?(d.notNeedUndo||c.__hasEnterExecCommand?(b=this._callCmdFn("execCommand",arguments),!c.__hasEnterExecCommand&&!d.ignoreContentChange&&!c._ignoreContentChange&&c.fireEvent("contentchange")):(c.__hasEnterExecCommand=!0,c.queryCommandState.apply(c,arguments)!=-1&&(c.fireEvent("saveScene"),c.fireEvent.apply(c,["beforeexeccommand",a].concat(arguments)),b=this._callCmdFn("execCommand",arguments),c.fireEvent.apply(c,["afterexeccommand",a].concat(arguments)),c.fireEvent("saveScene")),c.__hasEnterExecCommand=!1),!c.__hasEnterExecCommand&&!d.ignoreContentChange&&!c._ignoreContentChange&&c._selectionChange(),b):null},queryCommandState:function(a){return this._callCmdFn("queryCommandState",arguments)},queryCommandValue:function(a){return this._callCmdFn("queryCommandValue",arguments)},hasContents:function(a){if(a)for(var b,c=0;b=a[c++];)if(this.document.getElementsByTagName(b).length>0)return!0;if(!domUtils.isEmptyBlock(this.body))return!0;for(a=["div"],c=0;b=a[c++];)for(var d,e=domUtils.getElementsByTagName(this.document,b),f=0;d=e[f++];)if(domUtils.isCustomeNode(d))return!0;return!1},reset:function(){this.fireEvent("reset")},setEnabled:function(){var a,b=this;if("false"==b.body.contentEditable){b.body.contentEditable=!0,a=b.selection.getRange();try{a.moveToBookmark(b.lastBk),delete b.lastBk}catch(c){a.setStartAtFirst(b.body).collapse(!0)}a.select(!0),b.bkqueryCommandState&&(b.queryCommandState=b.bkqueryCommandState,delete b.bkqueryCommandState),b.bkqueryCommandValue&&(b.queryCommandValue=b.bkqueryCommandValue,delete b.bkqueryCommandValue),b.fireEvent("selectionchange")}},enable:function(){return this.setEnabled()},setDisabled:function(a){var b=this;a=a?utils.isArray(a)?a:[a]:[],"true"==b.body.contentEditable&&(b.lastBk||(b.lastBk=b.selection.getRange().createBookmark(!0)),b.body.contentEditable=!1,b.bkqueryCommandState=b.queryCommandState,b.bkqueryCommandValue=b.queryCommandValue,b.queryCommandState=function(c){return utils.indexOf(a,c)!=-1?b.bkqueryCommandState.apply(b,arguments):-1},b.queryCommandValue=function(c){return utils.indexOf(a,c)!=-1?b.bkqueryCommandValue.apply(b,arguments):null},b.fireEvent("selectionchange"))},disable:function(a){return this.setDisabled(a)},_setDefaultContent:function(){function a(){var b=this;b.document.getElementById("initContent")&&(b.body.innerHTML="

      "+(ie?"":"
      ")+"

      ",b.removeListener("firstBeforeExecCommand focus",a),setTimeout(function(){b.focus(),b._selectionChange()},0))}return function(b){var c=this;c.body.innerHTML='

      '+b+"

      ",c.addListener("firstBeforeExecCommand focus",a)}}(),setShow:function(){var a=this,b=a.selection.getRange();if("none"==a.container.style.display){try{b.moveToBookmark(a.lastBk),delete a.lastBk}catch(c){b.setStartAtFirst(a.body).collapse(!0)}setTimeout(function(){b.select(!0)},100),a.container.style.display=""}},show:function(){return this.setShow()},setHide:function(){ +var a=this;a.lastBk||(a.lastBk=a.selection.getRange().createBookmark(!0)),a.container.style.display="none"},hide:function(){return this.setHide()},getLang:function(a){var b=UE.I18N[this.options.lang];if(!b)throw Error("not import language file");a=(a||"").split(".");for(var c,d=0;(c=a[d++])&&(b=b[c],b););return b},getContentLength:function(a,b){var c=this.getContent(!1,!1,!0).length;if(a){b=(b||[]).concat(["hr","img","iframe"]),c=this.getContentTxt().replace(/[\t\r\n]+/g,"").length;for(var d,e=0;d=b[e++];)c+=this.document.getElementsByTagName(d).length}return c},addInputRule:function(a){this.inputRules.push(a)},filterInputRule:function(a){for(var b,c=0;b=this.inputRules[c++];)b.call(this,a)},addOutputRule:function(a){this.outputRules.push(a)},filterOutputRule:function(a){for(var b,c=0;b=this.outputRules[c++];)b.call(this,a)},getActionUrl:function(a){var b=this.getOpt(a)||a,c=this.getOpt("imageUrl"),d=this.getOpt("serverUrl");return!d&&c&&(d=c.replace(/^(.*[\/]).+([\.].+)$/,"$1controller$2")),d?(d=d+(d.indexOf("?")==-1?"?":"&")+"action="+(b||""),utils.formatUrl(d)):""}},utils.inherits(f,EventBase)}(),UE.Editor.defaultOptions=function(a){var b=a.options.UEDITOR_HOME_URL;return{isShow:!0,initialContent:"",initialStyle:"",autoClearinitialContent:!1,iframeCssUrl:b+"themes/iframe.css",textarea:"editorValue",focus:!1,focusInEnd:!0,autoClearEmptyNode:!0,fullscreen:!1,readonly:!1,zIndex:999,imagePopup:!0,enterTag:"p",customDomain:!1,lang:"zh-cn",langPath:b+"lang/",theme:"default",themePath:b+"themes/",allHtmlEnabled:!1,scaleEnabled:!1,tableNativeEditInFF:!1,autoSyncData:!0,fileNameFormat:"{time}{rand:6}"}},function(){UE.Editor.prototype.loadServerConfig=function(){function showErrorMsg(a){console&&console.error(a)}var me=this;setTimeout(function(){try{me.options.imageUrl&&me.setOpt("serverUrl",me.options.imageUrl.replace(/^(.*[\/]).+([\.].+)$/,"$1controller$2"));var configUrl=me.getActionUrl("config"),isJsonp=utils.isCrossDomainUrl(configUrl);me._serverConfigLoaded=!1,configUrl&&UE.ajax.request(configUrl,{method:"GET",dataType:isJsonp?"jsonp":"",onsuccess:function(r){try{var config=isJsonp?r:eval("("+r.responseText+")");utils.extend(me.options,config),me.fireEvent("serverConfigLoaded"),me._serverConfigLoaded=!0}catch(e){showErrorMsg(me.getLang("loadconfigFormatError"))}},onerror:function(){showErrorMsg(me.getLang("loadconfigHttpError"))}})}catch(e){showErrorMsg(me.getLang("loadconfigError"))}})},UE.Editor.prototype.isServerConfigLoaded=function(){var a=this;return a._serverConfigLoaded||!1},UE.Editor.prototype.afterConfigReady=function(a){if(a&&utils.isFunction(a)){var b=this,c=function(){a.apply(b,arguments),b.removeListener("serverConfigLoaded",c)};b.isServerConfigLoaded()?a.call(b,"serverConfigLoaded"):b.addListener("serverConfigLoaded",c)}}}(),UE.ajax=function(){function a(a){var b=[];for(var c in a)if("method"!=c&&"timeout"!=c&&"async"!=c&&"dataType"!=c&&"callback"!=c&&void 0!=a[c]&&null!=a[c])if("function"!=(typeof a[c]).toLowerCase()&&"object"!=(typeof a[c]).toLowerCase())b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));else if(utils.isArray(a[c]))for(var d=0;d/gi,"").replace(/]*>[\s\S]*?.<\/v:shape>/gi,function(a){if(browser.opera)return"";try{if(/Bitmap/i.test(a))return"";var c=a.match(/width:([ \d.]*p[tx])/i)[1],d=a.match(/height:([ \d.]*p[tx])/i)[1],e=a.match(/src=\s*"([^"]*)"/i)[1];return''}catch(f){return""}}).replace(/<\/?div[^>]*>/g,"").replace(/v:\w+=(["']?)[^'"]+\1/g,"").replace(/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|xml|meta|link|style|\w+:\w+)(?=[\s\/>]))[^>]*>/gi,"").replace(/

      ]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi,"

      $1

      ").replace(/\s+(class|lang|align)\s*=\s*(['"]?)([\w-]+)\2/gi,function(a,b,c,d){return"class"==b&&"MsoListParagraph"==d?a:""}).replace(/<(font|span)[^>]*>(\s*)<\/\1>/gi,function(a,b,c){return c.replace(/[\t\r\n ]+/g," ")}).replace(/(<[a-z][^>]*)\sstyle=(["'])([^\2]*?)\2/gi,function(a,c,d,e){for(var f,g=[],h=e.replace(/^\s+|\s+$/,"").replace(/'/g,"'").replace(/"/gi,"'").replace(/[\d.]+(cm|pt)/g,function(a){return utils.transUnitToPx(a)}).split(/;\s*/g),i=0;f=h[i];i++){var j,k,l=f.split(":");if(2==l.length){if(j=l[0].toLowerCase(),k=l[1].toLowerCase(),/^(background)\w*/.test(j)&&0==k.replace(/(initial|\s)/g,"").length||/^(margin)\w*/.test(j)&&/^0\w+$/.test(k))continue;switch(j){case"mso-padding-alt":case"mso-padding-top-alt":case"mso-padding-right-alt":case"mso-padding-bottom-alt":case"mso-padding-left-alt":case"mso-margin-alt":case"mso-margin-top-alt":case"mso-margin-right-alt":case"mso-margin-bottom-alt":case"mso-margin-left-alt":case"mso-height":case"mso-width":case"mso-vertical-align-alt":/1&&(a(h,j,!0),b(h,j)),c(k,h,i,j);break;case"text":d(g,h);break;case"element":e(g,h,i,j);break;case"comment":f(g,h,i)}return h}function d(a,b){"pre"==a.parentNode.tagName?b.push(a.data):b.push(l[a.parentNode.tagName]?utils.html(a.data):a.data.replace(/[ ]{2}/g,"  "))}function e(d,e,f,g){var h="";if(d.attrs){h=[];var i=d.attrs;for(var j in i)h.push(j+(void 0!==i[j]?'="'+(k[j]?utils.html(i[j]).replace(/["]/g,function(a){return"""}):utils.unhtml(i[j]))+'"':""));h=h.join(" ")}if(e.push("<"+d.tagName+(h?" "+h:"")+(dtd.$empty[d.tagName]?"/":"")+">"),f&&!dtd.$inlineWithA[d.tagName]&&"pre"!=d.tagName&&d.children&&d.children.length&&(g=a(e,g,!0),b(e,g)),d.children&&d.children.length)for(var l,m=0;l=d.children[m++];)f&&"element"==l.type&&!dtd.$inlineWithA[l.tagName]&&m>1&&(a(e,g),b(e,g)),c(l,e,f,g);dtd.$empty[d.tagName]||(f&&!dtd.$inlineWithA[d.tagName]&&"pre"!=d.tagName&&d.children&&d.children.length&&(g=a(e,g),b(e,g)),e.push(""))}function f(a,b){b.push("")}function g(a,b){var c;if("element"==a.type&&a.getAttr("id")==b)return a;if(a.children&&a.children.length)for(var d,e=0;d=a.children[e++];)if(c=g(d,b))return c}function h(a,b,c){if("element"==a.type&&a.tagName==b&&c.push(a),a.children&&a.children.length)for(var d,e=0;d=a.children[e++];)h(d,b,c)}function i(a,b){if(a.children&&a.children.length)for(var c,d=0;c=a.children[d];)i(c,b),c.parentNode&&(c.children&&c.children.length&&b(c),c.parentNode&&d++);else b(a)}var j=UE.uNode=function(a){this.type=a.type,this.data=a.data,this.tagName=a.tagName,this.parentNode=a.parentNode,this.attrs=a.attrs||{},this.children=a.children},k={href:1,src:1,_src:1,_href:1,cdata_data:1},l={style:1,script:1},m=" ",n="\n";j.createElement=function(a){return/[<>]/.test(a)?UE.htmlparser(a).children[0]:new j({type:"element",children:[],tagName:a})},j.createText=function(a,b){return new UE.uNode({type:"text",data:b?a:utils.unhtml(a||"")})},j.prototype={toHtml:function(a){var b=[];return c(this,b,a,0),b.join("")},innerHTML:function(a){if("element"!=this.type||dtd.$empty[this.tagName])return this;if(utils.isString(a)){if(this.children)for(var b,c=0;b=this.children[c++];)b.parentNode=null;this.children=[];for(var b,d=UE.htmlparser(a),c=0;b=d.children[c++];)this.children.push(b),b.parentNode=this;return this}var d=new UE.uNode({type:"root",children:this.children});return d.toHtml()},innerText:function(a,b){if("element"!=this.type||dtd.$empty[this.tagName])return this;if(a){if(this.children)for(var c,d=0;c=this.children[d++];)c.parentNode=null;return this.children=[],this.appendChild(j.createText(a,b)),this}return this.toHtml().replace(/<[^>]+>/g,"")},getData:function(){return"element"==this.type?"":this.data},firstChild:function(){return this.children?this.children[0]:null},lastChild:function(){return this.children?this.children[this.children.length-1]:null},previousSibling:function(){for(var a,b=this.parentNode,c=0;a=b.children[c];c++)if(a===this)return 0==c?null:b.children[c-1]},nextSibling:function(){for(var a,b=this.parentNode,c=0;a=b.children[c++];)if(a===this)return b.children[c]},replaceChild:function(a,b){if(this.children){a.parentNode&&a.parentNode.removeChild(a);for(var c,d=0;c=this.children[d];d++)if(c===b)return this.children.splice(d,1,a),b.parentNode=null,a.parentNode=this,a}},appendChild:function(a){if("root"==this.type||"element"==this.type&&!dtd.$empty[this.tagName]){this.children||(this.children=[]),a.parentNode&&a.parentNode.removeChild(a);for(var b,c=0;b=this.children[c];c++)if(b===a){this.children.splice(c,1);break}return this.children.push(a),a.parentNode=this,a}},insertBefore:function(a,b){if(this.children){a.parentNode&&a.parentNode.removeChild(a);for(var c,d=0;c=this.children[d];d++)if(c===b)return this.children.splice(d,0,a),a.parentNode=this,a}},insertAfter:function(a,b){if(this.children){a.parentNode&&a.parentNode.removeChild(a);for(var c,d=0;c=this.children[d];d++)if(c===b)return this.children.splice(d+1,0,a),a.parentNode=this,a}},removeChild:function(a,b){if(this.children)for(var c,d=0;c=this.children[d];d++)if(c===a){if(this.children.splice(d,1),c.parentNode=null,b&&c.children&&c.children.length)for(var e,f=0;e=c.children[f];f++)this.children.splice(d+f,0,e),e.parentNode=this;return c}},getAttr:function(a){return this.attrs&&this.attrs[a.toLowerCase()]},setAttr:function(a,b){if(!a)return void delete this.attrs;if(this.attrs||(this.attrs={}),utils.isObject(a))for(var c in a)a[c]?this.attrs[c.toLowerCase()]=a[c]:delete this.attrs[c];else b?this.attrs[a.toLowerCase()]=b:delete this.attrs[a]},getIndex:function(){for(var a,b=this.parentNode,c=0;a=b.children[c];c++)if(a===this)return c;return-1},getNodeById:function(a){var b;if(this.children&&this.children.length)for(var c,d=0;c=this.children[d++];)if(b=g(c,a))return b},getNodesByTagName:function(a){a=utils.trim(a).replace(/[ ]{2,}/g," ").split(" ");var b=[],c=this;return utils.each(a,function(a){if(c.children&&c.children.length)for(var d,e=0;d=c.children[e++];)h(d,a,b)}),b},getStyle:function(a){var b=this.getAttr("style");if(!b)return"";var c=new RegExp("(^|;)\\s*"+a+":([^;]+)","i"),d=b.match(c);return d&&d[0]?d[2]:""},setStyle:function(a,b){function c(a,b){var c=new RegExp("(^|;)\\s*"+a+":([^;]+;?)","gi");d=d.replace(c,"$1"),b&&(d=a+":"+utils.unhtml(b)+";"+d)}var d=this.getAttr("style");if(d||(d=""),utils.isObject(a))for(var e in a)c(e,a[e]);else c(a,b);this.setAttr("style",utils.trim(d))},traversal:function(a){return this.children&&this.children.length&&i(this,a),this}}}();var htmlparser=UE.htmlparser=function(a,b){function c(a,b){if(m[a.tagName]){var c=k.createElement(m[a.tagName]);a.appendChild(c),c.appendChild(k.createText(b)),a=c}else a.appendChild(k.createText(b))}function d(a,b,c){var e;if(e=l[b]){for(var f,h=a;"root"!=h.type;){if(utils.isArray(e)?utils.indexOf(e,h.tagName)!=-1:e==h.tagName){a=h,f=!0;break}h=h.parentNode}f||(a=d(a,utils.isArray(e)?e[0]:e))}var i=new k({parentNode:a,type:"element",tagName:b.toLowerCase(),children:dtd.$empty[b]?null:[]});if(c){for(var m,n={};m=g.exec(c);)n[m[1].toLowerCase()]=j[m[1].toLowerCase()]?m[2]||m[3]||m[4]:utils.unhtml(m[2]||m[3]||m[4]);i.attrs=n}return a.children.push(i),dtd.$empty[b]?a:i}function e(a,b){a.children.push(new k({type:"comment",data:b,parentNode:a}))}var f=/<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\s\/<>]+)\s*((?:(?:"[^"]*")|(?:'[^']*')|[^"'<>])*)\/?>))/g,g=/([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g,h={b:1,code:1,i:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,span:1,sub:1,img:1,sup:1,font:1,big:1,small:1,iframe:1,a:1,br:1,pre:1};a=a.replace(new RegExp(domUtils.fillChar,"g"),""),b||(a=a.replace(new RegExp("[\\r\\t\\n"+(b?"":" ")+"]*]*)>[\\r\\t\\n"+(b?"":" ")+"]*","g"),function(a,c){return c&&h[c.toLowerCase()]?a.replace(/(^[\n\r]+)|([\n\r]+$)/g,""):a.replace(new RegExp("^[\\r\\n"+(b?"":" ")+"]+"),"").replace(new RegExp("[\\r\\n"+(b?"":" ")+"]+$"),"")}));for(var i,j={href:1,src:1},k=UE.uNode,l={td:"tr",tr:["tbody","thead","tfoot"],tbody:"table",th:"tr",thead:"table",tfoot:"table",caption:"table",li:["ul","ol"],dt:"dl",dd:"dl",option:"select"},m={ol:"li",ul:"li"},n=0,o=0,p=new k({type:"root",children:[]}),q=p;i=f.exec(a);){n=i.index;try{if(n>o&&c(q,a.slice(o,n)),i[3])dtd.$cdata[q.tagName]?c(q,i[0]):q=d(q,i[3].toLowerCase(),i[4]);else if(i[1]){if("root"!=q.type)if(dtd.$cdata[q.tagName]&&!dtd.$cdata[i[1]])c(q,i[0]);else{for(var r=q;"element"==q.type&&q.tagName!=i[1].toLowerCase();)if(q=q.parentNode,"root"==q.type)throw q=r,"break";q=q.parentNode}}else i[2]&&e(q,i[2])}catch(s){}o=f.lastIndex}return o");break;case"div":if(b.getAttr("cdata_tag"))break;if(d=b.getAttr("class"),d&&/^line number\d+/.test(d))break;if(!e)break;for(var f,g=UE.uNode.createElement("p");f=b.firstChild();)"text"!=f.type&&UE.dom.dtd.$block[f.tagName]?g.firstChild()?(b.parentNode.insertBefore(g,b),g=UE.uNode.createElement("p")):b.parentNode.insertBefore(f,b):g.appendChild(f);g.firstChild()&&b.parentNode.insertBefore(g,b),b.parentNode.removeChild(b);break;case"dl":b.tagName="ul";break;case"dt":case"dd":b.tagName="li";break;case"li":var h=b.getAttr("class");h&&/list\-/.test(h)||b.setAttr();var i=b.getNodesByTagName("ol ul");UE.utils.each(i,function(a){b.parentNode.insertAfter(a,b)});break;case"td":case"th":case"caption":b.children&&b.children.length||b.appendChild(browser.ie11below?UE.uNode.createText(" "):UE.uNode.createElement("br"));break;case"table":a.options.disabledTableInTable&&c(b)&&(b.parentNode.insertBefore(UE.uNode.createText(b.innerText()),b),b.parentNode.removeChild(b))}}})}),a.addOutputRule(function(b){var c;b.traversal(function(b){if("element"==b.type){if(a.options.autoClearEmptyNode&&dtd.$inline[b.tagName]&&!dtd.$empty[b.tagName]&&(!b.attrs||utils.isEmptyObject(b.attrs)))return void(b.firstChild()?"span"!=b.tagName||b.attrs&&!utils.isEmptyObject(b.attrs)||b.parentNode.removeChild(b,!0):b.parentNode.removeChild(b));switch(b.tagName){case"div":(c=b.getAttr("cdata_tag"))&&(b.tagName=c,b.appendChild(UE.uNode.createText(b.getAttr("cdata_data"))),b.setAttr({cdata_tag:"",cdata_data:"",_ue_custom_node_:""}));break;case"a":(c=b.getAttr("_href"))&&b.setAttr({href:utils.html(c),_href:""});break;case"span":c=b.getAttr("id"),c&&/^_baidu_bookmark_/i.test(c)&&b.parentNode.removeChild(b);break;case"img":(c=b.getAttr("_src"))&&b.setAttr({src:b.getAttr("_src"),_src:""})}}})})},UE.commands.inserthtml={execCommand:function(a,b,c){var d,e,f=this;if(b&&f.fireEvent("beforeinserthtml",b)!==!0){if(d=f.selection.getRange(),e=d.document.createElement("div"),e.style.display="inline",!c){var g=UE.htmlparser(b);f.options.filterRules&&UE.filterNode(g,f.options.filterRules),f.filterInputRule(g),b=g.toHtml()}if(e.innerHTML=utils.trim(b),!d.collapsed){var h=d.startContainer;if(domUtils.isFillChar(h)&&d.setStartBefore(h),h=d.endContainer,domUtils.isFillChar(h)&&d.setEndAfter(h),d.txtToElmBoundary(),d.endContainer&&1==d.endContainer.nodeType&&(h=d.endContainer.childNodes[d.endOffset],h&&domUtils.isBr(h)&&d.setEndAfter(h)),0==d.startOffset&&(h=d.startContainer,domUtils.isBoundaryNode(h,"firstChild")&&(h=d.endContainer,d.endOffset==(3==h.nodeType?h.nodeValue.length:h.childNodes.length)&&domUtils.isBoundaryNode(h,"lastChild")&&(f.body.innerHTML="

      "+(browser.ie?"":"
      ")+"

      ",d.setStart(f.body.firstChild,0).collapse(!0)))),!d.collapsed&&d.deleteContents(),1==d.startContainer.nodeType){var i,j=d.startContainer.childNodes[d.startOffset];if(j&&domUtils.isBlockElm(j)&&(i=j.previousSibling)&&domUtils.isBlockElm(i)){for(d.setEnd(i,i.childNodes.length).collapse();j.firstChild;)i.appendChild(j.firstChild);domUtils.remove(j)}}}var j,k,i,l,m,n=0;d.inFillChar()&&(j=d.startContainer,domUtils.isFillChar(j)?(d.setStartBefore(j).collapse(!0),domUtils.remove(j)):domUtils.isFillChar(j,!0)&&(j.nodeValue=j.nodeValue.replace(fillCharReg,""),d.startOffset--,d.collapsed&&d.collapse(!0)));var o=domUtils.findParentByTagName(d.startContainer,"li",!0);if(o){for(var p,q;j=e.firstChild;){for(;j&&(3==j.nodeType||!domUtils.isBlockElm(j)||"HR"==j.tagName);)p=j.nextSibling,d.insertNode(j).collapse(),q=j,j=p;if(j)if(/^(ol|ul)$/i.test(j.tagName)){for(;j.firstChild;)q=j.firstChild,domUtils.insertAfter(o,j.firstChild),o=o.nextSibling;domUtils.remove(j)}else{var r;p=j.nextSibling,r=f.document.createElement("li"),domUtils.insertAfter(o,r),r.appendChild(j),q=j,j=p,o=r}}o=domUtils.findParentByTagName(d.startContainer,"li",!0),domUtils.isEmptyBlock(o)&&domUtils.remove(o),q&&d.setStartAfter(q).collapse(!0).select(!0)}else{for(;j=e.firstChild;){if(n){for(var s=f.document.createElement("p");j&&(3==j.nodeType||!dtd.$block[j.tagName]);)m=j.nextSibling,s.appendChild(j),j=m;s.firstChild&&(j=s)}if(d.insertNode(j),m=j.nextSibling,!n&&j.nodeType==domUtils.NODE_ELEMENT&&domUtils.isBlockElm(j)&&(k=domUtils.findParent(j,function(a){return domUtils.isBlockElm(a)}),k&&"body"!=k.tagName.toLowerCase()&&(!dtd[k.tagName][j.nodeName]||j.parentNode!==k))){if(dtd[k.tagName][j.nodeName])for(l=j.parentNode;l!==k;)i=l,l=l.parentNode;else i=k;domUtils.breakParent(j,i||l);var i=j.previousSibling;domUtils.trimWhiteTextNode(i),i.childNodes.length||domUtils.remove(i),!browser.ie&&(p=j.nextSibling)&&domUtils.isBlockElm(p)&&p.lastChild&&!domUtils.isBr(p.lastChild)&&p.appendChild(f.document.createElement("br")),n=1}var p=j.nextSibling;if(!e.firstChild&&p&&domUtils.isBlockElm(p)){d.setStart(p,0).collapse(!0);break}d.setEndAfter(j).collapse()}if(j=d.startContainer,m&&domUtils.isBr(m)&&domUtils.remove(m),domUtils.isBlockElm(j)&&domUtils.isEmptyNode(j))if(m=j.nextSibling)domUtils.remove(j),1==m.nodeType&&dtd.$block[m.tagName]&&d.setStart(m,0).collapse(!0).shrinkBoundary();else try{j.innerHTML=browser.ie?domUtils.fillChar:"
      "}catch(t){d.setStartBefore(j),domUtils.remove(j)}try{d.select(!0)}catch(t){}}setTimeout(function(){d=f.selection.getRange(),d.scrollToView(f.autoHeightEnabled,f.autoHeightEnabled?domUtils.getXY(f.iframe).y:0),f.fireEvent("afterinserthtml",b)},200)}}},UE.plugins.autotypeset=function(){function a(a,b){return a&&3!=a.nodeType?domUtils.isBr(a)?1:a&&a.parentNode&&l[a.tagName.toLowerCase()]?g&&g.contains(a)||a.getAttribute("pagebreak")?0:b?!domUtils.isEmptyBlock(a):domUtils.isEmptyBlock(a,new RegExp("[\\s"+domUtils.fillChar+"]","g")):void 0:0}function b(a){a.style.cssText||(domUtils.removeAttributes(a,["style"]),"span"==a.tagName.toLowerCase()&&domUtils.hasNoAttributes(a)&&domUtils.remove(a,!0))}function c(c,f){var h,l=this;if(f){if(!i.pasteFilter)return;h=l.document.createElement("div"),h.innerHTML=f.html}else h=l.document.body;for(var m,n=domUtils.getElementsByTagName(h,"*"),o=0;m=n[o++];)if(l.fireEvent("excludeNodeinautotype",m)!==!0){if(i.clearFontSize&&m.style.fontSize&&(domUtils.removeStyle(m,"font-size"),b(m)),i.clearFontFamily&&m.style.fontFamily&&(domUtils.removeStyle(m,"font-family"),b(m)),a(m)){if(i.mergeEmptyline)for(var p,q=m.nextSibling,r=domUtils.isBr(m);a(q)&&(p=q,q=p.nextSibling,!r||q&&(!q||domUtils.isBr(q)));)domUtils.remove(p);if(i.removeEmptyline&&domUtils.inDoc(m,h)&&!k[m.parentNode.tagName.toLowerCase()]){if(domUtils.isBr(m)&&(q=m.nextSibling,q&&!domUtils.isBr(q)))continue;domUtils.remove(m);continue}}if(a(m,!0)&&"SPAN"!=m.tagName&&(i.indent&&(m.style.textIndent=i.indentValue),i.textAlign&&(m.style.textAlign=i.textAlign)),i.removeClass&&m.className&&!j[m.className.toLowerCase()]){if(g&&g.contains(m))continue;domUtils.removeAttributes(m,["class"])}if(i.imageBlockLine&&"img"==m.tagName.toLowerCase()&&!m.getAttribute("emotion"))if(f){var s=m;switch(i.imageBlockLine){case"left":case"right":case"none":for(var p,t,q,u=s.parentNode;dtd.$inline[u.tagName]||"A"==u.tagName;)u=u.parentNode;if(p=u,"P"==p.tagName&&"center"==domUtils.getStyle(p,"text-align")&&!domUtils.isBody(p)&&1==domUtils.getChildCount(p,function(a){return!domUtils.isBr(a)&&!domUtils.isWhitespace(a)}))if(t=p.previousSibling,q=p.nextSibling,t&&q&&1==t.nodeType&&1==q.nodeType&&t.tagName==q.tagName&&domUtils.isBlockElm(t)){for(t.appendChild(p.firstChild);q.firstChild;)t.appendChild(q.firstChild);domUtils.remove(p),domUtils.remove(q)}else domUtils.setStyle(p,"text-align","");domUtils.setStyle(s,"float",i.imageBlockLine);break;case"center":if("center"!=l.queryCommandValue("imagefloat")){for(u=s.parentNode,domUtils.setStyle(s,"float","none"),p=s;u&&1==domUtils.getChildCount(u,function(a){return!domUtils.isBr(a)&&!domUtils.isWhitespace(a)})&&(dtd.$inline[u.tagName]||"A"==u.tagName);)p=u,u=u.parentNode;var v=l.document.createElement("p");domUtils.setAttributes(v,{style:"text-align:center"}),p.parentNode.insertBefore(v,p),v.appendChild(p),domUtils.setStyle(p,"float","")}}}else{var w=l.selection.getRange();w.selectNode(m).select(),l.execCommand("imagefloat",i.imageBlockLine)}i.removeEmptyNode&&i.removeTagNames[m.tagName.toLowerCase()]&&domUtils.hasNoAttributes(m)&&domUtils.isEmptyBlock(m)&&domUtils.remove(m)}if(i.tobdc){var x=UE.htmlparser(h.innerHTML);x.traversal(function(a){"text"==a.type&&(a.data=e(a.data))}),h.innerHTML=x.toHtml()}if(i.bdc2sb){var x=UE.htmlparser(h.innerHTML);x.traversal(function(a){"text"==a.type&&(a.data=d(a.data))}),h.innerHTML=x.toHtml()}f&&(f.html=h.innerHTML)}function d(a){for(var b="",c=0;c=65281&&d<=65373?String.fromCharCode(a.charCodeAt(c)-65248):12288==d?String.fromCharCode(a.charCodeAt(c)-12288+32):a.charAt(c)}return b}function e(a){a=utils.html(a);for(var b="",c=0;c0?e.substring(e.indexOf(d.options.imagePath),e.length-1).replace(/"|\(|\)/gi,""):"none"!=e?e.replace(/url\("?|"?\)/gi,""):"";var g=' ",b.push(g)},aftersetcontent:function(){0==c&&b()}},inputRule:function(d){c=!1,utils.each(d.getNodesByTagName("p"),function(d){var e=d.getAttr("data-background");e&&(c=!0,b(a(e)),d.parentNode.removeChild(d))})},outputRule:function(a){var b=this,c=(utils.cssRule(e,b.document)||"").replace(/[\n\r]+/g,"").match(f);c&&a.appendChild(UE.uNode.createElement('


      '))},commands:{background:{execCommand:function(a,c){b(c)},queryCommandValue:function(){var b=this,c=(utils.cssRule(e,b.document)||"").replace(/[\n\r]+/g,"").match(f);return c?a(c[1]):null},notNeedUndo:!0}}}}),UE.commands.imagefloat={execCommand:function(a,b){var c=this,d=c.selection.getRange();if(!d.collapsed){var e=d.getClosedNode();if(e&&"IMG"==e.tagName)switch(b){case"left":case"right":case"none":for(var f,g,h,i=e.parentNode;dtd.$inline[i.tagName]||"A"==i.tagName;)i=i.parentNode;if(f=i,"P"==f.tagName&&"center"==domUtils.getStyle(f,"text-align")){if(!domUtils.isBody(f)&&1==domUtils.getChildCount(f,function(a){return!domUtils.isBr(a)&&!domUtils.isWhitespace(a)}))if(g=f.previousSibling,h=f.nextSibling,g&&h&&1==g.nodeType&&1==h.nodeType&&g.tagName==h.tagName&&domUtils.isBlockElm(g)){for(g.appendChild(f.firstChild);h.firstChild;)g.appendChild(h.firstChild);domUtils.remove(f),domUtils.remove(h)}else domUtils.setStyle(f,"text-align","");d.selectNode(e).select()}domUtils.setStyle(e,"float","none"==b?"":b),"none"==b&&domUtils.removeAttributes(e,"align");break;case"center":if("center"!=c.queryCommandValue("imagefloat")){for(i=e.parentNode,domUtils.setStyle(e,"float",""),domUtils.removeAttributes(e,"align"),f=e;i&&1==domUtils.getChildCount(i,function(a){return!domUtils.isBr(a)&&!domUtils.isWhitespace(a)})&&(dtd.$inline[i.tagName]||"A"==i.tagName);)f=i,i=i.parentNode;d.setStartBefore(f).setCursor(!1),i=c.document.createElement("div"),i.appendChild(f),domUtils.setStyle(f,"float",""),c.execCommand("insertHtml",'

      '+i.innerHTML+"

      "),f=c.document.getElementById("_img_parent_tmp"),f.removeAttribute("id"),f=f.firstChild,d.selectNode(f).select(),h=f.parentNode.nextSibling,h&&domUtils.isEmptyNode(h)&&domUtils.remove(h)}}}},queryCommandValue:function(){var a,b,c=this.selection.getRange();return c.collapsed?"none":(a=c.getClosedNode(),a&&1==a.nodeType&&"IMG"==a.tagName?(b=domUtils.getComputedStyle(a,"float")||a.getAttribute("align"),"none"==b&&(b="center"==domUtils.getComputedStyle(a.parentNode,"text-align")?"center":b),{left:1,right:1,center:1}[b]?b:"none"):"none")},queryCommandState:function(){var a,b=this.selection.getRange();return b.collapsed?-1:(a=b.getClosedNode(),a&&1==a.nodeType&&"IMG"==a.tagName?0:-1)}},UE.commands.insertimage={execCommand:function(a,b){function c(a){utils.each("width,height,border,hspace,vspace".split(","),function(b){a[b]&&(a[b]=parseInt(a[b],10)||0)}),utils.each("src,_src".split(","),function(b){a[b]&&(a[b]=utils.unhtmlForUrl(a[b]))}),utils.each("title,alt".split(","),function(b){a[b]&&(a[b]=utils.unhtml(a[b]))})}if(b=utils.isArray(b)?b:[b],b.length){var d=this,e=d.selection.getRange(),f=e.getClosedNode();if(d.fireEvent("beforeinsertimage",b)!==!0){if(!f||!/img/i.test(f.tagName)||"edui-faked-video"==f.className&&f.className.indexOf("edui-upload-video")==-1||f.getAttribute("word_img")){var g,h=[],i="";if(g=b[0],1==b.length)c(g),i=''+g.alt+'","center"==g.floatStyle&&(i='

      '+i+"

      "),h.push(i);else for(var j=0;g=b[j++];)c(g),i="

      ",h.push(i);d.execCommand("insertHtml",h.join(""))}else{var k=b.shift(),l=k.floatStyle;delete k.floatStyle,domUtils.setAttributes(f,k),d.execCommand("imagefloat",l),b.length>0&&(e.setStartAfter(f).setCursor(!1,!0),d.execCommand("insertimage",b))}d.fireEvent("afterinsertimage",b)}}}},UE.plugins.justify=function(){var a=domUtils.isBlockElm,b={left:1,right:1,center:1,justify:1},c=function(b,c){var d=b.createBookmark(),e=function(a){return 1==a.nodeType?"br"!=a.tagName.toLowerCase()&&!domUtils.isBookmarkNode(a):!domUtils.isWhitespace(a)};b.enlarge(!0);for(var f,g=b.createBookmark(),h=domUtils.getNextDomNode(g.start,!1,e),i=b.cloneRange();h&&!(domUtils.getPosition(h,g.end)&domUtils.POSITION_FOLLOWING);)if(3!=h.nodeType&&a(h))h=domUtils.getNextDomNode(h,!0,e);else{for(i.setStartBefore(h);h&&h!==g.end&&!a(h);)f=h,h=domUtils.getNextDomNode(h,!1,null,function(b){return!a(b)});i.setEndAfter(f);var j=i.getCommonAncestor();if(!domUtils.isBody(j)&&a(j))domUtils.setStyles(j,utils.isString(c)?{"text-align":c}:c),h=j;else{var k=b.document.createElement("p");domUtils.setStyles(k,utils.isString(c)?{"text-align":c}:c);var l=i.extractContents();k.appendChild(l),i.insertNode(k),h=k}h=domUtils.getNextDomNode(h,!1,e)}return b.moveToBookmark(g).moveToBookmark(d)};UE.commands.justify={execCommand:function(a,b){var d,e=this.selection.getRange();return e.collapsed&&(d=this.document.createTextNode("p"),e.insertNode(d)),c(e,b),d&&(e.setStartBefore(d).collapse(!0),domUtils.remove(d)),e.select(),!0},queryCommandValue:function(){var a=this.selection.getStart(),c=domUtils.getComputedStyle(a,"text-align");return b[c]?c:"left"},queryCommandState:function(){var a=this.selection.getStart(),b=a&&domUtils.findParentByTagName(a,["td","th","caption"],!0);return b?-1:0}}},UE.plugins.font=function(){function a(a){for(var b;(b=a.parentNode)&&"SPAN"==b.tagName&&1==domUtils.getChildCount(b,function(a){return!domUtils.isBookmarkNode(a)&&!domUtils.isBr(a)});)b.style.cssText+=a.style.cssText,domUtils.remove(a,!0),a=b}function b(a,b,c){if(g[b]&&(a.adjustmentBoundary(),!a.collapsed&&1==a.startContainer.nodeType)){var d=a.startContainer.childNodes[a.startOffset];if(d&&domUtils.isTagNode(d,"span")){var e=a.createBookmark();utils.each(domUtils.getElementsByTagName(d,"span"),function(a){a.parentNode&&!domUtils.isBookmarkNode(a)&&("backcolor"==b&&domUtils.getComputedStyle(a,"background-color").toLowerCase()===c||(domUtils.removeStyle(a,g[b]),0==a.style.cssText.replace(/^\s+$/,"").length&&domUtils.remove(a,!0)))}),a.moveToBookmark(e)}}}function c(c,d,e){var f,g=c.collapsed,h=c.createBookmark();if(g)for(f=h.start.parentNode;dtd.$inline[f.tagName];)f=f.parentNode;else f=domUtils.getCommonAncestor(h.start,h.end);utils.each(domUtils.getElementsByTagName(f,"span"),function(b){if(b.parentNode&&!domUtils.isBookmarkNode(b)){if(/\s*border\s*:\s*none;?\s*/i.test(b.style.cssText))return void(/^\s*border\s*:\s*none;?\s*$/.test(b.style.cssText)?domUtils.remove(b,!0):domUtils.removeStyle(b,"border"));if(/border/i.test(b.style.cssText)&&"SPAN"==b.parentNode.tagName&&/border/i.test(b.parentNode.style.cssText)&&(b.style.cssText=b.style.cssText.replace(/border[^:]*:[^;]+;?/gi,"")),"fontborder"!=d||"none"!=e)for(var c=b.nextSibling;c&&1==c.nodeType&&"SPAN"==c.tagName;)if(domUtils.isBookmarkNode(c)&&"fontborder"==d)b.appendChild(c),c=b.nextSibling;else{if(c.style.cssText==b.style.cssText&&(domUtils.moveChild(c,b),domUtils.remove(c)),b.nextSibling===c)break;c=b.nextSibling}if(a(b),browser.ie&&browser.version>8){var f=domUtils.findParent(b,function(a){return"SPAN"==a.tagName&&/background-color/.test(a.style.cssText)});f&&!/background-color/.test(b.style.cssText)&&(b.style.backgroundColor=f.style.backgroundColor)}}}),c.moveToBookmark(h),b(c,d,e)}var d=this,e={forecolor:"color",backcolor:"background-color",fontsize:"font-size",fontfamily:"font-family",underline:"text-decoration",strikethrough:"text-decoration",fontborder:"border"},f={underline:1,strikethrough:1,fontborder:1},g={forecolor:"color",backcolor:"background-color",fontsize:"font-size",fontfamily:"font-family"};d.setOpt({fontfamily:[{name:"songti",val:"宋体,SimSun"},{name:"yahei",val:"微软雅黑,Microsoft YaHei"},{name:"kaiti",val:"楷体,楷体_GB2312, SimKai"},{name:"heiti",val:"黑体, SimHei"},{name:"lishu",val:"隶书, SimLi"},{name:"andaleMono",val:"andale mono"},{name:"arial",val:"arial, helvetica,sans-serif"},{name:"arialBlack",val:"arial black,avant garde"},{name:"comicSansMs",val:"comic sans ms"},{name:"impact",val:"impact,chicago"},{name:"timesNewRoman",val:"times new roman"}],fontsize:[10,11,12,14,16,18,20,24,36]}),d.addInputRule(function(a){utils.each(a.getNodesByTagName("u s del font strike"),function(a){if("font"==a.tagName){var b=[];for(var c in a.attrs)switch(c){case"size":b.push("font-size:"+({1:"10",2:"12",3:"16",4:"18",5:"24",6:"32",7:"48"}[a.attrs[c]]||a.attrs[c])+"px");break;case"color":b.push("color:"+a.attrs[c]);break;case"face":b.push("font-family:"+a.attrs[c]);break;case"style":b.push(a.attrs[c])}a.attrs={style:b.join(";")}}else{var d="u"==a.tagName?"underline":"line-through";a.attrs={style:(a.getAttr("style")||"")+"text-decoration:"+d+";"}}a.tagName="span"})});for(var h in e)!function(a,b){UE.commands[a]={execCommand:function(d,e){e=e||(this.queryCommandState(d)?"none":"underline"==d?"underline":"fontborder"==d?"1px solid #000":"line-through");var g,h=this,i=this.selection.getRange();if("default"==e)i.collapsed&&(g=h.document.createTextNode("font"),i.insertNode(g).select()),h.execCommand("removeFormat","span,a",b),g&&(i.setStartBefore(g).collapse(!0),domUtils.remove(g)),c(i,d,e),i.select();else if(i.collapsed){var j=domUtils.findParentByTagName(i.startContainer,"span",!0);if(g=h.document.createTextNode("font"),!j||j.children.length||j[browser.ie?"innerText":"textContent"].replace(fillCharReg,"").length){if(i.insertNode(g),i.selectNode(g).select(),j=i.document.createElement("span"),f[a]){if(domUtils.findParentByTagName(g,"a",!0))return i.setStartBefore(g).setCursor(),void domUtils.remove(g);h.execCommand("removeFormat","span,a",b)}if(j.style.cssText=b+":"+e,g.parentNode.insertBefore(j,g),!browser.ie||browser.ie&&9==browser.version)for(var k=j.parentNode;!domUtils.isBlockElm(k);)"SPAN"==k.tagName&&(j.style.cssText=k.style.cssText+";"+j.style.cssText),k=k.parentNode;opera?setTimeout(function(){i.setStart(j,0).collapse(!0),c(i,d,e),i.select()}):(i.setStart(j,0).collapse(!0),c(i,d,e),i.select())}else i.insertNode(g),f[a]&&(i.selectNode(g).select(),h.execCommand("removeFormat","span,a",b,null),j=domUtils.findParentByTagName(g,"span",!0),i.setStartBefore(g)),j&&(j.style.cssText+=";"+b+":"+e),i.collapse(!0).select();domUtils.remove(g)}else f[a]&&h.queryCommandValue(a)&&h.execCommand("removeFormat","span,a",b),i=h.selection.getRange(),i.applyInlineStyle("span",{style:b+":"+e}),c(i,d,e),i.select();return!0},queryCommandValue:function(a){var c=this.selection.getStart();if("underline"==a||"strikethrough"==a){for(var d,e=c;e&&!domUtils.isBlockElm(e)&&!domUtils.isBody(e);){if(1==e.nodeType&&(d=domUtils.getComputedStyle(e,b),"none"!=d))return d;e=e.parentNode}return"none"}if("fontborder"==a){for(var f,g=c;g&&dtd.$inline[g.tagName];){if((f=domUtils.getComputedStyle(g,"border"))&&/1px/.test(f)&&/solid/.test(f))return f;g=g.parentNode}return""}if("FontSize"==a){var h=domUtils.getComputedStyle(c,b),g=/^([\d\.]+)(\w+)$/.exec(h);return g?Math.floor(g[1])+g[2]:h}return domUtils.getComputedStyle(c,b)},queryCommandState:function(a){if(!f[a])return 0;var b=this.queryCommandValue(a);return"fontborder"==a?/1px/.test(b)&&/solid/.test(b):"underline"==a?/underline/.test(b):/line\-through/.test(b)}}}(h,e[h])},UE.plugins.link=function(){function a(a){var b=a.startContainer,c=a.endContainer;(b=domUtils.findParentByTagName(b,"a",!0))&&a.setStartBefore(b),(c=domUtils.findParentByTagName(c,"a",!0))&&a.setEndAfter(c)}function b(b,c,d){var e=b.cloneRange(),f=d.queryCommandValue("link");a(b=b.adjustmentBoundary());var g=b.startContainer;if(1==g.nodeType&&f&&(g=g.childNodes[b.startOffset],g&&1==g.nodeType&&"A"==g.tagName&&/^(?:https?|ftp|file)\s*:\s*\/\//.test(g[browser.ie?"innerText":"textContent"])&&(g[browser.ie?"innerText":"textContent"]=utils.html(c.textValue||c.href))),e.collapsed&&!f||(b.removeInlineStyle("a"),e=b.cloneRange()),e.collapsed){var h=b.document.createElement("a"),i="";c.textValue?(i=utils.html(c.textValue),delete c.textValue):i=utils.html(c.href),domUtils.setAttributes(h,c),g=domUtils.findParentByTagName(e.startContainer,"a",!0),g&&domUtils.isInNodeEndBoundary(e,g)&&b.setStartAfter(g).collapse(!0),h[browser.ie?"innerText":"textContent"]=i,b.insertNode(h).selectNode(h)}else b.applyInlineStyle("a",c)}UE.commands.unlink={execCommand:function(){var b,c=this.selection.getRange();c.collapsed&&!domUtils.findParentByTagName(c.startContainer,"a",!0)||(b=c.createBookmark(),a(c),c.removeInlineStyle("a").moveToBookmark(b).select())},queryCommandState:function(){return!this.highlight&&this.queryCommandValue("link")?0:-1}},UE.commands.link={execCommand:function(a,c){var d;c._href&&(c._href=utils.unhtml(c._href,/[<">]/g)),c.href&&(c.href=utils.unhtml(c.href,/[<">]/g)),c.textValue&&(c.textValue=utils.unhtml(c.textValue,/[<">]/g)),b(d=this.selection.getRange(),c,this),d.collapse().select(!0)},queryCommandValue:function(){var a,b=this.selection.getRange();if(!b.collapsed){b.shrinkBoundary();var c=3!=b.startContainer.nodeType&&b.startContainer.childNodes[b.startOffset]?b.startContainer.childNodes[b.startOffset]:b.startContainer,d=3==b.endContainer.nodeType||0==b.endOffset?b.endContainer:b.endContainer.childNodes[b.endOffset-1],e=b.getCommonAncestor();if(a=domUtils.findParentByTagName(e,"a",!0),!a&&1==e.nodeType)for(var f,g,h,i=e.getElementsByTagName("a"),j=0;h=i[j++];)if(f=domUtils.getPosition(h,c),g=domUtils.getPosition(h,d),(f&domUtils.POSITION_FOLLOWING||f&domUtils.POSITION_CONTAINS)&&(g&domUtils.POSITION_PRECEDING||g&domUtils.POSITION_CONTAINS)){a=h;break}return a}if(a=b.startContainer,a=1==a.nodeType?a:a.parentNode,a&&(a=domUtils.findParentByTagName(a,"a",!0))&&!domUtils.isInNodeEndBoundary(b,a))return a},queryCommandState:function(){var a=this.selection.getRange().getClosedNode(),b=a&&("edui-faked-video"==a.className||a.className.indexOf("edui-upload-video")!=-1);return b?-1:0}}},UE.plugins.insertframe=function(){function a(){b._iframe&&delete b._iframe}var b=this;b.addListener("selectionchange",function(){a()})},UE.commands.scrawl={queryCommandState:function(){return browser.ie&&browser.version<=8?-1:0}},UE.plugins.removeformat=function(){var a=this;a.setOpt({removeFormatTags:"b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var",removeFormatAttributes:"class,style,lang,width,height,align,hspace,valign"}),a.commands.removeformat={execCommand:function(a,b,c,d,e){function f(a){if(3==a.nodeType||"span"!=a.tagName.toLowerCase())return 0;if(browser.ie){var b=a.attributes;if(b.length){for(var c=0,d=b.length;c
      "+this.getContent(null,null,!0)+"
      "),b.close()},notNeedUndo:1},UE.plugins.selectall=function(){var a=this;a.commands.selectall={execCommand:function(){var a=this,b=a.body,c=a.selection.getRange();c.selectNodeContents(b),domUtils.isEmptyBlock(b)&&(browser.opera&&b.firstChild&&1==b.firstChild.nodeType&&c.setStartAtFirst(b.firstChild),c.collapse(!0)),c.select(!0)},notNeedUndo:1},a.addshortcutkey({selectAll:"ctrl+65"})},UE.plugins.paragraph=function(){var a=this,b=domUtils.isBlockElm,c=["TD","LI","PRE"],d=function(a,d,e,f){var g,h=a.createBookmark(),i=function(a){return 1==a.nodeType?"br"!=a.tagName.toLowerCase()&&!domUtils.isBookmarkNode(a):!domUtils.isWhitespace(a)};a.enlarge(!0);for(var j,k=a.createBookmark(),l=domUtils.getNextDomNode(k.start,!1,i),m=a.cloneRange();l&&!(domUtils.getPosition(l,k.end)&domUtils.POSITION_FOLLOWING);)if(3!=l.nodeType&&b(l))l=domUtils.getNextDomNode(l,!0,i);else{for(m.setStartBefore(l);l&&l!==k.end&&!b(l);)j=l,l=domUtils.getNextDomNode(l,!1,null,function(a){return!b(a)});m.setEndAfter(j),g=a.document.createElement(d),e&&(domUtils.setAttributes(g,e),f&&"customstyle"==f&&e.style&&(g.style.cssText=e.style)),g.appendChild(m.extractContents()),domUtils.isEmptyNode(g)&&domUtils.fillChar(a.document,g),m.insertNode(g);var n=g.parentNode;b(n)&&!domUtils.isBody(g.parentNode)&&utils.indexOf(c,n.tagName)==-1&&(f&&"customstyle"==f||(n.getAttribute("dir")&&g.setAttribute("dir",n.getAttribute("dir")),n.style.cssText&&(g.style.cssText=n.style.cssText+";"+g.style.cssText),n.style.textAlign&&!g.style.textAlign&&(g.style.textAlign=n.style.textAlign),n.style.textIndent&&!g.style.textIndent&&(g.style.textIndent=n.style.textIndent),n.style.padding&&!g.style.padding&&(g.style.padding=n.style.padding)),e&&/h\d/i.test(n.tagName)&&!/h\d/i.test(g.tagName)?(domUtils.setAttributes(n,e),f&&"customstyle"==f&&e.style&&(n.style.cssText=e.style),domUtils.remove(g,!0),g=n):domUtils.remove(g.parentNode,!0)),l=utils.indexOf(c,n.tagName)!=-1?n:g,l=domUtils.getNextDomNode(l,!1,i)}return a.moveToBookmark(k).moveToBookmark(h)};a.setOpt("paragraph",{p:"",h1:"",h2:"",h3:"",h4:"",h5:"",h6:""}),a.commands.paragraph={execCommand:function(a,b,c,e){var f=this.selection.getRange();if(f.collapsed){var g=this.document.createTextNode("p");if(f.insertNode(g),browser.ie){var h=g.previousSibling;h&&domUtils.isWhitespace(h)&&domUtils.remove(h),h=g.nextSibling,h&&domUtils.isWhitespace(h)&&domUtils.remove(h)}}if(f=d(f,b,c,e),g&&(f.setStartBefore(g).collapse(!0),pN=g.parentNode,domUtils.remove(g),domUtils.isBlockElm(pN)&&domUtils.isEmptyNode(pN)&&domUtils.fillNode(this.document,pN)),browser.gecko&&f.collapsed&&1==f.startContainer.nodeType){var i=f.startContainer.childNodes[f.startOffset];i&&1==i.nodeType&&i.tagName.toLowerCase()==b&&f.setStart(i,0).collapse(!0)}return f.select(),!0},queryCommandValue:function(){var a=domUtils.filterNodeList(this.selection.getStartElementPath(),"p h1 h2 h3 h4 h5 h6");return a?a.tagName.toLowerCase():""}}},function(){var a=domUtils.isBlockElm,b=function(a){return domUtils.filterNodeList(a.selection.getStartElementPath(),function(a){return a&&1==a.nodeType&&a.getAttribute("dir")})},c=function(c,d,e){var f,g=function(a){return 1==a.nodeType?!domUtils.isBookmarkNode(a):!domUtils.isWhitespace(a)},h=b(d);if(h&&c.collapsed)return h.setAttribute("dir",e),c;f=c.createBookmark(),c.enlarge(!0);for(var i,j=c.createBookmark(),k=domUtils.getNextDomNode(j.start,!1,g),l=c.cloneRange();k&&!(domUtils.getPosition(k,j.end)&domUtils.POSITION_FOLLOWING);)if(3!=k.nodeType&&a(k))k=domUtils.getNextDomNode(k,!0,g);else{for(l.setStartBefore(k);k&&k!==j.end&&!a(k);)i=k,k=domUtils.getNextDomNode(k,!1,null,function(b){return!a(b)});l.setEndAfter(i);var m=l.getCommonAncestor();if(!domUtils.isBody(m)&&a(m))m.setAttribute("dir",e),k=m;else{var n=c.document.createElement("p");n.setAttribute("dir",e);var o=l.extractContents();n.appendChild(o),l.insertNode(n),k=n}k=domUtils.getNextDomNode(k,!1,g)}return c.moveToBookmark(j).moveToBookmark(f)};UE.commands.directionality={execCommand:function(a,b){var d=this.selection.getRange();if(d.collapsed){var e=this.document.createTextNode("d");d.insertNode(e)}return c(d,this,b),e&&(d.setStartBefore(e).collapse(!0),domUtils.remove(e)),d.select(),!0},queryCommandValue:function(){var a=b(this);return a?a.getAttribute("dir"):"ltr"}}}(),UE.plugins.horizontal=function(){var a=this;a.commands.horizontal={execCommand:function(a){var b=this;if(b.queryCommandState(a)!==-1){b.execCommand("insertHtml","
      ");var c=b.selection.getRange(),d=c.startContainer;if(1==d.nodeType&&!d.childNodes[c.startOffset]){var e;(e=d.childNodes[c.startOffset-1])&&1==e.nodeType&&"HR"==e.tagName&&("p"==b.options.enterTag?(e=b.document.createElement("p"),c.insertNode(e),c.setStart(e,0).setCursor()):(e=b.document.createElement("br"),c.insertNode(e),c.setStartBefore(e).setCursor()))}return!0}},queryCommandState:function(){return domUtils.filterNodeList(this.selection.getStartElementPath(),"table")?-1:0}},a.addListener("delkeydown",function(a,b){var c=this.selection.getRange();if(c.txtToElmBoundary(!0),domUtils.isStartInblock(c)){var d=c.startContainer,e=d.previousSibling;if(e&&domUtils.isTagNode(e,"hr"))return domUtils.remove(e),c.select(),domUtils.preventDefault(b),!0}})},UE.commands.time=UE.commands.date={execCommand:function(a,b){function c(a,b){var c=("0"+a.getHours()).slice(-2),d=("0"+a.getMinutes()).slice(-2),e=("0"+a.getSeconds()).slice(-2);return b=b||"hh:ii:ss",b.replace(/hh/gi,c).replace(/ii/gi,d).replace(/ss/gi,e)}function d(a,b){var c=("000"+a.getFullYear()).slice(-4),d=c.slice(-2),e=("0"+(a.getMonth()+1)).slice(-2),f=("0"+a.getDate()).slice(-2);return b=b||"yyyy-mm-dd",b.replace(/yyyy/gi,c).replace(/yy/gi,d).replace(/mm/gi,e).replace(/dd/gi,f)}var e=new Date;this.execCommand("insertHtml","time"==a?c(e,b):d(e,b))}},UE.plugins.rowspacing=function(){var a=this;a.setOpt({rowspacingtop:["5","10","15","20","25"],rowspacingbottom:["5","10","15","20","25"]}),a.commands.rowspacing={execCommand:function(a,b,c){return this.execCommand("paragraph","p",{style:"margin-"+c+":"+b+"px"}),!0},queryCommandValue:function(a,b){var c,d=domUtils.filterNodeList(this.selection.getStartElementPath(),function(a){return domUtils.isBlockElm(a)});return d?(c=domUtils.getComputedStyle(d,"margin-"+b).replace(/[^\d]/g,""),c?c:0):0}}},UE.plugins.lineheight=function(){var a=this;a.setOpt({lineheight:["1","1.5","1.75","2","3","4","5"]}),a.commands.lineheight={execCommand:function(a,b){return this.execCommand("paragraph","p",{style:"line-height:"+("1"==b?"normal":b+"em")}),!0},queryCommandValue:function(){var a=domUtils.filterNodeList(this.selection.getStartElementPath(),function(a){return domUtils.isBlockElm(a)});if(a){var b=domUtils.getComputedStyle(a,"line-height");return"normal"==b?1:b.replace(/[^\d.]*/gi,"")}}}},UE.plugins.insertcode=function(){var a=this;a.ready(function(){utils.cssRule("pre","pre{margin:.5em 0;padding:.4em .6em;border-radius:8px;background:#f8f8f8;}",a.document)}),a.setOpt("insertcode",{as3:"ActionScript3",bash:"Bash/Shell",cpp:"C/C++",css:"Css",cf:"CodeFunction","c#":"C#",delphi:"Delphi",diff:"Diff",erlang:"Erlang",groovy:"Groovy",html:"Html",java:"Java",jfx:"JavaFx",js:"Javascript",pl:"Perl",php:"Php",plain:"Plain Text",ps:"PowerShell",python:"Python",ruby:"Ruby",scala:"Scala",sql:"Sql",vb:"Vb",xml:"Xml"}),a.commands.insertcode={execCommand:function(a,b){var c=this,d=c.selection.getRange(),e=domUtils.findParentByTagName(d.startContainer,"pre",!0);if(e)e.className="brush:"+b+";toolbar:false;";else{var f="";if(d.collapsed)f=browser.ie&&browser.ie11below?browser.version<=8?" ":"":"
      ";else{var g=d.extractContents(),h=c.document.createElement("div");h.appendChild(g),utils.each(UE.filterNode(UE.htmlparser(h.innerHTML.replace(/[\r\t]/g,"")),c.options.filterTxtRules).children,function(a){if(browser.ie&&browser.ie11below&&browser.version>8)"element"==a.type?"br"==a.tagName?f+="\n":dtd.$empty[a.tagName]||(utils.each(a.children,function(b){"element"==b.type?"br"==b.tagName?f+="\n":dtd.$empty[a.tagName]||(f+=b.innerText()):f+=b.data}),/\n$/.test(f)||(f+="\n")):f+=a.data+"\n",!a.nextSibling()&&/\n$/.test(f)&&(f=f.replace(/\n$/,""));else if(browser.ie&&browser.ie11below)"element"==a.type?"br"==a.tagName?f+="
      ":dtd.$empty[a.tagName]||(utils.each(a.children,function(b){"element"==b.type?"br"==b.tagName?f+="
      ":dtd.$empty[a.tagName]||(f+=b.innerText()):f+=b.data}),/br>$/.test(f)||(f+="
      ")):f+=a.data+"
      ",!a.nextSibling()&&/
      $/.test(f)&&(f=f.replace(/
      $/,""));else if(f+="element"==a.type?dtd.$empty[a.tagName]?"":a.innerText():a.data,!/br\/?\s*>$/.test(f)){if(!a.nextSibling())return;f+="
      "}})}c.execCommand("inserthtml",'
      '+f+"
      ",!0),e=c.document.getElementById("coder"),domUtils.removeAttributes(e,"id");var i=e.previousSibling;i&&(3==i.nodeType&&1==i.nodeValue.length&&browser.ie&&6==browser.version||domUtils.isEmptyBlock(i))&&domUtils.remove(i);var d=c.selection.getRange();domUtils.isEmptyBlock(e)?d.setStart(e,0).setCursor(!1,!0):d.selectNodeContents(e).select()}},queryCommandValue:function(){var a=this.selection.getStartElementPath(),b="";return utils.each(a,function(a){if("PRE"==a.nodeName){var c=a.className.match(/brush:([^;]+)/);return b=c&&c[1]?c[1]:"",!1}}),b}},a.addInputRule(function(a){utils.each(a.getNodesByTagName("pre"),function(a){var b=a.getNodesByTagName("br");if(b.length)return void(browser.ie&&browser.ie11below&&browser.version>8&&utils.each(b,function(a){var b=UE.uNode.createText("\n");a.parentNode.insertBefore(b,a),a.parentNode.removeChild(a)}));if(!(browser.ie&&browser.ie11below&&browser.version>8)){var c=a.innerText().split(/\n/);a.innerHTML(""),utils.each(c,function(b){b.length&&a.appendChild(UE.uNode.createText(b)),a.appendChild(UE.uNode.createElement("br"))})}})}),a.addOutputRule(function(a){utils.each(a.getNodesByTagName("pre"),function(a){var b="";utils.each(a.children,function(a){b+="text"==a.type?a.data.replace(/[ ]/g," ").replace(/\n$/,""):"br"==a.tagName?"\n":dtd.$empty[a.tagName]?a.innerText():""}),a.innerText(b.replace(/( |\n)+$/,""))})}),a.notNeedCodeQuery={help:1,undo:1,redo:1,source:1,print:1,searchreplace:1,fullscreen:1,preview:1,insertparagraph:1,elementpath:1,insertcode:1,inserthtml:1,selectall:1};a.queryCommandState;a.queryCommandState=function(a){var b=this;return!b.notNeedCodeQuery[a.toLowerCase()]&&b.selection&&b.queryCommandValue("insertcode")?-1:UE.Editor.prototype.queryCommandState.apply(this,arguments)},a.addListener("beforeenterkeydown",function(){var b=a.selection.getRange(),c=domUtils.findParentByTagName(b.startContainer,"pre",!0);if(c){if(a.fireEvent("saveScene"),b.collapsed||b.deleteContents(),!browser.ie||browser.ie9above){var c,d=a.document.createElement("br");b.insertNode(d).setStartAfter(d).collapse(!0);var e=d.nextSibling;e||browser.ie&&!(browser.version>10)?b.setStartAfter(d):b.insertNode(d.cloneNode(!1)), +c=d.previousSibling;for(var f;c;)if(f=c,c=c.previousSibling,!c||"BR"==c.nodeName){c=f;break}if(c){for(var g="";c&&"BR"!=c.nodeName&&new RegExp("^[\\s"+domUtils.fillChar+"]*$").test(c.nodeValue);)g+=c.nodeValue,c=c.nextSibling;if("BR"!=c.nodeName){var h=c.nodeValue.match(new RegExp("^([\\s"+domUtils.fillChar+"]+)"));h&&h[1]&&(g+=h[1])}g&&(g=a.document.createTextNode(g),b.insertNode(g).setStartAfter(g))}b.collapse(!0).select(!0)}else if(browser.version>8){var i=a.document.createTextNode("\n"),j=b.startContainer;if(0==b.startOffset){var k=j.previousSibling;if(k){b.insertNode(i);var l=a.document.createTextNode(" ");b.setStartAfter(i).insertNode(l).setStart(l,0).collapse(!0).select(!0)}}else{b.insertNode(i).setStartAfter(i);var l=a.document.createTextNode(" ");j=b.startContainer.childNodes[b.startOffset],j&&!/^\n/.test(j.nodeValue)&&b.setStartBefore(i),b.insertNode(l).setStart(l,0).collapse(!0).select(!0)}}else{var d=a.document.createElement("br");b.insertNode(d),b.insertNode(a.document.createTextNode(domUtils.fillChar)),b.setStartAfter(d),c=d.previousSibling;for(var f;c;)if(f=c,c=c.previousSibling,!c||"BR"==c.nodeName){c=f;break}if(c){for(var g="";c&&"BR"!=c.nodeName&&new RegExp("^[ "+domUtils.fillChar+"]*$").test(c.nodeValue);)g+=c.nodeValue,c=c.nextSibling;if("BR"!=c.nodeName){var h=c.nodeValue.match(new RegExp("^([ "+domUtils.fillChar+"]+)"));h&&h[1]&&(g+=h[1])}g=a.document.createTextNode(g),b.insertNode(g).setStartAfter(g)}b.collapse(!0).select()}return a.fireEvent("saveScene"),!0}}),a.addListener("tabkeydown",function(b,c){var d=a.selection.getRange(),e=domUtils.findParentByTagName(d.startContainer,"pre",!0);if(e){if(a.fireEvent("saveScene"),c.shiftKey);else if(d.collapsed){var f=a.document.createTextNode(" ");d.insertNode(f).setStartAfter(f).collapse(!0).select(!0)}else{for(var g=d.createBookmark(),h=g.start.previousSibling;h;){if(e.firstChild===h&&!domUtils.isBr(h)){e.insertBefore(a.document.createTextNode(" "),h);break}if(domUtils.isBr(h)){e.insertBefore(a.document.createTextNode(" "),h.nextSibling);break}h=h.previousSibling}var i=g.end;for(h=g.start.nextSibling,e.firstChild===g.start&&e.insertBefore(a.document.createTextNode(" "),h.nextSibling);h&&h!==i;){if(domUtils.isBr(h)&&h.nextSibling){if(h.nextSibling===i)break;e.insertBefore(a.document.createTextNode(" "),h.nextSibling)}h=h.nextSibling}d.moveToBookmark(g).select()}return a.fireEvent("saveScene"),!0}}),a.addListener("beforeinserthtml",function(a,b){var c=this,d=c.selection.getRange(),e=domUtils.findParentByTagName(d.startContainer,"pre",!0);if(e){d.collapsed||d.deleteContents();var f="";if(browser.ie&&browser.version>8){utils.each(UE.filterNode(UE.htmlparser(b),c.options.filterTxtRules).children,function(a){"element"==a.type?"br"==a.tagName?f+="\n":dtd.$empty[a.tagName]||(utils.each(a.children,function(b){"element"==b.type?"br"==b.tagName?f+="\n":dtd.$empty[a.tagName]||(f+=b.innerText()):f+=b.data}),/\n$/.test(f)||(f+="\n")):f+=a.data+"\n",!a.nextSibling()&&/\n$/.test(f)&&(f=f.replace(/\n$/,""))});var g=c.document.createTextNode(utils.html(f.replace(/ /g," ")));d.insertNode(g).selectNode(g).select()}else{var h=c.document.createDocumentFragment();utils.each(UE.filterNode(UE.htmlparser(b),c.options.filterTxtRules).children,function(a){"element"==a.type?"br"==a.tagName?h.appendChild(c.document.createElement("br")):dtd.$empty[a.tagName]||(utils.each(a.children,function(b){"element"==b.type?"br"==b.tagName?h.appendChild(c.document.createElement("br")):dtd.$empty[a.tagName]||h.appendChild(c.document.createTextNode(utils.html(b.innerText().replace(/ /g," ")))):h.appendChild(c.document.createTextNode(utils.html(b.data.replace(/ /g," "))))}),"BR"!=h.lastChild.nodeName&&h.appendChild(c.document.createElement("br"))):h.appendChild(c.document.createTextNode(utils.html(a.data.replace(/ /g," ")))),a.nextSibling()||"BR"!=h.lastChild.nodeName||h.removeChild(h.lastChild)}),d.insertNode(h).select()}return!0}}),a.addListener("keydown",function(a,b){var c=this,d=b.keyCode||b.which;if(40==d){var e,f=c.selection.getRange(),g=f.startContainer;if(f.collapsed&&(e=domUtils.findParentByTagName(f.startContainer,"pre",!0))&&!e.nextSibling){for(var h=e.lastChild;h&&"BR"==h.nodeName;)h=h.previousSibling;(h===g||f.startContainer===e&&f.startOffset==e.childNodes.length)&&(c.execCommand("insertparagraph"),domUtils.preventDefault(b))}}}),a.addListener("delkeydown",function(b,c){var d=this.selection.getRange();d.txtToElmBoundary(!0);var e=d.startContainer;if(domUtils.isTagNode(e,"pre")&&d.collapsed&&domUtils.isStartInblock(d)){var f=a.document.createElement("p");return domUtils.fillNode(a.document,f),e.parentNode.insertBefore(f,e),domUtils.remove(e),d.setStart(f,0).setCursor(!1,!0),domUtils.preventDefault(c),!0}})},UE.commands.cleardoc={execCommand:function(a){var b=this,c=b.options.enterTag,d=b.selection.getRange();"br"==c?(b.body.innerHTML="
      ",d.setStart(b.body,0).setCursor()):(b.body.innerHTML="

      "+(ie?"":"
      ")+"

      ",d.setStart(b.body.firstChild,0).setCursor(!1,!0)),setTimeout(function(){b.fireEvent("clearDoc")},0)}},UE.plugin.register("anchor",function(){return{bindEvents:{ready:function(){utils.cssRule("anchor",".anchorclass{background: url('"+this.options.themePath+this.options.theme+"/images/anchor.gif') no-repeat scroll left center transparent;cursor: auto;display: inline-block;height: 16px;width: 15px;}",this.document)}},outputRule:function(a){utils.each(a.getNodesByTagName("img"),function(a){var b;(b=a.getAttr("anchorname"))&&(a.tagName="a",a.setAttr({anchorname:"",name:b,"class":""}))})},inputRule:function(a){utils.each(a.getNodesByTagName("a"),function(a){var b;(b=a.getAttr("name"))&&!a.getAttr("href")&&(a.tagName="img",a.setAttr({anchorname:a.getAttr("name"),"class":"anchorclass"}),a.setAttr("name"))})},commands:{anchor:{execCommand:function(a,b){var c=this.selection.getRange(),d=c.getClosedNode();if(d&&d.getAttribute("anchorname"))b?d.setAttribute("anchorname",b):(c.setStartBefore(d).setCursor(),domUtils.remove(d));else if(b){var e=this.document.createElement("img");c.collapse(!0),domUtils.setAttributes(e,{anchorname:b,"class":"anchorclass"}),c.insertNode(e).setStartAfter(e).setCursor(!1,!0)}}}}}}),UE.plugins.wordcount=function(){var a=this;a.setOpt("wordCount",!0),a.addListener("contentchange",function(){a.fireEvent("wordcount")});var b;a.addListener("ready",function(){var a=this;domUtils.on(a.body,"keyup",function(c){var d=c.keyCode||c.which,e={16:1,18:1,20:1,37:1,38:1,39:1,40:1};d in e||(clearTimeout(b),b=setTimeout(function(){a.fireEvent("wordcount")},200))})})},UE.plugins.pagebreak=function(){function a(a){if(domUtils.isEmptyBlock(a)){for(var b,d=a.firstChild;d&&1==d.nodeType&&domUtils.isEmptyBlock(d);)b=d,d=d.firstChild;!b&&(b=a),domUtils.fillNode(c.document,b)}}function b(a){return a&&1==a.nodeType&&"HR"==a.tagName&&"pagebreak"==a.className}var c=this,d=["td"];c.setOpt("pageBreakTag","_ueditor_page_break_tag_"),c.ready(function(){utils.cssRule("pagebreak",".pagebreak{display:block;clear:both !important;cursor:default !important;width: 100% !important;margin:0;}",c.document)}),c.addInputRule(function(a){a.traversal(function(a){if("text"==a.type&&a.data==c.options.pageBreakTag){var b=UE.uNode.createElement('
      ');a.parentNode.insertBefore(b,a),a.parentNode.removeChild(a)}})}),c.addOutputRule(function(a){utils.each(a.getNodesByTagName("hr"),function(a){if("pagebreak"==a.getAttr("class")){var b=UE.uNode.createText(c.options.pageBreakTag);a.parentNode.insertBefore(b,a),a.parentNode.removeChild(a)}})}),c.commands.pagebreak={execCommand:function(){var e=c.selection.getRange(),f=c.document.createElement("hr");domUtils.setAttributes(f,{"class":"pagebreak",noshade:"noshade",size:"5"}),domUtils.unSelectable(f);var g,h=domUtils.findParentByTagName(e.startContainer,d,!0),i=[];if(h)switch(h.tagName){case"TD":if(g=h.parentNode,g.previousSibling)g.parentNode.insertBefore(f,g),i=domUtils.findParents(f);else{var j=domUtils.findParentByTagName(g,"table");j.parentNode.insertBefore(f,j),i=domUtils.findParents(f,!0)}g=i[1],f!==g&&domUtils.breakParent(f,g),c.fireEvent("afteradjusttable",c.document)}else{if(!e.collapsed){e.deleteContents();for(var k=e.startContainer;!domUtils.isBody(k)&&domUtils.isBlockElm(k)&&domUtils.isEmptyNode(k);)e.setStartBefore(k).collapse(!0),domUtils.remove(k),k=e.startContainer}e.insertNode(f);for(var l,g=f.parentNode;!domUtils.isBody(g);)domUtils.breakParent(f,g),l=f.nextSibling,l&&domUtils.isEmptyBlock(l)&&domUtils.remove(l),g=f.parentNode;l=f.nextSibling;var m=f.previousSibling;if(b(m)?domUtils.remove(m):m&&a(m),l)b(l)?domUtils.remove(l):a(l),e.setEndAfter(f).collapse(!1);else{var n=c.document.createElement("p");f.parentNode.appendChild(n),domUtils.fillNode(c.document,n),e.setStart(n,0).collapse(!0)}e.select(!0)}}}},UE.plugin.register("wordimage",function(){var a=this,b=[];return{commands:{wordimage:{execCommand:function(){for(var b,c=domUtils.getElementsByTagName(a.body,"img"),d=[],e=0;b=c[e++];){var f=b.getAttribute("word_img");f&&d.push(f)}return d},queryCommandState:function(){b=domUtils.getElementsByTagName(a.body,"img");for(var c,d=0;c=b[d++];)if(c.getAttribute("word_img"))return 1;return-1},notNeedUndo:!0}},inputRule:function(b){utils.each(b.getNodesByTagName("img"),function(b){var c=b.attrs,d=parseInt(c.width)<128||parseInt(c.height)<43,e=a.options,f=e.UEDITOR_HOME_URL+"themes/default/images/spacer.gif";c.src&&/^(?:(file:\/+))/.test(c.src)&&b.setAttr({width:c.width,height:c.height,alt:c.alt,word_img:c.src,src:f,style:"background:url("+(d?e.themePath+e.theme+"/images/word.gif":e.langPath+e.lang+"/images/localimage.png")+") no-repeat center center;border:1px solid #ddd"})})}}}),UE.plugins.dragdrop=function(){var a=this;a.ready(function(){domUtils.on(this.body,"dragend",function(){var b=a.selection.getRange(),c=b.getClosedNode()||a.selection.getStart();if(c&&"IMG"==c.tagName){for(var d,e=c.previousSibling;(d=c.nextSibling)&&1==d.nodeType&&"SPAN"==d.tagName&&!d.firstChild;)domUtils.remove(d);(!e||1!=e.nodeType||domUtils.isEmptyBlock(e))&&e||d&&(!d||domUtils.isEmptyBlock(d))||(e&&"P"==e.tagName&&!domUtils.isEmptyBlock(e)?(e.appendChild(c),domUtils.moveChild(d,e),domUtils.remove(d)):d&&"P"==d.tagName&&!domUtils.isEmptyBlock(d)&&d.insertBefore(c,d.firstChild),e&&"P"==e.tagName&&domUtils.isEmptyBlock(e)&&domUtils.remove(e),d&&"P"==d.tagName&&domUtils.isEmptyBlock(d)&&domUtils.remove(d),b.selectNode(c).select(),a.fireEvent("saveScene"))}})}),a.addListener("keyup",function(b,c){var d=c.keyCode||c.which;if(13==d){var e,f=a.selection.getRange();(e=domUtils.findParentByTagName(f.startContainer,"p",!0))&&"center"==domUtils.getComputedStyle(e,"text-align")&&domUtils.removeStyle(e,"text-align")}})},UE.plugins.undo=function(){function a(a,b){if(a.length!=b.length)return 0;for(var c=0,d=a.length;cf&&this.list.shift(),this.index=this.list.length-1,this.clearKey(),this.update())},this.update=function(){this.hasRedo=!!this.list[this.index+1],this.hasUndo=!!this.list[this.index-1]},this.reset=function(){this.list=[],this.index=0,this.hasUndo=!1,this.hasRedo=!1,this.clearKey()},this.clearKey=function(){m=0,k=null}}var d,e=this,f=e.options.maxUndoCount||20,g=e.options.maxInputCount||20,h=new RegExp(domUtils.fillChar+"|","gi"),i={ol:1,ul:1,table:1,tbody:1,tr:1,body:1},j=e.options.autoClearEmptyNode;e.undoManger=new c,e.undoManger.editor=e,e.addListener("saveScene",function(){var a=Array.prototype.splice.call(arguments,1);this.undoManger.save.apply(this.undoManger,a)}),e.addListener("reset",function(a,b){b||this.undoManger.reset()}),e.commands.redo=e.commands.undo={execCommand:function(a){this.undoManger[a]()},queryCommandState:function(a){return this.undoManger["has"+("undo"==a.toLowerCase()?"Undo":"Redo")]?0:-1},notNeedUndo:1};var k,l={16:1,17:1,18:1,37:1,38:1,39:1,40:1},m=0,n=!1;e.addListener("ready",function(){domUtils.on(this.body,"compositionstart",function(){n=!0}),domUtils.on(this.body,"compositionend",function(){n=!1})}),e.addshortcutkey({Undo:"ctrl+90",Redo:"ctrl+89"});var o=!0;e.addListener("keydown",function(a,b){function c(a){a.undoManger.save(!1,!0),a.fireEvent("selectionchange")}var e=this,f=b.keyCode||b.which;if(!(l[f]||b.ctrlKey||b.metaKey||b.shiftKey||b.altKey)){if(n)return;if(!e.selection.getRange().collapsed)return e.undoManger.save(!1,!0),void(o=!1);0==e.undoManger.list.length&&e.undoManger.save(!0),clearTimeout(d),d=setTimeout(function(){if(n)var a=setInterval(function(){n||(c(e),clearInterval(a))},300);else c(e)},200),k=f,m++,m>=g&&c(e)}}),e.addListener("keyup",function(a,b){var c=b.keyCode||b.which;if(!(l[c]||b.ctrlKey||b.metaKey||b.shiftKey||b.altKey)){if(n)return;o||(this.undoManger.save(!1,!0),o=!0)}}),e.stopCmdUndo=function(){e.__hasEnterExecCommand=!0},e.startCmdUndo=function(){e.__hasEnterExecCommand=!1}},UE.plugin.register("copy",function(){function a(){ZeroClipboard.config({debug:!1,swfPath:b.options.UEDITOR_HOME_URL+"third-party/zeroclipboard/ZeroClipboard.swf"});var a=b.zeroclipboard=new ZeroClipboard;a.on("copy",function(a){var c=a.client,d=b.selection.getRange(),e=document.createElement("div");e.appendChild(d.cloneContents()),c.setText(e.innerText||e.textContent),c.setHtml(e.innerHTML),d.select()}),a.on("mouseover mouseout",function(a){var b=a.target;"mouseover"==a.type?domUtils.addClass(b,"edui-state-hover"):"mouseout"==a.type&&domUtils.removeClasses(b,"edui-state-hover")}),a.on("wrongflash noflash",function(){ZeroClipboard.destroy()})}var b=this;return{bindEvents:{ready:function(){browser.ie||(window.ZeroClipboard?a():utils.loadFile(document,{src:b.options.UEDITOR_HOME_URL+"third-party/zeroclipboard/ZeroClipboard.js",tag:"script",type:"text/javascript",defer:"defer"},function(){a()}))}},commands:{copy:{execCommand:function(a){b.document.execCommand("copy")||alert(b.getLang("copymsg"))}}}}}),UE.plugins.paste=function(){function a(a){var b=this.document;if(!b.getElementById("baidu_pastebin")){var c=this.selection.getRange(),d=c.createBookmark(),e=b.createElement("div");e.id="baidu_pastebin",browser.webkit&&e.appendChild(b.createTextNode(domUtils.fillChar+domUtils.fillChar)),b.body.appendChild(e),d.start.style.display="",e.style.cssText="position:absolute;width:1px;height:1px;overflow:hidden;left:-1000px;white-space:nowrap;top:"+domUtils.getXY(d.start).y+"px",c.selectNodeContents(e).select(!0),setTimeout(function(){if(browser.webkit)for(var f,g=0,h=b.querySelectorAll("#baidu_pastebin");f=h[g++];){if(!domUtils.isEmptyNode(f)){e=f;break}domUtils.remove(f)}try{e.parentNode.removeChild(e)}catch(i){}c.moveToBookmark(d).select(!0),a(e)},0)}}function b(a){return a.replace(/<(\/?)([\w\-]+)([^>]*)>/gi,function(a,b,c,d){return c=c.toLowerCase(),{img:1}[c]?a:(d=d.replace(/([\w\-]*?)\s*=\s*(("([^"]*)")|('([^']*)')|([^\s>]+))/gi,function(a,b,c){return{src:1,href:1,name:1}[b.toLowerCase()]?b+"="+c+" ":""}),{span:1,div:1}[c]?"":"<"+b+c+" "+utils.trim(d)+">")})}function c(a){var c;if(a.firstChild){for(var h,i=domUtils.getElementsByTagName(a,"span"),j=0;h=i[j++];)"_baidu_cut_start"!=h.id&&"_baidu_cut_end"!=h.id||domUtils.remove(h);if(browser.webkit){for(var k,l=a.querySelectorAll("div br"),j=0;k=l[j++];){var m=k.parentNode;"DIV"==m.tagName&&1==m.childNodes.length&&(m.innerHTML="


      ",domUtils.remove(m))}for(var n,o=a.querySelectorAll("#baidu_pastebin"),j=0;n=o[j++];){var p=d.document.createElement("p");for(n.parentNode.insertBefore(p,n);n.firstChild;)p.appendChild(n.firstChild);domUtils.remove(n)}for(var q,r=a.querySelectorAll("meta"),j=0;q=r[j++];)domUtils.remove(q);var l=a.querySelectorAll("br");for(j=0;q=l[j++];)/^apple-/i.test(q.className)&&domUtils.remove(q)}if(browser.gecko){var s=a.querySelectorAll("[_moz_dirty]");for(j=0;q=s[j++];)q.removeAttribute("_moz_dirty")}if(!browser.ie)for(var q,t=a.querySelectorAll("span.Apple-style-span"),j=0;q=t[j++];)domUtils.remove(q,!0);c=a.innerHTML,c=UE.filterWord(c);var u=UE.htmlparser(c);if(d.options.filterRules&&UE.filterNode(u,d.options.filterRules),d.filterInputRule(u),browser.webkit){var v=u.lastChild();v&&"element"==v.type&&"br"==v.tagName&&u.removeChild(v),utils.each(d.body.querySelectorAll("div"),function(a){domUtils.isEmptyBlock(a)&&domUtils.remove(a,!0)})}if(c={html:u.toHtml()},d.fireEvent("beforepaste",c,u),!c.html)return;u=UE.htmlparser(c.html,!0),1===d.queryCommandState("pasteplain")?d.execCommand("insertHtml",UE.filterNode(u,d.options.filterTxtRules).toHtml(),!0):(UE.filterNode(u,d.options.filterTxtRules),e=u.toHtml(),f=c.html,g=d.selection.getRange().createAddress(!0),d.execCommand("insertHtml",d.getOpt("retainOnlyLabelPasted")===!0?b(f):f,!0)),d.fireEvent("afterpaste",c)}}var d=this;d.setOpt({retainOnlyLabelPasted:!1});var e,f,g;d.addListener("pasteTransfer",function(a,c){if(g&&e&&f&&e!=f){var h=d.selection.getRange();if(h.moveToAddress(g,!0),!h.collapsed){for(;!domUtils.isBody(h.startContainer);){var i=h.startContainer;if(1==i.nodeType){if(i=i.childNodes[h.startOffset],!i){h.setStartBefore(h.startContainer);continue}var j=i.previousSibling;j&&3==j.nodeType&&new RegExp("^[\n\r\t "+domUtils.fillChar+"]*$").test(j.nodeValue)&&h.setStartBefore(j)}if(0!=h.startOffset)break;h.setStartBefore(h.startContainer)}for(;!domUtils.isBody(h.endContainer);){var k=h.endContainer;if(1==k.nodeType){if(k=k.childNodes[h.endOffset],!k){h.setEndAfter(h.endContainer);continue}var l=k.nextSibling;l&&3==l.nodeType&&new RegExp("^[\n\r\t"+domUtils.fillChar+"]*$").test(l.nodeValue)&&h.setEndAfter(l)}if(h.endOffset!=h.endContainer[3==h.endContainer.nodeType?"nodeValue":"childNodes"].length)break;h.setEndAfter(h.endContainer)}}h.deleteContents(),h.select(!0),d.__hasEnterExecCommand=!0;var m=f;2===c?m=b(m):c&&(m=e),d.execCommand("inserthtml",m,!0),d.__hasEnterExecCommand=!1;for(var n=d.selection.getRange();!domUtils.isBody(n.startContainer)&&!n.startOffset&&n.startContainer[3==n.startContainer.nodeType?"nodeValue":"childNodes"].length;)n.setStartBefore(n.startContainer);var o=n.createAddress(!0);g.endAddress=o.startAddress}}),d.addListener("ready",function(){domUtils.on(d.body,"cut",function(){var a=d.selection.getRange();!a.collapsed&&d.undoManger&&d.undoManger.save()}),domUtils.on(d.body,browser.ie||browser.opera?"keydown":"paste",function(b){(!browser.ie&&!browser.opera||(b.ctrlKey||b.metaKey)&&"86"==b.keyCode)&&a.call(d,function(a){c(a)})})}),d.commands.paste={execCommand:function(b){browser.ie?(a.call(d,function(a){c(a)}),d.document.execCommand("paste")):alert(d.getLang("pastemsg"))}}},UE.plugins.pasteplain=function(){var a=this;a.setOpt({pasteplain:!1,filterTxtRules:function(){function a(a){a.tagName="p",a.setStyle()}function b(a){a.parentNode.removeChild(a,!0)}return{"-":"script style object iframe embed input select",p:{$:{}},br:{$:{}},div:function(a){for(var b,c=UE.uNode.createElement("p");b=a.firstChild();)"text"!=b.type&&UE.dom.dtd.$block[b.tagName]?c.firstChild()?(a.parentNode.insertBefore(c,a),c=UE.uNode.createElement("p")):a.parentNode.insertBefore(b,a):c.appendChild(b);c.firstChild()&&a.parentNode.insertBefore(c,a),a.parentNode.removeChild(a)},ol:b,ul:b,dl:b,dt:b,dd:b,li:b,caption:a,th:a,tr:a,h1:a,h2:a,h3:a,h4:a,h5:a,h6:a,td:function(a){var b=!!a.innerText();b&&a.parentNode.insertAfter(UE.uNode.createText("    "),a),a.parentNode.removeChild(a,a.innerText())}}}()});var b=a.options.pasteplain;a.commands.pasteplain={queryCommandState:function(){return b?1:0},execCommand:function(){b=0|!b},notNeedUndo:1}},UE.plugins.list=function(){function a(a){var b=[];for(var c in a)b.push(c);return b}function b(a){var b=a.className;return domUtils.hasClass(a,/custom_/)?b.match(/custom_(\w+)/)[1]:domUtils.getStyle(a,"list-style-type")}function c(a,c){utils.each(domUtils.getElementsByTagName(a,"ol ul"),function(f){if(domUtils.inDoc(f,a)){var g=f.parentNode;if(g.tagName==f.tagName){var h=b(f)||("OL"==f.tagName?"decimal":"disc"),i=b(g)||("OL"==g.tagName?"decimal":"disc");if(h==i){var l=utils.indexOf(k[f.tagName],h);l=l+1==k[f.tagName].length?0:l+1,e(f,k[f.tagName][l])}}var m=0,n=2;domUtils.hasClass(f,/custom_/)?/[ou]l/i.test(g.tagName)&&domUtils.hasClass(g,/custom_/)||(n=1):/[ou]l/i.test(g.tagName)&&domUtils.hasClass(g,/custom_/)&&(n=3);var o=domUtils.getStyle(f,"list-style-type");o&&(f.style.cssText="list-style-type:"+o),f.className=utils.trim(f.className.replace(/list-paddingleft-\w+/,""))+" list-paddingleft-"+n,utils.each(domUtils.getElementsByTagName(f,"li"),function(a){if(a.style.cssText&&(a.style.cssText=""),!a.firstChild)return void domUtils.remove(a);if(a.parentNode===f){if(m++,domUtils.hasClass(f,/custom_/)){var c=1,d=b(f);if("OL"==f.tagName){if(d)switch(d){case"cn":case"cn1":case"cn2":m>10&&(m%10==0||m>10&&m<20)?c=2:m>20&&(c=3);break;case"num2":m>9&&(c=2)}a.className="list-"+j[d]+m+" list-"+d+"-paddingleft-"+c}else a.className="list-"+j[d]+" list-"+d+"-paddingleft"}else a.className=a.className.replace(/list-[\w\-]+/gi,"");var e=a.getAttribute("class");null===e||e.replace(/\s/g,"")||domUtils.removeAttributes(a,"class")}}),!c&&d(f,f.tagName.toLowerCase(),b(f)||domUtils.getStyle(f,"list-style-type"),!0)}})}function d(a,d,e,f){var g=a.nextSibling;g&&1==g.nodeType&&g.tagName.toLowerCase()==d&&(b(g)||domUtils.getStyle(g,"list-style-type")||("ol"==d?"decimal":"disc"))==e&&(domUtils.moveChild(g,a),0==g.childNodes.length&&domUtils.remove(g)),g&&domUtils.isFillChar(g)&&domUtils.remove(g);var h=a.previousSibling;h&&1==h.nodeType&&h.tagName.toLowerCase()==d&&(b(h)||domUtils.getStyle(h,"list-style-type")||("ol"==d?"decimal":"disc"))==e&&domUtils.moveChild(a,h),h&&domUtils.isFillChar(h)&&domUtils.remove(h),!f&&domUtils.isEmptyBlock(a)&&domUtils.remove(a),b(a)&&c(a.ownerDocument,!0)}function e(a,b){j[b]&&(a.className="custom_"+b);try{domUtils.setStyle(a,"list-style-type",b)}catch(c){}}function f(a){var b=a.previousSibling;b&&domUtils.isEmptyBlock(b)&&domUtils.remove(b),b=a.nextSibling,b&&domUtils.isEmptyBlock(b)&&domUtils.remove(b)}function g(a){for(;a&&!domUtils.isBody(a);){if("TABLE"==a.nodeName)return null;if("LI"==a.nodeName)return a;a=a.parentNode}}var h=this,i={TD:1,PRE:1,BLOCKQUOTE:1},j={cn:"cn-1-",cn1:"cn-2-",cn2:"cn-3-",num:"num-1-",num1:"num-2-",num2:"num-3-",dash:"dash",dot:"dot"};h.setOpt({autoTransWordToList:!1,insertorderedlist:{num:"",num1:"",num2:"",cn:"",cn1:"",cn2:"",decimal:"","lower-alpha":"","lower-roman":"","upper-alpha":"","upper-roman":""},insertunorderedlist:{circle:"",disc:"",square:"",dash:"",dot:""},listDefaultPaddingLeft:"30",listiconpath:"http://bs.baidu.com/listicon/",maxListLevel:-1,disablePInList:!1});var k={OL:a(h.options.insertorderedlist),UL:a(h.options.insertunorderedlist)},l=h.options.listiconpath;for(var m in j)h.options.insertorderedlist.hasOwnProperty(m)||h.options.insertunorderedlist.hasOwnProperty(m)||delete j[m];h.ready(function(){var a=[];for(var b in j){if("dash"==b||"dot"==b)a.push("li.list-"+j[b]+"{background-image:url("+l+j[b]+".gif)}"),a.push("ul.custom_"+b+"{list-style:none;}ul.custom_"+b+" li{background-position:0 3px;background-repeat:no-repeat}");else{for(var c=0;c<99;c++)a.push("li.list-"+j[b]+c+"{background-image:url("+l+"list-"+j[b]+c+".gif)}");a.push("ol.custom_"+b+"{list-style:none;}ol.custom_"+b+" li{background-position:0 3px;background-repeat:no-repeat}")}switch(b){case"cn":a.push("li.list-"+b+"-paddingleft-1{padding-left:25px}"),a.push("li.list-"+b+"-paddingleft-2{padding-left:40px}"),a.push("li.list-"+b+"-paddingleft-3{padding-left:55px}");break;case"cn1":a.push("li.list-"+b+"-paddingleft-1{padding-left:30px}"),a.push("li.list-"+b+"-paddingleft-2{padding-left:40px}"),a.push("li.list-"+b+"-paddingleft-3{padding-left:55px}");break;case"cn2":a.push("li.list-"+b+"-paddingleft-1{padding-left:40px}"),a.push("li.list-"+b+"-paddingleft-2{padding-left:55px}"),a.push("li.list-"+b+"-paddingleft-3{padding-left:68px}");break;case"num":case"num1":a.push("li.list-"+b+"-paddingleft-1{padding-left:25px}");break;case"num2":a.push("li.list-"+b+"-paddingleft-1{padding-left:35px}"),a.push("li.list-"+b+"-paddingleft-2{padding-left:40px}");break;case"dash":a.push("li.list-"+b+"-paddingleft{padding-left:35px}");break;case"dot":a.push("li.list-"+b+"-paddingleft{padding-left:20px}")}}a.push(".list-paddingleft-1{padding-left:0}"),a.push(".list-paddingleft-2{padding-left:"+h.options.listDefaultPaddingLeft+"px}"),a.push(".list-paddingleft-3{padding-left:"+2*h.options.listDefaultPaddingLeft+"px}"),utils.cssRule("list","ol,ul{margin:0;pading:0;"+(browser.ie?"":"width:95%")+"}li{clear:both;}"+a.join("\n"),h.document)}),h.ready(function(){domUtils.on(h.body,"cut",function(){setTimeout(function(){var a,b=h.selection.getRange();if(!b.collapsed&&(a=domUtils.findParentByTagName(b.startContainer,"li",!0))&&!a.nextSibling&&domUtils.isEmptyBlock(a)){var c,d=a.parentNode;if(c=d.previousSibling)domUtils.remove(d),b.setStartAtLast(c).collapse(!0),b.select(!0);else if(c=d.nextSibling)domUtils.remove(d),b.setStartAtFirst(c).collapse(!0),b.select(!0);else{var e=h.document.createElement("p");domUtils.fillNode(h.document,e),d.parentNode.insertBefore(e,d),domUtils.remove(d),b.setStart(e,0).collapse(!0),b.select(!0)}}})})}),h.addListener("beforepaste",function(a,c){var d,e=this,f=e.selection.getRange(),g=UE.htmlparser(c.html,!0);if(d=domUtils.findParentByTagName(f.startContainer,"li",!0)){var h=d.parentNode,i="OL"==h.tagName?"ul":"ol";utils.each(g.getNodesByTagName(i),function(c){if(c.tagName=h.tagName,c.setAttr(),c.parentNode===g)a=b(h)||("OL"==h.tagName?"decimal":"disc");else{var d=c.parentNode.getAttr("class");a=d&&/custom_/.test(d)?d.match(/custom_(\w+)/)[1]:c.parentNode.getStyle("list-style-type"),a||(a="OL"==h.tagName?"decimal":"disc")}var e=utils.indexOf(k[h.tagName],a);c.parentNode!==g&&(e=e+1==k[h.tagName].length?0:e+1);var f=k[h.tagName][e];j[f]?c.setAttr("class","custom_"+f):c.setStyle("list-style-type",f)})}c.html=g.toHtml()}),h.getOpt("disablePInList")===!0&&h.addOutputRule(function(a){utils.each(a.getNodesByTagName("li"),function(a){var b=[],c=0;utils.each(a.children,function(d){if("p"==d.tagName){for(var e;e=d.children.pop();)b.splice(c,0,e),e.parentNode=a,lastNode=e;if(e=b[b.length-1],!e||"element"!=e.type||"br"!=e.tagName){var f=UE.uNode.createElement("br");f.parentNode=a,b.push(f)}c=b.length}}),b.length&&(a.children=b)})}),h.addInputRule(function(a){function b(a,b){var e=b.firstChild();if(e&&"element"==e.type&&"span"==e.tagName&&/Wingdings|Symbol/.test(e.getStyle("font-family"))){for(var f in d)if(d[f]==e.data)return f;return"disc"}for(var f in c)if(c[f].test(a))return f}if(utils.each(a.getNodesByTagName("li"),function(a){for(var b,c=UE.uNode.createElement("p"),d=0;b=a.children[d];)"text"==b.type||dtd.p[b.tagName]?c.appendChild(b):c.firstChild()?(a.insertBefore(c,b),c=UE.uNode.createElement("p"),d+=2):d++;(c.firstChild()&&!c.parentNode||!a.firstChild())&&a.appendChild(c),c.firstChild()||c.innerHTML(browser.ie?" ":"
      ");var e=a.firstChild(),f=e.lastChild();f&&"text"==f.type&&/^\s*$/.test(f.data)&&e.removeChild(f)}),h.options.autoTransWordToList){var c={num1:/^\d+\)/,decimal:/^\d+\./,"lower-alpha":/^[a-z]+\)/,"upper-alpha":/^[A-Z]+\./,cn:/^[\u4E00\u4E8C\u4E09\u56DB\u516d\u4e94\u4e03\u516b\u4e5d]+[\u3001]/,cn2:/^\([\u4E00\u4E8C\u4E09\u56DB\u516d\u4e94\u4e03\u516b\u4e5d]+\)/},d={square:"n"};utils.each(a.getNodesByTagName("p"),function(a){function d(a,b,d){if("ol"==a.tagName)if(browser.ie){var e=b.firstChild();"element"==e.type&&"span"==e.tagName&&c[d].test(e.innerText())&&b.removeChild(e)}else b.innerHTML(b.innerHTML().replace(c[d],""));else b.removeChild(b.firstChild());var f=UE.uNode.createElement("li");f.appendChild(b),a.appendChild(f)}if("MsoListParagraph"==a.getAttr("class")){a.setStyle("margin",""),a.setStyle("margin-left",""),a.setAttr("class","");var e,f=a,g=a;if("li"!=a.parentNode.tagName&&(e=b(a.innerText(),a))){var i=UE.uNode.createElement(h.options.insertorderedlist.hasOwnProperty(e)?"ol":"ul");for(j[e]?i.setAttr("class","custom_"+e):i.setStyle("list-style-type",e);a&&"li"!=a.parentNode.tagName&&b(a.innerText(),a);)f=a.nextSibling(),f||a.parentNode.insertBefore(i,a),d(i,a,e),a=f;!i.parentNode&&a&&a.parentNode&&a.parentNode.insertBefore(i,a)}var k=g.firstChild();k&&"element"==k.type&&"span"==k.tagName&&/^\s*( )+\s*$/.test(k.innerText())&&k.parentNode.removeChild(k)}})}}),h.addListener("contentchange",function(){c(h.document)}),h.addListener("keydown",function(a,b){function c(){b.preventDefault?b.preventDefault():b.returnValue=!1,h.fireEvent("contentchange"),h.undoManger&&h.undoManger.save()}function d(a,b){for(;a&&!domUtils.isBody(a);){if(b(a))return null;if(1==a.nodeType&&/[ou]l/i.test(a.tagName))return a;a=a.parentNode}return null}var e=b.keyCode||b.which;if(13==e&&!b.shiftKey){var g=h.selection.getRange(),i=domUtils.findParent(g.startContainer,function(a){return domUtils.isBlockElm(a)},!0),j=domUtils.findParentByTagName(g.startContainer,"li",!0);if(i&&"PRE"!=i.tagName&&!j){var k=i.innerHTML.replace(new RegExp(domUtils.fillChar,"g"),"");/^\s*1\s*\.[^\d]/.test(k)&&(i.innerHTML=k.replace(/^\s*1\s*\./,""),g.setStartAtLast(i).collapse(!0).select(),h.__hasEnterExecCommand=!0,h.execCommand("insertorderedlist"),h.__hasEnterExecCommand=!1)}var l=h.selection.getRange(),m=d(l.startContainer,function(a){return"TABLE"==a.tagName}),n=l.collapsed?m:d(l.endContainer,function(a){return"TABLE"==a.tagName});if(m&&n&&m===n){if(!l.collapsed){if(m=domUtils.findParentByTagName(l.startContainer,"li",!0),n=domUtils.findParentByTagName(l.endContainer,"li",!0),!m||!n||m!==n){var o=l.cloneRange(),p=o.collapse(!1).createBookmark();l.deleteContents(),o.moveToBookmark(p);var j=domUtils.findParentByTagName(o.startContainer,"li",!0);return f(j),o.select(),void c()}if(l.deleteContents(),j=domUtils.findParentByTagName(l.startContainer,"li",!0),j&&domUtils.isEmptyBlock(j))return v=j.previousSibling,next=j.nextSibling,s=h.document.createElement("p"),domUtils.fillNode(h.document,s),q=j.parentNode,v&&next?(l.setStart(next,0).collapse(!0).select(!0),domUtils.remove(j)):((v||next)&&v?j.parentNode.parentNode.insertBefore(s,q.nextSibling):q.parentNode.insertBefore(s,q),domUtils.remove(j),q.firstChild||domUtils.remove(q),l.setStart(s,0).setCursor()),void c()}if(j=domUtils.findParentByTagName(l.startContainer,"li",!0)){ +if(domUtils.isEmptyBlock(j)){p=l.createBookmark();var q=j.parentNode;if(j!==q.lastChild?(domUtils.breakParent(j,q),f(j)):(q.parentNode.insertBefore(j,q.nextSibling),domUtils.isEmptyNode(q)&&domUtils.remove(q)),!dtd.$list[j.parentNode.tagName])if(domUtils.isBlockElm(j.firstChild))domUtils.remove(j,!0);else{for(s=h.document.createElement("p"),j.parentNode.insertBefore(s,j);j.firstChild;)s.appendChild(j.firstChild);domUtils.remove(j)}l.moveToBookmark(p).select()}else{var r=j.firstChild;if(!r||!domUtils.isBlockElm(r)){var s=h.document.createElement("p");for(!j.firstChild&&domUtils.fillNode(h.document,s);j.firstChild;)s.appendChild(j.firstChild);j.appendChild(s),r=s}var t=h.document.createElement("span");l.insertNode(t),domUtils.breakParent(t,j);var u=t.nextSibling;r=u.firstChild,r||(s=h.document.createElement("p"),domUtils.fillNode(h.document,s),u.appendChild(s),r=s),domUtils.isEmptyNode(r)&&(r.innerHTML="",domUtils.fillNode(h.document,r)),l.setStart(r,0).collapse(!0).shrinkBoundary().select(),domUtils.remove(t);var v=u.previousSibling;v&&domUtils.isEmptyBlock(v)&&(v.innerHTML="

      ",domUtils.fillNode(h.document,v.firstChild))}c()}}}if(8==e&&(l=h.selection.getRange(),l.collapsed&&domUtils.isStartInblock(l)&&(o=l.cloneRange().trimBoundary(),j=domUtils.findParentByTagName(l.startContainer,"li",!0),j&&domUtils.isStartInblock(o)))){if(m=domUtils.findParentByTagName(l.startContainer,"p",!0),m&&m!==j.firstChild){var q=domUtils.findParentByTagName(m,["ol","ul"]);return domUtils.breakParent(m,q),f(m),h.fireEvent("contentchange"),l.setStart(m,0).setCursor(!1,!0),h.fireEvent("saveScene"),void domUtils.preventDefault(b)}if(j&&(v=j.previousSibling)){if(46==e&&j.childNodes.length)return;if(dtd.$list[v.tagName]&&(v=v.lastChild),h.undoManger&&h.undoManger.save(),r=j.firstChild,domUtils.isBlockElm(r))if(domUtils.isEmptyNode(r))for(v.appendChild(r),l.setStart(r,0).setCursor(!1,!0);j.firstChild;)v.appendChild(j.firstChild);else t=h.document.createElement("span"),l.insertNode(t),domUtils.isEmptyBlock(v)&&(v.innerHTML=""),domUtils.moveChild(j,v),l.setStartBefore(t).collapse(!0).select(!0),domUtils.remove(t);else if(domUtils.isEmptyNode(j)){var s=h.document.createElement("p");v.appendChild(s),l.setStart(s,0).setCursor()}else for(l.setEnd(v,v.childNodes.length).collapse().select(!0);j.firstChild;)v.appendChild(j.firstChild);return domUtils.remove(j),h.fireEvent("contentchange"),h.fireEvent("saveScene"),void domUtils.preventDefault(b)}if(j&&!j.previousSibling){var q=j.parentNode,p=l.createBookmark();if(domUtils.isTagNode(q.parentNode,"ol ul"))q.parentNode.insertBefore(j,q),domUtils.isEmptyNode(q)&&domUtils.remove(q);else{for(;j.firstChild;)q.parentNode.insertBefore(j.firstChild,q);domUtils.remove(j),domUtils.isEmptyNode(q)&&domUtils.remove(q)}return l.moveToBookmark(p).setCursor(!1,!0),h.fireEvent("contentchange"),h.fireEvent("saveScene"),void domUtils.preventDefault(b)}}}),h.addListener("keyup",function(a,c){var e=c.keyCode||c.which;if(8==e){var f,g=h.selection.getRange();(f=domUtils.findParentByTagName(g.startContainer,["ol","ul"],!0))&&d(f,f.tagName.toLowerCase(),b(f)||domUtils.getComputedStyle(f,"list-style-type"),!0)}}),h.addListener("tabkeydown",function(){function a(a){if(h.options.maxListLevel!=-1){for(var b=a.parentNode,c=0;/[ou]l/i.test(b.tagName);)c++,b=b.parentNode;if(c>=h.options.maxListLevel)return!0}}var c=h.selection.getRange(),f=domUtils.findParentByTagName(c.startContainer,"li",!0);if(f){var g;if(!c.collapsed){h.fireEvent("saveScene"),g=c.createBookmark();for(var i,j,l=0,m=domUtils.findParents(f);j=m[l++];)if(domUtils.isTagNode(j,"ol ul")){i=j;break}var n=f;if(g.end)for(;n&&!(domUtils.getPosition(n,g.end)&domUtils.POSITION_FOLLOWING);)if(a(n))n=domUtils.getNextDomNode(n,!1,null,function(a){return a!==i});else{var o=n.parentNode,p=h.document.createElement(o.tagName),q=utils.indexOf(k[p.tagName],b(o)||domUtils.getComputedStyle(o,"list-style-type")),r=q+1==k[p.tagName].length?0:q+1,s=k[p.tagName][r];for(e(p,s),o.insertBefore(p,n);n&&!(domUtils.getPosition(n,g.end)&domUtils.POSITION_FOLLOWING);){if(f=n.nextSibling,p.appendChild(n),!f||domUtils.isTagNode(f,"ol ul")){if(f)for(;(f=f.firstChild)&&"LI"!=f.tagName;);else f=domUtils.getNextDomNode(n,!1,null,function(a){return a!==i});break}n=f}d(p,p.tagName.toLowerCase(),s),n=f}return h.fireEvent("contentchange"),c.moveToBookmark(g).select(),!0}if(a(f))return!0;var o=f.parentNode,p=h.document.createElement(o.tagName),q=utils.indexOf(k[p.tagName],b(o)||domUtils.getComputedStyle(o,"list-style-type"));q=q+1==k[p.tagName].length?0:q+1;var s=k[p.tagName][q];if(e(p,s),domUtils.isStartInblock(c))return h.fireEvent("saveScene"),g=c.createBookmark(),o.insertBefore(p,f),p.appendChild(f),d(p,p.tagName.toLowerCase(),s),h.fireEvent("contentchange"),c.moveToBookmark(g).select(!0),!0}}),h.commands.insertorderedlist=h.commands.insertunorderedlist={execCommand:function(a,c){c||(c="insertorderedlist"==a.toLowerCase()?"decimal":"disc");var f=this,h=this.selection.getRange(),j=function(a){return 1==a.nodeType?"br"!=a.tagName.toLowerCase():!domUtils.isWhitespace(a)},k="insertorderedlist"==a.toLowerCase()?"ol":"ul",l=f.document.createDocumentFragment();h.adjustmentBoundary().shrinkBoundary();var m,n,o,p,q=h.createBookmark(!0),r=g(f.document.getElementById(q.start)),s=0,t=g(f.document.getElementById(q.end)),u=0;if(r||t){if(r&&(m=r.parentNode),q.end||(t=r),t&&(n=t.parentNode),m===n){for(;r!==t;){if(p=r,r=r.nextSibling,!domUtils.isBlockElm(p.firstChild)){for(var v=f.document.createElement("p");p.firstChild;)v.appendChild(p.firstChild);p.appendChild(v)}l.appendChild(p)}if(p=f.document.createElement("span"),m.insertBefore(p,t),!domUtils.isBlockElm(t.firstChild)){for(v=f.document.createElement("p");t.firstChild;)v.appendChild(t.firstChild);t.appendChild(v)}l.appendChild(t),domUtils.breakParent(p,m),domUtils.isEmptyNode(p.previousSibling)&&domUtils.remove(p.previousSibling),domUtils.isEmptyNode(p.nextSibling)&&domUtils.remove(p.nextSibling);var w=b(m)||domUtils.getComputedStyle(m,"list-style-type")||("insertorderedlist"==a.toLowerCase()?"decimal":"disc");if(m.tagName.toLowerCase()==k&&w==c){for(var x,y=0,z=f.document.createDocumentFragment();x=l.firstChild;)if(domUtils.isTagNode(x,"ol ul"))z.appendChild(x);else for(;x.firstChild;)z.appendChild(x.firstChild),domUtils.remove(x);p.parentNode.insertBefore(z,p)}else o=f.document.createElement(k),e(o,c),o.appendChild(l),p.parentNode.insertBefore(o,p);return domUtils.remove(p),o&&d(o,k,c),void h.moveToBookmark(q).select()}if(r){for(;r;){if(p=r.nextSibling,domUtils.isTagNode(r,"ol ul"))l.appendChild(r);else{for(var A=f.document.createDocumentFragment(),B=0;r.firstChild;)domUtils.isBlockElm(r.firstChild)&&(B=1),A.appendChild(r.firstChild);if(B)l.appendChild(A);else{var C=f.document.createElement("p");C.appendChild(A),l.appendChild(C)}domUtils.remove(r)}r=p}m.parentNode.insertBefore(l,m.nextSibling),domUtils.isEmptyNode(m)?(h.setStartBefore(m),domUtils.remove(m)):h.setStartAfter(m),s=1}if(t&&domUtils.inDoc(n,f.document)){for(r=n.firstChild;r&&r!==t;){if(p=r.nextSibling,domUtils.isTagNode(r,"ol ul"))l.appendChild(r);else{for(A=f.document.createDocumentFragment(),B=0;r.firstChild;)domUtils.isBlockElm(r.firstChild)&&(B=1),A.appendChild(r.firstChild);B?l.appendChild(A):(C=f.document.createElement("p"),C.appendChild(A),l.appendChild(C)),domUtils.remove(r)}r=p}var D=domUtils.createElement(f.document,"div",{tmpDiv:1});domUtils.moveChild(t,D),l.appendChild(D),domUtils.remove(t),n.parentNode.insertBefore(l,n),h.setEndBefore(n),domUtils.isEmptyNode(n)&&domUtils.remove(n),u=1}}s||h.setStartBefore(f.document.getElementById(q.start)),q.end&&!u&&h.setEndAfter(f.document.getElementById(q.end)),h.enlarge(!0,function(a){return i[a.tagName]}),l=f.document.createDocumentFragment();for(var E,F=h.createBookmark(),G=domUtils.getNextDomNode(F.start,!1,j),H=h.cloneRange(),I=domUtils.isBlockElm;G&&G!==F.end&&domUtils.getPosition(G,F.end)&domUtils.POSITION_PRECEDING;)if(3==G.nodeType||dtd.li[G.tagName]){if(1==G.nodeType&&dtd.$list[G.tagName]){for(;G.firstChild;)l.appendChild(G.firstChild);E=domUtils.getNextDomNode(G,!1,j),domUtils.remove(G),G=E;continue}for(E=G,H.setStartBefore(G);G&&G!==F.end&&(!I(G)||domUtils.isBookmarkNode(G));)E=G,G=domUtils.getNextDomNode(G,!1,null,function(a){return!i[a.tagName]});G&&I(G)&&(p=domUtils.getNextDomNode(E,!1,j),p&&domUtils.isBookmarkNode(p)&&(G=domUtils.getNextDomNode(p,!1,j),E=p)),H.setEndAfter(E),G=domUtils.getNextDomNode(E,!1,j);var J=h.document.createElement("li");if(J.appendChild(H.extractContents()),domUtils.isEmptyNode(J)){for(var E=h.document.createElement("p");J.firstChild;)E.appendChild(J.firstChild);J.appendChild(E)}l.appendChild(J)}else G=domUtils.getNextDomNode(G,!0,j);h.moveToBookmark(F).collapse(!0),o=f.document.createElement(k),e(o,c),o.appendChild(l),h.insertNode(o),d(o,k,c);for(var x,y=0,K=domUtils.getElementsByTagName(o,"div");x=K[y++];)x.getAttribute("tmpDiv")&&domUtils.remove(x,!0);h.moveToBookmark(q).select()},queryCommandState:function(a){for(var b,c="insertorderedlist"==a.toLowerCase()?"ol":"ul",d=this.selection.getStartElementPath(),e=0;b=d[e++];){if("TABLE"==b.nodeName)return 0;if(c==b.nodeName.toLowerCase())return 1}return 0},queryCommandValue:function(a){for(var c,d,e="insertorderedlist"==a.toLowerCase()?"ol":"ul",f=this.selection.getStartElementPath(),g=0;d=f[g++];){if("TABLE"==d.nodeName){c=null;break}if(e==d.nodeName.toLowerCase()){c=d;break}}return c?b(c)||domUtils.getComputedStyle(c,"list-style-type"):null}}},function(){var a={textarea:function(a,b){var c=b.ownerDocument.createElement("textarea");return c.style.cssText="position:absolute;resize:none;width:100%;height:100%;border:0;padding:0;margin:0;overflow-y:auto;",browser.ie&&browser.version<8&&(c.style.width=b.offsetWidth+"px",c.style.height=b.offsetHeight+"px",b.onresize=function(){c.style.width=b.offsetWidth+"px",c.style.height=b.offsetHeight+"px"}),b.appendChild(c),{setContent:function(a){c.value=a},getContent:function(){return c.value},select:function(){var a;browser.ie?(a=c.createTextRange(),a.collapse(!0),a.select()):(c.setSelectionRange(0,0),c.focus())},dispose:function(){b.removeChild(c),b.onresize=null,c=null,b=null}}},codemirror:function(a,b){var c=window.CodeMirror(b,{mode:"text/html",tabMode:"indent",lineNumbers:!0,lineWrapping:!0}),d=c.getWrapperElement();return d.style.cssText='position:absolute;left:0;top:0;width:100%;height:100%;font-family:consolas,"Courier new",monospace;font-size:13px;',c.getScrollerElement().style.cssText="position:absolute;left:0;top:0;width:100%;height:100%;",c.refresh(),{getCodeMirror:function(){return c},setContent:function(a){c.setValue(a)},getContent:function(){return c.getValue()},select:function(){c.focus()},dispose:function(){b.removeChild(d),d=null,c=null}}}};UE.plugins.source=function(){function b(b){return a["codemirror"==f.sourceEditor&&window.CodeMirror?"codemirror":"textarea"](e,b)}var c,d,e=this,f=this.options,g=!1;f.sourceEditor=browser.ie?"textarea":f.sourceEditor||"codemirror",e.setOpt({sourceEditorFirst:!1});var h,i,j;e.commands.source={execCommand:function(){if(g=!g){j=e.selection.getRange().createAddress(!1,!0),e.undoManger&&e.undoManger.save(!0),browser.gecko&&(e.body.contentEditable=!1),h=e.iframe.style.cssText,e.iframe.style.cssText+="position:absolute;left:-32768px;top:-32768px;",e.fireEvent("beforegetcontent");var a=UE.htmlparser(e.body.innerHTML);e.filterOutputRule(a),a.traversal(function(a){if("element"==a.type)switch(a.tagName){case"td":case"th":case"caption":a.children&&1==a.children.length&&"br"==a.firstChild().tagName&&a.removeChild(a.firstChild());break;case"pre":a.innerText(a.innerText().replace(/ /g," "))}}),e.fireEvent("aftergetcontent");var f=a.toHtml(!0);c=b(e.iframe.parentNode),c.setContent(f),d=e.setContent,e.setContent=function(a){var b=UE.htmlparser(a);e.filterInputRule(b),a=b.toHtml(),c.setContent(a)},setTimeout(function(){c.select(),e.addListener("fullscreenchanged",function(){try{c.getCodeMirror().refresh()}catch(a){}})}),i=e.getContent,e.getContent=function(){return c.getContent()||"

      "+(browser.ie?"":"
      ")+"

      "}}else{e.iframe.style.cssText=h;var k=c.getContent()||"

      "+(browser.ie?"":"
      ")+"

      ";k=k.replace(new RegExp("[\\r\\t\\n ]*]*)>","g"),function(a,b){return b&&!dtd.$inlineWithA[b.toLowerCase()]?a.replace(/(^[\n\r\t ]*)|([\n\r\t ]*$)/g,""):a.replace(/(^[\n\r\t]*)|([\n\r\t]*$)/g,"")}),e.setContent=d,e.setContent(k),c.dispose(),c=null,e.getContent=i;var l=e.body.firstChild;if(l||(e.body.innerHTML="

      "+(browser.ie?"":"
      ")+"

      ",l=e.body.firstChild),e.undoManger&&e.undoManger.save(!0),browser.gecko){var m=document.createElement("input");m.style.cssText="position:absolute;left:0;top:-32768px",document.body.appendChild(m),e.body.contentEditable=!1,setTimeout(function(){domUtils.setViewportOffset(m,{left:-32768,top:0}),m.focus(),setTimeout(function(){e.body.contentEditable=!0,e.selection.getRange().moveToAddress(j).select(!0),domUtils.remove(m)})})}else try{e.selection.getRange().moveToAddress(j).select(!0)}catch(n){}}this.fireEvent("sourcemodechanged",g)},queryCommandState:function(){return 0|g},notNeedUndo:1};var k=e.queryCommandState;e.queryCommandState=function(a){return a=a.toLowerCase(),g?a in{source:1,fullscreen:1}?1:-1:k.apply(this,arguments)},"codemirror"==f.sourceEditor&&e.addListener("ready",function(){utils.loadFile(document,{src:f.codeMirrorJsUrl||f.UEDITOR_HOME_URL+"third-party/codemirror/codemirror.js",tag:"script",type:"text/javascript",defer:"defer"},function(){f.sourceEditorFirst&&setTimeout(function(){e.execCommand("source")},0)}),utils.loadFile(document,{tag:"link",rel:"stylesheet",type:"text/css",href:f.codeMirrorCssUrl||f.UEDITOR_HOME_URL+"third-party/codemirror/codemirror.css"})})}}(),UE.plugins.enterkey=function(){var a,b=this,c=b.options.enterTag;b.addListener("keyup",function(c,d){var e=d.keyCode||d.which;if(13==e){var f,g=b.selection.getRange(),h=g.startContainer;if(browser.ie)b.fireEvent("saveScene",!0,!0);else{if(/h\d/i.test(a)){if(browser.gecko){var i=domUtils.findParentByTagName(h,["h1","h2","h3","h4","h5","h6","blockquote","caption","table"],!0);i||(b.document.execCommand("formatBlock",!1,"

      "),f=1)}else if(1==h.nodeType){var j,k=b.document.createTextNode("");if(g.insertNode(k),j=domUtils.findParentByTagName(k,"div",!0)){for(var l=b.document.createElement("p");j.firstChild;)l.appendChild(j.firstChild);j.parentNode.insertBefore(l,j),domUtils.remove(j),g.setStartBefore(k).setCursor(),f=1}domUtils.remove(k)}b.undoManger&&f&&b.undoManger.save()}browser.opera&&g.select()}}}),b.addListener("keydown",function(d,e){var f=e.keyCode||e.which;if(13==f){if(b.fireEvent("beforeenterkeydown"))return void domUtils.preventDefault(e);b.fireEvent("saveScene",!0,!0),a="";var g=b.selection.getRange();if(!g.collapsed){var h=g.startContainer,i=g.endContainer,j=domUtils.findParentByTagName(h,"td",!0),k=domUtils.findParentByTagName(i,"td",!0);if(j&&k&&j!==k||!j&&k||j&&!k)return void(e.preventDefault?e.preventDefault():e.returnValue=!1)}if("p"==c)browser.ie||(h=domUtils.findParentByTagName(g.startContainer,["ol","ul","p","h1","h2","h3","h4","h5","h6","blockquote","caption"],!0),h||browser.opera?(a=h.tagName,"p"==h.tagName.toLowerCase()&&browser.gecko&&domUtils.removeDirtyAttr(h)):(b.document.execCommand("formatBlock",!1,"

      "),browser.gecko&&(g=b.selection.getRange(),h=domUtils.findParentByTagName(g.startContainer,"p",!0),h&&domUtils.removeDirtyAttr(h))));else if(e.preventDefault?e.preventDefault():e.returnValue=!1,g.collapsed){m=g.document.createElement("br"),g.insertNode(m);var l=m.parentNode;l.lastChild===m?(m.parentNode.insertBefore(m.cloneNode(!0),m),g.setStartBefore(m)):g.setStartAfter(m),g.setCursor()}else if(g.deleteContents(),h=g.startContainer,1==h.nodeType&&(h=h.childNodes[g.startOffset])){for(;1==h.nodeType;){if(dtd.$empty[h.tagName])return g.setStartBefore(h).setCursor(),b.undoManger&&b.undoManger.save(),!1;if(!h.firstChild){var m=g.document.createElement("br");return h.appendChild(m),g.setStart(h,0).setCursor(),b.undoManger&&b.undoManger.save(),!1}h=h.firstChild}h===g.startContainer.childNodes[g.startOffset]?(m=g.document.createElement("br"),g.insertNode(m).setCursor()):g.setStart(h,0).setCursor()}else m=g.document.createElement("br"),g.insertNode(m).setStartAfter(m).setCursor()}})},UE.plugins.keystrokes=function(){var a=this,b=!0;a.addListener("keydown",function(c,d){var e=d.keyCode||d.which,f=a.selection.getRange();if(!f.collapsed&&!(d.ctrlKey||d.shiftKey||d.altKey||d.metaKey)&&(e>=65&&e<=90||e>=48&&e<=57||e>=96&&e<=111||{13:1,8:1,46:1}[e])){var g=f.startContainer;if(domUtils.isFillChar(g)&&f.setStartBefore(g),g=f.endContainer,domUtils.isFillChar(g)&&f.setEndAfter(g),f.txtToElmBoundary(),f.endContainer&&1==f.endContainer.nodeType&&(g=f.endContainer.childNodes[f.endOffset],g&&domUtils.isBr(g)&&f.setEndAfter(g)),0==f.startOffset&&(g=f.startContainer,domUtils.isBoundaryNode(g,"firstChild")&&(g=f.endContainer,f.endOffset==(3==g.nodeType?g.nodeValue.length:g.childNodes.length)&&domUtils.isBoundaryNode(g,"lastChild"))))return a.fireEvent("saveScene"),a.body.innerHTML="

      "+(browser.ie?"":"
      ")+"

      ",f.setStart(a.body.firstChild,0).setCursor(!1,!0),void a._selectionChange()}if(e==keymap.Backspace){if(f=a.selection.getRange(),b=f.collapsed,a.fireEvent("delkeydown",d))return;var h,i;if(f.collapsed&&f.inFillChar()&&(h=f.startContainer,domUtils.isFillChar(h)?(f.setStartBefore(h).shrinkBoundary(!0).collapse(!0),domUtils.remove(h)):(h.nodeValue=h.nodeValue.replace(new RegExp("^"+domUtils.fillChar),""),f.startOffset--,f.collapse(!0).select(!0))),h=f.getClosedNode())return a.fireEvent("saveScene"),f.setStartBefore(h),domUtils.remove(h),f.setCursor(),a.fireEvent("saveScene"),void domUtils.preventDefault(d);if(!browser.ie&&(h=domUtils.findParentByTagName(f.startContainer,"table",!0),i=domUtils.findParentByTagName(f.endContainer,"table",!0),h&&!i||!h&&i||h!==i))return void d.preventDefault()}if(e==keymap.Tab){var j={ol:1,ul:1,table:1};if(a.fireEvent("tabkeydown",d))return void domUtils.preventDefault(d);var k=a.selection.getRange();a.fireEvent("saveScene");for(var l=0,m="",n=a.options.tabSize||4,o=a.options.tabNode||" ";l"});d.insertNode(g).setStart(g,0).setCursor(!1,!0)}}if(!b&&(3==d.startContainer.nodeType||1==d.startContainer.nodeType&&domUtils.isEmptyBlock(d.startContainer)))if(browser.ie){var k=d.document.createElement("span");d.insertNode(k).setStartBefore(k).collapse(!0),d.select(),domUtils.remove(k)}else d.select()}})},UE.plugins.fiximgclick=function(){function a(){this.editor=null,this.resizer=null,this.cover=null,this.doc=document,this.prePos={x:0,y:0},this.startPos={x:0,y:0}}var b=!1;return function(){var c=[[0,0,-1,-1],[0,0,0,-1],[0,0,1,-1],[0,0,-1,0],[0,0,1,0],[0,0,-1,1],[0,0,0,1],[0,0,1,1]];a.prototype={init:function(a){var b=this;b.editor=a,b.startPos=this.prePos={x:0,y:0},b.dragId=-1;var c=[],d=b.cover=document.createElement("div"),e=b.resizer=document.createElement("div");for(d.id=b.editor.ui.id+"_imagescale_cover",d.style.cssText="position:absolute;display:none;z-index:"+b.editor.options.zIndex+";filter:alpha(opacity=0); opacity:0;background:#CCC;",domUtils.on(d,"mousedown click",function(){b.hide()}),i=0;i<8;i++)c.push('');e.id=b.editor.ui.id+"_imagescale",e.className="edui-editor-imagescale",e.innerHTML=c.join(""),e.style.cssText+=";display:none;border:1px solid #3b77ff;z-index:"+b.editor.options.zIndex+";",b.editor.ui.getDom().appendChild(d),b.editor.ui.getDom().appendChild(e),b.initStyle(),b.initEvents()},initStyle:function(){utils.cssRule("imagescale",".edui-editor-imagescale{display:none;position:absolute;border:1px solid #38B2CE;cursor:hand;-webkit-box-sizing: content-box;-moz-box-sizing: content-box;box-sizing: content-box;}.edui-editor-imagescale span{position:absolute;width:6px;height:6px;overflow:hidden;font-size:0px;display:block;background-color:#3C9DD0;}.edui-editor-imagescale .edui-editor-imagescale-hand0{cursor:nw-resize;top:0;margin-top:-4px;left:0;margin-left:-4px;}.edui-editor-imagescale .edui-editor-imagescale-hand1{cursor:n-resize;top:0;margin-top:-4px;left:50%;margin-left:-4px;}.edui-editor-imagescale .edui-editor-imagescale-hand2{cursor:ne-resize;top:0;margin-top:-4px;left:100%;margin-left:-3px;}.edui-editor-imagescale .edui-editor-imagescale-hand3{cursor:w-resize;top:50%;margin-top:-4px;left:0;margin-left:-4px;}.edui-editor-imagescale .edui-editor-imagescale-hand4{cursor:e-resize;top:50%;margin-top:-4px;left:100%;margin-left:-3px;}.edui-editor-imagescale .edui-editor-imagescale-hand5{cursor:sw-resize;top:100%;margin-top:-3px;left:0;margin-left:-4px;}.edui-editor-imagescale .edui-editor-imagescale-hand6{cursor:s-resize;top:100%;margin-top:-3px;left:50%;margin-left:-4px;}.edui-editor-imagescale .edui-editor-imagescale-hand7{cursor:se-resize;top:100%;margin-top:-3px;left:100%;margin-left:-3px;}")},initEvents:function(){var a=this;a.startPos.x=a.startPos.y=0,a.isDraging=!1},_eventHandler:function(a){var c=this;switch(a.type){case"mousedown":var d,d=a.target||a.srcElement;d.className.indexOf("edui-editor-imagescale-hand")!=-1&&c.dragId==-1&&(c.dragId=d.className.slice(-1),c.startPos.x=c.prePos.x=a.clientX,c.startPos.y=c.prePos.y=a.clientY,domUtils.on(c.doc,"mousemove",c.proxy(c._eventHandler,c)));break;case"mousemove":c.dragId!=-1&&(c.updateContainerStyle(c.dragId,{x:a.clientX-c.prePos.x,y:a.clientY-c.prePos.y}),c.prePos.x=a.clientX,c.prePos.y=a.clientY,b=!0,c.updateTargetElement());break;case"mouseup":c.dragId!=-1&&(c.updateContainerStyle(c.dragId,{x:a.clientX-c.prePos.x,y:a.clientY-c.prePos.y}),c.updateTargetElement(),c.target.parentNode&&c.attachTo(c.target),c.dragId=-1),domUtils.un(c.doc,"mousemove",c.proxy(c._eventHandler,c)),b&&(b=!1,c.editor.fireEvent("contentchange"))}},updateTargetElement:function(){var a=this;domUtils.setStyles(a.target,{width:a.resizer.style.width,height:a.resizer.style.height}),a.target.width=parseInt(a.resizer.style.width),a.target.height=parseInt(a.resizer.style.height),a.attachTo(a.target)},updateContainerStyle:function(a,b){var d,e=this,f=e.resizer;0!=c[a][0]&&(d=parseInt(f.style.left)+b.x,f.style.left=e._validScaledProp("left",d)+"px"),0!=c[a][1]&&(d=parseInt(f.style.top)+b.y,f.style.top=e._validScaledProp("top",d)+"px"),0!=c[a][2]&&(d=f.clientWidth+c[a][2]*b.x,f.style.width=e._validScaledProp("width",d)+"px"),0!=c[a][3]&&(d=f.clientHeight+c[a][3]*b.y,f.style.height=e._validScaledProp("height",d)+"px")},_validScaledProp:function(a,b){var c=this.resizer,d=document;switch(b=isNaN(b)?0:b,a){case"left":return b<0?0:b+c.clientWidth>d.clientWidth?d.clientWidth-c.clientWidth:b;case"top":return b<0?0:b+c.clientHeight>d.clientHeight?d.clientHeight-c.clientHeight:b;case"width":return b<=0?1:b+c.offsetLeft>d.clientWidth?d.clientWidth-c.offsetLeft:b;case"height":return b<=0?1:b+c.offsetTop>d.clientHeight?d.clientHeight-c.offsetTop:b}},hideCover:function(){this.cover.style.display="none"},showCover:function(){var a=this,b=domUtils.getXY(a.editor.ui.getDom()),c=domUtils.getXY(a.editor.iframe);domUtils.setStyles(a.cover,{width:a.editor.iframe.offsetWidth+"px",height:a.editor.iframe.offsetHeight+"px",top:c.y-b.y+"px",left:c.x-b.x+"px",position:"absolute",display:""})},show:function(a){var b=this;b.resizer.style.display="block",a&&b.attachTo(a),domUtils.on(this.resizer,"mousedown",b.proxy(b._eventHandler,b)),domUtils.on(b.doc,"mouseup",b.proxy(b._eventHandler,b)),b.showCover(),b.editor.fireEvent("afterscaleshow",b),b.editor.fireEvent("saveScene")},hide:function(){var a=this;a.hideCover(),a.resizer.style.display="none",domUtils.un(a.resizer,"mousedown",a.proxy(a._eventHandler,a)),domUtils.un(a.doc,"mouseup",a.proxy(a._eventHandler,a)),a.editor.fireEvent("afterscalehide",a)},proxy:function(a,b){return function(c){return a.apply(b||this,arguments)}},attachTo:function(a){var b=this,c=b.target=a,d=this.resizer,e=domUtils.getXY(c),f=domUtils.getXY(b.editor.iframe),g=domUtils.getXY(d.parentNode);domUtils.setStyles(d,{width:c.width+"px",height:c.height+"px",left:f.x+e.x-b.editor.document.body.scrollLeft-g.x-parseInt(d.style.borderLeftWidth)+"px",top:f.y+e.y-b.editor.document.body.scrollTop-g.y-parseInt(d.style.borderTopWidth)+"px"})}}}(),function(){var b,c=this;c.setOpt("imageScaleEnabled",!0),!browser.ie&&c.options.imageScaleEnabled&&c.addListener("click",function(d,e){var f=c.selection.getRange(),g=f.getClosedNode();if(g&&"IMG"==g.tagName&&"false"!=c.body.contentEditable){if(g.className.indexOf("edui-faked-music")!=-1||g.getAttribute("anchorname")||domUtils.hasClass(g,"loadingclass")||domUtils.hasClass(g,"loaderrorclass"))return;if(!b){b=new a,b.init(c),c.ui.getDom().appendChild(b.resizer);var h,i=function(a){b.hide(),b.target&&c.selection.getRange().selectNode(b.target).select()},j=function(a){var b=a.target||a.srcElement;!b||void 0!==b.className&&b.className.indexOf("edui-editor-imagescale")!=-1||i(a)};c.addListener("afterscaleshow",function(a){c.addListener("beforekeydown",i),c.addListener("beforemousedown",j),domUtils.on(document,"keydown",i),domUtils.on(document,"mousedown",j),c.selection.getNative().removeAllRanges()}),c.addListener("afterscalehide",function(a){c.removeListener("beforekeydown",i),c.removeListener("beforemousedown",j),domUtils.un(document,"keydown",i),domUtils.un(document,"mousedown",j);var d=b.target;d.parentNode&&c.selection.getRange().selectNode(d).select()}),domUtils.on(b.resizer,"mousedown",function(a){c.selection.getNative().removeAllRanges();var d=a.target||a.srcElement;d&&d.className.indexOf("edui-editor-imagescale-hand")==-1&&(h=setTimeout(function(){b.hide(),b.target&&c.selection.getRange().selectNode(d).select()},200))}),domUtils.on(b.resizer,"mouseup",function(a){var b=a.target||a.srcElement;b&&b.className.indexOf("edui-editor-imagescale-hand")==-1&&clearTimeout(h)})}b.show(g)}else b&&"none"!=b.resizer.style.display&&b.hide()}),browser.webkit&&c.addListener("click",function(a,b){if("IMG"==b.target.tagName&&"false"!=c.body.contentEditable){var d=new dom.Range(c.document);d.selectNode(b.target).select()}})}}(),UE.plugin.register("autolink",function(){var a=0;return browser.ie?{}:{bindEvents:{reset:function(){a=0},keydown:function(a,b){var c=this,d=b.keyCode||b.which;if(32==d||13==d){for(var e,f,g=c.selection.getNative(),h=g.getRangeAt(0).cloneRange(),i=h.startContainer;1==i.nodeType&&h.startOffset>0&&(i=h.startContainer.childNodes[h.startOffset-1]);)h.setStart(i,1==i.nodeType?i.childNodes.length:i.nodeValue.length),h.collapse(!0),i=h.startContainer;do{if(0==h.startOffset){for(i=h.startContainer.previousSibling;i&&1==i.nodeType;)i=i.lastChild;if(!i||domUtils.isFillChar(i))break;e=i.nodeValue.length}else i=h.startContainer,e=h.startOffset;h.setStart(i,e-1),f=h.toString().charCodeAt(0)}while(160!=f&&32!=f);if(h.toString().replace(new RegExp(domUtils.fillChar,"g"),"").match(/(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i)){for(;h.toString().length&&!/^(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i.test(h.toString());)try{h.setStart(h.startContainer,h.startOffset+1)}catch(j){for(var i=h.startContainer;!(next=i.nextSibling);){if(domUtils.isBody(i))return;i=i.parentNode}h.setStart(next,0)}if(domUtils.findParentByTagName(h.startContainer,"a",!0))return;var k,l=c.document.createElement("a"),m=c.document.createTextNode(" ");c.undoManger&&c.undoManger.save(),l.appendChild(h.extractContents()),l.href=l.innerHTML=l.innerHTML.replace(/<[^>]+>/g,""),k=l.getAttribute("href").replace(new RegExp(domUtils.fillChar,"g"),""),k=/^(?:https?:\/\/)/gi.test(k)?k:"http://"+k,l.setAttribute("_src",utils.html(k)),l.href=utils.html(k),h.insertNode(l),l.parentNode.insertBefore(m,l.nextSibling),h.setStart(m,0),h.collapse(!0),g.removeAllRanges(),g.addRange(h),c.undoManger&&c.undoManger.save()}}}}}},function(){function a(a){if(3==a.nodeType)return null;if("A"==a.nodeName)return a;for(var b=a.lastChild;b;){if("A"==b.nodeName)return b;if(3==b.nodeType){if(domUtils.isWhitespace(b)){b=b.previousSibling;continue}return null}b=b.lastChild}}var b={37:1,38:1,39:1,40:1,13:1,32:1};browser.ie&&this.addListener("keyup",function(c,d){var e=this,f=d.keyCode;if(b[f]){var g=e.selection.getRange(),h=g.startContainer;if(13==f){for(;h&&!domUtils.isBody(h)&&!domUtils.isBlockElm(h);)h=h.parentNode;if(h&&!domUtils.isBody(h)&&"P"==h.nodeName){var i=h.previousSibling;if(i&&1==i.nodeType){var i=a(i);i&&!i.getAttribute("_href")&&domUtils.remove(i,!0)}}}else if(32==f)3==h.nodeType&&/^\s$/.test(h.nodeValue)&&(h=h.previousSibling,h&&"A"==h.nodeName&&!h.getAttribute("_href")&&domUtils.remove(h,!0));else if(h=domUtils.findParentByTagName(h,"a",!0),h&&!h.getAttribute("_href")){var j=g.createBookmark();domUtils.remove(h,!0),g.moveToBookmark(j).select(!0)}}})}),UE.plugins.autoheight=function(){function a(){var a=this;clearTimeout(e),f||(!a.queryCommandState||a.queryCommandState&&1!=a.queryCommandState("source"))&&(e=setTimeout(function(){for(var b=a.body.lastChild;b&&1!=b.nodeType;)b=b.previousSibling;b&&1==b.nodeType&&(b.style.clear="both",d=Math.max(domUtils.getXY(b).y+b.offsetHeight+25,Math.max(h.minFrameHeight,h.initialFrameHeight)),d!=g&&(d!==parseInt(a.iframe.parentNode.style.height)&&(a.iframe.parentNode.style.height=d+"px"),a.body.style.height=d+"px",g=d),domUtils.removeStyle(b,"clear"))},50))}var b=this;if(b.autoHeightEnabled=b.options.autoHeightEnabled!==!1,b.autoHeightEnabled){var c,d,e,f,g=0,h=b.options;b.addListener("fullscreenchanged",function(a,b){f=b}),b.addListener("destroy",function(){b.removeListener("contentchange afterinserthtml keyup mouseup",a)}),b.enableAutoHeight=function(){var b=this;if(b.autoHeightEnabled){var d=b.document;b.autoHeightEnabled=!0,c=d.body.style.overflowY,d.body.style.overflowY="hidden",b.addListener("contentchange afterinserthtml keyup mouseup",a),setTimeout(function(){a.call(b)},browser.gecko?100:0),b.fireEvent("autoheightchanged",b.autoHeightEnabled)}},b.disableAutoHeight=function(){b.body.style.overflowY=c||"",b.removeListener("contentchange",a),b.removeListener("keyup",a),b.removeListener("mouseup",a),b.autoHeightEnabled=!1,b.fireEvent("autoheightchanged",b.autoHeightEnabled)},b.on("setHeight",function(){b.disableAutoHeight()}),b.addListener("ready",function(){b.enableAutoHeight();var c;domUtils.on(browser.ie?b.body:b.document,browser.webkit?"dragover":"drop",function(){clearTimeout(c),c=setTimeout(function(){a.call(b)},100)});var d;window.onscroll=function(){ +null===d?d=this.scrollY:0==this.scrollY&&0!=d&&(b.window.scrollTo(0,0),d=null)}})}},UE.plugins.autofloat=function(){function a(){return UE.ui?1:(alert(g.autofloatMsg),0)}function b(){var a=document.body.style;a.backgroundImage='url("about:blank")',a.backgroundAttachment="fixed"}function c(){var a=domUtils.getXY(k),b=domUtils.getComputedStyle(k,"position"),c=domUtils.getComputedStyle(k,"left");k.style.width=k.offsetWidth+"px",k.style.zIndex=1*f.options.zIndex+1,k.parentNode.insertBefore(q,k),o||p&&browser.ie?("absolute"!=k.style.position&&(k.style.position="absolute"),k.style.top=(document.body.scrollTop||document.documentElement.scrollTop)-l+i+"px"):(browser.ie7Compat&&r&&(r=!1,k.style.left=domUtils.getXY(k).x-document.documentElement.getBoundingClientRect().left+2+"px"),"fixed"!=k.style.position&&(k.style.position="fixed",k.style.top=i+"px",("absolute"==b||"relative"==b)&&parseFloat(c)&&(k.style.left=a.x+"px")))}function d(){r=!0,q.parentNode&&q.parentNode.removeChild(q),k.style.cssText=j}function e(){var a=m(f.container),b=f.options.toolbarTopOffset||0;a.top<0&&a.bottom-k.offsetHeight>b?c():d()}var f=this,g=f.getLang();f.setOpt({topOffset:0});var h=f.options.autoFloatEnabled!==!1,i=f.options.topOffset;if(h){var j,k,l,m,n=UE.ui.uiUtils,o=browser.ie&&browser.version<=6,p=browser.quirks,q=document.createElement("div"),r=!0,s=utils.defer(function(){e()},browser.ie?200:100,!0);f.addListener("destroy",function(){domUtils.un(window,["scroll","resize"],e),f.removeListener("keydown",s)}),f.addListener("ready",function(){if(a(f)){if(!f.ui)return;m=n.getClientRect,k=f.ui.getDom("toolbarbox"),l=m(k).top,j=k.style.cssText,q.style.height=k.offsetHeight+"px",o&&b(),domUtils.on(window,["scroll","resize"],e),f.addListener("keydown",s),f.addListener("beforefullscreenchange",function(a,b){b&&d()}),f.addListener("fullscreenchanged",function(a,b){b||e()}),f.addListener("sourcemodechanged",function(a,b){setTimeout(function(){e()},0)}),f.addListener("clearDoc",function(){setTimeout(function(){e()},0)})}})}},UE.plugins.video=function(){function a(a,b,d,e,f,g,h){a=utils.unhtmlForUrl(a),f=utils.unhtml(f),g=utils.unhtml(g),b=parseInt(b,10)||0,d=parseInt(d,10)||0;var i;switch(h){case"image":i="';break;case"embed":i='';break;case"video":var j=a.substr(a.lastIndexOf(".")+1);"ogv"==j&&(j="ogg"),i="'}return i}function b(b,c){utils.each(b.getNodesByTagName(c?"img":"embed video"),function(b){var d=b.getAttr("class");if(d&&d.indexOf("edui-faked-video")!=-1){var e=a(c?b.getAttr("_url"):b.getAttr("src"),b.getAttr("width"),b.getAttr("height"),null,b.getStyle("float")||"",d,c?"embed":"image");b.parentNode.replaceChild(UE.uNode.createElement(e),b)}if(d&&d.indexOf("edui-upload-video")!=-1){var e=a(c?b.getAttr("_url"):b.getAttr("src"),b.getAttr("width"),b.getAttr("height"),null,b.getStyle("float")||"",d,c?"video":"image");b.parentNode.replaceChild(UE.uNode.createElement(e),b)}})}var c=this;c.addOutputRule(function(a){b(a,!0)}),c.addInputRule(function(a){b(a)}),c.commands.insertvideo={execCommand:function(b,d,e){d=utils.isArray(d)?d:[d];for(var f,g,h=[],i="tmpVedio",j=0,k=d.length;j0)return 0;for(var c in dtd.$isNotEmpty)if(dtd.$isNotEmpty.hasOwnProperty(c)&&a.getElementsByTagName(c).length)return 0;return 1},b.getWidth=function(a){return a?parseInt(domUtils.getComputedStyle(a,"width"),10):0},b.getTableCellAlignState=function(a){!utils.isArray(a)&&(a=[a]);var b={},c=["align","valign"],d=null,e=!0;return utils.each(a,function(a){return utils.each(c,function(c){if(d=a.getAttribute(c),!b[c]&&d)b[c]=d;else if(!b[c]||d!==b[c])return e=!1,!1}),e}),e?b:null},b.getTableItemsByRange=function(a){var b=a.selection.getStart();b&&b.id&&0===b.id.indexOf("_baidu_bookmark_start_")&&b.nextSibling&&(b=b.nextSibling);var c=b&&domUtils.findParentByTagName(b,["td","th"],!0),d=c&&c.parentNode,e=b&&domUtils.findParentByTagName(b,"caption",!0),f=e?e.parentNode:d&&d.parentNode.parentNode;return{cell:c,tr:d,table:f,caption:e}},b.getUETableBySelected=function(a){var c=b.getTableItemsByRange(a).table;return c&&c.ueTable&&c.ueTable.selectedTds.length?c.ueTable:null},b.getDefaultValue=function(a,b){var c,d,e,f,g={thin:"0px",medium:"1px",thick:"2px"};if(b)return h=b.getElementsByTagName("td")[0],f=domUtils.getComputedStyle(b,"border-left-width"),c=parseInt(g[f]||f,10),f=domUtils.getComputedStyle(h,"padding-left"),d=parseInt(g[f]||f,10),f=domUtils.getComputedStyle(h,"border-left-width"),e=parseInt(g[f]||f,10),{tableBorder:c,tdPadding:d,tdBorder:e};b=a.document.createElement("table"),b.insertRow(0).insertCell(0).innerHTML="xxx",a.body.appendChild(b);var h=b.getElementsByTagName("td")[0];return f=domUtils.getComputedStyle(b,"border-left-width"),c=parseInt(g[f]||f,10),f=domUtils.getComputedStyle(h,"padding-left"),d=parseInt(g[f]||f,10),f=domUtils.getComputedStyle(h,"border-left-width"),e=parseInt(g[f]||f,10),domUtils.remove(b),{tableBorder:c,tdPadding:d,tdBorder:e}},b.getUETable=function(a){var c=a.tagName.toLowerCase();return a="td"==c||"th"==c||"caption"==c?domUtils.findParentByTagName(a,"table",!0):a,a.ueTable||(a.ueTable=new b(a)),a.ueTable},b.cloneCell=function(a,b,c){if(!a||utils.isString(a))return this.table.ownerDocument.createElement(a||"td");var d=domUtils.hasClass(a,"selectTdClass");d&&domUtils.removeClasses(a,"selectTdClass");var e=a.cloneNode(!0);return b&&(e.rowSpan=e.colSpan=1),!c&&domUtils.removeAttributes(e,"width height"),!c&&domUtils.removeAttributes(e,"style"),e.style.borderLeftStyle="",e.style.borderTopStyle="",e.style.borderLeftColor=a.style.borderRightColor,e.style.borderLeftWidth=a.style.borderRightWidth,e.style.borderTopColor=a.style.borderBottomColor,e.style.borderTopWidth=a.style.borderBottomWidth,d&&domUtils.addClass(a,"selectTdClass"),e},b.prototype={getMaxRows:function(){for(var a,b=this.table.rows,c=1,d=0;a=b[d];d++){for(var e,f=1,g=0;e=a.cells[g++];)f=Math.max(e.rowSpan||1,f);c=Math.max(f+d,c)}return c},getMaxCols:function(){for(var a,b=this.table.rows,c=0,d={},e=0;a=b[e];e++){for(var f,g=0,h=0;f=a.cells[h++];)if(g+=f.colSpan||1,f.rowSpan&&f.rowSpan>1)for(var i=1;ithis.rowsNum-1)?null:(e=c?h?i.endRowIndex+1:g.rowIndex+g.rowSpan:h?i.beginRowIndex-1:g.rowIndex-1,f=h?i.beginColIndex:g.colIndex,this.getCell(this.indexTable[e][f].rowIndex,this.indexTable[e][f].cellIndex))}catch(j){a(j)}},getSameEndPosCells:function(b,c){try{for(var d="x"===c.toLowerCase(),e=domUtils.getXY(b)[d?"x":"y"]+b["offset"+(d?"Width":"Height")],f=this.table.rows,g=null,h=[],i=0;ie&&d)break;if((b==j||e==l)&&(1==j[d?"colSpan":"rowSpan"]&&h.push(j),d))break}}return h}catch(m){a(m)}},setCellContent:function(a,b){a.innerHTML=b||(browser.ie?domUtils.fillChar:"
      ")},cloneCell:b.cloneCell,getSameStartPosXCells:function(b){try{for(var c,d=domUtils.getXY(b).x+b.offsetWidth,e=this.table.rows,f=[],g=0;gd)break;if(j==d&&1==h.colSpan){f.push(h);break}}}return f}catch(k){a(k)}},update:function(a){this.table=a||this.table,this.selectedTds=[],this.cellsRange={},this.indexTable=[];for(var b=this.table.rows,c=this.getMaxRows(),d=c-b.length,e=this.getMaxCols();d--;)this.table.insertRow(b.length);this.rowsNum=c,this.colsNum=e;for(var f=0,g=b.length;fc&&(j.rowSpan=c);for(var m=k,n=j.rowSpan||1,o=j.colSpan||1;this.indexTable[i][m];)m++;for(var p=0;p0)for(h=b;hf&&(m=Math.max(h,m));if(ee&&(l=Math.max(i,l));if(b>0)for(i=a;ig||d+b.colSpan-1>h)return null;j.push(this.getCell(c,b.cellIndex))}}return j},clearSelected:function(){b.removeSelectedClass(this.selectedTds),this.selectedTds=[],this.cellsRange={}},setSelected:function(a){var c=this.getCells(a);b.addSelectedClass(c),this.selectedTds=c,this.cellsRange=a},isFullRow:function(){var a=this.cellsRange;return a.endColIndex-a.beginColIndex+1==this.colsNum},isFullCol:function(){var a=this.cellsRange,b=this.table,c=b.getElementsByTagName("th"),d=a.endRowIndex-a.beginRowIndex+1;return c.length?d==this.rowsNum||d==this.rowsNum-1:d==this.rowsNum},getNextCell:function(b,c,d){try{var e,f,g=this.getCellInfo(b),h=this.selectedTds.length&&!d,i=this.cellsRange;return!c&&0==g.rowIndex||c&&(h?i.endRowIndex==this.rowsNum-1:g.rowIndex+g.rowSpan>this.rowsNum-1)?null:(e=c?h?i.endRowIndex+1:g.rowIndex+g.rowSpan:h?i.beginRowIndex-1:g.rowIndex-1,f=h?i.beginColIndex:g.colIndex,this.getCell(this.indexTable[e][f].rowIndex,this.indexTable[e][f].cellIndex))}catch(j){a(j)}},getPreviewCell:function(b,c){try{var d,e,f=this.getCellInfo(b),g=this.selectedTds.length,h=this.cellsRange;return!c&&(g?!h.beginColIndex:!f.colIndex)||c&&(g?h.endColIndex==this.colsNum-1:f.rowIndex>this.colsNum-1)?null:(d=c?g?h.beginRowIndex:f.rowIndex<1?0:f.rowIndex-1:g?h.beginRowIndex:f.rowIndex,e=c?g?h.endColIndex+1:f.colIndex:g?h.beginColIndex-1:f.colIndex<1?0:f.colIndex-1,this.getCell(this.indexTable[d][e].rowIndex,this.indexTable[d][e].cellIndex))}catch(i){a(i)}},moveContent:function(a,c){if(!b.isEmptyBlock(c)){if(b.isEmptyBlock(a))return void(a.innerHTML=c.innerHTML);var d=a.lastChild;for(3!=d.nodeType&&dtd.$block[d.tagName]||a.appendChild(a.ownerDocument.createElement("br"));d=c.firstChild;)a.appendChild(d)}},mergeRight:function(a){var b=this.getCellInfo(a),c=b.colIndex+b.colSpan,d=this.indexTable[b.rowIndex][c],e=this.getCell(d.rowIndex,d.cellIndex);a.colSpan=b.colSpan+d.colSpan,a.removeAttribute("width"),this.moveContent(a,e),this.deleteCell(e,d.rowIndex),this.update()},mergeDown:function(a){var b=this.getCellInfo(a),c=b.rowIndex+b.rowSpan,d=this.indexTable[c][b.colIndex],e=this.getCell(d.rowIndex,d.cellIndex);a.rowSpan=b.rowSpan+d.rowSpan,a.removeAttribute("height"),this.moveContent(a,e),this.deleteCell(e,d.rowIndex),this.update()},mergeRange:function(){var a=this.cellsRange,b=this.getCell(a.beginRowIndex,this.indexTable[a.beginRowIndex][a.beginColIndex].cellIndex);if("TH"==b.tagName&&a.endRowIndex!==a.beginRowIndex){var c=this.indexTable,d=this.getCellInfo(b);b=this.getCell(1,c[1][d.colIndex].cellIndex),a=this.getCellsRange(b,this.getCell(c[this.rowsNum-1][d.colIndex].rowIndex,c[this.rowsNum-1][d.colIndex].cellIndex))}for(var e,f=this.getCells(a),g=0;e=f[g++];)e!==b&&(this.moveContent(b,e),this.deleteCell(e));if(b.rowSpan=a.endRowIndex-a.beginRowIndex+1,b.rowSpan>1&&b.removeAttribute("height"),b.colSpan=a.endColIndex-a.beginColIndex+1,b.colSpan>1&&b.removeAttribute("width"),b.rowSpan==this.rowsNum&&1!=b.colSpan&&(b.colSpan=1),b.colSpan==this.colsNum&&1!=b.rowSpan){var h=b.parentNode.rowIndex;if(this.table.deleteRow)for(var g=h+1,i=h+1,j=b.rowSpan;g1&&g.rowIndex==a){var i=h.cloneNode(!0);i.rowSpan=h.rowSpan-1,i.innerHTML="",h.rowSpan=1;var j,k=a+1,l=this.table.rows[k],m=this.getPreviewMergedCellsNum(k,f)-e;m1?l.colSpan--:c[h].deleteCell(j.cellIndex),h+=j.rowSpan||1}}this.table.setAttribute("width",d-e),this.update()},splitToCells:function(a){var b=this,c=this.splitToRows(a);utils.each(c,function(a){b.splitToCols(a)})},splitToRows:function(a){var b=this.getCellInfo(a),c=b.rowIndex,d=b.colIndex,e=[];a.rowSpan=1,e.push(a);for(var f=c,g=c+b.rowSpan;f");for(var g=0;g'+(browser.ie&&browser.version<11?domUtils.fillChar:"
      ")+"");c.push("")}return"
      "+c.join("")+"
      "}b||(b=utils.extend({},{numCols:this.options.defaultCols,numRows:this.options.defaultRows,tdvalign:this.options.tdvalign}));var d=this,e=this.selection.getRange(),f=e.startContainer,h=domUtils.findParent(f,function(a){return domUtils.isBlockElm(a)},!0)||d.body,i=g(d),j=h.offsetWidth,k=Math.floor(j/b.numCols-2*i.tdPadding-i.tdBorder);!b.tdvalign&&(b.tdvalign=d.options.tdvalign),d.execCommand("inserthtml",c(b,k))}},UE.commands.insertparagraphbeforetable={queryCommandState:function(){return e(this).cell?0:-1},execCommand:function(){var a=e(this).table;if(a){var b=this.document.createElement("p");b.innerHTML=browser.ie?" ":"
      ",a.parentNode.insertBefore(b,a),this.selection.getRange().setStart(b,0).setCursor()}}},UE.commands.deletetable={queryCommandState:function(){var a=this.selection.getRange();return domUtils.findParentByTagName(a.startContainer,"table",!0)?0:-1},execCommand:function(a,b){var c=this.selection.getRange();if(b=b||domUtils.findParentByTagName(c.startContainer,"table",!0)){var d=b.nextSibling;d||(d=domUtils.createElement(this.document,"p",{innerHTML:browser.ie?domUtils.fillChar:"
      "}),b.parentNode.insertBefore(d,b)),domUtils.remove(b),c=this.selection.getRange(),3==d.nodeType?c.setStartBefore(d):c.setStart(d,0),c.setCursor(!1,!0),this.fireEvent("tablehasdeleted")}}},UE.commands.cellalign={queryCommandState:function(){return c(this).length?0:-1},execCommand:function(a,b){var d=c(this);if(d.length)for(var e,f=0;e=d[f++];)e.setAttribute("align",b)}},UE.commands.cellvalign={queryCommandState:function(){return c(this).length?0:-1},execCommand:function(a,b){var d=c(this);if(d.length)for(var e,f=0;e=d[f++];)e.setAttribute("vAlign",b)}},UE.commands.insertcaption={queryCommandState:function(){var a=e(this).table;return a&&0==a.getElementsByTagName("caption").length?1:-1},execCommand:function(){var a=e(this).table;if(a){var b=this.document.createElement("caption");b.innerHTML=browser.ie?domUtils.fillChar:"
      ",a.insertBefore(b,a.firstChild);var c=this.selection.getRange();c.setStart(b,0).setCursor()}}},UE.commands.deletecaption={queryCommandState:function(){var a=this.selection.getRange(),b=domUtils.findParentByTagName(a.startContainer,"table");return b?0==b.getElementsByTagName("caption").length?-1:1:-1},execCommand:function(){var a=this.selection.getRange(),b=domUtils.findParentByTagName(a.startContainer,"table");if(b){domUtils.remove(b.getElementsByTagName("caption")[0]);var c=this.selection.getRange();c.setStart(b.rows[0].cells[0],0).setCursor()}}},UE.commands.inserttitle={queryCommandState:function(){var a=e(this).table;if(a){var b=a.rows[0];return"th"!=b.cells[b.cells.length-1].tagName.toLowerCase()?0:-1}return-1},execCommand:function(){var a=e(this).table;a&&h(a).insertRow(0,"th");var b=a.getElementsByTagName("th")[0];this.selection.getRange().setStart(b,0).setCursor(!1,!0)}},UE.commands.deletetitle={queryCommandState:function(){var a=e(this).table;if(a){var b=a.rows[0];return"th"==b.cells[b.cells.length-1].tagName.toLowerCase()?0:-1}return-1},execCommand:function(){var a=e(this).table;a&&domUtils.remove(a.rows[0]);var b=a.getElementsByTagName("td")[0];this.selection.getRange().setStart(b,0).setCursor(!1,!0)}},UE.commands.inserttitlecol={queryCommandState:function(){var a=e(this).table;if(a){var b=a.rows[a.rows.length-1];return b.getElementsByTagName("th").length?-1:0}return-1},execCommand:function(b){var c=e(this).table;c&&h(c).insertCol(0,"th"),a(c,this);var d=c.getElementsByTagName("th")[0];this.selection.getRange().setStart(d,0).setCursor(!1,!0)}},UE.commands.deletetitlecol={queryCommandState:function(){var a=e(this).table;if(a){var b=a.rows[a.rows.length-1];return b.getElementsByTagName("th").length?0:-1}return-1},execCommand:function(){var b=e(this).table;if(b)for(var c=0;c=f.colsNum)return-1;var j=f.indexTable[g.rowIndex][i],k=c.rows[j.rowIndex].cells[j.cellIndex];return k&&d.tagName==k.tagName&&j.rowIndex==g.rowIndex&&j.rowSpan==g.rowSpan?0:-1},execCommand:function(a){var b=this.selection.getRange(),c=b.createBookmark(!0),d=e(this).cell,f=h(d);f.mergeRight(d),b.moveToBookmark(c).select()}},UE.commands.mergedown={queryCommandState:function(a){var b=e(this),c=b.table,d=b.cell;if(!c||!d)return-1;var f=h(c);if(f.selectedTds.length)return-1;var g=f.getCellInfo(d),i=g.rowIndex+g.rowSpan;if(i>=f.rowsNum)return-1;var j=f.indexTable[i][g.colIndex],k=c.rows[j.rowIndex].cells[j.cellIndex];return k&&d.tagName==k.tagName&&j.colIndex==g.colIndex&&j.colSpan==g.colSpan?0:-1},execCommand:function(){var a=this.selection.getRange(),b=a.createBookmark(!0),c=e(this).cell,d=h(c);d.mergeDown(c),a.moveToBookmark(b).select()}},UE.commands.mergecells={queryCommandState:function(){return f(this)?0:-1},execCommand:function(){var a=f(this);if(a&&a.selectedTds.length){var b=a.selectedTds[0];a.mergeRange();var c=this.selection.getRange();domUtils.isEmptyBlock(b)?c.setStart(b,0).collapse(!0):c.selectNodeContents(b),c.select()}}},UE.commands.insertrow={queryCommandState:function(){var a=e(this),b=a.cell;return b&&("TD"==b.tagName||"TH"==b.tagName&&a.tr!==a.table.rows[0])&&h(a.table).rowsNum0?-1:b&&(b.colSpan>1||b.rowSpan>1)?0:-1},execCommand:function(){var a=this.selection.getRange(),b=a.createBookmark(!0),c=e(this).cell,d=h(c);d.splitToCells(c),a.moveToBookmark(b).select()}},UE.commands.splittorows={queryCommandState:function(){var a=e(this),b=a.cell;if(!b)return-1;var c=h(a.table);return c.selectedTds.length>0?-1:b&&b.rowSpan>1?0:-1},execCommand:function(){var a=this.selection.getRange(),b=a.createBookmark(!0),c=e(this).cell,d=h(c);d.splitToRows(c),a.moveToBookmark(b).select()}},UE.commands.splittocols={queryCommandState:function(){var a=e(this),b=a.cell;if(!b)return-1;var c=h(a.table);return c.selectedTds.length>0?-1:b&&b.colSpan>1?0:-1},execCommand:function(){var a=this.selection.getRange(),b=a.createBookmark(!0),c=e(this).cell,d=h(c);d.splitToCols(c),a.moveToBookmark(b).select()}},UE.commands.adaptbytext=UE.commands.adaptbywindow={queryCommandState:function(){return e(this).table?0:-1},execCommand:function(b){var c=e(this),d=c.table;if(d)if("adaptbywindow"==b)a(d,this);else{var f=domUtils.getElementsByTagName(d,"td th");utils.each(f,function(a){a.removeAttribute("width")}),d.removeAttribute("width")}}},UE.commands.averagedistributecol={queryCommandState:function(){var a=f(this);return a&&(a.isFullRow()||a.isFullCol())?0:-1},execCommand:function(a){function b(){var a,b=e.table,c=0,f=0,h=g(d,b);if(e.isFullRow())c=b.offsetWidth,f=e.colsNum;else for(var i,j=e.cellsRange.beginColIndex,k=e.cellsRange.endColIndex,l=j;l<=k;)i=e.selectedTds[l],c+=i.offsetWidth,l+=i.colSpan,f+=1;return a=Math.ceil(c/f)-2*h.tdBorder-2*h.tdPadding}function c(a){utils.each(domUtils.getElementsByTagName(e.table,"th"),function(a){a.setAttribute("width","")});var b=e.isFullRow()?domUtils.getElementsByTagName(e.table,"td"):e.selectedTds;utils.each(b,function(b){1==b.colSpan&&b.setAttribute("width",a)})}var d=this,e=f(d);e&&e.selectedTds.length&&c(b())}},UE.commands.averagedistributerow={queryCommandState:function(){var a=f(this);return a?a.selectedTds&&/th/gi.test(a.selectedTds[0].tagName)?-1:a.isFullRow()||a.isFullCol()?0:-1:-1},execCommand:function(a){function b(){var a,b,c=0,f=e.table,h=g(d,f),i=parseInt(domUtils.getComputedStyle(f.getElementsByTagName("td")[0],"padding-top"));if(e.isFullCol()){var j,k,l=domUtils.getElementsByTagName(f,"caption"),m=domUtils.getElementsByTagName(f,"th");l.length>0&&(j=l[0].offsetHeight),m.length>0&&(k=m[0].offsetHeight),c=f.offsetHeight-(j||0)-(k||0),b=0==m.length?e.rowsNum:e.rowsNum-1}else{for(var n=e.cellsRange.beginRowIndex,o=e.cellsRange.endRowIndex,p=0,q=domUtils.getElementsByTagName(f,"tr"),r=n;r<=o;r++)c+=q[r].offsetHeight,p+=1;b=p}return a=browser.ie&&browser.version<9?Math.ceil(c/b):Math.ceil(c/b)-2*h.tdBorder-2*i}function c(a){var b=e.isFullCol()?domUtils.getElementsByTagName(e.table,"td"):e.selectedTds;utils.each(b,function(b){1==b.rowSpan&&b.setAttribute("height",a)})}var d=this,e=f(d);e&&e.selectedTds.length&&c(b())}},UE.commands.cellalignment={queryCommandState:function(){return e(this).table?0:-1},execCommand:function(a,b){var c=this,d=f(c);if(d)utils.each(d.selectedTds,function(a){domUtils.setAttributes(a,b)});else{var e=c.selection.getStart(),g=e&&domUtils.findParentByTagName(e,["td","th","caption"],!0);/caption/gi.test(g.tagName)?(g.style.textAlign=b.align,g.style.verticalAlign=b.vAlign):domUtils.setAttributes(g,b),c.selection.getRange().setCursor(!0)}},queryCommandValue:function(a){var b=e(this).cell;if(b||(b=c(this)[0]),b){var d=UE.UETable.getUETable(b).selectedTds;return!d.length&&(d=b),UE.UETable.getTableCellAlignState(d)}return null}},UE.commands.tablealignment={queryCommandState:function(){return browser.ie&&browser.version<8?-1:e(this).table?0:-1},execCommand:function(a,b){var c=this,d=c.selection.getStart(),e=d&&domUtils.findParentByTagName(d,["table"],!0);e&&e.setAttribute("align",b)}},UE.commands.edittable={queryCommandState:function(){return e(this).table?0:-1},execCommand:function(a,b){var c=this.selection.getRange(),d=domUtils.findParentByTagName(c.startContainer,"table");if(d){var e=domUtils.getElementsByTagName(d,"td").concat(domUtils.getElementsByTagName(d,"th"),domUtils.getElementsByTagName(d,"caption"));utils.each(e,function(a){a.style.borderColor=b})}}},UE.commands.edittd={queryCommandState:function(){return e(this).table?0:-1},execCommand:function(a,b){var c=this,d=f(c);if(d)utils.each(d.selectedTds,function(a){a.style.backgroundColor=b});else{var e=c.selection.getStart(),g=e&&domUtils.findParentByTagName(e,["td","th","caption"],!0);g&&(g.style.backgroundColor=b)}}},UE.commands.settablebackground={queryCommandState:function(){return c(this).length>1?0:-1},execCommand:function(a,b){var d,e;d=c(this),e=h(d[0]),e.setBackground(d,b)}},UE.commands.cleartablebackground={queryCommandState:function(){var a=c(this);if(!a.length)return-1;for(var b,d=0;b=a[d++];)if(""!==b.style.backgroundColor)return 0;return-1},execCommand:function(){var a=c(this),b=h(a[0]);b.removeBackground(a)}},UE.commands.interlacetable=UE.commands.uninterlacetable={queryCommandState:function(a){var b=e(this).table;if(!b)return-1;var c=b.getAttribute("interlaced");return"interlacetable"==a?"enabled"===c?-1:0:c&&"disabled"!==c?0:-1},execCommand:function(a,b){var c=e(this).table;"interlacetable"==a?(c.setAttribute("interlaced","enabled"),this.fireEvent("interlacetable",c,b)):(c.setAttribute("interlaced","disabled"),this.fireEvent("uninterlacetable",c))}},UE.commands.setbordervisible={queryCommandState:function(a){var b=e(this).table;return b?0:-1},execCommand:function(){var a=e(this).table;utils.each(domUtils.getElementsByTagName(a,"td"),function(a){a.style.borderWidth="1px",a.style.borderStyle="solid"})}}}(),UE.plugins.table=function(){function a(a){}function b(a,b){c(a,"width",!0),c(a,"height",!0)}function c(a,b,c){a.style[b]&&(c&&a.setAttribute(b,parseInt(a.style[b],10)),a.style[b]="")}function d(a){if("TD"==a.tagName||"TH"==a.tagName)return a;var b;return(b=domUtils.findParentByTagName(a,"td",!0)||domUtils.findParentByTagName(a,"th",!0))?b:null}function e(a){var b=new RegExp(domUtils.fillChar,"g");if(a[browser.ie?"innerText":"textContent"].replace(/^\s*$/,"").replace(b,"").length>0)return 0;for(var c in dtd.$isNotEmpty)if(a.getElementsByTagName(c).length)return 0;return 1}function f(a){return a.pageX||a.pageY?{x:a.pageX,y:a.pageY}:{x:a.clientX+N.document.body.scrollLeft-N.document.body.clientLeft,y:a.clientY+N.document.body.scrollTop-N.document.body.clientTop}}function g(b){if(!A())try{var c,e=d(b.target||b.srcElement);if(R&&(N.body.style.webkitUserSelect="none",(Math.abs(V.x-b.clientX)>T||Math.abs(V.y-b.clientY)>T)&&(t(),R=!1,U=0,v(b))),ca&&ha)return U=0,N.body.style.webkitUserSelect="none",N.selection.getNative()[browser.ie9below?"empty":"removeAllRanges"](),c=f(b),m(N,!0,ca,c,e),void("h"==ca?ga.style.left=k(ha,b)+"px":"v"==ca&&(ga.style.top=l(ha,b)+"px"));if(e){if(N.fireEvent("excludetable",e)===!0)return;c=f(b);var g=n(e,c),i=domUtils.findParentByTagName(e,"table",!0);if(j(i,e,b,!0)){if(N.fireEvent("excludetable",i)===!0)return;N.body.style.cursor="url("+N.options.cursorpath+"h.png),pointer"}else if(j(i,e,b)){if(N.fireEvent("excludetable",i)===!0)return;N.body.style.cursor="url("+N.options.cursorpath+"v.png),pointer"}else{N.body.style.cursor="text";/\d/.test(g)&&(g=g.replace(/\d/,""),e=Y(e).getPreviewCell(e,"v"==g)),m(N,!!e&&!!g,e?g:"",c,e)}}else h(!1,i,N)}catch(o){a(o)}}function h(a,b,c){if(a)i(b,c);else{if(fa)return;la=setTimeout(function(){!fa&&ea&&ea.parentNode&&ea.parentNode.removeChild(ea)},2e3)}}function i(a,b){function c(c,d){clearTimeout(g),g=setTimeout(function(){b.fireEvent("tableClicked",a,d)},300)}function d(c){clearTimeout(g);var d=Y(a),e=a.rows[0].cells[0],f=d.getLastCell(),h=d.getCellsRange(e,f);b.selection.getRange().setStart(e,0).setCursor(!1,!0),d.setSelected(h)}var e=domUtils.getXY(a),f=a.ownerDocument;if(ea&&ea.parentNode)return ea;ea=f.createElement("div"),ea.contentEditable=!1,ea.innerHTML="",ea.style.cssText="width:15px;height:15px;background-image:url("+b.options.UEDITOR_HOME_URL+"dialogs/table/dragicon.png);position: absolute;cursor:move;top:"+(e.y-15)+"px;left:"+e.x+"px;",domUtils.unSelectable(ea),ea.onmouseover=function(a){fa=!0},ea.onmouseout=function(a){fa=!1},domUtils.on(ea,"click",function(a,b){c(b,this)}),domUtils.on(ea,"dblclick",function(a,b){d(b)}),domUtils.on(ea,"dragstart",function(a,b){domUtils.preventDefault(b)});var g;f.body.appendChild(ea)}function j(a,b,c,d){var e=f(c),g=n(b,e);if(d){var h=a.getElementsByTagName("caption")[0],i=h?h.offsetHeight:0;return"v1"==g&&e.y-domUtils.getXY(a).y-i<8}return"h1"==g&&e.x-domUtils.getXY(a).x<8}function k(a,b){var c=Y(a);if(c){var d=c.getSameEndPosCells(a,"x")[0],e=c.getSameStartPosXCells(a)[0],g=f(b).x,h=(d?domUtils.getXY(d).x:domUtils.getXY(c.table).x)+20,i=e?domUtils.getXY(e).x+e.offsetWidth-20:N.body.offsetWidth+5||parseInt(domUtils.getComputedStyle(N.body,"width"),10);return h+=Q,i-=Q,gi?i:g}}function l(b,c){try{var d=domUtils.getXY(b).y,e=f(c).y;return ek[c]?(a=!1,!1):void l.push(d)});var b=a?l:k;utils.each(i,function(a,c){a.width=b[c]-G()})},0)}}}}function q(a){if(_(domUtils.getElementsByTagName(N.body,"td th")),utils.each(N.document.getElementsByTagName("table"),function(a){a.ueTable=null}),aa=M(N,a)){var b=domUtils.findParentByTagName(aa,"table",!0);ut=Y(b),ut&&ut.clearSelected(),da?r(a):(N.document.body.style.webkitUserSelect="",ia=!0,N.addListener("mouseover",x))}}function r(a){browser.ie&&(a=u(a)),t(),R=!0,O=setTimeout(function(){v(a)},W)}function s(a,b){for(var c=[],d=null,e=0,f=a.length;e0&&U--},W),2===U))return U=0,void p(b);if(2!=b.button){var c=this,d=c.selection.getRange(),e=domUtils.findParentByTagName(d.startContainer,"table",!0),f=domUtils.findParentByTagName(d.endContainer,"table",!0);if((e||f)&&(e===f?(e=domUtils.findParentByTagName(d.startContainer,["td","th","caption"],!0),f=domUtils.findParentByTagName(d.endContainer,["td","th","caption"],!0),e!==f&&c.selection.clearRange()):c.selection.clearRange()),ia=!1,c.document.body.style.webkitUserSelect="",ca&&ha&&(c.selection.getNative()[browser.ie9below?"empty":"removeAllRanges"](),U=0,ga=c.document.getElementById("ue_tableDragLine"))){var g=domUtils.getXY(ha),h=domUtils.getXY(ga);switch(ca){case"h":z(ha,h.x-g.x);break;case"v":B(ha,h.y-g.y-ha.offsetHeight)}return ca="",ha=null,I(c),void c.fireEvent("saveScene")}if(aa){var i=Y(aa),j=i?i.selectedTds[0]:null;if(j)d=new dom.Range(c.document),domUtils.isEmptyBlock(j)?d.setStart(j,0).setCursor(!1,!0):d.selectNodeContents(j).shrinkBoundary().setCursor(!1,!0);else if(d=c.selection.getRange().shrinkBoundary(),!d.collapsed){var e=domUtils.findParentByTagName(d.startContainer,["td","th"],!0),f=domUtils.findParentByTagName(d.endContainer,["td","th"],!0);(e&&!f||!e&&f||e&&f&&e!==f)&&d.setCursor(!1,!0)}aa=null,c.removeListener("mouseover",x)}else{var k=domUtils.findParentByTagName(b.target||b.srcElement,"td",!0);if(k||(k=domUtils.findParentByTagName(b.target||b.srcElement,"th",!0)),k&&("TD"==k.tagName||"TH"==k.tagName)){if(c.fireEvent("excludetable",k)===!0)return;d=new dom.Range(c.document),d.setStart(k,0).setCursor(!1,!0)}}c._selectionChange(250,b)}}}function x(a,b){if(!A()){var c=this,d=b.target||b.srcElement;if(ba=domUtils.findParentByTagName(d,"td",!0)||domUtils.findParentByTagName(d,"th",!0),aa&&ba&&("TD"==aa.tagName&&"TD"==ba.tagName||"TH"==aa.tagName&&"TH"==ba.tagName)&&domUtils.findParentByTagName(aa,"table")==domUtils.findParentByTagName(ba,"table")){var e=Y(ba);if(aa!=ba){c.document.body.style.webkitUserSelect="none",c.selection.getNative()[browser.ie9below?"empty":"removeAllRanges"]();var f=e.getCellsRange(aa,ba);e.setSelected(f)}else c.document.body.style.webkitUserSelect="",e.clearSelected()}b.preventDefault?b.preventDefault():b.returnValue=!1}}function y(a,b,c){var d=parseInt(domUtils.getComputedStyle(a,"line-height"),10),e=c+b;b=ef?(c&&g.push({left:a}),!1):void 0})}),g}function D(a,b,c){if(a-=G(),a<0)return 0;a-=E(b);var d=a<0?"left":"right";return a=Math.abs(a),utils.each(c,function(b){var c=b[d];c&&(a=Math.min(a,E(c)-Q))}),a=a<0?0:a,"left"===d?-a:a}function E(a){var b=0,b=a.offsetWidth-G();a.nextSibling||(b-=F(a)),b=b<0?0:b;try{a.width=b}catch(c){}return b}function F(a){if(tab=domUtils.findParentByTagName(a,"table",!1),void 0===tab.offsetVal){var b=a.previousSibling;b?tab.offsetVal=a.offsetWidth-b.offsetWidth===X.borderWidth?X.borderWidth:0:tab.offsetVal=0}return tab.offsetVal}function G(){if(void 0===X.tabcellSpace){var a=N.document.createElement("table"),b=N.document.createElement("tbody"),c=N.document.createElement("tr"),d=N.document.createElement("td"),e=null;d.style.cssText="border: 0;",d.width=1,c.appendChild(d),c.appendChild(e=d.cloneNode(!1)),b.appendChild(c),a.appendChild(b),a.style.cssText="visibility: hidden;",N.body.appendChild(a),X.paddingSpace=d.offsetWidth-1;var f=a.offsetWidth;d.style.cssText="",e.style.cssText="",X.borderWidth=(a.offsetWidth-f)/3,X.tabcellSpace=X.paddingSpace+X.borderWidth,N.body.removeChild(a)}return G=function(){return X.tabcellSpace},X.tabcellSpace}function H(a,b){ia||(ga=a.document.createElement("div"),domUtils.setAttributes(ga,{id:"ue_tableDragLine",unselectable:"on",contenteditable:!1,onresizestart:"return false",ondragstart:"return false",onselectstart:"return false",style:"background-color:blue;position:absolute;padding:0;margin:0;background-image:none;border:0px none;opacity:0;filter:alpha(opacity=0)"}),a.body.appendChild(ga))}function I(a){if(!ia)for(var b;b=a.document.getElementById("ue_tableDragLine");)domUtils.remove(b)}function J(a,b){if(b){var c,d=domUtils.findParentByTagName(b,"table"),e=d.getElementsByTagName("caption"),f=d.offsetWidth,g=d.offsetHeight-(e.length>0?e[0].offsetHeight:0),h=domUtils.getXY(d),i=domUtils.getXY(b);switch(a){case"h":c="height:"+g+"px;top:"+(h.y+(e.length>0?e[0].offsetHeight:0))+"px;left:"+(i.x+b.offsetWidth),ga.style.cssText=c+"px;position: absolute;display:block;background-color:blue;width:1px;border:0; color:blue;opacity:.3;filter:alpha(opacity=30)";break;case"v":c="width:"+f+"px;left:"+h.x+"px;top:"+(i.y+b.offsetHeight),ga.style.cssText=c+"px;overflow:hidden;position: absolute;display:block;background-color:blue;height:1px;border:0;color:blue;opacity:.2;filter:alpha(opacity=20)"}}}function K(a,b){for(var c,d,e=domUtils.getElementsByTagName(a.body,"table"),f=0;d=e[f++];){var g=domUtils.getElementsByTagName(d,"td");g[0]&&(b?(c=g[0].style.borderColor.replace(/\s/g,""),/(#ffffff)|(rgb\(255,255,255\))/gi.test(c)&&domUtils.addClass(d,"noBorderTable")):domUtils.removeClasses(d,"noBorderTable"))}}function L(a,b,c){var d=a.body;return d.offsetWidth-(b?2*parseInt(domUtils.getComputedStyle(d,"margin-left"),10):0)-2*c.tableBorder-(a.options.offsetWidth||0)}function M(a,b){var c=domUtils.findParentByTagName(b.target||b.srcElement,["td","th"],!0),d=null;if(!c)return null;if(d=n(c,f(b)),!c)return null;if("h1"===d&&c.previousSibling){var e=domUtils.getXY(c),g=c.offsetWidth;Math.abs(e.x+g-b.clientX)>g/3&&(c=c.previousSibling)}else if("v1"===d&&c.parentNode.previousSibling){var e=domUtils.getXY(c),h=c.offsetHeight;Math.abs(e.y+h-b.clientY)>h/3&&(c=c.parentNode.previousSibling.firstChild)}return c&&a.fireEvent("excludetable",c)!==!0?c:null}var N=this,O=null,P=null,Q=5,R=!1,S=5,T=10,U=0,V=null,W=360,X=UE.UETable,Y=function(a){return X.getUETable(a)},Z=function(a){return X.getUETableBySelected(a)},$=function(a,b){return X.getDefaultValue(a,b)},_=function(a){return X.removeSelectedClass(a)};N.ready(function(){var a=this,b=a.selection.getText;a.selection.getText=function(){var c=Z(a);if(c){var d="";return utils.each(c.selectedTds,function(a){d+=a[browser.ie?"innerText":"textContent"]}),d}return b.call(a.selection)}});var aa=null,ba=null,ca="",da=!1,ea=null,fa=!1,ga=null,ha=null,ia=!1,ja=!0;N.setOpt({maxColNum:20,maxRowNum:100,defaultCols:5,defaultRows:5,tdvalign:"top",cursorpath:N.options.UEDITOR_HOME_URL+"themes/default/images/cursor_",tableDragable:!1,classList:["ue-table-interlace-color-single","ue-table-interlace-color-double"]}),N.getUETable=Y;var ka={deletetable:1,inserttable:1,cellvalign:1,insertcaption:1,deletecaption:1,inserttitle:1,deletetitle:1,mergeright:1,mergedown:1,mergecells:1,insertrow:1,insertrownext:1,deleterow:1,insertcol:1,insertcolnext:1,deletecol:1,splittocells:1,splittorows:1,splittocols:1,adaptbytext:1,adaptbywindow:1,adaptbycustomer:1,insertparagraph:1,insertparagraphbeforetable:1,averagedistributecol:1,averagedistributerow:1};N.ready(function(){utils.cssRule("table",".selectTdClass{background-color:#edf5fa !important}table.noBorderTable td,table.noBorderTable th,table.noBorderTable caption{border:1px dashed #ddd !important}table{margin-bottom:10px;border-collapse:collapse;display:table;}td,th{padding: 5px 10px;border: 1px solid #DDD;}caption{border:1px dashed #DDD;border-bottom:0;padding:3px;text-align:center;}th{border-top:1px solid #BBB;background-color:#F7F7F7;}table tr.firstRow th{border-top-width:2px;}.ue-table-interlace-color-single{ background-color: #fcfcfc; } .ue-table-interlace-color-double{ background-color: #f7faff; }td p{margin:0;padding:0;}",N.document);var a,c,f;N.addListener("keydown",function(b,d){var g=this,h=d.keyCode||d.which;if(8==h){var i=Z(g);i&&i.selectedTds.length&&(i.isFullCol()?g.execCommand("deletecol"):i.isFullRow()?g.execCommand("deleterow"):g.fireEvent("delcells"),domUtils.preventDefault(d));var j=domUtils.findParentByTagName(g.selection.getStart(),"caption",!0),k=g.selection.getRange();if(k.collapsed&&j&&e(j)){g.fireEvent("saveScene");var l=j.parentNode;domUtils.remove(j),l&&k.setStart(l.rows[0].cells[0],0).setCursor(!1,!0),g.fireEvent("saveScene")}}if(46==h&&(i=Z(g))){g.fireEvent("saveScene");for(var m,n=0;m=i.selectedTds[n++];)domUtils.fillNode(g.document,m);g.fireEvent("saveScene"),domUtils.preventDefault(d)}if(13==h){var o=g.selection.getRange(),j=domUtils.findParentByTagName(o.startContainer,"caption",!0);if(j){var l=domUtils.findParentByTagName(j,"table");return o.collapsed?j&&o.setStart(l.rows[0].cells[0],0).setCursor(!1,!0):(o.deleteContents(),g.fireEvent("saveScene")),void domUtils.preventDefault(d)}if(o.collapsed){var l=domUtils.findParentByTagName(o.startContainer,"table");if(l){var p=l.rows[0].cells[0],q=domUtils.findParentByTagName(g.selection.getStart(),["td","th"],!0),r=l.previousSibling;if(p===q&&(!r||1==r.nodeType&&"TABLE"==r.tagName)&&domUtils.isStartInblock(o)){var s=domUtils.findParent(g.selection.getStart(),function(a){return domUtils.isBlockElm(a)},!0);s&&(/t(h|d)/i.test(s.tagName)||s===q.firstChild)&&(g.execCommand("insertparagraphbeforetable"),domUtils.preventDefault(d))}}}}if((d.ctrlKey||d.metaKey)&&"67"==d.keyCode){a=null;var i=Z(g);if(i){var t=i.selectedTds;c=i.isFullCol(),f=i.isFullRow(),a=[[i.cloneCell(t[0],null,!0)]];for(var m,n=1;m=t[n];n++)m.parentNode!==t[n-1].parentNode?a.push([i.cloneCell(m,null,!0)]):a[a.length-1].push(i.cloneCell(m,null,!0))}}}),N.addListener("tablehasdeleted",function(){m(this,!1,"",null),ea&&domUtils.remove(ea)}),N.addListener("beforepaste",function(d,g){var h=this,i=h.selection.getRange();if(domUtils.findParentByTagName(i.startContainer,"caption",!0)){var j=h.document.createElement("div");return j.innerHTML=g.html,void(g.html=j[browser.ie9below?"innerText":"textContent"])}var k=Z(h);if(a){h.fireEvent("saveScene");var l,m,i=h.selection.getRange(),n=domUtils.findParentByTagName(i.startContainer,["td","th"],!0);if(n){var o=Y(n);if(f){var p=o.getCellInfo(n).rowIndex;"TH"==n.tagName&&p++;for(var q,r=0;q=a[r++];){for(var s,t=o.insertRow(p++,"td"),u=0;s=q[u];u++){var v=t.cells[u];v||(v=t.insertCell(u)),v.innerHTML=s.innerHTML,s.getAttribute("width")&&v.setAttribute("width",s.getAttribute("width")),s.getAttribute("vAlign")&&v.setAttribute("vAlign",s.getAttribute("vAlign")),s.getAttribute("align")&&v.setAttribute("align",s.getAttribute("align")),s.style.cssText&&(v.style.cssText=s.style.cssText)}for(var s,u=0;(s=t.cells[u])&&q[u];u++)s.innerHTML=q[u].innerHTML,q[u].getAttribute("width")&&s.setAttribute("width",q[u].getAttribute("width")),q[u].getAttribute("vAlign")&&s.setAttribute("vAlign",q[u].getAttribute("vAlign")),q[u].getAttribute("align")&&s.setAttribute("align",q[u].getAttribute("align")),q[u].style.cssText&&(s.style.cssText=q[u].style.cssText)}}else{if(c){y=o.getCellInfo(n);for(var s,w=0,u=0,q=a[0];s=q[u++];)w+=s.colSpan||1;for(h.__hasEnterExecCommand=!0,r=0;r1&&(x.rowSpan=1)}var z=$(h),A=h.body.offsetWidth-(ja?2*parseInt(domUtils.getComputedStyle(h.body,"margin-left"),10):0)-2*z.tableBorder-(h.options.offsetWidth||0);h.execCommand("insertHTML",""+k.innerHTML.replace(/>\s*<").replace(/\bth\b/gi,"td")+"
      ")}return h.fireEvent("contentchange"),h.fireEvent("saveScene"),g.html="",!0}var B,j=h.document.createElement("div");j.innerHTML=g.html,B=j.getElementsByTagName("table"),domUtils.findParentByTagName(h.selection.getStart(),"table")?(utils.each(B,function(a){domUtils.remove(a)}),domUtils.findParentByTagName(h.selection.getStart(),"caption",!0)&&(j.innerHTML=j[browser.ie?"innerText":"textContent"])):utils.each(B,function(a){b(a,!0),domUtils.removeAttributes(a,["style","border"]),utils.each(domUtils.getElementsByTagName(a,"td"),function(a){e(a)&&domUtils.fillNode(h.document,a),b(a,!0)})}),g.html=j.innerHTML}),N.addListener("afterpaste",function(){utils.each(domUtils.getElementsByTagName(N.body,"table"),function(a){if(a.offsetWidth>N.body.offsetWidth){var b=$(N,a);a.style.width=N.body.offsetWidth-(ja?2*parseInt(domUtils.getComputedStyle(N.body,"margin-left"),10):0)-2*b.tableBorder-(N.options.offsetWidth||0)+"px"}})}),N.addListener("blur",function(){a=null});var i;N.addListener("keydown",function(){clearTimeout(i),i=setTimeout(function(){var a=N.selection.getRange(),b=domUtils.findParentByTagName(a.startContainer,["th","td"],!0);if(b){var c=b.parentNode.parentNode.parentNode;c.offsetWidth>c.getAttribute("width")&&(b.style.wordBreak="break-all")}},100)}),N.addListener("selectionchange",function(){m(N,!1,"",null)}),N.addListener("contentchange",function(){var a=this;if(I(a),!Z(a)){var b=a.selection.getRange(),c=b.startContainer;c=domUtils.findParentByTagName(c,["td","th"],!0),utils.each(domUtils.getElementsByTagName(a.document,"table"),function(b){a.fireEvent("excludetable",b)!==!0&&(b.ueTable=new X(b),b.onmouseover=function(){a.fireEvent("tablemouseover",b)},b.onmousemove=function(){a.fireEvent("tablemousemove",b),a.options.tableDragable&&h(!0,this,a),utils.defer(function(){a.fireEvent("contentchange",50)},!0)},b.onmouseout=function(){a.fireEvent("tablemouseout",b),m(a,!1,"",null),I(a)},b.onclick=function(b){b=a.window.event||b;var c=d(b.target||b.srcElement);if(c){var e,f=Y(c),g=f.table,h=f.getCellInfo(c),i=a.selection.getRange();if(j(g,c,b,!0)){var k=f.getCell(f.indexTable[f.rowsNum-1][h.colIndex].rowIndex,f.indexTable[f.rowsNum-1][h.colIndex].cellIndex);return void(b.shiftKey&&f.selectedTds.length?f.selectedTds[0]!==k?(e=f.getCellsRange(f.selectedTds[0],k),f.setSelected(e)):i&&i.selectNodeContents(k).select():c!==k?(e=f.getCellsRange(c,k),f.setSelected(e)):i&&i.selectNodeContents(k).select())}if(j(g,c,b)){var l=f.getCell(f.indexTable[h.rowIndex][f.colsNum-1].rowIndex,f.indexTable[h.rowIndex][f.colsNum-1].cellIndex);b.shiftKey&&f.selectedTds.length?f.selectedTds[0]!==l?(e=f.getCellsRange(f.selectedTds[0],l),f.setSelected(e)):i&&i.selectNodeContents(l).select():c!==l?(e=f.getCellsRange(c,l),f.setSelected(e)):i&&i.selectNodeContents(l).select()}}})}),K(a,!0)}}),domUtils.on(N.document,"mousemove",g),domUtils.on(N.document,"mouseout",function(a){var b=a.target||a.srcElement;"TABLE"==b.tagName&&m(N,!1,"",null)}),N.addListener("interlacetable",function(a,b,c){if(b)for(var d=this,e=b.rows,f=e.length,g=function(a,b,c){return a[b]?a[b]:c?a[b%a.length]:""},h=0;h1?k:f.getCellInfo(d).rowIndex;var g=f.getTabNextCell(d,k);g?e(g)?a.setStart(g,0).setCursor(!1,!0):a.selectNodeContents(g).select():(N.fireEvent("saveScene"),N.__hasEnterExecCommand=!0,this.execCommand("insertrownext"),N.__hasEnterExecCommand=!1,a=this.selection.getRange(),a.setStart(c.rows[c.rows.length-1].cells[0],0).setCursor(),N.fireEvent("saveScene"))}return!0}}),browser.ie&&N.addListener("selectionchange",function(){m(this,!1,"",null)}),N.addListener("keydown",function(a,b){var c=this,d=b.keyCode||b.which;if(8!=d&&46!=d){var e=!(b.ctrlKey||b.metaKey||b.shiftKey||b.altKey);e&&_(domUtils.getElementsByTagName(c.body,"td"));var f=Z(c);f&&e&&f.clearSelected()}}),N.addListener("beforegetcontent",function(){K(this,!1),browser.ie&&utils.each(this.document.getElementsByTagName("caption"),function(a){domUtils.isEmptyNode(a)&&(a.innerHTML=" ")})}),N.addListener("aftergetcontent",function(){K(this,!0)}),N.addListener("getAllHtml",function(){_(N.document.getElementsByTagName("td"))}),N.addListener("fullscreenchanged",function(a,b){if(!b){var c=this.body.offsetWidth/document.body.offsetWidth,d=domUtils.getElementsByTagName(this.body,"table");utils.each(d,function(a){if(a.offsetWidth1||c[e].getAttribute("rowspan")>1)return-1;return b?"enablesort"==a^"sortEnabled"!=b.getAttribute("data-sort")?-1:0:-1},execCommand:function(a){var b=d(this).table;b.setAttribute("data-sort","enablesort"==a?"sortEnabled":"sortDisabled"),"enablesort"==a?domUtils.addClass(b,"sortEnabled"):domUtils.removeClasses(b,"sortEnabled")}}},UE.plugins.contextmenu=function(){var a=this;if(a.setOpt("enableContextMenu",!0),a.getOpt("enableContextMenu")!==!1){var b,c=a.getLang("contextMenu"),d=a.options.contextMenu||[{label:c.selectall,cmdName:"selectall"},{label:c.cleardoc,cmdName:"cleardoc",exec:function(){confirm(c.confirmclear)&&this.execCommand("cleardoc")}},"-",{label:c.unlink,cmdName:"unlink"},"-",{group:c.paragraph,icon:"justifyjustify",subMenu:[{label:c.justifyleft,cmdName:"justify",value:"left"},{label:c.justifyright,cmdName:"justify",value:"right"},{label:c.justifycenter,cmdName:"justify",value:"center"},{label:c.justifyjustify,cmdName:"justify",value:"justify"}]},"-",{group:c.table,icon:"table",subMenu:[{label:c.inserttable,cmdName:"inserttable"},{label:c.deletetable,cmdName:"deletetable"},"-",{label:c.deleterow,cmdName:"deleterow"},{label:c.deletecol,cmdName:"deletecol"},{label:c.insertcol,cmdName:"insertcol"},{label:c.insertcolnext,cmdName:"insertcolnext"},{label:c.insertrow,cmdName:"insertrow"},{label:c.insertrownext,cmdName:"insertrownext"},"-",{label:c.insertcaption,cmdName:"insertcaption"},{label:c.deletecaption,cmdName:"deletecaption"},{label:c.inserttitle,cmdName:"inserttitle"},{label:c.deletetitle,cmdName:"deletetitle"},{label:c.inserttitlecol,cmdName:"inserttitlecol"},{label:c.deletetitlecol,cmdName:"deletetitlecol"},"-",{label:c.mergecells,cmdName:"mergecells"},{label:c.mergeright,cmdName:"mergeright"},{label:c.mergedown,cmdName:"mergedown"},"-",{label:c.splittorows,cmdName:"splittorows"},{label:c.splittocols,cmdName:"splittocols"},{label:c.splittocells,cmdName:"splittocells"},"-",{label:c.averageDiseRow,cmdName:"averagedistributerow"},{label:c.averageDisCol,cmdName:"averagedistributecol"},"-",{label:c.edittd,cmdName:"edittd",exec:function(){UE.ui.edittd&&new UE.ui.edittd(this),this.getDialog("edittd").open()}},{label:c.edittable,cmdName:"edittable",exec:function(){UE.ui.edittable&&new UE.ui.edittable(this),this.getDialog("edittable").open()}},{label:c.setbordervisible,cmdName:"setbordervisible"}]},{group:c.tablesort,icon:"tablesort",subMenu:[{label:c.enablesort,cmdName:"enablesort"},{label:c.disablesort,cmdName:"disablesort"},"-",{label:c.reversecurrent,cmdName:"sorttable",value:"reversecurrent"},{label:c.orderbyasc,cmdName:"sorttable",value:"orderbyasc"},{label:c.reversebyasc,cmdName:"sorttable",value:"reversebyasc"},{label:c.orderbynum,cmdName:"sorttable",value:"orderbynum"},{label:c.reversebynum,cmdName:"sorttable",value:"reversebynum"}]},{group:c.borderbk,icon:"borderBack",subMenu:[{label:c.setcolor,cmdName:"interlacetable",exec:function(){this.execCommand("interlacetable")}},{label:c.unsetcolor,cmdName:"uninterlacetable",exec:function(){this.execCommand("uninterlacetable")}},{label:c.setbackground,cmdName:"settablebackground",exec:function(){this.execCommand("settablebackground",{repeat:!0,colorList:["#bbb","#ccc"]})}},{label:c.unsetbackground,cmdName:"cleartablebackground",exec:function(){this.execCommand("cleartablebackground")}},{label:c.redandblue,cmdName:"settablebackground",exec:function(){this.execCommand("settablebackground",{repeat:!0,colorList:["red","blue"]})}},{label:c.threecolorgradient,cmdName:"settablebackground",exec:function(){this.execCommand("settablebackground",{repeat:!0,colorList:["#aaa","#bbb","#ccc"]})}}]},{group:c.aligntd,icon:"aligntd",subMenu:[{cmdName:"cellalignment",value:{align:"left",vAlign:"top"}},{cmdName:"cellalignment",value:{align:"center",vAlign:"top"}},{cmdName:"cellalignment",value:{align:"right",vAlign:"top"}},{cmdName:"cellalignment",value:{align:"left",vAlign:"middle"}},{cmdName:"cellalignment",value:{align:"center",vAlign:"middle"}},{cmdName:"cellalignment",value:{align:"right",vAlign:"middle"}},{cmdName:"cellalignment",value:{align:"left",vAlign:"bottom"}},{cmdName:"cellalignment",value:{align:"center",vAlign:"bottom"}},{cmdName:"cellalignment",value:{align:"right",vAlign:"bottom"}}]},{group:c.aligntable,icon:"aligntable",subMenu:[{cmdName:"tablealignment",className:"left",label:c.tableleft,value:"left"},{cmdName:"tablealignment",className:"center",label:c.tablecenter,value:"center"},{cmdName:"tablealignment",className:"right",label:c.tableright,value:"right"}]},"-",{label:c.insertparagraphbefore,cmdName:"insertparagraph",value:!0},{label:c.insertparagraphafter,cmdName:"insertparagraph"},{label:c.copy,cmdName:"copy"},{label:c.paste,cmdName:"paste"}];if(d.length){var e=UE.ui.uiUtils;a.addListener("contextmenu",function(f,g){var h=e.getViewportOffsetByEvent(g);a.fireEvent("beforeselectionchange"),b&&b.destroy();for(var i,j=0,k=[];i=d[j];j++){var l;!function(b){function d(){switch(b.icon){case"table":return a.getLang("contextMenu.table");case"justifyjustify":return a.getLang("contextMenu.paragraph");case"aligntd":return a.getLang("contextMenu.aligntd");case"aligntable":return a.getLang("contextMenu.aligntable");case"tablesort":return c.tablesort;case"borderBack":return c.borderbk;default:return""}}if("-"==b)(l=k[k.length-1])&&"-"!==l&&k.push("-");else if(b.hasOwnProperty("group")){for(var e,f=0,g=[];e=b.subMenu[f];f++)!function(b){"-"==b?(l=g[g.length-1])&&"-"!==l?g.push("-"):g.splice(g.length-1):(a.commands[b.cmdName]||UE.commands[b.cmdName]||b.query)&&(b.query?b.query():a.queryCommandState(b.cmdName))>-1&&g.push({label:b.label||a.getLang("contextMenu."+b.cmdName+(b.value||""))||"",className:"edui-for-"+b.cmdName+(b.className?" edui-for-"+b.cmdName+"-"+b.className:""),onclick:b.exec?function(){b.exec.call(a)}:function(){a.execCommand(b.cmdName,b.value)}})}(e);g.length&&k.push({label:d(),className:"edui-for-"+b.icon,subMenu:{items:g,editor:a}})}else(a.commands[b.cmdName]||UE.commands[b.cmdName]||b.query)&&(b.query?b.query.call(a):a.queryCommandState(b.cmdName))>-1&&k.push({label:b.label||a.getLang("contextMenu."+b.cmdName),className:"edui-for-"+(b.icon?b.icon:b.cmdName+(b.value||"")),onclick:b.exec?function(){b.exec.call(a)}:function(){a.execCommand(b.cmdName,b.value)}})}(i)}if("-"==k[k.length-1]&&k.pop(),b=new UE.ui.Menu({items:k,className:"edui-contextmenu",editor:a}),b.render(),b.showAt(h),a.fireEvent("aftershowcontextmenu",b),domUtils.preventDefault(g),browser.ie){var m;try{m=a.selection.getNative().createRange()}catch(n){return}if(m.item){var o=new dom.Range(a.document);o.selectNode(m.item(0)).select(!0,!0)}}}),a.addListener("aftershowcontextmenu",function(b,c){if(a.zeroclipboard){var d=c.items;for(var e in d)"edui-for-copy"==d[e].className&&a.zeroclipboard.clip(d[e].getDom())}})}}},UE.plugins.shortcutmenu=function(){var a,b=this,c=b.options.shortcutMenu||[];c.length&&(b.addListener("contextmenu mouseup",function(b,d){var e=this,f={type:b,target:d.target||d.srcElement,screenX:d.screenX,screenY:d.screenY,clientX:d.clientX,clientY:d.clientY};if(setTimeout(function(){var d=e.selection.getRange();d.collapsed!==!1&&"contextmenu"!=b||(a||(a=new baidu.editor.ui.ShortCutMenu({editor:e,items:c,theme:e.options.theme,className:"edui-shortcutmenu"}),a.render(),e.fireEvent("afterrendershortcutmenu",a)),a.show(f,!!UE.plugins.contextmenu))}),"contextmenu"==b&&(domUtils.preventDefault(d),browser.ie9below)){var g;try{g=e.selection.getNative().createRange()}catch(d){return}if(g.item){var h=new dom.Range(e.document);h.selectNode(g.item(0)).select(!0,!0)}}}),b.addListener("keydown",function(b){"keydown"==b&&a&&!a.isHidden&&a.hide()}))},UE.plugins.basestyle=function(){var a={bold:["strong","b"],italic:["em","i"],subscript:["sub"],superscript:["sup"]},b=function(a,b){return domUtils.filterNodeList(a.selection.getStartElementPath(),b)},c=this;c.addshortcutkey({Bold:"ctrl+66",Italic:"ctrl+73",Underline:"ctrl+85"}),c.addInputRule(function(a){utils.each(a.getNodesByTagName("b i"),function(a){switch(a.tagName){case"b":a.tagName="strong";break;case"i":a.tagName="em"}})});for(var d in a)!function(a,d){c.commands[a]={execCommand:function(a){var e=c.selection.getRange(),f=b(this,d);if(e.collapsed){if(f){var g=c.document.createTextNode("");e.insertNode(g).removeInlineStyle(d),e.setStartBefore(g),domUtils.remove(g)}else{var h=e.document.createElement(d[0]);"superscript"!=a&&"subscript"!=a||(g=c.document.createTextNode(""),e.insertNode(g).removeInlineStyle(["sub","sup"]).setStartBefore(g).collapse(!0)),e.insertNode(h).setStart(h,0)}e.collapse(!0)}else"superscript"!=a&&"subscript"!=a||f&&f.tagName.toLowerCase()==a||e.removeInlineStyle(["sub","sup"]),f?e.removeInlineStyle(d):e.applyInlineStyle(d[0]);e.select()},queryCommandState:function(){return b(this,d)?1:0}}}(d,a[d])},UE.plugins.elementpath=function(){var a,b,c=this;c.setOpt("elementPathEnabled",!0),c.options.elementPathEnabled&&(c.commands.elementpath={execCommand:function(d,e){var f=b[e],g=c.selection.getRange();a=1*e,g.selectNode(f).select()},queryCommandValue:function(){var c=[].concat(this.selection.getStartElementPath()).reverse(),d=[];b=c;for(var e,f=0;e=c[f];f++)if(3!=e.nodeType){var g=e.tagName.toLowerCase();if("img"==g&&e.getAttribute("anchorname")&&(g="anchor"),d[f]=g,a==f){a=-1;break}}return d}})},UE.plugins.formatmatch=function(){function a(f,g){function h(a){return m&&a.selectNode(m),a.applyInlineStyle(d[d.length-1].tagName,null,d)}if(browser.webkit)var i="IMG"==g.target.tagName?g.target:null;c.undoManger&&c.undoManger.save();var j=c.selection.getRange(),k=i||j.getClosedNode();if(b&&k&&"IMG"==k.tagName)k.style.cssText+=";float:"+(b.style.cssFloat||b.style.styleFloat||"none")+";display:"+(b.style.display||"inline"),b=null;else if(!b){var l=j.collapsed;if(l){var m=c.document.createTextNode("match");j.insertNode(m).select()}c.__hasEnterExecCommand=!0;var n=c.options.removeFormatAttributes;c.options.removeFormatAttributes="",c.execCommand("removeformat"),c.options.removeFormatAttributes=n,c.__hasEnterExecCommand=!1,j=c.selection.getRange(),d.length&&h(j),m&&j.setStartBefore(m).collapse(!0),j.select(),m&&domUtils.remove(m)}c.undoManger&&c.undoManger.save(),c.removeListener("mouseup",a),e=0}var b,c=this,d=[],e=0;c.addListener("reset",function(){d=[],e=0}),c.commands.formatmatch={execCommand:function(f){if(e)return e=0,d=[],void c.removeListener("mouseup",a);var g=c.selection.getRange();if(b=g.getClosedNode(),!b||"IMG"!=b.tagName){g.collapse(!0).shrinkBoundary();var h=g.startContainer;d=domUtils.findParents(h,!0,function(a){return!domUtils.isBlockElm(a)&&1==a.nodeType});for(var i,j=0;i=d[j];j++)if("A"==i.tagName){d.splice(j,1);break}}c.addListener("mouseup",a),e=1},queryCommandState:function(){return e},notNeedUndo:1}},UE.plugin.register("searchreplace",function(){function a(a,b,c){var d=b.searchStr;b.dir==-1&&(a=a.split("").reverse().join(""),d=d.split("").reverse().join(""),c=a.length-c);for(var e,f=new RegExp(d,"g"+(b.casesensitive?"":"i"));e=f.exec(a);)if(e.index>=c)return b.dir==-1?a.length-e.index-b.searchStr.length:e.index;return-1}function b(b,c,d){var e,f,h=d.all||1==d.dir?"getNextDomNode":"getPreDomNode";domUtils.isBody(b)&&(b=b.firstChild);for(var i=1;b;){if(e=3==b.nodeType?b.nodeValue:b[browser.ie?"innerText":"textContent"],f=a(e,d,c),i=0,f!=-1)return{node:b,index:f};for(b=domUtils[h](b);b&&g[b.nodeName.toLowerCase()];)b=domUtils[h](b,!0);b&&(c=d.dir==-1?(3==b.nodeType?b.nodeValue:b[browser.ie?"innerText":"textContent"]).length:0)}}function c(a,b,d){for(var e,f=0,g=a.firstChild,h=0;g;){if(3==g.nodeType){if(h=g.nodeValue.replace(/(^[\t\r\n]+)|([\t\r\n]+$)/,"").length,f+=h,f>=b)return{node:g,index:h-(f-b)}}else if(!dtd.$empty[g.tagName]&&(h=g[browser.ie?"innerText":"textContent"].replace(/(^[\t\r\n]+)|([\t\r\n]+$)/,"").length,f+=h,f>=b&&(e=c(g,h-(f-b),d))))return e;g=domUtils.getNextDomNode(g)}}function d(a,d){var f,g=a.selection.getRange(),h=d.searchStr,i=a.document.createElement("span");if(i.innerHTML="$$ueditor_searchreplace_key$$",g.shrinkBoundary(!0),!g.collapsed){g.select();var j=a.selection.getText();if(new RegExp("^"+d.searchStr+"$",d.casesensitive?"":"i").test(j)){if(void 0!=d.replaceStr)return e(g,d.replaceStr),g.select(),!0;g.collapse(d.dir==-1)}}g.insertNode(i),g.enlargeToBlockElm(!0),f=g.startContainer;var k=f[browser.ie?"innerText":"textContent"].indexOf("$$ueditor_searchreplace_key$$");g.setStartBefore(i),domUtils.remove(i);var l=b(f,k,d);if(l){var m=c(l.node,l.index,h),n=c(l.node,l.index+h.length,h);return g.setStart(m.node,m.index).setEnd(n.node,n.index),void 0!==d.replaceStr&&e(g,d.replaceStr),g.select(),!0}g.setCursor()}function e(a,b){b=f.document.createTextNode(b),a.deleteContents().insertNode(b)}var f=this,g={table:1,tbody:1,tr:1,ol:1,ul:1};return{commands:{searchreplace:{execCommand:function(a,b){utils.extend(b,{all:!1,casesensitive:!1,dir:1},!0);var c=0;if(b.all){var e=f.selection.getRange(),g=f.body.firstChild;for(g&&1==g.nodeType?(e.setStart(g,0),e.shrinkBoundary(!0)):3==g.nodeType&&e.setStartBefore(g),e.collapse(!0).select(!0),void 0!==b.replaceStr&&f.fireEvent("saveScene");d(this,b);)c++;c&&f.fireEvent("saveScene")}else void 0!==b.replaceStr&&f.fireEvent("saveScene"),d(this,b)&&c++,c&&f.fireEvent("saveScene");return c},notNeedUndo:1}}}}),UE.plugins.customstyle=function(){var a=this;a.setOpt({customstyle:[{tag:"h1",name:"tc",style:"font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:center;margin:0 0 20px 0;"},{tag:"h1",name:"tl",style:"font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:left;margin:0 0 10px 0;"},{tag:"span",name:"im",style:"font-size:16px;font-style:italic;font-weight:bold;line-height:18px;"},{tag:"span",name:"hi",style:"font-size:16px;font-style:italic;font-weight:bold;color:rgb(51, 153, 204);line-height:18px;"}]}),a.commands.customstyle={execCommand:function(a,b){var c,d,e=this,f=b.tag,g=domUtils.findParent(e.selection.getStart(),function(a){return a.getAttribute("label")},!0),h={};for(var i in b)void 0!==b[i]&&(h[i]=b[i]);if(delete h.tag,g&&g.getAttribute("label")==b.label){if(c=this.selection.getRange(),d=c.createBookmark(),c.collapsed)if(dtd.$block[g.tagName]){var j=e.document.createElement("p");domUtils.moveChild(g,j),g.parentNode.insertBefore(j,g),domUtils.remove(g)}else domUtils.remove(g,!0);else{var k=domUtils.getCommonAncestor(d.start,d.end),l=domUtils.getElementsByTagName(k,f);new RegExp(f,"i").test(k.tagName)&&l.push(k);for(var m,n=0;m=l[n++];)if(m.getAttribute("label")==b.label){var o=domUtils.getPosition(m,d.start),p=domUtils.getPosition(m,d.end);if((o&domUtils.POSITION_FOLLOWING||o&domUtils.POSITION_CONTAINS)&&(p&domUtils.POSITION_PRECEDING||p&domUtils.POSITION_CONTAINS)&&dtd.$block[f]){var j=e.document.createElement("p");domUtils.moveChild(m,j),m.parentNode.insertBefore(j,m)}domUtils.remove(m,!0)}g=domUtils.findParent(k,function(a){return a.getAttribute("label")==b.label},!0),g&&domUtils.remove(g,!0)}c.moveToBookmark(d).select()}else if(dtd.$block[f]){if(this.execCommand("paragraph",f,h,"customstyle"),c=e.selection.getRange(),!c.collapsed){c.collapse(),g=domUtils.findParent(e.selection.getStart(),function(a){return a.getAttribute("label")==b.label},!0);var q=e.document.createElement("p");domUtils.insertAfter(g,q),domUtils.fillNode(e.document,q),c.setStart(q,0).setCursor()}}else{if(c=e.selection.getRange(),c.collapsed)return g=e.document.createElement(f),domUtils.setAttributes(g,h),void c.insertNode(g).setStart(g,0).setCursor();d=c.createBookmark(),c.applyInlineStyle(f,h).moveToBookmark(d).select()}},queryCommandValue:function(){var a=domUtils.filterNodeList(this.selection.getStartElementPath(),function(a){return a.getAttribute("label")});return a?a.getAttribute("label"):""}},a.addListener("keyup",function(b,c){var d=c.keyCode||c.which;if(32==d||13==d){var e=a.selection.getRange();if(e.collapsed){var f=domUtils.findParent(a.selection.getStart(),function(a){return a.getAttribute("label")},!0);if(f&&dtd.$block[f.tagName]&&domUtils.isEmptyNode(f)){var g=a.document.createElement("p");domUtils.insertAfter(f,g),domUtils.fillNode(a.document,g),domUtils.remove(f),e.setStart(g,0).setCursor()}}}})},UE.plugins.catchremoteimage=function(){var me=this,ajax=UE.ajax;me.options.catchRemoteImageEnable!==!1&&(me.setOpt({catchRemoteImageEnable:!1}),me.addListener("afterpaste",function(){me.fireEvent("catchRemoteImage")}),me.addListener("catchRemoteImage",function(){function catchremoteimage(a,b){var c=utils.serializeParam(me.queryCommandValue("serverparam"))||"",d=utils.formatUrl(catcherActionUrl+(catcherActionUrl.indexOf("?")==-1?"?":"&")+c),e=utils.isCrossDomainUrl(d),f={method:"POST",dataType:e?"jsonp":"",timeout:6e4,onsuccess:b.success,onerror:b.error};f[catcherFieldName]=a,ajax.request(d,f)}for(var catcherLocalDomain=me.getOpt("catcherLocalDomain"),catcherActionUrl=me.getActionUrl(me.getOpt("catcherActionName")),catcherUrlPrefix=me.getOpt("catcherUrlPrefix"),catcherFieldName=me.getOpt("catcherFieldName"),remoteImages=[],imgs=domUtils.getElementsByTagName(me.document,"img"),test=function(a,b){if(a.indexOf(location.host)!=-1||/(^\.)|(^\/)/.test(a))return!0;if(b)for(var c,d=0;c=b[d++];)if(a.indexOf(c)!==-1)return!0;return!1},i=0,ci;ci=imgs[i++];)if(!ci.getAttribute("word_img")){var src=ci.getAttribute("_src")||ci.src||"";/^(https?|ftp):/i.test(src)&&!test(src,catcherLocalDomain)&&remoteImages.push(src)}remoteImages.length&&catchremoteimage(remoteImages,{success:function(r){try{var info=void 0!==r.state?r:eval("("+r.responseText+")")}catch(e){return}var i,j,ci,cj,oldSrc,newSrc,list=info.list;for(i=0;ci=imgs[i++];)for(oldSrc=ci.getAttribute("_src")||ci.src||"",j=0;cj=list[j++];)if(oldSrc==cj.source&&"SUCCESS"==cj.state){newSrc=catcherUrlPrefix+cj.url,domUtils.setAttributes(ci,{src:newSrc,_src:newSrc});break}me.fireEvent("catchremotesuccess")},error:function(){me.fireEvent("catchremoteerror")}})}))},UE.plugin.register("snapscreen",function(){function getLocation(a){var b,c=document.createElement("a"),d=utils.serializeParam(me.queryCommandValue("serverparam"))||"";return c.href=a,browser.ie&&(c.href=c.href),b=c.search,d&&(b=b+(b.indexOf("?")==-1?"?":"&")+d,b=b.replace(/[&]+/gi,"&")),{port:c.port,hostname:c.hostname,path:c.pathname+b||+c.hash}}var me=this,snapplugin;return{commands:{snapscreen:{execCommand:function(cmd){function onSuccess(rs){try{if(rs=eval("("+rs+")"),"SUCCESS"==rs.state){var opt=me.options;me.execCommand("insertimage",{src:opt.snapscreenUrlPrefix+rs.url,_src:opt.snapscreenUrlPrefix+rs.url,alt:rs.title||"",floatStyle:opt.snapscreenImgAlign})}else alert(rs.state)}catch(e){alert(lang.callBackErrorMsg)}}var url,local,res,lang=me.getLang("snapScreen_plugin");if(!snapplugin){var container=me.container,doc=me.container.ownerDocument||me.container.document;snapplugin=doc.createElement("object");try{snapplugin.type="application/x-pluginbaidusnap"}catch(e){return}snapplugin.style.cssText="position:absolute;left:-9999px;width:0;height:0;",snapplugin.setAttribute("width","0"),snapplugin.setAttribute("height","0"),container.appendChild(snapplugin)}url=me.getActionUrl(me.getOpt("snapscreenActionName")),local=getLocation(url),setTimeout(function(){try{res=snapplugin.saveSnapshot(local.hostname,local.path,local.port)}catch(a){return void me.ui._dialogs.snapscreenDialog.open()}onSuccess(res)},50)},queryCommandState:function(){return navigator.userAgent.indexOf("Windows",0)!=-1?0:-1}}}}}),UE.commands.insertparagraph={execCommand:function(a,b){for(var c,d=this,e=d.selection.getRange(),f=e.startContainer;f&&!domUtils.isBody(f);)c=f,f=f.parentNode;if(c){var g=d.document.createElement("p");b?c.parentNode.insertBefore(g,c):c.parentNode.insertBefore(g,c.nextSibling),domUtils.fillNode(d.document,g),e.setStart(g,0).setCursor(!1,!0)}}},UE.plugin.register("webapp",function(){function a(a,c){return c?'':'"}var b=this;return{outputRule:function(b){utils.each(b.getNodesByTagName("img"),function(b){var c;if("edui-faked-webapp"==b.getAttr("class")){c=a({title:b.getAttr("title"),width:b.getAttr("width"),height:b.getAttr("height"),align:b.getAttr("align"),cssfloat:b.getStyle("float"),url:b.getAttr("_url"),logo:b.getAttr("_logo_url")},!0);var d=UE.uNode.createElement(c);b.parentNode.replaceChild(d,b)}})},inputRule:function(b){utils.each(b.getNodesByTagName("iframe"),function(b){if("edui-faked-webapp"==b.getAttr("class")){var c=UE.uNode.createElement(a({title:b.getAttr("title"),width:b.getAttr("width"),height:b.getAttr("height"),align:b.getAttr("align"),cssfloat:b.getStyle("float"),url:b.getAttr("src"),logo:b.getAttr("logo_url")}));b.parentNode.replaceChild(c,b)}})},commands:{webapp:{execCommand:function(b,c){var d=this,e=a(utils.extend(c,{align:"none"}),!1);d.execCommand("inserthtml",e)},queryCommandState:function(){var a=this,b=a.selection.getRange().getClosedNode(),c=b&&"edui-faked-webapp"==b.className;return c?1:0}}}}}),UE.plugins.template=function(){UE.commands.template={execCommand:function(a,b){b.html&&this.execCommand("inserthtml",b.html)}},this.addListener("click",function(a,b){var c=b.target||b.srcElement,d=this.selection.getRange(),e=domUtils.findParent(c,function(a){if(a.className&&domUtils.hasClass(a,"ue_t"))return a},!0);e&&d.selectNode(e).shrinkBoundary().select()}),this.addListener("keydown",function(a,b){var c=this.selection.getRange();if(!c.collapsed&&!(b.ctrlKey||b.metaKey||b.shiftKey||b.altKey)){var d=domUtils.findParent(c.startContainer,function(a){if(a.className&&domUtils.hasClass(a,"ue_t"))return a},!0);d&&domUtils.removeClasses(d,["ue_t"])}})},UE.plugin.register("music",function(){function a(a,c,d,e,f,g){return g?'':"'}var b=this;return{outputRule:function(b){utils.each(b.getNodesByTagName("img"),function(b){var c;if("edui-faked-music"==b.getAttr("class")){var d=b.getStyle("float"),e=b.getAttr("align");c=a(b.getAttr("_url"),b.getAttr("width"),b.getAttr("height"),e,d,!0);var f=UE.uNode.createElement(c);b.parentNode.replaceChild(f,b)}})},inputRule:function(b){utils.each(b.getNodesByTagName("embed"),function(b){if("edui-faked-music"==b.getAttr("class")){var c=b.getStyle("float"),d=b.getAttr("align");html=a(b.getAttr("src"),b.getAttr("width"),b.getAttr("height"),d,c,!1);var e=UE.uNode.createElement(html);b.parentNode.replaceChild(e,b)}})},commands:{music:{execCommand:function(b,c){var d=this,e=a(c.url,c.width||400,c.height||95,"none",!1);d.execCommand("inserthtml",e)},queryCommandState:function(){var a=this,b=a.selection.getRange().getClosedNode(),c=b&&"edui-faked-music"==b.className;return c?1:0}}}}}),UE.plugin.register("autoupload",function(){function a(a,b){var c,d,e,f,g,h,i,j,k=b,l=/image\/\w+/i.test(a.type)?"image":"file",m="loading_"+(+new Date).toString(36);if(c=k.getOpt(l+"FieldName"),d=k.getOpt(l+"UrlPrefix"),e=k.getOpt(l+"MaxSize"),f=k.getOpt(l+"AllowFiles"),g=k.getActionUrl(k.getOpt(l+"ActionName")),i=function(a){var b=k.document.getElementById(m);b&&domUtils.remove(b),k.fireEvent("showmessage",{id:m,content:a,type:"error",timeout:4e3})},"image"==l?(h='',j=function(a){var b=d+a.url,c=k.document.getElementById(m);c&&(c.setAttribute("src",b),c.setAttribute("_src",b),c.setAttribute("title",a.title||""),c.setAttribute("alt",a.original||""),c.removeAttribute("id"),domUtils.removeClasses(c,"loadingclass"))}):(h='

      ',j=function(a){var b=d+a.url,c=k.document.getElementById(m),e=k.selection.getRange(),f=e.createBookmark();e.selectNode(c).select(),k.execCommand("insertfile",{url:b}),e.moveToBookmark(f).select()}),k.execCommand("inserthtml",h),!k.getOpt(l+"ActionName"))return void i(k.getLang("autoupload.errorLoadConfig"));if(a.size>e)return void i(k.getLang("autoupload.exceedSizeError"));var n=a.name?a.name.substr(a.name.lastIndexOf(".")):"";if(n&&"image"!=l||f&&(f.join("")+".").indexOf(n.toLowerCase()+".")==-1)return void i(k.getLang("autoupload.exceedTypeError"));var o=new XMLHttpRequest,p=new FormData,q=utils.serializeParam(k.queryCommandValue("serverparam"))||"",r=utils.formatUrl(g+(g.indexOf("?")==-1?"?":"&")+q);p.append(c,a,a.name||"blob."+a.type.substr("image/".length)),p.append("type","ajax"),o.open("post",r,!0),o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.addEventListener("load",function(a){try{var b=new Function("return "+utils.trim(a.target.response))();"SUCCESS"==b.state&&b.url?j(b):i(b.state)}catch(c){i(k.getLang("autoupload.loadError"))}}),o.send(p)}function b(a){return a.clipboardData&&a.clipboardData.items&&1==a.clipboardData.items.length&&/^image\//.test(a.clipboardData.items[0].type)?a.clipboardData.items:null}function c(a){return a.dataTransfer&&a.dataTransfer.files?a.dataTransfer.files:null}return{outputRule:function(a){utils.each(a.getNodesByTagName("img"),function(a){/\b(loaderrorclass)|(bloaderrorclass)\b/.test(a.getAttr("class"))&&a.parentNode.removeChild(a)}),utils.each(a.getNodesByTagName("p"),function(a){/\bloadpara\b/.test(a.getAttr("class"))&&a.parentNode.removeChild(a)})},bindEvents:{ready:function(d){var e=this;window.FormData&&window.FileReader&&(domUtils.on(e.body,"paste drop",function(d){var f,g=!1;if(f="paste"==d.type?b(d):c(d)){for(var h,i=f.length;i--;)h=f[i],h.getAsFile&&(h=h.getAsFile()),h&&h.size>0&&(a(h,e),g=!0);g&&d.preventDefault()}}),domUtils.on(e.body,"dragover",function(a){"Files"==a.dataTransfer.types[0]&&a.preventDefault()}),utils.cssRule("loading",".loadingclass{display:inline-block;cursor:default;background: url('"+this.options.themePath+this.options.theme+"/images/loading.gif') no-repeat center center transparent;border:1px solid #cccccc;margin-left:1px;height: 22px;width: 22px;}\n.loaderrorclass{display:inline-block;cursor:default;background: url('"+this.options.themePath+this.options.theme+"/images/loaderror.png') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;}",this.document))}}}}),UE.plugin.register("autosave",function(){function a(a){var f;if(!(new Date-c0?b._saveFlag=window.setTimeout(function(){a(b)},b.options.saveInterval):a(b))}},commands:{clearlocaldata:{execCommand:function(a,c){e&&b.getPreferences(e)&&b.removePreferences(e)},notNeedUndo:!0,ignoreContentChange:!0},getlocaldata:{execCommand:function(a,c){return e?b.getPreferences(e)||"":""},notNeedUndo:!0,ignoreContentChange:!0},drafts:{execCommand:function(a,c){e&&(b.body.innerHTML=b.getPreferences(e)||"

      "+domUtils.fillHtml+"

      ",b.focus(!0))},queryCommandState:function(){return e?null===b.getPreferences(e)?-1:0:-1},notNeedUndo:!0,ignoreContentChange:!0}}}}),UE.plugin.register("charts",function(){function a(a){var b=null,c=0;if(a.rows.length<2)return!1;if(a.rows[0].cells.length<2)return!1;b=a.rows[0].cells,c=b.length;for(var d,e=0;d=b[e];e++)if("th"!==d.tagName.toLowerCase())return!1;for(var f,e=1;f=a.rows[e];e++){if(f.cells.length!=c)return!1;if("th"!==f.cells[0].tagName.toLowerCase())return!1;for(var d,g=1;d=f.cells[g];g++){var h=utils.trim(d.innerText||d.textContent||"");if(h=h.replace(new RegExp(UE.dom.domUtils.fillChar,"g"),"").replace(/^\s+|\s+$/g,""),!/^\d*\.?\d+$/.test(h))return!1}}return!0}var b=this;return{bindEvents:{chartserror:function(){}},commands:{charts:{execCommand:function(c,d){var e=domUtils.findParentByTagName(this.selection.getRange().startContainer,"table",!0),f=[],g={};if(!e)return!1;if(!a(e))return b.fireEvent("chartserror"),!1;g.title=d.title||"",g.subTitle=d.subTitle||"",g.xTitle=d.xTitle||"",g.yTitle=d.yTitle||"",g.suffix=d.suffix||"",g.tip=d.tip||"",g.dataFormat=d.tableDataFormat||"",g.chartType=d.chartType||0;for(var h in g)g.hasOwnProperty(h)&&f.push(h+":"+g[h]);e.setAttribute("data-chart",f.join(";")),domUtils.addClass(e,"edui-charts-table")},queryCommandState:function(b,c){ +var d=domUtils.findParentByTagName(this.selection.getRange().startContainer,"table",!0);return d&&a(d)?0:-1}}},inputRule:function(a){utils.each(a.getNodesByTagName("table"),function(a){void 0!==a.getAttr("data-chart")&&a.setAttr("style")})},outputRule:function(a){utils.each(a.getNodesByTagName("table"),function(a){void 0!==a.getAttr("data-chart")&&a.setAttr("style","display: none;")})}}}),UE.plugin.register("section",function(){function a(a){this.tag="",this.level=-1,this.dom=null,this.nextSection=null,this.previousSection=null,this.parentSection=null,this.startAddress=[],this.endAddress=[],this.children=[]}function b(b){var c=new a;return utils.extend(c,b)}function c(a,b){for(var c=b,d=0;d=0){var o=h.selection.getRange().selectNode(i).createAddress(!0).startAddress,p=b({tag:i.tagName,title:i.innerText||i.textContent||"",level:f,dom:i,startAddress:utils.clone(o,[]),endAddress:utils.clone(o,[]),children:[]});for(j.nextSection=p,p.previousSection=j,g=j;f<=g.level;)g=g.parentSection;p.parentSection=g,g.children.push(p),k=j=p}else 1===i.nodeType&&e(i,c),k&&k.endAddress[k.endAddress.length-1]++}for(var f=c||["h1","h2","h3","h4","h5","h6"],g=0;g=c.length);f++){if(c[f]>a[f]){d=!0;break}if(c[f]=c.length);f++){if(c[f]a[f])break}return d&&e}var g,h,i=this;if(b&&d&&d.level!=-1&&(g=e?d.endAddress:d.startAddress,h=c(g,i.body),g&&h&&!f(b.startAddress,b.endAddress,g))){var j,k,l=c(b.startAddress,i.body),m=c(b.endAddress,i.body);if(e)for(j=m;j&&!(domUtils.getPosition(l,j)&domUtils.POSITION_FOLLOWING)&&(k=j.previousSibling,domUtils.insertAfter(h,j),j!=l);)j=k;else for(j=l;j&&!(domUtils.getPosition(j,m)&domUtils.POSITION_FOLLOWING)&&(k=j.nextSibling,h.parentNode.insertBefore(j,h),j!=m);)j=k;i.fireEvent("updateSections")}}},deletesection:{execCommand:function(a,b,c){function d(a){for(var b=e.body,c=0;c',b.className="edui-"+c.options.theme,b.id=c.ui.id+"_iframeupload",i.style.cssText=g,i.style.width=a+"px",i.style.height=e+"px",i.appendChild(b),i.parentNode&&(i.parentNode.style.width=a+"px",i.parentNode.style.height=a+"px");var k=h.getElementById("edui_form_"+j),l=h.getElementById("edui_input_"+j),m=h.getElementById("edui_iframe_"+j);domUtils.on(l,"change",function(){function a(){try{var e,f,g,h=(m.contentDocument||m.contentWindow.document).body,i=h.innerText||h.textContent||"";f=new Function("return "+i)(),e=c.options.imageUrlPrefix+f.url,"SUCCESS"==f.state&&f.url?(g=c.document.getElementById(d),g.setAttribute("src",e),g.setAttribute("_src",e),g.setAttribute("title",f.title||""),g.setAttribute("alt",f.original||""),g.removeAttribute("id"),domUtils.removeClasses(g,"loadingclass")):b&&b(f.state)}catch(j){b&&b(c.getLang("simpleupload.loadError"))}k.reset(),domUtils.un(m,"load",a)}function b(a){if(d){var b=c.document.getElementById(d);b&&domUtils.remove(b),c.fireEvent("showmessage",{id:d,content:a,type:"error",timeout:4e3})}}if(l.value){var d="loading_"+(+new Date).toString(36),e=utils.serializeParam(c.queryCommandValue("serverparam"))||"",f=c.getActionUrl(c.getOpt("imageActionName")),g=c.getOpt("imageAllowFiles");if(c.focus(),c.execCommand("inserthtml",''),!c.getOpt("imageActionName"))return void errorHandler(c.getLang("autoupload.errorLoadConfig"));var h=l.value,i=h?h.substr(h.lastIndexOf(".")):"";if(!i||g&&(g.join("")+".").indexOf(i.toLowerCase()+".")==-1)return void b(c.getLang("simpleupload.exceedTypeError"));domUtils.on(m,"load",a),k.action=utils.formatUrl(f+(f.indexOf("?")==-1?"?":"&")+e),k.submit()}});var n;c.addListener("selectionchange",function(){clearTimeout(n),n=setTimeout(function(){var a=c.queryCommandState("simpleupload");a==-1?l.disabled="disabled":l.disabled=!1},400)}),d=!0}),f.style.cssText=g,b.appendChild(f)}var b,c=this,d=!1;return{bindEvents:{ready:function(){utils.cssRule("loading",".loadingclass{display:inline-block;cursor:default;background: url('"+this.options.themePath+this.options.theme+"/images/loading.gif') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;}\n.loaderrorclass{display:inline-block;cursor:default;background: url('"+this.options.themePath+this.options.theme+"/images/loaderror.png') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;}",this.document)},simpleuploadbtnready:function(d,e){b=e,c.afterConfigReady(a)}},outputRule:function(a){utils.each(a.getNodesByTagName("img"),function(a){/\b(loaderrorclass)|(bloaderrorclass)\b/.test(a.getAttr("class"))&&a.parentNode.removeChild(a)})},commands:{simpleupload:{queryCommandState:function(){return d?0:-1}}}}}),UE.plugin.register("serverparam",function(){var a={};return{commands:{serverparam:{execCommand:function(b,c,d){void 0===c||null===c?a={}:utils.isString(c)?void 0===d||null===d?delete a[c]:a[c]=d:utils.isObject(c)?utils.extend(a,c,!0):utils.isFunction(c)&&utils.extend(a,c(),!0)},queryCommandValue:function(){return a||{}}}}}}),UE.plugin.register("insertfile",function(){function a(a){var b=a.substr(a.lastIndexOf(".")+1).toLowerCase(),c={};return c[b]?c[b]:c.txt}var b=this;return{commands:{insertfile:{execCommand:function(c,d){d=utils.isArray(d)?d:[d];var e,f,g,h,i="",j=b.getOpt("UEDITOR_HOME_URL"),k=j+("/"==j.substr(j.length-1)?"":"/")+"dialogs/attachment/fileTypeImages/";for(e=0;e'+h+"

      ";b.execCommand("insertHtml",i)}}}}}),UE.plugins.xssFilter=function(){function a(a){var b=a.tagName,d=a.attrs;return c.hasOwnProperty(b)?void UE.utils.each(d,function(d,e){c[b].indexOf(e)===-1&&a.setAttr(e)}):(a.parentNode.removeChild(a),!1)}var b=UEDITOR_CONFIG,c=b.whitList;c&&b.xssFilterRules&&(this.options.filterRules=function(){var b={};return UE.utils.each(c,function(c,d){b[d]=function(b){return a(b)}}),b}());var d=[];UE.utils.each(c,function(a,b){d.push(b)}),c&&b.inputXssFilter&&this.addInputRule(function(b){b.traversal(function(b){return"element"===b.type&&void a(b)})}),c&&b.outputXssFilter&&this.addOutputRule(function(b){b.traversal(function(b){return"element"===b.type&&void a(b)})})};var baidu=baidu||{};baidu.editor=baidu.editor||{},UE.ui=baidu.editor.ui={},function(){function a(){var a=document.getElementById("edui_fixedlayer");i.setViewportOffset(a,{left:0,top:0})}function b(b){d.on(window,"scroll",a),d.on(window,"resize",baidu.editor.utils.defer(a,0,!0))}var c=baidu.editor.browser,d=baidu.editor.dom.domUtils,e="$EDITORUI",f=window[e]={},g="ID"+e,h=0,i=baidu.editor.ui.uiUtils={uid:function(a){return a?a[g]||(a[g]=++h):++h},hook:function(a,b){var c;return a&&a._callbacks?c=a:(c=function(){var b;a&&(b=a.apply(this,arguments));for(var d=c._callbacks,e=d.length;e--;){var f=d[e].apply(this,arguments);void 0===b&&(b=f)}return b},c._callbacks=[]),c._callbacks.push(b),c},createElementByHtml:function(a){var b=document.createElement("div");return b.innerHTML=a,b=b.firstChild,b.parentNode.removeChild(b),b},getViewportElement:function(){return c.ie&&c.quirks?document.body:document.documentElement},getClientRect:function(a){var b;try{b=a.getBoundingClientRect()}catch(c){b={left:0,top:0,height:0,width:0}}for(var e,f={left:Math.round(b.left),top:Math.round(b.top),height:Math.round(b.bottom-b.top),width:Math.round(b.right-b.left)};(e=a.ownerDocument)!==document&&(a=d.getWindow(e).frameElement);)b=a.getBoundingClientRect(),f.left+=b.left,f.top+=b.top;return f.bottom=f.top+f.height,f.right=f.left+f.width,f},getViewportRect:function(){var a=i.getViewportElement(),b=0|(window.innerWidth||a.clientWidth),c=0|(window.innerHeight||a.clientHeight);return{left:0,top:0,height:c,width:b,bottom:c,right:b}},setViewportOffset:function(a,b){var c=i.getFixedLayer();a.parentNode===c?(a.style.left=b.left+"px",a.style.top=b.top+"px"):d.setViewportOffset(a,b)},getEventOffset:function(a){var b=a.target||a.srcElement,c=i.getClientRect(b),d=i.getViewportOffsetByEvent(a);return{left:d.left-c.left,top:d.top-c.top}},getViewportOffsetByEvent:function(a){var b=a.target||a.srcElement,c=d.getWindow(b).frameElement,e={left:a.clientX,top:a.clientY};if(c&&b.ownerDocument!==document){var f=i.getClientRect(c);e.left+=f.left,e.top+=f.top}return e},setGlobal:function(a,b){return f[a]=b,e+'["'+a+'"]'},unsetGlobal:function(a){delete f[a]},copyAttributes:function(a,b){for(var e=b.attributes,f=e.length;f--;){var g=e[f];"style"==g.nodeName||"class"==g.nodeName||c.ie&&!g.specified||a.setAttribute(g.nodeName,g.nodeValue)}b.className&&d.addClass(a,b.className),b.style.cssText&&(a.style.cssText+=";"+b.style.cssText)},removeStyle:function(a,b){if(a.style.removeProperty)a.style.removeProperty(b);else{if(!a.style.removeAttribute)throw"";a.style.removeAttribute(b)}},contains:function(a,b){return a&&b&&a!==b&&(a.contains?a.contains(b):16&a.compareDocumentPosition(b))},startDrag:function(a,b,c){function d(a){var c=a.clientX-g,d=a.clientY-h;b.ondragmove(c,d,a),a.stopPropagation?a.stopPropagation():a.cancelBubble=!0}function e(a){c.removeEventListener("mousemove",d,!0),c.removeEventListener("mouseup",e,!0),window.removeEventListener("mouseup",e,!0),b.ondragstop()}function f(){i.releaseCapture(),i.detachEvent("onmousemove",d),i.detachEvent("onmouseup",f),i.detachEvent("onlosecaptrue",f),b.ondragstop()}var c=c||document,g=a.clientX,h=a.clientY;if(c.addEventListener)c.addEventListener("mousemove",d,!0),c.addEventListener("mouseup",e,!0),window.addEventListener("mouseup",e,!0),a.preventDefault();else{var i=a.srcElement;i.setCapture(),i.attachEvent("onmousemove",d),i.attachEvent("onmouseup",f),i.attachEvent("onlosecaptrue",f),a.returnValue=!1}b.ondragstart()},getFixedLayer:function(){var d=document.getElementById("edui_fixedlayer");return null==d&&(d=document.createElement("div"),d.id="edui_fixedlayer",document.body.appendChild(d),c.ie&&c.version<=8?(d.style.position="absolute",b(),setTimeout(a)):d.style.position="fixed",d.style.left="0",d.style.top="0",d.style.width="0",d.style.height="0"),d},makeUnselectable:function(a){if(c.opera||c.ie&&c.version<9){if(a.unselectable="on",a.hasChildNodes())for(var b=0;b'}},a.inherits(c,b)}(),function(){var a=baidu.editor.utils,b=baidu.editor.dom.domUtils,c=baidu.editor.ui.UIBase,d=baidu.editor.ui.uiUtils,e=baidu.editor.ui.Mask=function(a){this.initOptions(a),this.initUIBase()};e.prototype={getHtmlTpl:function(){return'
      '},postRender:function(){var a=this;b.on(window,"resize",function(){setTimeout(function(){a.isHidden()||a._fill()})})},show:function(a){this._fill(),this.getDom().style.display="",this.getDom().style.zIndex=a},hide:function(){this.getDom().style.display="none",this.getDom().style.zIndex=""},isHidden:function(){return"none"==this.getDom().style.display},_onMouseDown:function(){return!1},_onClick:function(a,b){this.fireEvent("click",a,b)},_fill:function(){var a=this.getDom(),b=d.getViewportRect();a.style.width=b.width+"px",a.style.height=b.height+"px"}},a.inherits(e,c)}(),function(){function a(a,b){for(var c=0;c
      '+this.getContentHtmlTpl()+"
      "},getContentHtmlTpl:function(){return this.content?"string"==typeof this.content?this.content:this.content.renderHtml():""},_UIBase_postRender:e.prototype.postRender,postRender:function(){if(this.content instanceof e&&this.content.postRender(),this.captureWheel&&!this.captured){this.captured=!0;var a=(document.documentElement.clientHeight||document.body.clientHeight)-80,b=this.getDom().offsetHeight,f=c.getClientRect(this.combox.getDom()).top,g=this.getDom("content"),h=this.getDom("body").getElementsByTagName("iframe"),i=this;for(h.length&&(h=h[0]);f+b>a;)b-=30;g.style.height=b+"px",h&&(h.style.height=b+"px"),window.XMLHttpRequest?d.on(g,"onmousewheel"in document.body?"mousewheel":"DOMMouseScroll",function(a){a.preventDefault?a.preventDefault():a.returnValue=!1,a.wheelDelta?g.scrollTop-=a.wheelDelta/120*60:g.scrollTop-=a.detail/-3*60}):d.on(this.getDom(),"mousewheel",function(a){a.returnValue=!1,i.getDom("content").scrollTop-=a.wheelDelta/120*60})}this.fireEvent("postRenderAfter"),this.hide(!0),this._UIBase_postRender()},_doAutoRender:function(){!this.getDom()&&this.autoRender&&this.render()},mesureSize:function(){var a=this.getDom("content");return c.getClientRect(a)},fitSize:function(){if(this.captureWheel&&this.sized)return this.__size;this.sized=!0;var a=this.getDom("body");a.style.width="",a.style.height="";var b=this.mesureSize();if(this.captureWheel){a.style.width=-(-20-b.width)+"px";var c=parseInt(this.getDom("content").style.height,10);!window.isNaN(c)&&(b.height=c)}else a.style.width=b.width+"px";return a.style.height=b.height+"px",this.__size=b,this.captureWheel&&(this.getDom("content").style.overflow="auto"),b},showAnchor:function(a,b){this.showAnchorRect(c.getClientRect(a),b)},showAnchorRect:function(a,b,e){this._doAutoRender();var f=c.getViewportRect();this.getDom().style.visibility="hidden",this._show();var g,i,j,k,l=this.fitSize();b?(g=this.canSideLeft&&a.right+l.width>f.right&&a.left>l.width,i=this.canSideUp&&a.top+l.height>f.bottom&&a.bottom>l.height,j=g?a.left-l.width:a.right,k=i?a.bottom-l.height:a.top):(g=this.canSideLeft&&a.right+l.width>f.right&&a.left>l.width,i=this.canSideUp&&a.top+l.height>f.bottom&&a.bottom>l.height,j=g?a.right-l.width:a.left,k=i?a.top-l.height:a.bottom);var m=this.getDom();c.setViewportOffset(m,{left:j,top:k}),d.removeClasses(m,h),m.className+=" "+h[2*(i?1:0)+(g?1:0)],this.editor&&(m.style.zIndex=1*this.editor.container.style.zIndex+10,baidu.editor.ui.uiUtils.getFixedLayer().style.zIndex=m.style.zIndex-1),this.getDom().style.visibility="visible"},showAt:function(a){var b=a.left,c=a.top,d={left:b,top:c,right:b,bottom:c,height:0,width:0};this.showAnchorRect(d,!1,!0)},_show:function(){if(this._hidden){var a=this.getDom();a.style.display="",this._hidden=!1,this.fireEvent("show")}},isHidden:function(){return this._hidden},show:function(){this._doAutoRender(),this._show()},hide:function(a){!this._hidden&&this.getDom()&&(this.getDom().style.display="none",this._hidden=!0,a||this.fireEvent("hide"))},queryAutoHide:function(a){return!a||!c.contains(this.getDom(),a)}},b.inherits(f,e),d.on(document,"mousedown",function(b){var c=b.target||b.srcElement;a(b,c)}),d.on(window,"scroll",function(b,c){a(b,c)})}(),function(){function a(a,b){for(var c='
      '+a+'
      ',d=0;d"+(60==d?'":"")+""),c+=d<70?'':"";return c+="
      '+b.getLang("themeColor")+'
      '+b.getLang("standardColor")+"
      =60?"border-width:1px;":d>=10&&d<20?"border-width:1px 1px 0 1px;":"border-width:0 1px 0 1px;")+'">
      "}var b=baidu.editor.utils,c=baidu.editor.ui.UIBase,d=baidu.editor.ui.ColorPicker=function(a){this.initOptions(a),this.noColorText=this.noColorText||this.editor.getLang("clearColor"),this.initUIBase()};d.prototype={getHtmlTpl:function(){return a(this.noColorText,this.editor)},_onTableClick:function(a){var b=a.target||a.srcElement,c=b.getAttribute("data-color");c&&this.fireEvent("pickcolor",c)},_onTableOver:function(a){var b=a.target||a.srcElement,c=b.getAttribute("data-color");c&&(this.getDom("preview").style.backgroundColor=c)},_onTableOut:function(){this.getDom("preview").style.backgroundColor=""},_onPickNoColor:function(){this.fireEvent("picknocolor")}},b.inherits(d,c);var e="ffffff,000000,eeece1,1f497d,4f81bd,c0504d,9bbb59,8064a2,4bacc6,f79646,f2f2f2,7f7f7f,ddd9c3,c6d9f0,dbe5f1,f2dcdb,ebf1dd,e5e0ec,dbeef3,fdeada,d8d8d8,595959,c4bd97,8db3e2,b8cce4,e5b9b7,d7e3bc,ccc1d9,b7dde8,fbd5b5,bfbfbf,3f3f3f,938953,548dd4,95b3d7,d99694,c3d69b,b2a2c7,92cddc,fac08f,a5a5a5,262626,494429,17365d,366092,953734,76923c,5f497a,31859b,e36c09,7f7f7f,0c0c0c,1d1b10,0f243e,244061,632423,4f6128,3f3151,205867,974806,c00000,ff0000,ffc000,ffff00,92d050,00b050,00b0f0,0070c0,002060,7030a0,".split(",")}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.uiUtils,c=baidu.editor.ui.UIBase,d=baidu.editor.ui.TablePicker=function(a){this.initOptions(a),this.initTablePicker()};d.prototype={defaultNumRows:10,defaultNumCols:10,maxNumRows:20,maxNumCols:20,numRows:10,numCols:10,lengthOfCellSide:22,initTablePicker:function(){this.initUIBase()},getHtmlTpl:function(){return'
      '},_UIBase_render:c.prototype.render,render:function(a){this._UIBase_render(a),this.getDom("label").innerHTML="0"+this.editor.getLang("t_row")+" x 0"+this.editor.getLang("t_col")},_track:function(a,b){var c=this.getDom("overlay").style,d=this.lengthOfCellSide;c.width=a*d+"px",c.height=b*d+"px";var e=this.getDom("label");e.innerHTML=a+this.editor.getLang("t_col")+" x "+b+this.editor.getLang("t_row"),this.numCols=a,this.numRows=b},_onMouseOver:function(a,c){var d=a.relatedTarget||a.fromElement;b.contains(c,d)||c===d||(this.getDom("label").innerHTML="0"+this.editor.getLang("t_col")+" x 0"+this.editor.getLang("t_row"),this.getDom("overlay").style.visibility="")},_onMouseOut:function(a,c){var d=a.relatedTarget||a.toElement;b.contains(c,d)||c===d||(this.getDom("label").innerHTML="0"+this.editor.getLang("t_col")+" x 0"+this.editor.getLang("t_row"),this.getDom("overlay").style.visibility="hidden")},_onMouseMove:function(a,c){var d=(this.getDom("overlay").style,b.getEventOffset(a)),e=this.lengthOfCellSide,f=Math.ceil(d.left/e),g=Math.ceil(d.top/e);this._track(f,g)},_onClick:function(){this.fireEvent("picktable",this.numCols,this.numRows)}},a.inherits(d,c)}(),function(){var a=baidu.editor.browser,b=baidu.editor.dom.domUtils,c=baidu.editor.ui.uiUtils,d='onmousedown="$$.Stateful_onMouseDown(event, this);" onmouseup="$$.Stateful_onMouseUp(event, this);"'+(a.ie?' onmouseenter="$$.Stateful_onMouseEnter(event, this);" onmouseleave="$$.Stateful_onMouseLeave(event, this);"':' onmouseover="$$.Stateful_onMouseOver(event, this);" onmouseout="$$.Stateful_onMouseOut(event, this);"');baidu.editor.ui.Stateful={alwalysHoverable:!1,target:null,Stateful_init:function(){this._Stateful_dGetHtmlTpl=this.getHtmlTpl,this.getHtmlTpl=this.Stateful_getHtmlTpl},Stateful_getHtmlTpl:function(){var a=this._Stateful_dGetHtmlTpl();return a.replace(/stateful/g,function(){return d})},Stateful_onMouseEnter:function(a,b){this.target=b,this.isDisabled()&&!this.alwalysHoverable||(this.addState("hover"),this.fireEvent("over"))},Stateful_onMouseLeave:function(a,b){this.isDisabled()&&!this.alwalysHoverable||(this.removeState("hover"),this.removeState("active"),this.fireEvent("out"))},Stateful_onMouseOver:function(a,b){var d=a.relatedTarget;c.contains(b,d)||b===d||this.Stateful_onMouseEnter(a,b)},Stateful_onMouseOut:function(a,b){var d=a.relatedTarget;c.contains(b,d)||b===d||this.Stateful_onMouseLeave(a,b)},Stateful_onMouseDown:function(a,b){this.isDisabled()||this.addState("active")},Stateful_onMouseUp:function(a,b){this.isDisabled()||this.removeState("active")},Stateful_postRender:function(){this.disabled&&!this.hasState("disabled")&&this.addState("disabled")},hasState:function(a){return b.hasClass(this.getStateDom(),"edui-state-"+a)},addState:function(a){this.hasState(a)||(this.getStateDom().className+=" edui-state-"+a)},removeState:function(a){this.hasState(a)&&b.removeClasses(this.getStateDom(),["edui-state-"+a])},getStateDom:function(){return this.getDom("state")},isChecked:function(){return this.hasState("checked")},setChecked:function(a){!this.isDisabled()&&a?this.addState("checked"):this.removeState("checked")},isDisabled:function(){return this.hasState("disabled")},setDisabled:function(a){a?(this.removeState("hover"),this.removeState("checked"),this.removeState("active"),this.addState("disabled")):this.removeState("disabled")}}}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.UIBase,c=baidu.editor.ui.Stateful,d=baidu.editor.ui.Button=function(a){if(a.name){var b=a.name,c=a.cssRules;a.className||(a.className="edui-for-"+b),a.cssRules=".edui-default .edui-for-"+b+" .edui-icon {"+c+"}"}this.initOptions(a),this.initButton()};d.prototype={uiName:"button",label:"",title:"",showIcon:!0,showText:!0,cssRules:"",initButton:function(){this.initUIBase(),this.Stateful_init(),this.cssRules&&a.cssRule("edui-customize-"+this.name+"-style",this.cssRules)},getHtmlTpl:function(){return'
      '+(this.showIcon?'
      ':"")+(this.showText?'
      '+this.label+"
      ":"")+"
      "},postRender:function(){this.Stateful_postRender(),this.setDisabled(this.disabled)},_onMouseDown:function(a){var b=a.target||a.srcElement,c=b&&b.tagName&&b.tagName.toLowerCase();if("input"==c||"object"==c||"object"==c)return!1},_onClick:function(){this.isDisabled()||this.fireEvent("click")},setTitle:function(a){var b=this.getDom("label");b.innerHTML=a}},a.inherits(d,b),a.extend(d.prototype,c)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.uiUtils,c=(baidu.editor.dom.domUtils,baidu.editor.ui.UIBase),d=baidu.editor.ui.Stateful,e=baidu.editor.ui.SplitButton=function(a){this.initOptions(a),this.initSplitButton()};e.prototype={popup:null,uiName:"splitbutton",title:"",initSplitButton:function(){this.initUIBase(),this.Stateful_init();if(null!=this.popup){var a=this.popup;this.popup=null,this.setPopup(a)}},_UIBase_postRender:c.prototype.postRender,postRender:function(){this.Stateful_postRender(),this._UIBase_postRender()},setPopup:function(c){this.popup!==c&&(null!=this.popup&&this.popup.dispose(),c.addListener("show",a.bind(this._onPopupShow,this)),c.addListener("hide",a.bind(this._onPopupHide,this)),c.addListener("postrender",a.bind(function(){c.getDom("body").appendChild(b.createElementByHtml('
      ')),c.getDom().className+=" "+this.className},this)),this.popup=c)},_onPopupShow:function(){this.addState("opened")},_onPopupHide:function(){this.removeState("opened")},getHtmlTpl:function(){return'
      '},showPopup:function(){var a=b.getClientRect(this.getDom());a.top-=this.popup.SHADOW_RADIUS,a.height+=this.popup.SHADOW_RADIUS,this.popup.showAnchorRect(a)},_onArrowClick:function(a,b){this.isDisabled()||this.showPopup()},_onButtonClick:function(){this.isDisabled()||this.fireEvent("buttonclick")}},a.inherits(e,c),a.extend(e.prototype,d,!0)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.uiUtils,c=baidu.editor.ui.ColorPicker,d=baidu.editor.ui.Popup,e=baidu.editor.ui.SplitButton,f=baidu.editor.ui.ColorButton=function(a){this.initOptions(a),this.initColorButton()};f.prototype={initColorButton:function(){var a=this;this.popup=new d({content:new c({noColorText:a.editor.getLang("clearColor"),editor:a.editor,onpickcolor:function(b,c){a._onPickColor(c)},onpicknocolor:function(b,c){a._onPickNoColor(c)}}),editor:a.editor}),this.initSplitButton()},_SplitButton_postRender:e.prototype.postRender,postRender:function(){this._SplitButton_postRender(),this.getDom("button_body").appendChild(b.createElementByHtml('
      ')),this.getDom().className+=" edui-colorbutton"; +},setColor:function(a){this.getDom("colorlump").style.backgroundColor=a,this.color=a},_onPickColor:function(a){this.fireEvent("pickcolor",a)!==!1&&(this.setColor(a),this.popup.hide())},_onPickNoColor:function(a){this.fireEvent("picknocolor")!==!1&&this.popup.hide()}},a.inherits(f,e)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.Popup,c=baidu.editor.ui.TablePicker,d=baidu.editor.ui.SplitButton,e=baidu.editor.ui.TableButton=function(a){this.initOptions(a),this.initTableButton()};e.prototype={initTableButton:function(){var a=this;this.popup=new b({content:new c({editor:a.editor,onpicktable:function(b,c,d){a._onPickTable(c,d)}}),editor:a.editor}),this.initSplitButton()},_onPickTable:function(a,b){this.fireEvent("picktable",a,b)!==!1&&this.popup.hide()}},a.inherits(e,d)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.UIBase,c=baidu.editor.ui.AutoTypeSetPicker=function(a){this.initOptions(a),this.initAutoTypeSetPicker()};c.prototype={initAutoTypeSetPicker:function(){this.initUIBase()},getHtmlTpl:function(){var a=this.editor,b=a.options.autotypeset,c=a.getLang("autoTypeSet"),d="textAlignValue"+a.uid,e="imageBlockLineValue"+a.uid,f="symbolConverValue"+a.uid;return'
      "+c.mergeLine+'"+c.delLine+'
      "+c.removeFormat+'"+c.indent+'
      "+c.alignment+'"+a.getLang("justifyleft")+'"+a.getLang("justifycenter")+'"+a.getLang("justifyright")+'
      "+c.imageFloat+'"+a.getLang("default")+'"+a.getLang("justifyleft")+'"+a.getLang("justifycenter")+'"+a.getLang("justifyright")+'
      "+c.removeFontsize+'"+c.removeFontFamily+'
      "+c.removeHtml+'
      "+c.pasteFilter+'
      "+c.symbol+'"+c.bdc2sb+'"+c.tobdc+'
      "},_UIBase_render:b.prototype.render},a.inherits(c,b)}(),function(){function a(a){for(var c,d={},e=a.getDom(),f=a.editor.uid,g=null,h=null,i=domUtils.getElementsByTagName(e,"input"),j=i.length-1;c=i[j--];)if(g=c.getAttribute("type"),"checkbox"==g)if(h=c.getAttribute("name"),d[h]&&delete d[h],c.checked){var k=document.getElementById(h+"Value"+f);if(k){if(/input/gi.test(k.tagName))d[h]=k.value;else for(var l,m=k.getElementsByTagName("input"),n=m.length-1;l=m[n--];)if(l.checked){d[h]=l.value;break}}else d[h]=!0}else d[h]=!1;else d[c.getAttribute("value")]=c.checked;for(var o,p=domUtils.getElementsByTagName(e,"select"),j=0;o=p[j++];){var q=o.getAttribute("name");d[q]=d[q]?o.value:""}b.extend(a.editor.options.autotypeset,d),a.editor.setPreferences("autotypeset",d)}var b=baidu.editor.utils,c=baidu.editor.ui.Popup,d=baidu.editor.ui.AutoTypeSetPicker,e=baidu.editor.ui.SplitButton,f=baidu.editor.ui.AutoTypeSetButton=function(a){this.initOptions(a),this.initAutoTypeSetButton()};f.prototype={initAutoTypeSetButton:function(){var b=this;this.popup=new c({content:new d({editor:b.editor}),editor:b.editor,hide:function(){!this._hidden&&this.getDom()&&(a(this),this.getDom().style.display="none",this._hidden=!0,this.fireEvent("hide"))}});var e=0;this.popup.addListener("postRenderAfter",function(){var c=this;if(!e){var d=this.getDom(),f=d.getElementsByTagName("button")[0];f.onclick=function(){a(c),b.editor.execCommand("autotypeset"),c.hide()},domUtils.on(d,"click",function(d){var e=d.target||d.srcElement,f=b.editor.uid;if(e&&"INPUT"==e.tagName){if("imageBlockLine"==e.name||"textAlign"==e.name||"symbolConver"==e.name)for(var g=e.checked,h=document.getElementById(e.name+"Value"+f),i=h.getElementsByTagName("input"),j={imageBlockLine:"none",textAlign:"left",symbolConver:"tobdc"},k=0;k"),e.push('
      '),2===d&&e.push("");return'
      '+e.join("")+"
      "},getStateDom:function(){return this.target},_onClick:function(a){var c=a.target||a.srcElement;/icon/.test(c.className)&&(this.items[c.parentNode.getAttribute("index")].onclick(),b.postHide(a))},_UIBase_render:d.prototype.render},a.inherits(e,d),a.extend(e.prototype,c,!0)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.Stateful,c=baidu.editor.ui.uiUtils,d=baidu.editor.ui.UIBase,e=baidu.editor.ui.PastePicker=function(a){this.initOptions(a),this.initPastePicker()};e.prototype={initPastePicker:function(){this.initUIBase(),this.Stateful_init()},getHtmlTpl:function(){return'
      '+this.editor.getLang("pasteOpt")+'
      '},getStateDom:function(){return this.target},format:function(a){this.editor.ui._isTransfer=!0,this.editor.fireEvent("pasteTransfer",a)},_onClick:function(a){var b=domUtils.getNextDomNode(a),d=c.getViewportRect().height,e=c.getClientRect(b);e.top+e.height>d?b.style.top=-e.height-a.offsetHeight+"px":b.style.top="",/hidden/gi.test(domUtils.getComputedStyle(b,"visibility"))?(b.style.visibility="visible",domUtils.addClass(a,"edui-state-opened")):(b.style.visibility="hidden",domUtils.removeClasses(a,"edui-state-opened"))},_UIBase_render:d.prototype.render},a.inherits(e,d),a.extend(e.prototype,b,!0)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.uiUtils,c=baidu.editor.ui.UIBase,d=baidu.editor.ui.Toolbar=function(a){this.initOptions(a),this.initToolbar()};d.prototype={items:null,initToolbar:function(){this.items=this.items||[],this.initUIBase()},add:function(a,b){void 0===b?this.items.push(a):this.items.splice(b,0,a)},getHtmlTpl:function(){for(var a=[],b=0;b'+a.join("")+""},postRender:function(){for(var a=this.getDom(),c=0;c
      '},postRender:function(){},queryAutoHide:function(){return!0}};h.prototype={items:null,uiName:"menu",initMenu:function(){this.items=this.items||[],this.initPopup(),this.initItems()},initItems:function(){for(var a=0;a'+a.join("")+""},_Popup_postRender:e.prototype.postRender,postRender:function(){for(var a=this,d=0;d
      '+this.renderLabelHtml()+"
      "},postRender:function(){var a=this;this.addListener("over",function(){a.ownerMenu.fireEvent("submenuover",a),a.subMenu&&a.delayShowSubMenu()}),this.subMenu&&(this.getDom().className+=" edui-hassubmenu",this.subMenu.render(),this.addListener("out",function(){a.delayHideSubMenu()}),this.subMenu.addListener("over",function(){clearTimeout(a._closingTimer),a._closingTimer=null,a.addState("opened")}),this.ownerMenu.addListener("hide",function(){a.hideSubMenu()}),this.ownerMenu.addListener("submenuover",function(b,c){c!==a&&a.delayHideSubMenu()}),this.subMenu._bakQueryAutoHide=this.subMenu.queryAutoHide,this.subMenu.queryAutoHide=function(b){return(!b||!c.contains(a.getDom(),b))&&this._bakQueryAutoHide(b)}),this.getDom().style.tabIndex="-1",c.makeUnselectable(this.getDom()),this.Stateful_postRender()},delayShowSubMenu:function(){var a=this;a.isDisabled()||(a.addState("opened"),clearTimeout(a._showingTimer),clearTimeout(a._closingTimer),a._closingTimer=null,a._showingTimer=setTimeout(function(){a.showSubMenu()},250))},delayHideSubMenu:function(){var a=this;a.isDisabled()||(a.removeState("opened"),clearTimeout(a._showingTimer),a._closingTimer||(a._closingTimer=setTimeout(function(){a.hasState("opened")||a.hideSubMenu(),a._closingTimer=null},400)))},renderLabelHtml:function(){return'
      '+(this.label||"")+"
      "},getStateDom:function(){return this.getDom()},queryAutoHide:function(a){if(this.subMenu&&this.hasState("opened"))return this.subMenu.queryAutoHide(a)},_onClick:function(a,b){this.hasState("disabled")||this.fireEvent("click",a,b)!==!1&&(this.subMenu?this.showSubMenu():e.postHide(a))},showSubMenu:function(){var a=c.getClientRect(this.getDom());a.right-=5,a.left+=2,a.width-=7,a.top-=4,a.bottom+=4,a.height+=8,this.subMenu.showAnchorRect(a,!0,!0)},hideSubMenu:function(){this.subMenu.hide()}},a.inherits(j,d),a.extend(j.prototype,f,!0)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.uiUtils,c=baidu.editor.ui.Menu,d=baidu.editor.ui.SplitButton,e=baidu.editor.ui.Combox=function(a){this.initOptions(a),this.initCombox()};e.prototype={uiName:"combox",onbuttonclick:function(){this.showPopup()},initCombox:function(){var a=this;this.items=this.items||[];for(var b=0;bd.right&&(g=d.right-e.width);var h=a.top;h+e.height>d.bottom&&(h=d.bottom-e.height),c.style.left=Math.max(g,0)+"px",c.style.top=Math.max(h,0)+"px"},showAtCenter:function(){var a=f.getViewportRect();if(this.fullscreen){var b=this.getDom(),c=this.getDom("content");b.style.display="block";var d=UE.ui.uiUtils.getClientRect(b),g=UE.ui.uiUtils.getClientRect(c);b.style.left="-100000px",c.style.width=a.width-d.width+g.width+"px",c.style.height=a.height-d.height+g.height+"px",b.style.width=a.width+"px",b.style.height=a.height+"px",b.style.left=0,this._originalContext={html:{overflowX:document.documentElement.style.overflowX,overflowY:document.documentElement.style.overflowY},body:{overflowX:document.body.style.overflowX,overflowY:document.body.style.overflowY}},document.documentElement.style.overflowX="hidden",document.documentElement.style.overflowY="hidden",document.body.style.overflowX="hidden",document.body.style.overflowY="hidden"}else{this.getDom().style.display="";var h=this.fitSize(),i=0|this.getDom("titlebar").offsetHeight,j=a.width/2-h.width/2,k=a.height/2-(h.height-i)/2-i,l=this.getDom();this.safeSetOffset({left:Math.max(0|j,0),top:Math.max(0|k,0)}),e.hasClass(l,"edui-state-centered")||(l.className+=" edui-state-centered")}this._show()},getContentHtml:function(){var a="";return"string"==typeof this.content?a=this.content:this.iframeUrl&&(a=''),a},getHtmlTpl:function(){var a="";if(this.buttons){for(var b=[],c=0;c
      '+b.join("")+"
      "}return'
      '+(this.title||"")+"
      "+this.closeButton.renderHtml()+'
      '+(this.autoReset?"":this.getContentHtml())+"
      "+a+"
      "},postRender:function(){this.modalMask.getDom()||(this.modalMask.render(),this.modalMask.hide()),this.dragMask.getDom()||(this.dragMask.render(),this.dragMask.hide());var a=this;if(this.addListener("show",function(){a.modalMask.show(this.getDom().style.zIndex-2)}),this.addListener("hide",function(){a.modalMask.hide()}),this.buttons)for(var b=0;b',a.editor.container.style.zIndex&&(this.getDom().style.zIndex=1*a.editor.container.style.zIndex+1))}}),this.onbuttonclick=function(){this.showPopup()},this.initSplitButton()}},a.inherits(d,c)}(),function(){function a(a){var b=a.target||a.srcElement,c=g.findParent(b,function(a){return g.hasClass(a,"edui-shortcutmenu")||g.hasClass(a,"edui-popup")},!0);if(!c)for(var d,e=0;d=h[e++];)d.hide()}var b,c=baidu.editor.ui,d=c.UIBase,e=c.uiUtils,f=baidu.editor.utils,g=baidu.editor.dom.domUtils,h=[],i=!1,j=c.ShortCutMenu=function(a){this.initOptions(a),this.initShortCutMenu()};j.postHide=a,j.prototype={isHidden:!0,SPACE:5,initShortCutMenu:function(){this.items=this.items||[],this.initUIBase(),this.initItems(),this.initEvent(),h.push(this)},initEvent:function(){var a=this,c=a.editor.document;g.on(c,"mousemove",function(c){if(a.isHidden===!1){if(a.getSubMenuMark()||"contextmenu"==a.eventType)return;var d=!0,e=a.getDom(),f=e.offsetWidth,g=e.offsetHeight,h=f/2+a.SPACE,i=g/2,j=Math.abs(c.screenX-a.left),k=Math.abs(c.screenY-a.top);clearTimeout(b),b=setTimeout(function(){k>0&&ki&&ki+70&&k0&&jh&&jh+70&&j'+a+""}},f.inherits(j,d),g.on(document,"mousedown",function(b){a(b)}),g.on(window,"scroll",function(b){a(b)})}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.UIBase,c=baidu.editor.ui.Breakline=function(a){this.initOptions(a),this.initSeparator()};c.prototype={uiName:"Breakline",initSeparator:function(){this.initUIBase()},getHtmlTpl:function(){return"
      "}},a.inherits(c,b)}(),function(){var a=baidu.editor.utils,b=baidu.editor.dom.domUtils,c=baidu.editor.ui.UIBase,d=baidu.editor.ui.Message=function(a){this.initOptions(a),this.initMessage()};d.prototype={initMessage:function(){this.initUIBase()},getHtmlTpl:function(){return'
      ×
      '},reset:function(a){var b=this;a.keepshow||(clearTimeout(this.timer),b.timer=setTimeout(function(){b.hide()},a.timeout||4e3)),void 0!==a.content&&b.setContent(a.content),void 0!==a.type&&b.setType(a.type),b.show()},postRender:function(){var a=this,c=this.getDom("closer");c&&b.on(c,"click",function(){a.hide()})},setContent:function(a){this.getDom("content").innerHTML=a},setType:function(a){a=a||"info";var b=this.getDom("body");b.className=b.className.replace(/edui-message-type-[\w-]+/,"edui-message-type-"+a)},getContent:function(){return this.getDom("content").innerHTML},getType:function(){var a=this.getDom("body").match(/edui-message-type-([\w-]+)/);return a?a[1]:""},show:function(){this.getDom().style.display="block"},hide:function(){var a=this.getDom();a&&(a.style.display="none",a.parentNode&&a.parentNode.removeChild(a))}},a.inherits(d,c)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui,c=b.Dialog;b.buttons={},b.Dialog=function(a){var b=new c(a);return b.addListener("hide",function(){if(b.editor){var a=b.editor;try{if(browser.gecko){var c=a.window.scrollY,d=a.window.scrollX;a.body.focus(),a.window.scrollTo(d,c)}else a.focus()}catch(e){}}}),b};for(var d,e={anchor:"~/dialogs/anchor/anchor.html",insertimage:"~/dialogs/image/image.html",link:"~/dialogs/link/link.html",spechars:"~/dialogs/spechars/spechars.html",searchreplace:"~/dialogs/searchreplace/searchreplace.html",map:"~/dialogs/map/map.html",gmap:"~/dialogs/gmap/gmap.html",insertvideo:"~/dialogs/video/video.html",help:"~/dialogs/help/help.html",preview:"~/dialogs/preview/preview.html",emotion:"~/dialogs/emotion/emotion.html",wordimage:"~/dialogs/wordimage/wordimage.html",attachment:"~/dialogs/attachment/attachment.html",insertframe:"~/dialogs/insertframe/insertframe.html",edittip:"~/dialogs/table/edittip.html",edittable:"~/dialogs/table/edittable.html",edittd:"~/dialogs/table/edittd.html",webapp:"~/dialogs/webapp/webapp.html",snapscreen:"~/dialogs/snapscreen/snapscreen.html",scrawl:"~/dialogs/scrawl/scrawl.html",music:"~/dialogs/music/music.html",template:"~/dialogs/template/template.html",background:"~/dialogs/background/background.html",charts:"~/dialogs/charts/charts.html"},f=["undo","redo","formatmatch","bold","italic","underline","fontborder","touppercase","tolowercase","strikethrough","subscript","superscript","source","indent","outdent","blockquote","pasteplain","pagebreak","selectall","print","horizontal","removeformat","time","date","unlink","insertparagraphbeforetable","insertrow","insertcol","mergeright","mergedown","deleterow","deletecol","splittorows","splittocols","splittocells","mergecells","deletetable","drafts"],g=0;d=f[g++];)d=d.toLowerCase(),b[d]=function(a){return function(c){var d=new b.Button({className:"edui-for-"+a,title:c.options.labelMap[a]||c.getLang("labelMap."+a)||"",onclick:function(){c.execCommand(a)},theme:c.options.theme,showText:!1});return b.buttons[a]=d,c.addListener("selectionchange",function(b,e,f){var g=c.queryCommandState(a);g==-1?(d.setDisabled(!0),d.setChecked(!1)):f||(d.setDisabled(!1),d.setChecked(g))}),d}}(d);b.cleardoc=function(a){var c=new b.Button({className:"edui-for-cleardoc",title:a.options.labelMap.cleardoc||a.getLang("labelMap.cleardoc")||"",theme:a.options.theme,onclick:function(){confirm(a.getLang("confirmClear"))&&a.execCommand("cleardoc")}});return b.buttons.cleardoc=c,a.addListener("selectionchange",function(){c.setDisabled(a.queryCommandState("cleardoc")==-1)}),c};var h={justify:["left","right","center","justify"],imagefloat:["none","left","center","right"],directionality:["ltr","rtl"]};for(var i in h)!function(a,c){for(var d,e=0;d=c[e++];)!function(c){b[a.replace("float","")+c]=function(d){var e=new b.Button({ +className:"edui-for-"+a.replace("float","")+c,title:d.options.labelMap[a.replace("float","")+c]||d.getLang("labelMap."+a.replace("float","")+c)||"",theme:d.options.theme,onclick:function(){d.execCommand(a,c)}});return b.buttons[a]=e,d.addListener("selectionchange",function(b,f,g){e.setDisabled(d.queryCommandState(a)==-1),e.setChecked(d.queryCommandValue(a)==c&&!g)}),e}}(d)}(i,h[i]);for(var d,g=0;d=["backcolor","forecolor"][g++];)b[d]=function(a){return function(c){var d=new b.ColorButton({className:"edui-for-"+a,color:"default",title:c.options.labelMap[a]||c.getLang("labelMap."+a)||"",editor:c,onpickcolor:function(b,d){c.execCommand(a,d)},onpicknocolor:function(){c.execCommand(a,"default"),this.setColor("transparent"),this.color="default"},onbuttonclick:function(){c.execCommand(a,this.color)}});return b.buttons[a]=d,c.addListener("selectionchange",function(){d.setDisabled(c.queryCommandState(a)==-1)}),d}}(d);var j={noOk:["searchreplace","help","spechars","webapp","preview"],ok:["attachment","anchor","link","insertimage","map","gmap","insertframe","wordimage","insertvideo","insertframe","edittip","edittable","edittd","scrawl","template","music","background","charts"]};for(var i in j)!function(c,d){for(var f,g=0;f=d[g++];)browser.opera&&"searchreplace"===f||!function(d){b[d]=function(f,g,h){g=g||(f.options.iframeUrlMap||{})[d]||e[d],h=f.options.labelMap[d]||f.getLang("labelMap."+d)||"";var i;g&&(i=new b.Dialog(a.extend({iframeUrl:f.ui.mapUrl(g),editor:f,className:"edui-for-"+d,title:h,holdScroll:"insertimage"===d,fullscreen:/charts|preview/.test(d),closeDialog:f.getLang("closeDialog")},"ok"==c?{buttons:[{className:"edui-okbutton",label:f.getLang("ok"),editor:f,onclick:function(){i.close(!0)}},{className:"edui-cancelbutton",label:f.getLang("cancel"),editor:f,onclick:function(){i.close(!1)}}]}:{})),f.ui._dialogs[d+"Dialog"]=i);var j=new b.Button({className:"edui-for-"+d,title:h,onclick:function(){if(i)switch(d){case"wordimage":var a=f.execCommand("wordimage");a&&a.length&&(i.render(),i.open());break;case"scrawl":f.queryCommandState("scrawl")!=-1&&(i.render(),i.open());break;default:i.render(),i.open()}},theme:f.options.theme,disabled:"scrawl"==d&&f.queryCommandState("scrawl")==-1||"charts"==d});return b.buttons[d]=j,f.addListener("selectionchange",function(){var a={edittable:1};if(!(d in a)){var b=f.queryCommandState(d);j.getDom()&&(j.setDisabled(b==-1),j.setChecked(b))}}),j}}(f.toLowerCase())}(i,j[i]);b.snapscreen=function(a,c,d){d=a.options.labelMap.snapscreen||a.getLang("labelMap.snapscreen")||"";var f=new b.Button({className:"edui-for-snapscreen",title:d,onclick:function(){a.execCommand("snapscreen")},theme:a.options.theme});if(b.buttons.snapscreen=f,c=c||(a.options.iframeUrlMap||{}).snapscreen||e.snapscreen){var g=new b.Dialog({iframeUrl:a.ui.mapUrl(c),editor:a,className:"edui-for-snapscreen",title:d,buttons:[{className:"edui-okbutton",label:a.getLang("ok"),editor:a,onclick:function(){g.close(!0)}},{className:"edui-cancelbutton",label:a.getLang("cancel"),editor:a,onclick:function(){g.close(!1)}}]});g.render(),a.ui._dialogs.snapscreenDialog=g}return a.addListener("selectionchange",function(){f.setDisabled(a.queryCommandState("snapscreen")==-1)}),f},b.insertcode=function(c,d,e){d=c.options.insertcode||[],e=c.options.labelMap.insertcode||c.getLang("labelMap.insertcode")||"";var f=[];a.each(d,function(a,b){f.push({label:a,value:b,theme:c.options.theme,renderLabelHtml:function(){return'
      '+(this.label||"")+"
      "}})});var g=new b.Combox({editor:c,items:f,onselect:function(a,b){c.execCommand("insertcode",this.items[b].value)},onbuttonclick:function(){this.showPopup()},title:e,initValue:e,className:"edui-for-insertcode",indexByValue:function(a){if(a)for(var b,c=0;b=this.items[c];c++)if(b.value.indexOf(a)!=-1)return c;return-1}});return b.buttons.insertcode=g,c.addListener("selectionchange",function(a,b,d){if(!d){var f=c.queryCommandState("insertcode");if(f==-1)g.setDisabled(!0);else{g.setDisabled(!1);var h=c.queryCommandValue("insertcode");if(!h)return void g.setValue(e);h&&(h=h.replace(/['"]/g,"").split(",")[0]),g.setValue(h)}}}),g},b.fontfamily=function(c,d,e){if(d=c.options.fontfamily||[],e=c.options.labelMap.fontfamily||c.getLang("labelMap.fontfamily")||"",d.length){for(var f,g=0,h=[];f=d[g];g++){var i=c.getLang("fontfamily")[f.name]||"";!function(b,d){h.push({label:b,value:d,theme:c.options.theme,renderLabelHtml:function(){return'
      '+(this.label||"")+"
      "}})}(f.label||i,f.val)}var j=new b.Combox({editor:c,items:h,onselect:function(a,b){c.execCommand("FontFamily",this.items[b].value)},onbuttonclick:function(){this.showPopup()},title:e,initValue:e,className:"edui-for-fontfamily",indexByValue:function(a){if(a)for(var b,c=0;b=this.items[c];c++)if(b.value.indexOf(a)!=-1)return c;return-1}});return b.buttons.fontfamily=j,c.addListener("selectionchange",function(a,b,d){if(!d){var e=c.queryCommandState("FontFamily");if(e==-1)j.setDisabled(!0);else{j.setDisabled(!1);var f=c.queryCommandValue("FontFamily");f&&(f=f.replace(/['"]/g,"").split(",")[0]),j.setValue(f)}}}),j}},b.fontsize=function(a,c,d){if(d=a.options.labelMap.fontsize||a.getLang("labelMap.fontsize")||"",c=c||a.options.fontsize||[],c.length){for(var e=[],f=0;f'+(this.label||"")+""}})}var h=new b.Combox({editor:a,items:e,title:d,initValue:d,onselect:function(b,c){a.execCommand("FontSize",this.items[c].value)},onbuttonclick:function(){this.showPopup()},className:"edui-for-fontsize"});return b.buttons.fontsize=h,a.addListener("selectionchange",function(b,c,d){if(!d){var e=a.queryCommandState("FontSize");e==-1?h.setDisabled(!0):(h.setDisabled(!1),h.setValue(a.queryCommandValue("FontSize")))}}),h}},b.paragraph=function(c,d,e){if(e=c.options.labelMap.paragraph||c.getLang("labelMap.paragraph")||"",d=c.options.paragraph||[],!a.isEmptyObject(d)){var f=[];for(var g in d)f.push({value:g,label:d[g]||c.getLang("paragraph")[g],theme:c.options.theme,renderLabelHtml:function(){return'
      '+(this.label||"")+"
      "}});var h=new b.Combox({editor:c,items:f,title:e,initValue:e,className:"edui-for-paragraph",onselect:function(a,b){c.execCommand("Paragraph",this.items[b].value)},onbuttonclick:function(){this.showPopup()}});return b.buttons.paragraph=h,c.addListener("selectionchange",function(a,b,d){if(!d){var e=c.queryCommandState("Paragraph");if(e==-1)h.setDisabled(!0);else{h.setDisabled(!1);var f=c.queryCommandValue("Paragraph"),g=h.indexByValue(f);g!=-1?h.setValue(f):h.setValue(h.initValue)}}}),h}},b.customstyle=function(a){var c=a.options.customstyle||[],d=a.options.labelMap.customstyle||a.getLang("labelMap.customstyle")||"";if(c.length){for(var e,f=a.getLang("customstyle"),g=0,h=[];e=c[g++];)!function(b){var c={};c.label=b.label?b.label:f[b.name],c.style=b.style,c.className=b.className,c.tag=b.tag,h.push({label:c.label,value:c,theme:a.options.theme,renderLabelHtml:function(){return'
      <'+c.tag+" "+(c.className?' class="'+c.className+'"':"")+(c.style?' style="'+c.style+'"':"")+">"+c.label+"
      "}})}(e);var i=new b.Combox({editor:a,items:h,title:d,initValue:d,className:"edui-for-customstyle",onselect:function(b,c){a.execCommand("customstyle",this.items[c].value)},onbuttonclick:function(){this.showPopup()},indexByValue:function(a){for(var b,c=0;b=this.items[c++];)if(b.label==a)return c-1;return-1}});return b.buttons.customstyle=i,a.addListener("selectionchange",function(b,c,d){if(!d){var e=a.queryCommandState("customstyle");if(e==-1)i.setDisabled(!0);else{i.setDisabled(!1);var f=a.queryCommandValue("customstyle"),g=i.indexByValue(f);g!=-1?i.setValue(f):i.setValue(i.initValue)}}}),i}},b.inserttable=function(a,c,d){d=a.options.labelMap.inserttable||a.getLang("labelMap.inserttable")||"";var e=new b.TableButton({editor:a,title:d,className:"edui-for-inserttable",onpicktable:function(b,c,d){a.execCommand("InsertTable",{numRows:d,numCols:c,border:1})},onbuttonclick:function(){this.showPopup()}});return b.buttons.inserttable=e,a.addListener("selectionchange",function(){e.setDisabled(a.queryCommandState("inserttable")==-1)}),e},b.lineheight=function(a){var c=a.options.lineheight||[];if(c.length){for(var d,e=0,f=[];d=c[e++];)f.push({label:d,value:d,theme:a.options.theme,onclick:function(){a.execCommand("lineheight",this.value)}});var g=new b.MenuButton({editor:a,className:"edui-for-lineheight",title:a.options.labelMap.lineheight||a.getLang("labelMap.lineheight")||"",items:f,onbuttonclick:function(){var b=a.queryCommandValue("LineHeight")||this.value;a.execCommand("LineHeight",b)}});return b.buttons.lineheight=g,a.addListener("selectionchange",function(){var b=a.queryCommandState("LineHeight");if(b==-1)g.setDisabled(!0);else{g.setDisabled(!1);var c=a.queryCommandValue("LineHeight");c&&g.setValue((c+"").replace(/cm/,"")),g.setChecked(b)}}),g}};for(var k,l=["top","bottom"],m=0;k=l[m++];)!function(a){b["rowspacing"+a]=function(c){var d=c.options["rowspacing"+a]||[];if(!d.length)return null;for(var e,f=0,g=[];e=d[f++];)g.push({label:e,value:e,theme:c.options.theme,onclick:function(){c.execCommand("rowspacing",this.value,a)}});var h=new b.MenuButton({editor:c,className:"edui-for-rowspacing"+a,title:c.options.labelMap["rowspacing"+a]||c.getLang("labelMap.rowspacing"+a)||"",items:g,onbuttonclick:function(){var b=c.queryCommandValue("rowspacing",a)||this.value;c.execCommand("rowspacing",b,a)}});return b.buttons[a]=h,c.addListener("selectionchange",function(){var b=c.queryCommandState("rowspacing",a);if(b==-1)h.setDisabled(!0);else{h.setDisabled(!1);var d=c.queryCommandValue("rowspacing",a);d&&h.setValue((d+"").replace(/%/,"")),h.setChecked(b)}}),h}}(k);for(var n,o=["insertorderedlist","insertunorderedlist"],p=0;n=o[p++];)!function(a){b[a]=function(c){var d=c.options[a],e=function(){c.execCommand(a,this.value)},f=[];for(var g in d)f.push({label:d[g]||c.getLang()[a][g]||"",value:g,theme:c.options.theme,onclick:e});var h=new b.MenuButton({editor:c,className:"edui-for-"+a,title:c.getLang("labelMap."+a)||"",items:f,onbuttonclick:function(){var b=c.queryCommandValue(a)||this.value;c.execCommand(a,b)}});return b.buttons[a]=h,c.addListener("selectionchange",function(){var b=c.queryCommandState(a);if(b==-1)h.setDisabled(!0);else{h.setDisabled(!1);var d=c.queryCommandValue(a);h.setValue(d),h.setChecked(b)}}),h}}(n);b.fullscreen=function(a,c){c=a.options.labelMap.fullscreen||a.getLang("labelMap.fullscreen")||"";var d=new b.Button({className:"edui-for-fullscreen",title:c,theme:a.options.theme,onclick:function(){a.ui&&a.ui.setFullScreen(!a.ui.isFullScreen()),this.setChecked(a.ui.isFullScreen())}});return b.buttons.fullscreen=d,a.addListener("selectionchange",function(){var b=a.queryCommandState("fullscreen");d.setDisabled(b==-1),d.setChecked(a.ui.isFullScreen())}),d},b.emotion=function(a,c){var d="emotion",f=new b.MultiMenuPop({title:a.options.labelMap[d]||a.getLang("labelMap."+d)||"",editor:a,className:"edui-for-"+d,iframeUrl:a.ui.mapUrl(c||(a.options.iframeUrlMap||{})[d]||e[d])});return b.buttons[d]=f,a.addListener("selectionchange",function(){f.setDisabled(a.queryCommandState(d)==-1)}),f},b.autotypeset=function(a){var c=new b.AutoTypeSetButton({editor:a,title:a.options.labelMap.autotypeset||a.getLang("labelMap.autotypeset")||"",className:"edui-for-autotypeset",onbuttonclick:function(){a.execCommand("autotypeset")}});return b.buttons.autotypeset=c,a.addListener("selectionchange",function(){c.setDisabled(a.queryCommandState("autotypeset")==-1)}),c},b.simpleupload=function(a){var c="simpleupload",d=new b.Button({className:"edui-for-"+c,title:a.options.labelMap[c]||a.getLang("labelMap."+c)||"",onclick:function(){},theme:a.options.theme,showText:!1});return b.buttons[c]=d,a.addListener("ready",function(){var b=d.getDom("body"),c=b.children[0];a.fireEvent("simpleuploadbtnready",c)}),a.addListener("selectionchange",function(b,e,f){var g=a.queryCommandState(c);g==-1?(d.setDisabled(!0),d.setChecked(!1)):f||(d.setDisabled(!1),d.setChecked(g))}),d}}(),function(){function a(a){this.initOptions(a),this.initEditorUI()}var b=baidu.editor.utils,c=baidu.editor.ui.uiUtils,d=baidu.editor.ui.UIBase,e=baidu.editor.dom.domUtils,f=[];a.prototype={uiName:"editor",initEditorUI:function(){function a(a,b){a.setOpt({wordCount:!0,maximumWords:1e4,wordCountMsg:a.options.wordCountMsg||a.getLang("wordCountMsg"),wordOverFlowMsg:a.options.wordOverFlowMsg||a.getLang("wordOverFlowMsg")});var c=a.options,d=c.maximumWords,e=c.wordCountMsg,f=c.wordOverFlowMsg,g=b.getDom("wordcount");if(c.wordCount){var h=a.getContentLength(!0);h>d?(g.innerHTML=f,a.fireEvent("wordcountoverflow")):g.innerHTML=e.replace("{#leave}",d-h).replace("{#count}",h)}}this.editor.ui=this,this._dialogs={},this.initUIBase(),this._initToolbars();var b=this.editor,c=this;b.addListener("ready",function(){function d(){a(b,c),e.un(b.document,"click",arguments.callee)}b.getDialog=function(a){return b.ui._dialogs[a+"Dialog"]},e.on(b.window,"scroll",function(a){baidu.editor.ui.Popup.postHide(a)}),b.ui._actualFrameWidth=b.options.initialFrameWidth,UE.browser.ie&&6===UE.browser.version&&b.container.ownerDocument.execCommand("BackgroundImageCache",!1,!0),b.options.elementPathEnabled&&(b.ui.getDom("elementpath").innerHTML='
      '+b.getLang("elementPathTip")+":
      "),b.options.wordCount&&(e.on(b.document,"click",d),b.ui.getDom("wordcount").innerHTML=b.getLang("wordCountTip")),b.ui._scale(),b.options.scaleEnabled?(b.autoHeightEnabled&&b.disableAutoHeight(),c.enableScale()):c.disableScale(),b.options.elementPathEnabled||b.options.wordCount||b.options.scaleEnabled||(b.ui.getDom("elementpath").style.display="none",b.ui.getDom("wordcount").style.display="none",b.ui.getDom("scale").style.display="none"),b.selection.isFocus()&&b.fireEvent("selectionchange",!1,!0)}),b.addListener("mousedown",function(a,b){var c=b.target||b.srcElement;baidu.editor.ui.Popup.postHide(b,c),baidu.editor.ui.ShortCutMenu.postHide(b)}),b.addListener("delcells",function(){UE.ui.edittip&&new UE.ui.edittip(b),b.getDialog("edittip").open()});var d,f,g=!1;b.addListener("afterpaste",function(){b.queryCommandState("pasteplain")||(baidu.editor.ui.PastePicker&&(d=new baidu.editor.ui.Popup({content:new baidu.editor.ui.PastePicker({editor:b}),editor:b,className:"edui-wordpastepop"}),d.render()),g=!0)}),b.addListener("afterinserthtml",function(){clearTimeout(f),f=setTimeout(function(){if(d&&(g||b.ui._isTransfer)){if(d.isHidden()){var a=e.createElement(b.document,"span",{style:"line-height:0px;",innerHTML:"\ufeff"}),c=b.selection.getRange();c.insertNode(a);var f=getDomNode(a,"firstChild","previousSibling");f&&d.showAnchor(3==f.nodeType?f.parentNode:f),e.remove(a)}else d.show();delete b.ui._isTransfer,g=!1}},200)}),b.addListener("contextmenu",function(a,b){baidu.editor.ui.Popup.postHide(b)}),b.addListener("keydown",function(a,b){d&&d.dispose(b);var c=b.keyCode||b.which;b.altKey&&90==c&&UE.ui.buttons.fullscreen.onclick()}),b.addListener("wordcount",function(b){a(this,c)}),b.addListener("selectionchange",function(){b.options.elementPathEnabled&&c[(b.queryCommandState("elementpath")==-1?"dis":"en")+"ableElementPath"](),b.options.scaleEnabled&&c[(b.queryCommandState("scale")==-1?"dis":"en")+"ableScale"]()});var h=new baidu.editor.ui.Popup({editor:b,content:"",className:"edui-bubble",_onEditButtonClick:function(){this.hide(),b.ui._dialogs.linkDialog.open()},_onImgEditButtonClick:function(a){this.hide(),b.ui._dialogs[a]&&b.ui._dialogs[a].open()},_onImgSetFloat:function(a){this.hide(),b.execCommand("imagefloat",a)},_setIframeAlign:function(a){var b=h.anchorEl,c=b.cloneNode(!0);switch(a){case-2:c.setAttribute("align","");break;case-1:c.setAttribute("align","left");break;case 1:c.setAttribute("align","right")}b.parentNode.insertBefore(c,b),e.remove(b),h.anchorEl=c,h.showAnchor(h.anchorEl)},_updateIframe:function(){var a=b._iframe=h.anchorEl;e.hasClass(a,"ueditor_baidumap")?(b.selection.getRange().selectNode(a).select(),b.ui._dialogs.mapDialog.open(),h.hide()):(b.ui._dialogs.insertframeDialog.open(),h.hide())},_onRemoveButtonClick:function(a){b.execCommand(a),this.hide()},queryAutoHide:function(a){return a&&a.ownerDocument==b.document&&("img"==a.tagName.toLowerCase()||e.findParentByTagName(a,"a",!0))?a!==h.anchorEl:baidu.editor.ui.Popup.prototype.queryAutoHide.call(this,a)}});h.render(),b.options.imagePopup&&(b.addListener("mouseover",function(a,c){c=c||window.event;var d=c.target||c.srcElement;if(b.ui._dialogs.insertframeDialog&&/iframe/gi.test(d.tagName)){var e=h.formatHtml(""+b.getLang("property")+': '+b.getLang("default")+'  '+b.getLang("justifyleft")+'  '+b.getLang("justifyright")+'   '+b.getLang("modify")+"");e?(h.getDom("content").innerHTML=e,h.anchorEl=d,h.showAnchor(h.anchorEl)):h.hide()}}),b.addListener("selectionchange",function(a,c){if(c){var d="",f="",g=b.selection.getRange().getClosedNode(),i=b.ui._dialogs;if(g&&"IMG"==g.tagName){var j="insertimageDialog";if(g.className.indexOf("edui-faked-video")==-1&&g.className.indexOf("edui-upload-video")==-1||(j="insertvideoDialog"),g.className.indexOf("edui-faked-webapp")!=-1&&(j="webappDialog"),g.src.indexOf("http://api.map.baidu.com")!=-1&&(j="mapDialog"),g.className.indexOf("edui-faked-music")!=-1&&(j="musicDialog"),g.src.indexOf("http://maps.google.com/maps/api/staticmap")!=-1&&(j="gmapDialog"),g.getAttribute("anchorname")&&(j="anchorDialog",d=h.formatHtml(""+b.getLang("property")+': '+b.getLang("modify")+"  "+b.getLang("delete")+"")),g.getAttribute("word_img")&&(b.word_img=[g.getAttribute("word_img")],j="wordimageDialog"),(e.hasClass(g,"loadingclass")||e.hasClass(g,"loaderrorclass"))&&(j=""),!i[j])return;f=""+b.getLang("property")+': '+b.getLang("default")+'  '+b.getLang("justifyleft")+'  '+b.getLang("justifyright")+'  '+b.getLang("justifycenter")+"  '+b.getLang("modify")+"",!d&&(d=h.formatHtml(f))}if(b.ui._dialogs.linkDialog){var k,l=b.queryCommandValue("link");if(l&&(k=l.getAttribute("_href")||l.getAttribute("href",2))){var m=k;k.length>30&&(m=k.substring(0,20)+"..."),d&&(d+='
      '),d+=h.formatHtml(""+b.getLang("anthorMsg")+': '+m+' '+b.getLang("modify")+' '+b.getLang("clear")+""),h.showAnchor(l)}}d?(h.getDom("content").innerHTML=d,h.anchorEl=g||l,h.showAnchor(h.anchorEl)):h.hide()}}))},_initToolbars:function(){for(var a=this.editor,c=this.toolbars||[],d=[],e=0;e
      '+(this.toolbars.length?'
      '+this.renderToolbarBoxHtml()+"
      ":"")+'
      '},showWordImageDialog:function(){this._dialogs.wordimageDialog.open()},renderToolbarBoxHtml:function(){for(var a=[],b=0;b'+c+"");b.innerHTML='
      '+this.editor.getLang("elementPathTip")+": "+d.join(" > ")+"
      "}else b.style.display="none"},disableElementPath:function(){var a=this.getDom("elementpath");a.innerHTML="",a.style.display="none",this.elementPathEnabled=!1},enableElementPath:function(){var a=this.getDom("elementpath");a.style.display="",this.elementPathEnabled=!0,this._updateElementPath()},_scale:function(){function a(){o=e.getXY(h),p||(p=g.options.minFrameHeight+j.offsetHeight+k.offsetHeight),m.style.cssText="position:absolute;left:0;display:;top:0;background-color:#41ABFF;opacity:0.4;filter: Alpha(opacity=40);width:"+h.offsetWidth+"px;height:"+h.offsetHeight+"px;z-index:"+(g.options.zIndex+1),e.on(f,"mousemove",b),e.on(i,"mouseup",c),e.on(f,"mouseup",c)}function b(a){d();var b=a||window.event;r=b.pageX||f.documentElement.scrollLeft+b.clientX,s=b.pageY||f.documentElement.scrollTop+b.clientY,t=r-o.x,u=s-o.y,t>=q&&(n=!0,m.style.width=t+"px"),u>=p&&(n=!0,m.style.height=u+"px")}function c(){n&&(n=!1,g.ui._actualFrameWidth=m.offsetWidth-2,h.style.width=g.ui._actualFrameWidth+"px",g.setHeight(m.offsetHeight-k.offsetHeight-j.offsetHeight-2,!0)),m&&(m.style.display="none"),d(),e.un(f,"mousemove",b),e.un(i,"mouseup",c),e.un(f,"mouseup",c)}function d(){browser.ie?f.selection.clear():window.getSelection().removeAllRanges()}var f=document,g=this.editor,h=g.container,i=g.document,j=this.getDom("toolbarbox"),k=this.getDom("bottombar"),l=this.getDom("scale"),m=this.getDom("scalelayer"),n=!1,o=null,p=0,q=g.options.minFrameWidth,r=0,s=0,t=0,u=0,v=this;this.editor.addListener("fullscreenchanged",function(a,b){if(b)v.disableScale();else if(v.editor.options.scaleEnabled){v.enableScale();var c=v.editor.document.createElement("span");v.editor.body.appendChild(c),v.editor.body.style.height=Math.max(e.getXY(c).y,v.editor.iframe.offsetHeight-20)+"px",e.remove(c)}}),this.enableScale=function(){1!=g.queryCommandState("source")&&(l.style.display="",this.scaleEnabled=!0,e.on(l,"mousedown",a))},this.disableScale=function(){l.style.display="none",this.scaleEnabled=!1,e.un(l,"mousedown",a)}},isFullScreen:function(){return this._fullscreen},postRender:function(){d.prototype.postRender.call(this);for(var a=0;a[\n\r\t]+([ ]{4})+/g,">").replace(/[\n\r\t]+([ ]{4})+[\n\r\t]+<"),c.className&&(b.className=c.className),c.style.cssText&&(b.style.cssText=c.style.cssText),/textarea/i.test(c.tagName)?(d.textarea=c,d.textarea.style.display="none"):c.parentNode.removeChild(c),c.id&&(b.id=c.id,e.removeAttributes(c,"id")),c=b,c.innerHTML=""}e.addClass(c,"edui-"+d.options.theme),d.ui.render(c);var h=d.options;d.container=d.ui.getDom();for(var i,j=e.findParents(c,!0),k=[],l=0;i=j[l];l++)k[l]=i.style.display,i.style.display="block";if(h.initialFrameWidth)h.minFrameWidth=h.initialFrameWidth;else{h.minFrameWidth=h.initialFrameWidth=c.offsetWidth;var m=c.style.width;/%$/.test(m)&&(h.initialFrameWidth=m)}h.initialFrameHeight?h.minFrameHeight=h.initialFrameHeight:h.initialFrameHeight=h.minFrameHeight=c.offsetHeight;for(var i,l=0;i=j[l];l++)i.style.display=k[l];c.style.height&&(c.style.height=""),d.container.style.width=h.initialFrameWidth+(/%$/.test(h.initialFrameWidth)?"":"px"),d.container.style.zIndex=h.zIndex,f.call(d,d.ui.getDom("iframeholder")),d.fireEvent("afteruiready")}d.langIsReady?b():d.addListener("langReady",b)})},d},UE.getEditor=function(a,b){var c=g[a];return c||(c=g[a]=new UE.ui.Editor(b),c.render(a)),c},UE.delEditor=function(a){var b;(b=g[a])&&(b.key&&b.destroy(),delete g[a])},UE.registerUI=function(a,c,d,e){b.each(a.split(/\s+/),function(a){UE._customizeUI[a]={id:e,execFn:c,index:d}})}}(),UE.registerUI("message",function(a){function b(){var a=g.ui.getDom("toolbarbox");a&&(c.style.top=a.offsetHeight+3+"px"),c.style.zIndex=Math.max(g.options.zIndex,g.iframe.style.zIndex)+1}var c,d=baidu.editor.ui,e=d.Message,f=[],g=a;g.addListener("ready",function(){c=document.getElementById(g.ui.id+"_message_holder"),b(),setTimeout(function(){b()},500)}),g.addListener("showmessage",function(a,d){d=utils.isString(d)?{content:d}:d;var h=new e({timeout:d.timeout,type:d.type,content:d.content,keepshow:d.keepshow,editor:g}),i=d.id||"msg_"+(+new Date).toString(36);return h.render(c),f[i]=h,h.reset(d),b(),i}),g.addListener("updatemessage",function(a,b,d){d=utils.isString(d)?{content:d}:d;var e=f[b];e.render(c),e&&e.reset(d)}),g.addListener("hidemessage",function(a,b){var c=f[b];c&&c.hide()})}),UE.registerUI("autosave",function(a){var b=null,c=null;a.on("afterautosave",function(){clearTimeout(b),b=setTimeout(function(){c&&a.trigger("hidemessage",c),c=a.trigger("showmessage",{content:a.getLang("autosave.success"),timeout:2e3})},2e3)})})}(); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/assets/lib/ueditor/video-clip.png b/net452/SiteServer.Web/Home/assets/lib/ueditor/video-clip.png new file mode 100644 index 000000000..18f06ae46 Binary files /dev/null and b/net452/SiteServer.Web/Home/assets/lib/ueditor/video-clip.png differ diff --git a/net452/SiteServer.Web/Home/assets/lib/vee-validate-2.1.0.js b/net452/SiteServer.Web/Home/assets/lib/vee-validate-2.1.0.js new file mode 100644 index 000000000..3e137bfe2 --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/lib/vee-validate-2.1.0.js @@ -0,0 +1,7933 @@ +/** + * vee-validate v2.1.0-beta.9 + * (c) 2018 Abdelrahman Awad + * @license MIT + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.VeeValidate = factory()); +}(this, (function () { 'use strict'; + + var MILLISECONDS_IN_HOUR = 3600000; + var MILLISECONDS_IN_MINUTE = 60000; + var DEFAULT_ADDITIONAL_DIGITS = 2; + + var patterns = { + dateTimeDelimeter: /[T ]/, + plainTime: /:/, + + // year tokens + YY: /^(\d{2})$/, + YYY: [ + /^([+-]\d{2})$/, // 0 additional digits + /^([+-]\d{3})$/, // 1 additional digit + /^([+-]\d{4})$/ // 2 additional digits + ], + YYYY: /^(\d{4})/, + YYYYY: [ + /^([+-]\d{4})/, // 0 additional digits + /^([+-]\d{5})/, // 1 additional digit + /^([+-]\d{6})/ // 2 additional digits + ], + + // date tokens + MM: /^-(\d{2})$/, + DDD: /^-?(\d{3})$/, + MMDD: /^-?(\d{2})-?(\d{2})$/, + Www: /^-?W(\d{2})$/, + WwwD: /^-?W(\d{2})-?(\d{1})$/, + + HH: /^(\d{2}([.,]\d*)?)$/, + HHMM: /^(\d{2}):?(\d{2}([.,]\d*)?)$/, + HHMMSS: /^(\d{2}):?(\d{2}):?(\d{2}([.,]\d*)?)$/, + + // timezone tokens + timezone: /([Z+-].*)$/, + timezoneZ: /^(Z)$/, + timezoneHH: /^([+-])(\d{2})$/, + timezoneHHMM: /^([+-])(\d{2}):?(\d{2})$/ + }; + + /** + * @name toDate + * @category Common Helpers + * @summary Convert the given argument to an instance of Date. + * + * @description + * Convert the given argument to an instance of Date. + * + * If the argument is an instance of Date, the function returns its clone. + * + * If the argument is a number, it is treated as a timestamp. + * + * If an argument is a string, the function tries to parse it. + * Function accepts complete ISO 8601 formats as well as partial implementations. + * ISO 8601: http://en.wikipedia.org/wiki/ISO_8601 + * + * If the argument is null, it is treated as an invalid date. + * + * If all above fails, the function passes the given argument to Date constructor. + * + * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`. + * All *date-fns* functions will throw `RangeError` if `options.additionalDigits` is not 0, 1, 2 or undefined. + * + * @param {*} argument - the value to convert + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - the additional number of digits in the extended year format + * @returns {Date} the parsed date in the local time zone + * @throws {TypeError} 1 argument required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Convert string '2014-02-11T11:30:30' to date: + * var result = toDate('2014-02-11T11:30:30') + * //=> Tue Feb 11 2014 11:30:30 + * + * @example + * // Convert string '+02014101' to date, + * // if the additional number of digits in the extended year format is 1: + * var result = toDate('+02014101', {additionalDigits: 1}) + * //=> Fri Apr 11 2014 00:00:00 + */ + function toDate (argument, dirtyOptions) { + if (arguments.length < 1) { + throw new TypeError('1 argument required, but only ' + arguments.length + ' present') + } + + if (argument === null) { + return new Date(NaN) + } + + var options = dirtyOptions || {}; + + var additionalDigits = options.additionalDigits === undefined ? DEFAULT_ADDITIONAL_DIGITS : Number(options.additionalDigits); + if (additionalDigits !== 2 && additionalDigits !== 1 && additionalDigits !== 0) { + throw new RangeError('additionalDigits must be 0, 1 or 2') + } + + // Clone the date + if (argument instanceof Date) { + // Prevent the date to lose the milliseconds when passed to new Date() in IE10 + return new Date(argument.getTime()) + } else if (typeof argument !== 'string') { + return new Date(argument) + } + + var dateStrings = splitDateString(argument); + + var parseYearResult = parseYear(dateStrings.date, additionalDigits); + var year = parseYearResult.year; + var restDateString = parseYearResult.restDateString; + + var date = parseDate(restDateString, year); + + if (date) { + var timestamp = date.getTime(); + var time = 0; + var offset; + + if (dateStrings.time) { + time = parseTime(dateStrings.time); + } + + if (dateStrings.timezone) { + offset = parseTimezone(dateStrings.timezone); + } else { + // get offset accurate to hour in timezones that change offset + offset = new Date(timestamp + time).getTimezoneOffset(); + offset = new Date(timestamp + time + offset * MILLISECONDS_IN_MINUTE).getTimezoneOffset(); + } + + return new Date(timestamp + time + offset * MILLISECONDS_IN_MINUTE) + } else { + return new Date(argument) + } + } + + function splitDateString (dateString) { + var dateStrings = {}; + var array = dateString.split(patterns.dateTimeDelimeter); + var timeString; + + if (patterns.plainTime.test(array[0])) { + dateStrings.date = null; + timeString = array[0]; + } else { + dateStrings.date = array[0]; + timeString = array[1]; + } + + if (timeString) { + var token = patterns.timezone.exec(timeString); + if (token) { + dateStrings.time = timeString.replace(token[1], ''); + dateStrings.timezone = token[1]; + } else { + dateStrings.time = timeString; + } + } + + return dateStrings + } + + function parseYear (dateString, additionalDigits) { + var patternYYY = patterns.YYY[additionalDigits]; + var patternYYYYY = patterns.YYYYY[additionalDigits]; + + var token; + + // YYYY or ±YYYYY + token = patterns.YYYY.exec(dateString) || patternYYYYY.exec(dateString); + if (token) { + var yearString = token[1]; + return { + year: parseInt(yearString, 10), + restDateString: dateString.slice(yearString.length) + } + } + + // YY or ±YYY + token = patterns.YY.exec(dateString) || patternYYY.exec(dateString); + if (token) { + var centuryString = token[1]; + return { + year: parseInt(centuryString, 10) * 100, + restDateString: dateString.slice(centuryString.length) + } + } + + // Invalid ISO-formatted year + return { + year: null + } + } + + function parseDate (dateString, year) { + // Invalid ISO-formatted year + if (year === null) { + return null + } + + var token; + var date; + var month; + var week; + + // YYYY + if (dateString.length === 0) { + date = new Date(0); + date.setUTCFullYear(year); + return date + } + + // YYYY-MM + token = patterns.MM.exec(dateString); + if (token) { + date = new Date(0); + month = parseInt(token[1], 10) - 1; + date.setUTCFullYear(year, month); + return date + } + + // YYYY-DDD or YYYYDDD + token = patterns.DDD.exec(dateString); + if (token) { + date = new Date(0); + var dayOfYear = parseInt(token[1], 10); + date.setUTCFullYear(year, 0, dayOfYear); + return date + } + + // YYYY-MM-DD or YYYYMMDD + token = patterns.MMDD.exec(dateString); + if (token) { + date = new Date(0); + month = parseInt(token[1], 10) - 1; + var day = parseInt(token[2], 10); + date.setUTCFullYear(year, month, day); + return date + } + + // YYYY-Www or YYYYWww + token = patterns.Www.exec(dateString); + if (token) { + week = parseInt(token[1], 10) - 1; + return dayOfISOYear(year, week) + } + + // YYYY-Www-D or YYYYWwwD + token = patterns.WwwD.exec(dateString); + if (token) { + week = parseInt(token[1], 10) - 1; + var dayOfWeek = parseInt(token[2], 10) - 1; + return dayOfISOYear(year, week, dayOfWeek) + } + + // Invalid ISO-formatted date + return null + } + + function parseTime (timeString) { + var token; + var hours; + var minutes; + + // hh + token = patterns.HH.exec(timeString); + if (token) { + hours = parseFloat(token[1].replace(',', '.')); + return (hours % 24) * MILLISECONDS_IN_HOUR + } + + // hh:mm or hhmm + token = patterns.HHMM.exec(timeString); + if (token) { + hours = parseInt(token[1], 10); + minutes = parseFloat(token[2].replace(',', '.')); + return (hours % 24) * MILLISECONDS_IN_HOUR + + minutes * MILLISECONDS_IN_MINUTE + } + + // hh:mm:ss or hhmmss + token = patterns.HHMMSS.exec(timeString); + if (token) { + hours = parseInt(token[1], 10); + minutes = parseInt(token[2], 10); + var seconds = parseFloat(token[3].replace(',', '.')); + return (hours % 24) * MILLISECONDS_IN_HOUR + + minutes * MILLISECONDS_IN_MINUTE + + seconds * 1000 + } + + // Invalid ISO-formatted time + return null + } + + function parseTimezone (timezoneString) { + var token; + var absoluteOffset; + + // Z + token = patterns.timezoneZ.exec(timezoneString); + if (token) { + return 0 + } + + // ±hh + token = patterns.timezoneHH.exec(timezoneString); + if (token) { + absoluteOffset = parseInt(token[2], 10) * 60; + return (token[1] === '+') ? -absoluteOffset : absoluteOffset + } + + // ±hh:mm or ±hhmm + token = patterns.timezoneHHMM.exec(timezoneString); + if (token) { + absoluteOffset = parseInt(token[2], 10) * 60 + parseInt(token[3], 10); + return (token[1] === '+') ? -absoluteOffset : absoluteOffset + } + + return 0 + } + + function dayOfISOYear (isoYear, week, day) { + week = week || 0; + day = day || 0; + var date = new Date(0); + date.setUTCFullYear(isoYear, 0, 4); + var fourthOfJanuaryDay = date.getUTCDay() || 7; + var diff = week * 7 + day + 1 - fourthOfJanuaryDay; + date.setUTCDate(date.getUTCDate() + diff); + return date + } + + /** + * @name addMilliseconds + * @category Millisecond Helpers + * @summary Add the specified number of milliseconds to the given date. + * + * @description + * Add the specified number of milliseconds to the given date. + * + * @param {Date|String|Number} date - the date to be changed + * @param {Number} amount - the amount of milliseconds to be added + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Date} the new date with the milliseconds added + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Add 750 milliseconds to 10 July 2014 12:45:30.000: + * var result = addMilliseconds(new Date(2014, 6, 10, 12, 45, 30, 0), 750) + * //=> Thu Jul 10 2014 12:45:30.750 + */ + function addMilliseconds (dirtyDate, dirtyAmount, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var timestamp = toDate(dirtyDate, dirtyOptions).getTime(); + var amount = Number(dirtyAmount); + return new Date(timestamp + amount) + } + + function cloneObject (dirtyObject) { + dirtyObject = dirtyObject || {}; + var object = {}; + + for (var property in dirtyObject) { + if (dirtyObject.hasOwnProperty(property)) { + object[property] = dirtyObject[property]; + } + } + + return object + } + + var MILLISECONDS_IN_MINUTE$2 = 60000; + + /** + * @name addMinutes + * @category Minute Helpers + * @summary Add the specified number of minutes to the given date. + * + * @description + * Add the specified number of minutes to the given date. + * + * @param {Date|String|Number} date - the date to be changed + * @param {Number} amount - the amount of minutes to be added + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Date} the new date with the minutes added + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Add 30 minutes to 10 July 2014 12:00:00: + * var result = addMinutes(new Date(2014, 6, 10, 12, 0), 30) + * //=> Thu Jul 10 2014 12:30:00 + */ + function addMinutes (dirtyDate, dirtyAmount, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var amount = Number(dirtyAmount); + return addMilliseconds(dirtyDate, amount * MILLISECONDS_IN_MINUTE$2, dirtyOptions) + } + + /** + * @name isValid + * @category Common Helpers + * @summary Is the given date valid? + * + * @description + * Returns false if argument is Invalid Date and true otherwise. + * Argument is converted to Date using `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * Invalid Date is a Date, whose time value is NaN. + * + * Time value of Date: http://es5.github.io/#x15.9.1.1 + * + * @param {*} date - the date to check + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Boolean} the date is valid + * @throws {TypeError} 1 argument required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // For the valid date: + * var result = isValid(new Date(2014, 1, 31)) + * //=> true + * + * @example + * // For the value, convertable into a date: + * var result = isValid('2014-02-31') + * //=> true + * + * @example + * // For the invalid date: + * var result = isValid(new Date('')) + * //=> false + */ + function isValid (dirtyDate, dirtyOptions) { + if (arguments.length < 1) { + throw new TypeError('1 argument required, but only ' + arguments.length + ' present') + } + + var date = toDate(dirtyDate, dirtyOptions); + return !isNaN(date) + } + + var formatDistanceLocale = { + lessThanXSeconds: { + one: 'less than a second', + other: 'less than {{count}} seconds' + }, + + xSeconds: { + one: '1 second', + other: '{{count}} seconds' + }, + + halfAMinute: 'half a minute', + + lessThanXMinutes: { + one: 'less than a minute', + other: 'less than {{count}} minutes' + }, + + xMinutes: { + one: '1 minute', + other: '{{count}} minutes' + }, + + aboutXHours: { + one: 'about 1 hour', + other: 'about {{count}} hours' + }, + + xHours: { + one: '1 hour', + other: '{{count}} hours' + }, + + xDays: { + one: '1 day', + other: '{{count}} days' + }, + + aboutXMonths: { + one: 'about 1 month', + other: 'about {{count}} months' + }, + + xMonths: { + one: '1 month', + other: '{{count}} months' + }, + + aboutXYears: { + one: 'about 1 year', + other: 'about {{count}} years' + }, + + xYears: { + one: '1 year', + other: '{{count}} years' + }, + + overXYears: { + one: 'over 1 year', + other: 'over {{count}} years' + }, + + almostXYears: { + one: 'almost 1 year', + other: 'almost {{count}} years' + } + }; + + function formatDistance (token, count, options) { + options = options || {}; + + var result; + if (typeof formatDistanceLocale[token] === 'string') { + result = formatDistanceLocale[token]; + } else if (count === 1) { + result = formatDistanceLocale[token].one; + } else { + result = formatDistanceLocale[token].other.replace('{{count}}', count); + } + + if (options.addSuffix) { + if (options.comparison > 0) { + return 'in ' + result + } else { + return result + ' ago' + } + } + + return result + } + + var tokensToBeShortedPattern = /MMMM|MM|DD|dddd/g; + + function buildShortLongFormat (format) { + return format.replace(tokensToBeShortedPattern, function (token) { + return token.slice(1) + }) + } + + /** + * @name buildFormatLongFn + * @category Locale Helpers + * @summary Build `formatLong` property for locale used by `format`, `formatRelative` and `parse` functions. + * + * @description + * Build `formatLong` property for locale used by `format`, `formatRelative` and `parse` functions. + * Returns a function which takes one of the following tokens as the argument: + * `'LTS'`, `'LT'`, `'L'`, `'LL'`, `'LLL'`, `'l'`, `'ll'`, `'lll'`, `'llll'` + * and returns a long format string written as `format` token strings. + * See [format]{@link https://date-fns.org/docs/format} + * + * `'l'`, `'ll'`, `'lll'` and `'llll'` formats are built automatically + * by shortening some of the tokens from corresponding unshortened formats + * (e.g., if `LL` is `'MMMM DD YYYY'` then `ll` will be `MMM D YYYY`) + * + * @param {Object} obj - the object with long formats written as `format` token strings + * @param {String} obj.LT - time format: hours and minutes + * @param {String} obj.LTS - time format: hours, minutes and seconds + * @param {String} obj.L - short date format: numeric day, month and year + * @param {String} [obj.l] - short date format: numeric day, month and year (shortened) + * @param {String} obj.LL - long date format: day, month in words, and year + * @param {String} [obj.ll] - long date format: day, month in words, and year (shortened) + * @param {String} obj.LLL - long date and time format + * @param {String} [obj.lll] - long date and time format (shortened) + * @param {String} obj.LLLL - long date, time and weekday format + * @param {String} [obj.llll] - long date, time and weekday format (shortened) + * @returns {Function} `formatLong` property of the locale + * + * @example + * // For `en-US` locale: + * locale.formatLong = buildFormatLongFn({ + * LT: 'h:mm aa', + * LTS: 'h:mm:ss aa', + * L: 'MM/DD/YYYY', + * LL: 'MMMM D YYYY', + * LLL: 'MMMM D YYYY h:mm aa', + * LLLL: 'dddd, MMMM D YYYY h:mm aa' + * }) + */ + function buildFormatLongFn (obj) { + var formatLongLocale = { + LTS: obj.LTS, + LT: obj.LT, + L: obj.L, + LL: obj.LL, + LLL: obj.LLL, + LLLL: obj.LLLL, + l: obj.l || buildShortLongFormat(obj.L), + ll: obj.ll || buildShortLongFormat(obj.LL), + lll: obj.lll || buildShortLongFormat(obj.LLL), + llll: obj.llll || buildShortLongFormat(obj.LLLL) + }; + + return function (token) { + return formatLongLocale[token] + } + } + + var formatLong = buildFormatLongFn({ + LT: 'h:mm aa', + LTS: 'h:mm:ss aa', + L: 'MM/DD/YYYY', + LL: 'MMMM D YYYY', + LLL: 'MMMM D YYYY h:mm aa', + LLLL: 'dddd, MMMM D YYYY h:mm aa' + }); + + var formatRelativeLocale = { + lastWeek: '[last] dddd [at] LT', + yesterday: '[yesterday at] LT', + today: '[today at] LT', + tomorrow: '[tomorrow at] LT', + nextWeek: 'dddd [at] LT', + other: 'L' + }; + + function formatRelative (token, date, baseDate, options) { + return formatRelativeLocale[token] + } + + /** + * @name buildLocalizeFn + * @category Locale Helpers + * @summary Build `localize.weekday`, `localize.month` and `localize.timeOfDay` properties for the locale. + * + * @description + * Build `localize.weekday`, `localize.month` and `localize.timeOfDay` properties for the locale + * used by `format` function. + * If no `type` is supplied to the options of the resulting function, `defaultType` will be used (see example). + * + * `localize.weekday` function takes the weekday index as argument (0 - Sunday). + * `localize.month` takes the month index (0 - January). + * `localize.timeOfDay` takes the hours. Use `indexCallback` to convert them to an array index (see example). + * + * @param {Object} values - the object with arrays of values + * @param {String} defaultType - the default type for the localize function + * @param {Function} [indexCallback] - the callback which takes the resulting function argument + * and converts it into value array index + * @returns {Function} the resulting function + * + * @example + * var timeOfDayValues = { + * uppercase: ['AM', 'PM'], + * lowercase: ['am', 'pm'], + * long: ['a.m.', 'p.m.'] + * } + * locale.localize.timeOfDay = buildLocalizeFn(timeOfDayValues, 'long', function (hours) { + * // 0 is a.m. array index, 1 is p.m. array index + * return (hours / 12) >= 1 ? 1 : 0 + * }) + * locale.localize.timeOfDay(16, {type: 'uppercase'}) //=> 'PM' + * locale.localize.timeOfDay(5) //=> 'a.m.' + */ + function buildLocalizeFn (values, defaultType, indexCallback) { + return function (dirtyIndex, dirtyOptions) { + var options = dirtyOptions || {}; + var type = options.type ? String(options.type) : defaultType; + var valuesArray = values[type] || values[defaultType]; + var index = indexCallback ? indexCallback(Number(dirtyIndex)) : Number(dirtyIndex); + return valuesArray[index] + } + } + + /** + * @name buildLocalizeArrayFn + * @category Locale Helpers + * @summary Build `localize.weekdays`, `localize.months` and `localize.timesOfDay` properties for the locale. + * + * @description + * Build `localize.weekdays`, `localize.months` and `localize.timesOfDay` properties for the locale. + * If no `type` is supplied to the options of the resulting function, `defaultType` will be used (see example). + * + * @param {Object} values - the object with arrays of values + * @param {String} defaultType - the default type for the localize function + * @returns {Function} the resulting function + * + * @example + * var weekdayValues = { + * narrow: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'], + * short: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + * long: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] + * } + * locale.localize.weekdays = buildLocalizeArrayFn(weekdayValues, 'long') + * locale.localize.weekdays({type: 'narrow'}) //=> ['Su', 'Mo', ...] + * locale.localize.weekdays() //=> ['Sunday', 'Monday', ...] + */ + function buildLocalizeArrayFn (values, defaultType) { + return function (dirtyOptions) { + var options = dirtyOptions || {}; + var type = options.type ? String(options.type) : defaultType; + return values[type] || values[defaultType] + } + } + + // Note: in English, the names of days of the week and months are capitalized. + // If you are making a new locale based on this one, check if the same is true for the language you're working on. + // Generally, formatted dates should look like they are in the middle of a sentence, + // e.g. in Spanish language the weekdays and months should be in the lowercase. + var weekdayValues = { + narrow: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'], + short: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + long: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] + }; + + var monthValues = { + short: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + long: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] + }; + + // `timeOfDay` is used to designate which part of the day it is, when used with 12-hour clock. + // Use the system which is used the most commonly in the locale. + // For example, if the country doesn't use a.m./p.m., you can use `night`/`morning`/`afternoon`/`evening`: + // + // var timeOfDayValues = { + // any: ['in the night', 'in the morning', 'in the afternoon', 'in the evening'] + // } + // + // And later: + // + // var localize = { + // // The callback takes the hours as the argument and returns the array index + // timeOfDay: buildLocalizeFn(timeOfDayValues, 'any', function (hours) { + // if (hours >= 17) { + // return 3 + // } else if (hours >= 12) { + // return 2 + // } else if (hours >= 4) { + // return 1 + // } else { + // return 0 + // } + // }), + // timesOfDay: buildLocalizeArrayFn(timeOfDayValues, 'any') + // } + var timeOfDayValues = { + uppercase: ['AM', 'PM'], + lowercase: ['am', 'pm'], + long: ['a.m.', 'p.m.'] + }; + + function ordinalNumber (dirtyNumber, dirtyOptions) { + var number = Number(dirtyNumber); + + // If ordinal numbers depend on context, for example, + // if they are different for different grammatical genders, + // use `options.unit`: + // + // var options = dirtyOptions || {} + // var unit = String(options.unit) + // + // where `unit` can be 'month', 'quarter', 'week', 'isoWeek', 'dayOfYear', + // 'dayOfMonth' or 'dayOfWeek' + + var rem100 = number % 100; + if (rem100 > 20 || rem100 < 10) { + switch (rem100 % 10) { + case 1: + return number + 'st' + case 2: + return number + 'nd' + case 3: + return number + 'rd' + } + } + return number + 'th' + } + + var localize = { + ordinalNumber: ordinalNumber, + weekday: buildLocalizeFn(weekdayValues, 'long'), + weekdays: buildLocalizeArrayFn(weekdayValues, 'long'), + month: buildLocalizeFn(monthValues, 'long'), + months: buildLocalizeArrayFn(monthValues, 'long'), + timeOfDay: buildLocalizeFn(timeOfDayValues, 'long', function (hours) { + return (hours / 12) >= 1 ? 1 : 0 + }), + timesOfDay: buildLocalizeArrayFn(timeOfDayValues, 'long') + }; + + /** + * @name buildMatchFn + * @category Locale Helpers + * @summary Build `match.weekdays`, `match.months` and `match.timesOfDay` properties for the locale. + * + * @description + * Build `match.weekdays`, `match.months` and `match.timesOfDay` properties for the locale used by `parse` function. + * If no `type` is supplied to the options of the resulting function, `defaultType` will be used (see example). + * The result of the match function will be passed into corresponding parser function + * (`match.weekday`, `match.month` or `match.timeOfDay` respectively. See `buildParseFn`). + * + * @param {Object} values - the object with RegExps + * @param {String} defaultType - the default type for the match function + * @returns {Function} the resulting function + * + * @example + * var matchWeekdaysPatterns = { + * narrow: /^(su|mo|tu|we|th|fr|sa)/i, + * short: /^(sun|mon|tue|wed|thu|fri|sat)/i, + * long: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i + * } + * locale.match.weekdays = buildMatchFn(matchWeekdaysPatterns, 'long') + * locale.match.weekdays('Sunday', {type: 'narrow'}) //=> ['Su', 'Su', ...] + * locale.match.weekdays('Sunday') //=> ['Sunday', 'Sunday', ...] + */ + function buildMatchFn (patterns, defaultType) { + return function (dirtyString, dirtyOptions) { + var options = dirtyOptions || {}; + var type = options.type ? String(options.type) : defaultType; + var pattern = patterns[type] || patterns[defaultType]; + var string = String(dirtyString); + return string.match(pattern) + } + } + + /** + * @name buildParseFn + * @category Locale Helpers + * @summary Build `match.weekday`, `match.month` and `match.timeOfDay` properties for the locale. + * + * @description + * Build `match.weekday`, `match.month` and `match.timeOfDay` properties for the locale used by `parse` function. + * The argument of the resulting function is the result of the corresponding match function + * (`match.weekdays`, `match.months` or `match.timesOfDay` respectively. See `buildMatchFn`). + * + * @param {Object} values - the object with arrays of RegExps + * @param {String} defaultType - the default type for the parser function + * @returns {Function} the resulting function + * + * @example + * var parseWeekdayPatterns = { + * any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i] + * } + * locale.match.weekday = buildParseFn(matchWeekdaysPatterns, 'long') + * var matchResult = locale.match.weekdays('Friday') + * locale.match.weekday(matchResult) //=> 5 + */ + function buildParseFn (patterns, defaultType) { + return function (matchResult, dirtyOptions) { + var options = dirtyOptions || {}; + var type = options.type ? String(options.type) : defaultType; + var patternsArray = patterns[type] || patterns[defaultType]; + var string = matchResult[1]; + + return patternsArray.findIndex(function (pattern) { + return pattern.test(string) + }) + } + } + + /** + * @name buildMatchPatternFn + * @category Locale Helpers + * @summary Build match function from a single RegExp. + * + * @description + * Build match function from a single RegExp. + * Usually used for building `match.ordinalNumbers` property of the locale. + * + * @param {Object} pattern - the RegExp + * @returns {Function} the resulting function + * + * @example + * locale.match.ordinalNumbers = buildMatchPatternFn(/^(\d+)(th|st|nd|rd)?/i) + * locale.match.ordinalNumbers('3rd') //=> ['3rd', '3', 'rd', ...] + */ + function buildMatchPatternFn (pattern) { + return function (dirtyString) { + var string = String(dirtyString); + return string.match(pattern) + } + } + + /** + * @name parseDecimal + * @category Locale Helpers + * @summary Parses the match result into decimal number. + * + * @description + * Parses the match result into decimal number. + * Uses the string matched with the first set of parentheses of match RegExp. + * + * @param {Array} matchResult - the object returned by matching function + * @returns {Number} the parsed value + * + * @example + * locale.match = { + * ordinalNumbers: (dirtyString) { + * return String(dirtyString).match(/^(\d+)(th|st|nd|rd)?/i) + * }, + * ordinalNumber: parseDecimal + * } + */ + function parseDecimal (matchResult) { + return parseInt(matchResult[1], 10) + } + + var matchOrdinalNumbersPattern = /^(\d+)(th|st|nd|rd)?/i; + + var matchWeekdaysPatterns = { + narrow: /^(su|mo|tu|we|th|fr|sa)/i, + short: /^(sun|mon|tue|wed|thu|fri|sat)/i, + long: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i + }; + + var parseWeekdayPatterns = { + any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i] + }; + + var matchMonthsPatterns = { + short: /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i, + long: /^(january|february|march|april|may|june|july|august|september|october|november|december)/i + }; + + var parseMonthPatterns = { + any: [/^ja/i, /^f/i, /^mar/i, /^ap/i, /^may/i, /^jun/i, /^jul/i, /^au/i, /^s/i, /^o/i, /^n/i, /^d/i] + }; + + // `timeOfDay` is used to designate which part of the day it is, when used with 12-hour clock. + // Use the system which is used the most commonly in the locale. + // For example, if the country doesn't use a.m./p.m., you can use `night`/`morning`/`afternoon`/`evening`: + // + // var matchTimesOfDayPatterns = { + // long: /^((in the)? (night|morning|afternoon|evening?))/i + // } + // + // var parseTimeOfDayPatterns = { + // any: [/(night|morning)/i, /(afternoon|evening)/i] + // } + var matchTimesOfDayPatterns = { + short: /^(am|pm)/i, + long: /^([ap]\.?\s?m\.?)/i + }; + + var parseTimeOfDayPatterns = { + any: [/^a/i, /^p/i] + }; + + var match = { + ordinalNumbers: buildMatchPatternFn(matchOrdinalNumbersPattern), + ordinalNumber: parseDecimal, + weekdays: buildMatchFn(matchWeekdaysPatterns, 'long'), + weekday: buildParseFn(parseWeekdayPatterns, 'any'), + months: buildMatchFn(matchMonthsPatterns, 'long'), + month: buildParseFn(parseMonthPatterns, 'any'), + timesOfDay: buildMatchFn(matchTimesOfDayPatterns, 'long'), + timeOfDay: buildParseFn(parseTimeOfDayPatterns, 'any') + }; + + /** + * @type {Locale} + * @category Locales + * @summary English locale (United States). + * @language English + * @iso-639-2 eng + */ + var locale = { + formatDistance: formatDistance, + formatLong: formatLong, + formatRelative: formatRelative, + localize: localize, + match: match, + options: { + weekStartsOn: 0 /* Sunday */, + firstWeekContainsDate: 1 + } + }; + + var MILLISECONDS_IN_DAY$1 = 86400000; + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function getUTCDayOfYear (dirtyDate, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var timestamp = date.getTime(); + date.setUTCMonth(0, 1); + date.setUTCHours(0, 0, 0, 0); + var startOfYearTimestamp = date.getTime(); + var difference = timestamp - startOfYearTimestamp; + return Math.floor(difference / MILLISECONDS_IN_DAY$1) + 1 + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function startOfUTCISOWeek (dirtyDate, dirtyOptions) { + var weekStartsOn = 1; + + var date = toDate(dirtyDate, dirtyOptions); + var day = date.getUTCDay(); + var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn; + + date.setUTCDate(date.getUTCDate() - diff); + date.setUTCHours(0, 0, 0, 0); + return date + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function getUTCISOWeekYear (dirtyDate, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var year = date.getUTCFullYear(); + + var fourthOfJanuaryOfNextYear = new Date(0); + fourthOfJanuaryOfNextYear.setUTCFullYear(year + 1, 0, 4); + fourthOfJanuaryOfNextYear.setUTCHours(0, 0, 0, 0); + var startOfNextYear = startOfUTCISOWeek(fourthOfJanuaryOfNextYear, dirtyOptions); + + var fourthOfJanuaryOfThisYear = new Date(0); + fourthOfJanuaryOfThisYear.setUTCFullYear(year, 0, 4); + fourthOfJanuaryOfThisYear.setUTCHours(0, 0, 0, 0); + var startOfThisYear = startOfUTCISOWeek(fourthOfJanuaryOfThisYear, dirtyOptions); + + if (date.getTime() >= startOfNextYear.getTime()) { + return year + 1 + } else if (date.getTime() >= startOfThisYear.getTime()) { + return year + } else { + return year - 1 + } + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function startOfUTCISOWeekYear (dirtyDate, dirtyOptions) { + var year = getUTCISOWeekYear(dirtyDate, dirtyOptions); + var fourthOfJanuary = new Date(0); + fourthOfJanuary.setUTCFullYear(year, 0, 4); + fourthOfJanuary.setUTCHours(0, 0, 0, 0); + var date = startOfUTCISOWeek(fourthOfJanuary, dirtyOptions); + return date + } + + var MILLISECONDS_IN_WEEK$2 = 604800000; + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function getUTCISOWeek (dirtyDate, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var diff = startOfUTCISOWeek(date, dirtyOptions).getTime() - startOfUTCISOWeekYear(date, dirtyOptions).getTime(); + + // Round the number of days to the nearest integer + // because the number of milliseconds in a week is not constant + // (e.g. it's different in the week of the daylight saving time clock shift) + return Math.round(diff / MILLISECONDS_IN_WEEK$2) + 1 + } + + var formatters = { + // Month: 1, 2, ..., 12 + 'M': function (date) { + return date.getUTCMonth() + 1 + }, + + // Month: 1st, 2nd, ..., 12th + 'Mo': function (date, options) { + var month = date.getUTCMonth() + 1; + return options.locale.localize.ordinalNumber(month, {unit: 'month'}) + }, + + // Month: 01, 02, ..., 12 + 'MM': function (date) { + return addLeadingZeros(date.getUTCMonth() + 1, 2) + }, + + // Month: Jan, Feb, ..., Dec + 'MMM': function (date, options) { + return options.locale.localize.month(date.getUTCMonth(), {type: 'short'}) + }, + + // Month: January, February, ..., December + 'MMMM': function (date, options) { + return options.locale.localize.month(date.getUTCMonth(), {type: 'long'}) + }, + + // Quarter: 1, 2, 3, 4 + 'Q': function (date) { + return Math.ceil((date.getUTCMonth() + 1) / 3) + }, + + // Quarter: 1st, 2nd, 3rd, 4th + 'Qo': function (date, options) { + var quarter = Math.ceil((date.getUTCMonth() + 1) / 3); + return options.locale.localize.ordinalNumber(quarter, {unit: 'quarter'}) + }, + + // Day of month: 1, 2, ..., 31 + 'D': function (date) { + return date.getUTCDate() + }, + + // Day of month: 1st, 2nd, ..., 31st + 'Do': function (date, options) { + return options.locale.localize.ordinalNumber(date.getUTCDate(), {unit: 'dayOfMonth'}) + }, + + // Day of month: 01, 02, ..., 31 + 'DD': function (date) { + return addLeadingZeros(date.getUTCDate(), 2) + }, + + // Day of year: 1, 2, ..., 366 + 'DDD': function (date) { + return getUTCDayOfYear(date) + }, + + // Day of year: 1st, 2nd, ..., 366th + 'DDDo': function (date, options) { + return options.locale.localize.ordinalNumber(getUTCDayOfYear(date), {unit: 'dayOfYear'}) + }, + + // Day of year: 001, 002, ..., 366 + 'DDDD': function (date) { + return addLeadingZeros(getUTCDayOfYear(date), 3) + }, + + // Day of week: Su, Mo, ..., Sa + 'dd': function (date, options) { + return options.locale.localize.weekday(date.getUTCDay(), {type: 'narrow'}) + }, + + // Day of week: Sun, Mon, ..., Sat + 'ddd': function (date, options) { + return options.locale.localize.weekday(date.getUTCDay(), {type: 'short'}) + }, + + // Day of week: Sunday, Monday, ..., Saturday + 'dddd': function (date, options) { + return options.locale.localize.weekday(date.getUTCDay(), {type: 'long'}) + }, + + // Day of week: 0, 1, ..., 6 + 'd': function (date) { + return date.getUTCDay() + }, + + // Day of week: 0th, 1st, 2nd, ..., 6th + 'do': function (date, options) { + return options.locale.localize.ordinalNumber(date.getUTCDay(), {unit: 'dayOfWeek'}) + }, + + // Day of ISO week: 1, 2, ..., 7 + 'E': function (date) { + return date.getUTCDay() || 7 + }, + + // ISO week: 1, 2, ..., 53 + 'W': function (date) { + return getUTCISOWeek(date) + }, + + // ISO week: 1st, 2nd, ..., 53th + 'Wo': function (date, options) { + return options.locale.localize.ordinalNumber(getUTCISOWeek(date), {unit: 'isoWeek'}) + }, + + // ISO week: 01, 02, ..., 53 + 'WW': function (date) { + return addLeadingZeros(getUTCISOWeek(date), 2) + }, + + // Year: 00, 01, ..., 99 + 'YY': function (date) { + return addLeadingZeros(date.getUTCFullYear(), 4).substr(2) + }, + + // Year: 1900, 1901, ..., 2099 + 'YYYY': function (date) { + return addLeadingZeros(date.getUTCFullYear(), 4) + }, + + // ISO week-numbering year: 00, 01, ..., 99 + 'GG': function (date) { + return String(getUTCISOWeekYear(date)).substr(2) + }, + + // ISO week-numbering year: 1900, 1901, ..., 2099 + 'GGGG': function (date) { + return getUTCISOWeekYear(date) + }, + + // Hour: 0, 1, ... 23 + 'H': function (date) { + return date.getUTCHours() + }, + + // Hour: 00, 01, ..., 23 + 'HH': function (date) { + return addLeadingZeros(date.getUTCHours(), 2) + }, + + // Hour: 1, 2, ..., 12 + 'h': function (date) { + var hours = date.getUTCHours(); + if (hours === 0) { + return 12 + } else if (hours > 12) { + return hours % 12 + } else { + return hours + } + }, + + // Hour: 01, 02, ..., 12 + 'hh': function (date) { + return addLeadingZeros(formatters['h'](date), 2) + }, + + // Minute: 0, 1, ..., 59 + 'm': function (date) { + return date.getUTCMinutes() + }, + + // Minute: 00, 01, ..., 59 + 'mm': function (date) { + return addLeadingZeros(date.getUTCMinutes(), 2) + }, + + // Second: 0, 1, ..., 59 + 's': function (date) { + return date.getUTCSeconds() + }, + + // Second: 00, 01, ..., 59 + 'ss': function (date) { + return addLeadingZeros(date.getUTCSeconds(), 2) + }, + + // 1/10 of second: 0, 1, ..., 9 + 'S': function (date) { + return Math.floor(date.getUTCMilliseconds() / 100) + }, + + // 1/100 of second: 00, 01, ..., 99 + 'SS': function (date) { + return addLeadingZeros(Math.floor(date.getUTCMilliseconds() / 10), 2) + }, + + // Millisecond: 000, 001, ..., 999 + 'SSS': function (date) { + return addLeadingZeros(date.getUTCMilliseconds(), 3) + }, + + // Timezone: -01:00, +00:00, ... +12:00 + 'Z': function (date, options) { + var originalDate = options._originalDate || date; + return formatTimezone(originalDate.getTimezoneOffset(), ':') + }, + + // Timezone: -0100, +0000, ... +1200 + 'ZZ': function (date, options) { + var originalDate = options._originalDate || date; + return formatTimezone(originalDate.getTimezoneOffset()) + }, + + // Seconds timestamp: 512969520 + 'X': function (date, options) { + var originalDate = options._originalDate || date; + return Math.floor(originalDate.getTime() / 1000) + }, + + // Milliseconds timestamp: 512969520900 + 'x': function (date, options) { + var originalDate = options._originalDate || date; + return originalDate.getTime() + }, + + // AM, PM + 'A': function (date, options) { + return options.locale.localize.timeOfDay(date.getUTCHours(), {type: 'uppercase'}) + }, + + // am, pm + 'a': function (date, options) { + return options.locale.localize.timeOfDay(date.getUTCHours(), {type: 'lowercase'}) + }, + + // a.m., p.m. + 'aa': function (date, options) { + return options.locale.localize.timeOfDay(date.getUTCHours(), {type: 'long'}) + } + }; + + function formatTimezone (offset, delimeter) { + delimeter = delimeter || ''; + var sign = offset > 0 ? '-' : '+'; + var absOffset = Math.abs(offset); + var hours = Math.floor(absOffset / 60); + var minutes = absOffset % 60; + return sign + addLeadingZeros(hours, 2) + delimeter + addLeadingZeros(minutes, 2) + } + + function addLeadingZeros (number, targetLength) { + var output = Math.abs(number).toString(); + while (output.length < targetLength) { + output = '0' + output; + } + return output + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function addUTCMinutes (dirtyDate, dirtyAmount, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var amount = Number(dirtyAmount); + date.setUTCMinutes(date.getUTCMinutes() + amount); + return date + } + + var longFormattingTokensRegExp = /(\[[^[]*])|(\\)?(LTS|LT|LLLL|LLL|LL|L|llll|lll|ll|l)/g; + var defaultFormattingTokensRegExp = /(\[[^[]*])|(\\)?(x|ss|s|mm|m|hh|h|do|dddd|ddd|dd|d|aa|a|ZZ|Z|YYYY|YY|X|Wo|WW|W|SSS|SS|S|Qo|Q|Mo|MMMM|MMM|MM|M|HH|H|GGGG|GG|E|Do|DDDo|DDDD|DDD|DD|D|A|.)/g; + + /** + * @name format + * @category Common Helpers + * @summary Format the date. + * + * @description + * Return the formatted date string in the given format. + * + * Accepted tokens: + * | Unit | Token | Result examples | + * |-------------------------|-------|----------------------------------| + * | Month | M | 1, 2, ..., 12 | + * | | Mo | 1st, 2nd, ..., 12th | + * | | MM | 01, 02, ..., 12 | + * | | MMM | Jan, Feb, ..., Dec | + * | | MMMM | January, February, ..., December | + * | Quarter | Q | 1, 2, 3, 4 | + * | | Qo | 1st, 2nd, 3rd, 4th | + * | Day of month | D | 1, 2, ..., 31 | + * | | Do | 1st, 2nd, ..., 31st | + * | | DD | 01, 02, ..., 31 | + * | Day of year | DDD | 1, 2, ..., 366 | + * | | DDDo | 1st, 2nd, ..., 366th | + * | | DDDD | 001, 002, ..., 366 | + * | Day of week | d | 0, 1, ..., 6 | + * | | do | 0th, 1st, ..., 6th | + * | | dd | Su, Mo, ..., Sa | + * | | ddd | Sun, Mon, ..., Sat | + * | | dddd | Sunday, Monday, ..., Saturday | + * | Day of ISO week | E | 1, 2, ..., 7 | + * | ISO week | W | 1, 2, ..., 53 | + * | | Wo | 1st, 2nd, ..., 53rd | + * | | WW | 01, 02, ..., 53 | + * | Year | YY | 00, 01, ..., 99 | + * | | YYYY | 1900, 1901, ..., 2099 | + * | ISO week-numbering year | GG | 00, 01, ..., 99 | + * | | GGGG | 1900, 1901, ..., 2099 | + * | AM/PM | A | AM, PM | + * | | a | am, pm | + * | | aa | a.m., p.m. | + * | Hour | H | 0, 1, ... 23 | + * | | HH | 00, 01, ... 23 | + * | | h | 1, 2, ..., 12 | + * | | hh | 01, 02, ..., 12 | + * | Minute | m | 0, 1, ..., 59 | + * | | mm | 00, 01, ..., 59 | + * | Second | s | 0, 1, ..., 59 | + * | | ss | 00, 01, ..., 59 | + * | 1/10 of second | S | 0, 1, ..., 9 | + * | 1/100 of second | SS | 00, 01, ..., 99 | + * | Millisecond | SSS | 000, 001, ..., 999 | + * | Timezone | Z | -01:00, +00:00, ... +12:00 | + * | | ZZ | -0100, +0000, ..., +1200 | + * | Seconds timestamp | X | 512969520 | + * | Milliseconds timestamp | x | 512969520900 | + * | Long format | LT | 05:30 a.m. | + * | | LTS | 05:30:15 a.m. | + * | | L | 07/02/1995 | + * | | l | 7/2/1995 | + * | | LL | July 2 1995 | + * | | ll | Jul 2 1995 | + * | | LLL | July 2 1995 05:30 a.m. | + * | | lll | Jul 2 1995 05:30 a.m. | + * | | LLLL | Sunday, July 2 1995 05:30 a.m. | + * | | llll | Sun, Jul 2 1995 05:30 a.m. | + * + * The characters wrapped in square brackets are escaped. + * + * The result may vary by locale. + * + * @param {Date|String|Number} date - the original date + * @param {String} format - the string of tokens + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale} + * @returns {String} the formatted date string + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * @throws {RangeError} `options.locale` must contain `localize` property + * @throws {RangeError} `options.locale` must contain `formatLong` property + * + * @example + * // Represent 11 February 2014 in middle-endian format: + * var result = format( + * new Date(2014, 1, 11), + * 'MM/DD/YYYY' + * ) + * //=> '02/11/2014' + * + * @example + * // Represent 2 July 2014 in Esperanto: + * import { eoLocale } from 'date-fns/locale/eo' + * var result = format( + * new Date(2014, 6, 2), + * 'Do [de] MMMM YYYY', + * {locale: eoLocale} + * ) + * //=> '2-a de julio 2014' + */ + function format (dirtyDate, dirtyFormatStr, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var formatStr = String(dirtyFormatStr); + var options = dirtyOptions || {}; + + var locale$$1 = options.locale || locale; + + if (!locale$$1.localize) { + throw new RangeError('locale must contain localize property') + } + + if (!locale$$1.formatLong) { + throw new RangeError('locale must contain formatLong property') + } + + var localeFormatters = locale$$1.formatters || {}; + var formattingTokensRegExp = locale$$1.formattingTokensRegExp || defaultFormattingTokensRegExp; + var formatLong = locale$$1.formatLong; + + var originalDate = toDate(dirtyDate, options); + + if (!isValid(originalDate, options)) { + return 'Invalid Date' + } + + // Convert the date in system timezone to the same date in UTC+00:00 timezone. + // This ensures that when UTC functions will be implemented, locales will be compatible with them. + // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/376 + var timezoneOffset = originalDate.getTimezoneOffset(); + var utcDate = addUTCMinutes(originalDate, -timezoneOffset, options); + + var formatterOptions = cloneObject(options); + formatterOptions.locale = locale$$1; + formatterOptions.formatters = formatters; + + // When UTC functions will be implemented, options._originalDate will likely be a part of public API. + // Right now, please don't use it in locales. If you have to use an original date, + // please restore it from `date`, adding a timezone offset to it. + formatterOptions._originalDate = originalDate; + + var result = formatStr + .replace(longFormattingTokensRegExp, function (substring) { + if (substring[0] === '[') { + return substring + } + + if (substring[0] === '\\') { + return cleanEscapedString(substring) + } + + return formatLong(substring) + }) + .replace(formattingTokensRegExp, function (substring) { + var formatter = localeFormatters[substring] || formatters[substring]; + + if (formatter) { + return formatter(utcDate, formatterOptions) + } else { + return cleanEscapedString(substring) + } + }); + + return result + } + + function cleanEscapedString (input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|]$/g, '') + } + return input.replace(/\\/g, '') + } + + /** + * @name subMinutes + * @category Minute Helpers + * @summary Subtract the specified number of minutes from the given date. + * + * @description + * Subtract the specified number of minutes from the given date. + * + * @param {Date|String|Number} date - the date to be changed + * @param {Number} amount - the amount of minutes to be subtracted + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Date} the new date with the mintues subtracted + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Subtract 30 minutes from 10 July 2014 12:00:00: + * var result = subMinutes(new Date(2014, 6, 10, 12, 0), 30) + * //=> Thu Jul 10 2014 11:30:00 + */ + function subMinutes (dirtyDate, dirtyAmount, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var amount = Number(dirtyAmount); + return addMinutes(dirtyDate, -amount, dirtyOptions) + } + + /** + * @name isAfter + * @category Common Helpers + * @summary Is the first date after the second one? + * + * @description + * Is the first date after the second one? + * + * @param {Date|String|Number} date - the date that should be after the other one to return true + * @param {Date|String|Number} dateToCompare - the date to compare with + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Boolean} the first date is after the second date + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Is 10 July 1989 after 11 February 1987? + * var result = isAfter(new Date(1989, 6, 10), new Date(1987, 1, 11)) + * //=> true + */ + function isAfter (dirtyDate, dirtyDateToCompare, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var date = toDate(dirtyDate, dirtyOptions); + var dateToCompare = toDate(dirtyDateToCompare, dirtyOptions); + return date.getTime() > dateToCompare.getTime() + } + + /** + * @name isBefore + * @category Common Helpers + * @summary Is the first date before the second one? + * + * @description + * Is the first date before the second one? + * + * @param {Date|String|Number} date - the date that should be before the other one to return true + * @param {Date|String|Number} dateToCompare - the date to compare with + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Boolean} the first date is before the second date + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Is 10 July 1989 before 11 February 1987? + * var result = isBefore(new Date(1989, 6, 10), new Date(1987, 1, 11)) + * //=> false + */ + function isBefore (dirtyDate, dirtyDateToCompare, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var date = toDate(dirtyDate, dirtyOptions); + var dateToCompare = toDate(dirtyDateToCompare, dirtyOptions); + return date.getTime() < dateToCompare.getTime() + } + + /** + * @name isEqual + * @category Common Helpers + * @summary Are the given dates equal? + * + * @description + * Are the given dates equal? + * + * @param {Date|String|Number} dateLeft - the first date to compare + * @param {Date|String|Number} dateRight - the second date to compare + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Boolean} the dates are equal + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Are 2 July 2014 06:30:45.000 and 2 July 2014 06:30:45.500 equal? + * var result = isEqual( + * new Date(2014, 6, 2, 6, 30, 45, 0) + * new Date(2014, 6, 2, 6, 30, 45, 500) + * ) + * //=> false + */ + function isEqual (dirtyLeftDate, dirtyRightDate, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var dateLeft = toDate(dirtyLeftDate, dirtyOptions); + var dateRight = toDate(dirtyRightDate, dirtyOptions); + return dateLeft.getTime() === dateRight.getTime() + } + + var patterns$1 = { + 'M': /^(1[0-2]|0?\d)/, // 0 to 12 + 'D': /^(3[0-1]|[0-2]?\d)/, // 0 to 31 + 'DDD': /^(36[0-6]|3[0-5]\d|[0-2]?\d?\d)/, // 0 to 366 + 'W': /^(5[0-3]|[0-4]?\d)/, // 0 to 53 + 'YYYY': /^(\d{1,4})/, // 0 to 9999 + 'H': /^(2[0-3]|[0-1]?\d)/, // 0 to 23 + 'm': /^([0-5]?\d)/, // 0 to 59 + 'Z': /^([+-])(\d{2}):(\d{2})/, + 'ZZ': /^([+-])(\d{2})(\d{2})/, + singleDigit: /^(\d)/, + twoDigits: /^(\d{2})/, + threeDigits: /^(\d{3})/, + fourDigits: /^(\d{4})/, + anyDigits: /^(\d+)/ + }; + + function parseDecimal$1 (matchResult) { + return parseInt(matchResult[1], 10) + } + + var parsers = { + // Year: 00, 01, ..., 99 + 'YY': { + unit: 'twoDigitYear', + match: patterns$1.twoDigits, + parse: function (matchResult) { + return parseDecimal$1(matchResult) + } + }, + + // Year: 1900, 1901, ..., 2099 + 'YYYY': { + unit: 'year', + match: patterns$1.YYYY, + parse: parseDecimal$1 + }, + + // ISO week-numbering year: 00, 01, ..., 99 + 'GG': { + unit: 'isoYear', + match: patterns$1.twoDigits, + parse: function (matchResult) { + return parseDecimal$1(matchResult) + 1900 + } + }, + + // ISO week-numbering year: 1900, 1901, ..., 2099 + 'GGGG': { + unit: 'isoYear', + match: patterns$1.YYYY, + parse: parseDecimal$1 + }, + + // Quarter: 1, 2, 3, 4 + 'Q': { + unit: 'quarter', + match: patterns$1.singleDigit, + parse: parseDecimal$1 + }, + + // Ordinal quarter + 'Qo': { + unit: 'quarter', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'quarter'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'quarter'}) + } + }, + + // Month: 1, 2, ..., 12 + 'M': { + unit: 'month', + match: patterns$1.M, + parse: function (matchResult) { + return parseDecimal$1(matchResult) - 1 + } + }, + + // Ordinal month + 'Mo': { + unit: 'month', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'month'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'month'}) - 1 + } + }, + + // Month: 01, 02, ..., 12 + 'MM': { + unit: 'month', + match: patterns$1.twoDigits, + parse: function (matchResult) { + return parseDecimal$1(matchResult) - 1 + } + }, + + // Month: Jan, Feb, ..., Dec + 'MMM': { + unit: 'month', + match: function (string, options) { + return options.locale.match.months(string, {type: 'short'}) + }, + parse: function (matchResult, options) { + return options.locale.match.month(matchResult, {type: 'short'}) + } + }, + + // Month: January, February, ..., December + 'MMMM': { + unit: 'month', + match: function (string, options) { + return options.locale.match.months(string, {type: 'long'}) || + options.locale.match.months(string, {type: 'short'}) + }, + parse: function (matchResult, options) { + var parseResult = options.locale.match.month(matchResult, {type: 'long'}); + + if (parseResult == null) { + parseResult = options.locale.match.month(matchResult, {type: 'short'}); + } + + return parseResult + } + }, + + // ISO week: 1, 2, ..., 53 + 'W': { + unit: 'isoWeek', + match: patterns$1.W, + parse: parseDecimal$1 + }, + + // Ordinal ISO week + 'Wo': { + unit: 'isoWeek', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'isoWeek'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'isoWeek'}) + } + }, + + // ISO week: 01, 02, ..., 53 + 'WW': { + unit: 'isoWeek', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // Day of week: 0, 1, ..., 6 + 'd': { + unit: 'dayOfWeek', + match: patterns$1.singleDigit, + parse: parseDecimal$1 + }, + + // Ordinal day of week + 'do': { + unit: 'dayOfWeek', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'dayOfWeek'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'dayOfWeek'}) + } + }, + + // Day of week: Su, Mo, ..., Sa + 'dd': { + unit: 'dayOfWeek', + match: function (string, options) { + return options.locale.match.weekdays(string, {type: 'narrow'}) + }, + parse: function (matchResult, options) { + return options.locale.match.weekday(matchResult, {type: 'narrow'}) + } + }, + + // Day of week: Sun, Mon, ..., Sat + 'ddd': { + unit: 'dayOfWeek', + match: function (string, options) { + return options.locale.match.weekdays(string, {type: 'short'}) || + options.locale.match.weekdays(string, {type: 'narrow'}) + }, + parse: function (matchResult, options) { + var parseResult = options.locale.match.weekday(matchResult, {type: 'short'}); + + if (parseResult == null) { + parseResult = options.locale.match.weekday(matchResult, {type: 'narrow'}); + } + + return parseResult + } + }, + + // Day of week: Sunday, Monday, ..., Saturday + 'dddd': { + unit: 'dayOfWeek', + match: function (string, options) { + return options.locale.match.weekdays(string, {type: 'long'}) || + options.locale.match.weekdays(string, {type: 'short'}) || + options.locale.match.weekdays(string, {type: 'narrow'}) + }, + parse: function (matchResult, options) { + var parseResult = options.locale.match.weekday(matchResult, {type: 'long'}); + + if (parseResult == null) { + parseResult = options.locale.match.weekday(matchResult, {type: 'short'}); + + if (parseResult == null) { + parseResult = options.locale.match.weekday(matchResult, {type: 'narrow'}); + } + } + + return parseResult + } + }, + + // Day of ISO week: 1, 2, ..., 7 + 'E': { + unit: 'dayOfISOWeek', + match: patterns$1.singleDigit, + parse: function (matchResult) { + return parseDecimal$1(matchResult) + } + }, + + // Day of month: 1, 2, ..., 31 + 'D': { + unit: 'dayOfMonth', + match: patterns$1.D, + parse: parseDecimal$1 + }, + + // Ordinal day of month + 'Do': { + unit: 'dayOfMonth', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'dayOfMonth'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'dayOfMonth'}) + } + }, + + // Day of month: 01, 02, ..., 31 + 'DD': { + unit: 'dayOfMonth', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // Day of year: 1, 2, ..., 366 + 'DDD': { + unit: 'dayOfYear', + match: patterns$1.DDD, + parse: parseDecimal$1 + }, + + // Ordinal day of year + 'DDDo': { + unit: 'dayOfYear', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'dayOfYear'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'dayOfYear'}) + } + }, + + // Day of year: 001, 002, ..., 366 + 'DDDD': { + unit: 'dayOfYear', + match: patterns$1.threeDigits, + parse: parseDecimal$1 + }, + + // AM, PM + 'A': { + unit: 'timeOfDay', + match: function (string, options) { + return options.locale.match.timesOfDay(string, {type: 'short'}) + }, + parse: function (matchResult, options) { + return options.locale.match.timeOfDay(matchResult, {type: 'short'}) + } + }, + + // a.m., p.m. + 'aa': { + unit: 'timeOfDay', + match: function (string, options) { + return options.locale.match.timesOfDay(string, {type: 'long'}) || + options.locale.match.timesOfDay(string, {type: 'short'}) + }, + parse: function (matchResult, options) { + var parseResult = options.locale.match.timeOfDay(matchResult, {type: 'long'}); + + if (parseResult == null) { + parseResult = options.locale.match.timeOfDay(matchResult, {type: 'short'}); + } + + return parseResult + } + }, + + // Hour: 0, 1, ... 23 + 'H': { + unit: 'hours', + match: patterns$1.H, + parse: parseDecimal$1 + }, + + // Hour: 00, 01, ..., 23 + 'HH': { + unit: 'hours', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // Hour: 1, 2, ..., 12 + 'h': { + unit: 'timeOfDayHours', + match: patterns$1.M, + parse: parseDecimal$1 + }, + + // Hour: 01, 02, ..., 12 + 'hh': { + unit: 'timeOfDayHours', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // Minute: 0, 1, ..., 59 + 'm': { + unit: 'minutes', + match: patterns$1.m, + parse: parseDecimal$1 + }, + + // Minute: 00, 01, ..., 59 + 'mm': { + unit: 'minutes', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // Second: 0, 1, ..., 59 + 's': { + unit: 'seconds', + match: patterns$1.m, + parse: parseDecimal$1 + }, + + // Second: 00, 01, ..., 59 + 'ss': { + unit: 'seconds', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // 1/10 of second: 0, 1, ..., 9 + 'S': { + unit: 'milliseconds', + match: patterns$1.singleDigit, + parse: function (matchResult) { + return parseDecimal$1(matchResult) * 100 + } + }, + + // 1/100 of second: 00, 01, ..., 99 + 'SS': { + unit: 'milliseconds', + match: patterns$1.twoDigits, + parse: function (matchResult) { + return parseDecimal$1(matchResult) * 10 + } + }, + + // Millisecond: 000, 001, ..., 999 + 'SSS': { + unit: 'milliseconds', + match: patterns$1.threeDigits, + parse: parseDecimal$1 + }, + + // Timezone: -01:00, +00:00, ... +12:00 + 'Z': { + unit: 'timezone', + match: patterns$1.Z, + parse: function (matchResult) { + var sign = matchResult[1]; + var hours = parseInt(matchResult[2], 10); + var minutes = parseInt(matchResult[3], 10); + var absoluteOffset = hours * 60 + minutes; + return (sign === '+') ? absoluteOffset : -absoluteOffset + } + }, + + // Timezone: -0100, +0000, ... +1200 + 'ZZ': { + unit: 'timezone', + match: patterns$1.ZZ, + parse: function (matchResult) { + var sign = matchResult[1]; + var hours = parseInt(matchResult[2], 10); + var minutes = parseInt(matchResult[3], 10); + var absoluteOffset = hours * 60 + minutes; + return (sign === '+') ? absoluteOffset : -absoluteOffset + } + }, + + // Seconds timestamp: 512969520 + 'X': { + unit: 'timestamp', + match: patterns$1.anyDigits, + parse: function (matchResult) { + return parseDecimal$1(matchResult) * 1000 + } + }, + + // Milliseconds timestamp: 512969520900 + 'x': { + unit: 'timestamp', + match: patterns$1.anyDigits, + parse: parseDecimal$1 + } + }; + + parsers['a'] = parsers['A']; + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function setUTCDay (dirtyDate, dirtyDay, dirtyOptions) { + var options = dirtyOptions || {}; + var locale = options.locale; + var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn; + var defaultWeekStartsOn = localeWeekStartsOn === undefined ? 0 : Number(localeWeekStartsOn); + var weekStartsOn = options.weekStartsOn === undefined ? defaultWeekStartsOn : Number(options.weekStartsOn); + + // Test if weekStartsOn is between 0 and 6 _and_ is not NaN + if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) { + throw new RangeError('weekStartsOn must be between 0 and 6 inclusively') + } + + var date = toDate(dirtyDate, dirtyOptions); + var day = Number(dirtyDay); + + var currentDay = date.getUTCDay(); + + var remainder = day % 7; + var dayIndex = (remainder + 7) % 7; + + var diff = (dayIndex < weekStartsOn ? 7 : 0) + day - currentDay; + + date.setUTCDate(date.getUTCDate() + diff); + return date + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function setUTCISODay (dirtyDate, dirtyDay, dirtyOptions) { + var day = Number(dirtyDay); + + if (day % 7 === 0) { + day = day - 7; + } + + var weekStartsOn = 1; + var date = toDate(dirtyDate, dirtyOptions); + var currentDay = date.getUTCDay(); + + var remainder = day % 7; + var dayIndex = (remainder + 7) % 7; + + var diff = (dayIndex < weekStartsOn ? 7 : 0) + day - currentDay; + + date.setUTCDate(date.getUTCDate() + diff); + return date + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function setUTCISOWeek (dirtyDate, dirtyISOWeek, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var isoWeek = Number(dirtyISOWeek); + var diff = getUTCISOWeek(date, dirtyOptions) - isoWeek; + date.setUTCDate(date.getUTCDate() - diff * 7); + return date + } + + var MILLISECONDS_IN_DAY$3 = 86400000; + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function setUTCISOWeekYear (dirtyDate, dirtyISOYear, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var isoYear = Number(dirtyISOYear); + var dateStartOfYear = startOfUTCISOWeekYear(date, dirtyOptions); + var diff = Math.floor((date.getTime() - dateStartOfYear.getTime()) / MILLISECONDS_IN_DAY$3); + var fourthOfJanuary = new Date(0); + fourthOfJanuary.setUTCFullYear(isoYear, 0, 4); + fourthOfJanuary.setUTCHours(0, 0, 0, 0); + date = startOfUTCISOWeekYear(fourthOfJanuary, dirtyOptions); + date.setUTCDate(date.getUTCDate() + diff); + return date + } + + var MILLISECONDS_IN_MINUTE$6 = 60000; + + function setTimeOfDay (hours, timeOfDay) { + var isAM = timeOfDay === 0; + + if (isAM) { + if (hours === 12) { + return 0 + } + } else { + if (hours !== 12) { + return 12 + hours + } + } + + return hours + } + + var units = { + twoDigitYear: { + priority: 10, + set: function (dateValues, value) { + var century = Math.floor(dateValues.date.getUTCFullYear() / 100); + var year = century * 100 + value; + dateValues.date.setUTCFullYear(year, 0, 1); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + year: { + priority: 10, + set: function (dateValues, value) { + dateValues.date.setUTCFullYear(value, 0, 1); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + isoYear: { + priority: 10, + set: function (dateValues, value, options) { + dateValues.date = startOfUTCISOWeekYear(setUTCISOWeekYear(dateValues.date, value, options), options); + return dateValues + } + }, + + quarter: { + priority: 20, + set: function (dateValues, value) { + dateValues.date.setUTCMonth((value - 1) * 3, 1); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + month: { + priority: 30, + set: function (dateValues, value) { + dateValues.date.setUTCMonth(value, 1); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + isoWeek: { + priority: 40, + set: function (dateValues, value, options) { + dateValues.date = startOfUTCISOWeek(setUTCISOWeek(dateValues.date, value, options), options); + return dateValues + } + }, + + dayOfWeek: { + priority: 50, + set: function (dateValues, value, options) { + dateValues.date = setUTCDay(dateValues.date, value, options); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + dayOfISOWeek: { + priority: 50, + set: function (dateValues, value, options) { + dateValues.date = setUTCISODay(dateValues.date, value, options); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + dayOfMonth: { + priority: 50, + set: function (dateValues, value) { + dateValues.date.setUTCDate(value); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + dayOfYear: { + priority: 50, + set: function (dateValues, value) { + dateValues.date.setUTCMonth(0, value); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + timeOfDay: { + priority: 60, + set: function (dateValues, value, options) { + dateValues.timeOfDay = value; + return dateValues + } + }, + + hours: { + priority: 70, + set: function (dateValues, value, options) { + dateValues.date.setUTCHours(value, 0, 0, 0); + return dateValues + } + }, + + timeOfDayHours: { + priority: 70, + set: function (dateValues, value, options) { + var timeOfDay = dateValues.timeOfDay; + if (timeOfDay != null) { + value = setTimeOfDay(value, timeOfDay); + } + dateValues.date.setUTCHours(value, 0, 0, 0); + return dateValues + } + }, + + minutes: { + priority: 80, + set: function (dateValues, value) { + dateValues.date.setUTCMinutes(value, 0, 0); + return dateValues + } + }, + + seconds: { + priority: 90, + set: function (dateValues, value) { + dateValues.date.setUTCSeconds(value, 0); + return dateValues + } + }, + + milliseconds: { + priority: 100, + set: function (dateValues, value) { + dateValues.date.setUTCMilliseconds(value); + return dateValues + } + }, + + timezone: { + priority: 110, + set: function (dateValues, value) { + dateValues.date = new Date(dateValues.date.getTime() - value * MILLISECONDS_IN_MINUTE$6); + return dateValues + } + }, + + timestamp: { + priority: 120, + set: function (dateValues, value) { + dateValues.date = new Date(value); + return dateValues + } + } + }; + + var TIMEZONE_UNIT_PRIORITY = 110; + var MILLISECONDS_IN_MINUTE$7 = 60000; + + var longFormattingTokensRegExp$1 = /(\[[^[]*])|(\\)?(LTS|LT|LLLL|LLL|LL|L|llll|lll|ll|l)/g; + var defaultParsingTokensRegExp = /(\[[^[]*])|(\\)?(x|ss|s|mm|m|hh|h|do|dddd|ddd|dd|d|aa|a|ZZ|Z|YYYY|YY|X|Wo|WW|W|SSS|SS|S|Qo|Q|Mo|MMMM|MMM|MM|M|HH|H|GGGG|GG|E|Do|DDDo|DDDD|DDD|DD|D|A|.)/g; + + /** + * @name parse + * @category Common Helpers + * @summary Parse the date. + * + * @description + * Return the date parsed from string using the given format. + * + * Accepted format tokens: + * | Unit | Priority | Token | Input examples | + * |-------------------------|----------|-------|----------------------------------| + * | Year | 10 | YY | 00, 01, ..., 99 | + * | | | YYYY | 1900, 1901, ..., 2099 | + * | ISO week-numbering year | 10 | GG | 00, 01, ..., 99 | + * | | | GGGG | 1900, 1901, ..., 2099 | + * | Quarter | 20 | Q | 1, 2, 3, 4 | + * | | | Qo | 1st, 2nd, 3rd, 4th | + * | Month | 30 | M | 1, 2, ..., 12 | + * | | | Mo | 1st, 2nd, ..., 12th | + * | | | MM | 01, 02, ..., 12 | + * | | | MMM | Jan, Feb, ..., Dec | + * | | | MMMM | January, February, ..., December | + * | ISO week | 40 | W | 1, 2, ..., 53 | + * | | | Wo | 1st, 2nd, ..., 53rd | + * | | | WW | 01, 02, ..., 53 | + * | Day of week | 50 | d | 0, 1, ..., 6 | + * | | | do | 0th, 1st, ..., 6th | + * | | | dd | Su, Mo, ..., Sa | + * | | | ddd | Sun, Mon, ..., Sat | + * | | | dddd | Sunday, Monday, ..., Saturday | + * | Day of ISO week | 50 | E | 1, 2, ..., 7 | + * | Day of month | 50 | D | 1, 2, ..., 31 | + * | | | Do | 1st, 2nd, ..., 31st | + * | | | DD | 01, 02, ..., 31 | + * | Day of year | 50 | DDD | 1, 2, ..., 366 | + * | | | DDDo | 1st, 2nd, ..., 366th | + * | | | DDDD | 001, 002, ..., 366 | + * | Time of day | 60 | A | AM, PM | + * | | | a | am, pm | + * | | | aa | a.m., p.m. | + * | Hour | 70 | H | 0, 1, ... 23 | + * | | | HH | 00, 01, ... 23 | + * | Time of day hour | 70 | h | 1, 2, ..., 12 | + * | | | hh | 01, 02, ..., 12 | + * | Minute | 80 | m | 0, 1, ..., 59 | + * | | | mm | 00, 01, ..., 59 | + * | Second | 90 | s | 0, 1, ..., 59 | + * | | | ss | 00, 01, ..., 59 | + * | 1/10 of second | 100 | S | 0, 1, ..., 9 | + * | 1/100 of second | 100 | SS | 00, 01, ..., 99 | + * | Millisecond | 100 | SSS | 000, 001, ..., 999 | + * | Timezone | 110 | Z | -01:00, +00:00, ... +12:00 | + * | | | ZZ | -0100, +0000, ..., +1200 | + * | Seconds timestamp | 120 | X | 512969520 | + * | Milliseconds timestamp | 120 | x | 512969520900 | + * + * Values will be assigned to the date in the ascending order of its unit's priority. + * Units of an equal priority overwrite each other in the order of appearance. + * + * If no values of higher priority are parsed (e.g. when parsing string 'January 1st' without a year), + * the values will be taken from 3rd argument `baseDate` which works as a context of parsing. + * + * `baseDate` must be passed for correct work of the function. + * If you're not sure which `baseDate` to supply, create a new instance of Date: + * `parse('02/11/2014', 'MM/DD/YYYY', new Date())` + * In this case parsing will be done in the context of the current date. + * If `baseDate` is `Invalid Date` or a value not convertible to valid `Date`, + * then `Invalid Date` will be returned. + * + * Also, `parse` unfolds long formats like those in [format]{@link https://date-fns.org/docs/format}: + * | Token | Input examples | + * |-------|--------------------------------| + * | LT | 05:30 a.m. | + * | LTS | 05:30:15 a.m. | + * | L | 07/02/1995 | + * | l | 7/2/1995 | + * | LL | July 2 1995 | + * | ll | Jul 2 1995 | + * | LLL | July 2 1995 05:30 a.m. | + * | lll | Jul 2 1995 05:30 a.m. | + * | LLLL | Sunday, July 2 1995 05:30 a.m. | + * | llll | Sun, Jul 2 1995 05:30 a.m. | + * + * The characters wrapped in square brackets in the format string are escaped. + * + * The result may vary by locale. + * + * If `formatString` matches with `dateString` but does not provides tokens, `baseDate` will be returned. + * + * If parsing failed, `Invalid Date` will be returned. + * Invalid Date is a Date, whose time value is NaN. + * Time value of Date: http://es5.github.io/#x15.9.1.1 + * + * @param {String} dateString - the string to parse + * @param {String} formatString - the string of tokens + * @param {Date|String|Number} baseDate - the date to took the missing higher priority values from + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale} + * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday) + * @returns {Date} the parsed date + * @throws {TypeError} 3 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6 + * @throws {RangeError} `options.locale` must contain `match` property + * @throws {RangeError} `options.locale` must contain `formatLong` property + * + * @example + * // Parse 11 February 2014 from middle-endian format: + * var result = parse( + * '02/11/2014', + * 'MM/DD/YYYY', + * new Date() + * ) + * //=> Tue Feb 11 2014 00:00:00 + * + * @example + * // Parse 28th of February in English locale in the context of 2010 year: + * import eoLocale from 'date-fns/locale/eo' + * var result = parse( + * '28-a de februaro', + * 'Do [de] MMMM', + * new Date(2010, 0, 1) + * {locale: eoLocale} + * ) + * //=> Sun Feb 28 2010 00:00:00 + */ + function parse (dirtyDateString, dirtyFormatString, dirtyBaseDate, dirtyOptions) { + if (arguments.length < 3) { + throw new TypeError('3 arguments required, but only ' + arguments.length + ' present') + } + + var dateString = String(dirtyDateString); + var options = dirtyOptions || {}; + + var weekStartsOn = options.weekStartsOn === undefined ? 0 : Number(options.weekStartsOn); + + // Test if weekStartsOn is between 0 and 6 _and_ is not NaN + if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) { + throw new RangeError('weekStartsOn must be between 0 and 6 inclusively') + } + + var locale$$1 = options.locale || locale; + var localeParsers = locale$$1.parsers || {}; + var localeUnits = locale$$1.units || {}; + + if (!locale$$1.match) { + throw new RangeError('locale must contain match property') + } + + if (!locale$$1.formatLong) { + throw new RangeError('locale must contain formatLong property') + } + + var formatString = String(dirtyFormatString) + .replace(longFormattingTokensRegExp$1, function (substring) { + if (substring[0] === '[') { + return substring + } + + if (substring[0] === '\\') { + return cleanEscapedString$1(substring) + } + + return locale$$1.formatLong(substring) + }); + + if (formatString === '') { + if (dateString === '') { + return toDate(dirtyBaseDate, options) + } else { + return new Date(NaN) + } + } + + var subFnOptions = cloneObject(options); + subFnOptions.locale = locale$$1; + + var tokens = formatString.match(locale$$1.parsingTokensRegExp || defaultParsingTokensRegExp); + var tokensLength = tokens.length; + + // If timezone isn't specified, it will be set to the system timezone + var setters = [{ + priority: TIMEZONE_UNIT_PRIORITY, + set: dateToSystemTimezone, + index: 0 + }]; + + var i; + for (i = 0; i < tokensLength; i++) { + var token = tokens[i]; + var parser = localeParsers[token] || parsers[token]; + if (parser) { + var matchResult; + + if (parser.match instanceof RegExp) { + matchResult = parser.match.exec(dateString); + } else { + matchResult = parser.match(dateString, subFnOptions); + } + + if (!matchResult) { + return new Date(NaN) + } + + var unitName = parser.unit; + var unit = localeUnits[unitName] || units[unitName]; + + setters.push({ + priority: unit.priority, + set: unit.set, + value: parser.parse(matchResult, subFnOptions), + index: setters.length + }); + + var substring = matchResult[0]; + dateString = dateString.slice(substring.length); + } else { + var head = tokens[i].match(/^\[.*]$/) ? tokens[i].replace(/^\[|]$/g, '') : tokens[i]; + if (dateString.indexOf(head) === 0) { + dateString = dateString.slice(head.length); + } else { + return new Date(NaN) + } + } + } + + var uniquePrioritySetters = setters + .map(function (setter) { + return setter.priority + }) + .sort(function (a, b) { + return a - b + }) + .filter(function (priority, index, array) { + return array.indexOf(priority) === index + }) + .map(function (priority) { + return setters + .filter(function (setter) { + return setter.priority === priority + }) + .reverse() + }) + .map(function (setterArray) { + return setterArray[0] + }); + + var date = toDate(dirtyBaseDate, options); + + if (isNaN(date)) { + return new Date(NaN) + } + + // Convert the date in system timezone to the same date in UTC+00:00 timezone. + // This ensures that when UTC functions will be implemented, locales will be compatible with them. + // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/37 + var utcDate = subMinutes(date, date.getTimezoneOffset()); + + var dateValues = {date: utcDate}; + + var settersLength = uniquePrioritySetters.length; + for (i = 0; i < settersLength; i++) { + var setter = uniquePrioritySetters[i]; + dateValues = setter.set(dateValues, setter.value, subFnOptions); + } + + return dateValues.date + } + + function dateToSystemTimezone (dateValues) { + var date = dateValues.date; + var time = date.getTime(); + + // Get the system timezone offset at (moment of time - offset) + var offset = date.getTimezoneOffset(); + + // Get the system timezone offset at the exact moment of time + offset = new Date(time + offset * MILLISECONDS_IN_MINUTE$7).getTimezoneOffset(); + + // Convert date in timezone "UTC+00:00" to the system timezone + dateValues.date = new Date(time + offset * MILLISECONDS_IN_MINUTE$7); + + return dateValues + } + + function cleanEscapedString$1 (input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|]$/g, '') + } + return input.replace(/\\/g, '') + } + + // This file is generated automatically by `scripts/build/indices.js`. Please, don't change it. + + // + + /** + * Custom parse behavior on top of date-fns parse function. + */ + function parseDate$1 (date, format$$1) { + if (typeof date !== 'string') { + return isValid(date) ? date : null; + } + + var parsed = parse(date, format$$1, new Date()); + + // if date is not valid or the formatted output after parsing does not match + // the string value passed in (avoids overflows) + if (!isValid(parsed) || format(parsed, format$$1) !== date) { + return null; + } + + return parsed; + } + + var afterValidator = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var targetValue = ref.targetValue; + var inclusion = ref.inclusion; if ( inclusion === void 0 ) inclusion = false; + var format$$1 = ref.format; + + if (typeof format$$1 === 'undefined') { + format$$1 = inclusion; + inclusion = false; + } + + value = parseDate$1(value, format$$1); + targetValue = parseDate$1(targetValue, format$$1); + + // if either is not valid. + if (!value || !targetValue) { + return false; + } + + return isAfter(value, targetValue) || (inclusion && isEqual(value, targetValue)); + }; + + var options = { + hasTarget: true, + isDate: true + }; + + // required to convert from a list of array values to an object. + var paramNames = ['targetValue', 'inclusion', 'format']; + + var after = { + validate: afterValidator, + options: options, + paramNames: paramNames + }; + + /** + * Some Alpha Regex helpers. + * https://github.com/chriso/validator.js/blob/master/src/lib/alpha.js + */ + + var alpha = { + en: /^[A-Z]*$/i, + cs: /^[A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]*$/i, + da: /^[A-ZÆØÅ]*$/i, + de: /^[A-ZÄÖÜß]*$/i, + es: /^[A-ZÁÉÍÑÓÚÜ]*$/i, + fr: /^[A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]*$/i, + lt: /^[A-ZĄČĘĖĮŠŲŪŽ]*$/i, + nl: /^[A-ZÉËÏÓÖÜ]*$/i, + hu: /^[A-ZÁÉÍÓÖŐÚÜŰ]*$/i, + pl: /^[A-ZĄĆĘŚŁŃÓŻŹ]*$/i, + pt: /^[A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]*$/i, + ru: /^[А-ЯЁ]*$/i, + sk: /^[A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ]*$/i, + sr: /^[A-ZČĆŽŠĐ]*$/i, + tr: /^[A-ZÇĞİıÖŞÜ]*$/i, + uk: /^[А-ЩЬЮЯЄІЇҐ]*$/i, + ar: /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]*$/ + }; + + var alphaSpaces = { + en: /^[A-Z\s]*$/i, + cs: /^[A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ\s]*$/i, + da: /^[A-ZÆØÅ\s]*$/i, + de: /^[A-ZÄÖÜß\s]*$/i, + es: /^[A-ZÁÉÍÑÓÚÜ\s]*$/i, + fr: /^[A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ\s]*$/i, + lt: /^[A-ZĄČĘĖĮŠŲŪŽ\s]*$/i, + nl: /^[A-ZÉËÏÓÖÜ\s]*$/i, + hu: /^[A-ZÁÉÍÓÖŐÚÜŰ\s]*$/i, + pl: /^[A-ZĄĆĘŚŁŃÓŻŹ\s]*$/i, + pt: /^[A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ\s]*$/i, + ru: /^[А-ЯЁ\s]*$/i, + sk: /^[A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ\s]*$/i, + sr: /^[A-ZČĆŽŠĐ\s]*$/i, + tr: /^[A-ZÇĞİıÖŞÜ\s]*$/i, + uk: /^[А-ЩЬЮЯЄІЇҐ\s]*$/i, + ar: /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ\s]*$/ + }; + + var alphanumeric = { + en: /^[0-9A-Z]*$/i, + cs: /^[0-9A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]*$/i, + da: /^[0-9A-ZÆØÅ]$/i, + de: /^[0-9A-ZÄÖÜß]*$/i, + es: /^[0-9A-ZÁÉÍÑÓÚÜ]*$/i, + fr: /^[0-9A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]*$/i, + lt: /^[0-9A-ZĄČĘĖĮŠŲŪŽ]*$/i, + hu: /^[0-9A-ZÁÉÍÓÖŐÚÜŰ]*$/i, + nl: /^[0-9A-ZÉËÏÓÖÜ]*$/i, + pl: /^[0-9A-ZĄĆĘŚŁŃÓŻŹ]*$/i, + pt: /^[0-9A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]*$/i, + ru: /^[0-9А-ЯЁ]*$/i, + sk: /^[0-9A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ]*$/i, + sr: /^[0-9A-ZČĆŽŠĐ]*$/i, + tr: /^[0-9A-ZÇĞİıÖŞÜ]*$/i, + uk: /^[0-9А-ЩЬЮЯЄІЇҐ]*$/i, + ar: /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]*$/ + }; + + var alphaDash = { + en: /^[0-9A-Z_-]*$/i, + cs: /^[0-9A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ_-]*$/i, + da: /^[0-9A-ZÆØÅ_-]*$/i, + de: /^[0-9A-ZÄÖÜß_-]*$/i, + es: /^[0-9A-ZÁÉÍÑÓÚÜ_-]*$/i, + fr: /^[0-9A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ_-]*$/i, + lt: /^[0-9A-ZĄČĘĖĮŠŲŪŽ_-]*$/i, + nl: /^[0-9A-ZÉËÏÓÖÜ_-]*$/i, + hu: /^[0-9A-ZÁÉÍÓÖŐÚÜŰ_-]*$/i, + pl: /^[0-9A-ZĄĆĘŚŁŃÓŻŹ_-]*$/i, + pt: /^[0-9A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ_-]*$/i, + ru: /^[0-9А-ЯЁ_-]*$/i, + sk: /^[0-9A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ_-]*$/i, + sr: /^[0-9A-ZČĆŽŠĐ_-]*$/i, + tr: /^[0-9A-ZÇĞİıÖŞÜ_-]*$/i, + uk: /^[0-9А-ЩЬЮЯЄІЇҐ_-]*$/i, + ar: /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ_-]*$/ + }; + + var validate = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var locale = ref.locale; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate(val, [locale]); }); + } + + // Match at least one locale. + if (! locale) { + return Object.keys(alpha).some(function (loc) { return alpha[loc].test(value); }); + } + + return (alpha[locale] || alpha.en).test(value); + }; + + var paramNames$1 = ['locale']; + + var alpha$1 = { + validate: validate, + paramNames: paramNames$1 + }; + + var validate$1 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var locale = ref.locale; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$1(val, [locale]); }); + } + + // Match at least one locale. + if (! locale) { + return Object.keys(alphaDash).some(function (loc) { return alphaDash[loc].test(value); }); + } + + return (alphaDash[locale] || alphaDash.en).test(value); + }; + + var paramNames$2 = ['locale']; + + var alpha_dash = { + validate: validate$1, + paramNames: paramNames$2 + }; + + var validate$2 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var locale = ref.locale; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$2(val, [locale]); }); + } + + // Match at least one locale. + if (! locale) { + return Object.keys(alphanumeric).some(function (loc) { return alphanumeric[loc].test(value); }); + } + + return (alphanumeric[locale] || alphanumeric.en).test(value); + }; + + var paramNames$3 = ['locale']; + + var alpha_num = { + validate: validate$2, + paramNames: paramNames$3 + }; + + var validate$3 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var locale = ref.locale; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$3(val, [locale]); }); + } + + // Match at least one locale. + if (! locale) { + return Object.keys(alphaSpaces).some(function (loc) { return alphaSpaces[loc].test(value); }); + } + + return (alphaSpaces[locale] || alphaSpaces.en).test(value); + }; + + var paramNames$4 = ['locale']; + + var alpha_spaces = { + validate: validate$3, + paramNames: paramNames$4 + }; + + var validate$4 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var targetValue = ref.targetValue; + var inclusion = ref.inclusion; if ( inclusion === void 0 ) inclusion = false; + var format$$1 = ref.format; + + if (typeof format$$1 === 'undefined') { + format$$1 = inclusion; + inclusion = false; + } + + value = parseDate$1(value, format$$1); + targetValue = parseDate$1(targetValue, format$$1); + + // if either is not valid. + if (!value || !targetValue) { + return false; + } + + return isBefore(value, targetValue) || (inclusion && isEqual(value, targetValue)); + }; + + var options$1 = { + hasTarget: true, + isDate: true + }; + + var paramNames$5 = ['targetValue', 'inclusion', 'format']; + + var before = { + validate: validate$4, + options: options$1, + paramNames: paramNames$5 + }; + + var validate$5 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var min = ref.min; + var max = ref.max; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$5(val, { min: min, max: max }); }); + } + + return Number(min) <= value && Number(max) >= value; + }; + + var paramNames$6 = ['min', 'max']; + + var between = { + validate: validate$5, + paramNames: paramNames$6 + }; + + var validate$6 = function (value, ref) { + var targetValue = ref.targetValue; + + return String(value) === String(targetValue); + }; + var options$2 = { + hasTarget: true + }; + + var paramNames$7 = ['targetValue']; + + var confirmed = { + validate: validate$6, + options: options$2, + paramNames: paramNames$7 + }; + + function unwrapExports (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + var assertString_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = assertString; + function assertString(input) { + var isString = typeof input === 'string' || input instanceof String; + + if (!isString) { + throw new TypeError('This library (validator.js) validates strings only'); + } + } + module.exports = exports['default']; + }); + + unwrapExports(assertString_1); + + var isCreditCard_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = isCreditCard; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + /* eslint-disable max-len */ + var creditCard = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11}|6[27][0-9]{14})$/; + /* eslint-enable max-len */ + + function isCreditCard(str) { + (0, _assertString2.default)(str); + var sanitized = str.replace(/[- ]+/g, ''); + if (!creditCard.test(sanitized)) { + return false; + } + var sum = 0; + var digit = void 0; + var tmpNum = void 0; + var shouldDouble = void 0; + for (var i = sanitized.length - 1; i >= 0; i--) { + digit = sanitized.substring(i, i + 1); + tmpNum = parseInt(digit, 10); + if (shouldDouble) { + tmpNum *= 2; + if (tmpNum >= 10) { + sum += tmpNum % 10 + 1; + } else { + sum += tmpNum; + } + } else { + sum += tmpNum; + } + shouldDouble = !shouldDouble; + } + return !!(sum % 10 === 0 ? sanitized : false); + } + module.exports = exports['default']; + }); + + var isCreditCard = unwrapExports(isCreditCard_1); + + var validate$7 = function (value) { return isCreditCard(String(value)); }; + + var credit_card = { + validate: validate$7 + }; + + var validate$8 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var min$$1 = ref.min; + var max$$1 = ref.max; + var inclusivity = ref.inclusivity; if ( inclusivity === void 0 ) inclusivity = '()'; + var format$$1 = ref.format; + + if (typeof format$$1 === 'undefined') { + format$$1 = inclusivity; + inclusivity = '()'; + } + + var minDate = parseDate$1(String(min$$1), format$$1); + var maxDate = parseDate$1(String(max$$1), format$$1); + var dateVal = parseDate$1(String(value), format$$1); + + if (!minDate || !maxDate || !dateVal) { + return false; + } + + if (inclusivity === '()') { + return isAfter(dateVal, minDate) && isBefore(dateVal, maxDate); + } + + if (inclusivity === '(]') { + return isAfter(dateVal, minDate) && (isEqual(dateVal, maxDate) || isBefore(dateVal, maxDate)); + } + + if (inclusivity === '[)') { + return isBefore(dateVal, maxDate) && (isEqual(dateVal, minDate) || isAfter(dateVal, minDate)); + } + + return isEqual(dateVal, maxDate) || isEqual(dateVal, minDate) || + (isBefore(dateVal, maxDate) && isAfter(dateVal, minDate)); + }; + + var options$3 = { + isDate: true + }; + + var paramNames$8 = ['min', 'max', 'inclusivity', 'format']; + + var date_between = { + validate: validate$8, + options: options$3, + paramNames: paramNames$8 + }; + + var validate$9 = function (value, ref) { + var format = ref.format; + + return !!parseDate$1(value, format); + }; + + var options$4 = { + isDate: true + }; + + var paramNames$9 = ['format']; + + var date_format = { + validate: validate$9, + options: options$4, + paramNames: paramNames$9 + }; + + var validate$a = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var decimals = ref.decimals; if ( decimals === void 0 ) decimals = '*'; + var separator = ref.separator; if ( separator === void 0 ) separator = '.'; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$a(val, { decimals: decimals, separator: separator }); }); + } + + if (value === null || value === undefined || value === '') { + return true; + } + + // if is 0. + if (Number(decimals) === 0) { + return /^-?\d*$/.test(value); + } + + var regexPart = decimals === '*' ? '+' : ("{1," + decimals + "}"); + var regex = new RegExp(("^-?\\d*(\\" + separator + "\\d" + regexPart + ")?$")); + + if (! regex.test(value)) { + return false; + } + + var parsedValue = parseFloat(value); + + // eslint-disable-next-line + return parsedValue === parsedValue; + }; + + var paramNames$a = ['decimals', 'separator']; + + var decimal = { + validate: validate$a, + paramNames: paramNames$a + }; + + var validate$b = function (value, ref) { + var length = ref[0]; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$b(val, [length]); }); + } + var strVal = String(value); + + return /^[0-9]*$/.test(strVal) && strVal.length === Number(length); + }; + + var digits = { + validate: validate$b + }; + + var validateImage = function (file, width, height) { + var URL = window.URL || window.webkitURL; + return new Promise(function (resolve) { + var image = new Image(); + image.onerror = function () { return resolve({ valid: false }); }; + image.onload = function () { return resolve({ + valid: image.width === Number(width) && image.height === Number(height) + }); }; + + image.src = URL.createObjectURL(file); + }); + }; + + var validate$c = function (files, ref) { + var width = ref[0]; + var height = ref[1]; + + var list = []; + for (var i = 0; i < files.length; i++) { + // if file is not an image, reject. + if (! /\.(jpg|svg|jpeg|png|bmp|gif)$/i.test(files[i].name)) { + return false; + } + + list.push(files[i]); + } + + return Promise.all(list.map(function (file) { return validateImage(file, width, height); })); + }; + + var dimensions = { + validate: validate$c + }; + + var merge_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = merge; + function merge() { + var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var defaults = arguments[1]; + + for (var key in defaults) { + if (typeof obj[key] === 'undefined') { + obj[key] = defaults[key]; + } + } + return obj; + } + module.exports = exports['default']; + }); + + unwrapExports(merge_1); + + var isByteLength_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + + exports.default = isByteLength; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + /* eslint-disable prefer-rest-params */ + function isByteLength(str, options) { + (0, _assertString2.default)(str); + var min = void 0; + var max = void 0; + if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') { + min = options.min || 0; + max = options.max; + } else { + // backwards compatibility: isByteLength(str, min [, max]) + min = arguments[1]; + max = arguments[2]; + } + var len = encodeURI(str).split(/%..|./).length - 1; + return len >= min && (typeof max === 'undefined' || len <= max); + } + module.exports = exports['default']; + }); + + unwrapExports(isByteLength_1); + + var isFQDN_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = isFQDN; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + + + var _merge2 = _interopRequireDefault(merge_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + var default_fqdn_options = { + require_tld: true, + allow_underscores: false, + allow_trailing_dot: false + }; + + function isFQDN(str, options) { + (0, _assertString2.default)(str); + options = (0, _merge2.default)(options, default_fqdn_options); + + /* Remove the optional trailing dot before checking validity */ + if (options.allow_trailing_dot && str[str.length - 1] === '.') { + str = str.substring(0, str.length - 1); + } + var parts = str.split('.'); + for (var i = 0; i < parts.length; i++) { + if (parts[i].length > 63) { + return false; + } + } + if (options.require_tld) { + var tld = parts.pop(); + if (!parts.length || !/^([a-z\u00a1-\uffff]{2,}|xn[a-z0-9-]{2,})$/i.test(tld)) { + return false; + } + // disallow spaces + if (/[\s\u2002-\u200B\u202F\u205F\u3000\uFEFF\uDB40\uDC20]/.test(tld)) { + return false; + } + } + for (var part, _i = 0; _i < parts.length; _i++) { + part = parts[_i]; + if (options.allow_underscores) { + part = part.replace(/_/g, ''); + } + if (!/^[a-z\u00a1-\uffff0-9-]+$/i.test(part)) { + return false; + } + // disallow full-width chars + if (/[\uff01-\uff5e]/.test(part)) { + return false; + } + if (part[0] === '-' || part[part.length - 1] === '-') { + return false; + } + } + return true; + } + module.exports = exports['default']; + }); + + unwrapExports(isFQDN_1); + + var isIP_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = isIP; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + var ipv4Maybe = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/; + var ipv6Block = /^[0-9A-F]{1,4}$/i; + + function isIP(str) { + var version = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + + (0, _assertString2.default)(str); + version = String(version); + if (!version) { + return isIP(str, 4) || isIP(str, 6); + } else if (version === '4') { + if (!ipv4Maybe.test(str)) { + return false; + } + var parts = str.split('.').sort(function (a, b) { + return a - b; + }); + return parts[3] <= 255; + } else if (version === '6') { + var blocks = str.split(':'); + var foundOmissionBlock = false; // marker to indicate :: + + // At least some OS accept the last 32 bits of an IPv6 address + // (i.e. 2 of the blocks) in IPv4 notation, and RFC 3493 says + // that '::ffff:a.b.c.d' is valid for IPv4-mapped IPv6 addresses, + // and '::a.b.c.d' is deprecated, but also valid. + var foundIPv4TransitionBlock = isIP(blocks[blocks.length - 1], 4); + var expectedNumberOfBlocks = foundIPv4TransitionBlock ? 7 : 8; + + if (blocks.length > expectedNumberOfBlocks) { + return false; + } + // initial or final :: + if (str === '::') { + return true; + } else if (str.substr(0, 2) === '::') { + blocks.shift(); + blocks.shift(); + foundOmissionBlock = true; + } else if (str.substr(str.length - 2) === '::') { + blocks.pop(); + blocks.pop(); + foundOmissionBlock = true; + } + + for (var i = 0; i < blocks.length; ++i) { + // test for a :: which can not be at the string start/end + // since those cases have been handled above + if (blocks[i] === '' && i > 0 && i < blocks.length - 1) { + if (foundOmissionBlock) { + return false; // multiple :: in address + } + foundOmissionBlock = true; + } else if (foundIPv4TransitionBlock && i === blocks.length - 1) ; else if (!ipv6Block.test(blocks[i])) { + return false; + } + } + if (foundOmissionBlock) { + return blocks.length >= 1; + } + return blocks.length === expectedNumberOfBlocks; + } + return false; + } + module.exports = exports['default']; + }); + + var isIP = unwrapExports(isIP_1); + + var isEmail_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = isEmail; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + + + var _merge2 = _interopRequireDefault(merge_1); + + + + var _isByteLength2 = _interopRequireDefault(isByteLength_1); + + + + var _isFQDN2 = _interopRequireDefault(isFQDN_1); + + + + var _isIP2 = _interopRequireDefault(isIP_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + var default_email_options = { + allow_display_name: false, + require_display_name: false, + allow_utf8_local_part: true, + require_tld: true + }; + + /* eslint-disable max-len */ + /* eslint-disable no-control-regex */ + var displayName = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\,\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\s]*<(.+)>$/i; + var emailUserPart = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~]+$/i; + var gmailUserPart = /^[a-z\d]+$/; + var quotedEmailUser = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f]))*$/i; + var emailUserUtf8Part = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$/i; + var quotedEmailUserUtf8 = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*$/i; + /* eslint-enable max-len */ + /* eslint-enable no-control-regex */ + + function isEmail(str, options) { + (0, _assertString2.default)(str); + options = (0, _merge2.default)(options, default_email_options); + + if (options.require_display_name || options.allow_display_name) { + var display_email = str.match(displayName); + if (display_email) { + str = display_email[1]; + } else if (options.require_display_name) { + return false; + } + } + + var parts = str.split('@'); + var domain = parts.pop(); + var user = parts.join('@'); + + var lower_domain = domain.toLowerCase(); + + if (options.domain_specific_validation && (lower_domain === 'gmail.com' || lower_domain === 'googlemail.com')) { + /* + Previously we removed dots for gmail addresses before validating. + This was removed because it allows `multiple..dots@gmail.com` + to be reported as valid, but it is not. + Gmail only normalizes single dots, removing them from here is pointless, + should be done in normalizeEmail + */ + user = user.toLowerCase(); + + // Removing sub-address from username before gmail validation + var username = user.split('+')[0]; + + // Dots are not included in gmail length restriction + if (!(0, _isByteLength2.default)(username.replace('.', ''), { min: 6, max: 30 })) { + return false; + } + + var _user_parts = username.split('.'); + for (var i = 0; i < _user_parts.length; i++) { + if (!gmailUserPart.test(_user_parts[i])) { + return false; + } + } + } + + if (!(0, _isByteLength2.default)(user, { max: 64 }) || !(0, _isByteLength2.default)(domain, { max: 254 })) { + return false; + } + + if (!(0, _isFQDN2.default)(domain, { require_tld: options.require_tld })) { + if (!options.allow_ip_domain) { + return false; + } + + if (!(0, _isIP2.default)(domain)) { + if (!domain.startsWith('[') || !domain.endsWith(']')) { + return false; + } + + var noBracketdomain = domain.substr(1, domain.length - 2); + + if (noBracketdomain.length === 0 || !(0, _isIP2.default)(noBracketdomain)) { + return false; + } + } + } + + if (user[0] === '"') { + user = user.slice(1, user.length - 1); + return options.allow_utf8_local_part ? quotedEmailUserUtf8.test(user) : quotedEmailUser.test(user); + } + + var pattern = options.allow_utf8_local_part ? emailUserUtf8Part : emailUserPart; + + var user_parts = user.split('.'); + for (var _i = 0; _i < user_parts.length; _i++) { + if (!pattern.test(user_parts[_i])) { + return false; + } + } + + return true; + } + module.exports = exports['default']; + }); + + var isEmail = unwrapExports(isEmail_1); + + var validate$d = function (value, options) { + if ( options === void 0 ) options = {}; + + if (options.multiple) { + value = value.split(',').map(function (emailStr) { return emailStr.trim(); }); + } + + if (Array.isArray(value)) { + return value.every(function (val) { return isEmail(String(val), options); }); + } + + return isEmail(String(value), options); + }; + + var email = { + validate: validate$d + }; + + // + + var supportsPassive = true; + + var detectPassiveSupport = function () { + try { + var opts = Object.defineProperty({}, 'passive', { + get: function get () { + supportsPassive = true; + } + }); + window.addEventListener('testPassive', null, opts); + window.removeEventListener('testPassive', null, opts); + } catch (e) { + supportsPassive = false; + } + return supportsPassive; + }; + + var addEventListener = function (el, eventName, cb) { + el.addEventListener(eventName, cb, supportsPassive ? { passive: true } : false); + }; + + var isTextInput = function (el) { + return includes(['text', 'password', 'search', 'email', 'tel', 'url', 'textarea'], el.type); + }; + + var isCheckboxOrRadioInput = function (el) { + return includes(['radio', 'checkbox'], el.type); + }; + + var isDateInput = function (el) { + return includes(['date', 'week', 'month', 'datetime-local', 'time'], el.type); + }; + + /** + * Gets the data attribute. the name must be kebab-case. + */ + var getDataAttribute = function (el, name) { return el.getAttribute(("data-vv-" + name)); }; + + /** + * Checks if the values are either null or undefined. + */ + var isNullOrUndefined = function () { + var values = [], len = arguments.length; + while ( len-- ) values[ len ] = arguments[ len ]; + + return values.every(function (value) { + return value === null || value === undefined; + }); + }; + + /** + * Creates the default flags object. + */ + var createFlags = function () { return ({ + untouched: true, + touched: false, + dirty: false, + pristine: true, + valid: null, + invalid: null, + validated: false, + pending: false, + required: false, + changed: false + }); }; + + /** + * Shallow object comparison. + */ + var isEqual$1 = function (lhs, rhs) { + if (lhs instanceof RegExp && rhs instanceof RegExp) { + return isEqual$1(lhs.source, rhs.source) && isEqual$1(lhs.flags, rhs.flags); + } + + if (Array.isArray(lhs) && Array.isArray(rhs)) { + if (lhs.length !== rhs.length) { return false; } + + for (var i = 0; i < lhs.length; i++) { + if (!isEqual$1(lhs[i], rhs[i])) { + return false; + } + } + + return true; + } + + // if both are objects, compare each key recursively. + if (isObject(lhs) && isObject(rhs)) { + return Object.keys(lhs).every(function (key) { + return isEqual$1(lhs[key], rhs[key]); + }) && Object.keys(rhs).every(function (key) { + return isEqual$1(lhs[key], rhs[key]); + }); + } + + return lhs === rhs; + }; + + /** + * Determines the input field scope. + */ + var getScope = function (el) { + var scope = getDataAttribute(el, 'scope'); + if (isNullOrUndefined(scope)) { + var form = getForm(el); + + if (form) { + scope = getDataAttribute(form, 'scope'); + } + } + + return !isNullOrUndefined(scope) ? scope : null; + }; + + /** + * Get the closest form element. + */ + var getForm = function (el) { + if (isNullOrUndefined(el)) { return null; } + + if (el.tagName === 'FORM') { return el; } + + if (!isNullOrUndefined(el.form)) { return el.form; } + + return !isNullOrUndefined(el.parentNode) ? getForm(el.parentNode) : null; + }; + + /** + * Gets the value in an object safely. + */ + var getPath = function (path, target, def) { + if ( def === void 0 ) def = undefined; + + if (!path || !target) { return def; } + + var value = target; + path.split('.').every(function (prop) { + if (prop in value) { + value = value[prop]; + + return true; + } + + value = def; + + return false; + }); + + return value; + }; + + /** + * Checks if path exists within an object. + */ + var hasPath = function (path, target) { + var obj = target; + return path.split('.').every(function (prop) { + if (prop in obj) { + obj = obj[prop]; + + return true; + } + + return false; + }); + }; + + /** + * Parses a rule string expression. + */ + var parseRule = function (rule) { + var params = []; + var name = rule.split(':')[0]; + + if (includes(rule, ':')) { + params = rule.split(':').slice(1).join(':').split(','); + } + + return { name: name, params: params }; + }; + + /** + * Debounces a function. + */ + var debounce = function (fn, wait, immediate, token) { + if ( wait === void 0 ) wait = 0; + if ( immediate === void 0 ) immediate = false; + if ( token === void 0 ) token = { cancelled: false }; + + if (wait === 0) { + return fn; + } + + var timeout; + + return function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var later = function () { + timeout = null; + + if (!immediate && !token.cancelled) { fn.apply(void 0, args); } + }; + /* istanbul ignore next */ + var callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + /* istanbul ignore next */ + if (callNow) { fn.apply(void 0, args); } + }; + }; + + /** + * Appends a rule definition to a list of rules. + */ + var appendRule = function (rule, rules) { + if (!rules) { + return normalizeRules(rule); + } + + if (!rule) { + return normalizeRules(rules); + } + + if (typeof rules === 'string') { + rules = normalizeRules(rules); + } + + return assign({}, rules, normalizeRules(rule)); + }; + + /** + * Normalizes the given rules expression. + */ + var normalizeRules = function (rules) { + // if falsy value return an empty object. + if (!rules) { + return {}; + } + + if (isObject(rules)) { + // $FlowFixMe + return Object.keys(rules).reduce(function (prev, curr) { + var params = []; + // $FlowFixMe + if (rules[curr] === true) { + params = []; + } else if (Array.isArray(rules[curr])) { + params = rules[curr]; + } else if (isObject(rules[curr])) { + params = rules[curr]; + } else { + params = [rules[curr]]; + } + + // $FlowFixMe + if (rules[curr] !== false) { + prev[curr] = params; + } + + return prev; + }, {}); + } + + if (typeof rules !== 'string') { + warn('rules must be either a string or an object.'); + return {}; + } + + return rules.split('|').reduce(function (prev, rule) { + var parsedRule = parseRule(rule); + if (!parsedRule.name) { + return prev; + } + + prev[parsedRule.name] = parsedRule.params; + return prev; + }, {}); + }; + + /** + * Emits a warning to the console. + */ + var warn = function (message) { + console.warn(("[vee-validate] " + message)); // eslint-disable-line + }; + + /** + * Creates a branded error object. + */ + var createError = function (message) { return new Error(("[vee-validate] " + message)); }; + + /** + * Checks if the value is an object. + */ + var isObject = function (obj) { return obj !== null && obj && typeof obj === 'object' && ! Array.isArray(obj); }; + + /** + * Checks if a function is callable. + */ + var isCallable = function (func) { return typeof func === 'function'; }; + + /** + * Check if element has the css class on it. + */ + var hasClass = function (el, className) { + if (el.classList) { + return el.classList.contains(className); + } + + return !!el.className.match(new RegExp(("(\\s|^)" + className + "(\\s|$)"))); + }; + + /** + * Adds the provided css className to the element. + */ + var addClass = function (el, className) { + if (el.classList) { + el.classList.add(className); + return; + } + + if (!hasClass(el, className)) { + el.className += " " + className; + } + }; + + /** + * Remove the provided css className from the element. + */ + var removeClass = function (el, className) { + if (el.classList) { + el.classList.remove(className); + return; + } + + if (hasClass(el, className)) { + var reg = new RegExp(("(\\s|^)" + className + "(\\s|$)")); + el.className = el.className.replace(reg, ' '); + } + }; + + /** + * Adds or removes a class name on the input depending on the status flag. + */ + var toggleClass = function (el, className, status) { + if (!el || !className) { return; } + + if (Array.isArray(className)) { + className.forEach(function (item) { return toggleClass(el, item, status); }); + return; + } + + if (status) { + return addClass(el, className); + } + + removeClass(el, className); + }; + + /** + * Converts an array-like object to array, provides a simple polyfill for Array.from + */ + var toArray = function (arrayLike) { + if (isCallable(Array.from)) { + return Array.from(arrayLike); + } + + var array = []; + var length = arrayLike.length; + /* istanbul ignore next */ + for (var i = 0; i < length; i++) { + array.push(arrayLike[i]); + } + + /* istanbul ignore next */ + return array; + }; + + /** + * Assign polyfill from the mdn. + */ + var assign = function (target) { + var others = [], len = arguments.length - 1; + while ( len-- > 0 ) others[ len ] = arguments[ len + 1 ]; + + /* istanbul ignore else */ + if (isCallable(Object.assign)) { + return Object.assign.apply(Object, [ target ].concat( others )); + } + + /* istanbul ignore next */ + if (target == null) { + throw new TypeError('Cannot convert undefined or null to object'); + } + + /* istanbul ignore next */ + var to = Object(target); + /* istanbul ignore next */ + others.forEach(function (arg) { + // Skip over if undefined or null + if (arg != null) { + Object.keys(arg).forEach(function (key) { + to[key] = arg[key]; + }); + } + }); + /* istanbul ignore next */ + return to; + }; + + var id = 0; + var idTemplate = '{id}'; + + /** + * Generates a unique id. + */ + var uniqId = function () { + // handle too many uses of uniqId, although unlikely. + if (id >= 9999) { + id = 0; + // shift the template. + idTemplate = idTemplate.replace('{id}', '_{id}'); + } + + id++; + var newId = idTemplate.replace('{id}', String(id)); + + return newId; + }; + + /** + * finds the first element that satisfies the predicate callback, polyfills array.find + */ + var find = function (arrayLike, predicate) { + var array = Array.isArray(arrayLike) ? arrayLike : toArray(arrayLike); + for (var i = 0; i < array.length; i++) { + if (predicate(array[i])) { + return array[i]; + } + } + + return undefined; + }; + + var isBuiltInComponent = function (vnode) { + if (!vnode) { + return false; + } + + var tag = vnode.componentOptions.tag; + + return /^(keep-alive|transition|transition-group)$/.test(tag); + }; + + var makeEventsArray = function (events) { + return (typeof events === 'string' && events.length) ? events.split('|') : []; + }; + + var makeDelayObject = function (events, delay, delayConfig) { + if (typeof delay === 'number') { + return events.reduce(function (prev, e) { + prev[e] = delay; + return prev; + }, {}); + } + + return events.reduce(function (prev, e) { + if (typeof delay === 'object' && e in delay) { + prev[e] = delay[e]; + return prev; + } + + if (typeof delayConfig === 'number') { + prev[e] = delayConfig; + return prev; + } + + prev[e] = (delayConfig && delayConfig[e]) || 0; + + return prev; + }, {}); + }; + + var deepParseInt = function (input) { + if (typeof input === 'number') { return input; } + + if (typeof input === 'string') { return parseInt(input); } + + var map = {}; + for (var element in input) { + map[element] = parseInt(input[element]); + } + + return map; + }; + + var merge$1 = function (target, source) { + if (! (isObject(target) && isObject(source))) { + return target; + } + + Object.keys(source).forEach(function (key) { + var obj, obj$1; + + if (isObject(source[key])) { + if (! target[key]) { + assign(target, ( obj = {}, obj[key] = {}, obj )); + } + + merge$1(target[key], source[key]); + return; + } + + assign(target, ( obj$1 = {}, obj$1[key] = source[key], obj$1 )); + }); + + return target; + }; + + var fillRulesFromElement = function (el, rules) { + if (el.required) { + rules = appendRule('required', rules); + } + + if (isTextInput(el)) { + if (el.type === 'email') { + rules = appendRule(("email" + (el.multiple ? ':multiple' : '')), rules); + } + + if (el.pattern) { + rules = appendRule({ regex: el.pattern }, rules); + } + + // 524288 is the max on some browsers and test environments. + if (el.maxLength >= 0 && el.maxLength < 524288) { + rules = appendRule(("max:" + (el.maxLength)), rules); + } + + if (el.minLength > 0) { + rules = appendRule(("min:" + (el.minLength)), rules); + } + + return rules; + } + + if (el.type === 'number') { + rules = appendRule('decimal', rules); + if (el.min !== '') { + rules = appendRule(("min_value:" + (el.min)), rules); + } + + if (el.max !== '') { + rules = appendRule(("max_value:" + (el.max)), rules); + } + + return rules; + } + + if (isDateInput(el)) { + var timeFormat = el.step && Number(el.step) < 60 ? 'HH:mm:ss' : 'HH:mm'; + + if (el.type === 'date') { + return appendRule('date_format:YYYY-MM-DD', rules); + } + + if (el.type === 'datetime-local') { + return appendRule(("date_format:YYYY-MM-DDT" + timeFormat), rules); + } + + if (el.type === 'month') { + return appendRule('date_format:YYYY-MM', rules); + } + + if (el.type === 'week') { + return appendRule('date_format:YYYY-[W]WW', rules); + } + + if (el.type === 'time') { + return appendRule(("date_format:" + timeFormat), rules); + } + } + + return rules; + }; + + var values = function (obj) { + if (isCallable(Object.values)) { + return Object.values(obj); + } + + // fallback to keys() + /* istanbul ignore next */ + return obj[Object.keys(obj)[0]]; + }; + + var parseSelector = function (selector) { + var rule = null; + if (includes(selector, ':')) { + rule = selector.split(':').pop(); + selector = selector.replace((":" + rule), ''); + } + + if (selector[0] === '#') { + return { + id: selector.slice(1), + rule: rule, + name: null, + scope: null + }; + } + + var scope = null; + var name = selector; + if (includes(selector, '.')) { + var parts = selector.split('.'); + scope = parts[0]; + name = parts.slice(1).join('.'); + } + + return { + id: null, + scope: scope, + name: name, + rule: rule + }; + }; + + var includes = function (collection, item) { + return collection.indexOf(item) !== -1; + }; + + var validate$e = function (value, options) { + if (Array.isArray(value)) { + return value.every(function (val) { return validate$e(val, options); }); + } + + return toArray(options).some(function (item) { + // eslint-disable-next-line + return item == value; + }); + }; + + var included = { + validate: validate$e + }; + + var validate$f = function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + return !validate$e.apply(void 0, args); + }; + + var excluded = { + validate: validate$f + }; + + var validate$g = function (files, extensions) { + var regex = new RegExp((".(" + (extensions.join('|')) + ")$"), 'i'); + + return files.every(function (file) { return regex.test(file.name); }); + }; + + var ext = { + validate: validate$g + }; + + var validate$h = function (files) { return files.every(function (file) { return /\.(jpg|svg|jpeg|png|bmp|gif)$/i.test(file.name); }); }; + + var image = { + validate: validate$h + }; + + var validate$i = function (value) { + if (Array.isArray(value)) { + return value.every(function (val) { return /^-?[0-9]+$/.test(String(val)); }); + } + + return /^-?[0-9]+$/.test(String(value)); + }; + + var integer = { + validate: validate$i + }; + + var validate$j = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var version = ref.version; if ( version === void 0 ) version = 4; + + if (isNullOrUndefined(value)) { + value = ''; + } + + if (Array.isArray(value)) { + return value.every(function (val) { return isIP(val, version); }); + } + + return isIP(value, version); + }; + + var paramNames$b = ['version']; + + var ip = { + validate: validate$j, + paramNames: paramNames$b + }; + + var validate$k = function (value, ref) { + if ( ref === void 0 ) ref = []; + var other = ref[0]; + + return value === other; + }; + + var is = { + validate: validate$k + }; + + var validate$l = function (value, ref) { + if ( ref === void 0 ) ref = []; + var other = ref[0]; + + return value !== other; + }; + + var is_not = { + validate: validate$l + }; + + /** + * @param {Array|String} value + * @param {Number} length + * @param {Number} max + */ + var compare = function (value, length, max) { + if (max === undefined) { + return value.length === length; + } + + // cast to number. + max = Number(max); + + return value.length >= length && value.length <= max; + }; + + var validate$m = function (value, ref) { + var length = ref[0]; + var max = ref[1]; if ( max === void 0 ) max = undefined; + + length = Number(length); + if (value === undefined || value === null) { + return false; + } + + if (typeof value === 'number') { + value = String(value); + } + + if (!value.length) { + value = toArray(value); + } + + return compare(value, length, max); + }; + + var length = { + validate: validate$m + }; + + var validate$n = function (value, ref) { + var length = ref[0]; + + if (value === undefined || value === null) { + return length >= 0; + } + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$n(val, [length]); }); + } + + return String(value).length <= length; + }; + + var max$1 = { + validate: validate$n + }; + + var validate$o = function (value, ref) { + var max = ref[0]; + + if (value === null || value === undefined || value === '') { + return false; + } + + if (Array.isArray(value)) { + return value.length > 0 && value.every(function (val) { return validate$o(val, [max]); }); + } + + return Number(value) <= max; + }; + + var max_value = { + validate: validate$o + }; + + var validate$p = function (files, mimes) { + var regex = new RegExp(((mimes.join('|').replace('*', '.+')) + "$"), 'i'); + + return files.every(function (file) { return regex.test(file.type); }); + }; + + var mimes = { + validate: validate$p + }; + + var validate$q = function (value, ref) { + var length = ref[0]; + + if (value === undefined || value === null) { + return false; + } + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$q(val, [length]); }); + } + + return String(value).length >= length; + }; + + var min$1 = { + validate: validate$q + }; + + var validate$r = function (value, ref) { + var min = ref[0]; + + if (value === null || value === undefined || value === '') { + return false; + } + + if (Array.isArray(value)) { + return value.length > 0 && value.every(function (val) { return validate$r(val, [min]); }); + } + + return Number(value) >= min; + }; + + var min_value = { + validate: validate$r + }; + + var validate$s = function (value) { + if (Array.isArray(value)) { + return value.every(function (val) { return /^[0-9]+$/.test(String(val)); }); + } + + return /^[0-9]+$/.test(String(value)); + }; + + var numeric = { + validate: validate$s + }; + + var validate$t = function (value, ref) { + var expression = ref.expression; + + if (typeof expression === 'string') { + expression = new RegExp(expression); + } + + return expression.test(String(value)); + }; + + var paramNames$c = ['expression']; + + var regex = { + validate: validate$t, + paramNames: paramNames$c + }; + + var validate$u = function (value, ref) { + if ( ref === void 0 ) ref = []; + var invalidateFalse = ref[0]; if ( invalidateFalse === void 0 ) invalidateFalse = false; + + if (Array.isArray(value)) { + return !!value.length; + } + + // incase a field considers `false` as an empty value like checkboxes. + if (value === false && invalidateFalse) { + return false; + } + + if (value === undefined || value === null) { + return false; + } + + return !!String(value).trim().length; + }; + + var required = { + validate: validate$u + }; + + var validate$v = function (files, ref) { + var size = ref[0]; + + if (isNaN(size)) { + return false; + } + + var nSize = Number(size) * 1024; + for (var i = 0; i < files.length; i++) { + if (files[i].size > nSize) { + return false; + } + } + + return true; + }; + + var size = { + validate: validate$v + }; + + var isURL_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = isURL; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + + + var _isFQDN2 = _interopRequireDefault(isFQDN_1); + + + + var _isIP2 = _interopRequireDefault(isIP_1); + + + + var _merge2 = _interopRequireDefault(merge_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + var default_url_options = { + protocols: ['http', 'https', 'ftp'], + require_tld: true, + require_protocol: false, + require_host: true, + require_valid_protocol: true, + allow_underscores: false, + allow_trailing_dot: false, + allow_protocol_relative_urls: false + }; + + var wrapped_ipv6 = /^\[([^\]]+)\](?::([0-9]+))?$/; + + function isRegExp(obj) { + return Object.prototype.toString.call(obj) === '[object RegExp]'; + } + + function checkHost(host, matches) { + for (var i = 0; i < matches.length; i++) { + var match = matches[i]; + if (host === match || isRegExp(match) && match.test(host)) { + return true; + } + } + return false; + } + + function isURL(url, options) { + (0, _assertString2.default)(url); + if (!url || url.length >= 2083 || /[\s<>]/.test(url)) { + return false; + } + if (url.indexOf('mailto:') === 0) { + return false; + } + options = (0, _merge2.default)(options, default_url_options); + var protocol = void 0, + auth = void 0, + host = void 0, + hostname = void 0, + port = void 0, + port_str = void 0, + split = void 0, + ipv6 = void 0; + + split = url.split('#'); + url = split.shift(); + + split = url.split('?'); + url = split.shift(); + + split = url.split('://'); + if (split.length > 1) { + protocol = split.shift().toLowerCase(); + if (options.require_valid_protocol && options.protocols.indexOf(protocol) === -1) { + return false; + } + } else if (options.require_protocol) { + return false; + } else if (url.substr(0, 2) === '//') { + if (!options.allow_protocol_relative_urls) { + return false; + } + split[0] = url.substr(2); + } + url = split.join('://'); + + if (url === '') { + return false; + } + + split = url.split('/'); + url = split.shift(); + + if (url === '' && !options.require_host) { + return true; + } + + split = url.split('@'); + if (split.length > 1) { + auth = split.shift(); + if (auth.indexOf(':') >= 0 && auth.split(':').length > 2) { + return false; + } + } + hostname = split.join('@'); + + port_str = null; + ipv6 = null; + var ipv6_match = hostname.match(wrapped_ipv6); + if (ipv6_match) { + host = ''; + ipv6 = ipv6_match[1]; + port_str = ipv6_match[2] || null; + } else { + split = hostname.split(':'); + host = split.shift(); + if (split.length) { + port_str = split.join(':'); + } + } + + if (port_str !== null) { + port = parseInt(port_str, 10); + if (!/^[0-9]+$/.test(port_str) || port <= 0 || port > 65535) { + return false; + } + } + + if (!(0, _isIP2.default)(host) && !(0, _isFQDN2.default)(host, options) && (!ipv6 || !(0, _isIP2.default)(ipv6, 6))) { + return false; + } + + host = host || ipv6; + + if (options.host_whitelist && !checkHost(host, options.host_whitelist)) { + return false; + } + if (options.host_blacklist && checkHost(host, options.host_blacklist)) { + return false; + } + + return true; + } + module.exports = exports['default']; + }); + + var isURL = unwrapExports(isURL_1); + + var validate$w = function (value, options) { + if ( options === void 0 ) options = {}; + + if (isNullOrUndefined(value)) { + value = ''; + } + + if (Array.isArray(value)) { + return value.every(function (val) { return isURL(val, options); }); + } + + return isURL(value, options); + }; + + var url = { + validate: validate$w + }; + + /* eslint-disable camelcase */ + + var Rules = /*#__PURE__*/Object.freeze({ + after: after, + alpha_dash: alpha_dash, + alpha_num: alpha_num, + alpha_spaces: alpha_spaces, + alpha: alpha$1, + before: before, + between: between, + confirmed: confirmed, + credit_card: credit_card, + date_between: date_between, + date_format: date_format, + decimal: decimal, + digits: digits, + dimensions: dimensions, + email: email, + ext: ext, + image: image, + included: included, + integer: integer, + length: length, + ip: ip, + is_not: is_not, + is: is, + max: max$1, + max_value: max_value, + mimes: mimes, + min: min$1, + min_value: min_value, + excluded: excluded, + numeric: numeric, + regex: regex, + required: required, + size: size, + url: url + }); + + /** + * Formates file size. + * + * @param {Number|String} size + */ + var formatFileSize = function (size) { + var units = ['Byte', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + var threshold = 1024; + size = Number(size) * threshold; + var i = size === 0 ? 0 : Math.floor(Math.log(size) / Math.log(threshold)); + return (((size / Math.pow(threshold, i)).toFixed(2) * 1) + " " + (units[i])); + }; + + /** + * Checks if vee-validate is defined globally. + */ + var isDefinedGlobally = function () { + return typeof VeeValidate !== 'undefined'; + }; + + var obj; + + var messages = { + _default: function (field) { return ("The " + field + " value is not valid."); }, + after: function (field, ref) { + var target = ref[0]; + var inclusion = ref[1]; + + return ("The " + field + " must be after " + (inclusion ? 'or equal to ' : '') + target + "."); + }, + alpha_dash: function (field) { return ("The " + field + " field may contain alpha-numeric characters as well as dashes and underscores."); }, + alpha_num: function (field) { return ("The " + field + " field may only contain alpha-numeric characters."); }, + alpha_spaces: function (field) { return ("The " + field + " field may only contain alphabetic characters as well as spaces."); }, + alpha: function (field) { return ("The " + field + " field may only contain alphabetic characters."); }, + before: function (field, ref) { + var target = ref[0]; + var inclusion = ref[1]; + + return ("The " + field + " must be before " + (inclusion ? 'or equal to ' : '') + target + "."); + }, + between: function (field, ref) { + var min = ref[0]; + var max = ref[1]; + + return ("The " + field + " field must be between " + min + " and " + max + "."); + }, + confirmed: function (field) { return ("The " + field + " confirmation does not match."); }, + credit_card: function (field) { return ("The " + field + " field is invalid."); }, + date_between: function (field, ref) { + var min = ref[0]; + var max = ref[1]; + + return ("The " + field + " must be between " + min + " and " + max + "."); + }, + date_format: function (field, ref) { + var format = ref[0]; + + return ("The " + field + " must be in the format " + format + "."); + }, + decimal: function (field, ref) { + if ( ref === void 0 ) ref = []; + var decimals = ref[0]; if ( decimals === void 0 ) decimals = '*'; + + return ("The " + field + " field must be numeric and may contain " + (!decimals || decimals === '*' ? '' : decimals) + " decimal points."); + }, + digits: function (field, ref) { + var length = ref[0]; + + return ("The " + field + " field must be numeric and exactly contain " + length + " digits."); + }, + dimensions: function (field, ref) { + var width = ref[0]; + var height = ref[1]; + + return ("The " + field + " field must be " + width + " pixels by " + height + " pixels."); + }, + email: function (field) { return ("The " + field + " field must be a valid email."); }, + ext: function (field) { return ("The " + field + " field must be a valid file."); }, + image: function (field) { return ("The " + field + " field must be an image."); }, + included: function (field) { return ("The " + field + " field must be a valid value."); }, + integer: function (field) { return ("The " + field + " field must be an integer."); }, + ip: function (field) { return ("The " + field + " field must be a valid ip address."); }, + length: function (field, ref) { + var length = ref[0]; + var max = ref[1]; + + if (max) { + return ("The " + field + " length must be between " + length + " and " + max + "."); + } + + return ("The " + field + " length must be " + length + "."); + }, + max: function (field, ref) { + var length = ref[0]; + + return ("The " + field + " field may not be greater than " + length + " characters."); + }, + max_value: function (field, ref) { + var max = ref[0]; + + return ("The " + field + " field must be " + max + " or less."); + }, + mimes: function (field) { return ("The " + field + " field must have a valid file type."); }, + min: function (field, ref) { + var length = ref[0]; + + return ("The " + field + " field must be at least " + length + " characters."); + }, + min_value: function (field, ref) { + var min = ref[0]; + + return ("The " + field + " field must be " + min + " or more."); + }, + excluded: function (field) { return ("The " + field + " field must be a valid value."); }, + numeric: function (field) { return ("The " + field + " field may only contain numeric characters."); }, + regex: function (field) { return ("The " + field + " field format is invalid."); }, + required: function (field) { return ("The " + field + " field is required."); }, + size: function (field, ref) { + var size = ref[0]; + + return ("The " + field + " size must be less than " + (formatFileSize(size)) + "."); + }, + url: function (field) { return ("The " + field + " field is not a valid URL."); } + }; + + var locale$1 = { + name: 'en', + messages: messages, + attributes: {} + }; + + if (isDefinedGlobally()) { + // eslint-disable-next-line + VeeValidate.Validator.localize(( obj = {}, obj[locale$1.name] = locale$1, obj )); + } + + // + + var LOCALE = 'en'; + + var Dictionary = function Dictionary (dictionary) { + if ( dictionary === void 0 ) dictionary = {}; + + this.container = {}; + this.merge(dictionary); + }; + + var prototypeAccessors = { locale: { configurable: true } }; + + prototypeAccessors.locale.get = function () { + return LOCALE; + }; + + prototypeAccessors.locale.set = function (value) { + LOCALE = value || 'en'; + }; + + Dictionary.prototype.hasLocale = function hasLocale (locale) { + return !!this.container[locale]; + }; + + Dictionary.prototype.setDateFormat = function setDateFormat (locale, format) { + if (!this.container[locale]) { + this.container[locale] = {}; + } + + this.container[locale].dateFormat = format; + }; + + Dictionary.prototype.getDateFormat = function getDateFormat (locale) { + if (!this.container[locale] || !this.container[locale].dateFormat) { + return null; + } + + return this.container[locale].dateFormat; + }; + + Dictionary.prototype.getMessage = function getMessage (locale, key, data) { + var message = null; + if (!this.hasMessage(locale, key)) { + message = this._getDefaultMessage(locale); + } else { + message = this.container[locale].messages[key]; + } + + return isCallable(message) ? message.apply(void 0, data) : message; + }; + + /** + * Gets a specific message for field. falls back to the rule message. + */ + Dictionary.prototype.getFieldMessage = function getFieldMessage (locale, field, key, data) { + if (!this.hasLocale(locale)) { + return this.getMessage(locale, key, data); + } + + var dict = this.container[locale].custom && this.container[locale].custom[field]; + if (!dict || !dict[key]) { + return this.getMessage(locale, key, data); + } + + var message = dict[key]; + return isCallable(message) ? message.apply(void 0, data) : message; + }; + + Dictionary.prototype._getDefaultMessage = function _getDefaultMessage (locale) { + if (this.hasMessage(locale, '_default')) { + return this.container[locale].messages._default; + } + + return this.container.en.messages._default; + }; + + Dictionary.prototype.getAttribute = function getAttribute (locale, key, fallback) { + if ( fallback === void 0 ) fallback = ''; + + if (!this.hasAttribute(locale, key)) { + return fallback; + } + + return this.container[locale].attributes[key]; + }; + + Dictionary.prototype.hasMessage = function hasMessage (locale, key) { + return !! ( + this.hasLocale(locale) && + this.container[locale].messages && + this.container[locale].messages[key] + ); + }; + + Dictionary.prototype.hasAttribute = function hasAttribute (locale, key) { + return !! ( + this.hasLocale(locale) && + this.container[locale].attributes && + this.container[locale].attributes[key] + ); + }; + + Dictionary.prototype.merge = function merge$1$$1 (dictionary) { + merge$1(this.container, dictionary); + }; + + Dictionary.prototype.setMessage = function setMessage (locale, key, message) { + if (! this.hasLocale(locale)) { + this.container[locale] = { + messages: {}, + attributes: {} + }; + } + + this.container[locale].messages[key] = message; + }; + + Dictionary.prototype.setAttribute = function setAttribute (locale, key, attribute) { + if (! this.hasLocale(locale)) { + this.container[locale] = { + messages: {}, + attributes: {} + }; + } + + this.container[locale].attributes[key] = attribute; + }; + + Object.defineProperties( Dictionary.prototype, prototypeAccessors ); + + // + + var normalizeValue = function (value) { + if (isObject(value)) { + return Object.keys(value).reduce(function (prev, key) { + prev[key] = normalizeValue(value[key]); + + return prev; + }, {}); + } + + if (isCallable(value)) { + return value('{0}', ['{1}', '{2}', '{3}']); + } + + return value; + }; + + var normalizeFormat = function (locale) { + // normalize messages + var dictionary = {}; + if (locale.messages) { + dictionary.messages = normalizeValue(locale.messages); + } + + if (locale.custom) { + dictionary.custom = normalizeValue(locale.custom); + } + + if (locale.attributes) { + dictionary.attributes = locale.attributes; + } + + if (!isNullOrUndefined(locale.dateFormat)) { + dictionary.dateFormat = locale.dateFormat; + } + + return dictionary; + }; + + var I18nDictionary = function I18nDictionary (i18n, rootKey) { + this.i18n = i18n; + this.rootKey = rootKey; + }; + + var prototypeAccessors$1 = { locale: { configurable: true } }; + + prototypeAccessors$1.locale.get = function () { + return this.i18n.locale; + }; + + prototypeAccessors$1.locale.set = function (value) { + warn('Cannot set locale from the validator when using vue-i18n, use i18n.locale setter instead'); + }; + + I18nDictionary.prototype.getDateFormat = function getDateFormat (locale) { + return this.i18n.getDateTimeFormat(locale || this.locale); + }; + + I18nDictionary.prototype.setDateFormat = function setDateFormat (locale, value) { + this.i18n.setDateTimeFormat(locale || this.locale, value); + }; + + I18nDictionary.prototype.getMessage = function getMessage (locale, key, data) { + var path = (this.rootKey) + ".messages." + key; + if (!this.i18n.te(path)) { + return this.i18n.t(((this.rootKey) + ".messages._default"), locale, data); + } + + return this.i18n.t(path, locale, data); + }; + + I18nDictionary.prototype.getAttribute = function getAttribute (locale, key, fallback) { + if ( fallback === void 0 ) fallback = ''; + + var path = (this.rootKey) + ".attributes." + key; + if (!this.i18n.te(path)) { + return fallback; + } + + return this.i18n.t(path, locale); + }; + + I18nDictionary.prototype.getFieldMessage = function getFieldMessage (locale, field, key, data) { + var path = (this.rootKey) + ".custom." + field + "." + key; + if (this.i18n.te(path)) { + return this.i18n.t(path, locale, data); + } + + return this.getMessage(locale, key, data); + }; + + I18nDictionary.prototype.merge = function merge$1$$1 (dictionary) { + var this$1 = this; + + Object.keys(dictionary).forEach(function (localeKey) { + var obj; + + // i18n doesn't deep merge + // first clone the existing locale (avoid mutations to locale) + var clone = merge$1({}, getPath((localeKey + "." + (this$1.rootKey)), this$1.i18n.messages, {})); + // Merge cloned locale with new one + var locale = merge$1(clone, normalizeFormat(dictionary[localeKey])); + this$1.i18n.mergeLocaleMessage(localeKey, ( obj = {}, obj[this$1.rootKey] = locale, obj )); + if (locale.dateFormat) { + this$1.i18n.setDateTimeFormat(localeKey, locale.dateFormat); + } + }); + }; + + I18nDictionary.prototype.setMessage = function setMessage (locale, key, value) { + var obj, obj$1; + + this.merge(( obj$1 = {}, obj$1[locale] = { + messages: ( obj = {}, obj[key] = value, obj ) + }, obj$1 )); + }; + + I18nDictionary.prototype.setAttribute = function setAttribute (locale, key, value) { + var obj, obj$1; + + this.merge(( obj$1 = {}, obj$1[locale] = { + attributes: ( obj = {}, obj[key] = value, obj ) + }, obj$1 )); + }; + + Object.defineProperties( I18nDictionary.prototype, prototypeAccessors$1 ); + + // + + var defaultConfig = { + locale: 'en', + delay: 0, + errorBagName: 'errors', + dictionary: null, + strict: true, + fieldsBagName: 'fields', + classes: false, + classNames: null, + events: 'input', + inject: true, + fastExit: true, + aria: true, + validity: false, + i18n: null, + i18nRootKey: 'validation' + }; + + var currentConfig = assign({}, defaultConfig); + var dependencies = { + dictionary: new Dictionary({ + en: { + messages: {}, + attributes: {}, + custom: {} + } + }) + }; + + var Config = function Config () {}; + + var staticAccessors = { default: { configurable: true },current: { configurable: true } }; + + staticAccessors.default.get = function () { + return defaultConfig; + }; + + staticAccessors.current.get = function () { + return currentConfig; + }; + + Config.dependency = function dependency (key) { + return dependencies[key]; + }; + + /** + * Merges the config with a new one. + */ + Config.merge = function merge (config) { + currentConfig = assign({}, currentConfig, config); + if (currentConfig.i18n) { + Config.register('dictionary', new I18nDictionary(currentConfig.i18n, currentConfig.i18nRootKey)); + } + }; + + /** + * Registers a dependency. + */ + Config.register = function register (key, value) { + dependencies[key] = value; + }; + + /** + * Resolves the working config from a Vue instance. + */ + Config.resolve = function resolve (context) { + var selfConfig = getPath('$options.$_veeValidate', context, {}); + + return assign({}, Config.current, selfConfig); + }; + + Object.defineProperties( Config, staticAccessors ); + + // + + var ErrorBag = function ErrorBag (errorBag, id) { + if ( errorBag === void 0 ) errorBag = null; + if ( id === void 0 ) id = null; + + this.vmId = id || null; + // make this bag a mirror of the provided one, sharing the same items reference. + if (errorBag && errorBag instanceof ErrorBag) { + this.items = errorBag.items; + } else { + this.items = []; + } + }; + + ErrorBag.prototype[typeof Symbol === 'function' ? Symbol.iterator : '@@iterator'] = function () { + var this$1 = this; + + var index = 0; + return { + next: function () { + return { value: this$1.items[index++], done: index > this$1.items.length }; + } + }; + }; + + /** + * Adds an error to the internal array. + */ + ErrorBag.prototype.add = function add (error) { + var ref; + + (ref = this.items).push.apply( + ref, this._normalizeError(error) + ); + }; + + /** + * Normalizes passed errors to an error array. + */ + ErrorBag.prototype._normalizeError = function _normalizeError (error) { + var this$1 = this; + + if (Array.isArray(error)) { + return error.map(function (e) { + e.scope = !isNullOrUndefined(e.scope) ? e.scope : null; + e.vmId = !isNullOrUndefined(e.vmId) ? e.vmId : (this$1.vmId || null); + + return e; + }); + } + + error.scope = !isNullOrUndefined(error.scope) ? error.scope : null; + error.vmId = !isNullOrUndefined(error.vmId) ? error.vmId : (this.vmId || null); + + return [error]; + }; + + /** + * Regenrates error messages if they have a generator function. + */ + ErrorBag.prototype.regenerate = function regenerate () { + this.items.forEach(function (i) { + i.msg = isCallable(i.regenerate) ? i.regenerate() : i.msg; + }); + }; + + /** + * Updates a field error with the new field scope. + */ + ErrorBag.prototype.update = function update (id, error) { + var item = find(this.items, function (i) { return i.id === id; }); + if (!item) { + return; + } + + var idx = this.items.indexOf(item); + this.items.splice(idx, 1); + item.scope = error.scope; + this.items.push(item); + }; + + /** + * Gets all error messages from the internal array. + */ + ErrorBag.prototype.all = function all (scope) { + var this$1 = this; + + var filterFn = function (item) { + var matchesScope = true; + var matchesVM = true; + if (!isNullOrUndefined(scope)) { + matchesScope = item.scope === scope; + } + + if (!isNullOrUndefined(this$1.vmId)) { + matchesVM = item.vmId === this$1.vmId; + } + + return matchesVM && matchesScope; + }; + + return this.items.filter(filterFn).map(function (e) { return e.msg; }); + }; + + /** + * Checks if there are any errors in the internal array. + */ + ErrorBag.prototype.any = function any (scope) { + var this$1 = this; + + var filterFn = function (item) { + var matchesScope = true; + if (!isNullOrUndefined(scope)) { + matchesScope = item.scope === scope; + } + + if (!isNullOrUndefined(this$1.vmId)) { + matchesScope = item.vmId === this$1.vmId; + } + + return matchesScope; + }; + + return !!this.items.filter(filterFn).length; + }; + + /** + * Removes all items from the internal array. + */ + ErrorBag.prototype.clear = function clear (scope) { + var this$1 = this; + + var matchesVM = isNullOrUndefined(this.vmId) ? function () { return true; } : function (i) { return i.vmId === this$1.vmId; }; + if (isNullOrUndefined(scope)) { + scope = null; + } + + for (var i = 0; i < this.items.length; ++i) { + if (matchesVM(this$1.items[i]) && this$1.items[i].scope === scope) { + this$1.items.splice(i, 1); + --i; + } + } + }; + + /** + * Collects errors into groups or for a specific field. + */ + ErrorBag.prototype.collect = function collect (field, scope, map) { + var this$1 = this; + if ( map === void 0 ) map = true; + + var isSingleField = !isNullOrUndefined(field) && !field.includes('*'); + var groupErrors = function (items) { + var errors = items.reduce(function (collection, error) { + if (!isNullOrUndefined(this$1.vmId) && error.vmId !== this$1.vmId) { + return collection; + } + + if (!collection[error.field]) { + collection[error.field] = []; + } + + collection[error.field].push(map ? error.msg : error); + + return collection; + }, {}); + + // reduce the collection to be a single array. + if (isSingleField) { + return values(errors)[0] || []; + } + + return errors; + }; + + if (isNullOrUndefined(field)) { + return groupErrors(this.items); + } + + var selector = isNullOrUndefined(scope) ? String(field) : (scope + "." + field); + var ref = this._makeCandidateFilters(selector); + var isPrimary = ref.isPrimary; + var isAlt = ref.isAlt; + + var collected = this.items.reduce(function (prev, curr) { + if (isPrimary(curr)) { + prev.primary.push(curr); + } + + if (isAlt(curr)) { + prev.alt.push(curr); + } + + return prev; + }, { primary: [], alt: [] }); + + collected = collected.primary.length ? collected.primary : collected.alt; + + return groupErrors(collected); + }; + + /** + * Gets the internal array length. + */ + ErrorBag.prototype.count = function count () { + var this$1 = this; + + if (this.vmId) { + return this.items.filter(function (e) { return e.vmId === this$1.vmId; }).length; + } + + return this.items.length; + }; + + /** + * Finds and fetches the first error message for the specified field id. + */ + ErrorBag.prototype.firstById = function firstById (id) { + var error = find(this.items, function (i) { return i.id === id; }); + + return error ? error.msg : undefined; + }; + + /** + * Gets the first error message for a specific field. + */ + ErrorBag.prototype.first = function first (field, scope) { + if ( scope === void 0 ) scope = null; + + var selector = isNullOrUndefined(scope) ? field : (scope + "." + field); + var match = this._match(selector); + + return match && match.msg; + }; + + /** + * Returns the first error rule for the specified field + */ + ErrorBag.prototype.firstRule = function firstRule (field, scope) { + var errors = this.collect(field, scope, false); + + return (errors.length && errors[0].rule) || undefined; + }; + + /** + * Checks if the internal array has at least one error for the specified field. + */ + ErrorBag.prototype.has = function has (field, scope) { + if ( scope === void 0 ) scope = null; + + return !!this.first(field, scope); + }; + + /** + * Gets the first error message for a specific field and a rule. + */ + ErrorBag.prototype.firstByRule = function firstByRule (name, rule, scope) { + if ( scope === void 0 ) scope = null; + + var error = this.collect(name, scope, false).filter(function (e) { return e.rule === rule; })[0]; + + return (error && error.msg) || undefined; + }; + + /** + * Gets the first error message for a specific field that not match the rule. + */ + ErrorBag.prototype.firstNot = function firstNot (name, rule, scope) { + if ( rule === void 0 ) rule = 'required'; + if ( scope === void 0 ) scope = null; + + var error = this.collect(name, scope, false).filter(function (e) { return e.rule !== rule; })[0]; + + return (error && error.msg) || undefined; + }; + + /** + * Removes errors by matching against the id or ids. + */ + ErrorBag.prototype.removeById = function removeById (id) { + var this$1 = this; + + var condition = function (item) { return item.id === id; }; + if (Array.isArray(id)) { + condition = function (item) { return id.indexOf(item.id) !== -1; }; + } + + for (var i = 0; i < this.items.length; ++i) { + if (condition(this$1.items[i])) { + this$1.items.splice(i, 1); + --i; + } + } + }; + + /** + * Removes all error messages associated with a specific field. + */ + ErrorBag.prototype.remove = function remove (field, scope, vmId) { + var this$1 = this; + + if (isNullOrUndefined(field)) { + return; + } + + var selector = isNullOrUndefined(scope) ? String(field) : (scope + "." + field); + var ref = this._makeCandidateFilters(selector); + var isPrimary = ref.isPrimary; + var shouldRemove = function (item) { + if (isNullOrUndefined(vmId)) { return isPrimary(item); } + + return isPrimary(item) && item.vmId === vmId; + }; + + for (var i = 0; i < this.items.length; ++i) { + if (shouldRemove(this$1.items[i])) { + this$1.items.splice(i, 1); + --i; + } + } + }; + + ErrorBag.prototype._makeCandidateFilters = function _makeCandidateFilters (selector) { + var this$1 = this; + + var matchesRule = function () { return true; }; + var matchesScope = function () { return true; }; + var matchesName = function () { return true; }; + var matchesVM = function () { return true; }; + + var ref = parseSelector(selector); + var id = ref.id; + var rule = ref.rule; + var scope = ref.scope; + var name = ref.name; + + if (rule) { + matchesRule = function (item) { return item.rule === rule; }; + } + + // match by id, can be combined with rule selection. + if (id) { + return { + isPrimary: function (item) { return matchesRule(item) && (function (item) { return id === item.id; }); }, + isAlt: function () { return false; } + }; + } + + if (isNullOrUndefined(scope)) { + // if no scope specified, make sure the found error has no scope. + matchesScope = function (item) { return isNullOrUndefined(item.scope); }; + } else { + matchesScope = function (item) { return item.scope === scope; }; + } + + if (!isNullOrUndefined(name) && name !== '*') { + matchesName = function (item) { return item.field === name; }; + } + + if (!isNullOrUndefined(this.vmId)) { + matchesVM = function (item) { return item.vmId === this$1.vmId; }; + } + + // matches the first candidate. + var isPrimary = function (item) { + return matchesVM(item) && matchesName(item) && matchesRule(item) && matchesScope(item); + }; + + // matches a second candidate, which is a field with a name containing the '.' character. + var isAlt = function (item) { + return matchesVM(item) && matchesRule(item) && item.field === (scope + "." + name); + }; + + return { + isPrimary: isPrimary, + isAlt: isAlt + }; + }; + + ErrorBag.prototype._match = function _match (selector) { + if (isNullOrUndefined(selector)) { + return undefined; + } + + var ref = this._makeCandidateFilters(selector); + var isPrimary = ref.isPrimary; + var isAlt = ref.isAlt; + + return this.items.reduce(function (prev, item, idx, arr) { + var isLast = idx === arr.length - 1; + if (prev.primary) { + return isLast ? prev.primary : prev; + } + + if (isPrimary(item)) { + prev.primary = item; + } + + if (isAlt(item)) { + prev.alt = item; + } + + // keep going. + if (!isLast) { + return prev; + } + + return prev.primary || prev.alt; + }, {}); + }; + + /** + * Generates the options required to construct a field. + */ + var Resolver = function Resolver () {}; + + Resolver.generate = function generate (el, binding, vnode) { + var model = Resolver.resolveModel(binding, vnode); + var options = Config.resolve(vnode.context); + + return { + name: Resolver.resolveName(el, vnode), + el: el, + listen: !binding.modifiers.disable, + bails: binding.modifiers.bails ? true : (binding.modifiers.continues === true ? false : undefined), + scope: Resolver.resolveScope(el, binding, vnode), + vm: Resolver.makeVM(vnode.context), + expression: binding.value, + component: vnode.componentInstance, + classes: options.classes, + classNames: options.classNames, + getter: Resolver.resolveGetter(el, vnode, model), + events: Resolver.resolveEvents(el, vnode) || options.events, + model: model, + delay: Resolver.resolveDelay(el, vnode, options), + rules: Resolver.resolveRules(el, binding, vnode), + immediate: !!binding.modifiers.initial || !!binding.modifiers.immediate, + validity: options.validity, + aria: options.aria, + initialValue: Resolver.resolveInitialValue(vnode) + }; + }; + + Resolver.getCtorConfig = function getCtorConfig (vnode) { + if (!vnode.componentInstance) { return null; } + + var config = getPath('componentInstance.$options.$_veeValidate', vnode); + + return config; + }; + + /** + * Resolves the rules defined on an element. + */ + Resolver.resolveRules = function resolveRules (el, binding, vnode) { + var rules = ''; + if (!binding.value && (!binding || !binding.expression)) { + rules = getDataAttribute(el, 'rules'); + } + + if (binding.value && includes(['string', 'object'], typeof binding.value.rules)) { + rules = binding.value.rules; + } else if (binding.value) { + rules = binding.value; + } + + if (vnode.componentInstance) { + return rules; + } + + return fillRulesFromElement(el, rules); + }; + + /** + * @param {*} vnode + */ + Resolver.resolveInitialValue = function resolveInitialValue (vnode) { + var model = vnode.data.model || find(vnode.data.directives, function (d) { return d.name === 'model'; }); + + return model && model.value; + }; + + /** + * Creates a non-circular partial VM instance from a Vue instance. + * @param {*} vm + */ + Resolver.makeVM = function makeVM (vm) { + return { + get $el () { + return vm.$el; + }, + get $refs () { + return vm.$refs; + }, + $watch: vm.$watch ? vm.$watch.bind(vm) : function () {}, + $validator: vm.$validator ? { + errors: vm.$validator.errors, + validate: vm.$validator.validate.bind(vm.$validator), + update: vm.$validator.update.bind(vm.$validator) + } : null + }; + }; + + /** + * Resolves the delay value. + * @param {*} el + * @param {*} vnode + * @param {Object} options + */ + Resolver.resolveDelay = function resolveDelay (el, vnode, options) { + var delay = getDataAttribute(el, 'delay'); + var globalDelay = (options && 'delay' in options) ? options.delay : 0; + + if (!delay && vnode.componentInstance && vnode.componentInstance.$attrs) { + delay = vnode.componentInstance.$attrs['data-vv-delay']; + } + + if (!isObject(globalDelay)) { + return deepParseInt(delay || globalDelay); + } + + if (!isNullOrUndefined(delay)) { + globalDelay.input = delay; + } + + return deepParseInt(globalDelay); + }; + + /** + * Resolves the events to validate in response to. + * @param {*} el + * @param {*} vnode + */ + Resolver.resolveEvents = function resolveEvents (el, vnode) { + // resolve it from the root element. + var events = getDataAttribute(el, 'validate-on'); + + // resolve from data-vv-validate-on if its a vue component. + if (!events && vnode.componentInstance && vnode.componentInstance.$attrs) { + events = vnode.componentInstance.$attrs['data-vv-validate-on']; + } + + // resolve it from $_veeValidate options. + if (!events && vnode.componentInstance) { + var config = Resolver.getCtorConfig(vnode); + events = config && config.events; + } + + if (!events && Config.current.events) { + events = Config.current.events; + } + + // resolve the model event if its configured for custom components. + if (events && vnode.componentInstance && includes(events, 'input')) { + var ref = vnode.componentInstance.$options.model || { event: 'input' }; + var event = ref.event; + // if the prop was configured but not the model. + if (!event) { + return events; + } + + events = events.replace('input', event); + } + + return events; + }; + + /** + * Resolves the scope for the field. + * @param {*} el + * @param {*} binding + */ + Resolver.resolveScope = function resolveScope (el, binding, vnode) { + if ( vnode === void 0 ) vnode = {}; + + var scope = null; + if (vnode.componentInstance && isNullOrUndefined(scope)) { + scope = vnode.componentInstance.$attrs && vnode.componentInstance.$attrs['data-vv-scope']; + } + + return !isNullOrUndefined(scope) ? scope : getScope(el); + }; + + /** + * Checks if the node directives contains a v-model or a specified arg. + * Args take priority over models. + * + * @return {Object} + */ + Resolver.resolveModel = function resolveModel (binding, vnode) { + if (binding.arg) { + return { expression: binding.arg }; + } + + var model = vnode.data.model || find(vnode.data.directives, function (d) { return d.name === 'model'; }); + if (!model) { + return null; + } + + // https://github.com/vuejs/vue/blob/dev/src/core/util/lang.js#L26 + var watchable = !/[^\w.$]/.test(model.expression) && hasPath(model.expression, vnode.context); + var lazy = !!(model.modifiers && model.modifiers.lazy); + + if (!watchable) { + return { expression: null, lazy: lazy }; + } + + return { expression: model.expression, lazy: lazy }; + }; + + /** + * Resolves the field name to trigger validations. + * @return {String} The field name. + */ + Resolver.resolveName = function resolveName (el, vnode) { + var name = getDataAttribute(el, 'name'); + + if (!name && !vnode.componentInstance) { + return el.name; + } + + if (!name && vnode.componentInstance && vnode.componentInstance.$attrs) { + name = vnode.componentInstance.$attrs['data-vv-name'] || vnode.componentInstance.$attrs['name']; + } + + if (!name && vnode.componentInstance) { + var config = Resolver.getCtorConfig(vnode); + if (config && isCallable(config.name)) { + var boundGetter = config.name.bind(vnode.componentInstance); + + return boundGetter(); + } + + return vnode.componentInstance.name; + } + + return name; + }; + + /** + * Returns a value getter input type. + */ + Resolver.resolveGetter = function resolveGetter (el, vnode, model) { + if (model && model.expression) { + return function () { + return getPath(model.expression, vnode.context); + }; + } + + if (vnode.componentInstance) { + var path = getDataAttribute(el, 'value-path') || (vnode.componentInstance.$attrs && vnode.componentInstance.$attrs['data-vv-value-path']); + if (path) { + return function () { + return getPath(path, vnode.componentInstance); + }; + } + + var config = Resolver.getCtorConfig(vnode); + if (config && isCallable(config.value)) { + var boundGetter = config.value.bind(vnode.componentInstance); + + return function () { + return boundGetter(); + }; + } + + var ref = vnode.componentInstance.$options.model || { prop: 'value' }; + var prop = ref.prop; + + return function () { + return vnode.componentInstance[prop]; + }; + } + + switch (el.type) { + case 'checkbox': return function () { + var els = document.querySelectorAll(("input[name=\"" + (el.name) + "\"]")); + + els = toArray(els).filter(function (el) { return el.checked; }); + if (!els.length) { return undefined; } + + return els.map(function (checkbox) { return checkbox.value; }); + }; + case 'radio': return function () { + var els = document.querySelectorAll(("input[name=\"" + (el.name) + "\"]")); + var elm = find(els, function (el) { return el.checked; }); + + return elm && elm.value; + }; + case 'file': return function (context) { + return toArray(el.files); + }; + case 'select-multiple': return function () { + return toArray(el.options).filter(function (opt) { return opt.selected; }).map(function (opt) { return opt.value; }); + }; + default: return function () { + return el && el.value; + }; + } + }; + + // + + var RULES = {}; + var STRICT_MODE = true; + + var Validator = function Validator (validations, options) { + if ( options === void 0 ) options = { fastExit: true }; + + this.strict = STRICT_MODE; + this.errors = new ErrorBag(); + this.fields = new FieldBag(); + this._createFields(validations); + this.paused = false; + this.fastExit = !isNullOrUndefined(options && options.fastExit) ? options.fastExit : true; + }; + + var prototypeAccessors$2 = { rules: { configurable: true },flags: { configurable: true },dictionary: { configurable: true },_vm: { configurable: true },locale: { configurable: true } }; + var staticAccessors$1 = { rules: { configurable: true },dictionary: { configurable: true },locale: { configurable: true } }; + + staticAccessors$1.rules.get = function () { + return RULES; + }; + + prototypeAccessors$2.rules.get = function () { + return RULES; + }; + + prototypeAccessors$2.flags.get = function () { + return this.fields.items.reduce(function (acc, field) { + var obj; + + if (field.scope) { + acc[("$" + (field.scope))] = ( obj = {}, obj[field.name] = field.flags, obj ); + + return acc; + } + + acc[field.name] = field.flags; + + return acc; + }, {}); + }; + + /** + * Getter for the dictionary. + */ + prototypeAccessors$2.dictionary.get = function () { + return Config.dependency('dictionary'); + }; + + staticAccessors$1.dictionary.get = function () { + return Config.dependency('dictionary'); + }; + + prototypeAccessors$2._vm.get = function () { + return Config.dependency('vm'); + }; + + /** + * Getter for the current locale. + */ + prototypeAccessors$2.locale.get = function () { + return Validator.locale; + }; + + /** + * Setter for the validator locale. + */ + prototypeAccessors$2.locale.set = function (value) { + Validator.locale = value; + }; + + staticAccessors$1.locale.get = function () { + return this.dictionary.locale; + }; + + /** + * Setter for the validator locale. + */ + staticAccessors$1.locale.set = function (value) { + var hasChanged = value !== Validator.dictionary.locale; + Validator.dictionary.locale = value; + if (hasChanged && Config.dependency('vm')) { + Config.dependency('vm').$emit('localeChanged'); + } + }; + + /** + * Static constructor. + */ + Validator.create = function create (validations, options) { + return new Validator(validations, options); + }; + + /** + * Adds a custom validator to the list of validation rules. + */ + Validator.extend = function extend (name, validator, options) { + if ( options === void 0 ) options = {}; + + Validator._guardExtend(name, validator); + Validator._merge(name, { + validator: validator, + paramNames: options && options.paramNames, + options: assign({}, { hasTarget: false, immediate: true }, options || {}) + }); + }; + + /** + * Removes a rule from the list of validators. + */ + Validator.remove = function remove (name) { + delete RULES[name]; + }; + + /** + * Checks if the given rule name is a rule that targets other fields. + */ + Validator.isTargetRule = function isTargetRule (name) { + return !!RULES[name] && RULES[name].options.hasTarget; + }; + + /** + * Sets the operating mode for all newly created validators. + * strictMode = true: Values without a rule are invalid and cause failure. + * strictMode = false: Values without a rule are valid and are skipped. + */ + Validator.setStrictMode = function setStrictMode (strictMode) { + if ( strictMode === void 0 ) strictMode = true; + + STRICT_MODE = strictMode; + }; + + /** + * Adds and sets the current locale for the validator. + */ + Validator.prototype.localize = function localize (lang, dictionary) { + Validator.localize(lang, dictionary); + }; + + /** + * Adds and sets the current locale for the validator. + */ + Validator.localize = function localize (lang, dictionary) { + var obj; + + if (isObject(lang)) { + Validator.dictionary.merge(lang); + return; + } + + // merge the dictionary. + if (dictionary) { + var locale = lang || dictionary.name; + dictionary = assign({}, dictionary); + Validator.dictionary.merge(( obj = {}, obj[locale] = dictionary, obj )); + } + + if (lang) { + // set the locale. + Validator.locale = lang; + } + }; + + /** + * Registers a field to be validated. + */ + Validator.prototype.attach = function attach (fieldOpts) { + // fixes initial value detection with v-model and select elements. + var value = fieldOpts.initialValue; + var field = new Field(fieldOpts); + this.fields.push(field); + + // validate the field initially + if (field.immediate) { + this.validate(("#" + (field.id)), value || field.value, { vmId: fieldOpts.vmId }); + } else { + this._validate(field, value || field.value, { initial: true }).then(function (result) { + field.flags.valid = result.valid; + field.flags.invalid = !result.valid; + }); + } + + return field; + }; + + /** + * Sets the flags on a field. + */ + Validator.prototype.flag = function flag (name, flags, uid) { + if ( uid === void 0 ) uid = null; + + var field = this._resolveField(name, undefined, uid); + if (!field || !flags) { + return; + } + + field.setFlags(flags); + }; + + /** + * Removes a field from the validator. + */ + Validator.prototype.detach = function detach (name, scope, uid) { + var field = isCallable(name.destroy) ? name : this._resolveField(name, scope, uid); + if (!field) { return; } + + field.destroy(); + this.errors.remove(field.name, field.scope, field.vmId); + this.fields.remove(field); + }; + + /** + * Adds a custom validator to the list of validation rules. + */ + Validator.prototype.extend = function extend (name, validator, options) { + if ( options === void 0 ) options = {}; + + Validator.extend(name, validator, options); + }; + + Validator.prototype.reset = function reset (matcher) { + var this$1 = this; + + // two ticks + return this._vm.$nextTick().then(function () { + return this$1._vm.$nextTick(); + }).then(function () { + this$1.fields.filter(matcher).forEach(function (field) { + field.reset(); // reset field flags. + this$1.errors.remove(field.name, field.scope); + }); + }); + }; + + /** + * Updates a field, updating both errors and flags. + */ + Validator.prototype.update = function update (id, ref) { + var scope = ref.scope; + + var field = this._resolveField(("#" + id)); + if (!field) { return; } + + // remove old scope. + this.errors.update(id, { scope: scope }); + }; + + /** + * Removes a rule from the list of validators. + */ + Validator.prototype.remove = function remove (name) { + Validator.remove(name); + }; + + /** + * Validates a value against a registered field validations. + */ + Validator.prototype.validate = function validate (fieldDescriptor, value, ref) { + var this$1 = this; + if ( ref === void 0 ) ref = {}; + var silent = ref.silent; + var vmId = ref.vmId; + + if (this.paused) { return Promise.resolve(true); } + + // overload to validate all. + if (isNullOrUndefined(fieldDescriptor)) { + return this.validateScopes({ silent: silent, vmId: vmId }); + } + + // overload to validate scope-less fields. + if (fieldDescriptor === '*') { + return this.validateAll(undefined, { silent: silent, vmId: vmId }); + } + + // if scope validation was requested. + if (/^(.+)\.\*$/.test(fieldDescriptor)) { + var matched = fieldDescriptor.match(/^(.+)\.\*$/)[1]; + return this.validateAll(matched); + } + + var field = this._resolveField(fieldDescriptor); + if (!field) { + return this._handleFieldNotFound(name); + } + + if (!silent) { field.flags.pending = true; } + if (value === undefined) { + value = field.value; + } + + return this._validate(field, value).then(function (result) { + if (!silent) { + this$1._handleValidationResults([result], vmId); + } + + return result.valid; + }); + }; + + /** + * Pauses the validator. + */ + Validator.prototype.pause = function pause () { + this.paused = true; + + return this; + }; + + /** + * Resumes the validator. + */ + Validator.prototype.resume = function resume () { + this.paused = false; + + return this; + }; + + /** + * Validates each value against the corresponding field validations. + */ + Validator.prototype.validateAll = function validateAll (values$$1, ref) { + var this$1 = this; + if ( ref === void 0 ) ref = {}; + var silent = ref.silent; + var vmId = ref.vmId; + + if (this.paused) { return Promise.resolve(true); } + + var matcher = null; + var providedValues = false; + + if (typeof values$$1 === 'string') { + matcher = { scope: values$$1, vmId: vmId }; + } else if (isObject(values$$1)) { + matcher = Object.keys(values$$1).map(function (key) { + return { name: key, vmId: vmId, scope: null }; + }); + providedValues = true; + } else if (Array.isArray(values$$1)) { + matcher = values$$1.map(function (key) { + return { name: key, vmId: vmId }; + }); + } else { + matcher = { scope: null, vmId: vmId }; + } + + return Promise.all( + this.fields.filter(matcher).map(function (field) { return this$1._validate(field, providedValues ? values$$1[field.name] : field.value); }) + ).then(function (results) { + if (!silent) { + this$1._handleValidationResults(results, vmId); + } + + return results.every(function (t) { return t.valid; }); + }); + }; + + /** + * Validates all scopes. + */ + Validator.prototype.validateScopes = function validateScopes (ref) { + var this$1 = this; + if ( ref === void 0 ) ref = {}; + var silent = ref.silent; + var vmId = ref.vmId; + + if (this.paused) { return Promise.resolve(true); } + + return Promise.all( + this.fields.filter({ vmId: vmId }).map(function (field) { return this$1._validate(field, field.value); }) + ).then(function (results) { + if (!silent) { + this$1._handleValidationResults(results, vmId); + } + + return results.every(function (t) { return t.valid; }); + }); + }; + + /** + * Validates a value against the rules. + */ + Validator.prototype.verify = function verify (value, rules) { + var field = { name: '{field}', rules: normalizeRules(rules) }; + field.isRequired = field.rules.required; + + return this._validate(field, value).then(function (result) { + return { valid: result.valid, errors: result.errors.map(function (e) { return e.msg; }) }; + }); + }; + + /** + * Perform cleanup. + */ + Validator.prototype.destroy = function destroy () { + this._vm.$off('localeChanged'); + }; + + /** + * Creates the fields to be validated. + */ + Validator.prototype._createFields = function _createFields (validations) { + var this$1 = this; + + if (!validations) { return; } + + Object.keys(validations).forEach(function (field) { + var options = assign({}, { name: field, rules: validations[field] }); + this$1.attach(options); + }); + }; + + /** + * Date rules need the existence of a format, so date_format must be supplied. + */ + Validator.prototype._getDateFormat = function _getDateFormat (validations) { + var format = null; + if (validations.date_format && Array.isArray(validations.date_format)) { + format = validations.date_format[0]; + } + + return format || this.dictionary.getDateFormat(this.locale); + }; + + /** + * Formats an error message for field and a rule. + */ + Validator.prototype._formatErrorMessage = function _formatErrorMessage (field, rule, data, targetName) { + if ( data === void 0 ) data = {}; + if ( targetName === void 0 ) targetName = null; + + var name = this._getFieldDisplayName(field); + var params = this._getLocalizedParams(rule, targetName); + + return this.dictionary.getFieldMessage(this.locale, field.name, rule.name, [name, params, data]); + }; + + /** + * We need to convert any object param to an array format since the locales do not handle params as objects yet. + */ + Validator.prototype._convertParamObjectToArray = function _convertParamObjectToArray (obj, ruleName) { + if (Array.isArray(obj)) { + return obj; + } + + var paramNames = RULES[ruleName] && RULES[ruleName].paramNames; + if (!paramNames || !isObject(obj)) { + return obj; + } + + return paramNames.reduce(function (prev, paramName) { + if (paramName in obj) { + prev.push(obj[paramName]); + } + + return prev; + }, []); + }; + + /** + * Translates the parameters passed to the rule (mainly for target fields). + */ + Validator.prototype._getLocalizedParams = function _getLocalizedParams (rule, targetName) { + if ( targetName === void 0 ) targetName = null; + + var params = this._convertParamObjectToArray(rule.params, rule.name); + if (rule.options.hasTarget && params && params[0]) { + var localizedName = targetName || this.dictionary.getAttribute(this.locale, params[0], params[0]); + return [localizedName].concat(params.slice(1)); + } + + return params; + }; + + /** + * Resolves an appropriate display name, first checking 'data-as' or the registered 'prettyName' + */ + Validator.prototype._getFieldDisplayName = function _getFieldDisplayName (field) { + return field.alias || this.dictionary.getAttribute(this.locale, field.name, field.name); + }; + + /** + * Converts an array of params to an object with named properties. + * Only works if the rule is configured with a paramNames array. + * Returns the same params if it cannot convert it. + */ + Validator.prototype._convertParamArrayToObj = function _convertParamArrayToObj (params, ruleName) { + var paramNames = RULES[ruleName] && RULES[ruleName].paramNames; + if (!paramNames) { + return params; + } + + if (isObject(params)) { + // check if the object is either a config object or a single parameter that is an object. + var hasKeys = paramNames.some(function (name) { return Object.keys(params).indexOf(name) !== -1; }); + // if it has some of the keys, return it as is. + if (hasKeys) { + return params; + } + // otherwise wrap the object in an array. + params = [params]; + } + + // Reduce the paramsNames to a param object. + return params.reduce(function (prev, value, idx) { + prev[paramNames[idx]] = value; + + return prev; + }, {}); + }; + + /** + * Tests a single input value against a rule. + */ + Validator.prototype._test = function _test (field, value, rule) { + var this$1 = this; + + var validator = RULES[rule.name] ? RULES[rule.name].validate : null; + var params = Array.isArray(rule.params) ? toArray(rule.params) : rule.params; + if (!params) { + params = []; + } + + var targetName = null; + if (!validator || typeof validator !== 'function') { + return Promise.reject(createError(("No such validator '" + (rule.name) + "' exists."))); + } + + // has field dependencies. + if (rule.options.hasTarget) { + var target = find(field.dependencies, function (d) { return d.name === rule.name; }); + if (target) { + targetName = target.field.alias; + params = [target.field.value].concat(params.slice(1)); + } + } else if (rule.name === 'required' && field.rejectsFalse) { + // invalidate false if no args were specified and the field rejects false by default. + params = params.length ? params : [true]; + } + + if (rule.options.isDate) { + var dateFormat = this._getDateFormat(field.rules); + if (rule.name !== 'date_format') { + params.push(dateFormat); + } + } + + var result = validator(value, this._convertParamArrayToObj(params, rule.name)); + + // If it is a promise. + if (isCallable(result.then)) { + return result.then(function (values$$1) { + var allValid = true; + var data = {}; + if (Array.isArray(values$$1)) { + allValid = values$$1.every(function (t) { return (isObject(t) ? t.valid : t); }); + } else { // Is a single object/boolean. + allValid = isObject(values$$1) ? values$$1.valid : values$$1; + data = values$$1.data; + } + + return { + valid: allValid, + errors: allValid ? [] : [this$1._createFieldError(field, rule, data, targetName)] + }; + }); + } + + if (!isObject(result)) { + result = { valid: result, data: {} }; + } + + return { + valid: result.valid, + errors: result.valid ? [] : [this._createFieldError(field, rule, result.data, targetName)] + }; + }; + + /** + * Merges a validator object into the RULES and Messages. + */ + Validator._merge = function _merge (name, ref) { + var validator = ref.validator; + var options = ref.options; + var paramNames = ref.paramNames; + + var validate = isCallable(validator) ? validator : validator.validate; + if (validator.getMessage) { + Validator.dictionary.setMessage(Validator.locale, name, validator.getMessage); + } + + RULES[name] = { + validate: validate, + options: options, + paramNames: paramNames + }; + }; + + /** + * Guards from extension violations. + */ + Validator._guardExtend = function _guardExtend (name, validator) { + if (isCallable(validator)) { + return; + } + + if (!isCallable(validator.validate)) { + throw createError( + ("Extension Error: The validator '" + name + "' must be a function or have a 'validate' method.") + ); + } + }; + + /** + * Creates a Field Error Object. + */ + Validator.prototype._createFieldError = function _createFieldError (field, rule, data, targetName) { + var this$1 = this; + + return { + id: field.id, + vmId: field.vmId, + field: field.name, + msg: this._formatErrorMessage(field, rule, data, targetName), + rule: rule.name, + scope: field.scope, + regenerate: function () { + return this$1._formatErrorMessage(field, rule, data, targetName); + } + }; + }; + + /** + * Tries different strategies to find a field. + */ + Validator.prototype._resolveField = function _resolveField (name, scope, uid) { + if (name[0] === '#') { + return this.fields.find({ id: name.slice(1) }); + } + + if (!isNullOrUndefined(scope)) { + return this.fields.find({ name: name, scope: scope, vmId: uid }); + } + + if (includes(name, '.')) { + var ref = name.split('.'); + var fieldScope = ref[0]; + var fieldName = ref.slice(1); + var field = this.fields.find({ name: fieldName.join('.'), scope: fieldScope, vmId: uid }); + if (field) { + return field; + } + } + + return this.fields.find({ name: name, scope: null, vmId: uid }); + }; + + /** + * Handles when a field is not found depending on the strict flag. + */ + Validator.prototype._handleFieldNotFound = function _handleFieldNotFound (name, scope) { + if (!this.strict) { return Promise.resolve(true); } + + var fullName = isNullOrUndefined(scope) ? name : ("" + (!isNullOrUndefined(scope) ? scope + '.' : '') + name); + + return Promise.reject(createError( + ("Validating a non-existent field: \"" + fullName + "\". Use \"attach()\" first.") + )); + }; + + /** + * Handles validation results. + */ + Validator.prototype._handleValidationResults = function _handleValidationResults (results, vmId) { + var this$1 = this; + + var matchers = results.map(function (result) { return ({ id: result.id }); }); + this.errors.removeById(matchers.map(function (m) { return m.id; })); + // remove by name and scope to remove any custom errors added. + results.forEach(function (result) { + this$1.errors.remove(result.field, result.scope, vmId); + }); + var allErrors = results.reduce(function (prev, curr) { + prev.push.apply(prev, curr.errors); + + return prev; + }, []); + + this.errors.add(allErrors); + + // handle flags. + this.fields.filter(matchers).forEach(function (field) { + var result = find(results, function (r) { return r.id === field.id; }); + field.setFlags({ + pending: false, + valid: result.valid, + validated: true + }); + }); + }; + + Validator.prototype._shouldSkip = function _shouldSkip (field, value) { + // field is configured to run through the pipeline regardless + if (field.bails === false) { + return false; + } + + // disabled fields are skipped + if (field.isDisabled) { + return true; + } + + // skip if the field is not required and has an empty value. + return !field.isRequired && (isNullOrUndefined(value) || value === ''); + }; + + Validator.prototype._shouldBail = function _shouldBail (field, value) { + // if the field was configured explicitly. + if (field.bails !== undefined) { + return field.bails; + } + + return this.fastExit; + }; + + /** + * Starts the validation process. + */ + Validator.prototype._validate = function _validate (field, value, ref) { + var this$1 = this; + if ( ref === void 0 ) ref = {}; + var initial = ref.initial; + + if (this._shouldSkip(field, value)) { + return Promise.resolve({ valid: true, id: field.id, field: field.name, scope: field.scope, errors: [] }); + } + + var promises = []; + var errors = []; + var isExitEarly = false; + // use of '.some()' is to break iteration in middle by returning true + Object.keys(field.rules).filter(function (rule) { + if (!initial || !RULES[rule]) { return true; } + + return RULES[rule].options.immediate; + }).some(function (rule) { + var ruleOptions = RULES[rule] ? RULES[rule].options : {}; + var result = this$1._test(field, value, { name: rule, params: field.rules[rule], options: ruleOptions }); + if (isCallable(result.then)) { + promises.push(result); + } else if (!result.valid && this$1._shouldBail(field, value)) { + errors.push.apply(errors, result.errors); + isExitEarly = true; + } else { + // promisify the result. + promises.push(new Promise(function (resolve) { return resolve(result); })); + } + + return isExitEarly; + }); + + if (isExitEarly) { + return Promise.resolve({ valid: false, errors: errors, id: field.id, field: field.name, scope: field.scope }); + } + + return Promise.all(promises).then(function (results) { + return results.reduce(function (prev, v) { + var ref; + + if (!v.valid) { + (ref = prev.errors).push.apply(ref, v.errors); + } + + prev.valid = prev.valid && v.valid; + + return prev; + }, { valid: true, errors: errors, id: field.id, field: field.name, scope: field.scope }); + }); + }; + + Object.defineProperties( Validator.prototype, prototypeAccessors$2 ); + Object.defineProperties( Validator, staticAccessors$1 ); + + // + + var DEFAULT_OPTIONS = { + targetOf: null, + immediate: false, + scope: null, + listen: true, + name: null, + rules: {}, + vm: null, + classes: false, + validity: true, + aria: true, + events: 'input|blur', + delay: 0, + classNames: { + touched: 'touched', // the control has been blurred + untouched: 'untouched', // the control hasn't been blurred + valid: 'valid', // model is valid + invalid: 'invalid', // model is invalid + pristine: 'pristine', // control has not been interacted with + dirty: 'dirty' // control has been interacted with + } + }; + + var Field = function Field (options) { + if ( options === void 0 ) options = {}; + + this.id = uniqId(); + this.el = options.el; + this.updated = false; + this.dependencies = []; + this.vmId = options.vmId; + this.watchers = []; + this.events = []; + this.delay = 0; + this.rules = {}; + this._cacheId(options); + this.classNames = assign({}, DEFAULT_OPTIONS.classNames); + options = assign({}, DEFAULT_OPTIONS, options); + this._delay = !isNullOrUndefined(options.delay) ? options.delay : 0; // cache initial delay + this.validity = options.validity; + this.aria = options.aria; + this.flags = createFlags(); + this.vm = options.vm; + this.componentInstance = options.component; + this.ctorConfig = this.componentInstance ? getPath('$options.$_veeValidate', this.componentInstance) : undefined; + this.update(options); + // set initial value. + this.initialValue = this.value; + this.updated = false; + }; + + var prototypeAccessors$3 = { validator: { configurable: true },isRequired: { configurable: true },isDisabled: { configurable: true },alias: { configurable: true },value: { configurable: true },bails: { configurable: true },rejectsFalse: { configurable: true } }; + + prototypeAccessors$3.validator.get = function () { + if (!this.vm || !this.vm.$validator) { + return { validate: function () {} }; + } + + return this.vm.$validator; + }; + + prototypeAccessors$3.isRequired.get = function () { + return !!this.rules.required; + }; + + prototypeAccessors$3.isDisabled.get = function () { + return !!(this.componentInstance && this.componentInstance.disabled) || !!(this.el && this.el.disabled); + }; + + /** + * Gets the display name (user-friendly name). + */ + prototypeAccessors$3.alias.get = function () { + if (this._alias) { + return this._alias; + } + + var alias = null; + if (this.el) { + alias = getDataAttribute(this.el, 'as'); + } + + if (!alias && this.componentInstance) { + return this.componentInstance.$attrs && this.componentInstance.$attrs['data-vv-as']; + } + + return alias; + }; + + /** + * Gets the input value. + */ + + prototypeAccessors$3.value.get = function () { + if (!isCallable(this.getter)) { + return undefined; + } + + return this.getter(); + }; + + prototypeAccessors$3.bails.get = function () { + return this._bails; + }; + + /** + * If the field rejects false as a valid value for the required rule. + */ + + prototypeAccessors$3.rejectsFalse.get = function () { + if (this.componentInstance && this.ctorConfig) { + return !!this.ctorConfig.rejectsFalse; + } + + if (!this.el) { + return false; + } + + return this.el.type === 'checkbox'; + }; + + /** + * Determines if the instance matches the options provided. + */ + Field.prototype.matches = function matches (options) { + var this$1 = this; + + if (!options) { + return true; + } + + if (options.id) { + return this.id === options.id; + } + + var matchesComponentId = isNullOrUndefined(options.vmId) ? function () { return true; } : function (id) { return id === this$1.vmId; }; + if (!matchesComponentId(options.vmId)) { + return false; + } + + if (options.name === undefined && options.scope === undefined) { + return true; + } + + if (options.scope === undefined) { + return this.name === options.name; + } + + if (options.name === undefined) { + return this.scope === options.scope; + } + + return options.name === this.name && options.scope === this.scope; + }; + + /** + * Caches the field id. + */ + Field.prototype._cacheId = function _cacheId (options) { + if (this.el && !options.targetOf) { + this.el._veeValidateId = this.id; + } + }; + + /** + * Updates the field with changed data. + */ + Field.prototype.update = function update (options) { + this.targetOf = options.targetOf || null; + this.immediate = options.immediate || this.immediate || false; + + // update errors scope if the field scope was changed. + if (!isNullOrUndefined(options.scope) && options.scope !== this.scope && isCallable(this.validator.update)) { + this.validator.update(this.id, { scope: options.scope }); + } + this.scope = !isNullOrUndefined(options.scope) ? options.scope + : !isNullOrUndefined(this.scope) ? this.scope : null; + this.name = (!isNullOrUndefined(options.name) ? String(options.name) : options.name) || this.name || null; + this.rules = options.rules !== undefined ? normalizeRules(options.rules) : this.rules; + this._bails = options.bails !== undefined ? options.bails : this._bails; + this.model = options.model || this.model; + this.listen = options.listen !== undefined ? options.listen : this.listen; + this.classes = (options.classes || this.classes || false) && !this.componentInstance; + this.classNames = isObject(options.classNames) ? merge$1(this.classNames, options.classNames) : this.classNames; + this.getter = isCallable(options.getter) ? options.getter : this.getter; + this._alias = options.alias || this._alias; + this.events = (options.events) ? makeEventsArray(options.events) : this.events; + this.delay = makeDelayObject(this.events, options.delay || this.delay, this._delay); + this.updateDependencies(); + this.addActionListeners(); + + if (!this.name && !this.targetOf) { + warn('A field is missing a "name" or "data-vv-name" attribute'); + } + + // update required flag flags + if (options.rules !== undefined) { + this.flags.required = this.isRequired; + } + + // validate if it was validated before and field was updated and there was a rules mutation. + if (this.flags.validated && options.rules !== undefined && this.updated) { + this.validator.validate(("#" + (this.id))); + } + + this.updated = true; + this.addValueListeners(); + + // no need to continue. + if (!this.el) { + return; + } + this.updateClasses(); + this.updateAriaAttrs(); + }; + + /** + * Resets field flags and errors. + */ + Field.prototype.reset = function reset () { + var this$1 = this; + + if (this._cancellationToken) { + this._cancellationToken.cancelled = true; + delete this._cancellationToken; + } + + var defaults = createFlags(); + Object.keys(this.flags).filter(function (flag) { return flag !== 'required'; }).forEach(function (flag) { + this$1.flags[flag] = defaults[flag]; + }); + + this.addActionListeners(); + this.updateClasses(); + this.updateAriaAttrs(); + this.updateCustomValidity(); + }; + + /** + * Sets the flags and their negated counterparts, and updates the classes and re-adds action listeners. + */ + Field.prototype.setFlags = function setFlags (flags) { + var this$1 = this; + + var negated = { + pristine: 'dirty', + dirty: 'pristine', + valid: 'invalid', + invalid: 'valid', + touched: 'untouched', + untouched: 'touched' + }; + + Object.keys(flags).forEach(function (flag) { + this$1.flags[flag] = flags[flag]; + // if it has a negation and was not specified, set it as well. + if (negated[flag] && flags[negated[flag]] === undefined) { + this$1.flags[negated[flag]] = !flags[flag]; + } + }); + + if ( + flags.untouched !== undefined || + flags.touched !== undefined || + flags.dirty !== undefined || + flags.pristine !== undefined + ) { + this.addActionListeners(); + } + this.updateClasses(); + this.updateAriaAttrs(); + this.updateCustomValidity(); + }; + + /** + * Determines if the field requires references to target fields. + */ + Field.prototype.updateDependencies = function updateDependencies () { + var this$1 = this; + + // reset dependencies. + this.dependencies.forEach(function (d) { return d.field.destroy(); }); + this.dependencies = []; + + // we get the selectors for each field. + var fields = Object.keys(this.rules).reduce(function (prev, r) { + if (Validator.isTargetRule(r)) { + prev.push({ selector: this$1.rules[r][0], name: r }); + } + + return prev; + }, []); + + if (!fields.length || !this.vm || !this.vm.$el) { return; } + + // must be contained within the same component, so we use the vm root element constrain our dom search. + fields.forEach(function (ref$1) { + var selector = ref$1.selector; + var name = ref$1.name; + + var ref = this$1.vm.$refs[selector]; + var el = Array.isArray(ref) ? ref[0] : ref; + if (!el) { + return; + } + + var options = { + vm: this$1.vm, + classes: this$1.classes, + classNames: this$1.classNames, + delay: this$1.delay, + scope: this$1.scope, + events: this$1.events.join('|'), + immediate: this$1.immediate, + targetOf: this$1.id + }; + + // probably a component. + if (isCallable(el.$watch)) { + options.component = el; + options.el = el.$el; + options.getter = Resolver.resolveGetter(el.$el, el.$vnode); + } else { + options.el = el; + options.getter = Resolver.resolveGetter(el, {}); + } + + this$1.dependencies.push({ name: name, field: new Field(options) }); + }); + }; + + /** + * Removes listeners. + */ + Field.prototype.unwatch = function unwatch (tag) { + if ( tag === void 0 ) tag = null; + + if (!tag) { + this.watchers.forEach(function (w) { return w.unwatch(); }); + this.watchers = []; + return; + } + + this.watchers.filter(function (w) { return tag.test(w.tag); }).forEach(function (w) { return w.unwatch(); }); + this.watchers = this.watchers.filter(function (w) { return !tag.test(w.tag); }); + }; + + /** + * Updates the element classes depending on each field flag status. + */ + Field.prototype.updateClasses = function updateClasses () { + var this$1 = this; + + if (!this.classes || this.isDisabled) { return; } + var applyClasses = function (el) { + toggleClass(el, this$1.classNames.dirty, this$1.flags.dirty); + toggleClass(el, this$1.classNames.pristine, this$1.flags.pristine); + toggleClass(el, this$1.classNames.touched, this$1.flags.touched); + toggleClass(el, this$1.classNames.untouched, this$1.flags.untouched); + // make sure we don't set any classes if the state is undetermined. + if (!isNullOrUndefined(this$1.flags.valid) && this$1.flags.validated) { + toggleClass(el, this$1.classNames.valid, this$1.flags.valid); + } + + if (!isNullOrUndefined(this$1.flags.invalid) && this$1.flags.validated) { + toggleClass(el, this$1.classNames.invalid, this$1.flags.invalid); + } + }; + + if (!isCheckboxOrRadioInput(this.el)) { + applyClasses(this.el); + return; + } + + var els = document.querySelectorAll(("input[name=\"" + (this.el.name) + "\"]")); + toArray(els).forEach(applyClasses); + }; + + /** + * Adds the listeners required for automatic classes and some flags. + */ + Field.prototype.addActionListeners = function addActionListeners () { + var this$1 = this; + + // remove previous listeners. + this.unwatch(/class/); + + if (!this.el) { return; } + + var onBlur = function () { + this$1.flags.touched = true; + this$1.flags.untouched = false; + if (this$1.classes) { + toggleClass(this$1.el, this$1.classNames.touched, true); + toggleClass(this$1.el, this$1.classNames.untouched, false); + } + + // only needed once. + this$1.unwatch(/^class_blur$/); + }; + + var inputEvent = isTextInput(this.el) ? 'input' : 'change'; + var onInput = function () { + this$1.flags.dirty = true; + this$1.flags.pristine = false; + if (this$1.classes) { + toggleClass(this$1.el, this$1.classNames.pristine, false); + toggleClass(this$1.el, this$1.classNames.dirty, true); + } + + // only needed once. + this$1.unwatch(/^class_input$/); + }; + + if (this.componentInstance && isCallable(this.componentInstance.$once)) { + this.componentInstance.$once('input', onInput); + this.componentInstance.$once('blur', onBlur); + this.watchers.push({ + tag: 'class_input', + unwatch: function () { + this$1.componentInstance.$off('input', onInput); + } + }); + this.watchers.push({ + tag: 'class_blur', + unwatch: function () { + this$1.componentInstance.$off('blur', onBlur); + } + }); + return; + } + + if (!this.el) { return; } + + addEventListener(this.el, inputEvent, onInput); + // Checkboxes and radio buttons on Mac don't emit blur naturally, so we listen on click instead. + var blurEvent = isCheckboxOrRadioInput(this.el) ? 'change' : 'blur'; + addEventListener(this.el, blurEvent, onBlur); + this.watchers.push({ + tag: 'class_input', + unwatch: function () { + this$1.el.removeEventListener(inputEvent, onInput); + } + }); + + this.watchers.push({ + tag: 'class_blur', + unwatch: function () { + this$1.el.removeEventListener(blurEvent, onBlur); + } + }); + }; + + Field.prototype.checkValueChanged = function checkValueChanged () { + // handle some people initialize the value to null, since text inputs have empty string value. + if (this.initialValue === null && this.value === '' && isTextInput(this.el)) { + return false; + } + + return this.value !== this.initialValue; + }; + + /** + * Determines the suitable primary event to listen for. + */ + Field.prototype._determineInputEvent = function _determineInputEvent () { + // if its a custom component, use the customized model event or the input event. + if (this.componentInstance) { + return (this.componentInstance.$options.model && this.componentInstance.$options.model.event) || 'input'; + } + + if (this.model && this.model.lazy) { + return 'change'; + } + + if (isTextInput(this.el)) { + return 'input'; + } + + return 'change'; + }; + + /** + * Determines the list of events to listen to. + */ + Field.prototype._determineEventList = function _determineEventList (defaultInputEvent) { + // if no event is configured, or it is a component or a text input then respect the user choice. + if (!this.events.length || this.componentInstance || isTextInput(this.el)) { + return [].concat( this.events ); + } + + // force suitable event for non-text type fields. + return this.events.map(function (e) { + if (e === 'input') { + return defaultInputEvent; + } + + return e; + }); + }; + + /** + * Adds the listeners required for validation. + */ + Field.prototype.addValueListeners = function addValueListeners () { + var this$1 = this; + + this.unwatch(/^input_.+/); + if (!this.listen || !this.el) { return; } + + var token = { cancelled: false }; + var fn = this.targetOf ? function () { + this$1.flags.changed = this$1.checkValueChanged(); this$1.validator.validate(("#" + (this$1.targetOf))); + } : function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + // if its a DOM event, resolve the value, otherwise use the first parameter as the value. + if (args.length === 0 || (isCallable(Event) && args[0] instanceof Event) || (args[0] && args[0].srcElement)) { + args[0] = this$1.value; + } + + this$1.flags.changed = this$1.checkValueChanged(); + this$1.validator.validate(("#" + (this$1.id)), args[0]); + }; + + var inputEvent = this._determineInputEvent(); + var events = this._determineEventList(inputEvent); + + // if there is a model and an on input validation is requested. + if (this.model && includes(events, inputEvent)) { + var ctx = null; + var expression = this.model.expression; + // if its watchable from the context vm. + if (this.model.expression) { + ctx = this.vm; + expression = this.model.expression; + } + + // watch it from the custom component vm instead. + if (!expression && this.componentInstance && this.componentInstance.$options.model) { + ctx = this.componentInstance; + expression = this.componentInstance.$options.model.prop || 'value'; + } + + if (ctx && expression) { + var debouncedFn = debounce(fn, this.delay[inputEvent], false, token); + var unwatch = ctx.$watch(expression, function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + this$1.flags.pending = true; + this$1._cancellationToken = token; + debouncedFn.apply(void 0, args); + }); + this.watchers.push({ + tag: 'input_model', + unwatch: unwatch + }); + + // filter out input event as it is already handled by the watcher API. + events = events.filter(function (e) { return e !== inputEvent; }); + } + } + + // Add events. + events.forEach(function (e) { + var debouncedFn = debounce(fn, this$1.delay[e], false, token); + var validate = function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + this$1.flags.pending = true; + this$1._cancellationToken = token; + debouncedFn.apply(void 0, args); + }; + + this$1._addComponentEventListener(e, validate); + this$1._addHTMLEventListener(e, validate); + }); + }; + + Field.prototype._addComponentEventListener = function _addComponentEventListener (evt, validate) { + var this$1 = this; + + if (!this.componentInstance) { return; } + + this.componentInstance.$on(evt, validate); + this.watchers.push({ + tag: 'input_vue', + unwatch: function () { + this$1.componentInstance.$off(evt, validate); + } + }); + }; + + Field.prototype._addHTMLEventListener = function _addHTMLEventListener (evt, validate) { + var this$1 = this; + + if (!this.el || this.componentInstance) { return; } + + // listen for the current element. + var addListener = function (el) { + addEventListener(el, evt, validate); + this$1.watchers.push({ + tag: 'input_native', + unwatch: function () { + el.removeEventListener(evt, validate); + } + }); + }; + + addListener(this.el); + if (!isCheckboxOrRadioInput(this.el)) { + return; + } + + var els = document.querySelectorAll(("input[name=\"" + (this.el.name) + "\"]")); + toArray(els).forEach(function (el) { + // skip if it is added by v-validate and is not the current element. + if (el._veeValidateId && el !== this$1.el) { + return; + } + + addListener(el); + }); + }; + + /** + * Updates aria attributes on the element. + */ + Field.prototype.updateAriaAttrs = function updateAriaAttrs () { + var this$1 = this; + + if (!this.aria || !this.el || !isCallable(this.el.setAttribute)) { return; } + + var applyAriaAttrs = function (el) { + el.setAttribute('aria-required', this$1.isRequired ? 'true' : 'false'); + el.setAttribute('aria-invalid', this$1.flags.invalid ? 'true' : 'false'); + }; + + if (!isCheckboxOrRadioInput(this.el)) { + applyAriaAttrs(this.el); + return; + } + + var els = document.querySelectorAll(("input[name=\"" + (this.el.name) + "\"]")); + toArray(els).forEach(applyAriaAttrs); + }; + + /** + * Updates the custom validity for the field. + */ + Field.prototype.updateCustomValidity = function updateCustomValidity () { + if (!this.validity || !this.el || !isCallable(this.el.setCustomValidity) || !this.validator.errors) { return; } + + this.el.setCustomValidity(this.flags.valid ? '' : (this.validator.errors.firstById(this.id) || '')); + }; + + /** + * Removes all listeners. + */ + Field.prototype.destroy = function destroy () { + // ignore the result of any ongoing validation. + if (this._cancellationToken) { + this._cancellationToken.cancelled = true; + } + + this.unwatch(); + this.dependencies.forEach(function (d) { return d.field.destroy(); }); + this.dependencies = []; + }; + + Object.defineProperties( Field.prototype, prototypeAccessors$3 ); + + // + + var FieldBag = function FieldBag (items) { + if ( items === void 0 ) items = []; + + this.items = items || []; + }; + + var prototypeAccessors$4 = { length: { configurable: true } }; + + FieldBag.prototype[typeof Symbol === 'function' ? Symbol.iterator : '@@iterator'] = function () { + var this$1 = this; + + var index = 0; + return { + next: function () { + return { value: this$1.items[index++], done: index > this$1.items.length }; + } + }; + }; + + /** + * Gets the current items length. + */ + + prototypeAccessors$4.length.get = function () { + return this.items.length; + }; + + /** + * Finds the first field that matches the provided matcher object. + */ + FieldBag.prototype.find = function find$1 (matcher) { + return find(this.items, function (item) { return item.matches(matcher); }); + }; + + /** + * Filters the items down to the matched fields. + */ + FieldBag.prototype.filter = function filter (matcher) { + // multiple matchers to be tried. + if (Array.isArray(matcher)) { + return this.items.filter(function (item) { return matcher.some(function (m) { return item.matches(m); }); }); + } + + return this.items.filter(function (item) { return item.matches(matcher); }); + }; + + /** + * Maps the field items using the mapping function. + */ + FieldBag.prototype.map = function map (mapper) { + return this.items.map(mapper); + }; + + /** + * Finds and removes the first field that matches the provided matcher object, returns the removed item. + */ + FieldBag.prototype.remove = function remove (matcher) { + var item = null; + if (matcher instanceof Field) { + item = matcher; + } else { + item = this.find(matcher); + } + + if (!item) { return null; } + + var index = this.items.indexOf(item); + this.items.splice(index, 1); + + return item; + }; + + /** + * Adds a field item to the list. + */ + FieldBag.prototype.push = function push (item) { + if (! (item instanceof Field)) { + throw createError('FieldBag only accepts instances of Field that has an id defined.'); + } + + if (!item.id) { + throw createError('Field id must be defined.'); + } + + if (this.find({ id: item.id })) { + throw createError(("Field with id " + (item.id) + " is already added.")); + } + + this.items.push(item); + }; + + Object.defineProperties( FieldBag.prototype, prototypeAccessors$4 ); + + var ScopedValidator = function ScopedValidator (base, vm) { + this.id = vm._uid; + this._base = base; + this._paused = false; + + // create a mirror bag with limited component scope. + this.errors = new ErrorBag(base.errors, this.id); + }; + + var prototypeAccessors$5 = { flags: { configurable: true },rules: { configurable: true },fields: { configurable: true },dictionary: { configurable: true },locale: { configurable: true } }; + + prototypeAccessors$5.flags.get = function () { + var this$1 = this; + + return this._base.fields.items.filter(function (f) { return f.vmId === this$1.id; }).reduce(function (acc, field) { + if (field.scope) { + if (!acc[("$" + (field.scope))]) { + acc[("$" + (field.scope))] = {}; + } + + acc[("$" + (field.scope))][field.name] = field.flags; + } + + acc[field.name] = field.flags; + + return acc; + }, {}); + }; + + prototypeAccessors$5.rules.get = function () { + return this._base.rules; + }; + + prototypeAccessors$5.fields.get = function () { + return new FieldBag(this._base.fields.filter({ vmId: this.id })); + }; + + prototypeAccessors$5.dictionary.get = function () { + return this._base.dictionary; + }; + + prototypeAccessors$5.locale.get = function () { + return this._base.locale; + }; + + prototypeAccessors$5.locale.set = function (val) { + this._base.locale = val; + }; + + ScopedValidator.prototype.localize = function localize () { + var ref; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + return (ref = this._base).localize.apply(ref, args); + }; + + ScopedValidator.prototype.update = function update () { + var ref; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + return (ref = this._base).update.apply(ref, args); + }; + + ScopedValidator.prototype.attach = function attach (opts) { + var attachOpts = assign({}, opts, { vmId: this.id }); + + return this._base.attach(attachOpts); + }; + + ScopedValidator.prototype.pause = function pause () { + this._paused = true; + }; + + ScopedValidator.prototype.resume = function resume () { + this._paused = false; + }; + + ScopedValidator.prototype.remove = function remove (ruleName) { + return this._base.remove(ruleName); + }; + + ScopedValidator.prototype.detach = function detach () { + var ref; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + return (ref = this._base).detach.apply(ref, args.concat( [this.id] )); + }; + + ScopedValidator.prototype.extend = function extend () { + var ref; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + return (ref = this._base).extend.apply(ref, args); + }; + + ScopedValidator.prototype.validate = function validate (descriptor, value, opts) { + if ( opts === void 0 ) opts = {}; + + if (this._paused) { return Promise.resolve(true); } + + return this._base.validate(descriptor, value, assign({}, { vmId: this.id }, opts || {})); + }; + + ScopedValidator.prototype.validateAll = function validateAll (values$$1, opts) { + if ( opts === void 0 ) opts = {}; + + if (this._paused) { return Promise.resolve(true); } + + return this._base.validateAll(values$$1, assign({}, { vmId: this.id }, opts || {})); + }; + + ScopedValidator.prototype.validateScopes = function validateScopes (opts) { + if ( opts === void 0 ) opts = {}; + + if (this._paused) { return Promise.resolve(true); } + + return this._base.validateScopes(assign({}, { vmId: this.id }, opts || {})); + }; + + ScopedValidator.prototype.destroy = function destroy () { + delete this.id; + delete this._base; + }; + + ScopedValidator.prototype.reset = function reset (matcher) { + return this._base.reset(Object.assign({}, matcher || {}, { vmId: this.id })); + }; + + ScopedValidator.prototype.flag = function flag () { + var ref; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + return (ref = this._base).flag.apply(ref, args.concat( [this.id] )); + }; + + Object.defineProperties( ScopedValidator.prototype, prototypeAccessors$5 ); + + // + + /** + * Checks if a parent validator instance was requested. + */ + var requestsValidator = function (injections) { + if (isObject(injections) && injections.$validator) { + return true; + } + + return false; + }; + + var mixin = { + provide: function provide () { + if (this.$validator && !isBuiltInComponent(this.$vnode)) { + return { + $validator: this.$validator + }; + } + + return {}; + }, + beforeCreate: function beforeCreate () { + // if built in do nothing. + if (isBuiltInComponent(this.$vnode)) { + return; + } + + // if its a root instance set the config if it exists. + if (!this.$parent) { + Config.merge(this.$options.$_veeValidate || {}); + } + + var options = Config.resolve(this); + + // if its a root instance, inject anyways, or if it requested a new instance. + if (!this.$parent || (this.$options.$_veeValidate && /new/.test(this.$options.$_veeValidate.validator))) { + this.$validator = new ScopedValidator(Config.dependency('validator'), this); + } + + var requested = requestsValidator(this.$options.inject); + + // if automatic injection is enabled and no instance was requested. + if (! this.$validator && options.inject && !requested) { + this.$validator = new ScopedValidator(Config.dependency('validator'), this); + } + + // don't inject errors or fieldBag as no validator was resolved. + if (! requested && ! this.$validator) { + return; + } + + // There is a validator but it isn't injected, mark as reactive. + if (!requested && this.$validator) { + var Vue = this.$options._base; // the vue constructor. + Vue.util.defineReactive(this.$validator, 'errors', this.$validator.errors); + } + + if (! this.$options.computed) { + this.$options.computed = {}; + } + + this.$options.computed[options.errorBagName || 'errors'] = function errorBagGetter () { + return this.$validator.errors; + }; + this.$options.computed[options.fieldsBagName || 'fields'] = function fieldBagGetter () { + return this.$validator.fields.items.reduce(function (acc, field) { + if (field.scope) { + if (!acc[("$" + (field.scope))]) { + acc[("$" + (field.scope))] = {}; + } + + acc[("$" + (field.scope))][field.name] = field.flags; + + return acc; + } + + acc[field.name] = field.flags; + + return acc; + }, {}); + }; + }, + beforeDestroy: function beforeDestroy () { + if (this.$validator && this._uid === this.$validator.id) { + this.$validator.errors.clear(); // remove errors generated by this component. + } + } + }; + + // + + /** + * Finds the requested field by id from the context object. + */ + function findField (el, context) { + if (!context || !context.$validator) { + return null; + } + + return context.$validator.fields.find({ id: el._veeValidateId }); + } + var directive = { + bind: function bind (el, binding, vnode) { + var validator = vnode.context.$validator; + if (!validator) { + { + warn("No validator instance is present on vm, did you forget to inject '$validator'?"); + } + + return; + } + + var fieldOptions = Resolver.generate(el, binding, vnode); + validator.attach(fieldOptions); + }, + inserted: function inserted (el, binding, vnode) { + var field = findField(el, vnode.context); + var scope = Resolver.resolveScope(el, binding, vnode); + + // skip if scope hasn't changed. + if (!field || scope === field.scope) { return; } + + // only update scope. + field.update({ scope: scope }); + + // allows the field to re-evaluated once more in the update hook. + field.updated = false; + }, + update: function update (el, binding, vnode) { + var field = findField(el, vnode.context); + + // make sure we don't do unneccasary work if no important change was done. + if (!field || (field.updated && isEqual$1(binding.value, binding.oldValue))) { return; } + var scope = Resolver.resolveScope(el, binding, vnode); + var rules = Resolver.resolveRules(el, binding, vnode); + + field.update({ + scope: scope, + rules: rules + }); + }, + unbind: function unbind (el, binding, ref) { + var context = ref.context; + + var field = findField(el, context); + if (!field) { return; } + + context.$validator.detach(field); + } + }; + + var Vue; + + function install (_Vue, options) { + if ( options === void 0 ) options = {}; + + if (Vue && _Vue === Vue) { + { + warn('already installed, Vue.use(VeeValidate) should only be called once.'); + } + return; + } + + detectPassiveSupport(); + Vue = _Vue; + var validator = new Validator(null, options); + var localVue = new Vue({ + data: function () { return ({ + errors: validator.errors, + fields: validator.fields + }); } + }); + Config.register('vm', localVue); + Config.register('validator', validator); + Config.merge(options); + + var ref = Config.current; + var dictionary = ref.dictionary; + var i18n = ref.i18n; + + if (dictionary) { + validator.localize(dictionary); // merge the dictionary. + } + + var onLocaleChanged = function () { + validator.errors.regenerate(); + }; + + // watch locale changes using localVue instance or i18n. + if (!i18n) { + if (typeof window !== 'undefined') { + localVue.$on('localeChanged', onLocaleChanged); + } + } else { + i18n._vm.$watch('locale', onLocaleChanged); + } + + if (!i18n && options.locale) { + validator.localize(options.locale); // set the locale + } + + Validator.setStrictMode(Config.current.strict); + + Vue.mixin(mixin); + Vue.directive('validate', directive); + } + + // + + function use (plugin, options) { + if ( options === void 0 ) options = {}; + + if (!isCallable(plugin)) { + return warn('The plugin must be a callable function'); + } + + plugin({ Validator: Validator, ErrorBag: ErrorBag, Rules: Validator.rules }, options); + } + + // + + var normalize = function (fields) { + if (Array.isArray(fields)) { + return fields.reduce(function (prev, curr) { + if (includes(curr, '.')) { + prev[curr.split('.')[1]] = curr; + } else { + prev[curr] = curr; + } + + return prev; + }, {}); + } + + return fields; + }; + + // Combines two flags using either AND or OR depending on the flag type. + var combine = function (lhs, rhs) { + var mapper = { + pristine: function (lhs, rhs) { return lhs && rhs; }, + dirty: function (lhs, rhs) { return lhs || rhs; }, + touched: function (lhs, rhs) { return lhs || rhs; }, + untouched: function (lhs, rhs) { return lhs && rhs; }, + valid: function (lhs, rhs) { return lhs && rhs; }, + invalid: function (lhs, rhs) { return lhs || rhs; }, + pending: function (lhs, rhs) { return lhs || rhs; }, + required: function (lhs, rhs) { return lhs || rhs; }, + validated: function (lhs, rhs) { return lhs && rhs; } + }; + + return Object.keys(mapper).reduce(function (flags, flag) { + flags[flag] = mapper[flag](lhs[flag], rhs[flag]); + + return flags; + }, {}); + }; + + var mapScope = function (scope, deep) { + if ( deep === void 0 ) deep = true; + + return Object.keys(scope).reduce(function (flags, field) { + if (!flags) { + flags = assign({}, scope[field]); + return flags; + } + + // scope. + var isScope = field.indexOf('$') === 0; + if (deep && isScope) { + return combine(mapScope(scope[field]), flags); + } else if (!deep && isScope) { + return flags; + } + + flags = combine(flags, scope[field]); + + return flags; + }, null); + }; + + /** + * Maps fields to computed functions. + */ + var mapFields = function (fields) { + if (!fields) { + return function () { + return mapScope(this.$validator.flags); + }; + } + + var normalized = normalize(fields); + return Object.keys(normalized).reduce(function (prev, curr) { + var field = normalized[curr]; + prev[curr] = function mappedField () { + // if field exists + if (this.$validator.flags[field]) { + return this.$validator.flags[field]; + } + + // scopeless fields were selected. + if (normalized[curr] === '*') { + return mapScope(this.$validator.flags, false); + } + + // if it has a scope defined + var index = field.indexOf('.'); + if (index <= 0) { + return {}; + } + + var ref = field.split('.'); + var scope = ref[0]; + var name = ref.slice(1); + + scope = this.$validator.flags[("$" + scope)]; + name = name.join('.'); + + // an entire scope was selected: scope.* + if (name === '*' && scope) { + return mapScope(scope); + } + + if (scope && scope[name]) { + return scope[name]; + } + + return {}; + }; + + return prev; + }, {}); + }; + + var ErrorComponent = { + name: 'vv-error', + inject: ['$validator'], + functional: true, + props: { + for: { + type: String, + required: true + }, + tag: { + type: String, + default: 'span' + } + }, + render: function render (createElement, ref) { + var props = ref.props; + var injections = ref.injections; + + return createElement(props.tag, injections.$validator.errors.first(props.for)); + } + }; + + var minimal = { + install: install, + use: use, + directive: directive, + mixin: mixin, + mapFields: mapFields, + Validator: Validator, + ErrorBag: ErrorBag, + ErrorComponent: ErrorComponent, + version: '2.1.0-beta.9' + }; + + // rules plugin definition. + var rulesPlugin = function (ref) { + var Validator = ref.Validator; + + Object.keys(Rules).forEach(function (rule) { + Validator.extend(rule, Rules[rule].validate, assign({}, Rules[rule].options, { paramNames: Rules[rule].paramNames })); + }); + + // Merge the english messages. + Validator.localize('en', locale$1); + }; + + // install the rules via the plugin API. + minimal.use(rulesPlugin); + + minimal.Rules = Rules; + + return minimal; + +}))); diff --git a/net452/SiteServer.Web/Home/assets/lib/vee-validate-locale-zh_CN-2.1.0.js b/net452/SiteServer.Web/Home/assets/lib/vee-validate-locale-zh_CN-2.1.0.js new file mode 100644 index 000000000..8af33f16d --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/lib/vee-validate-locale-zh_CN-2.1.0.js @@ -0,0 +1 @@ +!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(n.__vee_validate_locale__zh_CN=n.__vee_validate_locale__zh_CN||{},n.__vee_validate_locale__zh_CN.js=e())}(this,function(){"use strict";var n,e={name:"zh_CN",messages:{after:function(n,e){return n+"必须在"+e[0]+"之后"},alpha_dash:function(n){return n+"能够包含字母数字字符、破折号和下划线"},alpha_num:function(n){return n+"只能包含字母数字字符"},alpha_spaces:function(n){return n+"只能包含字母字符和空格"},alpha:function(n){return n+"只能包含字母字符"},before:function(n,e){return n+"必须在"+e[0]+"之前"},between:function(n,e){return n+"必须在"+e[0]+"与"+e[1]+"之间"},confirmed:function(n,e){return n+"不能和"+e[0]+"匹配"},date_between:function(n,e){return n+"必须在"+e[0]+"和"+e[1]+"之间"},date_format:function(n,e){return n+"必须符合"+e[0]+"格式"},decimal:function(n,e){void 0===e&&(e=[]);var t=e[0];return void 0===t&&(t="*"),n+"必须是数字,且能够保留"+("*"===t?"":t)+"位小数"},digits:function(n,e){return n+"必须是数字,且精确到"+e[0]+"位数"},dimensions:function(n,e){return n+"必须在"+e[0]+"像素与"+e[1]+"像素之间"},email:function(n){return n+"不是一个有效的邮箱"},ext:function(n){return n+"不是一个有效的文件"},image:function(n){return n+"不是一张有效的图片"},included:function(n){return n+"不是一个有效值"},ip:function(n){return n+"不是一个有效的地址"},max:function(n,e){return n+"不能超过"+e[0]+"个字符"},max_value:function(n,e){return n+"必须小于或等于"+e[0]},mimes:function(n){return n+"不是一个有效的文件类型"},min:function(n,e){return n+"必须至少有"+e[0]+"个字符"},min_value:function(n,e){return n+"必须大于或等于"+e[0]},excluded:function(n){return n+"不是一个有效值"},numeric:function(n){return n+"只能包含数字字符"},regex:function(n){return n+"格式无效"},required:function(n){return n+"是必须的"},size:function(n,e){var t,r,u,i=e[0];return n+"必须小于"+(t=i,r=1024,u=0==(t=Number(t)*r)?0:Math.floor(Math.log(t)/Math.log(r)),1*(t/Math.pow(r,u)).toFixed(2)+" "+["Byte","KB","MB","GB","TB","PB","EB","ZB","YB"][u])},url:function(n){return n+"不是一个有效的url"}},attributes:{}};return"undefined"!=typeof VeeValidate&&VeeValidate.Validator.localize(((n={})[e.name]=e,n)),e}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/assets/lib/vue-2.5.16.min.js b/net452/SiteServer.Web/Home/assets/lib/vue-2.5.16.min.js new file mode 100644 index 000000000..37febff24 --- /dev/null +++ b/net452/SiteServer.Web/Home/assets/lib/vue-2.5.16.min.js @@ -0,0 +1,6 @@ +/*! + * Vue.js v2.5.16 + * (c) 2014-2018 Evan You + * Released under the MIT License. + */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Vue=t()}(this,function(){"use strict";var y=Object.freeze({});function M(e){return null==e}function D(e){return null!=e}function S(e){return!0===e}function T(e){return"string"==typeof e||"number"==typeof e||"symbol"==typeof e||"boolean"==typeof e}function P(e){return null!==e&&"object"==typeof e}var r=Object.prototype.toString;function l(e){return"[object Object]"===r.call(e)}function i(e){var t=parseFloat(String(e));return 0<=t&&Math.floor(t)===t&&isFinite(e)}function t(e){return null==e?"":"object"==typeof e?JSON.stringify(e,null,2):String(e)}function F(e){var t=parseFloat(e);return isNaN(t)?e:t}function s(e,t){for(var n=Object.create(null),r=e.split(","),i=0;ie.id;)n--;bt.splice(n+1,0,e)}else bt.push(e);Ct||(Ct=!0,Ze(At))}}(this)},St.prototype.run=function(){if(this.active){var e=this.get();if(e!==this.value||P(e)||this.deep){var t=this.value;if(this.value=e,this.user)try{this.cb.call(this.vm,e,t)}catch(e){Fe(e,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,e,t)}}},St.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},St.prototype.depend=function(){for(var e=this.deps.length;e--;)this.deps[e].depend()},St.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||f(this.vm._watchers,this);for(var e=this.deps.length;e--;)this.deps[e].removeSub(this);this.active=!1}};var Tt={enumerable:!0,configurable:!0,get:$,set:$};function Et(e,t,n){Tt.get=function(){return this[t][n]},Tt.set=function(e){this[t][n]=e},Object.defineProperty(e,n,Tt)}function jt(e){e._watchers=[];var t=e.$options;t.props&&function(n,r){var i=n.$options.propsData||{},o=n._props={},a=n.$options._propKeys=[];n.$parent&&ge(!1);var e=function(e){a.push(e);var t=Ie(e,r,i,n);Ce(o,e,t),e in n||Et(n,"_props",e)};for(var t in r)e(t);ge(!0)}(e,t.props),t.methods&&function(e,t){e.$options.props;for(var n in t)e[n]=null==t[n]?$:v(t[n],e)}(e,t.methods),t.data?function(e){var t=e.$options.data;l(t=e._data="function"==typeof t?function(e,t){se();try{return e.call(t,t)}catch(e){return Fe(e,t,"data()"),{}}finally{ce()}}(t,e):t||{})||(t={});var n=Object.keys(t),r=e.$options.props,i=(e.$options.methods,n.length);for(;i--;){var o=n[i];r&&p(r,o)||(void 0,36!==(a=(o+"").charCodeAt(0))&&95!==a&&Et(e,"_data",o))}var a;we(t,!0)}(e):we(e._data={},!0),t.computed&&function(e,t){var n=e._computedWatchers=Object.create(null),r=Y();for(var i in t){var o=t[i],a="function"==typeof o?o:o.get;r||(n[i]=new St(e,a||$,$,Nt)),i in e||Lt(e,i,o)}}(e,t.computed),t.watch&&t.watch!==G&&function(e,t){for(var n in t){var r=t[n];if(Array.isArray(r))for(var i=0;iparseInt(this.max)&&bn(a,s[0],s,this._vnode)),t.data.keepAlive=!0}return t||e&&e[0]}}};$n=hn,Cn={get:function(){return j}},Object.defineProperty($n,"config",Cn),$n.util={warn:re,extend:m,mergeOptions:Ne,defineReactive:Ce},$n.set=xe,$n.delete=ke,$n.nextTick=Ze,$n.options=Object.create(null),k.forEach(function(e){$n.options[e+"s"]=Object.create(null)}),m(($n.options._base=$n).options.components,kn),$n.use=function(e){var t=this._installedPlugins||(this._installedPlugins=[]);if(-1=a&&l()};setTimeout(function(){c\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,oo="[a-zA-Z_][\\w\\-\\.]*",ao="((?:"+oo+"\\:)?"+oo+")",so=new RegExp("^<"+ao),co=/^\s*(\/?)>/,lo=new RegExp("^<\\/"+ao+"[^>]*>"),uo=/^]+>/i,fo=/^",""":'"',"&":"&"," ":"\n"," ":"\t"},go=/&(?:lt|gt|quot|amp);/g,_o=/&(?:lt|gt|quot|amp|#10|#9);/g,bo=s("pre,textarea",!0),$o=function(e,t){return e&&bo(e)&&"\n"===t[0]};var wo,Co,xo,ko,Ao,Oo,So,To,Eo=/^@|^v-on:/,jo=/^v-|^@|^:/,No=/([^]*?)\s+(?:in|of)\s+([^]*)/,Lo=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,Io=/^\(|\)$/g,Mo=/:(.*)$/,Do=/^:|^v-bind:/,Po=/\.[^.]+/g,Fo=e(eo);function Ro(e,t,n){return{type:1,tag:e,attrsList:t,attrsMap:function(e){for(var t={},n=0,r=e.length;n]*>)","i")),n=i.replace(t,function(e,t,n){return r=n.length,ho(o)||"noscript"===o||(t=t.replace(//g,"$1").replace(//g,"$1")),$o(o,t)&&(t=t.slice(1)),d.chars&&d.chars(t),""});a+=i.length-n.length,i=n,A(o,a-r,a)}else{var s=i.indexOf("<");if(0===s){if(fo.test(i)){var c=i.indexOf("--\x3e");if(0<=c){d.shouldKeepComment&&d.comment(i.substring(4,c)),C(c+3);continue}}if(po.test(i)){var l=i.indexOf("]>");if(0<=l){C(l+2);continue}}var u=i.match(uo);if(u){C(u[0].length);continue}var f=i.match(lo);if(f){var p=a;C(f[0].length),A(f[1],p,a);continue}var _=x();if(_){k(_),$o(v,i)&&C(1);continue}}var b=void 0,$=void 0,w=void 0;if(0<=s){for($=i.slice(s);!(lo.test($)||so.test($)||fo.test($)||po.test($)||(w=$.indexOf("<",1))<0);)s+=w,$=i.slice(s);b=i.substring(0,s),C(s)}s<0&&(b=i,i=""),d.chars&&b&&d.chars(b)}if(i===e){d.chars&&d.chars(i);break}}function C(e){a+=e,i=i.substring(e)}function x(){var e=i.match(so);if(e){var t,n,r={tagName:e[1],attrs:[],start:a};for(C(e[0].length);!(t=i.match(co))&&(n=i.match(io));)C(n[0].length),r.attrs.push(n);if(t)return r.unarySlash=t[1],C(t[0].length),r.end=a,r}}function k(e){var t=e.tagName,n=e.unarySlash;m&&("p"===v&&ro(t)&&A(v),g(t)&&v===t&&A(t));for(var r,i,o,a=y(t)||!!n,s=e.attrs.length,c=new Array(s),l=0;l-1"+("true"===d?":("+l+")":":_q("+l+","+d+")")),Ar(c,"change","var $$a="+l+",$$el=$event.target,$$c=$$el.checked?("+d+"):("+v+");if(Array.isArray($$a)){var $$v="+(f?"_n("+p+")":p)+",$$i=_i($$a,$$v);if($$el.checked){$$i<0&&("+Er(l,"$$a.concat([$$v])")+")}else{$$i>-1&&("+Er(l,"$$a.slice(0,$$i).concat($$a.slice($$i+1))")+")}}else{"+Er(l,"$$c")+"}",null,!0);else if("input"===$&&"radio"===w)r=e,i=_,a=(o=b)&&o.number,s=Or(r,"value")||"null",Cr(r,"checked","_q("+i+","+(s=a?"_n("+s+")":s)+")"),Ar(r,"change",Er(i,s),null,!0);else if("input"===$||"textarea"===$)!function(e,t,n){var r=e.attrsMap.type,i=n||{},o=i.lazy,a=i.number,s=i.trim,c=!o&&"range"!==r,l=o?"change":"range"===r?Pr:"input",u="$event.target.value";s&&(u="$event.target.value.trim()"),a&&(u="_n("+u+")");var f=Er(t,u);c&&(f="if($event.target.composing)return;"+f),Cr(e,"value","("+t+")"),Ar(e,l,f,null,!0),(s||a)&&Ar(e,"blur","$forceUpdate()")}(e,_,b);else if(!j.isReservedTag($))return Tr(e,_,b),!1;return!0},text:function(e,t){t.value&&Cr(e,"textContent","_s("+t.value+")")},html:function(e,t){t.value&&Cr(e,"innerHTML","_s("+t.value+")")}},isPreTag:function(e){return"pre"===e},isUnaryTag:to,mustUseProp:Sn,canBeLeftOpenTag:no,isReservedTag:Un,getTagNamespace:Vn,staticKeys:(Go=Wo,Go.reduce(function(e,t){return e.concat(t.staticKeys||[])},[]).join(","))},Qo=e(function(e){return s("type,tag,attrsList,attrsMap,plain,parent,children,attrs"+(e?","+e:""))});function ea(e,t){e&&(Zo=Qo(t.staticKeys||""),Xo=t.isReservedTag||O,function e(t){t.static=function(e){if(2===e.type)return!1;if(3===e.type)return!0;return!(!e.pre&&(e.hasBindings||e.if||e.for||c(e.tag)||!Xo(e.tag)||function(e){for(;e.parent;){if("template"!==(e=e.parent).tag)return!1;if(e.for)return!0}return!1}(e)||!Object.keys(e).every(Zo)))}(t);if(1===t.type){if(!Xo(t.tag)&&"slot"!==t.tag&&null==t.attrsMap["inline-template"])return;for(var n=0,r=t.children.length;n|^function\s*\(/,na=/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/,ra={esc:27,tab:9,enter:13,space:32,up:38,left:37,right:39,down:40,delete:[8,46]},ia={esc:"Escape",tab:"Tab",enter:"Enter",space:" ",up:["Up","ArrowUp"],left:["Left","ArrowLeft"],right:["Right","ArrowRight"],down:["Down","ArrowDown"],delete:["Backspace","Delete"]},oa=function(e){return"if("+e+")return null;"},aa={stop:"$event.stopPropagation();",prevent:"$event.preventDefault();",self:oa("$event.target !== $event.currentTarget"),ctrl:oa("!$event.ctrlKey"),shift:oa("!$event.shiftKey"),alt:oa("!$event.altKey"),meta:oa("!$event.metaKey"),left:oa("'button' in $event && $event.button !== 0"),middle:oa("'button' in $event && $event.button !== 1"),right:oa("'button' in $event && $event.button !== 2")};function sa(e,t,n){var r=t?"nativeOn:{":"on:{";for(var i in e)r+='"'+i+'":'+ca(i,e[i])+",";return r.slice(0,-1)+"}"}function ca(t,e){if(!e)return"function(){}";if(Array.isArray(e))return"["+e.map(function(e){return ca(t,e)}).join(",")+"]";var n=na.test(e.value),r=ta.test(e.value);if(e.modifiers){var i="",o="",a=[];for(var s in e.modifiers)if(aa[s])o+=aa[s],ra[s]&&a.push(s);else if("exact"===s){var c=e.modifiers;o+=oa(["ctrl","shift","alt","meta"].filter(function(e){return!c[e]}).map(function(e){return"$event."+e+"Key"}).join("||"))}else a.push(s);return a.length&&(i+="if(!('button' in $event)&&"+a.map(la).join("&&")+")return null;"),o&&(i+=o),"function($event){"+i+(n?"return "+e.value+"($event)":r?"return ("+e.value+")($event)":e.value)+"}"}return n||r?e.value:"function($event){"+e.value+"}"}function la(e){var t=parseInt(e,10);if(t)return"$event.keyCode!=="+t;var n=ra[e],r=ia[e];return"_k($event.keyCode,"+JSON.stringify(e)+","+JSON.stringify(n)+",$event.key,"+JSON.stringify(r)+")"}var ua={on:function(e,t){e.wrapListeners=function(e){return"_g("+e+","+t.value+")"}},bind:function(t,n){t.wrapData=function(e){return"_b("+e+",'"+t.tag+"',"+n.value+","+(n.modifiers&&n.modifiers.prop?"true":"false")+(n.modifiers&&n.modifiers.sync?",true":"")+")"}},cloak:$},fa=function(e){this.options=e,this.warn=e.warn||$r,this.transforms=wr(e.modules,"transformCode"),this.dataGenFns=wr(e.modules,"genData"),this.directives=m(m({},ua),e.directives);var t=e.isReservedTag||O;this.maybeComponent=function(e){return!t(e.tag)},this.onceId=0,this.staticRenderFns=[]};function pa(e,t){var n=new fa(t);return{render:"with(this){return "+(e?da(e,n):'_c("div")')+"}",staticRenderFns:n.staticRenderFns}}function da(e,t){if(e.staticRoot&&!e.staticProcessed)return va(e,t);if(e.once&&!e.onceProcessed)return ha(e,t);if(e.for&&!e.forProcessed)return f=t,v=(u=e).for,h=u.alias,m=u.iterator1?","+u.iterator1:"",y=u.iterator2?","+u.iterator2:"",u.forProcessed=!0,(d||"_l")+"(("+v+"),function("+h+m+y+"){return "+(p||da)(u,f)+"})";if(e.if&&!e.ifProcessed)return ma(e,t);if("template"!==e.tag||e.slotTarget){if("slot"===e.tag)return function(e,t){var n=e.slotName||'"default"',r=_a(e,t),i="_t("+n+(r?","+r:""),o=e.attrs&&"{"+e.attrs.map(function(e){return g(e.name)+":"+e.value}).join(",")+"}",a=e.attrsMap["v-bind"];!o&&!a||r||(i+=",null");o&&(i+=","+o);a&&(i+=(o?"":",null")+","+a);return i+")"}(e,t);var n;if(e.component)a=e.component,c=t,l=(s=e).inlineTemplate?null:_a(s,c,!0),n="_c("+a+","+ya(s,c)+(l?","+l:"")+")";else{var r=e.plain?void 0:ya(e,t),i=e.inlineTemplate?null:_a(e,t,!0);n="_c('"+e.tag+"'"+(r?","+r:"")+(i?","+i:"")+")"}for(var o=0;o':'
      ',00?i:n)(t)}},function(t,e,n){var i=n(13);t.exports=function(t,e){if(!i(t))return t;var n,r;if(e&&"function"==typeof(n=t.toString)&&!i(r=n.call(t)))return r;if("function"==typeof(n=t.valueOf)&&!i(r=n.call(t)))return r;if(!e&&"function"==typeof(n=t.toString)&&!i(r=n.call(t)))return r;throw TypeError("Can't convert object to primitive value")}},function(t,e,n){var i=n(0),r=n(11),o=n(25),s=n(33),u=n(3).f;t.exports=function(t){var e=r.Symbol||(r.Symbol=o?{}:i.Symbol||{});"_"==t.charAt(0)||t in e||u(e,t,{value:s.f(t)})}},function(t,e,n){e.f=n(7)},function(t,e,n){var i=n(53),r=n(36),o=n(57),s=n(37),u=n(104);t.exports=function(t,e){var n=1==t,a=2==t,l=3==t,c=4==t,f=6==t,p=5==t||f,h=e||u;return function(e,u,d){for(var v,y,g=o(e),b=r(g),m=i(u,d,3),_=s(b.length),x=0,w=n?h(e,_):a?h(e,0):void 0;_>x;x++)if((p||x in b)&&(v=b[x],y=m(v,x,g),t))if(n)w[x]=y;else if(y)switch(t){case 3:return!0;case 5:return v;case 6:return x;case 2:w.push(v)}else if(c)return!1;return f?-1:l||c?c:w}}},function(t,e,n){t.exports=!n(8)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,e,n){var i=n(51);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==i(t)?t.split(""):Object(t)}},function(t,e,n){var i=n(56),r=Math.min;t.exports=function(t){return t>0?r(i(t),9007199254740991):0}},function(t,e,n){var i=n(111)("wks"),r=n(58),o=n(9).Symbol,s="function"==typeof o;(t.exports=function(t){return i[t]||(i[t]=s&&o[t]||(s?o:r)("Symbol."+t))}).store=i},function(t,e,n){"use strict";function i(t){return 0!==t&&(!(!Array.isArray(t)||0!==t.length)||!t)}function r(t){return function(){return!t.apply(void 0,arguments)}}function o(t,e){return void 0===t&&(t="undefined"),null===t&&(t="null"),!1===t&&(t="false"),-1!==t.toString().toLowerCase().indexOf(e.trim())}function s(t,e,n,i){return t.filter(function(t){return o(i(t,n),e)})}function u(t){return t.filter(function(t){return!t.$isLabel})}function a(t,e){return function(n){return n.reduce(function(n,i){return i[t]&&i[t].length?(n.push({$groupLabel:i[e],$isLabel:!0}),n.concat(i[t])):n},[])}}function l(t,e,n,i,r){return function(o){return o.map(function(o){var u;if(!o[n])return console.warn("Options passed to vue-multiselect do not contain groups, despite the config."),[];var a=s(o[n],t,e,r);return a.length?(u={},v()(u,i,o[i]),v()(u,n,a),u):[]})}}var c=n(65),f=n.n(c),p=n(59),h=(n.n(p),n(122)),d=(n.n(h),n(64)),v=n.n(d),y=n(120),g=(n.n(y),n(121)),b=(n.n(g),n(117)),m=(n.n(b),n(123)),_=(n.n(m),n(118)),x=(n.n(_),n(119)),w=(n.n(x),function(){for(var t=arguments.length,e=new Array(t),n=0;n-1},isSelected:function(t){var e=this.trackBy?t[this.trackBy]:t;return this.valueKeys.indexOf(e)>-1},getOptionLabel:function(t){if(i(t))return"";if(t.isTag)return t.label;if(t.$isLabel)return t.$groupLabel;var e=this.customLabel(t,this.label);return i(e)?"":e},select:function(t,e){if(t.$isLabel&&this.groupSelect)return void this.selectGroup(t);if(!(-1!==this.blockKeys.indexOf(e)||this.disabled||t.$isDisabled||t.$isLabel)&&(!this.max||!this.multiple||this.internalValue.length!==this.max)&&("Tab"!==e||this.pointerDirty)){if(t.isTag)this.$emit("tag",t.label,this.id),this.search="",this.closeOnSelect&&!this.multiple&&this.deactivate();else{if(this.isSelected(t))return void("Tab"!==e&&this.removeElement(t));this.$emit("select",t,this.id),this.multiple?this.$emit("input",this.internalValue.concat([t]),this.id):this.$emit("input",t,this.id),this.clearOnSelect&&(this.search="")}this.closeOnSelect&&this.deactivate()}},selectGroup:function(t){var e=this,n=this.options.find(function(n){return n[e.groupLabel]===t.$groupLabel});if(n)if(this.wholeGroupSelected(n)){this.$emit("remove",n[this.groupValues],this.id);var i=this.internalValue.filter(function(t){return-1===n[e.groupValues].indexOf(t)});this.$emit("input",i,this.id)}else{var o=n[this.groupValues].filter(r(this.isSelected));this.$emit("select",o,this.id),this.$emit("input",this.internalValue.concat(o),this.id)}},wholeGroupSelected:function(t){return t[this.groupValues].every(this.isSelected)},removeElement:function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(!this.disabled){if(!this.allowEmpty&&this.internalValue.length<=1)return void this.deactivate();var n="object"===f()(t)?this.valueKeys.indexOf(t[this.trackBy]):this.valueKeys.indexOf(t);if(this.$emit("remove",t,this.id),this.multiple){var i=this.internalValue.slice(0,n).concat(this.internalValue.slice(n+1));this.$emit("input",i,this.id)}else this.$emit("input",null,this.id);this.closeOnSelect&&e&&this.deactivate()}},removeLastElement:function(){-1===this.blockKeys.indexOf("Delete")&&0===this.search.length&&Array.isArray(this.internalValue)&&this.removeElement(this.internalValue[this.internalValue.length-1],!1)},activate:function(){var t=this;this.isOpen||this.disabled||(this.adjustPosition(),this.groupValues&&0===this.pointer&&this.filteredOptions.length&&(this.pointer=1),this.isOpen=!0,this.searchable?(this.preserveSearch||(this.search=""),this.$nextTick(function(){return t.$refs.search.focus()})):this.$el.focus(),this.$emit("open",this.id))},deactivate:function(){this.isOpen&&(this.isOpen=!1,this.searchable?this.$refs.search.blur():this.$el.blur(),this.preserveSearch||(this.search=""),this.$emit("close",this.getValue(),this.id))},toggle:function(){this.isOpen?this.deactivate():this.activate()},adjustPosition:function(){if("undefined"!=typeof window){var t=this.$el.getBoundingClientRect().top,e=window.innerHeight-this.$el.getBoundingClientRect().bottom;e>this.maxHeight||e>t||"below"===this.openDirection||"bottom"===this.openDirection?(this.prefferedOpenDirection="below",this.optimizedHeight=Math.min(e-40,this.maxHeight)):(this.prefferedOpenDirection="above",this.optimizedHeight=Math.min(t-40,this.maxHeight))}}}}},function(t,e,n){"use strict";var i=n(59);n.n(i);e.a={data:function(){return{pointer:0,pointerDirty:!1}},props:{showPointer:{type:Boolean,default:!0},optionHeight:{type:Number,default:40}},computed:{pointerPosition:function(){return this.pointer*this.optionHeight},visibleElements:function(){return this.optimizedHeight/this.optionHeight}},watch:{filteredOptions:function(){this.pointerAdjust()},isOpen:function(){this.pointerDirty=!1}},methods:{optionHighlight:function(t,e){return{"multiselect__option--highlight":t===this.pointer&&this.showPointer,"multiselect__option--selected":this.isSelected(e)}},groupHighlight:function(t,e){var n=this;if(!this.groupSelect)return["multiselect__option--disabled"];var i=this.options.find(function(t){return t[n.groupLabel]===e.$groupLabel});return[this.groupSelect?"multiselect__option--group":"multiselect__option--disabled",{"multiselect__option--highlight":t===this.pointer&&this.showPointer},{"multiselect__option--group-selected":this.wholeGroupSelected(i)}]},addPointerElement:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"Enter",e=t.key;this.filteredOptions.length>0&&this.select(this.filteredOptions[this.pointer],e),this.pointerReset()},pointerForward:function(){this.pointer0?(this.pointer--,this.$refs.list.scrollTop>=this.pointerPosition&&(this.$refs.list.scrollTop=this.pointerPosition),this.filteredOptions[this.pointer]&&this.filteredOptions[this.pointer].$isLabel&&!this.groupSelect&&this.pointerBackward()):this.filteredOptions[this.pointer]&&this.filteredOptions[0].$isLabel&&!this.groupSelect&&this.pointerForward(),this.pointerDirty=!0},pointerReset:function(){this.closeOnSelect&&(this.pointer=0,this.$refs.list&&(this.$refs.list.scrollTop=0))},pointerAdjust:function(){this.pointer>=this.filteredOptions.length-1&&(this.pointer=this.filteredOptions.length?this.filteredOptions.length-1:0),this.filteredOptions.length>0&&this.filteredOptions[this.pointer].$isLabel&&!this.groupSelect&&this.pointerForward()},pointerSet:function(t){this.pointer=t,this.pointerDirty=!0}}}},function(t,e){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},function(t,e,n){var i=n(13),r=n(0).document,o=i(r)&&i(r.createElement);t.exports=function(t){return o?r.createElement(t):{}}},function(t,e,n){t.exports=!n(1)&&!n(12)(function(){return 7!=Object.defineProperty(n(42)("div"),"a",{get:function(){return 7}}).a})},function(t,e,n){"use strict";var i=n(25),r=n(23),o=n(49),s=n(6),u=n(2),a=n(24),l=n(79),c=n(27),f=n(86),p=n(7)("iterator"),h=!([].keys&&"next"in[].keys()),d=function(){return this};t.exports=function(t,e,n,v,y,g,b){l(n,e,v);var m,_,x,w=function(t){if(!h&&t in P)return P[t];switch(t){case"keys":case"values":return function(){return new n(this,t)}}return function(){return new n(this,t)}},S=e+" Iterator",O="values"==y,L=!1,P=t.prototype,k=P[p]||P["@@iterator"]||y&&P[y],E=k||w(y),j=y?O?w("entries"):E:void 0,V="Array"==e?P.entries||k:k;if(V&&(x=f(V.call(new t)))!==Object.prototype&&(c(x,S,!0),i||u(x,p)||s(x,p,d)),O&&k&&"values"!==k.name&&(L=!0,E=function(){return k.call(this)}),i&&!b||!h&&!L&&P[p]||s(P,p,E),a[e]=E,a[S]=d,y)if(m={values:O?E:w("values"),keys:g?E:w("keys"),entries:j},b)for(_ in m)_ in P||o(P,_,m[_]);else r(r.P+r.F*(h||L),e,m);return m}},function(t,e,n){var i=n(10),r=n(83),o=n(22),s=n(28)("IE_PROTO"),u=function(){},a=function(){var t,e=n(42)("iframe"),i=o.length;for(e.style.display="none",n(76).appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write(" + + + + +
      + + + +
      + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentAdd.js b/net452/SiteServer.Web/Home/pages/contentAdd.js new file mode 100644 index 000000000..219197f04 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentAdd.js @@ -0,0 +1,336 @@ +var sourceIdUser = -1; +var sourceIdPreview = -99; + +var data = { + pageConfig: null, + pageLoad: false, + pageAlert: null, + pageType: '', + sites: [], + channels: [], + site: {}, + channel: {}, + allGroupNames: [], + allTagNames: [], + styles: [], + allCheckedLevels: [], + returnUrl: utils.getQueryString('returnUrl'), + + contentId: 0, + isColor: false, + isHot: false, + isRecommend: false, + isTop: false, + groupNames: [], + tagNames: [], + linkUrl: '', + addDate: new Date(), + checkedLevel: 0, +}; + +var methods = { + loadSite: function (res) { + this.pageConfig = res.config; + this.sites = res.sites; + this.channels = res.channels; + this.site = res.site; + this.channel = res.channel; + this.allGroupNames = res.allGroupNames; + this.allTagNames = res.allTagNames; + if (this.site && this.channel) { + this.loadContent(res.styles, res.checkedLevels, res.checkedLevel, res.content); + } else { + this.pageType = 'Unauthorized'; + } + }, + + loadChannel: function (res) { + this.loadContent(res.styles, res.checkedLevels, res.checkedLevel, res.value); + }, + + loadContent: function (styles, checkedLevels, checkedLevel, content) { + var $this = this; + + this.styles = []; + for (let i = 0; i < styles.length; i++) { + var style = styles[i]; + if (content.id) { + style.value = content[_.camelCase(style.attributeName)]; + } else { + style.value = style.defaultValue || ''; + } + this.styles.push(style); + } + this.allCheckedLevels = checkedLevels; + + this.contentId = content.id; + this.isTop = content.isTop; + this.isRecommend = content.isRecommend; + this.isHot = content.isHot; + this.isColor = content.isColor; + this.groupNames = []; + if (content.groupNameCollection) { + this.groupNames = content.groupNameCollection.split(','); + } + this.tagNames = []; + if (content.tags) { + this.tagNames = content.tags.split(','); + } + this.linkUrl = content.linkUrl; + this.addDate = content.addDate; + this.checkedLevel = checkedLevel; + + setTimeout(function () { + for (var i = 0; i < $this.styles.length; i++) { + var style = $this.styles[i]; + if (style.inputType === 'TextEditor') { + var editor = UE.getEditor(style.attributeName, { + allowDivTransToP: false, + maximumWords: 99999999 + }); + editor.styleIndex = i; + editor.ready(function () { + editor.addListener("contentChange", function () { + $this.styles[this.styleIndex].value = this.getContent(); + }); + }); + + $('#' + style.attributeName).show(); + } + } + + }, 100); + }, + + getValue: function (attributeName) { + for (var i = 0; i < this.styles.length; i++) { + var style = this.styles[i]; + if (style.attributeName === attributeName) { + return style.value; + } + } + return ''; + }, + + setValue: function (attributeName, value) { + for (var i = 0; i < this.styles.length; i++) { + var style = this.styles[i]; + if (style.attributeName === attributeName) { + style.value = value; + } + } + }, + + onSiteSelect: function (site) { + if (site.id === this.site.id) return; + var $this = this; + this.pageLoad = false; + utils.getConfig({ + pageName: 'contentAdd', + siteId: site.id + }, function (res) { + $this.pageLoad = true; + $this.loadSite(res); + }); + }, + + onChannelSelect: function (channel) { + if (channel.id === this.channel.id) return; + var $this = this; + this.pageLoad = false; + utils.getConfig({ + pageName: 'contentAdd', + siteId: this.site.id, + channelId: channel.id + }, function (res) { + $this.pageLoad = true; + $this.loadChannel(res); + }); + }, + + addTag: function (newTag) { + this.allTagNames.push(newTag); + this.tagNames.push(newTag); + }, + + submit: function (sourceId) { + var $this = this; + + var payload = { + id: this.contentId, + isTop: this.isTop, + isRecommend: this.isRecommend, + isHot: this.isHot, + isColor: this.isColor, + linkUrl: this.linkUrl, + addDate: this.addDate, + groupNameCollection: this.groupNames.join(','), + tags: this.tagNames.join(','), + checkedLevel: this.checkedLevel, + sourceId: sourceId + }; + for (var i = 0; i < this.styles.length; i++) { + var style = this.styles[i]; + payload[style.attributeName] = style.value; + } + + parent.utils.loading(true); + if (sourceId == sourceIdPreview) { + new utils.Api('/v1/contents/' + this.site.id + '/' + this.channel.id) + .post(payload, function (err, res) { + parent.utils.loading(false); + + if (err) { + $this.pageAlert = { + type: 'danger', + html: err.message + }; + return; + } + + var contentId = $this.contentId ? $this.contentId : res.value.id; + window.open(utils.getApiUrl('/preview/' + $this.site.id + '/' + $this.channel.id + '/' + contentId + '?isPreview=true&previewId=' + res.value.id)); + }); + } else if (payload.id) { + new utils.Api('/v1/contents/' + this.site.id + '/' + this.channel.id + '/' + payload.id) + .put(payload, function (err, res) { + parent.utils.loading(false); + + if (err) { + $this.pageAlert = { + type: 'danger', + html: err.message + }; + return; + } + + parent.swal2({ + toast: true, + type: 'success', + title: "稿件修改成功", + showConfirmButton: false, + timer: 3000 + }).then(function () { + parent.location.hash = $this.returnUrl; + }); + }); + } else { + new utils.Api('/v1/contents/' + this.site.id + '/' + this.channel.id) + .post(payload, function (err, res) { + parent.utils.loading(false); + + if (err) { + $this.pageAlert = { + type: 'danger', + html: err.message + }; + return; + } + + $this.pageType = 'success'; + }); + } + }, + + btnLayerClick: function (options) { + this.pageAlert = null; + var url = "pages/contentAddLayer" + + options.name + + ".html?siteId=" + + this.site.id + + "&channelId=" + + this.channel.id; + + if (options.contentId) { + url += "&contentId=" + options.contentId + } + + if (options.args) { + _.forIn(options.args, function (value, key) { + url += "&" + key + "=" + encodeURIComponent(value); + }); + } + + parent.utils.openLayer({ + title: options.title, + url: url, + full: options.full, + width: options.width ? options.width : 700, + height: options.height ? options.height : 500 + }); + }, + + btnImageClick: function (imageUrl) { + top.utils.openImagesLayer([imageUrl]); + }, + + btnContinueAddClick: function () { + location.reload(); + }, + + btnSubmitClick: function () { + var $this = this; + this.pageAlert = null; + + this.$validator.validate().then(function (result) { + if (result) { + $this.submit(sourceIdUser); + } + }); + }, + + btnPreviewClick: function () { + var $this = this; + this.pageAlert = null; + + this.$validator.validate().then(function (result) { + if (result) { + $this.submit(sourceIdPreview); + } + }); + } +}; + +Vue.component("multiselect", window.VueMultiselect.default); +Vue.component("date-picker", window.DatePicker.default); + +var $vue = new Vue({ + el: "#main", + data: data, + methods: methods, + created: function () { + var $this = this; + var siteId = 0; + var channelId = 0; + var contentId = parseInt(utils.getQueryString('contentId') || 0); + if (contentId == 0) { + siteId = parseInt(Cookies.get('SS-USER-SITE-ID') || 0); + channelId = parseInt(Cookies.get('SS-USER-CHANNEL-ID') || 0); + } else { + siteId = parseInt(utils.getQueryString('siteId') || 0); + channelId = parseInt(utils.getQueryString('channelId') || 0); + } + + utils.getConfig({ + pageName: 'contentAdd', + siteId: siteId, + channelId: channelId, + contentId: contentId + }, + function (res) { + if (res.value) { + $this.loadSite(res); + } else { + utils.redirectLogin(); + } + }); + } +}); + +var getValue = function (attributeName) { + return $vue.getValue(attributeName); +} + +var setValue = function (attributeName, value) { + $vue.setValue(attributeName, value); +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentAddLayerImage.html b/net452/SiteServer.Web/Home/pages/contentAddLayerImage.html new file mode 100644 index 000000000..5c1c76514 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentAddLayerImage.html @@ -0,0 +1,132 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentAddLayerImage.js b/net452/SiteServer.Web/Home/pages/contentAddLayerImage.js new file mode 100644 index 000000000..581748496 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentAddLayerImage.js @@ -0,0 +1,185 @@ +var $api = new utils.Api('/home/contentAddLayerImage'); +var $uploadUrl = utils.getApiUrl('/home/contentAddLayerImage'); + +var data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + attributeName: utils.getQueryString('attributeName'), + inputType: utils.getQueryString('inputType'), + pageLoad: false, + pageAlert: null, + file: null, + files: [], + isFix: true, + fixWidth: '300', + fixHeight: '', + isEditor: true, + editorIsFix: true, + editorFixWidth: '500', + editorFixHeight: '', + editorIsLinkToOriginal: false +}; + +var methods = { + loadConfig: function () { + var $this = this; + $this.pageLoad = true; + + $api.get({ + siteId: $this.siteId, + channelId: $this.channelId + }, function (err, res) { + if (err || !res || !res.value) return; + + $this.isFix = res.value.configImageIsFix; + $this.fixWidth = res.value.configImageFixWidth; + $this.fixHeight = res.value.configImageFixHeight; + $this.isEditor = res.value.configImageIsEditor; + $this.editorIsFix = res.value.configImageEditorIsFix; + $this.editorFixWidth = res.value.configImageEditorFixWidth; + $this.editorFixHeight = res.value.configImageEditorFixHeight; + $this.editorIsLinkToOriginal = res.value.configImageEditorIsLinkToOriginal; + + $this.loadUploader(); + }); + }, + loadUploader: function () { + var $this = this; + + var E = Q.event, + Uploader = Q.Uploader; + + var boxDropArea = document.getElementById("drop-area"); + + var uploader = new Uploader({ + url: $uploadUrl + '/actions/upload?siteId=' + $this.siteId + '&channelId=' + $this.channelId + '&userToken=' + utils.getToken(), + target: document.getElementById("drop-area"), + allows: ".gif,.jpg,.jpeg,.bmp,.png,.pneg,.webp", + multiple: $this.inputType === 'TextEditor', + on: { + select: function () { + if ($this.inputType !== 'TextEditor' && $this.files.length > 0) return false; + return true; + }, + add: function (task) { + if (task.disabled) { + return swal2({ + title: '文件错误!', + text: '允许上传的文件格式为:' + this.ops.allows, + type: 'error', + showConfirmButton: false + }); + } + }, + complete: function (task) { + var json = task.json; + if (!json || !json.path || !json.url) { + return swal2({ + title: "图片传失败!", + type: 'error', + showConfirmButton: false + }); + } else { + $this.files.push(json); + } + } + } + }); + + //若浏览器不支持html5上传,则禁止拖拽上传 + if (!Uploader.support.html5 || !uploader.html5) { + boxDropArea.innerHTML = "点击批量上传图片"; + return; + } + + //阻止浏览器默认拖放行为 + E.add(boxDropArea, "dragleave", E.stop); + E.add(boxDropArea, "dragenter", E.stop); + E.add(boxDropArea, "dragover", E.stop); + + E.add(boxDropArea, "drop", function (e) { + E.stop(e); + + //获取文件对象 + var files = e.dataTransfer.files; + + uploader.addList(files); + }); + }, + + del: function (file) { + this.files.splice(this.files.indexOf(file), 1); + }, + + getFilePaths: function () { + var arr = []; + for (var i = 0; i < this.files.length; i++) { + arr.push(this.files[i].path); + } + return arr; + }, + + btnSubmitClick: function () { + var $this = this; + var filePaths = this.getFilePaths().join(','); + if (!filePaths) { + return swal2({ + title: "请选择需要上传的图片!", + type: 'warning', + showConfirmButton: false + }); + } + + top.utils.loading(true); + $api.post({ + siteId: $this.siteId, + channelId: $this.channelId, + isFix: $this.isFix, + fixWidth: $this.fixWidth, + fixHeight: $this.fixHeight, + isEditor: $this.isEditor, + editorIsFix: $this.editorIsFix, + editorFixWidth: $this.editorFixWidth, + editorFixHeight: $this.editorFixHeight, + editorIsLinkToOriginal: $this.editorIsLinkToOriginal, + filePaths: filePaths + }, function (err, res) { + top.utils.loading(false); + if (err || !res || !res.value) return; + + var win = top.getContentWindow(); + var editorAttributeName = $this.attributeName; + + if ($this.inputType != 'TextEditor') { + editorAttributeName = 'Content'; + for (var i = 0; i < res.value.length; i++) { + var val = res.value[i]; + win.setValue($this.attributeName, val); + } + } + + var ue = win.UE.getEditor(editorAttributeName); + if (ue && typeof ue.execCommand === "function") { + for (var i = 0; i < res.editors.length; i++) { + var editor = res.editors[i]; + var html = ''; + if ($this.editorIsFix && $this.editorIsLinkToOriginal) { + html = '' + html + ''; + } + ue.execCommand("insertHTML", html); + } + } + + top.layer.closeAll(); + }); + } +}; + +new Vue({ + el: '#main', + data: data, + methods: methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contents.html b/net452/SiteServer.Web/Home/pages/contents.html new file mode 100644 index 000000000..89580c98c --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contents.html @@ -0,0 +1,270 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + + +
      + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contents.js b/net452/SiteServer.Web/Home/pages/contents.js new file mode 100644 index 000000000..e4b920049 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contents.js @@ -0,0 +1,238 @@ +var $api = new utils.Api('/home/contents'); + +Object.defineProperty(Object.prototype, "getProp", { + value: function (prop) { + var key, self = this; + for (key in self) { + if (key.toLowerCase() == prop.toLowerCase()) { + return self[key]; + } + } + } +}); + +var data = { + pageConfig: null, + pageLoad: false, + pageAlert: null, + pageType: null, + page: 1, + pageContents: [], + count: null, + pages: null, + sites: [], + channels: [], + site: {}, + channel: {}, + permissions: {}, + columns: null, + pageOptions: null, + isAllChecked: false +}; + +var methods = { + load: function (pageConfig, sites, channels, site, channel) { + this.pageConfig = pageConfig; + this.sites = sites; + this.channels = channels; + this.loadChannel(site, channel); + }, + + loadChannel: function (site, channel) { + this.site = site; + this.channel = channel; + if (this.site && this.channel) { + Cookies.set('SS-USER-SITE-ID', this.site.id, { + expires: 7 + }); + Cookies.set('SS-USER-CHANNEL-ID', this.channel.id, { + expires: 7 + }); + + this.loadContents(1); + } else { + this.pageType = 'Unauthorized' + } + }, + + btnAddClick: function () { + parent.location.hash = 'pages/contentAdd.html?siteId=' + this.site.id + '&channelId=' + this.channel.id + '&returnUrl=' + encodeURIComponent(parent.location.hash); + }, + + btnEditClick: function (contentId) { + parent.location.hash = 'pages/contentAdd.html?siteId=' + this.site.id + '&channelId=' + this.channel.id + '&contentId=' + contentId + '&returnUrl=' + encodeURIComponent(parent.location.hash); + }, + + btnLayerClick: function (options) { + event.stopPropagation(); + + this.pageAlert = null; + var url = "pages/contentsLayer" + + options.name + + ".html?siteId=" + + this.site.id + + "&channelId=" + + this.channel.id; + if (options.withContents) { + if (this.selectedContentIds.length === 0) return; + url += "&contentIds=" + this.selectedContentIds.join(",") + } else if (options.contentId) { + url += "&contentId=" + options.contentId + } + url += '&returnUrl=' + encodeURIComponent(parent.location.hash); + + parent.utils.openLayer({ + title: options.title, + url: url, + full: options.full, + width: options.width ? options.width : 700, + height: options.height ? options.height : 500 + }); + }, + + toggleChecked: function (content) { + content.isSelected = !content.isSelected; + if (!content.isSelected) { + this.isAllChecked = false; + } + }, + + selectAll: function () { + this.isAllChecked = !this.isAllChecked; + for (var i = 0; i < this.pageContents.length; i++) { + this.pageContents[i].isSelected = this.isAllChecked; + } + }, + + loadFirstPage: function () { + if (this.page === 1) return; + this.loadContents(1); + }, + + loadPrevPage: function () { + if (this.page - 1 <= 0) return; + this.loadContents(this.page - 1); + }, + + loadNextPage: function () { + if (this.page + 1 > this.pages) return; + this.loadContents(this.page + 1); + }, + + loadLastPage: function () { + if (this.page + 1 > this.pages) return; + this.loadContents(this.pages); + }, + + onSiteSelect(site) { + if (site.id === this.site.id) return; + var $this = this; + this.pageLoad = false; + utils.getConfig({ + pageName: 'contents', + siteId: site.id + }, function (res) { + $this.pageLoad = true; + $this.load(res.value, res.sites, res.channels, res.site, res.channel); + }); + }, + + onChannelSelect(channel) { + if (channel.id === this.channel.id) return; + this.loadChannel(this.site, channel); + this.loadContents(1); + }, + + onPageSelect(option) { + this.loadContents(option); + }, + + loadContents: function (page) { + var $this = this; + + if ($this.pageLoad) { + parent.utils.loading(true); + } + + $api.get({ + siteId: $this.site.id, + channelId: $this.channel.id, + page: page + }, + function (err, res) { + if ($this.pageLoad) { + parent.utils.loading(false); + parent.utils.scrollToTop(); + } else { + $this.pageLoad = true; + } + + if (err) { + $this.pageAlert = { + type: 'danger', + html: err.message + }; + return; + } + + $this.permissions = res.permissions; + $this.columns = res.columns; + + var pageContents = []; + for (var i = 0; i < res.value.length; i++) { + + var content = _.assign({}, res.value[i], { + isSelected: false + }); + pageContents.push(content); + } + $this.pageContents = pageContents; + $this.count = res.count; + $this.pages = res.pages; + $this.page = page; + $this.pageOptions = []; + for (var i = 1; i <= $this.pages; i++) { + $this.pageOptions.push(i); + } + } + ); + } +}; + +Vue.component("multiselect", window.VueMultiselect.default); + +var $vue = new Vue({ + el: "#main", + data: data, + methods: methods, + computed: { + selectedContentIds: function () { + var retval = []; + if (this.pageContents) { + for (var i = 0; i < this.pageContents.length; i++) { + if (this.pageContents[i].isSelected) { + retval.push(this.pageContents[i].id); + } + } + } + return retval; + } + }, + created: function () { + var $this = this; + var siteId = parseInt(utils.getQueryString('siteId') || Cookies.get('SS-USER-SITE-ID') || 0); + var channelId = parseInt(utils.getQueryString('channelId') || Cookies.get('SS-USER-CHANNEL-ID') || 0); + + utils.getConfig({ + pageName: 'contents', + siteId: siteId, + channelId: channelId + }, function (res) { + if (res.value) { + $this.load(res.config, res.sites, res.channels, res.site, res.channel); + } else { + utils.redirectLogin(); + } + }); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerArrange.html b/net452/SiteServer.Web/Home/pages/contentsLayerArrange.html new file mode 100644 index 000000000..9301ba81e --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerArrange.html @@ -0,0 +1,70 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerArrange.js b/net452/SiteServer.Web/Home/pages/contentsLayerArrange.js new file mode 100644 index 000000000..7f9b3adf6 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerArrange.js @@ -0,0 +1,42 @@ +var $api = new utils.Api('/home/contentsLayerArrange'); + +var data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + pageLoad: false, + pageAlert: null, + attributeName: 'Id', + isDesc: true +}; + +var methods = { + loadConfig: function () { + this.pageLoad = true; + }, + btnSubmitClick: function () { + var $this = this; + + parent.utils.loading(true); + $api.post({ + siteId: $this.siteId, + channelId: $this.channelId, + attributeName: $this.attributeName, + isDesc: $this.isDesc + }, + function (err, res) { + if (err || !res || !res.value) return; + + parent.location.reload(true); + } + ); + } +}; + +new Vue({ + el: '#main', + data: data, + methods: methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerAttributes.html b/net452/SiteServer.Web/Home/pages/contentsLayerAttributes.html new file mode 100644 index 000000000..47cc46793 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerAttributes.html @@ -0,0 +1,96 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerAttributes.js b/net452/SiteServer.Web/Home/pages/contentsLayerAttributes.js new file mode 100644 index 000000000..19e81f0d5 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerAttributes.js @@ -0,0 +1,52 @@ +var $api = new utils.Api('/home/contentsLayerAttributes'); + +var data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentIds: utils.getQueryString('contentIds'), + pageLoad: false, + pageAlert: null, + pageType: 'setAttributes', + isRecommend: false, + isHot: false, + isColor: false, + isTop: false, + hits: 0 +}; + +var methods = { + loadConfig: function () { + this.pageLoad = true; + }, + btnSubmitClick: function () { + var $this = this; + + parent.utils.loading(true); + $api.post({ + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds, + pageType: $this.pageType, + isRecommend: $this.isRecommend, + isHot: $this.isHot, + isColor: $this.isColor, + isTop: $this.isTop, + hits: $this.hits + }, + function (err, res) { + if (err || !res || !res.value) return; + + parent.location.reload(true); + } + ); + } +}; + +new Vue({ + el: '#main', + data: data, + methods: methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerCheck.html b/net452/SiteServer.Web/Home/pages/contentsLayerCheck.html new file mode 100644 index 000000000..c2cf5341a --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerCheck.html @@ -0,0 +1,102 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerCheck.js b/net452/SiteServer.Web/Home/pages/contentsLayerCheck.js new file mode 100644 index 000000000..303b79d90 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerCheck.js @@ -0,0 +1,90 @@ +var $api = new utils.Api('/home/contentsLayerCheck'); + +var data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentIds: utils.getQueryString('contentIds'), + pageLoad: false, + pageAlert: null, + contents: null, + description: '', + checkedLevels: null, + allChannels: null, + channels: [], + isChannelLoading: false, + checkedLevel: null, + isTranslate: false, + translateChannel: null, + reasons: null +}; + +var methods = { + loadConfig: function () { + var $this = this; + + $api.get({ + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds + }, + function (err, res) { + if (err || !res || !res.value) return; + + $this.contents = res.value; + $this.checkedLevels = res.checkedLevels; + $this.checkedLevel = res.checkedLevel; + $this.channels = $this.allChannels = res.allChannels; + $this.pageAlert = { + type: 'warning', + html: '此操作将审核以下 ' + + $this.contents.length + + ' 篇内容,确定吗?' + }; + $this.pageLoad = true; + } + ); + }, + asyncFind: function (query) { + this.isChannelLoading = true; + this.channels = []; + for (var i = 0; i < this.allChannels.length; i++) { + var channel = this.allChannels[i]; + if (channel.value.indexOf(query) !== -1) { + this.channels.push(channel); + } + } + this.isChannelLoading = false; + }, + btnSubmitClick: function () { + var $this = this; + + parent.utils.loading(true); + $api.post({ + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds, + checkedLevel: $this.checkedLevel, + isTranslate: $this.isTranslate, + translateChannelId: $this.translateChannel ? + $this.translateChannel.key : 0, + reasons: $this.reasons + }, + function (err, res) { + if (err || !res || !res.value) return; + + parent.location.reload(true); + } + ); + } +}; + +Vue.component('multiselect', window.VueMultiselect.default); + +new Vue({ + el: '#main', + data: data, + methods: methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerColumns.html b/net452/SiteServer.Web/Home/pages/contentsLayerColumns.html new file mode 100644 index 000000000..69ea64688 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerColumns.html @@ -0,0 +1,69 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerColumns.js b/net452/SiteServer.Web/Home/pages/contentsLayerColumns.js new file mode 100644 index 000000000..1ee0313cb --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerColumns.js @@ -0,0 +1,59 @@ +var $api = new utils.Api('/home/contentsLayerColumns'); + +var data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + pageLoad: false, + pageAlert: null, + attributes: null, + attributeNames: [] +}; + +var methods = { + loadConfig: function () { + var $this = this; + $api.get({ + siteId: $this.siteId, + channelId: $this.channelId + }, + function (err, res) { + if (err || !res || !res.value) return; + + $this.attributes = res.value; + $this.attributeNames = []; + for (var i = 0; i < $this.attributes.length; i++) { + var attribute = $this.attributes[i]; + if (attribute.selected) { + $this.attributeNames.push(attribute.value); + } + } + $this.pageLoad = true; + } + ); + }, + btnSubmitClick: function () { + var $this = this; + + parent.utils.loading(true); + $api.post({ + siteId: $this.siteId, + channelId: $this.channelId, + attributeNames: $this.attributeNames.join(',') + }, + function (err, res) { + if (err || !res || !res.value) return; + + parent.location.reload(true); + } + ); + } +}; + +new Vue({ + el: '#main', + data: data, + methods: methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerCopy.html b/net452/SiteServer.Web/Home/pages/contentsLayerCopy.html new file mode 100644 index 000000000..8aefac411 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerCopy.html @@ -0,0 +1,113 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerCopy.js b/net452/SiteServer.Web/Home/pages/contentsLayerCopy.js new file mode 100644 index 000000000..324037fb9 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerCopy.js @@ -0,0 +1,95 @@ +var $api = new utils.Api('/home/contentsLayerCopy'); +var $apiChannels = new utils.Api('/home/contentsLayerCopy/actions/getChannels'); + +var data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentIds: utils.getQueryString('contentIds'), + pageLoad: false, + pageAlert: null, + contents: null, + sites: [], + channels: [], + site: {}, + channel: null, + copyType: 'Copy', + isSubmit: false +}; + +var methods = { + loadConfig: function () { + var $this = this; + + $api.get({ + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds + }, + function (err, res) { + if (err || !res || !res.value) return; + + $this.contents = res.value; + $this.sites = res.sites; + $this.channels = res.channels; + $this.site = res.site; + + $this.pageLoad = true; + } + ); + }, + + onSiteSelect(site) { + if (site.id === this.site.id) return; + this.site = site; + var $this = this; + + parent.utils.loading(true); + $apiChannels.get({ + siteId: this.site.id + }, + function (err, res) { + parent.utils.loading(false); + if (err || !res || !res.value) return; + + $this.channels = res.value; + $this.channel = null; + } + ); + }, + + onChannelSelect(channel) { + this.channel = channel; + }, + + btnSubmitClick: function () { + var $this = this; + this.isSubmit = true; + if (!this.channel) return; + + parent.utils.loading(true); + $api.post({ + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds, + targetSiteId: $this.site.id, + targetChannelId: $this.channel.id + }, + function (err, res) { + if (err || !res || !res.value) return; + + parent.location.reload(true); + } + ); + } +}; + +Vue.component("multiselect", window.VueMultiselect.default); + +new Vue({ + el: '#main', + data: data, + methods: methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerCut.html b/net452/SiteServer.Web/Home/pages/contentsLayerCut.html new file mode 100644 index 000000000..2c0983165 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerCut.html @@ -0,0 +1,92 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerCut.js b/net452/SiteServer.Web/Home/pages/contentsLayerCut.js new file mode 100644 index 000000000..25c32686d --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerCut.js @@ -0,0 +1,100 @@ +var $api = new utils.Api('/home/contentsLayerCut'); +var $apiChannels = new utils.Api('/home/contentsLayerCut/actions/getChannels'); + +var data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentIds: utils.getQueryString('contentIds'), + pageLoad: false, + pageAlert: null, + contents: null, + sites: [], + channels: [], + site: {}, + channel: null, + isSubmit: false +}; + +var methods = { + loadConfig: function () { + var $this = this; + + $api.get({ + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds + }, + function (err, res) { + if (err || !res || !res.value) return; + + $this.contents = res.value; + $this.sites = res.sites; + $this.channels = res.channels; + $this.site = res.site; + + $this.pageAlert = { + type: 'danger', + html: '此操作将把以下 ' + + $this.contents.length + + ' 篇内容转移至指定栏目,确定吗?' + }; + $this.pageLoad = true; + } + ); + }, + + onSiteSelect(site) { + if (site.id === this.site.id) return; + this.site = site; + var $this = this; + + parent.utils.loading(true); + $apiChannels.get({ + siteId: this.site.id + }, + function (err, res) { + parent.utils.loading(false); + if (err || !res || !res.value) return; + + $this.channels = res.value; + $this.channel = null; + } + ); + }, + + onChannelSelect(channel) { + this.channel = channel; + }, + + btnSubmitClick: function () { + var $this = this; + this.isSubmit = true; + if (!this.channel) return; + + parent.utils.loading(true); + $api.post({ + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds, + targetSiteId: $this.site.id, + targetChannelId: $this.channel.id + }, + function (err, res) { + if (err || !res || !res.value) return; + + parent.location.reload(true); + } + ); + } +}; + +Vue.component("multiselect", window.VueMultiselect.default); + +new Vue({ + el: '#main', + data: data, + methods: methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerDelete.html b/net452/SiteServer.Web/Home/pages/contentsLayerDelete.html new file mode 100644 index 000000000..4b3a0eeed --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerDelete.html @@ -0,0 +1,85 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerDelete.js b/net452/SiteServer.Web/Home/pages/contentsLayerDelete.js new file mode 100644 index 000000000..cf0f8cd0f --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerDelete.js @@ -0,0 +1,62 @@ +var $api = new utils.Api('/home/contentsLayerDelete'); + +var data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentIds: utils.getQueryString('contentIds'), + pageLoad: false, + pageAlert: null, + contents: null, + isRetainFiles: false +}; + +var methods = { + loadConfig: function () { + var $this = this; + + $api.get({ + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds + }, + function (err, res) { + if (err || !res || !res.value) return; + + $this.contents = res.value; + $this.pageAlert = { + type: 'danger', + html: '此操作将把以下 ' + + $this.contents.length + + ' 篇内容放入回收站,确定吗?' + }; + $this.pageLoad = true; + } + ); + }, + btnSubmitClick: function () { + var $this = this; + + parent.utils.loading(true); + $api.post({ + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds, + isRetainFiles: $this.isRetainFiles + }, + function (err, res) { + if (err || !res || !res.value) return; + + parent.location.reload(true); + } + ); + } +}; + +new Vue({ + el: '#main', + data: data, + methods: methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerExport.html b/net452/SiteServer.Web/Home/pages/contentsLayerExport.html new file mode 100644 index 000000000..11a981ade --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerExport.html @@ -0,0 +1,119 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerExport.js b/net452/SiteServer.Web/Home/pages/contentsLayerExport.js new file mode 100644 index 000000000..a0a959dde --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerExport.js @@ -0,0 +1,129 @@ +var $api = new utils.Api('/home/contentsLayerExport'); + +var data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + pageLoad: false, + pageAlert: null, + columns: null, + checkedLevels: null, + checkedLevel: null, + + exportType: 'zip', + isAllCheckedLevel: true, + checkedLevelKeys: [], + isAllDate: true, + startDate: new Date(new Date().setDate(new Date().getDate() - 30)), + endDate: new Date(), + isAllColumns: false, + columnNames: [] +}; + +var methods = { + loadConfig: function () { + var $this = this; + $api.get({ + siteId: $this.siteId, + channelId: $this.channelId + }, + function (err, res) { + if (err || !res || !res.value) return; + + $this.columns = res.value; + $this.columnNames = []; + for (var i = 0; i < $this.columns.length; i++) { + var attribute = $this.columns[i]; + if (attribute.isList) { + $this.columnNames.push(attribute.attributeName); + } + } + $this.checkedLevels = res.checkedLevels; + for (var i = 0; i < $this.checkedLevels.length; i++) { + var checkedLevel = $this.checkedLevels[i]; + $this.checkedLevelKeys.push(checkedLevel.key); + } + $this.checkedLevel = res.checkedLevel; + $this.pageLoad = true; + } + ); + }, + + btnIsAllCheckedLevelClick: function () { + this.isAllCheckedLevel = !this.isAllCheckedLevel; + this.checkedLevelKeys = []; + if (this.isAllCheckedLevel) { + for (var i = 0; i < this.checkedLevels.length; i++) { + var checkedLevel = this.checkedLevels[i]; + this.checkedLevelKeys.push(checkedLevel.key); + } + } + }, + + btnIsAllColumnsClick: function () { + this.isAllColumns = !this.isAllColumns; + this.columnNames = ['Title']; + if (this.isAllColumns) { + for (var i = 0; i < this.columns.length; i++) { + var column = this.columns[i]; + this.columnNames.push(column.attributeName); + } + } + }, + + btnSubmitClick: function () { + var $this = this; + this.pageAlert = null; + + if (this.checkedLevelKeys.length === 0) { + return this.pageAlert = { + type: 'danger', + html: '必须至少选择一项内容状态' + }; + } + + parent.utils.loading(true); + $api.post({ + siteId: $this.siteId, + channelId: $this.channelId, + exportType: $this.exportType, + isAllCheckedLevel: $this.isAllCheckedLevel, + checkedLevelKeys: $this.checkedLevelKeys, + isAllDate: $this.isAllDate, + startDate: $this.startDate, + endDate: $this.endDate, + columnNames: $this.columnNames + }, + function (err, res) { + parent.utils.loading(false); + + if (err) { + return $this.pageAlert = { + type: 'danger', + html: res.message + }; + } + + if (res.isSuccess) { + window.open(res.value); + parent.layer.closeAll(); + } else { + return $this.pageAlert = { + type: 'danger', + html: '没有符合条件的内容,请重新选择导出条件' + }; + } + } + ); + } +}; + +Vue.component("date-picker", window.DatePicker.default); + +new Vue({ + el: '#main', + data: data, + methods: methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerGroup.html b/net452/SiteServer.Web/Home/pages/contentsLayerGroup.html new file mode 100644 index 000000000..c7dbb66e8 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerGroup.html @@ -0,0 +1,90 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerGroup.js b/net452/SiteServer.Web/Home/pages/contentsLayerGroup.js new file mode 100644 index 000000000..2fa889872 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerGroup.js @@ -0,0 +1,62 @@ +var $api = new utils.Api('/home/contentsLayerGroup'); + +var data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentIds: utils.getQueryString('contentIds'), + pageLoad: false, + pageAlert: null, + pageType: 'setGroup', + groupNames: null, + selected: [], + groupName: '', + description: '' +}; + +var methods = { + loadConfig: function () { + var $this = this; + + $api.get({ + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds + }, + function (err, res) { + if (err || !res || !res.value) return; + + $this.groupNames = res.value; + $this.pageLoad = true; + } + ); + }, + btnSubmitClick: function () { + var $this = this; + + parent.utils.loading(true); + $api.post({ + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds, + pageType: $this.pageType, + groupNames: $this.selected.join(','), + groupName: $this.groupName, + description: $this.description + }, + function (err, res) { + if (err || !res || !res.value) return; + + parent.location.reload(true); + } + ); + } +}; + +new Vue({ + el: '#main', + data: data, + methods: methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerImport.html b/net452/SiteServer.Web/Home/pages/contentsLayerImport.html new file mode 100644 index 000000000..523e2ded2 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerImport.html @@ -0,0 +1,103 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerImport.js b/net452/SiteServer.Web/Home/pages/contentsLayerImport.js new file mode 100644 index 000000000..b9af8b3a6 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerImport.js @@ -0,0 +1,156 @@ +var $api = new utils.Api('/home/contentsLayerImport'); +var $uploadUrl = utils.getApiUrl('/home/contentsLayerImport'); + +var data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + pageLoad: false, + pageAlert: null, + checkedLevels: null, + + importType: 'zip', + file: null, + files: [], + checkedLevel: null, + isOverride: false +}; + +var methods = { + loadConfig: function () { + var $this = this; + $this.pageLoad = true; + + $api.get({ + siteId: $this.siteId, + channelId: $this.channelId + }, + function (err, res) { + if (err || !res || !res.value) return; + + $this.checkedLevels = res.checkedLevels; + $this.checkedLevel = res.value; + $this.loadUploader(); + } + ); + }, + + loadUploader: function () { + var $this = this; + + var E = Q.event, + Uploader = Q.Uploader; + + var boxDropArea = document.getElementById("drop-area"); + + var uploader = new Uploader({ + url: $uploadUrl + '/actions/upload?siteId=' + $this.siteId + '&channelId=' + $this.channelId + '&userToken=' + utils.getToken(), + target: document.getElementById("drop-area"), + allows: ".zip,.csv,.txt", + on: { + add: function (task) { + if (task.ext != '.' + $this.importType) { + swal2({ + title: '文件错误!', + text: '允许上传的文件格式为:.' + $this.importType, + type: 'error', + showConfirmButton: false + }); + return false; + } + }, + complete: function (task) { + var json = task.json; + if (!json || json.ret != 1) { + return swal2({ + title: "文件上传失败!", + type: 'error', + showConfirmButton: false + }); + } + + if (json && json.fileName) { + $this.files.push(json); + } + } + } + }); + + //若浏览器不支持html5上传,则禁止拖拽上传 + if (!Uploader.support.html5 || !uploader.html5) { + boxDropArea.innerHTML = "点击批量上传文件"; + return; + } + + //阻止浏览器默认拖放行为 + E.add(boxDropArea, "dragleave", E.stop); + E.add(boxDropArea, "dragenter", E.stop); + E.add(boxDropArea, "dragover", E.stop); + + E.add(boxDropArea, "drop", function (e) { + E.stop(e); + + //获取文件对象 + var files = e.dataTransfer.files; + + uploader.addList(files); + }); + }, + + del: function (file) { + this.files.splice(this.files.indexOf(file), 1); + }, + + getFileNames: function () { + var arr = []; + for (var i = 0; i < this.files.length; i++) { + arr.push(this.files[i].fileName); + } + return arr; + }, + + btnSubmitClick: function () { + var $this = this; + this.pageAlert = null; + + var fileNames = this.getFileNames().join(','); + if (!fileNames) { + return swal2({ + title: "请选择需要导入的文件!", + type: 'warning', + showConfirmButton: false + }); + } + + parent.utils.loading(true); + $api.post({ + siteId: $this.siteId, + channelId: $this.channelId, + importType: $this.importType, + fileNames: $this.getFileNames(), + checkedLevel: $this.checkedLevel, + isOverride: $this.isOverride + }, + function (err, res) { + parent.utils.loading(false); + + if (err) { + return $this.pageAlert = { + type: 'danger', + html: res.message + }; + } + + parent.location.reload(true); + } + ); + } +}; + +new Vue({ + el: '#main', + data: data, + methods: methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerState.html b/net452/SiteServer.Web/Home/pages/contentsLayerState.html new file mode 100644 index 000000000..896d7b5a1 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerState.html @@ -0,0 +1,80 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerState.js b/net452/SiteServer.Web/Home/pages/contentsLayerState.js new file mode 100644 index 000000000..7655d9222 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerState.js @@ -0,0 +1,56 @@ +var $api = new utils.Api('/home/contentsLayerState'); + +var data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentId: parseInt(utils.getQueryString('contentId')), + pageLoad: false, + pageAlert: null, + contentChecks: null, + title: null, + checkState: null +}; + +var methods = { + loadConfig: function () { + var $this = this; + + $api.get({ + siteId: $this.siteId, + channelId: $this.channelId, + contentId: $this.contentId + }, + function (err, res) { + if (err || !res || !res.value) return; + + $this.contentChecks = res.value; + $this.title = res.title; + $this.checkState = res.checkState; + + $this.pageLoad = true; + } + ); + }, + btnSubmitClick: function () { + window.parent.layer.closeAll(); + window.parent.utils.openLayer({ + title: '审核内容', + url: 'contentsLayerCheck.cshtml?siteId=' + + this.siteId + + '&channelId=' + + this.channelId + + '&contentIds=' + + this.contentId, + full: true + }); + } +}; + +new Vue({ + el: '#main', + data: data, + methods: methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerTaxis.html b/net452/SiteServer.Web/Home/pages/contentsLayerTaxis.html new file mode 100644 index 000000000..331815441 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerTaxis.html @@ -0,0 +1,73 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerTaxis.js b/net452/SiteServer.Web/Home/pages/contentsLayerTaxis.js new file mode 100644 index 000000000..cdcfefc4e --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerTaxis.js @@ -0,0 +1,44 @@ +var $api = new utils.Api('/home/contentsLayerTaxis'); + +var data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentIds: utils.getQueryString('contentIds'), + pageLoad: false, + pageAlert: null, + isUp: true, + taxis: 1 +}; + +var methods = { + loadConfig: function () { + this.pageLoad = true; + }, + btnSubmitClick: function () { + var $this = this; + + parent.utils.loading(true); + $api.post({ + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds, + isUp: $this.isUp, + taxis: $this.taxis + }, + function (err, res) { + if (err || !res || !res.value) return; + + parent.location.reload(true); + } + ); + } +}; + +new Vue({ + el: '#main', + data: data, + methods: methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerView.html b/net452/SiteServer.Web/Home/pages/contentsLayerView.html new file mode 100644 index 000000000..88df9ff8c --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerView.html @@ -0,0 +1,96 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerView.js b/net452/SiteServer.Web/Home/pages/contentsLayerView.js new file mode 100644 index 000000000..e8484e5f1 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerView.js @@ -0,0 +1,54 @@ +var $api = new utils.Api('/home/contentsLayerView'); + +Object.defineProperty(Object.prototype, 'getProp', { + value: function (prop) { + var key, + self = this; + for (key in self) { + if (key.toLowerCase() == prop.toLowerCase()) { + return self[key]; + } + } + } +}); + +var data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentId: parseInt(utils.getQueryString('contentId')), + pageLoad: false, + pageAlert: null, + content: null, + channelName: null, + attributes: null +}; + +var methods = { + loadConfig: function () { + var $this = this; + + $api.get({ + siteId: $this.siteId, + channelId: $this.channelId, + contentId: $this.contentId + }, + function (err, res) { + if (err || !res || !res.value) return; + + $this.content = res.value; + $this.channelName = res.channelName; + $this.attributes = res.attributes; + $this.pageLoad = true; + } + ); + } +}; + +new Vue({ + el: '#main', + data: data, + methods: methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerWord.html b/net452/SiteServer.Web/Home/pages/contentsLayerWord.html new file mode 100644 index 000000000..60adb2ae2 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerWord.html @@ -0,0 +1,104 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/contentsLayerWord.js b/net452/SiteServer.Web/Home/pages/contentsLayerWord.js new file mode 100644 index 000000000..4e88692bf --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/contentsLayerWord.js @@ -0,0 +1,156 @@ +var $api = new utils.Api('/home/contentsLayerWord'); +var $uploadUrl = utils.getApiUrl('/home/contentsLayerWord'); + +var data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + returnUrl: utils.getQueryString('returnUrl'), + pageLoad: false, + pageAlert: null, + file: null, + files: [], + isFirstLineTitle: false, + isFirstLineRemove: true, + isClearFormat: true, + isFirstLineIndent: true, + isClearFontSize: true, + isClearFontFamily: true, + isClearImages: false, + checkedLevels: null, + checkedLevel: null +}; + +var methods = { + loadConfig: function () { + var $this = this; + $this.pageLoad = true; + + $api.get({ + siteId: $this.siteId, + channelId: $this.channelId + }, function (err, res) { + if (err || !res || !res.value) return; + + $this.checkedLevels = res.value; + $this.checkedLevel = res.checkedLevel; + + $this.loadUploader(); + }); + }, + loadUploader: function () { + var $this = this; + + var E = Q.event, + Uploader = Q.Uploader; + + var boxDropArea = document.getElementById("drop-area"); + + var uploader = new Uploader({ + url: $uploadUrl + '/actions/upload?siteId=' + $this.siteId + '&channelId=' + $this.channelId + '&userToken=' + utils.getToken(), + target: document.getElementById("drop-area"), + allows: ".doc,.docx", + on: { + add: function (task) { + if (task.disabled) { + return swal2({ + title: '文件错误!', + text: '允许上传的文件格式为:' + this.ops.allows, + type: 'error', + showConfirmButton: false + }); + } + }, + complete: function (task) { + var json = task.json; + if (!json || json.ret != 1) { + return swal2({ + title: "Word 文件上传失败!", + type: 'error', + showConfirmButton: false + }); + } + + if (json && json.fileName) { + $this.files.push(json); + } + } + } + }); + + //若浏览器不支持html5上传,则禁止拖拽上传 + if (!Uploader.support.html5 || !uploader.html5) { + boxDropArea.innerHTML = "点击批量上传Word文件"; + return; + } + + //阻止浏览器默认拖放行为 + E.add(boxDropArea, "dragleave", E.stop); + E.add(boxDropArea, "dragenter", E.stop); + E.add(boxDropArea, "dragover", E.stop); + + E.add(boxDropArea, "drop", function (e) { + E.stop(e); + + //获取文件对象 + var files = e.dataTransfer.files; + + uploader.addList(files); + }); + }, + del: function (file) { + this.files.splice(this.files.indexOf(file), 1); + }, + getFileNames: function () { + var arr = []; + for (var i = 0; i < this.files.length; i++) { + arr.push(this.files[i].fileName); + } + return arr; + }, + btnSubmitClick: function () { + var $this = this; + var fileNames = this.getFileNames().join(','); + if (!fileNames) { + return swal2({ + title: "请选择需要导入的Word文件!", + type: 'warning', + showConfirmButton: false + }); + } + + parent.utils.loading(true); + $api.post({ + siteId: $this.siteId, + channelId: $this.channelId, + isFirstLineTitle: $this.isFirstLineTitle, + isFirstLineRemove: $this.isFirstLineRemove, + isClearFormat: $this.isClearFormat, + isFirstLineIndent: $this.isFirstLineIndent, + isClearFontSize: $this.isClearFontSize, + isClearFontFamily: $this.isClearFontFamily, + isClearImages: $this.isClearImages, + checkedLevel: $this.checkedLevel, + fileNames: fileNames + }, function (err, res) { + if (err || !res || !res.value) return; + + parent.layer.closeAll(); + + var contentIdList = res.value; + if (contentIdList.length === 1) { + parent.location.hash = 'pages/contentAdd.html?siteId=' + $this.siteId + '&channelId=' + $this.channelId + '&contentId=' + contentIdList[0] + '&returnUrl=' + encodeURIComponent($this.returnUrl); + } else { + parent.location.reload(true); + } + }); + } +}; + +new Vue({ + el: '#main', + data: data, + methods: methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/dashboard.html b/net452/SiteServer.Web/Home/pages/dashboard.html new file mode 100644 index 000000000..2b5ca0e7e --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/dashboard.html @@ -0,0 +1,53 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/dashboard.js b/net452/SiteServer.Web/Home/pages/dashboard.js new file mode 100644 index 000000000..b1fc828b6 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/dashboard.js @@ -0,0 +1,23 @@ +new Vue({ + el: '#main', + data: { + pageUser: null, + pageConfig: null + }, + methods: { + load: function (pageUser, pageConfig) { + this.pageUser = pageUser; + this.pageConfig = pageConfig; + } + }, + created: function () { + var $this = this; + utils.getConfig('dashboard', function (res) { + if (res.value) { + $this.load(res.value, res.config); + } else { + utils.redirectLogin(); + } + }); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/login.html b/net452/SiteServer.Web/Home/pages/login.html new file mode 100644 index 000000000..d9ad50896 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/login.html @@ -0,0 +1,129 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + + + + diff --git a/net452/SiteServer.Web/Home/pages/login.js b/net452/SiteServer.Web/Home/pages/login.js new file mode 100644 index 000000000..c12e64e26 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/login.js @@ -0,0 +1,112 @@ +var $url = '/v1/users/actions/login'; +var $urlGetCaptcha = '/v1/captcha/LOGIN-CAPTCHA'; +var $urlCaptchaCheck = '/v1/captcha/LOGIN-CAPTCHA/actions/check'; + +var $api = axios.create({ + baseURL: utils.getApiUrl(), + withCredentials: true +}); + +if (window.top != self) { + window.top.location = self.location; +} + +var data = { + pageConfig: null, + pageSubmit: false, + pageAlert: null, + account: null, + password: null, + isAutoLogin: false, + captcha: null, + captchaUrl: null +}; + +var methods = { + load: function (pageConfig) { + this.pageConfig = pageConfig; + if (this.pageConfig.isHomeBackground && this.pageConfig.homeBackgroundUrl) { + $('body').css({ + 'background-image': 'url(' + this.pageConfig.homeBackgroundUrl + ')', + 'background-size': 'cover' + }); + } + this.reload(); + }, + + reload: function () { + this.captcha = ''; + this.pageSubmit = false; + this.captchaUrl = utils.getApiUrl($urlGetCaptcha) + '?r=' + new Date().getTime(); + }, + + checkCaptcha: function () { + var $this = this; + + utils.loading(true); + $api.post($urlCaptchaCheck, { + captcha: $this.captcha + }).then(function (response) { + var res = response.data; + + $this.login(); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + $this.reload(); + }); + }, + + login: function () { + var $this = this; + + utils.loading(true); + $api.post($url, { + account: $this.account, + password: md5($this.password), + isAutoLogin: $this.isAutoLogin + }).then(function (response) { + var res = response.data; + + utils.setToken(res.accessToken, res.expiresAt); + location.href = utils.getQueryString('returnUrl') || '../index.html'; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + btnLoginClick: function (e) { + e.preventDefault(); + + this.pageSubmit = true; + this.pageAlert = null; + if (!this.account || !this.password || !this.captcha) return; + this.checkCaptcha(); + }, + + btnRegisterClick: function () { + location.href = 'register.html?returnUrl=' + (utils.getQueryString('returnUrl') || 'login.html'); + } +}; + +new Vue({ + el: '#main', + data: data, + directives: { + focus: { + inserted: function (el) { + el.focus() + } + } + }, + methods: methods, + created: function () { + var $this = this; + utils.getConfig('login', function (res) { + $this.load(res.config); + }); + } +}); diff --git a/net452/SiteServer.Web/Home/pages/logout.html b/net452/SiteServer.Web/Home/pages/logout.html new file mode 100644 index 000000000..28936690f --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/logout.html @@ -0,0 +1,41 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + +
      +
      + +

      载入中,请稍后...

      +
      +
      + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/logout.js b/net452/SiteServer.Web/Home/pages/logout.js new file mode 100644 index 000000000..f69206b9f --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/logout.js @@ -0,0 +1,21 @@ +var $api = new utils.Api('/v1/users/actions/logout'); + +if (window.top != self) { + window.top.location = self.location; +} + +new Vue({ + el: '#main', + data: {}, + methods: { + logout: function () { + $api.post(null, function () { + utils.removeToken(); + location.href = utils.getQueryString('returnUrl') || 'login.html'; + }); + } + }, + created: function () { + this.logout(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/profile.html b/net452/SiteServer.Web/Home/pages/profile.html new file mode 100644 index 000000000..7410c1fce --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/profile.html @@ -0,0 +1,137 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/profile.js b/net452/SiteServer.Web/Home/pages/profile.js new file mode 100644 index 000000000..c150ec7f4 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/profile.js @@ -0,0 +1,161 @@ +var data = { + pageUser: null, + pageConfig: null, + pageAlert: null, + avatarUrl: null, + uploadUrl: null, + files: [], + editAvatar: false, + cropper: false, + styles: [] +}; + +var methods = { + load: function (pageUser, pageConfig, styles) { + this.pageUser = pageUser; + this.pageConfig = pageConfig; + this.avatarUrl = this.pageUser.avatarUrl || this.pageConfig.homeDefaultAvatarUrl || '../assets/images/default_avatar.png'; + this.uploadUrl = utils.getApiUrl('/v1/users/' + this.pageUser.id + '/avatar?userToken=' + utils.getToken()); + + this.styles = styles; + for (var i = 0; i < this.styles.length; i++) { + var style = this.styles[i]; + style.value = this.pageUser[_.camelCase(style.attributeName)]; + } + }, + + editSave: function () { + this.pageAlert = null; + this.editAvatar = false; + var oldFile = this.files[0]; + var binStr = atob(this.cropper.getCroppedCanvas().toDataURL(oldFile.type).split(',')[1]); + var arr = new Uint8Array(binStr.length); + for (var i = 0; i < binStr.length; i++) { + arr[i] = binStr.charCodeAt(i); + } + var file = new File([arr], oldFile.name, { + type: oldFile.type + }); + this.$refs.upload.update(oldFile.id, { + file, + type: file.type, + size: file.size, + active: true + }); + }, + + inputFile: function (newFile, oldFile, prevent) { + if (newFile && !oldFile) { + this.$nextTick(function () { + this.editAvatar = true; + }); + } + + if (!newFile && oldFile) { + this.editAvatar = false; + } + + if (newFile && oldFile && newFile.xhr && newFile.success !== oldFile.success) { + this.pageUser = newFile.response.value; + this.avatarUrl = this.pageUser.avatarUrl; + } + }, + + inputFilter: function (newFile, oldFile, prevent) { + if (newFile && !oldFile) { + if (!/\.(gif|jpg|jpeg|png|webp)$/i.test(newFile.name)) { + return prevent(); + } + } + if (newFile && (!oldFile || newFile.file !== oldFile.file)) { + newFile.url = ''; + var URL = window.URL || window.webkitURL; + if (URL && URL.createObjectURL) { + newFile.url = URL.createObjectURL(newFile.file); + } + } + }, + + submit: function () { + var $this = this; + + var payload = {}; + for (var i = 0; i < this.styles.length; i++) { + var style = this.styles[i]; + payload[style.attributeName] = style.value; + } + + parent.utils.loading(true); + new utils.Api('/v1/users/' + this.pageUser.id).put(payload, function (err, res) { + parent.utils.loading(false); + + if (err) { + $this.pageAlert = { + type: 'danger', + html: err.message + }; + return; + } + + $this.pageUser = res.value; + $this.pageAlert = { + type: 'success', + html: '个人资料修改成功' + }; + + utils.scrollToTop(); + }); + }, + + btnSubmitClick: function (e) { + e.preventDefault(); + this.pageAlert = null; + + var $this = this; + this.$validator.validate().then(function (result) { + if (result) { + $this.submit(); + } + }); + } +} + +new Vue({ + el: '#main', + data: data, + components: { + FileUpload: VueUploadComponent + }, + watch: { + editAvatar: function (value) { + if (value) { + this.$nextTick(function () { + if (!this.$refs.editImage) { + return; + } + var cropper = new Cropper(this.$refs.editImage, { + aspectRatio: 1 / 1, + viewMode: 1, + }); + this.cropper = cropper; + }) + } else { + if (this.cropper) { + this.cropper.destroy(); + this.cropper = false; + } + } + } + }, + methods: methods, + created: function () { + var $this = this; + utils.getConfig('profile', function (res) { + if (res.value) { + $this.load(res.value, res.config, res.styles); + } else { + utils.redirectLogin(); + } + }); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/register.html b/net452/SiteServer.Web/Home/pages/register.html new file mode 100644 index 000000000..f9b0cde28 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/register.html @@ -0,0 +1,141 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/register.js b/net452/SiteServer.Web/Home/pages/register.js new file mode 100644 index 000000000..85e30ebd9 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/register.js @@ -0,0 +1,152 @@ +var $api = new utils.Api('/v1/users'); +var $captchaGetUrl = utils.getApiUrl('/v1/captcha/REGISTER-CAPTCHA'); +var $captchaCheckApi = new utils.Api('/v1/captcha/REGISTER-CAPTCHA/actions/check'); + +if (window.top != self) { + window.top.location = self.location; +} + +var data = { + pageConfig: null, + pageAlert: null, + userName: null, + password: null, + captcha: null, + captchaUrl: null, + styles: [], + groups: [], + groupId: 0, + isAgreement: false, +}; + +var methods = { + load: function (pageConfig, styles, groups) { + this.pageConfig = pageConfig; + if (this.pageConfig.isHomeBackground && this.pageConfig.homeBackgroundUrl) { + $('body').css({ + 'background-image': 'url(' + this.pageConfig.homeBackgroundUrl + ')', + 'background-size': 'cover' + }); + } + + if (this.pageConfig.userRegistrationAttributes) { + var userRegistrationAttributes = this.pageConfig.userRegistrationAttributes.split(','); + for (var i = 0; i < styles.length; i++) { + var style = styles[i]; + if (userRegistrationAttributes.indexOf(style.attributeName) !== -1) { + style.value = style.defaultValue; + + this.styles.push(style); + } + } + } + + this.groups = groups; + this.reload(); + }, + reload: function () { + this.captcha = ''; + this.captchaUrl = $captchaGetUrl + '?r=' + new Date().getTime(); + }, + checkCaptcha: function () { + var $this = this; + + utils.loading(true); + $captchaCheckApi.post({ + captcha: $this.captcha + }, function (err) { + utils.loading(false); + + if (err) { + $this.reload(); + $this.pageAlert = { + type: 'danger', + html: err.message + }; + return; + } + + $this.register(); + }); + }, + register: function () { + var $this = this; + + var payload = { + userName: this.userName, + password: this.password, + groupId: this.groupId + }; + for (var i = 0; i < this.styles.length; i++) { + var style = this.styles[i]; + payload[style.attributeName] = style.value; + } + + utils.loading(true); + $api.post(payload, function (err, res) { + utils.loading(false); + if (err) { + $this.reload(); + $this.pageAlert = { + type: 'danger', + html: err.message + }; + return; + } + + if (res.value.isChecked) { + swal2({ + title: "恭喜,账号注册成功", + type: "success", + confirmButtonText: "进入登录页" + }).then(function () { + location.href = 'login.html?returnUrl=' + (utils.getQueryString('returnUrl') || '../index.html'); + }); + } else { + swal2({ + title: "账号注册成功,请等待管理员审核", + type: "success", + confirmButtonText: "进入登录页" + }).then(function () { + location.href = 'login.html?returnUrl=' + (utils.getQueryString('returnUrl') || '../index.html'); + }); + } + }); + }, + btnRegisterClick: function (e) { + e.preventDefault(); + this.pageAlert = null; + + var $this = this; + this.$validator.validate().then(function (result) { + if ($this.pageConfig.isHomeAgreement && !$this.isAgreement) { + return $this.pageAlert = { + type: 'danger', + html: '请勾选' + $this.pageConfig.homeAgreementHtml + }; + } + if (result) { + $this.checkCaptcha(); + } + }); + } +}; + +new Vue({ + el: '#main', + data: data, + directives: { + focus: { + inserted: function (el) { + el.focus() + } + } + }, + methods: methods, + created: function () { + var $this = this; + utils.getConfig('register', function (res) { + $this.load(res.config, res.styles, res.groups); + }); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/settings.html b/net452/SiteServer.Web/Home/pages/settings.html new file mode 100644 index 000000000..156e13f51 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/settings.html @@ -0,0 +1,170 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + + +
      + + +
      + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/Home/pages/settings.js b/net452/SiteServer.Web/Home/pages/settings.js new file mode 100644 index 000000000..461dbf156 --- /dev/null +++ b/net452/SiteServer.Web/Home/pages/settings.js @@ -0,0 +1,214 @@ +var data = { + pageUser: null, + pageConfig: null, + pageAlert: null, + avatarUrl: null, + uploadUrl: null, + files: [], + editAvatar: false, + cropper: false, + accountAlertType: "", + accountAlertMessage: "", + mobile: "", + email: "", + passwordAlertType: "", + passwordAlertMessage: "", + oldPassword: "", + newPassword: "", + confirmPassword: "", + deleteAlertMessage: "" +}; + +var methods = { + load: function (pageUser, pageConfig, styles) { + this.pageUser = pageUser; + this.pageConfig = pageConfig; + this.avatarUrl = this.pageUser.avatarUrl || this.pageConfig.homeDefaultAvatarUrl || '../assets/images/default_avatar.png'; + this.uploadUrl = utils.getApiUrl('/v1/users/' + this.pageUser.id + '/avatar?userToken=' + utils.getToken()); + + this.mobile = this.pageUser.mobile; + this.email = this.pageUser.email; + }, + + editSave: function () { + this.pageAlert = null; + this.editAvatar = false; + var oldFile = this.files[0]; + var binStr = atob(this.cropper.getCroppedCanvas().toDataURL(oldFile.type).split(',')[1]); + var arr = new Uint8Array(binStr.length); + for (var i = 0; i < binStr.length; i++) { + arr[i] = binStr.charCodeAt(i); + } + var file = new File([arr], oldFile.name, { + type: oldFile.type + }); + this.$refs.upload.update(oldFile.id, { + file, + type: file.type, + size: file.size, + active: true + }); + }, + + inputFile: function (newFile, oldFile, prevent) { + if (newFile && !oldFile) { + this.$nextTick(function () { + this.editAvatar = true; + }); + } + + if (!newFile && oldFile) { + this.editAvatar = false; + } + + if (newFile && oldFile && newFile.xhr && newFile.success !== oldFile.success) { + this.pageUser = newFile.response.value; + this.avatarUrl = this.pageUser.avatarUrl; + } + }, + + inputFilter: function (newFile, oldFile, prevent) { + if (newFile && !oldFile) { + if (!/\.(gif|jpg|jpeg|png|webp)$/i.test(newFile.name)) { + return prevent(); + } + } + if (newFile && (!oldFile || newFile.file !== oldFile.file)) { + newFile.url = ''; + var URL = window.URL || window.webkitURL; + if (URL && URL.createObjectURL) { + newFile.url = URL.createObjectURL(newFile.file); + } + } + }, + + updateAccount: function () { + var $this = this; + this.accountAlertMessage = ""; + + this.$validator.validate("account.*").then(function (result) { + if (result) { + parent.utils.loading(true); + new utils.Api('/v1/users/' + $this.pageUser.id).put({ + mobile: $this.mobile, + email: $this.email + }, function (err, res) { + parent.utils.loading(false); + + if (err) { + $this.accountAlertType = "danger"; + $this.accountAlertMessage = err.message; + return; + } + + $this.pageUser = res.value; + $this.accountAlertType = "success"; + $this.accountAlertMessage = '登录账号设置修改成功'; + }); + } + }); + }, + + updatePassword: function () { + var $this = this; + this.passwordAlertMessage = ""; + + this.$validator.validate("password.*").then(function (result) { + if (result) { + parent.utils.loading(true); + new utils.Api('/v1/users/' + $this.pageUser.id + '/actions/resetPassword').post({ + password: $this.oldPassword, + newPassword: $this.newPassword + }, function (err, res) { + parent.utils.loading(false); + + if (err) { + $this.passwordAlertType = "danger"; + $this.passwordAlertMessage = err.message; + return; + } + + $this.pageUser = res.value; + $this.passwordAlertType = "success"; + $this.passwordAlertMessage = '新密码设置成功'; + }); + } + }); + }, + + deleteAccount: function () { + var $this = this; + + swal2({ + title: "永久删除账户", + text: "帐户删除操作无法撤销,此操作会删除您的帐户以及帐户中的所有数据", + type: "warning", + confirmButtonClass: 'btn btn-danger', + confirmButtonText: '永久删除账户', + showCancelButton: true, + cancelButtonText: '取 消' + }).then(function (result) { + if (result.value) { + parent.utils.loading(true); + $this.deleteAlertMessage = ""; + + new utils.Api('/v1/users/' + $this.pageUser.id).delete(null, function (err, res) { + parent.utils.loading(false); + + if (err) { + $this.deleteAlertMessage = error.response.data.message; + return; + } + + swal2({ + title: "账户已关闭", + type: "success", + showConfirmButton: false + }).then(function () { + location.href = 'login.html'; + }); + }); + } + }); + } +} + +new Vue({ + el: '#main', + data: data, + components: { + FileUpload: VueUploadComponent + }, + watch: { + editAvatar: function (value) { + if (value) { + this.$nextTick(function () { + if (!this.$refs.editImage) { + return; + } + var cropper = new Cropper(this.$refs.editImage, { + aspectRatio: 1 / 1, + viewMode: 1, + }); + this.cropper = cropper; + }) + } else { + if (this.cropper) { + this.cropper.destroy(); + this.cropper = false; + } + } + } + }, + methods: methods, + created: function () { + var $this = this; + utils.getConfig('profile', function (res) { + if (res.value) { + $this.load(res.value, res.config, res.styles); + } else { + utils.redirectLogin(); + } + }); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/NamespaceHttpControllerSelector.cs b/net452/SiteServer.Web/NamespaceHttpControllerSelector.cs new file mode 100644 index 000000000..70165cb7d --- /dev/null +++ b/net452/SiteServer.Web/NamespaceHttpControllerSelector.cs @@ -0,0 +1,63 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Web.Http; +using System.Web.Http.Controllers; +using System.Web.Http.Dispatcher; +using System.Web.Http.Routing; + +namespace SiteServer.API +{ + public class NamespaceHttpControllerSelector : IHttpControllerSelector + { + private readonly HttpConfiguration _configuration; + private readonly Lazy> _controllers; + + public NamespaceHttpControllerSelector(HttpConfiguration config) + { + _configuration = config; + _controllers = new Lazy>(InitializeControllerDictionary); + } + + private Dictionary InitializeControllerDictionary() + { + var dictionary = new Dictionary(StringComparer.OrdinalIgnoreCase); + var assembliesResolver = _configuration.Services.GetAssembliesResolver(); + var controllersResolver = _configuration.Services.GetHttpControllerTypeResolver(); + var controllerTypes = controllersResolver.GetControllerTypes(assembliesResolver); + foreach (var t in controllerTypes) + { + dictionary[$"{t.Namespace}.{t.Name}"] = new HttpControllerDescriptor(_configuration, t.Name, t); + } + return dictionary; + } + + public HttpControllerDescriptor SelectController(HttpRequestMessage request) + { + var attributedRoutesData = request.GetRouteData().GetSubRoutes(); + var subRouteData = attributedRoutesData.FirstOrDefault(); + + if (subRouteData != null) + { + return ((HttpActionDescriptor[]) subRouteData.Route.DataTokens["actions"])[0].ControllerDescriptor; + + //var controllerType = ((HttpActionDescriptor[])subRouteData.Route.DataTokens["actions"])[0].ControllerDescriptor.ControllerType; + + //if (_controllers.Value.TryGetValue($"{controllerType.Namespace}.{controllerType.Name}", + // out var controllerDescriptor)) + //{ + // return controllerDescriptor; + //} + } + + throw new HttpResponseException(HttpStatusCode.NotFound); + } + + public IDictionary GetControllerMapping() + { + return _controllers.Value; + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Properties/AssemblyInfo.cs b/net452/SiteServer.Web/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..e5da7888a --- /dev/null +++ b/net452/SiteServer.Web/Properties/AssemblyInfo.cs @@ -0,0 +1,37 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// 有关程序集的常规信息通过下列特性集 +// 控制。更改这些特性值可修改 +// 与程序集关联的信息。 +[assembly: AssemblyTitle("WebApplication")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("WebApplication")] +[assembly: AssemblyCopyright("Copyright © 2017")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] +[assembly: InternalsVisibleTo("SiteServer.API.Tests")] + +// 将 ComVisible 设置为 false 会使此程序集中的类型 +// 对 COM 组件不可见。如果需要 +// 从 COM 访问此程序集中的某个类型,请针对该类型将 ComVisible 特性设置为 true。 +[assembly: ComVisible(false)] + +// 如果此项目向 COM 公开,则下列 GUID 用于 typelib 的 ID +[assembly: Guid("10782686-b998-4e54-b2af-86233c12355d")] + +// 程序集的版本信息由下列四个值组成: +// +// 主版本 +// 次版本 +// 内部版本号 +// 修订版本 +// +// 可以指定所有值,也可以使用“修订号”和“内部版本号”的默认值, +// 方法是按如下所示使用 "*": +[assembly: AssemblyVersion("0.0.0")] +[assembly: AssemblyFileVersion("0.0.0")] +[assembly: AssemblyInformationalVersion("0.0.0")] \ No newline at end of file diff --git a/net452/SiteServer.Web/Rest.cs b/net452/SiteServer.Web/Rest.cs new file mode 100644 index 000000000..b84485349 --- /dev/null +++ b/net452/SiteServer.Web/Rest.cs @@ -0,0 +1,643 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using SiteServer.CMS.Caches; +using SiteServer.CMS.Core; +using SiteServer.CMS.Database.Core; +using SiteServer.CMS.Database.Models; +using SiteServer.CMS.Fx; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Auth; + +namespace SiteServer.API +{ + public class Rest: IRequest + { + private const string AuthKeyUserHeader = "X-SS-USER-TOKEN"; + private const string AuthKeyUserCookie = "SS-USER-TOKEN"; + private const string AuthKeyUserQuery = "userToken"; + public const string AuthKeyAdminHeader = "X-SS-ADMIN-TOKEN"; + private const string AuthKeyAdminCookie = "SS-ADMIN-TOKEN"; + private const string AuthKeyAdminQuery = "adminToken"; + private const string AuthKeyApiHeader = "X-SS-API-KEY"; + private const string AuthKeyApiCookie = "SS-API-KEY"; + private const string AuthKeyApiQuery = "apiKey"; + + public const int AccessTokenExpireDays = 7; + + private readonly HttpRequestMessage _request; + + public Rest(HttpRequestMessage request) + { + _request = request; + + try + { + var apiToken = ApiToken; + if (!string.IsNullOrEmpty(apiToken)) + { + var tokenInfo = AccessTokenManager.GetAccessTokenInfo(apiToken); + if (tokenInfo != null) + { + if (!string.IsNullOrEmpty(tokenInfo.AdminName)) + { + var adminInfo = AdminManager.GetAdminInfoByUserName(tokenInfo.AdminName); + if (adminInfo != null && !adminInfo.Locked) + { + AdminInfo = adminInfo; + IsAdminLoggin = true; + } + } + + IsApiAuthenticated = true; + } + } + + var userToken = UserToken; + if (!string.IsNullOrEmpty(userToken)) + { + var tokenImpl = ParseAccessToken(userToken); + if (tokenImpl.UserId > 0 && !string.IsNullOrEmpty(tokenImpl.UserName)) + { + var userInfo = UserManager.GetUserInfoByUserId(tokenImpl.UserId); + if (userInfo != null && !userInfo.Locked && userInfo.Checked && userInfo.UserName == tokenImpl.UserName) + { + UserInfo = userInfo; + IsUserLoggin = true; + } + } + } + + var adminToken = AdminToken; + if (!string.IsNullOrEmpty(adminToken)) + { + var tokenImpl = ParseAccessToken(adminToken); + if (tokenImpl.UserId > 0 && !string.IsNullOrEmpty(tokenImpl.UserName)) + { + var adminInfo = AdminManager.GetAdminInfoByUserId(tokenImpl.UserId); + if (adminInfo != null && !adminInfo.Locked && adminInfo.UserName == tokenImpl.UserName) + { + AdminInfo = adminInfo; + IsAdminLoggin = true; + } + } + } + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + } + } + + #region Request + + /// + /// Returns an individual HTTP Header value + /// + public string GetHeader(string key) + { + return !_request.Headers.TryGetValues(key, out var keys) ? null : keys.First(); + } + + /// + /// Retrieves an individual cookie from the cookies collection + /// + public string GetCookie(string cookieName) + { + var cookie = _request.Headers.GetCookies(cookieName).FirstOrDefault(); + var value = cookie?[cookieName].Value; + return TranslateUtils.DecryptStringBySecretKey(value); + } + + private Dictionary _queryDict; + public Dictionary QueryDict + { + get + { + if (_queryDict != null) return _queryDict; + + _queryDict = _request.GetQueryNameValuePairs() + .ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase); + + return _queryDict; + } + } + + public bool IsQueryExists(string name) + { + return QueryDict.ContainsKey(name); + } + + public string GetQueryString(string name) + { + if (string.IsNullOrEmpty(name)) return null; + return QueryDict.TryGetValue(name, out var value) ? value : null; + } + + public int GetQueryInt(string name, int defaultValue = 0) + { + return TranslateUtils.ToIntWithNegative(GetQueryString(name), defaultValue); + } + + public decimal GetQueryDecimal(string name, decimal defaultValue = 0) + { + return TranslateUtils.ToDecimalWithNegative(GetQueryString(name), defaultValue); + } + + public bool GetQueryBool(string name, bool defaultValue = false) + { + return TranslateUtils.ToBool(GetQueryString(name), false); + } + + private Dictionary _postDict; + public Dictionary PostDict + { + get + { + if (_postDict != null) return _postDict; + + _postDict = new Dictionary(StringComparer.OrdinalIgnoreCase); + + var json = _request.Content.ReadAsStringAsync().Result; + if (string.IsNullOrEmpty(json)) return _postDict; + + var dict = TranslateUtils.JsonDeserialize>(json); + foreach (var key in dict.Keys) + { + _postDict[key] = dict[key]; + } + + return _postDict; + } + } + + public T GetPostObject() + { + var json = _request.Content.ReadAsStringAsync().Result; + return TranslateUtils.JsonDeserialize(json); + } + + public T GetPostObject(string name) + { + var json = GetPostString(name); + return TranslateUtils.JsonDeserialize(json); + } + + public bool IsPostExists(string name) + { + return PostDict.ContainsKey(name); + } + + private object GetPostObject(string name) + { + if (string.IsNullOrEmpty(name)) return null; + return PostDict.TryGetValue(name, out var value) ? value : null; + } + + public string GetPostString(string name) + { + var value = GetPostObject(name); + switch (value) + { + case null: + return null; + case string s: + return s; + default: + return value.ToString(); + } + } + + public int GetPostInt(string name, int defaultValue = 0) + { + var value = GetPostObject(name); + switch (value) + { + case null: + return 0; + case int _: + return (int)value; + default: + return TranslateUtils.ToIntWithNegative(value.ToString(), defaultValue); + } + } + + public decimal GetPostDecimal(string name, decimal defaultValue = 0) + { + var value = GetPostObject(name); + switch (value) + { + case null: + return 0; + case decimal _: + return (decimal)value; + default: + return TranslateUtils.ToDecimalWithNegative(value.ToString(), defaultValue); + } + } + + public bool GetPostBool(string name, bool defaultValue = false) + { + var value = GetPostObject(name); + switch (value) + { + case null: + return false; + case bool _: + return (bool)value; + default: + return TranslateUtils.ToBool(value.ToString(), defaultValue); + } + } + + public DateTime GetPostDateTime(string name, DateTime defaultValue) + { + var value = GetPostObject(name); + switch (value) + { + case null: + return DateTime.Now; + case DateTime _: + return (DateTime)value; + default: + return TranslateUtils.ToDateTime(value.ToString(), defaultValue); + } + } + + #endregion + + public bool IsApiAuthenticated { get; } + + public bool IsUserLoggin { get; } + + public bool IsAdminLoggin { get; private set; } + + public string ApiToken + { + get + { + var accessTokenStr = string.Empty; + if (!string.IsNullOrEmpty(GetHeader(AuthKeyApiHeader))) + { + accessTokenStr = GetHeader(AuthKeyApiHeader); + } + else if (IsQueryExists(AuthKeyApiQuery)) + { + accessTokenStr = GetQueryString(AuthKeyApiQuery); + } + else if (!string.IsNullOrEmpty(GetCookie(AuthKeyApiCookie))) + { + accessTokenStr = GetCookie(AuthKeyApiCookie); + } + + if (StringUtils.EndsWith(accessTokenStr, TranslateUtils.EncryptStingIndicator)) + { + accessTokenStr = TranslateUtils.DecryptStringBySecretKey(accessTokenStr); + } + + return accessTokenStr; + } + } + + private string UserToken + { + get + { + var accessTokenStr = string.Empty; + if (!string.IsNullOrEmpty(GetCookie(AuthKeyUserCookie))) + { + accessTokenStr = GetCookie(AuthKeyUserCookie); + } + else if (!string.IsNullOrEmpty(GetHeader(AuthKeyUserHeader))) + { + accessTokenStr = GetHeader(AuthKeyUserHeader); + } + else if (IsQueryExists(AuthKeyUserQuery)) + { + accessTokenStr = GetQueryString(AuthKeyUserQuery); + } + + if (StringUtils.EndsWith(accessTokenStr, TranslateUtils.EncryptStingIndicator)) + { + accessTokenStr = TranslateUtils.DecryptStringBySecretKey(accessTokenStr); + } + + return accessTokenStr; + } + } + + public string AdminToken + { + get + { + var accessTokenStr = string.Empty; + if (!string.IsNullOrEmpty(GetCookie(AuthKeyAdminCookie))) + { + accessTokenStr = GetCookie(AuthKeyAdminCookie); + } + else if (!string.IsNullOrEmpty(GetHeader(AuthKeyAdminHeader))) + { + accessTokenStr = GetHeader(AuthKeyAdminHeader); + } + else if (IsQueryExists(AuthKeyAdminQuery)) + { + accessTokenStr = GetQueryString(AuthKeyAdminQuery); + } + + if (StringUtils.EndsWith(accessTokenStr, TranslateUtils.EncryptStingIndicator)) + { + accessTokenStr = TranslateUtils.DecryptStringBySecretKey(accessTokenStr); + } + + return accessTokenStr; + } + } + + public int SiteId => GetQueryInt("siteId"); + + public int ChannelId => GetQueryInt("channelId"); + + public int ContentId => GetQueryInt("contentId"); + + #region Log + + public void AddSiteLog(int siteId, string action) + { + AddSiteLog(siteId, 0, 0, action, string.Empty); + } + + public void AddSiteLog(int siteId, string action, string summary) + { + AddSiteLog(siteId, 0, 0, action, summary); + } + + public void AddSiteLog(int siteId, int channelId, string action, string summary) + { + LogUtils.AddSiteLog(siteId, channelId, 0, AdminName, action, summary); + } + + public void AddSiteLog(int siteId, int channelId, int contentId, string action, string summary) + { + LogUtils.AddSiteLog(siteId, channelId, contentId, AdminName, action, summary); + } + + public void AddAdminLog(string action, string summary) + { + LogUtils.AddAdminLog(AdminName, action, summary); + } + + public void AddAdminLog(string action) + { + LogUtils.AddAdminLog(AdminName, action); + } + + #endregion + + #region Cookie + + public void SetCookie(string name, string value) + { + CookieUtils.SetCookie(name, value); + } + + public void SetCookie(string name, string value, TimeSpan expires) + { + CookieUtils.SetCookie(name, value, expires); + } + + public bool IsCookieExists(string name) + { + return CookieUtils.IsExists(name); + } + + #endregion + + private PermissionsImpl _userPermissionsImpl; + + public PermissionsImpl UserPermissionsImpl + { + get + { + if (_userPermissionsImpl != null) return _userPermissionsImpl; + + if (UserInfo != null) + { + var groupInfo = UserGroupManager.GetUserGroupInfo(UserInfo.GroupId); + if (groupInfo != null) + { + AdminInfo = AdminManager.GetAdminInfoByUserName(groupInfo.AdminName); + } + } + + _userPermissionsImpl = new PermissionsImpl(AdminInfo); + + return _userPermissionsImpl; + } + } + + public IPermissions UserPermissions => UserPermissionsImpl; + + private PermissionsImpl _adminPermissionsImpl; + + public PermissionsImpl AdminPermissionsImpl + { + get + { + if (_adminPermissionsImpl != null) return _adminPermissionsImpl; + + _adminPermissionsImpl = new PermissionsImpl(AdminInfo); + + return _adminPermissionsImpl; + } + } + + public IPermissions AdminPermissions => AdminPermissionsImpl; + + #region Administrator + + public int AdminId => AdminInfo?.Id ?? 0; + + public string AdminName + { + get + { + if (AdminInfo != null) + { + return AdminInfo.UserName; + } + + if (UserInfo != null) + { + var groupInfo = UserGroupManager.GetUserGroupInfo(UserInfo.GroupId); + if (groupInfo != null) + { + return groupInfo.AdminName; + } + } + + return string.Empty; + } + } + + public AdministratorInfo AdminInfo { get; private set; } + + public string AdminLogin(string userName, bool isAutoLogin) + { + if (string.IsNullOrEmpty(userName)) return null; + var adminInfo = AdminManager.GetAdminInfoByUserName(userName); + if (adminInfo == null || adminInfo.Locked) return null; + + AdminInfo = adminInfo; + IsAdminLoggin = true; + + var expiresAt = TimeSpan.FromDays(AccessTokenExpireDays); + var accessToken = GetAccessToken(adminInfo.Id, adminInfo.UserName, expiresAt); + + LogUtils.AddAdminLog(adminInfo.UserName, "管理员登录"); + + if (isAutoLogin) + { + CookieUtils.SetCookie(AuthKeyAdminCookie, accessToken, expiresAt); + } + else + { + CookieUtils.SetCookie(AuthKeyAdminCookie, accessToken); + } + + return accessToken; + } + + public void AdminLogout() + { + if (IsAdminLoggin) + { + PermissionsImpl.ClearAllCache(); + AdminManager.RemoveCache(AdminInfo); + } + + CookieUtils.Erase(AuthKeyAdminCookie); + } + + #endregion + + #region User + + public int UserId => UserInfo?.Id ?? 0; + + public string UserName => UserInfo?.UserName ?? string.Empty; + + public UserInfo UserInfo { get; private set; } + + public string UserLogin(string userName, bool isAutoLogin) + { + if (string.IsNullOrEmpty(userName)) return null; + + var userInfo = UserManager.GetUserInfoByUserName(userName); + if (userInfo == null || userInfo.Locked || !userInfo.Checked) return null; + + UserInfo = userInfo; + + var expiresAt = TimeSpan.FromDays(AccessTokenExpireDays); + var accessToken = GetAccessToken(UserId, UserName, expiresAt); + + DataProvider.User.UpdateLastActivityDateAndCountOfLogin(UserInfo); + LogUtils.AddUserLoginLog(userName); + + if (isAutoLogin) + { + CookieUtils.SetCookie(AuthKeyUserCookie, accessToken, expiresAt); + } + else + { + CookieUtils.SetCookie(AuthKeyUserCookie, accessToken); + } + + return accessToken; + } + + public void UserLogout() + { + UserInfo = null; + CookieUtils.Erase(AuthKeyUserCookie); + } + + #endregion + + #region Utils + + public static string GetAccessToken(int userId, string userName, TimeSpan expiresAt) + { + if (userId <= 0 || string.IsNullOrEmpty(userName)) return null; + + var userToken = new AccessTokenImpl + { + UserId = userId, + UserName = userName, + ExpiresAt = DateUtils.GetExpiresAt(expiresAt) + }; + + return JsonWebToken.Encode(userToken, WebConfigUtils.SecretKey, JwtHashAlgorithm.HS256); + } + + private static AccessTokenImpl ParseAccessToken(string accessToken) + { + if (string.IsNullOrEmpty(accessToken)) return new AccessTokenImpl(); + + try + { + var tokenObj = JsonWebToken.DecodeToObject(accessToken, WebConfigUtils.SecretKey); + + if (tokenObj?.ExpiresAt.AddDays(AccessTokenExpireDays) > DateTime.Now) + { + return tokenObj; + } + } + catch + { + // ignored + } + + return new AccessTokenImpl(); + } + + public object AdminRedirectCheck(bool checkInstall = false, bool checkDatabaseVersion = false, + bool checkLogin = false) + { + var redirect = false; + var redirectUrl = string.Empty; + + if (checkInstall && string.IsNullOrWhiteSpace(WebConfigUtils.ConnectionString)) + { + redirect = true; + redirectUrl = FxUtils.GetAdminUrl("installer/default.aspx"); + } + else if (checkDatabaseVersion && ConfigManager.Instance.Initialized && + ConfigManager.Instance.DatabaseVersion != SystemManager.Version) + { + redirect = true; + redirectUrl = AdminPagesUtils.UpdateUrl; + } + else if (checkLogin && (!IsAdminLoggin || AdminInfo == null || AdminInfo.Locked)) + { + redirect = true; + redirectUrl = AdminPagesUtils.LoginUrl; + } + + if (redirect) + { + return new + { + Value = false, + RedirectUrl = redirectUrl + }; + } + + return null; + } + + #endregion + } +} \ No newline at end of file diff --git a/SiteServer.Web/SiteFiles/assets/default_avatar.png b/net452/SiteServer.Web/SiteFiles/Home/default_avatar.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/default_avatar.png rename to net452/SiteServer.Web/SiteFiles/Home/default_avatar.png diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/audiojs/audio.min.js b/net452/SiteServer.Web/SiteFiles/assets/Flashes/audiojs/audio.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/audiojs/audio.min.js rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/audiojs/audio.min.js diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/audiojs/audiojs.swf b/net452/SiteServer.Web/SiteFiles/assets/Flashes/audiojs/audiojs.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/audiojs/audiojs.swf rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/audiojs/audiojs.swf diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/audiojs/player-graphics.gif b/net452/SiteServer.Web/SiteFiles/assets/Flashes/audiojs/player-graphics.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/audiojs/player-graphics.gif rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/audiojs/player-graphics.gif diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/bcastr31.swf b/net452/SiteServer.Web/SiteFiles/assets/Flashes/bcastr31.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/bcastr31.swf rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/bcastr31.swf diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/brplayer/player.swf b/net452/SiteServer.Web/SiteFiles/assets/Flashes/brplayer/player.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/brplayer/player.swf rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/brplayer/player.swf diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/flowplayer/flowplayer-3.2.12.min.js b/net452/SiteServer.Web/SiteFiles/assets/Flashes/flowplayer/flowplayer-3.2.12.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/flowplayer/flowplayer-3.2.12.min.js rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/flowplayer/flowplayer-3.2.12.min.js diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/flowplayer/flowplayer-3.2.16.swf b/net452/SiteServer.Web/SiteFiles/assets/Flashes/flowplayer/flowplayer-3.2.16.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/flowplayer/flowplayer-3.2.16.swf rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/flowplayer/flowplayer-3.2.16.swf diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/flowplayer/flowplayer.controls-3.2.15.swf b/net452/SiteServer.Web/SiteFiles/assets/Flashes/flowplayer/flowplayer.controls-3.2.15.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/flowplayer/flowplayer.controls-3.2.15.swf rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/flowplayer/flowplayer.controls-3.2.15.swf diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/focusali.swf b/net452/SiteServer.Web/SiteFiles/assets/Flashes/focusali.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/focusali.swf rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/focusali.swf diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/focusviewer.swf b/net452/SiteServer.Web/SiteFiles/assets/Flashes/focusviewer.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/focusviewer.swf rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/focusviewer.swf diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/focusviewerbg.png b/net452/SiteServer.Web/SiteFiles/assets/Flashes/focusviewerbg.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/focusviewerbg.png rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/focusviewerbg.png diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/jwplayer.swf b/net452/SiteServer.Web/SiteFiles/assets/Flashes/jwplayer.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/jwplayer.swf rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/jwplayer.swf diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/jwplayer6/jwplayer.flash.swf b/net452/SiteServer.Web/SiteFiles/assets/Flashes/jwplayer6/jwplayer.flash.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/jwplayer6/jwplayer.flash.swf rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/jwplayer6/jwplayer.flash.swf diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/jwplayer6/jwplayer.html5.js b/net452/SiteServer.Web/SiteFiles/assets/Flashes/jwplayer6/jwplayer.html5.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/jwplayer6/jwplayer.html5.js rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/jwplayer6/jwplayer.html5.js diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/jwplayer6/jwplayer.js b/net452/SiteServer.Web/SiteFiles/assets/Flashes/jwplayer6/jwplayer.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/jwplayer6/jwplayer.js rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/jwplayer6/jwplayer.js diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/lang/zh-cn.js b/net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/lang/zh-cn.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/lang/zh-cn.js rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/lang/zh-cn.js diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-and-player.min.js b/net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-and-player.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-and-player.min.js rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-and-player.min.js diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-audio-ogg.swf b/net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-audio-ogg.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-audio-ogg.swf rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-audio-ogg.swf diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-audio.swf b/net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-audio.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-audio.swf rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-audio.swf diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-video-hls.swf b/net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-video-hls.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-video-hls.swf rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-video-hls.swf diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-video-mdash.swf b/net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-video-mdash.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-video-mdash.swf rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-video-mdash.swf diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-video.swf b/net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-video.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-video.swf rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement-flash-video.swf diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement.min.js b/net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement.min.js rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelement.min.js diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelementplayer-legacy.min.css b/net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelementplayer-legacy.min.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelementplayer-legacy.min.css rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelementplayer-legacy.min.css diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelementplayer.min.css b/net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelementplayer.min.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelementplayer.min.css rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mediaelementplayer.min.css diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mejs-controls.png b/net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mejs-controls.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mejs-controls.png rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mejs-controls.png diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mejs-controls.svg b/net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mejs-controls.svg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mejs-controls.svg rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/mediaelement/mejs-controls.svg diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/vcastr3.swf b/net452/SiteServer.Web/SiteFiles/assets/Flashes/vcastr3.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/vcastr3.swf rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/vcastr3.swf diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/videojs/captions.vtt b/net452/SiteServer.Web/SiteFiles/assets/Flashes/videojs/captions.vtt similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/videojs/captions.vtt rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/videojs/captions.vtt diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video-js.css b/net452/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video-js.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/videojs/video-js.css rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video-js.css diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video-js.min.css b/net452/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video-js.min.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/videojs/video-js.min.css rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video-js.min.css diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video-js.png b/net452/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video-js.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/videojs/video-js.png rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video-js.png diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video-js.swf b/net452/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video-js.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/videojs/video-js.swf rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video-js.swf diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video.js b/net452/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/videojs/video.js rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video.js diff --git a/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video.min.js b/net452/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Flashes/videojs/video.min.js rename to net452/SiteServer.Web/SiteFiles/assets/Flashes/videojs/video.min.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/ajaxUpload.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/ajaxUpload.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/ajaxUpload.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/ajaxUpload.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/css/bootstrap-responsive.css b/net452/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/css/bootstrap-responsive.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/css/bootstrap-responsive.css rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/css/bootstrap-responsive.css diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/css/bootstrap-responsive.min.css b/net452/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/css/bootstrap-responsive.min.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/css/bootstrap-responsive.min.css rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/css/bootstrap-responsive.min.css diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/css/bootstrap.css b/net452/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/css/bootstrap.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/css/bootstrap.css rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/css/bootstrap.css diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/css/bootstrap.min.css b/net452/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/css/bootstrap.min.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/css/bootstrap.min.css rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/css/bootstrap.min.css diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/img/glyphicons-halflings-white.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/img/glyphicons-halflings-white.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/img/glyphicons-halflings-white.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/img/glyphicons-halflings-white.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/img/glyphicons-halflings.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/img/glyphicons-halflings.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/img/glyphicons-halflings.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/img/glyphicons-halflings.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/js/bootstrap.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/js/bootstrap.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/js/bootstrap.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/js/bootstrap.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/js/bootstrap.min.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/js/bootstrap.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/js/bootstrap.min.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/bootstrap/js/bootstrap.min.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/clipboard/jquery.clipboard.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/clipboard/jquery.clipboard.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/clipboard/jquery.clipboard.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/clipboard/jquery.clipboard.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/clipboard/jquery.clipboard.swf b/net452/SiteServer.Web/SiteFiles/assets/JQuery/clipboard/jquery.clipboard.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/clipboard/jquery.clipboard.swf rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/clipboard/jquery.clipboard.swf diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/css/colorpicker.css b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/css/colorpicker.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/css/colorpicker.css rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/css/colorpicker.css diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/blank.gif b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/blank.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/blank.gif rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/blank.gif diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_background.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_background.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_background.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_background.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_hex.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_hex.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_hex.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_hex.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_hsb_b.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_hsb_b.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_hsb_b.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_hsb_b.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_hsb_h.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_hsb_h.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_hsb_h.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_hsb_h.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_hsb_s.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_hsb_s.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_hsb_s.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_hsb_s.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_indic.gif b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_indic.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_indic.gif rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_indic.gif diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_overlay.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_overlay.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_overlay.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_overlay.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_rgb_b.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_rgb_b.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_rgb_b.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_rgb_b.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_rgb_g.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_rgb_g.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_rgb_g.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_rgb_g.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_rgb_r.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_rgb_r.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_rgb_r.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_rgb_r.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_select.gif b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_select.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_select.gif rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_select.gif diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_submit.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_submit.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_submit.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/colorpicker_submit.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_background.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_background.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_background.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_background.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_hex.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_hex.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_hex.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_hex.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_hsb_b.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_hsb_b.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_hsb_b.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_hsb_b.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_hsb_h.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_hsb_h.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_hsb_h.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_hsb_h.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_hsb_s.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_hsb_s.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_hsb_s.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_hsb_s.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_indic.gif b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_indic.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_indic.gif rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_indic.gif diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_rgb_b.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_rgb_b.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_rgb_b.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_rgb_b.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_rgb_g.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_rgb_g.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_rgb_g.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_rgb_g.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_rgb_r.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_rgb_r.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_rgb_r.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_rgb_r.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_submit.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_submit.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_submit.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/custom_submit.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/select.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/select.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/select.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/select.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/select2.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/select2.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/select2.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/select2.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/slider.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/slider.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/slider.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/images/slider.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/js/colorpicker.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/js/colorpicker.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/js/colorpicker.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/colorpicker/js/colorpicker.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/blank.gif b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/blank.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/blank.gif rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/blank.gif diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_close.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_close.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_close.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_close.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_loading.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_loading.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_loading.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_loading.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_nav_left.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_nav_left.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_nav_left.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_nav_left.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_nav_right.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_nav_right.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_nav_right.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_nav_right.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_e.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_e.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_e.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_e.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_n.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_n.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_n.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_n.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_ne.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_ne.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_ne.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_ne.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_nw.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_nw.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_nw.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_nw.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_s.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_s.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_s.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_s.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_se.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_se.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_se.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_se.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_sw.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_sw.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_sw.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_sw.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_w.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_w.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_w.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_shadow_w.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_title_left.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_title_left.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_title_left.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_title_left.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_title_main.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_title_main.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_title_main.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_title_main.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_title_over.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_title_over.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_title_over.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_title_over.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_title_right.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_title_right.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_title_right.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancy_title_right.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancybox-x.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancybox-x.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancybox-x.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancybox-x.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancybox-y.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancybox-y.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancybox-y.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancybox-y.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancybox.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancybox.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancybox.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/fancybox.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.easing-1.3.pack.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.easing-1.3.pack.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.easing-1.3.pack.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.easing-1.3.pack.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.fancybox-1.3.4.css b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.fancybox-1.3.4.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.fancybox-1.3.4.css rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.fancybox-1.3.4.css diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.fancybox-1.3.4.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.fancybox-1.3.4.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.fancybox-1.3.4.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.fancybox-1.3.4.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.fancybox-1.3.4.pack.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.fancybox-1.3.4.pack.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.fancybox-1.3.4.pack.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.fancybox-1.3.4.pack.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.mousewheel-3.0.4.pack.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.mousewheel-3.0.4.pack.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.mousewheel-3.0.4.pack.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/fancybox/jquery.mousewheel-3.0.4.pack.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/jcarousel/jquery.jcarousel.min.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/jcarousel/jquery.jcarousel.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/jcarousel/jquery.jcarousel.min.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/jcarousel/jquery.jcarousel.min.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/jquery-1.11.0.min.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/jquery-1.11.0.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/jquery-1.11.0.min.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/jquery-1.11.0.min.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/jquery-1.4.3.min.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/jquery-1.4.3.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/jquery-1.4.3.min.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/jquery-1.4.3.min.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/jquery-1.8.3.min.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/jquery-1.8.3.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/jquery-1.8.3.min.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/jquery-1.8.3.min.js diff --git a/SiteServer.Web/SiteFiles/assets/components/jquery-1.9.1.min.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/jquery-1.9.1.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/components/jquery-1.9.1.min.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/jquery-1.9.1.min.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/jquery-jtemplates.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/jquery-jtemplates.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/jquery-jtemplates.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/jquery-jtemplates.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/jquery.form.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/jquery.form.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/jquery.form.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/jquery.form.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/jqzoom/css/jqzoom.css b/net452/SiteServer.Web/SiteFiles/assets/JQuery/jqzoom/css/jqzoom.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/jqzoom/css/jqzoom.css rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/jqzoom/css/jqzoom.css diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/jqzoom/images/zoomloader.gif b/net452/SiteServer.Web/SiteFiles/assets/JQuery/jqzoom/images/zoomloader.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/jqzoom/images/zoomloader.gif rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/jqzoom/images/zoomloader.gif diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/jqzoom/jqzoom.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/jqzoom/jqzoom.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/jqzoom/jqzoom.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/jqzoom/jqzoom.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/arrow.gif b/net452/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/arrow.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/jscolor/arrow.gif rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/arrow.gif diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/cross.gif b/net452/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/cross.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/jscolor/cross.gif rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/cross.gif diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/demo.html b/net452/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/demo.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/jscolor/demo.html rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/demo.html diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/hs.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/hs.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/jscolor/hs.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/hs.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/hv.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/hv.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/jscolor/hv.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/hv.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/jscolor.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/jscolor.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/jscolor/jscolor.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/jscolor/jscolor.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/layer/extend/layer.ext.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/extend/layer.ext.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/layer/extend/layer.ext.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/extend/layer.ext.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/layer/layer.min.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/layer.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/layer/layer.min.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/layer.min.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/icon_ext.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/icon_ext.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/icon_ext.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/icon_ext.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/textbg.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/textbg.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/textbg.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/textbg.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_ico0.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_ico0.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_ico0.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_ico0.png diff --git a/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading0.gif b/net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading0.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading0.gif rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading0.gif diff --git a/net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading1.gif b/net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading1.gif new file mode 100644 index 000000000..db3a483e4 Binary files /dev/null and b/net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading1.gif differ diff --git a/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading2.gif b/net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading2.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading2.gif rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading2.gif diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading3.gif b/net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading3.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading3.gif rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_loading3.gif diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_title0.png b/net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_title0.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_title0.png rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/default/xubox_title0.png diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/layer.css b/net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/layer.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/layer.css rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/layer.css diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/layer.ext.css b/net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/layer.ext.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/layer.ext.css rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/layer/skin/layer.ext.css diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/queryString.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/queryString.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/queryString.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/queryString.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/css/showLoading.css b/net452/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/css/showLoading.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/showLoading/css/showLoading.css rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/css/showLoading.css diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/images/loading-bars.gif b/net452/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/images/loading-bars.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/showLoading/images/loading-bars.gif rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/images/loading-bars.gif diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/images/loading.gif b/net452/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/images/loading.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/showLoading/images/loading.gif rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/images/loading.gif diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/jquery.showLoading.example.html b/net452/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/jquery.showLoading.example.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/showLoading/jquery.showLoading.example.html rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/jquery.showLoading.example.html diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/js/jquery-1.3.2.min.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/js/jquery-1.3.2.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/showLoading/js/jquery-1.3.2.min.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/js/jquery-1.3.2.min.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/js/jquery.showLoading.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/js/jquery.showLoading.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/showLoading/js/jquery.showLoading.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/js/jquery.showLoading.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/js/jquery.showLoading.min.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/js/jquery.showLoading.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/showLoading/js/jquery.showLoading.min.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/showLoading/js/jquery.showLoading.min.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/toastr/toastr.min.css b/net452/SiteServer.Web/SiteFiles/assets/JQuery/toastr/toastr.min.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/toastr/toastr.min.css rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/toastr/toastr.min.css diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/toastr/toastr.min.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/toastr/toastr.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/toastr/toastr.min.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/toastr/toastr.min.js diff --git a/SiteServer.Web/SiteFiles/assets/JQuery/validate.js b/net452/SiteServer.Web/SiteFiles/assets/JQuery/validate.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/JQuery/validate.js rename to net452/SiteServer.Web/SiteFiles/assets/JQuery/validate.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/WdatePicker.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/WdatePicker.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/WdatePicker.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/WdatePicker.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/calendar.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/calendar.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/calendar.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/calendar.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/lang/en.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/lang/en.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/lang/en.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/lang/en.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/lang/zh-cn.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/lang/zh-cn.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/lang/zh-cn.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/lang/zh-cn.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/lang/zh-tw.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/lang/zh-tw.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/lang/zh-tw.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/lang/zh-tw.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/WdatePicker.css b/net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/WdatePicker.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/WdatePicker.css rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/WdatePicker.css diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/datePicker.gif b/net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/datePicker.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/datePicker.gif rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/datePicker.gif diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/default/datepicker.css b/net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/default/datepicker.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/default/datepicker.css rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/default/datepicker.css diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/default/img.gif b/net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/default/img.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/default/img.gif rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/default/img.gif diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/whyGreen/bg.jpg b/net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/whyGreen/bg.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/whyGreen/bg.jpg rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/whyGreen/bg.jpg diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/whyGreen/datepicker.css b/net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/whyGreen/datepicker.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/whyGreen/datepicker.css rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/whyGreen/datepicker.css diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/whyGreen/img.gif b/net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/whyGreen/img.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/whyGreen/img.gif rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/DatePicker/skin/whyGreen/img.gif diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/bairongflash.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/bairongflash.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/bairongflash.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/bairongflash.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/datestring.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/datestring.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/datestring.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/datestring.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/float/floatleft.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/float/floatleft.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/float/floatleft.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/float/floatleft.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/float/floatleft_close.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/float/floatleft_close.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/float/floatleft_close.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/float/floatleft_close.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/float/floatright.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/float/floatright.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/float/floatright.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/float/floatright.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/float/floatright_close.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/float/floatright_close.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/float/floatright_close.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/float/floatright_close.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/independent/tw_cn.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/independent/tw_cn.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/independent/tw_cn.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/independent/tw_cn.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/independent/validate.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/independent/validate.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/independent/validate.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/independent/validate.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/jquery-1.4.2.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/jquery-1.4.2.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/jquery-1.4.2.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/jquery-1.4.2.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/blank.gif b/net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/blank.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/blank.gif rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/blank.gif diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/close.gif b/net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/close.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/close.gif rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/close.gif diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/closelabel.gif b/net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/closelabel.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/closelabel.gif rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/closelabel.gif diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/loading.gif b/net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/loading.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/loading.gif rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/loading.gif diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/next.gif b/net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/next.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/next.gif rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/next.gif diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/nextlabel.gif b/net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/nextlabel.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/nextlabel.gif rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/nextlabel.gif diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/prev.gif b/net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/prev.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/prev.gif rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/prev.gif diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/prevlabel.gif b/net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/prevlabel.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/prevlabel.gif rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/Images/prevlabel.gif diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/lightbox.css b/net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/lightbox.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/lightbox/lightbox.css rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/lightbox.css diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/lightbox.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/lightbox.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/lightbox/lightbox.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/lightbox/lightbox.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/pngfix.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/pngfix.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/pngfix.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/pngfix.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/print.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/print.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/print.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/print.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/print_uft8.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/print_uft8.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/print_uft8.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/print_uft8.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/slide/fullscreen.swf b/net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/fullscreen.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/slide/fullscreen.swf rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/fullscreen.swf diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/arr_left.cur b/net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/arr_left.cur similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/slide/images/arr_left.cur rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/arr_left.cur diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/arr_right.cur b/net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/arr_right.cur similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/slide/images/arr_right.cur rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/arr_right.cur diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_01.png b/net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_01.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_01.png rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_01.png diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_02.png b/net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_02.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_02.png rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_02.png diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_03.gif b/net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_03.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_03.gif rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_03.gif diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_05.gif b/net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_05.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_05.gif rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_05.gif diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_06.png b/net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_06.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_06.png rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_06.png diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_07.gif b/net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_07.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_07.gif rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/e_m_07.gif diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/fullScreen2.png b/net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/fullScreen2.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/slide/images/fullScreen2.png rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/fullScreen2.png diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/loading_01.gif b/net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/loading_01.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/slide/images/loading_01.gif rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/loading_01.gif diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/unfcn_mj_01.png b/net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/unfcn_mj_01.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/slide/images/unfcn_mj_01.png rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/images/unfcn_mj_01.png diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/slide/script.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/script.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/slide/script.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/script.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/slide/style.css b/net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/style.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/slide/style.css rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/style.css diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/slide/template.html b/net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/template.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/slide/template.html rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/slide/template.html diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/static/adFloatInWin.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/static/adFloatInWin.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/static/adFloatInWin.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/static/adFloatInWin.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/static/adFloating.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/static/adFloating.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/static/adFloating.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/static/adFloating.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/stl/pagescript.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/stl/pagescript.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/stl/pagescript.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/stl/pagescript.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/stl/userscript.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/stl/userscript.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/stl/userscript.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/stl/userscript.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/button.png b/net452/SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/button.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/button.png rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/button.png diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/handlers.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/handlers.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/handlers.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/handlers.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/swfupload.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/swfupload.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/swfupload.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/swfupload.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/swfupload.swf b/net452/SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/swfupload.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/swfupload.swf rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/swfupload.swf diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/swfupload_fp9.swf b/net452/SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/swfupload_fp9.swf similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/swfupload_fp9.swf rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/swfUpload/swfupload_fp9.swf diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/swfobject.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/swfobject.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/swfobject.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/swfobject.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/tabstrip.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/tabstrip.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/tabstrip.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/tabstrip.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/validate.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/validate.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/validate.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/validate.js diff --git a/SiteServer.Web/SiteFiles/assets/Scripts/wz_tooltip.v3.33.js b/net452/SiteServer.Web/SiteFiles/assets/Scripts/wz_tooltip.v3.33.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Scripts/wz_tooltip.v3.33.js rename to net452/SiteServer.Web/SiteFiles/assets/Scripts/wz_tooltip.v3.33.js diff --git a/SiteServer.Web/SiteFiles/assets/Styles/Css/addition.css b/net452/SiteServer.Web/SiteFiles/assets/Styles/Css/addition.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/Css/addition.css rename to net452/SiteServer.Web/SiteFiles/assets/Styles/Css/addition.css diff --git a/SiteServer.Web/SiteFiles/assets/Styles/Css/candy_buttons.css b/net452/SiteServer.Web/SiteFiles/assets/Styles/Css/candy_buttons.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/Css/candy_buttons.css rename to net452/SiteServer.Web/SiteFiles/assets/Styles/Css/candy_buttons.css diff --git a/SiteServer.Web/SiteFiles/assets/Styles/Css/global.css b/net452/SiteServer.Web/SiteFiles/assets/Styles/Css/global.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/Css/global.css rename to net452/SiteServer.Web/SiteFiles/assets/Styles/Css/global.css diff --git a/SiteServer.Web/SiteFiles/assets/Styles/Css/lightbox.css b/net452/SiteServer.Web/SiteFiles/assets/Styles/Css/lightbox.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/Css/lightbox.css rename to net452/SiteServer.Web/SiteFiles/assets/Styles/Css/lightbox.css diff --git a/SiteServer.Web/SiteFiles/assets/Styles/Css/parts.css b/net452/SiteServer.Web/SiteFiles/assets/Styles/Css/parts.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/Css/parts.css rename to net452/SiteServer.Web/SiteFiles/assets/Styles/Css/parts.css diff --git a/SiteServer.Web/SiteFiles/assets/Styles/Css/slideAdv.css b/net452/SiteServer.Web/SiteFiles/assets/Styles/Css/slideAdv.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/Css/slideAdv.css rename to net452/SiteServer.Web/SiteFiles/assets/Styles/Css/slideAdv.css diff --git a/SiteServer.Web/SiteFiles/assets/Styles/Css/spaces.css b/net452/SiteServer.Web/SiteFiles/assets/Styles/Css/spaces.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/Css/spaces.css rename to net452/SiteServer.Web/SiteFiles/assets/Styles/Css/spaces.css diff --git a/SiteServer.Web/SiteFiles/assets/Styles/Css/wysiwygsettings.css b/net452/SiteServer.Web/SiteFiles/assets/Styles/Css/wysiwygsettings.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/Css/wysiwygsettings.css rename to net452/SiteServer.Web/SiteFiles/assets/Styles/Css/wysiwygsettings.css diff --git a/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/blank.gif b/net452/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/blank.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/blank.gif rename to net452/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/blank.gif diff --git a/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/close.gif b/net452/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/close.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/close.gif rename to net452/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/close.gif diff --git a/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/closelabel.gif b/net452/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/closelabel.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/closelabel.gif rename to net452/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/closelabel.gif diff --git a/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/loading.gif b/net452/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/loading.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/loading.gif rename to net452/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/loading.gif diff --git a/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/next.gif b/net452/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/next.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/next.gif rename to net452/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/next.gif diff --git a/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/nextlabel.gif b/net452/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/nextlabel.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/nextlabel.gif rename to net452/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/nextlabel.gif diff --git a/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/prev.gif b/net452/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/prev.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/prev.gif rename to net452/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/prev.gif diff --git a/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/prevlabel.gif b/net452/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/prevlabel.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/prevlabel.gif rename to net452/SiteServer.Web/SiteFiles/assets/Styles/Images/lightbox/prevlabel.gif diff --git a/SiteServer.Web/SiteFiles/assets/Styles/addition.css.1.1 b/net452/SiteServer.Web/SiteFiles/assets/Styles/addition.css.1.1 similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/addition.css.1.1 rename to net452/SiteServer.Web/SiteFiles/assets/Styles/addition.css.1.1 diff --git a/SiteServer.Web/SiteFiles/assets/Styles/candy_buttons.css.1.0 b/net452/SiteServer.Web/SiteFiles/assets/Styles/candy_buttons.css.1.0 similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/candy_buttons.css.1.0 rename to net452/SiteServer.Web/SiteFiles/assets/Styles/candy_buttons.css.1.0 diff --git a/SiteServer.Web/SiteFiles/assets/Styles/global.v1.0.css b/net452/SiteServer.Web/SiteFiles/assets/Styles/global.v1.0.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/global.v1.0.css rename to net452/SiteServer.Web/SiteFiles/assets/Styles/global.v1.0.css diff --git a/SiteServer.Web/SiteFiles/assets/Styles/parts.css.1.1 b/net452/SiteServer.Web/SiteFiles/assets/Styles/parts.css.1.1 similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/parts.css.1.1 rename to net452/SiteServer.Web/SiteFiles/assets/Styles/parts.css.1.1 diff --git a/SiteServer.Web/SiteFiles/assets/Styles/spaces.css.1.1 b/net452/SiteServer.Web/SiteFiles/assets/Styles/spaces.css.1.1 similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/spaces.css.1.1 rename to net452/SiteServer.Web/SiteFiles/assets/Styles/spaces.css.1.1 diff --git a/SiteServer.Web/SiteFiles/assets/Styles/tabstrip.css b/net452/SiteServer.Web/SiteFiles/assets/Styles/tabstrip.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/Styles/tabstrip.css rename to net452/SiteServer.Web/SiteFiles/assets/Styles/tabstrip.css diff --git a/SiteServer.Web/SiteFiles/assets/adv/style.css b/net452/SiteServer.Web/SiteFiles/assets/adv/style.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/adv/style.css rename to net452/SiteServer.Web/SiteFiles/assets/adv/style.css diff --git a/SiteServer.Web/SiteFiles/assets/commentInput/images/bg.png b/net452/SiteServer.Web/SiteFiles/assets/commentInput/images/bg.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/commentInput/images/bg.png rename to net452/SiteServer.Web/SiteFiles/assets/commentInput/images/bg.png diff --git a/SiteServer.Web/SiteFiles/assets/commentInput/images/btm.png b/net452/SiteServer.Web/SiteFiles/assets/commentInput/images/btm.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/commentInput/images/btm.png rename to net452/SiteServer.Web/SiteFiles/assets/commentInput/images/btm.png diff --git a/SiteServer.Web/SiteFiles/assets/commentInput/images/ent.png b/net452/SiteServer.Web/SiteFiles/assets/commentInput/images/ent.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/commentInput/images/ent.png rename to net452/SiteServer.Web/SiteFiles/assets/commentInput/images/ent.png diff --git a/SiteServer.Web/SiteFiles/assets/commentInput/images/ent2.png b/net452/SiteServer.Web/SiteFiles/assets/commentInput/images/ent2.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/commentInput/images/ent2.png rename to net452/SiteServer.Web/SiteFiles/assets/commentInput/images/ent2.png diff --git a/SiteServer.Web/SiteFiles/assets/commentInput/images/ent3.png b/net452/SiteServer.Web/SiteFiles/assets/commentInput/images/ent3.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/commentInput/images/ent3.png rename to net452/SiteServer.Web/SiteFiles/assets/commentInput/images/ent3.png diff --git a/SiteServer.Web/SiteFiles/assets/commentInput/images/success.png b/net452/SiteServer.Web/SiteFiles/assets/commentInput/images/success.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/commentInput/images/success.png rename to net452/SiteServer.Web/SiteFiles/assets/commentInput/images/success.png diff --git a/SiteServer.Web/SiteFiles/assets/commentInput/script.js b/net452/SiteServer.Web/SiteFiles/assets/commentInput/script.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/commentInput/script.js rename to net452/SiteServer.Web/SiteFiles/assets/commentInput/script.js diff --git a/SiteServer.Web/SiteFiles/assets/commentInput/style.css b/net452/SiteServer.Web/SiteFiles/assets/commentInput/style.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/commentInput/style.css rename to net452/SiteServer.Web/SiteFiles/assets/commentInput/style.css diff --git a/SiteServer.Web/SiteFiles/assets/commentInput/template.html b/net452/SiteServer.Web/SiteFiles/assets/commentInput/template.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/commentInput/template.html rename to net452/SiteServer.Web/SiteFiles/assets/commentInput/template.html diff --git a/SiteServer.Web/SiteServer/assets/jquery/jquery-1.9.1.min.js b/net452/SiteServer.Web/SiteFiles/assets/components/jquery-1.9.1.min.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/jquery/jquery-1.9.1.min.js rename to net452/SiteServer.Web/SiteFiles/assets/components/jquery-1.9.1.min.js diff --git a/SiteServer.Web/SiteFiles/assets/components/js.cookie.js b/net452/SiteServer.Web/SiteFiles/assets/components/js.cookie.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/components/js.cookie.js rename to net452/SiteServer.Web/SiteFiles/assets/components/js.cookie.js diff --git a/SiteServer.Web/SiteFiles/assets/components/lodash-4.17.4.min.js b/net452/SiteServer.Web/SiteFiles/assets/components/lodash-4.17.4.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/components/lodash-4.17.4.min.js rename to net452/SiteServer.Web/SiteFiles/assets/components/lodash-4.17.4.min.js diff --git a/SiteServer.Web/SiteFiles/assets/components/stlClient.js b/net452/SiteServer.Web/SiteFiles/assets/components/stlClient.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/components/stlClient.js rename to net452/SiteServer.Web/SiteFiles/assets/components/stlClient.js diff --git a/SiteServer.Web/SiteFiles/assets/components/vue-2.1.10.min.js b/net452/SiteServer.Web/SiteFiles/assets/components/vue-2.1.10.min.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/components/vue-2.1.10.min.js rename to net452/SiteServer.Web/SiteFiles/assets/components/vue-2.1.10.min.js diff --git a/net452/SiteServer.Web/SiteFiles/assets/default_avatar.png b/net452/SiteServer.Web/SiteFiles/assets/default_avatar.png new file mode 100644 index 000000000..5caa1fc98 Binary files /dev/null and b/net452/SiteServer.Web/SiteFiles/assets/default_avatar.png differ diff --git a/SiteServer.Web/SiteFiles/assets/digg/digg-bg.gif b/net452/SiteServer.Web/SiteFiles/assets/digg/digg-bg.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/digg/digg-bg.gif rename to net452/SiteServer.Web/SiteFiles/assets/digg/digg-bg.gif diff --git a/SiteServer.Web/SiteFiles/assets/digg/digg3.gif b/net452/SiteServer.Web/SiteFiles/assets/digg/digg3.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/digg/digg3.gif rename to net452/SiteServer.Web/SiteFiles/assets/digg/digg3.gif diff --git a/SiteServer.Web/SiteFiles/assets/digg/digg_bg.gif b/net452/SiteServer.Web/SiteFiles/assets/digg/digg_bg.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/digg/digg_bg.gif rename to net452/SiteServer.Web/SiteFiles/assets/digg/digg_bg.gif diff --git a/SiteServer.Web/SiteFiles/assets/digg/newdigg-bg.png b/net452/SiteServer.Web/SiteFiles/assets/digg/newdigg-bg.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/digg/newdigg-bg.png rename to net452/SiteServer.Web/SiteFiles/assets/digg/newdigg-bg.png diff --git a/SiteServer.Web/SiteFiles/assets/digg/script.js b/net452/SiteServer.Web/SiteFiles/assets/digg/script.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/digg/script.js rename to net452/SiteServer.Web/SiteFiles/assets/digg/script.js diff --git a/SiteServer.Web/SiteFiles/assets/digg/style1.css b/net452/SiteServer.Web/SiteFiles/assets/digg/style1.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/digg/style1.css rename to net452/SiteServer.Web/SiteFiles/assets/digg/style1.css diff --git a/SiteServer.Web/SiteFiles/assets/digg/style2.css b/net452/SiteServer.Web/SiteFiles/assets/digg/style2.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/digg/style2.css rename to net452/SiteServer.Web/SiteFiles/assets/digg/style2.css diff --git a/SiteServer.Web/SiteFiles/assets/digg/style3.css b/net452/SiteServer.Web/SiteFiles/assets/digg/style3.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/digg/style3.css rename to net452/SiteServer.Web/SiteFiles/assets/digg/style3.css diff --git a/SiteServer.Web/SiteFiles/assets/digg/style4.css b/net452/SiteServer.Web/SiteFiles/assets/digg/style4.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/digg/style4.css rename to net452/SiteServer.Web/SiteFiles/assets/digg/style4.css diff --git a/SiteServer.Web/SiteFiles/assets/dynamic/script.js b/net452/SiteServer.Web/SiteFiles/assets/dynamic/script.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/dynamic/script.js rename to net452/SiteServer.Web/SiteFiles/assets/dynamic/script.js diff --git a/SiteServer.Web/SiteFiles/assets/input/loading.html b/net452/SiteServer.Web/SiteFiles/assets/input/loading.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/input/loading.html rename to net452/SiteServer.Web/SiteFiles/assets/input/loading.html diff --git a/SiteServer.Web/SiteFiles/assets/input/no.html b/net452/SiteServer.Web/SiteFiles/assets/input/no.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/input/no.html rename to net452/SiteServer.Web/SiteFiles/assets/input/no.html diff --git a/SiteServer.Web/SiteFiles/assets/input/script.js b/net452/SiteServer.Web/SiteFiles/assets/input/script.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/input/script.js rename to net452/SiteServer.Web/SiteFiles/assets/input/script.js diff --git a/SiteServer.Web/SiteFiles/assets/input/template.html b/net452/SiteServer.Web/SiteFiles/assets/input/template.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/input/template.html rename to net452/SiteServer.Web/SiteFiles/assets/input/template.html diff --git a/SiteServer.Web/SiteFiles/assets/input/yes.html b/net452/SiteServer.Web/SiteFiles/assets/input/yes.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/input/yes.html rename to net452/SiteServer.Web/SiteFiles/assets/input/yes.html diff --git a/SiteServer.Web/SiteFiles/assets/loading.gif b/net452/SiteServer.Web/SiteFiles/assets/loading.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/loading.gif rename to net452/SiteServer.Web/SiteFiles/assets/loading.gif diff --git a/SiteServer.Web/SiteFiles/assets/print/print.gif b/net452/SiteServer.Web/SiteFiles/assets/print/print.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/print/print.gif rename to net452/SiteServer.Web/SiteFiles/assets/print/print.gif diff --git a/SiteServer.Web/SiteFiles/assets/print/return.gif b/net452/SiteServer.Web/SiteFiles/assets/print/return.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/print/return.gif rename to net452/SiteServer.Web/SiteFiles/assets/print/return.gif diff --git a/SiteServer.Web/SiteFiles/assets/resume/css/preview.css b/net452/SiteServer.Web/SiteFiles/assets/resume/css/preview.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/css/preview.css rename to net452/SiteServer.Web/SiteFiles/assets/resume/css/preview.css diff --git a/SiteServer.Web/SiteFiles/assets/resume/css/resume.css b/net452/SiteServer.Web/SiteFiles/assets/resume/css/resume.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/css/resume.css rename to net452/SiteServer.Web/SiteFiles/assets/resume/css/resume.css diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/bn_aboutbg.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/bn_aboutbg.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/bn_aboutbg.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/bn_aboutbg.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/bn_peoplebg.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/bn_peoplebg.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/bn_peoplebg.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/bn_peoplebg.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/btn_l.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/btn_l.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/btn_l.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/btn_l.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/btn_lo.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/btn_lo.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/btn_lo.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/btn_lo.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/btn_r.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/btn_r.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/btn_r.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/btn_r.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/btn_ro.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/btn_ro.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/btn_ro.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/btn_ro.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/btngray_l.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/btngray_l.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/btngray_l.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/btngray_l.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/btngray_lo.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/btngray_lo.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/btngray_lo.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/btngray_lo.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/btngray_r.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/btngray_r.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/btngray_r.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/btngray_r.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/btngray_ro.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/btngray_ro.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/btngray_ro.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/btngray_ro.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/btns_l.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/btns_l.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/btns_l.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/btns_l.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/btns_lo.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/btns_lo.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/btns_lo.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/btns_lo.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/btns_r.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/btns_r.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/btns_r.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/btns_r.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/btns_ro.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/btns_ro.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/btns_ro.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/btns_ro.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/container_bg.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/container_bg.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/container_bg.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/container_bg.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/container_bottom.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/container_bottom.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/container_bottom.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/container_bottom.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/container_top.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/container_top.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/container_top.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/container_top.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/dot_orange.gif b/net452/SiteServer.Web/SiteFiles/assets/resume/images/dot_orange.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/dot_orange.gif rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/dot_orange.gif diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/email.png b/net452/SiteServer.Web/SiteFiles/assets/resume/images/email.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/email.png rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/email.png diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/line_dot.gif b/net452/SiteServer.Web/SiteFiles/assets/resume/images/line_dot.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/line_dot.gif rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/line_dot.gif diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/lineshadow.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/lineshadow.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/lineshadow.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/lineshadow.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/pre_resume.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/pre_resume.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/pre_resume.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/pre_resume.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/resume_picture.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/resume_picture.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/resume_picture.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/resume_picture.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/resume_titlebg.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/resume_titlebg.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/resume_titlebg.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/resume_titlebg.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/site_path.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/site_path.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/site_path.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/site_path.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/split.gif b/net452/SiteServer.Web/SiteFiles/assets/resume/images/split.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/split.gif rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/split.gif diff --git a/SiteServer.Web/SiteFiles/assets/resume/images/topnav_bg.jpg b/net452/SiteServer.Web/SiteFiles/assets/resume/images/topnav_bg.jpg similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/images/topnav_bg.jpg rename to net452/SiteServer.Web/SiteFiles/assets/resume/images/topnav_bg.jpg diff --git a/SiteServer.Web/SiteFiles/assets/resume/js/resume.js b/net452/SiteServer.Web/SiteFiles/assets/resume/js/resume.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/js/resume.js rename to net452/SiteServer.Web/SiteFiles/assets/resume/js/resume.js diff --git a/SiteServer.Web/SiteFiles/assets/resume/template.html b/net452/SiteServer.Web/SiteFiles/assets/resume/template.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/resume/template.html rename to net452/SiteServer.Web/SiteFiles/assets/resume/template.html diff --git a/SiteServer.Web/SiteFiles/assets/s.gif b/net452/SiteServer.Web/SiteFiles/assets/s.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/s.gif rename to net452/SiteServer.Web/SiteFiles/assets/s.gif diff --git a/SiteServer.Web/SiteFiles/assets/search/loading.html b/net452/SiteServer.Web/SiteFiles/assets/search/loading.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/search/loading.html rename to net452/SiteServer.Web/SiteFiles/assets/search/loading.html diff --git a/SiteServer.Web/SiteFiles/assets/search/no.html b/net452/SiteServer.Web/SiteFiles/assets/search/no.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/search/no.html rename to net452/SiteServer.Web/SiteFiles/assets/search/no.html diff --git a/SiteServer.Web/SiteFiles/assets/search/yes.html b/net452/SiteServer.Web/SiteFiles/assets/search/yes.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/search/yes.html rename to net452/SiteServer.Web/SiteFiles/assets/search/yes.html diff --git a/SiteServer.Web/SiteFiles/assets/star/script.js b/net452/SiteServer.Web/SiteFiles/assets/star/script.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/star/script.js rename to net452/SiteServer.Web/SiteFiles/assets/star/script.js diff --git a/SiteServer.Web/SiteFiles/assets/star/style1.css b/net452/SiteServer.Web/SiteFiles/assets/star/style1.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/star/style1.css rename to net452/SiteServer.Web/SiteFiles/assets/star/style1.css diff --git a/SiteServer.Web/SiteFiles/assets/star/style1_off.gif b/net452/SiteServer.Web/SiteFiles/assets/star/style1_off.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/star/style1_off.gif rename to net452/SiteServer.Web/SiteFiles/assets/star/style1_off.gif diff --git a/SiteServer.Web/SiteFiles/assets/star/style1_on.gif b/net452/SiteServer.Web/SiteFiles/assets/star/style1_on.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/star/style1_on.gif rename to net452/SiteServer.Web/SiteFiles/assets/star/style1_on.gif diff --git a/SiteServer.Web/SiteFiles/assets/star/style2.css b/net452/SiteServer.Web/SiteFiles/assets/star/style2.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/star/style2.css rename to net452/SiteServer.Web/SiteFiles/assets/star/style2.css diff --git a/SiteServer.Web/SiteFiles/assets/star/style2_off.gif b/net452/SiteServer.Web/SiteFiles/assets/star/style2_off.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/star/style2_off.gif rename to net452/SiteServer.Web/SiteFiles/assets/star/style2_off.gif diff --git a/SiteServer.Web/SiteFiles/assets/star/style2_on.gif b/net452/SiteServer.Web/SiteFiles/assets/star/style2_on.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/star/style2_on.gif rename to net452/SiteServer.Web/SiteFiles/assets/star/style2_on.gif diff --git a/SiteServer.Web/SiteFiles/assets/star/style3.css b/net452/SiteServer.Web/SiteFiles/assets/star/style3.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/star/style3.css rename to net452/SiteServer.Web/SiteFiles/assets/star/style3.css diff --git a/SiteServer.Web/SiteFiles/assets/star/style3_off.gif b/net452/SiteServer.Web/SiteFiles/assets/star/style3_off.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/star/style3_off.gif rename to net452/SiteServer.Web/SiteFiles/assets/star/style3_off.gif diff --git a/SiteServer.Web/SiteFiles/assets/star/style3_on.gif b/net452/SiteServer.Web/SiteFiles/assets/star/style3_on.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/star/style3_on.gif rename to net452/SiteServer.Web/SiteFiles/assets/star/style3_on.gif diff --git a/SiteServer.Web/SiteFiles/assets/tags/default.css b/net452/SiteServer.Web/SiteFiles/assets/tags/default.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tags/default.css rename to net452/SiteServer.Web/SiteFiles/assets/tags/default.css diff --git a/SiteServer.Web/SiteFiles/assets/tree/brand.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/brand.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/brand.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/brand.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/category.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/category.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/category.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/category.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/content.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/content.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/content.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/content.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/content.png b/net452/SiteServer.Web/SiteFiles/assets/tree/content.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/content.png rename to net452/SiteServer.Web/SiteFiles/assets/tree/content.png diff --git a/SiteServer.Web/SiteFiles/assets/tree/department.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/department.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/department.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/department.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/dot.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/dot.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/dot.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/dot.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/empty.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/empty.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/empty.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/empty.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/feedback.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/feedback.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/feedback.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/feedback.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/folder.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/folder.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/folder.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/folder.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/goods.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/goods.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/goods.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/goods.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/goods.png b/net452/SiteServer.Web/SiteFiles/assets/tree/goods.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/goods.png rename to net452/SiteServer.Web/SiteFiles/assets/tree/goods.png diff --git a/SiteServer.Web/SiteFiles/assets/tree/govInteract.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/govInteract.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/govInteract.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/govInteract.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/govpublic.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/govpublic.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/govpublic.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/govpublic.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/image.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/image.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/image.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/image.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/itemContainer.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/itemContainer.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/itemContainer.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/itemContainer.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/job.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/job.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/job.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/job.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/minus.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/minus.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/minus.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/minus.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/minus.png b/net452/SiteServer.Web/SiteFiles/assets/tree/minus.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/minus.png rename to net452/SiteServer.Web/SiteFiles/assets/tree/minus.png diff --git a/SiteServer.Web/SiteFiles/assets/tree/open.png b/net452/SiteServer.Web/SiteFiles/assets/tree/open.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/open.png rename to net452/SiteServer.Web/SiteFiles/assets/tree/open.png diff --git a/SiteServer.Web/SiteFiles/assets/tree/openedfolder.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/openedfolder.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/openedfolder.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/openedfolder.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/photo.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/photo.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/photo.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/photo.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/plus.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/plus.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/plus.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/plus.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/plus.png b/net452/SiteServer.Web/SiteFiles/assets/tree/plus.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/plus.png rename to net452/SiteServer.Web/SiteFiles/assets/tree/plus.png diff --git a/SiteServer.Web/SiteFiles/assets/tree/site.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/site.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/site.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/site.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/siteHQ.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/siteHQ.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/siteHQ.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/siteHQ.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/subsite2.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/subsite2.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/subsite2.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/subsite2.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/subsite3.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/subsite3.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/subsite3.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/subsite3.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/subsite4.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/subsite4.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/subsite4.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/subsite4.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/subsite5.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/subsite5.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/subsite5.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/subsite5.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/subsite6.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/subsite6.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/subsite6.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/subsite6.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/subsite7.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/subsite7.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/subsite7.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/subsite7.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/subsite8.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/subsite8.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/subsite8.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/subsite8.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/subsite9.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/subsite9.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/subsite9.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/subsite9.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/teleplay.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/teleplay.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/teleplay.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/teleplay.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/tree_bottom.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/tree_bottom.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/tree_bottom.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/tree_bottom.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/tree_empty.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/tree_empty.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/tree_empty.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/tree_empty.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/tree_line.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/tree_line.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/tree_line.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/tree_line.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/tree_middle.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/tree_middle.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/tree_middle.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/tree_middle.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/tree_minusbottom.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/tree_minusbottom.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/tree_minusbottom.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/tree_minusbottom.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/tree_minusmiddle.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/tree_minusmiddle.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/tree_minusmiddle.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/tree_minusmiddle.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/tree_plusbottom.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/tree_plusbottom.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/tree_plusbottom.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/tree_plusbottom.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/tree_plusmiddle.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/tree_plusmiddle.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/tree_plusmiddle.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/tree_plusmiddle.gif diff --git a/SiteServer.Web/SiteFiles/assets/tree/vote.gif b/net452/SiteServer.Web/SiteFiles/assets/tree/vote.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/tree/vote.gif rename to net452/SiteServer.Web/SiteFiles/assets/tree/vote.gif diff --git a/SiteServer.Web/SiteFiles/assets/vote/css/style.css b/net452/SiteServer.Web/SiteFiles/assets/vote/css/style.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/vote/css/style.css rename to net452/SiteServer.Web/SiteFiles/assets/vote/css/style.css diff --git a/SiteServer.Web/SiteFiles/assets/vote/css/vote.css b/net452/SiteServer.Web/SiteFiles/assets/vote/css/vote.css similarity index 100% rename from SiteServer.Web/SiteFiles/assets/vote/css/vote.css rename to net452/SiteServer.Web/SiteFiles/assets/vote/css/vote.css diff --git a/SiteServer.Web/SiteFiles/assets/vote/images/bg_16.gif b/net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_16.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/vote/images/bg_16.gif rename to net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_16.gif diff --git a/SiteServer.Web/SiteFiles/assets/vote/images/bg_17.gif b/net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_17.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/vote/images/bg_17.gif rename to net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_17.gif diff --git a/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_1.gif b/net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_1.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/vote/images/bg_column_1.gif rename to net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_1.gif diff --git a/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_2.gif b/net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_2.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/vote/images/bg_column_2.gif rename to net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_2.gif diff --git a/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_3.gif b/net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_3.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/vote/images/bg_column_3.gif rename to net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_3.gif diff --git a/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_4.gif b/net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_4.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/vote/images/bg_column_4.gif rename to net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_4.gif diff --git a/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_5.gif b/net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_5.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/vote/images/bg_column_5.gif rename to net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_5.gif diff --git a/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_6.gif b/net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_6.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/vote/images/bg_column_6.gif rename to net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_6.gif diff --git a/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_7.gif b/net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_7.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/vote/images/bg_column_7.gif rename to net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_7.gif diff --git a/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_8.gif b/net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_8.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/vote/images/bg_column_8.gif rename to net452/SiteServer.Web/SiteFiles/assets/vote/images/bg_column_8.gif diff --git a/SiteServer.Web/SiteFiles/assets/vote/images/but_9.gif b/net452/SiteServer.Web/SiteFiles/assets/vote/images/but_9.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/vote/images/but_9.gif rename to net452/SiteServer.Web/SiteFiles/assets/vote/images/but_9.gif diff --git a/SiteServer.Web/SiteFiles/assets/vote/images/ico_warn.png b/net452/SiteServer.Web/SiteFiles/assets/vote/images/ico_warn.png similarity index 100% rename from SiteServer.Web/SiteFiles/assets/vote/images/ico_warn.png rename to net452/SiteServer.Web/SiteFiles/assets/vote/images/ico_warn.png diff --git a/SiteServer.Web/SiteFiles/assets/vote/inputTemplate.html b/net452/SiteServer.Web/SiteFiles/assets/vote/inputTemplate.html similarity index 100% rename from SiteServer.Web/SiteFiles/assets/vote/inputTemplate.html rename to net452/SiteServer.Web/SiteFiles/assets/vote/inputTemplate.html diff --git a/SiteServer.Web/SiteFiles/assets/vote/js/vote.js b/net452/SiteServer.Web/SiteFiles/assets/vote/js/vote.js similarity index 100% rename from SiteServer.Web/SiteFiles/assets/vote/js/vote.js rename to net452/SiteServer.Web/SiteFiles/assets/vote/js/vote.js diff --git a/SiteServer.Web/SiteFiles/assets/waiting.gif b/net452/SiteServer.Web/SiteFiles/assets/waiting.gif similarity index 100% rename from SiteServer.Web/SiteFiles/assets/waiting.gif rename to net452/SiteServer.Web/SiteFiles/assets/waiting.gif diff --git a/SiteServer.Web/SiteFiles/index.htm b/net452/SiteServer.Web/SiteFiles/index.htm similarity index 100% rename from SiteServer.Web/SiteFiles/index.htm rename to net452/SiteServer.Web/SiteFiles/index.htm diff --git a/net452/SiteServer.Web/SiteServer.API.csproj b/net452/SiteServer.Web/SiteServer.API.csproj new file mode 100644 index 000000000..a9ad36647 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer.API.csproj @@ -0,0 +1,309 @@ + + + + + Debug + AnyCPU + + + 2.0 + {69C00F60-F28A-4CBC-B1A4-2DB73BB97471} + {349c5851-65df-11da-9384-00065b846f21};{fae04ec0-301f-11d3-bf4b-00c04f79efbc} + Library + Properties + SiteServer.API + SiteServer.API + v4.5.2 + true + + + + + + + + + + + + true + full + false + bin\ + DEBUG;TRACE + prompt + 4 + + + true + pdbonly + true + bin\ + TRACE + prompt + 4 + + + + ..\..\packages\Dapper.1.60.6\lib\net451\Dapper.dll + + + ..\..\packages\Datory.0.1.7\lib\net452\Datory.dll + + + ..\..\packages\Google.Protobuf.3.5.1\lib\net45\Google.Protobuf.dll + + + + ..\..\packages\Microsoft.Owin.4.0.1\lib\net45\Microsoft.Owin.dll + + + ..\..\packages\Microsoft.Owin.Host.SystemWeb.4.0.1\lib\net45\Microsoft.Owin.Host.SystemWeb.dll + + + ..\..\packages\Microsoft.Owin.Security.4.0.1\lib\net45\Microsoft.Owin.Security.dll + + + ..\..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll + + + ..\..\packages\MySql.Data.8.0.15\lib\net452\MySql.Data.dll + + + ..\..\packages\Newtonsoft.Json.12.0.1\lib\net45\Newtonsoft.Json.dll + + + ..\..\packages\Npgsql.4.0.5\lib\net451\Npgsql.dll + + + ..\..\packages\Oracle.ManagedDataAccess.18.6.0\lib\net40\Oracle.ManagedDataAccess.dll + + + ..\..\packages\Owin.1.0\lib\net40\Owin.dll + + + ..\..\packages\SqlKata.1.1.7\lib\net45\QueryBuilder.dll + + + ..\..\packages\SiteServer.Plugin.2.2.14-beta\lib\net452\SiteServer.Plugin.dll + + + ..\..\packages\System.Buffers.4.4.0\lib\netstandard1.1\System.Buffers.dll + + + + + + + + ..\..\packages\System.Memory.4.5.2\lib\netstandard1.1\System.Memory.dll + + + + ..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.7\lib\net45\System.Net.Http.Formatting.dll + + + ..\..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard1.0\System.Runtime.CompilerServices.Unsafe.dll + + + ..\..\packages\System.Threading.Tasks.Extensions.4.5.2\lib\portable-net45+win8+wp8+wpa81\System.Threading.Tasks.Extensions.dll + + + + ..\..\packages\System.ValueTuple.4.5.0\lib\netstandard1.0\System.ValueTuple.dll + + + ..\..\packages\Microsoft.AspNet.Cors.5.2.7\lib\net45\System.Web.Cors.dll + + + + + + + + + + + ..\..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.Helpers.dll + + + ..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.7\lib\net45\System.Web.Http.dll + + + ..\..\packages\Microsoft.AspNet.WebApi.Cors.5.2.7\lib\net45\System.Web.Http.Cors.dll + + + ..\..\packages\Microsoft.AspNet.WebApi.WebHost.5.2.7\lib\net45\System.Web.Http.WebHost.dll + + + ..\..\packages\Microsoft.AspNet.Razor.3.2.7\lib\net45\System.Web.Razor.dll + + + ..\..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.dll + + + ..\..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Deployment.dll + + + ..\..\packages\Microsoft.AspNet.WebPages.3.2.7\lib\net45\System.Web.WebPages.Razor.dll + + + + + + + + + + + Web.config + + + + + + Designer + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {059e3927-37e1-4f6f-b525-fef40c54906b} + SiteServer.Utils + + + {6aa1713a-3b77-4b20-b8c7-fcb6de556f64} + SiteServer.BackgroundPages + + + {944127c3-915d-4f02-a534-64ec668c46ec} + SiteServer.CMS + + + + 10.0 + $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) + + + + + + + + + True + + + + + + + 这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。 + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Account/pagePassword.aspx b/net452/SiteServer.Web/SiteServer/Account/pagePassword.aspx new file mode 100644 index 000000000..b14155177 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Account/pagePassword.aspx @@ -0,0 +1,79 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Account.PagePassword" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + +
      + +
      + + + +
      +
      + +
      + +
      +
      + +
      + + + + + +
      + +
      + + +
      + +
      + + +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Account/pageProfile.aspx b/net452/SiteServer.Web/SiteServer/Account/pageProfile.aspx new file mode 100644 index 000000000..c37823969 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Account/pageProfile.aspx @@ -0,0 +1,72 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Account.PageProfile" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + +
      + +
      + + + +
      +
      + +
      + +
      +
      + +
      + + +
      + +
      + + +
      + +
      + + +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Ajax/ajaxBackupService.aspx b/net452/SiteServer.Web/SiteServer/Ajax/ajaxBackupService.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Ajax/ajaxBackupService.aspx rename to net452/SiteServer.Web/SiteServer/Ajax/ajaxBackupService.aspx diff --git a/SiteServer.Web/SiteServer/Ajax/ajaxCmsService.aspx b/net452/SiteServer.Web/SiteServer/Ajax/ajaxCmsService.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Ajax/ajaxCmsService.aspx rename to net452/SiteServer.Web/SiteServer/Ajax/ajaxCmsService.aspx diff --git a/SiteServer.Web/SiteServer/Ajax/ajaxCreateService.aspx b/net452/SiteServer.Web/SiteServer/Ajax/ajaxCreateService.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Ajax/ajaxCreateService.aspx rename to net452/SiteServer.Web/SiteServer/Ajax/ajaxCreateService.aspx diff --git a/SiteServer.Web/SiteServer/Ajax/ajaxOtherService.aspx b/net452/SiteServer.Web/SiteServer/Ajax/ajaxOtherService.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Ajax/ajaxOtherService.aspx rename to net452/SiteServer.Web/SiteServer/Ajax/ajaxOtherService.aspx diff --git a/SiteServer.Web/SiteServer/Ajax/ajaxSystemService.aspx b/net452/SiteServer.Web/SiteServer/Ajax/ajaxSystemService.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Ajax/ajaxSystemService.aspx rename to net452/SiteServer.Web/SiteServer/Ajax/ajaxSystemService.aspx diff --git a/SiteServer.Web/SiteServer/Ajax/ajaxUploadService.aspx b/net452/SiteServer.Web/SiteServer/Ajax/ajaxUploadService.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Ajax/ajaxUploadService.aspx rename to net452/SiteServer.Web/SiteServer/Ajax/ajaxUploadService.aspx diff --git a/net452/SiteServer.Web/SiteServer/Cms/ModalChannelTaxis.aspx b/net452/SiteServer.Web/SiteServer/Cms/ModalChannelTaxis.aspx new file mode 100644 index 000000000..708552039 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/ModalChannelTaxis.aspx @@ -0,0 +1,47 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.ModalChannelTaxis" Trace="false"%> + <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      + +
      + +
      +
      +
      + +
      + +
      + +
      +
      + + +
      +
      + +
      + +
      + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contents.cshtml b/net452/SiteServer.Web/SiteServer/Cms/contents.cshtml new file mode 100644 index 000000000..dc76c7adb --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contents.cshtml @@ -0,0 +1,210 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles{ + + +} +
      + + + + + + + + + + + + + + +
      + + + + + + + + + + + + + + + + + +
      操作状态 + + +
      + + + + + + + 编辑 + + + {{content.checkState }} + + + +
      +
      + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      +
      + + + + +
      +
      @section Scripts{ + } diff --git a/net452/SiteServer.Web/SiteServer/Cms/contents.js b/net452/SiteServer.Web/SiteServer/Cms/contents.js new file mode 100644 index 000000000..9b53e062d --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contents.js @@ -0,0 +1,260 @@ +var $url = "/pages/cms/contents"; +var $urlCreate = "/pages/cms/contents/actions/create"; + +Object.defineProperty(Object.prototype, "getProp", { + value: function (prop) { + var key, + self = this; + for (key in self) { + if (key.toLowerCase() == prop.toLowerCase()) { + return self[key]; + } + } + } +}); + +var $data = { + siteId: parseInt(utils.getQueryString("siteId")), + channelId: parseInt(utils.getQueryString("channelId")), + pageLoad: false, + pageAlert: null, + pageType: null, + page: 1, + pageContents: null, + count: null, + pages: null, + permissions: null, + columns: null, + pageOptions: null, + isAllChecked: false +}; + +var $methods = { + btnAddClick: function (e) { + e.stopPropagation(); + location.href = + "pageContentAdd.aspx?siteId=" + + this.siteId + + "&channelId=" + + this.channelId; + }, + + btnCreateClick: function (e) { + e.stopPropagation(); + + var $this = this; + $this.pageAlert = null; + if ($this.selectedContentIds.length === 0) return; + + utils.loading(true); + $api + .post($urlCreate, { + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.selectedContentIds.join(",") + }) + .then(function (response) { + var res = response.data; + + $this.pageAlert = { + type: "success", + html: '内容已添加至生成列队!生成进度查看' + }; + }) + .catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }) + .then(function () { + utils.loading(false); + }); + }, + + btnLayerClick: function (options, e) { + e.stopPropagation(); + + this.pageAlert = null; + var url = + "contentsLayer" + + options.name + + ".cshtml?siteId=" + + this.siteId + + "&channelId=" + + this.channelId; + if (options.withContents) { + if (this.selectedContentIds.length === 0) return; + url += "&contentIds=" + this.selectedContentIds.join(","); + } else if (options.contentId) { + url += "&contentId=" + options.contentId; + } + url += "&returnUrl=" + encodeURIComponent(location.href); + + utils.openLayer({ + title: options.title, + url: url, + full: options.full, + width: options.width ? options.width : 700, + height: options.height ? options.height : 500 + }); + }, + + btnContentViewClick: function (contentId, e) { + e.stopPropagation(); + + utils.openLayer({ + title: "查看内容", + url: "contentsLayerView.cshtml?siteId=" + + this.siteId + + "&channelId=" + + this.channelId + + "&contentId=" + + contentId, + full: true + }); + }, + + btnContentStateClick: function (contentId, e) { + e.stopPropagation(); + + utils.openLayer({ + title: "查看审核状态", + url: "contentsLayerState.cshtml?siteId=" + + this.siteId + + "&channelId=" + + this.channelId + + "&contentId=" + + contentId, + full: true + }); + }, + + toggleChecked: function (content) { + content.isSelected = !content.isSelected; + if (!content.isSelected) { + this.isAllChecked = false; + } + }, + + selectAll: function () { + this.isAllChecked = !this.isAllChecked; + for (var i = 0; i < this.pageContents.length; i++) { + this.pageContents[i].isSelected = this.isAllChecked; + } + }, + + loadFirstPage: function () { + if (this.page === 1) return; + this.loadContents(1); + }, + + loadPrevPage: function () { + if (this.page - 1 <= 0) return; + this.loadContents(this.page - 1); + }, + + loadNextPage: function () { + if (this.page + 1 > this.pages) return; + this.loadContents(this.page + 1); + }, + + loadLastPage: function () { + if (this.page + 1 > this.pages) return; + this.loadContents(this.pages); + }, + + onPageSelect: function (option) { + this.loadContents(option); + }, + + scrollToTop: function () { + document.documentElement.scrollTop = document.body.scrollTop = 0; + }, + + getPluginMenuUrl: function (pluginMenu) { + return pluginMenu.href + "&returnUrl=" + encodeURIComponent(location.href); + }, + + btnPluginMenuClick: function (pluginMenu, e) { + e.stopPropagation(); + + if (pluginMenu.target === "_layer") { + utils.openLayer({ + title: pluginMenu.text, + url: this.getPluginMenuUrl(pluginMenu), + full: true + }); + } + }, + + loadContents: function (page) { + var $this = this; + + if ($this.pageLoad) { + utils.loading(true); + } + + $api + .get($url, { + params: { + siteId: $this.siteId, + channelId: $this.channelId, + page: page + } + }) + .then(function (response) { + var res = response.data; + + var pageContents = []; + for (var i = 0; i < res.value.length; i++) { + var content = _.assign({}, res.value[i], { + isSelected: false + }); + pageContents.push(content); + } + $this.pageContents = pageContents; + $this.count = res.count; + $this.pages = res.pages; + $this.permissions = res.permissions; + $this.columns = res.columns; + $this.page = page; + $this.pageOptions = []; + for (var i = 1; i <= $this.pages; i++) { + $this.pageOptions.push(i); + } + }) + .catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }) + .then(function () { + if ($this.pageLoad) { + utils.loading(false); + $this.scrollToTop(); + } else { + $this.pageLoad = true; + } + }); + } +}; + +Vue.component("multiselect", window.VueMultiselect.default); + +var $vue = new Vue({ + el: "#main", + data: $data, + methods: $methods, + computed: { + selectedContentIds: function () { + var retval = []; + if (this.pageContents) { + for (var i = 0; i < this.pageContents.length; i++) { + if (this.pageContents[i].isSelected) { + retval.push(this.pageContents[i].id); + } + } + } + return retval; + } + }, + created: function () { + this.loadContents(1); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerArrange.cshtml b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerArrange.cshtml new file mode 100644 index 000000000..f04c00a1a --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerArrange.cshtml @@ -0,0 +1,26 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles { } + +
      + + +
      +
      + + +
      +
      +
      + + +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerArrange.js b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerArrange.js new file mode 100644 index 000000000..de692b2e4 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerArrange.js @@ -0,0 +1,41 @@ +var $url = '/pages/cms/contentsLayerArrange'; + +var $data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + pageLoad: false, + pageAlert: null, + attributeName: 'Id', + isDesc: true +}; + +var $methods = { + btnSubmitClick: function () { + var $this = this; + + utils.loading(true); + $api.post($url, { + siteId: $this.siteId, + channelId: $this.channelId, + attributeName: $this.attributeName, + isDesc: $this.isDesc + }).then(function (response) { + var res = response.data; + + parent.location.reload(true); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.pageLoad = true; + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerAttributes.cshtml b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerAttributes.cshtml new file mode 100644 index 000000000..847d779b8 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerAttributes.cshtml @@ -0,0 +1,52 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles { } + + +
      + + +
      +
      +
      + + +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerAttributes.js b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerAttributes.js new file mode 100644 index 000000000..e1a6161bb --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerAttributes.js @@ -0,0 +1,51 @@ +var $url = '/pages/cms/contentsLayerAttributes'; + +var $data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentIds: utils.getQueryString('contentIds'), + pageLoad: false, + pageAlert: null, + pageType: 'setAttributes', + isRecommend: false, + isHot: false, + isColor: false, + isTop: false, + hits: 0 +}; + +var $methods = { + btnSubmitClick: function () { + var $this = this; + + utils.loading(true); + $api.post($url, { + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds, + pageType: $this.pageType, + isRecommend: $this.isRecommend, + isHot: $this.isHot, + isColor: $this.isColor, + isTop: $this.isTop, + hits: $this.hits + }).then(function (response) { + var res = response.data; + + parent.location.reload(true); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.pageLoad = true; + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCheck.cshtml b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCheck.cshtml new file mode 100644 index 000000000..72d257982 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCheck.cshtml @@ -0,0 +1,58 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles{ + } + + + + + + + + + + + + + + + + + +
      内容Id 内容标题(点击查看) 添加时间状态
      {{ content.id }}{{ content.addDate }}
      +
      +
      + + +
      +
      + + +
      +
      +
      + + + + 转移栏目将把内容从当前栏目转移到所选栏目 +
      +
      + + +
      +
      +
      + + +
      @section Scripts{ + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCheck.js b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCheck.js new file mode 100644 index 000000000..ee31525ff --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCheck.js @@ -0,0 +1,94 @@ +var $url = '/pages/cms/contentsLayerCheck'; + +var $data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentIds: utils.getQueryString('contentIds'), + pageLoad: false, + pageAlert: null, + contents: null, + description: '', + checkedLevels: null, + allChannels: null, + channels: [], + isChannelLoading: false, + checkedLevel: null, + isTranslate: false, + translateChannel: null, + reasons: null +}; + +var $methods = { + loadConfig: function () { + var $this = this; + + $api.get($url, { + params: { + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds + } + }).then(function (response) { + var res = response.data; + + $this.contents = res.value; + $this.checkedLevels = res.checkedLevels; + $this.checkedLevel = res.checkedLevel; + $this.channels = $this.allChannels = res.allChannels; + $this.pageAlert = { + type: 'warning', + html: '此操作将审核以下 ' + $this.contents.length + ' 篇内容,确定吗?' + }; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + asyncFind: function (query) { + this.isChannelLoading = true; + this.channels = []; + for (var i = 0; i < this.allChannels.length; i++) { + var channel = this.allChannels[i]; + if (channel.value.indexOf(query) !== -1) { + this.channels.push(channel); + } + } + this.isChannelLoading = false; + }, + + btnSubmitClick: function () { + var $this = this; + + utils.loading(true); + $api.post($url, { + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds, + checkedLevel: $this.checkedLevel, + isTranslate: $this.isTranslate, + translateChannelId: $this.translateChannel ? $this.translateChannel.key : 0, + reasons: $this.reasons + }).then(function (response) { + var res = response.data; + + parent.location.reload(true); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } +}; + +Vue.component("multiselect", window.VueMultiselect.default); + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerColumns.cshtml b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerColumns.cshtml new file mode 100644 index 000000000..f5f76bb0e --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerColumns.cshtml @@ -0,0 +1,24 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles { } + +
      + +
      +
      +
      + + +
      +
      +
      +
      +
      +
      +
      + + +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerColumns.js b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerColumns.js new file mode 100644 index 000000000..0ee434db8 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerColumns.js @@ -0,0 +1,65 @@ +var $url = '/pages/cms/contentsLayerColumns'; + +var $data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + pageLoad: false, + pageAlert: null, + attributes: null, + attributeNames: [] +}; + +var $methods = { + loadConfig: function () { + var $this = this; + $api.get($url, { + params: { + siteId: $this.siteId, + channelId: $this.channelId + } + }).then(function (response) { + var res = response.data; + + $this.attributes = res.value; + $this.attributeNames = []; + for (var i = 0; i < $this.attributes.length; i++) { + var attribute = $this.attributes[i]; + if (attribute.selected) { + $this.attributeNames.push(attribute.value); + } + } + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + btnSubmitClick: function () { + var $this = this; + + utils.loading(true); + $api.post($url, { + siteId: $this.siteId, + channelId: $this.channelId, + attributeNames: $this.attributeNames.join(',') + }).then(function (response) { + var res = response.data; + + parent.location.reload(true); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCopy.cshtml b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCopy.cshtml new file mode 100644 index 000000000..ecfe4d44b --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCopy.cshtml @@ -0,0 +1,73 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles{ + } +
      + + + + + +
      +
      + + + + + +
      +
      + +
      +
      + + +
      +
      + + +
      +
      + + +
      +
      + “完全复制”将创建内容的副本,并拷贝到指定栏目下,副本和原始内容之间不存在关系。 + “引用地址”将创建内容的副本,并拷贝到指定栏目下,内容副本仅是原内容的引用,内容副本链接将和原内容链接一致。 + + + “引用内容”将创建内容的副本,并拷贝到指定栏目下,同时内容副本的数据与原内容保持同步,内容副本的链接指向副本内容。 +
      +
      + + + + + + + + + + + + + + + + + + +
      内容Id 内容标题(点击查看) 添加时间状态
      {{ content.id }}{{ content.addDate }}
      +
      +
      +
      + + +
      @section Scripts{ + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCopy.js b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCopy.js new file mode 100644 index 000000000..26709ac64 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCopy.js @@ -0,0 +1,103 @@ +var $url = '/pages/cms/contentsLayerCopy'; +var $urlGetChannels = '/pages/cms/contentsLayerCopy/actions/getChannels'; + +var $data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentIds: utils.getQueryString('contentIds'), + pageLoad: false, + pageAlert: null, + contents: null, + sites: [], + channels: [], + site: {}, + channel: null, + copyType: 'Copy', + isSubmit: false +}; + +var $methods = { + loadConfig: function () { + var $this = this; + + $api.get($url, { + params: { + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds + } + }).then(function (response) { + var res = response.data; + + $this.contents = res.value; + $this.sites = res.sites; + $this.channels = res.channels; + $this.site = res.site; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + onSiteSelect(site) { + var $this = this; + + if (site.id === $this.site.id) return; + $this.site = site; + + utils.loading(true); + $api.get($urlGetChannels, { + params: { + siteId: $this.site.id + } + }).then(function (response) { + var res = response.data; + + $this.channels = res.value; + $this.channel = null; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + onChannelSelect(channel) { + this.channel = channel; + }, + + btnSubmitClick: function () { + var $this = this; + $this.isSubmit = true; + if (!$this.channel) return; + + utils.loading(true); + $api.post($url, { + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds, + targetSiteId: $this.site.id, + targetChannelId: $this.channel.id + }).then(function (response) { + var res = response.data; + + parent.location.reload(true); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } +}; + +Vue.component("multiselect", window.VueMultiselect.default); + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCut.cshtml b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCut.cshtml new file mode 100644 index 000000000..3afaa53b3 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCut.cshtml @@ -0,0 +1,48 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles{ + } +
      + + + + + +
      +
      + + + + + +
      + + + + + + + + + + + + + + + + + +
      内容Id 内容标题(点击查看) 添加时间状态
      {{ content.id }}{{ content.addDate }}
      +
      +
      + + +
      @section Scripts{ + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCut.js b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCut.js new file mode 100644 index 000000000..7f0f87e51 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerCut.js @@ -0,0 +1,108 @@ +var $url = '/pages/cms/contentsLayerCut'; +var $urlGetChannels = '/pages/cms/contentsLayerCut/actions/getChannels'; + +var $data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentIds: utils.getQueryString('contentIds'), + pageLoad: false, + pageAlert: null, + contents: null, + sites: [], + channels: [], + site: {}, + channel: null, + isSubmit: false +}; + +var $methods = { + loadConfig: function () { + var $this = this; + + $api.get($url, { + params: { + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds + } + }).then(function (response) { + var res = response.data; + + $this.contents = res.value; + $this.sites = res.sites; + $this.channels = res.channels; + $this.site = res.site; + + $this.pageAlert = { + type: 'danger', + html: '此操作将把以下 ' + + $this.contents.length + + ' 篇内容转移至指定栏目,确定吗?' + }; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + onSiteSelect(site) { + var $this = this; + if (site.id === $this.site.id) return; + $this.site = site; + + utils.loading(true); + $api.get($urlGetChannels, { + params: { + siteId: $this.site.id + } + }).then(function (response) { + var res = response.data; + + $this.channels = res.value; + $this.channel = null; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + onChannelSelect(channel) { + this.channel = channel; + }, + + btnSubmitClick: function () { + var $this = this; + $this.isSubmit = true; + if (!$this.channel) return; + + utils.loading(true); + $api.post($url, { + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds, + targetSiteId: $this.site.id, + targetChannelId: $this.channel.id + }).then(function (response) { + var res = response.data; + + parent.location.reload(true); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } +}; + +Vue.component("multiselect", window.VueMultiselect.default); + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerDelete.cshtml b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerDelete.cshtml new file mode 100644 index 000000000..c7c0d02c6 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerDelete.cshtml @@ -0,0 +1,41 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles { } + + + + + + + + + + + + + + + + + + +
      内容Id 内容标题 添加时间状态
      {{ content.id }}{{ content.addDate }}
      +
      + +
      + + + + + 选择保留页面将仅在数据库中删除内容。 +
      +
      +
      +
      +
      + + +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerDelete.js b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerDelete.js new file mode 100644 index 000000000..4a5a4fdb0 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerDelete.js @@ -0,0 +1,65 @@ +var $url = '/pages/cms/contentsLayerDelete'; + +var $data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentIds: utils.getQueryString('contentIds'), + pageLoad: false, + pageAlert: null, + contents: null, + isRetainFiles: false +}; + +var $methods = { + loadConfig: function () { + var $this = this; + + $api.get($url, { + params: { + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds + } + }).then(function (response) { + var res = response.data; + + $this.contents = res.value; + $this.pageAlert = { + type: 'danger', + html: '此操作将把以下 ' + $this.contents.length + ' 篇内容放入回收站,确定吗?' + }; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + btnSubmitClick: function () { + var $this = this; + + utils.loading(true); + $api.post($url, { + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds, + isRetainFiles: $this.isRetainFiles + }).then(function (response) { + var res = response.data; + + parent.location.reload(true); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerExport.cshtml b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerExport.cshtml new file mode 100644 index 000000000..10c2051bf --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerExport.cshtml @@ -0,0 +1,75 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles { } + +
      + +
      +
      + + +
      +
      + + +
      +
      + 导出压缩包能够将内容以及内容相关的图片、附件等文件一并导出,导出Excel则仅能导出数据。 +
      +
      +
      + +
      + + +
      +
      +
      +
      + + +
      +
      +
      +
      + +
      +
      + + +
      +
      + + +
      +
      +
      开始时间: 结束时间: +
      +
      +
      +
      + +
      + + +
      +
      +
      +
      + + +
      +
      +
      +
      +
      + + +
      @section Scripts{ + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerExport.js b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerExport.js new file mode 100644 index 000000000..a1ee615b1 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerExport.js @@ -0,0 +1,126 @@ +var $url = '/pages/cms/contentsLayerExport'; + +var $data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + pageLoad: false, + pageAlert: null, + columns: null, + checkedLevels: null, + checkedLevel: null, + exportType: 'zip', + isAllCheckedLevel: true, + checkedLevelKeys: [], + isAllDate: true, + startDate: new Date(new Date().setDate(new Date().getDate() - 30)), + endDate: new Date(), + isAllColumns: false, + columnNames: [] +}; + +var $methods = { + loadConfig: function () { + var $this = this; + $api.get($url, { + params: { + siteId: $this.siteId, + channelId: $this.channelId + } + }).then(function (response) { + var res = response.data; + + $this.columns = res.value; + $this.columnNames = []; + for (var i = 0; i < $this.columns.length; i++) { + var attribute = $this.columns[i]; + if (attribute.isList) { + $this.columnNames.push(attribute.attributeName); + } + } + $this.checkedLevels = res.checkedLevels; + for (var i = 0; i < $this.checkedLevels.length; i++) { + var checkedLevel = $this.checkedLevels[i]; + $this.checkedLevelKeys.push(checkedLevel.key); + } + $this.checkedLevel = res.checkedLevel; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + btnIsAllCheckedLevelClick: function () { + this.isAllCheckedLevel = !this.isAllCheckedLevel; + this.checkedLevelKeys = []; + if (this.isAllCheckedLevel) { + for (var i = 0; i < this.checkedLevels.length; i++) { + var checkedLevel = this.checkedLevels[i]; + this.checkedLevelKeys.push(checkedLevel.key); + } + } + }, + + btnIsAllColumnsClick: function () { + this.isAllColumns = !this.isAllColumns; + this.columnNames = ['Title']; + if (this.isAllColumns) { + for (var i = 0; i < this.columns.length; i++) { + var column = this.columns[i]; + this.columnNames.push(column.attributeName); + } + } + }, + + btnSubmitClick: function () { + var $this = this; + this.pageAlert = null; + + if (this.checkedLevelKeys.length === 0) { + return this.pageAlert = { + type: 'danger', + html: '必须至少选择一项内容状态' + }; + } + + utils.loading(true); + $api.post($url, { + siteId: $this.siteId, + channelId: $this.channelId, + exportType: $this.exportType, + isAllCheckedLevel: $this.isAllCheckedLevel, + checkedLevelKeys: $this.checkedLevelKeys, + isAllDate: $this.isAllDate, + startDate: $this.startDate, + endDate: $this.endDate, + columnNames: $this.columnNames + }).then(function (response) { + var res = response.data; + + if (res.isSuccess) { + window.open(res.value); + parent.layer.closeAll(); + } else { + return $this.pageAlert = { + type: 'danger', + html: '没有符合条件的内容,请重新选择导出条件' + }; + } + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } +}; + +Vue.component("date-picker", window.DatePicker.default); + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerGroup.cshtml b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerGroup.cshtml new file mode 100644 index 000000000..0045dfd68 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerGroup.cshtml @@ -0,0 +1,46 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles { } + + +
      + + +
      +
      +
      + + +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerGroup.js b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerGroup.js new file mode 100644 index 000000000..974bb0be8 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerGroup.js @@ -0,0 +1,68 @@ +var $url = '/pages/cms/contentsLayerGroup'; + +var $data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentIds: utils.getQueryString('contentIds'), + pageLoad: false, + pageAlert: null, + pageType: 'setGroup', + groupNames: null, + selected: [], + groupName: '', + description: '' +}; + +var $methods = { + loadConfig: function () { + var $this = this; + + $api.get($url, { + params: { + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds + } + }).then(function (response) { + var res = response.data; + + $this.groupNames = res.value; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + btnSubmitClick: function () { + var $this = this; + + utils.loading(true); + $api.post($url, { + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds, + pageType: $this.pageType, + groupNames: $this.selected.join(','), + groupName: $this.groupName, + description: $this.description + }).then(function (response) { + var res = response.data; + + parent.location.reload(true); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerImport.cshtml b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerImport.cshtml new file mode 100644 index 000000000..e06c0b604 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerImport.cshtml @@ -0,0 +1,59 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles { } + +
      + +
      +
      + + +
      +
      + + +
      +
      + + +
      +
      + 请选择后台导出的压缩包,系统能够将内容以及内容相关的图片、附件等文件一并导入。 + 请选择Excel文件,系统将导入Excel文件对应的字段数据。 + 请选择以.txt结尾的纯文本文件,文件名将作为内容标题,文件内容将作为正文导入。 +
      +
      + 点击批量上传文件或者将文件拖拽到此区域
      +
      +
      +
      +
      +

      {{ file.fileName }}
      大小:{{ Math.round(file.length/1024) + ' KB' }}

      + 删 除 +
      +
      +
      +
      +
      + +
      +
      + + +
      +
      +
      +
      + + +
      +
      +
      + + +
      @section Scripts{ + + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerImport.js b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerImport.js new file mode 100644 index 000000000..557c90b81 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerImport.js @@ -0,0 +1,153 @@ +var $url = '/pages/cms/contentsLayerImport'; +var $uploadUrl = $apiUrl + '/pages/cms/contentsLayerImport'; + +var $data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + pageLoad: false, + pageAlert: null, + checkedLevels: null, + importType: 'zip', + file: null, + files: [], + checkedLevel: null, + isOverride: false +}; + +var $methods = { + loadConfig: function () { + var $this = this; + + $api.get($url, { + params: { + siteId: $this.siteId, + channelId: $this.channelId + } + }).then(function (response) { + var res = response.data; + + $this.checkedLevels = res.checkedLevels; + $this.checkedLevel = res.value; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + setTimeout($this.loadUploader, 100); + }); + }, + + loadUploader: function () { + var $this = this; + + var E = Q.event, + Uploader = Q.Uploader; + + var boxDropArea = document.getElementById("drop-area"); + + var uploader = new Uploader({ + url: $uploadUrl + '/actions/upload?siteId=' + $this.siteId + '&channelId=' + $this.channelId, + target: document.getElementById("drop-area"), + allows: ".zip,.csv,.txt", + on: { + add: function (task) { + if (task.ext != '.' + $this.importType) { + swal2({ + title: '文件错误!', + text: '允许上传的文件格式为:.' + $this.importType, + type: 'error', + showConfirmButton: false + }); + return false; + } + }, + complete: function (task) { + var json = task.json; + if (!json || json.ret != 1) { + return swal2({ + title: "文件上传失败!", + type: 'error', + showConfirmButton: false + }); + } + + if (json && json.fileName) { + $this.files.push(json); + } + } + } + }); + + //若浏览器不支持html5上传,则禁止拖拽上传 + if (!Uploader.support.html5 || !uploader.html5) { + boxDropArea.innerHTML = "点击批量上传文件"; + return; + } + + //阻止浏览器默认拖放行为 + E.add(boxDropArea, "dragleave", E.stop); + E.add(boxDropArea, "dragenter", E.stop); + E.add(boxDropArea, "dragover", E.stop); + + E.add(boxDropArea, "drop", function (e) { + E.stop(e); + + //获取文件对象 + var files = e.dataTransfer.files; + + uploader.addList(files); + }); + }, + + del: function (file) { + this.files.splice(this.files.indexOf(file), 1); + }, + + getFileNames: function () { + var arr = []; + for (var i = 0; i < this.files.length; i++) { + arr.push(this.files[i].fileName); + } + return arr; + }, + + btnSubmitClick: function () { + var $this = this; + this.pageAlert = null; + + var fileNames = this.getFileNames().join(','); + if (!fileNames) { + return swal2({ + title: "请选择需要导入的文件!", + type: 'warning', + showConfirmButton: false + }); + } + + utils.loading(true); + $api.post($url, { + siteId: $this.siteId, + channelId: $this.channelId, + importType: $this.importType, + fileNames: $this.getFileNames(), + checkedLevel: $this.checkedLevel, + isOverride: $this.isOverride + }).then(function (response) { + var res = response.data; + + parent.location.reload(true); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerState.cshtml b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerState.cshtml new file mode 100644 index 000000000..93f424a56 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerState.cshtml @@ -0,0 +1,36 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles { } + +
      + +
      +
      +
      + +
      +
      + + + + + + + + + + + + + + + +
      审核人审核时间原因
      {{ contentCheck.userName }} {{ contentCheck.checkDate }} {{ contentCheck.reasons }}
      +
      +
      + + +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerState.js b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerState.js new file mode 100644 index 000000000..64326fb97 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerState.js @@ -0,0 +1,59 @@ +var $url = '/pages/cms/contentsLayerState'; + +var $data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentId: parseInt(utils.getQueryString('contentId')), + pageLoad: false, + pageAlert: null, + contentChecks: null, + title: null, + checkState: null +}; + +var $methods = { + loadConfig: function () { + var $this = this; + + $api.get($url, { + params: { + siteId: $this.siteId, + channelId: $this.channelId, + contentId: $this.contentId + } + }).then(function (response) { + var res = response.data; + + $this.contentChecks = res.value; + $this.title = res.title; + $this.checkState = res.checkState; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + btnSubmitClick: function () { + window.parent.layer.closeAll(); + window.parent.utils.openLayer({ + title: "审核内容", + url: "contentsLayerCheck.cshtml?siteId=" + + this.siteId + + "&channelId=" + + this.channelId + + "&contentIds=" + + this.contentId, + full: true + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerTaxis.cshtml b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerTaxis.cshtml new file mode 100644 index 000000000..771b17531 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerTaxis.cshtml @@ -0,0 +1,29 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles { } + +
      + +
      + + + + +
      +
      +
      +
      + +
      + +
      +
      +
      +
      +
      + + +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerTaxis.js b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerTaxis.js new file mode 100644 index 000000000..584b6a8b8 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerTaxis.js @@ -0,0 +1,43 @@ +var $url = '/pages/cms/contentsLayerTaxis'; + +var $data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentIds: utils.getQueryString('contentIds'), + pageLoad: false, + pageAlert: null, + isUp: true, + taxis: 1 +}; + +var $methods = { + btnSubmitClick: function () { + var $this = this; + + utils.loading(true); + $api.post($url, { + siteId: $this.siteId, + channelId: $this.channelId, + contentIds: $this.contentIds, + isUp: $this.isUp, + taxis: $this.taxis + }).then(function (response) { + var res = response.data; + + parent.location.reload(true); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.pageLoad = true; + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerView.cshtml b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerView.cshtml new file mode 100644 index 000000000..f51d7c34b --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerView.cshtml @@ -0,0 +1,52 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles { } + +
      + +
      +
      +
      +
      + +
      {{ content.getProp(attribute.value) }}
      +
      +
      +
      + +
      {{ content.getProp('tags') }}
      +
      +
      +
      + +
      {{ content.getProp('groupNameCollection') }}
      +
      +
      +
      + +
      {{ content.getProp('lastEditDate') }}
      +
      +
      +
      + +
      {{ content.getProp('addUserName') }}
      +
      +
      +
      + +
      {{ content.getProp('lastEditUserName') }}
      +
      +
      +
      + +
      {{ + content.getProp('checkState') }}
      +
      +
      +
      +
      + +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerView.js b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerView.js new file mode 100644 index 000000000..46f800932 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerView.js @@ -0,0 +1,56 @@ +var $url = '/pages/cms/contentsLayerView'; + +Object.defineProperty(Object.prototype, "getProp", { + value: function (prop) { + var key, self = this; + for (key in self) { + if (key.toLowerCase() == prop.toLowerCase()) { + return self[key]; + } + } + } +}); + +var $data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + contentId: parseInt(utils.getQueryString('contentId')), + pageLoad: false, + pageAlert: null, + content: null, + channelName: null, + attributes: null +}; + +var $methods = { + loadConfig: function () { + var $this = this; + + $api.get($url, { + params: { + siteId: $this.siteId, + channelId: $this.channelId, + contentId: $this.contentId + } + }).then(function (response) { + var res = response.data; + + $this.content = res.value; + $this.channelName = res.channelName; + $this.attributes = res.attributes; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerWord.cshtml b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerWord.cshtml new file mode 100644 index 000000000..d849f652b --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerWord.cshtml @@ -0,0 +1,60 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles { } + +
      + 点击批量上传Word文件或者将Word文件拖拽到此区域
      +
      +
      +
      +
      +

      {{ file.fileName }}
      大小:{{ Math.round(file.length/1024) + ' KB' }}

      + 删 除 +
      +
      +
      +
      +
      + +
      +
      + + + + + + +
      + + + + + + + + + + +
      +
      +
      +
      +
      + +
      + +
      +
      +
      +
      +
      + + +
      @section Scripts{ + + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/contentsLayerWord.js b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerWord.js new file mode 100644 index 000000000..25038e926 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/contentsLayerWord.js @@ -0,0 +1,164 @@ +var $url = '/pages/cms/contentsLayerWord'; +var $uploadUrl = $apiUrl + '/pages/cms/contentsLayerWord'; + +var $data = { + siteId: parseInt(utils.getQueryString('siteId')), + channelId: parseInt(utils.getQueryString('channelId')), + pageLoad: false, + pageAlert: null, + file: null, + files: [], + isFirstLineTitle: false, + isFirstLineRemove: true, + isClearFormat: true, + isFirstLineIndent: true, + isClearFontSize: true, + isClearFontFamily: true, + isClearImages: false, + checkedLevels: null, + checkedLevel: null +}; + +var $methods = { + loadConfig: function () { + var $this = this; + + $api.get($url, { + params: { + siteId: $this.siteId, + channelId: $this.channelId + } + }).then(function (response) { + var res = response.data; + + $this.checkedLevels = res.value; + $this.checkedLevel = res.checkedLevel; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + setTimeout($this.loadUploader, 100); + }); + }, + + loadUploader: function () { + var $this = this; + + var E = Q.event, + Uploader = Q.Uploader; + + var boxDropArea = document.getElementById("drop-area"); + + var uploader = new Uploader({ + url: $uploadUrl + '/actions/upload?siteId=' + $this.siteId + '&channelId=' + $this.channelId, + target: document.getElementById("drop-area"), + allows: ".doc,.docx", + on: { + add: function (task) { + if (task.disabled) { + return swal2({ + title: "允许上传的文件格式为:" + this.ops.allows, + type: 'warning', + confirmButtonText: '关 闭' + }); + } + }, + complete: function (task) { + var json = task.json; + if (!json || json.ret != 1) { + return swal2({ + title: "上传失败!", + type: 'warning', + confirmButtonText: '关 闭' + }); + } + + if (json && json.fileName) { + $this.files.push(json); + } + } + } + }); + + //若浏览器不支持html5上传,则禁止拖拽上传 + if (!Uploader.support.html5 || !uploader.html5) { + boxDropArea.innerHTML = "点击批量上传Word文件"; + return; + } + + //阻止浏览器默认拖放行为 + E.add(boxDropArea, "dragleave", E.stop); + E.add(boxDropArea, "dragenter", E.stop); + E.add(boxDropArea, "dragover", E.stop); + + E.add(boxDropArea, "drop", function (e) { + E.stop(e); + + //获取文件对象 + var files = e.dataTransfer.files; + + uploader.addList(files); + }); + }, + + del: function (file) { + this.files.splice(this.files.indexOf(file), 1); + }, + + getFileNames: function () { + var arr = []; + for (var i = 0; i < this.files.length; i++) { + arr.push(this.files[i].fileName); + } + return arr; + }, + + btnSubmitClick: function () { + var $this = this; + var fileNames = this.getFileNames().join(','); + if (!fileNames) { + return swal2({ + title: "请选择需要导入的Word文件!", + type: 'warning', + showConfirmButton: '关 闭' + }); + } + + utils.loading(true); + $api.post($url, { + siteId: $this.siteId, + channelId: $this.channelId, + isFirstLineTitle: $this.isFirstLineTitle, + isFirstLineRemove: $this.isFirstLineRemove, + isClearFormat: $this.isClearFormat, + isFirstLineIndent: $this.isFirstLineIndent, + isClearFontSize: $this.isClearFontSize, + isClearFontFamily: $this.isClearFontFamily, + isClearImages: $this.isClearImages, + checkedLevel: $this.checkedLevel, + fileNames: fileNames + }).then(function (response) { + var res = response.data; + + var contentIdList = res.value; + if (contentIdList.length === 1) { + parent.location.href = 'pageContentAdd.aspx?siteId=' + $this.siteId + '&channelId=' + $this.channelId + '&id=' + contentIdList[0]; + } else { + parent.location.reload(true); + } + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/create.cshtml b/net452/SiteServer.Web/SiteServer/Cms/create.cshtml new file mode 100644 index 000000000..ff0cb0296 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/create.cshtml @@ -0,0 +1,57 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } +
      +
      生成栏目页
      +
      生成内容页
      +

      点击空白处可以选中栏目

      + + + + + + +
      +
      + + + +
      +
      + + +
      +
      + + + + {{ channel.channelName }} + ({{ channel.contentNum }}) + +
      +
      +
      +
      +
      + + + + + + + + +
      + + +
      +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/create.js b/net452/SiteServer.Web/SiteServer/Cms/create.js new file mode 100644 index 000000000..5eac59076 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/create.js @@ -0,0 +1,225 @@ +var $url = '/pages/cms/create'; +var $urlAll = '/pages/cms/create/all'; +var $siteId = parseInt(utils.getQueryString('siteId')); +var $type = utils.getQueryString('type'); + +var $data = { + pageLoad: false, + pageAlert: null, + pageType: null, + siteId: $siteId, + type: $type, + root: null, + pageChannels: [], + isAllChecked: false, + isDescendent: false, + isChannelPage: $type === 'channels', + isContentPage: $type === 'contents', + scope: 'all' +}; + +var $methods = { + displayChildren: function (channel, event) { + channel.isOpen ? this.hideChildren(channel) : this.showChildren(channel); + event.stopPropagation(); + }, + + toggleChecked: function (channel) { + channel.isChecked = !channel.isChecked; + if (!channel.isChecked) { + this.isAllChecked = false; + } + }, + + selectAll: function () { + this.isAllChecked = !this.isAllChecked; + for (var i = 0; i < this.pageChannels.length; i++) { + this.pageChannels[i].isChecked = this.isAllChecked; + } + this.reload(); + }, + + create: function () { + var $this = this; + + var channelIdList = []; + for (var i = 0; i < this.pageChannels.length; i++) { + if (this.pageChannels[i].isChecked) { + channelIdList.push(this.pageChannels[i].id); + } + } + + if (!$this.isAllChecked && channelIdList.length === 0) return; + if (!$this.isChannelPage && !this.isContentPage) return; + + utils.loading(true); + $api.post($url, { + siteId: $this.siteId, + channelIdList: $this.isAllChecked ? [] : channelIdList, + isAllChecked: $this.isAllChecked, + isDescendent: $this.isDescendent, + isChannelPage: $this.isChannelPage, + isContentPage: $this.isContentPage, + scope: $this.scope + }).then(function (response) { + var res = response.data; + + location.href = 'createStatus.cshtml?siteId=' + $this.siteId; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + createIndex: function () { + var $this = this; + + utils.loading(true); + $api.post($url, { + siteId: $this.siteId, + channelIdList: [$this.siteId], + isAllChecked: false, + isDescendent: false, + isChannelPage: true, + isContentPage: false + }).then(function (response) { + var res = response.data; + + location.href = 'createStatus.cshtml?siteId=' + $this.siteId; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + createAll: function () { + var $this = this; + + utils.loading(true); + $api.post($urlAll, { + siteId: $this.siteId + }).then(function (response) { + var res = response.data; + + location.href = 'createStatus.cshtml?siteId=' + $this.siteId; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + loadChannels: function () { + var $this = this; + + $api.get($url, { + params: { + siteId: $siteId, + parentId: $siteId + } + }).then(function (response) { + var res = response.data; + + $this.root = _.assign({}, res.parent, { + contentNum: res.countDict[res.parent.id], + isOpen: true, + isLoading: false, + isChecked: false, + children: [] + }); + + for (var i = 0; i < res.value.length; i++) { + var channel = _.assign({}, res.value[i], { + contentNum: res.countDict[res.value[i].id], + isOpen: false, + isLoading: false, + isChecked: false, + children: [] + }); + $this.root.children.push(channel); + } + + $this.reload(); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + reload: function () { + this.pageChannels = []; + this.addPageChannels(this.root); + }, + + addPageChannels: function (channel) { + this.pageChannels.push(channel); + if (channel.isOpen) { + for (var i = 0; i < channel.children.length; i++) { + var child = channel.children[i]; + this.addPageChannels(child); + } + } + }, + + showChildren: function (channel) { + var $this = this; + + channel.isOpen = true; + if (channel.childrenCount > 0 && channel.children.length === 0) { + channel.children = []; + channel.isLoading = true; + + $api.get($url, { + params: { + siteId: $siteId, + parentId: channel.id + } + }).then(function (response) { + var res = response.data; + + for (var i = 0; i < res.value.length; i++) { + var child = _.assign({}, res.value[i], { + contentNum: res.countDict[res.value[i].id], + isOpen: false, + isLoading: false, + isChecked: $this.isAllChecked, + children: [] + }); + + channel.children.push(child); + } + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + channel.isLoading = false; + + $this.reload(); + }); + } else { + $this.reload(); + } + }, + + hideChildren: function (channel) { + channel.isOpen = false; + this.reload(); + } +}; + +var $vue = new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + if (this.type === 'index') { + this.createIndex(); + } else if (this.type === 'all') { + this.createAll(); + } else { + this.loadChannels(); + } + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/createStatus.cshtml b/net452/SiteServer.Web/SiteServer/Cms/createStatus.cshtml new file mode 100644 index 000000000..a91a71030 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/createStatus.cshtml @@ -0,0 +1,75 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } +
      +
      +
      +
      +
      +

      剩余页面:

      +
      +
      + {{ channelsCount }} + + 栏目页 + +
      +
      + {{ contentsCount }} + + 内容页 + +
      +
      + {{ filesCount }} + + 文件页 + +
      +
      + {{ specialsCount }} + + 专题页 + +
      +
      + +
      +
      +
      +
      +
      + +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/createStatus.js b/net452/SiteServer.Web/SiteServer/Cms/createStatus.js new file mode 100644 index 000000000..3106e65b6 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/createStatus.js @@ -0,0 +1,69 @@ +var $url = '/pages/cms/createStatus'; +var $urlCancel = '/pages/cms/createStatus/actions/cancel'; + +var $data = { + pageLoad: false, + pageAlert: null, + pageType: null, + siteId: parseInt(utils.getQueryString('siteId')), + tasks: null, + channelsCount: null, + contentsCount: null, + filesCount: null, + specialsCount: null, + timeoutId: null +}; + +var $methods = { + load: function () { + var $this = this; + + $api.get($url, { + params: { + siteId: $this.siteId + } + }).then(function (response) { + var res = response.data; + + $this.tasks = res.value.tasks; + $this.channelsCount = res.value.channelsCount; + $this.contentsCount = res.value.contentsCount; + $this.filesCount = res.value.filesCount; + $this.specialsCount = res.value.specialsCount; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + $this.timeoutId = setTimeout(function () { + $this.load(); + }, 3000); + }); + }, + + btnCancelClick: function () { + var $this = this; + clearTimeout(this.timeoutId); + + utils.loading(true); + $api.post($urlCancel, { + siteId: $this.siteId + }).then(function (response) { + var res = response.data; + + $this.load(); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } +}; + +var $vue = new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.load(); + } +}); \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/js/jQueryRotateCompressed.js b/net452/SiteServer.Web/SiteServer/Cms/js/jQueryRotateCompressed.js similarity index 100% rename from SiteServer.Web/SiteServer/Cms/js/jQueryRotateCompressed.js rename to net452/SiteServer.Web/SiteServer/Cms/js/jQueryRotateCompressed.js diff --git a/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/GPL-LICENSE.txt b/net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/GPL-LICENSE.txt similarity index 100% rename from SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/GPL-LICENSE.txt rename to net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/GPL-LICENSE.txt diff --git a/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/MIT-LICENSE.txt b/net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/MIT-LICENSE.txt similarity index 100% rename from SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/MIT-LICENSE.txt rename to net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/MIT-LICENSE.txt diff --git a/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/border-anim-h.gif b/net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/border-anim-h.gif similarity index 100% rename from SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/border-anim-h.gif rename to net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/border-anim-h.gif diff --git a/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/border-anim-v.gif b/net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/border-anim-v.gif similarity index 100% rename from SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/border-anim-v.gif rename to net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/border-anim-v.gif diff --git a/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/border-h.gif b/net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/border-h.gif similarity index 100% rename from SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/border-h.gif rename to net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/border-h.gif diff --git a/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/border-v.gif b/net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/border-v.gif similarity index 100% rename from SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/border-v.gif rename to net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/border-v.gif diff --git a/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/imgareaselect-animated.css b/net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/imgareaselect-animated.css similarity index 100% rename from SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/imgareaselect-animated.css rename to net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/imgareaselect-animated.css diff --git a/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/imgareaselect-default.css b/net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/imgareaselect-default.css similarity index 100% rename from SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/imgareaselect-default.css rename to net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/imgareaselect-default.css diff --git a/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/imgareaselect-deprecated.css b/net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/imgareaselect-deprecated.css similarity index 100% rename from SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/imgareaselect-deprecated.css rename to net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/css/imgareaselect-deprecated.css diff --git a/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/scripts/jquery.imgareaselect.js b/net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/scripts/jquery.imgareaselect.js similarity index 100% rename from SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/scripts/jquery.imgareaselect.js rename to net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/scripts/jquery.imgareaselect.js diff --git a/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/scripts/jquery.imgareaselect.min.js b/net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/scripts/jquery.imgareaselect.min.js similarity index 100% rename from SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/scripts/jquery.imgareaselect.min.js rename to net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/scripts/jquery.imgareaselect.min.js diff --git a/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/scripts/jquery.imgareaselect.pack.js b/net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/scripts/jquery.imgareaselect.pack.js similarity index 100% rename from SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/scripts/jquery.imgareaselect.pack.js rename to net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/scripts/jquery.imgareaselect.pack.js diff --git a/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/scripts/jquery.min.js b/net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/scripts/jquery.min.js similarity index 100% rename from SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/scripts/jquery.min.js rename to net452/SiteServer.Web/SiteServer/Cms/js/jquery.imgareaselect/scripts/jquery.min.js diff --git a/SiteServer.Web/SiteServer/Cms/js/jquery.qrcode.min.js b/net452/SiteServer.Web/SiteServer/Cms/js/jquery.qrcode.min.js similarity index 100% rename from SiteServer.Web/SiteServer/Cms/js/jquery.qrcode.min.js rename to net452/SiteServer.Web/SiteServer/Cms/js/jquery.qrcode.min.js diff --git a/SiteServer.Web/SiteServer/Cms/modalAddToGroup.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalAddToGroup.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalAddToGroup.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalAddToGroup.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalChannelEdit.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalChannelEdit.aspx similarity index 98% rename from SiteServer.Web/SiteServer/Cms/modalChannelEdit.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalChannelEdit.aspx index 666f95393..1e5611682 100644 --- a/SiteServer.Web/SiteServer/Cms/modalChannelEdit.aspx +++ b/net452/SiteServer.Web/SiteServer/Cms/modalChannelEdit.aspx @@ -147,7 +147,7 @@
      -
      diff --git a/SiteServer.Web/SiteServer/Cms/modalChannelImport.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalChannelImport.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalChannelImport.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalChannelImport.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalChannelMultipleSelect.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalChannelMultipleSelect.aspx similarity index 92% rename from SiteServer.Web/SiteServer/Cms/modalChannelMultipleSelect.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalChannelMultipleSelect.aspx index 5e5b37688..6b19514af 100644 --- a/SiteServer.Web/SiteServer/Cms/modalChannelMultipleSelect.aspx +++ b/net452/SiteServer.Web/SiteServer/Cms/modalChannelMultipleSelect.aspx @@ -23,7 +23,7 @@
      - +
      diff --git a/SiteServer.Web/SiteServer/Cms/modalChannelSelect.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalChannelSelect.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalChannelSelect.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalChannelSelect.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalChannelsAdd.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalChannelsAdd.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalChannelsAdd.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalChannelsAdd.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalCheckState.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalCheckState.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalCheckState.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalCheckState.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalConfigurationCreateChannel.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalConfigurationCreateChannel.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalConfigurationCreateChannel.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalConfigurationCreateChannel.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalContentAttributes.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalContentAttributes.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalContentAttributes.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalContentAttributes.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalContentCheck.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalContentCheck.aspx similarity index 96% rename from SiteServer.Web/SiteServer/Cms/modalContentCheck.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalContentCheck.aspx index 23e586e6d..717625f6b 100644 --- a/SiteServer.Web/SiteServer/Cms/modalContentCheck.aspx +++ b/net452/SiteServer.Web/SiteServer/Cms/modalContentCheck.aspx @@ -15,7 +15,7 @@
      - +
      diff --git a/SiteServer.Web/SiteServer/Cms/modalContentCrossSiteTrans.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalContentCrossSiteTrans.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalContentCrossSiteTrans.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalContentCrossSiteTrans.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalContentExport.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalContentExport.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalContentExport.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalContentExport.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalContentGroupAdd.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalContentGroupAdd.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalContentGroupAdd.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalContentGroupAdd.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalContentImport.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalContentImport.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalContentImport.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalContentImport.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalContentMultipleSelect.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalContentMultipleSelect.aspx similarity index 95% rename from SiteServer.Web/SiteServer/Cms/modalContentMultipleSelect.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalContentMultipleSelect.aspx index 305310335..a5ad893c5 100644 --- a/SiteServer.Web/SiteServer/Cms/modalContentMultipleSelect.aspx +++ b/net452/SiteServer.Web/SiteServer/Cms/modalContentMultipleSelect.aspx @@ -29,7 +29,6 @@ diff --git a/SiteServer.Web/SiteServer/Cms/modalContentTagAdd.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalContentTagAdd.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalContentTagAdd.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalContentTagAdd.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalContentTaxis.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalContentTaxis.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalContentTaxis.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalContentTaxis.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalContentTidyUp.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalContentTidyUp.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalContentTidyUp.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalContentTidyUp.aspx diff --git a/net452/SiteServer.Web/SiteServer/Cms/modalContentView.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalContentView.aspx new file mode 100644 index 000000000..ae36be5a1 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/modalContentView.aspx @@ -0,0 +1,99 @@ +<%@ Page Language="C#" validateRequest="false" Inherits="SiteServer.BackgroundPages.Cms.ModalContentView" %> + <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + + + +
      + +
      + +
      +
      +
      + +
      + +
      + +
      +
      +
      + + + + + + + + +
      + +
      + +
      +
      +
      +
      + + +
      + +
      + +
      +
      +
      +
      + +
      + +
      + +
      +
      +
      + +
      + +
      + +
      +
      +
      + +
      + +
      + +
      +
      +
      + +
      + +
      + +
      +
      +
      + +
      + +
      + +
      + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/modalCreateChannels.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalCreateChannels.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalCreateChannels.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalCreateChannels.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalCreateDirectory.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalCreateDirectory.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalCreateDirectory.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalCreateDirectory.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalCrossSiteTransEdit.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalCrossSiteTransEdit.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalCrossSiteTransEdit.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalCrossSiteTransEdit.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalCuttingImage.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalCuttingImage.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalCuttingImage.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalCuttingImage.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalExportMessage.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalExportMessage.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalExportMessage.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalExportMessage.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalFileChangeName.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalFileChangeName.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalFileChangeName.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalFileChangeName.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalFileEdit.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalFileEdit.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalFileEdit.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalFileEdit.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalFilePathRule.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalFilePathRule.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalFilePathRule.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalFilePathRule.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalFileView.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalFileView.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalFileView.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalFileView.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalImport.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalImport.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalImport.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalImport.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalMessage.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalMessage.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalMessage.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalMessage.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalNodeGroupAdd.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalNodeGroupAdd.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalNodeGroupAdd.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalNodeGroupAdd.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalProgressBar.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalProgressBar.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalProgressBar.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalProgressBar.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalRelatedFieldAdd.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalRelatedFieldAdd.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalRelatedFieldAdd.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalRelatedFieldAdd.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalRelatedFieldItemAdd.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalRelatedFieldItemAdd.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalRelatedFieldItemAdd.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalRelatedFieldItemAdd.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalRelatedFieldItemEdit.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalRelatedFieldItemEdit.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalRelatedFieldItemEdit.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalRelatedFieldItemEdit.aspx diff --git a/net452/SiteServer.Web/SiteServer/Cms/modalSelectColumns.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalSelectColumns.aspx new file mode 100644 index 000000000..0622be9d1 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/modalSelectColumns.aspx @@ -0,0 +1,50 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.ModalSelectColumns" Trace="false"%> + <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + +
      + + +
      + +
      + +
      +
      +
      + +
      + +
      + + + + + + +
      + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/modalSelectFile.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalSelectFile.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalSelectFile.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalSelectFile.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalSelectImage.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalSelectImage.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalSelectImage.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalSelectImage.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalSelectVideo.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalSelectVideo.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalSelectVideo.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalSelectVideo.aspx diff --git a/net452/SiteServer.Web/SiteServer/Cms/modalSiteSelect.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalSiteSelect.aspx new file mode 100644 index 000000000..0edbfcd62 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/modalSiteSelect.aspx @@ -0,0 +1,46 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.ModalSiteSelect" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      @@ -36,7 +36,7 @@ - +
      栏目: -
      + + + + + + + + + + + + + + + + + + +
      站点名称文件夹Web访问地址
      + + + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/modalSpecialAdd.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalSpecialAdd.aspx new file mode 100644 index 000000000..1a5e51c64 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/modalSpecialAdd.aspx @@ -0,0 +1,62 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.ModalSpecialAdd" Trace="false"%> + <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      + +
      + +
      +
      + + +
      +
      +
      + +
      + +
      +
      + + +
      +
      + +
      + +
      + +
      +
      + +
      +
      +
      + +
      + +
      + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/modalSpecialUpload.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalSpecialUpload.aspx new file mode 100644 index 000000000..32223d7ce --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/modalSpecialUpload.aspx @@ -0,0 +1,45 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.ModalSpecialUpload" Trace="false"%> + <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      + +
      + +
      +
      +
      +
      + +
      + +
      + +
      +
      + +
      +
      + +
      + +
      + + +
      + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/modalTableStyleAdd.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalTableStyleAdd.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalTableStyleAdd.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalTableStyleAdd.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalTableStyleImport.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalTableStyleImport.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalTableStyleImport.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalTableStyleImport.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalTableStyleValidateAdd.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalTableStyleValidateAdd.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalTableStyleValidateAdd.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalTableStyleValidateAdd.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalTableStylesAdd.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalTableStylesAdd.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalTableStylesAdd.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalTableStylesAdd.aspx diff --git a/net452/SiteServer.Web/SiteServer/Cms/modalTemplateAssetsConfig.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalTemplateAssetsConfig.aspx new file mode 100644 index 000000000..b4628d465 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/modalTemplateAssetsConfig.aspx @@ -0,0 +1,34 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.ModalTemplateAssetsConfig" Trace="false"%> + <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      + + + + 文件夹相对路径指相对于站点的路径,如dir或者assets/dir + +
      + +
      + +
      + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/modalTemplateFilePathRule.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalTemplateFilePathRule.aspx new file mode 100644 index 000000000..fc921fbb3 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/modalTemplateFilePathRule.aspx @@ -0,0 +1,107 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.ModalTemplateFilePathRule" Trace="false"%> + <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + +
      + +
      + +
      +
      + 设置后链接将指向此地址 + +
      +
      +
      + +
      + +
      +
      + 设置此栏目的链接与子栏目及内容的关系 +
      +
      +
      + +
      + +
      +
      + +
      +
      +
      + +
      + +
      + +
      +
      + +
      +
      + 系统生成文件时采取的下级栏目页文件名规则 +
      +
      + + +
      + +
      + +
      +
      + +
      +
      + 系统生成文件时采取的下级内容页文件名规则 +
      +
      + +
      + +
      + + + + +
      +
      +
      +
      + +
      + + + + +
      +
      +
      + +
      + +
      + + +
      + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/modalTemplateRestore.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalTemplateRestore.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalTemplateRestore.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalTemplateRestore.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalTemplateView.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalTemplateView.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalTemplateView.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalTemplateView.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalTextEditorImportWord.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalTextEditorImportWord.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalTextEditorImportWord.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalTextEditorImportWord.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertAudio.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertAudio.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalTextEditorInsertAudio.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertAudio.aspx diff --git a/net452/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertImage.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertImage.aspx new file mode 100644 index 000000000..950541a60 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertImage.aspx @@ -0,0 +1,157 @@ +<%@ Page Language="C#" Trace="false" Inherits="SiteServer.BackgroundPages.Cms.ModalTextEditorInsertImage" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + +
      + + +
      + 点击批量上传图片或者将图片拖拽到此区域
      +
      +
      +
      +
      +

      {{ file.fileName }}
      大小:{{ Math.round(file.length/1024) + ' KB' }}

      + 删 除 +
      +
      +
      +
      +
      + + + + + + + + +
      +
      +
      + + +
      + + + + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertImageHandler.ashx b/net452/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertImageHandler.ashx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalTextEditorInsertImageHandler.ashx rename to net452/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertImageHandler.ashx diff --git a/net452/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertVideo.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertVideo.aspx new file mode 100644 index 000000000..c9acb8945 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/modalTextEditorInsertVideo.aspx @@ -0,0 +1,186 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.ModalTextEditorInsertVideo" %> + <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + +
      + +
      + +
      + +
      +
      + 上 传 +
      +
      +
      +
      +
      + + + +
      +
      + + + + +
      +
      + +
      + +
      + +
      +
      +
      + 上 传 +
      +
      + +
      + +
      + +
      +
      +
      +
      + +
      + +
      + +
      +
      + +
      +
      + +
      + +
      + +
      +
      + +
      +
      + +
      + +
      + + +
      + + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/modalUploadFile.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalUploadFile.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalUploadFile.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalUploadFile.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalUploadImage.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalUploadImage.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalUploadImage.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalUploadImage.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalUploadImageSingle.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalUploadImageSingle.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalUploadImageSingle.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalUploadImageSingle.aspx diff --git a/SiteServer.Web/SiteServer/Cms/modalUploadVideo.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalUploadVideo.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalUploadVideo.aspx rename to net452/SiteServer.Web/SiteServer/Cms/modalUploadVideo.aspx diff --git a/net452/SiteServer.Web/SiteServer/Cms/modalUploadWord.aspx b/net452/SiteServer.Web/SiteServer/Cms/modalUploadWord.aspx new file mode 100644 index 000000000..31ce5721c --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/modalUploadWord.aspx @@ -0,0 +1,153 @@ +<%@ Page Language="C#" Trace="false" Inherits="SiteServer.BackgroundPages.Cms.ModalUploadWord" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + +
      + + +
      + 点击批量上传Word文件或者将Word文件拖拽到此区域
      +
      +
      +
      +
      +

      {{ file.fileName }}
      大小:{{ Math.round(file.length/1024) + ' KB' }}

      + 删 除 +
      +
      +
      +
      +
      + +
      +
      + + + +
      + + + + +
      +
      +
      +
      +
      + +
      + +
      +
      +
      +
      +
      + + +
      + + + + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/modalUploadWordHandler.ashx b/net452/SiteServer.Web/SiteServer/Cms/modalUploadWordHandler.ashx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/modalUploadWordHandler.ashx rename to net452/SiteServer.Web/SiteServer/Cms/modalUploadWordHandler.ashx diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageChannel.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageChannel.aspx new file mode 100644 index 000000000..fdfea7ca0 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageChannel.aspx @@ -0,0 +1,107 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageChannel" enableViewState="false" %> + <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      + + + +
      +
      +
      + + + + + + + + + + + + + + + + + + + +
      栏目名所属栏目组栏目索引上升下降  + +
      +
      +
      +
      + + + +
      + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageChannelAdd.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageChannelAdd.aspx new file mode 100644 index 000000000..702b14760 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageChannelAdd.aspx @@ -0,0 +1,224 @@ +<%@ Page Language="C#" ValidateRequest="false" Inherits="SiteServer.BackgroundPages.Cms.PageChannelAdd" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      +
      + 添加栏目 +
      +

      + +
      + +
      + +
      +
      +
      +
      + +
      + +
      +
      + +
      +
      +
      + +
      + +
      +
      + +
      +
      +
      + +
      + +
      +
      +
      + + +
      + +
      + +
      +
      +
      + +
      + +
      + +
      +
      + 设置后链接将指向此地址 + +
      +
      +
      + +
      + +
      +
      + 设置此栏目的链接与子栏目及内容的关系 +
      +
      +
      + +
      + +
      +
      + 设置内容默认排序规则后,后台内容列表将改变排序显示规则 +
      +
      +
      + +
      + +
      +
      +
      +
      + +
      + +
      +
      +
      +
      + +
      + +
      +
      + +
      +
      +
      + +
      + +
      +
      + +
      +
      +
      + +
      + +
      +
      + +
      +
      +
      + +
      + + + + +
      +
      +
      +
      + +
      + + + + +
      +
      +
      +
      + +
      + +
      +
      + + +
      +
      +
      + +
      + +
      +
      +
      +
      + +
      + +
      +
      + + 注意:各关键词间用英文逗号“,”隔开。 +
      +
      +
      + +
      + +
      +
      + +
      +
      + + + +
      + +
      + +
      +
      + +
      + +
      +
      + + +
      +
      + +
      + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageChannelDelete.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageChannelDelete.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageChannelDelete.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageChannelDelete.aspx diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageChannelEdit.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageChannelEdit.aspx new file mode 100644 index 000000000..5d3b2419a --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageChannelEdit.aspx @@ -0,0 +1,216 @@ +<%@ Page Language="C#" ValidateRequest="false" Inherits="SiteServer.BackgroundPages.Cms.PageChannelEdit" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      +
      + 编辑栏目 +
      +

      + +
      + +
      + +
      +
      + +
      +
      + +
      + +
      + +
      +
      + +
      +
      + +
      + +
      + +
      +
      +
      + + +
      + +
      + +
      +
      +
      + +
      + +
      + +
      +
      + 设置后链接将指向此地址 + +
      +
      +
      + +
      + +
      +
      + 设置此栏目的链接与子栏目及内容的关系 +
      +
      +
      + +
      + +
      +
      + 设置内容默认排序规则后,后台内容列表将改变排序显示规则 +
      +
      +
      + +
      + +
      +
      +
      +
      + +
      + +
      +
      +
      +
      + +
      + +
      +
      + +
      +
      +
      + +
      + +
      +
      + +
      +
      +
      + +
      + +
      +
      + +
      +
      +
      + +
      + + + + +
      +
      +
      +
      + +
      + + + + +
      +
      +
      +
      + +
      + +
      +
      + + +
      +
      +
      + +
      + +
      +
      +
      +
      + +
      + +
      +
      + + 注意:各关键词间用英文逗号“,”分割。 +
      +
      +
      + +
      + +
      +
      + +
      +
      + + + +
      + +
      + +
      +
      + +
      + +
      + + +
      + +
      + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageChannelTranslate.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageChannelTranslate.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageChannelTranslate.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageChannelTranslate.aspx diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageChannelsGroup.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageChannelsGroup.aspx new file mode 100644 index 000000000..055f05478 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageChannelsGroup.aspx @@ -0,0 +1,79 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageChannelsGroup" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      + +
      +

      + +
      +
      +
      + + + + + + + + + + + + + + + + + + + +
      栏目名栏目索引添加日期
      + + + + + +
      +
      +
      +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationContent.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationContent.aspx new file mode 100644 index 000000000..4a007ffd8 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationContent.aspx @@ -0,0 +1,105 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationContent" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + +
      + +
      + + + +
      +
      + + +
      + +
      + + + + 如果修改了自动分页选项,需要将所有内容页重新生成 + +
      + + +
      + + +
      +
      + +
      + + + + 在标题中输入两连续的英文空格,内容页中标题将自动换行,列表页将忽略此空格 + +
      + +
      + + + + 当点击确定按钮保存内容的时候,会自动检测敏感词,弹框提示。 + +
      + +
      + + + + 选择内容审核的机制,需要多级审核的请选择多级审核机制,否则选择默认审核机制 + +
      + + +
      + + + + + + + + + 内容在添加后需要经多少次审核才能正式发布 + +
      +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationCreate.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationCreate.aspx new file mode 100644 index 000000000..1efd3ac51 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationCreate.aspx @@ -0,0 +1,133 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationCreate" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      + + +
      + +
      + + +
      + +
      + + +
      + +
      + + +
      + +
      + + +
      + +
      + + +
      + +
      + + +
      + +
      + + + + 此功能通常用于制作调试期间,网站开发期间建议启用 + +
      + +
      + + + + 设置翻页中生成的静态页面最大数,剩余页面将动态获取;设置为0代表将静态页面全部生成 + +
      + +
      + + + + 若启用此选项,文件名如果是默认文件名,文件名将省略 + +
      + + +
      + + + + 需要确保Web服务器支持默认文件名 + +
      +
      + +
      + + + + 若启用此选项,系统将不再生成所选添加时间之前的内容页 + +
      + + +
      + + + + 在此设置内容添加日期,此日期之前的内容页将不再生成 + +
      +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationCreateRule.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationCreateRule.aspx new file mode 100644 index 000000000..181f61e80 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationCreateRule.aspx @@ -0,0 +1,59 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationCreateRule" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      +
      + + + + + + + + + + + + + + + +
      栏目名 页面路径
      +
      +
      +
      +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationCreateTrigger.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationCreateTrigger.aspx new file mode 100644 index 000000000..4cb5c0c2e --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationCreateTrigger.aspx @@ -0,0 +1,60 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationCreateTrigger" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      +
      + + + + + + + + + + + + + + + +
      栏目名内容变动时需要生成的栏目 
      +
      +
      +
      + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationCrossSiteTrans.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationCrossSiteTrans.aspx new file mode 100644 index 000000000..6f5d75b7b --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationCrossSiteTrans.aspx @@ -0,0 +1,44 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationCrossSiteTrans" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      + + + +
      + +
      + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationCrossSiteTransChannels.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationCrossSiteTransChannels.aspx new file mode 100644 index 000000000..87bf66615 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationCrossSiteTransChannels.aspx @@ -0,0 +1,51 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationCrossSiteTransChannels" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      + + + + + + + + + + + + + + + +
      栏目名跨站转发设置
      + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationSite.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationSite.aspx new file mode 100644 index 000000000..a2a94d0f0 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationSite.aspx @@ -0,0 +1,61 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationSite" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + +
      + +
      + + + +
      +
      + + + 模板编码将同步修改 +
      + +
      + + +
      + +
      + + + 此功能通常用于制作调试期间,网站正式上线后不建议启用 +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationSiteAttributes.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationSiteAttributes.aspx new file mode 100644 index 000000000..a714557d7 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationSiteAttributes.aspx @@ -0,0 +1,54 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationSiteAttributes" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + +
      + +
      + +
      + + + +
      +
      + + +
      + + + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadFile.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadFile.aspx new file mode 100644 index 000000000..813f1fb9b --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadFile.aspx @@ -0,0 +1,101 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationUploadFile" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      + + +
      + +
      + + + + 本设置只影响新上传的附件, 设置更改之前的附件仍存放在原来位置 + +
      + +
      + + + + 本设置只影响新上传的附件, 设置更改之前的附件名仍保持不变 + +
      + +
      + + + + 类型之间用“,”分割 + +
      + +
      + +
      +
      + +
      +
      + + + + +
      +
      +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadImage.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadImage.aspx new file mode 100644 index 000000000..781a92ff8 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadImage.aspx @@ -0,0 +1,123 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationUploadImage" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      + + +
      + +
      + + + + 本设置只影响新上传的图片, 设置更改之前的图片仍存放在原来位置 + +
      + +
      + + + + 本设置只影响新上传的图片, 设置更改之前的图片名仍保持不变 + +
      + +
      + + + + 类型之间用“,”分割 + +
      + +
      + +
      +
      + +
      +
      + + + + +
      +
      +
      + +
      + + + 像素 +
      + +
      + + + 像素 +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadVideo.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadVideo.aspx new file mode 100644 index 000000000..747bdbe9f --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationUploadVideo.aspx @@ -0,0 +1,99 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationUploadVideo" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      + + +
      + +
      + + + + 本设置只影响新上传的视频, 设置更改之前的视频仍存放在原来位置 + +
      + +
      + + + + 本设置只影响新上传的视频, 设置更改之前的视频名仍保持不变 + +
      + +
      + + + 类型之间用“,”分割 +
      + +
      + +
      +
      + +
      +
      + + + + +
      +
      +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationWatermark.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationWatermark.aspx new file mode 100644 index 000000000..db3c63ae0 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageConfigurationWatermark.aspx @@ -0,0 +1,163 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageConfigurationWaterMark" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      + + +
      + + +
      + +
      + +
      + + 请在此选择水印添加的位置(共 9 个位置可选) + +
      +
      + + +
      + + + + 取值范围10%--100% (100%为不透明) + +
      +
      + + +
      + +
      + + + + +
      + + 需要添加水印的图片的最小尺寸,单位为像素,(0代表不限制) + +
      +
      + + +
      + + + + 选择使用的水印类型 + +
      +
      + + +
      + + + + 可以使用替换变量: {0}表示当前日期 {1}表示当前时间 例如:"上传于{0} {1}" + +
      +
      + + +
      + + +
      +
      + + +
      + + + + 像素 + +
      +
      + + +
      + + +
      + +
      +   + +   + +
      +
      +
      +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageContent.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageContent.aspx similarity index 84% rename from SiteServer.Web/SiteServer/Cms/pageContent.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageContent.aspx index 457d9f8a7..bc2c545b7 100644 --- a/SiteServer.Web/SiteServer/Cms/pageContent.aspx +++ b/net452/SiteServer.Web/SiteServer/Cms/pageContent.aspx @@ -8,9 +8,21 @@ @@ -20,20 +32,9 @@
      +
      - + + + + diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageContentAdd.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageContentAdd.aspx new file mode 100644 index 000000000..45e4801de --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageContentAdd.aspx @@ -0,0 +1,289 @@ +<%@ Page Language="C#" ValidateRequest="false" Inherits="SiteServer.BackgroundPages.Cms.PageContentAdd" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + + + + +
      + + +
      +
      + +
      +

      + + + +
      + +
      + +
      + + + +
      +
      + +
      +
      + + + +
      + + + +
      + +
      + + + + + 提示:按CTRL+回车可以快速提交 + +
      + +
      + + + + + + + diff --git a/SiteServer.Web/SiteServer/Cms/pageContentAddAfter.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageContentAddAfter.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageContentAddAfter.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageContentAddAfter.aspx diff --git a/SiteServer.Web/SiteServer/Cms/pageContentAddHandler.ashx b/net452/SiteServer.Web/SiteServer/Cms/pageContentAddHandler.ashx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageContentAddHandler.ashx rename to net452/SiteServer.Web/SiteServer/Cms/pageContentAddHandler.ashx diff --git a/SiteServer.Web/SiteServer/Cms/pageContentCheck.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageContentCheck.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageContentCheck.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageContentCheck.aspx diff --git a/SiteServer.Web/SiteServer/Cms/pageContentDelete.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageContentDelete.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageContentDelete.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageContentDelete.aspx diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageContentGroup.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageContentGroup.aspx new file mode 100644 index 000000000..d641aea90 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageContentGroup.aspx @@ -0,0 +1,94 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageContentGroup" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      内容组名称 内容组简介
      + + + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageContentMain.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageContentMain.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageContentMain.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageContentMain.aspx diff --git a/SiteServer.Web/SiteServer/Cms/pageContentSearch.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageContentSearch.aspx similarity index 89% rename from SiteServer.Web/SiteServer/Cms/pageContentSearch.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageContentSearch.aspx index 86847ee1b..2523cdd14 100644 --- a/SiteServer.Web/SiteServer/Cms/pageContentSearch.aspx +++ b/net452/SiteServer.Web/SiteServer/Cms/pageContentSearch.aspx @@ -31,7 +31,6 @@
      -
      @@ -69,7 +68,6 @@ 内容标题(点击查看) 栏目 - 操作 状态 @@ -87,9 +85,6 @@ - - - @@ -106,17 +101,21 @@ - +
      - + + + + + diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageContentTags.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageContentTags.aspx new file mode 100644 index 000000000..5f601e852 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageContentTags.aspx @@ -0,0 +1,105 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageContentTags" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + +
      + + + + + +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + +
      标签 使用次数
      + + + + + + + +
      +
      +
      +
      + + + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageContentTranslate.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageContentTranslate.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageContentTranslate.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageContentTranslate.aspx diff --git a/SiteServer.Web/SiteServer/Cms/pageContentTrash.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageContentTrash.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageContentTrash.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageContentTrash.aspx diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageContentTree.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageContentTree.aspx new file mode 100644 index 000000000..b4a4d058c --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageContentTree.aspx @@ -0,0 +1,40 @@ +<%@ Page Language="C#" Trace="false" EnableViewState="false" Inherits="SiteServer.BackgroundPages.BasePageCms" %> + <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + +
      +
      +
      + 栏目列表 +
      +
      + + + + +
      +
      + + + + diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageContentsGroup.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageContentsGroup.aspx new file mode 100644 index 000000000..19e1c9c0c --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageContentsGroup.aspx @@ -0,0 +1,93 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageContentsGroup" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      + +
      +

      + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      内容标题(点击查看)所属栏目添加日期状态
      + + + + + + + + + + + +
      +
      +
      +
      + + + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageCreateFile.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageCreateFile.aspx similarity index 85% rename from SiteServer.Web/SiteServer/Cms/pageCreateFile.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageCreateFile.aspx index c1238f37f..efbdf38dc 100644 --- a/SiteServer.Web/SiteServer/Cms/pageCreateFile.aspx +++ b/net452/SiteServer.Web/SiteServer/Cms/pageCreateFile.aspx @@ -53,18 +53,6 @@ -
      - -
      - -
      - -
      -
      - -
      -
      - diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageCreateSpecial.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageCreateSpecial.aspx new file mode 100644 index 000000000..069c76a83 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageCreateSpecial.aspx @@ -0,0 +1,62 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageCreateSpecial" %> + <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + +
      + + +
      +
      + 生成专题 +
      +

      + 选择需要生成的专题后点击“生成选定专题”即可生成对应的专题面,按住Ctrl可多选 +

      + +
      + +
      + +
      +
      + +
      +
      +
      + +
      +
      + + +
      + +
      +
      + +
      +
      + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageNodeGroup.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageNodeGroup.aspx new file mode 100644 index 000000000..0b09a054b --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageNodeGroup.aspx @@ -0,0 +1,94 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageNodeGroup" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      栏目组名称 栏目组简介
      + + + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageProgressBar.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageProgressBar.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageProgressBar.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageProgressBar.aspx diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageRelatedField.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageRelatedField.aspx new file mode 100644 index 000000000..94d454bcc --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageRelatedField.aspx @@ -0,0 +1,90 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageRelatedField" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      联动字段名称 级数
      + + + + + + + + + + + +
      +
      +
      +
      + +
      + + + + +
      + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageRelatedFieldItem.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageRelatedFieldItem.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageRelatedFieldItem.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageRelatedFieldItem.aspx diff --git a/SiteServer.Web/SiteServer/Cms/pageRelatedFieldMain.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageRelatedFieldMain.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageRelatedFieldMain.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageRelatedFieldMain.aspx diff --git a/SiteServer.Web/SiteServer/Cms/pageServiceStl.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageServiceStl.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageServiceStl.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageServiceStl.aspx diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageSpecial.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageSpecial.aspx new file mode 100644 index 000000000..8345e7ace --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageSpecial.aspx @@ -0,0 +1,77 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageSpecial" %> + <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      +
      + 专题管理 +
      +

      + +
      +
      + + + +
      +
      + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + +
      专题名称访问地址添加时间操作
      + + + + + + + +
      + +
      +
      +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageTableStyleChannel.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageTableStyleChannel.aspx new file mode 100644 index 000000000..b1c34fc2d --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageTableStyleChannel.aspx @@ -0,0 +1,109 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageTableStyleChannel" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      +
      + + + + 下级栏目的字段默认继承上级栏目的字段,设置字段时请先选择合适的栏目 + +
      +
      +
      + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      字段名 显示名称 表单提交类型验证规则排序显示样式表单验证
      + + + + + + + + + + + + + +
      +
      +
      +
      + +
      + + + + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageTableStyleContent.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageTableStyleContent.aspx new file mode 100644 index 000000000..ceec33330 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageTableStyleContent.aspx @@ -0,0 +1,113 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageTableStyleContent" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      +
      + + + + 下级栏目的字段默认继承上级栏目的字段,设置字段时请先选择合适的栏目 + +
      +
      +
      + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      字段名 显示名称 表单提交类型字段类型验证规则排序显示样式表单验证
      + + + + + + + + + + + + + + + +
      +
      +
      +
      + +
      + + + + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageTableStyleSite.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageTableStyleSite.aspx new file mode 100644 index 000000000..a59d0502f --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageTableStyleSite.aspx @@ -0,0 +1,97 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageTableStyleSite" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      字段名 显示名称 表单提交类型验证规则排序显示样式表单验证
      + + + + + + + + + + + + + +
      +
      +
      +
      + +
      + + + + + + + +
      + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageTemplate.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageTemplate.aspx similarity index 81% rename from SiteServer.Web/SiteServer/Cms/pageTemplate.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageTemplate.aspx index 35d214bdd..79e56d39a 100644 --- a/SiteServer.Web/SiteServer/Cms/pageTemplate.aspx +++ b/net452/SiteServer.Web/SiteServer/Cms/pageTemplate.aspx @@ -41,13 +41,9 @@ 模板名称 模板文件 生成文件名 - 使用次数 - 模板类型 - - - - - + 使用 + 模板类型 + @@ -69,19 +65,11 @@ - + - - - - - - - - diff --git a/SiteServer.Web/SiteServer/Cms/pageTemplateAdd.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageTemplateAdd.aspx similarity index 95% rename from SiteServer.Web/SiteServer/Cms/pageTemplateAdd.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageTemplateAdd.aspx index e4abcd485..66547ad1c 100644 --- a/SiteServer.Web/SiteServer/Cms/pageTemplateAdd.aspx +++ b/net452/SiteServer.Web/SiteServer/Cms/pageTemplateAdd.aspx @@ -8,7 +8,7 @@ + + + + +
      + + +
      +
      + +
      +

      + +

      + +
      +
      + + +
      +
      + + +
      +
      + +
      +
      + + +
      + +
      + +
      + + + + + + + + + + + +
      + +
      + +
      + + +
      + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageTemplateLeft.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageTemplateLeft.aspx new file mode 100644 index 000000000..0def43696 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageTemplateLeft.aspx @@ -0,0 +1,227 @@ +<%@ Page Language="C#" Trace="false" EnableViewState="false" Inherits="SiteServer.BackgroundPages.Cms.PageTemplateLeft" %> + <%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + +
      +
      +
      + 模板列表 +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      + + + 所有模板 + + + +
      + + + + 首页模板 + + + +
      + + + + 栏目模板 + + + +
      + + + + 内容模板 + + + +
      + + + + 单页模板 + + + +
      +
      + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Cms/pageTemplateLog.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageTemplateLog.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageTemplateLog.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageTemplateLog.aspx diff --git a/SiteServer.Web/SiteServer/Cms/pageTemplateMain.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageTemplateMain.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageTemplateMain.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageTemplateMain.aspx diff --git a/SiteServer.Web/SiteServer/Cms/pageTemplateMatch.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageTemplateMatch.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageTemplateMatch.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageTemplateMatch.aspx diff --git a/SiteServer.Web/SiteServer/Cms/pageTemplatePreview.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageTemplatePreview.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Cms/pageTemplatePreview.aspx rename to net452/SiteServer.Web/SiteServer/Cms/pageTemplatePreview.aspx diff --git a/net452/SiteServer.Web/SiteServer/Cms/pageTemplateReference.aspx b/net452/SiteServer.Web/SiteServer/Cms/pageTemplateReference.aspx new file mode 100644 index 000000000..c6e13343a --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Cms/pageTemplateReference.aspx @@ -0,0 +1,40 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Cms.PageTemplateReference" enableviewstate="false"%> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + +
      +
      + +
      +
      +
      + +
      + +
      + STL语言参考 +
      +

      + STL语言为SiteServer模板语言(SiteServer Template Language)的缩写,是一种和HTML语言类似的服务器端语言。 + STL 语言参考手册 +

      + + + +
      + + + + + diff --git a/net452/SiteServer.Web/SiteServer/Inc/foot.html b/net452/SiteServer.Web/SiteServer/Inc/foot.html new file mode 100644 index 000000000..932b07539 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Inc/foot.html @@ -0,0 +1,16 @@ + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Inc/head.html b/net452/SiteServer.Web/SiteServer/Inc/head.html similarity index 95% rename from SiteServer.Web/SiteServer/Inc/head.html rename to net452/SiteServer.Web/SiteServer/Inc/head.html index aa0693e13..61f3733b0 100644 --- a/SiteServer.Web/SiteServer/Inc/head.html +++ b/net452/SiteServer.Web/SiteServer/Inc/head.html @@ -11,4 +11,8 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Inc/script.js b/net452/SiteServer.Web/SiteServer/Inc/script.js similarity index 100% rename from SiteServer.Web/SiteServer/Inc/script.js rename to net452/SiteServer.Web/SiteServer/Inc/script.js diff --git a/SiteServer.Web/SiteServer/Installer/EULA.html b/net452/SiteServer.Web/SiteServer/Installer/EULA.html similarity index 100% rename from SiteServer.Web/SiteServer/Installer/EULA.html rename to net452/SiteServer.Web/SiteServer/Installer/EULA.html diff --git a/net452/SiteServer.Web/SiteServer/Installer/default.aspx b/net452/SiteServer.Web/SiteServer/Installer/default.aspx new file mode 100644 index 000000000..b9d6d8c72 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Installer/default.aspx @@ -0,0 +1,350 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.PageInstaller" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + SiteServer CMS 安装向导 + + + + + + + + +
      +
      +

      SiteServer CMS + 安装向导

      +

      欢迎来到SiteServer CMS 安装向导!只要进行以下几步操作,你就可以开始使用强大且可扩展的CMS系统了。

      + + + + +
      + +
      + +
      +
      + + +
      +
      + + + +
      + + 下表显示当前服务器环境 +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      参数
      服务器域名 + +
      SiteServer 版本 + +
      .NET版本 + +
      系统根目录 + +
      +
      +
      +
      +
      + + 系统要求必须满足下列所有的目录权限全部可读写的需求才能使用,如果没有相关权限请添加。 +
      +
      +
      +
      + + + + + + + + + + + + + + + + + +
      目录名读写权限
      /* + +
      /SiteFiles/* + +
      +
      +
      +
      +
      +
      + + +
      +
      + + + +
      + + + 请选择需要安装的数据库类型。 +
      + +
      + + + IP地址或者服务器名 +
      +
      + + +
      + +
      + + + 连接数据库的端口 +
      +
      +
      + + + 连接数据库的用户名 +
      +
      + + + 连接数据库的密码 +
      + +
      + + + 指定需要安装的Oracle数据库名称 +
      +
      +
      + +
      + + + 选择安装的数据库 +
      +
      +
      +
      + + +
      +
      + + + +
      + + + 在此设置总管理员的登录用户名 +
      +
      + + + 密码强度: + +
      +
      + + + 6-16个字符,支持大小写字母、数字和符号 +
      +
      + + + 设置是否加密Web.Config中的数据库连接字符串 +
      +
      +
      + + +
      +
      + + + + + +
      +
      + + + + + \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/Installer/index.aspx b/net452/SiteServer.Web/SiteServer/Installer/index.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Installer/index.aspx rename to net452/SiteServer.Web/SiteServer/Installer/index.aspx diff --git a/SiteServer.Web/SiteServer/Installer/password.css b/net452/SiteServer.Web/SiteServer/Installer/password.css similarity index 100% rename from SiteServer.Web/SiteServer/Installer/password.css rename to net452/SiteServer.Web/SiteServer/Installer/password.css diff --git a/SiteServer.Web/SiteServer/Installer/password.js b/net452/SiteServer.Web/SiteServer/Installer/password.js similarity index 100% rename from SiteServer.Web/SiteServer/Installer/password.js rename to net452/SiteServer.Web/SiteServer/Installer/password.js diff --git a/SiteServer.Web/SiteServer/Pic/Installer/printerIcon.gif b/net452/SiteServer.Web/SiteServer/Pic/Installer/printerIcon.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/Installer/printerIcon.gif rename to net452/SiteServer.Web/SiteServer/Pic/Installer/printerIcon.gif diff --git a/SiteServer.Web/SiteServer/Pic/animated_loading.gif b/net452/SiteServer.Web/SiteServer/Pic/animated_loading.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/animated_loading.gif rename to net452/SiteServer.Web/SiteServer/Pic/animated_loading.gif diff --git a/SiteServer.Web/SiteServer/Pic/bg_left.gif b/net452/SiteServer.Web/SiteServer/Pic/bg_left.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/bg_left.gif rename to net452/SiteServer.Web/SiteServer/Pic/bg_left.gif diff --git a/SiteServer.Web/SiteServer/Pic/bg_left2.gif b/net452/SiteServer.Web/SiteServer/Pic/bg_left2.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/bg_left2.gif rename to net452/SiteServer.Web/SiteServer/Pic/bg_left2.gif diff --git a/SiteServer.Web/SiteServer/Pic/bg_top.gif b/net452/SiteServer.Web/SiteServer/Pic/bg_top.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/bg_top.gif rename to net452/SiteServer.Web/SiteServer/Pic/bg_top.gif diff --git a/SiteServer.Web/SiteServer/Pic/bg_top2.gif b/net452/SiteServer.Web/SiteServer/Pic/bg_top2.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/bg_top2.gif rename to net452/SiteServer.Web/SiteServer/Pic/bg_top2.gif diff --git a/SiteServer.Web/SiteServer/Pic/btn_audio.png b/net452/SiteServer.Web/SiteServer/Pic/btn_audio.png similarity index 100% rename from SiteServer.Web/SiteServer/Pic/btn_audio.png rename to net452/SiteServer.Web/SiteServer/Pic/btn_audio.png diff --git a/SiteServer.Web/SiteServer/Pic/btn_detection.png b/net452/SiteServer.Web/SiteServer/Pic/btn_detection.png similarity index 100% rename from SiteServer.Web/SiteServer/Pic/btn_detection.png rename to net452/SiteServer.Web/SiteServer/Pic/btn_detection.png diff --git a/SiteServer.Web/SiteServer/Pic/btn_keywords.png b/net452/SiteServer.Web/SiteServer/Pic/btn_keywords.png similarity index 100% rename from SiteServer.Web/SiteServer/Pic/btn_keywords.png rename to net452/SiteServer.Web/SiteServer/Pic/btn_keywords.png diff --git a/SiteServer.Web/SiteServer/Pic/btn_select.png b/net452/SiteServer.Web/SiteServer/Pic/btn_select.png similarity index 100% rename from SiteServer.Web/SiteServer/Pic/btn_select.png rename to net452/SiteServer.Web/SiteServer/Pic/btn_select.png diff --git a/SiteServer.Web/SiteServer/Pic/btn_video.png b/net452/SiteServer.Web/SiteServer/Pic/btn_video.png similarity index 100% rename from SiteServer.Web/SiteServer/Pic/btn_video.png rename to net452/SiteServer.Web/SiteServer/Pic/btn_video.png diff --git a/SiteServer.Web/SiteServer/Pic/btn_word.png b/net452/SiteServer.Web/SiteServer/Pic/btn_word.png similarity index 100% rename from SiteServer.Web/SiteServer/Pic/btn_word.png rename to net452/SiteServer.Web/SiteServer/Pic/btn_word.png diff --git a/SiteServer.Web/SiteServer/Pic/bubble_arrow.gif b/net452/SiteServer.Web/SiteServer/Pic/bubble_arrow.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/bubble_arrow.gif rename to net452/SiteServer.Web/SiteServer/Pic/bubble_arrow.gif diff --git a/SiteServer.Web/SiteServer/Pic/button_bg.gif b/net452/SiteServer.Web/SiteServer/Pic/button_bg.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/button_bg.gif rename to net452/SiteServer.Web/SiteServer/Pic/button_bg.gif diff --git a/SiteServer.Web/SiteServer/Pic/calendar.gif b/net452/SiteServer.Web/SiteServer/Pic/calendar.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/calendar.gif rename to net452/SiteServer.Web/SiteServer/Pic/calendar.gif diff --git a/SiteServer.Web/SiteServer/Pic/cancel.png b/net452/SiteServer.Web/SiteServer/Pic/cancel.png similarity index 100% rename from SiteServer.Web/SiteServer/Pic/cancel.png rename to net452/SiteServer.Web/SiteServer/Pic/cancel.png diff --git a/SiteServer.Web/SiteServer/Pic/canedit.gif b/net452/SiteServer.Web/SiteServer/Pic/canedit.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/canedit.gif rename to net452/SiteServer.Web/SiteServer/Pic/canedit.gif diff --git a/SiteServer.Web/SiteServer/Pic/cantedit.gif b/net452/SiteServer.Web/SiteServer/Pic/cantedit.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/cantedit.gif rename to net452/SiteServer.Web/SiteServer/Pic/cantedit.gif diff --git a/SiteServer.Web/SiteServer/Pic/delete.gif b/net452/SiteServer.Web/SiteServer/Pic/delete.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/delete.gif rename to net452/SiteServer.Web/SiteServer/Pic/delete.gif diff --git a/SiteServer.Web/SiteServer/Pic/down.gif b/net452/SiteServer.Web/SiteServer/Pic/down.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/down.gif rename to net452/SiteServer.Web/SiteServer/Pic/down.gif diff --git a/SiteServer.Web/SiteServer/Pic/flash.jpg b/net452/SiteServer.Web/SiteServer/Pic/flash.jpg similarity index 100% rename from SiteServer.Web/SiteServer/Pic/flash.jpg rename to net452/SiteServer.Web/SiteServer/Pic/flash.jpg diff --git a/SiteServer.Web/SiteServer/Pic/flow.gif b/net452/SiteServer.Web/SiteServer/Pic/flow.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/flow.gif rename to net452/SiteServer.Web/SiteServer/Pic/flow.gif diff --git a/SiteServer.Web/SiteServer/Pic/flower.jpg b/net452/SiteServer.Web/SiteServer/Pic/flower.jpg similarity index 100% rename from SiteServer.Web/SiteServer/Pic/flower.jpg rename to net452/SiteServer.Web/SiteServer/Pic/flower.jpg diff --git a/SiteServer.Web/SiteServer/Pic/hello_today.gif b/net452/SiteServer.Web/SiteServer/Pic/hello_today.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/hello_today.gif rename to net452/SiteServer.Web/SiteServer/Pic/hello_today.gif diff --git a/SiteServer.Web/SiteServer/Pic/help.gif b/net452/SiteServer.Web/SiteServer/Pic/help.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/help.gif rename to net452/SiteServer.Web/SiteServer/Pic/help.gif diff --git a/SiteServer.Web/SiteServer/Pic/help_bar.gif b/net452/SiteServer.Web/SiteServer/Pic/help_bar.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/help_bar.gif rename to net452/SiteServer.Web/SiteServer/Pic/help_bar.gif diff --git a/SiteServer.Web/SiteServer/Pic/ico_error.gif b/net452/SiteServer.Web/SiteServer/Pic/ico_error.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/ico_error.gif rename to net452/SiteServer.Web/SiteServer/Pic/ico_error.gif diff --git a/SiteServer.Web/SiteServer/Pic/ico_info.gif b/net452/SiteServer.Web/SiteServer/Pic/ico_info.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/ico_info.gif rename to net452/SiteServer.Web/SiteServer/Pic/ico_info.gif diff --git a/SiteServer.Web/SiteServer/Pic/ico_succeed.gif b/net452/SiteServer.Web/SiteServer/Pic/ico_succeed.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/ico_succeed.gif rename to net452/SiteServer.Web/SiteServer/Pic/ico_succeed.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/attachment.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/attachment.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/attachment.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/attachment.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/bbs.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/bbs.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/bbs.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/bbs.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/down.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/down.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/down.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/down.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/down2.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/down2.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/down2.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/down2.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/error.jpg b/net452/SiteServer.Web/SiteServer/Pic/icon/error.jpg similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/error.jpg rename to net452/SiteServer.Web/SiteServer/Pic/icon/error.jpg diff --git a/SiteServer.Web/SiteServer/Pic/icon/false.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/false.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/false.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/false.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/gather.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/gather.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/gather.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/gather.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/help.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/help.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/help.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/help.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/help.png b/net452/SiteServer.Web/SiteServer/Pic/icon/help.png similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/help.png rename to net452/SiteServer.Web/SiteServer/Pic/icon/help.png diff --git a/SiteServer.Web/SiteServer/Pic/icon/hot.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/hot.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/hot.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/hot.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/issue.png b/net452/SiteServer.Web/SiteServer/Pic/icon/issue.png similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/issue.png rename to net452/SiteServer.Web/SiteServer/Pic/icon/issue.png diff --git a/SiteServer.Web/SiteServer/Pic/icon/link.png b/net452/SiteServer.Web/SiteServer/Pic/icon/link.png similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/link.png rename to net452/SiteServer.Web/SiteServer/Pic/icon/link.png diff --git a/SiteServer.Web/SiteServer/Pic/icon/new.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/new.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/new.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/new.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/normal.png b/net452/SiteServer.Web/SiteServer/Pic/icon/normal.png similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/normal.png rename to net452/SiteServer.Web/SiteServer/Pic/icon/normal.png diff --git a/SiteServer.Web/SiteServer/Pic/icon/recommend.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/recommend.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/recommend.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/recommend.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/ref.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/ref.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/ref.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/ref.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/reference.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/reference.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/reference.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/reference.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/reference.png b/net452/SiteServer.Web/SiteServer/Pic/icon/reference.png similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/reference.png rename to net452/SiteServer.Web/SiteServer/Pic/icon/reference.png diff --git a/SiteServer.Web/SiteServer/Pic/icon/right.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/right.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/right.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/right.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/search.png b/net452/SiteServer.Web/SiteServer/Pic/icon/search.png similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/search.png rename to net452/SiteServer.Web/SiteServer/Pic/icon/search.png diff --git a/SiteServer.Web/SiteServer/Pic/icon/toggleDown.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/toggleDown.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/toggleDown.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/toggleDown.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/toggleUp.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/toggleUp.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/toggleUp.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/toggleUp.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/top.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/top.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/top.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/top.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/tracker.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/tracker.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/tracker.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/tracker.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/true.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/true.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/true.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/true.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/up.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/up.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/up.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/up.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/up2.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/up2.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/up2.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/up2.gif diff --git a/SiteServer.Web/SiteServer/Pic/icon/video.png b/net452/SiteServer.Web/SiteServer/Pic/icon/video.png similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/video.png rename to net452/SiteServer.Web/SiteServer/Pic/icon/video.png diff --git a/SiteServer.Web/SiteServer/Pic/icon/warn.jpg b/net452/SiteServer.Web/SiteServer/Pic/icon/warn.jpg similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/warn.jpg rename to net452/SiteServer.Web/SiteServer/Pic/icon/warn.jpg diff --git a/SiteServer.Web/SiteServer/Pic/icon/wrong.gif b/net452/SiteServer.Web/SiteServer/Pic/icon/wrong.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/icon/wrong.gif rename to net452/SiteServer.Web/SiteServer/Pic/icon/wrong.gif diff --git a/SiteServer.Web/SiteServer/Pic/index_conn_left.gif b/net452/SiteServer.Web/SiteServer/Pic/index_conn_left.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/index_conn_left.gif rename to net452/SiteServer.Web/SiteServer/Pic/index_conn_left.gif diff --git a/SiteServer.Web/SiteServer/Pic/index_conn_left_bottom.gif b/net452/SiteServer.Web/SiteServer/Pic/index_conn_left_bottom.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/index_conn_left_bottom.gif rename to net452/SiteServer.Web/SiteServer/Pic/index_conn_left_bottom.gif diff --git a/SiteServer.Web/SiteServer/Pic/index_conn_right.gif b/net452/SiteServer.Web/SiteServer/Pic/index_conn_right.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/index_conn_right.gif rename to net452/SiteServer.Web/SiteServer/Pic/index_conn_right.gif diff --git a/SiteServer.Web/SiteServer/Pic/index_login_bg.gif b/net452/SiteServer.Web/SiteServer/Pic/index_login_bg.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/index_login_bg.gif rename to net452/SiteServer.Web/SiteServer/Pic/index_login_bg.gif diff --git a/SiteServer.Web/SiteServer/Pic/itemnote1.gif b/net452/SiteServer.Web/SiteServer/Pic/itemnote1.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/itemnote1.gif rename to net452/SiteServer.Web/SiteServer/Pic/itemnote1.gif diff --git a/SiteServer.Web/SiteServer/Pic/itemnote2.gif b/net452/SiteServer.Web/SiteServer/Pic/itemnote2.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/itemnote2.gif rename to net452/SiteServer.Web/SiteServer/Pic/itemnote2.gif diff --git a/SiteServer.Web/SiteServer/Pic/line.gif b/net452/SiteServer.Web/SiteServer/Pic/line.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/line.gif rename to net452/SiteServer.Web/SiteServer/Pic/line.gif diff --git a/SiteServer.Web/SiteServer/Pic/loading.gif b/net452/SiteServer.Web/SiteServer/Pic/loading.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/loading.gif rename to net452/SiteServer.Web/SiteServer/Pic/loading.gif diff --git a/SiteServer.Web/SiteServer/Pic/login_bottom_bg.gif b/net452/SiteServer.Web/SiteServer/Pic/login_bottom_bg.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/login_bottom_bg.gif rename to net452/SiteServer.Web/SiteServer/Pic/login_bottom_bg.gif diff --git a/SiteServer.Web/SiteServer/Pic/login_conn_left.gif b/net452/SiteServer.Web/SiteServer/Pic/login_conn_left.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/login_conn_left.gif rename to net452/SiteServer.Web/SiteServer/Pic/login_conn_left.gif diff --git a/SiteServer.Web/SiteServer/Pic/login_conn_left_b.gif b/net452/SiteServer.Web/SiteServer/Pic/login_conn_left_b.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/login_conn_left_b.gif rename to net452/SiteServer.Web/SiteServer/Pic/login_conn_left_b.gif diff --git a/SiteServer.Web/SiteServer/Pic/login_conn_right.gif b/net452/SiteServer.Web/SiteServer/Pic/login_conn_right.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/login_conn_right.gif rename to net452/SiteServer.Web/SiteServer/Pic/login_conn_right.gif diff --git a/SiteServer.Web/SiteServer/Pic/login_conn_right_b.gif b/net452/SiteServer.Web/SiteServer/Pic/login_conn_right_b.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/login_conn_right_b.gif rename to net452/SiteServer.Web/SiteServer/Pic/login_conn_right_b.gif diff --git a/SiteServer.Web/SiteServer/Pic/login_top_bg.gif b/net452/SiteServer.Web/SiteServer/Pic/login_top_bg.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/login_top_bg.gif rename to net452/SiteServer.Web/SiteServer/Pic/login_top_bg.gif diff --git a/SiteServer.Web/SiteServer/Pic/no_picture.gif b/net452/SiteServer.Web/SiteServer/Pic/no_picture.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/no_picture.gif rename to net452/SiteServer.Web/SiteServer/Pic/no_picture.gif diff --git a/SiteServer.Web/SiteServer/Pic/pencil.png b/net452/SiteServer.Web/SiteServer/Pic/pencil.png similarity index 100% rename from SiteServer.Web/SiteServer/Pic/pencil.png rename to net452/SiteServer.Web/SiteServer/Pic/pencil.png diff --git a/SiteServer.Web/SiteServer/Pic/rank.gif b/net452/SiteServer.Web/SiteServer/Pic/rank.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/rank.gif rename to net452/SiteServer.Web/SiteServer/Pic/rank.gif diff --git a/SiteServer.Web/SiteServer/Pic/separator1.gif b/net452/SiteServer.Web/SiteServer/Pic/separator1.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/separator1.gif rename to net452/SiteServer.Web/SiteServer/Pic/separator1.gif diff --git a/SiteServer.Web/SiteServer/Pic/separator2.gif b/net452/SiteServer.Web/SiteServer/Pic/separator2.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/separator2.gif rename to net452/SiteServer.Web/SiteServer/Pic/separator2.gif diff --git a/SiteServer.Web/SiteServer/Pic/taboff.gif b/net452/SiteServer.Web/SiteServer/Pic/taboff.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/taboff.gif rename to net452/SiteServer.Web/SiteServer/Pic/taboff.gif diff --git a/SiteServer.Web/SiteServer/Pic/taboff6.gif b/net452/SiteServer.Web/SiteServer/Pic/taboff6.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/taboff6.gif rename to net452/SiteServer.Web/SiteServer/Pic/taboff6.gif diff --git a/SiteServer.Web/SiteServer/Pic/tabon.gif b/net452/SiteServer.Web/SiteServer/Pic/tabon.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tabon.gif rename to net452/SiteServer.Web/SiteServer/Pic/tabon.gif diff --git a/SiteServer.Web/SiteServer/Pic/tabon6.gif b/net452/SiteServer.Web/SiteServer/Pic/tabon6.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tabon6.gif rename to net452/SiteServer.Web/SiteServer/Pic/tabon6.gif diff --git a/SiteServer.Web/SiteServer/Pic/tags_bg_ico.gif b/net452/SiteServer.Web/SiteServer/Pic/tags_bg_ico.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tags_bg_ico.gif rename to net452/SiteServer.Web/SiteServer/Pic/tags_bg_ico.gif diff --git a/SiteServer.Web/SiteServer/Pic/tips.gif b/net452/SiteServer.Web/SiteServer/Pic/tips.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tips.gif rename to net452/SiteServer.Web/SiteServer/Pic/tips.gif diff --git a/SiteServer.Web/SiteServer/Pic/tools.gif b/net452/SiteServer.Web/SiteServer/Pic/tools.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tools.gif rename to net452/SiteServer.Web/SiteServer/Pic/tools.gif diff --git a/SiteServer.Web/SiteServer/Pic/tracker_background.gif b/net452/SiteServer.Web/SiteServer/Pic/tracker_background.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tracker_background.gif rename to net452/SiteServer.Web/SiteServer/Pic/tracker_background.gif diff --git a/SiteServer.Web/SiteServer/Pic/tracker_bar.gif b/net452/SiteServer.Web/SiteServer/Pic/tracker_bar.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tracker_bar.gif rename to net452/SiteServer.Web/SiteServer/Pic/tracker_bar.gif diff --git a/SiteServer.Web/SiteServer/Pic/tracker_transparency_bar.gif b/net452/SiteServer.Web/SiteServer/Pic/tracker_transparency_bar.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tracker_transparency_bar.gif rename to net452/SiteServer.Web/SiteServer/Pic/tracker_transparency_bar.gif diff --git a/SiteServer.Web/SiteServer/Pic/tracker_transparency_bar_l.gif b/net452/SiteServer.Web/SiteServer/Pic/tracker_transparency_bar_l.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tracker_transparency_bar_l.gif rename to net452/SiteServer.Web/SiteServer/Pic/tracker_transparency_bar_l.gif diff --git a/SiteServer.Web/SiteServer/Pic/tracker_transparency_bar_r.gif b/net452/SiteServer.Web/SiteServer/Pic/tracker_transparency_bar_r.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tracker_transparency_bar_r.gif rename to net452/SiteServer.Web/SiteServer/Pic/tracker_transparency_bar_r.gif diff --git a/SiteServer.Web/SiteServer/Pic/tracker_tu_back.gif b/net452/SiteServer.Web/SiteServer/Pic/tracker_tu_back.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tracker_tu_back.gif rename to net452/SiteServer.Web/SiteServer/Pic/tracker_tu_back.gif diff --git a/SiteServer.Web/SiteServer/Pic/tree/dot.gif b/net452/SiteServer.Web/SiteServer/Pic/tree/dot.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tree/dot.gif rename to net452/SiteServer.Web/SiteServer/Pic/tree/dot.gif diff --git a/SiteServer.Web/SiteServer/Pic/tree/empty.gif b/net452/SiteServer.Web/SiteServer/Pic/tree/empty.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tree/empty.gif rename to net452/SiteServer.Web/SiteServer/Pic/tree/empty.gif diff --git a/SiteServer.Web/SiteServer/Pic/tree/folder.gif b/net452/SiteServer.Web/SiteServer/Pic/tree/folder.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tree/folder.gif rename to net452/SiteServer.Web/SiteServer/Pic/tree/folder.gif diff --git a/SiteServer.Web/SiteServer/Pic/tree/item.gif b/net452/SiteServer.Web/SiteServer/Pic/tree/item.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tree/item.gif rename to net452/SiteServer.Web/SiteServer/Pic/tree/item.gif diff --git a/SiteServer.Web/SiteServer/Pic/tree/itemContainer.gif b/net452/SiteServer.Web/SiteServer/Pic/tree/itemContainer.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tree/itemContainer.gif rename to net452/SiteServer.Web/SiteServer/Pic/tree/itemContainer.gif diff --git a/SiteServer.Web/SiteServer/Pic/tree/minus.gif b/net452/SiteServer.Web/SiteServer/Pic/tree/minus.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tree/minus.gif rename to net452/SiteServer.Web/SiteServer/Pic/tree/minus.gif diff --git a/SiteServer.Web/SiteServer/Pic/tree/openedfolder.gif b/net452/SiteServer.Web/SiteServer/Pic/tree/openedfolder.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tree/openedfolder.gif rename to net452/SiteServer.Web/SiteServer/Pic/tree/openedfolder.gif diff --git a/SiteServer.Web/SiteServer/Pic/tree/plus.gif b/net452/SiteServer.Web/SiteServer/Pic/tree/plus.gif similarity index 100% rename from SiteServer.Web/SiteServer/Pic/tree/plus.gif rename to net452/SiteServer.Web/SiteServer/Pic/tree/plus.gif diff --git a/net452/SiteServer.Web/SiteServer/Plugins/add.cshtml b/net452/SiteServer.Web/SiteServer/Plugins/add.cshtml new file mode 100644 index 000000000..7545248d2 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Plugins/add.cshtml @@ -0,0 +1,81 @@ +@{ Layout = "../Shared/_Layout.cshtml"; }
      +
      + +
      +
      + +
      +
      +
      +
      + + +
      + +
      +
      +
      + +
      +
      + + +
      + +
      + +
      + 价格: {{package.pluginInfo.price.toFixed(2)}} + 免 费 + + + | + 最新版本: {{ package.releaseInfo.version }} + + | + 更新时间: {{ package.releaseInfo.published }} + + + | + 标签: {{ tagName }} + + + +
      +
      {{ package.pluginInfo.summary }}
      +
      +
      + 更多 +
      @section Scripts{ + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Plugins/add.js b/net452/SiteServer.Web/SiteServer/Plugins/add.js new file mode 100644 index 000000000..04186a986 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Plugins/add.js @@ -0,0 +1,79 @@ +var $url = '/pages/plugins/add'; + +var $data = { + pageLoad: false, + pageAlert: null, + isNightly: null, + pluginVersion: null, + packageIds: null, + q: utils.getQueryString('q'), + keyword: utils.getQueryString('q') || '', + packages: null +}; + +var $methods = { + getIconUrl: function (url) { + return ssUtils.getPluginsUrl(url); + }, + + getTagNames: function (pluginInfo) { + var tagNames = []; + if (pluginInfo.tags) { + tagNames = pluginInfo.tags.split(','); + } + return tagNames; + }, + + load: function () { + var $this = this; + + $api.get($url).then(function (response) { + var res = response.data; + + $this.isNightly = res.isNightly; + $this.pluginVersion = res.pluginVersion; + $this.packageIds = res.packageIds; + + $ssApi.get($ssUrlPlugins, { + params: { + isNightly: $this.isNightly, + pluginVersion: $this.pluginVersion, + keyword: $this.keyword + } + }).then(function (response) { + var res = response.data; + + $this.packages = res.value; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + + }).catch(function (error) { + $this.pageLoad = true; + $this.pageAlert = utils.getPageAlert(error); + }); + }, + + btnSearchClick: function () { + location.href = '?q=' + this.keyword; + }, + + btnUploadClick: function () { + utils.openLayer({ + title: '离线安装插件', + url: 'addLayerUpload.cshtml', + full: true + }); + } +}; + +var $vue = new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.load(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Plugins/addLayerUpload.cshtml b/net452/SiteServer.Web/SiteServer/Plugins/addLayerUpload.cshtml new file mode 100644 index 000000000..a5c6518b7 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Plugins/addLayerUpload.cshtml @@ -0,0 +1,29 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles { } + +
      + 请到官网下载插件离线安装包并在此上传。 +
      +
      + 点击上传插件安装包或者将文件拖拽到此区域
      +
      +
      +
      +
      +

      {{ file.fileName }}
      大小:{{ Math.round(file.length/1024) + ' KB' }}

      + 删 除 +
      +
      +
      +
      +
      +
      + + +
      @section Scripts{ + + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Plugins/addLayerUpload.js b/net452/SiteServer.Web/SiteServer/Plugins/addLayerUpload.js new file mode 100644 index 000000000..6c39bfe34 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Plugins/addLayerUpload.js @@ -0,0 +1,146 @@ +var $url = '/pages/plugins/addLayerUpload'; +var $urlUpload = $apiUrl + '/pages/plugins/addLayerUpload/actions/upload'; + +var $data = { + pageLoad: false, + pageAlert: null, + importType: 'nupkg', + file: null, + files: [] +}; + +var $methods = { + loadConfig: function () { + var $this = this; + + $api.get($url).then(function (response) { + $this.pageLoad = true; + setTimeout(function () { + $this.loadUploader(); + }, 100); + }).catch(function (error) { + $this.pageLoad = true; + $this.pageAlert = utils.getPageAlert(error); + }); + }, + + loadUploader: function () { + var $this = this; + + var E = Q.event, + Uploader = Q.Uploader; + + var boxDropArea = document.getElementById("drop-area"); + + var uploader = new Uploader({ + url: $urlUpload, + target: document.getElementById("drop-area"), + allows: ".nupkg", + on: { + add: function (task) { + if (task.ext != '.' + $this.importType) { + swal2({ + title: '文件错误!', + text: '离线插件文件格式为:.' + $this.importType, + type: 'error', + showConfirmButton: false + }); + return false; + } + }, + complete: function (task) { + var json = task.json; + if (!json || json.ret != 1) { + return swal2({ + title: "文件上传失败!", + type: 'error', + showConfirmButton: false + }); + } + + if (json && json.fileName) { + $this.files.push(json); + } + } + } + }); + + //若浏览器不支持html5上传,则禁止拖拽上传 + if (!Uploader.support.html5 || !uploader.html5) { + boxDropArea.innerHTML = "点击批量上传文件"; + return; + } + + //阻止浏览器默认拖放行为 + E.add(boxDropArea, "dragleave", E.stop); + E.add(boxDropArea, "dragenter", E.stop); + E.add(boxDropArea, "dragover", E.stop); + + E.add(boxDropArea, "drop", function (e) { + E.stop(e); + + //获取文件对象 + var files = e.dataTransfer.files; + + uploader.addList(files); + }); + }, + + del: function (file) { + this.files.splice(this.files.indexOf(file), 1); + }, + + getFileNames: function () { + var arr = []; + for (var i = 0; i < this.files.length; i++) { + arr.push(this.files[i].fileName); + } + return arr; + }, + + btnSubmitClick: function () { + var $this = this; + this.pageAlert = null; + + var fileNames = this.getFileNames().join(','); + if (!fileNames) { + return swal2({ + title: "请上传插件安装包文件!", + type: 'warning', + showConfirmButton: false + }); + } + + parent.utils.loading(true); + $api.post({ + siteId: $this.siteId, + channelId: $this.channelId, + importType: $this.importType, + fileNames: $this.getFileNames(), + checkedLevel: $this.checkedLevel, + isOverride: $this.isOverride + }, + function (err, res) { + parent.utils.loading(false); + + if (err) { + return $this.pageAlert = { + type: 'danger', + html: res.message + }; + } + + parent.location.reload(true); + } + ); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.loadConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Plugins/install.cshtml b/net452/SiteServer.Web/SiteServer/Plugins/install.cshtml new file mode 100644 index 000000000..9914721da --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Plugins/install.cshtml @@ -0,0 +1,101 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } +
      +

      插件{{ pageType }}向导

      +

      欢迎来到插件{{ pageType }}向导!

      +
      + {{ listPackage.id }}({{ listPackage.packageType == 'Plugin' ? '插件' : '类库' }}) {{ listPackage.version }} — {{ pageType }}成功! + 等待{{ pageType }}! + 正在{{ pageType }}... +
      + + + + +
      +
      +

      {{ pageType }}完成!

      +

      恭喜,您已经完成了插件的{{ pageType }},系统将重启并跳转,请稍后...

      +
      @section Scripts{ + + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Plugins/install.js b/net452/SiteServer.Web/SiteServer/Plugins/install.js new file mode 100644 index 000000000..695a8728e --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Plugins/install.js @@ -0,0 +1,220 @@ +var $url = '/pages/plugins/install'; + +var $pluginIds = utils.getQueryString('pluginIds').split(','); +var $pageType = utils.getQueryString('isUpdate') === 'true' ? '升级' : '安装'; + +var $data = { + pluginIds: $pluginIds, + pageLoad: false, + pageAlert: null, + pageType: $pageType, + pageStep: 1, + isNightly: false, + pluginVersion: null, + downloadPlugins: null, + listPackages: [], + listPackageIds: [], + listIndex: 0, + currentPackage: {}, + currentPackages: [], + currentDownloadingId: 0, + currentDownloadIds: [], + currentUpdatingId: 0, + currentUpdatedIds: [] +}; + +var $methods = { + getConfig: function () { + var $this = this; + + $api.get($url + '/config').then(function (response) { + var res = response.data; + + $this.isNightly = res.isNightly; + $this.pluginVersion = res.pluginVersion; + $this.downloadPlugins = res.downloadPlugins; + + $this.getPackages(); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }); + }, + + getPackages: function () { + var $this = this; + + $ssApi.get($ssUrlUpdates, { + params: { + isNightly: $this.isNightly, + pluginVersion: $this.pluginVersion, + packageIds: $this.pluginIds.join(",") + } + }).then(function (response) { + var res = response.data; + + for (var i = 0; i < res.value.length; i++) { + var releaseInfo = res.value[i]; + + for (var j = 0; j < releaseInfo.pluginReferences.length; j++) { + var reference = releaseInfo.pluginReferences[j]; + + if ($this.listPackageIds.indexOf(reference.id) === -1) { + $this.listPackageIds.push(reference.id); + $this.listPackages.push({ + id: reference.id, + version: reference.version, + packageType: 'Plugin' + }); + } + } + + for (var k = 0; k < releaseInfo.libraryReferences.length; k++) { + var reference = releaseInfo.libraryReferences[k]; + if ($this.listPackageIds.indexOf(reference.id) === -1) { + $this.listPackageIds.push(reference.id); + $this.listPackages.push({ + id: reference.id, + version: reference.version, + packageType: 'Library' + }); + } + } + + if ($this.listPackageIds.indexOf(releaseInfo.pluginId) === -1) { + $this.listPackageIds.push(reference.id); + $this.listPackages.push({ + id: releaseInfo.pluginId, + version: releaseInfo.version, + packageType: 'Plugin' + }); + } + } + $this.installListPackage(); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + installListPackage: function () { + var $this = this; + + if ($this.listIndex === $this.listPackages.length) { + $this.clearCache(); + return; + } + + $this.package = $this.listPackages[$this.listIndex]; + $this.currentPackages.push($this.package); + + $this.download(); + }, + + download: function () { + var $this = this; + + for (var i = 0; i < $this.currentPackages.length; i++) { + var package = $this.currentPackages[i]; + if ($this.currentDownloadIds.indexOf(package.id) == -1) { + $this.currentDownloadingId = package.id; + $this.downloadPackage(package.id, package.version) + return; + } + } + + $this.update(); + }, + + downloadPackage: function (packageId, version) { + var $this = this; + + $api.post($url + '/download', { + packageId: packageId, + version: version + }).then(function (response) { + var res = response.data; + + $this.currentDownloadingId = 0; + $this.currentDownloadIds.push(packageId); + $this.download(); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }); + }, + + update: function () { + var $this = this; + $this.pageStep = 2; + + for (var i = 0; i < $this.currentPackages.length; i++) { + var package = $this.currentPackages[i]; + if ($this.currentUpdatedIds.indexOf(package.id) == -1) { + $this.currentUpdatingId = package.id; + $this.updatePackage(package.id, package.version, package.packageType); + return; + } + } + + $this.updateSuccess(); + }, + + updatePackage: function (packageId, version, packageType) { + var $this = this; + + $api.post($url + '/update', { + packageId: packageId, + version: version, + packageType: packageType + }).then(function (response) { + var res = response.data; + + $this.currentUpdatingId = 0; + $this.currentUpdatedIds.push(packageId); + $this.update(); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }); + }, + + updateSuccess: function () { + var $this = this; + + $this.listIndex++; + $this.pageStep = 1; + + $this.currentPackage = {}; + $this.currentPackages = []; + $this.currentDownloadingId = 0; + $this.currentDownloadIds = []; + $this.currentUpdatingId = 0; + $this.currentUpdatedIds = []; + + $this.installListPackage(); + }, + + clearCache: function () { + var $this = this; + + $this.pageStep = 0; + + $api.post($url + '/cache').then(function (response) { + var res = response.data; + + setTimeout(function () { + window.top.location.reload(true); + }, 3000); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }); + } +}; + +var $vue = new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.getConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Plugins/manage.cshtml b/net452/SiteServer.Web/SiteServer/Plugins/manage.cshtml new file mode 100644 index 000000000..37fe6f184 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Plugins/manage.cshtml @@ -0,0 +1,209 @@ +@{ Layout = "../Shared/_Layout.cshtml"; }
      +
      + +
      +
      + + +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      LOGO插件Id插件名称版本号作者插件介绍载入时间
      + + + {{ + package.id }} + {{ package.metadata.title }} {{ package.metadata.version }} {{ package.metadata.owners }} {{ package.metadata.description }} {{ package.initTime }}毫秒 + {{ package.isDisabled ? '启用' : '禁用' }} +    删除插件 +
      +
      +
      +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      LOGO插件Id插件名称版本号作者插件介绍载入时间
      + + + {{ + package.id }} + {{ package.metadata.title }} {{ package.metadata.version }} {{ package.metadata.owners }} {{ package.metadata.description }} {{ package.initTime }}毫秒 + {{ package.isDisabled ? '启用' : '禁用' }} +    删除插件 +
      +
      +
      +
      +
      +
      +
      + + + + + + + + + + + + + + + +
      插件Id错误详情
      + {{ + package.id }} + {{ package.errorMessage }} + 删除插件 +
      +
      +
      +
      +
      +
      发现以下插件发布了新版本,请点击升级插件按钮开始升级
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      LOGO插件Id插件名称已安装版本新版本更新说明发布时间
      + + + {{ + package.updatePackage.pluginId }} + {{ package.metadata.title }} {{ package.metadata ? package.metadata.version : '' }} {{ package.updatePackage.version }} {{ package.updatePackage.releaseNotes }} {{ package.updatePackage.published }} + 插件升级 +
      +
      +
      +
      +
      + 一键升级所有插件 +
      +
      +
      @section Scripts{ + + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Plugins/manage.js b/net452/SiteServer.Web/SiteServer/Plugins/manage.js new file mode 100644 index 000000000..558821492 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Plugins/manage.js @@ -0,0 +1,180 @@ +var $url = '/pages/plugins/manage'; +var $urlReload = '/pages/plugins/manage/actions/reload'; + +var $data = { + pageLoad: false, + pageAlert: null, + pageType: parseInt(utils.getQueryString("pageType") || '1'), + isNightly: null, + pluginVersion: null, + allPackages: null, + packageIds: null, + enabledPackages: [], + disabledPackages: [], + errorPackages: [], + updatePackages: [], + updatePackageIds: [], + referencePackageIds: [] +}; + +var $methods = { + getIconUrl: function (url) { + return ssUtils.getPluginsUrl(url); + }, + + load: function () { + var $this = this; + + $api.get($url).then(function (response) { + var res = response.data; + + $this.isNightly = res.isNightly; + $this.pluginVersion = res.pluginVersion; + $this.allPackages = res.allPackages; + $this.packageIds = res.packageIds; + + for (var i = 0; i < $this.allPackages.length; i++) { + var pkg = $this.allPackages[i]; + if (pkg.isRunnable && pkg.metadata) { + if (pkg.isDisabled) { + $this.disabledPackages.push(pkg); + } else { + $this.enabledPackages.push(pkg); + } + } else { + $this.errorPackages.push(pkg); + } + } + + $ssApi.get($ssUrlUpdates, { + params: { + isNightly: $this.isNightly, + pluginVersion: $this.pluginVersion, + packageIds: $this.packageIds + } + }).then(function (response) { + var res = response.data; + + for (var i = 0; i < res.value.length; i++) { + var releaseInfo = res.value[i]; + + var installedPackages = $.grep($this.allPackages, function (e) { + return e.id == releaseInfo.pluginId; + }); + if (installedPackages.length == 1) { + var installedPackage = installedPackages[0]; + installedPackage.updatePackage = releaseInfo; + + if (installedPackage.metadata && installedPackage.metadata.version) { + if (compareversion(installedPackage.metadata.version, releaseInfo.version) == -1) { + $this.updatePackages.push(installedPackage); + $this.updatePackageIds.push(installedPackage.id); + } + } else { + $this.updatePackages.push(installedPackage); + $this.updatePackageIds.push(installedPackage.id); + } + } + } + + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + enablePackage: function (pkg) { + var text = pkg.isDisabled ? '启用' : '禁用'; + var isReference = this.referencePackageIds.indexOf(pkg.id) !== -1; + if (isReference) { + return swal("无法" + text, "存在其他插件依赖此插件,需要删除依赖插件后才能进行" + text + "操作", "error"); + } + swal({ + title: text + '插件', + text: '此操作将会禁用“' + pkg.id + '”,确认吗?', + type: 'question', + showCancelButton: true, + cancelButtonText: '取 消', + confirmButtonText: pkg.isDisabled ? '启 用' : '禁 用' + }).then(function (result) { + if (result.value) { + utils.loading(true); + $api.post($url + '/' + pkg.id + '/actions/enable').then(function () { + utils.loading(false); + swal({ + type: 'success', + title: '插件' + text + '成功', + text: '插件' + text + '成功,系统需要重载页面', + confirmButtonText: '重新载入' + }).then(function () { + window.top.location.reload(true); + }); + }); + } + }); + }, + + deletePackage: function (pkg) { + var isReference = this.referencePackageIds.indexOf(pkg.id) !== -1; + if (isReference) { + return swal("无法删除", "存在其他插件依赖此插件,需要删除依赖插件后才能进行删除操作", "error"); + } + swal2({ + title: '删除插件', + text: '此操作将会删除“' + pkg.id + '”,确认吗?', + type: 'question', + showCancelButton: true, + confirmButtonClass: 'btn btn-danger', + cancelButtonText: '取 消', + confirmButtonText: '确认删除' + }) + .then(function (result) { + if (result.value) { + utils.loading(true); + $api.delete($url + '/' + pkg.id).then(function () { + utils.loading(false); + swal({ + type: 'success', + title: '插件删除成功', + text: '插件删除成功,系统需要重载页面', + confirmButtonText: '重新载入' + }) + .then(function () { + window.top.location.reload(true); + }); + }); + } + }); + }, + + btnReload: function () { + utils.loading(true); + $api.post($urlReload).then(function () { + utils.loading(false); + swal({ + type: 'success', + title: '插件重新加载成功', + text: '插件重新加载成功,系统需要重载页面', + confirmButtonText: '重新载入' + }).then(function () { + window.top.location.reload(true); + }); + }); + } +}; + +var $vue = new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.load(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Plugins/view.cshtml b/net452/SiteServer.Web/SiteServer/Plugins/view.cshtml new file mode 100644 index 000000000..e687fd7c5 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Plugins/view.cshtml @@ -0,0 +1,133 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } +
      +
      + +
      +

      {{ pluginInfo.pluginId || package.id }}.{{ releaseInfo.version || + package.version }}

      +

      {{ pluginInfo.title || package.title }}

      +
      +
      + 价格: {{ pluginInfo.price.toFixed(2) + }} + 免 费 + + + | + 最新版本: {{ pluginInfo.latestNightlyVersion }} + + | + 更新时间: {{ pluginInfo.latestNightlyPublished }} + + + + | + 标签: {{ tagName }} + + +
      +

      {{ pluginInfo.summary || package.summary }}

      + 系统检测到插件新版本,当前版本:{{ installedVersion + }},新版本:{{ releaseInfo.version }} +
      + + + + + 插件主页 + +
      +
      +
      +
      + +
      +
      +

      插件详情

      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      开发者 {{ + userInfo.userName }}
      版本发行说明{{ releaseInfo.releaseNotes || package.releaseNotes }}
      更新日期{{ releaseInfo.published || package.published }}
      插件Id{{ pluginInfo.pluginId || package.id }}
      版本号{{ releaseInfo.version || package.version }}
      标签{{ pluginInfo.tags }}
      插件项目链接 + + {{ pluginInfo.projectUrl }} +
      版权{{ pluginInfo.copyright }}
      +
      +
      +
      +

      依赖项

      +
      +

      此插件依赖的类库以及其他插件

      + + + + + + + + + + + + + + + + + + + + +
      依赖项版本类型
      {{ reference.id }}{{ reference.version }}插件
      {{ reference.id }}{{ reference.version }}类库
      +
      @section Scripts{ + + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Plugins/view.js b/net452/SiteServer.Web/SiteServer/Plugins/view.js new file mode 100644 index 000000000..62f4d2e1a --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Plugins/view.js @@ -0,0 +1,101 @@ +var pluginId = utils.getQueryString('pluginId'); +var returnUrl = utils.getQueryString('returnUrl'); +var $url = '/pages/plugins/view/' + pluginId; + +var $data = { + pageLoad: false, + pageAlert: null, + isNightly: null, + pluginVersion: null, + installed: null, + installedVersion: null, + package: null, + isShouldUpdate: false, + pluginInfo: {}, + releaseInfo: {}, + userInfo: {} +}; + +var $methods = { + getIconUrl: function (url) { + if (url && url.indexOf('://') !== -1) return url; + return ssUtils.getPluginsUrl(url); + }, + + getTagNames: function (pluginInfo) { + var tagNames = []; + if (pluginInfo.tags) { + tagNames = pluginInfo.tags.split(','); + } + return tagNames; + }, + + load: function () { + var $this = this; + + $api.get($url).then(function (response) { + var res = response.data; + + $this.isNightly = res.isNightly; + $this.pluginVersion = res.pluginVersion; + $this.installed = res.installed; + $this.installedVersion = res.installedVersion; + $this.package = res.package || {}; + + $ssApi.get($ssUrlPlugins + '/' + pluginId, { + params: { + isNightly: $this.isNightly, + pluginVersion: $this.pluginVersion + } + }).then(function (response) { + var res = response.data; + + $this.pluginInfo = res.value.pluginInfo; + $this.releaseInfo = res.value.releaseInfo; + $this.userInfo = res.value.userInfo; + + $this.isShouldUpdate = compareversion($this.installedVersion, $this.releaseInfo.version) == -1; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert({ + message: '系统在线获取插件信息失败,请检查网络环境是否能够访问外网' + }); + }).then(function () { + $this.pageLoad = true; + }); + + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + btnUpgradeClick: function () { + location.href = 'install.cshtml?isUpdate=true&pluginIds=' + this.pluginInfo.pluginId; + }, + + btnPurchaseClick: function () { + location.href = ssUtils.getPluginPageUrl(this.pluginInfo.pluginId); + }, + + btnInstallClick: function () { + location.href = 'install.cshtml?pluginIds=' + this.pluginInfo.pluginId; + }, + + btnTagClick: function (tagName) { + location.href = 'add.cshtml?q=' + encodeURIComponent(tagName); + }, + + btnReturn: function () { + location.href = returnUrl; + } +}; + +var $vue = new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.load(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/adminAccessTokens.cshtml b/net452/SiteServer.Web/SiteServer/Settings/adminAccessTokens.cshtml new file mode 100644 index 000000000..bcfce7d8e --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/adminAccessTokens.cshtml @@ -0,0 +1,92 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } +@section Scripts{ } + + diff --git a/net452/SiteServer.Web/SiteServer/Settings/adminAccessTokens.js b/net452/SiteServer.Web/SiteServer/Settings/adminAccessTokens.js new file mode 100644 index 000000000..219654902 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/adminAccessTokens.js @@ -0,0 +1,141 @@ +var $url = '/pages/settings/adminAccessTokens'; + +var $data = { + pageLoad: false, + pageAlert: { + type: 'warning', + html: 'API密钥可以用于访问 SiteServer REST API 阅读更多' + }, + pageType: null, + items: null, + adminNames: null, + scopes: null, + adminName: null, + item: null +}; + +var $methods = { + getList: function () { + var $this = this; + + $api.get($url).then(function (response) { + var res = response.data; + + $this.items = res.value; + $this.adminNames = res.adminNames; + $this.scopes = res.scopes; + $this.adminName = res.adminName; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + getItemScopes: function (item) { + if (!item.scopes) return ''; + var itemScopes = item.scopes.split(','); + var retval = []; + for (var i = 0; i < this.scopes.length; i++) { + if (itemScopes.indexOf(this.scopes[i]) !== -1) { + retval.push(this.scopes[i]); + } + } + + return retval.join(','); + }, + + delete: function (item) { + var $this = this; + + utils.loading(true); + $api.delete($url, { + params: { + id: item.id + } + }).then(function (response) { + var res = response.data; + + $this.items = res.value; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + submit: function (item) { + var $this = this; + + $this.item.scopes = $this.item.scopeList ? $this.item.scopeList.join(',') : ''; + + utils.loading(true); + $api.post($url, $this.item).then(function (response) { + var res = response.data; + + $this.pageAlert = { + type: 'success', + html: item.id ? 'API密钥修改成功!' : 'API密钥添加成功!' + }; + $this.item = null; + $this.items = res.value; + $this.pageType = 'list'; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + btnAddClick: function (item) { + this.pageType = 'add'; + this.item = item; + this.item.adminName = this.item.adminName ? this.item.adminName : this.adminName; + this.item.scopeList = this.item.scopes ? this.item.scopes.split(',') : []; + }, + + btnSubmitClick: function () { + this.submit(this.item); + }, + + btnCancelClick: function () { + this.pageType = 'list'; + }, + + btnViewClick: function (item) { + utils.openLayer({ + title: '获取密钥', + url: 'adminAccessTokensViewLayer.cshtml?id=' + item.id, + height: 410 + }); + }, + + btnDeleteClick: function (item) { + var $this = this; + + swal2({ + title: '删除API密钥', + text: '此操作将删除API密钥 ' + item.title + ',确定吗?', + type: 'question', + confirmButtonText: '删 除', + confirmButtonClass: 'btn btn-danger', + showCancelButton: true, + cancelButtonText: '取 消' + }) + .then(function (result) { + if (result.value) { + $this.delete(item); + $this.pageType = 'list'; + } + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.getList(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/adminAccessTokensViewLayer.cshtml b/net452/SiteServer.Web/SiteServer/Settings/adminAccessTokensViewLayer.cshtml new file mode 100644 index 000000000..8a8278cba --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/adminAccessTokensViewLayer.cshtml @@ -0,0 +1,37 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles { } + +
      +
      + +

      {{ tokenInfo && tokenInfo.title }}

      +
      +
      +
      + +
      + {{ accessToken }} +
      +
      + +
      +
      +
      + +

      {{ tokenInfo && tokenInfo.addDate }}

      +
      +
      +
      + +

      {{ tokenInfo && tokenInfo.lastModifiedDate }}

      +
      +
      +
      +
      +
      + +
      @section Scripts{ } diff --git a/net452/SiteServer.Web/SiteServer/Settings/adminAccessTokensViewLayer.js b/net452/SiteServer.Web/SiteServer/Settings/adminAccessTokensViewLayer.js new file mode 100644 index 000000000..c0a9637b6 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/adminAccessTokensViewLayer.js @@ -0,0 +1,67 @@ +var $url = '/pages/settings/adminAccessTokensViewLayer'; +var $id = utils.getQueryString('id'); + +var $data = { + pageLoad: false, + pageAlert: { + type: 'warning', + html: 'API密钥属于敏感信息,请妥善保管不要泄露;如果怀疑信息泄露,请重设密钥。' + }, + tokenInfo: null, + accessToken: null +}; + +var $methods = { + getAccessToken: function () { + var $this = this; + + $api.get($url, { + params: { + id: $id + } + }).then(function (response) { + var res = response.data; + + $this.tokenInfo = res.tokenInfo; + $this.accessToken = res.accessToken; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + regenerate: function () { + var $this = this; + + utils.loading(true); + $api.post($url, { + id: $id + }).then(function (response) { + var res = response.data; + + $this.accessToken = res.value; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + btnCancelClick: function () { + utils.closeLayer(); + }, + + btnRegenerateClick: function () { + this.regenerate(); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.getAccessToken(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/adminPassword.cshtml b/net452/SiteServer.Web/SiteServer/Settings/adminPassword.cshtml new file mode 100644 index 000000000..becd03832 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/adminPassword.cshtml @@ -0,0 +1,74 @@ +@{ Layout = "../Shared/_Layout.cshtml"; }
      +
      + +
      +
      + + +
      + + + 帐号用于登录系统,由字母、数字组成 +
      +
      + + +
      +
      + + +
      +
      +
      + + +
      +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/adminPassword.js b/net452/SiteServer.Web/SiteServer/Settings/adminPassword.js new file mode 100644 index 000000000..420194341 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/adminPassword.js @@ -0,0 +1,85 @@ +var $url = '/pages/settings/adminPassword'; +var $pageTypeAdmin = 'admin'; +var $pageTypeUser = 'user'; + +var $data = { + pageLoad: false, + pageAlert: null, + pageType: utils.getQueryString('pageType'), + userId: parseInt(utils.getQueryString('userId') || '0'), + adminInfo: null, + password: null, + confirmPassword: null +}; + +var $methods = { + getConfig: function () { + var $this = this; + + $api.get($url + '?userId=' + $this.userId).then(function (response) { + var res = response.data; + + $this.adminInfo = res.value; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + submit: function () { + var $this = this; + + utils.loading(true); + $api.post($url + '?userId=' + $this.userId, { + password: $this.password + }).then(function (response) { + var res = response.data; + + swal({ + toast: true, + type: 'success', + title: "密码更改成功!", + showConfirmButton: false, + timer: 3000 + }).then(function () { + if ($this.pageType == $pageTypeAdmin) { + $this.btnReturnClick(); + } else { + top.location.reload(true); + } + }); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + btnSubmitClick: function () { + this.pageAlert = null; + + var $this = this; + if (this.adminInfo.id > 0 && this.password != this.confirmPassword) { + return; + } + this.$validator.validate().then(function (result) { + if (result) { + $this.submit(); + } + }); + }, + + btnReturnClick: function () { + location.href = 'administrators.cshtml'; + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.getConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/adminProfile.cshtml b/net452/SiteServer.Web/SiteServer/Settings/adminProfile.cshtml new file mode 100644 index 000000000..dbcb7ad71 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/adminProfile.cshtml @@ -0,0 +1,121 @@ +@{ Layout = "../Shared/_Layout.cshtml"; }
      +
      + +
      +
      + + +
      + + + 帐号用于登录系统,由字母、数字组成 +
      +
      + + +
      +
      + +
      + + 上 传 +
      +
      + +
      + + + 可用于登录、找回密码等功能。 +
      +
      + + + 可用于登录、找回密码等功能。 +
      +
      + + +
      +
      + + +
      +
      +
      + + +
      +
      @section Scripts{ + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/adminProfile.js b/net452/SiteServer.Web/SiteServer/Settings/adminProfile.js new file mode 100644 index 000000000..39c9a33cb --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/adminProfile.js @@ -0,0 +1,107 @@ +var $url = '/pages/settings/adminProfile'; +var $pageTypeAdmin = 'admin'; +var $pageTypeUser = 'user'; + +var $data = { + pageLoad: false, + pageAlert: null, + pageType: utils.getQueryString('pageType'), + userId: parseInt(utils.getQueryString('userId') || '0'), + adminInfo: null, + departments: null, + areas: null, + password: null, + confirmPassword: null, + uploadUrl: null, + files: [] +}; + +var $methods = { + getConfig: function () { + var $this = this; + + $api.get($url + '?userId=' + $this.userId).then(function (response) { + var res = response.data; + + $this.adminInfo = res.value; + $this.departments = res.departments; + $this.areas = res.areas; + $this.uploadUrl = $apiUrl + '/pages/settings/adminProfile/upload?adminToken=' + res.adminToken + '&userId=' + $this.userId; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + inputAvatar(newFile, oldFile) { + if (Boolean(newFile) !== Boolean(oldFile) || oldFile.error !== newFile.error) { + if (!this.$refs.avatar.active) { + this.$refs.avatar.active = true + } + } + + if (newFile && oldFile && newFile.xhr && newFile.success !== oldFile.success) { + this.adminInfo.avatarUrl = newFile.response.value; + } + }, + + submit: function () { + var $this = this; + + utils.loading(true); + $api.post($url + '?userId=' + $this.userId, _.assign({}, $this.adminInfo, { + password: $this.password + })).then(function (response) { + var res = response.data; + + swal({ + toast: true, + type: 'success', + title: "管理员资料保存成功!", + showConfirmButton: false, + timer: 3000 + }).then(function () { + if ($this.pageType == $pageTypeAdmin) { + $this.btnReturnClick(); + } else { + top.location.reload(true); + } + }); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + btnSubmitClick: function () { + this.pageAlert = null; + + var $this = this; + if (this.adminInfo.id > 0 && this.password != this.confirmPassword) { + return; + } + this.$validator.validate().then(function (result) { + if (result) { + $this.submit(); + } + }); + }, + + btnReturnClick: function () { + location.href = 'administrators.cshtml'; + } +}; + +new Vue({ + el: '#main', + data: $data, + components: { + FileUpload: VueUploadComponent + }, + methods: $methods, + created: function () { + this.getConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/adminView.cshtml b/net452/SiteServer.Web/SiteServer/Settings/adminView.cshtml new file mode 100644 index 000000000..e3aa18e9c --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/adminView.cshtml @@ -0,0 +1,106 @@ +@{ Layout = "../Shared/_Layout.cshtml"; }
      +
      + +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      管理员Id {{ adminInfo.id }}
      账号 {{ adminInfo.userName }}
      姓名 {{ adminInfo.displayName }}
      级别 {{ level }}
      角色
      可管理站点
      创建时间 {{ adminInfo.creationDate }}
      最后登录时间 {{ adminInfo.lastActivityDate }}
      手机号码 {{ adminInfo.mobile }}
      电子邮箱 {{ adminInfo.email }}
      所属部门 {{ departmentName }}
      所在区域 {{ areaName }}
      + +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/adminView.js b/net452/SiteServer.Web/SiteServer/Settings/adminView.js new file mode 100644 index 000000000..e325e0bf4 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/adminView.js @@ -0,0 +1,54 @@ +var $url = '/pages/settings/adminView'; +var $pageTypeAdmin = 'admin'; +var $pageTypeUser = 'user'; + +var $data = { + pageLoad: false, + pageAlert: null, + pageType: utils.getQueryString('pageType'), + userId: parseInt(utils.getQueryString('userId') || '0'), + adminInfo: null, + departmentName: null, + areaName: null, + level: null, + isSuperAdmin: null, + siteNames: null, + isOrdinaryAdmin: null, + roleNames: null +}; + +var $methods = { + getConfig: function () { + var $this = this; + + $api.get($url + '?userId=' + $this.userId).then(function (response) { + var res = response.data; + + $this.adminInfo = res.value; + $this.departmentName = res.departmentName; + $this.areaName = res.areaName; + $this.level = res.level; + $this.isSuperAdmin = res.isSuperAdmin; + $this.siteNames = res.siteNames; + $this.isOrdinaryAdmin = res.isOrdinaryAdmin; + $this.roleNames = res.roleNames; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + btnReturnClick: function () { + location.href = 'administrators.cshtml'; + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.getConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/administrators.cshtml b/net452/SiteServer.Web/SiteServer/Settings/administrators.cshtml new file mode 100644 index 000000000..6f42ca9c6 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/administrators.cshtml @@ -0,0 +1,210 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } +@section Styles{ + + +} +@section Scripts{ + + +} + +
      + + +
      + + + +
      +
      +
      + + +
      +
      + + +
      +
      + + +
      +
      + + +
      +
      + + +
      + 搜 索 +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      头像账号姓名手机部门区域最后登录登录次数角色操作 + + +
      + + +
      {{ content.state }}
      + + {{ content.userName }} + +
      + {{ content.displayName || content.userName }} + + {{ content.mobile }} + + {{ content.departmentName }} + + {{ content.areaName }} + + {{ content.lastLoginDate }} + + {{ content.countOfLogin }} + + {{ content.roleName }} + + 修改资料 + 更改密码 + 权限设置 + + + +
      + +
      + 新 增 + + + + + + +
      + +
      +
      +
      + +
      +
      + + + + +
      +
      + +
      diff --git a/net452/SiteServer.Web/SiteServer/Settings/administrators.js b/net452/SiteServer.Web/SiteServer/Settings/administrators.js new file mode 100644 index 000000000..f47591e8e --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/administrators.js @@ -0,0 +1,275 @@ +var $url = '/pages/settings/administrators'; +var $urlActionsLock = '/pages/settings/administrators/actions/lock'; +var $urlActionsUnLock = '/pages/settings/administrators/actions/unlock'; +var $urlActionsDelete = '/pages/settings/administrators/actions/delete'; + +var $data = { + pageLoad: false, + pageAlert: null, + pageContents: null, + count: null, + pages: null, + roles: null, + departments: null, + areas: null, + pageOptions: null, + isAllChecked: false, + roleName: '', + order: '', + departmentId: 0, + areaId: 0, + keyword: '', + searchParams: null +}; + +var $methods = { + toggleChecked: function (content) { + content.isSelected = !content.isSelected; + if (!content.isSelected) { + this.isAllChecked = false; + } + }, + + selectAll: function () { + this.isAllChecked = !this.isAllChecked; + for (var i = 0; i < this.pageContents.length; i++) { + this.pageContents[i].isSelected = this.isAllChecked; + } + }, + + loadFirstPage: function () { + if (this.page === 1) return; + this.loadContents(1); + }, + + loadPrevPage: function () { + if (this.page - 1 <= 0) return; + this.loadContents(this.page - 1); + }, + + loadNextPage: function () { + if (this.page + 1 > this.pages) return; + this.loadContents(this.page + 1); + }, + + loadLastPage: function () { + if (this.page + 1 > this.pages) return; + this.loadContents(this.pages); + }, + + onPageSelect: function (option) { + this.loadContents(option); + }, + + scrollToTop: function () { + document.documentElement.scrollTop = document.body.scrollTop = 0; + }, + + btnSearchClick: function () { + this.searchParams = { + roleName: this.roleName, + order: this.order, + departmentId: this.departmentId, + areaId: this.areaId, + keyword: this.keyword + } + this.loadContents(1); + }, + + loadContents: function (page) { + var $this = this; + + if ($this.pageLoad) { + utils.loading(true); + } + + var params = _.assign({page: page}, this.searchParams); + + $api.get($url, { + params: params + }).then(function (response) { + var res = response.data; + + var pageContents = []; + for (var i = 0; i < res.value.length; i++) { + var content = _.assign({}, res.value[i], { + isSelected: false + }); + pageContents.push(content); + } + $this.pageContents = pageContents; + + $this.count = res.count; + $this.pages = res.pages; + $this.roles = res.roles; + $this.departments = res.departments; + $this.areas = res.areas; + $this.page = page; + $this.pageOptions = []; + for (var i = 1; i <= $this.pages; i++) { + $this.pageOptions.push(i); + } + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + if ($this.pageLoad) { + utils.loading(false); + $this.scrollToTop(); + } else { + $this.pageLoad = true; + } + }); + }, + + btnPermissionsClick: function(content) { + utils.openLayer({ + title: '权限设置', + url: 'modalPermissionsSet.aspx?userName=' + content.userName, + full: true + }); + }, + + btnLockClick: function () { + if (this.selectedContentIds.length === 0) return; + var $this = this; + + swal2({ + title: '锁定管理员', + text: '此操作将把所选管理员设置为锁定状态,确定吗?', + type: 'question', + confirmButtonText: '锁 定', + confirmButtonClass: 'btn btn-danger', + showCancelButton: true, + cancelButtonText: '取 消' + }) + .then(function (result) { + if (result.value) { + utils.loading(true); + $api.post($urlActionsLock, { + adminIds: $this.selectedContentIds.join(",") + }).then(function (response) { + var res = response.data; + + swal2.fire({ + title: '锁定管理员', + text: '成功锁定所选管理员', + type: 'success', + confirmButtonText: '确 定', + confirmButtonClass: 'btn btn-primary', + showCancelButton: false + }); + + $this.loadContents(1); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } + }); + }, + + btnUnLockClick: function() { + if (this.selectedContentIds.length === 0) return; + var $this = this; + + swal2({ + title: '解锁管理员', + text: '此操作将解锁所选管理员,确定吗?', + type: 'question', + confirmButtonText: '解 锁', + confirmButtonClass: 'btn btn-danger', + showCancelButton: true, + cancelButtonText: '取 消' + }) + .then(function (result) { + if (result.value) { + utils.loading(true); + $api.post($urlActionsUnLock, { + adminIds: $this.selectedContentIds.join(",") + }).then(function (response) { + var res = response.data; + + swal2.fire({ + title: '解锁管理员', + text: '成功解锁所选管理员', + type: 'success', + confirmButtonText: '确 定', + confirmButtonClass: 'btn btn-primary', + showCancelButton: false + }); + + $this.loadContents(1); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } + }); + }, + + btnDeleteClick: function () { + if (this.selectedContentIds.length === 0) return; + var $this = this; + + swal2({ + title: '删除管理员', + text: '此操作将删除所选管理员,确定吗?', + type: 'question', + confirmButtonText: '删 除', + confirmButtonClass: 'btn btn-danger', + showCancelButton: true, + cancelButtonText: '取 消' + }) + .then(function (result) { + if (result.value) { + utils.loading(true); + $api.post($urlActionsDelete, { + adminIds: $this.selectedContentIds.join(",") + }).then(function (response) { + var res = response.data; + + swal2.fire({ + title: '删除管理员', + text: '成功删除所选管理员', + type: 'success', + confirmButtonText: '确 定', + confirmButtonClass: 'btn btn-primary', + showCancelButton: false + }); + + $this.loadContents(1); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } + }); + } +}; + +Vue.component("multiselect", window.VueMultiselect.default); + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + computed: { + selectedContentIds: function () { + var retval = []; + if (this.pageContents) { + for (var i = 0; i < this.pageContents.length; i++) { + if (this.pageContents[i].isSelected) { + retval.push(this.pageContents[i].id); + } + } + } + return retval; + } + }, + created: function () { + this.loadContents(1); + } +}); diff --git a/SiteServer.Web/SiteServer/Settings/modalAdminSelect.aspx b/net452/SiteServer.Web/SiteServer/Settings/modalAdminSelect.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Settings/modalAdminSelect.aspx rename to net452/SiteServer.Web/SiteServer/Settings/modalAdminSelect.aspx diff --git a/SiteServer.Web/SiteServer/Settings/modalAreaAdd.aspx b/net452/SiteServer.Web/SiteServer/Settings/modalAreaAdd.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Settings/modalAreaAdd.aspx rename to net452/SiteServer.Web/SiteServer/Settings/modalAreaAdd.aspx diff --git a/SiteServer.Web/SiteServer/Settings/modalChangeSiteType.aspx b/net452/SiteServer.Web/SiteServer/Settings/modalChangeSiteType.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Settings/modalChangeSiteType.aspx rename to net452/SiteServer.Web/SiteServer/Settings/modalChangeSiteType.aspx diff --git a/SiteServer.Web/SiteServer/Settings/modalDepartmentAdd.aspx b/net452/SiteServer.Web/SiteServer/Settings/modalDepartmentAdd.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Settings/modalDepartmentAdd.aspx rename to net452/SiteServer.Web/SiteServer/Settings/modalDepartmentAdd.aspx diff --git a/SiteServer.Web/SiteServer/Settings/modalExportMessage.aspx b/net452/SiteServer.Web/SiteServer/Settings/modalExportMessage.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Settings/modalExportMessage.aspx rename to net452/SiteServer.Web/SiteServer/Settings/modalExportMessage.aspx diff --git a/SiteServer.Web/SiteServer/Settings/modalImportZip.aspx b/net452/SiteServer.Web/SiteServer/Settings/modalImportZip.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Settings/modalImportZip.aspx rename to net452/SiteServer.Web/SiteServer/Settings/modalImportZip.aspx diff --git a/SiteServer.Web/SiteServer/Settings/modalKeywordAdd.aspx b/net452/SiteServer.Web/SiteServer/Settings/modalKeywordAdd.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Settings/modalKeywordAdd.aspx rename to net452/SiteServer.Web/SiteServer/Settings/modalKeywordAdd.aspx diff --git a/SiteServer.Web/SiteServer/Settings/modalKeywordImport.aspx b/net452/SiteServer.Web/SiteServer/Settings/modalKeywordImport.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Settings/modalKeywordImport.aspx rename to net452/SiteServer.Web/SiteServer/Settings/modalKeywordImport.aspx diff --git a/SiteServer.Web/SiteServer/Settings/modalManualUpdateSystem.aspx b/net452/SiteServer.Web/SiteServer/Settings/modalManualUpdateSystem.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Settings/modalManualUpdateSystem.aspx rename to net452/SiteServer.Web/SiteServer/Settings/modalManualUpdateSystem.aspx diff --git a/SiteServer.Web/SiteServer/Settings/modalPermissionsSet.aspx b/net452/SiteServer.Web/SiteServer/Settings/modalPermissionsSet.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Settings/modalPermissionsSet.aspx rename to net452/SiteServer.Web/SiteServer/Settings/modalPermissionsSet.aspx diff --git a/SiteServer.Web/SiteServer/Settings/modalUserExport.aspx b/net452/SiteServer.Web/SiteServer/Settings/modalUserExport.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Settings/modalUserExport.aspx rename to net452/SiteServer.Web/SiteServer/Settings/modalUserExport.aspx diff --git a/SiteServer.Web/SiteServer/Settings/modalUserPassword.aspx b/net452/SiteServer.Web/SiteServer/Settings/modalUserPassword.aspx similarity index 100% rename from SiteServer.Web/SiteServer/Settings/modalUserPassword.aspx rename to net452/SiteServer.Web/SiteServer/Settings/modalUserPassword.aspx diff --git a/net452/SiteServer.Web/SiteServer/Settings/modalUserView.aspx b/net452/SiteServer.Web/SiteServer/Settings/modalUserView.aspx new file mode 100644 index 000000000..6f2c70c6c --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/modalUserView.aspx @@ -0,0 +1,60 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.ModalUserView" Trace="false"%> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      + +
      + +
      + +
      + +
      +
      + +
      + +
      + +
      + +
      + +
      +
      + +
      + +
      + +
      + +
      + +
      +
      + + + +
      + +
      + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageAdminArea.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageAdminArea.aspx new file mode 100644 index 000000000..0e0ad597f --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageAdminArea.aspx @@ -0,0 +1,84 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAdminArea" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + +
      区域名称管理员人数上升下降  + +
      + +
      +
      +
      + + + +
      + + + + +
      + + + + + + diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageAdminConfiguration.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageAdminConfiguration.aspx new file mode 100644 index 000000000..cb4c02db6 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageAdminConfiguration.aspx @@ -0,0 +1,108 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAdminConfiguration" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      + + + 0代表不限制 +
      + +
      + + + 0代表不限制 +
      + +
      + + +
      + +
      + + + +
      + + +
      + + + 一旦登录失败达到指定次数之后管理员就会被锁定 +
      + +
      + + +
      + + + +
      + + +
      +
      +
      + +
      + + + 注意:超级管理员、站点管理员、具有审核权限的管理员,此设置无效。 +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageAdminDepartment.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageAdminDepartment.aspx new file mode 100644 index 000000000..58b7646f8 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageAdminDepartment.aspx @@ -0,0 +1,85 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAdminDepartment" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + +
      部门名称部门编号管理员人数上升下降  + +
      + +
      +
      +
      + + + +
      + + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageAdminPermissionAdd.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageAdminPermissionAdd.aspx new file mode 100644 index 000000000..a01ed1b7f --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageAdminPermissionAdd.aspx @@ -0,0 +1,135 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAdminPermissionAdd" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + +
      + + + + + +
      + +
      + +
      + +
      +
      +
      + + + +
      + +
      + +
      + +
      +
      +
      + + + +
      + +
      + + +
      + +
      + + + 从下边选择需要管理的栏目,所选栏目下的所有子栏目都属于可管理范围 + + +
      + +
      + +
      + +
      + +
      + + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageAdminRole.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageAdminRole.aspx new file mode 100644 index 000000000..cfc2123c8 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageAdminRole.aspx @@ -0,0 +1,88 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAdminRole" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + +
      角色名称备注  
      + + + + + + + +
      + +
      +
      +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageAdminRoleAdd.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageAdminRoleAdd.aspx new file mode 100644 index 000000000..9caf19dc7 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageAdminRoleAdd.aspx @@ -0,0 +1,129 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAdminRoleAdd" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      + + + 唯一标识此角色的字符串 +
      + +
      + + +
      + +
      + +
      + +
      +
      + + + +
      + + +
      + + +
      +
      + +
      + +
      + +
      + + + + +
      + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisAdminLogin.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisAdminLogin.aspx new file mode 100644 index 000000000..59b47aec4 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisAdminLogin.aspx @@ -0,0 +1,162 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAnalysisAdminLogin" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + +
      + + + + + +
      +
      +
      + + +
      + +
      + + +
      + +
      + + +
      + + +
      + +
      + +

      + +

      + +
      + + +
      + +

      + +

      + +
      + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisAdminWork.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisAdminWork.aspx new file mode 100644 index 000000000..985678903 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisAdminWork.aspx @@ -0,0 +1,182 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAnalysisAdminWork" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + +
      + + + + + +
      +
      +
      + + +
      + +
      + + +
      + +
      + + +
      + + +
      + + + +
      + +
      +
      + +
      + +
      +
      +
      + + + + + + + + + + + + + + + + + + + +
      登录名 显示名 新增内容 更新内容
      + + + + + + + +
      +
      +
      +
      + + + +
      + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisSite.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisSite.aspx new file mode 100644 index 000000000..1f6e355a7 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisSite.aspx @@ -0,0 +1,180 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAnalysisSite" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + +
      + + + + + +
      +
      +
      + + +
      + +
      + + +
      + +
      + + +
      + + +
      + +
      + +
      +
      +
      + +
      + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      站点名称新增内容修改内容合计
      + + + + + + + +
      总计 + + + + + +
      +
      +
      +
      + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteChannels.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteChannels.aspx new file mode 100644 index 000000000..6e9398f3b --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteChannels.aspx @@ -0,0 +1,163 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAnalysisSiteChannels" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + +
      + + + + + +
      +
      +
      + + +
      + +
      + + +
      + +
      + + +
      + + +
      + +
      + +
      +
      + +
      + +
      +
      +
      + + + + + + + + + + + + + +
      栏目名新增内容修改内容
      +
      +
      +
      + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteHits.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteHits.aspx new file mode 100644 index 000000000..8a6e022e3 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteHits.aspx @@ -0,0 +1,141 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAnalysisSiteHits" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + +
      + + + + + +
      +
      +
      + + +
      +
      + +
      + +
      +
      + +
      + +
      +
      +
      + + + + + + + + + + + + + + + + + + + +
      站点名称点击量
      + + + +
      总计 + +
      +
      +
      +
      + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteHitsChannels.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteHitsChannels.aspx new file mode 100644 index 000000000..f636fb1bd --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisSiteHitsChannels.aspx @@ -0,0 +1,182 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAnalysisSiteHitsChannels" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + +
      + + + + + +
      +
      +
      + + +
      +
      + +
      + +
      +
      + +
      + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      内容标题(点击查看)所属栏目点击量日点击量周点击量月点击量最后点击时间
      + + + + + + + + + + + + + +
      +
      +
      +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisUser.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisUser.aspx new file mode 100644 index 000000000..bf2384c80 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageAnalysisUser.aspx @@ -0,0 +1,111 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageAnalysisUser" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + +
      + + + + + +
      +
      +
      + + +
      + +
      + + +
      + +
      + + +
      + + +
      + +
      + +

      + +

      + +
      + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageLogAdmin.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageLogAdmin.aspx new file mode 100644 index 000000000..2de6213d6 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageLogAdmin.aspx @@ -0,0 +1,125 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageLogAdmin" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      + + +
      + +
      + + +
      + +
      + + +
      + +
      + + +
      + + +
      + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      管理员IP地址日期动作描述 + +
      + + + + + + + + + + + +
      + +
      +
      +
      + + + +
      + + + + + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageLogConfiguration.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageLogConfiguration.aspx new file mode 100644 index 000000000..3e8041c6c --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageLogConfiguration.aspx @@ -0,0 +1,65 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageLogConfiguration" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      + + + 启用后系统将定时自动删除日志,以节省数据库存储空间 +
      + + +
      + + + 设置为60天,则默认只保留60天的日志,60天之前的日志将被系统自动删除 +
      +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageLogError.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageLogError.aspx new file mode 100644 index 000000000..7152be03a --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageLogError.aspx @@ -0,0 +1,128 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageLogError" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      + + +
      + +
      + + +
      +
      + +
      +
      + + +
      + +
      + + +
      + +
      + + +
      + + +
      + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + +
      Id错误摘要错误消息日期 + +
      + + + + + + + + + +
      + +
      +
      +
      + + + +
      + + + + + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageLogSite.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageLogSite.aspx new file mode 100644 index 000000000..df9a4c43f --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageLogSite.aspx @@ -0,0 +1,141 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageLogSite" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      + + +
      + +
      + + +
      + +
      + + +
      + +
      + + +
      +
      + +
      +
      + + +
      + +
      + + +
      + + +
      + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      管理员IP地址日期动作描述 + +
      + + + + + + + + + + + +
      + +
      +
      +
      + + + +
      + + + + + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageLogUser.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageLogUser.aspx new file mode 100644 index 000000000..5939c9d79 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageLogUser.aspx @@ -0,0 +1,125 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageLogUser" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      + + +
      + +
      + + +
      + +
      + + +
      + +
      + + +
      + + +
      + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      用户IP地址日期动作描述 + +
      + + + + + + + + + + + +
      + +
      +
      +
      + + + +
      + + + + + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageSite.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageSite.aspx new file mode 100644 index 000000000..8df2829bb --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageSite.aspx @@ -0,0 +1,94 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSite" EnableViewState="false" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + +
      站点名称文件夹内容表排序操作
      + + + + + + + + + +
      + +
      +
      +
      + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageSiteAdd.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageSiteAdd.aspx new file mode 100644 index 000000000..6dff327a4 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageSiteAdd.aspx @@ -0,0 +1,220 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteAdd" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + +
      +
      创建新站点 + +
      + +

      欢迎使用创建新站点向导,请选择创建站点的方式

      +
      + + +
      +
      + +

      请选择站点模板

      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + +
      站点模板名称站点模板文件夹站点模板介绍样图
      + + + + + + + + + +
      +
      +
      +
      +
      + +

      请选择在线模板,本页面只显示部分免费模板,更多站点模板请访问官网: https://www.siteserver.cn/templates +

      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      名称简介模板作者更新时间
      + + + + + + + + + + + +
      +
      +
      +
      +
      + +

      在此设置新建站点的名称、文件夹以及内容表等信息

      +
      + +
      + +
      +
      +
      + + +
      +
      + + + + + +
      + +
      + + +
      +
      + + + 实际在服务器中保存此网站的文件夹名称,此路径必须以英文或拼音命名 +
      +
      + +
      + + +
      +
      + +
      + + +
      +
      +
      + + + + + 请选择已存在的内容表 + + + + 请输入内容表名称,系统将检测数据库是否已存在指定的内容表,如果不存在系统将创建此内容表。 + +
      +
      + + +
      + +
      + + + + + + + + 指此内容在添加后需要经多少次审核才能正式发布 +
      +
      +
      + + +
      +
      +
      +
      + + + +
      +
      + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageSiteDelete.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageSiteDelete.aspx new file mode 100644 index 000000000..6bb3fda46 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageSiteDelete.aspx @@ -0,0 +1,62 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteDelete" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      +
      删除站点
      +

      站点名称: +

      +
      + + + + + + 选择保留文件删除操作将仅在数据库中删除此站点 +
      +
      + + +
      + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageSiteEdit.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageSiteEdit.aspx new file mode 100644 index 000000000..293989011 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageSiteEdit.aspx @@ -0,0 +1,118 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteEdit" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      +
      修改站点
      +
      + + +
      + +
      + + + 实际在服务器中保存此网站的文件夹名称,此路径必须以英文或拼音命名。 +
      +
      + +
      + + +
      +
      +
      + + + + + 请选择已存在的内容表 + + + + 请输入内容表名称,系统将检测数据库是否已存在指定的内容表,如果不存在系统将创建此内容表。 + +
      +
      + + + 设置站点排序,排序数字大的站点将排在其他站点之前 +
      +
      + + +
      + +
      + + + + + + + +
      +
      +
      + + +
      + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageSiteKeyword.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageSiteKeyword.aspx new file mode 100644 index 000000000..b0f939d74 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageSiteKeyword.aspx @@ -0,0 +1,93 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteKeyword" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + +
      敏感词替换为等级
      + + + + + + + + + +
      +
      +
      +
      + +
      + + + +
      + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageSiteSave.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageSiteSave.aspx new file mode 100644 index 000000000..5c28be7ac --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageSiteSave.aspx @@ -0,0 +1,151 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteSave" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      +
      保存站点模板
      + +

      保存站点模板能够将此站点的文件、栏目、内容、模板、插件等保存在站点模板文件夹中

      +
      + + +
      +
      + + + 文件名必须以T_开头,且以英文或拼音取名 +
      +
      + + +
      +
      + + +
      +
      + +

      保存站点文件,点击下一步将站点的文件保存到站点模板中

      +
      + + +
      + +
      + + +
      +
      +
      + +

      保存站点内容,点击下一步将站点的栏目及内容信息保存到站点模板中

      +
      + + +
      +
      + + +
      + +
      + + 从下边选择需要保存的栏目,所选栏目的下级栏目将自动保存到站点模板中 +
      + +
      +
      +
      + +

      保存站点数据,点击下一步将站点数据(包括模板、内容表、配置信息、插件等)保存到站点模板中

      +
      + +

      载入样图文件,选择样图文件的名称

      +
      + + +
      +
      + +

      站点模板保存成功,您已经完成保存站点模板的操作

      +
      +

      保存成功,站点模版保存在"SiteFiles\SiteTemplates\ + <%=TbSiteTemplateDir.Text%>"文件夹中

      +
      +
      +
      +
      + + + + + + +
      +
      + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageSiteTableStyle.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageSiteTableStyle.aspx new file mode 100644 index 000000000..474ba3344 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageSiteTableStyle.aspx @@ -0,0 +1,107 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteTableStyle" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      +
      虚拟字段管理
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      字段名显示名称表单提交类型字段类型验证规则排序显示样式表单验证
      + + + + + + + + + + + + + + + +
      +
      +
      +
      +
      + + + + + +
      + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageSiteTemplate.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageSiteTemplate.aspx new file mode 100644 index 000000000..2401a25bb --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageSiteTemplate.aspx @@ -0,0 +1,135 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteTemplate" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      站点模板名称站点模板文件夹站点模板介绍创建日期
      + + + + + + + + + + + + + +
      +
      +
      +
      +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + +
      未解压站点模板创建日期
      + + + + + + + +
      +
      +
      +
      +
      + +
      + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageSiteTemplateOnline.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageSiteTemplateOnline.aspx new file mode 100644 index 000000000..ee447c729 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageSiteTemplateOnline.aspx @@ -0,0 +1,92 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteTemplateOnline" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + +
      名称简介模板作者更新时间
      + + + + + + + + + + + +
      +
      +
      +
      +
      + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageSiteUrlApi.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageSiteUrlApi.aspx new file mode 100644 index 000000000..5442d9aad --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageSiteUrlApi.aspx @@ -0,0 +1,67 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteUrlApi" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      +
      + + + 设置API服务器部署方式 +
      + +
      + + +
      +
      +
      + +
      + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageSiteUrlAssets.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageSiteUrlAssets.aspx new file mode 100644 index 000000000..4cd2748a6 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageSiteUrlAssets.aspx @@ -0,0 +1,88 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteUrlAssets" enableViewState = "false" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + +
      站点名称文件夹存储文件夹访问地址
      + + + + + + + + + +
      +
      +
      +
      +
      + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageSiteUrlAssetsConfig.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageSiteUrlAssetsConfig.aspx new file mode 100644 index 000000000..0c17554f3 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageSiteUrlAssetsConfig.aspx @@ -0,0 +1,78 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteUrlAssetsConfig" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      +
      修改文件访问地址
      +

      站点名称: +

      +
      + + + 文件包含图片、视频、附件等除了HTML页面之外的所有文件 +
      + +
      + + +
      +
      + + +
      +
      +
      + + +
      + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageSiteUrlWeb.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageSiteUrlWeb.aspx new file mode 100644 index 000000000..6602da705 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageSiteUrlWeb.aspx @@ -0,0 +1,84 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteUrlWeb" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + +
      站点名称文件夹Web访问地址
      + + + + + + + +
      +
      +
      +
      +
      + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageSiteUrlWebConfig.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageSiteUrlWebConfig.aspx new file mode 100644 index 000000000..76987947e --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageSiteUrlWebConfig.aspx @@ -0,0 +1,71 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageSiteUrlWebConfig" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + +
      +
      修改Web访问地址
      +

      站点名称: +

      +
      + + + 设置网站页面部署方式 +
      + +
      + + +
      +
      +
      + + +
      + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageUser.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageUser.aspx new file mode 100644 index 000000000..cba479be1 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageUser.aspx @@ -0,0 +1,196 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageUser" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      +
      + + +
      + +
      + + + + + + + + + +
      + +
      + + + + + + + + + + + + +
      + +
      + + + + + + + + + + + + +
      + +
      + + + + + + + + + +
      +
      + +
      +
      + + +
      + +
      + + +
      + + +
      +
      + +
      +
      +
      + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
      账号邮箱手机注册时间用户组登录次数  + +
      + + + + + + + + + + + + + + + + +
      + +
      +
      +
      + + + +
      + + + + + + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageUserAdd.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageUserAdd.aspx new file mode 100644 index 000000000..ef4047f2f --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageUserAdd.aspx @@ -0,0 +1,116 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageUserAdd" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + +
      +
      + +
      + +
      + + + 帐号用于登录系统,由字母、数字组成 +
      + +
      + + +
      + +
      + + +
      + + +
      + + + + + +
      + +
      + + +
      +
      + +
      + + +
      + +
      + + +
      + +
      + + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageUtilityCache.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageUtilityCache.aspx new file mode 100644 index 000000000..a156e5f6e --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageUtilityCache.aspx @@ -0,0 +1,85 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageUtilityCache" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +

      + 当前缓存: + 个 + +

      + +
      +
      +
      + + + + + + + + + + + + + + + + + +
      缓存键缓存值
      + + + + + + + +
      + +
      +
      +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageUtilityDbLogDelete.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageUtilityDbLogDelete.aspx new file mode 100644 index 000000000..a8508f2af --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageUtilityDbLogDelete.aspx @@ -0,0 +1,52 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageUtilityDbLogDelete" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +

      + 上一次清空日志时间: + +

      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageUtilityEncrypt.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageUtilityEncrypt.aspx new file mode 100644 index 000000000..6b77ea35d --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageUtilityEncrypt.aspx @@ -0,0 +1,62 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageUtilityEncrypt" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      + + +
      + + +
      + + +
      +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageUtilityJsMin.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageUtilityJsMin.aspx new file mode 100644 index 000000000..ac189f7f3 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageUtilityJsMin.aspx @@ -0,0 +1,340 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageUtilityJsMin" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + + + + +
      + + + + + +
      +
      + + +
      + +
      + + +
      + +
      + + + + 原来大小: + + 压缩后大小: + + 压缩率: + + +
      + +
      + + + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/pageUtilityParameter.aspx b/net452/SiteServer.Web/SiteServer/Settings/pageUtilityParameter.aspx new file mode 100644 index 000000000..f8bfe2ce3 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/pageUtilityParameter.aspx @@ -0,0 +1,73 @@ +<%@ Page Language="C#" Inherits="SiteServer.BackgroundPages.Settings.PageUtilityParameter" %> +<%@ Register TagPrefix="ctrl" Namespace="SiteServer.BackgroundPages.Controls" Assembly="SiteServer.BackgroundPages" %> + + + + + + + + + +
      + + + + + +
      +
      +
      +
      + + + + + + + + + + + + + + + + + +
      参数名称
      + + + +
      + +
      +
      +
      + +
      + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/siteAdd.cshtml b/net452/SiteServer.Web/SiteServer/Settings/siteAdd.cshtml new file mode 100644 index 000000000..776de7334 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/siteAdd.cshtml @@ -0,0 +1,214 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } +
      +
      创建新站点
      + + + + +
      @section Scripts{ + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/siteAdd.js b/net452/SiteServer.Web/SiteServer/Settings/siteAdd.js new file mode 100644 index 000000000..7cba02de2 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/siteAdd.js @@ -0,0 +1,207 @@ +var $url = '/pages/settings/siteAdd'; + +var $data = { + pageLoad: false, + pageAlert: null, + pageType: utils.getQueryString('type') || 'selectType', + + siteTemplates: null, + isRootExists: null, + siteList: null, + tableNameList: null, + + page: parseInt(utils.getQueryString('page') || 1), + word: utils.getQueryString('word'), + tag: utils.getQueryString('tag'), + price: utils.getQueryString('price'), + order: utils.getQueryString('order'), + templateInfoList: null, + count: null, + pages: null, + allTagNames: [], + + createType: utils.getQueryString('createType'), + createTemplateId: utils.getQueryString('createTemplateId'), + siteName: '', + isRoot: false, + parentId: 0, + siteDir: '', + tableRule: 'Choose', + tableChoose: '', + tableHandWrite: '', + isImportContents: true, + isImportTableStyles: true +}; + +var $methods = { + getConfig: function () { + var $this = this; + + $api.get($url).then(function (response) { + var res = response.data; + + $this.siteTemplates = res.value; + $this.isRootExists = res.isRootExists; + $this.siteList = res.siteList; + $this.tableNameList = res.tableNameList; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + if ($this.pageType == 'selectCloud') { + $this.load(); + } + }); + }, + + getDisplayUrl: function (templateId) { + return ssUtils.getTemplatePageUrl(templateId); + }, + + getTemplateUrl: function (relatedUrl) { + return ssUtils.getTemplatesUrl(relatedUrl); + }, + + getPreviewUrl: function (templateId) { + return ssUtils.getDemoUrl(templateId); + }, + + getPageUrl: function (page) { + if (page < 1 || page > this.pages || page == this.page) return 'javascript:;'; + return this.getUrl(page, this.word, this.tag, this.price, this.order); + }, + + getTagUrl: function (tag) { + return this.getUrl(this.page, this.word, tag, this.price, this.order); + }, + + getPriceUrl: function (price) { + return this.getUrl(this.page, this.word, this.tag, price, this.order); + }, + + getOrderUrl: function (order) { + return this.getUrl(this.page, this.word, this.tag, this.price, order); + }, + + getUrl: function (page, word, tag, price, order) { + var url = '?type=selectCloud&page=' + page; + if (word) { + url += '&word=' + word; + } + if (tag) { + url += '&tag=' + tag; + } + if (price) { + url += '&price=' + (price); + } + if (order) { + url += '&order=' + (order); + } + return url; + }, + + priceChanged: function () { + this.load(); + }, + + orderChanged: function () { + this.load(); + }, + + load: function () { + var $this = this; + + if (this.pageLoad) { + utils.loading(true); + } + $ssApi.get(ssUrlTemplates, { + params: { + page: this.page, + word: this.word, + tag: this.tag, + price: this.price, + order: this.order + } + }) + .then(function (response) { + var res = response.data; + + $this.templateInfoList = res.value; + $this.count = res.count; + $this.pages = res.pages; + $this.allTagNames = res.allTagNames; + }) + .catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }) + .then(function () { + utils.loading(false); + this.pageLoad = true; + }); + }, + + getCreateType: function () { + if (this.createType == 'cloud') { + return '使用在线站点模板创建站点,站点模板:' + this.createTemplateId + ''; + } else if (this.createType == 'local') { + return '使用本地站点模板创建站点,站点模板:' + this.createTemplateId; + } else { + return '创建空站点(不使用站点模板)'; + } + }, + + btnLocalClick: function () { + this.pageType = 'selectLocal'; + this.createType = 'local'; + }, + + btnCloudClick: function () { + this.pageType = 'selectCloud'; + this.createType = 'cloud'; + this.load(); + }, + + btnCreateClick: function (createType, templateId) { + this.createType = createType; + this.createTemplateId = templateId; + this.pageType = 'create'; + }, + + btnSubmitClick: function () { + var $this = this; + + this.$validator.validate().then(function (result) { + if (result) { + utils.loading(true); + $api.post($url, { + createType: $this.createType, + createTemplateId: $this.createTemplateId, + siteName: $this.siteName, + isRoot: $this.isRoot, + parentId: $this.parentId, + siteDir: $this.siteDir, + tableRule: $this.tableRule, + tableChoose: $this.tableChoose, + tableHandWrite: $this.tableHandWrite, + isImportContents: $this.isImportContents, + isImportTableStyles: $this.isImportTableStyles + }).then(function (response) { + var res = response.data; + location.href = res.value; + }).catch(function (error) { + utils.loading(false); + $this.pageAlert = utils.getPageAlert(error); + }); + } + }); + } +}; + +var $vue = new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.getConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/siteTables.cshtml b/net452/SiteServer.Web/SiteServer/Settings/siteTables.cshtml new file mode 100644 index 000000000..996e425e5 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/siteTables.cshtml @@ -0,0 +1,83 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/siteTables.js b/net452/SiteServer.Web/SiteServer/Settings/siteTables.js new file mode 100644 index 000000000..72cdcf93c --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/siteTables.js @@ -0,0 +1,90 @@ +var $url = '/pages/settings/siteTables'; +var $urlGetColumns = '/pages/settings/siteTables/actions/getColumns'; +var $urlRemoveCache = '/pages/settings/siteTables/actions/removeCache'; + +var $data = { + pageLoad: false, + pageAlert: null, + pageType: null, + tableNames: null, + nameDict: null, + tableName: null, + columns: null, + count: null +}; + +var $methods = { + getTables: function () { + var $this = this; + + $api.get($url).then(function (response) { + var res = response.data; + + $this.tableNames = res.value; + $this.nameDict = res.nameDict; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + btnColumnsClick: function (tableName) { + var $this = this; + + utils.loading(true); + $api.post($urlGetColumns, { + tableName: tableName + }).then(function (response) { + var res = response.data; + + $this.pageType = 'columns'; + $this.tableName = tableName; + $this.columns = res.value; + $this.count = res.count; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + btnCancelClick: function () { + this.pageType = 'tables'; + this.tableName = null; + this.pageAlert = null; + }, + + btnRemoveCacheClick: function () { + var $this = this; + + utils.loading(true); + $api.post($urlRemoveCache, { + tableName: $this.tableName + }).then(function (response) { + var res = response.data; + + $this.pageType = 'columns'; + $this.columns = res.value; + $this.count = res.count; + utils.loading(false); + $this.pageAlert = { + type: 'success', + html: '内容表缓存清除成功!' + }; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.getTables(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/siteTemplateOnline.cshtml b/net452/SiteServer.Web/SiteServer/Settings/siteTemplateOnline.cshtml new file mode 100644 index 000000000..abeef160a --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/siteTemplateOnline.cshtml @@ -0,0 +1,114 @@ +@{ Layout = "../Shared/_Layout.cshtml"; }
      + +
      + +
      +
      +
      + + 搜索 +
      +
      + +
      +
      + +
      +
      +
      价格: +
      +
      排序: +
      +
      +
      +
      +
      +
      +
      +
      +
      + + + +

      {{ templateInfo.templateId }}

      +
      +

      + {{ templateInfo.description }} +

      + +
      +
      +
      +
      +
      + +
      @section Scripts{ + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/siteTemplateOnline.js b/net452/SiteServer.Web/SiteServer/Settings/siteTemplateOnline.js new file mode 100644 index 000000000..b57fa0d67 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/siteTemplateOnline.js @@ -0,0 +1,107 @@ +var $data = { + pageLoad: false, + pageAlert: null, + page: parseInt(utils.getQueryString('page') || 1), + word: utils.getQueryString('word'), + tag: utils.getQueryString('tag'), + price: utils.getQueryString('price'), + order: utils.getQueryString('order'), + + templateInfoList: null, + count: null, + pages: null, + allTagNames: [] +}; + +var $methods = { + getDisplayUrl: function (templateId) { + return ssUtils.getTemplatePageUrl(templateId); + }, + + getTemplateUrl: function (relatedUrl) { + return ssUtils.getTemplatesUrl(relatedUrl); + }, + + getPreviewUrl: function (templateId) { + return ssUtils.getDemoUrl(templateId); + }, + + getPageUrl: function (page) { + if (page < 1 || page > this.pages || page == this.page) return 'javascript:;'; + return this.getUrl(page, this.word, this.tag, this.price, this.order); + }, + + getTagUrl: function (tag) { + return this.getUrl(this.page, this.word, tag, this.price, this.order); + }, + + getPriceUrl: function (price) { + return this.getUrl(this.page, this.word, this.tag, price, this.order); + }, + + getOrderUrl: function (order) { + return this.getUrl(this.page, this.word, this.tag, this.price, order); + }, + + getUrl: function (page, word, tag, price, order) { + var url = '?page=' + page; + if (word) { + url += '&word=' + word; + } + if (tag) { + url += '&tag=' + tag; + } + if (price) { + url += '&price=' + (price); + } + if (order) { + url += '&order=' + (order); + } + return url; + }, + + priceChanged: function () { + this.load(); + }, + + orderChanged: function () { + this.load(); + }, + + load: function () { + var $this = this; + + $ssApi.get($ssUrlTemplates, { + params: { + page: this.page, + word: this.word, + tag: this.tag, + price: this.price, + order: this.order + } + }) + .then(function (response) { + var res = response.data; + + $this.templateInfoList = res.value; + $this.count = res.count; + $this.pages = res.pages; + $this.allTagNames = res.allTagNames; + }) + .catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }) + .then(function () { + $this.pageLoad = true; + }); + } +}; + +var $vue = new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.load(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/userConfig.cshtml b/net452/SiteServer.Web/SiteServer/Settings/userConfig.cshtml new file mode 100644 index 000000000..1e15ed641 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/userConfig.cshtml @@ -0,0 +1,201 @@ +@{ Layout = "../Shared/_Layout.cshtml"; }
      + +
      + + + +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/userConfig.js b/net452/SiteServer.Web/SiteServer/Settings/userConfig.js new file mode 100644 index 000000000..5412317f1 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/userConfig.js @@ -0,0 +1,105 @@ +var $url = '/pages/settings/userConfig'; + +var $data = { + pageLoad: false, + pageAlert: null, + pageType: null, + config: null, + isUserRegistrationAllowed: null, + isUserRegistrationChecked: null, + isUserUnRegistrationAllowed: null, + userPasswordMinLength: null, + userPasswordRestriction: null, + userRegistrationMinMinutes: null, + isUserLockLogin: null, + userLockLoginCount: null, + userLockLoginType: null, + userLockLoginHours: null, + userFindPasswordSmsTplId: null +}; + +var $methods = { + getConfig: function () { + var $this = this; + + $api.get($url).then(function (response) { + var res = response.data; + + $this.config = _.clone(res.value); + + $this.isUserRegistrationAllowed = res.value.isUserRegistrationAllowed; + $this.isUserRegistrationChecked = res.value.isUserRegistrationChecked; + $this.isUserUnRegistrationAllowed = res.value.isUserUnRegistrationAllowed; + $this.userPasswordMinLength = res.value.userPasswordMinLength; + $this.userPasswordRestriction = res.value.userPasswordRestriction; + $this.userRegistrationMinMinutes = res.value.userRegistrationMinMinutes; + $this.isUserLockLogin = res.value.isUserLockLogin; + $this.userLockLoginCount = res.value.userLockLoginCount; + $this.userLockLoginType = res.value.userLockLoginType; + $this.userLockLoginHours = res.value.userLockLoginHours; + $this.userFindPasswordSmsTplId = res.value.userFindPasswordSmsTplId; + + $this.pageType = 'list'; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + submit: function (item) { + var $this = this; + + utils.loading(true); + $api.post($url, { + isUserRegistrationAllowed: $this.isUserRegistrationAllowed, + isUserRegistrationChecked: $this.isUserRegistrationChecked, + isUserUnRegistrationAllowed: $this.isUserUnRegistrationAllowed, + userPasswordMinLength: $this.userPasswordMinLength, + userPasswordRestriction: $this.userPasswordRestriction, + userRegistrationMinMinutes: $this.userRegistrationMinMinutes, + isUserLockLogin: $this.isUserLockLogin, + userLockLoginCount: $this.userLockLoginCount, + userLockLoginType: $this.userLockLoginType, + userLockLoginHours: $this.userLockLoginHours, + userFindPasswordSmsTplId: $this.userFindPasswordSmsTplId + }).then(function (response) { + var res = response.data; + + $this.pageAlert = { + type: 'success', + html: '用户设置保存成功!' + }; + $this.config = _.clone(res.value); + $this.pageType = 'list'; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + getPasswordRestrictionText: function (val) { + if (val === 'LetterAndDigit') return '字母和数字组合'; + else if (val === 'LetterAndDigitAndSymbol') return '字母、数字以及符号组合'; + else return '不限制'; + }, + + btnSubmitClick: function () { + var $this = this; + this.$validator.validate().then(function (result) { + if (result) { + $this.submit($this.item); + } + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.getConfig(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/userGroup.cshtml b/net452/SiteServer.Web/SiteServer/Settings/userGroup.cshtml new file mode 100644 index 000000000..1f48cf975 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/userGroup.cshtml @@ -0,0 +1,79 @@ +@{ Layout = "../Shared/_Layout.cshtml"; }
      + +
      + + + +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/userGroup.js b/net452/SiteServer.Web/SiteServer/Settings/userGroup.js new file mode 100644 index 000000000..14259b488 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/userGroup.js @@ -0,0 +1,124 @@ +var $url = '/pages/settings/userGroup'; + +var $data = { + pageLoad: false, + pageAlert: null, + pageType: 'list', + items: null, + adminNames: null, +}; + +var $methods = { + getList: function () { + var $this = this; + + $api.get($url).then(function (response) { + var res = response.data; + + $this.items = res.value; + $this.adminNames = res.adminNames; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + delete: function (id) { + var $this = this; + + utils.loading(true); + $api.delete($url, { + params: { + id: id + } + }).then(function (response) { + var res = response.data; + + $this.items = res.value; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + submit: function (item) { + var $this = this; + + utils.loading(true); + $api.post($url, item).then(function (response) { + var res = response.data; + + $this.pageAlert = { + type: 'success', + html: item.id === -1 ? '用户组添加成功!' : '用户组修改成功!' + }; + $this.item = null; + $this.items = res.value; + $this.pageType = 'list'; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + btnEditClick: function (item) { + this.pageAlert = null; + this.pageType = 'add'; + this.item = item; + }, + + btnAddClick: function () { + this.pageAlert = null; + this.pageType = 'add'; + this.item = { + id: -1, + groupName: '', + adminName: '' + }; + }, + + btnDeleteClick: function (item) { + var $this = this; + + swal2({ + title: '删除用户组', + text: '此操作将删除用户组 ' + item.groupName + ',确定吗?', + type: 'question', + confirmButtonText: '删 除', + confirmButtonClass: 'btn btn-danger', + showCancelButton: true, + cancelButtonText: '取 消' + }) + .then(function (result) { + if (result.value) { + $this.delete(item.id); + } + }); + }, + + btnSubmitClick: function () { + var $this = this; + this.$validator.validate().then(function (result) { + if (result) { + $this.submit($this.item); + } + }); + }, + + btnCancelClick: function () { + this.pageAlert = null; + this.pageType = 'list'; + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.getList(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/userHome.cshtml b/net452/SiteServer.Web/SiteServer/Settings/userHome.cshtml new file mode 100644 index 000000000..44ea320e1 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/userHome.cshtml @@ -0,0 +1,231 @@ +@{ Layout = "../Shared/_Layout.cshtml"; }
      + +
      + + + +
      @section Scripts{ + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/userHome.js b/net452/SiteServer.Web/SiteServer/Settings/userHome.js new file mode 100644 index 000000000..3cf00356f --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/userHome.js @@ -0,0 +1,168 @@ +var $url = '/pages/settings/userHome'; + +var $data = { + pageLoad: false, + pageAlert: null, + pageType: null, + config: null, + files: [], + uploadLogoUrl: null, + homeDirectory: null, + isHomeClosed: null, + homeTitle: null, + isHomeLogo: null, + homeLogoUrl: null, + isHomeBackground: null, + homeBackgroundUrl: null, + homeDefaultAvatarUrl: null, + userRegistrationAttributes: [], + isUserRegistrationGroup: null, + isHomeAgreement: null, + homeAgreementHtml: null, + styles: null, +}; + +var $methods = { + apiSubmit: function () { + var $this = this; + + utils.loading(true); + $api.post($url, { + isHomeClosed: $this.isHomeClosed, + homeTitle: $this.homeTitle, + isHomeLogo: $this.isHomeLogo, + homeLogoUrl: $this.homeLogoUrl, + isHomeBackground: $this.isHomeBackground, + homeBackgroundUrl: $this.homeBackgroundUrl, + homeDefaultAvatarUrl: $this.homeDefaultAvatarUrl, + userRegistrationAttributes: $this.userRegistrationAttributes.join(','), + isUserRegistrationGroup: $this.isUserRegistrationGroup, + isHomeAgreement: $this.isHomeAgreement, + homeAgreementHtml: $this.homeAgreementHtml + }).then(function (response) { + var res = response.data; + + swal({ + toast: true, + type: 'success', + title: "设置保存成功!", + showConfirmButton: false, + timer: 1500 + }).then(function () { + $this.config = _.clone(res.value); + $this.pageType = 'list'; + }); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + apiGet: function () { + var $this = this; + + $api.get($url).then(function (response) { + var res = response.data; + + $this.config = _.clone(res.value); + $this.homeDirectory = res.homeDirectory; + + $this.isHomeClosed = res.value.isHomeClosed; + $this.homeTitle = res.value.homeTitle; + $this.isHomeLogo = res.value.isHomeLogo; + $this.homeLogoUrl = res.value.homeLogoUrl; + $this.isHomeBackground = res.value.isHomeBackground; + $this.homeBackgroundUrl = res.value.homeBackgroundUrl; + $this.homeDefaultAvatarUrl = res.value.homeDefaultAvatarUrl; + if (res.value.userRegistrationAttributes) { + $this.userRegistrationAttributes = res.value.userRegistrationAttributes.split(','); + } + $this.isUserRegistrationGroup = res.value.isUserRegistrationGroup; + $this.isHomeAgreement = res.value.isHomeAgreement; + $this.homeAgreementHtml = res.value.homeAgreementHtml; + $this.uploadUrl = $apiUrl + '/pages/settings/userHome/upload?adminToken=' + res.adminToken; + $this.styles = res.styles; + }).catch(function (error) { + this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageType = 'list'; + $this.pageLoad = true; + }); + }, + + inputLogo(newFile, oldFile) { + if (Boolean(newFile) !== Boolean(oldFile) || oldFile.error !== newFile.error) { + if (!this.$refs.logo.active) { + this.$refs.logo.active = true + } + } + + if (newFile && oldFile && newFile.xhr && newFile.success !== oldFile.success) { + this.homeLogoUrl = newFile.response.value; + } + }, + + inputBackground(newFile, oldFile) { + if (Boolean(newFile) !== Boolean(oldFile) || oldFile.error !== newFile.error) { + if (!this.$refs.background.active) { + this.$refs.background.active = true + } + } + + if (newFile && oldFile && newFile.xhr && newFile.success !== oldFile.success) { + this.homeBackgroundUrl = newFile.response.value; + } + }, + + inputAvatar(newFile, oldFile) { + if (Boolean(newFile) !== Boolean(oldFile) || oldFile.error !== newFile.error) { + if (!this.$refs.avatar.active) { + this.$refs.avatar.active = true + } + } + + if (newFile && oldFile && newFile.xhr && newFile.success !== oldFile.success) { + this.homeDefaultAvatarUrl = newFile.response.value; + } + }, + + getUserRegistrationAttributes: function () { + var str = '用户名, 密码'; + for (var i = 0; i < this.userRegistrationAttributes.length; i++) { + var attributeName = this.userRegistrationAttributes[i]; + var style = _.find(this.styles, function (x) { + return x.attributeName === attributeName + }); + if (style) { + str += ", " + style.displayName; + } + } + return str; + }, + + getUserRegistrationAttribute: function (val) { + return val; + }, + + btnSubmitClick: function () { + var $this = this; + this.$validator.validate().then(function (result) { + if (result) { + $this.apiSubmit(); + } + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + components: { + FileUpload: VueUploadComponent + }, + methods: $methods, + created: function () { + this.apiGet(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/userMenu.cshtml b/net452/SiteServer.Web/SiteServer/Settings/userMenu.cshtml new file mode 100644 index 000000000..22d3d087b --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/userMenu.cshtml @@ -0,0 +1,155 @@ +@{ Layout = "../Shared/_Layout.cshtml"; }
      + +
      + + + +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/userMenu.js b/net452/SiteServer.Web/SiteServer/Settings/userMenu.js new file mode 100644 index 000000000..e40f1a499 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/userMenu.js @@ -0,0 +1,230 @@ +var $url = '/pages/settings/userMenu'; +var $urlReset = '/pages/settings/userMenu/actions/reset'; + +var $data = { + pageLoad: false, + pageAlert: null, + pageType: 'list', + items: null, + groups: null, + item: null +}; + +var $methods = { + getItems: function (menus) { + var items = []; + for (var i = 0; i < menus.length; i++) { + var menu = menus[i]; + menu.isGroup = false; + menu.groupIds = []; + if (menu.groupIdCollection) { + menu.isGroup = true; + menu.groupIds = menu.groupIdCollection.split(','); + } + if (menu.parentId === 0) { + menu.children = []; + items.push(menu); + } + } + for (var i = 0; i < menus.length; i++) { + var menu = menus[i]; + if (menu.parentId > 0) { + var parent = _.find(items, function (x) { + return x.id === menu.parentId + }) + if (parent) { + parent.children.push(menu); + } + } + } + + return items; + }, + + getList: function () { + var $this = this; + + $api.get($url).then(function (response) { + var res = response.data; + + $this.items = $this.getItems(res.value); + $this.groups = res.groups; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + getUserGroups: function (item) { + if (item.isGroup) { + var str = ''; + _.forEach(this.groups, function (group) { + if (item.groupIds.indexOf(group.id + '') !== -1) { + str += ', ' + group.groupName; + } + }); + return str ? str.substr(2) : ''; + } + return '所有用户组'; + }, + + delete: function (id) { + var $this = this; + + utils.loading(true); + $api.delete($url, { + params: { + id: id + } + }).then(function (response) { + var res = response.data; + + $this.items = $this.getItems(res.value); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + reset: function () { + var $this = this; + + utils.loading(true); + $api.post($urlReset).then(function (response) { + var res = response.data; + + $this.items = $this.getItems(res.value); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + submit: function (item) { + var $this = this; + item.groupIdCollection = item.isGroup ? item.groupIds.join(',') : ''; + utils.loading(true); + $api.post($url, item).then(function (response) { + var res = response.data; + + $this.pageAlert = { + type: 'success', + html: item.id === -1 ? '用户菜单添加成功!' : '用户菜单修改成功!' + }; + $this.item = null; + $this.items = $this.getItems(res.value); + $this.pageType = 'list'; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + btnAddClick: function (parentId) { + var taxis = 0; + var parent = null; + if (parentId > 0) { + parent = this.items.find(function (x) { + return x.id === parentId; + }) + } + if (parent) { + _.forEach(parent.children, function (value) { + if (value.taxis > taxis) { + taxis = value.taxis; + } + }); + } else { + _.forEach(this.items, function (value) { + if (value.taxis > taxis) { + taxis = value.taxis; + } + }); + } + + this.item = { + id: 0, + systemId: '', + groupIdCollection: '', + isDisabled: false, + parentId: parentId, + taxis: taxis + 1, + text: '', + href: '', + iconClass: '', + target: '', + isGroup: false, + groupIds: [] + }; + this.pageType = 'add'; + }, + + btnResetClick: function () { + var $this = this; + + swal2({ + title: '重置用户菜单', + text: '此操作将把用户菜单恢复为系统默认值,确定吗?', + type: 'question', + showCancelButton: true, + confirmButtonClass: 'btn btn-danger', + cancelButtonText: '取 消', + confirmButtonText: '确认重置' + }) + .then(function (result) { + if (result.value) { + $this.reset(); + } + }); + }, + + btnEditClick: function (item) { + this.pageType = 'add'; + this.item = item; + }, + + btnDeleteClick: function (item) { + var $this = this; + + swal2({ + title: '删除用户菜单', + text: '此操作将删除用户菜单 ' + item.text + ',确定吗?', + type: 'question', + confirmButtonText: '删 除', + confirmButtonClass: 'btn btn-danger', + showCancelButton: true, + cancelButtonText: '取 消' + }) + .then(function (result) { + if (result.value) { + $this.delete(item.id); + } + }); + }, + + btnSubmitClick: function () { + var $this = this; + this.$validator.validate().then(function (result) { + if (result) { + $this.submit($this.item); + } + }); + }, + + btnCancelClick: function () { + this.pageType = 'list'; + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.getList(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/userStyle.cshtml b/net452/SiteServer.Web/SiteServer/Settings/userStyle.cshtml new file mode 100644 index 000000000..fc074e400 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/userStyle.cshtml @@ -0,0 +1,66 @@ +@{ Layout = "../Shared/_Layout.cshtml"; }
      + +
      + +
      + + + + + + + + + + + + + + + + + + + + + +
      排序字段名 显示名称 提交类型验证规则操作
      {{ item.taxis }} {{ item.attributeName }} {{ item.displayName }} {{ item.inputType }} + {{ item.validate || '无验证' }} + + 编辑 + 删除 +
      +
      +
      + + 新增字段 + +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Settings/userStyle.js b/net452/SiteServer.Web/SiteServer/Settings/userStyle.js new file mode 100644 index 000000000..f9d2d4c23 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Settings/userStyle.js @@ -0,0 +1,96 @@ +var $url = '/pages/settings/userStyle'; + +var $data = { + pageLoad: false, + pageAlert: null, + pageType: null, + items: null, + tableName: null, + relatedIdentities: null +}; + +var $methods = { + getList: function () { + var $this = this; + + $api.get($url).then(function (response) { + var res = response.data; + + $this.items = res.value; + $this.tableName = res.tableName; + $this.relatedIdentities = res.relatedIdentities; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + delete: function (attributeName) { + var $this = this; + + utils.loading(true); + $api.delete($url, { + params: { + attributeName: attributeName + } + }).then(function (response) { + var res = response.data; + + $this.items = res.value; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + }, + + btnEditClick: function (attributeName) { + utils.openLayer({ + title: '编辑字段', + url: '../Shared/tableStyle.cshtml?tableName=' + this.tableName + '&relatedIdentities=' + this.relatedIdentities + '&attributeName=' + attributeName + }); + }, + + btnValidateClick: function (attributeName) { + utils.openLayer({ + title: '设置验证规则', + url: '../Shared/tableValidate.cshtml?tableName=' + this.tableName + '&relatedIdentities=' + this.relatedIdentities + '&attributeName=' + attributeName + }); + }, + + btnAddClick: function () { + utils.openLayer({ + title: '新增字段', + url: '../Shared/tableStyle.cshtml?tableName=' + this.tableName + '&relatedIdentities=' + this.relatedIdentities + }); + }, + + btnDeleteClick: function (attributeName) { + var $this = this; + + swal2({ + title: '删除字段', + text: '此操作将删除字段 ' + attributeName + ',确定吗?', + type: 'question', + confirmButtonText: '删 除', + confirmButtonClass: 'btn btn-danger', + showCancelButton: true, + cancelButtonText: '取 消' + }) + .then(function (result) { + if (result.value) { + $this.delete(attributeName); + } + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.getList(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Shared/_Layout.cshtml b/net452/SiteServer.Web/SiteServer/Shared/_Layout.cshtml new file mode 100644 index 000000000..1bf8de9d1 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Shared/_Layout.cshtml @@ -0,0 +1,44 @@ +@{ var adminUrl = SiteServer.CMS.Env.AdminUrl; var apiUrl = SiteServer.CMS.Env.ApiUrl; } + + + + + + SiteServer 管理后台 + + + + + + + + @RenderSection("Styles", + false) + + + +
      + + +
      + + + + + + + + + + + + + + @RenderSection("Scripts", false) \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Shared/tableStyle.cshtml b/net452/SiteServer.Web/SiteServer/Shared/tableStyle.cshtml new file mode 100644 index 000000000..9d75183b3 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Shared/tableStyle.cshtml @@ -0,0 +1,142 @@ +@{ Layout = "_Layout.cshtml"; } @section Styles { } +
      +
      + + +
      +
      + + +
      +
      + + +
      +
      +
      +
      + + +
      +
      + + +
      +
      + + +
      +
      + + + +
      +
      + + +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Shared/tableStyle.js b/net452/SiteServer.Web/SiteServer/Shared/tableStyle.js new file mode 100644 index 000000000..a78b6f989 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Shared/tableStyle.js @@ -0,0 +1,94 @@ +var $url = '/pages/shared/tableStyle'; + +var $data = { + tableName: utils.getQueryString('tableName'), + attributeName: utils.getQueryString('attributeName'), + relatedIdentities: utils.getQueryString('relatedIdentities'), + pageLoad: false, + pageAlert: null, + styleInfo: null, + inputTypes: null, + isRapid: null, + rapidValues: null +}; + +var $methods = { + getStyle: function () { + var $this = this; + + $api.get($url, { + params: { + tableName: $this.tableName, + attributeName: $this.attributeName, + relatedIdentities: $this.relatedIdentities + } + }).then(function (response) { + var res = response.data; + + $this.styleInfo = res.value; + $this.inputTypes = res.inputTypes; + $this.isRapid = res.isRapid; + $this.rapidValues = res.rapidValues; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + btnSubmitClick: function () { + var $this = this; + this.$validator.validate().then(function (result) { + if (result) { + utils.loading(true); + $api.post($url, { + tableName: $this.tableName, + attributeName: $this.attributeName, + relatedIdentities: $this.relatedIdentities, + styleInfo: $this.styleInfo + }).then(function (response) { + var res = response.data; + + parent.location.reload(); + utils.closeLayer(); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } + }); + }, + + btnStyleItemRemoveClick: function (index) { + this.styleInfo.styleItems.splice(index, 1); + if (this.styleInfo.styleItems.length === 0) { + this.btnStyleItemAddClick(); + } + }, + + btnStyleItemAddClick: function () { + this.styleInfo.styleItems.push({ + itemTitle: '', + itemValue: '', + isSelected: false + }) + }, + + btnRadioClick: function (index) { + for (var i = 0; i < this.styleInfo.styleItems.length; i++) { + var element = this.styleInfo.styleItems[i]; + element.isSelected = false; + } + this.styleInfo.styleItems[index].isSelected = true; + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.getStyle(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Shared/tableValidate.cshtml b/net452/SiteServer.Web/SiteServer/Shared/tableValidate.cshtml new file mode 100644 index 000000000..d0d986098 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Shared/tableValidate.cshtml @@ -0,0 +1,135 @@ +@{ Layout = "_Layout.cshtml"; } @section Styles { } + + +
      +
      + + +
      @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/Shared/tableValidate.js b/net452/SiteServer.Web/SiteServer/Shared/tableValidate.js new file mode 100644 index 000000000..13454f053 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/Shared/tableValidate.js @@ -0,0 +1,242 @@ +var $url = '/pages/shared/tableValidate'; + +var $data = { + allRules: [{ + type: "required", + text: "字段为必填项" + }, { + type: "numeric", + text: "字段必须仅包含数字" + }, { + type: "email", + text: "字段必须是有效的电子邮件" + }, { + type: "mobile", + text: "字段必须是有效的手机号码" + }, { + type: "url", + text: "字段必须是有效的url" + }, { + type: "alpha", + text: "字段只能包含英文字母", + }, { + type: "alpha_dash", + text: "字段只能包含英文字母、数字、破折号或下划线" + }, { + type: "alpha_num", + text: "字段只能包含英文字母或数字" + }, { + type: "alpha_spaces", + text: "字段只能包含英文字母或空格" + }, { + type: "credit_card", + text: "字段必须是有效的信用卡" + }, { + type: "between", + text: "字段必须有一个以最小值和最大值为界的数值" + }, { + type: "decimal", + text: "字段必须是数字,并且可能包含指定数量的小数点" + }, { + type: "digits", + text: "字段必须是整数,并且具有指定的位数" + }, { + type: "included", + text: "字段必须具有指定列表中的值" + }, { + type: "excluded", + text: "字段不能具有指定列表中的值" + }, { + type: "ip", + text: "字段必须是一个有效的ipv4值的字符串" + }, { + type: "max", + text: "字段不能超过指定的长度" + }, { + type: "max_value", + text: "字段必须是数值,并且不能大于指定的值" + }, { + type: "min", + text: "字段不能低于指定的长度" + }, { + type: "min_value", + text: "字段必须是数值,并且不能小于指定的值" + }, { + type: "regex", + text: "字段必须匹配指定的正则表达式" + }], + tableName: utils.getQueryString('tableName'), + attributeName: utils.getQueryString('attributeName'), + relatedIdentities: utils.getQueryString('relatedIdentities'), + pageLoad: false, + pageAlert: null, + pageType: 'list', + validateRules: [], + ruleType: null, + ruleValue: null, + betweenMin: null, + betweenMax: null, + decimals: null, + digitsLength: null, + includedList: null, + maxLength: null, + maxValue: null, + minLength: null, + minValue: null, + excludedList: null, + regexValue: null +}; + +var $methods = { + getValue() { + if (this.validateRules.length === 0) return ''; + return _.map(this.validateRules, function (rule) { + return rule.value ? rule.type + ':' + rule.value : rule.type; + }).join('|'); + }, + + load: function () { + var $this = this; + + $api.get($url, { + params: { + tableName: $this.tableName, + attributeName: $this.attributeName, + relatedIdentities: $this.relatedIdentities + } + }).then(function (response) { + var res = response.data; + + var val = ''; + try { + if (res.value) { + val = res.value; + for (var i = 0; i < val.split('|').length; i++) { + var element = val.split('|')[i]; + if (element.indexOf(':') === -1) { + $this.validateRules.push({ + type: element, + value: null + }); + } else { + $this.validateRules.push({ + type: element.split(':')[0], + value: element.split(':')[1] + }); + } + } + } + } catch (e) {} + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + btnSubmitClick: function () { + var $this = this; + this.$validator.validate().then(function (result) { + if (result) { + utils.loading(true); + $api.post($url, { + tableName: $this.tableName, + attributeName: $this.attributeName, + relatedIdentities: $this.relatedIdentities, + value: $this.getValue() + }).then(function (response) { + var res = response.data; + + parent.location.reload(); + utils.closeLayer(); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } + }); + }, + + btnRemoveClick: function (index) { + this.validateRules.splice(index, 1); + }, + + btnAddClick: function () { + this.ruleType = null; + this.pageType = 'add'; + }, + + btnSaveClick: function () { + var $this = this; + this.$validator.validate().then(function (result) { + if (result) { + $this.validateRules.push({ + type: $this.ruleType, + value: $this.getRuleValue() + }); + $this.pageType = 'list'; + } + }); + }, + + btnCancelClick: function () { + this.pageType = 'list'; + }, + + getDescription(type) { + var index = _.findIndex(this.allRules, function (o) { + return o.type == type; + }); + return index !== -1 ? this.allRules[index].text : ''; + }, + + getRuleValue() { + if (this.ruleType === 'between') { + return this.betweenMin + ',' + this.betweenMax; + } else if (this.ruleType === 'decimal') { + return this.decimals; + } else if (this.ruleType === 'digits') { + return this.digitsLength; + } else if (this.ruleType === 'included') { + return this.includedList; + } else if (this.ruleType === 'max') { + return this.maxLength; + } else if (this.ruleType === 'max_value') { + return this.maxValue; + } else if (this.ruleType === 'min') { + return this.minLength; + } else if (this.ruleType === 'min_value') { + return this.minValue; + } else if (this.ruleType === 'excluded') { + return this.excludedList; + } else if (this.ruleType === 'regex') { + return this.regexValue; + } + + return ''; + }, + + getAvaliableRules() { + var rules = []; + for (var i = 0; i < this.allRules.length; i++) { + var element = this.allRules[i]; + var index = _.findIndex(this.validateRules, function (o) { + return o.type == element.type; + }); + if (index === -1) { + rules.push(this.allRules[i]) + } + } + return rules; + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.load(); + } +}); \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/assets/ajaxUpload.js b/net452/SiteServer.Web/SiteServer/assets/ajaxUpload.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/ajaxUpload.js rename to net452/SiteServer.Web/SiteServer/assets/ajaxUpload.js diff --git a/SiteServer.Web/SiteServer/assets/application.js b/net452/SiteServer.Web/SiteServer/assets/application.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/application.js rename to net452/SiteServer.Web/SiteServer/assets/application.js diff --git a/SiteServer.Web/SiteServer/assets/bootstrap/css/bootstrap.min.css b/net452/SiteServer.Web/SiteServer/assets/bootstrap/css/bootstrap.min.css similarity index 100% rename from SiteServer.Web/SiteServer/assets/bootstrap/css/bootstrap.min.css rename to net452/SiteServer.Web/SiteServer/assets/bootstrap/css/bootstrap.min.css diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/LICENSE b/net452/SiteServer.Web/SiteServer/assets/codeMirror/LICENSE similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/LICENSE rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/LICENSE diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/css/csscolors.css b/net452/SiteServer.Web/SiteServer/assets/codeMirror/css/csscolors.css similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/css/csscolors.css rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/css/csscolors.css diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/css/jscolors.css b/net452/SiteServer.Web/SiteServer/assets/codeMirror/css/jscolors.css similarity index 85% rename from SiteServer.Web/SiteServer/assets/codeMirror/css/jscolors.css rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/css/jscolors.css index ff753ddbe..3a9bfb7c7 100644 --- a/SiteServer.Web/SiteServer/assets/codeMirror/css/jscolors.css +++ b/net452/SiteServer.Web/SiteServer/assets/codeMirror/css/jscolors.css @@ -1,8 +1,8 @@ .editbox { - margin:0 0.4em; + margin:0.4em; padding: 0; - font-size: 12px; - font-family:Consolas,"Courier New",monospace; + font-size: 12px; + font-family:Consolas,"Courier New",monospace; line-height:16px; color: black; } diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/css/sparqlcolors.css b/net452/SiteServer.Web/SiteServer/assets/codeMirror/css/sparqlcolors.css similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/css/sparqlcolors.css rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/css/sparqlcolors.css diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/css/xmlcolors.css b/net452/SiteServer.Web/SiteServer/assets/codeMirror/css/xmlcolors.css similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/css/xmlcolors.css rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/css/xmlcolors.css diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/codemirror.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/codemirror.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/codemirror.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/codemirror.js diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/editor.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/editor.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/editor.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/editor.js diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/highlight.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/highlight.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/highlight.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/highlight.js diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/mirrorframe.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/mirrorframe.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/mirrorframe.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/mirrorframe.js diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/parsecss.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/parsecss.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/parsecss.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/parsecss.js diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/parsedummy.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/parsedummy.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/parsedummy.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/parsedummy.js diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/parsehtmlmixed.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/parsehtmlmixed.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/parsehtmlmixed.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/parsehtmlmixed.js diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/parsejavascript.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/parsejavascript.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/parsejavascript.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/parsejavascript.js diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/parsesparql.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/parsesparql.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/parsesparql.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/parsesparql.js diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/parsexml.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/parsexml.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/parsexml.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/parsexml.js diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/select.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/select.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/select.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/select.js diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/stringstream.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/stringstream.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/stringstream.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/stringstream.js diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/tokenize.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/tokenize.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/tokenize.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/tokenize.js diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/tokenizejavascript.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/tokenizejavascript.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/tokenizejavascript.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/tokenizejavascript.js diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/undo.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/undo.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/undo.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/undo.js diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/unittests.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/unittests.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/unittests.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/unittests.js diff --git a/SiteServer.Web/SiteServer/assets/codeMirror/js/util.js b/net452/SiteServer.Web/SiteServer/assets/codeMirror/js/util.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/codeMirror/js/util.js rename to net452/SiteServer.Web/SiteServer/assets/codeMirror/js/util.js diff --git a/net452/SiteServer.Web/SiteServer/assets/css/bootstrap-4.0.0.min.css b/net452/SiteServer.Web/SiteServer/assets/css/bootstrap-4.0.0.min.css new file mode 100644 index 000000000..6561b6f4c --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/css/bootstrap-4.0.0.min.css @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.0.0 (https://getbootstrap.com) + * Copyright 2011-2018 The Bootstrap Authors + * Copyright 2011-2018 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.2;color:inherit}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014 \00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-sm-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-sm-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-sm-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-sm-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-sm-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-sm-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-sm-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-sm-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-sm-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-sm-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-sm-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-sm-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-sm-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-sm-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-md-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-md-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-md-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-md-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-md-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-md-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-md-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-md-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-md-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-md-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-md-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-md-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-md-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-md-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-lg-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-lg-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-lg-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-lg-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-lg-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-lg-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-lg-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-lg-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-lg-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-lg-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-lg-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-lg-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-lg-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-lg-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-webkit-box-flex:0;-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-webkit-box-flex:0;-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-webkit-box-flex:0;-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-webkit-box-flex:0;-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-webkit-box-flex:0;-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-webkit-box-flex:0;-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-webkit-box-flex:0;-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-webkit-box-flex:0;-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-webkit-box-flex:0;-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-webkit-box-flex:0;-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-webkit-box-flex:0;-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-webkit-box-flex:0;-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-webkit-box-ordinal-group:0;-ms-flex-order:-1;order:-1}.order-xl-last{-webkit-box-ordinal-group:14;-ms-flex-order:13;order:13}.order-xl-0{-webkit-box-ordinal-group:1;-ms-flex-order:0;order:0}.order-xl-1{-webkit-box-ordinal-group:2;-ms-flex-order:1;order:1}.order-xl-2{-webkit-box-ordinal-group:3;-ms-flex-order:2;order:2}.order-xl-3{-webkit-box-ordinal-group:4;-ms-flex-order:3;order:3}.order-xl-4{-webkit-box-ordinal-group:5;-ms-flex-order:4;order:4}.order-xl-5{-webkit-box-ordinal-group:6;-ms-flex-order:5;order:5}.order-xl-6{-webkit-box-ordinal-group:7;-ms-flex-order:6;order:6}.order-xl-7{-webkit-box-ordinal-group:8;-ms-flex-order:7;order:7}.order-xl-8{-webkit-box-ordinal-group:9;-ms-flex-order:8;order:8}.order-xl-9{-webkit-box-ordinal-group:10;-ms-flex-order:9;order:9}.order-xl-10{-webkit-box-ordinal-group:11;-ms-flex-order:10;order:10}.order-xl-11{-webkit-box-ordinal-group:12;-ms-flex-order:11;order:11}.order-xl-12{-webkit-box-ordinal-group:13;-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;max-width:100%;margin-bottom:1rem;background-color:transparent}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:not([size]):not([multiple]){height:calc(2.25rem + 2px)}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm,.input-group-lg>.form-control-plaintext.form-control,.input-group-lg>.input-group-append>.form-control-plaintext.btn,.input-group-lg>.input-group-append>.form-control-plaintext.input-group-text,.input-group-lg>.input-group-prepend>.form-control-plaintext.btn,.input-group-lg>.input-group-prepend>.form-control-plaintext.input-group-text,.input-group-sm>.form-control-plaintext.form-control,.input-group-sm>.input-group-append>.form-control-plaintext.btn,.input-group-sm>.input-group-append>.form-control-plaintext.input-group-text,.input-group-sm>.input-group-prepend>.form-control-plaintext.btn,.input-group-sm>.input-group-prepend>.form-control-plaintext.input-group-text{padding-right:0;padding-left:0}.form-control-sm,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-sm>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-sm>select.form-control:not([size]):not([multiple]),select.form-control-sm:not([size]):not([multiple]){height:calc(1.8125rem + 2px)}.form-control-lg,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-lg>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-lg>select.form-control:not([size]):not([multiple]),select.form-control-lg:not([size]):not([multiple]){height:calc(2.875rem + 2px)}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(40,167,69,.8);border-radius:.2rem}.custom-select.is-valid,.form-control.is-valid,.was-validated .custom-select:valid,.was-validated .form-control:valid{border-color:#28a745}.custom-select.is-valid:focus,.form-control.is-valid:focus,.was-validated .custom-select:valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{background-color:#71dd8a}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(40,167,69,.25)}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label::before,.was-validated .custom-file-input:valid~.custom-file-label::before{border-color:inherit}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(220,53,69,.8);border-radius:.2rem}.custom-select.is-invalid,.form-control.is-invalid,.was-validated .custom-select:invalid,.was-validated .form-control:invalid{border-color:#dc3545}.custom-select.is-invalid:focus,.form-control.is-invalid:focus,.was-validated .custom-select:invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{background-color:#efa2a9}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(220,53,69,.25)}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label::before,.was-validated .custom-file-input:invalid~.custom-file-label::before{border-color:inherit}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .input-group{width:auto}.form-inline .form-check{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}.btn:focus,.btn:hover{text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}.btn:not(:disabled):not(.disabled).active,.btn:not(:disabled):not(.disabled):active{background-image:none}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-primary{color:#007bff;background-color:transparent;background-image:none;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;background-color:transparent;background-image:none;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;background-color:transparent;background-image:none;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;background-color:transparent;background-image:none;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;background-color:transparent;background-image:none;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;background-color:transparent;background-image:none;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;background-color:transparent;background-image:none;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;background-color:transparent;background-image:none;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;background-color:transparent}.btn-link:hover{color:#0056b3;text-decoration:underline;background-color:transparent;border-color:transparent}.btn-link.focus,.btn-link:focus{text-decoration:underline;border-color:transparent;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{opacity:0;transition:opacity .15s linear}.fade.show{opacity:1}.collapse{display:none}.collapse.show{display:block}tr.collapse.show{display:table-row}tbody.collapse.show{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}.dropdown,.dropup{position:relative}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropup .dropdown-menu{margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;width:0;height:0;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.btn-group,.btn-group-vertical{position:relative;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after{margin-left:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.btn-group-vertical .btn,.btn-group-vertical .btn-group{width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control{position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file:focus,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control{margin-left:-1px}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::before{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label,.input-group>.custom-file:not(:first-child) .custom-file-label::before{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-webkit-box;display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:active~.custom-control-label::before{color:#fff;background-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{margin-bottom:0}.custom-control-label::before{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;pointer-events:none;content:"";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#dee2e6}.custom-control-label::after{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;content:"";background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center;background-size:8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:inset 0 1px 2px rgba(0,0,0,.075),0 0 5px rgba(128,189,255,.5)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{opacity:0}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:125%}.custom-file{position:relative;display:inline-block;width:100%;height:calc(2.25rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(2.25rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-control{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:focus~.custom-file-control::before{border-color:#80bdff}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(2.25rem + 2px);padding:.375rem .75rem;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(calc(2.25rem + 2px) - 1px * 2);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:1px solid #ced4da;border-radius:0 .25rem .25rem 0}.nav{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-webkit-box-flex:1;-ms-flex-positive:1;flex-grow:1;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler:not(:disabled):not(.disabled){cursor:pointer}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}.navbar-expand-sm .dropup .dropdown-menu{top:auto;bottom:100%}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}.navbar-expand-md .dropup .dropdown-menu{top:auto;bottom:100%}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}.navbar-expand-lg .dropup .dropdown-menu{top:auto;bottom:100%}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}.navbar-expand-xl .dropup .dropdown-menu{top:auto;bottom:100%}}.navbar-expand{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row nowrap;flex-flow:row nowrap;-webkit-box-pack:start;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .dropdown-menu-right{right:0;left:auto}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-expand .dropup .dropdown-menu{top:auto;bottom:100%}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-webkit-box-flex:1;-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-header,.card-group>.card:first-child .card-img-top{border-top-right-radius:0}.card-group>.card:first-child .card-footer,.card-group>.card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-header,.card-group>.card:last-child .card-img-top{border-top-left-radius:0}.card-group>.card:last-child .card-footer,.card-group>.card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:.25rem}.card-group>.card:only-child .card-header,.card-group>.card:only-child .card-img-top{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-group>.card:only-child .card-footer,.card-group>.card:only-child .card-img-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-group>.card:not(:first-child):not(:last-child):not(:only-child){border-radius:0}.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top{border-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem}.card-columns .card{display:inline-block;width:100%}}.breadcrumb{display:-webkit-box;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;padding-left:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-webkit-box;display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-link:not(:disabled):not(.disabled){cursor:pointer}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}.badge-primary[href]:focus,.badge-primary[href]:hover{color:#fff;text-decoration:none;background-color:#0062cc}.badge-secondary{color:#fff;background-color:#6c757d}.badge-secondary[href]:focus,.badge-secondary[href]:hover{color:#fff;text-decoration:none;background-color:#545b62}.badge-success{color:#fff;background-color:#28a745}.badge-success[href]:focus,.badge-success[href]:hover{color:#fff;text-decoration:none;background-color:#1e7e34}.badge-info{color:#fff;background-color:#17a2b8}.badge-info[href]:focus,.badge-info[href]:hover{color:#fff;text-decoration:none;background-color:#117a8b}.badge-warning{color:#212529;background-color:#ffc107}.badge-warning[href]:focus,.badge-warning[href]:hover{color:#212529;text-decoration:none;background-color:#d39e00}.badge-danger{color:#fff;background-color:#dc3545}.badge-danger[href]:focus,.badge-danger[href]:hover{color:#fff;text-decoration:none;background-color:#bd2130}.badge-light{color:#212529;background-color:#f8f9fa}.badge-light[href]:focus,.badge-light[href]:hover{color:#212529;text-decoration:none;background-color:#dae0e5}.badge-dark{color:#fff;background-color:#343a40}.badge-dark[href]:focus,.badge-dark[href]:hover{color:#fff;text-decoration:none;background-color:#1d2124}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-webkit-box;display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;background-color:#007bff;transition:width .6s ease}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}.media{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start}.media-body{-webkit-box-flex:1;-ms-flex:1;flex:1}.list-group{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item:focus,.list-group-item:hover{z-index:1;text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:focus,.close:hover{color:#000;text-decoration:none;opacity:.75}.close:not(:disabled):not(.disabled){cursor:pointer}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-25%);transform:translate(0,-25%)}.modal.show .modal-dialog{-webkit-transform:translate(0,0);transform:translate(0,0)}.modal-dialog-centered{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;min-height:calc(100% - (.5rem * 2))}.modal-content{position:relative;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:start;-ms-flex-align:start;align-items:flex-start;-webkit-box-pack:justify;-ms-flex-pack:justify;justify-content:space-between;padding:1rem;border-bottom:1px solid #e9ecef;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-webkit-box-flex:1;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:end;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #e9ecef}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-centered{min-height:calc(100% - (1.75rem * 2))}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg{max-width:800px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top] .arrow,.bs-popover-top .arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-top .arrow::before{border-width:.5rem .5rem 0}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{bottom:0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-top .arrow::after{bottom:1px;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right] .arrow,.bs-popover-right .arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-right .arrow::before{border-width:.5rem .5rem .5rem 0}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{left:0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-right .arrow::after{left:1px;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom] .arrow,.bs-popover-bottom .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-bottom .arrow::before{border-width:0 .5rem .5rem .5rem}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{top:0;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-bottom .arrow::after{top:1px;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left] .arrow,.bs-popover-left .arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-left .arrow::before{border-width:.5rem 0 .5rem .5rem}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{right:0;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-left .arrow::after{right:1px;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-item{position:relative;display:none;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;transition:-webkit-transform .6s ease;transition:transform .6s ease;transition:transform .6s ease,-webkit-transform .6s ease;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.carousel-item-next,.carousel-item-prev{position:absolute;top:0}.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.active.carousel-item-right,.carousel-item-next{-webkit-transform:translateX(100%);transform:translateX(100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-right,.carousel-item-next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translateX(-100%);transform:translateX(-100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{position:absolute;right:0;bottom:10px;left:0;z-index:15;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{position:relative;-webkit-box-flex:0;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;background-color:rgba(255,255,255,.5)}.carousel-indicators li::before{position:absolute;top:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators li::after{position:absolute;bottom:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-circle{border-radius:50%!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-webkit-box!important;display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-webkit-inline-box!important;display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-sm-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-md-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-lg-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-webkit-box-orient:horizontal!important;-webkit-box-direction:normal!important;-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-webkit-box-orient:vertical!important;-webkit-box-direction:normal!important;-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-webkit-box-orient:horizontal!important;-webkit-box-direction:reverse!important;-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-webkit-box-orient:vertical!important;-webkit-box-direction:reverse!important;-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.justify-content-xl-start{-webkit-box-pack:start!important;-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-webkit-box-pack:end!important;-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-webkit-box-pack:center!important;-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-webkit-box-pack:justify!important;-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-webkit-box-align:start!important;-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-webkit-box-align:end!important;-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-webkit-box-align:center!important;-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-webkit-box-align:baseline!important;-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-webkit-box-align:stretch!important;-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;-webkit-clip-path:inset(50%);clip-path:inset(50%);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal;-webkit-clip-path:none;clip-path:none}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0062cc!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#545b62!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#1e7e34!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#117a8b!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#d39e00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#bd2130!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#dae0e5!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#1d2124!important}.text-muted{color:#6c757d!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #ddd!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/css/bootstrap-4.1.0.min.css b/net452/SiteServer.Web/SiteServer/assets/css/bootstrap-4.1.0.min.css new file mode 100644 index 000000000..e490fd02e --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/css/bootstrap-4.1.0.min.css @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.1.0 (https://getbootstrap.com/) + * Copyright 2011-2018 The Bootstrap Authors + * Copyright 2011-2018 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg:not(:root){overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.2;color:inherit}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014 \00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;max-width:100%;margin-bottom:1rem;background-color:transparent}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;padding:.375rem .75rem;font-size:1rem;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:not([size]):not([multiple]){height:calc(2.25rem + 2px)}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm,.input-group-lg>.form-control-plaintext.form-control,.input-group-lg>.input-group-append>.form-control-plaintext.btn,.input-group-lg>.input-group-append>.form-control-plaintext.input-group-text,.input-group-lg>.input-group-prepend>.form-control-plaintext.btn,.input-group-lg>.input-group-prepend>.form-control-plaintext.input-group-text,.input-group-sm>.form-control-plaintext.form-control,.input-group-sm>.input-group-append>.form-control-plaintext.btn,.input-group-sm>.input-group-append>.form-control-plaintext.input-group-text,.input-group-sm>.input-group-prepend>.form-control-plaintext.btn,.input-group-sm>.input-group-prepend>.form-control-plaintext.input-group-text{padding-right:0;padding-left:0}.form-control-sm,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-sm>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-sm>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-sm>select.form-control:not([size]):not([multiple]),select.form-control-sm:not([size]):not([multiple]){height:calc(1.8125rem + 2px)}.form-control-lg,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-lg>.input-group-append>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-append>select.input-group-text:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.btn:not([size]):not([multiple]),.input-group-lg>.input-group-prepend>select.input-group-text:not([size]):not([multiple]),.input-group-lg>select.form-control:not([size]):not([multiple]),select.form-control-lg:not([size]):not([multiple]){height:calc(2.875rem + 2px)}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(40,167,69,.8);border-radius:.2rem}.custom-select.is-valid,.form-control.is-valid,.was-validated .custom-select:valid,.was-validated .form-control:valid{border-color:#28a745}.custom-select.is-valid:focus,.form-control.is-valid:focus,.was-validated .custom-select:valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{background-color:#71dd8a}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(40,167,69,.25)}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label::before,.was-validated .custom-file-input:valid~.custom-file-label::before{border-color:inherit}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.5rem;margin-top:.1rem;font-size:.875rem;line-height:1;color:#fff;background-color:rgba(220,53,69,.8);border-radius:.2rem}.custom-select.is-invalid,.form-control.is-invalid,.was-validated .custom-select:invalid,.was-validated .form-control:invalid{border-color:#dc3545}.custom-select.is-invalid:focus,.form-control.is-invalid:focus,.was-validated .custom-select:invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{background-color:#efa2a9}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(220,53,69,.25)}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label::before,.was-validated .custom-file-input:invalid~.custom-file-label::before{border-color:inherit}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:focus,.btn:hover{text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}.btn:not(:disabled):not(.disabled).active,.btn:not(:disabled):not(.disabled):active{background-image:none}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-primary{color:#007bff;background-color:transparent;background-image:none;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;background-color:transparent;background-image:none;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;background-color:transparent;background-image:none;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;background-color:transparent;background-image:none;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;background-color:transparent;background-image:none;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;background-color:transparent;background-image:none;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;background-color:transparent;background-image:none;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;background-color:transparent;background-image:none;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;background-color:transparent}.btn-link:hover{color:#0056b3;text-decoration:underline;background-color:transparent;border-color:transparent}.btn-link.focus,.btn-link:focus{text-decoration:underline;border-color:transparent;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media screen and (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media screen and (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-right{right:0;left:auto}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;width:0;height:0;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:0 1 auto;flex:0 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical .btn,.btn-group-vertical .btn-group{width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file:focus,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control{margin-left:-1px}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label,.input-group>.custom-file:not(:first-child) .custom-file-label::after{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:active~.custom-control-label::before{color:#fff;background-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{margin-bottom:0}.custom-control-label::before{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;pointer-events:none;content:"";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#dee2e6}.custom-control-label::after{position:absolute;top:.25rem;left:0;display:block;width:1rem;height:1rem;content:"";background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center;background-size:8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:inset 0 1px 2px rgba(0,0,0,.075),0 0 5px rgba(128,189,255,.5)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{opacity:0}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:125%}.custom-file{position:relative;display:inline-block;width:100%;height:calc(2.25rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(2.25rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:focus~.custom-file-label::after{border-color:#80bdff}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(2.25rem + 2px);padding:.375rem .75rem;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:calc(calc(2.25rem + 2px) - 1px * 2);padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:1px solid #ced4da;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;padding-left:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;-webkit-appearance:none;appearance:none}.custom-range::-webkit-slider-thumb:focus{outline:0;box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;-moz-appearance:none;appearance:none}.custom-range::-moz-range-thumb:focus{outline:0;box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;appearance:none}.custom-range::-ms-thumb:focus{outline:0;box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler:not(:disabled):not(.disabled){cursor:pointer}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-ms-flexbox;display:flex;-ms-flex:1 0 0%;flex:1 0 0%;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-header,.card-group>.card:first-child .card-img-top{border-top-right-radius:0}.card-group>.card:first-child .card-footer,.card-group>.card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-header,.card-group>.card:last-child .card-img-top{border-top-left-radius:0}.card-group>.card:last-child .card-footer,.card-group>.card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:.25rem}.card-group>.card:only-child .card-header,.card-group>.card:only-child .card-img-top{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-group>.card:only-child .card-footer,.card-group>.card:only-child .card-img-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-group>.card:not(:first-child):not(:last-child):not(:only-child){border-radius:0}.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top{border-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion .card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion .card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion .card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion .card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-link:not(:disabled):not(.disabled){cursor:pointer}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}.badge-primary[href]:focus,.badge-primary[href]:hover{color:#fff;text-decoration:none;background-color:#0062cc}.badge-secondary{color:#fff;background-color:#6c757d}.badge-secondary[href]:focus,.badge-secondary[href]:hover{color:#fff;text-decoration:none;background-color:#545b62}.badge-success{color:#fff;background-color:#28a745}.badge-success[href]:focus,.badge-success[href]:hover{color:#fff;text-decoration:none;background-color:#1e7e34}.badge-info{color:#fff;background-color:#17a2b8}.badge-info[href]:focus,.badge-info[href]:hover{color:#fff;text-decoration:none;background-color:#117a8b}.badge-warning{color:#212529;background-color:#ffc107}.badge-warning[href]:focus,.badge-warning[href]:hover{color:#212529;text-decoration:none;background-color:#d39e00}.badge-danger{color:#fff;background-color:#dc3545}.badge-danger[href]:focus,.badge-danger[href]:hover{color:#fff;text-decoration:none;background-color:#bd2130}.badge-light{color:#212529;background-color:#f8f9fa}.badge-light[href]:focus,.badge-light[href]:hover{color:#212529;text-decoration:none;background-color:#dae0e5}.badge-dark{color:#fff;background-color:#343a40}.badge-dark[href]:focus,.badge-dark[href]:hover{color:#fff;text-decoration:none;background-color:#1d2124}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media screen and (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item:focus,.list-group-item:hover{z-index:1;text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:focus,.close:hover{color:#000;text-decoration:none;opacity:.75}.close:not(:disabled):not(.disabled){cursor:pointer}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-25%);transform:translate(0,-25%)}@media screen and (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:translate(0,0);transform:translate(0,0)}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - (.5rem * 2))}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem;border-bottom:1px solid #e9ecef;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #e9ecef}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-centered{min-height:calc(100% - (1.75rem * 2))}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg{max-width:800px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top] .arrow,.bs-popover-top .arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-top .arrow::before{border-width:.5rem .5rem 0}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{bottom:0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-top .arrow::after{bottom:1px;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right] .arrow,.bs-popover-right .arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-right .arrow::before{border-width:.5rem .5rem .5rem 0}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{left:0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-right .arrow::after{left:1px;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom] .arrow,.bs-popover-bottom .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-bottom .arrow::before{border-width:0 .5rem .5rem .5rem}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{top:0;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-bottom .arrow::after{top:1px;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left] .arrow,.bs-popover-left .arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-left .arrow::before{border-width:.5rem 0 .5rem .5rem}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{right:0;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-left .arrow::after{right:1px;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-item{position:relative;display:none;-ms-flex-align:center;align-items:center;width:100%;transition:-webkit-transform .6s ease;transition:transform .6s ease;transition:transform .6s ease,-webkit-transform .6s ease;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}@media screen and (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.carousel-item-next,.carousel-item-prev{position:absolute;top:0}.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.active.carousel-item-right,.carousel-item-next{-webkit-transform:translateX(100%);transform:translateX(100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-right,.carousel-item-next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translateX(-100%);transform:translateX(-100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.carousel-fade .carousel-item{opacity:0;transition-duration:.6s;transition-property:opacity}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{opacity:0}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev,.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev,.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{position:absolute;right:0;bottom:10px;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{position:relative;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;background-color:rgba(255,255,255,.5)}.carousel-indicators li::before{position:absolute;top:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators li::after{position:absolute;bottom:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-circle{border-radius:50%!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0062cc!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#545b62!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#1e7e34!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#117a8b!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#d39e00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#bd2130!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#dae0e5!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#1d2124!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}} +/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/assets/css/components.css b/net452/SiteServer.Web/SiteServer/assets/css/components.css similarity index 82% rename from SiteServer.Web/SiteServer/assets/css/components.css rename to net452/SiteServer.Web/SiteServer/assets/css/components.css index 92e112f8f..97bf70ed5 100644 --- a/SiteServer.Web/SiteServer/assets/css/components.css +++ b/net452/SiteServer.Web/SiteServer/assets/css/components.css @@ -19,29 +19,35 @@ border-radius: 2px; padding: 6px 14px; } -.btn-group-lg > .btn, + +.btn-group-lg>.btn, .btn-lg { padding: 10px 16px !important; font-size: 16px; } -.btn-group-sm > .btn, + +.btn-group-sm>.btn, .btn-sm { padding: 5px 10px !important; } -.btn-group-xs > .btn, + +.btn-group-xs>.btn, .btn-xs { padding: 1px 5px !important; } -.btn-group .btn + .btn, -.btn-group .btn + .btn-group, -.btn-group .btn-group + .btn, -.btn-group .btn-group + .btn-group { + +.btn-group .btn+.btn, +.btn-group .btn+.btn-group, +.btn-group .btn-group+.btn, +.btn-group .btn-group+.btn-group { margin-left: 0px; } + .btn-group.open .dropdown-toggle { -webkit-box-shadow: 0 0 0 100px rgba(0, 0, 0, 0.1) inset; box-shadow: 0 0 0 100px rgba(0, 0, 0, 0.1) inset; } + .btn-primary, .btn-success, .btn-info, @@ -52,32 +58,39 @@ .btn-pink { color: #ffffff !important; } + .btn-default { background-color: #dae6ec; border-color: #dae6ec; } + .btn-default:focus { background-color: #dae6ec; border-color: #C2CED4; } + .btn-default:hover { background-color: #dae6ec; border-color: #C2CED4; } + .btn-default:active { background-color: #dae6ec; border-color: #C2CED4; } + .btn-default.active, .btn-default:active, -.open > .dropdown-toggle.btn-default { +.open>.dropdown-toggle.btn-default { background-color: #dae6ec !important; border-color: #C2CED4 !important; } + .btn-primary { background-color: #00b19d !important; border: 1px solid #00b19d !important; } + .btn-primary:hover, .btn-primary:focus, .btn-primary:active, @@ -86,14 +99,16 @@ .btn-primary:active, .btn-primary:focus, .btn-primary:hover, -.open > .dropdown-toggle.btn-primary { +.open>.dropdown-toggle.btn-primary { background-color: #009886 !important; border: 1px solid #009886 !important; } + .btn-success { background-color: #3bafda !important; border: 1px solid #3bafda !important; } + .btn-success:hover, .btn-success:focus, .btn-success:active, @@ -102,14 +117,16 @@ .btn-success:active, .btn-success:focus, .btn-success:hover, -.open > .dropdown-toggle.btn-success { +.open>.dropdown-toggle.btn-success { background-color: #28a5d4 !important; border: 1px solid #28a5d4 !important; } + .btn-info { background-color: #3ddcf7 !important; border: 1px solid #3ddcf7 !important; } + .btn-info:hover, .btn-info:focus, .btn-info:active, @@ -118,14 +135,16 @@ .btn-info:active, .btn-info:focus, .btn-info:hover, -.open > .dropdown-toggle.btn-info { +.open>.dropdown-toggle.btn-info { background-color: #25d8f6 !important; border: 1px solid #25d8f6 !important; } + .btn-warning { background-color: #ffaa00 !important; border: 1px solid #ffaa00 !important; } + .btn-warning:hover, .btn-warning:focus, .btn-warning:active, @@ -134,14 +153,16 @@ .btn-warning:active, .btn-warning:focus, .btn-warning:hover, -.open > .dropdown-toggle.btn-warning { +.open>.dropdown-toggle.btn-warning { background-color: #e69900 !important; border: 1px solid #e69900 !important; } + .btn-danger { background-color: #ef5350 !important; border: 1px solid #ef5350 !important; } + .btn-danger:active, .btn-danger:focus, .btn-danger:hover, @@ -150,14 +171,16 @@ .btn-danger:active, .btn-danger:focus, .btn-danger:hover, -.open > .dropdown-toggle.btn-danger { +.open>.dropdown-toggle.btn-danger { background-color: #ed3c39 !important; border: 1px solid #ed3c39 !important; } + .btn-inverse { background-color: #4c5667 !important; border: 1px solid #4c5667 !important; } + .btn-inverse:hover, .btn-inverse:focus, .btn-inverse:active, @@ -166,69 +189,86 @@ .btn-inverse:active, .btn-inverse:focus, .btn-inverse:hover, -.open > .dropdown-toggle.btn-inverse { +.open>.dropdown-toggle.btn-inverse { background-color: #414a58 !important; border: 1px solid #414a58 !important; } + .btn-purple { background-color: #7266ba !important; border: 1px solid #7266ba !important; } + .btn-purple:hover, .btn-purple:focus, .btn-purple:active { background-color: #6254b2 !important; border: 1px solid #6254b2 !important; } + .btn-pink { background-color: #f76397 !important; border: 1px solid #f76397 !important; } + .btn-pink:hover, .btn-pink:focus, .btn-pink:active { background-color: #f64b87 !important; border: 1px solid #f64b87 !important; } + .btn-custom { border-bottom: 3px solid transparent; } + .btn-custom.btn-default { background-color: #dae6ec; border-bottom: 2px solid #a4b6bf !important; } + .btn-custom.btn-primary { border-bottom: 2px solid #007e70 !important; } + .btn-custom.btn-success { border-bottom: 2px solid #2494be !important; } + .btn-custom.btn-info { border-bottom: 2px solid #08aac6 !important; } + .btn-custom.btn-warning { border-bottom: 2px solid #cc8800 !important; } + .btn-custom.btn-danger { border-bottom: 2px solid #c71612 !important; } + .btn-custom.btn-inverse { border-bottom: 2px solid #21252c !important; } + .btn-custom.btn-purple { border-bottom: 2px solid #443a80 !important; } + .btn-custom.btn-pink { border-bottom: 2px solid #e80c59 !important; } + .btn-rounded { border-radius: 2em; padding: 6px 18px; } + .fileupload { overflow: hidden; position: relative; } + .fileupload input.upload { cursor: pointer; filter: alpha(opacity=0); @@ -240,6 +280,7 @@ right: 0; top: 0; } + /* =========== Panels =============*/ @@ -251,25 +292,31 @@ box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.1); margin-bottom: 20px; } + .panel .panel-body { padding: 20px; } + .panel .panel-body p { margin: 0px; } -.panel .panel-body p + p { + +.panel .panel-body p+p { margin-top: 15px; } + .panel-heading { border-radius: 0; border: none !important; padding: 10px 20px; } -.panel-default > .panel-heading { + +.panel-default>.panel-heading { background-color: #fafafa; border-bottom: none; color: #797979; } + .panel-title { font-size: 14px; font-weight: 600; @@ -278,98 +325,125 @@ text-transform: uppercase; letter-spacing: 0.03em; } + .panel-sub-title { margin-bottom: 3px; color: #CEE4FD; margin-top: -3px; } + .panel-footer { background: #fafafa; border-top: 0px; } + .panel-default .panel-sub-title { color: inherit; } + .panel-color .panel-title { color: #ffffff; } -.panel-primary > .panel-heading { + +.panel-primary>.panel-heading { background-color: #00b19d; } -.panel-success > .panel-heading { + +.panel-success>.panel-heading { background-color: #3bafda; } -.panel-info > .panel-heading { + +.panel-info>.panel-heading { background-color: #3ddcf7; } -.panel-warning > .panel-heading { + +.panel-warning>.panel-heading { background-color: #ffaa00; } -.panel-danger > .panel-heading { + +.panel-danger>.panel-heading { background-color: #ef5350; } -.panel-purple > .panel-heading { + +.panel-purple>.panel-heading { background-color: #7266ba; } -.panel-pink > .panel-heading { + +.panel-pink>.panel-heading { background-color: #f76397; } -.panel-inverse > .panel-heading { + +.panel-inverse>.panel-heading { background-color: #4c5667; } + .panel-border { border-radius: 3px; } + .panel-border .panel-heading { background-color: #ffffff; border-top: 3px solid #ccc !important; border-radius: 3px; padding: 10px 20px 0px; } + .panel-border .panel-body { padding: 15px 20px 20px 20px; } + .panel-border.panel-primary .panel-heading { border-color: #00b19d !important; color: #00b19d !important; } + .panel-border.panel-success .panel-heading { border-color: #3bafda !important; color: #3bafda !important; } + .panel-border.panel-info .panel-heading { border-color: #3ddcf7 !important; color: #3ddcf7 !important; } + .panel-border.panel-warning .panel-heading { border-color: #ffaa00 !important; color: #ffaa00 !important; } + .panel-border.panel-danger .panel-heading { border-color: #ef5350 !important; color: #ef5350 !important; } + .panel-border.panel-purple .panel-heading { border-color: #7266ba !important; color: #7266ba !important; } + .panel-border.panel-pink .panel-heading { border-color: #f76397 !important; color: #f76397 !important; } + .panel-border.panel-inverse .panel-heading { border-color: #4c5667 !important; color: #4c5667 !important; } + .panel-group .panel .panel-heading a[data-toggle=collapse].collapsed:before { content: '\f067'; } + .panel-group .panel .panel-heading .accordion-toggle.collapsed:before { content: '\f067'; } + .panel-group .panel .panel-heading a[data-toggle=collapse] { display: block; } + .panel-group .panel .panel-heading a[data-toggle=collapse]:before { content: '\f068'; display: block; @@ -379,9 +453,11 @@ text-align: right; width: 25px; } + .panel-group .panel .panel-heading .accordion-toggle { display: block; } + .panel-group .panel .panel-heading .accordion-toggle:before { content: '\f068'; display: block; @@ -391,20 +467,25 @@ text-align: right; width: 25px; } -.panel-group .panel .panel-heading + .panel-collapse .panel-body { + +.panel-group .panel .panel-heading+.panel-collapse .panel-body { border-top: none; } + .panel-group .panel-heading { padding: 12px 26px; } -.panel-group.panel-group-joined .panel + .panel { + +.panel-group.panel-group-joined .panel+.panel { border-top: 1px solid #eeeeee; margin-top: 0; } -.panel-group-joined .panel-group .panel + .panel { + +.panel-group-joined .panel-group .panel+.panel { border-top: 1px solid #eeeeee; margin-top: 0; } + /* =========== Portlets =============*/ @@ -419,11 +500,13 @@ margin-bottom: 20px; transition: all 0.4s; } + .portlet .portlet-heading { border-radius: 3px; color: #ffffff; padding: 12px 20px; } + .portlet .portlet-heading .portlet-title { color: #ffffff; float: left; @@ -434,6 +517,7 @@ text-transform: uppercase; letter-spacing: 0.03em; } + .portlet .portlet-heading .portlet-widgets { display: inline-block; float: right; @@ -443,12 +527,15 @@ position: relative; text-align: right; } + .portlet .portlet-heading .portlet-widgets .divider { margin: 0 5px; } + .portlet .portlet-heading a { color: #999999; } + .portlet .portlet-body { -moz-border-radius-bottomleft: 5px; -moz-border-radius-bottomright: 5px; @@ -459,12 +546,15 @@ border-bottom-right-radius: 5px; padding: 15px; } + .portlet-default .portlet-title { color: #797979 !important; } + .portlet .portlet-heading .portlet-widgets .collapsed .ion-minus-round:before { content: "\f217" !important; } + .portlet .portlet-heading.bg-purple a, .portlet .portlet-heading.bg-info a, .portlet .portlet-heading.bg-success a, @@ -475,6 +565,7 @@ .portlet .portlet-heading.bg-pink a { color: #ffffff; } + .panel-disabled { background: rgba(243, 242, 241, 0.5); cursor: progress; @@ -484,6 +575,7 @@ right: -5px; top: 0; } + .loader-1 { -moz-animation: loaderAnimate 1000ms linear infinite; -o-animation: loaderAnimate 1000ms linear infinite; @@ -498,6 +590,7 @@ top: 50%; width: 30px; } + .loader-1:after { -moz-animation: loaderAnimate2 1000ms ease-in-out infinite; -o-animation: loaderAnimate2 1000ms ease-in-out infinite; @@ -510,6 +603,7 @@ position: absolute; width: 30px; } + /* =========== Checkbox and Radio =============*/ @@ -517,12 +611,14 @@ padding-left: 20px; margin-left: 5px; } + .checkbox label { display: inline-block; padding-left: 5px; position: relative; margin-right: 25px; } + .checkbox label::before { -o-transition: 0.3s ease-in-out; -webkit-transition: 0.3s ease-in-out; @@ -540,6 +636,7 @@ width: 17px; outline: none !important; } + .checkbox label::after { color: #555555; display: inline-block; @@ -553,104 +650,131 @@ top: 0; width: 16px; } + .checkbox input[type="checkbox"] { cursor: pointer; opacity: 0; z-index: 1; outline: none !important; } -.checkbox input[type="checkbox"]:disabled + label { + +.checkbox input[type="checkbox"]:disabled+label { opacity: 0.65; } -.checkbox input[type="checkbox"]:focus + label::before { + +.checkbox input[type="checkbox"]:focus+label::before { outline-offset: -2px; outline: none; } -.checkbox input[type="checkbox"]:checked + label::after { + +.checkbox input[type="checkbox"]:checked+label::after { content: "\f122"; font-family: "Ionicons"; } -.checkbox input[type="checkbox"]:disabled + label::before { + +.checkbox input[type="checkbox"]:disabled+label::before { background-color: #eeeeee; cursor: not-allowed; } + .checkbox.checkbox-circle label::before { border-radius: 50%; } + .checkbox.checkbox-inline { margin-top: 0; } + .checkbox.checkbox-single label { height: 17px; } -.checkbox-primary input[type="checkbox"]:checked + label::before { + +.checkbox-primary input[type="checkbox"]:checked+label::before { background-color: #00b19d; border-color: #00b19d; } -.checkbox-primary input[type="checkbox"]:checked + label::after { + +.checkbox-primary input[type="checkbox"]:checked+label::after { color: #ffffff; margin-top: 4px; } -.checkbox-danger input[type="checkbox"]:checked + label::before { + +.checkbox-danger input[type="checkbox"]:checked+label::before { background-color: #ef5350; border-color: #ef5350; } -.checkbox-danger input[type="checkbox"]:checked + label::after { + +.checkbox-danger input[type="checkbox"]:checked+label::after { color: #ffffff; } -.checkbox-info input[type="checkbox"]:checked + label::before { + +.checkbox-info input[type="checkbox"]:checked+label::before { background-color: #3ddcf7; border-color: #3ddcf7; } -.checkbox-info input[type="checkbox"]:checked + label::after { + +.checkbox-info input[type="checkbox"]:checked+label::after { color: #ffffff; } -.checkbox-warning input[type="checkbox"]:checked + label::before { + +.checkbox-warning input[type="checkbox"]:checked+label::before { background-color: #ffaa00; border-color: #ffaa00; } -.checkbox-warning input[type="checkbox"]:checked + label::after { + +.checkbox-warning input[type="checkbox"]:checked+label::after { color: #ffffff; } -.checkbox-success input[type="checkbox"]:checked + label::before { + +.checkbox-success input[type="checkbox"]:checked+label::before { background-color: #3bafda; border-color: #3bafda; } -.checkbox-success input[type="checkbox"]:checked + label::after { + +.checkbox-success input[type="checkbox"]:checked+label::after { color: #ffffff; } -.checkbox-purple input[type="checkbox"]:checked + label::before { + +.checkbox-purple input[type="checkbox"]:checked+label::before { background-color: #7266ba; border-color: #7266ba; } -.checkbox-purple input[type="checkbox"]:checked + label::after { + +.checkbox-purple input[type="checkbox"]:checked+label::after { color: #ffffff; } -.checkbox-pink input[type="checkbox"]:checked + label::before { + +.checkbox-pink input[type="checkbox"]:checked+label::before { background-color: #f76397; border-color: #f76397; } -.checkbox-pink input[type="checkbox"]:checked + label::after { + +.checkbox-pink input[type="checkbox"]:checked+label::after { color: #ffffff; } -.checkbox-inverse input[type="checkbox"]:checked + label::before { + +.checkbox-inverse input[type="checkbox"]:checked+label::before { background-color: #4c5667; border-color: #4c5667; } -.checkbox-inverse input[type="checkbox"]:checked + label::after { + +.checkbox-inverse input[type="checkbox"]:checked+label::after { color: #ffffff; } + .radio { padding-left: 20px; margin-left: 10px; margin-top: 5px; } + .radio label { display: inline-block; padding-left: 5px; position: relative; margin-right: 25px; } + .radio label::before { -o-transition: border 0.5s ease-in-out; -webkit-transition: border 0.5s ease-in-out; @@ -668,6 +792,7 @@ transition: border 0.5s ease-in-out; width: 17px; } + .radio label::after { -moz-transition: -moz-transform 0.1s cubic-bezier(0.8, -0.33, 0.2, 1.33); -ms-transform: scale(0, 0); @@ -688,108 +813,140 @@ transition: transform 0.1s cubic-bezier(0.8, -0.33, 0.2, 1.33); width: 11px; } + .radio input[type="radio"] { cursor: pointer; opacity: 0; z-index: 1; outline: none !important; } -.radio input[type="radio"]:disabled + label { + +.radio input[type="radio"]:disabled+label { opacity: 0.65; } -.radio input[type="radio"]:focus + label::before { + +.radio input[type="radio"]:focus+label::before { outline-offset: -2px; outline: 5px auto -webkit-focus-ring-color; outline: thin dotted; } -.radio input[type="radio"]:checked + label::after { + +.radio input[type="radio"]:checked+label::after { -ms-transform: scale(1, 1); -o-transform: scale(1, 1); -webkit-transform: scale(1, 1); transform: scale(1, 1); } -.radio input[type="radio"]:disabled + label::before { + +.radio input[type="radio"]:disabled+label::before { cursor: not-allowed; } + .radio.radio-inline { margin-top: 0; } + .radio.radio-single label { height: 17px; } -.radio-primary input[type="radio"] + label::after { + +.radio-primary input[type="radio"]+label::after { background-color: #00b19d; } -.radio-primary input[type="radio"]:checked + label::before { + +.radio-primary input[type="radio"]:checked+label::before { border-color: #00b19d; } -.radio-primary input[type="radio"]:checked + label::after { + +.radio-primary input[type="radio"]:checked+label::after { background-color: #00b19d; margin-top: 5px; } -.radio-danger input[type="radio"] + label::after { + +.radio-danger input[type="radio"]+label::after { background-color: #ef5350; } -.radio-danger input[type="radio"]:checked + label::before { + +.radio-danger input[type="radio"]:checked+label::before { border-color: #ef5350; } -.radio-danger input[type="radio"]:checked + label::after { + +.radio-danger input[type="radio"]:checked+label::after { background-color: #ef5350; } -.radio-info input[type="radio"] + label::after { + +.radio-info input[type="radio"]+label::after { background-color: #3ddcf7; } -.radio-info input[type="radio"]:checked + label::before { + +.radio-info input[type="radio"]:checked+label::before { border-color: #3ddcf7; } -.radio-info input[type="radio"]:checked + label::after { + +.radio-info input[type="radio"]:checked+label::after { background-color: #3ddcf7; } -.radio-warning input[type="radio"] + label::after { + +.radio-warning input[type="radio"]+label::after { background-color: #ffaa00; } -.radio-warning input[type="radio"]:checked + label::before { + +.radio-warning input[type="radio"]:checked+label::before { border-color: #ffaa00; } -.radio-warning input[type="radio"]:checked + label::after { + +.radio-warning input[type="radio"]:checked+label::after { background-color: #ffaa00; } -.radio-success input[type="radio"] + label::after { + +.radio-success input[type="radio"]+label::after { background-color: #3bafda; } -.radio-success input[type="radio"]:checked + label::before { + +.radio-success input[type="radio"]:checked+label::before { border-color: #3bafda; } -.radio-success input[type="radio"]:checked + label::after { + +.radio-success input[type="radio"]:checked+label::after { background-color: #3bafda; } -.radio-purple input[type="radio"] + label::after { + +.radio-purple input[type="radio"]+label::after { background-color: #7266ba; } -.radio-purple input[type="radio"]:checked + label::before { + +.radio-purple input[type="radio"]:checked+label::before { border-color: #7266ba; } -.radio-purple input[type="radio"]:checked + label::after { + +.radio-purple input[type="radio"]:checked+label::after { background-color: #7266ba; } -.radio-pink input[type="radio"] + label::after { + +.radio-pink input[type="radio"]+label::after { background-color: #f76397; } -.radio-pink input[type="radio"]:checked + label::before { + +.radio-pink input[type="radio"]:checked+label::before { border-color: #f76397; } -.radio-pink input[type="radio"]:checked + label::after { + +.radio-pink input[type="radio"]:checked+label::after { background-color: #f76397; } -.radio-inverse input[type="radio"] + label::after { + +.radio-inverse input[type="radio"]+label::after { background-color: #4c5667; } -.radio-inverse input[type="radio"]:checked + label::before { + +.radio-inverse input[type="radio"]:checked+label::before { border-color: #4c5667; } -.radio-inverse input[type="radio"]:checked + label::after { + +.radio-inverse input[type="radio"]:checked+label::after { background-color: #4c5667; } + /* =========== Progressbars =============*/ @@ -801,57 +958,73 @@ margin-bottom: 18px; overflow: hidden; } + .progress-bar { box-shadow: none; font-size: 8px; font-weight: 600; line-height: 12px; } + .progress.progress-sm { height: 5px !important; } + .progress.progress-sm .progress-bar { font-size: 8px; line-height: 5px; } + .progress.progress-md { height: 15px !important; } + .progress.progress-md .progress-bar { font-size: 10.8px; line-height: 14.4px; } + .progress.progress-lg { height: 20px !important; } + .progress.progress-lg .progress-bar { font-size: 12px; line-height: 20px; } + .progress-bar-primary { background-color: #00b19d; } + .progress-bar-success { background-color: #3bafda; } + .progress-bar-info { background-color: #3ddcf7; } + .progress-bar-warning { background-color: #ffaa00; } + .progress-bar-danger { background-color: #ef5350; } + .progress-bar-inverse { background-color: #4c5667; } + .progress-bar-purple { background-color: #7266ba; } + .progress-bar-pink { background-color: #f76397; } + .progress-animated { -webkit-animation-duration: 5s; -webkit-animation-name: animationProgress; @@ -860,12 +1033,14 @@ animation-name: animationProgress; transition: 5s all; } + /* =========== Carousel =============*/ .carousel-control { width: 10%; } + .carousel-control span { position: absolute; top: 50%; @@ -874,101 +1049,115 @@ display: inline-block; font-size: 30px; } + .carousel-indicators li { border: 2px solid #ffffff; } + /* =========== Tables =============*/ .table { margin-bottom: 10px; } + tbody { color: #797979; } + th { color: #666666; font-size: 15px; } -.table > tbody > tr > td, -.table > tbody > tr > th, -.table > tfoot > tr > td, -.table > tfoot > tr > th, -.table > thead > tr > td, -.table > thead > tr > th { + +.table>tbody>tr>td, +.table>tbody>tr>th, +.table>tfoot>tr>td, +.table>tfoot>tr>th, +.table>thead>tr>td, +.table>thead>tr>th { border-top: 1px solid #f3f3f3; } -.table > thead > tr > th { + +.table>thead>tr>th { border-bottom: 2px solid #f3f3f3; } -.table > tbody > tr.success > td, -.table > tbody > tr.success > th, -.table > tbody > tr > td.success, -.table > tbody > tr > th.success, -.table > tfoot > tr.success > td, -.table > tfoot > tr.success > th, -.table > tfoot > tr > td.success, -.table > tfoot > tr > th.success, -.table > thead > tr.success > td, -.table > thead > tr.success > th, -.table > thead > tr > td.success, -.table > thead > tr > th.success { + +.table>tbody>tr.success>td, +.table>tbody>tr.success>th, +.table>tbody>tr>td.success, +.table>tbody>tr>th.success, +.table>tfoot>tr.success>td, +.table>tfoot>tr.success>th, +.table>tfoot>tr>td.success, +.table>tfoot>tr>th.success, +.table>thead>tr.success>td, +.table>thead>tr.success>th, +.table>thead>tr>td.success, +.table>thead>tr>th.success { background-color: rgba(59, 175, 218, 0.15); } -.table > tbody > tr.info > td, -.table > tbody > tr.info > th, -.table > tbody > tr > td.info, -.table > tbody > tr > th.info, -.table > tfoot > tr.info > td, -.table > tfoot > tr.info > th, -.table > tfoot > tr > td.info, -.table > tfoot > tr > th.info, -.table > thead > tr.info > td, -.table > thead > tr.info > th, -.table > thead > tr > td.info, -.table > thead > tr > th.info { + +.table>tbody>tr.info>td, +.table>tbody>tr.info>th, +.table>tbody>tr>td.info, +.table>tbody>tr>th.info, +.table>tfoot>tr.info>td, +.table>tfoot>tr.info>th, +.table>tfoot>tr>td.info, +.table>tfoot>tr>th.info, +.table>thead>tr.info>td, +.table>thead>tr.info>th, +.table>thead>tr>td.info, +.table>thead>tr>th.info { background-color: rgba(61, 220, 247, 0.15); } -.table > tbody > tr.warning > td, -.table > tbody > tr.warning > th, -.table > tbody > tr > td.warning, -.table > tbody > tr > th.warning, -.table > tfoot > tr.warning > td, -.table > tfoot > tr.warning > th, -.table > tfoot > tr > td.warning, -.table > tfoot > tr > th.warning, -.table > thead > tr.warning > td, -.table > thead > tr.warning > th, -.table > thead > tr > td.warning, -.table > thead > tr > th.warning { + +.table>tbody>tr.warning>td, +.table>tbody>tr.warning>th, +.table>tbody>tr>td.warning, +.table>tbody>tr>th.warning, +.table>tfoot>tr.warning>td, +.table>tfoot>tr.warning>th, +.table>tfoot>tr>td.warning, +.table>tfoot>tr>th.warning, +.table>thead>tr.warning>td, +.table>thead>tr.warning>th, +.table>thead>tr>td.warning, +.table>thead>tr>th.warning { background-color: rgba(255, 170, 0, 0.15); } -.table > tbody > tr.danger > td, -.table > tbody > tr.danger > th, -.table > tbody > tr > td.danger, -.table > tbody > tr > th.danger, -.table > tfoot > tr.danger > td, -.table > tfoot > tr.danger > th, -.table > tfoot > tr > td.danger, -.table > tfoot > tr > th.danger, -.table > thead > tr.danger > td, -.table > thead > tr.danger > th, -.table > thead > tr > td.danger, -.table > thead > tr > th.danger { + +.table>tbody>tr.danger>td, +.table>tbody>tr.danger>th, +.table>tbody>tr>td.danger, +.table>tbody>tr>th.danger, +.table>tfoot>tr.danger>td, +.table>tfoot>tr.danger>th, +.table>tfoot>tr>td.danger, +.table>tfoot>tr>th.danger, +.table>thead>tr.danger>td, +.table>thead>tr.danger>th, +.table>thead>tr>td.danger, +.table>thead>tr>th.danger { background-color: rgba(239, 83, 80, 0.15); } + table.focus-on tbody tr.focused th { background-color: #00b19d; color: #ffffff; } + table.focus-on tbody tr.focused td { background-color: #00b19d; color: #ffffff; } + .table-rep-plugin tbody th { font-size: 14px; font-weight: normal; } + .modal-block { background: transparent; margin: 40px auto; @@ -977,66 +1166,84 @@ table.focus-on tbody tr.focused td { position: relative; text-align: left; } + /* Data table */ #datatable-editable .actions a { padding: 5px; } + #datatable-editable .form-control { background-color: #ffffff; width: 100%; } + #datatable-editable .fa-trash-o { color: #ef5350; } + #datatable-editable .fa-times { color: #ef5350; } + #datatable-editable .fa-pencil { color: #29b6f6; } + #datatable-editable .fa-save { color: #33b86c; } + #datatable td { font-weight: normal; } + div.dataTables_paginate ul.pagination { margin-top: 30px; } + div.dataTables_info { padding-top: 38px; } + .dt-buttons { float: left; } + div#datatable-buttons_info { float: left; } + /* Fixed Header */ .fixedHeader-floating { top: 125px !important; } + /* Key table */ table.dataTable th.focus, table.dataTable td.focus { outline: 3px solid #00b19d !important; outline-offset: -1px; } + .table-rep-plugin .table-responsive { border: none !important; } + .table-rep-plugin tbody th { font-size: 14px; font-weight: normal; } + .table-rep-plugin .checkbox-row { padding-left: 40px; } + .table-rep-plugin .checkbox-row label { display: inline-block; padding-left: 5px; position: relative; } + .table-rep-plugin .checkbox-row label::before { -o-transition: 0.3s ease-in-out; -webkit-transition: 0.3s ease-in-out; @@ -1053,6 +1260,7 @@ table.dataTable td.focus { width: 17px; outline: none !important; } + .table-rep-plugin .checkbox-row label::after { color: #555555; display: inline-block; @@ -1066,89 +1274,110 @@ table.dataTable td.focus { top: -1px; width: 16px; } + .table-rep-plugin .checkbox-row input[type="checkbox"] { cursor: pointer; opacity: 0; z-index: 1; outline: none !important; } -.table-rep-plugin .checkbox-row input[type="checkbox"]:disabled + label { + +.table-rep-plugin .checkbox-row input[type="checkbox"]:disabled+label { opacity: 0.65; } -.table-rep-plugin .checkbox-row input[type="checkbox"]:focus + label::before { + +.table-rep-plugin .checkbox-row input[type="checkbox"]:focus+label::before { outline-offset: -2px; outline: none; } -.table-rep-plugin .checkbox-row input[type="checkbox"]:checked + label::after { + +.table-rep-plugin .checkbox-row input[type="checkbox"]:checked+label::after { content: "\f00c"; font-family: 'FontAwesome'; } -.table-rep-plugin .checkbox-row input[type="checkbox"]:disabled + label::before { + +.table-rep-plugin .checkbox-row input[type="checkbox"]:disabled+label::before { background-color: #eeeeee; cursor: not-allowed; } -.table-rep-plugin .checkbox-row input[type="checkbox"]:checked + label::before { + +.table-rep-plugin .checkbox-row input[type="checkbox"]:checked+label::before { background-color: #00b19d; border-color: #00b19d; } -.table-rep-plugin .checkbox-row input[type="checkbox"]:checked + label::after { + +.table-rep-plugin .checkbox-row input[type="checkbox"]:checked+label::after { color: #ffffff; } + /* Tablesaw */ .tablesaw thead { background: #f5f5f5; background-image: none; border: none; } + .tablesaw thead th { text-shadow: none; letter-spacing: 0.06em; } + .tablesaw thead tr:first-child th { padding-top: 1.1em; padding-bottom: 0.9em; } + .tablesaw thead tr:first-child th { font-weight: 600; font-family: inherit; border: none; } + .tablesaw td, .tablesaw tbody th { font-size: inherit; line-height: inherit; padding: 10px !important; } + .tablesaw-stack tbody tr, .tablesaw tbody tr { border-bottom: none; } + .tablesaw-sortable .tablesaw-sortable-head.tablesaw-sortable-ascending button:after, .tablesaw-sortable .tablesaw-sortable-head.tablesaw-sortable-descending button:after { font-family: FontAwesome; font-size: 10px; } + .tablesaw-sortable .tablesaw-sortable-head.tablesaw-sortable-ascending button:after { content: "\f176"; } + .tablesaw-sortable .tablesaw-sortable-head.tablesaw-sortable-descending button:after { content: "\f175"; } + .tablesaw-bar .btn-select.btn-small:after, .tablesaw-bar .btn-select.btn-micro:after { font-size: 8px; padding-right: 10px; } + .tablesaw-swipe .tablesaw-cell-persist { box-shadow: none; } + .tablesaw-enhanced .tablesaw-bar .btn { text-shadow: none; background-image: none; } + .tablesaw-enhanced .tablesaw-bar .btn.btn-select:hover { background: #ffffff; } + .tablesaw-enhanced .tablesaw-bar .btn:hover, .tablesaw-enhanced .tablesaw-bar .btn:focus, .tablesaw-enhanced .tablesaw-bar .btn:active { @@ -1158,6 +1387,7 @@ table.dataTable td.focus { box-shadow: none !important; background-image: none; } + /* ============= Form elements ============= */ @@ -1166,29 +1396,36 @@ table.dataTable td.focus { font-size: 12px; font-weight: 500; } + .parsley-error { border-color: #ef5350 !important; } + .parsley-errors-list { display: none; margin: 0; padding: 0; } + .parsley-errors-list.filled { display: block; } -.parsley-errors-list > li { + +.parsley-errors-list>li { font-size: 12px; list-style: none; color: #f6504d; } + /* Datepicker */ .datepicker { padding: 8px; } + .datepicker th { font-size: 14px !important; } + .datepicker table tr td.today, .datepicker table tr td.today:hover, .datepicker table tr td.today.disabled, @@ -1203,6 +1440,7 @@ table.dataTable td.focus { .datepicker table tr td span.active.disabled:hover { background-image: none; } + .datepicker table tr td span.active:hover, .datepicker table tr td span.active:hover:hover, .datepicker table tr td span.active.disabled:hover, @@ -1225,6 +1463,7 @@ table.dataTable td.focus { .datepicker table tr td span.active.disabled:hover[disabled] { background-color: #00b19d; } + .datepicker table tr td.active, .datepicker table tr td.active:hover, .datepicker table tr td.active.disabled, @@ -1234,21 +1473,26 @@ table.dataTable td.focus { box-shadow: none; text-shadow: none; } + .datepicker thead tr:first-child th:hover, .datepicker tfoot tr th:hover { background-color: #fafafa; } + .datepicker-inline { border: 2px solid #eeeeee; } + .daterangepicker td.active, .daterangepicker td.active:hover { background-color: #00b19d; border-color: #00b19d; } + .daterangepicker .input-mini.active { border: 1px solid #AAAAAA; } + .daterangepicker .ranges li { -webkit-border-radius: 2px; border-radius: 2px; @@ -1258,6 +1502,7 @@ table.dataTable td.focus { font-weight: 600; font-size: 12px; } + .daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.secondselect, @@ -1266,50 +1511,63 @@ table.dataTable td.focus { padding: 2px; width: 60px; } + .daterangepicker .ranges li.active, .daterangepicker .ranges li:hover { background-color: #00b19d; border: 1px solid #00b19d; } + .search-input { margin-bottom: 10px; } + .ms-selectable { box-shadow: none; outline: none !important; } + .ms-container .ms-list.ms-focus { box-shadow: none; } + .ms-container .ms-selectable li.ms-hover { background-color: #00b19d; } + .ms-container .ms-selection li.ms-hover { background-color: #00b19d; } + .note-editor { border: 1px solid #eeeeee; position: relative; } + .note-editor .note-toolbar { background-color: rgba(152, 166, 173, 0.1); border-bottom: 1px solid #eeeeee; margin: 0; } + .note-editor .note-statusbar { background-color: #ffffff; } + .note-editor .note-statusbar .note-resizebar { border-top: none; height: 15px; padding-top: 3px; } + .note-popover .popover .popover-content { padding: 5px 0 10px 5px; } + .note-toolbar { padding: 5px 0 10px 5px; } + /* Timepicker */ .bootstrap-timepicker-widget table td a:hover { background-color: transparent; @@ -1318,9 +1576,11 @@ table.dataTable td.focus { color: #00b19d; text-decoration: none; } + .editor-horizontal .popover-content { padding: 9px 30px; } + .datepicker table tr td.active, .datepicker table tr td.active:hover, .datepicker table tr td.active.disabled, @@ -1329,6 +1589,7 @@ table.dataTable td.focus { background-image: none; box-shadow: none; } + /* Dropzone */ .dropzone { min-height: 230px; @@ -1336,9 +1597,11 @@ table.dataTable td.focus { background: white; border-radius: 6px; } + .dropzone .dz-message { font-size: 30px; } + /* =========== Calendar =============*/ @@ -1346,21 +1609,26 @@ table.dataTable td.focus { float: left; margin-bottom: 0px; } + .none-border .modal-footer { border-top: none; } + .fc-toolbar { margin-bottom: 5px; } + .fc-toolbar h2 { font-size: 18px; font-weight: 600; line-height: 30px; text-transform: uppercase; } + .fc-day { background: #ffffff; } + .fc-toolbar .fc-state-active, .fc-toolbar .ui-state-active, .fc-toolbar button:focus, @@ -1368,12 +1636,15 @@ table.dataTable td.focus { .fc-toolbar .ui-state-hover { z-index: 0; } + .fc-widget-header { border: 1px solid #d5d5d5; } + .fc-widget-content { border: 1px solid #d5d5d5; } + .fc th.fc-widget-header { background: #dddddd; font-size: 14px; @@ -1381,28 +1652,35 @@ table.dataTable td.focus { padding: 10px 0px; text-transform: uppercase; } + .fc-button { background: #ffffff; border: 1px solid #d5d5d5; color: #555555; text-transform: capitalize; } + .fc-text-arrow { font-family: arial; font-size: 16px; } + .fc-state-hover { background: #F5F5F5; } + .fc-state-highlight { background: #f0f0f0; } + .fc-cell-overlay { background: #f0f0f0; } + .fc-unthemed .fc-today { background: #ffffff; } + .fc-event { border-radius: 2px; border: none; @@ -1412,18 +1690,22 @@ table.dataTable td.focus { padding: 5px 5px; text-align: center; } + .external-event { color: #ffffff; cursor: move; margin: 10px 0; padding: 6px 10px; } + .fc-basic-view td.fc-week-number span { padding-right: 5px; } + .fc-basic-view td.fc-day-number { padding-right: 5px; } + /* =========== Widgets =============*/ @@ -1433,26 +1715,31 @@ table.dataTable td.focus { padding: 10px 0; position: relative; } + .inbox-widget .inbox-item .inbox-item-img { display: block; float: left; margin-right: 15px; width: 40px; } + .inbox-widget .inbox-item img { width: 40px; } + .inbox-widget .inbox-item .inbox-item-author { color: #333333; display: block; margin: 0; } + .inbox-widget .inbox-item .inbox-item-text { color: #a0a0a0; display: block; font-size: 12px; margin: 0; } + .inbox-widget .inbox-item .inbox-item-date { color: #a9a9a9; font-size: 11px; @@ -1460,28 +1747,34 @@ table.dataTable td.focus { right: 7px; top: 2px; } + .conversation-list { list-style: none; max-height: 330px; padding: 0px 20px; } + .conversation-list li { margin-bottom: 24px; } + .conversation-list .chat-avatar { display: inline-block; float: left; text-align: center; width: 40px; } + .conversation-list .chat-avatar img { border-radius: 100%; width: 100%; } + .conversation-list .chat-avatar i { font-size: 12px; font-style: normal; } + .conversation-list .ctext-wrap { -moz-border-radius: 3px; -webkit-border-radius: 3px; @@ -1491,6 +1784,7 @@ table.dataTable td.focus { padding: 10px; position: relative; } + .conversation-list .ctext-wrap i { color: #1a2942; display: block; @@ -1499,10 +1793,12 @@ table.dataTable td.focus { font-weight: bold; position: relative; } + .conversation-list .ctext-wrap p { margin: 0px; padding-top: 3px; } + .conversation-list .ctext-wrap:after { right: 100%; top: 20%; @@ -1517,6 +1813,7 @@ table.dataTable td.focus { border-width: 5px; margin-top: -5px; } + .conversation-list .conversation-text { display: inline-block; float: left; @@ -1524,40 +1821,50 @@ table.dataTable td.focus { margin-left: 12px; width: 70%; } + .conversation-list .odd .chat-avatar { float: right !important; } + .conversation-list .odd .conversation-text { float: right !important; margin-right: 12px; text-align: right; width: 70% !important; } + .conversation-list .odd .ctext-wrap { background: #e8e9ec !important; } + .conversation-list .odd .ctext-wrap i { color: #acacac; } + .conversation-list .odd .ctext-wrap:after { border-color: rgba(238, 238, 242, 0) !important; border-left-color: #e8e9ec !important; left: 100% !important; top: 20% !important; } + .chat-send { padding-left: 0px; padding-right: 30px; } + .chat-send button { width: 100%; } + .chat-inputbar { padding-left: 30px; } + #todo-message { font-size: 16px; } + .todo-list li { border: 0px; margin: 0px; @@ -1565,18 +1872,22 @@ table.dataTable td.focus { padding-right: 0px !important; background: transparent !important; } + .todo-list li:last-of-type { border-bottom: none; } + .todo-send { padding-left: 0px; } + /* Widget-chart */ .widget-chart ul li { width: 31.5%; display: inline-block; padding: 0px; } + .widget-panel { padding: 30px 20px; padding-left: 30px; @@ -1584,6 +1895,7 @@ table.dataTable td.focus { position: relative; margin-bottom: 20px; } + .widget-panel i { font-size: 60px; padding: 30px; @@ -1594,42 +1906,80 @@ table.dataTable td.focus { top: 0px; line-height: 60px; } + .widget-user { min-height: 112px; } + .widget-user img { height: 72px; float: left; } + .widget-user .wid-u-info { margin-left: 90px; } + .widget-user .wid-u-info p { white-space: nowrap; display: block; overflow: hidden; text-overflow: ellipsis; } + .widget-simple-chart .circliful-chart { float: left; margin-top: -5px; } + .widget-icon i { float: left; font-size: 48px; } + .widget-icon .wid-icon-info { margin-left: 80px; } -.modalPage, .modalPage body { - background-color:#fff !important; + +.modalPage, +.modalPage body { + background-color: #fff !important; } -.modalPage, .modalPage form-horizontal{ - margin-left: 5px; - margin-right: 5px; +.modalPage, +.modalPage form-horizontal { + margin-left: 5px; + margin-right: 5px; } .navbar-nav { flex-direction: inherit; +} + +.scroll { + overflow-x: scroll !important; +} + +.table-tree a { + color: #55565d !important; +} + +.table-tree i { + font-size: 20px; + vertical-align: middle; + color: #7a7b80 !important; +} + +.table-tree>tbody>tr>td, +.table-tree>tbody>tr>th { + border-top: none !important; +} + +.table-tree a, +.table-tree span, +.table-tree div { + font-size: 14px !important; + margin-top: -5px !important; + vertical-align: middle; + display: inline-block !important; } \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/assets/css/core.css b/net452/SiteServer.Web/SiteServer/assets/css/core.css similarity index 98% rename from SiteServer.Web/SiteServer/assets/css/core.css rename to net452/SiteServer.Web/SiteServer/assets/css/core.css index 68aa606de..fff3947cc 100644 --- a/SiteServer.Web/SiteServer/assets/css/core.css +++ b/net452/SiteServer.Web/SiteServer/assets/css/core.css @@ -32,7 +32,7 @@ html { min-height: 100%; background: #f5f5f5; } -a { +.page-link, a { color: #337ab7; } h1, @@ -127,7 +127,6 @@ a:focus { background-color: #fff; } .header-title { - text-transform: uppercase; font-size: 15px; font-weight: 600; letter-spacing: 0.04em; @@ -391,16 +390,6 @@ pre { border-bottom-right-radius: 3px; border-top-right-radius: 3px; } -.pagination > li > a, -.pagination > li > span { - color: #636e7b; -} -.pagination > li > a:hover, -.pagination > li > span:hover, -.pagination > li > a:focus, -.pagination > li > span:focus { - background-color: #e4e7ea; -} .pagination-split li { margin-left: 5px; display: inline-block; @@ -414,6 +403,8 @@ pre { -webkit-border-radius: 3px; border-radius: 3px; } +.dropdown-item.active, .dropdown-item:active, +.page-item.active .page-link, .pagination > .active > a, .pagination > .active > span, .pagination > .active > a:hover, diff --git a/net452/SiteServer.Web/SiteServer/assets/css/font-awesome-4.7.0.min.css b/net452/SiteServer.Web/SiteServer/assets/css/font-awesome-4.7.0.min.css new file mode 100644 index 000000000..540440ce8 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/css/font-awesome-4.7.0.min.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/net452/SiteServer.Web/SiteServer/assets/css/ionicons-2.0.0.min.css b/net452/SiteServer.Web/SiteServer/assets/css/ionicons-2.0.0.min.css new file mode 100644 index 000000000..1c27b785f --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/css/ionicons-2.0.0.min.css @@ -0,0 +1 @@ +@charset "UTF-8";@font-face{font-family:Ionicons;src:url(../fonts/ionicons.eot?v=2.0.0);src:url(../fonts/ionicons.eot?v=2.0.0#iefix) format("embedded-opentype"),url(../fonts/ionicons.ttf?v=2.0.0) format("truetype"),url(../fonts/ionicons.woff?v=2.0.0) format("woff"),url(../fonts/ionicons.svg?v=2.0.0#Ionicons) format("svg");font-weight:400;font-style:normal}.ion,.ion-alert-circled:before,.ion-alert:before,.ion-android-add-circle:before,.ion-android-add:before,.ion-android-alarm-clock:before,.ion-android-alert:before,.ion-android-apps:before,.ion-android-archive:before,.ion-android-arrow-back:before,.ion-android-arrow-down:before,.ion-android-arrow-dropdown-circle:before,.ion-android-arrow-dropdown:before,.ion-android-arrow-dropleft-circle:before,.ion-android-arrow-dropleft:before,.ion-android-arrow-dropright-circle:before,.ion-android-arrow-dropright:before,.ion-android-arrow-dropup-circle:before,.ion-android-arrow-dropup:before,.ion-android-arrow-forward:before,.ion-android-arrow-up:before,.ion-android-attach:before,.ion-android-bar:before,.ion-android-bicycle:before,.ion-android-boat:before,.ion-android-bookmark:before,.ion-android-bulb:before,.ion-android-bus:before,.ion-android-calendar:before,.ion-android-call:before,.ion-android-camera:before,.ion-android-cancel:before,.ion-android-car:before,.ion-android-cart:before,.ion-android-chat:before,.ion-android-checkbox-blank:before,.ion-android-checkbox-outline-blank:before,.ion-android-checkbox-outline:before,.ion-android-checkbox:before,.ion-android-checkmark-circle:before,.ion-android-clipboard:before,.ion-android-close:before,.ion-android-cloud-circle:before,.ion-android-cloud-done:before,.ion-android-cloud-outline:before,.ion-android-cloud:before,.ion-android-color-palette:before,.ion-android-compass:before,.ion-android-contact:before,.ion-android-contacts:before,.ion-android-contract:before,.ion-android-create:before,.ion-android-delete:before,.ion-android-desktop:before,.ion-android-document:before,.ion-android-done-all:before,.ion-android-done:before,.ion-android-download:before,.ion-android-drafts:before,.ion-android-exit:before,.ion-android-expand:before,.ion-android-favorite-outline:before,.ion-android-favorite:before,.ion-android-film:before,.ion-android-folder-open:before,.ion-android-folder:before,.ion-android-funnel:before,.ion-android-globe:before,.ion-android-hand:before,.ion-android-hangout:before,.ion-android-happy:before,.ion-android-home:before,.ion-android-image:before,.ion-android-laptop:before,.ion-android-list:before,.ion-android-locate:before,.ion-android-lock:before,.ion-android-mail:before,.ion-android-map:before,.ion-android-menu:before,.ion-android-microphone-off:before,.ion-android-microphone:before,.ion-android-more-horizontal:before,.ion-android-more-vertical:before,.ion-android-navigate:before,.ion-android-notifications-none:before,.ion-android-notifications-off:before,.ion-android-notifications:before,.ion-android-open:before,.ion-android-options:before,.ion-android-people:before,.ion-android-person-add:before,.ion-android-person:before,.ion-android-phone-landscape:before,.ion-android-phone-portrait:before,.ion-android-pin:before,.ion-android-plane:before,.ion-android-playstore:before,.ion-android-print:before,.ion-android-radio-button-off:before,.ion-android-radio-button-on:before,.ion-android-refresh:before,.ion-android-remove-circle:before,.ion-android-remove:before,.ion-android-restaurant:before,.ion-android-sad:before,.ion-android-search:before,.ion-android-send:before,.ion-android-settings:before,.ion-android-share-alt:before,.ion-android-share:before,.ion-android-star-half:before,.ion-android-star-outline:before,.ion-android-star:before,.ion-android-stopwatch:before,.ion-android-subway:before,.ion-android-sunny:before,.ion-android-sync:before,.ion-android-textsms:before,.ion-android-time:before,.ion-android-train:before,.ion-android-unlock:before,.ion-android-upload:before,.ion-android-volume-down:before,.ion-android-volume-mute:before,.ion-android-volume-off:before,.ion-android-volume-up:before,.ion-android-walk:before,.ion-android-warning:before,.ion-android-watch:before,.ion-android-wifi:before,.ion-aperture:before,.ion-archive:before,.ion-arrow-down-a:before,.ion-arrow-down-b:before,.ion-arrow-down-c:before,.ion-arrow-expand:before,.ion-arrow-graph-down-left:before,.ion-arrow-graph-down-right:before,.ion-arrow-graph-up-left:before,.ion-arrow-graph-up-right:before,.ion-arrow-left-a:before,.ion-arrow-left-b:before,.ion-arrow-left-c:before,.ion-arrow-move:before,.ion-arrow-resize:before,.ion-arrow-return-left:before,.ion-arrow-return-right:before,.ion-arrow-right-a:before,.ion-arrow-right-b:before,.ion-arrow-right-c:before,.ion-arrow-shrink:before,.ion-arrow-swap:before,.ion-arrow-up-a:before,.ion-arrow-up-b:before,.ion-arrow-up-c:before,.ion-asterisk:before,.ion-at:before,.ion-backspace-outline:before,.ion-backspace:before,.ion-bag:before,.ion-battery-charging:before,.ion-battery-empty:before,.ion-battery-full:before,.ion-battery-half:before,.ion-battery-low:before,.ion-beaker:before,.ion-beer:before,.ion-bluetooth:before,.ion-bonfire:before,.ion-bookmark:before,.ion-bowtie:before,.ion-briefcase:before,.ion-bug:before,.ion-calculator:before,.ion-calendar:before,.ion-camera:before,.ion-card:before,.ion-cash:before,.ion-chatbox-working:before,.ion-chatbox:before,.ion-chatboxes:before,.ion-chatbubble-working:before,.ion-chatbubble:before,.ion-chatbubbles:before,.ion-checkmark-circled:before,.ion-checkmark-round:before,.ion-checkmark:before,.ion-chevron-down:before,.ion-chevron-left:before,.ion-chevron-right:before,.ion-chevron-up:before,.ion-clipboard:before,.ion-clock:before,.ion-close-circled:before,.ion-close-round:before,.ion-close:before,.ion-closed-captioning:before,.ion-cloud:before,.ion-code-download:before,.ion-code-working:before,.ion-code:before,.ion-coffee:before,.ion-compass:before,.ion-compose:before,.ion-connection-bars:before,.ion-contrast:before,.ion-crop:before,.ion-cube:before,.ion-disc:before,.ion-document-text:before,.ion-document:before,.ion-drag:before,.ion-earth:before,.ion-easel:before,.ion-edit:before,.ion-egg:before,.ion-eject:before,.ion-email-unread:before,.ion-email:before,.ion-erlenmeyer-flask-bubbles:before,.ion-erlenmeyer-flask:before,.ion-eye-disabled:before,.ion-eye:before,.ion-female:before,.ion-filing:before,.ion-film-marker:before,.ion-fireball:before,.ion-flag:before,.ion-flame:before,.ion-flash-off:before,.ion-flash:before,.ion-folder:before,.ion-fork-repo:before,.ion-fork:before,.ion-forward:before,.ion-funnel:before,.ion-gear-a:before,.ion-gear-b:before,.ion-grid:before,.ion-hammer:before,.ion-happy-outline:before,.ion-happy:before,.ion-headphone:before,.ion-heart-broken:before,.ion-heart:before,.ion-help-buoy:before,.ion-help-circled:before,.ion-help:before,.ion-home:before,.ion-icecream:before,.ion-image:before,.ion-images:before,.ion-information-circled:before,.ion-information:before,.ion-ionic:before,.ion-ios-alarm-outline:before,.ion-ios-alarm:before,.ion-ios-albums-outline:before,.ion-ios-albums:before,.ion-ios-americanfootball-outline:before,.ion-ios-americanfootball:before,.ion-ios-analytics-outline:before,.ion-ios-analytics:before,.ion-ios-arrow-back:before,.ion-ios-arrow-down:before,.ion-ios-arrow-forward:before,.ion-ios-arrow-left:before,.ion-ios-arrow-right:before,.ion-ios-arrow-thin-down:before,.ion-ios-arrow-thin-left:before,.ion-ios-arrow-thin-right:before,.ion-ios-arrow-thin-up:before,.ion-ios-arrow-up:before,.ion-ios-at-outline:before,.ion-ios-at:before,.ion-ios-barcode-outline:before,.ion-ios-barcode:before,.ion-ios-baseball-outline:before,.ion-ios-baseball:before,.ion-ios-basketball-outline:before,.ion-ios-basketball:before,.ion-ios-bell-outline:before,.ion-ios-bell:before,.ion-ios-body-outline:before,.ion-ios-body:before,.ion-ios-bolt-outline:before,.ion-ios-bolt:before,.ion-ios-book-outline:before,.ion-ios-book:before,.ion-ios-bookmarks-outline:before,.ion-ios-bookmarks:before,.ion-ios-box-outline:before,.ion-ios-box:before,.ion-ios-briefcase-outline:before,.ion-ios-briefcase:before,.ion-ios-browsers-outline:before,.ion-ios-browsers:before,.ion-ios-calculator-outline:before,.ion-ios-calculator:before,.ion-ios-calendar-outline:before,.ion-ios-calendar:before,.ion-ios-camera-outline:before,.ion-ios-camera:before,.ion-ios-cart-outline:before,.ion-ios-cart:before,.ion-ios-chatboxes-outline:before,.ion-ios-chatboxes:before,.ion-ios-chatbubble-outline:before,.ion-ios-chatbubble:before,.ion-ios-checkmark-empty:before,.ion-ios-checkmark-outline:before,.ion-ios-checkmark:before,.ion-ios-circle-filled:before,.ion-ios-circle-outline:before,.ion-ios-clock-outline:before,.ion-ios-clock:before,.ion-ios-close-empty:before,.ion-ios-close-outline:before,.ion-ios-close:before,.ion-ios-cloud-download-outline:before,.ion-ios-cloud-download:before,.ion-ios-cloud-outline:before,.ion-ios-cloud-upload-outline:before,.ion-ios-cloud-upload:before,.ion-ios-cloud:before,.ion-ios-cloudy-night-outline:before,.ion-ios-cloudy-night:before,.ion-ios-cloudy-outline:before,.ion-ios-cloudy:before,.ion-ios-cog-outline:before,.ion-ios-cog:before,.ion-ios-color-filter-outline:before,.ion-ios-color-filter:before,.ion-ios-color-wand-outline:before,.ion-ios-color-wand:before,.ion-ios-compose-outline:before,.ion-ios-compose:before,.ion-ios-contact-outline:before,.ion-ios-contact:before,.ion-ios-copy-outline:before,.ion-ios-copy:before,.ion-ios-crop-strong:before,.ion-ios-crop:before,.ion-ios-download-outline:before,.ion-ios-download:before,.ion-ios-drag:before,.ion-ios-email-outline:before,.ion-ios-email:before,.ion-ios-eye-outline:before,.ion-ios-eye:before,.ion-ios-fastforward-outline:before,.ion-ios-fastforward:before,.ion-ios-filing-outline:before,.ion-ios-filing:before,.ion-ios-film-outline:before,.ion-ios-film:before,.ion-ios-flag-outline:before,.ion-ios-flag:before,.ion-ios-flame-outline:before,.ion-ios-flame:before,.ion-ios-flask-outline:before,.ion-ios-flask:before,.ion-ios-flower-outline:before,.ion-ios-flower:before,.ion-ios-folder-outline:before,.ion-ios-folder:before,.ion-ios-football-outline:before,.ion-ios-football:before,.ion-ios-game-controller-a-outline:before,.ion-ios-game-controller-a:before,.ion-ios-game-controller-b-outline:before,.ion-ios-game-controller-b:before,.ion-ios-gear-outline:before,.ion-ios-gear:before,.ion-ios-glasses-outline:before,.ion-ios-glasses:before,.ion-ios-grid-view-outline:before,.ion-ios-grid-view:before,.ion-ios-heart-outline:before,.ion-ios-heart:before,.ion-ios-help-empty:before,.ion-ios-help-outline:before,.ion-ios-help:before,.ion-ios-home-outline:before,.ion-ios-home:before,.ion-ios-infinite-outline:before,.ion-ios-infinite:before,.ion-ios-information-empty:before,.ion-ios-information-outline:before,.ion-ios-information:before,.ion-ios-ionic-outline:before,.ion-ios-keypad-outline:before,.ion-ios-keypad:before,.ion-ios-lightbulb-outline:before,.ion-ios-lightbulb:before,.ion-ios-list-outline:before,.ion-ios-list:before,.ion-ios-location-outline:before,.ion-ios-location:before,.ion-ios-locked-outline:before,.ion-ios-locked:before,.ion-ios-loop-strong:before,.ion-ios-loop:before,.ion-ios-medical-outline:before,.ion-ios-medical:before,.ion-ios-medkit-outline:before,.ion-ios-medkit:before,.ion-ios-mic-off:before,.ion-ios-mic-outline:before,.ion-ios-mic:before,.ion-ios-minus-empty:before,.ion-ios-minus-outline:before,.ion-ios-minus:before,.ion-ios-monitor-outline:before,.ion-ios-monitor:before,.ion-ios-moon-outline:before,.ion-ios-moon:before,.ion-ios-more-outline:before,.ion-ios-more:before,.ion-ios-musical-note:before,.ion-ios-musical-notes:before,.ion-ios-navigate-outline:before,.ion-ios-navigate:before,.ion-ios-nutrition-outline:before,.ion-ios-nutrition:before,.ion-ios-paper-outline:before,.ion-ios-paper:before,.ion-ios-paperplane-outline:before,.ion-ios-paperplane:before,.ion-ios-partlysunny-outline:before,.ion-ios-partlysunny:before,.ion-ios-pause-outline:before,.ion-ios-pause:before,.ion-ios-paw-outline:before,.ion-ios-paw:before,.ion-ios-people-outline:before,.ion-ios-people:before,.ion-ios-person-outline:before,.ion-ios-person:before,.ion-ios-personadd-outline:before,.ion-ios-personadd:before,.ion-ios-photos-outline:before,.ion-ios-photos:before,.ion-ios-pie-outline:before,.ion-ios-pie:before,.ion-ios-pint-outline:before,.ion-ios-pint:before,.ion-ios-play-outline:before,.ion-ios-play:before,.ion-ios-plus-empty:before,.ion-ios-plus-outline:before,.ion-ios-plus:before,.ion-ios-pricetag-outline:before,.ion-ios-pricetag:before,.ion-ios-pricetags-outline:before,.ion-ios-pricetags:before,.ion-ios-printer-outline:before,.ion-ios-printer:before,.ion-ios-pulse-strong:before,.ion-ios-pulse:before,.ion-ios-rainy-outline:before,.ion-ios-rainy:before,.ion-ios-recording-outline:before,.ion-ios-recording:before,.ion-ios-redo-outline:before,.ion-ios-redo:before,.ion-ios-refresh-empty:before,.ion-ios-refresh-outline:before,.ion-ios-refresh:before,.ion-ios-reload:before,.ion-ios-reverse-camera-outline:before,.ion-ios-reverse-camera:before,.ion-ios-rewind-outline:before,.ion-ios-rewind:before,.ion-ios-rose-outline:before,.ion-ios-rose:before,.ion-ios-search-strong:before,.ion-ios-search:before,.ion-ios-settings-strong:before,.ion-ios-settings:before,.ion-ios-shuffle-strong:before,.ion-ios-shuffle:before,.ion-ios-skipbackward-outline:before,.ion-ios-skipbackward:before,.ion-ios-skipforward-outline:before,.ion-ios-skipforward:before,.ion-ios-snowy:before,.ion-ios-speedometer-outline:before,.ion-ios-speedometer:before,.ion-ios-star-half:before,.ion-ios-star-outline:before,.ion-ios-star:before,.ion-ios-stopwatch-outline:before,.ion-ios-stopwatch:before,.ion-ios-sunny-outline:before,.ion-ios-sunny:before,.ion-ios-telephone-outline:before,.ion-ios-telephone:before,.ion-ios-tennisball-outline:before,.ion-ios-tennisball:before,.ion-ios-thunderstorm-outline:before,.ion-ios-thunderstorm:before,.ion-ios-time-outline:before,.ion-ios-time:before,.ion-ios-timer-outline:before,.ion-ios-timer:before,.ion-ios-toggle-outline:before,.ion-ios-toggle:before,.ion-ios-trash-outline:before,.ion-ios-trash:before,.ion-ios-undo-outline:before,.ion-ios-undo:before,.ion-ios-unlocked-outline:before,.ion-ios-unlocked:before,.ion-ios-upload-outline:before,.ion-ios-upload:before,.ion-ios-videocam-outline:before,.ion-ios-videocam:before,.ion-ios-volume-high:before,.ion-ios-volume-low:before,.ion-ios-wineglass-outline:before,.ion-ios-wineglass:before,.ion-ios-world-outline:before,.ion-ios-world:before,.ion-ipad:before,.ion-iphone:before,.ion-ipod:before,.ion-jet:before,.ion-key:before,.ion-knife:before,.ion-laptop:before,.ion-leaf:before,.ion-levels:before,.ion-lightbulb:before,.ion-link:before,.ion-load-a:before,.ion-load-b:before,.ion-load-c:before,.ion-load-d:before,.ion-location:before,.ion-lock-combination:before,.ion-locked:before,.ion-log-in:before,.ion-log-out:before,.ion-loop:before,.ion-magnet:before,.ion-male:before,.ion-man:before,.ion-map:before,.ion-medkit:before,.ion-merge:before,.ion-mic-a:before,.ion-mic-b:before,.ion-mic-c:before,.ion-minus-circled:before,.ion-minus-round:before,.ion-minus:before,.ion-model-s:before,.ion-monitor:before,.ion-more:before,.ion-mouse:before,.ion-music-note:before,.ion-navicon-round:before,.ion-navicon:before,.ion-navigate:before,.ion-network:before,.ion-no-smoking:before,.ion-nuclear:before,.ion-outlet:before,.ion-paintbrush:before,.ion-paintbucket:before,.ion-paper-airplane:before,.ion-paperclip:before,.ion-pause:before,.ion-person-add:before,.ion-person-stalker:before,.ion-person:before,.ion-pie-graph:before,.ion-pin:before,.ion-pinpoint:before,.ion-pizza:before,.ion-plane:before,.ion-planet:before,.ion-play:before,.ion-playstation:before,.ion-plus-circled:before,.ion-plus-round:before,.ion-plus:before,.ion-podium:before,.ion-pound:before,.ion-power:before,.ion-pricetag:before,.ion-pricetags:before,.ion-printer:before,.ion-pull-request:before,.ion-qr-scanner:before,.ion-quote:before,.ion-radio-waves:before,.ion-record:before,.ion-refresh:before,.ion-reply-all:before,.ion-reply:before,.ion-ribbon-a:before,.ion-ribbon-b:before,.ion-sad-outline:before,.ion-sad:before,.ion-scissors:before,.ion-search:before,.ion-settings:before,.ion-share:before,.ion-shuffle:before,.ion-skip-backward:before,.ion-skip-forward:before,.ion-social-android-outline:before,.ion-social-android:before,.ion-social-angular-outline:before,.ion-social-angular:before,.ion-social-apple-outline:before,.ion-social-apple:before,.ion-social-bitcoin-outline:before,.ion-social-bitcoin:before,.ion-social-buffer-outline:before,.ion-social-buffer:before,.ion-social-chrome-outline:before,.ion-social-chrome:before,.ion-social-codepen-outline:before,.ion-social-codepen:before,.ion-social-css3-outline:before,.ion-social-css3:before,.ion-social-designernews-outline:before,.ion-social-designernews:before,.ion-social-dribbble-outline:before,.ion-social-dribbble:before,.ion-social-dropbox-outline:before,.ion-social-dropbox:before,.ion-social-euro-outline:before,.ion-social-euro:before,.ion-social-facebook-outline:before,.ion-social-facebook:before,.ion-social-foursquare-outline:before,.ion-social-foursquare:before,.ion-social-freebsd-devil:before,.ion-social-github-outline:before,.ion-social-github:before,.ion-social-google-outline:before,.ion-social-google:before,.ion-social-googleplus-outline:before,.ion-social-googleplus:before,.ion-social-hackernews-outline:before,.ion-social-hackernews:before,.ion-social-html5-outline:before,.ion-social-html5:before,.ion-social-instagram-outline:before,.ion-social-instagram:before,.ion-social-javascript-outline:before,.ion-social-javascript:before,.ion-social-linkedin-outline:before,.ion-social-linkedin:before,.ion-social-markdown:before,.ion-social-nodejs:before,.ion-social-octocat:before,.ion-social-pinterest-outline:before,.ion-social-pinterest:before,.ion-social-python:before,.ion-social-reddit-outline:before,.ion-social-reddit:before,.ion-social-rss-outline:before,.ion-social-rss:before,.ion-social-sass:before,.ion-social-skype-outline:before,.ion-social-skype:before,.ion-social-snapchat-outline:before,.ion-social-snapchat:before,.ion-social-tumblr-outline:before,.ion-social-tumblr:before,.ion-social-tux:before,.ion-social-twitch-outline:before,.ion-social-twitch:before,.ion-social-twitter-outline:before,.ion-social-twitter:before,.ion-social-usd-outline:before,.ion-social-usd:before,.ion-social-vimeo-outline:before,.ion-social-vimeo:before,.ion-social-whatsapp-outline:before,.ion-social-whatsapp:before,.ion-social-windows-outline:before,.ion-social-windows:before,.ion-social-wordpress-outline:before,.ion-social-wordpress:before,.ion-social-yahoo-outline:before,.ion-social-yahoo:before,.ion-social-yen-outline:before,.ion-social-yen:before,.ion-social-youtube-outline:before,.ion-social-youtube:before,.ion-soup-can-outline:before,.ion-soup-can:before,.ion-speakerphone:before,.ion-speedometer:before,.ion-spoon:before,.ion-star:before,.ion-stats-bars:before,.ion-steam:before,.ion-stop:before,.ion-thermometer:before,.ion-thumbsdown:before,.ion-thumbsup:before,.ion-toggle-filled:before,.ion-toggle:before,.ion-transgender:before,.ion-trash-a:before,.ion-trash-b:before,.ion-trophy:before,.ion-tshirt-outline:before,.ion-tshirt:before,.ion-umbrella:before,.ion-university:before,.ion-unlocked:before,.ion-upload:before,.ion-usb:before,.ion-videocamera:before,.ion-volume-high:before,.ion-volume-low:before,.ion-volume-medium:before,.ion-volume-mute:before,.ion-wand:before,.ion-waterdrop:before,.ion-wifi:before,.ion-wineglass:before,.ion-woman:before,.ion-wrench:before,.ion-xbox:before,.ionicons{display:inline-block;font-family:Ionicons;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;text-rendering:auto;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ion-alert:before{content:"\f101"}.ion-alert-circled:before{content:"\f100"}.ion-android-add:before{content:"\f2c7"}.ion-android-add-circle:before{content:"\f359"}.ion-android-alarm-clock:before{content:"\f35a"}.ion-android-alert:before{content:"\f35b"}.ion-android-apps:before{content:"\f35c"}.ion-android-archive:before{content:"\f2c9"}.ion-android-arrow-back:before{content:"\f2ca"}.ion-android-arrow-down:before{content:"\f35d"}.ion-android-arrow-dropdown:before{content:"\f35f"}.ion-android-arrow-dropdown-circle:before{content:"\f35e"}.ion-android-arrow-dropleft:before{content:"\f361"}.ion-android-arrow-dropleft-circle:before{content:"\f360"}.ion-android-arrow-dropright:before{content:"\f363"}.ion-android-arrow-dropright-circle:before{content:"\f362"}.ion-android-arrow-dropup:before{content:"\f365"}.ion-android-arrow-dropup-circle:before{content:"\f364"}.ion-android-arrow-forward:before{content:"\f30f"}.ion-android-arrow-up:before{content:"\f366"}.ion-android-attach:before{content:"\f367"}.ion-android-bar:before{content:"\f368"}.ion-android-bicycle:before{content:"\f369"}.ion-android-boat:before{content:"\f36a"}.ion-android-bookmark:before{content:"\f36b"}.ion-android-bulb:before{content:"\f36c"}.ion-android-bus:before{content:"\f36d"}.ion-android-calendar:before{content:"\f2d1"}.ion-android-call:before{content:"\f2d2"}.ion-android-camera:before{content:"\f2d3"}.ion-android-cancel:before{content:"\f36e"}.ion-android-car:before{content:"\f36f"}.ion-android-cart:before{content:"\f370"}.ion-android-chat:before{content:"\f2d4"}.ion-android-checkbox:before{content:"\f374"}.ion-android-checkbox-blank:before{content:"\f371"}.ion-android-checkbox-outline:before{content:"\f373"}.ion-android-checkbox-outline-blank:before{content:"\f372"}.ion-android-checkmark-circle:before{content:"\f375"}.ion-android-clipboard:before{content:"\f376"}.ion-android-close:before{content:"\f2d7"}.ion-android-cloud:before{content:"\f37a"}.ion-android-cloud-circle:before{content:"\f377"}.ion-android-cloud-done:before{content:"\f378"}.ion-android-cloud-outline:before{content:"\f379"}.ion-android-color-palette:before{content:"\f37b"}.ion-android-compass:before{content:"\f37c"}.ion-android-contact:before{content:"\f2d8"}.ion-android-contacts:before{content:"\f2d9"}.ion-android-contract:before{content:"\f37d"}.ion-android-create:before{content:"\f37e"}.ion-android-delete:before{content:"\f37f"}.ion-android-desktop:before{content:"\f380"}.ion-android-document:before{content:"\f381"}.ion-android-done:before{content:"\f383"}.ion-android-done-all:before{content:"\f382"}.ion-android-download:before{content:"\f2dd"}.ion-android-drafts:before{content:"\f384"}.ion-android-exit:before{content:"\f385"}.ion-android-expand:before{content:"\f386"}.ion-android-favorite:before{content:"\f388"}.ion-android-favorite-outline:before{content:"\f387"}.ion-android-film:before{content:"\f389"}.ion-android-folder:before{content:"\f2e0"}.ion-android-folder-open:before{content:"\f38a"}.ion-android-funnel:before{content:"\f38b"}.ion-android-globe:before{content:"\f38c"}.ion-android-hand:before{content:"\f2e3"}.ion-android-hangout:before{content:"\f38d"}.ion-android-happy:before{content:"\f38e"}.ion-android-home:before{content:"\f38f"}.ion-android-image:before{content:"\f2e4"}.ion-android-laptop:before{content:"\f390"}.ion-android-list:before{content:"\f391"}.ion-android-locate:before{content:"\f2e9"}.ion-android-lock:before{content:"\f392"}.ion-android-mail:before{content:"\f2eb"}.ion-android-map:before{content:"\f393"}.ion-android-menu:before{content:"\f394"}.ion-android-microphone:before{content:"\f2ec"}.ion-android-microphone-off:before{content:"\f395"}.ion-android-more-horizontal:before{content:"\f396"}.ion-android-more-vertical:before{content:"\f397"}.ion-android-navigate:before{content:"\f398"}.ion-android-notifications:before{content:"\f39b"}.ion-android-notifications-none:before{content:"\f399"}.ion-android-notifications-off:before{content:"\f39a"}.ion-android-open:before{content:"\f39c"}.ion-android-options:before{content:"\f39d"}.ion-android-people:before{content:"\f39e"}.ion-android-person:before{content:"\f3a0"}.ion-android-person-add:before{content:"\f39f"}.ion-android-phone-landscape:before{content:"\f3a1"}.ion-android-phone-portrait:before{content:"\f3a2"}.ion-android-pin:before{content:"\f3a3"}.ion-android-plane:before{content:"\f3a4"}.ion-android-playstore:before{content:"\f2f0"}.ion-android-print:before{content:"\f3a5"}.ion-android-radio-button-off:before{content:"\f3a6"}.ion-android-radio-button-on:before{content:"\f3a7"}.ion-android-refresh:before{content:"\f3a8"}.ion-android-remove:before{content:"\f2f4"}.ion-android-remove-circle:before{content:"\f3a9"}.ion-android-restaurant:before{content:"\f3aa"}.ion-android-sad:before{content:"\f3ab"}.ion-android-search:before{content:"\f2f5"}.ion-android-send:before{content:"\f2f6"}.ion-android-settings:before{content:"\f2f7"}.ion-android-share:before{content:"\f2f8"}.ion-android-share-alt:before{content:"\f3ac"}.ion-android-star:before{content:"\f2fc"}.ion-android-star-half:before{content:"\f3ad"}.ion-android-star-outline:before{content:"\f3ae"}.ion-android-stopwatch:before{content:"\f2fd"}.ion-android-subway:before{content:"\f3af"}.ion-android-sunny:before{content:"\f3b0"}.ion-android-sync:before{content:"\f3b1"}.ion-android-textsms:before{content:"\f3b2"}.ion-android-time:before{content:"\f3b3"}.ion-android-train:before{content:"\f3b4"}.ion-android-unlock:before{content:"\f3b5"}.ion-android-upload:before{content:"\f3b6"}.ion-android-volume-down:before{content:"\f3b7"}.ion-android-volume-mute:before{content:"\f3b8"}.ion-android-volume-off:before{content:"\f3b9"}.ion-android-volume-up:before{content:"\f3ba"}.ion-android-walk:before{content:"\f3bb"}.ion-android-warning:before{content:"\f3bc"}.ion-android-watch:before{content:"\f3bd"}.ion-android-wifi:before{content:"\f305"}.ion-aperture:before{content:"\f313"}.ion-archive:before{content:"\f102"}.ion-arrow-down-a:before{content:"\f103"}.ion-arrow-down-b:before{content:"\f104"}.ion-arrow-down-c:before{content:"\f105"}.ion-arrow-expand:before{content:"\f25e"}.ion-arrow-graph-down-left:before{content:"\f25f"}.ion-arrow-graph-down-right:before{content:"\f260"}.ion-arrow-graph-up-left:before{content:"\f261"}.ion-arrow-graph-up-right:before{content:"\f262"}.ion-arrow-left-a:before{content:"\f106"}.ion-arrow-left-b:before{content:"\f107"}.ion-arrow-left-c:before{content:"\f108"}.ion-arrow-move:before{content:"\f263"}.ion-arrow-resize:before{content:"\f264"}.ion-arrow-return-left:before{content:"\f265"}.ion-arrow-return-right:before{content:"\f266"}.ion-arrow-right-a:before{content:"\f109"}.ion-arrow-right-b:before{content:"\f10a"}.ion-arrow-right-c:before{content:"\f10b"}.ion-arrow-shrink:before{content:"\f267"}.ion-arrow-swap:before{content:"\f268"}.ion-arrow-up-a:before{content:"\f10c"}.ion-arrow-up-b:before{content:"\f10d"}.ion-arrow-up-c:before{content:"\f10e"}.ion-asterisk:before{content:"\f314"}.ion-at:before{content:"\f10f"}.ion-backspace:before{content:"\f3bf"}.ion-backspace-outline:before{content:"\f3be"}.ion-bag:before{content:"\f110"}.ion-battery-charging:before{content:"\f111"}.ion-battery-empty:before{content:"\f112"}.ion-battery-full:before{content:"\f113"}.ion-battery-half:before{content:"\f114"}.ion-battery-low:before{content:"\f115"}.ion-beaker:before{content:"\f269"}.ion-beer:before{content:"\f26a"}.ion-bluetooth:before{content:"\f116"}.ion-bonfire:before{content:"\f315"}.ion-bookmark:before{content:"\f26b"}.ion-bowtie:before{content:"\f3c0"}.ion-briefcase:before{content:"\f26c"}.ion-bug:before{content:"\f2be"}.ion-calculator:before{content:"\f26d"}.ion-calendar:before{content:"\f117"}.ion-camera:before{content:"\f118"}.ion-card:before{content:"\f119"}.ion-cash:before{content:"\f316"}.ion-chatbox:before{content:"\f11b"}.ion-chatbox-working:before{content:"\f11a"}.ion-chatboxes:before{content:"\f11c"}.ion-chatbubble:before{content:"\f11e"}.ion-chatbubble-working:before{content:"\f11d"}.ion-chatbubbles:before{content:"\f11f"}.ion-checkmark:before{content:"\f122"}.ion-checkmark-circled:before{content:"\f120"}.ion-checkmark-round:before{content:"\f121"}.ion-chevron-down:before{content:"\f123"}.ion-chevron-left:before{content:"\f124"}.ion-chevron-right:before{content:"\f125"}.ion-chevron-up:before{content:"\f126"}.ion-clipboard:before{content:"\f127"}.ion-clock:before{content:"\f26e"}.ion-close:before{content:"\f12a"}.ion-close-circled:before{content:"\f128"}.ion-close-round:before{content:"\f129"}.ion-closed-captioning:before{content:"\f317"}.ion-cloud:before{content:"\f12b"}.ion-code:before{content:"\f271"}.ion-code-download:before{content:"\f26f"}.ion-code-working:before{content:"\f270"}.ion-coffee:before{content:"\f272"}.ion-compass:before{content:"\f273"}.ion-compose:before{content:"\f12c"}.ion-connection-bars:before{content:"\f274"}.ion-contrast:before{content:"\f275"}.ion-crop:before{content:"\f3c1"}.ion-cube:before{content:"\f318"}.ion-disc:before{content:"\f12d"}.ion-document:before{content:"\f12f"}.ion-document-text:before{content:"\f12e"}.ion-drag:before{content:"\f130"}.ion-earth:before{content:"\f276"}.ion-easel:before{content:"\f3c2"}.ion-edit:before{content:"\f2bf"}.ion-egg:before{content:"\f277"}.ion-eject:before{content:"\f131"}.ion-email:before{content:"\f132"}.ion-email-unread:before{content:"\f3c3"}.ion-erlenmeyer-flask:before{content:"\f3c5"}.ion-erlenmeyer-flask-bubbles:before{content:"\f3c4"}.ion-eye:before{content:"\f133"}.ion-eye-disabled:before{content:"\f306"}.ion-female:before{content:"\f278"}.ion-filing:before{content:"\f134"}.ion-film-marker:before{content:"\f135"}.ion-fireball:before{content:"\f319"}.ion-flag:before{content:"\f279"}.ion-flame:before{content:"\f31a"}.ion-flash:before{content:"\f137"}.ion-flash-off:before{content:"\f136"}.ion-folder:before{content:"\f139"}.ion-fork:before{content:"\f27a"}.ion-fork-repo:before{content:"\f2c0"}.ion-forward:before{content:"\f13a"}.ion-funnel:before{content:"\f31b"}.ion-gear-a:before{content:"\f13d"}.ion-gear-b:before{content:"\f13e"}.ion-grid:before{content:"\f13f"}.ion-hammer:before{content:"\f27b"}.ion-happy:before{content:"\f31c"}.ion-happy-outline:before{content:"\f3c6"}.ion-headphone:before{content:"\f140"}.ion-heart:before{content:"\f141"}.ion-heart-broken:before{content:"\f31d"}.ion-help:before{content:"\f143"}.ion-help-buoy:before{content:"\f27c"}.ion-help-circled:before{content:"\f142"}.ion-home:before{content:"\f144"}.ion-icecream:before{content:"\f27d"}.ion-image:before{content:"\f147"}.ion-images:before{content:"\f148"}.ion-information:before{content:"\f14a"}.ion-information-circled:before{content:"\f149"}.ion-ionic:before{content:"\f14b"}.ion-ios-alarm:before{content:"\f3c8"}.ion-ios-alarm-outline:before{content:"\f3c7"}.ion-ios-albums:before{content:"\f3ca"}.ion-ios-albums-outline:before{content:"\f3c9"}.ion-ios-americanfootball:before{content:"\f3cc"}.ion-ios-americanfootball-outline:before{content:"\f3cb"}.ion-ios-analytics:before{content:"\f3ce"}.ion-ios-analytics-outline:before{content:"\f3cd"}.ion-ios-arrow-back:before{content:"\f3cf"}.ion-ios-arrow-down:before{content:"\f3d0"}.ion-ios-arrow-forward:before{content:"\f3d1"}.ion-ios-arrow-left:before{content:"\f3d2"}.ion-ios-arrow-right:before{content:"\f3d3"}.ion-ios-arrow-thin-down:before{content:"\f3d4"}.ion-ios-arrow-thin-left:before{content:"\f3d5"}.ion-ios-arrow-thin-right:before{content:"\f3d6"}.ion-ios-arrow-thin-up:before{content:"\f3d7"}.ion-ios-arrow-up:before{content:"\f3d8"}.ion-ios-at:before{content:"\f3da"}.ion-ios-at-outline:before{content:"\f3d9"}.ion-ios-barcode:before{content:"\f3dc"}.ion-ios-barcode-outline:before{content:"\f3db"}.ion-ios-baseball:before{content:"\f3de"}.ion-ios-baseball-outline:before{content:"\f3dd"}.ion-ios-basketball:before{content:"\f3e0"}.ion-ios-basketball-outline:before{content:"\f3df"}.ion-ios-bell:before{content:"\f3e2"}.ion-ios-bell-outline:before{content:"\f3e1"}.ion-ios-body:before{content:"\f3e4"}.ion-ios-body-outline:before{content:"\f3e3"}.ion-ios-bolt:before{content:"\f3e6"}.ion-ios-bolt-outline:before{content:"\f3e5"}.ion-ios-book:before{content:"\f3e8"}.ion-ios-book-outline:before{content:"\f3e7"}.ion-ios-bookmarks:before{content:"\f3ea"}.ion-ios-bookmarks-outline:before{content:"\f3e9"}.ion-ios-box:before{content:"\f3ec"}.ion-ios-box-outline:before{content:"\f3eb"}.ion-ios-briefcase:before{content:"\f3ee"}.ion-ios-briefcase-outline:before{content:"\f3ed"}.ion-ios-browsers:before{content:"\f3f0"}.ion-ios-browsers-outline:before{content:"\f3ef"}.ion-ios-calculator:before{content:"\f3f2"}.ion-ios-calculator-outline:before{content:"\f3f1"}.ion-ios-calendar:before{content:"\f3f4"}.ion-ios-calendar-outline:before{content:"\f3f3"}.ion-ios-camera:before{content:"\f3f6"}.ion-ios-camera-outline:before{content:"\f3f5"}.ion-ios-cart:before{content:"\f3f8"}.ion-ios-cart-outline:before{content:"\f3f7"}.ion-ios-chatboxes:before{content:"\f3fa"}.ion-ios-chatboxes-outline:before{content:"\f3f9"}.ion-ios-chatbubble:before{content:"\f3fc"}.ion-ios-chatbubble-outline:before{content:"\f3fb"}.ion-ios-checkmark:before{content:"\f3ff"}.ion-ios-checkmark-empty:before{content:"\f3fd"}.ion-ios-checkmark-outline:before{content:"\f3fe"}.ion-ios-circle-filled:before{content:"\f400"}.ion-ios-circle-outline:before{content:"\f401"}.ion-ios-clock:before{content:"\f403"}.ion-ios-clock-outline:before{content:"\f402"}.ion-ios-close:before{content:"\f406"}.ion-ios-close-empty:before{content:"\f404"}.ion-ios-close-outline:before{content:"\f405"}.ion-ios-cloud:before{content:"\f40c"}.ion-ios-cloud-download:before{content:"\f408"}.ion-ios-cloud-download-outline:before{content:"\f407"}.ion-ios-cloud-outline:before{content:"\f409"}.ion-ios-cloud-upload:before{content:"\f40b"}.ion-ios-cloud-upload-outline:before{content:"\f40a"}.ion-ios-cloudy:before{content:"\f410"}.ion-ios-cloudy-night:before{content:"\f40e"}.ion-ios-cloudy-night-outline:before{content:"\f40d"}.ion-ios-cloudy-outline:before{content:"\f40f"}.ion-ios-cog:before{content:"\f412"}.ion-ios-cog-outline:before{content:"\f411"}.ion-ios-color-filter:before{content:"\f414"}.ion-ios-color-filter-outline:before{content:"\f413"}.ion-ios-color-wand:before{content:"\f416"}.ion-ios-color-wand-outline:before{content:"\f415"}.ion-ios-compose:before{content:"\f418"}.ion-ios-compose-outline:before{content:"\f417"}.ion-ios-contact:before{content:"\f41a"}.ion-ios-contact-outline:before{content:"\f419"}.ion-ios-copy:before{content:"\f41c"}.ion-ios-copy-outline:before{content:"\f41b"}.ion-ios-crop:before{content:"\f41e"}.ion-ios-crop-strong:before{content:"\f41d"}.ion-ios-download:before{content:"\f420"}.ion-ios-download-outline:before{content:"\f41f"}.ion-ios-drag:before{content:"\f421"}.ion-ios-email:before{content:"\f423"}.ion-ios-email-outline:before{content:"\f422"}.ion-ios-eye:before{content:"\f425"}.ion-ios-eye-outline:before{content:"\f424"}.ion-ios-fastforward:before{content:"\f427"}.ion-ios-fastforward-outline:before{content:"\f426"}.ion-ios-filing:before{content:"\f429"}.ion-ios-filing-outline:before{content:"\f428"}.ion-ios-film:before{content:"\f42b"}.ion-ios-film-outline:before{content:"\f42a"}.ion-ios-flag:before{content:"\f42d"}.ion-ios-flag-outline:before{content:"\f42c"}.ion-ios-flame:before{content:"\f42f"}.ion-ios-flame-outline:before{content:"\f42e"}.ion-ios-flask:before{content:"\f431"}.ion-ios-flask-outline:before{content:"\f430"}.ion-ios-flower:before{content:"\f433"}.ion-ios-flower-outline:before{content:"\f432"}.ion-ios-folder:before{content:"\f435"}.ion-ios-folder-outline:before{content:"\f434"}.ion-ios-football:before{content:"\f437"}.ion-ios-football-outline:before{content:"\f436"}.ion-ios-game-controller-a:before{content:"\f439"}.ion-ios-game-controller-a-outline:before{content:"\f438"}.ion-ios-game-controller-b:before{content:"\f43b"}.ion-ios-game-controller-b-outline:before{content:"\f43a"}.ion-ios-gear:before{content:"\f43d"}.ion-ios-gear-outline:before{content:"\f43c"}.ion-ios-glasses:before{content:"\f43f"}.ion-ios-glasses-outline:before{content:"\f43e"}.ion-ios-grid-view:before{content:"\f441"}.ion-ios-grid-view-outline:before{content:"\f440"}.ion-ios-heart:before{content:"\f443"}.ion-ios-heart-outline:before{content:"\f442"}.ion-ios-help:before{content:"\f446"}.ion-ios-help-empty:before{content:"\f444"}.ion-ios-help-outline:before{content:"\f445"}.ion-ios-home:before{content:"\f448"}.ion-ios-home-outline:before{content:"\f447"}.ion-ios-infinite:before{content:"\f44a"}.ion-ios-infinite-outline:before{content:"\f449"}.ion-ios-information:before{content:"\f44d"}.ion-ios-information-empty:before{content:"\f44b"}.ion-ios-information-outline:before{content:"\f44c"}.ion-ios-ionic-outline:before{content:"\f44e"}.ion-ios-keypad:before{content:"\f450"}.ion-ios-keypad-outline:before{content:"\f44f"}.ion-ios-lightbulb:before{content:"\f452"}.ion-ios-lightbulb-outline:before{content:"\f451"}.ion-ios-list:before{content:"\f454"}.ion-ios-list-outline:before{content:"\f453"}.ion-ios-location:before{content:"\f456"}.ion-ios-location-outline:before{content:"\f455"}.ion-ios-locked:before{content:"\f458"}.ion-ios-locked-outline:before{content:"\f457"}.ion-ios-loop:before{content:"\f45a"}.ion-ios-loop-strong:before{content:"\f459"}.ion-ios-medical:before{content:"\f45c"}.ion-ios-medical-outline:before{content:"\f45b"}.ion-ios-medkit:before{content:"\f45e"}.ion-ios-medkit-outline:before{content:"\f45d"}.ion-ios-mic:before{content:"\f461"}.ion-ios-mic-off:before{content:"\f45f"}.ion-ios-mic-outline:before{content:"\f460"}.ion-ios-minus:before{content:"\f464"}.ion-ios-minus-empty:before{content:"\f462"}.ion-ios-minus-outline:before{content:"\f463"}.ion-ios-monitor:before{content:"\f466"}.ion-ios-monitor-outline:before{content:"\f465"}.ion-ios-moon:before{content:"\f468"}.ion-ios-moon-outline:before{content:"\f467"}.ion-ios-more:before{content:"\f46a"}.ion-ios-more-outline:before{content:"\f469"}.ion-ios-musical-note:before{content:"\f46b"}.ion-ios-musical-notes:before{content:"\f46c"}.ion-ios-navigate:before{content:"\f46e"}.ion-ios-navigate-outline:before{content:"\f46d"}.ion-ios-nutrition:before{content:"\f470"}.ion-ios-nutrition-outline:before{content:"\f46f"}.ion-ios-paper:before{content:"\f472"}.ion-ios-paper-outline:before{content:"\f471"}.ion-ios-paperplane:before{content:"\f474"}.ion-ios-paperplane-outline:before{content:"\f473"}.ion-ios-partlysunny:before{content:"\f476"}.ion-ios-partlysunny-outline:before{content:"\f475"}.ion-ios-pause:before{content:"\f478"}.ion-ios-pause-outline:before{content:"\f477"}.ion-ios-paw:before{content:"\f47a"}.ion-ios-paw-outline:before{content:"\f479"}.ion-ios-people:before{content:"\f47c"}.ion-ios-people-outline:before{content:"\f47b"}.ion-ios-person:before{content:"\f47e"}.ion-ios-person-outline:before{content:"\f47d"}.ion-ios-personadd:before{content:"\f480"}.ion-ios-personadd-outline:before{content:"\f47f"}.ion-ios-photos:before{content:"\f482"}.ion-ios-photos-outline:before{content:"\f481"}.ion-ios-pie:before{content:"\f484"}.ion-ios-pie-outline:before{content:"\f483"}.ion-ios-pint:before{content:"\f486"}.ion-ios-pint-outline:before{content:"\f485"}.ion-ios-play:before{content:"\f488"}.ion-ios-play-outline:before{content:"\f487"}.ion-ios-plus:before{content:"\f48b"}.ion-ios-plus-empty:before{content:"\f489"}.ion-ios-plus-outline:before{content:"\f48a"}.ion-ios-pricetag:before{content:"\f48d"}.ion-ios-pricetag-outline:before{content:"\f48c"}.ion-ios-pricetags:before{content:"\f48f"}.ion-ios-pricetags-outline:before{content:"\f48e"}.ion-ios-printer:before{content:"\f491"}.ion-ios-printer-outline:before{content:"\f490"}.ion-ios-pulse:before{content:"\f493"}.ion-ios-pulse-strong:before{content:"\f492"}.ion-ios-rainy:before{content:"\f495"}.ion-ios-rainy-outline:before{content:"\f494"}.ion-ios-recording:before{content:"\f497"}.ion-ios-recording-outline:before{content:"\f496"}.ion-ios-redo:before{content:"\f499"}.ion-ios-redo-outline:before{content:"\f498"}.ion-ios-refresh:before{content:"\f49c"}.ion-ios-refresh-empty:before{content:"\f49a"}.ion-ios-refresh-outline:before{content:"\f49b"}.ion-ios-reload:before{content:"\f49d"}.ion-ios-reverse-camera:before{content:"\f49f"}.ion-ios-reverse-camera-outline:before{content:"\f49e"}.ion-ios-rewind:before{content:"\f4a1"}.ion-ios-rewind-outline:before{content:"\f4a0"}.ion-ios-rose:before{content:"\f4a3"}.ion-ios-rose-outline:before{content:"\f4a2"}.ion-ios-search:before{content:"\f4a5"}.ion-ios-search-strong:before{content:"\f4a4"}.ion-ios-settings:before{content:"\f4a7"}.ion-ios-settings-strong:before{content:"\f4a6"}.ion-ios-shuffle:before{content:"\f4a9"}.ion-ios-shuffle-strong:before{content:"\f4a8"}.ion-ios-skipbackward:before{content:"\f4ab"}.ion-ios-skipbackward-outline:before{content:"\f4aa"}.ion-ios-skipforward:before{content:"\f4ad"}.ion-ios-skipforward-outline:before{content:"\f4ac"}.ion-ios-snowy:before{content:"\f4ae"}.ion-ios-speedometer:before{content:"\f4b0"}.ion-ios-speedometer-outline:before{content:"\f4af"}.ion-ios-star:before{content:"\f4b3"}.ion-ios-star-half:before{content:"\f4b1"}.ion-ios-star-outline:before{content:"\f4b2"}.ion-ios-stopwatch:before{content:"\f4b5"}.ion-ios-stopwatch-outline:before{content:"\f4b4"}.ion-ios-sunny:before{content:"\f4b7"}.ion-ios-sunny-outline:before{content:"\f4b6"}.ion-ios-telephone:before{content:"\f4b9"}.ion-ios-telephone-outline:before{content:"\f4b8"}.ion-ios-tennisball:before{content:"\f4bb"}.ion-ios-tennisball-outline:before{content:"\f4ba"}.ion-ios-thunderstorm:before{content:"\f4bd"}.ion-ios-thunderstorm-outline:before{content:"\f4bc"}.ion-ios-time:before{content:"\f4bf"}.ion-ios-time-outline:before{content:"\f4be"}.ion-ios-timer:before{content:"\f4c1"}.ion-ios-timer-outline:before{content:"\f4c0"}.ion-ios-toggle:before{content:"\f4c3"}.ion-ios-toggle-outline:before{content:"\f4c2"}.ion-ios-trash:before{content:"\f4c5"}.ion-ios-trash-outline:before{content:"\f4c4"}.ion-ios-undo:before{content:"\f4c7"}.ion-ios-undo-outline:before{content:"\f4c6"}.ion-ios-unlocked:before{content:"\f4c9"}.ion-ios-unlocked-outline:before{content:"\f4c8"}.ion-ios-upload:before{content:"\f4cb"}.ion-ios-upload-outline:before{content:"\f4ca"}.ion-ios-videocam:before{content:"\f4cd"}.ion-ios-videocam-outline:before{content:"\f4cc"}.ion-ios-volume-high:before{content:"\f4ce"}.ion-ios-volume-low:before{content:"\f4cf"}.ion-ios-wineglass:before{content:"\f4d1"}.ion-ios-wineglass-outline:before{content:"\f4d0"}.ion-ios-world:before{content:"\f4d3"}.ion-ios-world-outline:before{content:"\f4d2"}.ion-ipad:before{content:"\f1f9"}.ion-iphone:before{content:"\f1fa"}.ion-ipod:before{content:"\f1fb"}.ion-jet:before{content:"\f295"}.ion-key:before{content:"\f296"}.ion-knife:before{content:"\f297"}.ion-laptop:before{content:"\f1fc"}.ion-leaf:before{content:"\f1fd"}.ion-levels:before{content:"\f298"}.ion-lightbulb:before{content:"\f299"}.ion-link:before{content:"\f1fe"}.ion-load-a:before{content:"\f29a"}.ion-load-b:before{content:"\f29b"}.ion-load-c:before{content:"\f29c"}.ion-load-d:before{content:"\f29d"}.ion-location:before{content:"\f1ff"}.ion-lock-combination:before{content:"\f4d4"}.ion-locked:before{content:"\f200"}.ion-log-in:before{content:"\f29e"}.ion-log-out:before{content:"\f29f"}.ion-loop:before{content:"\f201"}.ion-magnet:before{content:"\f2a0"}.ion-male:before{content:"\f2a1"}.ion-man:before{content:"\f202"}.ion-map:before{content:"\f203"}.ion-medkit:before{content:"\f2a2"}.ion-merge:before{content:"\f33f"}.ion-mic-a:before{content:"\f204"}.ion-mic-b:before{content:"\f205"}.ion-mic-c:before{content:"\f206"}.ion-minus:before{content:"\f209"}.ion-minus-circled:before{content:"\f207"}.ion-minus-round:before{content:"\f208"}.ion-model-s:before{content:"\f2c1"}.ion-monitor:before{content:"\f20a"}.ion-more:before{content:"\f20b"}.ion-mouse:before{content:"\f340"}.ion-music-note:before{content:"\f20c"}.ion-navicon:before{content:"\f20e"}.ion-navicon-round:before{content:"\f20d"}.ion-navigate:before{content:"\f2a3"}.ion-network:before{content:"\f341"}.ion-no-smoking:before{content:"\f2c2"}.ion-nuclear:before{content:"\f2a4"}.ion-outlet:before{content:"\f342"}.ion-paintbrush:before{content:"\f4d5"}.ion-paintbucket:before{content:"\f4d6"}.ion-paper-airplane:before{content:"\f2c3"}.ion-paperclip:before{content:"\f20f"}.ion-pause:before{content:"\f210"}.ion-person:before{content:"\f213"}.ion-person-add:before{content:"\f211"}.ion-person-stalker:before{content:"\f212"}.ion-pie-graph:before{content:"\f2a5"}.ion-pin:before{content:"\f2a6"}.ion-pinpoint:before{content:"\f2a7"}.ion-pizza:before{content:"\f2a8"}.ion-plane:before{content:"\f214"}.ion-planet:before{content:"\f343"}.ion-play:before{content:"\f215"}.ion-playstation:before{content:"\f30a"}.ion-plus:before{content:"\f218"}.ion-plus-circled:before{content:"\f216"}.ion-plus-round:before{content:"\f217"}.ion-podium:before{content:"\f344"}.ion-pound:before{content:"\f219"}.ion-power:before{content:"\f2a9"}.ion-pricetag:before{content:"\f2aa"}.ion-pricetags:before{content:"\f2ab"}.ion-printer:before{content:"\f21a"}.ion-pull-request:before{content:"\f345"}.ion-qr-scanner:before{content:"\f346"}.ion-quote:before{content:"\f347"}.ion-radio-waves:before{content:"\f2ac"}.ion-record:before{content:"\f21b"}.ion-refresh:before{content:"\f21c"}.ion-reply:before{content:"\f21e"}.ion-reply-all:before{content:"\f21d"}.ion-ribbon-a:before{content:"\f348"}.ion-ribbon-b:before{content:"\f349"}.ion-sad:before{content:"\f34a"}.ion-sad-outline:before{content:"\f4d7"}.ion-scissors:before{content:"\f34b"}.ion-search:before{content:"\f21f"}.ion-settings:before{content:"\f2ad"}.ion-share:before{content:"\f220"}.ion-shuffle:before{content:"\f221"}.ion-skip-backward:before{content:"\f222"}.ion-skip-forward:before{content:"\f223"}.ion-social-android:before{content:"\f225"}.ion-social-android-outline:before{content:"\f224"}.ion-social-angular:before{content:"\f4d9"}.ion-social-angular-outline:before{content:"\f4d8"}.ion-social-apple:before{content:"\f227"}.ion-social-apple-outline:before{content:"\f226"}.ion-social-bitcoin:before{content:"\f2af"}.ion-social-bitcoin-outline:before{content:"\f2ae"}.ion-social-buffer:before{content:"\f229"}.ion-social-buffer-outline:before{content:"\f228"}.ion-social-chrome:before{content:"\f4db"}.ion-social-chrome-outline:before{content:"\f4da"}.ion-social-codepen:before{content:"\f4dd"}.ion-social-codepen-outline:before{content:"\f4dc"}.ion-social-css3:before{content:"\f4df"}.ion-social-css3-outline:before{content:"\f4de"}.ion-social-designernews:before{content:"\f22b"}.ion-social-designernews-outline:before{content:"\f22a"}.ion-social-dribbble:before{content:"\f22d"}.ion-social-dribbble-outline:before{content:"\f22c"}.ion-social-dropbox:before{content:"\f22f"}.ion-social-dropbox-outline:before{content:"\f22e"}.ion-social-euro:before{content:"\f4e1"}.ion-social-euro-outline:before{content:"\f4e0"}.ion-social-facebook:before{content:"\f231"}.ion-social-facebook-outline:before{content:"\f230"}.ion-social-foursquare:before{content:"\f34d"}.ion-social-foursquare-outline:before{content:"\f34c"}.ion-social-freebsd-devil:before{content:"\f2c4"}.ion-social-github:before{content:"\f233"}.ion-social-github-outline:before{content:"\f232"}.ion-social-google:before{content:"\f34f"}.ion-social-google-outline:before{content:"\f34e"}.ion-social-googleplus:before{content:"\f235"}.ion-social-googleplus-outline:before{content:"\f234"}.ion-social-hackernews:before{content:"\f237"}.ion-social-hackernews-outline:before{content:"\f236"}.ion-social-html5:before{content:"\f4e3"}.ion-social-html5-outline:before{content:"\f4e2"}.ion-social-instagram:before{content:"\f351"}.ion-social-instagram-outline:before{content:"\f350"}.ion-social-javascript:before{content:"\f4e5"}.ion-social-javascript-outline:before{content:"\f4e4"}.ion-social-linkedin:before{content:"\f239"}.ion-social-linkedin-outline:before{content:"\f238"}.ion-social-markdown:before{content:"\f4e6"}.ion-social-nodejs:before{content:"\f4e7"}.ion-social-octocat:before{content:"\f4e8"}.ion-social-pinterest:before{content:"\f2b1"}.ion-social-pinterest-outline:before{content:"\f2b0"}.ion-social-python:before{content:"\f4e9"}.ion-social-reddit:before{content:"\f23b"}.ion-social-reddit-outline:before{content:"\f23a"}.ion-social-rss:before{content:"\f23d"}.ion-social-rss-outline:before{content:"\f23c"}.ion-social-sass:before{content:"\f4ea"}.ion-social-skype:before{content:"\f23f"}.ion-social-skype-outline:before{content:"\f23e"}.ion-social-snapchat:before{content:"\f4ec"}.ion-social-snapchat-outline:before{content:"\f4eb"}.ion-social-tumblr:before{content:"\f241"}.ion-social-tumblr-outline:before{content:"\f240"}.ion-social-tux:before{content:"\f2c5"}.ion-social-twitch:before{content:"\f4ee"}.ion-social-twitch-outline:before{content:"\f4ed"}.ion-social-twitter:before{content:"\f243"}.ion-social-twitter-outline:before{content:"\f242"}.ion-social-usd:before{content:"\f353"}.ion-social-usd-outline:before{content:"\f352"}.ion-social-vimeo:before{content:"\f245"}.ion-social-vimeo-outline:before{content:"\f244"}.ion-social-whatsapp:before{content:"\f4f0"}.ion-social-whatsapp-outline:before{content:"\f4ef"}.ion-social-windows:before{content:"\f247"}.ion-social-windows-outline:before{content:"\f246"}.ion-social-wordpress:before{content:"\f249"}.ion-social-wordpress-outline:before{content:"\f248"}.ion-social-yahoo:before{content:"\f24b"}.ion-social-yahoo-outline:before{content:"\f24a"}.ion-social-yen:before{content:"\f4f2"}.ion-social-yen-outline:before{content:"\f4f1"}.ion-social-youtube:before{content:"\f24d"}.ion-social-youtube-outline:before{content:"\f24c"}.ion-soup-can:before{content:"\f4f4"}.ion-soup-can-outline:before{content:"\f4f3"}.ion-speakerphone:before{content:"\f2b2"}.ion-speedometer:before{content:"\f2b3"}.ion-spoon:before{content:"\f2b4"}.ion-star:before{content:"\f24e"}.ion-stats-bars:before{content:"\f2b5"}.ion-steam:before{content:"\f30b"}.ion-stop:before{content:"\f24f"}.ion-thermometer:before{content:"\f2b6"}.ion-thumbsdown:before{content:"\f250"}.ion-thumbsup:before{content:"\f251"}.ion-toggle:before{content:"\f355"}.ion-toggle-filled:before{content:"\f354"}.ion-transgender:before{content:"\f4f5"}.ion-trash-a:before{content:"\f252"}.ion-trash-b:before{content:"\f253"}.ion-trophy:before{content:"\f356"}.ion-tshirt:before{content:"\f4f7"}.ion-tshirt-outline:before{content:"\f4f6"}.ion-umbrella:before{content:"\f2b7"}.ion-university:before{content:"\f357"}.ion-unlocked:before{content:"\f254"}.ion-upload:before{content:"\f255"}.ion-usb:before{content:"\f2b8"}.ion-videocamera:before{content:"\f256"}.ion-volume-high:before{content:"\f257"}.ion-volume-low:before{content:"\f258"}.ion-volume-medium:before{content:"\f259"}.ion-volume-mute:before{content:"\f25a"}.ion-wand:before{content:"\f358"}.ion-waterdrop:before{content:"\f25b"}.ion-wifi:before{content:"\f25c"}.ion-wineglass:before{content:"\f2b9"}.ion-woman:before{content:"\f25d"}.ion-wrench:before{content:"\f2ba"}.ion-xbox:before{content:"\f30c"} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/css/ionicons.min.css b/net452/SiteServer.Web/SiteServer/assets/css/ionicons.min.css new file mode 100644 index 000000000..1c27b785f --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/css/ionicons.min.css @@ -0,0 +1 @@ +@charset "UTF-8";@font-face{font-family:Ionicons;src:url(../fonts/ionicons.eot?v=2.0.0);src:url(../fonts/ionicons.eot?v=2.0.0#iefix) format("embedded-opentype"),url(../fonts/ionicons.ttf?v=2.0.0) format("truetype"),url(../fonts/ionicons.woff?v=2.0.0) format("woff"),url(../fonts/ionicons.svg?v=2.0.0#Ionicons) format("svg");font-weight:400;font-style:normal}.ion,.ion-alert-circled:before,.ion-alert:before,.ion-android-add-circle:before,.ion-android-add:before,.ion-android-alarm-clock:before,.ion-android-alert:before,.ion-android-apps:before,.ion-android-archive:before,.ion-android-arrow-back:before,.ion-android-arrow-down:before,.ion-android-arrow-dropdown-circle:before,.ion-android-arrow-dropdown:before,.ion-android-arrow-dropleft-circle:before,.ion-android-arrow-dropleft:before,.ion-android-arrow-dropright-circle:before,.ion-android-arrow-dropright:before,.ion-android-arrow-dropup-circle:before,.ion-android-arrow-dropup:before,.ion-android-arrow-forward:before,.ion-android-arrow-up:before,.ion-android-attach:before,.ion-android-bar:before,.ion-android-bicycle:before,.ion-android-boat:before,.ion-android-bookmark:before,.ion-android-bulb:before,.ion-android-bus:before,.ion-android-calendar:before,.ion-android-call:before,.ion-android-camera:before,.ion-android-cancel:before,.ion-android-car:before,.ion-android-cart:before,.ion-android-chat:before,.ion-android-checkbox-blank:before,.ion-android-checkbox-outline-blank:before,.ion-android-checkbox-outline:before,.ion-android-checkbox:before,.ion-android-checkmark-circle:before,.ion-android-clipboard:before,.ion-android-close:before,.ion-android-cloud-circle:before,.ion-android-cloud-done:before,.ion-android-cloud-outline:before,.ion-android-cloud:before,.ion-android-color-palette:before,.ion-android-compass:before,.ion-android-contact:before,.ion-android-contacts:before,.ion-android-contract:before,.ion-android-create:before,.ion-android-delete:before,.ion-android-desktop:before,.ion-android-document:before,.ion-android-done-all:before,.ion-android-done:before,.ion-android-download:before,.ion-android-drafts:before,.ion-android-exit:before,.ion-android-expand:before,.ion-android-favorite-outline:before,.ion-android-favorite:before,.ion-android-film:before,.ion-android-folder-open:before,.ion-android-folder:before,.ion-android-funnel:before,.ion-android-globe:before,.ion-android-hand:before,.ion-android-hangout:before,.ion-android-happy:before,.ion-android-home:before,.ion-android-image:before,.ion-android-laptop:before,.ion-android-list:before,.ion-android-locate:before,.ion-android-lock:before,.ion-android-mail:before,.ion-android-map:before,.ion-android-menu:before,.ion-android-microphone-off:before,.ion-android-microphone:before,.ion-android-more-horizontal:before,.ion-android-more-vertical:before,.ion-android-navigate:before,.ion-android-notifications-none:before,.ion-android-notifications-off:before,.ion-android-notifications:before,.ion-android-open:before,.ion-android-options:before,.ion-android-people:before,.ion-android-person-add:before,.ion-android-person:before,.ion-android-phone-landscape:before,.ion-android-phone-portrait:before,.ion-android-pin:before,.ion-android-plane:before,.ion-android-playstore:before,.ion-android-print:before,.ion-android-radio-button-off:before,.ion-android-radio-button-on:before,.ion-android-refresh:before,.ion-android-remove-circle:before,.ion-android-remove:before,.ion-android-restaurant:before,.ion-android-sad:before,.ion-android-search:before,.ion-android-send:before,.ion-android-settings:before,.ion-android-share-alt:before,.ion-android-share:before,.ion-android-star-half:before,.ion-android-star-outline:before,.ion-android-star:before,.ion-android-stopwatch:before,.ion-android-subway:before,.ion-android-sunny:before,.ion-android-sync:before,.ion-android-textsms:before,.ion-android-time:before,.ion-android-train:before,.ion-android-unlock:before,.ion-android-upload:before,.ion-android-volume-down:before,.ion-android-volume-mute:before,.ion-android-volume-off:before,.ion-android-volume-up:before,.ion-android-walk:before,.ion-android-warning:before,.ion-android-watch:before,.ion-android-wifi:before,.ion-aperture:before,.ion-archive:before,.ion-arrow-down-a:before,.ion-arrow-down-b:before,.ion-arrow-down-c:before,.ion-arrow-expand:before,.ion-arrow-graph-down-left:before,.ion-arrow-graph-down-right:before,.ion-arrow-graph-up-left:before,.ion-arrow-graph-up-right:before,.ion-arrow-left-a:before,.ion-arrow-left-b:before,.ion-arrow-left-c:before,.ion-arrow-move:before,.ion-arrow-resize:before,.ion-arrow-return-left:before,.ion-arrow-return-right:before,.ion-arrow-right-a:before,.ion-arrow-right-b:before,.ion-arrow-right-c:before,.ion-arrow-shrink:before,.ion-arrow-swap:before,.ion-arrow-up-a:before,.ion-arrow-up-b:before,.ion-arrow-up-c:before,.ion-asterisk:before,.ion-at:before,.ion-backspace-outline:before,.ion-backspace:before,.ion-bag:before,.ion-battery-charging:before,.ion-battery-empty:before,.ion-battery-full:before,.ion-battery-half:before,.ion-battery-low:before,.ion-beaker:before,.ion-beer:before,.ion-bluetooth:before,.ion-bonfire:before,.ion-bookmark:before,.ion-bowtie:before,.ion-briefcase:before,.ion-bug:before,.ion-calculator:before,.ion-calendar:before,.ion-camera:before,.ion-card:before,.ion-cash:before,.ion-chatbox-working:before,.ion-chatbox:before,.ion-chatboxes:before,.ion-chatbubble-working:before,.ion-chatbubble:before,.ion-chatbubbles:before,.ion-checkmark-circled:before,.ion-checkmark-round:before,.ion-checkmark:before,.ion-chevron-down:before,.ion-chevron-left:before,.ion-chevron-right:before,.ion-chevron-up:before,.ion-clipboard:before,.ion-clock:before,.ion-close-circled:before,.ion-close-round:before,.ion-close:before,.ion-closed-captioning:before,.ion-cloud:before,.ion-code-download:before,.ion-code-working:before,.ion-code:before,.ion-coffee:before,.ion-compass:before,.ion-compose:before,.ion-connection-bars:before,.ion-contrast:before,.ion-crop:before,.ion-cube:before,.ion-disc:before,.ion-document-text:before,.ion-document:before,.ion-drag:before,.ion-earth:before,.ion-easel:before,.ion-edit:before,.ion-egg:before,.ion-eject:before,.ion-email-unread:before,.ion-email:before,.ion-erlenmeyer-flask-bubbles:before,.ion-erlenmeyer-flask:before,.ion-eye-disabled:before,.ion-eye:before,.ion-female:before,.ion-filing:before,.ion-film-marker:before,.ion-fireball:before,.ion-flag:before,.ion-flame:before,.ion-flash-off:before,.ion-flash:before,.ion-folder:before,.ion-fork-repo:before,.ion-fork:before,.ion-forward:before,.ion-funnel:before,.ion-gear-a:before,.ion-gear-b:before,.ion-grid:before,.ion-hammer:before,.ion-happy-outline:before,.ion-happy:before,.ion-headphone:before,.ion-heart-broken:before,.ion-heart:before,.ion-help-buoy:before,.ion-help-circled:before,.ion-help:before,.ion-home:before,.ion-icecream:before,.ion-image:before,.ion-images:before,.ion-information-circled:before,.ion-information:before,.ion-ionic:before,.ion-ios-alarm-outline:before,.ion-ios-alarm:before,.ion-ios-albums-outline:before,.ion-ios-albums:before,.ion-ios-americanfootball-outline:before,.ion-ios-americanfootball:before,.ion-ios-analytics-outline:before,.ion-ios-analytics:before,.ion-ios-arrow-back:before,.ion-ios-arrow-down:before,.ion-ios-arrow-forward:before,.ion-ios-arrow-left:before,.ion-ios-arrow-right:before,.ion-ios-arrow-thin-down:before,.ion-ios-arrow-thin-left:before,.ion-ios-arrow-thin-right:before,.ion-ios-arrow-thin-up:before,.ion-ios-arrow-up:before,.ion-ios-at-outline:before,.ion-ios-at:before,.ion-ios-barcode-outline:before,.ion-ios-barcode:before,.ion-ios-baseball-outline:before,.ion-ios-baseball:before,.ion-ios-basketball-outline:before,.ion-ios-basketball:before,.ion-ios-bell-outline:before,.ion-ios-bell:before,.ion-ios-body-outline:before,.ion-ios-body:before,.ion-ios-bolt-outline:before,.ion-ios-bolt:before,.ion-ios-book-outline:before,.ion-ios-book:before,.ion-ios-bookmarks-outline:before,.ion-ios-bookmarks:before,.ion-ios-box-outline:before,.ion-ios-box:before,.ion-ios-briefcase-outline:before,.ion-ios-briefcase:before,.ion-ios-browsers-outline:before,.ion-ios-browsers:before,.ion-ios-calculator-outline:before,.ion-ios-calculator:before,.ion-ios-calendar-outline:before,.ion-ios-calendar:before,.ion-ios-camera-outline:before,.ion-ios-camera:before,.ion-ios-cart-outline:before,.ion-ios-cart:before,.ion-ios-chatboxes-outline:before,.ion-ios-chatboxes:before,.ion-ios-chatbubble-outline:before,.ion-ios-chatbubble:before,.ion-ios-checkmark-empty:before,.ion-ios-checkmark-outline:before,.ion-ios-checkmark:before,.ion-ios-circle-filled:before,.ion-ios-circle-outline:before,.ion-ios-clock-outline:before,.ion-ios-clock:before,.ion-ios-close-empty:before,.ion-ios-close-outline:before,.ion-ios-close:before,.ion-ios-cloud-download-outline:before,.ion-ios-cloud-download:before,.ion-ios-cloud-outline:before,.ion-ios-cloud-upload-outline:before,.ion-ios-cloud-upload:before,.ion-ios-cloud:before,.ion-ios-cloudy-night-outline:before,.ion-ios-cloudy-night:before,.ion-ios-cloudy-outline:before,.ion-ios-cloudy:before,.ion-ios-cog-outline:before,.ion-ios-cog:before,.ion-ios-color-filter-outline:before,.ion-ios-color-filter:before,.ion-ios-color-wand-outline:before,.ion-ios-color-wand:before,.ion-ios-compose-outline:before,.ion-ios-compose:before,.ion-ios-contact-outline:before,.ion-ios-contact:before,.ion-ios-copy-outline:before,.ion-ios-copy:before,.ion-ios-crop-strong:before,.ion-ios-crop:before,.ion-ios-download-outline:before,.ion-ios-download:before,.ion-ios-drag:before,.ion-ios-email-outline:before,.ion-ios-email:before,.ion-ios-eye-outline:before,.ion-ios-eye:before,.ion-ios-fastforward-outline:before,.ion-ios-fastforward:before,.ion-ios-filing-outline:before,.ion-ios-filing:before,.ion-ios-film-outline:before,.ion-ios-film:before,.ion-ios-flag-outline:before,.ion-ios-flag:before,.ion-ios-flame-outline:before,.ion-ios-flame:before,.ion-ios-flask-outline:before,.ion-ios-flask:before,.ion-ios-flower-outline:before,.ion-ios-flower:before,.ion-ios-folder-outline:before,.ion-ios-folder:before,.ion-ios-football-outline:before,.ion-ios-football:before,.ion-ios-game-controller-a-outline:before,.ion-ios-game-controller-a:before,.ion-ios-game-controller-b-outline:before,.ion-ios-game-controller-b:before,.ion-ios-gear-outline:before,.ion-ios-gear:before,.ion-ios-glasses-outline:before,.ion-ios-glasses:before,.ion-ios-grid-view-outline:before,.ion-ios-grid-view:before,.ion-ios-heart-outline:before,.ion-ios-heart:before,.ion-ios-help-empty:before,.ion-ios-help-outline:before,.ion-ios-help:before,.ion-ios-home-outline:before,.ion-ios-home:before,.ion-ios-infinite-outline:before,.ion-ios-infinite:before,.ion-ios-information-empty:before,.ion-ios-information-outline:before,.ion-ios-information:before,.ion-ios-ionic-outline:before,.ion-ios-keypad-outline:before,.ion-ios-keypad:before,.ion-ios-lightbulb-outline:before,.ion-ios-lightbulb:before,.ion-ios-list-outline:before,.ion-ios-list:before,.ion-ios-location-outline:before,.ion-ios-location:before,.ion-ios-locked-outline:before,.ion-ios-locked:before,.ion-ios-loop-strong:before,.ion-ios-loop:before,.ion-ios-medical-outline:before,.ion-ios-medical:before,.ion-ios-medkit-outline:before,.ion-ios-medkit:before,.ion-ios-mic-off:before,.ion-ios-mic-outline:before,.ion-ios-mic:before,.ion-ios-minus-empty:before,.ion-ios-minus-outline:before,.ion-ios-minus:before,.ion-ios-monitor-outline:before,.ion-ios-monitor:before,.ion-ios-moon-outline:before,.ion-ios-moon:before,.ion-ios-more-outline:before,.ion-ios-more:before,.ion-ios-musical-note:before,.ion-ios-musical-notes:before,.ion-ios-navigate-outline:before,.ion-ios-navigate:before,.ion-ios-nutrition-outline:before,.ion-ios-nutrition:before,.ion-ios-paper-outline:before,.ion-ios-paper:before,.ion-ios-paperplane-outline:before,.ion-ios-paperplane:before,.ion-ios-partlysunny-outline:before,.ion-ios-partlysunny:before,.ion-ios-pause-outline:before,.ion-ios-pause:before,.ion-ios-paw-outline:before,.ion-ios-paw:before,.ion-ios-people-outline:before,.ion-ios-people:before,.ion-ios-person-outline:before,.ion-ios-person:before,.ion-ios-personadd-outline:before,.ion-ios-personadd:before,.ion-ios-photos-outline:before,.ion-ios-photos:before,.ion-ios-pie-outline:before,.ion-ios-pie:before,.ion-ios-pint-outline:before,.ion-ios-pint:before,.ion-ios-play-outline:before,.ion-ios-play:before,.ion-ios-plus-empty:before,.ion-ios-plus-outline:before,.ion-ios-plus:before,.ion-ios-pricetag-outline:before,.ion-ios-pricetag:before,.ion-ios-pricetags-outline:before,.ion-ios-pricetags:before,.ion-ios-printer-outline:before,.ion-ios-printer:before,.ion-ios-pulse-strong:before,.ion-ios-pulse:before,.ion-ios-rainy-outline:before,.ion-ios-rainy:before,.ion-ios-recording-outline:before,.ion-ios-recording:before,.ion-ios-redo-outline:before,.ion-ios-redo:before,.ion-ios-refresh-empty:before,.ion-ios-refresh-outline:before,.ion-ios-refresh:before,.ion-ios-reload:before,.ion-ios-reverse-camera-outline:before,.ion-ios-reverse-camera:before,.ion-ios-rewind-outline:before,.ion-ios-rewind:before,.ion-ios-rose-outline:before,.ion-ios-rose:before,.ion-ios-search-strong:before,.ion-ios-search:before,.ion-ios-settings-strong:before,.ion-ios-settings:before,.ion-ios-shuffle-strong:before,.ion-ios-shuffle:before,.ion-ios-skipbackward-outline:before,.ion-ios-skipbackward:before,.ion-ios-skipforward-outline:before,.ion-ios-skipforward:before,.ion-ios-snowy:before,.ion-ios-speedometer-outline:before,.ion-ios-speedometer:before,.ion-ios-star-half:before,.ion-ios-star-outline:before,.ion-ios-star:before,.ion-ios-stopwatch-outline:before,.ion-ios-stopwatch:before,.ion-ios-sunny-outline:before,.ion-ios-sunny:before,.ion-ios-telephone-outline:before,.ion-ios-telephone:before,.ion-ios-tennisball-outline:before,.ion-ios-tennisball:before,.ion-ios-thunderstorm-outline:before,.ion-ios-thunderstorm:before,.ion-ios-time-outline:before,.ion-ios-time:before,.ion-ios-timer-outline:before,.ion-ios-timer:before,.ion-ios-toggle-outline:before,.ion-ios-toggle:before,.ion-ios-trash-outline:before,.ion-ios-trash:before,.ion-ios-undo-outline:before,.ion-ios-undo:before,.ion-ios-unlocked-outline:before,.ion-ios-unlocked:before,.ion-ios-upload-outline:before,.ion-ios-upload:before,.ion-ios-videocam-outline:before,.ion-ios-videocam:before,.ion-ios-volume-high:before,.ion-ios-volume-low:before,.ion-ios-wineglass-outline:before,.ion-ios-wineglass:before,.ion-ios-world-outline:before,.ion-ios-world:before,.ion-ipad:before,.ion-iphone:before,.ion-ipod:before,.ion-jet:before,.ion-key:before,.ion-knife:before,.ion-laptop:before,.ion-leaf:before,.ion-levels:before,.ion-lightbulb:before,.ion-link:before,.ion-load-a:before,.ion-load-b:before,.ion-load-c:before,.ion-load-d:before,.ion-location:before,.ion-lock-combination:before,.ion-locked:before,.ion-log-in:before,.ion-log-out:before,.ion-loop:before,.ion-magnet:before,.ion-male:before,.ion-man:before,.ion-map:before,.ion-medkit:before,.ion-merge:before,.ion-mic-a:before,.ion-mic-b:before,.ion-mic-c:before,.ion-minus-circled:before,.ion-minus-round:before,.ion-minus:before,.ion-model-s:before,.ion-monitor:before,.ion-more:before,.ion-mouse:before,.ion-music-note:before,.ion-navicon-round:before,.ion-navicon:before,.ion-navigate:before,.ion-network:before,.ion-no-smoking:before,.ion-nuclear:before,.ion-outlet:before,.ion-paintbrush:before,.ion-paintbucket:before,.ion-paper-airplane:before,.ion-paperclip:before,.ion-pause:before,.ion-person-add:before,.ion-person-stalker:before,.ion-person:before,.ion-pie-graph:before,.ion-pin:before,.ion-pinpoint:before,.ion-pizza:before,.ion-plane:before,.ion-planet:before,.ion-play:before,.ion-playstation:before,.ion-plus-circled:before,.ion-plus-round:before,.ion-plus:before,.ion-podium:before,.ion-pound:before,.ion-power:before,.ion-pricetag:before,.ion-pricetags:before,.ion-printer:before,.ion-pull-request:before,.ion-qr-scanner:before,.ion-quote:before,.ion-radio-waves:before,.ion-record:before,.ion-refresh:before,.ion-reply-all:before,.ion-reply:before,.ion-ribbon-a:before,.ion-ribbon-b:before,.ion-sad-outline:before,.ion-sad:before,.ion-scissors:before,.ion-search:before,.ion-settings:before,.ion-share:before,.ion-shuffle:before,.ion-skip-backward:before,.ion-skip-forward:before,.ion-social-android-outline:before,.ion-social-android:before,.ion-social-angular-outline:before,.ion-social-angular:before,.ion-social-apple-outline:before,.ion-social-apple:before,.ion-social-bitcoin-outline:before,.ion-social-bitcoin:before,.ion-social-buffer-outline:before,.ion-social-buffer:before,.ion-social-chrome-outline:before,.ion-social-chrome:before,.ion-social-codepen-outline:before,.ion-social-codepen:before,.ion-social-css3-outline:before,.ion-social-css3:before,.ion-social-designernews-outline:before,.ion-social-designernews:before,.ion-social-dribbble-outline:before,.ion-social-dribbble:before,.ion-social-dropbox-outline:before,.ion-social-dropbox:before,.ion-social-euro-outline:before,.ion-social-euro:before,.ion-social-facebook-outline:before,.ion-social-facebook:before,.ion-social-foursquare-outline:before,.ion-social-foursquare:before,.ion-social-freebsd-devil:before,.ion-social-github-outline:before,.ion-social-github:before,.ion-social-google-outline:before,.ion-social-google:before,.ion-social-googleplus-outline:before,.ion-social-googleplus:before,.ion-social-hackernews-outline:before,.ion-social-hackernews:before,.ion-social-html5-outline:before,.ion-social-html5:before,.ion-social-instagram-outline:before,.ion-social-instagram:before,.ion-social-javascript-outline:before,.ion-social-javascript:before,.ion-social-linkedin-outline:before,.ion-social-linkedin:before,.ion-social-markdown:before,.ion-social-nodejs:before,.ion-social-octocat:before,.ion-social-pinterest-outline:before,.ion-social-pinterest:before,.ion-social-python:before,.ion-social-reddit-outline:before,.ion-social-reddit:before,.ion-social-rss-outline:before,.ion-social-rss:before,.ion-social-sass:before,.ion-social-skype-outline:before,.ion-social-skype:before,.ion-social-snapchat-outline:before,.ion-social-snapchat:before,.ion-social-tumblr-outline:before,.ion-social-tumblr:before,.ion-social-tux:before,.ion-social-twitch-outline:before,.ion-social-twitch:before,.ion-social-twitter-outline:before,.ion-social-twitter:before,.ion-social-usd-outline:before,.ion-social-usd:before,.ion-social-vimeo-outline:before,.ion-social-vimeo:before,.ion-social-whatsapp-outline:before,.ion-social-whatsapp:before,.ion-social-windows-outline:before,.ion-social-windows:before,.ion-social-wordpress-outline:before,.ion-social-wordpress:before,.ion-social-yahoo-outline:before,.ion-social-yahoo:before,.ion-social-yen-outline:before,.ion-social-yen:before,.ion-social-youtube-outline:before,.ion-social-youtube:before,.ion-soup-can-outline:before,.ion-soup-can:before,.ion-speakerphone:before,.ion-speedometer:before,.ion-spoon:before,.ion-star:before,.ion-stats-bars:before,.ion-steam:before,.ion-stop:before,.ion-thermometer:before,.ion-thumbsdown:before,.ion-thumbsup:before,.ion-toggle-filled:before,.ion-toggle:before,.ion-transgender:before,.ion-trash-a:before,.ion-trash-b:before,.ion-trophy:before,.ion-tshirt-outline:before,.ion-tshirt:before,.ion-umbrella:before,.ion-university:before,.ion-unlocked:before,.ion-upload:before,.ion-usb:before,.ion-videocamera:before,.ion-volume-high:before,.ion-volume-low:before,.ion-volume-medium:before,.ion-volume-mute:before,.ion-wand:before,.ion-waterdrop:before,.ion-wifi:before,.ion-wineglass:before,.ion-woman:before,.ion-wrench:before,.ion-xbox:before,.ionicons{display:inline-block;font-family:Ionicons;speak:none;font-style:normal;font-weight:400;font-variant:normal;text-transform:none;text-rendering:auto;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.ion-alert:before{content:"\f101"}.ion-alert-circled:before{content:"\f100"}.ion-android-add:before{content:"\f2c7"}.ion-android-add-circle:before{content:"\f359"}.ion-android-alarm-clock:before{content:"\f35a"}.ion-android-alert:before{content:"\f35b"}.ion-android-apps:before{content:"\f35c"}.ion-android-archive:before{content:"\f2c9"}.ion-android-arrow-back:before{content:"\f2ca"}.ion-android-arrow-down:before{content:"\f35d"}.ion-android-arrow-dropdown:before{content:"\f35f"}.ion-android-arrow-dropdown-circle:before{content:"\f35e"}.ion-android-arrow-dropleft:before{content:"\f361"}.ion-android-arrow-dropleft-circle:before{content:"\f360"}.ion-android-arrow-dropright:before{content:"\f363"}.ion-android-arrow-dropright-circle:before{content:"\f362"}.ion-android-arrow-dropup:before{content:"\f365"}.ion-android-arrow-dropup-circle:before{content:"\f364"}.ion-android-arrow-forward:before{content:"\f30f"}.ion-android-arrow-up:before{content:"\f366"}.ion-android-attach:before{content:"\f367"}.ion-android-bar:before{content:"\f368"}.ion-android-bicycle:before{content:"\f369"}.ion-android-boat:before{content:"\f36a"}.ion-android-bookmark:before{content:"\f36b"}.ion-android-bulb:before{content:"\f36c"}.ion-android-bus:before{content:"\f36d"}.ion-android-calendar:before{content:"\f2d1"}.ion-android-call:before{content:"\f2d2"}.ion-android-camera:before{content:"\f2d3"}.ion-android-cancel:before{content:"\f36e"}.ion-android-car:before{content:"\f36f"}.ion-android-cart:before{content:"\f370"}.ion-android-chat:before{content:"\f2d4"}.ion-android-checkbox:before{content:"\f374"}.ion-android-checkbox-blank:before{content:"\f371"}.ion-android-checkbox-outline:before{content:"\f373"}.ion-android-checkbox-outline-blank:before{content:"\f372"}.ion-android-checkmark-circle:before{content:"\f375"}.ion-android-clipboard:before{content:"\f376"}.ion-android-close:before{content:"\f2d7"}.ion-android-cloud:before{content:"\f37a"}.ion-android-cloud-circle:before{content:"\f377"}.ion-android-cloud-done:before{content:"\f378"}.ion-android-cloud-outline:before{content:"\f379"}.ion-android-color-palette:before{content:"\f37b"}.ion-android-compass:before{content:"\f37c"}.ion-android-contact:before{content:"\f2d8"}.ion-android-contacts:before{content:"\f2d9"}.ion-android-contract:before{content:"\f37d"}.ion-android-create:before{content:"\f37e"}.ion-android-delete:before{content:"\f37f"}.ion-android-desktop:before{content:"\f380"}.ion-android-document:before{content:"\f381"}.ion-android-done:before{content:"\f383"}.ion-android-done-all:before{content:"\f382"}.ion-android-download:before{content:"\f2dd"}.ion-android-drafts:before{content:"\f384"}.ion-android-exit:before{content:"\f385"}.ion-android-expand:before{content:"\f386"}.ion-android-favorite:before{content:"\f388"}.ion-android-favorite-outline:before{content:"\f387"}.ion-android-film:before{content:"\f389"}.ion-android-folder:before{content:"\f2e0"}.ion-android-folder-open:before{content:"\f38a"}.ion-android-funnel:before{content:"\f38b"}.ion-android-globe:before{content:"\f38c"}.ion-android-hand:before{content:"\f2e3"}.ion-android-hangout:before{content:"\f38d"}.ion-android-happy:before{content:"\f38e"}.ion-android-home:before{content:"\f38f"}.ion-android-image:before{content:"\f2e4"}.ion-android-laptop:before{content:"\f390"}.ion-android-list:before{content:"\f391"}.ion-android-locate:before{content:"\f2e9"}.ion-android-lock:before{content:"\f392"}.ion-android-mail:before{content:"\f2eb"}.ion-android-map:before{content:"\f393"}.ion-android-menu:before{content:"\f394"}.ion-android-microphone:before{content:"\f2ec"}.ion-android-microphone-off:before{content:"\f395"}.ion-android-more-horizontal:before{content:"\f396"}.ion-android-more-vertical:before{content:"\f397"}.ion-android-navigate:before{content:"\f398"}.ion-android-notifications:before{content:"\f39b"}.ion-android-notifications-none:before{content:"\f399"}.ion-android-notifications-off:before{content:"\f39a"}.ion-android-open:before{content:"\f39c"}.ion-android-options:before{content:"\f39d"}.ion-android-people:before{content:"\f39e"}.ion-android-person:before{content:"\f3a0"}.ion-android-person-add:before{content:"\f39f"}.ion-android-phone-landscape:before{content:"\f3a1"}.ion-android-phone-portrait:before{content:"\f3a2"}.ion-android-pin:before{content:"\f3a3"}.ion-android-plane:before{content:"\f3a4"}.ion-android-playstore:before{content:"\f2f0"}.ion-android-print:before{content:"\f3a5"}.ion-android-radio-button-off:before{content:"\f3a6"}.ion-android-radio-button-on:before{content:"\f3a7"}.ion-android-refresh:before{content:"\f3a8"}.ion-android-remove:before{content:"\f2f4"}.ion-android-remove-circle:before{content:"\f3a9"}.ion-android-restaurant:before{content:"\f3aa"}.ion-android-sad:before{content:"\f3ab"}.ion-android-search:before{content:"\f2f5"}.ion-android-send:before{content:"\f2f6"}.ion-android-settings:before{content:"\f2f7"}.ion-android-share:before{content:"\f2f8"}.ion-android-share-alt:before{content:"\f3ac"}.ion-android-star:before{content:"\f2fc"}.ion-android-star-half:before{content:"\f3ad"}.ion-android-star-outline:before{content:"\f3ae"}.ion-android-stopwatch:before{content:"\f2fd"}.ion-android-subway:before{content:"\f3af"}.ion-android-sunny:before{content:"\f3b0"}.ion-android-sync:before{content:"\f3b1"}.ion-android-textsms:before{content:"\f3b2"}.ion-android-time:before{content:"\f3b3"}.ion-android-train:before{content:"\f3b4"}.ion-android-unlock:before{content:"\f3b5"}.ion-android-upload:before{content:"\f3b6"}.ion-android-volume-down:before{content:"\f3b7"}.ion-android-volume-mute:before{content:"\f3b8"}.ion-android-volume-off:before{content:"\f3b9"}.ion-android-volume-up:before{content:"\f3ba"}.ion-android-walk:before{content:"\f3bb"}.ion-android-warning:before{content:"\f3bc"}.ion-android-watch:before{content:"\f3bd"}.ion-android-wifi:before{content:"\f305"}.ion-aperture:before{content:"\f313"}.ion-archive:before{content:"\f102"}.ion-arrow-down-a:before{content:"\f103"}.ion-arrow-down-b:before{content:"\f104"}.ion-arrow-down-c:before{content:"\f105"}.ion-arrow-expand:before{content:"\f25e"}.ion-arrow-graph-down-left:before{content:"\f25f"}.ion-arrow-graph-down-right:before{content:"\f260"}.ion-arrow-graph-up-left:before{content:"\f261"}.ion-arrow-graph-up-right:before{content:"\f262"}.ion-arrow-left-a:before{content:"\f106"}.ion-arrow-left-b:before{content:"\f107"}.ion-arrow-left-c:before{content:"\f108"}.ion-arrow-move:before{content:"\f263"}.ion-arrow-resize:before{content:"\f264"}.ion-arrow-return-left:before{content:"\f265"}.ion-arrow-return-right:before{content:"\f266"}.ion-arrow-right-a:before{content:"\f109"}.ion-arrow-right-b:before{content:"\f10a"}.ion-arrow-right-c:before{content:"\f10b"}.ion-arrow-shrink:before{content:"\f267"}.ion-arrow-swap:before{content:"\f268"}.ion-arrow-up-a:before{content:"\f10c"}.ion-arrow-up-b:before{content:"\f10d"}.ion-arrow-up-c:before{content:"\f10e"}.ion-asterisk:before{content:"\f314"}.ion-at:before{content:"\f10f"}.ion-backspace:before{content:"\f3bf"}.ion-backspace-outline:before{content:"\f3be"}.ion-bag:before{content:"\f110"}.ion-battery-charging:before{content:"\f111"}.ion-battery-empty:before{content:"\f112"}.ion-battery-full:before{content:"\f113"}.ion-battery-half:before{content:"\f114"}.ion-battery-low:before{content:"\f115"}.ion-beaker:before{content:"\f269"}.ion-beer:before{content:"\f26a"}.ion-bluetooth:before{content:"\f116"}.ion-bonfire:before{content:"\f315"}.ion-bookmark:before{content:"\f26b"}.ion-bowtie:before{content:"\f3c0"}.ion-briefcase:before{content:"\f26c"}.ion-bug:before{content:"\f2be"}.ion-calculator:before{content:"\f26d"}.ion-calendar:before{content:"\f117"}.ion-camera:before{content:"\f118"}.ion-card:before{content:"\f119"}.ion-cash:before{content:"\f316"}.ion-chatbox:before{content:"\f11b"}.ion-chatbox-working:before{content:"\f11a"}.ion-chatboxes:before{content:"\f11c"}.ion-chatbubble:before{content:"\f11e"}.ion-chatbubble-working:before{content:"\f11d"}.ion-chatbubbles:before{content:"\f11f"}.ion-checkmark:before{content:"\f122"}.ion-checkmark-circled:before{content:"\f120"}.ion-checkmark-round:before{content:"\f121"}.ion-chevron-down:before{content:"\f123"}.ion-chevron-left:before{content:"\f124"}.ion-chevron-right:before{content:"\f125"}.ion-chevron-up:before{content:"\f126"}.ion-clipboard:before{content:"\f127"}.ion-clock:before{content:"\f26e"}.ion-close:before{content:"\f12a"}.ion-close-circled:before{content:"\f128"}.ion-close-round:before{content:"\f129"}.ion-closed-captioning:before{content:"\f317"}.ion-cloud:before{content:"\f12b"}.ion-code:before{content:"\f271"}.ion-code-download:before{content:"\f26f"}.ion-code-working:before{content:"\f270"}.ion-coffee:before{content:"\f272"}.ion-compass:before{content:"\f273"}.ion-compose:before{content:"\f12c"}.ion-connection-bars:before{content:"\f274"}.ion-contrast:before{content:"\f275"}.ion-crop:before{content:"\f3c1"}.ion-cube:before{content:"\f318"}.ion-disc:before{content:"\f12d"}.ion-document:before{content:"\f12f"}.ion-document-text:before{content:"\f12e"}.ion-drag:before{content:"\f130"}.ion-earth:before{content:"\f276"}.ion-easel:before{content:"\f3c2"}.ion-edit:before{content:"\f2bf"}.ion-egg:before{content:"\f277"}.ion-eject:before{content:"\f131"}.ion-email:before{content:"\f132"}.ion-email-unread:before{content:"\f3c3"}.ion-erlenmeyer-flask:before{content:"\f3c5"}.ion-erlenmeyer-flask-bubbles:before{content:"\f3c4"}.ion-eye:before{content:"\f133"}.ion-eye-disabled:before{content:"\f306"}.ion-female:before{content:"\f278"}.ion-filing:before{content:"\f134"}.ion-film-marker:before{content:"\f135"}.ion-fireball:before{content:"\f319"}.ion-flag:before{content:"\f279"}.ion-flame:before{content:"\f31a"}.ion-flash:before{content:"\f137"}.ion-flash-off:before{content:"\f136"}.ion-folder:before{content:"\f139"}.ion-fork:before{content:"\f27a"}.ion-fork-repo:before{content:"\f2c0"}.ion-forward:before{content:"\f13a"}.ion-funnel:before{content:"\f31b"}.ion-gear-a:before{content:"\f13d"}.ion-gear-b:before{content:"\f13e"}.ion-grid:before{content:"\f13f"}.ion-hammer:before{content:"\f27b"}.ion-happy:before{content:"\f31c"}.ion-happy-outline:before{content:"\f3c6"}.ion-headphone:before{content:"\f140"}.ion-heart:before{content:"\f141"}.ion-heart-broken:before{content:"\f31d"}.ion-help:before{content:"\f143"}.ion-help-buoy:before{content:"\f27c"}.ion-help-circled:before{content:"\f142"}.ion-home:before{content:"\f144"}.ion-icecream:before{content:"\f27d"}.ion-image:before{content:"\f147"}.ion-images:before{content:"\f148"}.ion-information:before{content:"\f14a"}.ion-information-circled:before{content:"\f149"}.ion-ionic:before{content:"\f14b"}.ion-ios-alarm:before{content:"\f3c8"}.ion-ios-alarm-outline:before{content:"\f3c7"}.ion-ios-albums:before{content:"\f3ca"}.ion-ios-albums-outline:before{content:"\f3c9"}.ion-ios-americanfootball:before{content:"\f3cc"}.ion-ios-americanfootball-outline:before{content:"\f3cb"}.ion-ios-analytics:before{content:"\f3ce"}.ion-ios-analytics-outline:before{content:"\f3cd"}.ion-ios-arrow-back:before{content:"\f3cf"}.ion-ios-arrow-down:before{content:"\f3d0"}.ion-ios-arrow-forward:before{content:"\f3d1"}.ion-ios-arrow-left:before{content:"\f3d2"}.ion-ios-arrow-right:before{content:"\f3d3"}.ion-ios-arrow-thin-down:before{content:"\f3d4"}.ion-ios-arrow-thin-left:before{content:"\f3d5"}.ion-ios-arrow-thin-right:before{content:"\f3d6"}.ion-ios-arrow-thin-up:before{content:"\f3d7"}.ion-ios-arrow-up:before{content:"\f3d8"}.ion-ios-at:before{content:"\f3da"}.ion-ios-at-outline:before{content:"\f3d9"}.ion-ios-barcode:before{content:"\f3dc"}.ion-ios-barcode-outline:before{content:"\f3db"}.ion-ios-baseball:before{content:"\f3de"}.ion-ios-baseball-outline:before{content:"\f3dd"}.ion-ios-basketball:before{content:"\f3e0"}.ion-ios-basketball-outline:before{content:"\f3df"}.ion-ios-bell:before{content:"\f3e2"}.ion-ios-bell-outline:before{content:"\f3e1"}.ion-ios-body:before{content:"\f3e4"}.ion-ios-body-outline:before{content:"\f3e3"}.ion-ios-bolt:before{content:"\f3e6"}.ion-ios-bolt-outline:before{content:"\f3e5"}.ion-ios-book:before{content:"\f3e8"}.ion-ios-book-outline:before{content:"\f3e7"}.ion-ios-bookmarks:before{content:"\f3ea"}.ion-ios-bookmarks-outline:before{content:"\f3e9"}.ion-ios-box:before{content:"\f3ec"}.ion-ios-box-outline:before{content:"\f3eb"}.ion-ios-briefcase:before{content:"\f3ee"}.ion-ios-briefcase-outline:before{content:"\f3ed"}.ion-ios-browsers:before{content:"\f3f0"}.ion-ios-browsers-outline:before{content:"\f3ef"}.ion-ios-calculator:before{content:"\f3f2"}.ion-ios-calculator-outline:before{content:"\f3f1"}.ion-ios-calendar:before{content:"\f3f4"}.ion-ios-calendar-outline:before{content:"\f3f3"}.ion-ios-camera:before{content:"\f3f6"}.ion-ios-camera-outline:before{content:"\f3f5"}.ion-ios-cart:before{content:"\f3f8"}.ion-ios-cart-outline:before{content:"\f3f7"}.ion-ios-chatboxes:before{content:"\f3fa"}.ion-ios-chatboxes-outline:before{content:"\f3f9"}.ion-ios-chatbubble:before{content:"\f3fc"}.ion-ios-chatbubble-outline:before{content:"\f3fb"}.ion-ios-checkmark:before{content:"\f3ff"}.ion-ios-checkmark-empty:before{content:"\f3fd"}.ion-ios-checkmark-outline:before{content:"\f3fe"}.ion-ios-circle-filled:before{content:"\f400"}.ion-ios-circle-outline:before{content:"\f401"}.ion-ios-clock:before{content:"\f403"}.ion-ios-clock-outline:before{content:"\f402"}.ion-ios-close:before{content:"\f406"}.ion-ios-close-empty:before{content:"\f404"}.ion-ios-close-outline:before{content:"\f405"}.ion-ios-cloud:before{content:"\f40c"}.ion-ios-cloud-download:before{content:"\f408"}.ion-ios-cloud-download-outline:before{content:"\f407"}.ion-ios-cloud-outline:before{content:"\f409"}.ion-ios-cloud-upload:before{content:"\f40b"}.ion-ios-cloud-upload-outline:before{content:"\f40a"}.ion-ios-cloudy:before{content:"\f410"}.ion-ios-cloudy-night:before{content:"\f40e"}.ion-ios-cloudy-night-outline:before{content:"\f40d"}.ion-ios-cloudy-outline:before{content:"\f40f"}.ion-ios-cog:before{content:"\f412"}.ion-ios-cog-outline:before{content:"\f411"}.ion-ios-color-filter:before{content:"\f414"}.ion-ios-color-filter-outline:before{content:"\f413"}.ion-ios-color-wand:before{content:"\f416"}.ion-ios-color-wand-outline:before{content:"\f415"}.ion-ios-compose:before{content:"\f418"}.ion-ios-compose-outline:before{content:"\f417"}.ion-ios-contact:before{content:"\f41a"}.ion-ios-contact-outline:before{content:"\f419"}.ion-ios-copy:before{content:"\f41c"}.ion-ios-copy-outline:before{content:"\f41b"}.ion-ios-crop:before{content:"\f41e"}.ion-ios-crop-strong:before{content:"\f41d"}.ion-ios-download:before{content:"\f420"}.ion-ios-download-outline:before{content:"\f41f"}.ion-ios-drag:before{content:"\f421"}.ion-ios-email:before{content:"\f423"}.ion-ios-email-outline:before{content:"\f422"}.ion-ios-eye:before{content:"\f425"}.ion-ios-eye-outline:before{content:"\f424"}.ion-ios-fastforward:before{content:"\f427"}.ion-ios-fastforward-outline:before{content:"\f426"}.ion-ios-filing:before{content:"\f429"}.ion-ios-filing-outline:before{content:"\f428"}.ion-ios-film:before{content:"\f42b"}.ion-ios-film-outline:before{content:"\f42a"}.ion-ios-flag:before{content:"\f42d"}.ion-ios-flag-outline:before{content:"\f42c"}.ion-ios-flame:before{content:"\f42f"}.ion-ios-flame-outline:before{content:"\f42e"}.ion-ios-flask:before{content:"\f431"}.ion-ios-flask-outline:before{content:"\f430"}.ion-ios-flower:before{content:"\f433"}.ion-ios-flower-outline:before{content:"\f432"}.ion-ios-folder:before{content:"\f435"}.ion-ios-folder-outline:before{content:"\f434"}.ion-ios-football:before{content:"\f437"}.ion-ios-football-outline:before{content:"\f436"}.ion-ios-game-controller-a:before{content:"\f439"}.ion-ios-game-controller-a-outline:before{content:"\f438"}.ion-ios-game-controller-b:before{content:"\f43b"}.ion-ios-game-controller-b-outline:before{content:"\f43a"}.ion-ios-gear:before{content:"\f43d"}.ion-ios-gear-outline:before{content:"\f43c"}.ion-ios-glasses:before{content:"\f43f"}.ion-ios-glasses-outline:before{content:"\f43e"}.ion-ios-grid-view:before{content:"\f441"}.ion-ios-grid-view-outline:before{content:"\f440"}.ion-ios-heart:before{content:"\f443"}.ion-ios-heart-outline:before{content:"\f442"}.ion-ios-help:before{content:"\f446"}.ion-ios-help-empty:before{content:"\f444"}.ion-ios-help-outline:before{content:"\f445"}.ion-ios-home:before{content:"\f448"}.ion-ios-home-outline:before{content:"\f447"}.ion-ios-infinite:before{content:"\f44a"}.ion-ios-infinite-outline:before{content:"\f449"}.ion-ios-information:before{content:"\f44d"}.ion-ios-information-empty:before{content:"\f44b"}.ion-ios-information-outline:before{content:"\f44c"}.ion-ios-ionic-outline:before{content:"\f44e"}.ion-ios-keypad:before{content:"\f450"}.ion-ios-keypad-outline:before{content:"\f44f"}.ion-ios-lightbulb:before{content:"\f452"}.ion-ios-lightbulb-outline:before{content:"\f451"}.ion-ios-list:before{content:"\f454"}.ion-ios-list-outline:before{content:"\f453"}.ion-ios-location:before{content:"\f456"}.ion-ios-location-outline:before{content:"\f455"}.ion-ios-locked:before{content:"\f458"}.ion-ios-locked-outline:before{content:"\f457"}.ion-ios-loop:before{content:"\f45a"}.ion-ios-loop-strong:before{content:"\f459"}.ion-ios-medical:before{content:"\f45c"}.ion-ios-medical-outline:before{content:"\f45b"}.ion-ios-medkit:before{content:"\f45e"}.ion-ios-medkit-outline:before{content:"\f45d"}.ion-ios-mic:before{content:"\f461"}.ion-ios-mic-off:before{content:"\f45f"}.ion-ios-mic-outline:before{content:"\f460"}.ion-ios-minus:before{content:"\f464"}.ion-ios-minus-empty:before{content:"\f462"}.ion-ios-minus-outline:before{content:"\f463"}.ion-ios-monitor:before{content:"\f466"}.ion-ios-monitor-outline:before{content:"\f465"}.ion-ios-moon:before{content:"\f468"}.ion-ios-moon-outline:before{content:"\f467"}.ion-ios-more:before{content:"\f46a"}.ion-ios-more-outline:before{content:"\f469"}.ion-ios-musical-note:before{content:"\f46b"}.ion-ios-musical-notes:before{content:"\f46c"}.ion-ios-navigate:before{content:"\f46e"}.ion-ios-navigate-outline:before{content:"\f46d"}.ion-ios-nutrition:before{content:"\f470"}.ion-ios-nutrition-outline:before{content:"\f46f"}.ion-ios-paper:before{content:"\f472"}.ion-ios-paper-outline:before{content:"\f471"}.ion-ios-paperplane:before{content:"\f474"}.ion-ios-paperplane-outline:before{content:"\f473"}.ion-ios-partlysunny:before{content:"\f476"}.ion-ios-partlysunny-outline:before{content:"\f475"}.ion-ios-pause:before{content:"\f478"}.ion-ios-pause-outline:before{content:"\f477"}.ion-ios-paw:before{content:"\f47a"}.ion-ios-paw-outline:before{content:"\f479"}.ion-ios-people:before{content:"\f47c"}.ion-ios-people-outline:before{content:"\f47b"}.ion-ios-person:before{content:"\f47e"}.ion-ios-person-outline:before{content:"\f47d"}.ion-ios-personadd:before{content:"\f480"}.ion-ios-personadd-outline:before{content:"\f47f"}.ion-ios-photos:before{content:"\f482"}.ion-ios-photos-outline:before{content:"\f481"}.ion-ios-pie:before{content:"\f484"}.ion-ios-pie-outline:before{content:"\f483"}.ion-ios-pint:before{content:"\f486"}.ion-ios-pint-outline:before{content:"\f485"}.ion-ios-play:before{content:"\f488"}.ion-ios-play-outline:before{content:"\f487"}.ion-ios-plus:before{content:"\f48b"}.ion-ios-plus-empty:before{content:"\f489"}.ion-ios-plus-outline:before{content:"\f48a"}.ion-ios-pricetag:before{content:"\f48d"}.ion-ios-pricetag-outline:before{content:"\f48c"}.ion-ios-pricetags:before{content:"\f48f"}.ion-ios-pricetags-outline:before{content:"\f48e"}.ion-ios-printer:before{content:"\f491"}.ion-ios-printer-outline:before{content:"\f490"}.ion-ios-pulse:before{content:"\f493"}.ion-ios-pulse-strong:before{content:"\f492"}.ion-ios-rainy:before{content:"\f495"}.ion-ios-rainy-outline:before{content:"\f494"}.ion-ios-recording:before{content:"\f497"}.ion-ios-recording-outline:before{content:"\f496"}.ion-ios-redo:before{content:"\f499"}.ion-ios-redo-outline:before{content:"\f498"}.ion-ios-refresh:before{content:"\f49c"}.ion-ios-refresh-empty:before{content:"\f49a"}.ion-ios-refresh-outline:before{content:"\f49b"}.ion-ios-reload:before{content:"\f49d"}.ion-ios-reverse-camera:before{content:"\f49f"}.ion-ios-reverse-camera-outline:before{content:"\f49e"}.ion-ios-rewind:before{content:"\f4a1"}.ion-ios-rewind-outline:before{content:"\f4a0"}.ion-ios-rose:before{content:"\f4a3"}.ion-ios-rose-outline:before{content:"\f4a2"}.ion-ios-search:before{content:"\f4a5"}.ion-ios-search-strong:before{content:"\f4a4"}.ion-ios-settings:before{content:"\f4a7"}.ion-ios-settings-strong:before{content:"\f4a6"}.ion-ios-shuffle:before{content:"\f4a9"}.ion-ios-shuffle-strong:before{content:"\f4a8"}.ion-ios-skipbackward:before{content:"\f4ab"}.ion-ios-skipbackward-outline:before{content:"\f4aa"}.ion-ios-skipforward:before{content:"\f4ad"}.ion-ios-skipforward-outline:before{content:"\f4ac"}.ion-ios-snowy:before{content:"\f4ae"}.ion-ios-speedometer:before{content:"\f4b0"}.ion-ios-speedometer-outline:before{content:"\f4af"}.ion-ios-star:before{content:"\f4b3"}.ion-ios-star-half:before{content:"\f4b1"}.ion-ios-star-outline:before{content:"\f4b2"}.ion-ios-stopwatch:before{content:"\f4b5"}.ion-ios-stopwatch-outline:before{content:"\f4b4"}.ion-ios-sunny:before{content:"\f4b7"}.ion-ios-sunny-outline:before{content:"\f4b6"}.ion-ios-telephone:before{content:"\f4b9"}.ion-ios-telephone-outline:before{content:"\f4b8"}.ion-ios-tennisball:before{content:"\f4bb"}.ion-ios-tennisball-outline:before{content:"\f4ba"}.ion-ios-thunderstorm:before{content:"\f4bd"}.ion-ios-thunderstorm-outline:before{content:"\f4bc"}.ion-ios-time:before{content:"\f4bf"}.ion-ios-time-outline:before{content:"\f4be"}.ion-ios-timer:before{content:"\f4c1"}.ion-ios-timer-outline:before{content:"\f4c0"}.ion-ios-toggle:before{content:"\f4c3"}.ion-ios-toggle-outline:before{content:"\f4c2"}.ion-ios-trash:before{content:"\f4c5"}.ion-ios-trash-outline:before{content:"\f4c4"}.ion-ios-undo:before{content:"\f4c7"}.ion-ios-undo-outline:before{content:"\f4c6"}.ion-ios-unlocked:before{content:"\f4c9"}.ion-ios-unlocked-outline:before{content:"\f4c8"}.ion-ios-upload:before{content:"\f4cb"}.ion-ios-upload-outline:before{content:"\f4ca"}.ion-ios-videocam:before{content:"\f4cd"}.ion-ios-videocam-outline:before{content:"\f4cc"}.ion-ios-volume-high:before{content:"\f4ce"}.ion-ios-volume-low:before{content:"\f4cf"}.ion-ios-wineglass:before{content:"\f4d1"}.ion-ios-wineglass-outline:before{content:"\f4d0"}.ion-ios-world:before{content:"\f4d3"}.ion-ios-world-outline:before{content:"\f4d2"}.ion-ipad:before{content:"\f1f9"}.ion-iphone:before{content:"\f1fa"}.ion-ipod:before{content:"\f1fb"}.ion-jet:before{content:"\f295"}.ion-key:before{content:"\f296"}.ion-knife:before{content:"\f297"}.ion-laptop:before{content:"\f1fc"}.ion-leaf:before{content:"\f1fd"}.ion-levels:before{content:"\f298"}.ion-lightbulb:before{content:"\f299"}.ion-link:before{content:"\f1fe"}.ion-load-a:before{content:"\f29a"}.ion-load-b:before{content:"\f29b"}.ion-load-c:before{content:"\f29c"}.ion-load-d:before{content:"\f29d"}.ion-location:before{content:"\f1ff"}.ion-lock-combination:before{content:"\f4d4"}.ion-locked:before{content:"\f200"}.ion-log-in:before{content:"\f29e"}.ion-log-out:before{content:"\f29f"}.ion-loop:before{content:"\f201"}.ion-magnet:before{content:"\f2a0"}.ion-male:before{content:"\f2a1"}.ion-man:before{content:"\f202"}.ion-map:before{content:"\f203"}.ion-medkit:before{content:"\f2a2"}.ion-merge:before{content:"\f33f"}.ion-mic-a:before{content:"\f204"}.ion-mic-b:before{content:"\f205"}.ion-mic-c:before{content:"\f206"}.ion-minus:before{content:"\f209"}.ion-minus-circled:before{content:"\f207"}.ion-minus-round:before{content:"\f208"}.ion-model-s:before{content:"\f2c1"}.ion-monitor:before{content:"\f20a"}.ion-more:before{content:"\f20b"}.ion-mouse:before{content:"\f340"}.ion-music-note:before{content:"\f20c"}.ion-navicon:before{content:"\f20e"}.ion-navicon-round:before{content:"\f20d"}.ion-navigate:before{content:"\f2a3"}.ion-network:before{content:"\f341"}.ion-no-smoking:before{content:"\f2c2"}.ion-nuclear:before{content:"\f2a4"}.ion-outlet:before{content:"\f342"}.ion-paintbrush:before{content:"\f4d5"}.ion-paintbucket:before{content:"\f4d6"}.ion-paper-airplane:before{content:"\f2c3"}.ion-paperclip:before{content:"\f20f"}.ion-pause:before{content:"\f210"}.ion-person:before{content:"\f213"}.ion-person-add:before{content:"\f211"}.ion-person-stalker:before{content:"\f212"}.ion-pie-graph:before{content:"\f2a5"}.ion-pin:before{content:"\f2a6"}.ion-pinpoint:before{content:"\f2a7"}.ion-pizza:before{content:"\f2a8"}.ion-plane:before{content:"\f214"}.ion-planet:before{content:"\f343"}.ion-play:before{content:"\f215"}.ion-playstation:before{content:"\f30a"}.ion-plus:before{content:"\f218"}.ion-plus-circled:before{content:"\f216"}.ion-plus-round:before{content:"\f217"}.ion-podium:before{content:"\f344"}.ion-pound:before{content:"\f219"}.ion-power:before{content:"\f2a9"}.ion-pricetag:before{content:"\f2aa"}.ion-pricetags:before{content:"\f2ab"}.ion-printer:before{content:"\f21a"}.ion-pull-request:before{content:"\f345"}.ion-qr-scanner:before{content:"\f346"}.ion-quote:before{content:"\f347"}.ion-radio-waves:before{content:"\f2ac"}.ion-record:before{content:"\f21b"}.ion-refresh:before{content:"\f21c"}.ion-reply:before{content:"\f21e"}.ion-reply-all:before{content:"\f21d"}.ion-ribbon-a:before{content:"\f348"}.ion-ribbon-b:before{content:"\f349"}.ion-sad:before{content:"\f34a"}.ion-sad-outline:before{content:"\f4d7"}.ion-scissors:before{content:"\f34b"}.ion-search:before{content:"\f21f"}.ion-settings:before{content:"\f2ad"}.ion-share:before{content:"\f220"}.ion-shuffle:before{content:"\f221"}.ion-skip-backward:before{content:"\f222"}.ion-skip-forward:before{content:"\f223"}.ion-social-android:before{content:"\f225"}.ion-social-android-outline:before{content:"\f224"}.ion-social-angular:before{content:"\f4d9"}.ion-social-angular-outline:before{content:"\f4d8"}.ion-social-apple:before{content:"\f227"}.ion-social-apple-outline:before{content:"\f226"}.ion-social-bitcoin:before{content:"\f2af"}.ion-social-bitcoin-outline:before{content:"\f2ae"}.ion-social-buffer:before{content:"\f229"}.ion-social-buffer-outline:before{content:"\f228"}.ion-social-chrome:before{content:"\f4db"}.ion-social-chrome-outline:before{content:"\f4da"}.ion-social-codepen:before{content:"\f4dd"}.ion-social-codepen-outline:before{content:"\f4dc"}.ion-social-css3:before{content:"\f4df"}.ion-social-css3-outline:before{content:"\f4de"}.ion-social-designernews:before{content:"\f22b"}.ion-social-designernews-outline:before{content:"\f22a"}.ion-social-dribbble:before{content:"\f22d"}.ion-social-dribbble-outline:before{content:"\f22c"}.ion-social-dropbox:before{content:"\f22f"}.ion-social-dropbox-outline:before{content:"\f22e"}.ion-social-euro:before{content:"\f4e1"}.ion-social-euro-outline:before{content:"\f4e0"}.ion-social-facebook:before{content:"\f231"}.ion-social-facebook-outline:before{content:"\f230"}.ion-social-foursquare:before{content:"\f34d"}.ion-social-foursquare-outline:before{content:"\f34c"}.ion-social-freebsd-devil:before{content:"\f2c4"}.ion-social-github:before{content:"\f233"}.ion-social-github-outline:before{content:"\f232"}.ion-social-google:before{content:"\f34f"}.ion-social-google-outline:before{content:"\f34e"}.ion-social-googleplus:before{content:"\f235"}.ion-social-googleplus-outline:before{content:"\f234"}.ion-social-hackernews:before{content:"\f237"}.ion-social-hackernews-outline:before{content:"\f236"}.ion-social-html5:before{content:"\f4e3"}.ion-social-html5-outline:before{content:"\f4e2"}.ion-social-instagram:before{content:"\f351"}.ion-social-instagram-outline:before{content:"\f350"}.ion-social-javascript:before{content:"\f4e5"}.ion-social-javascript-outline:before{content:"\f4e4"}.ion-social-linkedin:before{content:"\f239"}.ion-social-linkedin-outline:before{content:"\f238"}.ion-social-markdown:before{content:"\f4e6"}.ion-social-nodejs:before{content:"\f4e7"}.ion-social-octocat:before{content:"\f4e8"}.ion-social-pinterest:before{content:"\f2b1"}.ion-social-pinterest-outline:before{content:"\f2b0"}.ion-social-python:before{content:"\f4e9"}.ion-social-reddit:before{content:"\f23b"}.ion-social-reddit-outline:before{content:"\f23a"}.ion-social-rss:before{content:"\f23d"}.ion-social-rss-outline:before{content:"\f23c"}.ion-social-sass:before{content:"\f4ea"}.ion-social-skype:before{content:"\f23f"}.ion-social-skype-outline:before{content:"\f23e"}.ion-social-snapchat:before{content:"\f4ec"}.ion-social-snapchat-outline:before{content:"\f4eb"}.ion-social-tumblr:before{content:"\f241"}.ion-social-tumblr-outline:before{content:"\f240"}.ion-social-tux:before{content:"\f2c5"}.ion-social-twitch:before{content:"\f4ee"}.ion-social-twitch-outline:before{content:"\f4ed"}.ion-social-twitter:before{content:"\f243"}.ion-social-twitter-outline:before{content:"\f242"}.ion-social-usd:before{content:"\f353"}.ion-social-usd-outline:before{content:"\f352"}.ion-social-vimeo:before{content:"\f245"}.ion-social-vimeo-outline:before{content:"\f244"}.ion-social-whatsapp:before{content:"\f4f0"}.ion-social-whatsapp-outline:before{content:"\f4ef"}.ion-social-windows:before{content:"\f247"}.ion-social-windows-outline:before{content:"\f246"}.ion-social-wordpress:before{content:"\f249"}.ion-social-wordpress-outline:before{content:"\f248"}.ion-social-yahoo:before{content:"\f24b"}.ion-social-yahoo-outline:before{content:"\f24a"}.ion-social-yen:before{content:"\f4f2"}.ion-social-yen-outline:before{content:"\f4f1"}.ion-social-youtube:before{content:"\f24d"}.ion-social-youtube-outline:before{content:"\f24c"}.ion-soup-can:before{content:"\f4f4"}.ion-soup-can-outline:before{content:"\f4f3"}.ion-speakerphone:before{content:"\f2b2"}.ion-speedometer:before{content:"\f2b3"}.ion-spoon:before{content:"\f2b4"}.ion-star:before{content:"\f24e"}.ion-stats-bars:before{content:"\f2b5"}.ion-steam:before{content:"\f30b"}.ion-stop:before{content:"\f24f"}.ion-thermometer:before{content:"\f2b6"}.ion-thumbsdown:before{content:"\f250"}.ion-thumbsup:before{content:"\f251"}.ion-toggle:before{content:"\f355"}.ion-toggle-filled:before{content:"\f354"}.ion-transgender:before{content:"\f4f5"}.ion-trash-a:before{content:"\f252"}.ion-trash-b:before{content:"\f253"}.ion-trophy:before{content:"\f356"}.ion-tshirt:before{content:"\f4f7"}.ion-tshirt-outline:before{content:"\f4f6"}.ion-umbrella:before{content:"\f2b7"}.ion-university:before{content:"\f357"}.ion-unlocked:before{content:"\f254"}.ion-upload:before{content:"\f255"}.ion-usb:before{content:"\f2b8"}.ion-videocamera:before{content:"\f256"}.ion-volume-high:before{content:"\f257"}.ion-volume-low:before{content:"\f258"}.ion-volume-medium:before{content:"\f259"}.ion-volume-mute:before{content:"\f25a"}.ion-wand:before{content:"\f358"}.ion-waterdrop:before{content:"\f25b"}.ion-wifi:before{content:"\f25c"}.ion-wineglass:before{content:"\f2b9"}.ion-woman:before{content:"\f25d"}.ion-wrench:before{content:"\f2ba"}.ion-xbox:before{content:"\f30c"} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/css/menu.css b/net452/SiteServer.Web/SiteServer/assets/css/menu.css new file mode 100644 index 000000000..a0450b98f --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/css/menu.css @@ -0,0 +1,1376 @@ +/* +Template Name: Minton Dashboard +Author: CoderThemes +Email: coderthemes@gmail.com +File: Topbar,Left-sidebar,Right-sidebar +*/ +.topbar { + left: 0px; + position: fixed; + right: 0; + top: 0px; + z-index: 999; +} + +.topbar .topbar-left { + background: #282c37; + float: left; + height: 70px; + position: relative; + width: 240px; + z-index: 1; +} + +.navbar-default { + background-color: #323944; + border-radius: 0px; + border: none; + margin-bottom: 0px; +} + +.navbar-default .navbar-nav>.open>a { + background-color: rgba(0, 0, 0, 0.06); +} + +.navbar-default .navbar-nav>.open>a:focus { + background-color: rgba(0, 0, 0, 0.06); +} + +.navbar-default .navbar-nav>.open>a:hover { + background-color: rgba(0, 0, 0, 0.06); +} + +.nav>li>a { + color: #ffffff !important; + line-height: 70px; + padding: 0px 15px; + position: relative; +} + +.nav>li>a i { + font-size: 20px; +} + +.profile img { + border: 2px solid #edf0f0; + height: 36px; + width: 36px; +} + +.dropdown-menu-lg { + width: 300px; +} + +.dropdown-menu-lg .list-group { + margin-bottom: 0px; +} + +.dropdown-menu-lg .list-group-item { + border: none; + padding: 10px 20px; +} + +.dropdown-menu-lg .media-heading { + margin-bottom: 0px; +} + +.dropdown-menu-lg .media-body p { + color: #828282; +} + +.notifi-title { + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + color: #000000; + font-size: 16px; + font-weight: 400; + padding: 5px 0px 10px; +} + +.notification-list em { + width: 30px; + text-align: center; + height: 30px; + line-height: 28px; + border-radius: 50%; + margin-top: 4px; +} + +.notification-list .list-group-item { + padding: 12px 20px; +} + +.notification-list .media-body { + display: inherit; + width: auto; + overflow: hidden; + margin-left: 50px; +} + +.notification-list .media-body h5 { + text-overflow: ellipsis; + white-space: nowrap; + display: block; + width: 100%; + font-weight: normal; + overflow: hidden; +} + +.noti-primary { + color: #00b19d; + border: 2px solid #00b19d; +} + +.noti-success { + color: #00b19d; + border: 2px solid #00b19d; +} + +.noti-info { + color: #3ddcf7; + border: 2px solid #3ddcf7; +} + +.noti-warning { + color: #ffaa00; + border: 2px solid #ffaa00; +} + +.noti-danger { + color: #ef5350; + border: 2px solid #ef5350; +} + +.noti-purple { + color: #7266ba; + border: 2px solid #7266ba; +} + +.noti-pink { + color: #f76397; + border: 2px solid #f76397; +} + +.noti-inverse { + color: #4c5667; + border: 2px solid #4c5667; +} + +.navbar-form { + border: none; + box-shadow: none; + padding: 0px; +} + +.app-search { + position: relative; + margin: 15px 0px 15px 10px; +} + +.app-search a { + position: absolute; + top: 10px; + right: 20px; + color: rgba(255, 255, 255, 0.7); +} + +.app-search a:hover { + color: #ffffff; +} + +.app-search .form-control, +.app-search .form-control:focus { + border: none; + font-size: 13px; + color: #ffffff; + font-weight: 600; + padding-left: 20px; + padding-right: 40px; + margin-top: 3px; + background: rgba(255, 255, 255, 0.2); + box-shadow: none; + border-radius: 30px; + width: 190px; +} + +input.app-search-input::-webkit-input-placeholder { + color: rgba(255, 255, 255, 0.7); + font-weight: normal; +} + +input.app-search-input:-moz-placeholder { + color: rgba(255, 255, 255, 0.7); +} + +input.app-search-input::-moz-placeholder { + color: rgba(255, 255, 255, 0.7); +} + +input.app-search-input:-ms-input-placeholder { + color: rgba(255, 255, 255, 0.7); +} + +.navbar-nav { + margin: 0px; +} + +.side-menu { + bottom: 0; + top: 0; + width: 200px; + z-index: 2; +} + +.side-menu.left { + background: #eeeeee; + box-shadow: -4px 4px 40px rgba(0, 0, 0, 0.15); + position: absolute; + top: 62px; +} + +body.fixed-left .side-menu.left { + bottom: 50px; + height: 100%; + margin-top: 0; + position: fixed; +} + +.content-page { + margin-left: 200px; + overflow: hidden; + background: #fff; + width: 100%; + height: 100%; + margin-top: 0; + position: fixed; +} + +.content-page>.content { + margin-bottom: 60px; + margin-top: 10px; + padding: 20px 5px 15px 5px; +} + +.button-menu-mobile { + background: transparent; + border: none; + color: #ffffff; + font-size: 21px; + line-height: 70px; + padding: 0px 15px; +} + +.button-menu-mobile:hover { + color: #eeeeee; +} + +.sidebar-inner { + height: 100%; + overflow: auto; +} + +#sidebar-menu, +#sidebar-menu ul, +#sidebar-menu li, +#sidebar-menu a { + border: 0; + font-family: 'Microsoft YaHei', sans-serif; + font-weight: normal; + line-height: 1; + font-size: 14px; + list-style: none; + margin: 0; + padding: 0; + position: relative; + text-decoration: none; +} + +#sidebar-menu { + background-color: #eeeeee; + width: 100%; +} + +#sidebar-menu a { + line-height: 1.3; +} + +#sidebar-menu a.badge { + display: block; + padding: 1px 5px; + font-weight: 600; + font-size: 12px; + float: right; + border-left: 0 !important; +} + +#sidebar-menu a.badge:hover { + background: #ffc107; + border-left: 0 !important; +} + +#sidebar-menu ul li .menu-arrow { + -webkit-transition: -webkit-transform 0.15s; + -o-transition: -o-transform 0.15s; + transition: transform .15s; + position: absolute; + right: 25px; + display: inline-block; + font-family: 'Ionicons'; + text-rendering: auto; + line-height: 25px; + font-size: 18px; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); + color: #98a6ad; +} + +#sidebar-menu ul li .menu-arrow:before { + content: "\f3d3"; +} + +#sidebar-menu ul li a.subdrop .menu-arrow { + -ms-transform: rotate(90deg); + -webkit-transform: rotate(90deg); + -o-transform: rotate(90deg); + transform: rotate(90deg); +} + +#sidebar-menu ul ul li { + border-top: 0; +} + +#sidebar-menu ul ul li.active a { + background: #ddd; + color: #00b19d; +} + +#sidebar-menu ul ul a { + color: #55565d; + display: block; + padding: 10px 10px 10px 45px; +} + +#sidebar-menu ul ul a:hover { + color: #00b19d; +} + +#sidebar-menu ul ul a i { + margin-right: 5px; +} + +#sidebar-menu ul ul ul a { + padding-left: 80px; +} + +#sidebar-menu>ul>li>a { + color: #565b5e; + border-left: 2px solid transparent; + display: block; + padding: 12px 10px; + font-size: 15px; +} + +#sidebar-menu>ul>li>a:hover { + background: #f5f5f5; + border-left: 2px solid #00b19d !important; +} + +#sidebar-menu>ul>li>a:hover i { + color: #00b19d !important; +} + +#sidebar-menu>ul>li>a:hover span { + color: #4c5667; +} + +#sidebar-menu>ul>li>a>span { + vertical-align: middle; +} + +#sidebar-menu>ul>li>a>i { + display: inline-block; + font-size: 18px; + line-height: 17px; + margin-left: 3px; + margin-right: 12px; + color: #565b5e; + text-align: center; + vertical-align: middle; + width: 20px; +} + +#sidebar-menu>ul>li>a>i.i-right { + float: right; + margin: 3px 0 0 0; +} + +#sidebar-menu>ul>li>a.active { + background: #f5f5f5; + border-left: 2px solid #00b19d !important; +} + +#sidebar-menu>ul>li>a.active i { + color: #00b19d !important; +} + +#sidebar-menu>ul>li>a.active span { + color: #4c5667; +} + +.menu-title { + padding: 12px 20px !important; + letter-spacing: .035em; + font-size: 15px !important; + margin-top: 10px !important; + font-weight: 500 !important; + padding-left: 32px !important; +} + +#sidebar-menu>ul>li>a.active.subdrop { + background: #f5f5f5 !important; + border-left: 2px solid #00b19d; +} + +#sidebar-menu>ul>li>a.active.subdrop i { + color: #00b19d; +} + +.subdrop { + background: #f5f5f5; + border-left: 2px solid #00b19d !important; +} + +.subdrop i { + color: #00b19d !important; +} + +.subdrop span { + color: #00b19d !important; +} + +#wrapper.enlarged .menu-title, +#wrapper.enlarged .menu-arrow { + display: none !important; +} + +#wrapper.enlarged #sidebar-menu ul ul { + box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); +} + +#wrapper.enlarged .left.side-menu { + width: 70px; + z-index: 5; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu>ul>li>a { + padding-left: 10px; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu>ul>li>a:hover { + background-color: #f5f5f5 !important; +} + +#wrapper.enlarged .left.side-menu span.pull-right { + display: none !important; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li { + position: relative; + white-space: nowrap; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li:hover>a { + background: #f5f5f5; + position: relative; + width: 260px; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li:hover>ul { + display: block; + left: 70px; + position: absolute; + width: 190px; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li:hover>ul a { + background: #ffffff; + border: none; + box-shadow: none; + padding-left: 15px; + position: relative; + width: 190px; + z-index: 6; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li:hover a span { + display: inline; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li>ul { + display: none; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul ul li:hover>ul { + display: block; + left: 190px; + margin-top: -36px; + position: absolute; + width: 190px; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul ul li>a span.pull-right { + -ms-transform: rotate(270deg); + -webkit-transform: rotate(270deg); + position: absolute; + right: 20px; + top: 12px; + transform: rotate(270deg); +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li>a span { + display: none; + padding-left: 10px; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu>ul>li>a>i { + margin: 0px; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu>ul>li>a { + padding: 15px 20px; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu>ul>li>a i { + margin-right: 20px !important; + font-size: 20px; + color: #a2acae; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li:hover>a { + position: relative; + width: 260px; + background: #f5f5f5; + color: #00b19d; + border-color: #00b19d; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li:hover>a i { + color: #00b19d; +} + +#wrapper.enlarged .content-page { + margin-left: 70px; +} + +#wrapper.enlarged .topbar .topbar-left { + width: 70px !important; +} + +#wrapper.enlarged .topbar .topbar-left .logo span { + display: none; + opacity: 0; +} + +#wrapper.enlarged .topbar .topbar-left .logo i { + margin-right: 0px; +} + +#wrapper.enlarged #sidebar-menu>ul>li:hover>a.open :after { + display: none; +} + +#wrapper.enlarged #sidebar-menu>ul>li:hover>a.active :after { + display: none; +} + +#wrapper.enlarged .user-detail { + bottom: 0px; + padding: 13px 0px; + width: 70px; + text-align: center; +} + +#wrapper.enlarged .user-detail .dropup { + margin: 0px auto; + margin-left: 17px; +} + +#wrapper.enlarged .user-detail h5 { + display: none; +} + +#wrapper.enlarged .user-detail p { + position: absolute; + right: 12px; + top: 22px; +} + +#wrapper.enlarged .user-detail p span { + display: none; +} + +#wrapper.enlarged #sidebar-menu ul ul li.active a { + color: #00b19d; +} + +#wrapper.enlarged .footer { + left: 70px; +} + +#wrapper.right-bar-enabled .right-bar { + right: 0; +} + +#wrapper.right-bar-enabled .left-layout { + left: 0; +} + +.right-bar-toggle:focus { + background-color: rgba(0, 0, 0, 0.06) !important; +} + +.side-bar.right-bar { + float: right !important; + right: -270px; + bottom: 0px; + top: 70px; +} + +.side-bar { + -moz-transition: all 200ms ease-out; + -webkit-transition: all 200ms ease-out; + background-color: #ffffff; + box-shadow: 0px 0px 8px 1px rgba(0, 0, 0, 0.1); + display: block; + overflow-y: auto; + position: fixed; + transition: all 200ms ease-out; + width: 200px; +} + +.side-bar .nav.nav-tabs+.tab-content { + margin-bottom: 0px; + padding: 20px; +} + +.side-bar .tabs li.tab a { + font-weight: 600; +} + +.right-bar { + background: #ffffff !important; + position: fixed !important; + z-index: 99 !important; +} + +.right-bar h4 { + border-bottom: 1px solid #eeeeee; + padding-bottom: 10px; +} + +.right-bar .nicescroll { + height: 100%; +} + + +/*---------------------------------------------------------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------------------------------------------------------------*/ +/*---------------------------------------------------------------------------------------------------------------------------------*/ + + + +#topnav { + right: 0; + left: 0; + top: 0; + z-index: 1030; + background-color: transparent; + border: 0; + -webkit-transition: all .5s ease; + transition: all .5s ease; + min-height: 62px; +} + +#topnav .has-submenu.active a { + color: #fff; +} + +#topnav .has-submenu.active a i { + color: #fff; +} + +#topnav .has-submenu.active .submenu li.active a { + color: #00b19d; +} + +#topnav .topbar-main { + font-family: 'Microsoft YaHei', sans-serif; + background-color: #00b19d; + height: 62px; +} + +#topnav .topbar-main .logo { + color: #ffffff !important; + font-size: 18px; + font-weight: 700; + letter-spacing: .05em; + margin-top: 8px; + margin-left: 8px; + float: left; +} + +#topnav .topbar-main .toggle { + color: #ffffff !important; + font-size: 18px; + font-weight: 700; + letter-spacing: .05em; + margin-top: 9px; + margin-left: 5px; + float: left; + text-decoration: none; +} + +#topnav .topbar-main .logo h1 { + margin: 0px auto; + text-align: center; +} + +#topnav .topbar-main .logo i { + color: #ffffff; +} + +#topnav .topbar-main .badge { + position: absolute; + top: 12px; + right: -5px; +} + +#topnav .topbar-main .nav>li>a { + color: #ffffff !important; + line-height: 60px; + padding: 0px 15px !important; + position: relative; + background: transparent !important; +} + +#topnav .topbar-main .nav>li>a i { + font-size: 24px; +} + +#topnav .topbar-main .nav>li>a { + padding: 0px 15px !important; +} + +#topnav .topbar-main .navbar-nav>.open>a { + background-color: rgba(255, 255, 255, 0.1) !important; +} + +#topnav .topbar-main .profile img { + border: 2px solid #edf0f0; + height: 36px; + width: 36px; +} + +#topnav .topbar-main .dropdown-menu-lg { + width: 300px; +} + +#topnav .topbar-main .dropdown-menu-lg .list-group { + margin-bottom: 0px; +} + +#topnav .topbar-main .dropdown-menu-lg .list-group-item { + border: none; + padding: 10px 20px; +} + +#topnav .topbar-main .dropdown-menu-lg .media-heading { + margin-bottom: 0px; +} + +#topnav .topbar-main .dropdown-menu-lg .media-body p { + color: #828282; +} + +#topnav .topbar-main .notification-list { + max-height: 230px; +} + +#topnav .topbar-main .notification-list em { + width: 34px; + text-align: center; +} + +#topnav .topbar-main .notification-list .media-body { + display: inherit; + width: auto; + overflow: hidden; + margin-left: 50px; +} + +#topnav .topbar-main .notification-list .media-body h5 { + text-overflow: ellipsis; + white-space: nowrap; + display: block; + width: 100%; + font-weight: normal; + overflow: hidden; +} + +#topnav .topbar-main .notifi-title { + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + font-size: 15px; + text-transform: uppercase; + font-weight: 600; + padding: 11px 20px 15px; + color: #4c5667; + font-family: 'Microsoft YaHei', sans-serif; +} + +#topnav .topbar-main .navbar-nav { + margin: 0px; +} + +#topnav .app-search { + position: relative; + margin: 15px 20px 15px 10px; +} + +#topnav .app-search a { + position: absolute; + top: 5px; + right: 15px; + color: rgba(255, 255, 255, 0.7); +} + +#topnav .app-search a i { + font-size: 18px; +} + +#topnav .app-search .form-control, +#topnav .app-search .form-control:focus { + border: none; + font-size: 13px; + color: #ffffff; + padding-left: 20px; + padding-right: 40px; + background: rgba(255, 255, 255, 0.1); + box-shadow: none; + border-radius: 30px; + height: 30px; + width: 180px; +} + +#topnav .app-search input::-webkit-input-placeholder { + color: rgba(255, 255, 255, 0.7); + font-weight: normal; +} + +#topnav .app-search input:-moz-placeholder { + color: rgba(255, 255, 255, 0.7); +} + +#topnav .app-search input::-moz-placeholder { + color: rgba(255, 255, 255, 0.7); +} + +#topnav .app-search input:-ms-input-placeholder { + color: rgba(255, 255, 255, 0.7); +} + +#topnav .notifi-title { + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + color: #000000; + font-size: 16px; + font-weight: 400; + padding: 5px 0px 10px; +} + +#topnav .notification-list em { + width: 30px; + text-align: center; + height: 30px; + line-height: 28px; + border-radius: 50%; + margin-top: 4px; +} + +#topnav .notification-list .list-group-item { + padding: 12px 20px; +} + +#topnav .notification-list .media-body { + display: inherit; + width: auto; + overflow: hidden; + margin-left: 50px; +} + +#topnav .notification-list .media-body h5 { + text-overflow: ellipsis; + white-space: nowrap; + display: block; + width: 100%; + font-weight: normal; + overflow: hidden; +} + +#topnav .noti-primary { + color: #00b19d; + border: 2px solid #00b19d; +} + +#topnav .noti-success { + color: #3bafda; + border: 2px solid #3bafda; +} + +#topnav .noti-info { + color: #3ddcf7; + border: 2px solid #3ddcf7; +} + +#topnav .noti-warning { + color: #ffaa00; + border: 2px solid #ffaa00; +} + +#topnav .noti-danger { + color: #ef5350; + border: 2px solid #ef5350; +} + +#topnav .noti-purple { + color: #7266ba; + border: 2px solid #7266ba; +} + +#topnav .noti-pink { + color: #f76397; + border: 2px solid #f76397; +} + +#topnav .noti-inverse { + color: #4c5667; + border: 2px solid #4c5667; +} + +#topnav .navbar-custom { + background-color: #ffffff; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); +} + +#topnav .navbar-toggle { + border: 0; + position: relative; + width: 60px; + height: 60px; + padding: 0; + margin: 0; + cursor: pointer; +} + +#topnav .navbar-toggle:hover { + background-color: transparent; +} + +#topnav .navbar-toggle:hover span { + background-color: #ffffff; +} + +#topnav .navbar-toggle:focus { + background-color: transparent; +} + +#topnav .navbar-toggle:focus span { + background-color: #00b19d; +} + +#topnav .navbar-toggle .lines { + width: 25px; + display: block; + position: relative; + margin: 23px auto 17px auto; + height: 18px; +} + +#topnav .navbar-toggle span { + height: 2px; + width: 100%; + background-color: #fff; + display: block; + margin-bottom: 5px; + -webkit-transition: -webkit-transform 0.5s ease; + transition: -webkit-transform 0.5s ease; + transition: transform .5s ease; +} + +#topnav .navbar-toggle.open span { + position: absolute; +} + +#topnav .navbar-toggle.open span:first-child { + top: 6px; + -webkit-transform: rotate(45deg); + transform: rotate(45deg); +} + +#topnav .navbar-toggle.open span:nth-child(2) { + visibility: hidden; +} + +#topnav .navbar-toggle.open span:last-child { + width: 100%; + top: 6px; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); +} + +#topnav .navigation-menu { + list-style: none; + margin: 0; + padding: 0; + margin-left: 210px; +} + +#topnav .navigation-menu>li { + float: left; + display: block; + position: relative; +} + +#topnav .navigation-menu>li>a { + display: block; + color: #fff; + font-weight: 500; + font-size: 14px; + -webkit-transition: all .3s ease; + transition: all .3s ease; + line-height: 20px; + padding-left: 15px; + padding-right: 15px; + text-decoration: none; +} + +#topnav .navigation-menu>li.active>a { + font-weight: 800; +} + +#topnav .navigation-menu>li>a:hover { + color: #fff; +} + +#topnav .navigation-menu>li>a:hover i { + color: #fff; +} + +#topnav .navigation-menu>li>a:focus { + color: #fff; +} + +#topnav .navigation-menu>li>a:focus i { + color: #fff; +} + +#topnav .navigation-menu>li>a:active { + color: #fff; +} + +#topnav .navigation-menu>li>a:active i { + color: #fff; +} + +#topnav .navigation-menu>li>a i { + font-size: 18px; + margin-right: 5px; + color: #fff; +} + +#topnav .navigation-menu>li>a:hover, +#topnav .navigation-menu>li>a:focus { + background-color: transparent; +} + +@media (min-width: 992px) { + #topnav .navigation-menu>li>a { + padding-top: 22px; + padding-bottom: 12px; + } +} + +/* + Responsive Menu +*/ +@media (min-width: 992px) { + #topnav .navigation-menu>li.last-elements .submenu { + left: auto; + right: 0; + } + + #topnav .navigation-menu>li.last-elements .submenu>li.has-submenu .submenu { + left: auto; + right: 100%; + margin-left: 0; + margin-right: 10px; + } + + #topnav .navigation-menu>li:hover a { + color: #fff; + } + + #topnav .navigation-menu>li:hover a i { + color: #fff; + } + + #topnav .navigation-menu>li .submenu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + border: 1px solid #e7e7e7; + padding: 15px 0; + list-style: none; + min-width: 200px; + visibility: hidden; + opacity: 0; + margin-top: 10px; + -webkit-transition: all .2s ease; + transition: all .2s ease; + background-color: #ffffff; + box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.1); + } + + #topnav .navigation-menu>li .submenu.megamenu { + white-space: nowrap; + width: auto; + } + + #topnav .navigation-menu>li .submenu.megamenu>li { + overflow: hidden; + width: 200px; + display: inline-block; + vertical-align: top; + } + + #topnav .navigation-menu>li .submenu>li.has-submenu>a:after { + content: "\f3d3"; + font-family: 'Ionicons'; + position: absolute; + right: 20px; + font-size: 16px; + top: 8px; + } + + #topnav .navigation-menu>li .submenu>li .submenu { + left: 100%; + top: 0; + margin-left: 10px; + margin-top: -1px; + } + + #topnav .navigation-menu>li .submenu li { + position: relative; + } + + #topnav .navigation-menu>li .submenu li ul { + list-style: none; + padding-left: 0; + margin: 0; + } + + #topnav .navigation-menu>li .submenu li a { + display: block; + padding: 8px 25px; + clear: both; + white-space: nowrap; + font-weight: 500; + font-size: 14px; + text-decoration: none; + color: #494e53; + } + + #topnav .navigation-menu>li .submenu li a:hover { + color: #00b19d; + } + + #topnav .navigation-menu>li .submenu li span { + display: block; + padding: 8px 25px; + clear: both; + line-height: 1.42857143; + white-space: nowrap; + font-size: 10px; + text-transform: uppercase; + letter-spacing: 2px; + font-weight: 500; + color: #949ba1; + } + + #topnav .navbar-toggle { + display: none; + } + + #topnav #navigation { + display: block !important; + } +} + +@media (max-width: 991px) { + .wrapper { + margin-top: 80px; + } + + .container { + width: auto; + } + + #topnav .navigation-menu { + float: none; + max-height: 400px; + } + + #topnav .navigation-menu>li { + float: none; + } + + #topnav .navigation-menu>li>a { + color: #797979; + padding: 15px; + } + + #topnav .navigation-menu>li>a i { + display: inline-block; + margin-right: 10px; + margin-bottom: 0px; + } + + #topnav .navigation-menu>li>a:after { + position: absolute; + right: 15px; + } + + #topnav .navigation-menu>li .submenu { + display: none; + list-style: none; + padding-left: 20px; + margin: 0; + } + + #topnav .navigation-menu>li .submenu li a { + display: block; + position: relative; + padding: 7px 20px; + color: #797979; + } + + #topnav .navigation-menu>li .submenu li a:hover { + color: #00b19d; + } + + #topnav .navigation-menu>li .submenu li.has-submenu>a:after { + content: "\e64b"; + font-family: "themify"; + position: absolute; + right: 30px; + } + + #topnav .navigation-menu>li .submenu.open { + display: block; + } + + #topnav .navigation-menu>li .submenu .submenu { + display: none; + list-style: none; + } + + #topnav .navigation-menu>li .submenu .submenu.open { + display: block; + } + + #topnav .navigation-menu>li .submenu.megamenu>li>ul { + list-style: none; + padding-left: 0; + } + + #topnav .navigation-menu>li .submenu.megamenu>li>ul>li>span { + display: block; + position: relative; + padding: 15px; + text-transform: uppercase; + font-size: 11px; + letter-spacing: 2px; + color: #79818a; + } + + #topnav .navigation-menu>li.has-submenu.open>a { + color: #00b19d; + } + + #topnav .navbar-header { + float: left; + } + + #navigation { + position: absolute; + top: 60px; + left: 0; + width: 100%; + display: none; + height: auto; + padding-bottom: 0; + overflow: auto; + border-top: 1px solid #e7e7e7; + border-bottom: 1px solid #e7e7e7; + background-color: #fff; + } + + #navigation.open { + display: block; + overflow-y: auto; + } +} + +@media (min-width: 768px) { + #topnav .navigation-menu>li.has-submenu:hover>.submenu { + visibility: visible; + opacity: 1; + margin-top: 0; + } + + #topnav .navigation-menu>li.has-submenu:hover>.submenu>li.has-submenu:hover>.submenu, + #topnav .navigation-menu>li.has-submenu:hover>.submenu>li.has-submenu:hover>.submenu>li.has-submenu:hover>.submenu { + visibility: visible; + opacity: 1; + margin-left: 0; + margin-right: 0; + } + + .navbar-toggle { + display: block; + } +} + +/* Footer */ +.footer { + border-top: 1px solid rgba(0, 0, 0, 0.1); + bottom: 0px; + color: #58666e; + text-align: left !important; + padding: 20px 0px; + position: absolute; + right: 0px; + left: 0px; +} \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/assets/css/pages.css b/net452/SiteServer.Web/SiteServer/assets/css/pages.css similarity index 99% rename from SiteServer.Web/SiteServer/assets/css/pages.css rename to net452/SiteServer.Web/SiteServer/assets/css/pages.css index 134406376..afc078b26 100644 --- a/SiteServer.Web/SiteServer/assets/css/pages.css +++ b/net452/SiteServer.Web/SiteServer/assets/css/pages.css @@ -1088,7 +1088,7 @@ h3.timeline-title { } .wrapper-page .form-control { height: 40px; - padding-left: 40px; + padding-left: 10px; } .wrapper-page .form-control-feedback { left: 15px; diff --git a/SiteServer.Web/SiteServer/assets/css/responsive.css b/net452/SiteServer.Web/SiteServer/assets/css/responsive.css similarity index 100% rename from SiteServer.Web/SiteServer/assets/css/responsive.css rename to net452/SiteServer.Web/SiteServer/assets/css/responsive.css diff --git a/net452/SiteServer.Web/SiteServer/assets/css/siteserver.min.css b/net452/SiteServer.Web/SiteServer/assets/css/siteserver.min.css new file mode 100644 index 000000000..4bf189ee7 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/css/siteserver.min.css @@ -0,0 +1,12 @@ +/*! + * SiteServer UI v1.0.7 (https://www.siteserver.cn) + * Copyright 2013-2018 SiteServer CMS. + * Licensed under GPL-3.0 (https://github.com/siteserver/siteserver-ui/blob/master/LICENSE) + */@charset "UTF-8";.gal-detail h4,.icon-list-demo div,.notification-list .notify-item .notify-details,.user-list .user-list-item .user-desc span.desc,.user-list .user-list-item .user-desc span.name,.widget-user .wid-u-info p{white-space:nowrap;text-overflow:ellipsis}.wrapper{padding-top:120px}.page-title-box{padding:22px 0}.page-title-box .page-title{font-size:20px;margin-bottom:0;margin-top:0;font-weight:600}#topnav{position:fixed;right:0;left:0;top:0;z-index:1030;background-color:transparent;border:0;-webkit-transition:all .5s ease;transition:all .5s ease;min-height:62px}#topnav .has-submenu.active .submenu li.active>a,#topnav .has-submenu.active a,#topnav .has-submenu.active a i{color:#00b19d}#topnav .topbar-main{background-color:#00b19d}#topnav .topbar-main .logo{color:#fff!important;font-size:20px;font-weight:700;letter-spacing:1px;line-height:58px;text-transform:uppercase;float:left}#topnav .topbar-main .logo-small{display:none}#topnav .topbar-main .badge-topbar{position:absolute;top:7px;right:7px;z-index:99}#topnav .topbar-main .nav>li>a{height:36px;width:36px;padding:0;font-size:24px;line-height:35px;text-align:center;border-radius:50%;margin:12px 8px;color:rgba(42,49,66,.7)}#topnav .topbar-main .dropdown-menu-lg .list-group,#topnav .topbar-main .dropdown-menu-lg .media-heading{margin-bottom:0}#topnav .topbar-main .nav>li>a:focus,#topnav .topbar-main .nav>li>a:hover{background-color:rgba(42,49,66,.1);color:#2a3142}#topnav .topbar-main .navbar-nav>.open>a{background-color:rgba(42,49,66,.1)!important}#topnav .topbar-main .profile img{height:34px;width:34px;display:block}#topnav .topbar-main .dropdown-menu-lg .list-group-item{border:none;padding:10px 20px}#topnav .topbar-main .dropdown-menu-lg .media-body p{color:#828282}#topnav .topbar-main .navbar-nav{margin:0}#topnav .app-search{position:relative;margin-top:14px}#topnav .app-search a{position:absolute;top:7px;right:26px;color:rgba(42,49,66,.7)}#topnav .app-search a:hover{color:rgba(42,49,66,.9)}#topnav .app-search .form-control,#topnav .app-search .form-control:focus{border-color:transparent;height:34px;color:#2a3142;border-radius:30px;padding:7px 40px 7px 20px;margin:0 12px 0 5px;background:rgba(42,49,66,.1);box-shadow:none;width:190px}#topnav .app-search input::-webkit-input-placeholder{color:rgba(42,49,66,.8)}#topnav .app-search input:-moz-placeholder{color:rgba(42,49,66,.8)}#topnav .app-search input::-moz-placeholder{color:rgba(42,49,66,.8)}#topnav .app-search input:-ms-input-placeholder{color:rgba(42,49,66,.8)}#topnav .navbar-custom{background-color:#fff;box-shadow:0 1px 1px rgba(0,0,0,.1)}#topnav .navbar-toggle{border:0;position:relative;padding:0;margin:0;cursor:pointer}#topnav .navbar-toggle:hover{background-color:transparent}#topnav .navbar-toggle:hover span{background-color:#fff}#topnav .navbar-toggle:focus{background-color:transparent}#topnav .navbar-toggle:focus span{background-color:#fff}#topnav .navbar-toggle .lines{width:25px;display:block;position:relative;margin:0 10px 0 0;padding-top:13px;height:23px;-webkit-transition:all .5s ease;transition:all .5s ease}#topnav .navbar-toggle span{height:2px;width:100%;background-color:rgba(255,255,255,.8);display:block;margin-bottom:5px;-webkit-transition:-webkit-transform .5s ease;transition:-webkit-transform .5s ease;transition:transform .5s ease}#topnav .navbar-toggle.open span{position:absolute}#topnav .navbar-toggle.open span:first-child{top:18px;-webkit-transform:rotate(45deg);transform:rotate(45deg)}#topnav .navbar-toggle.open span:nth-child(2){visibility:hidden}#topnav .navbar-toggle.open span:last-child{width:100%;top:18px;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}#topnav .navigation-menu{list-style:none;margin:0;padding:0}#topnav .navigation-menu>li{display:inline-block;position:relative}#topnav .navigation-menu>li>a{display:block;color:rgba(42,49,66,.7);font-weight:500;font-size:15px;-webkit-transition:all .5s ease;transition:all .5s ease;line-height:20px;padding-left:25px;padding-right:25px}#topnav .navigation-menu>li>a:active,#topnav .navigation-menu>li>a:focus,#topnav .navigation-menu>li>a:hover{color:#2a3142}#topnav .navigation-menu>li>a i{font-size:16px;margin-right:5px;-webkit-transition:all .5s ease;transition:all .5s ease}#topnav .navigation-menu>li>a:focus,#topnav .navigation-menu>li>a:hover{background-color:transparent}@media (min-width:992px){#topnav .navigation-menu>li>a{padding-top:20px;padding-bottom:20px}#topnav .navigation-menu>li:first-of-type>a{padding-left:0}#topnav .navigation-menu>li.last-elements .submenu{left:auto;right:0}#topnav .navigation-menu>li.last-elements .submenu>li.has-submenu .submenu{left:auto;right:100%;margin-left:0;margin-right:10px}#topnav .navigation-menu>li:hover a,#topnav .navigation-menu>li:hover a i,#topnav .navigation-menu>li>ul>li.has-submenu:active>a,#topnav .navigation-menu>li>ul>li.has-submenu:hover>a{color:#00b19d}#topnav .navigation-menu>li .submenu{position:absolute;top:100%;left:0;z-index:1000;border:1px solid #e7e7e7;padding:15px 0;list-style:none;min-width:200px;text-align:left;visibility:hidden;opacity:0;margin-top:10px;-webkit-transition:all .2s ease;transition:all .2s ease;background-color:#fff;box-shadow:0 2px 6px rgba(0,0,0,.05)}#topnav .navigation-menu>li .submenu.megamenu{white-space:nowrap;width:auto}#topnav .navigation-menu>li .submenu.megamenu>li{overflow:hidden;width:200px;display:inline-block;vertical-align:top}#topnav .navigation-menu>li .submenu>li.has-submenu>a:after{content:"\e649";font-family:themify;position:absolute;right:20px;top:13px;font-size:10px}#topnav .navigation-menu>li .submenu>li .submenu{left:100%;top:0;margin-left:10px;margin-top:-1px}#topnav .navigation-menu>li .submenu li{position:relative}#topnav .navigation-menu>li .submenu li ul{list-style:none;padding-left:0;margin:0}#topnav .navigation-menu>li .submenu li a{display:block;padding:8px 25px;clear:both;white-space:nowrap;font-size:15px;color:#2a3142;-webkit-transition:all .35s ease;transition:all .35s ease}#topnav .navigation-menu>li .submenu li a:hover{color:#00b19d}#topnav .navigation-menu>li .submenu li span{display:block;padding:8px 25px;clear:both;line-height:1.42857143;white-space:nowrap;font-size:10px;text-transform:uppercase;letter-spacing:2px;font-weight:500;color:#2a3142}#topnav .navbar-toggle{display:none}#topnav #navigation{display:block!important}}@media (max-width:991px){.wrapper{padding-top:60px}.container{width:auto!important}#topnav .navigation-menu{float:none;max-height:400px;text-align:left}#topnav .navigation-menu>li{display:block}#topnav .navigation-menu>li>a{color:#2a3142;padding:15px}#topnav .navigation-menu>li>a i{display:inline-block;margin-right:10px;margin-bottom:0;vertical-align:inherit}#topnav .navigation-menu>li>a:after{position:absolute;right:15px}#topnav .navigation-menu>li .submenu{display:none;list-style:none;padding-left:20px;margin:0}#topnav .navigation-menu>li .submenu li a{display:block;position:relative;padding:7px 20px;color:#2a3142}#topnav .navigation-menu>li .submenu li a:hover{color:#00b19d}#topnav .navigation-menu>li .submenu li.has-submenu>a:after{content:"\e64b";font-family:themify;position:absolute;right:30px;font-size:10px}#topnav .navigation-menu>li .submenu.open{display:block}#topnav .navigation-menu>li .submenu .submenu{display:none;list-style:none}#topnav .navigation-menu>li .submenu .submenu.open{display:block}#topnav .navigation-menu>li .submenu.megamenu>li>ul{list-style:none;padding-left:0}#topnav .navigation-menu>li .submenu.megamenu>li>ul>li>span{display:block;position:relative;padding:15px;text-transform:uppercase;font-size:11px;letter-spacing:2px;color:#2a3142}#topnav .has-submenu.active a,#topnav .has-submenu.active a i,#topnav .has-submenu.active a:active,#topnav .has-submenu.active a:focus,#topnav .navigation-menu>li.has-submenu.open>a{color:#00b19d}#topnav .navbar-header{float:left}#navigation{position:absolute;top:60px;left:0;width:100%;display:none;height:auto;padding-bottom:0;overflow:auto;border-top:1px solid #e7e7e7;border-bottom:1px solid #e7e7e7;background-color:#fff}#navigation.open{display:block;overflow-y:auto}}.profile-dropdown i,.profile-dropdown span,.waves-effect{vertical-align:middle}@media (min-width:768px){#topnav .navigation-menu>li.has-submenu:hover>.submenu{visibility:visible;opacity:1;margin-top:0}#topnav .navigation-menu>li.has-submenu:hover>.submenu>li.has-submenu:hover>.submenu{visibility:visible;opacity:1;margin-left:0;margin-right:0}.navbar-toggle{display:block}}.topbar-custom{border-radius:0;margin-bottom:0}.topbar-custom .nav-link{padding:0;line-height:60px;color:rgba(255,255,255,.6)}.topbar-custom .dropdown-toggle:after{content:initial}.topbar-custom .menu-left{overflow:hidden}.footer{border-top:1px solid rgba(0,0,0,.1);text-align:left!important}.footer ul li{padding-left:10px;padding-right:10px}.footer ul li a{color:#98a6ad}.footer ul li a:hover{color:#00b19d}.user-list .user-list-item{padding:10px 12px!important;border-bottom:1px solid #EEE!important}.user-list .user-list-item .avatar{float:left;margin-right:5px;width:30px;height:30px}.user-list .user-list-item .avatar img{border-radius:50%;width:100%}.user-list .user-list-item .icon{float:left;margin-right:5px;height:30px;width:30px;border-radius:50%;text-align:center}.user-list .user-list-item .icon i{color:#fff;line-height:30px;font-size:16px}.user-list .user-list-item .user-desc{margin-left:40px}.user-list .user-list-item .user-desc span.name{color:#2a3142;display:block;width:100%;overflow:hidden;font-size:13px}.user-list .user-list-item .user-desc span.desc{color:#98a6ad;display:block;width:100%;overflow:hidden;font-size:12px}.user-list .user-list-item .user-desc span.time{font-size:11px}.notification-list{margin-left:0!important}.notification-list .noti-title{border-radius:.25rem .25rem 0 0;margin:-6px 0 0;background-color:#fff;width:auto;padding:12px 20px}.notification-list .noti-title h5{margin:0}.notification-list .noti-title h5 small{color:#2a3142!important}.notification-list .noti-title .label{float:right}.notification-list .noti-icon{font-size:22px;padding:0 12px;vertical-align:middle;color:rgba(255,255,255,.8)}.notification-list .noti-icon-badge{display:inline-block;position:absolute;top:14px;right:8px}.notification-list .notify-item{padding:10px 20px}.notification-list .notify-item .notify-icon{float:left;height:36px;width:36px;line-height:36px;text-align:center;margin-right:10px;border-radius:50%;color:#fff}.notification-list .notify-item .notify-icon img{margin-top:4px}.notification-list .notify-item .notify-details{margin-bottom:0;overflow:hidden;margin-left:45px}.notification-list .notify-item .notify-details b{font-weight:500}.notification-list .notify-item .notify-details small{display:block}.notification-list .notify-item .notify-details span{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:13px}.notification-list .notify-all{border-radius:0 0 .25rem .25rem;margin:0 0 -5px;background-color:#eee}body,html{background:#f5f5f5}.notification-list .profile-dropdown .notify-item{padding:4px 20px}.profile-dropdown{width:170px}.profile-dropdown i{font-size:17px;margin-right:5px}.nav-user{padding:0 12px!important}.nav-user img{height:36px;width:36px}body{margin:0;color:#4c5667;overflow-x:hidden!important;font-size:.95rem;font-family:"Microsoft YaHei","微软雅黑",Arial,"黑体","宋体",sans-serif;padding-bottom:65px}html{overflow-x:hidden;position:relative;min-height:100%}*{outline:0!important}a:active,a:focus,a:hover{outline:0;text-decoration:none}.container-alt{margin-left:auto;margin-right:auto;padding-left:15px;padding-right:15px}.footer{background-color:#f9f9f9;bottom:0;color:#2a3142;padding:20px 30px;position:absolute;right:0;left:0}#wrapper{height:100%;overflow:hidden;width:100%}.page{bottom:0;left:0;right:0;top:0}.card-box{padding:20px;border:1px solid rgba(54,64,74,.08);-webkit-border-radius:5px;border-radius:5px;-moz-border-radius:5px;background-clip:padding-box;margin-bottom:20px;background-color:#fff}.header-title{letter-spacing:.02em;text-transform:uppercase;font-size:15px;font-weight:700;line-height:16px;margin-bottom:8px;margin-top:0}.social-links li a{-webkit-border-radius:50%;background:#EFF0F4;border-radius:50%;color:#7A7676;display:inline-block;height:30px;line-height:30px;text-align:center;width:30px}.h1,h1{font-size:36px}.h2,h2{font-size:30px}.h3,h3{font-size:24px}.h4,h4{font-size:18px}.h5,h5{font-size:14px}.h6,h6{font-size:12px}.container-fluid{max-width:95%}.row{margin-right:-10px;margin-left:-10px}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{padding-left:10px;padding-right:10px}.breadcrumb{background-color:transparent;margin-bottom:15px;margin-top:5px}.dropdown-menu{padding:4px 0;border:0;box-shadow:0 2px 5px 0 rgba(0,0,0,.26)}.dropdown-menu>li>a{padding:6px 20px}.dropdown-item.active,.dropdown-item:active{background-color:#f2f2f2;color:inherit}.dropdown-menu-lg{max-width:280px}code{color:#5d9cec;border-radius:4px}code,pre{background-color:#f4f8fb}.bg-empty{background:0 0!important}.bg-primary{background-color:#00b19d!important}.bg-success{background-color:#3bafda!important}.bg-info{background-color:#3ddcf7!important}.bg-warning{background-color:#fa0!important}.bg-danger{background-color:#ef5350!important}.bg-muted{background-color:#F5F5F5!important}.bg-inverse{background-color:#4c5667!important}.bg-purple{background-color:#7266ba!important}.bg-pink{background-color:#f76397!important}.bg-white{background-color:#fff!important}.text-white{color:#fff}.text-danger{color:#ef5350!important}.text-muted{color:#98a6ad!important}.text-primary{color:#00b19d!important}.text-warning{color:#fa0!important}.text-success{color:#3bafda!important}.text-info{color:#3ddcf7!important}.text-inverse{color:#4c5667!important}.text-pink{color:#f76397!important}.text-purple{color:#7266ba!important}.text-dark{color:#797979!important}.dropcap{font-size:3.1em}.dropcap,.dropcap-circle,.dropcap-square{display:block;float:left;font-weight:400;line-height:36px;margin-right:6px;text-shadow:none}.p-0{padding:0!important}.p-20{padding:20px}.p-t-10{padding-top:10px!important}.p-b-10{padding-bottom:10px!important}.m-0{margin:0!important}.m-r-5{margin-right:5px}.m-r-10{margin-right:10px}.m-r-15{margin-right:15px!important}.m-l-5{margin-left:5px}.m-l-10{margin-left:10px}.m-l-15{margin-left:15px}.m-t-5{margin-top:5px!important}.m-t-10{margin-top:10px!important}.m-t-15{margin-top:15px!important}.m-t-20{margin-top:20px!important}.m-t-30{margin-top:30px!important}.m-t-40{margin-top:40px!important}.m-t-50{margin-top:50px}.m-b-5{margin-bottom:5px}.m-b-10{margin-bottom:10px}.m-b-15{margin-bottom:15px}.m-b-20{margin-bottom:20px}.m-b-25{margin-bottom:25px}.m-b-30{margin-bottom:30px!important}.w-xs{min-width:80px}.w-sm{min-width:95px}.w-md{min-width:110px}.w-lg{min-width:140px}.m-h-50{min-height:50px}.l-h-34{line-height:34px!important}.font-light{font-weight:300}.font-normal{font-weight:400}.font-bold{font-weight:700}.font-13{font-size:13px}.font-14{font-size:14px}.font-15{font-size:15px}.font-16{font-size:16px}.font-18{font-size:18px}.wrapper-md{padding:20px}.pull-in{margin-left:-20px;margin-right:-20px}.b-0{border:none!important}.no-border{border:none}.center-page{float:none!important;margin:0 auto}.bx-s-0{box-shadow:none!important}.bx-shadow{-moz-box-shadow:0 1px 2px 0 rgba(0,0,0,.1);-webkit-box-shadow:0 1px 2px 0 rgba(0,0,0,.1);box-shadow:0 1px 2px 0 rgba(0,0,0,.1)}.mx-box{max-height:380px;min-height:380px}.thumb-sm{height:32px;width:32px}.thumb-md{height:48px;width:48px}.thumb-lg{height:88px;width:88px}/*! + * Waves v0.6.0 + * http://fian.my.id/Waves + * + * Copyright 2014 Alfiana E. Sibuea and other contributors + * Released under the MIT license + * https://github.com/fians/Waves/blob/master/LICENSE + */.waves-effect{position:relative;cursor:pointer;display:inline-block;overflow:hidden;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;z-index:1;will-change:opacity,transform;-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-o-transition:all .3s ease-out;-ms-transition:all .3s ease-out;transition:all .3s ease-out}.waves-effect .waves-ripple{position:absolute;border-radius:50%;width:20px;height:20px;margin-top:-10px;margin-left:-10px;opacity:0;background:rgba(0,0,0,.2);-webkit-transition:all .7s ease-out;-moz-transition:all .7s ease-out;-o-transition:all .7s ease-out;-ms-transition:all .7s ease-out;transition:all .7s ease-out;-webkit-transition-property:-webkit-transform,opacity;-moz-transition-property:-moz-transform,opacity;-o-transition-property:-o-transform,opacity;transition-property:transform,opacity;-webkit-transform:scale(0);-moz-transform:scale(0);-ms-transform:scale(0);-o-transform:scale(0);transform:scale(0);pointer-events:none}.waves-effect.waves-light .waves-ripple{background-color:rgba(255,255,255,.45)}.waves-effect.waves-red .waves-ripple{background-color:rgba(244,67,54,.7)}.waves-effect.waves-yellow .waves-ripple{background-color:rgba(255,235,59,.7)}.waves-effect.waves-orange .waves-ripple{background-color:rgba(255,152,0,.7)}.waves-effect.waves-purple .waves-ripple{background-color:rgba(156,39,176,.7)}.waves-effect.waves-green .waves-ripple{background-color:rgba(76,175,80,.7)}.waves-effect.waves-teal .waves-ripple{background-color:rgba(0,150,136,.7)}.waves-effect.waves-primary .waves-ripple{background-color:fade(#00b19d,40%)}.waves-notransition{-webkit-transition:none!important;-moz-transition:none!important;-o-transition:none!important;-ms-transition:none!important;transition:none!important}.waves-circle{-webkit-transform:translateZ(0);-moz-transform:translateZ(0);-ms-transform:translateZ(0);-o-transform:translateZ(0);transform:translateZ(0);text-align:center;width:2.5em;height:2.5em;line-height:2.5em;border-radius:50%;-webkit-mask-image:none}.waves-input-wrapper{border-radius:.2em;vertical-align:bottom}.waves-input-wrapper .waves-button-input{position:relative;top:0;left:0;z-index:1}.waves-block{display:block}@-webkit-keyframes cd-bounce-1{0%{opacity:0;-webkit-transform:scale(.5)}60%{opacity:1;-webkit-transform:scale(1.2)}100%{-webkit-transform:scale(1)}}@-moz-keyframes cd-bounce-1{0%{opacity:0;-moz-transform:scale(.5)}60%{opacity:1;-moz-transform:scale(1.2)}100%{-moz-transform:scale(1)}}@-o-keyframes cd-bounce-1{0%{opacity:0;-o-transform:scale(.5)}60%{opacity:1;-o-transform:scale(1.2)}100%{-o-transform:scale(1)}}@-webkit-keyframes cd-bounce-2{0%{opacity:0;-webkit-transform:translateX(-100px)}60%{opacity:1;-webkit-transform:translateX(20px)}100%{-webkit-transform:translateX(0)}}@-moz-keyframes cd-bounce-2{0%{opacity:0;-moz-transform:translateX(-100px)}60%{opacity:1;-moz-transform:translateX(20px)}100%{-moz-transform:translateX(0)}}@-o-keyframes cd-bounce-2{0%{opacity:0;-o-transform:translateX(-100px)}60%{opacity:1;-o-transform:translateX(20px)}100%{opacity:1;-o-transform:translateX(0)}}@-webkit-keyframes dropdownOpen{0%{opacity:0;-webkit-transform:scale(0)}100%{-webkit-transform:scale(1)}}@-moz-keyframes dropdownOpen{0%{opacity:0;-moz-transform:scale(0)}100%{-moz-transform:scale(1)}}@-o-keyframes dropdownOpen{0%{opacity:0;-o-transform:scale(0)}100%{-o-transform:scale(1)}}@-webkit-keyframes loaderAnimate{0%{-webkit-transform:rotate(0)}100%{-webkit-transform:rotate(220deg)}}@-moz-keyframes loaderAnimate{0%{-moz-transform:rotate(0)}100%{-moz-transform:rotate(220deg)}}@-o-keyframes loaderAnimate{0%{-o-transform:rotate(0)}100%{-o-transform:rotate(220deg)}}@keyframes loaderAnimate{0%{transform:rotate(0)}100%{transform:rotate(220deg)}}@-webkit-keyframes loaderAnimate2{0%{box-shadow:inset #555 0 0 0 8px;-webkit-transform:rotate(-140deg)}50%{box-shadow:inset #555 0 0 0 2px}100%{box-shadow:inset #555 0 0 0 8px;-webkit-transform:rotate(140deg)}}@-moz-keyframes loaderAnimate2{0%{box-shadow:inset #555 0 0 0 8px;-moz-transform:rotate(-140deg)}50%{box-shadow:inset #555 0 0 0 2px}100%{box-shadow:inset #555 0 0 0 8px;-moz-transform:rotate(140deg)}}@-o-keyframes loaderAnimate2{0%{box-shadow:inset #555 0 0 0 8px;-o-transform:rotate(-140deg)}50%{box-shadow:inset #555 0 0 0 2px}100%{box-shadow:inset #555 0 0 0 8px;-o-transform:rotate(140deg)}}@keyframes loaderAnimate2{100%{-webkit-transform:rotate(140deg);-moz-transform:rotate(140deg);-ms-transform:rotate(140deg)}0%{-webkit-transform:rotate(-140deg);-moz-transform:rotate(-140deg);-ms-transform:rotate(-140deg);box-shadow:inset #999 0 0 0 17px;transform:rotate(-140deg)}50%{box-shadow:inset #999 0 0 0 2px}100%{box-shadow:inset #999 0 0 0 17px;transform:rotate(140deg)}}.badge{font-weight:600;padding:3px 5px;font-size:12px;margin-top:1px}.badge-xs{font-size:9px}.badge-sm,.badge-xs{-webkit-transform:translate(0,-2px);-ms-transform:translate(0,-2px);-o-transform:translate(0,-2px);transform:translate(0,-2px)}.badge-primary{background-color:#00b19d}.badge-success{background-color:#3bafda}.badge-info{background-color:#3ddcf7}.badge-warning{background-color:#fa0;color:#fff}.badge-danger{background-color:#ef5350}.badge-purple{background-color:#7266ba;color:#fff}.badge-pink{background-color:#f76397;color:#fff}.badge-inverse{background-color:#4c5667;color:#fff}.pagination>li:first-child>a,.pagination>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pagination>li>a,.pagination>li>span{color:#636e7b}.pagination>li>a:focus,.pagination>li>a:hover,.pagination>li>span:focus,.pagination>li>span:hover{background-color:#e4e7ea}.pagination-split li{margin-left:5px;display:inline-block;float:left}.pagination-split li:first-child{margin-left:0}.pagination-split li a{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.page-item.active .page-link,.pagination>.active>a,.pagination>.active>a:focus,.pagination>.active>a:hover,.pagination>.active>span,.pagination>.active>span:focus,.pagination>.active>span:hover{background-color:#00b19d;border-color:#00b19d}.pager .disabled>a,.pager .disabled>a:focus,.pager .disabled>a:hover,.pager .disabled>span{opacity:.6}.pager li>a,.pager li>span{-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;color:#4c5667}.icon-list-demo div{cursor:pointer;line-height:50px;overflow:hidden;color:#75798B;font-size:14px}.icon-list-demo div p{margin-bottom:0;line-height:inherit}.icon-list-demo i{-webkit-transition:all .2s;display:inline-block;font-size:20px;margin:0;text-align:center;transition:all .2s;vertical-align:middle;width:40px}.loader-1,.loader-1:after{clip:rect(0,30px,30px,15px);height:30px;width:30px}.icon-list-demo .col-md-4:hover{color:#00b19d}.icon-list-demo .col-md-4:hover i{-o-transform:scale(1.5);-webkit-transform:scale(1.5);-moz-transform:scale(1.5);transform:scale(1.5)}.ionicon-list i{font-size:16px}.ionicon-list .col-md-3:hover i{-o-transform:scale(2);-webkit-transform:scale(2);-moz-transform:scale(2);transform:scale(2)}.button-list{margin-left:-8px;margin-bottom:-12px}.button-list .btn{margin-bottom:12px;margin-left:8px}@media print{#topnav,.breadcrumb,.btn-group.pull-right.m-t-15,.footer,.logo,.page-title,.topbar{display:none;margin:0;padding:0}.left,.right-bar{display:none}.card-box,.content,.wrapper{margin:0!important;padding:0!important;border:none!important}.content-page{margin-left:0;margin-top:0!important}}.btn-danger,.btn-dark,.btn-info,.btn-primary,.btn-success,.btn-warning{color:#fff}.btn-primary{background-color:#00b19d;border:1px solid #00b19d}.btn-primary.active,.btn-primary.focus,.btn-primary:active,.btn-primary:focus,.btn-primary:hover,.btn-primary:not([disabled]):not(.disabled).active,.btn-primary:not([disabled]):not(.disabled):active,.open>.dropdown-toggle.btn-primary,.show>.btn-primary.dropdown-toggle{background-color:#009886;border-color:#009886}.btn-outline-primary.focus,.btn-outline-primary:focus,.btn-primary.focus,.btn-primary:focus,.btn-primary:not([disabled]):not(.disabled).active,.btn-primary:not([disabled]):not(.disabled).active:focus,.btn-primary:not([disabled]):not(.disabled):active,.btn-primary:not([disabled]):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 2px rgba(0,177,157,.5)}.btn-light{border-color:#eee}.btn-light.active,.btn-light.focus,.btn-light:active,.btn-light:focus,.btn-light:hover,.open>.dropdown-toggle.btn-light{border-color:#bfbfbf}.btn-light.focus,.btn-light:focus,.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 2px #d9d9d9}.btn-success{background-color:#3bafda;border:1px solid #3bafda}.btn-success.active,.btn-success.focus,.btn-success:active,.btn-success:focus,.btn-success:hover,.btn-success:not([disabled]):not(.disabled).active,.btn-success:not([disabled]):not(.disabled):active,.open>.dropdown-toggle.btn-success,.show>.btn-success.dropdown-toggle{background-color:#28a5d4;border-color:#28a5d4}.btn-outline-success.focus,.btn-outline-success:focus,.btn-success.focus,.btn-success:focus,.btn-success:not([disabled]):not(.disabled).active,.btn-success:not([disabled]):not(.disabled).active:focus,.btn-success:not([disabled]):not(.disabled):active,.btn-success:not([disabled]):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 2px rgba(59,175,218,.5)}.btn-info{background-color:#3ddcf7;border:1px solid #3ddcf7}.btn-info.active,.btn-info.focus,.btn-info:active,.btn-info:focus,.btn-info:hover,.btn-info:not([disabled]):not(.disabled).active,.btn-info:not([disabled]):not(.disabled):active,.open>.dropdown-toggle.btn-info,.show>.btn-info.dropdown-toggle{background-color:#25d8f6;border-color:#25d8f6}.btn-info.focus,.btn-info:focus,.btn-info:not([disabled]):not(.disabled).active,.btn-info:not([disabled]):not(.disabled).active:focus,.btn-info:not([disabled]):not(.disabled):active,.btn-info:not([disabled]):not(.disabled):active:focus,.btn-outline-info.focus,.btn-outline-info:focus,.show>.btn-info.dropdown-toggle,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 2px rgba(61,220,247,.5)}.btn-warning{background-color:#fa0;border:1px solid #fa0;color:#fff}.btn-warning.active,.btn-warning.focus,.btn-warning:active,.btn-warning:focus,.btn-warning:hover,.btn-warning:not([disabled]):not(.disabled).active,.btn-warning:not([disabled]):not(.disabled):active,.open>.dropdown-toggle.btn-warning,.show>.btn-warning.dropdown-toggle{background-color:#e69900;border-color:#e69900;color:#fff}.btn-outline-warning.focus,.btn-outline-warning:focus,.btn-warning.focus,.btn-warning:focus,.btn-warning:not([disabled]):not(.disabled).active,.btn-warning:not([disabled]):not(.disabled).active:focus,.btn-warning:not([disabled]):not(.disabled):active,.btn-warning:not([disabled]):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 2px rgba(255,170,0,.5)}.btn-danger{background-color:#ef5350;border:1px solid #ef5350}.btn-danger.active,.btn-danger.focus,.btn-danger:active,.btn-danger:focus,.btn-danger:hover,.btn-danger:not([disabled]):not(.disabled).active,.btn-danger:not([disabled]):not(.disabled):active,.open>.dropdown-toggle.btn-danger,.show>.btn-danger.dropdown-toggle{background-color:#ed3c39;border-color:#ed3c39}.btn-danger.focus,.btn-danger:focus,.btn-danger:not([disabled]):not(.disabled).active,.btn-danger:not([disabled]):not(.disabled).active:focus,.btn-danger:not([disabled]):not(.disabled):active,.btn-danger:not([disabled]):not(.disabled):active:focus,.btn-outline-danger.focus,.btn-outline-danger:focus,.show>.btn-danger.dropdown-toggle,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 2px rgba(239,83,80,.5)}.btn-dark{background-color:#2a3142;border:1px solid #2a3142}.btn-dark.active,.btn-dark.focus,.btn-dark:active,.btn-dark:focus,.btn-dark:hover,.open>.dropdown-toggle.btn-dark{background-color:#202532;border-color:#202532}.btn-dark.focus,.btn-dark:focus,.btn-dark:not([disabled]):not(.disabled).active,.btn-dark:not([disabled]):not(.disabled):active,.btn-outline-dark.focus,.btn-outline-dark:focus,.show>.btn-dark.dropdown-toggle{box-shadow:0 0 0 2px rgba(42,49,66,.5)}.btn-link{color:#2a3142}.btn-link:hover{color:#00b19d}.btn-outline-primary{color:#00b19d;border-color:#00b19d}.btn-outline-primary:hover{background-color:#00b19d;border-color:#00b19d}.btn-outline-success{color:#3bafda;border-color:#3bafda}.btn-outline-success:hover{background-color:#3bafda;border-color:#3bafda}.btn-outline-info{color:#3ddcf7;border-color:#3ddcf7}.btn-outline-info:hover{background-color:#3ddcf7;border-color:#3ddcf7}.btn-outline-warning{color:#fa0;border-color:#fa0}.btn-outline-warning:hover{background-color:#fa0;border-color:#fa0;color:#fff}.btn-outline-danger{color:#ef5350;border-color:#ef5350}.btn-outline-danger:hover{background-color:#ef5350;border-color:#ef5350}.btn-outline-dark{color:#2a3142;border-color:#2a3142}.btn-outline-dark:hover{background-color:#2a3142;border-color:#2a3142}.btn-custom{border-bottom:3px solid transparent}.btn-custom.btn-default{background-color:#f3f3f3;border-bottom:2px solid #ccc!important}.btn-custom.btn-primary{border-bottom:2px solid #007e70!important}.btn-custom.btn-success{border-bottom:2px solid #2494be!important}.btn-custom.btn-info{border-bottom:2px solid #08aac6!important}.btn-custom.btn-warning{border-bottom:2px solid #c80!important}.btn-custom.btn-danger{border-bottom:2px solid #c71612!important}.btn-custom.btn-dark{border-bottom:2px solid #0b0c0f!important}.btn-rounded{border-radius:2em;padding:6px 18px}.fileupload{overflow:hidden;position:relative}.fileupload input.upload{cursor:pointer;filter:alpha(opacity=0);font-size:20px;margin:0;opacity:0;padding:0;position:absolute;right:0;top:0}.portlet{-moz-box-shadow:0 1px 2px 0 rgba(0,0,0,.1);-moz-transition:all .4s;-o-transition:all .4s;-webkit-box-shadow:0 1px 2px 0 rgba(0,0,0,.1);-webkit-transition:all .4s;background:#fff;box-shadow:0 1px 2px 0 rgba(0,0,0,.1);margin-bottom:20px;transition:all .4s}.portlet .portlet-heading{border-radius:3px;color:#fff;padding:12px 20px}.portlet .portlet-heading .portlet-title{color:#fff;float:left;font-size:16px;font-weight:600;margin-bottom:0;margin-top:6px;letter-spacing:.03em}.checkbox label,.radio label{font-weight:500;display:inline-block}.portlet .portlet-heading .portlet-widgets{display:inline-block;float:right;font-size:15px;line-height:30px;padding-left:15px;position:relative;text-align:right}.portlet .portlet-heading .portlet-widgets .divider{margin:0 5px}.portlet .portlet-heading a{color:#999}.portlet .portlet-body{-moz-border-radius-bottomleft:5px;-moz-border-radius-bottomright:5px;-webkit-border-bottom-left-radius:5px;-webkit-border-bottom-right-radius:5px;background:#fff;border-bottom-left-radius:5px;border-bottom-right-radius:5px;padding:15px}.portlet-default .portlet-title{color:#797979!important}.portlet .portlet-heading .portlet-widgets .collapsed .ion-minus-round:before{content:"\f217"!important}.portlet .portlet-heading.bg-danger a,.portlet .portlet-heading.bg-info a,.portlet .portlet-heading.bg-inverse a,.portlet .portlet-heading.bg-pink a,.portlet .portlet-heading.bg-primary a,.portlet .portlet-heading.bg-purple a,.portlet .portlet-heading.bg-success a,.portlet .portlet-heading.bg-warning a{color:#fff}.panel-disabled{background:rgba(243,242,241,.5);cursor:progress;bottom:15px;left:0;position:absolute;right:-5px;top:0}.loader-1{-moz-animation:loaderAnimate 1s linear infinite;-o-animation:loaderAnimate 1s linear infinite;-webkit-animation:loaderAnimate 1s linear infinite;animation:loaderAnimate 1s linear infinite;left:50%;margin-left:-15px;margin-top:-15px;position:absolute;top:50%}.checkbox.checkbox-inline,.radio.radio-inline{margin-top:0}.loader-1:after{-moz-animation:loaderAnimate2 1s ease-in-out infinite;-o-animation:loaderAnimate2 1s ease-in-out infinite;-webkit-animation:loaderAnimate2 1s ease-in-out infinite;animation:loaderAnimate2 1s ease-in-out infinite;border-radius:50%;content:'';position:absolute}.custom-checkbox .custom-control-input:checked~.custom-control-label::before,.custom-control-input:checked~.custom-control-label::before,.custom-radio .custom-control-input:checked~.custom-control-label::before{background-color:#00b19d}.checkbox label{padding-left:5px;position:relative;font-size:13px}.checkbox label::before{-o-transition:.3s ease-in-out;-webkit-transition:.3s ease-in-out;background-color:#fff;border-radius:3px;border:1px solid #98a6ad;content:"";display:inline-block;height:17px;left:0;margin-left:-17px;position:absolute;transition:.3s ease-in-out;width:17px;outline:0!important}.checkbox label::after{color:#333;display:inline-block;font-size:11px;height:16px;left:0;margin-left:-17px;padding-left:3px;padding-top:1px;position:absolute;top:0;width:16px}.checkbox-custom input[type=checkbox]:checked+label::after,.checkbox-danger input[type=checkbox]:checked+label::after,.checkbox-info input[type=checkbox]:checked+label::after,.checkbox-inverse input[type=checkbox]:checked+label::after,.checkbox-pink input[type=checkbox]:checked+label::after,.checkbox-primary input[type=checkbox]:checked+label::after,.checkbox-purple input[type=checkbox]:checked+label::after,.checkbox-success input[type=checkbox]:checked+label::after,.checkbox-warning input[type=checkbox]:checked+label::after{color:#fff}.checkbox input[type=checkbox]{cursor:pointer;opacity:0;z-index:1;outline:0!important}.checkbox input[type=checkbox]:disabled+label{opacity:.65}.checkbox input[type=checkbox]:focus+label::before{outline-offset:-2px;outline:0}.checkbox input[type=checkbox]:checked+label::after{content:"\f00c";font-family:FontAwesome}.checkbox input[type=checkbox]:disabled+label::before{background-color:#eee;cursor:not-allowed}.checkbox-custom input[type=checkbox]:checked+label::before,.checkbox-primary input[type=checkbox]:checked+label::before{background-color:#00b19d;border-color:#00b19d}.checkbox.checkbox-circle label::before{border-radius:50%}.checkbox.checkbox-single input{height:18px;width:18px;position:absolute}.checkbox.checkbox-single label{height:18px;width:18px}.checkbox.checkbox-single label:after,.checkbox.checkbox-single label:before{margin-left:0}.checkbox-danger input[type=checkbox]:checked+label::before{background-color:#ef5350;border-color:#ef5350}.checkbox-info input[type=checkbox]:checked+label::before{background-color:#3ddcf7;border-color:#3ddcf7}.checkbox-warning input[type=checkbox]:checked+label::before{background-color:#fa0;border-color:#fa0}.checkbox-success input[type=checkbox]:checked+label::before{background-color:#3bafda;border-color:#3bafda}.checkbox-purple input[type=checkbox]:checked+label::before{background-color:#7266ba;border-color:#7266ba}.checkbox-pink input[type=checkbox]:checked+label::before{background-color:#f76397;border-color:#f76397}.checkbox-inverse input[type=checkbox]:checked+label::before{background-color:#4c5667;border-color:#4c5667}.radio label{padding-left:5px;position:relative;font-size:13px}.radio label::before{-o-transition:border .5s ease-in-out;-webkit-transition:border .5s ease-in-out;background-color:#fff;border-radius:50%;border:1px solid #98a6ad;content:"";display:inline-block;height:17px;left:0;margin-left:-20px;position:absolute;transition:border .5s ease-in-out;width:17px;outline:0!important}.radio-custom input[type=radio]:checked+label::before,.radio-primary input[type=radio]:checked+label::before{border-color:#00b19d}.radio label::after{-moz-transition:-moz-transform .1s cubic-bezier(.8,-.33,.2,1.33);-ms-transform:scale(0,0);-o-transform:scale(0,0);-o-transition:-o-transform .1s cubic-bezier(.8,-.33,.2,1.33);-webkit-transform:scale(0,0);-webkit-transition:-webkit-transform .1s cubic-bezier(.8,-.33,.2,1.33);background-color:#333;border-radius:50%;content:" ";display:inline-block;height:11px;left:3px;margin-left:-20px;position:absolute;top:3px;transform:scale(0,0);transition:transform .1s cubic-bezier(.8,-.33,.2,1.33);width:11px}.radio-custom input[type=radio]+label::after,.radio-custom input[type=radio]:checked+label::after,.radio-primary input[type=radio]+label::after,.radio-primary input[type=radio]:checked+label::after{background-color:#00b19d}.radio input[type=radio]{cursor:pointer;opacity:0;z-index:1;outline:0!important}.radio input[type=radio]:disabled+label{opacity:.65}.radio input[type=radio]:focus+label::before{outline-offset:-2px;outline:dotted thin}.radio input[type=radio]:checked+label::after{-ms-transform:scale(1,1);-o-transform:scale(1,1);-webkit-transform:scale(1,1);transform:scale(1,1)}.radio input[type=radio]:disabled+label::before{cursor:not-allowed}.radio.radio-single label{height:17px}.radio-danger input[type=radio]+label::after,.radio-danger input[type=radio]:checked+label::after{background-color:#ef5350}.radio-danger input[type=radio]:checked+label::before{border-color:#ef5350}.radio-info input[type=radio]+label::after,.radio-info input[type=radio]:checked+label::after{background-color:#3ddcf7}.radio-info input[type=radio]:checked+label::before{border-color:#3ddcf7}.radio-warning input[type=radio]+label::after,.radio-warning input[type=radio]:checked+label::after{background-color:#fa0}.radio-warning input[type=radio]:checked+label::before{border-color:#fa0}.radio-success input[type=radio]+label::after,.radio-success input[type=radio]:checked+label::after{background-color:#3bafda}.radio-success input[type=radio]:checked+label::before{border-color:#3bafda}.radio-purple input[type=radio]+label::after,.radio-purple input[type=radio]:checked+label::after{background-color:#7266ba}.radio-purple input[type=radio]:checked+label::before{border-color:#7266ba}.radio-pink input[type=radio]+label::after,.radio-pink input[type=radio]:checked+label::after{background-color:#f76397}.radio-pink input[type=radio]:checked+label::before{border-color:#f76397}.tab-content{padding:20px 0 0}.nav-pills>li>a,.nav-tabs>li>a{color:#2a3142;font-weight:600}.nav-pills .nav-item.show .nav-link,.nav-pills .nav-link.active{background-color:#00b19d}.tabs-vertical-env .tab-content{background:#fff;display:table-cell;padding:0 0 0 20px;margin-bottom:0;vertical-align:top}.tabs-vertical-env .nav.tabs-vertical{display:table-cell;min-width:120px;vertical-align:top;width:150px}.tabs-vertical-env .nav.tabs-vertical li>a{color:#2a3142;white-space:nowrap;font-weight:600;border-radius:2px}.tabs-vertical-env .nav.tabs-vertical li>a.active{background-color:#00b19d;border:0;color:#fff}.tabs-vertical-env-right .tab-content{padding:0 20px 0 0}.tabs-bordered{border-bottom:2px solid rgba(152,166,173,.2)!important}.tabs-bordered .nav-item{margin-bottom:-2px}.tabs-bordered li a,.tabs-bordered li a:focus,.tabs-bordered li a:hover{border:0!important;padding:10px 20px!important}.tabs-bordered li a.active{border-bottom:2px solid #00b19d!important}.nav-pills>li>a{color:#2a3142}.nav-pills>li.active>a,.nav-pills>li.active>a:focus,.nav-pills>li.active>a:hover{background-color:#00b19d}.modal .modal-dialog .close{top:0;position:absolute;right:0;height:36px;width:36px;background-color:#2a3142;opacity:1;border:2px solid #fff;text-shadow:none;color:#fff;border-radius:50%;padding:0;font-size:18px}.modal .modal-dialog .modal-title{margin:0}.modal .modal-dialog .modal-content{-moz-box-shadow:none;-webkit-box-shadow:none;border-color:#DDD;border-radius:2px;box-shadow:none}.modal .modal-dialog .modal-content .modal-header{border-bottom-width:2px;margin:0}.modal .modal-dialog .modal-content .modal-body{padding:20px}.modal-full{width:98%;max-width:100%}.modal-demo{background-color:#fff;width:600px;border-radius:4px;display:none}.modal-demo .close{position:absolute;top:12px;right:25px;color:#fff;opacity:.5;font-weight:400;font-size:26px}.modal-demo .close:hover{opacity:1}.custom-modal-title{padding:15px 25px;line-height:22px;font-size:18px;background-color:#00b19d;color:#fff;text-align:left;margin:0}.custom-modal-text{padding:20px}.custombox-modal-flash .close,.custombox-modal-rotatedown .close{top:20px;z-index:9999}.progress{-webkit-box-shadow:none!important;background-color:#f3f3f3;box-shadow:none!important;height:10px;margin-bottom:18px;overflow:hidden}.progress-bar{box-shadow:none;font-size:8px;font-weight:600;background-color:#00b19d;line-height:12px}.progress.progress-sm{height:5px!important}.progress.progress-sm .progress-bar{font-size:8px;line-height:5px}.progress.progress-md{height:15px!important}.progress.progress-md .progress-bar{font-size:10.8px;line-height:14.4px}.tooltip-inner{border-radius:1px;padding:6px 10px}.jqstooltip{width:auto!important;height:auto!important}.popover{font-family:inherit}.popover .popover-title{background-color:transparent;color:#00b19d;margin:0;font-weight:600}.alert-success{background-color:#e4fffc!important;border-color:#00e4ca!important;color:#00b19d}.alert-success .alert-link{color:#00b19d}.alert-info,.alert-info .alert-link{color:#3ddcf7}.alert-info{background-color:#d0f7fd!important;border-color:#6ee5f9!important}.alert-warning{background-color:#fff7e6!important;border-color:#fb3!important;color:#fa0}.alert-warning .alert-link{color:#fa0}.alert-danger,.alert-danger .alert-link{color:#ef5350}.alert-danger{background-color:#fef4f4!important;border-color:#f3817f!important}.carousel-control{width:10%}.carousel-control span{position:absolute;top:50%;z-index:5;display:inline-block;font-size:30px}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.inbox-widget .inbox-item{border-bottom:1px solid #fafafa;overflow:hidden;padding:10px 0;position:relative}.inbox-widget .inbox-item .inbox-item-img{display:block;float:left;margin-right:15px;width:40px}.inbox-widget .inbox-item img{width:40px}.inbox-widget .inbox-item .inbox-item-author{color:#2a3142;display:block;margin:0}.inbox-widget .inbox-item .inbox-item-text{color:#98a6ad;display:block;font-size:12px;margin:0}.inbox-widget .inbox-item .inbox-item-date{color:#98a6ad;font-size:11px;position:absolute;right:7px;top:2px}.conversation-list{list-style:none;max-height:330px;padding:0 20px}.conversation-list li{margin-bottom:24px}.conversation-list .chat-avatar{display:inline-block;float:left;text-align:center;width:40px}.conversation-list .chat-avatar img{border-radius:100%;width:100%}.conversation-list .chat-avatar i{font-size:12px;font-style:normal}.conversation-list .ctext-wrap{-moz-border-radius:3px;-webkit-border-radius:3px;background:#f5f5f5;border-radius:3px;display:inline-block;padding:10px;position:relative}.conversation-list .ctext-wrap i{color:#2a3142;display:block;font-size:12px;font-style:normal;font-weight:700;position:relative}.conversation-list .ctext-wrap p{margin:0;padding-top:3px}.conversation-list .ctext-wrap:after{right:100%;top:20%;border:5px solid rgba(213,242,239,0);content:" ";height:0;width:0;position:absolute;pointer-events:none;border-right-color:#f5f5f5;margin-top:-5px}.conversation-list .conversation-text{display:inline-block;float:left;font-size:12px;margin-left:12px;width:70%}.conversation-list .odd .chat-avatar{float:right!important}.conversation-list .odd .conversation-text{float:right!important;margin-right:12px;text-align:right;width:70%!important}.conversation-list .odd p{color:#f2f2f2}.conversation-list .odd .ctext-wrap{background:#00b19d!important}.conversation-list .odd .ctext-wrap i{color:#fff}.conversation-list .odd .ctext-wrap:after{border-color:rgba(238,238,242,0)!important;border-left-color:#00b19d!important;left:100%!important;top:20%!important}.chat-send{padding-left:0;padding-right:30px}.chat-send button{width:100%}.chat-inputbar{padding-left:30px}#todo-message{font-size:16px}.todo-list li{border:0;margin:0;padding:5px!important;background:0 0!important;display:block}.todo-send{padding-left:0}.widget-chart ul li{width:31.5%;display:inline-block;padding:0}.widget-panel{padding:30px 20px 30px 30px;border-radius:4px;position:relative;margin-bottom:20px}.widget-panel i{font-size:60px;padding:30px;background:rgba(255,255,255,.2);position:absolute;right:0;bottom:0;top:0;line-height:60px}.widget-user{min-height:112px}.widget-user img{height:72px;float:left}.widget-user .wid-u-info{margin-left:90px}.widget-user .wid-u-info p{display:block;overflow:hidden}.widget-simple-chart .circliful-chart{float:left;margin-top:-5px}.widget-icon i{float:left;font-size:48px}.widget-icon .wid-icon-info{margin-left:80px}.widget-bg-color-icon .bg-icon{height:80px;width:80px;text-align:center;border-radius:50%}.widget-bg-color-icon .bg-icon i{font-size:32px;color:#fff!important;line-height:68px}.widget-bg-color-icon .bg-icon-info{background-color:rgba(61,220,247,.75);border:6px solid rgba(61,220,247,.3)}.widget-bg-color-icon .bg-icon-primary{background-color:rgba(0,177,157,.75);border:6px solid rgba(0,177,157,.3)}.widget-bg-color-icon .bg-icon-pink{background-color:rgba(247,99,151,.75);border:6px solid rgba(247,99,151,.3)}.widget-bg-color-icon .bg-icon-purple{background-color:rgba(114,102,186,.75);border:6px solid rgba(114,102,186,.3)}.widget-bg-color-icon .bg-icon-success{background-color:rgba(59,175,218,.75);border:6px solid rgba(59,175,218,.3)}.widget-bg-color-icon .bg-icon-warning{background-color:rgba(255,170,0,.75);border:6px solid rgba(255,170,0,.3)}.widget-bg-color-icon .bg-icon-danger{background-color:rgba(239,83,80,.75);border:6px solid rgba(239,83,80,.3)}.widget-bg-color-icon .bg-icon-inverse{background-color:rgba(76,86,103,.75);border:6px solid rgba(76,86,103,.3)}label{font-weight:500}.form-control{border:1px solid #cfcfcf;box-shadow:none;color:rgba(0,0,0,.6)}.form-control:focus{background:#fff;border-color:#a2a2a2;box-shadow:none}.input-sm{height:30px}.input-group-btn .btn{padding:7px 14px}.has-success .form-control{border-color:#3bafda;box-shadow:none!important}.has-warning .form-control{border-color:#fa0;box-shadow:none!important}.has-error .form-control{border-color:#ef5350;box-shadow:none!important}.input-group-addon{border-radius:2px}.bootstrap-tagsinput{box-shadow:none;padding:3px 7px;border:1px solid #f3f3f3}.bootstrap-tagsinput .label-info{background-color:#00b19d!important;display:inline-block;padding:2px 10px;border-radius:3px;font-size:14px;margin:2px}.ms-container{background:url(../images/multiple-arrow.png) 50% 50% no-repeat}.ms-container .ms-list{box-shadow:none;border:1px solid #f3f3f3}.ms-container .ms-list.ms-focus{border:1px solid #aaa;box-shadow:none}.ms-container .ms-selectable li.ms-elem-selectable,.ms-container .ms-selection li.ms-elem-selection{border:none;padding:5px 10px}.search-input{margin-bottom:10px}.ms-selectable{box-shadow:none;outline:0!important}.ms-container .ms-selectable li.ms-hover,.ms-container .ms-selection li.ms-hover{background-color:#00b19d}.select2-container{width:100%!important}.select2-container .select2-selection--single{border:1px solid #ebebeb;height:38px}.select2-container .select2-selection--single .select2-selection__rendered{line-height:36px;padding-left:12px}.select2-container .select2-selection--single .select2-selection__arrow{height:34px;width:34px;right:3px}.select2-container .select2-selection--single .select2-selection__arrow b{border-color:#c8c8c8 transparent transparent;border-width:6px 6px 0}.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #c8c8c8!important;border-width:0 6px 6px!important}.select2-container--default .select2-search--dropdown .select2-search__field,.select2-dropdown{border:1px solid #e1e1e1}.select2-results__option{padding:6px 12px}.select2-container--default .select2-search--dropdown{padding:10px;background-color:#fbfbfb}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#00b19d}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#eee;color:#2a3142}.select2-container--default .select2-results__option[aria-selected=true]:hover{background-color:#00b19d;color:#fff}.select2-container .select2-selection--multiple{min-height:38px;border:1px solid #e1e1e1!important}.select2-container .select2-selection--multiple .select2-selection__rendered{padding:2px 10px}.select2-container .select2-selection--multiple .select2-search__field{margin-top:7px;border:0}.select2-container .select2-selection--multiple .select2-selection__choice{background-color:#00b19d;border:1px solid transparent;color:#fff;border-radius:3px;padding:0 7px}.select2-container .select2-selection--multiple .select2-selection__choice__remove{color:#fff;margin-right:5px}.select2-container .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.datepicker{padding:8px}.datepicker th{font-size:14px!important}.datepicker table tr td span.active,.datepicker table tr td span.active.disabled,.datepicker table tr td span.active.disabled:hover,.datepicker table tr td span.active:hover,.datepicker table tr td.selected,.datepicker table tr td.selected.disabled,.datepicker table tr td.selected.disabled:hover,.datepicker table tr td.selected:hover,.datepicker table tr td.today,.datepicker table tr td.today.disabled,.datepicker table tr td.today.disabled:hover,.datepicker table tr td.today:hover{background-image:none}.datepicker table tr td span.active.active,.datepicker table tr td span.active.disabled,.datepicker table tr td span.active.disabled.active,.datepicker table tr td span.active.disabled.disabled,.datepicker table tr td span.active.disabled:active,.datepicker table tr td span.active.disabled:hover,.datepicker table tr td span.active.disabled:hover.active,.datepicker table tr td span.active.disabled:hover.disabled,.datepicker table tr td span.active.disabled:hover:active,.datepicker table tr td span.active.disabled:hover:hover,.datepicker table tr td span.active.disabled:hover[disabled],.datepicker table tr td span.active.disabled[disabled],.datepicker table tr td span.active:active,.datepicker table tr td span.active:hover,.datepicker table tr td span.active:hover.active,.datepicker table tr td span.active:hover.disabled,.datepicker table tr td span.active:hover:active,.datepicker table tr td span.active:hover:hover,.datepicker table tr td span.active:hover[disabled],.datepicker table tr td span.active[disabled]{background-color:#00b19d}.datepicker tfoot tr th:hover,.datepicker thead tr:first-child th:hover{background-color:#fafafa}.datepicker-inline{border:2px solid #eee}.datepicker table tr td.active,.datepicker table tr td.active.disabled,.datepicker table tr td.active.disabled:hover,.datepicker table tr td.active:hover{text-shadow:none;background-color:#00b19d!important;background-image:none;box-shadow:none}.daterangepicker td.active,.daterangepicker td.active:hover{background-color:#00b19d;border-color:#00b19d}.daterangepicker .input-mini.active{border:1px solid #AAA}.daterangepicker .ranges li{border-radius:2px;color:#797979;font-weight:600;font-size:12px}.daterangepicker select.ampmselect,.daterangepicker select.hourselect,.daterangepicker select.minuteselect,.daterangepicker select.secondselect{border:1px solid #e3e3e3;padding:2px;width:60px}.daterangepicker .ranges li.active,.daterangepicker .ranges li:hover{background-color:#00b19d;border:1px solid #00b19d}.bootstrap-touchspin .input-group-addon{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.25;color:#2a3142;text-align:center;background-color:#eee;border:1px solid rgba(42,49,66,.15)}.bootstrap-touchspin .input-group-btn:not(:first-child)>.btn,.bootstrap-touchspin .input-group-btn:not(:first-child)>.btn-group{z-index:2;margin-left:-1px}.bootstrap-touchspin .input-group .form-control:not(:first-child),.bootstrap-touchspin .input-group-addon:not(:first-child),.bootstrap-touchspin .input-group-btn:not(:first-child)>.btn,.bootstrap-touchspin .input-group-btn:not(:first-child)>.btn-group>.btn,.bootstrap-touchspin .input-group-btn:not(:first-child)>.dropdown-toggle,.bootstrap-touchspin .input-group-btn:not(:last-child)>.btn-group:not(:first-child)>.btn,.bootstrap-touchspin .input-group-btn:not(:last-child)>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.bootstrap-touchspin .input-group .form-control:not(:last-child),.bootstrap-touchspin .input-group-addon:not(:last-child),.bootstrap-touchspin .input-group-btn:not(:first-child)>.btn-group:not(:last-child)>.btn,.bootstrap-touchspin .input-group-btn:not(:first-child)>.btn:not(:last-child):not(.dropdown-toggle),.bootstrap-touchspin .input-group-btn:not(:last-child)>.btn,.bootstrap-touchspin .input-group-btn:not(:last-child)>.btn-group>.btn,.bootstrap-touchspin .input-group-btn:not(:last-child)>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.wizard>.content{background:#fff;min-height:240px;padding:20px}.wizard>.content>.body{padding:0;position:relative}.wizard>.content>.body input{border:1px solid #f3f3f3}.wizard>.content>.body ul>li{display:block;line-height:30px}.wizard>.content>.body label.error{color:#ef5350;margin-left:0}.wizard>.content>.body label{display:inline-block;margin-top:10px}.wizard>.steps .number{border-radius:50%;background-color:rgba(255,255,255,.3);display:inline-block;line-height:30px;margin-right:10px;width:30px;text-align:center}.wizard>.steps .disabled a{background:#fff;color:#333;cursor:default;border:1px solid #eaeaea}.wizard>.steps .disabled a:active,.wizard>.steps .disabled a:hover{background:#f9f9f9;color:#333;cursor:default;border:1px solid #eaeaea}.wizard>.steps .current a,.wizard>.steps .current a:active,.wizard>.steps .current a:hover{background:#00b19d}.wizard>.steps .current a .number,.wizard>.steps .current a:active .number,.wizard>.steps .current a:hover .number{color:#fff}.wizard>.steps .done a,.wizard>.steps .done a:active,.wizard>.steps .done a:hover{background:#ddd}.wizard>.content,.wizard>.steps a,.wizard>.steps a:active,.wizard>.steps a:hover{border-radius:2px}.wizard>.actions a,.wizard>.actions a:active,.wizard>.actions a:hover{background:#00b19d;border-radius:2px;color:#fff}.wizard>.actions .disabled a{background:#fff;color:#333;cursor:default;border:1px solid #eaeaea}.wizard>.actions .disabled a:active,.wizard>.actions .disabled a:hover{background:#f9f9f9;color:#333;cursor:default;border:1px solid #eaeaea}@media (max-width:767px){.wizard.vertical>.content,.wizard.vertical>.steps{display:inline;float:none;width:100%}.wizard>.steps>ul>li{width:100%}.wizard>.content{padding:0!important}.wizard>.content>.body{float:none;position:relative;width:100%;height:100%;padding:0}.wizard.vertical>.content{margin:0}}.error{color:#ef5350;font-size:12px;font-weight:500}.parsley-error{border-color:#ef5350!important}.parsley-errors-list{display:none;margin:0;padding:0}.parsley-errors-list.filled{display:block}.parsley-errors-list>li{font-size:12px;list-style:none;color:#ef5350}.dropzone{min-height:230px;border:2px dashed rgba(0,0,0,.3);background:#fff;border-radius:6px}.dropzone .dz-message{font-size:30px}.mce-content-body p{color:#9398a0;font-size:14px;font-weight:300}.mce-popover .mce-arrow:after{border-bottom-color:red}.mce-popover .mce-colorbutton-grid{margin:0;border:1px solid #d7dce5!important;padding:4px}.mce-reset .mce-window-head{border-bottom:1px solid #d7dce5}.mce-reset .mce-window-head .mce-title{color:#707780;font-size:16px;font-weight:400}.mce-reset .mce-textbox{border-radius:0;box-shadow:none;outline:0;border-color:#d7dce5;height:30px;font-weight:300;line-height:30px;color:#aaa;font-size:14px}.mce-reset .mce-textbox:focus{box-shadow:none;border-color:#00b19d}.mce-reset .mce-checkbox .mce-ico{background-image:none;background-color:#fff;border-radius:0;border:1px solid #d7dce5}.mce-reset .mce-checkbox .mce-label{color:#707780;font-size:12px;font-weight:400}.mce-container{border-radius:0!important;border-width:0!important}.mce-container .mce-menubar{background-color:#f2f4f7!important;border:1px solid #d7dce5!important;padding:2px}.mce-container .mce-menubar .mce-btn button span{color:#707780;font-size:14px;font-weight:400;text-transform:capitalize}.mce-container .mce-btn button,.mce-container .mce-primary button{color:#fff;font-weight:400;font-size:14px;text-shadow:none}.mce-container .mce-menubar .mce-btn button .mce-caret{border-top-color:#707780}.mce-container .mce-menubar .mce-btn button:hover,.mce-container .mce-menubar .mce-btn.mce-active button{background-color:#e8ebf1}.mce-container .mce-btn{background-color:#d7dce5;background-image:none;outline:0;border:0;border-radius:0}.mce-container .mce-btn:hover{background-color:#b8c1d1;background-image:none}.mce-container .mce-primary{background-color:#00b19d;background-image:none;outline:0;border:0;border-radius:0}.mce-container .mce-primary:hover{background-color:#0c7cd5;background-image:none}.mce-container .mce-toolbar-grp{background-color:#f2f4f7!important;border:1px solid #d7dce5!important;border-top-width:0!important;padding:6px}.mce-container .mce-edit-area{border:1px solid #d7dce5!important;border-width:0 1px!important}.mce-container .mce-statusbar{background-color:#f2f4f7!important;border:1px solid #d7dce5!important}.mce-container .mce-btn-group .mce-btn,.mce-container .mce-btn-group .mce-btn:focus,.mce-container .mce-btn-group .mce-btn:hover{box-shadow:none;background-color:#fff;background-image:none}.mce-container .mce-statusbar .mce-path .mce-path-item{color:#707780;font-size:14px;font-weight:400}.mce-container .mce-widget{color:#9398a0;font-size:14px;font-weight:400;border-left:1px solid transparent}.mce-container .mce-btn-group{border:1px solid #e9ecf2!important}.mce-container .mce-btn-group .mce-btn{border-width:0;border-radius:0!important}.mce-container .mce-btn-group .mce-btn button span{color:#707780;font-size:14px;font-weight:300}.mce-container .mce-btn-group .mce-btn button .mce-caret,.mce-container .mce-ico{color:#707780;font-size:14px}.mce-container .mce-panel{background-image:none}.mce-container.mce-menu{border:1px solid #d7dce5!important}.mce-container.mce-menu .mce-menu-item{background-image:none}.mce-container.mce-menu .mce-menu-item .mce-ico{color:#00b19d;font-size:14px}.mce-container.mce-menu .mce-menu-item .mce-text{color:#707780;font-size:14px;font-weight:400;text-transform:capitalize}.mce-container.mce-menu .mce-menu-item .mce-menu-shortcut{color:#aaa;font-size:12px;font-weight:300;text-transform:capitalize}.mce-container.mce-menu .mce-menu-item.mce-selected,.mce-container.mce-menu .mce-menu-item:focus,.mce-container.mce-menu .mce-menu-item:hover{background-color:#00b19d}.mce-container.mce-menu .mce-menu-item-sep,.mce-container.mce-menu .mce-menu-item-sep:hover,.mce-container.mce-menu .mce-menu-item.mce-disabled.mce-selected,.mce-container.mce-menu .mce-menu-item.mce-disabled:focus,.mce-container.mce-menu .mce-menu-item.mce-disabled:hover{background-color:#d7dce5}.mce-container.mce-menu .mce-menu-item.mce-selected .mce-ico,.mce-container.mce-menu .mce-menu-item.mce-selected .mce-menu-shortcut,.mce-container.mce-menu .mce-menu-item.mce-selected .mce-text,.mce-container.mce-menu .mce-menu-item:focus .mce-ico,.mce-container.mce-menu .mce-menu-item:focus .mce-menu-shortcut,.mce-container.mce-menu .mce-menu-item:focus .mce-text,.mce-container.mce-menu .mce-menu-item:hover .mce-ico,.mce-container.mce-menu .mce-menu-item:hover .mce-menu-shortcut,.mce-container.mce-menu .mce-menu-item:hover .mce-text{color:#fff}.mce-container.mce-menu .mce-menu-item.mce-disabled .mce-ico,.mce-container.mce-menu .mce-menu-item.mce-disabled .mce-menu-shortcut,.mce-container.mce-menu .mce-menu-item.mce-disabled .mce-text{color:#aaa}.mce-container.mce-menu .mce-menu-item.mce-disabled.mce-selected .mce-ico,.mce-container.mce-menu .mce-menu-item.mce-disabled.mce-selected .mce-menu-shortcut,.mce-container.mce-menu .mce-menu-item.mce-disabled.mce-selected .mce-text,.mce-container.mce-menu .mce-menu-item.mce-disabled:focus .mce-ico,.mce-container.mce-menu .mce-menu-item.mce-disabled:focus .mce-menu-shortcut,.mce-container.mce-menu .mce-menu-item.mce-disabled:focus .mce-text,.mce-container.mce-menu .mce-menu-item.mce-disabled:hover .mce-ico,.mce-container.mce-menu .mce-menu-item.mce-disabled:hover .mce-menu-shortcut,.mce-container.mce-menu .mce-menu-item.mce-disabled:hover .mce-text{color:#fff}.mce-menubtn button{color:#797979!important}.mce-menu-item-normal.mce-active{background-color:#00b19d!important}.mce-menu-item-normal.mce-active .mce-text{color:#fff!important}.note-btn-group .dropdown-menu>li>a{display:block;padding:5px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.note-air-popover,.note-icon-caret,.note-image-popover,.note-link-popover{display:none}.note-btn-group .dropdown-menu>li>a:hover{background-color:#f3f3f3}.note-air-popover .dropdown-toggle::after,.note-image-popover .dropdown-toggle::after,.note-link-popover .dropdown-toggle::after{margin-left:0}.table-wrapper .btn-toolbar,.tablesaw-columntoggle-btnwrap .btn-group{display:block}.note-editor{position:relative}.note-editor .btn-default{background-color:transparent;border-color:transparent}.note-editor .btn-group-sm>.btn,.note-editor .btn-sm{padding:8px 12px}.note-editor .note-toolbar{background-color:#f3f3f3;border-bottom:1px solid #eee;margin:0}.note-editor .note-statusbar{background-color:#fff}.note-editor .note-statusbar .note-resizebar{border-top:none;height:15px;padding-top:3px}.note-editor.note-frame{border:1px solid #eee}.note-popover .popover .popover-content{padding:5px 0 10px 5px}.note-popover .btn-default{background-color:transparent;border-color:transparent}.note-popover .btn-group-sm>.btn,.note-popover .btn-sm{padding:8px 12px}.note-toolbar{padding:5px 0 10px 5px}.table{margin-bottom:10px}.table>tbody>tr>td,.table>tbody>tr>th,.table>tfoot>tr>td,.table>tfoot>tr>th,.table>thead>tr>td,.table>thead>tr>th{border-color:1px solid #f3f3f3}.table>tbody>tr>td.middle-align,.table>thead>tr>td.middle-align{vertical-align:middle}.add-edit-table td,.add-edit-table th,.mails td{vertical-align:middle!important}.table>thead>tr>th{border-color:2px solid #f3f3f3}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.04)}.table>tbody>tr.success>td,.table>tbody>tr.success>th,.table>tbody>tr>td.success,.table>tbody>tr>th.success,.table>tfoot>tr.success>td,.table>tfoot>tr.success>th,.table>tfoot>tr>td.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>thead>tr.success>th,.table>thead>tr>td.success,.table>thead>tr>th.success{background-color:fade(#3bafda,15%)}.table>tbody>tr.info>td,.table>tbody>tr.info>th,.table>tbody>tr>td.info,.table>tbody>tr>th.info,.table>tfoot>tr.info>td,.table>tfoot>tr.info>th,.table>tfoot>tr>td.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>thead>tr.info>th,.table>thead>tr>td.info,.table>thead>tr>th.info{background-color:fade(#3ddcf7,15%)}.table>tbody>tr.warning>td,.table>tbody>tr.warning>th,.table>tbody>tr>td.warning,.table>tbody>tr>th.warning,.table>tfoot>tr.warning>td,.table>tfoot>tr.warning>th,.table>tfoot>tr>td.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>thead>tr.warning>th,.table>thead>tr>td.warning,.table>thead>tr>th.warning{background-color:fade(#fa0,15%)}.table>tbody>tr.danger>td,.table>tbody>tr.danger>th,.table>tbody>tr>td.danger,.table>tbody>tr>th.danger,.table>tfoot>tr.danger>td,.table>tfoot>tr.danger>th,.table>tfoot>tr>td.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>thead>tr.danger>th,.table>thead>tr>td.danger,.table>thead>tr>th.danger{background-color:fade(#ef5350,15%)}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e!important}.dataTables_wrapper.container-fluid{max-width:100%;padding:0}div.dataTables_paginate ul.pagination{margin-top:30px}div.dataTables_info{padding-top:38px}.dt-buttons,div#datatable-buttons_info{float:left}.table-wrapper .dropdown-menu{left:auto;right:0}table.dataTable td.focus,table.dataTable th.focus{outline:#00b19d solid 2px!important;outline-offset:-1px;background-color:rgba(0,177,157,.15)}table.dataTable tbody>tr.selected,table.dataTable tbody>tr>.selected{background-color:#00b19d}table.dataTable.dtr-inline.collapsed>tbody>tr>td:first-child:before,table.dataTable.dtr-inline.collapsed>tbody>tr>th:first-child:before{box-shadow:0 0 3px rgba(67,89,102,.2);background-color:#3bafda}table.dataTable.dtr-inline.collapsed>tbody>tr.parent>td:first-child:before,table.dataTable.dtr-inline.collapsed>tbody>tr.parent>th:first-child:before{background-color:#ef5350}.table-rep-plugin .dropdown-menu li.checkbox-row{padding:2px 15px!important}.table-rep-plugin .table-responsive{border:none!important}.table-rep-plugin tbody th{font-size:14px;font-weight:400}.table-rep-plugin .checkbox-row{padding-left:40px}.table-rep-plugin .checkbox-row label{display:inline-block;padding-left:5px;position:relative}.table-rep-plugin .checkbox-row label::before{-o-transition:.3s ease-in-out;-webkit-transition:.3s ease-in-out;background-color:#fff;border-radius:3px;border:1px solid #98a6ad;content:"";display:inline-block;height:17px;left:0;margin-left:-20px;position:absolute;transition:.3s ease-in-out;width:17px;outline:0!important}.table-rep-plugin .checkbox-row label::after{color:#f3f3f3;display:inline-block;font-size:11px;height:16px;left:0;margin-left:-20px;padding-left:3px;padding-top:1px;position:absolute;top:-1px;width:16px}.table-rep-plugin .checkbox-row input[type=checkbox]{cursor:pointer;opacity:0;z-index:1;outline:0!important}.table-rep-plugin .checkbox-row input[type=checkbox]:disabled+label{opacity:.65}.table-rep-plugin .checkbox-row input[type=checkbox]:focus+label::before{outline-offset:-2px;outline:0}.table-rep-plugin .checkbox-row input[type=checkbox]:checked+label::after{content:"\f00c";font-family:FontAwesome;color:#00b19d}.table-rep-plugin .checkbox-row input[type=checkbox]:disabled+label::before{background-color:#eee;cursor:not-allowed}.table-rep-plugin .checkbox-row input[type=checkbox]:checked+label::before{background-color:#fff;border-color:#00b19d}.table-rep-plugin .sticky-table-header,.table-rep-plugin table.focus-on tbody tr.focused td,.table-rep-plugin table.focus-on tbody tr.focused th{background-color:#00b19d;color:#fff;border-color:#00b19d}.table-rep-plugin .sticky-table-header.fixed-solution{top:120px!important}.table-rep-plugin .btn-default{background-color:#fff;border:1px solid rgba(42,49,66,.3)}.table-rep-plugin .btn-default.btn-primary{background-color:#00b19d}.table-rep-plugin .btn-toolbar{display:block}.table-rep-plugin .btn-group.pull-right{float:right}.table-rep-plugin .btn-group.pull-right .dropdown-menu{left:auto;right:0}.add-edit-table td{border:0!important}#datatable-editable .actions a{padding:5px}#datatable-editable .form-control{background-color:#fff;width:auto;height:20px}#datatable-editable .fa-times,#datatable-editable .fa-trash-o{color:#ef5350}#datatable-editable .fa-pencil{color:#00b19d}#datatable-editable .fa-save{color:#3bafda}#datatable td{font-weight:400}.modal-block{background:0 0;margin:40px auto;max-width:600px;padding:0;position:relative;text-align:left}.tablesaw thead{background:#f5f5f5;border:none}.tablesaw thead th{text-shadow:none;letter-spacing:.06em}.home-text,.ribbon span{letter-spacing:1px}.tablesaw thead tr:first-child th{padding-top:1.1em;padding-bottom:.9em;font-weight:600;font-family:inherit;border:none}.tablesaw tbody th,.tablesaw td{font-size:inherit;line-height:inherit;padding:10px!important}.tablesaw tbody tr,.tablesaw-stack tbody tr{border-bottom:none}.tablesaw-sortable .tablesaw-sortable-head.tablesaw-sortable-ascending button:after,.tablesaw-sortable .tablesaw-sortable-head.tablesaw-sortable-descending button:after{font-family:FontAwesome;font-size:10px}.tablesaw-sortable .tablesaw-sortable-head.tablesaw-sortable-ascending button:after{content:"\f176"}.tablesaw-sortable .tablesaw-sortable-head.tablesaw-sortable-descending button:after{content:"\f175"}.timeline-item.alt:after,.timeline-item:before,.timeline:before{content:""}.tablesaw-bar .btn-select.btn-micro:after,.tablesaw-bar .btn-select.btn-small:after{font-size:8px;padding-right:10px}.tablesaw-swipe .tablesaw-cell-persist{box-shadow:none}.tablesaw-enhanced .tablesaw-bar .btn{text-shadow:none;background-image:none}.tablesaw-enhanced .tablesaw-bar .btn.btn-select:hover{background:#fff}.tablesaw-enhanced .tablesaw-bar .btn:active,.tablesaw-enhanced .tablesaw-bar .btn:focus,.tablesaw-enhanced .tablesaw-bar .btn:hover{color:#00b19d!important;background-color:#f5f5f5;outline:0!important;box-shadow:none!important;background-image:none}.footable-odd{background-color:#fff}.footable-detail-show{background-color:#e6e6e6}.footable>thead>tr>th>span.footable-sort-indicator{float:right}.footable-pagination li{margin-left:5px;display:inline-block;float:left}.footable-pagination li a{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#2a3142;background-color:#fff;border:1px solid #eee}.gmaps-overlay_arrow.above,.gmaps-overlay_arrow.below{border-left:16px solid transparent;border-right:16px solid transparent}.footable-pagination li.active a{color:#fff}.gmaps,.gmaps-panaroma{height:300px;background:#eee;border-radius:3px}.gmaps-overlay{display:block;text-align:center;color:#fff;font-size:16px;line-height:40px;background:#00b19d;border-radius:4px;padding:10px 20px}.gmaps-overlay_arrow{left:50%;margin-left:-16px;width:0;height:0;position:absolute}.gmaps-overlay_arrow.above{bottom:-15px;border-top:16px solid #00b19d}.gmaps-overlay_arrow.below{top:-15px;border-bottom:16px solid #00b19d}.mails a{color:#797979}.mails td{position:relative}.mails td:last-of-type{width:100px;padding-right:20px}.mails tr:hover .text-white{display:none}.mails .mail-select{padding:12px 20px;min-width:134px}.mails .checkbox{margin-bottom:0;margin-top:0;vertical-align:middle;display:inline-block;height:17px}.mails .checkbox label{min-height:16px}.mail-list .list-group-item{background-color:transparent;color:#2a3142;font-size:.95rem}.mail-list .list-group-item:focus,.mail-list .list-group-item:hover{background-color:#eee}.mail-list .list-group-item.active{color:#ef5350}.unread a{font-weight:600;color:#444}.calendar{float:left;margin-bottom:0}.none-border .modal-footer{border-top:none}.fc-button,.fc-widget-content,.fc-widget-header{border:1px solid #d5d5d5}.fc-toolbar{margin-bottom:5px}.fc-toolbar h2{font-size:18px;font-weight:600;line-height:30px;text-transform:uppercase}.fc-day{background:#fff}.fc-toolbar .fc-state-active,.fc-toolbar .ui-state-active,.fc-toolbar .ui-state-hover,.fc-toolbar button:focus,.fc-toolbar button:hover{z-index:0}.fc th.fc-widget-header{background:#ddd;font-size:14px;line-height:20px;padding:10px 0;text-transform:uppercase}.fc-button{background:#fff;color:#555;text-transform:capitalize}.external-event,.fc-event .fc-content,.timeline .time-show a{color:#fff}.fc-text-arrow{font-family:arial;font-size:16px}.fc-state-hover{background:#F5F5F5}.fc-cell-overlay,.fc-state-highlight{background:#f0f0f0}.fc-unthemed .fc-today{background:#fff}.fc-event{border-radius:2px;border:none;cursor:move;font-size:13px;margin:5px 7px;padding:5px;text-align:center}.external-event{cursor:move;margin:10px 0;padding:6px 10px}.fc-basic-view td.fc-day-number,.fc-basic-view td.fc-week-number span{padding-right:5px}.timeline{border-collapse:collapse;border-spacing:0;display:table;margin-bottom:50px;position:relative;table-layout:fixed;width:100%}.timeline .time-show{margin-bottom:30px;margin-right:-75px;margin-top:30px;position:relative}.timeline:before{background-color:#d8d9df;bottom:0;left:50%;position:absolute;top:30px;width:1px;z-index:0}.timeline .timeline-icon{-webkit-border-radius:50%;background:#d8d9df;border-radius:50%;border:1px solid #d8d9df;color:#fff;display:block;height:20px;left:-54px;margin-top:-10px;position:absolute;text-align:center;top:50%;width:20px}.timeline .timeline-icon i{margin-top:9px}.timeline .time-icon:before{font-size:16px;margin-top:5px}h3.timeline-title{color:#c8ccd7;font-size:20px;font-weight:400;margin:0 0 5px;text-transform:uppercase}.timeline-item .timeline-desk .arrow,.timeline-item.alt .timeline-desk .arrow-alt{border-bottom:8px solid transparent;border-top:8px solid transparent;height:0;margin-top:-10px;position:absolute;top:50%}.timeline-item{display:table-row}.timeline-item:before{display:block;width:50%}.timeline-item .timeline-desk .arrow{border-right:8px solid #fff!important;display:block;left:-7px;width:0}.timeline-item.alt:after{display:block;width:50%}.timeline-item.alt .timeline-desk .arrow-alt{border-left:8px solid #fff!important;display:block;left:auto;right:-7px;width:0}.timeline-item.alt .timeline-desk .album{float:right;margin-top:20px}.timeline-item.alt .timeline-desk .album a{float:right;margin-left:5px}.timeline-item.alt .timeline-icon{left:auto;right:-56px}.timeline-item.alt:before{display:none}.timeline-item.alt .panel{margin-left:0;margin-right:45px}.timeline-item.alt .panel .panel-body p+p{margin-top:10px!important}.timeline-item.alt .timeline-date,.timeline-item.alt h4,.timeline-item.alt p{text-align:right}.timeline-desk{display:table-cell;vertical-align:top;width:50%}.timeline-desk h4{font-size:16px;margin:0}.timeline-desk .panel{background:#fff;display:block;margin-bottom:5px;margin-left:45px;position:relative;text-align:left;padding:15px;border-radius:5px}.timeline-desk h5 span{color:#797979;display:block;font-size:12px;margin-bottom:4px}.timeline-desk p{color:#999;font-size:14px;margin-bottom:0}.timeline-desk .album{margin-top:12px}.timeline-desk .album a{float:left;margin-right:5px}.timeline-desk .album img{height:36px;width:auto;border-radius:3px}.timeline-desk .notification{background:#fff;margin-top:20px;padding:8px}.timeline-2{border-left:2px solid #00b19d;position:relative}.time-item:after,.timeline-2 .time-item:after{background-color:#fff;border-radius:10px;border-style:solid;border-width:2px;bottom:0;left:0;top:5px}.timeline-2 .time-item:after{border-color:#00b19d;content:'';height:10px;margin-left:-6px;position:absolute;width:10px}.time-item{border-color:#dee5e7;padding-bottom:10px;position:relative}.time-item:before{content:" ";display:table}.time-item:after{border-color:#00b19d;content:'';height:14px;margin-left:-8px;position:absolute;width:14px}.time-item-item:after{content:" ";display:table}.item-info{margin-bottom:15px;margin-left:15px}.item-info p{font-size:13px}.swal2-modal{font-family:"Microsoft YaHei","微软雅黑",Arial,"黑体","宋体",sans-serif;box-shadow:0 10px 33px rgba(0,0,0,.1)}.swal2-modal .swal2-title{font-size:28px}.swal2-modal .swal2-content{font-size:16px}.swal2-modal .swal2-spacer{margin:10px 0}.swal2-modal .swal2-file,.swal2-modal .swal2-input,.swal2-modal .swal2-textarea{border:2px solid #98a6ad;font-size:16px;box-shadow:none}.swal2-modal .swal2-confirm.btn-confirm{background-color:#00b19d!important}.swal2-modal .swal2-cancel.btn-cancel{background-color:#ef5350!important}.swal2-modal .swal2-styled:focus{box-shadow:none!important}.swal2-icon.swal2-question{color:#00b19d;border-color:#00b19d}.swal2-icon.swal2-success,.swal2-icon.swal2-success .placeholder,.swal2-icon.swal2-success .swal2-success-ring{border-color:#3bafda}.swal2-icon.swal2-success .line,.swal2-icon.swal2-success [class^=swal2-success-line],.swal2-icon.swal2-success [class^=swal2-success-line][class$=long]{background-color:#3bafda}.swal2-icon.swal2-warning{color:#fa0;border-color:#fa0}.swal2-icon.swal2-error{border-color:#ef5350}.swal2-icon.swal2-error .line{background-color:#ef5350}.swal2-modal .swal2-file:focus,.swal2-modal .swal2-input:focus,.swal2-modal .swal2-textarea:focus{outline:0;border:2px solid #00b19d}.swal2-container.swal2-shown{background-color:rgba(42,49,66,.9)}.notifyjs-metro-base{position:relative;min-height:52px;min-width:250px;color:#444;border-radius:3px;-webkit-border-radius:3px;box-shadow:0 1px 0 rgba(0,0,0,.2);-webkit-animation:dropdownOpen .3s ease-out;-o-animation:dropdownOpen .3s ease-out;animation:dropdownOpen .3s ease-out}.notifyjs-metro-base .image{display:table;position:absolute;height:auto;width:auto;left:25px;top:50%;font-size:24px;-moz-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);-o-transform:translate(-50%,-50%);-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}.app-countdown div,.chart,.percent{display:inline-block}.notifyjs-metro-base .text-wrapper{display:inline-block;vertical-align:top;text-align:left;margin:10px 10px 10px 52px;clear:both}.app-countdown,.app-countdown>*,.chart{text-align:center}.notifyjs-metro-base .title{font-size:15px;line-height:20px;margin-bottom:5px;font-weight:700}.notifyjs-metro-base .text{font-size:12px;font-weight:400;max-width:360px;vertical-align:middle}.notifyjs-metro-cool{color:#fafafa!important;background-color:#4A525F;border:1px solid #4A525F}.custom-dd .dd-list .dd-item .dd-handle{background:rgba(152,166,173,.25)!important;border:none;padding:8px 16px;height:auto;font-weight:600;border-radius:3px}.custom-dd .dd-list .dd-item .dd-handle:hover{color:#00b19d}.custom-dd .dd-list .dd-item button{height:auto;font-size:17px;margin:8px auto;color:#555;width:30px}.custom-dd-empty .dd-list .dd3-handle{border:none;background:rgba(152,166,173,.25)!important;height:36px;width:36px}.custom-dd-empty .dd-list .dd3-handle:before{color:inherit;top:7px}.custom-dd-empty .dd-list .dd3-content:hover,.custom-dd-empty .dd-list .dd3-handle:hover{color:#00b19d}.custom-dd-empty .dd-list .dd3-content{height:auto;border:none;padding:8px 16px 8px 46px;background:rgba(152,166,173,.25)!important;font-weight:600}.custom-dd-empty .dd-list button{width:26px;height:26px;font-size:16px;font-weight:600}.morris-hover.morris-default-style{border-radius:5px;padding:10px 12px;background:#36404a;border:none;color:#fff!important}.chart-detail-list li{margin:0 10px}.chart-detail-list li h5{font-size:15px}.pieLabel div{font-size:14px!important}.chart{position:relative;width:110px;height:110px;margin-top:20px;margin-bottom:20px}.chart canvas{position:absolute;top:0;left:0}.chart.chart-widget-pie{margin-top:5px;margin-bottom:5px}.percent{line-height:110px;z-index:2;font-weight:600;font-size:18px;color:#797979}.percent:after{content:'%';margin-left:.1em;font-size:.8em}#flotTip{padding:8px 12px;background-color:#36404a;z-index:100;color:#fff;opacity:.9;font-size:13px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.legend tr{height:20px}.legendLabel{padding-left:10px!important;line-height:10px;padding-right:10px}.ct-golden-section:before{float:none}.ct-chart{max-height:300px}.ct-chart .ct-label{fill:#a3afb7;color:#a3afb7;font-size:12px;line-height:1}.ct-chart.simple-pie-chart-chartist .ct-label{color:#fff;fill:#fff;font-size:16px}.ct-chart .ct-series.ct-series-a .ct-bar,.ct-chart .ct-series.ct-series-a .ct-line,.ct-chart .ct-series.ct-series-a .ct-point,.ct-chart .ct-series.ct-series-a .ct-slice-donut{stroke:#00b19d}.ct-chart .ct-series.ct-series-b .ct-bar,.ct-chart .ct-series.ct-series-b .ct-line,.ct-chart .ct-series.ct-series-b .ct-point,.ct-chart .ct-series.ct-series-b .ct-slice-donut{stroke:#f76397}.ct-chart .ct-series.ct-series-c .ct-bar,.ct-chart .ct-series.ct-series-c .ct-line,.ct-chart .ct-series.ct-series-c .ct-point,.ct-chart .ct-series.ct-series-c .ct-slice-donut{stroke:#3bafda}.ct-chart .ct-series.ct-series-d .ct-bar,.ct-chart .ct-series.ct-series-d .ct-line,.ct-chart .ct-series.ct-series-d .ct-point,.ct-chart .ct-series.ct-series-d .ct-slice-donut{stroke:#3ddcf7}.ct-chart .ct-series.ct-series-e .ct-bar,.ct-chart .ct-series.ct-series-e .ct-line,.ct-chart .ct-series.ct-series-e .ct-point,.ct-chart .ct-series.ct-series-e .ct-slice-donut{stroke:#797979}.ct-chart .ct-series.ct-series-f .ct-bar,.ct-chart .ct-series.ct-series-f .ct-line,.ct-chart .ct-series.ct-series-f .ct-point,.ct-chart .ct-series.ct-series-f .ct-slice-donut{stroke:#7266ba}.ct-chart .ct-series.ct-series-g .ct-bar,.ct-chart .ct-series.ct-series-g .ct-line,.ct-chart .ct-series.ct-series-g .ct-point,.ct-chart .ct-series.ct-series-g .ct-slice-donut{stroke:#fa0}.ct-series-a .ct-area,.ct-series-a .ct-slice-pie{fill:#00b19d}.ct-series-b .ct-area,.ct-series-b .ct-slice-pie{fill:#f76397}.ct-series-c .ct-area,.ct-series-c .ct-slice-pie{fill:#3bafda}.ct-series-d .ct-area,.ct-series-d .ct-slice-pie{fill:#3ddcf7}.jqstooltip{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;background-color:#2a3142!important;padding:5px 10px!important;border-radius:3px;border-color:#2a3142!important}.jqsfield{font-size:12px!important;line-height:18px!important}.circliful-chart{margin:0 auto}.circle-info,.circle-info-half,.circle-text,.circle-text-half{font-size:12px;font-weight:600}.home-wrapper{margin:10% 0}.app-countdown{margin-top:40px}.app-countdown div span{display:block;width:150px}.app-countdown div span:first-child{font-size:3em;font-weight:700;height:48px;line-height:48px}.app-countdown div span:last-child{color:#333;font-size:.9em;height:25px;line-height:25px}.portfolioFilter a{-webkit-transition:all .3s ease-out;-moz-transition:all .3s ease-out;-o-transition:all .3s ease-out;transition:all .3s ease-out;color:#2a3142;padding:5px 10px;display:inline-block;font-size:14px;font-weight:500;border-radius:4px}.portfolioFilter a.current,.portfolioFilter a:hover{background-color:#00b19d;color:#fff}.thumb{background-color:#fff;border-radius:3px;box-shadow:0 1px 1px 0 rgba(0,0,0,.1);margin-top:30px;padding:10px;width:100%}.thumb-img{border-radius:2px;overflow:hidden;width:100%}.gal-detail h4{margin:16px auto 10px;width:80%;display:block;overflow:hidden;font-size:18px}.gal-detail p{margin-bottom:10px}.gal-detail .ga-border{height:3px;width:40px;background-color:#00b19d;margin:10px auto}.icon-main{font-size:60px}.maintenance-page{margin:10% 0}.wrapper-page{margin:7.5% auto;max-width:420px}.wrapper-page .form-control{height:40px}.logo-lg{font-size:25px!important;font-weight:700;color:#00b19d!important}.user-thumb img{height:88px;margin:0 auto;width:88px}.ex-page-content .svg-box{float:right}.message-box{margin:120px 50px}.message-box h1{color:#252932;font-size:98px;font-weight:700;line-height:98px;text-shadow:rgba(61,61,61,.3) 1px 1px,rgba(61,61,61,.2) 2px 2px,rgba(61,61,61,.3) 3px 3px}#Polygon-1,#Polygon-2,#Polygon-3,#Polygon-4,#Polygon-5{animation:float 1s infinite ease-in-out alternate}#Polygon-2{animation-delay:.2s}#Polygon-3{animation-delay:.4s}#Polygon-4{animation-delay:.6s}#Polygon-5{animation-delay:.8s}@keyframes float{100%{transform:translateY(20px)}}.jstree-default .jstree-clicked,.jstree-default .jstree-wholerow-clicked{background:rgba(0,177,157,.4);box-shadow:none}.jstree-default .jstree-hovered,.jstree-default .jstree-wholerow-hovered{background:rgba(0,177,157,.2);box-shadow:none}.pricing-column{position:relative;margin-bottom:40px}.pricing-column .inner-box{position:relative;padding:0 0 50px}.pricing-column .plan-header{position:relative;padding:30px 20px 25px}.pricing-column .plan-title{font-size:16px;margin-bottom:10px;color:#3bafda;text-transform:uppercase;letter-spacing:1px;font-weight:400}.pricing-column .plan-price{font-size:48px;margin-bottom:10px;color:#2a3142}.pricing-column .plan-duration{font-size:13px;color:#98a6ad}.pricing-column .plan-stats{position:relative;padding:30px 20px 15px}.pricing-column .plan-stats li{margin-bottom:15px;line-height:24px}.pricing-column .plan-stats li i{font-size:16px;vertical-align:middle;margin-right:5px}.ribbon{position:absolute;left:5px;top:-5px;z-index:1;overflow:hidden;width:75px;height:75px;text-align:right}.question-q-box,.ribbon span{color:#fff;text-align:center;font-weight:700}.ribbon span{font-size:10px;text-transform:uppercase;line-height:20px;transform:rotate(-45deg);-webkit-transform:rotate(-45deg);width:100px;display:block;box-shadow:0 0 8px 0 rgba(0,0,0,.06),0 1px 0 0 rgba(0,0,0,.02);background:#3bafda;background:linear-gradient(#3bafda 0,#3bafda 100%);position:absolute;top:19px;left:-21px}.ribbon span:after,.ribbon span:before{content:"";position:absolute;top:100%;z-index:-1;border-bottom:3px solid transparent;border-top:3px solid #2494be}.ribbon span:before{left:0;border-left:3px solid #2494be;border-right:3px solid transparent}.ribbon span:after{right:0;border-left:3px solid transparent;border-right:3px solid #2494be}.question-q-box{height:30px;width:30px;background-color:#ef5350;border-radius:50%;float:left;line-height:26px}.question{margin-top:0;margin-left:50px;font-size:16px}.answer{margin-left:50px;color:#98a6ad;margin-bottom:40px;line-height:26px}@media (min-width:768px) and (max-width:991px){body{overflow-x:hidden}.fixedHeader-floating{top:60px!important}}@media (max-width:768px){body{overflow-x:hidden}.container-fluid{max-width:100%}.topbar-left{width:70px!important}.topbar-left span{display:none!important}.topbar-left i{display:block!important;line-height:70px!important}.topbar .topbar-left{height:70px}.navbar-nav.navbar-right{float:right}.content-page{margin-left:0!important}.enlarged .left.side-menu{margin-left:-70px}.footer{left:0!important}.mobile-sidebar{left:0}.mobile-content{left:250px;right:-250px}.dataTables_wrapper .col-xs-6{width:100%;text-align:left}div#datatable-buttons_info{float:none}.ms-container{width:100%}.m-t-sm-50{margin-top:50px!important}.fixedHeader-floating{top:60px!important}}@media (max-width:767px){.navbar-nav .open .dropdown-menu{background-color:#fff;box-shadow:0 2px 5px 0 rgba(0,0,0,.26);left:auto;position:absolute;right:0}.navbar-nav .open .dropdown-menu li{display:block}.navbar-nav{margin:0;display:inline-block}.navbar-nav li{display:inline-block;line-height:1px}.dropdown-lg{width:200px!important}.user-box{float:right}.dataTables_length{float:none;margin-bottom:10px}.table-auto-res{display:block;width:100%;overflow-x:auto}}@media (max-width:480px){.side-menu{z-index:10!important}.button-menu-mobile{display:block}.search-bar{display:none!important}.logo-large{display:none}.logo-small{display:inline-block!important}.dropdown-menu-lg{max-width:230px}}@media (max-width:420px){.hide-phone{display:none!important}}@media (min-width:768px){.container-alt{width:750px}}@media (min-width:992px){.container-alt{width:970px}}@media (min-width:1200px){.container-alt{width:1170px}}@media (max-width:419px){.hidden-xxs,.page-title-box .breadcrumb,.topbar-left,.user-list .user-list-item .avatar,.user-list .user-list-item .icon{display:none}.topbar-left{width:70px!important}.content-page{margin-left:70px}.forced .side-menu.left{box-shadow:0 12px 12px rgba(0,0,0,.1)}.enlarged .side-menu.left{box-shadow:0 1px 1px rgba(0,0,0,.1)!important}.page-title{font-size:15px;max-width:250px;white-space:nowrap}.navbar-default{padding:0}.navbar-default .navbar-left{padding-left:0!important}.navbar-default .navbar-left li{padding:0 5px}.editable-responsive{overflow-x:auto}.navbar-nav .open .dropdown-menu{margin-right:-20px}.user-box .dropdown-menu{margin-right:0!important}.dropdown-lg{width:200px!important}.user-list .user-list-item .user-desc{margin-left:0}}.nav-rounded .nav-link{font-weight:400;border-radius:1.25rem;font-size:14px}.editable,.editable a,.editable span{border-bottom:dashed 1px #0056b3!important} \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/assets/datePicker/WdatePicker.js b/net452/SiteServer.Web/SiteServer/assets/datePicker/WdatePicker.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/datePicker/WdatePicker.js rename to net452/SiteServer.Web/SiteServer/assets/datePicker/WdatePicker.js diff --git a/SiteServer.Web/SiteServer/assets/datePicker/calendar.js b/net452/SiteServer.Web/SiteServer/assets/datePicker/calendar.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/datePicker/calendar.js rename to net452/SiteServer.Web/SiteServer/assets/datePicker/calendar.js diff --git a/SiteServer.Web/SiteServer/assets/datePicker/lang/en.js b/net452/SiteServer.Web/SiteServer/assets/datePicker/lang/en.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/datePicker/lang/en.js rename to net452/SiteServer.Web/SiteServer/assets/datePicker/lang/en.js diff --git a/SiteServer.Web/SiteServer/assets/datePicker/lang/zh-cn.js b/net452/SiteServer.Web/SiteServer/assets/datePicker/lang/zh-cn.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/datePicker/lang/zh-cn.js rename to net452/SiteServer.Web/SiteServer/assets/datePicker/lang/zh-cn.js diff --git a/SiteServer.Web/SiteServer/assets/datePicker/lang/zh-tw.js b/net452/SiteServer.Web/SiteServer/assets/datePicker/lang/zh-tw.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/datePicker/lang/zh-tw.js rename to net452/SiteServer.Web/SiteServer/assets/datePicker/lang/zh-tw.js diff --git a/SiteServer.Web/SiteServer/assets/datePicker/skin/WdatePicker.css b/net452/SiteServer.Web/SiteServer/assets/datePicker/skin/WdatePicker.css similarity index 100% rename from SiteServer.Web/SiteServer/assets/datePicker/skin/WdatePicker.css rename to net452/SiteServer.Web/SiteServer/assets/datePicker/skin/WdatePicker.css diff --git a/SiteServer.Web/SiteServer/assets/datePicker/skin/datePicker.gif b/net452/SiteServer.Web/SiteServer/assets/datePicker/skin/datePicker.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/datePicker/skin/datePicker.gif rename to net452/SiteServer.Web/SiteServer/assets/datePicker/skin/datePicker.gif diff --git a/SiteServer.Web/SiteServer/assets/datePicker/skin/default/datepicker.css b/net452/SiteServer.Web/SiteServer/assets/datePicker/skin/default/datepicker.css similarity index 100% rename from SiteServer.Web/SiteServer/assets/datePicker/skin/default/datepicker.css rename to net452/SiteServer.Web/SiteServer/assets/datePicker/skin/default/datepicker.css diff --git a/SiteServer.Web/SiteServer/assets/datePicker/skin/default/img.gif b/net452/SiteServer.Web/SiteServer/assets/datePicker/skin/default/img.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/datePicker/skin/default/img.gif rename to net452/SiteServer.Web/SiteServer/assets/datePicker/skin/default/img.gif diff --git a/SiteServer.Web/SiteServer/assets/datePicker/skin/whyGreen/bg.jpg b/net452/SiteServer.Web/SiteServer/assets/datePicker/skin/whyGreen/bg.jpg similarity index 100% rename from SiteServer.Web/SiteServer/assets/datePicker/skin/whyGreen/bg.jpg rename to net452/SiteServer.Web/SiteServer/assets/datePicker/skin/whyGreen/bg.jpg diff --git a/SiteServer.Web/SiteServer/assets/datePicker/skin/whyGreen/datepicker.css b/net452/SiteServer.Web/SiteServer/assets/datePicker/skin/whyGreen/datepicker.css similarity index 100% rename from SiteServer.Web/SiteServer/assets/datePicker/skin/whyGreen/datepicker.css rename to net452/SiteServer.Web/SiteServer/assets/datePicker/skin/whyGreen/datepicker.css diff --git a/SiteServer.Web/SiteServer/assets/datePicker/skin/whyGreen/img.gif b/net452/SiteServer.Web/SiteServer/assets/datePicker/skin/whyGreen/img.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/datePicker/skin/whyGreen/img.gif rename to net452/SiteServer.Web/SiteServer/assets/datePicker/skin/whyGreen/img.gif diff --git a/SiteServer.Web/SiteServer/assets/default/access.mdb b/net452/SiteServer.Web/SiteServer/assets/default/access.mdb similarity index 100% rename from SiteServer.Web/SiteServer/assets/default/access.mdb rename to net452/SiteServer.Web/SiteServer/assets/default/access.mdb diff --git a/SiteServer.Web/SiteServer/assets/echarts/.DS_Store b/net452/SiteServer.Web/SiteServer/assets/echarts/.DS_Store similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/.DS_Store rename to net452/SiteServer.Web/SiteServer/assets/echarts/.DS_Store diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/bar.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/bar.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/bar.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/bar.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/chord.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/chord.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/chord.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/chord.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/eventRiver.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/eventRiver.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/eventRiver.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/eventRiver.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/force.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/force.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/force.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/force.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/funnel.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/funnel.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/funnel.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/funnel.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/gauge.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/gauge.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/gauge.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/gauge.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/heatmap.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/heatmap.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/heatmap.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/heatmap.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/k.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/k.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/k.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/k.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/line.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/line.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/line.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/line.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/map.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/map.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/map.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/map.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/pie.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/pie.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/pie.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/pie.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/radar.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/radar.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/radar.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/radar.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/scatter.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/scatter.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/scatter.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/scatter.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/tree.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/tree.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/tree.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/tree.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/treemap.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/treemap.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/treemap.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/treemap.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/venn.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/venn.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/venn.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/venn.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/chart/wordCloud.js b/net452/SiteServer.Web/SiteServer/assets/echarts/chart/wordCloud.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/chart/wordCloud.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/chart/wordCloud.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/echarts-all.js b/net452/SiteServer.Web/SiteServer/assets/echarts/echarts-all.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/echarts-all.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/echarts-all.js diff --git a/SiteServer.Web/SiteServer/assets/echarts/echarts.js b/net452/SiteServer.Web/SiteServer/assets/echarts/echarts.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/echarts/echarts.js rename to net452/SiteServer.Web/SiteServer/assets/echarts/echarts.js diff --git a/net452/SiteServer.Web/SiteServer/assets/fonts/FontAwesome.otf b/net452/SiteServer.Web/SiteServer/assets/fonts/FontAwesome.otf new file mode 100644 index 000000000..401ec0f36 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/fonts/FontAwesome.otf differ diff --git a/net452/SiteServer.Web/SiteServer/assets/fonts/fontawesome-webfont.eot b/net452/SiteServer.Web/SiteServer/assets/fonts/fontawesome-webfont.eot new file mode 100644 index 000000000..e9f60ca95 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/fonts/fontawesome-webfont.eot differ diff --git a/net452/SiteServer.Web/SiteServer/assets/fonts/fontawesome-webfont.svg b/net452/SiteServer.Web/SiteServer/assets/fonts/fontawesome-webfont.svg new file mode 100644 index 000000000..855c845e5 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/net452/SiteServer.Web/SiteServer/assets/fonts/fontawesome-webfont.ttf b/net452/SiteServer.Web/SiteServer/assets/fonts/fontawesome-webfont.ttf new file mode 100644 index 000000000..35acda2fa Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/fonts/fontawesome-webfont.ttf differ diff --git a/net452/SiteServer.Web/SiteServer/assets/fonts/fontawesome-webfont.woff b/net452/SiteServer.Web/SiteServer/assets/fonts/fontawesome-webfont.woff new file mode 100644 index 000000000..400014a4b Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/fonts/fontawesome-webfont.woff differ diff --git a/net452/SiteServer.Web/SiteServer/assets/fonts/fontawesome-webfont.woff2 b/net452/SiteServer.Web/SiteServer/assets/fonts/fontawesome-webfont.woff2 new file mode 100644 index 000000000..4d13fc604 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/fonts/fontawesome-webfont.woff2 differ diff --git a/net452/SiteServer.Web/SiteServer/assets/fonts/ionicons.eot b/net452/SiteServer.Web/SiteServer/assets/fonts/ionicons.eot new file mode 100644 index 000000000..92a3f20a3 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/fonts/ionicons.eot differ diff --git a/net452/SiteServer.Web/SiteServer/assets/fonts/ionicons.svg b/net452/SiteServer.Web/SiteServer/assets/fonts/ionicons.svg new file mode 100644 index 000000000..49fc8f367 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/fonts/ionicons.svg @@ -0,0 +1,2230 @@ + + + + + +Created by FontForge 20120731 at Thu Dec 4 09:51:48 2014 + By Adam Bradley +Created by Adam Bradley with FontForge 2.0 (http://fontforge.sf.net) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/net452/SiteServer.Web/SiteServer/assets/fonts/ionicons.ttf b/net452/SiteServer.Web/SiteServer/assets/fonts/ionicons.ttf new file mode 100644 index 000000000..c4e463248 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/fonts/ionicons.ttf differ diff --git a/net452/SiteServer.Web/SiteServer/assets/fonts/ionicons.woff b/net452/SiteServer.Web/SiteServer/assets/fonts/ionicons.woff new file mode 100644 index 000000000..5f3a14e0a Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/fonts/ionicons.woff differ diff --git a/SiteServer.Web/SiteServer/assets/icons/Recommend.gif b/net452/SiteServer.Web/SiteServer/assets/icons/Recommend.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/Recommend.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/Recommend.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/add.gif b/net452/SiteServer.Web/SiteServer/assets/icons/add.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/add.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/add.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/addimage.gif b/net452/SiteServer.Web/SiteServer/assets/icons/addimage.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/addimage.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/addimage.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/addlist.gif b/net452/SiteServer.Web/SiteServer/assets/icons/addlist.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/addlist.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/addlist.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_first.gif b/net452/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_first.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/arrow/arrow_first.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_first.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_first_d.gif b/net452/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_first_d.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/arrow/arrow_first_d.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_first_d.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_last.gif b/net452/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_last.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/arrow/arrow_last.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_last.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_last_d.gif b/net452/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_last_d.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/arrow/arrow_last_d.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_last_d.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_next.gif b/net452/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_next.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/arrow/arrow_next.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_next.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_next_d.gif b/net452/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_next_d.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/arrow/arrow_next_d.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_next_d.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_prev.gif b/net452/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_prev.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/arrow/arrow_prev.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_prev.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_prev_d.gif b/net452/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_prev_d.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/arrow/arrow_prev_d.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/arrow/arrow_prev_d.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/arrows.gif b/net452/SiteServer.Web/SiteServer/assets/icons/arrows.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/arrows.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/arrows.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/attachment.gif b/net452/SiteServer.Web/SiteServer/assets/icons/attachment.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/attachment.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/attachment.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/cancel.gif b/net452/SiteServer.Web/SiteServer/assets/icons/cancel.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/cancel.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/cancel.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/click.gif b/net452/SiteServer.Web/SiteServer/assets/icons/click.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/click.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/click.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/close.gif b/net452/SiteServer.Web/SiteServer/assets/icons/close.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/close.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/close.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/colorpicker.gif b/net452/SiteServer.Web/SiteServer/assets/icons/colorpicker.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/colorpicker.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/colorpicker.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/default.gif b/net452/SiteServer.Web/SiteServer/assets/icons/default.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/default.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/default.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/delete.gif b/net452/SiteServer.Web/SiteServer/assets/icons/delete.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/delete.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/delete.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/deletelist.gif b/net452/SiteServer.Web/SiteServer/assets/icons/deletelist.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/deletelist.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/deletelist.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/design/write.gif b/net452/SiteServer.Web/SiteServer/assets/icons/design/write.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/design/write.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/design/write.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/dotted.gif b/net452/SiteServer.Web/SiteServer/assets/icons/dotted.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/dotted.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/dotted.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/down.gif b/net452/SiteServer.Web/SiteServer/assets/icons/down.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/down.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/down.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/down2.gif b/net452/SiteServer.Web/SiteServer/assets/icons/down2.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/down2.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/down2.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/download.gif b/net452/SiteServer.Web/SiteServer/assets/icons/download.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/download.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/download.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/dropdown.gif b/net452/SiteServer.Web/SiteServer/assets/icons/dropdown.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/dropdown.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/dropdown.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/edit.gif b/net452/SiteServer.Web/SiteServer/assets/icons/edit.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/edit.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/edit.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/editlist.gif b/net452/SiteServer.Web/SiteServer/assets/icons/editlist.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/editlist.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/editlist.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/0.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/0.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/0.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/0.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/1.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/1.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/1.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/1.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/10.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/10.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/10.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/10.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/11.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/11.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/11.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/11.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/12.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/12.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/12.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/12.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/13.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/13.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/13.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/13.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/14.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/14.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/14.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/14.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/15.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/15.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/15.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/15.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/16.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/16.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/16.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/16.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/17.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/17.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/17.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/17.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/18.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/18.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/18.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/18.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/19.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/19.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/19.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/19.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/2.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/2.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/2.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/2.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/20.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/20.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/20.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/20.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/21.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/21.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/21.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/21.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/22.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/22.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/22.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/22.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/23.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/23.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/23.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/23.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/24.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/24.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/24.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/24.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/25.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/25.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/25.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/25.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/26.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/26.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/26.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/26.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/27.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/27.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/27.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/27.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/28.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/28.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/28.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/28.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/29.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/29.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/29.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/29.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/3.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/3.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/3.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/3.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/30.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/30.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/30.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/30.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/31.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/31.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/31.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/31.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/32.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/32.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/32.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/32.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/33.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/33.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/33.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/33.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/34.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/34.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/34.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/34.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/35.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/35.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/35.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/35.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/36.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/36.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/36.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/36.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/37.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/37.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/37.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/37.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/38.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/38.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/38.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/38.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/39.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/39.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/39.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/39.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/4.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/4.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/4.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/4.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/40.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/40.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/40.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/40.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/41.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/41.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/41.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/41.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/42.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/42.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/42.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/42.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/43.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/43.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/43.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/43.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/44.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/44.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/44.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/44.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/45.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/45.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/45.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/45.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/46.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/46.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/46.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/46.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/47.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/47.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/47.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/47.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/48.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/48.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/48.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/48.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/49.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/49.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/49.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/49.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/5.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/5.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/5.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/5.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/50.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/50.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/50.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/50.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/51.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/51.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/51.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/51.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/52.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/52.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/52.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/52.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/53.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/53.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/53.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/53.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/54.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/54.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/54.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/54.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/55.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/55.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/55.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/55.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/56.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/56.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/56.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/56.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/57.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/57.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/57.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/57.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/58.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/58.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/58.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/58.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/59.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/59.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/59.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/59.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/6.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/6.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/6.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/6.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/60.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/60.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/60.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/60.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/61.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/61.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/61.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/61.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/62.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/62.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/62.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/62.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/63.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/63.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/63.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/63.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/7.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/7.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/7.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/7.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/8.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/8.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/8.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/8.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/emotion/9.gif b/net452/SiteServer.Web/SiteServer/assets/icons/emotion/9.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/emotion/9.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/emotion/9.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/empty.gif b/net452/SiteServer.Web/SiteServer/assets/icons/empty.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/empty.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/empty.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/error.gif b/net452/SiteServer.Web/SiteServer/assets/icons/error.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/error.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/error.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/error.jpg b/net452/SiteServer.Web/SiteServer/assets/icons/error.jpg similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/error.jpg rename to net452/SiteServer.Web/SiteServer/assets/icons/error.jpg diff --git a/SiteServer.Web/SiteServer/assets/icons/false.gif b/net452/SiteServer.Web/SiteServer/assets/icons/false.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/false.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/false.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/favicon.png b/net452/SiteServer.Web/SiteServer/assets/icons/favicon.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/favicon.png rename to net452/SiteServer.Web/SiteServer/assets/icons/favicon.png diff --git a/SiteServer.Web/SiteServer/assets/icons/favorite.gif b/net452/SiteServer.Web/SiteServer/assets/icons/favorite.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/favorite.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/favorite.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.ascx.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.ascx.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.ascx.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.ascx.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.asf.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.asf.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.asf.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.asf.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.asp.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.asp.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.asp.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.asp.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.aspx.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.aspx.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.aspx.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.aspx.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.asx.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.asx.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.asx.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.asx.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.avi.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.avi.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.avi.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.avi.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.bmp.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.bmp.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.bmp.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.bmp.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.css.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.css.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.css.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.css.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.directory.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.directory.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.directory.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.directory.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.dll.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.dll.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.dll.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.dll.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.doc.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.doc.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.doc.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.doc.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.gif.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.gif.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.gif.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.gif.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.htm.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.htm.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.htm.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.htm.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.html.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.html.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.html.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.html.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.image.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.image.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.image.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.image.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.jpeg.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.jpeg.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.jpeg.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.jpeg.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.jpg.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.jpg.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.jpg.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.jpg.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.js.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.js.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.js.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.js.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.jsp.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.jsp.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.jsp.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.jsp.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.mdb.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.mdb.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.mdb.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.mdb.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.mid.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.mid.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.mid.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.mid.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.midi.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.midi.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.midi.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.midi.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.mp3.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.mp3.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.mp3.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.mp3.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.mpeg.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.mpeg.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.mpeg.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.mpeg.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.mpg.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.mpg.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.mpg.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.mpg.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.pdf.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.pdf.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.pdf.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.pdf.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.php.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.php.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.php.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.php.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.png.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.png.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.png.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.png.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.ppt.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.ppt.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.ppt.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.ppt.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.rar.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.rar.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.rar.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.rar.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.rm.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.rm.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.rm.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.rm.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.shtml.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.shtml.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.shtml.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.shtml.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.swf.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.swf.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.swf.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.swf.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.txt.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.txt.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.txt.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.txt.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.unknown.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.unknown.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.unknown.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.unknown.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.video.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.video.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.video.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.video.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.wav.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.wav.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.wav.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.wav.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.wma.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.wma.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.wma.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.wma.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.xls.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.xls.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.xls.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.xls.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.xml.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.xml.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.xml.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.xml.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/large.zip.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.zip.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/large.zip.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/large.zip.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/document.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/document.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/document.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/document.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/folder.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/folder.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/folder.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/folder.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/folder_empty.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/folder_empty.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/folder_empty.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/folder_empty.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/folder_minus.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/folder_minus.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/folder_minus.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/folder_minus.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/folder_plus.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/folder_plus.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/folder_plus.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/folder_plus.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/picture.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/picture.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/picture.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/Icon/picture.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/back.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/back.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/back.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/back.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/backfolder.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/backfolder.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/backfolder.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/backfolder.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/background.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/background.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/background.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/background.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/create.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/create.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/create.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/create.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/createDirectory.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/createDirectory.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/createDirectory.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/createDirectory.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/delete.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/delete.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/delete.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/delete.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/file.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/file.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/file.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/file.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/folder.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/folder.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/folder.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/folder.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/folder_minus.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/folder_minus.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/folder_minus.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/folder_minus.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/folder_plus.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/folder_plus.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/folder_plus.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/folder_plus.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/graphics.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/graphics.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/graphics.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/graphics.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/reload.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/reload.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/reload.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/reload.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/rename.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/rename.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/rename.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/rename.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/renameon.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/renameon.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/renameon.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/renameon.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/root.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/root.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/root.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/root.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/selector.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/selector.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/selector.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/selector.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/seperator.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/seperator.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/seperator.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/seperator.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/sortasc.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/sortasc.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/sortasc.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/sortasc.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/toLeft.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/toLeft.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/toLeft.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/toLeft.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/toRight.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/toRight.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/toRight.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/toRight.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/topfolder.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/topfolder.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/topfolder.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/topfolder.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/management/up.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/up.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/management/up.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/management/up.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.ascx.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.ascx.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.ascx.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.ascx.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.asf.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.asf.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.asf.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.asf.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.asp.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.asp.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.asp.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.asp.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.aspx.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.aspx.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.aspx.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.aspx.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.asx.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.asx.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.asx.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.asx.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.avi.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.avi.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.avi.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.avi.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.bmp.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.bmp.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.bmp.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.bmp.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.css.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.css.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.css.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.css.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.directory.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.directory.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.directory.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.directory.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.dll.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.dll.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.dll.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.dll.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.doc.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.doc.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.doc.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.doc.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.gif.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.gif.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.gif.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.gif.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.htm.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.htm.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.htm.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.htm.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.html.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.html.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.html.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.html.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.image.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.image.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.image.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.image.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.jpeg.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.jpeg.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.jpeg.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.jpeg.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.jpg.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.jpg.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.jpg.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.jpg.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.js.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.js.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.js.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.js.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.jsp.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.jsp.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.jsp.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.jsp.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.mdb.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.mdb.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.mdb.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.mdb.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.mid.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.mid.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.mid.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.mid.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.midi.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.midi.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.midi.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.midi.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.mp3.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.mp3.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.mp3.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.mp3.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.mpeg.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.mpeg.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.mpeg.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.mpeg.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.mpg.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.mpg.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.mpg.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.mpg.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.pdf.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.pdf.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.pdf.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.pdf.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.php.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.php.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.php.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.php.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.png.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.png.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.png.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.png.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.ppt.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.ppt.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.ppt.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.ppt.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.rar.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.rar.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.rar.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.rar.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.rm.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.rm.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.rm.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.rm.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.shtml.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.shtml.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.shtml.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.shtml.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.swf.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.swf.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.swf.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.swf.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.txt.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.txt.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.txt.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.txt.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.unknown.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.unknown.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.unknown.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.unknown.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.video.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.video.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.video.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.video.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.wav.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.wav.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.wav.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.wav.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.wma.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.wma.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.wma.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.wma.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.xls.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.xls.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.xls.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.xls.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.xml.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.xml.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.xml.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.xml.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/filesystem/small.zip.gif b/net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.zip.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/filesystem/small.zip.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/filesystem/small.zip.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/globe.gif b/net452/SiteServer.Web/SiteServer/assets/icons/globe.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/globe.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/globe.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/globeOver.gif b/net452/SiteServer.Web/SiteServer/assets/icons/globeOver.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/globeOver.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/globeOver.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/help.gif b/net452/SiteServer.Web/SiteServer/assets/icons/help.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/help.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/help.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/hot.gif b/net452/SiteServer.Web/SiteServer/assets/icons/hot.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/hot.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/hot.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/ico_help.gif b/net452/SiteServer.Web/SiteServer/assets/icons/ico_help.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/ico_help.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/ico_help.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/img.gif b/net452/SiteServer.Web/SiteServer/assets/icons/img.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/img.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/img.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/lightbox.gif b/net452/SiteServer.Web/SiteServer/assets/icons/lightbox.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/lightbox.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/lightbox.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/loading.gif b/net452/SiteServer.Web/SiteServer/assets/icons/loading.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/loading.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/loading.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/logo.png b/net452/SiteServer.Web/SiteServer/assets/icons/logo.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/logo.png rename to net452/SiteServer.Web/SiteServer/assets/icons/logo.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/account.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/account.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/account.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/account.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/administrator.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/administrator.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/administrator.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/administrator.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/advImage.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/advImage.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/advImage.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/advImage.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/advertisement.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/advertisement.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/advertisement.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/advertisement.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/archive.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/archive.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/archive.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/archive.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/authentication.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/authentication.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/authentication.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/authentication.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/bShare.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/bShare.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/bShare.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/bShare.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/backup.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/backup.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/backup.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/backup.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/blog.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/blog.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/blog.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/blog.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/chart.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/chart.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/chart.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/chart.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/check.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/check.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/check.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/check.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/check.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/check.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/check.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/check.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/comment.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/comment.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/comment.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/comment.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/comment.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/comment.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/comment.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/comment.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/configuration.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/configuration.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/configuration.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/configuration.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/configuration.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/configuration.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/configuration.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/configuration.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/content.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/content.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/content.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/content.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/content.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/content.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/content.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/content.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/contentchannel.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/contentchannel.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/contentchannel.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/contentchannel.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/contentchannel.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/contentchannel.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/contentchannel.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/contentchannel.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/contents.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/contents.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/contents.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/contents.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/count.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/count.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/count.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/count.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/create.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/create.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/create.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/create.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/database.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/database.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/database.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/database.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/email.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/email.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/email.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/email.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/email.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/email.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/email.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/email.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/evaluation.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/evaluation.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/evaluation.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/evaluation.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/file.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/file.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/file.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/file.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/folder.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/folder.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/folder.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/folder.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/form.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/form.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/form.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/form.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/forum.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/forum.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/forum.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/forum.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/function.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/function.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/function.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/function.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/function.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/function.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/function.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/function.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/gather.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/gather.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/gather.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/gather.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/group.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/group.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/group.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/group.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/home.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/home.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/home.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/home.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/include.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/include.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/include.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/include.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/innerlink.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/innerlink.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/innerlink.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/innerlink.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/input.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/input.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/input.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/input.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/integration.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/integration.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/integration.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/integration.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/ipush.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/ipush.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/ipush.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/ipush.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/item.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/item.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/item.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/item.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/item.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/item.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/item.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/item.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/itemContainer.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/itemContainer.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/itemContainer.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/itemContainer.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/itemContainer.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/itemContainer.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/itemContainer.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/itemContainer.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/job.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/job.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/job.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/job.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/keyword.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/keyword.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/keyword.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/keyword.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/library.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/library.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/library.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/library.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/library.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/library.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/library.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/library.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/log.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/log.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/log.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/log.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/machine.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/machine.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/machine.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/machine.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/menu.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/menu.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/menu.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/menu.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/module.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/module.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/module.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/module.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/money.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/money.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/money.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/money.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/myweb.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/myweb.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/myweb.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/myweb.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/orgn.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/orgn.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/orgn.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/orgn.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/payment.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/payment.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/payment.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/payment.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/photo.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/photo.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/photo.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/photo.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/plugin.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/plugin.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/plugin.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/plugin.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/preview.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/preview.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/preview.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/preview.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/publish.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/publish.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/publish.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/publish.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/relatedField.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/relatedField.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/relatedField.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/relatedField.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/replace.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/replace.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/replace.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/replace.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/restriction.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/restriction.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/restriction.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/restriction.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/search.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/search.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/search.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/search.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/searchword.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/searchword.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/searchword.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/searchword.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/seo.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/seo.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/seo.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/seo.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/service.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/service.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/service.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/service.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/shortcut.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/shortcut.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/shortcut.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/shortcut.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/signin.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/signin.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/signin.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/signin.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/site.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/site.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/site.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/site.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/siteserver.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/siteserver.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/siteserver.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/siteserver.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/sms.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/sms.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/sms.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/sms.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/special.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/special.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/special.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/special.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/storage.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/storage.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/storage.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/storage.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/subscribe.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/subscribe.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/subscribe.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/subscribe.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/survey.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/survey.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/survey.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/survey.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/tagStyle.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/tagStyle.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/tagStyle.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/tagStyle.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/tagStyle.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/tagStyle.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/tagStyle.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/tagStyle.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/tags.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/tags.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/tags.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/tags.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/task.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/task.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/task.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/task.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/template.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/template.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/template.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/template.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/templateManage.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/templateManage.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/templateManage.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/templateManage.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/templateMatch.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/templateMatch.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/templateMatch.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/templateMatch.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/thread.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/thread.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/thread.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/thread.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/topic.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/topic.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/topic.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/topic.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/translate.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/translate.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/translate.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/translate.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/translate.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/translate.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/translate.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/translate.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/trash.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/trash.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/trash.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/trash.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/trial.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/trial.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/trial.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/trial.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/user.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/user.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/user.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/user.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/userDisk.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/userDisk.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/userDisk.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/userDisk.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/utils.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/utils.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/utils.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/utils.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/vote.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/vote.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/vote.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/vote.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/vs.jpg b/net452/SiteServer.Web/SiteServer/assets/icons/menu/vs.jpg similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/vs.jpg rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/vs.jpg diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/weixin.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/weixin.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/weixin.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/weixin.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/weixinMenu.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/weixinMenu.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/weixinMenu.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/weixinMenu.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/word.gif b/net452/SiteServer.Web/SiteServer/assets/icons/menu/word.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/word.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/word.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/wx_chat.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/wx_chat.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/wx_chat.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/wx_chat.png diff --git a/SiteServer.Web/SiteServer/assets/icons/menu/wx_list.png b/net452/SiteServer.Web/SiteServer/assets/icons/menu/wx_list.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/menu/wx_list.png rename to net452/SiteServer.Web/SiteServer/assets/icons/menu/wx_list.png diff --git a/SiteServer.Web/SiteServer/assets/icons/message.gif b/net452/SiteServer.Web/SiteServer/assets/icons/message.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/message.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/message.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/messageEmpty.gif b/net452/SiteServer.Web/SiteServer/assets/icons/messageEmpty.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/messageEmpty.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/messageEmpty.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/module/blog.gif b/net452/SiteServer.Web/SiteServer/assets/icons/module/blog.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/module/blog.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/module/blog.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/module/count.gif b/net452/SiteServer.Web/SiteServer/assets/icons/module/count.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/module/count.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/module/count.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/module/freshusers.gif b/net452/SiteServer.Web/SiteServer/assets/icons/module/freshusers.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/module/freshusers.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/module/freshusers.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/module/friends.gif b/net452/SiteServer.Web/SiteServer/assets/icons/module/friends.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/module/friends.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/module/friends.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/module/ico_close.gif b/net452/SiteServer.Web/SiteServer/assets/icons/module/ico_close.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/module/ico_close.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/module/ico_close.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/module/myweb.gif b/net452/SiteServer.Web/SiteServer/assets/icons/module/myweb.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/module/myweb.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/module/myweb.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/module/notes.gif b/net452/SiteServer.Web/SiteServer/assets/icons/module/notes.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/module/notes.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/module/notes.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/module/photo.gif b/net452/SiteServer.Web/SiteServer/assets/icons/module/photo.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/module/photo.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/module/photo.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/module/rss.gif b/net452/SiteServer.Web/SiteServer/assets/icons/module/rss.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/module/rss.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/module/rss.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/module/tags.gif b/net452/SiteServer.Web/SiteServer/assets/icons/module/tags.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/module/tags.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/module/tags.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/module/undefined.gif b/net452/SiteServer.Web/SiteServer/assets/icons/module/undefined.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/module/undefined.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/module/undefined.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/module/userinfo.gif b/net452/SiteServer.Web/SiteServer/assets/icons/module/userinfo.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/module/userinfo.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/module/userinfo.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/module/video.gif b/net452/SiteServer.Web/SiteServer/assets/icons/module/video.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/module/video.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/module/video.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/module/videorecommend.gif b/net452/SiteServer.Web/SiteServer/assets/icons/module/videorecommend.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/module/videorecommend.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/module/videorecommend.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/module/visitors.gif b/net452/SiteServer.Web/SiteServer/assets/icons/module/visitors.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/module/visitors.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/module/visitors.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/module/words.gif b/net452/SiteServer.Web/SiteServer/assets/icons/module/words.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/module/words.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/module/words.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/newwindow.gif b/net452/SiteServer.Web/SiteServer/assets/icons/newwindow.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/newwindow.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/newwindow.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/ok.gif b/net452/SiteServer.Web/SiteServer/assets/icons/ok.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/ok.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/ok.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/open.gif b/net452/SiteServer.Web/SiteServer/assets/icons/open.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/open.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/open.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/add_note.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/add_note.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/add_note.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/add_note.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_more_left_out.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_more_left_out.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_more_left_out.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_more_left_out.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_more_right_out.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_more_right_out.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_more_right_out.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_more_right_out.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_next_out.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_next_out.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_next_out.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_next_out.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_next_over.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_next_over.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_next_over.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_next_over.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_prev_out.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_prev_out.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_prev_out.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_prev_out.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_prev_over.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_prev_over.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_prev_over.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/context_arrow_prev_over.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/context_closed.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/context_closed.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/context_closed.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/context_closed.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/context_crap.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/context_crap.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/context_crap.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/context_crap.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/context_open.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/context_open.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/context_open.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/context_open.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/context_view_page_out.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/context_view_page_out.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/context_view_page_out.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/context_view_page_out.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/date_bg.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/date_bg.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/date_bg.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/date_bg.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/delete_grey.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/delete_grey.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/delete_grey.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/delete_grey.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/placeholder_first_photo.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/placeholder_first_photo.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/placeholder_first_photo.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/placeholder_first_photo.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/placeholder_last_photo.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/placeholder_last_photo.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/placeholder_last_photo.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/placeholder_last_photo.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/print.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/print.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/print.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/print.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/rotate.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/rotate.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/rotate.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/rotate.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/rotateLeft.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/rotateLeft.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/rotateLeft.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/rotateLeft.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/rotateRight.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/rotateRight.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/rotateRight.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/rotateRight.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/rotate_placeholder.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/rotate_placeholder.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/rotate_placeholder.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/rotate_placeholder.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/send_to_group.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/send_to_group.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/send_to_group.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/send_to_group.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/sets.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/sets.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/sets.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/sets.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/spaceball.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/spaceball.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/spaceball.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/spaceball.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/spaceout.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/spaceout.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/spaceout.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/spaceout.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/tc_white_bl.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/tc_white_bl.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/tc_white_bl.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/tc_white_bl.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/tc_white_br.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/tc_white_br.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/tc_white_br.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/tc_white_br.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/tc_white_tl.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/tc_white_tl.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/tc_white_tl.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/tc_white_tl.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/tc_white_tr.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/tc_white_tr.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/tc_white_tr.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/tc_white_tr.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/tc_yellow_bl.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/tc_yellow_bl.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/tc_yellow_bl.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/tc_yellow_bl.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/tc_yellow_br.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/tc_yellow_br.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/tc_yellow_br.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/tc_yellow_br.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/tc_yellow_tl.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/tc_yellow_tl.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/tc_yellow_tl.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/tc_yellow_tl.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/tc_yellow_tr.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/tc_yellow_tr.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/tc_yellow_tr.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/tc_yellow_tr.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/photo/zoom.gif b/net452/SiteServer.Web/SiteServer/assets/icons/photo/zoom.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/photo/zoom.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/photo/zoom.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/player.gif b/net452/SiteServer.Web/SiteServer/assets/icons/player.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/player.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/player.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/preview.gif b/net452/SiteServer.Web/SiteServer/assets/icons/preview.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/preview.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/preview.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/previewpane.gif b/net452/SiteServer.Web/SiteServer/assets/icons/previewpane.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/previewpane.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/previewpane.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/process.gif b/net452/SiteServer.Web/SiteServer/assets/icons/process.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/process.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/process.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/quote_e.gif b/net452/SiteServer.Web/SiteServer/assets/icons/quote_e.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/quote_e.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/quote_e.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/quote_s.gif b/net452/SiteServer.Web/SiteServer/assets/icons/quote_s.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/quote_s.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/quote_s.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/ref.gif b/net452/SiteServer.Web/SiteServer/assets/icons/ref.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/ref.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/ref.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/replace.gif b/net452/SiteServer.Web/SiteServer/assets/icons/replace.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/replace.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/replace.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/return.gif b/net452/SiteServer.Web/SiteServer/assets/icons/return.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/return.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/return.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/right.gif b/net452/SiteServer.Web/SiteServer/assets/icons/right.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/right.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/right.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/rss.gif b/net452/SiteServer.Web/SiteServer/assets/icons/rss.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/rss.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/rss.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/s.gif b/net452/SiteServer.Web/SiteServer/assets/icons/s.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/s.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/s.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/save.gif b/net452/SiteServer.Web/SiteServer/assets/icons/save.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/save.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/save.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/savedraft.gif b/net452/SiteServer.Web/SiteServer/assets/icons/savedraft.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/savedraft.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/savedraft.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/savedraft_disabled.gif b/net452/SiteServer.Web/SiteServer/assets/icons/savedraft_disabled.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/savedraft_disabled.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/savedraft_disabled.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/search.gif b/net452/SiteServer.Web/SiteServer/assets/icons/search.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/search.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/search.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/security/friends.gif b/net452/SiteServer.Web/SiteServer/assets/icons/security/friends.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/security/friends.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/security/friends.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/security/private.gif b/net452/SiteServer.Web/SiteServer/assets/icons/security/private.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/security/private.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/security/private.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/security/public.gif b/net452/SiteServer.Web/SiteServer/assets/icons/security/public.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/security/public.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/security/public.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/sets.gif b/net452/SiteServer.Web/SiteServer/assets/icons/sets.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/sets.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/sets.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/showMenu.gif b/net452/SiteServer.Web/SiteServer/assets/icons/showMenu.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/showMenu.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/showMenu.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/spaceball.gif b/net452/SiteServer.Web/SiteServer/assets/icons/spaceball.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/spaceball.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/spaceball.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/standard_msg_error.gif b/net452/SiteServer.Web/SiteServer/assets/icons/standard_msg_error.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/standard_msg_error.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/standard_msg_error.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/standard_msg_ok.gif b/net452/SiteServer.Web/SiteServer/assets/icons/standard_msg_ok.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/standard_msg_ok.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/standard_msg_ok.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/standard_msg_warn.gif b/net452/SiteServer.Web/SiteServer/assets/icons/standard_msg_warn.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/standard_msg_warn.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/standard_msg_warn.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tabstrip/hover_tab_bg.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/hover_tab_bg.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tabstrip/hover_tab_bg.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/hover_tab_bg.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tabstrip/hover_tab_left_icon.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/hover_tab_left_icon.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tabstrip/hover_tab_left_icon.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/hover_tab_left_icon.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tabstrip/hover_tab_right_icon.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/hover_tab_right_icon.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tabstrip/hover_tab_right_icon.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/hover_tab_right_icon.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tabstrip/selected_tab_bg.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/selected_tab_bg.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tabstrip/selected_tab_bg.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/selected_tab_bg.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tabstrip/selected_tab_left_icon.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/selected_tab_left_icon.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tabstrip/selected_tab_left_icon.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/selected_tab_left_icon.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tabstrip/selected_tab_right_icon.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/selected_tab_right_icon.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tabstrip/selected_tab_right_icon.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/selected_tab_right_icon.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tabstrip/tab.active.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/tab.active.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tabstrip/tab.active.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/tab.active.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tabstrip/tab_bg.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/tab_bg.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tabstrip/tab_bg.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/tab_bg.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tabstrip/tab_left_icon.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/tab_left_icon.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tabstrip/tab_left_icon.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/tab_left_icon.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tabstrip/tab_right_icon.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/tab_right_icon.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tabstrip/tab_right_icon.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tabstrip/tab_right_icon.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tags.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tags.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tags.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tags.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tags.png b/net452/SiteServer.Web/SiteServer/assets/icons/tags.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tags.png rename to net452/SiteServer.Web/SiteServer/assets/icons/tags.png diff --git a/SiteServer.Web/SiteServer/assets/icons/teleplay.gif b/net452/SiteServer.Web/SiteServer/assets/icons/teleplay.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/teleplay.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/teleplay.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tick.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tick.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tick.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tick.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tick_disabled.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tick_disabled.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tick_disabled.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tick_disabled.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tips.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tips.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tips.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tips.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/toggleDown.gif b/net452/SiteServer.Web/SiteServer/assets/icons/toggleDown.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/toggleDown.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/toggleDown.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/toggleUp.gif b/net452/SiteServer.Web/SiteServer/assets/icons/toggleUp.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/toggleUp.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/toggleUp.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tracker.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tracker.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tracker.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tracker.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/brand.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/brand.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/brand.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/brand.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/category.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/category.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/category.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/category.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/content.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/content.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/content.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/content.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/content.png b/net452/SiteServer.Web/SiteServer/assets/icons/tree/content.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/content.png rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/content.png diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/department.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/department.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/department.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/department.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/dot.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/dot.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/dot.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/dot.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/empty.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/empty.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/empty.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/empty.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/feedback.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/feedback.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/feedback.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/feedback.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/folder.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/folder.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/folder.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/folder.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/goods.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/goods.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/goods.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/goods.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/goods.png b/net452/SiteServer.Web/SiteServer/assets/icons/tree/goods.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/goods.png rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/goods.png diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/govInteract.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/govInteract.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/govInteract.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/govInteract.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/govpublic.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/govpublic.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/govpublic.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/govpublic.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/image.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/image.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/image.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/image.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/itemContainer.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/itemContainer.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/itemContainer.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/itemContainer.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/job.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/job.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/job.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/job.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/minus.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/minus.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/minus.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/minus.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/minus.png b/net452/SiteServer.Web/SiteServer/assets/icons/tree/minus.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/minus.png rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/minus.png diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/open.png b/net452/SiteServer.Web/SiteServer/assets/icons/tree/open.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/open.png rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/open.png diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/openedfolder.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/openedfolder.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/openedfolder.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/openedfolder.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/photo.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/photo.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/photo.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/photo.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/plus.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/plus.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/plus.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/plus.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/plus.png b/net452/SiteServer.Web/SiteServer/assets/icons/tree/plus.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/plus.png rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/plus.png diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/site.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/site.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/site.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/site.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/siteHQ.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/siteHQ.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/siteHQ.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/siteHQ.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/subsite2.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/subsite2.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/subsite2.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/subsite2.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/subsite3.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/subsite3.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/subsite3.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/subsite3.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/subsite4.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/subsite4.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/subsite4.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/subsite4.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/subsite5.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/subsite5.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/subsite5.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/subsite5.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/subsite6.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/subsite6.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/subsite6.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/subsite6.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/subsite7.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/subsite7.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/subsite7.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/subsite7.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/subsite8.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/subsite8.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/subsite8.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/subsite8.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/subsite9.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/subsite9.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/subsite9.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/subsite9.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/teleplay.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/teleplay.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/teleplay.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/teleplay.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/tree_bottom.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/tree_bottom.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/tree_bottom.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/tree_bottom.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/tree_empty.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/tree_empty.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/tree_empty.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/tree_empty.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/tree_line.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/tree_line.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/tree_line.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/tree_line.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/tree_middle.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/tree_middle.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/tree_middle.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/tree_middle.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/tree_minusbottom.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/tree_minusbottom.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/tree_minusbottom.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/tree_minusbottom.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/tree_minusmiddle.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/tree_minusmiddle.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/tree_minusmiddle.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/tree_minusmiddle.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/tree_plusbottom.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/tree_plusbottom.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/tree_plusbottom.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/tree_plusbottom.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/tree_plusmiddle.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/tree_plusmiddle.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/tree_plusmiddle.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/tree_plusmiddle.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/tree/vote.gif b/net452/SiteServer.Web/SiteServer/assets/icons/tree/vote.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/tree/vote.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/tree/vote.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/true.gif b/net452/SiteServer.Web/SiteServer/assets/icons/true.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/true.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/true.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/up.gif b/net452/SiteServer.Web/SiteServer/assets/icons/up.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/up.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/up.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/up2.gif b/net452/SiteServer.Web/SiteServer/assets/icons/up2.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/up2.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/up2.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/upfolder.gif b/net452/SiteServer.Web/SiteServer/assets/icons/upfolder.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/upfolder.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/upfolder.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/url.gif b/net452/SiteServer.Web/SiteServer/assets/icons/url.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/url.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/url.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/user/star_level1.gif b/net452/SiteServer.Web/SiteServer/assets/icons/user/star_level1.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/user/star_level1.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/user/star_level1.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/user/star_level2.gif b/net452/SiteServer.Web/SiteServer/assets/icons/user/star_level2.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/user/star_level2.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/user/star_level2.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/user/star_level3.gif b/net452/SiteServer.Web/SiteServer/assets/icons/user/star_level3.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/user/star_level3.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/user/star_level3.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/user/userImage.gif b/net452/SiteServer.Web/SiteServer/assets/icons/user/userImage.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/user/userImage.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/user/userImage.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/user/userImage.jpg b/net452/SiteServer.Web/SiteServer/assets/icons/user/userImage.jpg similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/user/userImage.jpg rename to net452/SiteServer.Web/SiteServer/assets/icons/user/userImage.jpg diff --git a/SiteServer.Web/SiteServer/assets/icons/user/usericon.gif b/net452/SiteServer.Web/SiteServer/assets/icons/user/usericon.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/user/usericon.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/user/usericon.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/view.png b/net452/SiteServer.Web/SiteServer/assets/icons/view.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/view.png rename to net452/SiteServer.Web/SiteServer/assets/icons/view.png diff --git a/SiteServer.Web/SiteServer/assets/icons/waiting.gif b/net452/SiteServer.Web/SiteServer/assets/icons/waiting.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/waiting.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/waiting.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/warn.jpg b/net452/SiteServer.Web/SiteServer/assets/icons/warn.jpg similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/warn.jpg rename to net452/SiteServer.Web/SiteServer/assets/icons/warn.jpg diff --git a/SiteServer.Web/SiteServer/assets/icons/write.gif b/net452/SiteServer.Web/SiteServer/assets/icons/write.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/write.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/write.gif diff --git a/SiteServer.Web/SiteServer/assets/icons/wrong.gif b/net452/SiteServer.Web/SiteServer/assets/icons/wrong.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/icons/wrong.gif rename to net452/SiteServer.Web/SiteServer/assets/icons/wrong.gif diff --git a/net452/SiteServer.Web/SiteServer/assets/images/connect.png b/net452/SiteServer.Web/SiteServer/assets/images/connect.png new file mode 100644 index 000000000..3b88275dc Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/images/connect.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/images/default_avatar.png b/net452/SiteServer.Web/SiteServer/assets/images/default_avatar.png new file mode 100644 index 000000000..5caa1fc98 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/images/default_avatar.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/images/favicon.png b/net452/SiteServer.Web/SiteServer/assets/images/favicon.png new file mode 100644 index 000000000..df48f0d22 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/images/favicon.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/images/loading.gif b/net452/SiteServer.Web/SiteServer/assets/images/loading.gif new file mode 100644 index 000000000..db3a483e4 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/images/loading.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/jquery/jquery-1.9.1.min.js b/net452/SiteServer.Web/SiteServer/assets/jquery/jquery-1.9.1.min.js new file mode 100644 index 000000000..006e95310 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/jquery/jquery-1.9.1.min.js @@ -0,0 +1,5 @@ +/*! jQuery v1.9.1 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license +//@ sourceMappingURL=jquery.min.map +*/(function(e,t){var n,r,i=typeof t,o=e.document,a=e.location,s=e.jQuery,u=e.$,l={},c=[],p="1.9.1",f=c.concat,d=c.push,h=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,b=function(e,t){return new b.fn.init(e,t,r)},x=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^[\],:{}\s]*$/,E=/(?:^|:|,)(?:\s*\[)+/g,S=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,A=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,j=/^-ms-/,D=/-([\da-z])/gi,L=function(e,t){return t.toUpperCase()},H=function(e){(o.addEventListener||"load"===e.type||"complete"===o.readyState)&&(q(),b.ready())},q=function(){o.addEventListener?(o.removeEventListener("DOMContentLoaded",H,!1),e.removeEventListener("load",H,!1)):(o.detachEvent("onreadystatechange",H),e.detachEvent("onload",H))};b.fn=b.prototype={jquery:p,constructor:b,init:function(e,n,r){var i,a;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof b?n[0]:n,b.merge(this,b.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:o,!0)),C.test(i[1])&&b.isPlainObject(n))for(i in n)b.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(a=o.getElementById(i[2]),a&&a.parentNode){if(a.id!==i[2])return r.find(e);this.length=1,this[0]=a}return this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):b.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),b.makeArray(e,this))},selector:"",length:0,size:function(){return this.length},toArray:function(){return h.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=b.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return b.each(this,e,t)},ready:function(e){return b.ready.promise().done(e),this},slice:function(){return this.pushStack(h.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(b.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:d,sort:[].sort,splice:[].splice},b.fn.init.prototype=b.fn,b.extend=b.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},u=1,l=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},u=2),"object"==typeof s||b.isFunction(s)||(s={}),l===u&&(s=this,--u);l>u;u++)if(null!=(o=arguments[u]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(b.isPlainObject(r)||(n=b.isArray(r)))?(n?(n=!1,a=e&&b.isArray(e)?e:[]):a=e&&b.isPlainObject(e)?e:{},s[i]=b.extend(c,a,r)):r!==t&&(s[i]=r));return s},b.extend({noConflict:function(t){return e.$===b&&(e.$=u),t&&e.jQuery===b&&(e.jQuery=s),b},isReady:!1,readyWait:1,holdReady:function(e){e?b.readyWait++:b.ready(!0)},ready:function(e){if(e===!0?!--b.readyWait:!b.isReady){if(!o.body)return setTimeout(b.ready);b.isReady=!0,e!==!0&&--b.readyWait>0||(n.resolveWith(o,[b]),b.fn.trigger&&b(o).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===b.type(e)},isArray:Array.isArray||function(e){return"array"===b.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if(!e||"object"!==b.type(e)||e.nodeType||b.isWindow(e))return!1;try{if(e.constructor&&!y.call(e,"constructor")&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||y.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=b.buildFragment([e],t,i),i&&b(i).remove(),b.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=b.trim(n),n&&k.test(n.replace(S,"@").replace(A,"]").replace(E,"")))?Function("return "+n)():(b.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||b.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&b.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(j,"ms-").replace(D,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:v&&!v.call("\ufeff\u00a0")?function(e){return null==e?"":v.call(e)}:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?b.merge(n,"string"==typeof e?[e]:e):d.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(g)return g.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return f.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),b.isFunction(e)?(r=h.call(arguments,2),i=function(){return e.apply(n||this,r.concat(h.call(arguments)))},i.guid=e.guid=e.guid||b.guid++,i):t},access:function(e,n,r,i,o,a,s){var u=0,l=e.length,c=null==r;if("object"===b.type(r)){o=!0;for(u in r)b.access(e,n,u,r[u],!0,a,s)}else if(i!==t&&(o=!0,b.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(b(e),n)})),n))for(;l>u;u++)n(e[u],r,s?i:i.call(e[u],u,n(e[u],r)));return o?e:c?n.call(e):l?n(e[0],r):a},now:function(){return(new Date).getTime()}}),b.ready.promise=function(t){if(!n)if(n=b.Deferred(),"complete"===o.readyState)setTimeout(b.ready);else if(o.addEventListener)o.addEventListener("DOMContentLoaded",H,!1),e.addEventListener("load",H,!1);else{o.attachEvent("onreadystatechange",H),e.attachEvent("onload",H);var r=!1;try{r=null==e.frameElement&&o.documentElement}catch(i){}r&&r.doScroll&&function a(){if(!b.isReady){try{r.doScroll("left")}catch(e){return setTimeout(a,50)}q(),b.ready()}}()}return n.promise(t)},b.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=b.type(e);return b.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=b(o);var _={};function F(e){var t=_[e]={};return b.each(e.match(w)||[],function(e,n){t[n]=!0}),t}b.Callbacks=function(e){e="string"==typeof e?_[e]||F(e):b.extend({},e);var n,r,i,o,a,s,u=[],l=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=u.length,n=!0;u&&o>a;a++)if(u[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,u&&(l?l.length&&c(l.shift()):r?u=[]:p.disable())},p={add:function(){if(u){var t=u.length;(function i(t){b.each(t,function(t,n){var r=b.type(n);"function"===r?e.unique&&p.has(n)||u.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=u.length:r&&(s=t,c(r))}return this},remove:function(){return u&&b.each(arguments,function(e,t){var r;while((r=b.inArray(t,u,r))>-1)u.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?b.inArray(e,u)>-1:!(!u||!u.length)},empty:function(){return u=[],this},disable:function(){return u=l=r=t,this},disabled:function(){return!u},lock:function(){return l=t,r||p.disable(),this},locked:function(){return!l},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!u||i&&!l||(n?l.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},b.extend({Deferred:function(e){var t=[["resolve","done",b.Callbacks("once memory"),"resolved"],["reject","fail",b.Callbacks("once memory"),"rejected"],["notify","progress",b.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return b.Deferred(function(n){b.each(t,function(t,o){var a=o[0],s=b.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&b.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?b.extend(e,r):r}},i={};return r.pipe=r.then,b.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=h.call(arguments),r=n.length,i=1!==r||e&&b.isFunction(e.promise)?r:0,o=1===i?e:b.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?h.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,u,l;if(r>1)for(s=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&b.isFunction(n[t].promise)?n[t].promise().done(a(t,l,n)).fail(o.reject).progress(a(t,u,s)):--i;return i||o.resolveWith(l,n),o.promise()}}),b.support=function(){var t,n,r,a,s,u,l,c,p,f,d=o.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="
      a",n=d.getElementsByTagName("*"),r=d.getElementsByTagName("a")[0],!n||!r||!n.length)return{};s=o.createElement("select"),l=s.appendChild(o.createElement("option")),a=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={getSetAttribute:"t"!==d.className,leadingWhitespace:3===d.firstChild.nodeType,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:"/a"===r.getAttribute("href"),opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:!!a.value,optSelected:l.selected,enctype:!!o.createElement("form").enctype,html5Clone:"<:nav>"!==o.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===o.compatMode,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},a.checked=!0,t.noCloneChecked=a.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!l.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}a=o.createElement("input"),a.setAttribute("value",""),t.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),t.radioValue="t"===a.value,a.setAttribute("checked","t"),a.setAttribute("name","t"),u=o.createDocumentFragment(),u.appendChild(a),t.appendChecked=a.checked,t.checkClone=u.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;return d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip,b(function(){var n,r,a,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",u=o.getElementsByTagName("body")[0];u&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",u.appendChild(n).appendChild(d),d.innerHTML="
      t
      ",a=d.getElementsByTagName("td"),a[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===a[0].offsetHeight,a[0].style.display="",a[1].style.display="none",t.reliableHiddenOffsets=p&&0===a[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=4===d.offsetWidth,t.doesNotIncludeMarginInBodyOffset=1!==u.offsetTop,e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(o.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="
      ",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(u.style.zoom=1)),u.removeChild(n),n=d=a=r=null)}),n=s=u=l=r=a=null,t}();var O=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,B=/([A-Z])/g;function P(e,n,r,i){if(b.acceptData(e)){var o,a,s=b.expando,u="string"==typeof n,l=e.nodeType,p=l?b.cache:e,f=l?e[s]:e[s]&&s;if(f&&p[f]&&(i||p[f].data)||!u||r!==t)return f||(l?e[s]=f=c.pop()||b.guid++:f=s),p[f]||(p[f]={},l||(p[f].toJSON=b.noop)),("object"==typeof n||"function"==typeof n)&&(i?p[f]=b.extend(p[f],n):p[f].data=b.extend(p[f].data,n)),o=p[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[b.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[b.camelCase(n)])):a=o,a}}function R(e,t,n){if(b.acceptData(e)){var r,i,o,a=e.nodeType,s=a?b.cache:e,u=a?e[b.expando]:b.expando;if(s[u]){if(t&&(o=n?s[u]:s[u].data)){b.isArray(t)?t=t.concat(b.map(t,b.camelCase)):t in o?t=[t]:(t=b.camelCase(t),t=t in o?[t]:t.split(" "));for(r=0,i=t.length;i>r;r++)delete o[t[r]];if(!(n?$:b.isEmptyObject)(o))return}(n||(delete s[u].data,$(s[u])))&&(a?b.cleanData([e],!0):b.support.deleteExpando||s!=s.window?delete s[u]:s[u]=null)}}}b.extend({cache:{},expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?b.cache[e[b.expando]]:e[b.expando],!!e&&!$(e)},data:function(e,t,n){return P(e,t,n)},removeData:function(e,t){return R(e,t)},_data:function(e,t,n){return P(e,t,n,!0)},_removeData:function(e,t){return R(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&b.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),b.fn.extend({data:function(e,n){var r,i,o=this[0],a=0,s=null;if(e===t){if(this.length&&(s=b.data(o),1===o.nodeType&&!b._data(o,"parsedAttrs"))){for(r=o.attributes;r.length>a;a++)i=r[a].name,i.indexOf("data-")||(i=b.camelCase(i.slice(5)),W(o,i,s[i]));b._data(o,"parsedAttrs",!0)}return s}return"object"==typeof e?this.each(function(){b.data(this,e)}):b.access(this,function(n){return n===t?o?W(o,e,b.data(o,e)):null:(this.each(function(){b.data(this,e,n)}),t)},null,n,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){b.removeData(this,e)})}});function W(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(B,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:O.test(r)?b.parseJSON(r):r}catch(o){}b.data(e,n,r)}else r=t}return r}function $(e){var t;for(t in e)if(("data"!==t||!b.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}b.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=b._data(e,n),r&&(!i||b.isArray(r)?i=b._data(e,n,b.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=b.queue(e,t),r=n.length,i=n.shift(),o=b._queueHooks(e,t),a=function(){b.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),o.cur=i,i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return b._data(e,n)||b._data(e,n,{empty:b.Callbacks("once memory").add(function(){b._removeData(e,t+"queue"),b._removeData(e,n)})})}}),b.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?b.queue(this[0],e):n===t?this:this.each(function(){var t=b.queue(this,e,n);b._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&b.dequeue(this,e)})},dequeue:function(e){return this.each(function(){b.dequeue(this,e)})},delay:function(e,t){return e=b.fx?b.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=b.Deferred(),a=this,s=this.length,u=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=b._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(u));return u(),o.promise(n)}});var I,z,X=/[\t\r\n]/g,U=/\r/g,V=/^(?:input|select|textarea|button|object)$/i,Y=/^(?:a|area)$/i,J=/^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,G=/^(?:checked|selected)$/i,Q=b.support.getSetAttribute,K=b.support.input;b.fn.extend({attr:function(e,t){return b.access(this,b.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){b.removeAttr(this,e)})},prop:function(e,t){return b.access(this,b.prop,e,t,arguments.length>1)},removeProp:function(e){return e=b.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,u="string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=b.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,u=0===arguments.length||"string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?b.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return b.isFunction(e)?this.each(function(n){b(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var o,a=0,s=b(this),u=t,l=e.match(w)||[];while(o=l[a++])u=r?u:!s.hasClass(o),s[u?"addClass":"removeClass"](o)}else(n===i||"boolean"===n)&&(this.className&&b._data(this,"__className__",this.className),this.className=this.className||e===!1?"":b._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(X," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=b.isFunction(e),this.each(function(n){var o,a=b(this);1===this.nodeType&&(o=i?e.call(this,n,a.val()):e,null==o?o="":"number"==typeof o?o+="":b.isArray(o)&&(o=b.map(o,function(e){return null==e?"":e+""})),r=b.valHooks[this.type]||b.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=b.valHooks[o.type]||b.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(U,""):null==n?"":n)}}}),b.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,u=0>i?s:o?i:0;for(;s>u;u++)if(n=r[u],!(!n.selected&&u!==i||(b.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&b.nodeName(n.parentNode,"optgroup"))){if(t=b(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n=b.makeArray(t);return b(e).find("option").each(function(){this.selected=b.inArray(b(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attr:function(e,n,r){var o,a,s,u=e.nodeType;if(e&&3!==u&&8!==u&&2!==u)return typeof e.getAttribute===i?b.prop(e,n,r):(a=1!==u||!b.isXMLDoc(e),a&&(n=n.toLowerCase(),o=b.attrHooks[n]||(J.test(n)?z:I)),r===t?o&&a&&"get"in o&&null!==(s=o.get(e,n))?s:(typeof e.getAttribute!==i&&(s=e.getAttribute(n)),null==s?t:s):null!==r?o&&a&&"set"in o&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r):(b.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=b.propFix[n]||n,J.test(n)?!Q&&G.test(n)?e[b.camelCase("default-"+n)]=e[r]=!1:e[r]=!1:b.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!b.support.radioValue&&"radio"===t&&b.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!b.isXMLDoc(e),a&&(n=b.propFix[n]||n,o=b.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):V.test(e.nodeName)||Y.test(e.nodeName)&&e.href?0:t}}}}),z={get:function(e,n){var r=b.prop(e,n),i="boolean"==typeof r&&e.getAttribute(n),o="boolean"==typeof r?K&&Q?null!=i:G.test(n)?e[b.camelCase("default-"+n)]:!!i:e.getAttributeNode(n);return o&&o.value!==!1?n.toLowerCase():t},set:function(e,t,n){return t===!1?b.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&b.propFix[n]||n,n):e[b.camelCase("default-"+n)]=e[n]=!0,n}},K&&Q||(b.attrHooks.value={get:function(e,n){var r=e.getAttributeNode(n);return b.nodeName(e,"input")?e.defaultValue:r&&r.specified?r.value:t},set:function(e,n,r){return b.nodeName(e,"input")?(e.defaultValue=n,t):I&&I.set(e,n,r)}}),Q||(I=b.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&("id"===n||"name"===n||"coords"===n?""!==r.value:r.specified)?r.value:t},set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},b.attrHooks.contenteditable={get:I.get,set:function(e,t,n){I.set(e,""===t?!1:t,n)}},b.each(["width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}})})),b.support.hrefNormalized||(b.each(["href","src","width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return null==r?t:r}})}),b.each(["href","src"],function(e,t){b.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}})),b.support.style||(b.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),b.support.optSelected||(b.propHooks.selected=b.extend(b.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),b.support.enctype||(b.propFix.enctype="encoding"),b.support.checkOn||b.each(["radio","checkbox"],function(){b.valHooks[this]={get:function(e){return null===e.getAttribute("value")?"on":e.value}}}),b.each(["radio","checkbox"],function(){b.valHooks[this]=b.extend(b.valHooks[this],{set:function(e,n){return b.isArray(n)?e.checked=b.inArray(b(e).val(),n)>=0:t}})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}b.event={global:{},add:function(e,n,r,o,a){var s,u,l,c,p,f,d,h,g,m,y,v=b._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=b.guid++),(u=v.events)||(u=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof b===i||e&&b.event.triggered===e.type?t:b.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(w)||[""],l=n.length;while(l--)s=rt.exec(n[l])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),p=b.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=b.event.special[g]||{},d=b.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&b.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=u[g])||(h=u[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),b.event.global[g]=!0;e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,p,f,d,h,g,m=b.hasData(e)&&b._data(e);if(m&&(c=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=b.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),u=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));u&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||b.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)b.event.remove(e,d+t[l],n,r,!0);b.isEmptyObject(c)&&(delete m.handle,b._removeData(e,"events"))}},trigger:function(n,r,i,a){var s,u,l,c,p,f,d,h=[i||o],g=y.call(n,"type")?n.type:n,m=y.call(n,"namespace")?n.namespace.split("."):[];if(l=f=i=i||o,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+b.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),u=0>g.indexOf(":")&&"on"+g,n=n[b.expando]?n:new b.Event(g,"object"==typeof n&&n),n.isTrigger=!0,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:b.makeArray(r,[n]),p=b.event.special[g]||{},a||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!a&&!p.noBubble&&!b.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(l=l.parentNode);l;l=l.parentNode)h.push(l),f=l;f===(i.ownerDocument||o)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((l=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(b._data(l,"events")||{})[n.type]&&b._data(l,"handle"),s&&s.apply(l,r),s=u&&l[u],s&&b.acceptData(l)&&s.apply&&s.apply(l,r)===!1&&n.preventDefault();if(n.type=g,!(a||n.isDefaultPrevented()||p._default&&p._default.apply(i.ownerDocument,r)!==!1||"click"===g&&b.nodeName(i,"a")||!b.acceptData(i)||!u||!i[g]||b.isWindow(i))){f=i[u],f&&(i[u]=null),b.event.triggered=g;try{i[g]()}catch(v){}b.event.triggered=t,f&&(i[u]=f)}return n.result}},dispatch:function(e){e=b.event.fix(e);var n,r,i,o,a,s=[],u=h.call(arguments),l=(b._data(this,"events")||{})[e.type]||[],c=b.event.special[e.type]||{};if(u[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=b.event.handlers.call(this,e,l),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((b.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],u=n.delegateCount,l=e.target;if(u&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!=this;l=l.parentNode||this)if(1===l.nodeType&&(l.disabled!==!0||"click"!==e.type)){for(o=[],a=0;u>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?b(r,this).index(l)>=0:b.find(r,this,null,[l]).length),o[r]&&o.push(i);o.length&&s.push({elem:l,handlers:o})}return n.length>u&&s.push({elem:this,handlers:n.slice(u)}),s},fix:function(e){if(e[b.expando])return e;var t,n,r,i=e.type,a=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new b.Event(a),t=r.length;while(t--)n=r[t],e[n]=a[n];return e.target||(e.target=a.srcElement||o),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,a):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,a,s=n.button,u=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||o,a=i.documentElement,r=i.body,e.pageX=n.clientX+(a&&a.scrollLeft||r&&r.scrollLeft||0)-(a&&a.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(a&&a.scrollTop||r&&r.scrollTop||0)-(a&&a.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&u&&(e.relatedTarget=u===e.target?n.toElement:u),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},click:{trigger:function(){return b.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t}},focus:{trigger:function(){if(this!==o.activeElement&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===o.activeElement&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=b.extend(new b.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?b.event.trigger(i,null,t):b.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},b.removeEvent=o.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},b.Event=function(e,n){return this instanceof b.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&b.extend(this,n),this.timeStamp=e&&e.timeStamp||b.now(),this[b.expando]=!0,t):new b.Event(e,n)},b.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},b.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){b.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj; +return(!i||i!==r&&!b.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),b.support.submitBubbles||(b.event.special.submit={setup:function(){return b.nodeName(this,"form")?!1:(b.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=b.nodeName(n,"input")||b.nodeName(n,"button")?n.form:t;r&&!b._data(r,"submitBubbles")&&(b.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),b._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&b.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return b.nodeName(this,"form")?!1:(b.event.remove(this,"._submit"),t)}}),b.support.changeBubbles||(b.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(b.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),b.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),b.event.simulate("change",this,e,!0)})),!1):(b.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!b._data(t,"changeBubbles")&&(b.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||b.event.simulate("change",this.parentNode,e,!0)}),b._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return b.event.remove(this,"._change"),!Z.test(this.nodeName)}}),b.support.focusinBubbles||b.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){b.event.simulate(t,e.target,b.event.fix(e),!0)};b.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),b.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return b().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=b.guid++)),this.each(function(){b.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,b(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){b.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){b.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?b.event.trigger(e,n,r,!0):t}}),function(e,t){var n,r,i,o,a,s,u,l,c,p,f,d,h,g,m,y,v,x="sizzle"+-new Date,w=e.document,T={},N=0,C=0,k=it(),E=it(),S=it(),A=typeof t,j=1<<31,D=[],L=D.pop,H=D.push,q=D.slice,M=D.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},_="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=F.replace("w","w#"),B="([*^$|!~]?=)",P="\\["+_+"*("+F+")"+_+"*(?:"+B+_+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+O+")|)|)"+_+"*\\]",R=":("+F+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+P.replace(3,8)+")*)|.*)\\)|)",W=RegExp("^"+_+"+|((?:^|[^\\\\])(?:\\\\.)*)"+_+"+$","g"),$=RegExp("^"+_+"*,"+_+"*"),I=RegExp("^"+_+"*([\\x20\\t\\r\\n\\f>+~])"+_+"*"),z=RegExp(R),X=RegExp("^"+O+"$"),U={ID:RegExp("^#("+F+")"),CLASS:RegExp("^\\.("+F+")"),NAME:RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:RegExp("^("+F.replace("w","w*")+")"),ATTR:RegExp("^"+P),PSEUDO:RegExp("^"+R),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+_+"*(even|odd|(([+-]|)(\\d*)n|)"+_+"*(?:([+-]|)"+_+"*(\\d+)|))"+_+"*\\)|)","i"),needsContext:RegExp("^"+_+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+_+"*((?:-\\d)?\\d*)"+_+"*\\)|)(?=[^-]|$)","i")},V=/[\x20\t\r\n\f]*[+~]/,Y=/^[^{]+\{\s*\[native code/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,G=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,K=/'|\\/g,Z=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,et=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,tt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{q.call(w.documentElement.childNodes,0)[0].nodeType}catch(nt){q=function(e){var t,n=[];while(t=this[e++])n.push(t);return n}}function rt(e){return Y.test(e+"")}function it(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>i.cacheLength&&delete e[t.shift()],e[n]=r}}function ot(e){return e[x]=!0,e}function at(e){var t=p.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}}function st(e,t,n,r){var i,o,a,s,u,l,f,g,m,v;if((t?t.ownerDocument||t:w)!==p&&c(t),t=t||p,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(!d&&!r){if(i=J.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&y(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return H.apply(n,q.call(t.getElementsByTagName(e),0)),n;if((a=i[3])&&T.getByClassName&&t.getElementsByClassName)return H.apply(n,q.call(t.getElementsByClassName(a),0)),n}if(T.qsa&&!h.test(e)){if(f=!0,g=x,m=t,v=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){l=ft(e),(f=t.getAttribute("id"))?g=f.replace(K,"\\$&"):t.setAttribute("id",g),g="[id='"+g+"'] ",u=l.length;while(u--)l[u]=g+dt(l[u]);m=V.test(e)&&t.parentNode||t,v=l.join(",")}if(v)try{return H.apply(n,q.call(m.querySelectorAll(v),0)),n}catch(b){}finally{f||t.removeAttribute("id")}}}return wt(e.replace(W,"$1"),t,n,r)}a=st.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},c=st.setDocument=function(e){var n=e?e.ownerDocument||e:w;return n!==p&&9===n.nodeType&&n.documentElement?(p=n,f=n.documentElement,d=a(n),T.tagNameNoComments=at(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),T.attributes=at(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),T.getByClassName=at(function(e){return e.innerHTML="",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),T.getByName=at(function(e){e.id=x+0,e.innerHTML="
      ",f.insertBefore(e,f.firstChild);var t=n.getElementsByName&&n.getElementsByName(x).length===2+n.getElementsByName(x+0).length;return T.getIdNotName=!n.getElementById(x),f.removeChild(e),t}),i.attrHandle=at(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==A&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},T.getIdNotName?(i.find.ID=function(e,t){if(typeof t.getElementById!==A&&!d){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){return e.getAttribute("id")===t}}):(i.find.ID=function(e,n){if(typeof n.getElementById!==A&&!d){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==A&&r.getAttributeNode("id").value===e?[r]:t:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){var n=typeof e.getAttributeNode!==A&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=T.tagNameNoComments?function(e,n){return typeof n.getElementsByTagName!==A?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.NAME=T.getByName&&function(e,n){return typeof n.getElementsByName!==A?n.getElementsByName(name):t},i.find.CLASS=T.getByClassName&&function(e,n){return typeof n.getElementsByClassName===A||d?t:n.getElementsByClassName(e)},g=[],h=[":focus"],(T.qsa=rt(n.querySelectorAll))&&(at(function(e){e.innerHTML="",e.querySelectorAll("[selected]").length||h.push("\\["+_+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||h.push(":checked")}),at(function(e){e.innerHTML="",e.querySelectorAll("[i^='']").length&&h.push("[*^$]="+_+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||h.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),h.push(",.*:")})),(T.matchesSelector=rt(m=f.matchesSelector||f.mozMatchesSelector||f.webkitMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&at(function(e){T.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",R)}),h=RegExp(h.join("|")),g=RegExp(g.join("|")),y=rt(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},v=f.compareDocumentPosition?function(e,t){var r;return e===t?(u=!0,0):(r=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t))?1&r||e.parentNode&&11===e.parentNode.nodeType?e===n||y(w,e)?-1:t===n||y(w,t)?1:0:4&r?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return u=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:0;if(o===a)return ut(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?ut(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},u=!1,[0,0].sort(v),T.detectDuplicates=u,p):p},st.matches=function(e,t){return st(e,null,null,t)},st.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Z,"='$1']"),!(!T.matchesSelector||d||g&&g.test(t)||h.test(t)))try{var n=m.call(e,t);if(n||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return st(t,p,null,[e]).length>0},st.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},st.attr=function(e,t){var n;return(e.ownerDocument||e)!==p&&c(e),d||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):d||T.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},st.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},st.uniqueSort=function(e){var t,n=[],r=1,i=0;if(u=!T.detectDuplicates,e.sort(v),u){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e};function ut(e,t){var n=t&&e,r=n&&(~t.sourceIndex||j)-(~e.sourceIndex||j);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function lt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ct(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function pt(e){return ot(function(t){return t=+t,ot(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}o=st.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=st.selectors={cacheLength:50,createPseudo:ot,match:U,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(et,tt),e[3]=(e[4]||e[5]||"").replace(et,tt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||st.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&st.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return U.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&z.test(n)&&(t=ft(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(et,tt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[e+" "];return t||(t=RegExp("(^|"+_+")"+e+"("+_+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==A&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=st.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[x]||(m[x]={}),l=c[e]||[],d=l[0]===N&&l[1],f=l[0]===N&&l[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[N,d,f];break}}else if(v&&(l=(t[x]||(t[x]={}))[e])&&l[0]===N)f=l[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[x]||(p[x]={}))[e]=[N,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||st.error("unsupported pseudo: "+e);return r[x]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?ot(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=M.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:ot(function(e){var t=[],n=[],r=s(e.replace(W,"$1"));return r[x]?ot(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:ot(function(e){return function(t){return st(e,t).length>0}}),contains:ot(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:ot(function(e){return X.test(e||"")||st.error("unsupported lang: "+e),e=e.replace(et,tt).toLowerCase(),function(t){var n;do if(n=d?t.getAttribute("xml:lang")||t.getAttribute("lang"):t.lang)return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return Q.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:pt(function(){return[0]}),last:pt(function(e,t){return[t-1]}),eq:pt(function(e,t,n){return[0>n?n+t:n]}),even:pt(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:pt(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:pt(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:pt(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}};for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[n]=lt(n);for(n in{submit:!0,reset:!0})i.pseudos[n]=ct(n);function ft(e,t){var n,r,o,a,s,u,l,c=E[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=i.preFilter;while(s){(!n||(r=$.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),u.push(o=[])),n=!1,(r=I.exec(s))&&(n=r.shift(),o.push({value:n,type:r[0].replace(W," ")}),s=s.slice(n.length));for(a in i.filter)!(r=U[a].exec(s))||l[a]&&!(r=l[a](r))||(n=r.shift(),o.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?st.error(e):E(e,u).slice(0)}function dt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function ht(e,t,n){var i=t.dir,o=n&&"parentNode"===i,a=C++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,s){var u,l,c,p=N+" "+a;if(s){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[x]||(t[x]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,s)||r,l[1]===!0)return!0}}function gt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function mt(e,t,n,r,i){var o,a=[],s=0,u=e.length,l=null!=t;for(;u>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),l&&t.push(s));return a}function yt(e,t,n,r,i,o){return r&&!r[x]&&(r=yt(r)),i&&!i[x]&&(i=yt(i,o)),ot(function(o,a,s,u){var l,c,p,f=[],d=[],h=a.length,g=o||xt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:mt(g,f,e,s,u),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,u),r){l=mt(y,d),r(l,[],s,u),c=l.length;while(c--)(p=l[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?M.call(o,p):f[c])>-1&&(o[l]=!(a[l]=p))}}else y=mt(y===a?y.splice(h,y.length):y),i?i(null,a,y,u):H.apply(a,y)})}function vt(e){var t,n,r,o=e.length,a=i.relative[e[0].type],s=a||i.relative[" "],u=a?1:0,c=ht(function(e){return e===t},s,!0),p=ht(function(e){return M.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>u;u++)if(n=i.relative[e[u].type])f=[ht(gt(f),n)];else{if(n=i.filter[e[u].type].apply(null,e[u].matches),n[x]){for(r=++u;o>r;r++)if(i.relative[e[r].type])break;return yt(u>1&>(f),u>1&&dt(e.slice(0,u-1)).replace(W,"$1"),n,r>u&&vt(e.slice(u,r)),o>r&&vt(e=e.slice(r)),o>r&&dt(e))}f.push(n)}return gt(f)}function bt(e,t){var n=0,o=t.length>0,a=e.length>0,s=function(s,u,c,f,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,T=l,C=s||a&&i.find.TAG("*",d&&u.parentNode||u),k=N+=null==T?1:Math.random()||.1;for(w&&(l=u!==p&&u,r=n);null!=(h=C[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,u,c)){f.push(h);break}w&&(N=k,r=++n)}o&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,o&&b!==v){g=0;while(m=t[g++])m(x,y,u,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=L.call(f));y=mt(y)}H.apply(f,y),w&&!s&&y.length>0&&v+t.length>1&&st.uniqueSort(f)}return w&&(N=k,l=T),x};return o?ot(s):s}s=st.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=ft(e)),n=t.length;while(n--)o=vt(t[n]),o[x]?r.push(o):i.push(o);o=S(e,bt(i,r))}return o};function xt(e,t,n){var r=0,i=t.length;for(;i>r;r++)st(e,t[r],n);return n}function wt(e,t,n,r){var o,a,u,l,c,p=ft(e);if(!r&&1===p.length){if(a=p[0]=p[0].slice(0),a.length>2&&"ID"===(u=a[0]).type&&9===t.nodeType&&!d&&i.relative[a[1].type]){if(t=i.find.ID(u.matches[0].replace(et,tt),t)[0],!t)return n;e=e.slice(a.shift().value.length)}o=U.needsContext.test(e)?0:a.length;while(o--){if(u=a[o],i.relative[l=u.type])break;if((c=i.find[l])&&(r=c(u.matches[0].replace(et,tt),V.test(a[0].type)&&t.parentNode||t))){if(a.splice(o,1),e=r.length&&dt(a),!e)return H.apply(n,q.call(r,0)),n;break}}}return s(e,p)(r,t,d,n,V.test(e)),n}i.pseudos.nth=i.pseudos.eq;function Tt(){}i.filters=Tt.prototype=i.pseudos,i.setFilters=new Tt,c(),st.attr=b.attr,b.find=st,b.expr=st.selectors,b.expr[":"]=b.expr.pseudos,b.unique=st.uniqueSort,b.text=st.getText,b.isXMLDoc=st.isXML,b.contains=st.contains}(e);var at=/Until$/,st=/^(?:parents|prev(?:Until|All))/,ut=/^.[^:#\[\.,]*$/,lt=b.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};b.fn.extend({find:function(e){var t,n,r,i=this.length;if("string"!=typeof e)return r=this,this.pushStack(b(e).filter(function(){for(t=0;i>t;t++)if(b.contains(r[t],this))return!0}));for(n=[],t=0;i>t;t++)b.find(e,this[t],n);return n=this.pushStack(i>1?b.unique(n):n),n.selector=(this.selector?this.selector+" ":"")+e,n},has:function(e){var t,n=b(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(b.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1))},filter:function(e){return this.pushStack(ft(this,e,!0))},is:function(e){return!!e&&("string"==typeof e?lt.test(e)?b(e,this.context).index(this[0])>=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,o=[],a=lt.test(e)||"string"!=typeof e?b(e,t||this.context):0;for(;i>r;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&11!==n.nodeType){if(a?a.index(n)>-1:b.find.matchesSelector(n,e)){o.push(n);break}n=n.parentNode}}return this.pushStack(o.length>1?b.unique(o):o)},index:function(e){return e?"string"==typeof e?b.inArray(this[0],b(e)):b.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?b(e,t):b.makeArray(e&&e.nodeType?[e]:e),r=b.merge(this.get(),n);return this.pushStack(b.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),b.fn.andSelf=b.fn.addBack;function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}b.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(e,t,n){return b.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(e,t,n){return b.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return b.dir(e,"previousSibling",n)},siblings:function(e){return b.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.merge([],e.childNodes)}},function(e,t){b.fn[e]=function(n,r){var i=b.map(this,t,n);return at.test(e)||(r=n),r&&"string"==typeof r&&(i=b.filter(r,i)),i=this.length>1&&!ct[e]?b.unique(i):i,this.length>1&&st.test(e)&&(i=i.reverse()),this.pushStack(i)}}),b.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),1===t.length?b.find.matchesSelector(t[0],e)?[t[0]]:[]:b.find.matches(e,t)},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!b(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(t=t||0,b.isFunction(t))return b.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return b.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=b.grep(e,function(e){return 1===e.nodeType});if(ut.test(t))return b.filter(t,r,!n);t=b.filter(t,r)}return b.grep(e,function(e){return b.inArray(e,t)>=0===n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/\s*$/g,At={option:[1,""],legend:[1,"
      ","
      "],area:[1,"",""],param:[1,"",""],thead:[1,"","
      "],tr:[2,"","
      "],col:[2,"","
      "],td:[3,"","
      "],_default:b.support.htmlSerialize?[0,"",""]:[1,"X
      ","
      "]},jt=dt(o),Dt=jt.appendChild(o.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,b.fn.extend({text:function(e){return b.access(this,function(e){return e===t?b.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(b.isFunction(e))return this.each(function(t){b(this).wrapAll(e.call(this,t))});if(this[0]){var t=b(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return b.isFunction(e)?this.each(function(t){b(this).wrapInner(e.call(this,t))}):this.each(function(){var t=b(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=b.isFunction(e);return this.each(function(n){b(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){b.nodeName(this,"body")||b(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.insertBefore(e,this.firstChild)})},before:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=0;for(;null!=(n=this[r]);r++)(!e||b.filter(e,[n]).length>0)&&(t||1!==n.nodeType||b.cleanData(Ot(n)),n.parentNode&&(t&&b.contains(n.ownerDocument,n)&&Mt(Ot(n,"script")),n.parentNode.removeChild(n)));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&b.cleanData(Ot(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&b.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return b.clone(this,e,t)})},html:function(e){return b.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!b.support.htmlSerialize&&mt.test(e)||!b.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(b.cleanData(Ot(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){var t=b.isFunction(e);return t||"string"==typeof e||(e=b(e).not(this).detach()),this.domManip([e],!0,function(e){var t=this.nextSibling,n=this.parentNode;n&&(b(this).remove(),n.insertBefore(e,t))})},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=f.apply([],e);var i,o,a,s,u,l,c=0,p=this.length,d=this,h=p-1,g=e[0],m=b.isFunction(g);if(m||!(1>=p||"string"!=typeof g||b.support.checkClone)&&Ct.test(g))return this.each(function(i){var o=d.eq(i);m&&(e[0]=g.call(this,i,n?o.html():t)),o.domManip(e,n,r)});if(p&&(l=b.buildFragment(e,this[0].ownerDocument,!1,this),i=l.firstChild,1===l.childNodes.length&&(l=i),i)){for(n=n&&b.nodeName(i,"tr"),s=b.map(Ot(l,"script"),Ht),a=s.length;p>c;c++)o=l,c!==h&&(o=b.clone(o,!0,!0),a&&b.merge(s,Ot(o,"script"))),r.call(n&&b.nodeName(this[c],"table")?Lt(this[c],"tbody"):this[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,b.map(s,qt),c=0;a>c;c++)o=s[c],kt.test(o.type||"")&&!b._data(o,"globalEval")&&b.contains(u,o)&&(o.src?b.ajax({url:o.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):b.globalEval((o.text||o.textContent||o.innerHTML||"").replace(St,"")));l=i=null}return this}});function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function Ht(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Mt(e,t){var n,r=0;for(;null!=(n=e[r]);r++)b._data(n,"globalEval",!t||b._data(t[r],"globalEval"))}function _t(e,t){if(1===t.nodeType&&b.hasData(e)){var n,r,i,o=b._data(e),a=b._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)b.event.add(t,n,s[n][r])}a.data&&(a.data=b.extend({},a.data))}}function Ft(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!b.support.noCloneEvent&&t[b.expando]){i=b._data(t);for(r in i.events)b.removeEvent(t,r,i.handle);t.removeAttribute(b.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),b.support.html5Clone&&e.innerHTML&&!b.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Nt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}b.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){b.fn[e]=function(e){var n,r=0,i=[],o=b(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),b(o[r])[t](n),d.apply(i,n.get());return this.pushStack(i)}});function Ot(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||b.nodeName(o,n)?s.push(o):b.merge(s,Ot(o,n));return n===t||n&&b.nodeName(e,n)?b.merge([e],s):s}function Bt(e){Nt.test(e.type)&&(e.defaultChecked=e.checked)}b.extend({clone:function(e,t,n){var r,i,o,a,s,u=b.contains(e.ownerDocument,e);if(b.support.html5Clone||b.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(b.support.noCloneEvent&&b.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||b.isXMLDoc(e)))for(r=Ot(o),s=Ot(e),a=0;null!=(i=s[a]);++a)r[a]&&Ft(i,r[a]);if(t)if(n)for(s=s||Ot(e),r=r||Ot(o),a=0;null!=(i=s[a]);a++)_t(i,r[a]);else _t(e,o);return r=Ot(o,"script"),r.length>0&&Mt(r,!u&&Ot(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,u,l,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===b.type(o))b.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),u=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[u]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!b.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!b.support.tbody){o="table"!==u||xt.test(o)?""!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)b.nodeName(l=o.childNodes[i],"tbody")&&!l.childNodes.length&&o.removeChild(l) +}b.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),b.support.appendChecked||b.grep(Ot(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===b.inArray(o,r))&&(a=b.contains(o.ownerDocument,o),s=Ot(f.appendChild(o),"script"),a&&Mt(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,u=b.expando,l=b.cache,p=b.support.deleteExpando,f=b.event.special;for(;null!=(n=e[s]);s++)if((t||b.acceptData(n))&&(o=n[u],a=o&&l[o])){if(a.events)for(r in a.events)f[r]?b.event.remove(n,r):b.removeEvent(n,r,a.handle);l[o]&&(delete l[o],p?delete n[u]:typeof n.removeAttribute!==i?n.removeAttribute(u):n[u]=null,c.push(o))}}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+x+")(.*)$","i"),Yt=RegExp("^("+x+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+x+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===b.css(e,"display")||!b.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=b._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=b._data(r,"olddisplay",un(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&b._data(r,"olddisplay",i?n:b.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}b.fn.extend({css:function(e,n){return b.access(this,function(e,n,r){var i,o,a={},s=0;if(b.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=b.css(e,n[s],!1,o);return a}return r!==t?b.style(e,n,r):b.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?b(this).show():b(this).hide()})}}),b.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,u=b.camelCase(n),l=e.style;if(n=b.cssProps[u]||(b.cssProps[u]=tn(l,u)),s=b.cssHooks[n]||b.cssHooks[u],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:l[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(b.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||b.cssNumber[u]||(r+="px"),b.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(l[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{l[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,u=b.camelCase(n);return n=b.cssProps[u]||(b.cssProps[u]=tn(e.style,u)),s=b.cssHooks[n]||b.cssHooks[u],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||b.isNumeric(o)?o||0:a):a},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s.getPropertyValue(n)||s[n]:t,l=e.style;return s&&(""!==u||b.contains(e.ownerDocument,e)||(u=b.style(e,n)),Yt.test(u)&&Ut.test(n)&&(i=l.width,o=l.minWidth,a=l.maxWidth,l.minWidth=l.maxWidth=l.width=u,u=s.width,l.width=i,l.minWidth=o,l.maxWidth=a)),u}):o.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s[n]:t,l=e.style;return null==u&&l&&l[n]&&(u=l[n]),Yt.test(u)&&!zt.test(n)&&(i=l.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),l.left="fontSize"===n?"1em":u,u=l.pixelLeft+"px",l.left=i,a&&(o.left=a)),""===u?"auto":u});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=b.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=b.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=b.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=b.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=b.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(b.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function un(e){var t=o,n=Gt[e];return n||(n=ln(e,t),"none"!==n&&n||(Pt=(Pt||b("';break;case 3:delete t.title,delete t.closeBtn,t.icon===-1&&0===t.icon,r.closeAll("loading");break;case 4:f||(t.content=[t.content,"body"]),t.follow=t.content[1],t.content=t.content[0]+'',delete t.title,t.tips="object"==typeof t.tips?t.tips:[t.tips,!0],t.tipsMore||r.closeAll("tips")}if(e.vessel(f,function(n,r,u){c.append(n[0]),f?function(){2==t.type||4==t.type?function(){i("body").append(n[1])}():function(){s.parents("."+l[0])[0]||(s.data("display",s.css("display")).show().addClass("layui-layer-wrap").wrap(n[1]),i("#"+l[0]+a).find("."+l[5]).before(r))}()}():c.append(n[1]),i(".layui-layer-move")[0]||c.append(o.moveElem=u),e.layero=i("#"+l[0]+a),t.scrollbar||l.html.css("overflow","hidden").attr("layer-full",a)}).auto(a),i("#layui-layer-shade"+e.index).css({"background-color":t.shade[1]||"#000",opacity:t.shade[0]||t.shade}),2==t.type&&6==r.ie&&e.layero.find("iframe").attr("src",s[0]),4==t.type?e.tips():e.offset(),t.fixed&&n.on("resize",function(){e.offset(),(/^\d+%$/.test(t.area[0])||/^\d+%$/.test(t.area[1]))&&e.auto(a),4==t.type&&e.tips()}),t.time<=0||setTimeout(function(){r.close(e.index)},t.time),e.move().callback(),l.anim[t.anim]){var u="layer-anim "+l.anim[t.anim];e.layero.addClass(u).one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",function(){i(this).removeClass(u)})}t.isOutAnim&&e.layero.data("isOutAnim",!0)}},s.pt.auto=function(e){var t=this,a=t.config,o=i("#"+l[0]+e);""===a.area[0]&&a.maxWidth>0&&(r.ie&&r.ie<8&&a.btn&&o.width(o.innerWidth()),o.outerWidth()>a.maxWidth&&o.width(a.maxWidth));var s=[o.innerWidth(),o.innerHeight()],f=o.find(l[1]).outerHeight()||0,c=o.find("."+l[6]).outerHeight()||0,u=function(e){e=o.find(e),e.height(s[1]-f-c-2*(0|parseFloat(e.css("padding-top"))))};switch(a.type){case 2:u("iframe");break;default:""===a.area[1]?a.maxHeight>0&&o.outerHeight()>a.maxHeight?(s[1]=a.maxHeight,u("."+l[5])):a.fixed&&s[1]>=n.height()&&(s[1]=n.height(),u("."+l[5])):u("."+l[5])}return t},s.pt.offset=function(){var e=this,t=e.config,i=e.layero,a=[i.outerWidth(),i.outerHeight()],o="object"==typeof t.offset;e.offsetTop=(n.height()-a[1])/2,e.offsetLeft=(n.width()-a[0])/2,o?(e.offsetTop=t.offset[0],e.offsetLeft=t.offset[1]||e.offsetLeft):"auto"!==t.offset&&("t"===t.offset?e.offsetTop=0:"r"===t.offset?e.offsetLeft=n.width()-a[0]:"b"===t.offset?e.offsetTop=n.height()-a[1]:"l"===t.offset?e.offsetLeft=0:"lt"===t.offset?(e.offsetTop=0,e.offsetLeft=0):"lb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=0):"rt"===t.offset?(e.offsetTop=0,e.offsetLeft=n.width()-a[0]):"rb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=n.width()-a[0]):e.offsetTop=t.offset),t.fixed||(e.offsetTop=/%$/.test(e.offsetTop)?n.height()*parseFloat(e.offsetTop)/100:parseFloat(e.offsetTop),e.offsetLeft=/%$/.test(e.offsetLeft)?n.width()*parseFloat(e.offsetLeft)/100:parseFloat(e.offsetLeft),e.offsetTop+=n.scrollTop(),e.offsetLeft+=n.scrollLeft()),i.attr("minLeft")&&(e.offsetTop=n.height()-(i.find(l[1]).outerHeight()||0),e.offsetLeft=i.css("left")),i.css({top:e.offsetTop,left:e.offsetLeft})},s.pt.tips=function(){var e=this,t=e.config,a=e.layero,o=[a.outerWidth(),a.outerHeight()],r=i(t.follow);r[0]||(r=i("body"));var s={width:r.outerWidth(),height:r.outerHeight(),top:r.offset().top,left:r.offset().left},f=a.find(".layui-layer-TipsG"),c=t.tips[0];t.tips[1]||f.remove(),s.autoLeft=function(){s.left+o[0]-n.width()>0?(s.tipLeft=s.left+s.width-o[0],f.css({right:12,left:"auto"})):s.tipLeft=s.left},s.where=[function(){s.autoLeft(),s.tipTop=s.top-o[1]-10,f.removeClass("layui-layer-TipsB").addClass("layui-layer-TipsT").css("border-right-color",t.tips[1])},function(){s.tipLeft=s.left+s.width+10,s.tipTop=s.top,f.removeClass("layui-layer-TipsL").addClass("layui-layer-TipsR").css("border-bottom-color",t.tips[1])},function(){s.autoLeft(),s.tipTop=s.top+s.height+10,f.removeClass("layui-layer-TipsT").addClass("layui-layer-TipsB").css("border-right-color",t.tips[1])},function(){s.tipLeft=s.left-o[0]-10,s.tipTop=s.top,f.removeClass("layui-layer-TipsR").addClass("layui-layer-TipsL").css("border-bottom-color",t.tips[1])}],s.where[c-1](),1===c?s.top-(n.scrollTop()+o[1]+16)<0&&s.where[2]():2===c?n.width()-(s.left+s.width+o[0]+16)>0||s.where[3]():3===c?s.top-n.scrollTop()+s.height+o[1]+16-n.height()>0&&s.where[0]():4===c&&o[0]+16-s.left>0&&s.where[1](),a.find("."+l[5]).css({"background-color":t.tips[1],"padding-right":t.closeBtn?"30px":""}),a.css({left:s.tipLeft-(t.fixed?n.scrollLeft():0),top:s.tipTop-(t.fixed?n.scrollTop():0)})},s.pt.move=function(){var e=this,t=e.config,a=i(document),s=e.layero,l=s.find(t.move),f=s.find(".layui-layer-resize"),c={};return t.move&&l.css("cursor","move"),l.on("mousedown",function(e){e.preventDefault(),t.move&&(c.moveStart=!0,c.offset=[e.clientX-parseFloat(s.css("left")),e.clientY-parseFloat(s.css("top"))],o.moveElem.css("cursor","move").show())}),f.on("mousedown",function(e){e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],c.area=[s.outerWidth(),s.outerHeight()],o.moveElem.css("cursor","se-resize").show()}),a.on("mousemove",function(i){if(c.moveStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1],l="fixed"===s.css("position");if(i.preventDefault(),c.stX=l?0:n.scrollLeft(),c.stY=l?0:n.scrollTop(),!t.moveOut){var f=n.width()-s.outerWidth()+c.stX,u=n.height()-s.outerHeight()+c.stY;af&&(a=f),ou&&(o=u)}s.css({left:a,top:o})}if(t.resize&&c.resizeStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1];i.preventDefault(),r.style(e.index,{width:c.area[0]+a,height:c.area[1]+o}),c.isResize=!0,t.resizing&&t.resizing(s)}}).on("mouseup",function(e){c.moveStart&&(delete c.moveStart,o.moveElem.hide(),t.moveEnd&&t.moveEnd(s)),c.resizeStart&&(delete c.resizeStart,o.moveElem.hide())}),e},s.pt.callback=function(){function e(){var e=a.cancel&&a.cancel(t.index,n);e===!1||r.close(t.index)}var t=this,n=t.layero,a=t.config;t.openLayer(),a.success&&(2==a.type?n.find("iframe").on("load",function(){a.success(n,t.index)}):a.success(n,t.index)),6==r.ie&&t.IE6(n),n.find("."+l[6]).children("a").on("click",function(){var e=i(this).index();if(0===e)a.yes?a.yes(t.index,n):a.btn1?a.btn1(t.index,n):r.close(t.index);else{var o=a["btn"+(e+1)]&&a["btn"+(e+1)](t.index,n);o===!1||r.close(t.index)}}),n.find("."+l[7]).on("click",e),a.shadeClose&&i("#layui-layer-shade"+t.index).on("click",function(){r.close(t.index)}),n.find(".layui-layer-min").on("click",function(){var e=a.min&&a.min(n);e===!1||r.min(t.index,a)}),n.find(".layui-layer-max").on("click",function(){i(this).hasClass("layui-layer-maxmin")?(r.restore(t.index),a.restore&&a.restore(n)):(r.full(t.index,a),setTimeout(function(){a.full&&a.full(n)},100))}),a.end&&(o.end[t.index]=a.end)},o.reselect=function(){i.each(i("select"),function(e,t){var n=i(this);n.parents("."+l[0])[0]||1==n.attr("layer")&&i("."+l[0]).length<1&&n.removeAttr("layer").show(),n=null})},s.pt.IE6=function(e){i("select").each(function(e,t){var n=i(this);n.parents("."+l[0])[0]||"none"===n.css("display")||n.attr({layer:"1"}).hide(),n=null})},s.pt.openLayer=function(){var e=this;r.zIndex=e.config.zIndex,r.setTop=function(e){var t=function(){r.zIndex++,e.css("z-index",r.zIndex+1)};return r.zIndex=parseInt(e[0].style.zIndex),e.on("mousedown",t),r.zIndex}},o.record=function(e){var t=[e.width(),e.height(),e.position().top,e.position().left+parseFloat(e.css("margin-left"))];e.find(".layui-layer-max").addClass("layui-layer-maxmin"),e.attr({area:t})},o.rescollbar=function(e){l.html.attr("layer-full")==e&&(l.html[0].style.removeProperty?l.html[0].style.removeProperty("overflow"):l.html[0].style.removeAttribute("overflow"),l.html.removeAttr("layer-full"))},e.layer=r,r.getChildFrame=function(e,t){return t=t||i("."+l[4]).attr("times"),i("#"+l[0]+t).find("iframe").contents().find(e)},r.getFrameIndex=function(e){return i("#"+e).parents("."+l[4]).attr("times")},r.iframeAuto=function(e){if(e){var t=r.getChildFrame("html",e).outerHeight(),n=i("#"+l[0]+e),a=n.find(l[1]).outerHeight()||0,o=n.find("."+l[6]).outerHeight()||0;n.css({height:t+a+o}),n.find("iframe").css({height:t})}},r.iframeSrc=function(e,t){i("#"+l[0]+e).find("iframe").attr("src",t)},r.style=function(e,t,n){var a=i("#"+l[0]+e),r=a.find(".layui-layer-content"),s=a.attr("type"),f=a.find(l[1]).outerHeight()||0,c=a.find("."+l[6]).outerHeight()||0;a.attr("minLeft");s!==o.type[3]&&s!==o.type[4]&&(n||(parseFloat(t.width)<=260&&(t.width=260),parseFloat(t.height)-f-c<=64&&(t.height=64+f+c)),a.css(t),c=a.find("."+l[6]).outerHeight(),s===o.type[2]?a.find("iframe").css({height:parseFloat(t.height)-f-c}):r.css({height:parseFloat(t.height)-f-c-parseFloat(r.css("padding-top"))-parseFloat(r.css("padding-bottom"))}))},r.min=function(e,t){var a=i("#"+l[0]+e),s=a.find(l[1]).outerHeight()||0,f=a.attr("minLeft")||181*o.minIndex+"px",c=a.css("position");o.record(a),o.minLeft[0]&&(f=o.minLeft[0],o.minLeft.shift()),a.attr("position",c),r.style(e,{width:180,height:s,left:f,top:n.height()-s,position:"fixed",overflow:"hidden"},!0),a.find(".layui-layer-min").hide(),"page"===a.attr("type")&&a.find(l[4]).hide(),o.rescollbar(e),a.attr("minLeft")||o.minIndex++,a.attr("minLeft",f)},r.restore=function(e){var t=i("#"+l[0]+e),n=t.attr("area").split(",");t.attr("type");r.style(e,{width:parseFloat(n[0]),height:parseFloat(n[1]),top:parseFloat(n[2]),left:parseFloat(n[3]),position:t.attr("position"),overflow:"visible"},!0),t.find(".layui-layer-max").removeClass("layui-layer-maxmin"),t.find(".layui-layer-min").show(),"page"===t.attr("type")&&t.find(l[4]).show(),o.rescollbar(e)},r.full=function(e){var t,a=i("#"+l[0]+e);o.record(a),l.html.attr("layer-full")||l.html.css("overflow","hidden").attr("layer-full",e),clearTimeout(t),t=setTimeout(function(){var t="fixed"===a.css("position");r.style(e,{top:t?0:n.scrollTop(),left:t?0:n.scrollLeft(),width:n.width(),height:n.height()},!0),a.find(".layui-layer-min").hide()},100)},r.title=function(e,t){var n=i("#"+l[0]+(t||r.index)).find(l[1]);n.html(e)},r.close=function(e){var t=i("#"+l[0]+e),n=t.attr("type"),a="layer-anim-close";if(t[0]){var s="layui-layer-wrap",f=function(){if(n===o.type[1]&&"object"===t.attr("conType")){t.children(":not(."+l[5]+")").remove();for(var a=t.find("."+s),r=0;r<2;r++)a.unwrap();a.css("display",a.data("display")).removeClass(s)}else{if(n===o.type[2])try{var f=i("#"+l[4]+e)[0];f.contentWindow.document.write(""),f.contentWindow.close(),t.find("."+l[5])[0].removeChild(f)}catch(c){}t[0].innerHTML="",t.remove()}"function"==typeof o.end[e]&&o.end[e](),delete o.end[e]};t.data("isOutAnim")&&t.addClass("layer-anim "+a),i("#layui-layer-moves, #layui-layer-shade"+e).remove(),6==r.ie&&o.reselect(),o.rescollbar(e),t.attr("minLeft")&&(o.minIndex--,o.minLeft.push(t.attr("minLeft"))),r.ie&&r.ie<10||!t.data("isOutAnim")?f():setTimeout(function(){f()},200)}},r.closeAll=function(e){i.each(i("."+l[0]),function(){var t=i(this),n=e?t.attr("type")===e:1;n&&r.close(t.attr("times")),n=null})};var f=r.cache||{},c=function(e){return f.skin?" "+f.skin+" "+f.skin+"-"+e:""};r.prompt=function(e,t){var a="";if(e=e||{},"function"==typeof e&&(t=e),e.area){var o=e.area;a='style="width: '+o[0]+"; height: "+o[1]+';"',delete e.area}var s,l=2==e.formType?'":function(){return''}(),f=e.success;return delete e.success,r.open(i.extend({type:1,btn:["确定","取消"],content:l,skin:"layui-layer-prompt"+c("prompt"),maxWidth:n.width(),success:function(e){s=e.find(".layui-layer-input"),s.focus(),"function"==typeof f&&f(e)},resize:!1,yes:function(i){var n=s.val();""===n?s.focus():n.length>(e.maxlength||500)?r.tips("最多输入"+(e.maxlength||500)+"个字数",s,{tips:1}):t&&t(n,i,s)}},e))},r.tab=function(e){e=e||{};var t=e.tab||{},n="layui-this",a=e.success;return delete e.success,r.open(i.extend({type:1,skin:"layui-layer-tab"+c("tab"),resize:!1,title:function(){var e=t.length,i=1,a="";if(e>0)for(a=''+t[0].title+"";i"+t[i].title+"";return a}(),content:'
        '+function(){var e=t.length,i=1,a="";if(e>0)for(a='
      • '+(t[0].content||"no content")+"
      • ";i'+(t[i].content||"no content")+"";return a}()+"
      ",success:function(t){var o=t.find(".layui-layer-title").children(),r=t.find(".layui-layer-tabmain").children();o.on("mousedown",function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0;var a=i(this),o=a.index();a.addClass(n).siblings().removeClass(n),r.eq(o).show().siblings().hide(),"function"==typeof e.change&&e.change(o)}),"function"==typeof a&&a(t)}},e))},r.photos=function(t,n,a){function o(e,t,i){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,i(e)}))}var s={};if(t=t||{},t.photos){var l=t.photos.constructor===Object,f=l?t.photos:{},u=f.data||[],d=f.start||0;s.imgIndex=(0|d)+1,t.img=t.img||"img";var y=t.success;if(delete t.success,l){if(0===u.length)return r.msg("没有图片")}else{var p=i(t.photos),h=function(){u=[],p.find(t.img).each(function(e){var t=i(this);t.attr("layer-index",e),u.push({alt:t.attr("alt"),pid:t.attr("layer-pid"),src:t.attr("layer-src")||t.attr("src"),thumb:t.attr("src")})})};if(h(),0===u.length)return;if(n||p.on("click",t.img,function(){var e=i(this),n=e.attr("layer-index");r.photos(i.extend(t,{photos:{start:n,data:u,tab:t.tab},full:t.full}),!0),h()}),!n)return}s.imgprev=function(e){s.imgIndex--,s.imgIndex<1&&(s.imgIndex=u.length),s.tabimg(e)},s.imgnext=function(e,t){s.imgIndex++,s.imgIndex>u.length&&(s.imgIndex=1,t)||s.tabimg(e)},s.keyup=function(e){if(!s.end){var t=e.keyCode;e.preventDefault(),37===t?s.imgprev(!0):39===t?s.imgnext(!0):27===t&&r.close(s.index)}},s.tabimg=function(e){if(!(u.length<=1))return f.start=s.imgIndex-1,r.close(s.index),r.photos(t,!0,e)},s.event=function(){s.bigimg.hover(function(){s.imgsee.show()},function(){s.imgsee.hide()}),s.bigimg.find(".layui-layer-imgprev").on("click",function(e){e.preventDefault(),s.imgprev()}),s.bigimg.find(".layui-layer-imgnext").on("click",function(e){e.preventDefault(),s.imgnext()}),i(document).on("keyup",s.keyup)},s.loadi=r.load(1,{shade:!("shade"in t)&&.9,scrollbar:!1}),o(u[d].src,function(n){r.close(s.loadi),s.index=r.open(i.extend({type:1,id:"layui-layer-photos",area:function(){var a=[n.width,n.height],o=[i(e).width()-100,i(e).height()-100];if(!t.full&&(a[0]>o[0]||a[1]>o[1])){var r=[a[0]/o[0],a[1]/o[1]];r[0]>r[1]?(a[0]=a[0]/r[0],a[1]=a[1]/r[0]):r[0]'+(u[d].alt||
      '+(u.length>1?'':"")+'
      '+(u[d].alt||"")+""+s.imgIndex+"/"+u.length+"
      ",success:function(e,i){s.bigimg=e.find(".layui-layer-phimg"),s.imgsee=e.find(".layui-layer-imguide,.layui-layer-imgbar"),s.event(e),t.tab&&t.tab(u[d],e),"function"==typeof y&&y(e)},end:function(){s.end=!0,i(document).off("keyup",s.keyup)}},t))},function(){r.close(s.loadi),r.msg("当前图片地址异常
      是否继续查看下一张?",{time:3e4,btn:["下一张","不看了"],yes:function(){u.length>1&&s.imgnext(!0,!0)}})})}},o.run=function(t){i=t,n=i(e),l.html=i("html"),r.open=function(e){var t=new s(e);return t.index}},e.layui&&layui.define?(r.ready(),layui.define("jquery",function(t){r.path=layui.cache.dir,o.run(layui.$),e.layer=r,t("layer",r)})):"function"==typeof define&&define.amd?define(["jquery"],function(){return o.run(e.jQuery),r}):function(){o.run(e.jQuery),r.ready()}()}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/mobile/layer.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/mobile/layer.js new file mode 100644 index 000000000..f9cf69313 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/mobile/layer.js @@ -0,0 +1,2 @@ +/*! layer mobile-v2.0.0 Web弹层组件 MIT License http://layer.layui.com/mobile By 贤心 */ + ;!function(e){"use strict";var t=document,n="querySelectorAll",i="getElementsByClassName",a=function(e){return t[n](e)},s={type:0,shade:!0,shadeClose:!0,fixed:!0,anim:"scale"},l={extend:function(e){var t=JSON.parse(JSON.stringify(s));for(var n in e)t[n]=e[n];return t},timer:{},end:{}};l.touch=function(e,t){e.addEventListener("click",function(e){t.call(this,e)},!1)};var r=0,o=["layui-m-layer"],c=function(e){var t=this;t.config=l.extend(e),t.view()};c.prototype.view=function(){var e=this,n=e.config,s=t.createElement("div");e.id=s.id=o[0]+r,s.setAttribute("class",o[0]+" "+o[0]+(n.type||0)),s.setAttribute("index",r);var l=function(){var e="object"==typeof n.title;return n.title?'

      '+(e?n.title[0]:n.title)+"

      ":""}(),c=function(){"string"==typeof n.btn&&(n.btn=[n.btn]);var e,t=(n.btn||[]).length;return 0!==t&&n.btn?(e=''+n.btn[0]+"",2===t&&(e=''+n.btn[1]+""+e),'
      '+e+"
      "):""}();if(n.fixed||(n.top=n.hasOwnProperty("top")?n.top:100,n.style=n.style||"",n.style+=" top:"+(t.body.scrollTop+n.top)+"px"),2===n.type&&(n.content='

      '+(n.content||"")+"

      "),n.skin&&(n.anim="up"),"msg"===n.skin&&(n.shade=!1),s.innerHTML=(n.shade?"
      ':"")+'
      "+l+'
      '+n.content+"
      "+c+"
      ",!n.type||2===n.type){var d=t[i](o[0]+n.type),y=d.length;y>=1&&layer.close(d[0].getAttribute("index"))}document.body.appendChild(s);var u=e.elem=a("#"+e.id)[0];n.success&&n.success(u),e.index=r++,e.action(n,u)},c.prototype.action=function(e,t){var n=this;e.time&&(l.timer[n.index]=setTimeout(function(){layer.close(n.index)},1e3*e.time));var a=function(){var t=this.getAttribute("type");0==t?(e.no&&e.no(),layer.close(n.index)):e.yes?e.yes(n.index):layer.close(n.index)};if(e.btn)for(var s=t[i]("layui-m-layerbtn")[0].children,r=s.length,o=0;odiv{line-height:22px;padding-top:7px;margin-bottom:20px;font-size:14px}.layui-m-layerbtn{display:box;display:-moz-box;display:-webkit-box;width:100%;height:50px;line-height:50px;font-size:0;border-top:1px solid #D0D0D0;background-color:#F2F2F2}.layui-m-layerbtn span{display:block;-moz-box-flex:1;box-flex:1;-webkit-box-flex:1;font-size:14px;cursor:pointer}.layui-m-layerbtn span[yes]{color:#40AFFE}.layui-m-layerbtn span[no]{border-right:1px solid #D0D0D0;border-radius:0 0 0 5px}.layui-m-layerbtn span:active{background-color:#F6F6F6}.layui-m-layerend{position:absolute;right:7px;top:10px;width:30px;height:30px;border:0;font-weight:400;background:0 0;cursor:pointer;-webkit-appearance:none;font-size:30px}.layui-m-layerend::after,.layui-m-layerend::before{position:absolute;left:5px;top:15px;content:'';width:18px;height:1px;background-color:#999;transform:rotate(45deg);-webkit-transform:rotate(45deg);border-radius:3px}.layui-m-layerend::after{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}body .layui-m-layer .layui-m-layer-footer{position:fixed;width:95%;max-width:100%;margin:0 auto;left:0;right:0;bottom:10px;background:0 0}.layui-m-layer-footer .layui-m-layercont{padding:20px;border-radius:5px 5px 0 0;background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn{display:block;height:auto;background:0 0;border-top:none}.layui-m-layer-footer .layui-m-layerbtn span{background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn span[no]{color:#FD482C;border-top:1px solid #c2c2c2;border-radius:0 0 5px 5px}.layui-m-layer-footer .layui-m-layerbtn span[yes]{margin-top:10px;border-radius:5px}body .layui-m-layer .layui-m-layer-msg{width:auto;max-width:90%;margin:0 auto;bottom:-150px;background-color:rgba(0,0,0,.7);color:#fff}.layui-m-layer-msg .layui-m-layercont{padding:10px 20px} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/icon-ext.png b/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/icon-ext.png new file mode 100644 index 000000000..bbbb669bb Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/icon-ext.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/icon.png b/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/icon.png new file mode 100644 index 000000000..3e17da8b1 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/icon.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/layer.css b/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/layer.css new file mode 100644 index 000000000..820b4a99b --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/layer.css @@ -0,0 +1 @@ +.layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span,.layui-layer-title{text-overflow:ellipsis;white-space:nowrap}html #layuicss-layer{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+"px")}.layui-layer{-webkit-overflow-scrolling:touch;top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;border-radius:2px;box-shadow:1px 1px 50px rgba(0,0,0,.3)}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.1);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-load{background:url(loading-1.gif) center center no-repeat #eee}.layui-layer-ico{background:url(icon.png) no-repeat}.layui-layer-btn a,.layui-layer-dialog .layui-layer-ico,.layui-layer-setwin a{display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-move{display:none;position:fixed;*position:absolute;left:0;top:0;width:100%;height:100%;cursor:move;opacity:0;filter:alpha(opacity=0);background-color:#fff;z-index:2147483647}.layui-layer-resize{position:absolute;width:15px;height:15px;right:0;bottom:0;cursor:se-resize}.layer-anim{-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-00{-webkit-animation-name:layer-bounceIn;animation-name:layer-bounceIn}@-webkit-keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:layer-zoomInDown;animation-name:layer-zoomInDown}@-webkit-keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:layer-fadeInUpBig;animation-name:layer-fadeInUpBig}@-webkit-keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:layer-zoomInLeft;animation-name:layer-zoomInLeft}@-webkit-keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layer-anim-04{-webkit-animation-name:layer-rollIn;animation-name:layer-rollIn}@keyframes layer-fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:layer-fadeIn;animation-name:layer-fadeIn}@-webkit-keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:layer-shake;animation-name:layer-shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layui-layer-title{padding:0 80px 0 20px;height:42px;line-height:42px;border-bottom:1px solid #eee;font-size:14px;color:#333;overflow:hidden;background-color:#F8F8F8;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:15px;font-size:0;line-height:initial}.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:10px;font-size:12px;_overflow:hidden}.layui-layer-setwin .layui-layer-min cite{position:absolute;width:14px;height:2px;left:0;top:50%;margin-top:-1px;background-color:#2E2D3C;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA}.layui-layer-setwin .layui-layer-max{background-position:-32px -40px}.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px}.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px}.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px}.layui-layer-setwin .layui-layer-close1{background-position:1px -40px;cursor:pointer}.layui-layer-setwin .layui-layer-close1:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;width:30px;height:30px;margin-left:0;background-position:-149px -31px;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{background-position:-180px -31px}.layui-layer-btn{text-align:right;padding:0 15px 12px;pointer-events:auto;user-select:none;-webkit-user-select:none}.layui-layer-btn a{height:28px;line-height:28px;margin:5px 5px 0;padding:0 15px;border:1px solid #dedede;background-color:#fff;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.8}.layui-layer-btn .layui-layer-btn0{border-color:#1E9FFF;background-color:#1E9FFF;color:#fff}.layui-layer-btn-l{text-align:left}.layui-layer-btn-c{text-align:center}.layui-layer-dialog{min-width:260px}.layui-layer-dialog .layui-layer-content{position:relative;padding:20px;line-height:24px;word-break:break-all;overflow:hidden;font-size:14px;overflow-x:hidden;overflow-y:auto}.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute;top:16px;left:15px;_left:-40px;width:30px;height:30px}.layui-layer-ico1{background-position:-30px 0}.layui-layer-ico2{background-position:-60px 0}.layui-layer-ico3{background-position:-90px 0}.layui-layer-ico4{background-position:-120px 0}.layui-layer-ico5{background-position:-150px 0}.layui-layer-ico6{background-position:-180px 0}.layui-layer-rim{border:6px solid #8D8D8D;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #D3D4D3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-content{padding:12px 25px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:20px 20px 20px 55px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(loading-0.gif) no-repeat}.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(loading-1.gif) no-repeat}.layui-layer-ico16,.layui-layer-loading .layui-layer-loading2{width:32px;height:32px;background:url(loading-2.gif) no-repeat}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:8px 15px;font-size:12px;_float:left;border-radius:2px;box-shadow:1px 1px 3px rgba(0,0,0,.2);background-color:#000;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#000}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:5px;border-bottom-style:solid;border-bottom-color:#000}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan[type=dialog]{min-width:280px}.layui-layer-lan .layui-layer-title{background:#4476A7;color:#fff;border:none}.layui-layer-lan .layui-layer-btn{padding:5px 10px 10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#fff;border-color:#E9E7E7;color:#333}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95;border-color:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1}.layui-layer-iconext{background:url(icon-ext.png) no-repeat}.layui-layer-prompt .layui-layer-input{display:block;width:230px;height:36px;margin:0 auto;line-height:30px;padding-left:10px;border:1px solid #e6e6e6;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px;padding:6px 10px}.layui-layer-prompt .layui-layer-content{padding:20px}.layui-layer-prompt .layui-layer-btn{padding-top:0}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;float:left;min-width:80px;max-width:260px;padding:0 20px;text-align:center;overflow:hidden;cursor:pointer}.layui-layer-tab .layui-layer-title span.layui-this{height:43px;border-left:1px solid #eee;border-right:1px solid #eee;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left:none}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.layui-this{display:block}.layui-layer-photos{-webkit-animation-duration:.8s;animation-duration:.8s}.layui-layer-photos .layui-layer-content{overflow:hidden;text-align:center}.layui-layer-photos .layui-layer-phimg img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-imgbar,.layui-layer-imguide{display:none}.layui-layer-imgnext,.layui-layer-imgprev{position:absolute;top:50%;width:27px;_width:44px;height:44px;margin-top:-22px;outline:0;blr:expression(this.onFocus=this.blur())}.layui-layer-imgprev{left:10px;background-position:-5px -5px;_background-position:-70px -5px}.layui-layer-imgprev:hover{background-position:-33px -5px;_background-position:-120px -5px}.layui-layer-imgnext{right:10px;_right:8px;background-position:-5px -50px;_background-position:-70px -50px}.layui-layer-imgnext:hover{background-position:-33px -50px;_background-position:-120px -50px}.layui-layer-imgbar{position:absolute;left:0;bottom:0;width:100%;height:32px;line-height:32px;background-color:rgba(0,0,0,.8);background-color:#000\9;filter:Alpha(opacity=80);color:#fff;overflow:hidden;font-size:0}.layui-layer-imgtit *{display:inline-block;*display:inline;*zoom:1;vertical-align:top;font-size:12px}.layui-layer-imgtit a{max-width:65%;overflow:hidden;color:#fff}.layui-layer-imgtit a:hover{color:#fff;text-decoration:underline}.layui-layer-imgtit em{padding-left:10px;font-style:normal}@-webkit-keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);-ms-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-close{-webkit-animation-name:layer-bounceOut;animation-name:layer-bounceOut;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.2s;animation-duration:.2s}@media screen and (max-width:1100px){.layui-layer-iframe{overflow-y:auto;-webkit-overflow-scrolling:touch}} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/loading-0.gif b/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/loading-0.gif new file mode 100644 index 000000000..6f3c9539a Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/loading-0.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/loading-1.gif b/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/loading-1.gif new file mode 100644 index 000000000..db3a483e4 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/loading-1.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/loading-2.gif b/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/loading-2.gif new file mode 100644 index 000000000..5bb90fd6a Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/js/todel/layer-3.1.1/theme/default/loading-2.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/lodash-4.17.10.min.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/lodash-4.17.10.min.js new file mode 100644 index 000000000..fced00b39 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/lodash-4.17.10.min.js @@ -0,0 +1,137 @@ +/** + * @license + * Lodash lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE + */ +;(function(){function n(n,t,r){switch(r.length){case 0:return n.call(t);case 1:return n.call(t,r[0]);case 2:return n.call(t,r[0],r[1]);case 3:return n.call(t,r[0],r[1],r[2])}return n.apply(t,r)}function t(n,t,r,e){for(var u=-1,i=null==n?0:n.length;++u"']/g,G=RegExp(V.source),H=RegExp(K.source),J=/<%-([\s\S]+?)%>/g,Y=/<%([\s\S]+?)%>/g,Q=/<%=([\s\S]+?)%>/g,X=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,nn=/^\w*$/,tn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,rn=/[\\^$.*+?()[\]{}|]/g,en=RegExp(rn.source),un=/^\s+|\s+$/g,on=/^\s+/,fn=/\s+$/,cn=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,an=/\{\n\/\* \[wrapped with (.+)\] \*/,ln=/,? & /,sn=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,hn=/\\(\\)?/g,pn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,_n=/\w*$/,vn=/^[-+]0x[0-9a-f]+$/i,gn=/^0b[01]+$/i,dn=/^\[object .+?Constructor\]$/,yn=/^0o[0-7]+$/i,bn=/^(?:0|[1-9]\d*)$/,xn=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,jn=/($^)/,wn=/['\n\r\u2028\u2029\\]/g,mn="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?)*",An="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+mn,En="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]?|[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",kn=RegExp("['\u2019]","g"),Sn=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g"),On=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+En+mn,"g"),In=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:d|ll|m|re|s|t|ve))?|[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?|\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])|\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])|\\d+",An].join("|"),"g"),Rn=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]"),zn=/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Wn="Array Buffer DataView Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Promise RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),Bn={}; +Bn["[object Float32Array]"]=Bn["[object Float64Array]"]=Bn["[object Int8Array]"]=Bn["[object Int16Array]"]=Bn["[object Int32Array]"]=Bn["[object Uint8Array]"]=Bn["[object Uint8ClampedArray]"]=Bn["[object Uint16Array]"]=Bn["[object Uint32Array]"]=true,Bn["[object Arguments]"]=Bn["[object Array]"]=Bn["[object ArrayBuffer]"]=Bn["[object Boolean]"]=Bn["[object DataView]"]=Bn["[object Date]"]=Bn["[object Error]"]=Bn["[object Function]"]=Bn["[object Map]"]=Bn["[object Number]"]=Bn["[object Object]"]=Bn["[object RegExp]"]=Bn["[object Set]"]=Bn["[object String]"]=Bn["[object WeakMap]"]=false; +var Ln={};Ln["[object Arguments]"]=Ln["[object Array]"]=Ln["[object ArrayBuffer]"]=Ln["[object DataView]"]=Ln["[object Boolean]"]=Ln["[object Date]"]=Ln["[object Float32Array]"]=Ln["[object Float64Array]"]=Ln["[object Int8Array]"]=Ln["[object Int16Array]"]=Ln["[object Int32Array]"]=Ln["[object Map]"]=Ln["[object Number]"]=Ln["[object Object]"]=Ln["[object RegExp]"]=Ln["[object Set]"]=Ln["[object String]"]=Ln["[object Symbol]"]=Ln["[object Uint8Array]"]=Ln["[object Uint8ClampedArray]"]=Ln["[object Uint16Array]"]=Ln["[object Uint32Array]"]=true, +Ln["[object Error]"]=Ln["[object Function]"]=Ln["[object WeakMap]"]=false;var Un={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Cn=parseFloat,Dn=parseInt,Mn=typeof global=="object"&&global&&global.Object===Object&&global,Tn=typeof self=="object"&&self&&self.Object===Object&&self,$n=Mn||Tn||Function("return this")(),Fn=typeof exports=="object"&&exports&&!exports.nodeType&&exports,Nn=Fn&&typeof module=="object"&&module&&!module.nodeType&&module,Pn=Nn&&Nn.exports===Fn,Zn=Pn&&Mn.process,qn=function(){ +try{var n=Nn&&Nn.f&&Nn.f("util").types;return n?n:Zn&&Zn.binding&&Zn.binding("util")}catch(n){}}(),Vn=qn&&qn.isArrayBuffer,Kn=qn&&qn.isDate,Gn=qn&&qn.isMap,Hn=qn&&qn.isRegExp,Jn=qn&&qn.isSet,Yn=qn&&qn.isTypedArray,Qn=b("length"),Xn=x({"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I", +"\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a","\u0106":"C", +"\u0108":"C","\u010a":"C","\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I","\u0129":"i", +"\u012b":"i","\u012d":"i","\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r","\u0159":"r", +"\u015a":"S","\u015c":"S","\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ","\u0133":"ij", +"\u0152":"Oe","\u0153":"oe","\u0149":"'n","\u017f":"s"}),nt=x({"&":"&","<":"<",">":">",'"':""","'":"'"}),tt=x({"&":"&","<":"<",">":">",""":'"',"'":"'"}),rt=function x(mn){function An(n){if(du(n)&&!of(n)&&!(n instanceof Un)){if(n instanceof On)return n;if(ii.call(n,"__wrapped__"))return $e(n)}return new On(n)}function En(){}function On(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=T}function Un(n){this.__wrapped__=n, +this.__actions__=[],this.__dir__=1,this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Mn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t=t?n:t)),n}function _t(n,t,e,u,i,o){var f,c=1&t,a=2&t,l=4&t;if(e&&(f=i?e(n,u,i,o):e(n)),f!==T)return f;if(!gu(n))return n;if(u=of(n)){if(f=me(n),!c)return Ur(n,f)}else{var s=_o(n),h="[object Function]"==s||"[object GeneratorFunction]"==s;if(cf(n))return Ir(n,c);if("[object Object]"==s||"[object Arguments]"==s||h&&!i){if(f=a||h?{}:Ae(n),!c)return a?Mr(n,lt(f,n)):Dr(n,at(f,n))}else{if(!Ln[s])return i?n:{};f=Ee(n,s,c)}}if(o||(o=new Zn), +i=o.get(n))return i;if(o.set(n,f),hf(n))return n.forEach(function(r){f.add(_t(r,t,e,r,n,o))}),f;if(lf(n))return n.forEach(function(r,u){f.set(u,_t(r,t,e,u,n,o))}),f;var a=l?a?ve:_e:a?Wu:zu,p=u?T:a(n);return r(p||n,function(r,u){p&&(u=r,r=n[u]),ot(f,u,_t(r,t,e,u,n,o))}),f}function vt(n){var t=zu(n);return function(r){return gt(r,n,t)}}function gt(n,t,r){var e=r.length;if(null==n)return!e;for(n=Yu(n);e--;){var u=r[e],i=t[u],o=n[u];if(o===T&&!(u in n)||!i(o))return false}return true}function dt(n,t,r){if(typeof n!="function")throw new ni("Expected a function"); +return yo(function(){n.apply(T,r)},t)}function yt(n,t,r,e){var u=-1,i=o,a=true,l=n.length,s=[],h=t.length;if(!l)return s;r&&(t=c(t,k(r))),e?(i=f,a=false):200<=t.length&&(i=O,a=false,t=new Nn(t));n:for(;++ut}function Rt(n,t){return null!=n&&ii.call(n,t)}function zt(n,t){return null!=n&&t in Yu(n)}function Wt(n,t,r){for(var e=r?f:o,u=n[0].length,i=n.length,a=i,l=Vu(i),s=1/0,h=[];a--;){var p=n[a];a&&t&&(p=c(p,k(t))),s=Ui(p.length,s), +l[a]=!r&&(t||120<=u&&120<=p.length)?new Nn(a&&p):T}var p=n[0],_=-1,v=l[0];n:for(;++_r.length?t:kt(t,hr(r,0,-1)),r=null==t?t:t[De(qe(r))],null==r?T:n(r,t,e)}function Ut(n){return du(n)&&"[object Arguments]"==Ot(n)}function Ct(n){ +return du(n)&&"[object ArrayBuffer]"==Ot(n)}function Dt(n){return du(n)&&"[object Date]"==Ot(n)}function Mt(n,t,r,e,u){if(n===t)t=true;else if(null==n||null==t||!du(n)&&!du(t))t=n!==n&&t!==t;else n:{var i=of(n),o=of(t),f=i?"[object Array]":_o(n),c=o?"[object Array]":_o(t),f="[object Arguments]"==f?"[object Object]":f,c="[object Arguments]"==c?"[object Object]":c,a="[object Object]"==f,o="[object Object]"==c;if((c=f==c)&&cf(n)){if(!cf(t)){t=false;break n}i=true,a=false}if(c&&!a)u||(u=new Zn),t=i||pf(n)?se(n,t,r,e,Mt,u):he(n,t,f,r,e,Mt,u);else{ +if(!(1&r)&&(i=a&&ii.call(n,"__wrapped__"),f=o&&ii.call(t,"__wrapped__"),i||f)){n=i?n.value():n,t=f?t.value():t,u||(u=new Zn),t=Mt(n,t,r,e,u);break n}if(c)t:if(u||(u=new Zn),i=1&r,f=_e(n),o=f.length,c=_e(t).length,o==c||i){for(a=o;a--;){var l=f[a];if(!(i?l in t:ii.call(t,l))){t=false;break t}}if((c=u.get(n))&&u.get(t))t=c==t;else{c=true,u.set(n,t),u.set(t,n);for(var s=i;++at?r:0,Se(t,r)?n[t]:T}function Xt(n,t,r){var e=-1;return t=c(t.length?t:[Tu],k(ye())), +n=Gt(n,function(n){return{a:c(t,function(t){return t(n)}),b:++e,c:n}}),w(n,function(n,t){var e;n:{e=-1;for(var u=n.a,i=t.a,o=u.length,f=r.length;++e=f?c:c*("desc"==r[e]?-1:1);break n}}e=n.b-t.b}return e})}function nr(n,t){return tr(n,t,function(t,r){return Ru(n,r)})}function tr(n,t,r){for(var e=-1,u=t.length,i={};++et||9007199254740991t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Vu(u);++e=u){for(;e>>1,o=n[i];null!==o&&!ju(o)&&(r?o<=t:ot.length?n:kt(n,hr(t,0,-1)),null==n||delete n[De(qe(t))]}function jr(n,t,r,e){for(var u=n.length,i=e?u:-1;(e?i--:++ie)return e?br(n[0]):[];for(var u=-1,i=Vu(e);++u=e?n:hr(n,t,r)}function Ir(n,t){if(t)return n.slice();var r=n.length,r=vi?vi(r):new n.constructor(r);return n.copy(r),r}function Rr(n){var t=new n.constructor(n.byteLength);return new _i(t).set(new _i(n)), +t}function zr(n,t){return new n.constructor(t?Rr(n.buffer):n.buffer,n.byteOffset,n.length)}function Wr(n,t){if(n!==t){var r=n!==T,e=null===n,u=n===n,i=ju(n),o=t!==T,f=null===t,c=t===t,a=ju(t);if(!f&&!a&&!i&&n>t||i&&o&&c&&!f&&!a||e&&o&&c||!r&&c||!u)return 1;if(!e&&!i&&!a&&nu?T:i,u=1),t=Yu(t);++eo&&f[0]!==a&&f[o-1]!==a?[]:L(f,a), +o-=c.length,or?r?or(t,n):t:(r=or(t,Si(n/D(t))),Rn.test(t)?Or(M(r),0,n).join(""):r.slice(0,n))}function te(t,r,e,u){function i(){for(var r=-1,c=arguments.length,a=-1,l=u.length,s=Vu(l+c),h=this&&this!==$n&&this instanceof i?f:t;++at||e)&&(1&n&&(i[2]=h[2],t|=1&r?0:4),(r=h[3])&&(e=i[3],i[3]=e?Br(e,r,h[4]):r,i[4]=e?L(i[3],"__lodash_placeholder__"):h[4]),(r=h[5])&&(e=i[5],i[5]=e?Lr(e,r,h[6]):r,i[6]=e?L(i[5],"__lodash_placeholder__"):h[6]),(r=h[7])&&(i[7]=r),128&n&&(i[8]=null==i[8]?h[8]:Ui(i[8],h[8])),null==i[9]&&(i[9]=h[9]),i[0]=h[0],i[1]=t),n=i[0],t=i[1], +r=i[2],e=i[3],u=i[4],f=i[9]=i[9]===T?c?0:n.length:Li(i[9]-a,0),!f&&24&t&&(t&=-25),Le((h?fo:go)(t&&1!=t?8==t||16==t?Kr(n,t,f):32!=t&&33!=t||u.length?Jr.apply(T,i):te(n,t,r,e):Pr(n,t,r),i),n,t)}function ce(n,t,r,e){return n===T||au(n,ri[r])&&!ii.call(e,r)?t:n}function ae(n,t,r,e,u,i){return gu(n)&&gu(t)&&(i.set(t,n),Yt(n,t,T,ae,i),i.delete(t)),n}function le(n){return bu(n)?T:n}function se(n,t,r,e,u,i){var o=1&r,f=n.length,c=t.length;if(f!=c&&!(o&&c>f))return false;if((c=i.get(n))&&i.get(t))return c==t;var c=-1,a=true,l=2&r?new Nn:T; +for(i.set(n,t),i.set(t,n);++cr&&(r=Li(e+r,0)),_(n,ye(t,3),r)):-1}function Ne(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e-1;return r!==T&&(u=Au(r),u=0>r?Li(e+u,0):Ui(u,e-1)),_(n,ye(t,3),u,true)}function Pe(n){return(null==n?0:n.length)?wt(n,1):[]}function Ze(n){ +return n&&n.length?n[0]:T}function qe(n){var t=null==n?0:n.length;return t?n[t-1]:T}function Ve(n,t){return n&&n.length&&t&&t.length?er(n,t):n}function Ke(n){return null==n?n:Ti.call(n)}function Ge(n){if(!n||!n.length)return[];var t=0;return n=i(n,function(n){if(su(n))return t=Li(n.length,t),true}),A(t,function(t){return c(n,b(t))})}function He(t,r){if(!t||!t.length)return[];var e=Ge(t);return null==r?e:c(e,function(t){return n(r,T,t)})}function Je(n){return n=An(n),n.__chain__=true,n}function Ye(n,t){ +return t(n)}function Qe(){return this}function Xe(n,t){return(of(n)?r:eo)(n,ye(t,3))}function nu(n,t){return(of(n)?e:uo)(n,ye(t,3))}function tu(n,t){return(of(n)?c:Gt)(n,ye(t,3))}function ru(n,t,r){return t=r?T:t,t=n&&null==t?n.length:t,fe(n,128,T,T,T,T,t)}function eu(n,t){var r;if(typeof t!="function")throw new ni("Expected a function");return n=Au(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=T),r}}function uu(n,t,r){return t=r?T:t,n=fe(n,8,T,T,T,T,T,t),n.placeholder=uu.placeholder, +n}function iu(n,t,r){return t=r?T:t,n=fe(n,16,T,T,T,T,T,t),n.placeholder=iu.placeholder,n}function ou(n,t,r){function e(t){var r=c,e=a;return c=a=T,_=t,s=n.apply(e,r)}function u(n){var r=n-p;return n-=_,p===T||r>=t||0>r||g&&n>=l}function i(){var n=Ko();if(u(n))return o(n);var r,e=yo;r=n-_,n=t-(n-p),r=g?Ui(n,l-r):n,h=e(i,r)}function o(n){return h=T,d&&c?e(n):(c=a=T,s)}function f(){var n=Ko(),r=u(n);if(c=arguments,a=this,p=n,r){if(h===T)return _=n=p,h=yo(i,t),v?e(n):s;if(g)return h=yo(i,t),e(p)}return h===T&&(h=yo(i,t)), +s}var c,a,l,s,h,p,_=0,v=false,g=false,d=true;if(typeof n!="function")throw new ni("Expected a function");return t=ku(t)||0,gu(r)&&(v=!!r.leading,l=(g="maxWait"in r)?Li(ku(r.maxWait)||0,t):l,d="trailing"in r?!!r.trailing:d),f.cancel=function(){h!==T&&ao(h),_=0,c=p=a=h=T},f.flush=function(){return h===T?s:o(Ko())},f}function fu(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;return i.has(u)?i.get(u):(e=n.apply(this,e),r.cache=i.set(u,e)||i,e)}if(typeof n!="function"||null!=t&&typeof t!="function")throw new ni("Expected a function"); +return r.cache=new(fu.Cache||Fn),r}function cu(n){if(typeof n!="function")throw new ni("Expected a function");return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}function au(n,t){return n===t||n!==n&&t!==t}function lu(n){return null!=n&&vu(n.length)&&!pu(n)}function su(n){return du(n)&&lu(n)}function hu(n){if(!du(n))return false;var t=Ot(n);return"[object Error]"==t||"[object DOMException]"==t||typeof n.message=="string"&&typeof n.name=="string"&&!bu(n); +}function pu(n){return!!gu(n)&&(n=Ot(n),"[object Function]"==n||"[object GeneratorFunction]"==n||"[object AsyncFunction]"==n||"[object Proxy]"==n)}function _u(n){return typeof n=="number"&&n==Au(n)}function vu(n){return typeof n=="number"&&-1=n}function gu(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function du(n){return null!=n&&typeof n=="object"}function yu(n){return typeof n=="number"||du(n)&&"[object Number]"==Ot(n)}function bu(n){return!(!du(n)||"[object Object]"!=Ot(n))&&(n=gi(n), +null===n||(n=ii.call(n,"constructor")&&n.constructor,typeof n=="function"&&n instanceof n&&ui.call(n)==ai))}function xu(n){return typeof n=="string"||!of(n)&&du(n)&&"[object String]"==Ot(n)}function ju(n){return typeof n=="symbol"||du(n)&&"[object Symbol]"==Ot(n)}function wu(n){if(!n)return[];if(lu(n))return xu(n)?M(n):Ur(n);if(ji&&n[ji]){n=n[ji]();for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}return t=_o(n),("[object Map]"==t?W:"[object Set]"==t?U:Lu)(n)}function mu(n){return n?(n=ku(n), +n===$||n===-$?1.7976931348623157e308*(0>n?-1:1):n===n?n:0):0===n?n:0}function Au(n){n=mu(n);var t=n%1;return n===n?t?n-t:n:0}function Eu(n){return n?pt(Au(n),0,4294967295):0}function ku(n){if(typeof n=="number")return n;if(ju(n))return F;if(gu(n)&&(n=typeof n.valueOf=="function"?n.valueOf():n,n=gu(n)?n+"":n),typeof n!="string")return 0===n?n:+n;n=n.replace(un,"");var t=gn.test(n);return t||yn.test(n)?Dn(n.slice(2),t?2:8):vn.test(n)?F:+n}function Su(n){return Cr(n,Wu(n))}function Ou(n){return null==n?"":yr(n); +}function Iu(n,t,r){return n=null==n?T:kt(n,t),n===T?r:n}function Ru(n,t){return null!=n&&we(n,t,zt)}function zu(n){return lu(n)?qn(n):Vt(n)}function Wu(n){if(lu(n))n=qn(n,true);else if(gu(n)){var t,r=ze(n),e=[];for(t in n)("constructor"!=t||!r&&ii.call(n,t))&&e.push(t);n=e}else{if(t=[],null!=n)for(r in Yu(n))t.push(r);n=t}return n}function Bu(n,t){if(null==n)return{};var r=c(ve(n),function(n){return[n]});return t=ye(t),tr(n,r,function(n,r){return t(n,r[0])})}function Lu(n){return null==n?[]:S(n,zu(n)); +}function Uu(n){return Tf(Ou(n).toLowerCase())}function Cu(n){return(n=Ou(n))&&n.replace(xn,Xn).replace(Sn,"")}function Du(n,t,r){return n=Ou(n),t=r?T:t,t===T?zn.test(n)?n.match(In)||[]:n.match(sn)||[]:n.match(t)||[]}function Mu(n){return function(){return n}}function Tu(n){return n}function $u(n){return qt(typeof n=="function"?n:_t(n,1))}function Fu(n,t,e){var u=zu(t),i=Et(t,u);null!=e||gu(t)&&(i.length||!u.length)||(e=t,t=n,n=this,i=Et(t,zu(t)));var o=!(gu(e)&&"chain"in e&&!e.chain),f=pu(n);return r(i,function(r){ +var e=t[r];n[r]=e,f&&(n.prototype[r]=function(){var t=this.__chain__;if(o||t){var r=n(this.__wrapped__);return(r.__actions__=Ur(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,a([this.value()],arguments))})}),n}function Nu(){}function Pu(n){return Ie(n)?b(De(n)):rr(n)}function Zu(){return[]}function qu(){return false}mn=null==mn?$n:rt.defaults($n.Object(),mn,rt.pick($n,Wn));var Vu=mn.Array,Ku=mn.Date,Gu=mn.Error,Hu=mn.Function,Ju=mn.Math,Yu=mn.Object,Qu=mn.RegExp,Xu=mn.String,ni=mn.TypeError,ti=Vu.prototype,ri=Yu.prototype,ei=mn["__core-js_shared__"],ui=Hu.prototype.toString,ii=ri.hasOwnProperty,oi=0,fi=function(){ +var n=/[^.]+$/.exec(ei&&ei.keys&&ei.keys.IE_PROTO||"");return n?"Symbol(src)_1."+n:""}(),ci=ri.toString,ai=ui.call(Yu),li=$n._,si=Qu("^"+ui.call(ii).replace(rn,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),hi=Pn?mn.Buffer:T,pi=mn.Symbol,_i=mn.Uint8Array,vi=hi?hi.g:T,gi=B(Yu.getPrototypeOf,Yu),di=Yu.create,yi=ri.propertyIsEnumerable,bi=ti.splice,xi=pi?pi.isConcatSpreadable:T,ji=pi?pi.iterator:T,wi=pi?pi.toStringTag:T,mi=function(){try{var n=je(Yu,"defineProperty"); +return n({},"",{}),n}catch(n){}}(),Ai=mn.clearTimeout!==$n.clearTimeout&&mn.clearTimeout,Ei=Ku&&Ku.now!==$n.Date.now&&Ku.now,ki=mn.setTimeout!==$n.setTimeout&&mn.setTimeout,Si=Ju.ceil,Oi=Ju.floor,Ii=Yu.getOwnPropertySymbols,Ri=hi?hi.isBuffer:T,zi=mn.isFinite,Wi=ti.join,Bi=B(Yu.keys,Yu),Li=Ju.max,Ui=Ju.min,Ci=Ku.now,Di=mn.parseInt,Mi=Ju.random,Ti=ti.reverse,$i=je(mn,"DataView"),Fi=je(mn,"Map"),Ni=je(mn,"Promise"),Pi=je(mn,"Set"),Zi=je(mn,"WeakMap"),qi=je(Yu,"create"),Vi=Zi&&new Zi,Ki={},Gi=Me($i),Hi=Me(Fi),Ji=Me(Ni),Yi=Me(Pi),Qi=Me(Zi),Xi=pi?pi.prototype:T,no=Xi?Xi.valueOf:T,to=Xi?Xi.toString:T,ro=function(){ +function n(){}return function(t){return gu(t)?di?di(t):(n.prototype=t,t=new n,n.prototype=T,t):{}}}();An.templateSettings={escape:J,evaluate:Y,interpolate:Q,variable:"",imports:{_:An}},An.prototype=En.prototype,An.prototype.constructor=An,On.prototype=ro(En.prototype),On.prototype.constructor=On,Un.prototype=ro(En.prototype),Un.prototype.constructor=Un,Mn.prototype.clear=function(){this.__data__=qi?qi(null):{},this.size=0},Mn.prototype.delete=function(n){return n=this.has(n)&&delete this.__data__[n], +this.size-=n?1:0,n},Mn.prototype.get=function(n){var t=this.__data__;return qi?(n=t[n],"__lodash_hash_undefined__"===n?T:n):ii.call(t,n)?t[n]:T},Mn.prototype.has=function(n){var t=this.__data__;return qi?t[n]!==T:ii.call(t,n)},Mn.prototype.set=function(n,t){var r=this.__data__;return this.size+=this.has(n)?0:1,r[n]=qi&&t===T?"__lodash_hash_undefined__":t,this},Tn.prototype.clear=function(){this.__data__=[],this.size=0},Tn.prototype.delete=function(n){var t=this.__data__;return n=ft(t,n),!(0>n)&&(n==t.length-1?t.pop():bi.call(t,n,1), +--this.size,true)},Tn.prototype.get=function(n){var t=this.__data__;return n=ft(t,n),0>n?T:t[n][1]},Tn.prototype.has=function(n){return-1e?(++this.size,r.push([n,t])):r[e][1]=t,this},Fn.prototype.clear=function(){this.size=0,this.__data__={hash:new Mn,map:new(Fi||Tn),string:new Mn}},Fn.prototype.delete=function(n){return n=be(this,n).delete(n),this.size-=n?1:0,n},Fn.prototype.get=function(n){return be(this,n).get(n); +},Fn.prototype.has=function(n){return be(this,n).has(n)},Fn.prototype.set=function(n,t){var r=be(this,n),e=r.size;return r.set(n,t),this.size+=r.size==e?0:1,this},Nn.prototype.add=Nn.prototype.push=function(n){return this.__data__.set(n,"__lodash_hash_undefined__"),this},Nn.prototype.has=function(n){return this.__data__.has(n)},Zn.prototype.clear=function(){this.__data__=new Tn,this.size=0},Zn.prototype.delete=function(n){var t=this.__data__;return n=t.delete(n),this.size=t.size,n},Zn.prototype.get=function(n){ +return this.__data__.get(n)},Zn.prototype.has=function(n){return this.__data__.has(n)},Zn.prototype.set=function(n,t){var r=this.__data__;if(r instanceof Tn){var e=r.__data__;if(!Fi||199>e.length)return e.push([n,t]),this.size=++r.size,this;r=this.__data__=new Fn(e)}return r.set(n,t),this.size=r.size,this};var eo=Fr(mt),uo=Fr(At,true),io=Nr(),oo=Nr(true),fo=Vi?function(n,t){return Vi.set(n,t),n}:Tu,co=mi?function(n,t){return mi(n,"toString",{configurable:true,enumerable:false,value:Mu(t),writable:true})}:Tu,ao=Ai||function(n){ +return $n.clearTimeout(n)},lo=Pi&&1/U(new Pi([,-0]))[1]==$?function(n){return new Pi(n)}:Nu,so=Vi?function(n){return Vi.get(n)}:Nu,ho=Ii?function(n){return null==n?[]:(n=Yu(n),i(Ii(n),function(t){return yi.call(n,t)}))}:Zu,po=Ii?function(n){for(var t=[];n;)a(t,ho(n)),n=gi(n);return t}:Zu,_o=Ot;($i&&"[object DataView]"!=_o(new $i(new ArrayBuffer(1)))||Fi&&"[object Map]"!=_o(new Fi)||Ni&&"[object Promise]"!=_o(Ni.resolve())||Pi&&"[object Set]"!=_o(new Pi)||Zi&&"[object WeakMap]"!=_o(new Zi))&&(_o=function(n){ +var t=Ot(n);if(n=(n="[object Object]"==t?n.constructor:T)?Me(n):"")switch(n){case Gi:return"[object DataView]";case Hi:return"[object Map]";case Ji:return"[object Promise]";case Yi:return"[object Set]";case Qi:return"[object WeakMap]"}return t});var vo=ei?pu:qu,go=Ue(fo),yo=ki||function(n,t){return $n.setTimeout(n,t)},bo=Ue(co),xo=function(n){n=fu(n,function(n){return 500===t.size&&t.clear(),n});var t=n.cache;return n}(function(n){var t=[];return 46===n.charCodeAt(0)&&t.push(""),n.replace(tn,function(n,r,e,u){ +t.push(e?u.replace(hn,"$1"):r||n)}),t}),jo=fr(function(n,t){return su(n)?yt(n,wt(t,1,su,true)):[]}),wo=fr(function(n,t){var r=qe(t);return su(r)&&(r=T),su(n)?yt(n,wt(t,1,su,true),ye(r,2)):[]}),mo=fr(function(n,t){var r=qe(t);return su(r)&&(r=T),su(n)?yt(n,wt(t,1,su,true),T,r):[]}),Ao=fr(function(n){var t=c(n,Er);return t.length&&t[0]===n[0]?Wt(t):[]}),Eo=fr(function(n){var t=qe(n),r=c(n,Er);return t===qe(r)?t=T:r.pop(),r.length&&r[0]===n[0]?Wt(r,ye(t,2)):[]}),ko=fr(function(n){var t=qe(n),r=c(n,Er);return(t=typeof t=="function"?t:T)&&r.pop(), +r.length&&r[0]===n[0]?Wt(r,T,t):[]}),So=fr(Ve),Oo=pe(function(n,t){var r=null==n?0:n.length,e=ht(n,t);return ur(n,c(t,function(n){return Se(n,r)?+n:n}).sort(Wr)),e}),Io=fr(function(n){return br(wt(n,1,su,true))}),Ro=fr(function(n){var t=qe(n);return su(t)&&(t=T),br(wt(n,1,su,true),ye(t,2))}),zo=fr(function(n){var t=qe(n),t=typeof t=="function"?t:T;return br(wt(n,1,su,true),T,t)}),Wo=fr(function(n,t){return su(n)?yt(n,t):[]}),Bo=fr(function(n){return mr(i(n,su))}),Lo=fr(function(n){var t=qe(n);return su(t)&&(t=T), +mr(i(n,su),ye(t,2))}),Uo=fr(function(n){var t=qe(n),t=typeof t=="function"?t:T;return mr(i(n,su),T,t)}),Co=fr(Ge),Do=fr(function(n){var t=n.length,t=1=t}),uf=Ut(function(){return arguments}())?Ut:function(n){return du(n)&&ii.call(n,"callee")&&!yi.call(n,"callee")},of=Vu.isArray,ff=Vn?k(Vn):Ct,cf=Ri||qu,af=Kn?k(Kn):Dt,lf=Gn?k(Gn):Tt,sf=Hn?k(Hn):Nt,hf=Jn?k(Jn):Pt,pf=Yn?k(Yn):Zt,_f=ee(Kt),vf=ee(function(n,t){return n<=t}),gf=$r(function(n,t){ +if(ze(t)||lu(t))Cr(t,zu(t),n);else for(var r in t)ii.call(t,r)&&ot(n,r,t[r])}),df=$r(function(n,t){Cr(t,Wu(t),n)}),yf=$r(function(n,t,r,e){Cr(t,Wu(t),n,e)}),bf=$r(function(n,t,r,e){Cr(t,zu(t),n,e)}),xf=pe(ht),jf=fr(function(n,t){n=Yu(n);var r=-1,e=t.length,u=2--n)return t.apply(this,arguments)}},An.ary=ru,An.assign=gf,An.assignIn=df,An.assignInWith=yf,An.assignWith=bf,An.at=xf,An.before=eu,An.bind=Go,An.bindAll=Ff,An.bindKey=Ho,An.castArray=function(){if(!arguments.length)return[];var n=arguments[0];return of(n)?n:[n]},An.chain=Je,An.chunk=function(n,t,r){if(t=(r?Oe(n,t,r):t===T)?1:Li(Au(t),0),r=null==n?0:n.length,!r||1>t)return[];for(var e=0,u=0,i=Vu(Si(r/t));et?0:t,e)):[]},An.dropRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Au(t),t=e-t,hr(n,0,0>t?0:t)):[]},An.dropRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true,true):[]; +},An.dropWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true):[]},An.fill=function(n,t,r,e){var u=null==n?0:n.length;if(!u)return[];for(r&&typeof r!="number"&&Oe(n,t,r)&&(r=0,e=u),u=n.length,r=Au(r),0>r&&(r=-r>u?0:u+r),e=e===T||e>u?u:Au(e),0>e&&(e+=u),e=r>e?0:Eu(e);r>>0,r?(n=Ou(n))&&(typeof t=="string"||null!=t&&!sf(t))&&(t=yr(t),!t&&Rn.test(n))?Or(M(n),0,r):n.split(t,r):[]},An.spread=function(t,r){if(typeof t!="function")throw new ni("Expected a function");return r=null==r?0:Li(Au(r),0), +fr(function(e){var u=e[r];return e=Or(e,0,r),u&&a(e,u),n(t,this,e)})},An.tail=function(n){var t=null==n?0:n.length;return t?hr(n,1,t):[]},An.take=function(n,t,r){return n&&n.length?(t=r||t===T?1:Au(t),hr(n,0,0>t?0:t)):[]},An.takeRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Au(t),t=e-t,hr(n,0>t?0:t,e)):[]},An.takeRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),false,true):[]},An.takeWhile=function(n,t){return n&&n.length?jr(n,ye(t,3)):[]},An.tap=function(n,t){return t(n), +n},An.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new ni("Expected a function");return gu(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),ou(n,t,{leading:e,maxWait:t,trailing:u})},An.thru=Ye,An.toArray=wu,An.toPairs=Rf,An.toPairsIn=zf,An.toPath=function(n){return of(n)?c(n,De):ju(n)?[n]:Ur(xo(Ou(n)))},An.toPlainObject=Su,An.transform=function(n,t,e){var u=of(n),i=u||cf(n)||pf(n);if(t=ye(t,4),null==e){var o=n&&n.constructor;e=i?u?new o:[]:gu(n)&&pu(o)?ro(gi(n)):{}; +}return(i?r:mt)(n,function(n,r,u){return t(e,n,r,u)}),e},An.unary=function(n){return ru(n,1)},An.union=Io,An.unionBy=Ro,An.unionWith=zo,An.uniq=function(n){return n&&n.length?br(n):[]},An.uniqBy=function(n,t){return n&&n.length?br(n,ye(t,2)):[]},An.uniqWith=function(n,t){return t=typeof t=="function"?t:T,n&&n.length?br(n,T,t):[]},An.unset=function(n,t){return null==n||xr(n,t)},An.unzip=Ge,An.unzipWith=He,An.update=function(n,t,r){return null==n?n:lr(n,t,kr(r)(kt(n,t)),void 0)},An.updateWith=function(n,t,r,e){ +return e=typeof e=="function"?e:T,null!=n&&(n=lr(n,t,kr(r)(kt(n,t)),e)),n},An.values=Lu,An.valuesIn=function(n){return null==n?[]:S(n,Wu(n))},An.without=Wo,An.words=Du,An.wrap=function(n,t){return Xo(kr(t),n)},An.xor=Bo,An.xorBy=Lo,An.xorWith=Uo,An.zip=Co,An.zipObject=function(n,t){return Ar(n||[],t||[],ot)},An.zipObjectDeep=function(n,t){return Ar(n||[],t||[],lr)},An.zipWith=Do,An.entries=Rf,An.entriesIn=zf,An.extend=df,An.extendWith=yf,Fu(An,An),An.add=Yf,An.attempt=$f,An.camelCase=Wf,An.capitalize=Uu, +An.ceil=Qf,An.clamp=function(n,t,r){return r===T&&(r=t,t=T),r!==T&&(r=ku(r),r=r===r?r:0),t!==T&&(t=ku(t),t=t===t?t:0),pt(ku(n),t,r)},An.clone=function(n){return _t(n,4)},An.cloneDeep=function(n){return _t(n,5)},An.cloneDeepWith=function(n,t){return t=typeof t=="function"?t:T,_t(n,5,t)},An.cloneWith=function(n,t){return t=typeof t=="function"?t:T,_t(n,4,t)},An.conformsTo=function(n,t){return null==t||gt(n,t,zu(t))},An.deburr=Cu,An.defaultTo=function(n,t){return null==n||n!==n?t:n},An.divide=Xf,An.endsWith=function(n,t,r){ +n=Ou(n),t=yr(t);var e=n.length,e=r=r===T?e:pt(Au(r),0,e);return r-=t.length,0<=r&&n.slice(r,e)==t},An.eq=au,An.escape=function(n){return(n=Ou(n))&&H.test(n)?n.replace(K,nt):n},An.escapeRegExp=function(n){return(n=Ou(n))&&en.test(n)?n.replace(rn,"\\$&"):n},An.every=function(n,t,r){var e=of(n)?u:bt;return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.find=$o,An.findIndex=Fe,An.findKey=function(n,t){return p(n,ye(t,3),mt)},An.findLast=Fo,An.findLastIndex=Ne,An.findLastKey=function(n,t){return p(n,ye(t,3),At); +},An.floor=nc,An.forEach=Xe,An.forEachRight=nu,An.forIn=function(n,t){return null==n?n:io(n,ye(t,3),Wu)},An.forInRight=function(n,t){return null==n?n:oo(n,ye(t,3),Wu)},An.forOwn=function(n,t){return n&&mt(n,ye(t,3))},An.forOwnRight=function(n,t){return n&&At(n,ye(t,3))},An.get=Iu,An.gt=rf,An.gte=ef,An.has=function(n,t){return null!=n&&we(n,t,Rt)},An.hasIn=Ru,An.head=Ze,An.identity=Tu,An.includes=function(n,t,r,e){return n=lu(n)?n:Lu(n),r=r&&!e?Au(r):0,e=n.length,0>r&&(r=Li(e+r,0)),xu(n)?r<=e&&-1r&&(r=Li(e+r,0)),v(n,t,r)):-1},An.inRange=function(n,t,r){return t=mu(t),r===T?(r=t,t=0):r=mu(r),n=ku(n),n>=Ui(t,r)&&n=n},An.isSet=hf,An.isString=xu,An.isSymbol=ju,An.isTypedArray=pf,An.isUndefined=function(n){return n===T},An.isWeakMap=function(n){return du(n)&&"[object WeakMap]"==_o(n)},An.isWeakSet=function(n){return du(n)&&"[object WeakSet]"==Ot(n)},An.join=function(n,t){return null==n?"":Wi.call(n,t)},An.kebabCase=Bf,An.last=qe,An.lastIndexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;if(r!==T&&(u=Au(r),u=0>u?Li(e+u,0):Ui(u,e-1)), +t===t){for(r=u+1;r--&&n[r]!==t;);n=r}else n=_(n,d,u,true);return n},An.lowerCase=Lf,An.lowerFirst=Uf,An.lt=_f,An.lte=vf,An.max=function(n){return n&&n.length?xt(n,Tu,It):T},An.maxBy=function(n,t){return n&&n.length?xt(n,ye(t,2),It):T},An.mean=function(n){return y(n,Tu)},An.meanBy=function(n,t){return y(n,ye(t,2))},An.min=function(n){return n&&n.length?xt(n,Tu,Kt):T},An.minBy=function(n,t){return n&&n.length?xt(n,ye(t,2),Kt):T},An.stubArray=Zu,An.stubFalse=qu,An.stubObject=function(){return{}},An.stubString=function(){ +return""},An.stubTrue=function(){return true},An.multiply=tc,An.nth=function(n,t){return n&&n.length?Qt(n,Au(t)):T},An.noConflict=function(){return $n._===this&&($n._=li),this},An.noop=Nu,An.now=Ko,An.pad=function(n,t,r){n=Ou(n);var e=(t=Au(t))?D(n):0;return!t||e>=t?n:(t=(t-e)/2,ne(Oi(t),r)+n+ne(Si(t),r))},An.padEnd=function(n,t,r){n=Ou(n);var e=(t=Au(t))?D(n):0;return t&&et){var e=n;n=t,t=e}return r||n%1||t%1?(r=Mi(),Ui(n+r*(t-n+Cn("1e-"+((r+"").length-1))),t)):ir(n,t)},An.reduce=function(n,t,r){var e=of(n)?l:j,u=3>arguments.length;return e(n,ye(t,4),r,u,eo)},An.reduceRight=function(n,t,r){var e=of(n)?s:j,u=3>arguments.length; +return e(n,ye(t,4),r,u,uo)},An.repeat=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:Au(t),or(Ou(n),t)},An.replace=function(){var n=arguments,t=Ou(n[0]);return 3>n.length?t:t.replace(n[1],n[2])},An.result=function(n,t,r){t=Sr(t,n);var e=-1,u=t.length;for(u||(u=1,n=T);++en||9007199254740991=i)return n;if(i=r-D(e),1>i)return e;if(r=o?Or(o,0,i).join(""):n.slice(0,i),u===T)return r+e;if(o&&(i+=r.length-i),sf(u)){if(n.slice(i).search(u)){var f=r;for(u.global||(u=Qu(u.source,Ou(_n.exec(u))+"g")), +u.lastIndex=0;o=u.exec(f);)var c=o.index;r=r.slice(0,c===T?i:c)}}else n.indexOf(yr(u),i)!=i&&(u=r.lastIndexOf(u),-1e.__dir__?"Right":"")}),e},Un.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),r(["filter","map","takeWhile"],function(n,t){var r=t+1,e=1==r||3==r;Un.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({ +iteratee:ye(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),r(["head","last"],function(n,t){var r="take"+(t?"Right":"");Un.prototype[n]=function(){return this[r](1).value()[0]}}),r(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");Un.prototype[n]=function(){return this.__filtered__?new Un(this):this[r](1)}}),Un.prototype.compact=function(){return this.filter(Tu)},Un.prototype.find=function(n){return this.filter(n).head()},Un.prototype.findLast=function(n){return this.reverse().find(n); +},Un.prototype.invokeMap=fr(function(n,t){return typeof n=="function"?new Un(this):this.map(function(r){return Lt(r,n,t)})}),Un.prototype.reject=function(n){return this.filter(cu(ye(n)))},Un.prototype.slice=function(n,t){n=Au(n);var r=this;return r.__filtered__&&(0t)?new Un(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==T&&(t=Au(t),r=0>t?r.dropRight(-t):r.take(t-n)),r)},Un.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},Un.prototype.toArray=function(){return this.take(4294967295); +},mt(Un.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=An[e?"take"+("last"==t?"Right":""):t],i=e||/^find/.test(t);u&&(An.prototype[t]=function(){function t(n){return n=u.apply(An,a([n],f)),e&&h?n[0]:n}var o=this.__wrapped__,f=e?[1]:arguments,c=o instanceof Un,l=f[0],s=c||of(o);s&&r&&typeof l=="function"&&1!=l.length&&(c=s=false);var h=this.__chain__,p=!!this.__actions__.length,l=i&&!h,c=c&&!p;return!i&&s?(o=c?o:new Un(this),o=n.apply(o,f),o.__actions__.push({ +func:Ye,args:[t],thisArg:T}),new On(o,h)):l&&c?n.apply(this,f):(o=this.thru(t),l?e?o.value()[0]:o.value():o)})}),r("pop push shift sort splice unshift".split(" "),function(n){var t=ti[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);An.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var u=this.value();return t.apply(of(u)?u:[],n)}return this[r](function(r){return t.apply(of(r)?r:[],n)})}}),mt(Un.prototype,function(n,t){var r=An[t];if(r){var e=r.name+""; +(Ki[e]||(Ki[e]=[])).push({name:t,func:r})}}),Ki[Jr(T,2).name]=[{name:"wrapper",func:T}],Un.prototype.clone=function(){var n=new Un(this.__wrapped__);return n.__actions__=Ur(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Ur(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=Ur(this.__views__),n},Un.prototype.reverse=function(){if(this.__filtered__){var n=new Un(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n; +},Un.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=of(t),u=0>r,i=e?t.length:0;n=i;for(var o=this.__views__,f=0,c=-1,a=o.length;++c=this.__values__.length;return{done:n,value:n?T:this.__values__[this.__index__++]}},An.prototype.plant=function(n){for(var t,r=this;r instanceof En;){ +var e=$e(r);e.__index__=0,e.__values__=T,t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},An.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Un?(this.__actions__.length&&(n=new Un(this)),n=n.reverse(),n.__actions__.push({func:Ye,args:[Ke],thisArg:T}),new On(n,this.__chain__)):this.thru(Ke)},An.prototype.toJSON=An.prototype.valueOf=An.prototype.value=function(){return wr(this.__wrapped__,this.__actions__)},An.prototype.first=An.prototype.head,ji&&(An.prototype[ji]=Qe), +An}();typeof define=="function"&&typeof define.amd=="object"&&define.amd?($n._=rt, define(function(){return rt})):Nn?((Nn.exports=rt)._=rt,Fn._=rt):$n._=rt}).call(this); diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/md5-2.10.0.min.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/md5-2.10.0.min.js new file mode 100644 index 000000000..7d8a3f53c --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/md5-2.10.0.min.js @@ -0,0 +1,2 @@ +!function(n){"use strict";function t(n,t){var r=(65535&n)+(65535&t);return(n>>16)+(t>>16)+(r>>16)<<16|65535&r}function r(n,t){return n<>>32-t}function e(n,e,o,u,c,f){return t(r(t(t(e,n),t(u,f)),c),o)}function o(n,t,r,o,u,c,f){return e(t&r|~t&o,n,t,u,c,f)}function u(n,t,r,o,u,c,f){return e(t&o|r&~o,n,t,u,c,f)}function c(n,t,r,o,u,c,f){return e(t^r^o,n,t,u,c,f)}function f(n,t,r,o,u,c,f){return e(r^(t|~o),n,t,u,c,f)}function i(n,r){n[r>>5]|=128<>>9<<4)]=r;var e,i,a,d,h,l=1732584193,g=-271733879,v=-1732584194,m=271733878;for(e=0;e>5]>>>t%32&255);return r}function d(n){var t,r=[];for(r[(n.length>>2)-1]=void 0,t=0;t>5]|=(255&n.charCodeAt(t/8))<16&&(o=i(o,8*n.length)),r=0;r<16;r+=1)u[r]=909522486^o[r],c[r]=1549556828^o[r];return e=i(u.concat(d(t)),512+8*t.length),a(i(c.concat(e),640))}function g(n){var t,r,e="";for(r=0;r>>4&15)+"0123456789abcdef".charAt(15&t);return e}function v(n){return unescape(encodeURIComponent(n))}function m(n){return h(v(n))}function p(n){return g(m(n))}function s(n,t){return l(v(n),v(t))}function C(n,t){return g(s(n,t))}function A(n,t,r){return t?r?s(t,n):C(t,n):r?m(n):p(n)}"function"==typeof define&&define.amd?define(function(){return A}):"object"==typeof module&&module.exports?module.exports=A:n.md5=A}(this); +//# sourceMappingURL=md5.min.js.map \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/sweetalert2-7.28.4.all.min.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/sweetalert2-7.28.4.all.min.js new file mode 100644 index 000000000..984375b41 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/sweetalert2-7.28.4.all.min.js @@ -0,0 +1,2 @@ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Sweetalert2=t()}(this,function(){"use strict";function V(e){return(V="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e})(e)}function s(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){for(var n=0;n\n
      \n
        \n
        \n \n
        \n
        \n ?\n
        \n
        \n !\n
        \n
        \n i\n
        \n
        \n
        \n \n
        \n
        \n
        \n \n

        \n \n
        \n
        \n
        \n \n \n
        \n \n \n
        \n \n
        \n \n \n
        \n
        \n
        \n \n \n
        \n
        \n
        \n \n').replace(/(^|\n)\s*/g,""),X=function(e){var t=w();if(t&&(t.parentNode.removeChild(t),W([document.documentElement,document.body],[_["no-backdrop"],_["toast-shown"],_["has-column"]])),!j()){var n=document.createElement("div");n.className=_.container,n.innerHTML=M,("string"==typeof e.target?document.querySelector(e.target):e.target).appendChild(n);var o,i=k(),r=B(),a=z(r,_.input),s=z(r,_.file),c=r.querySelector(".".concat(_.range," input")),u=r.querySelector(".".concat(_.range," output")),l=z(r,_.select),d=r.querySelector(".".concat(_.checkbox," input")),p=z(r,_.textarea);i.setAttribute("role",e.toast?"alert":"dialog"),i.setAttribute("aria-live",e.toast?"polite":"assertive"),e.toast||i.setAttribute("aria-modal","true");var f=function(e){He.isVisible()&&o!==e.target.value&&He.resetValidationMessage(),o=e.target.value};return a.oninput=f,s.onchange=f,l.onchange=f,d.onchange=f,p.oninput=f,c.oninput=function(e){f(e),u.value=c.value},c.onchange=function(e){f(e),c.nextSibling.value=c.value},i}R("SweetAlert2 requires document to initialize")},G=function(e,t){if(!e)return K(t);if("object"===V(e))if(t.innerHTML="",0 in e)for(var n=0;n in e;n++)t.appendChild(e[n].cloneNode(!0));else t.appendChild(e.cloneNode(!0));else e&&(t.innerHTML=e);U(t)},ee=function(){if(j())return!1;var e=document.createElement("div"),t={WebkitAnimation:"webkitAnimationEnd",OAnimation:"oAnimationEnd oanimationend",animation:"animationend"};for(var n in t)if(t.hasOwnProperty(n)&&void 0!==e.style[n])return t[n];return!1}(),te=function(e){var t=Q(),n=E(),o=Z();if(e.showConfirmButton||e.showCancelButton?U(t):K(t),e.showCancelButton?o.style.display="inline-block":K(o),e.showConfirmButton?n.style.removeProperty("display"):K(n),n.innerHTML=e.confirmButtonText,o.innerHTML=e.cancelButtonText,n.setAttribute("aria-label",e.confirmButtonAriaLabel),o.setAttribute("aria-label",e.cancelButtonAriaLabel),n.className=_.confirm,N(n,e.confirmButtonClass),o.className=_.cancel,N(o,e.cancelButtonClass),e.buttonsStyling){N([n,o],_.styled),e.confirmButtonColor&&(n.style.backgroundColor=e.confirmButtonColor),e.cancelButtonColor&&(o.style.backgroundColor=e.cancelButtonColor);var i=window.getComputedStyle(n).getPropertyValue("background-color");n.style.borderLeftColor=i,n.style.borderRightColor=i}else W([n,o],_.styled),n.style.backgroundColor=n.style.borderLeftColor=n.style.borderRightColor="",o.style.backgroundColor=o.style.borderLeftColor=o.style.borderRightColor=""},ne=function(e){var t=B().querySelector("#"+_.content);e.html?G(e.html,t):e.text?(t.textContent=e.text,U(t)):K(t)},oe=function(e){for(var t=x(),n=0;n=i.progressSteps.length&&q("Invalid currentProgressStep parameter, it should be less than progressSteps.length (currentProgressStep like JS arrays starts from 0)"),i.progressSteps.forEach(function(e,t){var n=document.createElement("li");if(N(n,_.progresscircle),n.innerHTML=e,t===a&&N(n,_.activeprogressstep),r.appendChild(n),t!==i.progressSteps.length-1){var o=document.createElement("li");N(o,_.progressline),i.progressStepsDistance&&(o.style.width=i.progressStepsDistance),r.appendChild(o)}})):K(r)},ae=function(e){var t=A();e.titleText?t.innerText=e.titleText:e.title&&("string"==typeof e.title&&(e.title=e.title.split("\n").join("
        ")),G(e.title,t))},se=function(){null===b.previousBodyPadding&&document.body.scrollHeight>window.innerHeight&&(b.previousBodyPadding=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right")),document.body.style.paddingRight=b.previousBodyPadding+function(){if("ontouchstart"in window||navigator.msMaxTouchPoints)return 0;var e=document.createElement("div");e.style.width="50px",e.style.height="50px",e.style.overflow="scroll",document.body.appendChild(e);var t=e.offsetWidth-e.clientWidth;return document.body.removeChild(e),t}()+"px")},ce={},ue=function(e,t){var n=w(),o=k();if(o){null!==e&&"function"==typeof e&&e(o),W(o,_.show),N(o,_.hide);var i=function(){T()?le(t):(new Promise(function(e){var t=window.scrollX,n=window.scrollY;ce.restoreFocusTimeout=setTimeout(function(){ce.previousActiveElement&&ce.previousActiveElement.focus?(ce.previousActiveElement.focus(),ce.previousActiveElement=null):document.body&&document.body.focus(),e()},100),void 0!==t&&void 0!==n&&window.scrollTo(t,n)}).then(function(){return le(t)}),ce.keydownTarget.removeEventListener("keydown",ce.keydownHandler,{capture:ce.keydownListenerCapture}),ce.keydownHandlerAdded=!1),n.parentNode&&n.parentNode.removeChild(n),W([document.documentElement,document.body],[_.shown,_["height-auto"],_["no-backdrop"],_["toast-shown"],_["toast-column"]]),L()&&(null!==b.previousBodyPadding&&(document.body.style.paddingRight=b.previousBodyPadding,b.previousBodyPadding=null),function(){if(v(document.body,_.iosfix)){var e=parseInt(document.body.style.top,10);W(document.body,_.iosfix),document.body.style.top="",document.body.scrollTop=-1*e}}(),f(document.body.children).forEach(function(e){e.hasAttribute("data-previous-aria-hidden")?(e.setAttribute("aria-hidden",e.getAttribute("data-previous-aria-hidden")),e.removeAttribute("data-previous-aria-hidden")):e.removeAttribute("aria-hidden")}))};ee&&!v(o,_.noanimation)?o.addEventListener(ee,function e(){o.removeEventListener(ee,e),v(o,_.hide)&&i()}):i()}},le=function(e){null!==e&&"function"==typeof e&&setTimeout(function(){e()})};function de(e){var t=function e(){for(var t=arguments.length,n=new Array(t),o=0;o.swal2-modal{box-shadow:0 0 10px rgba(0,0,0,.4)}body.swal2-no-backdrop .swal2-shown.swal2-top{top:0;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}body.swal2-no-backdrop .swal2-shown.swal2-top-left,body.swal2-no-backdrop .swal2-shown.swal2-top-start{top:0;left:0}body.swal2-no-backdrop .swal2-shown.swal2-top-end,body.swal2-no-backdrop .swal2-shown.swal2-top-right{top:0;right:0}body.swal2-no-backdrop .swal2-shown.swal2-center{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}body.swal2-no-backdrop .swal2-shown.swal2-center-left,body.swal2-no-backdrop .swal2-shown.swal2-center-start{top:50%;left:0;-webkit-transform:translateY(-50%);transform:translateY(-50%)}body.swal2-no-backdrop .swal2-shown.swal2-center-end,body.swal2-no-backdrop .swal2-shown.swal2-center-right{top:50%;right:0;-webkit-transform:translateY(-50%);transform:translateY(-50%)}body.swal2-no-backdrop .swal2-shown.swal2-bottom{bottom:0;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}body.swal2-no-backdrop .swal2-shown.swal2-bottom-left,body.swal2-no-backdrop .swal2-shown.swal2-bottom-start{bottom:0;left:0}body.swal2-no-backdrop .swal2-shown.swal2-bottom-end,body.swal2-no-backdrop .swal2-shown.swal2-bottom-right{right:0;bottom:0}.swal2-container{display:flex;position:fixed;top:0;right:0;bottom:0;left:0;flex-direction:row;align-items:center;justify-content:center;padding:10px;background-color:transparent;z-index:1060;overflow-x:hidden;-webkit-overflow-scrolling:touch}.swal2-container.swal2-top{align-items:flex-start}.swal2-container.swal2-top-left,.swal2-container.swal2-top-start{align-items:flex-start;justify-content:flex-start}.swal2-container.swal2-top-end,.swal2-container.swal2-top-right{align-items:flex-start;justify-content:flex-end}.swal2-container.swal2-center{align-items:center}.swal2-container.swal2-center-left,.swal2-container.swal2-center-start{align-items:center;justify-content:flex-start}.swal2-container.swal2-center-end,.swal2-container.swal2-center-right{align-items:center;justify-content:flex-end}.swal2-container.swal2-bottom{align-items:flex-end}.swal2-container.swal2-bottom-left,.swal2-container.swal2-bottom-start{align-items:flex-end;justify-content:flex-start}.swal2-container.swal2-bottom-end,.swal2-container.swal2-bottom-right{align-items:flex-end;justify-content:flex-end}.swal2-container.swal2-grow-fullscreen>.swal2-modal{display:flex!important;flex:1;align-self:stretch;justify-content:center}.swal2-container.swal2-grow-row>.swal2-modal{display:flex!important;flex:1;align-content:center;justify-content:center}.swal2-container.swal2-grow-column{flex:1;flex-direction:column}.swal2-container.swal2-grow-column.swal2-bottom,.swal2-container.swal2-grow-column.swal2-center,.swal2-container.swal2-grow-column.swal2-top{align-items:center}.swal2-container.swal2-grow-column.swal2-bottom-left,.swal2-container.swal2-grow-column.swal2-bottom-start,.swal2-container.swal2-grow-column.swal2-center-left,.swal2-container.swal2-grow-column.swal2-center-start,.swal2-container.swal2-grow-column.swal2-top-left,.swal2-container.swal2-grow-column.swal2-top-start{align-items:flex-start}.swal2-container.swal2-grow-column.swal2-bottom-end,.swal2-container.swal2-grow-column.swal2-bottom-right,.swal2-container.swal2-grow-column.swal2-center-end,.swal2-container.swal2-grow-column.swal2-center-right,.swal2-container.swal2-grow-column.swal2-top-end,.swal2-container.swal2-grow-column.swal2-top-right{align-items:flex-end}.swal2-container.swal2-grow-column>.swal2-modal{display:flex!important;flex:1;align-content:center;justify-content:center}.swal2-container:not(.swal2-top):not(.swal2-top-start):not(.swal2-top-end):not(.swal2-top-left):not(.swal2-top-right):not(.swal2-center-start):not(.swal2-center-end):not(.swal2-center-left):not(.swal2-center-right):not(.swal2-bottom):not(.swal2-bottom-start):not(.swal2-bottom-end):not(.swal2-bottom-left):not(.swal2-bottom-right):not(.swal2-grow-fullscreen)>.swal2-modal{margin:auto}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.swal2-container .swal2-modal{margin:0!important}}.swal2-container.swal2-fade{transition:background-color .1s}.swal2-container.swal2-shown{background-color:rgba(0,0,0,.4)}.swal2-popup{display:none;position:relative;flex-direction:column;justify-content:center;width:32em;max-width:100%;padding:1.25em;border-radius:.3125em;background:#fff;font-family:inherit;font-size:1rem;box-sizing:border-box}.swal2-popup:focus{outline:0}.swal2-popup.swal2-loading{overflow-y:hidden}.swal2-popup .swal2-header{display:flex;flex-direction:column;align-items:center}.swal2-popup .swal2-title{display:block;position:relative;max-width:100%;margin:0 0 .4em;padding:0;color:#595959;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word}.swal2-popup .swal2-actions{flex-wrap:wrap;align-items:center;justify-content:center;margin:1.25em auto 0;z-index:1}.swal2-popup .swal2-actions:not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}.swal2-popup .swal2-actions:not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0,0,0,.1),rgba(0,0,0,.1))}.swal2-popup .swal2-actions:not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.2))}.swal2-popup .swal2-actions.swal2-loading .swal2-styled.swal2-confirm{width:2.5em;height:2.5em;margin:.46875em;padding:0;border:.25em solid transparent;border-radius:100%;border-color:transparent;background-color:transparent!important;color:transparent;cursor:default;box-sizing:border-box;-webkit-animation:swal2-rotate-loading 1.5s linear 0s infinite normal;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.swal2-popup .swal2-actions.swal2-loading .swal2-styled.swal2-cancel{margin-right:30px;margin-left:30px}.swal2-popup .swal2-actions.swal2-loading :not(.swal2-styled).swal2-confirm::after{display:inline-block;width:15px;height:15px;margin-left:5px;border:3px solid #999;border-radius:50%;border-right-color:transparent;box-shadow:1px 1px 1px #fff;content:'';-webkit-animation:swal2-rotate-loading 1.5s linear 0s infinite normal;animation:swal2-rotate-loading 1.5s linear 0s infinite normal}.swal2-popup .swal2-styled{margin:.3125em;padding:.625em 2em;font-weight:500;box-shadow:none}.swal2-popup .swal2-styled:not([disabled]){cursor:pointer}.swal2-popup .swal2-styled.swal2-confirm{border:0;border-radius:.25em;background:initial;background-color:#3085d6;color:#fff;font-size:1.0625em}.swal2-popup .swal2-styled.swal2-cancel{border:0;border-radius:.25em;background:initial;background-color:#aaa;color:#fff;font-size:1.0625em}.swal2-popup .swal2-styled:focus{outline:0;box-shadow:0 0 0 2px #fff,0 0 0 4px rgba(50,100,150,.4)}.swal2-popup .swal2-styled::-moz-focus-inner{border:0}.swal2-popup .swal2-footer{justify-content:center;margin:1.25em 0 0;padding:1em 0 0;border-top:1px solid #eee;color:#545454;font-size:1em}.swal2-popup .swal2-image{max-width:100%;margin:1.25em auto}.swal2-popup .swal2-close{position:absolute;top:0;right:0;justify-content:center;width:1.2em;height:1.2em;padding:0;transition:color .1s ease-out;border:none;border-radius:0;background:0 0;color:#ccc;font-family:serif;font-size:2.5em;line-height:1.2;cursor:pointer;overflow:hidden}.swal2-popup .swal2-close:hover{-webkit-transform:none;transform:none;color:#f27474}.swal2-popup>.swal2-checkbox,.swal2-popup>.swal2-file,.swal2-popup>.swal2-input,.swal2-popup>.swal2-radio,.swal2-popup>.swal2-select,.swal2-popup>.swal2-textarea{display:none}.swal2-popup .swal2-content{justify-content:center;margin:0;padding:0;color:#545454;font-size:1.125em;font-weight:300;line-height:normal;z-index:1;word-wrap:break-word}.swal2-popup #swal2-content{text-align:center}.swal2-popup .swal2-checkbox,.swal2-popup .swal2-file,.swal2-popup .swal2-input,.swal2-popup .swal2-radio,.swal2-popup .swal2-select,.swal2-popup .swal2-textarea{margin:1em auto}.swal2-popup .swal2-file,.swal2-popup .swal2-input,.swal2-popup .swal2-textarea{width:100%;transition:border-color .3s,box-shadow .3s;border:1px solid #d9d9d9;border-radius:.1875em;font-size:1.125em;box-shadow:inset 0 1px 1px rgba(0,0,0,.06);box-sizing:border-box}.swal2-popup .swal2-file.swal2-inputerror,.swal2-popup .swal2-input.swal2-inputerror,.swal2-popup .swal2-textarea.swal2-inputerror{border-color:#f27474!important;box-shadow:0 0 2px #f27474!important}.swal2-popup .swal2-file:focus,.swal2-popup .swal2-input:focus,.swal2-popup .swal2-textarea:focus{border:1px solid #b4dbed;outline:0;box-shadow:0 0 3px #c4e6f5}.swal2-popup .swal2-file::-webkit-input-placeholder,.swal2-popup .swal2-input::-webkit-input-placeholder,.swal2-popup .swal2-textarea::-webkit-input-placeholder{color:#ccc}.swal2-popup .swal2-file:-ms-input-placeholder,.swal2-popup .swal2-input:-ms-input-placeholder,.swal2-popup .swal2-textarea:-ms-input-placeholder{color:#ccc}.swal2-popup .swal2-file::-ms-input-placeholder,.swal2-popup .swal2-input::-ms-input-placeholder,.swal2-popup .swal2-textarea::-ms-input-placeholder{color:#ccc}.swal2-popup .swal2-file::placeholder,.swal2-popup .swal2-input::placeholder,.swal2-popup .swal2-textarea::placeholder{color:#ccc}.swal2-popup .swal2-range input{width:80%}.swal2-popup .swal2-range output{width:20%;font-weight:600;text-align:center}.swal2-popup .swal2-range input,.swal2-popup .swal2-range output{height:2.625em;margin:1em auto;padding:0;font-size:1.125em;line-height:2.625em}.swal2-popup .swal2-input{height:2.625em;padding:0 .75em}.swal2-popup .swal2-input[type=number]{max-width:10em}.swal2-popup .swal2-file{font-size:1.125em}.swal2-popup .swal2-textarea{height:6.75em;padding:.75em}.swal2-popup .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;color:#545454;font-size:1.125em}.swal2-popup .swal2-checkbox,.swal2-popup .swal2-radio{align-items:center;justify-content:center}.swal2-popup .swal2-checkbox label,.swal2-popup .swal2-radio label{margin:0 .6em;font-size:1.125em}.swal2-popup .swal2-checkbox input,.swal2-popup .swal2-radio input{margin:0 .4em}.swal2-popup .swal2-validation-message{display:none;align-items:center;justify-content:center;padding:.625em;background:#f0f0f0;color:#666;font-size:1em;font-weight:300;overflow:hidden}.swal2-popup .swal2-validation-message::before{display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center;content:'!';zoom:normal}@supports (-ms-accelerator:true){.swal2-range input{width:100%!important}.swal2-range output{display:none}}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.swal2-range input{width:100%!important}.swal2-range output{display:none}}@-moz-document url-prefix(){.swal2-close:focus{outline:2px solid rgba(50,100,150,.4)}}.swal2-icon{position:relative;justify-content:center;width:5em;height:5em;margin:1.25em auto 1.875em;border:.25em solid transparent;border-radius:50%;line-height:5em;cursor:default;box-sizing:content-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;zoom:normal}.swal2-icon-text{font-size:3.75em}.swal2-icon.swal2-error{border-color:#f27474}.swal2-icon.swal2-error .swal2-x-mark{position:relative;flex-grow:1}.swal2-icon.swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.swal2-icon.swal2-warning{border-color:#facea8;color:#f8bb86}.swal2-icon.swal2-info{border-color:#9de0f6;color:#3fc3ee}.swal2-icon.swal2-question{border-color:#c9dae1;color:#87adbd}.swal2-icon.swal2-success{border-color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;-webkit-transform:rotate(45deg);transform:rotate(45deg);border-radius:50%}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=left]{top:-.4375em;left:-2.0635em;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:3.75em 3.75em;transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=right]{top:-.6875em;left:1.875em;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:0 3.75em;transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}.swal2-icon.swal2-success .swal2-success-ring{position:absolute;top:-.25em;left:-.25em;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%;z-index:2;box-sizing:content-box}.swal2-icon.swal2-success .swal2-success-fix{position:absolute;top:.5em;left:1.625em;width:.4375em;height:5.625em;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);z-index:1}.swal2-icon.swal2-success [class^=swal2-success-line]{display:block;position:absolute;height:.3125em;border-radius:.125em;background-color:#a5dc86;z-index:2}.swal2-icon.swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.875em;width:1.5625em;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.swal2-icon.swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.swal2-progresssteps{align-items:center;margin:0 0 1.25em;padding:0;font-weight:600}.swal2-progresssteps li{display:inline-block;position:relative}.swal2-progresssteps .swal2-progresscircle{width:2em;height:2em;border-radius:2em;background:#3085d6;color:#fff;line-height:2em;text-align:center;z-index:20}.swal2-progresssteps .swal2-progresscircle:first-child{margin-left:0}.swal2-progresssteps .swal2-progresscircle:last-child{margin-right:0}.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep{background:#3085d6}.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep~.swal2-progresscircle{background:#add8e6}.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep~.swal2-progressline{background:#add8e6}.swal2-progresssteps .swal2-progressline{width:2.5em;height:.4em;margin:0 -1px;background:#3085d6;z-index:10}[class^=swal2]{-webkit-tap-highlight-color:transparent}.swal2-show{-webkit-animation:swal2-show .3s;animation:swal2-show .3s}.swal2-show.swal2-noanimation{-webkit-animation:none;animation:none}.swal2-hide{-webkit-animation:swal2-hide .15s forwards;animation:swal2-hide .15s forwards}.swal2-hide.swal2-noanimation{-webkit-animation:none;animation:none}[dir=rtl] .swal2-close{right:auto;left:0}.swal2-animate-success-icon .swal2-success-line-tip{-webkit-animation:swal2-animate-success-line-tip .75s;animation:swal2-animate-success-line-tip .75s}.swal2-animate-success-icon .swal2-success-line-long{-webkit-animation:swal2-animate-success-line-long .75s;animation:swal2-animate-success-line-long .75s}.swal2-animate-success-icon .swal2-success-circular-line-right{-webkit-animation:swal2-rotate-success-circular-line 4.25s ease-in;animation:swal2-rotate-success-circular-line 4.25s ease-in}.swal2-animate-error-icon{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-animate-error-icon .swal2-x-mark{-webkit-animation:swal2-animate-error-x-mark .5s;animation:swal2-animate-error-x-mark .5s}@-webkit-keyframes swal2-rotate-loading{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes swal2-rotate-loading{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@media print{body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow-y:scroll!important}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container{position:initial!important}}"); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/vee-validate-2.1.0.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/vee-validate-2.1.0.js new file mode 100644 index 000000000..3e137bfe2 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/vee-validate-2.1.0.js @@ -0,0 +1,7933 @@ +/** + * vee-validate v2.1.0-beta.9 + * (c) 2018 Abdelrahman Awad + * @license MIT + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.VeeValidate = factory()); +}(this, (function () { 'use strict'; + + var MILLISECONDS_IN_HOUR = 3600000; + var MILLISECONDS_IN_MINUTE = 60000; + var DEFAULT_ADDITIONAL_DIGITS = 2; + + var patterns = { + dateTimeDelimeter: /[T ]/, + plainTime: /:/, + + // year tokens + YY: /^(\d{2})$/, + YYY: [ + /^([+-]\d{2})$/, // 0 additional digits + /^([+-]\d{3})$/, // 1 additional digit + /^([+-]\d{4})$/ // 2 additional digits + ], + YYYY: /^(\d{4})/, + YYYYY: [ + /^([+-]\d{4})/, // 0 additional digits + /^([+-]\d{5})/, // 1 additional digit + /^([+-]\d{6})/ // 2 additional digits + ], + + // date tokens + MM: /^-(\d{2})$/, + DDD: /^-?(\d{3})$/, + MMDD: /^-?(\d{2})-?(\d{2})$/, + Www: /^-?W(\d{2})$/, + WwwD: /^-?W(\d{2})-?(\d{1})$/, + + HH: /^(\d{2}([.,]\d*)?)$/, + HHMM: /^(\d{2}):?(\d{2}([.,]\d*)?)$/, + HHMMSS: /^(\d{2}):?(\d{2}):?(\d{2}([.,]\d*)?)$/, + + // timezone tokens + timezone: /([Z+-].*)$/, + timezoneZ: /^(Z)$/, + timezoneHH: /^([+-])(\d{2})$/, + timezoneHHMM: /^([+-])(\d{2}):?(\d{2})$/ + }; + + /** + * @name toDate + * @category Common Helpers + * @summary Convert the given argument to an instance of Date. + * + * @description + * Convert the given argument to an instance of Date. + * + * If the argument is an instance of Date, the function returns its clone. + * + * If the argument is a number, it is treated as a timestamp. + * + * If an argument is a string, the function tries to parse it. + * Function accepts complete ISO 8601 formats as well as partial implementations. + * ISO 8601: http://en.wikipedia.org/wiki/ISO_8601 + * + * If the argument is null, it is treated as an invalid date. + * + * If all above fails, the function passes the given argument to Date constructor. + * + * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`. + * All *date-fns* functions will throw `RangeError` if `options.additionalDigits` is not 0, 1, 2 or undefined. + * + * @param {*} argument - the value to convert + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - the additional number of digits in the extended year format + * @returns {Date} the parsed date in the local time zone + * @throws {TypeError} 1 argument required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Convert string '2014-02-11T11:30:30' to date: + * var result = toDate('2014-02-11T11:30:30') + * //=> Tue Feb 11 2014 11:30:30 + * + * @example + * // Convert string '+02014101' to date, + * // if the additional number of digits in the extended year format is 1: + * var result = toDate('+02014101', {additionalDigits: 1}) + * //=> Fri Apr 11 2014 00:00:00 + */ + function toDate (argument, dirtyOptions) { + if (arguments.length < 1) { + throw new TypeError('1 argument required, but only ' + arguments.length + ' present') + } + + if (argument === null) { + return new Date(NaN) + } + + var options = dirtyOptions || {}; + + var additionalDigits = options.additionalDigits === undefined ? DEFAULT_ADDITIONAL_DIGITS : Number(options.additionalDigits); + if (additionalDigits !== 2 && additionalDigits !== 1 && additionalDigits !== 0) { + throw new RangeError('additionalDigits must be 0, 1 or 2') + } + + // Clone the date + if (argument instanceof Date) { + // Prevent the date to lose the milliseconds when passed to new Date() in IE10 + return new Date(argument.getTime()) + } else if (typeof argument !== 'string') { + return new Date(argument) + } + + var dateStrings = splitDateString(argument); + + var parseYearResult = parseYear(dateStrings.date, additionalDigits); + var year = parseYearResult.year; + var restDateString = parseYearResult.restDateString; + + var date = parseDate(restDateString, year); + + if (date) { + var timestamp = date.getTime(); + var time = 0; + var offset; + + if (dateStrings.time) { + time = parseTime(dateStrings.time); + } + + if (dateStrings.timezone) { + offset = parseTimezone(dateStrings.timezone); + } else { + // get offset accurate to hour in timezones that change offset + offset = new Date(timestamp + time).getTimezoneOffset(); + offset = new Date(timestamp + time + offset * MILLISECONDS_IN_MINUTE).getTimezoneOffset(); + } + + return new Date(timestamp + time + offset * MILLISECONDS_IN_MINUTE) + } else { + return new Date(argument) + } + } + + function splitDateString (dateString) { + var dateStrings = {}; + var array = dateString.split(patterns.dateTimeDelimeter); + var timeString; + + if (patterns.plainTime.test(array[0])) { + dateStrings.date = null; + timeString = array[0]; + } else { + dateStrings.date = array[0]; + timeString = array[1]; + } + + if (timeString) { + var token = patterns.timezone.exec(timeString); + if (token) { + dateStrings.time = timeString.replace(token[1], ''); + dateStrings.timezone = token[1]; + } else { + dateStrings.time = timeString; + } + } + + return dateStrings + } + + function parseYear (dateString, additionalDigits) { + var patternYYY = patterns.YYY[additionalDigits]; + var patternYYYYY = patterns.YYYYY[additionalDigits]; + + var token; + + // YYYY or ±YYYYY + token = patterns.YYYY.exec(dateString) || patternYYYYY.exec(dateString); + if (token) { + var yearString = token[1]; + return { + year: parseInt(yearString, 10), + restDateString: dateString.slice(yearString.length) + } + } + + // YY or ±YYY + token = patterns.YY.exec(dateString) || patternYYY.exec(dateString); + if (token) { + var centuryString = token[1]; + return { + year: parseInt(centuryString, 10) * 100, + restDateString: dateString.slice(centuryString.length) + } + } + + // Invalid ISO-formatted year + return { + year: null + } + } + + function parseDate (dateString, year) { + // Invalid ISO-formatted year + if (year === null) { + return null + } + + var token; + var date; + var month; + var week; + + // YYYY + if (dateString.length === 0) { + date = new Date(0); + date.setUTCFullYear(year); + return date + } + + // YYYY-MM + token = patterns.MM.exec(dateString); + if (token) { + date = new Date(0); + month = parseInt(token[1], 10) - 1; + date.setUTCFullYear(year, month); + return date + } + + // YYYY-DDD or YYYYDDD + token = patterns.DDD.exec(dateString); + if (token) { + date = new Date(0); + var dayOfYear = parseInt(token[1], 10); + date.setUTCFullYear(year, 0, dayOfYear); + return date + } + + // YYYY-MM-DD or YYYYMMDD + token = patterns.MMDD.exec(dateString); + if (token) { + date = new Date(0); + month = parseInt(token[1], 10) - 1; + var day = parseInt(token[2], 10); + date.setUTCFullYear(year, month, day); + return date + } + + // YYYY-Www or YYYYWww + token = patterns.Www.exec(dateString); + if (token) { + week = parseInt(token[1], 10) - 1; + return dayOfISOYear(year, week) + } + + // YYYY-Www-D or YYYYWwwD + token = patterns.WwwD.exec(dateString); + if (token) { + week = parseInt(token[1], 10) - 1; + var dayOfWeek = parseInt(token[2], 10) - 1; + return dayOfISOYear(year, week, dayOfWeek) + } + + // Invalid ISO-formatted date + return null + } + + function parseTime (timeString) { + var token; + var hours; + var minutes; + + // hh + token = patterns.HH.exec(timeString); + if (token) { + hours = parseFloat(token[1].replace(',', '.')); + return (hours % 24) * MILLISECONDS_IN_HOUR + } + + // hh:mm or hhmm + token = patterns.HHMM.exec(timeString); + if (token) { + hours = parseInt(token[1], 10); + minutes = parseFloat(token[2].replace(',', '.')); + return (hours % 24) * MILLISECONDS_IN_HOUR + + minutes * MILLISECONDS_IN_MINUTE + } + + // hh:mm:ss or hhmmss + token = patterns.HHMMSS.exec(timeString); + if (token) { + hours = parseInt(token[1], 10); + minutes = parseInt(token[2], 10); + var seconds = parseFloat(token[3].replace(',', '.')); + return (hours % 24) * MILLISECONDS_IN_HOUR + + minutes * MILLISECONDS_IN_MINUTE + + seconds * 1000 + } + + // Invalid ISO-formatted time + return null + } + + function parseTimezone (timezoneString) { + var token; + var absoluteOffset; + + // Z + token = patterns.timezoneZ.exec(timezoneString); + if (token) { + return 0 + } + + // ±hh + token = patterns.timezoneHH.exec(timezoneString); + if (token) { + absoluteOffset = parseInt(token[2], 10) * 60; + return (token[1] === '+') ? -absoluteOffset : absoluteOffset + } + + // ±hh:mm or ±hhmm + token = patterns.timezoneHHMM.exec(timezoneString); + if (token) { + absoluteOffset = parseInt(token[2], 10) * 60 + parseInt(token[3], 10); + return (token[1] === '+') ? -absoluteOffset : absoluteOffset + } + + return 0 + } + + function dayOfISOYear (isoYear, week, day) { + week = week || 0; + day = day || 0; + var date = new Date(0); + date.setUTCFullYear(isoYear, 0, 4); + var fourthOfJanuaryDay = date.getUTCDay() || 7; + var diff = week * 7 + day + 1 - fourthOfJanuaryDay; + date.setUTCDate(date.getUTCDate() + diff); + return date + } + + /** + * @name addMilliseconds + * @category Millisecond Helpers + * @summary Add the specified number of milliseconds to the given date. + * + * @description + * Add the specified number of milliseconds to the given date. + * + * @param {Date|String|Number} date - the date to be changed + * @param {Number} amount - the amount of milliseconds to be added + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Date} the new date with the milliseconds added + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Add 750 milliseconds to 10 July 2014 12:45:30.000: + * var result = addMilliseconds(new Date(2014, 6, 10, 12, 45, 30, 0), 750) + * //=> Thu Jul 10 2014 12:45:30.750 + */ + function addMilliseconds (dirtyDate, dirtyAmount, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var timestamp = toDate(dirtyDate, dirtyOptions).getTime(); + var amount = Number(dirtyAmount); + return new Date(timestamp + amount) + } + + function cloneObject (dirtyObject) { + dirtyObject = dirtyObject || {}; + var object = {}; + + for (var property in dirtyObject) { + if (dirtyObject.hasOwnProperty(property)) { + object[property] = dirtyObject[property]; + } + } + + return object + } + + var MILLISECONDS_IN_MINUTE$2 = 60000; + + /** + * @name addMinutes + * @category Minute Helpers + * @summary Add the specified number of minutes to the given date. + * + * @description + * Add the specified number of minutes to the given date. + * + * @param {Date|String|Number} date - the date to be changed + * @param {Number} amount - the amount of minutes to be added + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Date} the new date with the minutes added + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Add 30 minutes to 10 July 2014 12:00:00: + * var result = addMinutes(new Date(2014, 6, 10, 12, 0), 30) + * //=> Thu Jul 10 2014 12:30:00 + */ + function addMinutes (dirtyDate, dirtyAmount, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var amount = Number(dirtyAmount); + return addMilliseconds(dirtyDate, amount * MILLISECONDS_IN_MINUTE$2, dirtyOptions) + } + + /** + * @name isValid + * @category Common Helpers + * @summary Is the given date valid? + * + * @description + * Returns false if argument is Invalid Date and true otherwise. + * Argument is converted to Date using `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * Invalid Date is a Date, whose time value is NaN. + * + * Time value of Date: http://es5.github.io/#x15.9.1.1 + * + * @param {*} date - the date to check + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Boolean} the date is valid + * @throws {TypeError} 1 argument required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // For the valid date: + * var result = isValid(new Date(2014, 1, 31)) + * //=> true + * + * @example + * // For the value, convertable into a date: + * var result = isValid('2014-02-31') + * //=> true + * + * @example + * // For the invalid date: + * var result = isValid(new Date('')) + * //=> false + */ + function isValid (dirtyDate, dirtyOptions) { + if (arguments.length < 1) { + throw new TypeError('1 argument required, but only ' + arguments.length + ' present') + } + + var date = toDate(dirtyDate, dirtyOptions); + return !isNaN(date) + } + + var formatDistanceLocale = { + lessThanXSeconds: { + one: 'less than a second', + other: 'less than {{count}} seconds' + }, + + xSeconds: { + one: '1 second', + other: '{{count}} seconds' + }, + + halfAMinute: 'half a minute', + + lessThanXMinutes: { + one: 'less than a minute', + other: 'less than {{count}} minutes' + }, + + xMinutes: { + one: '1 minute', + other: '{{count}} minutes' + }, + + aboutXHours: { + one: 'about 1 hour', + other: 'about {{count}} hours' + }, + + xHours: { + one: '1 hour', + other: '{{count}} hours' + }, + + xDays: { + one: '1 day', + other: '{{count}} days' + }, + + aboutXMonths: { + one: 'about 1 month', + other: 'about {{count}} months' + }, + + xMonths: { + one: '1 month', + other: '{{count}} months' + }, + + aboutXYears: { + one: 'about 1 year', + other: 'about {{count}} years' + }, + + xYears: { + one: '1 year', + other: '{{count}} years' + }, + + overXYears: { + one: 'over 1 year', + other: 'over {{count}} years' + }, + + almostXYears: { + one: 'almost 1 year', + other: 'almost {{count}} years' + } + }; + + function formatDistance (token, count, options) { + options = options || {}; + + var result; + if (typeof formatDistanceLocale[token] === 'string') { + result = formatDistanceLocale[token]; + } else if (count === 1) { + result = formatDistanceLocale[token].one; + } else { + result = formatDistanceLocale[token].other.replace('{{count}}', count); + } + + if (options.addSuffix) { + if (options.comparison > 0) { + return 'in ' + result + } else { + return result + ' ago' + } + } + + return result + } + + var tokensToBeShortedPattern = /MMMM|MM|DD|dddd/g; + + function buildShortLongFormat (format) { + return format.replace(tokensToBeShortedPattern, function (token) { + return token.slice(1) + }) + } + + /** + * @name buildFormatLongFn + * @category Locale Helpers + * @summary Build `formatLong` property for locale used by `format`, `formatRelative` and `parse` functions. + * + * @description + * Build `formatLong` property for locale used by `format`, `formatRelative` and `parse` functions. + * Returns a function which takes one of the following tokens as the argument: + * `'LTS'`, `'LT'`, `'L'`, `'LL'`, `'LLL'`, `'l'`, `'ll'`, `'lll'`, `'llll'` + * and returns a long format string written as `format` token strings. + * See [format]{@link https://date-fns.org/docs/format} + * + * `'l'`, `'ll'`, `'lll'` and `'llll'` formats are built automatically + * by shortening some of the tokens from corresponding unshortened formats + * (e.g., if `LL` is `'MMMM DD YYYY'` then `ll` will be `MMM D YYYY`) + * + * @param {Object} obj - the object with long formats written as `format` token strings + * @param {String} obj.LT - time format: hours and minutes + * @param {String} obj.LTS - time format: hours, minutes and seconds + * @param {String} obj.L - short date format: numeric day, month and year + * @param {String} [obj.l] - short date format: numeric day, month and year (shortened) + * @param {String} obj.LL - long date format: day, month in words, and year + * @param {String} [obj.ll] - long date format: day, month in words, and year (shortened) + * @param {String} obj.LLL - long date and time format + * @param {String} [obj.lll] - long date and time format (shortened) + * @param {String} obj.LLLL - long date, time and weekday format + * @param {String} [obj.llll] - long date, time and weekday format (shortened) + * @returns {Function} `formatLong` property of the locale + * + * @example + * // For `en-US` locale: + * locale.formatLong = buildFormatLongFn({ + * LT: 'h:mm aa', + * LTS: 'h:mm:ss aa', + * L: 'MM/DD/YYYY', + * LL: 'MMMM D YYYY', + * LLL: 'MMMM D YYYY h:mm aa', + * LLLL: 'dddd, MMMM D YYYY h:mm aa' + * }) + */ + function buildFormatLongFn (obj) { + var formatLongLocale = { + LTS: obj.LTS, + LT: obj.LT, + L: obj.L, + LL: obj.LL, + LLL: obj.LLL, + LLLL: obj.LLLL, + l: obj.l || buildShortLongFormat(obj.L), + ll: obj.ll || buildShortLongFormat(obj.LL), + lll: obj.lll || buildShortLongFormat(obj.LLL), + llll: obj.llll || buildShortLongFormat(obj.LLLL) + }; + + return function (token) { + return formatLongLocale[token] + } + } + + var formatLong = buildFormatLongFn({ + LT: 'h:mm aa', + LTS: 'h:mm:ss aa', + L: 'MM/DD/YYYY', + LL: 'MMMM D YYYY', + LLL: 'MMMM D YYYY h:mm aa', + LLLL: 'dddd, MMMM D YYYY h:mm aa' + }); + + var formatRelativeLocale = { + lastWeek: '[last] dddd [at] LT', + yesterday: '[yesterday at] LT', + today: '[today at] LT', + tomorrow: '[tomorrow at] LT', + nextWeek: 'dddd [at] LT', + other: 'L' + }; + + function formatRelative (token, date, baseDate, options) { + return formatRelativeLocale[token] + } + + /** + * @name buildLocalizeFn + * @category Locale Helpers + * @summary Build `localize.weekday`, `localize.month` and `localize.timeOfDay` properties for the locale. + * + * @description + * Build `localize.weekday`, `localize.month` and `localize.timeOfDay` properties for the locale + * used by `format` function. + * If no `type` is supplied to the options of the resulting function, `defaultType` will be used (see example). + * + * `localize.weekday` function takes the weekday index as argument (0 - Sunday). + * `localize.month` takes the month index (0 - January). + * `localize.timeOfDay` takes the hours. Use `indexCallback` to convert them to an array index (see example). + * + * @param {Object} values - the object with arrays of values + * @param {String} defaultType - the default type for the localize function + * @param {Function} [indexCallback] - the callback which takes the resulting function argument + * and converts it into value array index + * @returns {Function} the resulting function + * + * @example + * var timeOfDayValues = { + * uppercase: ['AM', 'PM'], + * lowercase: ['am', 'pm'], + * long: ['a.m.', 'p.m.'] + * } + * locale.localize.timeOfDay = buildLocalizeFn(timeOfDayValues, 'long', function (hours) { + * // 0 is a.m. array index, 1 is p.m. array index + * return (hours / 12) >= 1 ? 1 : 0 + * }) + * locale.localize.timeOfDay(16, {type: 'uppercase'}) //=> 'PM' + * locale.localize.timeOfDay(5) //=> 'a.m.' + */ + function buildLocalizeFn (values, defaultType, indexCallback) { + return function (dirtyIndex, dirtyOptions) { + var options = dirtyOptions || {}; + var type = options.type ? String(options.type) : defaultType; + var valuesArray = values[type] || values[defaultType]; + var index = indexCallback ? indexCallback(Number(dirtyIndex)) : Number(dirtyIndex); + return valuesArray[index] + } + } + + /** + * @name buildLocalizeArrayFn + * @category Locale Helpers + * @summary Build `localize.weekdays`, `localize.months` and `localize.timesOfDay` properties for the locale. + * + * @description + * Build `localize.weekdays`, `localize.months` and `localize.timesOfDay` properties for the locale. + * If no `type` is supplied to the options of the resulting function, `defaultType` will be used (see example). + * + * @param {Object} values - the object with arrays of values + * @param {String} defaultType - the default type for the localize function + * @returns {Function} the resulting function + * + * @example + * var weekdayValues = { + * narrow: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'], + * short: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + * long: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] + * } + * locale.localize.weekdays = buildLocalizeArrayFn(weekdayValues, 'long') + * locale.localize.weekdays({type: 'narrow'}) //=> ['Su', 'Mo', ...] + * locale.localize.weekdays() //=> ['Sunday', 'Monday', ...] + */ + function buildLocalizeArrayFn (values, defaultType) { + return function (dirtyOptions) { + var options = dirtyOptions || {}; + var type = options.type ? String(options.type) : defaultType; + return values[type] || values[defaultType] + } + } + + // Note: in English, the names of days of the week and months are capitalized. + // If you are making a new locale based on this one, check if the same is true for the language you're working on. + // Generally, formatted dates should look like they are in the middle of a sentence, + // e.g. in Spanish language the weekdays and months should be in the lowercase. + var weekdayValues = { + narrow: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'], + short: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + long: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] + }; + + var monthValues = { + short: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + long: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] + }; + + // `timeOfDay` is used to designate which part of the day it is, when used with 12-hour clock. + // Use the system which is used the most commonly in the locale. + // For example, if the country doesn't use a.m./p.m., you can use `night`/`morning`/`afternoon`/`evening`: + // + // var timeOfDayValues = { + // any: ['in the night', 'in the morning', 'in the afternoon', 'in the evening'] + // } + // + // And later: + // + // var localize = { + // // The callback takes the hours as the argument and returns the array index + // timeOfDay: buildLocalizeFn(timeOfDayValues, 'any', function (hours) { + // if (hours >= 17) { + // return 3 + // } else if (hours >= 12) { + // return 2 + // } else if (hours >= 4) { + // return 1 + // } else { + // return 0 + // } + // }), + // timesOfDay: buildLocalizeArrayFn(timeOfDayValues, 'any') + // } + var timeOfDayValues = { + uppercase: ['AM', 'PM'], + lowercase: ['am', 'pm'], + long: ['a.m.', 'p.m.'] + }; + + function ordinalNumber (dirtyNumber, dirtyOptions) { + var number = Number(dirtyNumber); + + // If ordinal numbers depend on context, for example, + // if they are different for different grammatical genders, + // use `options.unit`: + // + // var options = dirtyOptions || {} + // var unit = String(options.unit) + // + // where `unit` can be 'month', 'quarter', 'week', 'isoWeek', 'dayOfYear', + // 'dayOfMonth' or 'dayOfWeek' + + var rem100 = number % 100; + if (rem100 > 20 || rem100 < 10) { + switch (rem100 % 10) { + case 1: + return number + 'st' + case 2: + return number + 'nd' + case 3: + return number + 'rd' + } + } + return number + 'th' + } + + var localize = { + ordinalNumber: ordinalNumber, + weekday: buildLocalizeFn(weekdayValues, 'long'), + weekdays: buildLocalizeArrayFn(weekdayValues, 'long'), + month: buildLocalizeFn(monthValues, 'long'), + months: buildLocalizeArrayFn(monthValues, 'long'), + timeOfDay: buildLocalizeFn(timeOfDayValues, 'long', function (hours) { + return (hours / 12) >= 1 ? 1 : 0 + }), + timesOfDay: buildLocalizeArrayFn(timeOfDayValues, 'long') + }; + + /** + * @name buildMatchFn + * @category Locale Helpers + * @summary Build `match.weekdays`, `match.months` and `match.timesOfDay` properties for the locale. + * + * @description + * Build `match.weekdays`, `match.months` and `match.timesOfDay` properties for the locale used by `parse` function. + * If no `type` is supplied to the options of the resulting function, `defaultType` will be used (see example). + * The result of the match function will be passed into corresponding parser function + * (`match.weekday`, `match.month` or `match.timeOfDay` respectively. See `buildParseFn`). + * + * @param {Object} values - the object with RegExps + * @param {String} defaultType - the default type for the match function + * @returns {Function} the resulting function + * + * @example + * var matchWeekdaysPatterns = { + * narrow: /^(su|mo|tu|we|th|fr|sa)/i, + * short: /^(sun|mon|tue|wed|thu|fri|sat)/i, + * long: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i + * } + * locale.match.weekdays = buildMatchFn(matchWeekdaysPatterns, 'long') + * locale.match.weekdays('Sunday', {type: 'narrow'}) //=> ['Su', 'Su', ...] + * locale.match.weekdays('Sunday') //=> ['Sunday', 'Sunday', ...] + */ + function buildMatchFn (patterns, defaultType) { + return function (dirtyString, dirtyOptions) { + var options = dirtyOptions || {}; + var type = options.type ? String(options.type) : defaultType; + var pattern = patterns[type] || patterns[defaultType]; + var string = String(dirtyString); + return string.match(pattern) + } + } + + /** + * @name buildParseFn + * @category Locale Helpers + * @summary Build `match.weekday`, `match.month` and `match.timeOfDay` properties for the locale. + * + * @description + * Build `match.weekday`, `match.month` and `match.timeOfDay` properties for the locale used by `parse` function. + * The argument of the resulting function is the result of the corresponding match function + * (`match.weekdays`, `match.months` or `match.timesOfDay` respectively. See `buildMatchFn`). + * + * @param {Object} values - the object with arrays of RegExps + * @param {String} defaultType - the default type for the parser function + * @returns {Function} the resulting function + * + * @example + * var parseWeekdayPatterns = { + * any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i] + * } + * locale.match.weekday = buildParseFn(matchWeekdaysPatterns, 'long') + * var matchResult = locale.match.weekdays('Friday') + * locale.match.weekday(matchResult) //=> 5 + */ + function buildParseFn (patterns, defaultType) { + return function (matchResult, dirtyOptions) { + var options = dirtyOptions || {}; + var type = options.type ? String(options.type) : defaultType; + var patternsArray = patterns[type] || patterns[defaultType]; + var string = matchResult[1]; + + return patternsArray.findIndex(function (pattern) { + return pattern.test(string) + }) + } + } + + /** + * @name buildMatchPatternFn + * @category Locale Helpers + * @summary Build match function from a single RegExp. + * + * @description + * Build match function from a single RegExp. + * Usually used for building `match.ordinalNumbers` property of the locale. + * + * @param {Object} pattern - the RegExp + * @returns {Function} the resulting function + * + * @example + * locale.match.ordinalNumbers = buildMatchPatternFn(/^(\d+)(th|st|nd|rd)?/i) + * locale.match.ordinalNumbers('3rd') //=> ['3rd', '3', 'rd', ...] + */ + function buildMatchPatternFn (pattern) { + return function (dirtyString) { + var string = String(dirtyString); + return string.match(pattern) + } + } + + /** + * @name parseDecimal + * @category Locale Helpers + * @summary Parses the match result into decimal number. + * + * @description + * Parses the match result into decimal number. + * Uses the string matched with the first set of parentheses of match RegExp. + * + * @param {Array} matchResult - the object returned by matching function + * @returns {Number} the parsed value + * + * @example + * locale.match = { + * ordinalNumbers: (dirtyString) { + * return String(dirtyString).match(/^(\d+)(th|st|nd|rd)?/i) + * }, + * ordinalNumber: parseDecimal + * } + */ + function parseDecimal (matchResult) { + return parseInt(matchResult[1], 10) + } + + var matchOrdinalNumbersPattern = /^(\d+)(th|st|nd|rd)?/i; + + var matchWeekdaysPatterns = { + narrow: /^(su|mo|tu|we|th|fr|sa)/i, + short: /^(sun|mon|tue|wed|thu|fri|sat)/i, + long: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i + }; + + var parseWeekdayPatterns = { + any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i] + }; + + var matchMonthsPatterns = { + short: /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i, + long: /^(january|february|march|april|may|june|july|august|september|october|november|december)/i + }; + + var parseMonthPatterns = { + any: [/^ja/i, /^f/i, /^mar/i, /^ap/i, /^may/i, /^jun/i, /^jul/i, /^au/i, /^s/i, /^o/i, /^n/i, /^d/i] + }; + + // `timeOfDay` is used to designate which part of the day it is, when used with 12-hour clock. + // Use the system which is used the most commonly in the locale. + // For example, if the country doesn't use a.m./p.m., you can use `night`/`morning`/`afternoon`/`evening`: + // + // var matchTimesOfDayPatterns = { + // long: /^((in the)? (night|morning|afternoon|evening?))/i + // } + // + // var parseTimeOfDayPatterns = { + // any: [/(night|morning)/i, /(afternoon|evening)/i] + // } + var matchTimesOfDayPatterns = { + short: /^(am|pm)/i, + long: /^([ap]\.?\s?m\.?)/i + }; + + var parseTimeOfDayPatterns = { + any: [/^a/i, /^p/i] + }; + + var match = { + ordinalNumbers: buildMatchPatternFn(matchOrdinalNumbersPattern), + ordinalNumber: parseDecimal, + weekdays: buildMatchFn(matchWeekdaysPatterns, 'long'), + weekday: buildParseFn(parseWeekdayPatterns, 'any'), + months: buildMatchFn(matchMonthsPatterns, 'long'), + month: buildParseFn(parseMonthPatterns, 'any'), + timesOfDay: buildMatchFn(matchTimesOfDayPatterns, 'long'), + timeOfDay: buildParseFn(parseTimeOfDayPatterns, 'any') + }; + + /** + * @type {Locale} + * @category Locales + * @summary English locale (United States). + * @language English + * @iso-639-2 eng + */ + var locale = { + formatDistance: formatDistance, + formatLong: formatLong, + formatRelative: formatRelative, + localize: localize, + match: match, + options: { + weekStartsOn: 0 /* Sunday */, + firstWeekContainsDate: 1 + } + }; + + var MILLISECONDS_IN_DAY$1 = 86400000; + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function getUTCDayOfYear (dirtyDate, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var timestamp = date.getTime(); + date.setUTCMonth(0, 1); + date.setUTCHours(0, 0, 0, 0); + var startOfYearTimestamp = date.getTime(); + var difference = timestamp - startOfYearTimestamp; + return Math.floor(difference / MILLISECONDS_IN_DAY$1) + 1 + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function startOfUTCISOWeek (dirtyDate, dirtyOptions) { + var weekStartsOn = 1; + + var date = toDate(dirtyDate, dirtyOptions); + var day = date.getUTCDay(); + var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn; + + date.setUTCDate(date.getUTCDate() - diff); + date.setUTCHours(0, 0, 0, 0); + return date + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function getUTCISOWeekYear (dirtyDate, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var year = date.getUTCFullYear(); + + var fourthOfJanuaryOfNextYear = new Date(0); + fourthOfJanuaryOfNextYear.setUTCFullYear(year + 1, 0, 4); + fourthOfJanuaryOfNextYear.setUTCHours(0, 0, 0, 0); + var startOfNextYear = startOfUTCISOWeek(fourthOfJanuaryOfNextYear, dirtyOptions); + + var fourthOfJanuaryOfThisYear = new Date(0); + fourthOfJanuaryOfThisYear.setUTCFullYear(year, 0, 4); + fourthOfJanuaryOfThisYear.setUTCHours(0, 0, 0, 0); + var startOfThisYear = startOfUTCISOWeek(fourthOfJanuaryOfThisYear, dirtyOptions); + + if (date.getTime() >= startOfNextYear.getTime()) { + return year + 1 + } else if (date.getTime() >= startOfThisYear.getTime()) { + return year + } else { + return year - 1 + } + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function startOfUTCISOWeekYear (dirtyDate, dirtyOptions) { + var year = getUTCISOWeekYear(dirtyDate, dirtyOptions); + var fourthOfJanuary = new Date(0); + fourthOfJanuary.setUTCFullYear(year, 0, 4); + fourthOfJanuary.setUTCHours(0, 0, 0, 0); + var date = startOfUTCISOWeek(fourthOfJanuary, dirtyOptions); + return date + } + + var MILLISECONDS_IN_WEEK$2 = 604800000; + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function getUTCISOWeek (dirtyDate, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var diff = startOfUTCISOWeek(date, dirtyOptions).getTime() - startOfUTCISOWeekYear(date, dirtyOptions).getTime(); + + // Round the number of days to the nearest integer + // because the number of milliseconds in a week is not constant + // (e.g. it's different in the week of the daylight saving time clock shift) + return Math.round(diff / MILLISECONDS_IN_WEEK$2) + 1 + } + + var formatters = { + // Month: 1, 2, ..., 12 + 'M': function (date) { + return date.getUTCMonth() + 1 + }, + + // Month: 1st, 2nd, ..., 12th + 'Mo': function (date, options) { + var month = date.getUTCMonth() + 1; + return options.locale.localize.ordinalNumber(month, {unit: 'month'}) + }, + + // Month: 01, 02, ..., 12 + 'MM': function (date) { + return addLeadingZeros(date.getUTCMonth() + 1, 2) + }, + + // Month: Jan, Feb, ..., Dec + 'MMM': function (date, options) { + return options.locale.localize.month(date.getUTCMonth(), {type: 'short'}) + }, + + // Month: January, February, ..., December + 'MMMM': function (date, options) { + return options.locale.localize.month(date.getUTCMonth(), {type: 'long'}) + }, + + // Quarter: 1, 2, 3, 4 + 'Q': function (date) { + return Math.ceil((date.getUTCMonth() + 1) / 3) + }, + + // Quarter: 1st, 2nd, 3rd, 4th + 'Qo': function (date, options) { + var quarter = Math.ceil((date.getUTCMonth() + 1) / 3); + return options.locale.localize.ordinalNumber(quarter, {unit: 'quarter'}) + }, + + // Day of month: 1, 2, ..., 31 + 'D': function (date) { + return date.getUTCDate() + }, + + // Day of month: 1st, 2nd, ..., 31st + 'Do': function (date, options) { + return options.locale.localize.ordinalNumber(date.getUTCDate(), {unit: 'dayOfMonth'}) + }, + + // Day of month: 01, 02, ..., 31 + 'DD': function (date) { + return addLeadingZeros(date.getUTCDate(), 2) + }, + + // Day of year: 1, 2, ..., 366 + 'DDD': function (date) { + return getUTCDayOfYear(date) + }, + + // Day of year: 1st, 2nd, ..., 366th + 'DDDo': function (date, options) { + return options.locale.localize.ordinalNumber(getUTCDayOfYear(date), {unit: 'dayOfYear'}) + }, + + // Day of year: 001, 002, ..., 366 + 'DDDD': function (date) { + return addLeadingZeros(getUTCDayOfYear(date), 3) + }, + + // Day of week: Su, Mo, ..., Sa + 'dd': function (date, options) { + return options.locale.localize.weekday(date.getUTCDay(), {type: 'narrow'}) + }, + + // Day of week: Sun, Mon, ..., Sat + 'ddd': function (date, options) { + return options.locale.localize.weekday(date.getUTCDay(), {type: 'short'}) + }, + + // Day of week: Sunday, Monday, ..., Saturday + 'dddd': function (date, options) { + return options.locale.localize.weekday(date.getUTCDay(), {type: 'long'}) + }, + + // Day of week: 0, 1, ..., 6 + 'd': function (date) { + return date.getUTCDay() + }, + + // Day of week: 0th, 1st, 2nd, ..., 6th + 'do': function (date, options) { + return options.locale.localize.ordinalNumber(date.getUTCDay(), {unit: 'dayOfWeek'}) + }, + + // Day of ISO week: 1, 2, ..., 7 + 'E': function (date) { + return date.getUTCDay() || 7 + }, + + // ISO week: 1, 2, ..., 53 + 'W': function (date) { + return getUTCISOWeek(date) + }, + + // ISO week: 1st, 2nd, ..., 53th + 'Wo': function (date, options) { + return options.locale.localize.ordinalNumber(getUTCISOWeek(date), {unit: 'isoWeek'}) + }, + + // ISO week: 01, 02, ..., 53 + 'WW': function (date) { + return addLeadingZeros(getUTCISOWeek(date), 2) + }, + + // Year: 00, 01, ..., 99 + 'YY': function (date) { + return addLeadingZeros(date.getUTCFullYear(), 4).substr(2) + }, + + // Year: 1900, 1901, ..., 2099 + 'YYYY': function (date) { + return addLeadingZeros(date.getUTCFullYear(), 4) + }, + + // ISO week-numbering year: 00, 01, ..., 99 + 'GG': function (date) { + return String(getUTCISOWeekYear(date)).substr(2) + }, + + // ISO week-numbering year: 1900, 1901, ..., 2099 + 'GGGG': function (date) { + return getUTCISOWeekYear(date) + }, + + // Hour: 0, 1, ... 23 + 'H': function (date) { + return date.getUTCHours() + }, + + // Hour: 00, 01, ..., 23 + 'HH': function (date) { + return addLeadingZeros(date.getUTCHours(), 2) + }, + + // Hour: 1, 2, ..., 12 + 'h': function (date) { + var hours = date.getUTCHours(); + if (hours === 0) { + return 12 + } else if (hours > 12) { + return hours % 12 + } else { + return hours + } + }, + + // Hour: 01, 02, ..., 12 + 'hh': function (date) { + return addLeadingZeros(formatters['h'](date), 2) + }, + + // Minute: 0, 1, ..., 59 + 'm': function (date) { + return date.getUTCMinutes() + }, + + // Minute: 00, 01, ..., 59 + 'mm': function (date) { + return addLeadingZeros(date.getUTCMinutes(), 2) + }, + + // Second: 0, 1, ..., 59 + 's': function (date) { + return date.getUTCSeconds() + }, + + // Second: 00, 01, ..., 59 + 'ss': function (date) { + return addLeadingZeros(date.getUTCSeconds(), 2) + }, + + // 1/10 of second: 0, 1, ..., 9 + 'S': function (date) { + return Math.floor(date.getUTCMilliseconds() / 100) + }, + + // 1/100 of second: 00, 01, ..., 99 + 'SS': function (date) { + return addLeadingZeros(Math.floor(date.getUTCMilliseconds() / 10), 2) + }, + + // Millisecond: 000, 001, ..., 999 + 'SSS': function (date) { + return addLeadingZeros(date.getUTCMilliseconds(), 3) + }, + + // Timezone: -01:00, +00:00, ... +12:00 + 'Z': function (date, options) { + var originalDate = options._originalDate || date; + return formatTimezone(originalDate.getTimezoneOffset(), ':') + }, + + // Timezone: -0100, +0000, ... +1200 + 'ZZ': function (date, options) { + var originalDate = options._originalDate || date; + return formatTimezone(originalDate.getTimezoneOffset()) + }, + + // Seconds timestamp: 512969520 + 'X': function (date, options) { + var originalDate = options._originalDate || date; + return Math.floor(originalDate.getTime() / 1000) + }, + + // Milliseconds timestamp: 512969520900 + 'x': function (date, options) { + var originalDate = options._originalDate || date; + return originalDate.getTime() + }, + + // AM, PM + 'A': function (date, options) { + return options.locale.localize.timeOfDay(date.getUTCHours(), {type: 'uppercase'}) + }, + + // am, pm + 'a': function (date, options) { + return options.locale.localize.timeOfDay(date.getUTCHours(), {type: 'lowercase'}) + }, + + // a.m., p.m. + 'aa': function (date, options) { + return options.locale.localize.timeOfDay(date.getUTCHours(), {type: 'long'}) + } + }; + + function formatTimezone (offset, delimeter) { + delimeter = delimeter || ''; + var sign = offset > 0 ? '-' : '+'; + var absOffset = Math.abs(offset); + var hours = Math.floor(absOffset / 60); + var minutes = absOffset % 60; + return sign + addLeadingZeros(hours, 2) + delimeter + addLeadingZeros(minutes, 2) + } + + function addLeadingZeros (number, targetLength) { + var output = Math.abs(number).toString(); + while (output.length < targetLength) { + output = '0' + output; + } + return output + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function addUTCMinutes (dirtyDate, dirtyAmount, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var amount = Number(dirtyAmount); + date.setUTCMinutes(date.getUTCMinutes() + amount); + return date + } + + var longFormattingTokensRegExp = /(\[[^[]*])|(\\)?(LTS|LT|LLLL|LLL|LL|L|llll|lll|ll|l)/g; + var defaultFormattingTokensRegExp = /(\[[^[]*])|(\\)?(x|ss|s|mm|m|hh|h|do|dddd|ddd|dd|d|aa|a|ZZ|Z|YYYY|YY|X|Wo|WW|W|SSS|SS|S|Qo|Q|Mo|MMMM|MMM|MM|M|HH|H|GGGG|GG|E|Do|DDDo|DDDD|DDD|DD|D|A|.)/g; + + /** + * @name format + * @category Common Helpers + * @summary Format the date. + * + * @description + * Return the formatted date string in the given format. + * + * Accepted tokens: + * | Unit | Token | Result examples | + * |-------------------------|-------|----------------------------------| + * | Month | M | 1, 2, ..., 12 | + * | | Mo | 1st, 2nd, ..., 12th | + * | | MM | 01, 02, ..., 12 | + * | | MMM | Jan, Feb, ..., Dec | + * | | MMMM | January, February, ..., December | + * | Quarter | Q | 1, 2, 3, 4 | + * | | Qo | 1st, 2nd, 3rd, 4th | + * | Day of month | D | 1, 2, ..., 31 | + * | | Do | 1st, 2nd, ..., 31st | + * | | DD | 01, 02, ..., 31 | + * | Day of year | DDD | 1, 2, ..., 366 | + * | | DDDo | 1st, 2nd, ..., 366th | + * | | DDDD | 001, 002, ..., 366 | + * | Day of week | d | 0, 1, ..., 6 | + * | | do | 0th, 1st, ..., 6th | + * | | dd | Su, Mo, ..., Sa | + * | | ddd | Sun, Mon, ..., Sat | + * | | dddd | Sunday, Monday, ..., Saturday | + * | Day of ISO week | E | 1, 2, ..., 7 | + * | ISO week | W | 1, 2, ..., 53 | + * | | Wo | 1st, 2nd, ..., 53rd | + * | | WW | 01, 02, ..., 53 | + * | Year | YY | 00, 01, ..., 99 | + * | | YYYY | 1900, 1901, ..., 2099 | + * | ISO week-numbering year | GG | 00, 01, ..., 99 | + * | | GGGG | 1900, 1901, ..., 2099 | + * | AM/PM | A | AM, PM | + * | | a | am, pm | + * | | aa | a.m., p.m. | + * | Hour | H | 0, 1, ... 23 | + * | | HH | 00, 01, ... 23 | + * | | h | 1, 2, ..., 12 | + * | | hh | 01, 02, ..., 12 | + * | Minute | m | 0, 1, ..., 59 | + * | | mm | 00, 01, ..., 59 | + * | Second | s | 0, 1, ..., 59 | + * | | ss | 00, 01, ..., 59 | + * | 1/10 of second | S | 0, 1, ..., 9 | + * | 1/100 of second | SS | 00, 01, ..., 99 | + * | Millisecond | SSS | 000, 001, ..., 999 | + * | Timezone | Z | -01:00, +00:00, ... +12:00 | + * | | ZZ | -0100, +0000, ..., +1200 | + * | Seconds timestamp | X | 512969520 | + * | Milliseconds timestamp | x | 512969520900 | + * | Long format | LT | 05:30 a.m. | + * | | LTS | 05:30:15 a.m. | + * | | L | 07/02/1995 | + * | | l | 7/2/1995 | + * | | LL | July 2 1995 | + * | | ll | Jul 2 1995 | + * | | LLL | July 2 1995 05:30 a.m. | + * | | lll | Jul 2 1995 05:30 a.m. | + * | | LLLL | Sunday, July 2 1995 05:30 a.m. | + * | | llll | Sun, Jul 2 1995 05:30 a.m. | + * + * The characters wrapped in square brackets are escaped. + * + * The result may vary by locale. + * + * @param {Date|String|Number} date - the original date + * @param {String} format - the string of tokens + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale} + * @returns {String} the formatted date string + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * @throws {RangeError} `options.locale` must contain `localize` property + * @throws {RangeError} `options.locale` must contain `formatLong` property + * + * @example + * // Represent 11 February 2014 in middle-endian format: + * var result = format( + * new Date(2014, 1, 11), + * 'MM/DD/YYYY' + * ) + * //=> '02/11/2014' + * + * @example + * // Represent 2 July 2014 in Esperanto: + * import { eoLocale } from 'date-fns/locale/eo' + * var result = format( + * new Date(2014, 6, 2), + * 'Do [de] MMMM YYYY', + * {locale: eoLocale} + * ) + * //=> '2-a de julio 2014' + */ + function format (dirtyDate, dirtyFormatStr, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var formatStr = String(dirtyFormatStr); + var options = dirtyOptions || {}; + + var locale$$1 = options.locale || locale; + + if (!locale$$1.localize) { + throw new RangeError('locale must contain localize property') + } + + if (!locale$$1.formatLong) { + throw new RangeError('locale must contain formatLong property') + } + + var localeFormatters = locale$$1.formatters || {}; + var formattingTokensRegExp = locale$$1.formattingTokensRegExp || defaultFormattingTokensRegExp; + var formatLong = locale$$1.formatLong; + + var originalDate = toDate(dirtyDate, options); + + if (!isValid(originalDate, options)) { + return 'Invalid Date' + } + + // Convert the date in system timezone to the same date in UTC+00:00 timezone. + // This ensures that when UTC functions will be implemented, locales will be compatible with them. + // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/376 + var timezoneOffset = originalDate.getTimezoneOffset(); + var utcDate = addUTCMinutes(originalDate, -timezoneOffset, options); + + var formatterOptions = cloneObject(options); + formatterOptions.locale = locale$$1; + formatterOptions.formatters = formatters; + + // When UTC functions will be implemented, options._originalDate will likely be a part of public API. + // Right now, please don't use it in locales. If you have to use an original date, + // please restore it from `date`, adding a timezone offset to it. + formatterOptions._originalDate = originalDate; + + var result = formatStr + .replace(longFormattingTokensRegExp, function (substring) { + if (substring[0] === '[') { + return substring + } + + if (substring[0] === '\\') { + return cleanEscapedString(substring) + } + + return formatLong(substring) + }) + .replace(formattingTokensRegExp, function (substring) { + var formatter = localeFormatters[substring] || formatters[substring]; + + if (formatter) { + return formatter(utcDate, formatterOptions) + } else { + return cleanEscapedString(substring) + } + }); + + return result + } + + function cleanEscapedString (input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|]$/g, '') + } + return input.replace(/\\/g, '') + } + + /** + * @name subMinutes + * @category Minute Helpers + * @summary Subtract the specified number of minutes from the given date. + * + * @description + * Subtract the specified number of minutes from the given date. + * + * @param {Date|String|Number} date - the date to be changed + * @param {Number} amount - the amount of minutes to be subtracted + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Date} the new date with the mintues subtracted + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Subtract 30 minutes from 10 July 2014 12:00:00: + * var result = subMinutes(new Date(2014, 6, 10, 12, 0), 30) + * //=> Thu Jul 10 2014 11:30:00 + */ + function subMinutes (dirtyDate, dirtyAmount, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var amount = Number(dirtyAmount); + return addMinutes(dirtyDate, -amount, dirtyOptions) + } + + /** + * @name isAfter + * @category Common Helpers + * @summary Is the first date after the second one? + * + * @description + * Is the first date after the second one? + * + * @param {Date|String|Number} date - the date that should be after the other one to return true + * @param {Date|String|Number} dateToCompare - the date to compare with + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Boolean} the first date is after the second date + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Is 10 July 1989 after 11 February 1987? + * var result = isAfter(new Date(1989, 6, 10), new Date(1987, 1, 11)) + * //=> true + */ + function isAfter (dirtyDate, dirtyDateToCompare, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var date = toDate(dirtyDate, dirtyOptions); + var dateToCompare = toDate(dirtyDateToCompare, dirtyOptions); + return date.getTime() > dateToCompare.getTime() + } + + /** + * @name isBefore + * @category Common Helpers + * @summary Is the first date before the second one? + * + * @description + * Is the first date before the second one? + * + * @param {Date|String|Number} date - the date that should be before the other one to return true + * @param {Date|String|Number} dateToCompare - the date to compare with + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Boolean} the first date is before the second date + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Is 10 July 1989 before 11 February 1987? + * var result = isBefore(new Date(1989, 6, 10), new Date(1987, 1, 11)) + * //=> false + */ + function isBefore (dirtyDate, dirtyDateToCompare, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var date = toDate(dirtyDate, dirtyOptions); + var dateToCompare = toDate(dirtyDateToCompare, dirtyOptions); + return date.getTime() < dateToCompare.getTime() + } + + /** + * @name isEqual + * @category Common Helpers + * @summary Are the given dates equal? + * + * @description + * Are the given dates equal? + * + * @param {Date|String|Number} dateLeft - the first date to compare + * @param {Date|String|Number} dateRight - the second date to compare + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Boolean} the dates are equal + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Are 2 July 2014 06:30:45.000 and 2 July 2014 06:30:45.500 equal? + * var result = isEqual( + * new Date(2014, 6, 2, 6, 30, 45, 0) + * new Date(2014, 6, 2, 6, 30, 45, 500) + * ) + * //=> false + */ + function isEqual (dirtyLeftDate, dirtyRightDate, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var dateLeft = toDate(dirtyLeftDate, dirtyOptions); + var dateRight = toDate(dirtyRightDate, dirtyOptions); + return dateLeft.getTime() === dateRight.getTime() + } + + var patterns$1 = { + 'M': /^(1[0-2]|0?\d)/, // 0 to 12 + 'D': /^(3[0-1]|[0-2]?\d)/, // 0 to 31 + 'DDD': /^(36[0-6]|3[0-5]\d|[0-2]?\d?\d)/, // 0 to 366 + 'W': /^(5[0-3]|[0-4]?\d)/, // 0 to 53 + 'YYYY': /^(\d{1,4})/, // 0 to 9999 + 'H': /^(2[0-3]|[0-1]?\d)/, // 0 to 23 + 'm': /^([0-5]?\d)/, // 0 to 59 + 'Z': /^([+-])(\d{2}):(\d{2})/, + 'ZZ': /^([+-])(\d{2})(\d{2})/, + singleDigit: /^(\d)/, + twoDigits: /^(\d{2})/, + threeDigits: /^(\d{3})/, + fourDigits: /^(\d{4})/, + anyDigits: /^(\d+)/ + }; + + function parseDecimal$1 (matchResult) { + return parseInt(matchResult[1], 10) + } + + var parsers = { + // Year: 00, 01, ..., 99 + 'YY': { + unit: 'twoDigitYear', + match: patterns$1.twoDigits, + parse: function (matchResult) { + return parseDecimal$1(matchResult) + } + }, + + // Year: 1900, 1901, ..., 2099 + 'YYYY': { + unit: 'year', + match: patterns$1.YYYY, + parse: parseDecimal$1 + }, + + // ISO week-numbering year: 00, 01, ..., 99 + 'GG': { + unit: 'isoYear', + match: patterns$1.twoDigits, + parse: function (matchResult) { + return parseDecimal$1(matchResult) + 1900 + } + }, + + // ISO week-numbering year: 1900, 1901, ..., 2099 + 'GGGG': { + unit: 'isoYear', + match: patterns$1.YYYY, + parse: parseDecimal$1 + }, + + // Quarter: 1, 2, 3, 4 + 'Q': { + unit: 'quarter', + match: patterns$1.singleDigit, + parse: parseDecimal$1 + }, + + // Ordinal quarter + 'Qo': { + unit: 'quarter', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'quarter'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'quarter'}) + } + }, + + // Month: 1, 2, ..., 12 + 'M': { + unit: 'month', + match: patterns$1.M, + parse: function (matchResult) { + return parseDecimal$1(matchResult) - 1 + } + }, + + // Ordinal month + 'Mo': { + unit: 'month', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'month'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'month'}) - 1 + } + }, + + // Month: 01, 02, ..., 12 + 'MM': { + unit: 'month', + match: patterns$1.twoDigits, + parse: function (matchResult) { + return parseDecimal$1(matchResult) - 1 + } + }, + + // Month: Jan, Feb, ..., Dec + 'MMM': { + unit: 'month', + match: function (string, options) { + return options.locale.match.months(string, {type: 'short'}) + }, + parse: function (matchResult, options) { + return options.locale.match.month(matchResult, {type: 'short'}) + } + }, + + // Month: January, February, ..., December + 'MMMM': { + unit: 'month', + match: function (string, options) { + return options.locale.match.months(string, {type: 'long'}) || + options.locale.match.months(string, {type: 'short'}) + }, + parse: function (matchResult, options) { + var parseResult = options.locale.match.month(matchResult, {type: 'long'}); + + if (parseResult == null) { + parseResult = options.locale.match.month(matchResult, {type: 'short'}); + } + + return parseResult + } + }, + + // ISO week: 1, 2, ..., 53 + 'W': { + unit: 'isoWeek', + match: patterns$1.W, + parse: parseDecimal$1 + }, + + // Ordinal ISO week + 'Wo': { + unit: 'isoWeek', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'isoWeek'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'isoWeek'}) + } + }, + + // ISO week: 01, 02, ..., 53 + 'WW': { + unit: 'isoWeek', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // Day of week: 0, 1, ..., 6 + 'd': { + unit: 'dayOfWeek', + match: patterns$1.singleDigit, + parse: parseDecimal$1 + }, + + // Ordinal day of week + 'do': { + unit: 'dayOfWeek', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'dayOfWeek'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'dayOfWeek'}) + } + }, + + // Day of week: Su, Mo, ..., Sa + 'dd': { + unit: 'dayOfWeek', + match: function (string, options) { + return options.locale.match.weekdays(string, {type: 'narrow'}) + }, + parse: function (matchResult, options) { + return options.locale.match.weekday(matchResult, {type: 'narrow'}) + } + }, + + // Day of week: Sun, Mon, ..., Sat + 'ddd': { + unit: 'dayOfWeek', + match: function (string, options) { + return options.locale.match.weekdays(string, {type: 'short'}) || + options.locale.match.weekdays(string, {type: 'narrow'}) + }, + parse: function (matchResult, options) { + var parseResult = options.locale.match.weekday(matchResult, {type: 'short'}); + + if (parseResult == null) { + parseResult = options.locale.match.weekday(matchResult, {type: 'narrow'}); + } + + return parseResult + } + }, + + // Day of week: Sunday, Monday, ..., Saturday + 'dddd': { + unit: 'dayOfWeek', + match: function (string, options) { + return options.locale.match.weekdays(string, {type: 'long'}) || + options.locale.match.weekdays(string, {type: 'short'}) || + options.locale.match.weekdays(string, {type: 'narrow'}) + }, + parse: function (matchResult, options) { + var parseResult = options.locale.match.weekday(matchResult, {type: 'long'}); + + if (parseResult == null) { + parseResult = options.locale.match.weekday(matchResult, {type: 'short'}); + + if (parseResult == null) { + parseResult = options.locale.match.weekday(matchResult, {type: 'narrow'}); + } + } + + return parseResult + } + }, + + // Day of ISO week: 1, 2, ..., 7 + 'E': { + unit: 'dayOfISOWeek', + match: patterns$1.singleDigit, + parse: function (matchResult) { + return parseDecimal$1(matchResult) + } + }, + + // Day of month: 1, 2, ..., 31 + 'D': { + unit: 'dayOfMonth', + match: patterns$1.D, + parse: parseDecimal$1 + }, + + // Ordinal day of month + 'Do': { + unit: 'dayOfMonth', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'dayOfMonth'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'dayOfMonth'}) + } + }, + + // Day of month: 01, 02, ..., 31 + 'DD': { + unit: 'dayOfMonth', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // Day of year: 1, 2, ..., 366 + 'DDD': { + unit: 'dayOfYear', + match: patterns$1.DDD, + parse: parseDecimal$1 + }, + + // Ordinal day of year + 'DDDo': { + unit: 'dayOfYear', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'dayOfYear'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'dayOfYear'}) + } + }, + + // Day of year: 001, 002, ..., 366 + 'DDDD': { + unit: 'dayOfYear', + match: patterns$1.threeDigits, + parse: parseDecimal$1 + }, + + // AM, PM + 'A': { + unit: 'timeOfDay', + match: function (string, options) { + return options.locale.match.timesOfDay(string, {type: 'short'}) + }, + parse: function (matchResult, options) { + return options.locale.match.timeOfDay(matchResult, {type: 'short'}) + } + }, + + // a.m., p.m. + 'aa': { + unit: 'timeOfDay', + match: function (string, options) { + return options.locale.match.timesOfDay(string, {type: 'long'}) || + options.locale.match.timesOfDay(string, {type: 'short'}) + }, + parse: function (matchResult, options) { + var parseResult = options.locale.match.timeOfDay(matchResult, {type: 'long'}); + + if (parseResult == null) { + parseResult = options.locale.match.timeOfDay(matchResult, {type: 'short'}); + } + + return parseResult + } + }, + + // Hour: 0, 1, ... 23 + 'H': { + unit: 'hours', + match: patterns$1.H, + parse: parseDecimal$1 + }, + + // Hour: 00, 01, ..., 23 + 'HH': { + unit: 'hours', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // Hour: 1, 2, ..., 12 + 'h': { + unit: 'timeOfDayHours', + match: patterns$1.M, + parse: parseDecimal$1 + }, + + // Hour: 01, 02, ..., 12 + 'hh': { + unit: 'timeOfDayHours', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // Minute: 0, 1, ..., 59 + 'm': { + unit: 'minutes', + match: patterns$1.m, + parse: parseDecimal$1 + }, + + // Minute: 00, 01, ..., 59 + 'mm': { + unit: 'minutes', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // Second: 0, 1, ..., 59 + 's': { + unit: 'seconds', + match: patterns$1.m, + parse: parseDecimal$1 + }, + + // Second: 00, 01, ..., 59 + 'ss': { + unit: 'seconds', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // 1/10 of second: 0, 1, ..., 9 + 'S': { + unit: 'milliseconds', + match: patterns$1.singleDigit, + parse: function (matchResult) { + return parseDecimal$1(matchResult) * 100 + } + }, + + // 1/100 of second: 00, 01, ..., 99 + 'SS': { + unit: 'milliseconds', + match: patterns$1.twoDigits, + parse: function (matchResult) { + return parseDecimal$1(matchResult) * 10 + } + }, + + // Millisecond: 000, 001, ..., 999 + 'SSS': { + unit: 'milliseconds', + match: patterns$1.threeDigits, + parse: parseDecimal$1 + }, + + // Timezone: -01:00, +00:00, ... +12:00 + 'Z': { + unit: 'timezone', + match: patterns$1.Z, + parse: function (matchResult) { + var sign = matchResult[1]; + var hours = parseInt(matchResult[2], 10); + var minutes = parseInt(matchResult[3], 10); + var absoluteOffset = hours * 60 + minutes; + return (sign === '+') ? absoluteOffset : -absoluteOffset + } + }, + + // Timezone: -0100, +0000, ... +1200 + 'ZZ': { + unit: 'timezone', + match: patterns$1.ZZ, + parse: function (matchResult) { + var sign = matchResult[1]; + var hours = parseInt(matchResult[2], 10); + var minutes = parseInt(matchResult[3], 10); + var absoluteOffset = hours * 60 + minutes; + return (sign === '+') ? absoluteOffset : -absoluteOffset + } + }, + + // Seconds timestamp: 512969520 + 'X': { + unit: 'timestamp', + match: patterns$1.anyDigits, + parse: function (matchResult) { + return parseDecimal$1(matchResult) * 1000 + } + }, + + // Milliseconds timestamp: 512969520900 + 'x': { + unit: 'timestamp', + match: patterns$1.anyDigits, + parse: parseDecimal$1 + } + }; + + parsers['a'] = parsers['A']; + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function setUTCDay (dirtyDate, dirtyDay, dirtyOptions) { + var options = dirtyOptions || {}; + var locale = options.locale; + var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn; + var defaultWeekStartsOn = localeWeekStartsOn === undefined ? 0 : Number(localeWeekStartsOn); + var weekStartsOn = options.weekStartsOn === undefined ? defaultWeekStartsOn : Number(options.weekStartsOn); + + // Test if weekStartsOn is between 0 and 6 _and_ is not NaN + if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) { + throw new RangeError('weekStartsOn must be between 0 and 6 inclusively') + } + + var date = toDate(dirtyDate, dirtyOptions); + var day = Number(dirtyDay); + + var currentDay = date.getUTCDay(); + + var remainder = day % 7; + var dayIndex = (remainder + 7) % 7; + + var diff = (dayIndex < weekStartsOn ? 7 : 0) + day - currentDay; + + date.setUTCDate(date.getUTCDate() + diff); + return date + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function setUTCISODay (dirtyDate, dirtyDay, dirtyOptions) { + var day = Number(dirtyDay); + + if (day % 7 === 0) { + day = day - 7; + } + + var weekStartsOn = 1; + var date = toDate(dirtyDate, dirtyOptions); + var currentDay = date.getUTCDay(); + + var remainder = day % 7; + var dayIndex = (remainder + 7) % 7; + + var diff = (dayIndex < weekStartsOn ? 7 : 0) + day - currentDay; + + date.setUTCDate(date.getUTCDate() + diff); + return date + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function setUTCISOWeek (dirtyDate, dirtyISOWeek, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var isoWeek = Number(dirtyISOWeek); + var diff = getUTCISOWeek(date, dirtyOptions) - isoWeek; + date.setUTCDate(date.getUTCDate() - diff * 7); + return date + } + + var MILLISECONDS_IN_DAY$3 = 86400000; + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function setUTCISOWeekYear (dirtyDate, dirtyISOYear, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var isoYear = Number(dirtyISOYear); + var dateStartOfYear = startOfUTCISOWeekYear(date, dirtyOptions); + var diff = Math.floor((date.getTime() - dateStartOfYear.getTime()) / MILLISECONDS_IN_DAY$3); + var fourthOfJanuary = new Date(0); + fourthOfJanuary.setUTCFullYear(isoYear, 0, 4); + fourthOfJanuary.setUTCHours(0, 0, 0, 0); + date = startOfUTCISOWeekYear(fourthOfJanuary, dirtyOptions); + date.setUTCDate(date.getUTCDate() + diff); + return date + } + + var MILLISECONDS_IN_MINUTE$6 = 60000; + + function setTimeOfDay (hours, timeOfDay) { + var isAM = timeOfDay === 0; + + if (isAM) { + if (hours === 12) { + return 0 + } + } else { + if (hours !== 12) { + return 12 + hours + } + } + + return hours + } + + var units = { + twoDigitYear: { + priority: 10, + set: function (dateValues, value) { + var century = Math.floor(dateValues.date.getUTCFullYear() / 100); + var year = century * 100 + value; + dateValues.date.setUTCFullYear(year, 0, 1); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + year: { + priority: 10, + set: function (dateValues, value) { + dateValues.date.setUTCFullYear(value, 0, 1); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + isoYear: { + priority: 10, + set: function (dateValues, value, options) { + dateValues.date = startOfUTCISOWeekYear(setUTCISOWeekYear(dateValues.date, value, options), options); + return dateValues + } + }, + + quarter: { + priority: 20, + set: function (dateValues, value) { + dateValues.date.setUTCMonth((value - 1) * 3, 1); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + month: { + priority: 30, + set: function (dateValues, value) { + dateValues.date.setUTCMonth(value, 1); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + isoWeek: { + priority: 40, + set: function (dateValues, value, options) { + dateValues.date = startOfUTCISOWeek(setUTCISOWeek(dateValues.date, value, options), options); + return dateValues + } + }, + + dayOfWeek: { + priority: 50, + set: function (dateValues, value, options) { + dateValues.date = setUTCDay(dateValues.date, value, options); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + dayOfISOWeek: { + priority: 50, + set: function (dateValues, value, options) { + dateValues.date = setUTCISODay(dateValues.date, value, options); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + dayOfMonth: { + priority: 50, + set: function (dateValues, value) { + dateValues.date.setUTCDate(value); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + dayOfYear: { + priority: 50, + set: function (dateValues, value) { + dateValues.date.setUTCMonth(0, value); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + timeOfDay: { + priority: 60, + set: function (dateValues, value, options) { + dateValues.timeOfDay = value; + return dateValues + } + }, + + hours: { + priority: 70, + set: function (dateValues, value, options) { + dateValues.date.setUTCHours(value, 0, 0, 0); + return dateValues + } + }, + + timeOfDayHours: { + priority: 70, + set: function (dateValues, value, options) { + var timeOfDay = dateValues.timeOfDay; + if (timeOfDay != null) { + value = setTimeOfDay(value, timeOfDay); + } + dateValues.date.setUTCHours(value, 0, 0, 0); + return dateValues + } + }, + + minutes: { + priority: 80, + set: function (dateValues, value) { + dateValues.date.setUTCMinutes(value, 0, 0); + return dateValues + } + }, + + seconds: { + priority: 90, + set: function (dateValues, value) { + dateValues.date.setUTCSeconds(value, 0); + return dateValues + } + }, + + milliseconds: { + priority: 100, + set: function (dateValues, value) { + dateValues.date.setUTCMilliseconds(value); + return dateValues + } + }, + + timezone: { + priority: 110, + set: function (dateValues, value) { + dateValues.date = new Date(dateValues.date.getTime() - value * MILLISECONDS_IN_MINUTE$6); + return dateValues + } + }, + + timestamp: { + priority: 120, + set: function (dateValues, value) { + dateValues.date = new Date(value); + return dateValues + } + } + }; + + var TIMEZONE_UNIT_PRIORITY = 110; + var MILLISECONDS_IN_MINUTE$7 = 60000; + + var longFormattingTokensRegExp$1 = /(\[[^[]*])|(\\)?(LTS|LT|LLLL|LLL|LL|L|llll|lll|ll|l)/g; + var defaultParsingTokensRegExp = /(\[[^[]*])|(\\)?(x|ss|s|mm|m|hh|h|do|dddd|ddd|dd|d|aa|a|ZZ|Z|YYYY|YY|X|Wo|WW|W|SSS|SS|S|Qo|Q|Mo|MMMM|MMM|MM|M|HH|H|GGGG|GG|E|Do|DDDo|DDDD|DDD|DD|D|A|.)/g; + + /** + * @name parse + * @category Common Helpers + * @summary Parse the date. + * + * @description + * Return the date parsed from string using the given format. + * + * Accepted format tokens: + * | Unit | Priority | Token | Input examples | + * |-------------------------|----------|-------|----------------------------------| + * | Year | 10 | YY | 00, 01, ..., 99 | + * | | | YYYY | 1900, 1901, ..., 2099 | + * | ISO week-numbering year | 10 | GG | 00, 01, ..., 99 | + * | | | GGGG | 1900, 1901, ..., 2099 | + * | Quarter | 20 | Q | 1, 2, 3, 4 | + * | | | Qo | 1st, 2nd, 3rd, 4th | + * | Month | 30 | M | 1, 2, ..., 12 | + * | | | Mo | 1st, 2nd, ..., 12th | + * | | | MM | 01, 02, ..., 12 | + * | | | MMM | Jan, Feb, ..., Dec | + * | | | MMMM | January, February, ..., December | + * | ISO week | 40 | W | 1, 2, ..., 53 | + * | | | Wo | 1st, 2nd, ..., 53rd | + * | | | WW | 01, 02, ..., 53 | + * | Day of week | 50 | d | 0, 1, ..., 6 | + * | | | do | 0th, 1st, ..., 6th | + * | | | dd | Su, Mo, ..., Sa | + * | | | ddd | Sun, Mon, ..., Sat | + * | | | dddd | Sunday, Monday, ..., Saturday | + * | Day of ISO week | 50 | E | 1, 2, ..., 7 | + * | Day of month | 50 | D | 1, 2, ..., 31 | + * | | | Do | 1st, 2nd, ..., 31st | + * | | | DD | 01, 02, ..., 31 | + * | Day of year | 50 | DDD | 1, 2, ..., 366 | + * | | | DDDo | 1st, 2nd, ..., 366th | + * | | | DDDD | 001, 002, ..., 366 | + * | Time of day | 60 | A | AM, PM | + * | | | a | am, pm | + * | | | aa | a.m., p.m. | + * | Hour | 70 | H | 0, 1, ... 23 | + * | | | HH | 00, 01, ... 23 | + * | Time of day hour | 70 | h | 1, 2, ..., 12 | + * | | | hh | 01, 02, ..., 12 | + * | Minute | 80 | m | 0, 1, ..., 59 | + * | | | mm | 00, 01, ..., 59 | + * | Second | 90 | s | 0, 1, ..., 59 | + * | | | ss | 00, 01, ..., 59 | + * | 1/10 of second | 100 | S | 0, 1, ..., 9 | + * | 1/100 of second | 100 | SS | 00, 01, ..., 99 | + * | Millisecond | 100 | SSS | 000, 001, ..., 999 | + * | Timezone | 110 | Z | -01:00, +00:00, ... +12:00 | + * | | | ZZ | -0100, +0000, ..., +1200 | + * | Seconds timestamp | 120 | X | 512969520 | + * | Milliseconds timestamp | 120 | x | 512969520900 | + * + * Values will be assigned to the date in the ascending order of its unit's priority. + * Units of an equal priority overwrite each other in the order of appearance. + * + * If no values of higher priority are parsed (e.g. when parsing string 'January 1st' without a year), + * the values will be taken from 3rd argument `baseDate` which works as a context of parsing. + * + * `baseDate` must be passed for correct work of the function. + * If you're not sure which `baseDate` to supply, create a new instance of Date: + * `parse('02/11/2014', 'MM/DD/YYYY', new Date())` + * In this case parsing will be done in the context of the current date. + * If `baseDate` is `Invalid Date` or a value not convertible to valid `Date`, + * then `Invalid Date` will be returned. + * + * Also, `parse` unfolds long formats like those in [format]{@link https://date-fns.org/docs/format}: + * | Token | Input examples | + * |-------|--------------------------------| + * | LT | 05:30 a.m. | + * | LTS | 05:30:15 a.m. | + * | L | 07/02/1995 | + * | l | 7/2/1995 | + * | LL | July 2 1995 | + * | ll | Jul 2 1995 | + * | LLL | July 2 1995 05:30 a.m. | + * | lll | Jul 2 1995 05:30 a.m. | + * | LLLL | Sunday, July 2 1995 05:30 a.m. | + * | llll | Sun, Jul 2 1995 05:30 a.m. | + * + * The characters wrapped in square brackets in the format string are escaped. + * + * The result may vary by locale. + * + * If `formatString` matches with `dateString` but does not provides tokens, `baseDate` will be returned. + * + * If parsing failed, `Invalid Date` will be returned. + * Invalid Date is a Date, whose time value is NaN. + * Time value of Date: http://es5.github.io/#x15.9.1.1 + * + * @param {String} dateString - the string to parse + * @param {String} formatString - the string of tokens + * @param {Date|String|Number} baseDate - the date to took the missing higher priority values from + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale} + * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday) + * @returns {Date} the parsed date + * @throws {TypeError} 3 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6 + * @throws {RangeError} `options.locale` must contain `match` property + * @throws {RangeError} `options.locale` must contain `formatLong` property + * + * @example + * // Parse 11 February 2014 from middle-endian format: + * var result = parse( + * '02/11/2014', + * 'MM/DD/YYYY', + * new Date() + * ) + * //=> Tue Feb 11 2014 00:00:00 + * + * @example + * // Parse 28th of February in English locale in the context of 2010 year: + * import eoLocale from 'date-fns/locale/eo' + * var result = parse( + * '28-a de februaro', + * 'Do [de] MMMM', + * new Date(2010, 0, 1) + * {locale: eoLocale} + * ) + * //=> Sun Feb 28 2010 00:00:00 + */ + function parse (dirtyDateString, dirtyFormatString, dirtyBaseDate, dirtyOptions) { + if (arguments.length < 3) { + throw new TypeError('3 arguments required, but only ' + arguments.length + ' present') + } + + var dateString = String(dirtyDateString); + var options = dirtyOptions || {}; + + var weekStartsOn = options.weekStartsOn === undefined ? 0 : Number(options.weekStartsOn); + + // Test if weekStartsOn is between 0 and 6 _and_ is not NaN + if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) { + throw new RangeError('weekStartsOn must be between 0 and 6 inclusively') + } + + var locale$$1 = options.locale || locale; + var localeParsers = locale$$1.parsers || {}; + var localeUnits = locale$$1.units || {}; + + if (!locale$$1.match) { + throw new RangeError('locale must contain match property') + } + + if (!locale$$1.formatLong) { + throw new RangeError('locale must contain formatLong property') + } + + var formatString = String(dirtyFormatString) + .replace(longFormattingTokensRegExp$1, function (substring) { + if (substring[0] === '[') { + return substring + } + + if (substring[0] === '\\') { + return cleanEscapedString$1(substring) + } + + return locale$$1.formatLong(substring) + }); + + if (formatString === '') { + if (dateString === '') { + return toDate(dirtyBaseDate, options) + } else { + return new Date(NaN) + } + } + + var subFnOptions = cloneObject(options); + subFnOptions.locale = locale$$1; + + var tokens = formatString.match(locale$$1.parsingTokensRegExp || defaultParsingTokensRegExp); + var tokensLength = tokens.length; + + // If timezone isn't specified, it will be set to the system timezone + var setters = [{ + priority: TIMEZONE_UNIT_PRIORITY, + set: dateToSystemTimezone, + index: 0 + }]; + + var i; + for (i = 0; i < tokensLength; i++) { + var token = tokens[i]; + var parser = localeParsers[token] || parsers[token]; + if (parser) { + var matchResult; + + if (parser.match instanceof RegExp) { + matchResult = parser.match.exec(dateString); + } else { + matchResult = parser.match(dateString, subFnOptions); + } + + if (!matchResult) { + return new Date(NaN) + } + + var unitName = parser.unit; + var unit = localeUnits[unitName] || units[unitName]; + + setters.push({ + priority: unit.priority, + set: unit.set, + value: parser.parse(matchResult, subFnOptions), + index: setters.length + }); + + var substring = matchResult[0]; + dateString = dateString.slice(substring.length); + } else { + var head = tokens[i].match(/^\[.*]$/) ? tokens[i].replace(/^\[|]$/g, '') : tokens[i]; + if (dateString.indexOf(head) === 0) { + dateString = dateString.slice(head.length); + } else { + return new Date(NaN) + } + } + } + + var uniquePrioritySetters = setters + .map(function (setter) { + return setter.priority + }) + .sort(function (a, b) { + return a - b + }) + .filter(function (priority, index, array) { + return array.indexOf(priority) === index + }) + .map(function (priority) { + return setters + .filter(function (setter) { + return setter.priority === priority + }) + .reverse() + }) + .map(function (setterArray) { + return setterArray[0] + }); + + var date = toDate(dirtyBaseDate, options); + + if (isNaN(date)) { + return new Date(NaN) + } + + // Convert the date in system timezone to the same date in UTC+00:00 timezone. + // This ensures that when UTC functions will be implemented, locales will be compatible with them. + // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/37 + var utcDate = subMinutes(date, date.getTimezoneOffset()); + + var dateValues = {date: utcDate}; + + var settersLength = uniquePrioritySetters.length; + for (i = 0; i < settersLength; i++) { + var setter = uniquePrioritySetters[i]; + dateValues = setter.set(dateValues, setter.value, subFnOptions); + } + + return dateValues.date + } + + function dateToSystemTimezone (dateValues) { + var date = dateValues.date; + var time = date.getTime(); + + // Get the system timezone offset at (moment of time - offset) + var offset = date.getTimezoneOffset(); + + // Get the system timezone offset at the exact moment of time + offset = new Date(time + offset * MILLISECONDS_IN_MINUTE$7).getTimezoneOffset(); + + // Convert date in timezone "UTC+00:00" to the system timezone + dateValues.date = new Date(time + offset * MILLISECONDS_IN_MINUTE$7); + + return dateValues + } + + function cleanEscapedString$1 (input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|]$/g, '') + } + return input.replace(/\\/g, '') + } + + // This file is generated automatically by `scripts/build/indices.js`. Please, don't change it. + + // + + /** + * Custom parse behavior on top of date-fns parse function. + */ + function parseDate$1 (date, format$$1) { + if (typeof date !== 'string') { + return isValid(date) ? date : null; + } + + var parsed = parse(date, format$$1, new Date()); + + // if date is not valid or the formatted output after parsing does not match + // the string value passed in (avoids overflows) + if (!isValid(parsed) || format(parsed, format$$1) !== date) { + return null; + } + + return parsed; + } + + var afterValidator = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var targetValue = ref.targetValue; + var inclusion = ref.inclusion; if ( inclusion === void 0 ) inclusion = false; + var format$$1 = ref.format; + + if (typeof format$$1 === 'undefined') { + format$$1 = inclusion; + inclusion = false; + } + + value = parseDate$1(value, format$$1); + targetValue = parseDate$1(targetValue, format$$1); + + // if either is not valid. + if (!value || !targetValue) { + return false; + } + + return isAfter(value, targetValue) || (inclusion && isEqual(value, targetValue)); + }; + + var options = { + hasTarget: true, + isDate: true + }; + + // required to convert from a list of array values to an object. + var paramNames = ['targetValue', 'inclusion', 'format']; + + var after = { + validate: afterValidator, + options: options, + paramNames: paramNames + }; + + /** + * Some Alpha Regex helpers. + * https://github.com/chriso/validator.js/blob/master/src/lib/alpha.js + */ + + var alpha = { + en: /^[A-Z]*$/i, + cs: /^[A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]*$/i, + da: /^[A-ZÆØÅ]*$/i, + de: /^[A-ZÄÖÜß]*$/i, + es: /^[A-ZÁÉÍÑÓÚÜ]*$/i, + fr: /^[A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]*$/i, + lt: /^[A-ZĄČĘĖĮŠŲŪŽ]*$/i, + nl: /^[A-ZÉËÏÓÖÜ]*$/i, + hu: /^[A-ZÁÉÍÓÖŐÚÜŰ]*$/i, + pl: /^[A-ZĄĆĘŚŁŃÓŻŹ]*$/i, + pt: /^[A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]*$/i, + ru: /^[А-ЯЁ]*$/i, + sk: /^[A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ]*$/i, + sr: /^[A-ZČĆŽŠĐ]*$/i, + tr: /^[A-ZÇĞİıÖŞÜ]*$/i, + uk: /^[А-ЩЬЮЯЄІЇҐ]*$/i, + ar: /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]*$/ + }; + + var alphaSpaces = { + en: /^[A-Z\s]*$/i, + cs: /^[A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ\s]*$/i, + da: /^[A-ZÆØÅ\s]*$/i, + de: /^[A-ZÄÖÜß\s]*$/i, + es: /^[A-ZÁÉÍÑÓÚÜ\s]*$/i, + fr: /^[A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ\s]*$/i, + lt: /^[A-ZĄČĘĖĮŠŲŪŽ\s]*$/i, + nl: /^[A-ZÉËÏÓÖÜ\s]*$/i, + hu: /^[A-ZÁÉÍÓÖŐÚÜŰ\s]*$/i, + pl: /^[A-ZĄĆĘŚŁŃÓŻŹ\s]*$/i, + pt: /^[A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ\s]*$/i, + ru: /^[А-ЯЁ\s]*$/i, + sk: /^[A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ\s]*$/i, + sr: /^[A-ZČĆŽŠĐ\s]*$/i, + tr: /^[A-ZÇĞİıÖŞÜ\s]*$/i, + uk: /^[А-ЩЬЮЯЄІЇҐ\s]*$/i, + ar: /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ\s]*$/ + }; + + var alphanumeric = { + en: /^[0-9A-Z]*$/i, + cs: /^[0-9A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]*$/i, + da: /^[0-9A-ZÆØÅ]$/i, + de: /^[0-9A-ZÄÖÜß]*$/i, + es: /^[0-9A-ZÁÉÍÑÓÚÜ]*$/i, + fr: /^[0-9A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]*$/i, + lt: /^[0-9A-ZĄČĘĖĮŠŲŪŽ]*$/i, + hu: /^[0-9A-ZÁÉÍÓÖŐÚÜŰ]*$/i, + nl: /^[0-9A-ZÉËÏÓÖÜ]*$/i, + pl: /^[0-9A-ZĄĆĘŚŁŃÓŻŹ]*$/i, + pt: /^[0-9A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]*$/i, + ru: /^[0-9А-ЯЁ]*$/i, + sk: /^[0-9A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ]*$/i, + sr: /^[0-9A-ZČĆŽŠĐ]*$/i, + tr: /^[0-9A-ZÇĞİıÖŞÜ]*$/i, + uk: /^[0-9А-ЩЬЮЯЄІЇҐ]*$/i, + ar: /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]*$/ + }; + + var alphaDash = { + en: /^[0-9A-Z_-]*$/i, + cs: /^[0-9A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ_-]*$/i, + da: /^[0-9A-ZÆØÅ_-]*$/i, + de: /^[0-9A-ZÄÖÜß_-]*$/i, + es: /^[0-9A-ZÁÉÍÑÓÚÜ_-]*$/i, + fr: /^[0-9A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ_-]*$/i, + lt: /^[0-9A-ZĄČĘĖĮŠŲŪŽ_-]*$/i, + nl: /^[0-9A-ZÉËÏÓÖÜ_-]*$/i, + hu: /^[0-9A-ZÁÉÍÓÖŐÚÜŰ_-]*$/i, + pl: /^[0-9A-ZĄĆĘŚŁŃÓŻŹ_-]*$/i, + pt: /^[0-9A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ_-]*$/i, + ru: /^[0-9А-ЯЁ_-]*$/i, + sk: /^[0-9A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ_-]*$/i, + sr: /^[0-9A-ZČĆŽŠĐ_-]*$/i, + tr: /^[0-9A-ZÇĞİıÖŞÜ_-]*$/i, + uk: /^[0-9А-ЩЬЮЯЄІЇҐ_-]*$/i, + ar: /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ_-]*$/ + }; + + var validate = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var locale = ref.locale; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate(val, [locale]); }); + } + + // Match at least one locale. + if (! locale) { + return Object.keys(alpha).some(function (loc) { return alpha[loc].test(value); }); + } + + return (alpha[locale] || alpha.en).test(value); + }; + + var paramNames$1 = ['locale']; + + var alpha$1 = { + validate: validate, + paramNames: paramNames$1 + }; + + var validate$1 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var locale = ref.locale; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$1(val, [locale]); }); + } + + // Match at least one locale. + if (! locale) { + return Object.keys(alphaDash).some(function (loc) { return alphaDash[loc].test(value); }); + } + + return (alphaDash[locale] || alphaDash.en).test(value); + }; + + var paramNames$2 = ['locale']; + + var alpha_dash = { + validate: validate$1, + paramNames: paramNames$2 + }; + + var validate$2 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var locale = ref.locale; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$2(val, [locale]); }); + } + + // Match at least one locale. + if (! locale) { + return Object.keys(alphanumeric).some(function (loc) { return alphanumeric[loc].test(value); }); + } + + return (alphanumeric[locale] || alphanumeric.en).test(value); + }; + + var paramNames$3 = ['locale']; + + var alpha_num = { + validate: validate$2, + paramNames: paramNames$3 + }; + + var validate$3 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var locale = ref.locale; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$3(val, [locale]); }); + } + + // Match at least one locale. + if (! locale) { + return Object.keys(alphaSpaces).some(function (loc) { return alphaSpaces[loc].test(value); }); + } + + return (alphaSpaces[locale] || alphaSpaces.en).test(value); + }; + + var paramNames$4 = ['locale']; + + var alpha_spaces = { + validate: validate$3, + paramNames: paramNames$4 + }; + + var validate$4 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var targetValue = ref.targetValue; + var inclusion = ref.inclusion; if ( inclusion === void 0 ) inclusion = false; + var format$$1 = ref.format; + + if (typeof format$$1 === 'undefined') { + format$$1 = inclusion; + inclusion = false; + } + + value = parseDate$1(value, format$$1); + targetValue = parseDate$1(targetValue, format$$1); + + // if either is not valid. + if (!value || !targetValue) { + return false; + } + + return isBefore(value, targetValue) || (inclusion && isEqual(value, targetValue)); + }; + + var options$1 = { + hasTarget: true, + isDate: true + }; + + var paramNames$5 = ['targetValue', 'inclusion', 'format']; + + var before = { + validate: validate$4, + options: options$1, + paramNames: paramNames$5 + }; + + var validate$5 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var min = ref.min; + var max = ref.max; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$5(val, { min: min, max: max }); }); + } + + return Number(min) <= value && Number(max) >= value; + }; + + var paramNames$6 = ['min', 'max']; + + var between = { + validate: validate$5, + paramNames: paramNames$6 + }; + + var validate$6 = function (value, ref) { + var targetValue = ref.targetValue; + + return String(value) === String(targetValue); + }; + var options$2 = { + hasTarget: true + }; + + var paramNames$7 = ['targetValue']; + + var confirmed = { + validate: validate$6, + options: options$2, + paramNames: paramNames$7 + }; + + function unwrapExports (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + var assertString_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = assertString; + function assertString(input) { + var isString = typeof input === 'string' || input instanceof String; + + if (!isString) { + throw new TypeError('This library (validator.js) validates strings only'); + } + } + module.exports = exports['default']; + }); + + unwrapExports(assertString_1); + + var isCreditCard_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = isCreditCard; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + /* eslint-disable max-len */ + var creditCard = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11}|6[27][0-9]{14})$/; + /* eslint-enable max-len */ + + function isCreditCard(str) { + (0, _assertString2.default)(str); + var sanitized = str.replace(/[- ]+/g, ''); + if (!creditCard.test(sanitized)) { + return false; + } + var sum = 0; + var digit = void 0; + var tmpNum = void 0; + var shouldDouble = void 0; + for (var i = sanitized.length - 1; i >= 0; i--) { + digit = sanitized.substring(i, i + 1); + tmpNum = parseInt(digit, 10); + if (shouldDouble) { + tmpNum *= 2; + if (tmpNum >= 10) { + sum += tmpNum % 10 + 1; + } else { + sum += tmpNum; + } + } else { + sum += tmpNum; + } + shouldDouble = !shouldDouble; + } + return !!(sum % 10 === 0 ? sanitized : false); + } + module.exports = exports['default']; + }); + + var isCreditCard = unwrapExports(isCreditCard_1); + + var validate$7 = function (value) { return isCreditCard(String(value)); }; + + var credit_card = { + validate: validate$7 + }; + + var validate$8 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var min$$1 = ref.min; + var max$$1 = ref.max; + var inclusivity = ref.inclusivity; if ( inclusivity === void 0 ) inclusivity = '()'; + var format$$1 = ref.format; + + if (typeof format$$1 === 'undefined') { + format$$1 = inclusivity; + inclusivity = '()'; + } + + var minDate = parseDate$1(String(min$$1), format$$1); + var maxDate = parseDate$1(String(max$$1), format$$1); + var dateVal = parseDate$1(String(value), format$$1); + + if (!minDate || !maxDate || !dateVal) { + return false; + } + + if (inclusivity === '()') { + return isAfter(dateVal, minDate) && isBefore(dateVal, maxDate); + } + + if (inclusivity === '(]') { + return isAfter(dateVal, minDate) && (isEqual(dateVal, maxDate) || isBefore(dateVal, maxDate)); + } + + if (inclusivity === '[)') { + return isBefore(dateVal, maxDate) && (isEqual(dateVal, minDate) || isAfter(dateVal, minDate)); + } + + return isEqual(dateVal, maxDate) || isEqual(dateVal, minDate) || + (isBefore(dateVal, maxDate) && isAfter(dateVal, minDate)); + }; + + var options$3 = { + isDate: true + }; + + var paramNames$8 = ['min', 'max', 'inclusivity', 'format']; + + var date_between = { + validate: validate$8, + options: options$3, + paramNames: paramNames$8 + }; + + var validate$9 = function (value, ref) { + var format = ref.format; + + return !!parseDate$1(value, format); + }; + + var options$4 = { + isDate: true + }; + + var paramNames$9 = ['format']; + + var date_format = { + validate: validate$9, + options: options$4, + paramNames: paramNames$9 + }; + + var validate$a = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var decimals = ref.decimals; if ( decimals === void 0 ) decimals = '*'; + var separator = ref.separator; if ( separator === void 0 ) separator = '.'; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$a(val, { decimals: decimals, separator: separator }); }); + } + + if (value === null || value === undefined || value === '') { + return true; + } + + // if is 0. + if (Number(decimals) === 0) { + return /^-?\d*$/.test(value); + } + + var regexPart = decimals === '*' ? '+' : ("{1," + decimals + "}"); + var regex = new RegExp(("^-?\\d*(\\" + separator + "\\d" + regexPart + ")?$")); + + if (! regex.test(value)) { + return false; + } + + var parsedValue = parseFloat(value); + + // eslint-disable-next-line + return parsedValue === parsedValue; + }; + + var paramNames$a = ['decimals', 'separator']; + + var decimal = { + validate: validate$a, + paramNames: paramNames$a + }; + + var validate$b = function (value, ref) { + var length = ref[0]; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$b(val, [length]); }); + } + var strVal = String(value); + + return /^[0-9]*$/.test(strVal) && strVal.length === Number(length); + }; + + var digits = { + validate: validate$b + }; + + var validateImage = function (file, width, height) { + var URL = window.URL || window.webkitURL; + return new Promise(function (resolve) { + var image = new Image(); + image.onerror = function () { return resolve({ valid: false }); }; + image.onload = function () { return resolve({ + valid: image.width === Number(width) && image.height === Number(height) + }); }; + + image.src = URL.createObjectURL(file); + }); + }; + + var validate$c = function (files, ref) { + var width = ref[0]; + var height = ref[1]; + + var list = []; + for (var i = 0; i < files.length; i++) { + // if file is not an image, reject. + if (! /\.(jpg|svg|jpeg|png|bmp|gif)$/i.test(files[i].name)) { + return false; + } + + list.push(files[i]); + } + + return Promise.all(list.map(function (file) { return validateImage(file, width, height); })); + }; + + var dimensions = { + validate: validate$c + }; + + var merge_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = merge; + function merge() { + var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var defaults = arguments[1]; + + for (var key in defaults) { + if (typeof obj[key] === 'undefined') { + obj[key] = defaults[key]; + } + } + return obj; + } + module.exports = exports['default']; + }); + + unwrapExports(merge_1); + + var isByteLength_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + + exports.default = isByteLength; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + /* eslint-disable prefer-rest-params */ + function isByteLength(str, options) { + (0, _assertString2.default)(str); + var min = void 0; + var max = void 0; + if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') { + min = options.min || 0; + max = options.max; + } else { + // backwards compatibility: isByteLength(str, min [, max]) + min = arguments[1]; + max = arguments[2]; + } + var len = encodeURI(str).split(/%..|./).length - 1; + return len >= min && (typeof max === 'undefined' || len <= max); + } + module.exports = exports['default']; + }); + + unwrapExports(isByteLength_1); + + var isFQDN_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = isFQDN; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + + + var _merge2 = _interopRequireDefault(merge_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + var default_fqdn_options = { + require_tld: true, + allow_underscores: false, + allow_trailing_dot: false + }; + + function isFQDN(str, options) { + (0, _assertString2.default)(str); + options = (0, _merge2.default)(options, default_fqdn_options); + + /* Remove the optional trailing dot before checking validity */ + if (options.allow_trailing_dot && str[str.length - 1] === '.') { + str = str.substring(0, str.length - 1); + } + var parts = str.split('.'); + for (var i = 0; i < parts.length; i++) { + if (parts[i].length > 63) { + return false; + } + } + if (options.require_tld) { + var tld = parts.pop(); + if (!parts.length || !/^([a-z\u00a1-\uffff]{2,}|xn[a-z0-9-]{2,})$/i.test(tld)) { + return false; + } + // disallow spaces + if (/[\s\u2002-\u200B\u202F\u205F\u3000\uFEFF\uDB40\uDC20]/.test(tld)) { + return false; + } + } + for (var part, _i = 0; _i < parts.length; _i++) { + part = parts[_i]; + if (options.allow_underscores) { + part = part.replace(/_/g, ''); + } + if (!/^[a-z\u00a1-\uffff0-9-]+$/i.test(part)) { + return false; + } + // disallow full-width chars + if (/[\uff01-\uff5e]/.test(part)) { + return false; + } + if (part[0] === '-' || part[part.length - 1] === '-') { + return false; + } + } + return true; + } + module.exports = exports['default']; + }); + + unwrapExports(isFQDN_1); + + var isIP_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = isIP; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + var ipv4Maybe = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/; + var ipv6Block = /^[0-9A-F]{1,4}$/i; + + function isIP(str) { + var version = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + + (0, _assertString2.default)(str); + version = String(version); + if (!version) { + return isIP(str, 4) || isIP(str, 6); + } else if (version === '4') { + if (!ipv4Maybe.test(str)) { + return false; + } + var parts = str.split('.').sort(function (a, b) { + return a - b; + }); + return parts[3] <= 255; + } else if (version === '6') { + var blocks = str.split(':'); + var foundOmissionBlock = false; // marker to indicate :: + + // At least some OS accept the last 32 bits of an IPv6 address + // (i.e. 2 of the blocks) in IPv4 notation, and RFC 3493 says + // that '::ffff:a.b.c.d' is valid for IPv4-mapped IPv6 addresses, + // and '::a.b.c.d' is deprecated, but also valid. + var foundIPv4TransitionBlock = isIP(blocks[blocks.length - 1], 4); + var expectedNumberOfBlocks = foundIPv4TransitionBlock ? 7 : 8; + + if (blocks.length > expectedNumberOfBlocks) { + return false; + } + // initial or final :: + if (str === '::') { + return true; + } else if (str.substr(0, 2) === '::') { + blocks.shift(); + blocks.shift(); + foundOmissionBlock = true; + } else if (str.substr(str.length - 2) === '::') { + blocks.pop(); + blocks.pop(); + foundOmissionBlock = true; + } + + for (var i = 0; i < blocks.length; ++i) { + // test for a :: which can not be at the string start/end + // since those cases have been handled above + if (blocks[i] === '' && i > 0 && i < blocks.length - 1) { + if (foundOmissionBlock) { + return false; // multiple :: in address + } + foundOmissionBlock = true; + } else if (foundIPv4TransitionBlock && i === blocks.length - 1) ; else if (!ipv6Block.test(blocks[i])) { + return false; + } + } + if (foundOmissionBlock) { + return blocks.length >= 1; + } + return blocks.length === expectedNumberOfBlocks; + } + return false; + } + module.exports = exports['default']; + }); + + var isIP = unwrapExports(isIP_1); + + var isEmail_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = isEmail; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + + + var _merge2 = _interopRequireDefault(merge_1); + + + + var _isByteLength2 = _interopRequireDefault(isByteLength_1); + + + + var _isFQDN2 = _interopRequireDefault(isFQDN_1); + + + + var _isIP2 = _interopRequireDefault(isIP_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + var default_email_options = { + allow_display_name: false, + require_display_name: false, + allow_utf8_local_part: true, + require_tld: true + }; + + /* eslint-disable max-len */ + /* eslint-disable no-control-regex */ + var displayName = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\,\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\s]*<(.+)>$/i; + var emailUserPart = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~]+$/i; + var gmailUserPart = /^[a-z\d]+$/; + var quotedEmailUser = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f]))*$/i; + var emailUserUtf8Part = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$/i; + var quotedEmailUserUtf8 = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*$/i; + /* eslint-enable max-len */ + /* eslint-enable no-control-regex */ + + function isEmail(str, options) { + (0, _assertString2.default)(str); + options = (0, _merge2.default)(options, default_email_options); + + if (options.require_display_name || options.allow_display_name) { + var display_email = str.match(displayName); + if (display_email) { + str = display_email[1]; + } else if (options.require_display_name) { + return false; + } + } + + var parts = str.split('@'); + var domain = parts.pop(); + var user = parts.join('@'); + + var lower_domain = domain.toLowerCase(); + + if (options.domain_specific_validation && (lower_domain === 'gmail.com' || lower_domain === 'googlemail.com')) { + /* + Previously we removed dots for gmail addresses before validating. + This was removed because it allows `multiple..dots@gmail.com` + to be reported as valid, but it is not. + Gmail only normalizes single dots, removing them from here is pointless, + should be done in normalizeEmail + */ + user = user.toLowerCase(); + + // Removing sub-address from username before gmail validation + var username = user.split('+')[0]; + + // Dots are not included in gmail length restriction + if (!(0, _isByteLength2.default)(username.replace('.', ''), { min: 6, max: 30 })) { + return false; + } + + var _user_parts = username.split('.'); + for (var i = 0; i < _user_parts.length; i++) { + if (!gmailUserPart.test(_user_parts[i])) { + return false; + } + } + } + + if (!(0, _isByteLength2.default)(user, { max: 64 }) || !(0, _isByteLength2.default)(domain, { max: 254 })) { + return false; + } + + if (!(0, _isFQDN2.default)(domain, { require_tld: options.require_tld })) { + if (!options.allow_ip_domain) { + return false; + } + + if (!(0, _isIP2.default)(domain)) { + if (!domain.startsWith('[') || !domain.endsWith(']')) { + return false; + } + + var noBracketdomain = domain.substr(1, domain.length - 2); + + if (noBracketdomain.length === 0 || !(0, _isIP2.default)(noBracketdomain)) { + return false; + } + } + } + + if (user[0] === '"') { + user = user.slice(1, user.length - 1); + return options.allow_utf8_local_part ? quotedEmailUserUtf8.test(user) : quotedEmailUser.test(user); + } + + var pattern = options.allow_utf8_local_part ? emailUserUtf8Part : emailUserPart; + + var user_parts = user.split('.'); + for (var _i = 0; _i < user_parts.length; _i++) { + if (!pattern.test(user_parts[_i])) { + return false; + } + } + + return true; + } + module.exports = exports['default']; + }); + + var isEmail = unwrapExports(isEmail_1); + + var validate$d = function (value, options) { + if ( options === void 0 ) options = {}; + + if (options.multiple) { + value = value.split(',').map(function (emailStr) { return emailStr.trim(); }); + } + + if (Array.isArray(value)) { + return value.every(function (val) { return isEmail(String(val), options); }); + } + + return isEmail(String(value), options); + }; + + var email = { + validate: validate$d + }; + + // + + var supportsPassive = true; + + var detectPassiveSupport = function () { + try { + var opts = Object.defineProperty({}, 'passive', { + get: function get () { + supportsPassive = true; + } + }); + window.addEventListener('testPassive', null, opts); + window.removeEventListener('testPassive', null, opts); + } catch (e) { + supportsPassive = false; + } + return supportsPassive; + }; + + var addEventListener = function (el, eventName, cb) { + el.addEventListener(eventName, cb, supportsPassive ? { passive: true } : false); + }; + + var isTextInput = function (el) { + return includes(['text', 'password', 'search', 'email', 'tel', 'url', 'textarea'], el.type); + }; + + var isCheckboxOrRadioInput = function (el) { + return includes(['radio', 'checkbox'], el.type); + }; + + var isDateInput = function (el) { + return includes(['date', 'week', 'month', 'datetime-local', 'time'], el.type); + }; + + /** + * Gets the data attribute. the name must be kebab-case. + */ + var getDataAttribute = function (el, name) { return el.getAttribute(("data-vv-" + name)); }; + + /** + * Checks if the values are either null or undefined. + */ + var isNullOrUndefined = function () { + var values = [], len = arguments.length; + while ( len-- ) values[ len ] = arguments[ len ]; + + return values.every(function (value) { + return value === null || value === undefined; + }); + }; + + /** + * Creates the default flags object. + */ + var createFlags = function () { return ({ + untouched: true, + touched: false, + dirty: false, + pristine: true, + valid: null, + invalid: null, + validated: false, + pending: false, + required: false, + changed: false + }); }; + + /** + * Shallow object comparison. + */ + var isEqual$1 = function (lhs, rhs) { + if (lhs instanceof RegExp && rhs instanceof RegExp) { + return isEqual$1(lhs.source, rhs.source) && isEqual$1(lhs.flags, rhs.flags); + } + + if (Array.isArray(lhs) && Array.isArray(rhs)) { + if (lhs.length !== rhs.length) { return false; } + + for (var i = 0; i < lhs.length; i++) { + if (!isEqual$1(lhs[i], rhs[i])) { + return false; + } + } + + return true; + } + + // if both are objects, compare each key recursively. + if (isObject(lhs) && isObject(rhs)) { + return Object.keys(lhs).every(function (key) { + return isEqual$1(lhs[key], rhs[key]); + }) && Object.keys(rhs).every(function (key) { + return isEqual$1(lhs[key], rhs[key]); + }); + } + + return lhs === rhs; + }; + + /** + * Determines the input field scope. + */ + var getScope = function (el) { + var scope = getDataAttribute(el, 'scope'); + if (isNullOrUndefined(scope)) { + var form = getForm(el); + + if (form) { + scope = getDataAttribute(form, 'scope'); + } + } + + return !isNullOrUndefined(scope) ? scope : null; + }; + + /** + * Get the closest form element. + */ + var getForm = function (el) { + if (isNullOrUndefined(el)) { return null; } + + if (el.tagName === 'FORM') { return el; } + + if (!isNullOrUndefined(el.form)) { return el.form; } + + return !isNullOrUndefined(el.parentNode) ? getForm(el.parentNode) : null; + }; + + /** + * Gets the value in an object safely. + */ + var getPath = function (path, target, def) { + if ( def === void 0 ) def = undefined; + + if (!path || !target) { return def; } + + var value = target; + path.split('.').every(function (prop) { + if (prop in value) { + value = value[prop]; + + return true; + } + + value = def; + + return false; + }); + + return value; + }; + + /** + * Checks if path exists within an object. + */ + var hasPath = function (path, target) { + var obj = target; + return path.split('.').every(function (prop) { + if (prop in obj) { + obj = obj[prop]; + + return true; + } + + return false; + }); + }; + + /** + * Parses a rule string expression. + */ + var parseRule = function (rule) { + var params = []; + var name = rule.split(':')[0]; + + if (includes(rule, ':')) { + params = rule.split(':').slice(1).join(':').split(','); + } + + return { name: name, params: params }; + }; + + /** + * Debounces a function. + */ + var debounce = function (fn, wait, immediate, token) { + if ( wait === void 0 ) wait = 0; + if ( immediate === void 0 ) immediate = false; + if ( token === void 0 ) token = { cancelled: false }; + + if (wait === 0) { + return fn; + } + + var timeout; + + return function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var later = function () { + timeout = null; + + if (!immediate && !token.cancelled) { fn.apply(void 0, args); } + }; + /* istanbul ignore next */ + var callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + /* istanbul ignore next */ + if (callNow) { fn.apply(void 0, args); } + }; + }; + + /** + * Appends a rule definition to a list of rules. + */ + var appendRule = function (rule, rules) { + if (!rules) { + return normalizeRules(rule); + } + + if (!rule) { + return normalizeRules(rules); + } + + if (typeof rules === 'string') { + rules = normalizeRules(rules); + } + + return assign({}, rules, normalizeRules(rule)); + }; + + /** + * Normalizes the given rules expression. + */ + var normalizeRules = function (rules) { + // if falsy value return an empty object. + if (!rules) { + return {}; + } + + if (isObject(rules)) { + // $FlowFixMe + return Object.keys(rules).reduce(function (prev, curr) { + var params = []; + // $FlowFixMe + if (rules[curr] === true) { + params = []; + } else if (Array.isArray(rules[curr])) { + params = rules[curr]; + } else if (isObject(rules[curr])) { + params = rules[curr]; + } else { + params = [rules[curr]]; + } + + // $FlowFixMe + if (rules[curr] !== false) { + prev[curr] = params; + } + + return prev; + }, {}); + } + + if (typeof rules !== 'string') { + warn('rules must be either a string or an object.'); + return {}; + } + + return rules.split('|').reduce(function (prev, rule) { + var parsedRule = parseRule(rule); + if (!parsedRule.name) { + return prev; + } + + prev[parsedRule.name] = parsedRule.params; + return prev; + }, {}); + }; + + /** + * Emits a warning to the console. + */ + var warn = function (message) { + console.warn(("[vee-validate] " + message)); // eslint-disable-line + }; + + /** + * Creates a branded error object. + */ + var createError = function (message) { return new Error(("[vee-validate] " + message)); }; + + /** + * Checks if the value is an object. + */ + var isObject = function (obj) { return obj !== null && obj && typeof obj === 'object' && ! Array.isArray(obj); }; + + /** + * Checks if a function is callable. + */ + var isCallable = function (func) { return typeof func === 'function'; }; + + /** + * Check if element has the css class on it. + */ + var hasClass = function (el, className) { + if (el.classList) { + return el.classList.contains(className); + } + + return !!el.className.match(new RegExp(("(\\s|^)" + className + "(\\s|$)"))); + }; + + /** + * Adds the provided css className to the element. + */ + var addClass = function (el, className) { + if (el.classList) { + el.classList.add(className); + return; + } + + if (!hasClass(el, className)) { + el.className += " " + className; + } + }; + + /** + * Remove the provided css className from the element. + */ + var removeClass = function (el, className) { + if (el.classList) { + el.classList.remove(className); + return; + } + + if (hasClass(el, className)) { + var reg = new RegExp(("(\\s|^)" + className + "(\\s|$)")); + el.className = el.className.replace(reg, ' '); + } + }; + + /** + * Adds or removes a class name on the input depending on the status flag. + */ + var toggleClass = function (el, className, status) { + if (!el || !className) { return; } + + if (Array.isArray(className)) { + className.forEach(function (item) { return toggleClass(el, item, status); }); + return; + } + + if (status) { + return addClass(el, className); + } + + removeClass(el, className); + }; + + /** + * Converts an array-like object to array, provides a simple polyfill for Array.from + */ + var toArray = function (arrayLike) { + if (isCallable(Array.from)) { + return Array.from(arrayLike); + } + + var array = []; + var length = arrayLike.length; + /* istanbul ignore next */ + for (var i = 0; i < length; i++) { + array.push(arrayLike[i]); + } + + /* istanbul ignore next */ + return array; + }; + + /** + * Assign polyfill from the mdn. + */ + var assign = function (target) { + var others = [], len = arguments.length - 1; + while ( len-- > 0 ) others[ len ] = arguments[ len + 1 ]; + + /* istanbul ignore else */ + if (isCallable(Object.assign)) { + return Object.assign.apply(Object, [ target ].concat( others )); + } + + /* istanbul ignore next */ + if (target == null) { + throw new TypeError('Cannot convert undefined or null to object'); + } + + /* istanbul ignore next */ + var to = Object(target); + /* istanbul ignore next */ + others.forEach(function (arg) { + // Skip over if undefined or null + if (arg != null) { + Object.keys(arg).forEach(function (key) { + to[key] = arg[key]; + }); + } + }); + /* istanbul ignore next */ + return to; + }; + + var id = 0; + var idTemplate = '{id}'; + + /** + * Generates a unique id. + */ + var uniqId = function () { + // handle too many uses of uniqId, although unlikely. + if (id >= 9999) { + id = 0; + // shift the template. + idTemplate = idTemplate.replace('{id}', '_{id}'); + } + + id++; + var newId = idTemplate.replace('{id}', String(id)); + + return newId; + }; + + /** + * finds the first element that satisfies the predicate callback, polyfills array.find + */ + var find = function (arrayLike, predicate) { + var array = Array.isArray(arrayLike) ? arrayLike : toArray(arrayLike); + for (var i = 0; i < array.length; i++) { + if (predicate(array[i])) { + return array[i]; + } + } + + return undefined; + }; + + var isBuiltInComponent = function (vnode) { + if (!vnode) { + return false; + } + + var tag = vnode.componentOptions.tag; + + return /^(keep-alive|transition|transition-group)$/.test(tag); + }; + + var makeEventsArray = function (events) { + return (typeof events === 'string' && events.length) ? events.split('|') : []; + }; + + var makeDelayObject = function (events, delay, delayConfig) { + if (typeof delay === 'number') { + return events.reduce(function (prev, e) { + prev[e] = delay; + return prev; + }, {}); + } + + return events.reduce(function (prev, e) { + if (typeof delay === 'object' && e in delay) { + prev[e] = delay[e]; + return prev; + } + + if (typeof delayConfig === 'number') { + prev[e] = delayConfig; + return prev; + } + + prev[e] = (delayConfig && delayConfig[e]) || 0; + + return prev; + }, {}); + }; + + var deepParseInt = function (input) { + if (typeof input === 'number') { return input; } + + if (typeof input === 'string') { return parseInt(input); } + + var map = {}; + for (var element in input) { + map[element] = parseInt(input[element]); + } + + return map; + }; + + var merge$1 = function (target, source) { + if (! (isObject(target) && isObject(source))) { + return target; + } + + Object.keys(source).forEach(function (key) { + var obj, obj$1; + + if (isObject(source[key])) { + if (! target[key]) { + assign(target, ( obj = {}, obj[key] = {}, obj )); + } + + merge$1(target[key], source[key]); + return; + } + + assign(target, ( obj$1 = {}, obj$1[key] = source[key], obj$1 )); + }); + + return target; + }; + + var fillRulesFromElement = function (el, rules) { + if (el.required) { + rules = appendRule('required', rules); + } + + if (isTextInput(el)) { + if (el.type === 'email') { + rules = appendRule(("email" + (el.multiple ? ':multiple' : '')), rules); + } + + if (el.pattern) { + rules = appendRule({ regex: el.pattern }, rules); + } + + // 524288 is the max on some browsers and test environments. + if (el.maxLength >= 0 && el.maxLength < 524288) { + rules = appendRule(("max:" + (el.maxLength)), rules); + } + + if (el.minLength > 0) { + rules = appendRule(("min:" + (el.minLength)), rules); + } + + return rules; + } + + if (el.type === 'number') { + rules = appendRule('decimal', rules); + if (el.min !== '') { + rules = appendRule(("min_value:" + (el.min)), rules); + } + + if (el.max !== '') { + rules = appendRule(("max_value:" + (el.max)), rules); + } + + return rules; + } + + if (isDateInput(el)) { + var timeFormat = el.step && Number(el.step) < 60 ? 'HH:mm:ss' : 'HH:mm'; + + if (el.type === 'date') { + return appendRule('date_format:YYYY-MM-DD', rules); + } + + if (el.type === 'datetime-local') { + return appendRule(("date_format:YYYY-MM-DDT" + timeFormat), rules); + } + + if (el.type === 'month') { + return appendRule('date_format:YYYY-MM', rules); + } + + if (el.type === 'week') { + return appendRule('date_format:YYYY-[W]WW', rules); + } + + if (el.type === 'time') { + return appendRule(("date_format:" + timeFormat), rules); + } + } + + return rules; + }; + + var values = function (obj) { + if (isCallable(Object.values)) { + return Object.values(obj); + } + + // fallback to keys() + /* istanbul ignore next */ + return obj[Object.keys(obj)[0]]; + }; + + var parseSelector = function (selector) { + var rule = null; + if (includes(selector, ':')) { + rule = selector.split(':').pop(); + selector = selector.replace((":" + rule), ''); + } + + if (selector[0] === '#') { + return { + id: selector.slice(1), + rule: rule, + name: null, + scope: null + }; + } + + var scope = null; + var name = selector; + if (includes(selector, '.')) { + var parts = selector.split('.'); + scope = parts[0]; + name = parts.slice(1).join('.'); + } + + return { + id: null, + scope: scope, + name: name, + rule: rule + }; + }; + + var includes = function (collection, item) { + return collection.indexOf(item) !== -1; + }; + + var validate$e = function (value, options) { + if (Array.isArray(value)) { + return value.every(function (val) { return validate$e(val, options); }); + } + + return toArray(options).some(function (item) { + // eslint-disable-next-line + return item == value; + }); + }; + + var included = { + validate: validate$e + }; + + var validate$f = function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + return !validate$e.apply(void 0, args); + }; + + var excluded = { + validate: validate$f + }; + + var validate$g = function (files, extensions) { + var regex = new RegExp((".(" + (extensions.join('|')) + ")$"), 'i'); + + return files.every(function (file) { return regex.test(file.name); }); + }; + + var ext = { + validate: validate$g + }; + + var validate$h = function (files) { return files.every(function (file) { return /\.(jpg|svg|jpeg|png|bmp|gif)$/i.test(file.name); }); }; + + var image = { + validate: validate$h + }; + + var validate$i = function (value) { + if (Array.isArray(value)) { + return value.every(function (val) { return /^-?[0-9]+$/.test(String(val)); }); + } + + return /^-?[0-9]+$/.test(String(value)); + }; + + var integer = { + validate: validate$i + }; + + var validate$j = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var version = ref.version; if ( version === void 0 ) version = 4; + + if (isNullOrUndefined(value)) { + value = ''; + } + + if (Array.isArray(value)) { + return value.every(function (val) { return isIP(val, version); }); + } + + return isIP(value, version); + }; + + var paramNames$b = ['version']; + + var ip = { + validate: validate$j, + paramNames: paramNames$b + }; + + var validate$k = function (value, ref) { + if ( ref === void 0 ) ref = []; + var other = ref[0]; + + return value === other; + }; + + var is = { + validate: validate$k + }; + + var validate$l = function (value, ref) { + if ( ref === void 0 ) ref = []; + var other = ref[0]; + + return value !== other; + }; + + var is_not = { + validate: validate$l + }; + + /** + * @param {Array|String} value + * @param {Number} length + * @param {Number} max + */ + var compare = function (value, length, max) { + if (max === undefined) { + return value.length === length; + } + + // cast to number. + max = Number(max); + + return value.length >= length && value.length <= max; + }; + + var validate$m = function (value, ref) { + var length = ref[0]; + var max = ref[1]; if ( max === void 0 ) max = undefined; + + length = Number(length); + if (value === undefined || value === null) { + return false; + } + + if (typeof value === 'number') { + value = String(value); + } + + if (!value.length) { + value = toArray(value); + } + + return compare(value, length, max); + }; + + var length = { + validate: validate$m + }; + + var validate$n = function (value, ref) { + var length = ref[0]; + + if (value === undefined || value === null) { + return length >= 0; + } + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$n(val, [length]); }); + } + + return String(value).length <= length; + }; + + var max$1 = { + validate: validate$n + }; + + var validate$o = function (value, ref) { + var max = ref[0]; + + if (value === null || value === undefined || value === '') { + return false; + } + + if (Array.isArray(value)) { + return value.length > 0 && value.every(function (val) { return validate$o(val, [max]); }); + } + + return Number(value) <= max; + }; + + var max_value = { + validate: validate$o + }; + + var validate$p = function (files, mimes) { + var regex = new RegExp(((mimes.join('|').replace('*', '.+')) + "$"), 'i'); + + return files.every(function (file) { return regex.test(file.type); }); + }; + + var mimes = { + validate: validate$p + }; + + var validate$q = function (value, ref) { + var length = ref[0]; + + if (value === undefined || value === null) { + return false; + } + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$q(val, [length]); }); + } + + return String(value).length >= length; + }; + + var min$1 = { + validate: validate$q + }; + + var validate$r = function (value, ref) { + var min = ref[0]; + + if (value === null || value === undefined || value === '') { + return false; + } + + if (Array.isArray(value)) { + return value.length > 0 && value.every(function (val) { return validate$r(val, [min]); }); + } + + return Number(value) >= min; + }; + + var min_value = { + validate: validate$r + }; + + var validate$s = function (value) { + if (Array.isArray(value)) { + return value.every(function (val) { return /^[0-9]+$/.test(String(val)); }); + } + + return /^[0-9]+$/.test(String(value)); + }; + + var numeric = { + validate: validate$s + }; + + var validate$t = function (value, ref) { + var expression = ref.expression; + + if (typeof expression === 'string') { + expression = new RegExp(expression); + } + + return expression.test(String(value)); + }; + + var paramNames$c = ['expression']; + + var regex = { + validate: validate$t, + paramNames: paramNames$c + }; + + var validate$u = function (value, ref) { + if ( ref === void 0 ) ref = []; + var invalidateFalse = ref[0]; if ( invalidateFalse === void 0 ) invalidateFalse = false; + + if (Array.isArray(value)) { + return !!value.length; + } + + // incase a field considers `false` as an empty value like checkboxes. + if (value === false && invalidateFalse) { + return false; + } + + if (value === undefined || value === null) { + return false; + } + + return !!String(value).trim().length; + }; + + var required = { + validate: validate$u + }; + + var validate$v = function (files, ref) { + var size = ref[0]; + + if (isNaN(size)) { + return false; + } + + var nSize = Number(size) * 1024; + for (var i = 0; i < files.length; i++) { + if (files[i].size > nSize) { + return false; + } + } + + return true; + }; + + var size = { + validate: validate$v + }; + + var isURL_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = isURL; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + + + var _isFQDN2 = _interopRequireDefault(isFQDN_1); + + + + var _isIP2 = _interopRequireDefault(isIP_1); + + + + var _merge2 = _interopRequireDefault(merge_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + var default_url_options = { + protocols: ['http', 'https', 'ftp'], + require_tld: true, + require_protocol: false, + require_host: true, + require_valid_protocol: true, + allow_underscores: false, + allow_trailing_dot: false, + allow_protocol_relative_urls: false + }; + + var wrapped_ipv6 = /^\[([^\]]+)\](?::([0-9]+))?$/; + + function isRegExp(obj) { + return Object.prototype.toString.call(obj) === '[object RegExp]'; + } + + function checkHost(host, matches) { + for (var i = 0; i < matches.length; i++) { + var match = matches[i]; + if (host === match || isRegExp(match) && match.test(host)) { + return true; + } + } + return false; + } + + function isURL(url, options) { + (0, _assertString2.default)(url); + if (!url || url.length >= 2083 || /[\s<>]/.test(url)) { + return false; + } + if (url.indexOf('mailto:') === 0) { + return false; + } + options = (0, _merge2.default)(options, default_url_options); + var protocol = void 0, + auth = void 0, + host = void 0, + hostname = void 0, + port = void 0, + port_str = void 0, + split = void 0, + ipv6 = void 0; + + split = url.split('#'); + url = split.shift(); + + split = url.split('?'); + url = split.shift(); + + split = url.split('://'); + if (split.length > 1) { + protocol = split.shift().toLowerCase(); + if (options.require_valid_protocol && options.protocols.indexOf(protocol) === -1) { + return false; + } + } else if (options.require_protocol) { + return false; + } else if (url.substr(0, 2) === '//') { + if (!options.allow_protocol_relative_urls) { + return false; + } + split[0] = url.substr(2); + } + url = split.join('://'); + + if (url === '') { + return false; + } + + split = url.split('/'); + url = split.shift(); + + if (url === '' && !options.require_host) { + return true; + } + + split = url.split('@'); + if (split.length > 1) { + auth = split.shift(); + if (auth.indexOf(':') >= 0 && auth.split(':').length > 2) { + return false; + } + } + hostname = split.join('@'); + + port_str = null; + ipv6 = null; + var ipv6_match = hostname.match(wrapped_ipv6); + if (ipv6_match) { + host = ''; + ipv6 = ipv6_match[1]; + port_str = ipv6_match[2] || null; + } else { + split = hostname.split(':'); + host = split.shift(); + if (split.length) { + port_str = split.join(':'); + } + } + + if (port_str !== null) { + port = parseInt(port_str, 10); + if (!/^[0-9]+$/.test(port_str) || port <= 0 || port > 65535) { + return false; + } + } + + if (!(0, _isIP2.default)(host) && !(0, _isFQDN2.default)(host, options) && (!ipv6 || !(0, _isIP2.default)(ipv6, 6))) { + return false; + } + + host = host || ipv6; + + if (options.host_whitelist && !checkHost(host, options.host_whitelist)) { + return false; + } + if (options.host_blacklist && checkHost(host, options.host_blacklist)) { + return false; + } + + return true; + } + module.exports = exports['default']; + }); + + var isURL = unwrapExports(isURL_1); + + var validate$w = function (value, options) { + if ( options === void 0 ) options = {}; + + if (isNullOrUndefined(value)) { + value = ''; + } + + if (Array.isArray(value)) { + return value.every(function (val) { return isURL(val, options); }); + } + + return isURL(value, options); + }; + + var url = { + validate: validate$w + }; + + /* eslint-disable camelcase */ + + var Rules = /*#__PURE__*/Object.freeze({ + after: after, + alpha_dash: alpha_dash, + alpha_num: alpha_num, + alpha_spaces: alpha_spaces, + alpha: alpha$1, + before: before, + between: between, + confirmed: confirmed, + credit_card: credit_card, + date_between: date_between, + date_format: date_format, + decimal: decimal, + digits: digits, + dimensions: dimensions, + email: email, + ext: ext, + image: image, + included: included, + integer: integer, + length: length, + ip: ip, + is_not: is_not, + is: is, + max: max$1, + max_value: max_value, + mimes: mimes, + min: min$1, + min_value: min_value, + excluded: excluded, + numeric: numeric, + regex: regex, + required: required, + size: size, + url: url + }); + + /** + * Formates file size. + * + * @param {Number|String} size + */ + var formatFileSize = function (size) { + var units = ['Byte', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + var threshold = 1024; + size = Number(size) * threshold; + var i = size === 0 ? 0 : Math.floor(Math.log(size) / Math.log(threshold)); + return (((size / Math.pow(threshold, i)).toFixed(2) * 1) + " " + (units[i])); + }; + + /** + * Checks if vee-validate is defined globally. + */ + var isDefinedGlobally = function () { + return typeof VeeValidate !== 'undefined'; + }; + + var obj; + + var messages = { + _default: function (field) { return ("The " + field + " value is not valid."); }, + after: function (field, ref) { + var target = ref[0]; + var inclusion = ref[1]; + + return ("The " + field + " must be after " + (inclusion ? 'or equal to ' : '') + target + "."); + }, + alpha_dash: function (field) { return ("The " + field + " field may contain alpha-numeric characters as well as dashes and underscores."); }, + alpha_num: function (field) { return ("The " + field + " field may only contain alpha-numeric characters."); }, + alpha_spaces: function (field) { return ("The " + field + " field may only contain alphabetic characters as well as spaces."); }, + alpha: function (field) { return ("The " + field + " field may only contain alphabetic characters."); }, + before: function (field, ref) { + var target = ref[0]; + var inclusion = ref[1]; + + return ("The " + field + " must be before " + (inclusion ? 'or equal to ' : '') + target + "."); + }, + between: function (field, ref) { + var min = ref[0]; + var max = ref[1]; + + return ("The " + field + " field must be between " + min + " and " + max + "."); + }, + confirmed: function (field) { return ("The " + field + " confirmation does not match."); }, + credit_card: function (field) { return ("The " + field + " field is invalid."); }, + date_between: function (field, ref) { + var min = ref[0]; + var max = ref[1]; + + return ("The " + field + " must be between " + min + " and " + max + "."); + }, + date_format: function (field, ref) { + var format = ref[0]; + + return ("The " + field + " must be in the format " + format + "."); + }, + decimal: function (field, ref) { + if ( ref === void 0 ) ref = []; + var decimals = ref[0]; if ( decimals === void 0 ) decimals = '*'; + + return ("The " + field + " field must be numeric and may contain " + (!decimals || decimals === '*' ? '' : decimals) + " decimal points."); + }, + digits: function (field, ref) { + var length = ref[0]; + + return ("The " + field + " field must be numeric and exactly contain " + length + " digits."); + }, + dimensions: function (field, ref) { + var width = ref[0]; + var height = ref[1]; + + return ("The " + field + " field must be " + width + " pixels by " + height + " pixels."); + }, + email: function (field) { return ("The " + field + " field must be a valid email."); }, + ext: function (field) { return ("The " + field + " field must be a valid file."); }, + image: function (field) { return ("The " + field + " field must be an image."); }, + included: function (field) { return ("The " + field + " field must be a valid value."); }, + integer: function (field) { return ("The " + field + " field must be an integer."); }, + ip: function (field) { return ("The " + field + " field must be a valid ip address."); }, + length: function (field, ref) { + var length = ref[0]; + var max = ref[1]; + + if (max) { + return ("The " + field + " length must be between " + length + " and " + max + "."); + } + + return ("The " + field + " length must be " + length + "."); + }, + max: function (field, ref) { + var length = ref[0]; + + return ("The " + field + " field may not be greater than " + length + " characters."); + }, + max_value: function (field, ref) { + var max = ref[0]; + + return ("The " + field + " field must be " + max + " or less."); + }, + mimes: function (field) { return ("The " + field + " field must have a valid file type."); }, + min: function (field, ref) { + var length = ref[0]; + + return ("The " + field + " field must be at least " + length + " characters."); + }, + min_value: function (field, ref) { + var min = ref[0]; + + return ("The " + field + " field must be " + min + " or more."); + }, + excluded: function (field) { return ("The " + field + " field must be a valid value."); }, + numeric: function (field) { return ("The " + field + " field may only contain numeric characters."); }, + regex: function (field) { return ("The " + field + " field format is invalid."); }, + required: function (field) { return ("The " + field + " field is required."); }, + size: function (field, ref) { + var size = ref[0]; + + return ("The " + field + " size must be less than " + (formatFileSize(size)) + "."); + }, + url: function (field) { return ("The " + field + " field is not a valid URL."); } + }; + + var locale$1 = { + name: 'en', + messages: messages, + attributes: {} + }; + + if (isDefinedGlobally()) { + // eslint-disable-next-line + VeeValidate.Validator.localize(( obj = {}, obj[locale$1.name] = locale$1, obj )); + } + + // + + var LOCALE = 'en'; + + var Dictionary = function Dictionary (dictionary) { + if ( dictionary === void 0 ) dictionary = {}; + + this.container = {}; + this.merge(dictionary); + }; + + var prototypeAccessors = { locale: { configurable: true } }; + + prototypeAccessors.locale.get = function () { + return LOCALE; + }; + + prototypeAccessors.locale.set = function (value) { + LOCALE = value || 'en'; + }; + + Dictionary.prototype.hasLocale = function hasLocale (locale) { + return !!this.container[locale]; + }; + + Dictionary.prototype.setDateFormat = function setDateFormat (locale, format) { + if (!this.container[locale]) { + this.container[locale] = {}; + } + + this.container[locale].dateFormat = format; + }; + + Dictionary.prototype.getDateFormat = function getDateFormat (locale) { + if (!this.container[locale] || !this.container[locale].dateFormat) { + return null; + } + + return this.container[locale].dateFormat; + }; + + Dictionary.prototype.getMessage = function getMessage (locale, key, data) { + var message = null; + if (!this.hasMessage(locale, key)) { + message = this._getDefaultMessage(locale); + } else { + message = this.container[locale].messages[key]; + } + + return isCallable(message) ? message.apply(void 0, data) : message; + }; + + /** + * Gets a specific message for field. falls back to the rule message. + */ + Dictionary.prototype.getFieldMessage = function getFieldMessage (locale, field, key, data) { + if (!this.hasLocale(locale)) { + return this.getMessage(locale, key, data); + } + + var dict = this.container[locale].custom && this.container[locale].custom[field]; + if (!dict || !dict[key]) { + return this.getMessage(locale, key, data); + } + + var message = dict[key]; + return isCallable(message) ? message.apply(void 0, data) : message; + }; + + Dictionary.prototype._getDefaultMessage = function _getDefaultMessage (locale) { + if (this.hasMessage(locale, '_default')) { + return this.container[locale].messages._default; + } + + return this.container.en.messages._default; + }; + + Dictionary.prototype.getAttribute = function getAttribute (locale, key, fallback) { + if ( fallback === void 0 ) fallback = ''; + + if (!this.hasAttribute(locale, key)) { + return fallback; + } + + return this.container[locale].attributes[key]; + }; + + Dictionary.prototype.hasMessage = function hasMessage (locale, key) { + return !! ( + this.hasLocale(locale) && + this.container[locale].messages && + this.container[locale].messages[key] + ); + }; + + Dictionary.prototype.hasAttribute = function hasAttribute (locale, key) { + return !! ( + this.hasLocale(locale) && + this.container[locale].attributes && + this.container[locale].attributes[key] + ); + }; + + Dictionary.prototype.merge = function merge$1$$1 (dictionary) { + merge$1(this.container, dictionary); + }; + + Dictionary.prototype.setMessage = function setMessage (locale, key, message) { + if (! this.hasLocale(locale)) { + this.container[locale] = { + messages: {}, + attributes: {} + }; + } + + this.container[locale].messages[key] = message; + }; + + Dictionary.prototype.setAttribute = function setAttribute (locale, key, attribute) { + if (! this.hasLocale(locale)) { + this.container[locale] = { + messages: {}, + attributes: {} + }; + } + + this.container[locale].attributes[key] = attribute; + }; + + Object.defineProperties( Dictionary.prototype, prototypeAccessors ); + + // + + var normalizeValue = function (value) { + if (isObject(value)) { + return Object.keys(value).reduce(function (prev, key) { + prev[key] = normalizeValue(value[key]); + + return prev; + }, {}); + } + + if (isCallable(value)) { + return value('{0}', ['{1}', '{2}', '{3}']); + } + + return value; + }; + + var normalizeFormat = function (locale) { + // normalize messages + var dictionary = {}; + if (locale.messages) { + dictionary.messages = normalizeValue(locale.messages); + } + + if (locale.custom) { + dictionary.custom = normalizeValue(locale.custom); + } + + if (locale.attributes) { + dictionary.attributes = locale.attributes; + } + + if (!isNullOrUndefined(locale.dateFormat)) { + dictionary.dateFormat = locale.dateFormat; + } + + return dictionary; + }; + + var I18nDictionary = function I18nDictionary (i18n, rootKey) { + this.i18n = i18n; + this.rootKey = rootKey; + }; + + var prototypeAccessors$1 = { locale: { configurable: true } }; + + prototypeAccessors$1.locale.get = function () { + return this.i18n.locale; + }; + + prototypeAccessors$1.locale.set = function (value) { + warn('Cannot set locale from the validator when using vue-i18n, use i18n.locale setter instead'); + }; + + I18nDictionary.prototype.getDateFormat = function getDateFormat (locale) { + return this.i18n.getDateTimeFormat(locale || this.locale); + }; + + I18nDictionary.prototype.setDateFormat = function setDateFormat (locale, value) { + this.i18n.setDateTimeFormat(locale || this.locale, value); + }; + + I18nDictionary.prototype.getMessage = function getMessage (locale, key, data) { + var path = (this.rootKey) + ".messages." + key; + if (!this.i18n.te(path)) { + return this.i18n.t(((this.rootKey) + ".messages._default"), locale, data); + } + + return this.i18n.t(path, locale, data); + }; + + I18nDictionary.prototype.getAttribute = function getAttribute (locale, key, fallback) { + if ( fallback === void 0 ) fallback = ''; + + var path = (this.rootKey) + ".attributes." + key; + if (!this.i18n.te(path)) { + return fallback; + } + + return this.i18n.t(path, locale); + }; + + I18nDictionary.prototype.getFieldMessage = function getFieldMessage (locale, field, key, data) { + var path = (this.rootKey) + ".custom." + field + "." + key; + if (this.i18n.te(path)) { + return this.i18n.t(path, locale, data); + } + + return this.getMessage(locale, key, data); + }; + + I18nDictionary.prototype.merge = function merge$1$$1 (dictionary) { + var this$1 = this; + + Object.keys(dictionary).forEach(function (localeKey) { + var obj; + + // i18n doesn't deep merge + // first clone the existing locale (avoid mutations to locale) + var clone = merge$1({}, getPath((localeKey + "." + (this$1.rootKey)), this$1.i18n.messages, {})); + // Merge cloned locale with new one + var locale = merge$1(clone, normalizeFormat(dictionary[localeKey])); + this$1.i18n.mergeLocaleMessage(localeKey, ( obj = {}, obj[this$1.rootKey] = locale, obj )); + if (locale.dateFormat) { + this$1.i18n.setDateTimeFormat(localeKey, locale.dateFormat); + } + }); + }; + + I18nDictionary.prototype.setMessage = function setMessage (locale, key, value) { + var obj, obj$1; + + this.merge(( obj$1 = {}, obj$1[locale] = { + messages: ( obj = {}, obj[key] = value, obj ) + }, obj$1 )); + }; + + I18nDictionary.prototype.setAttribute = function setAttribute (locale, key, value) { + var obj, obj$1; + + this.merge(( obj$1 = {}, obj$1[locale] = { + attributes: ( obj = {}, obj[key] = value, obj ) + }, obj$1 )); + }; + + Object.defineProperties( I18nDictionary.prototype, prototypeAccessors$1 ); + + // + + var defaultConfig = { + locale: 'en', + delay: 0, + errorBagName: 'errors', + dictionary: null, + strict: true, + fieldsBagName: 'fields', + classes: false, + classNames: null, + events: 'input', + inject: true, + fastExit: true, + aria: true, + validity: false, + i18n: null, + i18nRootKey: 'validation' + }; + + var currentConfig = assign({}, defaultConfig); + var dependencies = { + dictionary: new Dictionary({ + en: { + messages: {}, + attributes: {}, + custom: {} + } + }) + }; + + var Config = function Config () {}; + + var staticAccessors = { default: { configurable: true },current: { configurable: true } }; + + staticAccessors.default.get = function () { + return defaultConfig; + }; + + staticAccessors.current.get = function () { + return currentConfig; + }; + + Config.dependency = function dependency (key) { + return dependencies[key]; + }; + + /** + * Merges the config with a new one. + */ + Config.merge = function merge (config) { + currentConfig = assign({}, currentConfig, config); + if (currentConfig.i18n) { + Config.register('dictionary', new I18nDictionary(currentConfig.i18n, currentConfig.i18nRootKey)); + } + }; + + /** + * Registers a dependency. + */ + Config.register = function register (key, value) { + dependencies[key] = value; + }; + + /** + * Resolves the working config from a Vue instance. + */ + Config.resolve = function resolve (context) { + var selfConfig = getPath('$options.$_veeValidate', context, {}); + + return assign({}, Config.current, selfConfig); + }; + + Object.defineProperties( Config, staticAccessors ); + + // + + var ErrorBag = function ErrorBag (errorBag, id) { + if ( errorBag === void 0 ) errorBag = null; + if ( id === void 0 ) id = null; + + this.vmId = id || null; + // make this bag a mirror of the provided one, sharing the same items reference. + if (errorBag && errorBag instanceof ErrorBag) { + this.items = errorBag.items; + } else { + this.items = []; + } + }; + + ErrorBag.prototype[typeof Symbol === 'function' ? Symbol.iterator : '@@iterator'] = function () { + var this$1 = this; + + var index = 0; + return { + next: function () { + return { value: this$1.items[index++], done: index > this$1.items.length }; + } + }; + }; + + /** + * Adds an error to the internal array. + */ + ErrorBag.prototype.add = function add (error) { + var ref; + + (ref = this.items).push.apply( + ref, this._normalizeError(error) + ); + }; + + /** + * Normalizes passed errors to an error array. + */ + ErrorBag.prototype._normalizeError = function _normalizeError (error) { + var this$1 = this; + + if (Array.isArray(error)) { + return error.map(function (e) { + e.scope = !isNullOrUndefined(e.scope) ? e.scope : null; + e.vmId = !isNullOrUndefined(e.vmId) ? e.vmId : (this$1.vmId || null); + + return e; + }); + } + + error.scope = !isNullOrUndefined(error.scope) ? error.scope : null; + error.vmId = !isNullOrUndefined(error.vmId) ? error.vmId : (this.vmId || null); + + return [error]; + }; + + /** + * Regenrates error messages if they have a generator function. + */ + ErrorBag.prototype.regenerate = function regenerate () { + this.items.forEach(function (i) { + i.msg = isCallable(i.regenerate) ? i.regenerate() : i.msg; + }); + }; + + /** + * Updates a field error with the new field scope. + */ + ErrorBag.prototype.update = function update (id, error) { + var item = find(this.items, function (i) { return i.id === id; }); + if (!item) { + return; + } + + var idx = this.items.indexOf(item); + this.items.splice(idx, 1); + item.scope = error.scope; + this.items.push(item); + }; + + /** + * Gets all error messages from the internal array. + */ + ErrorBag.prototype.all = function all (scope) { + var this$1 = this; + + var filterFn = function (item) { + var matchesScope = true; + var matchesVM = true; + if (!isNullOrUndefined(scope)) { + matchesScope = item.scope === scope; + } + + if (!isNullOrUndefined(this$1.vmId)) { + matchesVM = item.vmId === this$1.vmId; + } + + return matchesVM && matchesScope; + }; + + return this.items.filter(filterFn).map(function (e) { return e.msg; }); + }; + + /** + * Checks if there are any errors in the internal array. + */ + ErrorBag.prototype.any = function any (scope) { + var this$1 = this; + + var filterFn = function (item) { + var matchesScope = true; + if (!isNullOrUndefined(scope)) { + matchesScope = item.scope === scope; + } + + if (!isNullOrUndefined(this$1.vmId)) { + matchesScope = item.vmId === this$1.vmId; + } + + return matchesScope; + }; + + return !!this.items.filter(filterFn).length; + }; + + /** + * Removes all items from the internal array. + */ + ErrorBag.prototype.clear = function clear (scope) { + var this$1 = this; + + var matchesVM = isNullOrUndefined(this.vmId) ? function () { return true; } : function (i) { return i.vmId === this$1.vmId; }; + if (isNullOrUndefined(scope)) { + scope = null; + } + + for (var i = 0; i < this.items.length; ++i) { + if (matchesVM(this$1.items[i]) && this$1.items[i].scope === scope) { + this$1.items.splice(i, 1); + --i; + } + } + }; + + /** + * Collects errors into groups or for a specific field. + */ + ErrorBag.prototype.collect = function collect (field, scope, map) { + var this$1 = this; + if ( map === void 0 ) map = true; + + var isSingleField = !isNullOrUndefined(field) && !field.includes('*'); + var groupErrors = function (items) { + var errors = items.reduce(function (collection, error) { + if (!isNullOrUndefined(this$1.vmId) && error.vmId !== this$1.vmId) { + return collection; + } + + if (!collection[error.field]) { + collection[error.field] = []; + } + + collection[error.field].push(map ? error.msg : error); + + return collection; + }, {}); + + // reduce the collection to be a single array. + if (isSingleField) { + return values(errors)[0] || []; + } + + return errors; + }; + + if (isNullOrUndefined(field)) { + return groupErrors(this.items); + } + + var selector = isNullOrUndefined(scope) ? String(field) : (scope + "." + field); + var ref = this._makeCandidateFilters(selector); + var isPrimary = ref.isPrimary; + var isAlt = ref.isAlt; + + var collected = this.items.reduce(function (prev, curr) { + if (isPrimary(curr)) { + prev.primary.push(curr); + } + + if (isAlt(curr)) { + prev.alt.push(curr); + } + + return prev; + }, { primary: [], alt: [] }); + + collected = collected.primary.length ? collected.primary : collected.alt; + + return groupErrors(collected); + }; + + /** + * Gets the internal array length. + */ + ErrorBag.prototype.count = function count () { + var this$1 = this; + + if (this.vmId) { + return this.items.filter(function (e) { return e.vmId === this$1.vmId; }).length; + } + + return this.items.length; + }; + + /** + * Finds and fetches the first error message for the specified field id. + */ + ErrorBag.prototype.firstById = function firstById (id) { + var error = find(this.items, function (i) { return i.id === id; }); + + return error ? error.msg : undefined; + }; + + /** + * Gets the first error message for a specific field. + */ + ErrorBag.prototype.first = function first (field, scope) { + if ( scope === void 0 ) scope = null; + + var selector = isNullOrUndefined(scope) ? field : (scope + "." + field); + var match = this._match(selector); + + return match && match.msg; + }; + + /** + * Returns the first error rule for the specified field + */ + ErrorBag.prototype.firstRule = function firstRule (field, scope) { + var errors = this.collect(field, scope, false); + + return (errors.length && errors[0].rule) || undefined; + }; + + /** + * Checks if the internal array has at least one error for the specified field. + */ + ErrorBag.prototype.has = function has (field, scope) { + if ( scope === void 0 ) scope = null; + + return !!this.first(field, scope); + }; + + /** + * Gets the first error message for a specific field and a rule. + */ + ErrorBag.prototype.firstByRule = function firstByRule (name, rule, scope) { + if ( scope === void 0 ) scope = null; + + var error = this.collect(name, scope, false).filter(function (e) { return e.rule === rule; })[0]; + + return (error && error.msg) || undefined; + }; + + /** + * Gets the first error message for a specific field that not match the rule. + */ + ErrorBag.prototype.firstNot = function firstNot (name, rule, scope) { + if ( rule === void 0 ) rule = 'required'; + if ( scope === void 0 ) scope = null; + + var error = this.collect(name, scope, false).filter(function (e) { return e.rule !== rule; })[0]; + + return (error && error.msg) || undefined; + }; + + /** + * Removes errors by matching against the id or ids. + */ + ErrorBag.prototype.removeById = function removeById (id) { + var this$1 = this; + + var condition = function (item) { return item.id === id; }; + if (Array.isArray(id)) { + condition = function (item) { return id.indexOf(item.id) !== -1; }; + } + + for (var i = 0; i < this.items.length; ++i) { + if (condition(this$1.items[i])) { + this$1.items.splice(i, 1); + --i; + } + } + }; + + /** + * Removes all error messages associated with a specific field. + */ + ErrorBag.prototype.remove = function remove (field, scope, vmId) { + var this$1 = this; + + if (isNullOrUndefined(field)) { + return; + } + + var selector = isNullOrUndefined(scope) ? String(field) : (scope + "." + field); + var ref = this._makeCandidateFilters(selector); + var isPrimary = ref.isPrimary; + var shouldRemove = function (item) { + if (isNullOrUndefined(vmId)) { return isPrimary(item); } + + return isPrimary(item) && item.vmId === vmId; + }; + + for (var i = 0; i < this.items.length; ++i) { + if (shouldRemove(this$1.items[i])) { + this$1.items.splice(i, 1); + --i; + } + } + }; + + ErrorBag.prototype._makeCandidateFilters = function _makeCandidateFilters (selector) { + var this$1 = this; + + var matchesRule = function () { return true; }; + var matchesScope = function () { return true; }; + var matchesName = function () { return true; }; + var matchesVM = function () { return true; }; + + var ref = parseSelector(selector); + var id = ref.id; + var rule = ref.rule; + var scope = ref.scope; + var name = ref.name; + + if (rule) { + matchesRule = function (item) { return item.rule === rule; }; + } + + // match by id, can be combined with rule selection. + if (id) { + return { + isPrimary: function (item) { return matchesRule(item) && (function (item) { return id === item.id; }); }, + isAlt: function () { return false; } + }; + } + + if (isNullOrUndefined(scope)) { + // if no scope specified, make sure the found error has no scope. + matchesScope = function (item) { return isNullOrUndefined(item.scope); }; + } else { + matchesScope = function (item) { return item.scope === scope; }; + } + + if (!isNullOrUndefined(name) && name !== '*') { + matchesName = function (item) { return item.field === name; }; + } + + if (!isNullOrUndefined(this.vmId)) { + matchesVM = function (item) { return item.vmId === this$1.vmId; }; + } + + // matches the first candidate. + var isPrimary = function (item) { + return matchesVM(item) && matchesName(item) && matchesRule(item) && matchesScope(item); + }; + + // matches a second candidate, which is a field with a name containing the '.' character. + var isAlt = function (item) { + return matchesVM(item) && matchesRule(item) && item.field === (scope + "." + name); + }; + + return { + isPrimary: isPrimary, + isAlt: isAlt + }; + }; + + ErrorBag.prototype._match = function _match (selector) { + if (isNullOrUndefined(selector)) { + return undefined; + } + + var ref = this._makeCandidateFilters(selector); + var isPrimary = ref.isPrimary; + var isAlt = ref.isAlt; + + return this.items.reduce(function (prev, item, idx, arr) { + var isLast = idx === arr.length - 1; + if (prev.primary) { + return isLast ? prev.primary : prev; + } + + if (isPrimary(item)) { + prev.primary = item; + } + + if (isAlt(item)) { + prev.alt = item; + } + + // keep going. + if (!isLast) { + return prev; + } + + return prev.primary || prev.alt; + }, {}); + }; + + /** + * Generates the options required to construct a field. + */ + var Resolver = function Resolver () {}; + + Resolver.generate = function generate (el, binding, vnode) { + var model = Resolver.resolveModel(binding, vnode); + var options = Config.resolve(vnode.context); + + return { + name: Resolver.resolveName(el, vnode), + el: el, + listen: !binding.modifiers.disable, + bails: binding.modifiers.bails ? true : (binding.modifiers.continues === true ? false : undefined), + scope: Resolver.resolveScope(el, binding, vnode), + vm: Resolver.makeVM(vnode.context), + expression: binding.value, + component: vnode.componentInstance, + classes: options.classes, + classNames: options.classNames, + getter: Resolver.resolveGetter(el, vnode, model), + events: Resolver.resolveEvents(el, vnode) || options.events, + model: model, + delay: Resolver.resolveDelay(el, vnode, options), + rules: Resolver.resolveRules(el, binding, vnode), + immediate: !!binding.modifiers.initial || !!binding.modifiers.immediate, + validity: options.validity, + aria: options.aria, + initialValue: Resolver.resolveInitialValue(vnode) + }; + }; + + Resolver.getCtorConfig = function getCtorConfig (vnode) { + if (!vnode.componentInstance) { return null; } + + var config = getPath('componentInstance.$options.$_veeValidate', vnode); + + return config; + }; + + /** + * Resolves the rules defined on an element. + */ + Resolver.resolveRules = function resolveRules (el, binding, vnode) { + var rules = ''; + if (!binding.value && (!binding || !binding.expression)) { + rules = getDataAttribute(el, 'rules'); + } + + if (binding.value && includes(['string', 'object'], typeof binding.value.rules)) { + rules = binding.value.rules; + } else if (binding.value) { + rules = binding.value; + } + + if (vnode.componentInstance) { + return rules; + } + + return fillRulesFromElement(el, rules); + }; + + /** + * @param {*} vnode + */ + Resolver.resolveInitialValue = function resolveInitialValue (vnode) { + var model = vnode.data.model || find(vnode.data.directives, function (d) { return d.name === 'model'; }); + + return model && model.value; + }; + + /** + * Creates a non-circular partial VM instance from a Vue instance. + * @param {*} vm + */ + Resolver.makeVM = function makeVM (vm) { + return { + get $el () { + return vm.$el; + }, + get $refs () { + return vm.$refs; + }, + $watch: vm.$watch ? vm.$watch.bind(vm) : function () {}, + $validator: vm.$validator ? { + errors: vm.$validator.errors, + validate: vm.$validator.validate.bind(vm.$validator), + update: vm.$validator.update.bind(vm.$validator) + } : null + }; + }; + + /** + * Resolves the delay value. + * @param {*} el + * @param {*} vnode + * @param {Object} options + */ + Resolver.resolveDelay = function resolveDelay (el, vnode, options) { + var delay = getDataAttribute(el, 'delay'); + var globalDelay = (options && 'delay' in options) ? options.delay : 0; + + if (!delay && vnode.componentInstance && vnode.componentInstance.$attrs) { + delay = vnode.componentInstance.$attrs['data-vv-delay']; + } + + if (!isObject(globalDelay)) { + return deepParseInt(delay || globalDelay); + } + + if (!isNullOrUndefined(delay)) { + globalDelay.input = delay; + } + + return deepParseInt(globalDelay); + }; + + /** + * Resolves the events to validate in response to. + * @param {*} el + * @param {*} vnode + */ + Resolver.resolveEvents = function resolveEvents (el, vnode) { + // resolve it from the root element. + var events = getDataAttribute(el, 'validate-on'); + + // resolve from data-vv-validate-on if its a vue component. + if (!events && vnode.componentInstance && vnode.componentInstance.$attrs) { + events = vnode.componentInstance.$attrs['data-vv-validate-on']; + } + + // resolve it from $_veeValidate options. + if (!events && vnode.componentInstance) { + var config = Resolver.getCtorConfig(vnode); + events = config && config.events; + } + + if (!events && Config.current.events) { + events = Config.current.events; + } + + // resolve the model event if its configured for custom components. + if (events && vnode.componentInstance && includes(events, 'input')) { + var ref = vnode.componentInstance.$options.model || { event: 'input' }; + var event = ref.event; + // if the prop was configured but not the model. + if (!event) { + return events; + } + + events = events.replace('input', event); + } + + return events; + }; + + /** + * Resolves the scope for the field. + * @param {*} el + * @param {*} binding + */ + Resolver.resolveScope = function resolveScope (el, binding, vnode) { + if ( vnode === void 0 ) vnode = {}; + + var scope = null; + if (vnode.componentInstance && isNullOrUndefined(scope)) { + scope = vnode.componentInstance.$attrs && vnode.componentInstance.$attrs['data-vv-scope']; + } + + return !isNullOrUndefined(scope) ? scope : getScope(el); + }; + + /** + * Checks if the node directives contains a v-model or a specified arg. + * Args take priority over models. + * + * @return {Object} + */ + Resolver.resolveModel = function resolveModel (binding, vnode) { + if (binding.arg) { + return { expression: binding.arg }; + } + + var model = vnode.data.model || find(vnode.data.directives, function (d) { return d.name === 'model'; }); + if (!model) { + return null; + } + + // https://github.com/vuejs/vue/blob/dev/src/core/util/lang.js#L26 + var watchable = !/[^\w.$]/.test(model.expression) && hasPath(model.expression, vnode.context); + var lazy = !!(model.modifiers && model.modifiers.lazy); + + if (!watchable) { + return { expression: null, lazy: lazy }; + } + + return { expression: model.expression, lazy: lazy }; + }; + + /** + * Resolves the field name to trigger validations. + * @return {String} The field name. + */ + Resolver.resolveName = function resolveName (el, vnode) { + var name = getDataAttribute(el, 'name'); + + if (!name && !vnode.componentInstance) { + return el.name; + } + + if (!name && vnode.componentInstance && vnode.componentInstance.$attrs) { + name = vnode.componentInstance.$attrs['data-vv-name'] || vnode.componentInstance.$attrs['name']; + } + + if (!name && vnode.componentInstance) { + var config = Resolver.getCtorConfig(vnode); + if (config && isCallable(config.name)) { + var boundGetter = config.name.bind(vnode.componentInstance); + + return boundGetter(); + } + + return vnode.componentInstance.name; + } + + return name; + }; + + /** + * Returns a value getter input type. + */ + Resolver.resolveGetter = function resolveGetter (el, vnode, model) { + if (model && model.expression) { + return function () { + return getPath(model.expression, vnode.context); + }; + } + + if (vnode.componentInstance) { + var path = getDataAttribute(el, 'value-path') || (vnode.componentInstance.$attrs && vnode.componentInstance.$attrs['data-vv-value-path']); + if (path) { + return function () { + return getPath(path, vnode.componentInstance); + }; + } + + var config = Resolver.getCtorConfig(vnode); + if (config && isCallable(config.value)) { + var boundGetter = config.value.bind(vnode.componentInstance); + + return function () { + return boundGetter(); + }; + } + + var ref = vnode.componentInstance.$options.model || { prop: 'value' }; + var prop = ref.prop; + + return function () { + return vnode.componentInstance[prop]; + }; + } + + switch (el.type) { + case 'checkbox': return function () { + var els = document.querySelectorAll(("input[name=\"" + (el.name) + "\"]")); + + els = toArray(els).filter(function (el) { return el.checked; }); + if (!els.length) { return undefined; } + + return els.map(function (checkbox) { return checkbox.value; }); + }; + case 'radio': return function () { + var els = document.querySelectorAll(("input[name=\"" + (el.name) + "\"]")); + var elm = find(els, function (el) { return el.checked; }); + + return elm && elm.value; + }; + case 'file': return function (context) { + return toArray(el.files); + }; + case 'select-multiple': return function () { + return toArray(el.options).filter(function (opt) { return opt.selected; }).map(function (opt) { return opt.value; }); + }; + default: return function () { + return el && el.value; + }; + } + }; + + // + + var RULES = {}; + var STRICT_MODE = true; + + var Validator = function Validator (validations, options) { + if ( options === void 0 ) options = { fastExit: true }; + + this.strict = STRICT_MODE; + this.errors = new ErrorBag(); + this.fields = new FieldBag(); + this._createFields(validations); + this.paused = false; + this.fastExit = !isNullOrUndefined(options && options.fastExit) ? options.fastExit : true; + }; + + var prototypeAccessors$2 = { rules: { configurable: true },flags: { configurable: true },dictionary: { configurable: true },_vm: { configurable: true },locale: { configurable: true } }; + var staticAccessors$1 = { rules: { configurable: true },dictionary: { configurable: true },locale: { configurable: true } }; + + staticAccessors$1.rules.get = function () { + return RULES; + }; + + prototypeAccessors$2.rules.get = function () { + return RULES; + }; + + prototypeAccessors$2.flags.get = function () { + return this.fields.items.reduce(function (acc, field) { + var obj; + + if (field.scope) { + acc[("$" + (field.scope))] = ( obj = {}, obj[field.name] = field.flags, obj ); + + return acc; + } + + acc[field.name] = field.flags; + + return acc; + }, {}); + }; + + /** + * Getter for the dictionary. + */ + prototypeAccessors$2.dictionary.get = function () { + return Config.dependency('dictionary'); + }; + + staticAccessors$1.dictionary.get = function () { + return Config.dependency('dictionary'); + }; + + prototypeAccessors$2._vm.get = function () { + return Config.dependency('vm'); + }; + + /** + * Getter for the current locale. + */ + prototypeAccessors$2.locale.get = function () { + return Validator.locale; + }; + + /** + * Setter for the validator locale. + */ + prototypeAccessors$2.locale.set = function (value) { + Validator.locale = value; + }; + + staticAccessors$1.locale.get = function () { + return this.dictionary.locale; + }; + + /** + * Setter for the validator locale. + */ + staticAccessors$1.locale.set = function (value) { + var hasChanged = value !== Validator.dictionary.locale; + Validator.dictionary.locale = value; + if (hasChanged && Config.dependency('vm')) { + Config.dependency('vm').$emit('localeChanged'); + } + }; + + /** + * Static constructor. + */ + Validator.create = function create (validations, options) { + return new Validator(validations, options); + }; + + /** + * Adds a custom validator to the list of validation rules. + */ + Validator.extend = function extend (name, validator, options) { + if ( options === void 0 ) options = {}; + + Validator._guardExtend(name, validator); + Validator._merge(name, { + validator: validator, + paramNames: options && options.paramNames, + options: assign({}, { hasTarget: false, immediate: true }, options || {}) + }); + }; + + /** + * Removes a rule from the list of validators. + */ + Validator.remove = function remove (name) { + delete RULES[name]; + }; + + /** + * Checks if the given rule name is a rule that targets other fields. + */ + Validator.isTargetRule = function isTargetRule (name) { + return !!RULES[name] && RULES[name].options.hasTarget; + }; + + /** + * Sets the operating mode for all newly created validators. + * strictMode = true: Values without a rule are invalid and cause failure. + * strictMode = false: Values without a rule are valid and are skipped. + */ + Validator.setStrictMode = function setStrictMode (strictMode) { + if ( strictMode === void 0 ) strictMode = true; + + STRICT_MODE = strictMode; + }; + + /** + * Adds and sets the current locale for the validator. + */ + Validator.prototype.localize = function localize (lang, dictionary) { + Validator.localize(lang, dictionary); + }; + + /** + * Adds and sets the current locale for the validator. + */ + Validator.localize = function localize (lang, dictionary) { + var obj; + + if (isObject(lang)) { + Validator.dictionary.merge(lang); + return; + } + + // merge the dictionary. + if (dictionary) { + var locale = lang || dictionary.name; + dictionary = assign({}, dictionary); + Validator.dictionary.merge(( obj = {}, obj[locale] = dictionary, obj )); + } + + if (lang) { + // set the locale. + Validator.locale = lang; + } + }; + + /** + * Registers a field to be validated. + */ + Validator.prototype.attach = function attach (fieldOpts) { + // fixes initial value detection with v-model and select elements. + var value = fieldOpts.initialValue; + var field = new Field(fieldOpts); + this.fields.push(field); + + // validate the field initially + if (field.immediate) { + this.validate(("#" + (field.id)), value || field.value, { vmId: fieldOpts.vmId }); + } else { + this._validate(field, value || field.value, { initial: true }).then(function (result) { + field.flags.valid = result.valid; + field.flags.invalid = !result.valid; + }); + } + + return field; + }; + + /** + * Sets the flags on a field. + */ + Validator.prototype.flag = function flag (name, flags, uid) { + if ( uid === void 0 ) uid = null; + + var field = this._resolveField(name, undefined, uid); + if (!field || !flags) { + return; + } + + field.setFlags(flags); + }; + + /** + * Removes a field from the validator. + */ + Validator.prototype.detach = function detach (name, scope, uid) { + var field = isCallable(name.destroy) ? name : this._resolveField(name, scope, uid); + if (!field) { return; } + + field.destroy(); + this.errors.remove(field.name, field.scope, field.vmId); + this.fields.remove(field); + }; + + /** + * Adds a custom validator to the list of validation rules. + */ + Validator.prototype.extend = function extend (name, validator, options) { + if ( options === void 0 ) options = {}; + + Validator.extend(name, validator, options); + }; + + Validator.prototype.reset = function reset (matcher) { + var this$1 = this; + + // two ticks + return this._vm.$nextTick().then(function () { + return this$1._vm.$nextTick(); + }).then(function () { + this$1.fields.filter(matcher).forEach(function (field) { + field.reset(); // reset field flags. + this$1.errors.remove(field.name, field.scope); + }); + }); + }; + + /** + * Updates a field, updating both errors and flags. + */ + Validator.prototype.update = function update (id, ref) { + var scope = ref.scope; + + var field = this._resolveField(("#" + id)); + if (!field) { return; } + + // remove old scope. + this.errors.update(id, { scope: scope }); + }; + + /** + * Removes a rule from the list of validators. + */ + Validator.prototype.remove = function remove (name) { + Validator.remove(name); + }; + + /** + * Validates a value against a registered field validations. + */ + Validator.prototype.validate = function validate (fieldDescriptor, value, ref) { + var this$1 = this; + if ( ref === void 0 ) ref = {}; + var silent = ref.silent; + var vmId = ref.vmId; + + if (this.paused) { return Promise.resolve(true); } + + // overload to validate all. + if (isNullOrUndefined(fieldDescriptor)) { + return this.validateScopes({ silent: silent, vmId: vmId }); + } + + // overload to validate scope-less fields. + if (fieldDescriptor === '*') { + return this.validateAll(undefined, { silent: silent, vmId: vmId }); + } + + // if scope validation was requested. + if (/^(.+)\.\*$/.test(fieldDescriptor)) { + var matched = fieldDescriptor.match(/^(.+)\.\*$/)[1]; + return this.validateAll(matched); + } + + var field = this._resolveField(fieldDescriptor); + if (!field) { + return this._handleFieldNotFound(name); + } + + if (!silent) { field.flags.pending = true; } + if (value === undefined) { + value = field.value; + } + + return this._validate(field, value).then(function (result) { + if (!silent) { + this$1._handleValidationResults([result], vmId); + } + + return result.valid; + }); + }; + + /** + * Pauses the validator. + */ + Validator.prototype.pause = function pause () { + this.paused = true; + + return this; + }; + + /** + * Resumes the validator. + */ + Validator.prototype.resume = function resume () { + this.paused = false; + + return this; + }; + + /** + * Validates each value against the corresponding field validations. + */ + Validator.prototype.validateAll = function validateAll (values$$1, ref) { + var this$1 = this; + if ( ref === void 0 ) ref = {}; + var silent = ref.silent; + var vmId = ref.vmId; + + if (this.paused) { return Promise.resolve(true); } + + var matcher = null; + var providedValues = false; + + if (typeof values$$1 === 'string') { + matcher = { scope: values$$1, vmId: vmId }; + } else if (isObject(values$$1)) { + matcher = Object.keys(values$$1).map(function (key) { + return { name: key, vmId: vmId, scope: null }; + }); + providedValues = true; + } else if (Array.isArray(values$$1)) { + matcher = values$$1.map(function (key) { + return { name: key, vmId: vmId }; + }); + } else { + matcher = { scope: null, vmId: vmId }; + } + + return Promise.all( + this.fields.filter(matcher).map(function (field) { return this$1._validate(field, providedValues ? values$$1[field.name] : field.value); }) + ).then(function (results) { + if (!silent) { + this$1._handleValidationResults(results, vmId); + } + + return results.every(function (t) { return t.valid; }); + }); + }; + + /** + * Validates all scopes. + */ + Validator.prototype.validateScopes = function validateScopes (ref) { + var this$1 = this; + if ( ref === void 0 ) ref = {}; + var silent = ref.silent; + var vmId = ref.vmId; + + if (this.paused) { return Promise.resolve(true); } + + return Promise.all( + this.fields.filter({ vmId: vmId }).map(function (field) { return this$1._validate(field, field.value); }) + ).then(function (results) { + if (!silent) { + this$1._handleValidationResults(results, vmId); + } + + return results.every(function (t) { return t.valid; }); + }); + }; + + /** + * Validates a value against the rules. + */ + Validator.prototype.verify = function verify (value, rules) { + var field = { name: '{field}', rules: normalizeRules(rules) }; + field.isRequired = field.rules.required; + + return this._validate(field, value).then(function (result) { + return { valid: result.valid, errors: result.errors.map(function (e) { return e.msg; }) }; + }); + }; + + /** + * Perform cleanup. + */ + Validator.prototype.destroy = function destroy () { + this._vm.$off('localeChanged'); + }; + + /** + * Creates the fields to be validated. + */ + Validator.prototype._createFields = function _createFields (validations) { + var this$1 = this; + + if (!validations) { return; } + + Object.keys(validations).forEach(function (field) { + var options = assign({}, { name: field, rules: validations[field] }); + this$1.attach(options); + }); + }; + + /** + * Date rules need the existence of a format, so date_format must be supplied. + */ + Validator.prototype._getDateFormat = function _getDateFormat (validations) { + var format = null; + if (validations.date_format && Array.isArray(validations.date_format)) { + format = validations.date_format[0]; + } + + return format || this.dictionary.getDateFormat(this.locale); + }; + + /** + * Formats an error message for field and a rule. + */ + Validator.prototype._formatErrorMessage = function _formatErrorMessage (field, rule, data, targetName) { + if ( data === void 0 ) data = {}; + if ( targetName === void 0 ) targetName = null; + + var name = this._getFieldDisplayName(field); + var params = this._getLocalizedParams(rule, targetName); + + return this.dictionary.getFieldMessage(this.locale, field.name, rule.name, [name, params, data]); + }; + + /** + * We need to convert any object param to an array format since the locales do not handle params as objects yet. + */ + Validator.prototype._convertParamObjectToArray = function _convertParamObjectToArray (obj, ruleName) { + if (Array.isArray(obj)) { + return obj; + } + + var paramNames = RULES[ruleName] && RULES[ruleName].paramNames; + if (!paramNames || !isObject(obj)) { + return obj; + } + + return paramNames.reduce(function (prev, paramName) { + if (paramName in obj) { + prev.push(obj[paramName]); + } + + return prev; + }, []); + }; + + /** + * Translates the parameters passed to the rule (mainly for target fields). + */ + Validator.prototype._getLocalizedParams = function _getLocalizedParams (rule, targetName) { + if ( targetName === void 0 ) targetName = null; + + var params = this._convertParamObjectToArray(rule.params, rule.name); + if (rule.options.hasTarget && params && params[0]) { + var localizedName = targetName || this.dictionary.getAttribute(this.locale, params[0], params[0]); + return [localizedName].concat(params.slice(1)); + } + + return params; + }; + + /** + * Resolves an appropriate display name, first checking 'data-as' or the registered 'prettyName' + */ + Validator.prototype._getFieldDisplayName = function _getFieldDisplayName (field) { + return field.alias || this.dictionary.getAttribute(this.locale, field.name, field.name); + }; + + /** + * Converts an array of params to an object with named properties. + * Only works if the rule is configured with a paramNames array. + * Returns the same params if it cannot convert it. + */ + Validator.prototype._convertParamArrayToObj = function _convertParamArrayToObj (params, ruleName) { + var paramNames = RULES[ruleName] && RULES[ruleName].paramNames; + if (!paramNames) { + return params; + } + + if (isObject(params)) { + // check if the object is either a config object or a single parameter that is an object. + var hasKeys = paramNames.some(function (name) { return Object.keys(params).indexOf(name) !== -1; }); + // if it has some of the keys, return it as is. + if (hasKeys) { + return params; + } + // otherwise wrap the object in an array. + params = [params]; + } + + // Reduce the paramsNames to a param object. + return params.reduce(function (prev, value, idx) { + prev[paramNames[idx]] = value; + + return prev; + }, {}); + }; + + /** + * Tests a single input value against a rule. + */ + Validator.prototype._test = function _test (field, value, rule) { + var this$1 = this; + + var validator = RULES[rule.name] ? RULES[rule.name].validate : null; + var params = Array.isArray(rule.params) ? toArray(rule.params) : rule.params; + if (!params) { + params = []; + } + + var targetName = null; + if (!validator || typeof validator !== 'function') { + return Promise.reject(createError(("No such validator '" + (rule.name) + "' exists."))); + } + + // has field dependencies. + if (rule.options.hasTarget) { + var target = find(field.dependencies, function (d) { return d.name === rule.name; }); + if (target) { + targetName = target.field.alias; + params = [target.field.value].concat(params.slice(1)); + } + } else if (rule.name === 'required' && field.rejectsFalse) { + // invalidate false if no args were specified and the field rejects false by default. + params = params.length ? params : [true]; + } + + if (rule.options.isDate) { + var dateFormat = this._getDateFormat(field.rules); + if (rule.name !== 'date_format') { + params.push(dateFormat); + } + } + + var result = validator(value, this._convertParamArrayToObj(params, rule.name)); + + // If it is a promise. + if (isCallable(result.then)) { + return result.then(function (values$$1) { + var allValid = true; + var data = {}; + if (Array.isArray(values$$1)) { + allValid = values$$1.every(function (t) { return (isObject(t) ? t.valid : t); }); + } else { // Is a single object/boolean. + allValid = isObject(values$$1) ? values$$1.valid : values$$1; + data = values$$1.data; + } + + return { + valid: allValid, + errors: allValid ? [] : [this$1._createFieldError(field, rule, data, targetName)] + }; + }); + } + + if (!isObject(result)) { + result = { valid: result, data: {} }; + } + + return { + valid: result.valid, + errors: result.valid ? [] : [this._createFieldError(field, rule, result.data, targetName)] + }; + }; + + /** + * Merges a validator object into the RULES and Messages. + */ + Validator._merge = function _merge (name, ref) { + var validator = ref.validator; + var options = ref.options; + var paramNames = ref.paramNames; + + var validate = isCallable(validator) ? validator : validator.validate; + if (validator.getMessage) { + Validator.dictionary.setMessage(Validator.locale, name, validator.getMessage); + } + + RULES[name] = { + validate: validate, + options: options, + paramNames: paramNames + }; + }; + + /** + * Guards from extension violations. + */ + Validator._guardExtend = function _guardExtend (name, validator) { + if (isCallable(validator)) { + return; + } + + if (!isCallable(validator.validate)) { + throw createError( + ("Extension Error: The validator '" + name + "' must be a function or have a 'validate' method.") + ); + } + }; + + /** + * Creates a Field Error Object. + */ + Validator.prototype._createFieldError = function _createFieldError (field, rule, data, targetName) { + var this$1 = this; + + return { + id: field.id, + vmId: field.vmId, + field: field.name, + msg: this._formatErrorMessage(field, rule, data, targetName), + rule: rule.name, + scope: field.scope, + regenerate: function () { + return this$1._formatErrorMessage(field, rule, data, targetName); + } + }; + }; + + /** + * Tries different strategies to find a field. + */ + Validator.prototype._resolveField = function _resolveField (name, scope, uid) { + if (name[0] === '#') { + return this.fields.find({ id: name.slice(1) }); + } + + if (!isNullOrUndefined(scope)) { + return this.fields.find({ name: name, scope: scope, vmId: uid }); + } + + if (includes(name, '.')) { + var ref = name.split('.'); + var fieldScope = ref[0]; + var fieldName = ref.slice(1); + var field = this.fields.find({ name: fieldName.join('.'), scope: fieldScope, vmId: uid }); + if (field) { + return field; + } + } + + return this.fields.find({ name: name, scope: null, vmId: uid }); + }; + + /** + * Handles when a field is not found depending on the strict flag. + */ + Validator.prototype._handleFieldNotFound = function _handleFieldNotFound (name, scope) { + if (!this.strict) { return Promise.resolve(true); } + + var fullName = isNullOrUndefined(scope) ? name : ("" + (!isNullOrUndefined(scope) ? scope + '.' : '') + name); + + return Promise.reject(createError( + ("Validating a non-existent field: \"" + fullName + "\". Use \"attach()\" first.") + )); + }; + + /** + * Handles validation results. + */ + Validator.prototype._handleValidationResults = function _handleValidationResults (results, vmId) { + var this$1 = this; + + var matchers = results.map(function (result) { return ({ id: result.id }); }); + this.errors.removeById(matchers.map(function (m) { return m.id; })); + // remove by name and scope to remove any custom errors added. + results.forEach(function (result) { + this$1.errors.remove(result.field, result.scope, vmId); + }); + var allErrors = results.reduce(function (prev, curr) { + prev.push.apply(prev, curr.errors); + + return prev; + }, []); + + this.errors.add(allErrors); + + // handle flags. + this.fields.filter(matchers).forEach(function (field) { + var result = find(results, function (r) { return r.id === field.id; }); + field.setFlags({ + pending: false, + valid: result.valid, + validated: true + }); + }); + }; + + Validator.prototype._shouldSkip = function _shouldSkip (field, value) { + // field is configured to run through the pipeline regardless + if (field.bails === false) { + return false; + } + + // disabled fields are skipped + if (field.isDisabled) { + return true; + } + + // skip if the field is not required and has an empty value. + return !field.isRequired && (isNullOrUndefined(value) || value === ''); + }; + + Validator.prototype._shouldBail = function _shouldBail (field, value) { + // if the field was configured explicitly. + if (field.bails !== undefined) { + return field.bails; + } + + return this.fastExit; + }; + + /** + * Starts the validation process. + */ + Validator.prototype._validate = function _validate (field, value, ref) { + var this$1 = this; + if ( ref === void 0 ) ref = {}; + var initial = ref.initial; + + if (this._shouldSkip(field, value)) { + return Promise.resolve({ valid: true, id: field.id, field: field.name, scope: field.scope, errors: [] }); + } + + var promises = []; + var errors = []; + var isExitEarly = false; + // use of '.some()' is to break iteration in middle by returning true + Object.keys(field.rules).filter(function (rule) { + if (!initial || !RULES[rule]) { return true; } + + return RULES[rule].options.immediate; + }).some(function (rule) { + var ruleOptions = RULES[rule] ? RULES[rule].options : {}; + var result = this$1._test(field, value, { name: rule, params: field.rules[rule], options: ruleOptions }); + if (isCallable(result.then)) { + promises.push(result); + } else if (!result.valid && this$1._shouldBail(field, value)) { + errors.push.apply(errors, result.errors); + isExitEarly = true; + } else { + // promisify the result. + promises.push(new Promise(function (resolve) { return resolve(result); })); + } + + return isExitEarly; + }); + + if (isExitEarly) { + return Promise.resolve({ valid: false, errors: errors, id: field.id, field: field.name, scope: field.scope }); + } + + return Promise.all(promises).then(function (results) { + return results.reduce(function (prev, v) { + var ref; + + if (!v.valid) { + (ref = prev.errors).push.apply(ref, v.errors); + } + + prev.valid = prev.valid && v.valid; + + return prev; + }, { valid: true, errors: errors, id: field.id, field: field.name, scope: field.scope }); + }); + }; + + Object.defineProperties( Validator.prototype, prototypeAccessors$2 ); + Object.defineProperties( Validator, staticAccessors$1 ); + + // + + var DEFAULT_OPTIONS = { + targetOf: null, + immediate: false, + scope: null, + listen: true, + name: null, + rules: {}, + vm: null, + classes: false, + validity: true, + aria: true, + events: 'input|blur', + delay: 0, + classNames: { + touched: 'touched', // the control has been blurred + untouched: 'untouched', // the control hasn't been blurred + valid: 'valid', // model is valid + invalid: 'invalid', // model is invalid + pristine: 'pristine', // control has not been interacted with + dirty: 'dirty' // control has been interacted with + } + }; + + var Field = function Field (options) { + if ( options === void 0 ) options = {}; + + this.id = uniqId(); + this.el = options.el; + this.updated = false; + this.dependencies = []; + this.vmId = options.vmId; + this.watchers = []; + this.events = []; + this.delay = 0; + this.rules = {}; + this._cacheId(options); + this.classNames = assign({}, DEFAULT_OPTIONS.classNames); + options = assign({}, DEFAULT_OPTIONS, options); + this._delay = !isNullOrUndefined(options.delay) ? options.delay : 0; // cache initial delay + this.validity = options.validity; + this.aria = options.aria; + this.flags = createFlags(); + this.vm = options.vm; + this.componentInstance = options.component; + this.ctorConfig = this.componentInstance ? getPath('$options.$_veeValidate', this.componentInstance) : undefined; + this.update(options); + // set initial value. + this.initialValue = this.value; + this.updated = false; + }; + + var prototypeAccessors$3 = { validator: { configurable: true },isRequired: { configurable: true },isDisabled: { configurable: true },alias: { configurable: true },value: { configurable: true },bails: { configurable: true },rejectsFalse: { configurable: true } }; + + prototypeAccessors$3.validator.get = function () { + if (!this.vm || !this.vm.$validator) { + return { validate: function () {} }; + } + + return this.vm.$validator; + }; + + prototypeAccessors$3.isRequired.get = function () { + return !!this.rules.required; + }; + + prototypeAccessors$3.isDisabled.get = function () { + return !!(this.componentInstance && this.componentInstance.disabled) || !!(this.el && this.el.disabled); + }; + + /** + * Gets the display name (user-friendly name). + */ + prototypeAccessors$3.alias.get = function () { + if (this._alias) { + return this._alias; + } + + var alias = null; + if (this.el) { + alias = getDataAttribute(this.el, 'as'); + } + + if (!alias && this.componentInstance) { + return this.componentInstance.$attrs && this.componentInstance.$attrs['data-vv-as']; + } + + return alias; + }; + + /** + * Gets the input value. + */ + + prototypeAccessors$3.value.get = function () { + if (!isCallable(this.getter)) { + return undefined; + } + + return this.getter(); + }; + + prototypeAccessors$3.bails.get = function () { + return this._bails; + }; + + /** + * If the field rejects false as a valid value for the required rule. + */ + + prototypeAccessors$3.rejectsFalse.get = function () { + if (this.componentInstance && this.ctorConfig) { + return !!this.ctorConfig.rejectsFalse; + } + + if (!this.el) { + return false; + } + + return this.el.type === 'checkbox'; + }; + + /** + * Determines if the instance matches the options provided. + */ + Field.prototype.matches = function matches (options) { + var this$1 = this; + + if (!options) { + return true; + } + + if (options.id) { + return this.id === options.id; + } + + var matchesComponentId = isNullOrUndefined(options.vmId) ? function () { return true; } : function (id) { return id === this$1.vmId; }; + if (!matchesComponentId(options.vmId)) { + return false; + } + + if (options.name === undefined && options.scope === undefined) { + return true; + } + + if (options.scope === undefined) { + return this.name === options.name; + } + + if (options.name === undefined) { + return this.scope === options.scope; + } + + return options.name === this.name && options.scope === this.scope; + }; + + /** + * Caches the field id. + */ + Field.prototype._cacheId = function _cacheId (options) { + if (this.el && !options.targetOf) { + this.el._veeValidateId = this.id; + } + }; + + /** + * Updates the field with changed data. + */ + Field.prototype.update = function update (options) { + this.targetOf = options.targetOf || null; + this.immediate = options.immediate || this.immediate || false; + + // update errors scope if the field scope was changed. + if (!isNullOrUndefined(options.scope) && options.scope !== this.scope && isCallable(this.validator.update)) { + this.validator.update(this.id, { scope: options.scope }); + } + this.scope = !isNullOrUndefined(options.scope) ? options.scope + : !isNullOrUndefined(this.scope) ? this.scope : null; + this.name = (!isNullOrUndefined(options.name) ? String(options.name) : options.name) || this.name || null; + this.rules = options.rules !== undefined ? normalizeRules(options.rules) : this.rules; + this._bails = options.bails !== undefined ? options.bails : this._bails; + this.model = options.model || this.model; + this.listen = options.listen !== undefined ? options.listen : this.listen; + this.classes = (options.classes || this.classes || false) && !this.componentInstance; + this.classNames = isObject(options.classNames) ? merge$1(this.classNames, options.classNames) : this.classNames; + this.getter = isCallable(options.getter) ? options.getter : this.getter; + this._alias = options.alias || this._alias; + this.events = (options.events) ? makeEventsArray(options.events) : this.events; + this.delay = makeDelayObject(this.events, options.delay || this.delay, this._delay); + this.updateDependencies(); + this.addActionListeners(); + + if (!this.name && !this.targetOf) { + warn('A field is missing a "name" or "data-vv-name" attribute'); + } + + // update required flag flags + if (options.rules !== undefined) { + this.flags.required = this.isRequired; + } + + // validate if it was validated before and field was updated and there was a rules mutation. + if (this.flags.validated && options.rules !== undefined && this.updated) { + this.validator.validate(("#" + (this.id))); + } + + this.updated = true; + this.addValueListeners(); + + // no need to continue. + if (!this.el) { + return; + } + this.updateClasses(); + this.updateAriaAttrs(); + }; + + /** + * Resets field flags and errors. + */ + Field.prototype.reset = function reset () { + var this$1 = this; + + if (this._cancellationToken) { + this._cancellationToken.cancelled = true; + delete this._cancellationToken; + } + + var defaults = createFlags(); + Object.keys(this.flags).filter(function (flag) { return flag !== 'required'; }).forEach(function (flag) { + this$1.flags[flag] = defaults[flag]; + }); + + this.addActionListeners(); + this.updateClasses(); + this.updateAriaAttrs(); + this.updateCustomValidity(); + }; + + /** + * Sets the flags and their negated counterparts, and updates the classes and re-adds action listeners. + */ + Field.prototype.setFlags = function setFlags (flags) { + var this$1 = this; + + var negated = { + pristine: 'dirty', + dirty: 'pristine', + valid: 'invalid', + invalid: 'valid', + touched: 'untouched', + untouched: 'touched' + }; + + Object.keys(flags).forEach(function (flag) { + this$1.flags[flag] = flags[flag]; + // if it has a negation and was not specified, set it as well. + if (negated[flag] && flags[negated[flag]] === undefined) { + this$1.flags[negated[flag]] = !flags[flag]; + } + }); + + if ( + flags.untouched !== undefined || + flags.touched !== undefined || + flags.dirty !== undefined || + flags.pristine !== undefined + ) { + this.addActionListeners(); + } + this.updateClasses(); + this.updateAriaAttrs(); + this.updateCustomValidity(); + }; + + /** + * Determines if the field requires references to target fields. + */ + Field.prototype.updateDependencies = function updateDependencies () { + var this$1 = this; + + // reset dependencies. + this.dependencies.forEach(function (d) { return d.field.destroy(); }); + this.dependencies = []; + + // we get the selectors for each field. + var fields = Object.keys(this.rules).reduce(function (prev, r) { + if (Validator.isTargetRule(r)) { + prev.push({ selector: this$1.rules[r][0], name: r }); + } + + return prev; + }, []); + + if (!fields.length || !this.vm || !this.vm.$el) { return; } + + // must be contained within the same component, so we use the vm root element constrain our dom search. + fields.forEach(function (ref$1) { + var selector = ref$1.selector; + var name = ref$1.name; + + var ref = this$1.vm.$refs[selector]; + var el = Array.isArray(ref) ? ref[0] : ref; + if (!el) { + return; + } + + var options = { + vm: this$1.vm, + classes: this$1.classes, + classNames: this$1.classNames, + delay: this$1.delay, + scope: this$1.scope, + events: this$1.events.join('|'), + immediate: this$1.immediate, + targetOf: this$1.id + }; + + // probably a component. + if (isCallable(el.$watch)) { + options.component = el; + options.el = el.$el; + options.getter = Resolver.resolveGetter(el.$el, el.$vnode); + } else { + options.el = el; + options.getter = Resolver.resolveGetter(el, {}); + } + + this$1.dependencies.push({ name: name, field: new Field(options) }); + }); + }; + + /** + * Removes listeners. + */ + Field.prototype.unwatch = function unwatch (tag) { + if ( tag === void 0 ) tag = null; + + if (!tag) { + this.watchers.forEach(function (w) { return w.unwatch(); }); + this.watchers = []; + return; + } + + this.watchers.filter(function (w) { return tag.test(w.tag); }).forEach(function (w) { return w.unwatch(); }); + this.watchers = this.watchers.filter(function (w) { return !tag.test(w.tag); }); + }; + + /** + * Updates the element classes depending on each field flag status. + */ + Field.prototype.updateClasses = function updateClasses () { + var this$1 = this; + + if (!this.classes || this.isDisabled) { return; } + var applyClasses = function (el) { + toggleClass(el, this$1.classNames.dirty, this$1.flags.dirty); + toggleClass(el, this$1.classNames.pristine, this$1.flags.pristine); + toggleClass(el, this$1.classNames.touched, this$1.flags.touched); + toggleClass(el, this$1.classNames.untouched, this$1.flags.untouched); + // make sure we don't set any classes if the state is undetermined. + if (!isNullOrUndefined(this$1.flags.valid) && this$1.flags.validated) { + toggleClass(el, this$1.classNames.valid, this$1.flags.valid); + } + + if (!isNullOrUndefined(this$1.flags.invalid) && this$1.flags.validated) { + toggleClass(el, this$1.classNames.invalid, this$1.flags.invalid); + } + }; + + if (!isCheckboxOrRadioInput(this.el)) { + applyClasses(this.el); + return; + } + + var els = document.querySelectorAll(("input[name=\"" + (this.el.name) + "\"]")); + toArray(els).forEach(applyClasses); + }; + + /** + * Adds the listeners required for automatic classes and some flags. + */ + Field.prototype.addActionListeners = function addActionListeners () { + var this$1 = this; + + // remove previous listeners. + this.unwatch(/class/); + + if (!this.el) { return; } + + var onBlur = function () { + this$1.flags.touched = true; + this$1.flags.untouched = false; + if (this$1.classes) { + toggleClass(this$1.el, this$1.classNames.touched, true); + toggleClass(this$1.el, this$1.classNames.untouched, false); + } + + // only needed once. + this$1.unwatch(/^class_blur$/); + }; + + var inputEvent = isTextInput(this.el) ? 'input' : 'change'; + var onInput = function () { + this$1.flags.dirty = true; + this$1.flags.pristine = false; + if (this$1.classes) { + toggleClass(this$1.el, this$1.classNames.pristine, false); + toggleClass(this$1.el, this$1.classNames.dirty, true); + } + + // only needed once. + this$1.unwatch(/^class_input$/); + }; + + if (this.componentInstance && isCallable(this.componentInstance.$once)) { + this.componentInstance.$once('input', onInput); + this.componentInstance.$once('blur', onBlur); + this.watchers.push({ + tag: 'class_input', + unwatch: function () { + this$1.componentInstance.$off('input', onInput); + } + }); + this.watchers.push({ + tag: 'class_blur', + unwatch: function () { + this$1.componentInstance.$off('blur', onBlur); + } + }); + return; + } + + if (!this.el) { return; } + + addEventListener(this.el, inputEvent, onInput); + // Checkboxes and radio buttons on Mac don't emit blur naturally, so we listen on click instead. + var blurEvent = isCheckboxOrRadioInput(this.el) ? 'change' : 'blur'; + addEventListener(this.el, blurEvent, onBlur); + this.watchers.push({ + tag: 'class_input', + unwatch: function () { + this$1.el.removeEventListener(inputEvent, onInput); + } + }); + + this.watchers.push({ + tag: 'class_blur', + unwatch: function () { + this$1.el.removeEventListener(blurEvent, onBlur); + } + }); + }; + + Field.prototype.checkValueChanged = function checkValueChanged () { + // handle some people initialize the value to null, since text inputs have empty string value. + if (this.initialValue === null && this.value === '' && isTextInput(this.el)) { + return false; + } + + return this.value !== this.initialValue; + }; + + /** + * Determines the suitable primary event to listen for. + */ + Field.prototype._determineInputEvent = function _determineInputEvent () { + // if its a custom component, use the customized model event or the input event. + if (this.componentInstance) { + return (this.componentInstance.$options.model && this.componentInstance.$options.model.event) || 'input'; + } + + if (this.model && this.model.lazy) { + return 'change'; + } + + if (isTextInput(this.el)) { + return 'input'; + } + + return 'change'; + }; + + /** + * Determines the list of events to listen to. + */ + Field.prototype._determineEventList = function _determineEventList (defaultInputEvent) { + // if no event is configured, or it is a component or a text input then respect the user choice. + if (!this.events.length || this.componentInstance || isTextInput(this.el)) { + return [].concat( this.events ); + } + + // force suitable event for non-text type fields. + return this.events.map(function (e) { + if (e === 'input') { + return defaultInputEvent; + } + + return e; + }); + }; + + /** + * Adds the listeners required for validation. + */ + Field.prototype.addValueListeners = function addValueListeners () { + var this$1 = this; + + this.unwatch(/^input_.+/); + if (!this.listen || !this.el) { return; } + + var token = { cancelled: false }; + var fn = this.targetOf ? function () { + this$1.flags.changed = this$1.checkValueChanged(); this$1.validator.validate(("#" + (this$1.targetOf))); + } : function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + // if its a DOM event, resolve the value, otherwise use the first parameter as the value. + if (args.length === 0 || (isCallable(Event) && args[0] instanceof Event) || (args[0] && args[0].srcElement)) { + args[0] = this$1.value; + } + + this$1.flags.changed = this$1.checkValueChanged(); + this$1.validator.validate(("#" + (this$1.id)), args[0]); + }; + + var inputEvent = this._determineInputEvent(); + var events = this._determineEventList(inputEvent); + + // if there is a model and an on input validation is requested. + if (this.model && includes(events, inputEvent)) { + var ctx = null; + var expression = this.model.expression; + // if its watchable from the context vm. + if (this.model.expression) { + ctx = this.vm; + expression = this.model.expression; + } + + // watch it from the custom component vm instead. + if (!expression && this.componentInstance && this.componentInstance.$options.model) { + ctx = this.componentInstance; + expression = this.componentInstance.$options.model.prop || 'value'; + } + + if (ctx && expression) { + var debouncedFn = debounce(fn, this.delay[inputEvent], false, token); + var unwatch = ctx.$watch(expression, function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + this$1.flags.pending = true; + this$1._cancellationToken = token; + debouncedFn.apply(void 0, args); + }); + this.watchers.push({ + tag: 'input_model', + unwatch: unwatch + }); + + // filter out input event as it is already handled by the watcher API. + events = events.filter(function (e) { return e !== inputEvent; }); + } + } + + // Add events. + events.forEach(function (e) { + var debouncedFn = debounce(fn, this$1.delay[e], false, token); + var validate = function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + this$1.flags.pending = true; + this$1._cancellationToken = token; + debouncedFn.apply(void 0, args); + }; + + this$1._addComponentEventListener(e, validate); + this$1._addHTMLEventListener(e, validate); + }); + }; + + Field.prototype._addComponentEventListener = function _addComponentEventListener (evt, validate) { + var this$1 = this; + + if (!this.componentInstance) { return; } + + this.componentInstance.$on(evt, validate); + this.watchers.push({ + tag: 'input_vue', + unwatch: function () { + this$1.componentInstance.$off(evt, validate); + } + }); + }; + + Field.prototype._addHTMLEventListener = function _addHTMLEventListener (evt, validate) { + var this$1 = this; + + if (!this.el || this.componentInstance) { return; } + + // listen for the current element. + var addListener = function (el) { + addEventListener(el, evt, validate); + this$1.watchers.push({ + tag: 'input_native', + unwatch: function () { + el.removeEventListener(evt, validate); + } + }); + }; + + addListener(this.el); + if (!isCheckboxOrRadioInput(this.el)) { + return; + } + + var els = document.querySelectorAll(("input[name=\"" + (this.el.name) + "\"]")); + toArray(els).forEach(function (el) { + // skip if it is added by v-validate and is not the current element. + if (el._veeValidateId && el !== this$1.el) { + return; + } + + addListener(el); + }); + }; + + /** + * Updates aria attributes on the element. + */ + Field.prototype.updateAriaAttrs = function updateAriaAttrs () { + var this$1 = this; + + if (!this.aria || !this.el || !isCallable(this.el.setAttribute)) { return; } + + var applyAriaAttrs = function (el) { + el.setAttribute('aria-required', this$1.isRequired ? 'true' : 'false'); + el.setAttribute('aria-invalid', this$1.flags.invalid ? 'true' : 'false'); + }; + + if (!isCheckboxOrRadioInput(this.el)) { + applyAriaAttrs(this.el); + return; + } + + var els = document.querySelectorAll(("input[name=\"" + (this.el.name) + "\"]")); + toArray(els).forEach(applyAriaAttrs); + }; + + /** + * Updates the custom validity for the field. + */ + Field.prototype.updateCustomValidity = function updateCustomValidity () { + if (!this.validity || !this.el || !isCallable(this.el.setCustomValidity) || !this.validator.errors) { return; } + + this.el.setCustomValidity(this.flags.valid ? '' : (this.validator.errors.firstById(this.id) || '')); + }; + + /** + * Removes all listeners. + */ + Field.prototype.destroy = function destroy () { + // ignore the result of any ongoing validation. + if (this._cancellationToken) { + this._cancellationToken.cancelled = true; + } + + this.unwatch(); + this.dependencies.forEach(function (d) { return d.field.destroy(); }); + this.dependencies = []; + }; + + Object.defineProperties( Field.prototype, prototypeAccessors$3 ); + + // + + var FieldBag = function FieldBag (items) { + if ( items === void 0 ) items = []; + + this.items = items || []; + }; + + var prototypeAccessors$4 = { length: { configurable: true } }; + + FieldBag.prototype[typeof Symbol === 'function' ? Symbol.iterator : '@@iterator'] = function () { + var this$1 = this; + + var index = 0; + return { + next: function () { + return { value: this$1.items[index++], done: index > this$1.items.length }; + } + }; + }; + + /** + * Gets the current items length. + */ + + prototypeAccessors$4.length.get = function () { + return this.items.length; + }; + + /** + * Finds the first field that matches the provided matcher object. + */ + FieldBag.prototype.find = function find$1 (matcher) { + return find(this.items, function (item) { return item.matches(matcher); }); + }; + + /** + * Filters the items down to the matched fields. + */ + FieldBag.prototype.filter = function filter (matcher) { + // multiple matchers to be tried. + if (Array.isArray(matcher)) { + return this.items.filter(function (item) { return matcher.some(function (m) { return item.matches(m); }); }); + } + + return this.items.filter(function (item) { return item.matches(matcher); }); + }; + + /** + * Maps the field items using the mapping function. + */ + FieldBag.prototype.map = function map (mapper) { + return this.items.map(mapper); + }; + + /** + * Finds and removes the first field that matches the provided matcher object, returns the removed item. + */ + FieldBag.prototype.remove = function remove (matcher) { + var item = null; + if (matcher instanceof Field) { + item = matcher; + } else { + item = this.find(matcher); + } + + if (!item) { return null; } + + var index = this.items.indexOf(item); + this.items.splice(index, 1); + + return item; + }; + + /** + * Adds a field item to the list. + */ + FieldBag.prototype.push = function push (item) { + if (! (item instanceof Field)) { + throw createError('FieldBag only accepts instances of Field that has an id defined.'); + } + + if (!item.id) { + throw createError('Field id must be defined.'); + } + + if (this.find({ id: item.id })) { + throw createError(("Field with id " + (item.id) + " is already added.")); + } + + this.items.push(item); + }; + + Object.defineProperties( FieldBag.prototype, prototypeAccessors$4 ); + + var ScopedValidator = function ScopedValidator (base, vm) { + this.id = vm._uid; + this._base = base; + this._paused = false; + + // create a mirror bag with limited component scope. + this.errors = new ErrorBag(base.errors, this.id); + }; + + var prototypeAccessors$5 = { flags: { configurable: true },rules: { configurable: true },fields: { configurable: true },dictionary: { configurable: true },locale: { configurable: true } }; + + prototypeAccessors$5.flags.get = function () { + var this$1 = this; + + return this._base.fields.items.filter(function (f) { return f.vmId === this$1.id; }).reduce(function (acc, field) { + if (field.scope) { + if (!acc[("$" + (field.scope))]) { + acc[("$" + (field.scope))] = {}; + } + + acc[("$" + (field.scope))][field.name] = field.flags; + } + + acc[field.name] = field.flags; + + return acc; + }, {}); + }; + + prototypeAccessors$5.rules.get = function () { + return this._base.rules; + }; + + prototypeAccessors$5.fields.get = function () { + return new FieldBag(this._base.fields.filter({ vmId: this.id })); + }; + + prototypeAccessors$5.dictionary.get = function () { + return this._base.dictionary; + }; + + prototypeAccessors$5.locale.get = function () { + return this._base.locale; + }; + + prototypeAccessors$5.locale.set = function (val) { + this._base.locale = val; + }; + + ScopedValidator.prototype.localize = function localize () { + var ref; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + return (ref = this._base).localize.apply(ref, args); + }; + + ScopedValidator.prototype.update = function update () { + var ref; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + return (ref = this._base).update.apply(ref, args); + }; + + ScopedValidator.prototype.attach = function attach (opts) { + var attachOpts = assign({}, opts, { vmId: this.id }); + + return this._base.attach(attachOpts); + }; + + ScopedValidator.prototype.pause = function pause () { + this._paused = true; + }; + + ScopedValidator.prototype.resume = function resume () { + this._paused = false; + }; + + ScopedValidator.prototype.remove = function remove (ruleName) { + return this._base.remove(ruleName); + }; + + ScopedValidator.prototype.detach = function detach () { + var ref; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + return (ref = this._base).detach.apply(ref, args.concat( [this.id] )); + }; + + ScopedValidator.prototype.extend = function extend () { + var ref; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + return (ref = this._base).extend.apply(ref, args); + }; + + ScopedValidator.prototype.validate = function validate (descriptor, value, opts) { + if ( opts === void 0 ) opts = {}; + + if (this._paused) { return Promise.resolve(true); } + + return this._base.validate(descriptor, value, assign({}, { vmId: this.id }, opts || {})); + }; + + ScopedValidator.prototype.validateAll = function validateAll (values$$1, opts) { + if ( opts === void 0 ) opts = {}; + + if (this._paused) { return Promise.resolve(true); } + + return this._base.validateAll(values$$1, assign({}, { vmId: this.id }, opts || {})); + }; + + ScopedValidator.prototype.validateScopes = function validateScopes (opts) { + if ( opts === void 0 ) opts = {}; + + if (this._paused) { return Promise.resolve(true); } + + return this._base.validateScopes(assign({}, { vmId: this.id }, opts || {})); + }; + + ScopedValidator.prototype.destroy = function destroy () { + delete this.id; + delete this._base; + }; + + ScopedValidator.prototype.reset = function reset (matcher) { + return this._base.reset(Object.assign({}, matcher || {}, { vmId: this.id })); + }; + + ScopedValidator.prototype.flag = function flag () { + var ref; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + return (ref = this._base).flag.apply(ref, args.concat( [this.id] )); + }; + + Object.defineProperties( ScopedValidator.prototype, prototypeAccessors$5 ); + + // + + /** + * Checks if a parent validator instance was requested. + */ + var requestsValidator = function (injections) { + if (isObject(injections) && injections.$validator) { + return true; + } + + return false; + }; + + var mixin = { + provide: function provide () { + if (this.$validator && !isBuiltInComponent(this.$vnode)) { + return { + $validator: this.$validator + }; + } + + return {}; + }, + beforeCreate: function beforeCreate () { + // if built in do nothing. + if (isBuiltInComponent(this.$vnode)) { + return; + } + + // if its a root instance set the config if it exists. + if (!this.$parent) { + Config.merge(this.$options.$_veeValidate || {}); + } + + var options = Config.resolve(this); + + // if its a root instance, inject anyways, or if it requested a new instance. + if (!this.$parent || (this.$options.$_veeValidate && /new/.test(this.$options.$_veeValidate.validator))) { + this.$validator = new ScopedValidator(Config.dependency('validator'), this); + } + + var requested = requestsValidator(this.$options.inject); + + // if automatic injection is enabled and no instance was requested. + if (! this.$validator && options.inject && !requested) { + this.$validator = new ScopedValidator(Config.dependency('validator'), this); + } + + // don't inject errors or fieldBag as no validator was resolved. + if (! requested && ! this.$validator) { + return; + } + + // There is a validator but it isn't injected, mark as reactive. + if (!requested && this.$validator) { + var Vue = this.$options._base; // the vue constructor. + Vue.util.defineReactive(this.$validator, 'errors', this.$validator.errors); + } + + if (! this.$options.computed) { + this.$options.computed = {}; + } + + this.$options.computed[options.errorBagName || 'errors'] = function errorBagGetter () { + return this.$validator.errors; + }; + this.$options.computed[options.fieldsBagName || 'fields'] = function fieldBagGetter () { + return this.$validator.fields.items.reduce(function (acc, field) { + if (field.scope) { + if (!acc[("$" + (field.scope))]) { + acc[("$" + (field.scope))] = {}; + } + + acc[("$" + (field.scope))][field.name] = field.flags; + + return acc; + } + + acc[field.name] = field.flags; + + return acc; + }, {}); + }; + }, + beforeDestroy: function beforeDestroy () { + if (this.$validator && this._uid === this.$validator.id) { + this.$validator.errors.clear(); // remove errors generated by this component. + } + } + }; + + // + + /** + * Finds the requested field by id from the context object. + */ + function findField (el, context) { + if (!context || !context.$validator) { + return null; + } + + return context.$validator.fields.find({ id: el._veeValidateId }); + } + var directive = { + bind: function bind (el, binding, vnode) { + var validator = vnode.context.$validator; + if (!validator) { + { + warn("No validator instance is present on vm, did you forget to inject '$validator'?"); + } + + return; + } + + var fieldOptions = Resolver.generate(el, binding, vnode); + validator.attach(fieldOptions); + }, + inserted: function inserted (el, binding, vnode) { + var field = findField(el, vnode.context); + var scope = Resolver.resolveScope(el, binding, vnode); + + // skip if scope hasn't changed. + if (!field || scope === field.scope) { return; } + + // only update scope. + field.update({ scope: scope }); + + // allows the field to re-evaluated once more in the update hook. + field.updated = false; + }, + update: function update (el, binding, vnode) { + var field = findField(el, vnode.context); + + // make sure we don't do unneccasary work if no important change was done. + if (!field || (field.updated && isEqual$1(binding.value, binding.oldValue))) { return; } + var scope = Resolver.resolveScope(el, binding, vnode); + var rules = Resolver.resolveRules(el, binding, vnode); + + field.update({ + scope: scope, + rules: rules + }); + }, + unbind: function unbind (el, binding, ref) { + var context = ref.context; + + var field = findField(el, context); + if (!field) { return; } + + context.$validator.detach(field); + } + }; + + var Vue; + + function install (_Vue, options) { + if ( options === void 0 ) options = {}; + + if (Vue && _Vue === Vue) { + { + warn('already installed, Vue.use(VeeValidate) should only be called once.'); + } + return; + } + + detectPassiveSupport(); + Vue = _Vue; + var validator = new Validator(null, options); + var localVue = new Vue({ + data: function () { return ({ + errors: validator.errors, + fields: validator.fields + }); } + }); + Config.register('vm', localVue); + Config.register('validator', validator); + Config.merge(options); + + var ref = Config.current; + var dictionary = ref.dictionary; + var i18n = ref.i18n; + + if (dictionary) { + validator.localize(dictionary); // merge the dictionary. + } + + var onLocaleChanged = function () { + validator.errors.regenerate(); + }; + + // watch locale changes using localVue instance or i18n. + if (!i18n) { + if (typeof window !== 'undefined') { + localVue.$on('localeChanged', onLocaleChanged); + } + } else { + i18n._vm.$watch('locale', onLocaleChanged); + } + + if (!i18n && options.locale) { + validator.localize(options.locale); // set the locale + } + + Validator.setStrictMode(Config.current.strict); + + Vue.mixin(mixin); + Vue.directive('validate', directive); + } + + // + + function use (plugin, options) { + if ( options === void 0 ) options = {}; + + if (!isCallable(plugin)) { + return warn('The plugin must be a callable function'); + } + + plugin({ Validator: Validator, ErrorBag: ErrorBag, Rules: Validator.rules }, options); + } + + // + + var normalize = function (fields) { + if (Array.isArray(fields)) { + return fields.reduce(function (prev, curr) { + if (includes(curr, '.')) { + prev[curr.split('.')[1]] = curr; + } else { + prev[curr] = curr; + } + + return prev; + }, {}); + } + + return fields; + }; + + // Combines two flags using either AND or OR depending on the flag type. + var combine = function (lhs, rhs) { + var mapper = { + pristine: function (lhs, rhs) { return lhs && rhs; }, + dirty: function (lhs, rhs) { return lhs || rhs; }, + touched: function (lhs, rhs) { return lhs || rhs; }, + untouched: function (lhs, rhs) { return lhs && rhs; }, + valid: function (lhs, rhs) { return lhs && rhs; }, + invalid: function (lhs, rhs) { return lhs || rhs; }, + pending: function (lhs, rhs) { return lhs || rhs; }, + required: function (lhs, rhs) { return lhs || rhs; }, + validated: function (lhs, rhs) { return lhs && rhs; } + }; + + return Object.keys(mapper).reduce(function (flags, flag) { + flags[flag] = mapper[flag](lhs[flag], rhs[flag]); + + return flags; + }, {}); + }; + + var mapScope = function (scope, deep) { + if ( deep === void 0 ) deep = true; + + return Object.keys(scope).reduce(function (flags, field) { + if (!flags) { + flags = assign({}, scope[field]); + return flags; + } + + // scope. + var isScope = field.indexOf('$') === 0; + if (deep && isScope) { + return combine(mapScope(scope[field]), flags); + } else if (!deep && isScope) { + return flags; + } + + flags = combine(flags, scope[field]); + + return flags; + }, null); + }; + + /** + * Maps fields to computed functions. + */ + var mapFields = function (fields) { + if (!fields) { + return function () { + return mapScope(this.$validator.flags); + }; + } + + var normalized = normalize(fields); + return Object.keys(normalized).reduce(function (prev, curr) { + var field = normalized[curr]; + prev[curr] = function mappedField () { + // if field exists + if (this.$validator.flags[field]) { + return this.$validator.flags[field]; + } + + // scopeless fields were selected. + if (normalized[curr] === '*') { + return mapScope(this.$validator.flags, false); + } + + // if it has a scope defined + var index = field.indexOf('.'); + if (index <= 0) { + return {}; + } + + var ref = field.split('.'); + var scope = ref[0]; + var name = ref.slice(1); + + scope = this.$validator.flags[("$" + scope)]; + name = name.join('.'); + + // an entire scope was selected: scope.* + if (name === '*' && scope) { + return mapScope(scope); + } + + if (scope && scope[name]) { + return scope[name]; + } + + return {}; + }; + + return prev; + }, {}); + }; + + var ErrorComponent = { + name: 'vv-error', + inject: ['$validator'], + functional: true, + props: { + for: { + type: String, + required: true + }, + tag: { + type: String, + default: 'span' + } + }, + render: function render (createElement, ref) { + var props = ref.props; + var injections = ref.injections; + + return createElement(props.tag, injections.$validator.errors.first(props.for)); + } + }; + + var minimal = { + install: install, + use: use, + directive: directive, + mixin: mixin, + mapFields: mapFields, + Validator: Validator, + ErrorBag: ErrorBag, + ErrorComponent: ErrorComponent, + version: '2.1.0-beta.9' + }; + + // rules plugin definition. + var rulesPlugin = function (ref) { + var Validator = ref.Validator; + + Object.keys(Rules).forEach(function (rule) { + Validator.extend(rule, Rules[rule].validate, assign({}, Rules[rule].options, { paramNames: Rules[rule].paramNames })); + }); + + // Merge the english messages. + Validator.localize('en', locale$1); + }; + + // install the rules via the plugin API. + minimal.use(rulesPlugin); + + minimal.Rules = Rules; + + return minimal; + +}))); diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/vee-validate-locale-zh_CN-2.1.0.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/vee-validate-locale-zh_CN-2.1.0.js new file mode 100644 index 000000000..8af33f16d --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/vee-validate-locale-zh_CN-2.1.0.js @@ -0,0 +1 @@ +!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(n.__vee_validate_locale__zh_CN=n.__vee_validate_locale__zh_CN||{},n.__vee_validate_locale__zh_CN.js=e())}(this,function(){"use strict";var n,e={name:"zh_CN",messages:{after:function(n,e){return n+"必须在"+e[0]+"之后"},alpha_dash:function(n){return n+"能够包含字母数字字符、破折号和下划线"},alpha_num:function(n){return n+"只能包含字母数字字符"},alpha_spaces:function(n){return n+"只能包含字母字符和空格"},alpha:function(n){return n+"只能包含字母字符"},before:function(n,e){return n+"必须在"+e[0]+"之前"},between:function(n,e){return n+"必须在"+e[0]+"与"+e[1]+"之间"},confirmed:function(n,e){return n+"不能和"+e[0]+"匹配"},date_between:function(n,e){return n+"必须在"+e[0]+"和"+e[1]+"之间"},date_format:function(n,e){return n+"必须符合"+e[0]+"格式"},decimal:function(n,e){void 0===e&&(e=[]);var t=e[0];return void 0===t&&(t="*"),n+"必须是数字,且能够保留"+("*"===t?"":t)+"位小数"},digits:function(n,e){return n+"必须是数字,且精确到"+e[0]+"位数"},dimensions:function(n,e){return n+"必须在"+e[0]+"像素与"+e[1]+"像素之间"},email:function(n){return n+"不是一个有效的邮箱"},ext:function(n){return n+"不是一个有效的文件"},image:function(n){return n+"不是一张有效的图片"},included:function(n){return n+"不是一个有效值"},ip:function(n){return n+"不是一个有效的地址"},max:function(n,e){return n+"不能超过"+e[0]+"个字符"},max_value:function(n,e){return n+"必须小于或等于"+e[0]},mimes:function(n){return n+"不是一个有效的文件类型"},min:function(n,e){return n+"必须至少有"+e[0]+"个字符"},min_value:function(n,e){return n+"必须大于或等于"+e[0]},excluded:function(n){return n+"不是一个有效值"},numeric:function(n){return n+"只能包含数字字符"},regex:function(n){return n+"格式无效"},required:function(n){return n+"是必须的"},size:function(n,e){var t,r,u,i=e[0];return n+"必须小于"+(t=i,r=1024,u=0==(t=Number(t)*r)?0:Math.floor(Math.log(t)/Math.log(r)),1*(t/Math.pow(r,u)).toFixed(2)+" "+["Byte","KB","MB","GB","TB","PB","EB","ZB","YB"][u])},url:function(n){return n+"不是一个有效的url"}},attributes:{}};return"undefined"!=typeof VeeValidate&&VeeValidate.Validator.localize(((n={})[e.name]=e,n)),e}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/vue-2.5.16.min.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/vue-2.5.16.min.js new file mode 100644 index 000000000..37febff24 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/vue-2.5.16.min.js @@ -0,0 +1,6 @@ +/*! + * Vue.js v2.5.16 + * (c) 2014-2018 Evan You + * Released under the MIT License. + */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Vue=t()}(this,function(){"use strict";var y=Object.freeze({});function M(e){return null==e}function D(e){return null!=e}function S(e){return!0===e}function T(e){return"string"==typeof e||"number"==typeof e||"symbol"==typeof e||"boolean"==typeof e}function P(e){return null!==e&&"object"==typeof e}var r=Object.prototype.toString;function l(e){return"[object Object]"===r.call(e)}function i(e){var t=parseFloat(String(e));return 0<=t&&Math.floor(t)===t&&isFinite(e)}function t(e){return null==e?"":"object"==typeof e?JSON.stringify(e,null,2):String(e)}function F(e){var t=parseFloat(e);return isNaN(t)?e:t}function s(e,t){for(var n=Object.create(null),r=e.split(","),i=0;ie.id;)n--;bt.splice(n+1,0,e)}else bt.push(e);Ct||(Ct=!0,Ze(At))}}(this)},St.prototype.run=function(){if(this.active){var e=this.get();if(e!==this.value||P(e)||this.deep){var t=this.value;if(this.value=e,this.user)try{this.cb.call(this.vm,e,t)}catch(e){Fe(e,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,e,t)}}},St.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},St.prototype.depend=function(){for(var e=this.deps.length;e--;)this.deps[e].depend()},St.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||f(this.vm._watchers,this);for(var e=this.deps.length;e--;)this.deps[e].removeSub(this);this.active=!1}};var Tt={enumerable:!0,configurable:!0,get:$,set:$};function Et(e,t,n){Tt.get=function(){return this[t][n]},Tt.set=function(e){this[t][n]=e},Object.defineProperty(e,n,Tt)}function jt(e){e._watchers=[];var t=e.$options;t.props&&function(n,r){var i=n.$options.propsData||{},o=n._props={},a=n.$options._propKeys=[];n.$parent&&ge(!1);var e=function(e){a.push(e);var t=Ie(e,r,i,n);Ce(o,e,t),e in n||Et(n,"_props",e)};for(var t in r)e(t);ge(!0)}(e,t.props),t.methods&&function(e,t){e.$options.props;for(var n in t)e[n]=null==t[n]?$:v(t[n],e)}(e,t.methods),t.data?function(e){var t=e.$options.data;l(t=e._data="function"==typeof t?function(e,t){se();try{return e.call(t,t)}catch(e){return Fe(e,t,"data()"),{}}finally{ce()}}(t,e):t||{})||(t={});var n=Object.keys(t),r=e.$options.props,i=(e.$options.methods,n.length);for(;i--;){var o=n[i];r&&p(r,o)||(void 0,36!==(a=(o+"").charCodeAt(0))&&95!==a&&Et(e,"_data",o))}var a;we(t,!0)}(e):we(e._data={},!0),t.computed&&function(e,t){var n=e._computedWatchers=Object.create(null),r=Y();for(var i in t){var o=t[i],a="function"==typeof o?o:o.get;r||(n[i]=new St(e,a||$,$,Nt)),i in e||Lt(e,i,o)}}(e,t.computed),t.watch&&t.watch!==G&&function(e,t){for(var n in t){var r=t[n];if(Array.isArray(r))for(var i=0;iparseInt(this.max)&&bn(a,s[0],s,this._vnode)),t.data.keepAlive=!0}return t||e&&e[0]}}};$n=hn,Cn={get:function(){return j}},Object.defineProperty($n,"config",Cn),$n.util={warn:re,extend:m,mergeOptions:Ne,defineReactive:Ce},$n.set=xe,$n.delete=ke,$n.nextTick=Ze,$n.options=Object.create(null),k.forEach(function(e){$n.options[e+"s"]=Object.create(null)}),m(($n.options._base=$n).options.components,kn),$n.use=function(e){var t=this._installedPlugins||(this._installedPlugins=[]);if(-1=a&&l()};setTimeout(function(){c\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,oo="[a-zA-Z_][\\w\\-\\.]*",ao="((?:"+oo+"\\:)?"+oo+")",so=new RegExp("^<"+ao),co=/^\s*(\/?)>/,lo=new RegExp("^<\\/"+ao+"[^>]*>"),uo=/^]+>/i,fo=/^",""":'"',"&":"&"," ":"\n"," ":"\t"},go=/&(?:lt|gt|quot|amp);/g,_o=/&(?:lt|gt|quot|amp|#10|#9);/g,bo=s("pre,textarea",!0),$o=function(e,t){return e&&bo(e)&&"\n"===t[0]};var wo,Co,xo,ko,Ao,Oo,So,To,Eo=/^@|^v-on:/,jo=/^v-|^@|^:/,No=/([^]*?)\s+(?:in|of)\s+([^]*)/,Lo=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,Io=/^\(|\)$/g,Mo=/:(.*)$/,Do=/^:|^v-bind:/,Po=/\.[^.]+/g,Fo=e(eo);function Ro(e,t,n){return{type:1,tag:e,attrsList:t,attrsMap:function(e){for(var t={},n=0,r=e.length;n]*>)","i")),n=i.replace(t,function(e,t,n){return r=n.length,ho(o)||"noscript"===o||(t=t.replace(//g,"$1").replace(//g,"$1")),$o(o,t)&&(t=t.slice(1)),d.chars&&d.chars(t),""});a+=i.length-n.length,i=n,A(o,a-r,a)}else{var s=i.indexOf("<");if(0===s){if(fo.test(i)){var c=i.indexOf("--\x3e");if(0<=c){d.shouldKeepComment&&d.comment(i.substring(4,c)),C(c+3);continue}}if(po.test(i)){var l=i.indexOf("]>");if(0<=l){C(l+2);continue}}var u=i.match(uo);if(u){C(u[0].length);continue}var f=i.match(lo);if(f){var p=a;C(f[0].length),A(f[1],p,a);continue}var _=x();if(_){k(_),$o(v,i)&&C(1);continue}}var b=void 0,$=void 0,w=void 0;if(0<=s){for($=i.slice(s);!(lo.test($)||so.test($)||fo.test($)||po.test($)||(w=$.indexOf("<",1))<0);)s+=w,$=i.slice(s);b=i.substring(0,s),C(s)}s<0&&(b=i,i=""),d.chars&&b&&d.chars(b)}if(i===e){d.chars&&d.chars(i);break}}function C(e){a+=e,i=i.substring(e)}function x(){var e=i.match(so);if(e){var t,n,r={tagName:e[1],attrs:[],start:a};for(C(e[0].length);!(t=i.match(co))&&(n=i.match(io));)C(n[0].length),r.attrs.push(n);if(t)return r.unarySlash=t[1],C(t[0].length),r.end=a,r}}function k(e){var t=e.tagName,n=e.unarySlash;m&&("p"===v&&ro(t)&&A(v),g(t)&&v===t&&A(t));for(var r,i,o,a=y(t)||!!n,s=e.attrs.length,c=new Array(s),l=0;l-1"+("true"===d?":("+l+")":":_q("+l+","+d+")")),Ar(c,"change","var $$a="+l+",$$el=$event.target,$$c=$$el.checked?("+d+"):("+v+");if(Array.isArray($$a)){var $$v="+(f?"_n("+p+")":p)+",$$i=_i($$a,$$v);if($$el.checked){$$i<0&&("+Er(l,"$$a.concat([$$v])")+")}else{$$i>-1&&("+Er(l,"$$a.slice(0,$$i).concat($$a.slice($$i+1))")+")}}else{"+Er(l,"$$c")+"}",null,!0);else if("input"===$&&"radio"===w)r=e,i=_,a=(o=b)&&o.number,s=Or(r,"value")||"null",Cr(r,"checked","_q("+i+","+(s=a?"_n("+s+")":s)+")"),Ar(r,"change",Er(i,s),null,!0);else if("input"===$||"textarea"===$)!function(e,t,n){var r=e.attrsMap.type,i=n||{},o=i.lazy,a=i.number,s=i.trim,c=!o&&"range"!==r,l=o?"change":"range"===r?Pr:"input",u="$event.target.value";s&&(u="$event.target.value.trim()"),a&&(u="_n("+u+")");var f=Er(t,u);c&&(f="if($event.target.composing)return;"+f),Cr(e,"value","("+t+")"),Ar(e,l,f,null,!0),(s||a)&&Ar(e,"blur","$forceUpdate()")}(e,_,b);else if(!j.isReservedTag($))return Tr(e,_,b),!1;return!0},text:function(e,t){t.value&&Cr(e,"textContent","_s("+t.value+")")},html:function(e,t){t.value&&Cr(e,"innerHTML","_s("+t.value+")")}},isPreTag:function(e){return"pre"===e},isUnaryTag:to,mustUseProp:Sn,canBeLeftOpenTag:no,isReservedTag:Un,getTagNamespace:Vn,staticKeys:(Go=Wo,Go.reduce(function(e,t){return e.concat(t.staticKeys||[])},[]).join(","))},Qo=e(function(e){return s("type,tag,attrsList,attrsMap,plain,parent,children,attrs"+(e?","+e:""))});function ea(e,t){e&&(Zo=Qo(t.staticKeys||""),Xo=t.isReservedTag||O,function e(t){t.static=function(e){if(2===e.type)return!1;if(3===e.type)return!0;return!(!e.pre&&(e.hasBindings||e.if||e.for||c(e.tag)||!Xo(e.tag)||function(e){for(;e.parent;){if("template"!==(e=e.parent).tag)return!1;if(e.for)return!0}return!1}(e)||!Object.keys(e).every(Zo)))}(t);if(1===t.type){if(!Xo(t.tag)&&"slot"!==t.tag&&null==t.attrsMap["inline-template"])return;for(var n=0,r=t.children.length;n|^function\s*\(/,na=/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/,ra={esc:27,tab:9,enter:13,space:32,up:38,left:37,right:39,down:40,delete:[8,46]},ia={esc:"Escape",tab:"Tab",enter:"Enter",space:" ",up:["Up","ArrowUp"],left:["Left","ArrowLeft"],right:["Right","ArrowRight"],down:["Down","ArrowDown"],delete:["Backspace","Delete"]},oa=function(e){return"if("+e+")return null;"},aa={stop:"$event.stopPropagation();",prevent:"$event.preventDefault();",self:oa("$event.target !== $event.currentTarget"),ctrl:oa("!$event.ctrlKey"),shift:oa("!$event.shiftKey"),alt:oa("!$event.altKey"),meta:oa("!$event.metaKey"),left:oa("'button' in $event && $event.button !== 0"),middle:oa("'button' in $event && $event.button !== 1"),right:oa("'button' in $event && $event.button !== 2")};function sa(e,t,n){var r=t?"nativeOn:{":"on:{";for(var i in e)r+='"'+i+'":'+ca(i,e[i])+",";return r.slice(0,-1)+"}"}function ca(t,e){if(!e)return"function(){}";if(Array.isArray(e))return"["+e.map(function(e){return ca(t,e)}).join(",")+"]";var n=na.test(e.value),r=ta.test(e.value);if(e.modifiers){var i="",o="",a=[];for(var s in e.modifiers)if(aa[s])o+=aa[s],ra[s]&&a.push(s);else if("exact"===s){var c=e.modifiers;o+=oa(["ctrl","shift","alt","meta"].filter(function(e){return!c[e]}).map(function(e){return"$event."+e+"Key"}).join("||"))}else a.push(s);return a.length&&(i+="if(!('button' in $event)&&"+a.map(la).join("&&")+")return null;"),o&&(i+=o),"function($event){"+i+(n?"return "+e.value+"($event)":r?"return ("+e.value+")($event)":e.value)+"}"}return n||r?e.value:"function($event){"+e.value+"}"}function la(e){var t=parseInt(e,10);if(t)return"$event.keyCode!=="+t;var n=ra[e],r=ia[e];return"_k($event.keyCode,"+JSON.stringify(e)+","+JSON.stringify(n)+",$event.key,"+JSON.stringify(r)+")"}var ua={on:function(e,t){e.wrapListeners=function(e){return"_g("+e+","+t.value+")"}},bind:function(t,n){t.wrapData=function(e){return"_b("+e+",'"+t.tag+"',"+n.value+","+(n.modifiers&&n.modifiers.prop?"true":"false")+(n.modifiers&&n.modifiers.sync?",true":"")+")"}},cloak:$},fa=function(e){this.options=e,this.warn=e.warn||$r,this.transforms=wr(e.modules,"transformCode"),this.dataGenFns=wr(e.modules,"genData"),this.directives=m(m({},ua),e.directives);var t=e.isReservedTag||O;this.maybeComponent=function(e){return!t(e.tag)},this.onceId=0,this.staticRenderFns=[]};function pa(e,t){var n=new fa(t);return{render:"with(this){return "+(e?da(e,n):'_c("div")')+"}",staticRenderFns:n.staticRenderFns}}function da(e,t){if(e.staticRoot&&!e.staticProcessed)return va(e,t);if(e.once&&!e.onceProcessed)return ha(e,t);if(e.for&&!e.forProcessed)return f=t,v=(u=e).for,h=u.alias,m=u.iterator1?","+u.iterator1:"",y=u.iterator2?","+u.iterator2:"",u.forProcessed=!0,(d||"_l")+"(("+v+"),function("+h+m+y+"){return "+(p||da)(u,f)+"})";if(e.if&&!e.ifProcessed)return ma(e,t);if("template"!==e.tag||e.slotTarget){if("slot"===e.tag)return function(e,t){var n=e.slotName||'"default"',r=_a(e,t),i="_t("+n+(r?","+r:""),o=e.attrs&&"{"+e.attrs.map(function(e){return g(e.name)+":"+e.value}).join(",")+"}",a=e.attrsMap["v-bind"];!o&&!a||r||(i+=",null");o&&(i+=","+o);a&&(i+=(o?"":",null")+","+a);return i+")"}(e,t);var n;if(e.component)a=e.component,c=t,l=(s=e).inlineTemplate?null:_a(s,c,!0),n="_c("+a+","+ya(s,c)+(l?","+l:"")+")";else{var r=e.plain?void 0:ya(e,t),i=e.inlineTemplate?null:_a(e,t,!0);n="_c('"+e.tag+"'"+(r?","+r:"")+(i?","+i:"")+")"}for(var o=0;o':'
        ',0= 200 && xhr.status < 300) { + var response; + try { + response = JSON.parse(xhr.response); + } catch (err) { + response = xhr.response; + } + resolve(response); + } else { + reject(xhr.response); + } + }; + xhr.onerror = function () { + return reject(xhr.response); + }; + xhr.send(JSON.stringify(body)); + }); + }; + + /** + * Sends a XHR request with certain form data + * + * @param {XMLHttpRequest} xhr + * @param {Object} data + */ + var sendFormRequest = function sendFormRequest(xhr, data) { + var body = new FormData(); + for (var name in data) { + body.append(name, data[name]); + } + + return new Promise(function (resolve, reject) { + xhr.onload = function () { + if (xhr.status >= 200 && xhr.status < 300) { + var response; + try { + response = JSON.parse(xhr.response); + } catch (err) { + response = xhr.response; + } + resolve(response); + } else { + reject(xhr.response); + } + }; + xhr.onerror = function () { + return reject(xhr.response); + }; + xhr.send(body); + }); + }; + + /** + * Creates and sends XHR request + * + * @param {Object} options + * + * @returns Promise + */ + function request (options) { + var xhr = createRequest(options); + + return sendRequest(xhr, options.body); + } + + var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } + + var ChunkUploadHandler = function () { + /** + * Constructor + * + * @param {File} file + * @param {Object} options + */ + function ChunkUploadHandler(file, options) { + _classCallCheck(this, ChunkUploadHandler); + + this.file = file; + this.options = options; + } + + /** + * Gets the max retries from options + */ + + + _createClass(ChunkUploadHandler, [{ + key: 'createChunks', + + + /** + * Creates all the chunks in the initial state + */ + value: function createChunks() { + this.chunks = []; + + var start = 0; + var end = this.chunkSize; + while (start < this.fileSize) { + this.chunks.push({ + blob: this.file.file.slice(start, end), + startOffset: start, + active: false, + retries: this.maxRetries + }); + start = end; + end = start + this.chunkSize; + } + } + + /** + * Updates the progress of the file with the handler's progress + */ + + }, { + key: 'updateFileProgress', + value: function updateFileProgress() { + this.file.progress = this.progress; + } + + /** + * Paues the upload process + * - Stops all active requests + * - Sets the file not active + */ + + }, { + key: 'pause', + value: function pause() { + this.file.active = false; + this.stopChunks(); + } + + /** + * Stops all the current chunks + */ + + }, { + key: 'stopChunks', + value: function stopChunks() { + this.chunksUploading.forEach(function (chunk) { + chunk.xhr.abort(); + chunk.active = false; + }); + } + + /** + * Resumes the file upload + * - Sets the file active + * - Starts the following chunks + */ + + }, { + key: 'resume', + value: function resume() { + this.file.active = true; + this.startChunking(); + } + + /** + * Starts the file upload + * + * @returns Promise + * - resolve The file was uploaded + * - reject The file upload failed + */ + + }, { + key: 'upload', + value: function upload() { + var _this = this; + + this.promise = new Promise(function (resolve, reject) { + _this.resolve = resolve; + _this.reject = reject; + }); + this.start(); + + return this.promise; + } + + /** + * Start phase + * Sends a request to the backend to initialise the chunks + */ + + }, { + key: 'start', + value: function start() { + var _this2 = this; + + request({ + method: 'POST', + headers: Object.assign({}, this.headers, { + 'Content-Type': 'application/json' + }), + url: this.action, + body: Object.assign(this.startBody, { + phase: 'start', + mime_type: this.fileType, + size: this.fileSize, + name: this.fileName + }) + }).then(function (res) { + if (res.status !== 'success') { + _this2.file.response = res; + return _this2.reject('server'); + } + + _this2.sessionId = res.data.session_id; + _this2.chunkSize = res.data.end_offset; + + _this2.createChunks(); + _this2.startChunking(); + }).catch(function (res) { + _this2.file.response = res; + _this2.reject('server'); + }); + } + + /** + * Starts to upload chunks + */ + + }, { + key: 'startChunking', + value: function startChunking() { + for (var i = 0; i < this.maxActiveChunks; i++) { + this.uploadNextChunk(); + } + } + + /** + * Uploads the next chunk + * - Won't do anything if the process is paused + * - Will start finish phase if there are no more chunks to upload + */ + + }, { + key: 'uploadNextChunk', + value: function uploadNextChunk() { + if (this.file.active) { + if (this.hasChunksToUpload) { + return this.uploadChunk(this.chunksToUpload[0]); + } + + if (this.chunksUploading.length === 0) { + return this.finish(); + } + } + } + + /** + * Uploads a chunk + * - Sends the chunk to the backend + * - Sets the chunk as uploaded if everything went well + * - Decreases the number of retries if anything went wrong + * - Fails if there are no more retries + * + * @param {Object} chunk + */ + + }, { + key: 'uploadChunk', + value: function uploadChunk(chunk) { + var _this3 = this; + + chunk.progress = 0; + chunk.active = true; + this.updateFileProgress(); + chunk.xhr = createRequest({ + method: 'POST', + headers: this.headers, + url: this.action + }); + + chunk.xhr.upload.addEventListener('progress', function (evt) { + if (evt.lengthComputable) { + chunk.progress = Math.round(evt.loaded / evt.total * 100); + } + }, false); + + sendFormRequest(chunk.xhr, Object.assign(this.uploadBody, { + phase: 'upload', + session_id: this.sessionId, + start_offset: chunk.startOffset, + chunk: chunk.blob + })).then(function (res) { + chunk.active = false; + if (res.status === 'success') { + chunk.uploaded = true; + } else { + if (chunk.retries-- <= 0) { + _this3.stopChunks(); + return _this3.reject('upload'); + } + } + + _this3.uploadNextChunk(); + }).catch(function () { + chunk.active = false; + if (chunk.retries-- <= 0) { + _this3.stopChunks(); + return _this3.reject('upload'); + } + + _this3.uploadNextChunk(); + }); + } + + /** + * Finish phase + * Sends a request to the backend to finish the process + */ + + }, { + key: 'finish', + value: function finish() { + var _this4 = this; + + this.updateFileProgress(); + + request({ + method: 'POST', + headers: Object.assign({}, this.headers, { + 'Content-Type': 'application/json' + }), + url: this.action, + body: Object.assign(this.finishBody, { + phase: 'finish', + session_id: this.sessionId + }) + }).then(function (res) { + _this4.file.response = res; + if (res.status !== 'success') { + return _this4.reject('server'); + } + + _this4.resolve(res); + }).catch(function (res) { + _this4.file.response = res; + _this4.reject('server'); + }); + } + }, { + key: 'maxRetries', + get: function get() { + return parseInt(this.options.maxRetries); + } + + /** + * Gets the max number of active chunks being uploaded at once from options + */ + + }, { + key: 'maxActiveChunks', + get: function get() { + return parseInt(this.options.maxActive); + } + + /** + * Gets the file type + */ + + }, { + key: 'fileType', + get: function get() { + return this.file.type; + } + + /** + * Gets the file size + */ + + }, { + key: 'fileSize', + get: function get() { + return this.file.size; + } + + /** + * Gets the file size + */ + + }, { + key: 'fileName', + get: function get() { + return this.file.name; + } + + /** + * Gets action (url) to upload the file + */ + + }, { + key: 'action', + get: function get() { + return this.options.action || null; + } + + /** + * Gets the body to be merged when sending the request in start phase + */ + + }, { + key: 'startBody', + get: function get() { + return this.options.startBody || {}; + } + + /** + * Gets the body to be merged when sending the request in upload phase + */ + + }, { + key: 'uploadBody', + get: function get() { + return this.options.uploadBody || {}; + } + + /** + * Gets the body to be merged when sending the request in finish phase + */ + + }, { + key: 'finishBody', + get: function get() { + return this.options.finishBody || {}; + } + + /** + * Gets the headers of the requests from options + */ + + }, { + key: 'headers', + get: function get() { + return this.options.headers || {}; + } + + /** + * Whether it's ready to upload files or not + */ + + }, { + key: 'readyToUpload', + get: function get() { + return !!this.chunks; + } + + /** + * Gets the progress of the chunk upload + * - Gets all the completed chunks + * - Gets the progress of all the chunks that are being uploaded + */ + + }, { + key: 'progress', + get: function get() { + var _this5 = this; + + var completedProgress = this.chunksUploaded.length / this.chunks.length * 100; + var uploadingProgress = this.chunksUploading.reduce(function (progress, chunk) { + return progress + (chunk.progress | 0) / _this5.chunks.length; + }, 0); + + return Math.min(completedProgress + uploadingProgress, 100); + } + + /** + * Gets all the chunks that are pending to be uploaded + */ + + }, { + key: 'chunksToUpload', + get: function get() { + return this.chunks.filter(function (chunk) { + return !chunk.active && !chunk.uploaded; + }); + } + + /** + * Whether there are chunks to upload or not + */ + + }, { + key: 'hasChunksToUpload', + get: function get() { + return this.chunksToUpload.length > 0; + } + + /** + * Gets all the chunks that are uploading + */ + + }, { + key: 'chunksUploading', + get: function get() { + return this.chunks.filter(function (chunk) { + return !!chunk.xhr && !!chunk.active; + }); + } + + /** + * Gets all the chunks that have finished uploading + */ + + }, { + key: 'chunksUploaded', + get: function get() { + return this.chunks.filter(function (chunk) { + return !!chunk.uploaded; + }); + } + }]); + + return ChunkUploadHandler; + }(); + + // + // + // + // + // + // + // + // + // + // + // + // + // + + var script = { + methods: { + change: function change(e) { + this.$parent.addInputFile(e.target); + e.target.value = ''; + if (!e.target.files) { + // ie9 fix #219 + this.$destroy(); + // eslint-disable-next-line + new this.constructor({ + parent: this.$parent, + el: this.$el + }); + } + } + } + }; + + /* script */ + var __vue_script__ = script; + + /* template */ + var __vue_render__ = function __vue_render__() { + var _vm = this;var _h = _vm.$createElement;var _c = _vm._self._c || _h;return _c('input', { attrs: { "type": "file", "name": _vm.$parent.name, "id": _vm.$parent.inputId || _vm.$parent.name, "accept": _vm.$parent.accept, "capture": _vm.$parent.capture, "webkitdirectory": _vm.$parent.directory && _vm.$parent.features.directory, "directory": _vm.$parent.directory && _vm.$parent.features.directory, "multiple": _vm.$parent.multiple && _vm.$parent.features.html5 }, on: { "change": _vm.change } }); + }; + var __vue_staticRenderFns__ = []; + + /* style */ + var __vue_inject_styles__ = undefined; + /* scoped */ + var __vue_scope_id__ = undefined; + /* module identifier */ + var __vue_module_identifier__ = undefined; + /* functional template */ + var __vue_is_functional_template__ = false; + /* component normalizer */ + function __vue_normalize__(template, style, script$$1, scope, functional, moduleIdentifier, createInjector, createInjectorSSR) { + var component = (typeof script$$1 === 'function' ? script$$1.options : script$$1) || {}; + + if (!component.render) { + component.render = template.render; + component.staticRenderFns = template.staticRenderFns; + component._compiled = true; + + if (functional) component.functional = true; + } + + component._scopeId = scope; + + return component; + } + /* style inject */ + function __vue_create_injector__() { + var head = document.head || document.getElementsByTagName('head')[0]; + var styles = __vue_create_injector__.styles || (__vue_create_injector__.styles = {}); + var isOldIE = typeof navigator !== 'undefined' && /msie [6-9]\\b/.test(navigator.userAgent.toLowerCase()); + + return function addStyle(id, css) { + if (document.querySelector('style[data-vue-ssr-id~="' + id + '"]')) return; // SSR styles are present. + + var group = isOldIE ? css.media || 'default' : id; + var style = styles[group] || (styles[group] = { ids: [], parts: [], element: undefined }); + + if (!style.ids.includes(id)) { + var code = css.source; + var index = style.ids.length; + + style.ids.push(id); + + if (css.map) { + // https://developer.chrome.com/devtools/docs/javascript-debugging + // this makes source maps inside style tags work properly in Chrome + code += '\n/*# sourceURL=' + css.map.sources[0] + ' */'; + // http://stackoverflow.com/a/26603875 + code += '\n/*# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(JSON.stringify(css.map)))) + ' */'; + } + + if (isOldIE) { + style.element = style.element || document.querySelector('style[data-group=' + group + ']'); + } + + if (!style.element) { + var el = style.element = document.createElement('style'); + el.type = 'text/css'; + + if (css.media) el.setAttribute('media', css.media); + if (isOldIE) { + el.setAttribute('data-group', group); + el.setAttribute('data-next-index', '0'); + } + + head.appendChild(el); + } + + if (isOldIE) { + index = parseInt(style.element.getAttribute('data-next-index')); + style.element.setAttribute('data-next-index', index + 1); + } + + if (style.element.styleSheet) { + style.parts.push(code); + style.element.styleSheet.cssText = style.parts.filter(Boolean).join('\n'); + } else { + var textNode = document.createTextNode(code); + var nodes = style.element.childNodes; + if (nodes[index]) style.element.removeChild(nodes[index]); + if (nodes.length) style.element.insertBefore(textNode, nodes[index]);else style.element.appendChild(textNode); + } + } + }; + } + /* style inject SSR */ + + var InputFile = __vue_normalize__({ render: __vue_render__, staticRenderFns: __vue_staticRenderFns__ }, __vue_inject_styles__, __vue_script__, __vue_scope_id__, __vue_is_functional_template__, __vue_module_identifier__, __vue_create_injector__, undefined); + + var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; + + var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + + function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } } + + var CHUNK_DEFAULT_OPTIONS = { + headers: {}, + action: '', + minSize: 1048576, + maxActive: 3, + maxRetries: 5, + + handler: ChunkUploadHandler + }; + + var script$1 = { + components: { + InputFile: InputFile + }, + props: { + inputId: { + type: String + }, + + name: { + type: String, + default: 'file' + }, + + accept: { + type: String + }, + + capture: {}, + + multiple: { + type: Boolean + }, + + maximum: { + type: Number, + default: function _default() { + return this.multiple ? 0 : 1; + } + }, + + addIndex: { + type: [Boolean, Number] + }, + + directory: { + type: Boolean + }, + + postAction: { + type: String + }, + + putAction: { + type: String + }, + + customAction: { + type: Function + }, + + headers: { + type: Object, + default: Object + }, + + data: { + type: Object, + default: Object + }, + + timeout: { + type: Number, + default: 0 + }, + + drop: { + default: false + }, + + dropDirectory: { + type: Boolean, + default: true + }, + + size: { + type: Number, + default: 0 + }, + + extensions: { + default: Array + }, + + value: { + type: Array, + default: Array + }, + + thread: { + type: Number, + default: 1 + }, + + // Chunk upload enabled + chunkEnabled: { + type: Boolean, + default: false + }, + + // Chunk upload properties + chunk: { + type: Object, + default: function _default() { + return CHUNK_DEFAULT_OPTIONS; + } + } + }, + + data: function data() { + return { + files: this.value, + features: { + html5: true, + directory: false, + drag: false + }, + + active: false, + dropActive: false, + + uploading: 0, + + destroy: false + }; + }, + + + /** + * mounted + * @return {[type]} [description] + */ + mounted: function mounted() { + var input = document.createElement('input'); + input.type = 'file'; + input.multiple = true; + + // html5 特征 + if (window.FormData && input.files) { + // 上传目录特征 + if (typeof input.webkitdirectory === 'boolean' || typeof input.directory === 'boolean') { + this.features.directory = true; + } + + // 拖拽特征 + if (this.features.html5 && typeof input.ondrop !== 'undefined') { + this.features.drop = true; + } + } else { + this.features.html5 = false; + } + + // files 定位缓存 + this.maps = {}; + + this.$nextTick(function () { + + // 更新下父级 + if (this.$parent) { + this.$parent.$forceUpdate(); + } + + // 拖拽渲染 + this.watchDrop(this.drop); + }); + }, + + + /** + * beforeDestroy + * @return {[type]} [description] + */ + beforeDestroy: function beforeDestroy() { + // 已销毁 + this.destroy = true; + + // 设置成不激活 + this.active = false; + }, + + + computed: { + /** + * uploading 正在上传的线程 + * @return {[type]} [description] + */ + + /** + * uploaded 文件列表是否全部已上传 + * @return {[type]} [description] + */ + uploaded: function uploaded() { + var file = void 0; + for (var i = 0; i < this.files.length; i++) { + file = this.files[i]; + if (file.fileObject && !file.error && !file.success) { + return false; + } + } + return true; + }, + chunkOptions: function chunkOptions() { + return Object.assign(CHUNK_DEFAULT_OPTIONS, this.chunk); + }, + className: function className() { + return ['file-uploads', this.features.html5 ? 'file-uploads-html5' : 'file-uploads-html4', this.features.directory && this.directory ? 'file-uploads-directory' : undefined, this.features.drop && this.drop ? 'file-uploads-drop' : undefined]; + } + }, + + watch: { + active: function active(_active) { + this.watchActive(_active); + }, + dropActive: function dropActive() { + if (this.$parent) { + this.$parent.$forceUpdate(); + } + }, + drop: function drop(value) { + this.watchDrop(value); + }, + value: function value(files) { + if (this.files === files) { + return; + } + this.files = files; + + var oldMaps = this.maps; + + // 重写 maps 缓存 + this.maps = {}; + for (var i = 0; i < this.files.length; i++) { + var file = this.files[i]; + this.maps[file.id] = file; + } + + // add, update + for (var key in this.maps) { + var newFile = this.maps[key]; + var oldFile = oldMaps[key]; + if (newFile !== oldFile) { + this.emitFile(newFile, oldFile); + } + } + + // delete + for (var _key in oldMaps) { + if (!this.maps[_key]) { + this.emitFile(undefined, oldMaps[_key]); + } + } + } + }, + + methods: { + + // 清空 + clear: function clear() { + if (this.files.length) { + var files = this.files; + this.files = []; + + // 定位 + this.maps = {}; + + // 事件 + this.emitInput(); + for (var i = 0; i < files.length; i++) { + this.emitFile(undefined, files[i]); + } + } + return true; + }, + + + // 选择 + get: function get(id) { + if (!id) { + return false; + } + + if ((typeof id === 'undefined' ? 'undefined' : _typeof(id)) === 'object') { + return this.maps[id.id] || false; + } + + return this.maps[id] || false; + }, + + + // 添加 + add: function add(_files) { + var index = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this.addIndex; + + var files = _files; + var isArray = files instanceof Array; + + // 不是数组整理成数组 + if (!isArray) { + files = [files]; + } + + // 遍历规范对象 + var addFiles = []; + for (var i = 0; i < files.length; i++) { + var file = files[i]; + if (this.features.html5 && file instanceof Blob) { + file = { + file: file, + size: file.size, + name: file.webkitRelativePath || file.relativePath || file.name || 'unknown', + type: file.type + }; + } + var fileObject = false; + if (file.fileObject === false) ; else if (file.fileObject) { + fileObject = true; + } else if (typeof Element !== 'undefined' && file.el instanceof Element) { + fileObject = true; + } else if (typeof Blob !== 'undefined' && file.file instanceof Blob) { + fileObject = true; + } + if (fileObject) { + file = _extends({ + fileObject: true, + size: -1, + name: 'Filename', + type: '', + active: false, + error: '', + success: false, + putAction: this.putAction, + postAction: this.postAction, + timeout: this.timeout + }, file, { + response: {}, + + progress: '0.00', // 只读 + speed: 0 // 只读 + // xhr: false, // 只读 + // iframe: false, // 只读 + }); + + file.data = _extends({}, this.data, file.data ? file.data : {}); + + file.headers = _extends({}, this.headers, file.headers ? file.headers : {}); + } + + // 必须包含 id + if (!file.id) { + file.id = Math.random().toString(36).substr(2); + } + + if (this.emitFilter(file, undefined)) { + continue; + } + + // 最大数量限制 + if (this.maximum > 1 && addFiles.length + this.files.length >= this.maximum) { + break; + } + + addFiles.push(file); + + // 最大数量限制 + if (this.maximum === 1) { + break; + } + } + + // 没有文件 + if (!addFiles.length) { + return false; + } + + // 如果是 1 清空 + if (this.maximum === 1) { + this.clear(); + } + + // 添加进去 files + var newFiles = void 0; + if (index === true || index === 0) { + newFiles = addFiles.concat(this.files); + } else if (index) { + var _newFiles; + + newFiles = this.files.concat([]); + (_newFiles = newFiles).splice.apply(_newFiles, [index, 0].concat(addFiles)); + } else { + newFiles = this.files.concat(addFiles); + } + + this.files = newFiles; + + // 定位 + for (var _i = 0; _i < addFiles.length; _i++) { + var _file2 = addFiles[_i]; + this.maps[_file2.id] = _file2; + } + + // 事件 + this.emitInput(); + for (var _i2 = 0; _i2 < addFiles.length; _i2++) { + this.emitFile(addFiles[_i2], undefined); + } + + return isArray ? addFiles : addFiles[0]; + }, + + + // 添加表单文件 + addInputFile: function addInputFile(el) { + var files = []; + if (el.files) { + for (var i = 0; i < el.files.length; i++) { + var file = el.files[i]; + files.push({ + size: file.size, + name: file.webkitRelativePath || file.relativePath || file.name, + type: file.type, + file: file, + el: el + }); + } + } else { + var names = el.value.replace(/\\/g, '/').split('/'); + files.push({ + name: names[names.length - 1], + el: el + }); + } + return this.add(files); + }, + + + // 添加 DataTransfer + addDataTransfer: function addDataTransfer(dataTransfer) { + var _this = this; + + var files = []; + if (dataTransfer.items && dataTransfer.items.length) { + var items = []; + for (var i = 0; i < dataTransfer.items.length; i++) { + var item = dataTransfer.items[i]; + if (item.getAsEntry) { + item = item.getAsEntry() || item.getAsFile(); + } else if (item.webkitGetAsEntry) { + item = item.webkitGetAsEntry() || item.getAsFile(); + } else { + item = item.getAsFile(); + } + if (item) { + items.push(item); + } + } + + return new Promise(function (resolve, reject) { + var forEach = function forEach(i) { + var item = items[i]; + // 结束 文件数量大于 最大数量 + if (!item || _this.maximum > 0 && files.length >= _this.maximum) { + return resolve(_this.add(files)); + } + _this.getEntry(item).then(function (results) { + files.push.apply(files, _toConsumableArray(results)); + forEach(i + 1); + }); + }; + forEach(0); + }); + } + + if (dataTransfer.files.length) { + for (var _i3 = 0; _i3 < dataTransfer.files.length; _i3++) { + files.push(dataTransfer.files[_i3]); + if (this.maximum > 0 && files.length >= this.maximum) { + break; + } + } + return Promise.resolve(this.add(files)); + } + + return Promise.resolve([]); + }, + + + // 获得 entry + getEntry: function getEntry(entry) { + var _this2 = this; + + var path = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + + return new Promise(function (resolve, reject) { + if (entry.isFile) { + entry.file(function (file) { + resolve([{ + size: file.size, + name: path + file.name, + type: file.type, + file: file + }]); + }); + } else if (entry.isDirectory && _this2.dropDirectory) { + var files = []; + var dirReader = entry.createReader(); + var readEntries = function readEntries() { + dirReader.readEntries(function (entries) { + var forEach = function forEach(i) { + if (!entries[i] && i === 0 || _this2.maximum > 0 && files.length >= _this2.maximum) { + return resolve(files); + } + if (!entries[i]) { + return readEntries(); + } + _this2.getEntry(entries[i], path + entry.name + '/').then(function (results) { + files.push.apply(files, _toConsumableArray(results)); + forEach(i + 1); + }); + }; + forEach(0); + }); + }; + readEntries(); + } else { + resolve([]); + } + }); + }, + replace: function replace(id1, id2) { + var file1 = this.get(id1); + var file2 = this.get(id2); + if (!file1 || !file2 || file1 === file2) { + return false; + } + var files = this.files.concat([]); + var index1 = files.indexOf(file1); + var index2 = files.indexOf(file2); + if (index1 === -1 || index2 === -1) { + return false; + } + files[index1] = file2; + files[index2] = file1; + this.files = files; + this.emitInput(); + return true; + }, + + + // 移除 + remove: function remove(id) { + var file = this.get(id); + if (file) { + if (this.emitFilter(undefined, file)) { + return false; + } + var files = this.files.concat([]); + var index = files.indexOf(file); + if (index === -1) { + console.error('remove', file); + return false; + } + files.splice(index, 1); + this.files = files; + + // 定位 + delete this.maps[file.id]; + + // 事件 + this.emitInput(); + this.emitFile(undefined, file); + } + return file; + }, + + + // 更新 + update: function update(id, data) { + var file = this.get(id); + if (file) { + var newFile = _extends({}, file, data); + // 停用必须加上错误 + if (file.fileObject && file.active && !newFile.active && !newFile.error && !newFile.success) { + newFile.error = 'abort'; + } + + if (this.emitFilter(newFile, file)) { + return false; + } + + var files = this.files.concat([]); + var index = files.indexOf(file); + if (index === -1) { + console.error('update', file); + return false; + } + files.splice(index, 1, newFile); + this.files = files; + + // 删除 旧定位 写入 新定位 (已便支持修改id) + delete this.maps[file.id]; + this.maps[newFile.id] = newFile; + + // 事件 + this.emitInput(); + this.emitFile(newFile, file); + return newFile; + } + return false; + }, + + + // 预处理 事件 过滤器 + emitFilter: function emitFilter(newFile, oldFile) { + var isPrevent = false; + this.$emit('input-filter', newFile, oldFile, function () { + isPrevent = true; + return isPrevent; + }); + return isPrevent; + }, + + + // 处理后 事件 分发 + emitFile: function emitFile(newFile, oldFile) { + this.$emit('input-file', newFile, oldFile); + if (newFile && newFile.fileObject && newFile.active && (!oldFile || !oldFile.active)) { + this.uploading++; + // 激活 + this.$nextTick(function () { + var _this3 = this; + + setTimeout(function () { + _this3.upload(newFile).then(function () { + // eslint-disable-next-line + newFile = _this3.get(newFile); + if (newFile && newFile.fileObject) { + _this3.update(newFile, { + active: false, + success: !newFile.error + }); + } + }).catch(function (e) { + _this3.update(newFile, { + active: false, + success: false, + error: e.code || e.error || e.message || e + }); + }); + }, parseInt(Math.random() * 50 + 50, 10)); + }); + } else if ((!newFile || !newFile.fileObject || !newFile.active) && oldFile && oldFile.fileObject && oldFile.active) { + // 停止 + this.uploading--; + } + + // 自动延续激活 + if (this.active && (Boolean(newFile) !== Boolean(oldFile) || newFile.active !== oldFile.active)) { + this.watchActive(true); + } + }, + emitInput: function emitInput() { + this.$emit('input', this.files); + }, + + + // 上传 + upload: function upload(id) { + var file = this.get(id); + + // 被删除 + if (!file) { + return Promise.reject('not_exists'); + } + + // 不是文件对象 + if (!file.fileObject) { + return Promise.reject('file_object'); + } + + // 有错误直接响应 + if (file.error) { + return Promise.reject(file.error); + } + + // 已完成直接响应 + if (file.success) { + return Promise.resolve(file); + } + + // 后缀 + var extensions = this.extensions; + if (extensions && (extensions.length || typeof extensions.length === 'undefined')) { + if ((typeof extensions === 'undefined' ? 'undefined' : _typeof(extensions)) !== 'object' || !(extensions instanceof RegExp)) { + if (typeof extensions === 'string') { + extensions = extensions.split(',').map(function (value) { + return value.trim(); + }).filter(function (value) { + return value; + }); + } + extensions = new RegExp('\\.(' + extensions.join('|').replace(/\./g, '\\.') + ')$', 'i'); + } + if (file.name.search(extensions) === -1) { + return Promise.reject('extension'); + } + } + + // 大小 + if (this.size > 0 && file.size >= 0 && file.size > this.size) { + return Promise.reject('size'); + } + + if (this.customAction) { + return this.customAction(file, this); + } + + if (this.features.html5) { + if (this.shouldUseChunkUpload(file)) { + return this.uploadChunk(file); + } + if (file.putAction) { + return this.uploadPut(file); + } + if (file.postAction) { + return this.uploadHtml5(file); + } + } + if (file.postAction) { + return this.uploadHtml4(file); + } + return Promise.reject('No action configured'); + }, + + + /** + * Whether this file should be uploaded using chunk upload or not + * + * @param Object file + */ + shouldUseChunkUpload: function shouldUseChunkUpload(file) { + return this.chunkEnabled && !!this.chunkOptions.handler && file.size > this.chunkOptions.minSize; + }, + + + /** + * Upload a file using Chunk method + * + * @param File file + */ + uploadChunk: function uploadChunk(file) { + var HandlerClass = this.chunkOptions.handler; + file.chunk = new HandlerClass(file, this.chunkOptions); + + return file.chunk.upload(); + }, + uploadPut: function uploadPut(file) { + var querys = []; + var value = void 0; + for (var key in file.data) { + value = file.data[key]; + if (value !== null && value !== undefined) { + querys.push(encodeURIComponent(key) + '=' + encodeURIComponent(value)); + } + } + var queryString = querys.length ? (file.putAction.indexOf('?') === -1 ? '?' : '&') + querys.join('&') : ''; + var xhr = new XMLHttpRequest(); + xhr.open('PUT', file.putAction + queryString); + return this.uploadXhr(xhr, file, file.file); + }, + uploadHtml5: function uploadHtml5(file) { + var form = new window.FormData(); + var value = void 0; + for (var key in file.data) { + value = file.data[key]; + if (value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && typeof value.toString !== 'function') { + if (value instanceof File) { + form.append(key, value, value.name); + } else { + form.append(key, JSON.stringify(value)); + } + } else if (value !== null && value !== undefined) { + form.append(key, value); + } + } + form.append(this.name, file.file, file.file.filename || file.name); + var xhr = new XMLHttpRequest(); + xhr.open('POST', file.postAction); + return this.uploadXhr(xhr, file, form); + }, + uploadXhr: function uploadXhr(xhr, _file, body) { + var _this4 = this; + + var file = _file; + var speedTime = 0; + var speedLoaded = 0; + + // 进度条 + xhr.upload.onprogress = function (e) { + // 还未开始上传 已删除 未激活 + file = _this4.get(file); + if (!e.lengthComputable || !file || !file.fileObject || !file.active) { + return; + } + + // 进度 速度 每秒更新一次 + var speedTime2 = Math.round(Date.now() / 1000); + if (speedTime2 === speedTime) { + return; + } + speedTime = speedTime2; + + file = _this4.update(file, { + progress: (e.loaded / e.total * 100).toFixed(2), + speed: e.loaded - speedLoaded + }); + speedLoaded = e.loaded; + }; + + // 检查激活状态 + var interval = setInterval(function () { + file = _this4.get(file); + if (file && file.fileObject && !file.success && !file.error && file.active) { + return; + } + + if (interval) { + clearInterval(interval); + interval = false; + } + + try { + xhr.abort(); + xhr.timeout = 1; + } catch (e) {} + }, 100); + + return new Promise(function (resolve, reject) { + var complete = void 0; + var fn = function fn(e) { + // 已经处理过了 + if (complete) { + return; + } + complete = true; + if (interval) { + clearInterval(interval); + interval = false; + } + + file = _this4.get(file); + + // 不存在直接响应 + if (!file) { + return reject('not_exists'); + } + + // 不是文件对象 + if (!file.fileObject) { + return reject('file_object'); + } + + // 有错误自动响应 + if (file.error) { + return reject(file.error); + } + + // 未激活 + if (!file.active) { + return reject('abort'); + } + + // 已完成 直接相应 + if (file.success) { + return resolve(file); + } + + var data = {}; + + switch (e.type) { + case 'timeout': + case 'abort': + data.error = e.type; + break; + case 'error': + if (!xhr.status) { + data.error = 'network'; + } else if (xhr.status >= 500) { + data.error = 'server'; + } else if (xhr.status >= 400) { + data.error = 'denied'; + } + break; + default: + if (xhr.status >= 500) { + data.error = 'server'; + } else if (xhr.status >= 400) { + data.error = 'denied'; + } else { + data.progress = '100.00'; + } + } + + if (xhr.responseText) { + var contentType = xhr.getResponseHeader('Content-Type'); + if (contentType && contentType.indexOf('/json') !== -1) { + data.response = JSON.parse(xhr.responseText); + } else { + data.response = xhr.responseText; + } + } + + // 更新 + file = _this4.update(file, data); + + // 相应错误 + if (file.error) { + return reject(file.error); + } + + // 响应 + return resolve(file); + }; + + // 事件 + xhr.onload = fn; + xhr.onerror = fn; + xhr.onabort = fn; + xhr.ontimeout = fn; + + // 超时 + if (file.timeout) { + xhr.timeout = file.timeout; + } + + // headers + for (var key in file.headers) { + xhr.setRequestHeader(key, file.headers[key]); + } + + // 更新 xhr + file = _this4.update(file, { xhr: xhr }); + + // 开始上传 + xhr.send(body); + }); + }, + uploadHtml4: function uploadHtml4(_file) { + var _this5 = this; + + var file = _file; + var onKeydown = function onKeydown(e) { + if (e.keyCode === 27) { + e.preventDefault(); + } + }; + + var iframe = document.createElement('iframe'); + iframe.id = 'upload-iframe-' + file.id; + iframe.name = 'upload-iframe-' + file.id; + iframe.src = 'about:blank'; + iframe.setAttribute('style', 'width:1px;height:1px;top:-999em;position:absolute; margin-top:-999em;'); + + var form = document.createElement('form'); + + form.action = file.postAction; + + form.name = 'upload-form-' + file.id; + + form.setAttribute('method', 'POST'); + form.setAttribute('target', 'upload-iframe-' + file.id); + form.setAttribute('enctype', 'multipart/form-data'); + + var value = void 0; + var input = void 0; + for (var key in file.data) { + value = file.data[key]; + if (value && (typeof value === 'undefined' ? 'undefined' : _typeof(value)) === 'object' && typeof value.toString !== 'function') { + value = JSON.stringify(value); + } + if (value !== null && value !== undefined) { + input = document.createElement('input'); + input.type = 'hidden'; + input.name = key; + input.value = value; + form.appendChild(input); + } + } + form.appendChild(file.el); + + document.body.appendChild(iframe).appendChild(form); + + var getResponseData = function getResponseData() { + var doc = void 0; + try { + if (iframe.contentWindow) { + doc = iframe.contentWindow.document; + } + } catch (err) {} + if (!doc) { + try { + doc = iframe.contentDocument ? iframe.contentDocument : iframe.document; + } catch (err) { + doc = iframe.document; + } + } + if (doc && doc.body) { + return doc.body.innerHTML; + } + return null; + }; + + return new Promise(function (resolve, reject) { + setTimeout(function () { + file = _this5.update(file, { iframe: iframe }); + + // 不存在 + if (!file) { + return reject('not_exists'); + } + + // 定时检查 + var interval = setInterval(function () { + file = _this5.get(file); + if (file && file.fileObject && !file.success && !file.error && file.active) { + return; + } + + if (interval) { + clearInterval(interval); + interval = false; + } + + iframe.onabort({ type: file ? 'abort' : 'not_exists' }); + }, 100); + + var complete = void 0; + var fn = function fn(e) { + // 已经处理过了 + if (complete) { + return; + } + complete = true; + + if (interval) { + clearInterval(interval); + interval = false; + } + + // 关闭 esc 事件 + document.body.removeEventListener('keydown', onKeydown); + + file = _this5.get(file); + + // 不存在直接响应 + if (!file) { + return reject('not_exists'); + } + + // 不是文件对象 + if (!file.fileObject) { + return reject('file_object'); + } + + // 有错误自动响应 + if (file.error) { + return reject(file.error); + } + + // 未激活 + if (!file.active) { + return reject('abort'); + } + + // 已完成 直接相应 + if (file.success) { + return resolve(file); + } + + var response = getResponseData(); + var data = {}; + switch (e.type) { + case 'abort': + data.error = 'abort'; + break; + case 'error': + if (file.error) { + data.error = file.error; + } else if (response === null) { + data.error = 'network'; + } else { + data.error = 'denied'; + } + break; + default: + if (file.error) { + data.error = file.error; + } else if (data === null) { + data.error = 'network'; + } else { + data.progress = '100.00'; + } + } + + if (response !== null) { + if (response && response.substr(0, 1) === '{' && response.substr(response.length - 1, 1) === '}') { + try { + response = JSON.parse(response); + } catch (err) {} + } + data.response = response; + } + + // 更新 + file = _this5.update(file, data); + + if (file.error) { + return reject(file.error); + } + + // 响应 + return resolve(file); + }; + + // 添加事件 + iframe.onload = fn; + iframe.onerror = fn; + iframe.onabort = fn; + + // 禁止 esc 键 + document.body.addEventListener('keydown', onKeydown); + + // 提交 + form.submit(); + }, 50); + }).then(function (res) { + iframe.parentNode && iframe.parentNode.removeChild(iframe); + return res; + }).catch(function (res) { + iframe.parentNode && iframe.parentNode.removeChild(iframe); + return res; + }); + }, + watchActive: function watchActive(active) { + var file = void 0; + var index = 0; + while (file = this.files[index]) { + index++; + if (!file.fileObject) ; else if (active && !this.destroy) { + if (this.uploading >= this.thread || this.uploading && !this.features.html5) { + break; + } + if (!file.active && !file.error && !file.success) { + this.update(file, { active: true }); + } + } else { + if (file.active) { + this.update(file, { active: false }); + } + } + } + if (this.uploading === 0) { + this.active = false; + } + }, + watchDrop: function watchDrop(_el) { + var el = _el; + if (!this.features.drop) { + return; + } + + // 移除挂载 + if (this.dropElement) { + try { + document.removeEventListener('dragenter', this.onDragenter, false); + document.removeEventListener('dragleave', this.onDragleave, false); + document.removeEventListener('drop', this.onDocumentDrop, false); + this.dropElement.removeEventListener('dragover', this.onDragover, false); + this.dropElement.removeEventListener('drop', this.onDrop, false); + } catch (e) {} + } + + if (!el) { + el = false; + } else if (typeof el === 'string') { + el = document.querySelector(el) || this.$root.$el.querySelector(el); + } else if (el === true) { + el = this.$parent.$el; + } + + this.dropElement = el; + + if (this.dropElement) { + document.addEventListener('dragenter', this.onDragenter, false); + document.addEventListener('dragleave', this.onDragleave, false); + document.addEventListener('drop', this.onDocumentDrop, false); + this.dropElement.addEventListener('dragover', this.onDragover, false); + this.dropElement.addEventListener('drop', this.onDrop, false); + } + }, + onDragenter: function onDragenter(e) { + e.preventDefault(); + if (this.dropActive) { + return; + } + if (!e.dataTransfer) { + return; + } + var dt = e.dataTransfer; + if (dt.files && dt.files.length) { + this.dropActive = true; + } else if (!dt.types) { + this.dropActive = true; + } else if (dt.types.indexOf && dt.types.indexOf('Files') !== -1) { + this.dropActive = true; + } else if (dt.types.contains && dt.types.contains('Files')) { + this.dropActive = true; + } + }, + onDragleave: function onDragleave(e) { + e.preventDefault(); + if (!this.dropActive) { + return; + } + if (e.target.nodeName === 'HTML' || e.target === e.explicitOriginalTarget || !e.fromElement && (e.clientX <= 0 || e.clientY <= 0 || e.clientX >= window.innerWidth || e.clientY >= window.innerHeight)) { + this.dropActive = false; + } + }, + onDragover: function onDragover(e) { + e.preventDefault(); + }, + onDocumentDrop: function onDocumentDrop() { + this.dropActive = false; + }, + onDrop: function onDrop(e) { + e.preventDefault(); + this.addDataTransfer(e.dataTransfer); + } + } + }; + + /* script */ + var __vue_script__$1 = script$1; + + /* template */ + var __vue_render__$1 = function __vue_render__() { + var _vm = this;var _h = _vm.$createElement;var _c = _vm._self._c || _h;return _c('span', { class: _vm.className }, [_vm._t("default"), _vm._v(" "), _c('label', { attrs: { "for": _vm.inputId || _vm.name } }), _vm._v(" "), _c('input-file')], 2); + }; + var __vue_staticRenderFns__$1 = []; + + /* style */ + var __vue_inject_styles__$1 = function (inject) { + if (!inject) return; + inject("data-v-37fa7525_0", { source: "\n.file-uploads{overflow:hidden;position:relative;text-align:center;display:inline-block\n}\n.file-uploads.file-uploads-html4 input[type=file],.file-uploads.file-uploads-html5 label{background:#fff;opacity:0;font-size:20em;z-index:1;top:0;left:0;right:0;bottom:0;position:absolute;width:100%;height:100%\n}\n.file-uploads.file-uploads-html4 label,.file-uploads.file-uploads-html5 input[type=file]{background:rgba(255,255,255,0);overflow:hidden;position:fixed;width:1px;height:1px;z-index:-1;opacity:0\n}", map: undefined, media: undefined }); + }; + /* scoped */ + var __vue_scope_id__$1 = undefined; + /* module identifier */ + var __vue_module_identifier__$1 = undefined; + /* functional template */ + var __vue_is_functional_template__$1 = false; + /* component normalizer */ + function __vue_normalize__$1(template, style, script, scope, functional, moduleIdentifier, createInjector, createInjectorSSR) { + var component = (typeof script === 'function' ? script.options : script) || {}; + + if (!component.render) { + component.render = template.render; + component.staticRenderFns = template.staticRenderFns; + component._compiled = true; + + if (functional) component.functional = true; + } + + component._scopeId = scope; + + { + var hook = void 0; + if (style) { + hook = function hook(context) { + style.call(this, createInjector(context)); + }; + } + + if (hook !== undefined) { + if (component.functional) { + // register for functional component in vue file + var originalRender = component.render; + component.render = function renderWithStyleInjection(h, context) { + hook.call(context); + return originalRender(h, context); + }; + } else { + // inject component registration as beforeCreate hook + var existing = component.beforeCreate; + component.beforeCreate = existing ? [].concat(existing, hook) : [hook]; + } + } + } + + return component; + } + /* style inject */ + function __vue_create_injector__$1() { + var head = document.head || document.getElementsByTagName('head')[0]; + var styles = __vue_create_injector__$1.styles || (__vue_create_injector__$1.styles = {}); + var isOldIE = typeof navigator !== 'undefined' && /msie [6-9]\\b/.test(navigator.userAgent.toLowerCase()); + + return function addStyle(id, css) { + if (document.querySelector('style[data-vue-ssr-id~="' + id + '"]')) return; // SSR styles are present. + + var group = isOldIE ? css.media || 'default' : id; + var style = styles[group] || (styles[group] = { ids: [], parts: [], element: undefined }); + + if (!style.ids.includes(id)) { + var code = css.source; + var index = style.ids.length; + + style.ids.push(id); + + if (css.map) { + // https://developer.chrome.com/devtools/docs/javascript-debugging + // this makes source maps inside style tags work properly in Chrome + code += '\n/*# sourceURL=' + css.map.sources[0] + ' */'; + // http://stackoverflow.com/a/26603875 + code += '\n/*# sourceMappingURL=data:application/json;base64,' + btoa(unescape(encodeURIComponent(JSON.stringify(css.map)))) + ' */'; + } + + if (isOldIE) { + style.element = style.element || document.querySelector('style[data-group=' + group + ']'); + } + + if (!style.element) { + var el = style.element = document.createElement('style'); + el.type = 'text/css'; + + if (css.media) el.setAttribute('media', css.media); + if (isOldIE) { + el.setAttribute('data-group', group); + el.setAttribute('data-next-index', '0'); + } + + head.appendChild(el); + } + + if (isOldIE) { + index = parseInt(style.element.getAttribute('data-next-index')); + style.element.setAttribute('data-next-index', index + 1); + } + + if (style.element.styleSheet) { + style.parts.push(code); + style.element.styleSheet.cssText = style.parts.filter(Boolean).join('\n'); + } else { + var textNode = document.createTextNode(code); + var nodes = style.element.childNodes; + if (nodes[index]) style.element.removeChild(nodes[index]); + if (nodes.length) style.element.insertBefore(textNode, nodes[index]);else style.element.appendChild(textNode); + } + } + }; + } + /* style inject SSR */ + + var FileUpload = __vue_normalize__$1({ render: __vue_render__$1, staticRenderFns: __vue_staticRenderFns__$1 }, __vue_inject_styles__$1, __vue_script__$1, __vue_scope_id__$1, __vue_is_functional_template__$1, __vue_module_identifier__$1, __vue_create_injector__$1, undefined); + + var FileUpload$1 = /*#__PURE__*/Object.freeze({ + default: FileUpload + }); + + var require$$0 = ( FileUpload$1 && FileUpload ) || FileUpload$1; + + var src = require$$0; + + return src; + +}))); +//# sourceMappingURL=vue-upload-component.js.map diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/vue2-datepicker-2.4.3.min.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/vue2-datepicker-2.4.3.min.js new file mode 100644 index 000000000..aa734c2f7 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/vue2-datepicker-2.4.3.min.js @@ -0,0 +1 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.DatePicker=t():e.DatePicker=t()}(window,function(){return function(e){var t={};function n(a){if(t[a])return t[a].exports;var i=t[a]={i:a,l:!1,exports:{}};return e[a].call(i.exports,i,i.exports,n),i.l=!0,i.exports}return n.m=e,n.c=t,n.d=function(e,t,a){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:a})},n.r=function(e){Object.defineProperty(e,"__esModule",{value:!0})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=3)}([function(e,t,n){var a;!function(i){"use strict";var r={},s=/d{1,4}|M{1,4}|YY(?:YY)?|S{1,3}|Do|ZZ|([HhMsDm])\1?|[aA]|"[^"]*"|'[^']*'/g,o=/\d\d?/,l=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,u=/\[([^]*?)\]/gm,c=function(){};function d(e,t){for(var n=[],a=0,i=e.length;a3?0:(e-e%10!=10)*e%10]}};var x={D:function(e){return e.getDate()},DD:function(e){return p(e.getDate())},Do:function(e,t){return t.DoFn(e.getDate())},d:function(e){return e.getDay()},dd:function(e){return p(e.getDay())},ddd:function(e,t){return t.dayNamesShort[e.getDay()]},dddd:function(e,t){return t.dayNames[e.getDay()]},M:function(e){return e.getMonth()+1},MM:function(e){return p(e.getMonth()+1)},MMM:function(e,t){return t.monthNamesShort[e.getMonth()]},MMMM:function(e,t){return t.monthNames[e.getMonth()]},YY:function(e){return String(e.getFullYear()).substr(2)},YYYY:function(e){return p(e.getFullYear(),4)},h:function(e){return e.getHours()%12||12},hh:function(e){return p(e.getHours()%12||12)},H:function(e){return e.getHours()},HH:function(e){return p(e.getHours())},m:function(e){return e.getMinutes()},mm:function(e){return p(e.getMinutes())},s:function(e){return e.getSeconds()},ss:function(e){return p(e.getSeconds())},S:function(e){return Math.round(e.getMilliseconds()/100)},SS:function(e){return p(Math.round(e.getMilliseconds()/10),2)},SSS:function(e){return p(e.getMilliseconds(),3)},a:function(e,t){return e.getHours()<12?t.amPm[0]:t.amPm[1]},A:function(e,t){return e.getHours()<12?t.amPm[0].toUpperCase():t.amPm[1].toUpperCase()},ZZ:function(e){var t=e.getTimezoneOffset();return(t>0?"-":"+")+p(100*Math.floor(Math.abs(t)/60)+Math.abs(t)%60,4)}},y={D:[o,function(e,t){e.day=t}],Do:[new RegExp(o.source+l.source),function(e,t){e.day=parseInt(t,10)}],M:[o,function(e,t){e.month=t-1}],YY:[o,function(e,t){var n=+(""+(new Date).getFullYear()).substr(0,2);e.year=""+(t>68?n-1:n)+t}],h:[o,function(e,t){e.hour=t}],m:[o,function(e,t){e.minute=t}],s:[o,function(e,t){e.second=t}],YYYY:[/\d{4}/,function(e,t){e.year=t}],S:[/\d/,function(e,t){e.millisecond=100*t}],SS:[/\d{2}/,function(e,t){e.millisecond=10*t}],SSS:[/\d{3}/,function(e,t){e.millisecond=t}],d:[o,c],ddd:[l,c],MMM:[l,h("monthNamesShort")],MMMM:[l,h("monthNames")],a:[l,function(e,t,n){var a=t.toLowerCase();a===n.amPm[0]?e.isPm=!1:a===n.amPm[1]&&(e.isPm=!0)}],ZZ:[/([\+\-]\d\d:?\d\d|Z)/,function(e,t){"Z"===t&&(t="+00:00");var n,a=(t+"").match(/([\+\-]|\d\d)/gi);a&&(n=60*a[1]+parseInt(a[2],10),e.timezoneOffset="+"===a[0]?n:-n)}]};y.dd=y.d,y.dddd=y.ddd,y.DD=y.D,y.mm=y.m,y.hh=y.H=y.HH=y.h,y.MM=y.M,y.ss=y.s,y.A=y.a,r.masks={default:"ddd MMM DD YYYY HH:mm:ss",shortDate:"M/D/YY",mediumDate:"MMM D, YYYY",longDate:"MMMM D, YYYY",fullDate:"dddd, MMMM D, YYYY",shortTime:"HH:mm",mediumTime:"HH:mm:ss",longTime:"HH:mm:ss.SSS"},r.format=function(e,t,n){var a=n||r.i18n;if("number"==typeof e&&(e=new Date(e)),"[object Date]"!==Object.prototype.toString.call(e)||isNaN(e.getTime()))throw new Error("Invalid Date in fecha.format");var i=[];return(t=(t=(t=r.masks[t]||t||r.masks.default).replace(u,function(e,t){return i.push(t),"??"})).replace(s,function(t){return t in x?x[t](e,a):t.slice(1,t.length-1)})).replace(/\?\?/g,function(){return i.shift()})},r.parse=function(e,t,n){var a=n||r.i18n;if("string"!=typeof t)throw new Error("Invalid format in fecha.parse");if(t=r.masks[t]||t,e.length>1e3)return!1;var i=!0,o={};if(t.replace(s,function(t){if(y[t]){var n=y[t],r=e.search(n[0]);~r?e.replace(n[0],function(t){return n[1](o,t,a),e=e.substr(r+t.length),t}):i=!1}return y[t]?"":t.slice(1,t.length-1)}),!i)return!1;var l,u=new Date;return!0===o.isPm&&null!=o.hour&&12!=+o.hour?o.hour=+o.hour+12:!1===o.isPm&&12==+o.hour&&(o.hour=0),null!=o.timezoneOffset?(o.minute=+(o.minute||0)-+o.timezoneOffset,l=new Date(Date.UTC(o.year||u.getFullYear(),o.month||0,o.day||1,o.hour||0,o.minute||0,o.second||0,o.millisecond||0))):l=new Date(o.year||u.getFullYear(),o.month||0,o.day||1,o.hour||0,o.minute||0,o.second||0,o.millisecond||0),l},void 0!==e&&e.exports?e.exports=r:void 0===(a=function(){return r}.call(t,n,t,e))||(e.exports=a)}()},function(e,t){var n=/^(attrs|props|on|nativeOn|class|style|hook)$/;function a(e,t){return function(){e&&e.apply(this,arguments),t&&t.apply(this,arguments)}}e.exports=function(e){return e.reduce(function(e,t){var i,r,s,o,l;for(s in t)if(i=e[s],r=t[s],i&&n.test(s))if("class"===s&&("string"==typeof i&&(l=i,e[s]=i={},i[l]=!0),"string"==typeof r&&(l=r,t[s]=r={},r[l]=!0)),"on"===s||"nativeOn"===s||"hook"===s)for(o in r)i[o]=a(i[o],r[o]);else if(Array.isArray(i))e[s]=i.concat(r);else if(Array.isArray(r))e[s]=[i].concat(r);else for(o in r)i[o]=r[o];else e[s]=t[s];return e},{})}},function(e,t,n){"use strict";function a(e,t){for(var n=[],a={},i=0;in.parts.length&&(a.parts.length=n.parts.length)}else{var s=[];for(i=0;i=new Date(e[0]).getTime()}function u(e){var t=(e||"").split(":");return t.length>=2?{hours:parseInt(t[0],10),minutes:parseInt(t[1],10)}:null}function c(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"24",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:"a",a=e.hours,i=(a=(a="24"===t?a:a%12||12)<10?"0"+a:a)+":"+(e.minutes<10?"0"+e.minutes:e.minutes);if("12"===t){var r=e.hours>=12?"pm":"am";"A"===n&&(r=r.toUpperCase()),i=i+" "+r}return i}function d(e,t){try{return i.a.format(new Date(e),t)}catch(e){return""}}var h={zh:{days:["日","一","二","三","四","五","六"],months:["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],pickers:["未来7天","未来30天","最近7天","最近30天"],placeholder:{date:"请选择日期",dateRange:"请选择日期范围"}},en:{days:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],pickers:["next 7 days","next 30 days","previous 7 days","previous 30 days"],placeholder:{date:"Select Date",dateRange:"Select Date Range"}},ro:{days:["Lun","Mar","Mie","Joi","Vin","Sâm","Dum"],months:["Ian","Feb","Mar","Apr","Mai","Iun","Iul","Aug","Sep","Oct","Noi","Dec"],pickers:["urmatoarele 7 zile","urmatoarele 30 zile","ultimele 7 zile","ultimele 30 zile"],placeholder:{date:"Selectați Data",dateRange:"Selectați Intervalul De Date"}},fr:{days:["Dim","Lun","Mar","Mer","Jeu","Ven","Sam"],months:["Jan","Fev","Mar","Avr","Mai","Juin","Juil","Aout","Sep","Oct","Nov","Dec"],pickers:["7 jours suivants","30 jours suivants","7 jours précédents","30 jours précédents"],placeholder:{date:"Sélectionnez une date",dateRange:"Sélectionnez une période"}},es:{days:["Dom","Lun","mar","Mie","Jue","Vie","Sab"],months:["Ene","Feb","Mar","Abr","May","Jun","Jul","Ago","Sep","Oct","Nov","Dic"],pickers:["próximos 7 días","próximos 30 días","7 días anteriores","30 días anteriores"],placeholder:{date:"Seleccionar fecha",dateRange:"Seleccionar un rango de fechas"}},"pt-br":{days:["Dom","Seg","Ter","Qua","Quin","Sex","Sáb"],months:["Jan","Fev","Mar","Abr","Maio","Jun","Jul","Ago","Set","Out","Nov","Dez"],pickers:["próximos 7 dias","próximos 30 dias","7 dias anteriores"," 30 dias anteriores"],placeholder:{date:"Selecione uma data",dateRange:"Selecione um período"}},ru:{days:["Вс","Пн","Вт","Ср","Чт","Пт","Сб"],months:["Янв","Фев","Мар","Апр","Май","Июн","Июл","Авг","Сен","Окт","Ноя","Дек"],pickers:["след. 7 дней","след. 30 дней","прош. 7 дней","прош. 30 дней"],placeholder:{date:"Выберите дату",dateRange:"Выберите период"}},de:{days:["So","Mo","Di","Mi","Do","Fr","Sa"],months:["Januar","Februar","März","April","Mai","Juni","Juli","August","September","Oktober","November","Dezember"],pickers:["nächsten 7 Tage","nächsten 30 Tage","vorigen 7 Tage","vorigen 30 Tage"],placeholder:{date:"Datum auswählen",dateRange:"Zeitraum auswählen"}},it:{days:["Dom","Lun","Mar","Mer","Gio","Ven","Sab"],months:["Gen","Feb","Mar","Apr","Mag","Giu","Lug","Ago","Set","Ott","Nov","Dic"],pickers:["successivi 7 giorni","successivi 30 giorni","precedenti 7 giorni","precedenti 30 giorni"],placeholder:{date:"Seleziona una data",dateRange:"Seleziona un intervallo date"}},cs:{days:["Ned","Pon","Úte","Stř","Čtv","Pát","Sob"],months:["Led","Úno","Bře","Dub","Kvě","Čer","Čerc","Srp","Zář","Říj","Lis","Pro"],pickers:["příštích 7 dní","příštích 30 dní","předchozích 7 dní","předchozích 30 dní"],placeholder:{date:"Vyberte datum",dateRange:"Vyberte časové rozmezí"}},sl:{days:["Ned","Pon","Tor","Sre","Čet","Pet","Sob"],months:["Jan","Feb","Mar","Apr","Maj","Jun","Jul","Avg","Sep","Okt","Nov","Dec"],pickers:["naslednjih 7 dni","naslednjih 30 dni","prejšnjih 7 dni","prejšnjih 30 dni"],placeholder:{date:"Izberite datum",dateRange:"Izberite razpon med 2 datumoma"}}},p=h.zh,m={methods:{t:function(e){for(var t=this,n=t.$options.name;t&&(!n||"DatePicker"!==n);)(t=t.$parent)&&(n=t.$options.name);for(var a=t&&t.language||p,i=e.split("."),r=a,s=void 0,o=0,l=i.length;oo&&(e.scrollTop=r-e.clientHeight)}else e.scrollTop=0}var g=n(1),v=n.n(g);function x(e){if(Array.isArray(e)){for(var t=0,n=Array(e.length);t=1&&e<=7}},disabledDate:{type:Function,default:function(){return!1}}},methods:{selectDate:function(e){var t=e.year,n=e.month,a=e.day,i=new Date(t,n,a);this.disabledDate(i)||this.$emit("select",i)},getDays:function(e){var t=this.t("days"),n=parseInt(e,10);return t.concat(t).slice(n,n+7)},getDates:function(e,t,n){var a=[],i=new Date(e,t);i.setDate(0);for(var r=(i.getDay()+7-n)%7+1,s=i.getDate()-(r-1),o=0;othis.calendarMonth?i.push("next-month"):i.push("cur-month"),r===s&&i.push("today"),this.disabledDate(r)&&i.push("disabled"),o&&(r===o?i.push("actived"):l&&r<=o?i.push("inrange"):u&&r>=o&&i.push("inrange")),i},getCellTitle:function(e){var t=e.year,n=e.month,a=e.day;return d(new Date(t,n,a),this.dateFormat)}},render:function(e){var t=this,n=this.getDays(this.firstDayOfWeek).map(function(t){return e("th",[t])}),a=this.getDates(this.calendarYear,this.calendarMonth,this.firstDayOfWeek),i=Array.apply(null,{length:6}).map(function(n,i){var r=a.slice(7*i,7*i+7).map(function(n){var a={class:t.getCellClasses(n)};return e("td",v()([{class:"cell"},a,{attrs:{title:t.getCellTitle(n)},on:{click:t.selectDate.bind(t,n)}}]),[n.day])});return e("tr",[r])});return e("table",{class:"mx-panel mx-panel-date"},[e("thead",[e("tr",[n])]),e("tbody",[i])])}},PanelYear:{name:"panelYear",props:{value:null,firstYear:Number,disabledYear:Function},methods:{isDisabled:function(e){return!("function"!=typeof this.disabledYear||!this.disabledYear(e))},selectYear:function(e){this.isDisabled(e)||this.$emit("select",e)}},render:function(e){var t=this,n=10*Math.floor(this.firstYear/10),a=this.value&&new Date(this.value).getFullYear(),i=Array.apply(null,{length:10}).map(function(i,r){var s=n+r;return e("span",{class:{cell:!0,actived:a===s,disabled:t.isDisabled(s)},on:{click:t.selectYear.bind(t,s)}},[s])});return e("div",{class:"mx-panel mx-panel-year"},[i])}},PanelMonth:{name:"panelMonth",mixins:[m],props:{value:null,calendarYear:{default:(new Date).getFullYear()},disabledMonth:Function},methods:{isDisabled:function(e){return!("function"!=typeof this.disabledMonth||!this.disabledMonth(e))},selectMonth:function(e){this.isDisabled(e)||this.$emit("select",e)}},render:function(e){var t=this,n=this.t("months"),a=this.value&&new Date(this.value).getFullYear(),i=this.value&&new Date(this.value).getMonth();return n=n.map(function(n,r){return e("span",{class:{cell:!0,actived:a===t.calendarYear&&i===r,disabled:t.isDisabled(r)},on:{click:t.selectMonth.bind(t,r)}},[n])}),e("div",{class:"mx-panel mx-panel-month"},[n])}},PanelTime:{name:"panelTime",props:{timePickerOptions:{type:[Object,Function],default:function(){return null}},minuteStep:{type:Number,default:0,validator:function(e){return e>=0&&e<=60}},value:null,timeType:{type:Array,default:function(){return["24","a"]}},disabledTime:Function},computed:{currentHours:function(){return this.value?new Date(this.value).getHours():0},currentMinutes:function(){return this.value?new Date(this.value).getMinutes():0},currentSeconds:function(){return this.value?new Date(this.value).getSeconds():0}},methods:{stringifyText:function(e){return("00"+e).slice(String(e).length)},selectTime:function(e){"function"==typeof this.disabledTime&&this.disabledTime(e)||this.$emit("select",new Date(e))},pickTime:function(e){"function"==typeof this.disabledTime&&this.disabledTime(e)||this.$emit("pick",new Date(e))},getTimeSelectOptions:function(){var e=[],t=this.timePickerOptions;if(!t)return[];if("function"==typeof t)return t()||[];var n=u(t.start),a=u(t.end),i=u(t.step);if(n&&a&&i)for(var r=n.minutes+60*n.hours,s=a.minutes+60*a.hours,o=i.minutes+60*i.hours,l=Math.floor((s-r)/o),d=0;d<=l;d++){var h=r+d*o,p={hours:Math.floor(h/60),minutes:h%60};e.push({value:p,label:c.apply(void 0,[p].concat(x(this.timeType)))})}return e}},render:function(e){var t=this,n=new Date(this.value),a="function"==typeof this.disabledTime&&this.disabledTime,i=this.getTimeSelectOptions();if(Array.isArray(i)&&i.length)return i=i.map(function(i){var r=i.value.hours,s=i.value.minutes,o=new Date(n).setHours(r,s,0);return e("li",{class:{"mx-time-picker-item":!0,cell:!0,actived:r===t.currentHours&&s===t.currentMinutes,disabled:a&&a(o)},on:{click:t.pickTime.bind(t,o)}},[i.label])}),e("div",{class:"mx-panel mx-panel-time"},[e("ul",{class:"mx-time-list"},[i])]);var r=Array.apply(null,{length:24}).map(function(i,r){var s=new Date(n).setHours(r);return e("li",{class:{cell:!0,actived:r===t.currentHours,disabled:a&&a(s)},on:{click:t.selectTime.bind(t,s)}},[t.stringifyText(r)])}),s=this.minuteStep||1,o=parseInt(60/s),l=Array.apply(null,{length:o}).map(function(i,r){var o=r*s,l=new Date(n).setMinutes(o);return e("li",{class:{cell:!0,actived:o===t.currentMinutes,disabled:a&&a(l)},on:{click:t.selectTime.bind(t,l)}},[t.stringifyText(o)])}),u=Array.apply(null,{length:60}).map(function(i,r){var s=new Date(n).setSeconds(r);return e("li",{class:{cell:!0,actived:r===t.currentSeconds,disabled:a&&a(s)},on:{click:t.selectTime.bind(t,s)}},[t.stringifyText(r)])}),c=[r,l];return 0===this.minuteStep&&c.push(u),c=c.map(function(t){return e("ul",{class:"mx-time-list",style:{width:100/c.length+"%"}},[t])}),e("div",{class:"mx-panel mx-panel-time"},[c])}}},mixins:[m],props:{value:{default:null,validator:function(e){return null===e||o(e)}},startAt:null,endAt:null,visible:{type:Boolean,default:!1},type:{type:String,default:"date"},dateFormat:{type:String,default:"YYYY-MM-DD"},firstDayOfWeek:{default:7,type:Number,validator:function(e){return e>=1&&e<=7}},notBefore:{default:null,validator:function(e){return!e||o(e)}},notAfter:{default:null,validator:function(e){return!e||o(e)}},disabledDays:{type:[Array,Function],default:function(){return[]}},minuteStep:{type:Number,default:0,validator:function(e){return e>=0&&e<=60}},timePickerOptions:{type:[Object,Function],default:function(){return null}}},data:function(){var e=new Date,t=e.getFullYear();return{panel:"DATE",dates:[],calendarMonth:e.getMonth(),calendarYear:t,firstYear:10*Math.floor(t/10)}},computed:{now:{get:function(){return new Date(this.calendarYear,this.calendarMonth).getTime()},set:function(e){var t=new Date(e);this.calendarYear=t.getFullYear(),this.calendarMonth=t.getMonth()}},timeType:function(){return[/h+/.test(this.$parent.format)?"12":"24",/A/.test(this.$parent.format)?"A":"a"]},timeHeader:function(){return"time"===this.type?this.$parent.format:this.value&&d(this.value,this.dateFormat)},yearHeader:function(){return this.firstYear+" ~ "+(this.firstYear+10)},months:function(){return this.t("months")},notBeforeTime:function(){return this.getCriticalTime(this.notBefore)},notAfterTime:function(){return this.getCriticalTime(this.notAfter)}},watch:{value:{immediate:!0,handler:"updateNow"},visible:{immediate:!0,handler:"init"},panel:{immediate:!0,handler:"handelPanelChange"}},methods:{handelPanelChange:function(e){var t=this;"YEAR"===e?this.firstYear=10*Math.floor(this.calendarYear/10):"TIME"===e&&this.$nextTick(function(){for(var e=t.$el.querySelectorAll(".mx-panel-time .mx-time-list"),n=0,a=e.length;nthis.notAfterTime||t&&e>this.getCriticalTime(t)},inDisabledDays:function(e){var t=this;return Array.isArray(this.disabledDays)?this.disabledDays.some(function(n){return t.getCriticalTime(n)===e}):"function"==typeof this.disabledDays&&this.disabledDays(new Date(e))},isDisabledYear:function(e){var t=new Date(e,0).getTime(),n=new Date(e+1,0).getTime()-1;return this.inBefore(n)||this.inAfter(t)||"year"===this.type&&this.inDisabledDays(t)},isDisabledMonth:function(e){var t=new Date(this.calendarYear,e).getTime(),n=new Date(this.calendarYear,e+1).getTime()-1;return this.inBefore(n)||this.inAfter(t)||"month"===this.type&&this.inDisabledDays(t)},isDisabledDate:function(e){var t=new Date(e).getTime(),n=new Date(e).setHours(23,59,59,999);return this.inBefore(n)||this.inAfter(t)||this.inDisabledDays(t)},isDisabledTime:function(e,t,n){var a=new Date(e).getTime();return this.inBefore(a,t)||this.inAfter(a,n)||this.inDisabledDays(a)},selectDate:function(e){if("datetime"===this.type){var t=new Date(e);return s(this.value)&&t.setHours(this.value.getHours(),this.value.getMinutes(),this.value.getSeconds()),this.isDisabledTime(t)&&(t.setHours(0,0,0,0),this.notBefore&&t.getTime()0&&void 0!==arguments[0]&&arguments[0];return!(this.confirm&&!e||this.disabled)&&((this.range?!this.rangeEqual(this.value,this.currentValue):!this.dateEqual(this.value,this.currentValue))&&(this.$emit("input",this.currentValue),this.$emit("change",this.currentValue),!0))},handleValueChange:function(e){this.range?this.currentValue=l(e)?[new Date(e[0]),new Date(e[1])]:[null,null]:this.currentValue=o(e)?new Date(e):null},selectDate:function(e){this.currentValue=e,this.updateDate()&&this.closePopup()},selectStartDate:function(e){this.$set(this.currentValue,0,e),this.currentValue[1]&&this.updateDate()},selectEndDate:function(e){this.$set(this.currentValue,1,e),this.currentValue[0]&&this.updateDate()},selectTime:function(e,t){this.currentValue=e,this.updateDate()&&t&&this.closePopup()},selectStartTime:function(e){this.selectStartDate(e)},selectEndTime:function(e){this.selectEndDate(e)},showPopup:function(){this.disabled||(this.popupVisible=!0)},closePopup:function(){this.popupVisible=!1},displayPopup:function(){var e=document.documentElement.clientWidth,t=document.documentElement.clientHeight,n=this.$el.getBoundingClientRect(),a=this.$refs.calendar.getBoundingClientRect();this.position={},e-n.left a {\n color: inherit;\n text-decoration: none;\n cursor: pointer; }\n .mx-calendar-header > a:hover {\n color: #419dec; }\n .mx-icon-last-month, .mx-icon-last-year,\n .mx-icon-next-month,\n .mx-icon-next-year {\n padding: 0 6px;\n font-size: 20px;\n line-height: 30px; }\n .mx-icon-last-month, .mx-icon-last-year {\n float: left; }\n \n .mx-icon-next-month,\n .mx-icon-next-year {\n float: right; }\n\n.mx-calendar-content {\n width: 224px;\n height: 224px; }\n .mx-calendar-content .cell {\n vertical-align: middle;\n cursor: pointer; }\n .mx-calendar-content .cell:hover {\n background-color: #eaf8fe; }\n .mx-calendar-content .cell.actived {\n color: #fff;\n background-color: #1284e7; }\n .mx-calendar-content .cell.inrange {\n background-color: #eaf8fe; }\n .mx-calendar-content .cell.disabled {\n cursor: not-allowed;\n color: #ccc;\n background-color: #f3f3f3; }\n\n.mx-panel {\n width: 100%;\n height: 100%;\n text-align: center; }\n\n.mx-panel-date {\n table-layout: fixed;\n border-collapse: collapse;\n border-spacing: 0; }\n .mx-panel-date td, .mx-panel-date th {\n font-size: 12px;\n width: 32px;\n height: 32px;\n padding: 0;\n overflow: hidden;\n text-align: center; }\n .mx-panel-date td.today {\n color: #2a90e9; }\n .mx-panel-date td.last-month, .mx-panel-date td.next-month {\n color: #ddd; }\n\n.mx-panel-year {\n padding: 7px 0; }\n .mx-panel-year .cell {\n display: inline-block;\n width: 40%;\n margin: 1px 5%;\n line-height: 40px; }\n\n.mx-panel-month .cell {\n display: inline-block;\n width: 30%;\n line-height: 40px;\n margin: 8px 1.5%; }\n\n.mx-time-list {\n position: relative;\n float: left;\n margin: 0;\n padding: 0;\n list-style: none;\n width: 100%;\n height: 100%;\n border-top: 1px solid rgba(0, 0, 0, 0.05);\n border-left: 1px solid rgba(0, 0, 0, 0.05);\n overflow-y: auto;\n /* 滚动条滑块 */ }\n .mx-time-list .mx-time-picker-item {\n display: block;\n text-align: left;\n padding-left: 10px; }\n .mx-time-list:first-child {\n border-left: 0; }\n .mx-time-list .cell {\n width: 100%;\n font-size: 12px;\n height: 30px;\n line-height: 30px; }\n .mx-time-list::-webkit-scrollbar {\n width: 8px;\n height: 8px; }\n .mx-time-list::-webkit-scrollbar-thumb {\n background-color: rgba(0, 0, 0, 0.05);\n border-radius: 10px;\n -webkit-box-shadow: inset 1px 1px 0 rgba(0, 0, 0, 0.1);\n box-shadow: inset 1px 1px 0 rgba(0, 0, 0, 0.1); }\n .mx-time-list:hover::-webkit-scrollbar-thumb {\n background-color: rgba(0, 0, 0, 0.2); }\n",""])},function(e,t,n){var a=n(5);"string"==typeof a&&(a=[[e.i,a,""]]),a.locals&&(e.exports=a.locals);(0,n(2).default)("511dbeb0",a,!0,{})}])}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/Q.Uploader.file.all.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/Q.Uploader.file.all.js new file mode 100644 index 000000000..0fcf4ff6c --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/Q.Uploader.file.all.js @@ -0,0 +1,3 @@ +//devin87@qq.com +//build:2017/12/04 15:04:58 +!function(t,e){"use strict";function i(t,i){return t!==e?t:i}function n(t){return"[object Function]"===f.call(t)}function r(t){return"number"==typeof t&&t>0&&t===Math.floor(t)}function s(t,i,n){if(!t||!i)return t;for(var r in i)r!=e&&h.call(i,r)&&(n||t[r]===e)&&(t[r]=i[r]);return t}function a(t,e,i,n){for(var r=t[i||e],s=[];r;){if(1==r.nodeType){if(!n)return r;s.push(r)}r=r[e]}return n?s:null}function o(t){return t.firstElementChild||a(t,"nextSibling","firstChild",!1)}function l(t,e,i){var n=document.createElement(t);return e&&(n.className=e),i&&(n.innerHTML=i),n}function u(e){var i=e||t.event;return i.target||(i.target=i.srcElement),i}function c(t){return y.test(t)}function d(t,e,i){t=+t;for(var n=0,s="number"==typeof(e=e||1024),a=1,o=r(i)?i:s?100:e.length;t>=a&&n
        ');i.appendChild(s);var a=l(s),o=u(s);t.iframe=a,t.form=o,function(t,e){t.attachEvent?t.attachEvent("onload",e):t.addEventListener("load",e,!1)}(a,function(){if(0==t.workerIdle){var e;try{e=a.contentWindow.document.body.innerHTML}catch(t){}t.complete(void 0,I,e)}})}return t.targets.forEach(function(e){t.clickTrigger?g(e,"click",function(e){!1!==t.fire("select",e)&&(t.resetInput(),y(t.inputFile,"click"))}):g(e,"mouseover",function(e){t.target=this,t.updatePos()})}),t.clickTrigger||(g(n,"click",function(e){!1===t.fire("select",e)&&w(e)}),h(n,0),t.resetInput()),t.fire("init"),t.run("init")}},resetInput:function(){var t=this,e=t.boxInput;e.innerHTML='";var i=l(e);return g(i,"change",function(e){t.add(this),t.html5||t.resetInput()}),t.inputFile=i,t.updatePos()},updatePos:function(t){if(this.clickTrigger)return this;var e=this.getPos||p,i=this.boxInput,n=l(i),r=this.target,s=r.offsetWidth,a=r.offsetHeight,o=0==s?{left:-1e4,top:-1e4}:e(r);return i.style.width=n.style.width=s+"px",i.style.height=n.style.height=a+"px",i.style.left=o.left+"px",i.style.top=o.top+"px",t&&(i.style.zIndex=++b),this},fire:function(t,e,i){if(!i)return a(this.fns[t],this,e);var n=this.fns[t+"Async"];if(n)return a(n,this,e,i);i(a(this.fns[t],this,e))},run:function(t,e){var i=this[t];return i&&a(i,this,e),this},addTask:function(t,e){if(t||e){var n,r;e?(n=e.name||e.fileName,r=e.size||e.fileSize):(n=i(t.value,"\\").slice(1)||t.value,r=-1);var s,a=this,o=i(n,".").toLowerCase();a.disallows&&a.disallows[o]||a.allows&&!a.allows[o]?s="ext":-1!=r&&a.maxSize&&r>a.maxSize&&(s="size");var l={id:++T,name:n,ext:o,size:r,input:t,file:e,state:s?N:L};return s&&(l.limited=s,l.disabled=!0),a.fire("add",l,function(t){!1===t||l.disabled||l.limited||(l.index=a.list.length,a.list.push(l),a.map[l.id]=l,a.run("draw",l),a.auto&&a.start())}),l}},add:function(t){if("INPUT"==t.tagName){var e=t.files;if(e)for(var i=0,n=e.length;i=n||t<=0)return this;var r=e[i];return this.index++,this.upload(r)},upload:function(t){var e=this;return!t||t.state!=L||t.skip?e.start():(t.url=e.url,e.workerIdle--,e.fire("upload",t,function(i){if(!1===i)return e.complete(t,N);e.html5&&t.file?e._upload_html5_ready(t):t.input?e._upload_html4(t):e.complete(t,N)}),e)},queryState:function(t,e){var i=this,n=i.url,r=new XMLHttpRequest;return t.queryUrl=n+(-1==n.indexOf("?")?"?":"&")+"action=query&hash="+(t.hash||encodeURIComponent(t.name))+"&fileName="+encodeURIComponent(t.name),i.fire("sliceQuery",t),r.open("GET",t.queryUrl),r.onreadystatechange=function(){if(4==r.readyState){var n,s;if(r.status>=200&&r.status<400)if("ok"===(n=r.responseText)?s={ret:1}:n&&(s=c(n)),s&&"number"!=typeof s||(s={ret:0,start:s}),t.response=n,t.json=s,1==s.ret)t.queryOK=!0,i.cancel(t.id,!0).complete(t,I);else{var o=+s.start||0;o!=Math.floor(o)&&(o=0),t.sliceStart=o}a(e,i,r)}},r.onerror=function(){a(e,i,r)},r.send(null),i},_upload_html5_ready:function(t){var e=this,i=function(){t.state!=I&&(e.isSlice?e._upload_slice(t):e._upload_html5(t))},n=function(i){e.fire("hash",t,function(){t.hash&&e.isQueryState&&t.state!=I?e.queryState(t,i):i()})},r=function(i){if(e.isMd5&&v){var r=e.fns.hashProgress;v(t.file,function(e,r){t.hash=e,t.timeHash=r,n(i)},function(i){a(r,e,t,i)})}else n(i)};return e.isUploadAfterHash?r(i):(i(),r()),e},_process_params:function(t,e){this.data&&Object.forEach(this.data,e),t.data&&Object.forEach(t.data,e)},_upload_html5:function(t){var e=this,i=new XMLHttpRequest;t.xhr=i,i.upload.addEventListener("progress",function(i){e.progress(t,i.total,i.loaded)},!1),i.addEventListener("load",function(i){e.complete(t,I,i.target.responseText)},!1),i.addEventListener("error",function(){e.complete(t,M)},!1),i.addEventListener("abort",function(){e.complete(t,O)},!1);var n=new FormData;e._process_params(t,function(t,e){n.append(t,e)}),n.append("fileName",t.name),n.append(e.upName,t.blob||t.file,t.name),i.open("POST",t.url),e.fire("send",t,function(r){if(!1===r)return e.complete(t,N);i.send(n),e._afterSend(t)})},_upload_html4:function(t){var e=this,i=e.form,n=t.input;if(n._uploaded)return e.complete(t,I);n._uploaded=!0,n.name=e.upName,i.innerHTML="",i.appendChild(n),i.action=t.url,e._process_params(t,function(t,e){i.appendChild(f(''))}),e.fire("send",t,function(n){if(!1===n)return e.complete(t,N);i.submit(),e._afterSend(t)})},_afterSend:function(t){t.lastTime=t.startTime=Date.now(),t.state=k,this._lastTask=t,this.progress(t)},progress:function(t,e,i){e||(e=t.size),(!i||i<0)&&(i=0);var n=t.state||L;i>e&&(i=e),i>0&&n==L&&(t.state=n=k);n==I&&(e=i=t.size),function(t,e,i){if(e&&!(e<=0)){var n,r=Date.now();if(i>=e)return(n=r-t.startTime)?t.avgSpeed=Math.min(Math.round(1e3*e/n),e):t.speed||(t.avgSpeed=t.speed=e),t.time=n||0,void(t.endTime=r);(n=r-t.lastTime)<200||(t.speed=Math.min(Math.round(1e3*(i-t.loaded)/n),t.total),t.lastTime=r)}}(t,e,i),t.total=e,t.loaded=i,this.fire("progress",t),this.run("update",t)},_process_response:function(t,e){t.response=e,e&&"json"==this.dataType&&(t.json=c(e))},complete:function(t,e,i){return t||1!=this.workerThread||(t=this._lastTask),t&&(void 0!=e&&(t.state=e),t.state!=k&&e!=I||(t.state=I,this.progress(t,t.size,t.size)),void 0!==i&&this._process_response(t,i)),this.run("update",t).run("over",t),e==O&&this.fire("cancel",t),this.fire("complete",t),this.workerIdle++,this.started&&this.start(),this}},r.extend=function(t,e){o(r.prototype,t,e)},function(){var e=t.XMLHttpRequest;e&&(new e).upload&&t.FormData&&(x=!0);var i=document.createElement("input");i.type="file",E=!!i.files,S=x}(),o(r,{support:{html5:x,multiple:E},READY:L,PROCESSING:k,COMPLETE:I,SKIP:N,CANCEL:O,ERROR:M,UI:{},Lang:{status_ready:"准备中",status_processing:"上传中",status_complete:"已完成",status_skip:"已跳过",status_cancel:"已取消",status_error:"已失败"},getStatusText:function(t){var e=r.Lang;switch(t){case L:return e.status_ready;case k:return e.status_processing;case I:return e.status_complete;case N:return e.status_skip;case O:return e.status_cancel;case M:return e.status_error}return t}}),Q.Uploader=r}(window),function(t,e){"use strict";function i(t,e){t.className+=" "+e}function n(t,e){t&&(t.innerHTML=e||"")}var r=Q.def,s=Q.getFirst,a=Q.getLast,o=Q.getNext,l=Q.createEle,u=Q.formatSize,c=Q.event.add,d=Q.Uploader,f=d.Lang;d.UI.File={init:function(){var t=this.ops.view;t&&i(t,"ui-file "+(this.html5?"html5":"html4"))},draw:function(t){var e=this,i=e.ops,n=i.view;if(n){var o=i.button||{},u=r(f.cancel||o.cancel,"取消"),d=r(f.remove||o.remove,"删除"),h=t.name,p='
        '+h+'
        ',v=t.id,m=l("div","u-item",p);m.taskId=v,t.box=m,n.appendChild(m);var g=a(m.childNodes[1]),y=s(g),w=a(g);c(y,"click",function(){e.cancel(v)}),c(w,"click",function(){e.remove(v),n.removeChild(m)}),e.update(t)}},update:function(t){if(t&&t.box){var e=t.total||t.size,i=t.loaded,r=t.state,a=t.box.childNodes[1],l=s(a),c=o(l),f=o(c),h=s(f),p=o(f);if(n(o(p),d.getStatusText(r)),!(e<0)){var v="";if(this.html5&&void 0!=i&&i>=0){var m;if(r==d.PROCESSING){"100.0"==(m=Math.min(100*i/e,100).toFixed(1))&&(m="99.9")}else r==d.COMPLETE&&(m="100");m&&(m+="%",h.style.width=m,n(p,m)),v=''+u(i)+" / ";var g=t.avgSpeed||t.speed;n(c,u(g)+"/s")}n(l,v+=''+u(e)+"")}}},over:function(t){t&&t.box&&i(t.box,"u-over")}},d.extend(d.UI.File)}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/Q.Uploader.image.all.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/Q.Uploader.image.all.js new file mode 100644 index 000000000..cf8e81baa --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/Q.Uploader.image.all.js @@ -0,0 +1,3 @@ +//devin87@qq.com +//build:2017/12/04 15:04:59 +!function(t,e){"use strict";function i(t,i){return t!==e?t:i}function n(t){return"[object Function]"===d.call(t)}function r(t){return"number"==typeof t&&t>0&&t===Math.floor(t)}function a(t,i,n){if(!t||!i)return t;for(var r in i)r!=e&&h.call(i,r)&&(n||t[r]===e)&&(t[r]=i[r]);return t}function s(t,e,i,n){for(var r=t[i||e],a=[];r;){if(1==r.nodeType){if(!n)return r;a.push(r)}r=r[e]}return n?a:null}function o(t){return t.firstElementChild||s(t,"nextSibling","firstChild",!1)}function l(t,e,i){var n=document.createElement(t);return e&&(n.className=e),i&&(n.innerHTML=i),n}function u(e){var i=e||t.event;return i.target||(i.target=i.srcElement),i}function c(t){return w.test(t)}function f(t,e,i){t=+t;for(var n=0,a="number"==typeof(e=e||1024),s=1,o=r(i)?i:a?100:e.length;t>=s&&n
        ');i.appendChild(a);var s=l(a),o=u(a);t.iframe=s,t.form=o,function(t,e){t.attachEvent?t.attachEvent("onload",e):t.addEventListener("load",e,!1)}(s,function(){if(0==t.workerIdle){var e;try{e=s.contentWindow.document.body.innerHTML}catch(t){}t.complete(void 0,I,e)}})}return t.targets.forEach(function(e){t.clickTrigger?g(e,"click",function(e){!1!==t.fire("select",e)&&(t.resetInput(),w(t.inputFile,"click"))}):g(e,"mouseover",function(e){t.target=this,t.updatePos()})}),t.clickTrigger||(g(n,"click",function(e){!1===t.fire("select",e)&&y(e)}),h(n,0),t.resetInput()),t.fire("init"),t.run("init")}},resetInput:function(){var t=this,e=t.boxInput;e.innerHTML='";var i=l(e);return g(i,"change",function(e){t.add(this),t.html5||t.resetInput()}),t.inputFile=i,t.updatePos()},updatePos:function(t){if(this.clickTrigger)return this;var e=this.getPos||p,i=this.boxInput,n=l(i),r=this.target,a=r.offsetWidth,s=r.offsetHeight,o=0==a?{left:-1e4,top:-1e4}:e(r);return i.style.width=n.style.width=a+"px",i.style.height=n.style.height=s+"px",i.style.left=o.left+"px",i.style.top=o.top+"px",t&&(i.style.zIndex=++T),this},fire:function(t,e,i){if(!i)return s(this.fns[t],this,e);var n=this.fns[t+"Async"];if(n)return s(n,this,e,i);i(s(this.fns[t],this,e))},run:function(t,e){var i=this[t];return i&&s(i,this,e),this},addTask:function(t,e){if(t||e){var n,r;e?(n=e.name||e.fileName,r=e.size||e.fileSize):(n=i(t.value,"\\").slice(1)||t.value,r=-1);var a,s=this,o=i(n,".").toLowerCase();s.disallows&&s.disallows[o]||s.allows&&!s.allows[o]?a="ext":-1!=r&&s.maxSize&&r>s.maxSize&&(a="size");var l={id:++_,name:n,ext:o,size:r,input:t,file:e,state:a?M:L};return a&&(l.limited=a,l.disabled=!0),s.fire("add",l,function(t){!1===t||l.disabled||l.limited||(l.index=s.list.length,s.list.push(l),s.map[l.id]=l,s.run("draw",l),s.auto&&s.start())}),l}},add:function(t){if("INPUT"==t.tagName){var e=t.files;if(e)for(var i=0,n=e.length;i=n||t<=0)return this;var r=e[i];return this.index++,this.upload(r)},upload:function(t){var e=this;return!t||t.state!=L||t.skip?e.start():(t.url=e.url,e.workerIdle--,e.fire("upload",t,function(i){if(!1===i)return e.complete(t,M);e.html5&&t.file?e._upload_html5_ready(t):t.input?e._upload_html4(t):e.complete(t,M)}),e)},queryState:function(t,e){var i=this,n=i.url,r=new XMLHttpRequest;return t.queryUrl=n+(-1==n.indexOf("?")?"?":"&")+"action=query&hash="+(t.hash||encodeURIComponent(t.name))+"&fileName="+encodeURIComponent(t.name),i.fire("sliceQuery",t),r.open("GET",t.queryUrl),r.onreadystatechange=function(){if(4==r.readyState){var n,a;if(r.status>=200&&r.status<400)if("ok"===(n=r.responseText)?a={ret:1}:n&&(a=c(n)),a&&"number"!=typeof a||(a={ret:0,start:a}),t.response=n,t.json=a,1==a.ret)t.queryOK=!0,i.cancel(t.id,!0).complete(t,I);else{var o=+a.start||0;o!=Math.floor(o)&&(o=0),t.sliceStart=o}s(e,i,r)}},r.onerror=function(){s(e,i,r)},r.send(null),i},_upload_html5_ready:function(t){var e=this,i=function(){t.state!=I&&(e.isSlice?e._upload_slice(t):e._upload_html5(t))},n=function(i){e.fire("hash",t,function(){t.hash&&e.isQueryState&&t.state!=I?e.queryState(t,i):i()})},r=function(i){if(e.isMd5&&m){var r=e.fns.hashProgress;m(t.file,function(e,r){t.hash=e,t.timeHash=r,n(i)},function(i){s(r,e,t,i)})}else n(i)};return e.isUploadAfterHash?r(i):(i(),r()),e},_process_params:function(t,e){this.data&&Object.forEach(this.data,e),t.data&&Object.forEach(t.data,e)},_upload_html5:function(t){var e=this,i=new XMLHttpRequest;t.xhr=i,i.upload.addEventListener("progress",function(i){e.progress(t,i.total,i.loaded)},!1),i.addEventListener("load",function(i){e.complete(t,I,i.target.responseText)},!1),i.addEventListener("error",function(){e.complete(t,C)},!1),i.addEventListener("abort",function(){e.complete(t,O)},!1);var n=new FormData;e._process_params(t,function(t,e){n.append(t,e)}),n.append("fileName",t.name),n.append(e.upName,t.blob||t.file,t.name),i.open("POST",t.url),e.fire("send",t,function(r){if(!1===r)return e.complete(t,M);i.send(n),e._afterSend(t)})},_upload_html4:function(t){var e=this,i=e.form,n=t.input;if(n._uploaded)return e.complete(t,I);n._uploaded=!0,n.name=e.upName,i.innerHTML="",i.appendChild(n),i.action=t.url,e._process_params(t,function(t,e){i.appendChild(d(''))}),e.fire("send",t,function(n){if(!1===n)return e.complete(t,M);i.submit(),e._afterSend(t)})},_afterSend:function(t){t.lastTime=t.startTime=Date.now(),t.state=k,this._lastTask=t,this.progress(t)},progress:function(t,e,i){e||(e=t.size),(!i||i<0)&&(i=0);var n=t.state||L;i>e&&(i=e),i>0&&n==L&&(t.state=n=k);n==I&&(e=i=t.size),function(t,e,i){if(e&&!(e<=0)){var n,r=Date.now();if(i>=e)return(n=r-t.startTime)?t.avgSpeed=Math.min(Math.round(1e3*e/n),e):t.speed||(t.avgSpeed=t.speed=e),t.time=n||0,void(t.endTime=r);(n=r-t.lastTime)<200||(t.speed=Math.min(Math.round(1e3*(i-t.loaded)/n),t.total),t.lastTime=r)}}(t,e,i),t.total=e,t.loaded=i,this.fire("progress",t),this.run("update",t)},_process_response:function(t,e){t.response=e,e&&"json"==this.dataType&&(t.json=c(e))},complete:function(t,e,i){return t||1!=this.workerThread||(t=this._lastTask),t&&(void 0!=e&&(t.state=e),t.state!=k&&e!=I||(t.state=I,this.progress(t,t.size,t.size)),void 0!==i&&this._process_response(t,i)),this.run("update",t).run("over",t),e==O&&this.fire("cancel",t),this.fire("complete",t),this.workerIdle++,this.started&&this.start(),this}},r.extend=function(t,e){o(r.prototype,t,e)},function(){var e=t.XMLHttpRequest;e&&(new e).upload&&t.FormData&&(b=!0);var i=document.createElement("input");i.type="file",x=!!i.files,E=b}(),o(r,{support:{html5:b,multiple:x},READY:L,PROCESSING:k,COMPLETE:I,SKIP:M,CANCEL:O,ERROR:C,UI:{},Lang:{status_ready:"准备中",status_processing:"上传中",status_complete:"已完成",status_skip:"已跳过",status_cancel:"已取消",status_error:"已失败"},getStatusText:function(t){var e=r.Lang;switch(t){case L:return e.status_ready;case k:return e.status_processing;case I:return e.status_complete;case M:return e.status_skip;case O:return e.status_cancel;case C:return e.status_error}return t}}),Q.Uploader=r}(window),function(t,e){"use strict";function i(t,e){t.className+=" "+e}function n(i,n,r){var a=n.input,s=n.file||(a.files?a.files[0]:e);if(s)!function(e,i){var n=t.URL||t.webkitURL;if(n)return i(n.createObjectURL(e));if(t.FileReader){var r=new FileReader;r.onload=function(t){i(t.target.result)},r.readAsDataURL(e)}else e.readAsDataURL&&i(e.readAsDataURL())}(s,function(t){t&&(i.innerHTML=''),r&&r(t)});else if(a){var o=a.value;if(o&&!/^\w:\\fakepath/.test(o)||(a.select(),parent.document.body.focus(),document.selection&&(o=document.selection.createRange().text)),o){i.innerHTML='';try{u>6&&(i.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='"+o+"')")}catch(t){}}r&&r(o)}}function r(t,e,i,n){var r=new Image;r.src=t,r.onload=function(){var t=r.width,a=r.height,s=i.maxWidth,o=i.maxHeight,l=s&&t>s,u=o&&a>o;if(!(l||u))return n&&n(!1);l&&(t=s,a=Math.floor(r.height*t/r.width)),u&&(a=o,t=Math.floor(r.width*a/r.height));var c=document.createElement("canvas"),f=c.getContext("2d");c.width=t,c.height=a,f.drawImage(r,0,0,t,a),n&&n(c.toDataURL(e),e)}}var a=Q.getFirst,s=Q.getNext,o=Q.createEle,l=Q.setOpacity,u=Q.ie,c=Q.Uploader,f=t.Blob||t.WebkitBlob||t.MozBlob,d=t.WebKitBlobBuilder||t.MozBlobBuilder,h=function(){if(!t.FileReader||!t.atob||!f&&!d)return!1;var e=document.createElement("canvas");return!!e.getContext&&!!e.getContext("2d")}();c.support.imageScale=h,c.previewImage=n,c.scaleImage=r,c.UI.Image={init:function(){var t=this.ops,e=t.view;t.allows||(t.allows=".jpg,.png,.gif,.bmp,.webp,.tif,.tiff"),e&&i(e,"ui-image "+(this.html5?"html5":"html4"))},supportScale:function(t){if(!h)return!1;".jpeg"==t&&(t=".jpg");var e=(this.ops.scale||{}).types||".jpg";return!(-1==".jpg,.png,.gif,.bmp,.webp,.tif,.tiff".indexOf(t))&&("*"==e||-1!=e.indexOf(t))},previewImage:function(t,e,i){var a=this,s=e.scale||i.scale,o=s&&a.supportScale(e.ext);return o&&(e.skip=!0),n(t,e,function(t){a.fire("preview",{task:e,src:t}),t&&o&&r(t,function(t){var e=t.slice(1);return"image/"+("jpg"==e?"jpeg":e)}(e.ext),s,function(t,i){if(t){var n=function(t,e){for(var i=t.split(","),n=atob(i[1]),r=[],a=0,s=n.length;a
        '+n+"
        ",u=t.id,c=o("div","u-item",r);c.taskId=u;var f=a(c),d=s(f),h=a(d),p=s(d);l(d,.3),l(h,.5),t.box=c,t.boxProgress=h,t.boxDetail=p,i.appendChild(c),this.previewImage(f,t,e).update(t)}},update:function(t){if(t&&t.box){var i=t.total||t.size,n=t.loaded,r=t.state,a=t.boxProgress,s=t.boxDetail,o=c.getStatusText(r);if(this.html5&&n!=e&&n>=0){var l;if(r==c.PROCESSING){"100.0"==(l=Math.min(100*n/i,100).toFixed(1))&&(l="99.9")}else r==c.COMPLETE&&(l="100");l&&(o+=" "+(l+="%"),a.style.width=l)}!function(t,e){t&&(t.innerHTML=e||"")}(s,o)}},over:function(t){t&&t.box&&i(t.box,"u-over")}},c.extend(c.UI.Image)}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.Uploader.UI.File.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.Uploader.UI.File.js new file mode 100644 index 000000000..e6c9ad29a --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.Uploader.UI.File.js @@ -0,0 +1,3 @@ +//devin87@qq.com +//build:2017/08/23 11:31:56 +!function(e,i){"use strict";function s(e,i){e.className+=" "+i}function a(e,i){e&&(e.innerHTML=i||"")}var t=Q.def,d=Q.getFirst,l=Q.getLast,v=Q.getNext,c=Q.createEle,o=Q.formatSize,n=Q.event,r=n.add,u=Q.Uploader,f=u.Lang;u.UI.File={init:function(){var e=this.ops.view;e&&s(e,"ui-file "+(this.html5?"html5":"html4"))},draw:function(e){var i=this,s=i.ops,a=s.view;if(a){var v=s.button||{},o=t(f.cancel||v.cancel,"取消"),n=t(f.remove||v.remove,"删除"),u=e.name,p='
        '+u+'
        ',h=e.id,m=c("div","u-item",p);m.taskId=h,e.box=m,a.appendChild(m);var x=l(m.childNodes[1]),g=d(x),Q=l(x);r(g,"click",function(){i.cancel(h)}),r(Q,"click",function(){i.remove(h),a.removeChild(m)}),i.update(e)}},update:function(e){if(e&&e.box){var s=e.total||e.size,t=e.loaded,l=e.state,c=e.box,n=c.childNodes[1],r=d(n),f=v(r),p=v(f),h=d(p),m=v(p),x=v(m);if(a(x,u.getStatusText(l)),!(0>s)){var g="";if(this.html5&&t!=i&&t>=0){var Q;if(l==u.PROCESSING){var b=Math.min(100*t/s,100);Q=b.toFixed(1),"100.0"==Q&&(Q="99.9")}else l==u.COMPLETE&&(Q="100");Q&&(Q+="%",h.style.width=Q,a(m,Q)),g=''+o(t)+" / ";var w=e.avgSpeed||e.speed;a(f,o(w)+"/s")}g+=''+o(s)+"",a(r,g)}}},over:function(e){e&&e.box&&s(e.box,"u-over")}},u.extend(u.UI.File)}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.Uploader.UI.Image.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.Uploader.UI.Image.js new file mode 100644 index 000000000..9be82b36f --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.Uploader.UI.Image.js @@ -0,0 +1,3 @@ +//devin87@qq.com +//build:2017/08/23 11:31:57 +!function(e,t){"use strict";function i(e,t){e.className+=" "+t}function a(e,t){e&&(e.innerHTML=t||"")}function r(t,i){var a=e.URL||e.webkitURL;if(a)return i(a.createObjectURL(t));if(e.FileReader){var r=new FileReader;r.onload=function(e){i(e.target.result)},r.readAsDataURL(t)}else t.readAsDataURL&&i(t.readAsDataURL())}function n(e,i,a){var n=i.input,o=i.file||(n.files?n.files[0]:t);if(o)r(o,function(t){t&&(e.innerHTML=''),a&&a(t)});else if(n){var s=n.value;if(s&&!/^\w:\\fakepath/.test(s)||(n.select(),parent.document.body.focus(),document.selection&&(s=document.selection.createRange().text)),s){e.innerHTML='';try{g>6&&(e.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='"+s+"')")}catch(l){}}a&&a(s)}}function o(e){var t=e.slice(1);return"image/"+("jpg"==t?"jpeg":t)}function s(e,t){for(var i=e.split(","),a=atob(i[1]),r=[],n=0,o=a.length;o>n;n++)r[n]=a.charCodeAt(n);if(v)return new v([new Uint8Array(r)],{type:t});var s=new h;return s.append(r),s.getBlob(t)}function l(e,t,i,a){var r=new Image;r.src=e,r.onload=function(){var e=r.width,n=r.height,o=i.maxWidth,s=i.maxHeight,l=o&&e>o,c=s&&n>s,u=l||c;if(!u)return a&&a(!1);l&&(e=o,n=Math.floor(r.height*e/r.width)),c&&(n=s,e=Math.floor(r.width*n/r.height));var d=document.createElement("canvas"),f=d.getContext("2d");d.width=e,d.height=n,f.drawImage(r,0,0,e,n),a&&a(d.toDataURL(t),t)}}var c=Q.getFirst,u=Q.getNext,d=Q.createEle,f=Q.setOpacity,g=Q.ie,p=Q.Uploader,v=e.Blob||e.WebkitBlob||e.MozBlob,h=e.WebKitBlobBuilder||e.MozBlobBuilder,m=function(){if(!e.FileReader||!e.atob||!v&&!h)return!1;var t=document.createElement("canvas");return!!t.getContext&&!!t.getContext("2d")}(),b=".jpg,.png,.gif,.bmp,.webp,.tif,.tiff",w=".jpg";p.support.imageScale=m,p.previewImage=n,p.scaleImage=l,p.UI.Image={init:function(){var e=this.ops,t=e.view;e.allows||(e.allows=b),t&&i(t,"ui-image "+(this.html5?"html5":"html4"))},supportScale:function(e){if(!m)return!1;".jpeg"==e&&(e=".jpg");var t=(this.ops.scale||{}).types||w,i=-1!=b.indexOf(e);return i?"*"==t||-1!=t.indexOf(e):!1},previewImage:function(e,t,i){var a=this,r=t.scale||i.scale,c=r&&a.supportScale(t.ext);return c&&(t.skip=!0),n(e,t,function(e){a.fire("preview",{task:t,src:e}),e&&c&&l(e,o(t.ext),r,function(e,i){if(e){var r=s(e,i);t.blob=r,a.fire("scale",{task:t,base64:e,type:i,blob:r})}t.skip=!1,a.list.push(t),a.auto&&a.start()})}),a},draw:function(e){var t=this,i=t.ops,a=i.view;if(a){var r=e.name,n='
        '+r+"
        ",o=e.id,s=d("div","u-item",n);s.taskId=o;var l=c(s),g=u(l),p=c(g),v=u(g);f(g,.3),f(p,.5),e.box=s,e.boxProgress=p,e.boxDetail=v,a.appendChild(s),t.previewImage(l,e,i).update(e)}},update:function(e){if(e&&e.box){var i=this,r=e.total||e.size,n=e.loaded,o=e.state,s=e.boxProgress,l=e.boxDetail,c=p.getStatusText(o);if(i.html5&&n!=t&&n>=0){var u;if(o==p.PROCESSING){var d=Math.min(100*n/r,100);u=d.toFixed(1),"100.0"==u&&(u="99.9")}else o==p.COMPLETE&&(u="100");u&&(u+="%",c+=" "+u,s.style.width=u)}a(l,c)}},over:function(e){e&&e.box&&i(e.box,"u-over")}},p.extend(p.UI.Image)}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.Uploader.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.Uploader.js new file mode 100644 index 000000000..aaaeeddf8 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.Uploader.js @@ -0,0 +1,3 @@ +//devin87@qq.com +//build:2017/12/04 15:05:00 +!function(t,e){"use strict";function i(t,e){var i=t.lastIndexOf(e);return-1!=i?t.slice(i):""}function s(t){if(t){for(var e=t.split(","),i={},s=0,a=e.length;s
        ');i.appendChild(r);var n=u(r),o=l(r);t.iframe=n,t.form=o,function(t,e){t.attachEvent?t.attachEvent("onload",e):t.addEventListener("load",e,!1)}(n,function(){if(0==t.workerIdle){var e;try{e=n.contentWindow.document.body.innerHTML}catch(t){}t.complete(void 0,b,e)}})}return t.targets.forEach(function(e){t.clickTrigger?g(e,"click",function(e){!1!==t.fire("select",e)&&(t.resetInput(),_(t.inputFile,"click"))}):g(e,"mouseover",function(e){t.target=this,t.updatePos()})}),t.clickTrigger||(g(s,"click",function(e){!1===t.fire("select",e)&&y(e)}),p(s,0),t.resetInput()),t.fire("init"),t.run("init")}},resetInput:function(){var t=this,e=t.boxInput;e.innerHTML='";var i=u(e);return g(i,"change",function(e){t.add(this),t.html5||t.resetInput()}),t.inputFile=i,t.updatePos()},updatePos:function(t){if(this.clickTrigger)return this;var e=this.getPos||f,i=this.boxInput,s=u(i),a=this.target,r=a.offsetWidth,n=a.offsetHeight,o=0==r?{left:-1e4,top:-1e4}:e(a);return i.style.width=s.style.width=r+"px",i.style.height=s.style.height=n+"px",i.style.left=o.left+"px",i.style.top=o.top+"px",t&&(i.style.zIndex=++I),this},fire:function(t,e,i){if(!i)return n(this.fns[t],this,e);var s=this.fns[t+"Async"];if(s)return n(s,this,e,i);i(n(this.fns[t],this,e))},run:function(t,e){var i=this[t];return i&&n(i,this,e),this},addTask:function(t,e){if(t||e){var s,a;e?(s=e.name||e.fileName,a=e.size||e.fileSize):(s=i(t.value,"\\").slice(1)||t.value,a=-1);var r,n=this,o=i(s,".").toLowerCase();n.disallows&&n.disallows[o]||n.allows&&!n.allows[o]?r="ext":-1!=a&&n.maxSize&&a>n.maxSize&&(r="size");var u={id:++x,name:s,ext:o,size:a,input:t,file:e,state:r?z:E};return r&&(u.limited=r,u.disabled=!0),n.fire("add",u,function(t){!1===t||u.disabled||u.limited||(u.index=n.list.length,n.list.push(u),n.map[u.id]=u,n.run("draw",u),n.auto&&n.start())}),u}},add:function(t){if("INPUT"==t.tagName){var e=t.files;if(e)for(var i=0,s=e.length;i=s||t<=0)return this;var a=e[i];return this.index++,this.upload(a)},upload:function(t){var e=this;return!t||t.state!=E||t.skip?e.start():(t.url=e.url,e.workerIdle--,e.fire("upload",t,function(i){if(!1===i)return e.complete(t,z);e.html5&&t.file?e._upload_html5_ready(t):t.input?e._upload_html4(t):e.complete(t,z)}),e)},queryState:function(t,e){var i=this,s=i.url,a=new XMLHttpRequest;return t.queryUrl=s+(-1==s.indexOf("?")?"?":"&")+"action=query&hash="+(t.hash||encodeURIComponent(t.name))+"&fileName="+encodeURIComponent(t.name),i.fire("sliceQuery",t),a.open("GET",t.queryUrl),a.onreadystatechange=function(){if(4==a.readyState){var s,r;if(a.status>=200&&a.status<400)if("ok"===(s=a.responseText)?r={ret:1}:s&&(r=d(s)),r&&"number"!=typeof r||(r={ret:0,start:r}),t.response=s,t.json=r,1==r.ret)t.queryOK=!0,i.cancel(t.id,!0).complete(t,b);else{var o=+r.start||0;o!=Math.floor(o)&&(o=0),t.sliceStart=o}n(e,i,a)}},a.onerror=function(){n(e,i,a)},a.send(null),i},_upload_html5_ready:function(t){var e=this,i=function(){t.state!=b&&(e.isSlice?e._upload_slice(t):e._upload_html5(t))},s=function(i){e.fire("hash",t,function(){t.hash&&e.isQueryState&&t.state!=b?e.queryState(t,i):i()})},a=function(i){if(e.isMd5&&m){var a=e.fns.hashProgress;m(t.file,function(e,a){t.hash=e,t.timeHash=a,s(i)},function(i){n(a,e,t,i)})}else s(i)};return e.isUploadAfterHash?a(i):(i(),a()),e},_process_params:function(t,e){this.data&&Object.forEach(this.data,e),t.data&&Object.forEach(t.data,e)},_upload_html5:function(t){var e=this,i=new XMLHttpRequest;t.xhr=i,i.upload.addEventListener("progress",function(i){e.progress(t,i.total,i.loaded)},!1),i.addEventListener("load",function(i){e.complete(t,b,i.target.responseText)},!1),i.addEventListener("error",function(){e.complete(t,N)},!1),i.addEventListener("abort",function(){e.complete(t,M)},!1);var s=new FormData;e._process_params(t,function(t,e){s.append(t,e)}),s.append("fileName",t.name),s.append(e.upName,t.blob||t.file,t.name),i.open("POST",t.url),e.fire("send",t,function(a){if(!1===a)return e.complete(t,z);i.send(s),e._afterSend(t)})},_upload_html4:function(t){var e=this,i=e.form,s=t.input;if(s._uploaded)return e.complete(t,b);s._uploaded=!0,s.name=e.upName,i.innerHTML="",i.appendChild(s),i.action=t.url,e._process_params(t,function(t,e){i.appendChild(c(''))}),e.fire("send",t,function(s){if(!1===s)return e.complete(t,z);i.submit(),e._afterSend(t)})},_afterSend:function(t){t.lastTime=t.startTime=Date.now(),t.state=L,this._lastTask=t,this.progress(t)},progress:function(t,e,i){e||(e=t.size),(!i||i<0)&&(i=0);var s=t.state||E;i>e&&(i=e),i>0&&s==E&&(t.state=s=L);s==b&&(e=i=t.size),function(t,e,i){if(e&&!(e<=0)){var s,a=Date.now();if(i>=e)return(s=a-t.startTime)?t.avgSpeed=Math.min(Math.round(1e3*e/s),e):t.speed||(t.avgSpeed=t.speed=e),t.time=s||0,void(t.endTime=a);(s=a-t.lastTime)<200||(t.speed=Math.min(Math.round(1e3*(i-t.loaded)/s),t.total),t.lastTime=a)}}(t,e,i),t.total=e,t.loaded=i,this.fire("progress",t),this.run("update",t)},_process_response:function(t,e){t.response=e,e&&"json"==this.dataType&&(t.json=d(e))},complete:function(t,e,i){return t||1!=this.workerThread||(t=this._lastTask),t&&(void 0!=e&&(t.state=e),t.state!=L&&e!=b||(t.state=b,this.progress(t,t.size,t.size)),void 0!==i&&this._process_response(t,i)),this.run("update",t).run("over",t),e==M&&this.fire("cancel",t),this.fire("complete",t),this.workerIdle++,this.started&&this.start(),this}},a.extend=function(t,e){o(a.prototype,t,e)},function(){var e=t.XMLHttpRequest;e&&(new e).upload&&t.FormData&&(T=!0);var i=document.createElement("input");i.type="file",w=!!i.files,k=T}(),o(a,{support:{html5:T,multiple:w},READY:E,PROCESSING:L,COMPLETE:b,SKIP:z,CANCEL:M,ERROR:N,UI:{},Lang:{status_ready:"准备中",status_processing:"上传中",status_complete:"已完成",status_skip:"已跳过",status_cancel:"已取消",status_error:"已失败"},getStatusText:function(t){var e=a.Lang;switch(t){case E:return e.status_ready;case L:return e.status_processing;case b:return e.status_complete;case z:return e.status_skip;case M:return e.status_cancel;case N:return e.status_error}return t}}),Q.Uploader=a}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.Uploader.slice.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.Uploader.slice.js new file mode 100644 index 000000000..a263cbb1a --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.Uploader.slice.js @@ -0,0 +1,3 @@ +//devin87@qq.com +//build:2018/02/09 11:03:32 +!function(e,n){"use strict";var t=File.prototype.slice||File.prototype.mozSlice||File.prototype.webkitSlice,i=Q.Uploader;i.extend({_upload_slice:function(e){var n,o=this,a=e.blob||e.file,r=a.size,l=o.chunkSize,c=e.sliceStart||0;e.sliceCount=Math.ceil(r/l);var s=function(){c>=r||((n=c+l)>r&&(n=r),e.sliceStart=c,e.sliceEnd=n,e.sliceIndex=Math.ceil(n/l),e.sliceBlob=t.call(a,c,n),o.fire("sliceUpload",e,function(t){if(!1===t)return p();!function(t,a){var l=new XMLHttpRequest,s=e.url,p=n==r;e.xhr=l,s+=(-1==s.indexOf("?")?"?":"&")+"action=upload&hash="+(e.hash||e.name)+"&ok="+(p?"1":"0"),l.upload.addEventListener("progress",function(n){o.progress(e,r,c+n.loaded)},!1),l.addEventListener("load",function(n){p&&o.complete(e,i.COMPLETE,n.target.responseText),a()},!1),l.addEventListener("error",function(){o.complete(e,i.ERROR)},!1);var d=new FormData;p&&(o._process_params(e,function(e,n){d.append(e,n)}),d.append("fileName",e.name)),d.append(o.upName,t,e.name),l.open("POST",s),p?o.fire("send",e,function(n){if(!1===n)return o.complete(e,i.SKIP);l.send(d)}):l.send(d)}(e.sliceBlob,p)}))},p=function(){c=n,s()};s(),o._afterSend(e)}})}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.js new file mode 100644 index 000000000..92733445a --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.js @@ -0,0 +1,3 @@ +//devin87@qq.com +//build:2017/09/22 15:04:42 +!function(t,e){"use strict";function n(t,n){return t!==e?t:n}function r(t){return"[object Function]"===N.call(t)}function i(t){return"number"==typeof t&&t>0&&t===Math.floor(t)}function o(t,e){return r(t)?t.apply(e,C.call(arguments,2)):void 0}function a(t,n,r){if(!t||!n)return t;for(var i in n)i!=e&&B.call(n,i)&&(r||t[i]===e)&&(t[i]=n[i]);return t}function l(t,e){if(e!==!1&&!/^[\],:{}\s]*$/.test(t.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))throw new Error("JSON SyntaxError");try{return new Function("return "+t)()}catch(n){}}function u(t,n){1>=n&&(n*=100),t.style.opacity!=e?t.style.opacity=n/100:t.style.filter!=e&&(t.style.filter="alpha(opacity="+parseInt(n)+")")}function c(t,e){var n=0,r=0,i=t.offsetWidth,o=t.offsetHeight;do n+=t.offsetLeft,r+=t.offsetTop,t=t.offsetParent;while(t&&t!=e);return{left:n,top:r,width:i,height:o}}function f(t,e,n,r){for(var i=t[n||e],o=[];i;){if(1==i.nodeType){if(!r)return i;o.push(i)}i=i[e]}return r?o:null}function s(t){return t.previousElementSibling||f(t,"previousSibling",null,!1)}function p(t){return t.nextElementSibling||f(t,"nextSibling",null,!1)}function v(t){return t.firstElementChild||f(t,"nextSibling","firstChild",!1)}function d(t){return t.lastElementChild||f(t,"previousSibling","lastChild",!1)}function h(t){return t.children||f(t,"nextSibling","firstChild",!0)}function g(t,e,n){var r=document.createElement(t);return e&&(r.className=e),n&&(r.innerHTML=n),r}function E(t,e){var n=g("div","",t);return e?n.childNodes:v(n)}function m(e){var n=e||t.event;return n.target||(n.target=n.srcElement),n}function y(t,e,n,r){var i=function(o){n.call(t,m(o)),r&&j(t,e,i)};return H(t,e,i),r?void 0:{stop:function(){j(t,e,i)}}}function b(t,e){if(r(t[e]))t[e]();else if(t.fireEvent)t.fireEvent("on"+e);else if(t.dispatchEvent){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}}function x(t,e,n){var r=m(t);e!==!1&&(r.preventDefault?r.preventDefault():r.returnValue=!1),n!==!1&&(r.stopPropagation?r.stopPropagation():r.cancelBubble=!0)}function S(t){return F.test(t)}function O(t){if(!S(t))return!0;var n=RegExp.lastMatch.length,r=t.indexOf("/",n),i=t.slice(0,-1!=r?r:e);return i.toLowerCase()==(location.protocol+"//"+location.host).toLowerCase()}function w(t,e,n){t=+t,e=e||1024;for(var r=0,o="number"==typeof e,a=1,l=i(n)?n:o?100:e.length;t>=a&&l>r;)a*=o?e:e[r],r++;return r&&a>t&&(a/=o?e:e.last(),r--),{value:r?t/a:t,level:r}}function L(t,r){if(r=r===!0?{all:!0}:r||{},isNaN(t)||t==e||0>t){var i=r.error||"--";return r.all?{text:i}:i}var o=w(t,r.steps,r.limit),a=o.value,l=a.toFixed(n(r.digit,2));return r.trim!==!1&&-1!=l.lastIndexOf(".")&&(l=l.replace(/\.?0+$/,"")),o.text=l+(r.join||"")+(r.units||P)[o.level+(r.start||0)],r.all?o:o.text}var N=Object.prototype.toString,B=Object.prototype.hasOwnProperty,C=Array.prototype.slice;a(Object,{forEach:function(t,e,n){for(var r in t)B.call(t,r)&&e.call(n,r,t[r],t)}}),a(Array.prototype,{forEach:function(t,e){for(var n=this,r=0,i=n.length;i>r;r++)r in n&&t.call(e,n[r],r,n)}}),a(Date,{now:function(){return+new Date}});var M;(t.ActiveXObject||t.msIndexedDB)&&(M=document.documentMode||(t.XMLHttpRequest?7:6)),t.JSON||(t.JSON={}),JSON.parse||(JSON.parse=l);var H,j;document.addEventListener?(H=function(t,e,n){t.addEventListener(e,n,!1)},j=function(t,e,n){t.removeEventListener(e,n,!1)}):document.attachEvent&&(H=function(t,e,n){t.attachEvent("on"+e,n)},j=function(t,e,n){t.detachEvent("on"+e,n)});var F=/^https?:\/\//i,P=["B","KB","MB","GB","TB","PB","EB"],T={def:n,isFunc:r,isUInt:i,fire:o,extend:a,ie:M,setOpacity:u,getOffset:c,walk:f,getPrev:s,getNext:p,getFirst:v,getLast:d,getChilds:h,createEle:g,parseHTML:E,isHttpURL:S,isSameHost:O,parseLevel:w,formatSize:L};M&&(T["ie"+(6>M?6:M)]=!0),T.event={fix:m,stop:x,trigger:b,add:y},t.Q=T}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.md5File.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.md5File.js new file mode 100644 index 000000000..a8479bad7 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/Q.md5File.js @@ -0,0 +1,3 @@ +//devin87@qq.com +//build:2016/06/17 13:31:24 +!function(e,r){"use strict";function t(e,r,t){function a(){var r=p*n,t=r+n>=l?l:r+n;f.readAsArrayBuffer(i.call(e,r,t))}var l=e.size,c=Math.ceil(l/n),p=0,f=new FileReader,u=Date.now();o.reset(),f.onload=function(e){o.append(e.target.result),p++,t&&t(p/c),c>p?a():r&&r(o.end(),Date.now()-u)},f.onerror=r,a()}if(e.SparkMD5&&e.File){var i=File.prototype.slice||File.prototype.mozSlice||File.prototype.webkitSlice,o=new SparkMD5.ArrayBuffer,n=2097152;Q.md5File=t}}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/spark-md5.js b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/spark-md5.js new file mode 100644 index 000000000..ac44053a8 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/todel/web-uploader/js/spark-md5.js @@ -0,0 +1,3 @@ +//spark-md5 v2.0.2 https://github.com/satazor/js-spark-md5 +//build:2016/06/16 14:06:36 +!function(t){if("object"==typeof exports)module.exports=t();else if("function"==typeof define&&define.amd)define(t);else{var r;try{r=window}catch(n){r=self}r.SparkMD5=t()}}(function(t){"use strict";function r(t,r,n,e,f,i){return r=d(d(r,t),d(e,i)),d(r<>>32-f,n)}function n(t,n,e,f,i,h,o){return r(n&e|~n&f,t,n,i,h,o)}function e(t,n,e,f,i,h,o){return r(n&f|e&~f,t,n,i,h,o)}function f(t,n,e,f,i,h,o){return r(n^e^f,t,n,i,h,o)}function i(t,n,e,f,i,h,o){return r(e^(n|~f),t,n,i,h,o)}function h(t,r){var h=t[0],o=t[1],u=t[2],s=t[3];h=n(h,o,u,s,r[0],7,-680876936),s=n(s,h,o,u,r[1],12,-389564586),u=n(u,s,h,o,r[2],17,606105819),o=n(o,u,s,h,r[3],22,-1044525330),h=n(h,o,u,s,r[4],7,-176418897),s=n(s,h,o,u,r[5],12,1200080426),u=n(u,s,h,o,r[6],17,-1473231341),o=n(o,u,s,h,r[7],22,-45705983),h=n(h,o,u,s,r[8],7,1770035416),s=n(s,h,o,u,r[9],12,-1958414417),u=n(u,s,h,o,r[10],17,-42063),o=n(o,u,s,h,r[11],22,-1990404162),h=n(h,o,u,s,r[12],7,1804603682),s=n(s,h,o,u,r[13],12,-40341101),u=n(u,s,h,o,r[14],17,-1502002290),o=n(o,u,s,h,r[15],22,1236535329),h=e(h,o,u,s,r[1],5,-165796510),s=e(s,h,o,u,r[6],9,-1069501632),u=e(u,s,h,o,r[11],14,643717713),o=e(o,u,s,h,r[0],20,-373897302),h=e(h,o,u,s,r[5],5,-701558691),s=e(s,h,o,u,r[10],9,38016083),u=e(u,s,h,o,r[15],14,-660478335),o=e(o,u,s,h,r[4],20,-405537848),h=e(h,o,u,s,r[9],5,568446438),s=e(s,h,o,u,r[14],9,-1019803690),u=e(u,s,h,o,r[3],14,-187363961),o=e(o,u,s,h,r[8],20,1163531501),h=e(h,o,u,s,r[13],5,-1444681467),s=e(s,h,o,u,r[2],9,-51403784),u=e(u,s,h,o,r[7],14,1735328473),o=e(o,u,s,h,r[12],20,-1926607734),h=f(h,o,u,s,r[5],4,-378558),s=f(s,h,o,u,r[8],11,-2022574463),u=f(u,s,h,o,r[11],16,1839030562),o=f(o,u,s,h,r[14],23,-35309556),h=f(h,o,u,s,r[1],4,-1530992060),s=f(s,h,o,u,r[4],11,1272893353),u=f(u,s,h,o,r[7],16,-155497632),o=f(o,u,s,h,r[10],23,-1094730640),h=f(h,o,u,s,r[13],4,681279174),s=f(s,h,o,u,r[0],11,-358537222),u=f(u,s,h,o,r[3],16,-722521979),o=f(o,u,s,h,r[6],23,76029189),h=f(h,o,u,s,r[9],4,-640364487),s=f(s,h,o,u,r[12],11,-421815835),u=f(u,s,h,o,r[15],16,530742520),o=f(o,u,s,h,r[2],23,-995338651),h=i(h,o,u,s,r[0],6,-198630844),s=i(s,h,o,u,r[7],10,1126891415),u=i(u,s,h,o,r[14],15,-1416354905),o=i(o,u,s,h,r[5],21,-57434055),h=i(h,o,u,s,r[12],6,1700485571),s=i(s,h,o,u,r[3],10,-1894986606),u=i(u,s,h,o,r[10],15,-1051523),o=i(o,u,s,h,r[1],21,-2054922799),h=i(h,o,u,s,r[8],6,1873313359),s=i(s,h,o,u,r[15],10,-30611744),u=i(u,s,h,o,r[6],15,-1560198380),o=i(o,u,s,h,r[13],21,1309151649),h=i(h,o,u,s,r[4],6,-145523070),s=i(s,h,o,u,r[11],10,-1120210379),u=i(u,s,h,o,r[2],15,718787259),o=i(o,u,s,h,r[9],21,-343485551),t[0]=d(h,t[0]),t[1]=d(o,t[1]),t[2]=d(u,t[2]),t[3]=d(s,t[3])}function o(t){var r,n=[];for(r=0;64>r;r+=4)n[r>>2]=t.charCodeAt(r)+(t.charCodeAt(r+1)<<8)+(t.charCodeAt(r+2)<<16)+(t.charCodeAt(r+3)<<24);return n}function u(t){var r,n=[];for(r=0;64>r;r+=4)n[r>>2]=t[r]+(t[r+1]<<8)+(t[r+2]<<16)+(t[r+3]<<24);return n}function s(t){var r,n,e,f,i,u,s=t.length,a=[1732584193,-271733879,-1732584194,271733878];for(r=64;s>=r;r+=64)h(a,o(t.substring(r-64,r)));for(t=t.substring(r-64),n=t.length,e=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],r=0;n>r;r+=1)e[r>>2]|=t.charCodeAt(r)<<(r%4<<3);if(e[r>>2]|=128<<(r%4<<3),r>55)for(h(a,e),r=0;16>r;r+=1)e[r]=0;return f=8*s,f=f.toString(16).match(/(.*?)(.{0,8})$/),i=parseInt(f[2],16),u=parseInt(f[1],16)||0,e[14]=i,e[15]=u,h(a,e),a}function a(t){var r,n,e,f,i,o,s=t.length,a=[1732584193,-271733879,-1732584194,271733878];for(r=64;s>=r;r+=64)h(a,u(t.subarray(r-64,r)));for(t=s>r-64?t.subarray(r-64):new Uint8Array(0),n=t.length,e=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],r=0;n>r;r+=1)e[r>>2]|=t[r]<<(r%4<<3);if(e[r>>2]|=128<<(r%4<<3),r>55)for(h(a,e),r=0;16>r;r+=1)e[r]=0;return f=8*s,f=f.toString(16).match(/(.*?)(.{0,8})$/),i=parseInt(f[2],16),o=parseInt(f[1],16)||0,e[14]=i,e[15]=o,h(a,e),a}function p(t){var r,n="";for(r=0;4>r;r+=1)n+=v[t>>8*r+4&15]+v[t>>8*r&15];return n}function y(t){var r;for(r=0;rn;n+=1)i[n]=t.charCodeAt(n);return r?i:f}function b(t){return String.fromCharCode.apply(null,new Uint8Array(t))}function g(t,r,n){var e=new Uint8Array(t.byteLength+r.byteLength);return e.set(new Uint8Array(t)),e.set(new Uint8Array(r),t.byteLength),n?e:e.buffer}function _(t){var r,n=[],e=t.length;for(r=0;e-1>r;r+=2)n.push(parseInt(t.substr(r,2),16));return String.fromCharCode.apply(String,n)}function A(){this.reset()}var d=function(t,r){return t+r&4294967295},v=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];return"5d41402abc4b2a76b9719d911017c592"!==y(s("hello"))&&(d=function(t,r){var n=(65535&t)+(65535&r),e=(t>>16)+(r>>16)+(n>>16);return e<<16|65535&n}),"undefined"==typeof ArrayBuffer||ArrayBuffer.prototype.slice||!function(){function r(t,r){return t=0|t||0,0>t?Math.max(t+r,0):Math.min(t,r)}ArrayBuffer.prototype.slice=function(n,e){var f,i,h,o,u=this.byteLength,s=r(n,u),a=u;return e!==t&&(a=r(e,u)),s>a?new ArrayBuffer(0):(f=a-s,i=new ArrayBuffer(f),h=new Uint8Array(i),o=new Uint8Array(this,s,f),h.set(o),i)}}(),A.prototype.append=function(t){return this.appendBinary(c(t)),this},A.prototype.appendBinary=function(t){this._buff+=t,this._length+=t.length;var r,n=this._buff.length;for(r=64;n>=r;r+=64)h(this._hash,o(this._buff.substring(r-64,r)));return this._buff=this._buff.substring(r-64),this},A.prototype.end=function(t){var r,n,e=this._buff,f=e.length,i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(r=0;f>r;r+=1)i[r>>2]|=e.charCodeAt(r)<<(r%4<<3);return this._finish(i,f),n=y(this._hash),t&&(n=_(n)),this.reset(),n},A.prototype.reset=function(){return this._buff="",this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},A.prototype.getState=function(){return{buff:this._buff,length:this._length,hash:this._hash}},A.prototype.setState=function(t){return this._buff=t.buff,this._length=t.length,this._hash=t.hash,this},A.prototype.destroy=function(){delete this._hash,delete this._buff,delete this._length},A.prototype._finish=function(t,r){var n,e,f,i=r;if(t[i>>2]|=128<<(i%4<<3),i>55)for(h(this._hash,t),i=0;16>i;i+=1)t[i]=0;n=8*this._length,n=n.toString(16).match(/(.*?)(.{0,8})$/),e=parseInt(n[2],16),f=parseInt(n[1],16)||0,t[14]=e,t[15]=f,h(this._hash,t)},A.hash=function(t,r){return A.hashBinary(c(t),r)},A.hashBinary=function(t,r){var n=s(t),e=y(n);return r?_(e):e},A.ArrayBuffer=function(){this.reset()},A.ArrayBuffer.prototype.append=function(t){var r,n=g(this._buff.buffer,t,!0),e=n.length;for(this._length+=t.byteLength,r=64;e>=r;r+=64)h(this._hash,u(n.subarray(r-64,r)));return this._buff=e>r-64?new Uint8Array(n.buffer.slice(r-64)):new Uint8Array(0),this},A.ArrayBuffer.prototype.end=function(t){var r,n,e=this._buff,f=e.length,i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(r=0;f>r;r+=1)i[r>>2]|=e[r]<<(r%4<<3);return this._finish(i,f),n=y(this._hash),t&&(n=_(n)),this.reset(),n},A.ArrayBuffer.prototype.reset=function(){return this._buff=new Uint8Array(0),this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},A.ArrayBuffer.prototype.getState=function(){var t=A.prototype.getState.call(this);return t.buff=b(t.buff),t},A.ArrayBuffer.prototype.setState=function(t){return t.buff=l(t.buff,!0),A.prototype.setState.call(this,t)},A.ArrayBuffer.prototype.destroy=A.prototype.destroy,A.ArrayBuffer.prototype._finish=A.prototype._finish,A.ArrayBuffer.hash=function(t,r){var n=a(new Uint8Array(t)),e=y(n);return r?_(e):e},A}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/js/utils.js b/net452/SiteServer.Web/SiteServer/assets/js/utils.js new file mode 100644 index 000000000..59cd61003 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/js/utils.js @@ -0,0 +1,140 @@ +var $api = axios.create({ + baseURL: window.$apiUrl || '../api', + withCredentials: true +}); + +var swal2 = swal.mixin({ + confirmButtonClass: 'btn btn-primary', + cancelButtonClass: 'btn btn-default ml-2', + buttonsStyling: false, +}); + +if (window.Vue && window.VeeValidate) { + VeeValidate.Validator.localize('zh_CN'); + Vue.use(VeeValidate); + VeeValidate.Validator.localize({ + zh_CN: { + messages: { + required: function (name) { + return name + '不能为空' + }, + } + } + }); + VeeValidate.Validator.extend('mobile', { + getMessage: function () { + return " 请输入正确的手机号码" + }, + validate: function (value, args) { + return value.length == 11 && /^((13|14|15|16|17|18|19)[0-9]{1}\d{8})$/.test(value) + } + }); +} + +var nameUtils = { + logout: "logout.cshtml" +}; + +var utils = { + getQueryString: function (name) { + var result = location.search.match(new RegExp("[\?\&]" + name + "=([^\&]+)", "i")); + if (!result || result.length < 1) { + return ""; + } + return decodeURIComponent(decodeURIComponent(result[1])); + }, + + isInnerPage: function () { + if (window.top == self) { + window.top.location.href = '../main.cshtml?pageUrl=' + encodeURIComponent(location.href); + return false; + } + return true; + }, + + getPageAlert: function (error) { + var message = error.message; + if (error.response) { + if (error.response.status === 401) { + message = '检测到用户未登录或者登录已超时,请重新登录'; + } else if (error.response.data) { + if (error.response.data.exceptionMessage) { + message = error.response.data.exceptionMessage; + } else if (error.response.data.message) { + message = error.response.data.message; + } + } + } + + return { + type: "danger", + html: message + }; + }, + + loading: function (isLoading) { + if (isLoading) { + return layer.load(1, { + shade: [0.2, '#000'] + }); + } else { + layer.close(layer.index); + } + }, + + closeLayer: function () { + parent.layer.closeAll(); + return false; + }, + + openLayer: function (config) { + if (!config || !config.url) return false; + + if (!config.width) { + config.width = $(window).width() - 50; + } + if (!config.height) { + config.height = $(window).height() - 50; + } + + if (config.full) { + config.width = $(window).width() - 50; + config.height = $(window).height() - 50; + } + + layer.open({ + type: 2, + btn: null, + title: config.title, + area: [config.width + 'px', config.height + 'px'], + maxmin: true, + resize: true, + shadeClose: true, + content: config.url + }); + + return false; + }, + + getRedirectUrl: function (obj) { + if (typeof (obj) == 'object') { + var url = $apiUrl + '/pages/loading?siteId=' + obj.siteId; + if (obj.channelId) { + url += '&channelId=' + obj.channelId; + } + if (obj.contentId) { + url += '&contentId=' + obj.contentId; + } + if (obj.fileTemplateId) { + url += '&fileTemplateId=' + obj.fileTemplateId; + } + if (obj.specialId) { + url += '&specialId=' + obj.specialId; + } + return url; + } else if (typeof (obj) == 'string') { + return $apiUrl + '/pages/loading?redirectUrl=' + encodeURIComponent(obj); + } + return 'javascript:;'; + } +}; \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/assets/jscolor/arrow.gif b/net452/SiteServer.Web/SiteServer/assets/jscolor/arrow.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/jscolor/arrow.gif rename to net452/SiteServer.Web/SiteServer/assets/jscolor/arrow.gif diff --git a/SiteServer.Web/SiteServer/assets/jscolor/cross.gif b/net452/SiteServer.Web/SiteServer/assets/jscolor/cross.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/jscolor/cross.gif rename to net452/SiteServer.Web/SiteServer/assets/jscolor/cross.gif diff --git a/SiteServer.Web/SiteServer/assets/jscolor/demo.html b/net452/SiteServer.Web/SiteServer/assets/jscolor/demo.html similarity index 100% rename from SiteServer.Web/SiteServer/assets/jscolor/demo.html rename to net452/SiteServer.Web/SiteServer/assets/jscolor/demo.html diff --git a/SiteServer.Web/SiteServer/assets/jscolor/hs.png b/net452/SiteServer.Web/SiteServer/assets/jscolor/hs.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/jscolor/hs.png rename to net452/SiteServer.Web/SiteServer/assets/jscolor/hs.png diff --git a/SiteServer.Web/SiteServer/assets/jscolor/hv.png b/net452/SiteServer.Web/SiteServer/assets/jscolor/hv.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/jscolor/hv.png rename to net452/SiteServer.Web/SiteServer/assets/jscolor/hv.png diff --git a/SiteServer.Web/SiteServer/assets/jscolor/jscolor.js b/net452/SiteServer.Web/SiteServer/assets/jscolor/jscolor.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/jscolor/jscolor.js rename to net452/SiteServer.Web/SiteServer/assets/jscolor/jscolor.js diff --git a/SiteServer.Web/SiteServer/assets/json2/json2.js b/net452/SiteServer.Web/SiteServer/assets/json2/json2.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/json2/json2.js rename to net452/SiteServer.Web/SiteServer/assets/json2/json2.js diff --git a/SiteServer.Web/SiteServer/assets/layer/extend/layer.ext.js b/net452/SiteServer.Web/SiteServer/assets/layer/extend/layer.ext.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/layer/extend/layer.ext.js rename to net452/SiteServer.Web/SiteServer/assets/layer/extend/layer.ext.js diff --git a/SiteServer.Web/SiteServer/assets/layer/layer.min.js b/net452/SiteServer.Web/SiteServer/assets/layer/layer.min.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/layer/layer.min.js rename to net452/SiteServer.Web/SiteServer/assets/layer/layer.min.js diff --git a/SiteServer.Web/SiteServer/assets/layer/skin/default/icon_ext.png b/net452/SiteServer.Web/SiteServer/assets/layer/skin/default/icon_ext.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/layer/skin/default/icon_ext.png rename to net452/SiteServer.Web/SiteServer/assets/layer/skin/default/icon_ext.png diff --git a/SiteServer.Web/SiteServer/assets/layer/skin/default/textbg.png b/net452/SiteServer.Web/SiteServer/assets/layer/skin/default/textbg.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/layer/skin/default/textbg.png rename to net452/SiteServer.Web/SiteServer/assets/layer/skin/default/textbg.png diff --git a/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_ico0.png b/net452/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_ico0.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_ico0.png rename to net452/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_ico0.png diff --git a/net452/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading0.gif b/net452/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading0.gif new file mode 100644 index 000000000..6f3c9539a Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading0.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading1.gif b/net452/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading1.gif new file mode 100644 index 000000000..db3a483e4 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading1.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading2.gif b/net452/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading2.gif new file mode 100644 index 000000000..5bb90fd6a Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading2.gif differ diff --git a/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading3.gif b/net452/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading3.gif similarity index 100% rename from SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading3.gif rename to net452/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_loading3.gif diff --git a/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_title0.png b/net452/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_title0.png similarity index 100% rename from SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_title0.png rename to net452/SiteServer.Web/SiteServer/assets/layer/skin/default/xubox_title0.png diff --git a/SiteServer.Web/SiteServer/assets/layer/skin/layer.css b/net452/SiteServer.Web/SiteServer/assets/layer/skin/layer.css similarity index 100% rename from SiteServer.Web/SiteServer/assets/layer/skin/layer.css rename to net452/SiteServer.Web/SiteServer/assets/layer/skin/layer.css diff --git a/SiteServer.Web/SiteServer/assets/layer/skin/layer.ext.css b/net452/SiteServer.Web/SiteServer/assets/layer/skin/layer.ext.css similarity index 100% rename from SiteServer.Web/SiteServer/assets/layer/skin/layer.ext.css rename to net452/SiteServer.Web/SiteServer/assets/layer/skin/layer.ext.css diff --git a/net452/SiteServer.Web/SiteServer/assets/lib/axios-0.17.1.min.js b/net452/SiteServer.Web/SiteServer/assets/lib/axios-0.17.1.min.js new file mode 100644 index 000000000..c27e70b23 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/lib/axios-0.17.1.min.js @@ -0,0 +1,9 @@ +/* axios v0.17.1 | (c) 2017 by Matt Zabriskie */ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t():"function"==typeof define&&define.amd?define([],t):"object"==typeof exports?exports.axios=t():e.axios=t()}(this,function(){return function(e){function t(r){if(n[r])return n[r].exports;var o=n[r]={exports:{},id:r,loaded:!1};return e[r].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){e.exports=n(1)},function(e,t,n){"use strict";function r(e){var t=new s(e),n=i(s.prototype.request,t);return o.extend(n,s.prototype,t),o.extend(n,t),n}var o=n(2),i=n(3),s=n(5),u=n(6),a=r(u);a.Axios=s,a.create=function(e){return r(o.merge(u,e))},a.Cancel=n(23),a.CancelToken=n(24),a.isCancel=n(20),a.all=function(e){return Promise.all(e)},a.spread=n(25),e.exports=a,e.exports.default=a},function(e,t,n){"use strict";function r(e){return"[object Array]"===R.call(e)}function o(e){return"[object ArrayBuffer]"===R.call(e)}function i(e){return"undefined"!=typeof FormData&&e instanceof FormData}function s(e){var t;return t="undefined"!=typeof ArrayBuffer&&ArrayBuffer.isView?ArrayBuffer.isView(e):e&&e.buffer&&e.buffer instanceof ArrayBuffer}function u(e){return"string"==typeof e}function a(e){return"number"==typeof e}function c(e){return"undefined"==typeof e}function f(e){return null!==e&&"object"==typeof e}function p(e){return"[object Date]"===R.call(e)}function d(e){return"[object File]"===R.call(e)}function l(e){return"[object Blob]"===R.call(e)}function h(e){return"[object Function]"===R.call(e)}function m(e){return f(e)&&h(e.pipe)}function y(e){return"undefined"!=typeof URLSearchParams&&e instanceof URLSearchParams}function w(e){return e.replace(/^\s*/,"").replace(/\s*$/,"")}function g(){return("undefined"==typeof navigator||"ReactNative"!==navigator.product)&&("undefined"!=typeof window&&"undefined"!=typeof document)}function v(e,t){if(null!==e&&"undefined"!=typeof e)if("object"!=typeof e&&(e=[e]),r(e))for(var n=0,o=e.length;n + * @license MIT + */ +e.exports=function(e){return null!=e&&(n(e)||r(e)||!!e._isBuffer)}},function(e,t,n){"use strict";function r(e){this.defaults=e,this.interceptors={request:new s,response:new s}}var o=n(6),i=n(2),s=n(17),u=n(18);r.prototype.request=function(e){"string"==typeof e&&(e=i.merge({url:arguments[0]},arguments[1])),e=i.merge(o,this.defaults,{method:"get"},e),e.method=e.method.toLowerCase();var t=[u,void 0],n=Promise.resolve(e);for(this.interceptors.request.forEach(function(e){t.unshift(e.fulfilled,e.rejected)}),this.interceptors.response.forEach(function(e){t.push(e.fulfilled,e.rejected)});t.length;)n=n.then(t.shift(),t.shift());return n},i.forEach(["delete","get","head","options"],function(e){r.prototype[e]=function(t,n){return this.request(i.merge(n||{},{method:e,url:t}))}}),i.forEach(["post","put","patch"],function(e){r.prototype[e]=function(t,n,r){return this.request(i.merge(r||{},{method:e,url:t,data:n}))}}),e.exports=r},function(e,t,n){"use strict";function r(e,t){!i.isUndefined(e)&&i.isUndefined(e["Content-Type"])&&(e["Content-Type"]=t)}function o(){var e;return"undefined"!=typeof XMLHttpRequest?e=n(8):"undefined"!=typeof process&&(e=n(8)),e}var i=n(2),s=n(7),u={"Content-Type":"application/x-www-form-urlencoded"},a={adapter:o(),transformRequest:[function(e,t){return s(t,"Content-Type"),i.isFormData(e)||i.isArrayBuffer(e)||i.isBuffer(e)||i.isStream(e)||i.isFile(e)||i.isBlob(e)?e:i.isArrayBufferView(e)?e.buffer:i.isURLSearchParams(e)?(r(t,"application/x-www-form-urlencoded;charset=utf-8"),e.toString()):i.isObject(e)?(r(t,"application/json;charset=utf-8"),JSON.stringify(e)):e}],transformResponse:[function(e){if("string"==typeof e)try{e=JSON.parse(e)}catch(e){}return e}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,validateStatus:function(e){return e>=200&&e<300}};a.headers={common:{Accept:"application/json, text/plain, */*"}},i.forEach(["delete","get","head"],function(e){a.headers[e]={}}),i.forEach(["post","put","patch"],function(e){a.headers[e]=i.merge(u)}),e.exports=a},function(e,t,n){"use strict";var r=n(2);e.exports=function(e,t){r.forEach(e,function(n,r){r!==t&&r.toUpperCase()===t.toUpperCase()&&(e[t]=n,delete e[r])})}},function(e,t,n){"use strict";var r=n(2),o=n(9),i=n(12),s=n(13),u=n(14),a=n(10),c="undefined"!=typeof window&&window.btoa&&window.btoa.bind(window)||n(15);e.exports=function(e){return new Promise(function(t,f){var p=e.data,d=e.headers;r.isFormData(p)&&delete d["Content-Type"];var l=new XMLHttpRequest,h="onreadystatechange",m=!1;if("undefined"==typeof window||!window.XDomainRequest||"withCredentials"in l||u(e.url)||(l=new window.XDomainRequest,h="onload",m=!0,l.onprogress=function(){},l.ontimeout=function(){}),e.auth){var y=e.auth.username||"",w=e.auth.password||"";d.Authorization="Basic "+c(y+":"+w)}if(l.open(e.method.toUpperCase(),i(e.url,e.params,e.paramsSerializer),!0),l.timeout=e.timeout,l[h]=function(){if(l&&(4===l.readyState||m)&&(0!==l.status||l.responseURL&&0===l.responseURL.indexOf("file:"))){var n="getAllResponseHeaders"in l?s(l.getAllResponseHeaders()):null,r=e.responseType&&"text"!==e.responseType?l.response:l.responseText,i={data:r,status:1223===l.status?204:l.status,statusText:1223===l.status?"No Content":l.statusText,headers:n,config:e,request:l};o(t,f,i),l=null}},l.onerror=function(){f(a("Network Error",e,null,l)),l=null},l.ontimeout=function(){f(a("timeout of "+e.timeout+"ms exceeded",e,"ECONNABORTED",l)),l=null},r.isStandardBrowserEnv()){var g=n(16),v=(e.withCredentials||u(e.url))&&e.xsrfCookieName?g.read(e.xsrfCookieName):void 0;v&&(d[e.xsrfHeaderName]=v)}if("setRequestHeader"in l&&r.forEach(d,function(e,t){"undefined"==typeof p&&"content-type"===t.toLowerCase()?delete d[t]:l.setRequestHeader(t,e)}),e.withCredentials&&(l.withCredentials=!0),e.responseType)try{l.responseType=e.responseType}catch(t){if("json"!==e.responseType)throw t}"function"==typeof e.onDownloadProgress&&l.addEventListener("progress",e.onDownloadProgress),"function"==typeof e.onUploadProgress&&l.upload&&l.upload.addEventListener("progress",e.onUploadProgress),e.cancelToken&&e.cancelToken.promise.then(function(e){l&&(l.abort(),f(e),l=null)}),void 0===p&&(p=null),l.send(p)})}},function(e,t,n){"use strict";var r=n(10);e.exports=function(e,t,n){var o=n.config.validateStatus;n.status&&o&&!o(n.status)?t(r("Request failed with status code "+n.status,n.config,null,n.request,n)):e(n)}},function(e,t,n){"use strict";var r=n(11);e.exports=function(e,t,n,o,i){var s=new Error(e);return r(s,t,n,o,i)}},function(e,t){"use strict";e.exports=function(e,t,n,r,o){return e.config=t,n&&(e.code=n),e.request=r,e.response=o,e}},function(e,t,n){"use strict";function r(e){return encodeURIComponent(e).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}var o=n(2);e.exports=function(e,t,n){if(!t)return e;var i;if(n)i=n(t);else if(o.isURLSearchParams(t))i=t.toString();else{var s=[];o.forEach(t,function(e,t){null!==e&&"undefined"!=typeof e&&(o.isArray(e)&&(t+="[]"),o.isArray(e)||(e=[e]),o.forEach(e,function(e){o.isDate(e)?e=e.toISOString():o.isObject(e)&&(e=JSON.stringify(e)),s.push(r(t)+"="+r(e))}))}),i=s.join("&")}return i&&(e+=(e.indexOf("?")===-1?"?":"&")+i),e}},function(e,t,n){"use strict";var r=n(2),o=["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"];e.exports=function(e){var t,n,i,s={};return e?(r.forEach(e.split("\n"),function(e){if(i=e.indexOf(":"),t=r.trim(e.substr(0,i)).toLowerCase(),n=r.trim(e.substr(i+1)),t){if(s[t]&&o.indexOf(t)>=0)return;"set-cookie"===t?s[t]=(s[t]?s[t]:[]).concat([n]):s[t]=s[t]?s[t]+", "+n:n}}),s):s}},function(e,t,n){"use strict";var r=n(2);e.exports=r.isStandardBrowserEnv()?function(){function e(e){var t=e;return n&&(o.setAttribute("href",t),t=o.href),o.setAttribute("href",t),{href:o.href,protocol:o.protocol?o.protocol.replace(/:$/,""):"",host:o.host,search:o.search?o.search.replace(/^\?/,""):"",hash:o.hash?o.hash.replace(/^#/,""):"",hostname:o.hostname,port:o.port,pathname:"/"===o.pathname.charAt(0)?o.pathname:"/"+o.pathname}}var t,n=/(msie|trident)/i.test(navigator.userAgent),o=document.createElement("a");return t=e(window.location.href),function(n){var o=r.isString(n)?e(n):n;return o.protocol===t.protocol&&o.host===t.host}}():function(){return function(){return!0}}()},function(e,t){"use strict";function n(){this.message="String contains an invalid character"}function r(e){for(var t,r,i=String(e),s="",u=0,a=o;i.charAt(0|u)||(a="=",u%1);s+=a.charAt(63&t>>8-u%1*8)){if(r=i.charCodeAt(u+=.75),r>255)throw new n;t=t<<8|r}return s}var o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";n.prototype=new Error,n.prototype.code=5,n.prototype.name="InvalidCharacterError",e.exports=r},function(e,t,n){"use strict";var r=n(2);e.exports=r.isStandardBrowserEnv()?function(){return{write:function(e,t,n,o,i,s){var u=[];u.push(e+"="+encodeURIComponent(t)),r.isNumber(n)&&u.push("expires="+new Date(n).toGMTString()),r.isString(o)&&u.push("path="+o),r.isString(i)&&u.push("domain="+i),s===!0&&u.push("secure"),document.cookie=u.join("; ")},read:function(e){var t=document.cookie.match(new RegExp("(^|;\\s*)("+e+")=([^;]*)"));return t?decodeURIComponent(t[3]):null},remove:function(e){this.write(e,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}()},function(e,t,n){"use strict";function r(){this.handlers=[]}var o=n(2);r.prototype.use=function(e,t){return this.handlers.push({fulfilled:e,rejected:t}),this.handlers.length-1},r.prototype.eject=function(e){this.handlers[e]&&(this.handlers[e]=null)},r.prototype.forEach=function(e){o.forEach(this.handlers,function(t){null!==t&&e(t)})},e.exports=r},function(e,t,n){"use strict";function r(e){e.cancelToken&&e.cancelToken.throwIfRequested()}var o=n(2),i=n(19),s=n(20),u=n(6),a=n(21),c=n(22);e.exports=function(e){r(e),e.baseURL&&!a(e.url)&&(e.url=c(e.baseURL,e.url)),e.headers=e.headers||{},e.data=i(e.data,e.headers,e.transformRequest),e.headers=o.merge(e.headers.common||{},e.headers[e.method]||{},e.headers||{}),o.forEach(["delete","get","head","post","put","patch","common"],function(t){delete e.headers[t]});var t=e.adapter||u.adapter;return t(e).then(function(t){return r(e),t.data=i(t.data,t.headers,e.transformResponse),t},function(t){return s(t)||(r(e),t&&t.response&&(t.response.data=i(t.response.data,t.response.headers,e.transformResponse))),Promise.reject(t)})}},function(e,t,n){"use strict";var r=n(2);e.exports=function(e,t,n){return r.forEach(n,function(n){e=n(e,t)}),e}},function(e,t){"use strict";e.exports=function(e){return!(!e||!e.__CANCEL__)}},function(e,t){"use strict";e.exports=function(e){return/^([a-z][a-z\d\+\-\.]*:)?\/\//i.test(e)}},function(e,t){"use strict";e.exports=function(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}},function(e,t){"use strict";function n(e){this.message=e}n.prototype.toString=function(){return"Cancel"+(this.message?": "+this.message:"")},n.prototype.__CANCEL__=!0,e.exports=n},function(e,t,n){"use strict";function r(e){if("function"!=typeof e)throw new TypeError("executor must be a function.");var t;this.promise=new Promise(function(e){t=e});var n=this;e(function(e){n.reason||(n.reason=new o(e),t(n.reason))})}var o=n(23);r.prototype.throwIfRequested=function(){if(this.reason)throw this.reason},r.source=function(){var e,t=new r(function(t){e=t});return{token:t,cancel:e}},e.exports=r},function(e,t){"use strict";e.exports=function(e){return function(t){return e.apply(null,t)}}}])}); +//# sourceMappingURL=axios.min.map \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/lib/bootstrap.min.js b/net452/SiteServer.Web/SiteServer/assets/lib/bootstrap.min.js new file mode 100644 index 000000000..eac9842d7 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/lib/bootstrap.min.js @@ -0,0 +1,7 @@ +/*! + * Bootstrap v4.1.0 (https://getbootstrap.com/) + * Copyright 2011-2018 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports,require("jquery"),require("popper.js")):"function"==typeof define&&define.amd?define(["exports","jquery","popper.js"],e):e(t.bootstrap={},t.jQuery,t.Popper)}(this,function(t,e,c){"use strict";function i(t,e){for(var n=0;nthis._items.length-1||t<0))if(this._isSliding)P(this._element).one(Q.SLID,function(){return e.to(t)});else{if(n===t)return this.pause(),void this.cycle();var i=ndocument.documentElement.clientHeight;!this._isBodyOverflowing&&t&&(this._element.style.paddingLeft=this._scrollbarWidth+"px"),this._isBodyOverflowing&&!t&&(this._element.style.paddingRight=this._scrollbarWidth+"px")},t._resetAdjustments=function(){this._element.style.paddingLeft="",this._element.style.paddingRight=""},t._checkScrollbar=function(){var t=document.body.getBoundingClientRect();this._isBodyOverflowing=t.left+t.right
        ',trigger:"hover focus",title:"",delay:0,html:!(_e={AUTO:"auto",TOP:"top",RIGHT:"right",BOTTOM:"bottom",LEFT:"left"}),selector:!(de={animation:"boolean",template:"string",title:"(string|element|function)",trigger:"string",delay:"(number|object)",html:"boolean",selector:"(string|boolean)",placement:"(string|function)",offset:"(number|string)",container:"(string|element|boolean)",fallbackPlacement:"(string|array)",boundary:"(string|element)"}),placement:"top",offset:0,container:!1,fallbackPlacement:"flip",boundary:"scrollParent"},pe="out",ve={HIDE:"hide"+he,HIDDEN:"hidden"+he,SHOW:(me="show")+he,SHOWN:"shown"+he,INSERTED:"inserted"+he,CLICK:"click"+he,FOCUSIN:"focusin"+he,FOCUSOUT:"focusout"+he,MOUSEENTER:"mouseenter"+he,MOUSELEAVE:"mouseleave"+he},Ee="fade",ye="show",Te=".tooltip-inner",Ce=".arrow",Ie="hover",Ae="focus",De="click",be="manual",Se=function(){function i(t,e){if("undefined"==typeof c)throw new TypeError("Bootstrap tooltips require Popper.js (https://popper.js.org)");this._isEnabled=!0,this._timeout=0,this._hoverState="",this._activeTrigger={},this._popper=null,this.element=t,this.config=this._getConfig(e),this.tip=null,this._setListeners()}var t=i.prototype;return t.enable=function(){this._isEnabled=!0},t.disable=function(){this._isEnabled=!1},t.toggleEnabled=function(){this._isEnabled=!this._isEnabled},t.toggle=function(t){if(this._isEnabled)if(t){var e=this.constructor.DATA_KEY,n=oe(t.currentTarget).data(e);n||(n=new this.constructor(t.currentTarget,this._getDelegateConfig()),oe(t.currentTarget).data(e,n)),n._activeTrigger.click=!n._activeTrigger.click,n._isWithActiveTrigger()?n._enter(null,n):n._leave(null,n)}else{if(oe(this.getTipElement()).hasClass(ye))return void this._leave(null,this);this._enter(null,this)}},t.dispose=function(){clearTimeout(this._timeout),oe.removeData(this.element,this.constructor.DATA_KEY),oe(this.element).off(this.constructor.EVENT_KEY),oe(this.element).closest(".modal").off("hide.bs.modal"),this.tip&&oe(this.tip).remove(),this._isEnabled=null,this._timeout=null,this._hoverState=null,(this._activeTrigger=null)!==this._popper&&this._popper.destroy(),this._popper=null,this.element=null,this.config=null,this.tip=null},t.show=function(){var e=this;if("none"===oe(this.element).css("display"))throw new Error("Please use show on visible elements");var t=oe.Event(this.constructor.Event.SHOW);if(this.isWithContent()&&this._isEnabled){oe(this.element).trigger(t);var n=oe.contains(this.element.ownerDocument.documentElement,this.element);if(t.isDefaultPrevented()||!n)return;var i=this.getTipElement(),r=Cn.getUID(this.constructor.NAME);i.setAttribute("id",r),this.element.setAttribute("aria-describedby",r),this.setContent(),this.config.animation&&oe(i).addClass(Ee);var s="function"==typeof this.config.placement?this.config.placement.call(this,i,this.element):this.config.placement,o=this._getAttachment(s);this.addAttachmentClass(o);var a=!1===this.config.container?document.body:oe(this.config.container);oe(i).data(this.constructor.DATA_KEY,this),oe.contains(this.element.ownerDocument.documentElement,this.tip)||oe(i).appendTo(a),oe(this.element).trigger(this.constructor.Event.INSERTED),this._popper=new c(this.element,i,{placement:o,modifiers:{offset:{offset:this.config.offset},flip:{behavior:this.config.fallbackPlacement},arrow:{element:Ce},preventOverflow:{boundariesElement:this.config.boundary}},onCreate:function(t){t.originalPlacement!==t.placement&&e._handlePopperPlacementChange(t)},onUpdate:function(t){e._handlePopperPlacementChange(t)}}),oe(i).addClass(ye),"ontouchstart"in document.documentElement&&oe(document.body).children().on("mouseover",null,oe.noop);var l=function(){e.config.animation&&e._fixTransition();var t=e._hoverState;e._hoverState=null,oe(e.element).trigger(e.constructor.Event.SHOWN),t===pe&&e._leave(null,e)};if(oe(this.tip).hasClass(Ee)){var h=Cn.getTransitionDurationFromElement(this.tip);oe(this.tip).one(Cn.TRANSITION_END,l).emulateTransitionEnd(h)}else l()}},t.hide=function(t){var e=this,n=this.getTipElement(),i=oe.Event(this.constructor.Event.HIDE),r=function(){e._hoverState!==me&&n.parentNode&&n.parentNode.removeChild(n),e._cleanTipClass(),e.element.removeAttribute("aria-describedby"),oe(e.element).trigger(e.constructor.Event.HIDDEN),null!==e._popper&&e._popper.destroy(),t&&t()};if(oe(this.element).trigger(i),!i.isDefaultPrevented()){if(oe(n).removeClass(ye),"ontouchstart"in document.documentElement&&oe(document.body).children().off("mouseover",null,oe.noop),this._activeTrigger[De]=!1,this._activeTrigger[Ae]=!1,this._activeTrigger[Ie]=!1,oe(this.tip).hasClass(Ee)){var s=Cn.getTransitionDurationFromElement(n);oe(n).one(Cn.TRANSITION_END,r).emulateTransitionEnd(s)}else r();this._hoverState=""}},t.update=function(){null!==this._popper&&this._popper.scheduleUpdate()},t.isWithContent=function(){return Boolean(this.getTitle())},t.addAttachmentClass=function(t){oe(this.getTipElement()).addClass(ue+"-"+t)},t.getTipElement=function(){return this.tip=this.tip||oe(this.config.template)[0],this.tip},t.setContent=function(){var t=oe(this.getTipElement());this.setElementContent(t.find(Te),this.getTitle()),t.removeClass(Ee+" "+ye)},t.setElementContent=function(t,e){var n=this.config.html;"object"==typeof e&&(e.nodeType||e.jquery)?n?oe(e).parent().is(t)||t.empty().append(e):t.text(oe(e).text()):t[n?"html":"text"](e)},t.getTitle=function(){var t=this.element.getAttribute("data-original-title");return t||(t="function"==typeof this.config.title?this.config.title.call(this.element):this.config.title),t},t._getAttachment=function(t){return _e[t.toUpperCase()]},t._setListeners=function(){var i=this;this.config.trigger.split(" ").forEach(function(t){if("click"===t)oe(i.element).on(i.constructor.Event.CLICK,i.config.selector,function(t){return i.toggle(t)});else if(t!==be){var e=t===Ie?i.constructor.Event.MOUSEENTER:i.constructor.Event.FOCUSIN,n=t===Ie?i.constructor.Event.MOUSELEAVE:i.constructor.Event.FOCUSOUT;oe(i.element).on(e,i.config.selector,function(t){return i._enter(t)}).on(n,i.config.selector,function(t){return i._leave(t)})}oe(i.element).closest(".modal").on("hide.bs.modal",function(){return i.hide()})}),this.config.selector?this.config=h({},this.config,{trigger:"manual",selector:""}):this._fixTitle()},t._fixTitle=function(){var t=typeof this.element.getAttribute("data-original-title");(this.element.getAttribute("title")||"string"!==t)&&(this.element.setAttribute("data-original-title",this.element.getAttribute("title")||""),this.element.setAttribute("title",""))},t._enter=function(t,e){var n=this.constructor.DATA_KEY;(e=e||oe(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),oe(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusin"===t.type?Ae:Ie]=!0),oe(e.getTipElement()).hasClass(ye)||e._hoverState===me?e._hoverState=me:(clearTimeout(e._timeout),e._hoverState=me,e.config.delay&&e.config.delay.show?e._timeout=setTimeout(function(){e._hoverState===me&&e.show()},e.config.delay.show):e.show())},t._leave=function(t,e){var n=this.constructor.DATA_KEY;(e=e||oe(t.currentTarget).data(n))||(e=new this.constructor(t.currentTarget,this._getDelegateConfig()),oe(t.currentTarget).data(n,e)),t&&(e._activeTrigger["focusout"===t.type?Ae:Ie]=!1),e._isWithActiveTrigger()||(clearTimeout(e._timeout),e._hoverState=pe,e.config.delay&&e.config.delay.hide?e._timeout=setTimeout(function(){e._hoverState===pe&&e.hide()},e.config.delay.hide):e.hide())},t._isWithActiveTrigger=function(){for(var t in this._activeTrigger)if(this._activeTrigger[t])return!0;return!1},t._getConfig=function(t){return"number"==typeof(t=h({},this.constructor.Default,oe(this.element).data(),t)).delay&&(t.delay={show:t.delay,hide:t.delay}),"number"==typeof t.title&&(t.title=t.title.toString()),"number"==typeof t.content&&(t.content=t.content.toString()),Cn.typeCheckConfig(ae,t,this.constructor.DefaultType),t},t._getDelegateConfig=function(){var t={};if(this.config)for(var e in this.config)this.constructor.Default[e]!==this.config[e]&&(t[e]=this.config[e]);return t},t._cleanTipClass=function(){var t=oe(this.getTipElement()),e=t.attr("class").match(fe);null!==e&&0

        '}),He=h({},Nn.DefaultType,{content:"(string|element|function)"}),We="fade",xe=".popover-header",Ue=".popover-body",Ke={HIDE:"hide"+ke,HIDDEN:"hidden"+ke,SHOW:(Me="show")+ke,SHOWN:"shown"+ke,INSERTED:"inserted"+ke,CLICK:"click"+ke,FOCUSIN:"focusin"+ke,FOCUSOUT:"focusout"+ke,MOUSEENTER:"mouseenter"+ke,MOUSELEAVE:"mouseleave"+ke},Fe=function(t){var e,n;function i(){return t.apply(this,arguments)||this}n=t,(e=i).prototype=Object.create(n.prototype),(e.prototype.constructor=e).__proto__=n;var r=i.prototype;return r.isWithContent=function(){return this.getTitle()||this._getContent()},r.addAttachmentClass=function(t){we(this.getTipElement()).addClass(Le+"-"+t)},r.getTipElement=function(){return this.tip=this.tip||we(this.config.template)[0],this.tip},r.setContent=function(){var t=we(this.getTipElement());this.setElementContent(t.find(xe),this.getTitle());var e=this._getContent();"function"==typeof e&&(e=e.call(this.element)),this.setElementContent(t.find(Ue),e),t.removeClass(We+" "+Me)},r._getContent=function(){return this.element.getAttribute("data-content")||this.config.content},r._cleanTipClass=function(){var t=we(this.getTipElement()),e=t.attr("class").match(je);null!==e&&0=this._offsets[r]&&("undefined"==typeof this._offsets[r+1]||t)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^[\],:{}\s]*$/,E=/(?:^|:|,)(?:\s*\[)+/g,S=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,A=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,j=/^-ms-/,D=/-([\da-z])/gi,L=function(e,t){return t.toUpperCase()},H=function(e){(o.addEventListener||"load"===e.type||"complete"===o.readyState)&&(q(),b.ready())},q=function(){o.addEventListener?(o.removeEventListener("DOMContentLoaded",H,!1),e.removeEventListener("load",H,!1)):(o.detachEvent("onreadystatechange",H),e.detachEvent("onload",H))};b.fn=b.prototype={jquery:p,constructor:b,init:function(e,n,r){var i,a;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof b?n[0]:n,b.merge(this,b.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:o,!0)),C.test(i[1])&&b.isPlainObject(n))for(i in n)b.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(a=o.getElementById(i[2]),a&&a.parentNode){if(a.id!==i[2])return r.find(e);this.length=1,this[0]=a}return this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):b.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),b.makeArray(e,this))},selector:"",length:0,size:function(){return this.length},toArray:function(){return h.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=b.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return b.each(this,e,t)},ready:function(e){return b.ready.promise().done(e),this},slice:function(){return this.pushStack(h.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(b.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:d,sort:[].sort,splice:[].splice},b.fn.init.prototype=b.fn,b.extend=b.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},u=1,l=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},u=2),"object"==typeof s||b.isFunction(s)||(s={}),l===u&&(s=this,--u);l>u;u++)if(null!=(o=arguments[u]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(b.isPlainObject(r)||(n=b.isArray(r)))?(n?(n=!1,a=e&&b.isArray(e)?e:[]):a=e&&b.isPlainObject(e)?e:{},s[i]=b.extend(c,a,r)):r!==t&&(s[i]=r));return s},b.extend({noConflict:function(t){return e.$===b&&(e.$=u),t&&e.jQuery===b&&(e.jQuery=s),b},isReady:!1,readyWait:1,holdReady:function(e){e?b.readyWait++:b.ready(!0)},ready:function(e){if(e===!0?!--b.readyWait:!b.isReady){if(!o.body)return setTimeout(b.ready);b.isReady=!0,e!==!0&&--b.readyWait>0||(n.resolveWith(o,[b]),b.fn.trigger&&b(o).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===b.type(e)},isArray:Array.isArray||function(e){return"array"===b.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if(!e||"object"!==b.type(e)||e.nodeType||b.isWindow(e))return!1;try{if(e.constructor&&!y.call(e,"constructor")&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||y.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=b.buildFragment([e],t,i),i&&b(i).remove(),b.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=b.trim(n),n&&k.test(n.replace(S,"@").replace(A,"]").replace(E,"")))?Function("return "+n)():(b.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||b.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&b.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(j,"ms-").replace(D,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:v&&!v.call("\ufeff\u00a0")?function(e){return null==e?"":v.call(e)}:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?b.merge(n,"string"==typeof e?[e]:e):d.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(g)return g.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return f.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),b.isFunction(e)?(r=h.call(arguments,2),i=function(){return e.apply(n||this,r.concat(h.call(arguments)))},i.guid=e.guid=e.guid||b.guid++,i):t},access:function(e,n,r,i,o,a,s){var u=0,l=e.length,c=null==r;if("object"===b.type(r)){o=!0;for(u in r)b.access(e,n,u,r[u],!0,a,s)}else if(i!==t&&(o=!0,b.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(b(e),n)})),n))for(;l>u;u++)n(e[u],r,s?i:i.call(e[u],u,n(e[u],r)));return o?e:c?n.call(e):l?n(e[0],r):a},now:function(){return(new Date).getTime()}}),b.ready.promise=function(t){if(!n)if(n=b.Deferred(),"complete"===o.readyState)setTimeout(b.ready);else if(o.addEventListener)o.addEventListener("DOMContentLoaded",H,!1),e.addEventListener("load",H,!1);else{o.attachEvent("onreadystatechange",H),e.attachEvent("onload",H);var r=!1;try{r=null==e.frameElement&&o.documentElement}catch(i){}r&&r.doScroll&&function a(){if(!b.isReady){try{r.doScroll("left")}catch(e){return setTimeout(a,50)}q(),b.ready()}}()}return n.promise(t)},b.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=b.type(e);return b.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=b(o);var _={};function F(e){var t=_[e]={};return b.each(e.match(w)||[],function(e,n){t[n]=!0}),t}b.Callbacks=function(e){e="string"==typeof e?_[e]||F(e):b.extend({},e);var n,r,i,o,a,s,u=[],l=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=u.length,n=!0;u&&o>a;a++)if(u[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,u&&(l?l.length&&c(l.shift()):r?u=[]:p.disable())},p={add:function(){if(u){var t=u.length;(function i(t){b.each(t,function(t,n){var r=b.type(n);"function"===r?e.unique&&p.has(n)||u.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=u.length:r&&(s=t,c(r))}return this},remove:function(){return u&&b.each(arguments,function(e,t){var r;while((r=b.inArray(t,u,r))>-1)u.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?b.inArray(e,u)>-1:!(!u||!u.length)},empty:function(){return u=[],this},disable:function(){return u=l=r=t,this},disabled:function(){return!u},lock:function(){return l=t,r||p.disable(),this},locked:function(){return!l},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!u||i&&!l||(n?l.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},b.extend({Deferred:function(e){var t=[["resolve","done",b.Callbacks("once memory"),"resolved"],["reject","fail",b.Callbacks("once memory"),"rejected"],["notify","progress",b.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return b.Deferred(function(n){b.each(t,function(t,o){var a=o[0],s=b.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&b.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?b.extend(e,r):r}},i={};return r.pipe=r.then,b.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=h.call(arguments),r=n.length,i=1!==r||e&&b.isFunction(e.promise)?r:0,o=1===i?e:b.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?h.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,u,l;if(r>1)for(s=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&b.isFunction(n[t].promise)?n[t].promise().done(a(t,l,n)).fail(o.reject).progress(a(t,u,s)):--i;return i||o.resolveWith(l,n),o.promise()}}),b.support=function(){var t,n,r,a,s,u,l,c,p,f,d=o.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="
        a",n=d.getElementsByTagName("*"),r=d.getElementsByTagName("a")[0],!n||!r||!n.length)return{};s=o.createElement("select"),l=s.appendChild(o.createElement("option")),a=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={getSetAttribute:"t"!==d.className,leadingWhitespace:3===d.firstChild.nodeType,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:"/a"===r.getAttribute("href"),opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:!!a.value,optSelected:l.selected,enctype:!!o.createElement("form").enctype,html5Clone:"<:nav>"!==o.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===o.compatMode,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},a.checked=!0,t.noCloneChecked=a.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!l.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}a=o.createElement("input"),a.setAttribute("value",""),t.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),t.radioValue="t"===a.value,a.setAttribute("checked","t"),a.setAttribute("name","t"),u=o.createDocumentFragment(),u.appendChild(a),t.appendChecked=a.checked,t.checkClone=u.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;return d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip,b(function(){var n,r,a,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",u=o.getElementsByTagName("body")[0];u&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",u.appendChild(n).appendChild(d),d.innerHTML="
        t
        ",a=d.getElementsByTagName("td"),a[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===a[0].offsetHeight,a[0].style.display="",a[1].style.display="none",t.reliableHiddenOffsets=p&&0===a[0].offsetHeight,d.innerHTML="",d.style.cssText="box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;",t.boxSizing=4===d.offsetWidth,t.doesNotIncludeMarginInBodyOffset=1!==u.offsetTop,e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(o.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="
        ",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(u.style.zoom=1)),u.removeChild(n),n=d=a=r=null)}),n=s=u=l=r=a=null,t}();var O=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,B=/([A-Z])/g;function P(e,n,r,i){if(b.acceptData(e)){var o,a,s=b.expando,u="string"==typeof n,l=e.nodeType,p=l?b.cache:e,f=l?e[s]:e[s]&&s;if(f&&p[f]&&(i||p[f].data)||!u||r!==t)return f||(l?e[s]=f=c.pop()||b.guid++:f=s),p[f]||(p[f]={},l||(p[f].toJSON=b.noop)),("object"==typeof n||"function"==typeof n)&&(i?p[f]=b.extend(p[f],n):p[f].data=b.extend(p[f].data,n)),o=p[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[b.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[b.camelCase(n)])):a=o,a}}function R(e,t,n){if(b.acceptData(e)){var r,i,o,a=e.nodeType,s=a?b.cache:e,u=a?e[b.expando]:b.expando;if(s[u]){if(t&&(o=n?s[u]:s[u].data)){b.isArray(t)?t=t.concat(b.map(t,b.camelCase)):t in o?t=[t]:(t=b.camelCase(t),t=t in o?[t]:t.split(" "));for(r=0,i=t.length;i>r;r++)delete o[t[r]];if(!(n?$:b.isEmptyObject)(o))return}(n||(delete s[u].data,$(s[u])))&&(a?b.cleanData([e],!0):b.support.deleteExpando||s!=s.window?delete s[u]:s[u]=null)}}}b.extend({cache:{},expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?b.cache[e[b.expando]]:e[b.expando],!!e&&!$(e)},data:function(e,t,n){return P(e,t,n)},removeData:function(e,t){return R(e,t)},_data:function(e,t,n){return P(e,t,n,!0)},_removeData:function(e,t){return R(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&b.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),b.fn.extend({data:function(e,n){var r,i,o=this[0],a=0,s=null;if(e===t){if(this.length&&(s=b.data(o),1===o.nodeType&&!b._data(o,"parsedAttrs"))){for(r=o.attributes;r.length>a;a++)i=r[a].name,i.indexOf("data-")||(i=b.camelCase(i.slice(5)),W(o,i,s[i]));b._data(o,"parsedAttrs",!0)}return s}return"object"==typeof e?this.each(function(){b.data(this,e)}):b.access(this,function(n){return n===t?o?W(o,e,b.data(o,e)):null:(this.each(function(){b.data(this,e,n)}),t)},null,n,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){b.removeData(this,e)})}});function W(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(B,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:O.test(r)?b.parseJSON(r):r}catch(o){}b.data(e,n,r)}else r=t}return r}function $(e){var t;for(t in e)if(("data"!==t||!b.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}b.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=b._data(e,n),r&&(!i||b.isArray(r)?i=b._data(e,n,b.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=b.queue(e,t),r=n.length,i=n.shift(),o=b._queueHooks(e,t),a=function(){b.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),o.cur=i,i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return b._data(e,n)||b._data(e,n,{empty:b.Callbacks("once memory").add(function(){b._removeData(e,t+"queue"),b._removeData(e,n)})})}}),b.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?b.queue(this[0],e):n===t?this:this.each(function(){var t=b.queue(this,e,n);b._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&b.dequeue(this,e)})},dequeue:function(e){return this.each(function(){b.dequeue(this,e)})},delay:function(e,t){return e=b.fx?b.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=b.Deferred(),a=this,s=this.length,u=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=b._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(u));return u(),o.promise(n)}});var I,z,X=/[\t\r\n]/g,U=/\r/g,V=/^(?:input|select|textarea|button|object)$/i,Y=/^(?:a|area)$/i,J=/^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,G=/^(?:checked|selected)$/i,Q=b.support.getSetAttribute,K=b.support.input;b.fn.extend({attr:function(e,t){return b.access(this,b.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){b.removeAttr(this,e)})},prop:function(e,t){return b.access(this,b.prop,e,t,arguments.length>1)},removeProp:function(e){return e=b.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,u="string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=b.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,u=0===arguments.length||"string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?b.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return b.isFunction(e)?this.each(function(n){b(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var o,a=0,s=b(this),u=t,l=e.match(w)||[];while(o=l[a++])u=r?u:!s.hasClass(o),s[u?"addClass":"removeClass"](o)}else(n===i||"boolean"===n)&&(this.className&&b._data(this,"__className__",this.className),this.className=this.className||e===!1?"":b._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(X," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=b.isFunction(e),this.each(function(n){var o,a=b(this);1===this.nodeType&&(o=i?e.call(this,n,a.val()):e,null==o?o="":"number"==typeof o?o+="":b.isArray(o)&&(o=b.map(o,function(e){return null==e?"":e+""})),r=b.valHooks[this.type]||b.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=b.valHooks[o.type]||b.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(U,""):null==n?"":n)}}}),b.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,u=0>i?s:o?i:0;for(;s>u;u++)if(n=r[u],!(!n.selected&&u!==i||(b.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&b.nodeName(n.parentNode,"optgroup"))){if(t=b(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n=b.makeArray(t);return b(e).find("option").each(function(){this.selected=b.inArray(b(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attr:function(e,n,r){var o,a,s,u=e.nodeType;if(e&&3!==u&&8!==u&&2!==u)return typeof e.getAttribute===i?b.prop(e,n,r):(a=1!==u||!b.isXMLDoc(e),a&&(n=n.toLowerCase(),o=b.attrHooks[n]||(J.test(n)?z:I)),r===t?o&&a&&"get"in o&&null!==(s=o.get(e,n))?s:(typeof e.getAttribute!==i&&(s=e.getAttribute(n)),null==s?t:s):null!==r?o&&a&&"set"in o&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r):(b.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=b.propFix[n]||n,J.test(n)?!Q&&G.test(n)?e[b.camelCase("default-"+n)]=e[r]=!1:e[r]=!1:b.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!b.support.radioValue&&"radio"===t&&b.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!b.isXMLDoc(e),a&&(n=b.propFix[n]||n,o=b.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):V.test(e.nodeName)||Y.test(e.nodeName)&&e.href?0:t}}}}),z={get:function(e,n){var r=b.prop(e,n),i="boolean"==typeof r&&e.getAttribute(n),o="boolean"==typeof r?K&&Q?null!=i:G.test(n)?e[b.camelCase("default-"+n)]:!!i:e.getAttributeNode(n);return o&&o.value!==!1?n.toLowerCase():t},set:function(e,t,n){return t===!1?b.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&b.propFix[n]||n,n):e[b.camelCase("default-"+n)]=e[n]=!0,n}},K&&Q||(b.attrHooks.value={get:function(e,n){var r=e.getAttributeNode(n);return b.nodeName(e,"input")?e.defaultValue:r&&r.specified?r.value:t},set:function(e,n,r){return b.nodeName(e,"input")?(e.defaultValue=n,t):I&&I.set(e,n,r)}}),Q||(I=b.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&("id"===n||"name"===n||"coords"===n?""!==r.value:r.specified)?r.value:t},set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},b.attrHooks.contenteditable={get:I.get,set:function(e,t,n){I.set(e,""===t?!1:t,n)}},b.each(["width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}})})),b.support.hrefNormalized||(b.each(["href","src","width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return null==r?t:r}})}),b.each(["href","src"],function(e,t){b.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}})),b.support.style||(b.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),b.support.optSelected||(b.propHooks.selected=b.extend(b.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),b.support.enctype||(b.propFix.enctype="encoding"),b.support.checkOn||b.each(["radio","checkbox"],function(){b.valHooks[this]={get:function(e){return null===e.getAttribute("value")?"on":e.value}}}),b.each(["radio","checkbox"],function(){b.valHooks[this]=b.extend(b.valHooks[this],{set:function(e,n){return b.isArray(n)?e.checked=b.inArray(b(e).val(),n)>=0:t}})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}b.event={global:{},add:function(e,n,r,o,a){var s,u,l,c,p,f,d,h,g,m,y,v=b._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=b.guid++),(u=v.events)||(u=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof b===i||e&&b.event.triggered===e.type?t:b.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(w)||[""],l=n.length;while(l--)s=rt.exec(n[l])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),p=b.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=b.event.special[g]||{},d=b.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&b.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=u[g])||(h=u[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),b.event.global[g]=!0;e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,p,f,d,h,g,m=b.hasData(e)&&b._data(e);if(m&&(c=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=b.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),u=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));u&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||b.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)b.event.remove(e,d+t[l],n,r,!0);b.isEmptyObject(c)&&(delete m.handle,b._removeData(e,"events"))}},trigger:function(n,r,i,a){var s,u,l,c,p,f,d,h=[i||o],g=y.call(n,"type")?n.type:n,m=y.call(n,"namespace")?n.namespace.split("."):[];if(l=f=i=i||o,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+b.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),u=0>g.indexOf(":")&&"on"+g,n=n[b.expando]?n:new b.Event(g,"object"==typeof n&&n),n.isTrigger=!0,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:b.makeArray(r,[n]),p=b.event.special[g]||{},a||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!a&&!p.noBubble&&!b.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(l=l.parentNode);l;l=l.parentNode)h.push(l),f=l;f===(i.ownerDocument||o)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((l=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(b._data(l,"events")||{})[n.type]&&b._data(l,"handle"),s&&s.apply(l,r),s=u&&l[u],s&&b.acceptData(l)&&s.apply&&s.apply(l,r)===!1&&n.preventDefault();if(n.type=g,!(a||n.isDefaultPrevented()||p._default&&p._default.apply(i.ownerDocument,r)!==!1||"click"===g&&b.nodeName(i,"a")||!b.acceptData(i)||!u||!i[g]||b.isWindow(i))){f=i[u],f&&(i[u]=null),b.event.triggered=g;try{i[g]()}catch(v){}b.event.triggered=t,f&&(i[u]=f)}return n.result}},dispatch:function(e){e=b.event.fix(e);var n,r,i,o,a,s=[],u=h.call(arguments),l=(b._data(this,"events")||{})[e.type]||[],c=b.event.special[e.type]||{};if(u[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=b.event.handlers.call(this,e,l),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((b.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],u=n.delegateCount,l=e.target;if(u&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!=this;l=l.parentNode||this)if(1===l.nodeType&&(l.disabled!==!0||"click"!==e.type)){for(o=[],a=0;u>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?b(r,this).index(l)>=0:b.find(r,this,null,[l]).length),o[r]&&o.push(i);o.length&&s.push({elem:l,handlers:o})}return n.length>u&&s.push({elem:this,handlers:n.slice(u)}),s},fix:function(e){if(e[b.expando])return e;var t,n,r,i=e.type,a=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new b.Event(a),t=r.length;while(t--)n=r[t],e[n]=a[n];return e.target||(e.target=a.srcElement||o),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,a):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,a,s=n.button,u=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||o,a=i.documentElement,r=i.body,e.pageX=n.clientX+(a&&a.scrollLeft||r&&r.scrollLeft||0)-(a&&a.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(a&&a.scrollTop||r&&r.scrollTop||0)-(a&&a.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&u&&(e.relatedTarget=u===e.target?n.toElement:u),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},click:{trigger:function(){return b.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t}},focus:{trigger:function(){if(this!==o.activeElement&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===o.activeElement&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=b.extend(new b.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?b.event.trigger(i,null,t):b.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},b.removeEvent=o.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},b.Event=function(e,n){return this instanceof b.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&b.extend(this,n),this.timeStamp=e&&e.timeStamp||b.now(),this[b.expando]=!0,t):new b.Event(e,n)},b.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},b.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){b.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj; +return(!i||i!==r&&!b.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),b.support.submitBubbles||(b.event.special.submit={setup:function(){return b.nodeName(this,"form")?!1:(b.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=b.nodeName(n,"input")||b.nodeName(n,"button")?n.form:t;r&&!b._data(r,"submitBubbles")&&(b.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),b._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&b.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return b.nodeName(this,"form")?!1:(b.event.remove(this,"._submit"),t)}}),b.support.changeBubbles||(b.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(b.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),b.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),b.event.simulate("change",this,e,!0)})),!1):(b.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!b._data(t,"changeBubbles")&&(b.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||b.event.simulate("change",this.parentNode,e,!0)}),b._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return b.event.remove(this,"._change"),!Z.test(this.nodeName)}}),b.support.focusinBubbles||b.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){b.event.simulate(t,e.target,b.event.fix(e),!0)};b.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),b.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return b().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=b.guid++)),this.each(function(){b.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,b(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){b.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){b.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?b.event.trigger(e,n,r,!0):t}}),function(e,t){var n,r,i,o,a,s,u,l,c,p,f,d,h,g,m,y,v,x="sizzle"+-new Date,w=e.document,T={},N=0,C=0,k=it(),E=it(),S=it(),A=typeof t,j=1<<31,D=[],L=D.pop,H=D.push,q=D.slice,M=D.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},_="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=F.replace("w","w#"),B="([*^$|!~]?=)",P="\\["+_+"*("+F+")"+_+"*(?:"+B+_+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+O+")|)|)"+_+"*\\]",R=":("+F+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+P.replace(3,8)+")*)|.*)\\)|)",W=RegExp("^"+_+"+|((?:^|[^\\\\])(?:\\\\.)*)"+_+"+$","g"),$=RegExp("^"+_+"*,"+_+"*"),I=RegExp("^"+_+"*([\\x20\\t\\r\\n\\f>+~])"+_+"*"),z=RegExp(R),X=RegExp("^"+O+"$"),U={ID:RegExp("^#("+F+")"),CLASS:RegExp("^\\.("+F+")"),NAME:RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:RegExp("^("+F.replace("w","w*")+")"),ATTR:RegExp("^"+P),PSEUDO:RegExp("^"+R),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+_+"*(even|odd|(([+-]|)(\\d*)n|)"+_+"*(?:([+-]|)"+_+"*(\\d+)|))"+_+"*\\)|)","i"),needsContext:RegExp("^"+_+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+_+"*((?:-\\d)?\\d*)"+_+"*\\)|)(?=[^-]|$)","i")},V=/[\x20\t\r\n\f]*[+~]/,Y=/^[^{]+\{\s*\[native code/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,G=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,K=/'|\\/g,Z=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,et=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,tt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{q.call(w.documentElement.childNodes,0)[0].nodeType}catch(nt){q=function(e){var t,n=[];while(t=this[e++])n.push(t);return n}}function rt(e){return Y.test(e+"")}function it(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>i.cacheLength&&delete e[t.shift()],e[n]=r}}function ot(e){return e[x]=!0,e}function at(e){var t=p.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}}function st(e,t,n,r){var i,o,a,s,u,l,f,g,m,v;if((t?t.ownerDocument||t:w)!==p&&c(t),t=t||p,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(!d&&!r){if(i=J.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&y(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return H.apply(n,q.call(t.getElementsByTagName(e),0)),n;if((a=i[3])&&T.getByClassName&&t.getElementsByClassName)return H.apply(n,q.call(t.getElementsByClassName(a),0)),n}if(T.qsa&&!h.test(e)){if(f=!0,g=x,m=t,v=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){l=ft(e),(f=t.getAttribute("id"))?g=f.replace(K,"\\$&"):t.setAttribute("id",g),g="[id='"+g+"'] ",u=l.length;while(u--)l[u]=g+dt(l[u]);m=V.test(e)&&t.parentNode||t,v=l.join(",")}if(v)try{return H.apply(n,q.call(m.querySelectorAll(v),0)),n}catch(b){}finally{f||t.removeAttribute("id")}}}return wt(e.replace(W,"$1"),t,n,r)}a=st.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},c=st.setDocument=function(e){var n=e?e.ownerDocument||e:w;return n!==p&&9===n.nodeType&&n.documentElement?(p=n,f=n.documentElement,d=a(n),T.tagNameNoComments=at(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),T.attributes=at(function(e){e.innerHTML="";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),T.getByClassName=at(function(e){return e.innerHTML="",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),T.getByName=at(function(e){e.id=x+0,e.innerHTML="
        ",f.insertBefore(e,f.firstChild);var t=n.getElementsByName&&n.getElementsByName(x).length===2+n.getElementsByName(x+0).length;return T.getIdNotName=!n.getElementById(x),f.removeChild(e),t}),i.attrHandle=at(function(e){return e.innerHTML="",e.firstChild&&typeof e.firstChild.getAttribute!==A&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},T.getIdNotName?(i.find.ID=function(e,t){if(typeof t.getElementById!==A&&!d){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){return e.getAttribute("id")===t}}):(i.find.ID=function(e,n){if(typeof n.getElementById!==A&&!d){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==A&&r.getAttributeNode("id").value===e?[r]:t:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){var n=typeof e.getAttributeNode!==A&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=T.tagNameNoComments?function(e,n){return typeof n.getElementsByTagName!==A?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.NAME=T.getByName&&function(e,n){return typeof n.getElementsByName!==A?n.getElementsByName(name):t},i.find.CLASS=T.getByClassName&&function(e,n){return typeof n.getElementsByClassName===A||d?t:n.getElementsByClassName(e)},g=[],h=[":focus"],(T.qsa=rt(n.querySelectorAll))&&(at(function(e){e.innerHTML="",e.querySelectorAll("[selected]").length||h.push("\\["+_+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||h.push(":checked")}),at(function(e){e.innerHTML="",e.querySelectorAll("[i^='']").length&&h.push("[*^$]="+_+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||h.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),h.push(",.*:")})),(T.matchesSelector=rt(m=f.matchesSelector||f.mozMatchesSelector||f.webkitMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&at(function(e){T.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",R)}),h=RegExp(h.join("|")),g=RegExp(g.join("|")),y=rt(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},v=f.compareDocumentPosition?function(e,t){var r;return e===t?(u=!0,0):(r=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t))?1&r||e.parentNode&&11===e.parentNode.nodeType?e===n||y(w,e)?-1:t===n||y(w,t)?1:0:4&r?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return u=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:0;if(o===a)return ut(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?ut(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},u=!1,[0,0].sort(v),T.detectDuplicates=u,p):p},st.matches=function(e,t){return st(e,null,null,t)},st.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Z,"='$1']"),!(!T.matchesSelector||d||g&&g.test(t)||h.test(t)))try{var n=m.call(e,t);if(n||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return st(t,p,null,[e]).length>0},st.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},st.attr=function(e,t){var n;return(e.ownerDocument||e)!==p&&c(e),d||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):d||T.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},st.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},st.uniqueSort=function(e){var t,n=[],r=1,i=0;if(u=!T.detectDuplicates,e.sort(v),u){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e};function ut(e,t){var n=t&&e,r=n&&(~t.sourceIndex||j)-(~e.sourceIndex||j);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function lt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ct(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function pt(e){return ot(function(t){return t=+t,ot(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}o=st.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=st.selectors={cacheLength:50,createPseudo:ot,match:U,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(et,tt),e[3]=(e[4]||e[5]||"").replace(et,tt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||st.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&st.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return U.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&z.test(n)&&(t=ft(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(et,tt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[e+" "];return t||(t=RegExp("(^|"+_+")"+e+"("+_+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==A&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=st.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[x]||(m[x]={}),l=c[e]||[],d=l[0]===N&&l[1],f=l[0]===N&&l[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[N,d,f];break}}else if(v&&(l=(t[x]||(t[x]={}))[e])&&l[0]===N)f=l[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[x]||(p[x]={}))[e]=[N,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||st.error("unsupported pseudo: "+e);return r[x]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?ot(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=M.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:ot(function(e){var t=[],n=[],r=s(e.replace(W,"$1"));return r[x]?ot(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:ot(function(e){return function(t){return st(e,t).length>0}}),contains:ot(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:ot(function(e){return X.test(e||"")||st.error("unsupported lang: "+e),e=e.replace(et,tt).toLowerCase(),function(t){var n;do if(n=d?t.getAttribute("xml:lang")||t.getAttribute("lang"):t.lang)return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return Q.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:pt(function(){return[0]}),last:pt(function(e,t){return[t-1]}),eq:pt(function(e,t,n){return[0>n?n+t:n]}),even:pt(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:pt(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:pt(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:pt(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}};for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[n]=lt(n);for(n in{submit:!0,reset:!0})i.pseudos[n]=ct(n);function ft(e,t){var n,r,o,a,s,u,l,c=E[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=i.preFilter;while(s){(!n||(r=$.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),u.push(o=[])),n=!1,(r=I.exec(s))&&(n=r.shift(),o.push({value:n,type:r[0].replace(W," ")}),s=s.slice(n.length));for(a in i.filter)!(r=U[a].exec(s))||l[a]&&!(r=l[a](r))||(n=r.shift(),o.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?st.error(e):E(e,u).slice(0)}function dt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function ht(e,t,n){var i=t.dir,o=n&&"parentNode"===i,a=C++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,s){var u,l,c,p=N+" "+a;if(s){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[x]||(t[x]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,s)||r,l[1]===!0)return!0}}function gt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function mt(e,t,n,r,i){var o,a=[],s=0,u=e.length,l=null!=t;for(;u>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),l&&t.push(s));return a}function yt(e,t,n,r,i,o){return r&&!r[x]&&(r=yt(r)),i&&!i[x]&&(i=yt(i,o)),ot(function(o,a,s,u){var l,c,p,f=[],d=[],h=a.length,g=o||xt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:mt(g,f,e,s,u),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,u),r){l=mt(y,d),r(l,[],s,u),c=l.length;while(c--)(p=l[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?M.call(o,p):f[c])>-1&&(o[l]=!(a[l]=p))}}else y=mt(y===a?y.splice(h,y.length):y),i?i(null,a,y,u):H.apply(a,y)})}function vt(e){var t,n,r,o=e.length,a=i.relative[e[0].type],s=a||i.relative[" "],u=a?1:0,c=ht(function(e){return e===t},s,!0),p=ht(function(e){return M.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>u;u++)if(n=i.relative[e[u].type])f=[ht(gt(f),n)];else{if(n=i.filter[e[u].type].apply(null,e[u].matches),n[x]){for(r=++u;o>r;r++)if(i.relative[e[r].type])break;return yt(u>1&>(f),u>1&&dt(e.slice(0,u-1)).replace(W,"$1"),n,r>u&&vt(e.slice(u,r)),o>r&&vt(e=e.slice(r)),o>r&&dt(e))}f.push(n)}return gt(f)}function bt(e,t){var n=0,o=t.length>0,a=e.length>0,s=function(s,u,c,f,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,T=l,C=s||a&&i.find.TAG("*",d&&u.parentNode||u),k=N+=null==T?1:Math.random()||.1;for(w&&(l=u!==p&&u,r=n);null!=(h=C[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,u,c)){f.push(h);break}w&&(N=k,r=++n)}o&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,o&&b!==v){g=0;while(m=t[g++])m(x,y,u,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=L.call(f));y=mt(y)}H.apply(f,y),w&&!s&&y.length>0&&v+t.length>1&&st.uniqueSort(f)}return w&&(N=k,l=T),x};return o?ot(s):s}s=st.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=ft(e)),n=t.length;while(n--)o=vt(t[n]),o[x]?r.push(o):i.push(o);o=S(e,bt(i,r))}return o};function xt(e,t,n){var r=0,i=t.length;for(;i>r;r++)st(e,t[r],n);return n}function wt(e,t,n,r){var o,a,u,l,c,p=ft(e);if(!r&&1===p.length){if(a=p[0]=p[0].slice(0),a.length>2&&"ID"===(u=a[0]).type&&9===t.nodeType&&!d&&i.relative[a[1].type]){if(t=i.find.ID(u.matches[0].replace(et,tt),t)[0],!t)return n;e=e.slice(a.shift().value.length)}o=U.needsContext.test(e)?0:a.length;while(o--){if(u=a[o],i.relative[l=u.type])break;if((c=i.find[l])&&(r=c(u.matches[0].replace(et,tt),V.test(a[0].type)&&t.parentNode||t))){if(a.splice(o,1),e=r.length&&dt(a),!e)return H.apply(n,q.call(r,0)),n;break}}}return s(e,p)(r,t,d,n,V.test(e)),n}i.pseudos.nth=i.pseudos.eq;function Tt(){}i.filters=Tt.prototype=i.pseudos,i.setFilters=new Tt,c(),st.attr=b.attr,b.find=st,b.expr=st.selectors,b.expr[":"]=b.expr.pseudos,b.unique=st.uniqueSort,b.text=st.getText,b.isXMLDoc=st.isXML,b.contains=st.contains}(e);var at=/Until$/,st=/^(?:parents|prev(?:Until|All))/,ut=/^.[^:#\[\.,]*$/,lt=b.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};b.fn.extend({find:function(e){var t,n,r,i=this.length;if("string"!=typeof e)return r=this,this.pushStack(b(e).filter(function(){for(t=0;i>t;t++)if(b.contains(r[t],this))return!0}));for(n=[],t=0;i>t;t++)b.find(e,this[t],n);return n=this.pushStack(i>1?b.unique(n):n),n.selector=(this.selector?this.selector+" ":"")+e,n},has:function(e){var t,n=b(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(b.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1))},filter:function(e){return this.pushStack(ft(this,e,!0))},is:function(e){return!!e&&("string"==typeof e?lt.test(e)?b(e,this.context).index(this[0])>=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,o=[],a=lt.test(e)||"string"!=typeof e?b(e,t||this.context):0;for(;i>r;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&11!==n.nodeType){if(a?a.index(n)>-1:b.find.matchesSelector(n,e)){o.push(n);break}n=n.parentNode}}return this.pushStack(o.length>1?b.unique(o):o)},index:function(e){return e?"string"==typeof e?b.inArray(this[0],b(e)):b.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?b(e,t):b.makeArray(e&&e.nodeType?[e]:e),r=b.merge(this.get(),n);return this.pushStack(b.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),b.fn.andSelf=b.fn.addBack;function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}b.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(e,t,n){return b.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(e,t,n){return b.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return b.dir(e,"previousSibling",n)},siblings:function(e){return b.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.merge([],e.childNodes)}},function(e,t){b.fn[e]=function(n,r){var i=b.map(this,t,n);return at.test(e)||(r=n),r&&"string"==typeof r&&(i=b.filter(r,i)),i=this.length>1&&!ct[e]?b.unique(i):i,this.length>1&&st.test(e)&&(i=i.reverse()),this.pushStack(i)}}),b.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),1===t.length?b.find.matchesSelector(t[0],e)?[t[0]]:[]:b.find.matches(e,t)},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!b(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(t=t||0,b.isFunction(t))return b.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return b.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=b.grep(e,function(e){return 1===e.nodeType});if(ut.test(t))return b.filter(t,r,!n);t=b.filter(t,r)}return b.grep(e,function(e){return b.inArray(e,t)>=0===n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/\s*$/g,At={option:[1,""],legend:[1,"
        ","
        "],area:[1,"",""],param:[1,"",""],thead:[1,"","
        "],tr:[2,"","
        "],col:[2,"","
        "],td:[3,"","
        "],_default:b.support.htmlSerialize?[0,"",""]:[1,"X
        ","
        "]},jt=dt(o),Dt=jt.appendChild(o.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,b.fn.extend({text:function(e){return b.access(this,function(e){return e===t?b.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(b.isFunction(e))return this.each(function(t){b(this).wrapAll(e.call(this,t))});if(this[0]){var t=b(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return b.isFunction(e)?this.each(function(t){b(this).wrapInner(e.call(this,t))}):this.each(function(){var t=b(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=b.isFunction(e);return this.each(function(n){b(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){b.nodeName(this,"body")||b(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.insertBefore(e,this.firstChild)})},before:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=0;for(;null!=(n=this[r]);r++)(!e||b.filter(e,[n]).length>0)&&(t||1!==n.nodeType||b.cleanData(Ot(n)),n.parentNode&&(t&&b.contains(n.ownerDocument,n)&&Mt(Ot(n,"script")),n.parentNode.removeChild(n)));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&b.cleanData(Ot(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&b.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return b.clone(this,e,t)})},html:function(e){return b.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!b.support.htmlSerialize&&mt.test(e)||!b.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(b.cleanData(Ot(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){var t=b.isFunction(e);return t||"string"==typeof e||(e=b(e).not(this).detach()),this.domManip([e],!0,function(e){var t=this.nextSibling,n=this.parentNode;n&&(b(this).remove(),n.insertBefore(e,t))})},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=f.apply([],e);var i,o,a,s,u,l,c=0,p=this.length,d=this,h=p-1,g=e[0],m=b.isFunction(g);if(m||!(1>=p||"string"!=typeof g||b.support.checkClone)&&Ct.test(g))return this.each(function(i){var o=d.eq(i);m&&(e[0]=g.call(this,i,n?o.html():t)),o.domManip(e,n,r)});if(p&&(l=b.buildFragment(e,this[0].ownerDocument,!1,this),i=l.firstChild,1===l.childNodes.length&&(l=i),i)){for(n=n&&b.nodeName(i,"tr"),s=b.map(Ot(l,"script"),Ht),a=s.length;p>c;c++)o=l,c!==h&&(o=b.clone(o,!0,!0),a&&b.merge(s,Ot(o,"script"))),r.call(n&&b.nodeName(this[c],"table")?Lt(this[c],"tbody"):this[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,b.map(s,qt),c=0;a>c;c++)o=s[c],kt.test(o.type||"")&&!b._data(o,"globalEval")&&b.contains(u,o)&&(o.src?b.ajax({url:o.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):b.globalEval((o.text||o.textContent||o.innerHTML||"").replace(St,"")));l=i=null}return this}});function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function Ht(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Mt(e,t){var n,r=0;for(;null!=(n=e[r]);r++)b._data(n,"globalEval",!t||b._data(t[r],"globalEval"))}function _t(e,t){if(1===t.nodeType&&b.hasData(e)){var n,r,i,o=b._data(e),a=b._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)b.event.add(t,n,s[n][r])}a.data&&(a.data=b.extend({},a.data))}}function Ft(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!b.support.noCloneEvent&&t[b.expando]){i=b._data(t);for(r in i.events)b.removeEvent(t,r,i.handle);t.removeAttribute(b.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),b.support.html5Clone&&e.innerHTML&&!b.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Nt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}b.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){b.fn[e]=function(e){var n,r=0,i=[],o=b(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),b(o[r])[t](n),d.apply(i,n.get());return this.pushStack(i)}});function Ot(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||b.nodeName(o,n)?s.push(o):b.merge(s,Ot(o,n));return n===t||n&&b.nodeName(e,n)?b.merge([e],s):s}function Bt(e){Nt.test(e.type)&&(e.defaultChecked=e.checked)}b.extend({clone:function(e,t,n){var r,i,o,a,s,u=b.contains(e.ownerDocument,e);if(b.support.html5Clone||b.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(b.support.noCloneEvent&&b.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||b.isXMLDoc(e)))for(r=Ot(o),s=Ot(e),a=0;null!=(i=s[a]);++a)r[a]&&Ft(i,r[a]);if(t)if(n)for(s=s||Ot(e),r=r||Ot(o),a=0;null!=(i=s[a]);a++)_t(i,r[a]);else _t(e,o);return r=Ot(o,"script"),r.length>0&&Mt(r,!u&&Ot(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,u,l,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===b.type(o))b.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),u=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[u]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!b.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!b.support.tbody){o="table"!==u||xt.test(o)?""!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)b.nodeName(l=o.childNodes[i],"tbody")&&!l.childNodes.length&&o.removeChild(l) +}b.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),b.support.appendChecked||b.grep(Ot(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===b.inArray(o,r))&&(a=b.contains(o.ownerDocument,o),s=Ot(f.appendChild(o),"script"),a&&Mt(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,u=b.expando,l=b.cache,p=b.support.deleteExpando,f=b.event.special;for(;null!=(n=e[s]);s++)if((t||b.acceptData(n))&&(o=n[u],a=o&&l[o])){if(a.events)for(r in a.events)f[r]?b.event.remove(n,r):b.removeEvent(n,r,a.handle);l[o]&&(delete l[o],p?delete n[u]:typeof n.removeAttribute!==i?n.removeAttribute(u):n[u]=null,c.push(o))}}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+x+")(.*)$","i"),Yt=RegExp("^("+x+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+x+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===b.css(e,"display")||!b.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=b._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=b._data(r,"olddisplay",un(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&b._data(r,"olddisplay",i?n:b.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}b.fn.extend({css:function(e,n){return b.access(this,function(e,n,r){var i,o,a={},s=0;if(b.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=b.css(e,n[s],!1,o);return a}return r!==t?b.style(e,n,r):b.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?b(this).show():b(this).hide()})}}),b.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,u=b.camelCase(n),l=e.style;if(n=b.cssProps[u]||(b.cssProps[u]=tn(l,u)),s=b.cssHooks[n]||b.cssHooks[u],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:l[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(b.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||b.cssNumber[u]||(r+="px"),b.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(l[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{l[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,u=b.camelCase(n);return n=b.cssProps[u]||(b.cssProps[u]=tn(e.style,u)),s=b.cssHooks[n]||b.cssHooks[u],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||b.isNumeric(o)?o||0:a):a},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s.getPropertyValue(n)||s[n]:t,l=e.style;return s&&(""!==u||b.contains(e.ownerDocument,e)||(u=b.style(e,n)),Yt.test(u)&&Ut.test(n)&&(i=l.width,o=l.minWidth,a=l.maxWidth,l.minWidth=l.maxWidth=l.width=u,u=s.width,l.width=i,l.minWidth=o,l.maxWidth=a)),u}):o.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s[n]:t,l=e.style;return null==u&&l&&l[n]&&(u=l[n]),Yt.test(u)&&!zt.test(n)&&(i=l.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),l.left="fontSize"===n?"1em":u,u=l.pixelLeft+"px",l.left=i,a&&(o.left=a)),""===u?"auto":u});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=b.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=b.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=b.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=b.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=b.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(b.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function un(e){var t=o,n=Gt[e];return n||(n=ln(e,t),"none"!==n&&n||(Pt=(Pt||b("';break;case 3:delete t.title,delete t.closeBtn,t.icon===-1&&0===t.icon,r.closeAll("loading");break;case 4:f||(t.content=[t.content,"body"]),t.follow=t.content[1],t.content=t.content[0]+'',delete t.title,t.tips="object"==typeof t.tips?t.tips:[t.tips,!0],t.tipsMore||r.closeAll("tips")}if(e.vessel(f,function(n,r,u){c.append(n[0]),f?function(){2==t.type||4==t.type?function(){i("body").append(n[1])}():function(){s.parents("."+l[0])[0]||(s.data("display",s.css("display")).show().addClass("layui-layer-wrap").wrap(n[1]),i("#"+l[0]+a).find("."+l[5]).before(r))}()}():c.append(n[1]),i(".layui-layer-move")[0]||c.append(o.moveElem=u),e.layero=i("#"+l[0]+a),t.scrollbar||l.html.css("overflow","hidden").attr("layer-full",a)}).auto(a),i("#layui-layer-shade"+e.index).css({"background-color":t.shade[1]||"#000",opacity:t.shade[0]||t.shade}),2==t.type&&6==r.ie&&e.layero.find("iframe").attr("src",s[0]),4==t.type?e.tips():e.offset(),t.fixed&&n.on("resize",function(){e.offset(),(/^\d+%$/.test(t.area[0])||/^\d+%$/.test(t.area[1]))&&e.auto(a),4==t.type&&e.tips()}),t.time<=0||setTimeout(function(){r.close(e.index)},t.time),e.move().callback(),l.anim[t.anim]){var u="layer-anim "+l.anim[t.anim];e.layero.addClass(u).one("webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend",function(){i(this).removeClass(u)})}t.isOutAnim&&e.layero.data("isOutAnim",!0)}},s.pt.auto=function(e){var t=this,a=t.config,o=i("#"+l[0]+e);""===a.area[0]&&a.maxWidth>0&&(r.ie&&r.ie<8&&a.btn&&o.width(o.innerWidth()),o.outerWidth()>a.maxWidth&&o.width(a.maxWidth));var s=[o.innerWidth(),o.innerHeight()],f=o.find(l[1]).outerHeight()||0,c=o.find("."+l[6]).outerHeight()||0,u=function(e){e=o.find(e),e.height(s[1]-f-c-2*(0|parseFloat(e.css("padding-top"))))};switch(a.type){case 2:u("iframe");break;default:""===a.area[1]?a.maxHeight>0&&o.outerHeight()>a.maxHeight?(s[1]=a.maxHeight,u("."+l[5])):a.fixed&&s[1]>=n.height()&&(s[1]=n.height(),u("."+l[5])):u("."+l[5])}return t},s.pt.offset=function(){var e=this,t=e.config,i=e.layero,a=[i.outerWidth(),i.outerHeight()],o="object"==typeof t.offset;e.offsetTop=(n.height()-a[1])/2,e.offsetLeft=(n.width()-a[0])/2,o?(e.offsetTop=t.offset[0],e.offsetLeft=t.offset[1]||e.offsetLeft):"auto"!==t.offset&&("t"===t.offset?e.offsetTop=0:"r"===t.offset?e.offsetLeft=n.width()-a[0]:"b"===t.offset?e.offsetTop=n.height()-a[1]:"l"===t.offset?e.offsetLeft=0:"lt"===t.offset?(e.offsetTop=0,e.offsetLeft=0):"lb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=0):"rt"===t.offset?(e.offsetTop=0,e.offsetLeft=n.width()-a[0]):"rb"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=n.width()-a[0]):e.offsetTop=t.offset),t.fixed||(e.offsetTop=/%$/.test(e.offsetTop)?n.height()*parseFloat(e.offsetTop)/100:parseFloat(e.offsetTop),e.offsetLeft=/%$/.test(e.offsetLeft)?n.width()*parseFloat(e.offsetLeft)/100:parseFloat(e.offsetLeft),e.offsetTop+=n.scrollTop(),e.offsetLeft+=n.scrollLeft()),i.attr("minLeft")&&(e.offsetTop=n.height()-(i.find(l[1]).outerHeight()||0),e.offsetLeft=i.css("left")),i.css({top:e.offsetTop,left:e.offsetLeft})},s.pt.tips=function(){var e=this,t=e.config,a=e.layero,o=[a.outerWidth(),a.outerHeight()],r=i(t.follow);r[0]||(r=i("body"));var s={width:r.outerWidth(),height:r.outerHeight(),top:r.offset().top,left:r.offset().left},f=a.find(".layui-layer-TipsG"),c=t.tips[0];t.tips[1]||f.remove(),s.autoLeft=function(){s.left+o[0]-n.width()>0?(s.tipLeft=s.left+s.width-o[0],f.css({right:12,left:"auto"})):s.tipLeft=s.left},s.where=[function(){s.autoLeft(),s.tipTop=s.top-o[1]-10,f.removeClass("layui-layer-TipsB").addClass("layui-layer-TipsT").css("border-right-color",t.tips[1])},function(){s.tipLeft=s.left+s.width+10,s.tipTop=s.top,f.removeClass("layui-layer-TipsL").addClass("layui-layer-TipsR").css("border-bottom-color",t.tips[1])},function(){s.autoLeft(),s.tipTop=s.top+s.height+10,f.removeClass("layui-layer-TipsT").addClass("layui-layer-TipsB").css("border-right-color",t.tips[1])},function(){s.tipLeft=s.left-o[0]-10,s.tipTop=s.top,f.removeClass("layui-layer-TipsR").addClass("layui-layer-TipsL").css("border-bottom-color",t.tips[1])}],s.where[c-1](),1===c?s.top-(n.scrollTop()+o[1]+16)<0&&s.where[2]():2===c?n.width()-(s.left+s.width+o[0]+16)>0||s.where[3]():3===c?s.top-n.scrollTop()+s.height+o[1]+16-n.height()>0&&s.where[0]():4===c&&o[0]+16-s.left>0&&s.where[1](),a.find("."+l[5]).css({"background-color":t.tips[1],"padding-right":t.closeBtn?"30px":""}),a.css({left:s.tipLeft-(t.fixed?n.scrollLeft():0),top:s.tipTop-(t.fixed?n.scrollTop():0)})},s.pt.move=function(){var e=this,t=e.config,a=i(document),s=e.layero,l=s.find(t.move),f=s.find(".layui-layer-resize"),c={};return t.move&&l.css("cursor","move"),l.on("mousedown",function(e){e.preventDefault(),t.move&&(c.moveStart=!0,c.offset=[e.clientX-parseFloat(s.css("left")),e.clientY-parseFloat(s.css("top"))],o.moveElem.css("cursor","move").show())}),f.on("mousedown",function(e){e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],c.area=[s.outerWidth(),s.outerHeight()],o.moveElem.css("cursor","se-resize").show()}),a.on("mousemove",function(i){if(c.moveStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1],l="fixed"===s.css("position");if(i.preventDefault(),c.stX=l?0:n.scrollLeft(),c.stY=l?0:n.scrollTop(),!t.moveOut){var f=n.width()-s.outerWidth()+c.stX,u=n.height()-s.outerHeight()+c.stY;af&&(a=f),ou&&(o=u)}s.css({left:a,top:o})}if(t.resize&&c.resizeStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1];i.preventDefault(),r.style(e.index,{width:c.area[0]+a,height:c.area[1]+o}),c.isResize=!0,t.resizing&&t.resizing(s)}}).on("mouseup",function(e){c.moveStart&&(delete c.moveStart,o.moveElem.hide(),t.moveEnd&&t.moveEnd(s)),c.resizeStart&&(delete c.resizeStart,o.moveElem.hide())}),e},s.pt.callback=function(){function e(){var e=a.cancel&&a.cancel(t.index,n);e===!1||r.close(t.index)}var t=this,n=t.layero,a=t.config;t.openLayer(),a.success&&(2==a.type?n.find("iframe").on("load",function(){a.success(n,t.index)}):a.success(n,t.index)),6==r.ie&&t.IE6(n),n.find("."+l[6]).children("a").on("click",function(){var e=i(this).index();if(0===e)a.yes?a.yes(t.index,n):a.btn1?a.btn1(t.index,n):r.close(t.index);else{var o=a["btn"+(e+1)]&&a["btn"+(e+1)](t.index,n);o===!1||r.close(t.index)}}),n.find("."+l[7]).on("click",e),a.shadeClose&&i("#layui-layer-shade"+t.index).on("click",function(){r.close(t.index)}),n.find(".layui-layer-min").on("click",function(){var e=a.min&&a.min(n);e===!1||r.min(t.index,a)}),n.find(".layui-layer-max").on("click",function(){i(this).hasClass("layui-layer-maxmin")?(r.restore(t.index),a.restore&&a.restore(n)):(r.full(t.index,a),setTimeout(function(){a.full&&a.full(n)},100))}),a.end&&(o.end[t.index]=a.end)},o.reselect=function(){i.each(i("select"),function(e,t){var n=i(this);n.parents("."+l[0])[0]||1==n.attr("layer")&&i("."+l[0]).length<1&&n.removeAttr("layer").show(),n=null})},s.pt.IE6=function(e){i("select").each(function(e,t){var n=i(this);n.parents("."+l[0])[0]||"none"===n.css("display")||n.attr({layer:"1"}).hide(),n=null})},s.pt.openLayer=function(){var e=this;r.zIndex=e.config.zIndex,r.setTop=function(e){var t=function(){r.zIndex++,e.css("z-index",r.zIndex+1)};return r.zIndex=parseInt(e[0].style.zIndex),e.on("mousedown",t),r.zIndex}},o.record=function(e){var t=[e.width(),e.height(),e.position().top,e.position().left+parseFloat(e.css("margin-left"))];e.find(".layui-layer-max").addClass("layui-layer-maxmin"),e.attr({area:t})},o.rescollbar=function(e){l.html.attr("layer-full")==e&&(l.html[0].style.removeProperty?l.html[0].style.removeProperty("overflow"):l.html[0].style.removeAttribute("overflow"),l.html.removeAttr("layer-full"))},e.layer=r,r.getChildFrame=function(e,t){return t=t||i("."+l[4]).attr("times"),i("#"+l[0]+t).find("iframe").contents().find(e)},r.getFrameIndex=function(e){return i("#"+e).parents("."+l[4]).attr("times")},r.iframeAuto=function(e){if(e){var t=r.getChildFrame("html",e).outerHeight(),n=i("#"+l[0]+e),a=n.find(l[1]).outerHeight()||0,o=n.find("."+l[6]).outerHeight()||0;n.css({height:t+a+o}),n.find("iframe").css({height:t})}},r.iframeSrc=function(e,t){i("#"+l[0]+e).find("iframe").attr("src",t)},r.style=function(e,t,n){var a=i("#"+l[0]+e),r=a.find(".layui-layer-content"),s=a.attr("type"),f=a.find(l[1]).outerHeight()||0,c=a.find("."+l[6]).outerHeight()||0;a.attr("minLeft");s!==o.type[3]&&s!==o.type[4]&&(n||(parseFloat(t.width)<=260&&(t.width=260),parseFloat(t.height)-f-c<=64&&(t.height=64+f+c)),a.css(t),c=a.find("."+l[6]).outerHeight(),s===o.type[2]?a.find("iframe").css({height:parseFloat(t.height)-f-c}):r.css({height:parseFloat(t.height)-f-c-parseFloat(r.css("padding-top"))-parseFloat(r.css("padding-bottom"))}))},r.min=function(e,t){var a=i("#"+l[0]+e),s=a.find(l[1]).outerHeight()||0,f=a.attr("minLeft")||181*o.minIndex+"px",c=a.css("position");o.record(a),o.minLeft[0]&&(f=o.minLeft[0],o.minLeft.shift()),a.attr("position",c),r.style(e,{width:180,height:s,left:f,top:n.height()-s,position:"fixed",overflow:"hidden"},!0),a.find(".layui-layer-min").hide(),"page"===a.attr("type")&&a.find(l[4]).hide(),o.rescollbar(e),a.attr("minLeft")||o.minIndex++,a.attr("minLeft",f)},r.restore=function(e){var t=i("#"+l[0]+e),n=t.attr("area").split(",");t.attr("type");r.style(e,{width:parseFloat(n[0]),height:parseFloat(n[1]),top:parseFloat(n[2]),left:parseFloat(n[3]),position:t.attr("position"),overflow:"visible"},!0),t.find(".layui-layer-max").removeClass("layui-layer-maxmin"),t.find(".layui-layer-min").show(),"page"===t.attr("type")&&t.find(l[4]).show(),o.rescollbar(e)},r.full=function(e){var t,a=i("#"+l[0]+e);o.record(a),l.html.attr("layer-full")||l.html.css("overflow","hidden").attr("layer-full",e),clearTimeout(t),t=setTimeout(function(){var t="fixed"===a.css("position");r.style(e,{top:t?0:n.scrollTop(),left:t?0:n.scrollLeft(),width:n.width(),height:n.height()},!0),a.find(".layui-layer-min").hide()},100)},r.title=function(e,t){var n=i("#"+l[0]+(t||r.index)).find(l[1]);n.html(e)},r.close=function(e){var t=i("#"+l[0]+e),n=t.attr("type"),a="layer-anim-close";if(t[0]){var s="layui-layer-wrap",f=function(){if(n===o.type[1]&&"object"===t.attr("conType")){t.children(":not(."+l[5]+")").remove();for(var a=t.find("."+s),r=0;r<2;r++)a.unwrap();a.css("display",a.data("display")).removeClass(s)}else{if(n===o.type[2])try{var f=i("#"+l[4]+e)[0];f.contentWindow.document.write(""),f.contentWindow.close(),t.find("."+l[5])[0].removeChild(f)}catch(c){}t[0].innerHTML="",t.remove()}"function"==typeof o.end[e]&&o.end[e](),delete o.end[e]};t.data("isOutAnim")&&t.addClass("layer-anim "+a),i("#layui-layer-moves, #layui-layer-shade"+e).remove(),6==r.ie&&o.reselect(),o.rescollbar(e),t.attr("minLeft")&&(o.minIndex--,o.minLeft.push(t.attr("minLeft"))),r.ie&&r.ie<10||!t.data("isOutAnim")?f():setTimeout(function(){f()},200)}},r.closeAll=function(e){i.each(i("."+l[0]),function(){var t=i(this),n=e?t.attr("type")===e:1;n&&r.close(t.attr("times")),n=null})};var f=r.cache||{},c=function(e){return f.skin?" "+f.skin+" "+f.skin+"-"+e:""};r.prompt=function(e,t){var a="";if(e=e||{},"function"==typeof e&&(t=e),e.area){var o=e.area;a='style="width: '+o[0]+"; height: "+o[1]+';"',delete e.area}var s,l=2==e.formType?'":function(){return''}(),f=e.success;return delete e.success,r.open(i.extend({type:1,btn:["确定","取消"],content:l,skin:"layui-layer-prompt"+c("prompt"),maxWidth:n.width(),success:function(e){s=e.find(".layui-layer-input"),s.focus(),"function"==typeof f&&f(e)},resize:!1,yes:function(i){var n=s.val();""===n?s.focus():n.length>(e.maxlength||500)?r.tips("最多输入"+(e.maxlength||500)+"个字数",s,{tips:1}):t&&t(n,i,s)}},e))},r.tab=function(e){e=e||{};var t=e.tab||{},n="layui-this",a=e.success;return delete e.success,r.open(i.extend({type:1,skin:"layui-layer-tab"+c("tab"),resize:!1,title:function(){var e=t.length,i=1,a="";if(e>0)for(a=''+t[0].title+"";i"+t[i].title+"";return a}(),content:'
          '+function(){var e=t.length,i=1,a="";if(e>0)for(a='
        • '+(t[0].content||"no content")+"
        • ";i'+(t[i].content||"no content")+"";return a}()+"
        ",success:function(t){var o=t.find(".layui-layer-title").children(),r=t.find(".layui-layer-tabmain").children();o.on("mousedown",function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0;var a=i(this),o=a.index();a.addClass(n).siblings().removeClass(n),r.eq(o).show().siblings().hide(),"function"==typeof e.change&&e.change(o)}),"function"==typeof a&&a(t)}},e))},r.photos=function(t,n,a){function o(e,t,i){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,i(e)}))}var s={};if(t=t||{},t.photos){var l=t.photos.constructor===Object,f=l?t.photos:{},u=f.data||[],d=f.start||0;s.imgIndex=(0|d)+1,t.img=t.img||"img";var y=t.success;if(delete t.success,l){if(0===u.length)return r.msg("没有图片")}else{var p=i(t.photos),h=function(){u=[],p.find(t.img).each(function(e){var t=i(this);t.attr("layer-index",e),u.push({alt:t.attr("alt"),pid:t.attr("layer-pid"),src:t.attr("layer-src")||t.attr("src"),thumb:t.attr("src")})})};if(h(),0===u.length)return;if(n||p.on("click",t.img,function(){var e=i(this),n=e.attr("layer-index");r.photos(i.extend(t,{photos:{start:n,data:u,tab:t.tab},full:t.full}),!0),h()}),!n)return}s.imgprev=function(e){s.imgIndex--,s.imgIndex<1&&(s.imgIndex=u.length),s.tabimg(e)},s.imgnext=function(e,t){s.imgIndex++,s.imgIndex>u.length&&(s.imgIndex=1,t)||s.tabimg(e)},s.keyup=function(e){if(!s.end){var t=e.keyCode;e.preventDefault(),37===t?s.imgprev(!0):39===t?s.imgnext(!0):27===t&&r.close(s.index)}},s.tabimg=function(e){if(!(u.length<=1))return f.start=s.imgIndex-1,r.close(s.index),r.photos(t,!0,e)},s.event=function(){s.bigimg.hover(function(){s.imgsee.show()},function(){s.imgsee.hide()}),s.bigimg.find(".layui-layer-imgprev").on("click",function(e){e.preventDefault(),s.imgprev()}),s.bigimg.find(".layui-layer-imgnext").on("click",function(e){e.preventDefault(),s.imgnext()}),i(document).on("keyup",s.keyup)},s.loadi=r.load(1,{shade:!("shade"in t)&&.9,scrollbar:!1}),o(u[d].src,function(n){r.close(s.loadi),s.index=r.open(i.extend({type:1,id:"layui-layer-photos",area:function(){var a=[n.width,n.height],o=[i(e).width()-100,i(e).height()-100];if(!t.full&&(a[0]>o[0]||a[1]>o[1])){var r=[a[0]/o[0],a[1]/o[1]];r[0]>r[1]?(a[0]=a[0]/r[0],a[1]=a[1]/r[0]):r[0]'+(u[d].alt||
        '+(u.length>1?'':"")+'
        '+(u[d].alt||"")+""+s.imgIndex+"/"+u.length+"
        ",success:function(e,i){s.bigimg=e.find(".layui-layer-phimg"),s.imgsee=e.find(".layui-layer-imguide,.layui-layer-imgbar"),s.event(e),t.tab&&t.tab(u[d],e),"function"==typeof y&&y(e)},end:function(){s.end=!0,i(document).off("keyup",s.keyup)}},t))},function(){r.close(s.loadi),r.msg("当前图片地址异常
        是否继续查看下一张?",{time:3e4,btn:["下一张","不看了"],yes:function(){u.length>1&&s.imgnext(!0,!0)}})})}},o.run=function(t){i=t,n=i(e),l.html=i("html"),r.open=function(e){var t=new s(e);return t.index}},e.layui&&layui.define?(r.ready(),layui.define("jquery",function(t){r.path=layui.cache.dir,o.run(layui.$),e.layer=r,t("layer",r)})):"function"==typeof define&&define.amd?define(["jquery"],function(){return o.run(e.jQuery),r}):function(){o.run(e.jQuery),r.ready()}()}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/mobile/layer.js b/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/mobile/layer.js new file mode 100644 index 000000000..f9cf69313 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/mobile/layer.js @@ -0,0 +1,2 @@ +/*! layer mobile-v2.0.0 Web弹层组件 MIT License http://layer.layui.com/mobile By 贤心 */ + ;!function(e){"use strict";var t=document,n="querySelectorAll",i="getElementsByClassName",a=function(e){return t[n](e)},s={type:0,shade:!0,shadeClose:!0,fixed:!0,anim:"scale"},l={extend:function(e){var t=JSON.parse(JSON.stringify(s));for(var n in e)t[n]=e[n];return t},timer:{},end:{}};l.touch=function(e,t){e.addEventListener("click",function(e){t.call(this,e)},!1)};var r=0,o=["layui-m-layer"],c=function(e){var t=this;t.config=l.extend(e),t.view()};c.prototype.view=function(){var e=this,n=e.config,s=t.createElement("div");e.id=s.id=o[0]+r,s.setAttribute("class",o[0]+" "+o[0]+(n.type||0)),s.setAttribute("index",r);var l=function(){var e="object"==typeof n.title;return n.title?'

        '+(e?n.title[0]:n.title)+"

        ":""}(),c=function(){"string"==typeof n.btn&&(n.btn=[n.btn]);var e,t=(n.btn||[]).length;return 0!==t&&n.btn?(e=''+n.btn[0]+"",2===t&&(e=''+n.btn[1]+""+e),'
        '+e+"
        "):""}();if(n.fixed||(n.top=n.hasOwnProperty("top")?n.top:100,n.style=n.style||"",n.style+=" top:"+(t.body.scrollTop+n.top)+"px"),2===n.type&&(n.content='

        '+(n.content||"")+"

        "),n.skin&&(n.anim="up"),"msg"===n.skin&&(n.shade=!1),s.innerHTML=(n.shade?"
        ':"")+'
        "+l+'
        '+n.content+"
        "+c+"
        ",!n.type||2===n.type){var d=t[i](o[0]+n.type),y=d.length;y>=1&&layer.close(d[0].getAttribute("index"))}document.body.appendChild(s);var u=e.elem=a("#"+e.id)[0];n.success&&n.success(u),e.index=r++,e.action(n,u)},c.prototype.action=function(e,t){var n=this;e.time&&(l.timer[n.index]=setTimeout(function(){layer.close(n.index)},1e3*e.time));var a=function(){var t=this.getAttribute("type");0==t?(e.no&&e.no(),layer.close(n.index)):e.yes?e.yes(n.index):layer.close(n.index)};if(e.btn)for(var s=t[i]("layui-m-layerbtn")[0].children,r=s.length,o=0;odiv{line-height:22px;padding-top:7px;margin-bottom:20px;font-size:14px}.layui-m-layerbtn{display:box;display:-moz-box;display:-webkit-box;width:100%;height:50px;line-height:50px;font-size:0;border-top:1px solid #D0D0D0;background-color:#F2F2F2}.layui-m-layerbtn span{display:block;-moz-box-flex:1;box-flex:1;-webkit-box-flex:1;font-size:14px;cursor:pointer}.layui-m-layerbtn span[yes]{color:#40AFFE}.layui-m-layerbtn span[no]{border-right:1px solid #D0D0D0;border-radius:0 0 0 5px}.layui-m-layerbtn span:active{background-color:#F6F6F6}.layui-m-layerend{position:absolute;right:7px;top:10px;width:30px;height:30px;border:0;font-weight:400;background:0 0;cursor:pointer;-webkit-appearance:none;font-size:30px}.layui-m-layerend::after,.layui-m-layerend::before{position:absolute;left:5px;top:15px;content:'';width:18px;height:1px;background-color:#999;transform:rotate(45deg);-webkit-transform:rotate(45deg);border-radius:3px}.layui-m-layerend::after{transform:rotate(-45deg);-webkit-transform:rotate(-45deg)}body .layui-m-layer .layui-m-layer-footer{position:fixed;width:95%;max-width:100%;margin:0 auto;left:0;right:0;bottom:10px;background:0 0}.layui-m-layer-footer .layui-m-layercont{padding:20px;border-radius:5px 5px 0 0;background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn{display:block;height:auto;background:0 0;border-top:none}.layui-m-layer-footer .layui-m-layerbtn span{background-color:rgba(255,255,255,.8)}.layui-m-layer-footer .layui-m-layerbtn span[no]{color:#FD482C;border-top:1px solid #c2c2c2;border-radius:0 0 5px 5px}.layui-m-layer-footer .layui-m-layerbtn span[yes]{margin-top:10px;border-radius:5px}body .layui-m-layer .layui-m-layer-msg{width:auto;max-width:90%;margin:0 auto;bottom:-150px;background-color:rgba(0,0,0,.7);color:#fff}.layui-m-layer-msg .layui-m-layercont{padding:10px 20px} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/icon-ext.png b/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/icon-ext.png new file mode 100644 index 000000000..bbbb669bb Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/icon-ext.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/icon.png b/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/icon.png new file mode 100644 index 000000000..3e17da8b1 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/icon.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/layer.css b/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/layer.css new file mode 100644 index 000000000..820b4a99b --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/layer.css @@ -0,0 +1 @@ +.layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span,.layui-layer-title{text-overflow:ellipsis;white-space:nowrap}html #layuicss-layer{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+"px")}.layui-layer{-webkit-overflow-scrolling:touch;top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;border-radius:2px;box-shadow:1px 1px 50px rgba(0,0,0,.3)}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.1);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-load{background:url(loading-1.gif) center center no-repeat #eee}.layui-layer-ico{background:url(icon.png) no-repeat}.layui-layer-btn a,.layui-layer-dialog .layui-layer-ico,.layui-layer-setwin a{display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-move{display:none;position:fixed;*position:absolute;left:0;top:0;width:100%;height:100%;cursor:move;opacity:0;filter:alpha(opacity=0);background-color:#fff;z-index:2147483647}.layui-layer-resize{position:absolute;width:15px;height:15px;right:0;bottom:0;cursor:se-resize}.layer-anim{-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-00{-webkit-animation-name:layer-bounceIn;animation-name:layer-bounceIn}@-webkit-keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:layer-zoomInDown;animation-name:layer-zoomInDown}@-webkit-keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes layer-fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:layer-fadeInUpBig;animation-name:layer-fadeInUpBig}@-webkit-keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes layer-zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:layer-zoomInLeft;animation-name:layer-zoomInLeft}@-webkit-keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes layer-rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layer-anim-04{-webkit-animation-name:layer-rollIn;animation-name:layer-rollIn}@keyframes layer-fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:layer-fadeIn;animation-name:layer-fadeIn}@-webkit-keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes layer-shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:layer-shake;animation-name:layer-shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layui-layer-title{padding:0 80px 0 20px;height:42px;line-height:42px;border-bottom:1px solid #eee;font-size:14px;color:#333;overflow:hidden;background-color:#F8F8F8;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:15px;font-size:0;line-height:initial}.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:10px;font-size:12px;_overflow:hidden}.layui-layer-setwin .layui-layer-min cite{position:absolute;width:14px;height:2px;left:0;top:50%;margin-top:-1px;background-color:#2E2D3C;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA}.layui-layer-setwin .layui-layer-max{background-position:-32px -40px}.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px}.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px}.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px}.layui-layer-setwin .layui-layer-close1{background-position:1px -40px;cursor:pointer}.layui-layer-setwin .layui-layer-close1:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;width:30px;height:30px;margin-left:0;background-position:-149px -31px;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{background-position:-180px -31px}.layui-layer-btn{text-align:right;padding:0 15px 12px;pointer-events:auto;user-select:none;-webkit-user-select:none}.layui-layer-btn a{height:28px;line-height:28px;margin:5px 5px 0;padding:0 15px;border:1px solid #dedede;background-color:#fff;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.8}.layui-layer-btn .layui-layer-btn0{border-color:#1E9FFF;background-color:#1E9FFF;color:#fff}.layui-layer-btn-l{text-align:left}.layui-layer-btn-c{text-align:center}.layui-layer-dialog{min-width:260px}.layui-layer-dialog .layui-layer-content{position:relative;padding:20px;line-height:24px;word-break:break-all;overflow:hidden;font-size:14px;overflow-x:hidden;overflow-y:auto}.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute;top:16px;left:15px;_left:-40px;width:30px;height:30px}.layui-layer-ico1{background-position:-30px 0}.layui-layer-ico2{background-position:-60px 0}.layui-layer-ico3{background-position:-90px 0}.layui-layer-ico4{background-position:-120px 0}.layui-layer-ico5{background-position:-150px 0}.layui-layer-ico6{background-position:-180px 0}.layui-layer-rim{border:6px solid #8D8D8D;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #D3D4D3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-content{padding:12px 25px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:20px 20px 20px 55px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(loading-0.gif) no-repeat}.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(loading-1.gif) no-repeat}.layui-layer-ico16,.layui-layer-loading .layui-layer-loading2{width:32px;height:32px;background:url(loading-2.gif) no-repeat}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:8px 15px;font-size:12px;_float:left;border-radius:2px;box-shadow:1px 1px 3px rgba(0,0,0,.2);background-color:#000;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#000}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:5px;border-bottom-style:solid;border-bottom-color:#000}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan[type=dialog]{min-width:280px}.layui-layer-lan .layui-layer-title{background:#4476A7;color:#fff;border:none}.layui-layer-lan .layui-layer-btn{padding:5px 10px 10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#fff;border-color:#E9E7E7;color:#333}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95;border-color:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1}.layui-layer-iconext{background:url(icon-ext.png) no-repeat}.layui-layer-prompt .layui-layer-input{display:block;width:230px;height:36px;margin:0 auto;line-height:30px;padding-left:10px;border:1px solid #e6e6e6;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px;padding:6px 10px}.layui-layer-prompt .layui-layer-content{padding:20px}.layui-layer-prompt .layui-layer-btn{padding-top:0}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;float:left;min-width:80px;max-width:260px;padding:0 20px;text-align:center;overflow:hidden;cursor:pointer}.layui-layer-tab .layui-layer-title span.layui-this{height:43px;border-left:1px solid #eee;border-right:1px solid #eee;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left:none}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.layui-this{display:block}.layui-layer-photos{-webkit-animation-duration:.8s;animation-duration:.8s}.layui-layer-photos .layui-layer-content{overflow:hidden;text-align:center}.layui-layer-photos .layui-layer-phimg img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-imgbar,.layui-layer-imguide{display:none}.layui-layer-imgnext,.layui-layer-imgprev{position:absolute;top:50%;width:27px;_width:44px;height:44px;margin-top:-22px;outline:0;blr:expression(this.onFocus=this.blur())}.layui-layer-imgprev{left:10px;background-position:-5px -5px;_background-position:-70px -5px}.layui-layer-imgprev:hover{background-position:-33px -5px;_background-position:-120px -5px}.layui-layer-imgnext{right:10px;_right:8px;background-position:-5px -50px;_background-position:-70px -50px}.layui-layer-imgnext:hover{background-position:-33px -50px;_background-position:-120px -50px}.layui-layer-imgbar{position:absolute;left:0;bottom:0;width:100%;height:32px;line-height:32px;background-color:rgba(0,0,0,.8);background-color:#000\9;filter:Alpha(opacity=80);color:#fff;overflow:hidden;font-size:0}.layui-layer-imgtit *{display:inline-block;*display:inline;*zoom:1;vertical-align:top;font-size:12px}.layui-layer-imgtit a{max-width:65%;overflow:hidden;color:#fff}.layui-layer-imgtit a:hover{color:#fff;text-decoration:underline}.layui-layer-imgtit em{padding-left:10px;font-style:normal}@-webkit-keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes layer-bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);-ms-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-close{-webkit-animation-name:layer-bounceOut;animation-name:layer-bounceOut;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.2s;animation-duration:.2s}@media screen and (max-width:1100px){.layui-layer-iframe{overflow-y:auto;-webkit-overflow-scrolling:touch}} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/loading-0.gif b/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/loading-0.gif new file mode 100644 index 000000000..6f3c9539a Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/loading-0.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/loading-1.gif b/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/loading-1.gif new file mode 100644 index 000000000..db3a483e4 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/loading-1.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/loading-2.gif b/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/loading-2.gif new file mode 100644 index 000000000..5bb90fd6a Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/lib/layer-3.1.1/theme/default/loading-2.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/lib/lodash-4.17.10.min.js b/net452/SiteServer.Web/SiteServer/assets/lib/lodash-4.17.10.min.js new file mode 100644 index 000000000..fced00b39 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/lib/lodash-4.17.10.min.js @@ -0,0 +1,137 @@ +/** + * @license + * Lodash lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE + */ +;(function(){function n(n,t,r){switch(r.length){case 0:return n.call(t);case 1:return n.call(t,r[0]);case 2:return n.call(t,r[0],r[1]);case 3:return n.call(t,r[0],r[1],r[2])}return n.apply(t,r)}function t(n,t,r,e){for(var u=-1,i=null==n?0:n.length;++u"']/g,G=RegExp(V.source),H=RegExp(K.source),J=/<%-([\s\S]+?)%>/g,Y=/<%([\s\S]+?)%>/g,Q=/<%=([\s\S]+?)%>/g,X=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,nn=/^\w*$/,tn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g,rn=/[\\^$.*+?()[\]{}|]/g,en=RegExp(rn.source),un=/^\s+|\s+$/g,on=/^\s+/,fn=/\s+$/,cn=/\{(?:\n\/\* \[wrapped with .+\] \*\/)?\n?/,an=/\{\n\/\* \[wrapped with (.+)\] \*/,ln=/,? & /,sn=/[^\x00-\x2f\x3a-\x40\x5b-\x60\x7b-\x7f]+/g,hn=/\\(\\)?/g,pn=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,_n=/\w*$/,vn=/^[-+]0x[0-9a-f]+$/i,gn=/^0b[01]+$/i,dn=/^\[object .+?Constructor\]$/,yn=/^0o[0-7]+$/i,bn=/^(?:0|[1-9]\d*)$/,xn=/[\xc0-\xd6\xd8-\xf6\xf8-\xff\u0100-\u017f]/g,jn=/($^)/,wn=/['\n\r\u2028\u2029\\]/g,mn="[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?(?:\\u200d(?:[^\\ud800-\\udfff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])[\\ufe0e\\ufe0f]?(?:[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|\\ud83c[\\udffb-\\udfff])?)*",An="(?:[\\u2700-\\u27bf]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff])"+mn,En="(?:[^\\ud800-\\udfff][\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]?|[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]|(?:\\ud83c[\\udde6-\\uddff]){2}|[\\ud800-\\udbff][\\udc00-\\udfff]|[\\ud800-\\udfff])",kn=RegExp("['\u2019]","g"),Sn=RegExp("[\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff]","g"),On=RegExp("\\ud83c[\\udffb-\\udfff](?=\\ud83c[\\udffb-\\udfff])|"+En+mn,"g"),In=RegExp(["[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+(?:['\u2019](?:d|ll|m|re|s|t|ve))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde]|$)|(?:[A-Z\\xc0-\\xd6\\xd8-\\xde]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?(?=[\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000]|[A-Z\\xc0-\\xd6\\xd8-\\xde](?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])|$)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?(?:[a-z\\xdf-\\xf6\\xf8-\\xff]|[^\\ud800-\\udfff\\xac\\xb1\\xd7\\xf7\\x00-\\x2f\\x3a-\\x40\\x5b-\\x60\\x7b-\\xbf\\u2000-\\u206f \\t\\x0b\\f\\xa0\\ufeff\\n\\r\\u2028\\u2029\\u1680\\u180e\\u2000\\u2001\\u2002\\u2003\\u2004\\u2005\\u2006\\u2007\\u2008\\u2009\\u200a\\u202f\\u205f\\u3000\\d+\\u2700-\\u27bfa-z\\xdf-\\xf6\\xf8-\\xffA-Z\\xc0-\\xd6\\xd8-\\xde])+(?:['\u2019](?:d|ll|m|re|s|t|ve))?|[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?:['\u2019](?:D|LL|M|RE|S|T|VE))?|\\d*(?:1ST|2ND|3RD|(?![123])\\dTH)(?=\\b|[a-z_])|\\d*(?:1st|2nd|3rd|(?![123])\\dth)(?=\\b|[A-Z_])|\\d+",An].join("|"),"g"),Rn=RegExp("[\\u200d\\ud800-\\udfff\\u0300-\\u036f\\ufe20-\\ufe2f\\u20d0-\\u20ff\\ufe0e\\ufe0f]"),zn=/[a-z][A-Z]|[A-Z]{2,}[a-z]|[0-9][a-zA-Z]|[a-zA-Z][0-9]|[^a-zA-Z0-9 ]/,Wn="Array Buffer DataView Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Map Math Object Promise RegExp Set String Symbol TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap _ clearTimeout isFinite parseInt setTimeout".split(" "),Bn={}; +Bn["[object Float32Array]"]=Bn["[object Float64Array]"]=Bn["[object Int8Array]"]=Bn["[object Int16Array]"]=Bn["[object Int32Array]"]=Bn["[object Uint8Array]"]=Bn["[object Uint8ClampedArray]"]=Bn["[object Uint16Array]"]=Bn["[object Uint32Array]"]=true,Bn["[object Arguments]"]=Bn["[object Array]"]=Bn["[object ArrayBuffer]"]=Bn["[object Boolean]"]=Bn["[object DataView]"]=Bn["[object Date]"]=Bn["[object Error]"]=Bn["[object Function]"]=Bn["[object Map]"]=Bn["[object Number]"]=Bn["[object Object]"]=Bn["[object RegExp]"]=Bn["[object Set]"]=Bn["[object String]"]=Bn["[object WeakMap]"]=false; +var Ln={};Ln["[object Arguments]"]=Ln["[object Array]"]=Ln["[object ArrayBuffer]"]=Ln["[object DataView]"]=Ln["[object Boolean]"]=Ln["[object Date]"]=Ln["[object Float32Array]"]=Ln["[object Float64Array]"]=Ln["[object Int8Array]"]=Ln["[object Int16Array]"]=Ln["[object Int32Array]"]=Ln["[object Map]"]=Ln["[object Number]"]=Ln["[object Object]"]=Ln["[object RegExp]"]=Ln["[object Set]"]=Ln["[object String]"]=Ln["[object Symbol]"]=Ln["[object Uint8Array]"]=Ln["[object Uint8ClampedArray]"]=Ln["[object Uint16Array]"]=Ln["[object Uint32Array]"]=true, +Ln["[object Error]"]=Ln["[object Function]"]=Ln["[object WeakMap]"]=false;var Un={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Cn=parseFloat,Dn=parseInt,Mn=typeof global=="object"&&global&&global.Object===Object&&global,Tn=typeof self=="object"&&self&&self.Object===Object&&self,$n=Mn||Tn||Function("return this")(),Fn=typeof exports=="object"&&exports&&!exports.nodeType&&exports,Nn=Fn&&typeof module=="object"&&module&&!module.nodeType&&module,Pn=Nn&&Nn.exports===Fn,Zn=Pn&&Mn.process,qn=function(){ +try{var n=Nn&&Nn.f&&Nn.f("util").types;return n?n:Zn&&Zn.binding&&Zn.binding("util")}catch(n){}}(),Vn=qn&&qn.isArrayBuffer,Kn=qn&&qn.isDate,Gn=qn&&qn.isMap,Hn=qn&&qn.isRegExp,Jn=qn&&qn.isSet,Yn=qn&&qn.isTypedArray,Qn=b("length"),Xn=x({"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A","\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I", +"\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u","\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss","\u0100":"A","\u0102":"A","\u0104":"A","\u0101":"a","\u0103":"a","\u0105":"a","\u0106":"C", +"\u0108":"C","\u010a":"C","\u010c":"C","\u0107":"c","\u0109":"c","\u010b":"c","\u010d":"c","\u010e":"D","\u0110":"D","\u010f":"d","\u0111":"d","\u0112":"E","\u0114":"E","\u0116":"E","\u0118":"E","\u011a":"E","\u0113":"e","\u0115":"e","\u0117":"e","\u0119":"e","\u011b":"e","\u011c":"G","\u011e":"G","\u0120":"G","\u0122":"G","\u011d":"g","\u011f":"g","\u0121":"g","\u0123":"g","\u0124":"H","\u0126":"H","\u0125":"h","\u0127":"h","\u0128":"I","\u012a":"I","\u012c":"I","\u012e":"I","\u0130":"I","\u0129":"i", +"\u012b":"i","\u012d":"i","\u012f":"i","\u0131":"i","\u0134":"J","\u0135":"j","\u0136":"K","\u0137":"k","\u0138":"k","\u0139":"L","\u013b":"L","\u013d":"L","\u013f":"L","\u0141":"L","\u013a":"l","\u013c":"l","\u013e":"l","\u0140":"l","\u0142":"l","\u0143":"N","\u0145":"N","\u0147":"N","\u014a":"N","\u0144":"n","\u0146":"n","\u0148":"n","\u014b":"n","\u014c":"O","\u014e":"O","\u0150":"O","\u014d":"o","\u014f":"o","\u0151":"o","\u0154":"R","\u0156":"R","\u0158":"R","\u0155":"r","\u0157":"r","\u0159":"r", +"\u015a":"S","\u015c":"S","\u015e":"S","\u0160":"S","\u015b":"s","\u015d":"s","\u015f":"s","\u0161":"s","\u0162":"T","\u0164":"T","\u0166":"T","\u0163":"t","\u0165":"t","\u0167":"t","\u0168":"U","\u016a":"U","\u016c":"U","\u016e":"U","\u0170":"U","\u0172":"U","\u0169":"u","\u016b":"u","\u016d":"u","\u016f":"u","\u0171":"u","\u0173":"u","\u0174":"W","\u0175":"w","\u0176":"Y","\u0177":"y","\u0178":"Y","\u0179":"Z","\u017b":"Z","\u017d":"Z","\u017a":"z","\u017c":"z","\u017e":"z","\u0132":"IJ","\u0133":"ij", +"\u0152":"Oe","\u0153":"oe","\u0149":"'n","\u017f":"s"}),nt=x({"&":"&","<":"<",">":">",'"':""","'":"'"}),tt=x({"&":"&","<":"<",">":">",""":'"',"'":"'"}),rt=function x(mn){function An(n){if(du(n)&&!of(n)&&!(n instanceof Un)){if(n instanceof On)return n;if(ii.call(n,"__wrapped__"))return $e(n)}return new On(n)}function En(){}function On(n,t){this.__wrapped__=n,this.__actions__=[],this.__chain__=!!t,this.__index__=0,this.__values__=T}function Un(n){this.__wrapped__=n, +this.__actions__=[],this.__dir__=1,this.__filtered__=false,this.__iteratees__=[],this.__takeCount__=4294967295,this.__views__=[]}function Mn(n){var t=-1,r=null==n?0:n.length;for(this.clear();++t=t?n:t)),n}function _t(n,t,e,u,i,o){var f,c=1&t,a=2&t,l=4&t;if(e&&(f=i?e(n,u,i,o):e(n)),f!==T)return f;if(!gu(n))return n;if(u=of(n)){if(f=me(n),!c)return Ur(n,f)}else{var s=_o(n),h="[object Function]"==s||"[object GeneratorFunction]"==s;if(cf(n))return Ir(n,c);if("[object Object]"==s||"[object Arguments]"==s||h&&!i){if(f=a||h?{}:Ae(n),!c)return a?Mr(n,lt(f,n)):Dr(n,at(f,n))}else{if(!Ln[s])return i?n:{};f=Ee(n,s,c)}}if(o||(o=new Zn), +i=o.get(n))return i;if(o.set(n,f),hf(n))return n.forEach(function(r){f.add(_t(r,t,e,r,n,o))}),f;if(lf(n))return n.forEach(function(r,u){f.set(u,_t(r,t,e,u,n,o))}),f;var a=l?a?ve:_e:a?Wu:zu,p=u?T:a(n);return r(p||n,function(r,u){p&&(u=r,r=n[u]),ot(f,u,_t(r,t,e,u,n,o))}),f}function vt(n){var t=zu(n);return function(r){return gt(r,n,t)}}function gt(n,t,r){var e=r.length;if(null==n)return!e;for(n=Yu(n);e--;){var u=r[e],i=t[u],o=n[u];if(o===T&&!(u in n)||!i(o))return false}return true}function dt(n,t,r){if(typeof n!="function")throw new ni("Expected a function"); +return yo(function(){n.apply(T,r)},t)}function yt(n,t,r,e){var u=-1,i=o,a=true,l=n.length,s=[],h=t.length;if(!l)return s;r&&(t=c(t,k(r))),e?(i=f,a=false):200<=t.length&&(i=O,a=false,t=new Nn(t));n:for(;++ut}function Rt(n,t){return null!=n&&ii.call(n,t)}function zt(n,t){return null!=n&&t in Yu(n)}function Wt(n,t,r){for(var e=r?f:o,u=n[0].length,i=n.length,a=i,l=Vu(i),s=1/0,h=[];a--;){var p=n[a];a&&t&&(p=c(p,k(t))),s=Ui(p.length,s), +l[a]=!r&&(t||120<=u&&120<=p.length)?new Nn(a&&p):T}var p=n[0],_=-1,v=l[0];n:for(;++_r.length?t:kt(t,hr(r,0,-1)),r=null==t?t:t[De(qe(r))],null==r?T:n(r,t,e)}function Ut(n){return du(n)&&"[object Arguments]"==Ot(n)}function Ct(n){ +return du(n)&&"[object ArrayBuffer]"==Ot(n)}function Dt(n){return du(n)&&"[object Date]"==Ot(n)}function Mt(n,t,r,e,u){if(n===t)t=true;else if(null==n||null==t||!du(n)&&!du(t))t=n!==n&&t!==t;else n:{var i=of(n),o=of(t),f=i?"[object Array]":_o(n),c=o?"[object Array]":_o(t),f="[object Arguments]"==f?"[object Object]":f,c="[object Arguments]"==c?"[object Object]":c,a="[object Object]"==f,o="[object Object]"==c;if((c=f==c)&&cf(n)){if(!cf(t)){t=false;break n}i=true,a=false}if(c&&!a)u||(u=new Zn),t=i||pf(n)?se(n,t,r,e,Mt,u):he(n,t,f,r,e,Mt,u);else{ +if(!(1&r)&&(i=a&&ii.call(n,"__wrapped__"),f=o&&ii.call(t,"__wrapped__"),i||f)){n=i?n.value():n,t=f?t.value():t,u||(u=new Zn),t=Mt(n,t,r,e,u);break n}if(c)t:if(u||(u=new Zn),i=1&r,f=_e(n),o=f.length,c=_e(t).length,o==c||i){for(a=o;a--;){var l=f[a];if(!(i?l in t:ii.call(t,l))){t=false;break t}}if((c=u.get(n))&&u.get(t))t=c==t;else{c=true,u.set(n,t),u.set(t,n);for(var s=i;++at?r:0,Se(t,r)?n[t]:T}function Xt(n,t,r){var e=-1;return t=c(t.length?t:[Tu],k(ye())), +n=Gt(n,function(n){return{a:c(t,function(t){return t(n)}),b:++e,c:n}}),w(n,function(n,t){var e;n:{e=-1;for(var u=n.a,i=t.a,o=u.length,f=r.length;++e=f?c:c*("desc"==r[e]?-1:1);break n}}e=n.b-t.b}return e})}function nr(n,t){return tr(n,t,function(t,r){return Ru(n,r)})}function tr(n,t,r){for(var e=-1,u=t.length,i={};++et||9007199254740991t&&(t=-t>u?0:u+t),r=r>u?u:r,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Vu(u);++e=u){for(;e>>1,o=n[i];null!==o&&!ju(o)&&(r?o<=t:ot.length?n:kt(n,hr(t,0,-1)),null==n||delete n[De(qe(t))]}function jr(n,t,r,e){for(var u=n.length,i=e?u:-1;(e?i--:++ie)return e?br(n[0]):[];for(var u=-1,i=Vu(e);++u=e?n:hr(n,t,r)}function Ir(n,t){if(t)return n.slice();var r=n.length,r=vi?vi(r):new n.constructor(r);return n.copy(r),r}function Rr(n){var t=new n.constructor(n.byteLength);return new _i(t).set(new _i(n)), +t}function zr(n,t){return new n.constructor(t?Rr(n.buffer):n.buffer,n.byteOffset,n.length)}function Wr(n,t){if(n!==t){var r=n!==T,e=null===n,u=n===n,i=ju(n),o=t!==T,f=null===t,c=t===t,a=ju(t);if(!f&&!a&&!i&&n>t||i&&o&&c&&!f&&!a||e&&o&&c||!r&&c||!u)return 1;if(!e&&!i&&!a&&nu?T:i,u=1),t=Yu(t);++eo&&f[0]!==a&&f[o-1]!==a?[]:L(f,a), +o-=c.length,or?r?or(t,n):t:(r=or(t,Si(n/D(t))),Rn.test(t)?Or(M(r),0,n).join(""):r.slice(0,n))}function te(t,r,e,u){function i(){for(var r=-1,c=arguments.length,a=-1,l=u.length,s=Vu(l+c),h=this&&this!==$n&&this instanceof i?f:t;++at||e)&&(1&n&&(i[2]=h[2],t|=1&r?0:4),(r=h[3])&&(e=i[3],i[3]=e?Br(e,r,h[4]):r,i[4]=e?L(i[3],"__lodash_placeholder__"):h[4]),(r=h[5])&&(e=i[5],i[5]=e?Lr(e,r,h[6]):r,i[6]=e?L(i[5],"__lodash_placeholder__"):h[6]),(r=h[7])&&(i[7]=r),128&n&&(i[8]=null==i[8]?h[8]:Ui(i[8],h[8])),null==i[9]&&(i[9]=h[9]),i[0]=h[0],i[1]=t),n=i[0],t=i[1], +r=i[2],e=i[3],u=i[4],f=i[9]=i[9]===T?c?0:n.length:Li(i[9]-a,0),!f&&24&t&&(t&=-25),Le((h?fo:go)(t&&1!=t?8==t||16==t?Kr(n,t,f):32!=t&&33!=t||u.length?Jr.apply(T,i):te(n,t,r,e):Pr(n,t,r),i),n,t)}function ce(n,t,r,e){return n===T||au(n,ri[r])&&!ii.call(e,r)?t:n}function ae(n,t,r,e,u,i){return gu(n)&&gu(t)&&(i.set(t,n),Yt(n,t,T,ae,i),i.delete(t)),n}function le(n){return bu(n)?T:n}function se(n,t,r,e,u,i){var o=1&r,f=n.length,c=t.length;if(f!=c&&!(o&&c>f))return false;if((c=i.get(n))&&i.get(t))return c==t;var c=-1,a=true,l=2&r?new Nn:T; +for(i.set(n,t),i.set(t,n);++cr&&(r=Li(e+r,0)),_(n,ye(t,3),r)):-1}function Ne(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e-1;return r!==T&&(u=Au(r),u=0>r?Li(e+u,0):Ui(u,e-1)),_(n,ye(t,3),u,true)}function Pe(n){return(null==n?0:n.length)?wt(n,1):[]}function Ze(n){ +return n&&n.length?n[0]:T}function qe(n){var t=null==n?0:n.length;return t?n[t-1]:T}function Ve(n,t){return n&&n.length&&t&&t.length?er(n,t):n}function Ke(n){return null==n?n:Ti.call(n)}function Ge(n){if(!n||!n.length)return[];var t=0;return n=i(n,function(n){if(su(n))return t=Li(n.length,t),true}),A(t,function(t){return c(n,b(t))})}function He(t,r){if(!t||!t.length)return[];var e=Ge(t);return null==r?e:c(e,function(t){return n(r,T,t)})}function Je(n){return n=An(n),n.__chain__=true,n}function Ye(n,t){ +return t(n)}function Qe(){return this}function Xe(n,t){return(of(n)?r:eo)(n,ye(t,3))}function nu(n,t){return(of(n)?e:uo)(n,ye(t,3))}function tu(n,t){return(of(n)?c:Gt)(n,ye(t,3))}function ru(n,t,r){return t=r?T:t,t=n&&null==t?n.length:t,fe(n,128,T,T,T,T,t)}function eu(n,t){var r;if(typeof t!="function")throw new ni("Expected a function");return n=Au(n),function(){return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=T),r}}function uu(n,t,r){return t=r?T:t,n=fe(n,8,T,T,T,T,T,t),n.placeholder=uu.placeholder, +n}function iu(n,t,r){return t=r?T:t,n=fe(n,16,T,T,T,T,T,t),n.placeholder=iu.placeholder,n}function ou(n,t,r){function e(t){var r=c,e=a;return c=a=T,_=t,s=n.apply(e,r)}function u(n){var r=n-p;return n-=_,p===T||r>=t||0>r||g&&n>=l}function i(){var n=Ko();if(u(n))return o(n);var r,e=yo;r=n-_,n=t-(n-p),r=g?Ui(n,l-r):n,h=e(i,r)}function o(n){return h=T,d&&c?e(n):(c=a=T,s)}function f(){var n=Ko(),r=u(n);if(c=arguments,a=this,p=n,r){if(h===T)return _=n=p,h=yo(i,t),v?e(n):s;if(g)return h=yo(i,t),e(p)}return h===T&&(h=yo(i,t)), +s}var c,a,l,s,h,p,_=0,v=false,g=false,d=true;if(typeof n!="function")throw new ni("Expected a function");return t=ku(t)||0,gu(r)&&(v=!!r.leading,l=(g="maxWait"in r)?Li(ku(r.maxWait)||0,t):l,d="trailing"in r?!!r.trailing:d),f.cancel=function(){h!==T&&ao(h),_=0,c=p=a=h=T},f.flush=function(){return h===T?s:o(Ko())},f}function fu(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;return i.has(u)?i.get(u):(e=n.apply(this,e),r.cache=i.set(u,e)||i,e)}if(typeof n!="function"||null!=t&&typeof t!="function")throw new ni("Expected a function"); +return r.cache=new(fu.Cache||Fn),r}function cu(n){if(typeof n!="function")throw new ni("Expected a function");return function(){var t=arguments;switch(t.length){case 0:return!n.call(this);case 1:return!n.call(this,t[0]);case 2:return!n.call(this,t[0],t[1]);case 3:return!n.call(this,t[0],t[1],t[2])}return!n.apply(this,t)}}function au(n,t){return n===t||n!==n&&t!==t}function lu(n){return null!=n&&vu(n.length)&&!pu(n)}function su(n){return du(n)&&lu(n)}function hu(n){if(!du(n))return false;var t=Ot(n);return"[object Error]"==t||"[object DOMException]"==t||typeof n.message=="string"&&typeof n.name=="string"&&!bu(n); +}function pu(n){return!!gu(n)&&(n=Ot(n),"[object Function]"==n||"[object GeneratorFunction]"==n||"[object AsyncFunction]"==n||"[object Proxy]"==n)}function _u(n){return typeof n=="number"&&n==Au(n)}function vu(n){return typeof n=="number"&&-1=n}function gu(n){var t=typeof n;return null!=n&&("object"==t||"function"==t)}function du(n){return null!=n&&typeof n=="object"}function yu(n){return typeof n=="number"||du(n)&&"[object Number]"==Ot(n)}function bu(n){return!(!du(n)||"[object Object]"!=Ot(n))&&(n=gi(n), +null===n||(n=ii.call(n,"constructor")&&n.constructor,typeof n=="function"&&n instanceof n&&ui.call(n)==ai))}function xu(n){return typeof n=="string"||!of(n)&&du(n)&&"[object String]"==Ot(n)}function ju(n){return typeof n=="symbol"||du(n)&&"[object Symbol]"==Ot(n)}function wu(n){if(!n)return[];if(lu(n))return xu(n)?M(n):Ur(n);if(ji&&n[ji]){n=n[ji]();for(var t,r=[];!(t=n.next()).done;)r.push(t.value);return r}return t=_o(n),("[object Map]"==t?W:"[object Set]"==t?U:Lu)(n)}function mu(n){return n?(n=ku(n), +n===$||n===-$?1.7976931348623157e308*(0>n?-1:1):n===n?n:0):0===n?n:0}function Au(n){n=mu(n);var t=n%1;return n===n?t?n-t:n:0}function Eu(n){return n?pt(Au(n),0,4294967295):0}function ku(n){if(typeof n=="number")return n;if(ju(n))return F;if(gu(n)&&(n=typeof n.valueOf=="function"?n.valueOf():n,n=gu(n)?n+"":n),typeof n!="string")return 0===n?n:+n;n=n.replace(un,"");var t=gn.test(n);return t||yn.test(n)?Dn(n.slice(2),t?2:8):vn.test(n)?F:+n}function Su(n){return Cr(n,Wu(n))}function Ou(n){return null==n?"":yr(n); +}function Iu(n,t,r){return n=null==n?T:kt(n,t),n===T?r:n}function Ru(n,t){return null!=n&&we(n,t,zt)}function zu(n){return lu(n)?qn(n):Vt(n)}function Wu(n){if(lu(n))n=qn(n,true);else if(gu(n)){var t,r=ze(n),e=[];for(t in n)("constructor"!=t||!r&&ii.call(n,t))&&e.push(t);n=e}else{if(t=[],null!=n)for(r in Yu(n))t.push(r);n=t}return n}function Bu(n,t){if(null==n)return{};var r=c(ve(n),function(n){return[n]});return t=ye(t),tr(n,r,function(n,r){return t(n,r[0])})}function Lu(n){return null==n?[]:S(n,zu(n)); +}function Uu(n){return Tf(Ou(n).toLowerCase())}function Cu(n){return(n=Ou(n))&&n.replace(xn,Xn).replace(Sn,"")}function Du(n,t,r){return n=Ou(n),t=r?T:t,t===T?zn.test(n)?n.match(In)||[]:n.match(sn)||[]:n.match(t)||[]}function Mu(n){return function(){return n}}function Tu(n){return n}function $u(n){return qt(typeof n=="function"?n:_t(n,1))}function Fu(n,t,e){var u=zu(t),i=Et(t,u);null!=e||gu(t)&&(i.length||!u.length)||(e=t,t=n,n=this,i=Et(t,zu(t)));var o=!(gu(e)&&"chain"in e&&!e.chain),f=pu(n);return r(i,function(r){ +var e=t[r];n[r]=e,f&&(n.prototype[r]=function(){var t=this.__chain__;if(o||t){var r=n(this.__wrapped__);return(r.__actions__=Ur(this.__actions__)).push({func:e,args:arguments,thisArg:n}),r.__chain__=t,r}return e.apply(n,a([this.value()],arguments))})}),n}function Nu(){}function Pu(n){return Ie(n)?b(De(n)):rr(n)}function Zu(){return[]}function qu(){return false}mn=null==mn?$n:rt.defaults($n.Object(),mn,rt.pick($n,Wn));var Vu=mn.Array,Ku=mn.Date,Gu=mn.Error,Hu=mn.Function,Ju=mn.Math,Yu=mn.Object,Qu=mn.RegExp,Xu=mn.String,ni=mn.TypeError,ti=Vu.prototype,ri=Yu.prototype,ei=mn["__core-js_shared__"],ui=Hu.prototype.toString,ii=ri.hasOwnProperty,oi=0,fi=function(){ +var n=/[^.]+$/.exec(ei&&ei.keys&&ei.keys.IE_PROTO||"");return n?"Symbol(src)_1."+n:""}(),ci=ri.toString,ai=ui.call(Yu),li=$n._,si=Qu("^"+ui.call(ii).replace(rn,"\\$&").replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),hi=Pn?mn.Buffer:T,pi=mn.Symbol,_i=mn.Uint8Array,vi=hi?hi.g:T,gi=B(Yu.getPrototypeOf,Yu),di=Yu.create,yi=ri.propertyIsEnumerable,bi=ti.splice,xi=pi?pi.isConcatSpreadable:T,ji=pi?pi.iterator:T,wi=pi?pi.toStringTag:T,mi=function(){try{var n=je(Yu,"defineProperty"); +return n({},"",{}),n}catch(n){}}(),Ai=mn.clearTimeout!==$n.clearTimeout&&mn.clearTimeout,Ei=Ku&&Ku.now!==$n.Date.now&&Ku.now,ki=mn.setTimeout!==$n.setTimeout&&mn.setTimeout,Si=Ju.ceil,Oi=Ju.floor,Ii=Yu.getOwnPropertySymbols,Ri=hi?hi.isBuffer:T,zi=mn.isFinite,Wi=ti.join,Bi=B(Yu.keys,Yu),Li=Ju.max,Ui=Ju.min,Ci=Ku.now,Di=mn.parseInt,Mi=Ju.random,Ti=ti.reverse,$i=je(mn,"DataView"),Fi=je(mn,"Map"),Ni=je(mn,"Promise"),Pi=je(mn,"Set"),Zi=je(mn,"WeakMap"),qi=je(Yu,"create"),Vi=Zi&&new Zi,Ki={},Gi=Me($i),Hi=Me(Fi),Ji=Me(Ni),Yi=Me(Pi),Qi=Me(Zi),Xi=pi?pi.prototype:T,no=Xi?Xi.valueOf:T,to=Xi?Xi.toString:T,ro=function(){ +function n(){}return function(t){return gu(t)?di?di(t):(n.prototype=t,t=new n,n.prototype=T,t):{}}}();An.templateSettings={escape:J,evaluate:Y,interpolate:Q,variable:"",imports:{_:An}},An.prototype=En.prototype,An.prototype.constructor=An,On.prototype=ro(En.prototype),On.prototype.constructor=On,Un.prototype=ro(En.prototype),Un.prototype.constructor=Un,Mn.prototype.clear=function(){this.__data__=qi?qi(null):{},this.size=0},Mn.prototype.delete=function(n){return n=this.has(n)&&delete this.__data__[n], +this.size-=n?1:0,n},Mn.prototype.get=function(n){var t=this.__data__;return qi?(n=t[n],"__lodash_hash_undefined__"===n?T:n):ii.call(t,n)?t[n]:T},Mn.prototype.has=function(n){var t=this.__data__;return qi?t[n]!==T:ii.call(t,n)},Mn.prototype.set=function(n,t){var r=this.__data__;return this.size+=this.has(n)?0:1,r[n]=qi&&t===T?"__lodash_hash_undefined__":t,this},Tn.prototype.clear=function(){this.__data__=[],this.size=0},Tn.prototype.delete=function(n){var t=this.__data__;return n=ft(t,n),!(0>n)&&(n==t.length-1?t.pop():bi.call(t,n,1), +--this.size,true)},Tn.prototype.get=function(n){var t=this.__data__;return n=ft(t,n),0>n?T:t[n][1]},Tn.prototype.has=function(n){return-1e?(++this.size,r.push([n,t])):r[e][1]=t,this},Fn.prototype.clear=function(){this.size=0,this.__data__={hash:new Mn,map:new(Fi||Tn),string:new Mn}},Fn.prototype.delete=function(n){return n=be(this,n).delete(n),this.size-=n?1:0,n},Fn.prototype.get=function(n){return be(this,n).get(n); +},Fn.prototype.has=function(n){return be(this,n).has(n)},Fn.prototype.set=function(n,t){var r=be(this,n),e=r.size;return r.set(n,t),this.size+=r.size==e?0:1,this},Nn.prototype.add=Nn.prototype.push=function(n){return this.__data__.set(n,"__lodash_hash_undefined__"),this},Nn.prototype.has=function(n){return this.__data__.has(n)},Zn.prototype.clear=function(){this.__data__=new Tn,this.size=0},Zn.prototype.delete=function(n){var t=this.__data__;return n=t.delete(n),this.size=t.size,n},Zn.prototype.get=function(n){ +return this.__data__.get(n)},Zn.prototype.has=function(n){return this.__data__.has(n)},Zn.prototype.set=function(n,t){var r=this.__data__;if(r instanceof Tn){var e=r.__data__;if(!Fi||199>e.length)return e.push([n,t]),this.size=++r.size,this;r=this.__data__=new Fn(e)}return r.set(n,t),this.size=r.size,this};var eo=Fr(mt),uo=Fr(At,true),io=Nr(),oo=Nr(true),fo=Vi?function(n,t){return Vi.set(n,t),n}:Tu,co=mi?function(n,t){return mi(n,"toString",{configurable:true,enumerable:false,value:Mu(t),writable:true})}:Tu,ao=Ai||function(n){ +return $n.clearTimeout(n)},lo=Pi&&1/U(new Pi([,-0]))[1]==$?function(n){return new Pi(n)}:Nu,so=Vi?function(n){return Vi.get(n)}:Nu,ho=Ii?function(n){return null==n?[]:(n=Yu(n),i(Ii(n),function(t){return yi.call(n,t)}))}:Zu,po=Ii?function(n){for(var t=[];n;)a(t,ho(n)),n=gi(n);return t}:Zu,_o=Ot;($i&&"[object DataView]"!=_o(new $i(new ArrayBuffer(1)))||Fi&&"[object Map]"!=_o(new Fi)||Ni&&"[object Promise]"!=_o(Ni.resolve())||Pi&&"[object Set]"!=_o(new Pi)||Zi&&"[object WeakMap]"!=_o(new Zi))&&(_o=function(n){ +var t=Ot(n);if(n=(n="[object Object]"==t?n.constructor:T)?Me(n):"")switch(n){case Gi:return"[object DataView]";case Hi:return"[object Map]";case Ji:return"[object Promise]";case Yi:return"[object Set]";case Qi:return"[object WeakMap]"}return t});var vo=ei?pu:qu,go=Ue(fo),yo=ki||function(n,t){return $n.setTimeout(n,t)},bo=Ue(co),xo=function(n){n=fu(n,function(n){return 500===t.size&&t.clear(),n});var t=n.cache;return n}(function(n){var t=[];return 46===n.charCodeAt(0)&&t.push(""),n.replace(tn,function(n,r,e,u){ +t.push(e?u.replace(hn,"$1"):r||n)}),t}),jo=fr(function(n,t){return su(n)?yt(n,wt(t,1,su,true)):[]}),wo=fr(function(n,t){var r=qe(t);return su(r)&&(r=T),su(n)?yt(n,wt(t,1,su,true),ye(r,2)):[]}),mo=fr(function(n,t){var r=qe(t);return su(r)&&(r=T),su(n)?yt(n,wt(t,1,su,true),T,r):[]}),Ao=fr(function(n){var t=c(n,Er);return t.length&&t[0]===n[0]?Wt(t):[]}),Eo=fr(function(n){var t=qe(n),r=c(n,Er);return t===qe(r)?t=T:r.pop(),r.length&&r[0]===n[0]?Wt(r,ye(t,2)):[]}),ko=fr(function(n){var t=qe(n),r=c(n,Er);return(t=typeof t=="function"?t:T)&&r.pop(), +r.length&&r[0]===n[0]?Wt(r,T,t):[]}),So=fr(Ve),Oo=pe(function(n,t){var r=null==n?0:n.length,e=ht(n,t);return ur(n,c(t,function(n){return Se(n,r)?+n:n}).sort(Wr)),e}),Io=fr(function(n){return br(wt(n,1,su,true))}),Ro=fr(function(n){var t=qe(n);return su(t)&&(t=T),br(wt(n,1,su,true),ye(t,2))}),zo=fr(function(n){var t=qe(n),t=typeof t=="function"?t:T;return br(wt(n,1,su,true),T,t)}),Wo=fr(function(n,t){return su(n)?yt(n,t):[]}),Bo=fr(function(n){return mr(i(n,su))}),Lo=fr(function(n){var t=qe(n);return su(t)&&(t=T), +mr(i(n,su),ye(t,2))}),Uo=fr(function(n){var t=qe(n),t=typeof t=="function"?t:T;return mr(i(n,su),T,t)}),Co=fr(Ge),Do=fr(function(n){var t=n.length,t=1=t}),uf=Ut(function(){return arguments}())?Ut:function(n){return du(n)&&ii.call(n,"callee")&&!yi.call(n,"callee")},of=Vu.isArray,ff=Vn?k(Vn):Ct,cf=Ri||qu,af=Kn?k(Kn):Dt,lf=Gn?k(Gn):Tt,sf=Hn?k(Hn):Nt,hf=Jn?k(Jn):Pt,pf=Yn?k(Yn):Zt,_f=ee(Kt),vf=ee(function(n,t){return n<=t}),gf=$r(function(n,t){ +if(ze(t)||lu(t))Cr(t,zu(t),n);else for(var r in t)ii.call(t,r)&&ot(n,r,t[r])}),df=$r(function(n,t){Cr(t,Wu(t),n)}),yf=$r(function(n,t,r,e){Cr(t,Wu(t),n,e)}),bf=$r(function(n,t,r,e){Cr(t,zu(t),n,e)}),xf=pe(ht),jf=fr(function(n,t){n=Yu(n);var r=-1,e=t.length,u=2--n)return t.apply(this,arguments)}},An.ary=ru,An.assign=gf,An.assignIn=df,An.assignInWith=yf,An.assignWith=bf,An.at=xf,An.before=eu,An.bind=Go,An.bindAll=Ff,An.bindKey=Ho,An.castArray=function(){if(!arguments.length)return[];var n=arguments[0];return of(n)?n:[n]},An.chain=Je,An.chunk=function(n,t,r){if(t=(r?Oe(n,t,r):t===T)?1:Li(Au(t),0),r=null==n?0:n.length,!r||1>t)return[];for(var e=0,u=0,i=Vu(Si(r/t));et?0:t,e)):[]},An.dropRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Au(t),t=e-t,hr(n,0,0>t?0:t)):[]},An.dropRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true,true):[]; +},An.dropWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),true):[]},An.fill=function(n,t,r,e){var u=null==n?0:n.length;if(!u)return[];for(r&&typeof r!="number"&&Oe(n,t,r)&&(r=0,e=u),u=n.length,r=Au(r),0>r&&(r=-r>u?0:u+r),e=e===T||e>u?u:Au(e),0>e&&(e+=u),e=r>e?0:Eu(e);r>>0,r?(n=Ou(n))&&(typeof t=="string"||null!=t&&!sf(t))&&(t=yr(t),!t&&Rn.test(n))?Or(M(n),0,r):n.split(t,r):[]},An.spread=function(t,r){if(typeof t!="function")throw new ni("Expected a function");return r=null==r?0:Li(Au(r),0), +fr(function(e){var u=e[r];return e=Or(e,0,r),u&&a(e,u),n(t,this,e)})},An.tail=function(n){var t=null==n?0:n.length;return t?hr(n,1,t):[]},An.take=function(n,t,r){return n&&n.length?(t=r||t===T?1:Au(t),hr(n,0,0>t?0:t)):[]},An.takeRight=function(n,t,r){var e=null==n?0:n.length;return e?(t=r||t===T?1:Au(t),t=e-t,hr(n,0>t?0:t,e)):[]},An.takeRightWhile=function(n,t){return n&&n.length?jr(n,ye(t,3),false,true):[]},An.takeWhile=function(n,t){return n&&n.length?jr(n,ye(t,3)):[]},An.tap=function(n,t){return t(n), +n},An.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new ni("Expected a function");return gu(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),ou(n,t,{leading:e,maxWait:t,trailing:u})},An.thru=Ye,An.toArray=wu,An.toPairs=Rf,An.toPairsIn=zf,An.toPath=function(n){return of(n)?c(n,De):ju(n)?[n]:Ur(xo(Ou(n)))},An.toPlainObject=Su,An.transform=function(n,t,e){var u=of(n),i=u||cf(n)||pf(n);if(t=ye(t,4),null==e){var o=n&&n.constructor;e=i?u?new o:[]:gu(n)&&pu(o)?ro(gi(n)):{}; +}return(i?r:mt)(n,function(n,r,u){return t(e,n,r,u)}),e},An.unary=function(n){return ru(n,1)},An.union=Io,An.unionBy=Ro,An.unionWith=zo,An.uniq=function(n){return n&&n.length?br(n):[]},An.uniqBy=function(n,t){return n&&n.length?br(n,ye(t,2)):[]},An.uniqWith=function(n,t){return t=typeof t=="function"?t:T,n&&n.length?br(n,T,t):[]},An.unset=function(n,t){return null==n||xr(n,t)},An.unzip=Ge,An.unzipWith=He,An.update=function(n,t,r){return null==n?n:lr(n,t,kr(r)(kt(n,t)),void 0)},An.updateWith=function(n,t,r,e){ +return e=typeof e=="function"?e:T,null!=n&&(n=lr(n,t,kr(r)(kt(n,t)),e)),n},An.values=Lu,An.valuesIn=function(n){return null==n?[]:S(n,Wu(n))},An.without=Wo,An.words=Du,An.wrap=function(n,t){return Xo(kr(t),n)},An.xor=Bo,An.xorBy=Lo,An.xorWith=Uo,An.zip=Co,An.zipObject=function(n,t){return Ar(n||[],t||[],ot)},An.zipObjectDeep=function(n,t){return Ar(n||[],t||[],lr)},An.zipWith=Do,An.entries=Rf,An.entriesIn=zf,An.extend=df,An.extendWith=yf,Fu(An,An),An.add=Yf,An.attempt=$f,An.camelCase=Wf,An.capitalize=Uu, +An.ceil=Qf,An.clamp=function(n,t,r){return r===T&&(r=t,t=T),r!==T&&(r=ku(r),r=r===r?r:0),t!==T&&(t=ku(t),t=t===t?t:0),pt(ku(n),t,r)},An.clone=function(n){return _t(n,4)},An.cloneDeep=function(n){return _t(n,5)},An.cloneDeepWith=function(n,t){return t=typeof t=="function"?t:T,_t(n,5,t)},An.cloneWith=function(n,t){return t=typeof t=="function"?t:T,_t(n,4,t)},An.conformsTo=function(n,t){return null==t||gt(n,t,zu(t))},An.deburr=Cu,An.defaultTo=function(n,t){return null==n||n!==n?t:n},An.divide=Xf,An.endsWith=function(n,t,r){ +n=Ou(n),t=yr(t);var e=n.length,e=r=r===T?e:pt(Au(r),0,e);return r-=t.length,0<=r&&n.slice(r,e)==t},An.eq=au,An.escape=function(n){return(n=Ou(n))&&H.test(n)?n.replace(K,nt):n},An.escapeRegExp=function(n){return(n=Ou(n))&&en.test(n)?n.replace(rn,"\\$&"):n},An.every=function(n,t,r){var e=of(n)?u:bt;return r&&Oe(n,t,r)&&(t=T),e(n,ye(t,3))},An.find=$o,An.findIndex=Fe,An.findKey=function(n,t){return p(n,ye(t,3),mt)},An.findLast=Fo,An.findLastIndex=Ne,An.findLastKey=function(n,t){return p(n,ye(t,3),At); +},An.floor=nc,An.forEach=Xe,An.forEachRight=nu,An.forIn=function(n,t){return null==n?n:io(n,ye(t,3),Wu)},An.forInRight=function(n,t){return null==n?n:oo(n,ye(t,3),Wu)},An.forOwn=function(n,t){return n&&mt(n,ye(t,3))},An.forOwnRight=function(n,t){return n&&At(n,ye(t,3))},An.get=Iu,An.gt=rf,An.gte=ef,An.has=function(n,t){return null!=n&&we(n,t,Rt)},An.hasIn=Ru,An.head=Ze,An.identity=Tu,An.includes=function(n,t,r,e){return n=lu(n)?n:Lu(n),r=r&&!e?Au(r):0,e=n.length,0>r&&(r=Li(e+r,0)),xu(n)?r<=e&&-1r&&(r=Li(e+r,0)),v(n,t,r)):-1},An.inRange=function(n,t,r){return t=mu(t),r===T?(r=t,t=0):r=mu(r),n=ku(n),n>=Ui(t,r)&&n=n},An.isSet=hf,An.isString=xu,An.isSymbol=ju,An.isTypedArray=pf,An.isUndefined=function(n){return n===T},An.isWeakMap=function(n){return du(n)&&"[object WeakMap]"==_o(n)},An.isWeakSet=function(n){return du(n)&&"[object WeakSet]"==Ot(n)},An.join=function(n,t){return null==n?"":Wi.call(n,t)},An.kebabCase=Bf,An.last=qe,An.lastIndexOf=function(n,t,r){var e=null==n?0:n.length;if(!e)return-1;var u=e;if(r!==T&&(u=Au(r),u=0>u?Li(e+u,0):Ui(u,e-1)), +t===t){for(r=u+1;r--&&n[r]!==t;);n=r}else n=_(n,d,u,true);return n},An.lowerCase=Lf,An.lowerFirst=Uf,An.lt=_f,An.lte=vf,An.max=function(n){return n&&n.length?xt(n,Tu,It):T},An.maxBy=function(n,t){return n&&n.length?xt(n,ye(t,2),It):T},An.mean=function(n){return y(n,Tu)},An.meanBy=function(n,t){return y(n,ye(t,2))},An.min=function(n){return n&&n.length?xt(n,Tu,Kt):T},An.minBy=function(n,t){return n&&n.length?xt(n,ye(t,2),Kt):T},An.stubArray=Zu,An.stubFalse=qu,An.stubObject=function(){return{}},An.stubString=function(){ +return""},An.stubTrue=function(){return true},An.multiply=tc,An.nth=function(n,t){return n&&n.length?Qt(n,Au(t)):T},An.noConflict=function(){return $n._===this&&($n._=li),this},An.noop=Nu,An.now=Ko,An.pad=function(n,t,r){n=Ou(n);var e=(t=Au(t))?D(n):0;return!t||e>=t?n:(t=(t-e)/2,ne(Oi(t),r)+n+ne(Si(t),r))},An.padEnd=function(n,t,r){n=Ou(n);var e=(t=Au(t))?D(n):0;return t&&et){var e=n;n=t,t=e}return r||n%1||t%1?(r=Mi(),Ui(n+r*(t-n+Cn("1e-"+((r+"").length-1))),t)):ir(n,t)},An.reduce=function(n,t,r){var e=of(n)?l:j,u=3>arguments.length;return e(n,ye(t,4),r,u,eo)},An.reduceRight=function(n,t,r){var e=of(n)?s:j,u=3>arguments.length; +return e(n,ye(t,4),r,u,uo)},An.repeat=function(n,t,r){return t=(r?Oe(n,t,r):t===T)?1:Au(t),or(Ou(n),t)},An.replace=function(){var n=arguments,t=Ou(n[0]);return 3>n.length?t:t.replace(n[1],n[2])},An.result=function(n,t,r){t=Sr(t,n);var e=-1,u=t.length;for(u||(u=1,n=T);++en||9007199254740991=i)return n;if(i=r-D(e),1>i)return e;if(r=o?Or(o,0,i).join(""):n.slice(0,i),u===T)return r+e;if(o&&(i+=r.length-i),sf(u)){if(n.slice(i).search(u)){var f=r;for(u.global||(u=Qu(u.source,Ou(_n.exec(u))+"g")), +u.lastIndex=0;o=u.exec(f);)var c=o.index;r=r.slice(0,c===T?i:c)}}else n.indexOf(yr(u),i)!=i&&(u=r.lastIndexOf(u),-1e.__dir__?"Right":"")}),e},Un.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse()}}),r(["filter","map","takeWhile"],function(n,t){var r=t+1,e=1==r||3==r;Un.prototype[n]=function(n){var t=this.clone();return t.__iteratees__.push({ +iteratee:ye(n,3),type:r}),t.__filtered__=t.__filtered__||e,t}}),r(["head","last"],function(n,t){var r="take"+(t?"Right":"");Un.prototype[n]=function(){return this[r](1).value()[0]}}),r(["initial","tail"],function(n,t){var r="drop"+(t?"":"Right");Un.prototype[n]=function(){return this.__filtered__?new Un(this):this[r](1)}}),Un.prototype.compact=function(){return this.filter(Tu)},Un.prototype.find=function(n){return this.filter(n).head()},Un.prototype.findLast=function(n){return this.reverse().find(n); +},Un.prototype.invokeMap=fr(function(n,t){return typeof n=="function"?new Un(this):this.map(function(r){return Lt(r,n,t)})}),Un.prototype.reject=function(n){return this.filter(cu(ye(n)))},Un.prototype.slice=function(n,t){n=Au(n);var r=this;return r.__filtered__&&(0t)?new Un(r):(0>n?r=r.takeRight(-n):n&&(r=r.drop(n)),t!==T&&(t=Au(t),r=0>t?r.dropRight(-t):r.take(t-n)),r)},Un.prototype.takeRightWhile=function(n){return this.reverse().takeWhile(n).reverse()},Un.prototype.toArray=function(){return this.take(4294967295); +},mt(Un.prototype,function(n,t){var r=/^(?:filter|find|map|reject)|While$/.test(t),e=/^(?:head|last)$/.test(t),u=An[e?"take"+("last"==t?"Right":""):t],i=e||/^find/.test(t);u&&(An.prototype[t]=function(){function t(n){return n=u.apply(An,a([n],f)),e&&h?n[0]:n}var o=this.__wrapped__,f=e?[1]:arguments,c=o instanceof Un,l=f[0],s=c||of(o);s&&r&&typeof l=="function"&&1!=l.length&&(c=s=false);var h=this.__chain__,p=!!this.__actions__.length,l=i&&!h,c=c&&!p;return!i&&s?(o=c?o:new Un(this),o=n.apply(o,f),o.__actions__.push({ +func:Ye,args:[t],thisArg:T}),new On(o,h)):l&&c?n.apply(this,f):(o=this.thru(t),l?e?o.value()[0]:o.value():o)})}),r("pop push shift sort splice unshift".split(" "),function(n){var t=ti[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:pop|shift)$/.test(n);An.prototype[n]=function(){var n=arguments;if(e&&!this.__chain__){var u=this.value();return t.apply(of(u)?u:[],n)}return this[r](function(r){return t.apply(of(r)?r:[],n)})}}),mt(Un.prototype,function(n,t){var r=An[t];if(r){var e=r.name+""; +(Ki[e]||(Ki[e]=[])).push({name:t,func:r})}}),Ki[Jr(T,2).name]=[{name:"wrapper",func:T}],Un.prototype.clone=function(){var n=new Un(this.__wrapped__);return n.__actions__=Ur(this.__actions__),n.__dir__=this.__dir__,n.__filtered__=this.__filtered__,n.__iteratees__=Ur(this.__iteratees__),n.__takeCount__=this.__takeCount__,n.__views__=Ur(this.__views__),n},Un.prototype.reverse=function(){if(this.__filtered__){var n=new Un(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n; +},Un.prototype.value=function(){var n,t=this.__wrapped__.value(),r=this.__dir__,e=of(t),u=0>r,i=e?t.length:0;n=i;for(var o=this.__views__,f=0,c=-1,a=o.length;++c=this.__values__.length;return{done:n,value:n?T:this.__values__[this.__index__++]}},An.prototype.plant=function(n){for(var t,r=this;r instanceof En;){ +var e=$e(r);e.__index__=0,e.__values__=T,t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},An.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Un?(this.__actions__.length&&(n=new Un(this)),n=n.reverse(),n.__actions__.push({func:Ye,args:[Ke],thisArg:T}),new On(n,this.__chain__)):this.thru(Ke)},An.prototype.toJSON=An.prototype.valueOf=An.prototype.value=function(){return wr(this.__wrapped__,this.__actions__)},An.prototype.first=An.prototype.head,ji&&(An.prototype[ji]=Qe), +An}();typeof define=="function"&&typeof define.amd=="object"&&define.amd?($n._=rt, define(function(){return rt})):Nn?((Nn.exports=rt)._=rt,Fn._=rt):$n._=rt}).call(this); diff --git a/net452/SiteServer.Web/SiteServer/assets/lib/md5-2.10.0.min.js b/net452/SiteServer.Web/SiteServer/assets/lib/md5-2.10.0.min.js new file mode 100644 index 000000000..7d8a3f53c --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/lib/md5-2.10.0.min.js @@ -0,0 +1,2 @@ +!function(n){"use strict";function t(n,t){var r=(65535&n)+(65535&t);return(n>>16)+(t>>16)+(r>>16)<<16|65535&r}function r(n,t){return n<>>32-t}function e(n,e,o,u,c,f){return t(r(t(t(e,n),t(u,f)),c),o)}function o(n,t,r,o,u,c,f){return e(t&r|~t&o,n,t,u,c,f)}function u(n,t,r,o,u,c,f){return e(t&o|r&~o,n,t,u,c,f)}function c(n,t,r,o,u,c,f){return e(t^r^o,n,t,u,c,f)}function f(n,t,r,o,u,c,f){return e(r^(t|~o),n,t,u,c,f)}function i(n,r){n[r>>5]|=128<>>9<<4)]=r;var e,i,a,d,h,l=1732584193,g=-271733879,v=-1732584194,m=271733878;for(e=0;e>5]>>>t%32&255);return r}function d(n){var t,r=[];for(r[(n.length>>2)-1]=void 0,t=0;t>5]|=(255&n.charCodeAt(t/8))<16&&(o=i(o,8*n.length)),r=0;r<16;r+=1)u[r]=909522486^o[r],c[r]=1549556828^o[r];return e=i(u.concat(d(t)),512+8*t.length),a(i(c.concat(e),640))}function g(n){var t,r,e="";for(r=0;r>>4&15)+"0123456789abcdef".charAt(15&t);return e}function v(n){return unescape(encodeURIComponent(n))}function m(n){return h(v(n))}function p(n){return g(m(n))}function s(n,t){return l(v(n),v(t))}function C(n,t){return g(s(n,t))}function A(n,t,r){return t?r?s(t,n):C(t,n):r?m(n):p(n)}"function"==typeof define&&define.amd?define(function(){return A}):"object"==typeof module&&module.exports?module.exports=A:n.md5=A}(this); +//# sourceMappingURL=md5.min.js.map \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/lib/modernizr.min.js b/net452/SiteServer.Web/SiteServer/assets/lib/modernizr.min.js new file mode 100644 index 000000000..40dd2a9fe --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/lib/modernizr.min.js @@ -0,0 +1 @@ +window.Modernizr=function(e,t,n){function r(e){b.cssText=e}function o(e,t){return r(S.join(e+";")+(t||""))}function a(e,t){return typeof e===t}function i(e,t){return!!~(""+e).indexOf(t)}function c(e,t){for(var r in e){var o=e[r];if(!i(o,"-")&&b[o]!==n)return"pfx"==t?o:!0}return!1}function s(e,t,r){for(var o in e){var i=t[e[o]];if(i!==n)return r===!1?e[o]:a(i,"function")?i.bind(r||t):i}return!1}function u(e,t,n){var r=e.charAt(0).toUpperCase()+e.slice(1),o=(e+" "+k.join(r+" ")+r).split(" ");return a(t,"string")||a(t,"undefined")?c(o,t):(o=(e+" "+T.join(r+" ")+r).split(" "),s(o,t,n))}function l(){p.input=function(n){for(var r=0,o=n.length;o>r;r++)j[n[r]]=!!(n[r]in E);return j.list&&(j.list=!(!t.createElement("datalist")||!e.HTMLDataListElement)),j}("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")),p.inputtypes=function(e){for(var r,o,a,i=0,c=e.length;c>i;i++)E.setAttribute("type",o=e[i]),r="text"!==E.type,r&&(E.value=x,E.style.cssText="position:absolute;visibility:hidden;",/^range$/.test(o)&&E.style.WebkitAppearance!==n?(g.appendChild(E),a=t.defaultView,r=a.getComputedStyle&&"textfield"!==a.getComputedStyle(E,null).WebkitAppearance&&0!==E.offsetHeight,g.removeChild(E)):/^(search|tel)$/.test(o)||(r=/^(url|email)$/.test(o)?E.checkValidity&&E.checkValidity()===!1:E.value!=x)),P[e[i]]=!!r;return P}("search tel url email datetime date month week time datetime-local number range color".split(" "))}var d,f,m="2.8.3",p={},h=!0,g=t.documentElement,v="modernizr",y=t.createElement(v),b=y.style,E=t.createElement("input"),x=":)",w={}.toString,S=" -webkit- -moz- -o- -ms- ".split(" "),C="Webkit Moz O ms",k=C.split(" "),T=C.toLowerCase().split(" "),N={svg:"http://www.w3.org/2000/svg"},M={},P={},j={},$=[],D=$.slice,F=function(e,n,r,o){var a,i,c,s,u=t.createElement("div"),l=t.body,d=l||t.createElement("body");if(parseInt(r,10))for(;r--;)c=t.createElement("div"),c.id=o?o[r]:v+(r+1),u.appendChild(c);return a=["­",'"].join(""),u.id=v,(l?u:d).innerHTML+=a,d.appendChild(u),l||(d.style.background="",d.style.overflow="hidden",s=g.style.overflow,g.style.overflow="hidden",g.appendChild(d)),i=n(u,e),l?u.parentNode.removeChild(u):(d.parentNode.removeChild(d),g.style.overflow=s),!!i},z=function(t){var n=e.matchMedia||e.msMatchMedia;if(n)return n(t)&&n(t).matches||!1;var r;return F("@media "+t+" { #"+v+" { position: absolute; } }",function(t){r="absolute"==(e.getComputedStyle?getComputedStyle(t,null):t.currentStyle).position}),r},A=function(){function e(e,o){o=o||t.createElement(r[e]||"div"),e="on"+e;var i=e in o;return i||(o.setAttribute||(o=t.createElement("div")),o.setAttribute&&o.removeAttribute&&(o.setAttribute(e,""),i=a(o[e],"function"),a(o[e],"undefined")||(o[e]=n),o.removeAttribute(e))),o=null,i}var r={select:"input",change:"input",submit:"form",reset:"form",error:"img",load:"img",abort:"img"};return e}(),L={}.hasOwnProperty;f=a(L,"undefined")||a(L.call,"undefined")?function(e,t){return t in e&&a(e.constructor.prototype[t],"undefined")}:function(e,t){return L.call(e,t)},Function.prototype.bind||(Function.prototype.bind=function(e){var t=this;if("function"!=typeof t)throw new TypeError;var n=D.call(arguments,1),r=function(){if(this instanceof r){var o=function(){};o.prototype=t.prototype;var a=new o,i=t.apply(a,n.concat(D.call(arguments)));return Object(i)===i?i:a}return t.apply(e,n.concat(D.call(arguments)))};return r}),M.flexbox=function(){return u("flexWrap")},M.flexboxlegacy=function(){return u("boxDirection")},M.canvas=function(){var e=t.createElement("canvas");return!(!e.getContext||!e.getContext("2d"))},M.canvastext=function(){return!(!p.canvas||!a(t.createElement("canvas").getContext("2d").fillText,"function"))},M.webgl=function(){return!!e.WebGLRenderingContext},M.touch=function(){var n;return"ontouchstart"in e||e.DocumentTouch&&t instanceof DocumentTouch?n=!0:F(["@media (",S.join("touch-enabled),("),v,")","{#modernizr{top:9px;position:absolute}}"].join(""),function(e){n=9===e.offsetTop}),n},M.geolocation=function(){return"geolocation"in navigator},M.postmessage=function(){return!!e.postMessage},M.websqldatabase=function(){return!!e.openDatabase},M.indexedDB=function(){return!!u("indexedDB",e)},M.hashchange=function(){return A("hashchange",e)&&(t.documentMode===n||t.documentMode>7)},M.history=function(){return!(!e.history||!history.pushState)},M.draganddrop=function(){var e=t.createElement("div");return"draggable"in e||"ondragstart"in e&&"ondrop"in e},M.websockets=function(){return"WebSocket"in e||"MozWebSocket"in e},M.rgba=function(){return r("background-color:rgba(150,255,150,.5)"),i(b.backgroundColor,"rgba")},M.hsla=function(){return r("background-color:hsla(120,40%,100%,.5)"),i(b.backgroundColor,"rgba")||i(b.backgroundColor,"hsla")},M.multiplebgs=function(){return r("background:url(https://),url(https://),red url(https://)"),/(url\s*\(.*?){3}/.test(b.background)},M.backgroundsize=function(){return u("backgroundSize")},M.borderimage=function(){return u("borderImage")},M.borderradius=function(){return u("borderRadius")},M.boxshadow=function(){return u("boxShadow")},M.textshadow=function(){return""===t.createElement("div").style.textShadow},M.opacity=function(){return o("opacity:.55"),/^0.55$/.test(b.opacity)},M.cssanimations=function(){return u("animationName")},M.csscolumns=function(){return u("columnCount")},M.cssgradients=function(){var e="background-image:",t="gradient(linear,left top,right bottom,from(#9f9),to(white));",n="linear-gradient(left top,#9f9, white);";return r((e+"-webkit- ".split(" ").join(t+e)+S.join(n+e)).slice(0,-e.length)),i(b.backgroundImage,"gradient")},M.cssreflections=function(){return u("boxReflect")},M.csstransforms=function(){return!!u("transform")},M.csstransforms3d=function(){var e=!!u("perspective");return e&&"webkitPerspective"in g.style&&F("@media (transform-3d),(-webkit-transform-3d){#modernizr{left:9px;position:absolute;height:3px;}}",function(t){e=9===t.offsetLeft&&3===t.offsetHeight}),e},M.csstransitions=function(){return u("transition")},M.fontface=function(){var e;return F('@font-face {font-family:"font";src:url("https://")}',function(n,r){var o=t.getElementById("smodernizr"),a=o.sheet||o.styleSheet,i=a?a.cssRules&&a.cssRules[0]?a.cssRules[0].cssText:a.cssText||"":"";e=/src/i.test(i)&&0===i.indexOf(r.split(" ")[0])}),e},M.generatedcontent=function(){var e;return F(["#",v,"{font:0/0 a}#",v,':after{content:"',x,'";visibility:hidden;font:3px/1 a}'].join(""),function(t){e=t.offsetHeight>=3}),e},M.video=function(){var e=t.createElement("video"),n=!1;try{(n=!!e.canPlayType)&&(n=new Boolean(n),n.ogg=e.canPlayType('video/ogg; codecs="theora"').replace(/^no$/,""),n.h264=e.canPlayType('video/mp4; codecs="avc1.42E01E"').replace(/^no$/,""),n.webm=e.canPlayType('video/webm; codecs="vp8, vorbis"').replace(/^no$/,""))}catch(r){}return n},M.audio=function(){var e=t.createElement("audio"),n=!1;try{(n=!!e.canPlayType)&&(n=new Boolean(n),n.ogg=e.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,""),n.mp3=e.canPlayType("audio/mpeg;").replace(/^no$/,""),n.wav=e.canPlayType('audio/wav; codecs="1"').replace(/^no$/,""),n.m4a=(e.canPlayType("audio/x-m4a;")||e.canPlayType("audio/aac;")).replace(/^no$/,""))}catch(r){}return n},M.localstorage=function(){try{return localStorage.setItem(v,v),localStorage.removeItem(v),!0}catch(e){return!1}},M.sessionstorage=function(){try{return sessionStorage.setItem(v,v),sessionStorage.removeItem(v),!0}catch(e){return!1}},M.webworkers=function(){return!!e.Worker},M.applicationcache=function(){return!!e.applicationCache},M.svg=function(){return!!t.createElementNS&&!!t.createElementNS(N.svg,"svg").createSVGRect},M.inlinesvg=function(){var e=t.createElement("div");return e.innerHTML="",(e.firstChild&&e.firstChild.namespaceURI)==N.svg},M.smil=function(){return!!t.createElementNS&&/SVGAnimate/.test(w.call(t.createElementNS(N.svg,"animate")))},M.svgclippaths=function(){return!!t.createElementNS&&/SVGClipPath/.test(w.call(t.createElementNS(N.svg,"clipPath")))};for(var H in M)f(M,H)&&(d=H.toLowerCase(),p[d]=M[H](),$.push((p[d]?"":"no-")+d));return p.input||l(),p.addTest=function(e,t){if("object"==typeof e)for(var r in e)f(e,r)&&p.addTest(r,e[r]);else{if(e=e.toLowerCase(),p[e]!==n)return p;t="function"==typeof t?t():t,"undefined"!=typeof h&&h&&(g.className+=" "+(t?"":"no-")+e),p[e]=t}return p},r(""),y=E=null,function(e,t){function n(e,t){var n=e.createElement("p"),r=e.getElementsByTagName("head")[0]||e.documentElement;return n.innerHTML="x",r.insertBefore(n.lastChild,r.firstChild)}function r(){var e=y.elements;return"string"==typeof e?e.split(" "):e}function o(e){var t=v[e[h]];return t||(t={},g++,e[h]=g,v[g]=t),t}function a(e,n,r){if(n||(n=t),l)return n.createElement(e);r||(r=o(n));var a;return a=r.cache[e]?r.cache[e].cloneNode():p.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!a.canHaveChildren||m.test(e)||a.tagUrn?a:r.frag.appendChild(a)}function i(e,n){if(e||(e=t),l)return e.createDocumentFragment();n=n||o(e);for(var a=n.frag.cloneNode(),i=0,c=r(),s=c.length;s>i;i++)a.createElement(c[i]);return a}function c(e,t){t.cache||(t.cache={},t.createElem=e.createElement,t.createFrag=e.createDocumentFragment,t.frag=t.createFrag()),e.createElement=function(n){return y.shivMethods?a(n,e,t):t.createElem(n)},e.createDocumentFragment=Function("h,f","return function(){var n=f.cloneNode(),c=n.createElement;h.shivMethods&&("+r().join().replace(/[\w\-]+/g,function(e){return t.createElem(e),t.frag.createElement(e),'c("'+e+'")'})+");return n}")(y,t.frag)}function s(e){e||(e=t);var r=o(e);return!y.shivCSS||u||r.hasCSS||(r.hasCSS=!!n(e,"article,aside,dialog,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}mark{background:#FF0;color:#000}template{display:none}")),l||c(e,r),e}var u,l,d="3.7.0",f=e.html5||{},m=/^<|^(?:button|map|select|textarea|object|iframe|option|optgroup)$/i,p=/^(?:a|b|code|div|fieldset|h1|h2|h3|h4|h5|h6|i|label|li|ol|p|q|span|strong|style|table|tbody|td|th|tr|ul)$/i,h="_html5shiv",g=0,v={};!function(){try{var e=t.createElement("a");e.innerHTML="",u="hidden"in e,l=1==e.childNodes.length||function(){t.createElement("a");var e=t.createDocumentFragment();return"undefined"==typeof e.cloneNode||"undefined"==typeof e.createDocumentFragment||"undefined"==typeof e.createElement}()}catch(n){u=!0,l=!0}}();var y={elements:f.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output progress section summary template time video",version:d,shivCSS:f.shivCSS!==!1,supportsUnknownElements:l,shivMethods:f.shivMethods!==!1,type:"default",shivDocument:s,createElement:a,createDocumentFragment:i};e.html5=y,s(t)}(this,t),p._version=m,p._prefixes=S,p._domPrefixes=T,p._cssomPrefixes=k,p.mq=z,p.hasEvent=A,p.testProp=function(e){return c([e])},p.testAllProps=u,p.testStyles=F,p.prefixed=function(e,t,n){return t?u(e,t,n):u(e,"pfx")},g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(h?" js "+$.join(" "):""),p}(this,this.document); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/lib/popper.min.js b/net452/SiteServer.Web/SiteServer/assets/lib/popper.min.js new file mode 100644 index 000000000..95e9ef5a2 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/lib/popper.min.js @@ -0,0 +1,5 @@ +/* + Copyright (C) Federico Zivolo 2017 + Distributed under the MIT License (license terms are at http://opensource.org/licenses/MIT). + */(function(e,t){'object'==typeof exports&&'undefined'!=typeof module?module.exports=t():'function'==typeof define&&define.amd?define(t):e.Popper=t()})(this,function(){'use strict';function e(e){return e&&'[object Function]'==={}.toString.call(e)}function t(e,t){if(1!==e.nodeType)return[];var o=window.getComputedStyle(e,null);return t?o[t]:o}function o(e){return'HTML'===e.nodeName?e:e.parentNode||e.host}function n(e){if(!e||-1!==['HTML','BODY','#document'].indexOf(e.nodeName))return window.document.body;var i=t(e),r=i.overflow,p=i.overflowX,s=i.overflowY;return /(auto|scroll)/.test(r+s+p)?e:n(o(e))}function r(e){var o=e&&e.offsetParent,i=o&&o.nodeName;return i&&'BODY'!==i&&'HTML'!==i?-1!==['TD','TABLE'].indexOf(o.nodeName)&&'static'===t(o,'position')?r(o):o:window.document.documentElement}function p(e){var t=e.nodeName;return'BODY'!==t&&('HTML'===t||r(e.firstElementChild)===e)}function s(e){return null===e.parentNode?e:s(e.parentNode)}function d(e,t){if(!e||!e.nodeType||!t||!t.nodeType)return window.document.documentElement;var o=e.compareDocumentPosition(t)&Node.DOCUMENT_POSITION_FOLLOWING,i=o?e:t,n=o?t:e,a=document.createRange();a.setStart(i,0),a.setEnd(n,0);var f=a.commonAncestorContainer;if(e!==f&&t!==f||i.contains(n))return p(f)?f:r(f);var l=s(e);return l.host?d(l.host,t):d(e,s(t).host)}function a(e){var t=1=o.clientWidth&&i>=o.clientHeight}),f=0i[e]&&!t.escapeWithReference&&(n=z(p[o],i[e]-('right'===e?p.width:p.height))),pe({},o,n)}};return n.forEach(function(e){var t=-1===['left','top'].indexOf(e)?'secondary':'primary';p=se({},p,s[t](e))}),e.offsets.popper=p,e},priority:['left','right','top','bottom'],padding:5,boundariesElement:'scrollParent'},keepTogether:{order:400,enabled:!0,fn:function(e){var t=e.offsets,o=t.popper,i=t.reference,n=e.placement.split('-')[0],r=V,p=-1!==['top','bottom'].indexOf(n),s=p?'right':'bottom',d=p?'left':'top',a=p?'width':'height';return o[s]r(i[s])&&(e.offsets.popper[d]=r(i[s])),e}},arrow:{order:500,enabled:!0,fn:function(e,t){if(!F(e.instance.modifiers,'arrow','keepTogether'))return e;var o=t.element;if('string'==typeof o){if(o=e.instance.popper.querySelector(o),!o)return e;}else if(!e.instance.popper.contains(o))return console.warn('WARNING: `arrow.element` must be child of its popper element!'),e;var i=e.placement.split('-')[0],n=e.offsets,r=n.popper,p=n.reference,s=-1!==['left','right'].indexOf(i),d=s?'height':'width',a=s?'top':'left',f=s?'left':'top',l=s?'bottom':'right',m=O(o)[d];p[l]-mr[l]&&(e.offsets.popper[a]+=p[a]+m-r[l]);var h=p[a]+p[d]/2-m/2,g=h-c(e.offsets.popper)[a];return g=_(z(r[d]-m,g),0),e.arrowElement=o,e.offsets.arrow={},e.offsets.arrow[a]=Math.round(g),e.offsets.arrow[f]='',e},element:'[x-arrow]'},flip:{order:600,enabled:!0,fn:function(e,t){if(W(e.instance.modifiers,'inner'))return e;if(e.flipped&&e.placement===e.originalPlacement)return e;var o=w(e.instance.popper,e.instance.reference,t.padding,t.boundariesElement),i=e.placement.split('-')[0],n=L(i),r=e.placement.split('-')[1]||'',p=[];switch(t.behavior){case fe.FLIP:p=[i,n];break;case fe.CLOCKWISE:p=K(i);break;case fe.COUNTERCLOCKWISE:p=K(i,!0);break;default:p=t.behavior;}return p.forEach(function(s,d){if(i!==s||p.length===d+1)return e;i=e.placement.split('-')[0],n=L(i);var a=e.offsets.popper,f=e.offsets.reference,l=V,m='left'===i&&l(a.right)>l(f.left)||'right'===i&&l(a.left)l(f.top)||'bottom'===i&&l(a.top)l(o.right),g=l(a.top)l(o.bottom),b='left'===i&&h||'right'===i&&c||'top'===i&&g||'bottom'===i&&u,y=-1!==['top','bottom'].indexOf(i),w=!!t.flipVariations&&(y&&'start'===r&&h||y&&'end'===r&&c||!y&&'start'===r&&g||!y&&'end'===r&&u);(m||b||w)&&(e.flipped=!0,(m||b)&&(i=p[d+1]),w&&(r=j(r)),e.placement=i+(r?'-'+r:''),e.offsets.popper=se({},e.offsets.popper,S(e.instance.popper,e.offsets.reference,e.placement)),e=N(e.instance.modifiers,e,'flip'))}),e},behavior:'flip',padding:5,boundariesElement:'viewport'},inner:{order:700,enabled:!1,fn:function(e){var t=e.placement,o=t.split('-')[0],i=e.offsets,n=i.popper,r=i.reference,p=-1!==['left','right'].indexOf(o),s=-1===['top','left'].indexOf(o);return n[p?'left':'top']=r[t]-(s?n[p?'width':'height']:0),e.placement=L(t),e.offsets.popper=c(n),e}},hide:{order:800,enabled:!0,fn:function(e){if(!F(e.instance.modifiers,'hide','preventOverflow'))return e;var t=e.offsets.reference,o=T(e.instance.modifiers,function(e){return'preventOverflow'===e.name}).boundaries;if(t.bottomo.right||t.top>o.bottom||t.right\n
        \n
          \n
          \n \n
          \n
          \n ?\n
          \n
          \n !\n
          \n
          \n i\n
          \n
          \n
          \n \n
          \n
          \n
          \n \n

          \n \n
          \n
          \n
          \n \n \n
          \n \n \n
          \n \n
          \n \n \n
          \n
          \n
          \n \n \n
          \n
          \n
          \n \n').replace(/(^|\n)\s*/g,""),X=function(e){var t=w();if(t&&(t.parentNode.removeChild(t),W([document.documentElement,document.body],[_["no-backdrop"],_["toast-shown"],_["has-column"]])),!j()){var n=document.createElement("div");n.className=_.container,n.innerHTML=M,("string"==typeof e.target?document.querySelector(e.target):e.target).appendChild(n);var o,i=k(),r=B(),a=z(r,_.input),s=z(r,_.file),c=r.querySelector(".".concat(_.range," input")),u=r.querySelector(".".concat(_.range," output")),l=z(r,_.select),d=r.querySelector(".".concat(_.checkbox," input")),p=z(r,_.textarea);i.setAttribute("role",e.toast?"alert":"dialog"),i.setAttribute("aria-live",e.toast?"polite":"assertive"),e.toast||i.setAttribute("aria-modal","true");var f=function(e){He.isVisible()&&o!==e.target.value&&He.resetValidationMessage(),o=e.target.value};return a.oninput=f,s.onchange=f,l.onchange=f,d.onchange=f,p.oninput=f,c.oninput=function(e){f(e),u.value=c.value},c.onchange=function(e){f(e),c.nextSibling.value=c.value},i}R("SweetAlert2 requires document to initialize")},G=function(e,t){if(!e)return K(t);if("object"===V(e))if(t.innerHTML="",0 in e)for(var n=0;n in e;n++)t.appendChild(e[n].cloneNode(!0));else t.appendChild(e.cloneNode(!0));else e&&(t.innerHTML=e);U(t)},ee=function(){if(j())return!1;var e=document.createElement("div"),t={WebkitAnimation:"webkitAnimationEnd",OAnimation:"oAnimationEnd oanimationend",animation:"animationend"};for(var n in t)if(t.hasOwnProperty(n)&&void 0!==e.style[n])return t[n];return!1}(),te=function(e){var t=Q(),n=E(),o=Z();if(e.showConfirmButton||e.showCancelButton?U(t):K(t),e.showCancelButton?o.style.display="inline-block":K(o),e.showConfirmButton?n.style.removeProperty("display"):K(n),n.innerHTML=e.confirmButtonText,o.innerHTML=e.cancelButtonText,n.setAttribute("aria-label",e.confirmButtonAriaLabel),o.setAttribute("aria-label",e.cancelButtonAriaLabel),n.className=_.confirm,N(n,e.confirmButtonClass),o.className=_.cancel,N(o,e.cancelButtonClass),e.buttonsStyling){N([n,o],_.styled),e.confirmButtonColor&&(n.style.backgroundColor=e.confirmButtonColor),e.cancelButtonColor&&(o.style.backgroundColor=e.cancelButtonColor);var i=window.getComputedStyle(n).getPropertyValue("background-color");n.style.borderLeftColor=i,n.style.borderRightColor=i}else W([n,o],_.styled),n.style.backgroundColor=n.style.borderLeftColor=n.style.borderRightColor="",o.style.backgroundColor=o.style.borderLeftColor=o.style.borderRightColor=""},ne=function(e){var t=B().querySelector("#"+_.content);e.html?G(e.html,t):e.text?(t.textContent=e.text,U(t)):K(t)},oe=function(e){for(var t=x(),n=0;n=i.progressSteps.length&&q("Invalid currentProgressStep parameter, it should be less than progressSteps.length (currentProgressStep like JS arrays starts from 0)"),i.progressSteps.forEach(function(e,t){var n=document.createElement("li");if(N(n,_.progresscircle),n.innerHTML=e,t===a&&N(n,_.activeprogressstep),r.appendChild(n),t!==i.progressSteps.length-1){var o=document.createElement("li");N(o,_.progressline),i.progressStepsDistance&&(o.style.width=i.progressStepsDistance),r.appendChild(o)}})):K(r)},ae=function(e){var t=A();e.titleText?t.innerText=e.titleText:e.title&&("string"==typeof e.title&&(e.title=e.title.split("\n").join("
          ")),G(e.title,t))},se=function(){null===b.previousBodyPadding&&document.body.scrollHeight>window.innerHeight&&(b.previousBodyPadding=parseInt(window.getComputedStyle(document.body).getPropertyValue("padding-right")),document.body.style.paddingRight=b.previousBodyPadding+function(){if("ontouchstart"in window||navigator.msMaxTouchPoints)return 0;var e=document.createElement("div");e.style.width="50px",e.style.height="50px",e.style.overflow="scroll",document.body.appendChild(e);var t=e.offsetWidth-e.clientWidth;return document.body.removeChild(e),t}()+"px")},ce={},ue=function(e,t){var n=w(),o=k();if(o){null!==e&&"function"==typeof e&&e(o),W(o,_.show),N(o,_.hide);var i=function(){T()?le(t):(new Promise(function(e){var t=window.scrollX,n=window.scrollY;ce.restoreFocusTimeout=setTimeout(function(){ce.previousActiveElement&&ce.previousActiveElement.focus?(ce.previousActiveElement.focus(),ce.previousActiveElement=null):document.body&&document.body.focus(),e()},100),void 0!==t&&void 0!==n&&window.scrollTo(t,n)}).then(function(){return le(t)}),ce.keydownTarget.removeEventListener("keydown",ce.keydownHandler,{capture:ce.keydownListenerCapture}),ce.keydownHandlerAdded=!1),n.parentNode&&n.parentNode.removeChild(n),W([document.documentElement,document.body],[_.shown,_["height-auto"],_["no-backdrop"],_["toast-shown"],_["toast-column"]]),L()&&(null!==b.previousBodyPadding&&(document.body.style.paddingRight=b.previousBodyPadding,b.previousBodyPadding=null),function(){if(v(document.body,_.iosfix)){var e=parseInt(document.body.style.top,10);W(document.body,_.iosfix),document.body.style.top="",document.body.scrollTop=-1*e}}(),f(document.body.children).forEach(function(e){e.hasAttribute("data-previous-aria-hidden")?(e.setAttribute("aria-hidden",e.getAttribute("data-previous-aria-hidden")),e.removeAttribute("data-previous-aria-hidden")):e.removeAttribute("aria-hidden")}))};ee&&!v(o,_.noanimation)?o.addEventListener(ee,function e(){o.removeEventListener(ee,e),v(o,_.hide)&&i()}):i()}},le=function(e){null!==e&&"function"==typeof e&&setTimeout(function(){e()})};function de(e){var t=function e(){for(var t=arguments.length,n=new Array(t),o=0;o.swal2-modal{box-shadow:0 0 10px rgba(0,0,0,.4)}body.swal2-no-backdrop .swal2-shown.swal2-top{top:0;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}body.swal2-no-backdrop .swal2-shown.swal2-top-left,body.swal2-no-backdrop .swal2-shown.swal2-top-start{top:0;left:0}body.swal2-no-backdrop .swal2-shown.swal2-top-end,body.swal2-no-backdrop .swal2-shown.swal2-top-right{top:0;right:0}body.swal2-no-backdrop .swal2-shown.swal2-center{top:50%;left:50%;-webkit-transform:translate(-50%,-50%);transform:translate(-50%,-50%)}body.swal2-no-backdrop .swal2-shown.swal2-center-left,body.swal2-no-backdrop .swal2-shown.swal2-center-start{top:50%;left:0;-webkit-transform:translateY(-50%);transform:translateY(-50%)}body.swal2-no-backdrop .swal2-shown.swal2-center-end,body.swal2-no-backdrop .swal2-shown.swal2-center-right{top:50%;right:0;-webkit-transform:translateY(-50%);transform:translateY(-50%)}body.swal2-no-backdrop .swal2-shown.swal2-bottom{bottom:0;left:50%;-webkit-transform:translateX(-50%);transform:translateX(-50%)}body.swal2-no-backdrop .swal2-shown.swal2-bottom-left,body.swal2-no-backdrop .swal2-shown.swal2-bottom-start{bottom:0;left:0}body.swal2-no-backdrop .swal2-shown.swal2-bottom-end,body.swal2-no-backdrop .swal2-shown.swal2-bottom-right{right:0;bottom:0}.swal2-container{display:flex;position:fixed;top:0;right:0;bottom:0;left:0;flex-direction:row;align-items:center;justify-content:center;padding:10px;background-color:transparent;z-index:1060;overflow-x:hidden;-webkit-overflow-scrolling:touch}.swal2-container.swal2-top{align-items:flex-start}.swal2-container.swal2-top-left,.swal2-container.swal2-top-start{align-items:flex-start;justify-content:flex-start}.swal2-container.swal2-top-end,.swal2-container.swal2-top-right{align-items:flex-start;justify-content:flex-end}.swal2-container.swal2-center{align-items:center}.swal2-container.swal2-center-left,.swal2-container.swal2-center-start{align-items:center;justify-content:flex-start}.swal2-container.swal2-center-end,.swal2-container.swal2-center-right{align-items:center;justify-content:flex-end}.swal2-container.swal2-bottom{align-items:flex-end}.swal2-container.swal2-bottom-left,.swal2-container.swal2-bottom-start{align-items:flex-end;justify-content:flex-start}.swal2-container.swal2-bottom-end,.swal2-container.swal2-bottom-right{align-items:flex-end;justify-content:flex-end}.swal2-container.swal2-grow-fullscreen>.swal2-modal{display:flex!important;flex:1;align-self:stretch;justify-content:center}.swal2-container.swal2-grow-row>.swal2-modal{display:flex!important;flex:1;align-content:center;justify-content:center}.swal2-container.swal2-grow-column{flex:1;flex-direction:column}.swal2-container.swal2-grow-column.swal2-bottom,.swal2-container.swal2-grow-column.swal2-center,.swal2-container.swal2-grow-column.swal2-top{align-items:center}.swal2-container.swal2-grow-column.swal2-bottom-left,.swal2-container.swal2-grow-column.swal2-bottom-start,.swal2-container.swal2-grow-column.swal2-center-left,.swal2-container.swal2-grow-column.swal2-center-start,.swal2-container.swal2-grow-column.swal2-top-left,.swal2-container.swal2-grow-column.swal2-top-start{align-items:flex-start}.swal2-container.swal2-grow-column.swal2-bottom-end,.swal2-container.swal2-grow-column.swal2-bottom-right,.swal2-container.swal2-grow-column.swal2-center-end,.swal2-container.swal2-grow-column.swal2-center-right,.swal2-container.swal2-grow-column.swal2-top-end,.swal2-container.swal2-grow-column.swal2-top-right{align-items:flex-end}.swal2-container.swal2-grow-column>.swal2-modal{display:flex!important;flex:1;align-content:center;justify-content:center}.swal2-container:not(.swal2-top):not(.swal2-top-start):not(.swal2-top-end):not(.swal2-top-left):not(.swal2-top-right):not(.swal2-center-start):not(.swal2-center-end):not(.swal2-center-left):not(.swal2-center-right):not(.swal2-bottom):not(.swal2-bottom-start):not(.swal2-bottom-end):not(.swal2-bottom-left):not(.swal2-bottom-right):not(.swal2-grow-fullscreen)>.swal2-modal{margin:auto}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.swal2-container .swal2-modal{margin:0!important}}.swal2-container.swal2-fade{transition:background-color .1s}.swal2-container.swal2-shown{background-color:rgba(0,0,0,.4)}.swal2-popup{display:none;position:relative;flex-direction:column;justify-content:center;width:32em;max-width:100%;padding:1.25em;border-radius:.3125em;background:#fff;font-family:inherit;font-size:1rem;box-sizing:border-box}.swal2-popup:focus{outline:0}.swal2-popup.swal2-loading{overflow-y:hidden}.swal2-popup .swal2-header{display:flex;flex-direction:column;align-items:center}.swal2-popup .swal2-title{display:block;position:relative;max-width:100%;margin:0 0 .4em;padding:0;color:#595959;font-size:1.875em;font-weight:600;text-align:center;text-transform:none;word-wrap:break-word}.swal2-popup .swal2-actions{flex-wrap:wrap;align-items:center;justify-content:center;margin:1.25em auto 0;z-index:1}.swal2-popup .swal2-actions:not(.swal2-loading) .swal2-styled[disabled]{opacity:.4}.swal2-popup .swal2-actions:not(.swal2-loading) .swal2-styled:hover{background-image:linear-gradient(rgba(0,0,0,.1),rgba(0,0,0,.1))}.swal2-popup .swal2-actions:not(.swal2-loading) .swal2-styled:active{background-image:linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.2))}.swal2-popup .swal2-actions.swal2-loading .swal2-styled.swal2-confirm{width:2.5em;height:2.5em;margin:.46875em;padding:0;border:.25em solid transparent;border-radius:100%;border-color:transparent;background-color:transparent!important;color:transparent;cursor:default;box-sizing:border-box;-webkit-animation:swal2-rotate-loading 1.5s linear 0s infinite normal;animation:swal2-rotate-loading 1.5s linear 0s infinite normal;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.swal2-popup .swal2-actions.swal2-loading .swal2-styled.swal2-cancel{margin-right:30px;margin-left:30px}.swal2-popup .swal2-actions.swal2-loading :not(.swal2-styled).swal2-confirm::after{display:inline-block;width:15px;height:15px;margin-left:5px;border:3px solid #999;border-radius:50%;border-right-color:transparent;box-shadow:1px 1px 1px #fff;content:'';-webkit-animation:swal2-rotate-loading 1.5s linear 0s infinite normal;animation:swal2-rotate-loading 1.5s linear 0s infinite normal}.swal2-popup .swal2-styled{margin:.3125em;padding:.625em 2em;font-weight:500;box-shadow:none}.swal2-popup .swal2-styled:not([disabled]){cursor:pointer}.swal2-popup .swal2-styled.swal2-confirm{border:0;border-radius:.25em;background:initial;background-color:#3085d6;color:#fff;font-size:1.0625em}.swal2-popup .swal2-styled.swal2-cancel{border:0;border-radius:.25em;background:initial;background-color:#aaa;color:#fff;font-size:1.0625em}.swal2-popup .swal2-styled:focus{outline:0;box-shadow:0 0 0 2px #fff,0 0 0 4px rgba(50,100,150,.4)}.swal2-popup .swal2-styled::-moz-focus-inner{border:0}.swal2-popup .swal2-footer{justify-content:center;margin:1.25em 0 0;padding:1em 0 0;border-top:1px solid #eee;color:#545454;font-size:1em}.swal2-popup .swal2-image{max-width:100%;margin:1.25em auto}.swal2-popup .swal2-close{position:absolute;top:0;right:0;justify-content:center;width:1.2em;height:1.2em;padding:0;transition:color .1s ease-out;border:none;border-radius:0;background:0 0;color:#ccc;font-family:serif;font-size:2.5em;line-height:1.2;cursor:pointer;overflow:hidden}.swal2-popup .swal2-close:hover{-webkit-transform:none;transform:none;color:#f27474}.swal2-popup>.swal2-checkbox,.swal2-popup>.swal2-file,.swal2-popup>.swal2-input,.swal2-popup>.swal2-radio,.swal2-popup>.swal2-select,.swal2-popup>.swal2-textarea{display:none}.swal2-popup .swal2-content{justify-content:center;margin:0;padding:0;color:#545454;font-size:1.125em;font-weight:300;line-height:normal;z-index:1;word-wrap:break-word}.swal2-popup #swal2-content{text-align:center}.swal2-popup .swal2-checkbox,.swal2-popup .swal2-file,.swal2-popup .swal2-input,.swal2-popup .swal2-radio,.swal2-popup .swal2-select,.swal2-popup .swal2-textarea{margin:1em auto}.swal2-popup .swal2-file,.swal2-popup .swal2-input,.swal2-popup .swal2-textarea{width:100%;transition:border-color .3s,box-shadow .3s;border:1px solid #d9d9d9;border-radius:.1875em;font-size:1.125em;box-shadow:inset 0 1px 1px rgba(0,0,0,.06);box-sizing:border-box}.swal2-popup .swal2-file.swal2-inputerror,.swal2-popup .swal2-input.swal2-inputerror,.swal2-popup .swal2-textarea.swal2-inputerror{border-color:#f27474!important;box-shadow:0 0 2px #f27474!important}.swal2-popup .swal2-file:focus,.swal2-popup .swal2-input:focus,.swal2-popup .swal2-textarea:focus{border:1px solid #b4dbed;outline:0;box-shadow:0 0 3px #c4e6f5}.swal2-popup .swal2-file::-webkit-input-placeholder,.swal2-popup .swal2-input::-webkit-input-placeholder,.swal2-popup .swal2-textarea::-webkit-input-placeholder{color:#ccc}.swal2-popup .swal2-file:-ms-input-placeholder,.swal2-popup .swal2-input:-ms-input-placeholder,.swal2-popup .swal2-textarea:-ms-input-placeholder{color:#ccc}.swal2-popup .swal2-file::-ms-input-placeholder,.swal2-popup .swal2-input::-ms-input-placeholder,.swal2-popup .swal2-textarea::-ms-input-placeholder{color:#ccc}.swal2-popup .swal2-file::placeholder,.swal2-popup .swal2-input::placeholder,.swal2-popup .swal2-textarea::placeholder{color:#ccc}.swal2-popup .swal2-range input{width:80%}.swal2-popup .swal2-range output{width:20%;font-weight:600;text-align:center}.swal2-popup .swal2-range input,.swal2-popup .swal2-range output{height:2.625em;margin:1em auto;padding:0;font-size:1.125em;line-height:2.625em}.swal2-popup .swal2-input{height:2.625em;padding:0 .75em}.swal2-popup .swal2-input[type=number]{max-width:10em}.swal2-popup .swal2-file{font-size:1.125em}.swal2-popup .swal2-textarea{height:6.75em;padding:.75em}.swal2-popup .swal2-select{min-width:50%;max-width:100%;padding:.375em .625em;color:#545454;font-size:1.125em}.swal2-popup .swal2-checkbox,.swal2-popup .swal2-radio{align-items:center;justify-content:center}.swal2-popup .swal2-checkbox label,.swal2-popup .swal2-radio label{margin:0 .6em;font-size:1.125em}.swal2-popup .swal2-checkbox input,.swal2-popup .swal2-radio input{margin:0 .4em}.swal2-popup .swal2-validation-message{display:none;align-items:center;justify-content:center;padding:.625em;background:#f0f0f0;color:#666;font-size:1em;font-weight:300;overflow:hidden}.swal2-popup .swal2-validation-message::before{display:inline-block;width:1.5em;min-width:1.5em;height:1.5em;margin:0 .625em;border-radius:50%;background-color:#f27474;color:#fff;font-weight:600;line-height:1.5em;text-align:center;content:'!';zoom:normal}@supports (-ms-accelerator:true){.swal2-range input{width:100%!important}.swal2-range output{display:none}}@media all and (-ms-high-contrast:none),(-ms-high-contrast:active){.swal2-range input{width:100%!important}.swal2-range output{display:none}}@-moz-document url-prefix(){.swal2-close:focus{outline:2px solid rgba(50,100,150,.4)}}.swal2-icon{position:relative;justify-content:center;width:5em;height:5em;margin:1.25em auto 1.875em;border:.25em solid transparent;border-radius:50%;line-height:5em;cursor:default;box-sizing:content-box;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;zoom:normal}.swal2-icon-text{font-size:3.75em}.swal2-icon.swal2-error{border-color:#f27474}.swal2-icon.swal2-error .swal2-x-mark{position:relative;flex-grow:1}.swal2-icon.swal2-error [class^=swal2-x-mark-line]{display:block;position:absolute;top:2.3125em;width:2.9375em;height:.3125em;border-radius:.125em;background-color:#f27474}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=left]{left:1.0625em;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.swal2-icon.swal2-error [class^=swal2-x-mark-line][class$=right]{right:1em;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.swal2-icon.swal2-warning{border-color:#facea8;color:#f8bb86}.swal2-icon.swal2-info{border-color:#9de0f6;color:#3fc3ee}.swal2-icon.swal2-question{border-color:#c9dae1;color:#87adbd}.swal2-icon.swal2-success{border-color:#a5dc86}.swal2-icon.swal2-success [class^=swal2-success-circular-line]{position:absolute;width:3.75em;height:7.5em;-webkit-transform:rotate(45deg);transform:rotate(45deg);border-radius:50%}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=left]{top:-.4375em;left:-2.0635em;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:3.75em 3.75em;transform-origin:3.75em 3.75em;border-radius:7.5em 0 0 7.5em}.swal2-icon.swal2-success [class^=swal2-success-circular-line][class$=right]{top:-.6875em;left:1.875em;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);-webkit-transform-origin:0 3.75em;transform-origin:0 3.75em;border-radius:0 7.5em 7.5em 0}.swal2-icon.swal2-success .swal2-success-ring{position:absolute;top:-.25em;left:-.25em;width:100%;height:100%;border:.25em solid rgba(165,220,134,.3);border-radius:50%;z-index:2;box-sizing:content-box}.swal2-icon.swal2-success .swal2-success-fix{position:absolute;top:.5em;left:1.625em;width:.4375em;height:5.625em;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);z-index:1}.swal2-icon.swal2-success [class^=swal2-success-line]{display:block;position:absolute;height:.3125em;border-radius:.125em;background-color:#a5dc86;z-index:2}.swal2-icon.swal2-success [class^=swal2-success-line][class$=tip]{top:2.875em;left:.875em;width:1.5625em;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.swal2-icon.swal2-success [class^=swal2-success-line][class$=long]{top:2.375em;right:.5em;width:2.9375em;-webkit-transform:rotate(-45deg);transform:rotate(-45deg)}.swal2-progresssteps{align-items:center;margin:0 0 1.25em;padding:0;font-weight:600}.swal2-progresssteps li{display:inline-block;position:relative}.swal2-progresssteps .swal2-progresscircle{width:2em;height:2em;border-radius:2em;background:#3085d6;color:#fff;line-height:2em;text-align:center;z-index:20}.swal2-progresssteps .swal2-progresscircle:first-child{margin-left:0}.swal2-progresssteps .swal2-progresscircle:last-child{margin-right:0}.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep{background:#3085d6}.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep~.swal2-progresscircle{background:#add8e6}.swal2-progresssteps .swal2-progresscircle.swal2-activeprogressstep~.swal2-progressline{background:#add8e6}.swal2-progresssteps .swal2-progressline{width:2.5em;height:.4em;margin:0 -1px;background:#3085d6;z-index:10}[class^=swal2]{-webkit-tap-highlight-color:transparent}.swal2-show{-webkit-animation:swal2-show .3s;animation:swal2-show .3s}.swal2-show.swal2-noanimation{-webkit-animation:none;animation:none}.swal2-hide{-webkit-animation:swal2-hide .15s forwards;animation:swal2-hide .15s forwards}.swal2-hide.swal2-noanimation{-webkit-animation:none;animation:none}[dir=rtl] .swal2-close{right:auto;left:0}.swal2-animate-success-icon .swal2-success-line-tip{-webkit-animation:swal2-animate-success-line-tip .75s;animation:swal2-animate-success-line-tip .75s}.swal2-animate-success-icon .swal2-success-line-long{-webkit-animation:swal2-animate-success-line-long .75s;animation:swal2-animate-success-line-long .75s}.swal2-animate-success-icon .swal2-success-circular-line-right{-webkit-animation:swal2-rotate-success-circular-line 4.25s ease-in;animation:swal2-rotate-success-circular-line 4.25s ease-in}.swal2-animate-error-icon{-webkit-animation:swal2-animate-error-icon .5s;animation:swal2-animate-error-icon .5s}.swal2-animate-error-icon .swal2-x-mark{-webkit-animation:swal2-animate-error-x-mark .5s;animation:swal2-animate-error-x-mark .5s}@-webkit-keyframes swal2-rotate-loading{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes swal2-rotate-loading{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@media print{body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown){overflow-y:scroll!important}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown)>[aria-hidden=true]{display:none}body.swal2-shown:not(.swal2-no-backdrop):not(.swal2-toast-shown) .swal2-container{position:initial!important}}"); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/lib/vee-validate-2.1.0.js b/net452/SiteServer.Web/SiteServer/assets/lib/vee-validate-2.1.0.js new file mode 100644 index 000000000..3e137bfe2 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/lib/vee-validate-2.1.0.js @@ -0,0 +1,7933 @@ +/** + * vee-validate v2.1.0-beta.9 + * (c) 2018 Abdelrahman Awad + * @license MIT + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : + typeof define === 'function' && define.amd ? define(factory) : + (global.VeeValidate = factory()); +}(this, (function () { 'use strict'; + + var MILLISECONDS_IN_HOUR = 3600000; + var MILLISECONDS_IN_MINUTE = 60000; + var DEFAULT_ADDITIONAL_DIGITS = 2; + + var patterns = { + dateTimeDelimeter: /[T ]/, + plainTime: /:/, + + // year tokens + YY: /^(\d{2})$/, + YYY: [ + /^([+-]\d{2})$/, // 0 additional digits + /^([+-]\d{3})$/, // 1 additional digit + /^([+-]\d{4})$/ // 2 additional digits + ], + YYYY: /^(\d{4})/, + YYYYY: [ + /^([+-]\d{4})/, // 0 additional digits + /^([+-]\d{5})/, // 1 additional digit + /^([+-]\d{6})/ // 2 additional digits + ], + + // date tokens + MM: /^-(\d{2})$/, + DDD: /^-?(\d{3})$/, + MMDD: /^-?(\d{2})-?(\d{2})$/, + Www: /^-?W(\d{2})$/, + WwwD: /^-?W(\d{2})-?(\d{1})$/, + + HH: /^(\d{2}([.,]\d*)?)$/, + HHMM: /^(\d{2}):?(\d{2}([.,]\d*)?)$/, + HHMMSS: /^(\d{2}):?(\d{2}):?(\d{2}([.,]\d*)?)$/, + + // timezone tokens + timezone: /([Z+-].*)$/, + timezoneZ: /^(Z)$/, + timezoneHH: /^([+-])(\d{2})$/, + timezoneHHMM: /^([+-])(\d{2}):?(\d{2})$/ + }; + + /** + * @name toDate + * @category Common Helpers + * @summary Convert the given argument to an instance of Date. + * + * @description + * Convert the given argument to an instance of Date. + * + * If the argument is an instance of Date, the function returns its clone. + * + * If the argument is a number, it is treated as a timestamp. + * + * If an argument is a string, the function tries to parse it. + * Function accepts complete ISO 8601 formats as well as partial implementations. + * ISO 8601: http://en.wikipedia.org/wiki/ISO_8601 + * + * If the argument is null, it is treated as an invalid date. + * + * If all above fails, the function passes the given argument to Date constructor. + * + * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`. + * All *date-fns* functions will throw `RangeError` if `options.additionalDigits` is not 0, 1, 2 or undefined. + * + * @param {*} argument - the value to convert + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - the additional number of digits in the extended year format + * @returns {Date} the parsed date in the local time zone + * @throws {TypeError} 1 argument required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Convert string '2014-02-11T11:30:30' to date: + * var result = toDate('2014-02-11T11:30:30') + * //=> Tue Feb 11 2014 11:30:30 + * + * @example + * // Convert string '+02014101' to date, + * // if the additional number of digits in the extended year format is 1: + * var result = toDate('+02014101', {additionalDigits: 1}) + * //=> Fri Apr 11 2014 00:00:00 + */ + function toDate (argument, dirtyOptions) { + if (arguments.length < 1) { + throw new TypeError('1 argument required, but only ' + arguments.length + ' present') + } + + if (argument === null) { + return new Date(NaN) + } + + var options = dirtyOptions || {}; + + var additionalDigits = options.additionalDigits === undefined ? DEFAULT_ADDITIONAL_DIGITS : Number(options.additionalDigits); + if (additionalDigits !== 2 && additionalDigits !== 1 && additionalDigits !== 0) { + throw new RangeError('additionalDigits must be 0, 1 or 2') + } + + // Clone the date + if (argument instanceof Date) { + // Prevent the date to lose the milliseconds when passed to new Date() in IE10 + return new Date(argument.getTime()) + } else if (typeof argument !== 'string') { + return new Date(argument) + } + + var dateStrings = splitDateString(argument); + + var parseYearResult = parseYear(dateStrings.date, additionalDigits); + var year = parseYearResult.year; + var restDateString = parseYearResult.restDateString; + + var date = parseDate(restDateString, year); + + if (date) { + var timestamp = date.getTime(); + var time = 0; + var offset; + + if (dateStrings.time) { + time = parseTime(dateStrings.time); + } + + if (dateStrings.timezone) { + offset = parseTimezone(dateStrings.timezone); + } else { + // get offset accurate to hour in timezones that change offset + offset = new Date(timestamp + time).getTimezoneOffset(); + offset = new Date(timestamp + time + offset * MILLISECONDS_IN_MINUTE).getTimezoneOffset(); + } + + return new Date(timestamp + time + offset * MILLISECONDS_IN_MINUTE) + } else { + return new Date(argument) + } + } + + function splitDateString (dateString) { + var dateStrings = {}; + var array = dateString.split(patterns.dateTimeDelimeter); + var timeString; + + if (patterns.plainTime.test(array[0])) { + dateStrings.date = null; + timeString = array[0]; + } else { + dateStrings.date = array[0]; + timeString = array[1]; + } + + if (timeString) { + var token = patterns.timezone.exec(timeString); + if (token) { + dateStrings.time = timeString.replace(token[1], ''); + dateStrings.timezone = token[1]; + } else { + dateStrings.time = timeString; + } + } + + return dateStrings + } + + function parseYear (dateString, additionalDigits) { + var patternYYY = patterns.YYY[additionalDigits]; + var patternYYYYY = patterns.YYYYY[additionalDigits]; + + var token; + + // YYYY or ±YYYYY + token = patterns.YYYY.exec(dateString) || patternYYYYY.exec(dateString); + if (token) { + var yearString = token[1]; + return { + year: parseInt(yearString, 10), + restDateString: dateString.slice(yearString.length) + } + } + + // YY or ±YYY + token = patterns.YY.exec(dateString) || patternYYY.exec(dateString); + if (token) { + var centuryString = token[1]; + return { + year: parseInt(centuryString, 10) * 100, + restDateString: dateString.slice(centuryString.length) + } + } + + // Invalid ISO-formatted year + return { + year: null + } + } + + function parseDate (dateString, year) { + // Invalid ISO-formatted year + if (year === null) { + return null + } + + var token; + var date; + var month; + var week; + + // YYYY + if (dateString.length === 0) { + date = new Date(0); + date.setUTCFullYear(year); + return date + } + + // YYYY-MM + token = patterns.MM.exec(dateString); + if (token) { + date = new Date(0); + month = parseInt(token[1], 10) - 1; + date.setUTCFullYear(year, month); + return date + } + + // YYYY-DDD or YYYYDDD + token = patterns.DDD.exec(dateString); + if (token) { + date = new Date(0); + var dayOfYear = parseInt(token[1], 10); + date.setUTCFullYear(year, 0, dayOfYear); + return date + } + + // YYYY-MM-DD or YYYYMMDD + token = patterns.MMDD.exec(dateString); + if (token) { + date = new Date(0); + month = parseInt(token[1], 10) - 1; + var day = parseInt(token[2], 10); + date.setUTCFullYear(year, month, day); + return date + } + + // YYYY-Www or YYYYWww + token = patterns.Www.exec(dateString); + if (token) { + week = parseInt(token[1], 10) - 1; + return dayOfISOYear(year, week) + } + + // YYYY-Www-D or YYYYWwwD + token = patterns.WwwD.exec(dateString); + if (token) { + week = parseInt(token[1], 10) - 1; + var dayOfWeek = parseInt(token[2], 10) - 1; + return dayOfISOYear(year, week, dayOfWeek) + } + + // Invalid ISO-formatted date + return null + } + + function parseTime (timeString) { + var token; + var hours; + var minutes; + + // hh + token = patterns.HH.exec(timeString); + if (token) { + hours = parseFloat(token[1].replace(',', '.')); + return (hours % 24) * MILLISECONDS_IN_HOUR + } + + // hh:mm or hhmm + token = patterns.HHMM.exec(timeString); + if (token) { + hours = parseInt(token[1], 10); + minutes = parseFloat(token[2].replace(',', '.')); + return (hours % 24) * MILLISECONDS_IN_HOUR + + minutes * MILLISECONDS_IN_MINUTE + } + + // hh:mm:ss or hhmmss + token = patterns.HHMMSS.exec(timeString); + if (token) { + hours = parseInt(token[1], 10); + minutes = parseInt(token[2], 10); + var seconds = parseFloat(token[3].replace(',', '.')); + return (hours % 24) * MILLISECONDS_IN_HOUR + + minutes * MILLISECONDS_IN_MINUTE + + seconds * 1000 + } + + // Invalid ISO-formatted time + return null + } + + function parseTimezone (timezoneString) { + var token; + var absoluteOffset; + + // Z + token = patterns.timezoneZ.exec(timezoneString); + if (token) { + return 0 + } + + // ±hh + token = patterns.timezoneHH.exec(timezoneString); + if (token) { + absoluteOffset = parseInt(token[2], 10) * 60; + return (token[1] === '+') ? -absoluteOffset : absoluteOffset + } + + // ±hh:mm or ±hhmm + token = patterns.timezoneHHMM.exec(timezoneString); + if (token) { + absoluteOffset = parseInt(token[2], 10) * 60 + parseInt(token[3], 10); + return (token[1] === '+') ? -absoluteOffset : absoluteOffset + } + + return 0 + } + + function dayOfISOYear (isoYear, week, day) { + week = week || 0; + day = day || 0; + var date = new Date(0); + date.setUTCFullYear(isoYear, 0, 4); + var fourthOfJanuaryDay = date.getUTCDay() || 7; + var diff = week * 7 + day + 1 - fourthOfJanuaryDay; + date.setUTCDate(date.getUTCDate() + diff); + return date + } + + /** + * @name addMilliseconds + * @category Millisecond Helpers + * @summary Add the specified number of milliseconds to the given date. + * + * @description + * Add the specified number of milliseconds to the given date. + * + * @param {Date|String|Number} date - the date to be changed + * @param {Number} amount - the amount of milliseconds to be added + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Date} the new date with the milliseconds added + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Add 750 milliseconds to 10 July 2014 12:45:30.000: + * var result = addMilliseconds(new Date(2014, 6, 10, 12, 45, 30, 0), 750) + * //=> Thu Jul 10 2014 12:45:30.750 + */ + function addMilliseconds (dirtyDate, dirtyAmount, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var timestamp = toDate(dirtyDate, dirtyOptions).getTime(); + var amount = Number(dirtyAmount); + return new Date(timestamp + amount) + } + + function cloneObject (dirtyObject) { + dirtyObject = dirtyObject || {}; + var object = {}; + + for (var property in dirtyObject) { + if (dirtyObject.hasOwnProperty(property)) { + object[property] = dirtyObject[property]; + } + } + + return object + } + + var MILLISECONDS_IN_MINUTE$2 = 60000; + + /** + * @name addMinutes + * @category Minute Helpers + * @summary Add the specified number of minutes to the given date. + * + * @description + * Add the specified number of minutes to the given date. + * + * @param {Date|String|Number} date - the date to be changed + * @param {Number} amount - the amount of minutes to be added + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Date} the new date with the minutes added + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Add 30 minutes to 10 July 2014 12:00:00: + * var result = addMinutes(new Date(2014, 6, 10, 12, 0), 30) + * //=> Thu Jul 10 2014 12:30:00 + */ + function addMinutes (dirtyDate, dirtyAmount, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var amount = Number(dirtyAmount); + return addMilliseconds(dirtyDate, amount * MILLISECONDS_IN_MINUTE$2, dirtyOptions) + } + + /** + * @name isValid + * @category Common Helpers + * @summary Is the given date valid? + * + * @description + * Returns false if argument is Invalid Date and true otherwise. + * Argument is converted to Date using `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * Invalid Date is a Date, whose time value is NaN. + * + * Time value of Date: http://es5.github.io/#x15.9.1.1 + * + * @param {*} date - the date to check + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Boolean} the date is valid + * @throws {TypeError} 1 argument required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // For the valid date: + * var result = isValid(new Date(2014, 1, 31)) + * //=> true + * + * @example + * // For the value, convertable into a date: + * var result = isValid('2014-02-31') + * //=> true + * + * @example + * // For the invalid date: + * var result = isValid(new Date('')) + * //=> false + */ + function isValid (dirtyDate, dirtyOptions) { + if (arguments.length < 1) { + throw new TypeError('1 argument required, but only ' + arguments.length + ' present') + } + + var date = toDate(dirtyDate, dirtyOptions); + return !isNaN(date) + } + + var formatDistanceLocale = { + lessThanXSeconds: { + one: 'less than a second', + other: 'less than {{count}} seconds' + }, + + xSeconds: { + one: '1 second', + other: '{{count}} seconds' + }, + + halfAMinute: 'half a minute', + + lessThanXMinutes: { + one: 'less than a minute', + other: 'less than {{count}} minutes' + }, + + xMinutes: { + one: '1 minute', + other: '{{count}} minutes' + }, + + aboutXHours: { + one: 'about 1 hour', + other: 'about {{count}} hours' + }, + + xHours: { + one: '1 hour', + other: '{{count}} hours' + }, + + xDays: { + one: '1 day', + other: '{{count}} days' + }, + + aboutXMonths: { + one: 'about 1 month', + other: 'about {{count}} months' + }, + + xMonths: { + one: '1 month', + other: '{{count}} months' + }, + + aboutXYears: { + one: 'about 1 year', + other: 'about {{count}} years' + }, + + xYears: { + one: '1 year', + other: '{{count}} years' + }, + + overXYears: { + one: 'over 1 year', + other: 'over {{count}} years' + }, + + almostXYears: { + one: 'almost 1 year', + other: 'almost {{count}} years' + } + }; + + function formatDistance (token, count, options) { + options = options || {}; + + var result; + if (typeof formatDistanceLocale[token] === 'string') { + result = formatDistanceLocale[token]; + } else if (count === 1) { + result = formatDistanceLocale[token].one; + } else { + result = formatDistanceLocale[token].other.replace('{{count}}', count); + } + + if (options.addSuffix) { + if (options.comparison > 0) { + return 'in ' + result + } else { + return result + ' ago' + } + } + + return result + } + + var tokensToBeShortedPattern = /MMMM|MM|DD|dddd/g; + + function buildShortLongFormat (format) { + return format.replace(tokensToBeShortedPattern, function (token) { + return token.slice(1) + }) + } + + /** + * @name buildFormatLongFn + * @category Locale Helpers + * @summary Build `formatLong` property for locale used by `format`, `formatRelative` and `parse` functions. + * + * @description + * Build `formatLong` property for locale used by `format`, `formatRelative` and `parse` functions. + * Returns a function which takes one of the following tokens as the argument: + * `'LTS'`, `'LT'`, `'L'`, `'LL'`, `'LLL'`, `'l'`, `'ll'`, `'lll'`, `'llll'` + * and returns a long format string written as `format` token strings. + * See [format]{@link https://date-fns.org/docs/format} + * + * `'l'`, `'ll'`, `'lll'` and `'llll'` formats are built automatically + * by shortening some of the tokens from corresponding unshortened formats + * (e.g., if `LL` is `'MMMM DD YYYY'` then `ll` will be `MMM D YYYY`) + * + * @param {Object} obj - the object with long formats written as `format` token strings + * @param {String} obj.LT - time format: hours and minutes + * @param {String} obj.LTS - time format: hours, minutes and seconds + * @param {String} obj.L - short date format: numeric day, month and year + * @param {String} [obj.l] - short date format: numeric day, month and year (shortened) + * @param {String} obj.LL - long date format: day, month in words, and year + * @param {String} [obj.ll] - long date format: day, month in words, and year (shortened) + * @param {String} obj.LLL - long date and time format + * @param {String} [obj.lll] - long date and time format (shortened) + * @param {String} obj.LLLL - long date, time and weekday format + * @param {String} [obj.llll] - long date, time and weekday format (shortened) + * @returns {Function} `formatLong` property of the locale + * + * @example + * // For `en-US` locale: + * locale.formatLong = buildFormatLongFn({ + * LT: 'h:mm aa', + * LTS: 'h:mm:ss aa', + * L: 'MM/DD/YYYY', + * LL: 'MMMM D YYYY', + * LLL: 'MMMM D YYYY h:mm aa', + * LLLL: 'dddd, MMMM D YYYY h:mm aa' + * }) + */ + function buildFormatLongFn (obj) { + var formatLongLocale = { + LTS: obj.LTS, + LT: obj.LT, + L: obj.L, + LL: obj.LL, + LLL: obj.LLL, + LLLL: obj.LLLL, + l: obj.l || buildShortLongFormat(obj.L), + ll: obj.ll || buildShortLongFormat(obj.LL), + lll: obj.lll || buildShortLongFormat(obj.LLL), + llll: obj.llll || buildShortLongFormat(obj.LLLL) + }; + + return function (token) { + return formatLongLocale[token] + } + } + + var formatLong = buildFormatLongFn({ + LT: 'h:mm aa', + LTS: 'h:mm:ss aa', + L: 'MM/DD/YYYY', + LL: 'MMMM D YYYY', + LLL: 'MMMM D YYYY h:mm aa', + LLLL: 'dddd, MMMM D YYYY h:mm aa' + }); + + var formatRelativeLocale = { + lastWeek: '[last] dddd [at] LT', + yesterday: '[yesterday at] LT', + today: '[today at] LT', + tomorrow: '[tomorrow at] LT', + nextWeek: 'dddd [at] LT', + other: 'L' + }; + + function formatRelative (token, date, baseDate, options) { + return formatRelativeLocale[token] + } + + /** + * @name buildLocalizeFn + * @category Locale Helpers + * @summary Build `localize.weekday`, `localize.month` and `localize.timeOfDay` properties for the locale. + * + * @description + * Build `localize.weekday`, `localize.month` and `localize.timeOfDay` properties for the locale + * used by `format` function. + * If no `type` is supplied to the options of the resulting function, `defaultType` will be used (see example). + * + * `localize.weekday` function takes the weekday index as argument (0 - Sunday). + * `localize.month` takes the month index (0 - January). + * `localize.timeOfDay` takes the hours. Use `indexCallback` to convert them to an array index (see example). + * + * @param {Object} values - the object with arrays of values + * @param {String} defaultType - the default type for the localize function + * @param {Function} [indexCallback] - the callback which takes the resulting function argument + * and converts it into value array index + * @returns {Function} the resulting function + * + * @example + * var timeOfDayValues = { + * uppercase: ['AM', 'PM'], + * lowercase: ['am', 'pm'], + * long: ['a.m.', 'p.m.'] + * } + * locale.localize.timeOfDay = buildLocalizeFn(timeOfDayValues, 'long', function (hours) { + * // 0 is a.m. array index, 1 is p.m. array index + * return (hours / 12) >= 1 ? 1 : 0 + * }) + * locale.localize.timeOfDay(16, {type: 'uppercase'}) //=> 'PM' + * locale.localize.timeOfDay(5) //=> 'a.m.' + */ + function buildLocalizeFn (values, defaultType, indexCallback) { + return function (dirtyIndex, dirtyOptions) { + var options = dirtyOptions || {}; + var type = options.type ? String(options.type) : defaultType; + var valuesArray = values[type] || values[defaultType]; + var index = indexCallback ? indexCallback(Number(dirtyIndex)) : Number(dirtyIndex); + return valuesArray[index] + } + } + + /** + * @name buildLocalizeArrayFn + * @category Locale Helpers + * @summary Build `localize.weekdays`, `localize.months` and `localize.timesOfDay` properties for the locale. + * + * @description + * Build `localize.weekdays`, `localize.months` and `localize.timesOfDay` properties for the locale. + * If no `type` is supplied to the options of the resulting function, `defaultType` will be used (see example). + * + * @param {Object} values - the object with arrays of values + * @param {String} defaultType - the default type for the localize function + * @returns {Function} the resulting function + * + * @example + * var weekdayValues = { + * narrow: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'], + * short: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + * long: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] + * } + * locale.localize.weekdays = buildLocalizeArrayFn(weekdayValues, 'long') + * locale.localize.weekdays({type: 'narrow'}) //=> ['Su', 'Mo', ...] + * locale.localize.weekdays() //=> ['Sunday', 'Monday', ...] + */ + function buildLocalizeArrayFn (values, defaultType) { + return function (dirtyOptions) { + var options = dirtyOptions || {}; + var type = options.type ? String(options.type) : defaultType; + return values[type] || values[defaultType] + } + } + + // Note: in English, the names of days of the week and months are capitalized. + // If you are making a new locale based on this one, check if the same is true for the language you're working on. + // Generally, formatted dates should look like they are in the middle of a sentence, + // e.g. in Spanish language the weekdays and months should be in the lowercase. + var weekdayValues = { + narrow: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'], + short: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], + long: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'] + }; + + var monthValues = { + short: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], + long: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'] + }; + + // `timeOfDay` is used to designate which part of the day it is, when used with 12-hour clock. + // Use the system which is used the most commonly in the locale. + // For example, if the country doesn't use a.m./p.m., you can use `night`/`morning`/`afternoon`/`evening`: + // + // var timeOfDayValues = { + // any: ['in the night', 'in the morning', 'in the afternoon', 'in the evening'] + // } + // + // And later: + // + // var localize = { + // // The callback takes the hours as the argument and returns the array index + // timeOfDay: buildLocalizeFn(timeOfDayValues, 'any', function (hours) { + // if (hours >= 17) { + // return 3 + // } else if (hours >= 12) { + // return 2 + // } else if (hours >= 4) { + // return 1 + // } else { + // return 0 + // } + // }), + // timesOfDay: buildLocalizeArrayFn(timeOfDayValues, 'any') + // } + var timeOfDayValues = { + uppercase: ['AM', 'PM'], + lowercase: ['am', 'pm'], + long: ['a.m.', 'p.m.'] + }; + + function ordinalNumber (dirtyNumber, dirtyOptions) { + var number = Number(dirtyNumber); + + // If ordinal numbers depend on context, for example, + // if they are different for different grammatical genders, + // use `options.unit`: + // + // var options = dirtyOptions || {} + // var unit = String(options.unit) + // + // where `unit` can be 'month', 'quarter', 'week', 'isoWeek', 'dayOfYear', + // 'dayOfMonth' or 'dayOfWeek' + + var rem100 = number % 100; + if (rem100 > 20 || rem100 < 10) { + switch (rem100 % 10) { + case 1: + return number + 'st' + case 2: + return number + 'nd' + case 3: + return number + 'rd' + } + } + return number + 'th' + } + + var localize = { + ordinalNumber: ordinalNumber, + weekday: buildLocalizeFn(weekdayValues, 'long'), + weekdays: buildLocalizeArrayFn(weekdayValues, 'long'), + month: buildLocalizeFn(monthValues, 'long'), + months: buildLocalizeArrayFn(monthValues, 'long'), + timeOfDay: buildLocalizeFn(timeOfDayValues, 'long', function (hours) { + return (hours / 12) >= 1 ? 1 : 0 + }), + timesOfDay: buildLocalizeArrayFn(timeOfDayValues, 'long') + }; + + /** + * @name buildMatchFn + * @category Locale Helpers + * @summary Build `match.weekdays`, `match.months` and `match.timesOfDay` properties for the locale. + * + * @description + * Build `match.weekdays`, `match.months` and `match.timesOfDay` properties for the locale used by `parse` function. + * If no `type` is supplied to the options of the resulting function, `defaultType` will be used (see example). + * The result of the match function will be passed into corresponding parser function + * (`match.weekday`, `match.month` or `match.timeOfDay` respectively. See `buildParseFn`). + * + * @param {Object} values - the object with RegExps + * @param {String} defaultType - the default type for the match function + * @returns {Function} the resulting function + * + * @example + * var matchWeekdaysPatterns = { + * narrow: /^(su|mo|tu|we|th|fr|sa)/i, + * short: /^(sun|mon|tue|wed|thu|fri|sat)/i, + * long: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i + * } + * locale.match.weekdays = buildMatchFn(matchWeekdaysPatterns, 'long') + * locale.match.weekdays('Sunday', {type: 'narrow'}) //=> ['Su', 'Su', ...] + * locale.match.weekdays('Sunday') //=> ['Sunday', 'Sunday', ...] + */ + function buildMatchFn (patterns, defaultType) { + return function (dirtyString, dirtyOptions) { + var options = dirtyOptions || {}; + var type = options.type ? String(options.type) : defaultType; + var pattern = patterns[type] || patterns[defaultType]; + var string = String(dirtyString); + return string.match(pattern) + } + } + + /** + * @name buildParseFn + * @category Locale Helpers + * @summary Build `match.weekday`, `match.month` and `match.timeOfDay` properties for the locale. + * + * @description + * Build `match.weekday`, `match.month` and `match.timeOfDay` properties for the locale used by `parse` function. + * The argument of the resulting function is the result of the corresponding match function + * (`match.weekdays`, `match.months` or `match.timesOfDay` respectively. See `buildMatchFn`). + * + * @param {Object} values - the object with arrays of RegExps + * @param {String} defaultType - the default type for the parser function + * @returns {Function} the resulting function + * + * @example + * var parseWeekdayPatterns = { + * any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i] + * } + * locale.match.weekday = buildParseFn(matchWeekdaysPatterns, 'long') + * var matchResult = locale.match.weekdays('Friday') + * locale.match.weekday(matchResult) //=> 5 + */ + function buildParseFn (patterns, defaultType) { + return function (matchResult, dirtyOptions) { + var options = dirtyOptions || {}; + var type = options.type ? String(options.type) : defaultType; + var patternsArray = patterns[type] || patterns[defaultType]; + var string = matchResult[1]; + + return patternsArray.findIndex(function (pattern) { + return pattern.test(string) + }) + } + } + + /** + * @name buildMatchPatternFn + * @category Locale Helpers + * @summary Build match function from a single RegExp. + * + * @description + * Build match function from a single RegExp. + * Usually used for building `match.ordinalNumbers` property of the locale. + * + * @param {Object} pattern - the RegExp + * @returns {Function} the resulting function + * + * @example + * locale.match.ordinalNumbers = buildMatchPatternFn(/^(\d+)(th|st|nd|rd)?/i) + * locale.match.ordinalNumbers('3rd') //=> ['3rd', '3', 'rd', ...] + */ + function buildMatchPatternFn (pattern) { + return function (dirtyString) { + var string = String(dirtyString); + return string.match(pattern) + } + } + + /** + * @name parseDecimal + * @category Locale Helpers + * @summary Parses the match result into decimal number. + * + * @description + * Parses the match result into decimal number. + * Uses the string matched with the first set of parentheses of match RegExp. + * + * @param {Array} matchResult - the object returned by matching function + * @returns {Number} the parsed value + * + * @example + * locale.match = { + * ordinalNumbers: (dirtyString) { + * return String(dirtyString).match(/^(\d+)(th|st|nd|rd)?/i) + * }, + * ordinalNumber: parseDecimal + * } + */ + function parseDecimal (matchResult) { + return parseInt(matchResult[1], 10) + } + + var matchOrdinalNumbersPattern = /^(\d+)(th|st|nd|rd)?/i; + + var matchWeekdaysPatterns = { + narrow: /^(su|mo|tu|we|th|fr|sa)/i, + short: /^(sun|mon|tue|wed|thu|fri|sat)/i, + long: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i + }; + + var parseWeekdayPatterns = { + any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i] + }; + + var matchMonthsPatterns = { + short: /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i, + long: /^(january|february|march|april|may|june|july|august|september|october|november|december)/i + }; + + var parseMonthPatterns = { + any: [/^ja/i, /^f/i, /^mar/i, /^ap/i, /^may/i, /^jun/i, /^jul/i, /^au/i, /^s/i, /^o/i, /^n/i, /^d/i] + }; + + // `timeOfDay` is used to designate which part of the day it is, when used with 12-hour clock. + // Use the system which is used the most commonly in the locale. + // For example, if the country doesn't use a.m./p.m., you can use `night`/`morning`/`afternoon`/`evening`: + // + // var matchTimesOfDayPatterns = { + // long: /^((in the)? (night|morning|afternoon|evening?))/i + // } + // + // var parseTimeOfDayPatterns = { + // any: [/(night|morning)/i, /(afternoon|evening)/i] + // } + var matchTimesOfDayPatterns = { + short: /^(am|pm)/i, + long: /^([ap]\.?\s?m\.?)/i + }; + + var parseTimeOfDayPatterns = { + any: [/^a/i, /^p/i] + }; + + var match = { + ordinalNumbers: buildMatchPatternFn(matchOrdinalNumbersPattern), + ordinalNumber: parseDecimal, + weekdays: buildMatchFn(matchWeekdaysPatterns, 'long'), + weekday: buildParseFn(parseWeekdayPatterns, 'any'), + months: buildMatchFn(matchMonthsPatterns, 'long'), + month: buildParseFn(parseMonthPatterns, 'any'), + timesOfDay: buildMatchFn(matchTimesOfDayPatterns, 'long'), + timeOfDay: buildParseFn(parseTimeOfDayPatterns, 'any') + }; + + /** + * @type {Locale} + * @category Locales + * @summary English locale (United States). + * @language English + * @iso-639-2 eng + */ + var locale = { + formatDistance: formatDistance, + formatLong: formatLong, + formatRelative: formatRelative, + localize: localize, + match: match, + options: { + weekStartsOn: 0 /* Sunday */, + firstWeekContainsDate: 1 + } + }; + + var MILLISECONDS_IN_DAY$1 = 86400000; + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function getUTCDayOfYear (dirtyDate, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var timestamp = date.getTime(); + date.setUTCMonth(0, 1); + date.setUTCHours(0, 0, 0, 0); + var startOfYearTimestamp = date.getTime(); + var difference = timestamp - startOfYearTimestamp; + return Math.floor(difference / MILLISECONDS_IN_DAY$1) + 1 + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function startOfUTCISOWeek (dirtyDate, dirtyOptions) { + var weekStartsOn = 1; + + var date = toDate(dirtyDate, dirtyOptions); + var day = date.getUTCDay(); + var diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn; + + date.setUTCDate(date.getUTCDate() - diff); + date.setUTCHours(0, 0, 0, 0); + return date + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function getUTCISOWeekYear (dirtyDate, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var year = date.getUTCFullYear(); + + var fourthOfJanuaryOfNextYear = new Date(0); + fourthOfJanuaryOfNextYear.setUTCFullYear(year + 1, 0, 4); + fourthOfJanuaryOfNextYear.setUTCHours(0, 0, 0, 0); + var startOfNextYear = startOfUTCISOWeek(fourthOfJanuaryOfNextYear, dirtyOptions); + + var fourthOfJanuaryOfThisYear = new Date(0); + fourthOfJanuaryOfThisYear.setUTCFullYear(year, 0, 4); + fourthOfJanuaryOfThisYear.setUTCHours(0, 0, 0, 0); + var startOfThisYear = startOfUTCISOWeek(fourthOfJanuaryOfThisYear, dirtyOptions); + + if (date.getTime() >= startOfNextYear.getTime()) { + return year + 1 + } else if (date.getTime() >= startOfThisYear.getTime()) { + return year + } else { + return year - 1 + } + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function startOfUTCISOWeekYear (dirtyDate, dirtyOptions) { + var year = getUTCISOWeekYear(dirtyDate, dirtyOptions); + var fourthOfJanuary = new Date(0); + fourthOfJanuary.setUTCFullYear(year, 0, 4); + fourthOfJanuary.setUTCHours(0, 0, 0, 0); + var date = startOfUTCISOWeek(fourthOfJanuary, dirtyOptions); + return date + } + + var MILLISECONDS_IN_WEEK$2 = 604800000; + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function getUTCISOWeek (dirtyDate, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var diff = startOfUTCISOWeek(date, dirtyOptions).getTime() - startOfUTCISOWeekYear(date, dirtyOptions).getTime(); + + // Round the number of days to the nearest integer + // because the number of milliseconds in a week is not constant + // (e.g. it's different in the week of the daylight saving time clock shift) + return Math.round(diff / MILLISECONDS_IN_WEEK$2) + 1 + } + + var formatters = { + // Month: 1, 2, ..., 12 + 'M': function (date) { + return date.getUTCMonth() + 1 + }, + + // Month: 1st, 2nd, ..., 12th + 'Mo': function (date, options) { + var month = date.getUTCMonth() + 1; + return options.locale.localize.ordinalNumber(month, {unit: 'month'}) + }, + + // Month: 01, 02, ..., 12 + 'MM': function (date) { + return addLeadingZeros(date.getUTCMonth() + 1, 2) + }, + + // Month: Jan, Feb, ..., Dec + 'MMM': function (date, options) { + return options.locale.localize.month(date.getUTCMonth(), {type: 'short'}) + }, + + // Month: January, February, ..., December + 'MMMM': function (date, options) { + return options.locale.localize.month(date.getUTCMonth(), {type: 'long'}) + }, + + // Quarter: 1, 2, 3, 4 + 'Q': function (date) { + return Math.ceil((date.getUTCMonth() + 1) / 3) + }, + + // Quarter: 1st, 2nd, 3rd, 4th + 'Qo': function (date, options) { + var quarter = Math.ceil((date.getUTCMonth() + 1) / 3); + return options.locale.localize.ordinalNumber(quarter, {unit: 'quarter'}) + }, + + // Day of month: 1, 2, ..., 31 + 'D': function (date) { + return date.getUTCDate() + }, + + // Day of month: 1st, 2nd, ..., 31st + 'Do': function (date, options) { + return options.locale.localize.ordinalNumber(date.getUTCDate(), {unit: 'dayOfMonth'}) + }, + + // Day of month: 01, 02, ..., 31 + 'DD': function (date) { + return addLeadingZeros(date.getUTCDate(), 2) + }, + + // Day of year: 1, 2, ..., 366 + 'DDD': function (date) { + return getUTCDayOfYear(date) + }, + + // Day of year: 1st, 2nd, ..., 366th + 'DDDo': function (date, options) { + return options.locale.localize.ordinalNumber(getUTCDayOfYear(date), {unit: 'dayOfYear'}) + }, + + // Day of year: 001, 002, ..., 366 + 'DDDD': function (date) { + return addLeadingZeros(getUTCDayOfYear(date), 3) + }, + + // Day of week: Su, Mo, ..., Sa + 'dd': function (date, options) { + return options.locale.localize.weekday(date.getUTCDay(), {type: 'narrow'}) + }, + + // Day of week: Sun, Mon, ..., Sat + 'ddd': function (date, options) { + return options.locale.localize.weekday(date.getUTCDay(), {type: 'short'}) + }, + + // Day of week: Sunday, Monday, ..., Saturday + 'dddd': function (date, options) { + return options.locale.localize.weekday(date.getUTCDay(), {type: 'long'}) + }, + + // Day of week: 0, 1, ..., 6 + 'd': function (date) { + return date.getUTCDay() + }, + + // Day of week: 0th, 1st, 2nd, ..., 6th + 'do': function (date, options) { + return options.locale.localize.ordinalNumber(date.getUTCDay(), {unit: 'dayOfWeek'}) + }, + + // Day of ISO week: 1, 2, ..., 7 + 'E': function (date) { + return date.getUTCDay() || 7 + }, + + // ISO week: 1, 2, ..., 53 + 'W': function (date) { + return getUTCISOWeek(date) + }, + + // ISO week: 1st, 2nd, ..., 53th + 'Wo': function (date, options) { + return options.locale.localize.ordinalNumber(getUTCISOWeek(date), {unit: 'isoWeek'}) + }, + + // ISO week: 01, 02, ..., 53 + 'WW': function (date) { + return addLeadingZeros(getUTCISOWeek(date), 2) + }, + + // Year: 00, 01, ..., 99 + 'YY': function (date) { + return addLeadingZeros(date.getUTCFullYear(), 4).substr(2) + }, + + // Year: 1900, 1901, ..., 2099 + 'YYYY': function (date) { + return addLeadingZeros(date.getUTCFullYear(), 4) + }, + + // ISO week-numbering year: 00, 01, ..., 99 + 'GG': function (date) { + return String(getUTCISOWeekYear(date)).substr(2) + }, + + // ISO week-numbering year: 1900, 1901, ..., 2099 + 'GGGG': function (date) { + return getUTCISOWeekYear(date) + }, + + // Hour: 0, 1, ... 23 + 'H': function (date) { + return date.getUTCHours() + }, + + // Hour: 00, 01, ..., 23 + 'HH': function (date) { + return addLeadingZeros(date.getUTCHours(), 2) + }, + + // Hour: 1, 2, ..., 12 + 'h': function (date) { + var hours = date.getUTCHours(); + if (hours === 0) { + return 12 + } else if (hours > 12) { + return hours % 12 + } else { + return hours + } + }, + + // Hour: 01, 02, ..., 12 + 'hh': function (date) { + return addLeadingZeros(formatters['h'](date), 2) + }, + + // Minute: 0, 1, ..., 59 + 'm': function (date) { + return date.getUTCMinutes() + }, + + // Minute: 00, 01, ..., 59 + 'mm': function (date) { + return addLeadingZeros(date.getUTCMinutes(), 2) + }, + + // Second: 0, 1, ..., 59 + 's': function (date) { + return date.getUTCSeconds() + }, + + // Second: 00, 01, ..., 59 + 'ss': function (date) { + return addLeadingZeros(date.getUTCSeconds(), 2) + }, + + // 1/10 of second: 0, 1, ..., 9 + 'S': function (date) { + return Math.floor(date.getUTCMilliseconds() / 100) + }, + + // 1/100 of second: 00, 01, ..., 99 + 'SS': function (date) { + return addLeadingZeros(Math.floor(date.getUTCMilliseconds() / 10), 2) + }, + + // Millisecond: 000, 001, ..., 999 + 'SSS': function (date) { + return addLeadingZeros(date.getUTCMilliseconds(), 3) + }, + + // Timezone: -01:00, +00:00, ... +12:00 + 'Z': function (date, options) { + var originalDate = options._originalDate || date; + return formatTimezone(originalDate.getTimezoneOffset(), ':') + }, + + // Timezone: -0100, +0000, ... +1200 + 'ZZ': function (date, options) { + var originalDate = options._originalDate || date; + return formatTimezone(originalDate.getTimezoneOffset()) + }, + + // Seconds timestamp: 512969520 + 'X': function (date, options) { + var originalDate = options._originalDate || date; + return Math.floor(originalDate.getTime() / 1000) + }, + + // Milliseconds timestamp: 512969520900 + 'x': function (date, options) { + var originalDate = options._originalDate || date; + return originalDate.getTime() + }, + + // AM, PM + 'A': function (date, options) { + return options.locale.localize.timeOfDay(date.getUTCHours(), {type: 'uppercase'}) + }, + + // am, pm + 'a': function (date, options) { + return options.locale.localize.timeOfDay(date.getUTCHours(), {type: 'lowercase'}) + }, + + // a.m., p.m. + 'aa': function (date, options) { + return options.locale.localize.timeOfDay(date.getUTCHours(), {type: 'long'}) + } + }; + + function formatTimezone (offset, delimeter) { + delimeter = delimeter || ''; + var sign = offset > 0 ? '-' : '+'; + var absOffset = Math.abs(offset); + var hours = Math.floor(absOffset / 60); + var minutes = absOffset % 60; + return sign + addLeadingZeros(hours, 2) + delimeter + addLeadingZeros(minutes, 2) + } + + function addLeadingZeros (number, targetLength) { + var output = Math.abs(number).toString(); + while (output.length < targetLength) { + output = '0' + output; + } + return output + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function addUTCMinutes (dirtyDate, dirtyAmount, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var amount = Number(dirtyAmount); + date.setUTCMinutes(date.getUTCMinutes() + amount); + return date + } + + var longFormattingTokensRegExp = /(\[[^[]*])|(\\)?(LTS|LT|LLLL|LLL|LL|L|llll|lll|ll|l)/g; + var defaultFormattingTokensRegExp = /(\[[^[]*])|(\\)?(x|ss|s|mm|m|hh|h|do|dddd|ddd|dd|d|aa|a|ZZ|Z|YYYY|YY|X|Wo|WW|W|SSS|SS|S|Qo|Q|Mo|MMMM|MMM|MM|M|HH|H|GGGG|GG|E|Do|DDDo|DDDD|DDD|DD|D|A|.)/g; + + /** + * @name format + * @category Common Helpers + * @summary Format the date. + * + * @description + * Return the formatted date string in the given format. + * + * Accepted tokens: + * | Unit | Token | Result examples | + * |-------------------------|-------|----------------------------------| + * | Month | M | 1, 2, ..., 12 | + * | | Mo | 1st, 2nd, ..., 12th | + * | | MM | 01, 02, ..., 12 | + * | | MMM | Jan, Feb, ..., Dec | + * | | MMMM | January, February, ..., December | + * | Quarter | Q | 1, 2, 3, 4 | + * | | Qo | 1st, 2nd, 3rd, 4th | + * | Day of month | D | 1, 2, ..., 31 | + * | | Do | 1st, 2nd, ..., 31st | + * | | DD | 01, 02, ..., 31 | + * | Day of year | DDD | 1, 2, ..., 366 | + * | | DDDo | 1st, 2nd, ..., 366th | + * | | DDDD | 001, 002, ..., 366 | + * | Day of week | d | 0, 1, ..., 6 | + * | | do | 0th, 1st, ..., 6th | + * | | dd | Su, Mo, ..., Sa | + * | | ddd | Sun, Mon, ..., Sat | + * | | dddd | Sunday, Monday, ..., Saturday | + * | Day of ISO week | E | 1, 2, ..., 7 | + * | ISO week | W | 1, 2, ..., 53 | + * | | Wo | 1st, 2nd, ..., 53rd | + * | | WW | 01, 02, ..., 53 | + * | Year | YY | 00, 01, ..., 99 | + * | | YYYY | 1900, 1901, ..., 2099 | + * | ISO week-numbering year | GG | 00, 01, ..., 99 | + * | | GGGG | 1900, 1901, ..., 2099 | + * | AM/PM | A | AM, PM | + * | | a | am, pm | + * | | aa | a.m., p.m. | + * | Hour | H | 0, 1, ... 23 | + * | | HH | 00, 01, ... 23 | + * | | h | 1, 2, ..., 12 | + * | | hh | 01, 02, ..., 12 | + * | Minute | m | 0, 1, ..., 59 | + * | | mm | 00, 01, ..., 59 | + * | Second | s | 0, 1, ..., 59 | + * | | ss | 00, 01, ..., 59 | + * | 1/10 of second | S | 0, 1, ..., 9 | + * | 1/100 of second | SS | 00, 01, ..., 99 | + * | Millisecond | SSS | 000, 001, ..., 999 | + * | Timezone | Z | -01:00, +00:00, ... +12:00 | + * | | ZZ | -0100, +0000, ..., +1200 | + * | Seconds timestamp | X | 512969520 | + * | Milliseconds timestamp | x | 512969520900 | + * | Long format | LT | 05:30 a.m. | + * | | LTS | 05:30:15 a.m. | + * | | L | 07/02/1995 | + * | | l | 7/2/1995 | + * | | LL | July 2 1995 | + * | | ll | Jul 2 1995 | + * | | LLL | July 2 1995 05:30 a.m. | + * | | lll | Jul 2 1995 05:30 a.m. | + * | | LLLL | Sunday, July 2 1995 05:30 a.m. | + * | | llll | Sun, Jul 2 1995 05:30 a.m. | + * + * The characters wrapped in square brackets are escaped. + * + * The result may vary by locale. + * + * @param {Date|String|Number} date - the original date + * @param {String} format - the string of tokens + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale} + * @returns {String} the formatted date string + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * @throws {RangeError} `options.locale` must contain `localize` property + * @throws {RangeError} `options.locale` must contain `formatLong` property + * + * @example + * // Represent 11 February 2014 in middle-endian format: + * var result = format( + * new Date(2014, 1, 11), + * 'MM/DD/YYYY' + * ) + * //=> '02/11/2014' + * + * @example + * // Represent 2 July 2014 in Esperanto: + * import { eoLocale } from 'date-fns/locale/eo' + * var result = format( + * new Date(2014, 6, 2), + * 'Do [de] MMMM YYYY', + * {locale: eoLocale} + * ) + * //=> '2-a de julio 2014' + */ + function format (dirtyDate, dirtyFormatStr, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var formatStr = String(dirtyFormatStr); + var options = dirtyOptions || {}; + + var locale$$1 = options.locale || locale; + + if (!locale$$1.localize) { + throw new RangeError('locale must contain localize property') + } + + if (!locale$$1.formatLong) { + throw new RangeError('locale must contain formatLong property') + } + + var localeFormatters = locale$$1.formatters || {}; + var formattingTokensRegExp = locale$$1.formattingTokensRegExp || defaultFormattingTokensRegExp; + var formatLong = locale$$1.formatLong; + + var originalDate = toDate(dirtyDate, options); + + if (!isValid(originalDate, options)) { + return 'Invalid Date' + } + + // Convert the date in system timezone to the same date in UTC+00:00 timezone. + // This ensures that when UTC functions will be implemented, locales will be compatible with them. + // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/376 + var timezoneOffset = originalDate.getTimezoneOffset(); + var utcDate = addUTCMinutes(originalDate, -timezoneOffset, options); + + var formatterOptions = cloneObject(options); + formatterOptions.locale = locale$$1; + formatterOptions.formatters = formatters; + + // When UTC functions will be implemented, options._originalDate will likely be a part of public API. + // Right now, please don't use it in locales. If you have to use an original date, + // please restore it from `date`, adding a timezone offset to it. + formatterOptions._originalDate = originalDate; + + var result = formatStr + .replace(longFormattingTokensRegExp, function (substring) { + if (substring[0] === '[') { + return substring + } + + if (substring[0] === '\\') { + return cleanEscapedString(substring) + } + + return formatLong(substring) + }) + .replace(formattingTokensRegExp, function (substring) { + var formatter = localeFormatters[substring] || formatters[substring]; + + if (formatter) { + return formatter(utcDate, formatterOptions) + } else { + return cleanEscapedString(substring) + } + }); + + return result + } + + function cleanEscapedString (input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|]$/g, '') + } + return input.replace(/\\/g, '') + } + + /** + * @name subMinutes + * @category Minute Helpers + * @summary Subtract the specified number of minutes from the given date. + * + * @description + * Subtract the specified number of minutes from the given date. + * + * @param {Date|String|Number} date - the date to be changed + * @param {Number} amount - the amount of minutes to be subtracted + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Date} the new date with the mintues subtracted + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Subtract 30 minutes from 10 July 2014 12:00:00: + * var result = subMinutes(new Date(2014, 6, 10, 12, 0), 30) + * //=> Thu Jul 10 2014 11:30:00 + */ + function subMinutes (dirtyDate, dirtyAmount, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var amount = Number(dirtyAmount); + return addMinutes(dirtyDate, -amount, dirtyOptions) + } + + /** + * @name isAfter + * @category Common Helpers + * @summary Is the first date after the second one? + * + * @description + * Is the first date after the second one? + * + * @param {Date|String|Number} date - the date that should be after the other one to return true + * @param {Date|String|Number} dateToCompare - the date to compare with + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Boolean} the first date is after the second date + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Is 10 July 1989 after 11 February 1987? + * var result = isAfter(new Date(1989, 6, 10), new Date(1987, 1, 11)) + * //=> true + */ + function isAfter (dirtyDate, dirtyDateToCompare, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var date = toDate(dirtyDate, dirtyOptions); + var dateToCompare = toDate(dirtyDateToCompare, dirtyOptions); + return date.getTime() > dateToCompare.getTime() + } + + /** + * @name isBefore + * @category Common Helpers + * @summary Is the first date before the second one? + * + * @description + * Is the first date before the second one? + * + * @param {Date|String|Number} date - the date that should be before the other one to return true + * @param {Date|String|Number} dateToCompare - the date to compare with + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Boolean} the first date is before the second date + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Is 10 July 1989 before 11 February 1987? + * var result = isBefore(new Date(1989, 6, 10), new Date(1987, 1, 11)) + * //=> false + */ + function isBefore (dirtyDate, dirtyDateToCompare, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var date = toDate(dirtyDate, dirtyOptions); + var dateToCompare = toDate(dirtyDateToCompare, dirtyOptions); + return date.getTime() < dateToCompare.getTime() + } + + /** + * @name isEqual + * @category Common Helpers + * @summary Are the given dates equal? + * + * @description + * Are the given dates equal? + * + * @param {Date|String|Number} dateLeft - the first date to compare + * @param {Date|String|Number} dateRight - the second date to compare + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @returns {Boolean} the dates are equal + * @throws {TypeError} 2 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * + * @example + * // Are 2 July 2014 06:30:45.000 and 2 July 2014 06:30:45.500 equal? + * var result = isEqual( + * new Date(2014, 6, 2, 6, 30, 45, 0) + * new Date(2014, 6, 2, 6, 30, 45, 500) + * ) + * //=> false + */ + function isEqual (dirtyLeftDate, dirtyRightDate, dirtyOptions) { + if (arguments.length < 2) { + throw new TypeError('2 arguments required, but only ' + arguments.length + ' present') + } + + var dateLeft = toDate(dirtyLeftDate, dirtyOptions); + var dateRight = toDate(dirtyRightDate, dirtyOptions); + return dateLeft.getTime() === dateRight.getTime() + } + + var patterns$1 = { + 'M': /^(1[0-2]|0?\d)/, // 0 to 12 + 'D': /^(3[0-1]|[0-2]?\d)/, // 0 to 31 + 'DDD': /^(36[0-6]|3[0-5]\d|[0-2]?\d?\d)/, // 0 to 366 + 'W': /^(5[0-3]|[0-4]?\d)/, // 0 to 53 + 'YYYY': /^(\d{1,4})/, // 0 to 9999 + 'H': /^(2[0-3]|[0-1]?\d)/, // 0 to 23 + 'm': /^([0-5]?\d)/, // 0 to 59 + 'Z': /^([+-])(\d{2}):(\d{2})/, + 'ZZ': /^([+-])(\d{2})(\d{2})/, + singleDigit: /^(\d)/, + twoDigits: /^(\d{2})/, + threeDigits: /^(\d{3})/, + fourDigits: /^(\d{4})/, + anyDigits: /^(\d+)/ + }; + + function parseDecimal$1 (matchResult) { + return parseInt(matchResult[1], 10) + } + + var parsers = { + // Year: 00, 01, ..., 99 + 'YY': { + unit: 'twoDigitYear', + match: patterns$1.twoDigits, + parse: function (matchResult) { + return parseDecimal$1(matchResult) + } + }, + + // Year: 1900, 1901, ..., 2099 + 'YYYY': { + unit: 'year', + match: patterns$1.YYYY, + parse: parseDecimal$1 + }, + + // ISO week-numbering year: 00, 01, ..., 99 + 'GG': { + unit: 'isoYear', + match: patterns$1.twoDigits, + parse: function (matchResult) { + return parseDecimal$1(matchResult) + 1900 + } + }, + + // ISO week-numbering year: 1900, 1901, ..., 2099 + 'GGGG': { + unit: 'isoYear', + match: patterns$1.YYYY, + parse: parseDecimal$1 + }, + + // Quarter: 1, 2, 3, 4 + 'Q': { + unit: 'quarter', + match: patterns$1.singleDigit, + parse: parseDecimal$1 + }, + + // Ordinal quarter + 'Qo': { + unit: 'quarter', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'quarter'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'quarter'}) + } + }, + + // Month: 1, 2, ..., 12 + 'M': { + unit: 'month', + match: patterns$1.M, + parse: function (matchResult) { + return parseDecimal$1(matchResult) - 1 + } + }, + + // Ordinal month + 'Mo': { + unit: 'month', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'month'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'month'}) - 1 + } + }, + + // Month: 01, 02, ..., 12 + 'MM': { + unit: 'month', + match: patterns$1.twoDigits, + parse: function (matchResult) { + return parseDecimal$1(matchResult) - 1 + } + }, + + // Month: Jan, Feb, ..., Dec + 'MMM': { + unit: 'month', + match: function (string, options) { + return options.locale.match.months(string, {type: 'short'}) + }, + parse: function (matchResult, options) { + return options.locale.match.month(matchResult, {type: 'short'}) + } + }, + + // Month: January, February, ..., December + 'MMMM': { + unit: 'month', + match: function (string, options) { + return options.locale.match.months(string, {type: 'long'}) || + options.locale.match.months(string, {type: 'short'}) + }, + parse: function (matchResult, options) { + var parseResult = options.locale.match.month(matchResult, {type: 'long'}); + + if (parseResult == null) { + parseResult = options.locale.match.month(matchResult, {type: 'short'}); + } + + return parseResult + } + }, + + // ISO week: 1, 2, ..., 53 + 'W': { + unit: 'isoWeek', + match: patterns$1.W, + parse: parseDecimal$1 + }, + + // Ordinal ISO week + 'Wo': { + unit: 'isoWeek', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'isoWeek'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'isoWeek'}) + } + }, + + // ISO week: 01, 02, ..., 53 + 'WW': { + unit: 'isoWeek', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // Day of week: 0, 1, ..., 6 + 'd': { + unit: 'dayOfWeek', + match: patterns$1.singleDigit, + parse: parseDecimal$1 + }, + + // Ordinal day of week + 'do': { + unit: 'dayOfWeek', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'dayOfWeek'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'dayOfWeek'}) + } + }, + + // Day of week: Su, Mo, ..., Sa + 'dd': { + unit: 'dayOfWeek', + match: function (string, options) { + return options.locale.match.weekdays(string, {type: 'narrow'}) + }, + parse: function (matchResult, options) { + return options.locale.match.weekday(matchResult, {type: 'narrow'}) + } + }, + + // Day of week: Sun, Mon, ..., Sat + 'ddd': { + unit: 'dayOfWeek', + match: function (string, options) { + return options.locale.match.weekdays(string, {type: 'short'}) || + options.locale.match.weekdays(string, {type: 'narrow'}) + }, + parse: function (matchResult, options) { + var parseResult = options.locale.match.weekday(matchResult, {type: 'short'}); + + if (parseResult == null) { + parseResult = options.locale.match.weekday(matchResult, {type: 'narrow'}); + } + + return parseResult + } + }, + + // Day of week: Sunday, Monday, ..., Saturday + 'dddd': { + unit: 'dayOfWeek', + match: function (string, options) { + return options.locale.match.weekdays(string, {type: 'long'}) || + options.locale.match.weekdays(string, {type: 'short'}) || + options.locale.match.weekdays(string, {type: 'narrow'}) + }, + parse: function (matchResult, options) { + var parseResult = options.locale.match.weekday(matchResult, {type: 'long'}); + + if (parseResult == null) { + parseResult = options.locale.match.weekday(matchResult, {type: 'short'}); + + if (parseResult == null) { + parseResult = options.locale.match.weekday(matchResult, {type: 'narrow'}); + } + } + + return parseResult + } + }, + + // Day of ISO week: 1, 2, ..., 7 + 'E': { + unit: 'dayOfISOWeek', + match: patterns$1.singleDigit, + parse: function (matchResult) { + return parseDecimal$1(matchResult) + } + }, + + // Day of month: 1, 2, ..., 31 + 'D': { + unit: 'dayOfMonth', + match: patterns$1.D, + parse: parseDecimal$1 + }, + + // Ordinal day of month + 'Do': { + unit: 'dayOfMonth', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'dayOfMonth'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'dayOfMonth'}) + } + }, + + // Day of month: 01, 02, ..., 31 + 'DD': { + unit: 'dayOfMonth', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // Day of year: 1, 2, ..., 366 + 'DDD': { + unit: 'dayOfYear', + match: patterns$1.DDD, + parse: parseDecimal$1 + }, + + // Ordinal day of year + 'DDDo': { + unit: 'dayOfYear', + match: function (string, options) { + return options.locale.match.ordinalNumbers(string, {unit: 'dayOfYear'}) + }, + parse: function (matchResult, options) { + return options.locale.match.ordinalNumber(matchResult, {unit: 'dayOfYear'}) + } + }, + + // Day of year: 001, 002, ..., 366 + 'DDDD': { + unit: 'dayOfYear', + match: patterns$1.threeDigits, + parse: parseDecimal$1 + }, + + // AM, PM + 'A': { + unit: 'timeOfDay', + match: function (string, options) { + return options.locale.match.timesOfDay(string, {type: 'short'}) + }, + parse: function (matchResult, options) { + return options.locale.match.timeOfDay(matchResult, {type: 'short'}) + } + }, + + // a.m., p.m. + 'aa': { + unit: 'timeOfDay', + match: function (string, options) { + return options.locale.match.timesOfDay(string, {type: 'long'}) || + options.locale.match.timesOfDay(string, {type: 'short'}) + }, + parse: function (matchResult, options) { + var parseResult = options.locale.match.timeOfDay(matchResult, {type: 'long'}); + + if (parseResult == null) { + parseResult = options.locale.match.timeOfDay(matchResult, {type: 'short'}); + } + + return parseResult + } + }, + + // Hour: 0, 1, ... 23 + 'H': { + unit: 'hours', + match: patterns$1.H, + parse: parseDecimal$1 + }, + + // Hour: 00, 01, ..., 23 + 'HH': { + unit: 'hours', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // Hour: 1, 2, ..., 12 + 'h': { + unit: 'timeOfDayHours', + match: patterns$1.M, + parse: parseDecimal$1 + }, + + // Hour: 01, 02, ..., 12 + 'hh': { + unit: 'timeOfDayHours', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // Minute: 0, 1, ..., 59 + 'm': { + unit: 'minutes', + match: patterns$1.m, + parse: parseDecimal$1 + }, + + // Minute: 00, 01, ..., 59 + 'mm': { + unit: 'minutes', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // Second: 0, 1, ..., 59 + 's': { + unit: 'seconds', + match: patterns$1.m, + parse: parseDecimal$1 + }, + + // Second: 00, 01, ..., 59 + 'ss': { + unit: 'seconds', + match: patterns$1.twoDigits, + parse: parseDecimal$1 + }, + + // 1/10 of second: 0, 1, ..., 9 + 'S': { + unit: 'milliseconds', + match: patterns$1.singleDigit, + parse: function (matchResult) { + return parseDecimal$1(matchResult) * 100 + } + }, + + // 1/100 of second: 00, 01, ..., 99 + 'SS': { + unit: 'milliseconds', + match: patterns$1.twoDigits, + parse: function (matchResult) { + return parseDecimal$1(matchResult) * 10 + } + }, + + // Millisecond: 000, 001, ..., 999 + 'SSS': { + unit: 'milliseconds', + match: patterns$1.threeDigits, + parse: parseDecimal$1 + }, + + // Timezone: -01:00, +00:00, ... +12:00 + 'Z': { + unit: 'timezone', + match: patterns$1.Z, + parse: function (matchResult) { + var sign = matchResult[1]; + var hours = parseInt(matchResult[2], 10); + var minutes = parseInt(matchResult[3], 10); + var absoluteOffset = hours * 60 + minutes; + return (sign === '+') ? absoluteOffset : -absoluteOffset + } + }, + + // Timezone: -0100, +0000, ... +1200 + 'ZZ': { + unit: 'timezone', + match: patterns$1.ZZ, + parse: function (matchResult) { + var sign = matchResult[1]; + var hours = parseInt(matchResult[2], 10); + var minutes = parseInt(matchResult[3], 10); + var absoluteOffset = hours * 60 + minutes; + return (sign === '+') ? absoluteOffset : -absoluteOffset + } + }, + + // Seconds timestamp: 512969520 + 'X': { + unit: 'timestamp', + match: patterns$1.anyDigits, + parse: function (matchResult) { + return parseDecimal$1(matchResult) * 1000 + } + }, + + // Milliseconds timestamp: 512969520900 + 'x': { + unit: 'timestamp', + match: patterns$1.anyDigits, + parse: parseDecimal$1 + } + }; + + parsers['a'] = parsers['A']; + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function setUTCDay (dirtyDate, dirtyDay, dirtyOptions) { + var options = dirtyOptions || {}; + var locale = options.locale; + var localeWeekStartsOn = locale && locale.options && locale.options.weekStartsOn; + var defaultWeekStartsOn = localeWeekStartsOn === undefined ? 0 : Number(localeWeekStartsOn); + var weekStartsOn = options.weekStartsOn === undefined ? defaultWeekStartsOn : Number(options.weekStartsOn); + + // Test if weekStartsOn is between 0 and 6 _and_ is not NaN + if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) { + throw new RangeError('weekStartsOn must be between 0 and 6 inclusively') + } + + var date = toDate(dirtyDate, dirtyOptions); + var day = Number(dirtyDay); + + var currentDay = date.getUTCDay(); + + var remainder = day % 7; + var dayIndex = (remainder + 7) % 7; + + var diff = (dayIndex < weekStartsOn ? 7 : 0) + day - currentDay; + + date.setUTCDate(date.getUTCDate() + diff); + return date + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function setUTCISODay (dirtyDate, dirtyDay, dirtyOptions) { + var day = Number(dirtyDay); + + if (day % 7 === 0) { + day = day - 7; + } + + var weekStartsOn = 1; + var date = toDate(dirtyDate, dirtyOptions); + var currentDay = date.getUTCDay(); + + var remainder = day % 7; + var dayIndex = (remainder + 7) % 7; + + var diff = (dayIndex < weekStartsOn ? 7 : 0) + day - currentDay; + + date.setUTCDate(date.getUTCDate() + diff); + return date + } + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function setUTCISOWeek (dirtyDate, dirtyISOWeek, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var isoWeek = Number(dirtyISOWeek); + var diff = getUTCISOWeek(date, dirtyOptions) - isoWeek; + date.setUTCDate(date.getUTCDate() - diff * 7); + return date + } + + var MILLISECONDS_IN_DAY$3 = 86400000; + + // This function will be a part of public API when UTC function will be implemented. + // See issue: https://github.com/date-fns/date-fns/issues/376 + function setUTCISOWeekYear (dirtyDate, dirtyISOYear, dirtyOptions) { + var date = toDate(dirtyDate, dirtyOptions); + var isoYear = Number(dirtyISOYear); + var dateStartOfYear = startOfUTCISOWeekYear(date, dirtyOptions); + var diff = Math.floor((date.getTime() - dateStartOfYear.getTime()) / MILLISECONDS_IN_DAY$3); + var fourthOfJanuary = new Date(0); + fourthOfJanuary.setUTCFullYear(isoYear, 0, 4); + fourthOfJanuary.setUTCHours(0, 0, 0, 0); + date = startOfUTCISOWeekYear(fourthOfJanuary, dirtyOptions); + date.setUTCDate(date.getUTCDate() + diff); + return date + } + + var MILLISECONDS_IN_MINUTE$6 = 60000; + + function setTimeOfDay (hours, timeOfDay) { + var isAM = timeOfDay === 0; + + if (isAM) { + if (hours === 12) { + return 0 + } + } else { + if (hours !== 12) { + return 12 + hours + } + } + + return hours + } + + var units = { + twoDigitYear: { + priority: 10, + set: function (dateValues, value) { + var century = Math.floor(dateValues.date.getUTCFullYear() / 100); + var year = century * 100 + value; + dateValues.date.setUTCFullYear(year, 0, 1); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + year: { + priority: 10, + set: function (dateValues, value) { + dateValues.date.setUTCFullYear(value, 0, 1); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + isoYear: { + priority: 10, + set: function (dateValues, value, options) { + dateValues.date = startOfUTCISOWeekYear(setUTCISOWeekYear(dateValues.date, value, options), options); + return dateValues + } + }, + + quarter: { + priority: 20, + set: function (dateValues, value) { + dateValues.date.setUTCMonth((value - 1) * 3, 1); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + month: { + priority: 30, + set: function (dateValues, value) { + dateValues.date.setUTCMonth(value, 1); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + isoWeek: { + priority: 40, + set: function (dateValues, value, options) { + dateValues.date = startOfUTCISOWeek(setUTCISOWeek(dateValues.date, value, options), options); + return dateValues + } + }, + + dayOfWeek: { + priority: 50, + set: function (dateValues, value, options) { + dateValues.date = setUTCDay(dateValues.date, value, options); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + dayOfISOWeek: { + priority: 50, + set: function (dateValues, value, options) { + dateValues.date = setUTCISODay(dateValues.date, value, options); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + dayOfMonth: { + priority: 50, + set: function (dateValues, value) { + dateValues.date.setUTCDate(value); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + dayOfYear: { + priority: 50, + set: function (dateValues, value) { + dateValues.date.setUTCMonth(0, value); + dateValues.date.setUTCHours(0, 0, 0, 0); + return dateValues + } + }, + + timeOfDay: { + priority: 60, + set: function (dateValues, value, options) { + dateValues.timeOfDay = value; + return dateValues + } + }, + + hours: { + priority: 70, + set: function (dateValues, value, options) { + dateValues.date.setUTCHours(value, 0, 0, 0); + return dateValues + } + }, + + timeOfDayHours: { + priority: 70, + set: function (dateValues, value, options) { + var timeOfDay = dateValues.timeOfDay; + if (timeOfDay != null) { + value = setTimeOfDay(value, timeOfDay); + } + dateValues.date.setUTCHours(value, 0, 0, 0); + return dateValues + } + }, + + minutes: { + priority: 80, + set: function (dateValues, value) { + dateValues.date.setUTCMinutes(value, 0, 0); + return dateValues + } + }, + + seconds: { + priority: 90, + set: function (dateValues, value) { + dateValues.date.setUTCSeconds(value, 0); + return dateValues + } + }, + + milliseconds: { + priority: 100, + set: function (dateValues, value) { + dateValues.date.setUTCMilliseconds(value); + return dateValues + } + }, + + timezone: { + priority: 110, + set: function (dateValues, value) { + dateValues.date = new Date(dateValues.date.getTime() - value * MILLISECONDS_IN_MINUTE$6); + return dateValues + } + }, + + timestamp: { + priority: 120, + set: function (dateValues, value) { + dateValues.date = new Date(value); + return dateValues + } + } + }; + + var TIMEZONE_UNIT_PRIORITY = 110; + var MILLISECONDS_IN_MINUTE$7 = 60000; + + var longFormattingTokensRegExp$1 = /(\[[^[]*])|(\\)?(LTS|LT|LLLL|LLL|LL|L|llll|lll|ll|l)/g; + var defaultParsingTokensRegExp = /(\[[^[]*])|(\\)?(x|ss|s|mm|m|hh|h|do|dddd|ddd|dd|d|aa|a|ZZ|Z|YYYY|YY|X|Wo|WW|W|SSS|SS|S|Qo|Q|Mo|MMMM|MMM|MM|M|HH|H|GGGG|GG|E|Do|DDDo|DDDD|DDD|DD|D|A|.)/g; + + /** + * @name parse + * @category Common Helpers + * @summary Parse the date. + * + * @description + * Return the date parsed from string using the given format. + * + * Accepted format tokens: + * | Unit | Priority | Token | Input examples | + * |-------------------------|----------|-------|----------------------------------| + * | Year | 10 | YY | 00, 01, ..., 99 | + * | | | YYYY | 1900, 1901, ..., 2099 | + * | ISO week-numbering year | 10 | GG | 00, 01, ..., 99 | + * | | | GGGG | 1900, 1901, ..., 2099 | + * | Quarter | 20 | Q | 1, 2, 3, 4 | + * | | | Qo | 1st, 2nd, 3rd, 4th | + * | Month | 30 | M | 1, 2, ..., 12 | + * | | | Mo | 1st, 2nd, ..., 12th | + * | | | MM | 01, 02, ..., 12 | + * | | | MMM | Jan, Feb, ..., Dec | + * | | | MMMM | January, February, ..., December | + * | ISO week | 40 | W | 1, 2, ..., 53 | + * | | | Wo | 1st, 2nd, ..., 53rd | + * | | | WW | 01, 02, ..., 53 | + * | Day of week | 50 | d | 0, 1, ..., 6 | + * | | | do | 0th, 1st, ..., 6th | + * | | | dd | Su, Mo, ..., Sa | + * | | | ddd | Sun, Mon, ..., Sat | + * | | | dddd | Sunday, Monday, ..., Saturday | + * | Day of ISO week | 50 | E | 1, 2, ..., 7 | + * | Day of month | 50 | D | 1, 2, ..., 31 | + * | | | Do | 1st, 2nd, ..., 31st | + * | | | DD | 01, 02, ..., 31 | + * | Day of year | 50 | DDD | 1, 2, ..., 366 | + * | | | DDDo | 1st, 2nd, ..., 366th | + * | | | DDDD | 001, 002, ..., 366 | + * | Time of day | 60 | A | AM, PM | + * | | | a | am, pm | + * | | | aa | a.m., p.m. | + * | Hour | 70 | H | 0, 1, ... 23 | + * | | | HH | 00, 01, ... 23 | + * | Time of day hour | 70 | h | 1, 2, ..., 12 | + * | | | hh | 01, 02, ..., 12 | + * | Minute | 80 | m | 0, 1, ..., 59 | + * | | | mm | 00, 01, ..., 59 | + * | Second | 90 | s | 0, 1, ..., 59 | + * | | | ss | 00, 01, ..., 59 | + * | 1/10 of second | 100 | S | 0, 1, ..., 9 | + * | 1/100 of second | 100 | SS | 00, 01, ..., 99 | + * | Millisecond | 100 | SSS | 000, 001, ..., 999 | + * | Timezone | 110 | Z | -01:00, +00:00, ... +12:00 | + * | | | ZZ | -0100, +0000, ..., +1200 | + * | Seconds timestamp | 120 | X | 512969520 | + * | Milliseconds timestamp | 120 | x | 512969520900 | + * + * Values will be assigned to the date in the ascending order of its unit's priority. + * Units of an equal priority overwrite each other in the order of appearance. + * + * If no values of higher priority are parsed (e.g. when parsing string 'January 1st' without a year), + * the values will be taken from 3rd argument `baseDate` which works as a context of parsing. + * + * `baseDate` must be passed for correct work of the function. + * If you're not sure which `baseDate` to supply, create a new instance of Date: + * `parse('02/11/2014', 'MM/DD/YYYY', new Date())` + * In this case parsing will be done in the context of the current date. + * If `baseDate` is `Invalid Date` or a value not convertible to valid `Date`, + * then `Invalid Date` will be returned. + * + * Also, `parse` unfolds long formats like those in [format]{@link https://date-fns.org/docs/format}: + * | Token | Input examples | + * |-------|--------------------------------| + * | LT | 05:30 a.m. | + * | LTS | 05:30:15 a.m. | + * | L | 07/02/1995 | + * | l | 7/2/1995 | + * | LL | July 2 1995 | + * | ll | Jul 2 1995 | + * | LLL | July 2 1995 05:30 a.m. | + * | lll | Jul 2 1995 05:30 a.m. | + * | LLLL | Sunday, July 2 1995 05:30 a.m. | + * | llll | Sun, Jul 2 1995 05:30 a.m. | + * + * The characters wrapped in square brackets in the format string are escaped. + * + * The result may vary by locale. + * + * If `formatString` matches with `dateString` but does not provides tokens, `baseDate` will be returned. + * + * If parsing failed, `Invalid Date` will be returned. + * Invalid Date is a Date, whose time value is NaN. + * Time value of Date: http://es5.github.io/#x15.9.1.1 + * + * @param {String} dateString - the string to parse + * @param {String} formatString - the string of tokens + * @param {Date|String|Number} baseDate - the date to took the missing higher priority values from + * @param {Options} [options] - the object with options. See [Options]{@link https://date-fns.org/docs/Options} + * @param {0|1|2} [options.additionalDigits=2] - passed to `toDate`. See [toDate]{@link https://date-fns.org/docs/toDate} + * @param {Locale} [options.locale=defaultLocale] - the locale object. See [Locale]{@link https://date-fns.org/docs/Locale} + * @param {0|1|2|3|4|5|6} [options.weekStartsOn=0] - the index of the first day of the week (0 - Sunday) + * @returns {Date} the parsed date + * @throws {TypeError} 3 arguments required + * @throws {RangeError} `options.additionalDigits` must be 0, 1 or 2 + * @throws {RangeError} `options.weekStartsOn` must be between 0 and 6 + * @throws {RangeError} `options.locale` must contain `match` property + * @throws {RangeError} `options.locale` must contain `formatLong` property + * + * @example + * // Parse 11 February 2014 from middle-endian format: + * var result = parse( + * '02/11/2014', + * 'MM/DD/YYYY', + * new Date() + * ) + * //=> Tue Feb 11 2014 00:00:00 + * + * @example + * // Parse 28th of February in English locale in the context of 2010 year: + * import eoLocale from 'date-fns/locale/eo' + * var result = parse( + * '28-a de februaro', + * 'Do [de] MMMM', + * new Date(2010, 0, 1) + * {locale: eoLocale} + * ) + * //=> Sun Feb 28 2010 00:00:00 + */ + function parse (dirtyDateString, dirtyFormatString, dirtyBaseDate, dirtyOptions) { + if (arguments.length < 3) { + throw new TypeError('3 arguments required, but only ' + arguments.length + ' present') + } + + var dateString = String(dirtyDateString); + var options = dirtyOptions || {}; + + var weekStartsOn = options.weekStartsOn === undefined ? 0 : Number(options.weekStartsOn); + + // Test if weekStartsOn is between 0 and 6 _and_ is not NaN + if (!(weekStartsOn >= 0 && weekStartsOn <= 6)) { + throw new RangeError('weekStartsOn must be between 0 and 6 inclusively') + } + + var locale$$1 = options.locale || locale; + var localeParsers = locale$$1.parsers || {}; + var localeUnits = locale$$1.units || {}; + + if (!locale$$1.match) { + throw new RangeError('locale must contain match property') + } + + if (!locale$$1.formatLong) { + throw new RangeError('locale must contain formatLong property') + } + + var formatString = String(dirtyFormatString) + .replace(longFormattingTokensRegExp$1, function (substring) { + if (substring[0] === '[') { + return substring + } + + if (substring[0] === '\\') { + return cleanEscapedString$1(substring) + } + + return locale$$1.formatLong(substring) + }); + + if (formatString === '') { + if (dateString === '') { + return toDate(dirtyBaseDate, options) + } else { + return new Date(NaN) + } + } + + var subFnOptions = cloneObject(options); + subFnOptions.locale = locale$$1; + + var tokens = formatString.match(locale$$1.parsingTokensRegExp || defaultParsingTokensRegExp); + var tokensLength = tokens.length; + + // If timezone isn't specified, it will be set to the system timezone + var setters = [{ + priority: TIMEZONE_UNIT_PRIORITY, + set: dateToSystemTimezone, + index: 0 + }]; + + var i; + for (i = 0; i < tokensLength; i++) { + var token = tokens[i]; + var parser = localeParsers[token] || parsers[token]; + if (parser) { + var matchResult; + + if (parser.match instanceof RegExp) { + matchResult = parser.match.exec(dateString); + } else { + matchResult = parser.match(dateString, subFnOptions); + } + + if (!matchResult) { + return new Date(NaN) + } + + var unitName = parser.unit; + var unit = localeUnits[unitName] || units[unitName]; + + setters.push({ + priority: unit.priority, + set: unit.set, + value: parser.parse(matchResult, subFnOptions), + index: setters.length + }); + + var substring = matchResult[0]; + dateString = dateString.slice(substring.length); + } else { + var head = tokens[i].match(/^\[.*]$/) ? tokens[i].replace(/^\[|]$/g, '') : tokens[i]; + if (dateString.indexOf(head) === 0) { + dateString = dateString.slice(head.length); + } else { + return new Date(NaN) + } + } + } + + var uniquePrioritySetters = setters + .map(function (setter) { + return setter.priority + }) + .sort(function (a, b) { + return a - b + }) + .filter(function (priority, index, array) { + return array.indexOf(priority) === index + }) + .map(function (priority) { + return setters + .filter(function (setter) { + return setter.priority === priority + }) + .reverse() + }) + .map(function (setterArray) { + return setterArray[0] + }); + + var date = toDate(dirtyBaseDate, options); + + if (isNaN(date)) { + return new Date(NaN) + } + + // Convert the date in system timezone to the same date in UTC+00:00 timezone. + // This ensures that when UTC functions will be implemented, locales will be compatible with them. + // See an issue about UTC functions: https://github.com/date-fns/date-fns/issues/37 + var utcDate = subMinutes(date, date.getTimezoneOffset()); + + var dateValues = {date: utcDate}; + + var settersLength = uniquePrioritySetters.length; + for (i = 0; i < settersLength; i++) { + var setter = uniquePrioritySetters[i]; + dateValues = setter.set(dateValues, setter.value, subFnOptions); + } + + return dateValues.date + } + + function dateToSystemTimezone (dateValues) { + var date = dateValues.date; + var time = date.getTime(); + + // Get the system timezone offset at (moment of time - offset) + var offset = date.getTimezoneOffset(); + + // Get the system timezone offset at the exact moment of time + offset = new Date(time + offset * MILLISECONDS_IN_MINUTE$7).getTimezoneOffset(); + + // Convert date in timezone "UTC+00:00" to the system timezone + dateValues.date = new Date(time + offset * MILLISECONDS_IN_MINUTE$7); + + return dateValues + } + + function cleanEscapedString$1 (input) { + if (input.match(/\[[\s\S]/)) { + return input.replace(/^\[|]$/g, '') + } + return input.replace(/\\/g, '') + } + + // This file is generated automatically by `scripts/build/indices.js`. Please, don't change it. + + // + + /** + * Custom parse behavior on top of date-fns parse function. + */ + function parseDate$1 (date, format$$1) { + if (typeof date !== 'string') { + return isValid(date) ? date : null; + } + + var parsed = parse(date, format$$1, new Date()); + + // if date is not valid or the formatted output after parsing does not match + // the string value passed in (avoids overflows) + if (!isValid(parsed) || format(parsed, format$$1) !== date) { + return null; + } + + return parsed; + } + + var afterValidator = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var targetValue = ref.targetValue; + var inclusion = ref.inclusion; if ( inclusion === void 0 ) inclusion = false; + var format$$1 = ref.format; + + if (typeof format$$1 === 'undefined') { + format$$1 = inclusion; + inclusion = false; + } + + value = parseDate$1(value, format$$1); + targetValue = parseDate$1(targetValue, format$$1); + + // if either is not valid. + if (!value || !targetValue) { + return false; + } + + return isAfter(value, targetValue) || (inclusion && isEqual(value, targetValue)); + }; + + var options = { + hasTarget: true, + isDate: true + }; + + // required to convert from a list of array values to an object. + var paramNames = ['targetValue', 'inclusion', 'format']; + + var after = { + validate: afterValidator, + options: options, + paramNames: paramNames + }; + + /** + * Some Alpha Regex helpers. + * https://github.com/chriso/validator.js/blob/master/src/lib/alpha.js + */ + + var alpha = { + en: /^[A-Z]*$/i, + cs: /^[A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]*$/i, + da: /^[A-ZÆØÅ]*$/i, + de: /^[A-ZÄÖÜß]*$/i, + es: /^[A-ZÁÉÍÑÓÚÜ]*$/i, + fr: /^[A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]*$/i, + lt: /^[A-ZĄČĘĖĮŠŲŪŽ]*$/i, + nl: /^[A-ZÉËÏÓÖÜ]*$/i, + hu: /^[A-ZÁÉÍÓÖŐÚÜŰ]*$/i, + pl: /^[A-ZĄĆĘŚŁŃÓŻŹ]*$/i, + pt: /^[A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]*$/i, + ru: /^[А-ЯЁ]*$/i, + sk: /^[A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ]*$/i, + sr: /^[A-ZČĆŽŠĐ]*$/i, + tr: /^[A-ZÇĞİıÖŞÜ]*$/i, + uk: /^[А-ЩЬЮЯЄІЇҐ]*$/i, + ar: /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]*$/ + }; + + var alphaSpaces = { + en: /^[A-Z\s]*$/i, + cs: /^[A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ\s]*$/i, + da: /^[A-ZÆØÅ\s]*$/i, + de: /^[A-ZÄÖÜß\s]*$/i, + es: /^[A-ZÁÉÍÑÓÚÜ\s]*$/i, + fr: /^[A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ\s]*$/i, + lt: /^[A-ZĄČĘĖĮŠŲŪŽ\s]*$/i, + nl: /^[A-ZÉËÏÓÖÜ\s]*$/i, + hu: /^[A-ZÁÉÍÓÖŐÚÜŰ\s]*$/i, + pl: /^[A-ZĄĆĘŚŁŃÓŻŹ\s]*$/i, + pt: /^[A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ\s]*$/i, + ru: /^[А-ЯЁ\s]*$/i, + sk: /^[A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ\s]*$/i, + sr: /^[A-ZČĆŽŠĐ\s]*$/i, + tr: /^[A-ZÇĞİıÖŞÜ\s]*$/i, + uk: /^[А-ЩЬЮЯЄІЇҐ\s]*$/i, + ar: /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ\s]*$/ + }; + + var alphanumeric = { + en: /^[0-9A-Z]*$/i, + cs: /^[0-9A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]*$/i, + da: /^[0-9A-ZÆØÅ]$/i, + de: /^[0-9A-ZÄÖÜß]*$/i, + es: /^[0-9A-ZÁÉÍÑÓÚÜ]*$/i, + fr: /^[0-9A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]*$/i, + lt: /^[0-9A-ZĄČĘĖĮŠŲŪŽ]*$/i, + hu: /^[0-9A-ZÁÉÍÓÖŐÚÜŰ]*$/i, + nl: /^[0-9A-ZÉËÏÓÖÜ]*$/i, + pl: /^[0-9A-ZĄĆĘŚŁŃÓŻŹ]*$/i, + pt: /^[0-9A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ]*$/i, + ru: /^[0-9А-ЯЁ]*$/i, + sk: /^[0-9A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ]*$/i, + sr: /^[0-9A-ZČĆŽŠĐ]*$/i, + tr: /^[0-9A-ZÇĞİıÖŞÜ]*$/i, + uk: /^[0-9А-ЩЬЮЯЄІЇҐ]*$/i, + ar: /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]*$/ + }; + + var alphaDash = { + en: /^[0-9A-Z_-]*$/i, + cs: /^[0-9A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ_-]*$/i, + da: /^[0-9A-ZÆØÅ_-]*$/i, + de: /^[0-9A-ZÄÖÜß_-]*$/i, + es: /^[0-9A-ZÁÉÍÑÓÚÜ_-]*$/i, + fr: /^[0-9A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ_-]*$/i, + lt: /^[0-9A-ZĄČĘĖĮŠŲŪŽ_-]*$/i, + nl: /^[0-9A-ZÉËÏÓÖÜ_-]*$/i, + hu: /^[0-9A-ZÁÉÍÓÖŐÚÜŰ_-]*$/i, + pl: /^[0-9A-ZĄĆĘŚŁŃÓŻŹ_-]*$/i, + pt: /^[0-9A-ZÃÁÀÂÇÉÊÍÕÓÔÚÜ_-]*$/i, + ru: /^[0-9А-ЯЁ_-]*$/i, + sk: /^[0-9A-ZÁÄČĎÉÍĹĽŇÓŔŠŤÚÝŽ_-]*$/i, + sr: /^[0-9A-ZČĆŽŠĐ_-]*$/i, + tr: /^[0-9A-ZÇĞİıÖŞÜ_-]*$/i, + uk: /^[0-9А-ЩЬЮЯЄІЇҐ_-]*$/i, + ar: /^[٠١٢٣٤٥٦٧٨٩0-9ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ_-]*$/ + }; + + var validate = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var locale = ref.locale; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate(val, [locale]); }); + } + + // Match at least one locale. + if (! locale) { + return Object.keys(alpha).some(function (loc) { return alpha[loc].test(value); }); + } + + return (alpha[locale] || alpha.en).test(value); + }; + + var paramNames$1 = ['locale']; + + var alpha$1 = { + validate: validate, + paramNames: paramNames$1 + }; + + var validate$1 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var locale = ref.locale; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$1(val, [locale]); }); + } + + // Match at least one locale. + if (! locale) { + return Object.keys(alphaDash).some(function (loc) { return alphaDash[loc].test(value); }); + } + + return (alphaDash[locale] || alphaDash.en).test(value); + }; + + var paramNames$2 = ['locale']; + + var alpha_dash = { + validate: validate$1, + paramNames: paramNames$2 + }; + + var validate$2 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var locale = ref.locale; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$2(val, [locale]); }); + } + + // Match at least one locale. + if (! locale) { + return Object.keys(alphanumeric).some(function (loc) { return alphanumeric[loc].test(value); }); + } + + return (alphanumeric[locale] || alphanumeric.en).test(value); + }; + + var paramNames$3 = ['locale']; + + var alpha_num = { + validate: validate$2, + paramNames: paramNames$3 + }; + + var validate$3 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var locale = ref.locale; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$3(val, [locale]); }); + } + + // Match at least one locale. + if (! locale) { + return Object.keys(alphaSpaces).some(function (loc) { return alphaSpaces[loc].test(value); }); + } + + return (alphaSpaces[locale] || alphaSpaces.en).test(value); + }; + + var paramNames$4 = ['locale']; + + var alpha_spaces = { + validate: validate$3, + paramNames: paramNames$4 + }; + + var validate$4 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var targetValue = ref.targetValue; + var inclusion = ref.inclusion; if ( inclusion === void 0 ) inclusion = false; + var format$$1 = ref.format; + + if (typeof format$$1 === 'undefined') { + format$$1 = inclusion; + inclusion = false; + } + + value = parseDate$1(value, format$$1); + targetValue = parseDate$1(targetValue, format$$1); + + // if either is not valid. + if (!value || !targetValue) { + return false; + } + + return isBefore(value, targetValue) || (inclusion && isEqual(value, targetValue)); + }; + + var options$1 = { + hasTarget: true, + isDate: true + }; + + var paramNames$5 = ['targetValue', 'inclusion', 'format']; + + var before = { + validate: validate$4, + options: options$1, + paramNames: paramNames$5 + }; + + var validate$5 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var min = ref.min; + var max = ref.max; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$5(val, { min: min, max: max }); }); + } + + return Number(min) <= value && Number(max) >= value; + }; + + var paramNames$6 = ['min', 'max']; + + var between = { + validate: validate$5, + paramNames: paramNames$6 + }; + + var validate$6 = function (value, ref) { + var targetValue = ref.targetValue; + + return String(value) === String(targetValue); + }; + var options$2 = { + hasTarget: true + }; + + var paramNames$7 = ['targetValue']; + + var confirmed = { + validate: validate$6, + options: options$2, + paramNames: paramNames$7 + }; + + function unwrapExports (x) { + return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x; + } + + function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; + } + + var assertString_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = assertString; + function assertString(input) { + var isString = typeof input === 'string' || input instanceof String; + + if (!isString) { + throw new TypeError('This library (validator.js) validates strings only'); + } + } + module.exports = exports['default']; + }); + + unwrapExports(assertString_1); + + var isCreditCard_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = isCreditCard; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + /* eslint-disable max-len */ + var creditCard = /^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|(222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}|6(?:011|5[0-9][0-9])[0-9]{12}|3[47][0-9]{13}|3(?:0[0-5]|[68][0-9])[0-9]{11}|(?:2131|1800|35\d{3})\d{11}|6[27][0-9]{14})$/; + /* eslint-enable max-len */ + + function isCreditCard(str) { + (0, _assertString2.default)(str); + var sanitized = str.replace(/[- ]+/g, ''); + if (!creditCard.test(sanitized)) { + return false; + } + var sum = 0; + var digit = void 0; + var tmpNum = void 0; + var shouldDouble = void 0; + for (var i = sanitized.length - 1; i >= 0; i--) { + digit = sanitized.substring(i, i + 1); + tmpNum = parseInt(digit, 10); + if (shouldDouble) { + tmpNum *= 2; + if (tmpNum >= 10) { + sum += tmpNum % 10 + 1; + } else { + sum += tmpNum; + } + } else { + sum += tmpNum; + } + shouldDouble = !shouldDouble; + } + return !!(sum % 10 === 0 ? sanitized : false); + } + module.exports = exports['default']; + }); + + var isCreditCard = unwrapExports(isCreditCard_1); + + var validate$7 = function (value) { return isCreditCard(String(value)); }; + + var credit_card = { + validate: validate$7 + }; + + var validate$8 = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var min$$1 = ref.min; + var max$$1 = ref.max; + var inclusivity = ref.inclusivity; if ( inclusivity === void 0 ) inclusivity = '()'; + var format$$1 = ref.format; + + if (typeof format$$1 === 'undefined') { + format$$1 = inclusivity; + inclusivity = '()'; + } + + var minDate = parseDate$1(String(min$$1), format$$1); + var maxDate = parseDate$1(String(max$$1), format$$1); + var dateVal = parseDate$1(String(value), format$$1); + + if (!minDate || !maxDate || !dateVal) { + return false; + } + + if (inclusivity === '()') { + return isAfter(dateVal, minDate) && isBefore(dateVal, maxDate); + } + + if (inclusivity === '(]') { + return isAfter(dateVal, minDate) && (isEqual(dateVal, maxDate) || isBefore(dateVal, maxDate)); + } + + if (inclusivity === '[)') { + return isBefore(dateVal, maxDate) && (isEqual(dateVal, minDate) || isAfter(dateVal, minDate)); + } + + return isEqual(dateVal, maxDate) || isEqual(dateVal, minDate) || + (isBefore(dateVal, maxDate) && isAfter(dateVal, minDate)); + }; + + var options$3 = { + isDate: true + }; + + var paramNames$8 = ['min', 'max', 'inclusivity', 'format']; + + var date_between = { + validate: validate$8, + options: options$3, + paramNames: paramNames$8 + }; + + var validate$9 = function (value, ref) { + var format = ref.format; + + return !!parseDate$1(value, format); + }; + + var options$4 = { + isDate: true + }; + + var paramNames$9 = ['format']; + + var date_format = { + validate: validate$9, + options: options$4, + paramNames: paramNames$9 + }; + + var validate$a = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var decimals = ref.decimals; if ( decimals === void 0 ) decimals = '*'; + var separator = ref.separator; if ( separator === void 0 ) separator = '.'; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$a(val, { decimals: decimals, separator: separator }); }); + } + + if (value === null || value === undefined || value === '') { + return true; + } + + // if is 0. + if (Number(decimals) === 0) { + return /^-?\d*$/.test(value); + } + + var regexPart = decimals === '*' ? '+' : ("{1," + decimals + "}"); + var regex = new RegExp(("^-?\\d*(\\" + separator + "\\d" + regexPart + ")?$")); + + if (! regex.test(value)) { + return false; + } + + var parsedValue = parseFloat(value); + + // eslint-disable-next-line + return parsedValue === parsedValue; + }; + + var paramNames$a = ['decimals', 'separator']; + + var decimal = { + validate: validate$a, + paramNames: paramNames$a + }; + + var validate$b = function (value, ref) { + var length = ref[0]; + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$b(val, [length]); }); + } + var strVal = String(value); + + return /^[0-9]*$/.test(strVal) && strVal.length === Number(length); + }; + + var digits = { + validate: validate$b + }; + + var validateImage = function (file, width, height) { + var URL = window.URL || window.webkitURL; + return new Promise(function (resolve) { + var image = new Image(); + image.onerror = function () { return resolve({ valid: false }); }; + image.onload = function () { return resolve({ + valid: image.width === Number(width) && image.height === Number(height) + }); }; + + image.src = URL.createObjectURL(file); + }); + }; + + var validate$c = function (files, ref) { + var width = ref[0]; + var height = ref[1]; + + var list = []; + for (var i = 0; i < files.length; i++) { + // if file is not an image, reject. + if (! /\.(jpg|svg|jpeg|png|bmp|gif)$/i.test(files[i].name)) { + return false; + } + + list.push(files[i]); + } + + return Promise.all(list.map(function (file) { return validateImage(file, width, height); })); + }; + + var dimensions = { + validate: validate$c + }; + + var merge_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = merge; + function merge() { + var obj = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {}; + var defaults = arguments[1]; + + for (var key in defaults) { + if (typeof obj[key] === 'undefined') { + obj[key] = defaults[key]; + } + } + return obj; + } + module.exports = exports['default']; + }); + + unwrapExports(merge_1); + + var isByteLength_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; + + exports.default = isByteLength; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + /* eslint-disable prefer-rest-params */ + function isByteLength(str, options) { + (0, _assertString2.default)(str); + var min = void 0; + var max = void 0; + if ((typeof options === 'undefined' ? 'undefined' : _typeof(options)) === 'object') { + min = options.min || 0; + max = options.max; + } else { + // backwards compatibility: isByteLength(str, min [, max]) + min = arguments[1]; + max = arguments[2]; + } + var len = encodeURI(str).split(/%..|./).length - 1; + return len >= min && (typeof max === 'undefined' || len <= max); + } + module.exports = exports['default']; + }); + + unwrapExports(isByteLength_1); + + var isFQDN_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = isFQDN; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + + + var _merge2 = _interopRequireDefault(merge_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + var default_fqdn_options = { + require_tld: true, + allow_underscores: false, + allow_trailing_dot: false + }; + + function isFQDN(str, options) { + (0, _assertString2.default)(str); + options = (0, _merge2.default)(options, default_fqdn_options); + + /* Remove the optional trailing dot before checking validity */ + if (options.allow_trailing_dot && str[str.length - 1] === '.') { + str = str.substring(0, str.length - 1); + } + var parts = str.split('.'); + for (var i = 0; i < parts.length; i++) { + if (parts[i].length > 63) { + return false; + } + } + if (options.require_tld) { + var tld = parts.pop(); + if (!parts.length || !/^([a-z\u00a1-\uffff]{2,}|xn[a-z0-9-]{2,})$/i.test(tld)) { + return false; + } + // disallow spaces + if (/[\s\u2002-\u200B\u202F\u205F\u3000\uFEFF\uDB40\uDC20]/.test(tld)) { + return false; + } + } + for (var part, _i = 0; _i < parts.length; _i++) { + part = parts[_i]; + if (options.allow_underscores) { + part = part.replace(/_/g, ''); + } + if (!/^[a-z\u00a1-\uffff0-9-]+$/i.test(part)) { + return false; + } + // disallow full-width chars + if (/[\uff01-\uff5e]/.test(part)) { + return false; + } + if (part[0] === '-' || part[part.length - 1] === '-') { + return false; + } + } + return true; + } + module.exports = exports['default']; + }); + + unwrapExports(isFQDN_1); + + var isIP_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = isIP; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + var ipv4Maybe = /^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/; + var ipv6Block = /^[0-9A-F]{1,4}$/i; + + function isIP(str) { + var version = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : ''; + + (0, _assertString2.default)(str); + version = String(version); + if (!version) { + return isIP(str, 4) || isIP(str, 6); + } else if (version === '4') { + if (!ipv4Maybe.test(str)) { + return false; + } + var parts = str.split('.').sort(function (a, b) { + return a - b; + }); + return parts[3] <= 255; + } else if (version === '6') { + var blocks = str.split(':'); + var foundOmissionBlock = false; // marker to indicate :: + + // At least some OS accept the last 32 bits of an IPv6 address + // (i.e. 2 of the blocks) in IPv4 notation, and RFC 3493 says + // that '::ffff:a.b.c.d' is valid for IPv4-mapped IPv6 addresses, + // and '::a.b.c.d' is deprecated, but also valid. + var foundIPv4TransitionBlock = isIP(blocks[blocks.length - 1], 4); + var expectedNumberOfBlocks = foundIPv4TransitionBlock ? 7 : 8; + + if (blocks.length > expectedNumberOfBlocks) { + return false; + } + // initial or final :: + if (str === '::') { + return true; + } else if (str.substr(0, 2) === '::') { + blocks.shift(); + blocks.shift(); + foundOmissionBlock = true; + } else if (str.substr(str.length - 2) === '::') { + blocks.pop(); + blocks.pop(); + foundOmissionBlock = true; + } + + for (var i = 0; i < blocks.length; ++i) { + // test for a :: which can not be at the string start/end + // since those cases have been handled above + if (blocks[i] === '' && i > 0 && i < blocks.length - 1) { + if (foundOmissionBlock) { + return false; // multiple :: in address + } + foundOmissionBlock = true; + } else if (foundIPv4TransitionBlock && i === blocks.length - 1) ; else if (!ipv6Block.test(blocks[i])) { + return false; + } + } + if (foundOmissionBlock) { + return blocks.length >= 1; + } + return blocks.length === expectedNumberOfBlocks; + } + return false; + } + module.exports = exports['default']; + }); + + var isIP = unwrapExports(isIP_1); + + var isEmail_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = isEmail; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + + + var _merge2 = _interopRequireDefault(merge_1); + + + + var _isByteLength2 = _interopRequireDefault(isByteLength_1); + + + + var _isFQDN2 = _interopRequireDefault(isFQDN_1); + + + + var _isIP2 = _interopRequireDefault(isIP_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + var default_email_options = { + allow_display_name: false, + require_display_name: false, + allow_utf8_local_part: true, + require_tld: true + }; + + /* eslint-disable max-len */ + /* eslint-disable no-control-regex */ + var displayName = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\,\.\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF\s]*<(.+)>$/i; + var emailUserPart = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~]+$/i; + var gmailUserPart = /^[a-z\d]+$/; + var quotedEmailUser = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f]))*$/i; + var emailUserUtf8Part = /^[a-z\d!#\$%&'\*\+\-\/=\?\^_`{\|}~\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+$/i; + var quotedEmailUserUtf8 = /^([\s\x01-\x08\x0b\x0c\x0e-\x1f\x7f\x21\x23-\x5b\x5d-\x7e\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]|(\\[\x01-\x09\x0b\x0c\x0d-\x7f\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))*$/i; + /* eslint-enable max-len */ + /* eslint-enable no-control-regex */ + + function isEmail(str, options) { + (0, _assertString2.default)(str); + options = (0, _merge2.default)(options, default_email_options); + + if (options.require_display_name || options.allow_display_name) { + var display_email = str.match(displayName); + if (display_email) { + str = display_email[1]; + } else if (options.require_display_name) { + return false; + } + } + + var parts = str.split('@'); + var domain = parts.pop(); + var user = parts.join('@'); + + var lower_domain = domain.toLowerCase(); + + if (options.domain_specific_validation && (lower_domain === 'gmail.com' || lower_domain === 'googlemail.com')) { + /* + Previously we removed dots for gmail addresses before validating. + This was removed because it allows `multiple..dots@gmail.com` + to be reported as valid, but it is not. + Gmail only normalizes single dots, removing them from here is pointless, + should be done in normalizeEmail + */ + user = user.toLowerCase(); + + // Removing sub-address from username before gmail validation + var username = user.split('+')[0]; + + // Dots are not included in gmail length restriction + if (!(0, _isByteLength2.default)(username.replace('.', ''), { min: 6, max: 30 })) { + return false; + } + + var _user_parts = username.split('.'); + for (var i = 0; i < _user_parts.length; i++) { + if (!gmailUserPart.test(_user_parts[i])) { + return false; + } + } + } + + if (!(0, _isByteLength2.default)(user, { max: 64 }) || !(0, _isByteLength2.default)(domain, { max: 254 })) { + return false; + } + + if (!(0, _isFQDN2.default)(domain, { require_tld: options.require_tld })) { + if (!options.allow_ip_domain) { + return false; + } + + if (!(0, _isIP2.default)(domain)) { + if (!domain.startsWith('[') || !domain.endsWith(']')) { + return false; + } + + var noBracketdomain = domain.substr(1, domain.length - 2); + + if (noBracketdomain.length === 0 || !(0, _isIP2.default)(noBracketdomain)) { + return false; + } + } + } + + if (user[0] === '"') { + user = user.slice(1, user.length - 1); + return options.allow_utf8_local_part ? quotedEmailUserUtf8.test(user) : quotedEmailUser.test(user); + } + + var pattern = options.allow_utf8_local_part ? emailUserUtf8Part : emailUserPart; + + var user_parts = user.split('.'); + for (var _i = 0; _i < user_parts.length; _i++) { + if (!pattern.test(user_parts[_i])) { + return false; + } + } + + return true; + } + module.exports = exports['default']; + }); + + var isEmail = unwrapExports(isEmail_1); + + var validate$d = function (value, options) { + if ( options === void 0 ) options = {}; + + if (options.multiple) { + value = value.split(',').map(function (emailStr) { return emailStr.trim(); }); + } + + if (Array.isArray(value)) { + return value.every(function (val) { return isEmail(String(val), options); }); + } + + return isEmail(String(value), options); + }; + + var email = { + validate: validate$d + }; + + // + + var supportsPassive = true; + + var detectPassiveSupport = function () { + try { + var opts = Object.defineProperty({}, 'passive', { + get: function get () { + supportsPassive = true; + } + }); + window.addEventListener('testPassive', null, opts); + window.removeEventListener('testPassive', null, opts); + } catch (e) { + supportsPassive = false; + } + return supportsPassive; + }; + + var addEventListener = function (el, eventName, cb) { + el.addEventListener(eventName, cb, supportsPassive ? { passive: true } : false); + }; + + var isTextInput = function (el) { + return includes(['text', 'password', 'search', 'email', 'tel', 'url', 'textarea'], el.type); + }; + + var isCheckboxOrRadioInput = function (el) { + return includes(['radio', 'checkbox'], el.type); + }; + + var isDateInput = function (el) { + return includes(['date', 'week', 'month', 'datetime-local', 'time'], el.type); + }; + + /** + * Gets the data attribute. the name must be kebab-case. + */ + var getDataAttribute = function (el, name) { return el.getAttribute(("data-vv-" + name)); }; + + /** + * Checks if the values are either null or undefined. + */ + var isNullOrUndefined = function () { + var values = [], len = arguments.length; + while ( len-- ) values[ len ] = arguments[ len ]; + + return values.every(function (value) { + return value === null || value === undefined; + }); + }; + + /** + * Creates the default flags object. + */ + var createFlags = function () { return ({ + untouched: true, + touched: false, + dirty: false, + pristine: true, + valid: null, + invalid: null, + validated: false, + pending: false, + required: false, + changed: false + }); }; + + /** + * Shallow object comparison. + */ + var isEqual$1 = function (lhs, rhs) { + if (lhs instanceof RegExp && rhs instanceof RegExp) { + return isEqual$1(lhs.source, rhs.source) && isEqual$1(lhs.flags, rhs.flags); + } + + if (Array.isArray(lhs) && Array.isArray(rhs)) { + if (lhs.length !== rhs.length) { return false; } + + for (var i = 0; i < lhs.length; i++) { + if (!isEqual$1(lhs[i], rhs[i])) { + return false; + } + } + + return true; + } + + // if both are objects, compare each key recursively. + if (isObject(lhs) && isObject(rhs)) { + return Object.keys(lhs).every(function (key) { + return isEqual$1(lhs[key], rhs[key]); + }) && Object.keys(rhs).every(function (key) { + return isEqual$1(lhs[key], rhs[key]); + }); + } + + return lhs === rhs; + }; + + /** + * Determines the input field scope. + */ + var getScope = function (el) { + var scope = getDataAttribute(el, 'scope'); + if (isNullOrUndefined(scope)) { + var form = getForm(el); + + if (form) { + scope = getDataAttribute(form, 'scope'); + } + } + + return !isNullOrUndefined(scope) ? scope : null; + }; + + /** + * Get the closest form element. + */ + var getForm = function (el) { + if (isNullOrUndefined(el)) { return null; } + + if (el.tagName === 'FORM') { return el; } + + if (!isNullOrUndefined(el.form)) { return el.form; } + + return !isNullOrUndefined(el.parentNode) ? getForm(el.parentNode) : null; + }; + + /** + * Gets the value in an object safely. + */ + var getPath = function (path, target, def) { + if ( def === void 0 ) def = undefined; + + if (!path || !target) { return def; } + + var value = target; + path.split('.').every(function (prop) { + if (prop in value) { + value = value[prop]; + + return true; + } + + value = def; + + return false; + }); + + return value; + }; + + /** + * Checks if path exists within an object. + */ + var hasPath = function (path, target) { + var obj = target; + return path.split('.').every(function (prop) { + if (prop in obj) { + obj = obj[prop]; + + return true; + } + + return false; + }); + }; + + /** + * Parses a rule string expression. + */ + var parseRule = function (rule) { + var params = []; + var name = rule.split(':')[0]; + + if (includes(rule, ':')) { + params = rule.split(':').slice(1).join(':').split(','); + } + + return { name: name, params: params }; + }; + + /** + * Debounces a function. + */ + var debounce = function (fn, wait, immediate, token) { + if ( wait === void 0 ) wait = 0; + if ( immediate === void 0 ) immediate = false; + if ( token === void 0 ) token = { cancelled: false }; + + if (wait === 0) { + return fn; + } + + var timeout; + + return function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + var later = function () { + timeout = null; + + if (!immediate && !token.cancelled) { fn.apply(void 0, args); } + }; + /* istanbul ignore next */ + var callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + /* istanbul ignore next */ + if (callNow) { fn.apply(void 0, args); } + }; + }; + + /** + * Appends a rule definition to a list of rules. + */ + var appendRule = function (rule, rules) { + if (!rules) { + return normalizeRules(rule); + } + + if (!rule) { + return normalizeRules(rules); + } + + if (typeof rules === 'string') { + rules = normalizeRules(rules); + } + + return assign({}, rules, normalizeRules(rule)); + }; + + /** + * Normalizes the given rules expression. + */ + var normalizeRules = function (rules) { + // if falsy value return an empty object. + if (!rules) { + return {}; + } + + if (isObject(rules)) { + // $FlowFixMe + return Object.keys(rules).reduce(function (prev, curr) { + var params = []; + // $FlowFixMe + if (rules[curr] === true) { + params = []; + } else if (Array.isArray(rules[curr])) { + params = rules[curr]; + } else if (isObject(rules[curr])) { + params = rules[curr]; + } else { + params = [rules[curr]]; + } + + // $FlowFixMe + if (rules[curr] !== false) { + prev[curr] = params; + } + + return prev; + }, {}); + } + + if (typeof rules !== 'string') { + warn('rules must be either a string or an object.'); + return {}; + } + + return rules.split('|').reduce(function (prev, rule) { + var parsedRule = parseRule(rule); + if (!parsedRule.name) { + return prev; + } + + prev[parsedRule.name] = parsedRule.params; + return prev; + }, {}); + }; + + /** + * Emits a warning to the console. + */ + var warn = function (message) { + console.warn(("[vee-validate] " + message)); // eslint-disable-line + }; + + /** + * Creates a branded error object. + */ + var createError = function (message) { return new Error(("[vee-validate] " + message)); }; + + /** + * Checks if the value is an object. + */ + var isObject = function (obj) { return obj !== null && obj && typeof obj === 'object' && ! Array.isArray(obj); }; + + /** + * Checks if a function is callable. + */ + var isCallable = function (func) { return typeof func === 'function'; }; + + /** + * Check if element has the css class on it. + */ + var hasClass = function (el, className) { + if (el.classList) { + return el.classList.contains(className); + } + + return !!el.className.match(new RegExp(("(\\s|^)" + className + "(\\s|$)"))); + }; + + /** + * Adds the provided css className to the element. + */ + var addClass = function (el, className) { + if (el.classList) { + el.classList.add(className); + return; + } + + if (!hasClass(el, className)) { + el.className += " " + className; + } + }; + + /** + * Remove the provided css className from the element. + */ + var removeClass = function (el, className) { + if (el.classList) { + el.classList.remove(className); + return; + } + + if (hasClass(el, className)) { + var reg = new RegExp(("(\\s|^)" + className + "(\\s|$)")); + el.className = el.className.replace(reg, ' '); + } + }; + + /** + * Adds or removes a class name on the input depending on the status flag. + */ + var toggleClass = function (el, className, status) { + if (!el || !className) { return; } + + if (Array.isArray(className)) { + className.forEach(function (item) { return toggleClass(el, item, status); }); + return; + } + + if (status) { + return addClass(el, className); + } + + removeClass(el, className); + }; + + /** + * Converts an array-like object to array, provides a simple polyfill for Array.from + */ + var toArray = function (arrayLike) { + if (isCallable(Array.from)) { + return Array.from(arrayLike); + } + + var array = []; + var length = arrayLike.length; + /* istanbul ignore next */ + for (var i = 0; i < length; i++) { + array.push(arrayLike[i]); + } + + /* istanbul ignore next */ + return array; + }; + + /** + * Assign polyfill from the mdn. + */ + var assign = function (target) { + var others = [], len = arguments.length - 1; + while ( len-- > 0 ) others[ len ] = arguments[ len + 1 ]; + + /* istanbul ignore else */ + if (isCallable(Object.assign)) { + return Object.assign.apply(Object, [ target ].concat( others )); + } + + /* istanbul ignore next */ + if (target == null) { + throw new TypeError('Cannot convert undefined or null to object'); + } + + /* istanbul ignore next */ + var to = Object(target); + /* istanbul ignore next */ + others.forEach(function (arg) { + // Skip over if undefined or null + if (arg != null) { + Object.keys(arg).forEach(function (key) { + to[key] = arg[key]; + }); + } + }); + /* istanbul ignore next */ + return to; + }; + + var id = 0; + var idTemplate = '{id}'; + + /** + * Generates a unique id. + */ + var uniqId = function () { + // handle too many uses of uniqId, although unlikely. + if (id >= 9999) { + id = 0; + // shift the template. + idTemplate = idTemplate.replace('{id}', '_{id}'); + } + + id++; + var newId = idTemplate.replace('{id}', String(id)); + + return newId; + }; + + /** + * finds the first element that satisfies the predicate callback, polyfills array.find + */ + var find = function (arrayLike, predicate) { + var array = Array.isArray(arrayLike) ? arrayLike : toArray(arrayLike); + for (var i = 0; i < array.length; i++) { + if (predicate(array[i])) { + return array[i]; + } + } + + return undefined; + }; + + var isBuiltInComponent = function (vnode) { + if (!vnode) { + return false; + } + + var tag = vnode.componentOptions.tag; + + return /^(keep-alive|transition|transition-group)$/.test(tag); + }; + + var makeEventsArray = function (events) { + return (typeof events === 'string' && events.length) ? events.split('|') : []; + }; + + var makeDelayObject = function (events, delay, delayConfig) { + if (typeof delay === 'number') { + return events.reduce(function (prev, e) { + prev[e] = delay; + return prev; + }, {}); + } + + return events.reduce(function (prev, e) { + if (typeof delay === 'object' && e in delay) { + prev[e] = delay[e]; + return prev; + } + + if (typeof delayConfig === 'number') { + prev[e] = delayConfig; + return prev; + } + + prev[e] = (delayConfig && delayConfig[e]) || 0; + + return prev; + }, {}); + }; + + var deepParseInt = function (input) { + if (typeof input === 'number') { return input; } + + if (typeof input === 'string') { return parseInt(input); } + + var map = {}; + for (var element in input) { + map[element] = parseInt(input[element]); + } + + return map; + }; + + var merge$1 = function (target, source) { + if (! (isObject(target) && isObject(source))) { + return target; + } + + Object.keys(source).forEach(function (key) { + var obj, obj$1; + + if (isObject(source[key])) { + if (! target[key]) { + assign(target, ( obj = {}, obj[key] = {}, obj )); + } + + merge$1(target[key], source[key]); + return; + } + + assign(target, ( obj$1 = {}, obj$1[key] = source[key], obj$1 )); + }); + + return target; + }; + + var fillRulesFromElement = function (el, rules) { + if (el.required) { + rules = appendRule('required', rules); + } + + if (isTextInput(el)) { + if (el.type === 'email') { + rules = appendRule(("email" + (el.multiple ? ':multiple' : '')), rules); + } + + if (el.pattern) { + rules = appendRule({ regex: el.pattern }, rules); + } + + // 524288 is the max on some browsers and test environments. + if (el.maxLength >= 0 && el.maxLength < 524288) { + rules = appendRule(("max:" + (el.maxLength)), rules); + } + + if (el.minLength > 0) { + rules = appendRule(("min:" + (el.minLength)), rules); + } + + return rules; + } + + if (el.type === 'number') { + rules = appendRule('decimal', rules); + if (el.min !== '') { + rules = appendRule(("min_value:" + (el.min)), rules); + } + + if (el.max !== '') { + rules = appendRule(("max_value:" + (el.max)), rules); + } + + return rules; + } + + if (isDateInput(el)) { + var timeFormat = el.step && Number(el.step) < 60 ? 'HH:mm:ss' : 'HH:mm'; + + if (el.type === 'date') { + return appendRule('date_format:YYYY-MM-DD', rules); + } + + if (el.type === 'datetime-local') { + return appendRule(("date_format:YYYY-MM-DDT" + timeFormat), rules); + } + + if (el.type === 'month') { + return appendRule('date_format:YYYY-MM', rules); + } + + if (el.type === 'week') { + return appendRule('date_format:YYYY-[W]WW', rules); + } + + if (el.type === 'time') { + return appendRule(("date_format:" + timeFormat), rules); + } + } + + return rules; + }; + + var values = function (obj) { + if (isCallable(Object.values)) { + return Object.values(obj); + } + + // fallback to keys() + /* istanbul ignore next */ + return obj[Object.keys(obj)[0]]; + }; + + var parseSelector = function (selector) { + var rule = null; + if (includes(selector, ':')) { + rule = selector.split(':').pop(); + selector = selector.replace((":" + rule), ''); + } + + if (selector[0] === '#') { + return { + id: selector.slice(1), + rule: rule, + name: null, + scope: null + }; + } + + var scope = null; + var name = selector; + if (includes(selector, '.')) { + var parts = selector.split('.'); + scope = parts[0]; + name = parts.slice(1).join('.'); + } + + return { + id: null, + scope: scope, + name: name, + rule: rule + }; + }; + + var includes = function (collection, item) { + return collection.indexOf(item) !== -1; + }; + + var validate$e = function (value, options) { + if (Array.isArray(value)) { + return value.every(function (val) { return validate$e(val, options); }); + } + + return toArray(options).some(function (item) { + // eslint-disable-next-line + return item == value; + }); + }; + + var included = { + validate: validate$e + }; + + var validate$f = function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + return !validate$e.apply(void 0, args); + }; + + var excluded = { + validate: validate$f + }; + + var validate$g = function (files, extensions) { + var regex = new RegExp((".(" + (extensions.join('|')) + ")$"), 'i'); + + return files.every(function (file) { return regex.test(file.name); }); + }; + + var ext = { + validate: validate$g + }; + + var validate$h = function (files) { return files.every(function (file) { return /\.(jpg|svg|jpeg|png|bmp|gif)$/i.test(file.name); }); }; + + var image = { + validate: validate$h + }; + + var validate$i = function (value) { + if (Array.isArray(value)) { + return value.every(function (val) { return /^-?[0-9]+$/.test(String(val)); }); + } + + return /^-?[0-9]+$/.test(String(value)); + }; + + var integer = { + validate: validate$i + }; + + var validate$j = function (value, ref) { + if ( ref === void 0 ) ref = {}; + var version = ref.version; if ( version === void 0 ) version = 4; + + if (isNullOrUndefined(value)) { + value = ''; + } + + if (Array.isArray(value)) { + return value.every(function (val) { return isIP(val, version); }); + } + + return isIP(value, version); + }; + + var paramNames$b = ['version']; + + var ip = { + validate: validate$j, + paramNames: paramNames$b + }; + + var validate$k = function (value, ref) { + if ( ref === void 0 ) ref = []; + var other = ref[0]; + + return value === other; + }; + + var is = { + validate: validate$k + }; + + var validate$l = function (value, ref) { + if ( ref === void 0 ) ref = []; + var other = ref[0]; + + return value !== other; + }; + + var is_not = { + validate: validate$l + }; + + /** + * @param {Array|String} value + * @param {Number} length + * @param {Number} max + */ + var compare = function (value, length, max) { + if (max === undefined) { + return value.length === length; + } + + // cast to number. + max = Number(max); + + return value.length >= length && value.length <= max; + }; + + var validate$m = function (value, ref) { + var length = ref[0]; + var max = ref[1]; if ( max === void 0 ) max = undefined; + + length = Number(length); + if (value === undefined || value === null) { + return false; + } + + if (typeof value === 'number') { + value = String(value); + } + + if (!value.length) { + value = toArray(value); + } + + return compare(value, length, max); + }; + + var length = { + validate: validate$m + }; + + var validate$n = function (value, ref) { + var length = ref[0]; + + if (value === undefined || value === null) { + return length >= 0; + } + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$n(val, [length]); }); + } + + return String(value).length <= length; + }; + + var max$1 = { + validate: validate$n + }; + + var validate$o = function (value, ref) { + var max = ref[0]; + + if (value === null || value === undefined || value === '') { + return false; + } + + if (Array.isArray(value)) { + return value.length > 0 && value.every(function (val) { return validate$o(val, [max]); }); + } + + return Number(value) <= max; + }; + + var max_value = { + validate: validate$o + }; + + var validate$p = function (files, mimes) { + var regex = new RegExp(((mimes.join('|').replace('*', '.+')) + "$"), 'i'); + + return files.every(function (file) { return regex.test(file.type); }); + }; + + var mimes = { + validate: validate$p + }; + + var validate$q = function (value, ref) { + var length = ref[0]; + + if (value === undefined || value === null) { + return false; + } + + if (Array.isArray(value)) { + return value.every(function (val) { return validate$q(val, [length]); }); + } + + return String(value).length >= length; + }; + + var min$1 = { + validate: validate$q + }; + + var validate$r = function (value, ref) { + var min = ref[0]; + + if (value === null || value === undefined || value === '') { + return false; + } + + if (Array.isArray(value)) { + return value.length > 0 && value.every(function (val) { return validate$r(val, [min]); }); + } + + return Number(value) >= min; + }; + + var min_value = { + validate: validate$r + }; + + var validate$s = function (value) { + if (Array.isArray(value)) { + return value.every(function (val) { return /^[0-9]+$/.test(String(val)); }); + } + + return /^[0-9]+$/.test(String(value)); + }; + + var numeric = { + validate: validate$s + }; + + var validate$t = function (value, ref) { + var expression = ref.expression; + + if (typeof expression === 'string') { + expression = new RegExp(expression); + } + + return expression.test(String(value)); + }; + + var paramNames$c = ['expression']; + + var regex = { + validate: validate$t, + paramNames: paramNames$c + }; + + var validate$u = function (value, ref) { + if ( ref === void 0 ) ref = []; + var invalidateFalse = ref[0]; if ( invalidateFalse === void 0 ) invalidateFalse = false; + + if (Array.isArray(value)) { + return !!value.length; + } + + // incase a field considers `false` as an empty value like checkboxes. + if (value === false && invalidateFalse) { + return false; + } + + if (value === undefined || value === null) { + return false; + } + + return !!String(value).trim().length; + }; + + var required = { + validate: validate$u + }; + + var validate$v = function (files, ref) { + var size = ref[0]; + + if (isNaN(size)) { + return false; + } + + var nSize = Number(size) * 1024; + for (var i = 0; i < files.length; i++) { + if (files[i].size > nSize) { + return false; + } + } + + return true; + }; + + var size = { + validate: validate$v + }; + + var isURL_1 = createCommonjsModule(function (module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + exports.default = isURL; + + + + var _assertString2 = _interopRequireDefault(assertString_1); + + + + var _isFQDN2 = _interopRequireDefault(isFQDN_1); + + + + var _isIP2 = _interopRequireDefault(isIP_1); + + + + var _merge2 = _interopRequireDefault(merge_1); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + + var default_url_options = { + protocols: ['http', 'https', 'ftp'], + require_tld: true, + require_protocol: false, + require_host: true, + require_valid_protocol: true, + allow_underscores: false, + allow_trailing_dot: false, + allow_protocol_relative_urls: false + }; + + var wrapped_ipv6 = /^\[([^\]]+)\](?::([0-9]+))?$/; + + function isRegExp(obj) { + return Object.prototype.toString.call(obj) === '[object RegExp]'; + } + + function checkHost(host, matches) { + for (var i = 0; i < matches.length; i++) { + var match = matches[i]; + if (host === match || isRegExp(match) && match.test(host)) { + return true; + } + } + return false; + } + + function isURL(url, options) { + (0, _assertString2.default)(url); + if (!url || url.length >= 2083 || /[\s<>]/.test(url)) { + return false; + } + if (url.indexOf('mailto:') === 0) { + return false; + } + options = (0, _merge2.default)(options, default_url_options); + var protocol = void 0, + auth = void 0, + host = void 0, + hostname = void 0, + port = void 0, + port_str = void 0, + split = void 0, + ipv6 = void 0; + + split = url.split('#'); + url = split.shift(); + + split = url.split('?'); + url = split.shift(); + + split = url.split('://'); + if (split.length > 1) { + protocol = split.shift().toLowerCase(); + if (options.require_valid_protocol && options.protocols.indexOf(protocol) === -1) { + return false; + } + } else if (options.require_protocol) { + return false; + } else if (url.substr(0, 2) === '//') { + if (!options.allow_protocol_relative_urls) { + return false; + } + split[0] = url.substr(2); + } + url = split.join('://'); + + if (url === '') { + return false; + } + + split = url.split('/'); + url = split.shift(); + + if (url === '' && !options.require_host) { + return true; + } + + split = url.split('@'); + if (split.length > 1) { + auth = split.shift(); + if (auth.indexOf(':') >= 0 && auth.split(':').length > 2) { + return false; + } + } + hostname = split.join('@'); + + port_str = null; + ipv6 = null; + var ipv6_match = hostname.match(wrapped_ipv6); + if (ipv6_match) { + host = ''; + ipv6 = ipv6_match[1]; + port_str = ipv6_match[2] || null; + } else { + split = hostname.split(':'); + host = split.shift(); + if (split.length) { + port_str = split.join(':'); + } + } + + if (port_str !== null) { + port = parseInt(port_str, 10); + if (!/^[0-9]+$/.test(port_str) || port <= 0 || port > 65535) { + return false; + } + } + + if (!(0, _isIP2.default)(host) && !(0, _isFQDN2.default)(host, options) && (!ipv6 || !(0, _isIP2.default)(ipv6, 6))) { + return false; + } + + host = host || ipv6; + + if (options.host_whitelist && !checkHost(host, options.host_whitelist)) { + return false; + } + if (options.host_blacklist && checkHost(host, options.host_blacklist)) { + return false; + } + + return true; + } + module.exports = exports['default']; + }); + + var isURL = unwrapExports(isURL_1); + + var validate$w = function (value, options) { + if ( options === void 0 ) options = {}; + + if (isNullOrUndefined(value)) { + value = ''; + } + + if (Array.isArray(value)) { + return value.every(function (val) { return isURL(val, options); }); + } + + return isURL(value, options); + }; + + var url = { + validate: validate$w + }; + + /* eslint-disable camelcase */ + + var Rules = /*#__PURE__*/Object.freeze({ + after: after, + alpha_dash: alpha_dash, + alpha_num: alpha_num, + alpha_spaces: alpha_spaces, + alpha: alpha$1, + before: before, + between: between, + confirmed: confirmed, + credit_card: credit_card, + date_between: date_between, + date_format: date_format, + decimal: decimal, + digits: digits, + dimensions: dimensions, + email: email, + ext: ext, + image: image, + included: included, + integer: integer, + length: length, + ip: ip, + is_not: is_not, + is: is, + max: max$1, + max_value: max_value, + mimes: mimes, + min: min$1, + min_value: min_value, + excluded: excluded, + numeric: numeric, + regex: regex, + required: required, + size: size, + url: url + }); + + /** + * Formates file size. + * + * @param {Number|String} size + */ + var formatFileSize = function (size) { + var units = ['Byte', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + var threshold = 1024; + size = Number(size) * threshold; + var i = size === 0 ? 0 : Math.floor(Math.log(size) / Math.log(threshold)); + return (((size / Math.pow(threshold, i)).toFixed(2) * 1) + " " + (units[i])); + }; + + /** + * Checks if vee-validate is defined globally. + */ + var isDefinedGlobally = function () { + return typeof VeeValidate !== 'undefined'; + }; + + var obj; + + var messages = { + _default: function (field) { return ("The " + field + " value is not valid."); }, + after: function (field, ref) { + var target = ref[0]; + var inclusion = ref[1]; + + return ("The " + field + " must be after " + (inclusion ? 'or equal to ' : '') + target + "."); + }, + alpha_dash: function (field) { return ("The " + field + " field may contain alpha-numeric characters as well as dashes and underscores."); }, + alpha_num: function (field) { return ("The " + field + " field may only contain alpha-numeric characters."); }, + alpha_spaces: function (field) { return ("The " + field + " field may only contain alphabetic characters as well as spaces."); }, + alpha: function (field) { return ("The " + field + " field may only contain alphabetic characters."); }, + before: function (field, ref) { + var target = ref[0]; + var inclusion = ref[1]; + + return ("The " + field + " must be before " + (inclusion ? 'or equal to ' : '') + target + "."); + }, + between: function (field, ref) { + var min = ref[0]; + var max = ref[1]; + + return ("The " + field + " field must be between " + min + " and " + max + "."); + }, + confirmed: function (field) { return ("The " + field + " confirmation does not match."); }, + credit_card: function (field) { return ("The " + field + " field is invalid."); }, + date_between: function (field, ref) { + var min = ref[0]; + var max = ref[1]; + + return ("The " + field + " must be between " + min + " and " + max + "."); + }, + date_format: function (field, ref) { + var format = ref[0]; + + return ("The " + field + " must be in the format " + format + "."); + }, + decimal: function (field, ref) { + if ( ref === void 0 ) ref = []; + var decimals = ref[0]; if ( decimals === void 0 ) decimals = '*'; + + return ("The " + field + " field must be numeric and may contain " + (!decimals || decimals === '*' ? '' : decimals) + " decimal points."); + }, + digits: function (field, ref) { + var length = ref[0]; + + return ("The " + field + " field must be numeric and exactly contain " + length + " digits."); + }, + dimensions: function (field, ref) { + var width = ref[0]; + var height = ref[1]; + + return ("The " + field + " field must be " + width + " pixels by " + height + " pixels."); + }, + email: function (field) { return ("The " + field + " field must be a valid email."); }, + ext: function (field) { return ("The " + field + " field must be a valid file."); }, + image: function (field) { return ("The " + field + " field must be an image."); }, + included: function (field) { return ("The " + field + " field must be a valid value."); }, + integer: function (field) { return ("The " + field + " field must be an integer."); }, + ip: function (field) { return ("The " + field + " field must be a valid ip address."); }, + length: function (field, ref) { + var length = ref[0]; + var max = ref[1]; + + if (max) { + return ("The " + field + " length must be between " + length + " and " + max + "."); + } + + return ("The " + field + " length must be " + length + "."); + }, + max: function (field, ref) { + var length = ref[0]; + + return ("The " + field + " field may not be greater than " + length + " characters."); + }, + max_value: function (field, ref) { + var max = ref[0]; + + return ("The " + field + " field must be " + max + " or less."); + }, + mimes: function (field) { return ("The " + field + " field must have a valid file type."); }, + min: function (field, ref) { + var length = ref[0]; + + return ("The " + field + " field must be at least " + length + " characters."); + }, + min_value: function (field, ref) { + var min = ref[0]; + + return ("The " + field + " field must be " + min + " or more."); + }, + excluded: function (field) { return ("The " + field + " field must be a valid value."); }, + numeric: function (field) { return ("The " + field + " field may only contain numeric characters."); }, + regex: function (field) { return ("The " + field + " field format is invalid."); }, + required: function (field) { return ("The " + field + " field is required."); }, + size: function (field, ref) { + var size = ref[0]; + + return ("The " + field + " size must be less than " + (formatFileSize(size)) + "."); + }, + url: function (field) { return ("The " + field + " field is not a valid URL."); } + }; + + var locale$1 = { + name: 'en', + messages: messages, + attributes: {} + }; + + if (isDefinedGlobally()) { + // eslint-disable-next-line + VeeValidate.Validator.localize(( obj = {}, obj[locale$1.name] = locale$1, obj )); + } + + // + + var LOCALE = 'en'; + + var Dictionary = function Dictionary (dictionary) { + if ( dictionary === void 0 ) dictionary = {}; + + this.container = {}; + this.merge(dictionary); + }; + + var prototypeAccessors = { locale: { configurable: true } }; + + prototypeAccessors.locale.get = function () { + return LOCALE; + }; + + prototypeAccessors.locale.set = function (value) { + LOCALE = value || 'en'; + }; + + Dictionary.prototype.hasLocale = function hasLocale (locale) { + return !!this.container[locale]; + }; + + Dictionary.prototype.setDateFormat = function setDateFormat (locale, format) { + if (!this.container[locale]) { + this.container[locale] = {}; + } + + this.container[locale].dateFormat = format; + }; + + Dictionary.prototype.getDateFormat = function getDateFormat (locale) { + if (!this.container[locale] || !this.container[locale].dateFormat) { + return null; + } + + return this.container[locale].dateFormat; + }; + + Dictionary.prototype.getMessage = function getMessage (locale, key, data) { + var message = null; + if (!this.hasMessage(locale, key)) { + message = this._getDefaultMessage(locale); + } else { + message = this.container[locale].messages[key]; + } + + return isCallable(message) ? message.apply(void 0, data) : message; + }; + + /** + * Gets a specific message for field. falls back to the rule message. + */ + Dictionary.prototype.getFieldMessage = function getFieldMessage (locale, field, key, data) { + if (!this.hasLocale(locale)) { + return this.getMessage(locale, key, data); + } + + var dict = this.container[locale].custom && this.container[locale].custom[field]; + if (!dict || !dict[key]) { + return this.getMessage(locale, key, data); + } + + var message = dict[key]; + return isCallable(message) ? message.apply(void 0, data) : message; + }; + + Dictionary.prototype._getDefaultMessage = function _getDefaultMessage (locale) { + if (this.hasMessage(locale, '_default')) { + return this.container[locale].messages._default; + } + + return this.container.en.messages._default; + }; + + Dictionary.prototype.getAttribute = function getAttribute (locale, key, fallback) { + if ( fallback === void 0 ) fallback = ''; + + if (!this.hasAttribute(locale, key)) { + return fallback; + } + + return this.container[locale].attributes[key]; + }; + + Dictionary.prototype.hasMessage = function hasMessage (locale, key) { + return !! ( + this.hasLocale(locale) && + this.container[locale].messages && + this.container[locale].messages[key] + ); + }; + + Dictionary.prototype.hasAttribute = function hasAttribute (locale, key) { + return !! ( + this.hasLocale(locale) && + this.container[locale].attributes && + this.container[locale].attributes[key] + ); + }; + + Dictionary.prototype.merge = function merge$1$$1 (dictionary) { + merge$1(this.container, dictionary); + }; + + Dictionary.prototype.setMessage = function setMessage (locale, key, message) { + if (! this.hasLocale(locale)) { + this.container[locale] = { + messages: {}, + attributes: {} + }; + } + + this.container[locale].messages[key] = message; + }; + + Dictionary.prototype.setAttribute = function setAttribute (locale, key, attribute) { + if (! this.hasLocale(locale)) { + this.container[locale] = { + messages: {}, + attributes: {} + }; + } + + this.container[locale].attributes[key] = attribute; + }; + + Object.defineProperties( Dictionary.prototype, prototypeAccessors ); + + // + + var normalizeValue = function (value) { + if (isObject(value)) { + return Object.keys(value).reduce(function (prev, key) { + prev[key] = normalizeValue(value[key]); + + return prev; + }, {}); + } + + if (isCallable(value)) { + return value('{0}', ['{1}', '{2}', '{3}']); + } + + return value; + }; + + var normalizeFormat = function (locale) { + // normalize messages + var dictionary = {}; + if (locale.messages) { + dictionary.messages = normalizeValue(locale.messages); + } + + if (locale.custom) { + dictionary.custom = normalizeValue(locale.custom); + } + + if (locale.attributes) { + dictionary.attributes = locale.attributes; + } + + if (!isNullOrUndefined(locale.dateFormat)) { + dictionary.dateFormat = locale.dateFormat; + } + + return dictionary; + }; + + var I18nDictionary = function I18nDictionary (i18n, rootKey) { + this.i18n = i18n; + this.rootKey = rootKey; + }; + + var prototypeAccessors$1 = { locale: { configurable: true } }; + + prototypeAccessors$1.locale.get = function () { + return this.i18n.locale; + }; + + prototypeAccessors$1.locale.set = function (value) { + warn('Cannot set locale from the validator when using vue-i18n, use i18n.locale setter instead'); + }; + + I18nDictionary.prototype.getDateFormat = function getDateFormat (locale) { + return this.i18n.getDateTimeFormat(locale || this.locale); + }; + + I18nDictionary.prototype.setDateFormat = function setDateFormat (locale, value) { + this.i18n.setDateTimeFormat(locale || this.locale, value); + }; + + I18nDictionary.prototype.getMessage = function getMessage (locale, key, data) { + var path = (this.rootKey) + ".messages." + key; + if (!this.i18n.te(path)) { + return this.i18n.t(((this.rootKey) + ".messages._default"), locale, data); + } + + return this.i18n.t(path, locale, data); + }; + + I18nDictionary.prototype.getAttribute = function getAttribute (locale, key, fallback) { + if ( fallback === void 0 ) fallback = ''; + + var path = (this.rootKey) + ".attributes." + key; + if (!this.i18n.te(path)) { + return fallback; + } + + return this.i18n.t(path, locale); + }; + + I18nDictionary.prototype.getFieldMessage = function getFieldMessage (locale, field, key, data) { + var path = (this.rootKey) + ".custom." + field + "." + key; + if (this.i18n.te(path)) { + return this.i18n.t(path, locale, data); + } + + return this.getMessage(locale, key, data); + }; + + I18nDictionary.prototype.merge = function merge$1$$1 (dictionary) { + var this$1 = this; + + Object.keys(dictionary).forEach(function (localeKey) { + var obj; + + // i18n doesn't deep merge + // first clone the existing locale (avoid mutations to locale) + var clone = merge$1({}, getPath((localeKey + "." + (this$1.rootKey)), this$1.i18n.messages, {})); + // Merge cloned locale with new one + var locale = merge$1(clone, normalizeFormat(dictionary[localeKey])); + this$1.i18n.mergeLocaleMessage(localeKey, ( obj = {}, obj[this$1.rootKey] = locale, obj )); + if (locale.dateFormat) { + this$1.i18n.setDateTimeFormat(localeKey, locale.dateFormat); + } + }); + }; + + I18nDictionary.prototype.setMessage = function setMessage (locale, key, value) { + var obj, obj$1; + + this.merge(( obj$1 = {}, obj$1[locale] = { + messages: ( obj = {}, obj[key] = value, obj ) + }, obj$1 )); + }; + + I18nDictionary.prototype.setAttribute = function setAttribute (locale, key, value) { + var obj, obj$1; + + this.merge(( obj$1 = {}, obj$1[locale] = { + attributes: ( obj = {}, obj[key] = value, obj ) + }, obj$1 )); + }; + + Object.defineProperties( I18nDictionary.prototype, prototypeAccessors$1 ); + + // + + var defaultConfig = { + locale: 'en', + delay: 0, + errorBagName: 'errors', + dictionary: null, + strict: true, + fieldsBagName: 'fields', + classes: false, + classNames: null, + events: 'input', + inject: true, + fastExit: true, + aria: true, + validity: false, + i18n: null, + i18nRootKey: 'validation' + }; + + var currentConfig = assign({}, defaultConfig); + var dependencies = { + dictionary: new Dictionary({ + en: { + messages: {}, + attributes: {}, + custom: {} + } + }) + }; + + var Config = function Config () {}; + + var staticAccessors = { default: { configurable: true },current: { configurable: true } }; + + staticAccessors.default.get = function () { + return defaultConfig; + }; + + staticAccessors.current.get = function () { + return currentConfig; + }; + + Config.dependency = function dependency (key) { + return dependencies[key]; + }; + + /** + * Merges the config with a new one. + */ + Config.merge = function merge (config) { + currentConfig = assign({}, currentConfig, config); + if (currentConfig.i18n) { + Config.register('dictionary', new I18nDictionary(currentConfig.i18n, currentConfig.i18nRootKey)); + } + }; + + /** + * Registers a dependency. + */ + Config.register = function register (key, value) { + dependencies[key] = value; + }; + + /** + * Resolves the working config from a Vue instance. + */ + Config.resolve = function resolve (context) { + var selfConfig = getPath('$options.$_veeValidate', context, {}); + + return assign({}, Config.current, selfConfig); + }; + + Object.defineProperties( Config, staticAccessors ); + + // + + var ErrorBag = function ErrorBag (errorBag, id) { + if ( errorBag === void 0 ) errorBag = null; + if ( id === void 0 ) id = null; + + this.vmId = id || null; + // make this bag a mirror of the provided one, sharing the same items reference. + if (errorBag && errorBag instanceof ErrorBag) { + this.items = errorBag.items; + } else { + this.items = []; + } + }; + + ErrorBag.prototype[typeof Symbol === 'function' ? Symbol.iterator : '@@iterator'] = function () { + var this$1 = this; + + var index = 0; + return { + next: function () { + return { value: this$1.items[index++], done: index > this$1.items.length }; + } + }; + }; + + /** + * Adds an error to the internal array. + */ + ErrorBag.prototype.add = function add (error) { + var ref; + + (ref = this.items).push.apply( + ref, this._normalizeError(error) + ); + }; + + /** + * Normalizes passed errors to an error array. + */ + ErrorBag.prototype._normalizeError = function _normalizeError (error) { + var this$1 = this; + + if (Array.isArray(error)) { + return error.map(function (e) { + e.scope = !isNullOrUndefined(e.scope) ? e.scope : null; + e.vmId = !isNullOrUndefined(e.vmId) ? e.vmId : (this$1.vmId || null); + + return e; + }); + } + + error.scope = !isNullOrUndefined(error.scope) ? error.scope : null; + error.vmId = !isNullOrUndefined(error.vmId) ? error.vmId : (this.vmId || null); + + return [error]; + }; + + /** + * Regenrates error messages if they have a generator function. + */ + ErrorBag.prototype.regenerate = function regenerate () { + this.items.forEach(function (i) { + i.msg = isCallable(i.regenerate) ? i.regenerate() : i.msg; + }); + }; + + /** + * Updates a field error with the new field scope. + */ + ErrorBag.prototype.update = function update (id, error) { + var item = find(this.items, function (i) { return i.id === id; }); + if (!item) { + return; + } + + var idx = this.items.indexOf(item); + this.items.splice(idx, 1); + item.scope = error.scope; + this.items.push(item); + }; + + /** + * Gets all error messages from the internal array. + */ + ErrorBag.prototype.all = function all (scope) { + var this$1 = this; + + var filterFn = function (item) { + var matchesScope = true; + var matchesVM = true; + if (!isNullOrUndefined(scope)) { + matchesScope = item.scope === scope; + } + + if (!isNullOrUndefined(this$1.vmId)) { + matchesVM = item.vmId === this$1.vmId; + } + + return matchesVM && matchesScope; + }; + + return this.items.filter(filterFn).map(function (e) { return e.msg; }); + }; + + /** + * Checks if there are any errors in the internal array. + */ + ErrorBag.prototype.any = function any (scope) { + var this$1 = this; + + var filterFn = function (item) { + var matchesScope = true; + if (!isNullOrUndefined(scope)) { + matchesScope = item.scope === scope; + } + + if (!isNullOrUndefined(this$1.vmId)) { + matchesScope = item.vmId === this$1.vmId; + } + + return matchesScope; + }; + + return !!this.items.filter(filterFn).length; + }; + + /** + * Removes all items from the internal array. + */ + ErrorBag.prototype.clear = function clear (scope) { + var this$1 = this; + + var matchesVM = isNullOrUndefined(this.vmId) ? function () { return true; } : function (i) { return i.vmId === this$1.vmId; }; + if (isNullOrUndefined(scope)) { + scope = null; + } + + for (var i = 0; i < this.items.length; ++i) { + if (matchesVM(this$1.items[i]) && this$1.items[i].scope === scope) { + this$1.items.splice(i, 1); + --i; + } + } + }; + + /** + * Collects errors into groups or for a specific field. + */ + ErrorBag.prototype.collect = function collect (field, scope, map) { + var this$1 = this; + if ( map === void 0 ) map = true; + + var isSingleField = !isNullOrUndefined(field) && !field.includes('*'); + var groupErrors = function (items) { + var errors = items.reduce(function (collection, error) { + if (!isNullOrUndefined(this$1.vmId) && error.vmId !== this$1.vmId) { + return collection; + } + + if (!collection[error.field]) { + collection[error.field] = []; + } + + collection[error.field].push(map ? error.msg : error); + + return collection; + }, {}); + + // reduce the collection to be a single array. + if (isSingleField) { + return values(errors)[0] || []; + } + + return errors; + }; + + if (isNullOrUndefined(field)) { + return groupErrors(this.items); + } + + var selector = isNullOrUndefined(scope) ? String(field) : (scope + "." + field); + var ref = this._makeCandidateFilters(selector); + var isPrimary = ref.isPrimary; + var isAlt = ref.isAlt; + + var collected = this.items.reduce(function (prev, curr) { + if (isPrimary(curr)) { + prev.primary.push(curr); + } + + if (isAlt(curr)) { + prev.alt.push(curr); + } + + return prev; + }, { primary: [], alt: [] }); + + collected = collected.primary.length ? collected.primary : collected.alt; + + return groupErrors(collected); + }; + + /** + * Gets the internal array length. + */ + ErrorBag.prototype.count = function count () { + var this$1 = this; + + if (this.vmId) { + return this.items.filter(function (e) { return e.vmId === this$1.vmId; }).length; + } + + return this.items.length; + }; + + /** + * Finds and fetches the first error message for the specified field id. + */ + ErrorBag.prototype.firstById = function firstById (id) { + var error = find(this.items, function (i) { return i.id === id; }); + + return error ? error.msg : undefined; + }; + + /** + * Gets the first error message for a specific field. + */ + ErrorBag.prototype.first = function first (field, scope) { + if ( scope === void 0 ) scope = null; + + var selector = isNullOrUndefined(scope) ? field : (scope + "." + field); + var match = this._match(selector); + + return match && match.msg; + }; + + /** + * Returns the first error rule for the specified field + */ + ErrorBag.prototype.firstRule = function firstRule (field, scope) { + var errors = this.collect(field, scope, false); + + return (errors.length && errors[0].rule) || undefined; + }; + + /** + * Checks if the internal array has at least one error for the specified field. + */ + ErrorBag.prototype.has = function has (field, scope) { + if ( scope === void 0 ) scope = null; + + return !!this.first(field, scope); + }; + + /** + * Gets the first error message for a specific field and a rule. + */ + ErrorBag.prototype.firstByRule = function firstByRule (name, rule, scope) { + if ( scope === void 0 ) scope = null; + + var error = this.collect(name, scope, false).filter(function (e) { return e.rule === rule; })[0]; + + return (error && error.msg) || undefined; + }; + + /** + * Gets the first error message for a specific field that not match the rule. + */ + ErrorBag.prototype.firstNot = function firstNot (name, rule, scope) { + if ( rule === void 0 ) rule = 'required'; + if ( scope === void 0 ) scope = null; + + var error = this.collect(name, scope, false).filter(function (e) { return e.rule !== rule; })[0]; + + return (error && error.msg) || undefined; + }; + + /** + * Removes errors by matching against the id or ids. + */ + ErrorBag.prototype.removeById = function removeById (id) { + var this$1 = this; + + var condition = function (item) { return item.id === id; }; + if (Array.isArray(id)) { + condition = function (item) { return id.indexOf(item.id) !== -1; }; + } + + for (var i = 0; i < this.items.length; ++i) { + if (condition(this$1.items[i])) { + this$1.items.splice(i, 1); + --i; + } + } + }; + + /** + * Removes all error messages associated with a specific field. + */ + ErrorBag.prototype.remove = function remove (field, scope, vmId) { + var this$1 = this; + + if (isNullOrUndefined(field)) { + return; + } + + var selector = isNullOrUndefined(scope) ? String(field) : (scope + "." + field); + var ref = this._makeCandidateFilters(selector); + var isPrimary = ref.isPrimary; + var shouldRemove = function (item) { + if (isNullOrUndefined(vmId)) { return isPrimary(item); } + + return isPrimary(item) && item.vmId === vmId; + }; + + for (var i = 0; i < this.items.length; ++i) { + if (shouldRemove(this$1.items[i])) { + this$1.items.splice(i, 1); + --i; + } + } + }; + + ErrorBag.prototype._makeCandidateFilters = function _makeCandidateFilters (selector) { + var this$1 = this; + + var matchesRule = function () { return true; }; + var matchesScope = function () { return true; }; + var matchesName = function () { return true; }; + var matchesVM = function () { return true; }; + + var ref = parseSelector(selector); + var id = ref.id; + var rule = ref.rule; + var scope = ref.scope; + var name = ref.name; + + if (rule) { + matchesRule = function (item) { return item.rule === rule; }; + } + + // match by id, can be combined with rule selection. + if (id) { + return { + isPrimary: function (item) { return matchesRule(item) && (function (item) { return id === item.id; }); }, + isAlt: function () { return false; } + }; + } + + if (isNullOrUndefined(scope)) { + // if no scope specified, make sure the found error has no scope. + matchesScope = function (item) { return isNullOrUndefined(item.scope); }; + } else { + matchesScope = function (item) { return item.scope === scope; }; + } + + if (!isNullOrUndefined(name) && name !== '*') { + matchesName = function (item) { return item.field === name; }; + } + + if (!isNullOrUndefined(this.vmId)) { + matchesVM = function (item) { return item.vmId === this$1.vmId; }; + } + + // matches the first candidate. + var isPrimary = function (item) { + return matchesVM(item) && matchesName(item) && matchesRule(item) && matchesScope(item); + }; + + // matches a second candidate, which is a field with a name containing the '.' character. + var isAlt = function (item) { + return matchesVM(item) && matchesRule(item) && item.field === (scope + "." + name); + }; + + return { + isPrimary: isPrimary, + isAlt: isAlt + }; + }; + + ErrorBag.prototype._match = function _match (selector) { + if (isNullOrUndefined(selector)) { + return undefined; + } + + var ref = this._makeCandidateFilters(selector); + var isPrimary = ref.isPrimary; + var isAlt = ref.isAlt; + + return this.items.reduce(function (prev, item, idx, arr) { + var isLast = idx === arr.length - 1; + if (prev.primary) { + return isLast ? prev.primary : prev; + } + + if (isPrimary(item)) { + prev.primary = item; + } + + if (isAlt(item)) { + prev.alt = item; + } + + // keep going. + if (!isLast) { + return prev; + } + + return prev.primary || prev.alt; + }, {}); + }; + + /** + * Generates the options required to construct a field. + */ + var Resolver = function Resolver () {}; + + Resolver.generate = function generate (el, binding, vnode) { + var model = Resolver.resolveModel(binding, vnode); + var options = Config.resolve(vnode.context); + + return { + name: Resolver.resolveName(el, vnode), + el: el, + listen: !binding.modifiers.disable, + bails: binding.modifiers.bails ? true : (binding.modifiers.continues === true ? false : undefined), + scope: Resolver.resolveScope(el, binding, vnode), + vm: Resolver.makeVM(vnode.context), + expression: binding.value, + component: vnode.componentInstance, + classes: options.classes, + classNames: options.classNames, + getter: Resolver.resolveGetter(el, vnode, model), + events: Resolver.resolveEvents(el, vnode) || options.events, + model: model, + delay: Resolver.resolveDelay(el, vnode, options), + rules: Resolver.resolveRules(el, binding, vnode), + immediate: !!binding.modifiers.initial || !!binding.modifiers.immediate, + validity: options.validity, + aria: options.aria, + initialValue: Resolver.resolveInitialValue(vnode) + }; + }; + + Resolver.getCtorConfig = function getCtorConfig (vnode) { + if (!vnode.componentInstance) { return null; } + + var config = getPath('componentInstance.$options.$_veeValidate', vnode); + + return config; + }; + + /** + * Resolves the rules defined on an element. + */ + Resolver.resolveRules = function resolveRules (el, binding, vnode) { + var rules = ''; + if (!binding.value && (!binding || !binding.expression)) { + rules = getDataAttribute(el, 'rules'); + } + + if (binding.value && includes(['string', 'object'], typeof binding.value.rules)) { + rules = binding.value.rules; + } else if (binding.value) { + rules = binding.value; + } + + if (vnode.componentInstance) { + return rules; + } + + return fillRulesFromElement(el, rules); + }; + + /** + * @param {*} vnode + */ + Resolver.resolveInitialValue = function resolveInitialValue (vnode) { + var model = vnode.data.model || find(vnode.data.directives, function (d) { return d.name === 'model'; }); + + return model && model.value; + }; + + /** + * Creates a non-circular partial VM instance from a Vue instance. + * @param {*} vm + */ + Resolver.makeVM = function makeVM (vm) { + return { + get $el () { + return vm.$el; + }, + get $refs () { + return vm.$refs; + }, + $watch: vm.$watch ? vm.$watch.bind(vm) : function () {}, + $validator: vm.$validator ? { + errors: vm.$validator.errors, + validate: vm.$validator.validate.bind(vm.$validator), + update: vm.$validator.update.bind(vm.$validator) + } : null + }; + }; + + /** + * Resolves the delay value. + * @param {*} el + * @param {*} vnode + * @param {Object} options + */ + Resolver.resolveDelay = function resolveDelay (el, vnode, options) { + var delay = getDataAttribute(el, 'delay'); + var globalDelay = (options && 'delay' in options) ? options.delay : 0; + + if (!delay && vnode.componentInstance && vnode.componentInstance.$attrs) { + delay = vnode.componentInstance.$attrs['data-vv-delay']; + } + + if (!isObject(globalDelay)) { + return deepParseInt(delay || globalDelay); + } + + if (!isNullOrUndefined(delay)) { + globalDelay.input = delay; + } + + return deepParseInt(globalDelay); + }; + + /** + * Resolves the events to validate in response to. + * @param {*} el + * @param {*} vnode + */ + Resolver.resolveEvents = function resolveEvents (el, vnode) { + // resolve it from the root element. + var events = getDataAttribute(el, 'validate-on'); + + // resolve from data-vv-validate-on if its a vue component. + if (!events && vnode.componentInstance && vnode.componentInstance.$attrs) { + events = vnode.componentInstance.$attrs['data-vv-validate-on']; + } + + // resolve it from $_veeValidate options. + if (!events && vnode.componentInstance) { + var config = Resolver.getCtorConfig(vnode); + events = config && config.events; + } + + if (!events && Config.current.events) { + events = Config.current.events; + } + + // resolve the model event if its configured for custom components. + if (events && vnode.componentInstance && includes(events, 'input')) { + var ref = vnode.componentInstance.$options.model || { event: 'input' }; + var event = ref.event; + // if the prop was configured but not the model. + if (!event) { + return events; + } + + events = events.replace('input', event); + } + + return events; + }; + + /** + * Resolves the scope for the field. + * @param {*} el + * @param {*} binding + */ + Resolver.resolveScope = function resolveScope (el, binding, vnode) { + if ( vnode === void 0 ) vnode = {}; + + var scope = null; + if (vnode.componentInstance && isNullOrUndefined(scope)) { + scope = vnode.componentInstance.$attrs && vnode.componentInstance.$attrs['data-vv-scope']; + } + + return !isNullOrUndefined(scope) ? scope : getScope(el); + }; + + /** + * Checks if the node directives contains a v-model or a specified arg. + * Args take priority over models. + * + * @return {Object} + */ + Resolver.resolveModel = function resolveModel (binding, vnode) { + if (binding.arg) { + return { expression: binding.arg }; + } + + var model = vnode.data.model || find(vnode.data.directives, function (d) { return d.name === 'model'; }); + if (!model) { + return null; + } + + // https://github.com/vuejs/vue/blob/dev/src/core/util/lang.js#L26 + var watchable = !/[^\w.$]/.test(model.expression) && hasPath(model.expression, vnode.context); + var lazy = !!(model.modifiers && model.modifiers.lazy); + + if (!watchable) { + return { expression: null, lazy: lazy }; + } + + return { expression: model.expression, lazy: lazy }; + }; + + /** + * Resolves the field name to trigger validations. + * @return {String} The field name. + */ + Resolver.resolveName = function resolveName (el, vnode) { + var name = getDataAttribute(el, 'name'); + + if (!name && !vnode.componentInstance) { + return el.name; + } + + if (!name && vnode.componentInstance && vnode.componentInstance.$attrs) { + name = vnode.componentInstance.$attrs['data-vv-name'] || vnode.componentInstance.$attrs['name']; + } + + if (!name && vnode.componentInstance) { + var config = Resolver.getCtorConfig(vnode); + if (config && isCallable(config.name)) { + var boundGetter = config.name.bind(vnode.componentInstance); + + return boundGetter(); + } + + return vnode.componentInstance.name; + } + + return name; + }; + + /** + * Returns a value getter input type. + */ + Resolver.resolveGetter = function resolveGetter (el, vnode, model) { + if (model && model.expression) { + return function () { + return getPath(model.expression, vnode.context); + }; + } + + if (vnode.componentInstance) { + var path = getDataAttribute(el, 'value-path') || (vnode.componentInstance.$attrs && vnode.componentInstance.$attrs['data-vv-value-path']); + if (path) { + return function () { + return getPath(path, vnode.componentInstance); + }; + } + + var config = Resolver.getCtorConfig(vnode); + if (config && isCallable(config.value)) { + var boundGetter = config.value.bind(vnode.componentInstance); + + return function () { + return boundGetter(); + }; + } + + var ref = vnode.componentInstance.$options.model || { prop: 'value' }; + var prop = ref.prop; + + return function () { + return vnode.componentInstance[prop]; + }; + } + + switch (el.type) { + case 'checkbox': return function () { + var els = document.querySelectorAll(("input[name=\"" + (el.name) + "\"]")); + + els = toArray(els).filter(function (el) { return el.checked; }); + if (!els.length) { return undefined; } + + return els.map(function (checkbox) { return checkbox.value; }); + }; + case 'radio': return function () { + var els = document.querySelectorAll(("input[name=\"" + (el.name) + "\"]")); + var elm = find(els, function (el) { return el.checked; }); + + return elm && elm.value; + }; + case 'file': return function (context) { + return toArray(el.files); + }; + case 'select-multiple': return function () { + return toArray(el.options).filter(function (opt) { return opt.selected; }).map(function (opt) { return opt.value; }); + }; + default: return function () { + return el && el.value; + }; + } + }; + + // + + var RULES = {}; + var STRICT_MODE = true; + + var Validator = function Validator (validations, options) { + if ( options === void 0 ) options = { fastExit: true }; + + this.strict = STRICT_MODE; + this.errors = new ErrorBag(); + this.fields = new FieldBag(); + this._createFields(validations); + this.paused = false; + this.fastExit = !isNullOrUndefined(options && options.fastExit) ? options.fastExit : true; + }; + + var prototypeAccessors$2 = { rules: { configurable: true },flags: { configurable: true },dictionary: { configurable: true },_vm: { configurable: true },locale: { configurable: true } }; + var staticAccessors$1 = { rules: { configurable: true },dictionary: { configurable: true },locale: { configurable: true } }; + + staticAccessors$1.rules.get = function () { + return RULES; + }; + + prototypeAccessors$2.rules.get = function () { + return RULES; + }; + + prototypeAccessors$2.flags.get = function () { + return this.fields.items.reduce(function (acc, field) { + var obj; + + if (field.scope) { + acc[("$" + (field.scope))] = ( obj = {}, obj[field.name] = field.flags, obj ); + + return acc; + } + + acc[field.name] = field.flags; + + return acc; + }, {}); + }; + + /** + * Getter for the dictionary. + */ + prototypeAccessors$2.dictionary.get = function () { + return Config.dependency('dictionary'); + }; + + staticAccessors$1.dictionary.get = function () { + return Config.dependency('dictionary'); + }; + + prototypeAccessors$2._vm.get = function () { + return Config.dependency('vm'); + }; + + /** + * Getter for the current locale. + */ + prototypeAccessors$2.locale.get = function () { + return Validator.locale; + }; + + /** + * Setter for the validator locale. + */ + prototypeAccessors$2.locale.set = function (value) { + Validator.locale = value; + }; + + staticAccessors$1.locale.get = function () { + return this.dictionary.locale; + }; + + /** + * Setter for the validator locale. + */ + staticAccessors$1.locale.set = function (value) { + var hasChanged = value !== Validator.dictionary.locale; + Validator.dictionary.locale = value; + if (hasChanged && Config.dependency('vm')) { + Config.dependency('vm').$emit('localeChanged'); + } + }; + + /** + * Static constructor. + */ + Validator.create = function create (validations, options) { + return new Validator(validations, options); + }; + + /** + * Adds a custom validator to the list of validation rules. + */ + Validator.extend = function extend (name, validator, options) { + if ( options === void 0 ) options = {}; + + Validator._guardExtend(name, validator); + Validator._merge(name, { + validator: validator, + paramNames: options && options.paramNames, + options: assign({}, { hasTarget: false, immediate: true }, options || {}) + }); + }; + + /** + * Removes a rule from the list of validators. + */ + Validator.remove = function remove (name) { + delete RULES[name]; + }; + + /** + * Checks if the given rule name is a rule that targets other fields. + */ + Validator.isTargetRule = function isTargetRule (name) { + return !!RULES[name] && RULES[name].options.hasTarget; + }; + + /** + * Sets the operating mode for all newly created validators. + * strictMode = true: Values without a rule are invalid and cause failure. + * strictMode = false: Values without a rule are valid and are skipped. + */ + Validator.setStrictMode = function setStrictMode (strictMode) { + if ( strictMode === void 0 ) strictMode = true; + + STRICT_MODE = strictMode; + }; + + /** + * Adds and sets the current locale for the validator. + */ + Validator.prototype.localize = function localize (lang, dictionary) { + Validator.localize(lang, dictionary); + }; + + /** + * Adds and sets the current locale for the validator. + */ + Validator.localize = function localize (lang, dictionary) { + var obj; + + if (isObject(lang)) { + Validator.dictionary.merge(lang); + return; + } + + // merge the dictionary. + if (dictionary) { + var locale = lang || dictionary.name; + dictionary = assign({}, dictionary); + Validator.dictionary.merge(( obj = {}, obj[locale] = dictionary, obj )); + } + + if (lang) { + // set the locale. + Validator.locale = lang; + } + }; + + /** + * Registers a field to be validated. + */ + Validator.prototype.attach = function attach (fieldOpts) { + // fixes initial value detection with v-model and select elements. + var value = fieldOpts.initialValue; + var field = new Field(fieldOpts); + this.fields.push(field); + + // validate the field initially + if (field.immediate) { + this.validate(("#" + (field.id)), value || field.value, { vmId: fieldOpts.vmId }); + } else { + this._validate(field, value || field.value, { initial: true }).then(function (result) { + field.flags.valid = result.valid; + field.flags.invalid = !result.valid; + }); + } + + return field; + }; + + /** + * Sets the flags on a field. + */ + Validator.prototype.flag = function flag (name, flags, uid) { + if ( uid === void 0 ) uid = null; + + var field = this._resolveField(name, undefined, uid); + if (!field || !flags) { + return; + } + + field.setFlags(flags); + }; + + /** + * Removes a field from the validator. + */ + Validator.prototype.detach = function detach (name, scope, uid) { + var field = isCallable(name.destroy) ? name : this._resolveField(name, scope, uid); + if (!field) { return; } + + field.destroy(); + this.errors.remove(field.name, field.scope, field.vmId); + this.fields.remove(field); + }; + + /** + * Adds a custom validator to the list of validation rules. + */ + Validator.prototype.extend = function extend (name, validator, options) { + if ( options === void 0 ) options = {}; + + Validator.extend(name, validator, options); + }; + + Validator.prototype.reset = function reset (matcher) { + var this$1 = this; + + // two ticks + return this._vm.$nextTick().then(function () { + return this$1._vm.$nextTick(); + }).then(function () { + this$1.fields.filter(matcher).forEach(function (field) { + field.reset(); // reset field flags. + this$1.errors.remove(field.name, field.scope); + }); + }); + }; + + /** + * Updates a field, updating both errors and flags. + */ + Validator.prototype.update = function update (id, ref) { + var scope = ref.scope; + + var field = this._resolveField(("#" + id)); + if (!field) { return; } + + // remove old scope. + this.errors.update(id, { scope: scope }); + }; + + /** + * Removes a rule from the list of validators. + */ + Validator.prototype.remove = function remove (name) { + Validator.remove(name); + }; + + /** + * Validates a value against a registered field validations. + */ + Validator.prototype.validate = function validate (fieldDescriptor, value, ref) { + var this$1 = this; + if ( ref === void 0 ) ref = {}; + var silent = ref.silent; + var vmId = ref.vmId; + + if (this.paused) { return Promise.resolve(true); } + + // overload to validate all. + if (isNullOrUndefined(fieldDescriptor)) { + return this.validateScopes({ silent: silent, vmId: vmId }); + } + + // overload to validate scope-less fields. + if (fieldDescriptor === '*') { + return this.validateAll(undefined, { silent: silent, vmId: vmId }); + } + + // if scope validation was requested. + if (/^(.+)\.\*$/.test(fieldDescriptor)) { + var matched = fieldDescriptor.match(/^(.+)\.\*$/)[1]; + return this.validateAll(matched); + } + + var field = this._resolveField(fieldDescriptor); + if (!field) { + return this._handleFieldNotFound(name); + } + + if (!silent) { field.flags.pending = true; } + if (value === undefined) { + value = field.value; + } + + return this._validate(field, value).then(function (result) { + if (!silent) { + this$1._handleValidationResults([result], vmId); + } + + return result.valid; + }); + }; + + /** + * Pauses the validator. + */ + Validator.prototype.pause = function pause () { + this.paused = true; + + return this; + }; + + /** + * Resumes the validator. + */ + Validator.prototype.resume = function resume () { + this.paused = false; + + return this; + }; + + /** + * Validates each value against the corresponding field validations. + */ + Validator.prototype.validateAll = function validateAll (values$$1, ref) { + var this$1 = this; + if ( ref === void 0 ) ref = {}; + var silent = ref.silent; + var vmId = ref.vmId; + + if (this.paused) { return Promise.resolve(true); } + + var matcher = null; + var providedValues = false; + + if (typeof values$$1 === 'string') { + matcher = { scope: values$$1, vmId: vmId }; + } else if (isObject(values$$1)) { + matcher = Object.keys(values$$1).map(function (key) { + return { name: key, vmId: vmId, scope: null }; + }); + providedValues = true; + } else if (Array.isArray(values$$1)) { + matcher = values$$1.map(function (key) { + return { name: key, vmId: vmId }; + }); + } else { + matcher = { scope: null, vmId: vmId }; + } + + return Promise.all( + this.fields.filter(matcher).map(function (field) { return this$1._validate(field, providedValues ? values$$1[field.name] : field.value); }) + ).then(function (results) { + if (!silent) { + this$1._handleValidationResults(results, vmId); + } + + return results.every(function (t) { return t.valid; }); + }); + }; + + /** + * Validates all scopes. + */ + Validator.prototype.validateScopes = function validateScopes (ref) { + var this$1 = this; + if ( ref === void 0 ) ref = {}; + var silent = ref.silent; + var vmId = ref.vmId; + + if (this.paused) { return Promise.resolve(true); } + + return Promise.all( + this.fields.filter({ vmId: vmId }).map(function (field) { return this$1._validate(field, field.value); }) + ).then(function (results) { + if (!silent) { + this$1._handleValidationResults(results, vmId); + } + + return results.every(function (t) { return t.valid; }); + }); + }; + + /** + * Validates a value against the rules. + */ + Validator.prototype.verify = function verify (value, rules) { + var field = { name: '{field}', rules: normalizeRules(rules) }; + field.isRequired = field.rules.required; + + return this._validate(field, value).then(function (result) { + return { valid: result.valid, errors: result.errors.map(function (e) { return e.msg; }) }; + }); + }; + + /** + * Perform cleanup. + */ + Validator.prototype.destroy = function destroy () { + this._vm.$off('localeChanged'); + }; + + /** + * Creates the fields to be validated. + */ + Validator.prototype._createFields = function _createFields (validations) { + var this$1 = this; + + if (!validations) { return; } + + Object.keys(validations).forEach(function (field) { + var options = assign({}, { name: field, rules: validations[field] }); + this$1.attach(options); + }); + }; + + /** + * Date rules need the existence of a format, so date_format must be supplied. + */ + Validator.prototype._getDateFormat = function _getDateFormat (validations) { + var format = null; + if (validations.date_format && Array.isArray(validations.date_format)) { + format = validations.date_format[0]; + } + + return format || this.dictionary.getDateFormat(this.locale); + }; + + /** + * Formats an error message for field and a rule. + */ + Validator.prototype._formatErrorMessage = function _formatErrorMessage (field, rule, data, targetName) { + if ( data === void 0 ) data = {}; + if ( targetName === void 0 ) targetName = null; + + var name = this._getFieldDisplayName(field); + var params = this._getLocalizedParams(rule, targetName); + + return this.dictionary.getFieldMessage(this.locale, field.name, rule.name, [name, params, data]); + }; + + /** + * We need to convert any object param to an array format since the locales do not handle params as objects yet. + */ + Validator.prototype._convertParamObjectToArray = function _convertParamObjectToArray (obj, ruleName) { + if (Array.isArray(obj)) { + return obj; + } + + var paramNames = RULES[ruleName] && RULES[ruleName].paramNames; + if (!paramNames || !isObject(obj)) { + return obj; + } + + return paramNames.reduce(function (prev, paramName) { + if (paramName in obj) { + prev.push(obj[paramName]); + } + + return prev; + }, []); + }; + + /** + * Translates the parameters passed to the rule (mainly for target fields). + */ + Validator.prototype._getLocalizedParams = function _getLocalizedParams (rule, targetName) { + if ( targetName === void 0 ) targetName = null; + + var params = this._convertParamObjectToArray(rule.params, rule.name); + if (rule.options.hasTarget && params && params[0]) { + var localizedName = targetName || this.dictionary.getAttribute(this.locale, params[0], params[0]); + return [localizedName].concat(params.slice(1)); + } + + return params; + }; + + /** + * Resolves an appropriate display name, first checking 'data-as' or the registered 'prettyName' + */ + Validator.prototype._getFieldDisplayName = function _getFieldDisplayName (field) { + return field.alias || this.dictionary.getAttribute(this.locale, field.name, field.name); + }; + + /** + * Converts an array of params to an object with named properties. + * Only works if the rule is configured with a paramNames array. + * Returns the same params if it cannot convert it. + */ + Validator.prototype._convertParamArrayToObj = function _convertParamArrayToObj (params, ruleName) { + var paramNames = RULES[ruleName] && RULES[ruleName].paramNames; + if (!paramNames) { + return params; + } + + if (isObject(params)) { + // check if the object is either a config object or a single parameter that is an object. + var hasKeys = paramNames.some(function (name) { return Object.keys(params).indexOf(name) !== -1; }); + // if it has some of the keys, return it as is. + if (hasKeys) { + return params; + } + // otherwise wrap the object in an array. + params = [params]; + } + + // Reduce the paramsNames to a param object. + return params.reduce(function (prev, value, idx) { + prev[paramNames[idx]] = value; + + return prev; + }, {}); + }; + + /** + * Tests a single input value against a rule. + */ + Validator.prototype._test = function _test (field, value, rule) { + var this$1 = this; + + var validator = RULES[rule.name] ? RULES[rule.name].validate : null; + var params = Array.isArray(rule.params) ? toArray(rule.params) : rule.params; + if (!params) { + params = []; + } + + var targetName = null; + if (!validator || typeof validator !== 'function') { + return Promise.reject(createError(("No such validator '" + (rule.name) + "' exists."))); + } + + // has field dependencies. + if (rule.options.hasTarget) { + var target = find(field.dependencies, function (d) { return d.name === rule.name; }); + if (target) { + targetName = target.field.alias; + params = [target.field.value].concat(params.slice(1)); + } + } else if (rule.name === 'required' && field.rejectsFalse) { + // invalidate false if no args were specified and the field rejects false by default. + params = params.length ? params : [true]; + } + + if (rule.options.isDate) { + var dateFormat = this._getDateFormat(field.rules); + if (rule.name !== 'date_format') { + params.push(dateFormat); + } + } + + var result = validator(value, this._convertParamArrayToObj(params, rule.name)); + + // If it is a promise. + if (isCallable(result.then)) { + return result.then(function (values$$1) { + var allValid = true; + var data = {}; + if (Array.isArray(values$$1)) { + allValid = values$$1.every(function (t) { return (isObject(t) ? t.valid : t); }); + } else { // Is a single object/boolean. + allValid = isObject(values$$1) ? values$$1.valid : values$$1; + data = values$$1.data; + } + + return { + valid: allValid, + errors: allValid ? [] : [this$1._createFieldError(field, rule, data, targetName)] + }; + }); + } + + if (!isObject(result)) { + result = { valid: result, data: {} }; + } + + return { + valid: result.valid, + errors: result.valid ? [] : [this._createFieldError(field, rule, result.data, targetName)] + }; + }; + + /** + * Merges a validator object into the RULES and Messages. + */ + Validator._merge = function _merge (name, ref) { + var validator = ref.validator; + var options = ref.options; + var paramNames = ref.paramNames; + + var validate = isCallable(validator) ? validator : validator.validate; + if (validator.getMessage) { + Validator.dictionary.setMessage(Validator.locale, name, validator.getMessage); + } + + RULES[name] = { + validate: validate, + options: options, + paramNames: paramNames + }; + }; + + /** + * Guards from extension violations. + */ + Validator._guardExtend = function _guardExtend (name, validator) { + if (isCallable(validator)) { + return; + } + + if (!isCallable(validator.validate)) { + throw createError( + ("Extension Error: The validator '" + name + "' must be a function or have a 'validate' method.") + ); + } + }; + + /** + * Creates a Field Error Object. + */ + Validator.prototype._createFieldError = function _createFieldError (field, rule, data, targetName) { + var this$1 = this; + + return { + id: field.id, + vmId: field.vmId, + field: field.name, + msg: this._formatErrorMessage(field, rule, data, targetName), + rule: rule.name, + scope: field.scope, + regenerate: function () { + return this$1._formatErrorMessage(field, rule, data, targetName); + } + }; + }; + + /** + * Tries different strategies to find a field. + */ + Validator.prototype._resolveField = function _resolveField (name, scope, uid) { + if (name[0] === '#') { + return this.fields.find({ id: name.slice(1) }); + } + + if (!isNullOrUndefined(scope)) { + return this.fields.find({ name: name, scope: scope, vmId: uid }); + } + + if (includes(name, '.')) { + var ref = name.split('.'); + var fieldScope = ref[0]; + var fieldName = ref.slice(1); + var field = this.fields.find({ name: fieldName.join('.'), scope: fieldScope, vmId: uid }); + if (field) { + return field; + } + } + + return this.fields.find({ name: name, scope: null, vmId: uid }); + }; + + /** + * Handles when a field is not found depending on the strict flag. + */ + Validator.prototype._handleFieldNotFound = function _handleFieldNotFound (name, scope) { + if (!this.strict) { return Promise.resolve(true); } + + var fullName = isNullOrUndefined(scope) ? name : ("" + (!isNullOrUndefined(scope) ? scope + '.' : '') + name); + + return Promise.reject(createError( + ("Validating a non-existent field: \"" + fullName + "\". Use \"attach()\" first.") + )); + }; + + /** + * Handles validation results. + */ + Validator.prototype._handleValidationResults = function _handleValidationResults (results, vmId) { + var this$1 = this; + + var matchers = results.map(function (result) { return ({ id: result.id }); }); + this.errors.removeById(matchers.map(function (m) { return m.id; })); + // remove by name and scope to remove any custom errors added. + results.forEach(function (result) { + this$1.errors.remove(result.field, result.scope, vmId); + }); + var allErrors = results.reduce(function (prev, curr) { + prev.push.apply(prev, curr.errors); + + return prev; + }, []); + + this.errors.add(allErrors); + + // handle flags. + this.fields.filter(matchers).forEach(function (field) { + var result = find(results, function (r) { return r.id === field.id; }); + field.setFlags({ + pending: false, + valid: result.valid, + validated: true + }); + }); + }; + + Validator.prototype._shouldSkip = function _shouldSkip (field, value) { + // field is configured to run through the pipeline regardless + if (field.bails === false) { + return false; + } + + // disabled fields are skipped + if (field.isDisabled) { + return true; + } + + // skip if the field is not required and has an empty value. + return !field.isRequired && (isNullOrUndefined(value) || value === ''); + }; + + Validator.prototype._shouldBail = function _shouldBail (field, value) { + // if the field was configured explicitly. + if (field.bails !== undefined) { + return field.bails; + } + + return this.fastExit; + }; + + /** + * Starts the validation process. + */ + Validator.prototype._validate = function _validate (field, value, ref) { + var this$1 = this; + if ( ref === void 0 ) ref = {}; + var initial = ref.initial; + + if (this._shouldSkip(field, value)) { + return Promise.resolve({ valid: true, id: field.id, field: field.name, scope: field.scope, errors: [] }); + } + + var promises = []; + var errors = []; + var isExitEarly = false; + // use of '.some()' is to break iteration in middle by returning true + Object.keys(field.rules).filter(function (rule) { + if (!initial || !RULES[rule]) { return true; } + + return RULES[rule].options.immediate; + }).some(function (rule) { + var ruleOptions = RULES[rule] ? RULES[rule].options : {}; + var result = this$1._test(field, value, { name: rule, params: field.rules[rule], options: ruleOptions }); + if (isCallable(result.then)) { + promises.push(result); + } else if (!result.valid && this$1._shouldBail(field, value)) { + errors.push.apply(errors, result.errors); + isExitEarly = true; + } else { + // promisify the result. + promises.push(new Promise(function (resolve) { return resolve(result); })); + } + + return isExitEarly; + }); + + if (isExitEarly) { + return Promise.resolve({ valid: false, errors: errors, id: field.id, field: field.name, scope: field.scope }); + } + + return Promise.all(promises).then(function (results) { + return results.reduce(function (prev, v) { + var ref; + + if (!v.valid) { + (ref = prev.errors).push.apply(ref, v.errors); + } + + prev.valid = prev.valid && v.valid; + + return prev; + }, { valid: true, errors: errors, id: field.id, field: field.name, scope: field.scope }); + }); + }; + + Object.defineProperties( Validator.prototype, prototypeAccessors$2 ); + Object.defineProperties( Validator, staticAccessors$1 ); + + // + + var DEFAULT_OPTIONS = { + targetOf: null, + immediate: false, + scope: null, + listen: true, + name: null, + rules: {}, + vm: null, + classes: false, + validity: true, + aria: true, + events: 'input|blur', + delay: 0, + classNames: { + touched: 'touched', // the control has been blurred + untouched: 'untouched', // the control hasn't been blurred + valid: 'valid', // model is valid + invalid: 'invalid', // model is invalid + pristine: 'pristine', // control has not been interacted with + dirty: 'dirty' // control has been interacted with + } + }; + + var Field = function Field (options) { + if ( options === void 0 ) options = {}; + + this.id = uniqId(); + this.el = options.el; + this.updated = false; + this.dependencies = []; + this.vmId = options.vmId; + this.watchers = []; + this.events = []; + this.delay = 0; + this.rules = {}; + this._cacheId(options); + this.classNames = assign({}, DEFAULT_OPTIONS.classNames); + options = assign({}, DEFAULT_OPTIONS, options); + this._delay = !isNullOrUndefined(options.delay) ? options.delay : 0; // cache initial delay + this.validity = options.validity; + this.aria = options.aria; + this.flags = createFlags(); + this.vm = options.vm; + this.componentInstance = options.component; + this.ctorConfig = this.componentInstance ? getPath('$options.$_veeValidate', this.componentInstance) : undefined; + this.update(options); + // set initial value. + this.initialValue = this.value; + this.updated = false; + }; + + var prototypeAccessors$3 = { validator: { configurable: true },isRequired: { configurable: true },isDisabled: { configurable: true },alias: { configurable: true },value: { configurable: true },bails: { configurable: true },rejectsFalse: { configurable: true } }; + + prototypeAccessors$3.validator.get = function () { + if (!this.vm || !this.vm.$validator) { + return { validate: function () {} }; + } + + return this.vm.$validator; + }; + + prototypeAccessors$3.isRequired.get = function () { + return !!this.rules.required; + }; + + prototypeAccessors$3.isDisabled.get = function () { + return !!(this.componentInstance && this.componentInstance.disabled) || !!(this.el && this.el.disabled); + }; + + /** + * Gets the display name (user-friendly name). + */ + prototypeAccessors$3.alias.get = function () { + if (this._alias) { + return this._alias; + } + + var alias = null; + if (this.el) { + alias = getDataAttribute(this.el, 'as'); + } + + if (!alias && this.componentInstance) { + return this.componentInstance.$attrs && this.componentInstance.$attrs['data-vv-as']; + } + + return alias; + }; + + /** + * Gets the input value. + */ + + prototypeAccessors$3.value.get = function () { + if (!isCallable(this.getter)) { + return undefined; + } + + return this.getter(); + }; + + prototypeAccessors$3.bails.get = function () { + return this._bails; + }; + + /** + * If the field rejects false as a valid value for the required rule. + */ + + prototypeAccessors$3.rejectsFalse.get = function () { + if (this.componentInstance && this.ctorConfig) { + return !!this.ctorConfig.rejectsFalse; + } + + if (!this.el) { + return false; + } + + return this.el.type === 'checkbox'; + }; + + /** + * Determines if the instance matches the options provided. + */ + Field.prototype.matches = function matches (options) { + var this$1 = this; + + if (!options) { + return true; + } + + if (options.id) { + return this.id === options.id; + } + + var matchesComponentId = isNullOrUndefined(options.vmId) ? function () { return true; } : function (id) { return id === this$1.vmId; }; + if (!matchesComponentId(options.vmId)) { + return false; + } + + if (options.name === undefined && options.scope === undefined) { + return true; + } + + if (options.scope === undefined) { + return this.name === options.name; + } + + if (options.name === undefined) { + return this.scope === options.scope; + } + + return options.name === this.name && options.scope === this.scope; + }; + + /** + * Caches the field id. + */ + Field.prototype._cacheId = function _cacheId (options) { + if (this.el && !options.targetOf) { + this.el._veeValidateId = this.id; + } + }; + + /** + * Updates the field with changed data. + */ + Field.prototype.update = function update (options) { + this.targetOf = options.targetOf || null; + this.immediate = options.immediate || this.immediate || false; + + // update errors scope if the field scope was changed. + if (!isNullOrUndefined(options.scope) && options.scope !== this.scope && isCallable(this.validator.update)) { + this.validator.update(this.id, { scope: options.scope }); + } + this.scope = !isNullOrUndefined(options.scope) ? options.scope + : !isNullOrUndefined(this.scope) ? this.scope : null; + this.name = (!isNullOrUndefined(options.name) ? String(options.name) : options.name) || this.name || null; + this.rules = options.rules !== undefined ? normalizeRules(options.rules) : this.rules; + this._bails = options.bails !== undefined ? options.bails : this._bails; + this.model = options.model || this.model; + this.listen = options.listen !== undefined ? options.listen : this.listen; + this.classes = (options.classes || this.classes || false) && !this.componentInstance; + this.classNames = isObject(options.classNames) ? merge$1(this.classNames, options.classNames) : this.classNames; + this.getter = isCallable(options.getter) ? options.getter : this.getter; + this._alias = options.alias || this._alias; + this.events = (options.events) ? makeEventsArray(options.events) : this.events; + this.delay = makeDelayObject(this.events, options.delay || this.delay, this._delay); + this.updateDependencies(); + this.addActionListeners(); + + if (!this.name && !this.targetOf) { + warn('A field is missing a "name" or "data-vv-name" attribute'); + } + + // update required flag flags + if (options.rules !== undefined) { + this.flags.required = this.isRequired; + } + + // validate if it was validated before and field was updated and there was a rules mutation. + if (this.flags.validated && options.rules !== undefined && this.updated) { + this.validator.validate(("#" + (this.id))); + } + + this.updated = true; + this.addValueListeners(); + + // no need to continue. + if (!this.el) { + return; + } + this.updateClasses(); + this.updateAriaAttrs(); + }; + + /** + * Resets field flags and errors. + */ + Field.prototype.reset = function reset () { + var this$1 = this; + + if (this._cancellationToken) { + this._cancellationToken.cancelled = true; + delete this._cancellationToken; + } + + var defaults = createFlags(); + Object.keys(this.flags).filter(function (flag) { return flag !== 'required'; }).forEach(function (flag) { + this$1.flags[flag] = defaults[flag]; + }); + + this.addActionListeners(); + this.updateClasses(); + this.updateAriaAttrs(); + this.updateCustomValidity(); + }; + + /** + * Sets the flags and their negated counterparts, and updates the classes and re-adds action listeners. + */ + Field.prototype.setFlags = function setFlags (flags) { + var this$1 = this; + + var negated = { + pristine: 'dirty', + dirty: 'pristine', + valid: 'invalid', + invalid: 'valid', + touched: 'untouched', + untouched: 'touched' + }; + + Object.keys(flags).forEach(function (flag) { + this$1.flags[flag] = flags[flag]; + // if it has a negation and was not specified, set it as well. + if (negated[flag] && flags[negated[flag]] === undefined) { + this$1.flags[negated[flag]] = !flags[flag]; + } + }); + + if ( + flags.untouched !== undefined || + flags.touched !== undefined || + flags.dirty !== undefined || + flags.pristine !== undefined + ) { + this.addActionListeners(); + } + this.updateClasses(); + this.updateAriaAttrs(); + this.updateCustomValidity(); + }; + + /** + * Determines if the field requires references to target fields. + */ + Field.prototype.updateDependencies = function updateDependencies () { + var this$1 = this; + + // reset dependencies. + this.dependencies.forEach(function (d) { return d.field.destroy(); }); + this.dependencies = []; + + // we get the selectors for each field. + var fields = Object.keys(this.rules).reduce(function (prev, r) { + if (Validator.isTargetRule(r)) { + prev.push({ selector: this$1.rules[r][0], name: r }); + } + + return prev; + }, []); + + if (!fields.length || !this.vm || !this.vm.$el) { return; } + + // must be contained within the same component, so we use the vm root element constrain our dom search. + fields.forEach(function (ref$1) { + var selector = ref$1.selector; + var name = ref$1.name; + + var ref = this$1.vm.$refs[selector]; + var el = Array.isArray(ref) ? ref[0] : ref; + if (!el) { + return; + } + + var options = { + vm: this$1.vm, + classes: this$1.classes, + classNames: this$1.classNames, + delay: this$1.delay, + scope: this$1.scope, + events: this$1.events.join('|'), + immediate: this$1.immediate, + targetOf: this$1.id + }; + + // probably a component. + if (isCallable(el.$watch)) { + options.component = el; + options.el = el.$el; + options.getter = Resolver.resolveGetter(el.$el, el.$vnode); + } else { + options.el = el; + options.getter = Resolver.resolveGetter(el, {}); + } + + this$1.dependencies.push({ name: name, field: new Field(options) }); + }); + }; + + /** + * Removes listeners. + */ + Field.prototype.unwatch = function unwatch (tag) { + if ( tag === void 0 ) tag = null; + + if (!tag) { + this.watchers.forEach(function (w) { return w.unwatch(); }); + this.watchers = []; + return; + } + + this.watchers.filter(function (w) { return tag.test(w.tag); }).forEach(function (w) { return w.unwatch(); }); + this.watchers = this.watchers.filter(function (w) { return !tag.test(w.tag); }); + }; + + /** + * Updates the element classes depending on each field flag status. + */ + Field.prototype.updateClasses = function updateClasses () { + var this$1 = this; + + if (!this.classes || this.isDisabled) { return; } + var applyClasses = function (el) { + toggleClass(el, this$1.classNames.dirty, this$1.flags.dirty); + toggleClass(el, this$1.classNames.pristine, this$1.flags.pristine); + toggleClass(el, this$1.classNames.touched, this$1.flags.touched); + toggleClass(el, this$1.classNames.untouched, this$1.flags.untouched); + // make sure we don't set any classes if the state is undetermined. + if (!isNullOrUndefined(this$1.flags.valid) && this$1.flags.validated) { + toggleClass(el, this$1.classNames.valid, this$1.flags.valid); + } + + if (!isNullOrUndefined(this$1.flags.invalid) && this$1.flags.validated) { + toggleClass(el, this$1.classNames.invalid, this$1.flags.invalid); + } + }; + + if (!isCheckboxOrRadioInput(this.el)) { + applyClasses(this.el); + return; + } + + var els = document.querySelectorAll(("input[name=\"" + (this.el.name) + "\"]")); + toArray(els).forEach(applyClasses); + }; + + /** + * Adds the listeners required for automatic classes and some flags. + */ + Field.prototype.addActionListeners = function addActionListeners () { + var this$1 = this; + + // remove previous listeners. + this.unwatch(/class/); + + if (!this.el) { return; } + + var onBlur = function () { + this$1.flags.touched = true; + this$1.flags.untouched = false; + if (this$1.classes) { + toggleClass(this$1.el, this$1.classNames.touched, true); + toggleClass(this$1.el, this$1.classNames.untouched, false); + } + + // only needed once. + this$1.unwatch(/^class_blur$/); + }; + + var inputEvent = isTextInput(this.el) ? 'input' : 'change'; + var onInput = function () { + this$1.flags.dirty = true; + this$1.flags.pristine = false; + if (this$1.classes) { + toggleClass(this$1.el, this$1.classNames.pristine, false); + toggleClass(this$1.el, this$1.classNames.dirty, true); + } + + // only needed once. + this$1.unwatch(/^class_input$/); + }; + + if (this.componentInstance && isCallable(this.componentInstance.$once)) { + this.componentInstance.$once('input', onInput); + this.componentInstance.$once('blur', onBlur); + this.watchers.push({ + tag: 'class_input', + unwatch: function () { + this$1.componentInstance.$off('input', onInput); + } + }); + this.watchers.push({ + tag: 'class_blur', + unwatch: function () { + this$1.componentInstance.$off('blur', onBlur); + } + }); + return; + } + + if (!this.el) { return; } + + addEventListener(this.el, inputEvent, onInput); + // Checkboxes and radio buttons on Mac don't emit blur naturally, so we listen on click instead. + var blurEvent = isCheckboxOrRadioInput(this.el) ? 'change' : 'blur'; + addEventListener(this.el, blurEvent, onBlur); + this.watchers.push({ + tag: 'class_input', + unwatch: function () { + this$1.el.removeEventListener(inputEvent, onInput); + } + }); + + this.watchers.push({ + tag: 'class_blur', + unwatch: function () { + this$1.el.removeEventListener(blurEvent, onBlur); + } + }); + }; + + Field.prototype.checkValueChanged = function checkValueChanged () { + // handle some people initialize the value to null, since text inputs have empty string value. + if (this.initialValue === null && this.value === '' && isTextInput(this.el)) { + return false; + } + + return this.value !== this.initialValue; + }; + + /** + * Determines the suitable primary event to listen for. + */ + Field.prototype._determineInputEvent = function _determineInputEvent () { + // if its a custom component, use the customized model event or the input event. + if (this.componentInstance) { + return (this.componentInstance.$options.model && this.componentInstance.$options.model.event) || 'input'; + } + + if (this.model && this.model.lazy) { + return 'change'; + } + + if (isTextInput(this.el)) { + return 'input'; + } + + return 'change'; + }; + + /** + * Determines the list of events to listen to. + */ + Field.prototype._determineEventList = function _determineEventList (defaultInputEvent) { + // if no event is configured, or it is a component or a text input then respect the user choice. + if (!this.events.length || this.componentInstance || isTextInput(this.el)) { + return [].concat( this.events ); + } + + // force suitable event for non-text type fields. + return this.events.map(function (e) { + if (e === 'input') { + return defaultInputEvent; + } + + return e; + }); + }; + + /** + * Adds the listeners required for validation. + */ + Field.prototype.addValueListeners = function addValueListeners () { + var this$1 = this; + + this.unwatch(/^input_.+/); + if (!this.listen || !this.el) { return; } + + var token = { cancelled: false }; + var fn = this.targetOf ? function () { + this$1.flags.changed = this$1.checkValueChanged(); this$1.validator.validate(("#" + (this$1.targetOf))); + } : function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + // if its a DOM event, resolve the value, otherwise use the first parameter as the value. + if (args.length === 0 || (isCallable(Event) && args[0] instanceof Event) || (args[0] && args[0].srcElement)) { + args[0] = this$1.value; + } + + this$1.flags.changed = this$1.checkValueChanged(); + this$1.validator.validate(("#" + (this$1.id)), args[0]); + }; + + var inputEvent = this._determineInputEvent(); + var events = this._determineEventList(inputEvent); + + // if there is a model and an on input validation is requested. + if (this.model && includes(events, inputEvent)) { + var ctx = null; + var expression = this.model.expression; + // if its watchable from the context vm. + if (this.model.expression) { + ctx = this.vm; + expression = this.model.expression; + } + + // watch it from the custom component vm instead. + if (!expression && this.componentInstance && this.componentInstance.$options.model) { + ctx = this.componentInstance; + expression = this.componentInstance.$options.model.prop || 'value'; + } + + if (ctx && expression) { + var debouncedFn = debounce(fn, this.delay[inputEvent], false, token); + var unwatch = ctx.$watch(expression, function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + this$1.flags.pending = true; + this$1._cancellationToken = token; + debouncedFn.apply(void 0, args); + }); + this.watchers.push({ + tag: 'input_model', + unwatch: unwatch + }); + + // filter out input event as it is already handled by the watcher API. + events = events.filter(function (e) { return e !== inputEvent; }); + } + } + + // Add events. + events.forEach(function (e) { + var debouncedFn = debounce(fn, this$1.delay[e], false, token); + var validate = function () { + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + + this$1.flags.pending = true; + this$1._cancellationToken = token; + debouncedFn.apply(void 0, args); + }; + + this$1._addComponentEventListener(e, validate); + this$1._addHTMLEventListener(e, validate); + }); + }; + + Field.prototype._addComponentEventListener = function _addComponentEventListener (evt, validate) { + var this$1 = this; + + if (!this.componentInstance) { return; } + + this.componentInstance.$on(evt, validate); + this.watchers.push({ + tag: 'input_vue', + unwatch: function () { + this$1.componentInstance.$off(evt, validate); + } + }); + }; + + Field.prototype._addHTMLEventListener = function _addHTMLEventListener (evt, validate) { + var this$1 = this; + + if (!this.el || this.componentInstance) { return; } + + // listen for the current element. + var addListener = function (el) { + addEventListener(el, evt, validate); + this$1.watchers.push({ + tag: 'input_native', + unwatch: function () { + el.removeEventListener(evt, validate); + } + }); + }; + + addListener(this.el); + if (!isCheckboxOrRadioInput(this.el)) { + return; + } + + var els = document.querySelectorAll(("input[name=\"" + (this.el.name) + "\"]")); + toArray(els).forEach(function (el) { + // skip if it is added by v-validate and is not the current element. + if (el._veeValidateId && el !== this$1.el) { + return; + } + + addListener(el); + }); + }; + + /** + * Updates aria attributes on the element. + */ + Field.prototype.updateAriaAttrs = function updateAriaAttrs () { + var this$1 = this; + + if (!this.aria || !this.el || !isCallable(this.el.setAttribute)) { return; } + + var applyAriaAttrs = function (el) { + el.setAttribute('aria-required', this$1.isRequired ? 'true' : 'false'); + el.setAttribute('aria-invalid', this$1.flags.invalid ? 'true' : 'false'); + }; + + if (!isCheckboxOrRadioInput(this.el)) { + applyAriaAttrs(this.el); + return; + } + + var els = document.querySelectorAll(("input[name=\"" + (this.el.name) + "\"]")); + toArray(els).forEach(applyAriaAttrs); + }; + + /** + * Updates the custom validity for the field. + */ + Field.prototype.updateCustomValidity = function updateCustomValidity () { + if (!this.validity || !this.el || !isCallable(this.el.setCustomValidity) || !this.validator.errors) { return; } + + this.el.setCustomValidity(this.flags.valid ? '' : (this.validator.errors.firstById(this.id) || '')); + }; + + /** + * Removes all listeners. + */ + Field.prototype.destroy = function destroy () { + // ignore the result of any ongoing validation. + if (this._cancellationToken) { + this._cancellationToken.cancelled = true; + } + + this.unwatch(); + this.dependencies.forEach(function (d) { return d.field.destroy(); }); + this.dependencies = []; + }; + + Object.defineProperties( Field.prototype, prototypeAccessors$3 ); + + // + + var FieldBag = function FieldBag (items) { + if ( items === void 0 ) items = []; + + this.items = items || []; + }; + + var prototypeAccessors$4 = { length: { configurable: true } }; + + FieldBag.prototype[typeof Symbol === 'function' ? Symbol.iterator : '@@iterator'] = function () { + var this$1 = this; + + var index = 0; + return { + next: function () { + return { value: this$1.items[index++], done: index > this$1.items.length }; + } + }; + }; + + /** + * Gets the current items length. + */ + + prototypeAccessors$4.length.get = function () { + return this.items.length; + }; + + /** + * Finds the first field that matches the provided matcher object. + */ + FieldBag.prototype.find = function find$1 (matcher) { + return find(this.items, function (item) { return item.matches(matcher); }); + }; + + /** + * Filters the items down to the matched fields. + */ + FieldBag.prototype.filter = function filter (matcher) { + // multiple matchers to be tried. + if (Array.isArray(matcher)) { + return this.items.filter(function (item) { return matcher.some(function (m) { return item.matches(m); }); }); + } + + return this.items.filter(function (item) { return item.matches(matcher); }); + }; + + /** + * Maps the field items using the mapping function. + */ + FieldBag.prototype.map = function map (mapper) { + return this.items.map(mapper); + }; + + /** + * Finds and removes the first field that matches the provided matcher object, returns the removed item. + */ + FieldBag.prototype.remove = function remove (matcher) { + var item = null; + if (matcher instanceof Field) { + item = matcher; + } else { + item = this.find(matcher); + } + + if (!item) { return null; } + + var index = this.items.indexOf(item); + this.items.splice(index, 1); + + return item; + }; + + /** + * Adds a field item to the list. + */ + FieldBag.prototype.push = function push (item) { + if (! (item instanceof Field)) { + throw createError('FieldBag only accepts instances of Field that has an id defined.'); + } + + if (!item.id) { + throw createError('Field id must be defined.'); + } + + if (this.find({ id: item.id })) { + throw createError(("Field with id " + (item.id) + " is already added.")); + } + + this.items.push(item); + }; + + Object.defineProperties( FieldBag.prototype, prototypeAccessors$4 ); + + var ScopedValidator = function ScopedValidator (base, vm) { + this.id = vm._uid; + this._base = base; + this._paused = false; + + // create a mirror bag with limited component scope. + this.errors = new ErrorBag(base.errors, this.id); + }; + + var prototypeAccessors$5 = { flags: { configurable: true },rules: { configurable: true },fields: { configurable: true },dictionary: { configurable: true },locale: { configurable: true } }; + + prototypeAccessors$5.flags.get = function () { + var this$1 = this; + + return this._base.fields.items.filter(function (f) { return f.vmId === this$1.id; }).reduce(function (acc, field) { + if (field.scope) { + if (!acc[("$" + (field.scope))]) { + acc[("$" + (field.scope))] = {}; + } + + acc[("$" + (field.scope))][field.name] = field.flags; + } + + acc[field.name] = field.flags; + + return acc; + }, {}); + }; + + prototypeAccessors$5.rules.get = function () { + return this._base.rules; + }; + + prototypeAccessors$5.fields.get = function () { + return new FieldBag(this._base.fields.filter({ vmId: this.id })); + }; + + prototypeAccessors$5.dictionary.get = function () { + return this._base.dictionary; + }; + + prototypeAccessors$5.locale.get = function () { + return this._base.locale; + }; + + prototypeAccessors$5.locale.set = function (val) { + this._base.locale = val; + }; + + ScopedValidator.prototype.localize = function localize () { + var ref; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + return (ref = this._base).localize.apply(ref, args); + }; + + ScopedValidator.prototype.update = function update () { + var ref; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + return (ref = this._base).update.apply(ref, args); + }; + + ScopedValidator.prototype.attach = function attach (opts) { + var attachOpts = assign({}, opts, { vmId: this.id }); + + return this._base.attach(attachOpts); + }; + + ScopedValidator.prototype.pause = function pause () { + this._paused = true; + }; + + ScopedValidator.prototype.resume = function resume () { + this._paused = false; + }; + + ScopedValidator.prototype.remove = function remove (ruleName) { + return this._base.remove(ruleName); + }; + + ScopedValidator.prototype.detach = function detach () { + var ref; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + return (ref = this._base).detach.apply(ref, args.concat( [this.id] )); + }; + + ScopedValidator.prototype.extend = function extend () { + var ref; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + return (ref = this._base).extend.apply(ref, args); + }; + + ScopedValidator.prototype.validate = function validate (descriptor, value, opts) { + if ( opts === void 0 ) opts = {}; + + if (this._paused) { return Promise.resolve(true); } + + return this._base.validate(descriptor, value, assign({}, { vmId: this.id }, opts || {})); + }; + + ScopedValidator.prototype.validateAll = function validateAll (values$$1, opts) { + if ( opts === void 0 ) opts = {}; + + if (this._paused) { return Promise.resolve(true); } + + return this._base.validateAll(values$$1, assign({}, { vmId: this.id }, opts || {})); + }; + + ScopedValidator.prototype.validateScopes = function validateScopes (opts) { + if ( opts === void 0 ) opts = {}; + + if (this._paused) { return Promise.resolve(true); } + + return this._base.validateScopes(assign({}, { vmId: this.id }, opts || {})); + }; + + ScopedValidator.prototype.destroy = function destroy () { + delete this.id; + delete this._base; + }; + + ScopedValidator.prototype.reset = function reset (matcher) { + return this._base.reset(Object.assign({}, matcher || {}, { vmId: this.id })); + }; + + ScopedValidator.prototype.flag = function flag () { + var ref; + + var args = [], len = arguments.length; + while ( len-- ) args[ len ] = arguments[ len ]; + return (ref = this._base).flag.apply(ref, args.concat( [this.id] )); + }; + + Object.defineProperties( ScopedValidator.prototype, prototypeAccessors$5 ); + + // + + /** + * Checks if a parent validator instance was requested. + */ + var requestsValidator = function (injections) { + if (isObject(injections) && injections.$validator) { + return true; + } + + return false; + }; + + var mixin = { + provide: function provide () { + if (this.$validator && !isBuiltInComponent(this.$vnode)) { + return { + $validator: this.$validator + }; + } + + return {}; + }, + beforeCreate: function beforeCreate () { + // if built in do nothing. + if (isBuiltInComponent(this.$vnode)) { + return; + } + + // if its a root instance set the config if it exists. + if (!this.$parent) { + Config.merge(this.$options.$_veeValidate || {}); + } + + var options = Config.resolve(this); + + // if its a root instance, inject anyways, or if it requested a new instance. + if (!this.$parent || (this.$options.$_veeValidate && /new/.test(this.$options.$_veeValidate.validator))) { + this.$validator = new ScopedValidator(Config.dependency('validator'), this); + } + + var requested = requestsValidator(this.$options.inject); + + // if automatic injection is enabled and no instance was requested. + if (! this.$validator && options.inject && !requested) { + this.$validator = new ScopedValidator(Config.dependency('validator'), this); + } + + // don't inject errors or fieldBag as no validator was resolved. + if (! requested && ! this.$validator) { + return; + } + + // There is a validator but it isn't injected, mark as reactive. + if (!requested && this.$validator) { + var Vue = this.$options._base; // the vue constructor. + Vue.util.defineReactive(this.$validator, 'errors', this.$validator.errors); + } + + if (! this.$options.computed) { + this.$options.computed = {}; + } + + this.$options.computed[options.errorBagName || 'errors'] = function errorBagGetter () { + return this.$validator.errors; + }; + this.$options.computed[options.fieldsBagName || 'fields'] = function fieldBagGetter () { + return this.$validator.fields.items.reduce(function (acc, field) { + if (field.scope) { + if (!acc[("$" + (field.scope))]) { + acc[("$" + (field.scope))] = {}; + } + + acc[("$" + (field.scope))][field.name] = field.flags; + + return acc; + } + + acc[field.name] = field.flags; + + return acc; + }, {}); + }; + }, + beforeDestroy: function beforeDestroy () { + if (this.$validator && this._uid === this.$validator.id) { + this.$validator.errors.clear(); // remove errors generated by this component. + } + } + }; + + // + + /** + * Finds the requested field by id from the context object. + */ + function findField (el, context) { + if (!context || !context.$validator) { + return null; + } + + return context.$validator.fields.find({ id: el._veeValidateId }); + } + var directive = { + bind: function bind (el, binding, vnode) { + var validator = vnode.context.$validator; + if (!validator) { + { + warn("No validator instance is present on vm, did you forget to inject '$validator'?"); + } + + return; + } + + var fieldOptions = Resolver.generate(el, binding, vnode); + validator.attach(fieldOptions); + }, + inserted: function inserted (el, binding, vnode) { + var field = findField(el, vnode.context); + var scope = Resolver.resolveScope(el, binding, vnode); + + // skip if scope hasn't changed. + if (!field || scope === field.scope) { return; } + + // only update scope. + field.update({ scope: scope }); + + // allows the field to re-evaluated once more in the update hook. + field.updated = false; + }, + update: function update (el, binding, vnode) { + var field = findField(el, vnode.context); + + // make sure we don't do unneccasary work if no important change was done. + if (!field || (field.updated && isEqual$1(binding.value, binding.oldValue))) { return; } + var scope = Resolver.resolveScope(el, binding, vnode); + var rules = Resolver.resolveRules(el, binding, vnode); + + field.update({ + scope: scope, + rules: rules + }); + }, + unbind: function unbind (el, binding, ref) { + var context = ref.context; + + var field = findField(el, context); + if (!field) { return; } + + context.$validator.detach(field); + } + }; + + var Vue; + + function install (_Vue, options) { + if ( options === void 0 ) options = {}; + + if (Vue && _Vue === Vue) { + { + warn('already installed, Vue.use(VeeValidate) should only be called once.'); + } + return; + } + + detectPassiveSupport(); + Vue = _Vue; + var validator = new Validator(null, options); + var localVue = new Vue({ + data: function () { return ({ + errors: validator.errors, + fields: validator.fields + }); } + }); + Config.register('vm', localVue); + Config.register('validator', validator); + Config.merge(options); + + var ref = Config.current; + var dictionary = ref.dictionary; + var i18n = ref.i18n; + + if (dictionary) { + validator.localize(dictionary); // merge the dictionary. + } + + var onLocaleChanged = function () { + validator.errors.regenerate(); + }; + + // watch locale changes using localVue instance or i18n. + if (!i18n) { + if (typeof window !== 'undefined') { + localVue.$on('localeChanged', onLocaleChanged); + } + } else { + i18n._vm.$watch('locale', onLocaleChanged); + } + + if (!i18n && options.locale) { + validator.localize(options.locale); // set the locale + } + + Validator.setStrictMode(Config.current.strict); + + Vue.mixin(mixin); + Vue.directive('validate', directive); + } + + // + + function use (plugin, options) { + if ( options === void 0 ) options = {}; + + if (!isCallable(plugin)) { + return warn('The plugin must be a callable function'); + } + + plugin({ Validator: Validator, ErrorBag: ErrorBag, Rules: Validator.rules }, options); + } + + // + + var normalize = function (fields) { + if (Array.isArray(fields)) { + return fields.reduce(function (prev, curr) { + if (includes(curr, '.')) { + prev[curr.split('.')[1]] = curr; + } else { + prev[curr] = curr; + } + + return prev; + }, {}); + } + + return fields; + }; + + // Combines two flags using either AND or OR depending on the flag type. + var combine = function (lhs, rhs) { + var mapper = { + pristine: function (lhs, rhs) { return lhs && rhs; }, + dirty: function (lhs, rhs) { return lhs || rhs; }, + touched: function (lhs, rhs) { return lhs || rhs; }, + untouched: function (lhs, rhs) { return lhs && rhs; }, + valid: function (lhs, rhs) { return lhs && rhs; }, + invalid: function (lhs, rhs) { return lhs || rhs; }, + pending: function (lhs, rhs) { return lhs || rhs; }, + required: function (lhs, rhs) { return lhs || rhs; }, + validated: function (lhs, rhs) { return lhs && rhs; } + }; + + return Object.keys(mapper).reduce(function (flags, flag) { + flags[flag] = mapper[flag](lhs[flag], rhs[flag]); + + return flags; + }, {}); + }; + + var mapScope = function (scope, deep) { + if ( deep === void 0 ) deep = true; + + return Object.keys(scope).reduce(function (flags, field) { + if (!flags) { + flags = assign({}, scope[field]); + return flags; + } + + // scope. + var isScope = field.indexOf('$') === 0; + if (deep && isScope) { + return combine(mapScope(scope[field]), flags); + } else if (!deep && isScope) { + return flags; + } + + flags = combine(flags, scope[field]); + + return flags; + }, null); + }; + + /** + * Maps fields to computed functions. + */ + var mapFields = function (fields) { + if (!fields) { + return function () { + return mapScope(this.$validator.flags); + }; + } + + var normalized = normalize(fields); + return Object.keys(normalized).reduce(function (prev, curr) { + var field = normalized[curr]; + prev[curr] = function mappedField () { + // if field exists + if (this.$validator.flags[field]) { + return this.$validator.flags[field]; + } + + // scopeless fields were selected. + if (normalized[curr] === '*') { + return mapScope(this.$validator.flags, false); + } + + // if it has a scope defined + var index = field.indexOf('.'); + if (index <= 0) { + return {}; + } + + var ref = field.split('.'); + var scope = ref[0]; + var name = ref.slice(1); + + scope = this.$validator.flags[("$" + scope)]; + name = name.join('.'); + + // an entire scope was selected: scope.* + if (name === '*' && scope) { + return mapScope(scope); + } + + if (scope && scope[name]) { + return scope[name]; + } + + return {}; + }; + + return prev; + }, {}); + }; + + var ErrorComponent = { + name: 'vv-error', + inject: ['$validator'], + functional: true, + props: { + for: { + type: String, + required: true + }, + tag: { + type: String, + default: 'span' + } + }, + render: function render (createElement, ref) { + var props = ref.props; + var injections = ref.injections; + + return createElement(props.tag, injections.$validator.errors.first(props.for)); + } + }; + + var minimal = { + install: install, + use: use, + directive: directive, + mixin: mixin, + mapFields: mapFields, + Validator: Validator, + ErrorBag: ErrorBag, + ErrorComponent: ErrorComponent, + version: '2.1.0-beta.9' + }; + + // rules plugin definition. + var rulesPlugin = function (ref) { + var Validator = ref.Validator; + + Object.keys(Rules).forEach(function (rule) { + Validator.extend(rule, Rules[rule].validate, assign({}, Rules[rule].options, { paramNames: Rules[rule].paramNames })); + }); + + // Merge the english messages. + Validator.localize('en', locale$1); + }; + + // install the rules via the plugin API. + minimal.use(rulesPlugin); + + minimal.Rules = Rules; + + return minimal; + +}))); diff --git a/net452/SiteServer.Web/SiteServer/assets/lib/vee-validate-locale-zh_CN-2.1.0.js b/net452/SiteServer.Web/SiteServer/assets/lib/vee-validate-locale-zh_CN-2.1.0.js new file mode 100644 index 000000000..8af33f16d --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/lib/vee-validate-locale-zh_CN-2.1.0.js @@ -0,0 +1 @@ +!function(n,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(n.__vee_validate_locale__zh_CN=n.__vee_validate_locale__zh_CN||{},n.__vee_validate_locale__zh_CN.js=e())}(this,function(){"use strict";var n,e={name:"zh_CN",messages:{after:function(n,e){return n+"必须在"+e[0]+"之后"},alpha_dash:function(n){return n+"能够包含字母数字字符、破折号和下划线"},alpha_num:function(n){return n+"只能包含字母数字字符"},alpha_spaces:function(n){return n+"只能包含字母字符和空格"},alpha:function(n){return n+"只能包含字母字符"},before:function(n,e){return n+"必须在"+e[0]+"之前"},between:function(n,e){return n+"必须在"+e[0]+"与"+e[1]+"之间"},confirmed:function(n,e){return n+"不能和"+e[0]+"匹配"},date_between:function(n,e){return n+"必须在"+e[0]+"和"+e[1]+"之间"},date_format:function(n,e){return n+"必须符合"+e[0]+"格式"},decimal:function(n,e){void 0===e&&(e=[]);var t=e[0];return void 0===t&&(t="*"),n+"必须是数字,且能够保留"+("*"===t?"":t)+"位小数"},digits:function(n,e){return n+"必须是数字,且精确到"+e[0]+"位数"},dimensions:function(n,e){return n+"必须在"+e[0]+"像素与"+e[1]+"像素之间"},email:function(n){return n+"不是一个有效的邮箱"},ext:function(n){return n+"不是一个有效的文件"},image:function(n){return n+"不是一张有效的图片"},included:function(n){return n+"不是一个有效值"},ip:function(n){return n+"不是一个有效的地址"},max:function(n,e){return n+"不能超过"+e[0]+"个字符"},max_value:function(n,e){return n+"必须小于或等于"+e[0]},mimes:function(n){return n+"不是一个有效的文件类型"},min:function(n,e){return n+"必须至少有"+e[0]+"个字符"},min_value:function(n,e){return n+"必须大于或等于"+e[0]},excluded:function(n){return n+"不是一个有效值"},numeric:function(n){return n+"只能包含数字字符"},regex:function(n){return n+"格式无效"},required:function(n){return n+"是必须的"},size:function(n,e){var t,r,u,i=e[0];return n+"必须小于"+(t=i,r=1024,u=0==(t=Number(t)*r)?0:Math.floor(Math.log(t)/Math.log(r)),1*(t/Math.pow(r,u)).toFixed(2)+" "+["Byte","KB","MB","GB","TB","PB","EB","ZB","YB"][u])},url:function(n){return n+"不是一个有效的url"}},attributes:{}};return"undefined"!=typeof VeeValidate&&VeeValidate.Validator.localize(((n={})[e.name]=e,n)),e}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/lib/vue-2.5.16.min.js b/net452/SiteServer.Web/SiteServer/assets/lib/vue-2.5.16.min.js new file mode 100644 index 000000000..37febff24 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/lib/vue-2.5.16.min.js @@ -0,0 +1,6 @@ +/*! + * Vue.js v2.5.16 + * (c) 2014-2018 Evan You + * Released under the MIT License. + */ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Vue=t()}(this,function(){"use strict";var y=Object.freeze({});function M(e){return null==e}function D(e){return null!=e}function S(e){return!0===e}function T(e){return"string"==typeof e||"number"==typeof e||"symbol"==typeof e||"boolean"==typeof e}function P(e){return null!==e&&"object"==typeof e}var r=Object.prototype.toString;function l(e){return"[object Object]"===r.call(e)}function i(e){var t=parseFloat(String(e));return 0<=t&&Math.floor(t)===t&&isFinite(e)}function t(e){return null==e?"":"object"==typeof e?JSON.stringify(e,null,2):String(e)}function F(e){var t=parseFloat(e);return isNaN(t)?e:t}function s(e,t){for(var n=Object.create(null),r=e.split(","),i=0;ie.id;)n--;bt.splice(n+1,0,e)}else bt.push(e);Ct||(Ct=!0,Ze(At))}}(this)},St.prototype.run=function(){if(this.active){var e=this.get();if(e!==this.value||P(e)||this.deep){var t=this.value;if(this.value=e,this.user)try{this.cb.call(this.vm,e,t)}catch(e){Fe(e,this.vm,'callback for watcher "'+this.expression+'"')}else this.cb.call(this.vm,e,t)}}},St.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},St.prototype.depend=function(){for(var e=this.deps.length;e--;)this.deps[e].depend()},St.prototype.teardown=function(){if(this.active){this.vm._isBeingDestroyed||f(this.vm._watchers,this);for(var e=this.deps.length;e--;)this.deps[e].removeSub(this);this.active=!1}};var Tt={enumerable:!0,configurable:!0,get:$,set:$};function Et(e,t,n){Tt.get=function(){return this[t][n]},Tt.set=function(e){this[t][n]=e},Object.defineProperty(e,n,Tt)}function jt(e){e._watchers=[];var t=e.$options;t.props&&function(n,r){var i=n.$options.propsData||{},o=n._props={},a=n.$options._propKeys=[];n.$parent&&ge(!1);var e=function(e){a.push(e);var t=Ie(e,r,i,n);Ce(o,e,t),e in n||Et(n,"_props",e)};for(var t in r)e(t);ge(!0)}(e,t.props),t.methods&&function(e,t){e.$options.props;for(var n in t)e[n]=null==t[n]?$:v(t[n],e)}(e,t.methods),t.data?function(e){var t=e.$options.data;l(t=e._data="function"==typeof t?function(e,t){se();try{return e.call(t,t)}catch(e){return Fe(e,t,"data()"),{}}finally{ce()}}(t,e):t||{})||(t={});var n=Object.keys(t),r=e.$options.props,i=(e.$options.methods,n.length);for(;i--;){var o=n[i];r&&p(r,o)||(void 0,36!==(a=(o+"").charCodeAt(0))&&95!==a&&Et(e,"_data",o))}var a;we(t,!0)}(e):we(e._data={},!0),t.computed&&function(e,t){var n=e._computedWatchers=Object.create(null),r=Y();for(var i in t){var o=t[i],a="function"==typeof o?o:o.get;r||(n[i]=new St(e,a||$,$,Nt)),i in e||Lt(e,i,o)}}(e,t.computed),t.watch&&t.watch!==G&&function(e,t){for(var n in t){var r=t[n];if(Array.isArray(r))for(var i=0;iparseInt(this.max)&&bn(a,s[0],s,this._vnode)),t.data.keepAlive=!0}return t||e&&e[0]}}};$n=hn,Cn={get:function(){return j}},Object.defineProperty($n,"config",Cn),$n.util={warn:re,extend:m,mergeOptions:Ne,defineReactive:Ce},$n.set=xe,$n.delete=ke,$n.nextTick=Ze,$n.options=Object.create(null),k.forEach(function(e){$n.options[e+"s"]=Object.create(null)}),m(($n.options._base=$n).options.components,kn),$n.use=function(e){var t=this._installedPlugins||(this._installedPlugins=[]);if(-1=a&&l()};setTimeout(function(){c\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,oo="[a-zA-Z_][\\w\\-\\.]*",ao="((?:"+oo+"\\:)?"+oo+")",so=new RegExp("^<"+ao),co=/^\s*(\/?)>/,lo=new RegExp("^<\\/"+ao+"[^>]*>"),uo=/^]+>/i,fo=/^",""":'"',"&":"&"," ":"\n"," ":"\t"},go=/&(?:lt|gt|quot|amp);/g,_o=/&(?:lt|gt|quot|amp|#10|#9);/g,bo=s("pre,textarea",!0),$o=function(e,t){return e&&bo(e)&&"\n"===t[0]};var wo,Co,xo,ko,Ao,Oo,So,To,Eo=/^@|^v-on:/,jo=/^v-|^@|^:/,No=/([^]*?)\s+(?:in|of)\s+([^]*)/,Lo=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,Io=/^\(|\)$/g,Mo=/:(.*)$/,Do=/^:|^v-bind:/,Po=/\.[^.]+/g,Fo=e(eo);function Ro(e,t,n){return{type:1,tag:e,attrsList:t,attrsMap:function(e){for(var t={},n=0,r=e.length;n]*>)","i")),n=i.replace(t,function(e,t,n){return r=n.length,ho(o)||"noscript"===o||(t=t.replace(//g,"$1").replace(//g,"$1")),$o(o,t)&&(t=t.slice(1)),d.chars&&d.chars(t),""});a+=i.length-n.length,i=n,A(o,a-r,a)}else{var s=i.indexOf("<");if(0===s){if(fo.test(i)){var c=i.indexOf("--\x3e");if(0<=c){d.shouldKeepComment&&d.comment(i.substring(4,c)),C(c+3);continue}}if(po.test(i)){var l=i.indexOf("]>");if(0<=l){C(l+2);continue}}var u=i.match(uo);if(u){C(u[0].length);continue}var f=i.match(lo);if(f){var p=a;C(f[0].length),A(f[1],p,a);continue}var _=x();if(_){k(_),$o(v,i)&&C(1);continue}}var b=void 0,$=void 0,w=void 0;if(0<=s){for($=i.slice(s);!(lo.test($)||so.test($)||fo.test($)||po.test($)||(w=$.indexOf("<",1))<0);)s+=w,$=i.slice(s);b=i.substring(0,s),C(s)}s<0&&(b=i,i=""),d.chars&&b&&d.chars(b)}if(i===e){d.chars&&d.chars(i);break}}function C(e){a+=e,i=i.substring(e)}function x(){var e=i.match(so);if(e){var t,n,r={tagName:e[1],attrs:[],start:a};for(C(e[0].length);!(t=i.match(co))&&(n=i.match(io));)C(n[0].length),r.attrs.push(n);if(t)return r.unarySlash=t[1],C(t[0].length),r.end=a,r}}function k(e){var t=e.tagName,n=e.unarySlash;m&&("p"===v&&ro(t)&&A(v),g(t)&&v===t&&A(t));for(var r,i,o,a=y(t)||!!n,s=e.attrs.length,c=new Array(s),l=0;l-1"+("true"===d?":("+l+")":":_q("+l+","+d+")")),Ar(c,"change","var $$a="+l+",$$el=$event.target,$$c=$$el.checked?("+d+"):("+v+");if(Array.isArray($$a)){var $$v="+(f?"_n("+p+")":p)+",$$i=_i($$a,$$v);if($$el.checked){$$i<0&&("+Er(l,"$$a.concat([$$v])")+")}else{$$i>-1&&("+Er(l,"$$a.slice(0,$$i).concat($$a.slice($$i+1))")+")}}else{"+Er(l,"$$c")+"}",null,!0);else if("input"===$&&"radio"===w)r=e,i=_,a=(o=b)&&o.number,s=Or(r,"value")||"null",Cr(r,"checked","_q("+i+","+(s=a?"_n("+s+")":s)+")"),Ar(r,"change",Er(i,s),null,!0);else if("input"===$||"textarea"===$)!function(e,t,n){var r=e.attrsMap.type,i=n||{},o=i.lazy,a=i.number,s=i.trim,c=!o&&"range"!==r,l=o?"change":"range"===r?Pr:"input",u="$event.target.value";s&&(u="$event.target.value.trim()"),a&&(u="_n("+u+")");var f=Er(t,u);c&&(f="if($event.target.composing)return;"+f),Cr(e,"value","("+t+")"),Ar(e,l,f,null,!0),(s||a)&&Ar(e,"blur","$forceUpdate()")}(e,_,b);else if(!j.isReservedTag($))return Tr(e,_,b),!1;return!0},text:function(e,t){t.value&&Cr(e,"textContent","_s("+t.value+")")},html:function(e,t){t.value&&Cr(e,"innerHTML","_s("+t.value+")")}},isPreTag:function(e){return"pre"===e},isUnaryTag:to,mustUseProp:Sn,canBeLeftOpenTag:no,isReservedTag:Un,getTagNamespace:Vn,staticKeys:(Go=Wo,Go.reduce(function(e,t){return e.concat(t.staticKeys||[])},[]).join(","))},Qo=e(function(e){return s("type,tag,attrsList,attrsMap,plain,parent,children,attrs"+(e?","+e:""))});function ea(e,t){e&&(Zo=Qo(t.staticKeys||""),Xo=t.isReservedTag||O,function e(t){t.static=function(e){if(2===e.type)return!1;if(3===e.type)return!0;return!(!e.pre&&(e.hasBindings||e.if||e.for||c(e.tag)||!Xo(e.tag)||function(e){for(;e.parent;){if("template"!==(e=e.parent).tag)return!1;if(e.for)return!0}return!1}(e)||!Object.keys(e).every(Zo)))}(t);if(1===t.type){if(!Xo(t.tag)&&"slot"!==t.tag&&null==t.attrsMap["inline-template"])return;for(var n=0,r=t.children.length;n|^function\s*\(/,na=/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/,ra={esc:27,tab:9,enter:13,space:32,up:38,left:37,right:39,down:40,delete:[8,46]},ia={esc:"Escape",tab:"Tab",enter:"Enter",space:" ",up:["Up","ArrowUp"],left:["Left","ArrowLeft"],right:["Right","ArrowRight"],down:["Down","ArrowDown"],delete:["Backspace","Delete"]},oa=function(e){return"if("+e+")return null;"},aa={stop:"$event.stopPropagation();",prevent:"$event.preventDefault();",self:oa("$event.target !== $event.currentTarget"),ctrl:oa("!$event.ctrlKey"),shift:oa("!$event.shiftKey"),alt:oa("!$event.altKey"),meta:oa("!$event.metaKey"),left:oa("'button' in $event && $event.button !== 0"),middle:oa("'button' in $event && $event.button !== 1"),right:oa("'button' in $event && $event.button !== 2")};function sa(e,t,n){var r=t?"nativeOn:{":"on:{";for(var i in e)r+='"'+i+'":'+ca(i,e[i])+",";return r.slice(0,-1)+"}"}function ca(t,e){if(!e)return"function(){}";if(Array.isArray(e))return"["+e.map(function(e){return ca(t,e)}).join(",")+"]";var n=na.test(e.value),r=ta.test(e.value);if(e.modifiers){var i="",o="",a=[];for(var s in e.modifiers)if(aa[s])o+=aa[s],ra[s]&&a.push(s);else if("exact"===s){var c=e.modifiers;o+=oa(["ctrl","shift","alt","meta"].filter(function(e){return!c[e]}).map(function(e){return"$event."+e+"Key"}).join("||"))}else a.push(s);return a.length&&(i+="if(!('button' in $event)&&"+a.map(la).join("&&")+")return null;"),o&&(i+=o),"function($event){"+i+(n?"return "+e.value+"($event)":r?"return ("+e.value+")($event)":e.value)+"}"}return n||r?e.value:"function($event){"+e.value+"}"}function la(e){var t=parseInt(e,10);if(t)return"$event.keyCode!=="+t;var n=ra[e],r=ia[e];return"_k($event.keyCode,"+JSON.stringify(e)+","+JSON.stringify(n)+",$event.key,"+JSON.stringify(r)+")"}var ua={on:function(e,t){e.wrapListeners=function(e){return"_g("+e+","+t.value+")"}},bind:function(t,n){t.wrapData=function(e){return"_b("+e+",'"+t.tag+"',"+n.value+","+(n.modifiers&&n.modifiers.prop?"true":"false")+(n.modifiers&&n.modifiers.sync?",true":"")+")"}},cloak:$},fa=function(e){this.options=e,this.warn=e.warn||$r,this.transforms=wr(e.modules,"transformCode"),this.dataGenFns=wr(e.modules,"genData"),this.directives=m(m({},ua),e.directives);var t=e.isReservedTag||O;this.maybeComponent=function(e){return!t(e.tag)},this.onceId=0,this.staticRenderFns=[]};function pa(e,t){var n=new fa(t);return{render:"with(this){return "+(e?da(e,n):'_c("div")')+"}",staticRenderFns:n.staticRenderFns}}function da(e,t){if(e.staticRoot&&!e.staticProcessed)return va(e,t);if(e.once&&!e.onceProcessed)return ha(e,t);if(e.for&&!e.forProcessed)return f=t,v=(u=e).for,h=u.alias,m=u.iterator1?","+u.iterator1:"",y=u.iterator2?","+u.iterator2:"",u.forProcessed=!0,(d||"_l")+"(("+v+"),function("+h+m+y+"){return "+(p||da)(u,f)+"})";if(e.if&&!e.ifProcessed)return ma(e,t);if("template"!==e.tag||e.slotTarget){if("slot"===e.tag)return function(e,t){var n=e.slotName||'"default"',r=_a(e,t),i="_t("+n+(r?","+r:""),o=e.attrs&&"{"+e.attrs.map(function(e){return g(e.name)+":"+e.value}).join(",")+"}",a=e.attrsMap["v-bind"];!o&&!a||r||(i+=",null");o&&(i+=","+o);a&&(i+=(o?"":",null")+","+a);return i+")"}(e,t);var n;if(e.component)a=e.component,c=t,l=(s=e).inlineTemplate?null:_a(s,c,!0),n="_c("+a+","+ya(s,c)+(l?","+l:"")+")";else{var r=e.plain?void 0:ya(e,t),i=e.inlineTemplate?null:_a(e,t,!0);n="_c('"+e.tag+"'"+(r?","+r:"")+(i?","+i:"")+")"}for(var o=0;o':'
          ',00?i:n)(t)}},function(t,e,n){var i=n(13);t.exports=function(t,e){if(!i(t))return t;var n,r;if(e&&"function"==typeof(n=t.toString)&&!i(r=n.call(t)))return r;if("function"==typeof(n=t.valueOf)&&!i(r=n.call(t)))return r;if(!e&&"function"==typeof(n=t.toString)&&!i(r=n.call(t)))return r;throw TypeError("Can't convert object to primitive value")}},function(t,e,n){var i=n(0),r=n(11),o=n(25),s=n(33),u=n(3).f;t.exports=function(t){var e=r.Symbol||(r.Symbol=o?{}:i.Symbol||{});"_"==t.charAt(0)||t in e||u(e,t,{value:s.f(t)})}},function(t,e,n){e.f=n(7)},function(t,e,n){var i=n(53),r=n(36),o=n(57),s=n(37),u=n(104);t.exports=function(t,e){var n=1==t,a=2==t,l=3==t,c=4==t,f=6==t,p=5==t||f,h=e||u;return function(e,u,d){for(var v,y,g=o(e),b=r(g),m=i(u,d,3),_=s(b.length),x=0,w=n?h(e,_):a?h(e,0):void 0;_>x;x++)if((p||x in b)&&(v=b[x],y=m(v,x,g),t))if(n)w[x]=y;else if(y)switch(t){case 3:return!0;case 5:return v;case 6:return x;case 2:w.push(v)}else if(c)return!1;return f?-1:l||c?c:w}}},function(t,e,n){t.exports=!n(8)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,e,n){var i=n(51);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==i(t)?t.split(""):Object(t)}},function(t,e,n){var i=n(56),r=Math.min;t.exports=function(t){return t>0?r(i(t),9007199254740991):0}},function(t,e,n){var i=n(111)("wks"),r=n(58),o=n(9).Symbol,s="function"==typeof o;(t.exports=function(t){return i[t]||(i[t]=s&&o[t]||(s?o:r)("Symbol."+t))}).store=i},function(t,e,n){"use strict";function i(t){return 0!==t&&(!(!Array.isArray(t)||0!==t.length)||!t)}function r(t){return function(){return!t.apply(void 0,arguments)}}function o(t,e){return void 0===t&&(t="undefined"),null===t&&(t="null"),!1===t&&(t="false"),-1!==t.toString().toLowerCase().indexOf(e.trim())}function s(t,e,n,i){return t.filter(function(t){return o(i(t,n),e)})}function u(t){return t.filter(function(t){return!t.$isLabel})}function a(t,e){return function(n){return n.reduce(function(n,i){return i[t]&&i[t].length?(n.push({$groupLabel:i[e],$isLabel:!0}),n.concat(i[t])):n},[])}}function l(t,e,n,i,r){return function(o){return o.map(function(o){var u;if(!o[n])return console.warn("Options passed to vue-multiselect do not contain groups, despite the config."),[];var a=s(o[n],t,e,r);return a.length?(u={},v()(u,i,o[i]),v()(u,n,a),u):[]})}}var c=n(65),f=n.n(c),p=n(59),h=(n.n(p),n(122)),d=(n.n(h),n(64)),v=n.n(d),y=n(120),g=(n.n(y),n(121)),b=(n.n(g),n(117)),m=(n.n(b),n(123)),_=(n.n(m),n(118)),x=(n.n(_),n(119)),w=(n.n(x),function(){for(var t=arguments.length,e=new Array(t),n=0;n-1},isSelected:function(t){var e=this.trackBy?t[this.trackBy]:t;return this.valueKeys.indexOf(e)>-1},getOptionLabel:function(t){if(i(t))return"";if(t.isTag)return t.label;if(t.$isLabel)return t.$groupLabel;var e=this.customLabel(t,this.label);return i(e)?"":e},select:function(t,e){if(t.$isLabel&&this.groupSelect)return void this.selectGroup(t);if(!(-1!==this.blockKeys.indexOf(e)||this.disabled||t.$isDisabled||t.$isLabel)&&(!this.max||!this.multiple||this.internalValue.length!==this.max)&&("Tab"!==e||this.pointerDirty)){if(t.isTag)this.$emit("tag",t.label,this.id),this.search="",this.closeOnSelect&&!this.multiple&&this.deactivate();else{if(this.isSelected(t))return void("Tab"!==e&&this.removeElement(t));this.$emit("select",t,this.id),this.multiple?this.$emit("input",this.internalValue.concat([t]),this.id):this.$emit("input",t,this.id),this.clearOnSelect&&(this.search="")}this.closeOnSelect&&this.deactivate()}},selectGroup:function(t){var e=this,n=this.options.find(function(n){return n[e.groupLabel]===t.$groupLabel});if(n)if(this.wholeGroupSelected(n)){this.$emit("remove",n[this.groupValues],this.id);var i=this.internalValue.filter(function(t){return-1===n[e.groupValues].indexOf(t)});this.$emit("input",i,this.id)}else{var o=n[this.groupValues].filter(r(this.isSelected));this.$emit("select",o,this.id),this.$emit("input",this.internalValue.concat(o),this.id)}},wholeGroupSelected:function(t){return t[this.groupValues].every(this.isSelected)},removeElement:function(t){var e=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];if(!this.disabled){if(!this.allowEmpty&&this.internalValue.length<=1)return void this.deactivate();var n="object"===f()(t)?this.valueKeys.indexOf(t[this.trackBy]):this.valueKeys.indexOf(t);if(this.$emit("remove",t,this.id),this.multiple){var i=this.internalValue.slice(0,n).concat(this.internalValue.slice(n+1));this.$emit("input",i,this.id)}else this.$emit("input",null,this.id);this.closeOnSelect&&e&&this.deactivate()}},removeLastElement:function(){-1===this.blockKeys.indexOf("Delete")&&0===this.search.length&&Array.isArray(this.internalValue)&&this.removeElement(this.internalValue[this.internalValue.length-1],!1)},activate:function(){var t=this;this.isOpen||this.disabled||(this.adjustPosition(),this.groupValues&&0===this.pointer&&this.filteredOptions.length&&(this.pointer=1),this.isOpen=!0,this.searchable?(this.preserveSearch||(this.search=""),this.$nextTick(function(){return t.$refs.search.focus()})):this.$el.focus(),this.$emit("open",this.id))},deactivate:function(){this.isOpen&&(this.isOpen=!1,this.searchable?this.$refs.search.blur():this.$el.blur(),this.preserveSearch||(this.search=""),this.$emit("close",this.getValue(),this.id))},toggle:function(){this.isOpen?this.deactivate():this.activate()},adjustPosition:function(){if("undefined"!=typeof window){var t=this.$el.getBoundingClientRect().top,e=window.innerHeight-this.$el.getBoundingClientRect().bottom;e>this.maxHeight||e>t||"below"===this.openDirection||"bottom"===this.openDirection?(this.prefferedOpenDirection="below",this.optimizedHeight=Math.min(e-40,this.maxHeight)):(this.prefferedOpenDirection="above",this.optimizedHeight=Math.min(t-40,this.maxHeight))}}}}},function(t,e,n){"use strict";var i=n(59);n.n(i);e.a={data:function(){return{pointer:0,pointerDirty:!1}},props:{showPointer:{type:Boolean,default:!0},optionHeight:{type:Number,default:40}},computed:{pointerPosition:function(){return this.pointer*this.optionHeight},visibleElements:function(){return this.optimizedHeight/this.optionHeight}},watch:{filteredOptions:function(){this.pointerAdjust()},isOpen:function(){this.pointerDirty=!1}},methods:{optionHighlight:function(t,e){return{"multiselect__option--highlight":t===this.pointer&&this.showPointer,"multiselect__option--selected":this.isSelected(e)}},groupHighlight:function(t,e){var n=this;if(!this.groupSelect)return["multiselect__option--disabled"];var i=this.options.find(function(t){return t[n.groupLabel]===e.$groupLabel});return[this.groupSelect?"multiselect__option--group":"multiselect__option--disabled",{"multiselect__option--highlight":t===this.pointer&&this.showPointer},{"multiselect__option--group-selected":this.wholeGroupSelected(i)}]},addPointerElement:function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"Enter",e=t.key;this.filteredOptions.length>0&&this.select(this.filteredOptions[this.pointer],e),this.pointerReset()},pointerForward:function(){this.pointer0?(this.pointer--,this.$refs.list.scrollTop>=this.pointerPosition&&(this.$refs.list.scrollTop=this.pointerPosition),this.filteredOptions[this.pointer]&&this.filteredOptions[this.pointer].$isLabel&&!this.groupSelect&&this.pointerBackward()):this.filteredOptions[this.pointer]&&this.filteredOptions[0].$isLabel&&!this.groupSelect&&this.pointerForward(),this.pointerDirty=!0},pointerReset:function(){this.closeOnSelect&&(this.pointer=0,this.$refs.list&&(this.$refs.list.scrollTop=0))},pointerAdjust:function(){this.pointer>=this.filteredOptions.length-1&&(this.pointer=this.filteredOptions.length?this.filteredOptions.length-1:0),this.filteredOptions.length>0&&this.filteredOptions[this.pointer].$isLabel&&!this.groupSelect&&this.pointerForward()},pointerSet:function(t){this.pointer=t,this.pointerDirty=!0}}}},function(t,e){var n={}.toString;t.exports=function(t){return n.call(t).slice(8,-1)}},function(t,e,n){var i=n(13),r=n(0).document,o=i(r)&&i(r.createElement);t.exports=function(t){return o?r.createElement(t):{}}},function(t,e,n){t.exports=!n(1)&&!n(12)(function(){return 7!=Object.defineProperty(n(42)("div"),"a",{get:function(){return 7}}).a})},function(t,e,n){"use strict";var i=n(25),r=n(23),o=n(49),s=n(6),u=n(2),a=n(24),l=n(79),c=n(27),f=n(86),p=n(7)("iterator"),h=!([].keys&&"next"in[].keys()),d=function(){return this};t.exports=function(t,e,n,v,y,g,b){l(n,e,v);var m,_,x,w=function(t){if(!h&&t in P)return P[t];switch(t){case"keys":case"values":return function(){return new n(this,t)}}return function(){return new n(this,t)}},S=e+" Iterator",O="values"==y,L=!1,P=t.prototype,k=P[p]||P["@@iterator"]||y&&P[y],E=k||w(y),j=y?O?w("entries"):E:void 0,V="Array"==e?P.entries||k:k;if(V&&(x=f(V.call(new t)))!==Object.prototype&&(c(x,S,!0),i||u(x,p)||s(x,p,d)),O&&k&&"values"!==k.name&&(L=!0,E=function(){return k.call(this)}),i&&!b||!h&&!L&&P[p]||s(P,p,E),a[e]=E,a[S]=d,y)if(m={values:O?E:w("values"),keys:g?E:w("keys"),entries:j},b)for(_ in m)_ in P||o(P,_,m[_]);else r(r.P+r.F*(h||L),e,m);return m}},function(t,e,n){var i=n(10),r=n(83),o=n(22),s=n(28)("IE_PROTO"),u=function(){},a=function(){var t,e=n(42)("iframe"),i=o.length;for(e.style.display="none",n(76).appendChild(e),e.src="javascript:",t=e.contentWindow.document,t.open(),t.write("."); + } + }; + + // .on() was added in version 1.7.0, .load() was removed in version 3.0.0 so we fallback to .load() if .on() does + // not exist to not break existing applications + if (typeof _pageWindow.on == "function") { + _pageWindow.on("load", function () { _pageLoaded = true; }); + } + else { + _pageWindow.load(function () { _pageLoaded = true; }); + } + + function validateTransport(requestedTransport, connection) { + /// Validates the requested transport by cross checking it with the pre-defined signalR.transports + /// The designated transports that the user has specified. + /// The connection that will be using the requested transports. Used for logging purposes. + /// + + if ($.isArray(requestedTransport)) { + // Go through transport array and remove an "invalid" tranports + for (var i = requestedTransport.length - 1; i >= 0; i--) { + var transport = requestedTransport[i]; + if ($.type(transport) !== "string" || !signalR.transports[transport]) { + connection.log("Invalid transport: " + transport + ", removing it from the transports list."); + requestedTransport.splice(i, 1); + } + } + + // Verify we still have transports left, if we dont then we have invalid transports + if (requestedTransport.length === 0) { + connection.log("No transports remain within the specified transport array."); + requestedTransport = null; + } + } else if (!signalR.transports[requestedTransport] && requestedTransport !== "auto") { + connection.log("Invalid transport: " + requestedTransport.toString() + "."); + requestedTransport = null; + } else if (requestedTransport === "auto" && signalR._.ieVersion <= 8) { + // If we're doing an auto transport and we're IE8 then force longPolling, #1764 + return ["longPolling"]; + + } + + return requestedTransport; + } + + function getDefaultPort(protocol) { + if (protocol === "http:") { + return 80; + } else if (protocol === "https:") { + return 443; + } + } + + function addDefaultPort(protocol, url) { + // Remove ports from url. We have to check if there's a / or end of line + // following the port in order to avoid removing ports such as 8080. + if (url.match(/:\d+$/)) { + return url; + } else { + return url + ":" + getDefaultPort(protocol); + } + } + + function ConnectingMessageBuffer(connection, drainCallback) { + var that = this, + buffer = []; + + that.tryBuffer = function (message) { + if (connection.state === $.signalR.connectionState.connecting) { + buffer.push(message); + + return true; + } + + return false; + }; + + that.drain = function () { + // Ensure that the connection is connected when we drain (do not want to drain while a connection is not active) + if (connection.state === $.signalR.connectionState.connected) { + while (buffer.length > 0) { + drainCallback(buffer.shift()); + } + } + }; + + that.clear = function () { + buffer = []; + }; + } + + signalR.fn = signalR.prototype = { + init: function (url, qs, logging) { + var $connection = $(this); + + this.url = url; + this.qs = qs; + this.lastError = null; + this._ = { + keepAliveData: {}, + connectingMessageBuffer: new ConnectingMessageBuffer(this, function (message) { + $connection.triggerHandler(events.onReceived, [message]); + }), + lastMessageAt: new Date().getTime(), + lastActiveAt: new Date().getTime(), + beatInterval: 5000, // Default value, will only be overridden if keep alive is enabled, + beatHandle: null, + totalTransportConnectTimeout: 0 // This will be the sum of the TransportConnectTimeout sent in response to negotiate and connection.transportConnectTimeout + }; + if (typeof (logging) === "boolean") { + this.logging = logging; + } + }, + + _parseResponse: function (response) { + var that = this; + + if (!response) { + return response; + } else if (typeof response === "string") { + return that.json.parse(response); + } else { + return response; + } + }, + + _originalJson: window.JSON, + + json: window.JSON, + + isCrossDomain: function (url, against) { + /// Checks if url is cross domain + /// The base URL + /// + /// An optional argument to compare the URL against, if not specified it will be set to window.location. + /// If specified it must contain a protocol and a host property. + /// + var link; + + url = $.trim(url); + + against = against || window.location; + + if (url.indexOf("http") !== 0) { + return false; + } + + // Create an anchor tag. + link = window.document.createElement("a"); + link.href = url; + + // When checking for cross domain we have to special case port 80 because the window.location will remove the + return link.protocol + addDefaultPort(link.protocol, link.host) !== against.protocol + addDefaultPort(against.protocol, against.host); + }, + + ajaxDataType: "text", + + contentType: "application/json; charset=UTF-8", + + logging: false, + + state: signalR.connectionState.disconnected, + + clientProtocol: "1.5", + + reconnectDelay: 2000, + + transportConnectTimeout: 0, + + disconnectTimeout: 30000, // This should be set by the server in response to the negotiate request (30s default) + + reconnectWindow: 30000, // This should be set by the server in response to the negotiate request + + keepAliveWarnAt: 2 / 3, // Warn user of slow connection if we breach the X% mark of the keep alive timeout + + start: function (options, callback) { + /// Starts the connection + /// Options map + /// A callback function to execute when the connection has started + var connection = this, + config = { + pingInterval: 300000, + waitForPageLoad: true, + transport: "auto", + jsonp: false + }, + initialize, + deferred = connection._deferral || $.Deferred(), // Check to see if there is a pre-existing deferral that's being built on, if so we want to keep using it + parser = window.document.createElement("a"); + + connection.lastError = null; + + // Persist the deferral so that if start is called multiple times the same deferral is used. + connection._deferral = deferred; + + if (!connection.json) { + // no JSON! + throw new Error("SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8."); + } + + if ($.type(options) === "function") { + // Support calling with single callback parameter + callback = options; + } else if ($.type(options) === "object") { + $.extend(config, options); + if ($.type(config.callback) === "function") { + callback = config.callback; + } + } + + config.transport = validateTransport(config.transport, connection); + + // If the transport is invalid throw an error and abort start + if (!config.transport) { + throw new Error("SignalR: Invalid transport(s) specified, aborting start."); + } + + connection._.config = config; + + // Check to see if start is being called prior to page load + // If waitForPageLoad is true we then want to re-direct function call to the window load event + if (!_pageLoaded && config.waitForPageLoad === true) { + connection._.deferredStartHandler = function () { + connection.start(options, callback); + }; + _pageWindow.bind("load", connection._.deferredStartHandler); + + return deferred.promise(); + } + + // If we're already connecting just return the same deferral as the original connection start + if (connection.state === signalR.connectionState.connecting) { + return deferred.promise(); + } else if (changeState(connection, + signalR.connectionState.disconnected, + signalR.connectionState.connecting) === false) { + // We're not connecting so try and transition into connecting. + // If we fail to transition then we're either in connected or reconnecting. + + deferred.resolve(connection); + return deferred.promise(); + } + + configureStopReconnectingTimeout(connection); + + // Resolve the full url + parser.href = connection.url; + if (!parser.protocol || parser.protocol === ":") { + connection.protocol = window.document.location.protocol; + connection.host = parser.host || window.document.location.host; + } else { + connection.protocol = parser.protocol; + connection.host = parser.host; + } + + connection.baseUrl = connection.protocol + "//" + connection.host; + + // Set the websocket protocol + connection.wsProtocol = connection.protocol === "https:" ? "wss://" : "ws://"; + + // If jsonp with no/auto transport is specified, then set the transport to long polling + // since that is the only transport for which jsonp really makes sense. + // Some developers might actually choose to specify jsonp for same origin requests + // as demonstrated by Issue #623. + if (config.transport === "auto" && config.jsonp === true) { + config.transport = "longPolling"; + } + + // If the url is protocol relative, prepend the current windows protocol to the url. + if (connection.url.indexOf("//") === 0) { + connection.url = window.location.protocol + connection.url; + connection.log("Protocol relative URL detected, normalizing it to '" + connection.url + "'."); + } + + if (this.isCrossDomain(connection.url)) { + connection.log("Auto detected cross domain url."); + + if (config.transport === "auto") { + // TODO: Support XDM with foreverFrame + config.transport = ["webSockets", "serverSentEvents", "longPolling"]; + } + + if (typeof (config.withCredentials) === "undefined") { + config.withCredentials = true; + } + + // Determine if jsonp is the only choice for negotiation, ajaxSend and ajaxAbort. + // i.e. if the browser doesn't supports CORS + // If it is, ignore any preference to the contrary, and switch to jsonp. + if (!config.jsonp) { + config.jsonp = !$.support.cors; + + if (config.jsonp) { + connection.log("Using jsonp because this browser doesn't support CORS."); + } + } + + connection.contentType = signalR._.defaultContentType; + } + + connection.withCredentials = config.withCredentials; + + connection.ajaxDataType = config.jsonp ? "jsonp" : "text"; + + $(connection).bind(events.onStart, function (e, data) { + if ($.type(callback) === "function") { + callback.call(connection); + } + deferred.resolve(connection); + }); + + connection._.initHandler = signalR.transports._logic.initHandler(connection); + + initialize = function (transports, index) { + var noTransportError = signalR._.error(resources.noTransportOnInit); + + index = index || 0; + if (index >= transports.length) { + if (index === 0) { + connection.log("No transports supported by the server were selected."); + } else if (index === 1) { + connection.log("No fallback transports were selected."); + } else { + connection.log("Fallback transports exhausted."); + } + + // No transport initialized successfully + $(connection).triggerHandler(events.onError, [noTransportError]); + deferred.reject(noTransportError); + // Stop the connection if it has connected and move it into the disconnected state + connection.stop(); + return; + } + + // The connection was aborted + if (connection.state === signalR.connectionState.disconnected) { + return; + } + + var transportName = transports[index], + transport = signalR.transports[transportName], + onFallback = function () { + initialize(transports, index + 1); + }; + + connection.transport = transport; + + try { + connection._.initHandler.start(transport, function () { // success + // Firefox 11+ doesn't allow sync XHR withCredentials: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest#withCredentials + var isFirefox11OrGreater = signalR._.firefoxMajorVersion(window.navigator.userAgent) >= 11, + asyncAbort = !!connection.withCredentials && isFirefox11OrGreater; + + connection.log("The start request succeeded. Transitioning to the connected state."); + + if (supportsKeepAlive(connection)) { + signalR.transports._logic.monitorKeepAlive(connection); + } + + signalR.transports._logic.startHeartbeat(connection); + + // Used to ensure low activity clients maintain their authentication. + // Must be configured once a transport has been decided to perform valid ping requests. + signalR._.configurePingInterval(connection); + + if (!changeState(connection, + signalR.connectionState.connecting, + signalR.connectionState.connected)) { + connection.log("WARNING! The connection was not in the connecting state."); + } + + // Drain any incoming buffered messages (messages that came in prior to connect) + connection._.connectingMessageBuffer.drain(); + + $(connection).triggerHandler(events.onStart); + + // wire the stop handler for when the user leaves the page + _pageWindow.bind("unload", function () { + connection.log("Window unloading, stopping the connection."); + + connection.stop(asyncAbort); + }); + + if (isFirefox11OrGreater) { + // Firefox does not fire cross-domain XHRs in the normal unload handler on tab close. + // #2400 + _pageWindow.bind("beforeunload", function () { + // If connection.stop() runs runs in beforeunload and fails, it will also fail + // in unload unless connection.stop() runs after a timeout. + window.setTimeout(function () { + connection.stop(asyncAbort); + }, 0); + }); + } + }, onFallback); + } + catch (error) { + connection.log(transport.name + " transport threw '" + error.message + "' when attempting to start."); + onFallback(); + } + }; + + var url = connection.url + "/negotiate", + onFailed = function (error, connection) { + var err = signalR._.error(resources.errorOnNegotiate, error, connection._.negotiateRequest); + + $(connection).triggerHandler(events.onError, err); + deferred.reject(err); + // Stop the connection if negotiate failed + connection.stop(); + }; + + $(connection).triggerHandler(events.onStarting); + + url = signalR.transports._logic.prepareQueryString(connection, url); + + connection.log("Negotiating with '" + url + "'."); + + // Save the ajax negotiate request object so we can abort it if stop is called while the request is in flight. + connection._.negotiateRequest = signalR.transports._logic.ajax(connection, { + url: url, + error: function (error, statusText) { + // We don't want to cause any errors if we're aborting our own negotiate request. + if (statusText !== _negotiateAbortText) { + onFailed(error, connection); + } else { + // This rejection will noop if the deferred has already been resolved or rejected. + deferred.reject(signalR._.error(resources.stoppedWhileNegotiating, null /* error */, connection._.negotiateRequest)); + } + }, + success: function (result) { + var res, + keepAliveData, + protocolError, + transports = [], + supportedTransports = []; + + try { + res = connection._parseResponse(result); + } catch (error) { + onFailed(signalR._.error(resources.errorParsingNegotiateResponse, error), connection); + return; + } + + keepAliveData = connection._.keepAliveData; + connection.appRelativeUrl = res.Url; + connection.id = res.ConnectionId; + connection.token = res.ConnectionToken; + connection.webSocketServerUrl = res.WebSocketServerUrl; + + // The long poll timeout is the ConnectionTimeout plus 10 seconds + connection._.pollTimeout = res.ConnectionTimeout * 1000 + 10000; // in ms + + // Once the server has labeled the PersistentConnection as Disconnected, we should stop attempting to reconnect + // after res.DisconnectTimeout seconds. + connection.disconnectTimeout = res.DisconnectTimeout * 1000; // in ms + + // Add the TransportConnectTimeout from the response to the transportConnectTimeout from the client to calculate the total timeout + connection._.totalTransportConnectTimeout = connection.transportConnectTimeout + res.TransportConnectTimeout * 1000; + + // If we have a keep alive + if (res.KeepAliveTimeout) { + // Register the keep alive data as activated + keepAliveData.activated = true; + + // Timeout to designate when to force the connection into reconnecting converted to milliseconds + keepAliveData.timeout = res.KeepAliveTimeout * 1000; + + // Timeout to designate when to warn the developer that the connection may be dead or is not responding. + keepAliveData.timeoutWarning = keepAliveData.timeout * connection.keepAliveWarnAt; + + // Instantiate the frequency in which we check the keep alive. It must be short in order to not miss/pick up any changes + connection._.beatInterval = (keepAliveData.timeout - keepAliveData.timeoutWarning) / 3; + } else { + keepAliveData.activated = false; + } + + connection.reconnectWindow = connection.disconnectTimeout + (keepAliveData.timeout || 0); + + if (!res.ProtocolVersion || res.ProtocolVersion !== connection.clientProtocol) { + protocolError = signalR._.error(signalR._.format(resources.protocolIncompatible, connection.clientProtocol, res.ProtocolVersion)); + $(connection).triggerHandler(events.onError, [protocolError]); + deferred.reject(protocolError); + + return; + } + + $.each(signalR.transports, function (key) { + if ((key.indexOf("_") === 0) || (key === "webSockets" && !res.TryWebSockets)) { + return true; + } + supportedTransports.push(key); + }); + + if ($.isArray(config.transport)) { + $.each(config.transport, function (_, transport) { + if ($.inArray(transport, supportedTransports) >= 0) { + transports.push(transport); + } + }); + } else if (config.transport === "auto") { + transports = supportedTransports; + } else if ($.inArray(config.transport, supportedTransports) >= 0) { + transports.push(config.transport); + } + + initialize(transports); + } + }); + + return deferred.promise(); + }, + + starting: function (callback) { + /// Adds a callback that will be invoked before anything is sent over the connection + /// A callback function to execute before the connection is fully instantiated. + /// + var connection = this; + $(connection).bind(events.onStarting, function (e, data) { + callback.call(connection); + }); + return connection; + }, + + send: function (data) { + /// Sends data over the connection + /// The data to send over the connection + /// + var connection = this; + + if (connection.state === signalR.connectionState.disconnected) { + // Connection hasn't been started yet + throw new Error("SignalR: Connection must be started before data can be sent. Call .start() before .send()"); + } + + if (connection.state === signalR.connectionState.connecting) { + // Connection hasn't been started yet + throw new Error("SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started."); + } + + connection.transport.send(connection, data); + // REVIEW: Should we return deferred here? + return connection; + }, + + received: function (callback) { + /// Adds a callback that will be invoked after anything is received over the connection + /// A callback function to execute when any data is received on the connection + /// + var connection = this; + $(connection).bind(events.onReceived, function (e, data) { + callback.call(connection, data); + }); + return connection; + }, + + stateChanged: function (callback) { + /// Adds a callback that will be invoked when the connection state changes + /// A callback function to execute when the connection state changes + /// + var connection = this; + $(connection).bind(events.onStateChanged, function (e, data) { + callback.call(connection, data); + }); + return connection; + }, + + error: function (callback) { + /// Adds a callback that will be invoked after an error occurs with the connection + /// A callback function to execute when an error occurs on the connection + /// + var connection = this; + $(connection).bind(events.onError, function (e, errorData, sendData) { + connection.lastError = errorData; + // In practice 'errorData' is the SignalR built error object. + // In practice 'sendData' is undefined for all error events except those triggered by + // 'ajaxSend' and 'webSockets.send'.'sendData' is the original send payload. + callback.call(connection, errorData, sendData); + }); + return connection; + }, + + disconnected: function (callback) { + /// Adds a callback that will be invoked when the client disconnects + /// A callback function to execute when the connection is broken + /// + var connection = this; + $(connection).bind(events.onDisconnect, function (e, data) { + callback.call(connection); + }); + return connection; + }, + + connectionSlow: function (callback) { + /// Adds a callback that will be invoked when the client detects a slow connection + /// A callback function to execute when the connection is slow + /// + var connection = this; + $(connection).bind(events.onConnectionSlow, function (e, data) { + callback.call(connection); + }); + + return connection; + }, + + reconnecting: function (callback) { + /// Adds a callback that will be invoked when the underlying transport begins reconnecting + /// A callback function to execute when the connection enters a reconnecting state + /// + var connection = this; + $(connection).bind(events.onReconnecting, function (e, data) { + callback.call(connection); + }); + return connection; + }, + + reconnected: function (callback) { + /// Adds a callback that will be invoked when the underlying transport reconnects + /// A callback function to execute when the connection is restored + /// + var connection = this; + $(connection).bind(events.onReconnect, function (e, data) { + callback.call(connection); + }); + return connection; + }, + + stop: function (async, notifyServer) { + /// Stops listening + /// Whether or not to asynchronously abort the connection + /// Whether we want to notify the server that we are aborting the connection + /// + var connection = this, + // Save deferral because this is always cleaned up + deferral = connection._deferral; + + // Verify that we've bound a load event. + if (connection._.deferredStartHandler) { + // Unbind the event. + _pageWindow.unbind("load", connection._.deferredStartHandler); + } + + // Always clean up private non-timeout based state. + delete connection._.config; + delete connection._.deferredStartHandler; + + // This needs to be checked despite the connection state because a connection start can be deferred until page load. + // If we've deferred the start due to a page load we need to unbind the "onLoad" -> start event. + if (!_pageLoaded && (!connection._.config || connection._.config.waitForPageLoad === true)) { + connection.log("Stopping connection prior to negotiate."); + + // If we have a deferral we should reject it + if (deferral) { + deferral.reject(signalR._.error(resources.stoppedWhileLoading)); + } + + // Short-circuit because the start has not been fully started. + return; + } + + if (connection.state === signalR.connectionState.disconnected) { + return; + } + + connection.log("Stopping connection."); + + // Clear this no matter what + window.clearTimeout(connection._.beatHandle); + window.clearInterval(connection._.pingIntervalId); + + if (connection.transport) { + connection.transport.stop(connection); + + if (notifyServer !== false) { + connection.transport.abort(connection, async); + } + + if (supportsKeepAlive(connection)) { + signalR.transports._logic.stopMonitoringKeepAlive(connection); + } + + connection.transport = null; + } + + if (connection._.negotiateRequest) { + // If the negotiation request has already completed this will noop. + connection._.negotiateRequest.abort(_negotiateAbortText); + delete connection._.negotiateRequest; + } + + // Ensure that initHandler.stop() is called before connection._deferral is deleted + if (connection._.initHandler) { + connection._.initHandler.stop(); + } + + delete connection._deferral; + delete connection.messageId; + delete connection.groupsToken; + delete connection.id; + delete connection._.pingIntervalId; + delete connection._.lastMessageAt; + delete connection._.lastActiveAt; + + // Clear out our message buffer + connection._.connectingMessageBuffer.clear(); + + // Clean up this event + $(connection).unbind(events.onStart); + + // Trigger the disconnect event + changeState(connection, connection.state, signalR.connectionState.disconnected); + $(connection).triggerHandler(events.onDisconnect); + + return connection; + }, + + log: function (msg) { + log(msg, this.logging); + } + }; + + signalR.fn.init.prototype = signalR.fn; + + signalR.noConflict = function () { + /// Reinstates the original value of $.connection and returns the signalR object for manual assignment + /// + if ($.connection === signalR) { + $.connection = _connection; + } + return signalR; + }; + + if ($.connection) { + _connection = $.connection; + } + + $.connection = $.signalR = signalR; + +}(window.jQuery, window)); +/* jquery.signalR.transports.common.js */ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +/*global window:false */ +/// + +(function ($, window, undefined) { + + var signalR = $.signalR, + events = $.signalR.events, + changeState = $.signalR.changeState, + startAbortText = "__Start Aborted__", + transportLogic; + + signalR.transports = {}; + + function beat(connection) { + if (connection._.keepAliveData.monitoring) { + checkIfAlive(connection); + } + + // Ensure that we successfully marked active before continuing the heartbeat. + if (transportLogic.markActive(connection)) { + connection._.beatHandle = window.setTimeout(function () { + beat(connection); + }, connection._.beatInterval); + } + } + + function checkIfAlive(connection) { + var keepAliveData = connection._.keepAliveData, + timeElapsed; + + // Only check if we're connected + if (connection.state === signalR.connectionState.connected) { + timeElapsed = new Date().getTime() - connection._.lastMessageAt; + + // Check if the keep alive has completely timed out + if (timeElapsed >= keepAliveData.timeout) { + connection.log("Keep alive timed out. Notifying transport that connection has been lost."); + + // Notify transport that the connection has been lost + connection.transport.lostConnection(connection); + } else if (timeElapsed >= keepAliveData.timeoutWarning) { + // This is to assure that the user only gets a single warning + if (!keepAliveData.userNotified) { + connection.log("Keep alive has been missed, connection may be dead/slow."); + $(connection).triggerHandler(events.onConnectionSlow); + keepAliveData.userNotified = true; + } + } else { + keepAliveData.userNotified = false; + } + } + } + + function getAjaxUrl(connection, path) { + var url = connection.url + path; + + if (connection.transport) { + url += "?transport=" + connection.transport.name; + } + + return transportLogic.prepareQueryString(connection, url); + } + + function InitHandler(connection) { + this.connection = connection; + + this.startRequested = false; + this.startCompleted = false; + this.connectionStopped = false; + } + + InitHandler.prototype = { + start: function (transport, onSuccess, onFallback) { + var that = this, + connection = that.connection, + failCalled = false; + + if (that.startRequested || that.connectionStopped) { + connection.log("WARNING! " + transport.name + " transport cannot be started. Initialization ongoing or completed."); + return; + } + + connection.log(transport.name + " transport starting."); + + transport.start(connection, function () { + if (!failCalled) { + that.initReceived(transport, onSuccess); + } + }, function (error) { + // Don't allow the same transport to cause onFallback to be called twice + if (!failCalled) { + failCalled = true; + that.transportFailed(transport, error, onFallback); + } + + // Returns true if the transport should stop; + // false if it should attempt to reconnect + return !that.startCompleted || that.connectionStopped; + }); + + that.transportTimeoutHandle = window.setTimeout(function () { + if (!failCalled) { + failCalled = true; + connection.log(transport.name + " transport timed out when trying to connect."); + that.transportFailed(transport, undefined, onFallback); + } + }, connection._.totalTransportConnectTimeout); + }, + + stop: function () { + this.connectionStopped = true; + window.clearTimeout(this.transportTimeoutHandle); + signalR.transports._logic.tryAbortStartRequest(this.connection); + }, + + initReceived: function (transport, onSuccess) { + var that = this, + connection = that.connection; + + if (that.startRequested) { + connection.log("WARNING! The client received multiple init messages."); + return; + } + + if (that.connectionStopped) { + return; + } + + that.startRequested = true; + window.clearTimeout(that.transportTimeoutHandle); + + connection.log(transport.name + " transport connected. Initiating start request."); + signalR.transports._logic.ajaxStart(connection, function () { + that.startCompleted = true; + onSuccess(); + }); + }, + + transportFailed: function (transport, error, onFallback) { + var connection = this.connection, + deferred = connection._deferral, + wrappedError; + + if (this.connectionStopped) { + return; + } + + window.clearTimeout(this.transportTimeoutHandle); + + if (!this.startRequested) { + transport.stop(connection); + + connection.log(transport.name + " transport failed to connect. Attempting to fall back."); + onFallback(); + } else if (!this.startCompleted) { + // Do not attempt to fall back if a start request is ongoing during a transport failure. + // Instead, trigger an error and stop the connection. + wrappedError = signalR._.error(signalR.resources.errorDuringStartRequest, error); + + connection.log(transport.name + " transport failed during the start request. Stopping the connection."); + $(connection).triggerHandler(events.onError, [wrappedError]); + if (deferred) { + deferred.reject(wrappedError); + } + + connection.stop(); + } else { + // The start request has completed, but the connection has not stopped. + // No need to do anything here. The transport should attempt its normal reconnect logic. + } + } + }; + + transportLogic = signalR.transports._logic = { + ajax: function (connection, options) { + return $.ajax( + $.extend(/*deep copy*/ true, {}, $.signalR.ajaxDefaults, { + type: "GET", + data: {}, + xhrFields: { withCredentials: connection.withCredentials }, + contentType: connection.contentType, + dataType: connection.ajaxDataType + }, options)); + }, + + pingServer: function (connection) { + /// Pings the server + /// Connection associated with the server ping + /// + var url, + xhr, + deferral = $.Deferred(); + + if (connection.transport) { + url = connection.url + "/ping"; + + url = transportLogic.addQs(url, connection.qs); + + xhr = transportLogic.ajax(connection, { + url: url, + success: function (result) { + var data; + + try { + data = connection._parseResponse(result); + } + catch (error) { + deferral.reject( + signalR._.transportError( + signalR.resources.pingServerFailedParse, + connection.transport, + error, + xhr + ) + ); + connection.stop(); + return; + } + + if (data.Response === "pong") { + deferral.resolve(); + } + else { + deferral.reject( + signalR._.transportError( + signalR._.format(signalR.resources.pingServerFailedInvalidResponse, result), + connection.transport, + null /* error */, + xhr + ) + ); + } + }, + error: function (error) { + if (error.status === 401 || error.status === 403) { + deferral.reject( + signalR._.transportError( + signalR._.format(signalR.resources.pingServerFailedStatusCode, error.status), + connection.transport, + error, + xhr + ) + ); + connection.stop(); + } + else { + deferral.reject( + signalR._.transportError( + signalR.resources.pingServerFailed, + connection.transport, + error, + xhr + ) + ); + } + } + }); + } + else { + deferral.reject( + signalR._.transportError( + signalR.resources.noConnectionTransport, + connection.transport + ) + ); + } + + return deferral.promise(); + }, + + prepareQueryString: function (connection, url) { + var preparedUrl; + + // Use addQs to start since it handles the ?/& prefix for us + preparedUrl = transportLogic.addQs(url, "clientProtocol=" + connection.clientProtocol); + + // Add the user-specified query string params if any + preparedUrl = transportLogic.addQs(preparedUrl, connection.qs); + + if (connection.token) { + preparedUrl += "&connectionToken=" + window.encodeURIComponent(connection.token); + } + + if (connection.data) { + preparedUrl += "&connectionData=" + window.encodeURIComponent(connection.data); + } + + return preparedUrl; + }, + + addQs: function (url, qs) { + var appender = url.indexOf("?") !== -1 ? "&" : "?", + firstChar; + + if (!qs) { + return url; + } + + if (typeof (qs) === "object") { + return url + appender + $.param(qs); + } + + if (typeof (qs) === "string") { + firstChar = qs.charAt(0); + + if (firstChar === "?" || firstChar === "&") { + appender = ""; + } + + return url + appender + qs; + } + + throw new Error("Query string property must be either a string or object."); + }, + + // BUG #2953: The url needs to be same otherwise it will cause a memory leak + getUrl: function (connection, transport, reconnecting, poll, ajaxPost) { + /// Gets the url for making a GET based connect request + var baseUrl = transport === "webSockets" ? "" : connection.baseUrl, + url = baseUrl + connection.appRelativeUrl, + qs = "transport=" + transport; + + if (!ajaxPost && connection.groupsToken) { + qs += "&groupsToken=" + window.encodeURIComponent(connection.groupsToken); + } + + if (!reconnecting) { + url += "/connect"; + } else { + if (poll) { + // longPolling transport specific + url += "/poll"; + } else { + url += "/reconnect"; + } + + if (!ajaxPost && connection.messageId) { + qs += "&messageId=" + window.encodeURIComponent(connection.messageId); + } + } + url += "?" + qs; + url = transportLogic.prepareQueryString(connection, url); + + if (!ajaxPost) { + url += "&tid=" + Math.floor(Math.random() * 11); + } + + return url; + }, + + maximizePersistentResponse: function (minPersistentResponse) { + return { + MessageId: minPersistentResponse.C, + Messages: minPersistentResponse.M, + Initialized: typeof (minPersistentResponse.S) !== "undefined" ? true : false, + ShouldReconnect: typeof (minPersistentResponse.T) !== "undefined" ? true : false, + LongPollDelay: minPersistentResponse.L, + GroupsToken: minPersistentResponse.G + }; + }, + + updateGroups: function (connection, groupsToken) { + if (groupsToken) { + connection.groupsToken = groupsToken; + } + }, + + stringifySend: function (connection, message) { + if (typeof (message) === "string" || typeof (message) === "undefined" || message === null) { + return message; + } + return connection.json.stringify(message); + }, + + ajaxSend: function (connection, data) { + var payload = transportLogic.stringifySend(connection, data), + url = getAjaxUrl(connection, "/send"), + xhr, + onFail = function (error, connection) { + $(connection).triggerHandler(events.onError, [signalR._.transportError(signalR.resources.sendFailed, connection.transport, error, xhr), data]); + }; + + + xhr = transportLogic.ajax(connection, { + url: url, + type: connection.ajaxDataType === "jsonp" ? "GET" : "POST", + contentType: signalR._.defaultContentType, + data: { + data: payload + }, + success: function (result) { + var res; + + if (result) { + try { + res = connection._parseResponse(result); + } + catch (error) { + onFail(error, connection); + connection.stop(); + return; + } + + transportLogic.triggerReceived(connection, res); + } + }, + error: function (error, textStatus) { + if (textStatus === "abort" || textStatus === "parsererror") { + // The parsererror happens for sends that don't return any data, and hence + // don't write the jsonp callback to the response. This is harder to fix on the server + // so just hack around it on the client for now. + return; + } + + onFail(error, connection); + } + }); + + return xhr; + }, + + ajaxAbort: function (connection, async) { + if (typeof (connection.transport) === "undefined") { + return; + } + + // Async by default unless explicitly overidden + async = typeof async === "undefined" ? true : async; + + var url = getAjaxUrl(connection, "/abort"); + + transportLogic.ajax(connection, { + url: url, + async: async, + timeout: 1000, + type: "POST" + }); + + connection.log("Fired ajax abort async = " + async + "."); + }, + + ajaxStart: function (connection, onSuccess) { + var rejectDeferred = function (error) { + var deferred = connection._deferral; + if (deferred) { + deferred.reject(error); + } + }, + triggerStartError = function (error) { + connection.log("The start request failed. Stopping the connection."); + $(connection).triggerHandler(events.onError, [error]); + rejectDeferred(error); + connection.stop(); + }; + + connection._.startRequest = transportLogic.ajax(connection, { + url: getAjaxUrl(connection, "/start"), + success: function (result, statusText, xhr) { + var data; + + try { + data = connection._parseResponse(result); + } catch (error) { + triggerStartError(signalR._.error( + signalR._.format(signalR.resources.errorParsingStartResponse, result), + error, xhr)); + return; + } + + if (data.Response === "started") { + onSuccess(); + } else { + triggerStartError(signalR._.error( + signalR._.format(signalR.resources.invalidStartResponse, result), + null /* error */, xhr)); + } + }, + error: function (xhr, statusText, error) { + if (statusText !== startAbortText) { + triggerStartError(signalR._.error( + signalR.resources.errorDuringStartRequest, + error, xhr)); + } else { + // Stop has been called, no need to trigger the error handler + // or stop the connection again with onStartError + connection.log("The start request aborted because connection.stop() was called."); + rejectDeferred(signalR._.error( + signalR.resources.stoppedDuringStartRequest, + null /* error */, xhr)); + } + } + }); + }, + + tryAbortStartRequest: function (connection) { + if (connection._.startRequest) { + // If the start request has already completed this will noop. + connection._.startRequest.abort(startAbortText); + delete connection._.startRequest; + } + }, + + tryInitialize: function (connection, persistentResponse, onInitialized) { + if (persistentResponse.Initialized && onInitialized) { + onInitialized(); + } else if (persistentResponse.Initialized) { + connection.log("WARNING! The client received an init message after reconnecting."); + } + + }, + + triggerReceived: function (connection, data) { + if (!connection._.connectingMessageBuffer.tryBuffer(data)) { + $(connection).triggerHandler(events.onReceived, [data]); + } + }, + + processMessages: function (connection, minData, onInitialized) { + var data; + + // Update the last message time stamp + transportLogic.markLastMessage(connection); + + if (minData) { + data = transportLogic.maximizePersistentResponse(minData); + + transportLogic.updateGroups(connection, data.GroupsToken); + + if (data.MessageId) { + connection.messageId = data.MessageId; + } + + if (data.Messages) { + $.each(data.Messages, function (index, message) { + transportLogic.triggerReceived(connection, message); + }); + + transportLogic.tryInitialize(connection, data, onInitialized); + } + } + }, + + monitorKeepAlive: function (connection) { + var keepAliveData = connection._.keepAliveData; + + // If we haven't initiated the keep alive timeouts then we need to + if (!keepAliveData.monitoring) { + keepAliveData.monitoring = true; + + transportLogic.markLastMessage(connection); + + // Save the function so we can unbind it on stop + connection._.keepAliveData.reconnectKeepAliveUpdate = function () { + // Mark a new message so that keep alive doesn't time out connections + transportLogic.markLastMessage(connection); + }; + + // Update Keep alive on reconnect + $(connection).bind(events.onReconnect, connection._.keepAliveData.reconnectKeepAliveUpdate); + + connection.log("Now monitoring keep alive with a warning timeout of " + keepAliveData.timeoutWarning + ", keep alive timeout of " + keepAliveData.timeout + " and disconnecting timeout of " + connection.disconnectTimeout); + } else { + connection.log("Tried to monitor keep alive but it's already being monitored."); + } + }, + + stopMonitoringKeepAlive: function (connection) { + var keepAliveData = connection._.keepAliveData; + + // Only attempt to stop the keep alive monitoring if its being monitored + if (keepAliveData.monitoring) { + // Stop monitoring + keepAliveData.monitoring = false; + + // Remove the updateKeepAlive function from the reconnect event + $(connection).unbind(events.onReconnect, connection._.keepAliveData.reconnectKeepAliveUpdate); + + // Clear all the keep alive data + connection._.keepAliveData = {}; + connection.log("Stopping the monitoring of the keep alive."); + } + }, + + startHeartbeat: function (connection) { + connection._.lastActiveAt = new Date().getTime(); + beat(connection); + }, + + markLastMessage: function (connection) { + connection._.lastMessageAt = new Date().getTime(); + }, + + markActive: function (connection) { + if (transportLogic.verifyLastActive(connection)) { + connection._.lastActiveAt = new Date().getTime(); + return true; + } + + return false; + }, + + isConnectedOrReconnecting: function (connection) { + return connection.state === signalR.connectionState.connected || + connection.state === signalR.connectionState.reconnecting; + }, + + ensureReconnectingState: function (connection) { + if (changeState(connection, + signalR.connectionState.connected, + signalR.connectionState.reconnecting) === true) { + $(connection).triggerHandler(events.onReconnecting); + } + return connection.state === signalR.connectionState.reconnecting; + }, + + clearReconnectTimeout: function (connection) { + if (connection && connection._.reconnectTimeout) { + window.clearTimeout(connection._.reconnectTimeout); + delete connection._.reconnectTimeout; + } + }, + + verifyLastActive: function (connection) { + if (new Date().getTime() - connection._.lastActiveAt >= connection.reconnectWindow) { + var message = signalR._.format(signalR.resources.reconnectWindowTimeout, new Date(connection._.lastActiveAt), connection.reconnectWindow); + connection.log(message); + $(connection).triggerHandler(events.onError, [signalR._.error(message, /* source */ "TimeoutException")]); + connection.stop(/* async */ false, /* notifyServer */ false); + return false; + } + + return true; + }, + + reconnect: function (connection, transportName) { + var transport = signalR.transports[transportName]; + + // We should only set a reconnectTimeout if we are currently connected + // and a reconnectTimeout isn't already set. + if (transportLogic.isConnectedOrReconnecting(connection) && !connection._.reconnectTimeout) { + // Need to verify before the setTimeout occurs because an application sleep could occur during the setTimeout duration. + if (!transportLogic.verifyLastActive(connection)) { + return; + } + + connection._.reconnectTimeout = window.setTimeout(function () { + if (!transportLogic.verifyLastActive(connection)) { + return; + } + + transport.stop(connection); + + if (transportLogic.ensureReconnectingState(connection)) { + connection.log(transportName + " reconnecting."); + transport.start(connection); + } + }, connection.reconnectDelay); + } + }, + + handleParseFailure: function (connection, result, error, onFailed, context) { + var wrappedError = signalR._.transportError( + signalR._.format(signalR.resources.parseFailed, result), + connection.transport, + error, + context); + + // If we're in the initialization phase trigger onFailed, otherwise stop the connection. + if (onFailed && onFailed(wrappedError)) { + connection.log("Failed to parse server response while attempting to connect."); + } else { + $(connection).triggerHandler(events.onError, [wrappedError]); + connection.stop(); + } + }, + + initHandler: function (connection) { + return new InitHandler(connection); + }, + + foreverFrame: { + count: 0, + connections: {} + } + }; + +}(window.jQuery, window)); +/* jquery.signalR.transports.webSockets.js */ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + + +/*global window:false */ +/// + +(function ($, window, undefined) { + + var signalR = $.signalR, + events = $.signalR.events, + changeState = $.signalR.changeState, + transportLogic = signalR.transports._logic; + + signalR.transports.webSockets = { + name: "webSockets", + + supportsKeepAlive: function () { + return true; + }, + + send: function (connection, data) { + var payload = transportLogic.stringifySend(connection, data); + + try { + connection.socket.send(payload); + } catch (ex) { + $(connection).triggerHandler(events.onError, + [signalR._.transportError( + signalR.resources.webSocketsInvalidState, + connection.transport, + ex, + connection.socket + ), + data]); + } + }, + + start: function (connection, onSuccess, onFailed) { + var url, + opened = false, + that = this, + reconnecting = !onSuccess, + $connection = $(connection); + + if (!window.WebSocket) { + onFailed(); + return; + } + + if (!connection.socket) { + if (connection.webSocketServerUrl) { + url = connection.webSocketServerUrl; + } else { + url = connection.wsProtocol + connection.host; + } + + url += transportLogic.getUrl(connection, this.name, reconnecting); + + connection.log("Connecting to websocket endpoint '" + url + "'."); + connection.socket = new window.WebSocket(url); + + connection.socket.onopen = function () { + opened = true; + connection.log("Websocket opened."); + + transportLogic.clearReconnectTimeout(connection); + + if (changeState(connection, + signalR.connectionState.reconnecting, + signalR.connectionState.connected) === true) { + $connection.triggerHandler(events.onReconnect); + } + }; + + connection.socket.onclose = function (event) { + var error; + + // Only handle a socket close if the close is from the current socket. + // Sometimes on disconnect the server will push down an onclose event + // to an expired socket. + + if (this === connection.socket) { + if (opened && typeof event.wasClean !== "undefined" && event.wasClean === false) { + // Ideally this would use the websocket.onerror handler (rather than checking wasClean in onclose) but + // I found in some circumstances Chrome won't call onerror. This implementation seems to work on all browsers. + error = signalR._.transportError( + signalR.resources.webSocketClosed, + connection.transport, + event); + + connection.log("Unclean disconnect from websocket: " + (event.reason || "[no reason given].")); + } else { + connection.log("Websocket closed."); + } + + if (!onFailed || !onFailed(error)) { + if (error) { + $(connection).triggerHandler(events.onError, [error]); + } + + that.reconnect(connection); + } + } + }; + + connection.socket.onmessage = function (event) { + var data; + + try { + data = connection._parseResponse(event.data); + } + catch (error) { + transportLogic.handleParseFailure(connection, event.data, error, onFailed, event); + return; + } + + if (data) { + // data.M is PersistentResponse.Messages + if ($.isEmptyObject(data) || data.M) { + transportLogic.processMessages(connection, data, onSuccess); + } else { + // For websockets we need to trigger onReceived + // for callbacks to outgoing hub calls. + transportLogic.triggerReceived(connection, data); + } + } + }; + } + }, + + reconnect: function (connection) { + transportLogic.reconnect(connection, this.name); + }, + + lostConnection: function (connection) { + this.reconnect(connection); + }, + + stop: function (connection) { + // Don't trigger a reconnect after stopping + transportLogic.clearReconnectTimeout(connection); + + if (connection.socket) { + connection.log("Closing the Websocket."); + connection.socket.close(); + connection.socket = null; + } + }, + + abort: function (connection, async) { + transportLogic.ajaxAbort(connection, async); + } + }; + +}(window.jQuery, window)); +/* jquery.signalR.transports.serverSentEvents.js */ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + + +/*global window:false */ +/// + +(function ($, window, undefined) { + + var signalR = $.signalR, + events = $.signalR.events, + changeState = $.signalR.changeState, + transportLogic = signalR.transports._logic, + clearReconnectAttemptTimeout = function (connection) { + window.clearTimeout(connection._.reconnectAttemptTimeoutHandle); + delete connection._.reconnectAttemptTimeoutHandle; + }; + + signalR.transports.serverSentEvents = { + name: "serverSentEvents", + + supportsKeepAlive: function () { + return true; + }, + + timeOut: 3000, + + start: function (connection, onSuccess, onFailed) { + var that = this, + opened = false, + $connection = $(connection), + reconnecting = !onSuccess, + url; + + if (connection.eventSource) { + connection.log("The connection already has an event source. Stopping it."); + connection.stop(); + } + + if (!window.EventSource) { + if (onFailed) { + connection.log("This browser doesn't support SSE."); + onFailed(); + } + return; + } + + url = transportLogic.getUrl(connection, this.name, reconnecting); + + try { + connection.log("Attempting to connect to SSE endpoint '" + url + "'."); + connection.eventSource = new window.EventSource(url, { withCredentials: connection.withCredentials }); + } + catch (e) { + connection.log("EventSource failed trying to connect with error " + e.Message + "."); + if (onFailed) { + // The connection failed, call the failed callback + onFailed(); + } else { + $connection.triggerHandler(events.onError, [signalR._.transportError(signalR.resources.eventSourceFailedToConnect, connection.transport, e)]); + if (reconnecting) { + // If we were reconnecting, rather than doing initial connect, then try reconnect again + that.reconnect(connection); + } + } + return; + } + + if (reconnecting) { + connection._.reconnectAttemptTimeoutHandle = window.setTimeout(function () { + if (opened === false) { + // If we're reconnecting and the event source is attempting to connect, + // don't keep retrying. This causes duplicate connections to spawn. + if (connection.eventSource.readyState !== window.EventSource.OPEN) { + // If we were reconnecting, rather than doing initial connect, then try reconnect again + that.reconnect(connection); + } + } + }, + that.timeOut); + } + + connection.eventSource.addEventListener("open", function (e) { + connection.log("EventSource connected."); + + clearReconnectAttemptTimeout(connection); + transportLogic.clearReconnectTimeout(connection); + + if (opened === false) { + opened = true; + + if (changeState(connection, + signalR.connectionState.reconnecting, + signalR.connectionState.connected) === true) { + $connection.triggerHandler(events.onReconnect); + } + } + }, false); + + connection.eventSource.addEventListener("message", function (e) { + var res; + + // process messages + if (e.data === "initialized") { + return; + } + + try { + res = connection._parseResponse(e.data); + } + catch (error) { + transportLogic.handleParseFailure(connection, e.data, error, onFailed, e); + return; + } + + transportLogic.processMessages(connection, res, onSuccess); + }, false); + + connection.eventSource.addEventListener("error", function (e) { + var error = signalR._.transportError( + signalR.resources.eventSourceError, + connection.transport, + e); + + // Only handle an error if the error is from the current Event Source. + // Sometimes on disconnect the server will push down an error event + // to an expired Event Source. + if (this !== connection.eventSource) { + return; + } + + if (onFailed && onFailed(error)) { + return; + } + + connection.log("EventSource readyState: " + connection.eventSource.readyState + "."); + + if (e.eventPhase === window.EventSource.CLOSED) { + // We don't use the EventSource's native reconnect function as it + // doesn't allow us to change the URL when reconnecting. We need + // to change the URL to not include the /connect suffix, and pass + // the last message id we received. + connection.log("EventSource reconnecting due to the server connection ending."); + that.reconnect(connection); + } else { + // connection error + connection.log("EventSource error."); + $connection.triggerHandler(events.onError, [error]); + } + }, false); + }, + + reconnect: function (connection) { + transportLogic.reconnect(connection, this.name); + }, + + lostConnection: function (connection) { + this.reconnect(connection); + }, + + send: function (connection, data) { + transportLogic.ajaxSend(connection, data); + }, + + stop: function (connection) { + // Don't trigger a reconnect after stopping + clearReconnectAttemptTimeout(connection); + transportLogic.clearReconnectTimeout(connection); + + if (connection && connection.eventSource) { + connection.log("EventSource calling close()."); + connection.eventSource.close(); + connection.eventSource = null; + delete connection.eventSource; + } + }, + + abort: function (connection, async) { + transportLogic.ajaxAbort(connection, async); + } + }; + +}(window.jQuery, window)); +/* jquery.signalR.transports.foreverFrame.js */ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + + +/*global window:false */ +/// + +(function ($, window, undefined) { + + var signalR = $.signalR, + events = $.signalR.events, + changeState = $.signalR.changeState, + transportLogic = signalR.transports._logic, + createFrame = function () { + var frame = window.document.createElement("iframe"); + frame.setAttribute("style", "position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;"); + return frame; + }, + // Used to prevent infinite loading icon spins in older versions of ie + // We build this object inside a closure so we don't pollute the rest of + // the foreverFrame transport with unnecessary functions/utilities. + loadPreventer = (function () { + var loadingFixIntervalId = null, + loadingFixInterval = 1000, + attachedTo = 0; + + return { + prevent: function () { + // Prevent additional iframe removal procedures from newer browsers + if (signalR._.ieVersion <= 8) { + // We only ever want to set the interval one time, so on the first attachedTo + if (attachedTo === 0) { + // Create and destroy iframe every 3 seconds to prevent loading icon, super hacky + loadingFixIntervalId = window.setInterval(function () { + var tempFrame = createFrame(); + + window.document.body.appendChild(tempFrame); + window.document.body.removeChild(tempFrame); + + tempFrame = null; + }, loadingFixInterval); + } + + attachedTo++; + } + }, + cancel: function () { + // Only clear the interval if there's only one more object that the loadPreventer is attachedTo + if (attachedTo === 1) { + window.clearInterval(loadingFixIntervalId); + } + + if (attachedTo > 0) { + attachedTo--; + } + } + }; + })(); + + signalR.transports.foreverFrame = { + name: "foreverFrame", + + supportsKeepAlive: function () { + return true; + }, + + // Added as a value here so we can create tests to verify functionality + iframeClearThreshold: 50, + + start: function (connection, onSuccess, onFailed) { + var that = this, + frameId = (transportLogic.foreverFrame.count += 1), + url, + frame = createFrame(), + frameLoadHandler = function () { + connection.log("Forever frame iframe finished loading and is no longer receiving messages."); + if (!onFailed || !onFailed()) { + that.reconnect(connection); + } + }; + + if (window.EventSource) { + // If the browser supports SSE, don't use Forever Frame + if (onFailed) { + connection.log("Forever Frame is not supported by SignalR on browsers with SSE support."); + onFailed(); + } + return; + } + + frame.setAttribute("data-signalr-connection-id", connection.id); + + // Start preventing loading icon + // This will only perform work if the loadPreventer is not attached to another connection. + loadPreventer.prevent(); + + // Build the url + url = transportLogic.getUrl(connection, this.name); + url += "&frameId=" + frameId; + + // add frame to the document prior to setting URL to avoid caching issues. + window.document.documentElement.appendChild(frame); + + connection.log("Binding to iframe's load event."); + + if (frame.addEventListener) { + frame.addEventListener("load", frameLoadHandler, false); + } else if (frame.attachEvent) { + frame.attachEvent("onload", frameLoadHandler); + } + + frame.src = url; + transportLogic.foreverFrame.connections[frameId] = connection; + + connection.frame = frame; + connection.frameId = frameId; + + if (onSuccess) { + connection.onSuccess = function () { + connection.log("Iframe transport started."); + onSuccess(); + }; + } + }, + + reconnect: function (connection) { + var that = this; + + // Need to verify connection state and verify before the setTimeout occurs because an application sleep could occur during the setTimeout duration. + if (transportLogic.isConnectedOrReconnecting(connection) && transportLogic.verifyLastActive(connection)) { + window.setTimeout(function () { + // Verify that we're ok to reconnect. + if (!transportLogic.verifyLastActive(connection)) { + return; + } + + if (connection.frame && transportLogic.ensureReconnectingState(connection)) { + var frame = connection.frame, + src = transportLogic.getUrl(connection, that.name, true) + "&frameId=" + connection.frameId; + connection.log("Updating iframe src to '" + src + "'."); + frame.src = src; + } + }, connection.reconnectDelay); + } + }, + + lostConnection: function (connection) { + this.reconnect(connection); + }, + + send: function (connection, data) { + transportLogic.ajaxSend(connection, data); + }, + + receive: function (connection, data) { + var cw, + body, + response; + + if (connection.json !== connection._originalJson) { + // If there's a custom JSON parser configured then serialize the object + // using the original (browser) JSON parser and then deserialize it using + // the custom parser (connection._parseResponse does that). This is so we + // can easily send the response from the server as "raw" JSON but still + // support custom JSON deserialization in the browser. + data = connection._originalJson.stringify(data); + } + + response = connection._parseResponse(data); + + transportLogic.processMessages(connection, response, connection.onSuccess); + + // Protect against connection stopping from a callback trigger within the processMessages above. + if (connection.state === $.signalR.connectionState.connected) { + // Delete the script & div elements + connection.frameMessageCount = (connection.frameMessageCount || 0) + 1; + if (connection.frameMessageCount > signalR.transports.foreverFrame.iframeClearThreshold) { + connection.frameMessageCount = 0; + cw = connection.frame.contentWindow || connection.frame.contentDocument; + if (cw && cw.document && cw.document.body) { + body = cw.document.body; + + // Remove all the child elements from the iframe's body to conserver memory + while (body.firstChild) { + body.removeChild(body.firstChild); + } + } + } + } + }, + + stop: function (connection) { + var cw = null; + + // Stop attempting to prevent loading icon + loadPreventer.cancel(); + + if (connection.frame) { + if (connection.frame.stop) { + connection.frame.stop(); + } else { + try { + cw = connection.frame.contentWindow || connection.frame.contentDocument; + if (cw.document && cw.document.execCommand) { + cw.document.execCommand("Stop"); + } + } + catch (e) { + connection.log("Error occurred when stopping foreverFrame transport. Message = " + e.message + "."); + } + } + + // Ensure the iframe is where we left it + if (connection.frame.parentNode === window.document.documentElement) { + window.document.documentElement.removeChild(connection.frame); + } + + delete transportLogic.foreverFrame.connections[connection.frameId]; + connection.frame = null; + connection.frameId = null; + delete connection.frame; + delete connection.frameId; + delete connection.onSuccess; + delete connection.frameMessageCount; + connection.log("Stopping forever frame."); + } + }, + + abort: function (connection, async) { + transportLogic.ajaxAbort(connection, async); + }, + + getConnection: function (id) { + return transportLogic.foreverFrame.connections[id]; + }, + + started: function (connection) { + if (changeState(connection, + signalR.connectionState.reconnecting, + signalR.connectionState.connected) === true) { + + $(connection).triggerHandler(events.onReconnect); + } + } + }; + +}(window.jQuery, window)); +/* jquery.signalR.transports.longPolling.js */ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + + +/*global window:false */ +/// + +(function ($, window, undefined) { + + var signalR = $.signalR, + events = $.signalR.events, + changeState = $.signalR.changeState, + isDisconnecting = $.signalR.isDisconnecting, + transportLogic = signalR.transports._logic; + + signalR.transports.longPolling = { + name: "longPolling", + + supportsKeepAlive: function () { + return false; + }, + + reconnectDelay: 3000, + + start: function (connection, onSuccess, onFailed) { + /// Starts the long polling connection + /// The SignalR connection to start + var that = this, + fireConnect = function () { + fireConnect = $.noop; + + connection.log("LongPolling connected."); + + if (onSuccess) { + onSuccess(); + } else { + connection.log("WARNING! The client received an init message after reconnecting."); + } + }, + tryFailConnect = function (error) { + if (onFailed(error)) { + connection.log("LongPolling failed to connect."); + return true; + } + + return false; + }, + privateData = connection._, + reconnectErrors = 0, + fireReconnected = function (instance) { + window.clearTimeout(privateData.reconnectTimeoutId); + privateData.reconnectTimeoutId = null; + + if (changeState(instance, + signalR.connectionState.reconnecting, + signalR.connectionState.connected) === true) { + // Successfully reconnected! + instance.log("Raising the reconnect event"); + $(instance).triggerHandler(events.onReconnect); + } + }, + // 1 hour + maxFireReconnectedTimeout = 3600000; + + if (connection.pollXhr) { + connection.log("Polling xhr requests already exists, aborting."); + connection.stop(); + } + + connection.messageId = null; + + privateData.reconnectTimeoutId = null; + + privateData.pollTimeoutId = window.setTimeout(function () { + (function poll(instance, raiseReconnect) { + var messageId = instance.messageId, + connect = (messageId === null), + reconnecting = !connect, + polling = !raiseReconnect, + url = transportLogic.getUrl(instance, that.name, reconnecting, polling, true /* use Post for longPolling */), + postData = {}; + + if (instance.messageId) { + postData.messageId = instance.messageId; + } + + if (instance.groupsToken) { + postData.groupsToken = instance.groupsToken; + } + + // If we've disconnected during the time we've tried to re-instantiate the poll then stop. + if (isDisconnecting(instance) === true) { + return; + } + + connection.log("Opening long polling request to '" + url + "'."); + instance.pollXhr = transportLogic.ajax(connection, { + xhrFields: { + onprogress: function () { + transportLogic.markLastMessage(connection); + } + }, + url: url, + type: "POST", + contentType: signalR._.defaultContentType, + data: postData, + timeout: connection._.pollTimeout, + success: function (result) { + var minData, + delay = 0, + data, + shouldReconnect; + + connection.log("Long poll complete."); + + // Reset our reconnect errors so if we transition into a reconnecting state again we trigger + // reconnected quickly + reconnectErrors = 0; + + try { + // Remove any keep-alives from the beginning of the result + minData = connection._parseResponse(result); + } + catch (error) { + transportLogic.handleParseFailure(instance, result, error, tryFailConnect, instance.pollXhr); + return; + } + + // If there's currently a timeout to trigger reconnect, fire it now before processing messages + if (privateData.reconnectTimeoutId !== null) { + fireReconnected(instance); + } + + if (minData) { + data = transportLogic.maximizePersistentResponse(minData); + } + + transportLogic.processMessages(instance, minData, fireConnect); + + if (data && + $.type(data.LongPollDelay) === "number") { + delay = data.LongPollDelay; + } + + if (isDisconnecting(instance) === true) { + return; + } + + shouldReconnect = data && data.ShouldReconnect; + if (shouldReconnect) { + // Transition into the reconnecting state + // If this fails then that means that the user transitioned the connection into a invalid state in processMessages. + if (!transportLogic.ensureReconnectingState(instance)) { + return; + } + } + + // We never want to pass a raiseReconnect flag after a successful poll. This is handled via the error function + if (delay > 0) { + privateData.pollTimeoutId = window.setTimeout(function () { + poll(instance, shouldReconnect); + }, delay); + } else { + poll(instance, shouldReconnect); + } + }, + + error: function (data, textStatus) { + var error = signalR._.transportError(signalR.resources.longPollFailed, connection.transport, data, instance.pollXhr); + + // Stop trying to trigger reconnect, connection is in an error state + // If we're not in the reconnect state this will noop + window.clearTimeout(privateData.reconnectTimeoutId); + privateData.reconnectTimeoutId = null; + + if (textStatus === "abort") { + connection.log("Aborted xhr request."); + return; + } + + if (!tryFailConnect(error)) { + + // Increment our reconnect errors, we assume all errors to be reconnect errors + // In the case that it's our first error this will cause Reconnect to be fired + // after 1 second due to reconnectErrors being = 1. + reconnectErrors++; + + if (connection.state !== signalR.connectionState.reconnecting) { + connection.log("An error occurred using longPolling. Status = " + textStatus + ". Response = " + data.responseText + "."); + $(instance).triggerHandler(events.onError, [error]); + } + + // We check the state here to verify that we're not in an invalid state prior to verifying Reconnect. + // If we're not in connected or reconnecting then the next ensureReconnectingState check will fail and will return. + // Therefore we don't want to change that failure code path. + if ((connection.state === signalR.connectionState.connected || + connection.state === signalR.connectionState.reconnecting) && + !transportLogic.verifyLastActive(connection)) { + return; + } + + // Transition into the reconnecting state + // If this fails then that means that the user transitioned the connection into the disconnected or connecting state within the above error handler trigger. + if (!transportLogic.ensureReconnectingState(instance)) { + return; + } + + // Call poll with the raiseReconnect flag as true after the reconnect delay + privateData.pollTimeoutId = window.setTimeout(function () { + poll(instance, true); + }, that.reconnectDelay); + } + } + }); + + // This will only ever pass after an error has occurred via the poll ajax procedure. + if (reconnecting && raiseReconnect === true) { + // We wait to reconnect depending on how many times we've failed to reconnect. + // This is essentially a heuristic that will exponentially increase in wait time before + // triggering reconnected. This depends on the "error" handler of Poll to cancel this + // timeout if it triggers before the Reconnected event fires. + // The Math.min at the end is to ensure that the reconnect timeout does not overflow. + privateData.reconnectTimeoutId = window.setTimeout(function () { fireReconnected(instance); }, Math.min(1000 * (Math.pow(2, reconnectErrors) - 1), maxFireReconnectedTimeout)); + } + }(connection)); + }, 250); // Have to delay initial poll so Chrome doesn't show loader spinner in tab + }, + + lostConnection: function (connection) { + if (connection.pollXhr) { + connection.pollXhr.abort("lostConnection"); + } + }, + + send: function (connection, data) { + transportLogic.ajaxSend(connection, data); + }, + + stop: function (connection) { + /// Stops the long polling connection + /// The SignalR connection to stop + + window.clearTimeout(connection._.pollTimeoutId); + window.clearTimeout(connection._.reconnectTimeoutId); + + delete connection._.pollTimeoutId; + delete connection._.reconnectTimeoutId; + + if (connection.pollXhr) { + connection.pollXhr.abort(); + connection.pollXhr = null; + delete connection.pollXhr; + } + }, + + abort: function (connection, async) { + transportLogic.ajaxAbort(connection, async); + } + }; + +}(window.jQuery, window)); +/* jquery.signalR.hubs.js */ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + +/*global window:false */ +/// + +(function ($, window, undefined) { + + var eventNamespace = ".hubProxy", + signalR = $.signalR; + + function makeEventName(event) { + return event + eventNamespace; + } + + // Equivalent to Array.prototype.map + function map(arr, fun, thisp) { + var i, + length = arr.length, + result = []; + for (i = 0; i < length; i += 1) { + if (arr.hasOwnProperty(i)) { + result[i] = fun.call(thisp, arr[i], i, arr); + } + } + return result; + } + + function getArgValue(a) { + return $.isFunction(a) ? null : ($.type(a) === "undefined" ? null : a); + } + + function hasMembers(obj) { + for (var key in obj) { + // If we have any properties in our callback map then we have callbacks and can exit the loop via return + if (obj.hasOwnProperty(key)) { + return true; + } + } + + return false; + } + + function clearInvocationCallbacks(connection, error) { + /// + var callbacks = connection._.invocationCallbacks, + callback; + + if (hasMembers(callbacks)) { + connection.log("Clearing hub invocation callbacks with error: " + error + "."); + } + + // Reset the callback cache now as we have a local var referencing it + connection._.invocationCallbackId = 0; + delete connection._.invocationCallbacks; + connection._.invocationCallbacks = {}; + + // Loop over the callbacks and invoke them. + // We do this using a local var reference and *after* we've cleared the cache + // so that if a fail callback itself tries to invoke another method we don't + // end up with its callback in the list we're looping over. + for (var callbackId in callbacks) { + callback = callbacks[callbackId]; + callback.method.call(callback.scope, { E: error }); + } + } + + // hubProxy + function hubProxy(hubConnection, hubName) { + /// + /// Creates a new proxy object for the given hub connection that can be used to invoke + /// methods on server hubs and handle client method invocation requests from the server. + /// + return new hubProxy.fn.init(hubConnection, hubName); + } + + hubProxy.fn = hubProxy.prototype = { + init: function (connection, hubName) { + this.state = {}; + this.connection = connection; + this.hubName = hubName; + this._ = { + callbackMap: {} + }; + }, + + constructor: hubProxy, + + hasSubscriptions: function () { + return hasMembers(this._.callbackMap); + }, + + on: function (eventName, callback) { + /// Wires up a callback to be invoked when a invocation request is received from the server hub. + /// The name of the hub event to register the callback for. + /// The callback to be invoked. + var that = this, + callbackMap = that._.callbackMap; + + // Normalize the event name to lowercase + eventName = eventName.toLowerCase(); + + // If there is not an event registered for this callback yet we want to create its event space in the callback map. + if (!callbackMap[eventName]) { + callbackMap[eventName] = {}; + } + + // Map the callback to our encompassed function + callbackMap[eventName][callback] = function (e, data) { + callback.apply(that, data); + }; + + $(that).bind(makeEventName(eventName), callbackMap[eventName][callback]); + + return that; + }, + + off: function (eventName, callback) { + /// Removes the callback invocation request from the server hub for the given event name. + /// The name of the hub event to unregister the callback for. + /// The callback to be invoked. + var that = this, + callbackMap = that._.callbackMap, + callbackSpace; + + // Normalize the event name to lowercase + eventName = eventName.toLowerCase(); + + callbackSpace = callbackMap[eventName]; + + // Verify that there is an event space to unbind + if (callbackSpace) { + // Only unbind if there's an event bound with eventName and a callback with the specified callback + if (callbackSpace[callback]) { + $(that).unbind(makeEventName(eventName), callbackSpace[callback]); + + // Remove the callback from the callback map + delete callbackSpace[callback]; + + // Check if there are any members left on the event, if not we need to destroy it. + if (!hasMembers(callbackSpace)) { + delete callbackMap[eventName]; + } + } else if (!callback) { // Check if we're removing the whole event and we didn't error because of an invalid callback + $(that).unbind(makeEventName(eventName)); + + delete callbackMap[eventName]; + } + } + + return that; + }, + + invoke: function (methodName) { + /// Invokes a server hub method with the given arguments. + /// The name of the server hub method. + + var that = this, + connection = that.connection, + args = $.makeArray(arguments).slice(1), + argValues = map(args, getArgValue), + data = { H: that.hubName, M: methodName, A: argValues, I: connection._.invocationCallbackId }, + d = $.Deferred(), + callback = function (minResult) { + var result = that._maximizeHubResponse(minResult), + source, + error; + + // Update the hub state + $.extend(that.state, result.State); + + if (result.Progress) { + if (d.notifyWith) { + // Progress is only supported in jQuery 1.7+ + d.notifyWith(that, [result.Progress.Data]); + } else if(!connection._.progressjQueryVersionLogged) { + connection.log("A hub method invocation progress update was received but the version of jQuery in use (" + $.prototype.jquery + ") does not support progress updates. Upgrade to jQuery 1.7+ to receive progress notifications."); + connection._.progressjQueryVersionLogged = true; + } + } else if (result.Error) { + // Server hub method threw an exception, log it & reject the deferred + if (result.StackTrace) { + connection.log(result.Error + "\n" + result.StackTrace + "."); + } + + // result.ErrorData is only set if a HubException was thrown + source = result.IsHubException ? "HubException" : "Exception"; + error = signalR._.error(result.Error, source); + error.data = result.ErrorData; + + connection.log(that.hubName + "." + methodName + " failed to execute. Error: " + error.message); + d.rejectWith(that, [error]); + } else { + // Server invocation succeeded, resolve the deferred + connection.log("Invoked " + that.hubName + "." + methodName); + d.resolveWith(that, [result.Result]); + } + }; + + connection._.invocationCallbacks[connection._.invocationCallbackId.toString()] = { scope: that, method: callback }; + connection._.invocationCallbackId += 1; + + if (!$.isEmptyObject(that.state)) { + data.S = that.state; + } + + connection.log("Invoking " + that.hubName + "." + methodName); + connection.send(data); + + return d.promise(); + }, + + _maximizeHubResponse: function (minHubResponse) { + return { + State: minHubResponse.S, + Result: minHubResponse.R, + Progress: minHubResponse.P ? { + Id: minHubResponse.P.I, + Data: minHubResponse.P.D + } : null, + Id: minHubResponse.I, + IsHubException: minHubResponse.H, + Error: minHubResponse.E, + StackTrace: minHubResponse.T, + ErrorData: minHubResponse.D + }; + } + }; + + hubProxy.fn.init.prototype = hubProxy.fn; + + // hubConnection + function hubConnection(url, options) { + /// Creates a new hub connection. + /// [Optional] The hub route url, defaults to "/signalr". + /// [Optional] Settings to use when creating the hubConnection. + var settings = { + qs: null, + logging: false, + useDefaultPath: true + }; + + $.extend(settings, options); + + if (!url || settings.useDefaultPath) { + url = (url || "") + "/signalr"; + } + return new hubConnection.fn.init(url, settings); + } + + hubConnection.fn = hubConnection.prototype = $.connection(); + + hubConnection.fn.init = function (url, options) { + var settings = { + qs: null, + logging: false, + useDefaultPath: true + }, + connection = this; + + $.extend(settings, options); + + // Call the base constructor + $.signalR.fn.init.call(connection, url, settings.qs, settings.logging); + + // Object to store hub proxies for this connection + connection.proxies = {}; + + connection._.invocationCallbackId = 0; + connection._.invocationCallbacks = {}; + + // Wire up the received handler + connection.received(function (minData) { + var data, proxy, dataCallbackId, callback, hubName, eventName; + if (!minData) { + return; + } + + // We have to handle progress updates first in order to ensure old clients that receive + // progress updates enter the return value branch and then no-op when they can't find + // the callback in the map (because the minData.I value will not be a valid callback ID) + if (typeof (minData.P) !== "undefined") { + // Process progress notification + dataCallbackId = minData.P.I.toString(); + callback = connection._.invocationCallbacks[dataCallbackId]; + if (callback) { + callback.method.call(callback.scope, minData); + } + } else if (typeof (minData.I) !== "undefined") { + // We received the return value from a server method invocation, look up callback by id and call it + dataCallbackId = minData.I.toString(); + callback = connection._.invocationCallbacks[dataCallbackId]; + if (callback) { + // Delete the callback from the proxy + connection._.invocationCallbacks[dataCallbackId] = null; + delete connection._.invocationCallbacks[dataCallbackId]; + + // Invoke the callback + callback.method.call(callback.scope, minData); + } + } else { + data = this._maximizeClientHubInvocation(minData); + + // We received a client invocation request, i.e. broadcast from server hub + connection.log("Triggering client hub event '" + data.Method + "' on hub '" + data.Hub + "'."); + + // Normalize the names to lowercase + hubName = data.Hub.toLowerCase(); + eventName = data.Method.toLowerCase(); + + // Trigger the local invocation event + proxy = this.proxies[hubName]; + + // Update the hub state + $.extend(proxy.state, data.State); + $(proxy).triggerHandler(makeEventName(eventName), [data.Args]); + } + }); + + connection.error(function (errData, origData) { + var callbackId, callback; + + if (!origData) { + // No original data passed so this is not a send error + return; + } + + callbackId = origData.I; + callback = connection._.invocationCallbacks[callbackId]; + + // Verify that there is a callback bound (could have been cleared) + if (callback) { + // Delete the callback + connection._.invocationCallbacks[callbackId] = null; + delete connection._.invocationCallbacks[callbackId]; + + // Invoke the callback with an error to reject the promise + callback.method.call(callback.scope, { E: errData }); + } + }); + + connection.reconnecting(function () { + if (connection.transport && connection.transport.name === "webSockets") { + clearInvocationCallbacks(connection, "Connection started reconnecting before invocation result was received."); + } + }); + + connection.disconnected(function () { + clearInvocationCallbacks(connection, "Connection was disconnected before invocation result was received."); + }); + }; + + hubConnection.fn._maximizeClientHubInvocation = function (minClientHubInvocation) { + return { + Hub: minClientHubInvocation.H, + Method: minClientHubInvocation.M, + Args: minClientHubInvocation.A, + State: minClientHubInvocation.S + }; + }; + + hubConnection.fn._registerSubscribedHubs = function () { + /// + /// Sets the starting event to loop through the known hubs and register any new hubs + /// that have been added to the proxy. + /// + var connection = this; + + if (!connection._subscribedToHubs) { + connection._subscribedToHubs = true; + connection.starting(function () { + // Set the connection's data object with all the hub proxies with active subscriptions. + // These proxies will receive notifications from the server. + var subscribedHubs = []; + + $.each(connection.proxies, function (key) { + if (this.hasSubscriptions()) { + subscribedHubs.push({ name: key }); + connection.log("Client subscribed to hub '" + key + "'."); + } + }); + + if (subscribedHubs.length === 0) { + connection.log("No hubs have been subscribed to. The client will not receive data from hubs. To fix, declare at least one client side function prior to connection start for each hub you wish to subscribe to."); + } + + connection.data = connection.json.stringify(subscribedHubs); + }); + } + }; + + hubConnection.fn.createHubProxy = function (hubName) { + /// + /// Creates a new proxy object for the given hub connection that can be used to invoke + /// methods on server hubs and handle client method invocation requests from the server. + /// + /// + /// The name of the hub on the server to create the proxy for. + /// + + // Normalize the name to lowercase + hubName = hubName.toLowerCase(); + + var proxy = this.proxies[hubName]; + if (!proxy) { + proxy = hubProxy(this, hubName); + this.proxies[hubName] = proxy; + } + + this._registerSubscribedHubs(); + + return proxy; + }; + + hubConnection.fn.init.prototype = hubConnection.fn; + + $.hubConnection = hubConnection; + +}(window.jQuery, window)); +/* jquery.signalR.version.js */ +// Copyright (c) .NET Foundation. All rights reserved. +// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + + +/*global window:false */ +/// +(function ($, undefined) { + $.signalR.version = "2.3.0"; +}(window.jQuery)); diff --git a/net452/SiteServer.Web/SiteServer/assets/signalR/jquery.signalR-2.3.0.min.js b/net452/SiteServer.Web/SiteServer/assets/signalR/jquery.signalR-2.3.0.min.js new file mode 100644 index 000000000..069a8068a --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/signalR/jquery.signalR-2.3.0.min.js @@ -0,0 +1,9 @@ +/*! + * ASP.NET SignalR JavaScript Library v2.3.0 + * http://signalr.net/ + * + * Copyright (c) .NET Foundation. All rights reserved. + * Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. + * + */ +(function(n,t,i){function w(t,i){var u,f;if(n.isArray(t)){for(u=t.length-1;u>=0;u--)f=t[u],n.type(f)==="string"&&r.transports[f]||(i.log("Invalid transport: "+f+", removing it from the transports list."),t.splice(u,1));t.length===0&&(i.log("No transports remain within the specified transport array."),t=null)}else if(r.transports[t]||t==="auto"){if(t==="auto"&&r._.ieVersion<=8)return["longPolling"]}else i.log("Invalid transport: "+t.toString()+"."),t=null;return t}function b(n){return n==="http:"?80:n==="https:"?443:void 0}function a(n,t){return t.match(/:\d+$/)?t:t+":"+b(n)}function k(t,i){var u=this,r=[];u.tryBuffer=function(i){return t.state===n.signalR.connectionState.connecting?(r.push(i),!0):!1};u.drain=function(){if(t.state===n.signalR.connectionState.connected)while(r.length>0)i(r.shift())};u.clear=function(){r=[]}}var f={nojQuery:"jQuery was not found. Please ensure jQuery is referenced before the SignalR client JavaScript file.",noTransportOnInit:"No transport could be initialized successfully. Try specifying a different transport or none at all for auto initialization.",errorOnNegotiate:"Error during negotiation request.",stoppedWhileLoading:"The connection was stopped during page load.",stoppedWhileNegotiating:"The connection was stopped during the negotiate request.",errorParsingNegotiateResponse:"Error parsing negotiate response.",errorDuringStartRequest:"Error during start request. Stopping the connection.",stoppedDuringStartRequest:"The connection was stopped during the start request.",errorParsingStartResponse:"Error parsing start response: '{0}'. Stopping the connection.",invalidStartResponse:"Invalid start response: '{0}'. Stopping the connection.",protocolIncompatible:"You are using a version of the client that isn't compatible with the server. Client version {0}, server version {1}.",sendFailed:"Send failed.",parseFailed:"Failed at parsing response: {0}",longPollFailed:"Long polling request failed.",eventSourceFailedToConnect:"EventSource failed to connect.",eventSourceError:"Error raised by EventSource",webSocketClosed:"WebSocket closed.",pingServerFailedInvalidResponse:"Invalid ping response when pinging server: '{0}'.",pingServerFailed:"Failed to ping server.",pingServerFailedStatusCode:"Failed to ping server. Server responded with status code {0}, stopping the connection.",pingServerFailedParse:"Failed to parse ping server response, stopping the connection.",noConnectionTransport:"Connection is in an invalid state, there is no transport active.",webSocketsInvalidState:"The Web Socket transport is in an invalid state, transitioning into reconnecting.",reconnectTimeout:"Couldn't reconnect within the configured timeout of {0} ms, disconnecting.",reconnectWindowTimeout:"The client has been inactive since {0} and it has exceeded the inactivity timeout of {1} ms. Stopping the connection."};if(typeof n!="function")throw new Error(f.nojQuery);var r,h,o=t.document.readyState==="complete",e=n(t),c="__Negotiate Aborted__",u={onStart:"onStart",onStarting:"onStarting",onReceived:"onReceived",onError:"onError",onConnectionSlow:"onConnectionSlow",onReconnecting:"onReconnecting",onReconnect:"onReconnect",onStateChanged:"onStateChanged",onDisconnect:"onDisconnect"},v=function(n,i){if(i!==!1){var r;typeof t.console!="undefined"&&(r="["+(new Date).toTimeString()+"] SignalR: "+n,t.console.debug?t.console.debug(r):t.console.log&&t.console.log(r))}},s=function(t,i,r){return i===t.state?(t.state=r,n(t).triggerHandler(u.onStateChanged,[{oldState:i,newState:r}]),!0):!1},y=function(n){return n.state===r.connectionState.disconnected},l=function(n){return n._.keepAliveData.activated&&n.transport.supportsKeepAlive(n)},p=function(i){var f,e;i._.configuredStopReconnectingTimeout||(e=function(t){var i=r._.format(r.resources.reconnectTimeout,t.disconnectTimeout);t.log(i);n(t).triggerHandler(u.onError,[r._.error(i,"TimeoutException")]);t.stop(!1,!1)},i.reconnecting(function(){var n=this;n.state===r.connectionState.reconnecting&&(f=t.setTimeout(function(){e(n)},n.disconnectTimeout))}),i.stateChanged(function(n){n.oldState===r.connectionState.reconnecting&&t.clearTimeout(f)}),i._.configuredStopReconnectingTimeout=!0)};if(r=function(n,t,i){return new r.fn.init(n,t,i)},r._={defaultContentType:"application/x-www-form-urlencoded; charset=UTF-8",ieVersion:function(){var i,n;return t.navigator.appName==="Microsoft Internet Explorer"&&(n=/MSIE ([0-9]+\.[0-9]+)/.exec(t.navigator.userAgent),n&&(i=t.parseFloat(n[1]))),i}(),error:function(n,t,i){var r=new Error(n);return r.source=t,typeof i!="undefined"&&(r.context=i),r},transportError:function(n,t,r,u){var f=this.error(n,r,u);return f.transport=t?t.name:i,f},format:function(){for(var t=arguments[0],n=0;n<\/script>.");}},typeof e.on=="function")e.on("load",function(){o=!0});else e.load(function(){o=!0});r.fn=r.prototype={init:function(t,i,r){var f=n(this);this.url=t;this.qs=i;this.lastError=null;this._={keepAliveData:{},connectingMessageBuffer:new k(this,function(n){f.triggerHandler(u.onReceived,[n])}),lastMessageAt:(new Date).getTime(),lastActiveAt:(new Date).getTime(),beatInterval:5e3,beatHandle:null,totalTransportConnectTimeout:0};typeof r=="boolean"&&(this.logging=r)},_parseResponse:function(n){var t=this;return n?typeof n=="string"?t.json.parse(n):n:n},_originalJson:t.JSON,json:t.JSON,isCrossDomain:function(i,r){var u;return(i=n.trim(i),r=r||t.location,i.indexOf("http")!==0)?!1:(u=t.document.createElement("a"),u.href=i,u.protocol+a(u.protocol,u.host)!==r.protocol+a(r.protocol,r.host))},ajaxDataType:"text",contentType:"application/json; charset=UTF-8",logging:!1,state:r.connectionState.disconnected,clientProtocol:"1.5",reconnectDelay:2e3,transportConnectTimeout:0,disconnectTimeout:3e4,reconnectWindow:3e4,keepAliveWarnAt:2/3,start:function(i,h){var a=this,v={pingInterval:3e5,waitForPageLoad:!0,transport:"auto",jsonp:!1},d,y=a._deferral||n.Deferred(),b=t.document.createElement("a"),k,g;if(a.lastError=null,a._deferral=y,!a.json)throw new Error("SignalR: No JSON parser found. Please ensure json2.js is referenced before the SignalR.js file if you need to support clients without native JSON parsing support, e.g. IE<8.");if(n.type(i)==="function"?h=i:n.type(i)==="object"&&(n.extend(v,i),n.type(v.callback)==="function"&&(h=v.callback)),v.transport=w(v.transport,a),!v.transport)throw new Error("SignalR: Invalid transport(s) specified, aborting start.");return(a._.config=v,!o&&v.waitForPageLoad===!0)?(a._.deferredStartHandler=function(){a.start(i,h)},e.bind("load",a._.deferredStartHandler),y.promise()):a.state===r.connectionState.connecting?y.promise():s(a,r.connectionState.disconnected,r.connectionState.connecting)===!1?(y.resolve(a),y.promise()):(p(a),b.href=a.url,b.protocol&&b.protocol!==":"?(a.protocol=b.protocol,a.host=b.host):(a.protocol=t.document.location.protocol,a.host=b.host||t.document.location.host),a.baseUrl=a.protocol+"//"+a.host,a.wsProtocol=a.protocol==="https:"?"wss://":"ws://",v.transport==="auto"&&v.jsonp===!0&&(v.transport="longPolling"),a.url.indexOf("//")===0&&(a.url=t.location.protocol+a.url,a.log("Protocol relative URL detected, normalizing it to '"+a.url+"'.")),this.isCrossDomain(a.url)&&(a.log("Auto detected cross domain url."),v.transport==="auto"&&(v.transport=["webSockets","serverSentEvents","longPolling"]),typeof v.withCredentials=="undefined"&&(v.withCredentials=!0),v.jsonp||(v.jsonp=!n.support.cors,v.jsonp&&a.log("Using jsonp because this browser doesn't support CORS.")),a.contentType=r._.defaultContentType),a.withCredentials=v.withCredentials,a.ajaxDataType=v.jsonp?"jsonp":"text",n(a).bind(u.onStart,function(){n.type(h)==="function"&&h.call(a);y.resolve(a)}),a._.initHandler=r.transports._logic.initHandler(a),d=function(i,o){var c=r._.error(f.noTransportOnInit);if(o=o||0,o>=i.length){o===0?a.log("No transports supported by the server were selected."):o===1?a.log("No fallback transports were selected."):a.log("Fallback transports exhausted.");n(a).triggerHandler(u.onError,[c]);y.reject(c);a.stop();return}if(a.state!==r.connectionState.disconnected){var p=i[o],h=r.transports[p],v=function(){d(i,o+1)};a.transport=h;try{a._.initHandler.start(h,function(){var i=r._.firefoxMajorVersion(t.navigator.userAgent)>=11,f=!!a.withCredentials&&i;a.log("The start request succeeded. Transitioning to the connected state.");l(a)&&r.transports._logic.monitorKeepAlive(a);r.transports._logic.startHeartbeat(a);r._.configurePingInterval(a);s(a,r.connectionState.connecting,r.connectionState.connected)||a.log("WARNING! The connection was not in the connecting state.");a._.connectingMessageBuffer.drain();n(a).triggerHandler(u.onStart);e.bind("unload",function(){a.log("Window unloading, stopping the connection.");a.stop(f)});i&&e.bind("beforeunload",function(){t.setTimeout(function(){a.stop(f)},0)})},v)}catch(w){a.log(h.name+" transport threw '"+w.message+"' when attempting to start.");v()}}},k=a.url+"/negotiate",g=function(t,i){var e=r._.error(f.errorOnNegotiate,t,i._.negotiateRequest);n(i).triggerHandler(u.onError,e);y.reject(e);i.stop()},n(a).triggerHandler(u.onStarting),k=r.transports._logic.prepareQueryString(a,k),a.log("Negotiating with '"+k+"'."),a._.negotiateRequest=r.transports._logic.ajax(a,{url:k,error:function(n,t){t!==c?g(n,a):y.reject(r._.error(f.stoppedWhileNegotiating,null,a._.negotiateRequest))},success:function(t){var i,e,h,o=[],s=[];try{i=a._parseResponse(t)}catch(c){g(r._.error(f.errorParsingNegotiateResponse,c),a);return}if(e=a._.keepAliveData,a.appRelativeUrl=i.Url,a.id=i.ConnectionId,a.token=i.ConnectionToken,a.webSocketServerUrl=i.WebSocketServerUrl,a._.pollTimeout=i.ConnectionTimeout*1e3+1e4,a.disconnectTimeout=i.DisconnectTimeout*1e3,a._.totalTransportConnectTimeout=a.transportConnectTimeout+i.TransportConnectTimeout*1e3,i.KeepAliveTimeout?(e.activated=!0,e.timeout=i.KeepAliveTimeout*1e3,e.timeoutWarning=e.timeout*a.keepAliveWarnAt,a._.beatInterval=(e.timeout-e.timeoutWarning)/3):e.activated=!1,a.reconnectWindow=a.disconnectTimeout+(e.timeout||0),!i.ProtocolVersion||i.ProtocolVersion!==a.clientProtocol){h=r._.error(r._.format(f.protocolIncompatible,a.clientProtocol,i.ProtocolVersion));n(a).triggerHandler(u.onError,[h]);y.reject(h);return}n.each(r.transports,function(n){if(n.indexOf("_")===0||n==="webSockets"&&!i.TryWebSockets)return!0;s.push(n)});n.isArray(v.transport)?n.each(v.transport,function(t,i){n.inArray(i,s)>=0&&o.push(i)}):v.transport==="auto"?o=s:n.inArray(v.transport,s)>=0&&o.push(v.transport);d(o)}}),y.promise())},starting:function(t){var i=this;return n(i).bind(u.onStarting,function(){t.call(i)}),i},send:function(n){var t=this;if(t.state===r.connectionState.disconnected)throw new Error("SignalR: Connection must be started before data can be sent. Call .start() before .send()");if(t.state===r.connectionState.connecting)throw new Error("SignalR: Connection has not been fully initialized. Use .start().done() or .start().fail() to run logic after the connection has started.");return t.transport.send(t,n),t},received:function(t){var i=this;return n(i).bind(u.onReceived,function(n,r){t.call(i,r)}),i},stateChanged:function(t){var i=this;return n(i).bind(u.onStateChanged,function(n,r){t.call(i,r)}),i},error:function(t){var i=this;return n(i).bind(u.onError,function(n,r,u){i.lastError=r;t.call(i,r,u)}),i},disconnected:function(t){var i=this;return n(i).bind(u.onDisconnect,function(){t.call(i)}),i},connectionSlow:function(t){var i=this;return n(i).bind(u.onConnectionSlow,function(){t.call(i)}),i},reconnecting:function(t){var i=this;return n(i).bind(u.onReconnecting,function(){t.call(i)}),i},reconnected:function(t){var i=this;return n(i).bind(u.onReconnect,function(){t.call(i)}),i},stop:function(i,h){var a=this,v=a._deferral;if(a._.deferredStartHandler&&e.unbind("load",a._.deferredStartHandler),delete a._.config,delete a._.deferredStartHandler,!o&&(!a._.config||a._.config.waitForPageLoad===!0)){a.log("Stopping connection prior to negotiate.");v&&v.reject(r._.error(f.stoppedWhileLoading));return}if(a.state!==r.connectionState.disconnected)return a.log("Stopping connection."),t.clearTimeout(a._.beatHandle),t.clearInterval(a._.pingIntervalId),a.transport&&(a.transport.stop(a),h!==!1&&a.transport.abort(a,i),l(a)&&r.transports._logic.stopMonitoringKeepAlive(a),a.transport=null),a._.negotiateRequest&&(a._.negotiateRequest.abort(c),delete a._.negotiateRequest),a._.initHandler&&a._.initHandler.stop(),delete a._deferral,delete a.messageId,delete a.groupsToken,delete a.id,delete a._.pingIntervalId,delete a._.lastMessageAt,delete a._.lastActiveAt,a._.connectingMessageBuffer.clear(),n(a).unbind(u.onStart),s(a,a.state,r.connectionState.disconnected),n(a).triggerHandler(u.onDisconnect),a},log:function(n){v(n,this.logging)}};r.fn.init.prototype=r.fn;r.noConflict=function(){return n.connection===r&&(n.connection=h),r};n.connection&&(h=n.connection);n.connection=n.signalR=r})(window.jQuery,window),function(n,t,i){function s(n){n._.keepAliveData.monitoring&&l(n);u.markActive(n)&&(n._.beatHandle=t.setTimeout(function(){s(n)},n._.beatInterval))}function l(t){var i=t._.keepAliveData,u;t.state===r.connectionState.connected&&(u=(new Date).getTime()-t._.lastMessageAt,u>=i.timeout?(t.log("Keep alive timed out. Notifying transport that connection has been lost."),t.transport.lostConnection(t)):u>=i.timeoutWarning?i.userNotified||(t.log("Keep alive has been missed, connection may be dead/slow."),n(t).triggerHandler(f.onConnectionSlow),i.userNotified=!0):i.userNotified=!1)}function e(n,t){var i=n.url+t;return n.transport&&(i+="?transport="+n.transport.name),u.prepareQueryString(n,i)}function h(n){this.connection=n;this.startRequested=!1;this.startCompleted=!1;this.connectionStopped=!1}var r=n.signalR,f=n.signalR.events,c=n.signalR.changeState,o="__Start Aborted__",u;r.transports={};h.prototype={start:function(n,r,u){var f=this,e=f.connection,o=!1;if(f.startRequested||f.connectionStopped){e.log("WARNING! "+n.name+" transport cannot be started. Initialization ongoing or completed.");return}e.log(n.name+" transport starting.");n.start(e,function(){o||f.initReceived(n,r)},function(t){return o||(o=!0,f.transportFailed(n,t,u)),!f.startCompleted||f.connectionStopped});f.transportTimeoutHandle=t.setTimeout(function(){o||(o=!0,e.log(n.name+" transport timed out when trying to connect."),f.transportFailed(n,i,u))},e._.totalTransportConnectTimeout)},stop:function(){this.connectionStopped=!0;t.clearTimeout(this.transportTimeoutHandle);r.transports._logic.tryAbortStartRequest(this.connection)},initReceived:function(n,i){var u=this,f=u.connection;if(u.startRequested){f.log("WARNING! The client received multiple init messages.");return}u.connectionStopped||(u.startRequested=!0,t.clearTimeout(u.transportTimeoutHandle),f.log(n.name+" transport connected. Initiating start request."),r.transports._logic.ajaxStart(f,function(){u.startCompleted=!0;i()}))},transportFailed:function(i,u,e){var o=this.connection,h=o._deferral,s;this.connectionStopped||(t.clearTimeout(this.transportTimeoutHandle),this.startRequested?this.startCompleted||(s=r._.error(r.resources.errorDuringStartRequest,u),o.log(i.name+" transport failed during the start request. Stopping the connection."),n(o).triggerHandler(f.onError,[s]),h&&h.reject(s),o.stop()):(i.stop(o),o.log(i.name+" transport failed to connect. Attempting to fall back."),e()))}};u=r.transports._logic={ajax:function(t,i){return n.ajax(n.extend(!0,{},n.signalR.ajaxDefaults,{type:"GET",data:{},xhrFields:{withCredentials:t.withCredentials},contentType:t.contentType,dataType:t.ajaxDataType},i))},pingServer:function(t){var e,f,i=n.Deferred();return t.transport?(e=t.url+"/ping",e=u.addQs(e,t.qs),f=u.ajax(t,{url:e,success:function(n){var u;try{u=t._parseResponse(n)}catch(e){i.reject(r._.transportError(r.resources.pingServerFailedParse,t.transport,e,f));t.stop();return}u.Response==="pong"?i.resolve():i.reject(r._.transportError(r._.format(r.resources.pingServerFailedInvalidResponse,n),t.transport,null,f))},error:function(n){n.status===401||n.status===403?(i.reject(r._.transportError(r._.format(r.resources.pingServerFailedStatusCode,n.status),t.transport,n,f)),t.stop()):i.reject(r._.transportError(r.resources.pingServerFailed,t.transport,n,f))}})):i.reject(r._.transportError(r.resources.noConnectionTransport,t.transport)),i.promise()},prepareQueryString:function(n,i){var r;return r=u.addQs(i,"clientProtocol="+n.clientProtocol),r=u.addQs(r,n.qs),n.token&&(r+="&connectionToken="+t.encodeURIComponent(n.token)),n.data&&(r+="&connectionData="+t.encodeURIComponent(n.data)),r},addQs:function(t,i){var r=t.indexOf("?")!==-1?"&":"?",u;if(!i)return t;if(typeof i=="object")return t+r+n.param(i);if(typeof i=="string")return u=i.charAt(0),(u==="?"||u==="&")&&(r=""),t+r+i;throw new Error("Query string property must be either a string or object.");},getUrl:function(n,i,r,f,e){var h=i==="webSockets"?"":n.baseUrl,o=h+n.appRelativeUrl,s="transport="+i;return!e&&n.groupsToken&&(s+="&groupsToken="+t.encodeURIComponent(n.groupsToken)),r?(o+=f?"/poll":"/reconnect",!e&&n.messageId&&(s+="&messageId="+t.encodeURIComponent(n.messageId))):o+="/connect",o+="?"+s,o=u.prepareQueryString(n,o),e||(o+="&tid="+Math.floor(Math.random()*11)),o},maximizePersistentResponse:function(n){return{MessageId:n.C,Messages:n.M,Initialized:typeof n.S!="undefined"?!0:!1,ShouldReconnect:typeof n.T!="undefined"?!0:!1,LongPollDelay:n.L,GroupsToken:n.G}},updateGroups:function(n,t){t&&(n.groupsToken=t)},stringifySend:function(n,t){return typeof t=="string"||typeof t=="undefined"||t===null?t:n.json.stringify(t)},ajaxSend:function(t,i){var h=u.stringifySend(t,i),c=e(t,"/send"),o,s=function(t,u){n(u).triggerHandler(f.onError,[r._.transportError(r.resources.sendFailed,u.transport,t,o),i])};return o=u.ajax(t,{url:c,type:t.ajaxDataType==="jsonp"?"GET":"POST",contentType:r._.defaultContentType,data:{data:h},success:function(n){var i;if(n){try{i=t._parseResponse(n)}catch(r){s(r,t);t.stop();return}u.triggerReceived(t,i)}},error:function(n,i){i!=="abort"&&i!=="parsererror"&&s(n,t)}})},ajaxAbort:function(n,t){if(typeof n.transport!="undefined"){t=typeof t=="undefined"?!0:t;var i=e(n,"/abort");u.ajax(n,{url:i,async:t,timeout:1e3,type:"POST"});n.log("Fired ajax abort async = "+t+".")}},ajaxStart:function(t,i){var h=function(n){var i=t._deferral;i&&i.reject(n)},s=function(i){t.log("The start request failed. Stopping the connection.");n(t).triggerHandler(f.onError,[i]);h(i);t.stop()};t._.startRequest=u.ajax(t,{url:e(t,"/start"),success:function(n,u,f){var e;try{e=t._parseResponse(n)}catch(o){s(r._.error(r._.format(r.resources.errorParsingStartResponse,n),o,f));return}e.Response==="started"?i():s(r._.error(r._.format(r.resources.invalidStartResponse,n),null,f))},error:function(n,i,u){i!==o?s(r._.error(r.resources.errorDuringStartRequest,u,n)):(t.log("The start request aborted because connection.stop() was called."),h(r._.error(r.resources.stoppedDuringStartRequest,null,n)))}})},tryAbortStartRequest:function(n){n._.startRequest&&(n._.startRequest.abort(o),delete n._.startRequest)},tryInitialize:function(n,t,i){t.Initialized&&i?i():t.Initialized&&n.log("WARNING! The client received an init message after reconnecting.")},triggerReceived:function(t,i){t._.connectingMessageBuffer.tryBuffer(i)||n(t).triggerHandler(f.onReceived,[i])},processMessages:function(t,i,r){var f;u.markLastMessage(t);i&&(f=u.maximizePersistentResponse(i),u.updateGroups(t,f.GroupsToken),f.MessageId&&(t.messageId=f.MessageId),f.Messages&&(n.each(f.Messages,function(n,i){u.triggerReceived(t,i)}),u.tryInitialize(t,f,r)))},monitorKeepAlive:function(t){var i=t._.keepAliveData;i.monitoring?t.log("Tried to monitor keep alive but it's already being monitored."):(i.monitoring=!0,u.markLastMessage(t),t._.keepAliveData.reconnectKeepAliveUpdate=function(){u.markLastMessage(t)},n(t).bind(f.onReconnect,t._.keepAliveData.reconnectKeepAliveUpdate),t.log("Now monitoring keep alive with a warning timeout of "+i.timeoutWarning+", keep alive timeout of "+i.timeout+" and disconnecting timeout of "+t.disconnectTimeout))},stopMonitoringKeepAlive:function(t){var i=t._.keepAliveData;i.monitoring&&(i.monitoring=!1,n(t).unbind(f.onReconnect,t._.keepAliveData.reconnectKeepAliveUpdate),t._.keepAliveData={},t.log("Stopping the monitoring of the keep alive."))},startHeartbeat:function(n){n._.lastActiveAt=(new Date).getTime();s(n)},markLastMessage:function(n){n._.lastMessageAt=(new Date).getTime()},markActive:function(n){return u.verifyLastActive(n)?(n._.lastActiveAt=(new Date).getTime(),!0):!1},isConnectedOrReconnecting:function(n){return n.state===r.connectionState.connected||n.state===r.connectionState.reconnecting},ensureReconnectingState:function(t){return c(t,r.connectionState.connected,r.connectionState.reconnecting)===!0&&n(t).triggerHandler(f.onReconnecting),t.state===r.connectionState.reconnecting},clearReconnectTimeout:function(n){n&&n._.reconnectTimeout&&(t.clearTimeout(n._.reconnectTimeout),delete n._.reconnectTimeout)},verifyLastActive:function(t){if((new Date).getTime()-t._.lastActiveAt>=t.reconnectWindow){var i=r._.format(r.resources.reconnectWindowTimeout,new Date(t._.lastActiveAt),t.reconnectWindow);return t.log(i),n(t).triggerHandler(f.onError,[r._.error(i,"TimeoutException")]),t.stop(!1,!1),!1}return!0},reconnect:function(n,i){var f=r.transports[i];if(u.isConnectedOrReconnecting(n)&&!n._.reconnectTimeout){if(!u.verifyLastActive(n))return;n._.reconnectTimeout=t.setTimeout(function(){u.verifyLastActive(n)&&(f.stop(n),u.ensureReconnectingState(n)&&(n.log(i+" reconnecting."),f.start(n)))},n.reconnectDelay)}},handleParseFailure:function(t,i,u,e,o){var s=r._.transportError(r._.format(r.resources.parseFailed,i),t.transport,u,o);e&&e(s)?t.log("Failed to parse server response while attempting to connect."):(n(t).triggerHandler(f.onError,[s]),t.stop())},initHandler:function(n){return new h(n)},foreverFrame:{count:0,connections:{}}}}(window.jQuery,window),function(n,t){var r=n.signalR,u=n.signalR.events,f=n.signalR.changeState,i=r.transports._logic;r.transports.webSockets={name:"webSockets",supportsKeepAlive:function(){return!0},send:function(t,f){var e=i.stringifySend(t,f);try{t.socket.send(e)}catch(o){n(t).triggerHandler(u.onError,[r._.transportError(r.resources.webSocketsInvalidState,t.transport,o,t.socket),f])}},start:function(e,o,s){var h,c=!1,l=this,a=!o,v=n(e);if(!t.WebSocket){s();return}e.socket||(h=e.webSocketServerUrl?e.webSocketServerUrl:e.wsProtocol+e.host,h+=i.getUrl(e,this.name,a),e.log("Connecting to websocket endpoint '"+h+"'."),e.socket=new t.WebSocket(h),e.socket.onopen=function(){c=!0;e.log("Websocket opened.");i.clearReconnectTimeout(e);f(e,r.connectionState.reconnecting,r.connectionState.connected)===!0&&v.triggerHandler(u.onReconnect)},e.socket.onclose=function(t){var i;this===e.socket&&(c&&typeof t.wasClean!="undefined"&&t.wasClean===!1?(i=r._.transportError(r.resources.webSocketClosed,e.transport,t),e.log("Unclean disconnect from websocket: "+(t.reason||"[no reason given]."))):e.log("Websocket closed."),s&&s(i)||(i&&n(e).triggerHandler(u.onError,[i]),l.reconnect(e)))},e.socket.onmessage=function(t){var r;try{r=e._parseResponse(t.data)}catch(u){i.handleParseFailure(e,t.data,u,s,t);return}r&&(n.isEmptyObject(r)||r.M?i.processMessages(e,r,o):i.triggerReceived(e,r))})},reconnect:function(n){i.reconnect(n,this.name)},lostConnection:function(n){this.reconnect(n)},stop:function(n){i.clearReconnectTimeout(n);n.socket&&(n.log("Closing the Websocket."),n.socket.close(),n.socket=null)},abort:function(n,t){i.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){var i=n.signalR,u=n.signalR.events,e=n.signalR.changeState,r=i.transports._logic,f=function(n){t.clearTimeout(n._.reconnectAttemptTimeoutHandle);delete n._.reconnectAttemptTimeoutHandle};i.transports.serverSentEvents={name:"serverSentEvents",supportsKeepAlive:function(){return!0},timeOut:3e3,start:function(o,s,h){var c=this,l=!1,a=n(o),v=!s,y;if(o.eventSource&&(o.log("The connection already has an event source. Stopping it."),o.stop()),!t.EventSource){h&&(o.log("This browser doesn't support SSE."),h());return}y=r.getUrl(o,this.name,v);try{o.log("Attempting to connect to SSE endpoint '"+y+"'.");o.eventSource=new t.EventSource(y,{withCredentials:o.withCredentials})}catch(p){o.log("EventSource failed trying to connect with error "+p.Message+".");h?h():(a.triggerHandler(u.onError,[i._.transportError(i.resources.eventSourceFailedToConnect,o.transport,p)]),v&&c.reconnect(o));return}v&&(o._.reconnectAttemptTimeoutHandle=t.setTimeout(function(){l===!1&&o.eventSource.readyState!==t.EventSource.OPEN&&c.reconnect(o)},c.timeOut));o.eventSource.addEventListener("open",function(){o.log("EventSource connected.");f(o);r.clearReconnectTimeout(o);l===!1&&(l=!0,e(o,i.connectionState.reconnecting,i.connectionState.connected)===!0&&a.triggerHandler(u.onReconnect))},!1);o.eventSource.addEventListener("message",function(n){var t;if(n.data!=="initialized"){try{t=o._parseResponse(n.data)}catch(i){r.handleParseFailure(o,n.data,i,h,n);return}r.processMessages(o,t,s)}},!1);o.eventSource.addEventListener("error",function(n){var r=i._.transportError(i.resources.eventSourceError,o.transport,n);this===o.eventSource&&(h&&h(r)||(o.log("EventSource readyState: "+o.eventSource.readyState+"."),n.eventPhase===t.EventSource.CLOSED?(o.log("EventSource reconnecting due to the server connection ending."),c.reconnect(o)):(o.log("EventSource error."),a.triggerHandler(u.onError,[r]))))},!1)},reconnect:function(n){r.reconnect(n,this.name)},lostConnection:function(n){this.reconnect(n)},send:function(n,t){r.ajaxSend(n,t)},stop:function(n){f(n);r.clearReconnectTimeout(n);n&&n.eventSource&&(n.log("EventSource calling close()."),n.eventSource.close(),n.eventSource=null,delete n.eventSource)},abort:function(n,t){r.ajaxAbort(n,t)}}}(window.jQuery,window),function(n,t){var r=n.signalR,e=n.signalR.events,o=n.signalR.changeState,i=r.transports._logic,u=function(){var n=t.document.createElement("iframe");return n.setAttribute("style","position:absolute;top:0;left:0;width:0;height:0;visibility:hidden;"),n},f=function(){var i=null,f=1e3,n=0;return{prevent:function(){r._.ieVersion<=8&&(n===0&&(i=t.setInterval(function(){var n=u();t.document.body.appendChild(n);t.document.body.removeChild(n);n=null},f)),n++)},cancel:function(){n===1&&t.clearInterval(i);n>0&&n--}}}();r.transports.foreverFrame={name:"foreverFrame",supportsKeepAlive:function(){return!0},iframeClearThreshold:50,start:function(n,r,e){var l=this,s=i.foreverFrame.count+=1,h,o=u(),c=function(){n.log("Forever frame iframe finished loading and is no longer receiving messages.");e&&e()||l.reconnect(n)};if(t.EventSource){e&&(n.log("Forever Frame is not supported by SignalR on browsers with SSE support."),e());return}o.setAttribute("data-signalr-connection-id",n.id);f.prevent();h=i.getUrl(n,this.name);h+="&frameId="+s;t.document.documentElement.appendChild(o);n.log("Binding to iframe's load event.");o.addEventListener?o.addEventListener("load",c,!1):o.attachEvent&&o.attachEvent("onload",c);o.src=h;i.foreverFrame.connections[s]=n;n.frame=o;n.frameId=s;r&&(n.onSuccess=function(){n.log("Iframe transport started.");r()})},reconnect:function(n){var r=this;i.isConnectedOrReconnecting(n)&&i.verifyLastActive(n)&&t.setTimeout(function(){if(i.verifyLastActive(n)&&n.frame&&i.ensureReconnectingState(n)){var u=n.frame,t=i.getUrl(n,r.name,!0)+"&frameId="+n.frameId;n.log("Updating iframe src to '"+t+"'.");u.src=t}},n.reconnectDelay)},lostConnection:function(n){this.reconnect(n)},send:function(n,t){i.ajaxSend(n,t)},receive:function(t,u){var f,e,o;if(t.json!==t._originalJson&&(u=t._originalJson.stringify(u)),o=t._parseResponse(u),i.processMessages(t,o,t.onSuccess),t.state===n.signalR.connectionState.connected&&(t.frameMessageCount=(t.frameMessageCount||0)+1,t.frameMessageCount>r.transports.foreverFrame.iframeClearThreshold&&(t.frameMessageCount=0,f=t.frame.contentWindow||t.frame.contentDocument,f&&f.document&&f.document.body)))for(e=f.document.body;e.firstChild;)e.removeChild(e.firstChild)},stop:function(n){var r=null;if(f.cancel(),n.frame){if(n.frame.stop)n.frame.stop();else try{r=n.frame.contentWindow||n.frame.contentDocument;r.document&&r.document.execCommand&&r.document.execCommand("Stop")}catch(u){n.log("Error occurred when stopping foreverFrame transport. Message = "+u.message+".")}n.frame.parentNode===t.document.documentElement&&t.document.documentElement.removeChild(n.frame);delete i.foreverFrame.connections[n.frameId];n.frame=null;n.frameId=null;delete n.frame;delete n.frameId;delete n.onSuccess;delete n.frameMessageCount;n.log("Stopping forever frame.")}},abort:function(n,t){i.ajaxAbort(n,t)},getConnection:function(n){return i.foreverFrame.connections[n]},started:function(t){o(t,r.connectionState.reconnecting,r.connectionState.connected)===!0&&n(t).triggerHandler(e.onReconnect)}}}(window.jQuery,window),function(n,t){var r=n.signalR,u=n.signalR.events,e=n.signalR.changeState,f=n.signalR.isDisconnecting,i=r.transports._logic;r.transports.longPolling={name:"longPolling",supportsKeepAlive:function(){return!1},reconnectDelay:3e3,start:function(o,s,h){var a=this,v=function(){v=n.noop;o.log("LongPolling connected.");s?s():o.log("WARNING! The client received an init message after reconnecting.")},y=function(n){return h(n)?(o.log("LongPolling failed to connect."),!0):!1},c=o._,l=0,p=function(i){t.clearTimeout(c.reconnectTimeoutId);c.reconnectTimeoutId=null;e(i,r.connectionState.reconnecting,r.connectionState.connected)===!0&&(i.log("Raising the reconnect event"),n(i).triggerHandler(u.onReconnect))},w=36e5;o.pollXhr&&(o.log("Polling xhr requests already exists, aborting."),o.stop());o.messageId=null;c.reconnectTimeoutId=null;c.pollTimeoutId=t.setTimeout(function(){(function e(s,h){var g=s.messageId,nt=g===null,k=!nt,tt=!h,d=i.getUrl(s,a.name,k,tt,!0),b={};(s.messageId&&(b.messageId=s.messageId),s.groupsToken&&(b.groupsToken=s.groupsToken),f(s)!==!0)&&(o.log("Opening long polling request to '"+d+"'."),s.pollXhr=i.ajax(o,{xhrFields:{onprogress:function(){i.markLastMessage(o)}},url:d,type:"POST",contentType:r._.defaultContentType,data:b,timeout:o._.pollTimeout,success:function(r){var h,w=0,u,a;o.log("Long poll complete.");l=0;try{h=o._parseResponse(r)}catch(b){i.handleParseFailure(s,r,b,y,s.pollXhr);return}(c.reconnectTimeoutId!==null&&p(s),h&&(u=i.maximizePersistentResponse(h)),i.processMessages(s,h,v),u&&n.type(u.LongPollDelay)==="number"&&(w=u.LongPollDelay),f(s)!==!0)&&(a=u&&u.ShouldReconnect,!a||i.ensureReconnectingState(s))&&(w>0?c.pollTimeoutId=t.setTimeout(function(){e(s,a)},w):e(s,a))},error:function(f,h){var v=r._.transportError(r.resources.longPollFailed,o.transport,f,s.pollXhr);if(t.clearTimeout(c.reconnectTimeoutId),c.reconnectTimeoutId=null,h==="abort"){o.log("Aborted xhr request.");return}if(!y(v)){if(l++,o.state!==r.connectionState.reconnecting&&(o.log("An error occurred using longPolling. Status = "+h+". Response = "+f.responseText+"."),n(s).triggerHandler(u.onError,[v])),(o.state===r.connectionState.connected||o.state===r.connectionState.reconnecting)&&!i.verifyLastActive(o))return;if(!i.ensureReconnectingState(s))return;c.pollTimeoutId=t.setTimeout(function(){e(s,!0)},a.reconnectDelay)}}}),k&&h===!0&&(c.reconnectTimeoutId=t.setTimeout(function(){p(s)},Math.min(1e3*(Math.pow(2,l)-1),w))))})(o)},250)},lostConnection:function(n){n.pollXhr&&n.pollXhr.abort("lostConnection")},send:function(n,t){i.ajaxSend(n,t)},stop:function(n){t.clearTimeout(n._.pollTimeoutId);t.clearTimeout(n._.reconnectTimeoutId);delete n._.pollTimeoutId;delete n._.reconnectTimeoutId;n.pollXhr&&(n.pollXhr.abort(),n.pollXhr=null,delete n.pollXhr)},abort:function(n,t){i.ajaxAbort(n,t)}}}(window.jQuery,window),function(n){function r(n){return n+e}function s(n,t,i){for(var f=n.length,u=[],r=0;r
          ',e.titleMarkup='\n
          \n',e.textMarkup='\n
          ',e.footerMarkup='\n
          \n'},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1);e.CONFIRM_KEY="confirm",e.CANCEL_KEY="cancel";var r={visible:!0,text:null,value:null,className:"",closeModal:!0},i=Object.assign({},r,{visible:!1,text:"Cancel",value:null}),a=Object.assign({},r,{text:"OK",value:!0});e.defaultButtonList={cancel:i,confirm:a};var s=function(t){switch(t){case e.CONFIRM_KEY:return a;case e.CANCEL_KEY:return i;default:var n=t.charAt(0).toUpperCase()+t.slice(1);return Object.assign({},r,{text:n,value:t})}},c=function(t,e){var n=s(t);return!0===e?Object.assign({},n,{visible:!0}):"string"==typeof e?Object.assign({},n,{visible:!0,text:e}):o.isPlainObject(e)?Object.assign({visible:!0},n,e):Object.assign({},n,{visible:!1})},l=function(t){for(var e={},n=0,o=Object.keys(t);n=0&&w.splice(e,1)}function s(t){var e=document.createElement("style");return t.attrs.type="text/css",l(e,t.attrs),i(t,e),e}function c(t){var e=document.createElement("link");return t.attrs.type="text/css",t.attrs.rel="stylesheet",l(e,t.attrs),i(t,e),e}function l(t,e){Object.keys(e).forEach(function(n){t.setAttribute(n,e[n])})}function u(t,e){var n,o,r,i;if(e.transform&&t.css){if(!(i=e.transform(t.css)))return function(){};t.css=i}if(e.singleton){var l=h++;n=g||(g=s(e)),o=f.bind(null,n,l,!1),r=f.bind(null,n,l,!0)}else t.sourceMap&&"function"==typeof URL&&"function"==typeof URL.createObjectURL&&"function"==typeof URL.revokeObjectURL&&"function"==typeof Blob&&"function"==typeof btoa?(n=c(e),o=p.bind(null,n,e),r=function(){a(n),n.href&&URL.revokeObjectURL(n.href)}):(n=s(e),o=d.bind(null,n),r=function(){a(n)});return o(t),function(e){if(e){if(e.css===t.css&&e.media===t.media&&e.sourceMap===t.sourceMap)return;o(t=e)}else r()}}function f(t,e,n,o){var r=n?"":o.css;if(t.styleSheet)t.styleSheet.cssText=x(e,r);else{var i=document.createTextNode(r),a=t.childNodes;a[e]&&t.removeChild(a[e]),a.length?t.insertBefore(i,a[e]):t.appendChild(i)}}function d(t,e){var n=e.css,o=e.media;if(o&&t.setAttribute("media",o),t.styleSheet)t.styleSheet.cssText=n;else{for(;t.firstChild;)t.removeChild(t.firstChild);t.appendChild(document.createTextNode(n))}}function p(t,e,n){var o=n.css,r=n.sourceMap,i=void 0===e.convertToAbsoluteUrls&&r;(e.convertToAbsoluteUrls||i)&&(o=y(o)),r&&(o+="\n/*# sourceMappingURL=data:application/json;base64,"+btoa(unescape(encodeURIComponent(JSON.stringify(r))))+" */");var a=new Blob([o],{type:"text/css"}),s=t.href;t.href=URL.createObjectURL(a),s&&URL.revokeObjectURL(s)}var m={},b=function(t){var e;return function(){return void 0===e&&(e=t.apply(this,arguments)),e}}(function(){return window&&document&&document.all&&!window.atob}),v=function(t){var e={};return function(n){return void 0===e[n]&&(e[n]=t.call(this,n)),e[n]}}(function(t){return document.querySelector(t)}),g=null,h=0,w=[],y=n(15);t.exports=function(t,e){if("undefined"!=typeof DEBUG&&DEBUG&&"object"!=typeof document)throw new Error("The style-loader cannot be used in a non-browser environment");e=e||{},e.attrs="object"==typeof e.attrs?e.attrs:{},e.singleton||(e.singleton=b()),e.insertInto||(e.insertInto="head"),e.insertAt||(e.insertAt="bottom");var n=r(t,e);return o(n,e),function(t){for(var i=[],a=0;athis.length)&&-1!==this.indexOf(t,e)}),Array.prototype.includes||Object.defineProperty(Array.prototype,"includes",{value:function(t,e){if(null==this)throw new TypeError('"this" is null or not defined');var n=Object(this),o=n.length>>>0;if(0===o)return!1;for(var r=0|e,i=Math.max(r>=0?r:o-Math.abs(r),0);i=0&&(t._idleTimeoutId=setTimeout(function(){t._onTimeout&&t._onTimeout()},e))},n(19),e.setImmediate=setImmediate,e.clearImmediate=clearImmediate},function(t,e,n){(function(t,e){!function(t,n){"use strict";function o(t){"function"!=typeof t&&(t=new Function(""+t));for(var e=new Array(arguments.length-1),n=0;n1)for(var n=1;n',e.default=e.modalMarkup},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(0),r=o.default.OVERLAY,i='
          \n
          ';e.default=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(0),r=o.default.ICON;e.errorIconMarkup=function(){var t=r+"--error",e=t+"__line";return'\n
          \n \n \n
          \n '},e.warningIconMarkup=function(){var t=r+"--warning";return'\n \n \n \n '},e.successIconMarkup=function(){var t=r+"--success";return'\n \n \n\n
          \n
          \n '}},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(0),r=o.default.CONTENT;e.contentMarkup='\n
          \n\n
          \n'},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(0),r=o.default.BUTTON_CONTAINER,i=o.default.BUTTON,a=o.default.BUTTON_LOADER;e.buttonMarkup='\n
          \n\n \n\n
          \n
          \n
          \n
          \n
          \n\n
          \n'},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(4),r=n(2),i=n(0),a=i.default.ICON,s=i.default.ICON_CUSTOM,c=["error","warning","success","info"],l={error:r.errorIconMarkup(),warning:r.warningIconMarkup(),success:r.successIconMarkup()},u=function(t,e){var n=a+"--"+t;e.classList.add(n);var o=l[t];o&&(e.innerHTML=o)},f=function(t,e){e.classList.add(s);var n=document.createElement("img");n.src=t,e.appendChild(n)},d=function(t){if(t){var e=o.injectElIntoModal(r.iconMarkup);c.includes(t)?u(t,e):f(t,e)}};e.default=d},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(2),r=n(4),i=function(t){navigator.userAgent.includes("AppleWebKit")&&(t.style.display="none",t.offsetHeight,t.style.display="")};e.initTitle=function(t){if(t){var e=r.injectElIntoModal(o.titleMarkup);e.textContent=t,i(e)}},e.initText=function(t){if(t){var e=document.createDocumentFragment();t.split("\n").forEach(function(t,n,o){e.appendChild(document.createTextNode(t)),n0}).forEach(function(t){b.classList.add(t)})}n&&t===c.CONFIRM_KEY&&b.classList.add(s),b.textContent=r;var g={};return g[t]=i,f.setActionValue(g),f.setActionOptionsFor(t,{closeModal:p}),b.addEventListener("click",function(){return u.onAction(t)}),m},p=function(t,e){var n=r.injectElIntoModal(l.footerMarkup);for(var o in t){var i=t[o],a=d(o,i,e);i.visible&&n.appendChild(a)}0===n.children.length&&n.remove()};e.default=p},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(3),r=n(4),i=n(2),a=n(5),s=n(6),c=n(0),l=c.default.CONTENT,u=function(t){t.addEventListener("input",function(t){var e=t.target,n=e.value;a.setActionValue(n)}),t.addEventListener("keyup",function(t){if("Enter"===t.key)return s.onAction(o.CONFIRM_KEY)}),setTimeout(function(){t.focus(),a.setActionValue("")},0)},f=function(t,e,n){var o=document.createElement(e),r=l+"__"+e;o.classList.add(r);for(var i in n){var a=n[i];o[i]=a}"input"===e&&u(o),t.appendChild(o)},d=function(t){if(t){var e=r.injectElIntoModal(i.contentMarkup),n=t.element,o=t.attributes;"string"==typeof n?f(e,n,o):e.appendChild(n)}};e.default=d},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1),r=n(2),i=function(){var t=o.stringToNode(r.overlayMarkup);document.body.appendChild(t)};e.default=i},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(5),r=n(6),i=n(1),a=n(3),s=n(0),c=s.default.MODAL,l=s.default.BUTTON,u=s.default.OVERLAY,f=function(t){t.preventDefault(),v()},d=function(t){t.preventDefault(),g()},p=function(t){if(o.default.isOpen)switch(t.key){case"Escape":return r.onAction(a.CANCEL_KEY)}},m=function(t){if(o.default.isOpen)switch(t.key){case"Tab":return f(t)}},b=function(t){if(o.default.isOpen)return"Tab"===t.key&&t.shiftKey?d(t):void 0},v=function(){var t=i.getNode(l);t&&(t.tabIndex=0,t.focus())},g=function(){var t=i.getNode(c),e=t.querySelectorAll("."+l),n=e.length-1,o=e[n];o&&o.focus()},h=function(t){t[t.length-1].addEventListener("keydown",m)},w=function(t){t[0].addEventListener("keydown",b)},y=function(){var t=i.getNode(c),e=t.querySelectorAll("."+l);e.length&&(h(e),w(e))},x=function(t){if(i.getNode(u)===t.target)return r.onAction(a.CANCEL_KEY)},_=function(t){var e=i.getNode(u);e.removeEventListener("click",x),t&&e.addEventListener("click",x)},k=function(t){o.default.timer&&clearTimeout(o.default.timer),t&&(o.default.timer=window.setTimeout(function(){return r.onAction(a.CANCEL_KEY)},t))},O=function(t){t.closeOnEsc?document.addEventListener("keyup",p):document.removeEventListener("keyup",p),t.dangerMode?v():g(),y(),_(t.closeOnClickOutside),k(t.timer)};e.default=O},function(t,e,n){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var o=n(1),r=n(3),i=n(37),a=n(38),s={title:null,text:null,icon:null,buttons:r.defaultButtonList,content:null,className:null,closeOnClickOutside:!0,closeOnEsc:!0,dangerMode:!1,timer:null},c=Object.assign({},s);e.setDefaults=function(t){c=Object.assign({},s,t)};var l=function(t){var e=t&&t.button,n=t&&t.buttons;return void 0!==e&&void 0!==n&&o.throwErr("Cannot set both 'button' and 'buttons' options!"),void 0!==e?{confirm:e}:n},u=function(t){return o.ordinalSuffixOf(t+1)},f=function(t,e){o.throwErr(u(e)+" argument ('"+t+"') is invalid")},d=function(t,e){var n=t+1,r=e[n];o.isPlainObject(r)||void 0===r||o.throwErr("Expected "+u(n)+" argument ('"+r+"') to be a plain object")},p=function(t,e){var n=t+1,r=e[n];void 0!==r&&o.throwErr("Unexpected "+u(n)+" argument ("+r+")")},m=function(t,e,n,r){var i=typeof e,a="string"===i,s=e instanceof Element;if(a){if(0===n)return{text:e};if(1===n)return{text:e,title:r[0]};if(2===n)return d(n,r),{icon:e};f(e,n)}else{if(s&&0===n)return d(n,r),{content:e};if(o.isPlainObject(e))return p(n,r),e;f(e,n)}};e.getOpts=function(){for(var t=[],e=0;e | */ + /* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */ + + /* 涂鸦图片上传配置项 */ + "scrawlActionName": "uploadscrawl", /* 执行上传涂鸦的action名称 */ + "scrawlFieldName": "upfile", /* 提交的图片表单名称 */ + "scrawlPathFormat": "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */ + "scrawlMaxSize": 2048000, /* 上传大小限制,单位B */ + "scrawlUrlPrefix": "/ueditor/net/", /* 图片访问路径前缀 */ + "scrawlInsertAlign": "none", + + /* 截图工具上传 */ + "snapscreenActionName": "uploadimage", /* 执行上传截图的action名称 */ + "snapscreenPathFormat": "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */ + "snapscreenUrlPrefix": "/ueditor/net/", /* 图片访问路径前缀 */ + "snapscreenInsertAlign": "none", /* 插入的图片浮动方式 */ + + /* 抓取远程图片配置 */ + "catcherLocalDomain": ["127.0.0.1", "localhost", "img.baidu.com"], + "catcherActionName": "catchimage", /* 执行抓取远程图片的action名称 */ + "catcherFieldName": "source", /* 提交的图片列表表单名称 */ + "catcherPathFormat": "upload/image/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */ + "catcherUrlPrefix": "/ueditor/net/", /* 图片访问路径前缀 */ + "catcherMaxSize": 2048000, /* 上传大小限制,单位B */ + "catcherAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 抓取图片格式显示 */ + + /* 上传视频配置 */ + "videoActionName": "uploadvideo", /* 执行上传视频的action名称 */ + "videoFieldName": "upfile", /* 提交的视频表单名称 */ + "videoPathFormat": "upload/video/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */ + "videoUrlPrefix": "/ueditor/net/", /* 视频访问路径前缀 */ + "videoMaxSize": 102400000, /* 上传大小限制,单位B,默认100MB */ + "videoAllowFiles": [ + ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg", + ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid"], /* 上传视频格式显示 */ + + /* 上传文件配置 */ + "fileActionName": "uploadfile", /* controller里,执行上传视频的action名称 */ + "fileFieldName": "upfile", /* 提交的文件表单名称 */ + "filePathFormat": "upload/file/{yyyy}{mm}{dd}/{time}{rand:6}", /* 上传保存路径,可以自定义保存路径和文件名格式 */ + "fileUrlPrefix": "/ueditor/net/", /* 文件访问路径前缀 */ + "fileMaxSize": 51200000, /* 上传大小限制,单位B,默认50MB */ + "fileAllowFiles": [ + ".png", ".jpg", ".jpeg", ".gif", ".bmp", + ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg", + ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid", + ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso", + ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml" + ], /* 上传文件格式显示 */ + + /* 列出指定目录下的图片 */ + "imageManagerActionName": "listimage", /* 执行图片管理的action名称 */ + "imageManagerListPath": "upload/image", /* 指定要列出图片的目录 */ + "imageManagerListSize": 20, /* 每次列出文件数量 */ + "imageManagerUrlPrefix": "/ueditor/net/", /* 图片访问路径前缀 */ + "imageManagerInsertAlign": "none", /* 插入的图片浮动方式 */ + "imageManagerAllowFiles": [".png", ".jpg", ".jpeg", ".gif", ".bmp"], /* 列出的文件类型 */ + + /* 列出指定目录下的文件 */ + "fileManagerActionName": "listfile", /* 执行文件管理的action名称 */ + "fileManagerListPath": "upload/file", /* 指定要列出文件的目录 */ + "fileManagerUrlPrefix": "/ueditor/net/", /* 文件访问路径前缀 */ + "fileManagerListSize": 20, /* 每次列出文件数量 */ + "fileManagerAllowFiles": [ + ".png", ".jpg", ".jpeg", ".gif", ".bmp", + ".flv", ".swf", ".mkv", ".avi", ".rm", ".rmvb", ".mpeg", ".mpg", + ".ogg", ".ogv", ".mov", ".wmv", ".mp4", ".webm", ".mp3", ".wav", ".mid", + ".rar", ".zip", ".tar", ".gz", ".7z", ".bz2", ".cab", ".iso", + ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".pdf", ".txt", ".md", ".xml" + ] /* 列出的文件类型 */ + +} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/anchor/anchor.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/anchor/anchor.html new file mode 100644 index 000000000..f277847a4 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/anchor/anchor.html @@ -0,0 +1,40 @@ + + + + + + + + +
          + +
          + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/attachment.css b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/attachment.css new file mode 100644 index 000000000..548b4284d --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/attachment.css @@ -0,0 +1,681 @@ +@charset "utf-8"; +/* dialog样式 */ +.wrapper { + zoom: 1; + width: 630px; + *width: 626px; + height: 380px; + margin: 0 auto; + padding: 10px; + position: relative; + font-family: sans-serif; +} + +/*tab样式框大小*/ +.tabhead { + float:left; +} +.tabbody { + width: 100%; + height: 346px; + position: relative; + clear: both; +} + +.tabbody .panel { + position: absolute; + width: 0; + height: 0; + background: #fff; + overflow: hidden; + display: none; +} + +.tabbody .panel.focus { + width: 100%; + height: 346px; + display: block; +} + +/* 上传附件 */ +.tabbody #upload.panel { + width: 0; + height: 0; + overflow: hidden; + position: absolute !important; + clip: rect(1px, 1px, 1px, 1px); + background: #fff; + display: block; +} + +.tabbody #upload.panel.focus { + width: 100%; + height: 346px; + display: block; + clip: auto; +} + +#upload .queueList { + margin: 0; + width: 100%; + height: 100%; + position: absolute; + overflow: hidden; +} + +#upload p { + margin: 0; +} + +.element-invisible { + width: 0 !important; + height: 0 !important; + border: 0; + padding: 0; + margin: 0; + overflow: hidden; + position: absolute !important; + clip: rect(1px, 1px, 1px, 1px); +} + +#upload .placeholder { + margin: 10px; + border: 2px dashed #e6e6e6; + *border: 0px dashed #e6e6e6; + height: 172px; + padding-top: 150px; + text-align: center; + background: url(./images/image.png) center 70px no-repeat; + color: #cccccc; + font-size: 18px; + position: relative; + top:0; + *top: 10px; +} + +#upload .placeholder .webuploader-pick { + font-size: 18px; + background: #00b7ee; + border-radius: 3px; + line-height: 44px; + padding: 0 30px; + *width: 120px; + color: #fff; + display: inline-block; + margin: 0 auto 20px auto; + cursor: pointer; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); +} + +#upload .placeholder .webuploader-pick-hover { + background: #00a2d4; +} + + +#filePickerContainer { + text-align: center; +} + +#upload .placeholder .flashTip { + color: #666666; + font-size: 12px; + position: absolute; + width: 100%; + text-align: center; + bottom: 20px; +} + +#upload .placeholder .flashTip a { + color: #0785d1; + text-decoration: none; +} + +#upload .placeholder .flashTip a:hover { + text-decoration: underline; +} + +#upload .placeholder.webuploader-dnd-over { + border-color: #999999; +} + +#upload .filelist { + list-style: none; + margin: 0; + padding: 0; + overflow-x: hidden; + overflow-y: auto; + position: relative; + height: 300px; +} + +#upload .filelist:after { + content: ''; + display: block; + width: 0; + height: 0; + overflow: hidden; + clear: both; +} + +#upload .filelist li { + width: 113px; + height: 113px; + background: url(./images/bg.png); + text-align: center; + margin: 9px 0 0 9px; + *margin: 6px 0 0 6px; + position: relative; + display: block; + float: left; + overflow: hidden; + font-size: 12px; +} + +#upload .filelist li p.log { + position: relative; + top: -45px; +} + +#upload .filelist li p.title { + position: absolute; + top: 0; + left: 0; + width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + top: 5px; + text-indent: 5px; + text-align: left; +} + +#upload .filelist li p.progress { + position: absolute; + width: 100%; + bottom: 0; + left: 0; + height: 8px; + overflow: hidden; + z-index: 50; + margin: 0; + border-radius: 0; + background: none; + -webkit-box-shadow: 0 0 0; +} + +#upload .filelist li p.progress span { + display: none; + overflow: hidden; + width: 0; + height: 100%; + background: #1483d8 url(./images/progress.png) repeat-x; + + -webit-transition: width 200ms linear; + -moz-transition: width 200ms linear; + -o-transition: width 200ms linear; + -ms-transition: width 200ms linear; + transition: width 200ms linear; + + -webkit-animation: progressmove 2s linear infinite; + -moz-animation: progressmove 2s linear infinite; + -o-animation: progressmove 2s linear infinite; + -ms-animation: progressmove 2s linear infinite; + animation: progressmove 2s linear infinite; + + -webkit-transform: translateZ(0); +} + +@-webkit-keyframes progressmove { + 0% { + background-position: 0 0; + } + 100% { + background-position: 17px 0; + } +} + +@-moz-keyframes progressmove { + 0% { + background-position: 0 0; + } + 100% { + background-position: 17px 0; + } +} + +@keyframes progressmove { + 0% { + background-position: 0 0; + } + 100% { + background-position: 17px 0; + } +} + +#upload .filelist li p.imgWrap { + position: relative; + z-index: 2; + line-height: 113px; + vertical-align: middle; + overflow: hidden; + width: 113px; + height: 113px; + + -webkit-transform-origin: 50% 50%; + -moz-transform-origin: 50% 50%; + -o-transform-origin: 50% 50%; + -ms-transform-origin: 50% 50%; + transform-origin: 50% 50%; + + -webit-transition: 200ms ease-out; + -moz-transition: 200ms ease-out; + -o-transition: 200ms ease-out; + -ms-transition: 200ms ease-out; + transition: 200ms ease-out; +} +#upload .filelist li p.imgWrap.notimage { + margin-top: 0; + width: 111px; + height: 111px; + border: 1px #eeeeee solid; +} +#upload .filelist li p.imgWrap.notimage i.file-preview { + margin-top: 15px; +} + +#upload .filelist li img { + width: 100%; +} + +#upload .filelist li p.error { + background: #f43838; + color: #fff; + position: absolute; + bottom: 0; + left: 0; + height: 28px; + line-height: 28px; + width: 100%; + z-index: 100; + display:none; +} + +#upload .filelist li .success { + display: block; + position: absolute; + left: 0; + bottom: 0; + height: 40px; + width: 100%; + z-index: 200; + background: url(./images/success.png) no-repeat right bottom; + background-image: url(./images/success.gif) \9; +} + +#upload .filelist li.filePickerBlock { + width: 113px; + height: 113px; + background: url(./images/image.png) no-repeat center 12px; + border: 1px solid #eeeeee; + border-radius: 0; +} +#upload .filelist li.filePickerBlock div.webuploader-pick { + width: 100%; + height: 100%; + margin: 0; + padding: 0; + opacity: 0; + background: none; + font-size: 0; +} + +#upload .filelist div.file-panel { + position: absolute; + height: 0; + filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#80000000', endColorstr='#80000000') \0; + background: rgba(0, 0, 0, 0.5); + width: 100%; + top: 0; + left: 0; + overflow: hidden; + z-index: 300; +} + +#upload .filelist div.file-panel span { + width: 24px; + height: 24px; + display: inline; + float: right; + text-indent: -9999px; + overflow: hidden; + background: url(./images/icons.png) no-repeat; + background: url(./images/icons.gif) no-repeat \9; + margin: 5px 1px 1px; + cursor: pointer; + -webkit-tap-highlight-color: rgba(0,0,0,0); + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +#upload .filelist div.file-panel span.rotateLeft { + display:none; + background-position: 0 -24px; +} + +#upload .filelist div.file-panel span.rotateLeft:hover { + background-position: 0 0; +} + +#upload .filelist div.file-panel span.rotateRight { + display:none; + background-position: -24px -24px; +} + +#upload .filelist div.file-panel span.rotateRight:hover { + background-position: -24px 0; +} + +#upload .filelist div.file-panel span.cancel { + background-position: -48px -24px; +} + +#upload .filelist div.file-panel span.cancel:hover { + background-position: -48px 0; +} + +#upload .statusBar { + height: 45px; + border-bottom: 1px solid #dadada; + margin: 0 10px; + padding: 0; + line-height: 45px; + vertical-align: middle; + position: relative; +} + +#upload .statusBar .progress { + border: 1px solid #1483d8; + width: 198px; + background: #fff; + height: 18px; + position: absolute; + top: 12px; + display: none; + text-align: center; + line-height: 18px; + color: #6dbfff; + margin: 0 10px 0 0; +} +#upload .statusBar .progress span.percentage { + width: 0; + height: 100%; + left: 0; + top: 0; + background: #1483d8; + position: absolute; +} +#upload .statusBar .progress span.text { + position: relative; + z-index: 10; +} + +#upload .statusBar .info { + display: inline-block; + font-size: 14px; + color: #666666; +} + +#upload .statusBar .btns { + position: absolute; + top: 7px; + right: 0; + line-height: 30px; +} + +#filePickerBtn { + display: inline-block; + float: left; +} +#upload .statusBar .btns .webuploader-pick, +#upload .statusBar .btns .uploadBtn, +#upload .statusBar .btns .uploadBtn.state-uploading, +#upload .statusBar .btns .uploadBtn.state-paused { + background: #ffffff; + border: 1px solid #cfcfcf; + color: #565656; + padding: 0 18px; + display: inline-block; + border-radius: 3px; + margin-left: 10px; + cursor: pointer; + font-size: 14px; + float: left; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +#upload .statusBar .btns .webuploader-pick-hover, +#upload .statusBar .btns .uploadBtn:hover, +#upload .statusBar .btns .uploadBtn.state-uploading:hover, +#upload .statusBar .btns .uploadBtn.state-paused:hover { + background: #f0f0f0; +} + +#upload .statusBar .btns .uploadBtn, +#upload .statusBar .btns .uploadBtn.state-paused{ + background: #00b7ee; + color: #fff; + border-color: transparent; +} +#upload .statusBar .btns .uploadBtn:hover, +#upload .statusBar .btns .uploadBtn.state-paused:hover{ + background: #00a2d4; +} + +#upload .statusBar .btns .uploadBtn.disabled { + pointer-events: none; + filter:alpha(opacity=60); + -moz-opacity:0.6; + -khtml-opacity: 0.6; + opacity: 0.6; +} + + + +/* 图片管理样式 */ +#online { + width: 100%; + height: 336px; + padding: 10px 0 0 0; +} +#online #fileList{ + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + position: relative; +} +#online ul { + display: block; + list-style: none; + margin: 0; + padding: 0; +} +#online li { + float: left; + display: block; + list-style: none; + padding: 0; + width: 113px; + height: 113px; + margin: 0 0 9px 9px; + *margin: 0 0 6px 6px; + background-color: #eee; + overflow: hidden; + cursor: pointer; + position: relative; +} +#online li.clearFloat { + float: none; + clear: both; + display: block; + width:0; + height:0; + margin: 0; + padding: 0; +} +#online li img { + cursor: pointer; +} +#online li div.file-wrapper { + cursor: pointer; + position: absolute; + display: block; + width: 111px; + height: 111px; + border: 1px solid #eee; + background: url("./images/bg.png") repeat; +} +#online li div span.file-title{ + display: block; + padding: 0 3px; + margin: 3px 0 0 0; + font-size: 12px; + height: 13px; + color: #555555; + text-align: center; + width: 107px; + white-space: nowrap; + word-break: break-all; + overflow: hidden; + text-overflow: ellipsis; +} +#online li .icon { + cursor: pointer; + width: 113px; + height: 113px; + position: absolute; + top: 0; + left: 0; + z-index: 2; + border: 0; + background-repeat: no-repeat; +} +#online li .icon:hover { + width: 107px; + height: 107px; + border: 3px solid #1094fa; +} +#online li.selected .icon { + background-image: url(images/success.png); + background-image: url(images/success.gif) \9; + background-position: 75px 75px; +} +#online li.selected .icon:hover { + width: 107px; + height: 107px; + border: 3px solid #1094fa; + background-position: 72px 72px; +} + + +/* 在线文件的文件预览图标 */ +i.file-preview { + display: block; + margin: 10px auto; + width: 70px; + height: 70px; + background-image: url("./images/file-icons.png"); + background-image: url("./images/file-icons.gif") \9; + background-position: -140px center; + background-repeat: no-repeat; +} +i.file-preview.file-type-dir{ + background-position: 0 center; +} +i.file-preview.file-type-file{ + background-position: -140px center; +} +i.file-preview.file-type-filelist{ + background-position: -210px center; +} +i.file-preview.file-type-zip, +i.file-preview.file-type-rar, +i.file-preview.file-type-7z, +i.file-preview.file-type-tar, +i.file-preview.file-type-gz, +i.file-preview.file-type-bz2{ + background-position: -280px center; +} +i.file-preview.file-type-xls, +i.file-preview.file-type-xlsx{ + background-position: -350px center; +} +i.file-preview.file-type-doc, +i.file-preview.file-type-docx{ + background-position: -420px center; +} +i.file-preview.file-type-ppt, +i.file-preview.file-type-pptx{ + background-position: -490px center; +} +i.file-preview.file-type-vsd{ + background-position: -560px center; +} +i.file-preview.file-type-pdf{ + background-position: -630px center; +} +i.file-preview.file-type-txt, +i.file-preview.file-type-md, +i.file-preview.file-type-json, +i.file-preview.file-type-htm, +i.file-preview.file-type-xml, +i.file-preview.file-type-html, +i.file-preview.file-type-js, +i.file-preview.file-type-css, +i.file-preview.file-type-php, +i.file-preview.file-type-jsp, +i.file-preview.file-type-asp{ + background-position: -700px center; +} +i.file-preview.file-type-apk{ + background-position: -770px center; +} +i.file-preview.file-type-exe{ + background-position: -840px center; +} +i.file-preview.file-type-ipa{ + background-position: -910px center; +} +i.file-preview.file-type-mp4, +i.file-preview.file-type-swf, +i.file-preview.file-type-mkv, +i.file-preview.file-type-avi, +i.file-preview.file-type-flv, +i.file-preview.file-type-mov, +i.file-preview.file-type-mpg, +i.file-preview.file-type-mpeg, +i.file-preview.file-type-ogv, +i.file-preview.file-type-webm, +i.file-preview.file-type-rm, +i.file-preview.file-type-rmvb{ + background-position: -980px center; +} +i.file-preview.file-type-ogg, +i.file-preview.file-type-wav, +i.file-preview.file-type-wmv, +i.file-preview.file-type-mid, +i.file-preview.file-type-mp3{ + background-position: -1050px center; +} +i.file-preview.file-type-jpg, +i.file-preview.file-type-jpeg, +i.file-preview.file-type-gif, +i.file-preview.file-type-bmp, +i.file-preview.file-type-png, +i.file-preview.file-type-psd{ + background-position: -140px center; +} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/attachment.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/attachment.html new file mode 100644 index 000000000..2ae928202 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/attachment.html @@ -0,0 +1,60 @@ + + + + + ueditor图片对话框 + + + + + + + + + + + + + + +
          +
          + + +
          +
          + +
          +
          +
          +
          + 0% + +
          +
          +
          +
          +
          +
          +
          +
          +
          +
          +
          +
            +
          • +
          +
          +
          + + +
          +
          +
          + +
          +
          + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/attachment.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/attachment.js new file mode 100644 index 000000000..ce3be633d --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/attachment.js @@ -0,0 +1,754 @@ +/** + * User: Jinqn + * Date: 14-04-08 + * Time: 下午16:34 + * 上传图片对话框逻辑代码,包括tab: 远程图片/上传图片/在线图片/搜索图片 + */ + +(function () { + + var uploadFile, + onlineFile; + + window.onload = function () { + initTabs(); + initButtons(); + }; + + /* 初始化tab标签 */ + function initTabs() { + var tabs = $G('tabhead').children; + for (var i = 0; i < tabs.length; i++) { + domUtils.on(tabs[i], "click", function (e) { + var target = e.target || e.srcElement; + setTabFocus(target.getAttribute('data-content-id')); + }); + } + + setTabFocus('upload'); + } + + /* 初始化tabbody */ + function setTabFocus(id) { + if(!id) return; + var i, bodyId, tabs = $G('tabhead').children; + for (i = 0; i < tabs.length; i++) { + bodyId = tabs[i].getAttribute('data-content-id') + if (bodyId == id) { + domUtils.addClass(tabs[i], 'focus'); + domUtils.addClass($G(bodyId), 'focus'); + } else { + domUtils.removeClasses(tabs[i], 'focus'); + domUtils.removeClasses($G(bodyId), 'focus'); + } + } + switch (id) { + case 'upload': + uploadFile = uploadFile || new UploadFile('queueList'); + break; + case 'online': + onlineFile = onlineFile || new OnlineFile('fileList'); + break; + } + } + + /* 初始化onok事件 */ + function initButtons() { + + dialog.onok = function () { + var list = [], id, tabs = $G('tabhead').children; + for (var i = 0; i < tabs.length; i++) { + if (domUtils.hasClass(tabs[i], 'focus')) { + id = tabs[i].getAttribute('data-content-id'); + break; + } + } + + switch (id) { + case 'upload': + list = uploadFile.getInsertList(); + var count = uploadFile.getQueueCount(); + if (count) { + $('.info', '#queueList').html('' + '还有2个未上传文件'.replace(/[\d]/, count) + ''); + return false; + } + break; + case 'online': + list = onlineFile.getInsertList(); + break; + } + + editor.execCommand('insertfile', list); + }; + } + + + /* 上传附件 */ + function UploadFile(target) { + this.$wrap = target.constructor == String ? $('#' + target) : $(target); + this.init(); + } + UploadFile.prototype = { + init: function () { + this.fileList = []; + this.initContainer(); + this.initUploader(); + }, + initContainer: function () { + this.$queue = this.$wrap.find('.filelist'); + }, + /* 初始化容器 */ + initUploader: function () { + var _this = this, + $ = jQuery, // just in case. Make sure it's not an other libaray. + $wrap = _this.$wrap, + // 图片容器 + $queue = $wrap.find('.filelist'), + // 状态栏,包括进度和控制按钮 + $statusBar = $wrap.find('.statusBar'), + // 文件总体选择信息。 + $info = $statusBar.find('.info'), + // 上传按钮 + $upload = $wrap.find('.uploadBtn'), + // 上传按钮 + $filePickerBtn = $wrap.find('.filePickerBtn'), + // 上传按钮 + $filePickerBlock = $wrap.find('.filePickerBlock'), + // 没选择文件之前的内容。 + $placeHolder = $wrap.find('.placeholder'), + // 总体进度条 + $progress = $statusBar.find('.progress').hide(), + // 添加的文件数量 + fileCount = 0, + // 添加的文件总大小 + fileSize = 0, + // 优化retina, 在retina下这个值是2 + ratio = window.devicePixelRatio || 1, + // 缩略图大小 + thumbnailWidth = 113 * ratio, + thumbnailHeight = 113 * ratio, + // 可能有pedding, ready, uploading, confirm, done. + state = '', + // 所有文件的进度信息,key为file id + percentages = {}, + supportTransition = (function () { + var s = document.createElement('p').style, + r = 'transition' in s || + 'WebkitTransition' in s || + 'MozTransition' in s || + 'msTransition' in s || + 'OTransition' in s; + s = null; + return r; + })(), + // WebUploader实例 + uploader, + actionUrl = editor.getActionUrl(editor.getOpt('fileActionName')), + fileMaxSize = editor.getOpt('fileMaxSize'), + acceptExtensions = (editor.getOpt('fileAllowFiles') || []).join('').replace(/\./g, ',').replace(/^[,]/, '');; + + if (!WebUploader.Uploader.support()) { + $('#filePickerReady').after($('
          ').html(lang.errorNotSupport)).hide(); + return; + } else if (!editor.getOpt('fileActionName')) { + $('#filePickerReady').after($('
          ').html(lang.errorLoadConfig)).hide(); + return; + } + + uploader = _this.uploader = WebUploader.create({ + pick: { + id: '#filePickerReady', + label: lang.uploadSelectFile + }, + swf: '../../third-party/webuploader/Uploader.swf', + server: actionUrl, + fileVal: editor.getOpt('fileFieldName'), + duplicate: true, + fileSingleSizeLimit: fileMaxSize, + compress: false + }); + uploader.addButton({ + id: '#filePickerBlock' + }); + uploader.addButton({ + id: '#filePickerBtn', + label: lang.uploadAddFile + }); + + setState('pedding'); + + // 当有文件添加进来时执行,负责view的创建 + function addFile(file) { + var $li = $('
        • ' + + '

          ' + file.name + '

          ' + + '

          ' + + '

          ' + + '
        • '), + + $btns = $('
          ' + + '' + lang.uploadDelete + '' + + '' + lang.uploadTurnRight + '' + + '' + lang.uploadTurnLeft + '
          ').appendTo($li), + $prgress = $li.find('p.progress span'), + $wrap = $li.find('p.imgWrap'), + $info = $('

          ').hide().appendTo($li), + + showError = function (code) { + switch (code) { + case 'exceed_size': + text = lang.errorExceedSize; + break; + case 'interrupt': + text = lang.errorInterrupt; + break; + case 'http': + text = lang.errorHttp; + break; + case 'not_allow_type': + text = lang.errorFileType; + break; + default: + text = lang.errorUploadRetry; + break; + } + $info.text(text).show(); + }; + + if (file.getStatus() === 'invalid') { + showError(file.statusText); + } else { + $wrap.text(lang.uploadPreview); + if ('|png|jpg|jpeg|bmp|gif|'.indexOf('|'+file.ext.toLowerCase()+'|') == -1) { + $wrap.empty().addClass('notimage').append('' + + '' + file.name + ''); + } else { + if (browser.ie && browser.version <= 7) { + $wrap.text(lang.uploadNoPreview); + } else { + uploader.makeThumb(file, function (error, src) { + if (error || !src) { + $wrap.text(lang.uploadNoPreview); + } else { + var $img = $(''); + $wrap.empty().append($img); + $img.on('error', function () { + $wrap.text(lang.uploadNoPreview); + }); + } + }, thumbnailWidth, thumbnailHeight); + } + } + percentages[ file.id ] = [ file.size, 0 ]; + file.rotation = 0; + + /* 检查文件格式 */ + if (!file.ext || acceptExtensions.indexOf(file.ext.toLowerCase()) == -1) { + showError('not_allow_type'); + uploader.removeFile(file); + } + } + + file.on('statuschange', function (cur, prev) { + if (prev === 'progress') { + $prgress.hide().width(0); + } else if (prev === 'queued') { + $li.off('mouseenter mouseleave'); + $btns.remove(); + } + // 成功 + if (cur === 'error' || cur === 'invalid') { + showError(file.statusText); + percentages[ file.id ][ 1 ] = 1; + } else if (cur === 'interrupt') { + showError('interrupt'); + } else if (cur === 'queued') { + percentages[ file.id ][ 1 ] = 0; + } else if (cur === 'progress') { + $info.hide(); + $prgress.css('display', 'block'); + } else if (cur === 'complete') { + } + + $li.removeClass('state-' + prev).addClass('state-' + cur); + }); + + $li.on('mouseenter', function () { + $btns.stop().animate({height: 30}); + }); + $li.on('mouseleave', function () { + $btns.stop().animate({height: 0}); + }); + + $btns.on('click', 'span', function () { + var index = $(this).index(), + deg; + + switch (index) { + case 0: + uploader.removeFile(file); + return; + case 1: + file.rotation += 90; + break; + case 2: + file.rotation -= 90; + break; + } + + if (supportTransition) { + deg = 'rotate(' + file.rotation + 'deg)'; + $wrap.css({ + '-webkit-transform': deg, + '-mos-transform': deg, + '-o-transform': deg, + 'transform': deg + }); + } else { + $wrap.css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + (~~((file.rotation / 90) % 4 + 4) % 4) + ')'); + } + + }); + + $li.insertBefore($filePickerBlock); + } + + // 负责view的销毁 + function removeFile(file) { + var $li = $('#' + file.id); + delete percentages[ file.id ]; + updateTotalProgress(); + $li.off().find('.file-panel').off().end().remove(); + } + + function updateTotalProgress() { + var loaded = 0, + total = 0, + spans = $progress.children(), + percent; + + $.each(percentages, function (k, v) { + total += v[ 0 ]; + loaded += v[ 0 ] * v[ 1 ]; + }); + + percent = total ? loaded / total : 0; + + spans.eq(0).text(Math.round(percent * 100) + '%'); + spans.eq(1).css('width', Math.round(percent * 100) + '%'); + updateStatus(); + } + + function setState(val, files) { + + if (val != state) { + + var stats = uploader.getStats(); + + $upload.removeClass('state-' + state); + $upload.addClass('state-' + val); + + switch (val) { + + /* 未选择文件 */ + case 'pedding': + $queue.addClass('element-invisible'); + $statusBar.addClass('element-invisible'); + $placeHolder.removeClass('element-invisible'); + $progress.hide(); $info.hide(); + uploader.refresh(); + break; + + /* 可以开始上传 */ + case 'ready': + $placeHolder.addClass('element-invisible'); + $queue.removeClass('element-invisible'); + $statusBar.removeClass('element-invisible'); + $progress.hide(); $info.show(); + $upload.text(lang.uploadStart); + uploader.refresh(); + break; + + /* 上传中 */ + case 'uploading': + $progress.show(); $info.hide(); + $upload.text(lang.uploadPause); + break; + + /* 暂停上传 */ + case 'paused': + $progress.show(); $info.hide(); + $upload.text(lang.uploadContinue); + break; + + case 'confirm': + $progress.show(); $info.hide(); + $upload.text(lang.uploadStart); + + stats = uploader.getStats(); + if (stats.successNum && !stats.uploadFailNum) { + setState('finish'); + return; + } + break; + + case 'finish': + $progress.hide(); $info.show(); + if (stats.uploadFailNum) { + $upload.text(lang.uploadRetry); + } else { + $upload.text(lang.uploadStart); + } + break; + } + + state = val; + updateStatus(); + + } + + if (!_this.getQueueCount()) { + $upload.addClass('disabled') + } else { + $upload.removeClass('disabled') + } + + } + + function updateStatus() { + var text = '', stats; + + if (state === 'ready') { + text = lang.updateStatusReady.replace('_', fileCount).replace('_KB', WebUploader.formatSize(fileSize)); + } else if (state === 'confirm') { + stats = uploader.getStats(); + if (stats.uploadFailNum) { + text = lang.updateStatusConfirm.replace('_', stats.successNum).replace('_', stats.successNum); + } + } else { + stats = uploader.getStats(); + text = lang.updateStatusFinish.replace('_', fileCount). + replace('_KB', WebUploader.formatSize(fileSize)). + replace('_', stats.successNum); + + if (stats.uploadFailNum) { + text += lang.updateStatusError.replace('_', stats.uploadFailNum); + } + } + + $info.html(text); + } + + uploader.on('fileQueued', function (file) { + fileCount++; + fileSize += file.size; + + if (fileCount === 1) { + $placeHolder.addClass('element-invisible'); + $statusBar.show(); + } + + addFile(file); + }); + + uploader.on('fileDequeued', function (file) { + fileCount--; + fileSize -= file.size; + + removeFile(file); + updateTotalProgress(); + }); + + uploader.on('filesQueued', function (file) { + if (!uploader.isInProgress() && (state == 'pedding' || state == 'finish' || state == 'confirm' || state == 'ready')) { + setState('ready'); + } + updateTotalProgress(); + }); + + uploader.on('all', function (type, files) { + switch (type) { + case 'uploadFinished': + setState('confirm', files); + break; + case 'startUpload': + /* 添加额外的GET参数 */ + var params = utils.serializeParam(editor.queryCommandValue('serverparam')) || '', + url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?':'&') + 'encode=utf-8&' + params); + uploader.option('server', url); + setState('uploading', files); + break; + case 'stopUpload': + setState('paused', files); + break; + } + }); + + uploader.on('uploadBeforeSend', function (file, data, header) { + //这里可以通过data对象添加POST参数 + header['X_Requested_With'] = 'XMLHttpRequest'; + }); + + uploader.on('uploadProgress', function (file, percentage) { + var $li = $('#' + file.id), + $percent = $li.find('.progress span'); + + $percent.css('width', percentage * 100 + '%'); + percentages[ file.id ][ 1 ] = percentage; + updateTotalProgress(); + }); + + uploader.on('uploadSuccess', function (file, ret) { + var $file = $('#' + file.id); + try { + var responseText = (ret._raw || ret), + json = utils.str2json(responseText); + if (json.state == 'SUCCESS') { + _this.fileList.push(json); + $file.append(''); + } else { + $file.find('.error').text(json.state).show(); + } + } catch (e) { + $file.find('.error').text(lang.errorServerUpload).show(); + } + }); + + uploader.on('uploadError', function (file, code) { + }); + uploader.on('error', function (code, file) { + if (code == 'Q_TYPE_DENIED' || code == 'F_EXCEED_SIZE') { + addFile(file); + } + }); + uploader.on('uploadComplete', function (file, ret) { + }); + + $upload.on('click', function () { + if ($(this).hasClass('disabled')) { + return false; + } + + if (state === 'ready') { + uploader.upload(); + } else if (state === 'paused') { + uploader.upload(); + } else if (state === 'uploading') { + uploader.stop(); + } + }); + + $upload.addClass('state-' + state); + updateTotalProgress(); + }, + getQueueCount: function () { + var file, i, status, readyFile = 0, files = this.uploader.getFiles(); + for (i = 0; file = files[i++]; ) { + status = file.getStatus(); + if (status == 'queued' || status == 'uploading' || status == 'progress') readyFile++; + } + return readyFile; + }, + getInsertList: function () { + var i, link, data, list = [], + prefix = editor.getOpt('fileUrlPrefix'); + for (i = 0; i < this.fileList.length; i++) { + data = this.fileList[i]; + link = data.url; + list.push({ + title: data.original || link.substr(link.lastIndexOf('/') + 1), + url: prefix + link + }); + } + return list; + } + }; + + + /* 在线附件 */ + function OnlineFile(target) { + this.container = utils.isString(target) ? document.getElementById(target) : target; + this.init(); + } + OnlineFile.prototype = { + init: function () { + this.initContainer(); + this.initEvents(); + this.initData(); + }, + /* 初始化容器 */ + initContainer: function () { + this.container.innerHTML = ''; + this.list = document.createElement('ul'); + this.clearFloat = document.createElement('li'); + + domUtils.addClass(this.list, 'list'); + domUtils.addClass(this.clearFloat, 'clearFloat'); + + this.list.appendChild(this.clearFloat); + this.container.appendChild(this.list); + }, + /* 初始化滚动事件,滚动到地步自动拉取数据 */ + initEvents: function () { + var _this = this; + + /* 滚动拉取图片 */ + domUtils.on($G('fileList'), 'scroll', function(e){ + var panel = this; + if (panel.scrollHeight - (panel.offsetHeight + panel.scrollTop) < 10) { + _this.getFileData(); + } + }); + /* 选中图片 */ + domUtils.on(this.list, 'click', function (e) { + var target = e.target || e.srcElement, + li = target.parentNode; + + if (li.tagName.toLowerCase() == 'li') { + if (domUtils.hasClass(li, 'selected')) { + domUtils.removeClasses(li, 'selected'); + } else { + domUtils.addClass(li, 'selected'); + } + } + }); + }, + /* 初始化第一次的数据 */ + initData: function () { + + /* 拉取数据需要使用的值 */ + this.state = 0; + this.listSize = editor.getOpt('fileManagerListSize'); + this.listIndex = 0; + this.listEnd = false; + + /* 第一次拉取数据 */ + this.getFileData(); + }, + /* 向后台拉取图片列表数据 */ + getFileData: function () { + var _this = this; + + if(!_this.listEnd && !this.isLoadingData) { + this.isLoadingData = true; + ajax.request(editor.getActionUrl(editor.getOpt('fileManagerActionName')), { + timeout: 100000, + data: utils.extend({ + start: this.listIndex, + size: this.listSize + }, editor.queryCommandValue('serverparam')), + method: 'get', + onsuccess: function (r) { + try { + var json = eval('(' + r.responseText + ')'); + if (json.state == 'SUCCESS') { + _this.pushData(json.list); + _this.listIndex = parseInt(json.start) + parseInt(json.list.length); + if(_this.listIndex >= json.total) { + _this.listEnd = true; + } + _this.isLoadingData = false; + } + } catch (e) { + if(r.responseText.indexOf('ue_separate_ue') != -1) { + var list = r.responseText.split(r.responseText); + _this.pushData(list); + _this.listIndex = parseInt(list.length); + _this.listEnd = true; + _this.isLoadingData = false; + } + } + }, + onerror: function () { + _this.isLoadingData = false; + } + }); + } + }, + /* 添加图片到列表界面上 */ + pushData: function (list) { + var i, item, img, filetype, preview, icon, _this = this, + urlPrefix = editor.getOpt('fileManagerUrlPrefix'); + for (i = 0; i < list.length; i++) { + if(list[i] && list[i].url) { + item = document.createElement('li'); + icon = document.createElement('span'); + filetype = list[i].url.substr(list[i].url.lastIndexOf('.') + 1); + + if ( "png|jpg|jpeg|gif|bmp".indexOf(filetype) != -1 ) { + preview = document.createElement('img'); + domUtils.on(preview, 'load', (function(image){ + return function(){ + _this.scale(image, image.parentNode.offsetWidth, image.parentNode.offsetHeight); + }; + })(preview)); + preview.width = 113; + preview.setAttribute('src', urlPrefix + list[i].url + (list[i].url.indexOf('?') == -1 ? '?noCache=':'&noCache=') + (+new Date()).toString(36) ); + } else { + var ic = document.createElement('i'), + textSpan = document.createElement('span'); + textSpan.innerHTML = list[i].url.substr(list[i].url.lastIndexOf('/') + 1); + preview = document.createElement('div'); + preview.appendChild(ic); + preview.appendChild(textSpan); + domUtils.addClass(preview, 'file-wrapper'); + domUtils.addClass(textSpan, 'file-title'); + domUtils.addClass(ic, 'file-type-' + filetype); + domUtils.addClass(ic, 'file-preview'); + } + domUtils.addClass(icon, 'icon'); + item.setAttribute('data-url', urlPrefix + list[i].url); + if (list[i].original) { + item.setAttribute('data-title', list[i].original); + } + + item.appendChild(preview); + item.appendChild(icon); + this.list.insertBefore(item, this.clearFloat); + } + } + }, + /* 改变图片大小 */ + scale: function (img, w, h, type) { + var ow = img.width, + oh = img.height; + + if (type == 'justify') { + if (ow >= oh) { + img.width = w; + img.height = h * oh / ow; + img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px'; + } else { + img.width = w * ow / oh; + img.height = h; + img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px'; + } + } else { + if (ow >= oh) { + img.width = w * ow / oh; + img.height = h; + img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px'; + } else { + img.width = w; + img.height = h * oh / ow; + img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px'; + } + } + }, + getInsertList: function () { + var i, lis = this.list.children, list = []; + for (i = 0; i < lis.length; i++) { + if (domUtils.hasClass(lis[i], 'selected')) { + var url = lis[i].getAttribute('data-url'); + var title = lis[i].getAttribute('data-title') || url.substr(url.lastIndexOf('/') + 1); + list.push({ + title: title, + url: url + }); + } + } + return list; + } + }; + + +})(); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_chm.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_chm.gif new file mode 100644 index 000000000..9ca4fb6a2 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_chm.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_default.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_default.png new file mode 100644 index 000000000..50ac1cb16 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_default.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_doc.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_doc.gif new file mode 100644 index 000000000..206fede4e Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_doc.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_exe.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_exe.gif new file mode 100644 index 000000000..2e3b7a28e Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_exe.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_jpg.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_jpg.gif new file mode 100644 index 000000000..5d5dec026 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_jpg.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_mp3.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_mp3.gif new file mode 100644 index 000000000..b351a1f2a Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_mp3.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_mv.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_mv.gif new file mode 100644 index 000000000..26019b099 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_mv.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_pdf.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_pdf.gif new file mode 100644 index 000000000..bbb65c837 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_pdf.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_ppt.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_ppt.gif new file mode 100644 index 000000000..ccb26fbeb Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_ppt.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_psd.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_psd.gif new file mode 100644 index 000000000..2e8743a27 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_psd.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_rar.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_rar.gif new file mode 100644 index 000000000..5359e46d2 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_rar.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_txt.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_txt.gif new file mode 100644 index 000000000..e7b8dd21d Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_txt.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_xls.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_xls.gif new file mode 100644 index 000000000..e86c1c663 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/fileTypeImages/icon_xls.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/alignicon.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/alignicon.gif new file mode 100644 index 000000000..005a5ac65 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/alignicon.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/alignicon.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/alignicon.png new file mode 100644 index 000000000..4b6c444b7 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/alignicon.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/bg.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/bg.png new file mode 100644 index 000000000..580be0a01 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/bg.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/file-icons.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/file-icons.gif new file mode 100644 index 000000000..d8c02c27e Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/file-icons.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/file-icons.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/file-icons.png new file mode 100644 index 000000000..3ff82c8c4 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/file-icons.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/icons.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/icons.gif new file mode 100644 index 000000000..78459dea7 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/icons.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/icons.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/icons.png new file mode 100644 index 000000000..12e470016 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/icons.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/image.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/image.png new file mode 100644 index 000000000..19699f6a9 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/image.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/progress.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/progress.png new file mode 100644 index 000000000..717c4865c Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/progress.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/success.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/success.gif new file mode 100644 index 000000000..8d4f3112b Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/success.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/success.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/success.png new file mode 100644 index 000000000..94f968dc8 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/attachment/images/success.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/background/background.css b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/background/background.css new file mode 100644 index 000000000..5c41fe9a4 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/background/background.css @@ -0,0 +1,94 @@ +.wrapper{ width: 424px;margin: 10px auto; zoom:1;position: relative} +.tabbody{height:225px;} +.tabbody .panel { position: absolute;width:100%; height:100%;background: #fff; display: none;} +.tabbody .focus { display: block;} + +body{font-size: 12px;color: #888;overflow: hidden;} +input,label{vertical-align:middle} +.clear{clear: both;} +.pl{padding-left: 18px;padding-left: 23px\9;} + +#imageList {width: 420px;height: 215px;margin-top: 10px;overflow: hidden;overflow-y: auto;} +#imageList div {float: left;width: 100px;height: 95px;margin: 5px 10px;} +#imageList img {cursor: pointer;border: 2px solid white;} + +.bgarea{margin: 10px;padding: 5px;height: 84%;border: 1px solid #A8A297;} +.content div{margin: 10px 0 10px 5px;} +.content .iptradio{margin: 0px 5px 5px 0px;} +.txt{width:280px;} + +.wrapcolor{height: 19px;} +div.color{float: left;margin: 0;} +#colorPicker{width: 17px;height: 17px;border: 1px solid #CCC;display: inline-block;border-radius: 3px;box-shadow: 2px 2px 5px #D3D6DA;margin: 0;float: left;} +div.alignment,#custom{margin-left: 23px;margin-left: 28px\9;} +#custom input{height: 15px;min-height: 15px;width:20px;} +#repeatType{width:100px;} + + +/* 图片管理样式 */ +#imgManager { + width: 100%; + height: 225px; +} +#imgManager #imageList{ + width: 100%; + overflow-x: hidden; + overflow-y: auto; +} +#imgManager ul { + display: block; + list-style: none; + margin: 0; + padding: 0; +} +#imgManager li { + float: left; + display: block; + list-style: none; + padding: 0; + width: 113px; + height: 113px; + margin: 9px 0 0 19px; + background-color: #eee; + overflow: hidden; + cursor: pointer; + position: relative; +} +#imgManager li.clearFloat { + float: none; + clear: both; + display: block; + width:0; + height:0; + margin: 0; + padding: 0; +} +#imgManager li img { + cursor: pointer; +} +#imgManager li .icon { + cursor: pointer; + width: 113px; + height: 113px; + position: absolute; + top: 0; + left: 0; + z-index: 2; + border: 0; + background-repeat: no-repeat; +} +#imgManager li .icon:hover { + width: 107px; + height: 107px; + border: 3px solid #1094fa; +} +#imgManager li.selected .icon { + background-image: url(images/success.png); + background-position: 75px 75px; +} +#imgManager li.selected .icon:hover { + width: 107px; + height: 107px; + border: 3px solid #1094fa; + background-position: 72px 72px; +} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/background/background.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/background/background.html new file mode 100644 index 000000000..3cc2ac1ee --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/background/background.html @@ -0,0 +1,56 @@ + + + + + + + + +
          +
          + + +
          +
          +
          +
          + +
          +
          + + +
          +
          +
          + : +
          +
          +
          +
          +
          + +
          +
          + : +
          +
          + :x:px  y:px +
          +
          +
          + +
          +
          +
          +
          +
          +
          + + + diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/background/background.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/background/background.js new file mode 100644 index 000000000..9a4a1315d --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/background/background.js @@ -0,0 +1,376 @@ +(function () { + + var onlineImage, + backupStyle = editor.queryCommandValue('background'); + + window.onload = function () { + initTabs(); + initColorSelector(); + }; + + /* 初始化tab标签 */ + function initTabs(){ + var tabs = $G('tabHeads').children; + for (var i = 0; i < tabs.length; i++) { + domUtils.on(tabs[i], "click", function (e) { + var target = e.target || e.srcElement; + for (var j = 0; j < tabs.length; j++) { + if(tabs[j] == target){ + tabs[j].className = "focus"; + var contentId = tabs[j].getAttribute('data-content-id'); + $G(contentId).style.display = "block"; + if(contentId == 'imgManager') { + initImagePanel(); + } + }else { + tabs[j].className = ""; + $G(tabs[j].getAttribute('data-content-id')).style.display = "none"; + } + } + }); + } + } + + /* 初始化颜色设置 */ + function initColorSelector () { + var obj = editor.queryCommandValue('background'); + if (obj) { + var color = obj['background-color'], + repeat = obj['background-repeat'] || 'repeat', + image = obj['background-image'] || '', + position = obj['background-position'] || 'center center', + pos = position.split(' '), + x = parseInt(pos[0]) || 0, + y = parseInt(pos[1]) || 0; + + if(repeat == 'no-repeat' && (x || y)) repeat = 'self'; + + image = image.match(/url[\s]*\(([^\)]*)\)/); + image = image ? image[1]:''; + updateFormState('colored', color, image, repeat, x, y); + } else { + updateFormState(); + } + + var updateHandler = function () { + updateFormState(); + updateBackground(); + } + domUtils.on($G('nocolorRadio'), 'click', updateBackground); + domUtils.on($G('coloredRadio'), 'click', updateHandler); + domUtils.on($G('url'), 'keyup', function(){ + if($G('url').value && $G('alignment').style.display == "none") { + utils.each($G('repeatType').children, function(item){ + item.selected = ('repeat' == item.getAttribute('value') ? 'selected':false); + }); + } + updateHandler(); + }); + domUtils.on($G('repeatType'), 'change', updateHandler); + domUtils.on($G('x'), 'keyup', updateBackground); + domUtils.on($G('y'), 'keyup', updateBackground); + + initColorPicker(); + } + + /* 初始化颜色选择器 */ + function initColorPicker() { + var me = editor, + cp = $G("colorPicker"); + + /* 生成颜色选择器ui对象 */ + var popup = new UE.ui.Popup({ + content: new UE.ui.ColorPicker({ + noColorText: me.getLang("clearColor"), + editor: me, + onpickcolor: function (t, color) { + updateFormState('colored', color); + updateBackground(); + UE.ui.Popup.postHide(); + }, + onpicknocolor: function (t, color) { + updateFormState('colored', 'transparent'); + updateBackground(); + UE.ui.Popup.postHide(); + } + }), + editor: me, + onhide: function () { + } + }); + + /* 设置颜色选择器 */ + domUtils.on(cp, "click", function () { + popup.showAnchor(this); + }); + domUtils.on(document, 'mousedown', function (evt) { + var el = evt.target || evt.srcElement; + UE.ui.Popup.postHide(el); + }); + domUtils.on(window, 'scroll', function () { + UE.ui.Popup.postHide(); + }); + } + + /* 初始化在线图片列表 */ + function initImagePanel() { + onlineImage = onlineImage || new OnlineImage('imageList'); + } + + /* 更新背景色设置面板 */ + function updateFormState (radio, color, url, align, x, y) { + var nocolorRadio = $G('nocolorRadio'), + coloredRadio = $G('coloredRadio'); + + if(radio) { + nocolorRadio.checked = (radio == 'colored' ? false:'checked'); + coloredRadio.checked = (radio == 'colored' ? 'checked':false); + } + if(color) { + domUtils.setStyle($G("colorPicker"), "background-color", color); + } + + if(url && /^\//.test(url)) { + var a = document.createElement('a'); + a.href = url; + browser.ie && (a.href = a.href); + url = browser.ie ? a.href:(a.protocol + '//' + a.host + a.pathname + a.search + a.hash); + } + + if(url || url === '') { + $G('url').value = url; + } + if(align) { + utils.each($G('repeatType').children, function(item){ + item.selected = (align == item.getAttribute('value') ? 'selected':false); + }); + } + if(x || y) { + $G('x').value = parseInt(x) || 0; + $G('y').value = parseInt(y) || 0; + } + + $G('alignment').style.display = coloredRadio.checked && $G('url').value ? '':'none'; + $G('custom').style.display = coloredRadio.checked && $G('url').value && $G('repeatType').value == 'self' ? '':'none'; + } + + /* 更新背景颜色 */ + function updateBackground () { + if ($G('coloredRadio').checked) { + var color = domUtils.getStyle($G("colorPicker"), "background-color"), + bgimg = $G("url").value, + align = $G("repeatType").value, + backgroundObj = { + "background-repeat": "no-repeat", + "background-position": "center center" + }; + + if (color) backgroundObj["background-color"] = color; + if (bgimg) backgroundObj["background-image"] = 'url(' + bgimg + ')'; + if (align == 'self') { + backgroundObj["background-position"] = $G("x").value + "px " + $G("y").value + "px"; + } else if (align == 'repeat-x' || align == 'repeat-y' || align == 'repeat') { + backgroundObj["background-repeat"] = align; + } + + editor.execCommand('background', backgroundObj); + } else { + editor.execCommand('background', null); + } + } + + + /* 在线图片 */ + function OnlineImage(target) { + this.container = utils.isString(target) ? document.getElementById(target) : target; + this.init(); + } + OnlineImage.prototype = { + init: function () { + this.reset(); + this.initEvents(); + }, + /* 初始化容器 */ + initContainer: function () { + this.container.innerHTML = ''; + this.list = document.createElement('ul'); + this.clearFloat = document.createElement('li'); + + domUtils.addClass(this.list, 'list'); + domUtils.addClass(this.clearFloat, 'clearFloat'); + + this.list.id = 'imageListUl'; + this.list.appendChild(this.clearFloat); + this.container.appendChild(this.list); + }, + /* 初始化滚动事件,滚动到地步自动拉取数据 */ + initEvents: function () { + var _this = this; + + /* 滚动拉取图片 */ + domUtils.on($G('imageList'), 'scroll', function(e){ + var panel = this; + if (panel.scrollHeight - (panel.offsetHeight + panel.scrollTop) < 10) { + _this.getImageData(); + } + }); + /* 选中图片 */ + domUtils.on(this.container, 'click', function (e) { + var target = e.target || e.srcElement, + li = target.parentNode, + nodes = $G('imageListUl').childNodes; + + if (li.tagName.toLowerCase() == 'li') { + updateFormState('nocolor', null, ''); + for (var i = 0, node; node = nodes[i++];) { + if (node == li && !domUtils.hasClass(node, 'selected')) { + domUtils.addClass(node, 'selected'); + updateFormState('colored', null, li.firstChild.getAttribute("_src"), 'repeat'); + } else { + domUtils.removeClasses(node, 'selected'); + } + } + updateBackground(); + } + }); + }, + /* 初始化第一次的数据 */ + initData: function () { + + /* 拉取数据需要使用的值 */ + this.state = 0; + this.listSize = editor.getOpt('imageManagerListSize'); + this.listIndex = 0; + this.listEnd = false; + + /* 第一次拉取数据 */ + this.getImageData(); + }, + /* 重置界面 */ + reset: function() { + this.initContainer(); + this.initData(); + }, + /* 向后台拉取图片列表数据 */ + getImageData: function () { + var _this = this; + + if(!_this.listEnd && !this.isLoadingData) { + this.isLoadingData = true; + var url = editor.getActionUrl(editor.getOpt('imageManagerActionName')), + isJsonp = utils.isCrossDomainUrl(url); + ajax.request(url, { + 'timeout': 100000, + 'dataType': isJsonp ? 'jsonp':'', + 'data': utils.extend({ + start: this.listIndex, + size: this.listSize + }, editor.queryCommandValue('serverparam')), + 'method': 'get', + 'onsuccess': function (r) { + try { + var json = isJsonp ? r:eval('(' + r.responseText + ')'); + if (json.state == 'SUCCESS') { + _this.pushData(json.list); + _this.listIndex = parseInt(json.start) + parseInt(json.list.length); + if(_this.listIndex >= json.total) { + _this.listEnd = true; + } + _this.isLoadingData = false; + } + } catch (e) { + if(r.responseText.indexOf('ue_separate_ue') != -1) { + var list = r.responseText.split(r.responseText); + _this.pushData(list); + _this.listIndex = parseInt(list.length); + _this.listEnd = true; + _this.isLoadingData = false; + } + } + }, + 'onerror': function () { + _this.isLoadingData = false; + } + }); + } + }, + /* 添加图片到列表界面上 */ + pushData: function (list) { + var i, item, img, icon, _this = this, + urlPrefix = editor.getOpt('imageManagerUrlPrefix'); + for (i = 0; i < list.length; i++) { + if(list[i] && list[i].url) { + item = document.createElement('li'); + img = document.createElement('img'); + icon = document.createElement('span'); + + domUtils.on(img, 'load', (function(image){ + return function(){ + _this.scale(image, image.parentNode.offsetWidth, image.parentNode.offsetHeight); + } + })(img)); + img.width = 113; + img.setAttribute('src', urlPrefix + list[i].url + (list[i].url.indexOf('?') == -1 ? '?noCache=':'&noCache=') + (+new Date()).toString(36) ); + img.setAttribute('_src', urlPrefix + list[i].url); + domUtils.addClass(icon, 'icon'); + + item.appendChild(img); + item.appendChild(icon); + this.list.insertBefore(item, this.clearFloat); + } + } + }, + /* 改变图片大小 */ + scale: function (img, w, h, type) { + var ow = img.width, + oh = img.height; + + if (type == 'justify') { + if (ow >= oh) { + img.width = w; + img.height = h * oh / ow; + img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px'; + } else { + img.width = w * ow / oh; + img.height = h; + img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px'; + } + } else { + if (ow >= oh) { + img.width = w * ow / oh; + img.height = h; + img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px'; + } else { + img.width = w; + img.height = h * oh / ow; + img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px'; + } + } + }, + getInsertList: function () { + var i, lis = this.list.children, list = [], align = getAlign(); + for (i = 0; i < lis.length; i++) { + if (domUtils.hasClass(lis[i], 'selected')) { + var img = lis[i].firstChild, + src = img.getAttribute('_src'); + list.push({ + src: src, + _src: src, + floatStyle: align + }); + } + + } + return list; + } + }; + + dialog.onok = function () { + updateBackground(); + editor.fireEvent('saveScene'); + }; + dialog.oncancel = function () { + editor.execCommand('background', backupStyle); + }; + +})(); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/background/images/bg.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/background/images/bg.png new file mode 100644 index 000000000..580be0a01 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/background/images/bg.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/background/images/success.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/background/images/success.png new file mode 100644 index 000000000..94f968dc8 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/background/images/success.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/chart.config.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/chart.config.js new file mode 100644 index 000000000..678b00deb --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/chart.config.js @@ -0,0 +1,65 @@ +/* + * 图表配置文件 + * */ + + +//不同类型的配置 +var typeConfig = [ + { + chart: { + type: 'line' + }, + plotOptions: { + line: { + dataLabels: { + enabled: false + }, + enableMouseTracking: true + } + } + }, { + chart: { + type: 'line' + }, + plotOptions: { + line: { + dataLabels: { + enabled: true + }, + enableMouseTracking: false + } + } + }, { + chart: { + type: 'area' + } + }, { + chart: { + type: 'bar' + } + }, { + chart: { + type: 'column' + } + }, { + chart: { + plotBackgroundColor: null, + plotBorderWidth: null, + plotShadow: false + }, + plotOptions: { + pie: { + allowPointSelect: true, + cursor: 'pointer', + dataLabels: { + enabled: true, + color: '#000000', + connectorColor: '#000000', + formatter: function() { + return ''+ this.point.name +': '+ ( Math.round( this.point.percentage*100 ) / 100 ) +' %'; + } + } + } + } + } +]; diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/charts.css b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/charts.css new file mode 100644 index 000000000..ac3c76458 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/charts.css @@ -0,0 +1,165 @@ +html, body { + width: 100%; + height: 100%; + margin: 0; + padding: 0; + overflow-x: hidden; +} + +.main { + width: 100%; + overflow: hidden; +} + +.table-view { + height: 100%; + float: left; + margin: 20px; + width: 40%; +} + +.table-view .table-container { + width: 100%; + margin-bottom: 50px; + overflow: scroll; +} + +.table-view th { + padding: 5px 10px; + background-color: #F7F7F7; +} + +.table-view td { + width: 50px; + text-align: center; + padding:0; +} + +.table-container input { + width: 40px; + padding: 5px; + border: none; + outline: none; +} + +.table-view caption { + font-size: 18px; + text-align: left; +} + +.charts-view { + /*margin-left: 49%!important;*/ + width: 50%; + margin-left: 49%; + height: 400px; +} + +.charts-container { + border-left: 1px solid #c3c3c3; +} + +.charts-format fieldset { + padding-left: 20px; + margin-bottom: 50px; +} + +.charts-format legend { + padding-left: 10px; + padding-right: 10px; +} + +.format-item-container { + padding: 20px; +} + +.format-item-container label { + display: block; + margin: 10px 0; +} + +.charts-format .data-item { + border: 1px solid black; + outline: none; + padding: 2px 3px; +} + +/* 图表类型 */ + +.charts-type { + margin-top: 50px; + height: 300px; +} + +.scroll-view { + border: 1px solid #c3c3c3; + border-left: none; + border-right: none; + overflow: hidden; +} + +.scroll-container { + margin: 20px; + width: 100%; + overflow: hidden; +} + +.scroll-bed { + width: 10000px; + _margin-top: 20px; + -webkit-transition: margin-left .5s ease; + -moz-transition: margin-left .5s ease; + transition: margin-left .5s ease; +} + +.view-box { + display: inline-block; + *display: inline; + *zoom: 1; + margin-right: 20px; + border: 2px solid white; + line-height: 0; + overflow: hidden; + cursor: pointer; +} + +.view-box img { + border: 1px solid #cecece; +} + +.view-box.selected { + border-color: #7274A7; +} + +.button-container { + margin-bottom: 20px; + text-align: center; +} + +.button-container a { + display: inline-block; + width: 100px; + height: 25px; + line-height: 25px; + border: 1px solid #c2ccd1; + margin-right: 30px; + text-decoration: none; + color: black; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; + border-radius: 2px; +} + +.button-container a:HOVER { + background: #fcfcfc; +} + +.button-container a:ACTIVE { + border-top-color: #c2ccd1; + box-shadow:inset 0 5px 4px -4px rgba(49, 49, 64, 0.1); +} + +.edui-charts-not-data { + height: 100px; + line-height: 100px; + text-align: center; +} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/charts.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/charts.html new file mode 100644 index 000000000..70e23149f --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/charts.html @@ -0,0 +1,89 @@ + + + + chart + + + + + +
          +
          +

          +
          +

          +
          +
          +
          + +
          + + +
          +
          +
          +
          + +
          + + + + +
          +
          +
          + +
          + +

          +
          +
          +
          + +
          + +

          +
          +
          +
          + +
          +
          +
          +
          +

          +
          +
          +
          +
          +
          + + +
          +
          +
          +
          +
          + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/charts.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/charts.js new file mode 100644 index 000000000..37344fd12 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/charts.js @@ -0,0 +1,519 @@ +/* + * 图片转换对话框脚本 + **/ + +var tableData = [], + //编辑器页面table + editorTable = null, + chartsConfig = window.typeConfig, + resizeTimer = null, + //初始默认图表类型 + currentChartType = 0; + +window.onload = function () { + + editorTable = domUtils.findParentByTagName( editor.selection.getRange().startContainer, 'table', true); + + //未找到表格, 显示错误页面 + if ( !editorTable ) { + document.body.innerHTML = "
          未找到数据
          "; + return; + } + + //初始化图表类型选择 + initChartsTypeView(); + renderTable( editorTable ); + initEvent(); + initUserConfig( editorTable.getAttribute( "data-chart" ) ); + $( "#scrollBed .view-box:eq("+ currentChartType +")" ).trigger( "click" ); + updateViewType( currentChartType ); + + dialog.addListener( "resize", function () { + + if ( resizeTimer != null ) { + window.clearTimeout( resizeTimer ); + } + + resizeTimer = window.setTimeout( function () { + + resizeTimer = null; + + renderCharts(); + + }, 500 ); + + } ); + +}; + +function initChartsTypeView () { + + var contents = []; + + for ( var i = 0, len = chartsConfig.length; i
          ' ); + + } + + $( "#scrollBed" ).html( contents.join( "" ) ); + +} + +//渲染table, 以便用户修改数据 +function renderTable ( table ) { + + var tableHtml = []; + + //构造数据 + for ( var i = 0, row; row = table.rows[ i ]; i++ ) { + + tableData[ i ] = []; + tableHtml[ i ] = []; + + for ( var j = 0, cell; cell = row.cells[ j ]; j++ ) { + + var value = getCellValue( cell ); + + if ( i > 0 && j > 0 ) { + value = +value; + } + + if ( i === 0 || j === 0 ) { + tableHtml[ i ].push( '
          ' ); + } else { + tableHtml[ i ].push( '' ); + } + + tableData[ i ][ j ] = value; + + } + + tableHtml[ i ] = tableHtml[ i ].join( "" ); + + } + + //draw 表格 + $( "#tableContainer" ).html( '
          '+ value +'
          '+ tableHtml.join( "" ) +'
          ' ); + +} + +/* + * 根据表格已有的图表属性初始化当前图表属性 + */ +function initUserConfig ( config ) { + + var parsedConfig = {}; + + if ( !config ) { + return; + } + + config = config.split( ";" ); + + $.each( config, function ( index, item ) { + + item = item.split( ":" ); + parsedConfig[ item[ 0 ] ] = item[ 1 ]; + + } ); + + setUserConfig( parsedConfig ); + +} + +function initEvent () { + + var cacheValue = null, + //图表类型数 + typeViewCount = chartsConfig.length- 1, + $chartsTypeViewBox = $( '#scrollBed .view-box' ); + + $( ".charts-format" ).delegate( ".format-ctrl", "change", function () { + + renderCharts(); + + } ) + + $( ".table-view" ).delegate( ".data-item", "focus", function () { + + cacheValue = this.value; + + } ).delegate( ".data-item", "blur", function () { + + if ( this.value !== cacheValue ) { + renderCharts(); + } + + cacheValue = null; + + } ); + + $( "#buttonContainer" ).delegate( "a", "click", function (e) { + + e.preventDefault(); + + if ( this.getAttribute( "data-title" ) === 'prev' ) { + + if ( currentChartType > 0 ) { + currentChartType--; + updateViewType( currentChartType ); + } + + } else { + + if ( currentChartType < typeViewCount ) { + currentChartType++; + updateViewType( currentChartType ); + } + + } + + } ); + + //图表类型变化 + $( '#scrollBed' ).delegate( ".view-box", "click", function (e) { + + var index = $( this ).attr( "data-chart-type" ); + $chartsTypeViewBox.removeClass( "selected" ); + $( $chartsTypeViewBox[ index ] ).addClass( "selected" ); + + currentChartType = index | 0; + + //饼图, 禁用部分配置 + if ( currentChartType === chartsConfig.length - 1 ) { + + disableNotPieConfig(); + + //启用完整配置 + } else { + + enableNotPieConfig(); + + } + + renderCharts(); + + } ); + +} + +function renderCharts () { + + var data = collectData(); + + $('#chartsContainer').highcharts( $.extend( {}, chartsConfig[ currentChartType ], { + + credits: { + enabled: false + }, + exporting: { + enabled: false + }, + title: { + text: data.title, + x: -20 //center + }, + subtitle: { + text: data.subTitle, + x: -20 + }, + xAxis: { + title: { + text: data.xTitle + }, + categories: data.categories + }, + yAxis: { + title: { + text: data.yTitle + }, + plotLines: [{ + value: 0, + width: 1, + color: '#808080' + }] + }, + tooltip: { + enabled: true, + valueSuffix: data.suffix + }, + legend: { + layout: 'vertical', + align: 'right', + verticalAlign: 'middle', + borderWidth: 1 + }, + series: data.series + + } )); + +} + +function updateViewType ( index ) { + + $( "#scrollBed" ).css( 'marginLeft', -index*324+'px' ); + +} + +function collectData () { + + var form = document.forms[ 'data-form' ], + data = null; + + if ( currentChartType !== chartsConfig.length - 1 ) { + + data = getSeriesAndCategories(); + $.extend( data, getUserConfig() ); + + //饼图数据格式 + } else { + data = getSeriesForPieChart(); + data.title = form[ 'title' ].value; + data.suffix = form[ 'unit' ].value; + } + + return data; + +} + +/** + * 获取用户配置信息 + */ +function getUserConfig () { + + var form = document.forms[ 'data-form' ], + info = { + title: form[ 'title' ].value, + subTitle: form[ 'sub-title' ].value, + xTitle: form[ 'x-title' ].value, + yTitle: form[ 'y-title' ].value, + suffix: form[ 'unit' ].value, + //数据对齐方式 + tableDataFormat: getTableDataFormat (), + //饼图提示文字 + tip: $( "#tipInput" ).val() + }; + + return info; + +} + +function setUserConfig ( config ) { + + var form = document.forms[ 'data-form' ]; + + config.title && ( form[ 'title' ].value = config.title ); + config.subTitle && ( form[ 'sub-title' ].value = config.subTitle ); + config.xTitle && ( form[ 'x-title' ].value = config.xTitle ); + config.yTitle && ( form[ 'y-title' ].value = config.yTitle ); + config.suffix && ( form[ 'unit' ].value = config.suffix ); + config.dataFormat == "-1" && ( form[ 'charts-format' ][ 1 ].checked = true ); + config.tip && ( form[ 'tip' ].value = config.tip ); + currentChartType = config.chartType || 0; + +} + +function getSeriesAndCategories () { + + var form = document.forms[ 'data-form' ], + series = [], + categories = [], + tmp = [], + tableData = getTableData(); + + //反转数据 + if ( getTableDataFormat() === "-1" ) { + + for ( var i = 0, len = tableData.length; i < len; i++ ) { + + for ( var j = 0, jlen = tableData[ i ].length; j < jlen; j++ ) { + + if ( !tmp[ j ] ) { + tmp[ j ] = []; + } + + tmp[ j ][ i ] = tableData[ i ][ j ]; + + } + + } + + tableData = tmp; + + } + + categories = tableData[0].slice( 1 ); + + for ( var i = 1, data; data = tableData[ i ]; i++ ) { + + series.push( { + name: data[ 0 ], + data: data.slice( 1 ) + } ); + + } + + return { + series: series, + categories: categories + }; + +} + +/* + * 获取数据源数据对齐方式 + */ +function getTableDataFormat () { + + var form = document.forms[ 'data-form' ], + items = form['charts-format']; + + return items[ 0 ].checked ? items[ 0 ].value : items[ 1 ].value; + +} + +/* + * 禁用非饼图类型的配置项 + */ +function disableNotPieConfig() { + + updateConfigItem( 'disable' ); + +} + +/* + * 启用非饼图类型的配置项 + */ +function enableNotPieConfig() { + + updateConfigItem( 'enable' ); + +} + +function updateConfigItem ( value ) { + + var table = $( "#showTable" )[ 0 ], + isDisable = value === 'disable' ? true : false; + + //table中的input处理 + for ( var i = 2 , row; row = table.rows[ i ]; i++ ) { + + for ( var j = 1, cell; cell = row.cells[ j ]; j++ ) { + + $( "input", cell ).attr( "disabled", isDisable ); + + } + + } + + //其他项处理 + $( "input.not-pie-item" ).attr( "disabled", isDisable ); + $( "#tipInput" ).attr( "disabled", !isDisable ) + +} + +/* + * 获取饼图数据 + * 饼图的数据只取第一行的 + **/ +function getSeriesForPieChart () { + + var series = { + type: 'pie', + name: $("#tipInput").val(), + data: [] + }, + tableData = getTableData(); + + + for ( var j = 1, jlen = tableData[ 0 ].length; j < jlen; j++ ) { + + var title = tableData[ 0 ][ j ], + val = tableData[ 1 ][ j ]; + + series.data.push( [ title, val ] ); + + } + + return { + series: [ series ] + }; + +} + +function getTableData () { + + var table = document.getElementById( "showTable" ), + xCount = table.rows[0].cells.length - 1, + values = getTableInputValue(); + + for ( var i = 0, value; value = values[ i ]; i++ ) { + + tableData[ Math.floor( i / xCount ) + 1 ][ i % xCount + 1 ] = values[ i ]; + + } + + return tableData; + +} + +function getTableInputValue () { + + var table = document.getElementById( "showTable" ), + inputs = table.getElementsByTagName( "input" ), + values = []; + + for ( var i = 0, input; input = inputs[ i ]; i++ ) { + values.push( input.value | 0 ); + } + + return values; + +} + +function getCellValue ( cell ) { + + var value = utils.trim( ( cell.innerText || cell.textContent || '' ) ); + + return value.replace( new RegExp( UE.dom.domUtils.fillChar, 'g' ), '' ).replace( /^\s+|\s+$/g, '' ); + +} + + +//dialog确认事件 +dialog.onok = function () { + + //收集信息 + var form = document.forms[ 'data-form' ], + info = getUserConfig(); + + //添加图表类型 + info.chartType = currentChartType; + + //同步表格数据到编辑器 + syncTableData(); + + //执行图表命令 + editor.execCommand( 'charts', info ); + +}; + +/* + * 同步图表编辑视图的表格数据到编辑器里的原始表格 + */ +function syncTableData () { + + var tableData = getTableData(); + + for ( var i = 1, row; row = editorTable.rows[ i ]; i++ ) { + + for ( var j = 1, cell; cell = row.cells[ j ]; j++ ) { + + cell.innerHTML = tableData[ i ] [ j ]; + + } + + } + +} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts0.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts0.png new file mode 100644 index 000000000..9485e5ed8 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts0.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts1.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts1.png new file mode 100644 index 000000000..b5a003928 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts1.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts2.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts2.png new file mode 100644 index 000000000..7c91a39ff Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts2.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts3.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts3.png new file mode 100644 index 000000000..a6bc29bfc Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts3.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts4.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts4.png new file mode 100644 index 000000000..742006adc Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts4.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts5.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts5.png new file mode 100644 index 000000000..c49a29609 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/charts/images/charts5.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/emotion.css b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/emotion.css new file mode 100644 index 000000000..f801105ad --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/emotion.css @@ -0,0 +1,43 @@ +.jd img{ + background:transparent url(images/jxface2.gif?v=1.1) no-repeat scroll left top; + cursor:pointer;width:35px;height:35px;display:block; +} +.pp img{ + background:transparent url(images/fface.gif?v=1.1) no-repeat scroll left top; + cursor:pointer;width:25px;height:25px;display:block; +} +.ldw img{ + background:transparent url(images/wface.gif?v=1.1) no-repeat scroll left top; + cursor:pointer;width:35px;height:35px;display:block; +} +.tsj img{ + background:transparent url(images/tface.gif?v=1.1) no-repeat scroll left top; + cursor:pointer;width:35px;height:35px;display:block; +} +.cat img{ + background:transparent url(images/cface.gif?v=1.1) no-repeat scroll left top; + cursor:pointer;width:35px;height:35px;display:block; +} +.bb img{ + background:transparent url(images/bface.gif?v=1.1) no-repeat scroll left top; + cursor:pointer;width:35px;height:35px;display:block; +} +.youa img{ + background:transparent url(images/yface.gif?v=1.1) no-repeat scroll left top; + cursor:pointer;width:35px;height:35px;display:block; +} + +.smileytable td {height: 37px;} +#tabPanel{margin-left:5px;overflow: hidden;} +#tabContent {float:left;background:#FFFFFF;} +#tabContent div{display: none;width:480px;overflow:hidden;} +#tabIconReview.show{left:17px;display:block;} +.menuFocus{background:#ACCD3C;} +.menuDefault{background:#FFFFFF;} +#tabIconReview{position:absolute;left:406px;left:398px \9;top:41px;z-index:65533;width:90px;height:76px;} +img.review{width:90px;height:76px;border:2px solid #9cb945;background:#FFFFFF;background-position:center;background-repeat:no-repeat;} + +.wrapper .tabbody{position:relative;float:left;clear:both;padding:10px;width: 95%;} +.tabbody table{width: 100%;} +.tabbody td{border:1px solid #BAC498;} +.tabbody td span{display: block;zoom:1;padding:0 4px;} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/emotion.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/emotion.html new file mode 100644 index 000000000..fca08509a --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/emotion.html @@ -0,0 +1,54 @@ + + + + + + + + + + +
          +
          + + + + + + + +
          +
          +
          +
          +
          +
          +
          +
          +
          +
          +
          +
          + +
          + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/emotion.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/emotion.js new file mode 100644 index 000000000..6e158a913 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/emotion.js @@ -0,0 +1,186 @@ +window.onload = function () { + editor.setOpt({ + emotionLocalization:false + }); + + emotion.SmileyPath = editor.options.emotionLocalization === true ? 'images/' : "http://img.baidu.com/hi/"; + emotion.SmileyBox = createTabList( emotion.tabNum ); + emotion.tabExist = createArr( emotion.tabNum ); + + initImgName(); + initEvtHandler( "tabHeads" ); +}; + +function initImgName() { + for ( var pro in emotion.SmilmgName ) { + var tempName = emotion.SmilmgName[pro], + tempBox = emotion.SmileyBox[pro], + tempStr = ""; + + if ( tempBox.length ) return; + for ( var i = 1; i <= tempName[1]; i++ ) { + tempStr = tempName[0]; + if ( i < 10 ) tempStr = tempStr + '0'; + tempStr = tempStr + i + '.gif'; + tempBox.push( tempStr ); + } + } +} + +function initEvtHandler( conId ) { + var tabHeads = $G( conId ); + for ( var i = 0, j = 0; i < tabHeads.childNodes.length; i++ ) { + var tabObj = tabHeads.childNodes[i]; + if ( tabObj.nodeType == 1 ) { + domUtils.on( tabObj, "click", (function ( index ) { + return function () { + switchTab( index ); + }; + })( j ) ); + j++; + } + } + switchTab( 0 ); + $G( "tabIconReview" ).style.display = 'none'; +} + +function InsertSmiley( url, evt ) { + var obj = { + src:editor.options.emotionLocalization ? editor.options.UEDITOR_HOME_URL + "dialogs/emotion/" + url : url + }; + obj._src = obj.src; + editor.execCommand( 'insertimage', obj ); + if ( !evt.ctrlKey ) { + dialog.popup.hide(); + } +} + +function switchTab( index ) { + + autoHeight( index ); + if ( emotion.tabExist[index] == 0 ) { + emotion.tabExist[index] = 1; + createTab( 'tab' + index ); + } + //获取呈现元素句柄数组 + var tabHeads = $G( "tabHeads" ).getElementsByTagName( "span" ), + tabBodys = $G( "tabBodys" ).getElementsByTagName( "div" ), + i = 0, L = tabHeads.length; + //隐藏所有呈现元素 + for ( ; i < L; i++ ) { + tabHeads[i].className = ""; + tabBodys[i].style.display = "none"; + } + //显示对应呈现元素 + tabHeads[index].className = "focus"; + tabBodys[index].style.display = "block"; +} + +function autoHeight( index ) { + var iframe = dialog.getDom( "iframe" ), + parent = iframe.parentNode.parentNode; + switch ( index ) { + case 0: + iframe.style.height = "380px"; + parent.style.height = "392px"; + break; + case 1: + iframe.style.height = "220px"; + parent.style.height = "232px"; + break; + case 2: + iframe.style.height = "260px"; + parent.style.height = "272px"; + break; + case 3: + iframe.style.height = "300px"; + parent.style.height = "312px"; + break; + case 4: + iframe.style.height = "140px"; + parent.style.height = "152px"; + break; + case 5: + iframe.style.height = "260px"; + parent.style.height = "272px"; + break; + case 6: + iframe.style.height = "230px"; + parent.style.height = "242px"; + break; + default: + + } +} + + +function createTab( tabName ) { + var faceVersion = "?v=1.1", //版本号 + tab = $G( tabName ), //获取将要生成的Div句柄 + imagePath = emotion.SmileyPath + emotion.imageFolders[tabName], //获取显示表情和预览表情的路径 + positionLine = 11 / 2, //中间数 + iWidth = iHeight = 35, //图片长宽 + iColWidth = 3, //表格剩余空间的显示比例 + tableCss = emotion.imageCss[tabName], + cssOffset = emotion.imageCssOffset[tabName], + textHTML = [''], + i = 0, imgNum = emotion.SmileyBox[tabName].length, imgColNum = 11, faceImage, + sUrl, realUrl, posflag, offset, infor; + + for ( ; i < imgNum; ) { + textHTML.push( '' ); + for ( var j = 0; j < imgColNum; j++, i++ ) { + faceImage = emotion.SmileyBox[tabName][i]; + if ( faceImage ) { + sUrl = imagePath + faceImage + faceVersion; + realUrl = imagePath + faceImage; + posflag = j < positionLine ? 0 : 1; + offset = cssOffset * i * (-1) - 1; + infor = emotion.SmileyInfor[tabName][i]; + + textHTML.push( '' ); + } + textHTML.push( '' ); + } + textHTML.push( '
          ' ); + textHTML.push( '' ); + textHTML.push( '' ); + textHTML.push( '' ); + } else { + textHTML.push( '' ); + } + textHTML.push( '
          ' ); + textHTML = textHTML.join( "" ); + tab.innerHTML = textHTML; +} + +function over( td, srcPath, posFlag ) { + td.style.backgroundColor = "#ACCD3C"; + $G( 'faceReview' ).style.backgroundImage = "url(" + srcPath + ")"; + if ( posFlag == 1 ) $G( "tabIconReview" ).className = "show"; + $G( "tabIconReview" ).style.display = 'block'; +} + +function out( td ) { + td.style.backgroundColor = "transparent"; + var tabIconRevew = $G( "tabIconReview" ); + tabIconRevew.className = ""; + tabIconRevew.style.display = 'none'; +} + +function createTabList( tabNum ) { + var obj = {}; + for ( var i = 0; i < tabNum; i++ ) { + obj["tab" + i] = []; + } + return obj; +} + +function createArr( tabNum ) { + var arr = []; + for ( var i = 0; i < tabNum; i++ ) { + arr[i] = 0; + } + return arr; +} + diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/0.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/0.gif new file mode 100644 index 000000000..6964168b9 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/0.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/bface.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/bface.gif new file mode 100644 index 000000000..14fe618ab Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/bface.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/cface.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/cface.gif new file mode 100644 index 000000000..bff947f52 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/cface.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/fface.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/fface.gif new file mode 100644 index 000000000..0d8a6afeb Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/fface.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/jxface2.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/jxface2.gif new file mode 100644 index 000000000..a959c90f7 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/jxface2.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/neweditor-tab-bg.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/neweditor-tab-bg.png new file mode 100644 index 000000000..8f398b095 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/neweditor-tab-bg.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/tface.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/tface.gif new file mode 100644 index 000000000..1354f54b9 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/tface.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/wface.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/wface.gif new file mode 100644 index 000000000..5667160d8 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/wface.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/yface.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/yface.gif new file mode 100644 index 000000000..51608be0e Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/emotion/images/yface.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/gmap/gmap.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/gmap/gmap.html new file mode 100644 index 000000000..c4cbfe69c --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/gmap/gmap.html @@ -0,0 +1,89 @@ + + + + + + + + + + +
          + + + + + + +
          +
          +
          + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/help/help.css b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/help/help.css new file mode 100644 index 000000000..4478475fd --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/help/help.css @@ -0,0 +1,7 @@ +.wrapper{width: 370px;margin: 10px auto;zoom: 1;} +.tabbody{height: 360px;} +.tabbody .panel{width:100%;height: 360px;position: absolute;background: #fff;} +.tabbody .panel h1{font-size:26px;margin: 5px 0 0 5px;} +.tabbody .panel p{font-size:12px;margin: 5px 0 0 5px;} +.tabbody table{width:90%;line-height: 20px;margin: 5px 0 0 5px;;} +.tabbody table thead{font-weight: bold;line-height: 25px;} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/help/help.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/help/help.html new file mode 100644 index 000000000..9e50060e7 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/help/help.html @@ -0,0 +1,82 @@ + + + + 帮助 + + + + + +
          +
          + + +
          +
          +
          +

          UEditor

          +

          +

          +
          +
          + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          ctrl+b
          ctrl+c
          ctrl+x
          ctrl+v
          ctrl+y
          ctrl+z
          ctrl+i
          ctrl+u
          ctrl+a
          shift+enter
          alt+z
          +
          +
          +
          + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/help/help.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/help/help.js new file mode 100644 index 000000000..9a2272e38 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/help/help.js @@ -0,0 +1,56 @@ +/** + * Created with JetBrains PhpStorm. + * User: xuheng + * Date: 12-9-26 + * Time: 下午1:06 + * To change this template use File | Settings | File Templates. + */ +/** + * tab点击处理事件 + * @param tabHeads + * @param tabBodys + * @param obj + */ +function clickHandler( tabHeads,tabBodys,obj ) { + //head样式更改 + for ( var k = 0, len = tabHeads.length; k < len; k++ ) { + tabHeads[k].className = ""; + } + obj.className = "focus"; + //body显隐 + var tabSrc = obj.getAttribute( "tabSrc" ); + for ( var j = 0, length = tabBodys.length; j < length; j++ ) { + var body = tabBodys[j], + id = body.getAttribute( "id" ); + body.onclick = function(){ + this.style.zoom = 1; + }; + if ( id != tabSrc ) { + body.style.zIndex = 1; + } else { + body.style.zIndex = 200; + } + } + +} + +/** + * TAB切换 + * @param tabParentId tab的父节点ID或者对象本身 + */ +function switchTab( tabParentId ) { + var tabElements = $G( tabParentId ).children, + tabHeads = tabElements[0].children, + tabBodys = tabElements[1].children; + + for ( var i = 0, length = tabHeads.length; i < length; i++ ) { + var head = tabHeads[i]; + if ( head.className === "focus" )clickHandler(tabHeads,tabBodys, head ); + head.onclick = function () { + clickHandler(tabHeads,tabBodys,this); + } + } +} +switchTab("helptab"); + +document.getElementById('version').innerHTML = parent.UE.version; \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/image.css b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/image.css new file mode 100644 index 000000000..52c2295ef --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/image.css @@ -0,0 +1,894 @@ +@charset "utf-8"; +/* dialog样式 */ +.wrapper { + zoom: 1; + width: 630px; + *width: 626px; + height: 380px; + margin: 0 auto; + padding: 10px; + position: relative; + font-family: sans-serif; +} + +/*tab样式框大小*/ +.tabhead { + float:left; +} +.tabbody { + width: 100%; + height: 346px; + position: relative; + clear: both; +} + +.tabbody .panel { + position: absolute; + width: 0; + height: 0; + background: #fff; + overflow: hidden; + display: none; +} + +.tabbody .panel.focus { + width: 100%; + height: 346px; + display: block; +} + +/* 图片对齐方式 */ +.alignBar{ + float:right; + margin-top: 5px; + position: relative; +} + +.alignBar .algnLabel{ + float:left; + height: 20px; + line-height: 20px; +} + +.alignBar #alignIcon{ + zoom:1; + _display: inline; + display: inline-block; + position: relative; +} +.alignBar #alignIcon span{ + float: left; + cursor: pointer; + display: block; + width: 19px; + height: 17px; + margin-right: 3px; + margin-left: 3px; + background-image: url(./images/alignicon.jpg); +} +.alignBar #alignIcon .none-align{ + background-position: 0 -18px; +} +.alignBar #alignIcon .left-align{ + background-position: -20px -18px; +} +.alignBar #alignIcon .right-align{ + background-position: -40px -18px; +} +.alignBar #alignIcon .center-align{ + background-position: -60px -18px; +} +.alignBar #alignIcon .none-align.focus{ + background-position: 0 0; +} +.alignBar #alignIcon .left-align.focus{ + background-position: -20px 0; +} +.alignBar #alignIcon .right-align.focus{ + background-position: -40px 0; +} +.alignBar #alignIcon .center-align.focus{ + background-position: -60px 0; +} + + + + +/* 远程图片样式 */ +#remote { + z-index: 200; +} + +#remote .top{ + width: 100%; + margin-top: 25px; +} +#remote .left{ + display: block; + float: left; + width: 300px; + height:10px; +} +#remote .right{ + display: block; + float: right; + width: 300px; + height:10px; +} +#remote .row{ + margin-left: 20px; + clear: both; + height: 40px; +} + +#remote .row label{ + text-align: center; + width: 50px; + zoom:1; + _display: inline; + display:inline-block; + vertical-align: middle; +} +#remote .row label.algnLabel{ + float: left; + +} + +#remote input.text{ + width: 150px; + padding: 3px 6px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +#remote input.text:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); +} +#remote #url{ + width: 500px; + margin-bottom: 2px; +} +#remote #width, +#remote #height{ + width: 20px; + margin-left: 2px; + margin-right: 2px; +} +#remote #border, +#remote #vhSpace, +#remote #title{ + width: 180px; + margin-right: 5px; +} +#remote #lock{ +} +#remote #lockicon{ + zoom: 1; + _display:inline; + display: inline-block; + width: 20px; + height: 20px; + background: url("../../themes/default/images/lock.gif") -13px -13px no-repeat; + vertical-align: middle; +} +#remote #preview{ + clear: both; + width: 260px; + height: 240px; + z-index: 9999; + margin-top: 10px; + background-color: #eee; + overflow: hidden; +} + +/* 上传图片 */ +.tabbody #upload.panel { + width: 0; + height: 0; + overflow: hidden; + position: absolute !important; + clip: rect(1px, 1px, 1px, 1px); + background: #fff; + display: block; +} + +.tabbody #upload.panel.focus { + width: 100%; + height: 346px; + display: block; + clip: auto; +} + +#upload .queueList { + margin: 0; + width: 100%; + height: 100%; + position: absolute; + overflow: hidden; +} + +#upload p { + margin: 0; +} + +.element-invisible { + width: 0 !important; + height: 0 !important; + border: 0; + padding: 0; + margin: 0; + overflow: hidden; + position: absolute !important; + clip: rect(1px, 1px, 1px, 1px); +} + +#upload .placeholder { + margin: 10px; + border: 2px dashed #e6e6e6; + *border: 0px dashed #e6e6e6; + height: 172px; + padding-top: 150px; + text-align: center; + background: url(./images/image.png) center 70px no-repeat; + color: #cccccc; + font-size: 18px; + position: relative; + top:0; + *top: 10px; +} + +#upload .placeholder .webuploader-pick { + font-size: 18px; + background: #00b7ee; + border-radius: 3px; + line-height: 44px; + padding: 0 30px; + *width: 120px; + color: #fff; + display: inline-block; + margin: 0 auto 20px auto; + cursor: pointer; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); +} + +#upload .placeholder .webuploader-pick-hover { + background: #00a2d4; +} + + +#filePickerContainer { + text-align: center; +} + +#upload .placeholder .flashTip { + color: #666666; + font-size: 12px; + position: absolute; + width: 100%; + text-align: center; + bottom: 20px; +} + +#upload .placeholder .flashTip a { + color: #0785d1; + text-decoration: none; +} + +#upload .placeholder .flashTip a:hover { + text-decoration: underline; +} + +#upload .placeholder.webuploader-dnd-over { + border-color: #999999; +} + +#upload .filelist { + list-style: none; + margin: 0; + padding: 0; + overflow-x: hidden; + overflow-y: auto; + position: relative; + height: 300px; +} + +#upload .filelist:after { + content: ''; + display: block; + width: 0; + height: 0; + overflow: hidden; + clear: both; + position: relative; +} + +#upload .filelist li { + width: 113px; + height: 113px; + background: url(./images/bg.png); + text-align: center; + margin: 9px 0 0 9px; + *margin: 6px 0 0 6px; + position: relative; + display: block; + float: left; + overflow: hidden; + font-size: 12px; +} + +#upload .filelist li p.log { + position: relative; + top: -45px; +} + +#upload .filelist li p.title { + position: absolute; + top: 0; + left: 0; + width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + top: 5px; + text-indent: 5px; + text-align: left; +} + +#upload .filelist li p.progress { + position: absolute; + width: 100%; + bottom: 0; + left: 0; + height: 8px; + overflow: hidden; + z-index: 50; + margin: 0; + border-radius: 0; + background: none; + -webkit-box-shadow: 0 0 0; +} + +#upload .filelist li p.progress span { + display: none; + overflow: hidden; + width: 0; + height: 100%; + background: #1483d8 url(./images/progress.png) repeat-x; + + -webit-transition: width 200ms linear; + -moz-transition: width 200ms linear; + -o-transition: width 200ms linear; + -ms-transition: width 200ms linear; + transition: width 200ms linear; + + -webkit-animation: progressmove 2s linear infinite; + -moz-animation: progressmove 2s linear infinite; + -o-animation: progressmove 2s linear infinite; + -ms-animation: progressmove 2s linear infinite; + animation: progressmove 2s linear infinite; + + -webkit-transform: translateZ(0); +} + +@-webkit-keyframes progressmove { + 0% { + background-position: 0 0; + } + 100% { + background-position: 17px 0; + } +} + +@-moz-keyframes progressmove { + 0% { + background-position: 0 0; + } + 100% { + background-position: 17px 0; + } +} + +@keyframes progressmove { + 0% { + background-position: 0 0; + } + 100% { + background-position: 17px 0; + } +} + +#upload .filelist li p.imgWrap { + position: relative; + z-index: 2; + line-height: 113px; + vertical-align: middle; + overflow: hidden; + width: 113px; + height: 113px; + + -webkit-transform-origin: 50% 50%; + -moz-transform-origin: 50% 50%; + -o-transform-origin: 50% 50%; + -ms-transform-origin: 50% 50%; + transform-origin: 50% 50%; + + -webit-transition: 200ms ease-out; + -moz-transition: 200ms ease-out; + -o-transition: 200ms ease-out; + -ms-transition: 200ms ease-out; + transition: 200ms ease-out; +} + +#upload .filelist li img { + width: 100%; +} + +#upload .filelist li p.error { + background: #f43838; + color: #fff; + position: absolute; + bottom: 0; + left: 0; + height: 28px; + line-height: 28px; + width: 100%; + z-index: 100; + display:none; +} + +#upload .filelist li .success { + display: block; + position: absolute; + left: 0; + bottom: 0; + height: 40px; + width: 100%; + z-index: 200; + background: url(./images/success.png) no-repeat right bottom; + background: url(./images/success.gif) no-repeat right bottom \9; +} + +#upload .filelist li.filePickerBlock { + width: 113px; + height: 113px; + background: url(./images/image.png) no-repeat center 12px; + border: 1px solid #eeeeee; + border-radius: 0; +} +#upload .filelist li.filePickerBlock div.webuploader-pick { + width: 100%; + height: 100%; + margin: 0; + padding: 0; + opacity: 0; + background: none; + font-size: 0; +} + +#upload .filelist div.file-panel { + position: absolute; + height: 0; + filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#80000000', endColorstr='#80000000') \0; + background: rgba(0, 0, 0, 0.5); + width: 100%; + top: 0; + left: 0; + overflow: hidden; + z-index: 300; +} + +#upload .filelist div.file-panel span { + width: 24px; + height: 24px; + display: inline; + float: right; + text-indent: -9999px; + overflow: hidden; + background: url(./images/icons.png) no-repeat; + background: url(./images/icons.gif) no-repeat \9; + margin: 5px 1px 1px; + cursor: pointer; + -webkit-tap-highlight-color: rgba(0,0,0,0); + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +#upload .filelist div.file-panel span.rotateLeft { + display:none; + background-position: 0 -24px; +} + +#upload .filelist div.file-panel span.rotateLeft:hover { + background-position: 0 0; +} + +#upload .filelist div.file-panel span.rotateRight { + display:none; + background-position: -24px -24px; +} + +#upload .filelist div.file-panel span.rotateRight:hover { + background-position: -24px 0; +} + +#upload .filelist div.file-panel span.cancel { + background-position: -48px -24px; +} + +#upload .filelist div.file-panel span.cancel:hover { + background-position: -48px 0; +} + +#upload .statusBar { + height: 45px; + border-bottom: 1px solid #dadada; + margin: 0 10px; + padding: 0; + line-height: 45px; + vertical-align: middle; + position: relative; +} + +#upload .statusBar .progress { + border: 1px solid #1483d8; + width: 198px; + background: #fff; + height: 18px; + position: absolute; + top: 12px; + display: none; + text-align: center; + line-height: 18px; + color: #6dbfff; + margin: 0 10px 0 0; +} +#upload .statusBar .progress span.percentage { + width: 0; + height: 100%; + left: 0; + top: 0; + background: #1483d8; + position: absolute; +} +#upload .statusBar .progress span.text { + position: relative; + z-index: 10; +} + +#upload .statusBar .info { + display: inline-block; + font-size: 14px; + color: #666666; +} + +#upload .statusBar .btns { + position: absolute; + top: 7px; + right: 0; + line-height: 30px; +} + +#filePickerBtn { + display: inline-block; + float: left; +} +#upload .statusBar .btns .webuploader-pick, +#upload .statusBar .btns .uploadBtn, +#upload .statusBar .btns .uploadBtn.state-uploading, +#upload .statusBar .btns .uploadBtn.state-paused { + background: #ffffff; + border: 1px solid #cfcfcf; + color: #565656; + padding: 0 18px; + display: inline-block; + border-radius: 3px; + margin-left: 10px; + cursor: pointer; + font-size: 14px; + float: left; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +#upload .statusBar .btns .webuploader-pick-hover, +#upload .statusBar .btns .uploadBtn:hover, +#upload .statusBar .btns .uploadBtn.state-uploading:hover, +#upload .statusBar .btns .uploadBtn.state-paused:hover { + background: #f0f0f0; +} + +#upload .statusBar .btns .uploadBtn, +#upload .statusBar .btns .uploadBtn.state-paused{ + background: #00b7ee; + color: #fff; + border-color: transparent; +} +#upload .statusBar .btns .uploadBtn:hover, +#upload .statusBar .btns .uploadBtn.state-paused:hover{ + background: #00a2d4; +} + +#upload .statusBar .btns .uploadBtn.disabled { + pointer-events: none; + filter:alpha(opacity=60); + -moz-opacity:0.6; + -khtml-opacity: 0.6; + opacity: 0.6; +} + + + +/* 图片管理样式 */ +#online { + width: 100%; + height: 336px; + padding: 10px 0 0 0; +} +#online #imageList{ + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + position: relative; +} +#online ul { + display: block; + list-style: none; + margin: 0; + padding: 0; +} +#online li { + float: left; + display: block; + list-style: none; + padding: 0; + width: 113px; + height: 113px; + margin: 0 0 9px 9px; + *margin: 0 0 6px 6px; + background-color: #eee; + overflow: hidden; + cursor: pointer; + position: relative; +} +#online li.clearFloat { + float: none; + clear: both; + display: block; + width:0; + height:0; + margin: 0; + padding: 0; +} +#online li img { + cursor: pointer; +} +#online li .icon { + cursor: pointer; + width: 113px; + height: 113px; + position: absolute; + top: 0; + left: 0; + z-index: 2; + border: 0; + background-repeat: no-repeat; +} +#online li .icon:hover { + width: 107px; + height: 107px; + border: 3px solid #1094fa; +} +#online li.selected .icon { + background-image: url(images/success.png); + background-image: url(images/success.gif)\9; + background-position: 75px 75px; +} +#online li.selected .icon:hover { + width: 107px; + height: 107px; + border: 3px solid #1094fa; + background-position: 72px 72px; +} + + +/* 图片搜索样式 */ +#search .searchBar { + width: 100%; + height: 30px; + margin: 10px 0 5px 0; + padding: 0; +} + +#search input.text{ + width: 150px; + padding: 3px 6px; + font-size: 14px; + line-height: 1.42857143; + color: #555; + background-color: #fff; + background-image: none; + border: 1px solid #ccc; + border-radius: 4px; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); + -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; + transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; +} +#search input.text:focus { + border-color: #66afe9; + outline: 0; + -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); + box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6); +} +#search input.searchTxt { + margin-left:5px; + padding-left: 5px; + background: #FFF; + width: 300px; + *width: 260px; + height: 21px; + line-height: 21px; + float: left; + dislay: block; +} + +#search .searchType { + width: 65px; + height: 28px; + padding:0; + line-height: 28px; + border: 1px solid #d7d7d7; + border-radius: 0; + vertical-align: top; + margin-left: 5px; + float: left; + dislay: block; +} + +#search #searchBtn, +#search #searchReset { + display: inline-block; + margin-bottom: 0; + margin-right: 5px; + padding: 4px 10px; + font-weight: 400; + text-align: center; + vertical-align: middle; + cursor: pointer; + background-image: none; + border: 1px solid transparent; + white-space: nowrap; + font-size: 14px; + border-radius: 4px; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + vertical-align: top; + float: right; +} + +#search #searchBtn { + color: white; + border-color: #285e8e; + background-color: #3b97d7; +} +#search #searchReset { + color: #333; + border-color: #ccc; + background-color: #fff; +} +#search #searchBtn:hover { + background-color: #3276b1; +} +#search #searchReset:hover { + background-color: #eee; +} + +#search .msg { + margin-left: 5px; +} + +#search .searchList{ + width: 100%; + height: 300px; + overflow: hidden; + clear: both; +} +#search .searchList ul{ + margin:0; + padding:0; + list-style:none; + clear: both; + width: 100%; + height: 100%; + overflow-x: hidden; + overflow-y: auto; + zoom: 1; + position: relative; +} + +#search .searchList li { + list-style:none; + float: left; + display: block; + width: 115px; + margin: 5px 10px 5px 20px; + *margin: 5px 10px 5px 15px; + padding:0; + font-size: 12px; + box-shadow: 0 1px 3px rgba(0, 0, 0, .3); + -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, .3); + -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, .3); + position: relative; + vertical-align: top; + text-align: center; + overflow: hidden; + cursor: pointer; + filter: alpha(Opacity=100); + -moz-opacity: 1; + opacity: 1; + border: 2px solid #eee; +} + +#search .searchList li.selected { + filter: alpha(Opacity=40); + -moz-opacity: 0.4; + opacity: 0.4; + border: 2px solid #00a0e9; +} + +#search .searchList li p { + background-color: #eee; + margin: 0; + padding: 0; + position: relative; + width:100%; + height:115px; + overflow: hidden; +} + +#search .searchList li p img { + cursor: pointer; + border: 0; +} + +#search .searchList li a { + color: #999; + border-top: 1px solid #F2F2F2; + background: #FAFAFA; + text-align: center; + display: block; + padding: 0 5px; + width: 105px; + height:32px; + line-height:32px; + white-space:nowrap; + text-overflow:ellipsis; + text-decoration: none; + overflow: hidden; + word-break: break-all; +} + +#search .searchList a:hover { + text-decoration: underline; + color: #333; +} +#search .searchList .clearFloat{ + clear: both; +} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/image.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/image.html new file mode 100644 index 000000000..08ca022dd --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/image.html @@ -0,0 +1,120 @@ + + + + + ueditor图片对话框 + + + + + + + + + + + + + + +
          +
          + + + + +
          +
          + + + + + + + + +
          +
          + + +
          +
          +
          + + +
          +
          +
          +
          + +   px +   px + +
          +
          + + px +
          +
          + + px +
          +
          + + +
          +
          +
          +
          + + +
          +
          +
          +
          + 0% + +
          +
          +
          +
          +
          +
          +
          +
          +
          +
          +
          +
            +
          • +
          +
          +
          + + +
          +
          +
          + + + + +
          +
          + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/image.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/image.js new file mode 100644 index 000000000..cd76b2bd5 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/image.js @@ -0,0 +1,1142 @@ +/** + * User: Jinqn + * Date: 14-04-08 + * Time: 下午16:34 + * 上传图片对话框逻辑代码,包括tab: 远程图片/上传图片/在线图片/搜索图片 + */ + +(function () { + + var remoteImage, + uploadImage, + onlineImage, + searchImage; + + window.onload = function () { + initTabs(); + initAlign(); + initButtons(); + }; + + /* 初始化tab标签 */ + function initTabs() { + var tabs = $G('tabhead').children; + for (var i = 0; i < tabs.length; i++) { + domUtils.on(tabs[i], "click", function (e) { + var target = e.target || e.srcElement; + setTabFocus(target.getAttribute('data-content-id')); + }); + } + + var img = editor.selection.getRange().getClosedNode(); + if (img && img.tagName && img.tagName.toLowerCase() == 'img') { + setTabFocus('remote'); + } else { + setTabFocus('upload'); + } + } + + /* 初始化tabbody */ + function setTabFocus(id) { + if(!id) return; + var i, bodyId, tabs = $G('tabhead').children; + for (i = 0; i < tabs.length; i++) { + bodyId = tabs[i].getAttribute('data-content-id'); + if (bodyId == id) { + domUtils.addClass(tabs[i], 'focus'); + domUtils.addClass($G(bodyId), 'focus'); + } else { + domUtils.removeClasses(tabs[i], 'focus'); + domUtils.removeClasses($G(bodyId), 'focus'); + } + } + switch (id) { + case 'remote': + remoteImage = remoteImage || new RemoteImage(); + break; + case 'upload': + setAlign(editor.getOpt('imageInsertAlign')); + uploadImage = uploadImage || new UploadImage('queueList'); + break; + case 'online': + setAlign(editor.getOpt('imageManagerInsertAlign')); + onlineImage = onlineImage || new OnlineImage('imageList'); + onlineImage.reset(); + break; + case 'search': + setAlign(editor.getOpt('imageManagerInsertAlign')); + searchImage = searchImage || new SearchImage(); + break; + } + } + + /* 初始化onok事件 */ + function initButtons() { + + dialog.onok = function () { + var remote = false, list = [], id, tabs = $G('tabhead').children; + for (var i = 0; i < tabs.length; i++) { + if (domUtils.hasClass(tabs[i], 'focus')) { + id = tabs[i].getAttribute('data-content-id'); + break; + } + } + + switch (id) { + case 'remote': + list = remoteImage.getInsertList(); + break; + case 'upload': + list = uploadImage.getInsertList(); + var count = uploadImage.getQueueCount(); + if (count) { + $('.info', '#queueList').html('' + '还有2个未上传文件'.replace(/[\d]/, count) + ''); + return false; + } + break; + case 'online': + list = onlineImage.getInsertList(); + break; + case 'search': + list = searchImage.getInsertList(); + remote = true; + break; + } + + if(list) { + editor.execCommand('insertimage', list); + remote && editor.fireEvent("catchRemoteImage"); + } + }; + } + + + /* 初始化对其方式的点击事件 */ + function initAlign(){ + /* 点击align图标 */ + domUtils.on($G("alignIcon"), 'click', function(e){ + var target = e.target || e.srcElement; + if(target.className && target.className.indexOf('-align') != -1) { + setAlign(target.getAttribute('data-align')); + } + }); + } + + /* 设置对齐方式 */ + function setAlign(align){ + align = align || 'none'; + var aligns = $G("alignIcon").children; + for(i = 0; i < aligns.length; i++){ + if(aligns[i].getAttribute('data-align') == align) { + domUtils.addClass(aligns[i], 'focus'); + $G("align").value = aligns[i].getAttribute('data-align'); + } else { + domUtils.removeClasses(aligns[i], 'focus'); + } + } + } + /* 获取对齐方式 */ + function getAlign(){ + var align = $G("align").value || 'none'; + return align == 'none' ? '':align; + } + + + /* 在线图片 */ + function RemoteImage(target) { + this.container = utils.isString(target) ? document.getElementById(target) : target; + this.init(); + } + RemoteImage.prototype = { + init: function () { + this.initContainer(); + this.initEvents(); + }, + initContainer: function () { + this.dom = { + 'url': $G('url'), + 'width': $G('width'), + 'height': $G('height'), + 'border': $G('border'), + 'vhSpace': $G('vhSpace'), + 'title': $G('title'), + 'align': $G('align') + }; + var img = editor.selection.getRange().getClosedNode(); + if (img) { + this.setImage(img); + } + }, + initEvents: function () { + var _this = this, + locker = $G('lock'); + + /* 改变url */ + domUtils.on($G("url"), 'keyup', updatePreview); + domUtils.on($G("border"), 'keyup', updatePreview); + domUtils.on($G("title"), 'keyup', updatePreview); + + domUtils.on($G("width"), 'keyup', function(){ + updatePreview(); + if(locker.checked) { + var proportion =locker.getAttribute('data-proportion'); + $G('height').value = Math.round(this.value / proportion); + } else { + _this.updateLocker(); + } + }); + domUtils.on($G("height"), 'keyup', function(){ + updatePreview(); + if(locker.checked) { + var proportion =locker.getAttribute('data-proportion'); + $G('width').value = Math.round(this.value * proportion); + } else { + _this.updateLocker(); + } + }); + domUtils.on($G("lock"), 'change', function(){ + var proportion = parseInt($G("width").value) /parseInt($G("height").value); + locker.setAttribute('data-proportion', proportion); + }); + + function updatePreview(){ + _this.setPreview(); + } + }, + updateLocker: function(){ + var width = $G('width').value, + height = $G('height').value, + locker = $G('lock'); + if(width && height && width == parseInt(width) && height == parseInt(height)) { + locker.disabled = false; + locker.title = ''; + } else { + locker.checked = false; + locker.disabled = 'disabled'; + locker.title = lang.remoteLockError; + } + }, + setImage: function(img){ + /* 不是正常的图片 */ + if (!img.tagName || img.tagName.toLowerCase() != 'img' && !img.getAttribute("src") || !img.src) return; + + var wordImgFlag = img.getAttribute("word_img"), + src = wordImgFlag ? wordImgFlag.replace("&", "&") : (img.getAttribute('_src') || img.getAttribute("src", 2).replace("&", "&")), + align = editor.queryCommandValue("imageFloat"); + + /* 防止onchange事件循环调用 */ + if (src !== $G("url").value) $G("url").value = src; + if(src) { + /* 设置表单内容 */ + $G("width").value = img.width || ''; + $G("height").value = img.height || ''; + $G("border").value = img.getAttribute("border") || '0'; + $G("vhSpace").value = img.getAttribute("vspace") || '0'; + $G("title").value = img.title || img.alt || ''; + setAlign(align); + this.setPreview(); + this.updateLocker(); + } + }, + getData: function(){ + var data = {}; + for(var k in this.dom){ + data[k] = this.dom[k].value; + } + return data; + }, + setPreview: function(){ + var url = $G('url').value, + ow = parseInt($G('width').value, 10) || 0, + oh = parseInt($G('height').value, 10) || 0, + border = parseInt($G('border').value, 10) || 0, + title = $G('title').value, + preview = $G('preview'), + width, + height; + + url = utils.unhtmlForUrl(url); + title = utils.unhtml(title); + + width = ((!ow || !oh) ? preview.offsetWidth:Math.min(ow, preview.offsetWidth)); + width = width+(border*2) > preview.offsetWidth ? width:(preview.offsetWidth - (border*2)); + height = (!ow || !oh) ? '':width*oh/ow; + + if(url) { + preview.innerHTML = ''; + } + }, + getInsertList: function () { + var data = this.getData(); + if(data['url']) { + return [{ + src: data['url'], + _src: data['url'], + width: data['width'] || '', + height: data['height'] || '', + border: data['border'] || '', + floatStyle: data['align'] || '', + vspace: data['vhSpace'] || '', + title: data['title'] || '', + alt: data['title'] || '', + style: "width:" + data['width'] + "px;height:" + data['height'] + "px;" + }]; + } else { + return []; + } + } + }; + + + + /* 上传图片 */ + function UploadImage(target) { + this.$wrap = target.constructor == String ? $('#' + target) : $(target); + this.init(); + } + UploadImage.prototype = { + init: function () { + this.imageList = []; + this.initContainer(); + this.initUploader(); + }, + initContainer: function () { + this.$queue = this.$wrap.find('.filelist'); + }, + /* 初始化容器 */ + initUploader: function () { + var _this = this, + $ = jQuery, // just in case. Make sure it's not an other libaray. + $wrap = _this.$wrap, + // 图片容器 + $queue = $wrap.find('.filelist'), + // 状态栏,包括进度和控制按钮 + $statusBar = $wrap.find('.statusBar'), + // 文件总体选择信息。 + $info = $statusBar.find('.info'), + // 上传按钮 + $upload = $wrap.find('.uploadBtn'), + // 上传按钮 + $filePickerBtn = $wrap.find('.filePickerBtn'), + // 上传按钮 + $filePickerBlock = $wrap.find('.filePickerBlock'), + // 没选择文件之前的内容。 + $placeHolder = $wrap.find('.placeholder'), + // 总体进度条 + $progress = $statusBar.find('.progress').hide(), + // 添加的文件数量 + fileCount = 0, + // 添加的文件总大小 + fileSize = 0, + // 优化retina, 在retina下这个值是2 + ratio = window.devicePixelRatio || 1, + // 缩略图大小 + thumbnailWidth = 113 * ratio, + thumbnailHeight = 113 * ratio, + // 可能有pedding, ready, uploading, confirm, done. + state = '', + // 所有文件的进度信息,key为file id + percentages = {}, + supportTransition = (function () { + var s = document.createElement('p').style, + r = 'transition' in s || + 'WebkitTransition' in s || + 'MozTransition' in s || + 'msTransition' in s || + 'OTransition' in s; + s = null; + return r; + })(), + // WebUploader实例 + uploader, + actionUrl = editor.getActionUrl(editor.getOpt('imageActionName')), + acceptExtensions = (editor.getOpt('imageAllowFiles') || []).join('').replace(/\./g, ',').replace(/^[,]/, ''), + imageMaxSize = editor.getOpt('imageMaxSize'), + imageCompressBorder = editor.getOpt('imageCompressBorder'); + + if (!WebUploader.Uploader.support()) { + $('#filePickerReady').after($('
          ').html(lang.errorNotSupport)).hide(); + return; + } else if (!editor.getOpt('imageActionName')) { + $('#filePickerReady').after($('
          ').html(lang.errorLoadConfig)).hide(); + return; + } + + uploader = _this.uploader = WebUploader.create({ + pick: { + id: '#filePickerReady', + label: lang.uploadSelectFile + }, + accept: { + title: 'Images', + extensions: acceptExtensions, + mimeTypes: 'image/jpg,image/jpeg,image/png' + }, + swf: '../../third-party/webuploader/Uploader.swf', + server: actionUrl, + fileVal: editor.getOpt('imageFieldName'), + duplicate: true, + fileSingleSizeLimit: imageMaxSize, // 默认 2 M + compress: editor.getOpt('imageCompressEnable') ? { + width: imageCompressBorder, + height: imageCompressBorder, + // 图片质量,只有type为`image/jpeg`的时候才有效。 + quality: 90, + // 是否允许放大,如果想要生成小图的时候不失真,此选项应该设置为false. + allowMagnify: false, + // 是否允许裁剪。 + crop: false, + // 是否保留头部meta信息。 + preserveHeaders: true + }:false + }); + uploader.addButton({ + id: '#filePickerBlock' + }); + uploader.addButton({ + id: '#filePickerBtn', + label: lang.uploadAddFile + }); + + setState('pedding'); + + // 当有文件添加进来时执行,负责view的创建 + function addFile(file) { + var $li = $('
        • ' + + '

          ' + file.name + '

          ' + + '

          ' + + '

          ' + + '
        • '), + + $btns = $('
          ' + + '' + lang.uploadDelete + '' + + '' + lang.uploadTurnRight + '' + + '' + lang.uploadTurnLeft + '
          ').appendTo($li), + $prgress = $li.find('p.progress span'), + $wrap = $li.find('p.imgWrap'), + $info = $('

          ').hide().appendTo($li), + + showError = function (code) { + switch (code) { + case 'exceed_size': + text = lang.errorExceedSize; + break; + case 'interrupt': + text = lang.errorInterrupt; + break; + case 'http': + text = lang.errorHttp; + break; + case 'not_allow_type': + text = lang.errorFileType; + break; + default: + text = lang.errorUploadRetry; + break; + } + $info.text(text).show(); + }; + + if (file.getStatus() === 'invalid') { + showError(file.statusText); + } else { + $wrap.text(lang.uploadPreview); + if (browser.ie && browser.version <= 7) { + $wrap.text(lang.uploadNoPreview); + } else { + uploader.makeThumb(file, function (error, src) { + if (error || !src) { + $wrap.text(lang.uploadNoPreview); + } else { + var $img = $(''); + $wrap.empty().append($img); + $img.on('error', function () { + $wrap.text(lang.uploadNoPreview); + }); + } + }, thumbnailWidth, thumbnailHeight); + } + percentages[ file.id ] = [ file.size, 0 ]; + file.rotation = 0; + + /* 检查文件格式 */ + if (!file.ext || acceptExtensions.indexOf(file.ext.toLowerCase()) == -1) { + showError('not_allow_type'); + uploader.removeFile(file); + } + } + + file.on('statuschange', function (cur, prev) { + if (prev === 'progress') { + $prgress.hide().width(0); + } else if (prev === 'queued') { + $li.off('mouseenter mouseleave'); + $btns.remove(); + } + // 成功 + if (cur === 'error' || cur === 'invalid') { + showError(file.statusText); + percentages[ file.id ][ 1 ] = 1; + } else if (cur === 'interrupt') { + showError('interrupt'); + } else if (cur === 'queued') { + percentages[ file.id ][ 1 ] = 0; + } else if (cur === 'progress') { + $info.hide(); + $prgress.css('display', 'block'); + } else if (cur === 'complete') { + } + + $li.removeClass('state-' + prev).addClass('state-' + cur); + }); + + $li.on('mouseenter', function () { + $btns.stop().animate({height: 30}); + }); + $li.on('mouseleave', function () { + $btns.stop().animate({height: 0}); + }); + + $btns.on('click', 'span', function () { + var index = $(this).index(), + deg; + + switch (index) { + case 0: + uploader.removeFile(file); + return; + case 1: + file.rotation += 90; + break; + case 2: + file.rotation -= 90; + break; + } + + if (supportTransition) { + deg = 'rotate(' + file.rotation + 'deg)'; + $wrap.css({ + '-webkit-transform': deg, + '-mos-transform': deg, + '-o-transform': deg, + 'transform': deg + }); + } else { + $wrap.css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + (~~((file.rotation / 90) % 4 + 4) % 4) + ')'); + } + + }); + + $li.insertBefore($filePickerBlock); + } + + // 负责view的销毁 + function removeFile(file) { + var $li = $('#' + file.id); + delete percentages[ file.id ]; + updateTotalProgress(); + $li.off().find('.file-panel').off().end().remove(); + } + + function updateTotalProgress() { + var loaded = 0, + total = 0, + spans = $progress.children(), + percent; + + $.each(percentages, function (k, v) { + total += v[ 0 ]; + loaded += v[ 0 ] * v[ 1 ]; + }); + + percent = total ? loaded / total : 0; + + spans.eq(0).text(Math.round(percent * 100) + '%'); + spans.eq(1).css('width', Math.round(percent * 100) + '%'); + updateStatus(); + } + + function setState(val, files) { + + if (val != state) { + + var stats = uploader.getStats(); + + $upload.removeClass('state-' + state); + $upload.addClass('state-' + val); + + switch (val) { + + /* 未选择文件 */ + case 'pedding': + $queue.addClass('element-invisible'); + $statusBar.addClass('element-invisible'); + $placeHolder.removeClass('element-invisible'); + $progress.hide(); $info.hide(); + uploader.refresh(); + break; + + /* 可以开始上传 */ + case 'ready': + $placeHolder.addClass('element-invisible'); + $queue.removeClass('element-invisible'); + $statusBar.removeClass('element-invisible'); + $progress.hide(); $info.show(); + $upload.text(lang.uploadStart); + uploader.refresh(); + break; + + /* 上传中 */ + case 'uploading': + $progress.show(); $info.hide(); + $upload.text(lang.uploadPause); + break; + + /* 暂停上传 */ + case 'paused': + $progress.show(); $info.hide(); + $upload.text(lang.uploadContinue); + break; + + case 'confirm': + $progress.show(); $info.hide(); + $upload.text(lang.uploadStart); + + stats = uploader.getStats(); + if (stats.successNum && !stats.uploadFailNum) { + setState('finish'); + return; + } + break; + + case 'finish': + $progress.hide(); $info.show(); + if (stats.uploadFailNum) { + $upload.text(lang.uploadRetry); + } else { + $upload.text(lang.uploadStart); + } + break; + } + + state = val; + updateStatus(); + + } + + if (!_this.getQueueCount()) { + $upload.addClass('disabled') + } else { + $upload.removeClass('disabled') + } + + } + + function updateStatus() { + var text = '', stats; + + if (state === 'ready') { + text = lang.updateStatusReady.replace('_', fileCount).replace('_KB', WebUploader.formatSize(fileSize)); + } else if (state === 'confirm') { + stats = uploader.getStats(); + if (stats.uploadFailNum) { + text = lang.updateStatusConfirm.replace('_', stats.successNum).replace('_', stats.successNum); + } + } else { + stats = uploader.getStats(); + text = lang.updateStatusFinish.replace('_', fileCount). + replace('_KB', WebUploader.formatSize(fileSize)). + replace('_', stats.successNum); + + if (stats.uploadFailNum) { + text += lang.updateStatusError.replace('_', stats.uploadFailNum); + } + } + + $info.html(text); + } + + uploader.on('fileQueued', function (file) { + fileCount++; + fileSize += file.size; + + if (fileCount === 1) { + $placeHolder.addClass('element-invisible'); + $statusBar.show(); + } + + addFile(file); + }); + + uploader.on('fileDequeued', function (file) { + fileCount--; + fileSize -= file.size; + + removeFile(file); + updateTotalProgress(); + }); + + uploader.on('filesQueued', function (file) { + if (!uploader.isInProgress() && (state == 'pedding' || state == 'finish' || state == 'confirm' || state == 'ready')) { + setState('ready'); + } + updateTotalProgress(); + }); + + uploader.on('all', function (type, files) { + switch (type) { + case 'uploadFinished': + setState('confirm', files); + break; + case 'startUpload': + /* 添加额外的GET参数 */ + var params = utils.serializeParam(editor.queryCommandValue('serverparam')) || '', + url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?':'&') + 'encode=utf-8&' + params); + uploader.option('server', url); + setState('uploading', files); + break; + case 'stopUpload': + setState('paused', files); + break; + } + }); + + uploader.on('uploadBeforeSend', function (file, data, header) { + //这里可以通过data对象添加POST参数 + header['X_Requested_With'] = 'XMLHttpRequest'; + }); + + uploader.on('uploadProgress', function (file, percentage) { + var $li = $('#' + file.id), + $percent = $li.find('.progress span'); + + $percent.css('width', percentage * 100 + '%'); + percentages[ file.id ][ 1 ] = percentage; + updateTotalProgress(); + }); + + uploader.on('uploadSuccess', function (file, ret) { + var $file = $('#' + file.id); + try { + var responseText = (ret._raw || ret), + json = utils.str2json(responseText); + if (json.state == 'SUCCESS') { + _this.imageList.push(json); + $file.append(''); + } else { + $file.find('.error').text(json.state).show(); + } + } catch (e) { + $file.find('.error').text(lang.errorServerUpload).show(); + } + }); + + uploader.on('uploadError', function (file, code) { + }); + uploader.on('error', function (code, file) { + if (code == 'Q_TYPE_DENIED' || code == 'F_EXCEED_SIZE') { + addFile(file); + } + }); + uploader.on('uploadComplete', function (file, ret) { + }); + + $upload.on('click', function () { + if ($(this).hasClass('disabled')) { + return false; + } + + if (state === 'ready') { + uploader.upload(); + } else if (state === 'paused') { + uploader.upload(); + } else if (state === 'uploading') { + uploader.stop(); + } + }); + + $upload.addClass('state-' + state); + updateTotalProgress(); + }, + getQueueCount: function () { + var file, i, status, readyFile = 0, files = this.uploader.getFiles(); + for (i = 0; file = files[i++]; ) { + status = file.getStatus(); + if (status == 'queued' || status == 'uploading' || status == 'progress') readyFile++; + } + return readyFile; + }, + destroy: function () { + this.$wrap.remove(); + }, + getInsertList: function () { + var i, data, list = [], + align = getAlign(), + prefix = editor.getOpt('imageUrlPrefix'); + for (i = 0; i < this.imageList.length; i++) { + data = this.imageList[i]; + list.push({ + src: prefix + data.url, + _src: prefix + data.url, + title: data.title, + alt: data.original, + floatStyle: align + }); + } + return list; + } + }; + + + /* 在线图片 */ + function OnlineImage(target) { + this.container = utils.isString(target) ? document.getElementById(target) : target; + this.init(); + } + OnlineImage.prototype = { + init: function () { + this.reset(); + this.initEvents(); + }, + /* 初始化容器 */ + initContainer: function () { + this.container.innerHTML = ''; + this.list = document.createElement('ul'); + this.clearFloat = document.createElement('li'); + + domUtils.addClass(this.list, 'list'); + domUtils.addClass(this.clearFloat, 'clearFloat'); + + this.list.appendChild(this.clearFloat); + this.container.appendChild(this.list); + }, + /* 初始化滚动事件,滚动到地步自动拉取数据 */ + initEvents: function () { + var _this = this; + + /* 滚动拉取图片 */ + domUtils.on($G('imageList'), 'scroll', function(e){ + var panel = this; + if (panel.scrollHeight - (panel.offsetHeight + panel.scrollTop) < 10) { + _this.getImageData(); + } + }); + /* 选中图片 */ + domUtils.on(this.container, 'click', function (e) { + var target = e.target || e.srcElement, + li = target.parentNode; + + if (li.tagName.toLowerCase() == 'li') { + if (domUtils.hasClass(li, 'selected')) { + domUtils.removeClasses(li, 'selected'); + } else { + domUtils.addClass(li, 'selected'); + } + } + }); + }, + /* 初始化第一次的数据 */ + initData: function () { + + /* 拉取数据需要使用的值 */ + this.state = 0; + this.listSize = editor.getOpt('imageManagerListSize'); + this.listIndex = 0; + this.listEnd = false; + + /* 第一次拉取数据 */ + this.getImageData(); + }, + /* 重置界面 */ + reset: function() { + this.initContainer(); + this.initData(); + }, + /* 向后台拉取图片列表数据 */ + getImageData: function () { + var _this = this; + + if(!_this.listEnd && !this.isLoadingData) { + this.isLoadingData = true; + var url = editor.getActionUrl(editor.getOpt('imageManagerActionName')), + isJsonp = utils.isCrossDomainUrl(url); + ajax.request(url, { + 'timeout': 100000, + 'dataType': isJsonp ? 'jsonp':'', + 'data': utils.extend({ + start: this.listIndex, + size: this.listSize + }, editor.queryCommandValue('serverparam')), + 'method': 'get', + 'onsuccess': function (r) { + try { + var json = isJsonp ? r:eval('(' + r.responseText + ')'); + if (json.state == 'SUCCESS') { + _this.pushData(json.list); + _this.listIndex = parseInt(json.start) + parseInt(json.list.length); + if(_this.listIndex >= json.total) { + _this.listEnd = true; + } + _this.isLoadingData = false; + } + } catch (e) { + if(r.responseText.indexOf('ue_separate_ue') != -1) { + var list = r.responseText.split(r.responseText); + _this.pushData(list); + _this.listIndex = parseInt(list.length); + _this.listEnd = true; + _this.isLoadingData = false; + } + } + }, + 'onerror': function () { + _this.isLoadingData = false; + } + }); + } + }, + /* 添加图片到列表界面上 */ + pushData: function (list) { + var i, item, img, icon, _this = this, + urlPrefix = editor.getOpt('imageManagerUrlPrefix'); + for (i = 0; i < list.length; i++) { + if(list[i] && list[i].url) { + item = document.createElement('li'); + img = document.createElement('img'); + icon = document.createElement('span'); + + domUtils.on(img, 'load', (function(image){ + return function(){ + _this.scale(image, image.parentNode.offsetWidth, image.parentNode.offsetHeight); + } + })(img)); + img.width = 113; + img.setAttribute('src', urlPrefix + list[i].url + (list[i].url.indexOf('?') == -1 ? '?noCache=':'&noCache=') + (+new Date()).toString(36) ); + img.setAttribute('_src', urlPrefix + list[i].url); + domUtils.addClass(icon, 'icon'); + + item.appendChild(img); + item.appendChild(icon); + this.list.insertBefore(item, this.clearFloat); + } + } + }, + /* 改变图片大小 */ + scale: function (img, w, h, type) { + var ow = img.width, + oh = img.height; + + if (type == 'justify') { + if (ow >= oh) { + img.width = w; + img.height = h * oh / ow; + img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px'; + } else { + img.width = w * ow / oh; + img.height = h; + img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px'; + } + } else { + if (ow >= oh) { + img.width = w * ow / oh; + img.height = h; + img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px'; + } else { + img.width = w; + img.height = h * oh / ow; + img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px'; + } + } + }, + getInsertList: function () { + var i, lis = this.list.children, list = [], align = getAlign(); + for (i = 0; i < lis.length; i++) { + if (domUtils.hasClass(lis[i], 'selected')) { + var img = lis[i].firstChild, + src = img.getAttribute('_src'); + list.push({ + src: src, + _src: src, + alt: src.substr(src.lastIndexOf('/') + 1), + floatStyle: align + }); + } + + } + return list; + } + }; + + /*搜索图片 */ + function SearchImage() { + this.init(); + } + SearchImage.prototype = { + init: function () { + this.initEvents(); + }, + initEvents: function(){ + var _this = this; + + /* 点击搜索按钮 */ + domUtils.on($G('searchBtn'), 'click', function(){ + var key = $G('searchTxt').value; + if(key && key != lang.searchRemind) { + _this.getImageData(); + } + }); + /* 点击清除妞 */ + domUtils.on($G('searchReset'), 'click', function(){ + $G('searchTxt').value = lang.searchRemind; + $G('searchListUl').innerHTML = ''; + $G('searchType').selectedIndex = 0; + }); + /* 搜索框聚焦 */ + domUtils.on($G('searchTxt'), 'focus', function(){ + var key = $G('searchTxt').value; + if(key && key == lang.searchRemind) { + $G('searchTxt').value = ''; + } + }); + /* 搜索框回车键搜索 */ + domUtils.on($G('searchTxt'), 'keydown', function(e){ + var keyCode = e.keyCode || e.which; + if (keyCode == 13) { + $G('searchBtn').click(); + } + }); + + /* 选中图片 */ + domUtils.on($G('searchList'), 'click', function(e){ + var target = e.target || e.srcElement, + li = target.parentNode.parentNode; + + if (li.tagName.toLowerCase() == 'li') { + if (domUtils.hasClass(li, 'selected')) { + domUtils.removeClasses(li, 'selected'); + } else { + domUtils.addClass(li, 'selected'); + } + } + }); + }, + encodeToGb2312:function (str){ + if(!str) return ''; + var strOut = "", + z = 'D2BBB6A18140C6DF814181428143CDF2D5C9C8FDC9CFCFC2D8A2B2BBD3EB8144D8A4B3F38145D7A8C7D2D8A7CAC08146C7F0B1FBD2B5B4D4B6ABCBBFD8A9814781488149B6AA814AC1BDD1CF814BC9A5D8AD814CB8F6D1BEE3DCD6D0814D814EB7E1814FB4AE8150C1D98151D8BC8152CDE8B5A4CEAAD6F78153C0F6BED9D8AF815481558156C4CB8157BEC38158D8B1C3B4D2E58159D6AECEDAD5A7BAF5B7A6C0D6815AC6B9C5D2C7C7815BB9D4815CB3CBD2D2815D815ED8BFBEC5C6F2D2B2CFB0CFE7815F816081618162CAE981638164D8C081658166816781688169816AC2F2C2D2816BC8E9816C816D816E816F817081718172817381748175C7AC8176817781788179817A817B817CC1CB817DD3E8D5F9817ECAC2B6FED8A1D3DABFF78180D4C6BBA5D8C1CEE5BEAE81818182D8A88183D1C7D0A9818481858186D8BDD9EFCDF6BFBA8187BDBBBAA5D2E0B2FABAE0C4B68188CFEDBEA9CDA4C1C18189818A818BC7D7D9F1818CD9F4818D818E818F8190C8CBD8E9819181928193D2DACAB2C8CAD8ECD8EAD8C6BDF6C6CDB3F08194D8EBBDF1BDE98195C8D4B4D381968197C2D88198B2D6D7D0CACBCBFBD5CCB8B6CFC98199819A819BD9DAD8F0C7AA819CD8EE819DB4FAC1EED2D4819E819FD8ED81A0D2C7D8EFC3C781A181A281A3D1F681A4D6D9D8F281A5D8F5BCFEBCDB81A681A781A8C8CE81A9B7DD81AAB7C281ABC6F381AC81AD81AE81AF81B081B181B2D8F8D2C181B381B4CEE9BCBFB7FCB7A5D0DD81B581B681B781B881B9D6DAD3C5BBEFBBE1D8F181BA81BBC9A1CEB0B4AB81BCD8F381BDC9CBD8F6C2D7D8F781BE81BFCEB1D8F981C081C181C2B2AEB9C081C3D9A381C4B0E981C5C1E681C6C9EC81C7CBC581C8CBC6D9A481C981CA81CB81CC81CDB5E881CE81CFB5AB81D081D181D281D381D481D5CEBBB5CDD7A1D7F4D3D381D6CCE581D7BACE81D8D9A2D9DCD3E0D8FDB7F0D7F7D8FED8FAD9A1C4E381D981DAD3B6D8F4D9DD81DBD8FB81DCC5E581DD81DEC0D081DF81E0D1F0B0DB81E181E2BCD1D9A681E3D9A581E481E581E681E7D9ACD9AE81E8D9ABCAB981E981EA81EBD9A9D6B681EC81ED81EEB3DED9A881EFC0FD81F0CACC81F1D9AA81F2D9A781F381F4D9B081F581F6B6B181F781F881F9B9A981FAD2C081FB81FCCFC081FD81FEC2C28240BDC4D5ECB2E0C7C8BFEBD9AD8241D9AF8242CEEABAEE82438244824582468247C7D682488249824A824B824C824D824E824F8250B1E3825182528253B4D9B6EDD9B48254825582568257BFA182588259825AD9DEC7CEC0FED9B8825B825C825D825E825FCBD7B7FD8260D9B58261D9B7B1A3D3E1D9B98262D0C58263D9B682648265D9B18266D9B2C1A9D9B382678268BCF3D0DEB8A98269BEE3826AD9BD826B826C826D826ED9BA826FB0B3827082718272D9C28273827482758276827782788279827A827B827C827D827E8280D9C4B1B68281D9BF82828283B5B98284BEF3828582868287CCC8BAF2D2D08288D9C38289828ABDE8828BB3AB828C828D828ED9C5BEEB828FD9C6D9BBC4DF8290D9BED9C1D9C0829182928293829482958296829782988299829A829BD5AE829CD6B5829DC7E3829E829F82A082A1D9C882A282A382A4BCD9D9CA82A582A682A7D9BC82A8D9CBC6AB82A982AA82AB82AC82ADD9C982AE82AF82B082B1D7F682B2CDA382B382B482B582B682B782B882B982BABDA182BB82BC82BD82BE82BF82C0D9CC82C182C282C382C482C582C682C782C882C9C5BCCDB582CA82CB82CCD9CD82CD82CED9C7B3A5BFFE82CF82D082D182D2B8B582D382D4C0FC82D582D682D782D8B0F882D982DA82DB82DC82DD82DE82DF82E082E182E282E382E482E582E682E782E882E982EA82EB82EC82EDB4F682EED9CE82EFD9CFB4A2D9D082F082F1B4DF82F282F382F482F582F6B0C182F782F882F982FA82FB82FC82FDD9D1C9B582FE8340834183428343834483458346834783488349834A834B834C834D834E834F83508351CFF1835283538354835583568357D9D283588359835AC1C5835B835C835D835E835F836083618362836383648365D9D6C9AE8366836783688369D9D5D9D4D9D7836A836B836C836DCBDB836EBDA9836F8370837183728373C6A7837483758376837783788379837A837B837C837DD9D3D9D8837E83808381D9D9838283838384838583868387C8E583888389838A838B838C838D838E838F839083918392839383948395C0DC8396839783988399839A839B839C839D839E839F83A083A183A283A383A483A583A683A783A883A983AA83AB83AC83AD83AE83AF83B083B183B2B6F9D8A3D4CA83B3D4AAD0D6B3E4D5D783B4CFC8B9E283B5BFCB83B6C3E283B783B883B9B6D283BA83BBCDC3D9EED9F083BC83BD83BEB5B383BFB6B583C083C183C283C383C4BEA483C583C6C8EB83C783C8C8AB83C983CAB0CBB9ABC1F9D9E283CBC0BCB9B283CCB9D8D0CBB1F8C6E4BEDFB5E4D7C883CDD1F8BCE6CADE83CE83CFBCBDD9E6D8E783D083D1C4DA83D283D3B8D4C8BD83D483D5B2E1D4D983D683D783D883D9C3B083DA83DBC3E1DAA2C8DF83DCD0B483DDBEFCC5A983DE83DF83E0B9DA83E1DAA383E2D4A9DAA483E383E483E583E683E7D9FBB6AC83E883E9B7EBB1F9D9FCB3E5BEF683EABFF6D2B1C0E483EB83EC83EDB6B3D9FED9FD83EE83EFBEBB83F083F183F2C6E083F3D7BCDAA183F4C1B983F5B5F2C1E883F683F7BCF583F8B4D583F983FA83FB83FC83FD83FE844084418442C1DD8443C4FD84448445BCB8B7B284468447B7EF84488449844A844B844C844DD9EC844EC6BE844FBFADBBCB84508451B5CA8452DBC9D0D78453CDB9B0BCB3F6BBF7DBCABAAF8454D4E4B5B6B5F3D8D6C8D084558456B7D6C7D0D8D78457BFAF84588459DBBBD8D8845A845BD0CCBBAE845C845D845EEBBEC1D0C1F5D4F2B8D5B4B4845FB3F584608461C9BE846284638464C5D0846584668467C5D9C0FB8468B1F08469D8D9B9CE846AB5BD846B846CD8DA846D846ED6C6CBA2C8AFC9B2B4CCBFCC846FB9F48470D8DBD8DCB6E7BCC1CCEA847184728473847484758476CFF78477D8DDC7B084788479B9D0BDA3847A847BCCDE847CC6CA847D847E848084818482D8E08483D8DE84848485D8DF848684878488B0FE8489BEE7848ACAA3BCF4848B848C848D848EB8B1848F8490B8EE849184928493849484958496849784988499849AD8E2849BBDCB849CD8E4D8E3849D849E849F84A084A1C5FC84A284A384A484A584A684A784A8D8E584A984AAD8E684AB84AC84AD84AE84AF84B084B1C1A684B2C8B0B0ECB9A6BCD3CEF1DBBDC1D384B384B484B584B6B6AFD6FAC5ACBDD9DBBEDBBF84B784B884B9C0F8BEA2C0CD84BA84BB84BC84BD84BE84BF84C084C184C284C3DBC0CAC684C484C584C6B2AA84C784C884C9D3C284CAC3E384CBD1AB84CC84CD84CE84CFDBC284D0C0D584D184D284D3DBC384D4BFB184D584D684D784D884D984DAC4BC84DB84DC84DD84DEC7DA84DF84E084E184E284E384E484E584E684E784E884E9DBC484EA84EB84EC84ED84EE84EF84F084F1D9E8C9D784F284F384F4B9B4CEF0D4C884F584F684F784F8B0FCB4D284F9D0D984FA84FB84FC84FDD9E984FEDECBD9EB8540854185428543D8B0BBAFB1B18544B3D7D8CE85458546D4D185478548BDB3BFEF8549CFBB854A854BD8D0854C854D854EB7CB854F85508551D8D185528553855485558556855785588559855A855BC6A5C7F8D2BD855C855DD8D2C4E4855ECAAE855FC7A78560D8A68561C9FDCEE7BBDCB0EB856285638564BBAAD0AD8565B1B0D7E4D7BF8566B5A5C2F4C4CF85678568B2A98569B2B7856AB1E5DFB2D5BCBFA8C2ACD8D5C2B1856BD8D4CED4856CDAE0856DCEC0856E856FD8B4C3AED3A1CEA38570BCB4C8B4C2D18571BEEDD0B68572DAE18573857485758576C7E485778578B3A78579B6F2CCFCC0FA857A857BC0F7857CD1B9D1E1D8C7857D857E85808581858285838584B2DE85858586C0E58587BAF185888589D8C8858AD4AD858B858CCFE1D8C9858DD8CACFC3858EB3F8BEC7858F859085918592D8CB8593859485958596859785988599DBCC859A859B859C859DC8A5859E859F85A0CFD885A1C8FEB2CE85A285A385A485A585A6D3D6B2E6BCB0D3D1CBABB7B485A785A885A9B7A285AA85ABCAE585ACC8A1CADCB1E4D0F085ADC5D185AE85AF85B0DBC5B5FE85B185B2BFDAB9C5BEE4C1ED85B3DFB6DFB5D6BBBDD0D5D9B0C8B6A3BFC9CCA8DFB3CAB7D3D285B4D8CFD2B6BAC5CBBECCBE85B5DFB7B5F0DFB485B685B785B8D3F585B9B3D4B8F785BADFBA85BBBACFBCAAB5F585BCCDACC3FBBAF3C0F4CDC2CFF2DFB8CFC585BDC2C0DFB9C2F085BE85BF85C0BEFD85C1C1DFCDCCD2F7B7CDDFC185C2DFC485C385C4B7F1B0C9B6D6B7D485C5BAACCCFDBFD4CBB1C6F485C6D6A8DFC585C7CEE2B3B385C885C9CEFCB4B585CACEC7BAF085CBCEE185CCD1BD85CD85CEDFC085CF85D0B4F485D1B3CA85D2B8E6DFBB85D385D485D585D6C4C585D7DFBCDFBDDFBEC5BBDFBFDFC2D4B1DFC385D8C7BACED885D985DA85DB85DC85DDC4D885DEDFCA85DFDFCF85E0D6DC85E185E285E385E485E585E685E785E8DFC9DFDACEB685E9BAC7DFCEDFC8C5DE85EA85EBC9EBBAF4C3FC85EC85EDBED785EEDFC685EFDFCD85F0C5D885F185F285F385F4D5A6BACD85F5BECCD3BDB8C085F6D6E485F7DFC7B9BEBFA785F885F9C1FCDFCBDFCC85FADFD085FB85FC85FD85FE8640DFDBDFE58641DFD7DFD6D7C9DFE3DFE4E5EBD2A7DFD28642BFA98643D4DB8644BFC8DFD4864586468647CFCC86488649DFDD864AD1CA864BDFDEB0A7C6B7DFD3864CBAE5864DB6DFCDDBB9FED4D5864E864FDFDFCFECB0A5DFE7DFD1D1C6DFD5DFD8DFD9DFDC8650BBA98651DFE0DFE18652DFE2DFE6DFE8D3B486538654865586568657B8E7C5B6DFEAC9DAC1A8C4C486588659BFDECFF8865A865B865CD5DCDFEE865D865E865F866086618662B2B88663BADFDFEC8664DBC18665D1E48666866786688669CBF4B4BD866AB0A6866B866C866D866E866FDFF1CCC6DFF286708671DFED867286738674867586768677DFE986788679867A867BDFEB867CDFEFDFF0BBBD867D867EDFF386808681DFF48682BBA38683CADBCEA8E0A7B3AA8684E0A6868586868687E0A186888689868A868BDFFE868CCDD9DFFC868DDFFA868EBFD0D7C4868FC9CC86908691DFF8B0A186928693869486958696DFFD869786988699869ADFFBE0A2869B869C869D869E869FE0A886A086A186A286A3B7C886A486A5C6A1C9B6C0B2DFF586A686A7C5BE86A8D8C4DFF9C4F686A986AA86AB86AC86AD86AEE0A3E0A4E0A5D0A586AF86B0E0B4CCE486B1E0B186B2BFA6E0AFCEB9E0ABC9C686B386B4C0AEE0AEBAEDBAB0E0A986B586B686B7DFF686B8E0B386B986BAE0B886BB86BC86BDB4ADE0B986BE86BFCFB2BAC886C0E0B086C186C286C386C486C586C686C7D0FA86C886C986CA86CB86CC86CD86CE86CF86D0E0AC86D1D4FB86D2DFF786D3C5E786D4E0AD86D5D3F786D6E0B6E0B786D786D886D986DA86DBE0C4D0E186DC86DD86DEE0BC86DF86E0E0C9E0CA86E186E286E3E0BEE0AAC9A4E0C186E4E0B286E586E686E786E886E9CAC8E0C386EAE0B586EBCECB86ECCBC3E0CDE0C6E0C286EDE0CB86EEE0BAE0BFE0C086EF86F0E0C586F186F2E0C7E0C886F3E0CC86F4E0BB86F586F686F786F886F9CBD4E0D586FAE0D6E0D286FB86FC86FD86FE87408741E0D0BCCE87428743E0D18744B8C2D8C587458746874787488749874A874B874CD0EA874D874EC2EF874F8750E0CFE0BD875187528753E0D4E0D387548755E0D78756875787588759E0DCE0D8875A875B875CD6F6B3B0875DD7EC875ECBBB875F8760E0DA8761CEFB876287638764BAD987658766876787688769876A876B876C876D876E876F8770E0E1E0DDD2AD87718772877387748775E0E287768777E0DBE0D9E0DF87788779E0E0877A877B877C877D877EE0DE8780E0E4878187828783C6F7D8ACD4EBE0E6CAC98784878587868787E0E587888789878A878BB8C1878C878D878E878FE0E7E0E887908791879287938794879587968797E0E9E0E387988799879A879B879C879D879EBABFCCE7879F87A087A1E0EA87A287A387A487A587A687A787A887A987AA87AB87AC87AD87AE87AF87B0CFF987B187B287B387B487B587B687B787B887B987BA87BBE0EB87BC87BD87BE87BF87C087C187C2C8C287C387C487C587C6BDC087C787C887C987CA87CB87CC87CD87CE87CF87D087D187D287D3C4D287D487D587D687D787D887D987DA87DB87DCE0EC87DD87DEE0ED87DF87E0C7F4CBC487E1E0EEBBD8D8B6D2F2E0EFCDC587E2B6DA87E387E487E587E687E787E8E0F187E9D4B087EA87EBC0A7B4D187EC87EDCEA7E0F087EE87EF87F0E0F2B9CC87F187F2B9FACDBCE0F387F387F487F5C6D4E0F487F6D4B287F7C8A6E0F6E0F587F887F987FA87FB87FC87FD87FE8840884188428843884488458846884788488849E0F7884A884BCDC1884C884D884ECAA5884F885088518852D4DADBD7DBD98853DBD8B9E7DBDCDBDDB5D888548855DBDA8856885788588859885ADBDBB3A1DBDF885B885CBBF8885DD6B7885EDBE0885F886088618862BEF988638864B7BB8865DBD0CCAEBFB2BBB5D7F8BFD38866886788688869886ABFE9886B886CBCE1CCB3DBDEB0D3CEEBB7D8D7B9C6C2886D886EC0A4886FCCB98870DBE7DBE1C6BADBE38871DBE88872C5F7887388748875DBEA88768877DBE9BFC088788879887ADBE6DBE5887B887C887D887E8880B4B9C0ACC2A2DBE2DBE48881888288838884D0CDDBED88858886888788888889C0DDDBF2888A888B888C888D888E888F8890B6E28891889288938894DBF3DBD2B9B8D4ABDBEC8895BFD1DBF08896DBD18897B5E68898DBEBBFE58899889A889BDBEE889CDBF1889D889E889FDBF988A088A188A288A388A488A588A688A788A8B9A1B0A388A988AA88AB88AC88AD88AE88AFC2F188B088B1B3C7DBEF88B288B3DBF888B4C6D2DBF488B588B6DBF5DBF7DBF688B788B8DBFE88B9D3F2B2BA88BA88BB88BCDBFD88BD88BE88BF88C088C188C288C388C4DCA488C5DBFB88C688C788C888C9DBFA88CA88CB88CCDBFCC5E0BBF988CD88CEDCA388CF88D0DCA588D1CCC388D288D388D4B6D1DDC088D588D688D7DCA188D8DCA288D988DA88DBC7B588DC88DD88DEB6E988DF88E088E1DCA788E288E388E488E5DCA688E6DCA9B1A488E788E8B5CC88E988EA88EB88EC88EDBFB088EE88EF88F088F188F2D1DF88F388F488F588F6B6C288F788F888F988FA88FB88FC88FD88FE894089418942894389448945DCA88946894789488949894A894B894CCBFAEBF3894D894E894FCBDC89508951CBFE895289538954CCC189558956895789588959C8FB895A895B895C895D895E895FDCAA89608961896289638964CCEEDCAB89658966896789688969896A896B896C896D896E896F897089718972897389748975DBD38976DCAFDCAC8977BEB38978CAFB8979897A897BDCAD897C897D897E89808981898289838984C9CAC4B989858986898789888989C7BDDCAE898A898B898CD4F6D0E6898D898E898F89908991899289938994C4ABB6D589958996899789988999899A899B899C899D899E899F89A089A189A289A389A489A589A6DBD489A789A889A989AAB1DA89AB89AC89ADDBD589AE89AF89B089B189B289B389B489B589B689B789B8DBD689B989BA89BBBABE89BC89BD89BE89BF89C089C189C289C389C489C589C689C789C889C9C8C089CA89CB89CC89CD89CE89CFCABFC8C989D0D7B389D1C9F989D289D3BFC789D489D5BAF889D689D7D2BC89D889D989DA89DB89DC89DD89DE89DFE2BA89E0B4A689E189E2B1B889E389E489E589E689E7B8B489E8CFC489E989EA89EB89ECD9E7CFA6CDE289ED89EED9EDB6E089EFD2B989F089F1B9BB89F289F389F489F5E2B9E2B789F6B4F389F7CCECCCABB7F289F8D8B2D1EBBABB89F9CAA789FA89FBCDB789FC89FDD2C4BFE4BCD0B6E189FEDEC58A408A418A428A43DEC6DBBC8A44D1D98A458A46C6E6C4CEB7EE8A47B7DC8A488A49BFFCD7E08A4AC6F58A4B8A4CB1BCDEC8BDB1CCD7DECA8A4DDEC98A4E8A4F8A508A518A52B5EC8A53C9DD8A548A55B0C28A568A578A588A598A5A8A5B8A5C8A5D8A5E8A5F8A608A618A62C5AEC5AB8A63C4CC8A64BCE9CBFD8A658A668A67BAC38A688A698A6AE5F9C8E7E5FACDFD8A6BD7B1B8BEC2E88A6CC8D18A6D8A6EE5FB8A6F8A708A718A72B6CABCCB8A738A74D1FDE6A18A75C3EE8A768A778A788A79E6A48A7A8A7B8A7C8A7DE5FEE6A5CDD78A7E8A80B7C1E5FCE5FDE6A38A818A82C4DDE6A88A838A84E6A78A858A868A878A888A898A8AC3C38A8BC6DE8A8C8A8DE6AA8A8E8A8F8A908A918A928A938A94C4B78A958A968A97E6A2CABC8A988A998A9A8A9BBDE3B9C3E6A6D0D5CEAF8A9C8A9DE6A9E6B08A9ED2A68A9FBDAAE6AD8AA08AA18AA28AA38AA4E6AF8AA5C0D18AA68AA7D2CC8AA88AA98AAABCA78AAB8AAC8AAD8AAE8AAF8AB08AB18AB28AB38AB48AB58AB6E6B18AB7D2F68AB88AB98ABAD7CB8ABBCDFE8ABCCDDEC2A6E6ABE6ACBDBFE6AEE6B38ABD8ABEE6B28ABF8AC08AC18AC2E6B68AC3E6B88AC48AC58AC68AC7C4EF8AC88AC98ACAC4C88ACB8ACCBEEAC9EF8ACD8ACEE6B78ACFB6F08AD08AD18AD2C3E48AD38AD48AD58AD68AD78AD88AD9D3E9E6B48ADAE6B58ADBC8A28ADC8ADD8ADE8ADF8AE0E6BD8AE18AE28AE3E6B98AE48AE58AE68AE78AE8C6C58AE98AEACDF1E6BB8AEB8AEC8AED8AEE8AEF8AF08AF18AF28AF38AF4E6BC8AF58AF68AF78AF8BBE98AF98AFA8AFB8AFC8AFD8AFE8B40E6BE8B418B428B438B44E6BA8B458B46C0B78B478B488B498B4A8B4B8B4C8B4D8B4E8B4FD3A4E6BFC9F4E6C38B508B51E6C48B528B538B548B55D0F68B568B578B588B598B5A8B5B8B5C8B5D8B5E8B5F8B608B618B628B638B648B658B668B67C3BD8B688B698B6A8B6B8B6C8B6D8B6EC3C4E6C28B6F8B708B718B728B738B748B758B768B778B788B798B7A8B7B8B7CE6C18B7D8B7E8B808B818B828B838B84E6C7CFB18B85EBF48B868B87E6CA8B888B898B8A8B8B8B8CE6C58B8D8B8EBCDEC9A98B8F8B908B918B928B938B94BCB58B958B96CFD38B978B988B998B9A8B9BE6C88B9CE6C98B9DE6CE8B9EE6D08B9F8BA08BA1E6D18BA28BA38BA4E6CBB5D58BA5E6CC8BA68BA7E6CF8BA88BA9C4DB8BAAE6C68BAB8BAC8BAD8BAE8BAFE6CD8BB08BB18BB28BB38BB48BB58BB68BB78BB88BB98BBA8BBB8BBC8BBD8BBE8BBF8BC08BC18BC28BC38BC48BC58BC6E6D28BC78BC88BC98BCA8BCB8BCC8BCD8BCE8BCF8BD08BD18BD2E6D4E6D38BD38BD48BD58BD68BD78BD88BD98BDA8BDB8BDC8BDD8BDE8BDF8BE08BE18BE28BE38BE48BE58BE68BE78BE88BE98BEA8BEB8BECE6D58BEDD9F88BEE8BEFE6D68BF08BF18BF28BF38BF48BF58BF68BF7E6D78BF88BF98BFA8BFB8BFC8BFD8BFE8C408C418C428C438C448C458C468C47D7D3E6DD8C48E6DEBFD7D4D08C49D7D6B4E6CBEFE6DAD8C3D7CED0A28C4AC3CF8C4B8C4CE6DFBCBEB9C2E6DBD1A78C4D8C4EBAA2C2CF8C4FD8AB8C508C518C52CAEBE5EE8C53E6DC8C54B7F58C558C568C578C58C8E68C598C5AC4F58C5B8C5CE5B2C4FE8C5DCBFCE5B3D5AC8C5ED3EECAD8B0B28C5FCBCECDEA8C608C61BAEA8C628C638C64E5B58C65E5B48C66D7DAB9D9D6E6B6A8CDF0D2CBB1A6CAB58C67B3E8C9F3BFCDD0FBCAD2E5B6BBC28C688C698C6ACFDCB9AC8C6B8C6C8C6D8C6ED4D78C6F8C70BAA6D1E7CFFCBCD28C71E5B7C8DD8C728C738C74BFEDB1F6CBDE8C758C76BCC58C77BCC4D2FAC3DCBFDC8C788C798C7A8C7BB8BB8C7C8C7D8C7EC3C28C80BAAED4A28C818C828C838C848C858C868C878C888C89C7DEC4AFB2EC8C8AB9D18C8B8C8CE5BBC1C88C8D8C8ED5AF8C8F8C908C918C928C93E5BC8C94E5BE8C958C968C978C988C998C9A8C9BB4E7B6D4CBC2D1B0B5BC8C9C8C9DCAD98C9EB7E28C9F8CA0C9E48CA1BDAB8CA28CA3CEBED7F08CA48CA58CA68CA7D0A18CA8C9D98CA98CAAB6FBE6D8BCE28CABB3BE8CACC9D08CADE6D9B3A28CAE8CAF8CB08CB1DECC8CB2D3C8DECD8CB3D2A28CB48CB58CB68CB7DECE8CB88CB98CBA8CBBBECD8CBC8CBDDECF8CBE8CBF8CC0CAACD2FCB3DFE5EAC4E1BEA1CEB2C4F2BED6C6A8B2E38CC18CC2BED38CC38CC4C7FCCCEBBDECCEDD8CC58CC6CABAC6C1E5ECD0BC8CC78CC88CC9D5B98CCA8CCB8CCCE5ED8CCD8CCE8CCF8CD0CAF48CD1CDC0C2C58CD2E5EF8CD3C2C4E5F08CD48CD58CD68CD78CD88CD98CDAE5F8CDCD8CDBC9BD8CDC8CDD8CDE8CDF8CE08CE18CE2D2D9E1A88CE38CE48CE58CE6D3EC8CE7CBEAC6F18CE88CE98CEA8CEB8CECE1AC8CED8CEE8CEFE1A7E1A98CF08CF1E1AAE1AF8CF28CF3B2ED8CF4E1ABB8DAE1ADE1AEE1B0B5BAE1B18CF58CF68CF78CF88CF9E1B3E1B88CFA8CFB8CFC8CFD8CFED1D28D40E1B6E1B5C1EB8D418D428D43E1B78D44D4C08D45E1B28D46E1BAB0B68D478D488D498D4AE1B48D4BBFF98D4CE1B98D4D8D4EE1BB8D4F8D508D518D528D538D54E1BE8D558D568D578D588D598D5AE1BC8D5B8D5C8D5D8D5E8D5F8D60D6C58D618D628D638D648D658D668D67CFBF8D688D69E1BDE1BFC2CD8D6AB6EB8D6BD3F88D6C8D6DC7CD8D6E8D6FB7E58D708D718D728D738D748D758D768D778D788D79BEFE8D7A8D7B8D7C8D7D8D7E8D80E1C0E1C18D818D82E1C7B3E78D838D848D858D868D878D88C6E98D898D8A8D8B8D8C8D8DB4DE8D8ED1C28D8F8D908D918D92E1C88D938D94E1C68D958D968D978D988D99E1C58D9AE1C3E1C28D9BB1C08D9C8D9D8D9ED5B8E1C48D9F8DA08DA18DA28DA3E1CB8DA48DA58DA68DA78DA88DA98DAA8DABE1CCE1CA8DAC8DAD8DAE8DAF8DB08DB18DB28DB3EFFA8DB48DB5E1D3E1D2C7B68DB68DB78DB88DB98DBA8DBB8DBC8DBD8DBE8DBF8DC0E1C98DC18DC2E1CE8DC3E1D08DC48DC58DC68DC78DC88DC98DCA8DCB8DCC8DCD8DCEE1D48DCFE1D1E1CD8DD08DD1E1CF8DD28DD38DD48DD5E1D58DD68DD78DD88DD98DDA8DDB8DDC8DDD8DDE8DDF8DE08DE18DE2E1D68DE38DE48DE58DE68DE78DE88DE98DEA8DEB8DEC8DED8DEE8DEF8DF08DF18DF28DF38DF48DF58DF68DF78DF8E1D78DF98DFA8DFBE1D88DFC8DFD8DFE8E408E418E428E438E448E458E468E478E488E498E4A8E4B8E4C8E4D8E4E8E4F8E508E518E528E538E548E55E1DA8E568E578E588E598E5A8E5B8E5C8E5D8E5E8E5F8E608E618E62E1DB8E638E648E658E668E678E688E69CEA18E6A8E6B8E6C8E6D8E6E8E6F8E708E718E728E738E748E758E76E7DD8E77B4A8D6DD8E788E79D1B2B3B28E7A8E7BB9A4D7F3C7C9BEDEB9AE8E7CCED78E7D8E7EB2EEDBCF8E80BCBAD2D1CBC8B0CD8E818E82CFEF8E838E848E858E868E87D9E3BDED8E888E89B1D2CAD0B2BC8E8ACBA7B7AB8E8BCAA68E8C8E8D8E8ECFA38E8F8E90E0F8D5CAE0FB8E918E92E0FAC5C1CCFB8E93C1B1E0F9D6E3B2AFD6C4B5DB8E948E958E968E978E988E998E9A8E9BB4F8D6A18E9C8E9D8E9E8E9F8EA0CFAFB0EF8EA18EA2E0FC8EA38EA48EA58EA68EA7E1A1B3A38EA88EA9E0FDE0FEC3B18EAA8EAB8EAC8EADC3DD8EAEE1A2B7F98EAF8EB08EB18EB28EB38EB4BBCF8EB58EB68EB78EB88EB98EBA8EBBE1A3C4BB8EBC8EBD8EBE8EBF8EC0E1A48EC18EC2E1A58EC38EC4E1A6B4B18EC58EC68EC78EC88EC98ECA8ECB8ECC8ECD8ECE8ECF8ED08ED18ED28ED3B8C9C6BDC4EA8ED4B2A28ED5D0D28ED6E7DBBBC3D3D7D3C48ED7B9E3E2CF8ED88ED98EDAD7AF8EDBC7ECB1D38EDC8EDDB4B2E2D18EDE8EDF8EE0D0F2C2AEE2D08EE1BFE2D3A6B5D7E2D2B5EA8EE2C3EDB8FD8EE3B8AE8EE4C5D3B7CFE2D48EE58EE68EE78EE8E2D3B6C8D7F98EE98EEA8EEB8EEC8EEDCDA58EEE8EEF8EF08EF18EF2E2D88EF3E2D6CAFCBFB5D3B9E2D58EF48EF58EF68EF7E2D78EF88EF98EFA8EFB8EFC8EFD8EFE8F408F418F42C1AEC0C88F438F448F458F468F478F48E2DBE2DAC0AA8F498F4AC1CE8F4B8F4C8F4D8F4EE2DC8F4F8F508F518F528F538F548F558F568F578F588F598F5AE2DD8F5BE2DE8F5C8F5D8F5E8F5F8F608F618F628F638F64DBC88F65D1D3CDA28F668F67BDA88F688F698F6ADEC3D8A5BFAADBCDD2ECC6FAC5AA8F6B8F6C8F6DDEC48F6EB1D7DFAE8F6F8F708F71CABD8F72DFB18F73B9AD8F74D2FD8F75B8A5BAEB8F768F77B3DA8F788F798F7AB5DCD5C58F7B8F7C8F7D8F7EC3D6CFD2BBA18F80E5F3E5F28F818F82E5F48F83CDE48F84C8F58F858F868F878F888F898F8A8F8BB5AFC7BF8F8CE5F68F8D8F8E8F8FECB08F908F918F928F938F948F958F968F978F988F998F9A8F9B8F9C8F9D8F9EE5E68F9FB9E9B5B18FA0C2BCE5E8E5E7E5E98FA18FA28FA38FA4D2CD8FA58FA68FA7E1EAD0CE8FA8CDAE8FA9D1E58FAA8FABB2CAB1EB8FACB1F2C5ED8FAD8FAED5C3D3B08FAFE1DC8FB08FB18FB2E1DD8FB3D2DB8FB4B3B9B1CB8FB58FB68FB7CDF9D5F7E1DE8FB8BEB6B4FD8FB9E1DFBADCE1E0BBB2C2C9E1E18FBA8FBB8FBCD0EC8FBDCDBD8FBE8FBFE1E28FC0B5C3C5C7E1E38FC18FC2E1E48FC38FC48FC58FC6D3F98FC78FC88FC98FCA8FCB8FCCE1E58FCDD1AD8FCE8FCFE1E6CEA28FD08FD18FD28FD38FD48FD5E1E78FD6B5C28FD78FD88FD98FDAE1E8BBD58FDB8FDC8FDD8FDE8FDFD0C4E2E0B1D8D2E48FE08FE1E2E18FE28FE3BCC9C8CC8FE4E2E3ECFEECFDDFAF8FE58FE68FE7E2E2D6BECDFCC3A68FE88FE98FEAE3C38FEB8FECD6D2E2E78FED8FEEE2E88FEF8FF0D3C78FF18FF2E2ECBFEC8FF3E2EDE2E58FF48FF5B3C08FF68FF78FF8C4EE8FF98FFAE2EE8FFB8FFCD0C38FFDBAF6E2E9B7DEBBB3CCACCBCBE2E4E2E6E2EAE2EB8FFE90409041E2F790429043E2F4D4F5E2F390449045C5AD9046D5FAC5C2B2C090479048E2EF9049E2F2C1AFCBBC904A904BB5A1E2F9904C904D904EBCB1E2F1D0D4D4B9E2F5B9D6E2F6904F90509051C7D390529053905490559056E2F0905790589059905A905BD7DCEDA1905C905DE2F8905EEDA5E2FECAD1905F906090619062906390649065C1B59066BBD090679068BFD69069BAE3906A906BCBA1906C906D906EEDA6EDA3906F9070EDA29071907290739074BBD6EDA7D0F490759076EDA4BADEB6F7E3A1B6B2CCF1B9A79077CFA2C7A190789079BFD2907A907BB6F1907CE2FAE2FBE2FDE2FCC4D5E3A2907DD3C1907E90809081E3A7C7C49082908390849085CFA490869087E3A9BAB790889089908A908BE3A8908CBBDA908DE3A3908E908F9090E3A4E3AA9091E3A69092CEF2D3C690939094BBBC90959096D4C39097C4FA90989099EDA8D0FCE3A5909AC3F5909BE3ADB1AF909CE3B2909D909E909FBCC290A090A1E3ACB5BF90A290A390A490A590A690A790A890A9C7E9E3B090AA90AB90ACBEAACDEF90AD90AE90AF90B090B1BBF390B290B390B4CCE890B590B6E3AF90B7E3B190B8CFA7E3AE90B9CEA9BBDD90BA90BB90BC90BD90BEB5EBBEE5B2D2B3CD90BFB1B9E3ABB2D1B5ACB9DFB6E890C090C1CFEBE3B790C2BBCC90C390C4C8C7D0CA90C590C690C790C890C9E3B8B3EE90CA90CB90CC90CDEDA990CED3FAD3E490CF90D090D1EDAAE3B9D2E290D290D390D490D590D6E3B590D790D890D990DAD3DE90DB90DC90DD90DEB8D0E3B390DF90E0E3B6B7DF90E1E3B4C0A290E290E390E4E3BA90E590E690E790E890E990EA90EB90EC90ED90EE90EF90F090F190F290F390F490F590F690F7D4B890F890F990FA90FB90FC90FD90FE9140B4C89141E3BB9142BBC59143C9F791449145C9E5914691479148C4BD9149914A914B914C914D914E914FEDAB9150915191529153C2FD9154915591569157BBDBBFAE91589159915A915B915C915D915ECEBF915F916091619162E3BC9163BFB6916491659166916791689169916A916B916C916D916E916F9170917191729173917491759176B1EF91779178D4F79179917A917B917C917DE3BE917E9180918191829183918491859186EDAD918791889189918A918B918C918D918E918FE3BFBAA9EDAC91909191E3BD91929193919491959196919791989199919A919BE3C0919C919D919E919F91A091A1BAB691A291A391A4B6AE91A591A691A791A891A9D0B891AAB0C3EDAE91AB91AC91AD91AE91AFEDAFC0C191B0E3C191B191B291B391B491B591B691B791B891B991BA91BB91BC91BD91BE91BF91C091C1C5B391C291C391C491C591C691C791C891C991CA91CB91CC91CD91CE91CFE3C291D091D191D291D391D491D591D691D791D8DCB291D991DA91DB91DC91DD91DEEDB091DFB8EA91E0CEECEAA7D0E7CAF9C8D6CFB7B3C9CED2BDE491E191E2E3DEBBF2EAA8D5BD91E3C6DDEAA991E491E591E6EAAA91E7EAACEAAB91E8EAAEEAAD91E991EA91EB91ECBDD891EDEAAF91EEC2BE91EF91F091F191F2B4C1B4F791F391F4BBA791F591F691F791F891F9ECE6ECE5B7BFCBF9B1E291FAECE791FB91FC91FDC9C8ECE8ECE991FECAD6DED0B2C5D4FA92409241C6CBB0C7B4F2C8D3924292439244CDD092459246BFB8924792489249924A924B924C924DBFDB924E924FC7A4D6B49250C0A9DED1C9A8D1EFC5A4B0E7B3B6C8C592519252B0E292539254B7F692559256C5FA92579258B6F39259D5D2B3D0BCBC925A925B925CB3AD925D925E925F9260BEF1B0D1926192629263926492659266D2D6CAE3D7A59267CDB6B6B6BFB9D5DB9268B8A7C5D79269926A926BDED2BFD9C2D5C7C0926CBBA4B1A8926D926EC5EA926F9270C5FBCCA79271927292739274B1A7927592769277B5D692789279927AC4A8927BDED3D1BAB3E9927CC3F2927D927EB7F79280D6F4B5A3B2F0C4B4C4E9C0ADDED49281B0E8C5C4C1E09282B9D59283BEDCCDD8B0CE9284CDCFDED6BED0D7BEDED5D5D0B0DD92859286C4E292879288C2A3BCF09289D3B5C0B9C5A1B2A6D4F1928A928BC0A8CAC3DED7D5FC928CB9B0928DC8ADCBA9928EDED9BFBD928F929092919292C6B4D7A7CAB0C4C39293B3D6B9D29294929592969297D6B8EAFCB0B492989299929A929BBFE6929C929DCCF4929E929F92A092A1CDDA92A292A392A4D6BFC2CE92A5CECECCA2D0AEC4D3B5B2DED8D5F5BCB7BBD392A692A7B0A492A8C5B2B4EC92A992AA92ABD5F192AC92ADEAFD92AE92AF92B092B192B292B3DEDACDA692B492B5CDEC92B692B792B892B9CEE6DEDC92BACDB1C0A692BB92BCD7BD92BDDEDBB0C6BAB4C9D3C4F3BEE892BE92BF92C092C1B2B692C292C392C492C592C692C792C892C9C0CCCBF092CABCF1BBBBB5B792CB92CC92CDC5F592CEDEE692CF92D092D1DEE3BEDD92D292D3DEDF92D492D592D692D7B4B7BDDD92D892D9DEE0C4ED92DA92DB92DC92DDCFC692DEB5E092DF92E092E192E2B6DECADAB5F4DEE592E3D5C692E4DEE1CCCDC6FE92E5C5C592E692E792E8D2B492E9BEF292EA92EB92EC92ED92EE92EF92F0C2D392F1CCBDB3B892F2BDD392F3BFD8CDC6D1DAB4EB92F4DEE4DEDDDEE792F5EAFE92F692F7C2B0DEE292F892F9D6C0B5A792FAB2F492FBDEE892FCDEF292FD92FE934093419342DEED9343DEF193449345C8E0934693479348D7E1DEEFC3E8CCE19349B2E5934A934B934CD2BE934D934E934F9350935193529353DEEE9354DEEBCED59355B4A79356935793589359935ABFABBEBE935B935CBDD2935D935E935F9360DEE99361D4AE9362DEDE9363DEEA9364936593669367C0BF9368DEECB2F3B8E9C2A79369936ABDC1936B936C936D936E936FDEF5DEF893709371B2ABB4A493729373B4EAC9A6937493759376937793789379DEF6CBD1937AB8E3937BDEF7DEFA937C937D937E9380DEF9938193829383CCC29384B0E1B4EE93859386938793889389938AE5BA938B938C938D938E938FD0AF93909391B2EB9392EBA19393DEF493949395C9E3DEF3B0DAD2A1B1F79396CCAF939793989399939A939B939C939DDEF0939ECBA4939F93A093A1D5AA93A293A393A493A593A6DEFB93A793A893A993AA93AB93AC93AD93AEB4DD93AFC4A693B093B193B2DEFD93B393B493B593B693B793B893B993BA93BB93BCC3FEC4A1DFA193BD93BE93BF93C093C193C293C3C1CC93C4DEFCBEEF93C5C6B293C693C793C893C993CA93CB93CC93CD93CEB3C5C8F693CF93D0CBBADEFE93D193D2DFA493D393D493D593D6D7B293D793D893D993DA93DBB3B793DC93DD93DE93DFC1C393E093E1C7CBB2A5B4E993E2D7AB93E393E493E593E6C4EC93E7DFA2DFA393E8DFA593E9BAB393EA93EB93ECDFA693EDC0DE93EE93EFC9C393F093F193F293F393F493F593F6B2D9C7E693F7DFA793F8C7DC93F993FA93FB93FCDFA8EBA293FD93FE944094419442CBD3944394449445DFAA9446DFA99447B2C194489449944A944B944C944D944E944F9450945194529453945494559456945794589459945A945B945C945D945E945F9460C5CA94619462946394649465946694679468DFAB9469946A946B946C946D946E946F9470D4DC94719472947394749475C8C19476947794789479947A947B947C947D947E948094819482DFAC94839484948594869487BEF094889489DFADD6A7948A948B948C948DEAB7EBB6CAD5948ED8FCB8C4948FB9A594909491B7C5D5FE94929493949494959496B9CA94979498D0A7F4CD9499949AB5D0949B949CC3F4949DBEC8949E949F94A0EBB7B0BD94A194A2BDCC94A3C1B294A4B1D6B3A894A594A694A7B8D2C9A294A894A9B6D894AA94AB94AC94ADEBB8BEB494AE94AF94B0CAFD94B1C7C394B2D5FB94B394B4B7F394B594B694B794B894B994BA94BB94BC94BD94BE94BF94C094C194C294C3CEC494C494C594C6D5ABB1F394C794C894C9ECB3B0DF94CAECB594CB94CC94CDB6B794CEC1CF94CFF5FAD0B194D094D1D5E594D2CED394D394D4BDEFB3E294D5B8AB94D6D5B694D7EDBD94D8B6CF94D9CBB9D0C294DA94DB94DC94DD94DE94DF94E094E1B7BD94E294E3ECB6CAA994E494E594E6C5D494E7ECB9ECB8C2C3ECB794E894E994EA94EBD0FDECBA94ECECBBD7E594ED94EEECBC94EF94F094F1ECBDC6EC94F294F394F494F594F694F794F894F9CEDE94FABCC894FB94FCC8D5B5A9BEC9D6BCD4E794FD94FED1AED0F1EAB8EAB9EABABAB59540954195429543CAB1BFF595449545CDFA9546954795489549954AEAC0954BB0BAEABE954C954DC0A5954E954F9550EABB9551B2FD9552C3F7BBE8955395549555D2D7CEF4EABF955695579558EABC9559955A955BEAC3955CD0C7D3B3955D955E955F9560B4BA9561C3C1D7F29562956395649565D5D19566CAC79567EAC595689569EAC4EAC7EAC6956A956B956C956D956ED6E7956FCFD495709571EACB9572BBCE9573957495759576957795789579BDFAC9CE957A957BEACC957C957DC9B9CFFEEACAD4CEEACDEACF957E9580CDED9581958295839584EAC99585EACE95869587CEEE9588BBDE9589B3BF958A958B958C958D958EC6D5BEB0CEFA958F95909591C7E79592BEA7EAD095939594D6C7959595969597C1C095989599959AD4DD959BEAD1959C959DCFBE959E959F95A095A1EAD295A295A395A495A5CAEE95A695A795A895A9C5AFB0B595AA95AB95AC95AD95AEEAD495AF95B095B195B295B395B495B595B695B7EAD3F4DF95B895B995BA95BB95BCC4BA95BD95BE95BF95C095C1B1A995C295C395C495C5E5DF95C695C795C895C9EAD595CA95CB95CC95CD95CE95CF95D095D195D295D395D495D595D695D795D895D995DA95DB95DC95DD95DE95DF95E095E195E295E3CAEF95E4EAD6EAD7C6D895E595E695E795E895E995EA95EB95ECEAD895ED95EEEAD995EF95F095F195F295F395F4D4BB95F5C7FAD2B7B8FC95F695F7EAC295F8B2DC95F995FAC2FC95FBD4F8CCE6D7EE95FC95FD95FE9640964196429643D4C2D3D0EBC3C5F39644B7FE96459646EBD4964796489649CBB7EBDE964AC0CA964B964C964DCDFB964EB3AF964FC6DA965096519652965396549655EBFC9656C4BE9657CEB4C4A9B1BED4FD9658CAF59659D6EC965A965BC6D3B6E4965C965D965E965FBBFA96609661D0E096629663C9B19664D4D3C8A896659666B8CB9667E8BEC9BC96689669E8BB966AC0EED0D3B2C4B4E5966BE8BC966C966DD5C8966E966F967096719672B6C59673E8BDCAF8B8DCCCF5967496759676C0B496779678D1EEE8BFE8C29679967ABABC967BB1ADBDDC967CEABDE8C3967DE8C6967EE8CB9680968196829683E8CC9684CBC9B0E59685BCAB96869687B9B996889689E8C1968ACDF7968BE8CA968C968D968E968FCEF69690969196929693D5ED9694C1D6E8C49695C3B69696B9FBD6A6E8C8969796989699CAE0D4E6969AE8C0969BE8C5E8C7969CC7B9B7E3969DE8C9969EBFDDE8D2969F96A0E8D796A1E8D5BCDCBCCFE8DB96A296A396A496A596A696A796A896A9E8DE96AAE8DAB1FA96AB96AC96AD96AE96AF96B096B196B296B396B4B0D8C4B3B8CCC6E2C8BEC8E196B596B696B7E8CFE8D4E8D696B8B9F1E8D8D7F596B9C4FB96BAE8DC96BB96BCB2E996BD96BE96BFE8D196C096C1BCED96C296C3BFC2E8CDD6F996C4C1F8B2F196C596C696C796C896C996CA96CB96CCE8DF96CDCAC1E8D996CE96CF96D096D1D5A496D2B1EAD5BBE8CEE8D0B6B0E8D396D3E8DDC0B896D4CAF796D5CBA896D696D7C6DCC0F596D896D996DA96DB96DCE8E996DD96DE96DFD0A396E096E196E296E396E496E596E6E8F2D6EA96E796E896E996EA96EB96EC96EDE8E0E8E196EE96EF96F0D1F9BACBB8F996F196F2B8F1D4D4E8EF96F3E8EEE8ECB9F0CCD2E8E6CEA6BFF296F4B0B8E8F1E8F096F5D7C096F6E8E496F7CDA9C9A396F8BBB8BDDBE8EA96F996FA96FB96FC96FD96FE9740974197429743E8E2E8E3E8E5B5B5E8E7C7C5E8EBE8EDBDB0D7AE9744E8F897459746974797489749974A974B974CE8F5974DCDB0E8F6974E974F9750975197529753975497559756C1BA9757E8E89758C3B7B0F09759975A975B975C975D975E975F9760E8F4976197629763E8F7976497659766B9A3976797689769976A976B976C976D976E976F9770C9D2977197729773C3CECEE0C0E69774977597769777CBF39778CCDDD0B59779977ACAE1977BE8F3977C977D977E9780978197829783978497859786BCEC9787E8F997889789978A978B978C978DC3DE978EC6E5978FB9F79790979197929793B0F497949795D7D897969797BCAC9798C5EF9799979A979B979C979DCCC4979E979FE9A697A097A197A297A397A497A597A697A797A897A9C9AD97AAE9A2C0E297AB97AC97ADBFC397AE97AF97B0E8FEB9D797B1E8FB97B297B397B497B5E9A497B697B797B8D2CE97B997BA97BB97BC97BDE9A397BED6B2D7B597BFE9A797C0BDB797C197C297C397C497C597C697C797C897C997CA97CB97CCE8FCE8FD97CD97CE97CFE9A197D097D197D297D397D497D597D697D7CDD697D897D9D2AC97DA97DB97DCE9B297DD97DE97DF97E0E9A997E197E297E3B4AA97E4B4BB97E597E6E9AB97E797E897E997EA97EB97EC97ED97EE97EF97F097F197F297F397F497F597F697F7D0A897F897F9E9A597FA97FBB3FE97FC97FDE9ACC0E397FEE9AA98409841E9B998429843E9B89844984598469847E9AE98489849E8FA984A984BE9A8984C984D984E984F9850BFACE9B1E9BA98519852C2A5985398549855E9AF9856B8C59857E9AD9858D3DCE9B4E9B5E9B79859985A985BE9C7985C985D985E985F98609861C0C6E9C598629863E9B098649865E9BBB0F19866986798689869986A986B986C986D986E986FE9BCD5A598709871E9BE9872E9BF987398749875E9C198769877C1F198789879C8B6987A987B987CE9BD987D987E988098819882E9C29883988498859886988798889889988AE9C3988BE9B3988CE9B6988DBBB1988E988F9890E9C0989198929893989498959896BCF7989798989899E9C4E9C6989A989B989C989D989E989F98A098A198A298A398A498A5E9CA98A698A798A898A9E9CE98AA98AB98AC98AD98AE98AF98B098B198B298B3B2DB98B4E9C898B598B698B798B898B998BA98BB98BC98BD98BEB7AE98BF98C098C198C298C398C498C598C698C798C898C998CAE9CBE9CC98CB98CC98CD98CE98CF98D0D5C198D1C4A398D298D398D498D598D698D7E9D898D8BAE198D998DA98DB98DCE9C998DDD3A398DE98DF98E0E9D498E198E298E398E498E598E698E7E9D7E9D098E898E998EA98EB98ECE9CF98ED98EEC7C198EF98F098F198F298F398F498F598F6E9D298F798F898F998FA98FB98FC98FDE9D9B3C898FEE9D399409941994299439944CFF0994599469947E9CD99489949994A994B994C994D994E994F995099519952B3F79953995499559956995799589959E9D6995A995BE9DA995C995D995ECCB4995F99609961CFAD99629963996499659966996799689969996AE9D5996BE9DCE9DB996C996D996E996F9970E9DE99719972997399749975997699779978E9D19979997A997B997C997D997E99809981E9DD9982E9DFC3CA9983998499859986998799889989998A998B998C998D998E998F9990999199929993999499959996999799989999999A999B999C999D999E999F99A099A199A299A399A499A599A699A799A899A999AA99AB99AC99AD99AE99AF99B099B199B299B399B499B599B699B799B899B999BA99BB99BC99BD99BE99BF99C099C199C299C399C499C599C699C799C899C999CA99CB99CC99CD99CE99CF99D099D199D299D399D499D599D699D799D899D999DA99DB99DC99DD99DE99DF99E099E199E299E399E499E599E699E799E899E999EA99EB99EC99ED99EE99EF99F099F199F299F399F499F5C7B7B4CEBBB6D0C0ECA399F699F7C5B799F899F999FA99FB99FC99FD99FE9A409A419A42D3FB9A439A449A459A46ECA49A47ECA5C6DB9A489A499A4ABFEE9A4B9A4C9A4D9A4EECA69A4F9A50ECA7D0AA9A51C7B89A529A53B8E89A549A559A569A579A589A599A5A9A5B9A5C9A5D9A5E9A5FECA89A609A619A629A639A649A659A669A67D6B9D5FDB4CBB2BDCEE4C6E79A689A69CDE19A6A9A6B9A6C9A6D9A6E9A6F9A709A719A729A739A749A759A769A77B4F59A78CBC0BCDF9A799A7A9A7B9A7CE9E2E9E3D1EAE9E59A7DB4F9E9E49A7ED1B3CAE2B2D09A80E9E89A819A829A839A84E9E6E9E79A859A86D6B39A879A889A89E9E9E9EA9A8A9A8B9A8C9A8D9A8EE9EB9A8F9A909A919A929A939A949A959A96E9EC9A979A989A999A9A9A9B9A9C9A9D9A9EECAFC5B9B6CE9A9FD2F39AA09AA19AA29AA39AA49AA59AA6B5EE9AA7BBD9ECB19AA89AA9D2E39AAA9AAB9AAC9AAD9AAECEE39AAFC4B89AB0C3BF9AB19AB2B6BED8B9B1C8B1CFB1D1C5FE9AB3B1D09AB4C3AB9AB59AB69AB79AB89AB9D5B19ABA9ABB9ABC9ABD9ABE9ABF9AC09AC1EBA4BAC19AC29AC39AC4CCBA9AC59AC69AC7EBA59AC8EBA79AC99ACA9ACBEBA89ACC9ACD9ACEEBA69ACF9AD09AD19AD29AD39AD49AD5EBA9EBABEBAA9AD69AD79AD89AD99ADAEBAC9ADBCACFD8B5C3F19ADCC3A5C6F8EBADC4CA9ADDEBAEEBAFEBB0B7D59ADE9ADF9AE0B7FA9AE1EBB1C7E29AE2EBB39AE3BAA4D1F5B0B1EBB2EBB49AE49AE59AE6B5AAC2C8C7E89AE7EBB59AE8CBAEE3DF9AE99AEAD3C09AEB9AEC9AED9AEED9DB9AEF9AF0CDA1D6ADC7F39AF19AF29AF3D9E0BBE39AF4BABAE3E29AF59AF69AF79AF89AF9CFAB9AFA9AFB9AFCE3E0C9C79AFDBAB99AFE9B409B41D1B4E3E1C8EAB9AFBDADB3D8CEDB9B429B43CCC09B449B459B46E3E8E3E9CDF49B479B489B499B4A9B4BCCAD9B4CBCB39B4DE3EA9B4EE3EB9B4F9B50D0DA9B519B529B53C6FBB7DA9B549B55C7DFD2CACED69B56E3E4E3EC9B57C9F2B3C19B589B59E3E79B5A9B5BC6E3E3E59B5C9B5DEDB3E3E69B5E9B5F9B609B61C9B39B62C5E69B639B649B65B9B59B66C3BB9B67E3E3C5BDC1A4C2D9B2D79B68E3EDBBA6C4AD9B69E3F0BEDA9B6A9B6BE3FBE3F5BAD39B6C9B6D9B6E9B6FB7D0D3CD9B70D6CED5D3B9C1D5B4D1D89B719B729B739B74D0B9C7F69B759B769B77C8AAB2B49B78C3DA9B799B7A9B7BE3EE9B7C9B7DE3FCE3EFB7A8E3F7E3F49B7E9B809B81B7BA9B829B83C5A29B84E3F6C5DDB2A8C6FC9B85C4E09B869B87D7A29B88C0E1E3F99B899B8AE3FAE3FDCCA9E3F39B8BD3BE9B8CB1C3EDB4E3F1E3F29B8DE3F8D0BAC6C3D4F3E3FE9B8E9B8FBDE09B909B91E4A79B929B93E4A69B949B959B96D1F3E4A39B97E4A99B989B999B9AC8F79B9B9B9C9B9D9B9ECFB49B9FE4A8E4AEC2E59BA09BA1B6B49BA29BA39BA49BA59BA69BA7BDF29BA8E4A29BA99BAABAE9E4AA9BAB9BACE4AC9BAD9BAEB6FDD6DEE4B29BAFE4AD9BB09BB19BB2E4A19BB3BBEECDDDC7A2C5C99BB49BB5C1F79BB6E4A49BB7C7B3BDACBDBDE4A59BB8D7C7B2E29BB9E4ABBCC3E4AF9BBABBEBE4B0C5A8E4B19BBB9BBC9BBD9BBED5E3BFA39BBFE4BA9BC0E4B79BC1E4BB9BC29BC3E4BD9BC49BC5C6D69BC69BC7BAC6C0CB9BC89BC99BCAB8A1E4B49BCB9BCC9BCD9BCED4A19BCF9BD0BAA3BDFE9BD19BD29BD3E4BC9BD49BD59BD69BD79BD8CDBF9BD99BDAC4F99BDB9BDCCFFBC9E69BDD9BDED3BF9BDFCFD19BE09BE1E4B39BE2E4B8E4B9CCE99BE39BE49BE59BE69BE7CCCE9BE8C0D4E4B5C1B0E4B6CED09BE9BBC1B5D39BEAC8F3BDA7D5C7C9ACB8A2E4CA9BEB9BECE4CCD1C49BED9BEED2BA9BEF9BF0BAAD9BF19BF2BAD49BF39BF49BF59BF69BF79BF8E4C3B5ED9BF99BFA9BFBD7CDE4C0CFFDE4BF9BFC9BFD9BFEC1DCCCCA9C409C419C429C43CAE79C449C459C469C47C4D79C48CCD4E4C89C499C4A9C4BE4C7E4C19C4CE4C4B5AD9C4D9C4ED3D99C4FE4C69C509C519C529C53D2F9B4E39C54BBB49C559C56C9EE9C57B4BE9C589C599C5ABBEC9C5BD1CD9C5CCCEDEDB59C5D9C5E9C5F9C609C619C629C639C64C7E59C659C669C679C68D4A89C69E4CBD7D5E4C29C6ABDA5E4C59C6B9C6CD3E69C6DE4C9C9F89C6E9C6FE4BE9C709C71D3E59C729C73C7FEB6C99C74D4FCB2B3E4D79C759C769C77CEC29C78E4CD9C79CEBC9C7AB8DB9C7B9C7CE4D69C7DBFCA9C7E9C809C81D3CE9C82C3EC9C839C849C859C869C879C889C899C8AC5C8E4D89C8B9C8C9C8D9C8E9C8F9C909C919C92CDC4E4CF9C939C949C959C96E4D4E4D59C97BAFE9C98CFE69C999C9AD5BF9C9B9C9C9C9DE4D29C9E9C9F9CA09CA19CA29CA39CA49CA59CA69CA79CA8E4D09CA99CAAE4CE9CAB9CAC9CAD9CAE9CAF9CB09CB19CB29CB39CB49CB59CB69CB79CB89CB9CDE5CAAA9CBA9CBB9CBCC0A39CBDBDA6E4D39CBE9CBFB8C89CC09CC19CC29CC39CC4E4E7D4B49CC59CC69CC79CC89CC99CCA9CCBE4DB9CCC9CCD9CCEC1EF9CCF9CD0E4E99CD19CD2D2E79CD39CD4E4DF9CD5E4E09CD69CD7CFAA9CD89CD99CDA9CDBCBDD9CDCE4DAE4D19CDDE4E59CDEC8DCE4E39CDF9CE0C4E7E4E29CE1E4E19CE29CE39CE4B3FCE4E89CE59CE69CE79CE8B5E19CE99CEA9CEBD7CC9CEC9CED9CEEE4E69CEFBBAC9CF0D7D2CCCFEBF89CF1E4E49CF29CF3B9F69CF49CF59CF6D6CDE4D9E4DCC2FAE4DE9CF7C2CBC0C4C2D09CF8B1F5CCB29CF99CFA9CFB9CFC9CFD9CFE9D409D419D429D43B5CE9D449D459D469D47E4EF9D489D499D4A9D4B9D4C9D4D9D4E9D4FC6AF9D509D519D52C6E19D539D54E4F59D559D569D579D589D59C2A99D5A9D5B9D5CC0ECD1DDE4EE9D5D9D5E9D5F9D609D619D629D639D649D659D66C4AE9D679D689D69E4ED9D6A9D6B9D6C9D6DE4F6E4F4C2FE9D6EE4DD9D6FE4F09D70CAFE9D71D5C49D729D73E4F19D749D759D769D779D789D799D7AD1FA9D7B9D7C9D7D9D7E9D809D819D82E4EBE4EC9D839D849D85E4F29D86CEAB9D879D889D899D8A9D8B9D8C9D8D9D8E9D8F9D90C5CB9D919D929D93C7B19D94C2BA9D959D969D97E4EA9D989D999D9AC1CA9D9B9D9C9D9D9D9E9D9F9DA0CCB6B3B19DA19DA29DA3E4FB9DA4E4F39DA59DA69DA7E4FA9DA8E4FD9DA9E4FC9DAA9DAB9DAC9DAD9DAE9DAF9DB0B3CE9DB19DB29DB3B3BAE4F79DB49DB5E4F9E4F8C5EC9DB69DB79DB89DB99DBA9DBB9DBC9DBD9DBE9DBF9DC09DC19DC2C0BD9DC39DC49DC59DC6D4E89DC79DC89DC99DCA9DCBE5A29DCC9DCD9DCE9DCF9DD09DD19DD29DD39DD49DD59DD6B0C49DD79DD8E5A49DD99DDAE5A39DDB9DDC9DDD9DDE9DDF9DE0BCA49DE1E5A59DE29DE39DE49DE59DE69DE7E5A19DE89DE99DEA9DEB9DEC9DED9DEEE4FEB1F49DEF9DF09DF19DF29DF39DF49DF59DF69DF79DF89DF9E5A89DFAE5A9E5A69DFB9DFC9DFD9DFE9E409E419E429E439E449E459E469E47E5A7E5AA9E489E499E4A9E4B9E4C9E4D9E4E9E4F9E509E519E529E539E549E559E569E579E589E599E5A9E5B9E5C9E5D9E5E9E5F9E609E619E629E639E649E659E669E679E68C6D99E699E6A9E6B9E6C9E6D9E6E9E6F9E70E5ABE5AD9E719E729E739E749E759E769E77E5AC9E789E799E7A9E7B9E7C9E7D9E7E9E809E819E829E839E849E859E869E879E889E89E5AF9E8A9E8B9E8CE5AE9E8D9E8E9E8F9E909E919E929E939E949E959E969E979E989E999E9A9E9B9E9C9E9D9E9EB9E09E9F9EA0E5B09EA19EA29EA39EA49EA59EA69EA79EA89EA99EAA9EAB9EAC9EAD9EAEE5B19EAF9EB09EB19EB29EB39EB49EB59EB69EB79EB89EB99EBABBF0ECE1C3F09EBBB5C6BBD29EBC9EBD9EBE9EBFC1E9D4EE9EC0BEC49EC19EC29EC3D7C69EC4D4D6B2D3ECBE9EC59EC69EC79EC8EAC19EC99ECA9ECBC2AFB4B69ECC9ECD9ECED1D79ECF9ED09ED1B3B49ED2C8B2BFBBECC09ED39ED4D6CB9ED59ED6ECBFECC19ED79ED89ED99EDA9EDB9EDC9EDD9EDE9EDF9EE09EE19EE29EE3ECC5BEE6CCBFC5DABEBC9EE4ECC69EE5B1FE9EE69EE79EE8ECC4D5A8B5E39EE9ECC2C1B6B3E39EEA9EEBECC3CBB8C0C3CCFE9EEC9EED9EEE9EEFC1D29EF0ECC89EF19EF29EF39EF49EF59EF69EF79EF89EF99EFA9EFB9EFC9EFDBAE6C0D39EFED6F29F409F419F42D1CC9F439F449F459F46BFBE9F47B7B3C9D5ECC7BBE29F48CCCCBDFDC8C89F49CFA99F4A9F4B9F4C9F4D9F4E9F4F9F50CDE99F51C5EB9F529F539F54B7E99F559F569F579F589F599F5A9F5B9F5C9F5D9F5E9F5FD1C9BAB89F609F619F629F639F64ECC99F659F66ECCA9F67BBC0ECCB9F68ECE2B1BAB7D99F699F6A9F6B9F6C9F6D9F6E9F6F9F709F719F729F73BDB99F749F759F769F779F789F799F7A9F7BECCCD1E6ECCD9F7C9F7D9F7E9F80C8BB9F819F829F839F849F859F869F879F889F899F8A9F8B9F8C9F8D9F8EECD19F8F9F909F919F92ECD39F93BBCD9F94BCE59F959F969F979F989F999F9A9F9B9F9C9F9D9F9E9F9F9FA09FA1ECCF9FA2C9B79FA39FA49FA59FA69FA7C3BA9FA8ECE3D5D5ECD09FA99FAA9FAB9FAC9FADD6F39FAE9FAF9FB0ECD2ECCE9FB19FB29FB39FB4ECD49FB5ECD59FB69FB7C9BF9FB89FB99FBA9FBB9FBC9FBDCFA89FBE9FBF9FC09FC19FC2D0DC9FC39FC49FC59FC6D1AC9FC79FC89FC99FCAC8DB9FCB9FCC9FCDECD6CEF59FCE9FCF9FD09FD19FD2CAECECDA9FD39FD49FD59FD69FD79FD89FD9ECD99FDA9FDB9FDCB0BE9FDD9FDE9FDF9FE09FE19FE2ECD79FE3ECD89FE49FE59FE6ECE49FE79FE89FE99FEA9FEB9FEC9FED9FEE9FEFC8BC9FF09FF19FF29FF39FF49FF59FF69FF79FF89FF9C1C79FFA9FFB9FFC9FFD9FFEECDCD1E0A040A041A042A043A044A045A046A047A048A049ECDBA04AA04BA04CA04DD4EFA04EECDDA04FA050A051A052A053A054DBC6A055A056A057A058A059A05AA05BA05CA05DA05EECDEA05FA060A061A062A063A064A065A066A067A068A069A06AB1ACA06BA06CA06DA06EA06FA070A071A072A073A074A075A076A077A078A079A07AA07BA07CA07DA07EA080A081ECDFA082A083A084A085A086A087A088A089A08AA08BECE0A08CD7A6A08DC5C0A08EA08FA090EBBCB0AEA091A092A093BEF4B8B8D2AFB0D6B5F9A094D8B3A095CBACA096E3DDA097A098A099A09AA09BA09CA09DC6ACB0E6A09EA09FA0A0C5C6EBB9A0A1A0A2A0A3A0A4EBBAA0A5A0A6A0A7EBBBA0A8A0A9D1C0A0AAC5A3A0ABEAF2A0ACC4B2A0ADC4B5C0CEA0AEA0AFA0B0EAF3C4C1A0B1CEEFA0B2A0B3A0B4A0B5EAF0EAF4A0B6A0B7C9FCA0B8A0B9C7A3A0BAA0BBA0BCCCD8CEFEA0BDA0BEA0BFEAF5EAF6CFACC0E7A0C0A0C1EAF7A0C2A0C3A0C4A0C5A0C6B6BFEAF8A0C7EAF9A0C8EAFAA0C9A0CAEAFBA0CBA0CCA0CDA0CEA0CFA0D0A0D1A0D2A0D3A0D4A0D5A0D6EAF1A0D7A0D8A0D9A0DAA0DBA0DCA0DDA0DEA0DFA0E0A0E1A0E2C8AEE1EBA0E3B7B8E1ECA0E4A0E5A0E6E1EDA0E7D7B4E1EEE1EFD3CCA0E8A0E9A0EAA0EBA0ECA0EDA0EEE1F1BFF1E1F0B5D2A0EFA0F0A0F1B1B7A0F2A0F3A0F4A0F5E1F3E1F2A0F6BAFCA0F7E1F4A0F8A0F9A0FAA0FBB9B7A0FCBED1A0FDA0FEAA40AA41C4FCAA42BADDBDC6AA43AA44AA45AA46AA47AA48E1F5E1F7AA49AA4AB6C0CFC1CAA8E1F6D5F8D3FCE1F8E1FCE1F9AA4BAA4CE1FAC0EAAA4DE1FEE2A1C0C7AA4EAA4FAA50AA51E1FBAA52E1FDAA53AA54AA55AA56AA57AA58E2A5AA59AA5AAA5BC1D4AA5CAA5DAA5EAA5FE2A3AA60E2A8B2FEE2A2AA61AA62AA63C3CDB2C2E2A7E2A6AA64AA65E2A4E2A9AA66AA67E2ABAA68AA69AA6AD0C9D6EDC3A8E2ACAA6BCFD7AA6CAA6DE2AEAA6EAA6FBAEFAA70AA71E9E0E2ADE2AAAA72AA73AA74AA75BBABD4B3AA76AA77AA78AA79AA7AAA7BAA7CAA7DAA7EAA80AA81AA82AA83E2B0AA84AA85E2AFAA86E9E1AA87AA88AA89AA8AE2B1AA8BAA8CAA8DAA8EAA8FAA90AA91AA92E2B2AA93AA94AA95AA96AA97AA98AA99AA9AAA9BAA9CAA9DE2B3CCA1AA9EE2B4AA9FAAA0AB40AB41AB42AB43AB44AB45AB46AB47AB48AB49AB4AAB4BE2B5AB4CAB4DAB4EAB4FAB50D0FEAB51AB52C2CAAB53D3F1AB54CDF5AB55AB56E7E0AB57AB58E7E1AB59AB5AAB5BAB5CBEC1AB5DAB5EAB5FAB60C2EAAB61AB62AB63E7E4AB64AB65E7E3AB66AB67AB68AB69AB6AAB6BCDE6AB6CC3B5AB6DAB6EE7E2BBB7CFD6AB6FC1E1E7E9AB70AB71AB72E7E8AB73AB74E7F4B2A3AB75AB76AB77AB78E7EAAB79E7E6AB7AAB7BAB7CAB7DAB7EE7ECE7EBC9BAAB80AB81D5E4AB82E7E5B7A9E7E7AB83AB84AB85AB86AB87AB88AB89E7EEAB8AAB8BAB8CAB8DE7F3AB8ED6E9AB8FAB90AB91AB92E7EDAB93E7F2AB94E7F1AB95AB96AB97B0E0AB98AB99AB9AAB9BE7F5AB9CAB9DAB9EAB9FABA0AC40AC41AC42AC43AC44AC45AC46AC47AC48AC49AC4AC7F2AC4BC0C5C0EDAC4CAC4DC1F0E7F0AC4EAC4FAC50AC51E7F6CBF6AC52AC53AC54AC55AC56AC57AC58AC59AC5AE8A2E8A1AC5BAC5CAC5DAC5EAC5FAC60D7C1AC61AC62E7FAE7F9AC63E7FBAC64E7F7AC65E7FEAC66E7FDAC67E7FCAC68AC69C1D5C7D9C5FDC5C3AC6AAC6BAC6CAC6DAC6EC7EDAC6FAC70AC71AC72E8A3AC73AC74AC75AC76AC77AC78AC79AC7AAC7BAC7CAC7DAC7EAC80AC81AC82AC83AC84AC85AC86E8A6AC87E8A5AC88E8A7BAF7E7F8E8A4AC89C8F0C9AAAC8AAC8BAC8CAC8DAC8EAC8FAC90AC91AC92AC93AC94AC95AC96E8A9AC97AC98B9E5AC99AC9AAC9BAC9CAC9DD1FEE8A8AC9EAC9FACA0AD40AD41AD42E8AAAD43E8ADE8AEAD44C1A7AD45AD46AD47E8AFAD48AD49AD4AE8B0AD4BAD4CE8ACAD4DE8B4AD4EAD4FAD50AD51AD52AD53AD54AD55AD56AD57AD58E8ABAD59E8B1AD5AAD5BAD5CAD5DAD5EAD5FAD60AD61E8B5E8B2E8B3AD62AD63AD64AD65AD66AD67AD68AD69AD6AAD6BAD6CAD6DAD6EAD6FAD70AD71E8B7AD72AD73AD74AD75AD76AD77AD78AD79AD7AAD7BAD7CAD7DAD7EAD80AD81AD82AD83AD84AD85AD86AD87AD88AD89E8B6AD8AAD8BAD8CAD8DAD8EAD8FAD90AD91AD92B9CFAD93F0ACAD94F0ADAD95C6B0B0EAC8BFAD96CDDFAD97AD98AD99AD9AAD9BAD9CAD9DCECDEAB1AD9EAD9FADA0AE40EAB2AE41C6BFB4C9AE42AE43AE44AE45AE46AE47AE48EAB3AE49AE4AAE4BAE4CD5E7AE4DAE4EAE4FAE50AE51AE52AE53AE54DDF9AE55EAB4AE56EAB5AE57EAB6AE58AE59AE5AAE5BB8CADFB0C9F5AE5CCCF0AE5DAE5EC9FAAE5FAE60AE61AE62AE63C9FBAE64AE65D3C3CBA6AE66B8A6F0AEB1C2AE67E5B8CCEFD3C9BCD7C9EAAE68B5E7AE69C4D0B5E9AE6AEEAEBBADAE6BAE6CE7DEAE6DEEAFAE6EAE6FAE70AE71B3A9AE72AE73EEB2AE74AE75EEB1BDE7AE76EEB0CEB7AE77AE78AE79AE7AC5CFAE7BAE7CAE7DAE7EC1F4DBCEEEB3D0F3AE80AE81AE82AE83AE84AE85AE86AE87C2D4C6E8AE88AE89AE8AB7ACAE8BAE8CAE8DAE8EAE8FAE90AE91EEB4AE92B3EBAE93AE94AE95BBFBEEB5AE96AE97AE98AE99AE9AE7DCAE9BAE9CAE9DEEB6AE9EAE9FBDAEAEA0AF40AF41AF42F1E2AF43AF44AF45CAE8AF46D2C9F0DAAF47F0DBAF48F0DCC1C6AF49B8EDBECEAF4AAF4BF0DEAF4CC5B1F0DDD1F1AF4DF0E0B0CCBDEAAF4EAF4FAF50AF51AF52D2DFF0DFAF53B4AFB7E8F0E6F0E5C6A3F0E1F0E2B4C3AF54AF55F0E3D5EEAF56AF57CCDBBED2BCB2AF58AF59AF5AF0E8F0E7F0E4B2A1AF5BD6A2D3B8BEB7C8ACAF5CAF5DF0EAAF5EAF5FAF60AF61D1F7AF62D6CCBADBF0E9AF63B6BBAF64AF65CDB4AF66AF67C6A6AF68AF69AF6AC1A1F0EBF0EEAF6BF0EDF0F0F0ECAF6CBBBEF0EFAF6DAF6EAF6FAF70CCB5F0F2AF71AF72B3D5AF73AF74AF75AF76B1D4AF77AF78F0F3AF79AF7AF0F4F0F6B4E1AF7BF0F1AF7CF0F7AF7DAF7EAF80AF81F0FAAF82F0F8AF83AF84AF85F0F5AF86AF87AF88AF89F0FDAF8AF0F9F0FCF0FEAF8BF1A1AF8CAF8DAF8ECEC1F1A4AF8FF1A3AF90C1F6F0FBCADDAF91AF92B4F1B1F1CCB1AF93F1A6AF94AF95F1A7AF96AF97F1ACD5CEF1A9AF98AF99C8B3AF9AAF9BAF9CF1A2AF9DF1ABF1A8F1A5AF9EAF9FF1AAAFA0B040B041B042B043B044B045B046B0A9F1ADB047B048B049B04AB04BB04CF1AFB04DF1B1B04EB04FB050B051B052F1B0B053F1AEB054B055B056B057D1A2B058B059B05AB05BB05CB05DB05EF1B2B05FB060B061F1B3B062B063B064B065B066B067B068B069B9EFB06AB06BB5C7B06CB0D7B0D9B06DB06EB06FD4EDB070B5C4B071BDD4BBCAF0A7B072B073B8DEB074B075F0A8B076B077B0A8B078F0A9B079B07ACDEEB07BB07CF0AAB07DB07EB080B081B082B083B084B085B086B087F0ABB088B089B08AB08BB08CB08DB08EB08FB090C6A4B091B092D6E5F1E4B093F1E5B094B095B096B097B098B099B09AB09BB09CB09DC3F3B09EB09FD3DBB0A0B140D6D1C5E8B141D3AFB142D2E6B143B144EEC1B0BBD5B5D1CEBCE0BAD0B145BFF8B146B8C7B5C1C5CCB147B148CAA2B149B14AB14BC3CBB14CB14DB14EB14FB150EEC2B151B152B153B154B155B156B157B158C4BFB6A2B159EDECC3A4B15AD6B1B15BB15CB15DCFE0EDEFB15EB15FC5CEB160B6DCB161B162CAA1B163B164EDEDB165B166EDF0EDF1C3BCB167BFB4B168EDEEB169B16AB16BB16CB16DB16EB16FB170B171B172B173EDF4EDF2B174B175B176B177D5E6C3DFB178EDF3B179B17AB17BEDF6B17CD5A3D1A3B17DB17EB180EDF5B181C3D0B182B183B184B185B186EDF7BFF4BEECEDF8B187CCF7B188D1DBB189B18AB18BD7C5D5F6B18CEDFCB18DB18EB18FEDFBB190B191B192B193B194B195B196B197EDF9EDFAB198B199B19AB19BB19CB19DB19EB19FEDFDBEA6B1A0B240B241B242B243CBAFEEA1B6BDB244EEA2C4C0B245EDFEB246B247BDDEB2C7B248B249B24AB24BB24CB24DB24EB24FB250B251B252B253B6C3B254B255B256EEA5D8BAEEA3EEA6B257B258B259C3E9B3F2B25AB25BB25CB25DB25EB25FEEA7EEA4CFB9B260B261EEA8C2F7B262B263B264B265B266B267B268B269B26AB26BB26CB26DEEA9EEAAB26EDEABB26FB270C6B3B271C7C6B272D6F5B5C9B273CBB2B274B275B276EEABB277B278CDABB279EEACB27AB27BB27CB27DB27ED5B0B280EEADB281F6C4B282B283B284B285B286B287B288B289B28AB28BB28CB28DB28EDBC7B28FB290B291B292B293B294B295B296B297B4A3B298B299B29AC3ACF1E6B29BB29CB29DB29EB29FCAB8D2D3B2A0D6AAB340EFF2B341BED8B342BDC3EFF3B6CCB0ABB343B344B345B346CAAFB347B348EDB6B349EDB7B34AB34BB34CB34DCEF9B7AFBFF3EDB8C2EBC9B0B34EB34FB350B351B352B353EDB9B354B355C6F6BFB3B356B357B358EDBCC5F8B359D1D0B35AD7A9EDBAEDBBB35BD1E2B35CEDBFEDC0B35DEDC4B35EB35FB360EDC8B361EDC6EDCED5E8B362EDC9B363B364EDC7EDBEB365B366C5E9B367B368B369C6C6B36AB36BC9E9D4D2EDC1EDC2EDC3EDC5B36CC0F9B36DB4A1B36EB36FB370B371B9E8B372EDD0B373B374B375B376EDD1B377EDCAB378EDCFB379CEF8B37AB37BCBB6EDCCEDCDB37CB37DB37EB380B381CFF5B382B383B384B385B386B387B388B389B38AB38BB38CB38DEDD2C1F2D3B2EDCBC8B7B38EB38FB390B391B392B393B394B395BCEFB396B397B398B399C5F0B39AB39BB39CB39DB39EB39FB3A0B440B441B442EDD6B443B5EFB444B445C2B5B0ADCBE9B446B447B1AEB448EDD4B449B44AB44BCDEBB5E2B44CEDD5EDD3EDD7B44DB44EB5FAB44FEDD8B450EDD9B451EDDCB452B1CCB453B454B455B456B457B458B459B45AC5F6BCEEEDDACCBCB2EAB45BB45CB45DB45EEDDBB45FB460B461B462C4EBB463B464B4C5B465B466B467B0F5B468B469B46AEDDFC0DAB4E8B46BB46CB46DB46EC5CDB46FB470B471EDDDBFC4B472B473B474EDDEB475B476B477B478B479B47AB47BB47CB47DB47EB480B481B482B483C4A5B484B485B486EDE0B487B488B489B48AB48BEDE1B48CEDE3B48DB48EC1D7B48FB490BBC7B491B492B493B494B495B496BDB8B497B498B499EDE2B49AB49BB49CB49DB49EB49FB4A0B540B541B542B543B544B545EDE4B546B547B548B549B54AB54BB54CB54DB54EB54FEDE6B550B551B552B553B554EDE5B555B556B557B558B559B55AB55BB55CB55DB55EB55FB560B561B562B563EDE7B564B565B566B567B568CABEECEAC0F1B569C9E7B56AECEBC6EEB56BB56CB56DB56EECECB56FC6EDECEDB570B571B572B573B574B575B576B577B578ECF0B579B57AD7E6ECF3B57BB57CECF1ECEEECEFD7A3C9F1CBEEECF4B57DECF2B57EB580CFE9B581ECF6C6B1B582B583B584B585BCC0B586ECF5B587B588B589B58AB58BB58CB58DB5BBBBF6B58EECF7B58FB590B591B592B593D9F7BDFBB594B595C2BBECF8B596B597B598B599ECF9B59AB59BB59CB59DB8A3B59EB59FB5A0B640B641B642B643B644B645B646ECFAB647B648B649B64AB64BB64CB64DB64EB64FB650B651B652ECFBB653B654B655B656B657B658B659B65AB65BB65CB65DECFCB65EB65FB660B661B662D3EDD8AEC0EBB663C7DDBACCB664D0E3CBBDB665CDBAB666B667B8D1B668B669B1FCB66AC7EFB66BD6D6B66CB66DB66EBFC6C3EBB66FB670EFF5B671B672C3D8B673B674B675B676B677B678D7E2B679B67AB67BEFF7B3D3B67CC7D8D1EDB67DD6C8B67EEFF8B680EFF6B681BBFDB3C6B682B683B684B685B686B687B688BDD5B689B68AD2C6B68BBBE0B68CB68DCFA1B68EEFFCEFFBB68FB690EFF9B691B692B693B694B3CCB695C9D4CBB0B696B697B698B699B69AEFFEB69BB69CB0DEB69DB69ED6C9B69FB6A0B740EFFDB741B3EDB742B743F6D5B744B745B746B747B748B749B74AB74BB74CB74DB74EB74FB750B751B752CEC8B753B754B755F0A2B756F0A1B757B5BEBCDABBFCB758B8E5B759B75AB75BB75CB75DB75EC4C2B75FB760B761B762B763B764B765B766B767B768F0A3B769B76AB76BB76CB76DCBEBB76EB76FB770B771B772B773B774B775B776B777B778B779B77AB77BB77CB77DB77EB780B781B782B783B784B785B786F0A6B787B788B789D1A8B78ABEBFC7EEF1B6F1B7BFD5B78BB78CB78DB78EB4A9F1B8CDBBB78FC7D4D5ADB790F1B9B791F1BAB792B793B794B795C7CFB796B797B798D2A4D6CFB799B79AF1BBBDD1B4B0BEBDB79BB79CB79DB4DCCED1B79EBFDFF1BDB79FB7A0B840B841BFFAF1BCB842F1BFB843B844B845F1BEF1C0B846B847B848B849B84AF1C1B84BB84CB84DB84EB84FB850B851B852B853B854B855C1FEB856B857B858B859B85AB85BB85CB85DB85EB85FB860C1A2B861B862B863B864B865B866B867B868B869B86ACAFAB86BB86CD5BEB86DB86EB86FB870BEBABEB9D5C2B871B872BFA2B873CDAFF1B5B874B875B876B877B878B879BDDFB87AB6CBB87BB87CB87DB87EB880B881B882B883B884D6F1F3C3B885B886F3C4B887B8CDB888B889B88AF3C6F3C7B88BB0CAB88CF3C5B88DF3C9CBF1B88EB88FB890F3CBB891D0A6B892B893B1CAF3C8B894B895B896F3CFB897B5D1B898B899F3D7B89AF3D2B89BB89CB89DF3D4F3D3B7FBB89EB1BFB89FF3CEF3CAB5DAB8A0F3D0B940B941F3D1B942F3D5B943B944B945B946F3CDB947BCE3B948C1FDB949F3D6B94AB94BB94CB94DB94EB94FF3DAB950F3CCB951B5C8B952BDEEF3DCB953B954B7A4BFF0D6FECDB2B955B4F0B956B2DFB957F3D8B958F3D9C9B8B959F3DDB95AB95BF3DEB95CF3E1B95DB95EB95FB960B961B962B963B964B965B966B967F3DFB968B969F3E3F3E2B96AB96BF3DBB96CBFEAB96DB3EFB96EF3E0B96FB970C7A9B971BCF2B972B973B974B975F3EBB976B977B978B979B97AB97BB97CB9BFB97DB97EF3E4B980B981B982B2ADBBFEB983CBE3B984B985B986B987F3EDF3E9B988B989B98AB9DCF3EEB98BB98CB98DF3E5F3E6F3EAC2E1F3ECF3EFF3E8BCFDB98EB98FB990CFE4B991B992F3F0B993B994B995F3E7B996B997B998B999B99AB99BB99CB99DF3F2B99EB99FB9A0BA40D7ADC6AABA41BA42BA43BA44F3F3BA45BA46BA47BA48F3F1BA49C2A8BA4ABA4BBA4CBA4DBA4EB8DDF3F5BA4FBA50F3F4BA51BA52BA53B4DBBA54BA55BA56F3F6F3F7BA57BA58BA59F3F8BA5ABA5BBA5CC0BABA5DBA5EC0E9BA5FBA60BA61BA62BA63C5F1BA64BA65BA66BA67F3FBBA68F3FABA69BA6ABA6BBA6CBA6DBA6EBA6FBA70B4D8BA71BA72BA73F3FEF3F9BA74BA75F3FCBA76BA77BA78BA79BA7ABA7BF3FDBA7CBA7DBA7EBA80BA81BA82BA83BA84F4A1BA85BA86BA87BA88BA89BA8AF4A3BBC9BA8BBA8CF4A2BA8DBA8EBA8FBA90BA91BA92BA93BA94BA95BA96BA97BA98BA99F4A4BA9ABA9BBA9CBA9DBA9EBA9FB2BEF4A6F4A5BAA0BB40BB41BB42BB43BB44BB45BB46BB47BB48BB49BCAEBB4ABB4BBB4CBB4DBB4EBB4FBB50BB51BB52BB53BB54BB55BB56BB57BB58BB59BB5ABB5BBB5CBB5DBB5EBB5FBB60BB61BB62BB63BB64BB65BB66BB67BB68BB69BB6ABB6BBB6CBB6DBB6EC3D7D9E1BB6FBB70BB71BB72BB73BB74C0E0F4CCD7D1BB75BB76BB77BB78BB79BB7ABB7BBB7CBB7DBB7EBB80B7DBBB81BB82BB83BB84BB85BB86BB87F4CEC1A3BB88BB89C6C9BB8AB4D6D5B3BB8BBB8CBB8DF4D0F4CFF4D1CBDABB8EBB8FF4D2BB90D4C1D6E0BB91BB92BB93BB94B7E0BB95BB96BB97C1B8BB98BB99C1BBF4D3BEACBB9ABB9BBB9CBB9DBB9EB4E2BB9FBBA0F4D4F4D5BEABBC40BC41F4D6BC42BC43BC44F4DBBC45F4D7F4DABC46BAFDBC47F4D8F4D9BC48BC49BC4ABC4BBC4CBC4DBC4EB8E2CCC7F4DCBC4FB2DABC50BC51C3D3BC52BC53D4E3BFB7BC54BC55BC56BC57BC58BC59BC5AF4DDBC5BBC5CBC5DBC5EBC5FBC60C5B4BC61BC62BC63BC64BC65BC66BC67BC68F4E9BC69BC6ACFB5BC6BBC6CBC6DBC6EBC6FBC70BC71BC72BC73BC74BC75BC76BC77BC78CEC9BC79BC7ABC7BBC7CBC7DBC7EBC80BC81BC82BC83BC84BC85BC86BC87BC88BC89BC8ABC8BBC8CBC8DBC8ECBD8BC8FCBF7BC90BC91BC92BC93BDF4BC94BC95BC96D7CFBC97BC98BC99C0DBBC9ABC9BBC9CBC9DBC9EBC9FBCA0BD40BD41BD42BD43BD44BD45BD46BD47BD48BD49BD4ABD4BBD4CBD4DBD4EBD4FBD50BD51BD52BD53BD54BD55BD56BD57BD58BD59BD5ABD5BBD5CBD5DBD5EBD5FBD60BD61BD62BD63BD64BD65BD66BD67BD68BD69BD6ABD6BBD6CBD6DBD6EBD6FBD70BD71BD72BD73BD74BD75BD76D0F5BD77BD78BD79BD7ABD7BBD7CBD7DBD7EF4EABD80BD81BD82BD83BD84BD85BD86BD87BD88BD89BD8ABD8BBD8CBD8DBD8EBD8FBD90BD91BD92BD93BD94BD95BD96BD97BD98BD99BD9ABD9BBD9CBD9DBD9EBD9FBDA0BE40BE41BE42BE43BE44BE45BE46BE47BE48BE49BE4ABE4BBE4CF4EBBE4DBE4EBE4FBE50BE51BE52BE53F4ECBE54BE55BE56BE57BE58BE59BE5ABE5BBE5CBE5DBE5EBE5FBE60BE61BE62BE63BE64BE65BE66BE67BE68BE69BE6ABE6BBE6CBE6DBE6EBE6FBE70BE71BE72BE73BE74BE75BE76BE77BE78BE79BE7ABE7BBE7CBE7DBE7EBE80BE81BE82BE83BE84BE85BE86BE87BE88BE89BE8ABE8BBE8CBE8DBE8EBE8FBE90BE91BE92BE93BE94BE95BE96BE97BE98BE99BE9ABE9BBE9CBE9DBE9EBE9FBEA0BF40BF41BF42BF43BF44BF45BF46BF47BF48BF49BF4ABF4BBF4CBF4DBF4EBF4FBF50BF51BF52BF53BF54BF55BF56BF57BF58BF59BF5ABF5BBF5CBF5DBF5EBF5FBF60BF61BF62BF63BF64BF65BF66BF67BF68BF69BF6ABF6BBF6CBF6DBF6EBF6FBF70BF71BF72BF73BF74BF75BF76BF77BF78BF79BF7ABF7BBF7CBF7DBF7EBF80F7E3BF81BF82BF83BF84BF85B7B1BF86BF87BF88BF89BF8AF4EDBF8BBF8CBF8DBF8EBF8FBF90BF91BF92BF93BF94BF95BF96BF97BF98BF99BF9ABF9BBF9CBF9DBF9EBF9FBFA0C040C041C042C043C044C045C046C047C048C049C04AC04BC04CC04DC04EC04FC050C051C052C053C054C055C056C057C058C059C05AC05BC05CC05DC05EC05FC060C061C062C063D7EBC064C065C066C067C068C069C06AC06BC06CC06DC06EC06FC070C071C072C073C074C075C076C077C078C079C07AC07BF4EEC07CC07DC07EE6F9BEC0E6FABAECE6FBCFCBE6FCD4BCBCB6E6FDE6FEBCCDC8D2CEB3E7A1C080B4BFE7A2C9B4B8D9C4C9C081D7DDC2DAB7D7D6BDCEC6B7C4C082C083C5A6E7A3CFDFE7A4E7A5E7A6C1B7D7E9C9F0CFB8D6AFD6D5E7A7B0EDE7A8E7A9C9DCD2EFBEADE7AAB0F3C8DEBDE1E7ABC8C6C084E7ACBBE6B8F8D1A4E7ADC2E7BEF8BDCACDB3E7AEE7AFBEEED0E5C085CBE7CCD0BCCCE7B0BCA8D0F7E7B1C086D0F8E7B2E7B3B4C2E7B4E7B5C9FECEACC3E0E7B7B1C1B3F1C087E7B8E7B9D7DBD5C0E7BAC2CCD7BAE7BBE7BCE7BDBCEAC3E5C0C2E7BEE7BFBCA9C088E7C0E7C1E7B6B6D0E7C2C089E7C3E7C4BBBAB5DEC2C6B1E0E7C5D4B5E7C6B8BFE7C8E7C7B7ECC08AE7C9B2F8E7CAE7CBE7CCE7CDE7CEE7CFE7D0D3A7CBF5E7D1E7D2E7D3E7D4C9C9E7D5E7D6E7D7E7D8E7D9BDC9E7DAF3BEC08BB8D7C08CC8B1C08DC08EC08FC090C091C092C093F3BFC094F3C0F3C1C095C096C097C098C099C09AC09BC09CC09DC09EB9DECDF8C09FC0A0D8E8BAB1C140C2DEEEB7C141B7A3C142C143C144C145EEB9C146EEB8B0D5C147C148C149C14AC14BEEBBD5D6D7EFC14CC14DC14ED6C3C14FC150EEBDCAF0C151EEBCC152C153C154C155EEBEC156C157C158C159EEC0C15AC15BEEBFC15CC15DC15EC15FC160C161C162C163D1F2C164C7BCC165C3C0C166C167C168C169C16AB8E1C16BC16CC16DC16EC16FC1E7C170C171F4C6D0DFF4C7C172CFDBC173C174C8BAC175C176F4C8C177C178C179C17AC17BC17CC17DF4C9F4CAC17EF4CBC180C181C182C183C184D9FAB8FEC185C186E5F1D3F0C187F4E0C188CECCC189C18AC18BB3E1C18CC18DC18EC18FF1B4C190D2EEC191F4E1C192C193C194C195C196CFE8F4E2C197C198C7CCC199C19AC19BC19CC19DC19EB5D4B4E4F4E4C19FC1A0C240F4E3F4E5C241C242F4E6C243C244C245C246F4E7C247BAB2B0BFC248F4E8C249C24AC24BC24CC24DC24EC24FB7ADD2EDC250C251C252D2ABC0CFC253BFBCEBA3D5DFEAC8C254C255C256C257F1F3B6F8CBA3C258C259C4CDC25AF1E7C25BF1E8B8FBF1E9BAC4D4C5B0D2C25CC25DF1EAC25EC25FC260F1EBC261F1ECC262C263F1EDF1EEF1EFF1F1F1F0C5D5C264C265C266C267C268C269F1F2C26AB6FAC26BF1F4D2AEDEC7CBCAC26CC26DB3DCC26EB5A2C26FB9A2C270C271C4F4F1F5C272C273F1F6C274C275C276C1C4C1FBD6B0F1F7C277C278C279C27AF1F8C27BC1AAC27CC27DC27EC6B8C280BEDBC281C282C283C284C285C286C287C288C289C28AC28BC28CC28DC28EF1F9B4CFC28FC290C291C292C293C294F1FAC295C296C297C298C299C29AC29BC29CC29DC29EC29FC2A0C340EDB2EDB1C341C342CBE0D2DEC343CBC1D5D8C344C8E2C345C0DFBCA1C346C347C348C349C34AC34BEBC1C34CC34DD0A4C34ED6E2C34FB6C7B8D8EBC0B8CEC350EBBFB3A6B9C9D6ABC351B7F4B7CAC352C353C354BCE7B7BEEBC6C355EBC7B0B9BFCFC356EBC5D3FDC357EBC8C358C359EBC9C35AC35BB7CEC35CEBC2EBC4C9F6D6D7D5CDD0B2EBCFCEB8EBD0C35DB5A8C35EC35FC360C361C362B1B3EBD2CCA5C363C364C365C366C367C368C369C5D6EBD3C36AEBD1C5DFEBCECAA4EBD5B0FBC36BC36CBAFAC36DC36ED8B7F1E3C36FEBCAEBCBEBCCEBCDEBD6E6C0EBD9C370BFE8D2C8EBD7EBDCB8ECEBD8C371BDBAC372D0D8C373B0B7C374EBDDC4DCC375C376C377C378D6ACC379C37AC37BB4E0C37CC37DC2F6BCB9C37EC380EBDAEBDBD4E0C6EAC4D4EBDFC5A7D9F5C381B2B1C382EBE4C383BDC5C384C385C386EBE2C387C388C389C38AC38BC38CC38DC38EC38FC390C391C392C393EBE3C394C395B8ACC396CDD1EBE5C397C398C399EBE1C39AC1B3C39BC39CC39DC39EC39FC6A2C3A0C440C441C442C443C444C445CCF3C446EBE6C447C0B0D2B8EBE7C448C449C44AB8AFB8ADC44BEBE8C7BBCDF3C44CC44DC44EEBEAEBEBC44FC450C451C452C453EBEDC454C455C456C457D0C8C458EBF2C459EBEEC45AC45BC45CEBF1C8F9C45DD1FCEBECC45EC45FEBE9C460C461C462C463B8B9CFD9C4E5EBEFEBF0CCDACDC8B0F2C464EBF6C465C466C467C468C469EBF5C46AB2B2C46BC46CC46DC46EB8E0C46FEBF7C470C471C472C473C474C475B1ECC476C477CCC5C4A4CFA5C478C479C47AC47BC47CEBF9C47DC47EECA2C480C5F2C481EBFAC482C483C484C485C486C487C488C489C9C5C48AC48BC48CC48DC48EC48FE2DFEBFEC490C491C492C493CDCEECA1B1DBD3B7C494C495D2DCC496C497C498EBFDC499EBFBC49AC49BC49CC49DC49EC49FC4A0C540C541C542C543C544C545C546C547C548C549C54AC54BC54CC54DC54EB3BCC54FC550C551EAB0C552C553D7D4C554F4ABB3F4C555C556C557C558C559D6C1D6C2C55AC55BC55CC55DC55EC55FD5E9BECAC560F4A7C561D2A8F4A8F4A9C562F4AABECBD3DFC563C564C565C566C567C9E0C9E1C568C569F3C2C56ACAE6C56BCCF2C56CC56DC56EC56FC570C571E2B6CBB4C572CEE8D6DBC573F4ADF4AEF4AFC574C575C576C577F4B2C578BABDF4B3B0E3F4B0C579F4B1BDA2B2D5C57AF4B6F4B7B6E6B2B0CFCFF4B4B4ACC57BF4B5C57CC57DF4B8C57EC580C581C582C583F4B9C584C585CDA7C586F4BAC587F4BBC588C589C58AF4BCC58BC58CC58DC58EC58FC590C591C592CBD2C593F4BDC594C595C596C597F4BEC598C599C59AC59BC59CC59DC59EC59FF4BFC5A0C640C641C642C643F4DEC1BCBCE8C644C9ABD1DEE5F5C645C646C647C648DCB3D2D5C649C64ADCB4B0ACDCB5C64BC64CBDDAC64DDCB9C64EC64FC650D8C2C651DCB7D3F3C652C9D6DCBADCB6C653DCBBC3A2C654C655C656C657DCBCDCC5DCBDC658C659CEDFD6A5C65ADCCFC65BDCCDC65CC65DDCD2BDE6C2ABC65EDCB8DCCBDCCEDCBEB7D2B0C5DCC7D0BEDCC1BBA8C65FB7BCDCCCC660C661DCC6DCBFC7DBC662C663C664D1BFDCC0C665C666DCCAC667C668DCD0C669C66ACEADDCC2C66BDCC3DCC8DCC9B2D4DCD1CBD5C66CD4B7DCDBDCDFCCA6DCE6C66DC3E7DCDCC66EC66FBFC1DCD9C670B0FAB9B6DCE5DCD3C671DCC4DCD6C8F4BFE0C672C673C674C675C9BBC676C677C678B1BDC679D3A2C67AC67BDCDAC67CC67DDCD5C67EC6BBC680DCDEC681C682C683C684C685D7C2C3AFB7B6C7D1C3A9DCE2DCD8DCEBDCD4C686C687DCDDC688BEA5DCD7C689DCE0C68AC68BDCE3DCE4C68CDCF8C68DC68EDCE1DDA2DCE7C68FC690C691C692C693C694C695C696C697C698BCEBB4C4C699C69AC3A3B2E7DCFAC69BDCF2C69CDCEFC69DDCFCDCEED2F0B2E8C69EC8D7C8E3DCFBC69FDCEDC6A0C740C741DCF7C742C743DCF5C744C745BEA3DCF4C746B2DDC747C748C749C74AC74BDCF3BCF6DCE8BBC4C74CC0F3C74DC74EC74FC750C751BCD4DCE9DCEAC752DCF1DCF6DCF9B5B4C753C8D9BBE7DCFEDCFDD3ABDDA1DDA3DDA5D2F1DDA4DDA6DDA7D2A9C754C755C756C757C758C759C75ABAC9DDA9C75BC75CDDB6DDB1DDB4C75DC75EC75FC760C761C762C763DDB0C6CEC764C765C0F2C766C767C768C769C9AFC76AC76BC76CDCECDDAEC76DC76EC76FC770DDB7C771C772DCF0DDAFC773DDB8C774DDACC775C776C777C778C779C77AC77BDDB9DDB3DDADC4AAC77CC77DC77EC780DDA8C0B3C1ABDDAADDABC781DDB2BBF1DDB5D3A8DDBAC782DDBBC3A7C783C784DDD2DDBCC785C786C787DDD1C788B9BDC789C78ABED5C78BBEFAC78CC78DBACAC78EC78FC790C791DDCAC792DDC5C793DDBFC794C795C796B2CBDDC3C797DDCBB2A4DDD5C798C799C79ADDBEC79BC79CC79DC6D0DDD0C79EC79FC7A0C840C841DDD4C1E2B7C6C842C843C844C845C846DDCEDDCFC847C848C849DDC4C84AC84BC84CDDBDC84DDDCDCCD1C84EDDC9C84FC850C851C852DDC2C3C8C6BCCEAEDDCCC853DDC8C854C855C856C857C858C859DDC1C85AC85BC85CDDC6C2DCC85DC85EC85FC860C861C862D3A9D3AADDD3CFF4C8F8C863C864C865C866C867C868C869C86ADDE6C86BC86CC86DC86EC86FC870DDC7C871C872C873DDE0C2E4C874C875C876C877C878C879C87AC87BDDE1C87CC87DC87EC880C881C882C883C884C885C886DDD7C887C888C889C88AC88BD6F8C88CDDD9DDD8B8F0DDD6C88DC88EC88FC890C6CFC891B6ADC892C893C894C895C896DDE2C897BAF9D4E1DDE7C898C899C89AB4D0C89BDDDAC89CBFFBDDE3C89DDDDFC89EDDDDC89FC8A0C940C941C942C943C944B5D9C945C946C947C948DDDBDDDCDDDEC949BDAFDDE4C94ADDE5C94BC94CC94DC94EC94FC950C951C952DDF5C953C3C9C954C955CBE2C956C957C958C959DDF2C95AC95BC95CC95DC95EC95FC960C961C962C963C964C965C966D8E1C967C968C6D1C969DDF4C96AC96BC96CD5F4DDF3DDF0C96DC96EDDECC96FDDEFC970DDE8C971C972D0EEC973C974C975C976C8D8DDEEC977C978DDE9C979C97ADDEACBF2C97BDDEDC97CC97DB1CDC97EC980C981C982C983C984C0B6C985BCBBDDF1C986C987DDF7C988DDF6DDEBC989C98AC98BC98CC98DC5EEC98EC98FC990DDFBC991C992C993C994C995C996C997C998C999C99AC99BDEA4C99CC99DDEA3C99EC99FC9A0CA40CA41CA42CA43CA44CA45CA46CA47CA48DDF8CA49CA4ACA4BCA4CC3EFCA4DC2FBCA4ECA4FCA50D5E1CA51CA52CEB5CA53CA54CA55CA56DDFDCA57B2CCCA58CA59CA5ACA5BCA5CCA5DCA5ECA5FCA60C4E8CADFCA61CA62CA63CA64CA65CA66CA67CA68CA69CA6AC7BEDDFADDFCDDFEDEA2B0AAB1CECA6BCA6CCA6DCA6ECA6FDEACCA70CA71CA72CA73DEA6BDB6C8EFCA74CA75CA76CA77CA78CA79CA7ACA7BCA7CCA7DCA7EDEA1CA80CA81DEA5CA82CA83CA84CA85DEA9CA86CA87CA88CA89CA8ADEA8CA8BCA8CCA8DDEA7CA8ECA8FCA90CA91CA92CA93CA94CA95CA96DEADCA97D4CCCA98CA99CA9ACA9BDEB3DEAADEAECA9CCA9DC0D9CA9ECA9FCAA0CB40CB41B1A1DEB6CB42DEB1CB43CB44CB45CB46CB47CB48CB49DEB2CB4ACB4BCB4CCB4DCB4ECB4FCB50CB51CB52CB53CB54D1A6DEB5CB55CB56CB57CB58CB59CB5ACB5BDEAFCB5CCB5DCB5EDEB0CB5FD0BDCB60CB61CB62DEB4CAEDDEB9CB63CB64CB65CB66CB67CB68DEB8CB69DEB7CB6ACB6BCB6CCB6DCB6ECB6FCB70DEBBCB71CB72CB73CB74CB75CB76CB77BDE5CB78CB79CB7ACB7BCB7CB2D8C3EACB7DCB7EDEBACB80C5BACB81CB82CB83CB84CB85CB86DEBCCB87CB88CB89CB8ACB8BCB8CCB8DCCD9CB8ECB8FCB90CB91B7AACB92CB93CB94CB95CB96CB97CB98CB99CB9ACB9BCB9CCB9DCB9ECB9FCBA0CC40CC41D4E5CC42CC43CC44DEBDCC45CC46CC47CC48CC49DEBFCC4ACC4BCC4CCC4DCC4ECC4FCC50CC51CC52CC53CC54C4A2CC55CC56CC57CC58DEC1CC59CC5ACC5BCC5CCC5DCC5ECC5FCC60CC61CC62CC63CC64CC65CC66CC67CC68DEBECC69DEC0CC6ACC6BCC6CCC6DCC6ECC6FCC70CC71CC72CC73CC74CC75CC76CC77D5BACC78CC79CC7ADEC2CC7BCC7CCC7DCC7ECC80CC81CC82CC83CC84CC85CC86CC87CC88CC89CC8ACC8BF2AEBBA2C2B2C5B0C2C7CC8CCC8DF2AFCC8ECC8FCC90CC91CC92D0E9CC93CC94CC95D3DDCC96CC97CC98EBBDCC99CC9ACC9BCC9CCC9DCC9ECC9FCCA0B3E6F2B0CD40F2B1CD41CD42CAADCD43CD44CD45CD46CD47CD48CD49BAE7F2B3F2B5F2B4CBE4CFBAF2B2CAB4D2CFC2ECCD4ACD4BCD4CCD4DCD4ECD4FCD50CEC3F2B8B0F6F2B7CD51CD52CD53CD54CD55F2BECD56B2CFCD57CD58CD59CD5ACD5BCD5CD1C1F2BACD5DCD5ECD5FCD60CD61F2BCD4E9CD62CD63F2BBF2B6F2BFF2BDCD64F2B9CD65CD66F2C7F2C4F2C6CD67CD68F2CAF2C2F2C0CD69CD6ACD6BF2C5CD6CCD6DCD6ECD6FCD70D6FBCD71CD72CD73F2C1CD74C7F9C9DFCD75F2C8B9C6B5B0CD76CD77F2C3F2C9F2D0F2D6CD78CD79BBD7CD7ACD7BCD7CF2D5CDDCCD7DD6EBCD7ECD80F2D2F2D4CD81CD82CD83CD84B8F2CD85CD86CD87CD88F2CBCD89CD8ACD8BF2CEC2F9CD8CD5DDF2CCF2CDF2CFF2D3CD8DCD8ECD8FF2D9D3BCCD90CD91CD92CD93B6EACD94CAF1CD95B7E4F2D7CD96CD97CD98F2D8F2DAF2DDF2DBCD99CD9AF2DCCD9BCD9CCD9DCD9ED1D1F2D1CD9FCDC9CDA0CECFD6A9CE40F2E3CE41C3DBCE42F2E0CE43CE44C0AFF2ECF2DECE45F2E1CE46CE47CE48F2E8CE49CE4ACE4BCE4CF2E2CE4DCE4EF2E7CE4FCE50F2E6CE51CE52F2E9CE53CE54CE55F2DFCE56CE57F2E4F2EACE58CE59CE5ACE5BCE5CCE5DCE5ED3ACF2E5B2F5CE5FCE60F2F2CE61D0ABCE62CE63CE64CE65F2F5CE66CE67CE68BBC8CE69F2F9CE6ACE6BCE6CCE6DCE6ECE6FF2F0CE70CE71F2F6F2F8F2FACE72CE73CE74CE75CE76CE77CE78CE79F2F3CE7AF2F1CE7BCE7CCE7DBAFBCE7EB5FBCE80CE81CE82CE83F2EFF2F7F2EDF2EECE84CE85CE86F2EBF3A6CE87F3A3CE88CE89F3A2CE8ACE8BF2F4CE8CC8DACE8DCE8ECE8FCE90CE91F2FBCE92CE93CE94F3A5CE95CE96CE97CE98CE99CE9ACE9BC3F8CE9CCE9DCE9ECE9FCEA0CF40CF41CF42F2FDCF43CF44F3A7F3A9F3A4CF45F2FCCF46CF47CF48F3ABCF49F3AACF4ACF4BCF4CCF4DC2DDCF4ECF4FF3AECF50CF51F3B0CF52CF53CF54CF55CF56F3A1CF57CF58CF59F3B1F3ACCF5ACF5BCF5CCF5DCF5EF3AFF2FEF3ADCF5FCF60CF61CF62CF63CF64CF65F3B2CF66CF67CF68CF69F3B4CF6ACF6BCF6CCF6DF3A8CF6ECF6FCF70CF71F3B3CF72CF73CF74F3B5CF75CF76CF77CF78CF79CF7ACF7BCF7CCF7DCF7ED0B7CF80CF81CF82CF83F3B8CF84CF85CF86CF87D9F9CF88CF89CF8ACF8BCF8CCF8DF3B9CF8ECF8FCF90CF91CF92CF93CF94CF95F3B7CF96C8E4F3B6CF97CF98CF99CF9AF3BACF9BCF9CCF9DCF9ECF9FF3BBB4C0CFA0D040D041D042D043D044D045D046D047D048D049D04AD04BD04CD04DEEC3D04ED04FD050D051D052D053F3BCD054D055F3BDD056D057D058D1AAD059D05AD05BF4ACD0C6D05CD05DD05ED05FD060D061D0D0D1DCD062D063D064D065D066D067CFCED068D069BDD6D06AD1C3D06BD06CD06DD06ED06FD070D071BAE2E1E9D2C2F1C2B2B9D072D073B1EDF1C3D074C9C0B3C4D075D9F2D076CBA5D077F1C4D078D079D07AD07BD6D4D07CD07DD07ED080D081F1C5F4C0F1C6D082D4ACF1C7D083B0C0F4C1D084D085F4C2D086D087B4FCD088C5DBD089D08AD08BD08CCCBBD08DD08ED08FD0E4D090D091D092D093D094CDE0D095D096D097D098D099F1C8D09AD9F3D09BD09CD09DD09ED09FD0A0B1BBD140CFAED141D142D143B8A4D144D145D146D147D148F1CAD149D14AD14BD14CF1CBD14DD14ED14FD150B2C3C1D1D151D152D7B0F1C9D153D154F1CCD155D156D157D158F1CED159D15AD15BD9F6D15CD2E1D4A3D15DD15EF4C3C8B9D15FD160D161D162D163F4C4D164D165F1CDF1CFBFE3F1D0D166D167F1D4D168D169D16AD16BD16CD16DD16EF1D6F1D1D16FC9D1C5E1D170D171D172C2E3B9FCD173D174F1D3D175F1D5D176D177D178B9D3D179D17AD17BD17CD17DD17ED180F1DBD181D182D183D184D185BAD6D186B0FDF1D9D187D188D189D18AD18BF1D8F1D2F1DAD18CD18DD18ED18FD190F1D7D191D192D193C8ECD194D195D196D197CDCAF1DDD198D199D19AD19BE5BDD19CD19DD19EF1DCD19FF1DED1A0D240D241D242D243D244D245D246D247D248F1DFD249D24ACFE5D24BD24CD24DD24ED24FD250D251D252D253D254D255D256D257D258D259D25AD25BD25CD25DD25ED25FD260D261D262D263F4C5BDF3D264D265D266D267D268D269F1E0D26AD26BD26CD26DD26ED26FD270D271D272D273D274D275D276D277D278D279D27AD27BD27CD27DF1E1D27ED280D281CEF7D282D2AAD283F1FBD284D285B8B2D286D287D288D289D28AD28BD28CD28DD28ED28FD290D291D292D293D294D295D296D297D298D299D29AD29BD29CD29DD29ED29FD2A0D340D341D342D343D344D345D346D347D348D349D34AD34BD34CD34DD34ED34FD350D351D352D353D354D355D356D357D358D359D35AD35BD35CD35DD35EBCFBB9DBD35FB9E6C3D9CAD3EAE8C0C0BEF5EAE9EAEAEAEBD360EAECEAEDEAEEEAEFBDC7D361D362D363F5FBD364D365D366F5FDD367F5FED368F5FCD369D36AD36BD36CBDE2D36DF6A1B4A5D36ED36FD370D371F6A2D372D373D374F6A3D375D376D377ECB2D378D379D37AD37BD37CD37DD37ED380D381D382D383D384D1D4D385D386D387D388D389D38AD9EAD38BD38CD38DD38ED38FD390D391D392D393D394D395D396D397D398D399D39AD39BD39CD39DD39ED39FD3A0D440D441D442D443D444D445D446D447D448D449D44AD44BD44CD44DD44ED44FD450D451D452D453D454D455D456D457D458D459D45AD45BD45CD45DD45ED45FF6A4D460D461D462D463D464D465D466D467D468EEBAD469D46AD46BD46CD46DD46ED46FD470D471D472D473D474D475D476D477D478D479D47AD47BD47CD47DD47ED480D481D482D483D484D485D486D487D488D489D48AD48BD48CD48DD48ED48FD490D491D492D493D494D495D496D497D498D499D5B2D49AD49BD49CD49DD49ED49FD4A0D540D541D542D543D544D545D546D547D3FECCDCD548D549D54AD54BD54CD54DD54ED54FCAC4D550D551D552D553D554D555D556D557D558D559D55AD55BD55CD55DD55ED55FD560D561D562D563D564D565D566D567D568D569D56AD56BD56CD56DD56ED56FD570D571D572D573D574D575D576D577D578D579D57AD57BD57CD57DD57ED580D581D582D583D584D585D586D587D588D589D58AD58BD58CD58DD58ED58FD590D591D592D593D594D595D596D597D598D599D59AD59BD59CD59DD59ED59FD5A0D640D641D642D643D644D645D646D647D648D649D64AD64BD64CD64DD64ED64FD650D651D652D653D654D655D656D657D658D659D65AD65BD65CD65DD65ED65FD660D661D662E5C0D663D664D665D666D667D668D669D66AD66BD66CD66DD66ED66FD670D671D672D673D674D675D676D677D678D679D67AD67BD67CD67DD67ED680D681F6A5D682D683D684D685D686D687D688D689D68AD68BD68CD68DD68ED68FD690D691D692D693D694D695D696D697D698D699D69AD69BD69CD69DD69ED69FD6A0D740D741D742D743D744D745D746D747D748D749D74AD74BD74CD74DD74ED74FD750D751D752D753D754D755D756D757D758D759D75AD75BD75CD75DD75ED75FBEAFD760D761D762D763D764C6A9D765D766D767D768D769D76AD76BD76CD76DD76ED76FD770D771D772D773D774D775D776D777D778D779D77AD77BD77CD77DD77ED780D781D782D783D784D785D786D787D788D789D78AD78BD78CD78DD78ED78FD790D791D792D793D794D795D796D797D798DAA5BCC6B6A9B8BCC8CFBCA5DAA6DAA7CCD6C8C3DAA8C6FDD799D1B5D2E9D1B6BCC7D79ABDB2BBE4DAA9DAAAD1C8DAABD0EDB6EFC2DBD79BCBCFB7EDC9E8B7C3BEF7D6A4DAACDAADC6C0D7E7CAB6D79CD5A9CBDFD5EFDAAED6DFB4CADAB0DAAFD79DD2EBDAB1DAB2DAB3CAD4DAB4CAABDAB5DAB6B3CFD6EFDAB7BBB0B5AEDAB8DAB9B9EED1AFD2E8DABAB8C3CFEAB2EFDABBDABCD79EBDEBCEDCD3EFDABDCEF3DABED3D5BBE5DABFCBB5CBD0DAC0C7EBD6EEDAC1C5B5B6C1DAC2B7CCBFCEDAC3DAC4CBADDAC5B5F7DAC6C1C2D7BBDAC7CCB8D79FD2EAC4B1DAC8B5FDBBD1DAC9D0B3DACADACBCEBDDACCDACDDACEB2F7DAD1DACFD1E8DAD0C3D5DAD2D7A0DAD3DAD4DAD5D0BBD2A5B0F9DAD6C7ABDAD7BDF7C3A1DAD8DAD9C3FDCCB7DADADADBC0BEC6D7DADCDADDC7B4DADEDADFB9C8D840D841D842D843D844D845D846D847D848BBEDD849D84AD84BD84CB6B9F4F8D84DF4F9D84ED84FCDE3D850D851D852D853D854D855D856D857F5B9D858D859D85AD85BEBE0D85CD85DD85ED85FD860D861CFF3BBBFD862D863D864D865D866D867D868BAC0D4A5D869D86AD86BD86CD86DD86ED86FE1D9D870D871D872D873F5F4B1AAB2F2D874D875D876D877D878D879D87AF5F5D87BD87CF5F7D87DD87ED880BAD1F5F6D881C3B2D882D883D884D885D886D887D888F5F9D889D88AD88BF5F8D88CD88DD88ED88FD890D891D892D893D894D895D896D897D898D899D89AD89BD89CD89DD89ED89FD8A0D940D941D942D943D944D945D946D947D948D949D94AD94BD94CD94DD94ED94FD950D951D952D953D954D955D956D957D958D959D95AD95BD95CD95DD95ED95FD960D961D962D963D964D965D966D967D968D969D96AD96BD96CD96DD96ED96FD970D971D972D973D974D975D976D977D978D979D97AD97BD97CD97DD97ED980D981D982D983D984D985D986D987D988D989D98AD98BD98CD98DD98ED98FD990D991D992D993D994D995D996D997D998D999D99AD99BD99CD99DD99ED99FD9A0DA40DA41DA42DA43DA44DA45DA46DA47DA48DA49DA4ADA4BDA4CDA4DDA4EB1B4D5EAB8BADA4FB9B1B2C6D4F0CFCDB0DCD5CBBBF5D6CAB7B7CCB0C6B6B1E1B9BAD6FCB9E1B7A1BCFAEADAEADBCCF9B9F3EADCB4FBC3B3B7D1BAD8EADDD4F4EADEBCD6BBDFEADFC1DEC2B8D4DFD7CAEAE0EAE1EAE4EAE2EAE3C9DEB8B3B6C4EAE5CAEAC9CDB4CDDA50DA51E2D9C5E2EAE6C0B5DA52D7B8EAE7D7ACC8FCD8D3D8CDD4DEDA53D4F9C9C4D3AEB8D3B3E0DA54C9E2F4F6DA55DA56DA57BAD5DA58F4F7DA59DA5AD7DFDA5BDA5CF4F1B8B0D5D4B8CFC6F0DA5DDA5EDA5FDA60DA61DA62DA63DA64DA65B3C3DA66DA67F4F2B3ACDA68DA69DA6ADA6BD4BDC7F7DA6CDA6DDA6EDA6FDA70F4F4DA71DA72F4F3DA73DA74DA75DA76DA77DA78DA79DA7ADA7BDA7CCCCBDA7DDA7EDA80C8A4DA81DA82DA83DA84DA85DA86DA87DA88DA89DA8ADA8BDA8CDA8DF4F5DA8ED7E3C5BFF5C0DA8FDA90F5BBDA91F5C3DA92F5C2DA93D6BAF5C1DA94DA95DA96D4BEF5C4DA97F5CCDA98DA99DA9ADA9BB0CFB5F8DA9CF5C9F5CADA9DC5DCDA9EDA9FDAA0DB40F5C5F5C6DB41DB42F5C7F5CBDB43BEE0F5C8B8FADB44DB45DB46F5D0F5D3DB47DB48DB49BFE7DB4AB9F2F5BCF5CDDB4BDB4CC2B7DB4DDB4EDB4FCCF8DB50BCF9DB51F5CEF5CFF5D1B6E5F5D2DB52F5D5DB53DB54DB55DB56DB57DB58DB59F5BDDB5ADB5BDB5CF5D4D3BBDB5DB3ECDB5EDB5FCCA4DB60DB61DB62DB63F5D6DB64DB65DB66DB67DB68DB69DB6ADB6BF5D7BEE1F5D8DB6CDB6DCCDFF5DBDB6EDB6FDB70DB71DB72B2C8D7D9DB73F5D9DB74F5DAF5DCDB75F5E2DB76DB77DB78F5E0DB79DB7ADB7BF5DFF5DDDB7CDB7DF5E1DB7EDB80F5DEF5E4F5E5DB81CCE3DB82DB83E5BFB5B8F5E3F5E8CCA3DB84DB85DB86DB87DB88F5E6F5E7DB89DB8ADB8BDB8CDB8DDB8EF5BEDB8FDB90DB91DB92DB93DB94DB95DB96DB97DB98DB99DB9AB1C4DB9BDB9CF5BFDB9DDB9EB5C5B2E4DB9FF5ECF5E9DBA0B6D7DC40F5EDDC41F5EADC42DC43DC44DC45DC46F5EBDC47DC48B4DADC49D4EADC4ADC4BDC4CF5EEDC4DB3F9DC4EDC4FDC50DC51DC52DC53DC54F5EFF5F1DC55DC56DC57F5F0DC58DC59DC5ADC5BDC5CDC5DDC5EF5F2DC5FF5F3DC60DC61DC62DC63DC64DC65DC66DC67DC68DC69DC6ADC6BC9EDB9AADC6CDC6DC7FBDC6EDC6FB6E3DC70DC71DC72DC73DC74DC75DC76CCC9DC77DC78DC79DC7ADC7BDC7CDC7DDC7EDC80DC81DC82DC83DC84DC85DC86DC87DC88DC89DC8AEAA6DC8BDC8CDC8DDC8EDC8FDC90DC91DC92DC93DC94DC95DC96DC97DC98DC99DC9ADC9BDC9CDC9DDC9EDC9FDCA0DD40DD41DD42DD43DD44DD45DD46DD47DD48DD49DD4ADD4BDD4CDD4DDD4EDD4FDD50DD51DD52DD53DD54DD55DD56DD57DD58DD59DD5ADD5BDD5CDD5DDD5EDD5FDD60DD61DD62DD63DD64DD65DD66DD67DD68DD69DD6ADD6BDD6CDD6DDD6EDD6FDD70DD71DD72DD73DD74DD75DD76DD77DD78DD79DD7ADD7BDD7CDD7DDD7EDD80DD81DD82DD83DD84DD85DD86DD87DD88DD89DD8ADD8BDD8CDD8DDD8EDD8FDD90DD91DD92DD93DD94DD95DD96DD97DD98DD99DD9ADD9BDD9CDD9DDD9EDD9FDDA0DE40DE41DE42DE43DE44DE45DE46DE47DE48DE49DE4ADE4BDE4CDE4DDE4EDE4FDE50DE51DE52DE53DE54DE55DE56DE57DE58DE59DE5ADE5BDE5CDE5DDE5EDE5FDE60B3B5D4FEB9ECD0F9DE61E9EDD7AAE9EEC2D6C8EDBAE4E9EFE9F0E9F1D6E1E9F2E9F3E9F5E9F4E9F6E9F7C7E1E9F8D4D8E9F9BDCEDE62E9FAE9FBBDCFE9FCB8A8C1BEE9FDB1B2BBD4B9F5E9FEDE63EAA1EAA2EAA3B7F8BCADDE64CAE4E0CED4AFCFBDD5B7EAA4D5DEEAA5D0C1B9BCDE65B4C7B1D9DE66DE67DE68C0B1DE69DE6ADE6BDE6CB1E6B1E7DE6DB1E8DE6EDE6FDE70DE71B3BDC8E8DE72DE73DE74DE75E5C1DE76DE77B1DFDE78DE79DE7AC1C9B4EFDE7BDE7CC7A8D3D8DE7DC6F9D1B8DE7EB9FDC2F5DE80DE81DE82DE83DE84D3ADDE85D4CBBDFCDE86E5C2B7B5E5C3DE87DE88BBB9D5E2DE89BDF8D4B6CEA5C1ACB3D9DE8ADE8BCCF6DE8CE5C6E5C4E5C8DE8DE5CAE5C7B5CFC6C8DE8EB5FCE5C5DE8FCAF6DE90DE91E5C9DE92DE93DE94C3D4B1C5BCA3DE95DE96DE97D7B7DE98DE99CDCBCBCDCACACCD3E5CCE5CBC4E6DE9ADE9BD1A1D1B7E5CDDE9CE5D0DE9DCDB8D6F0E5CFB5DDDE9ECDBEDE9FE5D1B6BADEA0DF40CDA8B9E4DF41CAC5B3D1CBD9D4ECE5D2B7EADF42DF43DF44E5CEDF45DF46DF47DF48DF49DF4AE5D5B4FEE5D6DF4BDF4CDF4DDF4EDF4FE5D3E5D4DF50D2DDDF51DF52C2DFB1C6DF53D3E2DF54DF55B6DDCBECDF56E5D7DF57DF58D3F6DF59DF5ADF5BDF5CDF5DB1E9DF5EB6F4E5DAE5D8E5D9B5C0DF5FDF60DF61D2C5E5DCDF62DF63E5DEDF64DF65DF66DF67DF68DF69E5DDC7B2DF6AD2A3DF6BDF6CE5DBDF6DDF6EDF6FDF70D4E2D5DADF71DF72DF73DF74DF75E5E0D7F1DF76DF77DF78DF79DF7ADF7BDF7CE5E1DF7DB1DCD1FBDF7EE5E2E5E4DF80DF81DF82DF83E5E3DF84DF85E5E5DF86DF87DF88DF89DF8AD2D8DF8BB5CBDF8CE7DFDF8DDAF5DF8EDAF8DF8FDAF6DF90DAF7DF91DF92DF93DAFAD0CFC4C7DF94DF95B0EEDF96DF97DF98D0B0DF99DAF9DF9AD3CABAAADBA2C7F1DF9BDAFCDAFBC9DBDAFDDF9CDBA1D7DEDAFEC1DADF9DDF9EDBA5DF9FDFA0D3F4E040E041DBA7DBA4E042DBA8E043E044BDBCE045E046E047C0C9DBA3DBA6D6A3E048DBA9E049E04AE04BDBADE04CE04DE04EDBAEDBACBAC2E04FE050E051BFA4DBABE052E053E054DBAAD4C7B2BFE055E056DBAFE057B9F9E058DBB0E059E05AE05BE05CB3BBE05DE05EE05FB5A6E060E061E062E063B6BCDBB1E064E065E066B6F5E067DBB2E068E069E06AE06BE06CE06DE06EE06FE070E071E072E073E074E075E076E077E078E079E07AE07BB1C9E07CE07DE07EE080DBB4E081E082E083DBB3DBB5E084E085E086E087E088E089E08AE08BE08CE08DE08EDBB7E08FDBB6E090E091E092E093E094E095E096DBB8E097E098E099E09AE09BE09CE09DE09EE09FDBB9E0A0E140DBBAE141E142D3CFF4FAC7F5D7C3C5E4F4FCF4FDF4FBE143BEC6E144E145E146E147D0EFE148E149B7D3E14AE14BD4CDCCAAE14CE14DF5A2F5A1BAA8F4FECBD6E14EE14FE150F5A4C0D2E151B3EAE152CDAAF5A5F5A3BDB4F5A8E153F5A9BDCDC3B8BFE1CBE1F5AAE154E155E156F5A6F5A7C4F0E157E158E159E15AE15BF5ACE15CB4BCE15DD7EDE15EB4D7F5ABF5AEE15FE160F5ADF5AFD0D1E161E162E163E164E165E166E167C3D1C8A9E168E169E16AE16BE16CE16DF5B0F5B1E16EE16FE170E171E172E173F5B2E174E175F5B3F5B4F5B5E176E177E178E179F5B7F5B6E17AE17BE17CE17DF5B8E17EE180E181E182E183E184E185E186E187E188E189E18AB2C9E18BD3D4CACDE18CC0EFD6D8D2B0C1BFE18DBDF0E18EE18FE190E191E192E193E194E195E196E197B8AAE198E199E19AE19BE19CE19DE19EE19FE1A0E240E241E242E243E244E245E246E247E248E249E24AE24BE24CE24DE24EE24FE250E251E252E253E254E255E256E257E258E259E25AE25BE25CE25DE25EE25FE260E261E262E263E264E265E266E267E268E269E26AE26BE26CE26DE26EE26FE270E271E272E273E274E275E276E277E278E279E27AE27BE27CE27DE27EE280E281E282E283E284E285E286E287E288E289E28AE28BE28CE28DE28EE28FE290E291E292E293E294E295E296E297E298E299E29AE29BE29CE29DE29EE29FE2A0E340E341E342E343E344E345E346E347E348E349E34AE34BE34CE34DE34EE34FE350E351E352E353E354E355E356E357E358E359E35AE35BE35CE35DE35EE35FE360E361E362E363E364E365E366E367E368E369E36AE36BE36CE36DBCF8E36EE36FE370E371E372E373E374E375E376E377E378E379E37AE37BE37CE37DE37EE380E381E382E383E384E385E386E387F6C6E388E389E38AE38BE38CE38DE38EE38FE390E391E392E393E394E395E396E397E398E399E39AE39BE39CE39DE39EE39FE3A0E440E441E442E443E444E445F6C7E446E447E448E449E44AE44BE44CE44DE44EE44FE450E451E452E453E454E455E456E457E458E459E45AE45BE45CE45DE45EF6C8E45FE460E461E462E463E464E465E466E467E468E469E46AE46BE46CE46DE46EE46FE470E471E472E473E474E475E476E477E478E479E47AE47BE47CE47DE47EE480E481E482E483E484E485E486E487E488E489E48AE48BE48CE48DE48EE48FE490E491E492E493E494E495E496E497E498E499E49AE49BE49CE49DE49EE49FE4A0E540E541E542E543E544E545E546E547E548E549E54AE54BE54CE54DE54EE54FE550E551E552E553E554E555E556E557E558E559E55AE55BE55CE55DE55EE55FE560E561E562E563E564E565E566E567E568E569E56AE56BE56CE56DE56EE56FE570E571E572E573F6C9E574E575E576E577E578E579E57AE57BE57CE57DE57EE580E581E582E583E584E585E586E587E588E589E58AE58BE58CE58DE58EE58FE590E591E592E593E594E595E596E597E598E599E59AE59BE59CE59DE59EE59FF6CAE5A0E640E641E642E643E644E645E646E647E648E649E64AE64BE64CE64DE64EE64FE650E651E652E653E654E655E656E657E658E659E65AE65BE65CE65DE65EE65FE660E661E662F6CCE663E664E665E666E667E668E669E66AE66BE66CE66DE66EE66FE670E671E672E673E674E675E676E677E678E679E67AE67BE67CE67DE67EE680E681E682E683E684E685E686E687E688E689E68AE68BE68CE68DE68EE68FE690E691E692E693E694E695E696E697E698E699E69AE69BE69CE69DF6CBE69EE69FE6A0E740E741E742E743E744E745E746E747F7E9E748E749E74AE74BE74CE74DE74EE74FE750E751E752E753E754E755E756E757E758E759E75AE75BE75CE75DE75EE75FE760E761E762E763E764E765E766E767E768E769E76AE76BE76CE76DE76EE76FE770E771E772E773E774E775E776E777E778E779E77AE77BE77CE77DE77EE780E781E782E783E784E785E786E787E788E789E78AE78BE78CE78DE78EE78FE790E791E792E793E794E795E796E797E798E799E79AE79BE79CE79DE79EE79FE7A0E840E841E842E843E844E845E846E847E848E849E84AE84BE84CE84DE84EF6CDE84FE850E851E852E853E854E855E856E857E858E859E85AE85BE85CE85DE85EE85FE860E861E862E863E864E865E866E867E868E869E86AE86BE86CE86DE86EE86FE870E871E872E873E874E875E876E877E878E879E87AF6CEE87BE87CE87DE87EE880E881E882E883E884E885E886E887E888E889E88AE88BE88CE88DE88EE88FE890E891E892E893E894EEC4EEC5EEC6D5EBB6A4EEC8EEC7EEC9EECAC7A5EECBEECCE895B7B0B5F6EECDEECFE896EECEE897B8C6EED0EED1EED2B6DBB3AED6D3C4C6B1B5B8D6EED3EED4D4BFC7D5BEFBCED9B9B3EED6EED5EED8EED7C5A5EED9EEDAC7AEEEDBC7AFEEDCB2A7EEDDEEDEEEDFEEE0EEE1D7EAEEE2EEE3BCD8EEE4D3CBCCFAB2ACC1E5EEE5C7A6C3ADE898EEE6EEE7EEE8EEE9EEEAEEEBEEECE899EEEDEEEEEEEFE89AE89BEEF0EEF1EEF2EEF4EEF3E89CEEF5CDADC2C1EEF6EEF7EEF8D5A1EEF9CFB3EEFAEEFBE89DEEFCEEFDEFA1EEFEEFA2B8F5C3FAEFA3EFA4BDC2D2BFB2F9EFA5EFA6EFA7D2F8EFA8D6FDEFA9C6CCE89EEFAAEFABC1B4EFACCFFACBF8EFAEEFADB3FAB9F8EFAFEFB0D0E2EFB1EFB2B7E6D0BFEFB3EFB4EFB5C8F1CCE0EFB6EFB7EFB8EFB9EFBAD5E0EFBBB4EDC3AAEFBCE89FEFBDEFBEEFBFE8A0CEFDEFC0C2E0B4B8D7B6BDF5E940CFC7EFC3EFC1EFC2EFC4B6A7BCFCBEE2C3CCEFC5EFC6E941EFC7EFCFEFC8EFC9EFCAC7C2EFF1B6CDEFCBE942EFCCEFCDB6C6C3BEEFCEE943EFD0EFD1EFD2D5F2E944EFD3C4F7E945EFD4C4F8EFD5EFD6B8E4B0F7EFD7EFD8EFD9E946EFDAEFDBEFDCEFDDE947EFDEBEB5EFE1EFDFEFE0E948EFE2EFE3C1CDEFE4EFE5EFE6EFE7EFE8EFE9EFEAEFEBEFECC0D8E949EFEDC1ADEFEEEFEFEFF0E94AE94BCFE2E94CE94DE94EE94FE950E951E952E953B3A4E954E955E956E957E958E959E95AE95BE95CE95DE95EE95FE960E961E962E963E964E965E966E967E968E969E96AE96BE96CE96DE96EE96FE970E971E972E973E974E975E976E977E978E979E97AE97BE97CE97DE97EE980E981E982E983E984E985E986E987E988E989E98AE98BE98CE98DE98EE98FE990E991E992E993E994E995E996E997E998E999E99AE99BE99CE99DE99EE99FE9A0EA40EA41EA42EA43EA44EA45EA46EA47EA48EA49EA4AEA4BEA4CEA4DEA4EEA4FEA50EA51EA52EA53EA54EA55EA56EA57EA58EA59EA5AEA5BC3C5E3C5C9C1E3C6EA5CB1D5CECAB4B3C8F2E3C7CFD0E3C8BCE4E3C9E3CAC3C6D5A2C4D6B9EBCEC5E3CBC3F6E3CCEA5DB7A7B8F3BAD2E3CDE3CED4C4E3CFEA5EE3D0D1CBE3D1E3D2E3D3E3D4D1D6E3D5B2FBC0BBE3D6EA5FC0ABE3D7E3D8E3D9EA60E3DAE3DBEA61B8B7DAE2EA62B6D3EA63DAE4DAE3EA64EA65EA66EA67EA68EA69EA6ADAE6EA6BEA6CEA6DC8EEEA6EEA6FDAE5B7C0D1F4D2F5D5F3BDD7EA70EA71EA72EA73D7E8DAE8DAE7EA74B0A2CDD3EA75DAE9EA76B8BDBCCAC2BDC2A4B3C2DAEAEA77C2AAC4B0BDB5EA78EA79CFDEEA7AEA7BEA7CDAEBC9C2EA7DEA7EEA80EA81EA82B1DDEA83EA84EA85DAECEA86B6B8D4BAEA87B3FDEA88EA89DAEDD4C9CFD5C5E3EA8ADAEEEA8BEA8CEA8DEA8EEA8FDAEFEA90DAF0C1EACCD5CFDDEA91EA92EA93EA94EA95EA96EA97EA98EA99EA9AEA9BEA9CEA9DD3E7C2A1EA9EDAF1EA9FEAA0CBE5EB40DAF2EB41CBE6D2FEEB42EB43EB44B8F4EB45EB46DAF3B0AFCFB6EB47EB48D5CFEB49EB4AEB4BEB4CEB4DEB4EEB4FEB50EB51EB52CBEDEB53EB54EB55EB56EB57EB58EB59EB5ADAF4EB5BEB5CE3C4EB5DEB5EC1A5EB5FEB60F6BFEB61EB62F6C0F6C1C4D1EB63C8B8D1E3EB64EB65D0DBD1C5BCAFB9CDEB66EFF4EB67EB68B4C6D3BAF6C2B3FBEB69EB6AF6C3EB6BEB6CB5F1EB6DEB6EEB6FEB70EB71EB72EB73EB74EB75EB76F6C5EB77EB78EB79EB7AEB7BEB7CEB7DD3EAF6A7D1A9EB7EEB80EB81EB82F6A9EB83EB84EB85F6A8EB86EB87C1E3C0D7EB88B1A2EB89EB8AEB8BEB8CCEEDEB8DD0E8F6ABEB8EEB8FCFF6EB90F6AAD5F0F6ACC3B9EB91EB92EB93BBF4F6AEF6ADEB94EB95EB96C4DEEB97EB98C1D8EB99EB9AEB9BEB9CEB9DCBAAEB9ECFBCEB9FEBA0EC40EC41EC42EC43EC44EC45EC46EC47EC48F6AFEC49EC4AF6B0EC4BEC4CF6B1EC4DC2B6EC4EEC4FEC50EC51EC52B0D4C5F9EC53EC54EC55EC56F6B2EC57EC58EC59EC5AEC5BEC5CEC5DEC5EEC5FEC60EC61EC62EC63EC64EC65EC66EC67EC68EC69C7E0F6A6EC6AEC6BBEB8EC6CEC6DBEB2EC6EB5E5EC6FEC70B7C7EC71BFBFC3D2C3E6EC72EC73D8CCEC74EC75EC76B8EFEC77EC78EC79EC7AEC7BEC7CEC7DEC7EEC80BDF9D1A5EC81B0D0EC82EC83EC84EC85EC86F7B0EC87EC88EC89EC8AEC8BEC8CEC8DEC8EF7B1EC8FEC90EC91EC92EC93D0ACEC94B0B0EC95EC96EC97F7B2F7B3EC98F7B4EC99EC9AEC9BC7CAEC9CEC9DEC9EEC9FECA0ED40ED41BECFED42ED43F7B7ED44ED45ED46ED47ED48ED49ED4AF7B6ED4BB1DEED4CF7B5ED4DED4EF7B8ED4FF7B9ED50ED51ED52ED53ED54ED55ED56ED57ED58ED59ED5AED5BED5CED5DED5EED5FED60ED61ED62ED63ED64ED65ED66ED67ED68ED69ED6AED6BED6CED6DED6EED6FED70ED71ED72ED73ED74ED75ED76ED77ED78ED79ED7AED7BED7CED7DED7EED80ED81CEA4C8CDED82BAABE8B8E8B9E8BABEC2ED83ED84ED85ED86ED87D2F4ED88D4CFC9D8ED89ED8AED8BED8CED8DED8EED8FED90ED91ED92ED93ED94ED95ED96ED97ED98ED99ED9AED9BED9CED9DED9EED9FEDA0EE40EE41EE42EE43EE44EE45EE46EE47EE48EE49EE4AEE4BEE4CEE4DEE4EEE4FEE50EE51EE52EE53EE54EE55EE56EE57EE58EE59EE5AEE5BEE5CEE5DEE5EEE5FEE60EE61EE62EE63EE64EE65EE66EE67EE68EE69EE6AEE6BEE6CEE6DEE6EEE6FEE70EE71EE72EE73EE74EE75EE76EE77EE78EE79EE7AEE7BEE7CEE7DEE7EEE80EE81EE82EE83EE84EE85EE86EE87EE88EE89EE8AEE8BEE8CEE8DEE8EEE8FEE90EE91EE92EE93EE94EE95EE96EE97EE98EE99EE9AEE9BEE9CEE9DEE9EEE9FEEA0EF40EF41EF42EF43EF44EF45D2B3B6A5C7EAF1FCCFEECBB3D0EBE7EFCDE7B9CBB6D9F1FDB0E4CBCCF1FED4A4C2ADC1ECC6C4BEB1F2A1BCD5EF46F2A2F2A3EF47F2A4D2C3C6B5EF48CDC7F2A5EF49D3B1BFC5CCE2EF4AF2A6F2A7D1D5B6EEF2A8F2A9B5DFF2AAF2ABEF4BB2FCF2ACF2ADC8A7EF4CEF4DEF4EEF4FEF50EF51EF52EF53EF54EF55EF56EF57EF58EF59EF5AEF5BEF5CEF5DEF5EEF5FEF60EF61EF62EF63EF64EF65EF66EF67EF68EF69EF6AEF6BEF6CEF6DEF6EEF6FEF70EF71B7E7EF72EF73ECA9ECAAECABEF74ECACEF75EF76C6AEECADECAEEF77EF78EF79B7C9CAB3EF7AEF7BEF7CEF7DEF7EEF80EF81E2B8F7CFEF82EF83EF84EF85EF86EF87EF88EF89EF8AEF8BEF8CEF8DEF8EEF8FEF90EF91EF92EF93EF94EF95EF96EF97EF98EF99EF9AEF9BEF9CEF9DEF9EEF9FEFA0F040F041F042F043F044F7D0F045F046B2CDF047F048F049F04AF04BF04CF04DF04EF04FF050F051F052F053F054F055F056F057F058F059F05AF05BF05CF05DF05EF05FF060F061F062F063F7D1F064F065F066F067F068F069F06AF06BF06CF06DF06EF06FF070F071F072F073F074F075F076F077F078F079F07AF07BF07CF07DF07EF080F081F082F083F084F085F086F087F088F089F7D3F7D2F08AF08BF08CF08DF08EF08FF090F091F092F093F094F095F096E2BBF097BCA2F098E2BCE2BDE2BEE2BFE2C0E2C1B7B9D2FBBDA4CACEB1A5CBC7F099E2C2B6FCC8C4E2C3F09AF09BBDC8F09CB1FDE2C4F09DB6F6E2C5C4D9F09EF09FE2C6CFDAB9DDE2C7C0A1F0A0E2C8B2F6F140E2C9F141C1F3E2CAE2CBC2F8E2CCE2CDE2CECAD7D8B8D9E5CFE3F142F143F144F145F146F147F148F149F14AF14BF14CF0A5F14DF14EDCB0F14FF150F151F152F153F154F155F156F157F158F159F15AF15BF15CF15DF15EF15FF160F161F162F163F164F165F166F167F168F169F16AF16BF16CF16DF16EF16FF170F171F172F173F174F175F176F177F178F179F17AF17BF17CF17DF17EF180F181F182F183F184F185F186F187F188F189F18AF18BF18CF18DF18EF18FF190F191F192F193F194F195F196F197F198F199F19AF19BF19CF19DF19EF19FF1A0F240F241F242F243F244F245F246F247F248F249F24AF24BF24CF24DF24EF24FF250F251F252F253F254F255F256F257F258F259F25AF25BF25CF25DF25EF25FF260F261F262F263F264F265F266F267F268F269F26AF26BF26CF26DF26EF26FF270F271F272F273F274F275F276F277F278F279F27AF27BF27CF27DF27EF280F281F282F283F284F285F286F287F288F289F28AF28BF28CF28DF28EF28FF290F291F292F293F294F295F296F297F298F299F29AF29BF29CF29DF29EF29FF2A0F340F341F342F343F344F345F346F347F348F349F34AF34BF34CF34DF34EF34FF350F351C2EDD4A6CDD4D1B1B3DBC7FDF352B2B5C2BFE6E0CABBE6E1E6E2BED4E6E3D7A4CDD5E6E5BCDDE6E4E6E6E6E7C2EEF353BDBEE6E8C2E6BAA7E6E9F354E6EAB3D2D1E9F355F356BFA5E6EBC6EFE6ECE6EDF357F358E6EEC6ADE6EFF359C9A7E6F0E6F1E6F2E5B9E6F3E6F4C2E2E6F5E6F6D6E8E6F7F35AE6F8B9C7F35BF35CF35DF35EF35FF360F361F7BBF7BAF362F363F364F365F7BEF7BCBAA1F366F7BFF367F7C0F368F369F36AF7C2F7C1F7C4F36BF36CF7C3F36DF36EF36FF370F371F7C5F7C6F372F373F374F375F7C7F376CBE8F377F378F379F37AB8DFF37BF37CF37DF37EF380F381F7D4F382F7D5F383F384F385F386F7D6F387F388F389F38AF7D8F38BF7DAF38CF7D7F38DF38EF38FF390F391F392F393F394F395F7DBF396F7D9F397F398F399F39AF39BF39CF39DD7D7F39EF39FF3A0F440F7DCF441F442F443F444F445F446F7DDF447F448F449F7DEF44AF44BF44CF44DF44EF44FF450F451F452F453F454F7DFF455F456F457F7E0F458F459F45AF45BF45CF45DF45EF45FF460F461F462DBCBF463F464D8AAF465F466F467F468F469F46AF46BF46CE5F7B9EDF46DF46EF46FF470BFFDBBEAF7C9C6C7F7C8F471F7CAF7CCF7CBF472F473F474F7CDF475CEBAF476F7CEF477F478C4A7F479F47AF47BF47CF47DF47EF480F481F482F483F484F485F486F487F488F489F48AF48BF48CF48DF48EF48FF490F491F492F493F494F495F496F497F498F499F49AF49BF49CF49DF49EF49FF4A0F540F541F542F543F544F545F546F547F548F549F54AF54BF54CF54DF54EF54FF550F551F552F553F554F555F556F557F558F559F55AF55BF55CF55DF55EF55FF560F561F562F563F564F565F566F567F568F569F56AF56BF56CF56DF56EF56FF570F571F572F573F574F575F576F577F578F579F57AF57BF57CF57DF57EF580F581F582F583F584F585F586F587F588F589F58AF58BF58CF58DF58EF58FF590F591F592F593F594F595F596F597F598F599F59AF59BF59CF59DF59EF59FF5A0F640F641F642F643F644F645F646F647F648F649F64AF64BF64CF64DF64EF64FF650F651F652F653F654F655F656F657F658F659F65AF65BF65CF65DF65EF65FF660F661F662F663F664F665F666F667F668F669F66AF66BF66CF66DF66EF66FF670F671F672F673F674F675F676F677F678F679F67AF67BF67CF67DF67EF680F681F682F683F684F685F686F687F688F689F68AF68BF68CF68DF68EF68FF690F691F692F693F694F695F696F697F698F699F69AF69BF69CF69DF69EF69FF6A0F740F741F742F743F744F745F746F747F748F749F74AF74BF74CF74DF74EF74FF750F751F752F753F754F755F756F757F758F759F75AF75BF75CF75DF75EF75FF760F761F762F763F764F765F766F767F768F769F76AF76BF76CF76DF76EF76FF770F771F772F773F774F775F776F777F778F779F77AF77BF77CF77DF77EF780D3E3F781F782F6CFF783C2B3F6D0F784F785F6D1F6D2F6D3F6D4F786F787F6D6F788B1ABF6D7F789F6D8F6D9F6DAF78AF6DBF6DCF78BF78CF78DF78EF6DDF6DECFCAF78FF6DFF6E0F6E1F6E2F6E3F6E4C0F0F6E5F6E6F6E7F6E8F6E9F790F6EAF791F6EBF6ECF792F6EDF6EEF6EFF6F0F6F1F6F2F6F3F6F4BEA8F793F6F5F6F6F6F7F6F8F794F795F796F797F798C8FAF6F9F6FAF6FBF6FCF799F79AF6FDF6FEF7A1F7A2F7A3F7A4F7A5F79BF79CF7A6F7A7F7A8B1EEF7A9F7AAF7ABF79DF79EF7ACF7ADC1DBF7AEF79FF7A0F7AFF840F841F842F843F844F845F846F847F848F849F84AF84BF84CF84DF84EF84FF850F851F852F853F854F855F856F857F858F859F85AF85BF85CF85DF85EF85FF860F861F862F863F864F865F866F867F868F869F86AF86BF86CF86DF86EF86FF870F871F872F873F874F875F876F877F878F879F87AF87BF87CF87DF87EF880F881F882F883F884F885F886F887F888F889F88AF88BF88CF88DF88EF88FF890F891F892F893F894F895F896F897F898F899F89AF89BF89CF89DF89EF89FF8A0F940F941F942F943F944F945F946F947F948F949F94AF94BF94CF94DF94EF94FF950F951F952F953F954F955F956F957F958F959F95AF95BF95CF95DF95EF95FF960F961F962F963F964F965F966F967F968F969F96AF96BF96CF96DF96EF96FF970F971F972F973F974F975F976F977F978F979F97AF97BF97CF97DF97EF980F981F982F983F984F985F986F987F988F989F98AF98BF98CF98DF98EF98FF990F991F992F993F994F995F996F997F998F999F99AF99BF99CF99DF99EF99FF9A0FA40FA41FA42FA43FA44FA45FA46FA47FA48FA49FA4AFA4BFA4CFA4DFA4EFA4FFA50FA51FA52FA53FA54FA55FA56FA57FA58FA59FA5AFA5BFA5CFA5DFA5EFA5FFA60FA61FA62FA63FA64FA65FA66FA67FA68FA69FA6AFA6BFA6CFA6DFA6EFA6FFA70FA71FA72FA73FA74FA75FA76FA77FA78FA79FA7AFA7BFA7CFA7DFA7EFA80FA81FA82FA83FA84FA85FA86FA87FA88FA89FA8AFA8BFA8CFA8DFA8EFA8FFA90FA91FA92FA93FA94FA95FA96FA97FA98FA99FA9AFA9BFA9CFA9DFA9EFA9FFAA0FB40FB41FB42FB43FB44FB45FB46FB47FB48FB49FB4AFB4BFB4CFB4DFB4EFB4FFB50FB51FB52FB53FB54FB55FB56FB57FB58FB59FB5AFB5BC4F1F0AFBCA6F0B0C3F9FB5CC5B8D1BBFB5DF0B1F0B2F0B3F0B4F0B5D1BCFB5ED1ECFB5FF0B7F0B6D4A7FB60CDD2F0B8F0BAF0B9F0BBF0BCFB61FB62B8EBF0BDBAE8FB63F0BEF0BFBEE9F0C0B6ECF0C1F0C2F0C3F0C4C8B5F0C5F0C6FB64F0C7C5F4FB65F0C8FB66FB67FB68F0C9FB69F0CAF7BDFB6AF0CBF0CCF0CDFB6BF0CEFB6CFB6DFB6EFB6FF0CFBAD7FB70F0D0F0D1F0D2F0D3F0D4F0D5F0D6F0D8FB71FB72D3A5F0D7FB73F0D9FB74FB75FB76FB77FB78FB79FB7AFB7BFB7CFB7DF5BAC2B9FB7EFB80F7E4FB81FB82FB83FB84F7E5F7E6FB85FB86F7E7FB87FB88FB89FB8AFB8BFB8CF7E8C2B4FB8DFB8EFB8FFB90FB91FB92FB93FB94FB95F7EAFB96F7EBFB97FB98FB99FB9AFB9BFB9CC2F3FB9DFB9EFB9FFBA0FC40FC41FC42FC43FC44FC45FC46FC47FC48F4F0FC49FC4AFC4BF4EFFC4CFC4DC2E9FC4EF7E1F7E2FC4FFC50FC51FC52FC53BBC6FC54FC55FC56FC57D9E4FC58FC59FC5ACAF2C0E8F0A4FC5BBADAFC5CFC5DC7ADFC5EFC5FFC60C4ACFC61FC62F7ECF7EDF7EEFC63F7F0F7EFFC64F7F1FC65FC66F7F4FC67F7F3FC68F7F2F7F5FC69FC6AFC6BFC6CF7F6FC6DFC6EFC6FFC70FC71FC72FC73FC74FC75EDE9FC76EDEAEDEBFC77F6BCFC78FC79FC7AFC7BFC7CFC7DFC7EFC80FC81FC82FC83FC84F6BDFC85F6BEB6A6FC86D8BEFC87FC88B9C4FC89FC8AFC8BD8BBFC8CDCB1FC8DFC8EFC8FFC90FC91FC92CAF3FC93F7F7FC94FC95FC96FC97FC98FC99FC9AFC9BFC9CF7F8FC9DFC9EF7F9FC9FFCA0FD40FD41FD42FD43FD44F7FBFD45F7FAFD46B1C7FD47F7FCF7FDFD48FD49FD4AFD4BFD4CF7FEFD4DFD4EFD4FFD50FD51FD52FD53FD54FD55FD56FD57C6EBECB4FD58FD59FD5AFD5BFD5CFD5DFD5EFD5FFD60FD61FD62FD63FD64FD65FD66FD67FD68FD69FD6AFD6BFD6CFD6DFD6EFD6FFD70FD71FD72FD73FD74FD75FD76FD77FD78FD79FD7AFD7BFD7CFD7DFD7EFD80FD81FD82FD83FD84FD85B3DDF6B3FD86FD87F6B4C1E4F6B5F6B6F6B7F6B8F6B9F6BAC8A3F6BBFD88FD89FD8AFD8BFD8CFD8DFD8EFD8FFD90FD91FD92FD93C1FAB9A8EDE8FD94FD95FD96B9EAD9DFFD97FD98FD99FD9AFD9'; + + for (var i = 0; i < str.length; i++) { + var c = str.charAt(i), + code = str.charCodeAt(i); + if (c == " ") strOut += "+"; + else if (code >= 19968 && code <= 40869) { + var index = code - 19968; + strOut += "%" + z.substr(index * 4, 2) + "%" + z.substr(index * 4 + 2, 2); + } else { + strOut += "%" + str.charCodeAt(i).toString(16); + } + } + return strOut; + }, + /* 改变图片大小 */ + scale: function (img, w, h) { + var ow = img.width, + oh = img.height; + + if (ow >= oh) { + img.width = w * ow / oh; + img.height = h; + img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px'; + } else { + img.width = w; + img.height = h * oh / ow; + img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px'; + } + }, + getImageData: function(){ + var _this = this, + key = $G('searchTxt').value, + type = $G('searchType').value, + keepOriginName = editor.options.keepOriginName ? "1" : "0", + url = "http://image.baidu.com/i?ct=201326592&cl=2&lm=-1&st=-1&tn=baiduimagejson&istype=2&rn=32&fm=index&pv=&word=" + _this.encodeToGb2312(key) + type + "&keeporiginname=" + keepOriginName + "&" + +new Date; + + $G('searchListUl').innerHTML = lang.searchLoading; + ajax.request(url, { + 'dataType': 'jsonp', + 'charset': 'GB18030', + 'onsuccess':function(json){ + var list = []; + if(json && json.data) { + for(var i = 0; i < json.data.length; i++) { + if(json.data[i].objURL) { + list.push({ + title: json.data[i].fromPageTitleEnc, + src: json.data[i].objURL, + url: json.data[i].fromURL + }); + } + } + } + _this.setList(list); + }, + 'onerror':function(){ + $G('searchListUl').innerHTML = lang.searchRetry; + } + }); + }, + /* 添加图片到列表界面上 */ + setList: function (list) { + var i, item, p, img, link, _this = this, + listUl = $G('searchListUl'); + + listUl.innerHTML = ''; + if(list.length) { + for (i = 0; i < list.length; i++) { + item = document.createElement('li'); + p = document.createElement('p'); + img = document.createElement('img'); + link = document.createElement('a'); + + img.onload = function () { + _this.scale(this, 113, 113); + }; + img.width = 113; + img.setAttribute('src', list[i].src); + + link.href = list[i].url; + link.target = '_blank'; + link.title = list[i].title; + link.innerHTML = list[i].title; + + p.appendChild(img); + item.appendChild(p); + item.appendChild(link); + listUl.appendChild(item); + } + } else { + listUl.innerHTML = lang.searchRetry; + } + }, + getInsertList: function () { + var child, + src, + align = getAlign(), + list = [], + items = $G('searchListUl').children; + for(var i = 0; i < items.length; i++) { + child = items[i].firstChild && items[i].firstChild.firstChild; + if(child.tagName && child.tagName.toLowerCase() == 'img' && domUtils.hasClass(items[i], 'selected')) { + src = child.src; + list.push({ + src: src, + _src: src, + alt: src.substr(src.lastIndexOf('/') + 1), + floatStyle: align + }); + } + } + return list; + } + }; + +})(); diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/alignicon.jpg b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/alignicon.jpg new file mode 100644 index 000000000..754755b1b Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/alignicon.jpg differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/bg.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/bg.png new file mode 100644 index 000000000..580be0a01 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/bg.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/icons.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/icons.gif new file mode 100644 index 000000000..78459dea7 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/icons.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/icons.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/icons.png new file mode 100644 index 000000000..12e470016 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/icons.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/image.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/image.png new file mode 100644 index 000000000..19699f6a9 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/image.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/progress.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/progress.png new file mode 100644 index 000000000..717c4865c Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/progress.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/success.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/success.gif new file mode 100644 index 000000000..8d4f3112b Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/success.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/success.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/success.png new file mode 100644 index 000000000..94f968dc8 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/image/images/success.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/insertframe/insertframe.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/insertframe/insertframe.html new file mode 100644 index 000000000..7f1f3e9a1 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/insertframe/insertframe.html @@ -0,0 +1,98 @@ + + + + + + + + + +
          + + + + + + + + + + + + + + + + + + + +
          + + +
          px
          px
          + +
          +
          + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/internal.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/internal.js new file mode 100644 index 000000000..44dc17fbf --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/internal.js @@ -0,0 +1,81 @@ +(function () { + var parent = window.parent; + //dialog对象 + dialog = parent.$EDITORUI[window.frameElement.id.replace( /_iframe$/, '' )]; + //当前打开dialog的编辑器实例 + editor = dialog.editor; + + UE = parent.UE; + + domUtils = UE.dom.domUtils; + + utils = UE.utils; + + browser = UE.browser; + + ajax = UE.ajax; + + $G = function ( id ) { + return document.getElementById( id ) + }; + //focus元素 + $focus = function ( node ) { + setTimeout( function () { + if ( browser.ie ) { + var r = node.createTextRange(); + r.collapse( false ); + r.select(); + } else { + node.focus() + } + }, 0 ) + }; + utils.loadFile(document,{ + href:editor.options.themePath + editor.options.theme + "/dialogbase.css?cache="+Math.random(), + tag:"link", + type:"text/css", + rel:"stylesheet" + }); + lang = editor.getLang(dialog.className.split( "-" )[2]); + if(lang){ + domUtils.on(window,'load',function () { + + var langImgPath = editor.options.langPath + editor.options.lang + "/images/"; + //针对静态资源 + for ( var i in lang["static"] ) { + var dom = $G( i ); + if(!dom) continue; + var tagName = dom.tagName, + content = lang["static"][i]; + if(content.src){ + //clone + content = utils.extend({},content,false); + content.src = langImgPath + content.src; + } + if(content.style){ + content = utils.extend({},content,false); + content.style = content.style.replace(/url\s*\(/g,"url(" + langImgPath) + } + switch ( tagName.toLowerCase() ) { + case "var": + dom.parentNode.replaceChild( document.createTextNode( content ), dom ); + break; + case "select": + var ops = dom.options; + for ( var j = 0, oj; oj = ops[j]; ) { + oj.innerHTML = content.options[j++]; + } + for ( var p in content ) { + p != "options" && dom.setAttribute( p, content[p] ); + } + break; + default : + domUtils.setAttributes( dom, content); + } + } + } ); + } + + +})(); + diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/link/link.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/link/link.html new file mode 100644 index 000000000..55ab4d1e2 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/link/link.html @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
          + + +
          + + + diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/map/map.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/map/map.html new file mode 100644 index 000000000..e763b8eb0 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/map/map.html @@ -0,0 +1,135 @@ + + + + + + + + + + +
          + + + + + + + + + +
          ::
          +
          + +
          + + + + + diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/map/show.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/map/show.html new file mode 100644 index 000000000..329cfebfb --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/map/show.html @@ -0,0 +1,118 @@ + + + + + + + 百度地图API自定义地图 + + + + + + + +
          + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/music/music.css b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/music/music.css new file mode 100644 index 000000000..8fb7a94c3 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/music/music.css @@ -0,0 +1,30 @@ +.wrapper{margin: 5px 10px;} + +.searchBar{height:30px;padding:7px 0 3px;text-align:center;} +.searchBtn{font-size:13px;height:24px;} + +.resultBar{width:460px;margin:5px auto;border: 1px solid #CCC;border-radius: 5px;box-shadow: 2px 2px 5px #D3D6DA;overflow: hidden;} + +.listPanel{overflow: hidden;} +.panelon{display:block;} +.paneloff{display:none} + +.page{width:220px;margin:20px auto;overflow: hidden;} +.pageon{float:right;width:24px;line-height:24px;height:24px;margin-right: 5px;background: none;border: none;color: #000;font-weight: bold;text-align:center} +.pageoff{float:right;width:24px;line-height:24px;height:24px;cursor:pointer;background-color: #fff; + border: 1px solid #E7ECF0;color: #2D64B3;margin-right: 5px;text-decoration: none;text-align:center;} + +.m-box{width:460px;} +.m-m{float: left;line-height: 20px;height: 20px;} +.m-h{height:24px;line-height:24px;padding-left: 46px;background-color:#FAFAFA;border-bottom: 1px solid #DAD8D8;font-weight: bold;font-size: 12px;color: #333;} +.m-l{float:left;width:40px; } +.m-t{float:left;width:140px;} +.m-s{float:left;width:110px;} +.m-z{float:left;width:100px;} +.m-try-t{float: left;width: 60px;;} + +.m-try{float:left;width:20px;height:20px;background:url('http://static.tieba.baidu.com/tb/editor/images/try_music.gif') no-repeat ;} +.m-trying{float:left;width:20px;height:20px;background:url('http://static.tieba.baidu.com/tb/editor/images/stop_music.gif') no-repeat ;} + +.loading{width:95px;height:7px;font-size:7px;margin:60px auto;background:url(http://static.tieba.baidu.com/tb/editor/images/loading.gif) no-repeat} +.empty{width:300px;height:40px;padding:2px;margin:50px auto;line-height:40px; color:#006699;text-align:center;} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/music/music.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/music/music.html new file mode 100644 index 000000000..e7ef04f39 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/music/music.html @@ -0,0 +1,32 @@ + + + + + 插入音乐 + + + + +
          + +
          + +
          +
          +
          +
          + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/music/music.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/music/music.js new file mode 100644 index 000000000..1c538bf66 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/music/music.js @@ -0,0 +1,192 @@ +function Music() { + this.init(); +} +(function () { + var pages = [], + panels = [], + selectedItem = null; + Music.prototype = { + total:70, + pageSize:10, + dataUrl:"http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.search.common", + playerUrl:"http://box.baidu.com/widget/flash/bdspacesong.swf", + + init:function () { + var me = this; + domUtils.on($G("J_searchName"), "keyup", function (event) { + var e = window.event || event; + if (e.keyCode == 13) { + me.dosearch(); + } + }); + domUtils.on($G("J_searchBtn"), "click", function () { + me.dosearch(); + }); + }, + callback:function (data) { + var me = this; + me.data = data.song_list; + setTimeout(function () { + $G('J_resultBar').innerHTML = me._renderTemplate(data.song_list); + }, 300); + }, + dosearch:function () { + var me = this; + selectedItem = null; + var key = $G('J_searchName').value; + if (utils.trim(key) == "")return false; + key = encodeURIComponent(key); + me._sent(key); + }, + doselect:function (i) { + var me = this; + if (typeof i == 'object') { + selectedItem = i; + } else if (typeof i == 'number') { + selectedItem = me.data[i]; + } + }, + onpageclick:function (id) { + var me = this; + for (var i = 0; i < pages.length; i++) { + $G(pages[i]).className = 'pageoff'; + $G(panels[i]).className = 'paneloff'; + } + $G('page' + id).className = 'pageon'; + $G('panel' + id).className = 'panelon'; + }, + listenTest:function (elem) { + var me = this, + view = $G('J_preview'), + is_play_action = (elem.className == 'm-try'), + old_trying = me._getTryingElem(); + + if (old_trying) { + old_trying.className = 'm-try'; + view.innerHTML = ''; + } + if (is_play_action) { + elem.className = 'm-trying'; + view.innerHTML = me._buildMusicHtml(me._getUrl(true)); + } + }, + _sent:function (param) { + var me = this; + $G('J_resultBar').innerHTML = '
          '; + + utils.loadFile(document, { + src:me.dataUrl + '&query=' + param + '&page_size=' + me.total + '&callback=music.callback&.r=' + Math.random(), + tag:"script", + type:"text/javascript", + defer:"defer" + }); + }, + _removeHtml:function (str) { + var reg = /<\s*\/?\s*[^>]*\s*>/gi; + return str.replace(reg, ""); + }, + _getUrl:function (isTryListen) { + var me = this; + var param = 'from=tiebasongwidget&url=&name=' + encodeURIComponent(me._removeHtml(selectedItem.title)) + '&artist=' + + encodeURIComponent(me._removeHtml(selectedItem.author)) + '&extra=' + + encodeURIComponent(me._removeHtml(selectedItem.album_title)) + + '&autoPlay='+isTryListen+'' + '&loop=true'; + return me.playerUrl + "?" + param; + }, + _getTryingElem:function () { + var s = $G('J_listPanel').getElementsByTagName('span'); + + for (var i = 0; i < s.length; i++) { + if (s[i].className == 'm-trying') + return s[i]; + } + return null; + }, + _buildMusicHtml:function (playerUrl) { + var html = ' 12) + return s.substring(0, 5) + '...'; + if (!s) s = " "; + return s; + }, + _rebuildData:function (data) { + var me = this, + newData = [], + d = me.pageSize, + itembox; + for (var i = 0; i < data.length; i++) { + if ((i + d) % d == 0) { + itembox = []; + newData.push(itembox) + } + itembox.push(data[i]); + } + return newData; + }, + _renderTemplate:function (data) { + var me = this; + if (data.length == 0)return '
          ' + lang.emptyTxt + '
          '; + data = me._rebuildData(data); + var s = [], p = [], t = []; + s.push('
          '); + p.push('
          '); + for (var i = 0, tmpList; tmpList = data[i++];) { + panels.push('panel' + i); + pages.push('page' + i); + if (i == 1) { + s.push('
          '); + if (data.length != 1) { + t.push('
          ' + (i ) + '
          '); + } + } else { + s.push('
          '); + t.push('
          ' + (i ) + '
          '); + } + s.push('
          '); + s.push('
          ' + lang.chapter + '' + lang.singer + + '' + lang.special + '' + lang.listenTest + '
          '); + for (var j = 0, tmpObj; tmpObj = tmpList[j++];) { + s.push(''); + } + s.push('
          '); + s.push('
          '); + } + t.reverse(); + p.push(t.join('')); + s.push('
          '); + p.push('
          '); + return s.join('') + p.join(''); + }, + exec:function () { + var me = this; + if (selectedItem == null) return; + $G('J_preview').innerHTML = ""; + editor.execCommand('music', { + url:me._getUrl(false), + width:400, + height:95 + }); + } + }; +})(); + + + diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/preview/preview.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/preview/preview.html new file mode 100644 index 000000000..f6b433bcf --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/preview/preview.html @@ -0,0 +1,40 @@ + + + + + + + + + + +
          + +
          + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/addimg.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/addimg.png new file mode 100644 index 000000000..03a87135b Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/addimg.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/brush.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/brush.png new file mode 100644 index 000000000..efa6fdb01 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/brush.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/delimg.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/delimg.png new file mode 100644 index 000000000..5a892e40a Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/delimg.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/delimgH.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/delimgH.png new file mode 100644 index 000000000..2f0c5c9de Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/delimgH.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/empty.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/empty.png new file mode 100644 index 000000000..037519625 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/empty.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/emptyH.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/emptyH.png new file mode 100644 index 000000000..838ca7231 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/emptyH.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/eraser.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/eraser.png new file mode 100644 index 000000000..63e87cecb Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/eraser.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/redo.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/redo.png new file mode 100644 index 000000000..12cd9bbef Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/redo.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/redoH.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/redoH.png new file mode 100644 index 000000000..d9f33d38a Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/redoH.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/scale.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/scale.png new file mode 100644 index 000000000..935a3f3e1 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/scale.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/scaleH.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/scaleH.png new file mode 100644 index 000000000..72e64a9d0 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/scaleH.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/size.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/size.png new file mode 100644 index 000000000..836684505 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/size.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/undo.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/undo.png new file mode 100644 index 000000000..084c7cc73 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/undo.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/undoH.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/undoH.png new file mode 100644 index 000000000..fde7eb3c2 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/images/undoH.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/scrawl.css b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/scrawl.css new file mode 100644 index 000000000..b18430dc5 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/scrawl.css @@ -0,0 +1,72 @@ +/*common +*/ +body{margin: 0;} +table{width:100%;} +table td{padding:2px 4px;vertical-align: middle;} +a{text-decoration: none;} +em{font-style: normal;} +.border_style1{border: 1px solid #ccc;border-radius: 5px;box-shadow:2px 2px 5px #d3d6da;} +/*module +*/ +.main{margin: 8px;overflow: hidden;} + +.hot{float:left;height:335px;} +.drawBoard{position: relative; cursor: crosshair;} +.brushBorad{position: absolute;left:0;top:0;z-index: 998;} +.picBoard{border: none;text-align: center;line-height: 300px;cursor: default;} +.operateBar{margin-top:10px;font-size:12px;text-align: center;} +.operateBar span{margin-left: 10px;} + +.drawToolbar{float:right;width:110px;height:300px;overflow: hidden;} +.colorBar{margin-top:10px;font-size: 12px;text-align: center;} +.colorBar a{display:block;width: 10px;height: 10px;border:1px solid #1006F1;border-radius: 3px; box-shadow:2px 2px 5px #d3d6da;opacity: 0.3} +.sectionBar{margin-top:15px;font-size: 12px;text-align: center;} +.sectionBar a{display:inline-block;width:10px;height:12px;color: #888;text-indent: -999px;opacity: 0.3} +.size1{background: url('images/size.png') 1px center no-repeat ;} +.size2{background: url('images/size.png') -10px center no-repeat;} +.size3{background: url('images/size.png') -22px center no-repeat;} +.size4{background: url('images/size.png') -35px center no-repeat;} + +.addImgH{position: relative;} +.addImgH_form{position: absolute;left: 18px;top: -1px;width: 75px;height: 21px;opacity: 0;cursor: pointer;} +.addImgH_form input{width: 100%;} +/*scrawl遮罩层 +*/ +.maskLayerNull{display: none;} +.maskLayer{position: absolute;top:0;left:0;width: 100%; height: 100%;opacity: 0.7; + background-color: #fff;text-align:center;font-weight:bold;line-height:300px;z-index: 1000;} +/*btn state +*/ +.previousStepH .icon{display: inline-block;width:16px;height:16px;background-image: url('images/undoH.png');cursor: pointer;} +.previousStepH .text{color:#888;cursor:pointer;} +.previousStep .icon{display: inline-block;width:16px;height:16px;background-image: url('images/undo.png');cursor:default;} +.previousStep .text{color:#ccc;cursor:default;} + +.nextStepH .icon{display: inline-block;width:16px;height:16px;background-image: url('images/redoH.png');cursor: pointer;} +.nextStepH .text{color:#888;cursor:pointer;} +.nextStep .icon{display: inline-block;width:16px;height:16px;background-image: url('images/redo.png');cursor:default;} +.nextStep .text{color:#ccc;cursor:default;} + +.clearBoardH .icon{display: inline-block;width:16px;height:16px;background-image: url('images/emptyH.png');cursor: pointer;} +.clearBoardH .text{color:#888;cursor:pointer;} +.clearBoard .icon{display: inline-block;width:16px;height:16px;background-image: url('images/empty.png');cursor:default;} +.clearBoard .text{color:#ccc;cursor:default;} + +.scaleBoardH .icon{display: inline-block;width:16px;height:16px;background-image: url('images/scaleH.png');cursor: pointer;} +.scaleBoardH .text{color:#888;cursor:pointer;} +.scaleBoard .icon{display: inline-block;width:16px;height:16px;background-image: url('images/scale.png');cursor:default;} +.scaleBoard .text{color:#ccc;cursor:default;} + +.removeImgH .icon{display: inline-block;width:16px;height:16px;background-image: url('images/delimgH.png');cursor: pointer;} +.removeImgH .text{color:#888;cursor:pointer;} +.removeImg .icon{display: inline-block;width:16px;height:16px;background-image: url('images/delimg.png');cursor:default;} +.removeImg .text{color:#ccc;cursor:default;} + +.addImgH .icon{vertical-align:top;display: inline-block;width:16px;height:16px;background-image: url('images/addimg.png')} +.addImgH .text{color:#888;cursor:pointer;} +/*icon +*/ +.brushIcon{display: inline-block;width:16px;height:16px;background-image: url('images/brush.png')} +.eraserIcon{display: inline-block;width:16px;height:16px;background-image: url('images/eraser.png')} + + diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/scrawl.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/scrawl.html new file mode 100644 index 000000000..9371abd7b --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/scrawl.html @@ -0,0 +1,95 @@ + + + + + + + + + + +
          +
          +
          + +
          +
          +
          + + + + + + + + + + + + + + + + +
          +
          +
          +
          +
          + + 1 + 3 + 5 + 7 +
          +
          + + 1 + 3 + 5 + 7 +
          +
          +
          + + +
          + +
          + +
          +
          +
          + + + + +
          +
          +
          +
          + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/scrawl.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/scrawl.js new file mode 100644 index 000000000..e0c005e75 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/scrawl/scrawl.js @@ -0,0 +1,671 @@ +/** + * Created with JetBrains PhpStorm. + * User: xuheng + * Date: 12-5-22 + * Time: 上午11:38 + * To change this template use File | Settings | File Templates. + */ +var scrawl = function (options) { + options && this.initOptions(options); +}; +(function () { + var canvas = $G("J_brushBoard"), + context = canvas.getContext('2d'), + drawStep = [], //undo redo存储 + drawStepIndex = 0; //undo redo指针 + + scrawl.prototype = { + isScrawl:false, //是否涂鸦 + brushWidth:-1, //画笔粗细 + brushColor:"", //画笔颜色 + + initOptions:function (options) { + var me = this; + me.originalState(options);//初始页面状态 + me._buildToolbarColor(options.colorList);//动态生成颜色选择集合 + + me._addBoardListener(options.saveNum);//添加画板处理 + me._addOPerateListener(options.saveNum);//添加undo redo clearBoard处理 + me._addColorBarListener();//添加颜色选择处理 + me._addBrushBarListener();//添加画笔大小处理 + me._addEraserBarListener();//添加橡皮大小处理 + me._addAddImgListener();//添加增添背景图片处理 + me._addRemoveImgListenter();//删除背景图片处理 + me._addScalePicListenter();//添加缩放处理 + me._addClearSelectionListenter();//添加清楚选中状态处理 + + me._originalColorSelect(options.drawBrushColor);//初始化颜色选中 + me._originalBrushSelect(options.drawBrushSize);//初始化画笔选中 + me._clearSelection();//清楚选中状态 + }, + + originalState:function (options) { + var me = this; + + me.brushWidth = options.drawBrushSize;//同步画笔粗细 + me.brushColor = options.drawBrushColor;//同步画笔颜色 + + context.lineWidth = me.brushWidth;//初始画笔大小 + context.strokeStyle = me.brushColor;//初始画笔颜色 + context.fillStyle = "transparent";//初始画布背景颜色 + context.lineCap = "round";//去除锯齿 + context.fill(); + }, + _buildToolbarColor:function (colorList) { + var tmp = null, arr = []; + arr.push(""); + for (var i = 0, color; color = colorList[i++];) { + if ((i - 1) % 5 == 0) { + if (i != 1) { + arr.push(""); + } + arr.push(""); + } + tmp = '#' + color; + arr.push(""); + } + arr.push("
          "); + $G("J_colorBar").innerHTML = arr.join(""); + }, + + _addBoardListener:function (saveNum) { + var me = this, + margin = 0, + startX = -1, + startY = -1, + isMouseDown = false, + isMouseMove = false, + isMouseUp = false, + buttonPress = 0, button, flag = ''; + + margin = parseInt(domUtils.getComputedStyle($G("J_wrap"), "margin-left")); + drawStep.push(context.getImageData(0, 0, context.canvas.width, context.canvas.height)); + drawStepIndex += 1; + + domUtils.on(canvas, ["mousedown", "mousemove", "mouseup", "mouseout"], function (e) { + button = browser.webkit ? e.which : buttonPress; + switch (e.type) { + case 'mousedown': + buttonPress = 1; + flag = 1; + isMouseDown = true; + isMouseUp = false; + isMouseMove = false; + me.isScrawl = true; + startX = e.clientX - margin;//10为外边距总和 + startY = e.clientY - margin; + context.beginPath(); + break; + case 'mousemove' : + if (!flag && button == 0) { + return; + } + if (!flag && button) { + startX = e.clientX - margin;//10为外边距总和 + startY = e.clientY - margin; + context.beginPath(); + flag = 1; + } + if (isMouseUp || !isMouseDown) { + return; + } + var endX = e.clientX - margin, + endY = e.clientY - margin; + + context.moveTo(startX, startY); + context.lineTo(endX, endY); + context.stroke(); + startX = endX; + startY = endY; + isMouseMove = true; + break; + case 'mouseup': + buttonPress = 0; + if (!isMouseDown)return; + if (!isMouseMove) { + context.arc(startX, startY, context.lineWidth, 0, Math.PI * 2, false); + context.fillStyle = context.strokeStyle; + context.fill(); + } + context.closePath(); + me._saveOPerate(saveNum); + isMouseDown = false; + isMouseMove = false; + isMouseUp = true; + startX = -1; + startY = -1; + break; + case 'mouseout': + flag = ''; + buttonPress = 0; + if (button == 1) return; + context.closePath(); + break; + } + }); + }, + _addOPerateListener:function (saveNum) { + var me = this; + domUtils.on($G("J_previousStep"), "click", function () { + if (drawStepIndex > 1) { + drawStepIndex -= 1; + context.clearRect(0, 0, context.canvas.width, context.canvas.height); + context.putImageData(drawStep[drawStepIndex - 1], 0, 0); + me.btn2Highlight("J_nextStep"); + drawStepIndex == 1 && me.btn2disable("J_previousStep"); + } + }); + domUtils.on($G("J_nextStep"), "click", function () { + if (drawStepIndex > 0 && drawStepIndex < drawStep.length) { + context.clearRect(0, 0, context.canvas.width, context.canvas.height); + context.putImageData(drawStep[drawStepIndex], 0, 0); + drawStepIndex += 1; + me.btn2Highlight("J_previousStep"); + drawStepIndex == drawStep.length && me.btn2disable("J_nextStep"); + } + }); + domUtils.on($G("J_clearBoard"), "click", function () { + context.clearRect(0, 0, context.canvas.width, context.canvas.height); + drawStep = []; + me._saveOPerate(saveNum); + drawStepIndex = 1; + me.isScrawl = false; + me.btn2disable("J_previousStep"); + me.btn2disable("J_nextStep"); + me.btn2disable("J_clearBoard"); + }); + }, + _addColorBarListener:function () { + var me = this; + domUtils.on($G("J_colorBar"), "click", function (e) { + var target = me.getTarget(e), + color = target.title; + if (!!color) { + me._addColorSelect(target); + + me.brushColor = color; + context.globalCompositeOperation = "source-over"; + context.lineWidth = me.brushWidth; + context.strokeStyle = color; + } + }); + }, + _addBrushBarListener:function () { + var me = this; + domUtils.on($G("J_brushBar"), "click", function (e) { + var target = me.getTarget(e), + size = browser.ie ? target.innerText : target.text; + if (!!size) { + me._addBESelect(target); + + context.globalCompositeOperation = "source-over"; + context.lineWidth = parseInt(size); + context.strokeStyle = me.brushColor; + me.brushWidth = context.lineWidth; + } + }); + }, + _addEraserBarListener:function () { + var me = this; + domUtils.on($G("J_eraserBar"), "click", function (e) { + var target = me.getTarget(e), + size = browser.ie ? target.innerText : target.text; + if (!!size) { + me._addBESelect(target); + + context.lineWidth = parseInt(size); + context.globalCompositeOperation = "destination-out"; + context.strokeStyle = "#FFF"; + } + }); + }, + _addAddImgListener:function () { + var file = $G("J_imgTxt"); + if (!window.FileReader) { + $G("J_addImg").style.display = 'none'; + $G("J_removeImg").style.display = 'none'; + $G("J_sacleBoard").style.display = 'none'; + } + domUtils.on(file, "change", function (e) { + var frm = file.parentNode; + addMaskLayer(lang.backgroundUploading); + + var target = e.target || e.srcElement, + reader = new FileReader(); + reader.onload = function(evt){ + var target = evt.target || evt.srcElement; + ue_callback(target.result, 'SUCCESS'); + }; + reader.readAsDataURL(target.files[0]); + frm.reset(); + }); + }, + _addRemoveImgListenter:function () { + var me = this; + domUtils.on($G("J_removeImg"), "click", function () { + $G("J_picBoard").innerHTML = ""; + me.btn2disable("J_removeImg"); + me.btn2disable("J_sacleBoard"); + }); + }, + _addScalePicListenter:function () { + domUtils.on($G("J_sacleBoard"), "click", function () { + var picBoard = $G("J_picBoard"), + scaleCon = $G("J_scaleCon"), + img = picBoard.children[0]; + + if (img) { + if (!scaleCon) { + picBoard.style.cssText = "position:relative;z-index:999;"+picBoard.style.cssText; + img.style.cssText = "position: absolute;top:" + (canvas.height - img.height) / 2 + "px;left:" + (canvas.width - img.width) / 2 + "px;"; + var scale = new ScaleBoy(); + picBoard.appendChild(scale.init()); + scale.startScale(img); + } else { + if (scaleCon.style.visibility == "visible") { + scaleCon.style.visibility = "hidden"; + picBoard.style.position = ""; + picBoard.style.zIndex = ""; + } else { + scaleCon.style.visibility = "visible"; + picBoard.style.cssText += "position:relative;z-index:999"; + } + } + } + }); + }, + _addClearSelectionListenter:function () { + var doc = document; + domUtils.on(doc, 'mousemove', function (e) { + if (browser.ie && browser.version < 11) + doc.selection.clear(); + else + window.getSelection().removeAllRanges(); + }); + }, + _clearSelection:function () { + var list = ["J_operateBar", "J_colorBar", "J_brushBar", "J_eraserBar", "J_picBoard"]; + for (var i = 0, group; group = list[i++];) { + domUtils.unSelectable($G(group)); + } + }, + + _saveOPerate:function (saveNum) { + var me = this; + if (drawStep.length <= saveNum) { + if(drawStepIndex"); + } + scale.innerHTML = arr.join(""); + return scale; + } + + var rect = [ + //[left, top, width, height] + [1, 1, -1, -1], + [0, 1, 0, -1], + [0, 1, 1, -1], + [1, 0, -1, 0], + [0, 0, 1, 0], + [1, 0, -1, 1], + [0, 0, 0, 1], + [0, 0, 1, 1] + ]; + ScaleBoy.prototype = { + init:function () { + _appendStyle(); + var me = this, + scale = me.dom = _getDom(); + + me.scaleMousemove.fp = me; + domUtils.on(scale, 'mousedown', function (e) { + var target = e.target || e.srcElement; + me.start = {x:e.clientX, y:e.clientY}; + if (target.className.indexOf('hand') != -1) { + me.dir = target.className.replace('hand', ''); + } + domUtils.on(document.body, 'mousemove', me.scaleMousemove); + e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true; + }); + domUtils.on(document.body, 'mouseup', function (e) { + if (me.start) { + domUtils.un(document.body, 'mousemove', me.scaleMousemove); + if (me.moved) { + me.updateScaledElement({position:{x:scale.style.left, y:scale.style.top}, size:{w:scale.style.width, h:scale.style.height}}); + } + delete me.start; + delete me.moved; + delete me.dir; + } + }); + return scale; + }, + startScale:function (objElement) { + var me = this, Idom = me.dom; + + Idom.style.cssText = 'visibility:visible;top:' + objElement.style.top + ';left:' + objElement.style.left + ';width:' + objElement.offsetWidth + 'px;height:' + objElement.offsetHeight + 'px;'; + me.scalingElement = objElement; + }, + updateScaledElement:function (objStyle) { + var cur = this.scalingElement, + pos = objStyle.position, + size = objStyle.size; + if (pos) { + typeof pos.x != 'undefined' && (cur.style.left = pos.x); + typeof pos.y != 'undefined' && (cur.style.top = pos.y); + } + if (size) { + size.w && (cur.style.width = size.w); + size.h && (cur.style.height = size.h); + } + }, + updateStyleByDir:function (dir, offset) { + var me = this, + dom = me.dom, tmp; + + rect['def'] = [1, 1, 0, 0]; + if (rect[dir][0] != 0) { + tmp = parseInt(dom.style.left) + offset.x; + dom.style.left = me._validScaledProp('left', tmp) + 'px'; + } + if (rect[dir][1] != 0) { + tmp = parseInt(dom.style.top) + offset.y; + dom.style.top = me._validScaledProp('top', tmp) + 'px'; + } + if (rect[dir][2] != 0) { + tmp = dom.clientWidth + rect[dir][2] * offset.x; + dom.style.width = me._validScaledProp('width', tmp) + 'px'; + } + if (rect[dir][3] != 0) { + tmp = dom.clientHeight + rect[dir][3] * offset.y; + dom.style.height = me._validScaledProp('height', tmp) + 'px'; + } + if (dir === 'def') { + me.updateScaledElement({position:{x:dom.style.left, y:dom.style.top}}); + } + }, + scaleMousemove:function (e) { + var me = arguments.callee.fp, + start = me.start, + dir = me.dir || 'def', + offset = {x:e.clientX - start.x, y:e.clientY - start.y}; + + me.updateStyleByDir(dir, offset); + arguments.callee.fp.start = {x:e.clientX, y:e.clientY}; + arguments.callee.fp.moved = 1; + }, + _validScaledProp:function (prop, value) { + var ele = this.dom, + wrap = $G("J_picBoard"); + + value = isNaN(value) ? 0 : value; + switch (prop) { + case 'left': + return value < 0 ? 0 : (value + ele.clientWidth) > wrap.clientWidth ? wrap.clientWidth - ele.clientWidth : value; + case 'top': + return value < 0 ? 0 : (value + ele.clientHeight) > wrap.clientHeight ? wrap.clientHeight - ele.clientHeight : value; + case 'width': + return value <= 0 ? 1 : (value + ele.offsetLeft) > wrap.clientWidth ? wrap.clientWidth - ele.offsetLeft : value; + case 'height': + return value <= 0 ? 1 : (value + ele.offsetTop) > wrap.clientHeight ? wrap.clientHeight - ele.offsetTop : value; + } + } + }; +})(); + +//后台回调 +function ue_callback(url, state) { + var doc = document, + picBorard = $G("J_picBoard"), + img = doc.createElement("img"); + + //图片缩放 + function scale(img, max, oWidth, oHeight) { + var width = 0, height = 0, percent, ow = img.width || oWidth, oh = img.height || oHeight; + if (ow > max || oh > max) { + if (ow >= oh) { + if (width = ow - max) { + percent = (width / ow).toFixed(2); + img.height = oh - oh * percent; + img.width = max; + } + } else { + if (height = oh - max) { + percent = (height / oh).toFixed(2); + img.width = ow - ow * percent; + img.height = max; + } + } + } + } + + //移除遮罩层 + removeMaskLayer(); + //状态响应 + if (state == "SUCCESS") { + picBorard.innerHTML = ""; + img.onload = function () { + scale(this, 300); + picBorard.appendChild(img); + + var obj = new scrawl(); + obj.btn2Highlight("J_removeImg"); + //trace 2457 + obj.btn2Highlight("J_sacleBoard"); + }; + img.src = url; + } else { + alert(state); + } +} +//去掉遮罩层 +function removeMaskLayer() { + var maskLayer = $G("J_maskLayer"); + maskLayer.className = "maskLayerNull"; + maskLayer.innerHTML = ""; + dialog.buttons[0].setDisabled(false); +} +//添加遮罩层 +function addMaskLayer(html) { + var maskLayer = $G("J_maskLayer"); + dialog.buttons[0].setDisabled(true); + maskLayer.className = "maskLayer"; + maskLayer.innerHTML = html; +} +//执行确认按钮方法 +function exec(scrawlObj) { + if (scrawlObj.isScrawl) { + addMaskLayer(lang.scrawlUpLoading); + var base64 = scrawlObj.getCanvasData(); + if (!!base64) { + var options = { + timeout:100000, + onsuccess:function (xhr) { + if (!scrawlObj.isCancelScrawl) { + var responseObj; + responseObj = eval("(" + xhr.responseText + ")"); + if (responseObj.state == "SUCCESS") { + var imgObj = {}, + url = editor.options.scrawlUrlPrefix + responseObj.url; + imgObj.src = url; + imgObj._src = url; + imgObj.alt = responseObj.original || ''; + imgObj.title = responseObj.title || ''; + editor.execCommand("insertImage", imgObj); + dialog.close(); + } else { + alert(responseObj.state); + } + + } + }, + onerror:function () { + alert(lang.imageError); + dialog.close(); + } + }; + options[editor.getOpt('scrawlFieldName')] = base64; + + var actionUrl = editor.getActionUrl(editor.getOpt('scrawlActionName')), + params = utils.serializeParam(editor.queryCommandValue('serverparam')) || '', + url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?':'&') + params); + ajax.request(url, options); + } + } else { + addMaskLayer(lang.noScarwl + "   "); + } +} + diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/searchreplace/searchreplace.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/searchreplace/searchreplace.html new file mode 100644 index 000000000..b91f19014 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/searchreplace/searchreplace.html @@ -0,0 +1,102 @@ + + + + + + + + + +
          + +
          +
          + + + + + + + + + + + + + + + + + + + + + + +
          :
          + +
          + + +
          +   +
          + +
          +
          +
          + + + + + + + + + + + + + + + + + + + + + + + + + + +
          :
          :
          + +
          + + + + +
          +   +
          + +
          +
          +
          +
          + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/searchreplace/searchreplace.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/searchreplace/searchreplace.js new file mode 100644 index 000000000..1b5285736 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/searchreplace/searchreplace.js @@ -0,0 +1,164 @@ +/** + * Created with JetBrains PhpStorm. + * User: xuheng + * Date: 12-9-26 + * Time: 下午12:29 + * To change this template use File | Settings | File Templates. + */ + +//清空上次查选的痕迹 +editor.firstForSR = 0; +editor.currentRangeForSR = null; +//给tab注册切换事件 +/** + * tab点击处理事件 + * @param tabHeads + * @param tabBodys + * @param obj + */ +function clickHandler( tabHeads,tabBodys,obj ) { + //head样式更改 + for ( var k = 0, len = tabHeads.length; k < len; k++ ) { + tabHeads[k].className = ""; + } + obj.className = "focus"; + //body显隐 + var tabSrc = obj.getAttribute( "tabSrc" ); + for ( var j = 0, length = tabBodys.length; j < length; j++ ) { + var body = tabBodys[j], + id = body.getAttribute( "id" ); + if ( id != tabSrc ) { + body.style.zIndex = 1; + } else { + body.style.zIndex = 200; + } + } + +} + +/** + * TAB切换 + * @param tabParentId tab的父节点ID或者对象本身 + */ +function switchTab( tabParentId ) { + var tabElements = $G( tabParentId ).children, + tabHeads = tabElements[0].children, + tabBodys = tabElements[1].children; + + for ( var i = 0, length = tabHeads.length; i < length; i++ ) { + var head = tabHeads[i]; + if ( head.className === "focus" )clickHandler(tabHeads,tabBodys, head ); + head.onclick = function () { + clickHandler(tabHeads,tabBodys,this); + } + } +} +$G('searchtab').onmousedown = function(){ + $G('search-msg').innerHTML = ''; + $G('replace-msg').innerHTML = '' +} +//是否区分大小写 +function getMatchCase(id) { + return $G(id).checked ? true : false; +} +//查找 +$G("nextFindBtn").onclick = function (txt, dir, mcase) { + var findtxt = $G("findtxt").value, obj; + if (!findtxt) { + return false; + } + obj = { + searchStr:findtxt, + dir:1, + casesensitive:getMatchCase("matchCase") + }; + if (!frCommond(obj)) { + var bk = editor.selection.getRange().createBookmark(); + $G('search-msg').innerHTML = lang.getEnd; + editor.selection.getRange().moveToBookmark(bk).select(); + + + } +}; +$G("nextReplaceBtn").onclick = function (txt, dir, mcase) { + var findtxt = $G("findtxt1").value, obj; + if (!findtxt) { + return false; + } + obj = { + searchStr:findtxt, + dir:1, + casesensitive:getMatchCase("matchCase1") + }; + frCommond(obj); +}; +$G("preFindBtn").onclick = function (txt, dir, mcase) { + var findtxt = $G("findtxt").value, obj; + if (!findtxt) { + return false; + } + obj = { + searchStr:findtxt, + dir:-1, + casesensitive:getMatchCase("matchCase") + }; + if (!frCommond(obj)) { + $G('search-msg').innerHTML = lang.getStart; + } +}; +$G("preReplaceBtn").onclick = function (txt, dir, mcase) { + var findtxt = $G("findtxt1").value, obj; + if (!findtxt) { + return false; + } + obj = { + searchStr:findtxt, + dir:-1, + casesensitive:getMatchCase("matchCase1") + }; + frCommond(obj); +}; +//替换 +$G("repalceBtn").onclick = function () { + var findtxt = $G("findtxt1").value.replace(/^\s|\s$/g, ""), obj, + replacetxt = $G("replacetxt").value.replace(/^\s|\s$/g, ""); + if (!findtxt) { + return false; + } + if (findtxt == replacetxt || (!getMatchCase("matchCase1") && findtxt.toLowerCase() == replacetxt.toLowerCase())) { + return false; + } + obj = { + searchStr:findtxt, + dir:1, + casesensitive:getMatchCase("matchCase1"), + replaceStr:replacetxt + }; + frCommond(obj); +}; +//全部替换 +$G("repalceAllBtn").onclick = function () { + var findtxt = $G("findtxt1").value.replace(/^\s|\s$/g, ""), obj, + replacetxt = $G("replacetxt").value.replace(/^\s|\s$/g, ""); + if (!findtxt) { + return false; + } + if (findtxt == replacetxt || (!getMatchCase("matchCase1") && findtxt.toLowerCase() == replacetxt.toLowerCase())) { + return false; + } + obj = { + searchStr:findtxt, + casesensitive:getMatchCase("matchCase1"), + replaceStr:replacetxt, + all:true + }; + var num = frCommond(obj); + if (num) { + $G('replace-msg').innerHTML = lang.countMsg.replace("{#count}", num); + } +}; +//执行 +var frCommond = function (obj) { + return editor.execCommand("searchreplace", obj); +}; +switchTab("searchtab"); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/snapscreen/snapscreen.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/snapscreen/snapscreen.html new file mode 100644 index 000000000..cf8209ee7 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/snapscreen/snapscreen.html @@ -0,0 +1,58 @@ + + + + + + + + + +
          +

          +
          +
          +
          +
          +
          +
          + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/spechars/spechars.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/spechars/spechars.html new file mode 100644 index 000000000..0b5c416f8 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/spechars/spechars.html @@ -0,0 +1,21 @@ + + + + + + + + + +
          +
          +
          + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/spechars/spechars.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/spechars/spechars.js new file mode 100644 index 000000000..f4c155e15 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/spechars/spechars.js @@ -0,0 +1,57 @@ +/** + * Created with JetBrains PhpStorm. + * User: xuheng + * Date: 12-9-26 + * Time: 下午1:09 + * To change this template use File | Settings | File Templates. + */ +var charsContent = [ + { name:"tsfh", title:lang.tsfh, content:toArray("、,。,·,ˉ,ˇ,¨,〃,々,—,~,‖,…,‘,’,“,”,〔,〕,〈,〉,《,》,「,」,『,』,〖,〗,【,】,±,×,÷,∶,∧,∨,∑,∏,∪,∩,∈,∷,√,⊥,∥,∠,⌒,⊙,∫,∮,≡,≌,≈,∽,∝,≠,≮,≯,≤,≥,∞,∵,∴,♂,♀,°,′,″,℃,$,¤,¢,£,‰,§,№,☆,★,○,●,◎,◇,◆,□,■,△,▲,※,→,←,↑,↓,〓,〡,〢,〣,〤,〥,〦,〧,〨,〩,㊣,㎎,㎏,㎜,㎝,㎞,㎡,㏄,㏎,㏑,㏒,㏕,︰,¬,¦,℡,ˊ,ˋ,˙,–,―,‥,‵,℅,℉,↖,↗,↘,↙,∕,∟,∣,≒,≦,≧,⊿,═,║,╒,╓,╔,╕,╖,╗,╘,╙,╚,╛,╜,╝,╞,╟,╠,╡,╢,╣,╤,╥,╦,╧,╨,╩,╪,╫,╬,╭,╮,╯,╰,╱,╲,╳,▁,▂,▃,▄,▅,▆,▇,�,█,▉,▊,▋,▌,▍,▎,▏,▓,▔,▕,▼,▽,◢,◣,◤,◥,☉,⊕,〒,〝,〞")}, + { name:"lmsz", title:lang.lmsz, content:toArray("ⅰ,ⅱ,ⅲ,ⅳ,ⅴ,ⅵ,ⅶ,ⅷ,ⅸ,ⅹ,Ⅰ,Ⅱ,Ⅲ,Ⅳ,Ⅴ,Ⅵ,Ⅶ,Ⅷ,Ⅸ,Ⅹ,Ⅺ,Ⅻ")}, + { name:"szfh", title:lang.szfh, content:toArray("⒈,⒉,⒊,⒋,⒌,⒍,⒎,⒏,⒐,⒑,⒒,⒓,⒔,⒕,⒖,⒗,⒘,⒙,⒚,⒛,⑴,⑵,⑶,⑷,⑸,⑹,⑺,⑻,⑼,⑽,⑾,⑿,⒀,⒁,⒂,⒃,⒄,⒅,⒆,⒇,①,②,③,④,⑤,⑥,⑦,⑧,⑨,⑩,㈠,㈡,㈢,㈣,㈤,㈥,㈦,㈧,㈨,㈩")}, + { name:"rwfh", title:lang.rwfh, content:toArray("ぁ,あ,ぃ,い,ぅ,う,ぇ,え,ぉ,お,か,が,き,ぎ,く,ぐ,け,げ,こ,ご,さ,ざ,し,じ,す,ず,せ,ぜ,そ,ぞ,た,だ,ち,ぢ,っ,つ,づ,て,で,と,ど,な,に,ぬ,ね,の,は,ば,ぱ,ひ,び,ぴ,ふ,ぶ,ぷ,へ,べ,ぺ,ほ,ぼ,ぽ,ま,み,む,め,も,ゃ,や,ゅ,ゆ,ょ,よ,ら,り,る,れ,ろ,ゎ,わ,ゐ,ゑ,を,ん,ァ,ア,ィ,イ,ゥ,ウ,ェ,エ,ォ,オ,カ,ガ,キ,ギ,ク,グ,ケ,ゲ,コ,ゴ,サ,ザ,シ,ジ,ス,ズ,セ,ゼ,ソ,ゾ,タ,ダ,チ,ヂ,ッ,ツ,ヅ,テ,デ,ト,ド,ナ,ニ,ヌ,ネ,ノ,ハ,バ,パ,ヒ,ビ,ピ,フ,ブ,プ,ヘ,ベ,ペ,ホ,ボ,ポ,マ,ミ,ム,メ,モ,ャ,ヤ,ュ,ユ,ョ,ヨ,ラ,リ,ル,レ,ロ,ヮ,ワ,ヰ,ヱ,ヲ,ン,ヴ,ヵ,ヶ")}, + { name:"xlzm", title:lang.xlzm, content:toArray("Α,Β,Γ,Δ,Ε,Ζ,Η,Θ,Ι,Κ,Λ,Μ,Ν,Ξ,Ο,Π,Ρ,Σ,Τ,Υ,Φ,Χ,Ψ,Ω,α,β,γ,δ,ε,ζ,η,θ,ι,κ,λ,μ,ν,ξ,ο,π,ρ,σ,τ,υ,φ,χ,ψ,ω")}, + { name:"ewzm", title:lang.ewzm, content:toArray("А,Б,В,Г,Д,Е,Ё,Ж,З,И,Й,К,Л,М,Н,О,П,Р,С,Т,У,Ф,Х,Ц,Ч,Ш,Щ,Ъ,Ы,Ь,Э,Ю,Я,а,б,в,г,д,е,ё,ж,з,и,й,к,л,м,н,о,п,р,с,т,у,ф,х,ц,ч,ш,щ,ъ,ы,ь,э,ю,я")}, + { name:"pyzm", title:lang.pyzm, content:toArray("ā,á,ǎ,à,ē,é,ě,è,ī,í,ǐ,ì,ō,ó,ǒ,ò,ū,ú,ǔ,ù,ǖ,ǘ,ǚ,ǜ,ü")}, + { name:"yyyb", title:lang.yyyb, content:toArray("i:,i,e,æ,ʌ,ə:,ə,u:,u,ɔ:,ɔ,a:,ei,ai,ɔi,əu,au,iə,εə,uə,p,t,k,b,d,g,f,s,ʃ,θ,h,v,z,ʒ,ð,tʃ,tr,ts,dʒ,dr,dz,m,n,ŋ,l,r,w,j,")}, + { name:"zyzf", title:lang.zyzf, content:toArray("ㄅ,ㄆ,ㄇ,ㄈ,ㄉ,ㄊ,ㄋ,ㄌ,ㄍ,ㄎ,ㄏ,ㄐ,ㄑ,ㄒ,ㄓ,ㄔ,ㄕ,ㄖ,ㄗ,ㄘ,ㄙ,ㄚ,ㄛ,ㄜ,ㄝ,ㄞ,ㄟ,ㄠ,ㄡ,ㄢ,ㄣ,ㄤ,ㄥ,ㄦ,ㄧ,ㄨ")} +]; +(function createTab(content) { + for (var i = 0, ci; ci = content[i++];) { + var span = document.createElement("span"); + span.setAttribute("tabSrc", ci.name); + span.innerHTML = ci.title; + if (i == 1)span.className = "focus"; + domUtils.on(span, "click", function () { + var tmps = $G("tabHeads").children; + for (var k = 0, sk; sk = tmps[k++];) { + sk.className = ""; + } + tmps = $G("tabBodys").children; + for (var k = 0, sk; sk = tmps[k++];) { + sk.style.display = "none"; + } + this.className = "focus"; + $G(this.getAttribute("tabSrc")).style.display = ""; + }); + $G("tabHeads").appendChild(span); + domUtils.insertAfter(span, document.createTextNode("\n")); + var div = document.createElement("div"); + div.id = ci.name; + div.style.display = (i == 1) ? "" : "none"; + var cons = ci.content; + for (var j = 0, con; con = cons[j++];) { + var charSpan = document.createElement("span"); + charSpan.innerHTML = con; + domUtils.on(charSpan, "click", function () { + editor.execCommand("insertHTML", this.innerHTML); + dialog.close(); + }); + div.appendChild(charSpan); + } + $G("tabBodys").appendChild(div); + } +})(charsContent); +function toArray(str) { + return str.split(","); +} diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/dragicon.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/dragicon.png new file mode 100644 index 000000000..f26203bf3 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/dragicon.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/edittable.css b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/edittable.css new file mode 100644 index 000000000..c6f9396c9 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/edittable.css @@ -0,0 +1,84 @@ +body{ + overflow: hidden; + width: 540px; +} +.wrapper { + margin: 10px auto 0; + font-size: 12px; + overflow: hidden; + width: 520px; + height: 315px; +} + +.clear { + clear: both; +} + +.wrapper .left { + float: left; + margin-left: 10px;; +} + +.wrapper .right { + float: right; + border-left: 2px dotted #EDEDED; + padding-left: 15px; +} + +.section { + margin-bottom: 15px; + width: 240px; + overflow: hidden; +} + +.section h3 { + font-weight: bold; + padding: 5px 0; + margin-bottom: 10px; + border-bottom: 1px solid #EDEDED; + font-size: 12px; +} + +.section ul { + list-style: none; + overflow: hidden; + clear: both; + +} + +.section li { + float: left; + width: 120px;; +} + +.section .tone { + width: 80px;; +} + +.section .preview { + width: 220px; +} + +.section .preview table { + text-align: center; + vertical-align: middle; + color: #666; +} + +.section .preview caption { + font-weight: bold; +} + +.section .preview td { + border-width: 1px; + border-style: solid; + height: 22px; +} + +.section .preview th { + border-style: solid; + border-color: #DDD; + border-width: 2px 1px 1px 1px; + height: 22px; + background-color: #F7F7F7; +} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/edittable.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/edittable.html new file mode 100644 index 000000000..3c412fb82 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/edittable.html @@ -0,0 +1,64 @@ + + + + + + + + +
          +
          +
          +

          +
            +
          • + +
          • +
          • + +
          • +
          +
            +
          • + +
          • +
          • + +
          • +
          +
          +
          +
          +

          +
            +
          • + +
          • +
          • + +
          • +
          +
          +
          +
          +

          +
            +
          • + + +
          • +
          +
          +
          +
          +
          +
          +

          +
          +
          +
          +
          +
          + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/edittable.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/edittable.js new file mode 100644 index 000000000..11dbee7c5 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/edittable.js @@ -0,0 +1,237 @@ +/** + * Created with JetBrains PhpStorm. + * User: xuheng + * Date: 12-12-19 + * Time: 下午4:55 + * To change this template use File | Settings | File Templates. + */ +(function () { + var title = $G("J_title"), + titleCol = $G("J_titleCol"), + caption = $G("J_caption"), + sorttable = $G("J_sorttable"), + autoSizeContent = $G("J_autoSizeContent"), + autoSizePage = $G("J_autoSizePage"), + tone = $G("J_tone"), + me, + preview = $G("J_preview"); + + var editTable = function () { + me = this; + me.init(); + }; + editTable.prototype = { + init:function () { + var colorPiker = new UE.ui.ColorPicker({ + editor:editor + }), + colorPop = new UE.ui.Popup({ + editor:editor, + content:colorPiker + }); + + title.checked = editor.queryCommandState("inserttitle") == -1; + titleCol.checked = editor.queryCommandState("inserttitlecol") == -1; + caption.checked = editor.queryCommandState("insertcaption") == -1; + sorttable.checked = editor.queryCommandState("enablesort") == 1; + + var enablesortState = editor.queryCommandState("enablesort"), + disablesortState = editor.queryCommandState("disablesort"); + + sorttable.checked = !!(enablesortState < 0 && disablesortState >=0); + sorttable.disabled = !!(enablesortState < 0 && disablesortState < 0); + sorttable.title = enablesortState < 0 && disablesortState < 0 ? lang.errorMsg:''; + + me.createTable(title.checked, titleCol.checked, caption.checked); + me.setAutoSize(); + me.setColor(me.getColor()); + + domUtils.on(title, "click", me.titleHanler); + domUtils.on(titleCol, "click", me.titleColHanler); + domUtils.on(caption, "click", me.captionHanler); + domUtils.on(sorttable, "click", me.sorttableHanler); + domUtils.on(autoSizeContent, "click", me.autoSizeContentHanler); + domUtils.on(autoSizePage, "click", me.autoSizePageHanler); + + domUtils.on(tone, "click", function () { + colorPop.showAnchor(tone); + }); + domUtils.on(document, 'mousedown', function () { + colorPop.hide(); + }); + colorPiker.addListener("pickcolor", function () { + me.setColor(arguments[1]); + colorPop.hide(); + }); + colorPiker.addListener("picknocolor", function () { + me.setColor(""); + colorPop.hide(); + }); + }, + + createTable:function (hasTitle, hasTitleCol, hasCaption) { + var arr = [], + sortSpan = '^'; + arr.push(""); + if (hasCaption) { + arr.push("") + } + if (hasTitle) { + arr.push(""); + if(hasTitleCol) { arr.push(""); } + for (var j = 0; j < 5; j++) { + arr.push(""); + } + arr.push(""); + } + for (var i = 0; i < 6; i++) { + arr.push(""); + if(hasTitleCol) { arr.push("") } + for (var k = 0; k < 5; k++) { + arr.push("") + } + arr.push(""); + } + arr.push("
          " + lang.captionName + "
          " + lang.titleName + "" + lang.titleName + "
          " + lang.titleName + "" + lang.cellsName + "
          "); + preview.innerHTML = arr.join(""); + this.updateSortSpan(); + }, + titleHanler:function () { + var example = $G("J_example"), + frg=document.createDocumentFragment(), + color = domUtils.getComputedStyle(domUtils.getElementsByTagName(example, "td")[0], "border-color"), + colCount = example.rows[0].children.length; + + if (title.checked) { + example.insertRow(0); + for (var i = 0, node; i < colCount; i++) { + node = document.createElement("th"); + node.innerHTML = lang.titleName; + frg.appendChild(node); + } + example.rows[0].appendChild(frg); + + } else { + domUtils.remove(example.rows[0]); + } + me.setColor(color); + me.updateSortSpan(); + }, + titleColHanler:function () { + var example = $G("J_example"), + color = domUtils.getComputedStyle(domUtils.getElementsByTagName(example, "td")[0], "border-color"), + colArr = example.rows, + colCount = colArr.length; + + if (titleCol.checked) { + for (var i = 0, node; i < colCount; i++) { + node = document.createElement("th"); + node.innerHTML = lang.titleName; + colArr[i].insertBefore(node, colArr[i].children[0]); + } + } else { + for (var i = 0; i < colCount; i++) { + domUtils.remove(colArr[i].children[0]); + } + } + me.setColor(color); + me.updateSortSpan(); + }, + captionHanler:function () { + var example = $G("J_example"); + if (caption.checked) { + var row = document.createElement('caption'); + row.innerHTML = lang.captionName; + example.insertBefore(row, example.firstChild); + } else { + domUtils.remove(domUtils.getElementsByTagName(example, 'caption')[0]); + } + }, + sorttableHanler:function(){ + me.updateSortSpan(); + }, + autoSizeContentHanler:function () { + var example = $G("J_example"); + example.removeAttribute("width"); + }, + autoSizePageHanler:function () { + var example = $G("J_example"); + var tds = example.getElementsByTagName(example, "td"); + utils.each(tds, function (td) { + td.removeAttribute("width"); + }); + example.setAttribute('width', '100%'); + }, + updateSortSpan: function(){ + var example = $G("J_example"), + row = example.rows[0]; + + var spans = domUtils.getElementsByTagName(example,"span"); + utils.each(spans,function(span){ + span.parentNode.removeChild(span); + }); + if (sorttable.checked) { + utils.each(row.cells, function(cell, i){ + var span = document.createElement("span"); + span.innerHTML = "^"; + cell.appendChild(span); + }); + } + }, + getColor:function () { + var start = editor.selection.getStart(), color, + cell = domUtils.findParentByTagName(start, ["td", "th", "caption"], true); + color = cell && domUtils.getComputedStyle(cell, "border-color"); + if (!color) color = "#DDDDDD"; + return color; + }, + setColor:function (color) { + var example = $G("J_example"), + arr = domUtils.getElementsByTagName(example, "td").concat( + domUtils.getElementsByTagName(example, "th"), + domUtils.getElementsByTagName(example, "caption") + ); + + tone.value = color; + utils.each(arr, function (node) { + node.style.borderColor = color; + }); + + }, + setAutoSize:function () { + var me = this; + autoSizePage.checked = true; + me.autoSizePageHanler(); + } + }; + + new editTable; + + dialog.onok = function () { + editor.__hasEnterExecCommand = true; + + var checks = { + title:"inserttitle deletetitle", + titleCol:"inserttitlecol deletetitlecol", + caption:"insertcaption deletecaption", + sorttable:"enablesort disablesort" + }; + editor.fireEvent('saveScene'); + for(var i in checks){ + var cmds = checks[i].split(" "), + input = $G("J_" + i); + if(input["checked"]){ + editor.queryCommandState(cmds[0])!=-1 &&editor.execCommand(cmds[0]); + }else{ + editor.queryCommandState(cmds[1])!=-1 &&editor.execCommand(cmds[1]); + } + } + + editor.execCommand("edittable", tone.value); + autoSizeContent.checked ?editor.execCommand('adaptbytext') : ""; + autoSizePage.checked ? editor.execCommand("adaptbywindow") : ""; + editor.fireEvent('saveScene'); + + editor.__hasEnterExecCommand = false; + }; +})(); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/edittd.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/edittd.html new file mode 100644 index 000000000..49a52f719 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/edittd.html @@ -0,0 +1,61 @@ + + + + + + + + +
          + + +
          + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/edittip.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/edittip.html new file mode 100644 index 000000000..954f7bb66 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/table/edittip.html @@ -0,0 +1,33 @@ + + + + 表格删除提示 + + + + +
          +
          + +
          +
          + +
          +
          + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/bg.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/bg.png new file mode 100644 index 000000000..580be0a01 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/bg.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/center_focus.jpg b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/center_focus.jpg new file mode 100644 index 000000000..262b02916 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/center_focus.jpg differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/file-icons.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/file-icons.gif new file mode 100644 index 000000000..d8c02c27e Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/file-icons.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/file-icons.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/file-icons.png new file mode 100644 index 000000000..3ff82c8c4 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/file-icons.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/icons.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/icons.gif new file mode 100644 index 000000000..78459dea7 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/icons.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/icons.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/icons.png new file mode 100644 index 000000000..12e470016 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/icons.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/image.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/image.png new file mode 100644 index 000000000..19699f6a9 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/image.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/left_focus.jpg b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/left_focus.jpg new file mode 100644 index 000000000..7886d276d Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/left_focus.jpg differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/none_focus.jpg b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/none_focus.jpg new file mode 100644 index 000000000..7c768dcb4 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/none_focus.jpg differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/progress.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/progress.png new file mode 100644 index 000000000..717c4865c Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/progress.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/right_focus.jpg b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/right_focus.jpg new file mode 100644 index 000000000..173e10d2d Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/right_focus.jpg differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/success.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/success.gif new file mode 100644 index 000000000..8d4f3112b Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/success.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/success.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/success.png new file mode 100644 index 000000000..94f968dc8 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/images/success.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/video.css b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/video.css new file mode 100644 index 000000000..5870e7a15 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/video.css @@ -0,0 +1,635 @@ +@charset "utf-8"; +.wrapper{ width: 570px;_width:575px;margin: 10px auto; zoom:1;position: relative} +.tabbody{height: 335px;} +.tabbody .panel { + position: absolute; + width: 0; + height: 0; + background: #fff; + overflow: hidden; + display: none; +} +.tabbody .panel.focus { + width: 100%; + height: 335px; + display: block; +} + +.tabbody .panel table td{vertical-align: middle;} +#videoUrl { + width: 490px; + height: 21px; + line-height: 21px; + margin: 8px 5px; + background: #FFF; + border: 1px solid #d7d7d7; +} +#videoSearchTxt{margin-left:15px;background: #FFF;width:200px;height:21px;line-height:21px;border: 1px solid #d7d7d7;} +#searchList{width: 570px;overflow: auto;zoom:1;height: 270px;} +#searchList div{float: left;width: 120px;height: 135px;margin: 5px 15px;} +#searchList img{margin: 2px 8px;cursor: pointer;border: 2px solid #fff} /*不用缩略图*/ +#searchList p{margin-left: 10px;} +#videoType{ + width: 65px; + height: 23px; + line-height: 22px; + border: 1px solid #d7d7d7; +} +#videoSearchBtn,#videoSearchReset{ + /*width: 80px;*/ + height: 25px; + line-height: 25px; + background: #eee; + border: 1px solid #d7d7d7; + cursor: pointer; + padding: 0 5px; +} + + + +#preview{position: relative;width: 420px;padding:0;overflow: hidden; margin-left: 10px; _margin-left:5px; height: 280px;background-color: #ddd;float: left} +#preview .previewMsg {position:absolute;top:0;margin:0;padding:0;height:280px;width:100%;background-color: #666;} +#preview .previewMsg span{display:block;margin: 125px auto 0 auto;text-align:center;font-size:18px;color:#fff;} +#preview .previewVideo {position:absolute;top:0;margin:0;padding:0;height:280px;width:100%;} +.edui-video-wrapper fieldset{ + border: 1px solid #ddd; + padding-left: 5px; + margin-bottom: 20px; + padding-bottom: 5px; + width: 115px; +} + +#videoInfo {width: 120px;float: left;margin-left: 10px;_margin-left:7px;} +fieldset{ + border: 1px solid #ddd; + padding-left: 5px; + margin-bottom: 20px; + padding-bottom: 5px; + width: 115px; +} +fieldset legend{font-weight: bold;} +fieldset p{line-height: 30px;} +fieldset input.txt{ + width: 65px; + height: 21px; + line-height: 21px; + margin: 8px 5px; + background: #FFF; + border: 1px solid #d7d7d7; +} +label.url{font-weight: bold;margin-left: 5px;color: #06c;} +#videoFloat div{cursor:pointer;opacity: 0.5;filter: alpha(opacity = 50);margin:9px;_margin:5px;width:38px;height:36px;float:left;} +#videoFloat .focus{opacity: 1;filter: alpha(opacity = 100)} +span.view{display: inline-block;width: 30px;float: right;cursor: pointer;color: blue} + + + + +/* upload video */ +.tabbody #upload.panel { + width: 0; + height: 0; + overflow: hidden; + position: absolute !important; + clip: rect(1px, 1px, 1px, 1px); + background: #fff; + display: block; +} +.tabbody #upload.panel.focus { + width: 100%; + height: 335px; + display: block; + clip: auto; +} +#upload_alignment div{cursor:pointer;opacity: 0.5;filter: alpha(opacity = 50);margin:9px;_margin:5px;width:38px;height:36px;float:left;} +#upload_alignment .focus{opacity: 1;filter: alpha(opacity = 100)} +#upload_left { width:427px; float:left; } +#upload_left .controller { height: 30px; clear: both; } +#uploadVideoInfo{margin-top:10px;float:right;padding-right:8px;} + +#upload .queueList { + margin: 0; +} + +#upload p { + margin: 0; +} + +.element-invisible { + width: 0 !important; + height: 0 !important; + border: 0; + padding: 0; + margin: 0; + overflow: hidden; + position: absolute !important; + clip: rect(1px, 1px, 1px, 1px); +} + +#upload .placeholder { + margin: 10px; + margin-right:0; + border: 2px dashed #e6e6e6; + *border: 0px dashed #e6e6e6; + height: 161px; + padding-top: 150px; + text-align: center; + width: 97%; + float: left; + background: url(./images/image.png) center 70px no-repeat; + color: #cccccc; + font-size: 18px; + position: relative; + top:0; + *margin-left: 0; + *left: 10px; +} + +#upload .placeholder .webuploader-pick { + font-size: 18px; + background: #00b7ee; + border-radius: 3px; + line-height: 44px; + padding: 0 30px; + *width: 120px; + color: #fff; + display: inline-block; + margin: 0 auto 20px auto; + cursor: pointer; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); +} + +#upload .placeholder .webuploader-pick-hover { + background: #00a2d4; +} + + +#filePickerContainer { + text-align: center; +} + +#upload .placeholder .flashTip { + color: #666666; + font-size: 12px; + position: absolute; + width: 100%; + text-align: center; + bottom: 20px; +} + +#upload .placeholder .flashTip a { + color: #0785d1; + text-decoration: none; +} + +#upload .placeholder .flashTip a:hover { + text-decoration: underline; +} + +#upload .placeholder.webuploader-dnd-over { + border-color: #999999; +} + +#upload .filelist { + list-style: none; + margin: 0; + padding: 0; + overflow-x: hidden; + overflow-y: auto; + position: relative; + height: 285px; +} + +#upload .filelist:after { + content: ''; + display: block; + width: 0; + height: 0; + overflow: hidden; + clear: both; +} + +#upload .filelist li { + width: 113px; + height: 113px; + background: url(./images/bg.png); + text-align: center; + margin: 15px 0 0 20px; + *margin: 15px 0 0 15px; + position: relative; + display: block; + float: left; + overflow: hidden; + font-size: 12px; +} + +#upload .filelist li p.log { + position: relative; + top: -45px; +} + +#upload .filelist li p.title { + position: absolute; + top: 0; + left: 0; + width: 100%; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; + top: 5px; + text-indent: 5px; + text-align: left; +} + +#upload .filelist li p.progress { + position: absolute; + width: 100%; + bottom: 0; + left: 0; + height: 8px; + overflow: hidden; + z-index: 50; + margin: 0; + border-radius: 0; + background: none; + -webkit-box-shadow: 0 0 0; +} + +#upload .filelist li p.progress span { + display: none; + overflow: hidden; + width: 0; + height: 100%; + background: #1483d8 url(./images/progress.png) repeat-x; + + -webit-transition: width 200ms linear; + -moz-transition: width 200ms linear; + -o-transition: width 200ms linear; + -ms-transition: width 200ms linear; + transition: width 200ms linear; + + -webkit-animation: progressmove 2s linear infinite; + -moz-animation: progressmove 2s linear infinite; + -o-animation: progressmove 2s linear infinite; + -ms-animation: progressmove 2s linear infinite; + animation: progressmove 2s linear infinite; + + -webkit-transform: translateZ(0); +} + +@-webkit-keyframes progressmove { + 0% { + background-position: 0 0; + } + 100% { + background-position: 17px 0; + } +} + +@-moz-keyframes progressmove { + 0% { + background-position: 0 0; + } + 100% { + background-position: 17px 0; + } +} + +@keyframes progressmove { + 0% { + background-position: 0 0; + } + 100% { + background-position: 17px 0; + } +} + +#upload .filelist li p.imgWrap { + position: relative; + z-index: 2; + line-height: 113px; + vertical-align: middle; + overflow: hidden; + width: 113px; + height: 113px; + + -webkit-transform-origin: 50% 50%; + -moz-transform-origin: 50% 50%; + -o-transform-origin: 50% 50%; + -ms-transform-origin: 50% 50%; + transform-origin: 50% 50%; + + -webit-transition: 200ms ease-out; + -moz-transition: 200ms ease-out; + -o-transition: 200ms ease-out; + -ms-transition: 200ms ease-out; + transition: 200ms ease-out; +} +#upload .filelist li p.imgWrap.notimage { + margin-top: 0; + width: 111px; + height: 111px; + border: 1px #eeeeee solid; +} +#upload .filelist li p.imgWrap.notimage i.file-preview { + margin-top: 15px; +} + +#upload .filelist li img { + width: 100%; +} + +#upload .filelist li p.error { + background: #f43838; + color: #fff; + position: absolute; + bottom: 0; + left: 0; + height: 28px; + line-height: 28px; + width: 100%; + z-index: 100; + display:none; +} + +#upload .filelist li .success { + display: block; + position: absolute; + left: 0; + bottom: 0; + height: 40px; + width: 100%; + z-index: 200; + background: url(./images/success.png) no-repeat right bottom; + background-image: url(./images/success.gif) \9; +} + +#upload .filelist li.filePickerBlock { + width: 113px; + height: 113px; + background: url(./images/image.png) no-repeat center 12px; + border: 1px solid #eeeeee; + border-radius: 0; +} +#upload .filelist li.filePickerBlock div.webuploader-pick { + width: 100%; + height: 100%; + margin: 0; + padding: 0; + opacity: 0; + background: none; + font-size: 0; +} + +#upload .filelist div.file-panel { + position: absolute; + height: 0; + filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#80000000', endColorstr='#80000000') \0; + background: rgba(0, 0, 0, 0.5); + width: 100%; + top: 0; + left: 0; + overflow: hidden; + z-index: 300; +} + +#upload .filelist div.file-panel span { + width: 24px; + height: 24px; + display: inline; + float: right; + text-indent: -9999px; + overflow: hidden; + background: url(./images/icons.png) no-repeat; + background: url(./images/icons.gif) no-repeat \9; + margin: 5px 1px 1px; + cursor: pointer; + -webkit-tap-highlight-color: rgba(0,0,0,0); + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} + +#upload .filelist div.file-panel span.rotateLeft { + display:none; + background-position: 0 -24px; +} + +#upload .filelist div.file-panel span.rotateLeft:hover { + background-position: 0 0; +} + +#upload .filelist div.file-panel span.rotateRight { + display:none; + background-position: -24px -24px; +} + +#upload .filelist div.file-panel span.rotateRight:hover { + background-position: -24px 0; +} + +#upload .filelist div.file-panel span.cancel { + background-position: -48px -24px; +} + +#upload .filelist div.file-panel span.cancel:hover { + background-position: -48px 0; +} + +#upload .statusBar { + height: 45px; + border-bottom: 1px solid #dadada; + margin: 0 10px; + padding: 0; + line-height: 45px; + vertical-align: middle; + position: relative; +} + +#upload .statusBar .progress { + border: 1px solid #1483d8; + width: 198px; + background: #fff; + height: 18px; + position: absolute; + top: 12px; + display: none; + text-align: center; + line-height: 18px; + color: #6dbfff; + margin: 0 10px 0 0; +} +#upload .statusBar .progress span.percentage { + width: 0; + height: 100%; + left: 0; + top: 0; + background: #1483d8; + position: absolute; +} +#upload .statusBar .progress span.text { + position: relative; + z-index: 10; +} + +#upload .statusBar .info { + display: inline-block; + font-size: 14px; + color: #666666; +} + +#upload .statusBar .btns { + position: absolute; + top: 7px; + right: 0; + line-height: 30px; +} + +#filePickerBtn { + display: inline-block; + float: left; +} +#upload .statusBar .btns .webuploader-pick, +#upload .statusBar .btns .uploadBtn, +#upload .statusBar .btns .uploadBtn.state-uploading, +#upload .statusBar .btns .uploadBtn.state-paused { + background: #ffffff; + border: 1px solid #cfcfcf; + color: #565656; + padding: 0 18px; + display: inline-block; + border-radius: 3px; + margin-left: 10px; + cursor: pointer; + font-size: 14px; + float: left; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; +} +#upload .statusBar .btns .webuploader-pick-hover, +#upload .statusBar .btns .uploadBtn:hover, +#upload .statusBar .btns .uploadBtn.state-uploading:hover, +#upload .statusBar .btns .uploadBtn.state-paused:hover { + background: #f0f0f0; +} + +#upload .statusBar .btns .uploadBtn, +#upload .statusBar .btns .uploadBtn.state-paused{ + background: #00b7ee; + color: #fff; + border-color: transparent; +} +#upload .statusBar .btns .uploadBtn:hover, +#upload .statusBar .btns .uploadBtn.state-paused:hover{ + background: #00a2d4; +} + +#upload .statusBar .btns .uploadBtn.disabled { + pointer-events: none; + filter:alpha(opacity=60); + -moz-opacity:0.6; + -khtml-opacity: 0.6; + opacity: 0.6; +} + + +/* 在线文件的文件预览图标 */ +i.file-preview { + display: block; + margin: 10px auto; + width: 70px; + height: 70px; + background-image: url("./images/file-icons.png"); + background-image: url("./images/file-icons.gif") \9; + background-position: -140px center; + background-repeat: no-repeat; +} +i.file-preview.file-type-dir{ + background-position: 0 center; +} +i.file-preview.file-type-file{ + background-position: -140px center; +} +i.file-preview.file-type-filelist{ + background-position: -210px center; +} +i.file-preview.file-type-zip, +i.file-preview.file-type-rar, +i.file-preview.file-type-7z, +i.file-preview.file-type-tar, +i.file-preview.file-type-gz, +i.file-preview.file-type-bz2{ + background-position: -280px center; +} +i.file-preview.file-type-xls, +i.file-preview.file-type-xlsx{ + background-position: -350px center; +} +i.file-preview.file-type-doc, +i.file-preview.file-type-docx{ + background-position: -420px center; +} +i.file-preview.file-type-ppt, +i.file-preview.file-type-pptx{ + background-position: -490px center; +} +i.file-preview.file-type-vsd{ + background-position: -560px center; +} +i.file-preview.file-type-pdf{ + background-position: -630px center; +} +i.file-preview.file-type-txt, +i.file-preview.file-type-md, +i.file-preview.file-type-json, +i.file-preview.file-type-htm, +i.file-preview.file-type-xml, +i.file-preview.file-type-html, +i.file-preview.file-type-js, +i.file-preview.file-type-css, +i.file-preview.file-type-php, +i.file-preview.file-type-jsp, +i.file-preview.file-type-asp{ + background-position: -700px center; +} +i.file-preview.file-type-apk{ + background-position: -770px center; +} +i.file-preview.file-type-exe{ + background-position: -840px center; +} +i.file-preview.file-type-ipa{ + background-position: -910px center; +} +i.file-preview.file-type-mp4, +i.file-preview.file-type-swf, +i.file-preview.file-type-mkv, +i.file-preview.file-type-avi, +i.file-preview.file-type-flv, +i.file-preview.file-type-mov, +i.file-preview.file-type-mpg, +i.file-preview.file-type-mpeg, +i.file-preview.file-type-ogv, +i.file-preview.file-type-webm, +i.file-preview.file-type-rm, +i.file-preview.file-type-rmvb{ + background-position: -980px center; +} +i.file-preview.file-type-ogg, +i.file-preview.file-type-wav, +i.file-preview.file-type-wmv, +i.file-preview.file-type-mid, +i.file-preview.file-type-mp3{ + background-position: -1050px center; +} +i.file-preview.file-type-jpg, +i.file-preview.file-type-jpeg, +i.file-preview.file-type-gif, +i.file-preview.file-type-bmp, +i.file-preview.file-type-png, +i.file-preview.file-type-psd{ + background-position: -140px center; +} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/video.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/video.html new file mode 100644 index 000000000..500788291 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/video.html @@ -0,0 +1,86 @@ + + + + + + + + + +
          +
          +
          + + +
          +
          +
          +
          +
          +
          +
          + + + + +
          +
          +
          + +
          +
          +
          +
          +
          +
          +
          +
          +
          + 0% + +
          +
          +
          +
          +
          +
          +
          +
          +
          +
          +
          +
            +
          • +
          +
          +
          +
          +
          + + + + +
          +
          +
          + +
          +
          +
          +
          +
          +
          +
          + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/video.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/video.js new file mode 100644 index 000000000..a8c34d974 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/video/video.js @@ -0,0 +1,791 @@ +/** + * Created by JetBrains PhpStorm. + * User: taoqili + * Date: 12-2-20 + * Time: 上午11:19 + * To change this template use File | Settings | File Templates. + */ + +(function(){ + + var video = {}, + uploadVideoList = [], + isModifyUploadVideo = false, + uploadFile; + + window.onload = function(){ + $focus($G("videoUrl")); + initTabs(); + initVideo(); + initUpload(); + }; + + /* 初始化tab标签 */ + function initTabs(){ + var tabs = $G('tabHeads').children; + for (var i = 0; i < tabs.length; i++) { + domUtils.on(tabs[i], "click", function (e) { + var j, bodyId, target = e.target || e.srcElement; + for (j = 0; j < tabs.length; j++) { + bodyId = tabs[j].getAttribute('data-content-id'); + if(tabs[j] == target){ + domUtils.addClass(tabs[j], 'focus'); + domUtils.addClass($G(bodyId), 'focus'); + }else { + domUtils.removeClasses(tabs[j], 'focus'); + domUtils.removeClasses($G(bodyId), 'focus'); + } + } + }); + } + } + + function initVideo(){ + createAlignButton( ["videoFloat", "upload_alignment"] ); + addUrlChangeListener($G("videoUrl")); + addOkListener(); + + //编辑视频时初始化相关信息 + (function(){ + var img = editor.selection.getRange().getClosedNode(),url; + if(img && img.className){ + var hasFakedClass = (img.className == "edui-faked-video"), + hasUploadClass = img.className.indexOf("edui-upload-video")!=-1; + if(hasFakedClass || hasUploadClass) { + $G("videoUrl").value = url = img.getAttribute("_url"); + $G("videoWidth").value = img.width; + $G("videoHeight").value = img.height; + var align = domUtils.getComputedStyle(img,"float"), + parentAlign = domUtils.getComputedStyle(img.parentNode,"text-align"); + updateAlignButton(parentAlign==="center"?"center":align); + } + if(hasUploadClass) { + isModifyUploadVideo = true; + } + } + createPreviewVideo(url); + })(); + } + + /** + * 监听确认和取消两个按钮事件,用户执行插入或者清空正在播放的视频实例操作 + */ + function addOkListener(){ + dialog.onok = function(){ + $G("preview").innerHTML = ""; + var currentTab = findFocus("tabHeads","tabSrc"); + switch(currentTab){ + case "video": + return insertSingle(); + break; + case "videoSearch": + return insertSearch("searchList"); + break; + case "upload": + return insertUpload(); + break; + } + }; + dialog.oncancel = function(){ + $G("preview").innerHTML = ""; + }; + } + + /** + * 依据传入的align值更新按钮信息 + * @param align + */ + function updateAlignButton( align ) { + var aligns = $G( "videoFloat" ).children; + for ( var i = 0, ci; ci = aligns[i++]; ) { + if ( ci.getAttribute( "name" ) == align ) { + if ( ci.className !="focus" ) { + ci.className = "focus"; + } + } else { + if ( ci.className =="focus" ) { + ci.className = ""; + } + } + } + } + + /** + * 将单个视频信息插入编辑器中 + */ + function insertSingle(){ + var width = $G("videoWidth"), + height = $G("videoHeight"), + url=$G('videoUrl').value, + align = findFocus("videoFloat","name"); + if(!url) return false; + if ( !checkNum( [width, height] ) ) return false; + editor.execCommand('insertvideo', { + url: convert_url(url), + width: width.value, + height: height.value, + align: align + }, isModifyUploadVideo ? 'upload':null); + } + + /** + * 将元素id下的所有代表视频的图片插入编辑器中 + * @param id + */ + function insertSearch(id){ + var imgs = domUtils.getElementsByTagName($G(id),"img"), + videoObjs=[]; + for(var i=0,img; img=imgs[i++];){ + if(img.getAttribute("selected")){ + videoObjs.push({ + url:img.getAttribute("ue_video_url"), + width:420, + height:280, + align:"none" + }); + } + } + editor.execCommand('insertvideo',videoObjs); + } + + /** + * 找到id下具有focus类的节点并返回该节点下的某个属性 + * @param id + * @param returnProperty + */ + function findFocus( id, returnProperty ) { + var tabs = $G( id ).children, + property; + for ( var i = 0, ci; ci = tabs[i++]; ) { + if ( ci.className=="focus" ) { + property = ci.getAttribute( returnProperty ); + break; + } + } + return property; + } + function convert_url(url){ + if ( !url ) return ''; + url = utils.trim(url) + .replace(/v\.youku\.com\/v_show\/id_([\w\-=]+)\.html/i, 'player.youku.com/player.php/sid/$1/v.swf') + .replace(/(www\.)?youtube\.com\/watch\?v=([\w\-]+)/i, "www.youtube.com/v/$2") + .replace(/youtu.be\/(\w+)$/i, "www.youtube.com/v/$1") + .replace(/v\.ku6\.com\/.+\/([\w\.]+)\.html.*$/i, "player.ku6.com/refer/$1/v.swf") + .replace(/www\.56\.com\/u\d+\/v_([\w\-]+)\.html/i, "player.56.com/v_$1.swf") + .replace(/www.56.com\/w\d+\/play_album\-aid\-\d+_vid\-([^.]+)\.html/i, "player.56.com/v_$1.swf") + .replace(/v\.pps\.tv\/play_([\w]+)\.html.*$/i, "player.pps.tv/player/sid/$1/v.swf") + .replace(/www\.letv\.com\/ptv\/vplay\/([\d]+)\.html.*$/i, "i7.imgs.letv.com/player/swfPlayer.swf?id=$1&autoplay=0") + .replace(/www\.tudou\.com\/programs\/view\/([\w\-]+)\/?/i, "www.tudou.com/v/$1") + .replace(/v\.qq\.com\/cover\/[\w]+\/[\w]+\/([\w]+)\.html/i, "static.video.qq.com/TPout.swf?vid=$1") + .replace(/v\.qq\.com\/.+[\?\&]vid=([^&]+).*$/i, "static.video.qq.com/TPout.swf?vid=$1") + .replace(/my\.tv\.sohu\.com\/[\w]+\/[\d]+\/([\d]+)\.shtml.*$/i, "share.vrs.sohu.com/my/v.swf&id=$1"); + + return url; + } + + /** + * 检测传入的所有input框中输入的长宽是否是正数 + * @param nodes input框集合, + */ + function checkNum( nodes ) { + for ( var i = 0, ci; ci = nodes[i++]; ) { + var value = ci.value; + if ( !isNumber( value ) && value) { + alert( lang.numError ); + ci.value = ""; + ci.focus(); + return false; + } + } + return true; + } + + /** + * 数字判断 + * @param value + */ + function isNumber( value ) { + return /(0|^[1-9]\d*$)/.test( value ); + } + + /** + * 创建图片浮动选择按钮 + * @param ids + */ + function createAlignButton( ids ) { + for ( var i = 0, ci; ci = ids[i++]; ) { + var floatContainer = $G( ci ), + nameMaps = {"none":lang['default'], "left":lang.floatLeft, "right":lang.floatRight, "center":lang.block}; + for ( var j in nameMaps ) { + var div = document.createElement( "div" ); + div.setAttribute( "name", j ); + if ( j == "none" ) div.className="focus"; + div.style.cssText = "background:url(images/" + j + "_focus.jpg);"; + div.setAttribute( "title", nameMaps[j] ); + floatContainer.appendChild( div ); + } + switchSelect( ci ); + } + } + + /** + * 选择切换 + * @param selectParentId + */ + function switchSelect( selectParentId ) { + var selects = $G( selectParentId ).children; + for ( var i = 0, ci; ci = selects[i++]; ) { + domUtils.on( ci, "click", function () { + for ( var j = 0, cj; cj = selects[j++]; ) { + cj.className = ""; + cj.removeAttribute && cj.removeAttribute( "class" ); + } + this.className = "focus"; + } ) + } + } + + /** + * 监听url改变事件 + * @param url + */ + function addUrlChangeListener(url){ + if (browser.ie) { + url.onpropertychange = function () { + createPreviewVideo( this.value ); + } + } else { + url.addEventListener( "input", function () { + createPreviewVideo( this.value ); + }, false ); + } + } + + /** + * 根据url生成视频预览 + * @param url + */ + function createPreviewVideo(url){ + if ( !url )return; + + var conUrl = convert_url(url); + + conUrl = utils.unhtmlForUrl(conUrl); + + $G("preview").innerHTML = '
          '+lang.urlError+'
          '+ + '' + + ''; + } + + + /* 插入上传视频 */ + function insertUpload(){ + var videoObjs=[], + uploadDir = editor.getOpt('videoUrlPrefix'), + width = parseInt($G('upload_width').value, 10) || 420, + height = parseInt($G('upload_height').value, 10) || 280, + align = findFocus("upload_alignment","name") || 'none'; + for(var key in uploadVideoList) { + var file = uploadVideoList[key]; + videoObjs.push({ + url: uploadDir + file.url, + width:width, + height:height, + align:align + }); + } + + var count = uploadFile.getQueueCount(); + if (count) { + $('.info', '#queueList').html('' + '还有2个未上传文件'.replace(/[\d]/, count) + ''); + return false; + } else { + editor.execCommand('insertvideo', videoObjs, 'upload'); + } + } + + /*初始化上传标签*/ + function initUpload(){ + uploadFile = new UploadFile('queueList'); + } + + + /* 上传附件 */ + function UploadFile(target) { + this.$wrap = target.constructor == String ? $('#' + target) : $(target); + this.init(); + } + UploadFile.prototype = { + init: function () { + this.fileList = []; + this.initContainer(); + this.initUploader(); + }, + initContainer: function () { + this.$queue = this.$wrap.find('.filelist'); + }, + /* 初始化容器 */ + initUploader: function () { + var _this = this, + $ = jQuery, // just in case. Make sure it's not an other libaray. + $wrap = _this.$wrap, + // 图片容器 + $queue = $wrap.find('.filelist'), + // 状态栏,包括进度和控制按钮 + $statusBar = $wrap.find('.statusBar'), + // 文件总体选择信息。 + $info = $statusBar.find('.info'), + // 上传按钮 + $upload = $wrap.find('.uploadBtn'), + // 上传按钮 + $filePickerBtn = $wrap.find('.filePickerBtn'), + // 上传按钮 + $filePickerBlock = $wrap.find('.filePickerBlock'), + // 没选择文件之前的内容。 + $placeHolder = $wrap.find('.placeholder'), + // 总体进度条 + $progress = $statusBar.find('.progress').hide(), + // 添加的文件数量 + fileCount = 0, + // 添加的文件总大小 + fileSize = 0, + // 优化retina, 在retina下这个值是2 + ratio = window.devicePixelRatio || 1, + // 缩略图大小 + thumbnailWidth = 113 * ratio, + thumbnailHeight = 113 * ratio, + // 可能有pedding, ready, uploading, confirm, done. + state = '', + // 所有文件的进度信息,key为file id + percentages = {}, + supportTransition = (function () { + var s = document.createElement('p').style, + r = 'transition' in s || + 'WebkitTransition' in s || + 'MozTransition' in s || + 'msTransition' in s || + 'OTransition' in s; + s = null; + return r; + })(), + // WebUploader实例 + uploader, + actionUrl = editor.getActionUrl(editor.getOpt('videoActionName')), + fileMaxSize = editor.getOpt('videoMaxSize'), + acceptExtensions = (editor.getOpt('videoAllowFiles') || []).join('').replace(/\./g, ',').replace(/^[,]/, '');; + + if (!WebUploader.Uploader.support()) { + $('#filePickerReady').after($('
          ').html(lang.errorNotSupport)).hide(); + return; + } else if (!editor.getOpt('videoActionName')) { + $('#filePickerReady').after($('
          ').html(lang.errorLoadConfig)).hide(); + return; + } + + uploader = _this.uploader = WebUploader.create({ + pick: { + id: '#filePickerReady', + label: lang.uploadSelectFile + }, + swf: '../../third-party/webuploader/Uploader.swf', + server: actionUrl, + fileVal: editor.getOpt('videoFieldName'), + duplicate: true, + fileSingleSizeLimit: fileMaxSize, + compress: false + }); + uploader.addButton({ + id: '#filePickerBlock' + }); + uploader.addButton({ + id: '#filePickerBtn', + label: lang.uploadAddFile + }); + + setState('pedding'); + + // 当有文件添加进来时执行,负责view的创建 + function addFile(file) { + var $li = $('
        • ' + + '

          ' + file.name + '

          ' + + '

          ' + + '

          ' + + '
        • '), + + $btns = $('
          ' + + '' + lang.uploadDelete + '' + + '' + lang.uploadTurnRight + '' + + '' + lang.uploadTurnLeft + '
          ').appendTo($li), + $prgress = $li.find('p.progress span'), + $wrap = $li.find('p.imgWrap'), + $info = $('

          ').hide().appendTo($li), + + showError = function (code) { + switch (code) { + case 'exceed_size': + text = lang.errorExceedSize; + break; + case 'interrupt': + text = lang.errorInterrupt; + break; + case 'http': + text = lang.errorHttp; + break; + case 'not_allow_type': + text = lang.errorFileType; + break; + default: + text = lang.errorUploadRetry; + break; + } + $info.text(text).show(); + }; + + if (file.getStatus() === 'invalid') { + showError(file.statusText); + } else { + $wrap.text(lang.uploadPreview); + if ('|png|jpg|jpeg|bmp|gif|'.indexOf('|'+file.ext.toLowerCase()+'|') == -1) { + $wrap.empty().addClass('notimage').append('' + + '' + file.name + ''); + } else { + if (browser.ie && browser.version <= 7) { + $wrap.text(lang.uploadNoPreview); + } else { + uploader.makeThumb(file, function (error, src) { + if (error || !src || (/^data:/.test(src) && browser.ie && browser.version <= 7)) { + $wrap.text(lang.uploadNoPreview); + } else { + var $img = $(''); + $wrap.empty().append($img); + $img.on('error', function () { + $wrap.text(lang.uploadNoPreview); + }); + } + }, thumbnailWidth, thumbnailHeight); + } + } + percentages[ file.id ] = [ file.size, 0 ]; + file.rotation = 0; + + /* 检查文件格式 */ + if (!file.ext || acceptExtensions.indexOf(file.ext.toLowerCase()) == -1) { + showError('not_allow_type'); + uploader.removeFile(file); + } + } + + file.on('statuschange', function (cur, prev) { + if (prev === 'progress') { + $prgress.hide().width(0); + } else if (prev === 'queued') { + $li.off('mouseenter mouseleave'); + $btns.remove(); + } + // 成功 + if (cur === 'error' || cur === 'invalid') { + showError(file.statusText); + percentages[ file.id ][ 1 ] = 1; + } else if (cur === 'interrupt') { + showError('interrupt'); + } else if (cur === 'queued') { + percentages[ file.id ][ 1 ] = 0; + } else if (cur === 'progress') { + $info.hide(); + $prgress.css('display', 'block'); + } else if (cur === 'complete') { + } + + $li.removeClass('state-' + prev).addClass('state-' + cur); + }); + + $li.on('mouseenter', function () { + $btns.stop().animate({height: 30}); + }); + $li.on('mouseleave', function () { + $btns.stop().animate({height: 0}); + }); + + $btns.on('click', 'span', function () { + var index = $(this).index(), + deg; + + switch (index) { + case 0: + uploader.removeFile(file); + return; + case 1: + file.rotation += 90; + break; + case 2: + file.rotation -= 90; + break; + } + + if (supportTransition) { + deg = 'rotate(' + file.rotation + 'deg)'; + $wrap.css({ + '-webkit-transform': deg, + '-mos-transform': deg, + '-o-transform': deg, + 'transform': deg + }); + } else { + $wrap.css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + (~~((file.rotation / 90) % 4 + 4) % 4) + ')'); + } + + }); + + $li.insertBefore($filePickerBlock); + } + + // 负责view的销毁 + function removeFile(file) { + var $li = $('#' + file.id); + delete percentages[ file.id ]; + updateTotalProgress(); + $li.off().find('.file-panel').off().end().remove(); + } + + function updateTotalProgress() { + var loaded = 0, + total = 0, + spans = $progress.children(), + percent; + + $.each(percentages, function (k, v) { + total += v[ 0 ]; + loaded += v[ 0 ] * v[ 1 ]; + }); + + percent = total ? loaded / total : 0; + + spans.eq(0).text(Math.round(percent * 100) + '%'); + spans.eq(1).css('width', Math.round(percent * 100) + '%'); + updateStatus(); + } + + function setState(val, files) { + + if (val != state) { + + var stats = uploader.getStats(); + + $upload.removeClass('state-' + state); + $upload.addClass('state-' + val); + + switch (val) { + + /* 未选择文件 */ + case 'pedding': + $queue.addClass('element-invisible'); + $statusBar.addClass('element-invisible'); + $placeHolder.removeClass('element-invisible'); + $progress.hide(); $info.hide(); + uploader.refresh(); + break; + + /* 可以开始上传 */ + case 'ready': + $placeHolder.addClass('element-invisible'); + $queue.removeClass('element-invisible'); + $statusBar.removeClass('element-invisible'); + $progress.hide(); $info.show(); + $upload.text(lang.uploadStart); + uploader.refresh(); + break; + + /* 上传中 */ + case 'uploading': + $progress.show(); $info.hide(); + $upload.text(lang.uploadPause); + break; + + /* 暂停上传 */ + case 'paused': + $progress.show(); $info.hide(); + $upload.text(lang.uploadContinue); + break; + + case 'confirm': + $progress.show(); $info.hide(); + $upload.text(lang.uploadStart); + + stats = uploader.getStats(); + if (stats.successNum && !stats.uploadFailNum) { + setState('finish'); + return; + } + break; + + case 'finish': + $progress.hide(); $info.show(); + if (stats.uploadFailNum) { + $upload.text(lang.uploadRetry); + } else { + $upload.text(lang.uploadStart); + } + break; + } + + state = val; + updateStatus(); + + } + + if (!_this.getQueueCount()) { + $upload.addClass('disabled') + } else { + $upload.removeClass('disabled') + } + + } + + function updateStatus() { + var text = '', stats; + + if (state === 'ready') { + text = lang.updateStatusReady.replace('_', fileCount).replace('_KB', WebUploader.formatSize(fileSize)); + } else if (state === 'confirm') { + stats = uploader.getStats(); + if (stats.uploadFailNum) { + text = lang.updateStatusConfirm.replace('_', stats.successNum).replace('_', stats.successNum); + } + } else { + stats = uploader.getStats(); + text = lang.updateStatusFinish.replace('_', fileCount). + replace('_KB', WebUploader.formatSize(fileSize)). + replace('_', stats.successNum); + + if (stats.uploadFailNum) { + text += lang.updateStatusError.replace('_', stats.uploadFailNum); + } + } + + $info.html(text); + } + + uploader.on('fileQueued', function (file) { + fileCount++; + fileSize += file.size; + + if (fileCount === 1) { + $placeHolder.addClass('element-invisible'); + $statusBar.show(); + } + + addFile(file); + }); + + uploader.on('fileDequeued', function (file) { + fileCount--; + fileSize -= file.size; + + removeFile(file); + updateTotalProgress(); + }); + + uploader.on('filesQueued', function (file) { + if (!uploader.isInProgress() && (state == 'pedding' || state == 'finish' || state == 'confirm' || state == 'ready')) { + setState('ready'); + } + updateTotalProgress(); + }); + + uploader.on('all', function (type, files) { + switch (type) { + case 'uploadFinished': + setState('confirm', files); + break; + case 'startUpload': + /* 添加额外的GET参数 */ + var params = utils.serializeParam(editor.queryCommandValue('serverparam')) || '', + url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?':'&') + 'encode=utf-8&' + params); + uploader.option('server', url); + setState('uploading', files); + break; + case 'stopUpload': + setState('paused', files); + break; + } + }); + + uploader.on('uploadBeforeSend', function (file, data, header) { + //这里可以通过data对象添加POST参数 + header['X_Requested_With'] = 'XMLHttpRequest'; + }); + + uploader.on('uploadProgress', function (file, percentage) { + var $li = $('#' + file.id), + $percent = $li.find('.progress span'); + + $percent.css('width', percentage * 100 + '%'); + percentages[ file.id ][ 1 ] = percentage; + updateTotalProgress(); + }); + + uploader.on('uploadSuccess', function (file, ret) { + var $file = $('#' + file.id); + try { + var responseText = (ret._raw || ret), + json = utils.str2json(responseText); + if (json.state == 'SUCCESS') { + uploadVideoList.push({ + 'url': json.url, + 'type': json.type, + 'original':json.original + }); + $file.append(''); + } else { + $file.find('.error').text(json.state).show(); + } + } catch (e) { + $file.find('.error').text(lang.errorServerUpload).show(); + } + }); + + uploader.on('uploadError', function (file, code) { + }); + uploader.on('error', function (code, file) { + if (code == 'Q_TYPE_DENIED' || code == 'F_EXCEED_SIZE') { + addFile(file); + } + }); + uploader.on('uploadComplete', function (file, ret) { + }); + + $upload.on('click', function () { + if ($(this).hasClass('disabled')) { + return false; + } + + if (state === 'ready') { + uploader.upload(); + } else if (state === 'paused') { + uploader.upload(); + } else if (state === 'uploading') { + uploader.stop(); + } + }); + + $upload.addClass('state-' + state); + updateTotalProgress(); + }, + getQueueCount: function () { + var file, i, status, readyFile = 0, files = this.uploader.getFiles(); + for (i = 0; file = files[i++]; ) { + status = file.getStatus(); + if (status == 'queued' || status == 'uploading' || status == 'progress') readyFile++; + } + return readyFile; + }, + refresh: function(){ + this.uploader.refresh(); + } + }; + +})(); diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/wordimage/fClipboard_ueditor.swf b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/wordimage/fClipboard_ueditor.swf new file mode 100644 index 000000000..ac5d27f81 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/wordimage/fClipboard_ueditor.swf differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/wordimage/imageUploader.swf b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/wordimage/imageUploader.swf new file mode 100644 index 000000000..2a554cadb Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/wordimage/imageUploader.swf differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/wordimage/tangram.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/wordimage/tangram.js new file mode 100644 index 000000000..2ebd8fd3d --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/wordimage/tangram.js @@ -0,0 +1,1495 @@ +// Copyright (c) 2009, Baidu Inc. All rights reserved. +// +// Licensed under the BSD License +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http:// tangram.baidu.com/license.html +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + /** + * @namespace T Tangram七巧板 + * @name T + * @version 1.6.0 +*/ + +/** + * 声明baidu包 + * @author: allstar, erik, meizz, berg + */ +var T, + baidu = T = baidu || {version: "1.5.0"}; +baidu.guid = "$BAIDU$"; +baidu.$$ = window[baidu.guid] = window[baidu.guid] || {global:{}}; + +/** + * 使用flash资源封装的一些功能 + * @namespace baidu.flash + */ +baidu.flash = baidu.flash || {}; + +/** + * 操作dom的方法 + * @namespace baidu.dom + */ +baidu.dom = baidu.dom || {}; + + +/** + * 从文档中获取指定的DOM元素 + * @name baidu.dom.g + * @function + * @grammar baidu.dom.g(id) + * @param {string|HTMLElement} id 元素的id或DOM元素. + * @shortcut g,T.G + * @meta standard + * @see baidu.dom.q + * + * @return {HTMLElement|null} 获取的元素,查找不到时返回null,如果参数不合法,直接返回参数. + */ +baidu.dom.g = function(id) { + if (!id) return null; + if ('string' == typeof id || id instanceof String) { + return document.getElementById(id); + } else if (id.nodeName && (id.nodeType == 1 || id.nodeType == 9)) { + return id; + } + return null; +}; +baidu.g = baidu.G = baidu.dom.g; + + +/** + * 操作数组的方法 + * @namespace baidu.array + */ + +baidu.array = baidu.array || {}; + + +/** + * 遍历数组中所有元素 + * @name baidu.array.each + * @function + * @grammar baidu.array.each(source, iterator[, thisObject]) + * @param {Array} source 需要遍历的数组 + * @param {Function} iterator 对每个数组元素进行调用的函数,该函数有两个参数,第一个为数组元素,第二个为数组索引值,function (item, index)。 + * @param {Object} [thisObject] 函数调用时的this指针,如果没有此参数,默认是当前遍历的数组 + * @remark + * each方法不支持对Object的遍历,对Object的遍历使用baidu.object.each 。 + * @shortcut each + * @meta standard + * + * @returns {Array} 遍历的数组 + */ + +baidu.each = baidu.array.forEach = baidu.array.each = function (source, iterator, thisObject) { + var returnValue, item, i, len = source.length; + + if ('function' == typeof iterator) { + for (i = 0; i < len; i++) { + item = source[i]; + returnValue = iterator.call(thisObject || source, item, i); + + if (returnValue === false) { + break; + } + } + } + return source; +}; + +/** + * 对语言层面的封装,包括类型判断、模块扩展、继承基类以及对象自定义事件的支持。 + * @namespace baidu.lang + */ +baidu.lang = baidu.lang || {}; + + +/** + * 判断目标参数是否为function或Function实例 + * @name baidu.lang.isFunction + * @function + * @grammar baidu.lang.isFunction(source) + * @param {Any} source 目标参数 + * @version 1.2 + * @see baidu.lang.isString,baidu.lang.isObject,baidu.lang.isNumber,baidu.lang.isArray,baidu.lang.isElement,baidu.lang.isBoolean,baidu.lang.isDate + * @meta standard + * @returns {boolean} 类型判断结果 + */ +baidu.lang.isFunction = function (source) { + return '[object Function]' == Object.prototype.toString.call(source); +}; + +/** + * 判断目标参数是否string类型或String对象 + * @name baidu.lang.isString + * @function + * @grammar baidu.lang.isString(source) + * @param {Any} source 目标参数 + * @shortcut isString + * @meta standard + * @see baidu.lang.isObject,baidu.lang.isNumber,baidu.lang.isArray,baidu.lang.isElement,baidu.lang.isBoolean,baidu.lang.isDate + * + * @returns {boolean} 类型判断结果 + */ +baidu.lang.isString = function (source) { + return '[object String]' == Object.prototype.toString.call(source); +}; +baidu.isString = baidu.lang.isString; + + +/** + * 判断浏览器类型和特性的属性 + * @namespace baidu.browser + */ +baidu.browser = baidu.browser || {}; + + +/** + * 判断是否为opera浏览器 + * @property opera opera版本号 + * @grammar baidu.browser.opera + * @meta standard + * @see baidu.browser.ie,baidu.browser.firefox,baidu.browser.safari,baidu.browser.chrome + * @returns {Number} opera版本号 + */ + +/** + * opera 从10开始不是用opera后面的字符串进行版本的判断 + * 在Browser identification最后添加Version + 数字进行版本标识 + * opera后面的数字保持在9.80不变 + */ +baidu.browser.opera = /opera(\/| )(\d+(\.\d+)?)(.+?(version\/(\d+(\.\d+)?)))?/i.test(navigator.userAgent) ? + ( RegExp["\x246"] || RegExp["\x242"] ) : undefined; + + +/** + * 在目标元素的指定位置插入HTML代码 + * @name baidu.dom.insertHTML + * @function + * @grammar baidu.dom.insertHTML(element, position, html) + * @param {HTMLElement|string} element 目标元素或目标元素的id + * @param {string} position 插入html的位置信息,取值为beforeBegin,afterBegin,beforeEnd,afterEnd + * @param {string} html 要插入的html + * @remark + * + * 对于position参数,大小写不敏感
          + * 参数的意思:beforeBegin<span>afterBegin this is span! beforeEnd</span> afterEnd
          + * 此外,如果使用本函数插入带有script标签的HTML字符串,script标签对应的脚本将不会被执行。 + * + * @shortcut insertHTML + * @meta standard + * + * @returns {HTMLElement} 目标元素 + */ +baidu.dom.insertHTML = function (element, position, html) { + element = baidu.dom.g(element); + var range,begin; + if (element.insertAdjacentHTML && !baidu.browser.opera) { + element.insertAdjacentHTML(position, html); + } else { + range = element.ownerDocument.createRange(); + position = position.toUpperCase(); + if (position == 'AFTERBEGIN' || position == 'BEFOREEND') { + range.selectNodeContents(element); + range.collapse(position == 'AFTERBEGIN'); + } else { + begin = position == 'BEFOREBEGIN'; + range[begin ? 'setStartBefore' : 'setEndAfter'](element); + range.collapse(begin); + } + range.insertNode(range.createContextualFragment(html)); + } + return element; +}; + +baidu.insertHTML = baidu.dom.insertHTML; + +/** + * 操作flash对象的方法,包括创建flash对象、获取flash对象以及判断flash插件的版本号 + * @namespace baidu.swf + */ +baidu.swf = baidu.swf || {}; + + +/** + * 浏览器支持的flash插件版本 + * @property version 浏览器支持的flash插件版本 + * @grammar baidu.swf.version + * @return {String} 版本号 + * @meta standard + */ +baidu.swf.version = (function () { + var n = navigator; + if (n.plugins && n.mimeTypes.length) { + var plugin = n.plugins["Shockwave Flash"]; + if (plugin && plugin.description) { + return plugin.description + .replace(/([a-zA-Z]|\s)+/, "") + .replace(/(\s)+r/, ".") + ".0"; + } + } else if (window.ActiveXObject && !window.opera) { + for (var i = 12; i >= 2; i--) { + try { + var c = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.' + i); + if (c) { + var version = c.GetVariable("$version"); + return version.replace(/WIN/g,'').replace(/,/g,'.'); + } + } catch(e) {} + } + } +})(); + +/** + * 操作字符串的方法 + * @namespace baidu.string + */ +baidu.string = baidu.string || {}; + + +/** + * 对目标字符串进行html编码 + * @name baidu.string.encodeHTML + * @function + * @grammar baidu.string.encodeHTML(source) + * @param {string} source 目标字符串 + * @remark + * 编码字符有5个:&<>"' + * @shortcut encodeHTML + * @meta standard + * @see baidu.string.decodeHTML + * + * @returns {string} html编码后的字符串 + */ +baidu.string.encodeHTML = function (source) { + return String(source) + .replace(/&/g,'&') + .replace(//g,'>') + .replace(/"/g, """) + .replace(/'/g, "'"); +}; + +baidu.encodeHTML = baidu.string.encodeHTML; + +/** + * 创建flash对象的html字符串 + * @name baidu.swf.createHTML + * @function + * @grammar baidu.swf.createHTML(options) + * + * @param {Object} options 创建flash的选项参数 + * @param {string} options.id 要创建的flash的标识 + * @param {string} options.url flash文件的url + * @param {String} options.errorMessage 未安装flash player或flash player版本号过低时的提示 + * @param {string} options.ver 最低需要的flash player版本号 + * @param {string} options.width flash的宽度 + * @param {string} options.height flash的高度 + * @param {string} options.align flash的对齐方式,允许值:middle/left/right/top/bottom + * @param {string} options.base 设置用于解析swf文件中的所有相对路径语句的基本目录或URL + * @param {string} options.bgcolor swf文件的背景色 + * @param {string} options.salign 设置缩放的swf文件在由width和height设置定义的区域内的位置。允许值:l/r/t/b/tl/tr/bl/br + * @param {boolean} options.menu 是否显示右键菜单,允许值:true/false + * @param {boolean} options.loop 播放到最后一帧时是否重新播放,允许值: true/false + * @param {boolean} options.play flash是否在浏览器加载时就开始播放。允许值:true/false + * @param {string} options.quality 设置flash播放的画质,允许值:low/medium/high/autolow/autohigh/best + * @param {string} options.scale 设置flash内容如何缩放来适应设置的宽高。允许值:showall/noborder/exactfit + * @param {string} options.wmode 设置flash的显示模式。允许值:window/opaque/transparent + * @param {string} options.allowscriptaccess 设置flash与页面的通信权限。允许值:always/never/sameDomain + * @param {string} options.allownetworking 设置swf文件中允许使用的网络API。允许值:all/internal/none + * @param {boolean} options.allowfullscreen 是否允许flash全屏。允许值:true/false + * @param {boolean} options.seamlesstabbing 允许设置执行无缝跳格,从而使用户能跳出flash应用程序。该参数只能在安装Flash7及更高版本的Windows中使用。允许值:true/false + * @param {boolean} options.devicefont 设置静态文本对象是否以设备字体呈现。允许值:true/false + * @param {boolean} options.swliveconnect 第一次加载flash时浏览器是否应启动Java。允许值:true/false + * @param {Object} options.vars 要传递给flash的参数,支持JSON或string类型。 + * + * @see baidu.swf.create + * @meta standard + * @returns {string} flash对象的html字符串 + */ +baidu.swf.createHTML = function (options) { + options = options || {}; + var version = baidu.swf.version, + needVersion = options['ver'] || '6.0.0', + vUnit1, vUnit2, i, k, len, item, tmpOpt = {}, + encodeHTML = baidu.string.encodeHTML; + for (k in options) { + tmpOpt[k] = options[k]; + } + options = tmpOpt; + if (version) { + version = version.split('.'); + needVersion = needVersion.split('.'); + for (i = 0; i < 3; i++) { + vUnit1 = parseInt(version[i], 10); + vUnit2 = parseInt(needVersion[i], 10); + if (vUnit2 < vUnit1) { + break; + } else if (vUnit2 > vUnit1) { + return ''; + } + } + } else { + return ''; + } + + var vars = options['vars'], + objProperties = ['classid', 'codebase', 'id', 'width', 'height', 'align']; + options['align'] = options['align'] || 'middle'; + options['classid'] = 'clsid:d27cdb6e-ae6d-11cf-96b8-444553540000'; + options['codebase'] = 'http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0'; + options['movie'] = options['url'] || ''; + delete options['vars']; + delete options['url']; + if ('string' == typeof vars) { + options['flashvars'] = vars; + } else { + var fvars = []; + for (k in vars) { + item = vars[k]; + fvars.push(k + "=" + encodeURIComponent(item)); + } + options['flashvars'] = fvars.join('&'); + } + var str = [''); + var params = { + 'wmode' : 1, + 'scale' : 1, + 'quality' : 1, + 'play' : 1, + 'loop' : 1, + 'menu' : 1, + 'salign' : 1, + 'bgcolor' : 1, + 'base' : 1, + 'allowscriptaccess' : 1, + 'allownetworking' : 1, + 'allowfullscreen' : 1, + 'seamlesstabbing' : 1, + 'devicefont' : 1, + 'swliveconnect' : 1, + 'flashvars' : 1, + 'movie' : 1 + }; + + for (k in options) { + item = options[k]; + k = k.toLowerCase(); + if (params[k] && (item || item === false || item === 0)) { + str.push(''); + } + } + options['src'] = options['movie']; + options['name'] = options['id']; + delete options['id']; + delete options['movie']; + delete options['classid']; + delete options['codebase']; + options['type'] = 'application/x-shockwave-flash'; + options['pluginspage'] = 'http://www.macromedia.com/go/getflashplayer'; + str.push(''); + + return str.join(''); +}; + + +/** + * 在页面中创建一个flash对象 + * @name baidu.swf.create + * @function + * @grammar baidu.swf.create(options[, container]) + * + * @param {Object} options 创建flash的选项参数 + * @param {string} options.id 要创建的flash的标识 + * @param {string} options.url flash文件的url + * @param {String} options.errorMessage 未安装flash player或flash player版本号过低时的提示 + * @param {string} options.ver 最低需要的flash player版本号 + * @param {string} options.width flash的宽度 + * @param {string} options.height flash的高度 + * @param {string} options.align flash的对齐方式,允许值:middle/left/right/top/bottom + * @param {string} options.base 设置用于解析swf文件中的所有相对路径语句的基本目录或URL + * @param {string} options.bgcolor swf文件的背景色 + * @param {string} options.salign 设置缩放的swf文件在由width和height设置定义的区域内的位置。允许值:l/r/t/b/tl/tr/bl/br + * @param {boolean} options.menu 是否显示右键菜单,允许值:true/false + * @param {boolean} options.loop 播放到最后一帧时是否重新播放,允许值: true/false + * @param {boolean} options.play flash是否在浏览器加载时就开始播放。允许值:true/false + * @param {string} options.quality 设置flash播放的画质,允许值:low/medium/high/autolow/autohigh/best + * @param {string} options.scale 设置flash内容如何缩放来适应设置的宽高。允许值:showall/noborder/exactfit + * @param {string} options.wmode 设置flash的显示模式。允许值:window/opaque/transparent + * @param {string} options.allowscriptaccess 设置flash与页面的通信权限。允许值:always/never/sameDomain + * @param {string} options.allownetworking 设置swf文件中允许使用的网络API。允许值:all/internal/none + * @param {boolean} options.allowfullscreen 是否允许flash全屏。允许值:true/false + * @param {boolean} options.seamlesstabbing 允许设置执行无缝跳格,从而使用户能跳出flash应用程序。该参数只能在安装Flash7及更高版本的Windows中使用。允许值:true/false + * @param {boolean} options.devicefont 设置静态文本对象是否以设备字体呈现。允许值:true/false + * @param {boolean} options.swliveconnect 第一次加载flash时浏览器是否应启动Java。允许值:true/false + * @param {Object} options.vars 要传递给flash的参数,支持JSON或string类型。 + * + * @param {HTMLElement|string} [container] flash对象的父容器元素,不传递该参数时在当前代码位置创建flash对象。 + * @meta standard + * @see baidu.swf.createHTML,baidu.swf.getMovie + */ +baidu.swf.create = function (options, target) { + options = options || {}; + var html = baidu.swf.createHTML(options) + || options['errorMessage'] + || ''; + + if (target && 'string' == typeof target) { + target = document.getElementById(target); + } + baidu.dom.insertHTML( target || document.body ,'beforeEnd',html ); +}; +/** + * 判断是否为ie浏览器 + * @name baidu.browser.ie + * @field + * @grammar baidu.browser.ie + * @returns {Number} IE版本号 + */ +baidu.browser.ie = baidu.ie = /msie (\d+\.\d+)/i.test(navigator.userAgent) ? (document.documentMode || + RegExp['\x241']) : undefined; + +/** + * 移除数组中的项 + * @name baidu.array.remove + * @function + * @grammar baidu.array.remove(source, match) + * @param {Array} source 需要移除项的数组 + * @param {Any} match 要移除的项 + * @meta standard + * @see baidu.array.removeAt + * + * @returns {Array} 移除后的数组 + */ +baidu.array.remove = function (source, match) { + var len = source.length; + + while (len--) { + if (len in source && source[len] === match) { + source.splice(len, 1); + } + } + return source; +}; + +/** + * 判断目标参数是否Array对象 + * @name baidu.lang.isArray + * @function + * @grammar baidu.lang.isArray(source) + * @param {Any} source 目标参数 + * @meta standard + * @see baidu.lang.isString,baidu.lang.isObject,baidu.lang.isNumber,baidu.lang.isElement,baidu.lang.isBoolean,baidu.lang.isDate + * + * @returns {boolean} 类型判断结果 + */ +baidu.lang.isArray = function (source) { + return '[object Array]' == Object.prototype.toString.call(source); +}; + + + +/** + * 将一个变量转换成array + * @name baidu.lang.toArray + * @function + * @grammar baidu.lang.toArray(source) + * @param {mix} source 需要转换成array的变量 + * @version 1.3 + * @meta standard + * @returns {array} 转换后的array + */ +baidu.lang.toArray = function (source) { + if (source === null || source === undefined) + return []; + if (baidu.lang.isArray(source)) + return source; + if (typeof source.length !== 'number' || typeof source === 'string' || baidu.lang.isFunction(source)) { + return [source]; + } + if (source.item) { + var l = source.length, array = new Array(l); + while (l--) + array[l] = source[l]; + return array; + } + + return [].slice.call(source); +}; + +/** + * 获得flash对象的实例 + * @name baidu.swf.getMovie + * @function + * @grammar baidu.swf.getMovie(name) + * @param {string} name flash对象的名称 + * @see baidu.swf.create + * @meta standard + * @returns {HTMLElement} flash对象的实例 + */ +baidu.swf.getMovie = function (name) { + var movie = document[name], ret; + return baidu.browser.ie == 9 ? + movie && movie.length ? + (ret = baidu.array.remove(baidu.lang.toArray(movie),function(item){ + return item.tagName.toLowerCase() != "embed"; + })).length == 1 ? ret[0] : ret + : movie + : movie || window[name]; +}; + + +baidu.flash._Base = (function(){ + + var prefix = 'bd__flash__'; + + /** + * 创建一个随机的字符串 + * @private + * @return {String} + */ + function _createString(){ + return prefix + Math.floor(Math.random() * 2147483648).toString(36); + }; + + /** + * 检查flash状态 + * @private + * @param {Object} target flash对象 + * @return {Boolean} + */ + function _checkReady(target){ + if(typeof target !== 'undefined' && typeof target.flashInit !== 'undefined' && target.flashInit()){ + return true; + }else{ + return false; + } + }; + + /** + * 调用之前进行压栈的函数 + * @private + * @param {Array} callQueue 调用队列 + * @param {Object} target flash对象 + * @return {Null} + */ + function _callFn(callQueue, target){ + var result = null; + + callQueue = callQueue.reverse(); + baidu.each(callQueue, function(item){ + result = target.call(item.fnName, item.params); + item.callBack(result); + }); + }; + + /** + * 为传入的匿名函数创建函数名 + * @private + * @param {String|Function} fun 传入的匿名函数或者函数名 + * @return {String} + */ + function _createFunName(fun){ + var name = ''; + + if(baidu.lang.isFunction(fun)){ + name = _createString(); + window[name] = function(){ + fun.apply(window, arguments); + }; + + return name; + }else if(baidu.lang.isString){ + return fun; + } + }; + + /** + * 绘制flash + * @private + * @param {Object} options 创建参数 + * @return {Object} + */ + function _render(options){ + if(!options.id){ + options.id = _createString(); + } + + var container = options.container || ''; + delete(options.container); + + baidu.swf.create(options, container); + + return baidu.swf.getMovie(options.id); + }; + + return function(options, callBack){ + var me = this, + autoRender = (typeof options.autoRender !== 'undefined' ? options.autoRender : true), + createOptions = options.createOptions || {}, + target = null, + isReady = false, + callQueue = [], + timeHandle = null, + callBack = callBack || []; + + /** + * 将flash文件绘制到页面上 + * @public + * @return {Null} + */ + me.render = function(){ + target = _render(createOptions); + + if(callBack.length > 0){ + baidu.each(callBack, function(funName, index){ + callBack[index] = _createFunName(options[funName] || new Function()); + }); + } + me.call('setJSFuncName', [callBack]); + }; + + /** + * 返回flash状态 + * @return {Boolean} + */ + me.isReady = function(){ + return isReady; + }; + + /** + * 调用flash接口的统一入口 + * @param {String} fnName 调用的函数名 + * @param {Array} params 传入的参数组成的数组,若不许要参数,需传入空数组 + * @param {Function} [callBack] 异步调用后将返回值作为参数的调用回调函数,如无返回值,可以不传入此参数 + * @return {Null} + */ + me.call = function(fnName, params, callBack){ + if(!fnName) return null; + callBack = callBack || new Function(); + + var result = null; + + if(isReady){ + result = target.call(fnName, params); + callBack(result); + }else{ + callQueue.push({ + fnName: fnName, + params: params, + callBack: callBack + }); + + (!timeHandle) && (timeHandle = setInterval(_check, 200)); + } + }; + + /** + * 为传入的匿名函数创建函数名 + * @public + * @param {String|Function} fun 传入的匿名函数或者函数名 + * @return {String} + */ + me.createFunName = function(fun){ + return _createFunName(fun); + }; + + /** + * 检查flash是否ready, 并进行调用 + * @private + * @return {Null} + */ + function _check(){ + if(_checkReady(target)){ + clearInterval(timeHandle); + timeHandle = null; + _call(); + + isReady = true; + } + }; + + /** + * 调用之前进行压栈的函数 + * @private + * @return {Null} + */ + function _call(){ + _callFn(callQueue, target); + callQueue = []; + } + + autoRender && me.render(); + }; +})(); + + + +/** + * 创建flash based imageUploader + * @class + * @grammar baidu.flash.imageUploader(options) + * @param {Object} createOptions 创建flash时需要的参数,请参照baidu.swf.create文档 + * @config {Object} vars 创建imageUploader时所需要的参数 + * @config {Number} vars.gridWidth 每一个预览图片所占的宽度,应该为flash寛的整除 + * @config {Number} vars.gridHeight 每一个预览图片所占的高度,应该为flash高的整除 + * @config {Number} vars.picWidth 单张预览图片的宽度 + * @config {Number} vars.picHeight 单张预览图片的高度 + * @config {String} vars.uploadDataFieldName POST请求中图片数据的key,默认值'picdata' + * @config {String} vars.picDescFieldName POST请求中图片描述的key,默认值'picDesc' + * @config {Number} vars.maxSize 文件的最大体积,单位'MB' + * @config {Number} vars.compressSize 上传前如果图片体积超过该值,会先压缩 + * @config {Number} vars.maxNum:32 最大上传多少个文件 + * @config {Number} vars.compressLength 能接受的最大边长,超过该值会等比压缩 + * @config {String} vars.url 上传的url地址 + * @config {Number} vars.mode mode == 0时,是使用滚动条,mode == 1时,拉伸flash, 默认值为0 + * @see baidu.swf.createHTML + * @param {String} backgroundUrl 背景图片路径 + * @param {String} listBacgroundkUrl 布局控件背景 + * @param {String} buttonUrl 按钮图片不背景 + * @param {String|Function} selectFileCallback 选择文件的回调 + * @param {String|Function} exceedFileCallback文件超出限制的最大体积时的回调 + * @param {String|Function} deleteFileCallback 删除文件的回调 + * @param {String|Function} startUploadCallback 开始上传某个文件时的回调 + * @param {String|Function} uploadCompleteCallback 某个文件上传完成的回调 + * @param {String|Function} uploadErrorCallback 某个文件上传失败的回调 + * @param {String|Function} allCompleteCallback 全部上传完成时的回调 + * @param {String|Function} changeFlashHeight 改变Flash的高度,mode==1的时候才有用 + */ +baidu.flash.imageUploader = baidu.flash.imageUploader || function(options){ + + var me = this, + options = options || {}, + _flash = new baidu.flash._Base(options, [ + 'selectFileCallback', + 'exceedFileCallback', + 'deleteFileCallback', + 'startUploadCallback', + 'uploadCompleteCallback', + 'uploadErrorCallback', + 'allCompleteCallback', + 'changeFlashHeight' + ]); + /** + * 开始或回复上传图片 + * @public + * @return {Null} + */ + me.upload = function(){ + _flash.call('upload'); + }; + + /** + * 暂停上传图片 + * @public + * @return {Null} + */ + me.pause = function(){ + _flash.call('pause'); + }; + me.addCustomizedParams = function(index,obj){ + _flash.call('addCustomizedParams',[index,obj]); + } +}; + +/** + * 操作原生对象的方法 + * @namespace baidu.object + */ +baidu.object = baidu.object || {}; + + +/** + * 将源对象的所有属性拷贝到目标对象中 + * @author erik + * @name baidu.object.extend + * @function + * @grammar baidu.object.extend(target, source) + * @param {Object} target 目标对象 + * @param {Object} source 源对象 + * @see baidu.array.merge + * @remark + * +1.目标对象中,与源对象key相同的成员将会被覆盖。
          +2.源对象的prototype成员不会拷贝。 + + * @shortcut extend + * @meta standard + * + * @returns {Object} 目标对象 + */ +baidu.extend = +baidu.object.extend = function (target, source) { + for (var p in source) { + if (source.hasOwnProperty(p)) { + target[p] = source[p]; + } + } + + return target; +}; + + + + + +/** + * 创建flash based fileUploader + * @class + * @grammar baidu.flash.fileUploader(options) + * @param {Object} options + * @config {Object} createOptions 创建flash时需要的参数,请参照baidu.swf.create文档 + * @config {String} createOptions.width + * @config {String} createOptions.height + * @config {Number} maxNum 最大可选文件数 + * @config {Function|String} selectFile + * @config {Function|String} exceedMaxSize + * @config {Function|String} deleteFile + * @config {Function|String} uploadStart + * @config {Function|String} uploadComplete + * @config {Function|String} uploadError + * @config {Function|String} uploadProgress + */ +baidu.flash.fileUploader = baidu.flash.fileUploader || function(options){ + var me = this, + options = options || {}; + + options.createOptions = baidu.extend({ + wmod: 'transparent' + },options.createOptions || {}); + + var _flash = new baidu.flash._Base(options, [ + 'selectFile', + 'exceedMaxSize', + 'deleteFile', + 'uploadStart', + 'uploadComplete', + 'uploadError', + 'uploadProgress' + ]); + + _flash.call('setMaxNum', options.maxNum ? [options.maxNum] : [1]); + + /** + * 设置当鼠标移动到flash上时,是否变成手型 + * @public + * @param {Boolean} isCursor + * @return {Null} + */ + me.setHandCursor = function(isCursor){ + _flash.call('setHandCursor', [isCursor || false]); + }; + + /** + * 设置鼠标相应函数名 + * @param {String|Function} fun + */ + me.setMSFunName = function(fun){ + _flash.call('setMSFunName',[_flash.createFunName(fun)]); + }; + + /** + * 执行上传操作 + * @param {String} url 上传的url + * @param {String} fieldName 上传的表单字段名 + * @param {Object} postData 键值对,上传的POST数据 + * @param {Number|Array|null|-1} [index]上传的文件序列 + * Int值上传该文件 + * Array一次串行上传该序列文件 + * -1/null上传所有文件 + * @return {Null} + */ + me.upload = function(url, fieldName, postData, index){ + + if(typeof url !== 'string' || typeof fieldName !== 'string') return null; + if(typeof index === 'undefined') index = -1; + + _flash.call('upload', [url, fieldName, postData, index]); + }; + + /** + * 取消上传操作 + * @public + * @param {Number|-1} index + */ + me.cancel = function(index){ + if(typeof index === 'undefined') index = -1; + _flash.call('cancel', [index]); + }; + + /** + * 删除文件 + * @public + * @param {Number|Array} [index] 要删除的index,不传则全部删除 + * @param {Function} callBack + * */ + me.deleteFile = function(index, callBack){ + + var callBackAll = function(list){ + callBack && callBack(list); + }; + + if(typeof index === 'undefined'){ + _flash.call('deleteFilesAll', [], callBackAll); + return; + }; + + if(typeof index === 'Number') index = [index]; + index.sort(function(a,b){ + return b-a; + }); + baidu.each(index, function(item){ + _flash.call('deleteFileBy', item, callBackAll); + }); + }; + + /** + * 添加文件类型,支持macType + * @public + * @param {Object|Array[Object]} type {description:String, extention:String} + * @return {Null}; + */ + me.addFileType = function(type){ + var type = type || [[]]; + + if(type instanceof Array) type = [type]; + else type = [[type]]; + _flash.call('addFileTypes', type); + }; + + /** + * 设置文件类型,支持macType + * @public + * @param {Object|Array[Object]} type {description:String, extention:String} + * @return {Null}; + */ + me.setFileType = function(type){ + var type = type || [[]]; + + if(type instanceof Array) type = [type]; + else type = [[type]]; + _flash.call('setFileTypes', type); + }; + + /** + * 设置可选文件的数量限制 + * @public + * @param {Number} num + * @return {Null} + */ + me.setMaxNum = function(num){ + _flash.call('setMaxNum', [num]); + }; + + /** + * 设置可选文件大小限制,以兆M为单位 + * @public + * @param {Number} num,0为无限制 + * @return {Null} + */ + me.setMaxSize = function(num){ + _flash.call('setMaxSize', [num]); + }; + + /** + * @public + */ + me.getFileAll = function(callBack){ + _flash.call('getFileAll', [], callBack); + }; + + /** + * @public + * @param {Number} index + * @param {Function} [callBack] + */ + me.getFileByIndex = function(index, callBack){ + _flash.call('getFileByIndex', [], callBack); + }; + + /** + * @public + * @param {Number} index + * @param {function} [callBack] + */ + me.getStatusByIndex = function(index, callBack){ + _flash.call('getStatusByIndex', [], callBack); + }; +}; + +/** + * 使用动态script标签请求服务器资源,包括由服务器端的回调和浏览器端的回调 + * @namespace baidu.sio + */ +baidu.sio = baidu.sio || {}; + +/** + * + * @param {HTMLElement} src script节点 + * @param {String} url script节点的地址 + * @param {String} [charset] 编码 + */ +baidu.sio._createScriptTag = function(scr, url, charset){ + scr.setAttribute('type', 'text/javascript'); + charset && scr.setAttribute('charset', charset); + scr.setAttribute('src', url); + document.getElementsByTagName('head')[0].appendChild(scr); +}; + +/** + * 删除script的属性,再删除script标签,以解决修复内存泄漏的问题 + * + * @param {HTMLElement} src script节点 + */ +baidu.sio._removeScriptTag = function(scr){ + if (scr.clearAttributes) { + scr.clearAttributes(); + } else { + for (var attr in scr) { + if (scr.hasOwnProperty(attr)) { + delete scr[attr]; + } + } + } + if(scr && scr.parentNode){ + scr.parentNode.removeChild(scr); + } + scr = null; +}; + + +/** + * 通过script标签加载数据,加载完成由浏览器端触发回调 + * @name baidu.sio.callByBrowser + * @function + * @grammar baidu.sio.callByBrowser(url, opt_callback, opt_options) + * @param {string} url 加载数据的url + * @param {Function|string} opt_callback 数据加载结束时调用的函数或函数名 + * @param {Object} opt_options 其他可选项 + * @config {String} [charset] script的字符集 + * @config {Integer} [timeOut] 超时时间,超过这个时间将不再响应本请求,并触发onfailure函数 + * @config {Function} [onfailure] timeOut设定后才生效,到达超时时间时触发本函数 + * @remark + * 1、与callByServer不同,callback参数只支持Function类型,不支持string。 + * 2、如果请求了一个不存在的页面,callback函数在IE/opera下也会被调用,因此使用者需要在onsuccess函数中判断数据是否正确加载。 + * @meta standard + * @see baidu.sio.callByServer + */ +baidu.sio.callByBrowser = function (url, opt_callback, opt_options) { + var scr = document.createElement("SCRIPT"), + scriptLoaded = 0, + options = opt_options || {}, + charset = options['charset'], + callback = opt_callback || function(){}, + timeOut = options['timeOut'] || 0, + timer; + scr.onload = scr.onreadystatechange = function () { + if (scriptLoaded) { + return; + } + + var readyState = scr.readyState; + if ('undefined' == typeof readyState + || readyState == "loaded" + || readyState == "complete") { + scriptLoaded = 1; + try { + callback(); + clearTimeout(timer); + } finally { + scr.onload = scr.onreadystatechange = null; + baidu.sio._removeScriptTag(scr); + } + } + }; + + if( timeOut ){ + timer = setTimeout(function(){ + scr.onload = scr.onreadystatechange = null; + baidu.sio._removeScriptTag(scr); + options.onfailure && options.onfailure(); + }, timeOut); + } + + baidu.sio._createScriptTag(scr, url, charset); +}; + +/** + * 通过script标签加载数据,加载完成由服务器端触发回调 + * @name baidu.sio.callByServer + * @function + * @grammar baidu.sio.callByServer(url, callback[, opt_options]) + * @param {string} url 加载数据的url. + * @param {Function|string} callback 服务器端调用的函数或函数名。如果没有指定本参数,将在URL中寻找options['queryField']做为callback的方法名. + * @param {Object} opt_options 加载数据时的选项. + * @config {string} [charset] script的字符集 + * @config {string} [queryField] 服务器端callback请求字段名,默认为callback + * @config {Integer} [timeOut] 超时时间(单位:ms),超过这个时间将不再响应本请求,并触发onfailure函数 + * @config {Function} [onfailure] timeOut设定后才生效,到达超时时间时触发本函数 + * @remark + * 如果url中已经包含key为“options['queryField']”的query项,将会被替换成callback中参数传递或自动生成的函数名。 + * @meta standard + * @see baidu.sio.callByBrowser + */ +baidu.sio.callByServer = /**@function*/function(url, callback, opt_options) { + var scr = document.createElement('SCRIPT'), + prefix = 'bd__cbs__', + callbackName, + callbackImpl, + options = opt_options || {}, + charset = options['charset'], + queryField = options['queryField'] || 'callback', + timeOut = options['timeOut'] || 0, + timer, + reg = new RegExp('(\\?|&)' + queryField + '=([^&]*)'), + matches; + + if (baidu.lang.isFunction(callback)) { + callbackName = prefix + Math.floor(Math.random() * 2147483648).toString(36); + window[callbackName] = getCallBack(0); + } else if(baidu.lang.isString(callback)){ + callbackName = callback; + } else { + if (matches = reg.exec(url)) { + callbackName = matches[2]; + } + } + + if( timeOut ){ + timer = setTimeout(getCallBack(1), timeOut); + } + url = url.replace(reg, '\x241' + queryField + '=' + callbackName); + + if (url.search(reg) < 0) { + url += (url.indexOf('?') < 0 ? '?' : '&') + queryField + '=' + callbackName; + } + baidu.sio._createScriptTag(scr, url, charset); + + /* + * 返回一个函数,用于立即(挂在window上)或者超时(挂在setTimeout中)时执行 + */ + function getCallBack(onTimeOut){ + /*global callbackName, callback, scr, options;*/ + return function(){ + try { + if( onTimeOut ){ + options.onfailure && options.onfailure(); + }else{ + callback.apply(window, arguments); + clearTimeout(timer); + } + window[callbackName] = null; + delete window[callbackName]; + } catch (exception) { + } finally { + baidu.sio._removeScriptTag(scr); + } + } + } +}; + +/** + * 通过请求一个图片的方式令服务器存储一条日志 + * @function + * @grammar baidu.sio.log(url) + * @param {string} url 要发送的地址. + * @author: int08h,leeight + */ +baidu.sio.log = function(url) { + var img = new Image(), + key = 'tangram_sio_log_' + Math.floor(Math.random() * + 2147483648).toString(36); + window[key] = img; + + img.onload = img.onerror = img.onabort = function() { + img.onload = img.onerror = img.onabort = null; + + window[key] = null; + img = null; + }; + img.src = url; +}; + + + +/* + * Tangram + * Copyright 2009 Baidu Inc. All rights reserved. + * + * path: baidu/json.js + * author: erik + * version: 1.1.0 + * date: 2009/12/02 + */ + + +/** + * 操作json对象的方法 + * @namespace baidu.json + */ +baidu.json = baidu.json || {}; +/* + * Tangram + * Copyright 2009 Baidu Inc. All rights reserved. + * + * path: baidu/json/parse.js + * author: erik, berg + * version: 1.2 + * date: 2009/11/23 + */ + + + +/** + * 将字符串解析成json对象。注:不会自动祛除空格 + * @name baidu.json.parse + * @function + * @grammar baidu.json.parse(data) + * @param {string} source 需要解析的字符串 + * @remark + * 该方法的实现与ecma-262第五版中规定的JSON.parse不同,暂时只支持传入一个参数。后续会进行功能丰富。 + * @meta standard + * @see baidu.json.stringify,baidu.json.decode + * + * @returns {JSON} 解析结果json对象 + */ +baidu.json.parse = function (data) { + //2010/12/09:更新至不使用原生parse,不检测用户输入是否正确 + return (new Function("return (" + data + ")"))(); +}; +/* + * Tangram + * Copyright 2009 Baidu Inc. All rights reserved. + * + * path: baidu/json/decode.js + * author: erik, cat + * version: 1.3.4 + * date: 2010/12/23 + */ + + + +/** + * 将字符串解析成json对象,为过时接口,今后会被baidu.json.parse代替 + * @name baidu.json.decode + * @function + * @grammar baidu.json.decode(source) + * @param {string} source 需要解析的字符串 + * @meta out + * @see baidu.json.encode,baidu.json.parse + * + * @returns {JSON} 解析结果json对象 + */ +baidu.json.decode = baidu.json.parse; +/* + * Tangram + * Copyright 2009 Baidu Inc. All rights reserved. + * + * path: baidu/json/stringify.js + * author: erik + * version: 1.1.0 + * date: 2010/01/11 + */ + + + +/** + * 将json对象序列化 + * @name baidu.json.stringify + * @function + * @grammar baidu.json.stringify(value) + * @param {JSON} value 需要序列化的json对象 + * @remark + * 该方法的实现与ecma-262第五版中规定的JSON.stringify不同,暂时只支持传入一个参数。后续会进行功能丰富。 + * @meta standard + * @see baidu.json.parse,baidu.json.encode + * + * @returns {string} 序列化后的字符串 + */ +baidu.json.stringify = (function () { + /** + * 字符串处理时需要转义的字符表 + * @private + */ + var escapeMap = { + "\b": '\\b', + "\t": '\\t', + "\n": '\\n', + "\f": '\\f', + "\r": '\\r', + '"' : '\\"', + "\\": '\\\\' + }; + + /** + * 字符串序列化 + * @private + */ + function encodeString(source) { + if (/["\\\x00-\x1f]/.test(source)) { + source = source.replace( + /["\\\x00-\x1f]/g, + function (match) { + var c = escapeMap[match]; + if (c) { + return c; + } + c = match.charCodeAt(); + return "\\u00" + + Math.floor(c / 16).toString(16) + + (c % 16).toString(16); + }); + } + return '"' + source + '"'; + } + + /** + * 数组序列化 + * @private + */ + function encodeArray(source) { + var result = ["["], + l = source.length, + preComma, i, item; + + for (i = 0; i < l; i++) { + item = source[i]; + + switch (typeof item) { + case "undefined": + case "function": + case "unknown": + break; + default: + if(preComma) { + result.push(','); + } + result.push(baidu.json.stringify(item)); + preComma = 1; + } + } + result.push("]"); + return result.join(""); + } + + /** + * 处理日期序列化时的补零 + * @private + */ + function pad(source) { + return source < 10 ? '0' + source : source; + } + + /** + * 日期序列化 + * @private + */ + function encodeDate(source){ + return '"' + source.getFullYear() + "-" + + pad(source.getMonth() + 1) + "-" + + pad(source.getDate()) + "T" + + pad(source.getHours()) + ":" + + pad(source.getMinutes()) + ":" + + pad(source.getSeconds()) + '"'; + } + + return function (value) { + switch (typeof value) { + case 'undefined': + return 'undefined'; + + case 'number': + return isFinite(value) ? String(value) : "null"; + + case 'string': + return encodeString(value); + + case 'boolean': + return String(value); + + default: + if (value === null) { + return 'null'; + } else if (value instanceof Array) { + return encodeArray(value); + } else if (value instanceof Date) { + return encodeDate(value); + } else { + var result = ['{'], + encode = baidu.json.stringify, + preComma, + item; + + for (var key in value) { + if (Object.prototype.hasOwnProperty.call(value, key)) { + item = value[key]; + switch (typeof item) { + case 'undefined': + case 'unknown': + case 'function': + break; + default: + if (preComma) { + result.push(','); + } + preComma = 1; + result.push(encode(key) + ':' + encode(item)); + } + } + } + result.push('}'); + return result.join(''); + } + } + }; +})(); +/* + * Tangram + * Copyright 2009 Baidu Inc. All rights reserved. + * + * path: baidu/json/encode.js + * author: erik, cat + * version: 1.3.4 + * date: 2010/12/23 + */ + + + +/** + * 将json对象序列化,为过时接口,今后会被baidu.json.stringify代替 + * @name baidu.json.encode + * @function + * @grammar baidu.json.encode(value) + * @param {JSON} value 需要序列化的json对象 + * @meta out + * @see baidu.json.decode,baidu.json.stringify + * + * @returns {string} 序列化后的字符串 + */ +baidu.json.encode = baidu.json.stringify; diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/wordimage/wordimage.html b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/wordimage/wordimage.html new file mode 100644 index 000000000..6cf606741 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/wordimage/wordimage.html @@ -0,0 +1,111 @@ + + + + + + + + + +
          +
          + +
          +
          +
          +
          +
          + +
          + : +
          +
          +
          + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/wordimage/wordimage.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/wordimage/wordimage.js new file mode 100644 index 000000000..98f3a2264 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/dialogs/wordimage/wordimage.js @@ -0,0 +1,157 @@ +/** + * Created by JetBrains PhpStorm. + * User: taoqili + * Date: 12-1-30 + * Time: 下午12:50 + * To change this template use File | Settings | File Templates. + */ + + + +var wordImage = {}; +//(function(){ +var g = baidu.g, + flashObj,flashContainer; + +wordImage.init = function(opt, callbacks) { + showLocalPath("localPath"); + //createCopyButton("clipboard","localPath"); + createFlashUploader(opt, callbacks); + addUploadListener(); + addOkListener(); +}; + +function hideFlash(){ + flashObj = null; + flashContainer.innerHTML = ""; +} +function addOkListener() { + dialog.onok = function() { + if (!imageUrls.length) return; + var urlPrefix = editor.getOpt('imageUrlPrefix'), + images = domUtils.getElementsByTagName(editor.document,"img"); + editor.fireEvent('saveScene'); + for (var i = 0,img; img = images[i++];) { + var src = img.getAttribute("word_img"); + if (!src) continue; + for (var j = 0,url; url = imageUrls[j++];) { + if (src.indexOf(url.original.replace(" ","")) != -1) { + img.src = urlPrefix + url.url; + img.setAttribute("_src", urlPrefix + url.url); //同时修改"_src"属性 + img.setAttribute("title",url.title); + domUtils.removeAttributes(img, ["word_img","style","width","height"]); + editor.fireEvent("selectionchange"); + break; + } + } + } + editor.fireEvent('saveScene'); + hideFlash(); + }; + dialog.oncancel = function(){ + hideFlash(); + } +} + +/** + * 绑定开始上传事件 + */ +function addUploadListener() { + g("upload").onclick = function () { + flashObj.upload(); + this.style.display = "none"; + }; +} + +function showLocalPath(id) { + //单张编辑 + var img = editor.selection.getRange().getClosedNode(); + var images = editor.execCommand('wordimage'); + if(images.length==1 || img && img.tagName == 'IMG'){ + g(id).value = images[0]; + return; + } + var path = images[0]; + var leftSlashIndex = path.lastIndexOf("/")||0, //不同版本的doc和浏览器都可能影响到这个符号,故直接判断两种 + rightSlashIndex = path.lastIndexOf("\\")||0, + separater = leftSlashIndex > rightSlashIndex ? "/":"\\" ; + + path = path.substring(0, path.lastIndexOf(separater)+1); + g(id).value = path; +} + +function createFlashUploader(opt, callbacks) { + //由于lang.flashI18n是静态属性,不可以直接进行修改,否则会影响到后续内容 + var i18n = utils.extend({},lang.flashI18n); + //处理图片资源地址的编码,补全等问题 + for(var i in i18n){ + if(!(i in {"lang":1,"uploadingTF":1,"imageTF":1,"textEncoding":1}) && i18n[i]){ + i18n[i] = encodeURIComponent(editor.options.langPath + editor.options.lang + "/images/" + i18n[i]); + } + } + opt = utils.extend(opt,i18n,false); + var option = { + createOptions:{ + id:'flash', + url:opt.flashUrl, + width:opt.width, + height:opt.height, + errorMessage:lang.flashError, + wmode:browser.safari ? 'transparent' : 'window', + ver:'10.0.0', + vars:opt, + container:opt.container + } + }; + + option = extendProperty(callbacks, option); + flashObj = new baidu.flash.imageUploader(option); + flashContainer = $G(opt.container); +} + +function extendProperty(fromObj, toObj) { + for (var i in fromObj) { + if (!toObj[i]) { + toObj[i] = fromObj[i]; + } + } + return toObj; +} + +//})(); + +function getPasteData(id) { + baidu.g("msg").innerHTML = lang.copySuccess + "
          "; + setTimeout(function() { + baidu.g("msg").innerHTML = ""; + }, 5000); + return baidu.g(id).value; +} + +function createCopyButton(id, dataFrom) { + baidu.swf.create({ + id:"copyFlash", + url:"fClipboard_ueditor.swf", + width:"58", + height:"25", + errorMessage:"", + bgColor:"#CBCBCB", + wmode:"transparent", + ver:"10.0.0", + vars:{ + tid:dataFrom + } + }, id + ); + + var clipboard = baidu.swf.getMovie("copyFlash"); + var clipinterval = setInterval(function() { + if (clipboard && clipboard.flashInit) { + clearInterval(clipinterval); + clipboard.setHandCursor(true); + clipboard.setContentFuncName("getPasteData"); + //clipboard.setMEFuncName("mouseEventHandler"); + } + }, 500); +} +createCopyButton("clipboard", "localPath"); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/editor_config.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/editor_config.js new file mode 100644 index 000000000..5b59720f9 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/editor_config.js @@ -0,0 +1,200 @@ +! function () { + function e(e, l) { + return t(e || self.document.URL || self.location.href, l || s()) + } + + function s() { + var e = document.getElementsByTagName("script"); + return e[e.length - 1].src + } + + function t(e, s) { + var t = s; + return /^(\/|\\\\)/.test(s) ? t = /^.+?\w(\/|\\\\)/.exec(e)[0] + s.replace(/^(\/|\\\\)/, "") : /^[a-z]+:/i.test(s) || (e = e.split("#")[0].split("?")[0].replace(/[^\\\/]+$/, ""), t = e + "" + s), l(t) + } + + function l(e) { + var s = /^[a-z]+:\/\//.exec(e)[0], + t = null, + l = []; + for (e = e.replace(s, "").split("?")[0].split("#")[0], e = e.replace(/\\/g, "/").split(/\//), e[e.length - 1] = ""; e.length;) ".." === (t = e.shift()) ? l.pop() : "." !== t && l.push(t); + return s + l.join("/") + } + var a = window.UEDITOR_HOME_URL || e(); + window.UEDITOR_CONFIG = { + UEDITOR_HOME_URL: a, + serverUrl: window.UEDITOR_CONTROLLER_URL, + toolbars: [ + ["fullscreen", + "source", + "|", + "undo", + "redo", + "|", + "bold", + "italic", + "underline", + "fontborder", + "strikethrough", + "superscript", + "subscript", + "removeformat", + "formatmatch", + "autotypeset", + "blockquote", + "pasteplain", + "|", + "forecolor", + "backcolor", + "insertorderedlist", + "insertunorderedlist", + "selectall", + "cleardoc", + "|", + "rowspacingtop", + "rowspacingbottom", + "lineheight", + "|", + "customstyle", + "paragraph", + "fontfamily", + "fontsize", + "|", + "directionalityltr", + "directionalityrtl", + "indent", + "|", + "justifyleft", + "justifycenter", + "justifyright", + "justifyjustify", + "|", + "touppercase", + "tolowercase", + "|", + "link", + "unlink", + "anchor", + "|", + "imagenone", + "imageleft", + "imageright", + "imagecenter", + "|", + "simpleupload", + "insertimage", + "emotion", + "scrawl", + "attachment", + "map", + "insertframe", + "insertcode", + "template", + "background", + "|", + "horizontal", + "date", + "time", + "spechars", + "wordimage", + "|", + "inserttable", + "deletetable", + "insertparagraphbeforetable", + "insertrow", + "deleterow", + "insertcol", + "deletecol", + "mergecells", + "mergeright", + "mergedown", + "splittocells", + "splittorows", + "splittocols", + "charts", + "|", + "print", + "preview", + "searchreplace", + "pagebreak" + ] + ], + initialFrameHeight: 320, + enableAutoSave: !1, + saveInterval: 9999999999999, + allHtmlEnabled: !1, + pageBreakTag: "[SITESERVER_PAGE]", + xssFilterRules: false, + inputXssFilter: false, + outputXssFilter: false, + whitList: { + a: ["target", "href", "title", "class", "style", "name"], + abbr: ["title", "class", "style"], + address: ["class", "style"], + area: ["shape", "coords", "href", "alt"], + article: [], + aside: [], + audio: ["autoplay", "controls", "loop", "preload", "src", "class", "style"], + b: ["class", "style"], + bdi: ["dir"], + bdo: ["dir"], + big: [], + blockquote: ["cite", "class", "style"], + br: [], + caption: ["class", "style"], + center: [], + cite: [], + code: ["class", "style"], + col: ["align", "valign", "span", "width", "class", "style"], + colgroup: ["align", "valign", "span", "width", "class", "style"], + dd: ["class", "style"], + del: ["datetime"], + details: ["open"], + div: ["class", "style"], + dl: ["class", "style"], + dt: ["class", "style"], + em: ["class", "style"], + font: ["color", "size", "face"], + footer: [], + h1: ["class", "style"], + h2: ["class", "style"], + h3: ["class", "style"], + h4: ["class", "style"], + h5: ["class", "style"], + h6: ["class", "style"], + header: [], + hr: [], + i: ["class", "style"], + img: ["src", "alt", "title", "width", "height", "id", "_src", "_url", "loadingclass", "class", "data-latex", "word_img", "style", "anchorname"], + ins: ["datetime"], + li: ["class", "style"], + mark: [], + nav: [], + ol: ["class", "style"], + p: ["class", "style"], + pre: ["class", "style"], + s: [], + section: [], + small: [], + span: ["class", "style"], + sub: ["class", "style"], + sup: ["class", "style"], + strong: ["class", "style"], + table: ["width", "border", "align", "valign", "class", "style"], + tbody: ["align", "valign", "class", "style"], + td: ["width", "rowspan", "colspan", "align", "valign", "class", "style"], + tfoot: ["align", "valign", "class", "style"], + th: ["width", "rowspan", "colspan", "align", "valign", "class", "style"], + thead: ["align", "valign", "class", "style"], + tr: ["rowspan", "align", "valign", "class", "style"], + tt: [], + u: [], + ul: ["class", "style"], + video: ["autoplay", "controls", "loop", "preload", "src", "height", "width", "class", "style"], + source: ["src", "type"], + embed: ["type", "class", "pluginspage", "src", "width", "height", "align", "style", "wmode", "play", "loop", "menu", "allowscriptaccess", "allowfullscreen"] + } + }, window.UE = { + getUEBasePath: e + } +}(); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/en.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/en.js new file mode 100644 index 000000000..c7e22f5b4 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/en.js @@ -0,0 +1,684 @@ +/** + * Created with JetBrains PhpStorm. + * User: taoqili + * Date: 12-6-12 + * Time: 下午6:57 + * To change this template use File | Settings | File Templates. + */ +UE.I18N['en'] = { + 'labelMap':{ + 'anchor':'Anchor', 'undo':'Undo', 'redo':'Redo', 'bold':'Bold', 'indent':'Indent', 'snapscreen':'SnapScreen', + 'italic':'Italic', 'underline':'Underline', 'strikethrough':'Strikethrough', 'subscript':'SubScript','fontborder':'text border', + 'superscript':'SuperScript', 'formatmatch':'Format Match', 'source':'Source', 'blockquote':'BlockQuote', + 'pasteplain':'PastePlain', 'selectall':'SelectAll', 'print':'Print', 'preview':'Preview', + 'horizontal':'Horizontal', 'removeformat':'RemoveFormat', 'time':'Time', 'date':'Date', + 'unlink':'Unlink', 'insertrow':'InsertRow', 'insertcol':'InsertCol', 'mergeright':'MergeRight', 'mergedown':'MergeDown', + 'deleterow':'DeleteRow', 'deletecol':'DeleteCol', 'splittorows':'SplitToRows','insertcode':'insert code', + 'splittocols':'SplitToCols', 'splittocells':'SplitToCells','deletecaption':'DeleteCaption','inserttitle':'InsertTitle', + 'mergecells':'MergeCells', 'deletetable':'DeleteTable', 'cleardoc':'Clear', 'insertparagraphbeforetable':"InsertParagraphBeforeTable", + 'fontfamily':'FontFamily', 'fontsize':'FontSize', 'paragraph':'Paragraph','simpleupload':'Single Image','insertimage':'Multi Image','edittable':'Edit Table', 'edittd':'Edit Td','link':'Link', + 'emotion':'Emotion', 'spechars':'Spechars', 'searchreplace':'SearchReplace', 'map':'BaiduMap', 'gmap':'GoogleMap', + 'insertvideo':'Video', 'help':'Help', 'justifyleft':'JustifyLeft', 'justifyright':'JustifyRight', 'justifycenter':'JustifyCenter', + 'justifyjustify':'Justify', 'forecolor':'FontColor', 'backcolor':'BackColor', 'insertorderedlist':'OL', + 'insertunorderedlist':'UL', 'fullscreen':'FullScreen', 'directionalityltr':'EnterFromLeft', 'directionalityrtl':'EnterFromRight', + 'rowspacingtop':'RowSpacingTop', 'rowspacingbottom':'RowSpacingBottom', 'pagebreak':'PageBreak', 'insertframe':'Iframe', 'imagenone':'Default', + 'imageleft':'ImageLeft', 'imageright':'ImageRight', 'attachment':'Attachment', 'imagecenter':'ImageCenter', 'wordimage':'WordImage', + 'lineheight':'LineHeight','edittip':'EditTip','customstyle':'CustomStyle', 'scrawl':'Scrawl', 'autotypeset':'AutoTypeset', + 'webapp':'WebAPP', 'touppercase':'UpperCase', 'tolowercase':'LowerCase','template':'Template','background':'Background','inserttable':'InsertTable', + 'music':'Music', 'charts': 'charts','drafts': 'Load from Drafts' + }, + 'insertorderedlist':{ + 'num':'1,2,3...', + 'num1':'1),2),3)...', + 'num2':'(1),(2),(3)...', + 'cn':'一,二,三....', + 'cn1':'一),二),三)....', + 'cn2':'(一),(二),(三)....', + 'decimal':'1,2,3...', + 'lower-alpha':'a,b,c...', + 'lower-roman':'i,ii,iii...', + 'upper-alpha':'A,B,C...', + 'upper-roman':'I,II,III...' + }, + 'insertunorderedlist':{ + 'circle':'○ Circle', + 'disc':'● Circle dot', + 'square':'■ Rectangle ', + 'dash' :'- Dash', + 'dot' : '。dot' + }, + 'paragraph':{'p':'Paragraph', 'h1':'Title 1', 'h2':'Title 2', 'h3':'Title 3', 'h4':'Title 4', 'h5':'Title 5', 'h6':'Title 6'}, + 'fontfamily':{ + 'songti':'Sim Sun', + 'kaiti':'Sim Kai', + 'heiti':'Sim Hei', + 'lishu':'Sim Li', + 'yahei': 'Microsoft YaHei', + 'andaleMono':'Andale Mono', + 'arial': 'Arial', + 'arialBlack':'Arial Black', + 'comicSansMs':'Comic Sans MS', + 'impact':'Impact', + 'timesNewRoman':'Times New Roman' + }, + 'customstyle':{ + 'tc':'Title center', + 'tl':'Title left', + 'im':'Important', + 'hi':'Highlight' + }, + 'autoupload': { + 'exceedSizeError': 'File Size Exceed', + 'exceedTypeError': 'File Type Not Allow', + 'jsonEncodeError': 'Server Return Format Error', + 'loading':"loading...", + 'loadError':"load error", + 'errorLoadConfig': 'Server config not loaded, upload can not work.', + }, + 'simpleupload':{ + 'exceedSizeError': 'File Size Exceed', + 'exceedTypeError': 'File Type Not Allow', + 'jsonEncodeError': 'Server Return Format Error', + 'loading':"loading...", + 'loadError':"load error", + 'errorLoadConfig': 'Server config not loaded, upload can not work.', + }, + 'elementPathTip':"Path", + 'wordCountTip':"Word Count", + 'wordCountMsg':'{#count} characters entered,{#leave} left. ', + 'wordOverFlowMsg':'The number of characters has exceeded allowable maximum values, the server may refuse to save!', + 'ok':"OK", + 'cancel':"Cancel", + 'closeDialog':"closeDialog", + 'tableDrag':"You must import the file uiUtils.js before drag! ", + 'autofloatMsg':"The plugin AutoFloat depends on EditorUI!", + 'loadconfigError': 'Get server config error.', + 'loadconfigFormatError': 'Server config format error.', + 'loadconfigHttpError': 'Get server config http error.', + 'snapScreen_plugin':{ + 'browserMsg':"Only IE supported!", + 'callBackErrorMsg':"The callback data is wrong,please check the config!", + 'uploadErrorMsg':"Upload error,please check your server environment! " + }, + 'insertcode':{ + 'as3':'ActionScript 3', + 'bash':'Bash/Shell', + 'cpp':'C/C++', + 'css':'CSS', + 'cf':'ColdFusion', + 'c#':'C#', + 'delphi':'Delphi', + 'diff':'Diff', + 'erlang':'Erlang', + 'groovy':'Groovy', + 'html':'HTML', + 'java':'Java', + 'jfx':'JavaFX', + 'js':'JavaScript', + 'pl':'Perl', + 'php':'PHP', + 'plain':'Plain Text', + 'ps':'PowerShell', + 'python':'Python', + 'ruby':'Ruby', + 'scala':'Scala', + 'sql':'SQL', + 'vb':'Visual Basic', + 'xml':'XML' + }, + 'confirmClear':"Do you confirm to clear the Document?", + 'contextMenu':{ + 'delete':"Delete", + 'selectall':"Select all", + 'deletecode':"Delete Code", + 'cleardoc':"Clear Document", + 'confirmclear':"Do you confirm to clear the Document?", + 'unlink':"Unlink", + 'paragraph':"Paragraph", + 'edittable':"Table property", + 'aligncell':'Align cell', + 'aligntable':'Table alignment', + 'tableleft':'Left float', + 'tablecenter':'Center', + 'tableright':'Right float', + 'aligntd':'Cell alignment', + 'edittd':"Cell property", + 'setbordervisible':'set table edge visible', + 'table':"Table", + 'justifyleft':'Justify Left', + 'justifyright':'Justify Right', + 'justifycenter':'Justify Center', + 'justifyjustify':'Default', + 'deletetable':"Delete table", + 'insertparagraphbefore':"InsertedBeforeLine", + 'insertparagraphafter':'InsertedAfterLine', + 'inserttable':'Insert table', + 'insertcaption':'Insert caption', + 'deletecaption':'Delete Caption', + 'inserttitle':'Insert Title', + 'deletetitle':'Delete Title', + 'inserttitlecol':'Insert Title Col', + 'deletetitlecol':'Delete Title Col', + 'averageDiseRow':'AverageDise Row', + 'averageDisCol':'AverageDis Col', + 'deleterow':"Delete row", + 'deletecol':"Delete col", + 'insertrow':"Insert row", + 'insertcol':"Insert col", + 'insertrownext':'Insert Row Next', + 'insertcolnext':'Insert Col Next', + 'mergeright':"Merge right", + 'mergeleft':"Merge left", + 'mergedown':"Merge down", + 'mergecells':"Merge cells", + 'splittocells':"Split to cells", + 'splittocols':"Split to Cols", + 'splittorows':"Split to Rows", + 'tablesort':'Table sorting', + 'enablesort':'Sorting Enable', + 'disablesort':'Sorting Disable', + 'reversecurrent':'Reverse current', + 'orderbyasc':'Order By ASCII', + 'reversebyasc':'Reverse By ASCII', + 'orderbynum':'Order By Num', + 'reversebynum':'Reverse By Num', + 'borderbk':'Border shading', + 'setcolor':'interlaced color', + 'unsetcolor':'Cancel interlacedcolor', + 'setbackground':'Background interlaced', + 'unsetbackground':'Cancel Bk interlaced', + 'redandblue':'Blue and red', + 'threecolorgradient':'Three-color gradient', + 'copy':"Copy(Ctrl + c)", + 'copymsg':"Browser does not support. Please use 'Ctrl + c' instead!", + 'paste':"Paste(Ctrl + v)", + 'pastemsg':"Browser does not support. Please use 'Ctrl + v' instead!" + }, + 'copymsg': "Browser does not support. Please use 'Ctrl + c' instead!", + 'pastemsg': "Browser does not support. Please use 'Ctrl + v' instead!", + 'anthorMsg':"Link", + 'clearColor':'Clear', + 'standardColor':'Standard color', + 'themeColor':'Theme color', + 'property':'Property', + 'default':'Default', + 'modify':'Modify', + 'justifyleft':'Justify Left', + 'justifyright':'Justify Right', + 'justifycenter':'Justify Center', + 'justify':'Default', + 'clear':'Clear', + 'anchorMsg':'Anchor', + 'delete':'Delete', + 'clickToUpload':"Click to upload", + 'unset':'Language hasn\'t been set!', + 't_row':'row', + 't_col':'col', + 'pasteOpt':'Paste Option', + 'pasteSourceFormat':"Keep Source Formatting", + 'tagFormat':'Keep tag', + 'pasteTextFormat':'Keep Text only', + 'more':'More', + 'autoTypeSet':{ + 'mergeLine':"Merge empty line", + 'delLine':"Del empty line", + 'removeFormat':"Remove format", + 'indent':"Indent", + 'alignment':"Alignment", + 'imageFloat':"Image float", + 'removeFontsize':"Remove font size", + 'removeFontFamily':"Remove fontFamily", + 'removeHtml':"Remove redundant HTML code", + 'pasteFilter':"Paste filter", + 'run':"Done", + 'symbol':'Symbol Conversion', + 'bdc2sb':'Full-width to Half-width', + 'tobdc':'Half-width to Full-width' + }, + + 'background':{ + 'static':{ + 'lang_background_normal':'Normal', + 'lang_background_local':'Online', + 'lang_background_set':'Background Set', + 'lang_background_none':'No Background', + 'lang_background_colored':'Colored Background', + 'lang_background_color':'Color Set', + 'lang_background_netimg':'Net-Image', + 'lang_background_align':'Align Type', + 'lang_background_position':'Position', + 'repeatType':{'options':["Center", "Repeat-x", "Repeat-y", "Tile","Custom"]} + }, + 'noUploadImage':"No pictures has been uploaded!", + 'toggleSelect':'Change the active state by click!\n Image Size: ' + }, + //===============dialog i18N======================= + 'insertimage':{ + 'static':{ + 'lang_tab_remote':"Insert", + 'lang_tab_upload':"Local", + 'lang_tab_online':"Manager", + 'lang_tab_search':"Search", + 'lang_input_url':"Address:", + 'lang_input_size':"Size:", + 'lang_input_width':"Width", + 'lang_input_height':"Height", + 'lang_input_border':"Border:", + 'lang_input_vhspace':"Margins:", + 'lang_input_title':"Title:", + 'lang_input_align':'Image Float Style:', + 'lang_imgLoading':"Loading...", + 'lang_start_upload':"Start Upload", + 'lock':{'title':"Lock rate"}, + 'searchType':{'title':"ImageType", 'options':["News", "Wallpaper", "emotions", "photo"]}, + 'searchTxt':{'value':"Enter the search keyword!"}, + 'searchBtn':{'value':"Search"}, + 'searchReset':{'value':"Clear"}, + 'noneAlign':{'title':'None Float'}, + 'leftAlign':{'title':'Left Float'}, + 'rightAlign':{'title':'Right Float'}, + 'centerAlign':{'title':'Center In A Line'} + }, + 'uploadSelectFile':'Select File', + 'uploadAddFile':'Add File', + 'uploadStart':'Start Upload', + 'uploadPause':'Pause Upload', + 'uploadContinue':'Continue Upload', + 'uploadRetry':'Retry Upload', + 'uploadDelete':'Delete', + 'uploadTurnLeft':'Turn Left', + 'uploadTurnRight':'Turn Right', + 'uploadPreview':'Doing Preview', + 'uploadNoPreview':'Can Not Preview', + 'updateStatusReady': 'Selected _ pictures, total _KB.', + 'updateStatusConfirm': '_ uploaded successfully and _ upload failed', + 'updateStatusFinish': 'Total _ pictures (_KB), _ uploaded successfully', + 'updateStatusError': ' and _ upload failed', + 'errorNotSupport': 'WebUploader does not support the browser you are using. Please upgrade your browser or flash player', + 'errorLoadConfig': 'Server config not loaded, upload can not work.', + 'errorExceedSize':'File Size Exceed', + 'errorFileType':'File Type Not Allow', + 'errorInterrupt':'File Upload Interrupted', + 'errorUploadRetry':'Upload Error, Please Retry.', + 'errorHttp':'Http Error', + 'errorServerUpload':'Server Result Error.', + 'remoteLockError':"Cannot Lock the Proportion between width and height", + 'numError':"Please enter the correct Num. e.g 123,400", + 'imageUrlError':"The image format may be wrong!", + 'imageLoadError':"Error,please check the network or URL!", + 'searchRemind':"Enter the search keyword!", + 'searchLoading':"Image is loading,please wait...", + 'searchRetry':" Sorry,can't find the image,please try again!" + }, + 'attachment':{ + 'static':{ + 'lang_tab_upload': 'Upload', + 'lang_tab_online': 'Online', + 'lang_start_upload':"Start upload", + 'lang_drop_remind':"You can drop files here, a single maximum of 300 files" + }, + 'uploadSelectFile':'Select File', + 'uploadAddFile':'Add File', + 'uploadStart':'Start Upload', + 'uploadPause':'Pause Upload', + 'uploadContinue':'Continue Upload', + 'uploadRetry':'Retry Upload', + 'uploadDelete':'Delete', + 'uploadTurnLeft':'Turn Left', + 'uploadTurnRight':'Turn Right', + 'uploadPreview':'Doing Preview', + 'updateStatusReady': 'Selected _ files, total _KB.', + 'updateStatusConfirm': '_ uploaded successfully and _ upload failed', + 'updateStatusFinish': 'Total _ files (_KB), _ uploaded successfully', + 'updateStatusError': ' and _ upload failed', + 'errorNotSupport': 'WebUploader does not support the browser you are using. Please upgrade your browser or flash player', + 'errorLoadConfig': 'Server config not loaded, upload can not work.', + 'errorExceedSize':'File Size Exceed', + 'errorFileType':'File Type Not Allow', + 'errorInterrupt':'File Upload Interrupted', + 'errorUploadRetry':'Upload Error, Please Retry.', + 'errorHttp':'Http Error', + 'errorServerUpload':'Server Result Error.' + }, + + 'insertvideo':{ + 'static':{ + 'lang_tab_insertV':"Video", + 'lang_tab_searchV':"Search", + 'lang_tab_uploadV':"Upload", + 'lang_video_url':" URL ", + 'lang_video_size':"Video Size", + 'lang_videoW':"Width", + 'lang_videoH':"Height", + 'lang_alignment':"Alignment", + 'videoSearchTxt':{'value':"Enter the search keyword!"}, + 'videoType':{'options':["All", "Hot", "Entertainment", "Funny", "Sports", "Science", "variety"]}, + 'videoSearchBtn':{'value':"Search in Baidu"}, + 'videoSearchReset':{'value':"Clear result"}, + + 'lang_input_fileStatus':' No file uploaded!', + 'startUpload':{'style':"background:url(upload.png) no-repeat;"}, + + 'lang_upload_size':"Video Size", + 'lang_upload_width':"Width", + 'lang_upload_height':"Height", + 'lang_upload_alignment':"Alignment", + 'lang_format_advice':"Recommends mp4 format." + }, + 'numError':"Please enter the correct Num. e.g 123,400", + 'floatLeft':"Float left", + 'floatRight':"Float right", + 'default':"Default", + 'block':"Display in block", + 'urlError':"The video url format may be wrong!", + 'loading':"  The video is loading, please wait…", + 'clickToSelect':"Click to select", + 'goToSource':'Visit source video ', + 'noVideo':"    Sorry,can't find the video,please try again!", + + 'browseFiles':'Open files', + 'uploadSuccess':'Upload Successful!', + 'delSuccessFile':'Remove from the success of the queue', + 'delFailSaveFile':'Remove the save failed file', + 'statusPrompt':' file(s) uploaded! ', + 'flashVersionError':'The current Flash version is too low, please update FlashPlayer,then try again!', + 'flashLoadingError':'The Flash failed loading! Please check the path or network state', + 'fileUploadReady':'Wait for uploading...', + 'delUploadQueue':'Remove from the uploading queue ', + 'limitPrompt1':'Can not choose more than single', + 'limitPrompt2':'file(s)!Please choose again!', + 'delFailFile':'Remove failure file', + 'fileSizeLimit':'File size exceeds the limit!', + 'emptyFile':'Can not upload an empty file!', + 'fileTypeError':'File type error!', + 'unknownError':'Unknown error!', + 'fileUploading':'Uploading,please wait...', + 'cancelUpload':'Cancel upload', + 'netError':'Network error', + 'failUpload':'Upload failed', + 'serverIOError':'Server IO error!', + 'noAuthority':'No Permission!', + 'fileNumLimit':'Upload limit to the number', + 'failCheck':'Authentication fails, the upload is skipped!', + 'fileCanceling':'Cancel, please wait...', + 'stopUploading':'Upload has stopped...', + + 'uploadSelectFile':'Select File', + 'uploadAddFile':'Add File', + 'uploadStart':'Start Upload', + 'uploadPause':'Pause Upload', + 'uploadContinue':'Continue Upload', + 'uploadRetry':'Retry Upload', + 'uploadDelete':'Delete', + 'uploadTurnLeft':'Turn Left', + 'uploadTurnRight':'Turn Right', + 'uploadPreview':'Doing Preview', + 'updateStatusReady': 'Selected _ files, total _KB.', + 'updateStatusConfirm': '_ uploaded successfully and _ upload failed', + 'updateStatusFinish': 'Total _ files (_KB), _ uploaded successfully', + 'updateStatusError': ' and _ upload failed', + 'errorNotSupport': 'WebUploader does not support the browser you are using. Please upgrade your browser or flash player', + 'errorLoadConfig': 'Server config not loaded, upload can not work.', + 'errorExceedSize':'File Size Exceed', + 'errorFileType':'File Type Not Allow', + 'errorInterrupt':'File Upload Interrupted', + 'errorUploadRetry':'Upload Error, Please Retry.', + 'errorHttp':'Http Error', + 'errorServerUpload':'Server Result Error.' + }, + 'webapp':{ + 'tip1':"This function provided by Baidu APP,please apply for baidu APPKey webmaster first!", + 'tip2':"And then open the file ueditor.config.js to set it! ", + 'applyFor':"APPLY FOR", + 'anthorApi':"Baidu API" + }, + 'template':{ + 'static':{ + 'lang_template_bkcolor':'Background Color', + 'lang_template_clear' : 'Keep Content', + 'lang_template_select':'Select Template' + }, + 'blank':"Blank", + 'blog':"Blog", + 'resume':"Resume", + 'richText':"Rich Text", + 'scrPapers':"Scientific Papers" + }, + scrawl:{ + 'static':{ + 'lang_input_previousStep':"Previous", + 'lang_input_nextsStep':"Next", + 'lang_input_clear':'Clear', + 'lang_input_addPic':'AddImage', + 'lang_input_ScalePic':'ScaleImage', + 'lang_input_removePic':'RemoveImage', + 'J_imgTxt':{title:'Add background image'} + }, + 'noScarwl':"No paint, a white paper...", + 'scrawlUpLoading':"Image is uploading, please wait...", + 'continueBtn':"Try again", + 'imageError':"Image failed to load!", + 'backgroundUploading':'Image is uploading,please wait...' + }, + 'music':{ + 'static':{ + 'lang_input_tips':"Input singer/song/album, search you interested in music!", + 'J_searchBtn':{value:'Search songs'} + }, + 'emptyTxt':'Not search to the relevant music results, please change a keyword try.', + 'chapter':'Songs', + 'singer':'Singer', + 'special':'Album', + 'listenTest':'Audition' + }, + anchor:{ + 'static':{ + 'lang_input_anchorName':'Anchor Name:' + } + }, + 'charts':{ + 'static':{ + 'lang_data_source':'Data source:', + 'lang_chart_format': 'Chart format:', + 'lang_data_align': 'Align', + 'lang_chart_align_same': 'Consistent with the X-axis Y-axis', + 'lang_chart_align_reverse': 'X-axis Y-axis opposite', + 'lang_chart_title': 'Title', + 'lang_chart_main_title': 'main title:', + 'lang_chart_sub_title': 'sub title:', + 'lang_chart_x_title': 'X-axis title:', + 'lang_chart_y_title': 'Y-axis title:', + 'lang_chart_tip': 'Prompt', + 'lang_cahrt_tip_prefix': 'prefix:', + 'lang_cahrt_tip_description': '仅饼图有效, 当鼠标移动到饼图中相应的块上时,提示框内的文字的前缀', + 'lang_chart_data_unit': 'Unit', + 'lang_chart_data_unit_title': 'unit:', + 'lang_chart_data_unit_description': '显示在每个数据点上的数据的单位, 比如: 温度的单位 ℃', + 'lang_chart_type': 'Chart type:', + 'lang_prev_btn': 'Previous', + 'lang_next_btn': 'Next' + } + }, + emotion:{ + 'static':{ + 'lang_input_choice':'Choice', + 'lang_input_Tuzki':'Tuzki', + 'lang_input_lvdouwa':'LvDouWa', + 'lang_input_BOBO':'BOBO', + 'lang_input_babyCat':'BabyCat', + 'lang_input_bubble':'Bubble', + 'lang_input_youa':'YouA' + } + }, + gmap:{ + 'static':{ + 'lang_input_address':'Address:', + 'lang_input_search':'Search', + 'address':{value:"Beijing"} + }, + searchError:'Unable to locate the address!' + }, + help:{ + 'static':{ + 'lang_input_about':'About', + 'lang_input_shortcuts':'Shortcuts', + 'lang_input_introduction':"UEditor is developed by Baidu Co.ltd. It is lightweight, customizable , focusing on user experience and etc. , UEditor is based on open source BSD license , allowing free use and redistribution.", + 'lang_Txt_shortcuts':'Shortcuts', + 'lang_Txt_func':'Function', + 'lang_Txt_bold':'Bold', + 'lang_Txt_copy':'Copy', + 'lang_Txt_cut':'Cut', + 'lang_Txt_Paste':'Paste', + 'lang_Txt_undo':'Undo', + 'lang_Txt_redo':'Redo', + 'lang_Txt_italic':'Italic', + 'lang_Txt_underline':'Underline', + 'lang_Txt_selectAll':'Select All', + 'lang_Txt_visualEnter':'Submit', + 'lang_Txt_fullscreen':'Fullscreen' + } + }, + insertframe:{ + 'static':{ + 'lang_input_address':'Address:', + 'lang_input_width':'Width:', + 'lang_input_height':'height:', + 'lang_input_isScroll':'Enable scrollbars:', + 'lang_input_frameborder':'Show frame border:', + 'lang_input_alignMode':'Alignment:', + 'align':{title:"Alignment", options:["Default", "Left", "Right", "Center"]} + }, + 'enterAddress':'Please enter an address!' + }, + link:{ + 'static':{ + 'lang_input_text':'Text:', + 'lang_input_url':'URL:', + 'lang_input_title':'Title:', + 'lang_input_target':'open in new window:' + }, + 'validLink':'Supports only effective when a link is selected', + 'httpPrompt':'The hyperlink you enter should start with "http|https|ftp://"!' + }, + map:{ + 'static':{ + lang_city:"City", + lang_address:"Address", + city:{value:"Beijing"}, + lang_search:"Search", + lang_dynamicmap:"Dynamic map" + }, + cityMsg:"Please enter the city name!", + errorMsg:"Can't find the place!" + }, + searchreplace:{ + 'static':{ + lang_tab_search:"Search", + lang_tab_replace:"Replace", + lang_search1:"Search", + lang_search2:"Search", + lang_replace:"Replace", + lang_searchReg:'Support regular expression ,which starts and ends with a slash ,for example "/expression/"', + lang_searchReg1:'Support regular expression ,which starts and ends with a slash ,for example "/expression/"', + lang_case_sensitive1:"Case sense", + lang_case_sensitive2:"Case sense", + nextFindBtn:{value:"Next"}, + preFindBtn:{value:"Preview"}, + nextReplaceBtn:{value:"Next"}, + preReplaceBtn:{value:"Preview"}, + repalceBtn:{value:"Replace"}, + repalceAllBtn:{value:"Replace all"} + }, + getEnd:"Has the search to the bottom!", + getStart:"Has the search to the top!", + countMsg:"Altogether replaced {#count} character(s)!" + }, + snapscreen:{ + 'static':{ + lang_showMsg:"You should install the UEditor screenshots program first!", + lang_download:"Download!", + lang_step1:"Step1:Download the program and then run it", + lang_step2:"Step2:After complete install,try to click the button again" + } + }, + spechars:{ + 'static':{}, + tsfh:"Special", + lmsz:"Roman", + szfh:"Numeral", + rwfh:"Japanese", + xlzm:"The Greek", + ewzm:"Russian", + pyzm:"Phonetic", + yyyb:"English", + zyzf:"Others" + }, + 'edittable':{ + 'static':{ + 'lang_tableStyle':'Table style', + 'lang_insertCaption':'Add table header row', + 'lang_insertTitle':'Add table title row', + 'lang_insertTitleCol':'Add table title col', + 'lang_tableSize':'Automatically adjust table size', + 'lang_autoSizeContent':'Adaptive by form text', + 'lang_orderbycontent':"Table of contents sortable", + 'lang_autoSizePage':'Page width adaptive', + 'lang_example':'Example', + 'lang_borderStyle':'Table Border', + 'lang_color':'Color:' + }, + captionName:'Caption', + titleName:'Title', + cellsName:'text', + errorMsg:'There are merged cells, can not sort.' + }, + 'edittip':{ + 'static':{ + lang_delRow:'Delete entire row', + lang_delCol:'Delete entire col' + } + }, + 'edittd':{ + 'static':{ + lang_tdBkColor:'Background Color:' + } + }, + 'formula':{ + 'static':{ + } + }, + wordimage:{ + 'static':{ + lang_resave:"The re-save step", + uploadBtn:{src:"upload.png", alt:"Upload"}, + clipboard:{style:"background: url(copy.png) -153px -1px no-repeat;"}, + lang_step:" 1. Click top button to copy the url and then open the dialog to paste it. 2. Open after choose photos uploaded process." + }, + fileType:"Image", + flashError:"Flash initialization failed!", + netError:"Network error! Please try again!", + copySuccess:"URL has been copied!", + + 'flashI18n':{ + lang:encodeURI( '{"UploadingState":"totalNum: ${a},uploadComplete: ${b}", "BeforeUpload":"waitingNum: ${a}", "ExceedSize":"Size exceed${a}", "ErrorInPreview":"Preview failed", "DefaultDescription":"Description", "LoadingImage":"Loading..."}' ), + uploadingTF:encodeURI( '{"font":"Arial", "size":12, "color":"0x000", "bold":"true", "italic":"false", "underline":"false"}' ), + imageTF:encodeURI( '{"font":"Arial", "size":11, "color":"red", "bold":"false", "italic":"false", "underline":"false"}' ), + textEncoding:"utf-8", + addImageSkinURL:"addImage.png", + allDeleteBtnUpSkinURL:"allDeleteBtnUpSkin.png", + allDeleteBtnHoverSkinURL:"allDeleteBtnHoverSkin.png", + rotateLeftBtnEnableSkinURL:"rotateLeftEnable.png", + rotateLeftBtnDisableSkinURL:"rotateLeftDisable.png", + rotateRightBtnEnableSkinURL:"rotateRightEnable.png", + rotateRightBtnDisableSkinURL:"rotateRightDisable.png", + deleteBtnEnableSkinURL:"deleteEnable.png", + deleteBtnDisableSkinURL:"deleteDisable.png", + backgroundURL:'', + listBackgroundURL:'', + buttonURL:'button.png' + } + }, + 'autosave': { + 'success':'Local conservation success' + } +}; diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/addimage.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/addimage.png new file mode 100644 index 000000000..3a2fd1712 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/addimage.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/alldeletebtnhoverskin.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/alldeletebtnhoverskin.png new file mode 100644 index 000000000..355eeabbd Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/alldeletebtnhoverskin.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/alldeletebtnupskin.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/alldeletebtnupskin.png new file mode 100644 index 000000000..61658ce6f Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/alldeletebtnupskin.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/background.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/background.png new file mode 100644 index 000000000..d5bf5fdd8 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/background.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/button.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/button.png new file mode 100644 index 000000000..098874cb1 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/button.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/copy.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/copy.png new file mode 100644 index 000000000..f982e8bcb Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/copy.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/deletedisable.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/deletedisable.png new file mode 100644 index 000000000..c8ee75094 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/deletedisable.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/deleteenable.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/deleteenable.png new file mode 100644 index 000000000..26acc8835 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/deleteenable.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/listbackground.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/listbackground.png new file mode 100644 index 000000000..4f82ccd88 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/listbackground.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/localimage.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/localimage.png new file mode 100644 index 000000000..12c8e6aef Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/localimage.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/music.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/music.png new file mode 100644 index 000000000..2f495fe92 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/music.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/rotateleftdisable.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/rotateleftdisable.png new file mode 100644 index 000000000..741526e0d Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/rotateleftdisable.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/rotateleftenable.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/rotateleftenable.png new file mode 100644 index 000000000..e164ddbd6 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/rotateleftenable.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/rotaterightdisable.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/rotaterightdisable.png new file mode 100644 index 000000000..5a78c2606 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/rotaterightdisable.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/rotaterightenable.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/rotaterightenable.png new file mode 100644 index 000000000..d768531fc Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/rotaterightenable.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/upload.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/upload.png new file mode 100644 index 000000000..7bb15b3d6 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/en/images/upload.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/zh-cn/images/copy.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/zh-cn/images/copy.png new file mode 100644 index 000000000..b2536aac7 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/zh-cn/images/copy.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/zh-cn/images/localimage.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/zh-cn/images/localimage.png new file mode 100644 index 000000000..7303c3643 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/zh-cn/images/localimage.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/zh-cn/images/music.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/zh-cn/images/music.png new file mode 100644 index 000000000..354edebc3 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/zh-cn/images/music.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/zh-cn/images/upload.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/zh-cn/images/upload.png new file mode 100644 index 000000000..08d4d9268 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/zh-cn/images/upload.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/zh-cn/zh-cn.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/zh-cn/zh-cn.js new file mode 100644 index 000000000..4d5178f98 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/lang/zh-cn/zh-cn.js @@ -0,0 +1,669 @@ +/** + * Created with JetBrains PhpStorm. + * User: taoqili + * Date: 12-6-12 + * Time: 下午5:02 + * To change this template use File | Settings | File Templates. + */ +UE.I18N['zh-cn'] = { + 'labelMap':{ + 'anchor':'锚点', 'undo':'撤销', 'redo':'重做', 'bold':'加粗', 'indent':'首行缩进', 'snapscreen':'截图', + 'italic':'斜体', 'underline':'下划线', 'strikethrough':'删除线', 'subscript':'下标','fontborder':'字符边框', + 'superscript':'上标', 'formatmatch':'格式刷', 'source':'源代码', 'blockquote':'引用', + 'pasteplain':'纯文本粘贴模式', 'selectall':'全选', 'print':'打印', 'preview':'预览', + 'horizontal':'分隔线', 'removeformat':'清除格式', 'time':'时间', 'date':'日期', + 'unlink':'取消链接', 'insertrow':'前插入行', 'insertcol':'前插入列', 'mergeright':'右合并单元格', 'mergedown':'下合并单元格', + 'deleterow':'删除行', 'deletecol':'删除列', 'splittorows':'拆分成行', + 'splittocols':'拆分成列', 'splittocells':'完全拆分单元格','deletecaption':'删除表格标题','inserttitle':'插入标题', + 'mergecells':'合并多个单元格', 'deletetable':'删除表格', 'cleardoc':'清空文档','insertparagraphbeforetable':"表格前插入行",'insertcode':'代码语言', + 'fontfamily':'字体', 'fontsize':'字号', 'paragraph':'段落格式', 'simpleupload':'单图上传', 'insertimage':'多图上传','edittable':'表格属性','edittd':'单元格属性', 'link':'超链接', + 'emotion':'表情', 'spechars':'特殊字符', 'searchreplace':'查询替换', 'map':'Baidu地图', 'gmap':'Google地图', + 'insertvideo':'视频', 'help':'帮助', 'justifyleft':'居左对齐', 'justifyright':'居右对齐', 'justifycenter':'居中对齐', + 'justifyjustify':'两端对齐', 'forecolor':'字体颜色', 'backcolor':'背景色', 'insertorderedlist':'有序列表', + 'insertunorderedlist':'无序列表', 'fullscreen':'全屏', 'directionalityltr':'从左向右输入', 'directionalityrtl':'从右向左输入', + 'rowspacingtop':'段前距', 'rowspacingbottom':'段后距', 'pagebreak':'分页', 'insertframe':'插入Iframe', 'imagenone':'默认', + 'imageleft':'左浮动', 'imageright':'右浮动', 'attachment':'附件', 'imagecenter':'居中', 'wordimage':'图片转存', + 'lineheight':'行间距','edittip' :'编辑提示','customstyle':'自定义标题', 'autotypeset':'自动排版', + 'webapp':'百度应用','touppercase':'字母大写', 'tolowercase':'字母小写','background':'背景','template':'模板','scrawl':'涂鸦', + 'music':'音乐','inserttable':'插入表格','drafts': '从草稿箱加载', 'charts': '图表' + }, + 'insertorderedlist':{ + 'num':'1,2,3...', + 'num1':'1),2),3)...', + 'num2':'(1),(2),(3)...', + 'cn':'一,二,三....', + 'cn1':'一),二),三)....', + 'cn2':'(一),(二),(三)....', + 'decimal':'1,2,3...', + 'lower-alpha':'a,b,c...', + 'lower-roman':'i,ii,iii...', + 'upper-alpha':'A,B,C...', + 'upper-roman':'I,II,III...' + }, + 'insertunorderedlist':{ + 'circle':'○ 大圆圈', + 'disc':'● 小黑点', + 'square':'■ 小方块 ', + 'dash' :'— 破折号', + 'dot':' 。 小圆圈' + }, + 'paragraph':{'p':'段落', 'h1':'标题 1', 'h2':'标题 2', 'h3':'标题 3', 'h4':'标题 4', 'h5':'标题 5', 'h6':'标题 6'}, + 'fontfamily':{ + 'songti':'宋体', + 'kaiti':'楷体', + 'heiti':'黑体', + 'lishu':'隶书', + 'yahei':'微软雅黑', + 'andaleMono':'andale mono', + 'arial': 'arial', + 'arialBlack':'arial black', + 'comicSansMs':'comic sans ms', + 'impact':'impact', + 'timesNewRoman':'times new roman' + }, + 'customstyle':{ + 'tc':'标题居中', + 'tl':'标题居左', + 'im':'强调', + 'hi':'明显强调' + }, + 'autoupload': { + 'exceedSizeError': '文件大小超出限制', + 'exceedTypeError': '文件格式不允许', + 'jsonEncodeError': '服务器返回格式错误', + 'loading':"正在上传...", + 'loadError':"上传错误", + 'errorLoadConfig': '后端配置项没有正常加载,上传插件不能正常使用!' + }, + 'simpleupload':{ + 'exceedSizeError': '文件大小超出限制', + 'exceedTypeError': '文件格式不允许', + 'jsonEncodeError': '服务器返回格式错误', + 'loading':"正在上传...", + 'loadError':"上传错误", + 'errorLoadConfig': '后端配置项没有正常加载,上传插件不能正常使用!' + }, + 'elementPathTip':"元素路径", + 'wordCountTip':"字数统计", + 'wordCountMsg':'当前已输入{#count}个字符, 您还可以输入{#leave}个字符。 ', + 'wordOverFlowMsg':'字数超出最大允许值,服务器可能拒绝保存!', + 'ok':"确认", + 'cancel':"取消", + 'closeDialog':"关闭对话框", + 'tableDrag':"表格拖动必须引入uiUtils.js文件!", + 'autofloatMsg':"工具栏浮动依赖编辑器UI,您首先需要引入UI文件!", + 'loadconfigError': '获取后台配置项请求出错,上传功能将不能正常使用!', + 'loadconfigFormatError': '后台配置项返回格式出错,上传功能将不能正常使用!', + 'loadconfigHttpError': '请求后台配置项http错误,上传功能将不能正常使用!', + 'snapScreen_plugin':{ + 'browserMsg':"仅支持IE浏览器!", + 'callBackErrorMsg':"服务器返回数据有误,请检查配置项之后重试。", + 'uploadErrorMsg':"截图上传失败,请检查服务器端环境! " + }, + 'insertcode':{ + 'as3':'ActionScript 3', + 'bash':'Bash/Shell', + 'cpp':'C/C++', + 'css':'CSS', + 'cf':'ColdFusion', + 'c#':'C#', + 'delphi':'Delphi', + 'diff':'Diff', + 'erlang':'Erlang', + 'groovy':'Groovy', + 'html':'HTML', + 'java':'Java', + 'jfx':'JavaFX', + 'js':'JavaScript', + 'pl':'Perl', + 'php':'PHP', + 'plain':'Plain Text', + 'ps':'PowerShell', + 'python':'Python', + 'ruby':'Ruby', + 'scala':'Scala', + 'sql':'SQL', + 'vb':'Visual Basic', + 'xml':'XML' + }, + 'confirmClear':"确定清空当前文档么?", + 'contextMenu':{ + 'delete':"删除", + 'selectall':"全选", + 'deletecode':"删除代码", + 'cleardoc':"清空文档", + 'confirmclear':"确定清空当前文档么?", + 'unlink':"删除超链接", + 'paragraph':"段落格式", + 'edittable':"表格属性", + 'aligntd':"单元格对齐方式", + 'aligntable':'表格对齐方式', + 'tableleft':'左浮动', + 'tablecenter':'居中显示', + 'tableright':'右浮动', + 'edittd':"单元格属性", + 'setbordervisible':'设置表格边线可见', + 'justifyleft':'左对齐', + 'justifyright':'右对齐', + 'justifycenter':'居中对齐', + 'justifyjustify':'两端对齐', + 'table':"表格", + 'inserttable':'插入表格', + 'deletetable':"删除表格", + 'insertparagraphbefore':"前插入段落", + 'insertparagraphafter':'后插入段落', + 'deleterow':"删除当前行", + 'deletecol':"删除当前列", + 'insertrow':"前插入行", + 'insertcol':"左插入列", + 'insertrownext':'后插入行', + 'insertcolnext':'右插入列', + 'insertcaption':'插入表格名称', + 'deletecaption':'删除表格名称', + 'inserttitle':'插入表格标题行', + 'deletetitle':'删除表格标题行', + 'inserttitlecol':'插入表格标题列', + 'deletetitlecol':'删除表格标题列', + 'averageDiseRow':'平均分布各行', + 'averageDisCol':'平均分布各列', + 'mergeright':"向右合并", + 'mergeleft':"向左合并", + 'mergedown':"向下合并", + 'mergecells':"合并单元格", + 'splittocells':"完全拆分单元格", + 'splittocols':"拆分成列", + 'splittorows':"拆分成行", + 'tablesort':'表格排序', + 'enablesort':'设置表格可排序', + 'disablesort':'取消表格可排序', + 'reversecurrent':'逆序当前', + 'orderbyasc':'按ASCII字符升序', + 'reversebyasc':'按ASCII字符降序', + 'orderbynum':'按数值大小升序', + 'reversebynum':'按数值大小降序', + 'borderbk':'边框底纹', + 'setcolor':'表格隔行变色', + 'unsetcolor':'取消表格隔行变色', + 'setbackground':'选区背景隔行', + 'unsetbackground':'取消选区背景', + 'redandblue':'红蓝相间', + 'threecolorgradient':'三色渐变', + 'copy':"复制(Ctrl + c)", + 'copymsg': "浏览器不支持,请使用 'Ctrl + c'", + 'paste':"粘贴(Ctrl + v)", + 'pastemsg': "浏览器不支持,请使用 'Ctrl + v'" + }, + 'copymsg': "浏览器不支持,请使用 'Ctrl + c'", + 'pastemsg': "浏览器不支持,请使用 'Ctrl + v'", + 'anthorMsg':"链接", + 'clearColor':'清空颜色', + 'standardColor':'标准颜色', + 'themeColor':'主题颜色', + 'property':'属性', + 'default':'默认', + 'modify':'修改', + 'justifyleft':'左对齐', + 'justifyright':'右对齐', + 'justifycenter':'居中', + 'justify':'默认', + 'clear':'清除', + 'anchorMsg':'锚点', + 'delete':'删除', + 'clickToUpload':"点击上传", + 'unset':'尚未设置语言文件', + 't_row':'行', + 't_col':'列', + 'more':'更多', + 'pasteOpt':'粘贴选项', + 'pasteSourceFormat':"保留源格式", + 'tagFormat':'只保留标签', + 'pasteTextFormat':'只保留文本', + 'autoTypeSet':{ + 'mergeLine':"合并空行", + 'delLine':"清除空行", + 'removeFormat':"清除格式", + 'indent':"首行缩进", + 'alignment':"对齐方式", + 'imageFloat':"图片浮动", + 'removeFontsize':"清除字号", + 'removeFontFamily':"清除字体", + 'removeHtml':"清除冗余HTML代码", + 'pasteFilter':"粘贴过滤", + 'run':"执行", + 'symbol':'符号转换', + 'bdc2sb':'全角转半角', + 'tobdc':'半角转全角' + }, + + 'background':{ + 'static':{ + 'lang_background_normal':'背景设置', + 'lang_background_local':'在线图片', + 'lang_background_set':'选项', + 'lang_background_none':'无背景色', + 'lang_background_colored':'有背景色', + 'lang_background_color':'颜色设置', + 'lang_background_netimg':'网络图片', + 'lang_background_align':'对齐方式', + 'lang_background_position':'精确定位', + 'repeatType':{'options':["居中", "横向重复", "纵向重复", "平铺","自定义"]} + + }, + 'noUploadImage':"当前未上传过任何图片!", + 'toggleSelect':"单击可切换选中状态\n原图尺寸: " + }, + //===============dialog i18N======================= + 'insertimage':{ + 'static':{ + 'lang_tab_remote':"插入图片", //节点 + 'lang_tab_upload':"本地上传", + 'lang_tab_online':"在线管理", + 'lang_tab_search':"图片搜索", + 'lang_input_url':"地 址:", + 'lang_input_size':"大 小:", + 'lang_input_width':"宽度", + 'lang_input_height':"高度", + 'lang_input_border':"边 框:", + 'lang_input_vhspace':"边 距:", + 'lang_input_title':"描 述:", + 'lang_input_align':'图片浮动方式:', + 'lang_imgLoading':" 图片加载中……", + 'lang_start_upload':"开始上传", + 'lock':{'title':"锁定宽高比例"}, //属性 + 'searchType':{'title':"图片类型", 'options':["新闻", "壁纸", "表情", "头像"]}, //select的option + 'searchTxt':{'value':"请输入搜索关键词"}, + 'searchBtn':{'value':"百度一下"}, + 'searchReset':{'value':"清空搜索"}, + 'noneAlign':{'title':'无浮动'}, + 'leftAlign':{'title':'左浮动'}, + 'rightAlign':{'title':'右浮动'}, + 'centerAlign':{'title':'居中独占一行'} + }, + 'uploadSelectFile':'点击选择图片', + 'uploadAddFile':'继续添加', + 'uploadStart':'开始上传', + 'uploadPause':'暂停上传', + 'uploadContinue':'继续上传', + 'uploadRetry':'重试上传', + 'uploadDelete':'删除', + 'uploadTurnLeft':'向左旋转', + 'uploadTurnRight':'向右旋转', + 'uploadPreview':'预览中', + 'uploadNoPreview':'不能预览', + 'updateStatusReady': '选中_张图片,共_KB。', + 'updateStatusConfirm': '已成功上传_张照片,_张照片上传失败', + 'updateStatusFinish': '共_张(_KB),_张上传成功', + 'updateStatusError': ',_张上传失败。', + 'errorNotSupport': 'WebUploader 不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级 flash 播放器。', + 'errorLoadConfig': '后端配置项没有正常加载,上传插件不能正常使用!', + 'errorExceedSize':'文件大小超出', + 'errorFileType':'文件格式不允许', + 'errorInterrupt':'文件传输中断', + 'errorUploadRetry':'上传失败,请重试', + 'errorHttp':'http请求错误', + 'errorServerUpload':'服务器返回出错', + 'remoteLockError':"宽高不正确,不能所定比例", + 'numError':"请输入正确的长度或者宽度值!例如:123,400", + 'imageUrlError':"不允许的图片格式或者图片域!", + 'imageLoadError':"图片加载失败!请检查链接地址或网络状态!", + 'searchRemind':"请输入搜索关键词", + 'searchLoading':"图片加载中,请稍后……", + 'searchRetry':" :( ,抱歉,没有找到图片!请重试一次!" + }, + 'attachment':{ + 'static':{ + 'lang_tab_upload': '上传附件', + 'lang_tab_online': '在线附件', + 'lang_start_upload':"开始上传", + 'lang_drop_remind':"可以将文件拖到这里,单次最多可选100个文件" + }, + 'uploadSelectFile':'点击选择文件', + 'uploadAddFile':'继续添加', + 'uploadStart':'开始上传', + 'uploadPause':'暂停上传', + 'uploadContinue':'继续上传', + 'uploadRetry':'重试上传', + 'uploadDelete':'删除', + 'uploadTurnLeft':'向左旋转', + 'uploadTurnRight':'向右旋转', + 'uploadPreview':'预览中', + 'updateStatusReady': '选中_个文件,共_KB。', + 'updateStatusConfirm': '已成功上传_个文件,_个文件上传失败', + 'updateStatusFinish': '共_个(_KB),_个上传成功', + 'updateStatusError': ',_张上传失败。', + 'errorNotSupport': 'WebUploader 不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级 flash 播放器。', + 'errorLoadConfig': '后端配置项没有正常加载,上传插件不能正常使用!', + 'errorExceedSize':'文件大小超出', + 'errorFileType':'文件格式不允许', + 'errorInterrupt':'文件传输中断', + 'errorUploadRetry':'上传失败,请重试', + 'errorHttp':'http请求错误', + 'errorServerUpload':'服务器返回出错' + }, + 'insertvideo':{ + 'static':{ + 'lang_tab_insertV':"插入视频", + 'lang_tab_searchV':"搜索视频", + 'lang_tab_uploadV':"上传视频", + 'lang_video_url':"视频网址", + 'lang_video_size':"视频尺寸", + 'lang_videoW':"宽度", + 'lang_videoH':"高度", + 'lang_alignment':"对齐方式", + 'videoSearchTxt':{'value':"请输入搜索关键字!"}, + 'videoType':{'options':["全部", "热门", "娱乐", "搞笑", "体育", "科技", "综艺"]}, + 'videoSearchBtn':{'value':"百度一下"}, + 'videoSearchReset':{'value':"清空结果"}, + + 'lang_input_fileStatus':' 当前未上传文件', + 'startUpload':{'style':"background:url(upload.png) no-repeat;"}, + + 'lang_upload_size':"视频尺寸", + 'lang_upload_width':"宽度", + 'lang_upload_height':"高度", + 'lang_upload_alignment':"对齐方式", + 'lang_format_advice':"建议使用mp4格式." + + }, + 'numError':"请输入正确的数值,如123,400", + 'floatLeft':"左浮动", + 'floatRight':"右浮动", + '"default"':"默认", + 'block':"独占一行", + 'urlError':"输入的视频地址有误,请检查后再试!", + 'loading':"  视频加载中,请等待……", + 'clickToSelect':"点击选中", + 'goToSource':'访问源视频', + 'noVideo':"    抱歉,找不到对应的视频,请重试!", + + 'browseFiles':'浏览文件', + 'uploadSuccess':'上传成功!', + 'delSuccessFile':'从成功队列中移除', + 'delFailSaveFile':'移除保存失败文件', + 'statusPrompt':' 个文件已上传! ', + 'flashVersionError':'当前Flash版本过低,请更新FlashPlayer后重试!', + 'flashLoadingError':'Flash加载失败!请检查路径或网络状态', + 'fileUploadReady':'等待上传……', + 'delUploadQueue':'从上传队列中移除', + 'limitPrompt1':'单次不能选择超过', + 'limitPrompt2':'个文件!请重新选择!', + 'delFailFile':'移除失败文件', + 'fileSizeLimit':'文件大小超出限制!', + 'emptyFile':'空文件无法上传!', + 'fileTypeError':'文件类型不允许!', + 'unknownError':'未知错误!', + 'fileUploading':'上传中,请等待……', + 'cancelUpload':'取消上传', + 'netError':'网络错误', + 'failUpload':'上传失败!', + 'serverIOError':'服务器IO错误!', + 'noAuthority':'无权限!', + 'fileNumLimit':'上传个数限制', + 'failCheck':'验证失败,本次上传被跳过!', + 'fileCanceling':'取消中,请等待……', + 'stopUploading':'上传已停止……', + + 'uploadSelectFile':'点击选择文件', + 'uploadAddFile':'继续添加', + 'uploadStart':'开始上传', + 'uploadPause':'暂停上传', + 'uploadContinue':'继续上传', + 'uploadRetry':'重试上传', + 'uploadDelete':'删除', + 'uploadTurnLeft':'向左旋转', + 'uploadTurnRight':'向右旋转', + 'uploadPreview':'预览中', + 'updateStatusReady': '选中_个文件,共_KB。', + 'updateStatusConfirm': '成功上传_个,_个失败', + 'updateStatusFinish': '共_个(_KB),_个成功上传', + 'updateStatusError': ',_张上传失败。', + 'errorNotSupport': 'WebUploader 不支持您的浏览器!如果你使用的是IE浏览器,请尝试升级 flash 播放器。', + 'errorLoadConfig': '后端配置项没有正常加载,上传插件不能正常使用!', + 'errorExceedSize':'文件大小超出', + 'errorFileType':'文件格式不允许', + 'errorInterrupt':'文件传输中断', + 'errorUploadRetry':'上传失败,请重试', + 'errorHttp':'http请求错误', + 'errorServerUpload':'服务器返回出错' + }, + 'webapp':{ + 'tip1':"本功能由百度APP提供,如看到此页面,请各位站长首先申请百度APPKey!", + 'tip2':"申请完成之后请至ueditor.config.js中配置获得的appkey! ", + 'applyFor':"点此申请", + 'anthorApi':"百度API" + }, + 'template':{ + 'static':{ + 'lang_template_bkcolor':'背景颜色', + 'lang_template_clear' : '保留原有内容', + 'lang_template_select' : '选择模板' + }, + 'blank':"空白文档", + 'blog':"博客文章", + 'resume':"个人简历", + 'richText':"图文混排", + 'sciPapers':"科技论文" + + + }, + 'scrawl':{ + 'static':{ + 'lang_input_previousStep':"上一步", + 'lang_input_nextsStep':"下一步", + 'lang_input_clear':'清空', + 'lang_input_addPic':'添加背景', + 'lang_input_ScalePic':'缩放背景', + 'lang_input_removePic':'删除背景', + 'J_imgTxt':{title:'添加背景图片'} + }, + 'noScarwl':"尚未作画,白纸一张~", + 'scrawlUpLoading':"涂鸦上传中,别急哦~", + 'continueBtn':"继续", + 'imageError':"糟糕,图片读取失败了!", + 'backgroundUploading':'背景图片上传中,别急哦~' + }, + 'music':{ + 'static':{ + 'lang_input_tips':"输入歌手/歌曲/专辑,搜索您感兴趣的音乐!", + 'J_searchBtn':{value:'搜索歌曲'} + }, + 'emptyTxt':'未搜索到相关音乐结果,请换一个关键词试试。', + 'chapter':'歌曲', + 'singer':'歌手', + 'special':'专辑', + 'listenTest':'试听' + }, + 'anchor':{ + 'static':{ + 'lang_input_anchorName':'锚点名字:' + } + }, + 'charts':{ + 'static':{ + 'lang_data_source':'数据源:', + 'lang_chart_format': '图表格式:', + 'lang_data_align': '数据对齐方式', + 'lang_chart_align_same': '数据源与图表X轴Y轴一致', + 'lang_chart_align_reverse': '数据源与图表X轴Y轴相反', + 'lang_chart_title': '图表标题', + 'lang_chart_main_title': '主标题:', + 'lang_chart_sub_title': '子标题:', + 'lang_chart_x_title': 'X轴标题:', + 'lang_chart_y_title': 'Y轴标题:', + 'lang_chart_tip': '提示文字', + 'lang_cahrt_tip_prefix': '提示文字前缀:', + 'lang_cahrt_tip_description': '仅饼图有效, 当鼠标移动到饼图中相应的块上时,提示框内的文字的前缀', + 'lang_chart_data_unit': '数据单位', + 'lang_chart_data_unit_title': '单位:', + 'lang_chart_data_unit_description': '显示在每个数据点上的数据的单位, 比如: 温度的单位 ℃', + 'lang_chart_type': '图表类型:', + 'lang_prev_btn': '上一个', + 'lang_next_btn': '下一个' + } + }, + 'emotion':{ + 'static':{ + 'lang_input_choice':'精选', + 'lang_input_Tuzki':'兔斯基', + 'lang_input_BOBO':'BOBO', + 'lang_input_lvdouwa':'绿豆蛙', + 'lang_input_babyCat':'baby猫', + 'lang_input_bubble':'泡泡', + 'lang_input_youa':'有啊' + } + }, + 'gmap':{ + 'static':{ + 'lang_input_address':'地址', + 'lang_input_search':'搜索', + 'address':{value:"北京"} + }, + searchError:'无法定位到该地址!' + }, + 'help':{ + 'static':{ + 'lang_input_about':'关于UEditor', + 'lang_input_shortcuts':'快捷键', + 'lang_input_introduction':'UEditor是由百度web前端研发部开发的所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点。开源基于BSD协议,允许自由使用和修改代码。', + 'lang_Txt_shortcuts':'快捷键', + 'lang_Txt_func':'功能', + 'lang_Txt_bold':'给选中字设置为加粗', + 'lang_Txt_copy':'复制选中内容', + 'lang_Txt_cut':'剪切选中内容', + 'lang_Txt_Paste':'粘贴', + 'lang_Txt_undo':'重新执行上次操作', + 'lang_Txt_redo':'撤销上一次操作', + 'lang_Txt_italic':'给选中字设置为斜体', + 'lang_Txt_underline':'给选中字加下划线', + 'lang_Txt_selectAll':'全部选中', + 'lang_Txt_visualEnter':'软回车', + 'lang_Txt_fullscreen':'全屏' + } + }, + 'insertframe':{ + 'static':{ + 'lang_input_address':'地址:', + 'lang_input_width':'宽度:', + 'lang_input_height':'高度:', + 'lang_input_isScroll':'允许滚动条:', + 'lang_input_frameborder':'显示框架边框:', + 'lang_input_alignMode':'对齐方式:', + 'align':{title:"对齐方式", options:["默认", "左对齐", "右对齐", "居中"]} + }, + 'enterAddress':'请输入地址!' + }, + 'link':{ + 'static':{ + 'lang_input_text':'文本内容:', + 'lang_input_url':'链接地址:', + 'lang_input_title':'标题:', + 'lang_input_target':'是否在新窗口打开:' + }, + 'validLink':'只支持选中一个链接时生效', + 'httpPrompt':'您输入的超链接中不包含http等协议名称,默认将为您添加http://前缀' + }, + 'map':{ + 'static':{ + lang_city:"城市", + lang_address:"地址", + city:{value:"北京"}, + lang_search:"搜索", + lang_dynamicmap:"插入动态地图" + }, + cityMsg:"请选择城市", + errorMsg:"抱歉,找不到该位置!" + }, + 'searchreplace':{ + 'static':{ + lang_tab_search:"查找", + lang_tab_replace:"替换", + lang_search1:"查找", + lang_search2:"查找", + lang_replace:"替换", + lang_searchReg:'支持正则表达式,添加前后斜杠标示为正则表达式,例如“/表达式/”', + lang_searchReg1:'支持正则表达式,添加前后斜杠标示为正则表达式,例如“/表达式/”', + lang_case_sensitive1:"区分大小写", + lang_case_sensitive2:"区分大小写", + nextFindBtn:{value:"下一个"}, + preFindBtn:{value:"上一个"}, + nextReplaceBtn:{value:"下一个"}, + preReplaceBtn:{value:"上一个"}, + repalceBtn:{value:"替换"}, + repalceAllBtn:{value:"全部替换"} + }, + getEnd:"已经搜索到文章末尾!", + getStart:"已经搜索到文章头部", + countMsg:"总共替换了{#count}处!" + }, + 'snapscreen':{ + 'static':{ + lang_showMsg:"截图功能需要首先安装UEditor截图插件! ", + lang_download:"点此下载", + lang_step1:"第一步,下载UEditor截图插件并运行安装。", + lang_step2:"第二步,插件安装完成后即可使用,如不生效,请重启浏览器后再试!" + } + }, + 'spechars':{ + 'static':{}, + tsfh:"特殊字符", + lmsz:"罗马字符", + szfh:"数学字符", + rwfh:"日文字符", + xlzm:"希腊字母", + ewzm:"俄文字符", + pyzm:"拼音字母", + yyyb:"英语音标", + zyzf:"其他" + }, + 'edittable':{ + 'static':{ + 'lang_tableStyle':'表格样式', + 'lang_insertCaption':'添加表格名称行', + 'lang_insertTitle':'添加表格标题行', + 'lang_insertTitleCol':'添加表格标题列', + 'lang_orderbycontent':"使表格内容可排序", + 'lang_tableSize':'自动调整表格尺寸', + 'lang_autoSizeContent':'按表格文字自适应', + 'lang_autoSizePage':'按页面宽度自适应', + 'lang_example':'示例', + 'lang_borderStyle':'表格边框', + 'lang_color':'颜色:' + }, + captionName:'表格名称', + titleName:'标题', + cellsName:'内容', + errorMsg:'有合并单元格,不可排序' + }, + 'edittip':{ + 'static':{ + lang_delRow:'删除整行', + lang_delCol:'删除整列' + } + }, + 'edittd':{ + 'static':{ + lang_tdBkColor:'背景颜色:' + } + }, + 'formula':{ + 'static':{ + } + }, + 'wordimage':{ + 'static':{ + lang_resave:"转存步骤", + uploadBtn:{src:"upload.png",alt:"上传"}, + clipboard:{style:"background: url(copy.png) -153px -1px no-repeat;"}, + lang_step:"1、点击顶部复制按钮,将地址复制到剪贴板;2、点击添加照片按钮,在弹出的对话框中使用Ctrl+V粘贴地址;3、点击打开后选择图片上传流程。" + }, + 'fileType':"图片", + 'flashError':"FLASH初始化失败,请检查FLASH插件是否正确安装!", + 'netError':"网络连接错误,请重试!", + 'copySuccess':"图片地址已经复制!", + 'flashI18n':{} //留空默认中文 + }, + 'autosave': { + 'saving':'保存中...', + 'success':'本地保存成功' + } +}; diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/css/ueditor.css b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/css/ueditor.css new file mode 100644 index 000000000..44ae805a0 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/css/ueditor.css @@ -0,0 +1,1903 @@ +/*基础UI构建 +*/ +/* common layer */ +.edui-default .edui-box { + border: none; + padding: 0; + margin: 0; + overflow: hidden; +} + +.edui-default a.edui-box { + display: block; + text-decoration: none; + color: black; +} + +.edui-default a.edui-box:hover { + text-decoration: none; +} + +.edui-default a.edui-box:active { + text-decoration: none; +} + +.edui-default table.edui-box { + border-collapse: collapse; +} + +.edui-default ul.edui-box { + list-style-type: none; +} + +div.edui-box { + position: relative; + display: -moz-inline-box !important; + display: inline-block !important; + vertical-align: top; +} + +.edui-default .edui-clearfix { + zoom: 1 +} + +.edui-default .edui-clearfix:after { + content: '\20'; + display: block; + clear: both; +} + + * html div.edui-box { + display: inline !important; +} + +*:first-child+html div.edui-box { + display: inline !important; +} + +/* control layout */ +.edui-default .edui-button-body, .edui-splitbutton-body, .edui-menubutton-body, .edui-combox-body { + position: relative; +} + +.edui-default .edui-popup { + position: absolute; + -webkit-user-select: none; + -moz-user-select: none; +} + +.edui-default .edui-popup .edui-shadow { + position: absolute; + z-index: -1; +} + +.edui-default .edui-popup .edui-bordereraser { + position: absolute; + overflow: hidden; +} + +.edui-default .edui-tablepicker .edui-canvas { + position: relative; +} + +.edui-default .edui-tablepicker .edui-canvas .edui-overlay { + position: absolute; +} + +.edui-default .edui-dialog-modalmask, .edui-dialog-dragmask { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; +} + +.edui-default .edui-toolbar { + position: relative; +} + +/* + * default theme + */ +.edui-default .edui-label { + cursor: default; +} + +.edui-default span.edui-clickable { + color: blue; + cursor: pointer; + text-decoration: underline; +} + +.edui-default span.edui-unclickable { + color: gray; + cursor: default; +} +/* 工具栏 */ +.edui-default .edui-toolbar { + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + padding: 1px; + overflow: hidden; /*全屏下单独一行不占位*/ + zoom: 1; + width:auto; + height:auto; +} + +.edui-default .edui-toolbar .edui-button, +.edui-default .edui-toolbar .edui-splitbutton, +.edui-default .edui-toolbar .edui-menubutton, +.edui-default .edui-toolbar .edui-combox { + margin: 1px; +} +/*UI工具栏、编辑区域、底部*/ +.edui-default .edui-editor { + border: 1px solid #d4d4d4; + background-color: white; + position: relative; + overflow: visible; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.edui-editor div{ + width:auto; + height:auto; +} +.edui-default .edui-editor-toolbarbox { + position: relative; + zoom: 1; + -webkit-box-shadow:0 1px 4px rgba(204, 204, 204, 0.6); + -moz-box-shadow:0 1px 4px rgba(204, 204, 204, 0.6); + box-shadow:0 1px 4px rgba(204, 204, 204, 0.6); + border-top-left-radius:2px; + border-top-right-radius:2px; +} + +.edui-default .edui-editor-toolbarboxouter { + border-bottom: 1px solid #d4d4d4; + background-color: #fafafa; + background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2)); + background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2); + background-image: -o-linear-gradient(top, #ffffff, #f2f2f2); + background-image: linear-gradient(to bottom, #ffffff, #f2f2f2); + background-repeat: repeat-x; + /*border: 1px solid #d4d4d4;*/ + -webkit-border-radius: 4px 4px 0 0; + -moz-border-radius: 4px 4px 0 0; + border-radius: 4px 4px 0 0; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0); + *zoom: 1; + -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); + box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065); +} + +.edui-default .edui-editor-toolbarboxinner { + padding: 2px; +} + +.edui-default .edui-editor-iframeholder { + position: relative; + /*for fix ie6 toolbarmsg under iframe bug. relative -> static */ + /*_position: static !important;* +} + +.edui-default .edui-editor-iframeholder textarea { + font-family: consolas, "Courier New", "lucida console", monospace; + font-size: 12px; + line-height: 18px; +} + +.edui-default .edui-editor-bottombar { + /*border-top: 1px solid #ccc;*/ + /*height: 20px;*/ + /*width: 40%;*/ + /*float: left;*/ + /*overflow: hidden;*/ +} + +.edui-default .edui-editor-bottomContainer { + overflow: hidden; +} + +.edui-default .edui-editor-bottomContainer table { + width: 100%; + height: 0; + overflow: hidden; + border-spacing: 0; +} + +.edui-default .edui-editor-bottomContainer td { + white-space: nowrap; + border-top: 1px solid #ccc; + line-height: 20px; + font-size: 12px; + font-family: Arial, Helvetica, Tahoma, Verdana, Sans-Serif; +} + +.edui-default .edui-editor-wordcount { + text-align: right; + margin-right: 5px; + color: #aaa; +} +.edui-default .edui-editor-scale { + width: 12px; +} +.edui-default .edui-editor-scale .edui-editor-icon { + float: right; + width: 100%; + height: 12px; + margin-top: 10px; + background: url(../images/scale.png) no-repeat; + cursor: se-resize; +} +.edui-default .edui-editor-breadcrumb { + margin: 2px 0 0 3px; +} + +.edui-default .edui-editor-breadcrumb span { + cursor: pointer; + text-decoration: underline; + color: blue; +} + +.edui-default .edui-toolbar .edui-for-fullscreen { + float: right; +} + +.edui-default .edui-bubble .edui-popup-content { + border: 1px solid #DCAC6C; + background-color: #fff6d9; + padding: 5px; + font-size: 10pt; + font-family: "宋体"; +} + +.edui-default .edui-bubble .edui-shadow { + /*box-shadow: 1px 1px 3px #818181;*/ + /*-webkit-box-shadow: 2px 2px 3px #818181;*/ + /*-moz-box-shadow: 2px 2px 3px #818181;*/ + /*filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius = '2', MakeShadow = 'true', ShadowOpacity = '0.5');*/ +} + +.edui-default .edui-editor-toolbarmsg { + background-color: #FFF6D9; + border-bottom: 1px solid #ccc; + position: absolute; + bottom: -25px; + left: 0; + z-index: 1009; + width: 99.9%; +} + +.edui-default .edui-editor-toolbarmsg-upload { + font-size: 14px; + color: blue; + width: 100px; + height: 16px; + line-height: 16px; + cursor: pointer; + position: absolute; + top: 5px; + left: 350px; +} + +.edui-default .edui-editor-toolbarmsg-label { + font-size: 12px; + line-height: 16px; + padding: 4px; +} + +.edui-default .edui-editor-toolbarmsg-close { + float: right; + width: 20px; + height: 16px; + line-height: 16px; + cursor: pointer; + color: red; +} +/*可选中菜单按钮*/ +.edui-default .edui-list .edui-bordereraser { + display: none; +} + +.edui-default .edui-listitem { + padding: 1px; + white-space: nowrap; +} + +.edui-default .edui-list .edui-state-hover { + position: relative; + background-color: #fff5d4; + border: 1px solid #dcac6c; + padding: 0; +} + +.edui-default .edui-for-fontfamily .edui-listitem-label { + min-width: 130px; + _width: 120px; + font-size: 12px; + height: 22px; + line-height: 22px; + padding-left: 5px; +} +.edui-default .edui-for-insertcode .edui-listitem-label { + min-width: 120px; + _width: 120px; + font-size: 12px; + height: 22px; + line-height: 22px; + padding-left: 5px; +} +.edui-default .edui-for-underline .edui-listitem-label { + min-width: 120px; + _width: 120px; + padding: 3px 5px; + font-size: 12px; +} + +.edui-default .edui-for-fontsize .edui-listitem-label { + min-width: 120px; + _width: 120px; + padding: 3px 5px; + +} + +.edui-default .edui-for-paragraph .edui-listitem-label { + min-width: 200px; + _width: 200px; + padding: 2px 5px; +} + +.edui-default .edui-for-rowspacingtop .edui-listitem-label, +.edui-default .edui-for-rowspacingbottom .edui-listitem-label { + min-width: 53px; + _width: 53px; + padding: 2px 5px; +} + +.edui-default .edui-for-lineheight .edui-listitem-label { + min-width: 53px; + _width: 53px; + padding: 2px 5px; +} + +.edui-default .edui-for-customstyle .edui-listitem-label { + min-width: 200px; + _width: 200px; + width: 200px !important; + padding: 2px 5px; +} +/* 可选中按钮弹出菜单*/ +.edui-default .edui-menu { + z-index: 3000; +} + +.edui-default .edui-menu .edui-popup-content { + padding: 3px; +} + +.edui-default .edui-menu-body { + _width: 150px; + min-width: 170px; + background: url("../images/sparator_v.png") repeat-y 25px; +} + +.edui-default .edui-menuitem-body { +} + +.edui-default .edui-menuitem { + height: 20px; + cursor: default; + vertical-align: top; +} + +.edui-default .edui-menuitem .edui-icon { + width: 20px !important; + height: 20px !important; + background: url(../images/icons.png) 0 -4000px; + background: url(../images/icons.gif) 0 -4000px\9; +} + +.edui-default .edui-menuitem .edui-label { + font-size: 12px; + line-height: 20px; + height: 20px; + padding-left: 10px; +} + +.edui-default .edui-state-checked .edui-menuitem-body { + background: url("../images/icons-all.gif") no-repeat 6px -205px; +} + +.edui-default .edui-state-disabled .edui-menuitem-label { + color: gray; +} + + +/*不可选中菜单按钮 */ +.edui-default .edui-toolbar .edui-combox-body .edui-button-body { + width: 60px; + font-size: 12px; + height: 20px; + line-height: 20px; + padding-left: 5px; + white-space: nowrap; + margin: 0 3px 0 0; +} + +.edui-default .edui-toolbar .edui-combox-body .edui-arrow { + background: url(../images/icons.png) -741px 0; + _background: url(../images/icons.gif) -741px 0; + height: 20px; + width: 9px; +} + +.edui-default .edui-toolbar .edui-combox .edui-combox-body { + border: 1px solid #CCC; + background-color: white; + border-radius: 2px; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; +} + +.edui-default .edui-toolbar .edui-combox-body .edui-splitborder { + display: none; +} + +.edui-default .edui-toolbar .edui-combox-body .edui-arrow { + border-left: 1px solid #CCC; +} + +.edui-default .edui-toolbar .edui-state-hover .edui-combox-body { + background-color: #fff5d4; + border: 1px solid #dcac6c; +} + +.edui-default .edui-toolbar .edui-state-hover .edui-combox-body .edui-arrow { + border-left: 1px solid #dcac6c; +} + +.edui-default .edui-toolbar .edui-state-checked .edui-combox-body { + background-color: #FFE69F; + border: 1px solid #DCAC6C; +} + +.edui-toolbar .edui-state-checked .edui-combox-body .edui-arrow { + border-left: 1px solid #DCAC6C; +} + +.edui-toolbar .edui-state-disabled .edui-combox-body { + background-color: #F0F0EE; + opacity: 0.3; + filter: alpha(opacity = 30); +} + +.edui-toolbar .edui-state-opened .edui-combox-body { + background-color: white; + border: 1px solid gray; +} +/*普通按钮样式及状态*/ +.edui-default .edui-toolbar .edui-button .edui-icon, +.edui-default .edui-toolbar .edui-menubutton .edui-icon, +.edui-default .edui-toolbar .edui-splitbutton .edui-icon { + height: 20px !important; + width: 20px !important; + background-image: url(../images/icons.png); + background-image: url(../images/icons.gif) \9; +} + +.edui-default .edui-toolbar .edui-button .edui-button-wrap { + padding: 1px; + position: relative; +} + +.edui-default .edui-toolbar .edui-button .edui-state-hover .edui-button-wrap { + background-color: #fff5d4; + padding: 0; + border: 1px solid #dcac6c; +} + +.edui-default .edui-toolbar .edui-button .edui-state-checked .edui-button-wrap { + background-color: #ffe69f; + padding: 0; + border: 1px solid #dcac6c; + border-radius: 2px; + -webkit-border-radius: 2px; + -moz-border-radius: 2px; +} + +.edui-default .edui-toolbar .edui-button .edui-state-active .edui-button-wrap { + background-color: #ffffff; + padding: 0; + border: 1px solid gray; +} +.edui-default .edui-toolbar .edui-state-disabled .edui-label { + color: #ccc; +} +.edui-default .edui-toolbar .edui-state-disabled .edui-icon { + opacity: 0.3; + filter: alpha(opacity = 30); +} + +/* toolbar icons */ +.edui-default .edui-for-undo .edui-icon { + background-position: -160px 0; +} + +.edui-default .edui-for-redo .edui-icon { + background-position: -100px 0; +} + +.edui-default .edui-for-bold .edui-icon { + background-position: 0 0; +} + +.edui-default .edui-for-italic .edui-icon { + background-position: -60px 0; +} + +.edui-default .edui-for-fontborder .edui-icon { + background-position:-160px -40px; +} +.edui-default .edui-for-underline .edui-icon { + background-position: -140px 0; +} + +.edui-default .edui-for-strikethrough .edui-icon { + background-position: -120px 0; +} + +.edui-default .edui-for-subscript .edui-icon { + background-position: -600px 0; +} + +.edui-default .edui-for-superscript .edui-icon { + background-position: -620px 0; +} + +.edui-default .edui-for-blockquote .edui-icon { + background-position: -220px 0; +} + +.edui-default .edui-for-forecolor .edui-icon { + background-position: -720px 0; +} + +.edui-default .edui-for-backcolor .edui-icon { + background-position: -760px 0; +} + +.edui-default .edui-for-inserttable .edui-icon { + background-position: -580px -20px; +} + +.edui-default .edui-for-autotypeset .edui-icon { + background-position: -640px -40px; +} + +.edui-default .edui-for-justifyleft .edui-icon { + background-position: -460px 0; +} + +.edui-default .edui-for-justifycenter .edui-icon { + background-position: -420px 0; +} + +.edui-default .edui-for-justifyright .edui-icon { + background-position: -480px 0; +} + +.edui-default .edui-for-justifyjustify .edui-icon { + background-position: -440px 0; +} + +.edui-default .edui-for-insertorderedlist .edui-icon { + background-position: -80px 0; +} + +.edui-default .edui-for-insertunorderedlist .edui-icon { + background-position: -20px 0; +} + +.edui-default .edui-for-lineheight .edui-icon { + background-position: -725px -40px; +} + +.edui-default .edui-for-rowspacingbottom .edui-icon { + background-position: -745px -40px; +} + +.edui-default .edui-for-rowspacingtop .edui-icon { + background-position: -765px -40px; +} + +.edui-default .edui-for-horizontal .edui-icon { + background-position: -360px 0; +} + +.edui-default .edui-for-link .edui-icon { + background-position: -500px 0; +} + +.edui-default .edui-for-code .edui-icon { + background-position: -440px -40px; +} + +.edui-default .edui-for-insertimage .edui-icon { + background-position: -726px -77px; +} + +.edui-default .edui-for-insertframe .edui-icon { + background-position: -240px -40px; +} + +.edui-default .edui-for-emoticon .edui-icon { + background-position: -60px -20px; +} + +.edui-default .edui-for-spechars .edui-icon { + background-position: -240px 0; +} + +.edui-default .edui-for-help .edui-icon { + background-position: -340px 0; +} + +.edui-default .edui-for-print .edui-icon { + background-position: -440px -20px; +} + +.edui-default .edui-for-preview .edui-icon { + background-position: -420px -20px; +} + +.edui-default .edui-for-selectall .edui-icon { + background-position: -400px -20px; +} + +.edui-default .edui-for-searchreplace .edui-icon { + background-position: -520px -20px; +} + +.edui-default .edui-for-map .edui-icon { + background-position: -40px -40px; +} + +.edui-default .edui-for-gmap .edui-icon { + background-position: -260px -40px; +} + +.edui-default .edui-for-insertvideo .edui-icon { + background-position: -320px -20px; +} + +.edui-default .edui-for-time .edui-icon { + background-position: -160px -20px; +} + +.edui-default .edui-for-date .edui-icon { + background-position: -140px -20px; +} + +.edui-default .edui-for-cut .edui-icon { + background-position: -680px 0; +} + +.edui-default .edui-for-copy .edui-icon { + background-position: -700px 0; +} + +.edui-default .edui-for-paste .edui-icon { + background-position: -560px 0; +} + +.edui-default .edui-for-formatmatch .edui-icon { + background-position: -40px 0; +} + +.edui-default .edui-for-pasteplain .edui-icon { + background-position: -360px -20px; +} + +.edui-default .edui-for-directionalityltr .edui-icon { + background-position: -20px -20px; +} + +.edui-default .edui-for-directionalityrtl .edui-icon { + background-position: -40px -20px; +} + +.edui-default .edui-for-source .edui-icon { + background-position: -261px -0px; +} + +.edui-default .edui-for-removeformat .edui-icon { + background-position: -580px 0; +} + +.edui-default .edui-for-unlink .edui-icon { + background-position: -640px 0; +} + +.edui-default .edui-for-touppercase .edui-icon { + background-position: -786px 0; +} + +.edui-default .edui-for-tolowercase .edui-icon { + background-position: -806px 0; +} + +.edui-default .edui-for-insertrow .edui-icon { + background-position: -478px -76px; +} + +.edui-default .edui-for-insertrownext .edui-icon { + background-position: -498px -76px; +} + +.edui-default .edui-for-insertcol .edui-icon { + background-position: -455px -76px; +} + +.edui-default .edui-for-insertcolnext .edui-icon { + background-position: -429px -76px; +} + +.edui-default .edui-for-mergeright .edui-icon { + background-position: -60px -40px; +} + +.edui-default .edui-for-mergedown .edui-icon { + background-position: -80px -40px; +} + +.edui-default .edui-for-splittorows .edui-icon { + background-position: -100px -40px; +} + +.edui-default .edui-for-splittocols .edui-icon { + background-position: -120px -40px; +} + +.edui-default .edui-for-insertparagraphbeforetable .edui-icon { + background-position: -140px -40px; +} + +.edui-default .edui-for-deleterow .edui-icon { + background-position: -660px -20px; +} + +.edui-default .edui-for-deletecol .edui-icon { + background-position: -640px -20px; +} + +.edui-default .edui-for-splittocells .edui-icon { + background-position: -800px -20px; +} + +.edui-default .edui-for-mergecells .edui-icon { + background-position: -760px -20px; +} + +.edui-default .edui-for-deletetable .edui-icon { + background-position: -620px -20px; +} + +.edui-default .edui-for-cleardoc .edui-icon { + background-position: -520px 0; +} + +.edui-default .edui-for-fullscreen .edui-icon { + background-position: -100px -20px; +} + +.edui-default .edui-for-anchor .edui-icon { + background-position: -200px 0; +} + +.edui-default .edui-for-pagebreak .edui-icon { + background-position: -460px -40px; +} + +.edui-default .edui-for-imagenone .edui-icon { + background-position: -480px -40px; +} + +.edui-default .edui-for-imageleft .edui-icon { + background-position: -500px -40px; +} + +.edui-default .edui-for-wordimage .edui-icon { + background-position: -660px -40px; +} + +.edui-default .edui-for-imageright .edui-icon { + background-position: -520px -40px; +} + +.edui-default .edui-for-imagecenter .edui-icon { + background-position: -540px -40px; +} + +.edui-default .edui-for-indent .edui-icon { + background-position: -400px 0; +} + +.edui-default .edui-for-outdent .edui-icon { + background-position: -540px 0; +} + +.edui-default .edui-for-webapp .edui-icon { + background-position: -601px -40px +} + +.edui-default .edui-for-table .edui-icon { + background-position: -580px -20px; +} + +.edui-default .edui-for-edittable .edui-icon { + background-position: -420px -40px; +} + +.edui-default .edui-for-template .edui-icon { + background-position: -339px -40px; +} + +.edui-default .edui-for-delete .edui-icon { + background-position: -360px -40px; +} + +.edui-default .edui-for-attachment .edui-icon { + background-position: -620px -40px; +} + +.edui-default .edui-for-edittd .edui-icon { + background-position: -700px -40px; +} + +.edui-default .edui-for-snapscreen .edui-icon { + background-position: -581px -40px +} + +.edui-default .edui-for-scrawl .edui-icon { + background-position: -801px -41px +} + +.edui-default .edui-for-background .edui-icon { + background-position: -680px -40px; +} + +.edui-default .edui-for-music .edui-icon { + background-position: -18px -40px +} + +.edui-default .edui-for-formula .edui-icon { + background-position: -200px -40px +} + +.edui-default .edui-for-aligntd .edui-icon { + background-position: -236px -76px; +} + +.edui-default .edui-for-insertparagraphtrue .edui-icon { + background-position: -625px -76px; +} + +.edui-default .edui-for-insertparagraph .edui-icon { + background-position: -602px -76px; +} + +.edui-default .edui-for-insertcaption .edui-icon { + background-position: -336px -76px; +} + +.edui-default .edui-for-deletecaption .edui-icon { + background-position: -362px -76px; +} + +.edui-default .edui-for-inserttitle .edui-icon { + background-position: -286px -76px; +} + +.edui-default .edui-for-deletetitle .edui-icon { + background-position: -311px -76px; +} + +.edui-default .edui-for-aligntable .edui-icon { + background-position: -440px 0; +} + +.edui-default .edui-for-tablealignment-left .edui-icon { + background-position: -460px 0; +} + +.edui-default .edui-for-tablealignment-center .edui-icon { + background-position: -420px 0; +} + +.edui-default .edui-for-tablealignment-right .edui-icon { + background-position: -480px 0; +} + +.edui-default .edui-for-drafts .edui-icon { + background-position: -560px 0; +} + +.edui-default .edui-for-charts .edui-icon { + background: url( ../images/charts.png ) no-repeat 2px 3px!important; +} + +.edui-default .edui-for-inserttitlecol .edui-icon { + background-position: -673px -76px; +} + +.edui-default .edui-for-deletetitlecol .edui-icon { + background-position: -698px -76px; +} + +.edui-default .edui-for-simpleupload .edui-icon { + background-position: -380px 0px; +} +/*splitbutton*/ +.edui-default .edui-toolbar .edui-splitbutton-body .edui-arrow, +.edui-default .edui-toolbar .edui-menubutton-body .edui-arrow { + background: url(../images/icons.png) -741px 0; + _background: url(../images/icons.gif) -741px 0; + height: 20px; + width: 9px; +} + +.edui-default .edui-toolbar .edui-splitbutton .edui-splitbutton-body, +.edui-default .edui-toolbar .edui-menubutton .edui-menubutton-body { + padding: 1px; +} + +.edui-default .edui-toolbar .edui-splitborder { + width: 1px; + height: 20px; +} + +.edui-default .edui-toolbar .edui-state-hover .edui-splitborder { + width: 1px; + border-left: 0px solid #dcac6c; +} + +.edui-default .edui-toolbar .edui-state-active .edui-splitborder { + width: 0; + border-left: 1px solid gray; +} + +.edui-default .edui-toolbar .edui-state-opened .edui-splitborder { + width: 1px; + border: 0; +} + +.edui-default .edui-toolbar .edui-splitbutton .edui-state-hover .edui-splitbutton-body, +.edui-default .edui-toolbar .edui-menubutton .edui-state-hover .edui-menubutton-body { + background-color: #fff5d4; + border: 1px solid #dcac6c; + padding: 0; +} + +.edui-default .edui-toolbar .edui-splitbutton .edui-state-checked .edui-splitbutton-body, +.edui-default .edui-toolbar .edui-menubutton .edui-state-checked .edui-menubutton-body { + background-color: #FFE69F; + border: 1px solid #DCAC6C; + padding: 0; +} + +.edui-default .edui-toolbar .edui-splitbutton .edui-state-active .edui-splitbutton-body, +.edui-default .edui-toolbar .edui-menubutton .edui-state-active .edui-menubutton-body { + background-color: #ffffff; + border: 1px solid gray; + padding: 0; +} + +.edui-default .edui-state-disabled .edui-arrow { + opacity: 0.3; + _filter: alpha(opacity = 30); +} + +.edui-default .edui-toolbar .edui-splitbutton .edui-state-opened .edui-splitbutton-body, +.edui-default .edui-toolbar .edui-menubutton .edui-state-opened .edui-menubutton-body { + background-color: white; + border: 1px solid gray; + padding: 0; +} + +.edui-default .edui-for-insertorderedlist .edui-bordereraser, +.edui-default .edui-for-lineheight .edui-bordereraser, +.edui-default .edui-for-rowspacingtop .edui-bordereraser, +.edui-default .edui-for-rowspacingbottom .edui-bordereraser, +.edui-default .edui-for-insertunorderedlist .edui-bordereraser { + background-color: white; +} + +/* 解决嵌套导致的图标问题 */ +.edui-default .edui-for-insertorderedlist .edui-popup-body .edui-icon, +.edui-default .edui-for-lineheight .edui-popup-body .edui-icon, +.edui-default .edui-for-rowspacingtop .edui-popup-body .edui-icon, +.edui-default .edui-for-rowspacingbottom .edui-popup-body .edui-icon, +.edui-default .edui-for-insertunorderedlist .edui-popup-body .edui-icon { + /*background-position: 0 -40px;*/ + background-image: none ; +} + +/* 弹出菜单 */ +.edui-default .edui-popup { + z-index: 3000; + background-color: #ffffff; + width:auto; + height:auto; + +} + +.edui-default .edui-popup .edui-shadow { + left: 0; + top: 0; + width: 100%; + height: 100%; +} + +.edui-default .edui-popup-content { + border:1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 3px 4px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 3px 4px rgba(0, 0, 0, 0.2); + box-shadow: 0 3px 4px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; + padding: 5px; + background:#ffffff; +} + +.edui-default .edui-popup .edui-bordereraser { + background-color: white; + height: 3px; +} + +.edui-default .edui-menu .edui-bordereraser { + height: 3px; +} + +.edui-default .edui-anchor-topleft .edui-bordereraser { + left: 1px; + top: -2px; +} + +.edui-default .edui-anchor-topright .edui-bordereraser { + right: 1px; + top: -2px; +} + +.edui-default .edui-anchor-bottomleft .edui-bordereraser { + left: 0; + bottom: -6px; + height: 7px; + border-left: 1px solid gray; + border-right: 1px solid gray; +} + +.edui-default .edui-anchor-bottomright .edui-bordereraser { + right: 0; + bottom: -6px; + height: 7px; + border-left: 1px solid gray; + border-right: 1px solid gray; +} + +.edui-popup div{ + width:auto; + height:auto; +} +.edui-default .edui-editor-messageholder { + display: block; + width: 150px; + height: auto; + border: 0; + margin: 0; + padding: 0; + position: absolute; + top: 28px; + right: 3px; +} + +.edui-default .edui-message{ + min-height: 10px; + text-shadow: 0 1px 0 rgba(255,255,255,0.5); + padding: 0; + margin-bottom: 3px; + position: relative; +} +.edui-default .edui-message-body{ + border-radius: 3px; + padding: 8px 15px 8px 8px; + color: #c09853; + background-color: #fcf8e3; + border: 1px solid #fbeed5; +} +.edui-default .edui-message-type-info{ + color: #3a87ad; + background-color: #d9edf7; + border-color: #bce8f1 +} +.edui-default .edui-message-type-success{ + color: #468847; + background-color: #dff0d8; + border-color: #d6e9c6 +} +.edui-default .edui-message-type-danger, +.edui-default .edui-message-type-error{ + color: #b94a48; + background-color: #f2dede; + border-color: #eed3d7 +} +.edui-default .edui-message .edui-message-closer { + display: block; + width: 16px; + height: 16px; + line-height: 16px; + position: absolute; + top: 0; + right: 0; + padding: 0; + cursor: pointer; + background: transparent; + border: 0; + float: right; + font-size: 20px; + font-weight: bold; + color: #999; + text-shadow: 0 1px 0 #fff; + font-family: "Helvetica Neue",Helvetica,Arial,sans-serif; +} +.edui-default .edui-message .edui-message-content { + font-size: 10pt; + word-wrap: break-word; + word-break: normal; +} +/* 弹出对话框按钮和对话框大小 */ +.edui-default .edui-dialog { + z-index: 2000; + position: absolute; + +} + +.edui-dialog div{ + width:auto; +} + +.edui-default .edui-dialog-wrap { + margin-right: 6px; + margin-bottom: 6px; +} + +.edui-default .edui-dialog-fullscreen-flag { + margin-right: 0; + margin-bottom: 0; +} + +.edui-default .edui-dialog-body { + position: relative; + padding:2px 0 0 2px; + _zoom: 1; +} + +.edui-default .edui-dialog-fullscreen-flag .edui-dialog-body { + padding: 0; +} + +.edui-default .edui-dialog-shadow { + position: absolute; + z-index: -1; + left: 0; + top: 0; + width: 100%; + height: 100%; + background-color: #ffffff; + border: 1px solid #ccc; + border: 1px solid rgba(0, 0, 0, 0.2); + *border-right-width: 2px; + *border-bottom-width: 2px; + -webkit-border-radius: 6px; + -moz-border-radius: 6px; + border-radius: 6px; + -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2); + -webkit-background-clip: padding-box; + -moz-background-clip: padding; + background-clip: padding-box; +} + +.edui-default .edui-dialog-foot { + background-color: white; +} + +.edui-default .edui-dialog-titlebar { + height: 26px; + border-bottom: 1px solid #c6c6c6; + background: url(../images/dialog-title-bg.png) repeat-x bottom; + position: relative; + cursor: move; +} +.edui-default .edui-dialog-caption { + font-weight: bold; + font-size: 12px; + line-height: 26px; + padding-left: 5px; +} + +.edui-default .edui-dialog-draghandle { + height: 26px; +} + +.edui-default .edui-dialog-closebutton { + position: absolute !important; + right: 5px; + top: 3px; +} + +.edui-default .edui-dialog-closebutton .edui-button-body { + height: 20px; + width: 20px; + cursor: pointer; + background: url("../images/icons-all.gif") no-repeat 0 -59px; +} + +.edui-default .edui-dialog-closebutton .edui-state-hover .edui-button-body { + background: url("../images/icons-all.gif") no-repeat 0 -89px; +} + +.edui-default .edui-dialog-foot { + height: 40px; +} + +.edui-default .edui-dialog-buttons { + position: absolute; + right: 0; +} + +.edui-default .edui-dialog-buttons .edui-button { + margin-right: 10px; +} + +.edui-default .edui-dialog-buttons .edui-button .edui-button-body { + background: url("../images/icons-all.gif") no-repeat; + height: 24px; + width: 96px; + font-size: 12px; + line-height: 24px; + text-align: center; + cursor: default; +} + +.edui-default .edui-dialog-buttons .edui-button .edui-state-hover .edui-button-body { + background: url("../images/icons-all.gif") no-repeat 0 -30px; +} + +.edui-default .edui-dialog iframe { + border: 0; + padding: 0; + margin: 0; + vertical-align: top; +} + +.edui-default .edui-dialog-modalmask { + opacity: 0.3; + filter: alpha(opacity = 30); + background-color: #ccc; + position: absolute; + /*z-index: 1999;*/ +} + +.edui-default .edui-dialog-dragmask { + position: absolute; + /*z-index: 2001;*/ + background-color: transparent; + cursor: move; +} + +.edui-default .edui-dialog-content { + position: relative; +} + +.edui-default .dialogcontmask { + cursor: move; + visibility: hidden; + display: block; + position: absolute; + width: 100%; + height: 100%; + opacity: 0; + filter: alpha(opacity = 0); +} + +/*link-dialog*/ +.edui-default .edui-for-link .edui-dialog-content { + width: 420px; + height: 200px; + overflow: hidden; +} +/*background-dialog*/ +.edui-default .edui-for-background .edui-dialog-content { + width: 440px; + height: 280px; + overflow: hidden; +} + +/*template-dialog*/ +.edui-default .edui-for-template .edui-dialog-content { + width: 630px; + height: 390px; + overflow: hidden; +} + +/*scrawl-dialog*/ +.edui-default .edui-for-scrawl .edui-dialog-content { + width: 515px; + *width: 506px; + height: 360px; +} + +/*spechars-dialog*/ +.edui-default .edui-for-spechars .edui-dialog-content { + width: 620px; + height: 500px; + *width: 630px; + *height: 570px; +} + +/*image-dialog*/ +.edui-default .edui-for-insertimage .edui-dialog-content { + width: 650px; + height: 400px; + overflow: hidden; +} +/*webapp-dialog*/ +.edui-default .edui-for-webapp .edui-dialog-content { + width: 560px; + _width: 565px; + height: 450px; + overflow: hidden; +} + +/*image-insertframe*/ +.edui-default .edui-for-insertframe .edui-dialog-content { + width: 350px; + height: 200px; + overflow: hidden; +} + +/*wordImage-dialog*/ +.edui-default .edui-for-wordimage .edui-dialog-content { + width: 620px; + height: 380px; + overflow: hidden; +} + +/*attachment-dialog*/ +.edui-default .edui-for-attachment .edui-dialog-content { + width: 650px; + height: 400px; + overflow: hidden; +} + + +/*map-dialog*/ +.edui-default .edui-for-map .edui-dialog-content { + width: 550px; + height: 400px; +} + +/*gmap-dialog*/ +.edui-default .edui-for-gmap .edui-dialog-content { + width: 550px; + height: 400px; +} + +/*video-dialog*/ +.edui-default .edui-for-insertvideo .edui-dialog-content { + width: 590px; + height: 390px; +} + +/*anchor-dialog*/ +.edui-default .edui-for-anchor .edui-dialog-content { + width: 320px; + height: 60px; + overflow: hidden; +} + +/*searchreplace-dialog*/ +.edui-default .edui-for-searchreplace .edui-dialog-content { + width: 400px; + height: 220px; +} + +/*help-dialog*/ +.edui-default .edui-for-help .edui-dialog-content { + width: 400px; + height: 420px; +} + +/*edittable-dialog*/ +.edui-default .edui-for-edittable .edui-dialog-content { + width: 540px; + _width:590px; + height: 335px; +} + +/*edittip-dialog*/ +.edui-default .edui-for-edittip .edui-dialog-content { + width: 225px; + height: 60px; +} + +/*edittd-dialog*/ +.edui-default .edui-for-edittd .edui-dialog-content { + width: 240px; + height: 50px; +} +/*snapscreen-dialog*/ +.edui-default .edui-for-snapscreen .edui-dialog-content { + width: 400px; + height: 220px; +} + +/*music-dialog*/ +.edui-default .edui-for-music .edui-dialog-content { + width: 515px; + height: 360px; +} + +/*段落弹出菜单*/ +.edui-default .edui-for-paragraph .edui-listitem-label { + font-family: Tahoma, Verdana, Arial, Helvetica; +} + +.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-p { + font-size: 22px; + line-height: 27px; +} + +.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h1 { + font-weight: bolder; + font-size: 32px; + line-height: 36px; +} + +.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h2 { + font-weight: bolder; + font-size: 27px; + line-height: 29px; +} + +.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h3 { + font-weight: bolder; + font-size: 19px; + line-height: 23px; +} + +.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h4 { + font-weight: bolder; + font-size: 16px; + line-height: 19px +} + +.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h5 { + font-weight: bolder; + font-size: 13px; + line-height: 16px; +} + +.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h6 { + font-weight: bolder; + font-size: 12px; + line-height: 14px; +} +/* 表格弹出菜单 */ +.edui-default .edui-for-inserttable .edui-splitborder { + display: none +} +.edui-default .edui-for-inserttable .edui-splitbutton-body .edui-arrow { + width: 0 +} +.edui-default .edui-toolbar .edui-for-inserttable .edui-state-active .edui-splitborder{ + border-left: 1px solid transparent; +} +.edui-default .edui-tablepicker .edui-infoarea { + height: 14px; + line-height: 14px; + font-size: 12px; + width: 220px; + margin-bottom: 3px; + clear: both; +} + +.edui-default .edui-tablepicker .edui-infoarea .edui-label { + float: left; +} + +.edui-default .edui-dialog-buttons .edui-label { + line-height: 24px; +} + +.edui-default .edui-tablepicker .edui-infoarea .edui-clickable { + float: right; +} + +.edui-default .edui-tablepicker .edui-pickarea { + background: url("../images/unhighlighted.gif") repeat; + height: 220px; + width: 220px; +} + +.edui-default .edui-tablepicker .edui-pickarea .edui-overlay { + background: url("../images/highlighted.gif") repeat; +} + +/* 颜色弹出菜单 */ +.edui-default .edui-colorpicker-topbar { + height: 27px; + width: 200px; + /*border-bottom: 1px gray dashed;*/ +} + +.edui-default .edui-colorpicker-preview { + height: 20px; + border: 1px inset black; + margin-left: 1px; + width: 128px; + float: left; +} + +.edui-default .edui-colorpicker-nocolor { + float: right; + margin-right: 1px; + font-size: 12px; + line-height: 14px; + height: 14px; + border: 1px solid #333; + padding: 3px 5px; + cursor: pointer; +} + +.edui-default .edui-colorpicker-tablefirstrow { + height: 30px; +} + +.edui-default .edui-colorpicker-colorcell { + width: 14px; + height: 14px; + display: block; + margin: 0; + cursor: pointer; +} + +.edui-default .edui-colorpicker-colorcell:hover { + width: 14px; + height: 14px; + margin: 0; +} +.edui-default .edui-colorpicker-advbtn{ + display: block; + text-align: center; + cursor: pointer; + height:20px; +} +.arrow_down{ + background: white url('../images/arrow_down.png') no-repeat center; +} +.arrow_up{ + background: white url('../images/arrow_up.png') no-repeat center; +} +/*高级的样式*/ +.edui-colorpicker-adv{ + position: relative; + overflow: hidden; + height: 180px; + display: none; +} +.edui-colorpicker-plant, .edui-colorpicker-hue { + border: solid 1px #666; +} +.edui-colorpicker-pad { + width: 150px; + height: 150px; + left: 14px; + top: 13px; + position: absolute; + background: red; + overflow: hidden; + cursor: crosshair; +} +.edui-colorpicker-cover{ + position: absolute; + top: 0; + left: 0; + width: 150px; + height: 150px; + background: url("../images/tangram-colorpicker.png") -160px -200px; +} +.edui-colorpicker-padDot{ + position: absolute; + top: 0; + left: 0; + width: 11px; + height: 11px; + overflow: hidden; + background: url(../images/tangram-colorpicker.png) 0px -200px repeat-x; + z-index: 1000; + +} +.edui-colorpicker-sliderMain { + position: absolute; + left: 171px; + top: 13px; + width: 19px; + height: 152px; + background: url(../images/tangram-colorpicker.png) -179px -12px no-repeat; + +} +.edui-colorpicker-slider { + width: 100%; + height: 100%; + cursor: pointer; +} +.edui-colorpicker-thumb{ + position: absolute; + top: 0; + cursor: pointer; + height: 3px; + left: -1px; + right: -1px; + border: 1px solid black; + background: white; + opacity: .8; +} +/*自动排版弹出菜单*/ +.edui-default .edui-autotypesetpicker .edui-autotypesetpicker-body { + font-size: 12px; + margin-bottom: 3px; + clear: both; +} + +.edui-default .edui-autotypesetpicker-body table { + border-collapse: separate; + border-spacing: 2px; +} + +.edui-default .edui-autotypesetpicker-body td { + font-size: 12px; + word-wrap:break-word; +} + +.edui-default .edui-autotypesetpicker-body td input { + margin: 3px 3px 3px 4px; + *margin: 1px 0 0 0; +} +/*自动排版弹出菜单*/ +.edui-default .edui-cellalignpicker .edui-cellalignpicker-body { + width: 70px; + font-size: 12px; + cursor: default; +} + +.edui-default .edui-cellalignpicker-body table { + border-collapse: separate; + border-spacing: 0; +} +.edui-default .edui-cellalignpicker-body td{ + padding: 1px; +} +.edui-default .edui-cellalignpicker-body .edui-icon{ + height: 20px; + width: 20px; + padding: 1px; + background-image: url(../images/table-cell-align.png); +} + +.edui-default .edui-cellalignpicker-body .edui-left{ + background-position: 0 0; +} + +.edui-default .edui-cellalignpicker-body .edui-center{ + background-position: -25px 0; +} +.edui-default .edui-cellalignpicker-body .edui-right{ + background-position: -51px 0; +} + +.edui-default .edui-cellalignpicker-body td.edui-state-hover .edui-left{ + background-position: -73px 0; +} + +.edui-default .edui-cellalignpicker-body td.edui-state-hover .edui-center{ + background-position: -98px 0; +} + +.edui-default .edui-cellalignpicker-body td.edui-state-hover .edui-right{ + background-position: -124px 0; +} + +.edui-default .edui-cellalignpicker-body td.edui-cellalign-selected .edui-left { + background-position: -146px 0; + background-color: #f1f4f5; +} + +.edui-default .edui-cellalignpicker-body td.edui-cellalign-selected .edui-center { + background-position: -245px 0; +} + +.edui-default .edui-cellalignpicker-body td.edui-cellalign-selected .edui-right { + background-position: -271px 0; +} +/*分隔线*/ +.edui-default .edui-toolbar .edui-separator { + width: 2px; + height: 20px; + margin: 2px 4px 2px 3px; + background: url(../images/icons.png) -181px 0; + background: url(../images/icons.gif) -181px 0 \9; +} + +/*颜色按钮 */ +.edui-default .edui-toolbar .edui-colorbutton .edui-colorlump { + position: absolute; + overflow: hidden; + bottom: 1px; + left: 1px; + width: 18px; + height: 4px; +} +/*表情按钮及弹出菜单*/ +/*去除了表情的下拉箭头*/ +.edui-default .edui-for-emotion .edui-icon { + background-position: -60px -20px; +} +.edui-default .edui-for-emotion .edui-popup-content iframe +{ + width: 514px; + height: 380px; + overflow: hidden; +} +.edui-default .edui-for-emotion .edui-popup-content +{ + position: relative; + z-index: 555 +} + +.edui-default .edui-for-emotion .edui-splitborder { + display: none +} + +.edui-default .edui-for-emotion .edui-splitbutton-body .edui-arrow +{ + width: 0 +} +.edui-default .edui-toolbar .edui-for-emotion .edui-state-active .edui-splitborder +{ + border-left: 1px solid transparent; +} +/*contextmenu*/ +.edui-default .edui-hassubmenu .edui-arrow { + height: 20px; + width: 20px; + float: right; + background: url("../images/icons-all.gif") no-repeat 10px -233px; +} + +.edui-default .edui-menu-body .edui-menuitem { + padding: 1px; +} + +.edui-default .edui-menuseparator { + margin: 2px 0; + height: 1px; + overflow: hidden; +} + +.edui-default .edui-menuseparator-inner { + border-bottom: 1px solid #e2e3e3; + margin-left: 29px; + margin-right: 1px; +} + +.edui-default .edui-menu-body .edui-state-hover { + padding: 0 !important; + background-color: #fff5d4; + border: 1px solid #dcac6c; +} +/*弹出菜单*/ +.edui-default .edui-shortcutmenu { + padding: 2px; + width: 190px; + height: 50px; + background-color: #fff; + border: 1px solid #ccc; + border-radius: 5px; +} + +/*粘贴弹出菜单*/ +.edui-default .edui-wordpastepop .edui-popup-content{ + border: none; + padding: 0; + width: 54px; + height: 21px; +} +.edui-default .edui-pasteicon { + width: 100%; + height: 100%; + background-image: url('../images/wordpaste.png'); + background-position: 0 0; +} + +.edui-default .edui-pasteicon.edui-state-opened { + background-position: 0 -34px; +} + +.edui-default .edui-pastecontainer { + position: relative; + visibility: hidden; + width: 97px; + background: #fff; + border: 1px solid #ccc; +} + +.edui-default .edui-pastecontainer .edui-title { + font-weight: bold; + background: #F8F8FF; + height: 25px; + line-height: 25px; + font-size: 12px; + padding-left: 5px; +} + +.edui-default .edui-pastecontainer .edui-button { + overflow: hidden; + margin: 3px 0; +} + +.edui-default .edui-pastecontainer .edui-button .edui-richtxticon, +.edui-default .edui-pastecontainer .edui-button .edui-tagicon, +.edui-default .edui-pastecontainer .edui-button .edui-plaintxticon{ + float: left; + cursor: pointer; + width: 29px; + height: 29px; + margin-left: 5px; + background-image: url('../images/wordpaste.png'); + background-repeat: no-repeat; +} +.edui-default .edui-pastecontainer .edui-button .edui-richtxticon { + margin-left: 0; + background-position: -109px 0; +} +.edui-default .edui-pastecontainer .edui-button .edui-tagicon { + background-position: -148px 1px; +} + +.edui-default .edui-pastecontainer .edui-button .edui-plaintxticon { + background-position: -72px 0; +} + +.edui-default .edui-pastecontainer .edui-button .edui-state-hover .edui-richtxticon { + background-position: -109px -34px; +} +.edui-default .edui-pastecontainer .edui-button .edui-state-hover .edui-tagicon{ + background-position: -148px -34px; +} +.edui-default .edui-pastecontainer .edui-button .edui-state-hover .edui-plaintxticon{ + background-position: -72px -34px; +} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/css/ueditor.min.css b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/css/ueditor.min.css new file mode 100644 index 000000000..33af48bb0 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/css/ueditor.min.css @@ -0,0 +1,8 @@ +/*! + * UEditor + * version: ueditor + * build: Wed Aug 10 2016 11:05:21 GMT+0800 (CST) + */ + + +.edui-default .edui-box{border:0;padding:0;margin:0;overflow:hidden}.edui-default a.edui-box{display:block;text-decoration:none;color:#000}.edui-default a.edui-box:hover{text-decoration:none}.edui-default a.edui-box:active{text-decoration:none}.edui-default table.edui-box{border-collapse:collapse}.edui-default ul.edui-box{list-style-type:none}div.edui-box{position:relative;display:-moz-inline-box!important;display:inline-block!important;vertical-align:top}.edui-default .edui-clearfix{zoom:1}.edui-default .edui-clearfix:after{content:'\20';display:block;clear:both}* html div.edui-box{display:inline!important}:first-child+html div.edui-box{display:inline!important}.edui-default .edui-button-body,.edui-splitbutton-body,.edui-menubutton-body,.edui-combox-body{position:relative}.edui-default .edui-popup{position:absolute;-webkit-user-select:none;-moz-user-select:none}.edui-default .edui-popup .edui-shadow{position:absolute;z-index:-1}.edui-default .edui-popup .edui-bordereraser{position:absolute;overflow:hidden}.edui-default .edui-tablepicker .edui-canvas{position:relative}.edui-default .edui-tablepicker .edui-canvas .edui-overlay{position:absolute}.edui-default .edui-dialog-modalmask,.edui-dialog-dragmask{position:absolute;left:0;top:0;width:100%;height:100%}.edui-default .edui-toolbar{position:relative}.edui-default .edui-label{cursor:default}.edui-default span.edui-clickable{color:#00f;cursor:pointer;text-decoration:underline}.edui-default span.edui-unclickable{color:gray;cursor:default}.edui-default .edui-toolbar{cursor:default;-webkit-user-select:none;-moz-user-select:none;padding:1px;overflow:hidden;zoom:1;width:auto;height:auto}.edui-default .edui-toolbar .edui-button,.edui-default .edui-toolbar .edui-splitbutton,.edui-default .edui-toolbar .edui-menubutton,.edui-default .edui-toolbar .edui-combox{margin:1px}.edui-default .edui-editor{border:1px solid #d4d4d4;background-color:#fff;position:relative;overflow:visible;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.edui-editor div{width:auto;height:auto}.edui-default .edui-editor-toolbarbox{position:relative;zoom:1;-webkit-box-shadow:0 1px 4px rgba(204,204,204,.6);-moz-box-shadow:0 1px 4px rgba(204,204,204,.6);box-shadow:0 1px 4px rgba(204,204,204,.6);border-top-left-radius:2px;border-top-right-radius:2px}.edui-default .edui-editor-toolbarboxouter{border-bottom:1px solid #d4d4d4;background-color:#fafafa;background-image:-moz-linear-gradient(top,#fff,#f2f2f2);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f2f2f2));background-image:-webkit-linear-gradient(top,#fff,#f2f2f2);background-image:-o-linear-gradient(top,#fff,#f2f2f2);background-image:linear-gradient(to bottom,#fff,#f2f2f2);background-repeat:repeat-x;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);*zoom:1;-webkit-box-shadow:0 1px 4px rgba(0,0,0,.065);-moz-box-shadow:0 1px 4px rgba(0,0,0,.065);box-shadow:0 1px 4px rgba(0,0,0,.065)}.edui-default .edui-editor-toolbarboxinner{padding:2px}.edui-default .edui-editor-iframeholder{position:relative}.edui-default .edui-editor-bottomContainer{overflow:hidden}.edui-default .edui-editor-bottomContainer table{width:100%;height:0;overflow:hidden;border-spacing:0}.edui-default .edui-editor-bottomContainer td{white-space:nowrap;border-top:1px solid #ccc;line-height:20px;font-size:12px;font-family:Arial,Helvetica,Tahoma,Verdana,Sans-Serif}.edui-default .edui-editor-wordcount{text-align:right;margin-right:5px;color:#aaa}.edui-default .edui-editor-scale{width:12px}.edui-default .edui-editor-scale .edui-editor-icon{float:right;width:100%;height:12px;margin-top:10px;background:url(../images/scale.png) no-repeat;cursor:se-resize}.edui-default .edui-editor-breadcrumb{margin:2px 0 0 3px}.edui-default .edui-editor-breadcrumb span{cursor:pointer;text-decoration:underline;color:#00f}.edui-default .edui-toolbar .edui-for-fullscreen{float:right}.edui-default .edui-bubble .edui-popup-content{border:1px solid #DCAC6C;background-color:#fff6d9;padding:5px;font-size:10pt;font-family:"宋体"}.edui-default .edui-bubble .edui-shadow{}.edui-default .edui-editor-toolbarmsg{background-color:#FFF6D9;border-bottom:1px solid #ccc;position:absolute;bottom:-25px;left:0;z-index:1009;width:99.9%}.edui-default .edui-editor-toolbarmsg-upload{font-size:14px;color:#00f;width:100px;height:16px;line-height:16px;cursor:pointer;position:absolute;top:5px;left:350px}.edui-default .edui-editor-toolbarmsg-label{font-size:12px;line-height:16px;padding:4px}.edui-default .edui-editor-toolbarmsg-close{float:right;width:20px;height:16px;line-height:16px;cursor:pointer;color:red}.edui-default .edui-list .edui-bordereraser{display:none}.edui-default .edui-listitem{padding:1px;white-space:nowrap}.edui-default .edui-list .edui-state-hover{position:relative;background-color:#fff5d4;border:1px solid #dcac6c;padding:0}.edui-default .edui-for-fontfamily .edui-listitem-label{min-width:130px;_width:120px;font-size:12px;height:22px;line-height:22px;padding-left:5px}.edui-default .edui-for-insertcode .edui-listitem-label{min-width:120px;_width:120px;font-size:12px;height:22px;line-height:22px;padding-left:5px}.edui-default .edui-for-underline .edui-listitem-label{min-width:120px;_width:120px;padding:3px 5px;font-size:12px}.edui-default .edui-for-fontsize .edui-listitem-label{min-width:120px;_width:120px;padding:3px 5px}.edui-default .edui-for-paragraph .edui-listitem-label{min-width:200px;_width:200px;padding:2px 5px}.edui-default .edui-for-rowspacingtop .edui-listitem-label,.edui-default .edui-for-rowspacingbottom .edui-listitem-label{min-width:53px;_width:53px;padding:2px 5px}.edui-default .edui-for-lineheight .edui-listitem-label{min-width:53px;_width:53px;padding:2px 5px}.edui-default .edui-for-customstyle .edui-listitem-label{min-width:200px;_width:200px;width:200px!important;padding:2px 5px}.edui-default .edui-menu{z-index:3000}.edui-default .edui-menu .edui-popup-content{padding:3px}.edui-default .edui-menu-body{_width:150px;min-width:170px;background:url(../images/sparator_v.png) repeat-y 25px}.edui-default .edui-menuitem-body{}.edui-default .edui-menuitem{height:20px;cursor:default;vertical-align:top}.edui-default .edui-menuitem .edui-icon{width:20px!important;height:20px!important;background:url(../images/icons.png) 0 -4000px;background:url(../images/icons.gif) 0 -4000px\9}.edui-default .edui-menuitem .edui-label{font-size:12px;line-height:20px;height:20px;padding-left:10px}.edui-default .edui-state-checked .edui-menuitem-body{background:url(../images/icons-all.gif) no-repeat 6px -205px}.edui-default .edui-state-disabled .edui-menuitem-label{color:gray}.edui-default .edui-toolbar .edui-combox-body .edui-button-body{width:60px;font-size:12px;height:20px;line-height:20px;padding-left:5px;white-space:nowrap;margin:0 3px 0 0}.edui-default .edui-toolbar .edui-combox-body .edui-arrow{background:url(../images/icons.png) -741px 0;_background:url(../images/icons.gif) -741px 0;height:20px;width:9px}.edui-default .edui-toolbar .edui-combox .edui-combox-body{border:1px solid #CCC;background-color:#fff;border-radius:2px;-webkit-border-radius:2px;-moz-border-radius:2px}.edui-default .edui-toolbar .edui-combox-body .edui-splitborder{display:none}.edui-default .edui-toolbar .edui-combox-body .edui-arrow{border-left:1px solid #CCC}.edui-default .edui-toolbar .edui-state-hover .edui-combox-body{background-color:#fff5d4;border:1px solid #dcac6c}.edui-default .edui-toolbar .edui-state-hover .edui-combox-body .edui-arrow{border-left:1px solid #dcac6c}.edui-default .edui-toolbar .edui-state-checked .edui-combox-body{background-color:#FFE69F;border:1px solid #DCAC6C}.edui-toolbar .edui-state-checked .edui-combox-body .edui-arrow{border-left:1px solid #DCAC6C}.edui-toolbar .edui-state-disabled .edui-combox-body{background-color:#F0F0EE;opacity:.3;filter:alpha(opacity=30)}.edui-toolbar .edui-state-opened .edui-combox-body{background-color:#fff;border:1px solid gray}.edui-default .edui-toolbar .edui-button .edui-icon,.edui-default .edui-toolbar .edui-menubutton .edui-icon,.edui-default .edui-toolbar .edui-splitbutton .edui-icon{height:20px!important;width:20px!important;background-image:url(../images/icons.png);background-image:url(../images/icons.gif) \9}.edui-default .edui-toolbar .edui-button .edui-button-wrap{padding:1px;position:relative}.edui-default .edui-toolbar .edui-button .edui-state-hover .edui-button-wrap{background-color:#fff5d4;padding:0;border:1px solid #dcac6c}.edui-default .edui-toolbar .edui-button .edui-state-checked .edui-button-wrap{background-color:#ffe69f;padding:0;border:1px solid #dcac6c;border-radius:2px;-webkit-border-radius:2px;-moz-border-radius:2px}.edui-default .edui-toolbar .edui-button .edui-state-active .edui-button-wrap{background-color:#fff;padding:0;border:1px solid gray}.edui-default .edui-toolbar .edui-state-disabled .edui-label{color:#ccc}.edui-default .edui-toolbar .edui-state-disabled .edui-icon{opacity:.3;filter:alpha(opacity=30)}.edui-default .edui-for-undo .edui-icon{background-position:-160px 0}.edui-default .edui-for-redo .edui-icon{background-position:-100px 0}.edui-default .edui-for-bold .edui-icon{background-position:0 0}.edui-default .edui-for-italic .edui-icon{background-position:-60px 0}.edui-default .edui-for-fontborder .edui-icon{background-position:-160px -40px}.edui-default .edui-for-underline .edui-icon{background-position:-140px 0}.edui-default .edui-for-strikethrough .edui-icon{background-position:-120px 0}.edui-default .edui-for-subscript .edui-icon{background-position:-600px 0}.edui-default .edui-for-superscript .edui-icon{background-position:-620px 0}.edui-default .edui-for-blockquote .edui-icon{background-position:-220px 0}.edui-default .edui-for-forecolor .edui-icon{background-position:-720px 0}.edui-default .edui-for-backcolor .edui-icon{background-position:-760px 0}.edui-default .edui-for-inserttable .edui-icon{background-position:-580px -20px}.edui-default .edui-for-autotypeset .edui-icon{background-position:-640px -40px}.edui-default .edui-for-justifyleft .edui-icon{background-position:-460px 0}.edui-default .edui-for-justifycenter .edui-icon{background-position:-420px 0}.edui-default .edui-for-justifyright .edui-icon{background-position:-480px 0}.edui-default .edui-for-justifyjustify .edui-icon{background-position:-440px 0}.edui-default .edui-for-insertorderedlist .edui-icon{background-position:-80px 0}.edui-default .edui-for-insertunorderedlist .edui-icon{background-position:-20px 0}.edui-default .edui-for-lineheight .edui-icon{background-position:-725px -40px}.edui-default .edui-for-rowspacingbottom .edui-icon{background-position:-745px -40px}.edui-default .edui-for-rowspacingtop .edui-icon{background-position:-765px -40px}.edui-default .edui-for-horizontal .edui-icon{background-position:-360px 0}.edui-default .edui-for-link .edui-icon{background-position:-500px 0}.edui-default .edui-for-code .edui-icon{background-position:-440px -40px}.edui-default .edui-for-insertimage .edui-icon{background-position:-726px -77px}.edui-default .edui-for-insertframe .edui-icon{background-position:-240px -40px}.edui-default .edui-for-emoticon .edui-icon{background-position:-60px -20px}.edui-default .edui-for-spechars .edui-icon{background-position:-240px 0}.edui-default .edui-for-help .edui-icon{background-position:-340px 0}.edui-default .edui-for-print .edui-icon{background-position:-440px -20px}.edui-default .edui-for-preview .edui-icon{background-position:-420px -20px}.edui-default .edui-for-selectall .edui-icon{background-position:-400px -20px}.edui-default .edui-for-searchreplace .edui-icon{background-position:-520px -20px}.edui-default .edui-for-map .edui-icon{background-position:-40px -40px}.edui-default .edui-for-gmap .edui-icon{background-position:-260px -40px}.edui-default .edui-for-insertvideo .edui-icon{background-position:-320px -20px}.edui-default .edui-for-time .edui-icon{background-position:-160px -20px}.edui-default .edui-for-date .edui-icon{background-position:-140px -20px}.edui-default .edui-for-cut .edui-icon{background-position:-680px 0}.edui-default .edui-for-copy .edui-icon{background-position:-700px 0}.edui-default .edui-for-paste .edui-icon{background-position:-560px 0}.edui-default .edui-for-formatmatch .edui-icon{background-position:-40px 0}.edui-default .edui-for-pasteplain .edui-icon{background-position:-360px -20px}.edui-default .edui-for-directionalityltr .edui-icon{background-position:-20px -20px}.edui-default .edui-for-directionalityrtl .edui-icon{background-position:-40px -20px}.edui-default .edui-for-source .edui-icon{background-position:-261px -0px}.edui-default .edui-for-removeformat .edui-icon{background-position:-580px 0}.edui-default .edui-for-unlink .edui-icon{background-position:-640px 0}.edui-default .edui-for-touppercase .edui-icon{background-position:-786px 0}.edui-default .edui-for-tolowercase .edui-icon{background-position:-806px 0}.edui-default .edui-for-insertrow .edui-icon{background-position:-478px -76px}.edui-default .edui-for-insertrownext .edui-icon{background-position:-498px -76px}.edui-default .edui-for-insertcol .edui-icon{background-position:-455px -76px}.edui-default .edui-for-insertcolnext .edui-icon{background-position:-429px -76px}.edui-default .edui-for-mergeright .edui-icon{background-position:-60px -40px}.edui-default .edui-for-mergedown .edui-icon{background-position:-80px -40px}.edui-default .edui-for-splittorows .edui-icon{background-position:-100px -40px}.edui-default .edui-for-splittocols .edui-icon{background-position:-120px -40px}.edui-default .edui-for-insertparagraphbeforetable .edui-icon{background-position:-140px -40px}.edui-default .edui-for-deleterow .edui-icon{background-position:-660px -20px}.edui-default .edui-for-deletecol .edui-icon{background-position:-640px -20px}.edui-default .edui-for-splittocells .edui-icon{background-position:-800px -20px}.edui-default .edui-for-mergecells .edui-icon{background-position:-760px -20px}.edui-default .edui-for-deletetable .edui-icon{background-position:-620px -20px}.edui-default .edui-for-cleardoc .edui-icon{background-position:-520px 0}.edui-default .edui-for-fullscreen .edui-icon{background-position:-100px -20px}.edui-default .edui-for-anchor .edui-icon{background-position:-200px 0}.edui-default .edui-for-pagebreak .edui-icon{background-position:-460px -40px}.edui-default .edui-for-imagenone .edui-icon{background-position:-480px -40px}.edui-default .edui-for-imageleft .edui-icon{background-position:-500px -40px}.edui-default .edui-for-wordimage .edui-icon{background-position:-660px -40px}.edui-default .edui-for-imageright .edui-icon{background-position:-520px -40px}.edui-default .edui-for-imagecenter .edui-icon{background-position:-540px -40px}.edui-default .edui-for-indent .edui-icon{background-position:-400px 0}.edui-default .edui-for-outdent .edui-icon{background-position:-540px 0}.edui-default .edui-for-webapp .edui-icon{background-position:-601px -40px}.edui-default .edui-for-table .edui-icon{background-position:-580px -20px}.edui-default .edui-for-edittable .edui-icon{background-position:-420px -40px}.edui-default .edui-for-template .edui-icon{background-position:-339px -40px}.edui-default .edui-for-delete .edui-icon{background-position:-360px -40px}.edui-default .edui-for-attachment .edui-icon{background-position:-620px -40px}.edui-default .edui-for-edittd .edui-icon{background-position:-700px -40px}.edui-default .edui-for-snapscreen .edui-icon{background-position:-581px -40px}.edui-default .edui-for-scrawl .edui-icon{background-position:-801px -41px}.edui-default .edui-for-background .edui-icon{background-position:-680px -40px}.edui-default .edui-for-music .edui-icon{background-position:-18px -40px}.edui-default .edui-for-formula .edui-icon{background-position:-200px -40px}.edui-default .edui-for-aligntd .edui-icon{background-position:-236px -76px}.edui-default .edui-for-insertparagraphtrue .edui-icon{background-position:-625px -76px}.edui-default .edui-for-insertparagraph .edui-icon{background-position:-602px -76px}.edui-default .edui-for-insertcaption .edui-icon{background-position:-336px -76px}.edui-default .edui-for-deletecaption .edui-icon{background-position:-362px -76px}.edui-default .edui-for-inserttitle .edui-icon{background-position:-286px -76px}.edui-default .edui-for-deletetitle .edui-icon{background-position:-311px -76px}.edui-default .edui-for-aligntable .edui-icon{background-position:-440px 0}.edui-default .edui-for-tablealignment-left .edui-icon{background-position:-460px 0}.edui-default .edui-for-tablealignment-center .edui-icon{background-position:-420px 0}.edui-default .edui-for-tablealignment-right .edui-icon{background-position:-480px 0}.edui-default .edui-for-drafts .edui-icon{background-position:-560px 0}.edui-default .edui-for-charts .edui-icon{background:url( ../images/charts.png ) no-repeat 2px 3px!important}.edui-default .edui-for-inserttitlecol .edui-icon{background-position:-673px -76px}.edui-default .edui-for-deletetitlecol .edui-icon{background-position:-698px -76px}.edui-default .edui-for-simpleupload .edui-icon{background-position:-380px 0}.edui-default .edui-toolbar .edui-splitbutton-body .edui-arrow,.edui-default .edui-toolbar .edui-menubutton-body .edui-arrow{background:url(../images/icons.png) -741px 0;_background:url(../images/icons.gif) -741px 0;height:20px;width:9px}.edui-default .edui-toolbar .edui-splitbutton .edui-splitbutton-body,.edui-default .edui-toolbar .edui-menubutton .edui-menubutton-body{padding:1px}.edui-default .edui-toolbar .edui-splitborder{width:1px;height:20px}.edui-default .edui-toolbar .edui-state-hover .edui-splitborder{width:1px;border-left:0 solid #dcac6c}.edui-default .edui-toolbar .edui-state-active .edui-splitborder{width:0;border-left:1px solid gray}.edui-default .edui-toolbar .edui-state-opened .edui-splitborder{width:1px;border:0}.edui-default .edui-toolbar .edui-splitbutton .edui-state-hover .edui-splitbutton-body,.edui-default .edui-toolbar .edui-menubutton .edui-state-hover .edui-menubutton-body{background-color:#fff5d4;border:1px solid #dcac6c;padding:0}.edui-default .edui-toolbar .edui-splitbutton .edui-state-checked .edui-splitbutton-body,.edui-default .edui-toolbar .edui-menubutton .edui-state-checked .edui-menubutton-body{background-color:#FFE69F;border:1px solid #DCAC6C;padding:0}.edui-default .edui-toolbar .edui-splitbutton .edui-state-active .edui-splitbutton-body,.edui-default .edui-toolbar .edui-menubutton .edui-state-active .edui-menubutton-body{background-color:#fff;border:1px solid gray;padding:0}.edui-default .edui-state-disabled .edui-arrow{opacity:.3;_filter:alpha(opacity=30)}.edui-default .edui-toolbar .edui-splitbutton .edui-state-opened .edui-splitbutton-body,.edui-default .edui-toolbar .edui-menubutton .edui-state-opened .edui-menubutton-body{background-color:#fff;border:1px solid gray;padding:0}.edui-default .edui-for-insertorderedlist .edui-bordereraser,.edui-default .edui-for-lineheight .edui-bordereraser,.edui-default .edui-for-rowspacingtop .edui-bordereraser,.edui-default .edui-for-rowspacingbottom .edui-bordereraser,.edui-default .edui-for-insertunorderedlist .edui-bordereraser{background-color:#fff}.edui-default .edui-for-insertorderedlist .edui-popup-body .edui-icon,.edui-default .edui-for-lineheight .edui-popup-body .edui-icon,.edui-default .edui-for-rowspacingtop .edui-popup-body .edui-icon,.edui-default .edui-for-rowspacingbottom .edui-popup-body .edui-icon,.edui-default .edui-for-insertunorderedlist .edui-popup-body .edui-icon{background-image:none}.edui-default .edui-popup{z-index:3000;background-color:#fff;width:auto;height:auto}.edui-default .edui-popup .edui-shadow{left:0;top:0;width:100%;height:100%}.edui-default .edui-popup-content{border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 4px rgba(0,0,0,.2);-moz-box-shadow:0 3px 4px rgba(0,0,0,.2);box-shadow:0 3px 4px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;padding:5px;background:#fff}.edui-default .edui-popup .edui-bordereraser{background-color:#fff;height:3px}.edui-default .edui-menu .edui-bordereraser{height:3px}.edui-default .edui-anchor-topleft .edui-bordereraser{left:1px;top:-2px}.edui-default .edui-anchor-topright .edui-bordereraser{right:1px;top:-2px}.edui-default .edui-anchor-bottomleft .edui-bordereraser{left:0;bottom:-6px;height:7px;border-left:1px solid gray;border-right:1px solid gray}.edui-default .edui-anchor-bottomright .edui-bordereraser{right:0;bottom:-6px;height:7px;border-left:1px solid gray;border-right:1px solid gray}.edui-popup div{width:auto;height:auto}.edui-default .edui-editor-messageholder{display:block;width:150px;height:auto;border:0;margin:0;padding:0;position:absolute;top:28px;right:3px}.edui-default .edui-message{min-height:10px;text-shadow:0 1px 0 rgba(255,255,255,.5);padding:0;margin-bottom:3px;position:relative}.edui-default .edui-message-body{border-radius:3px;padding:8px 15px 8px 8px;color:#c09853;background-color:#fcf8e3;border:1px solid #fbeed5}.edui-default .edui-message-type-info{color:#3a87ad;background-color:#d9edf7;border-color:#bce8f1}.edui-default .edui-message-type-success{color:#468847;background-color:#dff0d8;border-color:#d6e9c6}.edui-default .edui-message-type-danger,.edui-default .edui-message-type-error{color:#b94a48;background-color:#f2dede;border-color:#eed3d7}.edui-default .edui-message .edui-message-closer{display:block;width:16px;height:16px;line-height:16px;position:absolute;top:0;right:0;padding:0;cursor:pointer;background:transparent;border:0;float:right;font-size:20px;font-weight:700;color:#999;text-shadow:0 1px 0 #fff;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif}.edui-default .edui-message .edui-message-content{font-size:10pt;word-wrap:break-word;word-break:normal}.edui-default .edui-dialog{z-index:2000;position:absolute}.edui-dialog div{width:auto}.edui-default .edui-dialog-wrap{margin-right:6px;margin-bottom:6px}.edui-default .edui-dialog-fullscreen-flag{margin-right:0;margin-bottom:0}.edui-default .edui-dialog-body{position:relative;padding:2px 0 0 2px;_zoom:1}.edui-default .edui-dialog-fullscreen-flag .edui-dialog-body{padding:0}.edui-default .edui-dialog-shadow{position:absolute;z-index:-1;left:0;top:0;width:100%;height:100%;background-color:#fff;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box}.edui-default .edui-dialog-foot{background-color:#fff}.edui-default .edui-dialog-titlebar{height:26px;border-bottom:1px solid #c6c6c6;background:url(../images/dialog-title-bg.png) repeat-x bottom;position:relative;cursor:move}.edui-default .edui-dialog-caption{font-weight:700;font-size:12px;line-height:26px;padding-left:5px}.edui-default .edui-dialog-draghandle{height:26px}.edui-default .edui-dialog-closebutton{position:absolute!important;right:5px;top:3px}.edui-default .edui-dialog-closebutton .edui-button-body{height:20px;width:20px;cursor:pointer;background:url(../images/icons-all.gif) no-repeat 0 -59px}.edui-default .edui-dialog-closebutton .edui-state-hover .edui-button-body{background:url(../images/icons-all.gif) no-repeat 0 -89px}.edui-default .edui-dialog-foot{height:40px}.edui-default .edui-dialog-buttons{position:absolute;right:0}.edui-default .edui-dialog-buttons .edui-button{margin-right:10px}.edui-default .edui-dialog-buttons .edui-button .edui-button-body{background:url(../images/icons-all.gif) no-repeat;height:24px;width:96px;font-size:12px;line-height:24px;text-align:center;cursor:default}.edui-default .edui-dialog-buttons .edui-button .edui-state-hover .edui-button-body{background:url(../images/icons-all.gif) no-repeat 0 -30px}.edui-default .edui-dialog iframe{border:0;padding:0;margin:0;vertical-align:top}.edui-default .edui-dialog-modalmask{opacity:.3;filter:alpha(opacity=30);background-color:#ccc;position:absolute}.edui-default .edui-dialog-dragmask{position:absolute;background-color:transparent;cursor:move}.edui-default .edui-dialog-content{position:relative}.edui-default .dialogcontmask{cursor:move;visibility:hidden;display:block;position:absolute;width:100%;height:100%;opacity:0;filter:alpha(opacity=0)}.edui-default .edui-for-link .edui-dialog-content{width:420px;height:200px;overflow:hidden}.edui-default .edui-for-background .edui-dialog-content{width:440px;height:280px;overflow:hidden}.edui-default .edui-for-template .edui-dialog-content{width:630px;height:390px;overflow:hidden}.edui-default .edui-for-scrawl .edui-dialog-content{width:515px;*width:506px;height:360px}.edui-default .edui-for-spechars .edui-dialog-content{width:620px;height:500px;*width:630px;*height:570px}.edui-default .edui-for-insertimage .edui-dialog-content{width:650px;height:400px;overflow:hidden}.edui-default .edui-for-webapp .edui-dialog-content{width:560px;_width:565px;height:450px;overflow:hidden}.edui-default .edui-for-insertframe .edui-dialog-content{width:350px;height:200px;overflow:hidden}.edui-default .edui-for-wordimage .edui-dialog-content{width:620px;height:380px;overflow:hidden}.edui-default .edui-for-attachment .edui-dialog-content{width:650px;height:400px;overflow:hidden}.edui-default .edui-for-map .edui-dialog-content{width:550px;height:400px}.edui-default .edui-for-gmap .edui-dialog-content{width:550px;height:400px}.edui-default .edui-for-insertvideo .edui-dialog-content{width:590px;height:390px}.edui-default .edui-for-anchor .edui-dialog-content{width:320px;height:60px;overflow:hidden}.edui-default .edui-for-searchreplace .edui-dialog-content{width:400px;height:220px}.edui-default .edui-for-help .edui-dialog-content{width:400px;height:420px}.edui-default .edui-for-edittable .edui-dialog-content{width:540px;_width:590px;height:335px}.edui-default .edui-for-edittip .edui-dialog-content{width:225px;height:60px}.edui-default .edui-for-edittd .edui-dialog-content{width:240px;height:50px}.edui-default .edui-for-snapscreen .edui-dialog-content{width:400px;height:220px}.edui-default .edui-for-music .edui-dialog-content{width:515px;height:360px}.edui-default .edui-for-paragraph .edui-listitem-label{font-family:Tahoma,Verdana,Arial,Helvetica}.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-p{font-size:22px;line-height:27px}.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h1{font-weight:bolder;font-size:32px;line-height:36px}.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h2{font-weight:bolder;font-size:27px;line-height:29px}.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h3{font-weight:bolder;font-size:19px;line-height:23px}.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h4{font-weight:bolder;font-size:16px;line-height:19px}.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h5{font-weight:bolder;font-size:13px;line-height:16px}.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h6{font-weight:bolder;font-size:12px;line-height:14px}.edui-default .edui-for-inserttable .edui-splitborder{display:none}.edui-default .edui-for-inserttable .edui-splitbutton-body .edui-arrow{width:0}.edui-default .edui-toolbar .edui-for-inserttable .edui-state-active .edui-splitborder{border-left:1px solid transparent}.edui-default .edui-tablepicker .edui-infoarea{height:14px;line-height:14px;font-size:12px;width:220px;margin-bottom:3px;clear:both}.edui-default .edui-tablepicker .edui-infoarea .edui-label{float:left}.edui-default .edui-dialog-buttons .edui-label{line-height:24px}.edui-default .edui-tablepicker .edui-infoarea .edui-clickable{float:right}.edui-default .edui-tablepicker .edui-pickarea{background:url(../images/unhighlighted.gif) repeat;height:220px;width:220px}.edui-default .edui-tablepicker .edui-pickarea .edui-overlay{background:url(../images/highlighted.gif) repeat}.edui-default .edui-colorpicker-topbar{height:27px;width:200px}.edui-default .edui-colorpicker-preview{height:20px;border:1px inset #000;margin-left:1px;width:128px;float:left}.edui-default .edui-colorpicker-nocolor{float:right;margin-right:1px;font-size:12px;line-height:14px;height:14px;border:1px solid #333;padding:3px 5px;cursor:pointer}.edui-default .edui-colorpicker-tablefirstrow{height:30px}.edui-default .edui-colorpicker-colorcell{width:14px;height:14px;display:block;margin:0;cursor:pointer}.edui-default .edui-colorpicker-colorcell:hover{width:14px;height:14px;margin:0}.edui-default .edui-colorpicker-advbtn{display:block;text-align:center;cursor:pointer;height:20px}.arrow_down{background:#fff url(../images/arrow_down.png) no-repeat center}.arrow_up{background:#fff url(../images/arrow_up.png) no-repeat center}.edui-colorpicker-adv{position:relative;overflow:hidden;height:180px;display:none}.edui-colorpicker-plant,.edui-colorpicker-hue{border:solid 1px #666}.edui-colorpicker-pad{width:150px;height:150px;left:14px;top:13px;position:absolute;background:red;overflow:hidden;cursor:crosshair}.edui-colorpicker-cover{position:absolute;top:0;left:0;width:150px;height:150px;background:url(../images/tangram-colorpicker.png) -160px -200px}.edui-colorpicker-padDot{position:absolute;top:0;left:0;width:11px;height:11px;overflow:hidden;background:url(../images/tangram-colorpicker.png) 0 -200px repeat-x;z-index:1000}.edui-colorpicker-sliderMain{position:absolute;left:171px;top:13px;width:19px;height:152px;background:url(../images/tangram-colorpicker.png) -179px -12px no-repeat}.edui-colorpicker-slider{width:100%;height:100%;cursor:pointer}.edui-colorpicker-thumb{position:absolute;top:0;cursor:pointer;height:3px;left:-1px;right:-1px;border:1px solid #000;background:#fff;opacity:.8}.edui-default .edui-autotypesetpicker .edui-autotypesetpicker-body{font-size:12px;margin-bottom:3px;clear:both}.edui-default .edui-autotypesetpicker-body table{border-collapse:separate;border-spacing:2px}.edui-default .edui-autotypesetpicker-body td{font-size:12px;word-wrap:break-word}.edui-default .edui-autotypesetpicker-body td input{margin:3px 3px 3px 4px;*margin:1px 0 0}.edui-default .edui-cellalignpicker .edui-cellalignpicker-body{width:70px;font-size:12px;cursor:default}.edui-default .edui-cellalignpicker-body table{border-collapse:separate;border-spacing:0}.edui-default .edui-cellalignpicker-body td{padding:1px}.edui-default .edui-cellalignpicker-body .edui-icon{height:20px;width:20px;padding:1px;background-image:url(../images/table-cell-align.png)}.edui-default .edui-cellalignpicker-body .edui-left{background-position:0 0}.edui-default .edui-cellalignpicker-body .edui-center{background-position:-25px 0}.edui-default .edui-cellalignpicker-body .edui-right{background-position:-51px 0}.edui-default .edui-cellalignpicker-body td.edui-state-hover .edui-left{background-position:-73px 0}.edui-default .edui-cellalignpicker-body td.edui-state-hover .edui-center{background-position:-98px 0}.edui-default .edui-cellalignpicker-body td.edui-state-hover .edui-right{background-position:-124px 0}.edui-default .edui-cellalignpicker-body td.edui-cellalign-selected .edui-left{background-position:-146px 0;background-color:#f1f4f5}.edui-default .edui-cellalignpicker-body td.edui-cellalign-selected .edui-center{background-position:-245px 0}.edui-default .edui-cellalignpicker-body td.edui-cellalign-selected .edui-right{background-position:-271px 0}.edui-default .edui-toolbar .edui-separator{width:2px;height:20px;margin:2px 4px 2px 3px;background:url(../images/icons.png) -181px 0;background:url(../images/icons.gif) -181px 0 \9}.edui-default .edui-toolbar .edui-colorbutton .edui-colorlump{position:absolute;overflow:hidden;bottom:1px;left:1px;width:18px;height:4px}.edui-default .edui-for-emotion .edui-icon{background-position:-60px -20px}.edui-default .edui-for-emotion .edui-popup-content iframe{width:514px;height:380px;overflow:hidden}.edui-default .edui-for-emotion .edui-popup-content{position:relative;z-index:555}.edui-default .edui-for-emotion .edui-splitborder{display:none}.edui-default .edui-for-emotion .edui-splitbutton-body .edui-arrow{width:0}.edui-default .edui-toolbar .edui-for-emotion .edui-state-active .edui-splitborder{border-left:1px solid transparent}.edui-default .edui-hassubmenu .edui-arrow{height:20px;width:20px;float:right;background:url(../images/icons-all.gif) no-repeat 10px -233px}.edui-default .edui-menu-body .edui-menuitem{padding:1px}.edui-default .edui-menuseparator{margin:2px 0;height:1px;overflow:hidden}.edui-default .edui-menuseparator-inner{border-bottom:1px solid #e2e3e3;margin-left:29px;margin-right:1px}.edui-default .edui-menu-body .edui-state-hover{padding:0!important;background-color:#fff5d4;border:1px solid #dcac6c}.edui-default .edui-shortcutmenu{padding:2px;width:190px;height:50px;background-color:#fff;border:1px solid #ccc;border-radius:5px}.edui-default .edui-wordpastepop .edui-popup-content{border:0;padding:0;width:54px;height:21px}.edui-default .edui-pasteicon{width:100%;height:100%;background-image:url(../images/wordpaste.png);background-position:0 0}.edui-default .edui-pasteicon.edui-state-opened{background-position:0 -34px}.edui-default .edui-pastecontainer{position:relative;visibility:hidden;width:97px;background:#fff;border:1px solid #ccc}.edui-default .edui-pastecontainer .edui-title{font-weight:700;background:#F8F8FF;height:25px;line-height:25px;font-size:12px;padding-left:5px}.edui-default .edui-pastecontainer .edui-button{overflow:hidden;margin:3px 0}.edui-default .edui-pastecontainer .edui-button .edui-richtxticon,.edui-default .edui-pastecontainer .edui-button .edui-tagicon,.edui-default .edui-pastecontainer .edui-button .edui-plaintxticon{float:left;cursor:pointer;width:29px;height:29px;margin-left:5px;background-image:url(../images/wordpaste.png);background-repeat:no-repeat}.edui-default .edui-pastecontainer .edui-button .edui-richtxticon{margin-left:0;background-position:-109px 0}.edui-default .edui-pastecontainer .edui-button .edui-tagicon{background-position:-148px 1px}.edui-default .edui-pastecontainer .edui-button .edui-plaintxticon{background-position:-72px 0}.edui-default .edui-pastecontainer .edui-button .edui-state-hover .edui-richtxticon{background-position:-109px -34px}.edui-default .edui-pastecontainer .edui-button .edui-state-hover .edui-tagicon{background-position:-148px -34px}.edui-default .edui-pastecontainer .edui-button .edui-state-hover .edui-plaintxticon{background-position:-72px -34px} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/dialogbase.css b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/dialogbase.css new file mode 100644 index 000000000..cd663d5de --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/dialogbase.css @@ -0,0 +1,100 @@ +/*弹出对话框页面样式组件 +*/ + +/*reset +*/ +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, font, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + outline: 0; + font-size: 100%; +} + +body { + line-height: 1; +} + +ol, ul { + list-style: none; +} + +blockquote, q { + quotes: none; +} + +ins { + text-decoration: none; +} + +del { + text-decoration: line-through; +} + +table { + border-collapse: collapse; + border-spacing: 0; +} + +/*module +*/ +body { + background-color: #fff; + font: 12px/1.5 sans-serif, "宋体", "Arial Narrow", HELVETICA; + color: #646464; +} + +/*tab*/ +.tabhead { + position: relative; + z-index: 10; +} + +.tabhead span { + display: inline-block; + padding: 0 5px; + height: 30px; + border: 1px solid #ccc; + background: url("images/dialog-title-bg.png") repeat-x; + text-align: center; + line-height: 30px; + cursor: pointer; + *margin-right: 5px; +} + +.tabhead span.focus { + height: 31px; + border-bottom: none; + background: #fff; +} + +.tabbody { + position: relative; + top: -1px; + margin: 0 auto; + border: 1px solid #ccc; +} + +/*button*/ +a.button { + display: block; + text-align: center; + line-height: 24px; + text-decoration: none; + height: 24px; + width: 95px; + border: 0; + color: #838383; + background: url(../../themes/default/images/icons-all.gif) no-repeat; +} + +a.button:hover { + background-position: 0 -30px; +} \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/anchor.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/anchor.gif new file mode 100644 index 000000000..5aa797b22 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/anchor.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/arrow.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/arrow.png new file mode 100644 index 000000000..d9008866b Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/arrow.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/arrow_down.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/arrow_down.png new file mode 100644 index 000000000..e9257e83b Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/arrow_down.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/arrow_up.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/arrow_up.png new file mode 100644 index 000000000..74277af1e Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/arrow_up.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/button-bg.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/button-bg.gif new file mode 100644 index 000000000..ec7fa2eab Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/button-bg.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/cancelbutton.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/cancelbutton.gif new file mode 100644 index 000000000..df4bc2c06 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/cancelbutton.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/charts.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/charts.png new file mode 100644 index 000000000..713965cc4 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/charts.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/cursor_h.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/cursor_h.gif new file mode 100644 index 000000000..d7c3e7e9e Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/cursor_h.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/cursor_h.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/cursor_h.png new file mode 100644 index 000000000..2088fc240 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/cursor_h.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/cursor_v.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/cursor_v.gif new file mode 100644 index 000000000..bb508db55 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/cursor_v.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/cursor_v.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/cursor_v.png new file mode 100644 index 000000000..6f39ca3d8 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/cursor_v.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/dialog-title-bg.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/dialog-title-bg.png new file mode 100644 index 000000000..f744f267f Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/dialog-title-bg.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/filescan.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/filescan.png new file mode 100644 index 000000000..1d2715886 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/filescan.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/highlighted.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/highlighted.gif new file mode 100644 index 000000000..9272b4915 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/highlighted.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/icons-all.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/icons-all.gif new file mode 100644 index 000000000..21915e59d Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/icons-all.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/icons.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/icons.gif new file mode 100644 index 000000000..7abd30a1c Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/icons.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/icons.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/icons.png new file mode 100644 index 000000000..c015e3aac Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/icons.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/loaderror.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/loaderror.png new file mode 100644 index 000000000..35ff33364 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/loaderror.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/loading.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/loading.gif new file mode 100644 index 000000000..b713e27df Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/loading.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/lock.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/lock.gif new file mode 100644 index 000000000..b4e6d7822 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/lock.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/neweditor-tab-bg.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/neweditor-tab-bg.png new file mode 100644 index 000000000..8f398b095 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/neweditor-tab-bg.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/pagebreak.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/pagebreak.gif new file mode 100644 index 000000000..8d1cffd64 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/pagebreak.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/scale.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/scale.png new file mode 100644 index 000000000..f45adb585 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/scale.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/sortable.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/sortable.png new file mode 100644 index 000000000..1bca64969 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/sortable.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/spacer.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/spacer.gif new file mode 100644 index 000000000..5bfd67a2d Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/spacer.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/sparator_v.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/sparator_v.png new file mode 100644 index 000000000..8cf5662da Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/sparator_v.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/table-cell-align.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/table-cell-align.png new file mode 100644 index 000000000..ddf42853e Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/table-cell-align.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/tangram-colorpicker.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/tangram-colorpicker.png new file mode 100644 index 000000000..738e500cf Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/tangram-colorpicker.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/toolbar_bg.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/toolbar_bg.png new file mode 100644 index 000000000..7ab685f42 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/toolbar_bg.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/unhighlighted.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/unhighlighted.gif new file mode 100644 index 000000000..7ad0b67ae Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/unhighlighted.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/upload.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/upload.png new file mode 100644 index 000000000..08d4d9268 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/upload.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/videologo.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/videologo.gif new file mode 100644 index 000000000..555af7417 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/videologo.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/word.gif b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/word.gif new file mode 100644 index 000000000..9ef5d09b7 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/word.gif differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/wordpaste.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/wordpaste.png new file mode 100644 index 000000000..936775810 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/default/images/wordpaste.png differ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/iframe.css b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/iframe.css new file mode 100644 index 000000000..774013afd --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/themes/iframe.css @@ -0,0 +1 @@ +/*可以在这里添加你自己的css*/ diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/third-party/SyntaxHighlighter/shCore.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/third-party/SyntaxHighlighter/shCore.js new file mode 100644 index 000000000..324918425 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/third-party/SyntaxHighlighter/shCore.js @@ -0,0 +1,3655 @@ +// XRegExp 1.5.1 +// (c) 2007-2012 Steven Levithan +// MIT License +// +// Provides an augmented, extensible, cross-browser implementation of regular expressions, +// including support for additional syntax, flags, and methods + +var XRegExp; + +if (XRegExp) { + // Avoid running twice, since that would break references to native globals + throw Error("can't load XRegExp twice in the same frame"); +} + +// Run within an anonymous function to protect variables and avoid new globals +(function (undefined) { + + //--------------------------------- + // Constructor + //--------------------------------- + + // Accepts a pattern and flags; returns a new, extended `RegExp` object. Differs from a native + // regular expression in that additional syntax and flags are supported and cross-browser + // syntax inconsistencies are ameliorated. `XRegExp(/regex/)` clones an existing regex and + // converts to type XRegExp + XRegExp = function (pattern, flags) { + var output = [], + currScope = XRegExp.OUTSIDE_CLASS, + pos = 0, + context, tokenResult, match, chr, regex; + + if (XRegExp.isRegExp(pattern)) { + if (flags !== undefined) + throw TypeError("can't supply flags when constructing one RegExp from another"); + return clone(pattern); + } + // Tokens become part of the regex construction process, so protect against infinite + // recursion when an XRegExp is constructed within a token handler or trigger + if (isInsideConstructor) + throw Error("can't call the XRegExp constructor within token definition functions"); + + flags = flags || ""; + context = { // `this` object for custom tokens + hasNamedCapture: false, + captureNames: [], + hasFlag: function (flag) {return flags.indexOf(flag) > -1;}, + setFlag: function (flag) {flags += flag;} + }; + + while (pos < pattern.length) { + // Check for custom tokens at the current position + tokenResult = runTokens(pattern, pos, currScope, context); + + if (tokenResult) { + output.push(tokenResult.output); + pos += (tokenResult.match[0].length || 1); + } else { + // Check for native multicharacter metasequences (excluding character classes) at + // the current position + if (match = nativ.exec.call(nativeTokens[currScope], pattern.slice(pos))) { + output.push(match[0]); + pos += match[0].length; + } else { + chr = pattern.charAt(pos); + if (chr === "[") + currScope = XRegExp.INSIDE_CLASS; + else if (chr === "]") + currScope = XRegExp.OUTSIDE_CLASS; + // Advance position one character + output.push(chr); + pos++; + } + } + } + + regex = RegExp(output.join(""), nativ.replace.call(flags, flagClip, "")); + regex._xregexp = { + source: pattern, + captureNames: context.hasNamedCapture ? context.captureNames : null + }; + return regex; + }; + + + //--------------------------------- + // Public properties + //--------------------------------- + + XRegExp.version = "1.5.1"; + + // Token scope bitflags + XRegExp.INSIDE_CLASS = 1; + XRegExp.OUTSIDE_CLASS = 2; + + + //--------------------------------- + // Private variables + //--------------------------------- + + var replacementToken = /\$(?:(\d\d?|[$&`'])|{([$\w]+)})/g, + flagClip = /[^gimy]+|([\s\S])(?=[\s\S]*\1)/g, // Nonnative and duplicate flags + quantifier = /^(?:[?*+]|{\d+(?:,\d*)?})\??/, + isInsideConstructor = false, + tokens = [], + // Copy native globals for reference ("native" is an ES3 reserved keyword) + nativ = { + exec: RegExp.prototype.exec, + test: RegExp.prototype.test, + match: String.prototype.match, + replace: String.prototype.replace, + split: String.prototype.split + }, + compliantExecNpcg = nativ.exec.call(/()??/, "")[1] === undefined, // check `exec` handling of nonparticipating capturing groups + compliantLastIndexIncrement = function () { + var x = /^/g; + nativ.test.call(x, ""); + return !x.lastIndex; + }(), + hasNativeY = RegExp.prototype.sticky !== undefined, + nativeTokens = {}; + + // `nativeTokens` match native multicharacter metasequences only (including deprecated octals, + // excluding character classes) + nativeTokens[XRegExp.INSIDE_CLASS] = /^(?:\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\dA-Fa-f]{2}|u[\dA-Fa-f]{4}|c[A-Za-z]|[\s\S]))/; + nativeTokens[XRegExp.OUTSIDE_CLASS] = /^(?:\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\d*|x[\dA-Fa-f]{2}|u[\dA-Fa-f]{4}|c[A-Za-z]|[\s\S])|\(\?[:=!]|[?*+]\?|{\d+(?:,\d*)?}\??)/; + + + //--------------------------------- + // Public methods + //--------------------------------- + + // Lets you extend or change XRegExp syntax and create custom flags. This is used internally by + // the XRegExp library and can be used to create XRegExp plugins. This function is intended for + // users with advanced knowledge of JavaScript's regular expression syntax and behavior. It can + // be disabled by `XRegExp.freezeTokens` + XRegExp.addToken = function (regex, handler, scope, trigger) { + tokens.push({ + pattern: clone(regex, "g" + (hasNativeY ? "y" : "")), + handler: handler, + scope: scope || XRegExp.OUTSIDE_CLASS, + trigger: trigger || null + }); + }; + + // Accepts a pattern and flags; returns an extended `RegExp` object. If the pattern and flag + // combination has previously been cached, the cached copy is returned; otherwise the newly + // created regex is cached + XRegExp.cache = function (pattern, flags) { + var key = pattern + "/" + (flags || ""); + return XRegExp.cache[key] || (XRegExp.cache[key] = XRegExp(pattern, flags)); + }; + + // Accepts a `RegExp` instance; returns a copy with the `/g` flag set. The copy has a fresh + // `lastIndex` (set to zero). If you want to copy a regex without forcing the `global` + // property, use `XRegExp(regex)`. Do not use `RegExp(regex)` because it will not preserve + // special properties required for named capture + XRegExp.copyAsGlobal = function (regex) { + return clone(regex, "g"); + }; + + // Accepts a string; returns the string with regex metacharacters escaped. The returned string + // can safely be used at any point within a regex to match the provided literal string. Escaped + // characters are [ ] { } ( ) * + ? - . , \ ^ $ | # and whitespace + XRegExp.escape = function (str) { + return str.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&"); + }; + + // Accepts a string to search, regex to search with, position to start the search within the + // string (default: 0), and an optional Boolean indicating whether matches must start at-or- + // after the position or at the specified position only. This function ignores the `lastIndex` + // of the provided regex in its own handling, but updates the property for compatibility + XRegExp.execAt = function (str, regex, pos, anchored) { + var r2 = clone(regex, "g" + ((anchored && hasNativeY) ? "y" : "")), + match; + r2.lastIndex = pos = pos || 0; + match = r2.exec(str); // Run the altered `exec` (required for `lastIndex` fix, etc.) + if (anchored && match && match.index !== pos) + match = null; + if (regex.global) + regex.lastIndex = match ? r2.lastIndex : 0; + return match; + }; + + // Breaks the unrestorable link to XRegExp's private list of tokens, thereby preventing + // syntax and flag changes. Should be run after XRegExp and any plugins are loaded + XRegExp.freezeTokens = function () { + XRegExp.addToken = function () { + throw Error("can't run addToken after freezeTokens"); + }; + }; + + // Accepts any value; returns a Boolean indicating whether the argument is a `RegExp` object. + // Note that this is also `true` for regex literals and regexes created by the `XRegExp` + // constructor. This works correctly for variables created in another frame, when `instanceof` + // and `constructor` checks would fail to work as intended + XRegExp.isRegExp = function (o) { + return Object.prototype.toString.call(o) === "[object RegExp]"; + }; + + // Executes `callback` once per match within `str`. Provides a simpler and cleaner way to + // iterate over regex matches compared to the traditional approaches of subverting + // `String.prototype.replace` or repeatedly calling `exec` within a `while` loop + XRegExp.iterate = function (str, regex, callback, context) { + var r2 = clone(regex, "g"), + i = -1, match; + while (match = r2.exec(str)) { // Run the altered `exec` (required for `lastIndex` fix, etc.) + if (regex.global) + regex.lastIndex = r2.lastIndex; // Doing this to follow expectations if `lastIndex` is checked within `callback` + callback.call(context, match, ++i, str, regex); + if (r2.lastIndex === match.index) + r2.lastIndex++; + } + if (regex.global) + regex.lastIndex = 0; + }; + + // Accepts a string and an array of regexes; returns the result of using each successive regex + // to search within the matches of the previous regex. The array of regexes can also contain + // objects with `regex` and `backref` properties, in which case the named or numbered back- + // references specified are passed forward to the next regex or returned. E.g.: + // var xregexpImgFileNames = XRegExp.matchChain(html, [ + // {regex: /]+)>/i, backref: 1}, // tag attributes + // {regex: XRegExp('(?ix) \\s src=" (? [^"]+ )'), backref: "src"}, // src attribute values + // {regex: XRegExp("^http://xregexp\\.com(/[^#?]+)", "i"), backref: 1}, // xregexp.com paths + // /[^\/]+$/ // filenames (strip directory paths) + // ]); + XRegExp.matchChain = function (str, chain) { + return function recurseChain (values, level) { + var item = chain[level].regex ? chain[level] : {regex: chain[level]}, + regex = clone(item.regex, "g"), + matches = [], i; + for (i = 0; i < values.length; i++) { + XRegExp.iterate(values[i], regex, function (match) { + matches.push(item.backref ? (match[item.backref] || "") : match[0]); + }); + } + return ((level === chain.length - 1) || !matches.length) ? + matches : recurseChain(matches, level + 1); + }([str], 0); + }; + + + //--------------------------------- + // New RegExp prototype methods + //--------------------------------- + + // Accepts a context object and arguments array; returns the result of calling `exec` with the + // first value in the arguments array. the context is ignored but is accepted for congruity + // with `Function.prototype.apply` + RegExp.prototype.apply = function (context, args) { + return this.exec(args[0]); + }; + + // Accepts a context object and string; returns the result of calling `exec` with the provided + // string. the context is ignored but is accepted for congruity with `Function.prototype.call` + RegExp.prototype.call = function (context, str) { + return this.exec(str); + }; + + + //--------------------------------- + // Overriden native methods + //--------------------------------- + + // Adds named capture support (with backreferences returned as `result.name`), and fixes two + // cross-browser issues per ES3: + // - Captured values for nonparticipating capturing groups should be returned as `undefined`, + // rather than the empty string. + // - `lastIndex` should not be incremented after zero-length matches. + RegExp.prototype.exec = function (str) { + var match, name, r2, origLastIndex; + if (!this.global) + origLastIndex = this.lastIndex; + match = nativ.exec.apply(this, arguments); + if (match) { + // Fix browsers whose `exec` methods don't consistently return `undefined` for + // nonparticipating capturing groups + if (!compliantExecNpcg && match.length > 1 && indexOf(match, "") > -1) { + r2 = RegExp(this.source, nativ.replace.call(getNativeFlags(this), "g", "")); + // Using `str.slice(match.index)` rather than `match[0]` in case lookahead allowed + // matching due to characters outside the match + nativ.replace.call((str + "").slice(match.index), r2, function () { + for (var i = 1; i < arguments.length - 2; i++) { + if (arguments[i] === undefined) + match[i] = undefined; + } + }); + } + // Attach named capture properties + if (this._xregexp && this._xregexp.captureNames) { + for (var i = 1; i < match.length; i++) { + name = this._xregexp.captureNames[i - 1]; + if (name) + match[name] = match[i]; + } + } + // Fix browsers that increment `lastIndex` after zero-length matches + if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index)) + this.lastIndex--; + } + if (!this.global) + this.lastIndex = origLastIndex; // Fix IE, Opera bug (last tested IE 9.0.5, Opera 11.61 on Windows) + return match; + }; + + // Fix browser bugs in native method + RegExp.prototype.test = function (str) { + // Use the native `exec` to skip some processing overhead, even though the altered + // `exec` would take care of the `lastIndex` fixes + var match, origLastIndex; + if (!this.global) + origLastIndex = this.lastIndex; + match = nativ.exec.call(this, str); + // Fix browsers that increment `lastIndex` after zero-length matches + if (match && !compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index)) + this.lastIndex--; + if (!this.global) + this.lastIndex = origLastIndex; // Fix IE, Opera bug (last tested IE 9.0.5, Opera 11.61 on Windows) + return !!match; + }; + + // Adds named capture support and fixes browser bugs in native method + String.prototype.match = function (regex) { + if (!XRegExp.isRegExp(regex)) + regex = RegExp(regex); // Native `RegExp` + if (regex.global) { + var result = nativ.match.apply(this, arguments); + regex.lastIndex = 0; // Fix IE bug + return result; + } + return regex.exec(this); // Run the altered `exec` + }; + + // Adds support for `${n}` tokens for named and numbered backreferences in replacement text, + // and provides named backreferences to replacement functions as `arguments[0].name`. Also + // fixes cross-browser differences in replacement text syntax when performing a replacement + // using a nonregex search value, and the value of replacement regexes' `lastIndex` property + // during replacement iterations. Note that this doesn't support SpiderMonkey's proprietary + // third (`flags`) parameter + String.prototype.replace = function (search, replacement) { + var isRegex = XRegExp.isRegExp(search), + captureNames, result, str, origLastIndex; + + // There are too many combinations of search/replacement types/values and browser bugs that + // preclude passing to native `replace`, so don't try + //if (...) + // return nativ.replace.apply(this, arguments); + + if (isRegex) { + if (search._xregexp) + captureNames = search._xregexp.captureNames; // Array or `null` + if (!search.global) + origLastIndex = search.lastIndex; + } else { + search = search + ""; // Type conversion + } + + if (Object.prototype.toString.call(replacement) === "[object Function]") { + result = nativ.replace.call(this + "", search, function () { + if (captureNames) { + // Change the `arguments[0]` string primitive to a String object which can store properties + arguments[0] = new String(arguments[0]); + // Store named backreferences on `arguments[0]` + for (var i = 0; i < captureNames.length; i++) { + if (captureNames[i]) + arguments[0][captureNames[i]] = arguments[i + 1]; + } + } + // Update `lastIndex` before calling `replacement` (fix browsers) + if (isRegex && search.global) + search.lastIndex = arguments[arguments.length - 2] + arguments[0].length; + return replacement.apply(null, arguments); + }); + } else { + str = this + ""; // Type conversion, so `args[args.length - 1]` will be a string (given nonstring `this`) + result = nativ.replace.call(str, search, function () { + var args = arguments; // Keep this function's `arguments` available through closure + return nativ.replace.call(replacement + "", replacementToken, function ($0, $1, $2) { + // Numbered backreference (without delimiters) or special variable + if ($1) { + switch ($1) { + case "$": return "$"; + case "&": return args[0]; + case "`": return args[args.length - 1].slice(0, args[args.length - 2]); + case "'": return args[args.length - 1].slice(args[args.length - 2] + args[0].length); + // Numbered backreference + default: + // What does "$10" mean? + // - Backreference 10, if 10 or more capturing groups exist + // - Backreference 1 followed by "0", if 1-9 capturing groups exist + // - Otherwise, it's the string "$10" + // Also note: + // - Backreferences cannot be more than two digits (enforced by `replacementToken`) + // - "$01" is equivalent to "$1" if a capturing group exists, otherwise it's the string "$01" + // - There is no "$0" token ("$&" is the entire match) + var literalNumbers = ""; + $1 = +$1; // Type conversion; drop leading zero + if (!$1) // `$1` was "0" or "00" + return $0; + while ($1 > args.length - 3) { + literalNumbers = String.prototype.slice.call($1, -1) + literalNumbers; + $1 = Math.floor($1 / 10); // Drop the last digit + } + return ($1 ? args[$1] || "" : "$") + literalNumbers; + } + // Named backreference or delimited numbered backreference + } else { + // What does "${n}" mean? + // - Backreference to numbered capture n. Two differences from "$n": + // - n can be more than two digits + // - Backreference 0 is allowed, and is the entire match + // - Backreference to named capture n, if it exists and is not a number overridden by numbered capture + // - Otherwise, it's the string "${n}" + var n = +$2; // Type conversion; drop leading zeros + if (n <= args.length - 3) + return args[n]; + n = captureNames ? indexOf(captureNames, $2) : -1; + return n > -1 ? args[n + 1] : $0; + } + }); + }); + } + + if (isRegex) { + if (search.global) + search.lastIndex = 0; // Fix IE, Safari bug (last tested IE 9.0.5, Safari 5.1.2 on Windows) + else + search.lastIndex = origLastIndex; // Fix IE, Opera bug (last tested IE 9.0.5, Opera 11.61 on Windows) + } + + return result; + }; + + // A consistent cross-browser, ES3 compliant `split` + String.prototype.split = function (s /* separator */, limit) { + // If separator `s` is not a regex, use the native `split` + if (!XRegExp.isRegExp(s)) + return nativ.split.apply(this, arguments); + + var str = this + "", // Type conversion + output = [], + lastLastIndex = 0, + match, lastLength; + + // Behavior for `limit`: if it's... + // - `undefined`: No limit + // - `NaN` or zero: Return an empty array + // - A positive number: Use `Math.floor(limit)` + // - A negative number: No limit + // - Other: Type-convert, then use the above rules + if (limit === undefined || +limit < 0) { + limit = Infinity; + } else { + limit = Math.floor(+limit); + if (!limit) + return []; + } + + // This is required if not `s.global`, and it avoids needing to set `s.lastIndex` to zero + // and restore it to its original value when we're done using the regex + s = XRegExp.copyAsGlobal(s); + + while (match = s.exec(str)) { // Run the altered `exec` (required for `lastIndex` fix, etc.) + if (s.lastIndex > lastLastIndex) { + output.push(str.slice(lastLastIndex, match.index)); + + if (match.length > 1 && match.index < str.length) + Array.prototype.push.apply(output, match.slice(1)); + + lastLength = match[0].length; + lastLastIndex = s.lastIndex; + + if (output.length >= limit) + break; + } + + if (s.lastIndex === match.index) + s.lastIndex++; + } + + if (lastLastIndex === str.length) { + if (!nativ.test.call(s, "") || lastLength) + output.push(""); + } else { + output.push(str.slice(lastLastIndex)); + } + + return output.length > limit ? output.slice(0, limit) : output; + }; + + + //--------------------------------- + // Private helper functions + //--------------------------------- + + // Supporting function for `XRegExp`, `XRegExp.copyAsGlobal`, etc. Returns a copy of a `RegExp` + // instance with a fresh `lastIndex` (set to zero), preserving properties required for named + // capture. Also allows adding new flags in the process of copying the regex + function clone (regex, additionalFlags) { + if (!XRegExp.isRegExp(regex)) + throw TypeError("type RegExp expected"); + var x = regex._xregexp; + regex = XRegExp(regex.source, getNativeFlags(regex) + (additionalFlags || "")); + if (x) { + regex._xregexp = { + source: x.source, + captureNames: x.captureNames ? x.captureNames.slice(0) : null + }; + } + return regex; + } + + function getNativeFlags (regex) { + return (regex.global ? "g" : "") + + (regex.ignoreCase ? "i" : "") + + (regex.multiline ? "m" : "") + + (regex.extended ? "x" : "") + // Proposed for ES4; included in AS3 + (regex.sticky ? "y" : ""); + } + + function runTokens (pattern, index, scope, context) { + var i = tokens.length, + result, match, t; + // Protect against constructing XRegExps within token handler and trigger functions + isInsideConstructor = true; + // Must reset `isInsideConstructor`, even if a `trigger` or `handler` throws + try { + while (i--) { // Run in reverse order + t = tokens[i]; + if ((scope & t.scope) && (!t.trigger || t.trigger.call(context))) { + t.pattern.lastIndex = index; + match = t.pattern.exec(pattern); // Running the altered `exec` here allows use of named backreferences, etc. + if (match && match.index === index) { + result = { + output: t.handler.call(context, match, scope), + match: match + }; + break; + } + } + } + } catch (err) { + throw err; + } finally { + isInsideConstructor = false; + } + return result; + } + + function indexOf (array, item, from) { + if (Array.prototype.indexOf) // Use the native array method if available + return array.indexOf(item, from); + for (var i = from || 0; i < array.length; i++) { + if (array[i] === item) + return i; + } + return -1; + } + + + //--------------------------------- + // Built-in tokens + //--------------------------------- + + // Augment XRegExp's regular expression syntax and flags. Note that when adding tokens, the + // third (`scope`) argument defaults to `XRegExp.OUTSIDE_CLASS` + + // Comment pattern: (?# ) + XRegExp.addToken( + /\(\?#[^)]*\)/, + function (match) { + // Keep tokens separated unless the following token is a quantifier + return nativ.test.call(quantifier, match.input.slice(match.index + match[0].length)) ? "" : "(?:)"; + } + ); + + // Capturing group (match the opening parenthesis only). + // Required for support of named capturing groups + XRegExp.addToken( + /\((?!\?)/, + function () { + this.captureNames.push(null); + return "("; + } + ); + + // Named capturing group (match the opening delimiter only): (? + XRegExp.addToken( + /\(\?<([$\w]+)>/, + function (match) { + this.captureNames.push(match[1]); + this.hasNamedCapture = true; + return "("; + } + ); + + // Named backreference: \k + XRegExp.addToken( + /\\k<([\w$]+)>/, + function (match) { + var index = indexOf(this.captureNames, match[1]); + // Keep backreferences separate from subsequent literal numbers. Preserve back- + // references to named groups that are undefined at this point as literal strings + return index > -1 ? + "\\" + (index + 1) + (isNaN(match.input.charAt(match.index + match[0].length)) ? "" : "(?:)") : + match[0]; + } + ); + + // Empty character class: [] or [^] + XRegExp.addToken( + /\[\^?]/, + function (match) { + // For cross-browser compatibility with ES3, convert [] to \b\B and [^] to [\s\S]. + // (?!) should work like \b\B, but is unreliable in Firefox + return match[0] === "[]" ? "\\b\\B" : "[\\s\\S]"; + } + ); + + // Mode modifier at the start of the pattern only, with any combination of flags imsx: (?imsx) + // Does not support x(?i), (?-i), (?i-m), (?i: ), (?i)(?m), etc. + XRegExp.addToken( + /^\(\?([imsx]+)\)/, + function (match) { + this.setFlag(match[1]); + return ""; + } + ); + + // Whitespace and comments, in free-spacing (aka extended) mode only + XRegExp.addToken( + /(?:\s+|#.*)+/, + function (match) { + // Keep tokens separated unless the following token is a quantifier + return nativ.test.call(quantifier, match.input.slice(match.index + match[0].length)) ? "" : "(?:)"; + }, + XRegExp.OUTSIDE_CLASS, + function () {return this.hasFlag("x");} + ); + + // Dot, in dotall (aka singleline) mode only + XRegExp.addToken( + /\./, + function () {return "[\\s\\S]";}, + XRegExp.OUTSIDE_CLASS, + function () {return this.hasFlag("s");} + ); + + + //--------------------------------- + // Backward compatibility + //--------------------------------- + + // Uncomment the following block for compatibility with XRegExp 1.0-1.2: + /* + XRegExp.matchWithinChain = XRegExp.matchChain; + RegExp.prototype.addFlags = function (s) {return clone(this, s);}; + RegExp.prototype.execAll = function (s) {var r = []; XRegExp.iterate(s, this, function (m) {r.push(m);}); return r;}; + RegExp.prototype.forEachExec = function (s, f, c) {return XRegExp.iterate(s, this, f, c);}; + RegExp.prototype.validate = function (s) {var r = RegExp("^(?:" + this.source + ")$(?!\\s)", getNativeFlags(this)); if (this.global) this.lastIndex = 0; return s.search(r) === 0;}; + */ + +})(); + +// +// Begin anonymous function. This is used to contain local scope variables without polutting global scope. +// +if (typeof(SyntaxHighlighter) == 'undefined') var SyntaxHighlighter = function() { + +// CommonJS + if (typeof(require) != 'undefined' && typeof(XRegExp) == 'undefined') + { + XRegExp = require('XRegExp').XRegExp; + } + +// Shortcut object which will be assigned to the SyntaxHighlighter variable. +// This is a shorthand for local reference in order to avoid long namespace +// references to SyntaxHighlighter.whatever... + var sh = { + defaults : { + /** Additional CSS class names to be added to highlighter elements. */ + 'class-name' : '', + + /** First line number. */ + 'first-line' : 1, + + /** + * Pads line numbers. Possible values are: + * + * false - don't pad line numbers. + * true - automaticaly pad numbers with minimum required number of leading zeroes. + * [int] - length up to which pad line numbers. + */ + 'pad-line-numbers' : false, + + /** Lines to highlight. */ + 'highlight' : false, + + /** Title to be displayed above the code block. */ + 'title' : null, + + /** Enables or disables smart tabs. */ + 'smart-tabs' : true, + + /** Gets or sets tab size. */ + 'tab-size' : 4, + + /** Enables or disables gutter. */ + 'gutter' : true, + + /** Enables or disables toolbar. */ + 'toolbar' : true, + + /** Enables quick code copy and paste from double click. */ + 'quick-code' : true, + + /** Forces code view to be collapsed. */ + 'collapse' : false, + + /** Enables or disables automatic links. */ + 'auto-links' : false, + + /** Gets or sets light mode. Equavalent to turning off gutter and toolbar. */ + 'light' : false, + + 'unindent' : true, + + 'html-script' : false + }, + + config : { + space : ' ', + + /** Enables use of + * + * ``` + */ + findParent:function (node, filterFn, includeSelf) { + if (node && !domUtils.isBody(node)) { + node = includeSelf ? node : node.parentNode; + while (node) { + if (!filterFn || filterFn(node) || domUtils.isBody(node)) { + return filterFn && !filterFn(node) && domUtils.isBody(node) ? null : node; + } + node = node.parentNode; + } + } + return null; + }, + /** + * 查找node的节点名为tagName的第一个祖先节点, 查找的起点是node节点的父节点。 + * @method findParentByTagName + * @param { Node } node 需要查找的节点对象 + * @param { Array } tagNames 需要查找的父节点的名称数组 + * @warning 查找的终点是到body节点为止 + * @return { Node | NULL } 如果找到符合条件的节点, 则返回该节点, 否则返回NULL + * @example + * ```javascript + * var node = UE.dom.domUtils.findParentByTagName( document.getElementsByTagName("div")[0], [ "BODY" ] ); + * //output: BODY + * console.log( node.tagName ); + * ``` + */ + + /** + * 查找node的节点名为tagName的祖先节点, 如果includeSelf的值为true,则查找的起点是给定的节点node, + * 否则, 起点是node的父节点。 + * @method findParentByTagName + * @param { Node } node 需要查找的节点对象 + * @param { Array } tagNames 需要查找的父节点的名称数组 + * @param { Boolean } includeSelf 查找过程是否包含node节点自身 + * @warning 查找的终点是到body节点为止 + * @return { Node | NULL } 如果找到符合条件的节点, 则返回该节点, 否则返回NULL + * @example + * ```javascript + * var queryTarget = document.getElementsByTagName("div")[0]; + * var node = UE.dom.domUtils.findParentByTagName( queryTarget, [ "DIV" ], true ); + * //output: true + * console.log( queryTarget === node ); + * ``` + */ + findParentByTagName:function (node, tagNames, includeSelf, excludeFn) { + tagNames = utils.listToMap(utils.isArray(tagNames) ? tagNames : [tagNames]); + return domUtils.findParent(node, function (node) { + return tagNames[node.tagName] && !(excludeFn && excludeFn(node)); + }, includeSelf); + }, + /** + * 查找节点node的祖先节点集合, 查找的起点是给定节点的父节点,结果集中不包含给定的节点。 + * @method findParents + * @param { Node } node 需要查找的节点对象 + * @return { Array } 给定节点的祖先节点数组 + * @grammar UE.dom.domUtils.findParents(node) => Array //返回一个祖先节点数组集合,不包含自身 + * @grammar UE.dom.domUtils.findParents(node,includeSelf) => Array //返回一个祖先节点数组集合,includeSelf指定是否包含自身 + * @grammar UE.dom.domUtils.findParents(node,includeSelf,filterFn) => Array //返回一个祖先节点数组集合,filterFn指定过滤条件,返回true的node将被选取 + * @grammar UE.dom.domUtils.findParents(node,includeSelf,filterFn,closerFirst) => Array //返回一个祖先节点数组集合,closerFirst为true的话,node的直接父亲节点是数组的第0个 + */ + + /** + * 查找节点node的祖先节点集合, 如果includeSelf的值为true, + * 则返回的结果集中允许出现当前给定的节点, 否则, 该节点不会出现在其结果集中。 + * @method findParents + * @param { Node } node 需要查找的节点对象 + * @param { Boolean } includeSelf 查找的结果中是否允许包含当前查找的节点对象 + * @return { Array } 给定节点的祖先节点数组 + */ + findParents:function (node, includeSelf, filterFn, closerFirst) { + var parents = includeSelf && ( filterFn && filterFn(node) || !filterFn ) ? [node] : []; + while (node = domUtils.findParent(node, filterFn)) { + parents.push(node); + } + return closerFirst ? parents : parents.reverse(); + }, + + /** + * 在节点node后面插入新节点newNode + * @method insertAfter + * @param { Node } node 目标节点 + * @param { Node } newNode 新插入的节点, 该节点将置于目标节点之后 + * @return { Node } 新插入的节点 + */ + insertAfter:function (node, newNode) { + return node.nextSibling ? node.parentNode.insertBefore(newNode, node.nextSibling): + node.parentNode.appendChild(newNode); + }, + + /** + * 删除节点node及其下属的所有节点 + * @method remove + * @param { Node } node 需要删除的节点对象 + * @return { Node } 返回刚删除的节点对象 + * @example + * ```html + *
          + *
          你好
          + *
          + * + * ``` + */ + + /** + * 删除节点node,并根据keepChildren的值决定是否保留子节点 + * @method remove + * @param { Node } node 需要删除的节点对象 + * @param { Boolean } keepChildren 是否需要保留子节点 + * @return { Node } 返回刚删除的节点对象 + * @example + * ```html + *
          + *
          你好
          + *
          + * + * ``` + */ + remove:function (node, keepChildren) { + var parent = node.parentNode, + child; + if (parent) { + if (keepChildren && node.hasChildNodes()) { + while (child = node.firstChild) { + parent.insertBefore(child, node); + } + } + parent.removeChild(node); + } + return node; + }, + + /** + * 取得node节点的下一个兄弟节点, 如果该节点其后没有兄弟节点, 则递归查找其父节点之后的第一个兄弟节点, + * 直到找到满足条件的节点或者递归到BODY节点之后才会结束。 + * @method getNextDomNode + * @param { Node } node 需要获取其后的兄弟节点的节点对象 + * @return { Node | NULL } 如果找满足条件的节点, 则返回该节点, 否则返回NULL + * @example + * ```html + * + *
          + * + *
          + * xxx + * + * + * ``` + * @example + * ```html + * + *
          + * + * xxx + *
          + * xxx + * + * + * ``` + */ + + /** + * 取得node节点的下一个兄弟节点, 如果startFromChild的值为ture,则先获取其子节点, + * 如果有子节点则直接返回第一个子节点;如果没有子节点或者startFromChild的值为false, + * 则执行getNextDomNode(Node node)的查找过程。 + * @method getNextDomNode + * @param { Node } node 需要获取其后的兄弟节点的节点对象 + * @param { Boolean } startFromChild 查找过程是否从其子节点开始 + * @return { Node | NULL } 如果找满足条件的节点, 则返回该节点, 否则返回NULL + * @see UE.dom.domUtils.getNextDomNode(Node) + */ + getNextDomNode:function (node, startFromChild, filterFn, guard) { + return getDomNode(node, 'firstChild', 'nextSibling', startFromChild, filterFn, guard); + }, + getPreDomNode:function (node, startFromChild, filterFn, guard) { + return getDomNode(node, 'lastChild', 'previousSibling', startFromChild, filterFn, guard); + }, + /** + * 检测节点node是否属是UEditor定义的bookmark节点 + * @method isBookmarkNode + * @private + * @param { Node } node 需要检测的节点对象 + * @return { Boolean } 是否是bookmark节点 + * @example + * ```html + * + * + * ``` + */ + isBookmarkNode:function (node) { + return node.nodeType == 1 && node.id && /^_baidu_bookmark_/i.test(node.id); + }, + /** + * 获取节点node所属的window对象 + * @method getWindow + * @param { Node } node 节点对象 + * @return { Window } 当前节点所属的window对象 + * @example + * ```javascript + * //output: true + * console.log( UE.dom.domUtils.getWindow( document.body ) === window ); + * ``` + */ + getWindow:function (node) { + var doc = node.ownerDocument || node; + return doc.defaultView || doc.parentWindow; + }, + /** + * 获取离nodeA与nodeB最近的公共的祖先节点 + * @method getCommonAncestor + * @param { Node } nodeA 第一个节点 + * @param { Node } nodeB 第二个节点 + * @remind 如果给定的两个节点是同一个节点, 将直接返回该节点。 + * @return { Node | NULL } 如果未找到公共节点, 返回NULL, 否则返回最近的公共祖先节点。 + * @example + * ```javascript + * var commonAncestor = UE.dom.domUtils.getCommonAncestor( document.body, document.body.firstChild ); + * //output: true + * console.log( commonAncestor.tagName.toLowerCase() === 'body' ); + * ``` + */ + getCommonAncestor:function (nodeA, nodeB) { + if (nodeA === nodeB) + return nodeA; + var parentsA = [nodeA] , parentsB = [nodeB], parent = nodeA, i = -1; + while (parent = parent.parentNode) { + if (parent === nodeB) { + return parent; + } + parentsA.push(parent); + } + parent = nodeB; + while (parent = parent.parentNode) { + if (parent === nodeA) + return parent; + parentsB.push(parent); + } + parentsA.reverse(); + parentsB.reverse(); + while (i++, parentsA[i] === parentsB[i]) { + } + return i == 0 ? null : parentsA[i - 1]; + + }, + /** + * 清除node节点左右连续为空的兄弟inline节点 + * @method clearEmptySibling + * @param { Node } node 执行的节点对象, 如果该节点的左右连续的兄弟节点是空的inline节点, + * 则这些兄弟节点将被删除 + * @grammar UE.dom.domUtils.clearEmptySibling(node,ignoreNext) //ignoreNext指定是否忽略右边空节点 + * @grammar UE.dom.domUtils.clearEmptySibling(node,ignoreNext,ignorePre) //ignorePre指定是否忽略左边空节点 + * @example + * ```html + * + *
          + * + * + * + * xxx + * + * + * + * ``` + */ + + /** + * 清除node节点左右连续为空的兄弟inline节点, 如果ignoreNext的值为true, + * 则忽略对右边兄弟节点的操作。 + * @method clearEmptySibling + * @param { Node } node 执行的节点对象, 如果该节点的左右连续的兄弟节点是空的inline节点, + * @param { Boolean } ignoreNext 是否忽略忽略对右边的兄弟节点的操作 + * 则这些兄弟节点将被删除 + * @see UE.dom.domUtils.clearEmptySibling(Node) + */ + + /** + * 清除node节点左右连续为空的兄弟inline节点, 如果ignoreNext的值为true, + * 则忽略对右边兄弟节点的操作, 如果ignorePre的值为true,则忽略对左边兄弟节点的操作。 + * @method clearEmptySibling + * @param { Node } node 执行的节点对象, 如果该节点的左右连续的兄弟节点是空的inline节点, + * @param { Boolean } ignoreNext 是否忽略忽略对右边的兄弟节点的操作 + * @param { Boolean } ignorePre 是否忽略忽略对左边的兄弟节点的操作 + * 则这些兄弟节点将被删除 + * @see UE.dom.domUtils.clearEmptySibling(Node) + */ + clearEmptySibling:function (node, ignoreNext, ignorePre) { + function clear(next, dir) { + var tmpNode; + while (next && !domUtils.isBookmarkNode(next) && (domUtils.isEmptyInlineElement(next) + //这里不能把空格算进来会吧空格干掉,出现文字间的空格丢掉了 + || !new RegExp('[^\t\n\r' + domUtils.fillChar + ']').test(next.nodeValue) )) { + tmpNode = next[dir]; + domUtils.remove(next); + next = tmpNode; + } + } + !ignoreNext && clear(node.nextSibling, 'nextSibling'); + !ignorePre && clear(node.previousSibling, 'previousSibling'); + }, + /** + * 将一个文本节点textNode拆分成两个文本节点,offset指定拆分位置 + * @method split + * @param { Node } textNode 需要拆分的文本节点对象 + * @param { int } offset 需要拆分的位置, 位置计算从0开始 + * @return { Node } 拆分后形成的新节点 + * @example + * ```html + *
          abcdef
          + * + * ``` + */ + split:function (node, offset) { + var doc = node.ownerDocument; + if (browser.ie && offset == node.nodeValue.length) { + var next = doc.createTextNode(''); + return domUtils.insertAfter(node, next); + } + var retval = node.splitText(offset); + //ie8下splitText不会跟新childNodes,我们手动触发他的更新 + if (browser.ie8) { + var tmpNode = doc.createTextNode(''); + domUtils.insertAfter(retval, tmpNode); + domUtils.remove(tmpNode); + } + return retval; + }, + + /** + * 检测文本节点textNode是否为空节点(包括空格、换行、占位符等字符) + * @method isWhitespace + * @param { Node } node 需要检测的节点对象 + * @return { Boolean } 检测的节点是否为空 + * @example + * ```html + *
          + * + *
          + * + * ``` + */ + isWhitespace:function (node) { + return !new RegExp('[^ \t\n\r' + domUtils.fillChar + ']').test(node.nodeValue); + }, + /** + * 获取元素element相对于viewport的位置坐标 + * @method getXY + * @param { Node } element 需要计算位置的节点对象 + * @return { Object } 返回形如{x:left,y:top}的一个key-value映射对象, 其中键x代表水平偏移距离, + * y代表垂直偏移距离。 + * + * @example + * ```javascript + * var location = UE.dom.domUtils.getXY( document.getElementById("test") ); + * //output: test的坐标为: 12, 24 + * console.log( 'test的坐标为: ', location.x, ',', location.y ); + * ``` + */ + getXY:function (element) { + var x = 0, y = 0; + while (element.offsetParent) { + y += element.offsetTop; + x += element.offsetLeft; + element = element.offsetParent; + } + return { 'x':x, 'y':y}; + }, + /** + * 为元素element绑定原生DOM事件,type为事件类型,handler为处理函数 + * @method on + * @param { Node } element 需要绑定事件的节点对象 + * @param { String } type 绑定的事件类型 + * @param { Function } handler 事件处理器 + * @example + * ```javascript + * UE.dom.domUtils.on(document.body,"click",function(e){ + * //e为事件对象,this为被点击元素对戏那个 + * }); + * ``` + */ + + /** + * 为元素element绑定原生DOM事件,type为事件类型,handler为处理函数 + * @method on + * @param { Node } element 需要绑定事件的节点对象 + * @param { Array } type 绑定的事件类型数组 + * @param { Function } handler 事件处理器 + * @example + * ```javascript + * UE.dom.domUtils.on(document.body,["click","mousedown"],function(evt){ + * //evt为事件对象,this为被点击元素对象 + * }); + * ``` + */ + on:function (element, type, handler) { + + var types = utils.isArray(type) ? type : utils.trim(type).split(/\s+/), + k = types.length; + if (k) while (k--) { + type = types[k]; + if (element.addEventListener) { + element.addEventListener(type, handler, false); + } else { + if (!handler._d) { + handler._d = { + els : [] + }; + } + var key = type + handler.toString(),index = utils.indexOf(handler._d.els,element); + if (!handler._d[key] || index == -1) { + if(index == -1){ + handler._d.els.push(element); + } + if(!handler._d[key]){ + handler._d[key] = function (evt) { + return handler.call(evt.srcElement, evt || window.event); + }; + } + + + element.attachEvent('on' + type, handler._d[key]); + } + } + } + element = null; + }, + /** + * 解除DOM事件绑定 + * @method un + * @param { Node } element 需要解除事件绑定的节点对象 + * @param { String } type 需要接触绑定的事件类型 + * @param { Function } handler 对应的事件处理器 + * @example + * ```javascript + * UE.dom.domUtils.un(document.body,"click",function(evt){ + * //evt为事件对象,this为被点击元素对象 + * }); + * ``` + */ + + /** + * 解除DOM事件绑定 + * @method un + * @param { Node } element 需要解除事件绑定的节点对象 + * @param { Array } type 需要接触绑定的事件类型数组 + * @param { Function } handler 对应的事件处理器 + * @example + * ```javascript + * UE.dom.domUtils.un(document.body, ["click","mousedown"],function(evt){ + * //evt为事件对象,this为被点击元素对象 + * }); + * ``` + */ + un:function (element, type, handler) { + var types = utils.isArray(type) ? type : utils.trim(type).split(/\s+/), + k = types.length; + if (k) while (k--) { + type = types[k]; + if (element.removeEventListener) { + element.removeEventListener(type, handler, false); + } else { + var key = type + handler.toString(); + try{ + element.detachEvent('on' + type, handler._d ? handler._d[key] : handler); + }catch(e){} + if (handler._d && handler._d[key]) { + var index = utils.indexOf(handler._d.els,element); + if(index!=-1){ + handler._d.els.splice(index,1); + } + handler._d.els.length == 0 && delete handler._d[key]; + } + } + } + }, + + /** + * 比较节点nodeA与节点nodeB是否具有相同的标签名、属性名以及属性值 + * @method isSameElement + * @param { Node } nodeA 需要比较的节点 + * @param { Node } nodeB 需要比较的节点 + * @return { Boolean } 两个节点是否具有相同的标签名、属性名以及属性值 + * @example + * ```html + * ssss + * bbbbb + * ssss + * bbbbb + * + * + * ``` + */ + isSameElement:function (nodeA, nodeB) { + if (nodeA.tagName != nodeB.tagName) { + return false; + } + var thisAttrs = nodeA.attributes, + otherAttrs = nodeB.attributes; + if (!ie && thisAttrs.length != otherAttrs.length) { + return false; + } + var attrA, attrB, al = 0, bl = 0; + for (var i = 0; attrA = thisAttrs[i++];) { + if (attrA.nodeName == 'style') { + if (attrA.specified) { + al++; + } + if (domUtils.isSameStyle(nodeA, nodeB)) { + continue; + } else { + return false; + } + } + if (ie) { + if (attrA.specified) { + al++; + attrB = otherAttrs.getNamedItem(attrA.nodeName); + } else { + continue; + } + } else { + attrB = nodeB.attributes[attrA.nodeName]; + } + if (!attrB.specified || attrA.nodeValue != attrB.nodeValue) { + return false; + } + } + // 有可能attrB的属性包含了attrA的属性之外还有自己的属性 + if (ie) { + for (i = 0; attrB = otherAttrs[i++];) { + if (attrB.specified) { + bl++; + } + } + if (al != bl) { + return false; + } + } + return true; + }, + + /** + * 判断节点nodeA与节点nodeB的元素的style属性是否一致 + * @method isSameStyle + * @param { Node } nodeA 需要比较的节点 + * @param { Node } nodeB 需要比较的节点 + * @return { Boolean } 两个节点是否具有相同的style属性值 + * @example + * ```html + * ssss + * bbbbb + * ssss + * bbbbb + * + * + * ``` + */ + isSameStyle:function (nodeA, nodeB) { + var styleA = nodeA.style.cssText.replace(/( ?; ?)/g, ';').replace(/( ?: ?)/g, ':'), + styleB = nodeB.style.cssText.replace(/( ?; ?)/g, ';').replace(/( ?: ?)/g, ':'); + if (browser.opera) { + styleA = nodeA.style; + styleB = nodeB.style; + if (styleA.length != styleB.length) + return false; + for (var p in styleA) { + if (/^(\d+|csstext)$/i.test(p)) { + continue; + } + if (styleA[p] != styleB[p]) { + return false; + } + } + return true; + } + if (!styleA || !styleB) { + return styleA == styleB; + } + styleA = styleA.split(';'); + styleB = styleB.split(';'); + if (styleA.length != styleB.length) { + return false; + } + for (var i = 0, ci; ci = styleA[i++];) { + if (utils.indexOf(styleB, ci) == -1) { + return false; + } + } + return true; + }, + /** + * 检查节点node是否为block元素 + * @method isBlockElm + * @param { Node } node 需要检测的节点对象 + * @return { Boolean } 是否是block元素节点 + * @warning 该方法的判断规则如下: 如果该元素原本是block元素, 则不论该元素当前的css样式是什么都会返回true; + * 否则,检测该元素的css样式, 如果该元素当前是block元素, 则返回true。 其余情况下都返回false。 + * @example + * ```html + * + * + *
          + * + * + * ``` + */ + isBlockElm:function (node) { + return node.nodeType == 1 && (dtd.$block[node.tagName] || styleBlock[domUtils.getComputedStyle(node, 'display')]) && !dtd.$nonChild[node.tagName]; + }, + /** + * 检测node节点是否为body节点 + * @method isBody + * @param { Element } node 需要检测的dom元素 + * @return { Boolean } 给定的元素是否是body元素 + * @example + * ```javascript + * //output: true + * console.log( UE.dom.domUtils.isBody( document.body ) ); + * ``` + */ + isBody:function (node) { + return node && node.nodeType == 1 && node.tagName.toLowerCase() == 'body'; + }, + /** + * 以node节点为分界,将该节点的指定祖先节点parent拆分成两个独立的节点, + * 拆分形成的两个节点之间是node节点 + * @method breakParent + * @param { Node } node 作为分界的节点对象 + * @param { Node } parent 该节点必须是node节点的祖先节点, 且是block节点。 + * @return { Node } 给定的node分界节点 + * @example + * ```javascript + * + * var node = document.createElement("span"), + * wrapNode = document.createElement( "div" ), + * parent = document.createElement("p"); + * + * parent.appendChild( node ); + * wrapNode.appendChild( parent ); + * + * //拆分前 + * //output:

          + * console.log( wrapNode.innerHTML ); + * + * + * UE.dom.domUtils.breakParent( node, parent ); + * //拆分后 + * //output:

          + * console.log( wrapNode.innerHTML ); + * + * ``` + */ + breakParent:function (node, parent) { + var tmpNode, + parentClone = node, + clone = node, + leftNodes, + rightNodes; + do { + parentClone = parentClone.parentNode; + if (leftNodes) { + tmpNode = parentClone.cloneNode(false); + tmpNode.appendChild(leftNodes); + leftNodes = tmpNode; + tmpNode = parentClone.cloneNode(false); + tmpNode.appendChild(rightNodes); + rightNodes = tmpNode; + } else { + leftNodes = parentClone.cloneNode(false); + rightNodes = leftNodes.cloneNode(false); + } + while (tmpNode = clone.previousSibling) { + leftNodes.insertBefore(tmpNode, leftNodes.firstChild); + } + while (tmpNode = clone.nextSibling) { + rightNodes.appendChild(tmpNode); + } + clone = parentClone; + } while (parent !== parentClone); + tmpNode = parent.parentNode; + tmpNode.insertBefore(leftNodes, parent); + tmpNode.insertBefore(rightNodes, parent); + tmpNode.insertBefore(node, rightNodes); + domUtils.remove(parent); + return node; + }, + /** + * 检查节点node是否是空inline节点 + * @method isEmptyInlineElement + * @param { Node } node 需要检测的节点对象 + * @return { Number } 如果给定的节点是空的inline节点, 则返回1, 否则返回0。 + * @example + * ```html + * => 1 + * => 1 + * => 1 + * xx => 0 + * ``` + */ + isEmptyInlineElement:function (node) { + if (node.nodeType != 1 || !dtd.$removeEmpty[ node.tagName ]) { + return 0; + } + node = node.firstChild; + while (node) { + //如果是创建的bookmark就跳过 + if (domUtils.isBookmarkNode(node)) { + return 0; + } + if (node.nodeType == 1 && !domUtils.isEmptyInlineElement(node) || + node.nodeType == 3 && !domUtils.isWhitespace(node) + ) { + return 0; + } + node = node.nextSibling; + } + return 1; + + }, + + /** + * 删除node节点下首尾两端的空白文本子节点 + * @method trimWhiteTextNode + * @param { Element } node 需要执行删除操作的元素对象 + * @example + * ```javascript + * var node = document.createElement("div"); + * + * node.appendChild( document.createTextNode( "" ) ); + * + * node.appendChild( document.createElement("div") ); + * + * node.appendChild( document.createTextNode( "" ) ); + * + * //3 + * console.log( node.childNodes.length ); + * + * UE.dom.domUtils.trimWhiteTextNode( node ); + * + * //1 + * console.log( node.childNodes.length ); + * ``` + */ + trimWhiteTextNode:function (node) { + function remove(dir) { + var child; + while ((child = node[dir]) && child.nodeType == 3 && domUtils.isWhitespace(child)) { + node.removeChild(child); + } + } + remove('firstChild'); + remove('lastChild'); + }, + + /** + * 合并node节点下相同的子节点 + * @name mergeChild + * @desc + * UE.dom.domUtils.mergeChild(node,tagName) //tagName要合并的子节点的标签 + * @example + *

          xxaaxx

          + * ==> UE.dom.domUtils.mergeChild(node,'span') + *

          xxaaxx

          + */ + mergeChild:function (node, tagName, attrs) { + var list = domUtils.getElementsByTagName(node, node.tagName.toLowerCase()); + for (var i = 0, ci; ci = list[i++];) { + if (!ci.parentNode || domUtils.isBookmarkNode(ci)) { + continue; + } + //span单独处理 + if (ci.tagName.toLowerCase() == 'span') { + if (node === ci.parentNode) { + domUtils.trimWhiteTextNode(node); + if (node.childNodes.length == 1) { + node.style.cssText = ci.style.cssText + ";" + node.style.cssText; + domUtils.remove(ci, true); + continue; + } + } + ci.style.cssText = node.style.cssText + ';' + ci.style.cssText; + if (attrs) { + var style = attrs.style; + if (style) { + style = style.split(';'); + for (var j = 0, s; s = style[j++];) { + ci.style[utils.cssStyleToDomStyle(s.split(':')[0])] = s.split(':')[1]; + } + } + } + if (domUtils.isSameStyle(ci, node)) { + domUtils.remove(ci, true); + } + continue; + } + if (domUtils.isSameElement(node, ci)) { + domUtils.remove(ci, true); + } + } + }, + + /** + * 原生方法getElementsByTagName的封装 + * @method getElementsByTagName + * @param { Node } node 目标节点对象 + * @param { String } tagName 需要查找的节点的tagName, 多个tagName以空格分割 + * @return { Array } 符合条件的节点集合 + */ + getElementsByTagName:function (node, name,filter) { + if(filter && utils.isString(filter)){ + var className = filter; + filter = function(node){return domUtils.hasClass(node,className)} + } + name = utils.trim(name).replace(/[ ]{2,}/g,' ').split(' '); + var arr = []; + for(var n = 0,ni;ni=name[n++];){ + var list = node.getElementsByTagName(ni); + for (var i = 0, ci; ci = list[i++];) { + if(!filter || filter(ci)) + arr.push(ci); + } + } + + return arr; + }, + /** + * 将节点node提取到父节点上 + * @method mergeToParent + * @param { Element } node 需要提取的元素对象 + * @example + * ```html + *
          + *
          + * + *
          + *
          + * + * + * ``` + */ + mergeToParent:function (node) { + var parent = node.parentNode; + while (parent && dtd.$removeEmpty[parent.tagName]) { + if (parent.tagName == node.tagName || parent.tagName == 'A') {//针对a标签单独处理 + domUtils.trimWhiteTextNode(parent); + //span需要特殊处理 不处理这样的情况 xxxxxxxxx + if (parent.tagName == 'SPAN' && !domUtils.isSameStyle(parent, node) + || (parent.tagName == 'A' && node.tagName == 'SPAN')) { + if (parent.childNodes.length > 1 || parent !== node.parentNode) { + node.style.cssText = parent.style.cssText + ";" + node.style.cssText; + parent = parent.parentNode; + continue; + } else { + parent.style.cssText += ";" + node.style.cssText; + //trace:952 a标签要保持下划线 + if (parent.tagName == 'A') { + parent.style.textDecoration = 'underline'; + } + } + } + if (parent.tagName != 'A') { + parent === node.parentNode && domUtils.remove(node, true); + break; + } + } + parent = parent.parentNode; + } + }, + /** + * 合并节点node的左右兄弟节点 + * @method mergeSibling + * @param { Element } node 需要合并的目标节点 + * @example + * ```html + * xxxxoooxxxx + * + * + * ``` + */ + + /** + * 合并节点node的左右兄弟节点, 可以根据给定的条件选择是否忽略合并左节点。 + * @method mergeSibling + * @param { Element } node 需要合并的目标节点 + * @param { Boolean } ignorePre 是否忽略合并左节点 + * @example + * ```html + * xxxxoooxxxx + * + * + * ``` + */ + + /** + * 合并节点node的左右兄弟节点,可以根据给定的条件选择是否忽略合并左右节点。 + * @method mergeSibling + * @param { Element } node 需要合并的目标节点 + * @param { Boolean } ignorePre 是否忽略合并左节点 + * @param { Boolean } ignoreNext 是否忽略合并右节点 + * @remind 如果同时忽略左右节点, 则该操作什么也不会做 + * @example + * ```html + * xxxxoooxxxx + * + * + * ``` + */ + mergeSibling:function (node, ignorePre, ignoreNext) { + function merge(rtl, start, node) { + var next; + if ((next = node[rtl]) && !domUtils.isBookmarkNode(next) && next.nodeType == 1 && domUtils.isSameElement(node, next)) { + while (next.firstChild) { + if (start == 'firstChild') { + node.insertBefore(next.lastChild, node.firstChild); + } else { + node.appendChild(next.firstChild); + } + } + domUtils.remove(next); + } + } + !ignorePre && merge('previousSibling', 'firstChild', node); + !ignoreNext && merge('nextSibling', 'lastChild', node); + }, + + /** + * 设置节点node及其子节点不会被选中 + * @method unSelectable + * @param { Element } node 需要执行操作的dom元素 + * @remind 执行该操作后的节点, 将不能被鼠标选中 + * @example + * ```javascript + * UE.dom.domUtils.unSelectable( document.body ); + * ``` + */ + unSelectable:ie && browser.ie9below || browser.opera ? function (node) { + //for ie9 + node.onselectstart = function () { + return false; + }; + node.onclick = node.onkeyup = node.onkeydown = function () { + return false; + }; + node.unselectable = 'on'; + node.setAttribute("unselectable", "on"); + for (var i = 0, ci; ci = node.all[i++];) { + switch (ci.tagName.toLowerCase()) { + case 'iframe' : + case 'textarea' : + case 'input' : + case 'select' : + break; + default : + ci.unselectable = 'on'; + node.setAttribute("unselectable", "on"); + } + } + } : function (node) { + node.style.MozUserSelect = + node.style.webkitUserSelect = + node.style.msUserSelect = + node.style.KhtmlUserSelect = 'none'; + }, + /** + * 删除节点node上的指定属性名称的属性 + * @method removeAttributes + * @param { Node } node 需要删除属性的节点对象 + * @param { String } attrNames 可以是空格隔开的多个属性名称,该操作将会依次删除相应的属性 + * @example + * ```html + *
          + * xxxxx + *
          + * + * + * ``` + */ + + /** + * 删除节点node上的指定属性名称的属性 + * @method removeAttributes + * @param { Node } node 需要删除属性的节点对象 + * @param { Array } attrNames 需要删除的属性名数组 + * @example + * ```html + *
          + * xxxxx + *
          + * + * + * ``` + */ + removeAttributes:function (node, attrNames) { + attrNames = utils.isArray(attrNames) ? attrNames : utils.trim(attrNames).replace(/[ ]{2,}/g,' ').split(' '); + for (var i = 0, ci; ci = attrNames[i++];) { + ci = attrFix[ci] || ci; + switch (ci) { + case 'className': + node[ci] = ''; + break; + case 'style': + node.style.cssText = ''; + var val = node.getAttributeNode('style'); + !browser.ie && val && node.removeAttributeNode(val); + } + node.removeAttribute(ci); + } + }, + /** + * 在doc下创建一个标签名为tag,属性为attrs的元素 + * @method createElement + * @param { DomDocument } doc 新创建的元素属于该document节点创建 + * @param { String } tagName 需要创建的元素的标签名 + * @param { Object } attrs 新创建的元素的属性key-value集合 + * @return { Element } 新创建的元素对象 + * @example + * ```javascript + * var ele = UE.dom.domUtils.createElement( document, 'div', { + * id: 'test' + * } ); + * + * //output: DIV + * console.log( ele.tagName ); + * + * //output: test + * console.log( ele.id ); + * + * ``` + */ + createElement:function (doc, tag, attrs) { + return domUtils.setAttributes(doc.createElement(tag), attrs) + }, + /** + * 为节点node添加属性attrs,attrs为属性键值对 + * @method setAttributes + * @param { Element } node 需要设置属性的元素对象 + * @param { Object } attrs 需要设置的属性名-值对 + * @return { Element } 设置属性的元素对象 + * @example + * ```html + * + * + * + * + */ + setAttributes:function (node, attrs) { + for (var attr in attrs) { + if(attrs.hasOwnProperty(attr)){ + var value = attrs[attr]; + switch (attr) { + case 'class': + //ie下要这样赋值,setAttribute不起作用 + node.className = value; + break; + case 'style' : + node.style.cssText = node.style.cssText + ";" + value; + break; + case 'innerHTML': + node[attr] = value; + break; + case 'value': + node.value = value; + break; + default: + node.setAttribute(attrFix[attr] || attr, value); + } + } + } + return node; + }, + + /** + * 获取元素element经过计算后的样式值 + * @method getComputedStyle + * @param { Element } element 需要获取样式的元素对象 + * @param { String } styleName 需要获取的样式名 + * @return { String } 获取到的样式值 + * @example + * ```html + * + * + * + * + * + * ``` + */ + getComputedStyle:function (element, styleName) { + //一下的属性单独处理 + var pros = 'width height top left'; + + if(pros.indexOf(styleName) > -1){ + return element['offset' + styleName.replace(/^\w/,function(s){return s.toUpperCase()})] + 'px'; + } + //忽略文本节点 + if (element.nodeType == 3) { + element = element.parentNode; + } + //ie下font-size若body下定义了font-size,则从currentStyle里会取到这个font-size. 取不到实际值,故此修改. + if (browser.ie && browser.version < 9 && styleName == 'font-size' && !element.style.fontSize && + !dtd.$empty[element.tagName] && !dtd.$nonChild[element.tagName]) { + var span = element.ownerDocument.createElement('span'); + span.style.cssText = 'padding:0;border:0;font-family:simsun;'; + span.innerHTML = '.'; + element.appendChild(span); + var result = span.offsetHeight; + element.removeChild(span); + span = null; + return result + 'px'; + } + try { + var value = domUtils.getStyle(element, styleName) || + (window.getComputedStyle ? domUtils.getWindow(element).getComputedStyle(element, '').getPropertyValue(styleName) : + ( element.currentStyle || element.style )[utils.cssStyleToDomStyle(styleName)]); + + } catch (e) { + return ""; + } + return utils.transUnitToPx(utils.fixColor(styleName, value)); + }, + /** + * 删除元素element指定的className + * @method removeClasses + * @param { Element } ele 需要删除class的元素节点 + * @param { String } classNames 需要删除的className, 多个className之间以空格分开 + * @example + * ```html + * xxx + * + * + * ``` + */ + + /** + * 删除元素element指定的className + * @method removeClasses + * @param { Element } ele 需要删除class的元素节点 + * @param { Array } classNames 需要删除的className数组 + * @example + * ```html + * xxx + * + * + * ``` + */ + removeClasses:function (elm, classNames) { + classNames = utils.isArray(classNames) ? classNames : + utils.trim(classNames).replace(/[ ]{2,}/g,' ').split(' '); + for(var i = 0,ci,cls = elm.className;ci=classNames[i++];){ + cls = cls.replace(new RegExp('\\b' + ci + '\\b'),'') + } + cls = utils.trim(cls).replace(/[ ]{2,}/g,' '); + if(cls){ + elm.className = cls; + }else{ + domUtils.removeAttributes(elm,['class']); + } + }, + /** + * 给元素element添加className + * @method addClass + * @param { Node } ele 需要增加className的元素 + * @param { String } classNames 需要添加的className, 多个className之间以空格分割 + * @remind 相同的类名不会被重复添加 + * @example + * ```html + * + * + * + * ``` + */ + + /** + * 判断元素element是否包含给定的样式类名className + * @method hasClass + * @param { Node } ele 需要检测的元素 + * @param { Array } classNames 需要检测的className数组 + * @return { Boolean } 元素是否包含所有给定的className + * @example + * ```html + * + * + * + * ``` + */ + hasClass:function (element, className) { + if(utils.isRegExp(className)){ + return className.test(element.className) + } + className = utils.trim(className).replace(/[ ]{2,}/g,' ').split(' '); + for(var i = 0,ci,cls = element.className;ci=className[i++];){ + if(!new RegExp('\\b' + ci + '\\b','i').test(cls)){ + return false; + } + } + return i - 1 == className.length; + }, + + /** + * 阻止事件默认行为 + * @method preventDefault + * @param { Event } evt 需要阻止默认行为的事件对象 + * @example + * ```javascript + * UE.dom.domUtils.preventDefault( evt ); + * ``` + */ + preventDefault:function (evt) { + evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false); + }, + /** + * 删除元素element指定的样式 + * @method removeStyle + * @param { Element } element 需要删除样式的元素 + * @param { String } styleName 需要删除的样式名 + * @example + * ```html + * + * + * + * ``` + */ + removeStyle:function (element, name) { + if(browser.ie ){ + //针对color先单独处理一下 + if(name == 'color'){ + name = '(^|;)' + name; + } + element.style.cssText = element.style.cssText.replace(new RegExp(name + '[^:]*:[^;]+;?','ig'),'') + }else{ + if (element.style.removeProperty) { + element.style.removeProperty (name); + }else { + element.style.removeAttribute (utils.cssStyleToDomStyle(name)); + } + } + + + if (!element.style.cssText) { + domUtils.removeAttributes(element, ['style']); + } + }, + /** + * 获取元素element的style属性的指定值 + * @method getStyle + * @param { Element } element 需要获取属性值的元素 + * @param { String } styleName 需要获取的style的名称 + * @warning 该方法仅获取元素style属性中所标明的值 + * @return { String } 该元素包含指定的style属性值 + * @example + * ```html + *
          + * + * + * ``` + */ + getStyle:function (element, name) { + var value = element.style[ utils.cssStyleToDomStyle(name) ]; + return utils.fixColor(name, value); + }, + /** + * 为元素element设置样式属性值 + * @method setStyle + * @param { Element } element 需要设置样式的元素 + * @param { String } styleName 样式名 + * @param { String } styleValue 样式值 + * @example + * ```html + *
          + * + * + * ``` + */ + setStyle:function (element, name, value) { + element.style[utils.cssStyleToDomStyle(name)] = value; + if(!utils.trim(element.style.cssText)){ + this.removeAttributes(element,'style') + } + }, + /** + * 为元素element设置多个样式属性值 + * @method setStyles + * @param { Element } element 需要设置样式的元素 + * @param { Object } styles 样式名值对 + * @example + * ```html + *
          + * + * + * ``` + */ + setStyles:function (element, styles) { + for (var name in styles) { + if (styles.hasOwnProperty(name)) { + domUtils.setStyle(element, name, styles[name]); + } + } + }, + /** + * 删除_moz_dirty属性 + * @private + * @method removeDirtyAttr + */ + removeDirtyAttr:function (node) { + for (var i = 0, ci, nodes = node.getElementsByTagName('*'); ci = nodes[i++];) { + ci.removeAttribute('_moz_dirty'); + } + node.removeAttribute('_moz_dirty'); + }, + /** + * 获取子节点的数量 + * @method getChildCount + * @param { Element } node 需要检测的元素 + * @return { Number } 给定的node元素的子节点数量 + * @example + * ```html + *
          + * + *
          + * + * + * ``` + */ + + /** + * 根据给定的过滤规则, 获取符合条件的子节点的数量 + * @method getChildCount + * @param { Element } node 需要检测的元素 + * @param { Function } fn 过滤器, 要求对符合条件的子节点返回true, 反之则要求返回false + * @return { Number } 符合过滤条件的node元素的子节点数量 + * @example + * ```html + *
          + * + *
          + * + * + * ``` + */ + getChildCount:function (node, fn) { + var count = 0, first = node.firstChild; + fn = fn || function () { + return 1; + }; + while (first) { + if (fn(first)) { + count++; + } + first = first.nextSibling; + } + return count; + }, + + /** + * 判断给定节点是否为空节点 + * @method isEmptyNode + * @param { Node } node 需要检测的节点对象 + * @return { Boolean } 节点是否为空 + * @example + * ```javascript + * UE.dom.domUtils.isEmptyNode( document.body ); + * ``` + */ + isEmptyNode:function (node) { + return !node.firstChild || domUtils.getChildCount(node, function (node) { + return !domUtils.isBr(node) && !domUtils.isBookmarkNode(node) && !domUtils.isWhitespace(node) + }) == 0 + }, + clearSelectedArr:function (nodes) { + var node; + while (node = nodes.pop()) { + domUtils.removeAttributes(node, ['class']); + } + }, + /** + * 将显示区域滚动到指定节点的位置 + * @method scrollToView + * @param {Node} node 节点 + * @param {window} win window对象 + * @param {Number} offsetTop 距离上方的偏移量 + */ + scrollToView:function (node, win, offsetTop) { + var getViewPaneSize = function () { + var doc = win.document, + mode = doc.compatMode == 'CSS1Compat'; + return { + width:( mode ? doc.documentElement.clientWidth : doc.body.clientWidth ) || 0, + height:( mode ? doc.documentElement.clientHeight : doc.body.clientHeight ) || 0 + }; + }, + getScrollPosition = function (win) { + if ('pageXOffset' in win) { + return { + x:win.pageXOffset || 0, + y:win.pageYOffset || 0 + }; + } + else { + var doc = win.document; + return { + x:doc.documentElement.scrollLeft || doc.body.scrollLeft || 0, + y:doc.documentElement.scrollTop || doc.body.scrollTop || 0 + }; + } + }; + var winHeight = getViewPaneSize().height, offset = winHeight * -1 + offsetTop; + offset += (node.offsetHeight || 0); + var elementPosition = domUtils.getXY(node); + offset += elementPosition.y; + var currentScroll = getScrollPosition(win).y; + // offset += 50; + if (offset > currentScroll || offset < currentScroll - winHeight) { + win.scrollTo(0, offset + (offset < 0 ? -20 : 20)); + } + }, + /** + * 判断给定节点是否为br + * @method isBr + * @param { Node } node 需要判断的节点对象 + * @return { Boolean } 给定的节点是否是br节点 + */ + isBr:function (node) { + return node.nodeType == 1 && node.tagName == 'BR'; + }, + /** + * 判断给定的节点是否是一个“填充”节点 + * @private + * @method isFillChar + * @param { Node } node 需要判断的节点 + * @param { Boolean } isInStart 是否从节点内容的开始位置匹配 + * @returns { Boolean } 节点是否是填充节点 + */ + isFillChar:function (node,isInStart) { + if(node.nodeType != 3) + return false; + var text = node.nodeValue; + if(isInStart){ + return new RegExp('^' + domUtils.fillChar).test(text) + } + return !text.replace(new RegExp(domUtils.fillChar,'g'), '').length + }, + isStartInblock:function (range) { + var tmpRange = range.cloneRange(), + flag = 0, + start = tmpRange.startContainer, + tmp; + if(start.nodeType == 1 && start.childNodes[tmpRange.startOffset]){ + start = start.childNodes[tmpRange.startOffset]; + var pre = start.previousSibling; + while(pre && domUtils.isFillChar(pre)){ + start = pre; + pre = pre.previousSibling; + } + } + if(this.isFillChar(start,true) && tmpRange.startOffset == 1){ + tmpRange.setStartBefore(start); + start = tmpRange.startContainer; + } + + while (start && domUtils.isFillChar(start)) { + tmp = start; + start = start.previousSibling + } + if (tmp) { + tmpRange.setStartBefore(tmp); + start = tmpRange.startContainer; + } + if (start.nodeType == 1 && domUtils.isEmptyNode(start) && tmpRange.startOffset == 1) { + tmpRange.setStart(start, 0).collapse(true); + } + while (!tmpRange.startOffset) { + start = tmpRange.startContainer; + if (domUtils.isBlockElm(start) || domUtils.isBody(start)) { + flag = 1; + break; + } + var pre = tmpRange.startContainer.previousSibling, + tmpNode; + if (!pre) { + tmpRange.setStartBefore(tmpRange.startContainer); + } else { + while (pre && domUtils.isFillChar(pre)) { + tmpNode = pre; + pre = pre.previousSibling; + } + if (tmpNode) { + tmpRange.setStartBefore(tmpNode); + } else { + tmpRange.setStartBefore(tmpRange.startContainer); + } + } + } + return flag && !domUtils.isBody(tmpRange.startContainer) ? 1 : 0; + }, + + /** + * 判断给定的元素是否是一个空元素 + * @method isEmptyBlock + * @param { Element } node 需要判断的元素 + * @return { Boolean } 是否是空元素 + * @example + * ```html + *
          + * + * + * ``` + */ + + /** + * 根据指定的判断规则判断给定的元素是否是一个空元素 + * @method isEmptyBlock + * @param { Element } node 需要判断的元素 + * @param { RegExp } reg 对内容执行判断的正则表达式对象 + * @return { Boolean } 是否是空元素 + */ + isEmptyBlock:function (node,reg) { + if(node.nodeType != 1) + return 0; + reg = reg || new RegExp('[ \xa0\t\r\n' + domUtils.fillChar + ']', 'g'); + + if (node[browser.ie ? 'innerText' : 'textContent'].replace(reg, '').length > 0) { + return 0; + } + for (var n in dtd.$isNotEmpty) { + if (node.getElementsByTagName(n).length) { + return 0; + } + } + return 1; + }, + + /** + * 移动元素使得该元素的位置移动指定的偏移量的距离 + * @method setViewportOffset + * @param { Element } element 需要设置偏移量的元素 + * @param { Object } offset 偏移量, 形如{ left: 100, top: 50 }的一个键值对, 表示该元素将在 + * 现有的位置上向水平方向偏移offset.left的距离, 在竖直方向上偏移 + * offset.top的距离 + * @example + * ```html + *
          + * + * + * ``` + */ + setViewportOffset:function (element, offset) { + var left = parseInt(element.style.left) | 0; + var top = parseInt(element.style.top) | 0; + var rect = element.getBoundingClientRect(); + var offsetLeft = offset.left - rect.left; + var offsetTop = offset.top - rect.top; + if (offsetLeft) { + element.style.left = left + offsetLeft + 'px'; + } + if (offsetTop) { + element.style.top = top + offsetTop + 'px'; + } + }, + + /** + * 用“填充字符”填充节点 + * @method fillNode + * @private + * @param { DomDocument } doc 填充的节点所在的docment对象 + * @param { Node } node 需要填充的节点对象 + * @example + * ```html + *
          + * + * + * ``` + */ + fillNode:function (doc, node) { + var tmpNode = browser.ie ? doc.createTextNode(domUtils.fillChar) : doc.createElement('br'); + node.innerHTML = ''; + node.appendChild(tmpNode); + }, + + /** + * 把节点src的所有子节点追加到另一个节点tag上去 + * @method moveChild + * @param { Node } src 源节点, 该节点下的所有子节点将被移除 + * @param { Node } tag 目标节点, 从源节点移除的子节点将被追加到该节点下 + * @example + * ```html + *
          + * + *
          + *
          + *
          + *
          + * + * + * ``` + */ + + /** + * 把节点src的所有子节点移动到另一个节点tag上去, 可以通过dir参数控制附加的行为是“追加”还是“插入顶部” + * @method moveChild + * @param { Node } src 源节点, 该节点下的所有子节点将被移除 + * @param { Node } tag 目标节点, 从源节点移除的子节点将被附加到该节点下 + * @param { Boolean } dir 附加方式, 如果为true, 则附加进去的节点将被放到目标节点的顶部, 反之,则放到末尾 + * @example + * ```html + *
          + * + *
          + *
          + *
          + *
          + * + * + * ``` + */ + moveChild:function (src, tag, dir) { + while (src.firstChild) { + if (dir && tag.firstChild) { + tag.insertBefore(src.lastChild, tag.firstChild); + } else { + tag.appendChild(src.firstChild); + } + } + }, + + /** + * 判断节点的标签上是否不存在任何属性 + * @method hasNoAttributes + * @private + * @param { Node } node 需要检测的节点对象 + * @return { Boolean } 节点是否不包含任何属性 + * @example + * ```html + *
          xxxx
          + * + * + * ``` + */ + hasNoAttributes:function (node) { + return browser.ie ? /^<\w+\s*?>/.test(node.outerHTML) : node.attributes.length == 0; + }, + + /** + * 检测节点是否是UEditor所使用的辅助节点 + * @method isCustomeNode + * @private + * @param { Node } node 需要检测的节点 + * @remind 辅助节点是指编辑器要完成工作临时添加的节点, 在输出的时候将会从编辑器内移除, 不会影响最终的结果。 + * @return { Boolean } 给定的节点是否是一个辅助节点 + */ + isCustomeNode:function (node) { + return node.nodeType == 1 && node.getAttribute('_ue_custom_node_'); + }, + + /** + * 检测节点的标签是否是给定的标签 + * @method isTagNode + * @param { Node } node 需要检测的节点对象 + * @param { String } tagName 标签 + * @return { Boolean } 节点的标签是否是给定的标签 + * @example + * ```html + *
          + * + * + * ``` + */ + isTagNode:function (node, tagNames) { + return node.nodeType == 1 && new RegExp('\\b' + node.tagName + '\\b','i').test(tagNames) + }, + + /** + * 给定一个节点数组,在通过指定的过滤器过滤后, 获取其中满足过滤条件的第一个节点 + * @method filterNodeList + * @param { Array } nodeList 需要过滤的节点数组 + * @param { Function } fn 过滤器, 对符合条件的节点, 执行结果返回true, 反之则返回false + * @return { Node | NULL } 如果找到符合过滤条件的节点, 则返回该节点, 否则返回NULL + * @example + * ```javascript + * var divNodes = document.getElementsByTagName("div"); + * divNodes = [].slice.call( divNodes, 0 ); + * + * //output: null + * console.log( UE.dom.domUtils.filterNodeList( divNodes, function ( node ) { + * return node.tagName.toLowerCase() !== 'div'; + * } ) ); + * ``` + */ + + /** + * 给定一个节点数组nodeList和一组标签名tagNames, 获取其中能够匹配标签名的节点集合中的第一个节点 + * @method filterNodeList + * @param { Array } nodeList 需要过滤的节点数组 + * @param { String } tagNames 需要匹配的标签名, 多个标签名之间用空格分割 + * @return { Node | NULL } 如果找到标签名匹配的节点, 则返回该节点, 否则返回NULL + * @example + * ```javascript + * var divNodes = document.getElementsByTagName("div"); + * divNodes = [].slice.call( divNodes, 0 ); + * + * //output: null + * console.log( UE.dom.domUtils.filterNodeList( divNodes, 'a span' ) ); + * ``` + */ + + /** + * 给定一个节点数组,在通过指定的过滤器过滤后, 如果参数forAll为true, 则会返回所有满足过滤 + * 条件的节点集合, 否则, 返回满足条件的节点集合中的第一个节点 + * @method filterNodeList + * @param { Array } nodeList 需要过滤的节点数组 + * @param { Function } fn 过滤器, 对符合条件的节点, 执行结果返回true, 反之则返回false + * @param { Boolean } forAll 是否返回整个节点数组, 如果该参数为false, 则返回节点集合中的第一个节点 + * @return { Array | Node | NULL } 如果找到符合过滤条件的节点, 则根据参数forAll的值决定返回满足 + * 过滤条件的节点数组或第一个节点, 否则返回NULL + * @example + * ```javascript + * var divNodes = document.getElementsByTagName("div"); + * divNodes = [].slice.call( divNodes, 0 ); + * + * //output: 3(假定有3个div) + * console.log( divNodes.length ); + * + * var nodes = UE.dom.domUtils.filterNodeList( divNodes, function ( node ) { + * return node.tagName.toLowerCase() === 'div'; + * }, true ); + * + * //output: 3 + * console.log( nodes.length ); + * + * var node = UE.dom.domUtils.filterNodeList( divNodes, function ( node ) { + * return node.tagName.toLowerCase() === 'div'; + * }, false ); + * + * //output: div + * console.log( node.nodeName ); + * ``` + */ + filterNodeList : function(nodelist,filter,forAll){ + var results = []; + if(!utils .isFunction(filter)){ + var str = filter; + filter = function(n){ + return utils.indexOf(utils.isArray(str) ? str:str.split(' '), n.tagName.toLowerCase()) != -1 + }; + } + utils.each(nodelist,function(n){ + filter(n) && results.push(n) + }); + return results.length == 0 ? null : results.length == 1 || !forAll ? results[0] : results + }, + + /** + * 查询给定的range选区是否在给定的node节点内,且在该节点的最末尾 + * @method isInNodeEndBoundary + * @param { UE.dom.Range } rng 需要判断的range对象, 该对象的startContainer不能为NULL + * @param node 需要检测的节点对象 + * @return { Number } 如果给定的选取range对象是在node内部的最末端, 则返回1, 否则返回0 + */ + isInNodeEndBoundary : function (rng,node){ + var start = rng.startContainer; + if(start.nodeType == 3 && rng.startOffset != start.nodeValue.length){ + return 0; + } + if(start.nodeType == 1 && rng.startOffset != start.childNodes.length){ + return 0; + } + while(start !== node){ + if(start.nextSibling){ + return 0 + }; + start = start.parentNode; + } + return 1; + }, + isBoundaryNode : function (node,dir){ + var tmp; + while(!domUtils.isBody(node)){ + tmp = node; + node = node.parentNode; + if(tmp !== node[dir]){ + return false; + } + } + return true; + }, + fillHtml : browser.ie11below ? ' ' : '
          ' +}; +var fillCharReg = new RegExp(domUtils.fillChar, 'g'); + +// core/Range.js +/** + * Range封装 + * @file + * @module UE.dom + * @class Range + * @since 1.2.6.1 + */ + +/** + * dom操作封装 + * @unfile + * @module UE.dom + */ + +/** + * Range实现类,本类是UEditor底层核心类,封装不同浏览器之间的Range操作。 + * @unfile + * @module UE.dom + * @class Range + */ + + +(function () { + var guid = 0, + fillChar = domUtils.fillChar, + fillData; + + /** + * 更新range的collapse状态 + * @param {Range} range range对象 + */ + function updateCollapse(range) { + range.collapsed = + range.startContainer && range.endContainer && + range.startContainer === range.endContainer && + range.startOffset == range.endOffset; + } + + function selectOneNode(rng){ + return !rng.collapsed && rng.startContainer.nodeType == 1 && rng.startContainer === rng.endContainer && rng.endOffset - rng.startOffset == 1 + } + function setEndPoint(toStart, node, offset, range) { + //如果node是自闭合标签要处理 + if (node.nodeType == 1 && (dtd.$empty[node.tagName] || dtd.$nonChild[node.tagName])) { + offset = domUtils.getNodeIndex(node) + (toStart ? 0 : 1); + node = node.parentNode; + } + if (toStart) { + range.startContainer = node; + range.startOffset = offset; + if (!range.endContainer) { + range.collapse(true); + } + } else { + range.endContainer = node; + range.endOffset = offset; + if (!range.startContainer) { + range.collapse(false); + } + } + updateCollapse(range); + return range; + } + + function execContentsAction(range, action) { + //调整边界 + //range.includeBookmark(); + var start = range.startContainer, + end = range.endContainer, + startOffset = range.startOffset, + endOffset = range.endOffset, + doc = range.document, + frag = doc.createDocumentFragment(), + tmpStart, tmpEnd; + if (start.nodeType == 1) { + start = start.childNodes[startOffset] || (tmpStart = start.appendChild(doc.createTextNode(''))); + } + if (end.nodeType == 1) { + end = end.childNodes[endOffset] || (tmpEnd = end.appendChild(doc.createTextNode(''))); + } + if (start === end && start.nodeType == 3) { + frag.appendChild(doc.createTextNode(start.substringData(startOffset, endOffset - startOffset))); + //is not clone + if (action) { + start.deleteData(startOffset, endOffset - startOffset); + range.collapse(true); + } + return frag; + } + var current, currentLevel, clone = frag, + startParents = domUtils.findParents(start, true), endParents = domUtils.findParents(end, true); + for (var i = 0; startParents[i] == endParents[i];) { + i++; + } + for (var j = i, si; si = startParents[j]; j++) { + current = si.nextSibling; + if (si == start) { + if (!tmpStart) { + if (range.startContainer.nodeType == 3) { + clone.appendChild(doc.createTextNode(start.nodeValue.slice(startOffset))); + //is not clone + if (action) { + start.deleteData(startOffset, start.nodeValue.length - startOffset); + } + } else { + clone.appendChild(!action ? start.cloneNode(true) : start); + } + } + } else { + currentLevel = si.cloneNode(false); + clone.appendChild(currentLevel); + } + while (current) { + if (current === end || current === endParents[j]) { + break; + } + si = current.nextSibling; + clone.appendChild(!action ? current.cloneNode(true) : current); + current = si; + } + clone = currentLevel; + } + clone = frag; + if (!startParents[i]) { + clone.appendChild(startParents[i - 1].cloneNode(false)); + clone = clone.firstChild; + } + for (var j = i, ei; ei = endParents[j]; j++) { + current = ei.previousSibling; + if (ei == end) { + if (!tmpEnd && range.endContainer.nodeType == 3) { + clone.appendChild(doc.createTextNode(end.substringData(0, endOffset))); + //is not clone + if (action) { + end.deleteData(0, endOffset); + } + } + } else { + currentLevel = ei.cloneNode(false); + clone.appendChild(currentLevel); + } + //如果两端同级,右边第一次已经被开始做了 + if (j != i || !startParents[i]) { + while (current) { + if (current === start) { + break; + } + ei = current.previousSibling; + clone.insertBefore(!action ? current.cloneNode(true) : current, clone.firstChild); + current = ei; + } + } + clone = currentLevel; + } + if (action) { + range.setStartBefore(!endParents[i] ? endParents[i - 1] : !startParents[i] ? startParents[i - 1] : endParents[i]).collapse(true); + } + tmpStart && domUtils.remove(tmpStart); + tmpEnd && domUtils.remove(tmpEnd); + return frag; + } + + /** + * 创建一个跟document绑定的空的Range实例 + * @constructor + * @param { Document } document 新建的选区所属的文档对象 + */ + + /** + * @property { Node } startContainer 当前Range的开始边界的容器节点, 可以是一个元素节点或者是文本节点 + */ + + /** + * @property { Node } startOffset 当前Range的开始边界容器节点的偏移量, 如果是元素节点, + * 该值就是childNodes中的第几个节点, 如果是文本节点就是文本内容的第几个字符 + */ + + /** + * @property { Node } endContainer 当前Range的结束边界的容器节点, 可以是一个元素节点或者是文本节点 + */ + + /** + * @property { Node } endOffset 当前Range的结束边界容器节点的偏移量, 如果是元素节点, + * 该值就是childNodes中的第几个节点, 如果是文本节点就是文本内容的第几个字符 + */ + + /** + * @property { Boolean } collapsed 当前Range是否闭合 + * @default true + * @remind Range是闭合的时候, startContainer === endContainer && startOffset === endOffset + */ + + /** + * @property { Document } document 当前Range所属的Document对象 + * @remind 不同range的的document属性可以是不同的 + */ + var Range = dom.Range = function (document) { + var me = this; + me.startContainer = + me.startOffset = + me.endContainer = + me.endOffset = null; + me.document = document; + me.collapsed = true; + }; + + /** + * 删除fillData + * @param doc + * @param excludeNode + */ + function removeFillData(doc, excludeNode) { + try { + if (fillData && domUtils.inDoc(fillData, doc)) { + if (!fillData.nodeValue.replace(fillCharReg, '').length) { + var tmpNode = fillData.parentNode; + domUtils.remove(fillData); + while (tmpNode && domUtils.isEmptyInlineElement(tmpNode) && + //safari的contains有bug + (browser.safari ? !(domUtils.getPosition(tmpNode,excludeNode) & domUtils.POSITION_CONTAINS) : !tmpNode.contains(excludeNode)) + ) { + fillData = tmpNode.parentNode; + domUtils.remove(tmpNode); + tmpNode = fillData; + } + } else { + fillData.nodeValue = fillData.nodeValue.replace(fillCharReg, ''); + } + } + } catch (e) { + } + } + + /** + * @param node + * @param dir + */ + function mergeSibling(node, dir) { + var tmpNode; + node = node[dir]; + while (node && domUtils.isFillChar(node)) { + tmpNode = node[dir]; + domUtils.remove(node); + node = tmpNode; + } + } + + Range.prototype = { + + /** + * 克隆选区的内容到一个DocumentFragment里 + * @method cloneContents + * @return { DocumentFragment | NULL } 如果选区是闭合的将返回null, 否则, 返回包含所clone内容的DocumentFragment元素 + * @example + * ```html + * + * + * xx[xxx]x + * + * + * + * ``` + */ + cloneContents:function () { + return this.collapsed ? null : execContentsAction(this, 0); + }, + + /** + * 删除当前选区范围中的所有内容 + * @method deleteContents + * @remind 执行完该操作后, 当前Range对象变成了闭合状态 + * @return { UE.dom.Range } 当前操作的Range对象 + * @example + * ```html + * + * + * xx[xxx]x + * + * + * + * ``` + */ + deleteContents:function () { + var txt; + if (!this.collapsed) { + execContentsAction(this, 1); + } + if (browser.webkit) { + txt = this.startContainer; + if (txt.nodeType == 3 && !txt.nodeValue.length) { + this.setStartBefore(txt).collapse(true); + domUtils.remove(txt); + } + } + return this; + }, + + /** + * 将当前选区的内容提取到一个DocumentFragment里 + * @method extractContents + * @remind 执行该操作后, 选区将变成闭合状态 + * @warning 执行该操作后, 原来选区所选中的内容将从dom树上剥离出来 + * @return { DocumentFragment } 返回包含所提取内容的DocumentFragment对象 + * @example + * ```html + * + * + * xx[xxx]x + * + * + * + */ + extractContents:function () { + return this.collapsed ? null : execContentsAction(this, 2); + }, + + /** + * 设置Range的开始容器节点和偏移量 + * @method setStart + * @remind 如果给定的节点是元素节点,那么offset指的是其子元素中索引为offset的元素, + * 如果是文本节点,那么offset指的是其文本内容的第offset个字符 + * @remind 如果提供的容器节点是一个不能包含子元素的节点, 则该选区的开始容器将被设置 + * 为该节点的父节点, 此时, 其距离开始容器的偏移量也变成了该节点在其父节点 + * 中的索引 + * @param { Node } node 将被设为当前选区开始边界容器的节点对象 + * @param { int } offset 选区的开始位置偏移量 + * @return { UE.dom.Range } 当前range对象 + * @example + * ```html + * + * xxxxxxxxxxxxx[xxx] + * + * + * ``` + * @example + * ```html + * + * xxx[xx]x + * + * + * ``` + */ + setStart:function (node, offset) { + return setEndPoint(true, node, offset, this); + }, + + /** + * 设置Range的结束容器和偏移量 + * @method setEnd + * @param { Node } node 作为当前选区结束边界容器的节点对象 + * @param { int } offset 结束边界的偏移量 + * @see UE.dom.Range:setStart(Node,int) + * @return { UE.dom.Range } 当前range对象 + */ + setEnd:function (node, offset) { + return setEndPoint(false, node, offset, this); + }, + + /** + * 将Range开始位置设置到node节点之后 + * @method setStartAfter + * @remind 该操作将会把给定节点的父节点作为range的开始容器, 且偏移量是该节点在其父节点中的位置索引+1 + * @param { Node } node 选区的开始边界将紧接着该节点之后 + * @return { UE.dom.Range } 当前range对象 + * @example + * ```html + * + * xxxxxxx[xxxx] + * + * + * ``` + */ + setStartAfter:function (node) { + return this.setStart(node.parentNode, domUtils.getNodeIndex(node) + 1); + }, + + /** + * 将Range开始位置设置到node节点之前 + * @method setStartBefore + * @remind 该操作将会把给定节点的父节点作为range的开始容器, 且偏移量是该节点在其父节点中的位置索引 + * @param { Node } node 新的选区开始位置在该节点之前 + * @see UE.dom.Range:setStartAfter(Node) + * @return { UE.dom.Range } 当前range对象 + */ + setStartBefore:function (node) { + return this.setStart(node.parentNode, domUtils.getNodeIndex(node)); + }, + + /** + * 将Range结束位置设置到node节点之后 + * @method setEndAfter + * @remind 该操作将会把给定节点的父节点作为range的结束容器, 且偏移量是该节点在其父节点中的位置索引+1 + * @param { Node } node 目标节点 + * @see UE.dom.Range:setStartAfter(Node) + * @return { UE.dom.Range } 当前range对象 + * @example + * ```html + * + * [xxxxxxx]xxxx + * + * + * ``` + */ + setEndAfter:function (node) { + return this.setEnd(node.parentNode, domUtils.getNodeIndex(node) + 1); + }, + + /** + * 将Range结束位置设置到node节点之前 + * @method setEndBefore + * @remind 该操作将会把给定节点的父节点作为range的结束容器, 且偏移量是该节点在其父节点中的位置索引 + * @param { Node } node 目标节点 + * @see UE.dom.Range:setEndAfter(Node) + * @return { UE.dom.Range } 当前range对象 + */ + setEndBefore:function (node) { + return this.setEnd(node.parentNode, domUtils.getNodeIndex(node)); + }, + + /** + * 设置Range的开始位置到node节点内的第一个子节点之前 + * @method setStartAtFirst + * @remind 选区的开始容器将变成给定的节点, 且偏移量为0 + * @remind 如果给定的节点是元素节点, 则该节点必须是允许包含子节点的元素。 + * @param { Node } node 目标节点 + * @see UE.dom.Range:setStartBefore(Node) + * @return { UE.dom.Range } 当前range对象 + * @example + * ```html + * + * xxxxx[xx]xxxx + * + * + * ``` + */ + setStartAtFirst:function (node) { + return this.setStart(node, 0); + }, + + /** + * 设置Range的开始位置到node节点内的最后一个节点之后 + * @method setStartAtLast + * @remind 选区的开始容器将变成给定的节点, 且偏移量为该节点的子节点数 + * @remind 如果给定的节点是元素节点, 则该节点必须是允许包含子节点的元素。 + * @param { Node } node 目标节点 + * @see UE.dom.Range:setStartAtFirst(Node) + * @return { UE.dom.Range } 当前range对象 + */ + setStartAtLast:function (node) { + return this.setStart(node, node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length); + }, + + /** + * 设置Range的结束位置到node节点内的第一个节点之前 + * @method setEndAtFirst + * @param { Node } node 目标节点 + * @remind 选区的结束容器将变成给定的节点, 且偏移量为0 + * @remind node必须是一个元素节点, 且必须是允许包含子节点的元素。 + * @see UE.dom.Range:setStartAtFirst(Node) + * @return { UE.dom.Range } 当前range对象 + */ + setEndAtFirst:function (node) { + return this.setEnd(node, 0); + }, + + /** + * 设置Range的结束位置到node节点内的最后一个节点之后 + * @method setEndAtLast + * @param { Node } node 目标节点 + * @remind 选区的结束容器将变成给定的节点, 且偏移量为该节点的子节点数量 + * @remind node必须是一个元素节点, 且必须是允许包含子节点的元素。 + * @see UE.dom.Range:setStartAtFirst(Node) + * @return { UE.dom.Range } 当前range对象 + */ + setEndAtLast:function (node) { + return this.setEnd(node, node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length); + }, + + /** + * 选中给定节点 + * @method selectNode + * @remind 此时, 选区的开始容器和结束容器都是该节点的父节点, 其startOffset是该节点在父节点中的位置索引, + * 而endOffset为startOffset+1 + * @param { Node } node 需要选中的节点 + * @return { UE.dom.Range } 当前range对象,此时的range仅包含当前给定的节点对象 + * @example + * ```html + * + * xxxxx[xx]xxxx + * + * + * ``` + */ + selectNode:function (node) { + return this.setStartBefore(node).setEndAfter(node); + }, + + /** + * 选中给定节点内部的所有节点 + * @method selectNodeContents + * @remind 此时, 选区的开始容器和结束容器都是该节点, 其startOffset为0, + * 而endOffset是该节点的子节点数。 + * @param { Node } node 目标节点, 当前range将包含该节点内的所有节点 + * @return { UE.dom.Range } 当前range对象, 此时range仅包含给定节点的所有子节点 + * @example + * ```html + * + * xxxxx[xx]xxxx + * + * + * ``` + */ + selectNodeContents:function (node) { + return this.setStart(node, 0).setEndAtLast(node); + }, + + /** + * clone当前Range对象 + * @method cloneRange + * @remind 返回的range是一个全新的range对象, 其内部所有属性与当前被clone的range相同。 + * @return { UE.dom.Range } 当前range对象的一个副本 + */ + cloneRange:function () { + var me = this; + return new Range(me.document).setStart(me.startContainer, me.startOffset).setEnd(me.endContainer, me.endOffset); + + }, + + /** + * 向当前选区的结束处闭合选区 + * @method collapse + * @return { UE.dom.Range } 当前range对象 + * @example + * ```html + * + * xxxxx[xx]xxxx + * + * + * ``` + */ + + /** + * 闭合当前选区,根据给定的toStart参数项决定是向当前选区开始处闭合还是向结束处闭合, + * 如果toStart的值为true,则向开始位置闭合, 反之,向结束位置闭合。 + * @method collapse + * @param { Boolean } toStart 是否向选区开始处闭合 + * @return { UE.dom.Range } 当前range对象,此时range对象处于闭合状态 + * @see UE.dom.Range:collapse() + * @example + * ```html + * + * xxxxx[xx]xxxx + * + * + * ``` + */ + collapse:function (toStart) { + var me = this; + if (toStart) { + me.endContainer = me.startContainer; + me.endOffset = me.startOffset; + } else { + me.startContainer = me.endContainer; + me.startOffset = me.endOffset; + } + me.collapsed = true; + return me; + }, + + /** + * 调整range的开始位置和结束位置,使其"收缩"到最小的位置 + * @method shrinkBoundary + * @return { UE.dom.Range } 当前range对象 + * @example + * ```html + * xxxx[xxxxx] => xxxx[xxxxx] + * ``` + * + * @example + * ```html + * + * x[xx]xxx + * + * + * ``` + * + * @example + * ```html + * [xxxxxxxxxxx] => [xxxxxxxxxxx] + * ``` + */ + + /** + * 调整range的开始位置和结束位置,使其"收缩"到最小的位置, + * 如果ignoreEnd的值为true,则忽略对结束位置的调整 + * @method shrinkBoundary + * @param { Boolean } ignoreEnd 是否忽略对结束位置的调整 + * @return { UE.dom.Range } 当前range对象 + * @see UE.dom.domUtils.Range:shrinkBoundary() + */ + shrinkBoundary:function (ignoreEnd) { + var me = this, child, + collapsed = me.collapsed; + function check(node){ + return node.nodeType == 1 && !domUtils.isBookmarkNode(node) && !dtd.$empty[node.tagName] && !dtd.$nonChild[node.tagName] + } + while (me.startContainer.nodeType == 1 //是element + && (child = me.startContainer.childNodes[me.startOffset]) //子节点也是element + && check(child)) { + me.setStart(child, 0); + } + if (collapsed) { + return me.collapse(true); + } + if (!ignoreEnd) { + while (me.endContainer.nodeType == 1//是element + && me.endOffset > 0 //如果是空元素就退出 endOffset=0那么endOffst-1为负值,childNodes[endOffset]报错 + && (child = me.endContainer.childNodes[me.endOffset - 1]) //子节点也是element + && check(child)) { + me.setEnd(child, child.childNodes.length); + } + } + return me; + }, + + /** + * 获取离当前选区内包含的所有节点最近的公共祖先节点, + * @method getCommonAncestor + * @remind 返回的公共祖先节点一定不是range自身的容器节点, 但有可能是一个文本节点 + * @return { Node } 当前range对象内所有节点的公共祖先节点 + * @example + * ```html + * //选区示例 + * xxxx[xxx]xxxxxx + * + * ``` + */ + + /** + * 获取当前选区所包含的所有节点的公共祖先节点, 可以根据给定的参数 includeSelf 决定获取到 + * 的公共祖先节点是否可以是当前选区的startContainer或endContainer节点, 如果 includeSelf + * 的取值为true, 则返回的节点可以是自身的容器节点, 否则, 则不能是容器节点 + * @method getCommonAncestor + * @param { Boolean } includeSelf 是否允许获取到的公共祖先节点是当前range对象的容器节点 + * @return { Node } 当前range对象内所有节点的公共祖先节点 + * @see UE.dom.Range:getCommonAncestor() + * @example + * ```html + * + * + * + * xxxxxxxxx[xxx]xxxxxxxx + * + * + * + * + * ``` + */ + + /** + * 获取当前选区所包含的所有节点的公共祖先节点, 可以根据给定的参数 includeSelf 决定获取到 + * 的公共祖先节点是否可以是当前选区的startContainer或endContainer节点, 如果 includeSelf + * 的取值为true, 则返回的节点可以是自身的容器节点, 否则, 则不能是容器节点; 同时可以根据 + * ignoreTextNode 参数的取值决定是否忽略类型为文本节点的祖先节点。 + * @method getCommonAncestor + * @param { Boolean } includeSelf 是否允许获取到的公共祖先节点是当前range对象的容器节点 + * @param { Boolean } ignoreTextNode 获取祖先节点的过程中是否忽略类型为文本节点的祖先节点 + * @return { Node } 当前range对象内所有节点的公共祖先节点 + * @see UE.dom.Range:getCommonAncestor() + * @see UE.dom.Range:getCommonAncestor(Boolean) + * @example + * ```html + * + * + * + * xxxxxxxx[x]xxxxxxxxxxx + * + * + * + * + * ``` + */ + getCommonAncestor:function (includeSelf, ignoreTextNode) { + var me = this, + start = me.startContainer, + end = me.endContainer; + if (start === end) { + if (includeSelf && selectOneNode(this)) { + start = start.childNodes[me.startOffset]; + if(start.nodeType == 1) + return start; + } + //只有在上来就相等的情况下才会出现是文本的情况 + return ignoreTextNode && start.nodeType == 3 ? start.parentNode : start; + } + return domUtils.getCommonAncestor(start, end); + }, + + /** + * 调整当前Range的开始和结束边界容器,如果是容器节点是文本节点,就调整到包含该文本节点的父节点上 + * @method trimBoundary + * @remind 该操作有可能会引起文本节点被切开 + * @return { UE.dom.Range } 当前range对象 + * @example + * ```html + * + * //选区示例 + * xxx[xxxxx]xxx + * + * + * ``` + */ + + /** + * 调整当前Range的开始和结束边界容器,如果是容器节点是文本节点,就调整到包含该文本节点的父节点上, + * 可以根据 ignoreEnd 参数的值决定是否调整对结束边界的调整 + * @method trimBoundary + * @param { Boolean } ignoreEnd 是否忽略对结束边界的调整 + * @return { UE.dom.Range } 当前range对象 + * @example + * ```html + * + * //选区示例 + * xxx[xxxxx]xxx + * + * + * ``` + */ + trimBoundary:function (ignoreEnd) { + this.txtToElmBoundary(); + var start = this.startContainer, + offset = this.startOffset, + collapsed = this.collapsed, + end = this.endContainer; + if (start.nodeType == 3) { + if (offset == 0) { + this.setStartBefore(start); + } else { + if (offset >= start.nodeValue.length) { + this.setStartAfter(start); + } else { + var textNode = domUtils.split(start, offset); + //跟新结束边界 + if (start === end) { + this.setEnd(textNode, this.endOffset - offset); + } else if (start.parentNode === end) { + this.endOffset += 1; + } + this.setStartBefore(textNode); + } + } + if (collapsed) { + return this.collapse(true); + } + } + if (!ignoreEnd) { + offset = this.endOffset; + end = this.endContainer; + if (end.nodeType == 3) { + if (offset == 0) { + this.setEndBefore(end); + } else { + offset < end.nodeValue.length && domUtils.split(end, offset); + this.setEndAfter(end); + } + } + } + return this; + }, + + /** + * 如果选区在文本的边界上,就扩展选区到文本的父节点上, 如果当前选区是闭合的, 则什么也不做 + * @method txtToElmBoundary + * @remind 该操作不会修改dom节点 + * @return { UE.dom.Range } 当前range对象 + */ + + /** + * 如果选区在文本的边界上,就扩展选区到文本的父节点上, 如果当前选区是闭合的, 则根据参数项 + * ignoreCollapsed 的值决定是否执行该调整 + * @method txtToElmBoundary + * @param { Boolean } ignoreCollapsed 是否忽略选区的闭合状态, 如果该参数取值为true, 则 + * 不论选区是否闭合, 都会执行该操作, 反之, 则不会对闭合的选区执行该操作 + * @return { UE.dom.Range } 当前range对象 + */ + txtToElmBoundary:function (ignoreCollapsed) { + function adjust(r, c) { + var container = r[c + 'Container'], + offset = r[c + 'Offset']; + if (container.nodeType == 3) { + if (!offset) { + r['set' + c.replace(/(\w)/, function (a) { + return a.toUpperCase(); + }) + 'Before'](container); + } else if (offset >= container.nodeValue.length) { + r['set' + c.replace(/(\w)/, function (a) { + return a.toUpperCase(); + }) + 'After' ](container); + } + } + } + + if (ignoreCollapsed || !this.collapsed) { + adjust(this, 'start'); + adjust(this, 'end'); + } + return this; + }, + + /** + * 在当前选区的开始位置前插入节点,新插入的节点会被该range包含 + * @method insertNode + * @param { Node } node 需要插入的节点 + * @remind 插入的节点可以是一个DocumentFragment依次插入多个节点 + * @return { UE.dom.Range } 当前range对象 + */ + insertNode:function (node) { + var first = node, length = 1; + if (node.nodeType == 11) { + first = node.firstChild; + length = node.childNodes.length; + } + this.trimBoundary(true); + var start = this.startContainer, + offset = this.startOffset; + var nextNode = start.childNodes[ offset ]; + if (nextNode) { + start.insertBefore(node, nextNode); + } else { + start.appendChild(node); + } + if (first.parentNode === this.endContainer) { + this.endOffset = this.endOffset + length; + } + return this.setStartBefore(first); + }, + + /** + * 闭合选区到当前选区的开始位置, 并且定位光标到闭合后的位置 + * @method setCursor + * @return { UE.dom.Range } 当前range对象 + * @see UE.dom.Range:collapse() + */ + + /** + * 闭合选区,可以根据参数toEnd的值控制选区是向前闭合还是向后闭合, 并且定位光标到闭合后的位置。 + * @method setCursor + * @param { Boolean } toEnd 是否向后闭合, 如果为true, 则闭合选区时, 将向结束容器方向闭合, + * 反之,则向开始容器方向闭合 + * @return { UE.dom.Range } 当前range对象 + * @see UE.dom.Range:collapse(Boolean) + */ + setCursor:function (toEnd, noFillData) { + return this.collapse(!toEnd).select(noFillData); + }, + + /** + * 创建当前range的一个书签,记录下当前range的位置,方便当dom树改变时,还能找回原来的选区位置 + * @method createBookmark + * @param { Boolean } serialize 控制返回的标记位置是对当前位置的引用还是ID,如果该值为true,则 + * 返回标记位置的ID, 反之则返回标记位置节点的引用 + * @return { Object } 返回一个书签记录键值对, 其包含的key有: start => 开始标记的ID或者引用, + * end => 结束标记的ID或引用, id => 当前标记的类型, 如果为true,则表示 + * 返回的记录的类型为ID, 反之则为引用 + */ + createBookmark:function (serialize, same) { + var endNode, + startNode = this.document.createElement('span'); + startNode.style.cssText = 'display:none;line-height:0px;'; + startNode.appendChild(this.document.createTextNode('\u200D')); + startNode.id = '_baidu_bookmark_start_' + (same ? '' : guid++); + + if (!this.collapsed) { + endNode = startNode.cloneNode(true); + endNode.id = '_baidu_bookmark_end_' + (same ? '' : guid++); + } + this.insertNode(startNode); + if (endNode) { + this.collapse().insertNode(endNode).setEndBefore(endNode); + } + this.setStartAfter(startNode); + return { + start:serialize ? startNode.id : startNode, + end:endNode ? serialize ? endNode.id : endNode : null, + id:serialize + } + }, + + /** + * 调整当前range的边界到书签位置,并删除该书签对象所标记的位置内的节点 + * @method moveToBookmark + * @param { BookMark } bookmark createBookmark所创建的标签对象 + * @return { UE.dom.Range } 当前range对象 + * @see UE.dom.Range:createBookmark(Boolean) + */ + moveToBookmark:function (bookmark) { + var start = bookmark.id ? this.document.getElementById(bookmark.start) : bookmark.start, + end = bookmark.end && bookmark.id ? this.document.getElementById(bookmark.end) : bookmark.end; + this.setStartBefore(start); + domUtils.remove(start); + if (end) { + this.setEndBefore(end); + domUtils.remove(end); + } else { + this.collapse(true); + } + return this; + }, + + /** + * 调整range的边界,使其"放大"到最近的父节点 + * @method enlarge + * @remind 会引起选区的变化 + * @return { UE.dom.Range } 当前range对象 + */ + + /** + * 调整range的边界,使其"放大"到最近的父节点,根据参数 toBlock 的取值, 可以 + * 要求扩大之后的父节点是block节点 + * @method enlarge + * @param { Boolean } toBlock 是否要求扩大之后的父节点必须是block节点 + * @return { UE.dom.Range } 当前range对象 + */ + enlarge:function (toBlock, stopFn) { + var isBody = domUtils.isBody, + pre, node, tmp = this.document.createTextNode(''); + if (toBlock) { + node = this.startContainer; + if (node.nodeType == 1) { + if (node.childNodes[this.startOffset]) { + pre = node = node.childNodes[this.startOffset] + } else { + node.appendChild(tmp); + pre = node = tmp; + } + } else { + pre = node; + } + while (1) { + if (domUtils.isBlockElm(node)) { + node = pre; + while ((pre = node.previousSibling) && !domUtils.isBlockElm(pre)) { + node = pre; + } + this.setStartBefore(node); + break; + } + pre = node; + node = node.parentNode; + } + node = this.endContainer; + if (node.nodeType == 1) { + if (pre = node.childNodes[this.endOffset]) { + node.insertBefore(tmp, pre); + } else { + node.appendChild(tmp); + } + pre = node = tmp; + } else { + pre = node; + } + while (1) { + if (domUtils.isBlockElm(node)) { + node = pre; + while ((pre = node.nextSibling) && !domUtils.isBlockElm(pre)) { + node = pre; + } + this.setEndAfter(node); + break; + } + pre = node; + node = node.parentNode; + } + if (tmp.parentNode === this.endContainer) { + this.endOffset--; + } + domUtils.remove(tmp); + } + + // 扩展边界到最大 + if (!this.collapsed) { + while (this.startOffset == 0) { + if (stopFn && stopFn(this.startContainer)) { + break; + } + if (isBody(this.startContainer)) { + break; + } + this.setStartBefore(this.startContainer); + } + while (this.endOffset == (this.endContainer.nodeType == 1 ? this.endContainer.childNodes.length : this.endContainer.nodeValue.length)) { + if (stopFn && stopFn(this.endContainer)) { + break; + } + if (isBody(this.endContainer)) { + break; + } + this.setEndAfter(this.endContainer); + } + } + return this; + }, + enlargeToBlockElm:function(ignoreEnd){ + while(!domUtils.isBlockElm(this.startContainer)){ + this.setStartBefore(this.startContainer); + } + if(!ignoreEnd){ + while(!domUtils.isBlockElm(this.endContainer)){ + this.setEndAfter(this.endContainer); + } + } + return this; + }, + /** + * 调整Range的边界,使其"缩小"到最合适的位置 + * @method adjustmentBoundary + * @return { UE.dom.Range } 当前range对象 + * @see UE.dom.Range:shrinkBoundary() + */ + adjustmentBoundary:function () { + if (!this.collapsed) { + while (!domUtils.isBody(this.startContainer) && + this.startOffset == this.startContainer[this.startContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length && + this.startContainer[this.startContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length + ) { + + this.setStartAfter(this.startContainer); + } + while (!domUtils.isBody(this.endContainer) && !this.endOffset && + this.endContainer[this.endContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length + ) { + this.setEndBefore(this.endContainer); + } + } + return this; + }, + + /** + * 给range选区中的内容添加给定的inline标签 + * @method applyInlineStyle + * @param { String } tagName 需要添加的标签名 + * @example + * ```html + *

          xxxx[xxxx]x

          ==> range.applyInlineStyle("strong") ==>

          xxxx[xxxx]x

          + * ``` + */ + + /** + * 给range选区中的内容添加给定的inline标签, 并且为标签附加上一些初始化属性。 + * @method applyInlineStyle + * @param { String } tagName 需要添加的标签名 + * @param { Object } attrs 跟随新添加的标签的属性 + * @return { UE.dom.Range } 当前选区 + * @example + * ```html + *

          xxxx[xxxx]x

          + * + * ==> + * + * + * range.applyInlineStyle("strong",{"style":"font-size:12px"}) + * + * ==> + * + *

          xxxx[xxxx]x

          + * ``` + */ + applyInlineStyle:function (tagName, attrs, list) { + if (this.collapsed)return this; + this.trimBoundary().enlarge(false, + function (node) { + return node.nodeType == 1 && domUtils.isBlockElm(node) + }).adjustmentBoundary(); + var bookmark = this.createBookmark(), + end = bookmark.end, + filterFn = function (node) { + return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' : !domUtils.isWhitespace(node); + }, + current = domUtils.getNextDomNode(bookmark.start, false, filterFn), + node, + pre, + range = this.cloneRange(); + while (current && (domUtils.getPosition(current, end) & domUtils.POSITION_PRECEDING)) { + if (current.nodeType == 3 || dtd[tagName][current.tagName]) { + range.setStartBefore(current); + node = current; + while (node && (node.nodeType == 3 || dtd[tagName][node.tagName]) && node !== end) { + pre = node; + node = domUtils.getNextDomNode(node, node.nodeType == 1, null, function (parent) { + return dtd[tagName][parent.tagName]; + }); + } + var frag = range.setEndAfter(pre).extractContents(), elm; + if (list && list.length > 0) { + var level, top; + top = level = list[0].cloneNode(false); + for (var i = 1, ci; ci = list[i++];) { + level.appendChild(ci.cloneNode(false)); + level = level.firstChild; + } + elm = level; + } else { + elm = range.document.createElement(tagName); + } + if (attrs) { + domUtils.setAttributes(elm, attrs); + } + elm.appendChild(frag); + range.insertNode(list ? top : elm); + //处理下滑线在a上的情况 + var aNode; + if (tagName == 'span' && attrs.style && /text\-decoration/.test(attrs.style) && (aNode = domUtils.findParentByTagName(elm, 'a', true))) { + domUtils.setAttributes(aNode, attrs); + domUtils.remove(elm, true); + elm = aNode; + } else { + domUtils.mergeSibling(elm); + domUtils.clearEmptySibling(elm); + } + //去除子节点相同的 + domUtils.mergeChild(elm, attrs); + current = domUtils.getNextDomNode(elm, false, filterFn); + domUtils.mergeToParent(elm); + if (node === end) { + break; + } + } else { + current = domUtils.getNextDomNode(current, true, filterFn); + } + } + return this.moveToBookmark(bookmark); + }, + + /** + * 移除当前选区内指定的inline标签,但保留其中的内容 + * @method removeInlineStyle + * @param { String } tagName 需要移除的标签名 + * @return { UE.dom.Range } 当前的range对象 + * @example + * ```html + * xx[xxxxyyyzz]z => range.removeInlineStyle(["em"]) => xx[xxxxyyyzz]z + * ``` + */ + + /** + * 移除当前选区内指定的一组inline标签,但保留其中的内容 + * @method removeInlineStyle + * @param { Array } tagNameArr 需要移除的标签名的数组 + * @return { UE.dom.Range } 当前的range对象 + * @see UE.dom.Range:removeInlineStyle(String) + */ + removeInlineStyle:function (tagNames) { + if (this.collapsed)return this; + tagNames = utils.isArray(tagNames) ? tagNames : [tagNames]; + this.shrinkBoundary().adjustmentBoundary(); + var start = this.startContainer, end = this.endContainer; + while (1) { + if (start.nodeType == 1) { + if (utils.indexOf(tagNames, start.tagName.toLowerCase()) > -1) { + break; + } + if (start.tagName.toLowerCase() == 'body') { + start = null; + break; + } + } + start = start.parentNode; + } + while (1) { + if (end.nodeType == 1) { + if (utils.indexOf(tagNames, end.tagName.toLowerCase()) > -1) { + break; + } + if (end.tagName.toLowerCase() == 'body') { + end = null; + break; + } + } + end = end.parentNode; + } + var bookmark = this.createBookmark(), + frag, + tmpRange; + if (start) { + tmpRange = this.cloneRange().setEndBefore(bookmark.start).setStartBefore(start); + frag = tmpRange.extractContents(); + tmpRange.insertNode(frag); + domUtils.clearEmptySibling(start, true); + start.parentNode.insertBefore(bookmark.start, start); + } + if (end) { + tmpRange = this.cloneRange().setStartAfter(bookmark.end).setEndAfter(end); + frag = tmpRange.extractContents(); + tmpRange.insertNode(frag); + domUtils.clearEmptySibling(end, false, true); + end.parentNode.insertBefore(bookmark.end, end.nextSibling); + } + var current = domUtils.getNextDomNode(bookmark.start, false, function (node) { + return node.nodeType == 1; + }), next; + while (current && current !== bookmark.end) { + next = domUtils.getNextDomNode(current, true, function (node) { + return node.nodeType == 1; + }); + if (utils.indexOf(tagNames, current.tagName.toLowerCase()) > -1) { + domUtils.remove(current, true); + } + current = next; + } + return this.moveToBookmark(bookmark); + }, + + /** + * 获取当前选中的自闭合的节点 + * @method getClosedNode + * @return { Node | NULL } 如果当前选中的是自闭合节点, 则返回该节点, 否则返回NULL + */ + getClosedNode:function () { + var node; + if (!this.collapsed) { + var range = this.cloneRange().adjustmentBoundary().shrinkBoundary(); + if (selectOneNode(range)) { + var child = range.startContainer.childNodes[range.startOffset]; + if (child && child.nodeType == 1 && (dtd.$empty[child.tagName] || dtd.$nonChild[child.tagName])) { + node = child; + } + } + } + return node; + }, + + /** + * 在页面上高亮range所表示的选区 + * @method select + * @return { UE.dom.Range } 返回当前Range对象 + */ + //这里不区分ie9以上,trace:3824 + select:browser.ie ? function (noFillData, textRange) { + var nativeRange; + if (!this.collapsed) + this.shrinkBoundary(); + var node = this.getClosedNode(); + if (node && !textRange) { + try { + nativeRange = this.document.body.createControlRange(); + nativeRange.addElement(node); + nativeRange.select(); + } catch (e) {} + return this; + } + var bookmark = this.createBookmark(), + start = bookmark.start, + end; + nativeRange = this.document.body.createTextRange(); + nativeRange.moveToElementText(start); + nativeRange.moveStart('character', 1); + if (!this.collapsed) { + var nativeRangeEnd = this.document.body.createTextRange(); + end = bookmark.end; + nativeRangeEnd.moveToElementText(end); + nativeRange.setEndPoint('EndToEnd', nativeRangeEnd); + } else { + if (!noFillData && this.startContainer.nodeType != 3) { + //使用|x固定住光标 + var tmpText = this.document.createTextNode(fillChar), + tmp = this.document.createElement('span'); + tmp.appendChild(this.document.createTextNode(fillChar)); + start.parentNode.insertBefore(tmp, start); + start.parentNode.insertBefore(tmpText, start); + //当点b,i,u时,不能清除i上边的b + removeFillData(this.document, tmpText); + fillData = tmpText; + mergeSibling(tmp, 'previousSibling'); + mergeSibling(start, 'nextSibling'); + nativeRange.moveStart('character', -1); + nativeRange.collapse(true); + } + } + this.moveToBookmark(bookmark); + tmp && domUtils.remove(tmp); + //IE在隐藏状态下不支持range操作,catch一下 + try { + nativeRange.select(); + } catch (e) { + } + return this; + } : function (notInsertFillData) { + function checkOffset(rng){ + + function check(node,offset,dir){ + if(node.nodeType == 3 && node.nodeValue.length < offset){ + rng[dir + 'Offset'] = node.nodeValue.length + } + } + check(rng.startContainer,rng.startOffset,'start'); + check(rng.endContainer,rng.endOffset,'end'); + } + var win = domUtils.getWindow(this.document), + sel = win.getSelection(), + txtNode; + //FF下关闭自动长高时滚动条在关闭dialog时会跳 + //ff下如果不body.focus将不能定位闭合光标到编辑器内 + browser.gecko ? this.document.body.focus() : win.focus(); + if (sel) { + sel.removeAllRanges(); + // trace:870 chrome/safari后边是br对于闭合得range不能定位 所以去掉了判断 + // this.startContainer.nodeType != 3 &&! ((child = this.startContainer.childNodes[this.startOffset]) && child.nodeType == 1 && child.tagName == 'BR' + if (this.collapsed && !notInsertFillData) { +// //opear如果没有节点接着,原生的不能够定位,不能在body的第一级插入空白节点 +// if (notInsertFillData && browser.opera && !domUtils.isBody(this.startContainer) && this.startContainer.nodeType == 1) { +// var tmp = this.document.createTextNode(''); +// this.insertNode(tmp).setStart(tmp, 0).collapse(true); +// } +// + //处理光标落在文本节点的情况 + //处理以下的情况 + //|xxxx + //xxxx|xxxx + //xxxx| + var start = this.startContainer,child = start; + if(start.nodeType == 1){ + child = start.childNodes[this.startOffset]; + + } + if( !(start.nodeType == 3 && this.startOffset) && + (child ? + (!child.previousSibling || child.previousSibling.nodeType != 3) + : + (!start.lastChild || start.lastChild.nodeType != 3) + ) + ){ + txtNode = this.document.createTextNode(fillChar); + //跟着前边走 + this.insertNode(txtNode); + removeFillData(this.document, txtNode); + mergeSibling(txtNode, 'previousSibling'); + mergeSibling(txtNode, 'nextSibling'); + fillData = txtNode; + this.setStart(txtNode, browser.webkit ? 1 : 0).collapse(true); + } + } + var nativeRange = this.document.createRange(); + if(this.collapsed && browser.opera && this.startContainer.nodeType == 1){ + var child = this.startContainer.childNodes[this.startOffset]; + if(!child){ + //往前靠拢 + child = this.startContainer.lastChild; + if( child && domUtils.isBr(child)){ + this.setStartBefore(child).collapse(true); + } + }else{ + //向后靠拢 + while(child && domUtils.isBlockElm(child)){ + if(child.nodeType == 1 && child.childNodes[0]){ + child = child.childNodes[0] + }else{ + break; + } + } + child && this.setStartBefore(child).collapse(true) + } + + } + //是createAddress最后一位算的不准,现在这里进行微调 + checkOffset(this); + nativeRange.setStart(this.startContainer, this.startOffset); + nativeRange.setEnd(this.endContainer, this.endOffset); + sel.addRange(nativeRange); + } + return this; + }, + + /** + * 滚动到当前range开始的位置 + * @method scrollToView + * @param { Window } win 当前range对象所属的window对象 + * @return { UE.dom.Range } 当前Range对象 + */ + + /** + * 滚动到距离当前range开始位置 offset 的位置处 + * @method scrollToView + * @param { Window } win 当前range对象所属的window对象 + * @param { Number } offset 距离range开始位置处的偏移量, 如果为正数, 则向下偏移, 反之, 则向上偏移 + * @return { UE.dom.Range } 当前Range对象 + */ + scrollToView:function (win, offset) { + win = win ? window : domUtils.getWindow(this.document); + var me = this, + span = me.document.createElement('span'); + //trace:717 + span.innerHTML = ' '; + me.cloneRange().insertNode(span); + domUtils.scrollToView(span, win, offset); + domUtils.remove(span); + return me; + }, + + /** + * 判断当前选区内容是否占位符 + * @private + * @method inFillChar + * @return { Boolean } 如果是占位符返回true,否则返回false + */ + inFillChar : function(){ + var start = this.startContainer; + if(this.collapsed && start.nodeType == 3 + && start.nodeValue.replace(new RegExp('^' + domUtils.fillChar),'').length + 1 == start.nodeValue.length + ){ + return true; + } + return false; + }, + + /** + * 保存 + * @method createAddress + * @private + * @return { Boolean } 返回开始和结束的位置 + * @example + * ```html + * + *

          + * aaaa + * + * + * bbbb + * + * + *

          + * + * + * + * ``` + */ + createAddress : function(ignoreEnd,ignoreTxt){ + var addr = {},me = this; + + function getAddress(isStart){ + var node = isStart ? me.startContainer : me.endContainer; + var parents = domUtils.findParents(node,true,function(node){return !domUtils.isBody(node)}), + addrs = []; + for(var i = 0,ci;ci = parents[i++];){ + addrs.push(domUtils.getNodeIndex(ci,ignoreTxt)); + } + var firstIndex = 0; + + if(ignoreTxt){ + if(node.nodeType == 3){ + var tmpNode = node.previousSibling; + while(tmpNode && tmpNode.nodeType == 3){ + firstIndex += tmpNode.nodeValue.replace(fillCharReg,'').length; + tmpNode = tmpNode.previousSibling; + } + firstIndex += (isStart ? me.startOffset : me.endOffset)// - (fillCharReg.test(node.nodeValue) ? 1 : 0 ) + }else{ + node = node.childNodes[ isStart ? me.startOffset : me.endOffset]; + if(node){ + firstIndex = domUtils.getNodeIndex(node,ignoreTxt); + }else{ + node = isStart ? me.startContainer : me.endContainer; + var first = node.firstChild; + while(first){ + if(domUtils.isFillChar(first)){ + first = first.nextSibling; + continue; + } + firstIndex++; + if(first.nodeType == 3){ + while( first && first.nodeType == 3){ + first = first.nextSibling; + } + }else{ + first = first.nextSibling; + } + } + } + } + + }else{ + firstIndex = isStart ? domUtils.isFillChar(node) ? 0 : me.startOffset : me.endOffset + } + if(firstIndex < 0){ + firstIndex = 0; + } + addrs.push(firstIndex); + return addrs; + } + addr.startAddress = getAddress(true); + if(!ignoreEnd){ + addr.endAddress = me.collapsed ? [].concat(addr.startAddress) : getAddress(); + } + return addr; + }, + + /** + * 保存 + * @method createAddress + * @private + * @return { Boolean } 返回开始和结束的位置 + * @example + * ```html + * + *

          + * aaaa + * + * + * bbbb + * + * + *

          + * + * + * + * ``` + */ + moveToAddress : function(addr,ignoreEnd){ + var me = this; + function getNode(address,isStart){ + var tmpNode = me.document.body, + parentNode,offset; + for(var i= 0,ci,l=address.length;i + * + * + * + * + * + * + * + * + * ``` + */ + + /** + * 遍历range内的节点。 + * 每当遍历一个节点时, 都会执行参数项 doFn 指定的函数, 该函数的接受当前遍历的节点 + * 作为其参数。 + * 可以通过参数项 filterFn 来指定一个过滤器, 只有符合该过滤器过滤规则的节点才会触 + * 发doFn函数的执行 + * @method traversal + * @param { Function } doFn 对每个遍历的节点要执行的方法, 该方法接受当前遍历的节点作为其参数 + * @param { Function } filterFn 过滤器, 该函数接受当前遍历的节点作为参数, 如果该节点满足过滤 + * 规则, 请返回true, 该节点会触发doFn, 否则, 请返回false, 则该节点不 + * 会触发doFn。 + * @return { UE.dom.Range } 当前range对象 + * @see UE.dom.Range:traversal(Function) + * @example + * ```html + * + * + * + * + * + * + * + * + * + * + * ``` + */ + traversal:function(doFn,filterFn){ + if (this.collapsed) + return this; + var bookmark = this.createBookmark(), + end = bookmark.end, + current = domUtils.getNextDomNode(bookmark.start, false, filterFn); + while (current && current !== end && (domUtils.getPosition(current, end) & domUtils.POSITION_PRECEDING)) { + var tmpNode = domUtils.getNextDomNode(current,false,filterFn); + doFn(current); + current = tmpNode; + } + return this.moveToBookmark(bookmark); + } + }; +})(); + +// core/Selection.js +/** + * 选集 + * @file + * @module UE.dom + * @class Selection + * @since 1.2.6.1 + */ + +/** + * 选区集合 + * @unfile + * @module UE.dom + * @class Selection + */ +(function () { + + function getBoundaryInformation( range, start ) { + var getIndex = domUtils.getNodeIndex; + range = range.duplicate(); + range.collapse( start ); + var parent = range.parentElement(); + //如果节点里没有子节点,直接退出 + if ( !parent.hasChildNodes() ) { + return {container:parent, offset:0}; + } + var siblings = parent.children, + child, + testRange = range.duplicate(), + startIndex = 0, endIndex = siblings.length - 1, index = -1, + distance; + while ( startIndex <= endIndex ) { + index = Math.floor( (startIndex + endIndex) / 2 ); + child = siblings[index]; + testRange.moveToElementText( child ); + var position = testRange.compareEndPoints( 'StartToStart', range ); + if ( position > 0 ) { + endIndex = index - 1; + } else if ( position < 0 ) { + startIndex = index + 1; + } else { + //trace:1043 + return {container:parent, offset:getIndex( child )}; + } + } + if ( index == -1 ) { + testRange.moveToElementText( parent ); + testRange.setEndPoint( 'StartToStart', range ); + distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length; + siblings = parent.childNodes; + if ( !distance ) { + child = siblings[siblings.length - 1]; + return {container:child, offset:child.nodeValue.length}; + } + + var i = siblings.length; + while ( distance > 0 ){ + distance -= siblings[ --i ].nodeValue.length; + } + return {container:siblings[i], offset:-distance}; + } + testRange.collapse( position > 0 ); + testRange.setEndPoint( position > 0 ? 'StartToStart' : 'EndToStart', range ); + distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length; + if ( !distance ) { + return dtd.$empty[child.tagName] || dtd.$nonChild[child.tagName] ? + {container:parent, offset:getIndex( child ) + (position > 0 ? 0 : 1)} : + {container:child, offset:position > 0 ? 0 : child.childNodes.length} + } + while ( distance > 0 ) { + try { + var pre = child; + child = child[position > 0 ? 'previousSibling' : 'nextSibling']; + distance -= child.nodeValue.length; + } catch ( e ) { + return {container:parent, offset:getIndex( pre )}; + } + } + return {container:child, offset:position > 0 ? -distance : child.nodeValue.length + distance} + } + + /** + * 将ieRange转换为Range对象 + * @param {Range} ieRange ieRange对象 + * @param {Range} range Range对象 + * @return {Range} range 返回转换后的Range对象 + */ + function transformIERangeToRange( ieRange, range ) { + if ( ieRange.item ) { + range.selectNode( ieRange.item( 0 ) ); + } else { + var bi = getBoundaryInformation( ieRange, true ); + range.setStart( bi.container, bi.offset ); + if ( ieRange.compareEndPoints( 'StartToEnd', ieRange ) != 0 ) { + bi = getBoundaryInformation( ieRange, false ); + range.setEnd( bi.container, bi.offset ); + } + } + return range; + } + + /** + * 获得ieRange + * @param {Selection} sel Selection对象 + * @return {ieRange} 得到ieRange + */ + function _getIERange( sel ) { + var ieRange; + //ie下有可能报错 + try { + ieRange = sel.getNative().createRange(); + } catch ( e ) { + return null; + } + var el = ieRange.item ? ieRange.item( 0 ) : ieRange.parentElement(); + if ( ( el.ownerDocument || el ) === sel.document ) { + return ieRange; + } + return null; + } + + var Selection = dom.Selection = function ( doc ) { + var me = this, iframe; + me.document = doc; + if ( browser.ie9below ) { + iframe = domUtils.getWindow( doc ).frameElement; + domUtils.on( iframe, 'beforedeactivate', function () { + me._bakIERange = me.getIERange(); + } ); + domUtils.on( iframe, 'activate', function () { + try { + if ( !_getIERange( me ) && me._bakIERange ) { + me._bakIERange.select(); + } + } catch ( ex ) { + } + me._bakIERange = null; + } ); + } + iframe = doc = null; + }; + + Selection.prototype = { + + rangeInBody : function(rng,txtRange){ + var node = browser.ie9below || txtRange ? rng.item ? rng.item() : rng.parentElement() : rng.startContainer; + + return node === this.document.body || domUtils.inDoc(node,this.document); + }, + + /** + * 获取原生seleciton对象 + * @method getNative + * @return { Object } 获得selection对象 + * @example + * ```javascript + * editor.selection.getNative(); + * ``` + */ + getNative:function () { + var doc = this.document; + try { + return !doc ? null : browser.ie9below ? doc.selection : domUtils.getWindow( doc ).getSelection(); + } catch ( e ) { + return null; + } + }, + + /** + * 获得ieRange + * @method getIERange + * @return { Object } 返回ie原生的Range + * @example + * ```javascript + * editor.selection.getIERange(); + * ``` + */ + getIERange:function () { + var ieRange = _getIERange( this ); + if ( !ieRange ) { + if ( this._bakIERange ) { + return this._bakIERange; + } + } + return ieRange; + }, + + /** + * 缓存当前选区的range和选区的开始节点 + * @method cache + */ + cache:function () { + this.clear(); + this._cachedRange = this.getRange(); + this._cachedStartElement = this.getStart(); + this._cachedStartElementPath = this.getStartElementPath(); + }, + + /** + * 获取选区开始位置的父节点到body + * @method getStartElementPath + * @return { Array } 返回父节点集合 + * @example + * ```javascript + * editor.selection.getStartElementPath(); + * ``` + */ + getStartElementPath:function () { + if ( this._cachedStartElementPath ) { + return this._cachedStartElementPath; + } + var start = this.getStart(); + if ( start ) { + return domUtils.findParents( start, true, null, true ) + } + return []; + }, + + /** + * 清空缓存 + * @method clear + */ + clear:function () { + this._cachedStartElementPath = this._cachedRange = this._cachedStartElement = null; + }, + + /** + * 编辑器是否得到了选区 + * @method isFocus + */ + isFocus:function () { + try { + if(browser.ie9below){ + + var nativeRange = _getIERange(this); + return !!(nativeRange && this.rangeInBody(nativeRange)); + }else{ + return !!this.getNative().rangeCount; + } + } catch ( e ) { + return false; + } + + }, + + /** + * 获取选区对应的Range + * @method getRange + * @return { Object } 得到Range对象 + * @example + * ```javascript + * editor.selection.getRange(); + * ``` + */ + getRange:function () { + var me = this; + function optimze( range ) { + var child = me.document.body.firstChild, + collapsed = range.collapsed; + while ( child && child.firstChild ) { + range.setStart( child, 0 ); + child = child.firstChild; + } + if ( !range.startContainer ) { + range.setStart( me.document.body, 0 ) + } + if ( collapsed ) { + range.collapse( true ); + } + } + + if ( me._cachedRange != null ) { + return this._cachedRange; + } + var range = new baidu.editor.dom.Range( me.document ); + + if ( browser.ie9below ) { + var nativeRange = me.getIERange(); + if ( nativeRange ) { + //备份的_bakIERange可能已经实效了,dom树发生了变化比如从源码模式切回来,所以try一下,实效就放到body开始位置 + try{ + transformIERangeToRange( nativeRange, range ); + }catch(e){ + optimze( range ); + } + + } else { + optimze( range ); + } + } else { + var sel = me.getNative(); + if ( sel && sel.rangeCount ) { + var firstRange = sel.getRangeAt( 0 ); + var lastRange = sel.getRangeAt( sel.rangeCount - 1 ); + range.setStart( firstRange.startContainer, firstRange.startOffset ).setEnd( lastRange.endContainer, lastRange.endOffset ); + if ( range.collapsed && domUtils.isBody( range.startContainer ) && !range.startOffset ) { + optimze( range ); + } + } else { + //trace:1734 有可能已经不在dom树上了,标识的节点 + if ( this._bakRange && domUtils.inDoc( this._bakRange.startContainer, this.document ) ){ + return this._bakRange; + } + optimze( range ); + } + } + return this._bakRange = range; + }, + + /** + * 获取开始元素,用于状态反射 + * @method getStart + * @return { Element } 获得开始元素 + * @example + * ```javascript + * editor.selection.getStart(); + * ``` + */ + getStart:function () { + if ( this._cachedStartElement ) { + return this._cachedStartElement; + } + var range = browser.ie9below ? this.getIERange() : this.getRange(), + tmpRange, + start, tmp, parent; + if ( browser.ie9below ) { + if ( !range ) { + //todo 给第一个值可能会有问题 + return this.document.body.firstChild; + } + //control元素 + if ( range.item ){ + return range.item( 0 ); + } + tmpRange = range.duplicate(); + //修正ie下x[xx] 闭合后 x|xx + tmpRange.text.length > 0 && tmpRange.moveStart( 'character', 1 ); + tmpRange.collapse( 1 ); + start = tmpRange.parentElement(); + parent = tmp = range.parentElement(); + while ( tmp = tmp.parentNode ) { + if ( tmp == start ) { + start = parent; + break; + } + } + } else { + range.shrinkBoundary(); + start = range.startContainer; + if ( start.nodeType == 1 && start.hasChildNodes() ){ + start = start.childNodes[Math.min( start.childNodes.length - 1, range.startOffset )]; + } + if ( start.nodeType == 3 ){ + return start.parentNode; + } + } + return start; + }, + + /** + * 得到选区中的文本 + * @method getText + * @return { String } 选区中包含的文本 + * @example + * ```javascript + * editor.selection.getText(); + * ``` + */ + getText:function () { + var nativeSel, nativeRange; + if ( this.isFocus() && (nativeSel = this.getNative()) ) { + nativeRange = browser.ie9below ? nativeSel.createRange() : nativeSel.getRangeAt( 0 ); + return browser.ie9below ? nativeRange.text : nativeRange.toString(); + } + return ''; + }, + + /** + * 清除选区 + * @method clearRange + * @example + * ```javascript + * editor.selection.clearRange(); + * ``` + */ + clearRange : function(){ + this.getNative()[browser.ie9below ? 'empty' : 'removeAllRanges'](); + } + }; +})(); + +// core/Editor.js +/** + * 编辑器主类,包含编辑器提供的大部分公用接口 + * @file + * @module UE + * @class Editor + * @since 1.2.6.1 + */ + +/** + * UEditor公用空间,UEditor所有的功能都挂载在该空间下 + * @unfile + * @module UE + */ + +/** + * UEditor的核心类,为用户提供与编辑器交互的接口。 + * @unfile + * @module UE + * @class Editor + */ + +(function () { + var uid = 0, _selectionChangeTimer; + + /** + * 获取编辑器的html内容,赋值到编辑器所在表单的textarea文本域里面 + * @private + * @method setValue + * @param { UE.Editor } editor 编辑器事例 + */ + function setValue(form, editor) { + var textarea; + if (editor.textarea) { + if (utils.isString(editor.textarea)) { + for (var i = 0, ti, tis = domUtils.getElementsByTagName(form, 'textarea'); ti = tis[i++];) { + if (ti.id == 'ueditor_textarea_' + editor.options.textarea) { + textarea = ti; + break; + } + } + } else { + textarea = editor.textarea; + } + } + if (!textarea) { + form.appendChild(textarea = domUtils.createElement(document, 'textarea', { + 'name': editor.options.textarea, + 'id': 'ueditor_textarea_' + editor.options.textarea, + 'style': "display:none" + })); + //不要产生多个textarea + editor.textarea = textarea; + } + !textarea.getAttribute('name') && textarea.setAttribute('name', editor.options.textarea ); + textarea.value = editor.hasContents() ? + (editor.options.allHtmlEnabled ? editor.getAllHtml() : editor.getContent(null, null, true)) : + '' + } + function loadPlugins(me){ + //初始化插件 + for (var pi in UE.plugins) { + UE.plugins[pi].call(me); + } + + } + function checkCurLang(I18N){ + for(var lang in I18N){ + return lang + } + } + + function langReadied(me){ + me.langIsReady = true; + + me.fireEvent("langReady"); + } + + /** + * 编辑器准备就绪后会触发该事件 + * @module UE + * @class Editor + * @event ready + * @remind render方法执行完成之后,会触发该事件 + * @remind + * @example + * ```javascript + * editor.addListener( 'ready', function( editor ) { + * editor.execCommand( 'focus' ); //编辑器家在完成后,让编辑器拿到焦点 + * } ); + * ``` + */ + /** + * 执行destroy方法,会触发该事件 + * @module UE + * @class Editor + * @event destroy + * @see UE.Editor:destroy() + */ + /** + * 执行reset方法,会触发该事件 + * @module UE + * @class Editor + * @event reset + * @see UE.Editor:reset() + */ + /** + * 执行focus方法,会触发该事件 + * @module UE + * @class Editor + * @event focus + * @see UE.Editor:focus(Boolean) + */ + /** + * 语言加载完成会触发该事件 + * @module UE + * @class Editor + * @event langReady + */ + /** + * 运行命令之后会触发该命令 + * @module UE + * @class Editor + * @event beforeExecCommand + */ + /** + * 运行命令之后会触发该命令 + * @module UE + * @class Editor + * @event afterExecCommand + */ + /** + * 运行命令之前会触发该命令 + * @module UE + * @class Editor + * @event firstBeforeExecCommand + */ + /** + * 在getContent方法执行之前会触发该事件 + * @module UE + * @class Editor + * @event beforeGetContent + * @see UE.Editor:getContent() + */ + /** + * 在getContent方法执行之后会触发该事件 + * @module UE + * @class Editor + * @event afterGetContent + * @see UE.Editor:getContent() + */ + /** + * 在getAllHtml方法执行时会触发该事件 + * @module UE + * @class Editor + * @event getAllHtml + * @see UE.Editor:getAllHtml() + */ + /** + * 在setContent方法执行之前会触发该事件 + * @module UE + * @class Editor + * @event beforeSetContent + * @see UE.Editor:setContent(String) + */ + /** + * 在setContent方法执行之后会触发该事件 + * @module UE + * @class Editor + * @event afterSetContent + * @see UE.Editor:setContent(String) + */ + /** + * 每当编辑器内部选区发生改变时,将触发该事件 + * @event selectionchange + * @warning 该事件的触发非常频繁,不建议在该事件的处理过程中做重量级的处理 + * @example + * ```javascript + * editor.addListener( 'selectionchange', function( editor ) { + * console.log('选区发生改变'); + * } + */ + /** + * 在所有selectionchange的监听函数执行之前,会触发该事件 + * @module UE + * @class Editor + * @event beforeSelectionChange + * @see UE.Editor:selectionchange + */ + /** + * 在所有selectionchange的监听函数执行完之后,会触发该事件 + * @module UE + * @class Editor + * @event afterSelectionChange + * @see UE.Editor:selectionchange + */ + /** + * 编辑器内容发生改变时会触发该事件 + * @module UE + * @class Editor + * @event contentChange + */ + + + /** + * 以默认参数构建一个编辑器实例 + * @constructor + * @remind 通过 改构造方法实例化的编辑器,不带ui层.需要render到一个容器,编辑器实例才能正常渲染到页面 + * @example + * ```javascript + * var editor = new UE.Editor(); + * editor.execCommand('blod'); + * ``` + * @see UE.Config + */ + + /** + * 以给定的参数集合创建一个编辑器实例,对于未指定的参数,将应用默认参数。 + * @constructor + * @remind 通过 改构造方法实例化的编辑器,不带ui层.需要render到一个容器,编辑器实例才能正常渲染到页面 + * @param { Object } setting 创建编辑器的参数 + * @example + * ```javascript + * var editor = new UE.Editor(); + * editor.execCommand('blod'); + * ``` + * @see UE.Config + */ + var Editor = UE.Editor = function (options) { + var me = this; + me.uid = uid++; + EventBase.call(me); + me.commands = {}; + me.options = utils.extend(utils.clone(options || {}), UEDITOR_CONFIG, true); + me.shortcutkeys = {}; + me.inputRules = []; + me.outputRules = []; + //设置默认的常用属性 + me.setOpt(Editor.defaultOptions(me)); + + /* 尝试异步加载后台配置 */ + me.loadServerConfig(); + + if(!utils.isEmptyObject(UE.I18N)){ + //修改默认的语言类型 + me.options.lang = checkCurLang(UE.I18N); + UE.plugin.load(me); + langReadied(me); + + }else{ + utils.loadFile(document, { + src: me.options.langPath + me.options.lang + "/" + me.options.lang + ".js", + tag: "script", + type: "text/javascript", + defer: "defer" + }, function () { + UE.plugin.load(me); + langReadied(me); + }); + } + + UE.instants['ueditorInstant' + me.uid] = me; + }; + Editor.prototype = { + registerCommand : function(name,obj){ + this.commands[name] = obj; + }, + /** + * 编辑器对外提供的监听ready事件的接口, 通过调用该方法,达到的效果与监听ready事件是一致的 + * @method ready + * @param { Function } fn 编辑器ready之后所执行的回调, 如果在注册事件之前编辑器已经ready,将会 + * 立即触发该回调。 + * @remind 需要等待编辑器加载完成后才能执行的代码,可以使用该方法传入 + * @example + * ```javascript + * editor.ready( function( editor ) { + * editor.setContent('初始化完毕'); + * } ); + * ``` + * @see UE.Editor.event:ready + */ + ready: function (fn) { + var me = this; + if (fn) { + me.isReady ? fn.apply(me) : me.addListener('ready', fn); + } + }, + + /** + * 该方法是提供给插件里面使用,设置配置项默认值 + * @method setOpt + * @warning 三处设置配置项的优先级: 实例化时传入参数 > setOpt()设置 > config文件里设置 + * @warning 该方法仅供编辑器插件内部和编辑器初始化时调用,其他地方不能调用。 + * @param { String } key 编辑器的可接受的选项名称 + * @param { * } val 该选项可接受的值 + * @example + * ```javascript + * editor.setOpt( 'initContent', '欢迎使用编辑器' ); + * ``` + */ + + /** + * 该方法是提供给插件里面使用,以{key:value}集合的方式设置插件内用到的配置项默认值 + * @method setOpt + * @warning 三处设置配置项的优先级: 实例化时传入参数 > setOpt()设置 > config文件里设置 + * @warning 该方法仅供编辑器插件内部和编辑器初始化时调用,其他地方不能调用。 + * @param { Object } options 将要设置的选项的键值对对象 + * @example + * ```javascript + * editor.setOpt( { + * 'initContent': '欢迎使用编辑器' + * } ); + * ``` + */ + setOpt: function (key, val) { + var obj = {}; + if (utils.isString(key)) { + obj[key] = val + } else { + obj = key; + } + utils.extend(this.options, obj, true); + }, + getOpt:function(key){ + return this.options[key] + }, + /** + * 销毁编辑器实例,使用textarea代替 + * @method destroy + * @example + * ```javascript + * editor.destroy(); + * ``` + */ + destroy: function () { + + var me = this; + me.fireEvent('destroy'); + var container = me.container.parentNode; + var textarea = me.textarea; + if (!textarea) { + textarea = document.createElement('textarea'); + container.parentNode.insertBefore(textarea, container); + } else { + textarea.style.display = '' + } + + textarea.style.width = me.iframe.offsetWidth + 'px'; + textarea.style.height = me.iframe.offsetHeight + 'px'; + textarea.value = me.getContent(); + textarea.id = me.key; + container.innerHTML = ''; + domUtils.remove(container); + var key = me.key; + //trace:2004 + for (var p in me) { + if (me.hasOwnProperty(p)) { + delete this[p]; + } + } + UE.delEditor(key); + }, + + /** + * 渲染编辑器的DOM到指定容器 + * @method render + * @param { String } containerId 指定一个容器ID + * @remind 执行该方法,会触发ready事件 + * @warning 必须且只能调用一次 + */ + + /** + * 渲染编辑器的DOM到指定容器 + * @method render + * @param { Element } containerDom 直接指定容器对象 + * @remind 执行该方法,会触发ready事件 + * @warning 必须且只能调用一次 + */ + render: function (container) { + var me = this, + options = me.options, + getStyleValue=function(attr){ + return parseInt(domUtils.getComputedStyle(container,attr)); + }; + if (utils.isString(container)) { + container = document.getElementById(container); + } + if (container) { + if(options.initialFrameWidth){ + options.minFrameWidth = options.initialFrameWidth + }else{ + options.minFrameWidth = options.initialFrameWidth = container.offsetWidth; + } + if(options.initialFrameHeight){ + options.minFrameHeight = options.initialFrameHeight + }else{ + options.initialFrameHeight = options.minFrameHeight = container.offsetHeight; + } + + container.style.width = /%$/.test(options.initialFrameWidth) ? '100%' : options.initialFrameWidth- + getStyleValue("padding-left")- getStyleValue("padding-right") +'px'; + container.style.height = /%$/.test(options.initialFrameHeight) ? '100%' : options.initialFrameHeight - + getStyleValue("padding-top")- getStyleValue("padding-bottom") +'px'; + + container.style.zIndex = options.zIndex; + + var html = ( ie && browser.version < 9 ? '' : '') + + '' + + '' + + ( options.iframeCssUrl ? '' : '' ) + + (options.initialStyle ? '' : '') + + '' + + ''; + container.appendChild(domUtils.createElement(document, 'iframe', { + id: 'ueditor_' + me.uid, + width: "100%", + height: "100%", + frameborder: "0", + //先注释掉了,加的原因忘记了,但开启会直接导致全屏模式下内容多时不会出现滚动条 +// scrolling :'no', + src: 'javascript:void(function(){document.open();' + (options.customDomain && document.domain != location.hostname ? 'document.domain="' + document.domain + '";' : '') + + 'document.write("' + html + '");document.close();}())' + })); + container.style.overflow = 'hidden'; + //解决如果是给定的百分比,会导致高度算不对的问题 + setTimeout(function(){ + if( /%$/.test(options.initialFrameWidth)){ + options.minFrameWidth = options.initialFrameWidth = container.offsetWidth; + //如果这里给定宽度,会导致ie在拖动窗口大小时,编辑区域不随着变化 +// container.style.width = options.initialFrameWidth + 'px'; + } + if(/%$/.test(options.initialFrameHeight)){ + options.minFrameHeight = options.initialFrameHeight = container.offsetHeight; + container.style.height = options.initialFrameHeight + 'px'; + } + }) + } + }, + + /** + * 编辑器初始化 + * @method _setup + * @private + * @param { Element } doc 编辑器Iframe中的文档对象 + */ + _setup: function (doc) { + + var me = this, + options = me.options; + if (ie) { + doc.body.disabled = true; + doc.body.contentEditable = true; + doc.body.disabled = false; + } else { + doc.body.contentEditable = true; + } + doc.body.spellcheck = false; + me.document = doc; + me.window = doc.defaultView || doc.parentWindow; + me.iframe = me.window.frameElement; + me.body = doc.body; + me.selection = new dom.Selection(doc); + //gecko初始化就能得到range,无法判断isFocus了 + var geckoSel; + if (browser.gecko && (geckoSel = this.selection.getNative())) { + geckoSel.removeAllRanges(); + } + this._initEvents(); + //为form提交提供一个隐藏的textarea + for (var form = this.iframe.parentNode; !domUtils.isBody(form); form = form.parentNode) { + if (form.tagName == 'FORM') { + me.form = form; + if(me.options.autoSyncData){ + domUtils.on(me.window,'blur',function(){ + setValue(form,me); + }); + }else{ + domUtils.on(form, 'submit', function () { + setValue(this, me); + }); + } + break; + } + } + if (options.initialContent) { + if (options.autoClearinitialContent) { + var oldExecCommand = me.execCommand; + me.execCommand = function () { + me.fireEvent('firstBeforeExecCommand'); + return oldExecCommand.apply(me, arguments); + }; + this._setDefaultContent(options.initialContent); + } else + this.setContent(options.initialContent, false, true); + } + + //编辑器不能为空内容 + + if (domUtils.isEmptyNode(me.body)) { + me.body.innerHTML = '

          ' + (browser.ie ? '' : '
          ') + '

          '; + } + //如果要求focus, 就把光标定位到内容开始 + if (options.focus) { + setTimeout(function () { + me.focus(me.options.focusInEnd); + //如果自动清除开着,就不需要做selectionchange; + !me.options.autoClearinitialContent && me._selectionChange(); + }, 0); + } + if (!me.container) { + me.container = this.iframe.parentNode; + } + if (options.fullscreen && me.ui) { + me.ui.setFullScreen(true); + } + + try { + me.document.execCommand('2D-position', false, false); + } catch (e) { + } + try { + me.document.execCommand('enableInlineTableEditing', false, false); + } catch (e) { + } + try { + me.document.execCommand('enableObjectResizing', false, false); + } catch (e) { + } + + //挂接快捷键 + me._bindshortcutKeys(); + me.isReady = 1; + me.fireEvent('ready'); + options.onready && options.onready.call(me); + if (!browser.ie9below) { + domUtils.on(me.window, ['blur', 'focus'], function (e) { + //chrome下会出现alt+tab切换时,导致选区位置不对 + if (e.type == 'blur') { + me._bakRange = me.selection.getRange(); + try { + me._bakNativeRange = me.selection.getNative().getRangeAt(0); + me.selection.getNative().removeAllRanges(); + } catch (e) { + me._bakNativeRange = null; + } + + } else { + try { + me._bakRange && me._bakRange.select(); + } catch (e) { + } + } + }); + } + //trace:1518 ff3.6body不够寛,会导致点击空白处无法获得焦点 + if (browser.gecko && browser.version <= 10902) { + //修复ff3.6初始化进来,不能点击获得焦点 + me.body.contentEditable = false; + setTimeout(function () { + me.body.contentEditable = true; + }, 100); + setInterval(function () { + me.body.style.height = me.iframe.offsetHeight - 20 + 'px' + }, 100) + } + + !options.isShow && me.setHide(); + options.readonly && me.setDisabled(); + }, + + /** + * 同步数据到编辑器所在的form + * 从编辑器的容器节点向上查找form元素,若找到,就同步编辑内容到找到的form里,为提交数据做准备,主要用于是手动提交的情况 + * 后台取得数据的键值,使用你容器上的name属性,如果没有就使用参数里的textarea项 + * @method sync + * @example + * ```javascript + * editor.sync(); + * form.sumbit(); //form变量已经指向了form元素 + * ``` + */ + + /** + * 根据传入的formId,在页面上查找要同步数据的表单,若找到,就同步编辑内容到找到的form里,为提交数据做准备 + * 后台取得数据的键值,该键值默认使用给定的编辑器容器的name属性,如果没有name属性则使用参数项里给定的“textarea”项 + * @method sync + * @param { String } formID 指定一个要同步数据的form的id,编辑器的数据会同步到你指定form下 + */ + sync: function (formId) { + var me = this, + form = formId ? document.getElementById(formId) : + domUtils.findParent(me.iframe.parentNode, function (node) { + return node.tagName == 'FORM' + }, true); + form && setValue(form, me); + }, + + /** + * 设置编辑器高度 + * @method setHeight + * @remind 当配置项autoHeightEnabled为真时,该方法无效 + * @param { Number } number 设置的高度值,纯数值,不带单位 + * @example + * ```javascript + * editor.setHeight(number); + * ``` + */ + setHeight: function (height,notSetHeight) { + if (height !== parseInt(this.iframe.parentNode.style.height)) { + this.iframe.parentNode.style.height = height + 'px'; + } + !notSetHeight && (this.options.minFrameHeight = this.options.initialFrameHeight = height); + this.body.style.height = height + 'px'; + !notSetHeight && this.trigger('setHeight') + }, + + /** + * 为编辑器的编辑命令提供快捷键 + * 这个接口是为插件扩展提供的接口,主要是为新添加的插件,如果需要添加快捷键,所提供的接口 + * @method addshortcutkey + * @param { Object } keyset 命令名和快捷键键值对对象,多个按钮的快捷键用“+”分隔 + * @example + * ```javascript + * editor.addshortcutkey({ + * "Bold" : "ctrl+66",//^B + * "Italic" : "ctrl+73", //^I + * }); + * ``` + */ + /** + * 这个接口是为插件扩展提供的接口,主要是为新添加的插件,如果需要添加快捷键,所提供的接口 + * @method addshortcutkey + * @param { String } cmd 触发快捷键时,响应的命令 + * @param { String } keys 快捷键的字符串,多个按钮用“+”分隔 + * @example + * ```javascript + * editor.addshortcutkey("Underline", "ctrl+85"); //^U + * ``` + */ + addshortcutkey: function (cmd, keys) { + var obj = {}; + if (keys) { + obj[cmd] = keys + } else { + obj = cmd; + } + utils.extend(this.shortcutkeys, obj) + }, + + /** + * 对编辑器设置keydown事件监听,绑定快捷键和命令,当快捷键组合触发成功,会响应对应的命令 + * @method _bindshortcutKeys + * @private + */ + _bindshortcutKeys: function () { + var me = this, shortcutkeys = this.shortcutkeys; + me.addListener('keydown', function (type, e) { + var keyCode = e.keyCode || e.which; + for (var i in shortcutkeys) { + var tmp = shortcutkeys[i].split(','); + for (var t = 0, ti; ti = tmp[t++];) { + ti = ti.split(':'); + var key = ti[0], param = ti[1]; + if (/^(ctrl)(\+shift)?\+(\d+)$/.test(key.toLowerCase()) || /^(\d+)$/.test(key)) { + if (( (RegExp.$1 == 'ctrl' ? (e.ctrlKey || e.metaKey) : 0) + && (RegExp.$2 != "" ? e[RegExp.$2.slice(1) + "Key"] : 1) + && keyCode == RegExp.$3 + ) || + keyCode == RegExp.$1 + ) { + if (me.queryCommandState(i,param) != -1) + me.execCommand(i, param); + domUtils.preventDefault(e); + } + } + } + + } + }); + }, + + /** + * 获取编辑器的内容 + * @method getContent + * @warning 该方法获取到的是经过编辑器内置的过滤规则进行过滤后得到的内容 + * @return { String } 编辑器的内容字符串, 如果编辑器的内容为空,或者是空的标签内容(如:”<p><br/></p>“), 则返回空字符串 + * @example + * ```javascript + * //编辑器html内容:

          123456

          + * var content = editor.getContent(); //返回值:

          123456

          + * ``` + */ + + /** + * 获取编辑器的内容。 可以通过参数定义编辑器内置的判空规则 + * @method getContent + * @param { Function } fn 自定的判空规则, 要求该方法返回一个boolean类型的值, + * 代表当前编辑器的内容是否空, + * 如果返回true, 则该方法将直接返回空字符串;如果返回false,则编辑器将返回 + * 经过内置过滤规则处理后的内容。 + * @remind 该方法在处理包含有初始化内容的时候能起到很好的作用。 + * @warning 该方法获取到的是经过编辑器内置的过滤规则进行过滤后得到的内容 + * @return { String } 编辑器的内容字符串 + * @example + * ```javascript + * // editor 是一个编辑器的实例 + * var content = editor.getContent( function ( editor ) { + * return editor.body.innerHTML === '欢迎使用UEditor'; //返回空字符串 + * } ); + * ``` + */ + getContent: function (cmd, fn,notSetCursor,ignoreBlank,formatter) { + var me = this; + if (cmd && utils.isFunction(cmd)) { + fn = cmd; + cmd = ''; + } + if (fn ? !fn() : !this.hasContents()) { + return ''; + } + me.fireEvent('beforegetcontent'); + var root = UE.htmlparser(me.body.innerHTML,ignoreBlank); + me.filterOutputRule(root); + me.fireEvent('aftergetcontent', cmd,root); + return root.toHtml(formatter); + }, + + /** + * 取得完整的html代码,可以直接显示成完整的html文档 + * @method getAllHtml + * @return { String } 编辑器的内容html文档字符串 + * @eaxmple + * ```javascript + * editor.getAllHtml(); //返回格式大致是: ...... + * ``` + */ + getAllHtml: function () { + var me = this, + headHtml = [], + html = ''; + me.fireEvent('getAllHtml', headHtml); + if (browser.ie && browser.version > 8) { + var headHtmlForIE9 = ''; + utils.each(me.document.styleSheets, function (si) { + headHtmlForIE9 += ( si.href ? '' : ''); + }); + utils.each(me.document.getElementsByTagName('script'), function (si) { + headHtmlForIE9 += si.outerHTML; + }); + + } + return '' + (me.options.charset ? '' : '') + + (headHtmlForIE9 || me.document.getElementsByTagName('head')[0].innerHTML) + headHtml.join('\n') + '' + + '' + me.getContent(null, null, true) + ''; + }, + + /** + * 得到编辑器的纯文本内容,但会保留段落格式 + * @method getPlainTxt + * @return { String } 编辑器带段落格式的纯文本内容字符串 + * @example + * ```javascript + * //编辑器html内容:

          1

          2

          + * console.log(editor.getPlainTxt()); //输出:"1\n2\n + * ``` + */ + getPlainTxt: function () { + var reg = new RegExp(domUtils.fillChar, 'g'), + html = this.body.innerHTML.replace(/[\n\r]/g, '');//ie要先去了\n在处理 + html = html.replace(/<(p|div)[^>]*>(| )<\/\1>/gi, '\n') + .replace(//gi, '\n') + .replace(/<[^>/]+>/g, '') + .replace(/(\n)?<\/([^>]+)>/g, function (a, b, c) { + return dtd.$block[c] ? '\n' : b ? b : ''; + }); + //取出来的空格会有c2a0会变成乱码,处理这种情况\u00a0 + return html.replace(reg, '').replace(/\u00a0/g, ' ').replace(/ /g, ' '); + }, + + /** + * 获取编辑器中的纯文本内容,没有段落格式 + * @method getContentTxt + * @return { String } 编辑器不带段落格式的纯文本内容字符串 + * @example + * ```javascript + * //编辑器html内容:

          1

          2

          + * console.log(editor.getPlainTxt()); //输出:"12 + * ``` + */ + getContentTxt: function () { + var reg = new RegExp(domUtils.fillChar, 'g'); + //取出来的空格会有c2a0会变成乱码,处理这种情况\u00a0 + return this.body[browser.ie ? 'innerText' : 'textContent'].replace(reg, '').replace(/\u00a0/g, ' '); + }, + + /** + * 设置编辑器的内容,可修改编辑器当前的html内容 + * @method setContent + * @warning 通过该方法插入的内容,是经过编辑器内置的过滤规则进行过滤后得到的内容 + * @warning 该方法会触发selectionchange事件 + * @param { String } html 要插入的html内容 + * @example + * ```javascript + * editor.getContent('

          test

          '); + * ``` + */ + + /** + * 设置编辑器的内容,可修改编辑器当前的html内容 + * @method setContent + * @warning 通过该方法插入的内容,是经过编辑器内置的过滤规则进行过滤后得到的内容 + * @warning 该方法会触发selectionchange事件 + * @param { String } html 要插入的html内容 + * @param { Boolean } isAppendTo 若传入true,不清空原来的内容,在最后插入内容,否则,清空内容再插入 + * @example + * ```javascript + * //假设设置前的编辑器内容是

          old text

          + * editor.setContent('

          new text

          ', true); //插入的结果是

          old text

          new text

          + * ``` + */ + setContent: function (html, isAppendTo, notFireSelectionchange) { + var me = this; + + me.fireEvent('beforesetcontent', html); + var root = UE.htmlparser(html); + me.filterInputRule(root); + html = root.toHtml(); + + me.body.innerHTML = (isAppendTo ? me.body.innerHTML : '') + html; + + + function isCdataDiv(node){ + return node.tagName == 'DIV' && node.getAttribute('cdata_tag'); + } + //给文本或者inline节点套p标签 + if (me.options.enterTag == 'p') { + + var child = this.body.firstChild, tmpNode; + if (!child || child.nodeType == 1 && + (dtd.$cdata[child.tagName] || isCdataDiv(child) || + domUtils.isCustomeNode(child) + ) + && child === this.body.lastChild) { + this.body.innerHTML = '

          ' + (browser.ie ? ' ' : '
          ') + '

          ' + this.body.innerHTML; + + } else { + var p = me.document.createElement('p'); + while (child) { + while (child && (child.nodeType == 3 || child.nodeType == 1 && dtd.p[child.tagName] && !dtd.$cdata[child.tagName])) { + tmpNode = child.nextSibling; + p.appendChild(child); + child = tmpNode; + } + if (p.firstChild) { + if (!child) { + me.body.appendChild(p); + break; + } else { + child.parentNode.insertBefore(p, child); + p = me.document.createElement('p'); + } + } + child = child.nextSibling; + } + } + } + me.fireEvent('aftersetcontent'); + me.fireEvent('contentchange'); + + !notFireSelectionchange && me._selectionChange(); + //清除保存的选区 + me._bakRange = me._bakIERange = me._bakNativeRange = null; + //trace:1742 setContent后gecko能得到焦点问题 + var geckoSel; + if (browser.gecko && (geckoSel = this.selection.getNative())) { + geckoSel.removeAllRanges(); + } + if(me.options.autoSyncData){ + me.form && setValue(me.form,me); + } + }, + + /** + * 让编辑器获得焦点,默认focus到编辑器头部 + * @method focus + * @example + * ```javascript + * editor.focus() + * ``` + */ + + /** + * 让编辑器获得焦点,toEnd确定focus位置 + * @method focus + * @param { Boolean } toEnd 默认focus到编辑器头部,toEnd为true时focus到内容尾部 + * @example + * ```javascript + * editor.focus(true) + * ``` + */ + focus: function (toEnd) { + try { + var me = this, + rng = me.selection.getRange(); + if (toEnd) { + var node = me.body.lastChild; + if(node && node.nodeType == 1 && !dtd.$empty[node.tagName]){ + if(domUtils.isEmptyBlock(node)){ + rng.setStartAtFirst(node) + }else{ + rng.setStartAtLast(node) + } + rng.collapse(true); + } + rng.setCursor(true); + } else { + if(!rng.collapsed && domUtils.isBody(rng.startContainer) && rng.startOffset == 0){ + + var node = me.body.firstChild; + if(node && node.nodeType == 1 && !dtd.$empty[node.tagName]){ + rng.setStartAtFirst(node).collapse(true); + } + } + + rng.select(true); + + } + this.fireEvent('focus selectionchange'); + } catch (e) { + } + + }, + isFocus:function(){ + return this.selection.isFocus(); + }, + blur:function(){ + var sel = this.selection.getNative(); + if(sel.empty && browser.ie){ + var nativeRng = document.body.createTextRange(); + nativeRng.moveToElementText(document.body); + nativeRng.collapse(true); + nativeRng.select(); + sel.empty() + }else{ + sel.removeAllRanges() + } + + //this.fireEvent('blur selectionchange'); + }, + /** + * 初始化UE事件及部分事件代理 + * @method _initEvents + * @private + */ + _initEvents: function () { + var me = this, + doc = me.document, + win = me.window; + me._proxyDomEvent = utils.bind(me._proxyDomEvent, me); + domUtils.on(doc, ['click', 'contextmenu', 'mousedown', 'keydown', 'keyup', 'keypress', 'mouseup', 'mouseover', 'mouseout', 'selectstart'], me._proxyDomEvent); + domUtils.on(win, ['focus', 'blur'], me._proxyDomEvent); + domUtils.on(me.body,'drop',function(e){ + //阻止ff下默认的弹出新页面打开图片 + if(browser.gecko && e.stopPropagation) { e.stopPropagation(); } + me.fireEvent('contentchange') + }); + domUtils.on(doc, ['mouseup', 'keydown'], function (evt) { + //特殊键不触发selectionchange + if (evt.type == 'keydown' && (evt.ctrlKey || evt.metaKey || evt.shiftKey || evt.altKey)) { + return; + } + if (evt.button == 2)return; + me._selectionChange(250, evt); + }); + }, + /** + * 触发事件代理 + * @method _proxyDomEvent + * @private + * @return { * } fireEvent的返回值 + * @see UE.EventBase:fireEvent(String) + */ + _proxyDomEvent: function (evt) { + if(this.fireEvent('before' + evt.type.replace(/^on/, '').toLowerCase()) === false){ + return false; + } + if(this.fireEvent(evt.type.replace(/^on/, ''), evt) === false){ + return false; + } + return this.fireEvent('after' + evt.type.replace(/^on/, '').toLowerCase()) + }, + /** + * 变化选区 + * @method _selectionChange + * @private + */ + _selectionChange: function (delay, evt) { + var me = this; + //有光标才做selectionchange 为了解决未focus时点击source不能触发更改工具栏状态的问题(source命令notNeedUndo=1) +// if ( !me.selection.isFocus() ){ +// return; +// } + + + var hackForMouseUp = false; + var mouseX, mouseY; + if (browser.ie && browser.version < 9 && evt && evt.type == 'mouseup') { + var range = this.selection.getRange(); + if (!range.collapsed) { + hackForMouseUp = true; + mouseX = evt.clientX; + mouseY = evt.clientY; + } + } + clearTimeout(_selectionChangeTimer); + _selectionChangeTimer = setTimeout(function () { + if (!me.selection || !me.selection.getNative()) { + return; + } + //修复一个IE下的bug: 鼠标点击一段已选择的文本中间时,可能在mouseup后的一段时间内取到的range是在selection的type为None下的错误值. + //IE下如果用户是拖拽一段已选择文本,则不会触发mouseup事件,所以这里的特殊处理不会对其有影响 + var ieRange; + if (hackForMouseUp && me.selection.getNative().type == 'None') { + ieRange = me.document.body.createTextRange(); + try { + ieRange.moveToPoint(mouseX, mouseY); + } catch (ex) { + ieRange = null; + } + } + var bakGetIERange; + if (ieRange) { + bakGetIERange = me.selection.getIERange; + me.selection.getIERange = function () { + return ieRange; + }; + } + me.selection.cache(); + if (bakGetIERange) { + me.selection.getIERange = bakGetIERange; + } + if (me.selection._cachedRange && me.selection._cachedStartElement) { + me.fireEvent('beforeselectionchange'); + // 第二个参数causeByUi为true代表由用户交互造成的selectionchange. + me.fireEvent('selectionchange', !!evt); + me.fireEvent('afterselectionchange'); + me.selection.clear(); + } + }, delay || 50); + }, + + /** + * 执行编辑命令 + * @method _callCmdFn + * @private + * @param { String } fnName 函数名称 + * @param { * } args 传给命令函数的参数 + * @return { * } 返回命令函数运行的返回值 + */ + _callCmdFn: function (fnName, args) { + var cmdName = args[0].toLowerCase(), + cmd, cmdFn; + cmd = this.commands[cmdName] || UE.commands[cmdName]; + cmdFn = cmd && cmd[fnName]; + //没有querycommandstate或者没有command的都默认返回0 + if ((!cmd || !cmdFn) && fnName == 'queryCommandState') { + return 0; + } else if (cmdFn) { + return cmdFn.apply(this, args); + } + }, + + /** + * 执行编辑命令cmdName,完成富文本编辑效果 + * @method execCommand + * @param { String } cmdName 需要执行的命令 + * @remind 具体命令的使用请参考命令列表 + * @return { * } 返回命令函数运行的返回值 + * @example + * ```javascript + * editor.execCommand(cmdName); + * ``` + */ + execCommand: function (cmdName) { + cmdName = cmdName.toLowerCase(); + var me = this, + result, + cmd = me.commands[cmdName] || UE.commands[cmdName]; + if (!cmd || !cmd.execCommand) { + return null; + } + if (!cmd.notNeedUndo && !me.__hasEnterExecCommand) { + me.__hasEnterExecCommand = true; + if (me.queryCommandState.apply(me,arguments) != -1) { + me.fireEvent('saveScene'); + me.fireEvent.apply(me, ['beforeexeccommand', cmdName].concat(arguments)); + result = this._callCmdFn('execCommand', arguments); + //保存场景时,做了内容对比,再看是否进行contentchange触发,这里多触发了一次,去掉 +// (!cmd.ignoreContentChange && !me._ignoreContentChange) && me.fireEvent('contentchange'); + me.fireEvent.apply(me, ['afterexeccommand', cmdName].concat(arguments)); + me.fireEvent('saveScene'); + } + me.__hasEnterExecCommand = false; + } else { + result = this._callCmdFn('execCommand', arguments); + (!me.__hasEnterExecCommand && !cmd.ignoreContentChange && !me._ignoreContentChange) && me.fireEvent('contentchange') + } + (!me.__hasEnterExecCommand && !cmd.ignoreContentChange && !me._ignoreContentChange) && me._selectionChange(); + return result; + }, + + /** + * 根据传入的command命令,查选编辑器当前的选区,返回命令的状态 + * @method queryCommandState + * @param { String } cmdName 需要查询的命令名称 + * @remind 具体命令的使用请参考命令列表 + * @return { Number } number 返回放前命令的状态,返回值三种情况:(-1|0|1) + * @example + * ```javascript + * editor.queryCommandState(cmdName) => (-1|0|1) + * ``` + * @see COMMAND.LIST + */ + queryCommandState: function (cmdName) { + return this._callCmdFn('queryCommandState', arguments); + }, + + /** + * 根据传入的command命令,查选编辑器当前的选区,根据命令返回相关的值 + * @method queryCommandValue + * @param { String } cmdName 需要查询的命令名称 + * @remind 具体命令的使用请参考命令列表 + * @remind 只有部分插件有此方法 + * @return { * } 返回每个命令特定的当前状态值 + * @grammar editor.queryCommandValue(cmdName) => {*} + * @see COMMAND.LIST + */ + queryCommandValue: function (cmdName) { + return this._callCmdFn('queryCommandValue', arguments); + }, + + /** + * 检查编辑区域中是否有内容 + * @method hasContents + * @remind 默认有文本内容,或者有以下节点都不认为是空 + * table,ul,ol,dl,iframe,area,base,col,hr,img,embed,input,link,meta,param + * @return { Boolean } 检查有内容返回true,否则返回false + * @example + * ```javascript + * editor.hasContents() + * ``` + */ + + /** + * 检查编辑区域中是否有内容,若包含参数tags中的节点类型,直接返回true + * @method hasContents + * @param { Array } tags 传入数组判断时用到的节点类型 + * @return { Boolean } 若文档中包含tags数组里对应的tag,返回true,否则返回false + * @example + * ```javascript + * editor.hasContents(['span']); + * ``` + */ + hasContents: function (tags) { + if (tags) { + for (var i = 0, ci; ci = tags[i++];) { + if (this.document.getElementsByTagName(ci).length > 0) { + return true; + } + } + } + if (!domUtils.isEmptyBlock(this.body)) { + return true + } + //随时添加,定义的特殊标签如果存在,不能认为是空 + tags = ['div']; + for (i = 0; ci = tags[i++];) { + var nodes = domUtils.getElementsByTagName(this.document, ci); + for (var n = 0, cn; cn = nodes[n++];) { + if (domUtils.isCustomeNode(cn)) { + return true; + } + } + } + return false; + }, + + /** + * 重置编辑器,可用来做多个tab使用同一个编辑器实例 + * @method reset + * @remind 此方法会清空编辑器内容,清空回退列表,会触发reset事件 + * @example + * ```javascript + * editor.reset() + * ``` + */ + reset: function () { + this.fireEvent('reset'); + }, + + /** + * 设置当前编辑区域可以编辑 + * @method setEnabled + * @example + * ```javascript + * editor.setEnabled() + * ``` + */ + setEnabled: function () { + var me = this, range; + if (me.body.contentEditable == 'false') { + me.body.contentEditable = true; + range = me.selection.getRange(); + //有可能内容丢失了 + try { + range.moveToBookmark(me.lastBk); + delete me.lastBk + } catch (e) { + range.setStartAtFirst(me.body).collapse(true) + } + range.select(true); + if (me.bkqueryCommandState) { + me.queryCommandState = me.bkqueryCommandState; + delete me.bkqueryCommandState; + } + if (me.bkqueryCommandValue) { + me.queryCommandValue = me.bkqueryCommandValue; + delete me.bkqueryCommandValue; + } + me.fireEvent('selectionchange'); + } + }, + enable: function () { + return this.setEnabled(); + }, + + /** 设置当前编辑区域不可编辑 + * @method setDisabled + */ + + /** 设置当前编辑区域不可编辑,except中的命令除外 + * @method setDisabled + * @param { String } except 例外命令的字符串 + * @remind 即使设置了disable,此处配置的例外命令仍然可以执行 + * @example + * ```javascript + * editor.setDisabled('bold'); //禁用工具栏中除加粗之外的所有功能 + * ``` + */ + + /** 设置当前编辑区域不可编辑,except中的命令除外 + * @method setDisabled + * @param { Array } except 例外命令的字符串数组,数组中的命令仍然可以执行 + * @remind 即使设置了disable,此处配置的例外命令仍然可以执行 + * @example + * ```javascript + * editor.setDisabled(['bold','insertimage']); //禁用工具栏中除加粗和插入图片之外的所有功能 + * ``` + */ + setDisabled: function (except) { + var me = this; + except = except ? utils.isArray(except) ? except : [except] : []; + if (me.body.contentEditable == 'true') { + if (!me.lastBk) { + me.lastBk = me.selection.getRange().createBookmark(true); + } + me.body.contentEditable = false; + me.bkqueryCommandState = me.queryCommandState; + me.bkqueryCommandValue = me.queryCommandValue; + me.queryCommandState = function (type) { + if (utils.indexOf(except, type) != -1) { + return me.bkqueryCommandState.apply(me, arguments); + } + return -1; + }; + me.queryCommandValue = function (type) { + if (utils.indexOf(except, type) != -1) { + return me.bkqueryCommandValue.apply(me, arguments); + } + return null; + }; + me.fireEvent('selectionchange'); + } + }, + disable: function (except) { + return this.setDisabled(except); + }, + + /** + * 设置默认内容 + * @method _setDefaultContent + * @private + * @param { String } cont 要存入的内容 + */ + _setDefaultContent: function () { + function clear() { + var me = this; + if (me.document.getElementById('initContent')) { + me.body.innerHTML = '

          ' + (ie ? '' : '
          ') + '

          '; + me.removeListener('firstBeforeExecCommand focus', clear); + setTimeout(function () { + me.focus(); + me._selectionChange(); + }, 0) + } + } + + return function (cont) { + var me = this; + me.body.innerHTML = '

          ' + cont + '

          '; + + me.addListener('firstBeforeExecCommand focus', clear); + } + }(), + + /** + * 显示编辑器 + * @method setShow + * @example + * ```javascript + * editor.setShow() + * ``` + */ + setShow: function () { + var me = this, range = me.selection.getRange(); + if (me.container.style.display == 'none') { + //有可能内容丢失了 + try { + range.moveToBookmark(me.lastBk); + delete me.lastBk + } catch (e) { + range.setStartAtFirst(me.body).collapse(true) + } + //ie下focus实效,所以做了个延迟 + setTimeout(function () { + range.select(true); + }, 100); + me.container.style.display = ''; + } + + }, + show: function () { + return this.setShow(); + }, + /** + * 隐藏编辑器 + * @method setHide + * @example + * ```javascript + * editor.setHide() + * ``` + */ + setHide: function () { + var me = this; + if (!me.lastBk) { + me.lastBk = me.selection.getRange().createBookmark(true); + } + me.container.style.display = 'none' + }, + hide: function () { + return this.setHide(); + }, + + /** + * 根据指定的路径,获取对应的语言资源 + * @method getLang + * @param { String } path 路径根据的是lang目录下的语言文件的路径结构 + * @return { Object | String } 根据路径返回语言资源的Json格式对象或者语言字符串 + * @example + * ```javascript + * editor.getLang('contextMenu.delete'); //如果当前是中文,那返回是的是'删除' + * ``` + */ + getLang: function (path) { + var lang = UE.I18N[this.options.lang]; + if (!lang) { + throw Error("not import language file"); + } + path = (path || "").split("."); + for (var i = 0, ci; ci = path[i++];) { + lang = lang[ci]; + if (!lang)break; + } + return lang; + }, + + /** + * 计算编辑器html内容字符串的长度 + * @method getContentLength + * @return { Number } 返回计算的长度 + * @example + * ```javascript + * //编辑器html内容

          132

          + * editor.getContentLength() //返回27 + * ``` + */ + /** + * 计算编辑器当前纯文本内容的长度 + * @method getContentLength + * @param { Boolean } ingoneHtml 传入true时,只按照纯文本来计算 + * @return { Number } 返回计算的长度,内容中有hr/img/iframe标签,长度加1 + * @example + * ```javascript + * //编辑器html内容

          132

          + * editor.getContentLength() //返回3 + * ``` + */ + getContentLength: function (ingoneHtml, tagNames) { + var count = this.getContent(false,false,true).length; + if (ingoneHtml) { + tagNames = (tagNames || []).concat([ 'hr', 'img', 'iframe']); + count = this.getContentTxt().replace(/[\t\r\n]+/g, '').length; + for (var i = 0, ci; ci = tagNames[i++];) { + count += this.document.getElementsByTagName(ci).length; + } + } + return count; + }, + + /** + * 注册输入过滤规则 + * @method addInputRule + * @param { Function } rule 要添加的过滤规则 + * @example + * ```javascript + * editor.addInputRule(function(root){ + * $.each(root.getNodesByTagName('div'),function(i,node){ + * node.tagName="p"; + * }); + * }); + * ``` + */ + addInputRule: function (rule) { + this.inputRules.push(rule); + }, + + /** + * 执行注册的过滤规则 + * @method filterInputRule + * @param { UE.uNode } root 要过滤的uNode节点 + * @remind 执行editor.setContent方法和执行'inserthtml'命令后,会运行该过滤函数 + * @example + * ```javascript + * editor.filterInputRule(editor.body); + * ``` + * @see UE.Editor:addInputRule + */ + filterInputRule: function (root) { + for (var i = 0, ci; ci = this.inputRules[i++];) { + ci.call(this, root) + } + }, + + /** + * 注册输出过滤规则 + * @method addOutputRule + * @param { Function } rule 要添加的过滤规则 + * @example + * ```javascript + * editor.addOutputRule(function(root){ + * $.each(root.getNodesByTagName('p'),function(i,node){ + * node.tagName="div"; + * }); + * }); + * ``` + */ + addOutputRule: function (rule) { + this.outputRules.push(rule) + }, + + /** + * 根据输出过滤规则,过滤编辑器内容 + * @method filterOutputRule + * @remind 执行editor.getContent方法的时候,会先运行该过滤函数 + * @param { UE.uNode } root 要过滤的uNode节点 + * @example + * ```javascript + * editor.filterOutputRule(editor.body); + * ``` + * @see UE.Editor:addOutputRule + */ + filterOutputRule: function (root) { + for (var i = 0, ci; ci = this.outputRules[i++];) { + ci.call(this, root) + } + }, + + /** + * 根据action名称获取请求的路径 + * @method getActionUrl + * @remind 假如没有设置serverUrl,会根据imageUrl设置默认的controller路径 + * @param { String } action action名称 + * @example + * ```javascript + * editor.getActionUrl('config'); //返回 "/ueditor/php/controller.php?action=config" + * editor.getActionUrl('image'); //返回 "/ueditor/php/controller.php?action=uplaodimage" + * editor.getActionUrl('scrawl'); //返回 "/ueditor/php/controller.php?action=uplaodscrawl" + * editor.getActionUrl('imageManager'); //返回 "/ueditor/php/controller.php?action=listimage" + * ``` + */ + getActionUrl: function(action){ + var actionName = this.getOpt(action) || action, + imageUrl = this.getOpt('imageUrl'), + serverUrl = this.getOpt('serverUrl'); + + if(!serverUrl && imageUrl) { + serverUrl = imageUrl.replace(/^(.*[\/]).+([\.].+)$/, '$1controller$2'); + } + + if(serverUrl) { + serverUrl = serverUrl + (serverUrl.indexOf('?') == -1 ? '?':'&') + 'action=' + (actionName || ''); + return utils.formatUrl(serverUrl); + } else { + return ''; + } + } + }; + utils.inherits(Editor, EventBase); +})(); + + +// core/Editor.defaultoptions.js +//维护编辑器一下默认的不在插件中的配置项 +UE.Editor.defaultOptions = function(editor){ + + var _url = editor.options.UEDITOR_HOME_URL; + return { + isShow: true, + initialContent: '', + initialStyle:'', + autoClearinitialContent: false, + iframeCssUrl: _url + 'themes/iframe.css', + textarea: 'editorValue', + focus: false, + focusInEnd: true, + autoClearEmptyNode: true, + fullscreen: false, + readonly: false, + zIndex: 999, + imagePopup: true, + enterTag: 'p', + customDomain: false, + lang: 'zh-cn', + langPath: _url + 'lang/', + theme: 'default', + themePath: _url + 'themes/', + allHtmlEnabled: false, + scaleEnabled: false, + tableNativeEditInFF: false, + autoSyncData : true, + fileNameFormat: '{time}{rand:6}' + } +}; + +// core/loadconfig.js +(function(){ + + UE.Editor.prototype.loadServerConfig = function(){ + var me = this; + setTimeout(function(){ + try{ + me.options.imageUrl && me.setOpt('serverUrl', me.options.imageUrl.replace(/^(.*[\/]).+([\.].+)$/, '$1controller$2')); + + var configUrl = me.getActionUrl('config'), + isJsonp = utils.isCrossDomainUrl(configUrl); + + /* 发出ajax请求 */ + me._serverConfigLoaded = false; + + configUrl && UE.ajax.request(configUrl,{ + 'method': 'GET', + 'dataType': isJsonp ? 'jsonp':'', + 'onsuccess':function(r){ + try { + var config = isJsonp ? r:eval("("+r.responseText+")"); + utils.extend(me.options, config); + me.fireEvent('serverConfigLoaded'); + me._serverConfigLoaded = true; + } catch (e) { + showErrorMsg(me.getLang('loadconfigFormatError')); + } + }, + 'onerror':function(){ + showErrorMsg(me.getLang('loadconfigHttpError')); + } + }); + } catch(e){ + showErrorMsg(me.getLang('loadconfigError')); + } + }); + + function showErrorMsg(msg) { + console && console.error(msg); + //me.fireEvent('showMessage', { + // 'title': msg, + // 'type': 'error' + //}); + } + }; + + UE.Editor.prototype.isServerConfigLoaded = function(){ + var me = this; + return me._serverConfigLoaded || false; + }; + + UE.Editor.prototype.afterConfigReady = function(handler){ + if (!handler || !utils.isFunction(handler)) return; + var me = this; + var readyHandler = function(){ + handler.apply(me, arguments); + me.removeListener('serverConfigLoaded', readyHandler); + }; + + if (me.isServerConfigLoaded()) { + handler.call(me, 'serverConfigLoaded'); + } else { + me.addListener('serverConfigLoaded', readyHandler); + } + }; + +})(); + + +// core/ajax.js +/** + * @file + * @module UE.ajax + * @since 1.2.6.1 + */ + +/** + * 提供对ajax请求的支持 + * @module UE.ajax + */ +UE.ajax = function() { + + //创建一个ajaxRequest对象 + var fnStr = 'XMLHttpRequest()'; + try { + new ActiveXObject("Msxml2.XMLHTTP"); + fnStr = 'ActiveXObject(\'Msxml2.XMLHTTP\')'; + } catch (e) { + try { + new ActiveXObject("Microsoft.XMLHTTP"); + fnStr = 'ActiveXObject(\'Microsoft.XMLHTTP\')' + } catch (e) { + } + } + var creatAjaxRequest = new Function('return new ' + fnStr); + + + /** + * 将json参数转化成适合ajax提交的参数列表 + * @param json + */ + function json2str(json) { + var strArr = []; + for (var i in json) { + //忽略默认的几个参数 + if(i=="method" || i=="timeout" || i=="async" || i=="dataType" || i=="callback") continue; + //忽略控制 + if(json[i] == undefined || json[i] == null) continue; + //传递过来的对象和函数不在提交之列 + if (!((typeof json[i]).toLowerCase() == "function" || (typeof json[i]).toLowerCase() == "object")) { + strArr.push( encodeURIComponent(i) + "="+encodeURIComponent(json[i]) ); + } else if (utils.isArray(json[i])) { + //支持传数组内容 + for(var j = 0; j < json[i].length; j++) { + strArr.push( encodeURIComponent(i) + "[]="+encodeURIComponent(json[i][j]) ); + } + } + } + return strArr.join("&"); + } + + function doAjax(url, ajaxOptions) { + var xhr = creatAjaxRequest(), + //是否超时 + timeIsOut = false, + //默认参数 + defaultAjaxOptions = { + method:"POST", + timeout:5000, + async:true, + data:{},//需要传递对象的话只能覆盖 + onsuccess:function() { + }, + onerror:function() { + } + }; + + if (typeof url === "object") { + ajaxOptions = url; + url = ajaxOptions.url; + } + if (!xhr || !url) return; + var ajaxOpts = ajaxOptions ? utils.extend(defaultAjaxOptions,ajaxOptions) : defaultAjaxOptions; + + var submitStr = json2str(ajaxOpts); // { name:"Jim",city:"Beijing" } --> "name=Jim&city=Beijing" + //如果用户直接通过data参数传递json对象过来,则也要将此json对象转化为字符串 + if (!utils.isEmptyObject(ajaxOpts.data)){ + submitStr += (submitStr? "&":"") + json2str(ajaxOpts.data); + } + //超时检测 + var timerID = setTimeout(function() { + if (xhr.readyState != 4) { + timeIsOut = true; + xhr.abort(); + clearTimeout(timerID); + } + }, ajaxOpts.timeout); + + var method = ajaxOpts.method.toUpperCase(); + var str = url + (url.indexOf("?")==-1?"?":"&") + (method=="POST"?"":submitStr+ "&noCache=" + +new Date); + xhr.open(method, str, ajaxOpts.async); + xhr.onreadystatechange = function() { + if (xhr.readyState == 4) { + if (!timeIsOut && xhr.status == 200) { + ajaxOpts.onsuccess(xhr); + } else { + ajaxOpts.onerror(xhr); + } + } + }; + if (method == "POST") { + xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); + xhr.send(submitStr); + } else { + xhr.send(null); + } + } + + function doJsonp(url, opts) { + + var successhandler = opts.onsuccess || function(){}, + scr = document.createElement('SCRIPT'), + options = opts || {}, + charset = options['charset'], + callbackField = options['jsonp'] || 'callback', + callbackFnName, + timeOut = options['timeOut'] || 0, + timer, + reg = new RegExp('(\\?|&)' + callbackField + '=([^&]*)'), + matches; + + if (utils.isFunction(successhandler)) { + callbackFnName = 'bd__editor__' + Math.floor(Math.random() * 2147483648).toString(36); + window[callbackFnName] = getCallBack(0); + } else if(utils.isString(successhandler)){ + callbackFnName = successhandler; + } else { + if (matches = reg.exec(url)) { + callbackFnName = matches[2]; + } + } + + url = url.replace(reg, '\x241' + callbackField + '=' + callbackFnName); + + if (url.search(reg) < 0) { + url += (url.indexOf('?') < 0 ? '?' : '&') + callbackField + '=' + callbackFnName; + } + + var queryStr = json2str(opts); // { name:"Jim",city:"Beijing" } --> "name=Jim&city=Beijing" + //如果用户直接通过data参数传递json对象过来,则也要将此json对象转化为字符串 + if (!utils.isEmptyObject(opts.data)){ + queryStr += (queryStr? "&":"") + json2str(opts.data); + } + if (queryStr) { + url = url.replace(/\?/, '?' + queryStr + '&'); + } + + scr.onerror = getCallBack(1); + if( timeOut ){ + timer = setTimeout(getCallBack(1), timeOut); + } + createScriptTag(scr, url, charset); + + function createScriptTag(scr, url, charset) { + scr.setAttribute('type', 'text/javascript'); + scr.setAttribute('defer', 'defer'); + charset && scr.setAttribute('charset', charset); + scr.setAttribute('src', url); + document.getElementsByTagName('head')[0].appendChild(scr); + } + + function getCallBack(onTimeOut){ + return function(){ + try { + if(onTimeOut){ + options.onerror && options.onerror(); + }else{ + try{ + clearTimeout(timer); + successhandler.apply(window, arguments); + } catch (e){} + } + } catch (exception) { + options.onerror && options.onerror.call(window, exception); + } finally { + options.oncomplete && options.oncomplete.apply(window, arguments); + scr.parentNode && scr.parentNode.removeChild(scr); + window[callbackFnName] = null; + try { + delete window[callbackFnName]; + }catch(e){} + } + } + } + } + + return { + /** + * 根据给定的参数项,向指定的url发起一个ajax请求。 ajax请求完成后,会根据请求结果调用相应回调: 如果请求 + * 成功, 则调用onsuccess回调, 失败则调用 onerror 回调 + * @method request + * @param { URLString } url ajax请求的url地址 + * @param { Object } ajaxOptions ajax请求选项的键值对,支持的选项如下: + * @example + * ```javascript + * //向sayhello.php发起一个异步的Ajax GET请求, 请求超时时间为10s, 请求完成后执行相应的回调。 + * UE.ajax.requeset( 'sayhello.php', { + * + * //请求方法。可选值: 'GET', 'POST',默认值是'POST' + * method: 'GET', + * + * //超时时间。 默认为5000, 单位是ms + * timeout: 10000, + * + * //是否是异步请求。 true为异步请求, false为同步请求 + * async: true, + * + * //请求携带的数据。如果请求为GET请求, data会经过stringify后附加到请求url之后。 + * data: { + * name: 'ueditor' + * }, + * + * //请求成功后的回调, 该回调接受当前的XMLHttpRequest对象作为参数。 + * onsuccess: function ( xhr ) { + * console.log( xhr.responseText ); + * }, + * + * //请求失败或者超时后的回调。 + * onerror: function ( xhr ) { + * alert( 'Ajax请求失败' ); + * } + * + * } ); + * ``` + */ + + /** + * 根据给定的参数项发起一个ajax请求, 参数项里必须包含一个url地址。 ajax请求完成后,会根据请求结果调用相应回调: 如果请求 + * 成功, 则调用onsuccess回调, 失败则调用 onerror 回调。 + * @method request + * @warning 如果在参数项里未提供一个key为“url”的地址值,则该请求将直接退出。 + * @param { Object } ajaxOptions ajax请求选项的键值对,支持的选项如下: + * @example + * ```javascript + * + * //向sayhello.php发起一个异步的Ajax POST请求, 请求超时时间为5s, 请求完成后不执行任何回调。 + * UE.ajax.requeset( 'sayhello.php', { + * + * //请求的地址, 该项是必须的。 + * url: 'sayhello.php' + * + * } ); + * ``` + */ + request:function(url, opts) { + if (opts && opts.dataType == 'jsonp') { + doJsonp(url, opts); + } else { + doAjax(url, opts); + } + }, + getJSONP:function(url, data, fn) { + var opts = { + 'data': data, + 'oncomplete': fn + }; + doJsonp(url, opts); + } + }; + + +}(); + + +// core/filterword.js +/** + * UE过滤word的静态方法 + * @file + */ + +/** + * UEditor公用空间,UEditor所有的功能都挂载在该空间下 + * @module UE + */ + + +/** + * 根据传入html字符串过滤word + * @module UE + * @since 1.2.6.1 + * @method filterWord + * @param { String } html html字符串 + * @return { String } 已过滤后的结果字符串 + * @example + * ```javascript + * UE.filterWord(html); + * ``` + */ +var filterWord = UE.filterWord = function () { + + //是否是word过来的内容 + function isWordDocument( str ) { + return /(class="?Mso|style="[^"]*\bmso\-|w:WordDocument|<(v|o):|lang=)/ig.test( str ); + } + //去掉小数 + function transUnit( v ) { + v = v.replace( /[\d.]+\w+/g, function ( m ) { + return utils.transUnitToPx(m); + } ); + return v; + } + + function filterPasteWord( str ) { + return str.replace(/[\t\r\n]+/g,' ') + .replace( //ig, "" ) + //转换图片 + .replace(/]*>[\s\S]*?.<\/v:shape>/gi,function(str){ + //opera能自己解析出image所这里直接返回空 + if(browser.opera){ + return ''; + } + try{ + //有可能是bitmap占为图,无用,直接过滤掉,主要体现在粘贴excel表格中 + if(/Bitmap/i.test(str)){ + return ''; + } + var width = str.match(/width:([ \d.]*p[tx])/i)[1], + height = str.match(/height:([ \d.]*p[tx])/i)[1], + src = str.match(/src=\s*"([^"]*)"/i)[1]; + return ''; + } catch(e){ + return ''; + } + }) + //针对wps添加的多余标签处理 + .replace(/<\/?div[^>]*>/g,'') + //去掉多余的属性 + .replace( /v:\w+=(["']?)[^'"]+\1/g, '' ) + .replace( /<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|xml|meta|link|style|\w+:\w+)(?=[\s\/>]))[^>]*>/gi, "" ) + .replace( /

          ]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi, "

          $1

          " ) + //去掉多余的属性 + .replace( /\s+(class|lang|align)\s*=\s*(['"]?)([\w-]+)\2/ig, function(str,name,marks,val){ + //保留list的标示 + return name == 'class' && val == 'MsoListParagraph' ? str : '' + }) + //清除多余的font/span不能匹配 有可能是空格 + .replace( /<(font|span)[^>]*>(\s*)<\/\1>/gi, function(a,b,c){ + return c.replace(/[\t\r\n ]+/g,' ') + }) + //处理style的问题 + .replace( /(<[a-z][^>]*)\sstyle=(["'])([^\2]*?)\2/gi, function( str, tag, tmp, style ) { + var n = [], + s = style.replace( /^\s+|\s+$/, '' ) + .replace(/'/g,'\'') + .replace( /"/gi, "'" ) + .replace(/[\d.]+(cm|pt)/g,function(str){ + return utils.transUnitToPx(str) + }) + .split( /;\s*/g ); + + for ( var i = 0,v; v = s[i];i++ ) { + + var name, value, + parts = v.split( ":" ); + + if ( parts.length == 2 ) { + name = parts[0].toLowerCase(); + value = parts[1].toLowerCase(); + if(/^(background)\w*/.test(name) && value.replace(/(initial|\s)/g,'').length == 0 + || + /^(margin)\w*/.test(name) && /^0\w+$/.test(value) + ){ + continue; + } + + switch ( name ) { + case "mso-padding-alt": + case "mso-padding-top-alt": + case "mso-padding-right-alt": + case "mso-padding-bottom-alt": + case "mso-padding-left-alt": + case "mso-margin-alt": + case "mso-margin-top-alt": + case "mso-margin-right-alt": + case "mso-margin-bottom-alt": + case "mso-margin-left-alt": + //ie下会出现挤到一起的情况 + //case "mso-table-layout-alt": + case "mso-height": + case "mso-width": + case "mso-vertical-align-alt": + //trace:1819 ff下会解析出padding在table上 + if(!/]/.test(html)) { + return UE.htmlparser(html).children[0] + } else { + return new uNode({ + type:'element', + children:[], + tagName:html + }) + } + }; + uNode.createText = function (data,noTrans) { + return new UE.uNode({ + type:'text', + 'data':noTrans ? data : utils.unhtml(data || '') + }) + }; + function nodeToHtml(node, arr, formatter, current) { + switch (node.type) { + case 'root': + for (var i = 0, ci; ci = node.children[i++];) { + //插入新行 + if (formatter && ci.type == 'element' && !dtd.$inlineWithA[ci.tagName] && i > 1) { + insertLine(arr, current, true); + insertIndent(arr, current) + } + nodeToHtml(ci, arr, formatter, current) + } + break; + case 'text': + isText(node, arr); + break; + case 'element': + isElement(node, arr, formatter, current); + break; + case 'comment': + isComment(node, arr, formatter); + } + return arr; + } + + function isText(node, arr) { + if(node.parentNode.tagName == 'pre'){ + //源码模式下输入html标签,不能做转换处理,直接输出 + arr.push(node.data) + }else{ + arr.push(notTransTagName[node.parentNode.tagName] ? utils.html(node.data) : node.data.replace(/[ ]{2}/g,'  ')) + } + + } + + function isElement(node, arr, formatter, current) { + var attrhtml = ''; + if (node.attrs) { + attrhtml = []; + var attrs = node.attrs; + for (var a in attrs) { + //这里就针对 + //

          '

          + //这里边的\"做转换,要不用innerHTML直接被截断了,属性src + //有可能做的不够 + attrhtml.push(a + (attrs[a] !== undefined ? '="' + (notTransAttrs[a] ? utils.html(attrs[a]).replace(/["]/g, function (a) { + return '"' + }) : utils.unhtml(attrs[a])) + '"' : '')) + } + attrhtml = attrhtml.join(' '); + } + arr.push('<' + node.tagName + + (attrhtml ? ' ' + attrhtml : '') + + (dtd.$empty[node.tagName] ? '\/' : '' ) + '>' + ); + //插入新行 + if (formatter && !dtd.$inlineWithA[node.tagName] && node.tagName != 'pre') { + if(node.children && node.children.length){ + current = insertLine(arr, current, true); + insertIndent(arr, current) + } + + } + if (node.children && node.children.length) { + for (var i = 0, ci; ci = node.children[i++];) { + if (formatter && ci.type == 'element' && !dtd.$inlineWithA[ci.tagName] && i > 1) { + insertLine(arr, current); + insertIndent(arr, current) + } + nodeToHtml(ci, arr, formatter, current) + } + } + if (!dtd.$empty[node.tagName]) { + if (formatter && !dtd.$inlineWithA[node.tagName] && node.tagName != 'pre') { + + if(node.children && node.children.length){ + current = insertLine(arr, current); + insertIndent(arr, current) + } + } + arr.push('<\/' + node.tagName + '>'); + } + + } + + function isComment(node, arr) { + arr.push(''); + } + + function getNodeById(root, id) { + var node; + if (root.type == 'element' && root.getAttr('id') == id) { + return root; + } + if (root.children && root.children.length) { + for (var i = 0, ci; ci = root.children[i++];) { + if (node = getNodeById(ci, id)) { + return node; + } + } + } + } + + function getNodesByTagName(node, tagName, arr) { + if (node.type == 'element' && node.tagName == tagName) { + arr.push(node); + } + if (node.children && node.children.length) { + for (var i = 0, ci; ci = node.children[i++];) { + getNodesByTagName(ci, tagName, arr) + } + } + } + function nodeTraversal(root,fn){ + if(root.children && root.children.length){ + for(var i= 0,ci;ci=root.children[i];){ + nodeTraversal(ci,fn); + //ci被替换的情况,这里就不再走 fn了 + if(ci.parentNode ){ + if(ci.children && ci.children.length){ + fn(ci) + } + if(ci.parentNode) i++ + } + } + }else{ + fn(root) + } + + } + uNode.prototype = { + + /** + * 当前节点对象,转换成html文本 + * @method toHtml + * @return { String } 返回转换后的html字符串 + * @example + * ```javascript + * node.toHtml(); + * ``` + */ + + /** + * 当前节点对象,转换成html文本 + * @method toHtml + * @param { Boolean } formatter 是否格式化返回值 + * @return { String } 返回转换后的html字符串 + * @example + * ```javascript + * node.toHtml( true ); + * ``` + */ + toHtml:function (formatter) { + var arr = []; + nodeToHtml(this, arr, formatter, 0); + return arr.join('') + }, + + /** + * 获取节点的html内容 + * @method innerHTML + * @warning 假如节点的type不是'element',或节点的标签名称不在dtd列表里,直接返回当前节点 + * @return { String } 返回节点的html内容 + * @example + * ```javascript + * var htmlstr = node.innerHTML(); + * ``` + */ + + /** + * 设置节点的html内容 + * @method innerHTML + * @warning 假如节点的type不是'element',或节点的标签名称不在dtd列表里,直接返回当前节点 + * @param { String } htmlstr 传入要设置的html内容 + * @return { UE.uNode } 返回节点本身 + * @example + * ```javascript + * node.innerHTML('text'); + * ``` + */ + innerHTML:function (htmlstr) { + if (this.type != 'element' || dtd.$empty[this.tagName]) { + return this; + } + if (utils.isString(htmlstr)) { + if(this.children){ + for (var i = 0, ci; ci = this.children[i++];) { + ci.parentNode = null; + } + } + this.children = []; + var tmpRoot = UE.htmlparser(htmlstr); + for (var i = 0, ci; ci = tmpRoot.children[i++];) { + this.children.push(ci); + ci.parentNode = this; + } + return this; + } else { + var tmpRoot = new UE.uNode({ + type:'root', + children:this.children + }); + return tmpRoot.toHtml(); + } + }, + + /** + * 获取节点的纯文本内容 + * @method innerText + * @warning 假如节点的type不是'element',或节点的标签名称不在dtd列表里,直接返回当前节点 + * @return { String } 返回节点的存文本内容 + * @example + * ```javascript + * var textStr = node.innerText(); + * ``` + */ + + /** + * 设置节点的纯文本内容 + * @method innerText + * @warning 假如节点的type不是'element',或节点的标签名称不在dtd列表里,直接返回当前节点 + * @param { String } textStr 传入要设置的文本内容 + * @return { UE.uNode } 返回节点本身 + * @example + * ```javascript + * node.innerText('text'); + * ``` + */ + innerText:function (textStr,noTrans) { + if (this.type != 'element' || dtd.$empty[this.tagName]) { + return this; + } + if (textStr) { + if(this.children){ + for (var i = 0, ci; ci = this.children[i++];) { + ci.parentNode = null; + } + } + this.children = []; + this.appendChild(uNode.createText(textStr,noTrans)); + return this; + } else { + return this.toHtml().replace(/<[^>]+>/g, ''); + } + }, + + /** + * 获取当前对象的data属性 + * @method getData + * @return { Object } 若节点的type值是elemenet,返回空字符串,否则返回节点的data属性 + * @example + * ```javascript + * node.getData(); + * ``` + */ + getData:function () { + if (this.type == 'element') + return ''; + return this.data + }, + + /** + * 获取当前节点下的第一个子节点 + * @method firstChild + * @return { UE.uNode } 返回第一个子节点 + * @example + * ```javascript + * node.firstChild(); //返回第一个子节点 + * ``` + */ + firstChild:function () { +// if (this.type != 'element' || dtd.$empty[this.tagName]) { +// return this; +// } + return this.children ? this.children[0] : null; + }, + + /** + * 获取当前节点下的最后一个子节点 + * @method lastChild + * @return { UE.uNode } 返回最后一个子节点 + * @example + * ```javascript + * node.lastChild(); //返回最后一个子节点 + * ``` + */ + lastChild:function () { +// if (this.type != 'element' || dtd.$empty[this.tagName] ) { +// return this; +// } + return this.children ? this.children[this.children.length - 1] : null; + }, + + /** + * 获取和当前节点有相同父亲节点的前一个节点 + * @method previousSibling + * @return { UE.uNode } 返回前一个节点 + * @example + * ```javascript + * node.children[2].previousSibling(); //返回子节点node.children[1] + * ``` + */ + previousSibling : function(){ + var parent = this.parentNode; + for (var i = 0, ci; ci = parent.children[i]; i++) { + if (ci === this) { + return i == 0 ? null : parent.children[i-1]; + } + } + + }, + + /** + * 获取和当前节点有相同父亲节点的后一个节点 + * @method nextSibling + * @return { UE.uNode } 返回后一个节点,找不到返回null + * @example + * ```javascript + * node.children[2].nextSibling(); //如果有,返回子节点node.children[3] + * ``` + */ + nextSibling : function(){ + var parent = this.parentNode; + for (var i = 0, ci; ci = parent.children[i++];) { + if (ci === this) { + return parent.children[i]; + } + } + }, + + /** + * 用新的节点替换当前节点 + * @method replaceChild + * @param { UE.uNode } target 要替换成该节点参数 + * @param { UE.uNode } source 要被替换掉的节点 + * @return { UE.uNode } 返回替换之后的节点对象 + * @example + * ```javascript + * node.replaceChild(newNode, childNode); //用newNode替换childNode,childNode是node的子节点 + * ``` + */ + replaceChild:function (target, source) { + if (this.children) { + if(target.parentNode){ + target.parentNode.removeChild(target); + } + for (var i = 0, ci; ci = this.children[i]; i++) { + if (ci === source) { + this.children.splice(i, 1, target); + source.parentNode = null; + target.parentNode = this; + return target; + } + } + } + }, + + /** + * 在节点的子节点列表最后位置插入一个节点 + * @method appendChild + * @param { UE.uNode } node 要插入的节点 + * @return { UE.uNode } 返回刚插入的子节点 + * @example + * ```javascript + * node.appendChild( newNode ); //在node内插入子节点newNode + * ``` + */ + appendChild:function (node) { + if (this.type == 'root' || (this.type == 'element' && !dtd.$empty[this.tagName])) { + if (!this.children) { + this.children = [] + } + if(node.parentNode){ + node.parentNode.removeChild(node); + } + for (var i = 0, ci; ci = this.children[i]; i++) { + if (ci === node) { + this.children.splice(i, 1); + break; + } + } + this.children.push(node); + node.parentNode = this; + return node; + } + + + }, + + /** + * 在传入节点的前面插入一个节点 + * @method insertBefore + * @param { UE.uNode } target 要插入的节点 + * @param { UE.uNode } source 在该参数节点前面插入 + * @return { UE.uNode } 返回刚插入的子节点 + * @example + * ```javascript + * node.parentNode.insertBefore(newNode, node); //在node节点后面插入newNode + * ``` + */ + insertBefore:function (target, source) { + if (this.children) { + if(target.parentNode){ + target.parentNode.removeChild(target); + } + for (var i = 0, ci; ci = this.children[i]; i++) { + if (ci === source) { + this.children.splice(i, 0, target); + target.parentNode = this; + return target; + } + } + + } + }, + + /** + * 在传入节点的后面插入一个节点 + * @method insertAfter + * @param { UE.uNode } target 要插入的节点 + * @param { UE.uNode } source 在该参数节点后面插入 + * @return { UE.uNode } 返回刚插入的子节点 + * @example + * ```javascript + * node.parentNode.insertAfter(newNode, node); //在node节点后面插入newNode + * ``` + */ + insertAfter:function (target, source) { + if (this.children) { + if(target.parentNode){ + target.parentNode.removeChild(target); + } + for (var i = 0, ci; ci = this.children[i]; i++) { + if (ci === source) { + this.children.splice(i + 1, 0, target); + target.parentNode = this; + return target; + } + + } + } + }, + + /** + * 从当前节点的子节点列表中,移除节点 + * @method removeChild + * @param { UE.uNode } node 要移除的节点引用 + * @param { Boolean } keepChildren 是否保留移除节点的子节点,若传入true,自动把移除节点的子节点插入到移除的位置 + * @return { * } 返回刚移除的子节点 + * @example + * ```javascript + * node.removeChild(childNode,true); //在node的子节点列表中移除child节点,并且吧child的子节点插入到移除的位置 + * ``` + */ + removeChild:function (node,keepChildren) { + if (this.children) { + for (var i = 0, ci; ci = this.children[i]; i++) { + if (ci === node) { + this.children.splice(i, 1); + ci.parentNode = null; + if(keepChildren && ci.children && ci.children.length){ + for(var j= 0,cj;cj=ci.children[j];j++){ + this.children.splice(i+j,0,cj); + cj.parentNode = this; + + } + } + return ci; + } + } + } + }, + + /** + * 获取当前节点所代表的元素属性,即获取attrs对象下的属性值 + * @method getAttr + * @param { String } attrName 要获取的属性名称 + * @return { * } 返回attrs对象下的属性值 + * @example + * ```javascript + * node.getAttr('title'); + * ``` + */ + getAttr:function (attrName) { + return this.attrs && this.attrs[attrName.toLowerCase()] + }, + + /** + * 设置当前节点所代表的元素属性,即设置attrs对象下的属性值 + * @method setAttr + * @param { String } attrName 要设置的属性名称 + * @param { * } attrVal 要设置的属性值,类型视设置的属性而定 + * @return { * } 返回attrs对象下的属性值 + * @example + * ```javascript + * node.setAttr('title','标题'); + * ``` + */ + setAttr:function (attrName, attrVal) { + if (!attrName) { + delete this.attrs; + return; + } + if(!this.attrs){ + this.attrs = {}; + } + if (utils.isObject(attrName)) { + for (var a in attrName) { + if (!attrName[a]) { + delete this.attrs[a] + } else { + this.attrs[a.toLowerCase()] = attrName[a]; + } + } + } else { + if (!attrVal) { + delete this.attrs[attrName] + } else { + this.attrs[attrName.toLowerCase()] = attrVal; + } + + } + }, + + /** + * 获取当前节点在父节点下的位置索引 + * @method getIndex + * @return { Number } 返回索引数值,如果没有父节点,返回-1 + * @example + * ```javascript + * node.getIndex(); + * ``` + */ + getIndex:function(){ + var parent = this.parentNode; + for(var i= 0,ci;ci=parent.children[i];i++){ + if(ci === this){ + return i; + } + } + return -1; + }, + + /** + * 在当前节点下,根据id查找节点 + * @method getNodeById + * @param { String } id 要查找的id + * @return { UE.uNode } 返回找到的节点 + * @example + * ```javascript + * node.getNodeById('textId'); + * ``` + */ + getNodeById:function (id) { + var node; + if (this.children && this.children.length) { + for (var i = 0, ci; ci = this.children[i++];) { + if (node = getNodeById(ci, id)) { + return node; + } + } + } + }, + + /** + * 在当前节点下,根据元素名称查找节点列表 + * @method getNodesByTagName + * @param { String } tagNames 要查找的元素名称 + * @return { Array } 返回找到的节点列表 + * @example + * ```javascript + * node.getNodesByTagName('span'); + * ``` + */ + getNodesByTagName:function (tagNames) { + tagNames = utils.trim(tagNames).replace(/[ ]{2,}/g, ' ').split(' '); + var arr = [], me = this; + utils.each(tagNames, function (tagName) { + if (me.children && me.children.length) { + for (var i = 0, ci; ci = me.children[i++];) { + getNodesByTagName(ci, tagName, arr) + } + } + }); + return arr; + }, + + /** + * 根据样式名称,获取节点的样式值 + * @method getStyle + * @param { String } name 要获取的样式名称 + * @return { String } 返回样式值 + * @example + * ```javascript + * node.getStyle('font-size'); + * ``` + */ + getStyle:function (name) { + var cssStyle = this.getAttr('style'); + if (!cssStyle) { + return '' + } + var reg = new RegExp('(^|;)\\s*' + name + ':([^;]+)','i'); + var match = cssStyle.match(reg); + if (match && match[0]) { + return match[2] + } + return ''; + }, + + /** + * 给节点设置样式 + * @method setStyle + * @param { String } name 要设置的的样式名称 + * @param { String } val 要设置的的样值 + * @example + * ```javascript + * node.setStyle('font-size', '12px'); + * ``` + */ + setStyle:function (name, val) { + function exec(name, val) { + var reg = new RegExp('(^|;)\\s*' + name + ':([^;]+;?)', 'gi'); + cssStyle = cssStyle.replace(reg, '$1'); + if (val) { + cssStyle = name + ':' + utils.unhtml(val) + ';' + cssStyle + } + + } + + var cssStyle = this.getAttr('style'); + if (!cssStyle) { + cssStyle = ''; + } + if (utils.isObject(name)) { + for (var a in name) { + exec(a, name[a]) + } + } else { + exec(name, val) + } + this.setAttr('style', utils.trim(cssStyle)) + }, + + /** + * 传入一个函数,递归遍历当前节点下的所有节点 + * @method traversal + * @param { Function } fn 遍历到节点的时,传入节点作为参数,运行此函数 + * @example + * ```javascript + * traversal(node, function(){ + * console.log(node.type); + * }); + * ``` + */ + traversal:function(fn){ + if(this.children && this.children.length){ + nodeTraversal(this,fn); + } + return this; + } + } +})(); + + +// core/htmlparser.js +/** + * html字符串转换成uNode节点 + * @file + * @module UE + * @since 1.2.6.1 + */ + +/** + * UEditor公用空间,UEditor所有的功能都挂载在该空间下 + * @unfile + * @module UE + */ + +/** + * html字符串转换成uNode节点的静态方法 + * @method htmlparser + * @param { String } htmlstr 要转换的html代码 + * @param { Boolean } ignoreBlank 若设置为true,转换的时候忽略\n\r\t等空白字符 + * @return { uNode } 给定的html片段转换形成的uNode对象 + * @example + * ```javascript + * var root = UE.htmlparser('

          htmlparser

          ', true); + * ``` + */ + +var htmlparser = UE.htmlparser = function (htmlstr,ignoreBlank) { + //todo 原来的方式 [^"'<>\/] 有\/就不能配对上 ') + } + html.push('') + } + //禁止指定table-width + return '
          这样的标签了 + //先去掉了,加上的原因忘了,这里先记录 + var re_tag = /<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\s\/<>]+)\s*((?:(?:"[^"]*")|(?:'[^']*')|[^"'<>])*)\/?>))/g, + re_attr = /([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g; + + //ie下取得的html可能会有\n存在,要去掉,在处理replace(/[\t\r\n]*/g,'');代码高量的\n不能去除 + var allowEmptyTags = { + b:1,code:1,i:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,span:1, + sub:1,img:1,sup:1,font:1,big:1,small:1,iframe:1,a:1,br:1,pre:1 + }; + htmlstr = htmlstr.replace(new RegExp(domUtils.fillChar, 'g'), ''); + if(!ignoreBlank){ + htmlstr = htmlstr.replace(new RegExp('[\\r\\t\\n'+(ignoreBlank?'':' ')+']*<\/?(\\w+)\\s*(?:[^>]*)>[\\r\\t\\n'+(ignoreBlank?'':' ')+']*','g'), function(a,b){ + //br暂时单独处理 + if(b && allowEmptyTags[b.toLowerCase()]){ + return a.replace(/(^[\n\r]+)|([\n\r]+$)/g,''); + } + return a.replace(new RegExp('^[\\r\\n'+(ignoreBlank?'':' ')+']+'),'').replace(new RegExp('[\\r\\n'+(ignoreBlank?'':' ')+']+$'),''); + }); + } + + var notTransAttrs = { + 'href':1, + 'src':1 + }; + + var uNode = UE.uNode, + needParentNode = { + 'td':'tr', + 'tr':['tbody','thead','tfoot'], + 'tbody':'table', + 'th':'tr', + 'thead':'table', + 'tfoot':'table', + 'caption':'table', + 'li':['ul', 'ol'], + 'dt':'dl', + 'dd':'dl', + 'option':'select' + }, + needChild = { + 'ol':'li', + 'ul':'li' + }; + + function text(parent, data) { + + if(needChild[parent.tagName]){ + var tmpNode = uNode.createElement(needChild[parent.tagName]); + parent.appendChild(tmpNode); + tmpNode.appendChild(uNode.createText(data)); + parent = tmpNode; + }else{ + + parent.appendChild(uNode.createText(data)); + } + } + + function element(parent, tagName, htmlattr) { + var needParentTag; + if (needParentTag = needParentNode[tagName]) { + var tmpParent = parent,hasParent; + while(tmpParent.type != 'root'){ + if(utils.isArray(needParentTag) ? utils.indexOf(needParentTag, tmpParent.tagName) != -1 : needParentTag == tmpParent.tagName){ + parent = tmpParent; + hasParent = true; + break; + } + tmpParent = tmpParent.parentNode; + } + if(!hasParent){ + parent = element(parent, utils.isArray(needParentTag) ? needParentTag[0] : needParentTag) + } + } + //按dtd处理嵌套 +// if(parent.type != 'root' && !dtd[parent.tagName][tagName]) +// parent = parent.parentNode; + var elm = new uNode({ + parentNode:parent, + type:'element', + tagName:tagName.toLowerCase(), + //是自闭合的处理一下 + children:dtd.$empty[tagName] ? null : [] + }); + //如果属性存在,处理属性 + if (htmlattr) { + var attrs = {}, match; + while (match = re_attr.exec(htmlattr)) { + attrs[match[1].toLowerCase()] = notTransAttrs[match[1].toLowerCase()] ? (match[2] || match[3] || match[4]) : utils.unhtml(match[2] || match[3] || match[4]) + } + elm.attrs = attrs; + } + //trace:3970 +// //如果parent下不能放elm +// if(dtd.$inline[parent.tagName] && dtd.$block[elm.tagName] && !dtd[parent.tagName][elm.tagName]){ +// parent = parent.parentNode; +// elm.parentNode = parent; +// } + parent.children.push(elm); + //如果是自闭合节点返回父亲节点 + return dtd.$empty[tagName] ? parent : elm + } + + function comment(parent, data) { + parent.children.push(new uNode({ + type:'comment', + data:data, + parentNode:parent + })); + } + + var match, currentIndex = 0, nextIndex = 0; + //设置根节点 + var root = new uNode({ + type:'root', + children:[] + }); + var currentParent = root; + + while (match = re_tag.exec(htmlstr)) { + currentIndex = match.index; + try{ + if (currentIndex > nextIndex) { + //text node + text(currentParent, htmlstr.slice(nextIndex, currentIndex)); + } + if (match[3]) { + + if(dtd.$cdata[currentParent.tagName]){ + text(currentParent, match[0]); + }else{ + //start tag + currentParent = element(currentParent, match[3].toLowerCase(), match[4]); + } + + + } else if (match[1]) { + if(currentParent.type != 'root'){ + if(dtd.$cdata[currentParent.tagName] && !dtd.$cdata[match[1]]){ + text(currentParent, match[0]); + }else{ + var tmpParent = currentParent; + while(currentParent.type == 'element' && currentParent.tagName != match[1].toLowerCase()){ + currentParent = currentParent.parentNode; + if(currentParent.type == 'root'){ + currentParent = tmpParent; + throw 'break' + } + } + //end tag + currentParent = currentParent.parentNode; + } + + } + + } else if (match[2]) { + //comment + comment(currentParent, match[2]) + } + }catch(e){} + + nextIndex = re_tag.lastIndex; + + } + //如果结束是文本,就有可能丢掉,所以这里手动判断一下 + //例如
        • sdfsdfsdf
        • sdfsdfsdfsdf + if (nextIndex < htmlstr.length) { + text(currentParent, htmlstr.slice(nextIndex)); + } + return root; +}; + + +// core/filternode.js +/** + * UE过滤节点的静态方法 + * @file + */ + +/** + * UEditor公用空间,UEditor所有的功能都挂载在该空间下 + * @module UE + */ + + +/** + * 根据传入节点和过滤规则过滤相应节点 + * @module UE + * @since 1.2.6.1 + * @method filterNode + * @param { Object } root 指定root节点 + * @param { Object } rules 过滤规则json对象 + * @example + * ```javascript + * UE.filterNode(root,editor.options.filterRules); + * ``` + */ +var filterNode = UE.filterNode = function () { + function filterNode(node,rules){ + switch (node.type) { + case 'text': + break; + case 'element': + var val; + if(val = rules[node.tagName]){ + if(val === '-'){ + node.parentNode.removeChild(node) + }else if(utils.isFunction(val)){ + var parentNode = node.parentNode, + index = node.getIndex(); + val(node); + if(node.parentNode){ + if(node.children){ + for(var i = 0,ci;ci=node.children[i];){ + filterNode(ci,rules); + if(ci.parentNode){ + i++; + } + } + } + }else{ + for(var i = index,ci;ci=parentNode.children[i];){ + filterNode(ci,rules); + if(ci.parentNode){ + i++; + } + } + } + + + }else{ + var attrs = val['$']; + if(attrs && node.attrs){ + var tmpAttrs = {},tmpVal; + for(var a in attrs){ + tmpVal = node.getAttr(a); + //todo 只先对style单独处理 + if(a == 'style' && utils.isArray(attrs[a])){ + var tmpCssStyle = []; + utils.each(attrs[a],function(v){ + var tmp; + if(tmp = node.getStyle(v)){ + tmpCssStyle.push(v + ':' + tmp); + } + }); + tmpVal = tmpCssStyle.join(';') + } + if(tmpVal){ + tmpAttrs[a] = tmpVal; + } + + } + node.attrs = tmpAttrs; + } + if(node.children){ + for(var i = 0,ci;ci=node.children[i];){ + filterNode(ci,rules); + if(ci.parentNode){ + i++; + } + } + } + } + }else{ + //如果不在名单里扣出子节点并删除该节点,cdata除外 + if(dtd.$cdata[node.tagName]){ + node.parentNode.removeChild(node) + }else{ + var parentNode = node.parentNode, + index = node.getIndex(); + node.parentNode.removeChild(node,true); + for(var i = index,ci;ci=parentNode.children[i];){ + filterNode(ci,rules); + if(ci.parentNode){ + i++; + } + } + } + } + break; + case 'comment': + node.parentNode.removeChild(node) + } + + } + return function(root,rules){ + if(utils.isEmptyObject(rules)){ + return root; + } + var val; + if(val = rules['-']){ + utils.each(val.split(' '),function(k){ + rules[k] = '-' + }) + } + for(var i= 0,ci;ci=root.children[i];){ + filterNode(ci,rules); + if(ci.parentNode){ + i++; + } + } + return root; + } +}(); + +// core/plugin.js +/** + * Created with JetBrains PhpStorm. + * User: campaign + * Date: 10/8/13 + * Time: 6:15 PM + * To change this template use File | Settings | File Templates. + */ +UE.plugin = function(){ + var _plugins = {}; + return { + register : function(pluginName,fn,oldOptionName,afterDisabled){ + if(oldOptionName && utils.isFunction(oldOptionName)){ + afterDisabled = oldOptionName; + oldOptionName = null + } + _plugins[pluginName] = { + optionName : oldOptionName || pluginName, + execFn : fn, + //当插件被禁用时执行 + afterDisabled : afterDisabled + } + }, + load : function(editor){ + utils.each(_plugins,function(plugin){ + var _export = plugin.execFn.call(editor); + if(editor.options[plugin.optionName] !== false){ + if(_export){ + //后边需要再做扩展 + utils.each(_export,function(v,k){ + switch(k.toLowerCase()){ + case 'shortcutkey': + editor.addshortcutkey(v); + break; + case 'bindevents': + utils.each(v,function(fn,eventName){ + editor.addListener(eventName,fn); + }); + break; + case 'bindmultievents': + utils.each(utils.isArray(v) ? v:[v],function(event){ + var types = utils.trim(event.type).split(/\s+/); + utils.each(types,function(eventName){ + editor.addListener(eventName, event.handler); + }); + }); + break; + case 'commands': + utils.each(v,function(execFn,execName){ + editor.commands[execName] = execFn + }); + break; + case 'outputrule': + editor.addOutputRule(v); + break; + case 'inputrule': + editor.addInputRule(v); + break; + case 'defaultoptions': + editor.setOpt(v) + } + }) + } + + }else if(plugin.afterDisabled){ + plugin.afterDisabled.call(editor) + } + + }); + //向下兼容 + utils.each(UE.plugins,function(plugin){ + plugin.call(editor); + }); + }, + run : function(pluginName,editor){ + var plugin = _plugins[pluginName]; + if(plugin){ + plugin.exeFn.call(editor) + } + } + } +}(); + +// core/keymap.js +var keymap = UE.keymap = { + 'Backspace' : 8, + 'Tab' : 9, + 'Enter' : 13, + + 'Shift':16, + 'Control':17, + 'Alt':18, + 'CapsLock':20, + + 'Esc':27, + + 'Spacebar':32, + + 'PageUp':33, + 'PageDown':34, + 'End':35, + 'Home':36, + + 'Left':37, + 'Up':38, + 'Right':39, + 'Down':40, + + 'Insert':45, + + 'Del':46, + + 'NumLock':144, + + 'Cmd':91, + + '=':187, + '-':189, + + "b":66, + 'i':73, + //回退 + 'z':90, + 'y':89, + //粘贴 + 'v' : 86, + 'x' : 88, + + 's' : 83, + + 'n' : 78 +}; + +// core/localstorage.js +//存储媒介封装 +var LocalStorage = UE.LocalStorage = (function () { + + var storage = window.localStorage || getUserData() || null, + LOCAL_FILE = 'localStorage'; + + return { + + saveLocalData: function (key, data) { + + if (storage && data) { + storage.setItem(key, data); + return true; + } + + return false; + + }, + + getLocalData: function (key) { + + if (storage) { + return storage.getItem(key); + } + + return null; + + }, + + removeItem: function (key) { + + storage && storage.removeItem(key); + + } + + }; + + function getUserData() { + + var container = document.createElement("div"); + container.style.display = "none"; + + if (!container.addBehavior) { + return null; + } + + container.addBehavior("#default#userdata"); + + return { + + getItem: function (key) { + + var result = null; + + try { + document.body.appendChild(container); + container.load(LOCAL_FILE); + result = container.getAttribute(key); + document.body.removeChild(container); + } catch (e) { + } + + return result; + + }, + + setItem: function (key, value) { + + document.body.appendChild(container); + container.setAttribute(key, value); + container.save(LOCAL_FILE); + document.body.removeChild(container); + + }, + + //// 暂时没有用到 + //clear: function () { + // + // var expiresTime = new Date(); + // expiresTime.setFullYear(expiresTime.getFullYear() - 1); + // document.body.appendChild(container); + // container.expires = expiresTime.toUTCString(); + // container.save(LOCAL_FILE); + // document.body.removeChild(container); + // + //}, + + removeItem: function (key) { + + document.body.appendChild(container); + container.removeAttribute(key); + container.save(LOCAL_FILE); + document.body.removeChild(container); + + } + + }; + + } + +})(); + +(function () { + + var ROOTKEY = 'ueditor_preference'; + + UE.Editor.prototype.setPreferences = function(key,value){ + var obj = {}; + if (utils.isString(key)) { + obj[ key ] = value; + } else { + obj = key; + } + var data = LocalStorage.getLocalData(ROOTKEY); + if (data && (data = utils.str2json(data))) { + utils.extend(data, obj); + } else { + data = obj; + } + data && LocalStorage.saveLocalData(ROOTKEY, utils.json2str(data)); + }; + + UE.Editor.prototype.getPreferences = function(key){ + var data = LocalStorage.getLocalData(ROOTKEY); + if (data && (data = utils.str2json(data))) { + return key ? data[key] : data + } + return null; + }; + + UE.Editor.prototype.removePreferences = function (key) { + var data = LocalStorage.getLocalData(ROOTKEY); + if (data && (data = utils.str2json(data))) { + data[key] = undefined; + delete data[key] + } + data && LocalStorage.saveLocalData(ROOTKEY, utils.json2str(data)); + }; + +})(); + + +// plugins/defaultfilter.js +///import core +///plugin 编辑器默认的过滤转换机制 + +UE.plugins['defaultfilter'] = function () { + var me = this; + me.setOpt({ + 'allowDivTransToP':true, + 'disabledTableInTable':true + }); + //默认的过滤处理 + //进入编辑器的内容处理 + me.addInputRule(function (root) { + var allowDivTransToP = this.options.allowDivTransToP; + var val; + function tdParent(node){ + while(node && node.type == 'element'){ + if(node.tagName == 'td'){ + return true; + } + node = node.parentNode; + } + return false; + } + //进行默认的处理 + root.traversal(function (node) { + if (node.type == 'element') { + if (!dtd.$cdata[node.tagName] && me.options.autoClearEmptyNode && dtd.$inline[node.tagName] && !dtd.$empty[node.tagName] && (!node.attrs || utils.isEmptyObject(node.attrs))) { + if (!node.firstChild()) node.parentNode.removeChild(node); + else if (node.tagName == 'span' && (!node.attrs || utils.isEmptyObject(node.attrs))) { + node.parentNode.removeChild(node, true) + } + return; + } + switch (node.tagName) { + case 'style': + case 'script': + node.setAttr({ + cdata_tag: node.tagName, + cdata_data: (node.innerHTML() || ''), + '_ue_custom_node_':'true' + }); + node.tagName = 'div'; + node.innerHTML(''); + break; + case 'a': + if (val = node.getAttr('href')) { + node.setAttr('_href', val) + } + break; + case 'img': + //todo base64暂时去掉,后边做远程图片上传后,干掉这个 + if (val = node.getAttr('src')) { + if (/^data:/.test(val)) { + node.parentNode.removeChild(node); + break; + } + } + node.setAttr('_src', node.getAttr('src')); + break; + case 'span': + if (browser.webkit && (val = node.getStyle('white-space'))) { + if (/nowrap|normal/.test(val)) { + node.setStyle('white-space', ''); + if (me.options.autoClearEmptyNode && utils.isEmptyObject(node.attrs)) { + node.parentNode.removeChild(node, true) + } + } + } + val = node.getAttr('id'); + if(val && /^_baidu_bookmark_/i.test(val)){ + node.parentNode.removeChild(node) + } + break; + case 'p': + if (val = node.getAttr('align')) { + node.setAttr('align'); + node.setStyle('text-align', val) + } + //trace:3431 +// var cssStyle = node.getAttr('style'); +// if (cssStyle) { +// cssStyle = cssStyle.replace(/(margin|padding)[^;]+/g, ''); +// node.setAttr('style', cssStyle) +// +// } + //p标签不允许嵌套 + utils.each(node.children,function(n){ + if(n.type == 'element' && n.tagName == 'p'){ + var next = n.nextSibling(); + node.parentNode.insertAfter(n,node); + var last = n; + while(next){ + var tmp = next.nextSibling(); + node.parentNode.insertAfter(next,last); + last = next; + next = tmp; + } + return false; + } + }); + if (!node.firstChild()) { + node.innerHTML(browser.ie ? ' ' : '
          ') + } + break; + case 'div': + if(node.getAttr('cdata_tag')){ + break; + } + //针对代码这里不处理插入代码的div + val = node.getAttr('class'); + if(val && /^line number\d+/.test(val)){ + break; + } + if(!allowDivTransToP){ + break; + } + var tmpNode, p = UE.uNode.createElement('p'); + while (tmpNode = node.firstChild()) { + if (tmpNode.type == 'text' || !UE.dom.dtd.$block[tmpNode.tagName]) { + p.appendChild(tmpNode); + } else { + if (p.firstChild()) { + node.parentNode.insertBefore(p, node); + p = UE.uNode.createElement('p'); + } else { + node.parentNode.insertBefore(tmpNode, node); + } + } + } + if (p.firstChild()) { + node.parentNode.insertBefore(p, node); + } + node.parentNode.removeChild(node); + break; + case 'dl': + node.tagName = 'ul'; + break; + case 'dt': + case 'dd': + node.tagName = 'li'; + break; + case 'li': + var className = node.getAttr('class'); + if (!className || !/list\-/.test(className)) { + node.setAttr() + } + var tmpNodes = node.getNodesByTagName('ol ul'); + UE.utils.each(tmpNodes, function (n) { + node.parentNode.insertAfter(n, node); + }); + break; + case 'td': + case 'th': + case 'caption': + if(!node.children || !node.children.length){ + node.appendChild(browser.ie11below ? UE.uNode.createText(' ') : UE.uNode.createElement('br')) + } + break; + case 'table': + if(me.options.disabledTableInTable && tdParent(node)){ + node.parentNode.insertBefore(UE.uNode.createText(node.innerText()),node); + node.parentNode.removeChild(node) + } + } + + } +// if(node.type == 'comment'){ +// node.parentNode.removeChild(node); +// } + }) + + }); + + //从编辑器出去的内容处理 + me.addOutputRule(function (root) { + + var val; + root.traversal(function (node) { + if (node.type == 'element') { + + if (me.options.autoClearEmptyNode && dtd.$inline[node.tagName] && !dtd.$empty[node.tagName] && (!node.attrs || utils.isEmptyObject(node.attrs))) { + + if (!node.firstChild()) node.parentNode.removeChild(node); + else if (node.tagName == 'span' && (!node.attrs || utils.isEmptyObject(node.attrs))) { + node.parentNode.removeChild(node, true) + } + return; + } + switch (node.tagName) { + case 'div': + if (val = node.getAttr('cdata_tag')) { + node.tagName = val; + node.appendChild(UE.uNode.createText(node.getAttr('cdata_data'))); + node.setAttr({cdata_tag: '', cdata_data: '','_ue_custom_node_':''}); + } + break; + case 'a': + if (val = node.getAttr('_href')) { + node.setAttr({ + 'href': utils.html(val), + '_href': '' + }) + } + break; + break; + case 'span': + val = node.getAttr('id'); + if(val && /^_baidu_bookmark_/i.test(val)){ + node.parentNode.removeChild(node) + } + break; + case 'img': + if (val = node.getAttr('_src')) { + node.setAttr({ + 'src': node.getAttr('_src'), + '_src': '' + }) + } + + + } + } + + }) + + + }); +}; + + +// plugins/inserthtml.js +/** + * 插入html字符串插件 + * @file + * @since 1.2.6.1 + */ + +/** + * 插入html代码 + * @command inserthtml + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } html 插入的html字符串 + * @remaind 插入的标签内容是在当前的选区位置上插入,如果当前是闭合状态,那直接插入内容, 如果当前是选中状态,将先清除当前选中内容后,再做插入 + * @warning 注意:该命令会对当前选区的位置,对插入的内容进行过滤转换处理。 过滤的规则遵循html语意化的原则。 + * @example + * ```javascript + * //xxx[BB]xxx 当前选区为非闭合选区,选中BB这两个文本 + * //执行命令,插入CC + * //插入后的效果 xxxCCxxx + * //

          xx|xxx

          当前选区为闭合状态 + * //插入

          CC

          + * //结果

          xx

          CC

          xxx

          + * //

          xxxx

          |

          xxx

          当前选区在两个p标签之间 + * //插入 xxxx + * //结果

          xxxx

          xxxx

          xxx

          + * ``` + */ + +UE.commands['inserthtml'] = { + execCommand: function (command,html,notNeedFilter){ + var me = this, + range, + div; + if(!html){ + return; + } + if(me.fireEvent('beforeinserthtml',html) === true){ + return; + } + range = me.selection.getRange(); + div = range.document.createElement( 'div' ); + div.style.display = 'inline'; + + if (!notNeedFilter) { + var root = UE.htmlparser(html); + //如果给了过滤规则就先进行过滤 + if(me.options.filterRules){ + UE.filterNode(root,me.options.filterRules); + } + //执行默认的处理 + me.filterInputRule(root); + html = root.toHtml() + } + div.innerHTML = utils.trim( html ); + + if ( !range.collapsed ) { + var tmpNode = range.startContainer; + if(domUtils.isFillChar(tmpNode)){ + range.setStartBefore(tmpNode) + } + tmpNode = range.endContainer; + if(domUtils.isFillChar(tmpNode)){ + range.setEndAfter(tmpNode) + } + range.txtToElmBoundary(); + //结束边界可能放到了br的前边,要把br包含进来 + // x[xxx]
          + if(range.endContainer && range.endContainer.nodeType == 1){ + tmpNode = range.endContainer.childNodes[range.endOffset]; + if(tmpNode && domUtils.isBr(tmpNode)){ + range.setEndAfter(tmpNode); + } + } + if(range.startOffset == 0){ + tmpNode = range.startContainer; + if(domUtils.isBoundaryNode(tmpNode,'firstChild') ){ + tmpNode = range.endContainer; + if(range.endOffset == (tmpNode.nodeType == 3 ? tmpNode.nodeValue.length : tmpNode.childNodes.length) && domUtils.isBoundaryNode(tmpNode,'lastChild')){ + me.body.innerHTML = '

          '+(browser.ie ? '' : '
          ')+'

          '; + range.setStart(me.body.firstChild,0).collapse(true) + + } + } + } + !range.collapsed && range.deleteContents(); + if(range.startContainer.nodeType == 1){ + var child = range.startContainer.childNodes[range.startOffset],pre; + if(child && domUtils.isBlockElm(child) && (pre = child.previousSibling) && domUtils.isBlockElm(pre)){ + range.setEnd(pre,pre.childNodes.length).collapse(); + while(child.firstChild){ + pre.appendChild(child.firstChild); + } + domUtils.remove(child); + } + } + + } + + + var child,parent,pre,tmp,hadBreak = 0, nextNode; + //如果当前位置选中了fillchar要干掉,要不会产生空行 + if(range.inFillChar()){ + child = range.startContainer; + if(domUtils.isFillChar(child)){ + range.setStartBefore(child).collapse(true); + domUtils.remove(child); + }else if(domUtils.isFillChar(child,true)){ + child.nodeValue = child.nodeValue.replace(fillCharReg,''); + range.startOffset--; + range.collapsed && range.collapse(true) + } + } + //列表单独处理 + var li = domUtils.findParentByTagName(range.startContainer,'li',true); + if(li){ + var next,last; + while(child = div.firstChild){ + //针对hr单独处理一下先 + while(child && (child.nodeType == 3 || !domUtils.isBlockElm(child) || child.tagName=='HR' )){ + next = child.nextSibling; + range.insertNode( child).collapse(); + last = child; + child = next; + + } + if(child){ + if(/^(ol|ul)$/i.test(child.tagName)){ + while(child.firstChild){ + last = child.firstChild; + domUtils.insertAfter(li,child.firstChild); + li = li.nextSibling; + } + domUtils.remove(child) + }else{ + var tmpLi; + next = child.nextSibling; + tmpLi = me.document.createElement('li'); + domUtils.insertAfter(li,tmpLi); + tmpLi.appendChild(child); + last = child; + child = next; + li = tmpLi; + } + } + } + li = domUtils.findParentByTagName(range.startContainer,'li',true); + if(domUtils.isEmptyBlock(li)){ + domUtils.remove(li) + } + if(last){ + + range.setStartAfter(last).collapse(true).select(true) + } + }else{ + while ( child = div.firstChild ) { + if(hadBreak){ + var p = me.document.createElement('p'); + while(child && (child.nodeType == 3 || !dtd.$block[child.tagName])){ + nextNode = child.nextSibling; + p.appendChild(child); + child = nextNode; + } + if(p.firstChild){ + + child = p + } + } + range.insertNode( child ); + nextNode = child.nextSibling; + if ( !hadBreak && child.nodeType == domUtils.NODE_ELEMENT && domUtils.isBlockElm( child ) ){ + + parent = domUtils.findParent( child,function ( node ){ return domUtils.isBlockElm( node ); } ); + if ( parent && parent.tagName.toLowerCase() != 'body' && !(dtd[parent.tagName][child.nodeName] && child.parentNode === parent)){ + if(!dtd[parent.tagName][child.nodeName]){ + pre = parent; + }else{ + tmp = child.parentNode; + while (tmp !== parent){ + pre = tmp; + tmp = tmp.parentNode; + + } + } + + + domUtils.breakParent( child, pre || tmp ); + //去掉break后前一个多余的节点

          |<[p> ==>

          |

          + var pre = child.previousSibling; + domUtils.trimWhiteTextNode(pre); + if(!pre.childNodes.length){ + domUtils.remove(pre); + } + //trace:2012,在非ie的情况,切开后剩下的节点有可能不能点入光标添加br占位 + + if(!browser.ie && + (next = child.nextSibling) && + domUtils.isBlockElm(next) && + next.lastChild && + !domUtils.isBr(next.lastChild)){ + next.appendChild(me.document.createElement('br')); + } + hadBreak = 1; + } + } + var next = child.nextSibling; + if(!div.firstChild && next && domUtils.isBlockElm(next)){ + + range.setStart(next,0).collapse(true); + break; + } + range.setEndAfter( child ).collapse(); + + } + + child = range.startContainer; + + if(nextNode && domUtils.isBr(nextNode)){ + domUtils.remove(nextNode) + } + //用chrome可能有空白展位符 + if(domUtils.isBlockElm(child) && domUtils.isEmptyNode(child)){ + if(nextNode = child.nextSibling){ + domUtils.remove(child); + if(nextNode.nodeType == 1 && dtd.$block[nextNode.tagName]){ + + range.setStart(nextNode,0).collapse(true).shrinkBoundary() + } + }else{ + + try{ + child.innerHTML = browser.ie ? domUtils.fillChar : '
          '; + }catch(e){ + range.setStartBefore(child); + domUtils.remove(child) + } + + } + + } + //加上true因为在删除表情等时会删两次,第一次是删的fillData + try{ + range.select(true); + }catch(e){} + + } + + + + setTimeout(function(){ + range = me.selection.getRange(); + range.scrollToView(me.autoHeightEnabled,me.autoHeightEnabled ? domUtils.getXY(me.iframe).y:0); + me.fireEvent('afterinserthtml', html); + },200); + } +}; + + +// plugins/autotypeset.js +/** + * 自动排版 + * @file + * @since 1.2.6.1 + */ + +/** + * 对当前编辑器的内容执行自动排版, 排版的行为根据config配置文件里的“autotypeset”选项进行控制。 + * @command autotypeset + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'autotypeset' ); + * ``` + */ + +UE.plugins['autotypeset'] = function(){ + + this.setOpt({'autotypeset': { + mergeEmptyline: true, //合并空行 + removeClass: true, //去掉冗余的class + removeEmptyline: false, //去掉空行 + textAlign:"left", //段落的排版方式,可以是 left,right,center,justify 去掉这个属性表示不执行排版 + imageBlockLine: 'center', //图片的浮动方式,独占一行剧中,左右浮动,默认: center,left,right,none 去掉这个属性表示不执行排版 + pasteFilter: false, //根据规则过滤没事粘贴进来的内容 + clearFontSize: false, //去掉所有的内嵌字号,使用编辑器默认的字号 + clearFontFamily: false, //去掉所有的内嵌字体,使用编辑器默认的字体 + removeEmptyNode: false, // 去掉空节点 + //可以去掉的标签 + removeTagNames: utils.extend({div:1},dtd.$removeEmpty), + indent: false, // 行首缩进 + indentValue : '2em', //行首缩进的大小 + bdc2sb: false, + tobdc: false + }}); + + var me = this, + opt = me.options.autotypeset, + remainClass = { + 'selectTdClass':1, + 'pagebreak':1, + 'anchorclass':1 + }, + remainTag = { + 'li':1 + }, + tags = { + div:1, + p:1, + //trace:2183 这些也认为是行 + blockquote:1,center:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1, + span:1 + }, + highlightCont; + //升级了版本,但配置项目里没有autotypeset + if(!opt){ + return; + } + + readLocalOpts(); + + function isLine(node,notEmpty){ + if(!node || node.nodeType == 3) + return 0; + if(domUtils.isBr(node)) + return 1; + if(node && node.parentNode && tags[node.tagName.toLowerCase()]){ + if(highlightCont && highlightCont.contains(node) + || + node.getAttribute('pagebreak') + ){ + return 0; + } + + return notEmpty ? !domUtils.isEmptyBlock(node) : domUtils.isEmptyBlock(node,new RegExp('[\\s'+domUtils.fillChar + +']','g')); + } + } + + function removeNotAttributeSpan(node){ + if(!node.style.cssText){ + domUtils.removeAttributes(node,['style']); + if(node.tagName.toLowerCase() == 'span' && domUtils.hasNoAttributes(node)){ + domUtils.remove(node,true); + } + } + } + function autotype(type,html){ + + var me = this,cont; + if(html){ + if(!opt.pasteFilter){ + return; + } + cont = me.document.createElement('div'); + cont.innerHTML = html.html; + }else{ + cont = me.document.body; + } + var nodes = domUtils.getElementsByTagName(cont,'*'); + + // 行首缩进,段落方向,段间距,段内间距 + for(var i=0,ci;ci=nodes[i++];){ + + if(me.fireEvent('excludeNodeinautotype',ci) === true){ + continue; + } + //font-size + if(opt.clearFontSize && ci.style.fontSize){ + domUtils.removeStyle(ci,'font-size'); + + removeNotAttributeSpan(ci); + + } + //font-family + if(opt.clearFontFamily && ci.style.fontFamily){ + domUtils.removeStyle(ci,'font-family'); + removeNotAttributeSpan(ci); + } + + if(isLine(ci)){ + //合并空行 + if(opt.mergeEmptyline ){ + var next = ci.nextSibling,tmpNode,isBr = domUtils.isBr(ci); + while(isLine(next)){ + tmpNode = next; + next = tmpNode.nextSibling; + if(isBr && (!next || next && !domUtils.isBr(next))){ + break; + } + domUtils.remove(tmpNode); + } + + } + //去掉空行,保留占位的空行 + if(opt.removeEmptyline && domUtils.inDoc(ci,cont) && !remainTag[ci.parentNode.tagName.toLowerCase()] ){ + if(domUtils.isBr(ci)){ + next = ci.nextSibling; + if(next && !domUtils.isBr(next)){ + continue; + } + } + domUtils.remove(ci); + continue; + + } + + } + if(isLine(ci,true) && ci.tagName != 'SPAN'){ + if(opt.indent){ + ci.style.textIndent = opt.indentValue; + } + if(opt.textAlign){ + ci.style.textAlign = opt.textAlign; + } + // if(opt.lineHeight) + // ci.style.lineHeight = opt.lineHeight + 'cm'; + + } + + //去掉class,保留的class不去掉 + if(opt.removeClass && ci.className && !remainClass[ci.className.toLowerCase()]){ + + if(highlightCont && highlightCont.contains(ci)){ + continue; + } + domUtils.removeAttributes(ci,['class']); + } + + //表情不处理 + if(opt.imageBlockLine && ci.tagName.toLowerCase() == 'img' && !ci.getAttribute('emotion')){ + if(html){ + var img = ci; + switch (opt.imageBlockLine){ + case 'left': + case 'right': + case 'none': + var pN = img.parentNode,tmpNode,pre,next; + while(dtd.$inline[pN.tagName] || pN.tagName == 'A'){ + pN = pN.parentNode; + } + tmpNode = pN; + if(tmpNode.tagName == 'P' && domUtils.getStyle(tmpNode,'text-align') == 'center'){ + if(!domUtils.isBody(tmpNode) && domUtils.getChildCount(tmpNode,function(node){return !domUtils.isBr(node) && !domUtils.isWhitespace(node)}) == 1){ + pre = tmpNode.previousSibling; + next = tmpNode.nextSibling; + if(pre && next && pre.nodeType == 1 && next.nodeType == 1 && pre.tagName == next.tagName && domUtils.isBlockElm(pre)){ + pre.appendChild(tmpNode.firstChild); + while(next.firstChild){ + pre.appendChild(next.firstChild); + } + domUtils.remove(tmpNode); + domUtils.remove(next); + }else{ + domUtils.setStyle(tmpNode,'text-align',''); + } + + + } + + + } + domUtils.setStyle(img,'float', opt.imageBlockLine); + break; + case 'center': + if(me.queryCommandValue('imagefloat') != 'center'){ + pN = img.parentNode; + domUtils.setStyle(img,'float','none'); + tmpNode = img; + while(pN && domUtils.getChildCount(pN,function(node){return !domUtils.isBr(node) && !domUtils.isWhitespace(node)}) == 1 + && (dtd.$inline[pN.tagName] || pN.tagName == 'A')){ + tmpNode = pN; + pN = pN.parentNode; + } + var pNode = me.document.createElement('p'); + domUtils.setAttributes(pNode,{ + + style:'text-align:center' + }); + tmpNode.parentNode.insertBefore(pNode,tmpNode); + pNode.appendChild(tmpNode); + domUtils.setStyle(tmpNode,'float',''); + + } + + + } + } else { + var range = me.selection.getRange(); + range.selectNode(ci).select(); + me.execCommand('imagefloat', opt.imageBlockLine); + } + + } + + //去掉冗余的标签 + if(opt.removeEmptyNode){ + if(opt.removeTagNames[ci.tagName.toLowerCase()] && domUtils.hasNoAttributes(ci) && domUtils.isEmptyBlock(ci)){ + domUtils.remove(ci); + } + } + } + if(opt.tobdc){ + var root = UE.htmlparser(cont.innerHTML); + root.traversal(function(node){ + if(node.type == 'text'){ + node.data = ToDBC(node.data) + } + }); + cont.innerHTML = root.toHtml() + } + if(opt.bdc2sb){ + var root = UE.htmlparser(cont.innerHTML); + root.traversal(function(node){ + if(node.type == 'text'){ + node.data = DBC2SB(node.data) + } + }); + cont.innerHTML = root.toHtml() + } + if(html){ + html.html = cont.innerHTML; + } + } + if(opt.pasteFilter){ + me.addListener('beforepaste',autotype); + } + + function DBC2SB(str) { + var result = ''; + for (var i = 0; i < str.length; i++) { + var code = str.charCodeAt(i); //获取当前字符的unicode编码 + if (code >= 65281 && code <= 65373)//在这个unicode编码范围中的是所有的英文字母已经各种字符 + { + result += String.fromCharCode(str.charCodeAt(i) - 65248); //把全角字符的unicode编码转换为对应半角字符的unicode码 + } else if (code == 12288)//空格 + { + result += String.fromCharCode(str.charCodeAt(i) - 12288 + 32); + } else { + result += str.charAt(i); + } + } + return result; + } + function ToDBC(txtstring) { + txtstring = utils.html(txtstring); + var tmp = ""; + var mark = "";/*用于判断,如果是html尖括里的标记,则不进行全角的转换*/ + for (var i = 0; i < txtstring.length; i++) { + if (txtstring.charCodeAt(i) == 32) { + tmp = tmp + String.fromCharCode(12288); + } + else if (txtstring.charCodeAt(i) < 127) { + tmp = tmp + String.fromCharCode(txtstring.charCodeAt(i) + 65248); + } + else { + tmp += txtstring.charAt(i); + } + } + return tmp; + } + + function readLocalOpts() { + var cookieOpt = me.getPreferences('autotypeset'); + utils.extend(me.options.autotypeset, cookieOpt); + } + + me.commands['autotypeset'] = { + execCommand:function () { + me.removeListener('beforepaste',autotype); + if(opt.pasteFilter){ + me.addListener('beforepaste',autotype); + } + autotype.call(me) + } + + }; + +}; + + + +// plugins/autosubmit.js +/** + * 快捷键提交 + * @file + * @since 1.2.6.1 + */ + +/** + * 提交表单 + * @command autosubmit + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'autosubmit' ); + * ``` + */ + +UE.plugin.register('autosubmit',function(){ + return { + shortcutkey:{ + "autosubmit":"ctrl+13" //手动提交 + }, + commands:{ + 'autosubmit':{ + execCommand:function () { + var me=this, + form = domUtils.findParentByTagName(me.iframe,"form", false); + if (form){ + if(me.fireEvent("beforesubmit")===false){ + return; + } + me.sync(); + form.submit(); + } + } + } + } + } +}); + +// plugins/background.js +/** + * 背景插件,为UEditor提供设置背景功能 + * @file + * @since 1.2.6.1 + */ +UE.plugin.register('background', function () { + var me = this, + cssRuleId = 'editor_background', + isSetColored, + reg = new RegExp('body[\\s]*\\{(.+)\\}', 'i'); + + function stringToObj(str) { + var obj = {}, styles = str.split(';'); + utils.each(styles, function (v) { + var index = v.indexOf(':'), + key = utils.trim(v.substr(0, index)).toLowerCase(); + key && (obj[key] = utils.trim(v.substr(index + 1) || '')); + }); + return obj; + } + + function setBackground(obj) { + if (obj) { + var styles = []; + for (var name in obj) { + if (obj.hasOwnProperty(name)) { + styles.push(name + ":" + obj[name] + '; '); + } + } + utils.cssRule(cssRuleId, styles.length ? ('body{' + styles.join("") + '}') : '', me.document); + } else { + utils.cssRule(cssRuleId, '', me.document) + } + } + //重写editor.hasContent方法 + + var orgFn = me.hasContents; + me.hasContents = function(){ + if(me.queryCommandValue('background')){ + return true + } + return orgFn.apply(me,arguments); + }; + return { + bindEvents: { + 'getAllHtml': function (type, headHtml) { + var body = this.body, + su = domUtils.getComputedStyle(body, "background-image"), + url = ""; + if (su.indexOf(me.options.imagePath) > 0) { + url = su.substring(su.indexOf(me.options.imagePath), su.length - 1).replace(/"|\(|\)/ig, ""); + } else { + url = su != "none" ? su.replace(/url\("?|"?\)/ig, "") : ""; + } + var html = ' '; + headHtml.push(html); + }, + 'aftersetcontent': function () { + if(isSetColored == false) setBackground(); + } + }, + inputRule: function (root) { + isSetColored = false; + utils.each(root.getNodesByTagName('p'), function (p) { + var styles = p.getAttr('data-background'); + if (styles) { + isSetColored = true; + setBackground(stringToObj(styles)); + p.parentNode.removeChild(p); + } + }) + }, + outputRule: function (root) { + var me = this, + styles = (utils.cssRule(cssRuleId, me.document) || '').replace(/[\n\r]+/g, '').match(reg); + if (styles) { + root.appendChild(UE.uNode.createElement('


          ')); + } + }, + commands: { + 'background': { + execCommand: function (cmd, obj) { + setBackground(obj); + }, + queryCommandValue: function () { + var me = this, + styles = (utils.cssRule(cssRuleId, me.document) || '').replace(/[\n\r]+/g, '').match(reg); + return styles ? stringToObj(styles[1]) : null; + }, + notNeedUndo: true + } + } + } +}); + +// plugins/image.js +/** + * 图片插入、排版插件 + * @file + * @since 1.2.6.1 + */ + +/** + * 图片对齐方式 + * @command imagefloat + * @method execCommand + * @remind 值center为独占一行居中 + * @param { String } cmd 命令字符串 + * @param { String } align 对齐方式,可传left、right、none、center + * @remaind center表示图片独占一行 + * @example + * ```javascript + * editor.execCommand( 'imagefloat', 'center' ); + * ``` + */ + +/** + * 如果选区所在位置是图片区域 + * @command imagefloat + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回图片对齐方式 + * @example + * ```javascript + * editor.queryCommandValue( 'imagefloat' ); + * ``` + */ + +UE.commands['imagefloat'] = { + execCommand:function (cmd, align) { + var me = this, + range = me.selection.getRange(); + if (!range.collapsed) { + var img = range.getClosedNode(); + if (img && img.tagName == 'IMG') { + switch (align) { + case 'left': + case 'right': + case 'none': + var pN = img.parentNode, tmpNode, pre, next; + while (dtd.$inline[pN.tagName] || pN.tagName == 'A') { + pN = pN.parentNode; + } + tmpNode = pN; + if (tmpNode.tagName == 'P' && domUtils.getStyle(tmpNode, 'text-align') == 'center') { + if (!domUtils.isBody(tmpNode) && domUtils.getChildCount(tmpNode, function (node) { + return !domUtils.isBr(node) && !domUtils.isWhitespace(node); + }) == 1) { + pre = tmpNode.previousSibling; + next = tmpNode.nextSibling; + if (pre && next && pre.nodeType == 1 && next.nodeType == 1 && pre.tagName == next.tagName && domUtils.isBlockElm(pre)) { + pre.appendChild(tmpNode.firstChild); + while (next.firstChild) { + pre.appendChild(next.firstChild); + } + domUtils.remove(tmpNode); + domUtils.remove(next); + } else { + domUtils.setStyle(tmpNode, 'text-align', ''); + } + + + } + + range.selectNode(img).select(); + } + domUtils.setStyle(img, 'float', align == 'none' ? '' : align); + if(align == 'none'){ + domUtils.removeAttributes(img,'align'); + } + + break; + case 'center': + if (me.queryCommandValue('imagefloat') != 'center') { + pN = img.parentNode; + domUtils.setStyle(img, 'float', ''); + domUtils.removeAttributes(img,'align'); + tmpNode = img; + while (pN && domUtils.getChildCount(pN, function (node) { + return !domUtils.isBr(node) && !domUtils.isWhitespace(node); + }) == 1 + && (dtd.$inline[pN.tagName] || pN.tagName == 'A')) { + tmpNode = pN; + pN = pN.parentNode; + } + range.setStartBefore(tmpNode).setCursor(false); + pN = me.document.createElement('div'); + pN.appendChild(tmpNode); + domUtils.setStyle(tmpNode, 'float', ''); + + me.execCommand('insertHtml', '

          ' + pN.innerHTML + '

          '); + + tmpNode = me.document.getElementById('_img_parent_tmp'); + tmpNode.removeAttribute('id'); + tmpNode = tmpNode.firstChild; + range.selectNode(tmpNode).select(); + //去掉后边多余的元素 + next = tmpNode.parentNode.nextSibling; + if (next && domUtils.isEmptyNode(next)) { + domUtils.remove(next); + } + + } + + break; + } + + } + } + }, + queryCommandValue:function () { + var range = this.selection.getRange(), + startNode, floatStyle; + if (range.collapsed) { + return 'none'; + } + startNode = range.getClosedNode(); + if (startNode && startNode.nodeType == 1 && startNode.tagName == 'IMG') { + floatStyle = domUtils.getComputedStyle(startNode, 'float') || startNode.getAttribute('align'); + + if (floatStyle == 'none') { + floatStyle = domUtils.getComputedStyle(startNode.parentNode, 'text-align') == 'center' ? 'center' : floatStyle; + } + return { + left:1, + right:1, + center:1 + }[floatStyle] ? floatStyle : 'none'; + } + return 'none'; + + + }, + queryCommandState:function () { + var range = this.selection.getRange(), + startNode; + + if (range.collapsed) return -1; + + startNode = range.getClosedNode(); + if (startNode && startNode.nodeType == 1 && startNode.tagName == 'IMG') { + return 0; + } + return -1; + } +}; + + +/** + * 插入图片 + * @command insertimage + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { Object } opt 属性键值对,这些属性都将被复制到当前插入图片 + * @remind 该命令第二个参数可接受一个图片配置项对象的数组,可以插入多张图片, + * 此时数组的每一个元素都是一个Object类型的图片属性集合。 + * @example + * ```javascript + * editor.execCommand( 'insertimage', { + * src:'a/b/c.jpg', + * width:'100', + * height:'100' + * } ); + * ``` + * @example + * ```javascript + * editor.execCommand( 'insertimage', [{ + * src:'a/b/c.jpg', + * width:'100', + * height:'100' + * },{ + * src:'a/b/d.jpg', + * width:'100', + * height:'100' + * }] ); + * ``` + */ + +UE.commands['insertimage'] = { + execCommand:function (cmd, opt) { + + opt = utils.isArray(opt) ? opt : [opt]; + if (!opt.length) { + return; + } + var me = this, + range = me.selection.getRange(), + img = range.getClosedNode(); + + if(me.fireEvent('beforeinsertimage', opt) === true){ + return; + } + + function unhtmlData(imgCi) { + + utils.each('width,height,border,hspace,vspace'.split(','), function (item) { + + if (imgCi[item]) { + imgCi[item] = parseInt(imgCi[item], 10) || 0; + } + }); + + utils.each('src,_src'.split(','), function (item) { + + if (imgCi[item]) { + imgCi[item] = utils.unhtmlForUrl(imgCi[item]); + } + }); + utils.each('title,alt'.split(','), function (item) { + + if (imgCi[item]) { + imgCi[item] = utils.unhtml(imgCi[item]); + } + }); + } + + if (img && /img/i.test(img.tagName) && (img.className != "edui-faked-video" || img.className.indexOf("edui-upload-video")!=-1) && !img.getAttribute("word_img")) { + var first = opt.shift(); + var floatStyle = first['floatStyle']; + delete first['floatStyle']; +//// img.style.border = (first.border||0) +"px solid #000"; +//// img.style.margin = (first.margin||0) +"px"; +// img.style.cssText += ';margin:' + (first.margin||0) +"px;" + 'border:' + (first.border||0) +"px solid #000"; + domUtils.setAttributes(img, first); + me.execCommand('imagefloat', floatStyle); + if (opt.length > 0) { + range.setStartAfter(img).setCursor(false, true); + me.execCommand('insertimage', opt); + } + + } else { + var html = [], str = '', ci; + ci = opt[0]; + if (opt.length == 1) { + unhtmlData(ci); + + str = '' + ci.alt + ''; + if (ci['floatStyle'] == 'center') { + str = '

          ' + str + '

          '; + } + html.push(str); + + } else { + for (var i = 0; ci = opt[i++];) { + unhtmlData(ci); + str = '

          '; + html.push(str); + } + } + + me.execCommand('insertHtml', html.join('')); + } + + me.fireEvent('afterinsertimage', opt) + } +}; + + +// plugins/justify.js +/** + * 段落格式 + * @file + * @since 1.2.6.1 + */ + +/** + * 段落对齐方式 + * @command justify + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } align 对齐方式:left => 居左,right => 居右,center => 居中,justify => 两端对齐 + * @example + * ```javascript + * editor.execCommand( 'justify', 'center' ); + * ``` + */ +/** + * 如果选区所在位置是段落区域,返回当前段落对齐方式 + * @command justify + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回段落对齐方式 + * @example + * ```javascript + * editor.queryCommandValue( 'justify' ); + * ``` + */ + +UE.plugins['justify']=function(){ + var me=this, + block = domUtils.isBlockElm, + defaultValue = { + left:1, + right:1, + center:1, + justify:1 + }, + doJustify = function (range, style) { + var bookmark = range.createBookmark(), + filterFn = function (node) { + return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' && !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace(node); + }; + + range.enlarge(true); + var bookmark2 = range.createBookmark(), + current = domUtils.getNextDomNode(bookmark2.start, false, filterFn), + tmpRange = range.cloneRange(), + tmpNode; + while (current && !(domUtils.getPosition(current, bookmark2.end) & domUtils.POSITION_FOLLOWING)) { + if (current.nodeType == 3 || !block(current)) { + tmpRange.setStartBefore(current); + while (current && current !== bookmark2.end && !block(current)) { + tmpNode = current; + current = domUtils.getNextDomNode(current, false, null, function (node) { + return !block(node); + }); + } + tmpRange.setEndAfter(tmpNode); + var common = tmpRange.getCommonAncestor(); + if (!domUtils.isBody(common) && block(common)) { + domUtils.setStyles(common, utils.isString(style) ? {'text-align':style} : style); + current = common; + } else { + var p = range.document.createElement('p'); + domUtils.setStyles(p, utils.isString(style) ? {'text-align':style} : style); + var frag = tmpRange.extractContents(); + p.appendChild(frag); + tmpRange.insertNode(p); + current = p; + } + current = domUtils.getNextDomNode(current, false, filterFn); + } else { + current = domUtils.getNextDomNode(current, true, filterFn); + } + } + return range.moveToBookmark(bookmark2).moveToBookmark(bookmark); + }; + + UE.commands['justify'] = { + execCommand:function (cmdName, align) { + var range = this.selection.getRange(), + txt; + + //闭合时单独处理 + if (range.collapsed) { + txt = this.document.createTextNode('p'); + range.insertNode(txt); + } + doJustify(range, align); + if (txt) { + range.setStartBefore(txt).collapse(true); + domUtils.remove(txt); + } + + range.select(); + + + return true; + }, + queryCommandValue:function () { + var startNode = this.selection.getStart(), + value = domUtils.getComputedStyle(startNode, 'text-align'); + return defaultValue[value] ? value : 'left'; + }, + queryCommandState:function () { + var start = this.selection.getStart(), + cell = start && domUtils.findParentByTagName(start, ["td", "th","caption"], true); + + return cell? -1:0; + } + + }; +}; + + +// plugins/font.js +/** + * 字体颜色,背景色,字号,字体,下划线,删除线 + * @file + * @since 1.2.6.1 + */ + +/** + * 字体颜色 + * @command forecolor + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } value 色值(必须十六进制) + * @example + * ```javascript + * editor.execCommand( 'forecolor', '#000' ); + * ``` + */ +/** + * 返回选区字体颜色 + * @command forecolor + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回字体颜色 + * @example + * ```javascript + * editor.queryCommandValue( 'forecolor' ); + * ``` + */ + +/** + * 字体背景颜色 + * @command backcolor + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } value 色值(必须十六进制) + * @example + * ```javascript + * editor.execCommand( 'backcolor', '#000' ); + * ``` + */ +/** + * 返回选区字体颜色 + * @command backcolor + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回字体背景颜色 + * @example + * ```javascript + * editor.queryCommandValue( 'backcolor' ); + * ``` + */ + +/** + * 字体大小 + * @command fontsize + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } value 字体大小 + * @example + * ```javascript + * editor.execCommand( 'fontsize', '14px' ); + * ``` + */ +/** + * 返回选区字体大小 + * @command fontsize + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回字体大小 + * @example + * ```javascript + * editor.queryCommandValue( 'fontsize' ); + * ``` + */ + +/** + * 字体样式 + * @command fontfamily + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } value 字体样式 + * @example + * ```javascript + * editor.execCommand( 'fontfamily', '微软雅黑' ); + * ``` + */ +/** + * 返回选区字体样式 + * @command fontfamily + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回字体样式 + * @example + * ```javascript + * editor.queryCommandValue( 'fontfamily' ); + * ``` + */ + +/** + * 字体下划线,与删除线互斥 + * @command underline + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'underline' ); + * ``` + */ + +/** + * 字体删除线,与下划线互斥 + * @command strikethrough + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'strikethrough' ); + * ``` + */ + +/** + * 字体边框 + * @command fontborder + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'fontborder' ); + * ``` + */ + +UE.plugins['font'] = function () { + var me = this, + fonts = { + 'forecolor': 'color', + 'backcolor': 'background-color', + 'fontsize': 'font-size', + 'fontfamily': 'font-family', + 'underline': 'text-decoration', + 'strikethrough': 'text-decoration', + 'fontborder': 'border' + }, + needCmd = {'underline': 1, 'strikethrough': 1, 'fontborder': 1}, + needSetChild = { + 'forecolor': 'color', + 'backcolor': 'background-color', + 'fontsize': 'font-size', + 'fontfamily': 'font-family' + + }; + me.setOpt({ + 'fontfamily': [ + { name: 'songti', val: '宋体,SimSun'}, + { name: 'yahei', val: '微软雅黑,Microsoft YaHei'}, + { name: 'kaiti', val: '楷体,楷体_GB2312, SimKai'}, + { name: 'heiti', val: '黑体, SimHei'}, + { name: 'lishu', val: '隶书, SimLi'}, + { name: 'andaleMono', val: 'andale mono'}, + { name: 'arial', val: 'arial, helvetica,sans-serif'}, + { name: 'arialBlack', val: 'arial black,avant garde'}, + { name: 'comicSansMs', val: 'comic sans ms'}, + { name: 'impact', val: 'impact,chicago'}, + { name: 'timesNewRoman', val: 'times new roman'} + ], + 'fontsize': [10, 11, 12, 14, 16, 18, 20, 24, 36] + }); + + function mergeWithParent(node){ + var parent; + while(parent = node.parentNode){ + if(parent.tagName == 'SPAN' && domUtils.getChildCount(parent,function(child){ + return !domUtils.isBookmarkNode(child) && !domUtils.isBr(child) + }) == 1) { + parent.style.cssText += node.style.cssText; + domUtils.remove(node,true); + node = parent; + + }else{ + break; + } + } + + } + function mergeChild(rng,cmdName,value){ + if(needSetChild[cmdName]){ + rng.adjustmentBoundary(); + if(!rng.collapsed && rng.startContainer.nodeType == 1){ + var start = rng.startContainer.childNodes[rng.startOffset]; + if(start && domUtils.isTagNode(start,'span')){ + var bk = rng.createBookmark(); + utils.each(domUtils.getElementsByTagName(start, 'span'), function (span) { + if (!span.parentNode || domUtils.isBookmarkNode(span))return; + if(cmdName == 'backcolor' && domUtils.getComputedStyle(span,'background-color').toLowerCase() === value){ + return; + } + domUtils.removeStyle(span,needSetChild[cmdName]); + if(span.style.cssText.replace(/^\s+$/,'').length == 0){ + domUtils.remove(span,true) + } + }); + rng.moveToBookmark(bk) + } + } + } + + } + function mergesibling(rng,cmdName,value) { + var collapsed = rng.collapsed, + bk = rng.createBookmark(), common; + if (collapsed) { + common = bk.start.parentNode; + while (dtd.$inline[common.tagName]) { + common = common.parentNode; + } + } else { + common = domUtils.getCommonAncestor(bk.start, bk.end); + } + utils.each(domUtils.getElementsByTagName(common, 'span'), function (span) { + if (!span.parentNode || domUtils.isBookmarkNode(span))return; + if (/\s*border\s*:\s*none;?\s*/i.test(span.style.cssText)) { + if(/^\s*border\s*:\s*none;?\s*$/.test(span.style.cssText)){ + domUtils.remove(span, true); + }else{ + domUtils.removeStyle(span,'border'); + } + return + } + if (/border/i.test(span.style.cssText) && span.parentNode.tagName == 'SPAN' && /border/i.test(span.parentNode.style.cssText)) { + span.style.cssText = span.style.cssText.replace(/border[^:]*:[^;]+;?/gi, ''); + } + if(!(cmdName=='fontborder' && value=='none')){ + var next = span.nextSibling; + while (next && next.nodeType == 1 && next.tagName == 'SPAN' ) { + if(domUtils.isBookmarkNode(next) && cmdName == 'fontborder') { + span.appendChild(next); + next = span.nextSibling; + continue; + } + if (next.style.cssText == span.style.cssText) { + domUtils.moveChild(next, span); + domUtils.remove(next); + } + if (span.nextSibling === next) + break; + next = span.nextSibling; + } + } + + + mergeWithParent(span); + if(browser.ie && browser.version > 8 ){ + //拷贝父亲们的特别的属性,这里只做背景颜色的处理 + var parent = domUtils.findParent(span,function(n){return n.tagName == 'SPAN' && /background-color/.test(n.style.cssText)}); + if(parent && !/background-color/.test(span.style.cssText)){ + span.style.backgroundColor = parent.style.backgroundColor; + } + } + + }); + rng.moveToBookmark(bk); + mergeChild(rng,cmdName,value) + } + + me.addInputRule(function (root) { + utils.each(root.getNodesByTagName('u s del font strike'), function (node) { + if (node.tagName == 'font') { + var cssStyle = []; + for (var p in node.attrs) { + switch (p) { + case 'size': + cssStyle.push('font-size:' + + ({ + '1':'10', + '2':'12', + '3':'16', + '4':'18', + '5':'24', + '6':'32', + '7':'48' + }[node.attrs[p]] || node.attrs[p]) + 'px'); + break; + case 'color': + cssStyle.push('color:' + node.attrs[p]); + break; + case 'face': + cssStyle.push('font-family:' + node.attrs[p]); + break; + case 'style': + cssStyle.push(node.attrs[p]); + } + } + node.attrs = { + 'style': cssStyle.join(';') + }; + } else { + var val = node.tagName == 'u' ? 'underline' : 'line-through'; + node.attrs = { + 'style': (node.getAttr('style') || '') + 'text-decoration:' + val + ';' + } + } + node.tagName = 'span'; + }); +// utils.each(root.getNodesByTagName('span'), function (node) { +// var val; +// if(val = node.getAttr('class')){ +// if(/fontstrikethrough/.test(val)){ +// node.setStyle('text-decoration','line-through'); +// if(node.attrs['class']){ +// node.attrs['class'] = node.attrs['class'].replace(/fontstrikethrough/,''); +// }else{ +// node.setAttr('class') +// } +// } +// if(/fontborder/.test(val)){ +// node.setStyle('border','1px solid #000'); +// if(node.attrs['class']){ +// node.attrs['class'] = node.attrs['class'].replace(/fontborder/,''); +// }else{ +// node.setAttr('class') +// } +// } +// } +// }); + }); +// me.addOutputRule(function(root){ +// utils.each(root.getNodesByTagName('span'), function (node) { +// var val; +// if(val = node.getStyle('text-decoration')){ +// if(/line-through/.test(val)){ +// if(node.attrs['class']){ +// node.attrs['class'] += ' fontstrikethrough'; +// }else{ +// node.setAttr('class','fontstrikethrough') +// } +// } +// +// node.setStyle('text-decoration') +// } +// if(val = node.getStyle('border')){ +// if(/1px/.test(val) && /solid/.test(val)){ +// if(node.attrs['class']){ +// node.attrs['class'] += ' fontborder'; +// +// }else{ +// node.setAttr('class','fontborder') +// } +// } +// node.setStyle('border') +// +// } +// }); +// }); + for (var p in fonts) { + (function (cmd, style) { + UE.commands[cmd] = { + execCommand: function (cmdName, value) { + value = value || (this.queryCommandState(cmdName) ? 'none' : cmdName == 'underline' ? 'underline' : + cmdName == 'fontborder' ? '1px solid #000' : + 'line-through'); + var me = this, + range = this.selection.getRange(), + text; + + if (value == 'default') { + + if (range.collapsed) { + text = me.document.createTextNode('font'); + range.insertNode(text).select(); + + } + me.execCommand('removeFormat', 'span,a', style); + if (text) { + range.setStartBefore(text).collapse(true); + domUtils.remove(text); + } + mergesibling(range,cmdName,value); + range.select() + } else { + if (!range.collapsed) { + if (needCmd[cmd] && me.queryCommandValue(cmd)) { + me.execCommand('removeFormat', 'span,a', style); + } + range = me.selection.getRange(); + + range.applyInlineStyle('span', {'style': style + ':' + value}); + mergesibling(range, cmdName,value); + range.select(); + } else { + + var span = domUtils.findParentByTagName(range.startContainer, 'span', true); + text = me.document.createTextNode('font'); + if (span && !span.children.length && !span[browser.ie ? 'innerText' : 'textContent'].replace(fillCharReg, '').length) { + //for ie hack when enter + range.insertNode(text); + if (needCmd[cmd]) { + range.selectNode(text).select(); + me.execCommand('removeFormat', 'span,a', style, null); + + span = domUtils.findParentByTagName(text, 'span', true); + range.setStartBefore(text); + + } + span && (span.style.cssText += ';' + style + ':' + value); + range.collapse(true).select(); + + + } else { + range.insertNode(text); + range.selectNode(text).select(); + span = range.document.createElement('span'); + + if (needCmd[cmd]) { + //a标签内的不处理跳过 + if (domUtils.findParentByTagName(text, 'a', true)) { + range.setStartBefore(text).setCursor(); + domUtils.remove(text); + return; + } + me.execCommand('removeFormat', 'span,a', style); + } + + span.style.cssText = style + ':' + value; + + + text.parentNode.insertBefore(span, text); + //修复,span套span 但样式不继承的问题 + if (!browser.ie || browser.ie && browser.version == 9) { + var spanParent = span.parentNode; + while (!domUtils.isBlockElm(spanParent)) { + if (spanParent.tagName == 'SPAN') { + //opera合并style不会加入";" + span.style.cssText = spanParent.style.cssText + ";" + span.style.cssText; + } + spanParent = spanParent.parentNode; + } + } + + + if (opera) { + setTimeout(function () { + range.setStart(span, 0).collapse(true); + mergesibling(range, cmdName,value); + range.select(); + }); + } else { + range.setStart(span, 0).collapse(true); + mergesibling(range,cmdName,value); + range.select(); + } + + //trace:981 + //domUtils.mergeToParent(span) + } + domUtils.remove(text); + } + + + } + return true; + }, + queryCommandValue: function (cmdName) { + var startNode = this.selection.getStart(); + + //trace:946 + if (cmdName == 'underline' || cmdName == 'strikethrough') { + var tmpNode = startNode, value; + while (tmpNode && !domUtils.isBlockElm(tmpNode) && !domUtils.isBody(tmpNode)) { + if (tmpNode.nodeType == 1) { + value = domUtils.getComputedStyle(tmpNode, style); + if (value != 'none') { + return value; + } + } + + tmpNode = tmpNode.parentNode; + } + return 'none'; + } + if (cmdName == 'fontborder') { + var tmp = startNode, val; + while (tmp && dtd.$inline[tmp.tagName]) { + if (val = domUtils.getComputedStyle(tmp, 'border')) { + + if (/1px/.test(val) && /solid/.test(val)) { + return val; + } + } + tmp = tmp.parentNode; + } + return '' + } + + if( cmdName == 'FontSize' ) { + var styleVal = domUtils.getComputedStyle(startNode, style), + tmp = /^([\d\.]+)(\w+)$/.exec( styleVal ); + + if( tmp ) { + + return Math.floor( tmp[1] ) + tmp[2]; + + } + + return styleVal; + + } + + return domUtils.getComputedStyle(startNode, style); + }, + queryCommandState: function (cmdName) { + if (!needCmd[cmdName]) + return 0; + var val = this.queryCommandValue(cmdName); + if (cmdName == 'fontborder') { + return /1px/.test(val) && /solid/.test(val) + } else { + return cmdName == 'underline' ? /underline/.test(val) : /line\-through/.test(val); + + } + + } + }; + })(p, fonts[p]); + } +}; + +// plugins/link.js +/** + * 超链接 + * @file + * @since 1.2.6.1 + */ + +/** + * 插入超链接 + * @command link + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { Object } options 设置自定义属性,例如:url、title、target + * @example + * ```javascript + * editor.execCommand( 'link', '{ + * url:'ueditor.baidu.com', + * title:'ueditor', + * target:'_blank' + * }' ); + * ``` + */ +/** + * 返回当前选中的第一个超链接节点 + * @command link + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { Element } 超链接节点 + * @example + * ```javascript + * editor.queryCommandValue( 'link' ); + * ``` + */ + +/** + * 取消超链接 + * @command unlink + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'unlink'); + * ``` + */ + +UE.plugins['link'] = function(){ + function optimize( range ) { + var start = range.startContainer,end = range.endContainer; + + if ( start = domUtils.findParentByTagName( start, 'a', true ) ) { + range.setStartBefore( start ); + } + if ( end = domUtils.findParentByTagName( end, 'a', true ) ) { + range.setEndAfter( end ); + } + } + + + UE.commands['unlink'] = { + execCommand : function() { + var range = this.selection.getRange(), + bookmark; + if(range.collapsed && !domUtils.findParentByTagName( range.startContainer, 'a', true )){ + return; + } + bookmark = range.createBookmark(); + optimize( range ); + range.removeInlineStyle( 'a' ).moveToBookmark( bookmark ).select(); + }, + queryCommandState : function(){ + return !this.highlight && this.queryCommandValue('link') ? 0 : -1; + } + + }; + function doLink(range,opt,me){ + var rngClone = range.cloneRange(), + link = me.queryCommandValue('link'); + optimize( range = range.adjustmentBoundary() ); + var start = range.startContainer; + if(start.nodeType == 1 && link){ + start = start.childNodes[range.startOffset]; + if(start && start.nodeType == 1 && start.tagName == 'A' && /^(?:https?|ftp|file)\s*:\s*\/\//.test(start[browser.ie?'innerText':'textContent'])){ + start[browser.ie ? 'innerText' : 'textContent'] = utils.html(opt.textValue||opt.href); + + } + } + if( !rngClone.collapsed || link){ + range.removeInlineStyle( 'a' ); + rngClone = range.cloneRange(); + } + + if ( rngClone.collapsed ) { + var a = range.document.createElement( 'a'), + text = ''; + if(opt.textValue){ + + text = utils.html(opt.textValue); + delete opt.textValue; + }else{ + text = utils.html(opt.href); + + } + domUtils.setAttributes( a, opt ); + start = domUtils.findParentByTagName( rngClone.startContainer, 'a', true ); + if(start && domUtils.isInNodeEndBoundary(rngClone,start)){ + range.setStartAfter(start).collapse(true); + + } + a[browser.ie ? 'innerText' : 'textContent'] = text; + range.insertNode(a).selectNode( a ); + } else { + range.applyInlineStyle( 'a', opt ); + + } + } + UE.commands['link'] = { + execCommand : function( cmdName, opt ) { + var range; + opt._href && (opt._href = utils.unhtml(opt._href,/[<">]/g)); + opt.href && (opt.href = utils.unhtml(opt.href,/[<">]/g)); + opt.textValue && (opt.textValue = utils.unhtml(opt.textValue,/[<">]/g)); + doLink(range=this.selection.getRange(),opt,this); + //闭合都不加占位符,如果加了会在a后边多个占位符节点,导致a是图片背景组成的列表,出现空白问题 + range.collapse().select(true); + + }, + queryCommandValue : function() { + var range = this.selection.getRange(), + node; + if ( range.collapsed ) { +// node = this.selection.getStart(); + //在ie下getstart()取值偏上了 + node = range.startContainer; + node = node.nodeType == 1 ? node : node.parentNode; + + if ( node && (node = domUtils.findParentByTagName( node, 'a', true )) && ! domUtils.isInNodeEndBoundary(range,node)) { + + return node; + } + } else { + //trace:1111 如果是

          xx

          startContainer是p就会找不到a + range.shrinkBoundary(); + var start = range.startContainer.nodeType == 3 || !range.startContainer.childNodes[range.startOffset] ? range.startContainer : range.startContainer.childNodes[range.startOffset], + end = range.endContainer.nodeType == 3 || range.endOffset == 0 ? range.endContainer : range.endContainer.childNodes[range.endOffset-1], + common = range.getCommonAncestor(); + node = domUtils.findParentByTagName( common, 'a', true ); + if ( !node && common.nodeType == 1){ + + var as = common.getElementsByTagName( 'a' ), + ps,pe; + + for ( var i = 0,ci; ci = as[i++]; ) { + ps = domUtils.getPosition( ci, start ),pe = domUtils.getPosition( ci,end); + if ( (ps & domUtils.POSITION_FOLLOWING || ps & domUtils.POSITION_CONTAINS) + && + (pe & domUtils.POSITION_PRECEDING || pe & domUtils.POSITION_CONTAINS) + ) { + node = ci; + break; + } + } + } + return node; + } + + }, + queryCommandState : function() { + //判断如果是视频的话连接不可用 + //fix 853 + var img = this.selection.getRange().getClosedNode(), + flag = img && (img.className == "edui-faked-video" || img.className.indexOf("edui-upload-video")!=-1); + return flag ? -1 : 0; + } + }; +}; + +// plugins/iframe.js +///import core +///import plugins\inserthtml.js +///commands 插入框架 +///commandsName InsertFrame +///commandsTitle 插入Iframe +///commandsDialog dialogs\insertframe + +UE.plugins['insertframe'] = function() { + var me =this; + function deleteIframe(){ + me._iframe && delete me._iframe; + } + + me.addListener("selectionchange",function(){ + deleteIframe(); + }); + +}; + + + +// plugins/scrawl.js +///import core +///commands 涂鸦 +///commandsName Scrawl +///commandsTitle 涂鸦 +///commandsDialog dialogs\scrawl +UE.commands['scrawl'] = { + queryCommandState : function(){ + return ( browser.ie && browser.version <= 8 ) ? -1 :0; + } +}; + + +// plugins/removeformat.js +/** + * 清除格式 + * @file + * @since 1.2.6.1 + */ + +/** + * 清除文字样式 + * @command removeformat + * @method execCommand + * @param { String } cmd 命令字符串 + * @param {String} tags 以逗号隔开的标签。如:strong + * @param {String} style 样式如:color + * @param {String} attrs 属性如:width + * @example + * ```javascript + * editor.execCommand( 'removeformat', 'strong','color','width' ); + * ``` + */ + +UE.plugins['removeformat'] = function(){ + var me = this; + me.setOpt({ + 'removeFormatTags': 'b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var', + 'removeFormatAttributes':'class,style,lang,width,height,align,hspace,valign' + }); + me.commands['removeformat'] = { + execCommand : function( cmdName, tags, style, attrs,notIncludeA ) { + + var tagReg = new RegExp( '^(?:' + (tags || this.options.removeFormatTags).replace( /,/g, '|' ) + ')$', 'i' ) , + removeFormatAttributes = style ? [] : (attrs || this.options.removeFormatAttributes).split( ',' ), + range = new dom.Range( this.document ), + bookmark,node,parent, + filter = function( node ) { + return node.nodeType == 1; + }; + + function isRedundantSpan (node) { + if (node.nodeType == 3 || node.tagName.toLowerCase() != 'span'){ + return 0; + } + if (browser.ie) { + //ie 下判断实效,所以只能简单用style来判断 + //return node.style.cssText == '' ? 1 : 0; + var attrs = node.attributes; + if ( attrs.length ) { + for ( var i = 0,l = attrs.length; i + var node = range.startContainer, + tmp, + collapsed = range.collapsed; + while(node.nodeType == 1 && domUtils.isEmptyNode(node) && dtd.$removeEmpty[node.tagName]){ + tmp = node.parentNode; + range.setStartBefore(node); + //trace:937 + //更新结束边界 + if(range.startContainer === range.endContainer){ + range.endOffset--; + } + domUtils.remove(node); + node = tmp; + } + + if(!collapsed){ + node = range.endContainer; + while(node.nodeType == 1 && domUtils.isEmptyNode(node) && dtd.$removeEmpty[node.tagName]){ + tmp = node.parentNode; + range.setEndBefore(node); + domUtils.remove(node); + + node = tmp; + } + + + } + } + + + + range = this.selection.getRange(); + doRemove( range ); + range.select(); + + } + + }; + +}; + + +// plugins/blockquote.js +/** + * 添加引用 + * @file + * @since 1.2.6.1 + */ + +/** + * 添加引用 + * @command blockquote + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'blockquote' ); + * ``` + */ + +/** + * 添加引用 + * @command blockquote + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { Object } attrs 节点属性 + * @example + * ```javascript + * editor.execCommand( 'blockquote',{ + * style: "color: red;" + * } ); + * ``` + */ + + +UE.plugins['blockquote'] = function(){ + var me = this; + function getObj(editor){ + return domUtils.filterNodeList(editor.selection.getStartElementPath(),'blockquote'); + } + me.commands['blockquote'] = { + execCommand : function( cmdName, attrs ) { + var range = this.selection.getRange(), + obj = getObj(this), + blockquote = dtd.blockquote, + bookmark = range.createBookmark(); + + if ( obj ) { + + var start = range.startContainer, + startBlock = domUtils.isBlockElm(start) ? start : domUtils.findParent(start,function(node){return domUtils.isBlockElm(node)}), + + end = range.endContainer, + endBlock = domUtils.isBlockElm(end) ? end : domUtils.findParent(end,function(node){return domUtils.isBlockElm(node)}); + + //处理一下li + startBlock = domUtils.findParentByTagName(startBlock,'li',true) || startBlock; + endBlock = domUtils.findParentByTagName(endBlock,'li',true) || endBlock; + + + if(startBlock.tagName == 'LI' || startBlock.tagName == 'TD' || startBlock === obj || domUtils.isBody(startBlock)){ + domUtils.remove(obj,true); + }else{ + domUtils.breakParent(startBlock,obj); + } + + if(startBlock !== endBlock){ + obj = domUtils.findParentByTagName(endBlock,'blockquote'); + if(obj){ + if(endBlock.tagName == 'LI' || endBlock.tagName == 'TD'|| domUtils.isBody(endBlock)){ + obj.parentNode && domUtils.remove(obj,true); + }else{ + domUtils.breakParent(endBlock,obj); + } + + } + } + + var blockquotes = domUtils.getElementsByTagName(this.document,'blockquote'); + for(var i=0,bi;bi=blockquotes[i++];){ + if(!bi.childNodes.length){ + domUtils.remove(bi); + }else if(domUtils.getPosition(bi,startBlock)&domUtils.POSITION_FOLLOWING && domUtils.getPosition(bi,endBlock)&domUtils.POSITION_PRECEDING){ + domUtils.remove(bi,true); + } + } + + + + + } else { + + var tmpRange = range.cloneRange(), + node = tmpRange.startContainer.nodeType == 1 ? tmpRange.startContainer : tmpRange.startContainer.parentNode, + preNode = node, + doEnd = 1; + + //调整开始 + while ( 1 ) { + if ( domUtils.isBody(node) ) { + if ( preNode !== node ) { + if ( range.collapsed ) { + tmpRange.selectNode( preNode ); + doEnd = 0; + } else { + tmpRange.setStartBefore( preNode ); + } + }else{ + tmpRange.setStart(node,0); + } + + break; + } + if ( !blockquote[node.tagName] ) { + if ( range.collapsed ) { + tmpRange.selectNode( preNode ); + } else{ + tmpRange.setStartBefore( preNode); + } + break; + } + + preNode = node; + node = node.parentNode; + } + + //调整结束 + if ( doEnd ) { + preNode = node = node = tmpRange.endContainer.nodeType == 1 ? tmpRange.endContainer : tmpRange.endContainer.parentNode; + while ( 1 ) { + + if ( domUtils.isBody( node ) ) { + if ( preNode !== node ) { + + tmpRange.setEndAfter( preNode ); + + } else { + tmpRange.setEnd( node, node.childNodes.length ); + } + + break; + } + if ( !blockquote[node.tagName] ) { + tmpRange.setEndAfter( preNode ); + break; + } + + preNode = node; + node = node.parentNode; + } + + } + + + node = range.document.createElement( 'blockquote' ); + domUtils.setAttributes( node, attrs ); + node.appendChild( tmpRange.extractContents() ); + tmpRange.insertNode( node ); + //去除重复的 + var childs = domUtils.getElementsByTagName(node,'blockquote'); + for(var i=0,ci;ci=childs[i++];){ + if(ci.parentNode){ + domUtils.remove(ci,true); + } + } + + } + range.moveToBookmark( bookmark ).select(); + }, + queryCommandState : function() { + return getObj(this) ? 1 : 0; + } + }; +}; + + + +// plugins/convertcase.js +/** + * 大小写转换 + * @file + * @since 1.2.6.1 + */ + +/** + * 把选区内文本变大写,与“tolowercase”命令互斥 + * @command touppercase + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'touppercase' ); + * ``` + */ + +/** + * 把选区内文本变小写,与“touppercase”命令互斥 + * @command tolowercase + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'tolowercase' ); + * ``` + */ +UE.commands['touppercase'] = +UE.commands['tolowercase'] = { + execCommand:function (cmd) { + var me = this; + var rng = me.selection.getRange(); + if(rng.collapsed){ + return rng; + } + var bk = rng.createBookmark(), + bkEnd = bk.end, + filterFn = function( node ) { + return !domUtils.isBr(node) && !domUtils.isWhitespace( node ); + }, + curNode = domUtils.getNextDomNode( bk.start, false, filterFn ); + while ( curNode && (domUtils.getPosition( curNode, bkEnd ) & domUtils.POSITION_PRECEDING) ) { + + if ( curNode.nodeType == 3 ) { + curNode.nodeValue = curNode.nodeValue[cmd == 'touppercase' ? 'toUpperCase' : 'toLowerCase'](); + } + curNode = domUtils.getNextDomNode( curNode, true, filterFn ); + if(curNode === bkEnd){ + break; + } + + } + rng.moveToBookmark(bk).select(); + } +}; + + + +// plugins/indent.js +/** + * 首行缩进 + * @file + * @since 1.2.6.1 + */ + +/** + * 缩进 + * @command indent + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'indent' ); + * ``` + */ +UE.commands['indent'] = { + execCommand : function() { + var me = this,value = me.queryCommandState("indent") ? "0em" : (me.options.indentValue || '2em'); + me.execCommand('Paragraph','p',{style:'text-indent:'+ value}); + }, + queryCommandState : function() { + var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),'p h1 h2 h3 h4 h5 h6'); + return pN && pN.style.textIndent && parseInt(pN.style.textIndent) ? 1 : 0; + } + +}; + + +// plugins/print.js +/** + * 打印 + * @file + * @since 1.2.6.1 + */ + +/** + * 打印 + * @command print + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'print' ); + * ``` + */ +UE.commands['print'] = { + execCommand : function(){ + this.window.print(); + }, + notNeedUndo : 1 +}; + + + +// plugins/preview.js +/** + * 预览 + * @file + * @since 1.2.6.1 + */ + +/** + * 预览 + * @command preview + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'preview' ); + * ``` + */ +UE.commands['preview'] = { + execCommand : function(){ + var w = window.open('', '_blank', ''), + d = w.document; + d.open(); + d.write('
          '+this.getContent(null,null,true)+'
          '); + d.close(); + }, + notNeedUndo : 1 +}; + + +// plugins/selectall.js +/** + * 全选 + * @file + * @since 1.2.6.1 + */ + +/** + * 选中所有内容 + * @command selectall + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'selectall' ); + * ``` + */ +UE.plugins['selectall'] = function(){ + var me = this; + me.commands['selectall'] = { + execCommand : function(){ + //去掉了原生的selectAll,因为会出现报错和当内容为空时,不能出现闭合状态的光标 + var me = this,body = me.body, + range = me.selection.getRange(); + range.selectNodeContents(body); + if(domUtils.isEmptyBlock(body)){ + //opera不能自动合并到元素的里边,要手动处理一下 + if(browser.opera && body.firstChild && body.firstChild.nodeType == 1){ + range.setStartAtFirst(body.firstChild); + } + range.collapse(true); + } + range.select(true); + }, + notNeedUndo : 1 + }; + + + //快捷键 + me.addshortcutkey({ + "selectAll" : "ctrl+65" + }); +}; + + +// plugins/paragraph.js +/** + * 段落样式 + * @file + * @since 1.2.6.1 + */ + +/** + * 段落格式 + * @command paragraph + * @method execCommand + * @param { String } cmd 命令字符串 + * @param {String} style 标签值为:'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6' + * @param {Object} attrs 标签的属性 + * @example + * ```javascript + * editor.execCommand( 'Paragraph','h1','{ + * class:'test' + * }' ); + * ``` + */ + +/** + * 返回选区内节点标签名 + * @command paragraph + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 节点标签名 + * @example + * ```javascript + * editor.queryCommandValue( 'Paragraph' ); + * ``` + */ + +UE.plugins['paragraph'] = function() { + var me = this, + block = domUtils.isBlockElm, + notExchange = ['TD','LI','PRE'], + + doParagraph = function(range,style,attrs,sourceCmdName){ + var bookmark = range.createBookmark(), + filterFn = function( node ) { + return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' && !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace( node ); + }, + para; + + range.enlarge( true ); + var bookmark2 = range.createBookmark(), + current = domUtils.getNextDomNode( bookmark2.start, false, filterFn ), + tmpRange = range.cloneRange(), + tmpNode; + while ( current && !(domUtils.getPosition( current, bookmark2.end ) & domUtils.POSITION_FOLLOWING) ) { + if ( current.nodeType == 3 || !block( current ) ) { + tmpRange.setStartBefore( current ); + while ( current && current !== bookmark2.end && !block( current ) ) { + tmpNode = current; + current = domUtils.getNextDomNode( current, false, null, function( node ) { + return !block( node ); + } ); + } + tmpRange.setEndAfter( tmpNode ); + + para = range.document.createElement( style ); + if(attrs){ + domUtils.setAttributes(para,attrs); + if(sourceCmdName && sourceCmdName == 'customstyle' && attrs.style){ + para.style.cssText = attrs.style; + } + } + para.appendChild( tmpRange.extractContents() ); + //需要内容占位 + if(domUtils.isEmptyNode(para)){ + domUtils.fillChar(range.document,para); + + } + + tmpRange.insertNode( para ); + + var parent = para.parentNode; + //如果para上一级是一个block元素且不是body,td就删除它 + if ( block( parent ) && !domUtils.isBody( para.parentNode ) && utils.indexOf(notExchange,parent.tagName)==-1) { + //存储dir,style + if(!(sourceCmdName && sourceCmdName == 'customstyle')){ + parent.getAttribute('dir') && para.setAttribute('dir',parent.getAttribute('dir')); + //trace:1070 + parent.style.cssText && (para.style.cssText = parent.style.cssText + ';' + para.style.cssText); + //trace:1030 + parent.style.textAlign && !para.style.textAlign && (para.style.textAlign = parent.style.textAlign); + parent.style.textIndent && !para.style.textIndent && (para.style.textIndent = parent.style.textIndent); + parent.style.padding && !para.style.padding && (para.style.padding = parent.style.padding); + } + + //trace:1706 选择的就是h1-6要删除 + if(attrs && /h\d/i.test(parent.tagName) && !/h\d/i.test(para.tagName) ){ + domUtils.setAttributes(parent,attrs); + if(sourceCmdName && sourceCmdName == 'customstyle' && attrs.style){ + parent.style.cssText = attrs.style; + } + domUtils.remove(para,true); + para = parent; + }else{ + domUtils.remove( para.parentNode, true ); + } + + } + if( utils.indexOf(notExchange,parent.tagName)!=-1){ + current = parent; + }else{ + current = para; + } + + + current = domUtils.getNextDomNode( current, false, filterFn ); + } else { + current = domUtils.getNextDomNode( current, true, filterFn ); + } + } + return range.moveToBookmark( bookmark2 ).moveToBookmark( bookmark ); + }; + me.setOpt('paragraph',{'p':'', 'h1':'', 'h2':'', 'h3':'', 'h4':'', 'h5':'', 'h6':''}); + me.commands['paragraph'] = { + execCommand : function( cmdName, style,attrs,sourceCmdName ) { + var range = this.selection.getRange(); + //闭合时单独处理 + if(range.collapsed){ + var txt = this.document.createTextNode('p'); + range.insertNode(txt); + //去掉冗余的fillchar + if(browser.ie){ + var node = txt.previousSibling; + if(node && domUtils.isWhitespace(node)){ + domUtils.remove(node); + } + node = txt.nextSibling; + if(node && domUtils.isWhitespace(node)){ + domUtils.remove(node); + } + } + + } + range = doParagraph(range,style,attrs,sourceCmdName); + if(txt){ + range.setStartBefore(txt).collapse(true); + pN = txt.parentNode; + + domUtils.remove(txt); + + if(domUtils.isBlockElm(pN)&&domUtils.isEmptyNode(pN)){ + domUtils.fillNode(this.document,pN); + } + + } + + if(browser.gecko && range.collapsed && range.startContainer.nodeType == 1){ + var child = range.startContainer.childNodes[range.startOffset]; + if(child && child.nodeType == 1 && child.tagName.toLowerCase() == style){ + range.setStart(child,0).collapse(true); + } + } + //trace:1097 原来有true,原因忘了,但去了就不能清除多余的占位符了 + range.select(); + + + return true; + }, + queryCommandValue : function() { + var node = domUtils.filterNodeList(this.selection.getStartElementPath(),'p h1 h2 h3 h4 h5 h6'); + return node ? node.tagName.toLowerCase() : ''; + } + }; +}; + + +// plugins/directionality.js +/** + * 设置文字输入的方向的插件 + * @file + * @since 1.2.6.1 + */ +(function() { + var block = domUtils.isBlockElm , + getObj = function(editor){ +// var startNode = editor.selection.getStart(), +// parents; +// if ( startNode ) { +// //查找所有的是block的父亲节点 +// parents = domUtils.findParents( startNode, true, block, true ); +// for ( var i = 0,ci; ci = parents[i++]; ) { +// if ( ci.getAttribute( 'dir' ) ) { +// return ci; +// } +// } +// } + return domUtils.filterNodeList(editor.selection.getStartElementPath(),function(n){return n && n.nodeType == 1 && n.getAttribute('dir')}); + + }, + doDirectionality = function(range,editor,forward){ + + var bookmark, + filterFn = function( node ) { + return node.nodeType == 1 ? !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace(node); + }, + + obj = getObj( editor ); + + if ( obj && range.collapsed ) { + obj.setAttribute( 'dir', forward ); + return range; + } + bookmark = range.createBookmark(); + range.enlarge( true ); + var bookmark2 = range.createBookmark(), + current = domUtils.getNextDomNode( bookmark2.start, false, filterFn ), + tmpRange = range.cloneRange(), + tmpNode; + while ( current && !(domUtils.getPosition( current, bookmark2.end ) & domUtils.POSITION_FOLLOWING) ) { + if ( current.nodeType == 3 || !block( current ) ) { + tmpRange.setStartBefore( current ); + while ( current && current !== bookmark2.end && !block( current ) ) { + tmpNode = current; + current = domUtils.getNextDomNode( current, false, null, function( node ) { + return !block( node ); + } ); + } + tmpRange.setEndAfter( tmpNode ); + var common = tmpRange.getCommonAncestor(); + if ( !domUtils.isBody( common ) && block( common ) ) { + //遍历到了block节点 + common.setAttribute( 'dir', forward ); + current = common; + } else { + //没有遍历到,添加一个block节点 + var p = range.document.createElement( 'p' ); + p.setAttribute( 'dir', forward ); + var frag = tmpRange.extractContents(); + p.appendChild( frag ); + tmpRange.insertNode( p ); + current = p; + } + + current = domUtils.getNextDomNode( current, false, filterFn ); + } else { + current = domUtils.getNextDomNode( current, true, filterFn ); + } + } + return range.moveToBookmark( bookmark2 ).moveToBookmark( bookmark ); + }; + + /** + * 文字输入方向 + * @command directionality + * @method execCommand + * @param { String } cmdName 命令字符串 + * @param { String } forward 传入'ltr'表示从左向右输入,传入'rtl'表示从右向左输入 + * @example + * ```javascript + * editor.execCommand( 'directionality', 'ltr'); + * ``` + */ + + /** + * 查询当前选区的文字输入方向 + * @command directionality + * @method queryCommandValue + * @param { String } cmdName 命令字符串 + * @return { String } 返回'ltr'表示从左向右输入,返回'rtl'表示从右向左输入 + * @example + * ```javascript + * editor.queryCommandValue( 'directionality'); + * ``` + */ + UE.commands['directionality'] = { + execCommand : function( cmdName,forward ) { + var range = this.selection.getRange(); + //闭合时单独处理 + if(range.collapsed){ + var txt = this.document.createTextNode('d'); + range.insertNode(txt); + } + doDirectionality(range,this,forward); + if(txt){ + range.setStartBefore(txt).collapse(true); + domUtils.remove(txt); + } + + range.select(); + return true; + }, + queryCommandValue : function() { + var node = getObj(this); + return node ? node.getAttribute('dir') : 'ltr'; + } + }; +})(); + + + +// plugins/horizontal.js +/** + * 插入分割线插件 + * @file + * @since 1.2.6.1 + */ + +/** + * 插入分割线 + * @command horizontal + * @method execCommand + * @param { String } cmdName 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'horizontal' ); + * ``` + */ +UE.plugins['horizontal'] = function(){ + var me = this; + me.commands['horizontal'] = { + execCommand : function( cmdName ) { + var me = this; + if(me.queryCommandState(cmdName)!==-1){ + me.execCommand('insertHtml','
          '); + var range = me.selection.getRange(), + start = range.startContainer; + if(start.nodeType == 1 && !start.childNodes[range.startOffset] ){ + + var tmp; + if(tmp = start.childNodes[range.startOffset - 1]){ + if(tmp.nodeType == 1 && tmp.tagName == 'HR'){ + if(me.options.enterTag == 'p'){ + tmp = me.document.createElement('p'); + range.insertNode(tmp); + range.setStart(tmp,0).setCursor(); + + }else{ + tmp = me.document.createElement('br'); + range.insertNode(tmp); + range.setStartBefore(tmp).setCursor(); + } + } + } + + } + return true; + } + + }, + //边界在table里不能加分隔线 + queryCommandState : function() { + return domUtils.filterNodeList(this.selection.getStartElementPath(),'table') ? -1 : 0; + } + }; +// me.addListener('delkeyup',function(){ +// var rng = this.selection.getRange(); +// if(browser.ie && browser.version > 8){ +// rng.txtToElmBoundary(true); +// if(domUtils.isStartInblock(rng)){ +// var tmpNode = rng.startContainer; +// var pre = tmpNode.previousSibling; +// if(pre && domUtils.isTagNode(pre,'hr')){ +// domUtils.remove(pre); +// rng.select(); +// return; +// } +// } +// } +// if(domUtils.isBody(rng.startContainer)){ +// var hr = rng.startContainer.childNodes[rng.startOffset -1]; +// if(hr && hr.nodeName == 'HR'){ +// var next = hr.nextSibling; +// if(next){ +// rng.setStart(next,0) +// }else if(hr.previousSibling){ +// rng.setStartAtLast(hr.previousSibling) +// }else{ +// var p = this.document.createElement('p'); +// hr.parentNode.insertBefore(p,hr); +// domUtils.fillNode(this.document,p); +// rng.setStart(p,0); +// } +// domUtils.remove(hr); +// rng.setCursor(false,true); +// } +// } +// }) + me.addListener('delkeydown',function(name,evt){ + var rng = this.selection.getRange(); + rng.txtToElmBoundary(true); + if(domUtils.isStartInblock(rng)){ + var tmpNode = rng.startContainer; + var pre = tmpNode.previousSibling; + if(pre && domUtils.isTagNode(pre,'hr')){ + domUtils.remove(pre); + rng.select(); + domUtils.preventDefault(evt); + return true; + + } + } + + }) +}; + + + +// plugins/time.js +/** + * 插入时间和日期 + * @file + * @since 1.2.6.1 + */ + +/** + * 插入时间,默认格式:12:59:59 + * @command time + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'time'); + * ``` + */ + +/** + * 插入日期,默认格式:2013-08-30 + * @command date + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'date'); + * ``` + */ +UE.commands['time'] = UE.commands["date"] = { + execCommand : function(cmd, format){ + var date = new Date; + + function formatTime(date, format) { + var hh = ('0' + date.getHours()).slice(-2), + ii = ('0' + date.getMinutes()).slice(-2), + ss = ('0' + date.getSeconds()).slice(-2); + format = format || 'hh:ii:ss'; + return format.replace(/hh/ig, hh).replace(/ii/ig, ii).replace(/ss/ig, ss); + } + function formatDate(date, format) { + var yyyy = ('000' + date.getFullYear()).slice(-4), + yy = yyyy.slice(-2), + mm = ('0' + (date.getMonth()+1)).slice(-2), + dd = ('0' + date.getDate()).slice(-2); + format = format || 'yyyy-mm-dd'; + return format.replace(/yyyy/ig, yyyy).replace(/yy/ig, yy).replace(/mm/ig, mm).replace(/dd/ig, dd); + } + + this.execCommand('insertHtml',cmd == "time" ? formatTime(date, format):formatDate(date, format) ); + } +}; + + +// plugins/rowspacing.js +/** + * 段前段后间距插件 + * @file + * @since 1.2.6.1 + */ + +/** + * 设置段间距 + * @command rowspacing + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } value 段间距的值,以px为单位 + * @param { String } dir 间距位置,top或bottom,分别表示段前和段后 + * @example + * ```javascript + * editor.execCommand( 'rowspacing', '10', 'top' ); + * ``` + */ + +UE.plugins['rowspacing'] = function(){ + var me = this; + me.setOpt({ + 'rowspacingtop':['5', '10', '15', '20', '25'], + 'rowspacingbottom':['5', '10', '15', '20', '25'] + + }); + me.commands['rowspacing'] = { + execCommand : function( cmdName,value,dir ) { + this.execCommand('paragraph','p',{style:'margin-'+dir+':'+value + 'px'}); + return true; + }, + queryCommandValue : function(cmdName,dir) { + var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),function(node){return domUtils.isBlockElm(node) }), + value; + //trace:1026 + if(pN){ + value = domUtils.getComputedStyle(pN,'margin-'+dir).replace(/[^\d]/g,''); + return !value ? 0 : value; + } + return 0; + + } + }; +}; + + + + +// plugins/lineheight.js +/** + * 设置行内间距 + * @file + * @since 1.2.6.1 + */ +UE.plugins['lineheight'] = function(){ + var me = this; + me.setOpt({'lineheight':['1', '1.5','1.75','2', '3', '4', '5']}); + + /** + * 行距 + * @command lineheight + * @method execCommand + * @param { String } cmdName 命令字符串 + * @param { String } value 传入的行高值, 该值是当前字体的倍数, 例如: 1.5, 1.75 + * @example + * ```javascript + * editor.execCommand( 'lineheight', 1.5); + * ``` + */ + /** + * 查询当前选区内容的行高大小 + * @command lineheight + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回当前行高大小 + * @example + * ```javascript + * editor.queryCommandValue( 'lineheight' ); + * ``` + */ + + me.commands['lineheight'] = { + execCommand : function( cmdName,value ) { + this.execCommand('paragraph','p',{style:'line-height:'+ (value == "1" ? "normal" : value + 'em') }); + return true; + }, + queryCommandValue : function() { + var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),function(node){return domUtils.isBlockElm(node)}); + if(pN){ + var value = domUtils.getComputedStyle(pN,'line-height'); + return value == 'normal' ? 1 : value.replace(/[^\d.]*/ig,""); + } + } + }; +}; + + + + +// plugins/insertcode.js +/** + * 插入代码插件 + * @file + * @since 1.2.6.1 + */ + +UE.plugins['insertcode'] = function() { + var me = this; + me.ready(function(){ + utils.cssRule('pre','pre{margin:.5em 0;padding:.4em .6em;border-radius:8px;background:#f8f8f8;}', + me.document) + }); + me.setOpt('insertcode',{ + 'as3':'ActionScript3', + 'bash':'Bash/Shell', + 'cpp':'C/C++', + 'css':'Css', + 'cf':'CodeFunction', + 'c#':'C#', + 'delphi':'Delphi', + 'diff':'Diff', + 'erlang':'Erlang', + 'groovy':'Groovy', + 'html':'Html', + 'java':'Java', + 'jfx':'JavaFx', + 'js':'Javascript', + 'pl':'Perl', + 'php':'Php', + 'plain':'Plain Text', + 'ps':'PowerShell', + 'python':'Python', + 'ruby':'Ruby', + 'scala':'Scala', + 'sql':'Sql', + 'vb':'Vb', + 'xml':'Xml' + }); + + /** + * 插入代码 + * @command insertcode + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } lang 插入代码的语言 + * @example + * ```javascript + * editor.execCommand( 'insertcode', 'javascript' ); + * ``` + */ + + /** + * 如果选区所在位置是插入插入代码区域,返回代码的语言 + * @command insertcode + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回代码的语言 + * @example + * ```javascript + * editor.queryCommandValue( 'insertcode' ); + * ``` + */ + + me.commands['insertcode'] = { + execCommand : function(cmd,lang){ + var me = this, + rng = me.selection.getRange(), + pre = domUtils.findParentByTagName(rng.startContainer,'pre',true); + if(pre){ + pre.className = 'brush:'+lang+';toolbar:false;'; + }else{ + var code = ''; + if(rng.collapsed){ + code = browser.ie && browser.ie11below ? (browser.version <= 8 ? ' ':''):'
          '; + }else{ + var frag = rng.extractContents(); + var div = me.document.createElement('div'); + div.appendChild(frag); + + utils.each(UE.filterNode(UE.htmlparser(div.innerHTML.replace(/[\r\t]/g,'')),me.options.filterTxtRules).children,function(node){ + if(browser.ie && browser.ie11below && browser.version > 8){ + + if(node.type =='element'){ + if(node.tagName == 'br'){ + code += '\n' + }else if(!dtd.$empty[node.tagName]){ + utils.each(node.children,function(cn){ + if(cn.type =='element'){ + if(cn.tagName == 'br'){ + code += '\n' + }else if(!dtd.$empty[node.tagName]){ + code += cn.innerText(); + } + }else{ + code += cn.data + } + }) + if(!/\n$/.test(code)){ + code += '\n'; + } + } + }else{ + code += node.data + '\n' + } + if(!node.nextSibling() && /\n$/.test(code)){ + code = code.replace(/\n$/,''); + } + }else{ + if(browser.ie && browser.ie11below){ + + if(node.type =='element'){ + if(node.tagName == 'br'){ + code += '
          ' + }else if(!dtd.$empty[node.tagName]){ + utils.each(node.children,function(cn){ + if(cn.type =='element'){ + if(cn.tagName == 'br'){ + code += '
          ' + }else if(!dtd.$empty[node.tagName]){ + code += cn.innerText(); + } + }else{ + code += cn.data + } + }); + if(!/br>$/.test(code)){ + code += '
          '; + } + } + }else{ + code += node.data + '
          ' + } + if(!node.nextSibling() && /
          $/.test(code)){ + code = code.replace(/
          $/,''); + } + + }else{ + code += (node.type == 'element' ? (dtd.$empty[node.tagName] ? '' : node.innerText()) : node.data); + if(!/br\/?\s*>$/.test(code)){ + if(!node.nextSibling()) + return; + code += '
          ' + } + } + + } + + }); + } + me.execCommand('inserthtml','
          '+code+'
          ',true); + + pre = me.document.getElementById('coder'); + domUtils.removeAttributes(pre,'id'); + var tmpNode = pre.previousSibling; + + if(tmpNode && (tmpNode.nodeType == 3 && tmpNode.nodeValue.length == 1 && browser.ie && browser.version == 6 || domUtils.isEmptyBlock(tmpNode))){ + + domUtils.remove(tmpNode) + } + var rng = me.selection.getRange(); + if(domUtils.isEmptyBlock(pre)){ + rng.setStart(pre,0).setCursor(false,true) + }else{ + rng.selectNodeContents(pre).select() + } + } + + + + }, + queryCommandValue : function(){ + var path = this.selection.getStartElementPath(); + var lang = ''; + utils.each(path,function(node){ + if(node.nodeName =='PRE'){ + var match = node.className.match(/brush:([^;]+)/); + lang = match && match[1] ? match[1] : ''; + return false; + } + }); + return lang; + } + }; + + me.addInputRule(function(root){ + utils.each(root.getNodesByTagName('pre'),function(pre){ + var brs = pre.getNodesByTagName('br'); + if(brs.length){ + browser.ie && browser.ie11below && browser.version > 8 && utils.each(brs,function(br){ + var txt = UE.uNode.createText('\n'); + br.parentNode.insertBefore(txt,br); + br.parentNode.removeChild(br); + }); + return; + } + if(browser.ie && browser.ie11below && browser.version > 8) + return; + var code = pre.innerText().split(/\n/); + pre.innerHTML(''); + utils.each(code,function(c){ + if(c.length){ + pre.appendChild(UE.uNode.createText(c)); + } + pre.appendChild(UE.uNode.createElement('br')) + }) + }) + }); + me.addOutputRule(function(root){ + utils.each(root.getNodesByTagName('pre'),function(pre){ + var code = ''; + utils.each(pre.children,function(n){ + if(n.type == 'text'){ + //在ie下文本内容有可能末尾带有\n要去掉 + //trace:3396 + code += n.data.replace(/[ ]/g,' ').replace(/\n$/,''); + }else{ + if(n.tagName == 'br'){ + code += '\n' + }else{ + code += (!dtd.$empty[n.tagName] ? '' : n.innerText()); + } + + } + + }); + + pre.innerText(code.replace(/( |\n)+$/,'')) + }) + }); + //不需要判断highlight的command列表 + me.notNeedCodeQuery ={ + help:1, + undo:1, + redo:1, + source:1, + print:1, + searchreplace:1, + fullscreen:1, + preview:1, + insertparagraph:1, + elementpath:1, + insertcode:1, + inserthtml:1, + selectall:1 + }; + //将queyCommamndState重置 + var orgQuery = me.queryCommandState; + me.queryCommandState = function(cmd){ + var me = this; + + if(!me.notNeedCodeQuery[cmd.toLowerCase()] && me.selection && me.queryCommandValue('insertcode')){ + return -1; + } + return UE.Editor.prototype.queryCommandState.apply(this,arguments) + }; + me.addListener('beforeenterkeydown',function(){ + var rng = me.selection.getRange(); + var pre = domUtils.findParentByTagName(rng.startContainer,'pre',true); + if(pre){ + me.fireEvent('saveScene'); + if(!rng.collapsed){ + rng.deleteContents(); + } + if(!browser.ie || browser.ie9above){ + var tmpNode = me.document.createElement('br'),pre; + rng.insertNode(tmpNode).setStartAfter(tmpNode).collapse(true); + var next = tmpNode.nextSibling; + if(!next && (!browser.ie || browser.version > 10)){ + rng.insertNode(tmpNode.cloneNode(false)); + }else{ + rng.setStartAfter(tmpNode); + } + pre = tmpNode.previousSibling; + var tmp; + while(pre ){ + tmp = pre; + pre = pre.previousSibling; + if(!pre || pre.nodeName == 'BR'){ + pre = tmp; + break; + } + } + if(pre){ + var str = ''; + while(pre && pre.nodeName != 'BR' && new RegExp('^[\\s'+domUtils.fillChar+']*$').test(pre.nodeValue)){ + str += pre.nodeValue; + pre = pre.nextSibling; + } + if(pre.nodeName != 'BR'){ + var match = pre.nodeValue.match(new RegExp('^([\\s'+domUtils.fillChar+']+)')); + if(match && match[1]){ + str += match[1] + } + + } + if(str){ + str = me.document.createTextNode(str); + rng.insertNode(str).setStartAfter(str); + } + } + rng.collapse(true).select(true); + }else{ + if(browser.version > 8){ + + var txt = me.document.createTextNode('\n'); + var start = rng.startContainer; + if(rng.startOffset == 0){ + var preNode = start.previousSibling; + if(preNode){ + rng.insertNode(txt); + var fillchar = me.document.createTextNode(' '); + rng.setStartAfter(txt).insertNode(fillchar).setStart(fillchar,0).collapse(true).select(true) + } + }else{ + rng.insertNode(txt).setStartAfter(txt); + var fillchar = me.document.createTextNode(' '); + start = rng.startContainer.childNodes[rng.startOffset]; + if(start && !/^\n/.test(start.nodeValue)){ + rng.setStartBefore(txt) + } + rng.insertNode(fillchar).setStart(fillchar,0).collapse(true).select(true) + } + + }else{ + var tmpNode = me.document.createElement('br'); + rng.insertNode(tmpNode); + rng.insertNode(me.document.createTextNode(domUtils.fillChar)); + rng.setStartAfter(tmpNode); + pre = tmpNode.previousSibling; + var tmp; + while(pre ){ + tmp = pre; + pre = pre.previousSibling; + if(!pre || pre.nodeName == 'BR'){ + pre = tmp; + break; + } + } + if(pre){ + var str = ''; + while(pre && pre.nodeName != 'BR' && new RegExp('^[ '+domUtils.fillChar+']*$').test(pre.nodeValue)){ + str += pre.nodeValue; + pre = pre.nextSibling; + } + if(pre.nodeName != 'BR'){ + var match = pre.nodeValue.match(new RegExp('^([ '+domUtils.fillChar+']+)')); + if(match && match[1]){ + str += match[1] + } + + } + + str = me.document.createTextNode(str); + rng.insertNode(str).setStartAfter(str); + } + rng.collapse(true).select(); + } + + + } + me.fireEvent('saveScene'); + return true; + } + + + }); + + me.addListener('tabkeydown',function(cmd,evt){ + var rng = me.selection.getRange(); + var pre = domUtils.findParentByTagName(rng.startContainer,'pre',true); + if(pre){ + me.fireEvent('saveScene'); + if(evt.shiftKey){ + + }else{ + if(!rng.collapsed){ + var bk = rng.createBookmark(); + var start = bk.start.previousSibling; + + while(start){ + if(pre.firstChild === start && !domUtils.isBr(start)){ + pre.insertBefore(me.document.createTextNode(' '),start); + + break; + } + if(domUtils.isBr(start)){ + pre.insertBefore(me.document.createTextNode(' '),start.nextSibling); + + break; + } + start = start.previousSibling; + } + var end = bk.end; + start = bk.start.nextSibling; + if(pre.firstChild === bk.start){ + pre.insertBefore(me.document.createTextNode(' '),start.nextSibling) + + } + while(start && start !== end){ + if(domUtils.isBr(start) && start.nextSibling){ + if(start.nextSibling === end){ + break; + } + pre.insertBefore(me.document.createTextNode(' '),start.nextSibling) + } + + start = start.nextSibling; + } + rng.moveToBookmark(bk).select(); + }else{ + var tmpNode = me.document.createTextNode(' '); + rng.insertNode(tmpNode).setStartAfter(tmpNode).collapse(true).select(true); + } + } + + + me.fireEvent('saveScene'); + return true; + } + + + }); + + + me.addListener('beforeinserthtml',function(evtName,html){ + var me = this, + rng = me.selection.getRange(), + pre = domUtils.findParentByTagName(rng.startContainer,'pre',true); + if(pre){ + if(!rng.collapsed){ + rng.deleteContents() + } + var htmlstr = ''; + if(browser.ie && browser.version > 8){ + + utils.each(UE.filterNode(UE.htmlparser(html),me.options.filterTxtRules).children,function(node){ + if(node.type =='element'){ + if(node.tagName == 'br'){ + htmlstr += '\n' + }else if(!dtd.$empty[node.tagName]){ + utils.each(node.children,function(cn){ + if(cn.type =='element'){ + if(cn.tagName == 'br'){ + htmlstr += '\n' + }else if(!dtd.$empty[node.tagName]){ + htmlstr += cn.innerText(); + } + }else{ + htmlstr += cn.data + } + }) + if(!/\n$/.test(htmlstr)){ + htmlstr += '\n'; + } + } + }else{ + htmlstr += node.data + '\n' + } + if(!node.nextSibling() && /\n$/.test(htmlstr)){ + htmlstr = htmlstr.replace(/\n$/,''); + } + }); + var tmpNode = me.document.createTextNode(utils.html(htmlstr.replace(/ /g,' '))); + rng.insertNode(tmpNode).selectNode(tmpNode).select(); + }else{ + var frag = me.document.createDocumentFragment(); + + utils.each(UE.filterNode(UE.htmlparser(html),me.options.filterTxtRules).children,function(node){ + if(node.type =='element'){ + if(node.tagName == 'br'){ + frag.appendChild(me.document.createElement('br')) + }else if(!dtd.$empty[node.tagName]){ + utils.each(node.children,function(cn){ + if(cn.type =='element'){ + if(cn.tagName == 'br'){ + + frag.appendChild(me.document.createElement('br')) + }else if(!dtd.$empty[node.tagName]){ + frag.appendChild(me.document.createTextNode(utils.html(cn.innerText().replace(/ /g,' ')))); + + } + }else{ + frag.appendChild(me.document.createTextNode(utils.html( cn.data.replace(/ /g,' ')))); + + } + }) + if(frag.lastChild.nodeName != 'BR'){ + frag.appendChild(me.document.createElement('br')) + } + } + }else{ + frag.appendChild(me.document.createTextNode(utils.html( node.data.replace(/ /g,' ')))); + } + if(!node.nextSibling() && frag.lastChild.nodeName == 'BR'){ + frag.removeChild(frag.lastChild) + } + + + }); + rng.insertNode(frag).select(); + + } + + return true; + } + }); + //方向键的处理 + me.addListener('keydown',function(cmd,evt){ + var me = this,keyCode = evt.keyCode || evt.which; + if(keyCode == 40){ + var rng = me.selection.getRange(),pre,start = rng.startContainer; + if(rng.collapsed && (pre = domUtils.findParentByTagName(rng.startContainer,'pre',true)) && !pre.nextSibling){ + var last = pre.lastChild + while(last && last.nodeName == 'BR'){ + last = last.previousSibling; + } + if(last === start || rng.startContainer === pre && rng.startOffset == pre.childNodes.length){ + me.execCommand('insertparagraph'); + domUtils.preventDefault(evt) + } + + } + } + }); + //trace:3395 + me.addListener('delkeydown',function(type,evt){ + var rng = this.selection.getRange(); + rng.txtToElmBoundary(true); + var start = rng.startContainer; + if(domUtils.isTagNode(start,'pre') && rng.collapsed && domUtils.isStartInblock(rng)){ + var p = me.document.createElement('p'); + domUtils.fillNode(me.document,p); + start.parentNode.insertBefore(p,start); + domUtils.remove(start); + rng.setStart(p,0).setCursor(false,true); + domUtils.preventDefault(evt); + return true; + } + }) +}; + + +// plugins/cleardoc.js +/** + * 清空文档插件 + * @file + * @since 1.2.6.1 + */ + +/** + * 清空文档 + * @command cleardoc + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * //editor 是编辑器实例 + * editor.execCommand('cleardoc'); + * ``` + */ + +UE.commands['cleardoc'] = { + execCommand : function( cmdName) { + var me = this, + enterTag = me.options.enterTag, + range = me.selection.getRange(); + if(enterTag == "br"){ + me.body.innerHTML = "
          "; + range.setStart(me.body,0).setCursor(); + }else{ + me.body.innerHTML = "

          "+(ie ? "" : "
          ")+"

          "; + range.setStart(me.body.firstChild,0).setCursor(false,true); + } + setTimeout(function(){ + me.fireEvent("clearDoc"); + },0); + + } +}; + + + +// plugins/anchor.js +/** + * 锚点插件,为UEditor提供插入锚点支持 + * @file + * @since 1.2.6.1 + */ +UE.plugin.register('anchor', function (){ + + return { + bindEvents:{ + 'ready':function(){ + utils.cssRule('anchor', + '.anchorclass{background: url(\'' + + this.options.themePath + + this.options.theme +'/images/anchor.gif\') no-repeat scroll left center transparent;cursor: auto;display: inline-block;height: 16px;width: 15px;}', + this.document); + } + }, + outputRule: function(root){ + utils.each(root.getNodesByTagName('img'),function(a){ + var val; + if(val = a.getAttr('anchorname')){ + a.tagName = 'a'; + a.setAttr({ + anchorname : '', + name : val, + 'class' : '' + }) + } + }) + }, + inputRule:function(root){ + utils.each(root.getNodesByTagName('a'),function(a){ + var val; + if((val = a.getAttr('name')) && !a.getAttr('href')){ + a.tagName = 'img'; + a.setAttr({ + anchorname :a.getAttr('name'), + 'class' : 'anchorclass' + }); + a.setAttr('name') + + } + }) + + }, + commands:{ + /** + * 插入锚点 + * @command anchor + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } name 锚点名称字符串 + * @example + * ```javascript + * //editor 是编辑器实例 + * editor.execCommand('anchor', 'anchor1'); + * ``` + */ + 'anchor':{ + execCommand:function (cmd, name) { + var range = this.selection.getRange(),img = range.getClosedNode(); + if (img && img.getAttribute('anchorname')) { + if (name) { + img.setAttribute('anchorname', name); + } else { + range.setStartBefore(img).setCursor(); + domUtils.remove(img); + } + } else { + if (name) { + //只在选区的开始插入 + var anchor = this.document.createElement('img'); + range.collapse(true); + domUtils.setAttributes(anchor,{ + 'anchorname':name, + 'class':'anchorclass' + }); + range.insertNode(anchor).setStartAfter(anchor).setCursor(false,true); + } + } + } + } + } + } +}); + + +// plugins/wordcount.js +///import core +///commands 字数统计 +///commandsName WordCount,wordCount +///commandsTitle 字数统计 +/* + * Created by JetBrains WebStorm. + * User: taoqili + * Date: 11-9-7 + * Time: 下午8:18 + * To change this template use File | Settings | File Templates. + */ + +UE.plugins['wordcount'] = function(){ + var me = this; + me.setOpt('wordCount',true); + me.addListener('contentchange',function(){ + me.fireEvent('wordcount'); + }); + var timer; + me.addListener('ready',function(){ + var me = this; + domUtils.on(me.body,"keyup",function(evt){ + var code = evt.keyCode||evt.which, + //忽略的按键,ctr,alt,shift,方向键 + ignores = {"16":1,"18":1,"20":1,"37":1,"38":1,"39":1,"40":1}; + if(code in ignores) return; + clearTimeout(timer); + timer = setTimeout(function(){ + me.fireEvent('wordcount'); + },200) + }) + }); +}; + + +// plugins/pagebreak.js +/** + * 分页功能插件 + * @file + * @since 1.2.6.1 + */ +UE.plugins['pagebreak'] = function () { + var me = this, + notBreakTags = ['td']; + me.setOpt('pageBreakTag','_ueditor_page_break_tag_'); + + function fillNode(node){ + if(domUtils.isEmptyBlock(node)){ + var firstChild = node.firstChild,tmpNode; + + while(firstChild && firstChild.nodeType == 1 && domUtils.isEmptyBlock(firstChild)){ + tmpNode = firstChild; + firstChild = firstChild.firstChild; + } + !tmpNode && (tmpNode = node); + domUtils.fillNode(me.document,tmpNode); + } + } + //分页符样式添加 + + me.ready(function(){ + utils.cssRule('pagebreak','.pagebreak{display:block;clear:both !important;cursor:default !important;width: 100% !important;margin:0;}',me.document); + }); + function isHr(node){ + return node && node.nodeType == 1 && node.tagName == 'HR' && node.className == 'pagebreak'; + } + me.addInputRule(function(root){ + root.traversal(function(node){ + if(node.type == 'text' && node.data == me.options.pageBreakTag){ + var hr = UE.uNode.createElement('
          '); + node.parentNode.insertBefore(hr,node); + node.parentNode.removeChild(node) + } + }) + }); + me.addOutputRule(function(node){ + utils.each(node.getNodesByTagName('hr'),function(n){ + if(n.getAttr('class') == 'pagebreak'){ + var txt = UE.uNode.createText(me.options.pageBreakTag); + n.parentNode.insertBefore(txt,n); + n.parentNode.removeChild(n); + } + }) + + }); + + /** + * 插入分页符 + * @command pagebreak + * @method execCommand + * @param { String } cmd 命令字符串 + * @remind 在表格中插入分页符会把表格切分成两部分 + * @remind 获取编辑器内的数据时, 编辑器会把分页符转换成“_ueditor_page_break_tag_”字符串, + * 以便于提交数据到服务器端后处理分页。 + * @example + * ```javascript + * editor.execCommand( 'pagebreak'); //插入一个hr标签,带有样式类名pagebreak + * ``` + */ + + me.commands['pagebreak'] = { + execCommand:function () { + var range = me.selection.getRange(),hr = me.document.createElement('hr'); + domUtils.setAttributes(hr,{ + 'class' : 'pagebreak', + noshade:"noshade", + size:"5" + }); + domUtils.unSelectable(hr); + //table单独处理 + var node = domUtils.findParentByTagName(range.startContainer, notBreakTags, true), + + parents = [], pN; + if (node) { + switch (node.tagName) { + case 'TD': + pN = node.parentNode; + if (!pN.previousSibling) { + var table = domUtils.findParentByTagName(pN, 'table'); +// var tableWrapDiv = table.parentNode; +// if(tableWrapDiv && tableWrapDiv.nodeType == 1 +// && tableWrapDiv.tagName == 'DIV' +// && tableWrapDiv.getAttribute('dropdrag') +// ){ +// domUtils.remove(tableWrapDiv,true); +// } + table.parentNode.insertBefore(hr, table); + parents = domUtils.findParents(hr, true); + + } else { + pN.parentNode.insertBefore(hr, pN); + parents = domUtils.findParents(hr); + + } + pN = parents[1]; + if (hr !== pN) { + domUtils.breakParent(hr, pN); + + } + //table要重写绑定一下拖拽 + me.fireEvent('afteradjusttable',me.document); + } + + } else { + + if (!range.collapsed) { + range.deleteContents(); + var start = range.startContainer; + while ( !domUtils.isBody(start) && domUtils.isBlockElm(start) && domUtils.isEmptyNode(start)) { + range.setStartBefore(start).collapse(true); + domUtils.remove(start); + start = range.startContainer; + } + + } + range.insertNode(hr); + + var pN = hr.parentNode, nextNode; + while (!domUtils.isBody(pN)) { + domUtils.breakParent(hr, pN); + nextNode = hr.nextSibling; + if (nextNode && domUtils.isEmptyBlock(nextNode)) { + domUtils.remove(nextNode); + } + pN = hr.parentNode; + } + nextNode = hr.nextSibling; + var pre = hr.previousSibling; + if(isHr(pre)){ + domUtils.remove(pre); + }else{ + pre && fillNode(pre); + } + + if(!nextNode){ + var p = me.document.createElement('p'); + + hr.parentNode.appendChild(p); + domUtils.fillNode(me.document,p); + range.setStart(p,0).collapse(true); + }else{ + if(isHr(nextNode)){ + domUtils.remove(nextNode); + }else{ + fillNode(nextNode); + } + range.setEndAfter(hr).collapse(false); + } + + range.select(true); + + } + + } + }; +}; + +// plugins/wordimage.js +///import core +///commands 本地图片引导上传 +///commandsName WordImage +///commandsTitle 本地图片引导上传 +///commandsDialog dialogs\wordimage + +UE.plugin.register('wordimage',function(){ + var me = this, + images = []; + return { + commands : { + 'wordimage':{ + execCommand:function () { + var images = domUtils.getElementsByTagName(me.body, "img"); + var urlList = []; + for (var i = 0, ci; ci = images[i++];) { + var url = ci.getAttribute("word_img"); + url && urlList.push(url); + } + return urlList; + }, + queryCommandState:function () { + images = domUtils.getElementsByTagName(me.body, "img"); + for (var i = 0, ci; ci = images[i++];) { + if (ci.getAttribute("word_img")) { + return 1; + } + } + return -1; + }, + notNeedUndo:true + } + }, + inputRule : function (root) { + utils.each(root.getNodesByTagName('img'), function (img) { + var attrs = img.attrs, + flag = parseInt(attrs.width) < 128 || parseInt(attrs.height) < 43, + opt = me.options, + src = opt.UEDITOR_HOME_URL + 'themes/default/images/spacer.gif'; + if (attrs['src'] && /^(?:(file:\/+))/.test(attrs['src'])) { + img.setAttr({ + width:attrs.width, + height:attrs.height, + alt:attrs.alt, + word_img: attrs.src, + src:src, + 'style':'background:url(' + ( flag ? opt.themePath + opt.theme + '/images/word.gif' : opt.langPath + opt.lang + '/images/localimage.png') + ') no-repeat center center;border:1px solid #ddd' + }) + } + }) + } + } +}); + +// plugins/dragdrop.js +UE.plugins['dragdrop'] = function (){ + + var me = this; + me.ready(function(){ + domUtils.on(this.body,'dragend',function(){ + var rng = me.selection.getRange(); + var node = rng.getClosedNode()||me.selection.getStart(); + + if(node && node.tagName == 'IMG'){ + + var pre = node.previousSibling,next; + while(next = node.nextSibling){ + if(next.nodeType == 1 && next.tagName == 'SPAN' && !next.firstChild){ + domUtils.remove(next) + }else{ + break; + } + } + + + if((pre && pre.nodeType == 1 && !domUtils.isEmptyBlock(pre) || !pre) && (!next || next && !domUtils.isEmptyBlock(next))){ + if(pre && pre.tagName == 'P' && !domUtils.isEmptyBlock(pre)){ + pre.appendChild(node); + domUtils.moveChild(next,pre); + domUtils.remove(next); + }else if(next && next.tagName == 'P' && !domUtils.isEmptyBlock(next)){ + next.insertBefore(node,next.firstChild); + } + + if(pre && pre.tagName == 'P' && domUtils.isEmptyBlock(pre)){ + domUtils.remove(pre) + } + if(next && next.tagName == 'P' && domUtils.isEmptyBlock(next)){ + domUtils.remove(next) + } + rng.selectNode(node).select(); + me.fireEvent('saveScene'); + + } + + } + + }) + }); + me.addListener('keyup', function(type, evt) { + var keyCode = evt.keyCode || evt.which; + if (keyCode == 13) { + var rng = me.selection.getRange(),node; + if(node = domUtils.findParentByTagName(rng.startContainer,'p',true)){ + if(domUtils.getComputedStyle(node,'text-align') == 'center'){ + domUtils.removeStyle(node,'text-align') + } + } + } + }) +}; + + +// plugins/undo.js +/** + * undo redo + * @file + * @since 1.2.6.1 + */ + +/** + * 撤销上一次执行的命令 + * @command undo + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'undo' ); + * ``` + */ + +/** + * 重做上一次执行的命令 + * @command redo + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'redo' ); + * ``` + */ + +UE.plugins['undo'] = function () { + var saveSceneTimer; + var me = this, + maxUndoCount = me.options.maxUndoCount || 20, + maxInputCount = me.options.maxInputCount || 20, + fillchar = new RegExp(domUtils.fillChar + '|<\/hr>', 'gi');// ie会产生多余的 + var noNeedFillCharTags = { + ol:1,ul:1,table:1,tbody:1,tr:1,body:1 + }; + var orgState = me.options.autoClearEmptyNode; + function compareAddr(indexA, indexB) { + if (indexA.length != indexB.length) + return 0; + for (var i = 0, l = indexA.length; i < l; i++) { + if (indexA[i] != indexB[i]) + return 0 + } + return 1; + } + + function compareRangeAddress(rngAddrA, rngAddrB) { + if (rngAddrA.collapsed != rngAddrB.collapsed) { + return 0; + } + if (!compareAddr(rngAddrA.startAddress, rngAddrB.startAddress) || !compareAddr(rngAddrA.endAddress, rngAddrB.endAddress)) { + return 0; + } + return 1; + } + + function UndoManager() { + this.list = []; + this.index = 0; + this.hasUndo = false; + this.hasRedo = false; + this.undo = function () { + if (this.hasUndo) { + if (!this.list[this.index - 1] && this.list.length == 1) { + this.reset(); + return; + } + while (this.list[this.index].content == this.list[this.index - 1].content) { + this.index--; + if (this.index == 0) { + return this.restore(0); + } + } + this.restore(--this.index); + } + }; + this.redo = function () { + if (this.hasRedo) { + while (this.list[this.index].content == this.list[this.index + 1].content) { + this.index++; + if (this.index == this.list.length - 1) { + return this.restore(this.index); + } + } + this.restore(++this.index); + } + }; + + this.restore = function () { + var me = this.editor; + var scene = this.list[this.index]; + var root = UE.htmlparser(scene.content.replace(fillchar, '')); + me.options.autoClearEmptyNode = false; + me.filterInputRule(root); + me.options.autoClearEmptyNode = orgState; + //trace:873 + //去掉展位符 + me.document.body.innerHTML = root.toHtml(); + me.fireEvent('afterscencerestore'); + //处理undo后空格不展位的问题 + if (browser.ie) { + utils.each(domUtils.getElementsByTagName(me.document,'td th caption p'),function(node){ + if(domUtils.isEmptyNode(node)){ + domUtils.fillNode(me.document, node); + } + }) + } + + try{ + var rng = new dom.Range(me.document).moveToAddress(scene.address); + rng.select(noNeedFillCharTags[rng.startContainer.nodeName.toLowerCase()]); + }catch(e){} + + this.update(); + this.clearKey(); + //不能把自己reset了 + me.fireEvent('reset', true); + }; + + this.getScene = function () { + var me = this.editor; + var rng = me.selection.getRange(), + rngAddress = rng.createAddress(false,true); + me.fireEvent('beforegetscene'); + var root = UE.htmlparser(me.body.innerHTML); + me.options.autoClearEmptyNode = false; + me.filterOutputRule(root); + me.options.autoClearEmptyNode = orgState; + var cont = root.toHtml(); + //trace:3461 + //这个会引起回退时导致空格丢失的情况 +// browser.ie && (cont = cont.replace(/> <').replace(/\s*\s*/g, '>')); + me.fireEvent('aftergetscene'); + + return { + address:rngAddress, + content:cont + } + }; + this.save = function (notCompareRange,notSetCursor) { + clearTimeout(saveSceneTimer); + var currentScene = this.getScene(notSetCursor), + lastScene = this.list[this.index]; + + if(lastScene && lastScene.content != currentScene.content){ + me.trigger('contentchange') + } + //内容相同位置相同不存 + if (lastScene && lastScene.content == currentScene.content && + ( notCompareRange ? 1 : compareRangeAddress(lastScene.address, currentScene.address) ) + ) { + return; + } + this.list = this.list.slice(0, this.index + 1); + this.list.push(currentScene); + //如果大于最大数量了,就把最前的剔除 + if (this.list.length > maxUndoCount) { + this.list.shift(); + } + this.index = this.list.length - 1; + this.clearKey(); + //跟新undo/redo状态 + this.update(); + + }; + this.update = function () { + this.hasRedo = !!this.list[this.index + 1]; + this.hasUndo = !!this.list[this.index - 1]; + }; + this.reset = function () { + this.list = []; + this.index = 0; + this.hasUndo = false; + this.hasRedo = false; + this.clearKey(); + }; + this.clearKey = function () { + keycont = 0; + lastKeyCode = null; + }; + } + + me.undoManger = new UndoManager(); + me.undoManger.editor = me; + function saveScene() { + this.undoManger.save(); + } + + me.addListener('saveScene', function () { + var args = Array.prototype.splice.call(arguments,1); + this.undoManger.save.apply(this.undoManger,args); + }); + +// me.addListener('beforeexeccommand', saveScene); +// me.addListener('afterexeccommand', saveScene); + + me.addListener('reset', function (type, exclude) { + if (!exclude) { + this.undoManger.reset(); + } + }); + me.commands['redo'] = me.commands['undo'] = { + execCommand:function (cmdName) { + this.undoManger[cmdName](); + }, + queryCommandState:function (cmdName) { + return this.undoManger['has' + (cmdName.toLowerCase() == 'undo' ? 'Undo' : 'Redo')] ? 0 : -1; + }, + notNeedUndo:1 + }; + + var keys = { + // /*Backspace*/ 8:1, /*Delete*/ 46:1, + /*Shift*/ 16:1, /*Ctrl*/ 17:1, /*Alt*/ 18:1, + 37:1, 38:1, 39:1, 40:1 + + }, + keycont = 0, + lastKeyCode; + //输入法状态下不计算字符数 + var inputType = false; + me.addListener('ready', function () { + domUtils.on(this.body, 'compositionstart', function () { + inputType = true; + }); + domUtils.on(this.body, 'compositionend', function () { + inputType = false; + }) + }); + //快捷键 + me.addshortcutkey({ + "Undo":"ctrl+90", //undo + "Redo":"ctrl+89" //redo + + }); + var isCollapsed = true; + me.addListener('keydown', function (type, evt) { + + var me = this; + var keyCode = evt.keyCode || evt.which; + if (!keys[keyCode] && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey) { + if (inputType) + return; + + if(!me.selection.getRange().collapsed){ + me.undoManger.save(false,true); + isCollapsed = false; + return; + } + if (me.undoManger.list.length == 0) { + me.undoManger.save(true); + } + clearTimeout(saveSceneTimer); + function save(cont){ + cont.undoManger.save(false,true); + cont.fireEvent('selectionchange'); + } + saveSceneTimer = setTimeout(function(){ + if(inputType){ + var interalTimer = setInterval(function(){ + if(!inputType){ + save(me); + clearInterval(interalTimer) + } + },300) + return; + } + save(me); + },200); + + lastKeyCode = keyCode; + keycont++; + if (keycont >= maxInputCount ) { + save(me) + } + } + }); + me.addListener('keyup', function (type, evt) { + var keyCode = evt.keyCode || evt.which; + if (!keys[keyCode] && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey) { + if (inputType) + return; + if(!isCollapsed){ + this.undoManger.save(false,true); + isCollapsed = true; + } + } + }); + //扩展实例,添加关闭和开启命令undo + me.stopCmdUndo = function(){ + me.__hasEnterExecCommand = true; + }; + me.startCmdUndo = function(){ + me.__hasEnterExecCommand = false; + } +}; + + +// plugins/copy.js +UE.plugin.register('copy', function () { + + var me = this; + + function initZeroClipboard() { + + ZeroClipboard.config({ + debug: false, + swfPath: me.options.UEDITOR_HOME_URL + 'third-party/zeroclipboard/ZeroClipboard.swf' + }); + + var client = me.zeroclipboard = new ZeroClipboard(); + + // 复制内容 + client.on('copy', function (e) { + var client = e.client, + rng = me.selection.getRange(), + div = document.createElement('div'); + + div.appendChild(rng.cloneContents()); + client.setText(div.innerText || div.textContent); + client.setHtml(div.innerHTML); + rng.select(); + }); + // hover事件传递到target + client.on('mouseover mouseout', function (e) { + var target = e.target; + if (e.type == 'mouseover') { + domUtils.addClass(target, 'edui-state-hover'); + } else if (e.type == 'mouseout') { + domUtils.removeClasses(target, 'edui-state-hover'); + } + }); + // flash加载不成功 + client.on('wrongflash noflash', function () { + ZeroClipboard.destroy(); + }); + } + + return { + bindEvents: { + 'ready': function () { + if (!browser.ie) { + if (window.ZeroClipboard) { + initZeroClipboard(); + } else { + utils.loadFile(document, { + src: me.options.UEDITOR_HOME_URL + "third-party/zeroclipboard/ZeroClipboard.js", + tag: "script", + type: "text/javascript", + defer: "defer" + }, function () { + initZeroClipboard(); + }); + } + } + } + }, + commands: { + 'copy': { + execCommand: function (cmd) { + if (!me.document.execCommand('copy')) { + alert(me.getLang('copymsg')); + } + } + } + } + } +}); + + +// plugins/paste.js +///import core +///import plugins/inserthtml.js +///import plugins/undo.js +///import plugins/serialize.js +///commands 粘贴 +///commandsName PastePlain +///commandsTitle 纯文本粘贴模式 +/** + * @description 粘贴 + * @author zhanyi + */ +UE.plugins['paste'] = function () { + function getClipboardData(callback) { + var doc = this.document; + if (doc.getElementById('baidu_pastebin')) { + return; + } + var range = this.selection.getRange(), + bk = range.createBookmark(), + //创建剪贴的容器div + pastebin = doc.createElement('div'); + pastebin.id = 'baidu_pastebin'; + // Safari 要求div必须有内容,才能粘贴内容进来 + browser.webkit && pastebin.appendChild(doc.createTextNode(domUtils.fillChar + domUtils.fillChar)); + doc.body.appendChild(pastebin); + //trace:717 隐藏的span不能得到top + //bk.start.innerHTML = ' '; + bk.start.style.display = ''; + pastebin.style.cssText = "position:absolute;width:1px;height:1px;overflow:hidden;left:-1000px;white-space:nowrap;top:" + + //要在现在光标平行的位置加入,否则会出现跳动的问题 + domUtils.getXY(bk.start).y + 'px'; + + range.selectNodeContents(pastebin).select(true); + + setTimeout(function () { + if (browser.webkit) { + for (var i = 0, pastebins = doc.querySelectorAll('#baidu_pastebin'), pi; pi = pastebins[i++];) { + if (domUtils.isEmptyNode(pi)) { + domUtils.remove(pi); + } else { + pastebin = pi; + break; + } + } + } + try { + pastebin.parentNode.removeChild(pastebin); + } catch (e) { + } + range.moveToBookmark(bk).select(true); + callback(pastebin); + }, 0); + } + + var me = this; + + me.setOpt({ + retainOnlyLabelPasted : false + }); + + var txtContent, htmlContent, address; + + function getPureHtml(html){ + return html.replace(/<(\/?)([\w\-]+)([^>]*)>/gi, function (a, b, tagName, attrs) { + tagName = tagName.toLowerCase(); + if ({img: 1}[tagName]) { + return a; + } + attrs = attrs.replace(/([\w\-]*?)\s*=\s*(("([^"]*)")|('([^']*)')|([^\s>]+))/gi, function (str, atr, val) { + if ({ + 'src': 1, + 'href': 1, + 'name': 1 + }[atr.toLowerCase()]) { + return atr + '=' + val + ' ' + } + return '' + }); + if ({ + 'span': 1, + 'div': 1 + }[tagName]) { + return '' + } else { + + return '<' + b + tagName + ' ' + utils.trim(attrs) + '>' + } + + }); + } + function filter(div) { + var html; + if (div.firstChild) { + //去掉cut中添加的边界值 + var nodes = domUtils.getElementsByTagName(div, 'span'); + for (var i = 0, ni; ni = nodes[i++];) { + if (ni.id == '_baidu_cut_start' || ni.id == '_baidu_cut_end') { + domUtils.remove(ni); + } + } + + if (browser.webkit) { + + var brs = div.querySelectorAll('div br'); + for (var i = 0, bi; bi = brs[i++];) { + var pN = bi.parentNode; + if (pN.tagName == 'DIV' && pN.childNodes.length == 1) { + pN.innerHTML = '


          '; + domUtils.remove(pN); + } + } + var divs = div.querySelectorAll('#baidu_pastebin'); + for (var i = 0, di; di = divs[i++];) { + var tmpP = me.document.createElement('p'); + di.parentNode.insertBefore(tmpP, di); + while (di.firstChild) { + tmpP.appendChild(di.firstChild); + } + domUtils.remove(di); + } + + var metas = div.querySelectorAll('meta'); + for (var i = 0, ci; ci = metas[i++];) { + domUtils.remove(ci); + } + + var brs = div.querySelectorAll('br'); + for (i = 0; ci = brs[i++];) { + if (/^apple-/i.test(ci.className)) { + domUtils.remove(ci); + } + } + } + if (browser.gecko) { + var dirtyNodes = div.querySelectorAll('[_moz_dirty]'); + for (i = 0; ci = dirtyNodes[i++];) { + ci.removeAttribute('_moz_dirty'); + } + } + if (!browser.ie) { + var spans = div.querySelectorAll('span.Apple-style-span'); + for (var i = 0, ci; ci = spans[i++];) { + domUtils.remove(ci, true); + } + } + + //ie下使用innerHTML会产生多余的\r\n字符,也会产生 这里过滤掉 + html = div.innerHTML;//.replace(/>(?:(\s| )*?)<'); + + //过滤word粘贴过来的冗余属性 + html = UE.filterWord(html); + //取消了忽略空白的第二个参数,粘贴过来的有些是有空白的,会被套上相关的标签 + var root = UE.htmlparser(html); + //如果给了过滤规则就先进行过滤 + if (me.options.filterRules) { + UE.filterNode(root, me.options.filterRules); + } + //执行默认的处理 + me.filterInputRule(root); + //针对chrome的处理 + if (browser.webkit) { + var br = root.lastChild(); + if (br && br.type == 'element' && br.tagName == 'br') { + root.removeChild(br) + } + utils.each(me.body.querySelectorAll('div'), function (node) { + if (domUtils.isEmptyBlock(node)) { + domUtils.remove(node,true) + } + }) + } + html = {'html': root.toHtml()}; + me.fireEvent('beforepaste', html, root); + //抢了默认的粘贴,那后边的内容就不执行了,比如表格粘贴 + if(!html.html){ + return; + } + root = UE.htmlparser(html.html,true); + //如果开启了纯文本模式 + if (me.queryCommandState('pasteplain') === 1) { + me.execCommand('insertHtml', UE.filterNode(root, me.options.filterTxtRules).toHtml(), true); + } else { + //文本模式 + UE.filterNode(root, me.options.filterTxtRules); + txtContent = root.toHtml(); + //完全模式 + htmlContent = html.html; + + address = me.selection.getRange().createAddress(true); + me.execCommand('insertHtml', me.getOpt('retainOnlyLabelPasted') === true ? getPureHtml(htmlContent) : htmlContent, true); + } + me.fireEvent("afterpaste", html); + } + } + + me.addListener('pasteTransfer', function (cmd, plainType) { + + if (address && txtContent && htmlContent && txtContent != htmlContent) { + var range = me.selection.getRange(); + range.moveToAddress(address, true); + + if (!range.collapsed) { + + while (!domUtils.isBody(range.startContainer) + ) { + var start = range.startContainer; + if(start.nodeType == 1){ + start = start.childNodes[range.startOffset]; + if(!start){ + range.setStartBefore(range.startContainer); + continue; + } + var pre = start.previousSibling; + + if(pre && pre.nodeType == 3 && new RegExp('^[\n\r\t '+domUtils.fillChar+']*$').test(pre.nodeValue)){ + range.setStartBefore(pre) + } + } + if(range.startOffset == 0){ + range.setStartBefore(range.startContainer); + }else{ + break; + } + + } + while (!domUtils.isBody(range.endContainer) + ) { + var end = range.endContainer; + if(end.nodeType == 1){ + end = end.childNodes[range.endOffset]; + if(!end){ + range.setEndAfter(range.endContainer); + continue; + } + var next = end.nextSibling; + if(next && next.nodeType == 3 && new RegExp('^[\n\r\t'+domUtils.fillChar+']*$').test(next.nodeValue)){ + range.setEndAfter(next) + } + } + if(range.endOffset == range.endContainer[range.endContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length){ + range.setEndAfter(range.endContainer); + }else{ + break; + } + + } + + } + + range.deleteContents(); + range.select(true); + me.__hasEnterExecCommand = true; + var html = htmlContent; + if (plainType === 2 ) { + html = getPureHtml(html); + } else if (plainType) { + html = txtContent; + } + me.execCommand('inserthtml', html, true); + me.__hasEnterExecCommand = false; + var rng = me.selection.getRange(); + while (!domUtils.isBody(rng.startContainer) && !rng.startOffset && + rng.startContainer[rng.startContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length + ) { + rng.setStartBefore(rng.startContainer); + } + var tmpAddress = rng.createAddress(true); + address.endAddress = tmpAddress.startAddress; + } + }); + + me.addListener('ready', function () { + domUtils.on(me.body, 'cut', function () { + var range = me.selection.getRange(); + if (!range.collapsed && me.undoManger) { + me.undoManger.save(); + } + }); + + //ie下beforepaste在点击右键时也会触发,所以用监控键盘才处理 + domUtils.on(me.body, browser.ie || browser.opera ? 'keydown' : 'paste', function (e) { + if ((browser.ie || browser.opera) && ((!e.ctrlKey && !e.metaKey) || e.keyCode != '86')) { + return; + } + getClipboardData.call(me, function (div) { + filter(div); + }); + }); + + }); + + me.commands['paste'] = { + execCommand: function (cmd) { + if (browser.ie) { + getClipboardData.call(me, function (div) { + filter(div); + }); + me.document.execCommand('paste'); + } else { + alert(me.getLang('pastemsg')); + } + } + } +}; + + + +// plugins/puretxtpaste.js +/** + * 纯文本粘贴插件 + * @file + * @since 1.2.6.1 + */ + +UE.plugins['pasteplain'] = function(){ + var me = this; + me.setOpt({ + 'pasteplain':false, + 'filterTxtRules' : function(){ + function transP(node){ + node.tagName = 'p'; + node.setStyle(); + } + function removeNode(node){ + node.parentNode.removeChild(node,true) + } + return { + //直接删除及其字节点内容 + '-' : 'script style object iframe embed input select', + 'p': {$:{}}, + 'br':{$:{}}, + div: function (node) { + var tmpNode, p = UE.uNode.createElement('p'); + while (tmpNode = node.firstChild()) { + if (tmpNode.type == 'text' || !UE.dom.dtd.$block[tmpNode.tagName]) { + p.appendChild(tmpNode); + } else { + if (p.firstChild()) { + node.parentNode.insertBefore(p, node); + p = UE.uNode.createElement('p'); + } else { + node.parentNode.insertBefore(tmpNode, node); + } + } + } + if (p.firstChild()) { + node.parentNode.insertBefore(p, node); + } + node.parentNode.removeChild(node); + }, + ol: removeNode, + ul: removeNode, + dl:removeNode, + dt:removeNode, + dd:removeNode, + 'li':removeNode, + 'caption':transP, + 'th':transP, + 'tr':transP, + 'h1':transP,'h2':transP,'h3':transP,'h4':transP,'h5':transP,'h6':transP, + 'td':function(node){ + //没有内容的td直接删掉 + var txt = !!node.innerText(); + if(txt){ + node.parentNode.insertAfter(UE.uNode.createText('    '),node); + } + node.parentNode.removeChild(node,node.innerText()) + } + } + }() + }); + //暂时这里支持一下老版本的属性 + var pasteplain = me.options.pasteplain; + + /** + * 启用或取消纯文本粘贴模式 + * @command pasteplain + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.queryCommandState( 'pasteplain' ); + * ``` + */ + + /** + * 查询当前是否处于纯文本粘贴模式 + * @command pasteplain + * @method queryCommandState + * @param { String } cmd 命令字符串 + * @return { int } 如果处于纯文本模式,返回1,否则,返回0 + * @example + * ```javascript + * editor.queryCommandState( 'pasteplain' ); + * ``` + */ + me.commands['pasteplain'] = { + queryCommandState: function (){ + return pasteplain ? 1 : 0; + }, + execCommand: function (){ + pasteplain = !pasteplain|0; + }, + notNeedUndo : 1 + }; +}; + +// plugins/list.js +/** + * 有序列表,无序列表插件 + * @file + * @since 1.2.6.1 + */ + +UE.plugins['list'] = function () { + var me = this, + notExchange = { + 'TD':1, + 'PRE':1, + 'BLOCKQUOTE':1 + }; + var customStyle = { + 'cn' : 'cn-1-', + 'cn1' : 'cn-2-', + 'cn2' : 'cn-3-', + 'num': 'num-1-', + 'num1' : 'num-2-', + 'num2' : 'num-3-', + 'dash' : 'dash', + 'dot':'dot' + }; + + me.setOpt( { + 'autoTransWordToList':false, + 'insertorderedlist':{ + 'num':'', + 'num1':'', + 'num2':'', + 'cn':'', + 'cn1':'', + 'cn2':'', + 'decimal':'', + 'lower-alpha':'', + 'lower-roman':'', + 'upper-alpha':'', + 'upper-roman':'' + }, + 'insertunorderedlist':{ + 'circle':'', + 'disc':'', + 'square':'', + 'dash' : '', + 'dot':'' + }, + listDefaultPaddingLeft : '30', + listiconpath : 'http://bs.baidu.com/listicon/', + maxListLevel : -1,//-1不限制 + disablePInList:false + } ); + function listToArray(list){ + var arr = []; + for(var p in list){ + arr.push(p) + } + return arr; + } + var listStyle = { + 'OL':listToArray(me.options.insertorderedlist), + 'UL':listToArray(me.options.insertunorderedlist) + }; + var liiconpath = me.options.listiconpath; + + //根据用户配置,调整customStyle + for(var s in customStyle){ + if(!me.options.insertorderedlist.hasOwnProperty(s) && !me.options.insertunorderedlist.hasOwnProperty(s)){ + delete customStyle[s]; + } + } + + me.ready(function () { + var customCss = []; + for(var p in customStyle){ + if(p == 'dash' || p == 'dot'){ + customCss.push('li.list-' + customStyle[p] + '{background-image:url(' + liiconpath +customStyle[p]+'.gif)}'); + customCss.push('ul.custom_'+p+'{list-style:none;}ul.custom_'+p+' li{background-position:0 3px;background-repeat:no-repeat}'); + }else{ + for(var i= 0;i<99;i++){ + customCss.push('li.list-' + customStyle[p] + i + '{background-image:url(' + liiconpath + 'list-'+customStyle[p] + i + '.gif)}') + } + customCss.push('ol.custom_'+p+'{list-style:none;}ol.custom_'+p+' li{background-position:0 3px;background-repeat:no-repeat}'); + } + switch(p){ + case 'cn': + customCss.push('li.list-'+p+'-paddingleft-1{padding-left:25px}'); + customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}'); + customCss.push('li.list-'+p+'-paddingleft-3{padding-left:55px}'); + break; + case 'cn1': + customCss.push('li.list-'+p+'-paddingleft-1{padding-left:30px}'); + customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}'); + customCss.push('li.list-'+p+'-paddingleft-3{padding-left:55px}'); + break; + case 'cn2': + customCss.push('li.list-'+p+'-paddingleft-1{padding-left:40px}'); + customCss.push('li.list-'+p+'-paddingleft-2{padding-left:55px}'); + customCss.push('li.list-'+p+'-paddingleft-3{padding-left:68px}'); + break; + case 'num': + case 'num1': + customCss.push('li.list-'+p+'-paddingleft-1{padding-left:25px}'); + break; + case 'num2': + customCss.push('li.list-'+p+'-paddingleft-1{padding-left:35px}'); + customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}'); + break; + case 'dash': + customCss.push('li.list-'+p+'-paddingleft{padding-left:35px}'); + break; + case 'dot': + customCss.push('li.list-'+p+'-paddingleft{padding-left:20px}'); + } + } + customCss.push('.list-paddingleft-1{padding-left:0}'); + customCss.push('.list-paddingleft-2{padding-left:'+me.options.listDefaultPaddingLeft+'px}'); + customCss.push('.list-paddingleft-3{padding-left:'+me.options.listDefaultPaddingLeft*2+'px}'); + //如果不给宽度会在自定应样式里出现滚动条 + utils.cssRule('list', 'ol,ul{margin:0;pading:0;'+(browser.ie ? '' : 'width:95%')+'}li{clear:both;}'+customCss.join('\n'), me.document); + }); + //单独处理剪切的问题 + me.ready(function(){ + domUtils.on(me.body,'cut',function(){ + setTimeout(function(){ + var rng = me.selection.getRange(),li; + //trace:3416 + if(!rng.collapsed){ + if(li = domUtils.findParentByTagName(rng.startContainer,'li',true)){ + if(!li.nextSibling && domUtils.isEmptyBlock(li)){ + var pn = li.parentNode,node; + if(node = pn.previousSibling){ + domUtils.remove(pn); + rng.setStartAtLast(node).collapse(true); + rng.select(true); + }else if(node = pn.nextSibling){ + domUtils.remove(pn); + rng.setStartAtFirst(node).collapse(true); + rng.select(true); + }else{ + var tmpNode = me.document.createElement('p'); + domUtils.fillNode(me.document,tmpNode); + pn.parentNode.insertBefore(tmpNode,pn); + domUtils.remove(pn); + rng.setStart(tmpNode,0).collapse(true); + rng.select(true); + } + } + } + } + + }) + }) + }); + + function getStyle(node){ + var cls = node.className; + if(domUtils.hasClass(node,/custom_/)){ + return cls.match(/custom_(\w+)/)[1] + } + return domUtils.getStyle(node, 'list-style-type') + + } + + me.addListener('beforepaste',function(type,html){ + var me = this, + rng = me.selection.getRange(),li; + var root = UE.htmlparser(html.html,true); + if(li = domUtils.findParentByTagName(rng.startContainer,'li',true)){ + var list = li.parentNode,tagName = list.tagName == 'OL' ? 'ul':'ol'; + utils.each(root.getNodesByTagName(tagName),function(n){ + n.tagName = list.tagName; + n.setAttr(); + if(n.parentNode === root){ + type = getStyle(list) || (list.tagName == 'OL' ? 'decimal' : 'disc') + }else{ + var className = n.parentNode.getAttr('class'); + if(className && /custom_/.test(className)){ + type = className.match(/custom_(\w+)/)[1] + }else{ + type = n.parentNode.getStyle('list-style-type'); + } + if(!type){ + type = list.tagName == 'OL' ? 'decimal' : 'disc'; + } + } + var index = utils.indexOf(listStyle[list.tagName], type); + if(n.parentNode !== root) + index = index + 1 == listStyle[list.tagName].length ? 0 : index + 1; + var currentStyle = listStyle[list.tagName][index]; + if(customStyle[currentStyle]){ + n.setAttr('class', 'custom_' + currentStyle) + + }else{ + n.setStyle('list-style-type',currentStyle) + } + }) + + } + + html.html = root.toHtml(); + }); + //导出时,去掉p标签 + me.getOpt('disablePInList') === true && me.addOutputRule(function(root){ + utils.each(root.getNodesByTagName('li'),function(li){ + var newChildrens = [],index=0; + utils.each(li.children,function(n){ + if(n.tagName == 'p'){ + var tmpNode; + while(tmpNode = n.children.pop()) { + newChildrens.splice(index,0,tmpNode); + tmpNode.parentNode = li; + lastNode = tmpNode; + } + tmpNode = newChildrens[newChildrens.length-1]; + if(!tmpNode || tmpNode.type != 'element' || tmpNode.tagName != 'br'){ + var br = UE.uNode.createElement('br'); + br.parentNode = li; + newChildrens.push(br); + } + + index = newChildrens.length; + } + }); + if(newChildrens.length){ + li.children = newChildrens; + } + }); + }); + //进入编辑器的li要套p标签 + me.addInputRule(function(root){ + utils.each(root.getNodesByTagName('li'),function(li){ + var tmpP = UE.uNode.createElement('p'); + for(var i= 0,ci;ci=li.children[i];){ + if(ci.type == 'text' || dtd.p[ci.tagName]){ + tmpP.appendChild(ci); + }else{ + if(tmpP.firstChild()){ + li.insertBefore(tmpP,ci); + tmpP = UE.uNode.createElement('p'); + i = i + 2; + }else{ + i++; + } + + } + } + if(tmpP.firstChild() && !tmpP.parentNode || !li.firstChild()){ + li.appendChild(tmpP); + } + //trace:3357 + //p不能为空 + if (!tmpP.firstChild()) { + tmpP.innerHTML(browser.ie ? ' ' : '
          ') + } + //去掉末尾的空白 + var p = li.firstChild(); + var lastChild = p.lastChild(); + if(lastChild && lastChild.type == 'text' && /^\s*$/.test(lastChild.data)){ + p.removeChild(lastChild) + } + }); + if(me.options.autoTransWordToList){ + var orderlisttype = { + 'num1':/^\d+\)/, + 'decimal':/^\d+\./, + 'lower-alpha':/^[a-z]+\)/, + 'upper-alpha':/^[A-Z]+\./, + 'cn':/^[\u4E00\u4E8C\u4E09\u56DB\u516d\u4e94\u4e03\u516b\u4e5d]+[\u3001]/, + 'cn2':/^\([\u4E00\u4E8C\u4E09\u56DB\u516d\u4e94\u4e03\u516b\u4e5d]+\)/ + }, + unorderlisttype = { + 'square':'n' + }; + function checkListType(content,container){ + var span = container.firstChild(); + if(span && span.type == 'element' && span.tagName == 'span' && /Wingdings|Symbol/.test(span.getStyle('font-family'))){ + for(var p in unorderlisttype){ + if(unorderlisttype[p] == span.data){ + return p + } + } + return 'disc' + } + for(var p in orderlisttype){ + if(orderlisttype[p].test(content)){ + return p; + } + } + + } + utils.each(root.getNodesByTagName('p'),function(node){ + if(node.getAttr('class') != 'MsoListParagraph'){ + return + } + + //word粘贴过来的会带有margin要去掉,但这样也可能会误命中一些央视 + node.setStyle('margin',''); + node.setStyle('margin-left',''); + node.setAttr('class',''); + + function appendLi(list,p,type){ + if(list.tagName == 'ol'){ + if(browser.ie){ + var first = p.firstChild(); + if(first.type =='element' && first.tagName == 'span' && orderlisttype[type].test(first.innerText())){ + p.removeChild(first); + } + }else{ + p.innerHTML(p.innerHTML().replace(orderlisttype[type],'')); + } + }else{ + p.removeChild(p.firstChild()) + } + + var li = UE.uNode.createElement('li'); + li.appendChild(p); + list.appendChild(li); + } + var tmp = node,type,cacheNode = node; + + if(node.parentNode.tagName != 'li' && (type = checkListType(node.innerText(),node))){ + + var list = UE.uNode.createElement(me.options.insertorderedlist.hasOwnProperty(type) ? 'ol' : 'ul'); + if(customStyle[type]){ + list.setAttr('class','custom_'+type) + }else{ + list.setStyle('list-style-type',type) + } + while(node && node.parentNode.tagName != 'li' && checkListType(node.innerText(),node)){ + tmp = node.nextSibling(); + if(!tmp){ + node.parentNode.insertBefore(list,node) + } + appendLi(list,node,type); + node = tmp; + } + if(!list.parentNode && node && node.parentNode){ + node.parentNode.insertBefore(list,node) + } + } + var span = cacheNode.firstChild(); + if(span && span.type == 'element' && span.tagName == 'span' && /^\s*( )+\s*$/.test(span.innerText())){ + span.parentNode.removeChild(span) + } + }) + } + + }); + + //调整索引标签 + me.addListener('contentchange',function(){ + adjustListStyle(me.document) + }); + + function adjustListStyle(doc,ignore){ + utils.each(domUtils.getElementsByTagName(doc,'ol ul'),function(node){ + + if(!domUtils.inDoc(node,doc)) + return; + + var parent = node.parentNode; + if(parent.tagName == node.tagName){ + var nodeStyleType = getStyle(node) || (node.tagName == 'OL' ? 'decimal' : 'disc'), + parentStyleType = getStyle(parent) || (parent.tagName == 'OL' ? 'decimal' : 'disc'); + if(nodeStyleType == parentStyleType){ + var styleIndex = utils.indexOf(listStyle[node.tagName], nodeStyleType); + styleIndex = styleIndex + 1 == listStyle[node.tagName].length ? 0 : styleIndex + 1; + setListStyle(node,listStyle[node.tagName][styleIndex]) + } + + } + var index = 0,type = 2; + if( domUtils.hasClass(node,/custom_/)){ + if(!(/[ou]l/i.test(parent.tagName) && domUtils.hasClass(parent,/custom_/))){ + type = 1; + } + }else{ + if(/[ou]l/i.test(parent.tagName) && domUtils.hasClass(parent,/custom_/)){ + type = 3; + } + } + + var style = domUtils.getStyle(node, 'list-style-type'); + style && (node.style.cssText = 'list-style-type:' + style); + node.className = utils.trim(node.className.replace(/list-paddingleft-\w+/,'')) + ' list-paddingleft-' + type; + utils.each(domUtils.getElementsByTagName(node,'li'),function(li){ + li.style.cssText && (li.style.cssText = ''); + if(!li.firstChild){ + domUtils.remove(li); + return; + } + if(li.parentNode !== node){ + return; + } + index++; + if(domUtils.hasClass(node,/custom_/) ){ + var paddingLeft = 1,currentStyle = getStyle(node); + if(node.tagName == 'OL'){ + if(currentStyle){ + switch(currentStyle){ + case 'cn' : + case 'cn1': + case 'cn2': + if(index > 10 && (index % 10 == 0 || index > 10 && index < 20)){ + paddingLeft = 2 + }else if(index > 20){ + paddingLeft = 3 + } + break; + case 'num2' : + if(index > 9){ + paddingLeft = 2 + } + } + } + li.className = 'list-'+customStyle[currentStyle]+ index + ' ' + 'list-'+currentStyle+'-paddingleft-' + paddingLeft; + }else{ + li.className = 'list-'+customStyle[currentStyle] + ' ' + 'list-'+currentStyle+'-paddingleft'; + } + }else{ + li.className = li.className.replace(/list-[\w\-]+/gi,''); + } + var className = li.getAttribute('class'); + if(className !== null && !className.replace(/\s/g,'')){ + domUtils.removeAttributes(li,'class') + } + }); + !ignore && adjustList(node,node.tagName.toLowerCase(),getStyle(node)||domUtils.getStyle(node, 'list-style-type'),true); + }) + } + function adjustList(list, tag, style,ignoreEmpty) { + var nextList = list.nextSibling; + if (nextList && nextList.nodeType == 1 && nextList.tagName.toLowerCase() == tag && (getStyle(nextList) || domUtils.getStyle(nextList, 'list-style-type') || (tag == 'ol' ? 'decimal' : 'disc')) == style) { + domUtils.moveChild(nextList, list); + if (nextList.childNodes.length == 0) { + domUtils.remove(nextList); + } + } + if(nextList && domUtils.isFillChar(nextList)){ + domUtils.remove(nextList); + } + var preList = list.previousSibling; + if (preList && preList.nodeType == 1 && preList.tagName.toLowerCase() == tag && (getStyle(preList) || domUtils.getStyle(preList, 'list-style-type') || (tag == 'ol' ? 'decimal' : 'disc')) == style) { + domUtils.moveChild(list, preList); + } + if(preList && domUtils.isFillChar(preList)){ + domUtils.remove(preList); + } + !ignoreEmpty && domUtils.isEmptyBlock(list) && domUtils.remove(list); + if(getStyle(list)){ + adjustListStyle(list.ownerDocument,true) + } + } + + function setListStyle(list,style){ + if(customStyle[style]){ + list.className = 'custom_' + style; + } + try{ + domUtils.setStyle(list, 'list-style-type', style); + }catch(e){} + } + function clearEmptySibling(node) { + var tmpNode = node.previousSibling; + if (tmpNode && domUtils.isEmptyBlock(tmpNode)) { + domUtils.remove(tmpNode); + } + tmpNode = node.nextSibling; + if (tmpNode && domUtils.isEmptyBlock(tmpNode)) { + domUtils.remove(tmpNode); + } + } + + me.addListener('keydown', function (type, evt) { + function preventAndSave() { + evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false); + me.fireEvent('contentchange'); + me.undoManger && me.undoManger.save(); + } + function findList(node,filterFn){ + while(node && !domUtils.isBody(node)){ + if(filterFn(node)){ + return null + } + if(node.nodeType == 1 && /[ou]l/i.test(node.tagName)){ + return node; + } + node = node.parentNode; + } + return null; + } + var keyCode = evt.keyCode || evt.which; + if (keyCode == 13 && !evt.shiftKey) {//回车 + var rng = me.selection.getRange(), + parent = domUtils.findParent(rng.startContainer,function(node){return domUtils.isBlockElm(node)},true), + li = domUtils.findParentByTagName(rng.startContainer,'li',true); + if(parent && parent.tagName != 'PRE' && !li){ + var html = parent.innerHTML.replace(new RegExp(domUtils.fillChar, 'g'),''); + if(/^\s*1\s*\.[^\d]/.test(html)){ + parent.innerHTML = html.replace(/^\s*1\s*\./,''); + rng.setStartAtLast(parent).collapse(true).select(); + me.__hasEnterExecCommand = true; + me.execCommand('insertorderedlist'); + me.__hasEnterExecCommand = false; + } + } + var range = me.selection.getRange(), + start = findList(range.startContainer,function (node) { + return node.tagName == 'TABLE'; + }), + end = range.collapsed ? start : findList(range.endContainer,function (node) { + return node.tagName == 'TABLE'; + }); + + if (start && end && start === end) { + + if (!range.collapsed) { + start = domUtils.findParentByTagName(range.startContainer, 'li', true); + end = domUtils.findParentByTagName(range.endContainer, 'li', true); + if (start && end && start === end) { + range.deleteContents(); + li = domUtils.findParentByTagName(range.startContainer, 'li', true); + if (li && domUtils.isEmptyBlock(li)) { + + pre = li.previousSibling; + next = li.nextSibling; + p = me.document.createElement('p'); + + domUtils.fillNode(me.document, p); + parentList = li.parentNode; + if (pre && next) { + range.setStart(next, 0).collapse(true).select(true); + domUtils.remove(li); + + } else { + if (!pre && !next || !pre) { + + parentList.parentNode.insertBefore(p, parentList); + + + } else { + li.parentNode.parentNode.insertBefore(p, parentList.nextSibling); + } + domUtils.remove(li); + if (!parentList.firstChild) { + domUtils.remove(parentList); + } + range.setStart(p, 0).setCursor(); + + + } + preventAndSave(); + return; + + } + } else { + var tmpRange = range.cloneRange(), + bk = tmpRange.collapse(false).createBookmark(); + + range.deleteContents(); + tmpRange.moveToBookmark(bk); + var li = domUtils.findParentByTagName(tmpRange.startContainer, 'li', true); + + clearEmptySibling(li); + tmpRange.select(); + preventAndSave(); + return; + } + } + + + li = domUtils.findParentByTagName(range.startContainer, 'li', true); + + if (li) { + if (domUtils.isEmptyBlock(li)) { + bk = range.createBookmark(); + var parentList = li.parentNode; + if (li !== parentList.lastChild) { + domUtils.breakParent(li, parentList); + clearEmptySibling(li); + } else { + + parentList.parentNode.insertBefore(li, parentList.nextSibling); + if (domUtils.isEmptyNode(parentList)) { + domUtils.remove(parentList); + } + } + //嵌套不处理 + if (!dtd.$list[li.parentNode.tagName]) { + + if (!domUtils.isBlockElm(li.firstChild)) { + p = me.document.createElement('p'); + li.parentNode.insertBefore(p, li); + while (li.firstChild) { + p.appendChild(li.firstChild); + } + domUtils.remove(li); + } else { + domUtils.remove(li, true); + } + } + range.moveToBookmark(bk).select(); + + + } else { + var first = li.firstChild; + if (!first || !domUtils.isBlockElm(first)) { + var p = me.document.createElement('p'); + + !li.firstChild && domUtils.fillNode(me.document, p); + while (li.firstChild) { + + p.appendChild(li.firstChild); + } + li.appendChild(p); + first = p; + } + + var span = me.document.createElement('span'); + + range.insertNode(span); + domUtils.breakParent(span, li); + + var nextLi = span.nextSibling; + first = nextLi.firstChild; + + if (!first) { + p = me.document.createElement('p'); + + domUtils.fillNode(me.document, p); + nextLi.appendChild(p); + first = p; + } + if (domUtils.isEmptyNode(first)) { + first.innerHTML = ''; + domUtils.fillNode(me.document, first); + } + + range.setStart(first, 0).collapse(true).shrinkBoundary().select(); + domUtils.remove(span); + var pre = nextLi.previousSibling; + if (pre && domUtils.isEmptyBlock(pre)) { + pre.innerHTML = '

          '; + domUtils.fillNode(me.document, pre.firstChild); + } + + } +// } + preventAndSave(); + } + + + } + + + } + if (keyCode == 8) { + //修中ie中li下的问题 + range = me.selection.getRange(); + if (range.collapsed && domUtils.isStartInblock(range)) { + tmpRange = range.cloneRange().trimBoundary(); + li = domUtils.findParentByTagName(range.startContainer, 'li', true); + //要在li的最左边,才能处理 + if (li && domUtils.isStartInblock(tmpRange)) { + start = domUtils.findParentByTagName(range.startContainer, 'p', true); + if (start && start !== li.firstChild) { + var parentList = domUtils.findParentByTagName(start,['ol','ul']); + domUtils.breakParent(start,parentList); + clearEmptySibling(start); + me.fireEvent('contentchange'); + range.setStart(start,0).setCursor(false,true); + me.fireEvent('saveScene'); + domUtils.preventDefault(evt); + return; + } + + if (li && (pre = li.previousSibling)) { + if (keyCode == 46 && li.childNodes.length) { + return; + } + //有可能上边的兄弟节点是个2级菜单,要追加到2级菜单的最后的li + if (dtd.$list[pre.tagName]) { + pre = pre.lastChild; + } + me.undoManger && me.undoManger.save(); + first = li.firstChild; + if (domUtils.isBlockElm(first)) { + if (domUtils.isEmptyNode(first)) { +// range.setEnd(pre, pre.childNodes.length).shrinkBoundary().collapse().select(true); + pre.appendChild(first); + range.setStart(first, 0).setCursor(false, true); + //first不是唯一的节点 + while (li.firstChild) { + pre.appendChild(li.firstChild); + } + } else { + + span = me.document.createElement('span'); + range.insertNode(span); + //判断pre是否是空的节点,如果是


          类型的空节点,干掉p标签防止它占位 + if (domUtils.isEmptyBlock(pre)) { + pre.innerHTML = ''; + } + domUtils.moveChild(li, pre); + range.setStartBefore(span).collapse(true).select(true); + + domUtils.remove(span); + + } + } else { + if (domUtils.isEmptyNode(li)) { + var p = me.document.createElement('p'); + pre.appendChild(p); + range.setStart(p, 0).setCursor(); +// range.setEnd(pre, pre.childNodes.length).shrinkBoundary().collapse().select(true); + } else { + range.setEnd(pre, pre.childNodes.length).collapse().select(true); + while (li.firstChild) { + pre.appendChild(li.firstChild); + } + } + } + domUtils.remove(li); + me.fireEvent('contentchange'); + me.fireEvent('saveScene'); + domUtils.preventDefault(evt); + return; + + } + //trace:980 + + if (li && !li.previousSibling) { + var parentList = li.parentNode; + var bk = range.createBookmark(); + if(domUtils.isTagNode(parentList.parentNode,'ol ul')){ + parentList.parentNode.insertBefore(li,parentList); + if(domUtils.isEmptyNode(parentList)){ + domUtils.remove(parentList) + } + }else{ + + while(li.firstChild){ + parentList.parentNode.insertBefore(li.firstChild,parentList); + } + + domUtils.remove(li); + if(domUtils.isEmptyNode(parentList)){ + domUtils.remove(parentList) + } + + } + range.moveToBookmark(bk).setCursor(false,true); + me.fireEvent('contentchange'); + me.fireEvent('saveScene'); + domUtils.preventDefault(evt); + return; + + } + + + } + + + } + + } + }); + + me.addListener('keyup',function(type, evt){ + var keyCode = evt.keyCode || evt.which; + if (keyCode == 8) { + var rng = me.selection.getRange(),list; + if(list = domUtils.findParentByTagName(rng.startContainer,['ol', 'ul'],true)){ + adjustList(list,list.tagName.toLowerCase(),getStyle(list)||domUtils.getComputedStyle(list,'list-style-type'),true) + } + } + }); + //处理tab键 + me.addListener('tabkeydown',function(){ + + var range = me.selection.getRange(); + + //控制级数 + function checkLevel(li){ + if(me.options.maxListLevel != -1){ + var level = li.parentNode,levelNum = 0; + while(/[ou]l/i.test(level.tagName)){ + levelNum++; + level = level.parentNode; + } + if(levelNum >= me.options.maxListLevel){ + return true; + } + } + } + //只以开始为准 + //todo 后续改进 + var li = domUtils.findParentByTagName(range.startContainer, 'li', true); + if(li){ + + var bk; + if(range.collapsed){ + if(checkLevel(li)) + return true; + var parentLi = li.parentNode, + list = me.document.createElement(parentLi.tagName), + index = utils.indexOf(listStyle[list.tagName], getStyle(parentLi)||domUtils.getComputedStyle(parentLi, 'list-style-type')); + index = index + 1 == listStyle[list.tagName].length ? 0 : index + 1; + var currentStyle = listStyle[list.tagName][index]; + setListStyle(list,currentStyle); + if(domUtils.isStartInblock(range)){ + me.fireEvent('saveScene'); + bk = range.createBookmark(); + parentLi.insertBefore(list, li); + list.appendChild(li); + adjustList(list,list.tagName.toLowerCase(),currentStyle); + me.fireEvent('contentchange'); + range.moveToBookmark(bk).select(true); + return true; + } + }else{ + me.fireEvent('saveScene'); + bk = range.createBookmark(); + for(var i= 0,closeList,parents = domUtils.findParents(li),ci;ci=parents[i++];){ + if(domUtils.isTagNode(ci,'ol ul')){ + closeList = ci; + break; + } + } + var current = li; + if(bk.end){ + while(current && !(domUtils.getPosition(current, bk.end) & domUtils.POSITION_FOLLOWING)){ + if(checkLevel(current)){ + current = domUtils.getNextDomNode(current,false,null,function(node){return node !== closeList}); + continue; + } + var parentLi = current.parentNode, + list = me.document.createElement(parentLi.tagName), + index = utils.indexOf(listStyle[list.tagName], getStyle(parentLi)||domUtils.getComputedStyle(parentLi, 'list-style-type')); + var currentIndex = index + 1 == listStyle[list.tagName].length ? 0 : index + 1; + var currentStyle = listStyle[list.tagName][currentIndex]; + setListStyle(list,currentStyle); + parentLi.insertBefore(list, current); + while(current && !(domUtils.getPosition(current, bk.end) & domUtils.POSITION_FOLLOWING)){ + li = current.nextSibling; + list.appendChild(current); + if(!li || domUtils.isTagNode(li,'ol ul')){ + if(li){ + while(li = li.firstChild){ + if(li.tagName == 'LI'){ + break; + } + } + }else{ + li = domUtils.getNextDomNode(current,false,null,function(node){return node !== closeList}); + } + break; + } + current = li; + } + adjustList(list,list.tagName.toLowerCase(),currentStyle); + current = li; + } + } + me.fireEvent('contentchange'); + range.moveToBookmark(bk).select(); + return true; + } + } + + }); + function getLi(start){ + while(start && !domUtils.isBody(start)){ + if(start.nodeName == 'TABLE'){ + return null; + } + if(start.nodeName == 'LI'){ + return start + } + start = start.parentNode; + } + } + + /** + * 有序列表,与“insertunorderedlist”命令互斥 + * @command insertorderedlist + * @method execCommand + * @param { String } command 命令字符串 + * @param { String } style 插入的有序列表类型,值为:decimal,lower-alpha,lower-roman,upper-alpha,upper-roman,cn,cn1,cn2,num,num1,num2 + * @example + * ```javascript + * editor.execCommand( 'insertorderedlist','decimal'); + * ``` + */ + /** + * 查询当前选区内容是否有序列表 + * @command insertorderedlist + * @method queryCommandState + * @param { String } cmd 命令字符串 + * @return { int } 如果当前选区是有序列表返回1,否则返回0 + * @example + * ```javascript + * editor.queryCommandState( 'insertorderedlist' ); + * ``` + */ + /** + * 查询当前选区内容是否有序列表 + * @command insertorderedlist + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @return { String } 返回当前有序列表的类型,值为null或decimal,lower-alpha,lower-roman,upper-alpha,upper-roman,cn,cn1,cn2,num,num1,num2 + * @example + * ```javascript + * editor.queryCommandValue( 'insertorderedlist' ); + * ``` + */ + + /** + * 无序列表,与“insertorderedlist”命令互斥 + * @command insertunorderedlist + * @method execCommand + * @param { String } command 命令字符串 + * @param { String } style 插入的无序列表类型,值为:circle,disc,square,dash,dot + * @example + * ```javascript + * editor.execCommand( 'insertunorderedlist','circle'); + * ``` + */ + /** + * 查询当前是否有word文档粘贴进来的图片 + * @command insertunorderedlist + * @method insertunorderedlist + * @param { String } command 命令字符串 + * @return { int } 如果当前选区是无序列表返回1,否则返回0 + * @example + * ```javascript + * editor.queryCommandState( 'insertunorderedlist' ); + * ``` + */ + /** + * 查询当前选区内容是否有序列表 + * @command insertunorderedlist + * @method queryCommandValue + * @param { String } command 命令字符串 + * @return { String } 返回当前无序列表的类型,值为null或circle,disc,square,dash,dot + * @example + * ```javascript + * editor.queryCommandValue( 'insertunorderedlist' ); + * ``` + */ + + me.commands['insertorderedlist'] = + me.commands['insertunorderedlist'] = { + execCommand:function (command, style) { + + if (!style) { + style = command.toLowerCase() == 'insertorderedlist' ? 'decimal' : 'disc'; + } + var me = this, + range = this.selection.getRange(), + filterFn = function (node) { + return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' : !domUtils.isWhitespace(node); + }, + tag = command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul', + frag = me.document.createDocumentFragment(); + //去掉是因为会出现选到末尾,导致adjustmentBoundary缩到ol/ul的位置 + //range.shrinkBoundary();//.adjustmentBoundary(); + range.adjustmentBoundary().shrinkBoundary(); + var bko = range.createBookmark(true), + start = getLi(me.document.getElementById(bko.start)), + modifyStart = 0, + end = getLi(me.document.getElementById(bko.end)), + modifyEnd = 0, + startParent, endParent, + list, tmp; + + if (start || end) { + start && (startParent = start.parentNode); + if (!bko.end) { + end = start; + } + end && (endParent = end.parentNode); + + if (startParent === endParent) { + while (start !== end) { + tmp = start; + start = start.nextSibling; + if (!domUtils.isBlockElm(tmp.firstChild)) { + var p = me.document.createElement('p'); + while (tmp.firstChild) { + p.appendChild(tmp.firstChild); + } + tmp.appendChild(p); + } + frag.appendChild(tmp); + } + tmp = me.document.createElement('span'); + startParent.insertBefore(tmp, end); + if (!domUtils.isBlockElm(end.firstChild)) { + p = me.document.createElement('p'); + while (end.firstChild) { + p.appendChild(end.firstChild); + } + end.appendChild(p); + } + frag.appendChild(end); + domUtils.breakParent(tmp, startParent); + if (domUtils.isEmptyNode(tmp.previousSibling)) { + domUtils.remove(tmp.previousSibling); + } + if (domUtils.isEmptyNode(tmp.nextSibling)) { + domUtils.remove(tmp.nextSibling) + } + var nodeStyle = getStyle(startParent) || domUtils.getComputedStyle(startParent, 'list-style-type') || (command.toLowerCase() == 'insertorderedlist' ? 'decimal' : 'disc'); + if (startParent.tagName.toLowerCase() == tag && nodeStyle == style) { + for (var i = 0, ci, tmpFrag = me.document.createDocumentFragment(); ci = frag.firstChild;) { + if(domUtils.isTagNode(ci,'ol ul')){ +// 删除时,子列表不处理 +// utils.each(domUtils.getElementsByTagName(ci,'li'),function(li){ +// while(li.firstChild){ +// tmpFrag.appendChild(li.firstChild); +// } +// +// }); + tmpFrag.appendChild(ci); + }else{ + while (ci.firstChild) { + + tmpFrag.appendChild(ci.firstChild); + domUtils.remove(ci); + } + } + + } + tmp.parentNode.insertBefore(tmpFrag, tmp); + } else { + list = me.document.createElement(tag); + setListStyle(list,style); + list.appendChild(frag); + tmp.parentNode.insertBefore(list, tmp); + } + + domUtils.remove(tmp); + list && adjustList(list, tag, style); + range.moveToBookmark(bko).select(); + return; + } + //开始 + if (start) { + while (start) { + tmp = start.nextSibling; + if (domUtils.isTagNode(start, 'ol ul')) { + frag.appendChild(start); + } else { + var tmpfrag = me.document.createDocumentFragment(), + hasBlock = 0; + while (start.firstChild) { + if (domUtils.isBlockElm(start.firstChild)) { + hasBlock = 1; + } + tmpfrag.appendChild(start.firstChild); + } + if (!hasBlock) { + var tmpP = me.document.createElement('p'); + tmpP.appendChild(tmpfrag); + frag.appendChild(tmpP); + } else { + frag.appendChild(tmpfrag); + } + domUtils.remove(start); + } + + start = tmp; + } + startParent.parentNode.insertBefore(frag, startParent.nextSibling); + if (domUtils.isEmptyNode(startParent)) { + range.setStartBefore(startParent); + domUtils.remove(startParent); + } else { + range.setStartAfter(startParent); + } + modifyStart = 1; + } + + if (end && domUtils.inDoc(endParent, me.document)) { + //结束 + start = endParent.firstChild; + while (start && start !== end) { + tmp = start.nextSibling; + if (domUtils.isTagNode(start, 'ol ul')) { + frag.appendChild(start); + } else { + tmpfrag = me.document.createDocumentFragment(); + hasBlock = 0; + while (start.firstChild) { + if (domUtils.isBlockElm(start.firstChild)) { + hasBlock = 1; + } + tmpfrag.appendChild(start.firstChild); + } + if (!hasBlock) { + tmpP = me.document.createElement('p'); + tmpP.appendChild(tmpfrag); + frag.appendChild(tmpP); + } else { + frag.appendChild(tmpfrag); + } + domUtils.remove(start); + } + start = tmp; + } + var tmpDiv = domUtils.createElement(me.document, 'div', { + 'tmpDiv':1 + }); + domUtils.moveChild(end, tmpDiv); + + frag.appendChild(tmpDiv); + domUtils.remove(end); + endParent.parentNode.insertBefore(frag, endParent); + range.setEndBefore(endParent); + if (domUtils.isEmptyNode(endParent)) { + domUtils.remove(endParent); + } + + modifyEnd = 1; + } + + + } + + if (!modifyStart) { + range.setStartBefore(me.document.getElementById(bko.start)); + } + if (bko.end && !modifyEnd) { + range.setEndAfter(me.document.getElementById(bko.end)); + } + range.enlarge(true, function (node) { + return notExchange[node.tagName]; + }); + + frag = me.document.createDocumentFragment(); + + var bk = range.createBookmark(), + current = domUtils.getNextDomNode(bk.start, false, filterFn), + tmpRange = range.cloneRange(), + tmpNode, + block = domUtils.isBlockElm; + + while (current && current !== bk.end && (domUtils.getPosition(current, bk.end) & domUtils.POSITION_PRECEDING)) { + + if (current.nodeType == 3 || dtd.li[current.tagName]) { + if (current.nodeType == 1 && dtd.$list[current.tagName]) { + while (current.firstChild) { + frag.appendChild(current.firstChild); + } + tmpNode = domUtils.getNextDomNode(current, false, filterFn); + domUtils.remove(current); + current = tmpNode; + continue; + + } + tmpNode = current; + tmpRange.setStartBefore(current); + + while (current && current !== bk.end && (!block(current) || domUtils.isBookmarkNode(current) )) { + tmpNode = current; + current = domUtils.getNextDomNode(current, false, null, function (node) { + return !notExchange[node.tagName]; + }); + } + + if (current && block(current)) { + tmp = domUtils.getNextDomNode(tmpNode, false, filterFn); + if (tmp && domUtils.isBookmarkNode(tmp)) { + current = domUtils.getNextDomNode(tmp, false, filterFn); + tmpNode = tmp; + } + } + tmpRange.setEndAfter(tmpNode); + + current = domUtils.getNextDomNode(tmpNode, false, filterFn); + + var li = range.document.createElement('li'); + + li.appendChild(tmpRange.extractContents()); + if(domUtils.isEmptyNode(li)){ + var tmpNode = range.document.createElement('p'); + while(li.firstChild){ + tmpNode.appendChild(li.firstChild) + } + li.appendChild(tmpNode); + } + frag.appendChild(li); + } else { + current = domUtils.getNextDomNode(current, true, filterFn); + } + } + range.moveToBookmark(bk).collapse(true); + list = me.document.createElement(tag); + setListStyle(list,style); + list.appendChild(frag); + range.insertNode(list); + //当前list上下看能否合并 + adjustList(list, tag, style); + //去掉冗余的tmpDiv + for (var i = 0, ci, tmpDivs = domUtils.getElementsByTagName(list, 'div'); ci = tmpDivs[i++];) { + if (ci.getAttribute('tmpDiv')) { + domUtils.remove(ci, true) + } + } + range.moveToBookmark(bko).select(); + + }, + queryCommandState:function (command) { + var tag = command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul'; + var path = this.selection.getStartElementPath(); + for(var i= 0,ci;ci = path[i++];){ + if(ci.nodeName == 'TABLE'){ + return 0 + } + if(tag == ci.nodeName.toLowerCase()){ + return 1 + }; + } + return 0; + + }, + queryCommandValue:function (command) { + var tag = command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul'; + var path = this.selection.getStartElementPath(), + node; + for(var i= 0,ci;ci = path[i++];){ + if(ci.nodeName == 'TABLE'){ + node = null; + break; + } + if(tag == ci.nodeName.toLowerCase()){ + node = ci; + break; + }; + } + return node ? getStyle(node) || domUtils.getComputedStyle(node, 'list-style-type') : null; + } + }; +}; + + + +// plugins/source.js +/** + * 源码编辑插件 + * @file + * @since 1.2.6.1 + */ + +(function (){ + var sourceEditors = { + textarea: function (editor, holder){ + var textarea = holder.ownerDocument.createElement('textarea'); + textarea.style.cssText = 'position:absolute;resize:none;width:100%;height:100%;border:0;padding:0;margin:0;overflow-y:auto;'; + // todo: IE下只有onresize属性可用... 很纠结 + if (browser.ie && browser.version < 8) { + textarea.style.width = holder.offsetWidth + 'px'; + textarea.style.height = holder.offsetHeight + 'px'; + holder.onresize = function (){ + textarea.style.width = holder.offsetWidth + 'px'; + textarea.style.height = holder.offsetHeight + 'px'; + }; + } + holder.appendChild(textarea); + return { + setContent: function (content){ + textarea.value = content; + }, + getContent: function (){ + return textarea.value; + }, + select: function (){ + var range; + if (browser.ie) { + range = textarea.createTextRange(); + range.collapse(true); + range.select(); + } else { + //todo: chrome下无法设置焦点 + textarea.setSelectionRange(0, 0); + textarea.focus(); + } + }, + dispose: function (){ + holder.removeChild(textarea); + // todo + holder.onresize = null; + textarea = null; + holder = null; + } + }; + }, + codemirror: function (editor, holder){ + + var codeEditor = window.CodeMirror(holder, { + mode: "text/html", + tabMode: "indent", + lineNumbers: true, + lineWrapping:true + }); + var dom = codeEditor.getWrapperElement(); + dom.style.cssText = 'position:absolute;left:0;top:0;width:100%;height:100%;font-family:consolas,"Courier new",monospace;font-size:13px;'; + codeEditor.getScrollerElement().style.cssText = 'position:absolute;left:0;top:0;width:100%;height:100%;'; + codeEditor.refresh(); + return { + getCodeMirror:function(){ + return codeEditor; + }, + setContent: function (content){ + codeEditor.setValue(content); + }, + getContent: function (){ + return codeEditor.getValue(); + }, + select: function (){ + codeEditor.focus(); + }, + dispose: function (){ + holder.removeChild(dom); + dom = null; + codeEditor = null; + } + }; + } + }; + + UE.plugins['source'] = function (){ + var me = this; + var opt = this.options; + var sourceMode = false; + var sourceEditor; + var orgSetContent; + opt.sourceEditor = browser.ie ? 'textarea' : (opt.sourceEditor || 'codemirror'); + + me.setOpt({ + sourceEditorFirst:false + }); + function createSourceEditor(holder){ + return sourceEditors[opt.sourceEditor == 'codemirror' && window.CodeMirror ? 'codemirror' : 'textarea'](me, holder); + } + + var bakCssText; + //解决在源码模式下getContent不能得到最新的内容问题 + var oldGetContent, + bakAddress; + + /** + * 切换源码模式和编辑模式 + * @command source + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'source'); + * ``` + */ + + /** + * 查询当前编辑区域的状态是源码模式还是可视化模式 + * @command source + * @method queryCommandState + * @param { String } cmd 命令字符串 + * @return { int } 如果当前是源码编辑模式,返回1,否则返回0 + * @example + * ```javascript + * editor.queryCommandState( 'source' ); + * ``` + */ + + me.commands['source'] = { + execCommand: function (){ + + sourceMode = !sourceMode; + if (sourceMode) { + bakAddress = me.selection.getRange().createAddress(false,true); + me.undoManger && me.undoManger.save(true); + if(browser.gecko){ + me.body.contentEditable = false; + } + + bakCssText = me.iframe.style.cssText; + me.iframe.style.cssText += 'position:absolute;left:-32768px;top:-32768px;'; + + + me.fireEvent('beforegetcontent'); + var root = UE.htmlparser(me.body.innerHTML); + me.filterOutputRule(root); + root.traversal(function (node) { + if (node.type == 'element') { + switch (node.tagName) { + case 'td': + case 'th': + case 'caption': + if(node.children && node.children.length == 1){ + if(node.firstChild().tagName == 'br' ){ + node.removeChild(node.firstChild()) + } + }; + break; + case 'pre': + node.innerText(node.innerText().replace(/ /g,' ')) + + } + } + }); + + me.fireEvent('aftergetcontent'); + + var content = root.toHtml(true); + + sourceEditor = createSourceEditor(me.iframe.parentNode); + + sourceEditor.setContent(content); + + orgSetContent = me.setContent; + + me.setContent = function(html){ + //这里暂时不触发事件,防止报错 + var root = UE.htmlparser(html); + me.filterInputRule(root); + html = root.toHtml(); + sourceEditor.setContent(html); + }; + + setTimeout(function (){ + sourceEditor.select(); + me.addListener('fullscreenchanged', function(){ + try{ + sourceEditor.getCodeMirror().refresh() + }catch(e){} + }); + }); + + //重置getContent,源码模式下取值也能是最新的数据 + oldGetContent = me.getContent; + me.getContent = function (){ + return sourceEditor.getContent() || '

          ' + (browser.ie ? '' : '
          ')+'

          '; + }; + } else { + me.iframe.style.cssText = bakCssText; + var cont = sourceEditor.getContent() || '

          ' + (browser.ie ? '' : '
          ')+'

          '; + //处理掉block节点前后的空格,有可能会误命中,暂时不考虑 + cont = cont.replace(new RegExp('[\\r\\t\\n ]*<\/?(\\w+)\\s*(?:[^>]*)>','g'), function(a,b){ + if(b && !dtd.$inlineWithA[b.toLowerCase()]){ + return a.replace(/(^[\n\r\t ]*)|([\n\r\t ]*$)/g,''); + } + return a.replace(/(^[\n\r\t]*)|([\n\r\t]*$)/g,'') + }); + me.setContent = orgSetContent; + + me.setContent(cont); + sourceEditor.dispose(); + sourceEditor = null; + //还原getContent方法 + me.getContent = oldGetContent; + var first = me.body.firstChild; + //trace:1106 都删除空了,下边会报错,所以补充一个p占位 + if(!first){ + me.body.innerHTML = '

          '+(browser.ie?'':'
          ')+'

          '; + first = me.body.firstChild; + } + + + //要在ifm为显示时ff才能取到selection,否则报错 + //这里不能比较位置了 + me.undoManger && me.undoManger.save(true); + + if(browser.gecko){ + + var input = document.createElement('input'); + input.style.cssText = 'position:absolute;left:0;top:-32768px'; + + document.body.appendChild(input); + + me.body.contentEditable = false; + setTimeout(function(){ + domUtils.setViewportOffset(input, { left: -32768, top: 0 }); + input.focus(); + setTimeout(function(){ + me.body.contentEditable = true; + me.selection.getRange().moveToAddress(bakAddress).select(true); + domUtils.remove(input); + }); + + }); + }else{ + //ie下有可能报错,比如在代码顶头的情况 + try{ + me.selection.getRange().moveToAddress(bakAddress).select(true); + }catch(e){} + + } + } + this.fireEvent('sourcemodechanged', sourceMode); + }, + queryCommandState: function (){ + return sourceMode|0; + }, + notNeedUndo : 1 + }; + var oldQueryCommandState = me.queryCommandState; + + me.queryCommandState = function (cmdName){ + cmdName = cmdName.toLowerCase(); + if (sourceMode) { + //源码模式下可以开启的命令 + return cmdName in { + 'source' : 1, + 'fullscreen' : 1 + } ? 1 : -1 + } + return oldQueryCommandState.apply(this, arguments); + }; + + if(opt.sourceEditor == "codemirror"){ + + me.addListener("ready",function(){ + utils.loadFile(document,{ + src : opt.codeMirrorJsUrl || opt.UEDITOR_HOME_URL + "third-party/codemirror/codemirror.js", + tag : "script", + type : "text/javascript", + defer : "defer" + },function(){ + if(opt.sourceEditorFirst){ + setTimeout(function(){ + me.execCommand("source"); + },0); + } + }); + utils.loadFile(document,{ + tag : "link", + rel : "stylesheet", + type : "text/css", + href : opt.codeMirrorCssUrl || opt.UEDITOR_HOME_URL + "third-party/codemirror/codemirror.css" + }); + + }); + } + + }; + +})(); + +// plugins/enterkey.js +///import core +///import plugins/undo.js +///commands 设置回车标签p或br +///commandsName EnterKey +///commandsTitle 设置回车标签p或br +/** + * @description 处理回车 + * @author zhanyi + */ +UE.plugins['enterkey'] = function() { + var hTag, + me = this, + tag = me.options.enterTag; + me.addListener('keyup', function(type, evt) { + + var keyCode = evt.keyCode || evt.which; + if (keyCode == 13) { + var range = me.selection.getRange(), + start = range.startContainer, + doSave; + + //修正在h1-h6里边回车后不能嵌套p的问题 + if (!browser.ie) { + + if (/h\d/i.test(hTag)) { + if (browser.gecko) { + var h = domUtils.findParentByTagName(start, [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6','blockquote','caption','table'], true); + if (!h) { + me.document.execCommand('formatBlock', false, '

          '); + doSave = 1; + } + } else { + //chrome remove div + if (start.nodeType == 1) { + var tmp = me.document.createTextNode(''),div; + range.insertNode(tmp); + div = domUtils.findParentByTagName(tmp, 'div', true); + if (div) { + var p = me.document.createElement('p'); + while (div.firstChild) { + p.appendChild(div.firstChild); + } + div.parentNode.insertBefore(p, div); + domUtils.remove(div); + range.setStartBefore(tmp).setCursor(); + doSave = 1; + } + domUtils.remove(tmp); + + } + } + + if (me.undoManger && doSave) { + me.undoManger.save(); + } + } + //没有站位符,会出现多行的问题 + browser.opera && range.select(); + }else{ + me.fireEvent('saveScene',true,true) + } + } + }); + + me.addListener('keydown', function(type, evt) { + var keyCode = evt.keyCode || evt.which; + if (keyCode == 13) {//回车 + if(me.fireEvent('beforeenterkeydown')){ + domUtils.preventDefault(evt); + return; + } + me.fireEvent('saveScene',true,true); + hTag = ''; + + + var range = me.selection.getRange(); + + if (!range.collapsed) { + //跨td不能删 + var start = range.startContainer, + end = range.endContainer, + startTd = domUtils.findParentByTagName(start, 'td', true), + endTd = domUtils.findParentByTagName(end, 'td', true); + if (startTd && endTd && startTd !== endTd || !startTd && endTd || startTd && !endTd) { + evt.preventDefault ? evt.preventDefault() : ( evt.returnValue = false); + return; + } + } + if (tag == 'p') { + + + if (!browser.ie) { + + start = domUtils.findParentByTagName(range.startContainer, ['ol','ul','p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6','blockquote','caption'], true); + + //opera下执行formatblock会在table的场景下有问题,回车在opera原生支持很好,所以暂时在opera去掉调用这个原生的command + //trace:2431 + if (!start && !browser.opera) { + + me.document.execCommand('formatBlock', false, '

          '); + + if (browser.gecko) { + range = me.selection.getRange(); + start = domUtils.findParentByTagName(range.startContainer, 'p', true); + start && domUtils.removeDirtyAttr(start); + } + + + } else { + hTag = start.tagName; + start.tagName.toLowerCase() == 'p' && browser.gecko && domUtils.removeDirtyAttr(start); + } + + } + + } else { + evt.preventDefault ? evt.preventDefault() : ( evt.returnValue = false); + + if (!range.collapsed) { + range.deleteContents(); + start = range.startContainer; + if (start.nodeType == 1 && (start = start.childNodes[range.startOffset])) { + while (start.nodeType == 1) { + if (dtd.$empty[start.tagName]) { + range.setStartBefore(start).setCursor(); + if (me.undoManger) { + me.undoManger.save(); + } + return false; + } + if (!start.firstChild) { + var br = range.document.createElement('br'); + start.appendChild(br); + range.setStart(start, 0).setCursor(); + if (me.undoManger) { + me.undoManger.save(); + } + return false; + } + start = start.firstChild; + } + if (start === range.startContainer.childNodes[range.startOffset]) { + br = range.document.createElement('br'); + range.insertNode(br).setCursor(); + + } else { + range.setStart(start, 0).setCursor(); + } + + + } else { + br = range.document.createElement('br'); + range.insertNode(br).setStartAfter(br).setCursor(); + } + + + } else { + br = range.document.createElement('br'); + range.insertNode(br); + var parent = br.parentNode; + if (parent.lastChild === br) { + br.parentNode.insertBefore(br.cloneNode(true), br); + range.setStartBefore(br); + } else { + range.setStartAfter(br); + } + range.setCursor(); + + } + + } + + } + }); +}; + + +// plugins/keystrokes.js +/* 处理特殊键的兼容性问题 */ +UE.plugins['keystrokes'] = function() { + var me = this; + var collapsed = true; + me.addListener('keydown', function(type, evt) { + var keyCode = evt.keyCode || evt.which, + rng = me.selection.getRange(); + + //处理全选的情况 + if(!rng.collapsed && !(evt.ctrlKey || evt.shiftKey || evt.altKey || evt.metaKey) && (keyCode >= 65 && keyCode <=90 + || keyCode >= 48 && keyCode <= 57 || + keyCode >= 96 && keyCode <= 111 || { + 13:1, + 8:1, + 46:1 + }[keyCode]) + ){ + + var tmpNode = rng.startContainer; + if(domUtils.isFillChar(tmpNode)){ + rng.setStartBefore(tmpNode) + } + tmpNode = rng.endContainer; + if(domUtils.isFillChar(tmpNode)){ + rng.setEndAfter(tmpNode) + } + rng.txtToElmBoundary(); + //结束边界可能放到了br的前边,要把br包含进来 + // x[xxx]
          + if(rng.endContainer && rng.endContainer.nodeType == 1){ + tmpNode = rng.endContainer.childNodes[rng.endOffset]; + if(tmpNode && domUtils.isBr(tmpNode)){ + rng.setEndAfter(tmpNode); + } + } + if(rng.startOffset == 0){ + tmpNode = rng.startContainer; + if(domUtils.isBoundaryNode(tmpNode,'firstChild') ){ + tmpNode = rng.endContainer; + if(rng.endOffset == (tmpNode.nodeType == 3 ? tmpNode.nodeValue.length : tmpNode.childNodes.length) && domUtils.isBoundaryNode(tmpNode,'lastChild')){ + me.fireEvent('saveScene'); + me.body.innerHTML = '

          '+(browser.ie ? '' : '
          ')+'

          '; + rng.setStart(me.body.firstChild,0).setCursor(false,true); + me._selectionChange(); + return; + } + } + } + } + + //处理backspace + if (keyCode == keymap.Backspace) { + rng = me.selection.getRange(); + collapsed = rng.collapsed; + if(me.fireEvent('delkeydown',evt)){ + return; + } + var start,end; + //避免按两次删除才能生效的问题 + if(rng.collapsed && rng.inFillChar()){ + start = rng.startContainer; + + if(domUtils.isFillChar(start)){ + rng.setStartBefore(start).shrinkBoundary(true).collapse(true); + domUtils.remove(start) + }else{ + start.nodeValue = start.nodeValue.replace(new RegExp('^' + domUtils.fillChar ),''); + rng.startOffset--; + rng.collapse(true).select(true) + } + } + + //解决选中control元素不能删除的问题 + if (start = rng.getClosedNode()) { + me.fireEvent('saveScene'); + rng.setStartBefore(start); + domUtils.remove(start); + rng.setCursor(); + me.fireEvent('saveScene'); + domUtils.preventDefault(evt); + return; + } + //阻止在table上的删除 + if (!browser.ie) { + start = domUtils.findParentByTagName(rng.startContainer, 'table', true); + end = domUtils.findParentByTagName(rng.endContainer, 'table', true); + if (start && !end || !start && end || start !== end) { + evt.preventDefault(); + return; + } + } + + } + //处理tab键的逻辑 + if (keyCode == keymap.Tab) { + //不处理以下标签 + var excludeTagNameForTabKey = { + 'ol' : 1, + 'ul' : 1, + 'table':1 + }; + //处理组件里的tab按下事件 + if(me.fireEvent('tabkeydown',evt)){ + domUtils.preventDefault(evt); + return; + } + var range = me.selection.getRange(); + me.fireEvent('saveScene'); + for (var i = 0,txt = '',tabSize = me.options.tabSize|| 4,tabNode = me.options.tabNode || ' '; i < tabSize; i++) { + txt += tabNode; + } + var span = me.document.createElement('span'); + span.innerHTML = txt + domUtils.fillChar; + if (range.collapsed) { + range.insertNode(span.cloneNode(true).firstChild).setCursor(true); + } else { + var filterFn = function(node) { + return domUtils.isBlockElm(node) && !excludeTagNameForTabKey[node.tagName.toLowerCase()] + + }; + //普通的情况 + start = domUtils.findParent(range.startContainer, filterFn,true); + end = domUtils.findParent(range.endContainer, filterFn,true); + if (start && end && start === end) { + range.deleteContents(); + range.insertNode(span.cloneNode(true).firstChild).setCursor(true); + } else { + var bookmark = range.createBookmark(); + range.enlarge(true); + var bookmark2 = range.createBookmark(), + current = domUtils.getNextDomNode(bookmark2.start, false, filterFn); + while (current && !(domUtils.getPosition(current, bookmark2.end) & domUtils.POSITION_FOLLOWING)) { + current.insertBefore(span.cloneNode(true).firstChild, current.firstChild); + current = domUtils.getNextDomNode(current, false, filterFn); + } + range.moveToBookmark(bookmark2).moveToBookmark(bookmark).select(); + } + } + domUtils.preventDefault(evt) + } + //trace:1634 + //ff的del键在容器空的时候,也会删除 + if(browser.gecko && keyCode == 46){ + range = me.selection.getRange(); + if(range.collapsed){ + start = range.startContainer; + if(domUtils.isEmptyBlock(start)){ + var parent = start.parentNode; + while(domUtils.getChildCount(parent) == 1 && !domUtils.isBody(parent)){ + start = parent; + parent = parent.parentNode; + } + if(start === parent.lastChild) + evt.preventDefault(); + return; + } + } + } + }); + me.addListener('keyup', function(type, evt) { + var keyCode = evt.keyCode || evt.which, + rng,me = this; + if(keyCode == keymap.Backspace){ + if(me.fireEvent('delkeyup')){ + return; + } + rng = me.selection.getRange(); + if(rng.collapsed){ + var tmpNode, + autoClearTagName = ['h1','h2','h3','h4','h5','h6']; + if(tmpNode = domUtils.findParentByTagName(rng.startContainer,autoClearTagName,true)){ + if(domUtils.isEmptyBlock(tmpNode)){ + var pre = tmpNode.previousSibling; + if(pre && pre.nodeName != 'TABLE'){ + domUtils.remove(tmpNode); + rng.setStartAtLast(pre).setCursor(false,true); + return; + }else{ + var next = tmpNode.nextSibling; + if(next && next.nodeName != 'TABLE'){ + domUtils.remove(tmpNode); + rng.setStartAtFirst(next).setCursor(false,true); + return; + } + } + } + } + //处理当删除到body时,要重新给p标签展位 + if(domUtils.isBody(rng.startContainer)){ + var tmpNode = domUtils.createElement(me.document,'p',{ + 'innerHTML' : browser.ie ? domUtils.fillChar : '
          ' + }); + rng.insertNode(tmpNode).setStart(tmpNode,0).setCursor(false,true); + } + } + + + //chrome下如果删除了inline标签,浏览器会有记忆,在输入文字还是会套上刚才删除的标签,所以这里再选一次就不会了 + if( !collapsed && (rng.startContainer.nodeType == 3 || rng.startContainer.nodeType == 1 && domUtils.isEmptyBlock(rng.startContainer))){ + if(browser.ie){ + var span = rng.document.createElement('span'); + rng.insertNode(span).setStartBefore(span).collapse(true); + rng.select(); + domUtils.remove(span) + }else{ + rng.select() + } + + } + } + + + }) +}; + +// plugins/fiximgclick.js +///import core +///commands 修复chrome下图片不能点击的问题,出现八个角可改变大小 +///commandsName FixImgClick +///commandsTitle 修复chrome下图片不能点击的问题,出现八个角可改变大小 +//修复chrome下图片不能点击的问题,出现八个角可改变大小 + +UE.plugins['fiximgclick'] = (function () { + + var elementUpdated = false; + function Scale() { + this.editor = null; + this.resizer = null; + this.cover = null; + this.doc = document; + this.prePos = {x: 0, y: 0}; + this.startPos = {x: 0, y: 0}; + } + + (function () { + var rect = [ + //[left, top, width, height] + [0, 0, -1, -1], + [0, 0, 0, -1], + [0, 0, 1, -1], + [0, 0, -1, 0], + [0, 0, 1, 0], + [0, 0, -1, 1], + [0, 0, 0, 1], + [0, 0, 1, 1] + ]; + + Scale.prototype = { + init: function (editor) { + var me = this; + me.editor = editor; + me.startPos = this.prePos = {x: 0, y: 0}; + me.dragId = -1; + + var hands = [], + cover = me.cover = document.createElement('div'), + resizer = me.resizer = document.createElement('div'); + + cover.id = me.editor.ui.id + '_imagescale_cover'; + cover.style.cssText = 'position:absolute;display:none;z-index:' + (me.editor.options.zIndex) + ';filter:alpha(opacity=0); opacity:0;background:#CCC;'; + domUtils.on(cover, 'mousedown click', function () { + me.hide(); + }); + + for (i = 0; i < 8; i++) { + hands.push(''); + } + resizer.id = me.editor.ui.id + '_imagescale'; + resizer.className = 'edui-editor-imagescale'; + resizer.innerHTML = hands.join(''); + resizer.style.cssText += ';display:none;border:1px solid #3b77ff;z-index:' + (me.editor.options.zIndex) + ';'; + + me.editor.ui.getDom().appendChild(cover); + me.editor.ui.getDom().appendChild(resizer); + + me.initStyle(); + me.initEvents(); + }, + initStyle: function () { + utils.cssRule('imagescale', '.edui-editor-imagescale{display:none;position:absolute;border:1px solid #38B2CE;cursor:hand;-webkit-box-sizing: content-box;-moz-box-sizing: content-box;box-sizing: content-box;}' + + '.edui-editor-imagescale span{position:absolute;width:6px;height:6px;overflow:hidden;font-size:0px;display:block;background-color:#3C9DD0;}' + + '.edui-editor-imagescale .edui-editor-imagescale-hand0{cursor:nw-resize;top:0;margin-top:-4px;left:0;margin-left:-4px;}' + + '.edui-editor-imagescale .edui-editor-imagescale-hand1{cursor:n-resize;top:0;margin-top:-4px;left:50%;margin-left:-4px;}' + + '.edui-editor-imagescale .edui-editor-imagescale-hand2{cursor:ne-resize;top:0;margin-top:-4px;left:100%;margin-left:-3px;}' + + '.edui-editor-imagescale .edui-editor-imagescale-hand3{cursor:w-resize;top:50%;margin-top:-4px;left:0;margin-left:-4px;}' + + '.edui-editor-imagescale .edui-editor-imagescale-hand4{cursor:e-resize;top:50%;margin-top:-4px;left:100%;margin-left:-3px;}' + + '.edui-editor-imagescale .edui-editor-imagescale-hand5{cursor:sw-resize;top:100%;margin-top:-3px;left:0;margin-left:-4px;}' + + '.edui-editor-imagescale .edui-editor-imagescale-hand6{cursor:s-resize;top:100%;margin-top:-3px;left:50%;margin-left:-4px;}' + + '.edui-editor-imagescale .edui-editor-imagescale-hand7{cursor:se-resize;top:100%;margin-top:-3px;left:100%;margin-left:-3px;}'); + }, + initEvents: function () { + var me = this; + + me.startPos.x = me.startPos.y = 0; + me.isDraging = false; + }, + _eventHandler: function (e) { + var me = this; + switch (e.type) { + case 'mousedown': + var hand = e.target || e.srcElement, hand; + if (hand.className.indexOf('edui-editor-imagescale-hand') != -1 && me.dragId == -1) { + me.dragId = hand.className.slice(-1); + me.startPos.x = me.prePos.x = e.clientX; + me.startPos.y = me.prePos.y = e.clientY; + domUtils.on(me.doc,'mousemove', me.proxy(me._eventHandler, me)); + } + break; + case 'mousemove': + if (me.dragId != -1) { + me.updateContainerStyle(me.dragId, {x: e.clientX - me.prePos.x, y: e.clientY - me.prePos.y}); + me.prePos.x = e.clientX; + me.prePos.y = e.clientY; + elementUpdated = true; + me.updateTargetElement(); + + } + break; + case 'mouseup': + if (me.dragId != -1) { + me.updateContainerStyle(me.dragId, {x: e.clientX - me.prePos.x, y: e.clientY - me.prePos.y}); + me.updateTargetElement(); + if (me.target.parentNode) me.attachTo(me.target); + me.dragId = -1; + } + domUtils.un(me.doc,'mousemove', me.proxy(me._eventHandler, me)); + //修复只是点击挪动点,但没有改变大小,不应该触发contentchange + if(elementUpdated){ + elementUpdated = false; + me.editor.fireEvent('contentchange'); + } + + break; + default: + break; + } + }, + updateTargetElement: function () { + var me = this; + domUtils.setStyles(me.target, { + 'width': me.resizer.style.width, + 'height': me.resizer.style.height + }); + me.target.width = parseInt(me.resizer.style.width); + me.target.height = parseInt(me.resizer.style.height); + me.attachTo(me.target); + }, + updateContainerStyle: function (dir, offset) { + var me = this, + dom = me.resizer, tmp; + + if (rect[dir][0] != 0) { + tmp = parseInt(dom.style.left) + offset.x; + dom.style.left = me._validScaledProp('left', tmp) + 'px'; + } + if (rect[dir][1] != 0) { + tmp = parseInt(dom.style.top) + offset.y; + dom.style.top = me._validScaledProp('top', tmp) + 'px'; + } + if (rect[dir][2] != 0) { + tmp = dom.clientWidth + rect[dir][2] * offset.x; + dom.style.width = me._validScaledProp('width', tmp) + 'px'; + } + if (rect[dir][3] != 0) { + tmp = dom.clientHeight + rect[dir][3] * offset.y; + dom.style.height = me._validScaledProp('height', tmp) + 'px'; + } + }, + _validScaledProp: function (prop, value) { + var ele = this.resizer, + wrap = document; + + value = isNaN(value) ? 0 : value; + switch (prop) { + case 'left': + return value < 0 ? 0 : (value + ele.clientWidth) > wrap.clientWidth ? wrap.clientWidth - ele.clientWidth : value; + case 'top': + return value < 0 ? 0 : (value + ele.clientHeight) > wrap.clientHeight ? wrap.clientHeight - ele.clientHeight : value; + case 'width': + return value <= 0 ? 1 : (value + ele.offsetLeft) > wrap.clientWidth ? wrap.clientWidth - ele.offsetLeft : value; + case 'height': + return value <= 0 ? 1 : (value + ele.offsetTop) > wrap.clientHeight ? wrap.clientHeight - ele.offsetTop : value; + } + }, + hideCover: function () { + this.cover.style.display = 'none'; + }, + showCover: function () { + var me = this, + editorPos = domUtils.getXY(me.editor.ui.getDom()), + iframePos = domUtils.getXY(me.editor.iframe); + + domUtils.setStyles(me.cover, { + 'width': me.editor.iframe.offsetWidth + 'px', + 'height': me.editor.iframe.offsetHeight + 'px', + 'top': iframePos.y - editorPos.y + 'px', + 'left': iframePos.x - editorPos.x + 'px', + 'position': 'absolute', + 'display': '' + }) + }, + show: function (targetObj) { + var me = this; + me.resizer.style.display = 'block'; + if(targetObj) me.attachTo(targetObj); + + domUtils.on(this.resizer, 'mousedown', me.proxy(me._eventHandler, me)); + domUtils.on(me.doc, 'mouseup', me.proxy(me._eventHandler, me)); + + me.showCover(); + me.editor.fireEvent('afterscaleshow', me); + me.editor.fireEvent('saveScene'); + }, + hide: function () { + var me = this; + me.hideCover(); + me.resizer.style.display = 'none'; + + domUtils.un(me.resizer, 'mousedown', me.proxy(me._eventHandler, me)); + domUtils.un(me.doc, 'mouseup', me.proxy(me._eventHandler, me)); + me.editor.fireEvent('afterscalehide', me); + }, + proxy: function( fn, context ) { + return function(e) { + return fn.apply( context || this, arguments); + }; + }, + attachTo: function (targetObj) { + var me = this, + target = me.target = targetObj, + resizer = this.resizer, + imgPos = domUtils.getXY(target), + iframePos = domUtils.getXY(me.editor.iframe), + editorPos = domUtils.getXY(resizer.parentNode); + + domUtils.setStyles(resizer, { + 'width': target.width + 'px', + 'height': target.height + 'px', + 'left': iframePos.x + imgPos.x - me.editor.document.body.scrollLeft - editorPos.x - parseInt(resizer.style.borderLeftWidth) + 'px', + 'top': iframePos.y + imgPos.y - me.editor.document.body.scrollTop - editorPos.y - parseInt(resizer.style.borderTopWidth) + 'px' + }); + } + } + })(); + + return function () { + var me = this, + imageScale; + + me.setOpt('imageScaleEnabled', true); + + if ( !browser.ie && me.options.imageScaleEnabled) { + me.addListener('click', function (type, e) { + + var range = me.selection.getRange(), + img = range.getClosedNode(); + + if (img && img.tagName == 'IMG' && me.body.contentEditable!="false") { + + if (img.className.indexOf("edui-faked-music") != -1 || + img.getAttribute("anchorname") || + domUtils.hasClass(img, 'loadingclass') || + domUtils.hasClass(img, 'loaderrorclass')) { return } + + if (!imageScale) { + imageScale = new Scale(); + imageScale.init(me); + me.ui.getDom().appendChild(imageScale.resizer); + + var _keyDownHandler = function (e) { + imageScale.hide(); + if(imageScale.target) me.selection.getRange().selectNode(imageScale.target).select(); + }, _mouseDownHandler = function (e) { + var ele = e.target || e.srcElement; + if (ele && (ele.className===undefined || ele.className.indexOf('edui-editor-imagescale') == -1)) { + _keyDownHandler(e); + } + }, timer; + + me.addListener('afterscaleshow', function (e) { + me.addListener('beforekeydown', _keyDownHandler); + me.addListener('beforemousedown', _mouseDownHandler); + domUtils.on(document, 'keydown', _keyDownHandler); + domUtils.on(document,'mousedown', _mouseDownHandler); + me.selection.getNative().removeAllRanges(); + }); + me.addListener('afterscalehide', function (e) { + me.removeListener('beforekeydown', _keyDownHandler); + me.removeListener('beforemousedown', _mouseDownHandler); + domUtils.un(document, 'keydown', _keyDownHandler); + domUtils.un(document,'mousedown', _mouseDownHandler); + var target = imageScale.target; + if (target.parentNode) { + me.selection.getRange().selectNode(target).select(); + } + }); + //TODO 有iframe的情况,mousedown不能往下传。。 + domUtils.on(imageScale.resizer, 'mousedown', function (e) { + me.selection.getNative().removeAllRanges(); + var ele = e.target || e.srcElement; + if (ele && ele.className.indexOf('edui-editor-imagescale-hand') == -1) { + timer = setTimeout(function () { + imageScale.hide(); + if(imageScale.target) me.selection.getRange().selectNode(ele).select(); + }, 200); + } + }); + domUtils.on(imageScale.resizer, 'mouseup', function (e) { + var ele = e.target || e.srcElement; + if (ele && ele.className.indexOf('edui-editor-imagescale-hand') == -1) { + clearTimeout(timer); + } + }); + } + imageScale.show(img); + } else { + if (imageScale && imageScale.resizer.style.display != 'none') imageScale.hide(); + } + }); + } + + if (browser.webkit) { + me.addListener('click', function (type, e) { + if (e.target.tagName == 'IMG' && me.body.contentEditable!="false") { + var range = new dom.Range(me.document); + range.selectNode(e.target).select(); + } + }); + } + } +})(); + +// plugins/autolink.js +///import core +///commands 为非ie浏览器自动添加a标签 +///commandsName AutoLink +///commandsTitle 自动增加链接 +/** + * @description 为非ie浏览器自动添加a标签 + * @author zhanyi + */ + +UE.plugin.register('autolink',function(){ + var cont = 0; + + return !browser.ie ? { + + bindEvents:{ + 'reset' : function(){ + cont = 0; + }, + 'keydown':function(type, evt) { + var me = this; + var keyCode = evt.keyCode || evt.which; + + if (keyCode == 32 || keyCode == 13) { + + var sel = me.selection.getNative(), + range = sel.getRangeAt(0).cloneRange(), + offset, + charCode; + + var start = range.startContainer; + while (start.nodeType == 1 && range.startOffset > 0) { + start = range.startContainer.childNodes[range.startOffset - 1]; + if (!start){ + break; + } + range.setStart(start, start.nodeType == 1 ? start.childNodes.length : start.nodeValue.length); + range.collapse(true); + start = range.startContainer; + } + + do{ + if (range.startOffset == 0) { + start = range.startContainer.previousSibling; + + while (start && start.nodeType == 1) { + start = start.lastChild; + } + if (!start || domUtils.isFillChar(start)){ + break; + } + offset = start.nodeValue.length; + } else { + start = range.startContainer; + offset = range.startOffset; + } + range.setStart(start, offset - 1); + charCode = range.toString().charCodeAt(0); + } while (charCode != 160 && charCode != 32); + + if (range.toString().replace(new RegExp(domUtils.fillChar, 'g'), '').match(/(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i)) { + while(range.toString().length){ + if(/^(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i.test(range.toString())){ + break; + } + try{ + range.setStart(range.startContainer,range.startOffset+1); + }catch(e){ + //trace:2121 + var start = range.startContainer; + while(!(next = start.nextSibling)){ + if(domUtils.isBody(start)){ + return; + } + start = start.parentNode; + + } + range.setStart(next,0); + + } + + } + //range的开始边界已经在a标签里的不再处理 + if(domUtils.findParentByTagName(range.startContainer,'a',true)){ + return; + } + var a = me.document.createElement('a'),text = me.document.createTextNode(' '),href; + + me.undoManger && me.undoManger.save(); + a.appendChild(range.extractContents()); + a.href = a.innerHTML = a.innerHTML.replace(/<[^>]+>/g,''); + href = a.getAttribute("href").replace(new RegExp(domUtils.fillChar,'g'),''); + href = /^(?:https?:\/\/)/ig.test(href) ? href : "http://"+ href; + a.setAttribute('_src',utils.html(href)); + a.href = utils.html(href); + + range.insertNode(a); + a.parentNode.insertBefore(text, a.nextSibling); + range.setStart(text, 0); + range.collapse(true); + sel.removeAllRanges(); + sel.addRange(range); + me.undoManger && me.undoManger.save(); + } + } + } + } + }:{} + },function(){ + var keyCodes = { + 37:1, 38:1, 39:1, 40:1, + 13:1,32:1 + }; + function checkIsCludeLink(node){ + if(node.nodeType == 3){ + return null + } + if(node.nodeName == 'A'){ + return node; + } + var lastChild = node.lastChild; + + while(lastChild){ + if(lastChild.nodeName == 'A'){ + return lastChild; + } + if(lastChild.nodeType == 3){ + if(domUtils.isWhitespace(lastChild)){ + lastChild = lastChild.previousSibling; + continue; + } + return null + } + lastChild = lastChild.lastChild; + } + } + browser.ie && this.addListener('keyup',function(cmd,evt){ + var me = this,keyCode = evt.keyCode; + if(keyCodes[keyCode]){ + var rng = me.selection.getRange(); + var start = rng.startContainer; + + if(keyCode == 13){ + while(start && !domUtils.isBody(start) && !domUtils.isBlockElm(start)){ + start = start.parentNode; + } + if(start && !domUtils.isBody(start) && start.nodeName == 'P'){ + var pre = start.previousSibling; + if(pre && pre.nodeType == 1){ + var pre = checkIsCludeLink(pre); + if(pre && !pre.getAttribute('_href')){ + domUtils.remove(pre,true); + } + } + } + }else if(keyCode == 32 ){ + if(start.nodeType == 3 && /^\s$/.test(start.nodeValue)){ + start = start.previousSibling; + if(start && start.nodeName == 'A' && !start.getAttribute('_href')){ + domUtils.remove(start,true); + } + } + }else { + start = domUtils.findParentByTagName(start,'a',true); + if(start && !start.getAttribute('_href')){ + var bk = rng.createBookmark(); + + domUtils.remove(start,true); + rng.moveToBookmark(bk).select(true) + } + } + + } + + + }); + } +); + +// plugins/autoheight.js +///import core +///commands 当输入内容超过编辑器高度时,编辑器自动增高 +///commandsName AutoHeight,autoHeightEnabled +///commandsTitle 自动增高 +/** + * @description 自动伸展 + * @author zhanyi + */ +UE.plugins['autoheight'] = function () { + var me = this; + //提供开关,就算加载也可以关闭 + me.autoHeightEnabled = me.options.autoHeightEnabled !== false; + if (!me.autoHeightEnabled) { + return; + } + + var bakOverflow, + lastHeight = 0, + options = me.options, + currentHeight, + timer; + + function adjustHeight() { + var me = this; + clearTimeout(timer); + if(isFullscreen)return; + if (!me.queryCommandState || me.queryCommandState && me.queryCommandState('source') != 1) { + timer = setTimeout(function(){ + + var node = me.body.lastChild; + while(node && node.nodeType != 1){ + node = node.previousSibling; + } + if(node && node.nodeType == 1){ + node.style.clear = 'both'; + currentHeight = Math.max(domUtils.getXY(node).y + node.offsetHeight + 25 ,Math.max(options.minFrameHeight, options.initialFrameHeight)) ; + if (currentHeight != lastHeight) { + if (currentHeight !== parseInt(me.iframe.parentNode.style.height)) { + me.iframe.parentNode.style.height = currentHeight + 'px'; + } + me.body.style.height = currentHeight + 'px'; + lastHeight = currentHeight; + } + domUtils.removeStyle(node,'clear'); + } + + + },50) + } + } + var isFullscreen; + me.addListener('fullscreenchanged',function(cmd,f){ + isFullscreen = f + }); + me.addListener('destroy', function () { + me.removeListener('contentchange afterinserthtml keyup mouseup',adjustHeight) + }); + me.enableAutoHeight = function () { + var me = this; + if (!me.autoHeightEnabled) { + return; + } + var doc = me.document; + me.autoHeightEnabled = true; + bakOverflow = doc.body.style.overflowY; + doc.body.style.overflowY = 'hidden'; + me.addListener('contentchange afterinserthtml keyup mouseup',adjustHeight); + //ff不给事件算得不对 + + setTimeout(function () { + adjustHeight.call(me); + }, browser.gecko ? 100 : 0); + me.fireEvent('autoheightchanged', me.autoHeightEnabled); + }; + me.disableAutoHeight = function () { + + me.body.style.overflowY = bakOverflow || ''; + + me.removeListener('contentchange', adjustHeight); + me.removeListener('keyup', adjustHeight); + me.removeListener('mouseup', adjustHeight); + me.autoHeightEnabled = false; + me.fireEvent('autoheightchanged', me.autoHeightEnabled); + }; + + me.on('setHeight',function(){ + me.disableAutoHeight() + }); + me.addListener('ready', function () { + me.enableAutoHeight(); + //trace:1764 + var timer; + domUtils.on(browser.ie ? me.body : me.document, browser.webkit ? 'dragover' : 'drop', function () { + clearTimeout(timer); + timer = setTimeout(function () { + //trace:3681 + adjustHeight.call(me); + }, 100); + + }); + //修复内容过多时,回到顶部,顶部内容被工具栏遮挡问题 + var lastScrollY; + window.onscroll = function(){ + if(lastScrollY === null){ + lastScrollY = this.scrollY + }else if(this.scrollY == 0 && lastScrollY != 0){ + me.window.scrollTo(0,0); + lastScrollY = null; + } + } + }); + + +}; + + + +// plugins/autofloat.js +///import core +///commands 悬浮工具栏 +///commandsName AutoFloat,autoFloatEnabled +///commandsTitle 悬浮工具栏 +/** + * modified by chengchao01 + * 注意: 引入此功能后,在IE6下会将body的背景图片覆盖掉! + */ +UE.plugins['autofloat'] = function() { + var me = this, + lang = me.getLang(); + me.setOpt({ + topOffset:0 + }); + var optsAutoFloatEnabled = me.options.autoFloatEnabled !== false, + topOffset = me.options.topOffset; + + + //如果不固定toolbar的位置,则直接退出 + if(!optsAutoFloatEnabled){ + return; + } + var uiUtils = UE.ui.uiUtils, + LteIE6 = browser.ie && browser.version <= 6, + quirks = browser.quirks; + + function checkHasUI(){ + if(!UE.ui){ + alert(lang.autofloatMsg); + return 0; + } + return 1; + } + function fixIE6FixedPos(){ + var docStyle = document.body.style; + docStyle.backgroundImage = 'url("about:blank")'; + docStyle.backgroundAttachment = 'fixed'; + } + var bakCssText, + placeHolder = document.createElement('div'), + toolbarBox,orgTop, + getPosition, + flag =true; //ie7模式下需要偏移 + function setFloating(){ + var toobarBoxPos = domUtils.getXY(toolbarBox), + origalFloat = domUtils.getComputedStyle(toolbarBox,'position'), + origalLeft = domUtils.getComputedStyle(toolbarBox,'left'); + toolbarBox.style.width = toolbarBox.offsetWidth + 'px'; + toolbarBox.style.zIndex = me.options.zIndex * 1 + 1; + toolbarBox.parentNode.insertBefore(placeHolder, toolbarBox); + if (LteIE6 || (quirks && browser.ie)) { + if(toolbarBox.style.position != 'absolute'){ + toolbarBox.style.position = 'absolute'; + } + toolbarBox.style.top = (document.body.scrollTop||document.documentElement.scrollTop) - orgTop + topOffset + 'px'; + } else { + if (browser.ie7Compat && flag) { + flag = false; + toolbarBox.style.left = domUtils.getXY(toolbarBox).x - document.documentElement.getBoundingClientRect().left+2 + 'px'; + } + if(toolbarBox.style.position != 'fixed'){ + toolbarBox.style.position = 'fixed'; + toolbarBox.style.top = topOffset +"px"; + ((origalFloat == 'absolute' || origalFloat == 'relative') && parseFloat(origalLeft)) && (toolbarBox.style.left = toobarBoxPos.x + 'px'); + } + } + } + function unsetFloating(){ + flag = true; + if(placeHolder.parentNode){ + placeHolder.parentNode.removeChild(placeHolder); + } + + toolbarBox.style.cssText = bakCssText; + } + + function updateFloating(){ + var rect3 = getPosition(me.container); + var offset=me.options.toolbarTopOffset||0; + if (rect3.top < 0 && rect3.bottom - toolbarBox.offsetHeight > offset) { + setFloating(); + }else{ + unsetFloating(); + } + } + var defer_updateFloating = utils.defer(function(){ + updateFloating(); + },browser.ie ? 200 : 100,true); + + me.addListener('destroy',function(){ + domUtils.un(window, ['scroll','resize'], updateFloating); + me.removeListener('keydown', defer_updateFloating); + }); + + me.addListener('ready', function(){ + if(checkHasUI(me)){ + //加载了ui组件,但在new时,没有加载ui,导致编辑器实例上没有ui类,所以这里做判断 + if(!me.ui){ + return; + } + getPosition = uiUtils.getClientRect; + toolbarBox = me.ui.getDom('toolbarbox'); + orgTop = getPosition(toolbarBox).top; + bakCssText = toolbarBox.style.cssText; + placeHolder.style.height = toolbarBox.offsetHeight + 'px'; + if(LteIE6){ + fixIE6FixedPos(); + } + domUtils.on(window, ['scroll','resize'], updateFloating); + me.addListener('keydown', defer_updateFloating); + + me.addListener('beforefullscreenchange', function (t, enabled){ + if (enabled) { + unsetFloating(); + } + }); + me.addListener('fullscreenchanged', function (t, enabled){ + if (!enabled) { + updateFloating(); + } + }); + me.addListener('sourcemodechanged', function (t, enabled){ + setTimeout(function (){ + updateFloating(); + },0); + }); + me.addListener("clearDoc",function(){ + setTimeout(function(){ + updateFloating(); + },0); + + }) + } + }); +}; + + +// plugins/video.js +/** + * video插件, 为UEditor提供视频插入支持 + * @file + * @since 1.2.6.1 + */ + +UE.plugins['video'] = function (){ + var me =this; + + /** + * 创建插入视频字符窜 + * @param url 视频地址 + * @param width 视频宽度 + * @param height 视频高度 + * @param align 视频对齐 + * @param toEmbed 是否以flash代替显示 + * @param addParagraph 是否需要添加P 标签 + */ + function creatInsertStr(url,width,height,id,align,classname,type){ + + url = utils.unhtmlForUrl(url); + align = utils.unhtml(align); + classname = utils.unhtml(classname); + + width = parseInt(width, 10) || 0; + height = parseInt(height, 10) || 0; + + var str; + switch (type){ + case 'image': + str = '' + break; + case 'embed': + str = ''; + break; + case 'video': + var ext = url.substr(url.lastIndexOf('.') + 1); + if(ext == 'ogv') ext = 'ogg'; + str = '' + + ''; + break; + } + return str; + } + + function switchImgAndVideo(root,img2video){ + utils.each(root.getNodesByTagName(img2video ? 'img' : 'embed video'),function(node){ + var className = node.getAttr('class'); + if(className && className.indexOf('edui-faked-video') != -1){ + var html = creatInsertStr( img2video ? node.getAttr('_url') : node.getAttr('src'),node.getAttr('width'),node.getAttr('height'),null,node.getStyle('float') || '',className,img2video ? 'embed':'image'); + node.parentNode.replaceChild(UE.uNode.createElement(html),node); + } + if(className && className.indexOf('edui-upload-video') != -1){ + var html = creatInsertStr( img2video ? node.getAttr('_url') : node.getAttr('src'),node.getAttr('width'),node.getAttr('height'),null,node.getStyle('float') || '',className,img2video ? 'video':'image'); + node.parentNode.replaceChild(UE.uNode.createElement(html),node); + } + }) + } + + me.addOutputRule(function(root){ + switchImgAndVideo(root,true) + }); + me.addInputRule(function(root){ + switchImgAndVideo(root) + }); + + /** + * 插入视频 + * @command insertvideo + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { Object } videoAttr 键值对对象, 描述一个视频的所有属性 + * @example + * ```javascript + * + * var videoAttr = { + * //视频地址 + * url: 'http://www.youku.com/xxx', + * //视频宽高值, 单位px + * width: 200, + * height: 100 + * }; + * + * //editor 是编辑器实例 + * //向编辑器插入单个视频 + * editor.execCommand( 'insertvideo', videoAttr ); + * ``` + */ + + /** + * 插入视频 + * @command insertvideo + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { Array } videoArr 需要插入的视频的数组, 其中的每一个元素都是一个键值对对象, 描述了一个视频的所有属性 + * @example + * ```javascript + * + * var videoAttr1 = { + * //视频地址 + * url: 'http://www.youku.com/xxx', + * //视频宽高值, 单位px + * width: 200, + * height: 100 + * }, + * videoAttr2 = { + * //视频地址 + * url: 'http://www.youku.com/xxx', + * //视频宽高值, 单位px + * width: 200, + * height: 100 + * } + * + * //editor 是编辑器实例 + * //该方法将会向编辑器内插入两个视频 + * editor.execCommand( 'insertvideo', [ videoAttr1, videoAttr2 ] ); + * ``` + */ + + /** + * 查询当前光标所在处是否是一个视频 + * @command insertvideo + * @method queryCommandState + * @param { String } cmd 需要查询的命令字符串 + * @return { int } 如果当前光标所在处的元素是一个视频对象, 则返回1,否则返回0 + * @example + * ```javascript + * + * //editor 是编辑器实例 + * editor.queryCommandState( 'insertvideo' ); + * ``` + */ + me.commands["insertvideo"] = { + execCommand: function (cmd, videoObjs, type){ + videoObjs = utils.isArray(videoObjs)?videoObjs:[videoObjs]; + var html = [],id = 'tmpVedio', cl; + for(var i=0,vi,len = videoObjs.length;i 0) { + return 0; + } + for (var i in dtd.$isNotEmpty) if (dtd.$isNotEmpty.hasOwnProperty(i)) { + if (node.getElementsByTagName(i).length) { + return 0; + } + } + return 1; + }; + UETable.getWidth = function (cell) { + if (!cell)return 0; + return parseInt(domUtils.getComputedStyle(cell, "width"), 10); + }; + + /** + * 获取单元格或者单元格组的“对齐”状态。 如果当前的检测对象是一个单元格组, 只有在满足所有单元格的 水平和竖直 对齐属性都相同的 + * 条件时才会返回其状态值,否则将返回null; 如果当前只检测了一个单元格, 则直接返回当前单元格的对齐状态; + * @param table cell or table cells , 支持单个单元格dom对象 或者 单元格dom对象数组 + * @return { align: 'left' || 'right' || 'center', valign: 'top' || 'middle' || 'bottom' } 或者 null + */ + UETable.getTableCellAlignState = function ( cells ) { + + !utils.isArray( cells ) && ( cells = [cells] ); + + var result = {}, + status = ['align', 'valign'], + tempStatus = null, + isSame = true;//状态是否相同 + + utils.each( cells, function( cellNode ){ + + utils.each( status, function( currentState ){ + + tempStatus = cellNode.getAttribute( currentState ); + + if( !result[ currentState ] && tempStatus ) { + result[ currentState ] = tempStatus; + } else if( !result[ currentState ] || ( tempStatus !== result[ currentState ] ) ) { + isSame = false; + return false; + } + + } ); + + return isSame; + + }); + + return isSame ? result : null; + + }; + + /** + * 根据当前选区获取相关的table信息 + * @return {Object} + */ + UETable.getTableItemsByRange = function (editor) { + var start = editor.selection.getStart(); + + //ff下会选中bookmark + if( start && start.id && start.id.indexOf('_baidu_bookmark_start_') === 0 && start.nextSibling) { + start = start.nextSibling; + } + + //在table或者td边缘有可能存在选中tr的情况 + var cell = start && domUtils.findParentByTagName(start, ["td", "th"], true), + tr = cell && cell.parentNode, + caption = start && domUtils.findParentByTagName(start, 'caption', true), + table = caption ? caption.parentNode : tr && tr.parentNode.parentNode; + + return { + cell:cell, + tr:tr, + table:table, + caption:caption + } + }; + UETable.getUETableBySelected = function (editor) { + var table = UETable.getTableItemsByRange(editor).table; + if (table && table.ueTable && table.ueTable.selectedTds.length) { + return table.ueTable; + } + return null; + }; + + UETable.getDefaultValue = function (editor, table) { + var borderMap = { + thin:'0px', + medium:'1px', + thick:'2px' + }, + tableBorder, tdPadding, tdBorder, tmpValue; + if (!table) { + table = editor.document.createElement('table'); + table.insertRow(0).insertCell(0).innerHTML = 'xxx'; + editor.body.appendChild(table); + var td = table.getElementsByTagName('td')[0]; + tmpValue = domUtils.getComputedStyle(table, 'border-left-width'); + tableBorder = parseInt(borderMap[tmpValue] || tmpValue, 10); + tmpValue = domUtils.getComputedStyle(td, 'padding-left'); + tdPadding = parseInt(borderMap[tmpValue] || tmpValue, 10); + tmpValue = domUtils.getComputedStyle(td, 'border-left-width'); + tdBorder = parseInt(borderMap[tmpValue] || tmpValue, 10); + domUtils.remove(table); + return { + tableBorder:tableBorder, + tdPadding:tdPadding, + tdBorder:tdBorder + }; + } else { + td = table.getElementsByTagName('td')[0]; + tmpValue = domUtils.getComputedStyle(table, 'border-left-width'); + tableBorder = parseInt(borderMap[tmpValue] || tmpValue, 10); + tmpValue = domUtils.getComputedStyle(td, 'padding-left'); + tdPadding = parseInt(borderMap[tmpValue] || tmpValue, 10); + tmpValue = domUtils.getComputedStyle(td, 'border-left-width'); + tdBorder = parseInt(borderMap[tmpValue] || tmpValue, 10); + return { + tableBorder:tableBorder, + tdPadding:tdPadding, + tdBorder:tdBorder + }; + } + }; + /** + * 根据当前点击的td或者table获取索引对象 + * @param tdOrTable + */ + UETable.getUETable = function (tdOrTable) { + var tag = tdOrTable.tagName.toLowerCase(); + tdOrTable = (tag == "td" || tag == "th" || tag == 'caption') ? domUtils.findParentByTagName(tdOrTable, "table", true) : tdOrTable; + if (!tdOrTable.ueTable) { + tdOrTable.ueTable = new UETable(tdOrTable); + } + return tdOrTable.ueTable; + }; + + UETable.cloneCell = function(cell,ignoreMerge,keepPro){ + if (!cell || utils.isString(cell)) { + return this.table.ownerDocument.createElement(cell || 'td'); + } + var flag = domUtils.hasClass(cell, "selectTdClass"); + flag && domUtils.removeClasses(cell, "selectTdClass"); + var tmpCell = cell.cloneNode(true); + if (ignoreMerge) { + tmpCell.rowSpan = tmpCell.colSpan = 1; + } + //去掉宽高 + !keepPro && domUtils.removeAttributes(tmpCell,'width height'); + !keepPro && domUtils.removeAttributes(tmpCell,'style'); + + tmpCell.style.borderLeftStyle = ""; + tmpCell.style.borderTopStyle = ""; + tmpCell.style.borderLeftColor = cell.style.borderRightColor; + tmpCell.style.borderLeftWidth = cell.style.borderRightWidth; + tmpCell.style.borderTopColor = cell.style.borderBottomColor; + tmpCell.style.borderTopWidth = cell.style.borderBottomWidth; + flag && domUtils.addClass(cell, "selectTdClass"); + return tmpCell; + } + + UETable.prototype = { + getMaxRows:function () { + var rows = this.table.rows, maxLen = 1; + for (var i = 0, row; row = rows[i]; i++) { + var currentMax = 1; + for (var j = 0, cj; cj = row.cells[j++];) { + currentMax = Math.max(cj.rowSpan || 1, currentMax); + } + maxLen = Math.max(currentMax + i, maxLen); + } + return maxLen; + }, + /** + * 获取当前表格的最大列数 + */ + getMaxCols:function () { + var rows = this.table.rows, maxLen = 0, cellRows = {}; + for (var i = 0, row; row = rows[i]; i++) { + var cellsNum = 0; + for (var j = 0, cj; cj = row.cells[j++];) { + cellsNum += (cj.colSpan || 1); + if (cj.rowSpan && cj.rowSpan > 1) { + for (var k = 1; k < cj.rowSpan; k++) { + if (!cellRows['row_' + (i + k)]) { + cellRows['row_' + (i + k)] = (cj.colSpan || 1); + } else { + cellRows['row_' + (i + k)]++ + } + } + + } + } + cellsNum += cellRows['row_' + i] || 0; + maxLen = Math.max(cellsNum, maxLen); + } + return maxLen; + }, + getCellColIndex:function (cell) { + + }, + /** + * 获取当前cell旁边的单元格, + * @param cell + * @param right + */ + getHSideCell:function (cell, right) { + try { + var cellInfo = this.getCellInfo(cell), + previewRowIndex, previewColIndex; + var len = this.selectedTds.length, + range = this.cellsRange; + //首行或者首列没有前置单元格 + if ((!right && (!len ? !cellInfo.colIndex : !range.beginColIndex)) || (right && (!len ? (cellInfo.colIndex == (this.colsNum - 1)) : (range.endColIndex == this.colsNum - 1)))) return null; + + previewRowIndex = !len ? cellInfo.rowIndex : range.beginRowIndex; + previewColIndex = !right ? ( !len ? (cellInfo.colIndex < 1 ? 0 : (cellInfo.colIndex - 1)) : range.beginColIndex - 1) + : ( !len ? cellInfo.colIndex + 1 : range.endColIndex + 1); + return this.getCell(this.indexTable[previewRowIndex][previewColIndex].rowIndex, this.indexTable[previewRowIndex][previewColIndex].cellIndex); + } catch (e) { + showError(e); + } + }, + getTabNextCell:function (cell, preRowIndex) { + var cellInfo = this.getCellInfo(cell), + rowIndex = preRowIndex || cellInfo.rowIndex, + colIndex = cellInfo.colIndex + 1 + (cellInfo.colSpan - 1), + nextCell; + try { + nextCell = this.getCell(this.indexTable[rowIndex][colIndex].rowIndex, this.indexTable[rowIndex][colIndex].cellIndex); + } catch (e) { + try { + rowIndex = rowIndex * 1 + 1; + colIndex = 0; + nextCell = this.getCell(this.indexTable[rowIndex][colIndex].rowIndex, this.indexTable[rowIndex][colIndex].cellIndex); + } catch (e) { + } + } + return nextCell; + + }, + /** + * 获取视觉上的后置单元格 + * @param cell + * @param bottom + */ + getVSideCell:function (cell, bottom, ignoreRange) { + try { + var cellInfo = this.getCellInfo(cell), + nextRowIndex, nextColIndex; + var len = this.selectedTds.length && !ignoreRange, + range = this.cellsRange; + //末行或者末列没有后置单元格 + if ((!bottom && (cellInfo.rowIndex == 0)) || (bottom && (!len ? (cellInfo.rowIndex + cellInfo.rowSpan > this.rowsNum - 1) : (range.endRowIndex == this.rowsNum - 1)))) return null; + + nextRowIndex = !bottom ? ( !len ? cellInfo.rowIndex - 1 : range.beginRowIndex - 1) + : ( !len ? (cellInfo.rowIndex + cellInfo.rowSpan) : range.endRowIndex + 1); + nextColIndex = !len ? cellInfo.colIndex : range.beginColIndex; + return this.getCell(this.indexTable[nextRowIndex][nextColIndex].rowIndex, this.indexTable[nextRowIndex][nextColIndex].cellIndex); + } catch (e) { + showError(e); + } + }, + /** + * 获取相同结束位置的单元格,xOrY指代了是获取x轴相同还是y轴相同 + */ + getSameEndPosCells:function (cell, xOrY) { + try { + var flag = (xOrY.toLowerCase() === "x"), + end = domUtils.getXY(cell)[flag ? 'x' : 'y'] + cell["offset" + (flag ? 'Width' : 'Height')], + rows = this.table.rows, + cells = null, returns = []; + for (var i = 0; i < this.rowsNum; i++) { + cells = rows[i].cells; + for (var j = 0, tmpCell; tmpCell = cells[j++];) { + var tmpEnd = domUtils.getXY(tmpCell)[flag ? 'x' : 'y'] + tmpCell["offset" + (flag ? 'Width' : 'Height')]; + //对应行的td已经被上面行rowSpan了 + if (tmpEnd > end && flag) break; + if (cell == tmpCell || end == tmpEnd) { + //只获取单一的单元格 + //todo 仅获取单一单元格在特定情况下会造成returns为空,从而影响后续的拖拽实现,修正这个。需考虑性能 + if (tmpCell[flag ? "colSpan" : "rowSpan"] == 1) { + returns.push(tmpCell); + } + if (flag) break; + } + } + } + return returns; + } catch (e) { + showError(e); + } + }, + setCellContent:function (cell, content) { + cell.innerHTML = content || (browser.ie ? domUtils.fillChar : "
          "); + }, + cloneCell:UETable.cloneCell, + /** + * 获取跟当前单元格的右边竖线为左边的所有未合并单元格 + */ + getSameStartPosXCells:function (cell) { + try { + var start = domUtils.getXY(cell).x + cell.offsetWidth, + rows = this.table.rows, cells , returns = []; + for (var i = 0; i < this.rowsNum; i++) { + cells = rows[i].cells; + for (var j = 0, tmpCell; tmpCell = cells[j++];) { + var tmpStart = domUtils.getXY(tmpCell).x; + if (tmpStart > start) break; + if (tmpStart == start && tmpCell.colSpan == 1) { + returns.push(tmpCell); + break; + } + } + } + return returns; + } catch (e) { + showError(e); + } + }, + /** + * 更新table对应的索引表 + */ + update:function (table) { + this.table = table || this.table; + this.selectedTds = []; + this.cellsRange = {}; + this.indexTable = []; + var rows = this.table.rows, + rowsNum = this.getMaxRows(), + dNum = rowsNum - rows.length, + colsNum = this.getMaxCols(); + while (dNum--) { + this.table.insertRow(rows.length); + } + this.rowsNum = rowsNum; + this.colsNum = colsNum; + for (var i = 0, len = rows.length; i < len; i++) { + this.indexTable[i] = new Array(colsNum); + } + //填充索引表 + for (var rowIndex = 0, row; row = rows[rowIndex]; rowIndex++) { + for (var cellIndex = 0, cell, cells = row.cells; cell = cells[cellIndex]; cellIndex++) { + //修正整行被rowSpan时导致的行数计算错误 + if (cell.rowSpan > rowsNum) { + cell.rowSpan = rowsNum; + } + var colIndex = cellIndex, + rowSpan = cell.rowSpan || 1, + colSpan = cell.colSpan || 1; + //当已经被上一行rowSpan或者被前一列colSpan了,则跳到下一个单元格进行 + while (this.indexTable[rowIndex][colIndex]) colIndex++; + for (var j = 0; j < rowSpan; j++) { + for (var k = 0; k < colSpan; k++) { + this.indexTable[rowIndex + j][colIndex + k] = { + rowIndex:rowIndex, + cellIndex:cellIndex, + colIndex:colIndex, + rowSpan:rowSpan, + colSpan:colSpan + } + } + } + } + } + //修复残缺td + for (j = 0; j < rowsNum; j++) { + for (k = 0; k < colsNum; k++) { + if (this.indexTable[j][k] === undefined) { + row = rows[j]; + cell = row.cells[row.cells.length - 1]; + cell = cell ? cell.cloneNode(true) : this.table.ownerDocument.createElement("td"); + this.setCellContent(cell); + if (cell.colSpan !== 1)cell.colSpan = 1; + if (cell.rowSpan !== 1)cell.rowSpan = 1; + row.appendChild(cell); + this.indexTable[j][k] = { + rowIndex:j, + cellIndex:cell.cellIndex, + colIndex:k, + rowSpan:1, + colSpan:1 + } + } + } + } + //当框选后删除行或者列后撤销,需要重建选区。 + var tds = domUtils.getElementsByTagName(this.table, "td"), + selectTds = []; + utils.each(tds, function (td) { + if (domUtils.hasClass(td, "selectTdClass")) { + selectTds.push(td); + } + }); + if (selectTds.length) { + var start = selectTds[0], + end = selectTds[selectTds.length - 1], + startInfo = this.getCellInfo(start), + endInfo = this.getCellInfo(end); + this.selectedTds = selectTds; + this.cellsRange = { + beginRowIndex:startInfo.rowIndex, + beginColIndex:startInfo.colIndex, + endRowIndex:endInfo.rowIndex + endInfo.rowSpan - 1, + endColIndex:endInfo.colIndex + endInfo.colSpan - 1 + }; + } + //给第一行设置firstRow的样式名称,在排序图标的样式上使用到 + if(!domUtils.hasClass(this.table.rows[0], "firstRow")) { + domUtils.addClass(this.table.rows[0], "firstRow"); + for(var i = 1; i< this.table.rows.length; i++) { + domUtils.removeClasses(this.table.rows[i], "firstRow"); + } + } + }, + /** + * 获取单元格的索引信息 + */ + getCellInfo:function (cell) { + if (!cell) return; + var cellIndex = cell.cellIndex, + rowIndex = cell.parentNode.rowIndex, + rowInfo = this.indexTable[rowIndex], + numCols = this.colsNum; + for (var colIndex = cellIndex; colIndex < numCols; colIndex++) { + var cellInfo = rowInfo[colIndex]; + if (cellInfo.rowIndex === rowIndex && cellInfo.cellIndex === cellIndex) { + return cellInfo; + } + } + }, + /** + * 根据行列号获取单元格 + */ + getCell:function (rowIndex, cellIndex) { + return rowIndex < this.rowsNum && this.table.rows[rowIndex].cells[cellIndex] || null; + }, + /** + * 删除单元格 + */ + deleteCell:function (cell, rowIndex) { + rowIndex = typeof rowIndex == 'number' ? rowIndex : cell.parentNode.rowIndex; + var row = this.table.rows[rowIndex]; + row.deleteCell(cell.cellIndex); + }, + /** + * 根据始末两个单元格获取被框选的所有单元格范围 + */ + getCellsRange:function (cellA, cellB) { + function checkRange(beginRowIndex, beginColIndex, endRowIndex, endColIndex) { + var tmpBeginRowIndex = beginRowIndex, + tmpBeginColIndex = beginColIndex, + tmpEndRowIndex = endRowIndex, + tmpEndColIndex = endColIndex, + cellInfo, colIndex, rowIndex; + // 通过indexTable检查是否存在超出TableRange上边界的情况 + if (beginRowIndex > 0) { + for (colIndex = beginColIndex; colIndex < endColIndex; colIndex++) { + cellInfo = me.indexTable[beginRowIndex][colIndex]; + rowIndex = cellInfo.rowIndex; + if (rowIndex < beginRowIndex) { + tmpBeginRowIndex = Math.min(rowIndex, tmpBeginRowIndex); + } + } + } + // 通过indexTable检查是否存在超出TableRange右边界的情况 + if (endColIndex < me.colsNum) { + for (rowIndex = beginRowIndex; rowIndex < endRowIndex; rowIndex++) { + cellInfo = me.indexTable[rowIndex][endColIndex]; + colIndex = cellInfo.colIndex + cellInfo.colSpan - 1; + if (colIndex > endColIndex) { + tmpEndColIndex = Math.max(colIndex, tmpEndColIndex); + } + } + } + // 检查是否有超出TableRange下边界的情况 + if (endRowIndex < me.rowsNum) { + for (colIndex = beginColIndex; colIndex < endColIndex; colIndex++) { + cellInfo = me.indexTable[endRowIndex][colIndex]; + rowIndex = cellInfo.rowIndex + cellInfo.rowSpan - 1; + if (rowIndex > endRowIndex) { + tmpEndRowIndex = Math.max(rowIndex, tmpEndRowIndex); + } + } + } + // 检查是否有超出TableRange左边界的情况 + if (beginColIndex > 0) { + for (rowIndex = beginRowIndex; rowIndex < endRowIndex; rowIndex++) { + cellInfo = me.indexTable[rowIndex][beginColIndex]; + colIndex = cellInfo.colIndex; + if (colIndex < beginColIndex) { + tmpBeginColIndex = Math.min(cellInfo.colIndex, tmpBeginColIndex); + } + } + } + //递归调用直至所有完成所有框选单元格的扩展 + if (tmpBeginRowIndex != beginRowIndex || tmpBeginColIndex != beginColIndex || tmpEndRowIndex != endRowIndex || tmpEndColIndex != endColIndex) { + return checkRange(tmpBeginRowIndex, tmpBeginColIndex, tmpEndRowIndex, tmpEndColIndex); + } else { + // 不需要扩展TableRange的情况 + return { + beginRowIndex:beginRowIndex, + beginColIndex:beginColIndex, + endRowIndex:endRowIndex, + endColIndex:endColIndex + }; + } + } + + try { + var me = this, + cellAInfo = me.getCellInfo(cellA); + if (cellA === cellB) { + return { + beginRowIndex:cellAInfo.rowIndex, + beginColIndex:cellAInfo.colIndex, + endRowIndex:cellAInfo.rowIndex + cellAInfo.rowSpan - 1, + endColIndex:cellAInfo.colIndex + cellAInfo.colSpan - 1 + }; + } + var cellBInfo = me.getCellInfo(cellB); + // 计算TableRange的四个边 + var beginRowIndex = Math.min(cellAInfo.rowIndex, cellBInfo.rowIndex), + beginColIndex = Math.min(cellAInfo.colIndex, cellBInfo.colIndex), + endRowIndex = Math.max(cellAInfo.rowIndex + cellAInfo.rowSpan - 1, cellBInfo.rowIndex + cellBInfo.rowSpan - 1), + endColIndex = Math.max(cellAInfo.colIndex + cellAInfo.colSpan - 1, cellBInfo.colIndex + cellBInfo.colSpan - 1); + + return checkRange(beginRowIndex, beginColIndex, endRowIndex, endColIndex); + } catch (e) { + //throw e; + } + }, + /** + * 依据cellsRange获取对应的单元格集合 + */ + getCells:function (range) { + //每次获取cells之前必须先清除上次的选择,否则会对后续获取操作造成影响 + this.clearSelected(); + var beginRowIndex = range.beginRowIndex, + beginColIndex = range.beginColIndex, + endRowIndex = range.endRowIndex, + endColIndex = range.endColIndex, + cellInfo, rowIndex, colIndex, tdHash = {}, returnTds = []; + for (var i = beginRowIndex; i <= endRowIndex; i++) { + for (var j = beginColIndex; j <= endColIndex; j++) { + cellInfo = this.indexTable[i][j]; + rowIndex = cellInfo.rowIndex; + colIndex = cellInfo.colIndex; + // 如果Cells里已经包含了此Cell则跳过 + var key = rowIndex + '|' + colIndex; + if (tdHash[key]) continue; + tdHash[key] = 1; + if (rowIndex < i || colIndex < j || rowIndex + cellInfo.rowSpan - 1 > endRowIndex || colIndex + cellInfo.colSpan - 1 > endColIndex) { + return null; + } + returnTds.push(this.getCell(rowIndex, cellInfo.cellIndex)); + } + } + return returnTds; + }, + /** + * 清理已经选中的单元格 + */ + clearSelected:function () { + UETable.removeSelectedClass(this.selectedTds); + this.selectedTds = []; + this.cellsRange = {}; + }, + /** + * 根据range设置已经选中的单元格 + */ + setSelected:function (range) { + var cells = this.getCells(range); + UETable.addSelectedClass(cells); + this.selectedTds = cells; + this.cellsRange = range; + }, + isFullRow:function () { + var range = this.cellsRange; + return (range.endColIndex - range.beginColIndex + 1) == this.colsNum; + }, + isFullCol:function () { + var range = this.cellsRange, + table = this.table, + ths = table.getElementsByTagName("th"), + rows = range.endRowIndex - range.beginRowIndex + 1; + return !ths.length ? rows == this.rowsNum : rows == this.rowsNum || (rows == this.rowsNum - 1); + + }, + /** + * 获取视觉上的前置单元格,默认是左边,top传入时 + * @param cell + * @param top + */ + getNextCell:function (cell, bottom, ignoreRange) { + try { + var cellInfo = this.getCellInfo(cell), + nextRowIndex, nextColIndex; + var len = this.selectedTds.length && !ignoreRange, + range = this.cellsRange; + //末行或者末列没有后置单元格 + if ((!bottom && (cellInfo.rowIndex == 0)) || (bottom && (!len ? (cellInfo.rowIndex + cellInfo.rowSpan > this.rowsNum - 1) : (range.endRowIndex == this.rowsNum - 1)))) return null; + + nextRowIndex = !bottom ? ( !len ? cellInfo.rowIndex - 1 : range.beginRowIndex - 1) + : ( !len ? (cellInfo.rowIndex + cellInfo.rowSpan) : range.endRowIndex + 1); + nextColIndex = !len ? cellInfo.colIndex : range.beginColIndex; + return this.getCell(this.indexTable[nextRowIndex][nextColIndex].rowIndex, this.indexTable[nextRowIndex][nextColIndex].cellIndex); + } catch (e) { + showError(e); + } + }, + getPreviewCell:function (cell, top) { + try { + var cellInfo = this.getCellInfo(cell), + previewRowIndex, previewColIndex; + var len = this.selectedTds.length, + range = this.cellsRange; + //首行或者首列没有前置单元格 + if ((!top && (!len ? !cellInfo.colIndex : !range.beginColIndex)) || (top && (!len ? (cellInfo.rowIndex > (this.colsNum - 1)) : (range.endColIndex == this.colsNum - 1)))) return null; + + previewRowIndex = !top ? ( !len ? cellInfo.rowIndex : range.beginRowIndex ) + : ( !len ? (cellInfo.rowIndex < 1 ? 0 : (cellInfo.rowIndex - 1)) : range.beginRowIndex); + previewColIndex = !top ? ( !len ? (cellInfo.colIndex < 1 ? 0 : (cellInfo.colIndex - 1)) : range.beginColIndex - 1) + : ( !len ? cellInfo.colIndex : range.endColIndex + 1); + return this.getCell(this.indexTable[previewRowIndex][previewColIndex].rowIndex, this.indexTable[previewRowIndex][previewColIndex].cellIndex); + } catch (e) { + showError(e); + } + }, + /** + * 移动单元格中的内容 + */ + moveContent:function (cellTo, cellFrom) { + if (UETable.isEmptyBlock(cellFrom)) return; + if (UETable.isEmptyBlock(cellTo)) { + cellTo.innerHTML = cellFrom.innerHTML; + return; + } + var child = cellTo.lastChild; + if (child.nodeType == 3 || !dtd.$block[child.tagName]) { + cellTo.appendChild(cellTo.ownerDocument.createElement('br')) + } + while (child = cellFrom.firstChild) { + cellTo.appendChild(child); + } + }, + /** + * 向右合并单元格 + */ + mergeRight:function (cell) { + var cellInfo = this.getCellInfo(cell), + rightColIndex = cellInfo.colIndex + cellInfo.colSpan, + rightCellInfo = this.indexTable[cellInfo.rowIndex][rightColIndex], + rightCell = this.getCell(rightCellInfo.rowIndex, rightCellInfo.cellIndex); + //合并 + cell.colSpan = cellInfo.colSpan + rightCellInfo.colSpan; + //被合并的单元格不应存在宽度属性 + cell.removeAttribute("width"); + //移动内容 + this.moveContent(cell, rightCell); + //删掉被合并的Cell + this.deleteCell(rightCell, rightCellInfo.rowIndex); + this.update(); + }, + /** + * 向下合并单元格 + */ + mergeDown:function (cell) { + var cellInfo = this.getCellInfo(cell), + downRowIndex = cellInfo.rowIndex + cellInfo.rowSpan, + downCellInfo = this.indexTable[downRowIndex][cellInfo.colIndex], + downCell = this.getCell(downCellInfo.rowIndex, downCellInfo.cellIndex); + cell.rowSpan = cellInfo.rowSpan + downCellInfo.rowSpan; + cell.removeAttribute("height"); + this.moveContent(cell, downCell); + this.deleteCell(downCell, downCellInfo.rowIndex); + this.update(); + }, + /** + * 合并整个range中的内容 + */ + mergeRange:function () { + //由于合并操作可以在任意时刻进行,所以无法通过鼠标位置等信息实时生成range,只能通过缓存实例中的cellsRange对象来访问 + var range = this.cellsRange, + leftTopCell = this.getCell(range.beginRowIndex, this.indexTable[range.beginRowIndex][range.beginColIndex].cellIndex); + + if (leftTopCell.tagName == "TH" && range.endRowIndex !== range.beginRowIndex) { + var index = this.indexTable, + info = this.getCellInfo(leftTopCell); + leftTopCell = this.getCell(1, index[1][info.colIndex].cellIndex); + range = this.getCellsRange(leftTopCell, this.getCell(index[this.rowsNum - 1][info.colIndex].rowIndex, index[this.rowsNum - 1][info.colIndex].cellIndex)); + } + + // 删除剩余的Cells + var cells = this.getCells(range); + for(var i= 0,ci;ci=cells[i++];){ + if (ci !== leftTopCell) { + this.moveContent(leftTopCell, ci); + this.deleteCell(ci); + } + } + // 修改左上角Cell的rowSpan和colSpan,并调整宽度属性设置 + leftTopCell.rowSpan = range.endRowIndex - range.beginRowIndex + 1; + leftTopCell.rowSpan > 1 && leftTopCell.removeAttribute("height"); + leftTopCell.colSpan = range.endColIndex - range.beginColIndex + 1; + leftTopCell.colSpan > 1 && leftTopCell.removeAttribute("width"); + if (leftTopCell.rowSpan == this.rowsNum && leftTopCell.colSpan != 1) { + leftTopCell.colSpan = 1; + } + + if (leftTopCell.colSpan == this.colsNum && leftTopCell.rowSpan != 1) { + var rowIndex = leftTopCell.parentNode.rowIndex; + //解决IE下的表格操作问题 + if( this.table.deleteRow ) { + for (var i = rowIndex+ 1, curIndex=rowIndex+ 1, len=leftTopCell.rowSpan; i < len; i++) { + this.table.deleteRow(curIndex); + } + } else { + for (var i = 0, len=leftTopCell.rowSpan - 1; i < len; i++) { + var row = this.table.rows[rowIndex + 1]; + row.parentNode.removeChild(row); + } + } + leftTopCell.rowSpan = 1; + } + this.update(); + }, + /** + * 插入一行单元格 + */ + insertRow:function (rowIndex, sourceCell) { + var numCols = this.colsNum, + table = this.table, + row = table.insertRow(rowIndex), cell, + isInsertTitle = typeof sourceCell == 'string' && sourceCell.toUpperCase() == 'TH'; + + function replaceTdToTh(colIndex, cell, tableRow) { + if (colIndex == 0) { + var tr = tableRow.nextSibling || tableRow.previousSibling, + th = tr.cells[colIndex]; + if (th.tagName == 'TH') { + th = cell.ownerDocument.createElement("th"); + th.appendChild(cell.firstChild); + tableRow.insertBefore(th, cell); + domUtils.remove(cell) + } + }else{ + if (cell.tagName == 'TH') { + var td = cell.ownerDocument.createElement("td"); + td.appendChild(cell.firstChild); + tableRow.insertBefore(td, cell); + domUtils.remove(cell) + } + } + } + + //首行直接插入,无需考虑部分单元格被rowspan的情况 + if (rowIndex == 0 || rowIndex == this.rowsNum) { + for (var colIndex = 0; colIndex < numCols; colIndex++) { + cell = this.cloneCell(sourceCell, true); + this.setCellContent(cell); + cell.getAttribute('vAlign') && cell.setAttribute('vAlign', cell.getAttribute('vAlign')); + row.appendChild(cell); + if(!isInsertTitle) replaceTdToTh(colIndex, cell, row); + } + } else { + var infoRow = this.indexTable[rowIndex], + cellIndex = 0; + for (colIndex = 0; colIndex < numCols; colIndex++) { + var cellInfo = infoRow[colIndex]; + //如果存在某个单元格的rowspan穿过待插入行的位置,则修改该单元格的rowspan即可,无需插入单元格 + if (cellInfo.rowIndex < rowIndex) { + cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex); + cell.rowSpan = cellInfo.rowSpan + 1; + } else { + cell = this.cloneCell(sourceCell, true); + this.setCellContent(cell); + row.appendChild(cell); + } + if(!isInsertTitle) replaceTdToTh(colIndex, cell, row); + } + } + //框选时插入不触发contentchange,需要手动更新索引。 + this.update(); + return row; + }, + /** + * 删除一行单元格 + * @param rowIndex + */ + deleteRow:function (rowIndex) { + var row = this.table.rows[rowIndex], + infoRow = this.indexTable[rowIndex], + colsNum = this.colsNum, + count = 0; //处理计数 + for (var colIndex = 0; colIndex < colsNum;) { + var cellInfo = infoRow[colIndex], + cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex); + if (cell.rowSpan > 1) { + if (cellInfo.rowIndex == rowIndex) { + var clone = cell.cloneNode(true); + clone.rowSpan = cell.rowSpan - 1; + clone.innerHTML = ""; + cell.rowSpan = 1; + var nextRowIndex = rowIndex + 1, + nextRow = this.table.rows[nextRowIndex], + insertCellIndex, + preMerged = this.getPreviewMergedCellsNum(nextRowIndex, colIndex) - count; + if (preMerged < colIndex) { + insertCellIndex = colIndex - preMerged - 1; + //nextRow.insertCell(insertCellIndex); + domUtils.insertAfter(nextRow.cells[insertCellIndex], clone); + } else { + if (nextRow.cells.length) nextRow.insertBefore(clone, nextRow.cells[0]) + } + count += 1; + //cell.parentNode.removeChild(cell); + } + } + colIndex += cell.colSpan || 1; + } + var deleteTds = [], cacheMap = {}; + for (colIndex = 0; colIndex < colsNum; colIndex++) { + var tmpRowIndex = infoRow[colIndex].rowIndex, + tmpCellIndex = infoRow[colIndex].cellIndex, + key = tmpRowIndex + "_" + tmpCellIndex; + if (cacheMap[key])continue; + cacheMap[key] = 1; + cell = this.getCell(tmpRowIndex, tmpCellIndex); + deleteTds.push(cell); + } + var mergeTds = []; + utils.each(deleteTds, function (td) { + if (td.rowSpan == 1) { + td.parentNode.removeChild(td); + } else { + mergeTds.push(td); + } + }); + utils.each(mergeTds, function (td) { + td.rowSpan--; + }); + row.parentNode.removeChild(row); + //浏览器方法本身存在bug,采用自定义方法删除 + //this.table.deleteRow(rowIndex); + this.update(); + }, + insertCol:function (colIndex, sourceCell, defaultValue) { + var rowsNum = this.rowsNum, + rowIndex = 0, + tableRow, cell, + backWidth = parseInt((this.table.offsetWidth - (this.colsNum + 1) * 20 - (this.colsNum + 1)) / (this.colsNum + 1), 10), + isInsertTitleCol = typeof sourceCell == 'string' && sourceCell.toUpperCase() == 'TH'; + + function replaceTdToTh(rowIndex, cell, tableRow) { + if (rowIndex == 0) { + var th = cell.nextSibling || cell.previousSibling; + if (th.tagName == 'TH') { + th = cell.ownerDocument.createElement("th"); + th.appendChild(cell.firstChild); + tableRow.insertBefore(th, cell); + domUtils.remove(cell) + } + }else{ + if (cell.tagName == 'TH') { + var td = cell.ownerDocument.createElement("td"); + td.appendChild(cell.firstChild); + tableRow.insertBefore(td, cell); + domUtils.remove(cell) + } + } + } + + var preCell; + if (colIndex == 0 || colIndex == this.colsNum) { + for (; rowIndex < rowsNum; rowIndex++) { + tableRow = this.table.rows[rowIndex]; + preCell = tableRow.cells[colIndex == 0 ? colIndex : tableRow.cells.length]; + cell = this.cloneCell(sourceCell, true); //tableRow.insertCell(colIndex == 0 ? colIndex : tableRow.cells.length); + this.setCellContent(cell); + cell.setAttribute('vAlign', cell.getAttribute('vAlign')); + preCell && cell.setAttribute('width', preCell.getAttribute('width')); + if (!colIndex) { + tableRow.insertBefore(cell, tableRow.cells[0]); + } else { + domUtils.insertAfter(tableRow.cells[tableRow.cells.length - 1], cell); + } + if(!isInsertTitleCol) replaceTdToTh(rowIndex, cell, tableRow) + } + } else { + for (; rowIndex < rowsNum; rowIndex++) { + var cellInfo = this.indexTable[rowIndex][colIndex]; + if (cellInfo.colIndex < colIndex) { + cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex); + cell.colSpan = cellInfo.colSpan + 1; + } else { + tableRow = this.table.rows[rowIndex]; + preCell = tableRow.cells[cellInfo.cellIndex]; + + cell = this.cloneCell(sourceCell, true);//tableRow.insertCell(cellInfo.cellIndex); + this.setCellContent(cell); + cell.setAttribute('vAlign', cell.getAttribute('vAlign')); + preCell && cell.setAttribute('width', preCell.getAttribute('width')); + //防止IE下报错 + preCell ? tableRow.insertBefore(cell, preCell) : tableRow.appendChild(cell); + } + if(!isInsertTitleCol) replaceTdToTh(rowIndex, cell, tableRow); + } + } + //框选时插入不触发contentchange,需要手动更新索引 + this.update(); + this.updateWidth(backWidth, defaultValue || {tdPadding:10, tdBorder:1}); + }, + updateWidth:function (width, defaultValue) { + var table = this.table, + tmpWidth = UETable.getWidth(table) - defaultValue.tdPadding * 2 - defaultValue.tdBorder + width; + if (tmpWidth < table.ownerDocument.body.offsetWidth) { + table.setAttribute("width", tmpWidth); + return; + } + var tds = domUtils.getElementsByTagName(this.table, "td th"); + utils.each(tds, function (td) { + td.setAttribute("width", width); + }) + }, + deleteCol:function (colIndex) { + var indexTable = this.indexTable, + tableRows = this.table.rows, + backTableWidth = this.table.getAttribute("width"), + backTdWidth = 0, + rowsNum = this.rowsNum, + cacheMap = {}; + for (var rowIndex = 0; rowIndex < rowsNum;) { + var infoRow = indexTable[rowIndex], + cellInfo = infoRow[colIndex], + key = cellInfo.rowIndex + '_' + cellInfo.colIndex; + // 跳过已经处理过的Cell + if (cacheMap[key])continue; + cacheMap[key] = 1; + var cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex); + if (!backTdWidth) backTdWidth = cell && parseInt(cell.offsetWidth / cell.colSpan, 10).toFixed(0); + // 如果Cell的colSpan大于1, 就修改colSpan, 否则就删掉这个Cell + if (cell.colSpan > 1) { + cell.colSpan--; + } else { + tableRows[rowIndex].deleteCell(cellInfo.cellIndex); + } + rowIndex += cellInfo.rowSpan || 1; + } + this.table.setAttribute("width", backTableWidth - backTdWidth); + this.update(); + }, + splitToCells:function (cell) { + var me = this, + cells = this.splitToRows(cell); + utils.each(cells, function (cell) { + me.splitToCols(cell); + }) + }, + splitToRows:function (cell) { + var cellInfo = this.getCellInfo(cell), + rowIndex = cellInfo.rowIndex, + colIndex = cellInfo.colIndex, + results = []; + // 修改Cell的rowSpan + cell.rowSpan = 1; + results.push(cell); + // 补齐单元格 + for (var i = rowIndex, endRow = rowIndex + cellInfo.rowSpan; i < endRow; i++) { + if (i == rowIndex)continue; + var tableRow = this.table.rows[i], + tmpCell = tableRow.insertCell(colIndex - this.getPreviewMergedCellsNum(i, colIndex)); + tmpCell.colSpan = cellInfo.colSpan; + this.setCellContent(tmpCell); + tmpCell.setAttribute('vAlign', cell.getAttribute('vAlign')); + tmpCell.setAttribute('align', cell.getAttribute('align')); + if (cell.style.cssText) { + tmpCell.style.cssText = cell.style.cssText; + } + results.push(tmpCell); + } + this.update(); + return results; + }, + getPreviewMergedCellsNum:function (rowIndex, colIndex) { + var indexRow = this.indexTable[rowIndex], + num = 0; + for (var i = 0; i < colIndex;) { + var colSpan = indexRow[i].colSpan, + tmpRowIndex = indexRow[i].rowIndex; + num += (colSpan - (tmpRowIndex == rowIndex ? 1 : 0)); + i += colSpan; + } + return num; + }, + splitToCols:function (cell) { + var backWidth = (cell.offsetWidth / cell.colSpan - 22).toFixed(0), + + cellInfo = this.getCellInfo(cell), + rowIndex = cellInfo.rowIndex, + colIndex = cellInfo.colIndex, + results = []; + // 修改Cell的rowSpan + cell.colSpan = 1; + cell.setAttribute("width", backWidth); + results.push(cell); + // 补齐单元格 + for (var j = colIndex, endCol = colIndex + cellInfo.colSpan; j < endCol; j++) { + if (j == colIndex)continue; + var tableRow = this.table.rows[rowIndex], + tmpCell = tableRow.insertCell(this.indexTable[rowIndex][j].cellIndex + 1); + tmpCell.rowSpan = cellInfo.rowSpan; + this.setCellContent(tmpCell); + tmpCell.setAttribute('vAlign', cell.getAttribute('vAlign')); + tmpCell.setAttribute('align', cell.getAttribute('align')); + tmpCell.setAttribute('width', backWidth); + if (cell.style.cssText) { + tmpCell.style.cssText = cell.style.cssText; + } + //处理th的情况 + if (cell.tagName == 'TH') { + var th = cell.ownerDocument.createElement('th'); + th.appendChild(tmpCell.firstChild); + th.setAttribute('vAlign', cell.getAttribute('vAlign')); + th.rowSpan = tmpCell.rowSpan; + tableRow.insertBefore(th, tmpCell); + domUtils.remove(tmpCell); + } + results.push(tmpCell); + } + this.update(); + return results; + }, + isLastCell:function (cell, rowsNum, colsNum) { + rowsNum = rowsNum || this.rowsNum; + colsNum = colsNum || this.colsNum; + var cellInfo = this.getCellInfo(cell); + return ((cellInfo.rowIndex + cellInfo.rowSpan) == rowsNum) && + ((cellInfo.colIndex + cellInfo.colSpan) == colsNum); + }, + getLastCell:function (cells) { + cells = cells || this.table.getElementsByTagName("td"); + var firstInfo = this.getCellInfo(cells[0]); + var me = this, last = cells[0], + tr = last.parentNode, + cellsNum = 0, cols = 0, rows; + utils.each(cells, function (cell) { + if (cell.parentNode == tr)cols += cell.colSpan || 1; + cellsNum += cell.rowSpan * cell.colSpan || 1; + }); + rows = cellsNum / cols; + utils.each(cells, function (cell) { + if (me.isLastCell(cell, rows, cols)) { + last = cell; + return false; + } + }); + return last; + + }, + selectRow:function (rowIndex) { + var indexRow = this.indexTable[rowIndex], + start = this.getCell(indexRow[0].rowIndex, indexRow[0].cellIndex), + end = this.getCell(indexRow[this.colsNum - 1].rowIndex, indexRow[this.colsNum - 1].cellIndex), + range = this.getCellsRange(start, end); + this.setSelected(range); + }, + selectTable:function () { + var tds = this.table.getElementsByTagName("td"), + range = this.getCellsRange(tds[0], tds[tds.length - 1]); + this.setSelected(range); + }, + setBackground:function (cells, value) { + if (typeof value === "string") { + utils.each(cells, function (cell) { + cell.style.backgroundColor = value; + }) + } else if (typeof value === "object") { + value = utils.extend({ + repeat:true, + colorList:["#ddd", "#fff"] + }, value); + var rowIndex = this.getCellInfo(cells[0]).rowIndex, + count = 0, + colors = value.colorList, + getColor = function (list, index, repeat) { + return list[index] ? list[index] : repeat ? list[index % list.length] : ""; + }; + for (var i = 0, cell; cell = cells[i++];) { + var cellInfo = this.getCellInfo(cell); + cell.style.backgroundColor = getColor(colors, ((rowIndex + count) == cellInfo.rowIndex) ? count : ++count, value.repeat); + } + } + }, + removeBackground:function (cells) { + utils.each(cells, function (cell) { + cell.style.backgroundColor = ""; + }) + } + + + }; + function showError(e) { + } +})(); + +// plugins/table.cmds.js +/** + * Created with JetBrains PhpStorm. + * User: taoqili + * Date: 13-2-20 + * Time: 下午6:25 + * To change this template use File | Settings | File Templates. + */ +; +(function () { + var UT = UE.UETable, + getTableItemsByRange = function (editor) { + return UT.getTableItemsByRange(editor); + }, + getUETableBySelected = function (editor) { + return UT.getUETableBySelected(editor) + }, + getDefaultValue = function (editor, table) { + return UT.getDefaultValue(editor, table); + }, + getUETable = function (tdOrTable) { + return UT.getUETable(tdOrTable); + }; + + + UE.commands['inserttable'] = { + queryCommandState: function () { + return getTableItemsByRange(this).table ? -1 : 0; + }, + execCommand: function (cmd, opt) { + function createTable(opt, tdWidth) { + var html = [], + rowsNum = opt.numRows, + colsNum = opt.numCols; + for (var r = 0; r < rowsNum; r++) { + html.push(''); + for (var c = 0; c < colsNum; c++) { + html.push('
        • ' + (browser.ie && browser.version < 11 ? domUtils.fillChar : '
          ') + '
          ' + html.join('') + '
          ' + } + + if (!opt) { + opt = utils.extend({}, { + numCols: this.options.defaultCols, + numRows: this.options.defaultRows, + tdvalign: this.options.tdvalign + }) + } + var me = this; + var range = this.selection.getRange(), + start = range.startContainer, + firstParentBlock = domUtils.findParent(start, function (node) { + return domUtils.isBlockElm(node); + }, true) || me.body; + + var defaultValue = getDefaultValue(me), + tableWidth = firstParentBlock.offsetWidth, + tdWidth = Math.floor(tableWidth / opt.numCols - defaultValue.tdPadding * 2 - defaultValue.tdBorder); + + //todo其他属性 + !opt.tdvalign && (opt.tdvalign = me.options.tdvalign); + me.execCommand("inserthtml", createTable(opt, tdWidth)); + } + }; + + UE.commands['insertparagraphbeforetable'] = { + queryCommandState: function () { + return getTableItemsByRange(this).cell ? 0 : -1; + }, + execCommand: function () { + var table = getTableItemsByRange(this).table; + if (table) { + var p = this.document.createElement("p"); + p.innerHTML = browser.ie ? ' ' : '
          '; + table.parentNode.insertBefore(p, table); + this.selection.getRange().setStart(p, 0).setCursor(); + } + } + }; + + UE.commands['deletetable'] = { + queryCommandState: function () { + var rng = this.selection.getRange(); + return domUtils.findParentByTagName(rng.startContainer, 'table', true) ? 0 : -1; + }, + execCommand: function (cmd, table) { + var rng = this.selection.getRange(); + table = table || domUtils.findParentByTagName(rng.startContainer, 'table', true); + if (table) { + var next = table.nextSibling; + if (!next) { + next = domUtils.createElement(this.document, 'p', { + 'innerHTML': browser.ie ? domUtils.fillChar : '
          ' + }); + table.parentNode.insertBefore(next, table); + } + domUtils.remove(table); + rng = this.selection.getRange(); + if (next.nodeType == 3) { + rng.setStartBefore(next) + } else { + rng.setStart(next, 0) + } + rng.setCursor(false, true) + this.fireEvent("tablehasdeleted") + + } + + } + }; + UE.commands['cellalign'] = { + queryCommandState: function () { + return getSelectedArr(this).length ? 0 : -1 + }, + execCommand: function (cmd, align) { + var selectedTds = getSelectedArr(this); + if (selectedTds.length) { + for (var i = 0, ci; ci = selectedTds[i++];) { + ci.setAttribute('align', align); + } + } + } + }; + UE.commands['cellvalign'] = { + queryCommandState: function () { + return getSelectedArr(this).length ? 0 : -1; + }, + execCommand: function (cmd, valign) { + var selectedTds = getSelectedArr(this); + if (selectedTds.length) { + for (var i = 0, ci; ci = selectedTds[i++];) { + ci.setAttribute('vAlign', valign); + } + } + } + }; + UE.commands['insertcaption'] = { + queryCommandState: function () { + var table = getTableItemsByRange(this).table; + if (table) { + return table.getElementsByTagName('caption').length == 0 ? 1 : -1; + } + return -1; + }, + execCommand: function () { + var table = getTableItemsByRange(this).table; + if (table) { + var caption = this.document.createElement('caption'); + caption.innerHTML = browser.ie ? domUtils.fillChar : '
          '; + table.insertBefore(caption, table.firstChild); + var range = this.selection.getRange(); + range.setStart(caption, 0).setCursor(); + } + + } + }; + UE.commands['deletecaption'] = { + queryCommandState: function () { + var rng = this.selection.getRange(), + table = domUtils.findParentByTagName(rng.startContainer, 'table'); + if (table) { + return table.getElementsByTagName('caption').length == 0 ? -1 : 1; + } + return -1; + }, + execCommand: function () { + var rng = this.selection.getRange(), + table = domUtils.findParentByTagName(rng.startContainer, 'table'); + if (table) { + domUtils.remove(table.getElementsByTagName('caption')[0]); + var range = this.selection.getRange(); + range.setStart(table.rows[0].cells[0], 0).setCursor(); + } + + } + }; + UE.commands['inserttitle'] = { + queryCommandState: function () { + var table = getTableItemsByRange(this).table; + if (table) { + var firstRow = table.rows[0]; + return firstRow.cells[firstRow.cells.length-1].tagName.toLowerCase() != 'th' ? 0 : -1 + } + return -1; + }, + execCommand: function () { + var table = getTableItemsByRange(this).table; + if (table) { + getUETable(table).insertRow(0, 'th'); + } + var th = table.getElementsByTagName('th')[0]; + this.selection.getRange().setStart(th, 0).setCursor(false, true); + } + }; + UE.commands['deletetitle'] = { + queryCommandState: function () { + var table = getTableItemsByRange(this).table; + if (table) { + var firstRow = table.rows[0]; + return firstRow.cells[firstRow.cells.length-1].tagName.toLowerCase() == 'th' ? 0 : -1 + } + return -1; + }, + execCommand: function () { + var table = getTableItemsByRange(this).table; + if (table) { + domUtils.remove(table.rows[0]) + } + var td = table.getElementsByTagName('td')[0]; + this.selection.getRange().setStart(td, 0).setCursor(false, true); + } + }; + UE.commands['inserttitlecol'] = { + queryCommandState: function () { + var table = getTableItemsByRange(this).table; + if (table) { + var lastRow = table.rows[table.rows.length-1]; + return lastRow.getElementsByTagName('th').length ? -1 : 0; + } + return -1; + }, + execCommand: function (cmd) { + var table = getTableItemsByRange(this).table; + if (table) { + getUETable(table).insertCol(0, 'th'); + } + resetTdWidth(table, this); + var th = table.getElementsByTagName('th')[0]; + this.selection.getRange().setStart(th, 0).setCursor(false, true); + } + }; + UE.commands['deletetitlecol'] = { + queryCommandState: function () { + var table = getTableItemsByRange(this).table; + if (table) { + var lastRow = table.rows[table.rows.length-1]; + return lastRow.getElementsByTagName('th').length ? 0 : -1; + } + return -1; + }, + execCommand: function () { + var table = getTableItemsByRange(this).table; + if (table) { + for(var i = 0; i< table.rows.length; i++ ){ + domUtils.remove(table.rows[i].children[0]) + } + } + resetTdWidth(table, this); + var td = table.getElementsByTagName('td')[0]; + this.selection.getRange().setStart(td, 0).setCursor(false, true); + } + }; + + UE.commands["mergeright"] = { + queryCommandState: function (cmd) { + var tableItems = getTableItemsByRange(this), + table = tableItems.table, + cell = tableItems.cell; + + if (!table || !cell) return -1; + var ut = getUETable(table); + if (ut.selectedTds.length) return -1; + + var cellInfo = ut.getCellInfo(cell), + rightColIndex = cellInfo.colIndex + cellInfo.colSpan; + if (rightColIndex >= ut.colsNum) return -1; // 如果处于最右边则不能向右合并 + + var rightCellInfo = ut.indexTable[cellInfo.rowIndex][rightColIndex], + rightCell = table.rows[rightCellInfo.rowIndex].cells[rightCellInfo.cellIndex]; + if (!rightCell || cell.tagName != rightCell.tagName) return -1; // TH和TD不能相互合并 + + // 当且仅当两个Cell的开始列号和结束列号一致时能进行合并 + return (rightCellInfo.rowIndex == cellInfo.rowIndex && rightCellInfo.rowSpan == cellInfo.rowSpan) ? 0 : -1; + }, + execCommand: function (cmd) { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell); + ut.mergeRight(cell); + rng.moveToBookmark(bk).select(); + } + }; + UE.commands["mergedown"] = { + queryCommandState: function (cmd) { + var tableItems = getTableItemsByRange(this), + table = tableItems.table, + cell = tableItems.cell; + + if (!table || !cell) return -1; + var ut = getUETable(table); + if (ut.selectedTds.length)return -1; + + var cellInfo = ut.getCellInfo(cell), + downRowIndex = cellInfo.rowIndex + cellInfo.rowSpan; + if (downRowIndex >= ut.rowsNum) return -1; // 如果处于最下边则不能向下合并 + + var downCellInfo = ut.indexTable[downRowIndex][cellInfo.colIndex], + downCell = table.rows[downCellInfo.rowIndex].cells[downCellInfo.cellIndex]; + if (!downCell || cell.tagName != downCell.tagName) return -1; // TH和TD不能相互合并 + + // 当且仅当两个Cell的开始列号和结束列号一致时能进行合并 + return (downCellInfo.colIndex == cellInfo.colIndex && downCellInfo.colSpan == cellInfo.colSpan) ? 0 : -1; + }, + execCommand: function () { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell); + ut.mergeDown(cell); + rng.moveToBookmark(bk).select(); + } + }; + UE.commands["mergecells"] = { + queryCommandState: function () { + return getUETableBySelected(this) ? 0 : -1; + }, + execCommand: function () { + var ut = getUETableBySelected(this); + if (ut && ut.selectedTds.length) { + var cell = ut.selectedTds[0]; + ut.mergeRange(); + var rng = this.selection.getRange(); + if (domUtils.isEmptyBlock(cell)) { + rng.setStart(cell, 0).collapse(true) + } else { + rng.selectNodeContents(cell) + } + rng.select(); + } + + + } + }; + UE.commands["insertrow"] = { + queryCommandState: function () { + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell; + return cell && (cell.tagName == "TD" || (cell.tagName == 'TH' && tableItems.tr !== tableItems.table.rows[0])) && + getUETable(tableItems.table).rowsNum < this.options.maxRowNum ? 0 : -1; + }, + execCommand: function () { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell, + table = tableItems.table, + ut = getUETable(table), + cellInfo = ut.getCellInfo(cell); + //ut.insertRow(!ut.selectedTds.length ? cellInfo.rowIndex:ut.cellsRange.beginRowIndex,''); + if (!ut.selectedTds.length) { + ut.insertRow(cellInfo.rowIndex, cell); + } else { + var range = ut.cellsRange; + for (var i = 0, len = range.endRowIndex - range.beginRowIndex + 1; i < len; i++) { + ut.insertRow(range.beginRowIndex, cell); + } + } + rng.moveToBookmark(bk).select(); + if (table.getAttribute("interlaced") === "enabled")this.fireEvent("interlacetable", table); + } + }; + //后插入行 + UE.commands["insertrownext"] = { + queryCommandState: function () { + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell; + return cell && (cell.tagName == "TD") && getUETable(tableItems.table).rowsNum < this.options.maxRowNum ? 0 : -1; + }, + execCommand: function () { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell, + table = tableItems.table, + ut = getUETable(table), + cellInfo = ut.getCellInfo(cell); + //ut.insertRow(!ut.selectedTds.length? cellInfo.rowIndex + cellInfo.rowSpan : ut.cellsRange.endRowIndex + 1,''); + if (!ut.selectedTds.length) { + ut.insertRow(cellInfo.rowIndex + cellInfo.rowSpan, cell); + } else { + var range = ut.cellsRange; + for (var i = 0, len = range.endRowIndex - range.beginRowIndex + 1; i < len; i++) { + ut.insertRow(range.endRowIndex + 1, cell); + } + } + rng.moveToBookmark(bk).select(); + if (table.getAttribute("interlaced") === "enabled")this.fireEvent("interlacetable", table); + } + }; + UE.commands["deleterow"] = { + queryCommandState: function () { + var tableItems = getTableItemsByRange(this); + return tableItems.cell ? 0 : -1; + }, + execCommand: function () { + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell), + cellsRange = ut.cellsRange, + cellInfo = ut.getCellInfo(cell), + preCell = ut.getVSideCell(cell), + nextCell = ut.getVSideCell(cell, true), + rng = this.selection.getRange(); + if (utils.isEmptyObject(cellsRange)) { + ut.deleteRow(cellInfo.rowIndex); + } else { + for (var i = cellsRange.beginRowIndex; i < cellsRange.endRowIndex + 1; i++) { + ut.deleteRow(cellsRange.beginRowIndex); + } + } + var table = ut.table; + if (!table.getElementsByTagName('td').length) { + var nextSibling = table.nextSibling; + domUtils.remove(table); + if (nextSibling) { + rng.setStart(nextSibling, 0).setCursor(false, true); + } + } else { + if (cellInfo.rowSpan == 1 || cellInfo.rowSpan == cellsRange.endRowIndex - cellsRange.beginRowIndex + 1) { + if (nextCell || preCell) rng.selectNodeContents(nextCell || preCell).setCursor(false, true); + } else { + var newCell = ut.getCell(cellInfo.rowIndex, ut.indexTable[cellInfo.rowIndex][cellInfo.colIndex].cellIndex); + if (newCell) rng.selectNodeContents(newCell).setCursor(false, true); + } + } + if (table.getAttribute("interlaced") === "enabled")this.fireEvent("interlacetable", table); + } + }; + UE.commands["insertcol"] = { + queryCommandState: function (cmd) { + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell; + return cell && (cell.tagName == "TD" || (cell.tagName == 'TH' && cell !== tableItems.tr.cells[0])) && + getUETable(tableItems.table).colsNum < this.options.maxColNum ? 0 : -1; + }, + execCommand: function (cmd) { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + if (this.queryCommandState(cmd) == -1)return; + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell), + cellInfo = ut.getCellInfo(cell); + + //ut.insertCol(!ut.selectedTds.length ? cellInfo.colIndex:ut.cellsRange.beginColIndex); + if (!ut.selectedTds.length) { + ut.insertCol(cellInfo.colIndex, cell); + } else { + var range = ut.cellsRange; + for (var i = 0, len = range.endColIndex - range.beginColIndex + 1; i < len; i++) { + ut.insertCol(range.beginColIndex, cell); + } + } + rng.moveToBookmark(bk).select(true); + } + }; + UE.commands["insertcolnext"] = { + queryCommandState: function () { + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell; + return cell && getUETable(tableItems.table).colsNum < this.options.maxColNum ? 0 : -1; + }, + execCommand: function () { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell), + cellInfo = ut.getCellInfo(cell); + //ut.insertCol(!ut.selectedTds.length ? cellInfo.colIndex + cellInfo.colSpan:ut.cellsRange.endColIndex +1); + if (!ut.selectedTds.length) { + ut.insertCol(cellInfo.colIndex + cellInfo.colSpan, cell); + } else { + var range = ut.cellsRange; + for (var i = 0, len = range.endColIndex - range.beginColIndex + 1; i < len; i++) { + ut.insertCol(range.endColIndex + 1, cell); + } + } + rng.moveToBookmark(bk).select(); + } + }; + + UE.commands["deletecol"] = { + queryCommandState: function () { + var tableItems = getTableItemsByRange(this); + return tableItems.cell ? 0 : -1; + }, + execCommand: function () { + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell), + range = ut.cellsRange, + cellInfo = ut.getCellInfo(cell), + preCell = ut.getHSideCell(cell), + nextCell = ut.getHSideCell(cell, true); + if (utils.isEmptyObject(range)) { + ut.deleteCol(cellInfo.colIndex); + } else { + for (var i = range.beginColIndex; i < range.endColIndex + 1; i++) { + ut.deleteCol(range.beginColIndex); + } + } + var table = ut.table, + rng = this.selection.getRange(); + + if (!table.getElementsByTagName('td').length) { + var nextSibling = table.nextSibling; + domUtils.remove(table); + if (nextSibling) { + rng.setStart(nextSibling, 0).setCursor(false, true); + } + } else { + if (domUtils.inDoc(cell, this.document)) { + rng.setStart(cell, 0).setCursor(false, true); + } else { + if (nextCell && domUtils.inDoc(nextCell, this.document)) { + rng.selectNodeContents(nextCell).setCursor(false, true); + } else { + if (preCell && domUtils.inDoc(preCell, this.document)) { + rng.selectNodeContents(preCell).setCursor(true, true); + } + } + } + } + } + }; + UE.commands["splittocells"] = { + queryCommandState: function () { + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell; + if (!cell) return -1; + var ut = getUETable(tableItems.table); + if (ut.selectedTds.length > 0) return -1; + return cell && (cell.colSpan > 1 || cell.rowSpan > 1) ? 0 : -1; + }, + execCommand: function () { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell); + ut.splitToCells(cell); + rng.moveToBookmark(bk).select(); + } + }; + UE.commands["splittorows"] = { + queryCommandState: function () { + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell; + if (!cell) return -1; + var ut = getUETable(tableItems.table); + if (ut.selectedTds.length > 0) return -1; + return cell && cell.rowSpan > 1 ? 0 : -1; + }, + execCommand: function () { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell); + ut.splitToRows(cell); + rng.moveToBookmark(bk).select(); + } + }; + UE.commands["splittocols"] = { + queryCommandState: function () { + var tableItems = getTableItemsByRange(this), + cell = tableItems.cell; + if (!cell) return -1; + var ut = getUETable(tableItems.table); + if (ut.selectedTds.length > 0) return -1; + return cell && cell.colSpan > 1 ? 0 : -1; + }, + execCommand: function () { + var rng = this.selection.getRange(), + bk = rng.createBookmark(true); + var cell = getTableItemsByRange(this).cell, + ut = getUETable(cell); + ut.splitToCols(cell); + rng.moveToBookmark(bk).select(); + + } + }; + + UE.commands["adaptbytext"] = + UE.commands["adaptbywindow"] = { + queryCommandState: function () { + return getTableItemsByRange(this).table ? 0 : -1 + }, + execCommand: function (cmd) { + var tableItems = getTableItemsByRange(this), + table = tableItems.table; + if (table) { + if (cmd == 'adaptbywindow') { + resetTdWidth(table, this); + } else { + var cells = domUtils.getElementsByTagName(table, "td th"); + utils.each(cells, function (cell) { + cell.removeAttribute("width"); + }); + table.removeAttribute("width"); + } + } + } + }; + + //平均分配各列 + UE.commands['averagedistributecol'] = { + queryCommandState: function () { + var ut = getUETableBySelected(this); + if (!ut) return -1; + return ut.isFullRow() || ut.isFullCol() ? 0 : -1; + }, + execCommand: function (cmd) { + var me = this, + ut = getUETableBySelected(me); + + function getAverageWidth() { + var tb = ut.table, + averageWidth, sumWidth = 0, colsNum = 0, + tbAttr = getDefaultValue(me, tb); + + if (ut.isFullRow()) { + sumWidth = tb.offsetWidth; + colsNum = ut.colsNum; + } else { + var begin = ut.cellsRange.beginColIndex, + end = ut.cellsRange.endColIndex, + node; + for (var i = begin; i <= end;) { + node = ut.selectedTds[i]; + sumWidth += node.offsetWidth; + i += node.colSpan; + colsNum += 1; + } + } + averageWidth = Math.ceil(sumWidth / colsNum) - tbAttr.tdBorder * 2 - tbAttr.tdPadding * 2; + return averageWidth; + } + + function setAverageWidth(averageWidth) { + utils.each(domUtils.getElementsByTagName(ut.table, "th"), function (node) { + node.setAttribute("width", ""); + }); + var cells = ut.isFullRow() ? domUtils.getElementsByTagName(ut.table, "td") : ut.selectedTds; + + utils.each(cells, function (node) { + if (node.colSpan == 1) { + node.setAttribute("width", averageWidth); + } + }); + } + + if (ut && ut.selectedTds.length) { + setAverageWidth(getAverageWidth()); + } + } + }; + //平均分配各行 + UE.commands['averagedistributerow'] = { + queryCommandState: function () { + var ut = getUETableBySelected(this); + if (!ut) return -1; + if (ut.selectedTds && /th/ig.test(ut.selectedTds[0].tagName)) return -1; + return ut.isFullRow() || ut.isFullCol() ? 0 : -1; + }, + execCommand: function (cmd) { + var me = this, + ut = getUETableBySelected(me); + + function getAverageHeight() { + var averageHeight, rowNum, sumHeight = 0, + tb = ut.table, + tbAttr = getDefaultValue(me, tb), + tdpadding = parseInt(domUtils.getComputedStyle(tb.getElementsByTagName('td')[0], "padding-top")); + + if (ut.isFullCol()) { + var captionArr = domUtils.getElementsByTagName(tb, "caption"), + thArr = domUtils.getElementsByTagName(tb, "th"), + captionHeight, thHeight; + + if (captionArr.length > 0) { + captionHeight = captionArr[0].offsetHeight; + } + if (thArr.length > 0) { + thHeight = thArr[0].offsetHeight; + } + + sumHeight = tb.offsetHeight - (captionHeight || 0) - (thHeight || 0); + rowNum = thArr.length == 0 ? ut.rowsNum : (ut.rowsNum - 1); + } else { + var begin = ut.cellsRange.beginRowIndex, + end = ut.cellsRange.endRowIndex, + count = 0, + trs = domUtils.getElementsByTagName(tb, "tr"); + for (var i = begin; i <= end; i++) { + sumHeight += trs[i].offsetHeight; + count += 1; + } + rowNum = count; + } + //ie8下是混杂模式 + if (browser.ie && browser.version < 9) { + averageHeight = Math.ceil(sumHeight / rowNum); + } else { + averageHeight = Math.ceil(sumHeight / rowNum) - tbAttr.tdBorder * 2 - tdpadding * 2; + } + return averageHeight; + } + + function setAverageHeight(averageHeight) { + var cells = ut.isFullCol() ? domUtils.getElementsByTagName(ut.table, "td") : ut.selectedTds; + utils.each(cells, function (node) { + if (node.rowSpan == 1) { + node.setAttribute("height", averageHeight); + } + }); + } + + if (ut && ut.selectedTds.length) { + setAverageHeight(getAverageHeight()); + } + } + }; + + //单元格对齐方式 + UE.commands['cellalignment'] = { + queryCommandState: function () { + return getTableItemsByRange(this).table ? 0 : -1 + }, + execCommand: function (cmd, data) { + var me = this, + ut = getUETableBySelected(me); + + if (!ut) { + var start = me.selection.getStart(), + cell = start && domUtils.findParentByTagName(start, ["td", "th", "caption"], true); + if (!/caption/ig.test(cell.tagName)) { + domUtils.setAttributes(cell, data); + } else { + cell.style.textAlign = data.align; + cell.style.verticalAlign = data.vAlign; + } + me.selection.getRange().setCursor(true); + } else { + utils.each(ut.selectedTds, function (cell) { + domUtils.setAttributes(cell, data); + }); + } + }, + /** + * 查询当前点击的单元格的对齐状态, 如果当前已经选择了多个单元格, 则会返回所有单元格经过统一协调过后的状态 + * @see UE.UETable.getTableCellAlignState + */ + queryCommandValue: function (cmd) { + + var activeMenuCell = getTableItemsByRange( this).cell; + + if( !activeMenuCell ) { + activeMenuCell = getSelectedArr(this)[0]; + } + + if (!activeMenuCell) { + + return null; + + } else { + + //获取同时选中的其他单元格 + var cells = UE.UETable.getUETable(activeMenuCell).selectedTds; + + !cells.length && ( cells = activeMenuCell ); + + return UE.UETable.getTableCellAlignState(cells); + + } + + } + }; + //表格对齐方式 + UE.commands['tablealignment'] = { + queryCommandState: function () { + if (browser.ie && browser.version < 8) { + return -1; + } + return getTableItemsByRange(this).table ? 0 : -1 + }, + execCommand: function (cmd, value) { + var me = this, + start = me.selection.getStart(), + table = start && domUtils.findParentByTagName(start, ["table"], true); + + if (table) { + table.setAttribute("align",value); + } + } + }; + + //表格属性 + UE.commands['edittable'] = { + queryCommandState: function () { + return getTableItemsByRange(this).table ? 0 : -1 + }, + execCommand: function (cmd, color) { + var rng = this.selection.getRange(), + table = domUtils.findParentByTagName(rng.startContainer, 'table'); + if (table) { + var arr = domUtils.getElementsByTagName(table, "td").concat( + domUtils.getElementsByTagName(table, "th"), + domUtils.getElementsByTagName(table, "caption") + ); + utils.each(arr, function (node) { + node.style.borderColor = color; + }); + } + } + }; + //单元格属性 + UE.commands['edittd'] = { + queryCommandState: function () { + return getTableItemsByRange(this).table ? 0 : -1 + }, + execCommand: function (cmd, bkColor) { + var me = this, + ut = getUETableBySelected(me); + + if (!ut) { + var start = me.selection.getStart(), + cell = start && domUtils.findParentByTagName(start, ["td", "th", "caption"], true); + if (cell) { + cell.style.backgroundColor = bkColor; + } + } else { + utils.each(ut.selectedTds, function (cell) { + cell.style.backgroundColor = bkColor; + }); + } + } + }; + + UE.commands["settablebackground"] = { + queryCommandState: function () { + return getSelectedArr(this).length > 1 ? 0 : -1; + }, + execCommand: function (cmd, value) { + var cells, ut; + cells = getSelectedArr(this); + ut = getUETable(cells[0]); + ut.setBackground(cells, value); + } + }; + + UE.commands["cleartablebackground"] = { + queryCommandState: function () { + var cells = getSelectedArr(this); + if (!cells.length)return -1; + for (var i = 0, cell; cell = cells[i++];) { + if (cell.style.backgroundColor !== "") return 0; + } + return -1; + }, + execCommand: function () { + var cells = getSelectedArr(this), + ut = getUETable(cells[0]); + ut.removeBackground(cells); + } + }; + + UE.commands["interlacetable"] = UE.commands["uninterlacetable"] = { + queryCommandState: function (cmd) { + var table = getTableItemsByRange(this).table; + if (!table) return -1; + var interlaced = table.getAttribute("interlaced"); + if (cmd == "interlacetable") { + //TODO 待定 + //是否需要待定,如果设置,则命令只能单次执行成功,但反射具备toggle效果;否则可以覆盖前次命令,但反射将不存在toggle效果 + return (interlaced === "enabled") ? -1 : 0; + } else { + return (!interlaced || interlaced === "disabled") ? -1 : 0; + } + }, + execCommand: function (cmd, classList) { + var table = getTableItemsByRange(this).table; + if (cmd == "interlacetable") { + table.setAttribute("interlaced", "enabled"); + this.fireEvent("interlacetable", table, classList); + } else { + table.setAttribute("interlaced", "disabled"); + this.fireEvent("uninterlacetable", table); + } + } + }; + UE.commands["setbordervisible"] = { + queryCommandState: function (cmd) { + var table = getTableItemsByRange(this).table; + if (!table) return -1; + return 0; + }, + execCommand: function () { + var table = getTableItemsByRange(this).table; + utils.each(domUtils.getElementsByTagName(table,'td'),function(td){ + td.style.borderWidth = '1px'; + td.style.borderStyle = 'solid'; + }) + } + }; + function resetTdWidth(table, editor) { + var tds = domUtils.getElementsByTagName(table,'td th'); + utils.each(tds, function (td) { + td.removeAttribute("width"); + }); + table.setAttribute('width', getTableWidth(editor, true, getDefaultValue(editor, table))); + var tdsWidths = []; + setTimeout(function () { + utils.each(tds, function (td) { + (td.colSpan == 1) && tdsWidths.push(td.offsetWidth) + }) + utils.each(tds, function (td,i) { + (td.colSpan == 1) && td.setAttribute("width", tdsWidths[i] + ""); + }) + }, 0); + } + + function getTableWidth(editor, needIEHack, defaultValue) { + var body = editor.body; + return body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (editor.options.offsetWidth || 0); + } + + function getSelectedArr(editor) { + var cell = getTableItemsByRange(editor).cell; + if (cell) { + var ut = getUETable(cell); + return ut.selectedTds.length ? ut.selectedTds : [cell]; + } else { + return []; + } + } +})(); + + +// plugins/table.action.js +/** + * Created with JetBrains PhpStorm. + * User: taoqili + * Date: 12-10-12 + * Time: 上午10:05 + * To change this template use File | Settings | File Templates. + */ +UE.plugins['table'] = function () { + var me = this, + tabTimer = null, + //拖动计时器 + tableDragTimer = null, + //双击计时器 + tableResizeTimer = null, + //单元格最小宽度 + cellMinWidth = 5, + isInResizeBuffer = false, + //单元格边框大小 + cellBorderWidth = 5, + //鼠标偏移距离 + offsetOfTableCell = 10, + //记录在有限时间内的点击状态, 共有3个取值, 0, 1, 2。 0代表未初始化, 1代表单击了1次,2代表2次 + singleClickState = 0, + userActionStatus = null, + //双击允许的时间范围 + dblclickTime = 360, + UT = UE.UETable, + getUETable = function (tdOrTable) { + return UT.getUETable(tdOrTable); + }, + getUETableBySelected = function (editor) { + return UT.getUETableBySelected(editor); + }, + getDefaultValue = function (editor, table) { + return UT.getDefaultValue(editor, table); + }, + removeSelectedClass = function (cells) { + return UT.removeSelectedClass(cells); + }; + + function showError(e) { +// throw e; + } + me.ready(function(){ + var me = this; + var orgGetText = me.selection.getText; + me.selection.getText = function(){ + var table = getUETableBySelected(me); + if(table){ + var str = ''; + utils.each(table.selectedTds,function(td){ + str += td[browser.ie?'innerText':'textContent']; + }) + return str; + }else{ + return orgGetText.call(me.selection) + } + + } + }) + + //处理拖动及框选相关方法 + var startTd = null, //鼠标按下时的锚点td + currentTd = null, //当前鼠标经过时的td + onDrag = "", //指示当前拖动状态,其值可为"","h","v" ,分别表示未拖动状态,横向拖动状态,纵向拖动状态,用于鼠标移动过程中的判断 + onBorder = false, //检测鼠标按下时是否处在单元格边缘位置 + dragButton = null, + dragOver = false, + dragLine = null, //模拟的拖动线 + dragTd = null; //发生拖动的目标td + + var mousedown = false, + //todo 判断混乱模式 + needIEHack = true; + + me.setOpt({ + 'maxColNum':20, + 'maxRowNum':100, + 'defaultCols':5, + 'defaultRows':5, + 'tdvalign':'top', + 'cursorpath':me.options.UEDITOR_HOME_URL + "themes/default/images/cursor_", + 'tableDragable':false, + 'classList':["ue-table-interlace-color-single","ue-table-interlace-color-double"] + }); + me.getUETable = getUETable; + var commands = { + 'deletetable':1, + 'inserttable':1, + 'cellvalign':1, + 'insertcaption':1, + 'deletecaption':1, + 'inserttitle':1, + 'deletetitle':1, + "mergeright":1, + "mergedown":1, + "mergecells":1, + "insertrow":1, + "insertrownext":1, + "deleterow":1, + "insertcol":1, + "insertcolnext":1, + "deletecol":1, + "splittocells":1, + "splittorows":1, + "splittocols":1, + "adaptbytext":1, + "adaptbywindow":1, + "adaptbycustomer":1, + "insertparagraph":1, + "insertparagraphbeforetable":1, + "averagedistributecol":1, + "averagedistributerow":1 + }; + me.ready(function () { + utils.cssRule('table', + //选中的td上的样式 + '.selectTdClass{background-color:#edf5fa !important}' + + 'table.noBorderTable td,table.noBorderTable th,table.noBorderTable caption{border:1px dashed #ddd !important}' + + //插入的表格的默认样式 + 'table{margin-bottom:10px;border-collapse:collapse;display:table;}' + + 'td,th{padding: 5px 10px;border: 1px solid #DDD;}' + + 'caption{border:1px dashed #DDD;border-bottom:0;padding:3px;text-align:center;}' + + 'th{border-top:1px solid #BBB;background-color:#F7F7F7;}' + + 'table tr.firstRow th{border-top-width:2px;}' + + '.ue-table-interlace-color-single{ background-color: #fcfcfc; } .ue-table-interlace-color-double{ background-color: #f7faff; }' + + 'td p{margin:0;padding:0;}', me.document); + + var tableCopyList, isFullCol, isFullRow; + //注册del/backspace事件 + me.addListener('keydown', function (cmd, evt) { + var me = this; + var keyCode = evt.keyCode || evt.which; + + if (keyCode == 8) { + + var ut = getUETableBySelected(me); + if (ut && ut.selectedTds.length) { + + if (ut.isFullCol()) { + me.execCommand('deletecol') + } else if (ut.isFullRow()) { + me.execCommand('deleterow') + } else { + me.fireEvent('delcells'); + } + domUtils.preventDefault(evt); + } + + var caption = domUtils.findParentByTagName(me.selection.getStart(), 'caption', true), + range = me.selection.getRange(); + if (range.collapsed && caption && isEmptyBlock(caption)) { + me.fireEvent('saveScene'); + var table = caption.parentNode; + domUtils.remove(caption); + if (table) { + range.setStart(table.rows[0].cells[0], 0).setCursor(false, true); + } + me.fireEvent('saveScene'); + } + + } + + if (keyCode == 46) { + + ut = getUETableBySelected(me); + if (ut) { + me.fireEvent('saveScene'); + for (var i = 0, ci; ci = ut.selectedTds[i++];) { + domUtils.fillNode(me.document, ci) + } + me.fireEvent('saveScene'); + domUtils.preventDefault(evt); + + } + + } + if (keyCode == 13) { + + var rng = me.selection.getRange(), + caption = domUtils.findParentByTagName(rng.startContainer, 'caption', true); + if (caption) { + var table = domUtils.findParentByTagName(caption, 'table'); + if (!rng.collapsed) { + + rng.deleteContents(); + me.fireEvent('saveScene'); + } else { + if (caption) { + rng.setStart(table.rows[0].cells[0], 0).setCursor(false, true); + } + } + domUtils.preventDefault(evt); + return; + } + if (rng.collapsed) { + var table = domUtils.findParentByTagName(rng.startContainer, 'table'); + if (table) { + var cell = table.rows[0].cells[0], + start = domUtils.findParentByTagName(me.selection.getStart(), ['td', 'th'], true), + preNode = table.previousSibling; + if (cell === start && (!preNode || preNode.nodeType == 1 && preNode.tagName == 'TABLE' ) && domUtils.isStartInblock(rng)) { + var first = domUtils.findParent(me.selection.getStart(), function(n){return domUtils.isBlockElm(n)}, true); + if(first && ( /t(h|d)/i.test(first.tagName) || first === start.firstChild )){ + me.execCommand('insertparagraphbeforetable'); + domUtils.preventDefault(evt); + } + + } + } + } + } + + if ((evt.ctrlKey || evt.metaKey) && evt.keyCode == '67') { + tableCopyList = null; + var ut = getUETableBySelected(me); + if (ut) { + var tds = ut.selectedTds; + isFullCol = ut.isFullCol(); + isFullRow = ut.isFullRow(); + tableCopyList = [ + [ut.cloneCell(tds[0],null,true)] + ]; + for (var i = 1, ci; ci = tds[i]; i++) { + if (ci.parentNode !== tds[i - 1].parentNode) { + tableCopyList.push([ut.cloneCell(ci,null,true)]); + } else { + tableCopyList[tableCopyList.length - 1].push(ut.cloneCell(ci,null,true)); + } + + } + } + } + }); + me.addListener("tablehasdeleted",function(){ + toggleDraggableState(this, false, "", null); + if (dragButton)domUtils.remove(dragButton); + }); + + me.addListener('beforepaste', function (cmd, html) { + var me = this; + var rng = me.selection.getRange(); + if (domUtils.findParentByTagName(rng.startContainer, 'caption', true)) { + var div = me.document.createElement("div"); + div.innerHTML = html.html; + //trace:3729 + html.html = div[browser.ie9below ? 'innerText' : 'textContent']; + return; + } + var table = getUETableBySelected(me); + if (tableCopyList) { + me.fireEvent('saveScene'); + var rng = me.selection.getRange(); + var td = domUtils.findParentByTagName(rng.startContainer, ['td', 'th'], true), tmpNode, preNode; + if (td) { + var ut = getUETable(td); + if (isFullRow) { + var rowIndex = ut.getCellInfo(td).rowIndex; + if (td.tagName == 'TH') { + rowIndex++; + } + for (var i = 0, ci; ci = tableCopyList[i++];) { + var tr = ut.insertRow(rowIndex++, "td"); + for (var j = 0, cj; cj = ci[j]; j++) { + var cell = tr.cells[j]; + if (!cell) { + cell = tr.insertCell(j) + } + cell.innerHTML = cj.innerHTML; + cj.getAttribute('width') && cell.setAttribute('width', cj.getAttribute('width')); + cj.getAttribute('vAlign') && cell.setAttribute('vAlign', cj.getAttribute('vAlign')); + cj.getAttribute('align') && cell.setAttribute('align', cj.getAttribute('align')); + cj.style.cssText && (cell.style.cssText = cj.style.cssText) + } + for (var j = 0, cj; cj = tr.cells[j]; j++) { + if (!ci[j]) + break; + cj.innerHTML = ci[j].innerHTML; + ci[j].getAttribute('width') && cj.setAttribute('width', ci[j].getAttribute('width')); + ci[j].getAttribute('vAlign') && cj.setAttribute('vAlign', ci[j].getAttribute('vAlign')); + ci[j].getAttribute('align') && cj.setAttribute('align', ci[j].getAttribute('align')); + ci[j].style.cssText && (cj.style.cssText = ci[j].style.cssText) + } + } + } else { + if (isFullCol) { + cellInfo = ut.getCellInfo(td); + var maxColNum = 0; + for (var j = 0, ci = tableCopyList[0], cj; cj = ci[j++];) { + maxColNum += cj.colSpan || 1; + } + me.__hasEnterExecCommand = true; + for (i = 0; i < maxColNum; i++) { + me.execCommand('insertcol'); + } + me.__hasEnterExecCommand = false; + td = ut.table.rows[0].cells[cellInfo.cellIndex]; + if (td.tagName == 'TH') { + td = ut.table.rows[1].cells[cellInfo.cellIndex]; + } + } + for (var i = 0, ci; ci = tableCopyList[i++];) { + tmpNode = td; + for (var j = 0, cj; cj = ci[j++];) { + if (td) { + td.innerHTML = cj.innerHTML; + //todo 定制处理 + cj.getAttribute('width') && td.setAttribute('width', cj.getAttribute('width')); + cj.getAttribute('vAlign') && td.setAttribute('vAlign', cj.getAttribute('vAlign')); + cj.getAttribute('align') && td.setAttribute('align', cj.getAttribute('align')); + cj.style.cssText && (td.style.cssText = cj.style.cssText); + preNode = td; + td = td.nextSibling; + } else { + var cloneTd = cj.cloneNode(true); + domUtils.removeAttributes(cloneTd, ['class', 'rowSpan', 'colSpan']); + + preNode.parentNode.appendChild(cloneTd) + } + } + td = ut.getNextCell(tmpNode, true, true); + if (!tableCopyList[i]) + break; + if (!td) { + var cellInfo = ut.getCellInfo(tmpNode); + ut.table.insertRow(ut.table.rows.length); + ut.update(); + td = ut.getVSideCell(tmpNode, true); + } + } + } + ut.update(); + } else { + table = me.document.createElement('table'); + for (var i = 0, ci; ci = tableCopyList[i++];) { + var tr = table.insertRow(table.rows.length); + for (var j = 0, cj; cj = ci[j++];) { + cloneTd = UT.cloneCell(cj,null,true); + domUtils.removeAttributes(cloneTd, ['class']); + tr.appendChild(cloneTd) + } + if (j == 2 && cloneTd.rowSpan > 1) { + cloneTd.rowSpan = 1; + } + } + + var defaultValue = getDefaultValue(me), + width = me.body.offsetWidth - + (needIEHack ? parseInt(domUtils.getComputedStyle(me.body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (me.options.offsetWidth || 0); + me.execCommand('insertHTML', '' + table.innerHTML.replace(/>\s*<').replace(/\bth\b/gi, "td") + '
          ') + } + me.fireEvent('contentchange'); + me.fireEvent('saveScene'); + html.html = ''; + return true; + } else { + var div = me.document.createElement("div"), tables; + div.innerHTML = html.html; + tables = div.getElementsByTagName("table"); + if (domUtils.findParentByTagName(me.selection.getStart(), 'table')) { + utils.each(tables, function (t) { + domUtils.remove(t) + }); + if (domUtils.findParentByTagName(me.selection.getStart(), 'caption', true)) { + div.innerHTML = div[browser.ie ? 'innerText' : 'textContent']; + } + } else { + utils.each(tables, function (table) { + removeStyleSize(table, true); + domUtils.removeAttributes(table, ['style', 'border']); + utils.each(domUtils.getElementsByTagName(table, "td"), function (td) { + if (isEmptyBlock(td)) { + domUtils.fillNode(me.document, td); + } + removeStyleSize(td, true); +// domUtils.removeAttributes(td, ['style']) + }); + }); + } + html.html = div.innerHTML; + } + }); + + me.addListener('afterpaste', function () { + utils.each(domUtils.getElementsByTagName(me.body, "table"), function (table) { + if (table.offsetWidth > me.body.offsetWidth) { + var defaultValue = getDefaultValue(me, table); + table.style.width = me.body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(me.body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (me.options.offsetWidth || 0) + 'px' + } + }) + }); + me.addListener('blur', function () { + tableCopyList = null; + }); + var timer; + me.addListener('keydown', function () { + clearTimeout(timer); + timer = setTimeout(function () { + var rng = me.selection.getRange(), + cell = domUtils.findParentByTagName(rng.startContainer, ['th', 'td'], true); + if (cell) { + var table = cell.parentNode.parentNode.parentNode; + if (table.offsetWidth > table.getAttribute("width")) { + cell.style.wordBreak = "break-all"; + } + } + + }, 100); + }); + me.addListener("selectionchange", function () { + toggleDraggableState(me, false, "", null); + }); + + + //内容变化时触发索引更新 + //todo 可否考虑标记检测,如果不涉及表格的变化就不进行索引重建和更新 + me.addListener("contentchange", function () { + var me = this; + //尽可能排除一些不需要更新的状况 + hideDragLine(me); + if (getUETableBySelected(me))return; + var rng = me.selection.getRange(); + var start = rng.startContainer; + start = domUtils.findParentByTagName(start, ['td', 'th'], true); + utils.each(domUtils.getElementsByTagName(me.document, 'table'), function (table) { + if (me.fireEvent("excludetable", table) === true) return; + table.ueTable = new UT(table); + //trace:3742 +// utils.each(domUtils.getElementsByTagName(me.document, 'td'), function (td) { +// +// if (domUtils.isEmptyBlock(td) && td !== start) { +// domUtils.fillNode(me.document, td); +// if (browser.ie && browser.version == 6) { +// td.innerHTML = ' ' +// } +// } +// }); +// utils.each(domUtils.getElementsByTagName(me.document, 'th'), function (th) { +// if (domUtils.isEmptyBlock(th) && th !== start) { +// domUtils.fillNode(me.document, th); +// if (browser.ie && browser.version == 6) { +// th.innerHTML = ' ' +// } +// } +// }); + table.onmouseover = function () { + me.fireEvent('tablemouseover', table); + }; + table.onmousemove = function () { + me.fireEvent('tablemousemove', table); + me.options.tableDragable && toggleDragButton(true, this, me); + utils.defer(function(){ + me.fireEvent('contentchange',50) + },true) + }; + table.onmouseout = function () { + me.fireEvent('tablemouseout', table); + toggleDraggableState(me, false, "", null); + hideDragLine(me); + }; + table.onclick = function (evt) { + evt = me.window.event || evt; + var target = getParentTdOrTh(evt.target || evt.srcElement); + if (!target)return; + var ut = getUETable(target), + table = ut.table, + cellInfo = ut.getCellInfo(target), + cellsRange, + rng = me.selection.getRange(); +// if ("topLeft" == inPosition(table, mouseCoords(evt))) { +// cellsRange = ut.getCellsRange(ut.table.rows[0].cells[0], ut.getLastCell()); +// ut.setSelected(cellsRange); +// return; +// } +// if ("bottomRight" == inPosition(table, mouseCoords(evt))) { +// +// return; +// } + if (inTableSide(table, target, evt, true)) { + var endTdCol = ut.getCell(ut.indexTable[ut.rowsNum - 1][cellInfo.colIndex].rowIndex, ut.indexTable[ut.rowsNum - 1][cellInfo.colIndex].cellIndex); + if (evt.shiftKey && ut.selectedTds.length) { + if (ut.selectedTds[0] !== endTdCol) { + cellsRange = ut.getCellsRange(ut.selectedTds[0], endTdCol); + ut.setSelected(cellsRange); + } else { + rng && rng.selectNodeContents(endTdCol).select(); + } + } else { + if (target !== endTdCol) { + cellsRange = ut.getCellsRange(target, endTdCol); + ut.setSelected(cellsRange); + } else { + rng && rng.selectNodeContents(endTdCol).select(); + } + } + return; + } + if (inTableSide(table, target, evt)) { + var endTdRow = ut.getCell(ut.indexTable[cellInfo.rowIndex][ut.colsNum - 1].rowIndex, ut.indexTable[cellInfo.rowIndex][ut.colsNum - 1].cellIndex); + if (evt.shiftKey && ut.selectedTds.length) { + if (ut.selectedTds[0] !== endTdRow) { + cellsRange = ut.getCellsRange(ut.selectedTds[0], endTdRow); + ut.setSelected(cellsRange); + } else { + rng && rng.selectNodeContents(endTdRow).select(); + } + } else { + if (target !== endTdRow) { + cellsRange = ut.getCellsRange(target, endTdRow); + ut.setSelected(cellsRange); + } else { + rng && rng.selectNodeContents(endTdRow).select(); + } + } + } + }; + }); + + switchBorderColor(me, true); + }); + + domUtils.on(me.document, "mousemove", mouseMoveEvent); + + domUtils.on(me.document, "mouseout", function (evt) { + var target = evt.target || evt.srcElement; + if (target.tagName == "TABLE") { + toggleDraggableState(me, false, "", null); + } + }); + /** + * 表格隔行变色 + */ + me.addListener("interlacetable",function(type,table,classList){ + if(!table) return; + var me = this, + rows = table.rows, + len = rows.length, + getClass = function(list,index,repeat){ + return list[index] ? list[index] : repeat ? list[index % list.length]: ""; + }; + for(var i = 0;i 1 ? currentRowIndex : ua.getCellInfo(cell).rowIndex; + var nextCell = ua.getTabNextCell(cell, currentRowIndex); + if (nextCell) { + if (isEmptyBlock(nextCell)) { + range.setStart(nextCell, 0).setCursor(false, true) + } else { + range.selectNodeContents(nextCell).select() + } + } else { + me.fireEvent('saveScene'); + me.__hasEnterExecCommand = true; + this.execCommand('insertrownext'); + me.__hasEnterExecCommand = false; + range = this.selection.getRange(); + range.setStart(table.rows[table.rows.length - 1].cells[0], 0).setCursor(); + me.fireEvent('saveScene'); + } + } + return true; + } + + }); + browser.ie && me.addListener('selectionchange', function () { + toggleDraggableState(this, false, "", null); + }); + me.addListener("keydown", function (type, evt) { + var me = this; + //处理在表格的最后一个输入tab产生新的表格 + var keyCode = evt.keyCode || evt.which; + if (keyCode == 8 || keyCode == 46) { + return; + } + var notCtrlKey = !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey; + notCtrlKey && removeSelectedClass(domUtils.getElementsByTagName(me.body, "td")); + var ut = getUETableBySelected(me); + if (!ut) return; + notCtrlKey && ut.clearSelected(); + }); + + me.addListener("beforegetcontent", function () { + switchBorderColor(this, false); + browser.ie && utils.each(this.document.getElementsByTagName('caption'), function (ci) { + if (domUtils.isEmptyNode(ci)) { + ci.innerHTML = ' ' + } + }); + }); + me.addListener("aftergetcontent", function () { + switchBorderColor(this, true); + }); + me.addListener("getAllHtml", function () { + removeSelectedClass(me.document.getElementsByTagName("td")); + }); + //修正全屏状态下插入的表格宽度在非全屏状态下撑开编辑器的情况 + me.addListener("fullscreenchanged", function (type, fullscreen) { + if (!fullscreen) { + var ratio = this.body.offsetWidth / document.body.offsetWidth, + tables = domUtils.getElementsByTagName(this.body, "table"); + utils.each(tables, function (table) { + if (table.offsetWidth < me.body.offsetWidth) return false; + var tds = domUtils.getElementsByTagName(table, "td"), + backWidths = []; + utils.each(tds, function (td) { + backWidths.push(td.offsetWidth); + }); + for (var i = 0, td; td = tds[i]; i++) { + td.setAttribute("width", Math.floor(backWidths[i] * ratio)); + } + table.setAttribute("width", Math.floor(getTableWidth(me, needIEHack, getDefaultValue(me)))) + }); + } + }); + + //重写execCommand命令,用于处理框选时的处理 + var oldExecCommand = me.execCommand; + me.execCommand = function (cmd, datatat) { + + var me = this, + args = arguments; + + cmd = cmd.toLowerCase(); + var ut = getUETableBySelected(me), tds, + range = new dom.Range(me.document), + cmdFun = me.commands[cmd] || UE.commands[cmd], + result; + if (!cmdFun) return; + if (ut && !commands[cmd] && !cmdFun.notNeedUndo && !me.__hasEnterExecCommand) { + me.__hasEnterExecCommand = true; + me.fireEvent("beforeexeccommand", cmd); + tds = ut.selectedTds; + var lastState = -2, lastValue = -2, value, state; + for (var i = 0, td; td = tds[i]; i++) { + if (isEmptyBlock(td)) { + range.setStart(td, 0).setCursor(false, true) + } else { + range.selectNode(td).select(true); + } + state = me.queryCommandState(cmd); + value = me.queryCommandValue(cmd); + if (state != -1) { + if (lastState !== state || lastValue !== value) { + me._ignoreContentChange = true; + result = oldExecCommand.apply(me, arguments); + me._ignoreContentChange = false; + + } + lastState = me.queryCommandState(cmd); + lastValue = me.queryCommandValue(cmd); + if (domUtils.isEmptyBlock(td)) { + domUtils.fillNode(me.document, td) + } + } + } + range.setStart(tds[0], 0).shrinkBoundary(true).setCursor(false, true); + me.fireEvent('contentchange'); + me.fireEvent("afterexeccommand", cmd); + me.__hasEnterExecCommand = false; + me._selectionChange(); + } else { + result = oldExecCommand.apply(me, arguments); + } + return result; + }; + + + }); + /** + * 删除obj的宽高style,改成属性宽高 + * @param obj + * @param replaceToProperty + */ + function removeStyleSize(obj, replaceToProperty) { + removeStyle(obj, "width", true); + removeStyle(obj, "height", true); + } + + function removeStyle(obj, styleName, replaceToProperty) { + if (obj.style[styleName]) { + replaceToProperty && obj.setAttribute(styleName, parseInt(obj.style[styleName], 10)); + obj.style[styleName] = ""; + } + } + + function getParentTdOrTh(ele) { + if (ele.tagName == "TD" || ele.tagName == "TH") return ele; + var td; + if (td = domUtils.findParentByTagName(ele, "td", true) || domUtils.findParentByTagName(ele, "th", true)) return td; + return null; + } + + function isEmptyBlock(node) { + var reg = new RegExp(domUtils.fillChar, 'g'); + if (node[browser.ie ? 'innerText' : 'textContent'].replace(/^\s*$/, '').replace(reg, '').length > 0) { + return 0; + } + for (var n in dtd.$isNotEmpty) { + if (node.getElementsByTagName(n).length) { + return 0; + } + } + return 1; + } + + + function mouseCoords(evt) { + if (evt.pageX || evt.pageY) { + return { x:evt.pageX, y:evt.pageY }; + } + return { + x:evt.clientX + me.document.body.scrollLeft - me.document.body.clientLeft, + y:evt.clientY + me.document.body.scrollTop - me.document.body.clientTop + }; + } + + function mouseMoveEvent(evt) { + + if( isEditorDisabled() ) { + return; + } + + try { + + //普通状态下鼠标移动 + var target = getParentTdOrTh(evt.target || evt.srcElement), + pos; + + //区分用户的行为是拖动还是双击 + if( isInResizeBuffer ) { + + me.body.style.webkitUserSelect = 'none'; + + if( Math.abs( userActionStatus.x - evt.clientX ) > offsetOfTableCell || Math.abs( userActionStatus.y - evt.clientY ) > offsetOfTableCell ) { + clearTableDragTimer(); + isInResizeBuffer = false; + singleClickState = 0; + //drag action + tableBorderDrag(evt); + } + } + + //修改单元格大小时的鼠标移动 + if (onDrag && dragTd) { + singleClickState = 0; + me.body.style.webkitUserSelect = 'none'; + me.selection.getNative()[browser.ie9below ? 'empty' : 'removeAllRanges'](); + pos = mouseCoords(evt); + toggleDraggableState(me, true, onDrag, pos, target); + if (onDrag == "h") { + dragLine.style.left = getPermissionX(dragTd, evt) + "px"; + } else if (onDrag == "v") { + dragLine.style.top = getPermissionY(dragTd, evt) + "px"; + } + return; + } + //当鼠标处于table上时,修改移动过程中的光标状态 + if (target) { + //针对使用table作为容器的组件不触发拖拽效果 + if (me.fireEvent('excludetable', target) === true) + return; + pos = mouseCoords(evt); + var state = getRelation(target, pos), + table = domUtils.findParentByTagName(target, "table", true); + + if (inTableSide(table, target, evt, true)) { + if (me.fireEvent("excludetable", table) === true) return; + me.body.style.cursor = "url(" + me.options.cursorpath + "h.png),pointer"; + } else if (inTableSide(table, target, evt)) { + if (me.fireEvent("excludetable", table) === true) return; + me.body.style.cursor = "url(" + me.options.cursorpath + "v.png),pointer"; + } else { + me.body.style.cursor = "text"; + var curCell = target; + if (/\d/.test(state)) { + state = state.replace(/\d/, ''); + target = getUETable(target).getPreviewCell(target, state == "v"); + } + //位于第一行的顶部或者第一列的左边时不可拖动 + toggleDraggableState(me, target ? !!state : false, target ? state : '', pos, target); + + } + } else { + toggleDragButton(false, table, me); + } + + } catch (e) { + showError(e); + } + } + + var dragButtonTimer; + + function toggleDragButton(show, table, editor) { + if (!show) { + if (dragOver)return; + dragButtonTimer = setTimeout(function () { + !dragOver && dragButton && dragButton.parentNode && dragButton.parentNode.removeChild(dragButton); + }, 2000); + } else { + createDragButton(table, editor); + } + } + + function createDragButton(table, editor) { + var pos = domUtils.getXY(table), + doc = table.ownerDocument; + if (dragButton && dragButton.parentNode)return dragButton; + dragButton = doc.createElement("div"); + dragButton.contentEditable = false; + dragButton.innerHTML = ""; + dragButton.style.cssText = "width:15px;height:15px;background-image:url(" + editor.options.UEDITOR_HOME_URL + "dialogs/table/dragicon.png);position: absolute;cursor:move;top:" + (pos.y - 15) + "px;left:" + (pos.x) + "px;"; + domUtils.unSelectable(dragButton); + dragButton.onmouseover = function (evt) { + dragOver = true; + }; + dragButton.onmouseout = function (evt) { + dragOver = false; + }; + domUtils.on(dragButton, 'click', function (type, evt) { + doClick(evt, this); + }); + domUtils.on(dragButton, 'dblclick', function (type, evt) { + doDblClick(evt); + }); + domUtils.on(dragButton, 'dragstart', function (type, evt) { + domUtils.preventDefault(evt); + }); + var timer; + + function doClick(evt, button) { + // 部分浏览器下需要清理 + clearTimeout(timer); + timer = setTimeout(function () { + editor.fireEvent("tableClicked", table, button); + }, 300); + } + + function doDblClick(evt) { + clearTimeout(timer); + var ut = getUETable(table), + start = table.rows[0].cells[0], + end = ut.getLastCell(), + range = ut.getCellsRange(start, end); + editor.selection.getRange().setStart(start, 0).setCursor(false, true); + ut.setSelected(range); + } + + doc.body.appendChild(dragButton); + } + + +// function inPosition(table, pos) { +// var tablePos = domUtils.getXY(table), +// width = table.offsetWidth, +// height = table.offsetHeight; +// if (pos.x - tablePos.x < 5 && pos.y - tablePos.y < 5) { +// return "topLeft"; +// } else if (tablePos.x + width - pos.x < 5 && tablePos.y + height - pos.y < 5) { +// return "bottomRight"; +// } +// } + + function inTableSide(table, cell, evt, top) { + var pos = mouseCoords(evt), + state = getRelation(cell, pos); + + if (top) { + var caption = table.getElementsByTagName("caption")[0], + capHeight = caption ? caption.offsetHeight : 0; + return (state == "v1") && ((pos.y - domUtils.getXY(table).y - capHeight) < 8); + } else { + return (state == "h1") && ((pos.x - domUtils.getXY(table).x) < 8); + } + } + + /** + * 获取拖动时允许的X轴坐标 + * @param dragTd + * @param evt + */ + function getPermissionX(dragTd, evt) { + var ut = getUETable(dragTd); + if (ut) { + var preTd = ut.getSameEndPosCells(dragTd, "x")[0], + nextTd = ut.getSameStartPosXCells(dragTd)[0], + mouseX = mouseCoords(evt).x, + left = (preTd ? domUtils.getXY(preTd).x : domUtils.getXY(ut.table).x) + 20 , + right = nextTd ? domUtils.getXY(nextTd).x + nextTd.offsetWidth - 20 : (me.body.offsetWidth + 5 || parseInt(domUtils.getComputedStyle(me.body, "width"), 10)); + + left += cellMinWidth; + right -= cellMinWidth; + + return mouseX < left ? left : mouseX > right ? right : mouseX; + } + } + + /** + * 获取拖动时允许的Y轴坐标 + */ + function getPermissionY(dragTd, evt) { + try { + var top = domUtils.getXY(dragTd).y, + mousePosY = mouseCoords(evt).y; + return mousePosY < top ? top : mousePosY; + } catch (e) { + showError(e); + } + } + + /** + * 移动状态切换 + */ + function toggleDraggableState(editor, draggable, dir, mousePos, cell) { + try { + editor.body.style.cursor = dir == "h" ? "col-resize" : dir == "v" ? "row-resize" : "text"; + if (browser.ie) { + if (dir && !mousedown && !getUETableBySelected(editor)) { + getDragLine(editor, editor.document); + showDragLineAt(dir, cell); + } else { + hideDragLine(editor) + } + } + onBorder = draggable; + } catch (e) { + showError(e); + } + } + + /** + * 获取与UETable相关的resize line + * @param uetable UETable对象 + */ + function getResizeLineByUETable() { + + var lineId = '_UETableResizeLine', + line = this.document.getElementById( lineId ); + + if( !line ) { + line = this.document.createElement("div"); + line.id = lineId; + line.contnetEditable = false; + line.setAttribute("unselectable", "on"); + + var styles = { + width: 2*cellBorderWidth + 1 + 'px', + position: 'absolute', + 'z-index': 100000, + cursor: 'col-resize', + background: 'red', + display: 'none' + }; + + //切换状态 + line.onmouseout = function(){ + this.style.display = 'none'; + }; + + utils.extend( line.style, styles ); + + this.document.body.appendChild( line ); + + } + + return line; + + } + + /** + * 更新resize-line + */ + function updateResizeLine( cell, uetable ) { + + var line = getResizeLineByUETable.call( this ), + table = uetable.table, + styles = { + top: domUtils.getXY( table ).y + 'px', + left: domUtils.getXY( cell).x + cell.offsetWidth - cellBorderWidth + 'px', + display: 'block', + height: table.offsetHeight + 'px' + }; + + utils.extend( line.style, styles ); + + } + + /** + * 显示resize-line + */ + function showResizeLine( cell ) { + + var uetable = getUETable( cell ); + + updateResizeLine.call( this, cell, uetable ); + + } + + /** + * 获取鼠标与当前单元格的相对位置 + * @param ele + * @param mousePos + */ + function getRelation(ele, mousePos) { + var elePos = domUtils.getXY(ele); + + if( !elePos ) { + return ''; + } + + if (elePos.x + ele.offsetWidth - mousePos.x < cellBorderWidth) { + return "h"; + } + if (mousePos.x - elePos.x < cellBorderWidth) { + return 'h1' + } + if (elePos.y + ele.offsetHeight - mousePos.y < cellBorderWidth) { + return "v"; + } + if (mousePos.y - elePos.y < cellBorderWidth) { + return 'v1' + } + return ''; + } + + function mouseDownEvent(type, evt) { + + if( isEditorDisabled() ) { + return ; + } + + userActionStatus = { + x: evt.clientX, + y: evt.clientY + }; + + //右键菜单单独处理 + if (evt.button == 2) { + var ut = getUETableBySelected(me), + flag = false; + + if (ut) { + var td = getTargetTd(me, evt); + utils.each(ut.selectedTds, function (ti) { + if (ti === td) { + flag = true; + } + }); + if (!flag) { + removeSelectedClass(domUtils.getElementsByTagName(me.body, "th td")); + ut.clearSelected() + } else { + td = ut.selectedTds[0]; + setTimeout(function () { + me.selection.getRange().setStart(td, 0).setCursor(false, true); + }, 0); + + } + } + } else { + tableClickHander( evt ); + } + + } + + //清除表格的计时器 + function clearTableTimer() { + tabTimer && clearTimeout( tabTimer ); + tabTimer = null; + } + + //双击收缩 + function tableDbclickHandler(evt) { + singleClickState = 0; + evt = evt || me.window.event; + var target = getParentTdOrTh(evt.target || evt.srcElement); + if (target) { + var h; + if (h = getRelation(target, mouseCoords(evt))) { + + hideDragLine( me ); + + if (h == 'h1') { + h = 'h'; + if (inTableSide(domUtils.findParentByTagName(target, "table"), target, evt)) { + me.execCommand('adaptbywindow'); + } else { + target = getUETable(target).getPreviewCell(target); + if (target) { + var rng = me.selection.getRange(); + rng.selectNodeContents(target).setCursor(true, true) + } + } + } + if (h == 'h') { + var ut = getUETable(target), + table = ut.table, + cells = getCellsByMoveBorder( target, table, true ); + + cells = extractArray( cells, 'left' ); + + ut.width = ut.offsetWidth; + + var oldWidth = [], + newWidth = []; + + utils.each( cells, function( cell ){ + + oldWidth.push( cell.offsetWidth ); + + } ); + + utils.each( cells, function( cell ){ + + cell.removeAttribute("width"); + + } ); + + window.setTimeout( function(){ + + //是否允许改变 + var changeable = true; + + utils.each( cells, function( cell, index ){ + + var width = cell.offsetWidth; + + if( width > oldWidth[index] ) { + changeable = false; + return false; + } + + newWidth.push( width ); + + } ); + + var change = changeable ? newWidth : oldWidth; + + utils.each( cells, function( cell, index ){ + + cell.width = change[index] - getTabcellSpace(); + + } ); + + + }, 0 ); + +// minWidth -= cellMinWidth; +// +// table.removeAttribute("width"); +// utils.each(cells, function (cell) { +// cell.style.width = ""; +// cell.width -= minWidth; +// }); + + } + } + } + } + + function tableClickHander( evt ) { + + removeSelectedClass(domUtils.getElementsByTagName(me.body, "td th")); + //trace:3113 + //选中单元格,点击table外部,不会清掉table上挂的ueTable,会引起getUETableBySelected方法返回值 + utils.each(me.document.getElementsByTagName('table'), function (t) { + t.ueTable = null; + }); + startTd = getTargetTd(me, evt); + if( !startTd ) return; + var table = domUtils.findParentByTagName(startTd, "table", true); + ut = getUETable(table); + ut && ut.clearSelected(); + + //判断当前鼠标状态 + if (!onBorder) { + me.document.body.style.webkitUserSelect = ''; + mousedown = true; + me.addListener('mouseover', mouseOverEvent); + } else { + //边框上的动作处理 + borderActionHandler( evt ); + } + + + } + + //处理表格边框上的动作, 这里做延时处理,避免两种动作互相影响 + function borderActionHandler( evt ) { + + if ( browser.ie ) { + evt = reconstruct(evt ); + } + + clearTableDragTimer(); + + //是否正在等待resize的缓冲中 + isInResizeBuffer = true; + + tableDragTimer = setTimeout(function(){ + tableBorderDrag( evt ); + }, dblclickTime); + + } + + function extractArray( originArr, key ) { + + var result = [], + tmp = null; + + for( var i = 0, len = originArr.length; i 0 && singleClickState--; + }, dblclickTime ); + + if( singleClickState === 2 ) { + + singleClickState = 0; + tableDbclickHandler(evt); + return; + + } + + } + + if (evt.button == 2)return; + var me = this; + //清除表格上原生跨选问题 + var range = me.selection.getRange(), + start = domUtils.findParentByTagName(range.startContainer, 'table', true), + end = domUtils.findParentByTagName(range.endContainer, 'table', true); + + if (start || end) { + if (start === end) { + start = domUtils.findParentByTagName(range.startContainer, ['td', 'th', 'caption'], true); + end = domUtils.findParentByTagName(range.endContainer, ['td', 'th', 'caption'], true); + if (start !== end) { + me.selection.clearRange() + } + } else { + me.selection.clearRange() + } + } + mousedown = false; + me.document.body.style.webkitUserSelect = ''; + //拖拽状态下的mouseUP + if ( onDrag && dragTd ) { + + me.selection.getNative()[browser.ie9below ? 'empty' : 'removeAllRanges'](); + + singleClickState = 0; + dragLine = me.document.getElementById('ue_tableDragLine'); + + // trace 3973 + if (dragLine) { + var dragTdPos = domUtils.getXY(dragTd), + dragLinePos = domUtils.getXY(dragLine); + + switch (onDrag) { + case "h": + changeColWidth(dragTd, dragLinePos.x - dragTdPos.x); + break; + case "v": + changeRowHeight(dragTd, dragLinePos.y - dragTdPos.y - dragTd.offsetHeight); + break; + default: + } + onDrag = ""; + dragTd = null; + + hideDragLine(me); + me.fireEvent('saveScene'); + return; + } + } + //正常状态下的mouseup + if (!startTd) { + var target = domUtils.findParentByTagName(evt.target || evt.srcElement, "td", true); + if (!target) target = domUtils.findParentByTagName(evt.target || evt.srcElement, "th", true); + if (target && (target.tagName == "TD" || target.tagName == "TH")) { + if (me.fireEvent("excludetable", target) === true) return; + range = new dom.Range(me.document); + range.setStart(target, 0).setCursor(false, true); + } + } else { + var ut = getUETable(startTd), + cell = ut ? ut.selectedTds[0] : null; + if (cell) { + range = new dom.Range(me.document); + if (domUtils.isEmptyBlock(cell)) { + range.setStart(cell, 0).setCursor(false, true); + } else { + range.selectNodeContents(cell).shrinkBoundary().setCursor(false, true); + } + } else { + range = me.selection.getRange().shrinkBoundary(); + if (!range.collapsed) { + var start = domUtils.findParentByTagName(range.startContainer, ['td', 'th'], true), + end = domUtils.findParentByTagName(range.endContainer, ['td', 'th'], true); + //在table里边的不能清除 + if (start && !end || !start && end || start && end && start !== end) { + range.setCursor(false, true); + } + } + } + startTd = null; + me.removeListener('mouseover', mouseOverEvent); + } + me._selectionChange(250, evt); + } + + function mouseOverEvent(type, evt) { + + if( isEditorDisabled() ) { + return; + } + + var me = this, + tar = evt.target || evt.srcElement; + currentTd = domUtils.findParentByTagName(tar, "td", true) || domUtils.findParentByTagName(tar, "th", true); + //需要判断两个TD是否位于同一个表格内 + if (startTd && currentTd && + ((startTd.tagName == "TD" && currentTd.tagName == "TD") || (startTd.tagName == "TH" && currentTd.tagName == "TH")) && + domUtils.findParentByTagName(startTd, 'table') == domUtils.findParentByTagName(currentTd, 'table')) { + var ut = getUETable(currentTd); + if (startTd != currentTd) { + me.document.body.style.webkitUserSelect = 'none'; + me.selection.getNative()[browser.ie9below ? 'empty' : 'removeAllRanges'](); + var range = ut.getCellsRange(startTd, currentTd); + ut.setSelected(range); + } else { + me.document.body.style.webkitUserSelect = ''; + ut.clearSelected(); + } + + } + evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false); + } + + function setCellHeight(cell, height, backHeight) { + var lineHight = parseInt(domUtils.getComputedStyle(cell, "line-height"), 10), + tmpHeight = backHeight + height; + height = tmpHeight < lineHight ? lineHight : tmpHeight; + if (cell.style.height) cell.style.height = ""; + cell.rowSpan == 1 ? cell.setAttribute("height", height) : (cell.removeAttribute && cell.removeAttribute("height")); + } + + function getWidth(cell) { + if (!cell)return 0; + return parseInt(domUtils.getComputedStyle(cell, "width"), 10); + } + + function changeColWidth(cell, changeValue) { + + var ut = getUETable(cell); + if (ut) { + + //根据当前移动的边框获取相关的单元格 + var table = ut.table, + cells = getCellsByMoveBorder( cell, table ); + + table.style.width = ""; + table.removeAttribute("width"); + + //修正改变量 + changeValue = correctChangeValue( changeValue, cell, cells ); + + if (cell.nextSibling) { + + var i=0; + + utils.each( cells, function( cellGroup ){ + + cellGroup.left.width = (+cellGroup.left.width)+changeValue; + cellGroup.right && ( cellGroup.right.width = (+cellGroup.right.width)-changeValue ); + + } ); + + } else { + + utils.each( cells, function( cellGroup ){ + cellGroup.left.width -= -changeValue; + } ); + + } + } + + } + + function isEditorDisabled() { + return me.body.contentEditable === "false"; + } + + function changeRowHeight(td, changeValue) { + if (Math.abs(changeValue) < 10) return; + var ut = getUETable(td); + if (ut) { + var cells = ut.getSameEndPosCells(td, "y"), + //备份需要连带变化的td的原始高度,否则后期无法获取正确的值 + backHeight = cells[0] ? cells[0].offsetHeight : 0; + for (var i = 0, cell; cell = cells[i++];) { + setCellHeight(cell, changeValue, backHeight); + } + } + + } + + /** + * 获取调整单元格大小的相关单元格 + * @isContainMergeCell 返回的结果中是否包含发生合并后的单元格 + */ + function getCellsByMoveBorder( cell, table, isContainMergeCell ) { + + if( !table ) { + table = domUtils.findParentByTagName( cell, 'table' ); + } + + if( !table ) { + return null; + } + + //获取到该单元格所在行的序列号 + var index = domUtils.getNodeIndex( cell ), + temp = cell, + rows = table.rows, + colIndex = 0; + + while( temp ) { + //获取到当前单元格在未发生单元格合并时的序列 + if( temp.nodeType === 1 ) { + colIndex += (temp.colSpan || 1); + } + temp = temp.previousSibling; + } + + temp = null; + + //记录想关的单元格 + var borderCells = []; + + utils.each(rows, function( tabRow ){ + + var cells = tabRow.cells, + currIndex = 0; + + utils.each( cells, function( tabCell ){ + + currIndex += (tabCell.colSpan || 1); + + if( currIndex === colIndex ) { + + borderCells.push({ + left: tabCell, + right: tabCell.nextSibling || null + }); + + return false; + + } else if( currIndex > colIndex ) { + + if( isContainMergeCell ) { + borderCells.push({ + left: tabCell + }); + } + + return false; + } + + + } ); + + }); + + return borderCells; + + } + + + /** + * 通过给定的单元格集合获取最小的单元格width + */ + function getMinWidthByTableCells( cells ) { + + var minWidth = Number.MAX_VALUE; + + for( var i = 0, curCell; curCell = cells[ i ] ; i++ ) { + + minWidth = Math.min( minWidth, curCell.width || getTableCellWidth( curCell ) ); + + } + + return minWidth; + + } + + function correctChangeValue( changeValue, relatedCell, cells ) { + + //为单元格的paading预留空间 + changeValue -= getTabcellSpace(); + + if( changeValue < 0 ) { + return 0; + } + + changeValue -= getTableCellWidth( relatedCell ); + + //确定方向 + var direction = changeValue < 0 ? 'left':'right'; + + changeValue = Math.abs(changeValue); + + //只关心非最后一个单元格就可以 + utils.each( cells, function( cellGroup ){ + + var curCell = cellGroup[direction]; + + //为单元格保留最小空间 + if( curCell ) { + changeValue = Math.min( changeValue, getTableCellWidth( curCell )-cellMinWidth ); + } + + + } ); + + + //修正越界 + changeValue = changeValue < 0 ? 0 : changeValue; + + return direction === 'left' ? -changeValue : changeValue; + + } + + function getTableCellWidth( cell ) { + + var width = 0, + //偏移纠正量 + offset = 0, + width = cell.offsetWidth - getTabcellSpace(); + + //最后一个节点纠正一下 + if( !cell.nextSibling ) { + + width -= getTableCellOffset( cell ); + + } + + width = width < 0 ? 0 : width; + + try { + cell.width = width; + } catch(e) { + } + + return width; + + } + + /** + * 获取单元格所在表格的最末单元格的偏移量 + */ + function getTableCellOffset( cell ) { + + tab = domUtils.findParentByTagName( cell, "table", false); + + if( tab.offsetVal === undefined ) { + + var prev = cell.previousSibling; + + if( prev ) { + + //最后一个单元格和前一个单元格的width diff结果 如果恰好为一个border width, 则条件成立 + tab.offsetVal = cell.offsetWidth - prev.offsetWidth === UT.borderWidth ? UT.borderWidth : 0; + + } else { + tab.offsetVal = 0; + } + + } + + return tab.offsetVal; + + } + + function getTabcellSpace() { + + if( UT.tabcellSpace === undefined ) { + + var cell = null, + tab = me.document.createElement("table"), + tbody = me.document.createElement("tbody"), + trow = me.document.createElement("tr"), + tabcell = me.document.createElement("td"), + mirror = null; + + tabcell.style.cssText = 'border: 0;'; + tabcell.width = 1; + + trow.appendChild( tabcell ); + trow.appendChild( mirror = tabcell.cloneNode( false ) ); + + tbody.appendChild( trow ); + + tab.appendChild( tbody ); + + tab.style.cssText = "visibility: hidden;"; + + me.body.appendChild( tab ); + + UT.paddingSpace = tabcell.offsetWidth - 1; + + var tmpTabWidth = tab.offsetWidth; + + tabcell.style.cssText = ''; + mirror.style.cssText = ''; + + UT.borderWidth = ( tab.offsetWidth - tmpTabWidth ) / 3; + + UT.tabcellSpace = UT.paddingSpace + UT.borderWidth; + + me.body.removeChild( tab ); + + } + + getTabcellSpace = function(){ return UT.tabcellSpace; }; + + return UT.tabcellSpace; + + } + + function getDragLine(editor, doc) { + if (mousedown)return; + dragLine = editor.document.createElement("div"); + domUtils.setAttributes(dragLine, { + id:"ue_tableDragLine", + unselectable:'on', + contenteditable:false, + 'onresizestart':'return false', + 'ondragstart':'return false', + 'onselectstart':'return false', + style:"background-color:blue;position:absolute;padding:0;margin:0;background-image:none;border:0px none;opacity:0;filter:alpha(opacity=0)" + }); + editor.body.appendChild(dragLine); + } + + function hideDragLine(editor) { + if (mousedown)return; + var line; + while (line = editor.document.getElementById('ue_tableDragLine')) { + domUtils.remove(line) + } + } + + /** + * 依据state(v|h)在cell位置显示横线 + * @param state + * @param cell + */ + function showDragLineAt(state, cell) { + if (!cell) return; + var table = domUtils.findParentByTagName(cell, "table"), + caption = table.getElementsByTagName('caption'), + width = table.offsetWidth, + height = table.offsetHeight - (caption.length > 0 ? caption[0].offsetHeight : 0), + tablePos = domUtils.getXY(table), + cellPos = domUtils.getXY(cell), css; + switch (state) { + case "h": + css = 'height:' + height + 'px;top:' + (tablePos.y + (caption.length > 0 ? caption[0].offsetHeight : 0)) + 'px;left:' + (cellPos.x + cell.offsetWidth); + dragLine.style.cssText = css + 'px;position: absolute;display:block;background-color:blue;width:1px;border:0; color:blue;opacity:.3;filter:alpha(opacity=30)'; + break; + case "v": + css = 'width:' + width + 'px;left:' + tablePos.x + 'px;top:' + (cellPos.y + cell.offsetHeight ); + //必须加上border:0和color:blue,否则低版ie不支持背景色显示 + dragLine.style.cssText = css + 'px;overflow:hidden;position: absolute;display:block;background-color:blue;height:1px;border:0;color:blue;opacity:.2;filter:alpha(opacity=20)'; + break; + default: + } + } + + /** + * 当表格边框颜色为白色时设置为虚线,true为添加虚线 + * @param editor + * @param flag + */ + function switchBorderColor(editor, flag) { + var tableArr = domUtils.getElementsByTagName(editor.body, "table"), color; + for (var i = 0, node; node = tableArr[i++];) { + var td = domUtils.getElementsByTagName(node, "td"); + if (td[0]) { + if (flag) { + color = (td[0].style.borderColor).replace(/\s/g, ""); + if (/(#ffffff)|(rgb\(255,255,255\))/ig.test(color)) + domUtils.addClass(node, "noBorderTable") + } else { + domUtils.removeClasses(node, "noBorderTable") + } + } + + } + } + + function getTableWidth(editor, needIEHack, defaultValue) { + var body = editor.body; + return body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (editor.options.offsetWidth || 0); + } + + /** + * 获取当前拖动的单元格 + */ + function getTargetTd(editor, evt) { + + var target = domUtils.findParentByTagName(evt.target || evt.srcElement, ["td", "th"], true), + dir = null; + + if( !target ) { + return null; + } + + dir = getRelation( target, mouseCoords( evt ) ); + + //如果有前一个节点, 需要做一个修正, 否则可能会得到一个错误的td + + if( !target ) { + return null; + } + + if( dir === 'h1' && target.previousSibling ) { + + var position = domUtils.getXY( target), + cellWidth = target.offsetWidth; + + if( Math.abs( position.x + cellWidth - evt.clientX ) > cellWidth / 3 ) { + target = target.previousSibling; + } + + } else if( dir === 'v1' && target.parentNode.previousSibling ) { + + var position = domUtils.getXY( target), + cellHeight = target.offsetHeight; + + if( Math.abs( position.y + cellHeight - evt.clientY ) > cellHeight / 3 ) { + target = target.parentNode.previousSibling.firstChild; + } + + } + + + //排除了非td内部以及用于代码高亮部分的td + return target && !(editor.fireEvent("excludetable", target) === true) ? target : null; + } + +}; + + +// plugins/table.sort.js +/** + * Created with JetBrains PhpStorm. + * User: Jinqn + * Date: 13-10-12 + * Time: 上午10:20 + * To change this template use File | Settings | File Templates. + */ + +UE.UETable.prototype.sortTable = function (sortByCellIndex, compareFn) { + var table = this.table, + rows = table.rows, + trArray = [], + flag = rows[0].cells[0].tagName === "TH", + lastRowIndex = 0; + if(this.selectedTds.length){ + var range = this.cellsRange, + len = range.endRowIndex + 1; + for (var i = range.beginRowIndex; i < len; i++) { + trArray[i] = rows[i]; + } + trArray.splice(0,range.beginRowIndex); + lastRowIndex = (range.endRowIndex +1) === this.rowsNum ? 0 : range.endRowIndex +1; + }else{ + for (var i = 0,len = rows.length; i < len; i++) { + trArray[i] = rows[i]; + } + } + + var Fn = { + 'reversecurrent': function(td1,td2){ + return 1; + }, + 'orderbyasc': function(td1,td2){ + var value1 = td1.innerText||td1.textContent, + value2 = td2.innerText||td2.textContent; + return value1.localeCompare(value2); + }, + 'reversebyasc': function(td1,td2){ + var value1 = td1.innerHTML, + value2 = td2.innerHTML; + return value2.localeCompare(value1); + }, + 'orderbynum': function(td1,td2){ + var value1 = td1[browser.ie ? 'innerText':'textContent'].match(/\d+/), + value2 = td2[browser.ie ? 'innerText':'textContent'].match(/\d+/); + if(value1) value1 = +value1[0]; + if(value2) value2 = +value2[0]; + return (value1||0) - (value2||0); + }, + 'reversebynum': function(td1,td2){ + var value1 = td1[browser.ie ? 'innerText':'textContent'].match(/\d+/), + value2 = td2[browser.ie ? 'innerText':'textContent'].match(/\d+/); + if(value1) value1 = +value1[0]; + if(value2) value2 = +value2[0]; + return (value2||0) - (value1||0); + } + }; + + //对表格设置排序的标记data-sort-type + table.setAttribute('data-sort-type', compareFn && typeof compareFn === "string" && Fn[compareFn] ? compareFn:''); + + //th不参与排序 + flag && trArray.splice(0, 1); + trArray = utils.sort(trArray,function (tr1, tr2) { + var result; + if (compareFn && typeof compareFn === "function") { + result = compareFn.call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]); + } else if (compareFn && typeof compareFn === "number") { + result = 1; + } else if (compareFn && typeof compareFn === "string" && Fn[compareFn]) { + result = Fn[compareFn].call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]); + } else { + result = Fn['orderbyasc'].call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]); + } + return result; + }); + var fragment = table.ownerDocument.createDocumentFragment(); + for (var j = 0, len = trArray.length; j < len; j++) { + fragment.appendChild(trArray[j]); + } + var tbody = table.getElementsByTagName("tbody")[0]; + if(!lastRowIndex){ + tbody.appendChild(fragment); + }else{ + tbody.insertBefore(fragment,rows[lastRowIndex- range.endRowIndex + range.beginRowIndex - 1]) + } +}; + +UE.plugins['tablesort'] = function () { + var me = this, + UT = UE.UETable, + getUETable = function (tdOrTable) { + return UT.getUETable(tdOrTable); + }, + getTableItemsByRange = function (editor) { + return UT.getTableItemsByRange(editor); + }; + + + me.ready(function () { + //添加表格可排序的样式 + utils.cssRule('tablesort', + 'table.sortEnabled tr.firstRow th,table.sortEnabled tr.firstRow td{padding-right:20px;background-repeat: no-repeat;background-position: center right;' + + ' background-image:url(' + me.options.themePath + me.options.theme + '/images/sortable.png);}', + me.document); + + //做单元格合并操作时,清除可排序标识 + me.addListener("afterexeccommand", function (type, cmd) { + if( cmd == 'mergeright' || cmd == 'mergedown' || cmd == 'mergecells') { + this.execCommand('disablesort'); + } + }); + }); + + + + //表格排序 + UE.commands['sorttable'] = { + queryCommandState: function () { + var me = this, + tableItems = getTableItemsByRange(me); + if (!tableItems.cell) return -1; + var table = tableItems.table, + cells = table.getElementsByTagName("td"); + for (var i = 0, cell; cell = cells[i++];) { + if (cell.rowSpan != 1 || cell.colSpan != 1) return -1; + } + return 0; + }, + execCommand: function (cmd, fn) { + var me = this, + range = me.selection.getRange(), + bk = range.createBookmark(true), + tableItems = getTableItemsByRange(me), + cell = tableItems.cell, + ut = getUETable(tableItems.table), + cellInfo = ut.getCellInfo(cell); + ut.sortTable(cellInfo.cellIndex, fn); + range.moveToBookmark(bk); + try{ + range.select(); + }catch(e){} + } + }; + + //设置表格可排序,清除表格可排序 + UE.commands["enablesort"] = UE.commands["disablesort"] = { + queryCommandState: function (cmd) { + var table = getTableItemsByRange(this).table; + if(table && cmd=='enablesort') { + var cells = domUtils.getElementsByTagName(table, 'th td'); + for(var i = 0; i1 || cells[i].getAttribute('rowspan')>1) return -1; + } + } + + return !table ? -1: cmd=='enablesort' ^ table.getAttribute('data-sort')!='sortEnabled' ? -1:0; + }, + execCommand: function (cmd) { + var table = getTableItemsByRange(this).table; + table.setAttribute("data-sort", cmd == "enablesort" ? "sortEnabled" : "sortDisabled"); + cmd == "enablesort" ? domUtils.addClass(table,"sortEnabled"):domUtils.removeClasses(table,"sortEnabled"); + } + }; +}; + + +// plugins/contextmenu.js +///import core +///commands 右键菜单 +///commandsName ContextMenu +///commandsTitle 右键菜单 +/** + * 右键菜单 + * @function + * @name baidu.editor.plugins.contextmenu + * @author zhanyi + */ + +UE.plugins['contextmenu'] = function () { + var me = this; + me.setOpt('enableContextMenu',true); + if(me.getOpt('enableContextMenu') === false){ + return; + } + var lang = me.getLang( "contextMenu" ), + menu, + items = me.options.contextMenu || [ + {label:lang['selectall'], cmdName:'selectall'}, + { + label:lang.cleardoc, + cmdName:'cleardoc', + exec:function () { + if ( confirm( lang.confirmclear ) ) { + this.execCommand( 'cleardoc' ); + } + } + }, + '-', + { + label:lang.unlink, + cmdName:'unlink' + }, + '-', + { + group:lang.paragraph, + icon:'justifyjustify', + subMenu:[ + { + label:lang.justifyleft, + cmdName:'justify', + value:'left' + }, + { + label:lang.justifyright, + cmdName:'justify', + value:'right' + }, + { + label:lang.justifycenter, + cmdName:'justify', + value:'center' + }, + { + label:lang.justifyjustify, + cmdName:'justify', + value:'justify' + } + ] + }, + '-', + { + group:lang.table, + icon:'table', + subMenu:[ + { + label:lang.inserttable, + cmdName:'inserttable' + }, + { + label:lang.deletetable, + cmdName:'deletetable' + }, + '-', + { + label:lang.deleterow, + cmdName:'deleterow' + }, + { + label:lang.deletecol, + cmdName:'deletecol' + }, + { + label:lang.insertcol, + cmdName:'insertcol' + }, + { + label:lang.insertcolnext, + cmdName:'insertcolnext' + }, + { + label:lang.insertrow, + cmdName:'insertrow' + }, + { + label:lang.insertrownext, + cmdName:'insertrownext' + }, + '-', + { + label:lang.insertcaption, + cmdName:'insertcaption' + }, + { + label:lang.deletecaption, + cmdName:'deletecaption' + }, + { + label:lang.inserttitle, + cmdName:'inserttitle' + }, + { + label:lang.deletetitle, + cmdName:'deletetitle' + }, + { + label:lang.inserttitlecol, + cmdName:'inserttitlecol' + }, + { + label:lang.deletetitlecol, + cmdName:'deletetitlecol' + }, + '-', + { + label:lang.mergecells, + cmdName:'mergecells' + }, + { + label:lang.mergeright, + cmdName:'mergeright' + }, + { + label:lang.mergedown, + cmdName:'mergedown' + }, + '-', + { + label:lang.splittorows, + cmdName:'splittorows' + }, + { + label:lang.splittocols, + cmdName:'splittocols' + }, + { + label:lang.splittocells, + cmdName:'splittocells' + }, + '-', + { + label:lang.averageDiseRow, + cmdName:'averagedistributerow' + }, + { + label:lang.averageDisCol, + cmdName:'averagedistributecol' + }, + '-', + { + label:lang.edittd, + cmdName:'edittd', + exec:function () { + if ( UE.ui['edittd'] ) { + new UE.ui['edittd']( this ); + } + this.getDialog('edittd').open(); + } + }, + { + label:lang.edittable, + cmdName:'edittable', + exec:function () { + if ( UE.ui['edittable'] ) { + new UE.ui['edittable']( this ); + } + this.getDialog('edittable').open(); + } + }, + { + label:lang.setbordervisible, + cmdName:'setbordervisible' + } + ] + }, + { + group:lang.tablesort, + icon:'tablesort', + subMenu:[ + { + label:lang.enablesort, + cmdName:'enablesort' + }, + { + label:lang.disablesort, + cmdName:'disablesort' + }, + '-', + { + label:lang.reversecurrent, + cmdName:'sorttable', + value:'reversecurrent' + }, + { + label:lang.orderbyasc, + cmdName:'sorttable', + value:'orderbyasc' + }, + { + label:lang.reversebyasc, + cmdName:'sorttable', + value:'reversebyasc' + }, + { + label:lang.orderbynum, + cmdName:'sorttable', + value:'orderbynum' + }, + { + label:lang.reversebynum, + cmdName:'sorttable', + value:'reversebynum' + } + ] + }, + { + group:lang.borderbk, + icon:'borderBack', + subMenu:[ + { + label:lang.setcolor, + cmdName:"interlacetable", + exec:function(){ + this.execCommand("interlacetable"); + } + }, + { + label:lang.unsetcolor, + cmdName:"uninterlacetable", + exec:function(){ + this.execCommand("uninterlacetable"); + } + }, + { + label:lang.setbackground, + cmdName:"settablebackground", + exec:function(){ + this.execCommand("settablebackground",{repeat:true,colorList:["#bbb","#ccc"]}); + } + }, + { + label:lang.unsetbackground, + cmdName:"cleartablebackground", + exec:function(){ + this.execCommand("cleartablebackground"); + } + }, + { + label:lang.redandblue, + cmdName:"settablebackground", + exec:function(){ + this.execCommand("settablebackground",{repeat:true,colorList:["red","blue"]}); + } + }, + { + label:lang.threecolorgradient, + cmdName:"settablebackground", + exec:function(){ + this.execCommand("settablebackground",{repeat:true,colorList:["#aaa","#bbb","#ccc"]}); + } + } + ] + }, + { + group:lang.aligntd, + icon:'aligntd', + subMenu:[ + { + cmdName:'cellalignment', + value:{align:'left',vAlign:'top'} + }, + { + cmdName:'cellalignment', + value:{align:'center',vAlign:'top'} + }, + { + cmdName:'cellalignment', + value:{align:'right',vAlign:'top'} + }, + { + cmdName:'cellalignment', + value:{align:'left',vAlign:'middle'} + }, + { + cmdName:'cellalignment', + value:{align:'center',vAlign:'middle'} + }, + { + cmdName:'cellalignment', + value:{align:'right',vAlign:'middle'} + }, + { + cmdName:'cellalignment', + value:{align:'left',vAlign:'bottom'} + }, + { + cmdName:'cellalignment', + value:{align:'center',vAlign:'bottom'} + }, + { + cmdName:'cellalignment', + value:{align:'right',vAlign:'bottom'} + } + ] + }, + { + group:lang.aligntable, + icon:'aligntable', + subMenu:[ + { + cmdName:'tablealignment', + className: 'left', + label:lang.tableleft, + value:"left" + }, + { + cmdName:'tablealignment', + className: 'center', + label:lang.tablecenter, + value:"center" + }, + { + cmdName:'tablealignment', + className: 'right', + label:lang.tableright, + value:"right" + } + ] + }, + '-', + { + label:lang.insertparagraphbefore, + cmdName:'insertparagraph', + value:true + }, + { + label:lang.insertparagraphafter, + cmdName:'insertparagraph' + }, + { + label:lang['copy'], + cmdName:'copy' + }, + { + label:lang['paste'], + cmdName:'paste' + } + ]; + if ( !items.length ) { + return; + } + var uiUtils = UE.ui.uiUtils; + + me.addListener( 'contextmenu', function ( type, evt ) { + + var offset = uiUtils.getViewportOffsetByEvent( evt ); + me.fireEvent( 'beforeselectionchange' ); + if ( menu ) { + menu.destroy(); + } + for ( var i = 0, ti, contextItems = []; ti = items[i]; i++ ) { + var last; + (function ( item ) { + if ( item == '-' ) { + if ( (last = contextItems[contextItems.length - 1 ] ) && last !== '-' ) { + contextItems.push( '-' ); + } + } else if ( item.hasOwnProperty( "group" ) ) { + for ( var j = 0, cj, subMenu = []; cj = item.subMenu[j]; j++ ) { + (function ( subItem ) { + if ( subItem == '-' ) { + if ( (last = subMenu[subMenu.length - 1 ] ) && last !== '-' ) { + subMenu.push( '-' ); + }else{ + subMenu.splice(subMenu.length-1); + } + } else { + if ( (me.commands[subItem.cmdName] || UE.commands[subItem.cmdName] || subItem.query) && + (subItem.query ? subItem.query() : me.queryCommandState( subItem.cmdName )) > -1 ) { + subMenu.push( { + 'label':subItem.label || me.getLang( "contextMenu." + subItem.cmdName + (subItem.value || '') )||"", + 'className':'edui-for-' +subItem.cmdName + ( subItem.className ? ( ' edui-for-' + subItem.cmdName + '-' + subItem.className ) : '' ), + onclick:subItem.exec ? function () { + subItem.exec.call( me ); + } : function () { + me.execCommand( subItem.cmdName, subItem.value ); + } + } ); + } + } + })( cj ); + } + if ( subMenu.length ) { + function getLabel(){ + switch (item.icon){ + case "table": + return me.getLang( "contextMenu.table" ); + case "justifyjustify": + return me.getLang( "contextMenu.paragraph" ); + case "aligntd": + return me.getLang("contextMenu.aligntd"); + case "aligntable": + return me.getLang("contextMenu.aligntable"); + case "tablesort": + return lang.tablesort; + case "borderBack": + return lang.borderbk; + default : + return ''; + } + } + contextItems.push( { + //todo 修正成自动获取方式 + 'label':getLabel(), + className:'edui-for-' + item.icon, + 'subMenu':{ + items:subMenu, + editor:me + } + } ); + } + + } else { + //有可能commmand没有加载右键不能出来,或者没有command也想能展示出来添加query方法 + if ( (me.commands[item.cmdName] || UE.commands[item.cmdName] || item.query) && + (item.query ? item.query.call(me) : me.queryCommandState( item.cmdName )) > -1 ) { + + contextItems.push( { + 'label':item.label || me.getLang( "contextMenu." + item.cmdName ), + className:'edui-for-' + (item.icon ? item.icon : item.cmdName + (item.value || '')), + onclick:item.exec ? function () { + item.exec.call( me ); + } : function () { + me.execCommand( item.cmdName, item.value ); + } + } ); + } + + } + + })( ti ); + } + if ( contextItems[contextItems.length - 1] == '-' ) { + contextItems.pop(); + } + + menu = new UE.ui.Menu( { + items:contextItems, + className:"edui-contextmenu", + editor:me + } ); + menu.render(); + menu.showAt( offset ); + + me.fireEvent("aftershowcontextmenu",menu); + + domUtils.preventDefault( evt ); + if ( browser.ie ) { + var ieRange; + try { + ieRange = me.selection.getNative().createRange(); + } catch ( e ) { + return; + } + if ( ieRange.item ) { + var range = new dom.Range( me.document ); + range.selectNode( ieRange.item( 0 ) ).select( true, true ); + } + } + }); + + // 添加复制的flash按钮 + me.addListener('aftershowcontextmenu', function(type, menu) { + if (me.zeroclipboard) { + var items = menu.items; + for (var key in items) { + if (items[key].className == 'edui-for-copy') { + me.zeroclipboard.clip(items[key].getDom()); + } + } + } + }); + +}; + + +// plugins/shortcutmenu.js +///import core +///commands 弹出菜单 +// commandsName popupmenu +///commandsTitle 弹出菜单 +/** + * 弹出菜单 + * @function + * @name baidu.editor.plugins.popupmenu + * @author xuheng + */ + +UE.plugins['shortcutmenu'] = function () { + var me = this, + menu, + items = me.options.shortcutMenu || []; + + if (!items.length) { + return; + } + + me.addListener ('contextmenu mouseup' , function (type , e) { + var me = this, + customEvt = { + type : type , + target : e.target || e.srcElement , + screenX : e.screenX , + screenY : e.screenY , + clientX : e.clientX , + clientY : e.clientY + }; + + setTimeout (function () { + var rng = me.selection.getRange (); + if (rng.collapsed === false || type == "contextmenu") { + + if (!menu) { + menu = new baidu.editor.ui.ShortCutMenu ({ + editor : me , + items : items , + theme : me.options.theme , + className : 'edui-shortcutmenu' + }); + + menu.render (); + me.fireEvent ("afterrendershortcutmenu" , menu); + } + + menu.show (customEvt , !!UE.plugins['contextmenu']); + } + }); + + if (type == 'contextmenu') { + domUtils.preventDefault (e); + if (browser.ie9below) { + var ieRange; + try { + ieRange = me.selection.getNative().createRange(); + } catch (e) { + return; + } + if (ieRange.item) { + var range = new dom.Range (me.document); + range.selectNode (ieRange.item (0)).select (true , true); + + } + } + } + }); + + me.addListener ('keydown' , function (type) { + if (type == "keydown") { + menu && !menu.isHidden && menu.hide (); + } + + }); + +}; + + + + +// plugins/basestyle.js +/** + * B、I、sub、super命令支持 + * @file + * @since 1.2.6.1 + */ + +UE.plugins['basestyle'] = function(){ + + /** + * 字体加粗 + * @command bold + * @param { String } cmd 命令字符串 + * @remind 对已加粗的文本内容执行该命令, 将取消加粗 + * @method execCommand + * @example + * ```javascript + * //editor是编辑器实例 + * //对当前选中的文本内容执行加粗操作 + * //第一次执行, 文本内容加粗 + * editor.execCommand( 'bold' ); + * + * //第二次执行, 文本内容取消加粗 + * editor.execCommand( 'bold' ); + * ``` + */ + + + /** + * 字体倾斜 + * @command italic + * @method execCommand + * @param { String } cmd 命令字符串 + * @remind 对已倾斜的文本内容执行该命令, 将取消倾斜 + * @example + * ```javascript + * //editor是编辑器实例 + * //对当前选中的文本内容执行斜体操作 + * //第一次操作, 文本内容将变成斜体 + * editor.execCommand( 'italic' ); + * + * //再次对同一文本内容执行, 则文本内容将恢复正常 + * editor.execCommand( 'italic' ); + * ``` + */ + + /** + * 下标文本,与“superscript”命令互斥 + * @command subscript + * @method execCommand + * @remind 把选中的文本内容切换成下标文本, 如果当前选中的文本已经是下标, 则该操作会把文本内容还原成正常文本 + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * //editor是编辑器实例 + * //对当前选中的文本内容执行下标操作 + * //第一次操作, 文本内容将变成下标文本 + * editor.execCommand( 'subscript' ); + * + * //再次对同一文本内容执行, 则文本内容将恢复正常 + * editor.execCommand( 'subscript' ); + * ``` + */ + + /** + * 上标文本,与“subscript”命令互斥 + * @command superscript + * @method execCommand + * @remind 把选中的文本内容切换成上标文本, 如果当前选中的文本已经是上标, 则该操作会把文本内容还原成正常文本 + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * //editor是编辑器实例 + * //对当前选中的文本内容执行上标操作 + * //第一次操作, 文本内容将变成上标文本 + * editor.execCommand( 'superscript' ); + * + * //再次对同一文本内容执行, 则文本内容将恢复正常 + * editor.execCommand( 'superscript' ); + * ``` + */ + var basestyles = { + 'bold':['strong','b'], + 'italic':['em','i'], + 'subscript':['sub'], + 'superscript':['sup'] + }, + getObj = function(editor,tagNames){ + return domUtils.filterNodeList(editor.selection.getStartElementPath(),tagNames); + }, + me = this; + //添加快捷键 + me.addshortcutkey({ + "Bold" : "ctrl+66",//^B + "Italic" : "ctrl+73", //^I + "Underline" : "ctrl+85"//^U + }); + me.addInputRule(function(root){ + utils.each(root.getNodesByTagName('b i'),function(node){ + switch (node.tagName){ + case 'b': + node.tagName = 'strong'; + break; + case 'i': + node.tagName = 'em'; + } + }); + }); + for ( var style in basestyles ) { + (function( cmd, tagNames ) { + me.commands[cmd] = { + execCommand : function( cmdName ) { + var range = me.selection.getRange(),obj = getObj(this,tagNames); + if ( range.collapsed ) { + if ( obj ) { + var tmpText = me.document.createTextNode(''); + range.insertNode( tmpText ).removeInlineStyle( tagNames ); + range.setStartBefore(tmpText); + domUtils.remove(tmpText); + } else { + var tmpNode = range.document.createElement( tagNames[0] ); + if(cmdName == 'superscript' || cmdName == 'subscript'){ + tmpText = me.document.createTextNode(''); + range.insertNode(tmpText) + .removeInlineStyle(['sub','sup']) + .setStartBefore(tmpText) + .collapse(true); + } + range.insertNode( tmpNode ).setStart( tmpNode, 0 ); + } + range.collapse( true ); + } else { + if(cmdName == 'superscript' || cmdName == 'subscript'){ + if(!obj || obj.tagName.toLowerCase() != cmdName){ + range.removeInlineStyle(['sub','sup']); + } + } + obj ? range.removeInlineStyle( tagNames ) : range.applyInlineStyle( tagNames[0] ); + } + range.select(); + }, + queryCommandState : function() { + return getObj(this,tagNames) ? 1 : 0; + } + }; + })( style, basestyles[style] ); + } +}; + + + +// plugins/elementpath.js +/** + * 选取路径命令 + * @file + */ +UE.plugins['elementpath'] = function(){ + var currentLevel, + tagNames, + me = this; + me.setOpt('elementPathEnabled',true); + if(!me.options.elementPathEnabled){ + return; + } + me.commands['elementpath'] = { + execCommand : function( cmdName, level ) { + var start = tagNames[level], + range = me.selection.getRange(); + currentLevel = level*1; + range.selectNode(start).select(); + }, + queryCommandValue : function() { + //产生一个副本,不能修改原来的startElementPath; + var parents = [].concat(this.selection.getStartElementPath()).reverse(), + names = []; + tagNames = parents; + for(var i=0,ci;ci=parents[i];i++){ + if(ci.nodeType == 3) { + continue; + } + var name = ci.tagName.toLowerCase(); + if(name == 'img' && ci.getAttribute('anchorname')){ + name = 'anchor'; + } + names[i] = name; + if(currentLevel == i){ + currentLevel = -1; + break; + } + } + return names; + } + }; +}; + + + +// plugins/formatmatch.js +/** + * 格式刷,只格式inline的 + * @file + * @since 1.2.6.1 + */ + +/** + * 格式刷 + * @command formatmatch + * @method execCommand + * @remind 该操作不能复制段落格式 + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * //editor是编辑器实例 + * //获取格式刷 + * editor.execCommand( 'formatmatch' ); + * ``` + */ +UE.plugins['formatmatch'] = function(){ + + var me = this, + list = [],img, + flag = 0; + + me.addListener('reset',function(){ + list = []; + flag = 0; + }); + + function addList(type,evt){ + + if(browser.webkit){ + var target = evt.target.tagName == 'IMG' ? evt.target : null; + } + + function addFormat(range){ + + if(text){ + range.selectNode(text); + } + return range.applyInlineStyle(list[list.length-1].tagName,null,list); + + } + + me.undoManger && me.undoManger.save(); + + var range = me.selection.getRange(), + imgT = target || range.getClosedNode(); + if(img && imgT && imgT.tagName == 'IMG'){ + //trace:964 + + imgT.style.cssText += ';float:' + (img.style.cssFloat || img.style.styleFloat ||'none') + ';display:' + (img.style.display||'inline'); + + img = null; + }else{ + if(!img){ + var collapsed = range.collapsed; + if(collapsed){ + var text = me.document.createTextNode('match'); + range.insertNode(text).select(); + + + } + me.__hasEnterExecCommand = true; + //不能把block上的属性干掉 + //trace:1553 + var removeFormatAttributes = me.options.removeFormatAttributes; + me.options.removeFormatAttributes = ''; + me.execCommand('removeformat'); + me.options.removeFormatAttributes = removeFormatAttributes; + me.__hasEnterExecCommand = false; + //trace:969 + range = me.selection.getRange(); + if(list.length){ + addFormat(range); + } + if(text){ + range.setStartBefore(text).collapse(true); + + } + range.select(); + text && domUtils.remove(text); + } + + } + + + + + me.undoManger && me.undoManger.save(); + me.removeListener('mouseup',addList); + flag = 0; + } + + me.commands['formatmatch'] = { + execCommand : function( cmdName ) { + + if(flag){ + flag = 0; + list = []; + me.removeListener('mouseup',addList); + return; + } + + + + var range = me.selection.getRange(); + img = range.getClosedNode(); + if(!img || img.tagName != 'IMG'){ + range.collapse(true).shrinkBoundary(); + var start = range.startContainer; + list = domUtils.findParents(start,true,function(node){ + return !domUtils.isBlockElm(node) && node.nodeType == 1; + }); + //a不能加入格式刷, 并且克隆节点 + for(var i=0,ci;ci=list[i];i++){ + if(ci.tagName == 'A'){ + list.splice(i,1); + break; + } + } + + } + + me.addListener('mouseup',addList); + flag = 1; + + + }, + queryCommandState : function() { + return flag; + }, + notNeedUndo : 1 + }; +}; + + + +// plugins/searchreplace.js +///import core +///commands 查找替换 +///commandsName SearchReplace +///commandsTitle 查询替换 +///commandsDialog dialogs\searchreplace +/** + * @description 查找替换 + * @author zhanyi + */ + +UE.plugin.register('searchreplace',function(){ + var me = this; + + var _blockElm = {'table':1,'tbody':1,'tr':1,'ol':1,'ul':1}; + + function findTextInString(textContent,opt,currentIndex){ + var str = opt.searchStr; + if(opt.dir == -1){ + textContent = textContent.split('').reverse().join(''); + str = str.split('').reverse().join(''); + currentIndex = textContent.length - currentIndex; + + } + var reg = new RegExp(str,'g' + (opt.casesensitive ? '' : 'i')),match; + + while(match = reg.exec(textContent)){ + if(match.index >= currentIndex){ + return opt.dir == -1 ? textContent.length - match.index - opt.searchStr.length : match.index; + } + } + return -1 + } + function findTextBlockElm(node,currentIndex,opt){ + var textContent,index,methodName = opt.all || opt.dir == 1 ? 'getNextDomNode' : 'getPreDomNode'; + if(domUtils.isBody(node)){ + node = node.firstChild; + } + var first = 1; + while(node){ + textContent = node.nodeType == 3 ? node.nodeValue : node[browser.ie ? 'innerText' : 'textContent']; + index = findTextInString(textContent,opt,currentIndex ); + first = 0; + if(index!=-1){ + return { + 'node':node, + 'index':index + } + } + node = domUtils[methodName](node); + while(node && _blockElm[node.nodeName.toLowerCase()]){ + node = domUtils[methodName](node,true); + } + if(node){ + currentIndex = opt.dir == -1 ? (node.nodeType == 3 ? node.nodeValue : node[browser.ie ? 'innerText' : 'textContent']).length : 0; + } + + } + } + function findNTextInBlockElm(node,index,str){ + var currentIndex = 0, + currentNode = node.firstChild, + currentNodeLength = 0, + result; + while(currentNode){ + if(currentNode.nodeType == 3){ + currentNodeLength = currentNode.nodeValue.replace(/(^[\t\r\n]+)|([\t\r\n]+$)/,'').length; + currentIndex += currentNodeLength; + if(currentIndex >= index){ + return { + 'node':currentNode, + 'index': currentNodeLength - (currentIndex - index) + } + } + }else if(!dtd.$empty[currentNode.tagName]){ + currentNodeLength = currentNode[browser.ie ? 'innerText' : 'textContent'].replace(/(^[\t\r\n]+)|([\t\r\n]+$)/,'').length + currentIndex += currentNodeLength; + if(currentIndex >= index){ + result = findNTextInBlockElm(currentNode,currentNodeLength - (currentIndex - index),str); + if(result){ + return result; + } + } + } + currentNode = domUtils.getNextDomNode(currentNode); + + } + } + + function searchReplace(me,opt){ + + var rng = me.selection.getRange(), + startBlockNode, + searchStr = opt.searchStr, + span = me.document.createElement('span'); + span.innerHTML = '$$ueditor_searchreplace_key$$'; + + rng.shrinkBoundary(true); + + //判断是不是第一次选中 + if(!rng.collapsed){ + rng.select(); + var rngText = me.selection.getText(); + if(new RegExp('^' + opt.searchStr + '$',(opt.casesensitive ? '' : 'i')).test(rngText)){ + if(opt.replaceStr != undefined){ + replaceText(rng,opt.replaceStr); + rng.select(); + return true; + }else{ + rng.collapse(opt.dir == -1) + } + + } + } + + + rng.insertNode(span); + rng.enlargeToBlockElm(true); + startBlockNode = rng.startContainer; + var currentIndex = startBlockNode[browser.ie ? 'innerText' : 'textContent'].indexOf('$$ueditor_searchreplace_key$$'); + rng.setStartBefore(span); + domUtils.remove(span); + var result = findTextBlockElm(startBlockNode,currentIndex,opt); + if(result){ + var rngStart = findNTextInBlockElm(result.node,result.index,searchStr); + var rngEnd = findNTextInBlockElm(result.node,result.index + searchStr.length,searchStr); + rng.setStart(rngStart.node,rngStart.index).setEnd(rngEnd.node,rngEnd.index); + + if(opt.replaceStr !== undefined){ + replaceText(rng,opt.replaceStr) + } + rng.select(); + return true; + }else{ + rng.setCursor() + } + + } + function replaceText(rng,str){ + + str = me.document.createTextNode(str); + rng.deleteContents().insertNode(str); + + } + return { + commands:{ + 'searchreplace':{ + execCommand:function(cmdName,opt){ + utils.extend(opt,{ + all : false, + casesensitive : false, + dir : 1 + },true); + var num = 0; + if(opt.all){ + + var rng = me.selection.getRange(), + first = me.body.firstChild; + if(first && first.nodeType == 1){ + rng.setStart(first,0); + rng.shrinkBoundary(true); + }else if(first.nodeType == 3){ + rng.setStartBefore(first) + } + rng.collapse(true).select(true); + if(opt.replaceStr !== undefined){ + me.fireEvent('saveScene'); + } + while(searchReplace(this,opt)){ + num++; + } + if(num){ + me.fireEvent('saveScene'); + } + }else{ + if(opt.replaceStr !== undefined){ + me.fireEvent('saveScene'); + } + if(searchReplace(this,opt)){ + num++ + } + if(num){ + me.fireEvent('saveScene'); + } + + } + + return num; + }, + notNeedUndo:1 + } + } + } +}); + +// plugins/customstyle.js +/** + * 自定义样式 + * @file + * @since 1.2.6.1 + */ + +/** + * 根据config配置文件里“customstyle”选项的值对匹配的标签执行样式替换。 + * @command customstyle + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand( 'customstyle' ); + * ``` + */ +UE.plugins['customstyle'] = function() { + var me = this; + me.setOpt({ 'customstyle':[ + {tag:'h1',name:'tc', style:'font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:center;margin:0 0 20px 0;'}, + {tag:'h1',name:'tl', style:'font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:left;margin:0 0 10px 0;'}, + {tag:'span',name:'im', style:'font-size:16px;font-style:italic;font-weight:bold;line-height:18px;'}, + {tag:'span',name:'hi', style:'font-size:16px;font-style:italic;font-weight:bold;color:rgb(51, 153, 204);line-height:18px;'} + ]}); + me.commands['customstyle'] = { + execCommand : function(cmdName, obj) { + var me = this, + tagName = obj.tag, + node = domUtils.findParent(me.selection.getStart(), function(node) { + return node.getAttribute('label'); + }, true), + range,bk,tmpObj = {}; + for (var p in obj) { + if(obj[p]!==undefined) + tmpObj[p] = obj[p]; + } + delete tmpObj.tag; + if (node && node.getAttribute('label') == obj.label) { + range = this.selection.getRange(); + bk = range.createBookmark(); + if (range.collapsed) { + //trace:1732 删掉自定义标签,要有p来回填站位 + if(dtd.$block[node.tagName]){ + var fillNode = me.document.createElement('p'); + domUtils.moveChild(node, fillNode); + node.parentNode.insertBefore(fillNode, node); + domUtils.remove(node); + }else{ + domUtils.remove(node,true); + } + + } else { + + var common = domUtils.getCommonAncestor(bk.start, bk.end), + nodes = domUtils.getElementsByTagName(common, tagName); + if(new RegExp(tagName,'i').test(common.tagName)){ + nodes.push(common); + } + for (var i = 0,ni; ni = nodes[i++];) { + if (ni.getAttribute('label') == obj.label) { + var ps = domUtils.getPosition(ni, bk.start),pe = domUtils.getPosition(ni, bk.end); + if ((ps & domUtils.POSITION_FOLLOWING || ps & domUtils.POSITION_CONTAINS) + && + (pe & domUtils.POSITION_PRECEDING || pe & domUtils.POSITION_CONTAINS) + ) + if (dtd.$block[tagName]) { + var fillNode = me.document.createElement('p'); + domUtils.moveChild(ni, fillNode); + ni.parentNode.insertBefore(fillNode, ni); + } + domUtils.remove(ni, true); + } + } + node = domUtils.findParent(common, function(node) { + return node.getAttribute('label') == obj.label; + }, true); + if (node) { + + domUtils.remove(node, true); + + } + + } + range.moveToBookmark(bk).select(); + } else { + if (dtd.$block[tagName]) { + this.execCommand('paragraph', tagName, tmpObj,'customstyle'); + range = me.selection.getRange(); + if (!range.collapsed) { + range.collapse(); + node = domUtils.findParent(me.selection.getStart(), function(node) { + return node.getAttribute('label') == obj.label; + }, true); + var pNode = me.document.createElement('p'); + domUtils.insertAfter(node, pNode); + domUtils.fillNode(me.document, pNode); + range.setStart(pNode, 0).setCursor(); + } + } else { + + range = me.selection.getRange(); + if (range.collapsed) { + node = me.document.createElement(tagName); + domUtils.setAttributes(node, tmpObj); + range.insertNode(node).setStart(node, 0).setCursor(); + + return; + } + + bk = range.createBookmark(); + range.applyInlineStyle(tagName, tmpObj).moveToBookmark(bk).select(); + } + } + + }, + queryCommandValue : function() { + var parent = domUtils.filterNodeList( + this.selection.getStartElementPath(), + function(node){return node.getAttribute('label')} + ); + return parent ? parent.getAttribute('label') : ''; + } + }; + //当去掉customstyle是,如果是块元素,用p代替 + me.addListener('keyup', function(type, evt) { + var keyCode = evt.keyCode || evt.which; + + if (keyCode == 32 || keyCode == 13) { + var range = me.selection.getRange(); + if (range.collapsed) { + var node = domUtils.findParent(me.selection.getStart(), function(node) { + return node.getAttribute('label'); + }, true); + if (node && dtd.$block[node.tagName] && domUtils.isEmptyNode(node)) { + var p = me.document.createElement('p'); + domUtils.insertAfter(node, p); + domUtils.fillNode(me.document, p); + domUtils.remove(node); + range.setStart(p, 0).setCursor(); + + + } + } + } + }); +}; + +// plugins/catchremoteimage.js +///import core +///commands 远程图片抓取 +///commandsName catchRemoteImage,catchremoteimageenable +///commandsTitle 远程图片抓取 +/** + * 远程图片抓取,当开启本插件时所有不符合本地域名的图片都将被抓取成为本地服务器上的图片 + */ +UE.plugins['catchremoteimage'] = function () { + var me = this, + ajax = UE.ajax; + + /* 设置默认值 */ + if (me.options.catchRemoteImageEnable === false) return; + me.setOpt({ + catchRemoteImageEnable: false + }); + + me.addListener("afterpaste", function () { + me.fireEvent("catchRemoteImage"); + }); + + me.addListener("catchRemoteImage", function () { + + var catcherLocalDomain = me.getOpt('catcherLocalDomain'), + catcherActionUrl = me.getActionUrl(me.getOpt('catcherActionName')), + catcherUrlPrefix = me.getOpt('catcherUrlPrefix'), + catcherFieldName = me.getOpt('catcherFieldName'); + + var remoteImages = [], + imgs = domUtils.getElementsByTagName(me.document, "img"), + test = function (src, urls) { + if (src.indexOf(location.host) != -1 || /(^\.)|(^\/)/.test(src)) { + return true; + } + if (urls) { + for (var j = 0, url; url = urls[j++];) { + if (src.indexOf(url) !== -1) { + return true; + } + } + } + return false; + }; + + for (var i = 0, ci; ci = imgs[i++];) { + if (ci.getAttribute("word_img")) { + continue; + } + var src = ci.getAttribute("_src") || ci.src || ""; + if (/^(https?|ftp):/i.test(src) && !test(src, catcherLocalDomain)) { + remoteImages.push(src); + } + } + + if (remoteImages.length) { + catchremoteimage(remoteImages, { + //成功抓取 + success: function (r) { + try { + var info = r.state !== undefined ? r:eval("(" + r.responseText + ")"); + } catch (e) { + return; + } + + /* 获取源路径和新路径 */ + var i, j, ci, cj, oldSrc, newSrc, list = info.list; + + for (i = 0; ci = imgs[i++];) { + oldSrc = ci.getAttribute("_src") || ci.src || ""; + for (j = 0; cj = list[j++];) { + if (oldSrc == cj.source && cj.state == "SUCCESS") { //抓取失败时不做替换处理 + newSrc = catcherUrlPrefix + cj.url; + domUtils.setAttributes(ci, { + "src": newSrc, + "_src": newSrc + }); + break; + } + } + } + me.fireEvent('catchremotesuccess') + }, + //回调失败,本次请求超时 + error: function () { + me.fireEvent("catchremoteerror"); + } + }); + } + + function catchremoteimage(imgs, callbacks) { + var params = utils.serializeParam(me.queryCommandValue('serverparam')) || '', + url = utils.formatUrl(catcherActionUrl + (catcherActionUrl.indexOf('?') == -1 ? '?':'&') + params), + isJsonp = utils.isCrossDomainUrl(url), + opt = { + 'method': 'POST', + 'dataType': isJsonp ? 'jsonp':'', + 'timeout': 60000, //单位:毫秒,回调请求超时设置。目标用户如果网速不是很快的话此处建议设置一个较大的数值 + 'onsuccess': callbacks["success"], + 'onerror': callbacks["error"] + }; + opt[catcherFieldName] = imgs; + ajax.request(url, opt); + } + + }); +}; + +// plugins/snapscreen.js +/** + * 截屏插件,为UEditor提供插入支持 + * @file + * @since 1.4.2 + */ +UE.plugin.register('snapscreen', function (){ + + var me = this; + var snapplugin; + + function getLocation(url){ + var search, + a = document.createElement('a'), + params = utils.serializeParam(me.queryCommandValue('serverparam')) || ''; + + a.href = url; + if (browser.ie) { + a.href = a.href; + } + + + search = a.search; + if (params) { + search = search + (search.indexOf('?') == -1 ? '?':'&')+ params; + search = search.replace(/[&]+/ig, '&'); + } + return { + 'port': a.port, + 'hostname': a.hostname, + 'path': a.pathname + search || + a.hash + } + } + + return { + commands:{ + /** + * 字体背景颜色 + * @command snapscreen + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand('snapscreen'); + * ``` + */ + 'snapscreen':{ + execCommand:function (cmd) { + var url, local, res; + var lang = me.getLang("snapScreen_plugin"); + + if(!snapplugin){ + var container = me.container; + var doc = me.container.ownerDocument || me.container.document; + snapplugin = doc.createElement("object"); + try{snapplugin.type = "application/x-pluginbaidusnap";}catch(e){ + return; + } + snapplugin.style.cssText = "position:absolute;left:-9999px;width:0;height:0;"; + snapplugin.setAttribute("width","0"); + snapplugin.setAttribute("height","0"); + container.appendChild(snapplugin); + } + + function onSuccess(rs){ + try{ + rs = eval("("+ rs +")"); + if(rs.state == 'SUCCESS'){ + var opt = me.options; + me.execCommand('insertimage', { + src: opt.snapscreenUrlPrefix + rs.url, + _src: opt.snapscreenUrlPrefix + rs.url, + alt: rs.title || '', + floatStyle: opt.snapscreenImgAlign + }); + } else { + alert(rs.state); + } + }catch(e){ + alert(lang.callBackErrorMsg); + } + } + url = me.getActionUrl(me.getOpt('snapscreenActionName')); + local = getLocation(url); + setTimeout(function () { + try{ + res =snapplugin.saveSnapshot(local.hostname, local.path, local.port); + }catch(e){ + me.ui._dialogs['snapscreenDialog'].open(); + return; + } + + onSuccess(res); + }, 50); + }, + queryCommandState: function(){ + return (navigator.userAgent.indexOf("Windows",0) != -1) ? 0:-1; + } + } + } + } +}); + + +// plugins/insertparagraph.js +/** + * 插入段落 + * @file + * @since 1.2.6.1 + */ + + +/** + * 插入段落 + * @command insertparagraph + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * //editor是编辑器实例 + * editor.execCommand( 'insertparagraph' ); + * ``` + */ + +UE.commands['insertparagraph'] = { + execCommand : function( cmdName,front) { + var me = this, + range = me.selection.getRange(), + start = range.startContainer,tmpNode; + while(start ){ + if(domUtils.isBody(start)){ + break; + } + tmpNode = start; + start = start.parentNode; + } + if(tmpNode){ + var p = me.document.createElement('p'); + if(front){ + tmpNode.parentNode.insertBefore(p,tmpNode) + }else{ + tmpNode.parentNode.insertBefore(p,tmpNode.nextSibling) + } + domUtils.fillNode(me.document,p); + range.setStart(p,0).setCursor(false,true); + } + } +}; + + + +// plugins/webapp.js +/** + * 百度应用 + * @file + * @since 1.2.6.1 + */ + + +/** + * 插入百度应用 + * @command webapp + * @method execCommand + * @remind 需要百度APPKey + * @remind 百度应用主页: http://app.baidu.com/ + * @param { Object } appOptions 应用所需的参数项, 支持的key有: title=>应用标题, width=>应用容器宽度, + * height=>应用容器高度,logo=>应用logo,url=>应用地址 + * @example + * ```javascript + * //editor是编辑器实例 + * //在编辑器里插入一个“植物大战僵尸”的APP + * editor.execCommand( 'webapp' , { + * title: '植物大战僵尸', + * width: 560, + * height: 465, + * logo: '应用展示的图片', + * url: '百度应用的地址' + * } ); + * ``` + */ + +//UE.plugins['webapp'] = function () { +// var me = this; +// function createInsertStr( obj, toIframe, addParagraph ) { +// return !toIframe ? +// (addParagraph ? '

          ' : '') + '' + +// (addParagraph ? '

          ' : '') +// : +// ''; +// } +// +// function switchImgAndIframe( img2frame ) { +// var tmpdiv, +// nodes = domUtils.getElementsByTagName( me.document, !img2frame ? "iframe" : "img" ); +// for ( var i = 0, node; node = nodes[i++]; ) { +// if ( node.className != "edui-faked-webapp" ){ +// continue; +// } +// tmpdiv = me.document.createElement( "div" ); +// tmpdiv.innerHTML = createInsertStr( img2frame ? {url:node.getAttribute( "_url" ), width:node.width, height:node.height,title:node.title,logo:node.style.backgroundImage.replace("url(","").replace(")","")} : {url:node.getAttribute( "src", 2 ),title:node.title, width:node.width, height:node.height,logo:node.getAttribute("logo_url")}, img2frame ? true : false,false ); +// node.parentNode.replaceChild( tmpdiv.firstChild, node ); +// } +// } +// +// me.addListener( "beforegetcontent", function () { +// switchImgAndIframe( true ); +// } ); +// me.addListener( 'aftersetcontent', function () { +// switchImgAndIframe( false ); +// } ); +// me.addListener( 'aftergetcontent', function ( cmdName ) { +// if ( cmdName == 'aftergetcontent' && me.queryCommandState( 'source' ) ){ +// return; +// } +// switchImgAndIframe( false ); +// } ); +// +// me.commands['webapp'] = { +// execCommand:function ( cmd, obj ) { +// me.execCommand( "inserthtml", createInsertStr( obj, false,true ) ); +// } +// }; +//}; + +UE.plugin.register('webapp', function (){ + var me = this; + function createInsertStr(obj,toEmbed){ + return !toEmbed ? + '' + : + '' + + } + return { + outputRule: function(root){ + utils.each(root.getNodesByTagName('img'),function(node){ + var html; + if(node.getAttr('class') == 'edui-faked-webapp'){ + html = createInsertStr({ + title:node.getAttr('title'), + 'width':node.getAttr('width'), + 'height':node.getAttr('height'), + 'align':node.getAttr('align'), + 'cssfloat':node.getStyle('float'), + 'url':node.getAttr("_url"), + 'logo':node.getAttr('_logo_url') + },true); + var embed = UE.uNode.createElement(html); + node.parentNode.replaceChild(embed,node); + } + }) + }, + inputRule:function(root){ + utils.each(root.getNodesByTagName('iframe'),function(node){ + if(node.getAttr('class') == 'edui-faked-webapp'){ + var img = UE.uNode.createElement(createInsertStr({ + title:node.getAttr('title'), + 'width':node.getAttr('width'), + 'height':node.getAttr('height'), + 'align':node.getAttr('align'), + 'cssfloat':node.getStyle('float'), + 'url':node.getAttr("src"), + 'logo':node.getAttr('logo_url') + })); + node.parentNode.replaceChild(img,node); + } + }) + + }, + commands:{ + /** + * 插入百度应用 + * @command webapp + * @method execCommand + * @remind 需要百度APPKey + * @remind 百度应用主页: http://app.baidu.com/ + * @param { Object } appOptions 应用所需的参数项, 支持的key有: title=>应用标题, width=>应用容器宽度, + * height=>应用容器高度,logo=>应用logo,url=>应用地址 + * @example + * ```javascript + * //editor是编辑器实例 + * //在编辑器里插入一个“植物大战僵尸”的APP + * editor.execCommand( 'webapp' , { + * title: '植物大战僵尸', + * width: 560, + * height: 465, + * logo: '应用展示的图片', + * url: '百度应用的地址' + * } ); + * ``` + */ + 'webapp':{ + execCommand:function (cmd, obj) { + + var me = this, + str = createInsertStr(utils.extend(obj,{ + align:'none' + }), false); + me.execCommand("inserthtml",str); + }, + queryCommandState:function () { + var me = this, + img = me.selection.getRange().getClosedNode(), + flag = img && (img.className == "edui-faked-webapp"); + return flag ? 1 : 0; + } + } + } + } +}); + +// plugins/template.js +///import core +///import plugins\inserthtml.js +///import plugins\cleardoc.js +///commands 模板 +///commandsName template +///commandsTitle 模板 +///commandsDialog dialogs\template +UE.plugins['template'] = function () { + UE.commands['template'] = { + execCommand:function (cmd, obj) { + obj.html && this.execCommand("inserthtml", obj.html); + } + }; + this.addListener("click", function (type, evt) { + var el = evt.target || evt.srcElement, + range = this.selection.getRange(); + var tnode = domUtils.findParent(el, function (node) { + if (node.className && domUtils.hasClass(node, "ue_t")) { + return node; + } + }, true); + tnode && range.selectNode(tnode).shrinkBoundary().select(); + }); + this.addListener("keydown", function (type, evt) { + var range = this.selection.getRange(); + if (!range.collapsed) { + if (!evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey) { + var tnode = domUtils.findParent(range.startContainer, function (node) { + if (node.className && domUtils.hasClass(node, "ue_t")) { + return node; + } + }, true); + if (tnode) { + domUtils.removeClasses(tnode, ["ue_t"]); + } + } + } + }); +}; + + +// plugins/music.js +/** + * 插入音乐命令 + * @file + */ +UE.plugin.register('music', function (){ + var me = this; + function creatInsertStr(url,width,height,align,cssfloat,toEmbed){ + return !toEmbed ? + '' + : + ''; + } + return { + outputRule: function(root){ + utils.each(root.getNodesByTagName('img'),function(node){ + var html; + if(node.getAttr('class') == 'edui-faked-music'){ + var cssfloat = node.getStyle('float'); + var align = node.getAttr('align'); + html = creatInsertStr(node.getAttr("_url"), node.getAttr('width'), node.getAttr('height'), align, cssfloat, true); + var embed = UE.uNode.createElement(html); + node.parentNode.replaceChild(embed,node); + } + }) + }, + inputRule:function(root){ + utils.each(root.getNodesByTagName('embed'),function(node){ + if(node.getAttr('class') == 'edui-faked-music'){ + var cssfloat = node.getStyle('float'); + var align = node.getAttr('align'); + html = creatInsertStr(node.getAttr("src"), node.getAttr('width'), node.getAttr('height'), align, cssfloat,false); + var img = UE.uNode.createElement(html); + node.parentNode.replaceChild(img,node); + } + }) + + }, + commands:{ + /** + * 插入音乐 + * @command music + * @method execCommand + * @param { Object } musicOptions 插入音乐的参数项, 支持的key有: url=>音乐地址; + * width=>音乐容器宽度;height=>音乐容器高度;align=>音乐文件的对齐方式, 可选值有: left, center, right, none + * @example + * ```javascript + * //editor是编辑器实例 + * //在编辑器里插入一个“植物大战僵尸”的APP + * editor.execCommand( 'music' , { + * width: 400, + * height: 95, + * align: "center", + * url: "音乐地址" + * } ); + * ``` + */ + 'music':{ + execCommand:function (cmd, musicObj) { + var me = this, + str = creatInsertStr(musicObj.url, musicObj.width || 400, musicObj.height || 95, "none", false); + me.execCommand("inserthtml",str); + }, + queryCommandState:function () { + var me = this, + img = me.selection.getRange().getClosedNode(), + flag = img && (img.className == "edui-faked-music"); + return flag ? 1 : 0; + } + } + } + } +}); + +// plugins/autoupload.js +/** + * @description + * 1.拖放文件到编辑区域,自动上传并插入到选区 + * 2.插入粘贴板的图片,自动上传并插入到选区 + * @author Jinqn + * @date 2013-10-14 + */ +UE.plugin.register('autoupload', function (){ + + function sendAndInsertFile(file, editor) { + var me = editor; + //模拟数据 + var fieldName, urlPrefix, maxSize, allowFiles, actionUrl, + loadingHtml, errorHandler, successHandler, + filetype = /image\/\w+/i.test(file.type) ? 'image':'file', + loadingId = 'loading_' + (+new Date()).toString(36); + + fieldName = me.getOpt(filetype + 'FieldName'); + urlPrefix = me.getOpt(filetype + 'UrlPrefix'); + maxSize = me.getOpt(filetype + 'MaxSize'); + allowFiles = me.getOpt(filetype + 'AllowFiles'); + actionUrl = me.getActionUrl(me.getOpt(filetype + 'ActionName')); + errorHandler = function(title) { + var loader = me.document.getElementById(loadingId); + loader && domUtils.remove(loader); + me.fireEvent('showmessage', { + 'id': loadingId, + 'content': title, + 'type': 'error', + 'timeout': 4000 + }); + }; + + if (filetype == 'image') { + loadingHtml = ''; + successHandler = function(data) { + var link = urlPrefix + data.url, + loader = me.document.getElementById(loadingId); + if (loader) { + loader.setAttribute('src', link); + loader.setAttribute('_src', link); + loader.setAttribute('title', data.title || ''); + loader.setAttribute('alt', data.original || ''); + loader.removeAttribute('id'); + domUtils.removeClasses(loader, 'loadingclass'); + } + }; + } else { + loadingHtml = '

          ' + + '' + + '

          '; + successHandler = function(data) { + var link = urlPrefix + data.url, + loader = me.document.getElementById(loadingId); + + var rng = me.selection.getRange(), + bk = rng.createBookmark(); + rng.selectNode(loader).select(); + me.execCommand('insertfile', {'url': link}); + rng.moveToBookmark(bk).select(); + }; + } + + /* 插入loading的占位符 */ + me.execCommand('inserthtml', loadingHtml); + + /* 判断后端配置是否没有加载成功 */ + if (!me.getOpt(filetype + 'ActionName')) { + errorHandler(me.getLang('autoupload.errorLoadConfig')); + return; + } + /* 判断文件大小是否超出限制 */ + if(file.size > maxSize) { + errorHandler(me.getLang('autoupload.exceedSizeError')); + return; + } + /* 判断文件格式是否超出允许 */ + var fileext = file.name ? file.name.substr(file.name.lastIndexOf('.')):''; + if ((fileext && filetype != 'image') || (allowFiles && (allowFiles.join('') + '.').indexOf(fileext.toLowerCase() + '.') == -1)) { + errorHandler(me.getLang('autoupload.exceedTypeError')); + return; + } + + /* 创建Ajax并提交 */ + var xhr = new XMLHttpRequest(), + fd = new FormData(), + params = utils.serializeParam(me.queryCommandValue('serverparam')) || '', + url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?':'&') + params); + + fd.append(fieldName, file, file.name || ('blob.' + file.type.substr('image/'.length))); + fd.append('type', 'ajax'); + xhr.open("post", url, true); + xhr.setRequestHeader("X-Requested-With", "XMLHttpRequest"); + xhr.addEventListener('load', function (e) { + try{ + var json = (new Function("return " + utils.trim(e.target.response)))(); + if (json.state == 'SUCCESS' && json.url) { + successHandler(json); + } else { + errorHandler(json.state); + } + }catch(er){ + errorHandler(me.getLang('autoupload.loadError')); + } + }); + xhr.send(fd); + } + + function getPasteImage(e){ + return e.clipboardData && e.clipboardData.items && e.clipboardData.items.length == 1 && /^image\//.test(e.clipboardData.items[0].type) ? e.clipboardData.items:null; + } + function getDropImage(e){ + return e.dataTransfer && e.dataTransfer.files ? e.dataTransfer.files:null; + } + + return { + outputRule: function(root){ + utils.each(root.getNodesByTagName('img'),function(n){ + if (/\b(loaderrorclass)|(bloaderrorclass)\b/.test(n.getAttr('class'))) { + n.parentNode.removeChild(n); + } + }); + utils.each(root.getNodesByTagName('p'),function(n){ + if (/\bloadpara\b/.test(n.getAttr('class'))) { + n.parentNode.removeChild(n); + } + }); + }, + bindEvents:{ + //插入粘贴板的图片,拖放插入图片 + 'ready':function(e){ + var me = this; + if(window.FormData && window.FileReader) { + domUtils.on(me.body, 'paste drop', function(e){ + var hasImg = false, + items; + //获取粘贴板文件列表或者拖放文件列表 + items = e.type == 'paste' ? getPasteImage(e):getDropImage(e); + if(items){ + var len = items.length, + file; + while (len--){ + file = items[len]; + if(file.getAsFile) file = file.getAsFile(); + if(file && file.size > 0) { + sendAndInsertFile(file, me); + hasImg = true; + } + } + hasImg && e.preventDefault(); + } + + }); + //取消拖放图片时出现的文字光标位置提示 + domUtils.on(me.body, 'dragover', function (e) { + if(e.dataTransfer.types[0] == 'Files') { + e.preventDefault(); + } + }); + + //设置loading的样式 + utils.cssRule('loading', + '.loadingclass{display:inline-block;cursor:default;background: url(\'' + + this.options.themePath + + this.options.theme +'/images/loading.gif\') no-repeat center center transparent;border:1px solid #cccccc;margin-left:1px;height: 22px;width: 22px;}\n' + + '.loaderrorclass{display:inline-block;cursor:default;background: url(\'' + + this.options.themePath + + this.options.theme +'/images/loaderror.png\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;' + + '}', + this.document); + } + } + } + } +}); + +// plugins/autosave.js +UE.plugin.register('autosave', function (){ + + var me = this, + //无限循环保护 + lastSaveTime = new Date(), + //最小保存间隔时间 + MIN_TIME = 20, + //auto save key + saveKey = null; + + function save ( editor ) { + + var saveData; + + if ( new Date() - lastSaveTime < MIN_TIME ) { + return; + } + + if ( !editor.hasContents() ) { + //这里不能调用命令来删除, 会造成事件死循环 + saveKey && me.removePreferences( saveKey ); + return; + } + + lastSaveTime = new Date(); + + editor._saveFlag = null; + + saveData = me.body.innerHTML; + + if ( editor.fireEvent( "beforeautosave", { + content: saveData + } ) === false ) { + return; + } + + me.setPreferences( saveKey, saveData ); + + editor.fireEvent( "afterautosave", { + content: saveData + } ); + + } + + return { + defaultOptions: { + //默认间隔时间 + saveInterval: 500 + }, + bindEvents:{ + 'ready':function(){ + + var _suffix = "-drafts-data", + key = null; + + if ( me.key ) { + key = me.key + _suffix; + } else { + key = ( me.container.parentNode.id || 'ue-common' ) + _suffix; + } + + //页面地址+编辑器ID 保持唯一 + saveKey = ( location.protocol + location.host + location.pathname ).replace( /[.:\/]/g, '_' ) + key; + + }, + + 'contentchange': function () { + + if ( !saveKey ) { + return; + } + + if ( me._saveFlag ) { + window.clearTimeout( me._saveFlag ); + } + + if ( me.options.saveInterval > 0 ) { + + me._saveFlag = window.setTimeout( function () { + + save( me ); + + }, me.options.saveInterval ); + + } else { + + save(me); + + } + + + } + }, + commands:{ + 'clearlocaldata':{ + execCommand:function (cmd, name) { + if ( saveKey && me.getPreferences( saveKey ) ) { + me.removePreferences( saveKey ) + } + }, + notNeedUndo: true, + ignoreContentChange:true + }, + + 'getlocaldata':{ + execCommand:function (cmd, name) { + return saveKey ? me.getPreferences( saveKey ) || '' : ''; + }, + notNeedUndo: true, + ignoreContentChange:true + }, + + 'drafts':{ + execCommand:function (cmd, name) { + if ( saveKey ) { + me.body.innerHTML = me.getPreferences( saveKey ) || '

          '+domUtils.fillHtml+'

          '; + me.focus(true); + } + }, + queryCommandState: function () { + return saveKey ? ( me.getPreferences( saveKey ) === null ? -1 : 0 ) : -1; + }, + notNeedUndo: true, + ignoreContentChange:true + } + } + } + +}); + +// plugins/charts.js +UE.plugin.register('charts', function (){ + + var me = this; + + return { + bindEvents: { + 'chartserror': function () { + } + }, + commands:{ + 'charts': { + execCommand: function ( cmd, data ) { + + var tableNode = domUtils.findParentByTagName(this.selection.getRange().startContainer, 'table', true), + flagText = [], + config = {}; + + if ( !tableNode ) { + return false; + } + + if ( !validData( tableNode ) ) { + me.fireEvent( "chartserror" ); + return false; + } + + config.title = data.title || ''; + config.subTitle = data.subTitle || ''; + config.xTitle = data.xTitle || ''; + config.yTitle = data.yTitle || ''; + config.suffix = data.suffix || ''; + config.tip = data.tip || ''; + //数据对齐方式 + config.dataFormat = data.tableDataFormat || ''; + //图表类型 + config.chartType = data.chartType || 0; + + for ( var key in config ) { + + if ( !config.hasOwnProperty( key ) ) { + continue; + } + + flagText.push( key+":"+config[ key ] ); + + } + + tableNode.setAttribute( "data-chart", flagText.join( ";" ) ); + domUtils.addClass( tableNode, "edui-charts-table" ); + + + + }, + queryCommandState: function ( cmd, name ) { + + var tableNode = domUtils.findParentByTagName(this.selection.getRange().startContainer, 'table', true); + return tableNode && validData( tableNode ) ? 0 : -1; + + } + } + }, + inputRule:function(root){ + utils.each(root.getNodesByTagName('table'),function( tableNode ){ + + if ( tableNode.getAttr("data-chart") !== undefined ) { + tableNode.setAttr("style"); + } + + }) + + }, + outputRule:function(root){ + utils.each(root.getNodesByTagName('table'),function( tableNode ){ + + if ( tableNode.getAttr("data-chart") !== undefined ) { + tableNode.setAttr("style", "display: none;"); + } + + }) + + } + } + + function validData ( table ) { + + var firstRows = null, + cellCount = 0; + + //行数不够 + if ( table.rows.length < 2 ) { + return false; + } + + //列数不够 + if ( table.rows[0].cells.length < 2 ) { + return false; + } + + //第一行所有cell必须是th + firstRows = table.rows[ 0 ].cells; + cellCount = firstRows.length; + + for ( var i = 0, cell; cell = firstRows[ i ]; i++ ) { + + if ( cell.tagName.toLowerCase() !== 'th' ) { + return false; + } + + } + + for ( var i = 1, row; row = table.rows[ i ]; i++ ) { + + //每行单元格数不匹配, 返回false + if ( row.cells.length != cellCount ) { + return false; + } + + //第一列不是th也返回false + if ( row.cells[0].tagName.toLowerCase() !== 'th' ) { + return false; + } + + for ( var j = 1, cell; cell = row.cells[ j ]; j++ ) { + + var value = utils.trim( ( cell.innerText || cell.textContent || '' ) ); + + value = value.replace( new RegExp( UE.dom.domUtils.fillChar, 'g' ), '' ).replace( /^\s+|\s+$/g, '' ); + + //必须是数字 + if ( !/^\d*\.?\d+$/.test( value ) ) { + return false; + } + + } + + } + + return true; + + } + +}); + +// plugins/section.js +/** + * 目录大纲支持插件 + * @file + * @since 1.3.0 + */ +UE.plugin.register('section', function (){ + /* 目录节点对象 */ + function Section(option){ + this.tag = ''; + this.level = -1, + this.dom = null; + this.nextSection = null; + this.previousSection = null; + this.parentSection = null; + this.startAddress = []; + this.endAddress = []; + this.children = []; + } + function getSection(option) { + var section = new Section(); + return utils.extend(section, option); + } + function getNodeFromAddress(startAddress, root) { + var current = root; + for(var i = 0;i < startAddress.length; i++) { + if(!current.childNodes) return null; + current = current.childNodes[startAddress[i]]; + } + return current; + } + + var me = this; + + return { + bindMultiEvents:{ + type: 'aftersetcontent afterscencerestore', + handler: function(){ + me.fireEvent('updateSections'); + } + }, + bindEvents:{ + /* 初始化、拖拽、粘贴、执行setcontent之后 */ + 'ready': function (){ + me.fireEvent('updateSections'); + domUtils.on(me.body, 'drop paste', function(){ + me.fireEvent('updateSections'); + }); + }, + /* 执行paragraph命令之后 */ + 'afterexeccommand': function (type, cmd) { + if(cmd == 'paragraph') { + me.fireEvent('updateSections'); + } + }, + /* 部分键盘操作,触发updateSections事件 */ + 'keyup': function (type, e) { + var me = this, + range = me.selection.getRange(); + if(range.collapsed != true) { + me.fireEvent('updateSections'); + } else { + var keyCode = e.keyCode || e.which; + if(keyCode == 13 || keyCode == 8 || keyCode == 46) { + me.fireEvent('updateSections'); + } + } + } + }, + commands:{ + 'getsections': { + execCommand: function (cmd, levels) { + var levelFn = levels || ['h1', 'h2', 'h3', 'h4', 'h5', 'h6']; + + for (var i = 0; i < levelFn.length; i++) { + if (typeof levelFn[i] == 'string') { + levelFn[i] = function(fn){ + return function(node){ + return node.tagName == fn.toUpperCase() + }; + }(levelFn[i]); + } else if (typeof levelFn[i] != 'function') { + levelFn[i] = function (node) { + return null; + } + } + } + function getSectionLevel(node) { + for (var i = 0; i < levelFn.length; i++) { + if (levelFn[i](node)) return i; + } + return -1; + } + + var me = this, + Directory = getSection({'level':-1, 'title':'root'}), + previous = Directory; + + function traversal(node, Directory) { + var level, + tmpSection = null, + parent, + child, + children = node.childNodes; + for (var i = 0, len = children.length; i < len; i++) { + child = children[i]; + level = getSectionLevel(child); + if (level >= 0) { + var address = me.selection.getRange().selectNode(child).createAddress(true).startAddress, + current = getSection({ + 'tag': child.tagName, + 'title': child.innerText || child.textContent || '', + 'level': level, + 'dom': child, + 'startAddress': utils.clone(address, []), + 'endAddress': utils.clone(address, []), + 'children': [] + }); + previous.nextSection = current; + current.previousSection = previous; + parent = previous; + while(level <= parent.level){ + parent = parent.parentSection; + } + current.parentSection = parent; + parent.children.push(current); + tmpSection = previous = current; + } else { + child.nodeType === 1 && traversal(child, Directory); + tmpSection && tmpSection.endAddress[tmpSection.endAddress.length - 1] ++; + } + } + } + traversal(me.body, Directory); + return Directory; + }, + notNeedUndo: true + }, + 'movesection': { + execCommand: function (cmd, sourceSection, targetSection, isAfter) { + + var me = this, + targetAddress, + target; + + if(!sourceSection || !targetSection || targetSection.level == -1) return; + + targetAddress = isAfter ? targetSection.endAddress:targetSection.startAddress; + target = getNodeFromAddress(targetAddress, me.body); + + /* 判断目标地址是否被源章节包含 */ + if(!targetAddress || !target || isContainsAddress(sourceSection.startAddress, sourceSection.endAddress, targetAddress)) return; + + var startNode = getNodeFromAddress(sourceSection.startAddress, me.body), + endNode = getNodeFromAddress(sourceSection.endAddress, me.body), + current, + nextNode; + + if(isAfter) { + current = endNode; + while ( current && !(domUtils.getPosition( startNode, current ) & domUtils.POSITION_FOLLOWING) ) { + nextNode = current.previousSibling; + domUtils.insertAfter(target, current); + if(current == startNode) break; + current = nextNode; + } + } else { + current = startNode; + while ( current && !(domUtils.getPosition( current, endNode ) & domUtils.POSITION_FOLLOWING) ) { + nextNode = current.nextSibling; + target.parentNode.insertBefore(current, target); + if(current == endNode) break; + current = nextNode; + } + } + + me.fireEvent('updateSections'); + + /* 获取地址的包含关系 */ + function isContainsAddress(startAddress, endAddress, addressTarget){ + var isAfterStartAddress = false, + isBeforeEndAddress = false; + for(var i = 0; i< startAddress.length; i++){ + if(i >= addressTarget.length) break; + if(addressTarget[i] > startAddress[i]) { + isAfterStartAddress = true; + break; + } else if(addressTarget[i] < startAddress[i]) { + break; + } + } + for(var i = 0; i< endAddress.length; i++){ + if(i >= addressTarget.length) break; + if(addressTarget[i] < startAddress[i]) { + isBeforeEndAddress = true; + break; + } else if(addressTarget[i] > startAddress[i]) { + break; + } + } + return isAfterStartAddress && isBeforeEndAddress; + } + } + }, + 'deletesection': { + execCommand: function (cmd, section, keepChildren) { + var me = this; + + if(!section) return; + + function getNodeFromAddress(startAddress) { + var current = me.body; + for(var i = 0;i < startAddress.length; i++) { + if(!current.childNodes) return null; + current = current.childNodes[startAddress[i]]; + } + return current; + } + + var startNode = getNodeFromAddress(section.startAddress), + endNode = getNodeFromAddress(section.endAddress), + current = startNode, + nextNode; + + if(!keepChildren) { + while ( current && domUtils.inDoc(endNode, me.document) && !(domUtils.getPosition( current, endNode ) & domUtils.POSITION_FOLLOWING) ) { + nextNode = current.nextSibling; + domUtils.remove(current); + current = nextNode; + } + } else { + domUtils.remove(current); + } + + me.fireEvent('updateSections'); + } + }, + 'selectsection': { + execCommand: function (cmd, section) { + if(!section && !section.dom) return false; + var me = this, + range = me.selection.getRange(), + address = { + 'startAddress':utils.clone(section.startAddress, []), + 'endAddress':utils.clone(section.endAddress, []) + }; + address.endAddress[address.endAddress.length - 1]++; + range.moveToAddress(address).select().scrollToView(); + return true; + }, + notNeedUndo: true + }, + 'scrolltosection': { + execCommand: function (cmd, section) { + if(!section && !section.dom) return false; + var me = this, + range = me.selection.getRange(), + address = { + 'startAddress':section.startAddress, + 'endAddress':section.endAddress + }; + address.endAddress[address.endAddress.length - 1]++; + range.moveToAddress(address).scrollToView(); + return true; + }, + notNeedUndo: true + } + } + } +}); + +// plugins/simpleupload.js +/** + * @description + * 简单上传:点击按钮,直接选择文件上传 + * @author Jinqn + * @date 2014-03-31 + */ +UE.plugin.register('simpleupload', function (){ + var me = this, + isLoaded = false, + containerBtn; + + function initUploadBtn(){ + var w = containerBtn.offsetWidth || 20, + h = containerBtn.offsetHeight || 20, + btnIframe = document.createElement('iframe'), + btnStyle = 'display:block;width:' + w + 'px;height:' + h + 'px;overflow:hidden;border:0;margin:0;padding:0;position:absolute;top:0;left:0;filter:alpha(opacity=0);-moz-opacity:0;-khtml-opacity: 0;opacity: 0;cursor:pointer;'; + + domUtils.on(btnIframe, 'load', function(){ + + var timestrap = (+new Date()).toString(36), + wrapper, + btnIframeDoc, + btnIframeBody; + + btnIframeDoc = (btnIframe.contentDocument || btnIframe.contentWindow.document); + btnIframeBody = btnIframeDoc.body; + wrapper = btnIframeDoc.createElement('div'); + + wrapper.innerHTML = '
          ' + + '' + + '
          ' + + ''; + + wrapper.className = 'edui-' + me.options.theme; + wrapper.id = me.ui.id + '_iframeupload'; + btnIframeBody.style.cssText = btnStyle; + btnIframeBody.style.width = w + 'px'; + btnIframeBody.style.height = h + 'px'; + btnIframeBody.appendChild(wrapper); + + if (btnIframeBody.parentNode) { + btnIframeBody.parentNode.style.width = w + 'px'; + btnIframeBody.parentNode.style.height = w + 'px'; + } + + var form = btnIframeDoc.getElementById('edui_form_' + timestrap); + var input = btnIframeDoc.getElementById('edui_input_' + timestrap); + var iframe = btnIframeDoc.getElementById('edui_iframe_' + timestrap); + + domUtils.on(input, 'change', function(){ + if(!input.value) return; + var loadingId = 'loading_' + (+new Date()).toString(36); + var params = utils.serializeParam(me.queryCommandValue('serverparam')) || ''; + + var imageActionUrl = me.getActionUrl(me.getOpt('imageActionName')); + var allowFiles = me.getOpt('imageAllowFiles'); + + me.focus(); + me.execCommand('inserthtml', ''); + + function callback(){ + try{ + var link, json, loader, + body = (iframe.contentDocument || iframe.contentWindow.document).body, + result = body.innerText || body.textContent || ''; + json = (new Function("return " + result))(); + link = me.options.imageUrlPrefix + json.url; + if(json.state == 'SUCCESS' && json.url) { + loader = me.document.getElementById(loadingId); + loader.setAttribute('src', link); + loader.setAttribute('_src', link); + loader.setAttribute('title', json.title || ''); + loader.setAttribute('alt', json.original || ''); + loader.removeAttribute('id'); + domUtils.removeClasses(loader, 'loadingclass'); + } else { + showErrorLoader && showErrorLoader(json.state); + } + }catch(er){ + showErrorLoader && showErrorLoader(me.getLang('simpleupload.loadError')); + } + form.reset(); + domUtils.un(iframe, 'load', callback); + } + function showErrorLoader(title){ + if(loadingId) { + var loader = me.document.getElementById(loadingId); + loader && domUtils.remove(loader); + me.fireEvent('showmessage', { + 'id': loadingId, + 'content': title, + 'type': 'error', + 'timeout': 4000 + }); + } + } + + /* 判断后端配置是否没有加载成功 */ + if (!me.getOpt('imageActionName')) { + errorHandler(me.getLang('autoupload.errorLoadConfig')); + return; + } + // 判断文件格式是否错误 + var filename = input.value, + fileext = filename ? filename.substr(filename.lastIndexOf('.')):''; + if (!fileext || (allowFiles && (allowFiles.join('') + '.').indexOf(fileext.toLowerCase() + '.') == -1)) { + showErrorLoader(me.getLang('simpleupload.exceedTypeError')); + return; + } + + domUtils.on(iframe, 'load', callback); + form.action = utils.formatUrl(imageActionUrl + (imageActionUrl.indexOf('?') == -1 ? '?':'&') + params); + form.submit(); + }); + + var stateTimer; + me.addListener('selectionchange', function () { + clearTimeout(stateTimer); + stateTimer = setTimeout(function() { + var state = me.queryCommandState('simpleupload'); + if (state == -1) { + input.disabled = 'disabled'; + } else { + input.disabled = false; + } + }, 400); + }); + isLoaded = true; + }); + + btnIframe.style.cssText = btnStyle; + containerBtn.appendChild(btnIframe); + } + + return { + bindEvents:{ + 'ready': function() { + //设置loading的样式 + utils.cssRule('loading', + '.loadingclass{display:inline-block;cursor:default;background: url(\'' + + this.options.themePath + + this.options.theme +'/images/loading.gif\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;}\n' + + '.loaderrorclass{display:inline-block;cursor:default;background: url(\'' + + this.options.themePath + + this.options.theme +'/images/loaderror.png\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;' + + '}', + this.document); + }, + /* 初始化简单上传按钮 */ + 'simpleuploadbtnready': function(type, container) { + containerBtn = container; + me.afterConfigReady(initUploadBtn); + } + }, + outputRule: function(root){ + utils.each(root.getNodesByTagName('img'),function(n){ + if (/\b(loaderrorclass)|(bloaderrorclass)\b/.test(n.getAttr('class'))) { + n.parentNode.removeChild(n); + } + }); + }, + commands: { + 'simpleupload': { + queryCommandState: function () { + return isLoaded ? 0:-1; + } + } + } + } +}); + +// plugins/serverparam.js +/** + * 服务器提交的额外参数列表设置插件 + * @file + * @since 1.2.6.1 + */ +UE.plugin.register('serverparam', function (){ + + var me = this, + serverParam = {}; + + return { + commands:{ + /** + * 修改服务器提交的额外参数列表,清除所有项 + * @command serverparam + * @method execCommand + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.execCommand('serverparam'); + * editor.queryCommandValue('serverparam'); //返回空 + * ``` + */ + /** + * 修改服务器提交的额外参数列表,删除指定项 + * @command serverparam + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } key 要清除的属性 + * @example + * ```javascript + * editor.execCommand('serverparam', 'name'); //删除属性name + * ``` + */ + /** + * 修改服务器提交的额外参数列表,使用键值添加项 + * @command serverparam + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { String } key 要添加的属性 + * @param { String } value 要添加属性的值 + * @example + * ```javascript + * editor.execCommand('serverparam', 'name', 'hello'); + * editor.queryCommandValue('serverparam'); //返回对象 {'name': 'hello'} + * ``` + */ + /** + * 修改服务器提交的额外参数列表,传入键值对对象添加多项 + * @command serverparam + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { Object } key 传入的键值对对象 + * @example + * ```javascript + * editor.execCommand('serverparam', {'name': 'hello'}); + * editor.queryCommandValue('serverparam'); //返回对象 {'name': 'hello'} + * ``` + */ + /** + * 修改服务器提交的额外参数列表,使用自定义函数添加多项 + * @command serverparam + * @method execCommand + * @param { String } cmd 命令字符串 + * @param { Function } key 自定义获取参数的函数 + * @example + * ```javascript + * editor.execCommand('serverparam', function(editor){ + * return {'key': 'value'}; + * }); + * editor.queryCommandValue('serverparam'); //返回对象 {'key': 'value'} + * ``` + */ + + /** + * 获取服务器提交的额外参数列表 + * @command serverparam + * @method queryCommandValue + * @param { String } cmd 命令字符串 + * @example + * ```javascript + * editor.queryCommandValue( 'serverparam' ); //返回对象 {'key': 'value'} + * ``` + */ + 'serverparam':{ + execCommand:function (cmd, key, value) { + if (key === undefined || key === null) { //不传参数,清空列表 + serverParam = {}; + } else if (utils.isString(key)) { //传入键值 + if(value === undefined || value === null) { + delete serverParam[key]; + } else { + serverParam[key] = value; + } + } else if (utils.isObject(key)) { //传入对象,覆盖列表项 + utils.extend(serverParam, key, true); + } else if (utils.isFunction(key)){ //传入函数,添加列表项 + utils.extend(serverParam, key(), true); + } + }, + queryCommandValue: function(){ + return serverParam || {}; + } + } + } + } +}); + + +// plugins/insertfile.js +/** + * 插入附件 + */ +UE.plugin.register('insertfile', function (){ + + var me = this; + + function getFileIcon(url){ + var ext = url.substr(url.lastIndexOf('.') + 1).toLowerCase(), + maps = { + + }; + return maps[ext] ? maps[ext]:maps['txt']; + } + + return { + commands:{ + 'insertfile': { + execCommand: function (command, filelist){ + filelist = utils.isArray(filelist) ? filelist : [filelist]; + + var i, item, icon, title, + html = '', + URL = me.getOpt('UEDITOR_HOME_URL'); + for (i = 0; i < filelist.length; i++) { + item = filelist[i]; + title = item.title || item.url.substr(item.url.lastIndexOf('/') + 1); + html += '

          ' + + '' + title + '' + + '

          '; + } + me.execCommand('insertHtml', html); + } + } + } + } +}); + + + + +// plugins/xssFilter.js +/** + * @file xssFilter.js + * @desc xss过滤器 + * @author robbenmu + */ + +UE.plugins.xssFilter = function() { + + var config = UEDITOR_CONFIG; + var whitList = config.whitList; + + function filter(node) { + + var tagName = node.tagName; + var attrs = node.attrs; + + if (!whitList.hasOwnProperty(tagName)) { + node.parentNode.removeChild(node); + return false; + } + + UE.utils.each(attrs, function (val, key) { + + if (whitList[tagName].indexOf(key) === -1) { + node.setAttr(key); + } + }); + } + + // 添加inserthtml\paste等操作用的过滤规则 + if (whitList && config.xssFilterRules) { + this.options.filterRules = function () { + + var result = {}; + + UE.utils.each(whitList, function(val, key) { + result[key] = function (node) { + return filter(node); + }; + }); + + return result; + }(); + } + + var tagList = []; + + UE.utils.each(whitList, function (val, key) { + tagList.push(key); + }); + + // 添加input过滤规则 + // + if (whitList && config.inputXssFilter) { + this.addInputRule(function (root) { + + root.traversal(function(node) { + if (node.type !== 'element') { + return false; + } + filter(node); + }); + }); + } + // 添加output过滤规则 + // + if (whitList && config.outputXssFilter) { + this.addOutputRule(function (root) { + + root.traversal(function(node) { + if (node.type !== 'element') { + return false; + } + filter(node); + }); + }); + } + +}; + + +// ui/ui.js +var baidu = baidu || {}; +baidu.editor = baidu.editor || {}; +UE.ui = baidu.editor.ui = {}; + +// ui/uiutils.js +(function (){ + var browser = baidu.editor.browser, + domUtils = baidu.editor.dom.domUtils; + + var magic = '$EDITORUI'; + var root = window[magic] = {}; + var uidMagic = 'ID' + magic; + var uidCount = 0; + + var uiUtils = baidu.editor.ui.uiUtils = { + uid: function (obj){ + return (obj ? obj[uidMagic] || (obj[uidMagic] = ++ uidCount) : ++ uidCount); + }, + hook: function ( fn, callback ) { + var dg; + if (fn && fn._callbacks) { + dg = fn; + } else { + dg = function (){ + var q; + if (fn) { + q = fn.apply(this, arguments); + } + var callbacks = dg._callbacks; + var k = callbacks.length; + while (k --) { + var r = callbacks[k].apply(this, arguments); + if (q === undefined) { + q = r; + } + } + return q; + }; + dg._callbacks = []; + } + dg._callbacks.push(callback); + return dg; + }, + createElementByHtml: function (html){ + var el = document.createElement('div'); + el.innerHTML = html; + el = el.firstChild; + el.parentNode.removeChild(el); + return el; + }, + getViewportElement: function (){ + return (browser.ie && browser.quirks) ? + document.body : document.documentElement; + }, + getClientRect: function (element){ + var bcr; + //trace IE6下在控制编辑器显隐时可能会报错,catch一下 + try{ + bcr = element.getBoundingClientRect(); + }catch(e){ + bcr={left:0,top:0,height:0,width:0} + } + var rect = { + left: Math.round(bcr.left), + top: Math.round(bcr.top), + height: Math.round(bcr.bottom - bcr.top), + width: Math.round(bcr.right - bcr.left) + }; + var doc; + while ((doc = element.ownerDocument) !== document && + (element = domUtils.getWindow(doc).frameElement)) { + bcr = element.getBoundingClientRect(); + rect.left += bcr.left; + rect.top += bcr.top; + } + rect.bottom = rect.top + rect.height; + rect.right = rect.left + rect.width; + return rect; + }, + getViewportRect: function (){ + var viewportEl = uiUtils.getViewportElement(); + var width = (window.innerWidth || viewportEl.clientWidth) | 0; + var height = (window.innerHeight ||viewportEl.clientHeight) | 0; + return { + left: 0, + top: 0, + height: height, + width: width, + bottom: height, + right: width + }; + }, + setViewportOffset: function (element, offset){ + var rect; + var fixedLayer = uiUtils.getFixedLayer(); + if (element.parentNode === fixedLayer) { + element.style.left = offset.left + 'px'; + element.style.top = offset.top + 'px'; + } else { + domUtils.setViewportOffset(element, offset); + } + }, + getEventOffset: function (evt){ + var el = evt.target || evt.srcElement; + var rect = uiUtils.getClientRect(el); + var offset = uiUtils.getViewportOffsetByEvent(evt); + return { + left: offset.left - rect.left, + top: offset.top - rect.top + }; + }, + getViewportOffsetByEvent: function (evt){ + var el = evt.target || evt.srcElement; + var frameEl = domUtils.getWindow(el).frameElement; + var offset = { + left: evt.clientX, + top: evt.clientY + }; + if (frameEl && el.ownerDocument !== document) { + var rect = uiUtils.getClientRect(frameEl); + offset.left += rect.left; + offset.top += rect.top; + } + return offset; + }, + setGlobal: function (id, obj){ + root[id] = obj; + return magic + '["' + id + '"]'; + }, + unsetGlobal: function (id){ + delete root[id]; + }, + copyAttributes: function (tgt, src){ + var attributes = src.attributes; + var k = attributes.length; + while (k --) { + var attrNode = attributes[k]; + if ( attrNode.nodeName != 'style' && attrNode.nodeName != 'class' && (!browser.ie || attrNode.specified) ) { + tgt.setAttribute(attrNode.nodeName, attrNode.nodeValue); + } + } + if (src.className) { + domUtils.addClass(tgt,src.className); + } + if (src.style.cssText) { + tgt.style.cssText += ';' + src.style.cssText; + } + }, + removeStyle: function (el, styleName){ + if (el.style.removeProperty) { + el.style.removeProperty(styleName); + } else if (el.style.removeAttribute) { + el.style.removeAttribute(styleName); + } else throw ''; + }, + contains: function (elA, elB){ + return elA && elB && (elA === elB ? false : ( + elA.contains ? elA.contains(elB) : + elA.compareDocumentPosition(elB) & 16 + )); + }, + startDrag: function (evt, callbacks,doc){ + var doc = doc || document; + var startX = evt.clientX; + var startY = evt.clientY; + function handleMouseMove(evt){ + var x = evt.clientX - startX; + var y = evt.clientY - startY; + callbacks.ondragmove(x, y,evt); + if (evt.stopPropagation) { + evt.stopPropagation(); + } else { + evt.cancelBubble = true; + } + } + if (doc.addEventListener) { + function handleMouseUp(evt){ + doc.removeEventListener('mousemove', handleMouseMove, true); + doc.removeEventListener('mouseup', handleMouseUp, true); + window.removeEventListener('mouseup', handleMouseUp, true); + callbacks.ondragstop(); + } + doc.addEventListener('mousemove', handleMouseMove, true); + doc.addEventListener('mouseup', handleMouseUp, true); + window.addEventListener('mouseup', handleMouseUp, true); + + evt.preventDefault(); + } else { + var elm = evt.srcElement; + elm.setCapture(); + function releaseCaptrue(){ + elm.releaseCapture(); + elm.detachEvent('onmousemove', handleMouseMove); + elm.detachEvent('onmouseup', releaseCaptrue); + elm.detachEvent('onlosecaptrue', releaseCaptrue); + callbacks.ondragstop(); + } + elm.attachEvent('onmousemove', handleMouseMove); + elm.attachEvent('onmouseup', releaseCaptrue); + elm.attachEvent('onlosecaptrue', releaseCaptrue); + evt.returnValue = false; + } + callbacks.ondragstart(); + }, + getFixedLayer: function (){ + var layer = document.getElementById('edui_fixedlayer'); + if (layer == null) { + layer = document.createElement('div'); + layer.id = 'edui_fixedlayer'; + document.body.appendChild(layer); + if (browser.ie && browser.version <= 8) { + layer.style.position = 'absolute'; + bindFixedLayer(); + setTimeout(updateFixedOffset); + } else { + layer.style.position = 'fixed'; + } + layer.style.left = '0'; + layer.style.top = '0'; + layer.style.width = '0'; + layer.style.height = '0'; + } + return layer; + }, + makeUnselectable: function (element){ + if (browser.opera || (browser.ie && browser.version < 9)) { + element.unselectable = 'on'; + if (element.hasChildNodes()) { + for (var i=0; i
          '; + } + }; + utils.inherits(Separator, UIBase); + +})(); + + +// ui/mask.js +///import core +///import uicore +(function (){ + var utils = baidu.editor.utils, + domUtils = baidu.editor.dom.domUtils, + UIBase = baidu.editor.ui.UIBase, + uiUtils = baidu.editor.ui.uiUtils; + + var Mask = baidu.editor.ui.Mask = function (options){ + this.initOptions(options); + this.initUIBase(); + }; + Mask.prototype = { + getHtmlTpl: function (){ + return '
          '; + }, + postRender: function (){ + var me = this; + domUtils.on(window, 'resize', function (){ + setTimeout(function (){ + if (!me.isHidden()) { + me._fill(); + } + }); + }); + }, + show: function (zIndex){ + this._fill(); + this.getDom().style.display = ''; + this.getDom().style.zIndex = zIndex; + }, + hide: function (){ + this.getDom().style.display = 'none'; + this.getDom().style.zIndex = ''; + }, + isHidden: function (){ + return this.getDom().style.display == 'none'; + }, + _onMouseDown: function (){ + return false; + }, + _onClick: function (e, target){ + this.fireEvent('click', e, target); + }, + _fill: function (){ + var el = this.getDom(); + var vpRect = uiUtils.getViewportRect(); + el.style.width = vpRect.width + 'px'; + el.style.height = vpRect.height + 'px'; + } + }; + utils.inherits(Mask, UIBase); +})(); + + +// ui/popup.js +///import core +///import uicore +(function () { + var utils = baidu.editor.utils, + uiUtils = baidu.editor.ui.uiUtils, + domUtils = baidu.editor.dom.domUtils, + UIBase = baidu.editor.ui.UIBase, + Popup = baidu.editor.ui.Popup = function (options){ + this.initOptions(options); + this.initPopup(); + }; + + var allPopups = []; + function closeAllPopup( evt,el ){ + for ( var i = 0; i < allPopups.length; i++ ) { + var pop = allPopups[i]; + if (!pop.isHidden()) { + if (pop.queryAutoHide(el) !== false) { + if(evt&&/scroll/ig.test(evt.type)&&pop.className=="edui-wordpastepop") return; + pop.hide(); + } + } + } + + if(allPopups.length) + pop.editor.fireEvent("afterhidepop"); + } + + Popup.postHide = closeAllPopup; + + var ANCHOR_CLASSES = ['edui-anchor-topleft','edui-anchor-topright', + 'edui-anchor-bottomleft','edui-anchor-bottomright']; + Popup.prototype = { + SHADOW_RADIUS: 5, + content: null, + _hidden: false, + autoRender: true, + canSideLeft: true, + canSideUp: true, + initPopup: function (){ + this.initUIBase(); + allPopups.push( this ); + }, + getHtmlTpl: function (){ + return '
          ' + + '
          ' + + ' ' + + '
          ' + + '
          ' + + this.getContentHtmlTpl() + + '
          ' + + '
          ' + + '
          '; + }, + getContentHtmlTpl: function (){ + if(this.content){ + if (typeof this.content == 'string') { + return this.content; + } + return this.content.renderHtml(); + }else{ + return '' + } + + }, + _UIBase_postRender: UIBase.prototype.postRender, + postRender: function (){ + + + if (this.content instanceof UIBase) { + this.content.postRender(); + } + + //捕获鼠标滚轮 + if( this.captureWheel && !this.captured ) { + + this.captured = true; + + var winHeight = ( document.documentElement.clientHeight || document.body.clientHeight ) - 80, + _height = this.getDom().offsetHeight, + _top = uiUtils.getClientRect( this.combox.getDom() ).top, + content = this.getDom('content'), + ifr = this.getDom('body').getElementsByTagName('iframe'), + me = this; + + ifr.length && ( ifr = ifr[0] ); + + while( _top + _height > winHeight ) { + _height -= 30; + } + content.style.height = _height + 'px'; + //同步更改iframe高度 + ifr && ( ifr.style.height = _height + 'px' ); + + //阻止在combox上的鼠标滚轮事件, 防止用户的正常操作被误解 + if( window.XMLHttpRequest ) { + + domUtils.on( content, ( 'onmousewheel' in document.body ) ? 'mousewheel' :'DOMMouseScroll' , function(e){ + + if(e.preventDefault) { + e.preventDefault(); + } else { + e.returnValue = false; + } + + if( e.wheelDelta ) { + + content.scrollTop -= ( e.wheelDelta / 120 )*60; + + } else { + + content.scrollTop -= ( e.detail / -3 )*60; + + } + + }); + + } else { + + //ie6 + domUtils.on( this.getDom(), 'mousewheel' , function(e){ + + e.returnValue = false; + + me.getDom('content').scrollTop -= ( e.wheelDelta / 120 )*60; + + }); + + } + + } + this.fireEvent('postRenderAfter'); + this.hide(true); + this._UIBase_postRender(); + }, + _doAutoRender: function (){ + if (!this.getDom() && this.autoRender) { + this.render(); + } + }, + mesureSize: function (){ + var box = this.getDom('content'); + return uiUtils.getClientRect(box); + }, + fitSize: function (){ + if( this.captureWheel && this.sized ) { + return this.__size; + } + this.sized = true; + var popBodyEl = this.getDom('body'); + popBodyEl.style.width = ''; + popBodyEl.style.height = ''; + var size = this.mesureSize(); + if( this.captureWheel ) { + popBodyEl.style.width = -(-20 -size.width) + 'px'; + var height = parseInt( this.getDom('content').style.height, 10 ); + !window.isNaN( height ) && ( size.height = height ); + } else { + popBodyEl.style.width = size.width + 'px'; + } + popBodyEl.style.height = size.height + 'px'; + this.__size = size; + this.captureWheel && (this.getDom('content').style.overflow = 'auto'); + return size; + }, + showAnchor: function ( element, hoz ){ + this.showAnchorRect( uiUtils.getClientRect( element ), hoz ); + }, + showAnchorRect: function ( rect, hoz, adj ){ + this._doAutoRender(); + var vpRect = uiUtils.getViewportRect(); + this.getDom().style.visibility = 'hidden'; + this._show(); + var popSize = this.fitSize(); + + var sideLeft, sideUp, left, top; + if (hoz) { + sideLeft = this.canSideLeft && (rect.right + popSize.width > vpRect.right && rect.left > popSize.width); + sideUp = this.canSideUp && (rect.top + popSize.height > vpRect.bottom && rect.bottom > popSize.height); + left = (sideLeft ? rect.left - popSize.width : rect.right); + top = (sideUp ? rect.bottom - popSize.height : rect.top); + } else { + sideLeft = this.canSideLeft && (rect.right + popSize.width > vpRect.right && rect.left > popSize.width); + sideUp = this.canSideUp && (rect.top + popSize.height > vpRect.bottom && rect.bottom > popSize.height); + left = (sideLeft ? rect.right - popSize.width : rect.left); + top = (sideUp ? rect.top - popSize.height : rect.bottom); + } + + var popEl = this.getDom(); + uiUtils.setViewportOffset(popEl, { + left: left, + top: top + }); + domUtils.removeClasses(popEl, ANCHOR_CLASSES); + popEl.className += ' ' + ANCHOR_CLASSES[(sideUp ? 1 : 0) * 2 + (sideLeft ? 1 : 0)]; + if(this.editor){ + popEl.style.zIndex = this.editor.container.style.zIndex * 1 + 10; + baidu.editor.ui.uiUtils.getFixedLayer().style.zIndex = popEl.style.zIndex - 1; + } + this.getDom().style.visibility = 'visible'; + + }, + showAt: function (offset) { + var left = offset.left; + var top = offset.top; + var rect = { + left: left, + top: top, + right: left, + bottom: top, + height: 0, + width: 0 + }; + this.showAnchorRect(rect, false, true); + }, + _show: function (){ + if (this._hidden) { + var box = this.getDom(); + box.style.display = ''; + this._hidden = false; +// if (box.setActive) { +// box.setActive(); +// } + this.fireEvent('show'); + } + }, + isHidden: function (){ + return this._hidden; + }, + show: function (){ + this._doAutoRender(); + this._show(); + }, + hide: function (notNofity){ + if (!this._hidden && this.getDom()) { + this.getDom().style.display = 'none'; + this._hidden = true; + if (!notNofity) { + this.fireEvent('hide'); + } + } + }, + queryAutoHide: function (el){ + return !el || !uiUtils.contains(this.getDom(), el); + } + }; + utils.inherits(Popup, UIBase); + + domUtils.on( document, 'mousedown', function ( evt ) { + var el = evt.target || evt.srcElement; + closeAllPopup( evt,el ); + } ); + domUtils.on( window, 'scroll', function (evt,el) { + closeAllPopup( evt,el ); + } ); + +})(); + + +// ui/colorpicker.js +///import core +///import uicore +(function (){ + var utils = baidu.editor.utils, + UIBase = baidu.editor.ui.UIBase, + ColorPicker = baidu.editor.ui.ColorPicker = function (options){ + this.initOptions(options); + this.noColorText = this.noColorText || this.editor.getLang("clearColor"); + this.initUIBase(); + }; + + ColorPicker.prototype = { + getHtmlTpl: function (){ + return genColorPicker(this.noColorText,this.editor); + }, + _onTableClick: function (evt){ + var tgt = evt.target || evt.srcElement; + var color = tgt.getAttribute('data-color'); + if (color) { + this.fireEvent('pickcolor', color); + } + }, + _onTableOver: function (evt){ + var tgt = evt.target || evt.srcElement; + var color = tgt.getAttribute('data-color'); + if (color) { + this.getDom('preview').style.backgroundColor = color; + } + }, + _onTableOut: function (){ + this.getDom('preview').style.backgroundColor = ''; + }, + _onPickNoColor: function (){ + this.fireEvent('picknocolor'); + } + }; + utils.inherits(ColorPicker, UIBase); + + var COLORS = ( + 'ffffff,000000,eeece1,1f497d,4f81bd,c0504d,9bbb59,8064a2,4bacc6,f79646,' + + 'f2f2f2,7f7f7f,ddd9c3,c6d9f0,dbe5f1,f2dcdb,ebf1dd,e5e0ec,dbeef3,fdeada,' + + 'd8d8d8,595959,c4bd97,8db3e2,b8cce4,e5b9b7,d7e3bc,ccc1d9,b7dde8,fbd5b5,' + + 'bfbfbf,3f3f3f,938953,548dd4,95b3d7,d99694,c3d69b,b2a2c7,92cddc,fac08f,' + + 'a5a5a5,262626,494429,17365d,366092,953734,76923c,5f497a,31859b,e36c09,' + + '7f7f7f,0c0c0c,1d1b10,0f243e,244061,632423,4f6128,3f3151,205867,974806,' + + 'c00000,ff0000,ffc000,ffff00,92d050,00b050,00b0f0,0070c0,002060,7030a0,').split(','); + + function genColorPicker(noColorText,editor){ + var html = '
          ' + + '
          ' + + '
          ' + + '
          '+ noColorText +'
          ' + + '
          ' + + '' + + ''+ + ''; + for (var i=0; i':'')+''; + } + html += i<70 ? '':''; + } + html += '
          '+editor.getLang("themeColor")+'
          '+editor.getLang("standardColor")+'
          '; + return html; + } +})(); + + +// ui/tablepicker.js +///import core +///import uicore +(function (){ + var utils = baidu.editor.utils, + uiUtils = baidu.editor.ui.uiUtils, + UIBase = baidu.editor.ui.UIBase; + + var TablePicker = baidu.editor.ui.TablePicker = function (options){ + this.initOptions(options); + this.initTablePicker(); + }; + TablePicker.prototype = { + defaultNumRows: 10, + defaultNumCols: 10, + maxNumRows: 20, + maxNumCols: 20, + numRows: 10, + numCols: 10, + lengthOfCellSide: 22, + initTablePicker: function (){ + this.initUIBase(); + }, + getHtmlTpl: function (){ + var me = this; + return '
          ' + + '
          ' + + '
          ' + + '' + + '
          ' + + '
          ' + + '
          ' + + '
          ' + + '
          ' + + '
          '; + }, + _UIBase_render: UIBase.prototype.render, + render: function (holder){ + this._UIBase_render(holder); + this.getDom('label').innerHTML = '0'+this.editor.getLang("t_row")+' x 0'+this.editor.getLang("t_col"); + }, + _track: function (numCols, numRows){ + var style = this.getDom('overlay').style; + var sideLen = this.lengthOfCellSide; + style.width = numCols * sideLen + 'px'; + style.height = numRows * sideLen + 'px'; + var label = this.getDom('label'); + label.innerHTML = numCols +this.editor.getLang("t_col")+' x ' + numRows + this.editor.getLang("t_row"); + this.numCols = numCols; + this.numRows = numRows; + }, + _onMouseOver: function (evt, el){ + var rel = evt.relatedTarget || evt.fromElement; + if (!uiUtils.contains(el, rel) && el !== rel) { + this.getDom('label').innerHTML = '0'+this.editor.getLang("t_col")+' x 0'+this.editor.getLang("t_row"); + this.getDom('overlay').style.visibility = ''; + } + }, + _onMouseOut: function (evt, el){ + var rel = evt.relatedTarget || evt.toElement; + if (!uiUtils.contains(el, rel) && el !== rel) { + this.getDom('label').innerHTML = '0'+this.editor.getLang("t_col")+' x 0'+this.editor.getLang("t_row"); + this.getDom('overlay').style.visibility = 'hidden'; + } + }, + _onMouseMove: function (evt, el){ + var style = this.getDom('overlay').style; + var offset = uiUtils.getEventOffset(evt); + var sideLen = this.lengthOfCellSide; + var numCols = Math.ceil(offset.left / sideLen); + var numRows = Math.ceil(offset.top / sideLen); + this._track(numCols, numRows); + }, + _onClick: function (){ + this.fireEvent('picktable', this.numCols, this.numRows); + } + }; + utils.inherits(TablePicker, UIBase); +})(); + + +// ui/stateful.js +(function (){ + var browser = baidu.editor.browser, + domUtils = baidu.editor.dom.domUtils, + uiUtils = baidu.editor.ui.uiUtils; + + var TPL_STATEFUL = 'onmousedown="$$.Stateful_onMouseDown(event, this);"' + + ' onmouseup="$$.Stateful_onMouseUp(event, this);"' + + ( browser.ie ? ( + ' onmouseenter="$$.Stateful_onMouseEnter(event, this);"' + + ' onmouseleave="$$.Stateful_onMouseLeave(event, this);"' ) + : ( + ' onmouseover="$$.Stateful_onMouseOver(event, this);"' + + ' onmouseout="$$.Stateful_onMouseOut(event, this);"' )); + + baidu.editor.ui.Stateful = { + alwalysHoverable: false, + target:null,//目标元素和this指向dom不一样 + Stateful_init: function (){ + this._Stateful_dGetHtmlTpl = this.getHtmlTpl; + this.getHtmlTpl = this.Stateful_getHtmlTpl; + }, + Stateful_getHtmlTpl: function (){ + var tpl = this._Stateful_dGetHtmlTpl(); + // 使用function避免$转义 + return tpl.replace(/stateful/g, function (){ return TPL_STATEFUL; }); + }, + Stateful_onMouseEnter: function (evt, el){ + this.target=el; + if (!this.isDisabled() || this.alwalysHoverable) { + this.addState('hover'); + this.fireEvent('over'); + } + }, + Stateful_onMouseLeave: function (evt, el){ + if (!this.isDisabled() || this.alwalysHoverable) { + this.removeState('hover'); + this.removeState('active'); + this.fireEvent('out'); + } + }, + Stateful_onMouseOver: function (evt, el){ + var rel = evt.relatedTarget; + if (!uiUtils.contains(el, rel) && el !== rel) { + this.Stateful_onMouseEnter(evt, el); + } + }, + Stateful_onMouseOut: function (evt, el){ + var rel = evt.relatedTarget; + if (!uiUtils.contains(el, rel) && el !== rel) { + this.Stateful_onMouseLeave(evt, el); + } + }, + Stateful_onMouseDown: function (evt, el){ + if (!this.isDisabled()) { + this.addState('active'); + } + }, + Stateful_onMouseUp: function (evt, el){ + if (!this.isDisabled()) { + this.removeState('active'); + } + }, + Stateful_postRender: function (){ + if (this.disabled && !this.hasState('disabled')) { + this.addState('disabled'); + } + }, + hasState: function (state){ + return domUtils.hasClass(this.getStateDom(), 'edui-state-' + state); + }, + addState: function (state){ + if (!this.hasState(state)) { + this.getStateDom().className += ' edui-state-' + state; + } + }, + removeState: function (state){ + if (this.hasState(state)) { + domUtils.removeClasses(this.getStateDom(), ['edui-state-' + state]); + } + }, + getStateDom: function (){ + return this.getDom('state'); + }, + isChecked: function (){ + return this.hasState('checked'); + }, + setChecked: function (checked){ + if (!this.isDisabled() && checked) { + this.addState('checked'); + } else { + this.removeState('checked'); + } + }, + isDisabled: function (){ + return this.hasState('disabled'); + }, + setDisabled: function (disabled){ + if (disabled) { + this.removeState('hover'); + this.removeState('checked'); + this.removeState('active'); + this.addState('disabled'); + } else { + this.removeState('disabled'); + } + } + }; +})(); + + +// ui/button.js +///import core +///import uicore +///import ui/stateful.js +(function (){ + var utils = baidu.editor.utils, + UIBase = baidu.editor.ui.UIBase, + Stateful = baidu.editor.ui.Stateful, + Button = baidu.editor.ui.Button = function (options){ + if(options.name){ + var btnName = options.name; + var cssRules = options.cssRules; + if(!options.className){ + options.className = 'edui-for-' + btnName; + } + options.cssRules = '.edui-default .edui-for-'+ btnName +' .edui-icon {'+ cssRules +'}' + } + this.initOptions(options); + this.initButton(); + }; + Button.prototype = { + uiName: 'button', + label: '', + title: '', + showIcon: true, + showText: true, + cssRules:'', + initButton: function (){ + this.initUIBase(); + this.Stateful_init(); + if(this.cssRules){ + utils.cssRule('edui-customize-'+this.name+'-style',this.cssRules); + } + }, + getHtmlTpl: function (){ + return '
          ' + + '
          ' + + '
          ' + + (this.showIcon ? '
          ' : '') + + (this.showText ? '
          ' + this.label + '
          ' : '') + + '
          ' + + '
          ' + + '
          '; + }, + postRender: function (){ + this.Stateful_postRender(); + this.setDisabled(this.disabled) + }, + _onMouseDown: function (e){ + var target = e.target || e.srcElement, + tagName = target && target.tagName && target.tagName.toLowerCase(); + if (tagName == 'input' || tagName == 'object' || tagName == 'object') { + return false; + } + }, + _onClick: function (){ + if (!this.isDisabled()) { + this.fireEvent('click'); + } + }, + setTitle: function(text){ + var label = this.getDom('label'); + label.innerHTML = text; + } + }; + utils.inherits(Button, UIBase); + utils.extend(Button.prototype, Stateful); + +})(); + + +// ui/splitbutton.js +///import core +///import uicore +///import ui/stateful.js +(function (){ + var utils = baidu.editor.utils, + uiUtils = baidu.editor.ui.uiUtils, + domUtils = baidu.editor.dom.domUtils, + UIBase = baidu.editor.ui.UIBase, + Stateful = baidu.editor.ui.Stateful, + SplitButton = baidu.editor.ui.SplitButton = function (options){ + this.initOptions(options); + this.initSplitButton(); + }; + SplitButton.prototype = { + popup: null, + uiName: 'splitbutton', + title: '', + initSplitButton: function (){ + this.initUIBase(); + this.Stateful_init(); + var me = this; + if (this.popup != null) { + var popup = this.popup; + this.popup = null; + this.setPopup(popup); + } + }, + _UIBase_postRender: UIBase.prototype.postRender, + postRender: function (){ + this.Stateful_postRender(); + this._UIBase_postRender(); + }, + setPopup: function (popup){ + if (this.popup === popup) return; + if (this.popup != null) { + this.popup.dispose(); + } + popup.addListener('show', utils.bind(this._onPopupShow, this)); + popup.addListener('hide', utils.bind(this._onPopupHide, this)); + popup.addListener('postrender', utils.bind(function (){ + popup.getDom('body').appendChild( + uiUtils.createElementByHtml('
          ') + ); + popup.getDom().className += ' ' + this.className; + }, this)); + this.popup = popup; + }, + _onPopupShow: function (){ + this.addState('opened'); + }, + _onPopupHide: function (){ + this.removeState('opened'); + }, + getHtmlTpl: function (){ + return '
          ' + + '
          ' + + '
          ' + + '
          ' + + '
          ' + + '
          ' + + '
          ' + + '
          '; + }, + showPopup: function (){ + // 当popup往上弹出的时候,做特殊处理 + var rect = uiUtils.getClientRect(this.getDom()); + rect.top -= this.popup.SHADOW_RADIUS; + rect.height += this.popup.SHADOW_RADIUS; + this.popup.showAnchorRect(rect); + }, + _onArrowClick: function (event, el){ + if (!this.isDisabled()) { + this.showPopup(); + } + }, + _onButtonClick: function (){ + if (!this.isDisabled()) { + this.fireEvent('buttonclick'); + } + } + }; + utils.inherits(SplitButton, UIBase); + utils.extend(SplitButton.prototype, Stateful, true); + +})(); + + +// ui/colorbutton.js +///import core +///import uicore +///import ui/colorpicker.js +///import ui/popup.js +///import ui/splitbutton.js +(function (){ + var utils = baidu.editor.utils, + uiUtils = baidu.editor.ui.uiUtils, + ColorPicker = baidu.editor.ui.ColorPicker, + Popup = baidu.editor.ui.Popup, + SplitButton = baidu.editor.ui.SplitButton, + ColorButton = baidu.editor.ui.ColorButton = function (options){ + this.initOptions(options); + this.initColorButton(); + }; + ColorButton.prototype = { + initColorButton: function (){ + var me = this; + this.popup = new Popup({ + content: new ColorPicker({ + noColorText: me.editor.getLang("clearColor"), + editor:me.editor, + onpickcolor: function (t, color){ + me._onPickColor(color); + }, + onpicknocolor: function (t, color){ + me._onPickNoColor(color); + } + }), + editor:me.editor + }); + this.initSplitButton(); + }, + _SplitButton_postRender: SplitButton.prototype.postRender, + postRender: function (){ + this._SplitButton_postRender(); + this.getDom('button_body').appendChild( + uiUtils.createElementByHtml('
          ') + ); + this.getDom().className += ' edui-colorbutton'; + }, + setColor: function (color){ + this.getDom('colorlump').style.backgroundColor = color; + this.color = color; + }, + _onPickColor: function (color){ + if (this.fireEvent('pickcolor', color) !== false) { + this.setColor(color); + this.popup.hide(); + } + }, + _onPickNoColor: function (color){ + if (this.fireEvent('picknocolor') !== false) { + this.popup.hide(); + } + } + }; + utils.inherits(ColorButton, SplitButton); + +})(); + + +// ui/tablebutton.js +///import core +///import uicore +///import ui/popup.js +///import ui/tablepicker.js +///import ui/splitbutton.js +(function (){ + var utils = baidu.editor.utils, + Popup = baidu.editor.ui.Popup, + TablePicker = baidu.editor.ui.TablePicker, + SplitButton = baidu.editor.ui.SplitButton, + TableButton = baidu.editor.ui.TableButton = function (options){ + this.initOptions(options); + this.initTableButton(); + }; + TableButton.prototype = { + initTableButton: function (){ + var me = this; + this.popup = new Popup({ + content: new TablePicker({ + editor:me.editor, + onpicktable: function (t, numCols, numRows){ + me._onPickTable(numCols, numRows); + } + }), + 'editor':me.editor + }); + this.initSplitButton(); + }, + _onPickTable: function (numCols, numRows){ + if (this.fireEvent('picktable', numCols, numRows) !== false) { + this.popup.hide(); + } + } + }; + utils.inherits(TableButton, SplitButton); + +})(); + + +// ui/autotypesetpicker.js +///import core +///import uicore +(function () { + var utils = baidu.editor.utils, + UIBase = baidu.editor.ui.UIBase; + + var AutoTypeSetPicker = baidu.editor.ui.AutoTypeSetPicker = function (options) { + this.initOptions(options); + this.initAutoTypeSetPicker(); + }; + AutoTypeSetPicker.prototype = { + initAutoTypeSetPicker:function () { + this.initUIBase(); + }, + getHtmlTpl:function () { + var me = this.editor, + opt = me.options.autotypeset, + lang = me.getLang("autoTypeSet"); + + var textAlignInputName = 'textAlignValue' + me.uid, + imageBlockInputName = 'imageBlockLineValue' + me.uid, + symbolConverInputName = 'symbolConverValue' + me.uid; + + return '
          ' + + '
          ' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '' + + '
          ' + lang.mergeLine + '' + lang.delLine + '
          ' + lang.removeFormat + '' + lang.indent + '
          ' + lang.alignment + '' + + '' + me.getLang("justifyleft") + + '' + me.getLang("justifycenter") + + '' + me.getLang("justifyright") + + '
          ' + lang.imageFloat + '' + + '' + me.getLang("default") + + '' + me.getLang("justifyleft") + + '' + me.getLang("justifycenter") + + '' + me.getLang("justifyright") + + '
          ' + lang.removeFontsize + '' + lang.removeFontFamily + '
          ' + lang.removeHtml + '
          ' + lang.pasteFilter + '
          ' + lang.symbol + '' + + '' + lang.bdc2sb + + '' + lang.tobdc + '' + + '
          ' + + '
          ' + + '
          '; + + + }, + _UIBase_render:UIBase.prototype.render + }; + utils.inherits(AutoTypeSetPicker, UIBase); +})(); + + +// ui/autotypesetbutton.js +///import core +///import uicore +///import ui/popup.js +///import ui/autotypesetpicker.js +///import ui/splitbutton.js +(function (){ + var utils = baidu.editor.utils, + Popup = baidu.editor.ui.Popup, + AutoTypeSetPicker = baidu.editor.ui.AutoTypeSetPicker, + SplitButton = baidu.editor.ui.SplitButton, + AutoTypeSetButton = baidu.editor.ui.AutoTypeSetButton = function (options){ + this.initOptions(options); + this.initAutoTypeSetButton(); + }; + function getPara(me){ + + var opt = {}, + cont = me.getDom(), + editorId = me.editor.uid, + inputType = null, + attrName = null, + ipts = domUtils.getElementsByTagName(cont,"input"); + for(var i=ipts.length-1,ipt;ipt=ipts[i--];){ + inputType = ipt.getAttribute("type"); + if(inputType=="checkbox"){ + attrName = ipt.getAttribute("name"); + opt[attrName] && delete opt[attrName]; + if(ipt.checked){ + var attrValue = document.getElementById( attrName + "Value" + editorId ); + if(attrValue){ + if(/input/ig.test(attrValue.tagName)){ + opt[attrName] = attrValue.value; + } else { + var iptChilds = attrValue.getElementsByTagName("input"); + for(var j=iptChilds.length-1,iptchild;iptchild=iptChilds[j--];){ + if(iptchild.checked){ + opt[attrName] = iptchild.value; + break; + } + } + } + } else { + opt[attrName] = true; + } + } else { + opt[attrName] = false; + } + } else { + opt[ipt.getAttribute("value")] = ipt.checked; + } + + } + + var selects = domUtils.getElementsByTagName(cont,"select"); + for(var i=0,si;si=selects[i++];){ + var attr = si.getAttribute('name'); + opt[attr] = opt[attr] ? si.value : ''; + } + + utils.extend(me.editor.options.autotypeset,opt); + + me.editor.setPreferences('autotypeset', opt); + } + + AutoTypeSetButton.prototype = { + initAutoTypeSetButton: function (){ + + var me = this; + this.popup = new Popup({ + //传入配置参数 + content: new AutoTypeSetPicker({editor:me.editor}), + 'editor':me.editor, + hide : function(){ + if (!this._hidden && this.getDom()) { + getPara(this); + this.getDom().style.display = 'none'; + this._hidden = true; + this.fireEvent('hide'); + } + } + }); + var flag = 0; + this.popup.addListener('postRenderAfter',function(){ + var popupUI = this; + if(flag)return; + var cont = this.getDom(), + btn = cont.getElementsByTagName('button')[0]; + + btn.onclick = function(){ + getPara(popupUI); + me.editor.execCommand('autotypeset'); + popupUI.hide() + }; + + domUtils.on(cont, 'click', function(e) { + var target = e.target || e.srcElement, + editorId = me.editor.uid; + if (target && target.tagName == 'INPUT') { + + // 点击图片浮动的checkbox,去除对应的radio + if (target.name == 'imageBlockLine' || target.name == 'textAlign' || target.name == 'symbolConver') { + var checked = target.checked, + radioTd = document.getElementById( target.name + 'Value' + editorId), + radios = radioTd.getElementsByTagName('input'), + defalutSelect = { + 'imageBlockLine': 'none', + 'textAlign': 'left', + 'symbolConver': 'tobdc' + }; + + for (var i = 0; i < radios.length; i++) { + if (checked) { + if (radios[i].value == defalutSelect[target.name]) { + radios[i].checked = 'checked'; + } + } else { + radios[i].checked = false; + } + } + } + // 点击radio,选中对应的checkbox + if (target.name == ('imageBlockLineValue' + editorId) || target.name == ('textAlignValue' + editorId) || target.name == 'bdc') { + var checkboxs = target.parentNode.previousSibling.getElementsByTagName('input'); + checkboxs && (checkboxs[0].checked = true); + } + + getPara(popupUI); + } + }); + + flag = 1; + }); + this.initSplitButton(); + } + }; + utils.inherits(AutoTypeSetButton, SplitButton); + +})(); + + +// ui/cellalignpicker.js +///import core +///import uicore +(function () { + var utils = baidu.editor.utils, + Popup = baidu.editor.ui.Popup, + Stateful = baidu.editor.ui.Stateful, + UIBase = baidu.editor.ui.UIBase; + + /** + * 该参数将新增一个参数: selected, 参数类型为一个Object, 形如{ 'align': 'center', 'valign': 'top' }, 表示单元格的初始 + * 对齐状态为: 竖直居上,水平居中; 其中 align的取值为:'center', 'left', 'right'; valign的取值为: 'top', 'middle', 'bottom' + * @update 2013/4/2 hancong03@baidu.com + */ + var CellAlignPicker = baidu.editor.ui.CellAlignPicker = function (options) { + this.initOptions(options); + this.initSelected(); + this.initCellAlignPicker(); + }; + CellAlignPicker.prototype = { + //初始化选中状态, 该方法将根据传递进来的参数获取到应该选中的对齐方式图标的索引 + initSelected: function(){ + + var status = { + + valign: { + top: 0, + middle: 1, + bottom: 2 + }, + align: { + left: 0, + center: 1, + right: 2 + }, + count: 3 + + }, + result = -1; + + if( this.selected ) { + this.selectedIndex = status.valign[ this.selected.valign ] * status.count + status.align[ this.selected.align ]; + } + + }, + initCellAlignPicker:function () { + this.initUIBase(); + this.Stateful_init(); + }, + getHtmlTpl:function () { + + var alignType = [ 'left', 'center', 'right' ], + COUNT = 9, + tempClassName = null, + tempIndex = -1, + tmpl = []; + + + for( var i= 0; i'); + + tmpl.push( '
          ' ); + + tempIndex === 2 && tmpl.push(''); + + } + + return '
          ' + + '
          ' + + '' + + tmpl.join('') + + '
          ' + + '
          ' + + '
          '; + }, + getStateDom: function (){ + return this.target; + }, + _onClick: function (evt){ + var target= evt.target || evt.srcElement; + if(/icon/.test(target.className)){ + this.items[target.parentNode.getAttribute("index")].onclick(); + Popup.postHide(evt); + } + }, + _UIBase_render:UIBase.prototype.render + }; + utils.inherits(CellAlignPicker, UIBase); + utils.extend(CellAlignPicker.prototype, Stateful,true); +})(); + + + + + +// ui/pastepicker.js +///import core +///import uicore +(function () { + var utils = baidu.editor.utils, + Stateful = baidu.editor.ui.Stateful, + uiUtils = baidu.editor.ui.uiUtils, + UIBase = baidu.editor.ui.UIBase; + + var PastePicker = baidu.editor.ui.PastePicker = function (options) { + this.initOptions(options); + this.initPastePicker(); + }; + PastePicker.prototype = { + initPastePicker:function () { + this.initUIBase(); + this.Stateful_init(); + }, + getHtmlTpl:function () { + return '
          ' + + '
          ' + + '
          ' + this.editor.getLang("pasteOpt") + '
          ' + + '
          ' + + '
          ' + + '
          ' + + '
          ' + + '
          ' + + '
          ' + + '
          ' + + '
          ' + + '
          ' + + '
          ' + }, + getStateDom:function () { + return this.target; + }, + format:function (param) { + this.editor.ui._isTransfer = true; + this.editor.fireEvent('pasteTransfer', param); + }, + _onClick:function (cur) { + var node = domUtils.getNextDomNode(cur), + screenHt = uiUtils.getViewportRect().height, + subPop = uiUtils.getClientRect(node); + + if ((subPop.top + subPop.height) > screenHt) + node.style.top = (-subPop.height - cur.offsetHeight) + "px"; + else + node.style.top = ""; + + if (/hidden/ig.test(domUtils.getComputedStyle(node, "visibility"))) { + node.style.visibility = "visible"; + domUtils.addClass(cur, "edui-state-opened"); + } else { + node.style.visibility = "hidden"; + domUtils.removeClasses(cur, "edui-state-opened") + } + }, + _UIBase_render:UIBase.prototype.render + }; + utils.inherits(PastePicker, UIBase); + utils.extend(PastePicker.prototype, Stateful, true); +})(); + + + + + + +// ui/toolbar.js +(function (){ + var utils = baidu.editor.utils, + uiUtils = baidu.editor.ui.uiUtils, + UIBase = baidu.editor.ui.UIBase, + Toolbar = baidu.editor.ui.Toolbar = function (options){ + this.initOptions(options); + this.initToolbar(); + }; + Toolbar.prototype = { + items: null, + initToolbar: function (){ + this.items = this.items || []; + this.initUIBase(); + }, + add: function (item,index){ + if(index === undefined){ + this.items.push(item); + }else{ + this.items.splice(index,0,item) + } + + }, + getHtmlTpl: function (){ + var buff = []; + for (var i=0; i' + + buff.join('') + + '
          ' + }, + postRender: function (){ + var box = this.getDom(); + for (var i=0; i
          '; + }, + postRender:function () { + }, + queryAutoHide:function () { + return true; + } + }; + Menu.prototype = { + items:null, + uiName:'menu', + initMenu:function () { + this.items = this.items || []; + this.initPopup(); + this.initItems(); + }, + initItems:function () { + for (var i = 0; i < this.items.length; i++) { + var item = this.items[i]; + if (item == '-') { + this.items[i] = this.getSeparator(); + } else if (!(item instanceof MenuItem)) { + item.editor = this.editor; + item.theme = this.editor.options.theme; + this.items[i] = this.createItem(item); + } + } + }, + getSeparator:function () { + return menuSeparator; + }, + createItem:function (item) { + //新增一个参数menu, 该参数存储了menuItem所对应的menu引用 + item.menu = this; + return new MenuItem(item); + }, + _Popup_getContentHtmlTpl:Popup.prototype.getContentHtmlTpl, + getContentHtmlTpl:function () { + if (this.items.length == 0) { + return this._Popup_getContentHtmlTpl(); + } + var buff = []; + for (var i = 0; i < this.items.length; i++) { + var item = this.items[i]; + buff[i] = item.renderHtml(); + } + return ('
          ' + buff.join('') + '
          '); + }, + _Popup_postRender:Popup.prototype.postRender, + postRender:function () { + var me = this; + for (var i = 0; i < this.items.length; i++) { + var item = this.items[i]; + item.ownerMenu = this; + item.postRender(); + } + domUtils.on(this.getDom(), 'mouseover', function (evt) { + evt = evt || event; + var rel = evt.relatedTarget || evt.fromElement; + var el = me.getDom(); + if (!uiUtils.contains(el, rel) && el !== rel) { + me.fireEvent('over'); + } + }); + this._Popup_postRender(); + }, + queryAutoHide:function (el) { + if (el) { + if (uiUtils.contains(this.getDom(), el)) { + return false; + } + for (var i = 0; i < this.items.length; i++) { + var item = this.items[i]; + if (item.queryAutoHide(el) === false) { + return false; + } + } + } + }, + clearItems:function () { + for (var i = 0; i < this.items.length; i++) { + var item = this.items[i]; + clearTimeout(item._showingTimer); + clearTimeout(item._closingTimer); + if (item.subMenu) { + item.subMenu.destroy(); + } + } + this.items = []; + }, + destroy:function () { + if (this.getDom()) { + domUtils.remove(this.getDom()); + } + this.clearItems(); + }, + dispose:function () { + this.destroy(); + } + }; + utils.inherits(Menu, Popup); + + /** + * @update 2013/04/03 hancong03 新增一个参数menu, 该参数存储了menuItem所对应的menu引用 + * @type {Function} + */ + var MenuItem = baidu.editor.ui.MenuItem = function (options) { + this.initOptions(options); + this.initUIBase(); + this.Stateful_init(); + if (this.subMenu && !(this.subMenu instanceof Menu)) { + if (options.className && options.className.indexOf("aligntd") != -1) { + var me = this; + + //获取单元格对齐初始状态 + this.subMenu.selected = this.editor.queryCommandValue( 'cellalignment' ); + + this.subMenu = new Popup({ + content:new CellAlignPicker(this.subMenu), + parentMenu:me, + editor:me.editor, + destroy:function () { + if (this.getDom()) { + domUtils.remove(this.getDom()); + } + } + }); + this.subMenu.addListener("postRenderAfter", function () { + domUtils.on(this.getDom(), "mouseover", function () { + me.addState('opened'); + }); + }); + } else { + this.subMenu = new Menu(this.subMenu); + } + } + }; + MenuItem.prototype = { + label:'', + subMenu:null, + ownerMenu:null, + uiName:'menuitem', + alwalysHoverable:true, + getHtmlTpl:function () { + return '
          ' + + '
          ' + + this.renderLabelHtml() + + '
          ' + + '
          '; + }, + postRender:function () { + var me = this; + this.addListener('over', function () { + me.ownerMenu.fireEvent('submenuover', me); + if (me.subMenu) { + me.delayShowSubMenu(); + } + }); + if (this.subMenu) { + this.getDom().className += ' edui-hassubmenu'; + this.subMenu.render(); + this.addListener('out', function () { + me.delayHideSubMenu(); + }); + this.subMenu.addListener('over', function () { + clearTimeout(me._closingTimer); + me._closingTimer = null; + me.addState('opened'); + }); + this.ownerMenu.addListener('hide', function () { + me.hideSubMenu(); + }); + this.ownerMenu.addListener('submenuover', function (t, subMenu) { + if (subMenu !== me) { + me.delayHideSubMenu(); + } + }); + this.subMenu._bakQueryAutoHide = this.subMenu.queryAutoHide; + this.subMenu.queryAutoHide = function (el) { + if (el && uiUtils.contains(me.getDom(), el)) { + return false; + } + return this._bakQueryAutoHide(el); + }; + } + this.getDom().style.tabIndex = '-1'; + uiUtils.makeUnselectable(this.getDom()); + this.Stateful_postRender(); + }, + delayShowSubMenu:function () { + var me = this; + if (!me.isDisabled()) { + me.addState('opened'); + clearTimeout(me._showingTimer); + clearTimeout(me._closingTimer); + me._closingTimer = null; + me._showingTimer = setTimeout(function () { + me.showSubMenu(); + }, 250); + } + }, + delayHideSubMenu:function () { + var me = this; + if (!me.isDisabled()) { + me.removeState('opened'); + clearTimeout(me._showingTimer); + if (!me._closingTimer) { + me._closingTimer = setTimeout(function () { + if (!me.hasState('opened')) { + me.hideSubMenu(); + } + me._closingTimer = null; + }, 400); + } + } + }, + renderLabelHtml:function () { + return '
          ' + + '
          ' + + '
          ' + (this.label || '') + '
          '; + }, + getStateDom:function () { + return this.getDom(); + }, + queryAutoHide:function (el) { + if (this.subMenu && this.hasState('opened')) { + return this.subMenu.queryAutoHide(el); + } + }, + _onClick:function (event, this_) { + if (this.hasState('disabled')) return; + if (this.fireEvent('click', event, this_) !== false) { + if (this.subMenu) { + this.showSubMenu(); + } else { + Popup.postHide(event); + } + } + }, + showSubMenu:function () { + var rect = uiUtils.getClientRect(this.getDom()); + rect.right -= 5; + rect.left += 2; + rect.width -= 7; + rect.top -= 4; + rect.bottom += 4; + rect.height += 8; + this.subMenu.showAnchorRect(rect, true, true); + }, + hideSubMenu:function () { + this.subMenu.hide(); + } + }; + utils.inherits(MenuItem, UIBase); + utils.extend(MenuItem.prototype, Stateful, true); +})(); + + +// ui/combox.js +///import core +///import uicore +///import ui/menu.js +///import ui/splitbutton.js +(function (){ + // todo: menu和item提成通用list + var utils = baidu.editor.utils, + uiUtils = baidu.editor.ui.uiUtils, + Menu = baidu.editor.ui.Menu, + SplitButton = baidu.editor.ui.SplitButton, + Combox = baidu.editor.ui.Combox = function (options){ + this.initOptions(options); + this.initCombox(); + }; + Combox.prototype = { + uiName: 'combox', + onbuttonclick:function () { + this.showPopup(); + }, + initCombox: function (){ + var me = this; + this.items = this.items || []; + for (var i=0; i vpRect.right) { + left = vpRect.right - rect.width; + } + var top = offset.top; + if (top + rect.height > vpRect.bottom) { + top = vpRect.bottom - rect.height; + } + el.style.left = Math.max(left, 0) + 'px'; + el.style.top = Math.max(top, 0) + 'px'; + }, + showAtCenter: function (){ + + var vpRect = uiUtils.getViewportRect(); + + if ( !this.fullscreen ) { + this.getDom().style.display = ''; + var popSize = this.fitSize(); + var titleHeight = this.getDom('titlebar').offsetHeight | 0; + var left = vpRect.width / 2 - popSize.width / 2; + var top = vpRect.height / 2 - (popSize.height - titleHeight) / 2 - titleHeight; + var popEl = this.getDom(); + this.safeSetOffset({ + left: Math.max(left | 0, 0), + top: Math.max(top | 0, 0) + }); + if (!domUtils.hasClass(popEl, 'edui-state-centered')) { + popEl.className += ' edui-state-centered'; + } + } else { + var dialogWrapNode = this.getDom(), + contentNode = this.getDom('content'); + + dialogWrapNode.style.display = "block"; + + var wrapRect = UE.ui.uiUtils.getClientRect( dialogWrapNode ), + contentRect = UE.ui.uiUtils.getClientRect( contentNode ); + dialogWrapNode.style.left = "-100000px"; + + contentNode.style.width = ( vpRect.width - wrapRect.width + contentRect.width ) + "px"; + contentNode.style.height = ( vpRect.height - wrapRect.height + contentRect.height ) + "px"; + + dialogWrapNode.style.width = vpRect.width + "px"; + dialogWrapNode.style.height = vpRect.height + "px"; + dialogWrapNode.style.left = 0; + + //保存环境的overflow值 + this._originalContext = { + html: { + overflowX: document.documentElement.style.overflowX, + overflowY: document.documentElement.style.overflowY + }, + body: { + overflowX: document.body.style.overflowX, + overflowY: document.body.style.overflowY + } + }; + + document.documentElement.style.overflowX = 'hidden'; + document.documentElement.style.overflowY = 'hidden'; + document.body.style.overflowX = 'hidden'; + document.body.style.overflowY = 'hidden'; + + } + + this._show(); + }, + getContentHtml: function (){ + var contentHtml = ''; + if (typeof this.content == 'string') { + contentHtml = this.content; + } else if (this.iframeUrl) { + contentHtml = ''; + } + return contentHtml; + }, + getHtmlTpl: function (){ + var footHtml = ''; + + if (this.buttons) { + var buff = []; + for (var i=0; i' + buff.join('') + '
          ' + + ''; + } + + return '
          ' + + '
          ' + + '
          ' + + '
          ' + + '' + (this.title || '') + '' + + '
          ' + + this.closeButton.renderHtml() + + '
          ' + + '
          '+ ( this.autoReset ? '' : this.getContentHtml()) +'
          ' + + footHtml + + '
          '; + }, + postRender: function (){ + // todo: 保持居中/记住上次关闭位置选项 + if (!this.modalMask.getDom()) { + this.modalMask.render(); + this.modalMask.hide(); + } + if (!this.dragMask.getDom()) { + this.dragMask.render(); + this.dragMask.hide(); + } + var me = this; + this.addListener('show', function (){ + me.modalMask.show(this.getDom().style.zIndex - 2); + }); + this.addListener('hide', function (){ + me.modalMask.hide(); + }); + if (this.buttons) { + for (var i=0; i'; + me.editor.container.style.zIndex && (this.getDom().style.zIndex = me.editor.container.style.zIndex * 1 + 1); + } + } + // canSideUp:false, + // canSideLeft:false + }); + this.onbuttonclick = function(){ + this.showPopup(); + }; + this.initSplitButton(); + } + + }; + + utils.inherits(MultiMenuPop, SplitButton); +})(); + + +// ui/shortcutmenu.js +(function () { + var UI = baidu.editor.ui, + UIBase = UI.UIBase, + uiUtils = UI.uiUtils, + utils = baidu.editor.utils, + domUtils = baidu.editor.dom.domUtils; + + var allMenus = [],//存储所有快捷菜单 + timeID, + isSubMenuShow = false;//是否有子pop显示 + + var ShortCutMenu = UI.ShortCutMenu = function (options) { + this.initOptions (options); + this.initShortCutMenu (); + }; + + ShortCutMenu.postHide = hideAllMenu; + + ShortCutMenu.prototype = { + isHidden : true , + SPACE : 5 , + initShortCutMenu : function () { + this.items = this.items || []; + this.initUIBase (); + this.initItems (); + this.initEvent (); + allMenus.push (this); + } , + initEvent : function () { + var me = this, + doc = me.editor.document; + + domUtils.on (doc , "mousemove" , function (e) { + if (me.isHidden === false) { + //有pop显示就不隐藏快捷菜单 + if (me.getSubMenuMark () || me.eventType == "contextmenu") return; + + + var flag = true, + el = me.getDom (), + wt = el.offsetWidth, + ht = el.offsetHeight, + distanceX = wt / 2 + me.SPACE,//距离中心X标准 + distanceY = ht / 2,//距离中心Y标准 + x = Math.abs (e.screenX - me.left),//离中心距离横坐标 + y = Math.abs (e.screenY - me.top);//离中心距离纵坐标 + + clearTimeout (timeID); + timeID = setTimeout (function () { + if (y > 0 && y < distanceY) { + me.setOpacity (el , "1"); + } else if (y > distanceY && y < distanceY + 70) { + me.setOpacity (el , "0.5"); + flag = false; + } else if (y > distanceY + 70 && y < distanceY + 140) { + me.hide (); + } + + if (flag && x > 0 && x < distanceX) { + me.setOpacity (el , "1") + } else if (x > distanceX && x < distanceX + 70) { + me.setOpacity (el , "0.5") + } else if (x > distanceX + 70 && x < distanceX + 140) { + me.hide (); + } + }); + } + }); + + //ie\ff下 mouseout不准 + if (browser.chrome) { + domUtils.on (doc , "mouseout" , function (e) { + var relatedTgt = e.relatedTarget || e.toElement; + + if (relatedTgt == null || relatedTgt.tagName == "HTML") { + me.hide (); + } + }); + } + + me.editor.addListener ("afterhidepop" , function () { + if (!me.isHidden) { + isSubMenuShow = true; + } + }); + + } , + initItems : function () { + if (utils.isArray (this.items)) { + for (var i = 0, len = this.items.length ; i < len ; i++) { + var item = this.items[i].toLowerCase (); + + if (UI[item]) { + this.items[i] = new UI[item] (this.editor); + this.items[i].className += " edui-shortcutsubmenu "; + } + } + } + } , + setOpacity : function (el , value) { + if (browser.ie && browser.version < 9) { + el.style.filter = "alpha(opacity = " + parseFloat (value) * 100 + ");" + } else { + el.style.opacity = value; + } + } , + getSubMenuMark : function () { + isSubMenuShow = false; + var layerEle = uiUtils.getFixedLayer (); + var list = domUtils.getElementsByTagName (layerEle , "div" , function (node) { + return domUtils.hasClass (node , "edui-shortcutsubmenu edui-popup") + }); + + for (var i = 0, node ; node = list[i++] ;) { + if (node.style.display != "none") { + isSubMenuShow = true; + } + } + return isSubMenuShow; + } , + show : function (e , hasContextmenu) { + var me = this, + offset = {}, + el = this.getDom (), + fixedlayer = uiUtils.getFixedLayer (); + + function setPos (offset) { + if (offset.left < 0) { + offset.left = 0; + } + if (offset.top < 0) { + offset.top = 0; + } + el.style.cssText = "position:absolute;left:" + offset.left + "px;top:" + offset.top + "px;"; + } + + function setPosByCxtMenu (menu) { + if (!menu.tagName) { + menu = menu.getDom (); + } + offset.left = parseInt (menu.style.left); + offset.top = parseInt (menu.style.top); + offset.top -= el.offsetHeight + 15; + setPos (offset); + } + + + me.eventType = e.type; + el.style.cssText = "display:block;left:-9999px"; + + if (e.type == "contextmenu" && hasContextmenu) { + var menu = domUtils.getElementsByTagName (fixedlayer , "div" , "edui-contextmenu")[0]; + if (menu) { + setPosByCxtMenu (menu) + } else { + me.editor.addListener ("aftershowcontextmenu" , function (type , menu) { + setPosByCxtMenu (menu); + }); + } + } else { + offset = uiUtils.getViewportOffsetByEvent (e); + offset.top -= el.offsetHeight + me.SPACE; + offset.left += me.SPACE + 20; + setPos (offset); + me.setOpacity (el , 0.2); + } + + + me.isHidden = false; + me.left = e.screenX + el.offsetWidth / 2 - me.SPACE; + me.top = e.screenY - (el.offsetHeight / 2) - me.SPACE; + + if (me.editor) { + el.style.zIndex = me.editor.container.style.zIndex * 1 + 10; + fixedlayer.style.zIndex = el.style.zIndex - 1; + } + } , + hide : function () { + if (this.getDom ()) { + this.getDom ().style.display = "none"; + } + this.isHidden = true; + } , + postRender : function () { + if (utils.isArray (this.items)) { + for (var i = 0, item ; item = this.items[i++] ;) { + item.postRender (); + } + } + } , + getHtmlTpl : function () { + var buff; + if (utils.isArray (this.items)) { + buff = []; + for (var i = 0 ; i < this.items.length ; i++) { + buff[i] = this.items[i].renderHtml (); + } + buff = buff.join (""); + } else { + buff = this.items; + } + + return '
          ' + + buff + + '
          '; + } + }; + + utils.inherits (ShortCutMenu , UIBase); + + function hideAllMenu (e) { + var tgt = e.target || e.srcElement, + cur = domUtils.findParent (tgt , function (node) { + return domUtils.hasClass (node , "edui-shortcutmenu") || domUtils.hasClass (node , "edui-popup"); + } , true); + + if (!cur) { + for (var i = 0, menu ; menu = allMenus[i++] ;) { + menu.hide () + } + } + } + + domUtils.on (document , 'mousedown' , function (e) { + hideAllMenu (e); + }); + + domUtils.on (window , 'scroll' , function (e) { + hideAllMenu (e); + }); + +}) (); + + +// ui/breakline.js +(function (){ + var utils = baidu.editor.utils, + UIBase = baidu.editor.ui.UIBase, + Breakline = baidu.editor.ui.Breakline = function (options){ + this.initOptions(options); + this.initSeparator(); + }; + Breakline.prototype = { + uiName: 'Breakline', + initSeparator: function (){ + this.initUIBase(); + }, + getHtmlTpl: function (){ + return '
          '; + } + }; + utils.inherits(Breakline, UIBase); + +})(); + + +// ui/message.js +///import core +///import uicore +(function () { + var utils = baidu.editor.utils, + domUtils = baidu.editor.dom.domUtils, + UIBase = baidu.editor.ui.UIBase, + Message = baidu.editor.ui.Message = function (options){ + this.initOptions(options); + this.initMessage(); + }; + + Message.prototype = { + initMessage: function (){ + this.initUIBase(); + }, + getHtmlTpl: function (){ + return '
          ' + + '
          ×
          ' + + '
          ' + + ' ' + + '
          ' + + '
          ' + + '
          ' + + '
          ' + + '
          '; + }, + reset: function(opt){ + var me = this; + if (!opt.keepshow) { + clearTimeout(this.timer); + me.timer = setTimeout(function(){ + me.hide(); + }, opt.timeout || 4000); + } + + opt.content !== undefined && me.setContent(opt.content); + opt.type !== undefined && me.setType(opt.type); + + me.show(); + }, + postRender: function(){ + var me = this, + closer = this.getDom('closer'); + closer && domUtils.on(closer, 'click', function(){ + me.hide(); + }); + }, + setContent: function(content){ + this.getDom('content').innerHTML = content; + }, + setType: function(type){ + type = type || 'info'; + var body = this.getDom('body'); + body.className = body.className.replace(/edui-message-type-[\w-]+/, 'edui-message-type-' + type); + }, + getContent: function(){ + return this.getDom('content').innerHTML; + }, + getType: function(){ + var arr = this.getDom('body').match(/edui-message-type-([\w-]+)/); + return arr ? arr[1]:''; + }, + show: function (){ + this.getDom().style.display = 'block'; + }, + hide: function (){ + var dom = this.getDom(); + if (dom) { + dom.style.display = 'none'; + dom.parentNode && dom.parentNode.removeChild(dom); + } + } + }; + + utils.inherits(Message, UIBase); + +})(); + + +// adapter/editorui.js +//ui跟编辑器的适配層 +//那个按钮弹出是dialog,是下拉筐等都是在这个js中配置 +//自己写的ui也要在这里配置,放到baidu.editor.ui下边,当编辑器实例化的时候会根据ueditor.config中的toolbars找到相应的进行实例化 +(function () { + var utils = baidu.editor.utils; + var editorui = baidu.editor.ui; + var _Dialog = editorui.Dialog; + editorui.buttons = {}; + + editorui.Dialog = function (options) { + var dialog = new _Dialog(options); + dialog.addListener('hide', function () { + + if (dialog.editor) { + var editor = dialog.editor; + try { + if (browser.gecko) { + var y = editor.window.scrollY, + x = editor.window.scrollX; + editor.body.focus(); + editor.window.scrollTo(x, y); + } else { + editor.focus(); + } + + + } catch (ex) { + } + } + }); + return dialog; + }; + + var iframeUrlMap = { + 'anchor':'~/dialogs/anchor/anchor.html', + 'insertimage':'~/dialogs/image/image.html', + 'link':'~/dialogs/link/link.html', + 'spechars':'~/dialogs/spechars/spechars.html', + 'searchreplace':'~/dialogs/searchreplace/searchreplace.html', + 'map':'~/dialogs/map/map.html', + 'gmap':'~/dialogs/gmap/gmap.html', + 'insertvideo':'~/dialogs/video/video.html', + 'help':'~/dialogs/help/help.html', + 'preview':'~/dialogs/preview/preview.html', + 'emotion':'~/dialogs/emotion/emotion.html', + 'wordimage':'~/dialogs/wordimage/wordimage.html', + 'attachment':'~/dialogs/attachment/attachment.html', + 'insertframe':'~/dialogs/insertframe/insertframe.html', + 'edittip':'~/dialogs/table/edittip.html', + 'edittable':'~/dialogs/table/edittable.html', + 'edittd':'~/dialogs/table/edittd.html', + 'webapp':'~/dialogs/webapp/webapp.html', + 'snapscreen':'~/dialogs/snapscreen/snapscreen.html', + 'scrawl':'~/dialogs/scrawl/scrawl.html', + 'music':'~/dialogs/music/music.html', + 'template':'~/dialogs/template/template.html', + 'background':'~/dialogs/background/background.html', + 'charts': '~/dialogs/charts/charts.html' + }; + //为工具栏添加按钮,以下都是统一的按钮触发命令,所以写在一起 + var btnCmds = ['undo', 'redo', 'formatmatch', + 'bold', 'italic', 'underline', 'fontborder', 'touppercase', 'tolowercase', + 'strikethrough', 'subscript', 'superscript', 'source', 'indent', 'outdent', + 'blockquote', 'pasteplain', 'pagebreak', + 'selectall', 'print','horizontal', 'removeformat', 'time', 'date', 'unlink', + 'insertparagraphbeforetable', 'insertrow', 'insertcol', 'mergeright', 'mergedown', 'deleterow', + 'deletecol', 'splittorows', 'splittocols', 'splittocells', 'mergecells', 'deletetable', 'drafts']; + + for (var i = 0, ci; ci = btnCmds[i++];) { + ci = ci.toLowerCase(); + editorui[ci] = function (cmd) { + return function (editor) { + var ui = new editorui.Button({ + className:'edui-for-' + cmd, + title:editor.options.labelMap[cmd] || editor.getLang("labelMap." + cmd) || '', + onclick:function () { + editor.execCommand(cmd); + }, + theme:editor.options.theme, + showText:false + }); + editorui.buttons[cmd] = ui; + editor.addListener('selectionchange', function (type, causeByUi, uiReady) { + var state = editor.queryCommandState(cmd); + if (state == -1) { + ui.setDisabled(true); + ui.setChecked(false); + } else { + if (!uiReady) { + ui.setDisabled(false); + ui.setChecked(state); + } + } + }); + return ui; + }; + }(ci); + } + + //清除文档 + editorui.cleardoc = function (editor) { + var ui = new editorui.Button({ + className:'edui-for-cleardoc', + title:editor.options.labelMap.cleardoc || editor.getLang("labelMap.cleardoc") || '', + theme:editor.options.theme, + onclick:function () { + if (confirm(editor.getLang("confirmClear"))) { + editor.execCommand('cleardoc'); + } + } + }); + editorui.buttons["cleardoc"] = ui; + editor.addListener('selectionchange', function () { + ui.setDisabled(editor.queryCommandState('cleardoc') == -1); + }); + return ui; + }; + + //排版,图片排版,文字方向 + var typeset = { + 'justify':['left', 'right', 'center', 'justify'], + 'imagefloat':['none', 'left', 'center', 'right'], + 'directionality':['ltr', 'rtl'] + }; + + for (var p in typeset) { + + (function (cmd, val) { + for (var i = 0, ci; ci = val[i++];) { + (function (cmd2) { + editorui[cmd.replace('float', '') + cmd2] = function (editor) { + var ui = new editorui.Button({ + className:'edui-for-' + cmd.replace('float', '') + cmd2, + title:editor.options.labelMap[cmd.replace('float', '') + cmd2] || editor.getLang("labelMap." + cmd.replace('float', '') + cmd2) || '', + theme:editor.options.theme, + onclick:function () { + editor.execCommand(cmd, cmd2); + } + }); + editorui.buttons[cmd] = ui; + editor.addListener('selectionchange', function (type, causeByUi, uiReady) { + ui.setDisabled(editor.queryCommandState(cmd) == -1); + ui.setChecked(editor.queryCommandValue(cmd) == cmd2 && !uiReady); + }); + return ui; + }; + })(ci) + } + })(p, typeset[p]) + } + + //字体颜色和背景颜色 + for (var i = 0, ci; ci = ['backcolor', 'forecolor'][i++];) { + editorui[ci] = function (cmd) { + return function (editor) { + var ui = new editorui.ColorButton({ + className:'edui-for-' + cmd, + color:'default', + title:editor.options.labelMap[cmd] || editor.getLang("labelMap." + cmd) || '', + editor:editor, + onpickcolor:function (t, color) { + editor.execCommand(cmd, color); + }, + onpicknocolor:function () { + editor.execCommand(cmd, 'default'); + this.setColor('transparent'); + this.color = 'default'; + }, + onbuttonclick:function () { + editor.execCommand(cmd, this.color); + } + }); + editorui.buttons[cmd] = ui; + editor.addListener('selectionchange', function () { + ui.setDisabled(editor.queryCommandState(cmd) == -1); + }); + return ui; + }; + }(ci); + } + + + var dialogBtns = { + noOk:['searchreplace', 'help', 'spechars', 'webapp','preview'], + ok:['attachment', 'anchor', 'link', 'insertimage', 'map', 'gmap', 'insertframe', 'wordimage', + 'insertvideo', 'insertframe', 'edittip', 'edittable', 'edittd', 'scrawl', 'template', 'music', 'background', 'charts'] + }; + + for (var p in dialogBtns) { + (function (type, vals) { + for (var i = 0, ci; ci = vals[i++];) { + //todo opera下存在问题 + if (browser.opera && ci === "searchreplace") { + continue; + } + (function (cmd) { + editorui[cmd] = function (editor, iframeUrl, title) { + iframeUrl = iframeUrl || (editor.options.iframeUrlMap || {})[cmd] || iframeUrlMap[cmd]; + title = editor.options.labelMap[cmd] || editor.getLang("labelMap." + cmd) || ''; + + var dialog; + //没有iframeUrl不创建dialog + if (iframeUrl) { + dialog = new editorui.Dialog(utils.extend({ + iframeUrl:editor.ui.mapUrl(iframeUrl), + editor:editor, + className:'edui-for-' + cmd, + title:title, + holdScroll: cmd === 'insertimage', + fullscreen: /charts|preview/.test(cmd), + closeDialog:editor.getLang("closeDialog") + }, type == 'ok' ? { + buttons:[ + { + className:'edui-okbutton', + label:editor.getLang("ok"), + editor:editor, + onclick:function () { + dialog.close(true); + } + }, + { + className:'edui-cancelbutton', + label:editor.getLang("cancel"), + editor:editor, + onclick:function () { + dialog.close(false); + } + } + ] + } : {})); + + editor.ui._dialogs[cmd + "Dialog"] = dialog; + } + + var ui = new editorui.Button({ + className:'edui-for-' + cmd, + title:title, + onclick:function () { + if (dialog) { + switch (cmd) { + case "wordimage": + var images = editor.execCommand("wordimage"); + if (images && images.length) { + dialog.render(); + dialog.open(); + } + break; + case "scrawl": + if (editor.queryCommandState("scrawl") != -1) { + dialog.render(); + dialog.open(); + } + + break; + default: + dialog.render(); + dialog.open(); + } + } + }, + theme:editor.options.theme, + disabled:(cmd == 'scrawl' && editor.queryCommandState("scrawl") == -1) || ( cmd == 'charts' ) + }); + editorui.buttons[cmd] = ui; + editor.addListener('selectionchange', function () { + //只存在于右键菜单而无工具栏按钮的ui不需要检测状态 + var unNeedCheckState = {'edittable':1}; + if (cmd in unNeedCheckState)return; + + var state = editor.queryCommandState(cmd); + if (ui.getDom()) { + ui.setDisabled(state == -1); + ui.setChecked(state); + } + + }); + + return ui; + }; + })(ci.toLowerCase()) + } + })(p, dialogBtns[p]); + } + + editorui.snapscreen = function (editor, iframeUrl, title) { + title = editor.options.labelMap['snapscreen'] || editor.getLang("labelMap.snapscreen") || ''; + var ui = new editorui.Button({ + className:'edui-for-snapscreen', + title:title, + onclick:function () { + editor.execCommand("snapscreen"); + }, + theme:editor.options.theme + + }); + editorui.buttons['snapscreen'] = ui; + iframeUrl = iframeUrl || (editor.options.iframeUrlMap || {})["snapscreen"] || iframeUrlMap["snapscreen"]; + if (iframeUrl) { + var dialog = new editorui.Dialog({ + iframeUrl:editor.ui.mapUrl(iframeUrl), + editor:editor, + className:'edui-for-snapscreen', + title:title, + buttons:[ + { + className:'edui-okbutton', + label:editor.getLang("ok"), + editor:editor, + onclick:function () { + dialog.close(true); + } + }, + { + className:'edui-cancelbutton', + label:editor.getLang("cancel"), + editor:editor, + onclick:function () { + dialog.close(false); + } + } + ] + + }); + dialog.render(); + editor.ui._dialogs["snapscreenDialog"] = dialog; + } + editor.addListener('selectionchange', function () { + ui.setDisabled(editor.queryCommandState('snapscreen') == -1); + }); + return ui; + }; + + editorui.insertcode = function (editor, list, title) { + list = editor.options['insertcode'] || []; + title = editor.options.labelMap['insertcode'] || editor.getLang("labelMap.insertcode") || ''; + // if (!list.length) return; + var items = []; + utils.each(list,function(key,val){ + items.push({ + label:key, + value:val, + theme:editor.options.theme, + renderLabelHtml:function () { + return '
          ' + (this.label || '') + '
          '; + } + }); + }); + + var ui = new editorui.Combox({ + editor:editor, + items:items, + onselect:function (t, index) { + editor.execCommand('insertcode', this.items[index].value); + }, + onbuttonclick:function () { + this.showPopup(); + }, + title:title, + initValue:title, + className:'edui-for-insertcode', + indexByValue:function (value) { + if (value) { + for (var i = 0, ci; ci = this.items[i]; i++) { + if (ci.value.indexOf(value) != -1) + return i; + } + } + + return -1; + } + }); + editorui.buttons['insertcode'] = ui; + editor.addListener('selectionchange', function (type, causeByUi, uiReady) { + if (!uiReady) { + var state = editor.queryCommandState('insertcode'); + if (state == -1) { + ui.setDisabled(true); + } else { + ui.setDisabled(false); + var value = editor.queryCommandValue('insertcode'); + if(!value){ + ui.setValue(title); + return; + } + //trace:1871 ie下从源码模式切换回来时,字体会带单引号,而且会有逗号 + value && (value = value.replace(/['"]/g, '').split(',')[0]); + ui.setValue(value); + + } + } + + }); + return ui; + }; + editorui.fontfamily = function (editor, list, title) { + + list = editor.options['fontfamily'] || []; + title = editor.options.labelMap['fontfamily'] || editor.getLang("labelMap.fontfamily") || ''; + if (!list.length) return; + for (var i = 0, ci, items = []; ci = list[i]; i++) { + var langLabel = editor.getLang('fontfamily')[ci.name] || ""; + (function (key, val) { + items.push({ + label:key, + value:val, + theme:editor.options.theme, + renderLabelHtml:function () { + return '
          ' + (this.label || '') + '
          '; + } + }); + })(ci.label || langLabel, ci.val) + } + var ui = new editorui.Combox({ + editor:editor, + items:items, + onselect:function (t, index) { + editor.execCommand('FontFamily', this.items[index].value); + }, + onbuttonclick:function () { + this.showPopup(); + }, + title:title, + initValue:title, + className:'edui-for-fontfamily', + indexByValue:function (value) { + if (value) { + for (var i = 0, ci; ci = this.items[i]; i++) { + if (ci.value.indexOf(value) != -1) + return i; + } + } + + return -1; + } + }); + editorui.buttons['fontfamily'] = ui; + editor.addListener('selectionchange', function (type, causeByUi, uiReady) { + if (!uiReady) { + var state = editor.queryCommandState('FontFamily'); + if (state == -1) { + ui.setDisabled(true); + } else { + ui.setDisabled(false); + var value = editor.queryCommandValue('FontFamily'); + //trace:1871 ie下从源码模式切换回来时,字体会带单引号,而且会有逗号 + value && (value = value.replace(/['"]/g, '').split(',')[0]); + ui.setValue(value); + + } + } + + }); + return ui; + }; + + editorui.fontsize = function (editor, list, title) { + title = editor.options.labelMap['fontsize'] || editor.getLang("labelMap.fontsize") || ''; + list = list || editor.options['fontsize'] || []; + if (!list.length) return; + var items = []; + for (var i = 0; i < list.length; i++) { + var size = list[i] + 'px'; + items.push({ + label:size, + value:size, + theme:editor.options.theme, + renderLabelHtml:function () { + return '
          ' + (this.label || '') + '
          '; + } + }); + } + var ui = new editorui.Combox({ + editor:editor, + items:items, + title:title, + initValue:title, + onselect:function (t, index) { + editor.execCommand('FontSize', this.items[index].value); + }, + onbuttonclick:function () { + this.showPopup(); + }, + className:'edui-for-fontsize' + }); + editorui.buttons['fontsize'] = ui; + editor.addListener('selectionchange', function (type, causeByUi, uiReady) { + if (!uiReady) { + var state = editor.queryCommandState('FontSize'); + if (state == -1) { + ui.setDisabled(true); + } else { + ui.setDisabled(false); + ui.setValue(editor.queryCommandValue('FontSize')); + } + } + + }); + return ui; + }; + + editorui.paragraph = function (editor, list, title) { + title = editor.options.labelMap['paragraph'] || editor.getLang("labelMap.paragraph") || ''; + list = editor.options['paragraph'] || []; + if (utils.isEmptyObject(list)) return; + var items = []; + for (var i in list) { + items.push({ + value:i, + label:list[i] || editor.getLang("paragraph")[i], + theme:editor.options.theme, + renderLabelHtml:function () { + return '
          ' + (this.label || '') + '
          '; + } + }) + } + var ui = new editorui.Combox({ + editor:editor, + items:items, + title:title, + initValue:title, + className:'edui-for-paragraph', + onselect:function (t, index) { + editor.execCommand('Paragraph', this.items[index].value); + }, + onbuttonclick:function () { + this.showPopup(); + } + }); + editorui.buttons['paragraph'] = ui; + editor.addListener('selectionchange', function (type, causeByUi, uiReady) { + if (!uiReady) { + var state = editor.queryCommandState('Paragraph'); + if (state == -1) { + ui.setDisabled(true); + } else { + ui.setDisabled(false); + var value = editor.queryCommandValue('Paragraph'); + var index = ui.indexByValue(value); + if (index != -1) { + ui.setValue(value); + } else { + ui.setValue(ui.initValue); + } + } + } + + }); + return ui; + }; + + + //自定义标题 + editorui.customstyle = function (editor) { + var list = editor.options['customstyle'] || [], + title = editor.options.labelMap['customstyle'] || editor.getLang("labelMap.customstyle") || ''; + if (!list.length)return; + var langCs = editor.getLang('customstyle'); + for (var i = 0, items = [], t; t = list[i++];) { + (function (t) { + var ck = {}; + ck.label = t.label ? t.label : langCs[t.name]; + ck.style = t.style; + ck.className = t.className; + ck.tag = t.tag; + items.push({ + label:ck.label, + value:ck, + theme:editor.options.theme, + renderLabelHtml:function () { + return '
          ' + '<' + ck.tag + ' ' + (ck.className ? ' class="' + ck.className + '"' : "") + + (ck.style ? ' style="' + ck.style + '"' : "") + '>' + ck.label + "<\/" + ck.tag + ">" + + '
          '; + } + }); + })(t); + } + + var ui = new editorui.Combox({ + editor:editor, + items:items, + title:title, + initValue:title, + className:'edui-for-customstyle', + onselect:function (t, index) { + editor.execCommand('customstyle', this.items[index].value); + }, + onbuttonclick:function () { + this.showPopup(); + }, + indexByValue:function (value) { + for (var i = 0, ti; ti = this.items[i++];) { + if (ti.label == value) { + return i - 1 + } + } + return -1; + } + }); + editorui.buttons['customstyle'] = ui; + editor.addListener('selectionchange', function (type, causeByUi, uiReady) { + if (!uiReady) { + var state = editor.queryCommandState('customstyle'); + if (state == -1) { + ui.setDisabled(true); + } else { + ui.setDisabled(false); + var value = editor.queryCommandValue('customstyle'); + var index = ui.indexByValue(value); + if (index != -1) { + ui.setValue(value); + } else { + ui.setValue(ui.initValue); + } + } + } + + }); + return ui; + }; + editorui.inserttable = function (editor, iframeUrl, title) { + title = editor.options.labelMap['inserttable'] || editor.getLang("labelMap.inserttable") || ''; + var ui = new editorui.TableButton({ + editor:editor, + title:title, + className:'edui-for-inserttable', + onpicktable:function (t, numCols, numRows) { + editor.execCommand('InsertTable', {numRows:numRows, numCols:numCols, border:1}); + }, + onbuttonclick:function () { + this.showPopup(); + } + }); + editorui.buttons['inserttable'] = ui; + editor.addListener('selectionchange', function () { + ui.setDisabled(editor.queryCommandState('inserttable') == -1); + }); + return ui; + }; + + editorui.lineheight = function (editor) { + var val = editor.options.lineheight || []; + if (!val.length)return; + for (var i = 0, ci, items = []; ci = val[i++];) { + items.push({ + //todo:写死了 + label:ci, + value:ci, + theme:editor.options.theme, + onclick:function () { + editor.execCommand("lineheight", this.value); + } + }) + } + var ui = new editorui.MenuButton({ + editor:editor, + className:'edui-for-lineheight', + title:editor.options.labelMap['lineheight'] || editor.getLang("labelMap.lineheight") || '', + items:items, + onbuttonclick:function () { + var value = editor.queryCommandValue('LineHeight') || this.value; + editor.execCommand("LineHeight", value); + } + }); + editorui.buttons['lineheight'] = ui; + editor.addListener('selectionchange', function () { + var state = editor.queryCommandState('LineHeight'); + if (state == -1) { + ui.setDisabled(true); + } else { + ui.setDisabled(false); + var value = editor.queryCommandValue('LineHeight'); + value && ui.setValue((value + '').replace(/cm/, '')); + ui.setChecked(state) + } + }); + return ui; + }; + + var rowspacings = ['top', 'bottom']; + for (var r = 0, ri; ri = rowspacings[r++];) { + (function (cmd) { + editorui['rowspacing' + cmd] = function (editor) { + var val = editor.options['rowspacing' + cmd] || []; + if (!val.length) return null; + for (var i = 0, ci, items = []; ci = val[i++];) { + items.push({ + label:ci, + value:ci, + theme:editor.options.theme, + onclick:function () { + editor.execCommand("rowspacing", this.value, cmd); + } + }) + } + var ui = new editorui.MenuButton({ + editor:editor, + className:'edui-for-rowspacing' + cmd, + title:editor.options.labelMap['rowspacing' + cmd] || editor.getLang("labelMap.rowspacing" + cmd) || '', + items:items, + onbuttonclick:function () { + var value = editor.queryCommandValue('rowspacing', cmd) || this.value; + editor.execCommand("rowspacing", value, cmd); + } + }); + editorui.buttons[cmd] = ui; + editor.addListener('selectionchange', function () { + var state = editor.queryCommandState('rowspacing', cmd); + if (state == -1) { + ui.setDisabled(true); + } else { + ui.setDisabled(false); + var value = editor.queryCommandValue('rowspacing', cmd); + value && ui.setValue((value + '').replace(/%/, '')); + ui.setChecked(state) + } + }); + return ui; + } + })(ri) + } + //有序,无序列表 + var lists = ['insertorderedlist', 'insertunorderedlist']; + for (var l = 0, cl; cl = lists[l++];) { + (function (cmd) { + editorui[cmd] = function (editor) { + var vals = editor.options[cmd], + _onMenuClick = function () { + editor.execCommand(cmd, this.value); + }, items = []; + for (var i in vals) { + items.push({ + label:vals[i] || editor.getLang()[cmd][i] || "", + value:i, + theme:editor.options.theme, + onclick:_onMenuClick + }) + } + var ui = new editorui.MenuButton({ + editor:editor, + className:'edui-for-' + cmd, + title:editor.getLang("labelMap." + cmd) || '', + 'items':items, + onbuttonclick:function () { + var value = editor.queryCommandValue(cmd) || this.value; + editor.execCommand(cmd, value); + } + }); + editorui.buttons[cmd] = ui; + editor.addListener('selectionchange', function () { + var state = editor.queryCommandState(cmd); + if (state == -1) { + ui.setDisabled(true); + } else { + ui.setDisabled(false); + var value = editor.queryCommandValue(cmd); + ui.setValue(value); + ui.setChecked(state) + } + }); + return ui; + }; + })(cl) + } + + editorui.fullscreen = function (editor, title) { + title = editor.options.labelMap['fullscreen'] || editor.getLang("labelMap.fullscreen") || ''; + var ui = new editorui.Button({ + className:'edui-for-fullscreen', + title:title, + theme:editor.options.theme, + onclick:function () { + if (editor.ui) { + editor.ui.setFullScreen(!editor.ui.isFullScreen()); + } + this.setChecked(editor.ui.isFullScreen()); + } + }); + editorui.buttons['fullscreen'] = ui; + editor.addListener('selectionchange', function () { + var state = editor.queryCommandState('fullscreen'); + ui.setDisabled(state == -1); + ui.setChecked(editor.ui.isFullScreen()); + }); + return ui; + }; + + // 表情 + editorui["emotion"] = function (editor, iframeUrl) { + var cmd = "emotion"; + var ui = new editorui.MultiMenuPop({ + title:editor.options.labelMap[cmd] || editor.getLang("labelMap." + cmd + "") || '', + editor:editor, + className:'edui-for-' + cmd, + iframeUrl:editor.ui.mapUrl(iframeUrl || (editor.options.iframeUrlMap || {})[cmd] || iframeUrlMap[cmd]) + }); + editorui.buttons[cmd] = ui; + + editor.addListener('selectionchange', function () { + ui.setDisabled(editor.queryCommandState(cmd) == -1) + }); + return ui; + }; + + editorui.autotypeset = function (editor) { + var ui = new editorui.AutoTypeSetButton({ + editor:editor, + title:editor.options.labelMap['autotypeset'] || editor.getLang("labelMap.autotypeset") || '', + className:'edui-for-autotypeset', + onbuttonclick:function () { + editor.execCommand('autotypeset') + } + }); + editorui.buttons['autotypeset'] = ui; + editor.addListener('selectionchange', function () { + ui.setDisabled(editor.queryCommandState('autotypeset') == -1); + }); + return ui; + }; + + /* 简单上传插件 */ + editorui["simpleupload"] = function (editor) { + var name = 'simpleupload', + ui = new editorui.Button({ + className:'edui-for-' + name, + title:editor.options.labelMap[name] || editor.getLang("labelMap." + name) || '', + onclick:function () {}, + theme:editor.options.theme, + showText:false + }); + editorui.buttons[name] = ui; + editor.addListener('ready', function() { + var b = ui.getDom('body'), + iconSpan = b.children[0]; + editor.fireEvent('simpleuploadbtnready', iconSpan); + }); + editor.addListener('selectionchange', function (type, causeByUi, uiReady) { + var state = editor.queryCommandState(name); + if (state == -1) { + ui.setDisabled(true); + ui.setChecked(false); + } else { + if (!uiReady) { + ui.setDisabled(false); + ui.setChecked(state); + } + } + }); + return ui; + }; + +})(); + + +// adapter/editor.js +///import core +///commands 全屏 +///commandsName FullScreen +///commandsTitle 全屏 +(function () { + var utils = baidu.editor.utils, + uiUtils = baidu.editor.ui.uiUtils, + UIBase = baidu.editor.ui.UIBase, + domUtils = baidu.editor.dom.domUtils; + var nodeStack = []; + + function EditorUI(options) { + this.initOptions(options); + this.initEditorUI(); + } + + EditorUI.prototype = { + uiName:'editor', + initEditorUI:function () { + this.editor.ui = this; + this._dialogs = {}; + this.initUIBase(); + this._initToolbars(); + var editor = this.editor, + me = this; + + editor.addListener('ready', function () { + //提供getDialog方法 + editor.getDialog = function (name) { + return editor.ui._dialogs[name + "Dialog"]; + }; + domUtils.on(editor.window, 'scroll', function (evt) { + baidu.editor.ui.Popup.postHide(evt); + }); + //提供编辑器实时宽高(全屏时宽高不变化) + editor.ui._actualFrameWidth = editor.options.initialFrameWidth; + + UE.browser.ie && UE.browser.version === 6 && editor.container.ownerDocument.execCommand("BackgroundImageCache", false, true); + + //display bottom-bar label based on config + if (editor.options.elementPathEnabled) { + editor.ui.getDom('elementpath').innerHTML = '
          ' + editor.getLang("elementPathTip") + ':
          '; + } + if (editor.options.wordCount) { + function countFn() { + setCount(editor,me); + domUtils.un(editor.document, "click", arguments.callee); + } + domUtils.on(editor.document, "click", countFn); + editor.ui.getDom('wordcount').innerHTML = editor.getLang("wordCountTip"); + } + editor.ui._scale(); + if (editor.options.scaleEnabled) { + if (editor.autoHeightEnabled) { + editor.disableAutoHeight(); + } + me.enableScale(); + } else { + me.disableScale(); + } + if (!editor.options.elementPathEnabled && !editor.options.wordCount && !editor.options.scaleEnabled) { + editor.ui.getDom('elementpath').style.display = "none"; + editor.ui.getDom('wordcount').style.display = "none"; + editor.ui.getDom('scale').style.display = "none"; + } + + if (!editor.selection.isFocus())return; + editor.fireEvent('selectionchange', false, true); + + + }); + + editor.addListener('mousedown', function (t, evt) { + var el = evt.target || evt.srcElement; + baidu.editor.ui.Popup.postHide(evt, el); + baidu.editor.ui.ShortCutMenu.postHide(evt); + + }); + editor.addListener("delcells", function () { + if (UE.ui['edittip']) { + new UE.ui['edittip'](editor); + } + editor.getDialog('edittip').open(); + }); + + var pastePop, isPaste = false, timer; + editor.addListener("afterpaste", function () { + if(editor.queryCommandState('pasteplain')) + return; + if(baidu.editor.ui.PastePicker){ + pastePop = new baidu.editor.ui.Popup({ + content:new baidu.editor.ui.PastePicker({editor:editor}), + editor:editor, + className:'edui-wordpastepop' + }); + pastePop.render(); + } + isPaste = true; + }); + + editor.addListener("afterinserthtml", function () { + clearTimeout(timer); + timer = setTimeout(function () { + if (pastePop && (isPaste || editor.ui._isTransfer)) { + if(pastePop.isHidden()){ + var span = domUtils.createElement(editor.document, 'span', { + 'style':"line-height:0px;", + 'innerHTML':'\ufeff' + }), + range = editor.selection.getRange(); + range.insertNode(span); + var tmp= getDomNode(span, 'firstChild', 'previousSibling'); + tmp && pastePop.showAnchor(tmp.nodeType == 3 ? tmp.parentNode : tmp); + domUtils.remove(span); + }else{ + pastePop.show(); + } + delete editor.ui._isTransfer; + isPaste = false; + } + }, 200) + }); + editor.addListener('contextmenu', function (t, evt) { + baidu.editor.ui.Popup.postHide(evt); + }); + editor.addListener('keydown', function (t, evt) { + if (pastePop) pastePop.dispose(evt); + var keyCode = evt.keyCode || evt.which; + if(evt.altKey&&keyCode==90){ + UE.ui.buttons['fullscreen'].onclick(); + } + }); + editor.addListener('wordcount', function (type) { + setCount(this,me); + }); + function setCount(editor,ui) { + editor.setOpt({ + wordCount:true, + maximumWords:10000, + wordCountMsg:editor.options.wordCountMsg || editor.getLang("wordCountMsg"), + wordOverFlowMsg:editor.options.wordOverFlowMsg || editor.getLang("wordOverFlowMsg") + }); + var opt = editor.options, + max = opt.maximumWords, + msg = opt.wordCountMsg , + errMsg = opt.wordOverFlowMsg, + countDom = ui.getDom('wordcount'); + if (!opt.wordCount) { + return; + } + var count = editor.getContentLength(true); + if (count > max) { + countDom.innerHTML = errMsg; + editor.fireEvent("wordcountoverflow"); + } else { + countDom.innerHTML = msg.replace("{#leave}", max - count).replace("{#count}", count); + } + } + + editor.addListener('selectionchange', function () { + if (editor.options.elementPathEnabled) { + me[(editor.queryCommandState('elementpath') == -1 ? 'dis' : 'en') + 'ableElementPath']() + } + if (editor.options.scaleEnabled) { + me[(editor.queryCommandState('scale') == -1 ? 'dis' : 'en') + 'ableScale'](); + + } + }); + var popup = new baidu.editor.ui.Popup({ + editor:editor, + content:'', + className:'edui-bubble', + _onEditButtonClick:function () { + this.hide(); + editor.ui._dialogs.linkDialog.open(); + }, + _onImgEditButtonClick:function (name) { + this.hide(); + editor.ui._dialogs[name] && editor.ui._dialogs[name].open(); + + }, + _onImgSetFloat:function (value) { + this.hide(); + editor.execCommand("imagefloat", value); + + }, + _setIframeAlign:function (value) { + var frame = popup.anchorEl; + var newFrame = frame.cloneNode(true); + switch (value) { + case -2: + newFrame.setAttribute("align", ""); + break; + case -1: + newFrame.setAttribute("align", "left"); + break; + case 1: + newFrame.setAttribute("align", "right"); + break; + } + frame.parentNode.insertBefore(newFrame, frame); + domUtils.remove(frame); + popup.anchorEl = newFrame; + popup.showAnchor(popup.anchorEl); + }, + _updateIframe:function () { + var frame = editor._iframe = popup.anchorEl; + if(domUtils.hasClass(frame, 'ueditor_baidumap')) { + editor.selection.getRange().selectNode(frame).select(); + editor.ui._dialogs.mapDialog.open(); + popup.hide(); + } else { + editor.ui._dialogs.insertframeDialog.open(); + popup.hide(); + } + }, + _onRemoveButtonClick:function (cmdName) { + editor.execCommand(cmdName); + this.hide(); + }, + queryAutoHide:function (el) { + if (el && el.ownerDocument == editor.document) { + if (el.tagName.toLowerCase() == 'img' || domUtils.findParentByTagName(el, 'a', true)) { + return el !== popup.anchorEl; + } + } + return baidu.editor.ui.Popup.prototype.queryAutoHide.call(this, el); + } + }); + popup.render(); + if (editor.options.imagePopup) { + editor.addListener('mouseover', function (t, evt) { + evt = evt || window.event; + var el = evt.target || evt.srcElement; + if (editor.ui._dialogs.insertframeDialog && /iframe/ig.test(el.tagName)) { + var html = popup.formatHtml( + '' + editor.getLang("property") + ': ' + editor.getLang("default") + '  ' + editor.getLang("justifyleft") + '  ' + editor.getLang("justifyright") + '  ' + + ' ' + editor.getLang("modify") + ''); + if (html) { + popup.getDom('content').innerHTML = html; + popup.anchorEl = el; + popup.showAnchor(popup.anchorEl); + } else { + popup.hide(); + } + } + }); + editor.addListener('selectionchange', function (t, causeByUi) { + if (!causeByUi) return; + var html = '', str = "", + img = editor.selection.getRange().getClosedNode(), + dialogs = editor.ui._dialogs; + if (img && img.tagName == 'IMG') { + var dialogName = 'insertimageDialog'; + if (img.className.indexOf("edui-faked-video") != -1 || img.className.indexOf("edui-upload-video") != -1) { + dialogName = "insertvideoDialog" + } + if (img.className.indexOf("edui-faked-webapp") != -1) { + dialogName = "webappDialog" + } + if (img.src.indexOf("http://api.map.baidu.com") != -1) { + dialogName = "mapDialog" + } + if (img.className.indexOf("edui-faked-music") != -1) { + dialogName = "musicDialog" + } + if (img.src.indexOf("http://maps.google.com/maps/api/staticmap") != -1) { + dialogName = "gmapDialog" + } + if (img.getAttribute("anchorname")) { + dialogName = "anchorDialog"; + html = popup.formatHtml( + '' + editor.getLang("property") + ': ' + editor.getLang("modify") + '  ' + + '' + editor.getLang("delete") + ''); + } + if (img.getAttribute("word_img")) { + //todo 放到dialog去做查询 + editor.word_img = [img.getAttribute("word_img")]; + dialogName = "wordimageDialog" + } + if(domUtils.hasClass(img, 'loadingclass') || domUtils.hasClass(img, 'loaderrorclass')) { + dialogName = ""; + } + if (!dialogs[dialogName]) { + return; + } + str = '' + editor.getLang("property") + ': '+ + '' + editor.getLang("default") + '  ' + + '' + editor.getLang("justifyleft") + '  ' + + '' + editor.getLang("justifyright") + '  ' + + '' + editor.getLang("justifycenter") + '  '+ + '' + editor.getLang("modify") + ''; + + !html && (html = popup.formatHtml(str)) + + } + if (editor.ui._dialogs.linkDialog) { + var link = editor.queryCommandValue('link'); + var url; + if (link && (url = (link.getAttribute('_href') || link.getAttribute('href', 2)))) { + var txt = url; + if (url.length > 30) { + txt = url.substring(0, 20) + "..."; + } + if (html) { + html += '
          ' + } + html += popup.formatHtml( + '' + editor.getLang("anthorMsg") + ': ' + txt + '' + + ' ' + editor.getLang("modify") + '' + + ' ' + editor.getLang("clear") + ''); + popup.showAnchor(link); + } + } + + if (html) { + popup.getDom('content').innerHTML = html; + popup.anchorEl = img || link; + popup.showAnchor(popup.anchorEl); + } else { + popup.hide(); + } + }); + } + + }, + _initToolbars:function () { + var editor = this.editor; + var toolbars = this.toolbars || []; + var toolbarUis = []; + for (var i = 0; i < toolbars.length; i++) { + var toolbar = toolbars[i]; + var toolbarUi = new baidu.editor.ui.Toolbar({theme:editor.options.theme}); + for (var j = 0; j < toolbar.length; j++) { + var toolbarItem = toolbar[j]; + var toolbarItemUi = null; + if (typeof toolbarItem == 'string') { + toolbarItem = toolbarItem.toLowerCase(); + if (toolbarItem == '|') { + toolbarItem = 'Separator'; + } + if(toolbarItem == '||'){ + toolbarItem = 'Breakline'; + } + if (baidu.editor.ui[toolbarItem]) { + toolbarItemUi = new baidu.editor.ui[toolbarItem](editor); + } + + //fullscreen这里单独处理一下,放到首行去 + if (toolbarItem == 'fullscreen') { + if (toolbarUis && toolbarUis[0]) { + toolbarUis[0].items.splice(0, 0, toolbarItemUi); + } else { + toolbarItemUi && toolbarUi.items.splice(0, 0, toolbarItemUi); + } + + continue; + + + } + } else { + toolbarItemUi = toolbarItem; + } + if (toolbarItemUi && toolbarItemUi.id) { + + toolbarUi.add(toolbarItemUi); + } + } + toolbarUis[i] = toolbarUi; + } + + //接受外部定制的UI + + utils.each(UE._customizeUI,function(obj,key){ + var itemUI,index; + if(obj.id && obj.id != editor.key){ + return false; + } + itemUI = obj.execFn.call(editor,editor,key); + if(itemUI){ + index = obj.index; + if(index === undefined){ + index = toolbarUi.items.length; + } + toolbarUi.add(itemUI,index) + } + }); + + this.toolbars = toolbarUis; + }, + getHtmlTpl:function () { + return '
          ' + + '
          ' + + (this.toolbars.length ? + '
          ' + + this.renderToolbarBoxHtml() + + '
          ' : '') + + '' + + '
          ' + + '
          ' + + '
          ' + + '
          ' + + //modify wdcount by matao + '
          ' + + '' + + '' + + '' + + '
          ' + + '
          ' + + '
          '; + }, + showWordImageDialog:function () { + this._dialogs['wordimageDialog'].open(); + }, + renderToolbarBoxHtml:function () { + var buff = []; + for (var i = 0; i < this.toolbars.length; i++) { + buff.push(this.toolbars[i].renderHtml()); + } + return buff.join(''); + }, + setFullScreen:function (fullscreen) { + + var editor = this.editor, + container = editor.container.parentNode.parentNode; + if (this._fullscreen != fullscreen) { + this._fullscreen = fullscreen; + this.editor.fireEvent('beforefullscreenchange', fullscreen); + if (baidu.editor.browser.gecko) { + var bk = editor.selection.getRange().createBookmark(); + } + if (fullscreen) { + while (container.tagName != "BODY") { + var position = baidu.editor.dom.domUtils.getComputedStyle(container, "position"); + nodeStack.push(position); + container.style.position = "static"; + container = container.parentNode; + } + this._bakHtmlOverflow = document.documentElement.style.overflow; + this._bakBodyOverflow = document.body.style.overflow; + this._bakAutoHeight = this.editor.autoHeightEnabled; + this._bakScrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop); + + this._bakEditorContaninerWidth = editor.iframe.parentNode.offsetWidth; + if (this._bakAutoHeight) { + //当全屏时不能执行自动长高 + editor.autoHeightEnabled = false; + this.editor.disableAutoHeight(); + } + + document.documentElement.style.overflow = 'hidden'; + //修复,滚动条不收起的问题 + + window.scrollTo(0,window.scrollY); + this._bakCssText = this.getDom().style.cssText; + this._bakCssText1 = this.getDom('iframeholder').style.cssText; + editor.iframe.parentNode.style.width = ''; + this._updateFullScreen(); + } else { + while (container.tagName != "BODY") { + container.style.position = nodeStack.shift(); + container = container.parentNode; + } + this.getDom().style.cssText = this._bakCssText; + this.getDom('iframeholder').style.cssText = this._bakCssText1; + if (this._bakAutoHeight) { + editor.autoHeightEnabled = true; + this.editor.enableAutoHeight(); + } + + document.documentElement.style.overflow = this._bakHtmlOverflow; + document.body.style.overflow = this._bakBodyOverflow; + editor.iframe.parentNode.style.width = this._bakEditorContaninerWidth + 'px'; + window.scrollTo(0, this._bakScrollTop); + } + if (browser.gecko && editor.body.contentEditable === 'true') { + var input = document.createElement('input'); + document.body.appendChild(input); + editor.body.contentEditable = false; + setTimeout(function () { + input.focus(); + setTimeout(function () { + editor.body.contentEditable = true; + editor.fireEvent('fullscreenchanged', fullscreen); + editor.selection.getRange().moveToBookmark(bk).select(true); + baidu.editor.dom.domUtils.remove(input); + fullscreen && window.scroll(0, 0); + }, 0) + }, 0) + } + + if(editor.body.contentEditable === 'true'){ + this.editor.fireEvent('fullscreenchanged', fullscreen); + this.triggerLayout(); + } + + } + }, + _updateFullScreen:function () { + if (this._fullscreen) { + var vpRect = uiUtils.getViewportRect(); + this.getDom().style.cssText = 'border:0;position:absolute;left:0;top:' + (this.editor.options.topOffset || 0) + 'px;width:' + vpRect.width + 'px;height:' + vpRect.height + 'px;z-index:' + (this.getDom().style.zIndex * 1 + 100); + uiUtils.setViewportOffset(this.getDom(), { left:0, top:this.editor.options.topOffset || 0 }); + this.editor.setHeight(vpRect.height - this.getDom('toolbarbox').offsetHeight - this.getDom('bottombar').offsetHeight - (this.editor.options.topOffset || 0),true); + //不手动调一下,会导致全屏失效 + if(browser.gecko){ + try{ + window.onresize(); + }catch(e){ + + } + + } + } + }, + _updateElementPath:function () { + var bottom = this.getDom('elementpath'), list; + if (this.elementPathEnabled && (list = this.editor.queryCommandValue('elementpath'))) { + + var buff = []; + for (var i = 0, ci; ci = list[i]; i++) { + buff[i] = this.formatHtml('' + ci + ''); + } + bottom.innerHTML = '
          ' + this.editor.getLang("elementPathTip") + ': ' + buff.join(' > ') + '
          '; + + } else { + bottom.style.display = 'none' + } + }, + disableElementPath:function () { + var bottom = this.getDom('elementpath'); + bottom.innerHTML = ''; + bottom.style.display = 'none'; + this.elementPathEnabled = false; + + }, + enableElementPath:function () { + var bottom = this.getDom('elementpath'); + bottom.style.display = ''; + this.elementPathEnabled = true; + this._updateElementPath(); + }, + _scale:function () { + var doc = document, + editor = this.editor, + editorHolder = editor.container, + editorDocument = editor.document, + toolbarBox = this.getDom("toolbarbox"), + bottombar = this.getDom("bottombar"), + scale = this.getDom("scale"), + scalelayer = this.getDom("scalelayer"); + + var isMouseMove = false, + position = null, + minEditorHeight = 0, + minEditorWidth = editor.options.minFrameWidth, + pageX = 0, + pageY = 0, + scaleWidth = 0, + scaleHeight = 0; + + function down() { + position = domUtils.getXY(editorHolder); + + if (!minEditorHeight) { + minEditorHeight = editor.options.minFrameHeight + toolbarBox.offsetHeight + bottombar.offsetHeight; + } + + scalelayer.style.cssText = "position:absolute;left:0;display:;top:0;background-color:#41ABFF;opacity:0.4;filter: Alpha(opacity=40);width:" + editorHolder.offsetWidth + "px;height:" + + editorHolder.offsetHeight + "px;z-index:" + (editor.options.zIndex + 1); + + domUtils.on(doc, "mousemove", move); + domUtils.on(editorDocument, "mouseup", up); + domUtils.on(doc, "mouseup", up); + } + + var me = this; + //by xuheng 全屏时关掉缩放 + this.editor.addListener('fullscreenchanged', function (e, fullScreen) { + if (fullScreen) { + me.disableScale(); + + } else { + if (me.editor.options.scaleEnabled) { + me.enableScale(); + var tmpNode = me.editor.document.createElement('span'); + me.editor.body.appendChild(tmpNode); + me.editor.body.style.height = Math.max(domUtils.getXY(tmpNode).y, me.editor.iframe.offsetHeight - 20) + 'px'; + domUtils.remove(tmpNode) + } + } + }); + function move(event) { + clearSelection(); + var e = event || window.event; + pageX = e.pageX || (doc.documentElement.scrollLeft + e.clientX); + pageY = e.pageY || (doc.documentElement.scrollTop + e.clientY); + scaleWidth = pageX - position.x; + scaleHeight = pageY - position.y; + + if (scaleWidth >= minEditorWidth) { + isMouseMove = true; + scalelayer.style.width = scaleWidth + 'px'; + } + if (scaleHeight >= minEditorHeight) { + isMouseMove = true; + scalelayer.style.height = scaleHeight + "px"; + } + } + + function up() { + if (isMouseMove) { + isMouseMove = false; + editor.ui._actualFrameWidth = scalelayer.offsetWidth - 2; + editorHolder.style.width = editor.ui._actualFrameWidth + 'px'; + + editor.setHeight(scalelayer.offsetHeight - bottombar.offsetHeight - toolbarBox.offsetHeight - 2,true); + } + if (scalelayer) { + scalelayer.style.display = "none"; + } + clearSelection(); + domUtils.un(doc, "mousemove", move); + domUtils.un(editorDocument, "mouseup", up); + domUtils.un(doc, "mouseup", up); + } + + function clearSelection() { + if (browser.ie) + doc.selection.clear(); + else + window.getSelection().removeAllRanges(); + } + + this.enableScale = function () { + //trace:2868 + if (editor.queryCommandState("source") == 1) return; + scale.style.display = ""; + this.scaleEnabled = true; + domUtils.on(scale, "mousedown", down); + }; + this.disableScale = function () { + scale.style.display = "none"; + this.scaleEnabled = false; + domUtils.un(scale, "mousedown", down); + }; + }, + isFullScreen:function () { + return this._fullscreen; + }, + postRender:function () { + UIBase.prototype.postRender.call(this); + for (var i = 0; i < this.toolbars.length; i++) { + this.toolbars[i].postRender(); + } + var me = this; + var timerId, + domUtils = baidu.editor.dom.domUtils, + updateFullScreenTime = function () { + clearTimeout(timerId); + timerId = setTimeout(function () { + me._updateFullScreen(); + }); + }; + domUtils.on(window, 'resize', updateFullScreenTime); + + me.addListener('destroy', function () { + domUtils.un(window, 'resize', updateFullScreenTime); + clearTimeout(timerId); + }) + }, + showToolbarMsg:function (msg, flag) { + this.getDom('toolbarmsg_label').innerHTML = msg; + this.getDom('toolbarmsg').style.display = ''; + // + if (!flag) { + var w = this.getDom('upload_dialog'); + w.style.display = 'none'; + } + }, + hideToolbarMsg:function () { + this.getDom('toolbarmsg').style.display = 'none'; + }, + mapUrl:function (url) { + return url ? url.replace('~/', this.editor.options.UEDITOR_HOME_URL || '') : '' + }, + triggerLayout:function () { + var dom = this.getDom(); + if (dom.style.zoom == '1') { + dom.style.zoom = '100%'; + } else { + dom.style.zoom = '1'; + } + } + }; + utils.inherits(EditorUI, baidu.editor.ui.UIBase); + + + var instances = {}; + + + UE.ui.Editor = function (options) { + var editor = new UE.Editor(options); + editor.options.editor = editor; + utils.loadFile(document, { + href:editor.options.themePath + editor.options.theme + "/css/ueditor.css", + tag:"link", + type:"text/css", + rel:"stylesheet" + }); + + var oldRender = editor.render; + editor.render = function (holder) { + if (holder.constructor === String) { + editor.key = holder; + instances[holder] = editor; + } + utils.domReady(function () { + editor.langIsReady ? renderUI() : editor.addListener("langReady", renderUI); + function renderUI() { + editor.setOpt({ + labelMap:editor.options.labelMap || editor.getLang('labelMap') + }); + new EditorUI(editor.options); + if (holder) { + if (holder.constructor === String) { + holder = document.getElementById(holder); + } + holder && holder.getAttribute('name') && ( editor.options.textarea = holder.getAttribute('name')); + if (holder && /script|textarea/ig.test(holder.tagName)) { + var newDiv = document.createElement('div'); + holder.parentNode.insertBefore(newDiv, holder); + var cont = holder.value || holder.innerHTML; + editor.options.initialContent = /^[\t\r\n ]*$/.test(cont) ? editor.options.initialContent : + cont.replace(/>[\n\r\t]+([ ]{4})+/g, '>') + .replace(/[\n\r\t]+([ ]{4})+[\n\r\t]+<'); + holder.className && (newDiv.className = holder.className); + holder.style.cssText && (newDiv.style.cssText = holder.style.cssText); + if (/textarea/i.test(holder.tagName)) { + editor.textarea = holder; + editor.textarea.style.display = 'none'; + + + } else { + holder.parentNode.removeChild(holder); + + + } + if(holder.id){ + newDiv.id = holder.id; + domUtils.removeAttributes(holder,'id'); + } + holder = newDiv; + holder.innerHTML = ''; + } + + } + domUtils.addClass(holder, "edui-" + editor.options.theme); + editor.ui.render(holder); + var opt = editor.options; + //给实例添加一个编辑器的容器引用 + editor.container = editor.ui.getDom(); + var parents = domUtils.findParents(holder,true); + var displays = []; + for(var i = 0 ,ci;ci=parents[i];i++){ + displays[i] = ci.style.display; + ci.style.display = 'block' + } + if (opt.initialFrameWidth) { + opt.minFrameWidth = opt.initialFrameWidth; + } else { + opt.minFrameWidth = opt.initialFrameWidth = holder.offsetWidth; + var styleWidth = holder.style.width; + if(/%$/.test(styleWidth)) { + opt.initialFrameWidth = styleWidth; + } + } + if (opt.initialFrameHeight) { + opt.minFrameHeight = opt.initialFrameHeight; + } else { + opt.initialFrameHeight = opt.minFrameHeight = holder.offsetHeight; + } + for(var i = 0 ,ci;ci=parents[i];i++){ + ci.style.display = displays[i] + } + //编辑器最外容器设置了高度,会导致,编辑器不占位 + //todo 先去掉,没有找到原因 + if(holder.style.height){ + holder.style.height = '' + } + editor.container.style.width = opt.initialFrameWidth + (/%$/.test(opt.initialFrameWidth) ? '' : 'px'); + editor.container.style.zIndex = opt.zIndex; + oldRender.call(editor, editor.ui.getDom('iframeholder')); + editor.fireEvent("afteruiready"); + } + }) + }; + return editor; + }; + + + /** + * @file + * @name UE + * @short UE + * @desc UEditor的顶部命名空间 + */ + /** + * @name getEditor + * @since 1.2.4+ + * @grammar UE.getEditor(id,[opt]) => Editor实例 + * @desc 提供一个全局的方法得到编辑器实例 + * + * * ''id'' 放置编辑器的容器id, 如果容器下的编辑器已经存在,就直接返回 + * * ''opt'' 编辑器的可选参数 + * @example + * UE.getEditor('containerId',{onready:function(){//创建一个编辑器实例 + * this.setContent('hello') + * }}); + * UE.getEditor('containerId'); //返回刚创建的实例 + * + */ + UE.getEditor = function (id, opt) { + var editor = instances[id]; + if (!editor) { + editor = instances[id] = new UE.ui.Editor(opt); + editor.render(id); + } + return editor; + }; + + + UE.delEditor = function (id) { + var editor; + if (editor = instances[id]) { + editor.key && editor.destroy(); + delete instances[id] + } + }; + + UE.registerUI = function(uiName,fn,index,editorId){ + utils.each(uiName.split(/\s+/), function (name) { + UE._customizeUI[name] = { + id : editorId, + execFn:fn, + index:index + }; + }) + + } + +})(); + +// adapter/message.js +UE.registerUI('message', function(editor) { + + var editorui = baidu.editor.ui; + var Message = editorui.Message; + var holder; + var _messageItems = []; + var me = editor; + + me.addListener('ready', function(){ + holder = document.getElementById(me.ui.id + '_message_holder'); + updateHolderPos(); + setTimeout(function(){ + updateHolderPos(); + }, 500); + }); + + me.addListener('showmessage', function(type, opt){ + opt = utils.isString(opt) ? { + 'content': opt + } : opt; + var message = new Message({ + 'timeout': opt.timeout, + 'type': opt.type, + 'content': opt.content, + 'keepshow': opt.keepshow, + 'editor': me + }), + mid = opt.id || ('msg_' + (+new Date()).toString(36)); + message.render(holder); + _messageItems[mid] = message; + message.reset(opt); + updateHolderPos(); + return mid; + }); + + me.addListener('updatemessage',function(type, id, opt){ + opt = utils.isString(opt) ? { + 'content': opt + } : opt; + var message = _messageItems[id]; + message.render(holder); + message && message.reset(opt); + }); + + me.addListener('hidemessage',function(type, id){ + var message = _messageItems[id]; + message && message.hide(); + }); + + function updateHolderPos(){ + var toolbarbox = me.ui.getDom('toolbarbox'); + if (toolbarbox) { + holder.style.top = toolbarbox.offsetHeight + 3 + 'px'; + } + holder.style.zIndex = Math.max(me.options.zIndex, me.iframe.style.zIndex) + 1; + } + +}); + + +// adapter/autosave.js +UE.registerUI('autosave', function(editor) { + var timer = null,uid = null; + editor.on('afterautosave',function(){ + clearTimeout(timer); + + timer = setTimeout(function(){ + if(uid){ + editor.trigger('hidemessage',uid); + } + uid = editor.trigger('showmessage',{ + content : editor.getLang('autosave.success'), + timeout : 2000 + }); + + },2000) + }) + +}); + + + +})(); diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/ueditor.parse.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/ueditor.parse.js new file mode 100644 index 000000000..1efc481c0 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/ueditor.parse.js @@ -0,0 +1,1022 @@ +/*! + * UEditor + * version: ueditor + * build: Wed Aug 10 2016 11:05:21 GMT+0800 (CST) + */ + +(function(){ + +(function(){ + UE = window.UE || {}; + var isIE = !!window.ActiveXObject; + //定义utils工具 + var utils = { + removeLastbs : function(url){ + return url.replace(/\/$/,'') + }, + extend : function(t,s){ + var a = arguments, + notCover = this.isBoolean(a[a.length - 1]) ? a[a.length - 1] : false, + len = this.isBoolean(a[a.length - 1]) ? a.length - 1 : a.length; + for (var i = 1; i < len; i++) { + var x = a[i]; + for (var k in x) { + if (!notCover || !t.hasOwnProperty(k)) { + t[k] = x[k]; + } + } + } + return t; + }, + isIE : isIE, + cssRule : isIE ? function(key,style,doc){ + var indexList,index; + doc = doc || document; + if(doc.indexList){ + indexList = doc.indexList; + }else{ + indexList = doc.indexList = {}; + } + var sheetStyle; + if(!indexList[key]){ + if(style === undefined){ + return '' + } + sheetStyle = doc.createStyleSheet('',index = doc.styleSheets.length); + indexList[key] = index; + }else{ + sheetStyle = doc.styleSheets[indexList[key]]; + } + if(style === undefined){ + return sheetStyle.cssText + } + sheetStyle.cssText = sheetStyle.cssText + '\n' + (style || '') + } : function(key,style,doc){ + doc = doc || document; + var head = doc.getElementsByTagName('head')[0],node; + if(!(node = doc.getElementById(key))){ + if(style === undefined){ + return '' + } + node = doc.createElement('style'); + node.id = key; + head.appendChild(node) + } + if(style === undefined){ + return node.innerHTML + } + if(style !== ''){ + node.innerHTML = node.innerHTML + '\n' + style; + }else{ + head.removeChild(node) + } + }, + domReady : function (onready) { + var doc = window.document; + if (doc.readyState === "complete") { + onready(); + }else{ + if (isIE) { + (function () { + if (doc.isReady) return; + try { + doc.documentElement.doScroll("left"); + } catch (error) { + setTimeout(arguments.callee, 0); + return; + } + onready(); + })(); + window.attachEvent('onload', function(){ + onready() + }); + } else { + doc.addEventListener("DOMContentLoaded", function () { + doc.removeEventListener("DOMContentLoaded", arguments.callee, false); + onready(); + }, false); + window.addEventListener('load', function(){onready()}, false); + } + } + + }, + each : function(obj, iterator, context) { + if (obj == null) return; + if (obj.length === +obj.length) { + for (var i = 0, l = obj.length; i < l; i++) { + if(iterator.call(context, obj[i], i, obj) === false) + return false; + } + } else { + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + if(iterator.call(context, obj[key], key, obj) === false) + return false; + } + } + } + }, + inArray : function(arr,item){ + var index = -1; + this.each(arr,function(v,i){ + if(v === item){ + index = i; + return false; + } + }); + return index; + }, + pushItem : function(arr,item){ + if(this.inArray(arr,item)==-1){ + arr.push(item) + } + }, + trim: function (str) { + return str.replace(/(^[ \t\n\r]+)|([ \t\n\r]+$)/g, ''); + }, + indexOf: function (array, item, start) { + var index = -1; + start = this.isNumber(start) ? start : 0; + this.each(array, function (v, i) { + if (i >= start && v === item) { + index = i; + return false; + } + }); + return index; + }, + hasClass: function (element, className) { + className = className.replace(/(^[ ]+)|([ ]+$)/g, '').replace(/[ ]{2,}/g, ' ').split(' '); + for (var i = 0, ci, cls = element.className; ci = className[i++];) { + if (!new RegExp('\\b' + ci + '\\b', 'i').test(cls)) { + return false; + } + } + return i - 1 == className.length; + }, + addClass:function (elm, classNames) { + if(!elm)return; + classNames = this.trim(classNames).replace(/[ ]{2,}/g,' ').split(' '); + for(var i = 0,ci,cls = elm.className;ci=classNames[i++];){ + if(!new RegExp('\\b' + ci + '\\b').test(cls)){ + cls += ' ' + ci; + } + } + elm.className = utils.trim(cls); + }, + removeClass:function (elm, classNames) { + classNames = this.isArray(classNames) ? classNames : + this.trim(classNames).replace(/[ ]{2,}/g,' ').split(' '); + for(var i = 0,ci,cls = elm.className;ci=classNames[i++];){ + cls = cls.replace(new RegExp('\\b' + ci + '\\b'),'') + } + cls = this.trim(cls).replace(/[ ]{2,}/g,' '); + elm.className = cls; + !cls && elm.removeAttribute('className'); + }, + on: function (element, type, handler) { + var types = this.isArray(type) ? type : type.split(/\s+/), + k = types.length; + if (k) while (k--) { + type = types[k]; + if (element.addEventListener) { + element.addEventListener(type, handler, false); + } else { + if (!handler._d) { + handler._d = { + els : [] + }; + } + var key = type + handler.toString(),index = utils.indexOf(handler._d.els,element); + if (!handler._d[key] || index == -1) { + if(index == -1){ + handler._d.els.push(element); + } + if(!handler._d[key]){ + handler._d[key] = function (evt) { + return handler.call(evt.srcElement, evt || window.event); + }; + } + + + element.attachEvent('on' + type, handler._d[key]); + } + } + } + element = null; + }, + off: function (element, type, handler) { + var types = this.isArray(type) ? type : type.split(/\s+/), + k = types.length; + if (k) while (k--) { + type = types[k]; + if (element.removeEventListener) { + element.removeEventListener(type, handler, false); + } else { + var key = type + handler.toString(); + try{ + element.detachEvent('on' + type, handler._d ? handler._d[key] : handler); + }catch(e){} + if (handler._d && handler._d[key]) { + var index = utils.indexOf(handler._d.els,element); + if(index!=-1){ + handler._d.els.splice(index,1); + } + handler._d.els.length == 0 && delete handler._d[key]; + } + } + } + }, + loadFile : function () { + var tmpList = []; + function getItem(doc,obj){ + try{ + for(var i= 0,ci;ci=tmpList[i++];){ + if(ci.doc === doc && ci.url == (obj.src || obj.href)){ + return ci; + } + } + }catch(e){ + return null; + } + + } + return function (doc, obj, fn) { + var item = getItem(doc,obj); + if (item) { + if(item.ready){ + fn && fn(); + }else{ + item.funs.push(fn) + } + return; + } + tmpList.push({ + doc:doc, + url:obj.src||obj.href, + funs:[fn] + }); + if (!doc.body) { + var html = []; + for(var p in obj){ + if(p == 'tag')continue; + html.push(p + '="' + obj[p] + '"') + } + doc.write('<' + obj.tag + ' ' + html.join(' ') + ' >'); + return; + } + if (obj.id && doc.getElementById(obj.id)) { + return; + } + var element = doc.createElement(obj.tag); + delete obj.tag; + for (var p in obj) { + element.setAttribute(p, obj[p]); + } + element.onload = element.onreadystatechange = function () { + if (!this.readyState || /loaded|complete/.test(this.readyState)) { + item = getItem(doc,obj); + if (item.funs.length > 0) { + item.ready = 1; + for (var fi; fi = item.funs.pop();) { + fi(); + } + } + element.onload = element.onreadystatechange = null; + } + }; + element.onerror = function(){ + throw Error('The load '+(obj.href||obj.src)+' fails,check the url') + }; + doc.getElementsByTagName("head")[0].appendChild(element); + } + }() + }; + utils.each(['String', 'Function', 'Array', 'Number', 'RegExp', 'Object','Boolean'], function (v) { + utils['is' + v] = function (obj) { + return Object.prototype.toString.apply(obj) == '[object ' + v + ']'; + } + }); + var parselist = {}; + UE.parse = { + register : function(parseName,fn){ + parselist[parseName] = fn; + }, + load : function(opt){ + utils.each(parselist,function(v){ + v.call(opt,utils); + }) + } + }; + uParse = function(selector,opt){ + utils.domReady(function(){ + var contents; + if(document.querySelectorAll){ + contents = document.querySelectorAll(selector) + }else{ + if(/^#/.test(selector)){ + contents = [document.getElementById(selector.replace(/^#/,''))] + }else if(/^\./.test(selector)){ + var contents = []; + utils.each(document.getElementsByTagName('*'),function(node){ + if(node.className && new RegExp('\\b' + selector.replace(/^\./,'') + '\\b','i').test(node.className)){ + contents.push(node) + } + }) + }else{ + contents = document.getElementsByTagName(selector) + } + } + utils.each(contents,function(v){ + UE.parse.load(utils.extend({root:v,selector:selector},opt)) + }) + }) + } +})(); + +UE.parse.register('insertcode',function(utils){ + var pres = this.root.getElementsByTagName('pre'); + if(pres.length){ + if(typeof XRegExp == "undefined"){ + var jsurl,cssurl; + if(this.rootPath !== undefined){ + jsurl = utils.removeLastbs(this.rootPath) + '/third-party/SyntaxHighlighter/shCore.js'; + cssurl = utils.removeLastbs(this.rootPath) + '/third-party/SyntaxHighlighter/shCoreDefault.css'; + }else{ + jsurl = this.highlightJsUrl; + cssurl = this.highlightCssUrl; + } + utils.loadFile(document,{ + id : "syntaxhighlighter_css", + tag : "link", + rel : "stylesheet", + type : "text/css", + href : cssurl + }); + utils.loadFile(document,{ + id : "syntaxhighlighter_js", + src : jsurl, + tag : "script", + type : "text/javascript", + defer : "defer" + },function(){ + utils.each(pres,function(pi){ + if(pi && /brush/i.test(pi.className)){ + SyntaxHighlighter.highlight(pi); + } + }); + }); + }else{ + utils.each(pres,function(pi){ + if(pi && /brush/i.test(pi.className)){ + SyntaxHighlighter.highlight(pi); + } + }); + } + } + +}); +UE.parse.register('table', function (utils) { + var me = this, + root = this.root, + tables = root.getElementsByTagName('table'); + if (tables.length) { + var selector = this.selector; + //追加默认的表格样式 + utils.cssRule('table', + selector + ' table.noBorderTable td,' + + selector + ' table.noBorderTable th,' + + selector + ' table.noBorderTable caption{border:1px dashed #ddd !important}' + + selector + ' table.sortEnabled tr.firstRow th,' + selector + ' table.sortEnabled tr.firstRow td{padding-right:20px; background-repeat: no-repeat;' + + 'background-position: center right; background-image:url(' + this.rootPath + 'themes/default/images/sortable.png);}' + + selector + ' table.sortEnabled tr.firstRow th:hover,' + selector + ' table.sortEnabled tr.firstRow td:hover{background-color: #EEE;}' + + selector + ' table{margin-bottom:10px;border-collapse:collapse;display:table;}' + + selector + ' td,' + selector + ' th{ background:white; padding: 5px 10px;border: 1px solid #DDD;}' + + selector + ' caption{border:1px dashed #DDD;border-bottom:0;padding:3px;text-align:center;}' + + selector + ' th{border-top:1px solid #BBB;background:#F7F7F7;}' + + selector + ' table tr.firstRow th{border-top:2px solid #BBB;background:#F7F7F7;}' + + selector + ' tr.ue-table-interlace-color-single td{ background: #fcfcfc; }' + + selector + ' tr.ue-table-interlace-color-double td{ background: #f7faff; }' + + selector + ' td p{margin:0;padding:0;}', + document); + //填充空的单元格 + + utils.each('td th caption'.split(' '), function (tag) { + var cells = root.getElementsByTagName(tag); + cells.length && utils.each(cells, function (node) { + if (!node.firstChild) { + node.innerHTML = ' '; + + } + }) + }); + + //表格可排序 + var tables = root.getElementsByTagName('table'); + utils.each(tables, function (table) { + if (/\bsortEnabled\b/.test(table.className)) { + utils.on(table, 'click', function(e){ + var target = e.target || e.srcElement, + cell = findParentByTagName(target, ['td', 'th']); + var table = findParentByTagName(target, 'table'), + colIndex = utils.indexOf(table.rows[0].cells, cell), + sortType = table.getAttribute('data-sort-type'); + if(colIndex != -1) { + sortTable(table, colIndex, me.tableSortCompareFn || sortType); + updateTable(table); + } + }); + } + }); + + //按照标签名查找父节点 + function findParentByTagName(target, tagNames) { + var i, current = target; + tagNames = utils.isArray(tagNames) ? tagNames:[tagNames]; + while(current){ + for(i = 0;i < tagNames.length; i++) { + if(current.tagName == tagNames[i].toUpperCase()) return current; + } + current = current.parentNode; + } + return null; + } + //表格排序 + function sortTable(table, sortByCellIndex, compareFn) { + var rows = table.rows, + trArray = [], + flag = rows[0].cells[0].tagName === "TH", + lastRowIndex = 0; + + for (var i = 0,len = rows.length; i < len; i++) { + trArray[i] = rows[i]; + } + + var Fn = { + 'reversecurrent': function(td1,td2){ + return 1; + }, + 'orderbyasc': function(td1,td2){ + var value1 = td1.innerText||td1.textContent, + value2 = td2.innerText||td2.textContent; + return value1.localeCompare(value2); + }, + 'reversebyasc': function(td1,td2){ + var value1 = td1.innerHTML, + value2 = td2.innerHTML; + return value2.localeCompare(value1); + }, + 'orderbynum': function(td1,td2){ + var value1 = td1[utils.isIE ? 'innerText':'textContent'].match(/\d+/), + value2 = td2[utils.isIE ? 'innerText':'textContent'].match(/\d+/); + if(value1) value1 = +value1[0]; + if(value2) value2 = +value2[0]; + return (value1||0) - (value2||0); + }, + 'reversebynum': function(td1,td2){ + var value1 = td1[utils.isIE ? 'innerText':'textContent'].match(/\d+/), + value2 = td2[utils.isIE ? 'innerText':'textContent'].match(/\d+/); + if(value1) value1 = +value1[0]; + if(value2) value2 = +value2[0]; + return (value2||0) - (value1||0); + } + }; + + //对表格设置排序的标记data-sort-type + table.setAttribute('data-sort-type', compareFn && typeof compareFn === "string" && Fn[compareFn] ? compareFn:''); + + //th不参与排序 + flag && trArray.splice(0, 1); + trArray = sort(trArray,function (tr1, tr2) { + var result; + if (compareFn && typeof compareFn === "function") { + result = compareFn.call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]); + } else if (compareFn && typeof compareFn === "number") { + result = 1; + } else if (compareFn && typeof compareFn === "string" && Fn[compareFn]) { + result = Fn[compareFn].call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]); + } else { + result = Fn['orderbyasc'].call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]); + } + return result; + }); + var fragment = table.ownerDocument.createDocumentFragment(); + for (var j = 0, len = trArray.length; j < len; j++) { + fragment.appendChild(trArray[j]); + } + var tbody = table.getElementsByTagName("tbody")[0]; + if(!lastRowIndex){ + tbody.appendChild(fragment); + }else{ + tbody.insertBefore(fragment,rows[lastRowIndex- range.endRowIndex + range.beginRowIndex - 1]) + } + } + //冒泡排序 + function sort(array, compareFn){ + compareFn = compareFn || function(item1, item2){ return item1.localeCompare(item2);}; + for(var i= 0,len = array.length; i 0){ + var t = array[i]; + array[i] = array[j]; + array[j] = t; + } + } + } + return array; + } + //更新表格 + function updateTable(table) { + //给第一行设置firstRow的样式名称,在排序图标的样式上使用到 + if(!utils.hasClass(table.rows[0], "firstRow")) { + for(var i = 1; i< table.rows.length; i++) { + utils.removeClass(table.rows[i], "firstRow"); + } + utils.addClass(table.rows[0], "firstRow"); + } + } + } +}); +UE.parse.register('charts',function( utils ){ + + utils.cssRule('chartsContainerHeight','.edui-chart-container { height:'+(this.chartContainerHeight||300)+'px}'); + var resourceRoot = this.rootPath, + containers = this.root, + sources = null; + + //不存在指定的根路径, 则直接退出 + if ( !resourceRoot ) { + return; + } + + if ( sources = parseSources() ) { + + loadResources(); + + } + + + function parseSources () { + + if ( !containers ) { + return null; + } + + return extractChartData( containers ); + + } + + /** + * 提取数据 + */ + function extractChartData ( rootNode ) { + + var data = [], + tables = rootNode.getElementsByTagName( "table" ); + + for ( var i = 0, tableNode; tableNode = tables[ i ]; i++ ) { + + if ( tableNode.getAttribute( "data-chart" ) !== null ) { + + data.push( formatData( tableNode ) ); + + } + + } + + return data.length ? data : null; + + } + + function formatData ( tableNode ) { + + var meta = tableNode.getAttribute( "data-chart" ), + metaConfig = {}, + data = []; + + //提取table数据 + for ( var i = 0, row; row = tableNode.rows[ i ]; i++ ) { + + var rowData = []; + + for ( var j = 0, cell; cell = row.cells[ j ]; j++ ) { + + var value = ( cell.innerText || cell.textContent || '' ); + rowData.push( cell.tagName == 'TH' ? value:(value | 0) ); + + } + + data.push( rowData ); + + } + + //解析元信息 + meta = meta.split( ";" ); + for ( var i = 0, metaData; metaData = meta[ i ]; i++ ) { + + metaData = metaData.split( ":" ); + metaConfig[ metaData[ 0 ] ] = metaData[ 1 ]; + + } + + + return { + table: tableNode, + meta: metaConfig, + data: data + }; + + } + + //加载资源 + function loadResources () { + + loadJQuery(); + + } + + function loadJQuery () { + + //不存在jquery, 则加载jquery + if ( !window.jQuery ) { + + utils.loadFile(document,{ + src : resourceRoot + "/third-party/jquery-1.10.2.min.js", + tag : "script", + type : "text/javascript", + defer : "defer" + },function(){ + + loadHighcharts(); + + }); + + } else { + + loadHighcharts(); + + } + + } + + function loadHighcharts () { + + //不存在Highcharts, 则加载Highcharts + if ( !window.Highcharts ) { + + utils.loadFile(document,{ + src : resourceRoot + "/third-party/highcharts/highcharts.js", + tag : "script", + type : "text/javascript", + defer : "defer" + },function(){ + + loadTypeConfig(); + + }); + + } else { + + loadTypeConfig(); + + } + + } + + //加载图表差异化配置文件 + function loadTypeConfig () { + + utils.loadFile(document,{ + src : resourceRoot + "/dialogs/charts/chart.config.js", + tag : "script", + type : "text/javascript", + defer : "defer" + },function(){ + + render(); + + }); + + } + + //渲染图表 + function render () { + + var config = null, + chartConfig = null, + container = null; + + for ( var i = 0, len = sources.length; i < len; i++ ) { + + config = sources[ i ]; + + chartConfig = analysisConfig( config ); + + container = createContainer( config.table ); + + renderChart( container, typeConfig[ config.meta.chartType ], chartConfig ); + + } + + + } + + /** + * 渲染图表 + * @param container 图表容器节点对象 + * @param typeConfig 图表类型配置 + * @param config 图表通用配置 + * */ + function renderChart ( container, typeConfig, config ) { + + + $( container ).highcharts( $.extend( {}, typeConfig, { + + credits: { + enabled: false + }, + exporting: { + enabled: false + }, + title: { + text: config.title, + x: -20 //center + }, + subtitle: { + text: config.subTitle, + x: -20 + }, + xAxis: { + title: { + text: config.xTitle + }, + categories: config.categories + }, + yAxis: { + title: { + text: config.yTitle + }, + plotLines: [{ + value: 0, + width: 1, + color: '#808080' + }] + }, + tooltip: { + enabled: true, + valueSuffix: config.suffix + }, + legend: { + layout: 'vertical', + align: 'right', + verticalAlign: 'middle', + borderWidth: 1 + }, + series: config.series + + } )); + + } + + /** + * 创建图表的容器 + * 新创建的容器会替换掉对应的table对象 + * */ + function createContainer ( tableNode ) { + + var container = document.createElement( "div" ); + container.className = "edui-chart-container"; + + tableNode.parentNode.replaceChild( container, tableNode ); + + return container; + + } + + //根据config解析出正确的类别和图表数据信息 + function analysisConfig ( config ) { + + var series = [], + //数据类别 + categories = [], + result = [], + data = config.data, + meta = config.meta; + + //数据对齐方式为相反的方式, 需要反转数据 + if ( meta.dataFormat != "1" ) { + + for ( var i = 0, len = data.length; i < len ; i++ ) { + + for ( var j = 0, jlen = data[ i ].length; j < jlen; j++ ) { + + if ( !result[ j ] ) { + result[ j ] = []; + } + + result[ j ][ i ] = data[ i ][ j ]; + + } + + } + + data = result; + + } + + result = {}; + + //普通图表 + if ( meta.chartType != typeConfig.length - 1 ) { + + categories = data[ 0 ].slice( 1 ); + + for ( var i = 1, curData; curData = data[ i ]; i++ ) { + series.push( { + name: curData[ 0 ], + data: curData.slice( 1 ) + } ); + } + + result.series = series; + result.categories = categories; + result.title = meta.title; + result.subTitle = meta.subTitle; + result.xTitle = meta.xTitle; + result.yTitle = meta.yTitle; + result.suffix = meta.suffix; + + } else { + + var curData = []; + + for ( var i = 1, len = data[ 0 ].length; i < len; i++ ) { + + curData.push( [ data[ 0 ][ i ], data[ 1 ][ i ] | 0 ] ); + + } + + //饼图 + series[ 0 ] = { + type: 'pie', + name: meta.tip, + data: curData + }; + + result.series = series; + result.title = meta.title; + result.suffix = meta.suffix; + + } + + return result; + + } + +}); +UE.parse.register('background', function (utils) { + var me = this, + root = me.root, + p = root.getElementsByTagName('p'), + styles; + + for (var i = 0,ci; ci = p[i++];) { + styles = ci.getAttribute('data-background'); + if (styles){ + ci.parentNode.removeChild(ci); + } + } + + //追加默认的表格样式 + styles && utils.cssRule('ueditor_background', me.selector + '{' + styles + '}', document); +}); +UE.parse.register('list',function(utils){ + var customCss = [], + customStyle = { + 'cn' : 'cn-1-', + 'cn1' : 'cn-2-', + 'cn2' : 'cn-3-', + 'num' : 'num-1-', + 'num1' : 'num-2-', + 'num2' : 'num-3-', + 'dash' : 'dash', + 'dot' : 'dot' + }; + + + utils.extend(this,{ + liiconpath : 'http://bs.baidu.com/listicon/', + listDefaultPaddingLeft : '20' + }); + + var root = this.root, + ols = root.getElementsByTagName('ol'), + uls = root.getElementsByTagName('ul'), + selector = this.selector; + + if(ols.length){ + applyStyle.call(this,ols); + } + + if(uls.length){ + applyStyle.call(this,uls); + } + + if(ols.length || uls.length){ + customCss.push(selector +' .list-paddingleft-1{padding-left:0}'); + customCss.push(selector +' .list-paddingleft-2{padding-left:'+ this.listDefaultPaddingLeft+'px}'); + customCss.push(selector +' .list-paddingleft-3{padding-left:'+ this.listDefaultPaddingLeft*2+'px}'); + + utils.cssRule('list', selector +' ol,'+selector +' ul{margin:0;padding:0;}li{clear:both;}'+customCss.join('\n'), document); + } + function applyStyle(nodes){ + var T = this; + utils.each(nodes,function(list){ + if(list.className && /custom_/i.test(list.className)){ + var listStyle = list.className.match(/custom_(\w+)/)[1]; + if(listStyle == 'dash' || listStyle == 'dot'){ + utils.pushItem(customCss,selector +' li.list-' + customStyle[listStyle] + '{background-image:url(' + T.liiconpath +customStyle[listStyle]+'.gif)}'); + utils.pushItem(customCss,selector +' ul.custom_'+listStyle+'{list-style:none;} '+ selector +' ul.custom_'+listStyle+' li{background-position:0 3px;background-repeat:no-repeat}'); + + }else{ + var index = 1; + utils.each(list.childNodes,function(li){ + if(li.tagName == 'LI'){ + utils.pushItem(customCss,selector + ' li.list-' + customStyle[listStyle] + index + '{background-image:url(' + T.liiconpath + 'list-'+customStyle[listStyle] +index + '.gif)}'); + index++; + } + }); + utils.pushItem(customCss,selector + ' ol.custom_'+listStyle+'{list-style:none;}'+selector+' ol.custom_'+listStyle+' li{background-position:0 3px;background-repeat:no-repeat}'); + } + switch(listStyle){ + case 'cn': + utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-1{padding-left:25px}'); + utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-2{padding-left:40px}'); + utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-3{padding-left:55px}'); + break; + case 'cn1': + utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-1{padding-left:30px}'); + utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-2{padding-left:40px}'); + utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-3{padding-left:55px}'); + break; + case 'cn2': + utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-1{padding-left:40px}'); + utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-2{padding-left:55px}'); + utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-3{padding-left:68px}'); + break; + case 'num': + case 'num1': + utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-1{padding-left:25px}'); + break; + case 'num2': + utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-1{padding-left:35px}'); + utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-2{padding-left:40px}'); + break; + case 'dash': + utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft{padding-left:35px}'); + break; + case 'dot': + utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft{padding-left:20px}'); + } + } + }); + } + + +}); +UE.parse.register('vedio',function(utils){ + var video = this.root.getElementsByTagName('video'), + audio = this.root.getElementsByTagName('audio'); + + document.createElement('video');document.createElement('audio'); + if(video.length || audio.length){ + var sourcePath = utils.removeLastbs(this.rootPath), + jsurl = sourcePath + '/third-party/video-js/video.js', + cssurl = sourcePath + '/third-party/video-js/video-js.min.css', + swfUrl = sourcePath + '/third-party/video-js/video-js.swf'; + + if(window.videojs) { + videojs.autoSetup(); + } else { + utils.loadFile(document,{ + id : "video_css", + tag : "link", + rel : "stylesheet", + type : "text/css", + href : cssurl + }); + utils.loadFile(document,{ + id : "video_js", + src : jsurl, + tag : "script", + type : "text/javascript" + },function(){ + videojs.options.flash.swf = swfUrl; + videojs.autoSetup(); + }); + } + + } +}); + +})(); diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/ueditor.parse.min.js b/net452/SiteServer.Web/SiteServer/assets/ueditor/ueditor.parse.min.js new file mode 100644 index 000000000..652460c8d --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/ueditor/ueditor.parse.min.js @@ -0,0 +1,7 @@ +/*! + * UEditor + * version: ueditor + * build: Wed Aug 10 2016 11:05:24 GMT+0800 (CST) + */ + +!function(){!function(){UE=window.UE||{};var a=!!window.ActiveXObject,b={removeLastbs:function(a){return a.replace(/\/$/,"")},extend:function(a,b){for(var c=arguments,d=!!this.isBoolean(c[c.length-1])&&c[c.length-1],e=this.isBoolean(c[c.length-1])?c.length-1:c.length,f=1;f=c&&a===b)return d=e,!1}),d},hasClass:function(a,b){b=b.replace(/(^[ ]+)|([ ]+$)/g,"").replace(/[ ]{2,}/g," ").split(" ");for(var c,d=0,e=a.className;c=b[d++];)if(!new RegExp("\\b"+c+"\\b","i").test(e))return!1;return d-1==b.length},addClass:function(a,c){if(a){c=this.trim(c).replace(/[ ]{2,}/g," ").split(" ");for(var d,e=0,f=a.className;d=c[e++];)new RegExp("\\b"+d+"\\b").test(f)||(f+=" "+d);a.className=b.trim(f)}},removeClass:function(a,b){b=this.isArray(b)?b:this.trim(b).replace(/[ ]{2,}/g," ").split(" ");for(var c,d=0,e=a.className;c=b[d++];)e=e.replace(new RegExp("\\b"+c+"\\b"),"");e=this.trim(e).replace(/[ ]{2,}/g," "),a.className=e,!e&&a.removeAttribute("className")},on:function(a,c,d){var e=this.isArray(c)?c:c.split(/\s+/),f=e.length;if(f)for(;f--;)if(c=e[f],a.addEventListener)a.addEventListener(c,d,!1);else{d._d||(d._d={els:[]});var g=c+d.toString(),h=b.indexOf(d._d.els,a);d._d[g]&&h!=-1||(h==-1&&d._d.els.push(a),d._d[g]||(d._d[g]=function(a){return d.call(a.srcElement,a||window.event)}),a.attachEvent("on"+c,d._d[g]))}a=null},off:function(a,c,d){var e=this.isArray(c)?c:c.split(/\s+/),f=e.length;if(f)for(;f--;)if(c=e[f],a.removeEventListener)a.removeEventListener(c,d,!1);else{var g=c+d.toString();try{a.detachEvent("on"+c,d._d?d._d[g]:d)}catch(h){}if(d._d&&d._d[g]){var i=b.indexOf(d._d.els,a);i!=-1&&d._d.els.splice(i,1),0==d._d.els.length&&delete d._d[g]}}},loadFile:function(){function a(a,c){try{for(var d,e=0;d=b[e++];)if(d.doc===a&&d.url==(c.src||c.href))return d}catch(f){return null}}var b=[];return function(c,d,e){var f=a(c,d);if(f)return void(f.ready?e&&e():f.funs.push(e));if(b.push({doc:c,url:d.src||d.href,funs:[e]}),!c.body){var g=[];for(var h in d)"tag"!=h&&g.push(h+'="'+d[h]+'"');return void c.write("<"+d.tag+" "+g.join(" ")+" >")}if(!d.id||!c.getElementById(d.id)){var i=c.createElement(d.tag);delete d.tag;for(var h in d)i.setAttribute(h,d[h]);i.onload=i.onreadystatechange=function(){if(!this.readyState||/loaded|complete/.test(this.readyState)){if(f=a(c,d),f.funs.length>0){f.ready=1;for(var b;b=f.funs.pop();)b()}i.onload=i.onreadystatechange=null}},i.onerror=function(){throw Error("The load "+(d.href||d.src)+" fails,check the url")},c.getElementsByTagName("head")[0].appendChild(i)}}}()};b.each(["String","Function","Array","Number","RegExp","Object","Boolean"],function(a){b["is"+a]=function(b){return Object.prototype.toString.apply(b)=="[object "+a+"]"}});var c={};UE.parse={register:function(a,b){c[a]=b},load:function(a){b.each(c,function(c){c.call(a,b)})}},uParse=function(a,c){b.domReady(function(){var d;if(document.querySelectorAll)d=document.querySelectorAll(a);else if(/^#/.test(a))d=[document.getElementById(a.replace(/^#/,""))];else if(/^\./.test(a)){var d=[];b.each(document.getElementsByTagName("*"),function(b){b.className&&new RegExp("\\b"+a.replace(/^\./,"")+"\\b","i").test(b.className)&&d.push(b)})}else d=document.getElementsByTagName(a);b.each(d,function(d){UE.parse.load(b.extend({root:d,selector:a},c))})})}}(),UE.parse.register("insertcode",function(a){var b=this.root.getElementsByTagName("pre");if(b.length)if("undefined"==typeof XRegExp){var c,d;void 0!==this.rootPath?(c=a.removeLastbs(this.rootPath)+"/third-party/SyntaxHighlighter/shCore.js",d=a.removeLastbs(this.rootPath)+"/third-party/SyntaxHighlighter/shCoreDefault.css"):(c=this.highlightJsUrl,d=this.highlightCssUrl),a.loadFile(document,{id:"syntaxhighlighter_css",tag:"link",rel:"stylesheet",type:"text/css",href:d}),a.loadFile(document,{id:"syntaxhighlighter_js",src:c,tag:"script",type:"text/javascript",defer:"defer"},function(){a.each(b,function(a){a&&/brush/i.test(a.className)&&SyntaxHighlighter.highlight(a)})})}else a.each(b,function(a){a&&/brush/i.test(a.className)&&SyntaxHighlighter.highlight(a)})}),UE.parse.register("table",function(a){function b(b,c){var d,e=b;for(c=a.isArray(c)?c:[c];e;){for(d=0;d0){var g=a[c];a[c]=a[e],a[e]=g}return a}function e(b){if(!a.hasClass(b.rows[0],"firstRow")){for(var c=1;c-1,mac:a.indexOf("macintosh")>-1,quirks:"BackCompat"==document.compatMode};c.gecko="Gecko"==navigator.product&&!c.webkit&&!c.opera&&!c.ie;var d=0;if(c.ie){var e=a.match(/(?:msie\s([\w.]+))/),f=a.match(/(?:trident.*rv:([\w.]+))/);d=e&&f&&e[1]&&f[1]?Math.max(1*e[1],1*f[1]):e&&e[1]?1*e[1]:f&&f[1]?1*f[1]:0,c.ie11Compat=11==document.documentMode,c.ie9Compat=9==document.documentMode,c.ie8=!!document.documentMode,c.ie8Compat=8==document.documentMode,c.ie7Compat=7==d&&!document.documentMode||7==document.documentMode,c.ie6Compat=d<7||c.quirks,c.ie9above=d>8,c.ie9below=d<9,c.ie11above=d>10,c.ie11below=d<11}if(c.gecko){var g=a.match(/rv:([\d\.]+)/);g&&(g=g[1].split("."),d=1e4*g[0]+100*(g[1]||0)+1*(g[2]||0))}return/chrome\/(\d+\.\d)/i.test(a)&&(c.chrome=+RegExp.$1),/(\d+\.\d)?(?:\.\d)?\s+safari\/?(\d+\.\d+)?/i.test(a)&&!/chrome/i.test(a)&&(c.safari=+(RegExp.$1||RegExp.$2)),c.opera&&(d=parseFloat(b.version())),c.webkit&&(d=parseFloat(a.match(/ applewebkit\/(\d+)/)[1])),c.version=d,c.isCompatible=!c.mobile&&(c.ie&&d>=6||c.gecko&&d>=10801||c.opera&&d>=9.5||c.air&&d>=1||c.webkit&&d>=522||!1),c}(),ie=browser.ie,webkit=browser.webkit,gecko=browser.gecko,opera=browser.opera,utils=UE.utils={each:function(a,b,c){if(null!=a)if(a.length===+a.length){for(var d=0,e=a.length;d=c&&a===b)return d=e,!1}),d},removeItem:function(a,b){for(var c=0,d=a.length;c'](?:(amp|lt|quot|gt|#39|nbsp|#\d+);)?/g,function(a,b){return b?a:{"<":"<","&":"&",'"':""",">":">","'":"'"}[a]}):""},unhtmlForUrl:function(a,b){return a?a.replace(b||/[<">']/g,function(a){return{"<":"<","&":"&",'"':""",">":">","'":"'"}[a]}):""},html:function(a){return a?a.replace(/&((g|l|quo)t|amp|#39|nbsp);/g,function(a){return{"<":"<","&":"&",""":'"',">":">","'":"'"," ":" "}[a]}):""},cssStyleToDomStyle:function(){var a=document.createElement("div").style,b={"float":void 0!=a.cssFloat?"cssFloat":void 0!=a.styleFloat?"styleFloat":"float"};return function(a){return b[a]||(b[a]=a.toLowerCase().replace(/-./g,function(a){return a.charAt(1).toUpperCase()}))}}(),loadFile:function(){function a(a,c){try{for(var d,e=0;d=b[e++];)if(d.doc===a&&d.url==(c.src||c.href))return d}catch(f){return null}}var b=[];return function(c,d,e){var f=a(c,d);if(f)return void(f.ready?e&&e():f.funs.push(e));if(b.push({doc:c,url:d.src||d.href,funs:[e]}),!c.body){var g=[];for(var h in d)"tag"!=h&&g.push(h+'="'+d[h]+'"');return void c.write("<"+d.tag+" "+g.join(" ")+" >")}if(!d.id||!c.getElementById(d.id)){var i=c.createElement(d.tag);delete d.tag;for(var h in d)i.setAttribute(h,d[h]);i.onload=i.onreadystatechange=function(){if(!this.readyState||/loaded|complete/.test(this.readyState)){if(f=a(c,d),f.funs.length>0){f.ready=1;for(var b;b=f.funs.pop();)b()}i.onload=i.onreadystatechange=null}},i.onerror=function(){throw Error("The load "+(d.href||d.src)+" fails,check the url settings of file ueditor.config.js ")},c.getElementsByTagName("head")[0].appendChild(i)}}}(),isEmptyObject:function(a){if(null==a)return!0;if(this.isArray(a)||this.isString(a))return 0===a.length;for(var b in a)if(a.hasOwnProperty(b))return!1;return!0},fixColor:function(a,b){if(/color/i.test(a)&&/rgba?/.test(b)){var c=b.split(",");if(c.length>3)return"";b="#";for(var d,e=0;d=c[e++];)d=parseInt(d.replace(/[^\d]/gi,""),10).toString(16),b+=1==d.length?"0"+d:d;b=b.toUpperCase()}return b},optCss:function(a){function b(a,b){if(!a)return"";var c=a.top,d=a.bottom,e=a.left,f=a.right,g="";if(c&&e&&d&&f)g+=";"+b+":"+(c==d&&d==e&&e==f?c:c==d&&e==f?c+" "+e:e==f?c+" "+e+" "+d:c+" "+f+" "+d+" "+e)+";";else for(var h in a)g+=";"+b+"-"+h+":"+a[h]+";";return g}var c,d;return a=a.replace(/(padding|margin|border)\-([^:]+):([^;]+);?/gi,function(a,b,e,f){if(1==f.split(" ").length)switch(b){case"padding":return!c&&(c={}),c[e]=f,"";case"margin":return!d&&(d={}),d[e]=f,"";case"border":return"initial"==f?"":a}return a}),a+=b(c,"padding")+b(d,"margin"),a.replace(/^[ \n\r\t;]*|[ \n\r\t]*$/,"").replace(/;([ \n\r\t]+)|\1;/g,";").replace(/(&((l|g)t|quot|#39))?;{2,}/g,function(a,b){return b?b+";;":";"})},clone:function(a,b){var c;b=b||{};for(var d in a)a.hasOwnProperty(d)&&(c=a[d],"object"==typeof c?(b[d]=utils.isArray(c)?[]:{},utils.clone(a[d],b[d])):b[d]=c);return b},transUnitToPx:function(a){if(!/(pt|cm)/.test(a))return a;var b;switch(a.replace(/([\d.]+)(\w+)/,function(c,d,e){a=d,b=e}),b){case"cm":a=25*parseFloat(a);break;case"pt":a=Math.round(96*parseFloat(a)/72)}return a+(a?"px":"")},domReady:function(){function a(a){a.isReady=!0;for(var c;c=b.pop();c());}var b=[];return function(c,d){d=d||window;var e=d.document;c&&b.push(c),"complete"===e.readyState?a(e):(e.isReady&&a(e),browser.ie&&11!=browser.version?(!function(){if(!e.isReady){try{e.documentElement.doScroll("left")}catch(b){return void setTimeout(arguments.callee,0)}a(e)}}(),d.attachEvent("onload",function(){a(e)})):(e.addEventListener("DOMContentLoaded",function(){e.removeEventListener("DOMContentLoaded",arguments.callee,!1),a(e)},!1),d.addEventListener("load",function(){a(e)},!1)))}}(),cssRule:browser.ie&&11!=browser.version?function(a,b,c){var d,e;if(void 0===b||b&&b.nodeType&&9==b.nodeType){if(c=b&&b.nodeType&&9==b.nodeType?b:c||document,d=c.indexList||(c.indexList={}),e=d[a],void 0!==e)return c.styleSheets[e].cssText}else{if(c=c||document,d=c.indexList||(c.indexList={}),e=d[a],""===b)return void 0!==e&&(c.styleSheets[e].cssText="",delete d[a],!0);void 0!==e?sheetStyle=c.styleSheets[e]:(sheetStyle=c.createStyleSheet("",e=c.styleSheets.length),d[a]=e),sheetStyle.cssText=b}}:function(a,b,c){var d;return void 0===b||b&&b.nodeType&&9==b.nodeType?(c=b&&b.nodeType&&9==b.nodeType?b:c||document,d=c.getElementById(a),d?d.innerHTML:void 0):(c=c||document,d=c.getElementById(a),""===b?!!d&&(d.parentNode.removeChild(d),!0):void(d?d.innerHTML=b:(d=c.createElement("style"),d.id=a,d.innerHTML=b,c.getElementsByTagName("head")[0].appendChild(d))))},sort:function(a,b){b=b||function(a,b){return a.localeCompare(b)};for(var c=0,d=a.length;c0){var g=a[c];a[c]=a[e],a[e]=g}return a},serializeParam:function(a){var b=[];for(var c in a)if("method"!=c&&"timeout"!=c&&"async"!=c)if("function"!=(typeof a[c]).toLowerCase()&&"object"!=(typeof a[c]).toLowerCase())b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));else if(utils.isArray(a[c]))for(var d=0;d1||b!==a.parentNode){a.style.cssText=b.style.cssText+";"+a.style.cssText,b=b.parentNode;continue}b.style.cssText+=";"+a.style.cssText,"A"==b.tagName&&(b.style.textDecoration="underline")}if("A"!=b.tagName){b===a.parentNode&&domUtils.remove(a,!0);break}}b=b.parentNode}},mergeSibling:function(a,b,c){function d(a,b,c){var d;if((d=c[a])&&!domUtils.isBookmarkNode(d)&&1==d.nodeType&&domUtils.isSameElement(c,d)){for(;d.firstChild;)"firstChild"==b?c.insertBefore(d.lastChild,c.firstChild):c.appendChild(d.firstChild);domUtils.remove(d)}}!b&&d("previousSibling","firstChild",a),!c&&d("nextSibling","lastChild",a)},unSelectable:ie&&browser.ie9below||browser.opera?function(a){a.onselectstart=function(){return!1},a.onclick=a.onkeyup=a.onkeydown=function(){return!1},a.unselectable="on",a.setAttribute("unselectable","on");for(var b,c=0;b=a.all[c++];)switch(b.tagName.toLowerCase()){case"iframe":case"textarea":case"input":case"select":break;default:b.unselectable="on",a.setAttribute("unselectable","on")}}:function(a){a.style.MozUserSelect=a.style.webkitUserSelect=a.style.msUserSelect=a.style.KhtmlUserSelect="none"},removeAttributes:function(a,b){b=utils.isArray(b)?b:utils.trim(b).replace(/[ ]{2,}/g," ").split(" ");for(var c,d=0;c=b[d++];){switch(c=attrFix[c]||c){case"className":a[c]="";break;case"style":a.style.cssText="";var e=a.getAttributeNode("style");!browser.ie&&e&&a.removeAttributeNode(e)}a.removeAttribute(c)}},createElement:function(a,b,c){return domUtils.setAttributes(a.createElement(b),c)},setAttributes:function(a,b){for(var c in b)if(b.hasOwnProperty(c)){var d=b[c];switch(c){case"class":a.className=d;break;case"style":a.style.cssText=a.style.cssText+";"+d;break;case"innerHTML":a[c]=d;break;case"value":a.value=d;break;default:a.setAttribute(attrFix[c]||c,d)}}return a},getComputedStyle:function(a,b){var c="width height top left";if(c.indexOf(b)>-1)return a["offset"+b.replace(/^\w/,function(a){return a.toUpperCase()})]+"px";if(3==a.nodeType&&(a=a.parentNode),browser.ie&&browser.version<9&&"font-size"==b&&!a.style.fontSize&&!dtd.$empty[a.tagName]&&!dtd.$nonChild[a.tagName]){var d=a.ownerDocument.createElement("span");d.style.cssText="padding:0;border:0;font-family:simsun;",d.innerHTML=".",a.appendChild(d);var e=d.offsetHeight;return a.removeChild(d),d=null,e+"px"}try{var f=domUtils.getStyle(a,b)||(window.getComputedStyle?domUtils.getWindow(a).getComputedStyle(a,"").getPropertyValue(b):(a.currentStyle||a.style)[utils.cssStyleToDomStyle(b)])}catch(g){return""}return utils.transUnitToPx(utils.fixColor(b,f))},removeClasses:function(a,b){b=utils.isArray(b)?b:utils.trim(b).replace(/[ ]{2,}/g," ").split(" ");for(var c,d=0,e=a.className;c=b[d++];)e=e.replace(new RegExp("\\b"+c+"\\b"),"");e=utils.trim(e).replace(/[ ]{2,}/g," "),e?a.className=e:domUtils.removeAttributes(a,["class"])},addClass:function(a,b){if(a){b=utils.trim(b).replace(/[ ]{2,}/g," ").split(" ");for(var c,d=0,e=a.className;c=b[d++];)new RegExp("\\b"+c+"\\b").test(e)||(e+=" "+c);a.className=utils.trim(e)}},hasClass:function(a,b){if(utils.isRegExp(b))return b.test(a.className);b=utils.trim(b).replace(/[ ]{2,}/g," ").split(" ");for(var c,d=0,e=a.className;c=b[d++];)if(!new RegExp("\\b"+c+"\\b","i").test(e))return!1;return d-1==b.length},preventDefault:function(a){a.preventDefault?a.preventDefault():a.returnValue=!1},removeStyle:function(a,b){browser.ie?("color"==b&&(b="(^|;)"+b),a.style.cssText=a.style.cssText.replace(new RegExp(b+"[^:]*:[^;]+;?","ig"),"")):a.style.removeProperty?a.style.removeProperty(b):a.style.removeAttribute(utils.cssStyleToDomStyle(b)),a.style.cssText||domUtils.removeAttributes(a,["style"])},getStyle:function(a,b){var c=a.style[utils.cssStyleToDomStyle(b)];return utils.fixColor(b,c)},setStyle:function(a,b,c){a.style[utils.cssStyleToDomStyle(b)]=c,utils.trim(a.style.cssText)||this.removeAttributes(a,"style")},setStyles:function(a,b){for(var c in b)b.hasOwnProperty(c)&&domUtils.setStyle(a,c,b[c])},removeDirtyAttr:function(a){for(var b,c=0,d=a.getElementsByTagName("*");b=d[c++];)b.removeAttribute("_moz_dirty");a.removeAttribute("_moz_dirty")},getChildCount:function(a,b){var c=0,d=a.firstChild;for(b=b||function(){return 1};d;)b(d)&&c++,d=d.nextSibling;return c},isEmptyNode:function(a){return!a.firstChild||0==domUtils.getChildCount(a,function(a){return!domUtils.isBr(a)&&!domUtils.isBookmarkNode(a)&&!domUtils.isWhitespace(a)})},clearSelectedArr:function(a){for(var b;b=a.pop();)domUtils.removeAttributes(b,["class"])},scrollToView:function(a,b,c){var d=function(){var a=b.document,c="CSS1Compat"==a.compatMode;return{width:(c?a.documentElement.clientWidth:a.body.clientWidth)||0,height:(c?a.documentElement.clientHeight:a.body.clientHeight)||0}},e=function(a){if("pageXOffset"in a)return{x:a.pageXOffset||0,y:a.pageYOffset||0};var b=a.document;return{x:b.documentElement.scrollLeft||b.body.scrollLeft||0,y:b.documentElement.scrollTop||b.body.scrollTop||0}},f=d().height,g=f*-1+c;g+=a.offsetHeight||0;var h=domUtils.getXY(a);g+=h.y;var i=e(b).y;(g>i||g0)return 0;for(var c in dtd.$isNotEmpty)if(a.getElementsByTagName(c).length)return 0;return 1},setViewportOffset:function(a,b){var c=0|parseInt(a.style.left),d=0|parseInt(a.style.top),e=a.getBoundingClientRect(),f=b.left-e.left,g=b.top-e.top;f&&(a.style.left=c+f+"px"),g&&(a.style.top=d+g+"px")},fillNode:function(a,b){var c=browser.ie?a.createTextNode(domUtils.fillChar):a.createElement("br");b.innerHTML="",b.appendChild(c)},moveChild:function(a,b,c){for(;a.firstChild;)c&&b.firstChild?b.insertBefore(a.lastChild,b.firstChild):b.appendChild(a.firstChild)},hasNoAttributes:function(a){return browser.ie?/^<\w+\s*?>/.test(a.outerHTML):0==a.attributes.length},isCustomeNode:function(a){return 1==a.nodeType&&a.getAttribute("_ue_custom_node_")},isTagNode:function(a,b){return 1==a.nodeType&&new RegExp("\\b"+a.tagName+"\\b","i").test(b)},filterNodeList:function(a,b,c){var d=[];if(!utils.isFunction(b)){var e=b;b=function(a){return utils.indexOf(utils.isArray(e)?e:e.split(" "),a.tagName.toLowerCase())!=-1}}return utils.each(a,function(a){b(a)&&d.push(a)}),0==d.length?null:1!=d.length&&c?d:d[0]},isInNodeEndBoundary:function(a,b){var c=a.startContainer;if(3==c.nodeType&&a.startOffset!=c.nodeValue.length)return 0;if(1==c.nodeType&&a.startOffset!=c.childNodes.length)return 0;for(;c!==b;){if(c.nextSibling)return 0;c=c.parentNode}return 1},isBoundaryNode:function(a,b){for(var c;!domUtils.isBody(a);)if(c=a,a=a.parentNode,c!==a[b])return!1;return!0},fillHtml:browser.ie11below?" ":"
          "},fillCharReg=new RegExp(domUtils.fillChar,"g");!function(){function a(a){a.collapsed=a.startContainer&&a.endContainer&&a.startContainer===a.endContainer&&a.startOffset==a.endOffset}function b(a){return!a.collapsed&&1==a.startContainer.nodeType&&a.startContainer===a.endContainer&&a.endOffset-a.startOffset==1}function c(b,c,d,e){return 1==c.nodeType&&(dtd.$empty[c.tagName]||dtd.$nonChild[c.tagName])&&(d=domUtils.getNodeIndex(c)+(b?0:1),c=c.parentNode),b?(e.startContainer=c,e.startOffset=d,e.endContainer||e.collapse(!0)):(e.endContainer=c,e.endOffset=d,e.startContainer||e.collapse(!1)),a(e),e}function d(a,b){var c,d,e=a.startContainer,f=a.endContainer,g=a.startOffset,h=a.endOffset,i=a.document,j=i.createDocumentFragment();if(1==e.nodeType&&(e=e.childNodes[g]||(c=e.appendChild(i.createTextNode("")))),1==f.nodeType&&(f=f.childNodes[h]||(d=f.appendChild(i.createTextNode("")))),e===f&&3==e.nodeType)return j.appendChild(i.createTextNode(e.substringData(g,h-g))),b&&(e.deleteData(g,h-g),a.collapse(!0)),j;for(var k,l,m=j,n=domUtils.findParents(e,!0),o=domUtils.findParents(f,!0),p=0;n[p]==o[p];)p++;for(var q,r=p;q=n[r];r++){for(k=q.nextSibling,q==e?c||(3==a.startContainer.nodeType?(m.appendChild(i.createTextNode(e.nodeValue.slice(g))),b&&e.deleteData(g,e.nodeValue.length-g)):m.appendChild(b?e:e.cloneNode(!0))):(l=q.cloneNode(!1),m.appendChild(l));k&&k!==f&&k!==o[r];)q=k.nextSibling,m.appendChild(b?k:k.cloneNode(!0)),k=q;m=l}m=j,n[p]||(m.appendChild(n[p-1].cloneNode(!1)),m=m.firstChild);for(var s,r=p;s=o[r];r++){if(k=s.previousSibling,s==f?d||3!=a.endContainer.nodeType||(m.appendChild(i.createTextNode(f.substringData(0,h))),b&&f.deleteData(0,h)):(l=s.cloneNode(!1),m.appendChild(l)),r!=p||!n[p])for(;k&&k!==e;)s=k.previousSibling,m.insertBefore(b?k:k.cloneNode(!0),m.firstChild),k=s;m=l}return b&&a.setStartBefore(o[p]?n[p]?o[p]:n[p-1]:o[p-1]).collapse(!0),c&&domUtils.remove(c),d&&domUtils.remove(d),j}function e(a,b){try{if(g&&domUtils.inDoc(g,a))if(g.nodeValue.replace(fillCharReg,"").length)g.nodeValue=g.nodeValue.replace(fillCharReg,"");else{var c=g.parentNode;for(domUtils.remove(g);c&&domUtils.isEmptyInlineElement(c)&&(browser.safari?!(domUtils.getPosition(c,b)&domUtils.POSITION_CONTAINS):!c.contains(b));)g=c.parentNode,domUtils.remove(c),c=g}}catch(d){} +}function f(a,b){var c;for(a=a[b];a&&domUtils.isFillChar(a);)c=a[b],domUtils.remove(a),a=c}var g,h=0,i=domUtils.fillChar,j=dom.Range=function(a){var b=this;b.startContainer=b.startOffset=b.endContainer=b.endOffset=null,b.document=a,b.collapsed=!0};j.prototype={cloneContents:function(){return this.collapsed?null:d(this,0)},deleteContents:function(){var a;return this.collapsed||d(this,1),browser.webkit&&(a=this.startContainer,3!=a.nodeType||a.nodeValue.length||(this.setStartBefore(a).collapse(!0),domUtils.remove(a))),this},extractContents:function(){return this.collapsed?null:d(this,2)},setStart:function(a,b){return c(!0,a,b,this)},setEnd:function(a,b){return c(!1,a,b,this)},setStartAfter:function(a){return this.setStart(a.parentNode,domUtils.getNodeIndex(a)+1)},setStartBefore:function(a){return this.setStart(a.parentNode,domUtils.getNodeIndex(a))},setEndAfter:function(a){return this.setEnd(a.parentNode,domUtils.getNodeIndex(a)+1)},setEndBefore:function(a){return this.setEnd(a.parentNode,domUtils.getNodeIndex(a))},setStartAtFirst:function(a){return this.setStart(a,0)},setStartAtLast:function(a){return this.setStart(a,3==a.nodeType?a.nodeValue.length:a.childNodes.length)},setEndAtFirst:function(a){return this.setEnd(a,0)},setEndAtLast:function(a){return this.setEnd(a,3==a.nodeType?a.nodeValue.length:a.childNodes.length)},selectNode:function(a){return this.setStartBefore(a).setEndAfter(a)},selectNodeContents:function(a){return this.setStart(a,0).setEndAtLast(a)},cloneRange:function(){var a=this;return new j(a.document).setStart(a.startContainer,a.startOffset).setEnd(a.endContainer,a.endOffset)},collapse:function(a){var b=this;return a?(b.endContainer=b.startContainer,b.endOffset=b.startOffset):(b.startContainer=b.endContainer,b.startOffset=b.endOffset),b.collapsed=!0,b},shrinkBoundary:function(a){function b(a){return 1==a.nodeType&&!domUtils.isBookmarkNode(a)&&!dtd.$empty[a.tagName]&&!dtd.$nonChild[a.tagName]}for(var c,d=this,e=d.collapsed;1==d.startContainer.nodeType&&(c=d.startContainer.childNodes[d.startOffset])&&b(c);)d.setStart(c,0);if(e)return d.collapse(!0);if(!a)for(;1==d.endContainer.nodeType&&d.endOffset>0&&(c=d.endContainer.childNodes[d.endOffset-1])&&b(c);)d.setEnd(c,c.childNodes.length);return d},getCommonAncestor:function(a,c){var d=this,e=d.startContainer,f=d.endContainer;return e===f?a&&b(this)&&(e=e.childNodes[d.startOffset],1==e.nodeType)?e:c&&3==e.nodeType?e.parentNode:e:domUtils.getCommonAncestor(e,f)},trimBoundary:function(a){this.txtToElmBoundary();var b=this.startContainer,c=this.startOffset,d=this.collapsed,e=this.endContainer;if(3==b.nodeType){if(0==c)this.setStartBefore(b);else if(c>=b.nodeValue.length)this.setStartAfter(b);else{var f=domUtils.split(b,c);b===e?this.setEnd(f,this.endOffset-c):b.parentNode===e&&(this.endOffset+=1),this.setStartBefore(f)}if(d)return this.collapse(!0)}return a||(c=this.endOffset,e=this.endContainer,3==e.nodeType&&(0==c?this.setEndBefore(e):(c=c.nodeValue.length&&a["set"+b.replace(/(\w)/,function(a){return a.toUpperCase()})+"After"](c):a["set"+b.replace(/(\w)/,function(a){return a.toUpperCase()})+"Before"](c))}return!a&&this.collapsed||(b(this,"start"),b(this,"end")),this},insertNode:function(a){var b=a,c=1;11==a.nodeType&&(b=a.firstChild,c=a.childNodes.length),this.trimBoundary(!0);var d=this.startContainer,e=this.startOffset,f=d.childNodes[e];return f?d.insertBefore(a,f):d.appendChild(a),b.parentNode===this.endContainer&&(this.endOffset=this.endOffset+c),this.setStartBefore(b)},setCursor:function(a,b){return this.collapse(!a).select(b)},createBookmark:function(a,b){var c,d=this.document.createElement("span");return d.style.cssText="display:none;line-height:0px;",d.appendChild(this.document.createTextNode("‍")),d.id="_baidu_bookmark_start_"+(b?"":h++),this.collapsed||(c=d.cloneNode(!0),c.id="_baidu_bookmark_end_"+(b?"":h++)),this.insertNode(d),c&&this.collapse().insertNode(c).setEndBefore(c),this.setStartAfter(d),{start:a?d.id:d,end:c?a?c.id:c:null,id:a}},moveToBookmark:function(a){var b=a.id?this.document.getElementById(a.start):a.start,c=a.end&&a.id?this.document.getElementById(a.end):a.end;return this.setStartBefore(b),domUtils.remove(b),c?(this.setEndBefore(c),domUtils.remove(c)):this.collapse(!0),this},enlarge:function(a,b){var c,d,e=domUtils.isBody,f=this.document.createTextNode("");if(a){for(d=this.startContainer,1==d.nodeType?d.childNodes[this.startOffset]?c=d=d.childNodes[this.startOffset]:(d.appendChild(f),c=d=f):c=d;;){if(domUtils.isBlockElm(d)){for(d=c;(c=d.previousSibling)&&!domUtils.isBlockElm(c);)d=c;this.setStartBefore(d);break}c=d,d=d.parentNode}for(d=this.endContainer,1==d.nodeType?((c=d.childNodes[this.endOffset])?d.insertBefore(f,c):d.appendChild(f),c=d=f):c=d;;){if(domUtils.isBlockElm(d)){for(d=c;(c=d.nextSibling)&&!domUtils.isBlockElm(c);)d=c;this.setEndAfter(d);break}c=d,d=d.parentNode}f.parentNode===this.endContainer&&this.endOffset--,domUtils.remove(f)}if(!this.collapsed){for(;!(0!=this.startOffset||b&&b(this.startContainer)||e(this.startContainer));)this.setStartBefore(this.startContainer);for(;!(this.endOffset!=(1==this.endContainer.nodeType?this.endContainer.childNodes.length:this.endContainer.nodeValue.length)||b&&b(this.endContainer)||e(this.endContainer));)this.setEndAfter(this.endContainer)}return this},enlargeToBlockElm:function(a){for(;!domUtils.isBlockElm(this.startContainer);)this.setStartBefore(this.startContainer);if(!a)for(;!domUtils.isBlockElm(this.endContainer);)this.setEndAfter(this.endContainer);return this},adjustmentBoundary:function(){if(!this.collapsed){for(;!domUtils.isBody(this.startContainer)&&this.startOffset==this.startContainer[3==this.startContainer.nodeType?"nodeValue":"childNodes"].length&&this.startContainer[3==this.startContainer.nodeType?"nodeValue":"childNodes"].length;)this.setStartAfter(this.startContainer);for(;!domUtils.isBody(this.endContainer)&&!this.endOffset&&this.endContainer[3==this.endContainer.nodeType?"nodeValue":"childNodes"].length;)this.setEndBefore(this.endContainer)}return this},applyInlineStyle:function(a,b,c){if(this.collapsed)return this;this.trimBoundary().enlarge(!1,function(a){return 1==a.nodeType&&domUtils.isBlockElm(a)}).adjustmentBoundary();for(var d,e,f=this.createBookmark(),g=f.end,h=function(a){return 1==a.nodeType?"br"!=a.tagName.toLowerCase():!domUtils.isWhitespace(a)},i=domUtils.getNextDomNode(f.start,!1,h),j=this.cloneRange();i&&domUtils.getPosition(i,g)&domUtils.POSITION_PRECEDING;)if(3==i.nodeType||dtd[a][i.tagName]){for(j.setStartBefore(i),d=i;d&&(3==d.nodeType||dtd[a][d.tagName])&&d!==g;)e=d,d=domUtils.getNextDomNode(d,1==d.nodeType,null,function(b){return dtd[a][b.tagName]});var k,l=j.setEndAfter(e).extractContents();if(c&&c.length>0){var m,n;n=m=c[0].cloneNode(!1);for(var o,p=1;o=c[p++];)m.appendChild(o.cloneNode(!1)),m=m.firstChild;k=m}else k=j.document.createElement(a);b&&domUtils.setAttributes(k,b),k.appendChild(l),j.insertNode(c?n:k);var q;if("span"==a&&b.style&&/text\-decoration/.test(b.style)&&(q=domUtils.findParentByTagName(k,"a",!0))?(domUtils.setAttributes(q,b),domUtils.remove(k,!0),k=q):(domUtils.mergeSibling(k),domUtils.clearEmptySibling(k)),domUtils.mergeChild(k,b),i=domUtils.getNextDomNode(k,!1,h),domUtils.mergeToParent(k),d===g)break}else i=domUtils.getNextDomNode(i,!0,h);return this.moveToBookmark(f)},removeInlineStyle:function(a){if(this.collapsed)return this;a=utils.isArray(a)?a:[a],this.shrinkBoundary().adjustmentBoundary();for(var b=this.startContainer,c=this.endContainer;;){if(1==b.nodeType){if(utils.indexOf(a,b.tagName.toLowerCase())>-1)break;if("body"==b.tagName.toLowerCase()){b=null;break}}b=b.parentNode}for(;;){if(1==c.nodeType){if(utils.indexOf(a,c.tagName.toLowerCase())>-1)break;if("body"==c.tagName.toLowerCase()){c=null;break}}c=c.parentNode}var d,e,f=this.createBookmark();b&&(e=this.cloneRange().setEndBefore(f.start).setStartBefore(b),d=e.extractContents(),e.insertNode(d),domUtils.clearEmptySibling(b,!0),b.parentNode.insertBefore(f.start,b)),c&&(e=this.cloneRange().setStartAfter(f.end).setEndAfter(c),d=e.extractContents(),e.insertNode(d),domUtils.clearEmptySibling(c,!1,!0),c.parentNode.insertBefore(f.end,c.nextSibling));for(var g,h=domUtils.getNextDomNode(f.start,!1,function(a){return 1==a.nodeType});h&&h!==f.end;)g=domUtils.getNextDomNode(h,!0,function(a){return 1==a.nodeType}),utils.indexOf(a,h.tagName.toLowerCase())>-1&&domUtils.remove(h,!0),h=g;return this.moveToBookmark(f)},getClosedNode:function(){var a;if(!this.collapsed){var c=this.cloneRange().adjustmentBoundary().shrinkBoundary();if(b(c)){var d=c.startContainer.childNodes[c.startOffset];d&&1==d.nodeType&&(dtd.$empty[d.tagName]||dtd.$nonChild[d.tagName])&&(a=d)}}return a},select:browser.ie?function(a,b){var c;this.collapsed||this.shrinkBoundary();var d=this.getClosedNode();if(d&&!b){try{c=this.document.body.createControlRange(),c.addElement(d),c.select()}catch(h){}return this}var j,k=this.createBookmark(),l=k.start;if(c=this.document.body.createTextRange(),c.moveToElementText(l),c.moveStart("character",1),this.collapsed){if(!a&&3!=this.startContainer.nodeType){var m=this.document.createTextNode(i),n=this.document.createElement("span");n.appendChild(this.document.createTextNode(i)),l.parentNode.insertBefore(n,l),l.parentNode.insertBefore(m,l),e(this.document,m),g=m,f(n,"previousSibling"),f(l,"nextSibling"),c.moveStart("character",-1),c.collapse(!0)}}else{var o=this.document.body.createTextRange();j=k.end,o.moveToElementText(j),c.setEndPoint("EndToEnd",o)}this.moveToBookmark(k),n&&domUtils.remove(n);try{c.select()}catch(h){}return this}:function(a){function b(a){function b(b,c,d){3==b.nodeType&&b.nodeValue.length0)j=k-1;else{if(!(l<0))return{container:d,offset:c(e)};i=k+1}}if(k==-1){if(h.moveToElementText(d),h.setEndPoint("StartToStart",a),f=h.text.replace(/(\r\n|\r)/g,"\n").length,g=d.childNodes,!f)return e=g[g.length-1],{container:e,offset:e.nodeValue.length};for(var m=g.length;f>0;)f-=g[--m].nodeValue.length;return{container:g[m],offset:-f}}if(h.collapse(l>0),h.setEndPoint(l>0?"StartToStart":"EndToStart",a),f=h.text.replace(/(\r\n|\r)/g,"\n").length,!f)return dtd.$empty[e.tagName]||dtd.$nonChild[e.tagName]?{container:d,offset:c(e)+(l>0?0:1)}:{container:e,offset:l>0?0:e.childNodes.length};for(;f>0;)try{var n=e;e=e[l>0?"previousSibling":"nextSibling"],f-=e.nodeValue.length}catch(o){return{container:d,offset:c(n)}}return{container:e,offset:l>0?-f:e.nodeValue.length+f}}function b(b,c){if(b.item)c.selectNode(b.item(0));else{var d=a(b,!0);c.setStart(d.container,d.offset),0!=b.compareEndPoints("StartToEnd",b)&&(d=a(b,!1),c.setEnd(d.container,d.offset))}return c}function c(a){var b;try{b=a.getNative().createRange()}catch(c){return null}var d=b.item?b.item(0):b.parentElement();return(d.ownerDocument||d)===a.document?b:null}var d=dom.Selection=function(a){var b,d=this;d.document=a,browser.ie9below&&(b=domUtils.getWindow(a).frameElement,domUtils.on(b,"beforedeactivate",function(){d._bakIERange=d.getIERange()}),domUtils.on(b,"activate",function(){try{!c(d)&&d._bakIERange&&d._bakIERange.select()}catch(a){}d._bakIERange=null})),b=a=null};d.prototype={rangeInBody:function(a,b){var c=browser.ie9below||b?a.item?a.item():a.parentElement():a.startContainer;return c===this.document.body||domUtils.inDoc(c,this.document)},getNative:function(){var a=this.document;try{return a?browser.ie9below?a.selection:domUtils.getWindow(a).getSelection():null}catch(b){return null}},getIERange:function(){var a=c(this);return!a&&this._bakIERange?this._bakIERange:a},cache:function(){this.clear(),this._cachedRange=this.getRange(),this._cachedStartElement=this.getStart(),this._cachedStartElementPath=this.getStartElementPath()},getStartElementPath:function(){if(this._cachedStartElementPath)return this._cachedStartElementPath;var a=this.getStart();return a?domUtils.findParents(a,!0,null,!0):[]},clear:function(){this._cachedStartElementPath=this._cachedRange=this._cachedStartElement=null},isFocus:function(){try{if(browser.ie9below){var a=c(this);return!(!a||!this.rangeInBody(a))}return!!this.getNative().rangeCount}catch(b){return!1}},getRange:function(){function a(a){for(var b=c.document.body.firstChild,d=a.collapsed;b&&b.firstChild;)a.setStart(b,0),b=b.firstChild;a.startContainer||a.setStart(c.document.body,0),d&&a.collapse(!0)}var c=this;if(null!=c._cachedRange)return this._cachedRange;var d=new baidu.editor.dom.Range(c.document);if(browser.ie9below){var e=c.getIERange();if(e)try{b(e,d)}catch(f){a(d)}else a(d)}else{var g=c.getNative();if(g&&g.rangeCount){var h=g.getRangeAt(0),i=g.getRangeAt(g.rangeCount-1);d.setStart(h.startContainer,h.startOffset).setEnd(i.endContainer,i.endOffset),d.collapsed&&domUtils.isBody(d.startContainer)&&!d.startOffset&&a(d)}else{if(this._bakRange&&domUtils.inDoc(this._bakRange.startContainer,this.document))return this._bakRange;a(d)}}return this._bakRange=d},getStart:function(){if(this._cachedStartElement)return this._cachedStartElement;var a,b,c,d,e=browser.ie9below?this.getIERange():this.getRange();if(browser.ie9below){if(!e)return this.document.body.firstChild;if(e.item)return e.item(0);for(a=e.duplicate(),a.text.length>0&&a.moveStart("character",1),a.collapse(1),b=a.parentElement(),d=c=e.parentElement();c=c.parentNode;)if(c==b){b=d;break}}else if(e.shrinkBoundary(),b=e.startContainer,1==b.nodeType&&b.hasChildNodes()&&(b=b.childNodes[Math.min(b.childNodes.length-1,e.startOffset)]),3==b.nodeType)return b.parentNode;return b},getText:function(){var a,b;return this.isFocus()&&(a=this.getNative())?(b=browser.ie9below?a.createRange():a.getRangeAt(0),browser.ie9below?b.text:b.toString()):""},clearRange:function(){this.getNative()[browser.ie9below?"empty":"removeAllRanges"]()}}}(),function(){function a(a,b){var c;if(b.textarea)if(utils.isString(b.textarea)){for(var d,e=0,f=domUtils.getElementsByTagName(a,"textarea");d=f[e++];)if(d.id=="ueditor_textarea_"+b.options.textarea){c=d;break}}else c=b.textarea;c||(a.appendChild(c=domUtils.createElement(document,"textarea",{name:b.options.textarea,id:"ueditor_textarea_"+b.options.textarea,style:"display:none"})),b.textarea=c),!c.getAttribute("name")&&c.setAttribute("name",b.options.textarea),c.value=b.hasContents()?b.options.allHtmlEnabled?b.getAllHtml():b.getContent(null,null,!0):""}function b(a){for(var b in a)return b}function c(a){a.langIsReady=!0,a.fireEvent("langReady")}var d,e=0,f=UE.Editor=function(a){var d=this;d.uid=e++,EventBase.call(d),d.commands={},d.options=utils.extend(utils.clone(a||{}),UEDITOR_CONFIG,!0),d.shortcutkeys={},d.inputRules=[],d.outputRules=[],d.setOpt(f.defaultOptions(d)),d.loadServerConfig(),utils.isEmptyObject(UE.I18N)?utils.loadFile(document,{src:d.options.langPath+d.options.lang+"/"+d.options.lang+".js",tag:"script",type:"text/javascript",defer:"defer"},function(){UE.plugin.load(d),c(d)}):(d.options.lang=b(UE.I18N),UE.plugin.load(d),c(d)),UE.instants["ueditorInstant"+d.uid]=d};f.prototype={registerCommand:function(a,b){this.commands[a]=b},ready:function(a){var b=this;a&&(b.isReady?a.apply(b):b.addListener("ready",a))},setOpt:function(a,b){var c={};utils.isString(a)?c[a]=b:c=a,utils.extend(this.options,c,!0)},getOpt:function(a){return this.options[a]},destroy:function(){var a=this;a.fireEvent("destroy");var b=a.container.parentNode,c=a.textarea;c?c.style.display="":(c=document.createElement("textarea"),b.parentNode.insertBefore(c,b)),c.style.width=a.iframe.offsetWidth+"px",c.style.height=a.iframe.offsetHeight+"px",c.value=a.getContent(),c.id=a.key,b.innerHTML="",domUtils.remove(b);var d=a.key;for(var e in a)a.hasOwnProperty(e)&&delete this[e];UE.delEditor(d)},render:function(a){var b=this,c=b.options,d=function(b){return parseInt(domUtils.getComputedStyle(a,b))};if(utils.isString(a)&&(a=document.getElementById(a)),a){c.initialFrameWidth?c.minFrameWidth=c.initialFrameWidth:c.minFrameWidth=c.initialFrameWidth=a.offsetWidth,c.initialFrameHeight?c.minFrameHeight=c.initialFrameHeight:c.initialFrameHeight=c.minFrameHeight=a.offsetHeight,a.style.width=/%$/.test(c.initialFrameWidth)?"100%":c.initialFrameWidth-d("padding-left")-d("padding-right")+"px",a.style.height=/%$/.test(c.initialFrameHeight)?"100%":c.initialFrameHeight-d("padding-top")-d("padding-bottom")+"px",a.style.zIndex=c.zIndex;var e=(ie&&browser.version<9?"":"")+""+(c.iframeCssUrl?"":"")+(c.initialStyle?"":"")+"";a.appendChild(domUtils.createElement(document,"iframe",{id:"ueditor_"+b.uid,width:"100%",height:"100%",frameborder:"0",src:"javascript:void(function(){document.open();"+(c.customDomain&&document.domain!=location.hostname?'document.domain="'+document.domain+'";':"")+'document.write("'+e+'");document.close();}())'})),a.style.overflow="hidden",setTimeout(function(){/%$/.test(c.initialFrameWidth)&&(c.minFrameWidth=c.initialFrameWidth=a.offsetWidth),/%$/.test(c.initialFrameHeight)&&(c.minFrameHeight=c.initialFrameHeight=a.offsetHeight,a.style.height=c.initialFrameHeight+"px")})}},_setup:function(b){var c=this,d=c.options;ie?(b.body.disabled=!0,b.body.contentEditable=!0,b.body.disabled=!1):b.body.contentEditable=!0,b.body.spellcheck=!1,c.document=b,c.window=b.defaultView||b.parentWindow,c.iframe=c.window.frameElement,c.body=b.body,c.selection=new dom.Selection(b);var e;browser.gecko&&(e=this.selection.getNative())&&e.removeAllRanges(),this._initEvents();for(var f=this.iframe.parentNode;!domUtils.isBody(f);f=f.parentNode)if("FORM"==f.tagName){c.form=f,c.options.autoSyncData?domUtils.on(c.window,"blur",function(){a(f,c)}):domUtils.on(f,"submit",function(){a(this,c)});break}if(d.initialContent)if(d.autoClearinitialContent){var g=c.execCommand;c.execCommand=function(){return c.fireEvent("firstBeforeExecCommand"),g.apply(c,arguments)},this._setDefaultContent(d.initialContent)}else this.setContent(d.initialContent,!1,!0);domUtils.isEmptyNode(c.body)&&(c.body.innerHTML="

          "+(browser.ie?"":"
          ")+"

          "),d.focus&&setTimeout(function(){c.focus(c.options.focusInEnd),!c.options.autoClearinitialContent&&c._selectionChange()},0),c.container||(c.container=this.iframe.parentNode),d.fullscreen&&c.ui&&c.ui.setFullScreen(!0);try{c.document.execCommand("2D-position",!1,!1)}catch(h){}try{c.document.execCommand("enableInlineTableEditing",!1,!1)}catch(h){}try{c.document.execCommand("enableObjectResizing",!1,!1)}catch(h){}c._bindshortcutKeys(),c.isReady=1,c.fireEvent("ready"),d.onready&&d.onready.call(c),browser.ie9below||domUtils.on(c.window,["blur","focus"],function(a){if("blur"==a.type){c._bakRange=c.selection.getRange();try{c._bakNativeRange=c.selection.getNative().getRangeAt(0),c.selection.getNative().removeAllRanges()}catch(a){c._bakNativeRange=null}}else try{c._bakRange&&c._bakRange.select()}catch(a){}}),browser.gecko&&browser.version<=10902&&(c.body.contentEditable=!1,setTimeout(function(){c.body.contentEditable=!0},100),setInterval(function(){c.body.style.height=c.iframe.offsetHeight-20+"px"},100)),!d.isShow&&c.setHide(),d.readonly&&c.setDisabled()},sync:function(b){var c=this,d=b?document.getElementById(b):domUtils.findParent(c.iframe.parentNode,function(a){return"FORM"==a.tagName},!0);d&&a(d,c)},setHeight:function(a,b){a!==parseInt(this.iframe.parentNode.style.height)&&(this.iframe.parentNode.style.height=a+"px"),!b&&(this.options.minFrameHeight=this.options.initialFrameHeight=a),this.body.style.height=a+"px",!b&&this.trigger("setHeight")},addshortcutkey:function(a,b){var c={};b?c[a]=b:c=a,utils.extend(this.shortcutkeys,c)},_bindshortcutKeys:function(){var a=this,b=this.shortcutkeys;a.addListener("keydown",function(c,d){var e=d.keyCode||d.which;for(var f in b)for(var g,h=b[f].split(","),i=0;g=h[i++];){g=g.split(":");var j=g[0],k=g[1];(/^(ctrl)(\+shift)?\+(\d+)$/.test(j.toLowerCase())||/^(\d+)$/.test(j))&&(("ctrl"==RegExp.$1?d.ctrlKey||d.metaKey:0)&&(""!=RegExp.$2?d[RegExp.$2.slice(1)+"Key"]:1)&&e==RegExp.$3||e==RegExp.$1)&&(a.queryCommandState(f,k)!=-1&&a.execCommand(f,k),domUtils.preventDefault(d))}})},getContent:function(a,b,c,d,e){var f=this;if(a&&utils.isFunction(a)&&(b=a,a=""),b?!b():!this.hasContents())return"";f.fireEvent("beforegetcontent");var g=UE.htmlparser(f.body.innerHTML,d);return f.filterOutputRule(g),f.fireEvent("aftergetcontent",a,g),g.toHtml(e)},getAllHtml:function(){var a=this,b=[];if(a.fireEvent("getAllHtml",b),browser.ie&&browser.version>8){var c="";utils.each(a.document.styleSheets,function(a){c+=a.href?'':""}),utils.each(a.document.getElementsByTagName("script"),function(a){c+=a.outerHTML})}return""+(a.options.charset?'':"")+(c||a.document.getElementsByTagName("head")[0].innerHTML)+b.join("\n")+""+a.getContent(null,null,!0)+""},getPlainTxt:function(){var a=new RegExp(domUtils.fillChar,"g"),b=this.body.innerHTML.replace(/[\n\r]/g,"");return b=b.replace(/<(p|div)[^>]*>(| )<\/\1>/gi,"\n").replace(//gi,"\n").replace(/<[^>\/]+>/g,"").replace(/(\n)?<\/([^>]+)>/g,function(a,b,c){return dtd.$block[c]?"\n":b?b:""}),b.replace(a,"").replace(/\u00a0/g," ").replace(/ /g," ")},getContentTxt:function(){var a=new RegExp(domUtils.fillChar,"g");return this.body[browser.ie?"innerText":"textContent"].replace(a,"").replace(/\u00a0/g," ")},setContent:function(b,c,d){function e(a){return"DIV"==a.tagName&&a.getAttribute("cdata_tag")}var f=this;f.fireEvent("beforesetcontent",b);var g=UE.htmlparser(b);if(f.filterInputRule(g),b=g.toHtml(),f.body.innerHTML=(c?f.body.innerHTML:"")+b,"p"==f.options.enterTag){var h,i=this.body.firstChild;if(!i||1==i.nodeType&&(dtd.$cdata[i.tagName]||e(i)||domUtils.isCustomeNode(i))&&i===this.body.lastChild)this.body.innerHTML="

          "+(browser.ie?" ":"
          ")+"

          "+this.body.innerHTML;else for(var j=f.document.createElement("p");i;){for(;i&&(3==i.nodeType||1==i.nodeType&&dtd.p[i.tagName]&&!dtd.$cdata[i.tagName]);)h=i.nextSibling,j.appendChild(i),i=h;if(j.firstChild){if(!i){f.body.appendChild(j);break}i.parentNode.insertBefore(j,i),j=f.document.createElement("p")}i=i.nextSibling}}f.fireEvent("aftersetcontent"),f.fireEvent("contentchange"),!d&&f._selectionChange(),f._bakRange=f._bakIERange=f._bakNativeRange=null;var k;browser.gecko&&(k=this.selection.getNative())&&k.removeAllRanges(),f.options.autoSyncData&&f.form&&a(f.form,f)},focus:function(a){try{var b=this,c=b.selection.getRange();if(a){var d=b.body.lastChild;d&&1==d.nodeType&&!dtd.$empty[d.tagName]&&(domUtils.isEmptyBlock(d)?c.setStartAtFirst(d):c.setStartAtLast(d),c.collapse(!0)),c.setCursor(!0)}else{if(!c.collapsed&&domUtils.isBody(c.startContainer)&&0==c.startOffset){var d=b.body.firstChild;d&&1==d.nodeType&&!dtd.$empty[d.tagName]&&c.setStartAtFirst(d).collapse(!0)}c.select(!0)}this.fireEvent("focus selectionchange")}catch(e){}},isFocus:function(){return this.selection.isFocus()},blur:function(){var a=this.selection.getNative();if(a.empty&&browser.ie){var b=document.body.createTextRange();b.moveToElementText(document.body),b.collapse(!0),b.select(),a.empty()}else a.removeAllRanges()},_initEvents:function(){var a=this,b=a.document,c=a.window;a._proxyDomEvent=utils.bind(a._proxyDomEvent,a),domUtils.on(b,["click","contextmenu","mousedown","keydown","keyup","keypress","mouseup","mouseover","mouseout","selectstart"],a._proxyDomEvent),domUtils.on(c,["focus","blur"],a._proxyDomEvent),domUtils.on(a.body,"drop",function(b){browser.gecko&&b.stopPropagation&&b.stopPropagation(),a.fireEvent("contentchange")}),domUtils.on(b,["mouseup","keydown"],function(b){"keydown"==b.type&&(b.ctrlKey||b.metaKey||b.shiftKey||b.altKey)||2!=b.button&&a._selectionChange(250,b)})},_proxyDomEvent:function(a){return this.fireEvent("before"+a.type.replace(/^on/,"").toLowerCase())!==!1&&(this.fireEvent(a.type.replace(/^on/,""),a)!==!1&&this.fireEvent("after"+a.type.replace(/^on/,"").toLowerCase()))},_selectionChange:function(a,b){var c,e,f=this,g=!1;if(browser.ie&&browser.version<9&&b&&"mouseup"==b.type){var h=this.selection.getRange();h.collapsed||(g=!0,c=b.clientX,e=b.clientY)}clearTimeout(d),d=setTimeout(function(){if(f.selection&&f.selection.getNative()){var a;if(g&&"None"==f.selection.getNative().type){a=f.document.body.createTextRange();try{a.moveToPoint(c,e)}catch(d){a=null}}var h;a&&(h=f.selection.getIERange,f.selection.getIERange=function(){return a}),f.selection.cache(),h&&(f.selection.getIERange=h),f.selection._cachedRange&&f.selection._cachedStartElement&&(f.fireEvent("beforeselectionchange"),f.fireEvent("selectionchange",!!b),f.fireEvent("afterselectionchange"),f.selection.clear())}},a||50)},_callCmdFn:function(a,b){var c,d,e=b[0].toLowerCase();return c=this.commands[e]||UE.commands[e],d=c&&c[a],c&&d||"queryCommandState"!=a?d?d.apply(this,b):void 0:0},execCommand:function(a){a=a.toLowerCase();var b,c=this,d=c.commands[a]||UE.commands[a];return d&&d.execCommand?(d.notNeedUndo||c.__hasEnterExecCommand?(b=this._callCmdFn("execCommand",arguments),!c.__hasEnterExecCommand&&!d.ignoreContentChange&&!c._ignoreContentChange&&c.fireEvent("contentchange")):(c.__hasEnterExecCommand=!0,c.queryCommandState.apply(c,arguments)!=-1&&(c.fireEvent("saveScene"),c.fireEvent.apply(c,["beforeexeccommand",a].concat(arguments)),b=this._callCmdFn("execCommand",arguments),c.fireEvent.apply(c,["afterexeccommand",a].concat(arguments)),c.fireEvent("saveScene")),c.__hasEnterExecCommand=!1),!c.__hasEnterExecCommand&&!d.ignoreContentChange&&!c._ignoreContentChange&&c._selectionChange(),b):null},queryCommandState:function(a){return this._callCmdFn("queryCommandState",arguments)},queryCommandValue:function(a){return this._callCmdFn("queryCommandValue",arguments)},hasContents:function(a){if(a)for(var b,c=0;b=a[c++];)if(this.document.getElementsByTagName(b).length>0)return!0;if(!domUtils.isEmptyBlock(this.body))return!0;for(a=["div"],c=0;b=a[c++];)for(var d,e=domUtils.getElementsByTagName(this.document,b),f=0;d=e[f++];)if(domUtils.isCustomeNode(d))return!0;return!1},reset:function(){this.fireEvent("reset")},setEnabled:function(){var a,b=this;if("false"==b.body.contentEditable){b.body.contentEditable=!0,a=b.selection.getRange();try{a.moveToBookmark(b.lastBk),delete b.lastBk}catch(c){a.setStartAtFirst(b.body).collapse(!0)}a.select(!0),b.bkqueryCommandState&&(b.queryCommandState=b.bkqueryCommandState,delete b.bkqueryCommandState),b.bkqueryCommandValue&&(b.queryCommandValue=b.bkqueryCommandValue,delete b.bkqueryCommandValue),b.fireEvent("selectionchange")}},enable:function(){return this.setEnabled()},setDisabled:function(a){var b=this;a=a?utils.isArray(a)?a:[a]:[],"true"==b.body.contentEditable&&(b.lastBk||(b.lastBk=b.selection.getRange().createBookmark(!0)),b.body.contentEditable=!1,b.bkqueryCommandState=b.queryCommandState,b.bkqueryCommandValue=b.queryCommandValue,b.queryCommandState=function(c){return utils.indexOf(a,c)!=-1?b.bkqueryCommandState.apply(b,arguments):-1},b.queryCommandValue=function(c){return utils.indexOf(a,c)!=-1?b.bkqueryCommandValue.apply(b,arguments):null},b.fireEvent("selectionchange"))},disable:function(a){return this.setDisabled(a)},_setDefaultContent:function(){function a(){var b=this;b.document.getElementById("initContent")&&(b.body.innerHTML="

          "+(ie?"":"
          ")+"

          ",b.removeListener("firstBeforeExecCommand focus",a),setTimeout(function(){b.focus(),b._selectionChange()},0))}return function(b){var c=this;c.body.innerHTML='

          '+b+"

          ",c.addListener("firstBeforeExecCommand focus",a)}}(),setShow:function(){var a=this,b=a.selection.getRange();if("none"==a.container.style.display){try{b.moveToBookmark(a.lastBk),delete a.lastBk}catch(c){b.setStartAtFirst(a.body).collapse(!0)}setTimeout(function(){b.select(!0)},100),a.container.style.display=""}},show:function(){return this.setShow()},setHide:function(){ +var a=this;a.lastBk||(a.lastBk=a.selection.getRange().createBookmark(!0)),a.container.style.display="none"},hide:function(){return this.setHide()},getLang:function(a){var b=UE.I18N[this.options.lang];if(!b)throw Error("not import language file");a=(a||"").split(".");for(var c,d=0;(c=a[d++])&&(b=b[c],b););return b},getContentLength:function(a,b){var c=this.getContent(!1,!1,!0).length;if(a){b=(b||[]).concat(["hr","img","iframe"]),c=this.getContentTxt().replace(/[\t\r\n]+/g,"").length;for(var d,e=0;d=b[e++];)c+=this.document.getElementsByTagName(d).length}return c},addInputRule:function(a){this.inputRules.push(a)},filterInputRule:function(a){for(var b,c=0;b=this.inputRules[c++];)b.call(this,a)},addOutputRule:function(a){this.outputRules.push(a)},filterOutputRule:function(a){for(var b,c=0;b=this.outputRules[c++];)b.call(this,a)},getActionUrl:function(a){var b=this.getOpt(a)||a,c=this.getOpt("imageUrl"),d=this.getOpt("serverUrl");return!d&&c&&(d=c.replace(/^(.*[\/]).+([\.].+)$/,"$1controller$2")),d?(d=d+(d.indexOf("?")==-1?"?":"&")+"action="+(b||""),utils.formatUrl(d)):""}},utils.inherits(f,EventBase)}(),UE.Editor.defaultOptions=function(a){var b=a.options.UEDITOR_HOME_URL;return{isShow:!0,initialContent:"",initialStyle:"",autoClearinitialContent:!1,iframeCssUrl:b+"themes/iframe.css",textarea:"editorValue",focus:!1,focusInEnd:!0,autoClearEmptyNode:!0,fullscreen:!1,readonly:!1,zIndex:999,imagePopup:!0,enterTag:"p",customDomain:!1,lang:"zh-cn",langPath:b+"lang/",theme:"default",themePath:b+"themes/",allHtmlEnabled:!1,scaleEnabled:!1,tableNativeEditInFF:!1,autoSyncData:!0,fileNameFormat:"{time}{rand:6}"}},function(){UE.Editor.prototype.loadServerConfig=function(){function showErrorMsg(a){console&&console.error(a)}var me=this;setTimeout(function(){try{me.options.imageUrl&&me.setOpt("serverUrl",me.options.imageUrl.replace(/^(.*[\/]).+([\.].+)$/,"$1controller$2"));var configUrl=me.getActionUrl("config"),isJsonp=utils.isCrossDomainUrl(configUrl);me._serverConfigLoaded=!1,configUrl&&UE.ajax.request(configUrl,{method:"GET",dataType:isJsonp?"jsonp":"",onsuccess:function(r){try{var config=isJsonp?r:eval("("+r.responseText+")");utils.extend(me.options,config),me.fireEvent("serverConfigLoaded"),me._serverConfigLoaded=!0}catch(e){showErrorMsg(me.getLang("loadconfigFormatError"))}},onerror:function(){showErrorMsg(me.getLang("loadconfigHttpError"))}})}catch(e){showErrorMsg(me.getLang("loadconfigError"))}})},UE.Editor.prototype.isServerConfigLoaded=function(){var a=this;return a._serverConfigLoaded||!1},UE.Editor.prototype.afterConfigReady=function(a){if(a&&utils.isFunction(a)){var b=this,c=function(){a.apply(b,arguments),b.removeListener("serverConfigLoaded",c)};b.isServerConfigLoaded()?a.call(b,"serverConfigLoaded"):b.addListener("serverConfigLoaded",c)}}}(),UE.ajax=function(){function a(a){var b=[];for(var c in a)if("method"!=c&&"timeout"!=c&&"async"!=c&&"dataType"!=c&&"callback"!=c&&void 0!=a[c]&&null!=a[c])if("function"!=(typeof a[c]).toLowerCase()&&"object"!=(typeof a[c]).toLowerCase())b.push(encodeURIComponent(c)+"="+encodeURIComponent(a[c]));else if(utils.isArray(a[c]))for(var d=0;d/gi,"").replace(/]*>[\s\S]*?.<\/v:shape>/gi,function(a){if(browser.opera)return"";try{if(/Bitmap/i.test(a))return"";var c=a.match(/width:([ \d.]*p[tx])/i)[1],d=a.match(/height:([ \d.]*p[tx])/i)[1],e=a.match(/src=\s*"([^"]*)"/i)[1];return''}catch(f){return""}}).replace(/<\/?div[^>]*>/g,"").replace(/v:\w+=(["']?)[^'"]+\1/g,"").replace(/<(!|script[^>]*>.*?<\/script(?=[>\s])|\/?(\?xml(:\w+)?|xml|meta|link|style|\w+:\w+)(?=[\s\/>]))[^>]*>/gi,"").replace(/

          ]*class="?MsoHeading"?[^>]*>(.*?)<\/p>/gi,"

          $1

          ").replace(/\s+(class|lang|align)\s*=\s*(['"]?)([\w-]+)\2/gi,function(a,b,c,d){return"class"==b&&"MsoListParagraph"==d?a:""}).replace(/<(font|span)[^>]*>(\s*)<\/\1>/gi,function(a,b,c){return c.replace(/[\t\r\n ]+/g," ")}).replace(/(<[a-z][^>]*)\sstyle=(["'])([^\2]*?)\2/gi,function(a,c,d,e){for(var f,g=[],h=e.replace(/^\s+|\s+$/,"").replace(/'/g,"'").replace(/"/gi,"'").replace(/[\d.]+(cm|pt)/g,function(a){return utils.transUnitToPx(a)}).split(/;\s*/g),i=0;f=h[i];i++){var j,k,l=f.split(":");if(2==l.length){if(j=l[0].toLowerCase(),k=l[1].toLowerCase(),/^(background)\w*/.test(j)&&0==k.replace(/(initial|\s)/g,"").length||/^(margin)\w*/.test(j)&&/^0\w+$/.test(k))continue;switch(j){case"mso-padding-alt":case"mso-padding-top-alt":case"mso-padding-right-alt":case"mso-padding-bottom-alt":case"mso-padding-left-alt":case"mso-margin-alt":case"mso-margin-top-alt":case"mso-margin-right-alt":case"mso-margin-bottom-alt":case"mso-margin-left-alt":case"mso-height":case"mso-width":case"mso-vertical-align-alt":/1&&(a(h,j,!0),b(h,j)),c(k,h,i,j);break;case"text":d(g,h);break;case"element":e(g,h,i,j);break;case"comment":f(g,h,i)}return h}function d(a,b){"pre"==a.parentNode.tagName?b.push(a.data):b.push(l[a.parentNode.tagName]?utils.html(a.data):a.data.replace(/[ ]{2}/g,"  "))}function e(d,e,f,g){var h="";if(d.attrs){h=[];var i=d.attrs;for(var j in i)h.push(j+(void 0!==i[j]?'="'+(k[j]?utils.html(i[j]).replace(/["]/g,function(a){return"""}):utils.unhtml(i[j]))+'"':""));h=h.join(" ")}if(e.push("<"+d.tagName+(h?" "+h:"")+(dtd.$empty[d.tagName]?"/":"")+">"),f&&!dtd.$inlineWithA[d.tagName]&&"pre"!=d.tagName&&d.children&&d.children.length&&(g=a(e,g,!0),b(e,g)),d.children&&d.children.length)for(var l,m=0;l=d.children[m++];)f&&"element"==l.type&&!dtd.$inlineWithA[l.tagName]&&m>1&&(a(e,g),b(e,g)),c(l,e,f,g);dtd.$empty[d.tagName]||(f&&!dtd.$inlineWithA[d.tagName]&&"pre"!=d.tagName&&d.children&&d.children.length&&(g=a(e,g),b(e,g)),e.push(""))}function f(a,b){b.push("")}function g(a,b){var c;if("element"==a.type&&a.getAttr("id")==b)return a;if(a.children&&a.children.length)for(var d,e=0;d=a.children[e++];)if(c=g(d,b))return c}function h(a,b,c){if("element"==a.type&&a.tagName==b&&c.push(a),a.children&&a.children.length)for(var d,e=0;d=a.children[e++];)h(d,b,c)}function i(a,b){if(a.children&&a.children.length)for(var c,d=0;c=a.children[d];)i(c,b),c.parentNode&&(c.children&&c.children.length&&b(c),c.parentNode&&d++);else b(a)}var j=UE.uNode=function(a){this.type=a.type,this.data=a.data,this.tagName=a.tagName,this.parentNode=a.parentNode,this.attrs=a.attrs||{},this.children=a.children},k={href:1,src:1,_src:1,_href:1,cdata_data:1},l={style:1,script:1},m=" ",n="\n";j.createElement=function(a){return/[<>]/.test(a)?UE.htmlparser(a).children[0]:new j({type:"element",children:[],tagName:a})},j.createText=function(a,b){return new UE.uNode({type:"text",data:b?a:utils.unhtml(a||"")})},j.prototype={toHtml:function(a){var b=[];return c(this,b,a,0),b.join("")},innerHTML:function(a){if("element"!=this.type||dtd.$empty[this.tagName])return this;if(utils.isString(a)){if(this.children)for(var b,c=0;b=this.children[c++];)b.parentNode=null;this.children=[];for(var b,d=UE.htmlparser(a),c=0;b=d.children[c++];)this.children.push(b),b.parentNode=this;return this}var d=new UE.uNode({type:"root",children:this.children});return d.toHtml()},innerText:function(a,b){if("element"!=this.type||dtd.$empty[this.tagName])return this;if(a){if(this.children)for(var c,d=0;c=this.children[d++];)c.parentNode=null;return this.children=[],this.appendChild(j.createText(a,b)),this}return this.toHtml().replace(/<[^>]+>/g,"")},getData:function(){return"element"==this.type?"":this.data},firstChild:function(){return this.children?this.children[0]:null},lastChild:function(){return this.children?this.children[this.children.length-1]:null},previousSibling:function(){for(var a,b=this.parentNode,c=0;a=b.children[c];c++)if(a===this)return 0==c?null:b.children[c-1]},nextSibling:function(){for(var a,b=this.parentNode,c=0;a=b.children[c++];)if(a===this)return b.children[c]},replaceChild:function(a,b){if(this.children){a.parentNode&&a.parentNode.removeChild(a);for(var c,d=0;c=this.children[d];d++)if(c===b)return this.children.splice(d,1,a),b.parentNode=null,a.parentNode=this,a}},appendChild:function(a){if("root"==this.type||"element"==this.type&&!dtd.$empty[this.tagName]){this.children||(this.children=[]),a.parentNode&&a.parentNode.removeChild(a);for(var b,c=0;b=this.children[c];c++)if(b===a){this.children.splice(c,1);break}return this.children.push(a),a.parentNode=this,a}},insertBefore:function(a,b){if(this.children){a.parentNode&&a.parentNode.removeChild(a);for(var c,d=0;c=this.children[d];d++)if(c===b)return this.children.splice(d,0,a),a.parentNode=this,a}},insertAfter:function(a,b){if(this.children){a.parentNode&&a.parentNode.removeChild(a);for(var c,d=0;c=this.children[d];d++)if(c===b)return this.children.splice(d+1,0,a),a.parentNode=this,a}},removeChild:function(a,b){if(this.children)for(var c,d=0;c=this.children[d];d++)if(c===a){if(this.children.splice(d,1),c.parentNode=null,b&&c.children&&c.children.length)for(var e,f=0;e=c.children[f];f++)this.children.splice(d+f,0,e),e.parentNode=this;return c}},getAttr:function(a){return this.attrs&&this.attrs[a.toLowerCase()]},setAttr:function(a,b){if(!a)return void delete this.attrs;if(this.attrs||(this.attrs={}),utils.isObject(a))for(var c in a)a[c]?this.attrs[c.toLowerCase()]=a[c]:delete this.attrs[c];else b?this.attrs[a.toLowerCase()]=b:delete this.attrs[a]},getIndex:function(){for(var a,b=this.parentNode,c=0;a=b.children[c];c++)if(a===this)return c;return-1},getNodeById:function(a){var b;if(this.children&&this.children.length)for(var c,d=0;c=this.children[d++];)if(b=g(c,a))return b},getNodesByTagName:function(a){a=utils.trim(a).replace(/[ ]{2,}/g," ").split(" ");var b=[],c=this;return utils.each(a,function(a){if(c.children&&c.children.length)for(var d,e=0;d=c.children[e++];)h(d,a,b)}),b},getStyle:function(a){var b=this.getAttr("style");if(!b)return"";var c=new RegExp("(^|;)\\s*"+a+":([^;]+)","i"),d=b.match(c);return d&&d[0]?d[2]:""},setStyle:function(a,b){function c(a,b){var c=new RegExp("(^|;)\\s*"+a+":([^;]+;?)","gi");d=d.replace(c,"$1"),b&&(d=a+":"+utils.unhtml(b)+";"+d)}var d=this.getAttr("style");if(d||(d=""),utils.isObject(a))for(var e in a)c(e,a[e]);else c(a,b);this.setAttr("style",utils.trim(d))},traversal:function(a){return this.children&&this.children.length&&i(this,a),this}}}();var htmlparser=UE.htmlparser=function(a,b){function c(a,b){if(m[a.tagName]){var c=k.createElement(m[a.tagName]);a.appendChild(c),c.appendChild(k.createText(b)),a=c}else a.appendChild(k.createText(b))}function d(a,b,c){var e;if(e=l[b]){for(var f,h=a;"root"!=h.type;){if(utils.isArray(e)?utils.indexOf(e,h.tagName)!=-1:e==h.tagName){a=h,f=!0;break}h=h.parentNode}f||(a=d(a,utils.isArray(e)?e[0]:e))}var i=new k({parentNode:a,type:"element",tagName:b.toLowerCase(),children:dtd.$empty[b]?null:[]});if(c){for(var m,n={};m=g.exec(c);)n[m[1].toLowerCase()]=j[m[1].toLowerCase()]?m[2]||m[3]||m[4]:utils.unhtml(m[2]||m[3]||m[4]);i.attrs=n}return a.children.push(i),dtd.$empty[b]?a:i}function e(a,b){a.children.push(new k({type:"comment",data:b,parentNode:a}))}var f=/<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\s\/<>]+)\s*((?:(?:"[^"]*")|(?:'[^']*')|[^"'<>])*)\/?>))/g,g=/([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g,h={b:1,code:1,i:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,span:1,sub:1,img:1,sup:1,font:1,big:1,small:1,iframe:1,a:1,br:1,pre:1};a=a.replace(new RegExp(domUtils.fillChar,"g"),""),b||(a=a.replace(new RegExp("[\\r\\t\\n"+(b?"":" ")+"]*]*)>[\\r\\t\\n"+(b?"":" ")+"]*","g"),function(a,c){return c&&h[c.toLowerCase()]?a.replace(/(^[\n\r]+)|([\n\r]+$)/g,""):a.replace(new RegExp("^[\\r\\n"+(b?"":" ")+"]+"),"").replace(new RegExp("[\\r\\n"+(b?"":" ")+"]+$"),"")}));for(var i,j={href:1,src:1},k=UE.uNode,l={td:"tr",tr:["tbody","thead","tfoot"],tbody:"table",th:"tr",thead:"table",tfoot:"table",caption:"table",li:["ul","ol"],dt:"dl",dd:"dl",option:"select"},m={ol:"li",ul:"li"},n=0,o=0,p=new k({type:"root",children:[]}),q=p;i=f.exec(a);){n=i.index;try{if(n>o&&c(q,a.slice(o,n)),i[3])dtd.$cdata[q.tagName]?c(q,i[0]):q=d(q,i[3].toLowerCase(),i[4]);else if(i[1]){if("root"!=q.type)if(dtd.$cdata[q.tagName]&&!dtd.$cdata[i[1]])c(q,i[0]);else{for(var r=q;"element"==q.type&&q.tagName!=i[1].toLowerCase();)if(q=q.parentNode,"root"==q.type)throw q=r,"break";q=q.parentNode}}else i[2]&&e(q,i[2])}catch(s){}o=f.lastIndex}return o");break;case"div":if(b.getAttr("cdata_tag"))break;if(d=b.getAttr("class"),d&&/^line number\d+/.test(d))break;if(!e)break;for(var f,g=UE.uNode.createElement("p");f=b.firstChild();)"text"!=f.type&&UE.dom.dtd.$block[f.tagName]?g.firstChild()?(b.parentNode.insertBefore(g,b),g=UE.uNode.createElement("p")):b.parentNode.insertBefore(f,b):g.appendChild(f);g.firstChild()&&b.parentNode.insertBefore(g,b),b.parentNode.removeChild(b);break;case"dl":b.tagName="ul";break;case"dt":case"dd":b.tagName="li";break;case"li":var h=b.getAttr("class");h&&/list\-/.test(h)||b.setAttr();var i=b.getNodesByTagName("ol ul");UE.utils.each(i,function(a){b.parentNode.insertAfter(a,b)});break;case"td":case"th":case"caption":b.children&&b.children.length||b.appendChild(browser.ie11below?UE.uNode.createText(" "):UE.uNode.createElement("br"));break;case"table":a.options.disabledTableInTable&&c(b)&&(b.parentNode.insertBefore(UE.uNode.createText(b.innerText()),b),b.parentNode.removeChild(b))}}})}),a.addOutputRule(function(b){var c;b.traversal(function(b){if("element"==b.type){if(a.options.autoClearEmptyNode&&dtd.$inline[b.tagName]&&!dtd.$empty[b.tagName]&&(!b.attrs||utils.isEmptyObject(b.attrs)))return void(b.firstChild()?"span"!=b.tagName||b.attrs&&!utils.isEmptyObject(b.attrs)||b.parentNode.removeChild(b,!0):b.parentNode.removeChild(b));switch(b.tagName){case"div":(c=b.getAttr("cdata_tag"))&&(b.tagName=c,b.appendChild(UE.uNode.createText(b.getAttr("cdata_data"))),b.setAttr({cdata_tag:"",cdata_data:"",_ue_custom_node_:""}));break;case"a":(c=b.getAttr("_href"))&&b.setAttr({href:utils.html(c),_href:""});break;case"span":c=b.getAttr("id"),c&&/^_baidu_bookmark_/i.test(c)&&b.parentNode.removeChild(b);break;case"img":(c=b.getAttr("_src"))&&b.setAttr({src:b.getAttr("_src"),_src:""})}}})})},UE.commands.inserthtml={execCommand:function(a,b,c){var d,e,f=this;if(b&&f.fireEvent("beforeinserthtml",b)!==!0){if(d=f.selection.getRange(),e=d.document.createElement("div"),e.style.display="inline",!c){var g=UE.htmlparser(b);f.options.filterRules&&UE.filterNode(g,f.options.filterRules),f.filterInputRule(g),b=g.toHtml()}if(e.innerHTML=utils.trim(b),!d.collapsed){var h=d.startContainer;if(domUtils.isFillChar(h)&&d.setStartBefore(h),h=d.endContainer,domUtils.isFillChar(h)&&d.setEndAfter(h),d.txtToElmBoundary(),d.endContainer&&1==d.endContainer.nodeType&&(h=d.endContainer.childNodes[d.endOffset],h&&domUtils.isBr(h)&&d.setEndAfter(h)),0==d.startOffset&&(h=d.startContainer,domUtils.isBoundaryNode(h,"firstChild")&&(h=d.endContainer,d.endOffset==(3==h.nodeType?h.nodeValue.length:h.childNodes.length)&&domUtils.isBoundaryNode(h,"lastChild")&&(f.body.innerHTML="

          "+(browser.ie?"":"
          ")+"

          ",d.setStart(f.body.firstChild,0).collapse(!0)))),!d.collapsed&&d.deleteContents(),1==d.startContainer.nodeType){var i,j=d.startContainer.childNodes[d.startOffset];if(j&&domUtils.isBlockElm(j)&&(i=j.previousSibling)&&domUtils.isBlockElm(i)){for(d.setEnd(i,i.childNodes.length).collapse();j.firstChild;)i.appendChild(j.firstChild);domUtils.remove(j)}}}var j,k,i,l,m,n=0;d.inFillChar()&&(j=d.startContainer,domUtils.isFillChar(j)?(d.setStartBefore(j).collapse(!0),domUtils.remove(j)):domUtils.isFillChar(j,!0)&&(j.nodeValue=j.nodeValue.replace(fillCharReg,""),d.startOffset--,d.collapsed&&d.collapse(!0)));var o=domUtils.findParentByTagName(d.startContainer,"li",!0);if(o){for(var p,q;j=e.firstChild;){for(;j&&(3==j.nodeType||!domUtils.isBlockElm(j)||"HR"==j.tagName);)p=j.nextSibling,d.insertNode(j).collapse(),q=j,j=p;if(j)if(/^(ol|ul)$/i.test(j.tagName)){for(;j.firstChild;)q=j.firstChild,domUtils.insertAfter(o,j.firstChild),o=o.nextSibling;domUtils.remove(j)}else{var r;p=j.nextSibling,r=f.document.createElement("li"),domUtils.insertAfter(o,r),r.appendChild(j),q=j,j=p,o=r}}o=domUtils.findParentByTagName(d.startContainer,"li",!0),domUtils.isEmptyBlock(o)&&domUtils.remove(o),q&&d.setStartAfter(q).collapse(!0).select(!0)}else{for(;j=e.firstChild;){if(n){for(var s=f.document.createElement("p");j&&(3==j.nodeType||!dtd.$block[j.tagName]);)m=j.nextSibling,s.appendChild(j),j=m;s.firstChild&&(j=s)}if(d.insertNode(j),m=j.nextSibling,!n&&j.nodeType==domUtils.NODE_ELEMENT&&domUtils.isBlockElm(j)&&(k=domUtils.findParent(j,function(a){return domUtils.isBlockElm(a)}),k&&"body"!=k.tagName.toLowerCase()&&(!dtd[k.tagName][j.nodeName]||j.parentNode!==k))){if(dtd[k.tagName][j.nodeName])for(l=j.parentNode;l!==k;)i=l,l=l.parentNode;else i=k;domUtils.breakParent(j,i||l);var i=j.previousSibling;domUtils.trimWhiteTextNode(i),i.childNodes.length||domUtils.remove(i),!browser.ie&&(p=j.nextSibling)&&domUtils.isBlockElm(p)&&p.lastChild&&!domUtils.isBr(p.lastChild)&&p.appendChild(f.document.createElement("br")),n=1}var p=j.nextSibling;if(!e.firstChild&&p&&domUtils.isBlockElm(p)){d.setStart(p,0).collapse(!0);break}d.setEndAfter(j).collapse()}if(j=d.startContainer,m&&domUtils.isBr(m)&&domUtils.remove(m),domUtils.isBlockElm(j)&&domUtils.isEmptyNode(j))if(m=j.nextSibling)domUtils.remove(j),1==m.nodeType&&dtd.$block[m.tagName]&&d.setStart(m,0).collapse(!0).shrinkBoundary();else try{j.innerHTML=browser.ie?domUtils.fillChar:"
          "}catch(t){d.setStartBefore(j),domUtils.remove(j)}try{d.select(!0)}catch(t){}}setTimeout(function(){d=f.selection.getRange(),d.scrollToView(f.autoHeightEnabled,f.autoHeightEnabled?domUtils.getXY(f.iframe).y:0),f.fireEvent("afterinserthtml",b)},200)}}},UE.plugins.autotypeset=function(){function a(a,b){return a&&3!=a.nodeType?domUtils.isBr(a)?1:a&&a.parentNode&&l[a.tagName.toLowerCase()]?g&&g.contains(a)||a.getAttribute("pagebreak")?0:b?!domUtils.isEmptyBlock(a):domUtils.isEmptyBlock(a,new RegExp("[\\s"+domUtils.fillChar+"]","g")):void 0:0}function b(a){a.style.cssText||(domUtils.removeAttributes(a,["style"]),"span"==a.tagName.toLowerCase()&&domUtils.hasNoAttributes(a)&&domUtils.remove(a,!0))}function c(c,f){var h,l=this;if(f){if(!i.pasteFilter)return;h=l.document.createElement("div"),h.innerHTML=f.html}else h=l.document.body;for(var m,n=domUtils.getElementsByTagName(h,"*"),o=0;m=n[o++];)if(l.fireEvent("excludeNodeinautotype",m)!==!0){if(i.clearFontSize&&m.style.fontSize&&(domUtils.removeStyle(m,"font-size"),b(m)),i.clearFontFamily&&m.style.fontFamily&&(domUtils.removeStyle(m,"font-family"),b(m)),a(m)){if(i.mergeEmptyline)for(var p,q=m.nextSibling,r=domUtils.isBr(m);a(q)&&(p=q,q=p.nextSibling,!r||q&&(!q||domUtils.isBr(q)));)domUtils.remove(p);if(i.removeEmptyline&&domUtils.inDoc(m,h)&&!k[m.parentNode.tagName.toLowerCase()]){if(domUtils.isBr(m)&&(q=m.nextSibling,q&&!domUtils.isBr(q)))continue;domUtils.remove(m);continue}}if(a(m,!0)&&"SPAN"!=m.tagName&&(i.indent&&(m.style.textIndent=i.indentValue),i.textAlign&&(m.style.textAlign=i.textAlign)),i.removeClass&&m.className&&!j[m.className.toLowerCase()]){if(g&&g.contains(m))continue;domUtils.removeAttributes(m,["class"])}if(i.imageBlockLine&&"img"==m.tagName.toLowerCase()&&!m.getAttribute("emotion"))if(f){var s=m;switch(i.imageBlockLine){case"left":case"right":case"none":for(var p,t,q,u=s.parentNode;dtd.$inline[u.tagName]||"A"==u.tagName;)u=u.parentNode;if(p=u,"P"==p.tagName&&"center"==domUtils.getStyle(p,"text-align")&&!domUtils.isBody(p)&&1==domUtils.getChildCount(p,function(a){return!domUtils.isBr(a)&&!domUtils.isWhitespace(a)}))if(t=p.previousSibling,q=p.nextSibling,t&&q&&1==t.nodeType&&1==q.nodeType&&t.tagName==q.tagName&&domUtils.isBlockElm(t)){for(t.appendChild(p.firstChild);q.firstChild;)t.appendChild(q.firstChild);domUtils.remove(p),domUtils.remove(q)}else domUtils.setStyle(p,"text-align","");domUtils.setStyle(s,"float",i.imageBlockLine);break;case"center":if("center"!=l.queryCommandValue("imagefloat")){for(u=s.parentNode,domUtils.setStyle(s,"float","none"),p=s;u&&1==domUtils.getChildCount(u,function(a){return!domUtils.isBr(a)&&!domUtils.isWhitespace(a)})&&(dtd.$inline[u.tagName]||"A"==u.tagName);)p=u,u=u.parentNode;var v=l.document.createElement("p");domUtils.setAttributes(v,{style:"text-align:center"}),p.parentNode.insertBefore(v,p),v.appendChild(p),domUtils.setStyle(p,"float","")}}}else{var w=l.selection.getRange();w.selectNode(m).select(),l.execCommand("imagefloat",i.imageBlockLine)}i.removeEmptyNode&&i.removeTagNames[m.tagName.toLowerCase()]&&domUtils.hasNoAttributes(m)&&domUtils.isEmptyBlock(m)&&domUtils.remove(m)}if(i.tobdc){var x=UE.htmlparser(h.innerHTML);x.traversal(function(a){"text"==a.type&&(a.data=e(a.data))}),h.innerHTML=x.toHtml()}if(i.bdc2sb){var x=UE.htmlparser(h.innerHTML);x.traversal(function(a){"text"==a.type&&(a.data=d(a.data))}),h.innerHTML=x.toHtml()}f&&(f.html=h.innerHTML)}function d(a){for(var b="",c=0;c=65281&&d<=65373?String.fromCharCode(a.charCodeAt(c)-65248):12288==d?String.fromCharCode(a.charCodeAt(c)-12288+32):a.charAt(c)}return b}function e(a){a=utils.html(a);for(var b="",c=0;c0?e.substring(e.indexOf(d.options.imagePath),e.length-1).replace(/"|\(|\)/gi,""):"none"!=e?e.replace(/url\("?|"?\)/gi,""):"";var g=' ",b.push(g)},aftersetcontent:function(){0==c&&b()}},inputRule:function(d){c=!1,utils.each(d.getNodesByTagName("p"),function(d){var e=d.getAttr("data-background");e&&(c=!0,b(a(e)),d.parentNode.removeChild(d))})},outputRule:function(a){var b=this,c=(utils.cssRule(e,b.document)||"").replace(/[\n\r]+/g,"").match(f);c&&a.appendChild(UE.uNode.createElement('


          '))},commands:{background:{execCommand:function(a,c){b(c)},queryCommandValue:function(){var b=this,c=(utils.cssRule(e,b.document)||"").replace(/[\n\r]+/g,"").match(f);return c?a(c[1]):null},notNeedUndo:!0}}}}),UE.commands.imagefloat={execCommand:function(a,b){var c=this,d=c.selection.getRange();if(!d.collapsed){var e=d.getClosedNode();if(e&&"IMG"==e.tagName)switch(b){case"left":case"right":case"none":for(var f,g,h,i=e.parentNode;dtd.$inline[i.tagName]||"A"==i.tagName;)i=i.parentNode;if(f=i,"P"==f.tagName&&"center"==domUtils.getStyle(f,"text-align")){if(!domUtils.isBody(f)&&1==domUtils.getChildCount(f,function(a){return!domUtils.isBr(a)&&!domUtils.isWhitespace(a)}))if(g=f.previousSibling,h=f.nextSibling,g&&h&&1==g.nodeType&&1==h.nodeType&&g.tagName==h.tagName&&domUtils.isBlockElm(g)){for(g.appendChild(f.firstChild);h.firstChild;)g.appendChild(h.firstChild);domUtils.remove(f),domUtils.remove(h)}else domUtils.setStyle(f,"text-align","");d.selectNode(e).select()}domUtils.setStyle(e,"float","none"==b?"":b),"none"==b&&domUtils.removeAttributes(e,"align");break;case"center":if("center"!=c.queryCommandValue("imagefloat")){for(i=e.parentNode,domUtils.setStyle(e,"float",""),domUtils.removeAttributes(e,"align"),f=e;i&&1==domUtils.getChildCount(i,function(a){return!domUtils.isBr(a)&&!domUtils.isWhitespace(a)})&&(dtd.$inline[i.tagName]||"A"==i.tagName);)f=i,i=i.parentNode;d.setStartBefore(f).setCursor(!1),i=c.document.createElement("div"),i.appendChild(f),domUtils.setStyle(f,"float",""),c.execCommand("insertHtml",'

          '+i.innerHTML+"

          "),f=c.document.getElementById("_img_parent_tmp"),f.removeAttribute("id"),f=f.firstChild,d.selectNode(f).select(),h=f.parentNode.nextSibling,h&&domUtils.isEmptyNode(h)&&domUtils.remove(h)}}}},queryCommandValue:function(){var a,b,c=this.selection.getRange();return c.collapsed?"none":(a=c.getClosedNode(),a&&1==a.nodeType&&"IMG"==a.tagName?(b=domUtils.getComputedStyle(a,"float")||a.getAttribute("align"),"none"==b&&(b="center"==domUtils.getComputedStyle(a.parentNode,"text-align")?"center":b),{left:1,right:1,center:1}[b]?b:"none"):"none")},queryCommandState:function(){var a,b=this.selection.getRange();return b.collapsed?-1:(a=b.getClosedNode(),a&&1==a.nodeType&&"IMG"==a.tagName?0:-1)}},UE.commands.insertimage={execCommand:function(a,b){function c(a){utils.each("width,height,border,hspace,vspace".split(","),function(b){a[b]&&(a[b]=parseInt(a[b],10)||0)}),utils.each("src,_src".split(","),function(b){a[b]&&(a[b]=utils.unhtmlForUrl(a[b]))}),utils.each("title,alt".split(","),function(b){a[b]&&(a[b]=utils.unhtml(a[b]))})}if(b=utils.isArray(b)?b:[b],b.length){var d=this,e=d.selection.getRange(),f=e.getClosedNode();if(d.fireEvent("beforeinsertimage",b)!==!0){if(!f||!/img/i.test(f.tagName)||"edui-faked-video"==f.className&&f.className.indexOf("edui-upload-video")==-1||f.getAttribute("word_img")){var g,h=[],i="";if(g=b[0],1==b.length)c(g),i=''+g.alt+'","center"==g.floatStyle&&(i='

          '+i+"

          "),h.push(i);else for(var j=0;g=b[j++];)c(g),i="

          ",h.push(i);d.execCommand("insertHtml",h.join(""))}else{var k=b.shift(),l=k.floatStyle;delete k.floatStyle,domUtils.setAttributes(f,k),d.execCommand("imagefloat",l),b.length>0&&(e.setStartAfter(f).setCursor(!1,!0),d.execCommand("insertimage",b))}d.fireEvent("afterinsertimage",b)}}}},UE.plugins.justify=function(){var a=domUtils.isBlockElm,b={left:1,right:1,center:1,justify:1},c=function(b,c){var d=b.createBookmark(),e=function(a){return 1==a.nodeType?"br"!=a.tagName.toLowerCase()&&!domUtils.isBookmarkNode(a):!domUtils.isWhitespace(a)};b.enlarge(!0);for(var f,g=b.createBookmark(),h=domUtils.getNextDomNode(g.start,!1,e),i=b.cloneRange();h&&!(domUtils.getPosition(h,g.end)&domUtils.POSITION_FOLLOWING);)if(3!=h.nodeType&&a(h))h=domUtils.getNextDomNode(h,!0,e);else{for(i.setStartBefore(h);h&&h!==g.end&&!a(h);)f=h,h=domUtils.getNextDomNode(h,!1,null,function(b){return!a(b)});i.setEndAfter(f);var j=i.getCommonAncestor();if(!domUtils.isBody(j)&&a(j))domUtils.setStyles(j,utils.isString(c)?{"text-align":c}:c),h=j;else{var k=b.document.createElement("p");domUtils.setStyles(k,utils.isString(c)?{"text-align":c}:c);var l=i.extractContents();k.appendChild(l),i.insertNode(k),h=k}h=domUtils.getNextDomNode(h,!1,e)}return b.moveToBookmark(g).moveToBookmark(d)};UE.commands.justify={execCommand:function(a,b){var d,e=this.selection.getRange();return e.collapsed&&(d=this.document.createTextNode("p"),e.insertNode(d)),c(e,b),d&&(e.setStartBefore(d).collapse(!0),domUtils.remove(d)),e.select(),!0},queryCommandValue:function(){var a=this.selection.getStart(),c=domUtils.getComputedStyle(a,"text-align");return b[c]?c:"left"},queryCommandState:function(){var a=this.selection.getStart(),b=a&&domUtils.findParentByTagName(a,["td","th","caption"],!0);return b?-1:0}}},UE.plugins.font=function(){function a(a){for(var b;(b=a.parentNode)&&"SPAN"==b.tagName&&1==domUtils.getChildCount(b,function(a){return!domUtils.isBookmarkNode(a)&&!domUtils.isBr(a)});)b.style.cssText+=a.style.cssText,domUtils.remove(a,!0),a=b}function b(a,b,c){if(g[b]&&(a.adjustmentBoundary(),!a.collapsed&&1==a.startContainer.nodeType)){var d=a.startContainer.childNodes[a.startOffset];if(d&&domUtils.isTagNode(d,"span")){var e=a.createBookmark();utils.each(domUtils.getElementsByTagName(d,"span"),function(a){a.parentNode&&!domUtils.isBookmarkNode(a)&&("backcolor"==b&&domUtils.getComputedStyle(a,"background-color").toLowerCase()===c||(domUtils.removeStyle(a,g[b]),0==a.style.cssText.replace(/^\s+$/,"").length&&domUtils.remove(a,!0)))}),a.moveToBookmark(e)}}}function c(c,d,e){var f,g=c.collapsed,h=c.createBookmark();if(g)for(f=h.start.parentNode;dtd.$inline[f.tagName];)f=f.parentNode;else f=domUtils.getCommonAncestor(h.start,h.end);utils.each(domUtils.getElementsByTagName(f,"span"),function(b){if(b.parentNode&&!domUtils.isBookmarkNode(b)){if(/\s*border\s*:\s*none;?\s*/i.test(b.style.cssText))return void(/^\s*border\s*:\s*none;?\s*$/.test(b.style.cssText)?domUtils.remove(b,!0):domUtils.removeStyle(b,"border"));if(/border/i.test(b.style.cssText)&&"SPAN"==b.parentNode.tagName&&/border/i.test(b.parentNode.style.cssText)&&(b.style.cssText=b.style.cssText.replace(/border[^:]*:[^;]+;?/gi,"")),"fontborder"!=d||"none"!=e)for(var c=b.nextSibling;c&&1==c.nodeType&&"SPAN"==c.tagName;)if(domUtils.isBookmarkNode(c)&&"fontborder"==d)b.appendChild(c),c=b.nextSibling;else{if(c.style.cssText==b.style.cssText&&(domUtils.moveChild(c,b),domUtils.remove(c)),b.nextSibling===c)break;c=b.nextSibling}if(a(b),browser.ie&&browser.version>8){var f=domUtils.findParent(b,function(a){return"SPAN"==a.tagName&&/background-color/.test(a.style.cssText)});f&&!/background-color/.test(b.style.cssText)&&(b.style.backgroundColor=f.style.backgroundColor)}}}),c.moveToBookmark(h),b(c,d,e)}var d=this,e={forecolor:"color",backcolor:"background-color",fontsize:"font-size",fontfamily:"font-family",underline:"text-decoration",strikethrough:"text-decoration",fontborder:"border"},f={underline:1,strikethrough:1,fontborder:1},g={forecolor:"color",backcolor:"background-color",fontsize:"font-size",fontfamily:"font-family"};d.setOpt({fontfamily:[{name:"songti",val:"宋体,SimSun"},{name:"yahei",val:"微软雅黑,Microsoft YaHei"},{name:"kaiti",val:"楷体,楷体_GB2312, SimKai"},{name:"heiti",val:"黑体, SimHei"},{name:"lishu",val:"隶书, SimLi"},{name:"andaleMono",val:"andale mono"},{name:"arial",val:"arial, helvetica,sans-serif"},{name:"arialBlack",val:"arial black,avant garde"},{name:"comicSansMs",val:"comic sans ms"},{name:"impact",val:"impact,chicago"},{name:"timesNewRoman",val:"times new roman"}],fontsize:[10,11,12,14,16,18,20,24,36]}),d.addInputRule(function(a){utils.each(a.getNodesByTagName("u s del font strike"),function(a){if("font"==a.tagName){var b=[];for(var c in a.attrs)switch(c){case"size":b.push("font-size:"+({1:"10",2:"12",3:"16",4:"18",5:"24",6:"32",7:"48"}[a.attrs[c]]||a.attrs[c])+"px");break;case"color":b.push("color:"+a.attrs[c]);break;case"face":b.push("font-family:"+a.attrs[c]);break;case"style":b.push(a.attrs[c])}a.attrs={style:b.join(";")}}else{var d="u"==a.tagName?"underline":"line-through";a.attrs={style:(a.getAttr("style")||"")+"text-decoration:"+d+";"}}a.tagName="span"})});for(var h in e)!function(a,b){UE.commands[a]={execCommand:function(d,e){e=e||(this.queryCommandState(d)?"none":"underline"==d?"underline":"fontborder"==d?"1px solid #000":"line-through");var g,h=this,i=this.selection.getRange();if("default"==e)i.collapsed&&(g=h.document.createTextNode("font"),i.insertNode(g).select()),h.execCommand("removeFormat","span,a",b),g&&(i.setStartBefore(g).collapse(!0),domUtils.remove(g)),c(i,d,e),i.select();else if(i.collapsed){var j=domUtils.findParentByTagName(i.startContainer,"span",!0);if(g=h.document.createTextNode("font"),!j||j.children.length||j[browser.ie?"innerText":"textContent"].replace(fillCharReg,"").length){if(i.insertNode(g),i.selectNode(g).select(),j=i.document.createElement("span"),f[a]){if(domUtils.findParentByTagName(g,"a",!0))return i.setStartBefore(g).setCursor(),void domUtils.remove(g);h.execCommand("removeFormat","span,a",b)}if(j.style.cssText=b+":"+e,g.parentNode.insertBefore(j,g),!browser.ie||browser.ie&&9==browser.version)for(var k=j.parentNode;!domUtils.isBlockElm(k);)"SPAN"==k.tagName&&(j.style.cssText=k.style.cssText+";"+j.style.cssText),k=k.parentNode;opera?setTimeout(function(){i.setStart(j,0).collapse(!0),c(i,d,e),i.select()}):(i.setStart(j,0).collapse(!0),c(i,d,e),i.select())}else i.insertNode(g),f[a]&&(i.selectNode(g).select(),h.execCommand("removeFormat","span,a",b,null),j=domUtils.findParentByTagName(g,"span",!0),i.setStartBefore(g)),j&&(j.style.cssText+=";"+b+":"+e),i.collapse(!0).select();domUtils.remove(g)}else f[a]&&h.queryCommandValue(a)&&h.execCommand("removeFormat","span,a",b),i=h.selection.getRange(),i.applyInlineStyle("span",{style:b+":"+e}),c(i,d,e),i.select();return!0},queryCommandValue:function(a){var c=this.selection.getStart();if("underline"==a||"strikethrough"==a){for(var d,e=c;e&&!domUtils.isBlockElm(e)&&!domUtils.isBody(e);){if(1==e.nodeType&&(d=domUtils.getComputedStyle(e,b),"none"!=d))return d;e=e.parentNode}return"none"}if("fontborder"==a){for(var f,g=c;g&&dtd.$inline[g.tagName];){if((f=domUtils.getComputedStyle(g,"border"))&&/1px/.test(f)&&/solid/.test(f))return f;g=g.parentNode}return""}if("FontSize"==a){var h=domUtils.getComputedStyle(c,b),g=/^([\d\.]+)(\w+)$/.exec(h);return g?Math.floor(g[1])+g[2]:h}return domUtils.getComputedStyle(c,b)},queryCommandState:function(a){if(!f[a])return 0;var b=this.queryCommandValue(a);return"fontborder"==a?/1px/.test(b)&&/solid/.test(b):"underline"==a?/underline/.test(b):/line\-through/.test(b)}}}(h,e[h])},UE.plugins.link=function(){function a(a){var b=a.startContainer,c=a.endContainer;(b=domUtils.findParentByTagName(b,"a",!0))&&a.setStartBefore(b),(c=domUtils.findParentByTagName(c,"a",!0))&&a.setEndAfter(c)}function b(b,c,d){var e=b.cloneRange(),f=d.queryCommandValue("link");a(b=b.adjustmentBoundary());var g=b.startContainer;if(1==g.nodeType&&f&&(g=g.childNodes[b.startOffset],g&&1==g.nodeType&&"A"==g.tagName&&/^(?:https?|ftp|file)\s*:\s*\/\//.test(g[browser.ie?"innerText":"textContent"])&&(g[browser.ie?"innerText":"textContent"]=utils.html(c.textValue||c.href))),e.collapsed&&!f||(b.removeInlineStyle("a"),e=b.cloneRange()),e.collapsed){var h=b.document.createElement("a"),i="";c.textValue?(i=utils.html(c.textValue),delete c.textValue):i=utils.html(c.href),domUtils.setAttributes(h,c),g=domUtils.findParentByTagName(e.startContainer,"a",!0),g&&domUtils.isInNodeEndBoundary(e,g)&&b.setStartAfter(g).collapse(!0),h[browser.ie?"innerText":"textContent"]=i,b.insertNode(h).selectNode(h)}else b.applyInlineStyle("a",c)}UE.commands.unlink={execCommand:function(){var b,c=this.selection.getRange();c.collapsed&&!domUtils.findParentByTagName(c.startContainer,"a",!0)||(b=c.createBookmark(),a(c),c.removeInlineStyle("a").moveToBookmark(b).select())},queryCommandState:function(){return!this.highlight&&this.queryCommandValue("link")?0:-1}},UE.commands.link={execCommand:function(a,c){var d;c._href&&(c._href=utils.unhtml(c._href,/[<">]/g)),c.href&&(c.href=utils.unhtml(c.href,/[<">]/g)),c.textValue&&(c.textValue=utils.unhtml(c.textValue,/[<">]/g)),b(d=this.selection.getRange(),c,this),d.collapse().select(!0)},queryCommandValue:function(){var a,b=this.selection.getRange();if(!b.collapsed){b.shrinkBoundary();var c=3!=b.startContainer.nodeType&&b.startContainer.childNodes[b.startOffset]?b.startContainer.childNodes[b.startOffset]:b.startContainer,d=3==b.endContainer.nodeType||0==b.endOffset?b.endContainer:b.endContainer.childNodes[b.endOffset-1],e=b.getCommonAncestor();if(a=domUtils.findParentByTagName(e,"a",!0),!a&&1==e.nodeType)for(var f,g,h,i=e.getElementsByTagName("a"),j=0;h=i[j++];)if(f=domUtils.getPosition(h,c),g=domUtils.getPosition(h,d),(f&domUtils.POSITION_FOLLOWING||f&domUtils.POSITION_CONTAINS)&&(g&domUtils.POSITION_PRECEDING||g&domUtils.POSITION_CONTAINS)){a=h;break}return a}if(a=b.startContainer,a=1==a.nodeType?a:a.parentNode,a&&(a=domUtils.findParentByTagName(a,"a",!0))&&!domUtils.isInNodeEndBoundary(b,a))return a},queryCommandState:function(){var a=this.selection.getRange().getClosedNode(),b=a&&("edui-faked-video"==a.className||a.className.indexOf("edui-upload-video")!=-1);return b?-1:0}}},UE.plugins.insertframe=function(){function a(){b._iframe&&delete b._iframe}var b=this;b.addListener("selectionchange",function(){a()})},UE.commands.scrawl={queryCommandState:function(){return browser.ie&&browser.version<=8?-1:0}},UE.plugins.removeformat=function(){var a=this;a.setOpt({removeFormatTags:"b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var",removeFormatAttributes:"class,style,lang,width,height,align,hspace,valign"}),a.commands.removeformat={execCommand:function(a,b,c,d,e){function f(a){if(3==a.nodeType||"span"!=a.tagName.toLowerCase())return 0;if(browser.ie){var b=a.attributes;if(b.length){for(var c=0,d=b.length;c
          "+this.getContent(null,null,!0)+"
          "),b.close()},notNeedUndo:1},UE.plugins.selectall=function(){var a=this;a.commands.selectall={execCommand:function(){var a=this,b=a.body,c=a.selection.getRange();c.selectNodeContents(b),domUtils.isEmptyBlock(b)&&(browser.opera&&b.firstChild&&1==b.firstChild.nodeType&&c.setStartAtFirst(b.firstChild),c.collapse(!0)),c.select(!0)},notNeedUndo:1},a.addshortcutkey({selectAll:"ctrl+65"})},UE.plugins.paragraph=function(){var a=this,b=domUtils.isBlockElm,c=["TD","LI","PRE"],d=function(a,d,e,f){var g,h=a.createBookmark(),i=function(a){return 1==a.nodeType?"br"!=a.tagName.toLowerCase()&&!domUtils.isBookmarkNode(a):!domUtils.isWhitespace(a)};a.enlarge(!0);for(var j,k=a.createBookmark(),l=domUtils.getNextDomNode(k.start,!1,i),m=a.cloneRange();l&&!(domUtils.getPosition(l,k.end)&domUtils.POSITION_FOLLOWING);)if(3!=l.nodeType&&b(l))l=domUtils.getNextDomNode(l,!0,i);else{for(m.setStartBefore(l);l&&l!==k.end&&!b(l);)j=l,l=domUtils.getNextDomNode(l,!1,null,function(a){return!b(a)});m.setEndAfter(j),g=a.document.createElement(d),e&&(domUtils.setAttributes(g,e),f&&"customstyle"==f&&e.style&&(g.style.cssText=e.style)),g.appendChild(m.extractContents()),domUtils.isEmptyNode(g)&&domUtils.fillChar(a.document,g),m.insertNode(g);var n=g.parentNode;b(n)&&!domUtils.isBody(g.parentNode)&&utils.indexOf(c,n.tagName)==-1&&(f&&"customstyle"==f||(n.getAttribute("dir")&&g.setAttribute("dir",n.getAttribute("dir")),n.style.cssText&&(g.style.cssText=n.style.cssText+";"+g.style.cssText),n.style.textAlign&&!g.style.textAlign&&(g.style.textAlign=n.style.textAlign),n.style.textIndent&&!g.style.textIndent&&(g.style.textIndent=n.style.textIndent),n.style.padding&&!g.style.padding&&(g.style.padding=n.style.padding)),e&&/h\d/i.test(n.tagName)&&!/h\d/i.test(g.tagName)?(domUtils.setAttributes(n,e),f&&"customstyle"==f&&e.style&&(n.style.cssText=e.style),domUtils.remove(g,!0),g=n):domUtils.remove(g.parentNode,!0)),l=utils.indexOf(c,n.tagName)!=-1?n:g,l=domUtils.getNextDomNode(l,!1,i)}return a.moveToBookmark(k).moveToBookmark(h)};a.setOpt("paragraph",{p:"",h1:"",h2:"",h3:"",h4:"",h5:"",h6:""}),a.commands.paragraph={execCommand:function(a,b,c,e){var f=this.selection.getRange();if(f.collapsed){var g=this.document.createTextNode("p");if(f.insertNode(g),browser.ie){var h=g.previousSibling;h&&domUtils.isWhitespace(h)&&domUtils.remove(h),h=g.nextSibling,h&&domUtils.isWhitespace(h)&&domUtils.remove(h)}}if(f=d(f,b,c,e),g&&(f.setStartBefore(g).collapse(!0),pN=g.parentNode,domUtils.remove(g),domUtils.isBlockElm(pN)&&domUtils.isEmptyNode(pN)&&domUtils.fillNode(this.document,pN)),browser.gecko&&f.collapsed&&1==f.startContainer.nodeType){var i=f.startContainer.childNodes[f.startOffset];i&&1==i.nodeType&&i.tagName.toLowerCase()==b&&f.setStart(i,0).collapse(!0)}return f.select(),!0},queryCommandValue:function(){var a=domUtils.filterNodeList(this.selection.getStartElementPath(),"p h1 h2 h3 h4 h5 h6");return a?a.tagName.toLowerCase():""}}},function(){var a=domUtils.isBlockElm,b=function(a){return domUtils.filterNodeList(a.selection.getStartElementPath(),function(a){return a&&1==a.nodeType&&a.getAttribute("dir")})},c=function(c,d,e){var f,g=function(a){return 1==a.nodeType?!domUtils.isBookmarkNode(a):!domUtils.isWhitespace(a)},h=b(d);if(h&&c.collapsed)return h.setAttribute("dir",e),c;f=c.createBookmark(),c.enlarge(!0);for(var i,j=c.createBookmark(),k=domUtils.getNextDomNode(j.start,!1,g),l=c.cloneRange();k&&!(domUtils.getPosition(k,j.end)&domUtils.POSITION_FOLLOWING);)if(3!=k.nodeType&&a(k))k=domUtils.getNextDomNode(k,!0,g);else{for(l.setStartBefore(k);k&&k!==j.end&&!a(k);)i=k,k=domUtils.getNextDomNode(k,!1,null,function(b){return!a(b)});l.setEndAfter(i);var m=l.getCommonAncestor();if(!domUtils.isBody(m)&&a(m))m.setAttribute("dir",e),k=m;else{var n=c.document.createElement("p");n.setAttribute("dir",e);var o=l.extractContents();n.appendChild(o),l.insertNode(n),k=n}k=domUtils.getNextDomNode(k,!1,g)}return c.moveToBookmark(j).moveToBookmark(f)};UE.commands.directionality={execCommand:function(a,b){var d=this.selection.getRange();if(d.collapsed){var e=this.document.createTextNode("d");d.insertNode(e)}return c(d,this,b),e&&(d.setStartBefore(e).collapse(!0),domUtils.remove(e)),d.select(),!0},queryCommandValue:function(){var a=b(this);return a?a.getAttribute("dir"):"ltr"}}}(),UE.plugins.horizontal=function(){var a=this;a.commands.horizontal={execCommand:function(a){var b=this;if(b.queryCommandState(a)!==-1){b.execCommand("insertHtml","
          ");var c=b.selection.getRange(),d=c.startContainer;if(1==d.nodeType&&!d.childNodes[c.startOffset]){var e;(e=d.childNodes[c.startOffset-1])&&1==e.nodeType&&"HR"==e.tagName&&("p"==b.options.enterTag?(e=b.document.createElement("p"),c.insertNode(e),c.setStart(e,0).setCursor()):(e=b.document.createElement("br"),c.insertNode(e),c.setStartBefore(e).setCursor()))}return!0}},queryCommandState:function(){return domUtils.filterNodeList(this.selection.getStartElementPath(),"table")?-1:0}},a.addListener("delkeydown",function(a,b){var c=this.selection.getRange();if(c.txtToElmBoundary(!0),domUtils.isStartInblock(c)){var d=c.startContainer,e=d.previousSibling;if(e&&domUtils.isTagNode(e,"hr"))return domUtils.remove(e),c.select(),domUtils.preventDefault(b),!0}})},UE.commands.time=UE.commands.date={execCommand:function(a,b){function c(a,b){var c=("0"+a.getHours()).slice(-2),d=("0"+a.getMinutes()).slice(-2),e=("0"+a.getSeconds()).slice(-2);return b=b||"hh:ii:ss",b.replace(/hh/gi,c).replace(/ii/gi,d).replace(/ss/gi,e)}function d(a,b){var c=("000"+a.getFullYear()).slice(-4),d=c.slice(-2),e=("0"+(a.getMonth()+1)).slice(-2),f=("0"+a.getDate()).slice(-2);return b=b||"yyyy-mm-dd",b.replace(/yyyy/gi,c).replace(/yy/gi,d).replace(/mm/gi,e).replace(/dd/gi,f)}var e=new Date;this.execCommand("insertHtml","time"==a?c(e,b):d(e,b))}},UE.plugins.rowspacing=function(){var a=this;a.setOpt({rowspacingtop:["5","10","15","20","25"],rowspacingbottom:["5","10","15","20","25"]}),a.commands.rowspacing={execCommand:function(a,b,c){return this.execCommand("paragraph","p",{style:"margin-"+c+":"+b+"px"}),!0},queryCommandValue:function(a,b){var c,d=domUtils.filterNodeList(this.selection.getStartElementPath(),function(a){return domUtils.isBlockElm(a)});return d?(c=domUtils.getComputedStyle(d,"margin-"+b).replace(/[^\d]/g,""),c?c:0):0}}},UE.plugins.lineheight=function(){var a=this;a.setOpt({lineheight:["1","1.5","1.75","2","3","4","5"]}),a.commands.lineheight={execCommand:function(a,b){return this.execCommand("paragraph","p",{style:"line-height:"+("1"==b?"normal":b+"em")}),!0},queryCommandValue:function(){var a=domUtils.filterNodeList(this.selection.getStartElementPath(),function(a){return domUtils.isBlockElm(a)});if(a){var b=domUtils.getComputedStyle(a,"line-height");return"normal"==b?1:b.replace(/[^\d.]*/gi,"")}}}},UE.plugins.insertcode=function(){var a=this;a.ready(function(){utils.cssRule("pre","pre{margin:.5em 0;padding:.4em .6em;border-radius:8px;background:#f8f8f8;}",a.document)}),a.setOpt("insertcode",{as3:"ActionScript3",bash:"Bash/Shell",cpp:"C/C++",css:"Css",cf:"CodeFunction","c#":"C#",delphi:"Delphi",diff:"Diff",erlang:"Erlang",groovy:"Groovy",html:"Html",java:"Java",jfx:"JavaFx",js:"Javascript",pl:"Perl",php:"Php",plain:"Plain Text",ps:"PowerShell",python:"Python",ruby:"Ruby",scala:"Scala",sql:"Sql",vb:"Vb",xml:"Xml"}),a.commands.insertcode={execCommand:function(a,b){var c=this,d=c.selection.getRange(),e=domUtils.findParentByTagName(d.startContainer,"pre",!0);if(e)e.className="brush:"+b+";toolbar:false;";else{var f="";if(d.collapsed)f=browser.ie&&browser.ie11below?browser.version<=8?" ":"":"
          ";else{var g=d.extractContents(),h=c.document.createElement("div");h.appendChild(g),utils.each(UE.filterNode(UE.htmlparser(h.innerHTML.replace(/[\r\t]/g,"")),c.options.filterTxtRules).children,function(a){if(browser.ie&&browser.ie11below&&browser.version>8)"element"==a.type?"br"==a.tagName?f+="\n":dtd.$empty[a.tagName]||(utils.each(a.children,function(b){"element"==b.type?"br"==b.tagName?f+="\n":dtd.$empty[a.tagName]||(f+=b.innerText()):f+=b.data}),/\n$/.test(f)||(f+="\n")):f+=a.data+"\n",!a.nextSibling()&&/\n$/.test(f)&&(f=f.replace(/\n$/,""));else if(browser.ie&&browser.ie11below)"element"==a.type?"br"==a.tagName?f+="
          ":dtd.$empty[a.tagName]||(utils.each(a.children,function(b){"element"==b.type?"br"==b.tagName?f+="
          ":dtd.$empty[a.tagName]||(f+=b.innerText()):f+=b.data}),/br>$/.test(f)||(f+="
          ")):f+=a.data+"
          ",!a.nextSibling()&&/
          $/.test(f)&&(f=f.replace(/
          $/,""));else if(f+="element"==a.type?dtd.$empty[a.tagName]?"":a.innerText():a.data,!/br\/?\s*>$/.test(f)){if(!a.nextSibling())return;f+="
          "}})}c.execCommand("inserthtml",'
          '+f+"
          ",!0),e=c.document.getElementById("coder"),domUtils.removeAttributes(e,"id");var i=e.previousSibling;i&&(3==i.nodeType&&1==i.nodeValue.length&&browser.ie&&6==browser.version||domUtils.isEmptyBlock(i))&&domUtils.remove(i);var d=c.selection.getRange();domUtils.isEmptyBlock(e)?d.setStart(e,0).setCursor(!1,!0):d.selectNodeContents(e).select()}},queryCommandValue:function(){var a=this.selection.getStartElementPath(),b="";return utils.each(a,function(a){if("PRE"==a.nodeName){var c=a.className.match(/brush:([^;]+)/);return b=c&&c[1]?c[1]:"",!1}}),b}},a.addInputRule(function(a){utils.each(a.getNodesByTagName("pre"),function(a){var b=a.getNodesByTagName("br");if(b.length)return void(browser.ie&&browser.ie11below&&browser.version>8&&utils.each(b,function(a){var b=UE.uNode.createText("\n");a.parentNode.insertBefore(b,a),a.parentNode.removeChild(a)}));if(!(browser.ie&&browser.ie11below&&browser.version>8)){var c=a.innerText().split(/\n/);a.innerHTML(""),utils.each(c,function(b){b.length&&a.appendChild(UE.uNode.createText(b)),a.appendChild(UE.uNode.createElement("br"))})}})}),a.addOutputRule(function(a){utils.each(a.getNodesByTagName("pre"),function(a){var b="";utils.each(a.children,function(a){b+="text"==a.type?a.data.replace(/[ ]/g," ").replace(/\n$/,""):"br"==a.tagName?"\n":dtd.$empty[a.tagName]?a.innerText():""}),a.innerText(b.replace(/( |\n)+$/,""))})}),a.notNeedCodeQuery={help:1,undo:1,redo:1,source:1,print:1,searchreplace:1,fullscreen:1,preview:1,insertparagraph:1,elementpath:1,insertcode:1,inserthtml:1,selectall:1};a.queryCommandState;a.queryCommandState=function(a){var b=this;return!b.notNeedCodeQuery[a.toLowerCase()]&&b.selection&&b.queryCommandValue("insertcode")?-1:UE.Editor.prototype.queryCommandState.apply(this,arguments)},a.addListener("beforeenterkeydown",function(){var b=a.selection.getRange(),c=domUtils.findParentByTagName(b.startContainer,"pre",!0);if(c){if(a.fireEvent("saveScene"),b.collapsed||b.deleteContents(),!browser.ie||browser.ie9above){var c,d=a.document.createElement("br");b.insertNode(d).setStartAfter(d).collapse(!0);var e=d.nextSibling;e||browser.ie&&!(browser.version>10)?b.setStartAfter(d):b.insertNode(d.cloneNode(!1)), +c=d.previousSibling;for(var f;c;)if(f=c,c=c.previousSibling,!c||"BR"==c.nodeName){c=f;break}if(c){for(var g="";c&&"BR"!=c.nodeName&&new RegExp("^[\\s"+domUtils.fillChar+"]*$").test(c.nodeValue);)g+=c.nodeValue,c=c.nextSibling;if("BR"!=c.nodeName){var h=c.nodeValue.match(new RegExp("^([\\s"+domUtils.fillChar+"]+)"));h&&h[1]&&(g+=h[1])}g&&(g=a.document.createTextNode(g),b.insertNode(g).setStartAfter(g))}b.collapse(!0).select(!0)}else if(browser.version>8){var i=a.document.createTextNode("\n"),j=b.startContainer;if(0==b.startOffset){var k=j.previousSibling;if(k){b.insertNode(i);var l=a.document.createTextNode(" ");b.setStartAfter(i).insertNode(l).setStart(l,0).collapse(!0).select(!0)}}else{b.insertNode(i).setStartAfter(i);var l=a.document.createTextNode(" ");j=b.startContainer.childNodes[b.startOffset],j&&!/^\n/.test(j.nodeValue)&&b.setStartBefore(i),b.insertNode(l).setStart(l,0).collapse(!0).select(!0)}}else{var d=a.document.createElement("br");b.insertNode(d),b.insertNode(a.document.createTextNode(domUtils.fillChar)),b.setStartAfter(d),c=d.previousSibling;for(var f;c;)if(f=c,c=c.previousSibling,!c||"BR"==c.nodeName){c=f;break}if(c){for(var g="";c&&"BR"!=c.nodeName&&new RegExp("^[ "+domUtils.fillChar+"]*$").test(c.nodeValue);)g+=c.nodeValue,c=c.nextSibling;if("BR"!=c.nodeName){var h=c.nodeValue.match(new RegExp("^([ "+domUtils.fillChar+"]+)"));h&&h[1]&&(g+=h[1])}g=a.document.createTextNode(g),b.insertNode(g).setStartAfter(g)}b.collapse(!0).select()}return a.fireEvent("saveScene"),!0}}),a.addListener("tabkeydown",function(b,c){var d=a.selection.getRange(),e=domUtils.findParentByTagName(d.startContainer,"pre",!0);if(e){if(a.fireEvent("saveScene"),c.shiftKey);else if(d.collapsed){var f=a.document.createTextNode(" ");d.insertNode(f).setStartAfter(f).collapse(!0).select(!0)}else{for(var g=d.createBookmark(),h=g.start.previousSibling;h;){if(e.firstChild===h&&!domUtils.isBr(h)){e.insertBefore(a.document.createTextNode(" "),h);break}if(domUtils.isBr(h)){e.insertBefore(a.document.createTextNode(" "),h.nextSibling);break}h=h.previousSibling}var i=g.end;for(h=g.start.nextSibling,e.firstChild===g.start&&e.insertBefore(a.document.createTextNode(" "),h.nextSibling);h&&h!==i;){if(domUtils.isBr(h)&&h.nextSibling){if(h.nextSibling===i)break;e.insertBefore(a.document.createTextNode(" "),h.nextSibling)}h=h.nextSibling}d.moveToBookmark(g).select()}return a.fireEvent("saveScene"),!0}}),a.addListener("beforeinserthtml",function(a,b){var c=this,d=c.selection.getRange(),e=domUtils.findParentByTagName(d.startContainer,"pre",!0);if(e){d.collapsed||d.deleteContents();var f="";if(browser.ie&&browser.version>8){utils.each(UE.filterNode(UE.htmlparser(b),c.options.filterTxtRules).children,function(a){"element"==a.type?"br"==a.tagName?f+="\n":dtd.$empty[a.tagName]||(utils.each(a.children,function(b){"element"==b.type?"br"==b.tagName?f+="\n":dtd.$empty[a.tagName]||(f+=b.innerText()):f+=b.data}),/\n$/.test(f)||(f+="\n")):f+=a.data+"\n",!a.nextSibling()&&/\n$/.test(f)&&(f=f.replace(/\n$/,""))});var g=c.document.createTextNode(utils.html(f.replace(/ /g," ")));d.insertNode(g).selectNode(g).select()}else{var h=c.document.createDocumentFragment();utils.each(UE.filterNode(UE.htmlparser(b),c.options.filterTxtRules).children,function(a){"element"==a.type?"br"==a.tagName?h.appendChild(c.document.createElement("br")):dtd.$empty[a.tagName]||(utils.each(a.children,function(b){"element"==b.type?"br"==b.tagName?h.appendChild(c.document.createElement("br")):dtd.$empty[a.tagName]||h.appendChild(c.document.createTextNode(utils.html(b.innerText().replace(/ /g," ")))):h.appendChild(c.document.createTextNode(utils.html(b.data.replace(/ /g," "))))}),"BR"!=h.lastChild.nodeName&&h.appendChild(c.document.createElement("br"))):h.appendChild(c.document.createTextNode(utils.html(a.data.replace(/ /g," ")))),a.nextSibling()||"BR"!=h.lastChild.nodeName||h.removeChild(h.lastChild)}),d.insertNode(h).select()}return!0}}),a.addListener("keydown",function(a,b){var c=this,d=b.keyCode||b.which;if(40==d){var e,f=c.selection.getRange(),g=f.startContainer;if(f.collapsed&&(e=domUtils.findParentByTagName(f.startContainer,"pre",!0))&&!e.nextSibling){for(var h=e.lastChild;h&&"BR"==h.nodeName;)h=h.previousSibling;(h===g||f.startContainer===e&&f.startOffset==e.childNodes.length)&&(c.execCommand("insertparagraph"),domUtils.preventDefault(b))}}}),a.addListener("delkeydown",function(b,c){var d=this.selection.getRange();d.txtToElmBoundary(!0);var e=d.startContainer;if(domUtils.isTagNode(e,"pre")&&d.collapsed&&domUtils.isStartInblock(d)){var f=a.document.createElement("p");return domUtils.fillNode(a.document,f),e.parentNode.insertBefore(f,e),domUtils.remove(e),d.setStart(f,0).setCursor(!1,!0),domUtils.preventDefault(c),!0}})},UE.commands.cleardoc={execCommand:function(a){var b=this,c=b.options.enterTag,d=b.selection.getRange();"br"==c?(b.body.innerHTML="
          ",d.setStart(b.body,0).setCursor()):(b.body.innerHTML="

          "+(ie?"":"
          ")+"

          ",d.setStart(b.body.firstChild,0).setCursor(!1,!0)),setTimeout(function(){b.fireEvent("clearDoc")},0)}},UE.plugin.register("anchor",function(){return{bindEvents:{ready:function(){utils.cssRule("anchor",".anchorclass{background: url('"+this.options.themePath+this.options.theme+"/images/anchor.gif') no-repeat scroll left center transparent;cursor: auto;display: inline-block;height: 16px;width: 15px;}",this.document)}},outputRule:function(a){utils.each(a.getNodesByTagName("img"),function(a){var b;(b=a.getAttr("anchorname"))&&(a.tagName="a",a.setAttr({anchorname:"",name:b,"class":""}))})},inputRule:function(a){utils.each(a.getNodesByTagName("a"),function(a){var b;(b=a.getAttr("name"))&&!a.getAttr("href")&&(a.tagName="img",a.setAttr({anchorname:a.getAttr("name"),"class":"anchorclass"}),a.setAttr("name"))})},commands:{anchor:{execCommand:function(a,b){var c=this.selection.getRange(),d=c.getClosedNode();if(d&&d.getAttribute("anchorname"))b?d.setAttribute("anchorname",b):(c.setStartBefore(d).setCursor(),domUtils.remove(d));else if(b){var e=this.document.createElement("img");c.collapse(!0),domUtils.setAttributes(e,{anchorname:b,"class":"anchorclass"}),c.insertNode(e).setStartAfter(e).setCursor(!1,!0)}}}}}}),UE.plugins.wordcount=function(){var a=this;a.setOpt("wordCount",!0),a.addListener("contentchange",function(){a.fireEvent("wordcount")});var b;a.addListener("ready",function(){var a=this;domUtils.on(a.body,"keyup",function(c){var d=c.keyCode||c.which,e={16:1,18:1,20:1,37:1,38:1,39:1,40:1};d in e||(clearTimeout(b),b=setTimeout(function(){a.fireEvent("wordcount")},200))})})},UE.plugins.pagebreak=function(){function a(a){if(domUtils.isEmptyBlock(a)){for(var b,d=a.firstChild;d&&1==d.nodeType&&domUtils.isEmptyBlock(d);)b=d,d=d.firstChild;!b&&(b=a),domUtils.fillNode(c.document,b)}}function b(a){return a&&1==a.nodeType&&"HR"==a.tagName&&"pagebreak"==a.className}var c=this,d=["td"];c.setOpt("pageBreakTag","_ueditor_page_break_tag_"),c.ready(function(){utils.cssRule("pagebreak",".pagebreak{display:block;clear:both !important;cursor:default !important;width: 100% !important;margin:0;}",c.document)}),c.addInputRule(function(a){a.traversal(function(a){if("text"==a.type&&a.data==c.options.pageBreakTag){var b=UE.uNode.createElement('
          ');a.parentNode.insertBefore(b,a),a.parentNode.removeChild(a)}})}),c.addOutputRule(function(a){utils.each(a.getNodesByTagName("hr"),function(a){if("pagebreak"==a.getAttr("class")){var b=UE.uNode.createText(c.options.pageBreakTag);a.parentNode.insertBefore(b,a),a.parentNode.removeChild(a)}})}),c.commands.pagebreak={execCommand:function(){var e=c.selection.getRange(),f=c.document.createElement("hr");domUtils.setAttributes(f,{"class":"pagebreak",noshade:"noshade",size:"5"}),domUtils.unSelectable(f);var g,h=domUtils.findParentByTagName(e.startContainer,d,!0),i=[];if(h)switch(h.tagName){case"TD":if(g=h.parentNode,g.previousSibling)g.parentNode.insertBefore(f,g),i=domUtils.findParents(f);else{var j=domUtils.findParentByTagName(g,"table");j.parentNode.insertBefore(f,j),i=domUtils.findParents(f,!0)}g=i[1],f!==g&&domUtils.breakParent(f,g),c.fireEvent("afteradjusttable",c.document)}else{if(!e.collapsed){e.deleteContents();for(var k=e.startContainer;!domUtils.isBody(k)&&domUtils.isBlockElm(k)&&domUtils.isEmptyNode(k);)e.setStartBefore(k).collapse(!0),domUtils.remove(k),k=e.startContainer}e.insertNode(f);for(var l,g=f.parentNode;!domUtils.isBody(g);)domUtils.breakParent(f,g),l=f.nextSibling,l&&domUtils.isEmptyBlock(l)&&domUtils.remove(l),g=f.parentNode;l=f.nextSibling;var m=f.previousSibling;if(b(m)?domUtils.remove(m):m&&a(m),l)b(l)?domUtils.remove(l):a(l),e.setEndAfter(f).collapse(!1);else{var n=c.document.createElement("p");f.parentNode.appendChild(n),domUtils.fillNode(c.document,n),e.setStart(n,0).collapse(!0)}e.select(!0)}}}},UE.plugin.register("wordimage",function(){var a=this,b=[];return{commands:{wordimage:{execCommand:function(){for(var b,c=domUtils.getElementsByTagName(a.body,"img"),d=[],e=0;b=c[e++];){var f=b.getAttribute("word_img");f&&d.push(f)}return d},queryCommandState:function(){b=domUtils.getElementsByTagName(a.body,"img");for(var c,d=0;c=b[d++];)if(c.getAttribute("word_img"))return 1;return-1},notNeedUndo:!0}},inputRule:function(b){utils.each(b.getNodesByTagName("img"),function(b){var c=b.attrs,d=parseInt(c.width)<128||parseInt(c.height)<43,e=a.options,f=e.UEDITOR_HOME_URL+"themes/default/images/spacer.gif";c.src&&/^(?:(file:\/+))/.test(c.src)&&b.setAttr({width:c.width,height:c.height,alt:c.alt,word_img:c.src,src:f,style:"background:url("+(d?e.themePath+e.theme+"/images/word.gif":e.langPath+e.lang+"/images/localimage.png")+") no-repeat center center;border:1px solid #ddd"})})}}}),UE.plugins.dragdrop=function(){var a=this;a.ready(function(){domUtils.on(this.body,"dragend",function(){var b=a.selection.getRange(),c=b.getClosedNode()||a.selection.getStart();if(c&&"IMG"==c.tagName){for(var d,e=c.previousSibling;(d=c.nextSibling)&&1==d.nodeType&&"SPAN"==d.tagName&&!d.firstChild;)domUtils.remove(d);(!e||1!=e.nodeType||domUtils.isEmptyBlock(e))&&e||d&&(!d||domUtils.isEmptyBlock(d))||(e&&"P"==e.tagName&&!domUtils.isEmptyBlock(e)?(e.appendChild(c),domUtils.moveChild(d,e),domUtils.remove(d)):d&&"P"==d.tagName&&!domUtils.isEmptyBlock(d)&&d.insertBefore(c,d.firstChild),e&&"P"==e.tagName&&domUtils.isEmptyBlock(e)&&domUtils.remove(e),d&&"P"==d.tagName&&domUtils.isEmptyBlock(d)&&domUtils.remove(d),b.selectNode(c).select(),a.fireEvent("saveScene"))}})}),a.addListener("keyup",function(b,c){var d=c.keyCode||c.which;if(13==d){var e,f=a.selection.getRange();(e=domUtils.findParentByTagName(f.startContainer,"p",!0))&&"center"==domUtils.getComputedStyle(e,"text-align")&&domUtils.removeStyle(e,"text-align")}})},UE.plugins.undo=function(){function a(a,b){if(a.length!=b.length)return 0;for(var c=0,d=a.length;cf&&this.list.shift(),this.index=this.list.length-1,this.clearKey(),this.update())},this.update=function(){this.hasRedo=!!this.list[this.index+1],this.hasUndo=!!this.list[this.index-1]},this.reset=function(){this.list=[],this.index=0,this.hasUndo=!1,this.hasRedo=!1,this.clearKey()},this.clearKey=function(){m=0,k=null}}var d,e=this,f=e.options.maxUndoCount||20,g=e.options.maxInputCount||20,h=new RegExp(domUtils.fillChar+"|","gi"),i={ol:1,ul:1,table:1,tbody:1,tr:1,body:1},j=e.options.autoClearEmptyNode;e.undoManger=new c,e.undoManger.editor=e,e.addListener("saveScene",function(){var a=Array.prototype.splice.call(arguments,1);this.undoManger.save.apply(this.undoManger,a)}),e.addListener("reset",function(a,b){b||this.undoManger.reset()}),e.commands.redo=e.commands.undo={execCommand:function(a){this.undoManger[a]()},queryCommandState:function(a){return this.undoManger["has"+("undo"==a.toLowerCase()?"Undo":"Redo")]?0:-1},notNeedUndo:1};var k,l={16:1,17:1,18:1,37:1,38:1,39:1,40:1},m=0,n=!1;e.addListener("ready",function(){domUtils.on(this.body,"compositionstart",function(){n=!0}),domUtils.on(this.body,"compositionend",function(){n=!1})}),e.addshortcutkey({Undo:"ctrl+90",Redo:"ctrl+89"});var o=!0;e.addListener("keydown",function(a,b){function c(a){a.undoManger.save(!1,!0),a.fireEvent("selectionchange")}var e=this,f=b.keyCode||b.which;if(!(l[f]||b.ctrlKey||b.metaKey||b.shiftKey||b.altKey)){if(n)return;if(!e.selection.getRange().collapsed)return e.undoManger.save(!1,!0),void(o=!1);0==e.undoManger.list.length&&e.undoManger.save(!0),clearTimeout(d),d=setTimeout(function(){if(n)var a=setInterval(function(){n||(c(e),clearInterval(a))},300);else c(e)},200),k=f,m++,m>=g&&c(e)}}),e.addListener("keyup",function(a,b){var c=b.keyCode||b.which;if(!(l[c]||b.ctrlKey||b.metaKey||b.shiftKey||b.altKey)){if(n)return;o||(this.undoManger.save(!1,!0),o=!0)}}),e.stopCmdUndo=function(){e.__hasEnterExecCommand=!0},e.startCmdUndo=function(){e.__hasEnterExecCommand=!1}},UE.plugin.register("copy",function(){function a(){ZeroClipboard.config({debug:!1,swfPath:b.options.UEDITOR_HOME_URL+"third-party/zeroclipboard/ZeroClipboard.swf"});var a=b.zeroclipboard=new ZeroClipboard;a.on("copy",function(a){var c=a.client,d=b.selection.getRange(),e=document.createElement("div");e.appendChild(d.cloneContents()),c.setText(e.innerText||e.textContent),c.setHtml(e.innerHTML),d.select()}),a.on("mouseover mouseout",function(a){var b=a.target;"mouseover"==a.type?domUtils.addClass(b,"edui-state-hover"):"mouseout"==a.type&&domUtils.removeClasses(b,"edui-state-hover")}),a.on("wrongflash noflash",function(){ZeroClipboard.destroy()})}var b=this;return{bindEvents:{ready:function(){browser.ie||(window.ZeroClipboard?a():utils.loadFile(document,{src:b.options.UEDITOR_HOME_URL+"third-party/zeroclipboard/ZeroClipboard.js",tag:"script",type:"text/javascript",defer:"defer"},function(){a()}))}},commands:{copy:{execCommand:function(a){b.document.execCommand("copy")||alert(b.getLang("copymsg"))}}}}}),UE.plugins.paste=function(){function a(a){var b=this.document;if(!b.getElementById("baidu_pastebin")){var c=this.selection.getRange(),d=c.createBookmark(),e=b.createElement("div");e.id="baidu_pastebin",browser.webkit&&e.appendChild(b.createTextNode(domUtils.fillChar+domUtils.fillChar)),b.body.appendChild(e),d.start.style.display="",e.style.cssText="position:absolute;width:1px;height:1px;overflow:hidden;left:-1000px;white-space:nowrap;top:"+domUtils.getXY(d.start).y+"px",c.selectNodeContents(e).select(!0),setTimeout(function(){if(browser.webkit)for(var f,g=0,h=b.querySelectorAll("#baidu_pastebin");f=h[g++];){if(!domUtils.isEmptyNode(f)){e=f;break}domUtils.remove(f)}try{e.parentNode.removeChild(e)}catch(i){}c.moveToBookmark(d).select(!0),a(e)},0)}}function b(a){return a.replace(/<(\/?)([\w\-]+)([^>]*)>/gi,function(a,b,c,d){return c=c.toLowerCase(),{img:1}[c]?a:(d=d.replace(/([\w\-]*?)\s*=\s*(("([^"]*)")|('([^']*)')|([^\s>]+))/gi,function(a,b,c){return{src:1,href:1,name:1}[b.toLowerCase()]?b+"="+c+" ":""}),{span:1,div:1}[c]?"":"<"+b+c+" "+utils.trim(d)+">")})}function c(a){var c;if(a.firstChild){for(var h,i=domUtils.getElementsByTagName(a,"span"),j=0;h=i[j++];)"_baidu_cut_start"!=h.id&&"_baidu_cut_end"!=h.id||domUtils.remove(h);if(browser.webkit){for(var k,l=a.querySelectorAll("div br"),j=0;k=l[j++];){var m=k.parentNode;"DIV"==m.tagName&&1==m.childNodes.length&&(m.innerHTML="


          ",domUtils.remove(m))}for(var n,o=a.querySelectorAll("#baidu_pastebin"),j=0;n=o[j++];){var p=d.document.createElement("p");for(n.parentNode.insertBefore(p,n);n.firstChild;)p.appendChild(n.firstChild);domUtils.remove(n)}for(var q,r=a.querySelectorAll("meta"),j=0;q=r[j++];)domUtils.remove(q);var l=a.querySelectorAll("br");for(j=0;q=l[j++];)/^apple-/i.test(q.className)&&domUtils.remove(q)}if(browser.gecko){var s=a.querySelectorAll("[_moz_dirty]");for(j=0;q=s[j++];)q.removeAttribute("_moz_dirty")}if(!browser.ie)for(var q,t=a.querySelectorAll("span.Apple-style-span"),j=0;q=t[j++];)domUtils.remove(q,!0);c=a.innerHTML,c=UE.filterWord(c);var u=UE.htmlparser(c);if(d.options.filterRules&&UE.filterNode(u,d.options.filterRules),d.filterInputRule(u),browser.webkit){var v=u.lastChild();v&&"element"==v.type&&"br"==v.tagName&&u.removeChild(v),utils.each(d.body.querySelectorAll("div"),function(a){domUtils.isEmptyBlock(a)&&domUtils.remove(a,!0)})}if(c={html:u.toHtml()},d.fireEvent("beforepaste",c,u),!c.html)return;u=UE.htmlparser(c.html,!0),1===d.queryCommandState("pasteplain")?d.execCommand("insertHtml",UE.filterNode(u,d.options.filterTxtRules).toHtml(),!0):(UE.filterNode(u,d.options.filterTxtRules),e=u.toHtml(),f=c.html,g=d.selection.getRange().createAddress(!0),d.execCommand("insertHtml",d.getOpt("retainOnlyLabelPasted")===!0?b(f):f,!0)),d.fireEvent("afterpaste",c)}}var d=this;d.setOpt({retainOnlyLabelPasted:!1});var e,f,g;d.addListener("pasteTransfer",function(a,c){if(g&&e&&f&&e!=f){var h=d.selection.getRange();if(h.moveToAddress(g,!0),!h.collapsed){for(;!domUtils.isBody(h.startContainer);){var i=h.startContainer;if(1==i.nodeType){if(i=i.childNodes[h.startOffset],!i){h.setStartBefore(h.startContainer);continue}var j=i.previousSibling;j&&3==j.nodeType&&new RegExp("^[\n\r\t "+domUtils.fillChar+"]*$").test(j.nodeValue)&&h.setStartBefore(j)}if(0!=h.startOffset)break;h.setStartBefore(h.startContainer)}for(;!domUtils.isBody(h.endContainer);){var k=h.endContainer;if(1==k.nodeType){if(k=k.childNodes[h.endOffset],!k){h.setEndAfter(h.endContainer);continue}var l=k.nextSibling;l&&3==l.nodeType&&new RegExp("^[\n\r\t"+domUtils.fillChar+"]*$").test(l.nodeValue)&&h.setEndAfter(l)}if(h.endOffset!=h.endContainer[3==h.endContainer.nodeType?"nodeValue":"childNodes"].length)break;h.setEndAfter(h.endContainer)}}h.deleteContents(),h.select(!0),d.__hasEnterExecCommand=!0;var m=f;2===c?m=b(m):c&&(m=e),d.execCommand("inserthtml",m,!0),d.__hasEnterExecCommand=!1;for(var n=d.selection.getRange();!domUtils.isBody(n.startContainer)&&!n.startOffset&&n.startContainer[3==n.startContainer.nodeType?"nodeValue":"childNodes"].length;)n.setStartBefore(n.startContainer);var o=n.createAddress(!0);g.endAddress=o.startAddress}}),d.addListener("ready",function(){domUtils.on(d.body,"cut",function(){var a=d.selection.getRange();!a.collapsed&&d.undoManger&&d.undoManger.save()}),domUtils.on(d.body,browser.ie||browser.opera?"keydown":"paste",function(b){(!browser.ie&&!browser.opera||(b.ctrlKey||b.metaKey)&&"86"==b.keyCode)&&a.call(d,function(a){c(a)})})}),d.commands.paste={execCommand:function(b){browser.ie?(a.call(d,function(a){c(a)}),d.document.execCommand("paste")):alert(d.getLang("pastemsg"))}}},UE.plugins.pasteplain=function(){var a=this;a.setOpt({pasteplain:!1,filterTxtRules:function(){function a(a){a.tagName="p",a.setStyle()}function b(a){a.parentNode.removeChild(a,!0)}return{"-":"script style object iframe embed input select",p:{$:{}},br:{$:{}},div:function(a){for(var b,c=UE.uNode.createElement("p");b=a.firstChild();)"text"!=b.type&&UE.dom.dtd.$block[b.tagName]?c.firstChild()?(a.parentNode.insertBefore(c,a),c=UE.uNode.createElement("p")):a.parentNode.insertBefore(b,a):c.appendChild(b);c.firstChild()&&a.parentNode.insertBefore(c,a),a.parentNode.removeChild(a)},ol:b,ul:b,dl:b,dt:b,dd:b,li:b,caption:a,th:a,tr:a,h1:a,h2:a,h3:a,h4:a,h5:a,h6:a,td:function(a){var b=!!a.innerText();b&&a.parentNode.insertAfter(UE.uNode.createText("    "),a),a.parentNode.removeChild(a,a.innerText())}}}()});var b=a.options.pasteplain;a.commands.pasteplain={queryCommandState:function(){return b?1:0},execCommand:function(){b=0|!b},notNeedUndo:1}},UE.plugins.list=function(){function a(a){var b=[];for(var c in a)b.push(c);return b}function b(a){var b=a.className;return domUtils.hasClass(a,/custom_/)?b.match(/custom_(\w+)/)[1]:domUtils.getStyle(a,"list-style-type")}function c(a,c){utils.each(domUtils.getElementsByTagName(a,"ol ul"),function(f){if(domUtils.inDoc(f,a)){var g=f.parentNode;if(g.tagName==f.tagName){var h=b(f)||("OL"==f.tagName?"decimal":"disc"),i=b(g)||("OL"==g.tagName?"decimal":"disc");if(h==i){var l=utils.indexOf(k[f.tagName],h);l=l+1==k[f.tagName].length?0:l+1,e(f,k[f.tagName][l])}}var m=0,n=2;domUtils.hasClass(f,/custom_/)?/[ou]l/i.test(g.tagName)&&domUtils.hasClass(g,/custom_/)||(n=1):/[ou]l/i.test(g.tagName)&&domUtils.hasClass(g,/custom_/)&&(n=3);var o=domUtils.getStyle(f,"list-style-type");o&&(f.style.cssText="list-style-type:"+o),f.className=utils.trim(f.className.replace(/list-paddingleft-\w+/,""))+" list-paddingleft-"+n,utils.each(domUtils.getElementsByTagName(f,"li"),function(a){if(a.style.cssText&&(a.style.cssText=""),!a.firstChild)return void domUtils.remove(a);if(a.parentNode===f){if(m++,domUtils.hasClass(f,/custom_/)){var c=1,d=b(f);if("OL"==f.tagName){if(d)switch(d){case"cn":case"cn1":case"cn2":m>10&&(m%10==0||m>10&&m<20)?c=2:m>20&&(c=3);break;case"num2":m>9&&(c=2)}a.className="list-"+j[d]+m+" list-"+d+"-paddingleft-"+c}else a.className="list-"+j[d]+" list-"+d+"-paddingleft"}else a.className=a.className.replace(/list-[\w\-]+/gi,"");var e=a.getAttribute("class");null===e||e.replace(/\s/g,"")||domUtils.removeAttributes(a,"class")}}),!c&&d(f,f.tagName.toLowerCase(),b(f)||domUtils.getStyle(f,"list-style-type"),!0)}})}function d(a,d,e,f){var g=a.nextSibling;g&&1==g.nodeType&&g.tagName.toLowerCase()==d&&(b(g)||domUtils.getStyle(g,"list-style-type")||("ol"==d?"decimal":"disc"))==e&&(domUtils.moveChild(g,a),0==g.childNodes.length&&domUtils.remove(g)),g&&domUtils.isFillChar(g)&&domUtils.remove(g);var h=a.previousSibling;h&&1==h.nodeType&&h.tagName.toLowerCase()==d&&(b(h)||domUtils.getStyle(h,"list-style-type")||("ol"==d?"decimal":"disc"))==e&&domUtils.moveChild(a,h),h&&domUtils.isFillChar(h)&&domUtils.remove(h),!f&&domUtils.isEmptyBlock(a)&&domUtils.remove(a),b(a)&&c(a.ownerDocument,!0)}function e(a,b){j[b]&&(a.className="custom_"+b);try{domUtils.setStyle(a,"list-style-type",b)}catch(c){}}function f(a){var b=a.previousSibling;b&&domUtils.isEmptyBlock(b)&&domUtils.remove(b),b=a.nextSibling,b&&domUtils.isEmptyBlock(b)&&domUtils.remove(b)}function g(a){for(;a&&!domUtils.isBody(a);){if("TABLE"==a.nodeName)return null;if("LI"==a.nodeName)return a;a=a.parentNode}}var h=this,i={TD:1,PRE:1,BLOCKQUOTE:1},j={cn:"cn-1-",cn1:"cn-2-",cn2:"cn-3-",num:"num-1-",num1:"num-2-",num2:"num-3-",dash:"dash",dot:"dot"};h.setOpt({autoTransWordToList:!1,insertorderedlist:{num:"",num1:"",num2:"",cn:"",cn1:"",cn2:"",decimal:"","lower-alpha":"","lower-roman":"","upper-alpha":"","upper-roman":""},insertunorderedlist:{circle:"",disc:"",square:"",dash:"",dot:""},listDefaultPaddingLeft:"30",listiconpath:"http://bs.baidu.com/listicon/",maxListLevel:-1,disablePInList:!1});var k={OL:a(h.options.insertorderedlist),UL:a(h.options.insertunorderedlist)},l=h.options.listiconpath;for(var m in j)h.options.insertorderedlist.hasOwnProperty(m)||h.options.insertunorderedlist.hasOwnProperty(m)||delete j[m];h.ready(function(){var a=[];for(var b in j){if("dash"==b||"dot"==b)a.push("li.list-"+j[b]+"{background-image:url("+l+j[b]+".gif)}"),a.push("ul.custom_"+b+"{list-style:none;}ul.custom_"+b+" li{background-position:0 3px;background-repeat:no-repeat}");else{for(var c=0;c<99;c++)a.push("li.list-"+j[b]+c+"{background-image:url("+l+"list-"+j[b]+c+".gif)}");a.push("ol.custom_"+b+"{list-style:none;}ol.custom_"+b+" li{background-position:0 3px;background-repeat:no-repeat}")}switch(b){case"cn":a.push("li.list-"+b+"-paddingleft-1{padding-left:25px}"),a.push("li.list-"+b+"-paddingleft-2{padding-left:40px}"),a.push("li.list-"+b+"-paddingleft-3{padding-left:55px}");break;case"cn1":a.push("li.list-"+b+"-paddingleft-1{padding-left:30px}"),a.push("li.list-"+b+"-paddingleft-2{padding-left:40px}"),a.push("li.list-"+b+"-paddingleft-3{padding-left:55px}");break;case"cn2":a.push("li.list-"+b+"-paddingleft-1{padding-left:40px}"),a.push("li.list-"+b+"-paddingleft-2{padding-left:55px}"),a.push("li.list-"+b+"-paddingleft-3{padding-left:68px}");break;case"num":case"num1":a.push("li.list-"+b+"-paddingleft-1{padding-left:25px}");break;case"num2":a.push("li.list-"+b+"-paddingleft-1{padding-left:35px}"),a.push("li.list-"+b+"-paddingleft-2{padding-left:40px}");break;case"dash":a.push("li.list-"+b+"-paddingleft{padding-left:35px}");break;case"dot":a.push("li.list-"+b+"-paddingleft{padding-left:20px}")}}a.push(".list-paddingleft-1{padding-left:0}"),a.push(".list-paddingleft-2{padding-left:"+h.options.listDefaultPaddingLeft+"px}"),a.push(".list-paddingleft-3{padding-left:"+2*h.options.listDefaultPaddingLeft+"px}"),utils.cssRule("list","ol,ul{margin:0;pading:0;"+(browser.ie?"":"width:95%")+"}li{clear:both;}"+a.join("\n"),h.document)}),h.ready(function(){domUtils.on(h.body,"cut",function(){setTimeout(function(){var a,b=h.selection.getRange();if(!b.collapsed&&(a=domUtils.findParentByTagName(b.startContainer,"li",!0))&&!a.nextSibling&&domUtils.isEmptyBlock(a)){var c,d=a.parentNode;if(c=d.previousSibling)domUtils.remove(d),b.setStartAtLast(c).collapse(!0),b.select(!0);else if(c=d.nextSibling)domUtils.remove(d),b.setStartAtFirst(c).collapse(!0),b.select(!0);else{var e=h.document.createElement("p");domUtils.fillNode(h.document,e),d.parentNode.insertBefore(e,d),domUtils.remove(d),b.setStart(e,0).collapse(!0),b.select(!0)}}})})}),h.addListener("beforepaste",function(a,c){var d,e=this,f=e.selection.getRange(),g=UE.htmlparser(c.html,!0);if(d=domUtils.findParentByTagName(f.startContainer,"li",!0)){var h=d.parentNode,i="OL"==h.tagName?"ul":"ol";utils.each(g.getNodesByTagName(i),function(c){if(c.tagName=h.tagName,c.setAttr(),c.parentNode===g)a=b(h)||("OL"==h.tagName?"decimal":"disc");else{var d=c.parentNode.getAttr("class");a=d&&/custom_/.test(d)?d.match(/custom_(\w+)/)[1]:c.parentNode.getStyle("list-style-type"),a||(a="OL"==h.tagName?"decimal":"disc")}var e=utils.indexOf(k[h.tagName],a);c.parentNode!==g&&(e=e+1==k[h.tagName].length?0:e+1);var f=k[h.tagName][e];j[f]?c.setAttr("class","custom_"+f):c.setStyle("list-style-type",f)})}c.html=g.toHtml()}),h.getOpt("disablePInList")===!0&&h.addOutputRule(function(a){utils.each(a.getNodesByTagName("li"),function(a){var b=[],c=0;utils.each(a.children,function(d){if("p"==d.tagName){for(var e;e=d.children.pop();)b.splice(c,0,e),e.parentNode=a,lastNode=e;if(e=b[b.length-1],!e||"element"!=e.type||"br"!=e.tagName){var f=UE.uNode.createElement("br");f.parentNode=a,b.push(f)}c=b.length}}),b.length&&(a.children=b)})}),h.addInputRule(function(a){function b(a,b){var e=b.firstChild();if(e&&"element"==e.type&&"span"==e.tagName&&/Wingdings|Symbol/.test(e.getStyle("font-family"))){for(var f in d)if(d[f]==e.data)return f;return"disc"}for(var f in c)if(c[f].test(a))return f}if(utils.each(a.getNodesByTagName("li"),function(a){for(var b,c=UE.uNode.createElement("p"),d=0;b=a.children[d];)"text"==b.type||dtd.p[b.tagName]?c.appendChild(b):c.firstChild()?(a.insertBefore(c,b),c=UE.uNode.createElement("p"),d+=2):d++;(c.firstChild()&&!c.parentNode||!a.firstChild())&&a.appendChild(c),c.firstChild()||c.innerHTML(browser.ie?" ":"
          ");var e=a.firstChild(),f=e.lastChild();f&&"text"==f.type&&/^\s*$/.test(f.data)&&e.removeChild(f)}),h.options.autoTransWordToList){var c={num1:/^\d+\)/,decimal:/^\d+\./,"lower-alpha":/^[a-z]+\)/,"upper-alpha":/^[A-Z]+\./,cn:/^[\u4E00\u4E8C\u4E09\u56DB\u516d\u4e94\u4e03\u516b\u4e5d]+[\u3001]/,cn2:/^\([\u4E00\u4E8C\u4E09\u56DB\u516d\u4e94\u4e03\u516b\u4e5d]+\)/},d={square:"n"};utils.each(a.getNodesByTagName("p"),function(a){function d(a,b,d){if("ol"==a.tagName)if(browser.ie){var e=b.firstChild();"element"==e.type&&"span"==e.tagName&&c[d].test(e.innerText())&&b.removeChild(e)}else b.innerHTML(b.innerHTML().replace(c[d],""));else b.removeChild(b.firstChild());var f=UE.uNode.createElement("li");f.appendChild(b),a.appendChild(f)}if("MsoListParagraph"==a.getAttr("class")){a.setStyle("margin",""),a.setStyle("margin-left",""),a.setAttr("class","");var e,f=a,g=a;if("li"!=a.parentNode.tagName&&(e=b(a.innerText(),a))){var i=UE.uNode.createElement(h.options.insertorderedlist.hasOwnProperty(e)?"ol":"ul");for(j[e]?i.setAttr("class","custom_"+e):i.setStyle("list-style-type",e);a&&"li"!=a.parentNode.tagName&&b(a.innerText(),a);)f=a.nextSibling(),f||a.parentNode.insertBefore(i,a),d(i,a,e),a=f;!i.parentNode&&a&&a.parentNode&&a.parentNode.insertBefore(i,a)}var k=g.firstChild();k&&"element"==k.type&&"span"==k.tagName&&/^\s*( )+\s*$/.test(k.innerText())&&k.parentNode.removeChild(k)}})}}),h.addListener("contentchange",function(){c(h.document)}),h.addListener("keydown",function(a,b){function c(){b.preventDefault?b.preventDefault():b.returnValue=!1,h.fireEvent("contentchange"),h.undoManger&&h.undoManger.save()}function d(a,b){for(;a&&!domUtils.isBody(a);){if(b(a))return null;if(1==a.nodeType&&/[ou]l/i.test(a.tagName))return a;a=a.parentNode}return null}var e=b.keyCode||b.which;if(13==e&&!b.shiftKey){var g=h.selection.getRange(),i=domUtils.findParent(g.startContainer,function(a){return domUtils.isBlockElm(a)},!0),j=domUtils.findParentByTagName(g.startContainer,"li",!0);if(i&&"PRE"!=i.tagName&&!j){var k=i.innerHTML.replace(new RegExp(domUtils.fillChar,"g"),"");/^\s*1\s*\.[^\d]/.test(k)&&(i.innerHTML=k.replace(/^\s*1\s*\./,""),g.setStartAtLast(i).collapse(!0).select(),h.__hasEnterExecCommand=!0,h.execCommand("insertorderedlist"),h.__hasEnterExecCommand=!1)}var l=h.selection.getRange(),m=d(l.startContainer,function(a){return"TABLE"==a.tagName}),n=l.collapsed?m:d(l.endContainer,function(a){return"TABLE"==a.tagName});if(m&&n&&m===n){if(!l.collapsed){if(m=domUtils.findParentByTagName(l.startContainer,"li",!0),n=domUtils.findParentByTagName(l.endContainer,"li",!0),!m||!n||m!==n){var o=l.cloneRange(),p=o.collapse(!1).createBookmark();l.deleteContents(),o.moveToBookmark(p);var j=domUtils.findParentByTagName(o.startContainer,"li",!0);return f(j),o.select(),void c()}if(l.deleteContents(),j=domUtils.findParentByTagName(l.startContainer,"li",!0),j&&domUtils.isEmptyBlock(j))return v=j.previousSibling,next=j.nextSibling,s=h.document.createElement("p"),domUtils.fillNode(h.document,s),q=j.parentNode,v&&next?(l.setStart(next,0).collapse(!0).select(!0),domUtils.remove(j)):((v||next)&&v?j.parentNode.parentNode.insertBefore(s,q.nextSibling):q.parentNode.insertBefore(s,q),domUtils.remove(j),q.firstChild||domUtils.remove(q),l.setStart(s,0).setCursor()),void c()}if(j=domUtils.findParentByTagName(l.startContainer,"li",!0)){ +if(domUtils.isEmptyBlock(j)){p=l.createBookmark();var q=j.parentNode;if(j!==q.lastChild?(domUtils.breakParent(j,q),f(j)):(q.parentNode.insertBefore(j,q.nextSibling),domUtils.isEmptyNode(q)&&domUtils.remove(q)),!dtd.$list[j.parentNode.tagName])if(domUtils.isBlockElm(j.firstChild))domUtils.remove(j,!0);else{for(s=h.document.createElement("p"),j.parentNode.insertBefore(s,j);j.firstChild;)s.appendChild(j.firstChild);domUtils.remove(j)}l.moveToBookmark(p).select()}else{var r=j.firstChild;if(!r||!domUtils.isBlockElm(r)){var s=h.document.createElement("p");for(!j.firstChild&&domUtils.fillNode(h.document,s);j.firstChild;)s.appendChild(j.firstChild);j.appendChild(s),r=s}var t=h.document.createElement("span");l.insertNode(t),domUtils.breakParent(t,j);var u=t.nextSibling;r=u.firstChild,r||(s=h.document.createElement("p"),domUtils.fillNode(h.document,s),u.appendChild(s),r=s),domUtils.isEmptyNode(r)&&(r.innerHTML="",domUtils.fillNode(h.document,r)),l.setStart(r,0).collapse(!0).shrinkBoundary().select(),domUtils.remove(t);var v=u.previousSibling;v&&domUtils.isEmptyBlock(v)&&(v.innerHTML="

          ",domUtils.fillNode(h.document,v.firstChild))}c()}}}if(8==e&&(l=h.selection.getRange(),l.collapsed&&domUtils.isStartInblock(l)&&(o=l.cloneRange().trimBoundary(),j=domUtils.findParentByTagName(l.startContainer,"li",!0),j&&domUtils.isStartInblock(o)))){if(m=domUtils.findParentByTagName(l.startContainer,"p",!0),m&&m!==j.firstChild){var q=domUtils.findParentByTagName(m,["ol","ul"]);return domUtils.breakParent(m,q),f(m),h.fireEvent("contentchange"),l.setStart(m,0).setCursor(!1,!0),h.fireEvent("saveScene"),void domUtils.preventDefault(b)}if(j&&(v=j.previousSibling)){if(46==e&&j.childNodes.length)return;if(dtd.$list[v.tagName]&&(v=v.lastChild),h.undoManger&&h.undoManger.save(),r=j.firstChild,domUtils.isBlockElm(r))if(domUtils.isEmptyNode(r))for(v.appendChild(r),l.setStart(r,0).setCursor(!1,!0);j.firstChild;)v.appendChild(j.firstChild);else t=h.document.createElement("span"),l.insertNode(t),domUtils.isEmptyBlock(v)&&(v.innerHTML=""),domUtils.moveChild(j,v),l.setStartBefore(t).collapse(!0).select(!0),domUtils.remove(t);else if(domUtils.isEmptyNode(j)){var s=h.document.createElement("p");v.appendChild(s),l.setStart(s,0).setCursor()}else for(l.setEnd(v,v.childNodes.length).collapse().select(!0);j.firstChild;)v.appendChild(j.firstChild);return domUtils.remove(j),h.fireEvent("contentchange"),h.fireEvent("saveScene"),void domUtils.preventDefault(b)}if(j&&!j.previousSibling){var q=j.parentNode,p=l.createBookmark();if(domUtils.isTagNode(q.parentNode,"ol ul"))q.parentNode.insertBefore(j,q),domUtils.isEmptyNode(q)&&domUtils.remove(q);else{for(;j.firstChild;)q.parentNode.insertBefore(j.firstChild,q);domUtils.remove(j),domUtils.isEmptyNode(q)&&domUtils.remove(q)}return l.moveToBookmark(p).setCursor(!1,!0),h.fireEvent("contentchange"),h.fireEvent("saveScene"),void domUtils.preventDefault(b)}}}),h.addListener("keyup",function(a,c){var e=c.keyCode||c.which;if(8==e){var f,g=h.selection.getRange();(f=domUtils.findParentByTagName(g.startContainer,["ol","ul"],!0))&&d(f,f.tagName.toLowerCase(),b(f)||domUtils.getComputedStyle(f,"list-style-type"),!0)}}),h.addListener("tabkeydown",function(){function a(a){if(h.options.maxListLevel!=-1){for(var b=a.parentNode,c=0;/[ou]l/i.test(b.tagName);)c++,b=b.parentNode;if(c>=h.options.maxListLevel)return!0}}var c=h.selection.getRange(),f=domUtils.findParentByTagName(c.startContainer,"li",!0);if(f){var g;if(!c.collapsed){h.fireEvent("saveScene"),g=c.createBookmark();for(var i,j,l=0,m=domUtils.findParents(f);j=m[l++];)if(domUtils.isTagNode(j,"ol ul")){i=j;break}var n=f;if(g.end)for(;n&&!(domUtils.getPosition(n,g.end)&domUtils.POSITION_FOLLOWING);)if(a(n))n=domUtils.getNextDomNode(n,!1,null,function(a){return a!==i});else{var o=n.parentNode,p=h.document.createElement(o.tagName),q=utils.indexOf(k[p.tagName],b(o)||domUtils.getComputedStyle(o,"list-style-type")),r=q+1==k[p.tagName].length?0:q+1,s=k[p.tagName][r];for(e(p,s),o.insertBefore(p,n);n&&!(domUtils.getPosition(n,g.end)&domUtils.POSITION_FOLLOWING);){if(f=n.nextSibling,p.appendChild(n),!f||domUtils.isTagNode(f,"ol ul")){if(f)for(;(f=f.firstChild)&&"LI"!=f.tagName;);else f=domUtils.getNextDomNode(n,!1,null,function(a){return a!==i});break}n=f}d(p,p.tagName.toLowerCase(),s),n=f}return h.fireEvent("contentchange"),c.moveToBookmark(g).select(),!0}if(a(f))return!0;var o=f.parentNode,p=h.document.createElement(o.tagName),q=utils.indexOf(k[p.tagName],b(o)||domUtils.getComputedStyle(o,"list-style-type"));q=q+1==k[p.tagName].length?0:q+1;var s=k[p.tagName][q];if(e(p,s),domUtils.isStartInblock(c))return h.fireEvent("saveScene"),g=c.createBookmark(),o.insertBefore(p,f),p.appendChild(f),d(p,p.tagName.toLowerCase(),s),h.fireEvent("contentchange"),c.moveToBookmark(g).select(!0),!0}}),h.commands.insertorderedlist=h.commands.insertunorderedlist={execCommand:function(a,c){c||(c="insertorderedlist"==a.toLowerCase()?"decimal":"disc");var f=this,h=this.selection.getRange(),j=function(a){return 1==a.nodeType?"br"!=a.tagName.toLowerCase():!domUtils.isWhitespace(a)},k="insertorderedlist"==a.toLowerCase()?"ol":"ul",l=f.document.createDocumentFragment();h.adjustmentBoundary().shrinkBoundary();var m,n,o,p,q=h.createBookmark(!0),r=g(f.document.getElementById(q.start)),s=0,t=g(f.document.getElementById(q.end)),u=0;if(r||t){if(r&&(m=r.parentNode),q.end||(t=r),t&&(n=t.parentNode),m===n){for(;r!==t;){if(p=r,r=r.nextSibling,!domUtils.isBlockElm(p.firstChild)){for(var v=f.document.createElement("p");p.firstChild;)v.appendChild(p.firstChild);p.appendChild(v)}l.appendChild(p)}if(p=f.document.createElement("span"),m.insertBefore(p,t),!domUtils.isBlockElm(t.firstChild)){for(v=f.document.createElement("p");t.firstChild;)v.appendChild(t.firstChild);t.appendChild(v)}l.appendChild(t),domUtils.breakParent(p,m),domUtils.isEmptyNode(p.previousSibling)&&domUtils.remove(p.previousSibling),domUtils.isEmptyNode(p.nextSibling)&&domUtils.remove(p.nextSibling);var w=b(m)||domUtils.getComputedStyle(m,"list-style-type")||("insertorderedlist"==a.toLowerCase()?"decimal":"disc");if(m.tagName.toLowerCase()==k&&w==c){for(var x,y=0,z=f.document.createDocumentFragment();x=l.firstChild;)if(domUtils.isTagNode(x,"ol ul"))z.appendChild(x);else for(;x.firstChild;)z.appendChild(x.firstChild),domUtils.remove(x);p.parentNode.insertBefore(z,p)}else o=f.document.createElement(k),e(o,c),o.appendChild(l),p.parentNode.insertBefore(o,p);return domUtils.remove(p),o&&d(o,k,c),void h.moveToBookmark(q).select()}if(r){for(;r;){if(p=r.nextSibling,domUtils.isTagNode(r,"ol ul"))l.appendChild(r);else{for(var A=f.document.createDocumentFragment(),B=0;r.firstChild;)domUtils.isBlockElm(r.firstChild)&&(B=1),A.appendChild(r.firstChild);if(B)l.appendChild(A);else{var C=f.document.createElement("p");C.appendChild(A),l.appendChild(C)}domUtils.remove(r)}r=p}m.parentNode.insertBefore(l,m.nextSibling),domUtils.isEmptyNode(m)?(h.setStartBefore(m),domUtils.remove(m)):h.setStartAfter(m),s=1}if(t&&domUtils.inDoc(n,f.document)){for(r=n.firstChild;r&&r!==t;){if(p=r.nextSibling,domUtils.isTagNode(r,"ol ul"))l.appendChild(r);else{for(A=f.document.createDocumentFragment(),B=0;r.firstChild;)domUtils.isBlockElm(r.firstChild)&&(B=1),A.appendChild(r.firstChild);B?l.appendChild(A):(C=f.document.createElement("p"),C.appendChild(A),l.appendChild(C)),domUtils.remove(r)}r=p}var D=domUtils.createElement(f.document,"div",{tmpDiv:1});domUtils.moveChild(t,D),l.appendChild(D),domUtils.remove(t),n.parentNode.insertBefore(l,n),h.setEndBefore(n),domUtils.isEmptyNode(n)&&domUtils.remove(n),u=1}}s||h.setStartBefore(f.document.getElementById(q.start)),q.end&&!u&&h.setEndAfter(f.document.getElementById(q.end)),h.enlarge(!0,function(a){return i[a.tagName]}),l=f.document.createDocumentFragment();for(var E,F=h.createBookmark(),G=domUtils.getNextDomNode(F.start,!1,j),H=h.cloneRange(),I=domUtils.isBlockElm;G&&G!==F.end&&domUtils.getPosition(G,F.end)&domUtils.POSITION_PRECEDING;)if(3==G.nodeType||dtd.li[G.tagName]){if(1==G.nodeType&&dtd.$list[G.tagName]){for(;G.firstChild;)l.appendChild(G.firstChild);E=domUtils.getNextDomNode(G,!1,j),domUtils.remove(G),G=E;continue}for(E=G,H.setStartBefore(G);G&&G!==F.end&&(!I(G)||domUtils.isBookmarkNode(G));)E=G,G=domUtils.getNextDomNode(G,!1,null,function(a){return!i[a.tagName]});G&&I(G)&&(p=domUtils.getNextDomNode(E,!1,j),p&&domUtils.isBookmarkNode(p)&&(G=domUtils.getNextDomNode(p,!1,j),E=p)),H.setEndAfter(E),G=domUtils.getNextDomNode(E,!1,j);var J=h.document.createElement("li");if(J.appendChild(H.extractContents()),domUtils.isEmptyNode(J)){for(var E=h.document.createElement("p");J.firstChild;)E.appendChild(J.firstChild);J.appendChild(E)}l.appendChild(J)}else G=domUtils.getNextDomNode(G,!0,j);h.moveToBookmark(F).collapse(!0),o=f.document.createElement(k),e(o,c),o.appendChild(l),h.insertNode(o),d(o,k,c);for(var x,y=0,K=domUtils.getElementsByTagName(o,"div");x=K[y++];)x.getAttribute("tmpDiv")&&domUtils.remove(x,!0);h.moveToBookmark(q).select()},queryCommandState:function(a){for(var b,c="insertorderedlist"==a.toLowerCase()?"ol":"ul",d=this.selection.getStartElementPath(),e=0;b=d[e++];){if("TABLE"==b.nodeName)return 0;if(c==b.nodeName.toLowerCase())return 1}return 0},queryCommandValue:function(a){for(var c,d,e="insertorderedlist"==a.toLowerCase()?"ol":"ul",f=this.selection.getStartElementPath(),g=0;d=f[g++];){if("TABLE"==d.nodeName){c=null;break}if(e==d.nodeName.toLowerCase()){c=d;break}}return c?b(c)||domUtils.getComputedStyle(c,"list-style-type"):null}}},function(){var a={textarea:function(a,b){var c=b.ownerDocument.createElement("textarea");return c.style.cssText="position:absolute;resize:none;width:100%;height:100%;border:0;padding:0;margin:0;overflow-y:auto;",browser.ie&&browser.version<8&&(c.style.width=b.offsetWidth+"px",c.style.height=b.offsetHeight+"px",b.onresize=function(){c.style.width=b.offsetWidth+"px",c.style.height=b.offsetHeight+"px"}),b.appendChild(c),{setContent:function(a){c.value=a},getContent:function(){return c.value},select:function(){var a;browser.ie?(a=c.createTextRange(),a.collapse(!0),a.select()):(c.setSelectionRange(0,0),c.focus())},dispose:function(){b.removeChild(c),b.onresize=null,c=null,b=null}}},codemirror:function(a,b){var c=window.CodeMirror(b,{mode:"text/html",tabMode:"indent",lineNumbers:!0,lineWrapping:!0}),d=c.getWrapperElement();return d.style.cssText='position:absolute;left:0;top:0;width:100%;height:100%;font-family:consolas,"Courier new",monospace;font-size:13px;',c.getScrollerElement().style.cssText="position:absolute;left:0;top:0;width:100%;height:100%;",c.refresh(),{getCodeMirror:function(){return c},setContent:function(a){c.setValue(a)},getContent:function(){return c.getValue()},select:function(){c.focus()},dispose:function(){b.removeChild(d),d=null,c=null}}}};UE.plugins.source=function(){function b(b){return a["codemirror"==f.sourceEditor&&window.CodeMirror?"codemirror":"textarea"](e,b)}var c,d,e=this,f=this.options,g=!1;f.sourceEditor=browser.ie?"textarea":f.sourceEditor||"codemirror",e.setOpt({sourceEditorFirst:!1});var h,i,j;e.commands.source={execCommand:function(){if(g=!g){j=e.selection.getRange().createAddress(!1,!0),e.undoManger&&e.undoManger.save(!0),browser.gecko&&(e.body.contentEditable=!1),h=e.iframe.style.cssText,e.iframe.style.cssText+="position:absolute;left:-32768px;top:-32768px;",e.fireEvent("beforegetcontent");var a=UE.htmlparser(e.body.innerHTML);e.filterOutputRule(a),a.traversal(function(a){if("element"==a.type)switch(a.tagName){case"td":case"th":case"caption":a.children&&1==a.children.length&&"br"==a.firstChild().tagName&&a.removeChild(a.firstChild());break;case"pre":a.innerText(a.innerText().replace(/ /g," "))}}),e.fireEvent("aftergetcontent");var f=a.toHtml(!0);c=b(e.iframe.parentNode),c.setContent(f),d=e.setContent,e.setContent=function(a){var b=UE.htmlparser(a);e.filterInputRule(b),a=b.toHtml(),c.setContent(a)},setTimeout(function(){c.select(),e.addListener("fullscreenchanged",function(){try{c.getCodeMirror().refresh()}catch(a){}})}),i=e.getContent,e.getContent=function(){return c.getContent()||"

          "+(browser.ie?"":"
          ")+"

          "}}else{e.iframe.style.cssText=h;var k=c.getContent()||"

          "+(browser.ie?"":"
          ")+"

          ";k=k.replace(new RegExp("[\\r\\t\\n ]*]*)>","g"),function(a,b){return b&&!dtd.$inlineWithA[b.toLowerCase()]?a.replace(/(^[\n\r\t ]*)|([\n\r\t ]*$)/g,""):a.replace(/(^[\n\r\t]*)|([\n\r\t]*$)/g,"")}),e.setContent=d,e.setContent(k),c.dispose(),c=null,e.getContent=i;var l=e.body.firstChild;if(l||(e.body.innerHTML="

          "+(browser.ie?"":"
          ")+"

          ",l=e.body.firstChild),e.undoManger&&e.undoManger.save(!0),browser.gecko){var m=document.createElement("input");m.style.cssText="position:absolute;left:0;top:-32768px",document.body.appendChild(m),e.body.contentEditable=!1,setTimeout(function(){domUtils.setViewportOffset(m,{left:-32768,top:0}),m.focus(),setTimeout(function(){e.body.contentEditable=!0,e.selection.getRange().moveToAddress(j).select(!0),domUtils.remove(m)})})}else try{e.selection.getRange().moveToAddress(j).select(!0)}catch(n){}}this.fireEvent("sourcemodechanged",g)},queryCommandState:function(){return 0|g},notNeedUndo:1};var k=e.queryCommandState;e.queryCommandState=function(a){return a=a.toLowerCase(),g?a in{source:1,fullscreen:1}?1:-1:k.apply(this,arguments)},"codemirror"==f.sourceEditor&&e.addListener("ready",function(){utils.loadFile(document,{src:f.codeMirrorJsUrl||f.UEDITOR_HOME_URL+"third-party/codemirror/codemirror.js",tag:"script",type:"text/javascript",defer:"defer"},function(){f.sourceEditorFirst&&setTimeout(function(){e.execCommand("source")},0)}),utils.loadFile(document,{tag:"link",rel:"stylesheet",type:"text/css",href:f.codeMirrorCssUrl||f.UEDITOR_HOME_URL+"third-party/codemirror/codemirror.css"})})}}(),UE.plugins.enterkey=function(){var a,b=this,c=b.options.enterTag;b.addListener("keyup",function(c,d){var e=d.keyCode||d.which;if(13==e){var f,g=b.selection.getRange(),h=g.startContainer;if(browser.ie)b.fireEvent("saveScene",!0,!0);else{if(/h\d/i.test(a)){if(browser.gecko){var i=domUtils.findParentByTagName(h,["h1","h2","h3","h4","h5","h6","blockquote","caption","table"],!0);i||(b.document.execCommand("formatBlock",!1,"

          "),f=1)}else if(1==h.nodeType){var j,k=b.document.createTextNode("");if(g.insertNode(k),j=domUtils.findParentByTagName(k,"div",!0)){for(var l=b.document.createElement("p");j.firstChild;)l.appendChild(j.firstChild);j.parentNode.insertBefore(l,j),domUtils.remove(j),g.setStartBefore(k).setCursor(),f=1}domUtils.remove(k)}b.undoManger&&f&&b.undoManger.save()}browser.opera&&g.select()}}}),b.addListener("keydown",function(d,e){var f=e.keyCode||e.which;if(13==f){if(b.fireEvent("beforeenterkeydown"))return void domUtils.preventDefault(e);b.fireEvent("saveScene",!0,!0),a="";var g=b.selection.getRange();if(!g.collapsed){var h=g.startContainer,i=g.endContainer,j=domUtils.findParentByTagName(h,"td",!0),k=domUtils.findParentByTagName(i,"td",!0);if(j&&k&&j!==k||!j&&k||j&&!k)return void(e.preventDefault?e.preventDefault():e.returnValue=!1)}if("p"==c)browser.ie||(h=domUtils.findParentByTagName(g.startContainer,["ol","ul","p","h1","h2","h3","h4","h5","h6","blockquote","caption"],!0),h||browser.opera?(a=h.tagName,"p"==h.tagName.toLowerCase()&&browser.gecko&&domUtils.removeDirtyAttr(h)):(b.document.execCommand("formatBlock",!1,"

          "),browser.gecko&&(g=b.selection.getRange(),h=domUtils.findParentByTagName(g.startContainer,"p",!0),h&&domUtils.removeDirtyAttr(h))));else if(e.preventDefault?e.preventDefault():e.returnValue=!1,g.collapsed){m=g.document.createElement("br"),g.insertNode(m);var l=m.parentNode;l.lastChild===m?(m.parentNode.insertBefore(m.cloneNode(!0),m),g.setStartBefore(m)):g.setStartAfter(m),g.setCursor()}else if(g.deleteContents(),h=g.startContainer,1==h.nodeType&&(h=h.childNodes[g.startOffset])){for(;1==h.nodeType;){if(dtd.$empty[h.tagName])return g.setStartBefore(h).setCursor(),b.undoManger&&b.undoManger.save(),!1;if(!h.firstChild){var m=g.document.createElement("br");return h.appendChild(m),g.setStart(h,0).setCursor(),b.undoManger&&b.undoManger.save(),!1}h=h.firstChild}h===g.startContainer.childNodes[g.startOffset]?(m=g.document.createElement("br"),g.insertNode(m).setCursor()):g.setStart(h,0).setCursor()}else m=g.document.createElement("br"),g.insertNode(m).setStartAfter(m).setCursor()}})},UE.plugins.keystrokes=function(){var a=this,b=!0;a.addListener("keydown",function(c,d){var e=d.keyCode||d.which,f=a.selection.getRange();if(!f.collapsed&&!(d.ctrlKey||d.shiftKey||d.altKey||d.metaKey)&&(e>=65&&e<=90||e>=48&&e<=57||e>=96&&e<=111||{13:1,8:1,46:1}[e])){var g=f.startContainer;if(domUtils.isFillChar(g)&&f.setStartBefore(g),g=f.endContainer,domUtils.isFillChar(g)&&f.setEndAfter(g),f.txtToElmBoundary(),f.endContainer&&1==f.endContainer.nodeType&&(g=f.endContainer.childNodes[f.endOffset],g&&domUtils.isBr(g)&&f.setEndAfter(g)),0==f.startOffset&&(g=f.startContainer,domUtils.isBoundaryNode(g,"firstChild")&&(g=f.endContainer,f.endOffset==(3==g.nodeType?g.nodeValue.length:g.childNodes.length)&&domUtils.isBoundaryNode(g,"lastChild"))))return a.fireEvent("saveScene"),a.body.innerHTML="

          "+(browser.ie?"":"
          ")+"

          ",f.setStart(a.body.firstChild,0).setCursor(!1,!0),void a._selectionChange()}if(e==keymap.Backspace){if(f=a.selection.getRange(),b=f.collapsed,a.fireEvent("delkeydown",d))return;var h,i;if(f.collapsed&&f.inFillChar()&&(h=f.startContainer,domUtils.isFillChar(h)?(f.setStartBefore(h).shrinkBoundary(!0).collapse(!0),domUtils.remove(h)):(h.nodeValue=h.nodeValue.replace(new RegExp("^"+domUtils.fillChar),""),f.startOffset--,f.collapse(!0).select(!0))),h=f.getClosedNode())return a.fireEvent("saveScene"),f.setStartBefore(h),domUtils.remove(h),f.setCursor(),a.fireEvent("saveScene"),void domUtils.preventDefault(d);if(!browser.ie&&(h=domUtils.findParentByTagName(f.startContainer,"table",!0),i=domUtils.findParentByTagName(f.endContainer,"table",!0),h&&!i||!h&&i||h!==i))return void d.preventDefault()}if(e==keymap.Tab){var j={ol:1,ul:1,table:1};if(a.fireEvent("tabkeydown",d))return void domUtils.preventDefault(d);var k=a.selection.getRange();a.fireEvent("saveScene");for(var l=0,m="",n=a.options.tabSize||4,o=a.options.tabNode||" ";l"});d.insertNode(g).setStart(g,0).setCursor(!1,!0)}}if(!b&&(3==d.startContainer.nodeType||1==d.startContainer.nodeType&&domUtils.isEmptyBlock(d.startContainer)))if(browser.ie){var k=d.document.createElement("span");d.insertNode(k).setStartBefore(k).collapse(!0),d.select(),domUtils.remove(k)}else d.select()}})},UE.plugins.fiximgclick=function(){function a(){this.editor=null,this.resizer=null,this.cover=null,this.doc=document,this.prePos={x:0,y:0},this.startPos={x:0,y:0}}var b=!1;return function(){var c=[[0,0,-1,-1],[0,0,0,-1],[0,0,1,-1],[0,0,-1,0],[0,0,1,0],[0,0,-1,1],[0,0,0,1],[0,0,1,1]];a.prototype={init:function(a){var b=this;b.editor=a,b.startPos=this.prePos={x:0,y:0},b.dragId=-1;var c=[],d=b.cover=document.createElement("div"),e=b.resizer=document.createElement("div");for(d.id=b.editor.ui.id+"_imagescale_cover",d.style.cssText="position:absolute;display:none;z-index:"+b.editor.options.zIndex+";filter:alpha(opacity=0); opacity:0;background:#CCC;",domUtils.on(d,"mousedown click",function(){b.hide()}),i=0;i<8;i++)c.push('');e.id=b.editor.ui.id+"_imagescale",e.className="edui-editor-imagescale",e.innerHTML=c.join(""),e.style.cssText+=";display:none;border:1px solid #3b77ff;z-index:"+b.editor.options.zIndex+";",b.editor.ui.getDom().appendChild(d),b.editor.ui.getDom().appendChild(e),b.initStyle(),b.initEvents()},initStyle:function(){utils.cssRule("imagescale",".edui-editor-imagescale{display:none;position:absolute;border:1px solid #38B2CE;cursor:hand;-webkit-box-sizing: content-box;-moz-box-sizing: content-box;box-sizing: content-box;}.edui-editor-imagescale span{position:absolute;width:6px;height:6px;overflow:hidden;font-size:0px;display:block;background-color:#3C9DD0;}.edui-editor-imagescale .edui-editor-imagescale-hand0{cursor:nw-resize;top:0;margin-top:-4px;left:0;margin-left:-4px;}.edui-editor-imagescale .edui-editor-imagescale-hand1{cursor:n-resize;top:0;margin-top:-4px;left:50%;margin-left:-4px;}.edui-editor-imagescale .edui-editor-imagescale-hand2{cursor:ne-resize;top:0;margin-top:-4px;left:100%;margin-left:-3px;}.edui-editor-imagescale .edui-editor-imagescale-hand3{cursor:w-resize;top:50%;margin-top:-4px;left:0;margin-left:-4px;}.edui-editor-imagescale .edui-editor-imagescale-hand4{cursor:e-resize;top:50%;margin-top:-4px;left:100%;margin-left:-3px;}.edui-editor-imagescale .edui-editor-imagescale-hand5{cursor:sw-resize;top:100%;margin-top:-3px;left:0;margin-left:-4px;}.edui-editor-imagescale .edui-editor-imagescale-hand6{cursor:s-resize;top:100%;margin-top:-3px;left:50%;margin-left:-4px;}.edui-editor-imagescale .edui-editor-imagescale-hand7{cursor:se-resize;top:100%;margin-top:-3px;left:100%;margin-left:-3px;}")},initEvents:function(){var a=this;a.startPos.x=a.startPos.y=0,a.isDraging=!1},_eventHandler:function(a){var c=this;switch(a.type){case"mousedown":var d,d=a.target||a.srcElement;d.className.indexOf("edui-editor-imagescale-hand")!=-1&&c.dragId==-1&&(c.dragId=d.className.slice(-1),c.startPos.x=c.prePos.x=a.clientX,c.startPos.y=c.prePos.y=a.clientY,domUtils.on(c.doc,"mousemove",c.proxy(c._eventHandler,c)));break;case"mousemove":c.dragId!=-1&&(c.updateContainerStyle(c.dragId,{x:a.clientX-c.prePos.x,y:a.clientY-c.prePos.y}),c.prePos.x=a.clientX,c.prePos.y=a.clientY,b=!0,c.updateTargetElement());break;case"mouseup":c.dragId!=-1&&(c.updateContainerStyle(c.dragId,{x:a.clientX-c.prePos.x,y:a.clientY-c.prePos.y}),c.updateTargetElement(),c.target.parentNode&&c.attachTo(c.target),c.dragId=-1),domUtils.un(c.doc,"mousemove",c.proxy(c._eventHandler,c)),b&&(b=!1,c.editor.fireEvent("contentchange"))}},updateTargetElement:function(){var a=this;domUtils.setStyles(a.target,{width:a.resizer.style.width,height:a.resizer.style.height}),a.target.width=parseInt(a.resizer.style.width),a.target.height=parseInt(a.resizer.style.height),a.attachTo(a.target)},updateContainerStyle:function(a,b){var d,e=this,f=e.resizer;0!=c[a][0]&&(d=parseInt(f.style.left)+b.x,f.style.left=e._validScaledProp("left",d)+"px"),0!=c[a][1]&&(d=parseInt(f.style.top)+b.y,f.style.top=e._validScaledProp("top",d)+"px"),0!=c[a][2]&&(d=f.clientWidth+c[a][2]*b.x,f.style.width=e._validScaledProp("width",d)+"px"),0!=c[a][3]&&(d=f.clientHeight+c[a][3]*b.y,f.style.height=e._validScaledProp("height",d)+"px")},_validScaledProp:function(a,b){var c=this.resizer,d=document;switch(b=isNaN(b)?0:b,a){case"left":return b<0?0:b+c.clientWidth>d.clientWidth?d.clientWidth-c.clientWidth:b;case"top":return b<0?0:b+c.clientHeight>d.clientHeight?d.clientHeight-c.clientHeight:b;case"width":return b<=0?1:b+c.offsetLeft>d.clientWidth?d.clientWidth-c.offsetLeft:b;case"height":return b<=0?1:b+c.offsetTop>d.clientHeight?d.clientHeight-c.offsetTop:b}},hideCover:function(){this.cover.style.display="none"},showCover:function(){var a=this,b=domUtils.getXY(a.editor.ui.getDom()),c=domUtils.getXY(a.editor.iframe);domUtils.setStyles(a.cover,{width:a.editor.iframe.offsetWidth+"px",height:a.editor.iframe.offsetHeight+"px",top:c.y-b.y+"px",left:c.x-b.x+"px",position:"absolute",display:""})},show:function(a){var b=this;b.resizer.style.display="block",a&&b.attachTo(a),domUtils.on(this.resizer,"mousedown",b.proxy(b._eventHandler,b)),domUtils.on(b.doc,"mouseup",b.proxy(b._eventHandler,b)),b.showCover(),b.editor.fireEvent("afterscaleshow",b),b.editor.fireEvent("saveScene")},hide:function(){var a=this;a.hideCover(),a.resizer.style.display="none",domUtils.un(a.resizer,"mousedown",a.proxy(a._eventHandler,a)),domUtils.un(a.doc,"mouseup",a.proxy(a._eventHandler,a)),a.editor.fireEvent("afterscalehide",a)},proxy:function(a,b){return function(c){return a.apply(b||this,arguments)}},attachTo:function(a){var b=this,c=b.target=a,d=this.resizer,e=domUtils.getXY(c),f=domUtils.getXY(b.editor.iframe),g=domUtils.getXY(d.parentNode);domUtils.setStyles(d,{width:c.width+"px",height:c.height+"px",left:f.x+e.x-b.editor.document.body.scrollLeft-g.x-parseInt(d.style.borderLeftWidth)+"px",top:f.y+e.y-b.editor.document.body.scrollTop-g.y-parseInt(d.style.borderTopWidth)+"px"})}}}(),function(){var b,c=this;c.setOpt("imageScaleEnabled",!0),!browser.ie&&c.options.imageScaleEnabled&&c.addListener("click",function(d,e){var f=c.selection.getRange(),g=f.getClosedNode();if(g&&"IMG"==g.tagName&&"false"!=c.body.contentEditable){if(g.className.indexOf("edui-faked-music")!=-1||g.getAttribute("anchorname")||domUtils.hasClass(g,"loadingclass")||domUtils.hasClass(g,"loaderrorclass"))return;if(!b){b=new a,b.init(c),c.ui.getDom().appendChild(b.resizer);var h,i=function(a){b.hide(),b.target&&c.selection.getRange().selectNode(b.target).select()},j=function(a){var b=a.target||a.srcElement;!b||void 0!==b.className&&b.className.indexOf("edui-editor-imagescale")!=-1||i(a)};c.addListener("afterscaleshow",function(a){c.addListener("beforekeydown",i),c.addListener("beforemousedown",j),domUtils.on(document,"keydown",i),domUtils.on(document,"mousedown",j),c.selection.getNative().removeAllRanges()}),c.addListener("afterscalehide",function(a){c.removeListener("beforekeydown",i),c.removeListener("beforemousedown",j),domUtils.un(document,"keydown",i),domUtils.un(document,"mousedown",j);var d=b.target;d.parentNode&&c.selection.getRange().selectNode(d).select()}),domUtils.on(b.resizer,"mousedown",function(a){c.selection.getNative().removeAllRanges();var d=a.target||a.srcElement;d&&d.className.indexOf("edui-editor-imagescale-hand")==-1&&(h=setTimeout(function(){b.hide(),b.target&&c.selection.getRange().selectNode(d).select()},200))}),domUtils.on(b.resizer,"mouseup",function(a){var b=a.target||a.srcElement;b&&b.className.indexOf("edui-editor-imagescale-hand")==-1&&clearTimeout(h)})}b.show(g)}else b&&"none"!=b.resizer.style.display&&b.hide()}),browser.webkit&&c.addListener("click",function(a,b){if("IMG"==b.target.tagName&&"false"!=c.body.contentEditable){var d=new dom.Range(c.document);d.selectNode(b.target).select()}})}}(),UE.plugin.register("autolink",function(){var a=0;return browser.ie?{}:{bindEvents:{reset:function(){a=0},keydown:function(a,b){var c=this,d=b.keyCode||b.which;if(32==d||13==d){for(var e,f,g=c.selection.getNative(),h=g.getRangeAt(0).cloneRange(),i=h.startContainer;1==i.nodeType&&h.startOffset>0&&(i=h.startContainer.childNodes[h.startOffset-1]);)h.setStart(i,1==i.nodeType?i.childNodes.length:i.nodeValue.length),h.collapse(!0),i=h.startContainer;do{if(0==h.startOffset){for(i=h.startContainer.previousSibling;i&&1==i.nodeType;)i=i.lastChild;if(!i||domUtils.isFillChar(i))break;e=i.nodeValue.length}else i=h.startContainer,e=h.startOffset;h.setStart(i,e-1),f=h.toString().charCodeAt(0)}while(160!=f&&32!=f);if(h.toString().replace(new RegExp(domUtils.fillChar,"g"),"").match(/(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i)){for(;h.toString().length&&!/^(?:https?:\/\/|ssh:\/\/|ftp:\/\/|file:\/|www\.)/i.test(h.toString());)try{h.setStart(h.startContainer,h.startOffset+1)}catch(j){for(var i=h.startContainer;!(next=i.nextSibling);){if(domUtils.isBody(i))return;i=i.parentNode}h.setStart(next,0)}if(domUtils.findParentByTagName(h.startContainer,"a",!0))return;var k,l=c.document.createElement("a"),m=c.document.createTextNode(" ");c.undoManger&&c.undoManger.save(),l.appendChild(h.extractContents()),l.href=l.innerHTML=l.innerHTML.replace(/<[^>]+>/g,""),k=l.getAttribute("href").replace(new RegExp(domUtils.fillChar,"g"),""),k=/^(?:https?:\/\/)/gi.test(k)?k:"http://"+k,l.setAttribute("_src",utils.html(k)),l.href=utils.html(k),h.insertNode(l),l.parentNode.insertBefore(m,l.nextSibling),h.setStart(m,0),h.collapse(!0),g.removeAllRanges(),g.addRange(h),c.undoManger&&c.undoManger.save()}}}}}},function(){function a(a){if(3==a.nodeType)return null;if("A"==a.nodeName)return a;for(var b=a.lastChild;b;){if("A"==b.nodeName)return b;if(3==b.nodeType){if(domUtils.isWhitespace(b)){b=b.previousSibling;continue}return null}b=b.lastChild}}var b={37:1,38:1,39:1,40:1,13:1,32:1};browser.ie&&this.addListener("keyup",function(c,d){var e=this,f=d.keyCode;if(b[f]){var g=e.selection.getRange(),h=g.startContainer;if(13==f){for(;h&&!domUtils.isBody(h)&&!domUtils.isBlockElm(h);)h=h.parentNode;if(h&&!domUtils.isBody(h)&&"P"==h.nodeName){var i=h.previousSibling;if(i&&1==i.nodeType){var i=a(i);i&&!i.getAttribute("_href")&&domUtils.remove(i,!0)}}}else if(32==f)3==h.nodeType&&/^\s$/.test(h.nodeValue)&&(h=h.previousSibling,h&&"A"==h.nodeName&&!h.getAttribute("_href")&&domUtils.remove(h,!0));else if(h=domUtils.findParentByTagName(h,"a",!0),h&&!h.getAttribute("_href")){var j=g.createBookmark();domUtils.remove(h,!0),g.moveToBookmark(j).select(!0)}}})}),UE.plugins.autoheight=function(){function a(){var a=this;clearTimeout(e),f||(!a.queryCommandState||a.queryCommandState&&1!=a.queryCommandState("source"))&&(e=setTimeout(function(){for(var b=a.body.lastChild;b&&1!=b.nodeType;)b=b.previousSibling;b&&1==b.nodeType&&(b.style.clear="both",d=Math.max(domUtils.getXY(b).y+b.offsetHeight+25,Math.max(h.minFrameHeight,h.initialFrameHeight)),d!=g&&(d!==parseInt(a.iframe.parentNode.style.height)&&(a.iframe.parentNode.style.height=d+"px"),a.body.style.height=d+"px",g=d),domUtils.removeStyle(b,"clear"))},50))}var b=this;if(b.autoHeightEnabled=b.options.autoHeightEnabled!==!1,b.autoHeightEnabled){var c,d,e,f,g=0,h=b.options;b.addListener("fullscreenchanged",function(a,b){f=b}),b.addListener("destroy",function(){b.removeListener("contentchange afterinserthtml keyup mouseup",a)}),b.enableAutoHeight=function(){var b=this;if(b.autoHeightEnabled){var d=b.document;b.autoHeightEnabled=!0,c=d.body.style.overflowY,d.body.style.overflowY="hidden",b.addListener("contentchange afterinserthtml keyup mouseup",a),setTimeout(function(){a.call(b)},browser.gecko?100:0),b.fireEvent("autoheightchanged",b.autoHeightEnabled)}},b.disableAutoHeight=function(){b.body.style.overflowY=c||"",b.removeListener("contentchange",a),b.removeListener("keyup",a),b.removeListener("mouseup",a),b.autoHeightEnabled=!1,b.fireEvent("autoheightchanged",b.autoHeightEnabled)},b.on("setHeight",function(){b.disableAutoHeight()}),b.addListener("ready",function(){b.enableAutoHeight();var c;domUtils.on(browser.ie?b.body:b.document,browser.webkit?"dragover":"drop",function(){clearTimeout(c),c=setTimeout(function(){a.call(b)},100)});var d;window.onscroll=function(){ +null===d?d=this.scrollY:0==this.scrollY&&0!=d&&(b.window.scrollTo(0,0),d=null)}})}},UE.plugins.autofloat=function(){function a(){return UE.ui?1:(alert(g.autofloatMsg),0)}function b(){var a=document.body.style;a.backgroundImage='url("about:blank")',a.backgroundAttachment="fixed"}function c(){var a=domUtils.getXY(k),b=domUtils.getComputedStyle(k,"position"),c=domUtils.getComputedStyle(k,"left");k.style.width=k.offsetWidth+"px",k.style.zIndex=1*f.options.zIndex+1,k.parentNode.insertBefore(q,k),o||p&&browser.ie?("absolute"!=k.style.position&&(k.style.position="absolute"),k.style.top=(document.body.scrollTop||document.documentElement.scrollTop)-l+i+"px"):(browser.ie7Compat&&r&&(r=!1,k.style.left=domUtils.getXY(k).x-document.documentElement.getBoundingClientRect().left+2+"px"),"fixed"!=k.style.position&&(k.style.position="fixed",k.style.top=i+"px",("absolute"==b||"relative"==b)&&parseFloat(c)&&(k.style.left=a.x+"px")))}function d(){r=!0,q.parentNode&&q.parentNode.removeChild(q),k.style.cssText=j}function e(){var a=m(f.container),b=f.options.toolbarTopOffset||0;a.top<0&&a.bottom-k.offsetHeight>b?c():d()}var f=this,g=f.getLang();f.setOpt({topOffset:0});var h=f.options.autoFloatEnabled!==!1,i=f.options.topOffset;if(h){var j,k,l,m,n=UE.ui.uiUtils,o=browser.ie&&browser.version<=6,p=browser.quirks,q=document.createElement("div"),r=!0,s=utils.defer(function(){e()},browser.ie?200:100,!0);f.addListener("destroy",function(){domUtils.un(window,["scroll","resize"],e),f.removeListener("keydown",s)}),f.addListener("ready",function(){if(a(f)){if(!f.ui)return;m=n.getClientRect,k=f.ui.getDom("toolbarbox"),l=m(k).top,j=k.style.cssText,q.style.height=k.offsetHeight+"px",o&&b(),domUtils.on(window,["scroll","resize"],e),f.addListener("keydown",s),f.addListener("beforefullscreenchange",function(a,b){b&&d()}),f.addListener("fullscreenchanged",function(a,b){b||e()}),f.addListener("sourcemodechanged",function(a,b){setTimeout(function(){e()},0)}),f.addListener("clearDoc",function(){setTimeout(function(){e()},0)})}})}},UE.plugins.video=function(){function a(a,b,d,e,f,g,h){a=utils.unhtmlForUrl(a),f=utils.unhtml(f),g=utils.unhtml(g),b=parseInt(b,10)||0,d=parseInt(d,10)||0;var i;switch(h){case"image":i="';break;case"embed":i='';break;case"video":var j=a.substr(a.lastIndexOf(".")+1);"ogv"==j&&(j="ogg"),i="'}return i}function b(b,c){utils.each(b.getNodesByTagName(c?"img":"embed video"),function(b){var d=b.getAttr("class");if(d&&d.indexOf("edui-faked-video")!=-1){var e=a(c?b.getAttr("_url"):b.getAttr("src"),b.getAttr("width"),b.getAttr("height"),null,b.getStyle("float")||"",d,c?"embed":"image");b.parentNode.replaceChild(UE.uNode.createElement(e),b)}if(d&&d.indexOf("edui-upload-video")!=-1){var e=a(c?b.getAttr("_url"):b.getAttr("src"),b.getAttr("width"),b.getAttr("height"),null,b.getStyle("float")||"",d,c?"video":"image");b.parentNode.replaceChild(UE.uNode.createElement(e),b)}})}var c=this;c.addOutputRule(function(a){b(a,!0)}),c.addInputRule(function(a){b(a)}),c.commands.insertvideo={execCommand:function(b,d,e){d=utils.isArray(d)?d:[d];for(var f,g,h=[],i="tmpVedio",j=0,k=d.length;j0)return 0;for(var c in dtd.$isNotEmpty)if(dtd.$isNotEmpty.hasOwnProperty(c)&&a.getElementsByTagName(c).length)return 0;return 1},b.getWidth=function(a){return a?parseInt(domUtils.getComputedStyle(a,"width"),10):0},b.getTableCellAlignState=function(a){!utils.isArray(a)&&(a=[a]);var b={},c=["align","valign"],d=null,e=!0;return utils.each(a,function(a){return utils.each(c,function(c){if(d=a.getAttribute(c),!b[c]&&d)b[c]=d;else if(!b[c]||d!==b[c])return e=!1,!1}),e}),e?b:null},b.getTableItemsByRange=function(a){var b=a.selection.getStart();b&&b.id&&0===b.id.indexOf("_baidu_bookmark_start_")&&b.nextSibling&&(b=b.nextSibling);var c=b&&domUtils.findParentByTagName(b,["td","th"],!0),d=c&&c.parentNode,e=b&&domUtils.findParentByTagName(b,"caption",!0),f=e?e.parentNode:d&&d.parentNode.parentNode;return{cell:c,tr:d,table:f,caption:e}},b.getUETableBySelected=function(a){var c=b.getTableItemsByRange(a).table;return c&&c.ueTable&&c.ueTable.selectedTds.length?c.ueTable:null},b.getDefaultValue=function(a,b){var c,d,e,f,g={thin:"0px",medium:"1px",thick:"2px"};if(b)return h=b.getElementsByTagName("td")[0],f=domUtils.getComputedStyle(b,"border-left-width"),c=parseInt(g[f]||f,10),f=domUtils.getComputedStyle(h,"padding-left"),d=parseInt(g[f]||f,10),f=domUtils.getComputedStyle(h,"border-left-width"),e=parseInt(g[f]||f,10),{tableBorder:c,tdPadding:d,tdBorder:e};b=a.document.createElement("table"),b.insertRow(0).insertCell(0).innerHTML="xxx",a.body.appendChild(b);var h=b.getElementsByTagName("td")[0];return f=domUtils.getComputedStyle(b,"border-left-width"),c=parseInt(g[f]||f,10),f=domUtils.getComputedStyle(h,"padding-left"),d=parseInt(g[f]||f,10),f=domUtils.getComputedStyle(h,"border-left-width"),e=parseInt(g[f]||f,10),domUtils.remove(b),{tableBorder:c,tdPadding:d,tdBorder:e}},b.getUETable=function(a){var c=a.tagName.toLowerCase();return a="td"==c||"th"==c||"caption"==c?domUtils.findParentByTagName(a,"table",!0):a,a.ueTable||(a.ueTable=new b(a)),a.ueTable},b.cloneCell=function(a,b,c){if(!a||utils.isString(a))return this.table.ownerDocument.createElement(a||"td");var d=domUtils.hasClass(a,"selectTdClass");d&&domUtils.removeClasses(a,"selectTdClass");var e=a.cloneNode(!0);return b&&(e.rowSpan=e.colSpan=1),!c&&domUtils.removeAttributes(e,"width height"),!c&&domUtils.removeAttributes(e,"style"),e.style.borderLeftStyle="",e.style.borderTopStyle="",e.style.borderLeftColor=a.style.borderRightColor,e.style.borderLeftWidth=a.style.borderRightWidth,e.style.borderTopColor=a.style.borderBottomColor,e.style.borderTopWidth=a.style.borderBottomWidth,d&&domUtils.addClass(a,"selectTdClass"),e},b.prototype={getMaxRows:function(){for(var a,b=this.table.rows,c=1,d=0;a=b[d];d++){for(var e,f=1,g=0;e=a.cells[g++];)f=Math.max(e.rowSpan||1,f);c=Math.max(f+d,c)}return c},getMaxCols:function(){for(var a,b=this.table.rows,c=0,d={},e=0;a=b[e];e++){for(var f,g=0,h=0;f=a.cells[h++];)if(g+=f.colSpan||1,f.rowSpan&&f.rowSpan>1)for(var i=1;ithis.rowsNum-1)?null:(e=c?h?i.endRowIndex+1:g.rowIndex+g.rowSpan:h?i.beginRowIndex-1:g.rowIndex-1,f=h?i.beginColIndex:g.colIndex,this.getCell(this.indexTable[e][f].rowIndex,this.indexTable[e][f].cellIndex))}catch(j){a(j)}},getSameEndPosCells:function(b,c){try{for(var d="x"===c.toLowerCase(),e=domUtils.getXY(b)[d?"x":"y"]+b["offset"+(d?"Width":"Height")],f=this.table.rows,g=null,h=[],i=0;ie&&d)break;if((b==j||e==l)&&(1==j[d?"colSpan":"rowSpan"]&&h.push(j),d))break}}return h}catch(m){a(m)}},setCellContent:function(a,b){a.innerHTML=b||(browser.ie?domUtils.fillChar:"
          ")},cloneCell:b.cloneCell,getSameStartPosXCells:function(b){try{for(var c,d=domUtils.getXY(b).x+b.offsetWidth,e=this.table.rows,f=[],g=0;gd)break;if(j==d&&1==h.colSpan){f.push(h);break}}}return f}catch(k){a(k)}},update:function(a){this.table=a||this.table,this.selectedTds=[],this.cellsRange={},this.indexTable=[];for(var b=this.table.rows,c=this.getMaxRows(),d=c-b.length,e=this.getMaxCols();d--;)this.table.insertRow(b.length);this.rowsNum=c,this.colsNum=e;for(var f=0,g=b.length;fc&&(j.rowSpan=c);for(var m=k,n=j.rowSpan||1,o=j.colSpan||1;this.indexTable[i][m];)m++;for(var p=0;p0)for(h=b;hf&&(m=Math.max(h,m));if(ee&&(l=Math.max(i,l));if(b>0)for(i=a;ig||d+b.colSpan-1>h)return null;j.push(this.getCell(c,b.cellIndex))}}return j},clearSelected:function(){b.removeSelectedClass(this.selectedTds),this.selectedTds=[],this.cellsRange={}},setSelected:function(a){var c=this.getCells(a);b.addSelectedClass(c),this.selectedTds=c,this.cellsRange=a},isFullRow:function(){var a=this.cellsRange;return a.endColIndex-a.beginColIndex+1==this.colsNum},isFullCol:function(){var a=this.cellsRange,b=this.table,c=b.getElementsByTagName("th"),d=a.endRowIndex-a.beginRowIndex+1;return c.length?d==this.rowsNum||d==this.rowsNum-1:d==this.rowsNum},getNextCell:function(b,c,d){try{var e,f,g=this.getCellInfo(b),h=this.selectedTds.length&&!d,i=this.cellsRange;return!c&&0==g.rowIndex||c&&(h?i.endRowIndex==this.rowsNum-1:g.rowIndex+g.rowSpan>this.rowsNum-1)?null:(e=c?h?i.endRowIndex+1:g.rowIndex+g.rowSpan:h?i.beginRowIndex-1:g.rowIndex-1,f=h?i.beginColIndex:g.colIndex,this.getCell(this.indexTable[e][f].rowIndex,this.indexTable[e][f].cellIndex))}catch(j){a(j)}},getPreviewCell:function(b,c){try{var d,e,f=this.getCellInfo(b),g=this.selectedTds.length,h=this.cellsRange;return!c&&(g?!h.beginColIndex:!f.colIndex)||c&&(g?h.endColIndex==this.colsNum-1:f.rowIndex>this.colsNum-1)?null:(d=c?g?h.beginRowIndex:f.rowIndex<1?0:f.rowIndex-1:g?h.beginRowIndex:f.rowIndex,e=c?g?h.endColIndex+1:f.colIndex:g?h.beginColIndex-1:f.colIndex<1?0:f.colIndex-1,this.getCell(this.indexTable[d][e].rowIndex,this.indexTable[d][e].cellIndex))}catch(i){a(i)}},moveContent:function(a,c){if(!b.isEmptyBlock(c)){if(b.isEmptyBlock(a))return void(a.innerHTML=c.innerHTML);var d=a.lastChild;for(3!=d.nodeType&&dtd.$block[d.tagName]||a.appendChild(a.ownerDocument.createElement("br"));d=c.firstChild;)a.appendChild(d)}},mergeRight:function(a){var b=this.getCellInfo(a),c=b.colIndex+b.colSpan,d=this.indexTable[b.rowIndex][c],e=this.getCell(d.rowIndex,d.cellIndex);a.colSpan=b.colSpan+d.colSpan,a.removeAttribute("width"),this.moveContent(a,e),this.deleteCell(e,d.rowIndex),this.update()},mergeDown:function(a){var b=this.getCellInfo(a),c=b.rowIndex+b.rowSpan,d=this.indexTable[c][b.colIndex],e=this.getCell(d.rowIndex,d.cellIndex);a.rowSpan=b.rowSpan+d.rowSpan,a.removeAttribute("height"),this.moveContent(a,e),this.deleteCell(e,d.rowIndex),this.update()},mergeRange:function(){var a=this.cellsRange,b=this.getCell(a.beginRowIndex,this.indexTable[a.beginRowIndex][a.beginColIndex].cellIndex);if("TH"==b.tagName&&a.endRowIndex!==a.beginRowIndex){var c=this.indexTable,d=this.getCellInfo(b);b=this.getCell(1,c[1][d.colIndex].cellIndex),a=this.getCellsRange(b,this.getCell(c[this.rowsNum-1][d.colIndex].rowIndex,c[this.rowsNum-1][d.colIndex].cellIndex))}for(var e,f=this.getCells(a),g=0;e=f[g++];)e!==b&&(this.moveContent(b,e),this.deleteCell(e));if(b.rowSpan=a.endRowIndex-a.beginRowIndex+1,b.rowSpan>1&&b.removeAttribute("height"),b.colSpan=a.endColIndex-a.beginColIndex+1,b.colSpan>1&&b.removeAttribute("width"),b.rowSpan==this.rowsNum&&1!=b.colSpan&&(b.colSpan=1),b.colSpan==this.colsNum&&1!=b.rowSpan){var h=b.parentNode.rowIndex;if(this.table.deleteRow)for(var g=h+1,i=h+1,j=b.rowSpan;g1&&g.rowIndex==a){var i=h.cloneNode(!0);i.rowSpan=h.rowSpan-1,i.innerHTML="",h.rowSpan=1;var j,k=a+1,l=this.table.rows[k],m=this.getPreviewMergedCellsNum(k,f)-e;m1?l.colSpan--:c[h].deleteCell(j.cellIndex),h+=j.rowSpan||1}}this.table.setAttribute("width",d-e),this.update()},splitToCells:function(a){var b=this,c=this.splitToRows(a);utils.each(c,function(a){b.splitToCols(a)})},splitToRows:function(a){var b=this.getCellInfo(a),c=b.rowIndex,d=b.colIndex,e=[];a.rowSpan=1,e.push(a);for(var f=c,g=c+b.rowSpan;f");for(var g=0;g'+(browser.ie&&browser.version<11?domUtils.fillChar:"
          ")+"");c.push("")}return"
          "+c.join("")+"
          "}b||(b=utils.extend({},{numCols:this.options.defaultCols,numRows:this.options.defaultRows,tdvalign:this.options.tdvalign}));var d=this,e=this.selection.getRange(),f=e.startContainer,h=domUtils.findParent(f,function(a){return domUtils.isBlockElm(a)},!0)||d.body,i=g(d),j=h.offsetWidth,k=Math.floor(j/b.numCols-2*i.tdPadding-i.tdBorder);!b.tdvalign&&(b.tdvalign=d.options.tdvalign),d.execCommand("inserthtml",c(b,k))}},UE.commands.insertparagraphbeforetable={queryCommandState:function(){return e(this).cell?0:-1},execCommand:function(){var a=e(this).table;if(a){var b=this.document.createElement("p");b.innerHTML=browser.ie?" ":"
          ",a.parentNode.insertBefore(b,a),this.selection.getRange().setStart(b,0).setCursor()}}},UE.commands.deletetable={queryCommandState:function(){var a=this.selection.getRange();return domUtils.findParentByTagName(a.startContainer,"table",!0)?0:-1},execCommand:function(a,b){var c=this.selection.getRange();if(b=b||domUtils.findParentByTagName(c.startContainer,"table",!0)){var d=b.nextSibling;d||(d=domUtils.createElement(this.document,"p",{innerHTML:browser.ie?domUtils.fillChar:"
          "}),b.parentNode.insertBefore(d,b)),domUtils.remove(b),c=this.selection.getRange(),3==d.nodeType?c.setStartBefore(d):c.setStart(d,0),c.setCursor(!1,!0),this.fireEvent("tablehasdeleted")}}},UE.commands.cellalign={queryCommandState:function(){return c(this).length?0:-1},execCommand:function(a,b){var d=c(this);if(d.length)for(var e,f=0;e=d[f++];)e.setAttribute("align",b)}},UE.commands.cellvalign={queryCommandState:function(){return c(this).length?0:-1},execCommand:function(a,b){var d=c(this);if(d.length)for(var e,f=0;e=d[f++];)e.setAttribute("vAlign",b)}},UE.commands.insertcaption={queryCommandState:function(){var a=e(this).table;return a&&0==a.getElementsByTagName("caption").length?1:-1},execCommand:function(){var a=e(this).table;if(a){var b=this.document.createElement("caption");b.innerHTML=browser.ie?domUtils.fillChar:"
          ",a.insertBefore(b,a.firstChild);var c=this.selection.getRange();c.setStart(b,0).setCursor()}}},UE.commands.deletecaption={queryCommandState:function(){var a=this.selection.getRange(),b=domUtils.findParentByTagName(a.startContainer,"table");return b?0==b.getElementsByTagName("caption").length?-1:1:-1},execCommand:function(){var a=this.selection.getRange(),b=domUtils.findParentByTagName(a.startContainer,"table");if(b){domUtils.remove(b.getElementsByTagName("caption")[0]);var c=this.selection.getRange();c.setStart(b.rows[0].cells[0],0).setCursor()}}},UE.commands.inserttitle={queryCommandState:function(){var a=e(this).table;if(a){var b=a.rows[0];return"th"!=b.cells[b.cells.length-1].tagName.toLowerCase()?0:-1}return-1},execCommand:function(){var a=e(this).table;a&&h(a).insertRow(0,"th");var b=a.getElementsByTagName("th")[0];this.selection.getRange().setStart(b,0).setCursor(!1,!0)}},UE.commands.deletetitle={queryCommandState:function(){var a=e(this).table;if(a){var b=a.rows[0];return"th"==b.cells[b.cells.length-1].tagName.toLowerCase()?0:-1}return-1},execCommand:function(){var a=e(this).table;a&&domUtils.remove(a.rows[0]);var b=a.getElementsByTagName("td")[0];this.selection.getRange().setStart(b,0).setCursor(!1,!0)}},UE.commands.inserttitlecol={queryCommandState:function(){var a=e(this).table;if(a){var b=a.rows[a.rows.length-1];return b.getElementsByTagName("th").length?-1:0}return-1},execCommand:function(b){var c=e(this).table;c&&h(c).insertCol(0,"th"),a(c,this);var d=c.getElementsByTagName("th")[0];this.selection.getRange().setStart(d,0).setCursor(!1,!0)}},UE.commands.deletetitlecol={queryCommandState:function(){var a=e(this).table;if(a){var b=a.rows[a.rows.length-1];return b.getElementsByTagName("th").length?0:-1}return-1},execCommand:function(){var b=e(this).table;if(b)for(var c=0;c=f.colsNum)return-1;var j=f.indexTable[g.rowIndex][i],k=c.rows[j.rowIndex].cells[j.cellIndex];return k&&d.tagName==k.tagName&&j.rowIndex==g.rowIndex&&j.rowSpan==g.rowSpan?0:-1},execCommand:function(a){var b=this.selection.getRange(),c=b.createBookmark(!0),d=e(this).cell,f=h(d);f.mergeRight(d),b.moveToBookmark(c).select()}},UE.commands.mergedown={queryCommandState:function(a){var b=e(this),c=b.table,d=b.cell;if(!c||!d)return-1;var f=h(c);if(f.selectedTds.length)return-1;var g=f.getCellInfo(d),i=g.rowIndex+g.rowSpan;if(i>=f.rowsNum)return-1;var j=f.indexTable[i][g.colIndex],k=c.rows[j.rowIndex].cells[j.cellIndex];return k&&d.tagName==k.tagName&&j.colIndex==g.colIndex&&j.colSpan==g.colSpan?0:-1},execCommand:function(){var a=this.selection.getRange(),b=a.createBookmark(!0),c=e(this).cell,d=h(c);d.mergeDown(c),a.moveToBookmark(b).select()}},UE.commands.mergecells={queryCommandState:function(){return f(this)?0:-1},execCommand:function(){var a=f(this);if(a&&a.selectedTds.length){var b=a.selectedTds[0];a.mergeRange();var c=this.selection.getRange();domUtils.isEmptyBlock(b)?c.setStart(b,0).collapse(!0):c.selectNodeContents(b),c.select()}}},UE.commands.insertrow={queryCommandState:function(){var a=e(this),b=a.cell;return b&&("TD"==b.tagName||"TH"==b.tagName&&a.tr!==a.table.rows[0])&&h(a.table).rowsNum0?-1:b&&(b.colSpan>1||b.rowSpan>1)?0:-1},execCommand:function(){var a=this.selection.getRange(),b=a.createBookmark(!0),c=e(this).cell,d=h(c);d.splitToCells(c),a.moveToBookmark(b).select()}},UE.commands.splittorows={queryCommandState:function(){var a=e(this),b=a.cell;if(!b)return-1;var c=h(a.table);return c.selectedTds.length>0?-1:b&&b.rowSpan>1?0:-1},execCommand:function(){var a=this.selection.getRange(),b=a.createBookmark(!0),c=e(this).cell,d=h(c);d.splitToRows(c),a.moveToBookmark(b).select()}},UE.commands.splittocols={queryCommandState:function(){var a=e(this),b=a.cell;if(!b)return-1;var c=h(a.table);return c.selectedTds.length>0?-1:b&&b.colSpan>1?0:-1},execCommand:function(){var a=this.selection.getRange(),b=a.createBookmark(!0),c=e(this).cell,d=h(c);d.splitToCols(c),a.moveToBookmark(b).select()}},UE.commands.adaptbytext=UE.commands.adaptbywindow={queryCommandState:function(){return e(this).table?0:-1},execCommand:function(b){var c=e(this),d=c.table;if(d)if("adaptbywindow"==b)a(d,this);else{var f=domUtils.getElementsByTagName(d,"td th");utils.each(f,function(a){a.removeAttribute("width")}),d.removeAttribute("width")}}},UE.commands.averagedistributecol={queryCommandState:function(){var a=f(this);return a&&(a.isFullRow()||a.isFullCol())?0:-1},execCommand:function(a){function b(){var a,b=e.table,c=0,f=0,h=g(d,b);if(e.isFullRow())c=b.offsetWidth,f=e.colsNum;else for(var i,j=e.cellsRange.beginColIndex,k=e.cellsRange.endColIndex,l=j;l<=k;)i=e.selectedTds[l],c+=i.offsetWidth,l+=i.colSpan,f+=1;return a=Math.ceil(c/f)-2*h.tdBorder-2*h.tdPadding}function c(a){utils.each(domUtils.getElementsByTagName(e.table,"th"),function(a){a.setAttribute("width","")});var b=e.isFullRow()?domUtils.getElementsByTagName(e.table,"td"):e.selectedTds;utils.each(b,function(b){1==b.colSpan&&b.setAttribute("width",a)})}var d=this,e=f(d);e&&e.selectedTds.length&&c(b())}},UE.commands.averagedistributerow={queryCommandState:function(){var a=f(this);return a?a.selectedTds&&/th/gi.test(a.selectedTds[0].tagName)?-1:a.isFullRow()||a.isFullCol()?0:-1:-1},execCommand:function(a){function b(){var a,b,c=0,f=e.table,h=g(d,f),i=parseInt(domUtils.getComputedStyle(f.getElementsByTagName("td")[0],"padding-top"));if(e.isFullCol()){var j,k,l=domUtils.getElementsByTagName(f,"caption"),m=domUtils.getElementsByTagName(f,"th");l.length>0&&(j=l[0].offsetHeight),m.length>0&&(k=m[0].offsetHeight),c=f.offsetHeight-(j||0)-(k||0),b=0==m.length?e.rowsNum:e.rowsNum-1}else{for(var n=e.cellsRange.beginRowIndex,o=e.cellsRange.endRowIndex,p=0,q=domUtils.getElementsByTagName(f,"tr"),r=n;r<=o;r++)c+=q[r].offsetHeight,p+=1;b=p}return a=browser.ie&&browser.version<9?Math.ceil(c/b):Math.ceil(c/b)-2*h.tdBorder-2*i}function c(a){var b=e.isFullCol()?domUtils.getElementsByTagName(e.table,"td"):e.selectedTds;utils.each(b,function(b){1==b.rowSpan&&b.setAttribute("height",a)})}var d=this,e=f(d);e&&e.selectedTds.length&&c(b())}},UE.commands.cellalignment={queryCommandState:function(){return e(this).table?0:-1},execCommand:function(a,b){var c=this,d=f(c);if(d)utils.each(d.selectedTds,function(a){domUtils.setAttributes(a,b)});else{var e=c.selection.getStart(),g=e&&domUtils.findParentByTagName(e,["td","th","caption"],!0);/caption/gi.test(g.tagName)?(g.style.textAlign=b.align,g.style.verticalAlign=b.vAlign):domUtils.setAttributes(g,b),c.selection.getRange().setCursor(!0)}},queryCommandValue:function(a){var b=e(this).cell;if(b||(b=c(this)[0]),b){var d=UE.UETable.getUETable(b).selectedTds;return!d.length&&(d=b),UE.UETable.getTableCellAlignState(d)}return null}},UE.commands.tablealignment={queryCommandState:function(){return browser.ie&&browser.version<8?-1:e(this).table?0:-1},execCommand:function(a,b){var c=this,d=c.selection.getStart(),e=d&&domUtils.findParentByTagName(d,["table"],!0);e&&e.setAttribute("align",b)}},UE.commands.edittable={queryCommandState:function(){return e(this).table?0:-1},execCommand:function(a,b){var c=this.selection.getRange(),d=domUtils.findParentByTagName(c.startContainer,"table");if(d){var e=domUtils.getElementsByTagName(d,"td").concat(domUtils.getElementsByTagName(d,"th"),domUtils.getElementsByTagName(d,"caption"));utils.each(e,function(a){a.style.borderColor=b})}}},UE.commands.edittd={queryCommandState:function(){return e(this).table?0:-1},execCommand:function(a,b){var c=this,d=f(c);if(d)utils.each(d.selectedTds,function(a){a.style.backgroundColor=b});else{var e=c.selection.getStart(),g=e&&domUtils.findParentByTagName(e,["td","th","caption"],!0);g&&(g.style.backgroundColor=b)}}},UE.commands.settablebackground={queryCommandState:function(){return c(this).length>1?0:-1},execCommand:function(a,b){var d,e;d=c(this),e=h(d[0]),e.setBackground(d,b)}},UE.commands.cleartablebackground={queryCommandState:function(){var a=c(this);if(!a.length)return-1;for(var b,d=0;b=a[d++];)if(""!==b.style.backgroundColor)return 0;return-1},execCommand:function(){var a=c(this),b=h(a[0]);b.removeBackground(a)}},UE.commands.interlacetable=UE.commands.uninterlacetable={queryCommandState:function(a){var b=e(this).table;if(!b)return-1;var c=b.getAttribute("interlaced");return"interlacetable"==a?"enabled"===c?-1:0:c&&"disabled"!==c?0:-1},execCommand:function(a,b){var c=e(this).table;"interlacetable"==a?(c.setAttribute("interlaced","enabled"),this.fireEvent("interlacetable",c,b)):(c.setAttribute("interlaced","disabled"),this.fireEvent("uninterlacetable",c))}},UE.commands.setbordervisible={queryCommandState:function(a){var b=e(this).table;return b?0:-1},execCommand:function(){var a=e(this).table;utils.each(domUtils.getElementsByTagName(a,"td"),function(a){a.style.borderWidth="1px",a.style.borderStyle="solid"})}}}(),UE.plugins.table=function(){function a(a){}function b(a,b){c(a,"width",!0),c(a,"height",!0)}function c(a,b,c){a.style[b]&&(c&&a.setAttribute(b,parseInt(a.style[b],10)),a.style[b]="")}function d(a){if("TD"==a.tagName||"TH"==a.tagName)return a;var b;return(b=domUtils.findParentByTagName(a,"td",!0)||domUtils.findParentByTagName(a,"th",!0))?b:null}function e(a){var b=new RegExp(domUtils.fillChar,"g");if(a[browser.ie?"innerText":"textContent"].replace(/^\s*$/,"").replace(b,"").length>0)return 0;for(var c in dtd.$isNotEmpty)if(a.getElementsByTagName(c).length)return 0;return 1}function f(a){return a.pageX||a.pageY?{x:a.pageX,y:a.pageY}:{x:a.clientX+N.document.body.scrollLeft-N.document.body.clientLeft,y:a.clientY+N.document.body.scrollTop-N.document.body.clientTop}}function g(b){if(!A())try{var c,e=d(b.target||b.srcElement);if(R&&(N.body.style.webkitUserSelect="none",(Math.abs(V.x-b.clientX)>T||Math.abs(V.y-b.clientY)>T)&&(t(),R=!1,U=0,v(b))),ca&&ha)return U=0,N.body.style.webkitUserSelect="none",N.selection.getNative()[browser.ie9below?"empty":"removeAllRanges"](),c=f(b),m(N,!0,ca,c,e),void("h"==ca?ga.style.left=k(ha,b)+"px":"v"==ca&&(ga.style.top=l(ha,b)+"px"));if(e){if(N.fireEvent("excludetable",e)===!0)return;c=f(b);var g=n(e,c),i=domUtils.findParentByTagName(e,"table",!0);if(j(i,e,b,!0)){if(N.fireEvent("excludetable",i)===!0)return;N.body.style.cursor="url("+N.options.cursorpath+"h.png),pointer"}else if(j(i,e,b)){if(N.fireEvent("excludetable",i)===!0)return;N.body.style.cursor="url("+N.options.cursorpath+"v.png),pointer"}else{N.body.style.cursor="text";/\d/.test(g)&&(g=g.replace(/\d/,""),e=Y(e).getPreviewCell(e,"v"==g)),m(N,!!e&&!!g,e?g:"",c,e)}}else h(!1,i,N)}catch(o){a(o)}}function h(a,b,c){if(a)i(b,c);else{if(fa)return;la=setTimeout(function(){!fa&&ea&&ea.parentNode&&ea.parentNode.removeChild(ea)},2e3)}}function i(a,b){function c(c,d){clearTimeout(g),g=setTimeout(function(){b.fireEvent("tableClicked",a,d)},300)}function d(c){clearTimeout(g);var d=Y(a),e=a.rows[0].cells[0],f=d.getLastCell(),h=d.getCellsRange(e,f);b.selection.getRange().setStart(e,0).setCursor(!1,!0),d.setSelected(h)}var e=domUtils.getXY(a),f=a.ownerDocument;if(ea&&ea.parentNode)return ea;ea=f.createElement("div"),ea.contentEditable=!1,ea.innerHTML="",ea.style.cssText="width:15px;height:15px;background-image:url("+b.options.UEDITOR_HOME_URL+"dialogs/table/dragicon.png);position: absolute;cursor:move;top:"+(e.y-15)+"px;left:"+e.x+"px;",domUtils.unSelectable(ea),ea.onmouseover=function(a){fa=!0},ea.onmouseout=function(a){fa=!1},domUtils.on(ea,"click",function(a,b){c(b,this)}),domUtils.on(ea,"dblclick",function(a,b){d(b)}),domUtils.on(ea,"dragstart",function(a,b){domUtils.preventDefault(b)});var g;f.body.appendChild(ea)}function j(a,b,c,d){var e=f(c),g=n(b,e);if(d){var h=a.getElementsByTagName("caption")[0],i=h?h.offsetHeight:0;return"v1"==g&&e.y-domUtils.getXY(a).y-i<8}return"h1"==g&&e.x-domUtils.getXY(a).x<8}function k(a,b){var c=Y(a);if(c){var d=c.getSameEndPosCells(a,"x")[0],e=c.getSameStartPosXCells(a)[0],g=f(b).x,h=(d?domUtils.getXY(d).x:domUtils.getXY(c.table).x)+20,i=e?domUtils.getXY(e).x+e.offsetWidth-20:N.body.offsetWidth+5||parseInt(domUtils.getComputedStyle(N.body,"width"),10);return h+=Q,i-=Q,gi?i:g}}function l(b,c){try{var d=domUtils.getXY(b).y,e=f(c).y;return ek[c]?(a=!1,!1):void l.push(d)});var b=a?l:k;utils.each(i,function(a,c){a.width=b[c]-G()})},0)}}}}function q(a){if(_(domUtils.getElementsByTagName(N.body,"td th")),utils.each(N.document.getElementsByTagName("table"),function(a){a.ueTable=null}),aa=M(N,a)){var b=domUtils.findParentByTagName(aa,"table",!0);ut=Y(b),ut&&ut.clearSelected(),da?r(a):(N.document.body.style.webkitUserSelect="",ia=!0,N.addListener("mouseover",x))}}function r(a){browser.ie&&(a=u(a)),t(),R=!0,O=setTimeout(function(){v(a)},W)}function s(a,b){for(var c=[],d=null,e=0,f=a.length;e0&&U--},W),2===U))return U=0,void p(b);if(2!=b.button){var c=this,d=c.selection.getRange(),e=domUtils.findParentByTagName(d.startContainer,"table",!0),f=domUtils.findParentByTagName(d.endContainer,"table",!0);if((e||f)&&(e===f?(e=domUtils.findParentByTagName(d.startContainer,["td","th","caption"],!0),f=domUtils.findParentByTagName(d.endContainer,["td","th","caption"],!0),e!==f&&c.selection.clearRange()):c.selection.clearRange()),ia=!1,c.document.body.style.webkitUserSelect="",ca&&ha&&(c.selection.getNative()[browser.ie9below?"empty":"removeAllRanges"](),U=0,ga=c.document.getElementById("ue_tableDragLine"))){var g=domUtils.getXY(ha),h=domUtils.getXY(ga);switch(ca){case"h":z(ha,h.x-g.x);break;case"v":B(ha,h.y-g.y-ha.offsetHeight)}return ca="",ha=null,I(c),void c.fireEvent("saveScene")}if(aa){var i=Y(aa),j=i?i.selectedTds[0]:null;if(j)d=new dom.Range(c.document),domUtils.isEmptyBlock(j)?d.setStart(j,0).setCursor(!1,!0):d.selectNodeContents(j).shrinkBoundary().setCursor(!1,!0);else if(d=c.selection.getRange().shrinkBoundary(),!d.collapsed){var e=domUtils.findParentByTagName(d.startContainer,["td","th"],!0),f=domUtils.findParentByTagName(d.endContainer,["td","th"],!0);(e&&!f||!e&&f||e&&f&&e!==f)&&d.setCursor(!1,!0)}aa=null,c.removeListener("mouseover",x)}else{var k=domUtils.findParentByTagName(b.target||b.srcElement,"td",!0);if(k||(k=domUtils.findParentByTagName(b.target||b.srcElement,"th",!0)),k&&("TD"==k.tagName||"TH"==k.tagName)){if(c.fireEvent("excludetable",k)===!0)return;d=new dom.Range(c.document),d.setStart(k,0).setCursor(!1,!0)}}c._selectionChange(250,b)}}}function x(a,b){if(!A()){var c=this,d=b.target||b.srcElement;if(ba=domUtils.findParentByTagName(d,"td",!0)||domUtils.findParentByTagName(d,"th",!0),aa&&ba&&("TD"==aa.tagName&&"TD"==ba.tagName||"TH"==aa.tagName&&"TH"==ba.tagName)&&domUtils.findParentByTagName(aa,"table")==domUtils.findParentByTagName(ba,"table")){var e=Y(ba);if(aa!=ba){c.document.body.style.webkitUserSelect="none",c.selection.getNative()[browser.ie9below?"empty":"removeAllRanges"]();var f=e.getCellsRange(aa,ba);e.setSelected(f)}else c.document.body.style.webkitUserSelect="",e.clearSelected()}b.preventDefault?b.preventDefault():b.returnValue=!1}}function y(a,b,c){var d=parseInt(domUtils.getComputedStyle(a,"line-height"),10),e=c+b;b=ef?(c&&g.push({left:a}),!1):void 0})}),g}function D(a,b,c){if(a-=G(),a<0)return 0;a-=E(b);var d=a<0?"left":"right";return a=Math.abs(a),utils.each(c,function(b){var c=b[d];c&&(a=Math.min(a,E(c)-Q))}),a=a<0?0:a,"left"===d?-a:a}function E(a){var b=0,b=a.offsetWidth-G();a.nextSibling||(b-=F(a)),b=b<0?0:b;try{a.width=b}catch(c){}return b}function F(a){if(tab=domUtils.findParentByTagName(a,"table",!1),void 0===tab.offsetVal){var b=a.previousSibling;b?tab.offsetVal=a.offsetWidth-b.offsetWidth===X.borderWidth?X.borderWidth:0:tab.offsetVal=0}return tab.offsetVal}function G(){if(void 0===X.tabcellSpace){var a=N.document.createElement("table"),b=N.document.createElement("tbody"),c=N.document.createElement("tr"),d=N.document.createElement("td"),e=null;d.style.cssText="border: 0;",d.width=1,c.appendChild(d),c.appendChild(e=d.cloneNode(!1)),b.appendChild(c),a.appendChild(b),a.style.cssText="visibility: hidden;",N.body.appendChild(a),X.paddingSpace=d.offsetWidth-1;var f=a.offsetWidth;d.style.cssText="",e.style.cssText="",X.borderWidth=(a.offsetWidth-f)/3,X.tabcellSpace=X.paddingSpace+X.borderWidth,N.body.removeChild(a)}return G=function(){return X.tabcellSpace},X.tabcellSpace}function H(a,b){ia||(ga=a.document.createElement("div"),domUtils.setAttributes(ga,{id:"ue_tableDragLine",unselectable:"on",contenteditable:!1,onresizestart:"return false",ondragstart:"return false",onselectstart:"return false",style:"background-color:blue;position:absolute;padding:0;margin:0;background-image:none;border:0px none;opacity:0;filter:alpha(opacity=0)"}),a.body.appendChild(ga))}function I(a){if(!ia)for(var b;b=a.document.getElementById("ue_tableDragLine");)domUtils.remove(b)}function J(a,b){if(b){var c,d=domUtils.findParentByTagName(b,"table"),e=d.getElementsByTagName("caption"),f=d.offsetWidth,g=d.offsetHeight-(e.length>0?e[0].offsetHeight:0),h=domUtils.getXY(d),i=domUtils.getXY(b);switch(a){case"h":c="height:"+g+"px;top:"+(h.y+(e.length>0?e[0].offsetHeight:0))+"px;left:"+(i.x+b.offsetWidth),ga.style.cssText=c+"px;position: absolute;display:block;background-color:blue;width:1px;border:0; color:blue;opacity:.3;filter:alpha(opacity=30)";break;case"v":c="width:"+f+"px;left:"+h.x+"px;top:"+(i.y+b.offsetHeight),ga.style.cssText=c+"px;overflow:hidden;position: absolute;display:block;background-color:blue;height:1px;border:0;color:blue;opacity:.2;filter:alpha(opacity=20)"}}}function K(a,b){for(var c,d,e=domUtils.getElementsByTagName(a.body,"table"),f=0;d=e[f++];){var g=domUtils.getElementsByTagName(d,"td");g[0]&&(b?(c=g[0].style.borderColor.replace(/\s/g,""),/(#ffffff)|(rgb\(255,255,255\))/gi.test(c)&&domUtils.addClass(d,"noBorderTable")):domUtils.removeClasses(d,"noBorderTable"))}}function L(a,b,c){var d=a.body;return d.offsetWidth-(b?2*parseInt(domUtils.getComputedStyle(d,"margin-left"),10):0)-2*c.tableBorder-(a.options.offsetWidth||0)}function M(a,b){var c=domUtils.findParentByTagName(b.target||b.srcElement,["td","th"],!0),d=null;if(!c)return null;if(d=n(c,f(b)),!c)return null;if("h1"===d&&c.previousSibling){var e=domUtils.getXY(c),g=c.offsetWidth;Math.abs(e.x+g-b.clientX)>g/3&&(c=c.previousSibling)}else if("v1"===d&&c.parentNode.previousSibling){var e=domUtils.getXY(c),h=c.offsetHeight;Math.abs(e.y+h-b.clientY)>h/3&&(c=c.parentNode.previousSibling.firstChild)}return c&&a.fireEvent("excludetable",c)!==!0?c:null}var N=this,O=null,P=null,Q=5,R=!1,S=5,T=10,U=0,V=null,W=360,X=UE.UETable,Y=function(a){return X.getUETable(a)},Z=function(a){return X.getUETableBySelected(a)},$=function(a,b){return X.getDefaultValue(a,b)},_=function(a){return X.removeSelectedClass(a)};N.ready(function(){var a=this,b=a.selection.getText;a.selection.getText=function(){var c=Z(a);if(c){var d="";return utils.each(c.selectedTds,function(a){d+=a[browser.ie?"innerText":"textContent"]}),d}return b.call(a.selection)}});var aa=null,ba=null,ca="",da=!1,ea=null,fa=!1,ga=null,ha=null,ia=!1,ja=!0;N.setOpt({maxColNum:20,maxRowNum:100,defaultCols:5,defaultRows:5,tdvalign:"top",cursorpath:N.options.UEDITOR_HOME_URL+"themes/default/images/cursor_",tableDragable:!1,classList:["ue-table-interlace-color-single","ue-table-interlace-color-double"]}),N.getUETable=Y;var ka={deletetable:1,inserttable:1,cellvalign:1,insertcaption:1,deletecaption:1,inserttitle:1,deletetitle:1,mergeright:1,mergedown:1,mergecells:1,insertrow:1,insertrownext:1,deleterow:1,insertcol:1,insertcolnext:1,deletecol:1,splittocells:1,splittorows:1,splittocols:1,adaptbytext:1,adaptbywindow:1,adaptbycustomer:1,insertparagraph:1,insertparagraphbeforetable:1,averagedistributecol:1,averagedistributerow:1};N.ready(function(){utils.cssRule("table",".selectTdClass{background-color:#edf5fa !important}table.noBorderTable td,table.noBorderTable th,table.noBorderTable caption{border:1px dashed #ddd !important}table{margin-bottom:10px;border-collapse:collapse;display:table;}td,th{padding: 5px 10px;border: 1px solid #DDD;}caption{border:1px dashed #DDD;border-bottom:0;padding:3px;text-align:center;}th{border-top:1px solid #BBB;background-color:#F7F7F7;}table tr.firstRow th{border-top-width:2px;}.ue-table-interlace-color-single{ background-color: #fcfcfc; } .ue-table-interlace-color-double{ background-color: #f7faff; }td p{margin:0;padding:0;}",N.document);var a,c,f;N.addListener("keydown",function(b,d){var g=this,h=d.keyCode||d.which;if(8==h){var i=Z(g);i&&i.selectedTds.length&&(i.isFullCol()?g.execCommand("deletecol"):i.isFullRow()?g.execCommand("deleterow"):g.fireEvent("delcells"),domUtils.preventDefault(d));var j=domUtils.findParentByTagName(g.selection.getStart(),"caption",!0),k=g.selection.getRange();if(k.collapsed&&j&&e(j)){g.fireEvent("saveScene");var l=j.parentNode;domUtils.remove(j),l&&k.setStart(l.rows[0].cells[0],0).setCursor(!1,!0),g.fireEvent("saveScene")}}if(46==h&&(i=Z(g))){g.fireEvent("saveScene");for(var m,n=0;m=i.selectedTds[n++];)domUtils.fillNode(g.document,m);g.fireEvent("saveScene"),domUtils.preventDefault(d)}if(13==h){var o=g.selection.getRange(),j=domUtils.findParentByTagName(o.startContainer,"caption",!0);if(j){var l=domUtils.findParentByTagName(j,"table");return o.collapsed?j&&o.setStart(l.rows[0].cells[0],0).setCursor(!1,!0):(o.deleteContents(),g.fireEvent("saveScene")),void domUtils.preventDefault(d)}if(o.collapsed){var l=domUtils.findParentByTagName(o.startContainer,"table");if(l){var p=l.rows[0].cells[0],q=domUtils.findParentByTagName(g.selection.getStart(),["td","th"],!0),r=l.previousSibling;if(p===q&&(!r||1==r.nodeType&&"TABLE"==r.tagName)&&domUtils.isStartInblock(o)){var s=domUtils.findParent(g.selection.getStart(),function(a){return domUtils.isBlockElm(a)},!0);s&&(/t(h|d)/i.test(s.tagName)||s===q.firstChild)&&(g.execCommand("insertparagraphbeforetable"),domUtils.preventDefault(d))}}}}if((d.ctrlKey||d.metaKey)&&"67"==d.keyCode){a=null;var i=Z(g);if(i){var t=i.selectedTds;c=i.isFullCol(),f=i.isFullRow(),a=[[i.cloneCell(t[0],null,!0)]];for(var m,n=1;m=t[n];n++)m.parentNode!==t[n-1].parentNode?a.push([i.cloneCell(m,null,!0)]):a[a.length-1].push(i.cloneCell(m,null,!0))}}}),N.addListener("tablehasdeleted",function(){m(this,!1,"",null),ea&&domUtils.remove(ea)}),N.addListener("beforepaste",function(d,g){var h=this,i=h.selection.getRange();if(domUtils.findParentByTagName(i.startContainer,"caption",!0)){var j=h.document.createElement("div");return j.innerHTML=g.html,void(g.html=j[browser.ie9below?"innerText":"textContent"])}var k=Z(h);if(a){h.fireEvent("saveScene");var l,m,i=h.selection.getRange(),n=domUtils.findParentByTagName(i.startContainer,["td","th"],!0);if(n){var o=Y(n);if(f){var p=o.getCellInfo(n).rowIndex;"TH"==n.tagName&&p++;for(var q,r=0;q=a[r++];){for(var s,t=o.insertRow(p++,"td"),u=0;s=q[u];u++){var v=t.cells[u];v||(v=t.insertCell(u)),v.innerHTML=s.innerHTML,s.getAttribute("width")&&v.setAttribute("width",s.getAttribute("width")),s.getAttribute("vAlign")&&v.setAttribute("vAlign",s.getAttribute("vAlign")),s.getAttribute("align")&&v.setAttribute("align",s.getAttribute("align")),s.style.cssText&&(v.style.cssText=s.style.cssText)}for(var s,u=0;(s=t.cells[u])&&q[u];u++)s.innerHTML=q[u].innerHTML,q[u].getAttribute("width")&&s.setAttribute("width",q[u].getAttribute("width")),q[u].getAttribute("vAlign")&&s.setAttribute("vAlign",q[u].getAttribute("vAlign")),q[u].getAttribute("align")&&s.setAttribute("align",q[u].getAttribute("align")),q[u].style.cssText&&(s.style.cssText=q[u].style.cssText)}}else{if(c){y=o.getCellInfo(n);for(var s,w=0,u=0,q=a[0];s=q[u++];)w+=s.colSpan||1;for(h.__hasEnterExecCommand=!0,r=0;r1&&(x.rowSpan=1)}var z=$(h),A=h.body.offsetWidth-(ja?2*parseInt(domUtils.getComputedStyle(h.body,"margin-left"),10):0)-2*z.tableBorder-(h.options.offsetWidth||0);h.execCommand("insertHTML",""+k.innerHTML.replace(/>\s*<").replace(/\bth\b/gi,"td")+"
          ")}return h.fireEvent("contentchange"),h.fireEvent("saveScene"),g.html="",!0}var B,j=h.document.createElement("div");j.innerHTML=g.html,B=j.getElementsByTagName("table"),domUtils.findParentByTagName(h.selection.getStart(),"table")?(utils.each(B,function(a){domUtils.remove(a)}),domUtils.findParentByTagName(h.selection.getStart(),"caption",!0)&&(j.innerHTML=j[browser.ie?"innerText":"textContent"])):utils.each(B,function(a){b(a,!0),domUtils.removeAttributes(a,["style","border"]),utils.each(domUtils.getElementsByTagName(a,"td"),function(a){e(a)&&domUtils.fillNode(h.document,a),b(a,!0)})}),g.html=j.innerHTML}),N.addListener("afterpaste",function(){utils.each(domUtils.getElementsByTagName(N.body,"table"),function(a){if(a.offsetWidth>N.body.offsetWidth){var b=$(N,a);a.style.width=N.body.offsetWidth-(ja?2*parseInt(domUtils.getComputedStyle(N.body,"margin-left"),10):0)-2*b.tableBorder-(N.options.offsetWidth||0)+"px"}})}),N.addListener("blur",function(){a=null});var i;N.addListener("keydown",function(){clearTimeout(i),i=setTimeout(function(){var a=N.selection.getRange(),b=domUtils.findParentByTagName(a.startContainer,["th","td"],!0);if(b){var c=b.parentNode.parentNode.parentNode;c.offsetWidth>c.getAttribute("width")&&(b.style.wordBreak="break-all")}},100)}),N.addListener("selectionchange",function(){m(N,!1,"",null)}),N.addListener("contentchange",function(){var a=this;if(I(a),!Z(a)){var b=a.selection.getRange(),c=b.startContainer;c=domUtils.findParentByTagName(c,["td","th"],!0),utils.each(domUtils.getElementsByTagName(a.document,"table"),function(b){a.fireEvent("excludetable",b)!==!0&&(b.ueTable=new X(b),b.onmouseover=function(){a.fireEvent("tablemouseover",b)},b.onmousemove=function(){a.fireEvent("tablemousemove",b),a.options.tableDragable&&h(!0,this,a),utils.defer(function(){a.fireEvent("contentchange",50)},!0)},b.onmouseout=function(){a.fireEvent("tablemouseout",b),m(a,!1,"",null),I(a)},b.onclick=function(b){b=a.window.event||b;var c=d(b.target||b.srcElement);if(c){var e,f=Y(c),g=f.table,h=f.getCellInfo(c),i=a.selection.getRange();if(j(g,c,b,!0)){var k=f.getCell(f.indexTable[f.rowsNum-1][h.colIndex].rowIndex,f.indexTable[f.rowsNum-1][h.colIndex].cellIndex);return void(b.shiftKey&&f.selectedTds.length?f.selectedTds[0]!==k?(e=f.getCellsRange(f.selectedTds[0],k),f.setSelected(e)):i&&i.selectNodeContents(k).select():c!==k?(e=f.getCellsRange(c,k),f.setSelected(e)):i&&i.selectNodeContents(k).select())}if(j(g,c,b)){var l=f.getCell(f.indexTable[h.rowIndex][f.colsNum-1].rowIndex,f.indexTable[h.rowIndex][f.colsNum-1].cellIndex);b.shiftKey&&f.selectedTds.length?f.selectedTds[0]!==l?(e=f.getCellsRange(f.selectedTds[0],l),f.setSelected(e)):i&&i.selectNodeContents(l).select():c!==l?(e=f.getCellsRange(c,l),f.setSelected(e)):i&&i.selectNodeContents(l).select()}}})}),K(a,!0)}}),domUtils.on(N.document,"mousemove",g),domUtils.on(N.document,"mouseout",function(a){var b=a.target||a.srcElement;"TABLE"==b.tagName&&m(N,!1,"",null)}),N.addListener("interlacetable",function(a,b,c){if(b)for(var d=this,e=b.rows,f=e.length,g=function(a,b,c){return a[b]?a[b]:c?a[b%a.length]:""},h=0;h1?k:f.getCellInfo(d).rowIndex;var g=f.getTabNextCell(d,k);g?e(g)?a.setStart(g,0).setCursor(!1,!0):a.selectNodeContents(g).select():(N.fireEvent("saveScene"),N.__hasEnterExecCommand=!0,this.execCommand("insertrownext"),N.__hasEnterExecCommand=!1,a=this.selection.getRange(),a.setStart(c.rows[c.rows.length-1].cells[0],0).setCursor(),N.fireEvent("saveScene"))}return!0}}),browser.ie&&N.addListener("selectionchange",function(){m(this,!1,"",null)}),N.addListener("keydown",function(a,b){var c=this,d=b.keyCode||b.which;if(8!=d&&46!=d){var e=!(b.ctrlKey||b.metaKey||b.shiftKey||b.altKey);e&&_(domUtils.getElementsByTagName(c.body,"td"));var f=Z(c);f&&e&&f.clearSelected()}}),N.addListener("beforegetcontent",function(){K(this,!1),browser.ie&&utils.each(this.document.getElementsByTagName("caption"),function(a){domUtils.isEmptyNode(a)&&(a.innerHTML=" ")})}),N.addListener("aftergetcontent",function(){K(this,!0)}),N.addListener("getAllHtml",function(){_(N.document.getElementsByTagName("td"))}),N.addListener("fullscreenchanged",function(a,b){if(!b){var c=this.body.offsetWidth/document.body.offsetWidth,d=domUtils.getElementsByTagName(this.body,"table");utils.each(d,function(a){if(a.offsetWidth1||c[e].getAttribute("rowspan")>1)return-1;return b?"enablesort"==a^"sortEnabled"!=b.getAttribute("data-sort")?-1:0:-1},execCommand:function(a){var b=d(this).table;b.setAttribute("data-sort","enablesort"==a?"sortEnabled":"sortDisabled"),"enablesort"==a?domUtils.addClass(b,"sortEnabled"):domUtils.removeClasses(b,"sortEnabled")}}},UE.plugins.contextmenu=function(){var a=this;if(a.setOpt("enableContextMenu",!0),a.getOpt("enableContextMenu")!==!1){var b,c=a.getLang("contextMenu"),d=a.options.contextMenu||[{label:c.selectall,cmdName:"selectall"},{label:c.cleardoc,cmdName:"cleardoc",exec:function(){confirm(c.confirmclear)&&this.execCommand("cleardoc")}},"-",{label:c.unlink,cmdName:"unlink"},"-",{group:c.paragraph,icon:"justifyjustify",subMenu:[{label:c.justifyleft,cmdName:"justify",value:"left"},{label:c.justifyright,cmdName:"justify",value:"right"},{label:c.justifycenter,cmdName:"justify",value:"center"},{label:c.justifyjustify,cmdName:"justify",value:"justify"}]},"-",{group:c.table,icon:"table",subMenu:[{label:c.inserttable,cmdName:"inserttable"},{label:c.deletetable,cmdName:"deletetable"},"-",{label:c.deleterow,cmdName:"deleterow"},{label:c.deletecol,cmdName:"deletecol"},{label:c.insertcol,cmdName:"insertcol"},{label:c.insertcolnext,cmdName:"insertcolnext"},{label:c.insertrow,cmdName:"insertrow"},{label:c.insertrownext,cmdName:"insertrownext"},"-",{label:c.insertcaption,cmdName:"insertcaption"},{label:c.deletecaption,cmdName:"deletecaption"},{label:c.inserttitle,cmdName:"inserttitle"},{label:c.deletetitle,cmdName:"deletetitle"},{label:c.inserttitlecol,cmdName:"inserttitlecol"},{label:c.deletetitlecol,cmdName:"deletetitlecol"},"-",{label:c.mergecells,cmdName:"mergecells"},{label:c.mergeright,cmdName:"mergeright"},{label:c.mergedown,cmdName:"mergedown"},"-",{label:c.splittorows,cmdName:"splittorows"},{label:c.splittocols,cmdName:"splittocols"},{label:c.splittocells,cmdName:"splittocells"},"-",{label:c.averageDiseRow,cmdName:"averagedistributerow"},{label:c.averageDisCol,cmdName:"averagedistributecol"},"-",{label:c.edittd,cmdName:"edittd",exec:function(){UE.ui.edittd&&new UE.ui.edittd(this),this.getDialog("edittd").open()}},{label:c.edittable,cmdName:"edittable",exec:function(){UE.ui.edittable&&new UE.ui.edittable(this),this.getDialog("edittable").open()}},{label:c.setbordervisible,cmdName:"setbordervisible"}]},{group:c.tablesort,icon:"tablesort",subMenu:[{label:c.enablesort,cmdName:"enablesort"},{label:c.disablesort,cmdName:"disablesort"},"-",{label:c.reversecurrent,cmdName:"sorttable",value:"reversecurrent"},{label:c.orderbyasc,cmdName:"sorttable",value:"orderbyasc"},{label:c.reversebyasc,cmdName:"sorttable",value:"reversebyasc"},{label:c.orderbynum,cmdName:"sorttable",value:"orderbynum"},{label:c.reversebynum,cmdName:"sorttable",value:"reversebynum"}]},{group:c.borderbk,icon:"borderBack",subMenu:[{label:c.setcolor,cmdName:"interlacetable",exec:function(){this.execCommand("interlacetable")}},{label:c.unsetcolor,cmdName:"uninterlacetable",exec:function(){this.execCommand("uninterlacetable")}},{label:c.setbackground,cmdName:"settablebackground",exec:function(){this.execCommand("settablebackground",{repeat:!0,colorList:["#bbb","#ccc"]})}},{label:c.unsetbackground,cmdName:"cleartablebackground",exec:function(){this.execCommand("cleartablebackground")}},{label:c.redandblue,cmdName:"settablebackground",exec:function(){this.execCommand("settablebackground",{repeat:!0,colorList:["red","blue"]})}},{label:c.threecolorgradient,cmdName:"settablebackground",exec:function(){this.execCommand("settablebackground",{repeat:!0,colorList:["#aaa","#bbb","#ccc"]})}}]},{group:c.aligntd,icon:"aligntd",subMenu:[{cmdName:"cellalignment",value:{align:"left",vAlign:"top"}},{cmdName:"cellalignment",value:{align:"center",vAlign:"top"}},{cmdName:"cellalignment",value:{align:"right",vAlign:"top"}},{cmdName:"cellalignment",value:{align:"left",vAlign:"middle"}},{cmdName:"cellalignment",value:{align:"center",vAlign:"middle"}},{cmdName:"cellalignment",value:{align:"right",vAlign:"middle"}},{cmdName:"cellalignment",value:{align:"left",vAlign:"bottom"}},{cmdName:"cellalignment",value:{align:"center",vAlign:"bottom"}},{cmdName:"cellalignment",value:{align:"right",vAlign:"bottom"}}]},{group:c.aligntable,icon:"aligntable",subMenu:[{cmdName:"tablealignment",className:"left",label:c.tableleft,value:"left"},{cmdName:"tablealignment",className:"center",label:c.tablecenter,value:"center"},{cmdName:"tablealignment",className:"right",label:c.tableright,value:"right"}]},"-",{label:c.insertparagraphbefore,cmdName:"insertparagraph",value:!0},{label:c.insertparagraphafter,cmdName:"insertparagraph"},{label:c.copy,cmdName:"copy"},{label:c.paste,cmdName:"paste"}];if(d.length){var e=UE.ui.uiUtils;a.addListener("contextmenu",function(f,g){var h=e.getViewportOffsetByEvent(g);a.fireEvent("beforeselectionchange"),b&&b.destroy();for(var i,j=0,k=[];i=d[j];j++){var l;!function(b){function d(){switch(b.icon){case"table":return a.getLang("contextMenu.table");case"justifyjustify":return a.getLang("contextMenu.paragraph");case"aligntd":return a.getLang("contextMenu.aligntd");case"aligntable":return a.getLang("contextMenu.aligntable");case"tablesort":return c.tablesort;case"borderBack":return c.borderbk;default:return""}}if("-"==b)(l=k[k.length-1])&&"-"!==l&&k.push("-");else if(b.hasOwnProperty("group")){for(var e,f=0,g=[];e=b.subMenu[f];f++)!function(b){"-"==b?(l=g[g.length-1])&&"-"!==l?g.push("-"):g.splice(g.length-1):(a.commands[b.cmdName]||UE.commands[b.cmdName]||b.query)&&(b.query?b.query():a.queryCommandState(b.cmdName))>-1&&g.push({label:b.label||a.getLang("contextMenu."+b.cmdName+(b.value||""))||"",className:"edui-for-"+b.cmdName+(b.className?" edui-for-"+b.cmdName+"-"+b.className:""),onclick:b.exec?function(){b.exec.call(a)}:function(){a.execCommand(b.cmdName,b.value)}})}(e);g.length&&k.push({label:d(),className:"edui-for-"+b.icon,subMenu:{items:g,editor:a}})}else(a.commands[b.cmdName]||UE.commands[b.cmdName]||b.query)&&(b.query?b.query.call(a):a.queryCommandState(b.cmdName))>-1&&k.push({label:b.label||a.getLang("contextMenu."+b.cmdName),className:"edui-for-"+(b.icon?b.icon:b.cmdName+(b.value||"")),onclick:b.exec?function(){b.exec.call(a)}:function(){a.execCommand(b.cmdName,b.value)}})}(i)}if("-"==k[k.length-1]&&k.pop(),b=new UE.ui.Menu({items:k,className:"edui-contextmenu",editor:a}),b.render(),b.showAt(h),a.fireEvent("aftershowcontextmenu",b),domUtils.preventDefault(g),browser.ie){var m;try{m=a.selection.getNative().createRange()}catch(n){return}if(m.item){var o=new dom.Range(a.document);o.selectNode(m.item(0)).select(!0,!0)}}}),a.addListener("aftershowcontextmenu",function(b,c){if(a.zeroclipboard){var d=c.items;for(var e in d)"edui-for-copy"==d[e].className&&a.zeroclipboard.clip(d[e].getDom())}})}}},UE.plugins.shortcutmenu=function(){var a,b=this,c=b.options.shortcutMenu||[];c.length&&(b.addListener("contextmenu mouseup",function(b,d){var e=this,f={type:b,target:d.target||d.srcElement,screenX:d.screenX,screenY:d.screenY,clientX:d.clientX,clientY:d.clientY};if(setTimeout(function(){var d=e.selection.getRange();d.collapsed!==!1&&"contextmenu"!=b||(a||(a=new baidu.editor.ui.ShortCutMenu({editor:e,items:c,theme:e.options.theme,className:"edui-shortcutmenu"}),a.render(),e.fireEvent("afterrendershortcutmenu",a)),a.show(f,!!UE.plugins.contextmenu))}),"contextmenu"==b&&(domUtils.preventDefault(d),browser.ie9below)){var g;try{g=e.selection.getNative().createRange()}catch(d){return}if(g.item){var h=new dom.Range(e.document);h.selectNode(g.item(0)).select(!0,!0)}}}),b.addListener("keydown",function(b){"keydown"==b&&a&&!a.isHidden&&a.hide()}))},UE.plugins.basestyle=function(){var a={bold:["strong","b"],italic:["em","i"],subscript:["sub"],superscript:["sup"]},b=function(a,b){return domUtils.filterNodeList(a.selection.getStartElementPath(),b)},c=this;c.addshortcutkey({Bold:"ctrl+66",Italic:"ctrl+73",Underline:"ctrl+85"}),c.addInputRule(function(a){utils.each(a.getNodesByTagName("b i"),function(a){switch(a.tagName){case"b":a.tagName="strong";break;case"i":a.tagName="em"}})});for(var d in a)!function(a,d){c.commands[a]={execCommand:function(a){var e=c.selection.getRange(),f=b(this,d);if(e.collapsed){if(f){var g=c.document.createTextNode("");e.insertNode(g).removeInlineStyle(d),e.setStartBefore(g),domUtils.remove(g)}else{var h=e.document.createElement(d[0]);"superscript"!=a&&"subscript"!=a||(g=c.document.createTextNode(""),e.insertNode(g).removeInlineStyle(["sub","sup"]).setStartBefore(g).collapse(!0)),e.insertNode(h).setStart(h,0)}e.collapse(!0)}else"superscript"!=a&&"subscript"!=a||f&&f.tagName.toLowerCase()==a||e.removeInlineStyle(["sub","sup"]),f?e.removeInlineStyle(d):e.applyInlineStyle(d[0]);e.select()},queryCommandState:function(){return b(this,d)?1:0}}}(d,a[d])},UE.plugins.elementpath=function(){var a,b,c=this;c.setOpt("elementPathEnabled",!0),c.options.elementPathEnabled&&(c.commands.elementpath={execCommand:function(d,e){var f=b[e],g=c.selection.getRange();a=1*e,g.selectNode(f).select()},queryCommandValue:function(){var c=[].concat(this.selection.getStartElementPath()).reverse(),d=[];b=c;for(var e,f=0;e=c[f];f++)if(3!=e.nodeType){var g=e.tagName.toLowerCase();if("img"==g&&e.getAttribute("anchorname")&&(g="anchor"),d[f]=g,a==f){a=-1;break}}return d}})},UE.plugins.formatmatch=function(){function a(f,g){function h(a){return m&&a.selectNode(m),a.applyInlineStyle(d[d.length-1].tagName,null,d)}if(browser.webkit)var i="IMG"==g.target.tagName?g.target:null;c.undoManger&&c.undoManger.save();var j=c.selection.getRange(),k=i||j.getClosedNode();if(b&&k&&"IMG"==k.tagName)k.style.cssText+=";float:"+(b.style.cssFloat||b.style.styleFloat||"none")+";display:"+(b.style.display||"inline"),b=null;else if(!b){var l=j.collapsed;if(l){var m=c.document.createTextNode("match");j.insertNode(m).select()}c.__hasEnterExecCommand=!0;var n=c.options.removeFormatAttributes;c.options.removeFormatAttributes="",c.execCommand("removeformat"),c.options.removeFormatAttributes=n,c.__hasEnterExecCommand=!1,j=c.selection.getRange(),d.length&&h(j),m&&j.setStartBefore(m).collapse(!0),j.select(),m&&domUtils.remove(m)}c.undoManger&&c.undoManger.save(),c.removeListener("mouseup",a),e=0}var b,c=this,d=[],e=0;c.addListener("reset",function(){d=[],e=0}),c.commands.formatmatch={execCommand:function(f){if(e)return e=0,d=[],void c.removeListener("mouseup",a);var g=c.selection.getRange();if(b=g.getClosedNode(),!b||"IMG"!=b.tagName){g.collapse(!0).shrinkBoundary();var h=g.startContainer;d=domUtils.findParents(h,!0,function(a){return!domUtils.isBlockElm(a)&&1==a.nodeType});for(var i,j=0;i=d[j];j++)if("A"==i.tagName){d.splice(j,1);break}}c.addListener("mouseup",a),e=1},queryCommandState:function(){return e},notNeedUndo:1}},UE.plugin.register("searchreplace",function(){function a(a,b,c){var d=b.searchStr;b.dir==-1&&(a=a.split("").reverse().join(""),d=d.split("").reverse().join(""),c=a.length-c);for(var e,f=new RegExp(d,"g"+(b.casesensitive?"":"i"));e=f.exec(a);)if(e.index>=c)return b.dir==-1?a.length-e.index-b.searchStr.length:e.index;return-1}function b(b,c,d){var e,f,h=d.all||1==d.dir?"getNextDomNode":"getPreDomNode";domUtils.isBody(b)&&(b=b.firstChild);for(var i=1;b;){if(e=3==b.nodeType?b.nodeValue:b[browser.ie?"innerText":"textContent"],f=a(e,d,c),i=0,f!=-1)return{node:b,index:f};for(b=domUtils[h](b);b&&g[b.nodeName.toLowerCase()];)b=domUtils[h](b,!0);b&&(c=d.dir==-1?(3==b.nodeType?b.nodeValue:b[browser.ie?"innerText":"textContent"]).length:0)}}function c(a,b,d){for(var e,f=0,g=a.firstChild,h=0;g;){if(3==g.nodeType){if(h=g.nodeValue.replace(/(^[\t\r\n]+)|([\t\r\n]+$)/,"").length,f+=h,f>=b)return{node:g,index:h-(f-b)}}else if(!dtd.$empty[g.tagName]&&(h=g[browser.ie?"innerText":"textContent"].replace(/(^[\t\r\n]+)|([\t\r\n]+$)/,"").length,f+=h,f>=b&&(e=c(g,h-(f-b),d))))return e;g=domUtils.getNextDomNode(g)}}function d(a,d){var f,g=a.selection.getRange(),h=d.searchStr,i=a.document.createElement("span");if(i.innerHTML="$$ueditor_searchreplace_key$$",g.shrinkBoundary(!0),!g.collapsed){g.select();var j=a.selection.getText();if(new RegExp("^"+d.searchStr+"$",d.casesensitive?"":"i").test(j)){if(void 0!=d.replaceStr)return e(g,d.replaceStr),g.select(),!0;g.collapse(d.dir==-1)}}g.insertNode(i),g.enlargeToBlockElm(!0),f=g.startContainer;var k=f[browser.ie?"innerText":"textContent"].indexOf("$$ueditor_searchreplace_key$$");g.setStartBefore(i),domUtils.remove(i);var l=b(f,k,d);if(l){var m=c(l.node,l.index,h),n=c(l.node,l.index+h.length,h);return g.setStart(m.node,m.index).setEnd(n.node,n.index),void 0!==d.replaceStr&&e(g,d.replaceStr),g.select(),!0}g.setCursor()}function e(a,b){b=f.document.createTextNode(b),a.deleteContents().insertNode(b)}var f=this,g={table:1,tbody:1,tr:1,ol:1,ul:1};return{commands:{searchreplace:{execCommand:function(a,b){utils.extend(b,{all:!1,casesensitive:!1,dir:1},!0);var c=0;if(b.all){var e=f.selection.getRange(),g=f.body.firstChild;for(g&&1==g.nodeType?(e.setStart(g,0),e.shrinkBoundary(!0)):3==g.nodeType&&e.setStartBefore(g),e.collapse(!0).select(!0),void 0!==b.replaceStr&&f.fireEvent("saveScene");d(this,b);)c++;c&&f.fireEvent("saveScene")}else void 0!==b.replaceStr&&f.fireEvent("saveScene"),d(this,b)&&c++,c&&f.fireEvent("saveScene");return c},notNeedUndo:1}}}}),UE.plugins.customstyle=function(){var a=this;a.setOpt({customstyle:[{tag:"h1",name:"tc",style:"font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:center;margin:0 0 20px 0;"},{tag:"h1",name:"tl",style:"font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:left;margin:0 0 10px 0;"},{tag:"span",name:"im",style:"font-size:16px;font-style:italic;font-weight:bold;line-height:18px;"},{tag:"span",name:"hi",style:"font-size:16px;font-style:italic;font-weight:bold;color:rgb(51, 153, 204);line-height:18px;"}]}),a.commands.customstyle={execCommand:function(a,b){var c,d,e=this,f=b.tag,g=domUtils.findParent(e.selection.getStart(),function(a){return a.getAttribute("label")},!0),h={};for(var i in b)void 0!==b[i]&&(h[i]=b[i]);if(delete h.tag,g&&g.getAttribute("label")==b.label){if(c=this.selection.getRange(),d=c.createBookmark(),c.collapsed)if(dtd.$block[g.tagName]){var j=e.document.createElement("p");domUtils.moveChild(g,j),g.parentNode.insertBefore(j,g),domUtils.remove(g)}else domUtils.remove(g,!0);else{var k=domUtils.getCommonAncestor(d.start,d.end),l=domUtils.getElementsByTagName(k,f);new RegExp(f,"i").test(k.tagName)&&l.push(k);for(var m,n=0;m=l[n++];)if(m.getAttribute("label")==b.label){var o=domUtils.getPosition(m,d.start),p=domUtils.getPosition(m,d.end);if((o&domUtils.POSITION_FOLLOWING||o&domUtils.POSITION_CONTAINS)&&(p&domUtils.POSITION_PRECEDING||p&domUtils.POSITION_CONTAINS)&&dtd.$block[f]){var j=e.document.createElement("p");domUtils.moveChild(m,j),m.parentNode.insertBefore(j,m)}domUtils.remove(m,!0)}g=domUtils.findParent(k,function(a){return a.getAttribute("label")==b.label},!0),g&&domUtils.remove(g,!0)}c.moveToBookmark(d).select()}else if(dtd.$block[f]){if(this.execCommand("paragraph",f,h,"customstyle"),c=e.selection.getRange(),!c.collapsed){c.collapse(),g=domUtils.findParent(e.selection.getStart(),function(a){return a.getAttribute("label")==b.label},!0);var q=e.document.createElement("p");domUtils.insertAfter(g,q),domUtils.fillNode(e.document,q),c.setStart(q,0).setCursor()}}else{if(c=e.selection.getRange(),c.collapsed)return g=e.document.createElement(f),domUtils.setAttributes(g,h),void c.insertNode(g).setStart(g,0).setCursor();d=c.createBookmark(),c.applyInlineStyle(f,h).moveToBookmark(d).select()}},queryCommandValue:function(){var a=domUtils.filterNodeList(this.selection.getStartElementPath(),function(a){return a.getAttribute("label")});return a?a.getAttribute("label"):""}},a.addListener("keyup",function(b,c){var d=c.keyCode||c.which;if(32==d||13==d){var e=a.selection.getRange();if(e.collapsed){var f=domUtils.findParent(a.selection.getStart(),function(a){return a.getAttribute("label")},!0);if(f&&dtd.$block[f.tagName]&&domUtils.isEmptyNode(f)){var g=a.document.createElement("p");domUtils.insertAfter(f,g),domUtils.fillNode(a.document,g),domUtils.remove(f),e.setStart(g,0).setCursor()}}}})},UE.plugins.catchremoteimage=function(){var me=this,ajax=UE.ajax;me.options.catchRemoteImageEnable!==!1&&(me.setOpt({catchRemoteImageEnable:!1}),me.addListener("afterpaste",function(){me.fireEvent("catchRemoteImage")}),me.addListener("catchRemoteImage",function(){function catchremoteimage(a,b){var c=utils.serializeParam(me.queryCommandValue("serverparam"))||"",d=utils.formatUrl(catcherActionUrl+(catcherActionUrl.indexOf("?")==-1?"?":"&")+c),e=utils.isCrossDomainUrl(d),f={method:"POST",dataType:e?"jsonp":"",timeout:6e4,onsuccess:b.success,onerror:b.error};f[catcherFieldName]=a,ajax.request(d,f)}for(var catcherLocalDomain=me.getOpt("catcherLocalDomain"),catcherActionUrl=me.getActionUrl(me.getOpt("catcherActionName")),catcherUrlPrefix=me.getOpt("catcherUrlPrefix"),catcherFieldName=me.getOpt("catcherFieldName"),remoteImages=[],imgs=domUtils.getElementsByTagName(me.document,"img"),test=function(a,b){if(a.indexOf(location.host)!=-1||/(^\.)|(^\/)/.test(a))return!0;if(b)for(var c,d=0;c=b[d++];)if(a.indexOf(c)!==-1)return!0;return!1},i=0,ci;ci=imgs[i++];)if(!ci.getAttribute("word_img")){var src=ci.getAttribute("_src")||ci.src||"";/^(https?|ftp):/i.test(src)&&!test(src,catcherLocalDomain)&&remoteImages.push(src)}remoteImages.length&&catchremoteimage(remoteImages,{success:function(r){try{var info=void 0!==r.state?r:eval("("+r.responseText+")")}catch(e){return}var i,j,ci,cj,oldSrc,newSrc,list=info.list;for(i=0;ci=imgs[i++];)for(oldSrc=ci.getAttribute("_src")||ci.src||"",j=0;cj=list[j++];)if(oldSrc==cj.source&&"SUCCESS"==cj.state){newSrc=catcherUrlPrefix+cj.url,domUtils.setAttributes(ci,{src:newSrc,_src:newSrc});break}me.fireEvent("catchremotesuccess")},error:function(){me.fireEvent("catchremoteerror")}})}))},UE.plugin.register("snapscreen",function(){function getLocation(a){var b,c=document.createElement("a"),d=utils.serializeParam(me.queryCommandValue("serverparam"))||"";return c.href=a,browser.ie&&(c.href=c.href),b=c.search,d&&(b=b+(b.indexOf("?")==-1?"?":"&")+d,b=b.replace(/[&]+/gi,"&")),{port:c.port,hostname:c.hostname,path:c.pathname+b||+c.hash}}var me=this,snapplugin;return{commands:{snapscreen:{execCommand:function(cmd){function onSuccess(rs){try{if(rs=eval("("+rs+")"),"SUCCESS"==rs.state){var opt=me.options;me.execCommand("insertimage",{src:opt.snapscreenUrlPrefix+rs.url,_src:opt.snapscreenUrlPrefix+rs.url,alt:rs.title||"",floatStyle:opt.snapscreenImgAlign})}else alert(rs.state)}catch(e){alert(lang.callBackErrorMsg)}}var url,local,res,lang=me.getLang("snapScreen_plugin");if(!snapplugin){var container=me.container,doc=me.container.ownerDocument||me.container.document;snapplugin=doc.createElement("object");try{snapplugin.type="application/x-pluginbaidusnap"}catch(e){return}snapplugin.style.cssText="position:absolute;left:-9999px;width:0;height:0;",snapplugin.setAttribute("width","0"),snapplugin.setAttribute("height","0"),container.appendChild(snapplugin)}url=me.getActionUrl(me.getOpt("snapscreenActionName")),local=getLocation(url),setTimeout(function(){try{res=snapplugin.saveSnapshot(local.hostname,local.path,local.port)}catch(a){return void me.ui._dialogs.snapscreenDialog.open()}onSuccess(res)},50)},queryCommandState:function(){return navigator.userAgent.indexOf("Windows",0)!=-1?0:-1}}}}}),UE.commands.insertparagraph={execCommand:function(a,b){for(var c,d=this,e=d.selection.getRange(),f=e.startContainer;f&&!domUtils.isBody(f);)c=f,f=f.parentNode;if(c){var g=d.document.createElement("p");b?c.parentNode.insertBefore(g,c):c.parentNode.insertBefore(g,c.nextSibling),domUtils.fillNode(d.document,g),e.setStart(g,0).setCursor(!1,!0)}}},UE.plugin.register("webapp",function(){function a(a,c){return c?'':'"}var b=this;return{outputRule:function(b){utils.each(b.getNodesByTagName("img"),function(b){var c;if("edui-faked-webapp"==b.getAttr("class")){c=a({title:b.getAttr("title"),width:b.getAttr("width"),height:b.getAttr("height"),align:b.getAttr("align"),cssfloat:b.getStyle("float"),url:b.getAttr("_url"),logo:b.getAttr("_logo_url")},!0);var d=UE.uNode.createElement(c);b.parentNode.replaceChild(d,b)}})},inputRule:function(b){utils.each(b.getNodesByTagName("iframe"),function(b){if("edui-faked-webapp"==b.getAttr("class")){var c=UE.uNode.createElement(a({title:b.getAttr("title"),width:b.getAttr("width"),height:b.getAttr("height"),align:b.getAttr("align"),cssfloat:b.getStyle("float"),url:b.getAttr("src"),logo:b.getAttr("logo_url")}));b.parentNode.replaceChild(c,b)}})},commands:{webapp:{execCommand:function(b,c){var d=this,e=a(utils.extend(c,{align:"none"}),!1);d.execCommand("inserthtml",e)},queryCommandState:function(){var a=this,b=a.selection.getRange().getClosedNode(),c=b&&"edui-faked-webapp"==b.className;return c?1:0}}}}}),UE.plugins.template=function(){UE.commands.template={execCommand:function(a,b){b.html&&this.execCommand("inserthtml",b.html)}},this.addListener("click",function(a,b){var c=b.target||b.srcElement,d=this.selection.getRange(),e=domUtils.findParent(c,function(a){if(a.className&&domUtils.hasClass(a,"ue_t"))return a},!0);e&&d.selectNode(e).shrinkBoundary().select()}),this.addListener("keydown",function(a,b){var c=this.selection.getRange();if(!c.collapsed&&!(b.ctrlKey||b.metaKey||b.shiftKey||b.altKey)){var d=domUtils.findParent(c.startContainer,function(a){if(a.className&&domUtils.hasClass(a,"ue_t"))return a},!0);d&&domUtils.removeClasses(d,["ue_t"])}})},UE.plugin.register("music",function(){function a(a,c,d,e,f,g){return g?'':"'}var b=this;return{outputRule:function(b){utils.each(b.getNodesByTagName("img"),function(b){var c;if("edui-faked-music"==b.getAttr("class")){var d=b.getStyle("float"),e=b.getAttr("align");c=a(b.getAttr("_url"),b.getAttr("width"),b.getAttr("height"),e,d,!0);var f=UE.uNode.createElement(c);b.parentNode.replaceChild(f,b)}})},inputRule:function(b){utils.each(b.getNodesByTagName("embed"),function(b){if("edui-faked-music"==b.getAttr("class")){var c=b.getStyle("float"),d=b.getAttr("align");html=a(b.getAttr("src"),b.getAttr("width"),b.getAttr("height"),d,c,!1);var e=UE.uNode.createElement(html);b.parentNode.replaceChild(e,b)}})},commands:{music:{execCommand:function(b,c){var d=this,e=a(c.url,c.width||400,c.height||95,"none",!1);d.execCommand("inserthtml",e)},queryCommandState:function(){var a=this,b=a.selection.getRange().getClosedNode(),c=b&&"edui-faked-music"==b.className;return c?1:0}}}}}),UE.plugin.register("autoupload",function(){function a(a,b){var c,d,e,f,g,h,i,j,k=b,l=/image\/\w+/i.test(a.type)?"image":"file",m="loading_"+(+new Date).toString(36);if(c=k.getOpt(l+"FieldName"),d=k.getOpt(l+"UrlPrefix"),e=k.getOpt(l+"MaxSize"),f=k.getOpt(l+"AllowFiles"),g=k.getActionUrl(k.getOpt(l+"ActionName")),i=function(a){var b=k.document.getElementById(m);b&&domUtils.remove(b),k.fireEvent("showmessage",{id:m,content:a,type:"error",timeout:4e3})},"image"==l?(h='',j=function(a){var b=d+a.url,c=k.document.getElementById(m);c&&(c.setAttribute("src",b),c.setAttribute("_src",b),c.setAttribute("title",a.title||""),c.setAttribute("alt",a.original||""),c.removeAttribute("id"),domUtils.removeClasses(c,"loadingclass"))}):(h='

          ',j=function(a){var b=d+a.url,c=k.document.getElementById(m),e=k.selection.getRange(),f=e.createBookmark();e.selectNode(c).select(),k.execCommand("insertfile",{url:b}),e.moveToBookmark(f).select()}),k.execCommand("inserthtml",h),!k.getOpt(l+"ActionName"))return void i(k.getLang("autoupload.errorLoadConfig"));if(a.size>e)return void i(k.getLang("autoupload.exceedSizeError"));var n=a.name?a.name.substr(a.name.lastIndexOf(".")):"";if(n&&"image"!=l||f&&(f.join("")+".").indexOf(n.toLowerCase()+".")==-1)return void i(k.getLang("autoupload.exceedTypeError"));var o=new XMLHttpRequest,p=new FormData,q=utils.serializeParam(k.queryCommandValue("serverparam"))||"",r=utils.formatUrl(g+(g.indexOf("?")==-1?"?":"&")+q);p.append(c,a,a.name||"blob."+a.type.substr("image/".length)),p.append("type","ajax"),o.open("post",r,!0),o.setRequestHeader("X-Requested-With","XMLHttpRequest"),o.addEventListener("load",function(a){try{var b=new Function("return "+utils.trim(a.target.response))();"SUCCESS"==b.state&&b.url?j(b):i(b.state)}catch(c){i(k.getLang("autoupload.loadError"))}}),o.send(p)}function b(a){return a.clipboardData&&a.clipboardData.items&&1==a.clipboardData.items.length&&/^image\//.test(a.clipboardData.items[0].type)?a.clipboardData.items:null}function c(a){return a.dataTransfer&&a.dataTransfer.files?a.dataTransfer.files:null}return{outputRule:function(a){utils.each(a.getNodesByTagName("img"),function(a){/\b(loaderrorclass)|(bloaderrorclass)\b/.test(a.getAttr("class"))&&a.parentNode.removeChild(a)}),utils.each(a.getNodesByTagName("p"),function(a){/\bloadpara\b/.test(a.getAttr("class"))&&a.parentNode.removeChild(a)})},bindEvents:{ready:function(d){var e=this;window.FormData&&window.FileReader&&(domUtils.on(e.body,"paste drop",function(d){var f,g=!1;if(f="paste"==d.type?b(d):c(d)){for(var h,i=f.length;i--;)h=f[i],h.getAsFile&&(h=h.getAsFile()),h&&h.size>0&&(a(h,e),g=!0);g&&d.preventDefault()}}),domUtils.on(e.body,"dragover",function(a){"Files"==a.dataTransfer.types[0]&&a.preventDefault()}),utils.cssRule("loading",".loadingclass{display:inline-block;cursor:default;background: url('"+this.options.themePath+this.options.theme+"/images/loading.gif') no-repeat center center transparent;border:1px solid #cccccc;margin-left:1px;height: 22px;width: 22px;}\n.loaderrorclass{display:inline-block;cursor:default;background: url('"+this.options.themePath+this.options.theme+"/images/loaderror.png') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;}",this.document))}}}}),UE.plugin.register("autosave",function(){function a(a){var f;if(!(new Date-c0?b._saveFlag=window.setTimeout(function(){a(b)},b.options.saveInterval):a(b))}},commands:{clearlocaldata:{execCommand:function(a,c){e&&b.getPreferences(e)&&b.removePreferences(e)},notNeedUndo:!0,ignoreContentChange:!0},getlocaldata:{execCommand:function(a,c){return e?b.getPreferences(e)||"":""},notNeedUndo:!0,ignoreContentChange:!0},drafts:{execCommand:function(a,c){e&&(b.body.innerHTML=b.getPreferences(e)||"

          "+domUtils.fillHtml+"

          ",b.focus(!0))},queryCommandState:function(){return e?null===b.getPreferences(e)?-1:0:-1},notNeedUndo:!0,ignoreContentChange:!0}}}}),UE.plugin.register("charts",function(){function a(a){var b=null,c=0;if(a.rows.length<2)return!1;if(a.rows[0].cells.length<2)return!1;b=a.rows[0].cells,c=b.length;for(var d,e=0;d=b[e];e++)if("th"!==d.tagName.toLowerCase())return!1;for(var f,e=1;f=a.rows[e];e++){if(f.cells.length!=c)return!1;if("th"!==f.cells[0].tagName.toLowerCase())return!1;for(var d,g=1;d=f.cells[g];g++){var h=utils.trim(d.innerText||d.textContent||"");if(h=h.replace(new RegExp(UE.dom.domUtils.fillChar,"g"),"").replace(/^\s+|\s+$/g,""),!/^\d*\.?\d+$/.test(h))return!1}}return!0}var b=this;return{bindEvents:{chartserror:function(){}},commands:{charts:{execCommand:function(c,d){var e=domUtils.findParentByTagName(this.selection.getRange().startContainer,"table",!0),f=[],g={};if(!e)return!1;if(!a(e))return b.fireEvent("chartserror"),!1;g.title=d.title||"",g.subTitle=d.subTitle||"",g.xTitle=d.xTitle||"",g.yTitle=d.yTitle||"",g.suffix=d.suffix||"",g.tip=d.tip||"",g.dataFormat=d.tableDataFormat||"",g.chartType=d.chartType||0;for(var h in g)g.hasOwnProperty(h)&&f.push(h+":"+g[h]);e.setAttribute("data-chart",f.join(";")),domUtils.addClass(e,"edui-charts-table")},queryCommandState:function(b,c){ +var d=domUtils.findParentByTagName(this.selection.getRange().startContainer,"table",!0);return d&&a(d)?0:-1}}},inputRule:function(a){utils.each(a.getNodesByTagName("table"),function(a){void 0!==a.getAttr("data-chart")&&a.setAttr("style")})},outputRule:function(a){utils.each(a.getNodesByTagName("table"),function(a){void 0!==a.getAttr("data-chart")&&a.setAttr("style","display: none;")})}}}),UE.plugin.register("section",function(){function a(a){this.tag="",this.level=-1,this.dom=null,this.nextSection=null,this.previousSection=null,this.parentSection=null,this.startAddress=[],this.endAddress=[],this.children=[]}function b(b){var c=new a;return utils.extend(c,b)}function c(a,b){for(var c=b,d=0;d=0){var o=h.selection.getRange().selectNode(i).createAddress(!0).startAddress,p=b({tag:i.tagName,title:i.innerText||i.textContent||"",level:f,dom:i,startAddress:utils.clone(o,[]),endAddress:utils.clone(o,[]),children:[]});for(j.nextSection=p,p.previousSection=j,g=j;f<=g.level;)g=g.parentSection;p.parentSection=g,g.children.push(p),k=j=p}else 1===i.nodeType&&e(i,c),k&&k.endAddress[k.endAddress.length-1]++}for(var f=c||["h1","h2","h3","h4","h5","h6"],g=0;g=c.length);f++){if(c[f]>a[f]){d=!0;break}if(c[f]=c.length);f++){if(c[f]a[f])break}return d&&e}var g,h,i=this;if(b&&d&&d.level!=-1&&(g=e?d.endAddress:d.startAddress,h=c(g,i.body),g&&h&&!f(b.startAddress,b.endAddress,g))){var j,k,l=c(b.startAddress,i.body),m=c(b.endAddress,i.body);if(e)for(j=m;j&&!(domUtils.getPosition(l,j)&domUtils.POSITION_FOLLOWING)&&(k=j.previousSibling,domUtils.insertAfter(h,j),j!=l);)j=k;else for(j=l;j&&!(domUtils.getPosition(j,m)&domUtils.POSITION_FOLLOWING)&&(k=j.nextSibling,h.parentNode.insertBefore(j,h),j!=m);)j=k;i.fireEvent("updateSections")}}},deletesection:{execCommand:function(a,b,c){function d(a){for(var b=e.body,c=0;c',b.className="edui-"+c.options.theme,b.id=c.ui.id+"_iframeupload",i.style.cssText=g,i.style.width=a+"px",i.style.height=e+"px",i.appendChild(b),i.parentNode&&(i.parentNode.style.width=a+"px",i.parentNode.style.height=a+"px");var k=h.getElementById("edui_form_"+j),l=h.getElementById("edui_input_"+j),m=h.getElementById("edui_iframe_"+j);domUtils.on(l,"change",function(){function a(){try{var e,f,g,h=(m.contentDocument||m.contentWindow.document).body,i=h.innerText||h.textContent||"";f=new Function("return "+i)(),e=c.options.imageUrlPrefix+f.url,"SUCCESS"==f.state&&f.url?(g=c.document.getElementById(d),g.setAttribute("src",e),g.setAttribute("_src",e),g.setAttribute("title",f.title||""),g.setAttribute("alt",f.original||""),g.removeAttribute("id"),domUtils.removeClasses(g,"loadingclass")):b&&b(f.state)}catch(j){b&&b(c.getLang("simpleupload.loadError"))}k.reset(),domUtils.un(m,"load",a)}function b(a){if(d){var b=c.document.getElementById(d);b&&domUtils.remove(b),c.fireEvent("showmessage",{id:d,content:a,type:"error",timeout:4e3})}}if(l.value){var d="loading_"+(+new Date).toString(36),e=utils.serializeParam(c.queryCommandValue("serverparam"))||"",f=c.getActionUrl(c.getOpt("imageActionName")),g=c.getOpt("imageAllowFiles");if(c.focus(),c.execCommand("inserthtml",''),!c.getOpt("imageActionName"))return void errorHandler(c.getLang("autoupload.errorLoadConfig"));var h=l.value,i=h?h.substr(h.lastIndexOf(".")):"";if(!i||g&&(g.join("")+".").indexOf(i.toLowerCase()+".")==-1)return void b(c.getLang("simpleupload.exceedTypeError"));domUtils.on(m,"load",a),k.action=utils.formatUrl(f+(f.indexOf("?")==-1?"?":"&")+e),k.submit()}});var n;c.addListener("selectionchange",function(){clearTimeout(n),n=setTimeout(function(){var a=c.queryCommandState("simpleupload");a==-1?l.disabled="disabled":l.disabled=!1},400)}),d=!0}),f.style.cssText=g,b.appendChild(f)}var b,c=this,d=!1;return{bindEvents:{ready:function(){utils.cssRule("loading",".loadingclass{display:inline-block;cursor:default;background: url('"+this.options.themePath+this.options.theme+"/images/loading.gif') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;}\n.loaderrorclass{display:inline-block;cursor:default;background: url('"+this.options.themePath+this.options.theme+"/images/loaderror.png') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;}",this.document)},simpleuploadbtnready:function(d,e){b=e,c.afterConfigReady(a)}},outputRule:function(a){utils.each(a.getNodesByTagName("img"),function(a){/\b(loaderrorclass)|(bloaderrorclass)\b/.test(a.getAttr("class"))&&a.parentNode.removeChild(a)})},commands:{simpleupload:{queryCommandState:function(){return d?0:-1}}}}}),UE.plugin.register("serverparam",function(){var a={};return{commands:{serverparam:{execCommand:function(b,c,d){void 0===c||null===c?a={}:utils.isString(c)?void 0===d||null===d?delete a[c]:a[c]=d:utils.isObject(c)?utils.extend(a,c,!0):utils.isFunction(c)&&utils.extend(a,c(),!0)},queryCommandValue:function(){return a||{}}}}}}),UE.plugin.register("insertfile",function(){function a(a){var b=a.substr(a.lastIndexOf(".")+1).toLowerCase(),c={};return c[b]?c[b]:c.txt}var b=this;return{commands:{insertfile:{execCommand:function(c,d){d=utils.isArray(d)?d:[d];var e,f,g,h,i="",j=b.getOpt("UEDITOR_HOME_URL"),k=j+("/"==j.substr(j.length-1)?"":"/")+"dialogs/attachment/fileTypeImages/";for(e=0;e'+h+"

          ";b.execCommand("insertHtml",i)}}}}}),UE.plugins.xssFilter=function(){function a(a){var b=a.tagName,d=a.attrs;return c.hasOwnProperty(b)?void UE.utils.each(d,function(d,e){c[b].indexOf(e)===-1&&a.setAttr(e)}):(a.parentNode.removeChild(a),!1)}var b=UEDITOR_CONFIG,c=b.whitList;c&&b.xssFilterRules&&(this.options.filterRules=function(){var b={};return UE.utils.each(c,function(c,d){b[d]=function(b){return a(b)}}),b}());var d=[];UE.utils.each(c,function(a,b){d.push(b)}),c&&b.inputXssFilter&&this.addInputRule(function(b){b.traversal(function(b){return"element"===b.type&&void a(b)})}),c&&b.outputXssFilter&&this.addOutputRule(function(b){b.traversal(function(b){return"element"===b.type&&void a(b)})})};var baidu=baidu||{};baidu.editor=baidu.editor||{},UE.ui=baidu.editor.ui={},function(){function a(){var a=document.getElementById("edui_fixedlayer");i.setViewportOffset(a,{left:0,top:0})}function b(b){d.on(window,"scroll",a),d.on(window,"resize",baidu.editor.utils.defer(a,0,!0))}var c=baidu.editor.browser,d=baidu.editor.dom.domUtils,e="$EDITORUI",f=window[e]={},g="ID"+e,h=0,i=baidu.editor.ui.uiUtils={uid:function(a){return a?a[g]||(a[g]=++h):++h},hook:function(a,b){var c;return a&&a._callbacks?c=a:(c=function(){var b;a&&(b=a.apply(this,arguments));for(var d=c._callbacks,e=d.length;e--;){var f=d[e].apply(this,arguments);void 0===b&&(b=f)}return b},c._callbacks=[]),c._callbacks.push(b),c},createElementByHtml:function(a){var b=document.createElement("div");return b.innerHTML=a,b=b.firstChild,b.parentNode.removeChild(b),b},getViewportElement:function(){return c.ie&&c.quirks?document.body:document.documentElement},getClientRect:function(a){var b;try{b=a.getBoundingClientRect()}catch(c){b={left:0,top:0,height:0,width:0}}for(var e,f={left:Math.round(b.left),top:Math.round(b.top),height:Math.round(b.bottom-b.top),width:Math.round(b.right-b.left)};(e=a.ownerDocument)!==document&&(a=d.getWindow(e).frameElement);)b=a.getBoundingClientRect(),f.left+=b.left,f.top+=b.top;return f.bottom=f.top+f.height,f.right=f.left+f.width,f},getViewportRect:function(){var a=i.getViewportElement(),b=0|(window.innerWidth||a.clientWidth),c=0|(window.innerHeight||a.clientHeight);return{left:0,top:0,height:c,width:b,bottom:c,right:b}},setViewportOffset:function(a,b){var c=i.getFixedLayer();a.parentNode===c?(a.style.left=b.left+"px",a.style.top=b.top+"px"):d.setViewportOffset(a,b)},getEventOffset:function(a){var b=a.target||a.srcElement,c=i.getClientRect(b),d=i.getViewportOffsetByEvent(a);return{left:d.left-c.left,top:d.top-c.top}},getViewportOffsetByEvent:function(a){var b=a.target||a.srcElement,c=d.getWindow(b).frameElement,e={left:a.clientX,top:a.clientY};if(c&&b.ownerDocument!==document){var f=i.getClientRect(c);e.left+=f.left,e.top+=f.top}return e},setGlobal:function(a,b){return f[a]=b,e+'["'+a+'"]'},unsetGlobal:function(a){delete f[a]},copyAttributes:function(a,b){for(var e=b.attributes,f=e.length;f--;){var g=e[f];"style"==g.nodeName||"class"==g.nodeName||c.ie&&!g.specified||a.setAttribute(g.nodeName,g.nodeValue)}b.className&&d.addClass(a,b.className),b.style.cssText&&(a.style.cssText+=";"+b.style.cssText)},removeStyle:function(a,b){if(a.style.removeProperty)a.style.removeProperty(b);else{if(!a.style.removeAttribute)throw"";a.style.removeAttribute(b)}},contains:function(a,b){return a&&b&&a!==b&&(a.contains?a.contains(b):16&a.compareDocumentPosition(b))},startDrag:function(a,b,c){function d(a){var c=a.clientX-g,d=a.clientY-h;b.ondragmove(c,d,a),a.stopPropagation?a.stopPropagation():a.cancelBubble=!0}function e(a){c.removeEventListener("mousemove",d,!0),c.removeEventListener("mouseup",e,!0),window.removeEventListener("mouseup",e,!0),b.ondragstop()}function f(){i.releaseCapture(),i.detachEvent("onmousemove",d),i.detachEvent("onmouseup",f),i.detachEvent("onlosecaptrue",f),b.ondragstop()}var c=c||document,g=a.clientX,h=a.clientY;if(c.addEventListener)c.addEventListener("mousemove",d,!0),c.addEventListener("mouseup",e,!0),window.addEventListener("mouseup",e,!0),a.preventDefault();else{var i=a.srcElement;i.setCapture(),i.attachEvent("onmousemove",d),i.attachEvent("onmouseup",f),i.attachEvent("onlosecaptrue",f),a.returnValue=!1}b.ondragstart()},getFixedLayer:function(){var d=document.getElementById("edui_fixedlayer");return null==d&&(d=document.createElement("div"),d.id="edui_fixedlayer",document.body.appendChild(d),c.ie&&c.version<=8?(d.style.position="absolute",b(),setTimeout(a)):d.style.position="fixed",d.style.left="0",d.style.top="0",d.style.width="0",d.style.height="0"),d},makeUnselectable:function(a){if(c.opera||c.ie&&c.version<9){if(a.unselectable="on",a.hasChildNodes())for(var b=0;b'}},a.inherits(c,b)}(),function(){var a=baidu.editor.utils,b=baidu.editor.dom.domUtils,c=baidu.editor.ui.UIBase,d=baidu.editor.ui.uiUtils,e=baidu.editor.ui.Mask=function(a){this.initOptions(a),this.initUIBase()};e.prototype={getHtmlTpl:function(){return'
          '},postRender:function(){var a=this;b.on(window,"resize",function(){setTimeout(function(){a.isHidden()||a._fill()})})},show:function(a){this._fill(),this.getDom().style.display="",this.getDom().style.zIndex=a},hide:function(){this.getDom().style.display="none",this.getDom().style.zIndex=""},isHidden:function(){return"none"==this.getDom().style.display},_onMouseDown:function(){return!1},_onClick:function(a,b){this.fireEvent("click",a,b)},_fill:function(){var a=this.getDom(),b=d.getViewportRect();a.style.width=b.width+"px",a.style.height=b.height+"px"}},a.inherits(e,c)}(),function(){function a(a,b){for(var c=0;c
          '+this.getContentHtmlTpl()+"
          "},getContentHtmlTpl:function(){return this.content?"string"==typeof this.content?this.content:this.content.renderHtml():""},_UIBase_postRender:e.prototype.postRender,postRender:function(){if(this.content instanceof e&&this.content.postRender(),this.captureWheel&&!this.captured){this.captured=!0;var a=(document.documentElement.clientHeight||document.body.clientHeight)-80,b=this.getDom().offsetHeight,f=c.getClientRect(this.combox.getDom()).top,g=this.getDom("content"),h=this.getDom("body").getElementsByTagName("iframe"),i=this;for(h.length&&(h=h[0]);f+b>a;)b-=30;g.style.height=b+"px",h&&(h.style.height=b+"px"),window.XMLHttpRequest?d.on(g,"onmousewheel"in document.body?"mousewheel":"DOMMouseScroll",function(a){a.preventDefault?a.preventDefault():a.returnValue=!1,a.wheelDelta?g.scrollTop-=a.wheelDelta/120*60:g.scrollTop-=a.detail/-3*60}):d.on(this.getDom(),"mousewheel",function(a){a.returnValue=!1,i.getDom("content").scrollTop-=a.wheelDelta/120*60})}this.fireEvent("postRenderAfter"),this.hide(!0),this._UIBase_postRender()},_doAutoRender:function(){!this.getDom()&&this.autoRender&&this.render()},mesureSize:function(){var a=this.getDom("content");return c.getClientRect(a)},fitSize:function(){if(this.captureWheel&&this.sized)return this.__size;this.sized=!0;var a=this.getDom("body");a.style.width="",a.style.height="";var b=this.mesureSize();if(this.captureWheel){a.style.width=-(-20-b.width)+"px";var c=parseInt(this.getDom("content").style.height,10);!window.isNaN(c)&&(b.height=c)}else a.style.width=b.width+"px";return a.style.height=b.height+"px",this.__size=b,this.captureWheel&&(this.getDom("content").style.overflow="auto"),b},showAnchor:function(a,b){this.showAnchorRect(c.getClientRect(a),b)},showAnchorRect:function(a,b,e){this._doAutoRender();var f=c.getViewportRect();this.getDom().style.visibility="hidden",this._show();var g,i,j,k,l=this.fitSize();b?(g=this.canSideLeft&&a.right+l.width>f.right&&a.left>l.width,i=this.canSideUp&&a.top+l.height>f.bottom&&a.bottom>l.height,j=g?a.left-l.width:a.right,k=i?a.bottom-l.height:a.top):(g=this.canSideLeft&&a.right+l.width>f.right&&a.left>l.width,i=this.canSideUp&&a.top+l.height>f.bottom&&a.bottom>l.height,j=g?a.right-l.width:a.left,k=i?a.top-l.height:a.bottom);var m=this.getDom();c.setViewportOffset(m,{left:j,top:k}),d.removeClasses(m,h),m.className+=" "+h[2*(i?1:0)+(g?1:0)],this.editor&&(m.style.zIndex=1*this.editor.container.style.zIndex+10,baidu.editor.ui.uiUtils.getFixedLayer().style.zIndex=m.style.zIndex-1),this.getDom().style.visibility="visible"},showAt:function(a){var b=a.left,c=a.top,d={left:b,top:c,right:b,bottom:c,height:0,width:0};this.showAnchorRect(d,!1,!0)},_show:function(){if(this._hidden){var a=this.getDom();a.style.display="",this._hidden=!1,this.fireEvent("show")}},isHidden:function(){return this._hidden},show:function(){this._doAutoRender(),this._show()},hide:function(a){!this._hidden&&this.getDom()&&(this.getDom().style.display="none",this._hidden=!0,a||this.fireEvent("hide"))},queryAutoHide:function(a){return!a||!c.contains(this.getDom(),a)}},b.inherits(f,e),d.on(document,"mousedown",function(b){var c=b.target||b.srcElement;a(b,c)}),d.on(window,"scroll",function(b,c){a(b,c)})}(),function(){function a(a,b){for(var c='
          '+a+'
          ',d=0;d"+(60==d?'":"")+""),c+=d<70?'':"";return c+="
          '+b.getLang("themeColor")+'
          '+b.getLang("standardColor")+"
          =60?"border-width:1px;":d>=10&&d<20?"border-width:1px 1px 0 1px;":"border-width:0 1px 0 1px;")+'">
          "}var b=baidu.editor.utils,c=baidu.editor.ui.UIBase,d=baidu.editor.ui.ColorPicker=function(a){this.initOptions(a),this.noColorText=this.noColorText||this.editor.getLang("clearColor"),this.initUIBase()};d.prototype={getHtmlTpl:function(){return a(this.noColorText,this.editor)},_onTableClick:function(a){var b=a.target||a.srcElement,c=b.getAttribute("data-color");c&&this.fireEvent("pickcolor",c)},_onTableOver:function(a){var b=a.target||a.srcElement,c=b.getAttribute("data-color");c&&(this.getDom("preview").style.backgroundColor=c)},_onTableOut:function(){this.getDom("preview").style.backgroundColor=""},_onPickNoColor:function(){this.fireEvent("picknocolor")}},b.inherits(d,c);var e="ffffff,000000,eeece1,1f497d,4f81bd,c0504d,9bbb59,8064a2,4bacc6,f79646,f2f2f2,7f7f7f,ddd9c3,c6d9f0,dbe5f1,f2dcdb,ebf1dd,e5e0ec,dbeef3,fdeada,d8d8d8,595959,c4bd97,8db3e2,b8cce4,e5b9b7,d7e3bc,ccc1d9,b7dde8,fbd5b5,bfbfbf,3f3f3f,938953,548dd4,95b3d7,d99694,c3d69b,b2a2c7,92cddc,fac08f,a5a5a5,262626,494429,17365d,366092,953734,76923c,5f497a,31859b,e36c09,7f7f7f,0c0c0c,1d1b10,0f243e,244061,632423,4f6128,3f3151,205867,974806,c00000,ff0000,ffc000,ffff00,92d050,00b050,00b0f0,0070c0,002060,7030a0,".split(",")}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.uiUtils,c=baidu.editor.ui.UIBase,d=baidu.editor.ui.TablePicker=function(a){this.initOptions(a),this.initTablePicker()};d.prototype={defaultNumRows:10,defaultNumCols:10,maxNumRows:20,maxNumCols:20,numRows:10,numCols:10,lengthOfCellSide:22,initTablePicker:function(){this.initUIBase()},getHtmlTpl:function(){return'
          '},_UIBase_render:c.prototype.render,render:function(a){this._UIBase_render(a),this.getDom("label").innerHTML="0"+this.editor.getLang("t_row")+" x 0"+this.editor.getLang("t_col")},_track:function(a,b){var c=this.getDom("overlay").style,d=this.lengthOfCellSide;c.width=a*d+"px",c.height=b*d+"px";var e=this.getDom("label");e.innerHTML=a+this.editor.getLang("t_col")+" x "+b+this.editor.getLang("t_row"),this.numCols=a,this.numRows=b},_onMouseOver:function(a,c){var d=a.relatedTarget||a.fromElement;b.contains(c,d)||c===d||(this.getDom("label").innerHTML="0"+this.editor.getLang("t_col")+" x 0"+this.editor.getLang("t_row"),this.getDom("overlay").style.visibility="")},_onMouseOut:function(a,c){var d=a.relatedTarget||a.toElement;b.contains(c,d)||c===d||(this.getDom("label").innerHTML="0"+this.editor.getLang("t_col")+" x 0"+this.editor.getLang("t_row"),this.getDom("overlay").style.visibility="hidden")},_onMouseMove:function(a,c){var d=(this.getDom("overlay").style,b.getEventOffset(a)),e=this.lengthOfCellSide,f=Math.ceil(d.left/e),g=Math.ceil(d.top/e);this._track(f,g)},_onClick:function(){this.fireEvent("picktable",this.numCols,this.numRows)}},a.inherits(d,c)}(),function(){var a=baidu.editor.browser,b=baidu.editor.dom.domUtils,c=baidu.editor.ui.uiUtils,d='onmousedown="$$.Stateful_onMouseDown(event, this);" onmouseup="$$.Stateful_onMouseUp(event, this);"'+(a.ie?' onmouseenter="$$.Stateful_onMouseEnter(event, this);" onmouseleave="$$.Stateful_onMouseLeave(event, this);"':' onmouseover="$$.Stateful_onMouseOver(event, this);" onmouseout="$$.Stateful_onMouseOut(event, this);"');baidu.editor.ui.Stateful={alwalysHoverable:!1,target:null,Stateful_init:function(){this._Stateful_dGetHtmlTpl=this.getHtmlTpl,this.getHtmlTpl=this.Stateful_getHtmlTpl},Stateful_getHtmlTpl:function(){var a=this._Stateful_dGetHtmlTpl();return a.replace(/stateful/g,function(){return d})},Stateful_onMouseEnter:function(a,b){this.target=b,this.isDisabled()&&!this.alwalysHoverable||(this.addState("hover"),this.fireEvent("over"))},Stateful_onMouseLeave:function(a,b){this.isDisabled()&&!this.alwalysHoverable||(this.removeState("hover"),this.removeState("active"),this.fireEvent("out"))},Stateful_onMouseOver:function(a,b){var d=a.relatedTarget;c.contains(b,d)||b===d||this.Stateful_onMouseEnter(a,b)},Stateful_onMouseOut:function(a,b){var d=a.relatedTarget;c.contains(b,d)||b===d||this.Stateful_onMouseLeave(a,b)},Stateful_onMouseDown:function(a,b){this.isDisabled()||this.addState("active")},Stateful_onMouseUp:function(a,b){this.isDisabled()||this.removeState("active")},Stateful_postRender:function(){this.disabled&&!this.hasState("disabled")&&this.addState("disabled")},hasState:function(a){return b.hasClass(this.getStateDom(),"edui-state-"+a)},addState:function(a){this.hasState(a)||(this.getStateDom().className+=" edui-state-"+a)},removeState:function(a){this.hasState(a)&&b.removeClasses(this.getStateDom(),["edui-state-"+a])},getStateDom:function(){return this.getDom("state")},isChecked:function(){return this.hasState("checked")},setChecked:function(a){!this.isDisabled()&&a?this.addState("checked"):this.removeState("checked")},isDisabled:function(){return this.hasState("disabled")},setDisabled:function(a){a?(this.removeState("hover"),this.removeState("checked"),this.removeState("active"),this.addState("disabled")):this.removeState("disabled")}}}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.UIBase,c=baidu.editor.ui.Stateful,d=baidu.editor.ui.Button=function(a){if(a.name){var b=a.name,c=a.cssRules;a.className||(a.className="edui-for-"+b),a.cssRules=".edui-default .edui-for-"+b+" .edui-icon {"+c+"}"}this.initOptions(a),this.initButton()};d.prototype={uiName:"button",label:"",title:"",showIcon:!0,showText:!0,cssRules:"",initButton:function(){this.initUIBase(),this.Stateful_init(),this.cssRules&&a.cssRule("edui-customize-"+this.name+"-style",this.cssRules)},getHtmlTpl:function(){return'
          '+(this.showIcon?'
          ':"")+(this.showText?'
          '+this.label+"
          ":"")+"
          "},postRender:function(){this.Stateful_postRender(),this.setDisabled(this.disabled)},_onMouseDown:function(a){var b=a.target||a.srcElement,c=b&&b.tagName&&b.tagName.toLowerCase();if("input"==c||"object"==c||"object"==c)return!1},_onClick:function(){this.isDisabled()||this.fireEvent("click")},setTitle:function(a){var b=this.getDom("label");b.innerHTML=a}},a.inherits(d,b),a.extend(d.prototype,c)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.uiUtils,c=(baidu.editor.dom.domUtils,baidu.editor.ui.UIBase),d=baidu.editor.ui.Stateful,e=baidu.editor.ui.SplitButton=function(a){this.initOptions(a),this.initSplitButton()};e.prototype={popup:null,uiName:"splitbutton",title:"",initSplitButton:function(){this.initUIBase(),this.Stateful_init();if(null!=this.popup){var a=this.popup;this.popup=null,this.setPopup(a)}},_UIBase_postRender:c.prototype.postRender,postRender:function(){this.Stateful_postRender(),this._UIBase_postRender()},setPopup:function(c){this.popup!==c&&(null!=this.popup&&this.popup.dispose(),c.addListener("show",a.bind(this._onPopupShow,this)),c.addListener("hide",a.bind(this._onPopupHide,this)),c.addListener("postrender",a.bind(function(){c.getDom("body").appendChild(b.createElementByHtml('
          ')),c.getDom().className+=" "+this.className},this)),this.popup=c)},_onPopupShow:function(){this.addState("opened")},_onPopupHide:function(){this.removeState("opened")},getHtmlTpl:function(){return'
          '},showPopup:function(){var a=b.getClientRect(this.getDom());a.top-=this.popup.SHADOW_RADIUS,a.height+=this.popup.SHADOW_RADIUS,this.popup.showAnchorRect(a)},_onArrowClick:function(a,b){this.isDisabled()||this.showPopup()},_onButtonClick:function(){this.isDisabled()||this.fireEvent("buttonclick")}},a.inherits(e,c),a.extend(e.prototype,d,!0)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.uiUtils,c=baidu.editor.ui.ColorPicker,d=baidu.editor.ui.Popup,e=baidu.editor.ui.SplitButton,f=baidu.editor.ui.ColorButton=function(a){this.initOptions(a),this.initColorButton()};f.prototype={initColorButton:function(){var a=this;this.popup=new d({content:new c({noColorText:a.editor.getLang("clearColor"),editor:a.editor,onpickcolor:function(b,c){a._onPickColor(c)},onpicknocolor:function(b,c){a._onPickNoColor(c)}}),editor:a.editor}),this.initSplitButton()},_SplitButton_postRender:e.prototype.postRender,postRender:function(){this._SplitButton_postRender(),this.getDom("button_body").appendChild(b.createElementByHtml('
          ')),this.getDom().className+=" edui-colorbutton"; +},setColor:function(a){this.getDom("colorlump").style.backgroundColor=a,this.color=a},_onPickColor:function(a){this.fireEvent("pickcolor",a)!==!1&&(this.setColor(a),this.popup.hide())},_onPickNoColor:function(a){this.fireEvent("picknocolor")!==!1&&this.popup.hide()}},a.inherits(f,e)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.Popup,c=baidu.editor.ui.TablePicker,d=baidu.editor.ui.SplitButton,e=baidu.editor.ui.TableButton=function(a){this.initOptions(a),this.initTableButton()};e.prototype={initTableButton:function(){var a=this;this.popup=new b({content:new c({editor:a.editor,onpicktable:function(b,c,d){a._onPickTable(c,d)}}),editor:a.editor}),this.initSplitButton()},_onPickTable:function(a,b){this.fireEvent("picktable",a,b)!==!1&&this.popup.hide()}},a.inherits(e,d)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.UIBase,c=baidu.editor.ui.AutoTypeSetPicker=function(a){this.initOptions(a),this.initAutoTypeSetPicker()};c.prototype={initAutoTypeSetPicker:function(){this.initUIBase()},getHtmlTpl:function(){var a=this.editor,b=a.options.autotypeset,c=a.getLang("autoTypeSet"),d="textAlignValue"+a.uid,e="imageBlockLineValue"+a.uid,f="symbolConverValue"+a.uid;return'
          "+c.mergeLine+'"+c.delLine+'
          "+c.removeFormat+'"+c.indent+'
          "+c.alignment+'"+a.getLang("justifyleft")+'"+a.getLang("justifycenter")+'"+a.getLang("justifyright")+'
          "+c.imageFloat+'"+a.getLang("default")+'"+a.getLang("justifyleft")+'"+a.getLang("justifycenter")+'"+a.getLang("justifyright")+'
          "+c.removeFontsize+'"+c.removeFontFamily+'
          "+c.removeHtml+'
          "+c.pasteFilter+'
          "+c.symbol+'"+c.bdc2sb+'"+c.tobdc+'
          "},_UIBase_render:b.prototype.render},a.inherits(c,b)}(),function(){function a(a){for(var c,d={},e=a.getDom(),f=a.editor.uid,g=null,h=null,i=domUtils.getElementsByTagName(e,"input"),j=i.length-1;c=i[j--];)if(g=c.getAttribute("type"),"checkbox"==g)if(h=c.getAttribute("name"),d[h]&&delete d[h],c.checked){var k=document.getElementById(h+"Value"+f);if(k){if(/input/gi.test(k.tagName))d[h]=k.value;else for(var l,m=k.getElementsByTagName("input"),n=m.length-1;l=m[n--];)if(l.checked){d[h]=l.value;break}}else d[h]=!0}else d[h]=!1;else d[c.getAttribute("value")]=c.checked;for(var o,p=domUtils.getElementsByTagName(e,"select"),j=0;o=p[j++];){var q=o.getAttribute("name");d[q]=d[q]?o.value:""}b.extend(a.editor.options.autotypeset,d),a.editor.setPreferences("autotypeset",d)}var b=baidu.editor.utils,c=baidu.editor.ui.Popup,d=baidu.editor.ui.AutoTypeSetPicker,e=baidu.editor.ui.SplitButton,f=baidu.editor.ui.AutoTypeSetButton=function(a){this.initOptions(a),this.initAutoTypeSetButton()};f.prototype={initAutoTypeSetButton:function(){var b=this;this.popup=new c({content:new d({editor:b.editor}),editor:b.editor,hide:function(){!this._hidden&&this.getDom()&&(a(this),this.getDom().style.display="none",this._hidden=!0,this.fireEvent("hide"))}});var e=0;this.popup.addListener("postRenderAfter",function(){var c=this;if(!e){var d=this.getDom(),f=d.getElementsByTagName("button")[0];f.onclick=function(){a(c),b.editor.execCommand("autotypeset"),c.hide()},domUtils.on(d,"click",function(d){var e=d.target||d.srcElement,f=b.editor.uid;if(e&&"INPUT"==e.tagName){if("imageBlockLine"==e.name||"textAlign"==e.name||"symbolConver"==e.name)for(var g=e.checked,h=document.getElementById(e.name+"Value"+f),i=h.getElementsByTagName("input"),j={imageBlockLine:"none",textAlign:"left",symbolConver:"tobdc"},k=0;k"),e.push('
          '),2===d&&e.push("");return'
          '+e.join("")+"
          "},getStateDom:function(){return this.target},_onClick:function(a){var c=a.target||a.srcElement;/icon/.test(c.className)&&(this.items[c.parentNode.getAttribute("index")].onclick(),b.postHide(a))},_UIBase_render:d.prototype.render},a.inherits(e,d),a.extend(e.prototype,c,!0)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.Stateful,c=baidu.editor.ui.uiUtils,d=baidu.editor.ui.UIBase,e=baidu.editor.ui.PastePicker=function(a){this.initOptions(a),this.initPastePicker()};e.prototype={initPastePicker:function(){this.initUIBase(),this.Stateful_init()},getHtmlTpl:function(){return'
          '+this.editor.getLang("pasteOpt")+'
          '},getStateDom:function(){return this.target},format:function(a){this.editor.ui._isTransfer=!0,this.editor.fireEvent("pasteTransfer",a)},_onClick:function(a){var b=domUtils.getNextDomNode(a),d=c.getViewportRect().height,e=c.getClientRect(b);e.top+e.height>d?b.style.top=-e.height-a.offsetHeight+"px":b.style.top="",/hidden/gi.test(domUtils.getComputedStyle(b,"visibility"))?(b.style.visibility="visible",domUtils.addClass(a,"edui-state-opened")):(b.style.visibility="hidden",domUtils.removeClasses(a,"edui-state-opened"))},_UIBase_render:d.prototype.render},a.inherits(e,d),a.extend(e.prototype,b,!0)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.uiUtils,c=baidu.editor.ui.UIBase,d=baidu.editor.ui.Toolbar=function(a){this.initOptions(a),this.initToolbar()};d.prototype={items:null,initToolbar:function(){this.items=this.items||[],this.initUIBase()},add:function(a,b){void 0===b?this.items.push(a):this.items.splice(b,0,a)},getHtmlTpl:function(){for(var a=[],b=0;b'+a.join("")+""},postRender:function(){for(var a=this.getDom(),c=0;c
          '},postRender:function(){},queryAutoHide:function(){return!0}};h.prototype={items:null,uiName:"menu",initMenu:function(){this.items=this.items||[],this.initPopup(),this.initItems()},initItems:function(){for(var a=0;a'+a.join("")+""},_Popup_postRender:e.prototype.postRender,postRender:function(){for(var a=this,d=0;d
          '+this.renderLabelHtml()+"
          "},postRender:function(){var a=this;this.addListener("over",function(){a.ownerMenu.fireEvent("submenuover",a),a.subMenu&&a.delayShowSubMenu()}),this.subMenu&&(this.getDom().className+=" edui-hassubmenu",this.subMenu.render(),this.addListener("out",function(){a.delayHideSubMenu()}),this.subMenu.addListener("over",function(){clearTimeout(a._closingTimer),a._closingTimer=null,a.addState("opened")}),this.ownerMenu.addListener("hide",function(){a.hideSubMenu()}),this.ownerMenu.addListener("submenuover",function(b,c){c!==a&&a.delayHideSubMenu()}),this.subMenu._bakQueryAutoHide=this.subMenu.queryAutoHide,this.subMenu.queryAutoHide=function(b){return(!b||!c.contains(a.getDom(),b))&&this._bakQueryAutoHide(b)}),this.getDom().style.tabIndex="-1",c.makeUnselectable(this.getDom()),this.Stateful_postRender()},delayShowSubMenu:function(){var a=this;a.isDisabled()||(a.addState("opened"),clearTimeout(a._showingTimer),clearTimeout(a._closingTimer),a._closingTimer=null,a._showingTimer=setTimeout(function(){a.showSubMenu()},250))},delayHideSubMenu:function(){var a=this;a.isDisabled()||(a.removeState("opened"),clearTimeout(a._showingTimer),a._closingTimer||(a._closingTimer=setTimeout(function(){a.hasState("opened")||a.hideSubMenu(),a._closingTimer=null},400)))},renderLabelHtml:function(){return'
          '+(this.label||"")+"
          "},getStateDom:function(){return this.getDom()},queryAutoHide:function(a){if(this.subMenu&&this.hasState("opened"))return this.subMenu.queryAutoHide(a)},_onClick:function(a,b){this.hasState("disabled")||this.fireEvent("click",a,b)!==!1&&(this.subMenu?this.showSubMenu():e.postHide(a))},showSubMenu:function(){var a=c.getClientRect(this.getDom());a.right-=5,a.left+=2,a.width-=7,a.top-=4,a.bottom+=4,a.height+=8,this.subMenu.showAnchorRect(a,!0,!0)},hideSubMenu:function(){this.subMenu.hide()}},a.inherits(j,d),a.extend(j.prototype,f,!0)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.uiUtils,c=baidu.editor.ui.Menu,d=baidu.editor.ui.SplitButton,e=baidu.editor.ui.Combox=function(a){this.initOptions(a),this.initCombox()};e.prototype={uiName:"combox",onbuttonclick:function(){this.showPopup()},initCombox:function(){var a=this;this.items=this.items||[];for(var b=0;bd.right&&(g=d.right-e.width);var h=a.top;h+e.height>d.bottom&&(h=d.bottom-e.height),c.style.left=Math.max(g,0)+"px",c.style.top=Math.max(h,0)+"px"},showAtCenter:function(){var a=f.getViewportRect();if(this.fullscreen){var b=this.getDom(),c=this.getDom("content");b.style.display="block";var d=UE.ui.uiUtils.getClientRect(b),g=UE.ui.uiUtils.getClientRect(c);b.style.left="-100000px",c.style.width=a.width-d.width+g.width+"px",c.style.height=a.height-d.height+g.height+"px",b.style.width=a.width+"px",b.style.height=a.height+"px",b.style.left=0,this._originalContext={html:{overflowX:document.documentElement.style.overflowX,overflowY:document.documentElement.style.overflowY},body:{overflowX:document.body.style.overflowX,overflowY:document.body.style.overflowY}},document.documentElement.style.overflowX="hidden",document.documentElement.style.overflowY="hidden",document.body.style.overflowX="hidden",document.body.style.overflowY="hidden"}else{this.getDom().style.display="";var h=this.fitSize(),i=0|this.getDom("titlebar").offsetHeight,j=a.width/2-h.width/2,k=a.height/2-(h.height-i)/2-i,l=this.getDom();this.safeSetOffset({left:Math.max(0|j,0),top:Math.max(0|k,0)}),e.hasClass(l,"edui-state-centered")||(l.className+=" edui-state-centered")}this._show()},getContentHtml:function(){var a="";return"string"==typeof this.content?a=this.content:this.iframeUrl&&(a=''),a},getHtmlTpl:function(){var a="";if(this.buttons){for(var b=[],c=0;c
          '+b.join("")+"
          "}return'
          '+(this.title||"")+"
          "+this.closeButton.renderHtml()+'
          '+(this.autoReset?"":this.getContentHtml())+"
          "+a+"
          "},postRender:function(){this.modalMask.getDom()||(this.modalMask.render(),this.modalMask.hide()),this.dragMask.getDom()||(this.dragMask.render(),this.dragMask.hide());var a=this;if(this.addListener("show",function(){a.modalMask.show(this.getDom().style.zIndex-2)}),this.addListener("hide",function(){a.modalMask.hide()}),this.buttons)for(var b=0;b',a.editor.container.style.zIndex&&(this.getDom().style.zIndex=1*a.editor.container.style.zIndex+1))}}),this.onbuttonclick=function(){this.showPopup()},this.initSplitButton()}},a.inherits(d,c)}(),function(){function a(a){var b=a.target||a.srcElement,c=g.findParent(b,function(a){return g.hasClass(a,"edui-shortcutmenu")||g.hasClass(a,"edui-popup")},!0);if(!c)for(var d,e=0;d=h[e++];)d.hide()}var b,c=baidu.editor.ui,d=c.UIBase,e=c.uiUtils,f=baidu.editor.utils,g=baidu.editor.dom.domUtils,h=[],i=!1,j=c.ShortCutMenu=function(a){this.initOptions(a),this.initShortCutMenu()};j.postHide=a,j.prototype={isHidden:!0,SPACE:5,initShortCutMenu:function(){this.items=this.items||[],this.initUIBase(),this.initItems(),this.initEvent(),h.push(this)},initEvent:function(){var a=this,c=a.editor.document;g.on(c,"mousemove",function(c){if(a.isHidden===!1){if(a.getSubMenuMark()||"contextmenu"==a.eventType)return;var d=!0,e=a.getDom(),f=e.offsetWidth,g=e.offsetHeight,h=f/2+a.SPACE,i=g/2,j=Math.abs(c.screenX-a.left),k=Math.abs(c.screenY-a.top);clearTimeout(b),b=setTimeout(function(){k>0&&ki&&ki+70&&k0&&jh&&jh+70&&j'+a+""}},f.inherits(j,d),g.on(document,"mousedown",function(b){a(b)}),g.on(window,"scroll",function(b){a(b)})}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui.UIBase,c=baidu.editor.ui.Breakline=function(a){this.initOptions(a),this.initSeparator()};c.prototype={uiName:"Breakline",initSeparator:function(){this.initUIBase()},getHtmlTpl:function(){return"
          "}},a.inherits(c,b)}(),function(){var a=baidu.editor.utils,b=baidu.editor.dom.domUtils,c=baidu.editor.ui.UIBase,d=baidu.editor.ui.Message=function(a){this.initOptions(a),this.initMessage()};d.prototype={initMessage:function(){this.initUIBase()},getHtmlTpl:function(){return'
          ×
          '},reset:function(a){var b=this;a.keepshow||(clearTimeout(this.timer),b.timer=setTimeout(function(){b.hide()},a.timeout||4e3)),void 0!==a.content&&b.setContent(a.content),void 0!==a.type&&b.setType(a.type),b.show()},postRender:function(){var a=this,c=this.getDom("closer");c&&b.on(c,"click",function(){a.hide()})},setContent:function(a){this.getDom("content").innerHTML=a},setType:function(a){a=a||"info";var b=this.getDom("body");b.className=b.className.replace(/edui-message-type-[\w-]+/,"edui-message-type-"+a)},getContent:function(){return this.getDom("content").innerHTML},getType:function(){var a=this.getDom("body").match(/edui-message-type-([\w-]+)/);return a?a[1]:""},show:function(){this.getDom().style.display="block"},hide:function(){var a=this.getDom();a&&(a.style.display="none",a.parentNode&&a.parentNode.removeChild(a))}},a.inherits(d,c)}(),function(){var a=baidu.editor.utils,b=baidu.editor.ui,c=b.Dialog;b.buttons={},b.Dialog=function(a){var b=new c(a);return b.addListener("hide",function(){if(b.editor){var a=b.editor;try{if(browser.gecko){var c=a.window.scrollY,d=a.window.scrollX;a.body.focus(),a.window.scrollTo(d,c)}else a.focus()}catch(e){}}}),b};for(var d,e={anchor:"~/dialogs/anchor/anchor.html",insertimage:"~/dialogs/image/image.html",link:"~/dialogs/link/link.html",spechars:"~/dialogs/spechars/spechars.html",searchreplace:"~/dialogs/searchreplace/searchreplace.html",map:"~/dialogs/map/map.html",gmap:"~/dialogs/gmap/gmap.html",insertvideo:"~/dialogs/video/video.html",help:"~/dialogs/help/help.html",preview:"~/dialogs/preview/preview.html",emotion:"~/dialogs/emotion/emotion.html",wordimage:"~/dialogs/wordimage/wordimage.html",attachment:"~/dialogs/attachment/attachment.html",insertframe:"~/dialogs/insertframe/insertframe.html",edittip:"~/dialogs/table/edittip.html",edittable:"~/dialogs/table/edittable.html",edittd:"~/dialogs/table/edittd.html",webapp:"~/dialogs/webapp/webapp.html",snapscreen:"~/dialogs/snapscreen/snapscreen.html",scrawl:"~/dialogs/scrawl/scrawl.html",music:"~/dialogs/music/music.html",template:"~/dialogs/template/template.html",background:"~/dialogs/background/background.html",charts:"~/dialogs/charts/charts.html"},f=["undo","redo","formatmatch","bold","italic","underline","fontborder","touppercase","tolowercase","strikethrough","subscript","superscript","source","indent","outdent","blockquote","pasteplain","pagebreak","selectall","print","horizontal","removeformat","time","date","unlink","insertparagraphbeforetable","insertrow","insertcol","mergeright","mergedown","deleterow","deletecol","splittorows","splittocols","splittocells","mergecells","deletetable","drafts"],g=0;d=f[g++];)d=d.toLowerCase(),b[d]=function(a){return function(c){var d=new b.Button({className:"edui-for-"+a,title:c.options.labelMap[a]||c.getLang("labelMap."+a)||"",onclick:function(){c.execCommand(a)},theme:c.options.theme,showText:!1});return b.buttons[a]=d,c.addListener("selectionchange",function(b,e,f){var g=c.queryCommandState(a);g==-1?(d.setDisabled(!0),d.setChecked(!1)):f||(d.setDisabled(!1),d.setChecked(g))}),d}}(d);b.cleardoc=function(a){var c=new b.Button({className:"edui-for-cleardoc",title:a.options.labelMap.cleardoc||a.getLang("labelMap.cleardoc")||"",theme:a.options.theme,onclick:function(){confirm(a.getLang("confirmClear"))&&a.execCommand("cleardoc")}});return b.buttons.cleardoc=c,a.addListener("selectionchange",function(){c.setDisabled(a.queryCommandState("cleardoc")==-1)}),c};var h={justify:["left","right","center","justify"],imagefloat:["none","left","center","right"],directionality:["ltr","rtl"]};for(var i in h)!function(a,c){for(var d,e=0;d=c[e++];)!function(c){b[a.replace("float","")+c]=function(d){var e=new b.Button({ +className:"edui-for-"+a.replace("float","")+c,title:d.options.labelMap[a.replace("float","")+c]||d.getLang("labelMap."+a.replace("float","")+c)||"",theme:d.options.theme,onclick:function(){d.execCommand(a,c)}});return b.buttons[a]=e,d.addListener("selectionchange",function(b,f,g){e.setDisabled(d.queryCommandState(a)==-1),e.setChecked(d.queryCommandValue(a)==c&&!g)}),e}}(d)}(i,h[i]);for(var d,g=0;d=["backcolor","forecolor"][g++];)b[d]=function(a){return function(c){var d=new b.ColorButton({className:"edui-for-"+a,color:"default",title:c.options.labelMap[a]||c.getLang("labelMap."+a)||"",editor:c,onpickcolor:function(b,d){c.execCommand(a,d)},onpicknocolor:function(){c.execCommand(a,"default"),this.setColor("transparent"),this.color="default"},onbuttonclick:function(){c.execCommand(a,this.color)}});return b.buttons[a]=d,c.addListener("selectionchange",function(){d.setDisabled(c.queryCommandState(a)==-1)}),d}}(d);var j={noOk:["searchreplace","help","spechars","webapp","preview"],ok:["attachment","anchor","link","insertimage","map","gmap","insertframe","wordimage","insertvideo","insertframe","edittip","edittable","edittd","scrawl","template","music","background","charts"]};for(var i in j)!function(c,d){for(var f,g=0;f=d[g++];)browser.opera&&"searchreplace"===f||!function(d){b[d]=function(f,g,h){g=g||(f.options.iframeUrlMap||{})[d]||e[d],h=f.options.labelMap[d]||f.getLang("labelMap."+d)||"";var i;g&&(i=new b.Dialog(a.extend({iframeUrl:f.ui.mapUrl(g),editor:f,className:"edui-for-"+d,title:h,holdScroll:"insertimage"===d,fullscreen:/charts|preview/.test(d),closeDialog:f.getLang("closeDialog")},"ok"==c?{buttons:[{className:"edui-okbutton",label:f.getLang("ok"),editor:f,onclick:function(){i.close(!0)}},{className:"edui-cancelbutton",label:f.getLang("cancel"),editor:f,onclick:function(){i.close(!1)}}]}:{})),f.ui._dialogs[d+"Dialog"]=i);var j=new b.Button({className:"edui-for-"+d,title:h,onclick:function(){if(i)switch(d){case"wordimage":var a=f.execCommand("wordimage");a&&a.length&&(i.render(),i.open());break;case"scrawl":f.queryCommandState("scrawl")!=-1&&(i.render(),i.open());break;default:i.render(),i.open()}},theme:f.options.theme,disabled:"scrawl"==d&&f.queryCommandState("scrawl")==-1||"charts"==d});return b.buttons[d]=j,f.addListener("selectionchange",function(){var a={edittable:1};if(!(d in a)){var b=f.queryCommandState(d);j.getDom()&&(j.setDisabled(b==-1),j.setChecked(b))}}),j}}(f.toLowerCase())}(i,j[i]);b.snapscreen=function(a,c,d){d=a.options.labelMap.snapscreen||a.getLang("labelMap.snapscreen")||"";var f=new b.Button({className:"edui-for-snapscreen",title:d,onclick:function(){a.execCommand("snapscreen")},theme:a.options.theme});if(b.buttons.snapscreen=f,c=c||(a.options.iframeUrlMap||{}).snapscreen||e.snapscreen){var g=new b.Dialog({iframeUrl:a.ui.mapUrl(c),editor:a,className:"edui-for-snapscreen",title:d,buttons:[{className:"edui-okbutton",label:a.getLang("ok"),editor:a,onclick:function(){g.close(!0)}},{className:"edui-cancelbutton",label:a.getLang("cancel"),editor:a,onclick:function(){g.close(!1)}}]});g.render(),a.ui._dialogs.snapscreenDialog=g}return a.addListener("selectionchange",function(){f.setDisabled(a.queryCommandState("snapscreen")==-1)}),f},b.insertcode=function(c,d,e){d=c.options.insertcode||[],e=c.options.labelMap.insertcode||c.getLang("labelMap.insertcode")||"";var f=[];a.each(d,function(a,b){f.push({label:a,value:b,theme:c.options.theme,renderLabelHtml:function(){return'
          '+(this.label||"")+"
          "}})});var g=new b.Combox({editor:c,items:f,onselect:function(a,b){c.execCommand("insertcode",this.items[b].value)},onbuttonclick:function(){this.showPopup()},title:e,initValue:e,className:"edui-for-insertcode",indexByValue:function(a){if(a)for(var b,c=0;b=this.items[c];c++)if(b.value.indexOf(a)!=-1)return c;return-1}});return b.buttons.insertcode=g,c.addListener("selectionchange",function(a,b,d){if(!d){var f=c.queryCommandState("insertcode");if(f==-1)g.setDisabled(!0);else{g.setDisabled(!1);var h=c.queryCommandValue("insertcode");if(!h)return void g.setValue(e);h&&(h=h.replace(/['"]/g,"").split(",")[0]),g.setValue(h)}}}),g},b.fontfamily=function(c,d,e){if(d=c.options.fontfamily||[],e=c.options.labelMap.fontfamily||c.getLang("labelMap.fontfamily")||"",d.length){for(var f,g=0,h=[];f=d[g];g++){var i=c.getLang("fontfamily")[f.name]||"";!function(b,d){h.push({label:b,value:d,theme:c.options.theme,renderLabelHtml:function(){return'
          '+(this.label||"")+"
          "}})}(f.label||i,f.val)}var j=new b.Combox({editor:c,items:h,onselect:function(a,b){c.execCommand("FontFamily",this.items[b].value)},onbuttonclick:function(){this.showPopup()},title:e,initValue:e,className:"edui-for-fontfamily",indexByValue:function(a){if(a)for(var b,c=0;b=this.items[c];c++)if(b.value.indexOf(a)!=-1)return c;return-1}});return b.buttons.fontfamily=j,c.addListener("selectionchange",function(a,b,d){if(!d){var e=c.queryCommandState("FontFamily");if(e==-1)j.setDisabled(!0);else{j.setDisabled(!1);var f=c.queryCommandValue("FontFamily");f&&(f=f.replace(/['"]/g,"").split(",")[0]),j.setValue(f)}}}),j}},b.fontsize=function(a,c,d){if(d=a.options.labelMap.fontsize||a.getLang("labelMap.fontsize")||"",c=c||a.options.fontsize||[],c.length){for(var e=[],f=0;f'+(this.label||"")+""}})}var h=new b.Combox({editor:a,items:e,title:d,initValue:d,onselect:function(b,c){a.execCommand("FontSize",this.items[c].value)},onbuttonclick:function(){this.showPopup()},className:"edui-for-fontsize"});return b.buttons.fontsize=h,a.addListener("selectionchange",function(b,c,d){if(!d){var e=a.queryCommandState("FontSize");e==-1?h.setDisabled(!0):(h.setDisabled(!1),h.setValue(a.queryCommandValue("FontSize")))}}),h}},b.paragraph=function(c,d,e){if(e=c.options.labelMap.paragraph||c.getLang("labelMap.paragraph")||"",d=c.options.paragraph||[],!a.isEmptyObject(d)){var f=[];for(var g in d)f.push({value:g,label:d[g]||c.getLang("paragraph")[g],theme:c.options.theme,renderLabelHtml:function(){return'
          '+(this.label||"")+"
          "}});var h=new b.Combox({editor:c,items:f,title:e,initValue:e,className:"edui-for-paragraph",onselect:function(a,b){c.execCommand("Paragraph",this.items[b].value)},onbuttonclick:function(){this.showPopup()}});return b.buttons.paragraph=h,c.addListener("selectionchange",function(a,b,d){if(!d){var e=c.queryCommandState("Paragraph");if(e==-1)h.setDisabled(!0);else{h.setDisabled(!1);var f=c.queryCommandValue("Paragraph"),g=h.indexByValue(f);g!=-1?h.setValue(f):h.setValue(h.initValue)}}}),h}},b.customstyle=function(a){var c=a.options.customstyle||[],d=a.options.labelMap.customstyle||a.getLang("labelMap.customstyle")||"";if(c.length){for(var e,f=a.getLang("customstyle"),g=0,h=[];e=c[g++];)!function(b){var c={};c.label=b.label?b.label:f[b.name],c.style=b.style,c.className=b.className,c.tag=b.tag,h.push({label:c.label,value:c,theme:a.options.theme,renderLabelHtml:function(){return'
          <'+c.tag+" "+(c.className?' class="'+c.className+'"':"")+(c.style?' style="'+c.style+'"':"")+">"+c.label+"
          "}})}(e);var i=new b.Combox({editor:a,items:h,title:d,initValue:d,className:"edui-for-customstyle",onselect:function(b,c){a.execCommand("customstyle",this.items[c].value)},onbuttonclick:function(){this.showPopup()},indexByValue:function(a){for(var b,c=0;b=this.items[c++];)if(b.label==a)return c-1;return-1}});return b.buttons.customstyle=i,a.addListener("selectionchange",function(b,c,d){if(!d){var e=a.queryCommandState("customstyle");if(e==-1)i.setDisabled(!0);else{i.setDisabled(!1);var f=a.queryCommandValue("customstyle"),g=i.indexByValue(f);g!=-1?i.setValue(f):i.setValue(i.initValue)}}}),i}},b.inserttable=function(a,c,d){d=a.options.labelMap.inserttable||a.getLang("labelMap.inserttable")||"";var e=new b.TableButton({editor:a,title:d,className:"edui-for-inserttable",onpicktable:function(b,c,d){a.execCommand("InsertTable",{numRows:d,numCols:c,border:1})},onbuttonclick:function(){this.showPopup()}});return b.buttons.inserttable=e,a.addListener("selectionchange",function(){e.setDisabled(a.queryCommandState("inserttable")==-1)}),e},b.lineheight=function(a){var c=a.options.lineheight||[];if(c.length){for(var d,e=0,f=[];d=c[e++];)f.push({label:d,value:d,theme:a.options.theme,onclick:function(){a.execCommand("lineheight",this.value)}});var g=new b.MenuButton({editor:a,className:"edui-for-lineheight",title:a.options.labelMap.lineheight||a.getLang("labelMap.lineheight")||"",items:f,onbuttonclick:function(){var b=a.queryCommandValue("LineHeight")||this.value;a.execCommand("LineHeight",b)}});return b.buttons.lineheight=g,a.addListener("selectionchange",function(){var b=a.queryCommandState("LineHeight");if(b==-1)g.setDisabled(!0);else{g.setDisabled(!1);var c=a.queryCommandValue("LineHeight");c&&g.setValue((c+"").replace(/cm/,"")),g.setChecked(b)}}),g}};for(var k,l=["top","bottom"],m=0;k=l[m++];)!function(a){b["rowspacing"+a]=function(c){var d=c.options["rowspacing"+a]||[];if(!d.length)return null;for(var e,f=0,g=[];e=d[f++];)g.push({label:e,value:e,theme:c.options.theme,onclick:function(){c.execCommand("rowspacing",this.value,a)}});var h=new b.MenuButton({editor:c,className:"edui-for-rowspacing"+a,title:c.options.labelMap["rowspacing"+a]||c.getLang("labelMap.rowspacing"+a)||"",items:g,onbuttonclick:function(){var b=c.queryCommandValue("rowspacing",a)||this.value;c.execCommand("rowspacing",b,a)}});return b.buttons[a]=h,c.addListener("selectionchange",function(){var b=c.queryCommandState("rowspacing",a);if(b==-1)h.setDisabled(!0);else{h.setDisabled(!1);var d=c.queryCommandValue("rowspacing",a);d&&h.setValue((d+"").replace(/%/,"")),h.setChecked(b)}}),h}}(k);for(var n,o=["insertorderedlist","insertunorderedlist"],p=0;n=o[p++];)!function(a){b[a]=function(c){var d=c.options[a],e=function(){c.execCommand(a,this.value)},f=[];for(var g in d)f.push({label:d[g]||c.getLang()[a][g]||"",value:g,theme:c.options.theme,onclick:e});var h=new b.MenuButton({editor:c,className:"edui-for-"+a,title:c.getLang("labelMap."+a)||"",items:f,onbuttonclick:function(){var b=c.queryCommandValue(a)||this.value;c.execCommand(a,b)}});return b.buttons[a]=h,c.addListener("selectionchange",function(){var b=c.queryCommandState(a);if(b==-1)h.setDisabled(!0);else{h.setDisabled(!1);var d=c.queryCommandValue(a);h.setValue(d),h.setChecked(b)}}),h}}(n);b.fullscreen=function(a,c){c=a.options.labelMap.fullscreen||a.getLang("labelMap.fullscreen")||"";var d=new b.Button({className:"edui-for-fullscreen",title:c,theme:a.options.theme,onclick:function(){a.ui&&a.ui.setFullScreen(!a.ui.isFullScreen()),this.setChecked(a.ui.isFullScreen())}});return b.buttons.fullscreen=d,a.addListener("selectionchange",function(){var b=a.queryCommandState("fullscreen");d.setDisabled(b==-1),d.setChecked(a.ui.isFullScreen())}),d},b.emotion=function(a,c){var d="emotion",f=new b.MultiMenuPop({title:a.options.labelMap[d]||a.getLang("labelMap."+d)||"",editor:a,className:"edui-for-"+d,iframeUrl:a.ui.mapUrl(c||(a.options.iframeUrlMap||{})[d]||e[d])});return b.buttons[d]=f,a.addListener("selectionchange",function(){f.setDisabled(a.queryCommandState(d)==-1)}),f},b.autotypeset=function(a){var c=new b.AutoTypeSetButton({editor:a,title:a.options.labelMap.autotypeset||a.getLang("labelMap.autotypeset")||"",className:"edui-for-autotypeset",onbuttonclick:function(){a.execCommand("autotypeset")}});return b.buttons.autotypeset=c,a.addListener("selectionchange",function(){c.setDisabled(a.queryCommandState("autotypeset")==-1)}),c},b.simpleupload=function(a){var c="simpleupload",d=new b.Button({className:"edui-for-"+c,title:a.options.labelMap[c]||a.getLang("labelMap."+c)||"",onclick:function(){},theme:a.options.theme,showText:!1});return b.buttons[c]=d,a.addListener("ready",function(){var b=d.getDom("body"),c=b.children[0];a.fireEvent("simpleuploadbtnready",c)}),a.addListener("selectionchange",function(b,e,f){var g=a.queryCommandState(c);g==-1?(d.setDisabled(!0),d.setChecked(!1)):f||(d.setDisabled(!1),d.setChecked(g))}),d}}(),function(){function a(a){this.initOptions(a),this.initEditorUI()}var b=baidu.editor.utils,c=baidu.editor.ui.uiUtils,d=baidu.editor.ui.UIBase,e=baidu.editor.dom.domUtils,f=[];a.prototype={uiName:"editor",initEditorUI:function(){function a(a,b){a.setOpt({wordCount:!0,maximumWords:1e4,wordCountMsg:a.options.wordCountMsg||a.getLang("wordCountMsg"),wordOverFlowMsg:a.options.wordOverFlowMsg||a.getLang("wordOverFlowMsg")});var c=a.options,d=c.maximumWords,e=c.wordCountMsg,f=c.wordOverFlowMsg,g=b.getDom("wordcount");if(c.wordCount){var h=a.getContentLength(!0);h>d?(g.innerHTML=f,a.fireEvent("wordcountoverflow")):g.innerHTML=e.replace("{#leave}",d-h).replace("{#count}",h)}}this.editor.ui=this,this._dialogs={},this.initUIBase(),this._initToolbars();var b=this.editor,c=this;b.addListener("ready",function(){function d(){a(b,c),e.un(b.document,"click",arguments.callee)}b.getDialog=function(a){return b.ui._dialogs[a+"Dialog"]},e.on(b.window,"scroll",function(a){baidu.editor.ui.Popup.postHide(a)}),b.ui._actualFrameWidth=b.options.initialFrameWidth,UE.browser.ie&&6===UE.browser.version&&b.container.ownerDocument.execCommand("BackgroundImageCache",!1,!0),b.options.elementPathEnabled&&(b.ui.getDom("elementpath").innerHTML='
          '+b.getLang("elementPathTip")+":
          "),b.options.wordCount&&(e.on(b.document,"click",d),b.ui.getDom("wordcount").innerHTML=b.getLang("wordCountTip")),b.ui._scale(),b.options.scaleEnabled?(b.autoHeightEnabled&&b.disableAutoHeight(),c.enableScale()):c.disableScale(),b.options.elementPathEnabled||b.options.wordCount||b.options.scaleEnabled||(b.ui.getDom("elementpath").style.display="none",b.ui.getDom("wordcount").style.display="none",b.ui.getDom("scale").style.display="none"),b.selection.isFocus()&&b.fireEvent("selectionchange",!1,!0)}),b.addListener("mousedown",function(a,b){var c=b.target||b.srcElement;baidu.editor.ui.Popup.postHide(b,c),baidu.editor.ui.ShortCutMenu.postHide(b)}),b.addListener("delcells",function(){UE.ui.edittip&&new UE.ui.edittip(b),b.getDialog("edittip").open()});var d,f,g=!1;b.addListener("afterpaste",function(){b.queryCommandState("pasteplain")||(baidu.editor.ui.PastePicker&&(d=new baidu.editor.ui.Popup({content:new baidu.editor.ui.PastePicker({editor:b}),editor:b,className:"edui-wordpastepop"}),d.render()),g=!0)}),b.addListener("afterinserthtml",function(){clearTimeout(f),f=setTimeout(function(){if(d&&(g||b.ui._isTransfer)){if(d.isHidden()){var a=e.createElement(b.document,"span",{style:"line-height:0px;",innerHTML:"\ufeff"}),c=b.selection.getRange();c.insertNode(a);var f=getDomNode(a,"firstChild","previousSibling");f&&d.showAnchor(3==f.nodeType?f.parentNode:f),e.remove(a)}else d.show();delete b.ui._isTransfer,g=!1}},200)}),b.addListener("contextmenu",function(a,b){baidu.editor.ui.Popup.postHide(b)}),b.addListener("keydown",function(a,b){d&&d.dispose(b);var c=b.keyCode||b.which;b.altKey&&90==c&&UE.ui.buttons.fullscreen.onclick()}),b.addListener("wordcount",function(b){a(this,c)}),b.addListener("selectionchange",function(){b.options.elementPathEnabled&&c[(b.queryCommandState("elementpath")==-1?"dis":"en")+"ableElementPath"](),b.options.scaleEnabled&&c[(b.queryCommandState("scale")==-1?"dis":"en")+"ableScale"]()});var h=new baidu.editor.ui.Popup({editor:b,content:"",className:"edui-bubble",_onEditButtonClick:function(){this.hide(),b.ui._dialogs.linkDialog.open()},_onImgEditButtonClick:function(a){this.hide(),b.ui._dialogs[a]&&b.ui._dialogs[a].open()},_onImgSetFloat:function(a){this.hide(),b.execCommand("imagefloat",a)},_setIframeAlign:function(a){var b=h.anchorEl,c=b.cloneNode(!0);switch(a){case-2:c.setAttribute("align","");break;case-1:c.setAttribute("align","left");break;case 1:c.setAttribute("align","right")}b.parentNode.insertBefore(c,b),e.remove(b),h.anchorEl=c,h.showAnchor(h.anchorEl)},_updateIframe:function(){var a=b._iframe=h.anchorEl;e.hasClass(a,"ueditor_baidumap")?(b.selection.getRange().selectNode(a).select(),b.ui._dialogs.mapDialog.open(),h.hide()):(b.ui._dialogs.insertframeDialog.open(),h.hide())},_onRemoveButtonClick:function(a){b.execCommand(a),this.hide()},queryAutoHide:function(a){return a&&a.ownerDocument==b.document&&("img"==a.tagName.toLowerCase()||e.findParentByTagName(a,"a",!0))?a!==h.anchorEl:baidu.editor.ui.Popup.prototype.queryAutoHide.call(this,a)}});h.render(),b.options.imagePopup&&(b.addListener("mouseover",function(a,c){c=c||window.event;var d=c.target||c.srcElement;if(b.ui._dialogs.insertframeDialog&&/iframe/gi.test(d.tagName)){var e=h.formatHtml(""+b.getLang("property")+': '+b.getLang("default")+'  '+b.getLang("justifyleft")+'  '+b.getLang("justifyright")+'   '+b.getLang("modify")+"");e?(h.getDom("content").innerHTML=e,h.anchorEl=d,h.showAnchor(h.anchorEl)):h.hide()}}),b.addListener("selectionchange",function(a,c){if(c){var d="",f="",g=b.selection.getRange().getClosedNode(),i=b.ui._dialogs;if(g&&"IMG"==g.tagName){var j="insertimageDialog";if(g.className.indexOf("edui-faked-video")==-1&&g.className.indexOf("edui-upload-video")==-1||(j="insertvideoDialog"),g.className.indexOf("edui-faked-webapp")!=-1&&(j="webappDialog"),g.src.indexOf("http://api.map.baidu.com")!=-1&&(j="mapDialog"),g.className.indexOf("edui-faked-music")!=-1&&(j="musicDialog"),g.src.indexOf("http://maps.google.com/maps/api/staticmap")!=-1&&(j="gmapDialog"),g.getAttribute("anchorname")&&(j="anchorDialog",d=h.formatHtml(""+b.getLang("property")+': '+b.getLang("modify")+"  "+b.getLang("delete")+"")),g.getAttribute("word_img")&&(b.word_img=[g.getAttribute("word_img")],j="wordimageDialog"),(e.hasClass(g,"loadingclass")||e.hasClass(g,"loaderrorclass"))&&(j=""),!i[j])return;f=""+b.getLang("property")+': '+b.getLang("default")+'  '+b.getLang("justifyleft")+'  '+b.getLang("justifyright")+'  '+b.getLang("justifycenter")+"  '+b.getLang("modify")+"",!d&&(d=h.formatHtml(f))}if(b.ui._dialogs.linkDialog){var k,l=b.queryCommandValue("link");if(l&&(k=l.getAttribute("_href")||l.getAttribute("href",2))){var m=k;k.length>30&&(m=k.substring(0,20)+"..."),d&&(d+='
          '),d+=h.formatHtml(""+b.getLang("anthorMsg")+': '+m+' '+b.getLang("modify")+' '+b.getLang("clear")+""),h.showAnchor(l)}}d?(h.getDom("content").innerHTML=d,h.anchorEl=g||l,h.showAnchor(h.anchorEl)):h.hide()}}))},_initToolbars:function(){for(var a=this.editor,c=this.toolbars||[],d=[],e=0;e
          '+(this.toolbars.length?'
          '+this.renderToolbarBoxHtml()+"
          ":"")+'
          '},showWordImageDialog:function(){this._dialogs.wordimageDialog.open()},renderToolbarBoxHtml:function(){for(var a=[],b=0;b'+c+"");b.innerHTML='
          '+this.editor.getLang("elementPathTip")+": "+d.join(" > ")+"
          "}else b.style.display="none"},disableElementPath:function(){var a=this.getDom("elementpath");a.innerHTML="",a.style.display="none",this.elementPathEnabled=!1},enableElementPath:function(){var a=this.getDom("elementpath");a.style.display="",this.elementPathEnabled=!0,this._updateElementPath()},_scale:function(){function a(){o=e.getXY(h),p||(p=g.options.minFrameHeight+j.offsetHeight+k.offsetHeight),m.style.cssText="position:absolute;left:0;display:;top:0;background-color:#41ABFF;opacity:0.4;filter: Alpha(opacity=40);width:"+h.offsetWidth+"px;height:"+h.offsetHeight+"px;z-index:"+(g.options.zIndex+1),e.on(f,"mousemove",b),e.on(i,"mouseup",c),e.on(f,"mouseup",c)}function b(a){d();var b=a||window.event;r=b.pageX||f.documentElement.scrollLeft+b.clientX,s=b.pageY||f.documentElement.scrollTop+b.clientY,t=r-o.x,u=s-o.y,t>=q&&(n=!0,m.style.width=t+"px"),u>=p&&(n=!0,m.style.height=u+"px")}function c(){n&&(n=!1,g.ui._actualFrameWidth=m.offsetWidth-2,h.style.width=g.ui._actualFrameWidth+"px",g.setHeight(m.offsetHeight-k.offsetHeight-j.offsetHeight-2,!0)),m&&(m.style.display="none"),d(),e.un(f,"mousemove",b),e.un(i,"mouseup",c),e.un(f,"mouseup",c)}function d(){browser.ie?f.selection.clear():window.getSelection().removeAllRanges()}var f=document,g=this.editor,h=g.container,i=g.document,j=this.getDom("toolbarbox"),k=this.getDom("bottombar"),l=this.getDom("scale"),m=this.getDom("scalelayer"),n=!1,o=null,p=0,q=g.options.minFrameWidth,r=0,s=0,t=0,u=0,v=this;this.editor.addListener("fullscreenchanged",function(a,b){if(b)v.disableScale();else if(v.editor.options.scaleEnabled){v.enableScale();var c=v.editor.document.createElement("span");v.editor.body.appendChild(c),v.editor.body.style.height=Math.max(e.getXY(c).y,v.editor.iframe.offsetHeight-20)+"px",e.remove(c)}}),this.enableScale=function(){1!=g.queryCommandState("source")&&(l.style.display="",this.scaleEnabled=!0,e.on(l,"mousedown",a))},this.disableScale=function(){l.style.display="none",this.scaleEnabled=!1,e.un(l,"mousedown",a)}},isFullScreen:function(){return this._fullscreen},postRender:function(){d.prototype.postRender.call(this);for(var a=0;a[\n\r\t]+([ ]{4})+/g,">").replace(/[\n\r\t]+([ ]{4})+[\n\r\t]+<"),c.className&&(b.className=c.className),c.style.cssText&&(b.style.cssText=c.style.cssText),/textarea/i.test(c.tagName)?(d.textarea=c,d.textarea.style.display="none"):c.parentNode.removeChild(c),c.id&&(b.id=c.id,e.removeAttributes(c,"id")),c=b,c.innerHTML=""}e.addClass(c,"edui-"+d.options.theme),d.ui.render(c);var h=d.options;d.container=d.ui.getDom();for(var i,j=e.findParents(c,!0),k=[],l=0;i=j[l];l++)k[l]=i.style.display,i.style.display="block";if(h.initialFrameWidth)h.minFrameWidth=h.initialFrameWidth;else{h.minFrameWidth=h.initialFrameWidth=c.offsetWidth;var m=c.style.width;/%$/.test(m)&&(h.initialFrameWidth=m)}h.initialFrameHeight?h.minFrameHeight=h.initialFrameHeight:h.initialFrameHeight=h.minFrameHeight=c.offsetHeight;for(var i,l=0;i=j[l];l++)i.style.display=k[l];c.style.height&&(c.style.height=""),d.container.style.width=h.initialFrameWidth+(/%$/.test(h.initialFrameWidth)?"":"px"),d.container.style.zIndex=h.zIndex,f.call(d,d.ui.getDom("iframeholder")),d.fireEvent("afteruiready")}d.langIsReady?b():d.addListener("langReady",b)})},d},UE.getEditor=function(a,b){var c=g[a];return c||(c=g[a]=new UE.ui.Editor(b),c.render(a)),c},UE.delEditor=function(a){var b;(b=g[a])&&(b.key&&b.destroy(),delete g[a])},UE.registerUI=function(a,c,d,e){b.each(a.split(/\s+/),function(a){UE._customizeUI[a]={id:e,execFn:c,index:d}})}}(),UE.registerUI("message",function(a){function b(){var a=g.ui.getDom("toolbarbox");a&&(c.style.top=a.offsetHeight+3+"px"),c.style.zIndex=Math.max(g.options.zIndex,g.iframe.style.zIndex)+1}var c,d=baidu.editor.ui,e=d.Message,f=[],g=a;g.addListener("ready",function(){c=document.getElementById(g.ui.id+"_message_holder"),b(),setTimeout(function(){b()},500)}),g.addListener("showmessage",function(a,d){d=utils.isString(d)?{content:d}:d;var h=new e({timeout:d.timeout,type:d.type,content:d.content,keepshow:d.keepshow,editor:g}),i=d.id||"msg_"+(+new Date).toString(36);return h.render(c),f[i]=h,h.reset(d),b(),i}),g.addListener("updatemessage",function(a,b,d){d=utils.isString(d)?{content:d}:d;var e=f[b];e.render(c),e&&e.reset(d)}),g.addListener("hidemessage",function(a,b){var c=f[b];c&&c.hide()})}),UE.registerUI("autosave",function(a){var b=null,c=null;a.on("afterautosave",function(){clearTimeout(b),b=setTimeout(function(){c&&a.trigger("hidemessage",c),c=a.trigger("showmessage",{content:a.getLang("autosave.success"),timeout:2e3})},2e3)})})}(); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/ueditor/video-clip.png b/net452/SiteServer.Web/SiteServer/assets/ueditor/video-clip.png new file mode 100644 index 000000000..18f06ae46 Binary files /dev/null and b/net452/SiteServer.Web/SiteServer/assets/ueditor/video-clip.png differ diff --git a/SiteServer.Web/SiteServer/assets/validate.js b/net452/SiteServer.Web/SiteServer/assets/validate.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/validate.js rename to net452/SiteServer.Web/SiteServer/assets/validate.js diff --git a/SiteServer.Web/SiteServer/assets/vue/README.md b/net452/SiteServer.Web/SiteServer/assets/vue/README.md similarity index 100% rename from SiteServer.Web/SiteServer/assets/vue/README.md rename to net452/SiteServer.Web/SiteServer/assets/vue/README.md diff --git a/SiteServer.Web/SiteServer/assets/vue/vue.min.js b/net452/SiteServer.Web/SiteServer/assets/vue/vue.min.js similarity index 100% rename from SiteServer.Web/SiteServer/assets/vue/vue.min.js rename to net452/SiteServer.Web/SiteServer/assets/vue/vue.min.js diff --git a/net452/SiteServer.Web/SiteServer/assets/web-uploader/Q.Uploader.file.all.js b/net452/SiteServer.Web/SiteServer/assets/web-uploader/Q.Uploader.file.all.js new file mode 100644 index 000000000..0fcf4ff6c --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/web-uploader/Q.Uploader.file.all.js @@ -0,0 +1,3 @@ +//devin87@qq.com +//build:2017/12/04 15:04:58 +!function(t,e){"use strict";function i(t,i){return t!==e?t:i}function n(t){return"[object Function]"===f.call(t)}function r(t){return"number"==typeof t&&t>0&&t===Math.floor(t)}function s(t,i,n){if(!t||!i)return t;for(var r in i)r!=e&&h.call(i,r)&&(n||t[r]===e)&&(t[r]=i[r]);return t}function a(t,e,i,n){for(var r=t[i||e],s=[];r;){if(1==r.nodeType){if(!n)return r;s.push(r)}r=r[e]}return n?s:null}function o(t){return t.firstElementChild||a(t,"nextSibling","firstChild",!1)}function l(t,e,i){var n=document.createElement(t);return e&&(n.className=e),i&&(n.innerHTML=i),n}function u(e){var i=e||t.event;return i.target||(i.target=i.srcElement),i}function c(t){return y.test(t)}function d(t,e,i){t=+t;for(var n=0,s="number"==typeof(e=e||1024),a=1,o=r(i)?i:s?100:e.length;t>=a&&n
          ');i.appendChild(s);var a=l(s),o=u(s);t.iframe=a,t.form=o,function(t,e){t.attachEvent?t.attachEvent("onload",e):t.addEventListener("load",e,!1)}(a,function(){if(0==t.workerIdle){var e;try{e=a.contentWindow.document.body.innerHTML}catch(t){}t.complete(void 0,I,e)}})}return t.targets.forEach(function(e){t.clickTrigger?g(e,"click",function(e){!1!==t.fire("select",e)&&(t.resetInput(),y(t.inputFile,"click"))}):g(e,"mouseover",function(e){t.target=this,t.updatePos()})}),t.clickTrigger||(g(n,"click",function(e){!1===t.fire("select",e)&&w(e)}),h(n,0),t.resetInput()),t.fire("init"),t.run("init")}},resetInput:function(){var t=this,e=t.boxInput;e.innerHTML='";var i=l(e);return g(i,"change",function(e){t.add(this),t.html5||t.resetInput()}),t.inputFile=i,t.updatePos()},updatePos:function(t){if(this.clickTrigger)return this;var e=this.getPos||p,i=this.boxInput,n=l(i),r=this.target,s=r.offsetWidth,a=r.offsetHeight,o=0==s?{left:-1e4,top:-1e4}:e(r);return i.style.width=n.style.width=s+"px",i.style.height=n.style.height=a+"px",i.style.left=o.left+"px",i.style.top=o.top+"px",t&&(i.style.zIndex=++b),this},fire:function(t,e,i){if(!i)return a(this.fns[t],this,e);var n=this.fns[t+"Async"];if(n)return a(n,this,e,i);i(a(this.fns[t],this,e))},run:function(t,e){var i=this[t];return i&&a(i,this,e),this},addTask:function(t,e){if(t||e){var n,r;e?(n=e.name||e.fileName,r=e.size||e.fileSize):(n=i(t.value,"\\").slice(1)||t.value,r=-1);var s,a=this,o=i(n,".").toLowerCase();a.disallows&&a.disallows[o]||a.allows&&!a.allows[o]?s="ext":-1!=r&&a.maxSize&&r>a.maxSize&&(s="size");var l={id:++T,name:n,ext:o,size:r,input:t,file:e,state:s?N:L};return s&&(l.limited=s,l.disabled=!0),a.fire("add",l,function(t){!1===t||l.disabled||l.limited||(l.index=a.list.length,a.list.push(l),a.map[l.id]=l,a.run("draw",l),a.auto&&a.start())}),l}},add:function(t){if("INPUT"==t.tagName){var e=t.files;if(e)for(var i=0,n=e.length;i=n||t<=0)return this;var r=e[i];return this.index++,this.upload(r)},upload:function(t){var e=this;return!t||t.state!=L||t.skip?e.start():(t.url=e.url,e.workerIdle--,e.fire("upload",t,function(i){if(!1===i)return e.complete(t,N);e.html5&&t.file?e._upload_html5_ready(t):t.input?e._upload_html4(t):e.complete(t,N)}),e)},queryState:function(t,e){var i=this,n=i.url,r=new XMLHttpRequest;return t.queryUrl=n+(-1==n.indexOf("?")?"?":"&")+"action=query&hash="+(t.hash||encodeURIComponent(t.name))+"&fileName="+encodeURIComponent(t.name),i.fire("sliceQuery",t),r.open("GET",t.queryUrl),r.onreadystatechange=function(){if(4==r.readyState){var n,s;if(r.status>=200&&r.status<400)if("ok"===(n=r.responseText)?s={ret:1}:n&&(s=c(n)),s&&"number"!=typeof s||(s={ret:0,start:s}),t.response=n,t.json=s,1==s.ret)t.queryOK=!0,i.cancel(t.id,!0).complete(t,I);else{var o=+s.start||0;o!=Math.floor(o)&&(o=0),t.sliceStart=o}a(e,i,r)}},r.onerror=function(){a(e,i,r)},r.send(null),i},_upload_html5_ready:function(t){var e=this,i=function(){t.state!=I&&(e.isSlice?e._upload_slice(t):e._upload_html5(t))},n=function(i){e.fire("hash",t,function(){t.hash&&e.isQueryState&&t.state!=I?e.queryState(t,i):i()})},r=function(i){if(e.isMd5&&v){var r=e.fns.hashProgress;v(t.file,function(e,r){t.hash=e,t.timeHash=r,n(i)},function(i){a(r,e,t,i)})}else n(i)};return e.isUploadAfterHash?r(i):(i(),r()),e},_process_params:function(t,e){this.data&&Object.forEach(this.data,e),t.data&&Object.forEach(t.data,e)},_upload_html5:function(t){var e=this,i=new XMLHttpRequest;t.xhr=i,i.upload.addEventListener("progress",function(i){e.progress(t,i.total,i.loaded)},!1),i.addEventListener("load",function(i){e.complete(t,I,i.target.responseText)},!1),i.addEventListener("error",function(){e.complete(t,M)},!1),i.addEventListener("abort",function(){e.complete(t,O)},!1);var n=new FormData;e._process_params(t,function(t,e){n.append(t,e)}),n.append("fileName",t.name),n.append(e.upName,t.blob||t.file,t.name),i.open("POST",t.url),e.fire("send",t,function(r){if(!1===r)return e.complete(t,N);i.send(n),e._afterSend(t)})},_upload_html4:function(t){var e=this,i=e.form,n=t.input;if(n._uploaded)return e.complete(t,I);n._uploaded=!0,n.name=e.upName,i.innerHTML="",i.appendChild(n),i.action=t.url,e._process_params(t,function(t,e){i.appendChild(f(''))}),e.fire("send",t,function(n){if(!1===n)return e.complete(t,N);i.submit(),e._afterSend(t)})},_afterSend:function(t){t.lastTime=t.startTime=Date.now(),t.state=k,this._lastTask=t,this.progress(t)},progress:function(t,e,i){e||(e=t.size),(!i||i<0)&&(i=0);var n=t.state||L;i>e&&(i=e),i>0&&n==L&&(t.state=n=k);n==I&&(e=i=t.size),function(t,e,i){if(e&&!(e<=0)){var n,r=Date.now();if(i>=e)return(n=r-t.startTime)?t.avgSpeed=Math.min(Math.round(1e3*e/n),e):t.speed||(t.avgSpeed=t.speed=e),t.time=n||0,void(t.endTime=r);(n=r-t.lastTime)<200||(t.speed=Math.min(Math.round(1e3*(i-t.loaded)/n),t.total),t.lastTime=r)}}(t,e,i),t.total=e,t.loaded=i,this.fire("progress",t),this.run("update",t)},_process_response:function(t,e){t.response=e,e&&"json"==this.dataType&&(t.json=c(e))},complete:function(t,e,i){return t||1!=this.workerThread||(t=this._lastTask),t&&(void 0!=e&&(t.state=e),t.state!=k&&e!=I||(t.state=I,this.progress(t,t.size,t.size)),void 0!==i&&this._process_response(t,i)),this.run("update",t).run("over",t),e==O&&this.fire("cancel",t),this.fire("complete",t),this.workerIdle++,this.started&&this.start(),this}},r.extend=function(t,e){o(r.prototype,t,e)},function(){var e=t.XMLHttpRequest;e&&(new e).upload&&t.FormData&&(x=!0);var i=document.createElement("input");i.type="file",E=!!i.files,S=x}(),o(r,{support:{html5:x,multiple:E},READY:L,PROCESSING:k,COMPLETE:I,SKIP:N,CANCEL:O,ERROR:M,UI:{},Lang:{status_ready:"准备中",status_processing:"上传中",status_complete:"已完成",status_skip:"已跳过",status_cancel:"已取消",status_error:"已失败"},getStatusText:function(t){var e=r.Lang;switch(t){case L:return e.status_ready;case k:return e.status_processing;case I:return e.status_complete;case N:return e.status_skip;case O:return e.status_cancel;case M:return e.status_error}return t}}),Q.Uploader=r}(window),function(t,e){"use strict";function i(t,e){t.className+=" "+e}function n(t,e){t&&(t.innerHTML=e||"")}var r=Q.def,s=Q.getFirst,a=Q.getLast,o=Q.getNext,l=Q.createEle,u=Q.formatSize,c=Q.event.add,d=Q.Uploader,f=d.Lang;d.UI.File={init:function(){var t=this.ops.view;t&&i(t,"ui-file "+(this.html5?"html5":"html4"))},draw:function(t){var e=this,i=e.ops,n=i.view;if(n){var o=i.button||{},u=r(f.cancel||o.cancel,"取消"),d=r(f.remove||o.remove,"删除"),h=t.name,p='
          '+h+'
          ',v=t.id,m=l("div","u-item",p);m.taskId=v,t.box=m,n.appendChild(m);var g=a(m.childNodes[1]),y=s(g),w=a(g);c(y,"click",function(){e.cancel(v)}),c(w,"click",function(){e.remove(v),n.removeChild(m)}),e.update(t)}},update:function(t){if(t&&t.box){var e=t.total||t.size,i=t.loaded,r=t.state,a=t.box.childNodes[1],l=s(a),c=o(l),f=o(c),h=s(f),p=o(f);if(n(o(p),d.getStatusText(r)),!(e<0)){var v="";if(this.html5&&void 0!=i&&i>=0){var m;if(r==d.PROCESSING){"100.0"==(m=Math.min(100*i/e,100).toFixed(1))&&(m="99.9")}else r==d.COMPLETE&&(m="100");m&&(m+="%",h.style.width=m,n(p,m)),v=''+u(i)+" / ";var g=t.avgSpeed||t.speed;n(c,u(g)+"/s")}n(l,v+=''+u(e)+"")}}},over:function(t){t&&t.box&&i(t.box,"u-over")}},d.extend(d.UI.File)}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/web-uploader/Q.Uploader.image.all.js b/net452/SiteServer.Web/SiteServer/assets/web-uploader/Q.Uploader.image.all.js new file mode 100644 index 000000000..cf8e81baa --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/web-uploader/Q.Uploader.image.all.js @@ -0,0 +1,3 @@ +//devin87@qq.com +//build:2017/12/04 15:04:59 +!function(t,e){"use strict";function i(t,i){return t!==e?t:i}function n(t){return"[object Function]"===d.call(t)}function r(t){return"number"==typeof t&&t>0&&t===Math.floor(t)}function a(t,i,n){if(!t||!i)return t;for(var r in i)r!=e&&h.call(i,r)&&(n||t[r]===e)&&(t[r]=i[r]);return t}function s(t,e,i,n){for(var r=t[i||e],a=[];r;){if(1==r.nodeType){if(!n)return r;a.push(r)}r=r[e]}return n?a:null}function o(t){return t.firstElementChild||s(t,"nextSibling","firstChild",!1)}function l(t,e,i){var n=document.createElement(t);return e&&(n.className=e),i&&(n.innerHTML=i),n}function u(e){var i=e||t.event;return i.target||(i.target=i.srcElement),i}function c(t){return w.test(t)}function f(t,e,i){t=+t;for(var n=0,a="number"==typeof(e=e||1024),s=1,o=r(i)?i:a?100:e.length;t>=s&&n
          ');i.appendChild(a);var s=l(a),o=u(a);t.iframe=s,t.form=o,function(t,e){t.attachEvent?t.attachEvent("onload",e):t.addEventListener("load",e,!1)}(s,function(){if(0==t.workerIdle){var e;try{e=s.contentWindow.document.body.innerHTML}catch(t){}t.complete(void 0,I,e)}})}return t.targets.forEach(function(e){t.clickTrigger?g(e,"click",function(e){!1!==t.fire("select",e)&&(t.resetInput(),w(t.inputFile,"click"))}):g(e,"mouseover",function(e){t.target=this,t.updatePos()})}),t.clickTrigger||(g(n,"click",function(e){!1===t.fire("select",e)&&y(e)}),h(n,0),t.resetInput()),t.fire("init"),t.run("init")}},resetInput:function(){var t=this,e=t.boxInput;e.innerHTML='";var i=l(e);return g(i,"change",function(e){t.add(this),t.html5||t.resetInput()}),t.inputFile=i,t.updatePos()},updatePos:function(t){if(this.clickTrigger)return this;var e=this.getPos||p,i=this.boxInput,n=l(i),r=this.target,a=r.offsetWidth,s=r.offsetHeight,o=0==a?{left:-1e4,top:-1e4}:e(r);return i.style.width=n.style.width=a+"px",i.style.height=n.style.height=s+"px",i.style.left=o.left+"px",i.style.top=o.top+"px",t&&(i.style.zIndex=++T),this},fire:function(t,e,i){if(!i)return s(this.fns[t],this,e);var n=this.fns[t+"Async"];if(n)return s(n,this,e,i);i(s(this.fns[t],this,e))},run:function(t,e){var i=this[t];return i&&s(i,this,e),this},addTask:function(t,e){if(t||e){var n,r;e?(n=e.name||e.fileName,r=e.size||e.fileSize):(n=i(t.value,"\\").slice(1)||t.value,r=-1);var a,s=this,o=i(n,".").toLowerCase();s.disallows&&s.disallows[o]||s.allows&&!s.allows[o]?a="ext":-1!=r&&s.maxSize&&r>s.maxSize&&(a="size");var l={id:++_,name:n,ext:o,size:r,input:t,file:e,state:a?M:L};return a&&(l.limited=a,l.disabled=!0),s.fire("add",l,function(t){!1===t||l.disabled||l.limited||(l.index=s.list.length,s.list.push(l),s.map[l.id]=l,s.run("draw",l),s.auto&&s.start())}),l}},add:function(t){if("INPUT"==t.tagName){var e=t.files;if(e)for(var i=0,n=e.length;i=n||t<=0)return this;var r=e[i];return this.index++,this.upload(r)},upload:function(t){var e=this;return!t||t.state!=L||t.skip?e.start():(t.url=e.url,e.workerIdle--,e.fire("upload",t,function(i){if(!1===i)return e.complete(t,M);e.html5&&t.file?e._upload_html5_ready(t):t.input?e._upload_html4(t):e.complete(t,M)}),e)},queryState:function(t,e){var i=this,n=i.url,r=new XMLHttpRequest;return t.queryUrl=n+(-1==n.indexOf("?")?"?":"&")+"action=query&hash="+(t.hash||encodeURIComponent(t.name))+"&fileName="+encodeURIComponent(t.name),i.fire("sliceQuery",t),r.open("GET",t.queryUrl),r.onreadystatechange=function(){if(4==r.readyState){var n,a;if(r.status>=200&&r.status<400)if("ok"===(n=r.responseText)?a={ret:1}:n&&(a=c(n)),a&&"number"!=typeof a||(a={ret:0,start:a}),t.response=n,t.json=a,1==a.ret)t.queryOK=!0,i.cancel(t.id,!0).complete(t,I);else{var o=+a.start||0;o!=Math.floor(o)&&(o=0),t.sliceStart=o}s(e,i,r)}},r.onerror=function(){s(e,i,r)},r.send(null),i},_upload_html5_ready:function(t){var e=this,i=function(){t.state!=I&&(e.isSlice?e._upload_slice(t):e._upload_html5(t))},n=function(i){e.fire("hash",t,function(){t.hash&&e.isQueryState&&t.state!=I?e.queryState(t,i):i()})},r=function(i){if(e.isMd5&&m){var r=e.fns.hashProgress;m(t.file,function(e,r){t.hash=e,t.timeHash=r,n(i)},function(i){s(r,e,t,i)})}else n(i)};return e.isUploadAfterHash?r(i):(i(),r()),e},_process_params:function(t,e){this.data&&Object.forEach(this.data,e),t.data&&Object.forEach(t.data,e)},_upload_html5:function(t){var e=this,i=new XMLHttpRequest;t.xhr=i,i.upload.addEventListener("progress",function(i){e.progress(t,i.total,i.loaded)},!1),i.addEventListener("load",function(i){e.complete(t,I,i.target.responseText)},!1),i.addEventListener("error",function(){e.complete(t,C)},!1),i.addEventListener("abort",function(){e.complete(t,O)},!1);var n=new FormData;e._process_params(t,function(t,e){n.append(t,e)}),n.append("fileName",t.name),n.append(e.upName,t.blob||t.file,t.name),i.open("POST",t.url),e.fire("send",t,function(r){if(!1===r)return e.complete(t,M);i.send(n),e._afterSend(t)})},_upload_html4:function(t){var e=this,i=e.form,n=t.input;if(n._uploaded)return e.complete(t,I);n._uploaded=!0,n.name=e.upName,i.innerHTML="",i.appendChild(n),i.action=t.url,e._process_params(t,function(t,e){i.appendChild(d(''))}),e.fire("send",t,function(n){if(!1===n)return e.complete(t,M);i.submit(),e._afterSend(t)})},_afterSend:function(t){t.lastTime=t.startTime=Date.now(),t.state=k,this._lastTask=t,this.progress(t)},progress:function(t,e,i){e||(e=t.size),(!i||i<0)&&(i=0);var n=t.state||L;i>e&&(i=e),i>0&&n==L&&(t.state=n=k);n==I&&(e=i=t.size),function(t,e,i){if(e&&!(e<=0)){var n,r=Date.now();if(i>=e)return(n=r-t.startTime)?t.avgSpeed=Math.min(Math.round(1e3*e/n),e):t.speed||(t.avgSpeed=t.speed=e),t.time=n||0,void(t.endTime=r);(n=r-t.lastTime)<200||(t.speed=Math.min(Math.round(1e3*(i-t.loaded)/n),t.total),t.lastTime=r)}}(t,e,i),t.total=e,t.loaded=i,this.fire("progress",t),this.run("update",t)},_process_response:function(t,e){t.response=e,e&&"json"==this.dataType&&(t.json=c(e))},complete:function(t,e,i){return t||1!=this.workerThread||(t=this._lastTask),t&&(void 0!=e&&(t.state=e),t.state!=k&&e!=I||(t.state=I,this.progress(t,t.size,t.size)),void 0!==i&&this._process_response(t,i)),this.run("update",t).run("over",t),e==O&&this.fire("cancel",t),this.fire("complete",t),this.workerIdle++,this.started&&this.start(),this}},r.extend=function(t,e){o(r.prototype,t,e)},function(){var e=t.XMLHttpRequest;e&&(new e).upload&&t.FormData&&(b=!0);var i=document.createElement("input");i.type="file",x=!!i.files,E=b}(),o(r,{support:{html5:b,multiple:x},READY:L,PROCESSING:k,COMPLETE:I,SKIP:M,CANCEL:O,ERROR:C,UI:{},Lang:{status_ready:"准备中",status_processing:"上传中",status_complete:"已完成",status_skip:"已跳过",status_cancel:"已取消",status_error:"已失败"},getStatusText:function(t){var e=r.Lang;switch(t){case L:return e.status_ready;case k:return e.status_processing;case I:return e.status_complete;case M:return e.status_skip;case O:return e.status_cancel;case C:return e.status_error}return t}}),Q.Uploader=r}(window),function(t,e){"use strict";function i(t,e){t.className+=" "+e}function n(i,n,r){var a=n.input,s=n.file||(a.files?a.files[0]:e);if(s)!function(e,i){var n=t.URL||t.webkitURL;if(n)return i(n.createObjectURL(e));if(t.FileReader){var r=new FileReader;r.onload=function(t){i(t.target.result)},r.readAsDataURL(e)}else e.readAsDataURL&&i(e.readAsDataURL())}(s,function(t){t&&(i.innerHTML=''),r&&r(t)});else if(a){var o=a.value;if(o&&!/^\w:\\fakepath/.test(o)||(a.select(),parent.document.body.focus(),document.selection&&(o=document.selection.createRange().text)),o){i.innerHTML='';try{u>6&&(i.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='"+o+"')")}catch(t){}}r&&r(o)}}function r(t,e,i,n){var r=new Image;r.src=t,r.onload=function(){var t=r.width,a=r.height,s=i.maxWidth,o=i.maxHeight,l=s&&t>s,u=o&&a>o;if(!(l||u))return n&&n(!1);l&&(t=s,a=Math.floor(r.height*t/r.width)),u&&(a=o,t=Math.floor(r.width*a/r.height));var c=document.createElement("canvas"),f=c.getContext("2d");c.width=t,c.height=a,f.drawImage(r,0,0,t,a),n&&n(c.toDataURL(e),e)}}var a=Q.getFirst,s=Q.getNext,o=Q.createEle,l=Q.setOpacity,u=Q.ie,c=Q.Uploader,f=t.Blob||t.WebkitBlob||t.MozBlob,d=t.WebKitBlobBuilder||t.MozBlobBuilder,h=function(){if(!t.FileReader||!t.atob||!f&&!d)return!1;var e=document.createElement("canvas");return!!e.getContext&&!!e.getContext("2d")}();c.support.imageScale=h,c.previewImage=n,c.scaleImage=r,c.UI.Image={init:function(){var t=this.ops,e=t.view;t.allows||(t.allows=".jpg,.png,.gif,.bmp,.webp,.tif,.tiff"),e&&i(e,"ui-image "+(this.html5?"html5":"html4"))},supportScale:function(t){if(!h)return!1;".jpeg"==t&&(t=".jpg");var e=(this.ops.scale||{}).types||".jpg";return!(-1==".jpg,.png,.gif,.bmp,.webp,.tif,.tiff".indexOf(t))&&("*"==e||-1!=e.indexOf(t))},previewImage:function(t,e,i){var a=this,s=e.scale||i.scale,o=s&&a.supportScale(e.ext);return o&&(e.skip=!0),n(t,e,function(t){a.fire("preview",{task:e,src:t}),t&&o&&r(t,function(t){var e=t.slice(1);return"image/"+("jpg"==e?"jpeg":e)}(e.ext),s,function(t,i){if(t){var n=function(t,e){for(var i=t.split(","),n=atob(i[1]),r=[],a=0,s=n.length;a
          '+n+"
          ",u=t.id,c=o("div","u-item",r);c.taskId=u;var f=a(c),d=s(f),h=a(d),p=s(d);l(d,.3),l(h,.5),t.box=c,t.boxProgress=h,t.boxDetail=p,i.appendChild(c),this.previewImage(f,t,e).update(t)}},update:function(t){if(t&&t.box){var i=t.total||t.size,n=t.loaded,r=t.state,a=t.boxProgress,s=t.boxDetail,o=c.getStatusText(r);if(this.html5&&n!=e&&n>=0){var l;if(r==c.PROCESSING){"100.0"==(l=Math.min(100*n/i,100).toFixed(1))&&(l="99.9")}else r==c.COMPLETE&&(l="100");l&&(o+=" "+(l+="%"),a.style.width=l)}!function(t,e){t&&(t.innerHTML=e||"")}(s,o)}},over:function(t){t&&t.box&&i(t.box,"u-over")}},c.extend(c.UI.Image)}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.Uploader.UI.File.js b/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.Uploader.UI.File.js new file mode 100644 index 000000000..e6c9ad29a --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.Uploader.UI.File.js @@ -0,0 +1,3 @@ +//devin87@qq.com +//build:2017/08/23 11:31:56 +!function(e,i){"use strict";function s(e,i){e.className+=" "+i}function a(e,i){e&&(e.innerHTML=i||"")}var t=Q.def,d=Q.getFirst,l=Q.getLast,v=Q.getNext,c=Q.createEle,o=Q.formatSize,n=Q.event,r=n.add,u=Q.Uploader,f=u.Lang;u.UI.File={init:function(){var e=this.ops.view;e&&s(e,"ui-file "+(this.html5?"html5":"html4"))},draw:function(e){var i=this,s=i.ops,a=s.view;if(a){var v=s.button||{},o=t(f.cancel||v.cancel,"取消"),n=t(f.remove||v.remove,"删除"),u=e.name,p='
          '+u+'
          ',h=e.id,m=c("div","u-item",p);m.taskId=h,e.box=m,a.appendChild(m);var x=l(m.childNodes[1]),g=d(x),Q=l(x);r(g,"click",function(){i.cancel(h)}),r(Q,"click",function(){i.remove(h),a.removeChild(m)}),i.update(e)}},update:function(e){if(e&&e.box){var s=e.total||e.size,t=e.loaded,l=e.state,c=e.box,n=c.childNodes[1],r=d(n),f=v(r),p=v(f),h=d(p),m=v(p),x=v(m);if(a(x,u.getStatusText(l)),!(0>s)){var g="";if(this.html5&&t!=i&&t>=0){var Q;if(l==u.PROCESSING){var b=Math.min(100*t/s,100);Q=b.toFixed(1),"100.0"==Q&&(Q="99.9")}else l==u.COMPLETE&&(Q="100");Q&&(Q+="%",h.style.width=Q,a(m,Q)),g=''+o(t)+" / ";var w=e.avgSpeed||e.speed;a(f,o(w)+"/s")}g+=''+o(s)+"",a(r,g)}}},over:function(e){e&&e.box&&s(e.box,"u-over")}},u.extend(u.UI.File)}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.Uploader.UI.Image.js b/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.Uploader.UI.Image.js new file mode 100644 index 000000000..9be82b36f --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.Uploader.UI.Image.js @@ -0,0 +1,3 @@ +//devin87@qq.com +//build:2017/08/23 11:31:57 +!function(e,t){"use strict";function i(e,t){e.className+=" "+t}function a(e,t){e&&(e.innerHTML=t||"")}function r(t,i){var a=e.URL||e.webkitURL;if(a)return i(a.createObjectURL(t));if(e.FileReader){var r=new FileReader;r.onload=function(e){i(e.target.result)},r.readAsDataURL(t)}else t.readAsDataURL&&i(t.readAsDataURL())}function n(e,i,a){var n=i.input,o=i.file||(n.files?n.files[0]:t);if(o)r(o,function(t){t&&(e.innerHTML=''),a&&a(t)});else if(n){var s=n.value;if(s&&!/^\w:\\fakepath/.test(s)||(n.select(),parent.document.body.focus(),document.selection&&(s=document.selection.createRange().text)),s){e.innerHTML='';try{g>6&&(e.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod='scale',src='"+s+"')")}catch(l){}}a&&a(s)}}function o(e){var t=e.slice(1);return"image/"+("jpg"==t?"jpeg":t)}function s(e,t){for(var i=e.split(","),a=atob(i[1]),r=[],n=0,o=a.length;o>n;n++)r[n]=a.charCodeAt(n);if(v)return new v([new Uint8Array(r)],{type:t});var s=new h;return s.append(r),s.getBlob(t)}function l(e,t,i,a){var r=new Image;r.src=e,r.onload=function(){var e=r.width,n=r.height,o=i.maxWidth,s=i.maxHeight,l=o&&e>o,c=s&&n>s,u=l||c;if(!u)return a&&a(!1);l&&(e=o,n=Math.floor(r.height*e/r.width)),c&&(n=s,e=Math.floor(r.width*n/r.height));var d=document.createElement("canvas"),f=d.getContext("2d");d.width=e,d.height=n,f.drawImage(r,0,0,e,n),a&&a(d.toDataURL(t),t)}}var c=Q.getFirst,u=Q.getNext,d=Q.createEle,f=Q.setOpacity,g=Q.ie,p=Q.Uploader,v=e.Blob||e.WebkitBlob||e.MozBlob,h=e.WebKitBlobBuilder||e.MozBlobBuilder,m=function(){if(!e.FileReader||!e.atob||!v&&!h)return!1;var t=document.createElement("canvas");return!!t.getContext&&!!t.getContext("2d")}(),b=".jpg,.png,.gif,.bmp,.webp,.tif,.tiff",w=".jpg";p.support.imageScale=m,p.previewImage=n,p.scaleImage=l,p.UI.Image={init:function(){var e=this.ops,t=e.view;e.allows||(e.allows=b),t&&i(t,"ui-image "+(this.html5?"html5":"html4"))},supportScale:function(e){if(!m)return!1;".jpeg"==e&&(e=".jpg");var t=(this.ops.scale||{}).types||w,i=-1!=b.indexOf(e);return i?"*"==t||-1!=t.indexOf(e):!1},previewImage:function(e,t,i){var a=this,r=t.scale||i.scale,c=r&&a.supportScale(t.ext);return c&&(t.skip=!0),n(e,t,function(e){a.fire("preview",{task:t,src:e}),e&&c&&l(e,o(t.ext),r,function(e,i){if(e){var r=s(e,i);t.blob=r,a.fire("scale",{task:t,base64:e,type:i,blob:r})}t.skip=!1,a.list.push(t),a.auto&&a.start()})}),a},draw:function(e){var t=this,i=t.ops,a=i.view;if(a){var r=e.name,n='
          '+r+"
          ",o=e.id,s=d("div","u-item",n);s.taskId=o;var l=c(s),g=u(l),p=c(g),v=u(g);f(g,.3),f(p,.5),e.box=s,e.boxProgress=p,e.boxDetail=v,a.appendChild(s),t.previewImage(l,e,i).update(e)}},update:function(e){if(e&&e.box){var i=this,r=e.total||e.size,n=e.loaded,o=e.state,s=e.boxProgress,l=e.boxDetail,c=p.getStatusText(o);if(i.html5&&n!=t&&n>=0){var u;if(o==p.PROCESSING){var d=Math.min(100*n/r,100);u=d.toFixed(1),"100.0"==u&&(u="99.9")}else o==p.COMPLETE&&(u="100");u&&(u+="%",c+=" "+u,s.style.width=u)}a(l,c)}},over:function(e){e&&e.box&&i(e.box,"u-over")}},p.extend(p.UI.Image)}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.Uploader.js b/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.Uploader.js new file mode 100644 index 000000000..aaaeeddf8 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.Uploader.js @@ -0,0 +1,3 @@ +//devin87@qq.com +//build:2017/12/04 15:05:00 +!function(t,e){"use strict";function i(t,e){var i=t.lastIndexOf(e);return-1!=i?t.slice(i):""}function s(t){if(t){for(var e=t.split(","),i={},s=0,a=e.length;s
          ');i.appendChild(r);var n=u(r),o=l(r);t.iframe=n,t.form=o,function(t,e){t.attachEvent?t.attachEvent("onload",e):t.addEventListener("load",e,!1)}(n,function(){if(0==t.workerIdle){var e;try{e=n.contentWindow.document.body.innerHTML}catch(t){}t.complete(void 0,b,e)}})}return t.targets.forEach(function(e){t.clickTrigger?g(e,"click",function(e){!1!==t.fire("select",e)&&(t.resetInput(),_(t.inputFile,"click"))}):g(e,"mouseover",function(e){t.target=this,t.updatePos()})}),t.clickTrigger||(g(s,"click",function(e){!1===t.fire("select",e)&&y(e)}),p(s,0),t.resetInput()),t.fire("init"),t.run("init")}},resetInput:function(){var t=this,e=t.boxInput;e.innerHTML='";var i=u(e);return g(i,"change",function(e){t.add(this),t.html5||t.resetInput()}),t.inputFile=i,t.updatePos()},updatePos:function(t){if(this.clickTrigger)return this;var e=this.getPos||f,i=this.boxInput,s=u(i),a=this.target,r=a.offsetWidth,n=a.offsetHeight,o=0==r?{left:-1e4,top:-1e4}:e(a);return i.style.width=s.style.width=r+"px",i.style.height=s.style.height=n+"px",i.style.left=o.left+"px",i.style.top=o.top+"px",t&&(i.style.zIndex=++I),this},fire:function(t,e,i){if(!i)return n(this.fns[t],this,e);var s=this.fns[t+"Async"];if(s)return n(s,this,e,i);i(n(this.fns[t],this,e))},run:function(t,e){var i=this[t];return i&&n(i,this,e),this},addTask:function(t,e){if(t||e){var s,a;e?(s=e.name||e.fileName,a=e.size||e.fileSize):(s=i(t.value,"\\").slice(1)||t.value,a=-1);var r,n=this,o=i(s,".").toLowerCase();n.disallows&&n.disallows[o]||n.allows&&!n.allows[o]?r="ext":-1!=a&&n.maxSize&&a>n.maxSize&&(r="size");var u={id:++x,name:s,ext:o,size:a,input:t,file:e,state:r?z:E};return r&&(u.limited=r,u.disabled=!0),n.fire("add",u,function(t){!1===t||u.disabled||u.limited||(u.index=n.list.length,n.list.push(u),n.map[u.id]=u,n.run("draw",u),n.auto&&n.start())}),u}},add:function(t){if("INPUT"==t.tagName){var e=t.files;if(e)for(var i=0,s=e.length;i=s||t<=0)return this;var a=e[i];return this.index++,this.upload(a)},upload:function(t){var e=this;return!t||t.state!=E||t.skip?e.start():(t.url=e.url,e.workerIdle--,e.fire("upload",t,function(i){if(!1===i)return e.complete(t,z);e.html5&&t.file?e._upload_html5_ready(t):t.input?e._upload_html4(t):e.complete(t,z)}),e)},queryState:function(t,e){var i=this,s=i.url,a=new XMLHttpRequest;return t.queryUrl=s+(-1==s.indexOf("?")?"?":"&")+"action=query&hash="+(t.hash||encodeURIComponent(t.name))+"&fileName="+encodeURIComponent(t.name),i.fire("sliceQuery",t),a.open("GET",t.queryUrl),a.onreadystatechange=function(){if(4==a.readyState){var s,r;if(a.status>=200&&a.status<400)if("ok"===(s=a.responseText)?r={ret:1}:s&&(r=d(s)),r&&"number"!=typeof r||(r={ret:0,start:r}),t.response=s,t.json=r,1==r.ret)t.queryOK=!0,i.cancel(t.id,!0).complete(t,b);else{var o=+r.start||0;o!=Math.floor(o)&&(o=0),t.sliceStart=o}n(e,i,a)}},a.onerror=function(){n(e,i,a)},a.send(null),i},_upload_html5_ready:function(t){var e=this,i=function(){t.state!=b&&(e.isSlice?e._upload_slice(t):e._upload_html5(t))},s=function(i){e.fire("hash",t,function(){t.hash&&e.isQueryState&&t.state!=b?e.queryState(t,i):i()})},a=function(i){if(e.isMd5&&m){var a=e.fns.hashProgress;m(t.file,function(e,a){t.hash=e,t.timeHash=a,s(i)},function(i){n(a,e,t,i)})}else s(i)};return e.isUploadAfterHash?a(i):(i(),a()),e},_process_params:function(t,e){this.data&&Object.forEach(this.data,e),t.data&&Object.forEach(t.data,e)},_upload_html5:function(t){var e=this,i=new XMLHttpRequest;t.xhr=i,i.upload.addEventListener("progress",function(i){e.progress(t,i.total,i.loaded)},!1),i.addEventListener("load",function(i){e.complete(t,b,i.target.responseText)},!1),i.addEventListener("error",function(){e.complete(t,N)},!1),i.addEventListener("abort",function(){e.complete(t,M)},!1);var s=new FormData;e._process_params(t,function(t,e){s.append(t,e)}),s.append("fileName",t.name),s.append(e.upName,t.blob||t.file,t.name),i.open("POST",t.url),e.fire("send",t,function(a){if(!1===a)return e.complete(t,z);i.send(s),e._afterSend(t)})},_upload_html4:function(t){var e=this,i=e.form,s=t.input;if(s._uploaded)return e.complete(t,b);s._uploaded=!0,s.name=e.upName,i.innerHTML="",i.appendChild(s),i.action=t.url,e._process_params(t,function(t,e){i.appendChild(c(''))}),e.fire("send",t,function(s){if(!1===s)return e.complete(t,z);i.submit(),e._afterSend(t)})},_afterSend:function(t){t.lastTime=t.startTime=Date.now(),t.state=L,this._lastTask=t,this.progress(t)},progress:function(t,e,i){e||(e=t.size),(!i||i<0)&&(i=0);var s=t.state||E;i>e&&(i=e),i>0&&s==E&&(t.state=s=L);s==b&&(e=i=t.size),function(t,e,i){if(e&&!(e<=0)){var s,a=Date.now();if(i>=e)return(s=a-t.startTime)?t.avgSpeed=Math.min(Math.round(1e3*e/s),e):t.speed||(t.avgSpeed=t.speed=e),t.time=s||0,void(t.endTime=a);(s=a-t.lastTime)<200||(t.speed=Math.min(Math.round(1e3*(i-t.loaded)/s),t.total),t.lastTime=a)}}(t,e,i),t.total=e,t.loaded=i,this.fire("progress",t),this.run("update",t)},_process_response:function(t,e){t.response=e,e&&"json"==this.dataType&&(t.json=d(e))},complete:function(t,e,i){return t||1!=this.workerThread||(t=this._lastTask),t&&(void 0!=e&&(t.state=e),t.state!=L&&e!=b||(t.state=b,this.progress(t,t.size,t.size)),void 0!==i&&this._process_response(t,i)),this.run("update",t).run("over",t),e==M&&this.fire("cancel",t),this.fire("complete",t),this.workerIdle++,this.started&&this.start(),this}},a.extend=function(t,e){o(a.prototype,t,e)},function(){var e=t.XMLHttpRequest;e&&(new e).upload&&t.FormData&&(T=!0);var i=document.createElement("input");i.type="file",w=!!i.files,k=T}(),o(a,{support:{html5:T,multiple:w},READY:E,PROCESSING:L,COMPLETE:b,SKIP:z,CANCEL:M,ERROR:N,UI:{},Lang:{status_ready:"准备中",status_processing:"上传中",status_complete:"已完成",status_skip:"已跳过",status_cancel:"已取消",status_error:"已失败"},getStatusText:function(t){var e=a.Lang;switch(t){case E:return e.status_ready;case L:return e.status_processing;case b:return e.status_complete;case z:return e.status_skip;case M:return e.status_cancel;case N:return e.status_error}return t}}),Q.Uploader=a}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.Uploader.slice.js b/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.Uploader.slice.js new file mode 100644 index 000000000..a263cbb1a --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.Uploader.slice.js @@ -0,0 +1,3 @@ +//devin87@qq.com +//build:2018/02/09 11:03:32 +!function(e,n){"use strict";var t=File.prototype.slice||File.prototype.mozSlice||File.prototype.webkitSlice,i=Q.Uploader;i.extend({_upload_slice:function(e){var n,o=this,a=e.blob||e.file,r=a.size,l=o.chunkSize,c=e.sliceStart||0;e.sliceCount=Math.ceil(r/l);var s=function(){c>=r||((n=c+l)>r&&(n=r),e.sliceStart=c,e.sliceEnd=n,e.sliceIndex=Math.ceil(n/l),e.sliceBlob=t.call(a,c,n),o.fire("sliceUpload",e,function(t){if(!1===t)return p();!function(t,a){var l=new XMLHttpRequest,s=e.url,p=n==r;e.xhr=l,s+=(-1==s.indexOf("?")?"?":"&")+"action=upload&hash="+(e.hash||e.name)+"&ok="+(p?"1":"0"),l.upload.addEventListener("progress",function(n){o.progress(e,r,c+n.loaded)},!1),l.addEventListener("load",function(n){p&&o.complete(e,i.COMPLETE,n.target.responseText),a()},!1),l.addEventListener("error",function(){o.complete(e,i.ERROR)},!1);var d=new FormData;p&&(o._process_params(e,function(e,n){d.append(e,n)}),d.append("fileName",e.name)),d.append(o.upName,t,e.name),l.open("POST",s),p?o.fire("send",e,function(n){if(!1===n)return o.complete(e,i.SKIP);l.send(d)}):l.send(d)}(e.sliceBlob,p)}))},p=function(){c=n,s()};s(),o._afterSend(e)}})}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.js b/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.js new file mode 100644 index 000000000..92733445a --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.js @@ -0,0 +1,3 @@ +//devin87@qq.com +//build:2017/09/22 15:04:42 +!function(t,e){"use strict";function n(t,n){return t!==e?t:n}function r(t){return"[object Function]"===N.call(t)}function i(t){return"number"==typeof t&&t>0&&t===Math.floor(t)}function o(t,e){return r(t)?t.apply(e,C.call(arguments,2)):void 0}function a(t,n,r){if(!t||!n)return t;for(var i in n)i!=e&&B.call(n,i)&&(r||t[i]===e)&&(t[i]=n[i]);return t}function l(t,e){if(e!==!1&&!/^[\],:{}\s]*$/.test(t.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,"@").replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,"]").replace(/(?:^|:|,)(?:\s*\[)+/g,"")))throw new Error("JSON SyntaxError");try{return new Function("return "+t)()}catch(n){}}function u(t,n){1>=n&&(n*=100),t.style.opacity!=e?t.style.opacity=n/100:t.style.filter!=e&&(t.style.filter="alpha(opacity="+parseInt(n)+")")}function c(t,e){var n=0,r=0,i=t.offsetWidth,o=t.offsetHeight;do n+=t.offsetLeft,r+=t.offsetTop,t=t.offsetParent;while(t&&t!=e);return{left:n,top:r,width:i,height:o}}function f(t,e,n,r){for(var i=t[n||e],o=[];i;){if(1==i.nodeType){if(!r)return i;o.push(i)}i=i[e]}return r?o:null}function s(t){return t.previousElementSibling||f(t,"previousSibling",null,!1)}function p(t){return t.nextElementSibling||f(t,"nextSibling",null,!1)}function v(t){return t.firstElementChild||f(t,"nextSibling","firstChild",!1)}function d(t){return t.lastElementChild||f(t,"previousSibling","lastChild",!1)}function h(t){return t.children||f(t,"nextSibling","firstChild",!0)}function g(t,e,n){var r=document.createElement(t);return e&&(r.className=e),n&&(r.innerHTML=n),r}function E(t,e){var n=g("div","",t);return e?n.childNodes:v(n)}function m(e){var n=e||t.event;return n.target||(n.target=n.srcElement),n}function y(t,e,n,r){var i=function(o){n.call(t,m(o)),r&&j(t,e,i)};return H(t,e,i),r?void 0:{stop:function(){j(t,e,i)}}}function b(t,e){if(r(t[e]))t[e]();else if(t.fireEvent)t.fireEvent("on"+e);else if(t.dispatchEvent){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}}function x(t,e,n){var r=m(t);e!==!1&&(r.preventDefault?r.preventDefault():r.returnValue=!1),n!==!1&&(r.stopPropagation?r.stopPropagation():r.cancelBubble=!0)}function S(t){return F.test(t)}function O(t){if(!S(t))return!0;var n=RegExp.lastMatch.length,r=t.indexOf("/",n),i=t.slice(0,-1!=r?r:e);return i.toLowerCase()==(location.protocol+"//"+location.host).toLowerCase()}function w(t,e,n){t=+t,e=e||1024;for(var r=0,o="number"==typeof e,a=1,l=i(n)?n:o?100:e.length;t>=a&&l>r;)a*=o?e:e[r],r++;return r&&a>t&&(a/=o?e:e.last(),r--),{value:r?t/a:t,level:r}}function L(t,r){if(r=r===!0?{all:!0}:r||{},isNaN(t)||t==e||0>t){var i=r.error||"--";return r.all?{text:i}:i}var o=w(t,r.steps,r.limit),a=o.value,l=a.toFixed(n(r.digit,2));return r.trim!==!1&&-1!=l.lastIndexOf(".")&&(l=l.replace(/\.?0+$/,"")),o.text=l+(r.join||"")+(r.units||P)[o.level+(r.start||0)],r.all?o:o.text}var N=Object.prototype.toString,B=Object.prototype.hasOwnProperty,C=Array.prototype.slice;a(Object,{forEach:function(t,e,n){for(var r in t)B.call(t,r)&&e.call(n,r,t[r],t)}}),a(Array.prototype,{forEach:function(t,e){for(var n=this,r=0,i=n.length;i>r;r++)r in n&&t.call(e,n[r],r,n)}}),a(Date,{now:function(){return+new Date}});var M;(t.ActiveXObject||t.msIndexedDB)&&(M=document.documentMode||(t.XMLHttpRequest?7:6)),t.JSON||(t.JSON={}),JSON.parse||(JSON.parse=l);var H,j;document.addEventListener?(H=function(t,e,n){t.addEventListener(e,n,!1)},j=function(t,e,n){t.removeEventListener(e,n,!1)}):document.attachEvent&&(H=function(t,e,n){t.attachEvent("on"+e,n)},j=function(t,e,n){t.detachEvent("on"+e,n)});var F=/^https?:\/\//i,P=["B","KB","MB","GB","TB","PB","EB"],T={def:n,isFunc:r,isUInt:i,fire:o,extend:a,ie:M,setOpacity:u,getOffset:c,walk:f,getPrev:s,getNext:p,getFirst:v,getLast:d,getChilds:h,createEle:g,parseHTML:E,isHttpURL:S,isSameHost:O,parseLevel:w,formatSize:L};M&&(T["ie"+(6>M?6:M)]=!0),T.event={fix:m,stop:x,trigger:b,add:y},t.Q=T}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.md5File.js b/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.md5File.js new file mode 100644 index 000000000..a8479bad7 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/Q.md5File.js @@ -0,0 +1,3 @@ +//devin87@qq.com +//build:2016/06/17 13:31:24 +!function(e,r){"use strict";function t(e,r,t){function a(){var r=p*n,t=r+n>=l?l:r+n;f.readAsArrayBuffer(i.call(e,r,t))}var l=e.size,c=Math.ceil(l/n),p=0,f=new FileReader,u=Date.now();o.reset(),f.onload=function(e){o.append(e.target.result),p++,t&&t(p/c),c>p?a():r&&r(o.end(),Date.now()-u)},f.onerror=r,a()}if(e.SparkMD5&&e.File){var i=File.prototype.slice||File.prototype.mozSlice||File.prototype.webkitSlice,o=new SparkMD5.ArrayBuffer,n=2097152;Q.md5File=t}}(window); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/spark-md5.js b/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/spark-md5.js new file mode 100644 index 000000000..ac44053a8 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/assets/web-uploader/js/spark-md5.js @@ -0,0 +1,3 @@ +//spark-md5 v2.0.2 https://github.com/satazor/js-spark-md5 +//build:2016/06/16 14:06:36 +!function(t){if("object"==typeof exports)module.exports=t();else if("function"==typeof define&&define.amd)define(t);else{var r;try{r=window}catch(n){r=self}r.SparkMD5=t()}}(function(t){"use strict";function r(t,r,n,e,f,i){return r=d(d(r,t),d(e,i)),d(r<>>32-f,n)}function n(t,n,e,f,i,h,o){return r(n&e|~n&f,t,n,i,h,o)}function e(t,n,e,f,i,h,o){return r(n&f|e&~f,t,n,i,h,o)}function f(t,n,e,f,i,h,o){return r(n^e^f,t,n,i,h,o)}function i(t,n,e,f,i,h,o){return r(e^(n|~f),t,n,i,h,o)}function h(t,r){var h=t[0],o=t[1],u=t[2],s=t[3];h=n(h,o,u,s,r[0],7,-680876936),s=n(s,h,o,u,r[1],12,-389564586),u=n(u,s,h,o,r[2],17,606105819),o=n(o,u,s,h,r[3],22,-1044525330),h=n(h,o,u,s,r[4],7,-176418897),s=n(s,h,o,u,r[5],12,1200080426),u=n(u,s,h,o,r[6],17,-1473231341),o=n(o,u,s,h,r[7],22,-45705983),h=n(h,o,u,s,r[8],7,1770035416),s=n(s,h,o,u,r[9],12,-1958414417),u=n(u,s,h,o,r[10],17,-42063),o=n(o,u,s,h,r[11],22,-1990404162),h=n(h,o,u,s,r[12],7,1804603682),s=n(s,h,o,u,r[13],12,-40341101),u=n(u,s,h,o,r[14],17,-1502002290),o=n(o,u,s,h,r[15],22,1236535329),h=e(h,o,u,s,r[1],5,-165796510),s=e(s,h,o,u,r[6],9,-1069501632),u=e(u,s,h,o,r[11],14,643717713),o=e(o,u,s,h,r[0],20,-373897302),h=e(h,o,u,s,r[5],5,-701558691),s=e(s,h,o,u,r[10],9,38016083),u=e(u,s,h,o,r[15],14,-660478335),o=e(o,u,s,h,r[4],20,-405537848),h=e(h,o,u,s,r[9],5,568446438),s=e(s,h,o,u,r[14],9,-1019803690),u=e(u,s,h,o,r[3],14,-187363961),o=e(o,u,s,h,r[8],20,1163531501),h=e(h,o,u,s,r[13],5,-1444681467),s=e(s,h,o,u,r[2],9,-51403784),u=e(u,s,h,o,r[7],14,1735328473),o=e(o,u,s,h,r[12],20,-1926607734),h=f(h,o,u,s,r[5],4,-378558),s=f(s,h,o,u,r[8],11,-2022574463),u=f(u,s,h,o,r[11],16,1839030562),o=f(o,u,s,h,r[14],23,-35309556),h=f(h,o,u,s,r[1],4,-1530992060),s=f(s,h,o,u,r[4],11,1272893353),u=f(u,s,h,o,r[7],16,-155497632),o=f(o,u,s,h,r[10],23,-1094730640),h=f(h,o,u,s,r[13],4,681279174),s=f(s,h,o,u,r[0],11,-358537222),u=f(u,s,h,o,r[3],16,-722521979),o=f(o,u,s,h,r[6],23,76029189),h=f(h,o,u,s,r[9],4,-640364487),s=f(s,h,o,u,r[12],11,-421815835),u=f(u,s,h,o,r[15],16,530742520),o=f(o,u,s,h,r[2],23,-995338651),h=i(h,o,u,s,r[0],6,-198630844),s=i(s,h,o,u,r[7],10,1126891415),u=i(u,s,h,o,r[14],15,-1416354905),o=i(o,u,s,h,r[5],21,-57434055),h=i(h,o,u,s,r[12],6,1700485571),s=i(s,h,o,u,r[3],10,-1894986606),u=i(u,s,h,o,r[10],15,-1051523),o=i(o,u,s,h,r[1],21,-2054922799),h=i(h,o,u,s,r[8],6,1873313359),s=i(s,h,o,u,r[15],10,-30611744),u=i(u,s,h,o,r[6],15,-1560198380),o=i(o,u,s,h,r[13],21,1309151649),h=i(h,o,u,s,r[4],6,-145523070),s=i(s,h,o,u,r[11],10,-1120210379),u=i(u,s,h,o,r[2],15,718787259),o=i(o,u,s,h,r[9],21,-343485551),t[0]=d(h,t[0]),t[1]=d(o,t[1]),t[2]=d(u,t[2]),t[3]=d(s,t[3])}function o(t){var r,n=[];for(r=0;64>r;r+=4)n[r>>2]=t.charCodeAt(r)+(t.charCodeAt(r+1)<<8)+(t.charCodeAt(r+2)<<16)+(t.charCodeAt(r+3)<<24);return n}function u(t){var r,n=[];for(r=0;64>r;r+=4)n[r>>2]=t[r]+(t[r+1]<<8)+(t[r+2]<<16)+(t[r+3]<<24);return n}function s(t){var r,n,e,f,i,u,s=t.length,a=[1732584193,-271733879,-1732584194,271733878];for(r=64;s>=r;r+=64)h(a,o(t.substring(r-64,r)));for(t=t.substring(r-64),n=t.length,e=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],r=0;n>r;r+=1)e[r>>2]|=t.charCodeAt(r)<<(r%4<<3);if(e[r>>2]|=128<<(r%4<<3),r>55)for(h(a,e),r=0;16>r;r+=1)e[r]=0;return f=8*s,f=f.toString(16).match(/(.*?)(.{0,8})$/),i=parseInt(f[2],16),u=parseInt(f[1],16)||0,e[14]=i,e[15]=u,h(a,e),a}function a(t){var r,n,e,f,i,o,s=t.length,a=[1732584193,-271733879,-1732584194,271733878];for(r=64;s>=r;r+=64)h(a,u(t.subarray(r-64,r)));for(t=s>r-64?t.subarray(r-64):new Uint8Array(0),n=t.length,e=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],r=0;n>r;r+=1)e[r>>2]|=t[r]<<(r%4<<3);if(e[r>>2]|=128<<(r%4<<3),r>55)for(h(a,e),r=0;16>r;r+=1)e[r]=0;return f=8*s,f=f.toString(16).match(/(.*?)(.{0,8})$/),i=parseInt(f[2],16),o=parseInt(f[1],16)||0,e[14]=i,e[15]=o,h(a,e),a}function p(t){var r,n="";for(r=0;4>r;r+=1)n+=v[t>>8*r+4&15]+v[t>>8*r&15];return n}function y(t){var r;for(r=0;rn;n+=1)i[n]=t.charCodeAt(n);return r?i:f}function b(t){return String.fromCharCode.apply(null,new Uint8Array(t))}function g(t,r,n){var e=new Uint8Array(t.byteLength+r.byteLength);return e.set(new Uint8Array(t)),e.set(new Uint8Array(r),t.byteLength),n?e:e.buffer}function _(t){var r,n=[],e=t.length;for(r=0;e-1>r;r+=2)n.push(parseInt(t.substr(r,2),16));return String.fromCharCode.apply(String,n)}function A(){this.reset()}var d=function(t,r){return t+r&4294967295},v=["0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"];return"5d41402abc4b2a76b9719d911017c592"!==y(s("hello"))&&(d=function(t,r){var n=(65535&t)+(65535&r),e=(t>>16)+(r>>16)+(n>>16);return e<<16|65535&n}),"undefined"==typeof ArrayBuffer||ArrayBuffer.prototype.slice||!function(){function r(t,r){return t=0|t||0,0>t?Math.max(t+r,0):Math.min(t,r)}ArrayBuffer.prototype.slice=function(n,e){var f,i,h,o,u=this.byteLength,s=r(n,u),a=u;return e!==t&&(a=r(e,u)),s>a?new ArrayBuffer(0):(f=a-s,i=new ArrayBuffer(f),h=new Uint8Array(i),o=new Uint8Array(this,s,f),h.set(o),i)}}(),A.prototype.append=function(t){return this.appendBinary(c(t)),this},A.prototype.appendBinary=function(t){this._buff+=t,this._length+=t.length;var r,n=this._buff.length;for(r=64;n>=r;r+=64)h(this._hash,o(this._buff.substring(r-64,r)));return this._buff=this._buff.substring(r-64),this},A.prototype.end=function(t){var r,n,e=this._buff,f=e.length,i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(r=0;f>r;r+=1)i[r>>2]|=e.charCodeAt(r)<<(r%4<<3);return this._finish(i,f),n=y(this._hash),t&&(n=_(n)),this.reset(),n},A.prototype.reset=function(){return this._buff="",this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},A.prototype.getState=function(){return{buff:this._buff,length:this._length,hash:this._hash}},A.prototype.setState=function(t){return this._buff=t.buff,this._length=t.length,this._hash=t.hash,this},A.prototype.destroy=function(){delete this._hash,delete this._buff,delete this._length},A.prototype._finish=function(t,r){var n,e,f,i=r;if(t[i>>2]|=128<<(i%4<<3),i>55)for(h(this._hash,t),i=0;16>i;i+=1)t[i]=0;n=8*this._length,n=n.toString(16).match(/(.*?)(.{0,8})$/),e=parseInt(n[2],16),f=parseInt(n[1],16)||0,t[14]=e,t[15]=f,h(this._hash,t)},A.hash=function(t,r){return A.hashBinary(c(t),r)},A.hashBinary=function(t,r){var n=s(t),e=y(n);return r?_(e):e},A.ArrayBuffer=function(){this.reset()},A.ArrayBuffer.prototype.append=function(t){var r,n=g(this._buff.buffer,t,!0),e=n.length;for(this._length+=t.byteLength,r=64;e>=r;r+=64)h(this._hash,u(n.subarray(r-64,r)));return this._buff=e>r-64?new Uint8Array(n.buffer.slice(r-64)):new Uint8Array(0),this},A.ArrayBuffer.prototype.end=function(t){var r,n,e=this._buff,f=e.length,i=[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];for(r=0;f>r;r+=1)i[r>>2]|=e[r]<<(r%4<<3);return this._finish(i,f),n=y(this._hash),t&&(n=_(n)),this.reset(),n},A.ArrayBuffer.prototype.reset=function(){return this._buff=new Uint8Array(0),this._length=0,this._hash=[1732584193,-271733879,-1732584194,271733878],this},A.ArrayBuffer.prototype.getState=function(){var t=A.prototype.getState.call(this);return t.buff=b(t.buff),t},A.ArrayBuffer.prototype.setState=function(t){return t.buff=l(t.buff,!0),A.prototype.setState.call(this,t)},A.ArrayBuffer.prototype.destroy=A.prototype.destroy,A.ArrayBuffer.prototype._finish=A.prototype._finish,A.ArrayBuffer.hash=function(t,r){var n=a(new Uint8Array(t)),e=y(n);return r?_(e):e},A}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/connect/authorize.cshtml b/net452/SiteServer.Web/SiteServer/connect/authorize.cshtml new file mode 100644 index 000000000..229cbc6f0 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/connect/authorize.cshtml @@ -0,0 +1,2 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Scripts{ + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/connect/authorize.js b/net452/SiteServer.Web/SiteServer/connect/authorize.js new file mode 100644 index 000000000..979a56572 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/connect/authorize.js @@ -0,0 +1,47 @@ +var $url = '/pages/cloud/authorize'; + +var $data = { + pageLoad: false, + pageAlert: null +}; + +var $methods = { + load: function () { + var $this = this; + + $ssApi.post($ssUrlLogin, { + account: $this.account, + password: md5($this.password), + isAutoLogin: $this.isAutoLogin + }).then(function (response) { + var res = response.data; + + top.location.reload(); + + // $api.post($url, { + // userName: res.value.userName, + // accessToken: res.accessToken, + // expiresAt: res.expiresAt + // }).then(function (response) { + // var res = response.data; + + // location.href = utils.getQueryString('returnUrl') || 'dashboard.cshtml'; + // }).catch(function (error) { + // utils.loading(false); + // $this.pageAlert = utils.getPageAlert(error); + // }); + }).catch(function (error) { + utils.loading(false); + $this.pageAlert = utils.getPageAlert(error); + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.load(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/connect/dashboard.cshtml b/net452/SiteServer.Web/SiteServer/connect/dashboard.cshtml new file mode 100644 index 000000000..7d3d12a58 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/connect/dashboard.cshtml @@ -0,0 +1,136 @@ +@{ Layout = "../Shared/_Layout.cshtml"; }
          +
          + +
          +
          + +
          +
          +

          连接

          +
          +
          +
          +
          +
          +
          +

          站点连接

          +
          + +
          +
          +
          + user +
          +
          您的站点已连接至 WordPress.com。 您是 Jetpack 所有者。
          +
          +
          +
          + Card link + Another link +
          +
          +
          +
          +
          +
          +

          账户连接

          +
          +
          + 退出 +
          +
          +
          +
          + user +
          +
          已使用 {{ userName }} 的身份进行连接。
          + starlying@gmail.com +
          +
          +
          +
          +
          +
          +

          安全性

          +
          +
          +
          +
          +
          +
          +

          安全扫描

          +
          + +
          +
          +
          + user +
          +
          为了自动全面地扫描安全威胁,请 升级您的帐户
          +
          +
          +
          +
          +
          +
          +
          +
          +

          安全扫描

          +
          + +
          +
          +
          + user +
          +
          为了自动全面地扫描安全威胁,请 升级您的帐户
          +
          +
          +
          +
          +
          +
          +
          +
          +

          文件实时同步

          +
          + +
          +
          +
          + user +
          +
          将系统内的所有文件夹及文件实时同步上传至SiteServer CMS云端,在其他服务器通过 + siteserver.exe命令行工具实时监测更新并下载文件到本机。
          +
          +
          +
          +
          +
          +
          @section Scripts{ + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/connect/dashboard.js b/net452/SiteServer.Web/SiteServer/connect/dashboard.js new file mode 100644 index 000000000..a390b0a53 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/connect/dashboard.js @@ -0,0 +1,49 @@ +var $url = '/pages/cloud/dashboard'; + +var $data = { + pageLoad: false, + pageAlert: null, + userName: null, + accessToken: null, +}; + +var $methods = { + load: function () { + var $this = this; + + $api.get($url).then(function (response) { + var res = response.data; + + $this.userName = res.value; + $this.accessToken = res.accessToken; + $this.pageLoad = true; + }).catch(function (error) { + location.href = 'login.cshtml'; + }); + + + // $ssApi.get($url).then(function (response) { + // var res = response.data; + + // $this.userInfo = res.value; + // }).catch(function (error) { + // $this.pageAlert = utils.getPageAlert(error); + + // if (error.response && error.response.status === 401) { + // ssUtils.redirectToLogin(); + // } + // }).then(function () { + // $this.pageLoad = true; + // }); + + } +} + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.load(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/connect/index.cshtml b/net452/SiteServer.Web/SiteServer/connect/index.cshtml new file mode 100644 index 000000000..45d0272f9 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/connect/index.cshtml @@ -0,0 +1,97 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Scripts{ + + }
          +
          +
          +
          +

          管理员登录

          +
          + +
          +
          + +
          +

          SiteServer CMS 云连接

          +

          将CMS系统与云计算相结合,利用大规模的云计算基础设施,发挥CMS系统的最大价值

          +
          +
          请使用超级管理员身份登录
          +
          + +
          +
          +
          +
          + + + +
          + +
          +
          +
          +
          +
          +
          +
          + + + +
          + +
          +
          +
          +
          +
          +
          +
          + + + +
          + +
          +
          +
          +
          +
          +
          +
          + + + +
          +
          +
          +
          +

          开启云连接即表示,您同意遵守服务条款,并将某些数据和设置同步至 SITESERVER.CN +

          + +
          +
          +
          + +
          +
          +
          +
          +
          \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/connect/index.js b/net452/SiteServer.Web/SiteServer/connect/index.js new file mode 100644 index 000000000..3ae776aba --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/connect/index.js @@ -0,0 +1,151 @@ +var $guid = utils.getQueryString('guid'); + +var $urlLogin = '/pages/connect/index/actions/login'; +var $urlConnect = '/pages/connect/index/actions/connect'; +var $urlGetCaptcha = '/v1/captcha/LOGIN-CAPTCHA'; +var $urlCheckCaptcha = '/v1/captcha/LOGIN-CAPTCHA/actions/check'; + +var $data = { + pageLoad: false, + pageAlert: null, + pageSubmit: false, + account: null, + password: null, + captcha: null, + captchaUrl: null, + isNightlyUpdate: null, + apiPrefix: null, + adminDirectory: null, + homeDirectory: null, + secretKey: null, + cmsVersion: null, + pluginVersion: null, + apiVersion: null, + adminName: null, + adminToken: null, + repositoryOwner: null, + repositoryName: null, + repositoryToken: null +}; + +var $methods = { + reload: function () { + this.pageLoad = true; + this.captcha = ''; + this.pageSubmit = false; + this.captchaUrl = $apiUrl + $urlGetCaptcha + '?r=' + new Date().getTime(); + }, + + apiCheckCaptcha: function () { + var $this = this; + + utils.loading(true); + $api.post($urlCheckCaptcha, { + captcha: $this.captcha + }).then(function (response) { + $this.apiLogin(); + }).catch(function (error) { + utils.loading(false); + $this.reload(); + $this.pageAlert = utils.getPageAlert(error); + }); + }, + + apiLogin: function () { + var $this = this; + + $api.post($urlLogin, { + account: $this.account, + password: md5($this.password) + }).then(function (response) { + var res = response.data; + + $this.isNightlyUpdate = res.isNightlyUpdate; + $this.apiPrefix = res.apiPrefix; + $this.adminDirectory = res.adminDirectory; + $this.homeDirectory = res.homeDirectory; + $this.secretKey = res.secretKey; + $this.cmsVersion = res.cmsVersion; + $this.pluginVersion = res.pluginVersion; + $this.apiVersion = res.apiVersion; + $this.adminName = res.adminName; + $this.adminToken = res.adminToken; + + $this.ssApiConnect(); + }).catch(function (error) { + utils.loading(false); + $this.pageAlert = utils.getPageAlert(error); + }); + }, + + ssApiConnect: function () { + var $this = this; + + $ssApi.post($ssUrlConnections, { + guid: $guid, + isNightlyUpdate: $this.isNightlyUpdate, + apiPrefix: $this.apiPrefix, + adminDirectory: $this.adminDirectory, + homeDirectory: $this.homeDirectory, + secretKey: $this.secretKey, + cmsVersion: $this.cmsVersion, + pluginVersion: $this.pluginVersion, + apiVersion: $this.apiVersion, + adminName: $this.adminName, + adminToken: $this.adminToken + }).then(function (response) { + var res = response.data; + + $this.repositoryOwner = res.repositoryOwner; + $this.repositoryName = res.repositoryName; + $this.repositoryToken = res.repositoryToken; + + $this.apiConnect(); + }).catch(function (error) { + utils.loading(false); + $this.pageAlert = utils.getPageAlert(error); + }); + }, + + apiConnect: function () { + var $this = this; + + $api.post($urlConnect, { + repositoryOwner: $this.repositoryOwner, + repositoryName: $this.repositoryName, + repositoryToken: $this.repositoryToken + }).then(function (response) { + var res = response.data; + + location.href = ssUtils.getConnectUrl($guid); + }).catch(function (error) { + utils.loading(false); + $this.pageAlert = utils.getPageAlert(error); + }); + }, + + btnConnectClick: function (e) { + e.preventDefault(); + + this.pageSubmit = true; + this.pageAlert = null; + if (!this.account || !this.password || !this.captcha) return; + this.apiCheckCaptcha(); + } +} + +new Vue({ + el: '#main', + data: $data, + directives: { + focus: { + inserted: function (el) { + el.focus() + } + } + }, + methods: $methods, + created: function () { + this.reload(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/connect/layerLogin.cshtml b/net452/SiteServer.Web/SiteServer/connect/layerLogin.cshtml new file mode 100644 index 000000000..1c8165424 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/connect/layerLogin.cshtml @@ -0,0 +1,77 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Styles { }
          +
          云服务
          +
          +
          + + +
          +
          +
          +
          + +
          + +
          +
          +
          +
          +
          +
          +
          + +
          + +
          +
          +
          +
          +
          +
          +
          + +
          + +
          +
          +
          +
          +
          +
          + + +
          +
          +
          + + + +
          +
          +
          +
          + +
          +
          +
          + + +
          +
          @section Scripts{ + + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/connect/layerLogin.js b/net452/SiteServer.Web/SiteServer/connect/layerLogin.js new file mode 100644 index 000000000..eb5c56fdb --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/connect/layerLogin.js @@ -0,0 +1,113 @@ +var $url = "/pages/cloud/layerLogin"; + +var $data = { + pageLoad: false, + pageSubmit: false, + pageAlert: null, + account: null, + password: null, + isAutoLogin: false, + captcha: null, + captchaUrl: null +}; + +var $methods = { + load: function() { + this.reload(); + this.pageLoad = true; + }, + + reload: function() { + this.captcha = ""; + this.pageSubmit = false; + this.captchaUrl = + $ssApiUrl + "/" + $ssUrlCaptchaGet + "?r=" + new Date().getTime(); + }, + + checkCaptcha: function() { + var $this = this; + + utils.loading(true); + $ssApi + .post($ssUrlCaptchaCheck, { + captcha: $this.captcha + }) + .then(function(response) { + var res = response.data; + + $this.login(); + }) + .catch(function(error) { + $this.pageAlert = utils.getPageAlert(error); + }) + .then(function() { + utils.loading(false); + $this.reload(); + }); + }, + + login: function() { + var $this = this; + + utils.loading(true); + $ssApi + .post($ssUrlLogin, { + account: $this.account, + password: md5($this.password), + isAutoLogin: $this.isAutoLogin + }) + .then(function(response) { + var res = response.data; + + top.location.reload(); + + // $api.post($url, { + // userName: res.value.userName, + // accessToken: res.accessToken, + // expiresAt: res.expiresAt + // }).then(function (response) { + // var res = response.data; + + // location.href = utils.getQueryString('returnUrl') || 'dashboard.cshtml'; + // }).catch(function (error) { + // utils.loading(false); + // $this.pageAlert = utils.getPageAlert(error); + // }); + }) + .catch(function(error) { + utils.loading(false); + $this.pageAlert = utils.getPageAlert(error); + }); + }, + + btnLoginClick: function(e) { + e.preventDefault(); + + this.pageSubmit = true; + this.pageAlert = null; + if (!this.account || !this.password || !this.captcha) return; + this.checkCaptcha(); + }, + + btnRegisterClick: function() { + location.href = + "register.cshtml?returnUrl=" + + (utils.getQueryString("returnUrl") || "login.cshtml"); + } +}; + +new Vue({ + el: "#main", + data: $data, + directives: { + focus: { + inserted: function(el) { + el.focus(); + } + } + }, + methods: $methods, + created: function() { + this.load(); + } +}); diff --git a/net452/SiteServer.Web/SiteServer/connect/login.cshtml b/net452/SiteServer.Web/SiteServer/connect/login.cshtml new file mode 100644 index 000000000..ccd45678f --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/connect/login.cshtml @@ -0,0 +1,80 @@ +@{ Layout = "../Shared/_Layout.cshtml"; }
          +
          +
          +
          {{ pageConfig.homeTitle }}
          +
          +
          + + +
          +
          +
          +
          + +
          + +
          +
          +
          +
          +
          +
          +
          + +
          + +
          +
          +
          +
          +
          +
          +
          + +
          + +
          +
          +
          +
          +
          +
          + + +
          +
          +
          + + + +
          +
          +
          +
          + +
          +
          +
          + + +
          +
          +
          +
          @section Scripts{ + + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/connect/login.js b/net452/SiteServer.Web/SiteServer/connect/login.js new file mode 100644 index 000000000..d95b74a5d --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/connect/login.js @@ -0,0 +1,139 @@ +var $url = "/pages/cloud/login"; + +var $data = { + pageLoad: false, + pageConfig: null, + pageSubmit: false, + pageAlert: null, + account: null, + password: null, + isAutoLogin: false, + captcha: null, + captchaUrl: null +}; + +var $methods = { + load: function() { + var $this = this; + $ssApi + .get($ssUrlHome + "?pageName=login") + .then(function(response) { + var res = response.data; + + $this.pageConfig = res.config; + if ( + $this.pageConfig.isHomeBackground && + $this.pageConfig.homeBackgroundUrl + ) { + $("body").css({ + "background-image": + "url(" + $this.pageConfig.homeBackgroundUrl + ")", + "background-size": "cover" + }); + } + $this.reload(); + }) + .catch(function(error) { + $this.pageAlert = utils.getPageAlert(error); + }) + .then(function() { + $this.pageLoad = true; + }); + }, + + reload: function() { + this.captcha = ""; + this.pageSubmit = false; + this.captchaUrl = + $ssApiUrl + "/" + $ssUrlCaptchaGet + "?r=" + new Date().getTime(); + }, + + checkCaptcha: function() { + var $this = this; + + utils.loading(true); + $ssApi + .post($ssUrlCaptchaCheck, { + captcha: $this.captcha + }) + .then(function(response) { + var res = response.data; + + $this.login(); + }) + .catch(function(error) { + $this.pageAlert = utils.getPageAlert(error); + }) + .then(function() { + utils.loading(false); + $this.reload(); + }); + }, + + login: function() { + var $this = this; + + utils.loading(true); + $ssApi + .post($ssUrlLogin, { + account: $this.account, + password: md5($this.password), + isAutoLogin: $this.isAutoLogin + }) + .then(function(response) { + var res = response.data; + + $api + .post($url, { + userName: res.value.userName, + accessToken: res.accessToken, + expiresAt: res.expiresAt + }) + .then(function(response) { + var res = response.data; + + location.href = + utils.getQueryString("returnUrl") || "dashboard.cshtml"; + }) + .catch(function(error) { + utils.loading(false); + $this.pageAlert = utils.getPageAlert(error); + }); + }) + .catch(function(error) { + utils.loading(false); + $this.pageAlert = utils.getPageAlert(error); + }); + }, + + btnLoginClick: function(e) { + e.preventDefault(); + + this.pageSubmit = true; + this.pageAlert = null; + if (!this.account || !this.password || !this.captcha) return; + this.checkCaptcha(); + }, + + btnRegisterClick: function() { + location.href = + "register.cshtml?returnUrl=" + + (utils.getQueryString("returnUrl") || "login.cshtml"); + } +}; + +new Vue({ + el: "#main", + data: $data, + directives: { + focus: { + inserted: function(el) { + el.focus(); + } + } + }, + methods: $methods, + created: function() { + this.load(); + } +}); diff --git a/net452/SiteServer.Web/SiteServer/connect/logout.cshtml b/net452/SiteServer.Web/SiteServer/connect/logout.cshtml new file mode 100644 index 000000000..762d63d8e --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/connect/logout.cshtml @@ -0,0 +1,2 @@ +@{ Layout = "../Shared/_Layout.cshtml"; } @section Scripts{ + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/connect/logout.js b/net452/SiteServer.Web/SiteServer/connect/logout.js new file mode 100644 index 000000000..b1df4b4f4 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/connect/logout.js @@ -0,0 +1,37 @@ +var $url = '/pages/cloud/logout'; + +var $data = { + pageLoad: false, + pageAlert: null +}; + +var $methods = { + logout: function () { + + $ssApi.post($ssUrlLogout).then(function (response) { + var res = response.data; + + top.location.reload(); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }); + + // $api.post($url).then(function (response) { + // var res = response.data; + + // location.href = utils.getQueryString('returnUrl') || 'login.cshtml'; + // }).catch(function (error) { + // $this.pageLoad = true; + // $this.pageAlert = utils.getPageAlert(error); + // }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.logout(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/connect/register.cshtml b/net452/SiteServer.Web/SiteServer/connect/register.cshtml new file mode 100644 index 000000000..ed9bf733e --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/connect/register.cshtml @@ -0,0 +1,141 @@ + + + + + + SiteServer CMS - 用户中心 + + + + + + + + + + + + + + +
          + + +
          + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/connect/register.js b/net452/SiteServer.Web/SiteServer/connect/register.js new file mode 100644 index 000000000..ac56a547a --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/connect/register.js @@ -0,0 +1,152 @@ +var $api = new utils.Api('/v1/users'); +var $captchaGetUrl = utils.getApiUrl('/v1/captcha/REGISTER-CAPTCHA'); +var $captchaCheckApi = new utils.Api('/v1/captcha/REGISTER-CAPTCHA/actions/check'); + +if (window.top != self) { + window.top.location = self.location; +} + +var $data = { + pageConfig: null, + pageAlert: null, + userName: null, + password: null, + captcha: null, + captchaUrl: null, + styles: [], + groups: [], + groupId: 0, + isAgreement: false +}; + +var $methods = { + load: function (pageConfig, styles, groups) { + this.pageConfig = pageConfig; + if (this.pageConfig.isHomeBackground && this.pageConfig.homeBackgroundUrl) { + $('body').css({ + 'background-image': 'url(' + this.pageConfig.homeBackgroundUrl + ')', + 'background-size': 'cover' + }); + } + + if (this.pageConfig.userRegistrationAttributes) { + var userRegistrationAttributes = this.pageConfig.userRegistrationAttributes.split(','); + for (var i = 0; i < styles.length; i++) { + var style = styles[i]; + if (userRegistrationAttributes.indexOf(style.attributeName) !== -1) { + style.value = style.defaultValue; + + this.styles.push(style); + } + } + } + + this.groups = groups; + this.reload(); + }, + reload: function () { + this.captcha = ''; + this.captchaUrl = $captchaGetUrl + '?r=' + new Date().getTime(); + }, + checkCaptcha: function () { + var $this = this; + + utils.loading(true); + $captchaCheckApi.post({ + captcha: $this.captcha + }, function (err) { + utils.loading(false); + + if (err) { + $this.reload(); + $this.pageAlert = { + type: 'danger', + html: err.message + }; + return; + } + + $this.register(); + }); + }, + register: function () { + var $this = this; + + var payload = { + userName: this.userName, + password: this.password, + groupId: this.groupId + }; + for (var i = 0; i < this.styles.length; i++) { + var style = this.styles[i]; + payload[style.attributeName] = style.value; + } + + utils.loading(true); + $api.post(payload, function (err, res) { + utils.loading(false); + if (err) { + $this.reload(); + $this.pageAlert = { + type: 'danger', + html: err.message + }; + return; + } + + if (res.value.isChecked) { + swal2({ + title: "恭喜,账号注册成功", + type: "success", + confirmButtonText: "进入登录页" + }).then(function () { + location.href = 'login.cshtml?returnUrl=' + (utils.getQueryString('returnUrl') || '../index.cshtml'); + }); + } else { + swal2({ + title: "账号注册成功,请等待管理员审核", + type: "success", + confirmButtonText: "进入登录页" + }).then(function () { + location.href = 'login.cshtml?returnUrl=' + (utils.getQueryString('returnUrl') || '../index.cshtml'); + }); + } + }); + }, + btnRegisterClick: function (e) { + e.preventDefault(); + this.pageAlert = null; + + var $this = this; + this.$validator.validate().then(function (result) { + if ($this.pageConfig.isHomeAgreement && !$this.isAgreement) { + return $this.pageAlert = { + type: 'danger', + html: '请勾选' + $this.pageConfig.homeAgreementHtml + }; + } + if (result) { + $this.checkCaptcha(); + } + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + directives: { + focus: { + inserted: function (el) { + el.focus() + } + } + }, + methods: $methods, + created: function () { + var $this = this; + utils.getConfig('register', function (res) { + $this.load(res.config, res.styles, res.groups); + }); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/dashboard.cshtml b/net452/SiteServer.Web/SiteServer/dashboard.cshtml new file mode 100644 index 000000000..91a1e90c8 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/dashboard.cshtml @@ -0,0 +1,44 @@ +@{ Layout = "./Shared/_Layout.cshtml"; } +
          +

          欢迎使用 SiteServer CMS 管理后台

          +
          +
          +
          +

          {{ version }}

          +

          当前版本

          +
          +
          +
          +
          +

          {{ updateDate }}

          +

          最近升级时间

          +
          +
          +
          +
          +

          {{ lastActivityDate }}

          +

          上次登录时间

          +
          +
          +
          +
          +
          待审核内容
          +

          共有 {{ unCheckedListTotalCount }} 篇内容待审核

          + +
          +
          @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/dashboard.js b/net452/SiteServer.Web/SiteServer/dashboard.js new file mode 100644 index 000000000..5e514ab48 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/dashboard.js @@ -0,0 +1,58 @@ +var $url = "/pages/dashboard"; +var $urlUnCheckedList = "/pages/dashboard/unCheckedList"; + +var $data = { + pageLoad: false, + pageAlert: null, + version: null, + lastActivityDate: null, + updateDate: null, + unCheckedList: null, + unCheckedListTotalCount: 0 +}; + +var $methods = { + load: function () { + var $this = this; + + $api.get($url).then(function (response) { + var res = response.data; + + $this.version = res.value.version; + $this.lastActivityDate = res.value.lastActivityDate; + $this.updateDate = res.value.updateDate; + + $this.getUnCheckedList(); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + getUnCheckedList: function () { + var $this = this; + + $api.get($urlUnCheckedList).then(function (response) { + var res = response.data; + + $this.unCheckedList = res.value; + for (i = 0; i < $this.unCheckedList.length; i++) { + $this.unCheckedListTotalCount += $this.unCheckedList[i].count; + } + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + utils.loading(false); + }); + } +}; + +new Vue({ + el: "#main", + data: $data, + methods: $methods, + created: function () { + this.load(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/default.aspx b/net452/SiteServer.Web/SiteServer/default.aspx new file mode 100644 index 000000000..acf3d4687 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/default.aspx @@ -0,0 +1,2 @@ +<%@ Page Language="C#" %> +<%Page.Response.Redirect("main.cshtml", false);%> \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/error.cshtml b/net452/SiteServer.Web/SiteServer/error.cshtml new file mode 100644 index 000000000..0f88804b6 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/error.cshtml @@ -0,0 +1,20 @@ +@{ Layout = "./Shared/_Layout.cshtml"; } +
          +
          + 错误信息 +
          +
          +

          +

          +

          +
          + +
          @section Scripts{ + } diff --git a/net452/SiteServer.Web/SiteServer/error.js b/net452/SiteServer.Web/SiteServer/error.js new file mode 100644 index 000000000..f2e02880e --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/error.js @@ -0,0 +1,54 @@ +var $url = "/pages/error"; + +var $data = { + pageLoad: false, + pageAlert: null, + logId: utils.getQueryString('logId'), + message: utils.getQueryString('message'), + stacktrace: null, + addDate: null +}; + +var $methods = { + loadError: function () { + var $this = this; + if (!$this.logId) { + $this.pageLoad = true; + return; + } + + $api.get($url, { + params: { + logId: $this.logId + } + }).then(function (response) { + var res = response.data; + + $this.message = res.logInfo.summary + ' ' + res.logInfo.message; + $this.stacktrace = res.logInfo.stacktrace; + $this.addDate = res.logInfo.addDate; + $this.reportError(res.logInfo, res.version); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + reportError: function (logInfo, version) { + if (!logInfo) return; + Rollbar.error(logInfo.summary + ' ' + logInfo.message, { + version: version, + stacktrace: logInfo.stacktrace + }); + } +}; + +var $vue = new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.loadError(); + } +}); \ No newline at end of file diff --git a/SiteServer.Web/SiteServer/images/avatar.jpg b/net452/SiteServer.Web/SiteServer/images/avatar.jpg similarity index 100% rename from SiteServer.Web/SiteServer/images/avatar.jpg rename to net452/SiteServer.Web/SiteServer/images/avatar.jpg diff --git a/SiteServer.Web/SiteServer/images/bg_repno.gif b/net452/SiteServer.Web/SiteServer/images/bg_repno.gif similarity index 100% rename from SiteServer.Web/SiteServer/images/bg_repno.gif rename to net452/SiteServer.Web/SiteServer/images/bg_repno.gif diff --git a/SiteServer.Web/SiteServer/images/collapsed-group.jpg b/net452/SiteServer.Web/SiteServer/images/collapsed-group.jpg similarity index 100% rename from SiteServer.Web/SiteServer/images/collapsed-group.jpg rename to net452/SiteServer.Web/SiteServer/images/collapsed-group.jpg diff --git a/SiteServer.Web/SiteServer/images/expanded-group.jpg b/net452/SiteServer.Web/SiteServer/images/expanded-group.jpg similarity index 100% rename from SiteServer.Web/SiteServer/images/expanded-group.jpg rename to net452/SiteServer.Web/SiteServer/images/expanded-group.jpg diff --git a/SiteServer.Web/SiteServer/images/loading.gif b/net452/SiteServer.Web/SiteServer/images/loading.gif similarity index 100% rename from SiteServer.Web/SiteServer/images/loading.gif rename to net452/SiteServer.Web/SiteServer/images/loading.gif diff --git a/SiteServer.Web/SiteServer/images/loading2.gif b/net452/SiteServer.Web/SiteServer/images/loading2.gif similarity index 100% rename from SiteServer.Web/SiteServer/images/loading2.gif rename to net452/SiteServer.Web/SiteServer/images/loading2.gif diff --git a/SiteServer.Web/SiteServer/images/m1.png b/net452/SiteServer.Web/SiteServer/images/m1.png similarity index 100% rename from SiteServer.Web/SiteServer/images/m1.png rename to net452/SiteServer.Web/SiteServer/images/m1.png diff --git a/SiteServer.Web/SiteServer/images/m2.png b/net452/SiteServer.Web/SiteServer/images/m2.png similarity index 100% rename from SiteServer.Web/SiteServer/images/m2.png rename to net452/SiteServer.Web/SiteServer/images/m2.png diff --git a/SiteServer.Web/SiteServer/images/m3.png b/net452/SiteServer.Web/SiteServer/images/m3.png similarity index 100% rename from SiteServer.Web/SiteServer/images/m3.png rename to net452/SiteServer.Web/SiteServer/images/m3.png diff --git a/SiteServer.Web/SiteServer/images/minus.png b/net452/SiteServer.Web/SiteServer/images/minus.png similarity index 100% rename from SiteServer.Web/SiteServer/images/minus.png rename to net452/SiteServer.Web/SiteServer/images/minus.png diff --git a/SiteServer.Web/SiteServer/images/navigationBg.png b/net452/SiteServer.Web/SiteServer/images/navigationBg.png similarity index 100% rename from SiteServer.Web/SiteServer/images/navigationBg.png rename to net452/SiteServer.Web/SiteServer/images/navigationBg.png diff --git a/SiteServer.Web/SiteServer/images/plus.png b/net452/SiteServer.Web/SiteServer/images/plus.png similarity index 100% rename from SiteServer.Web/SiteServer/images/plus.png rename to net452/SiteServer.Web/SiteServer/images/plus.png diff --git a/SiteServer.Web/SiteServer/images/siteserver.png b/net452/SiteServer.Web/SiteServer/images/siteserver.png similarity index 100% rename from SiteServer.Web/SiteServer/images/siteserver.png rename to net452/SiteServer.Web/SiteServer/images/siteserver.png diff --git a/SiteServer.Web/SiteServer/images/sorting-asc.png b/net452/SiteServer.Web/SiteServer/images/sorting-asc.png similarity index 100% rename from SiteServer.Web/SiteServer/images/sorting-asc.png rename to net452/SiteServer.Web/SiteServer/images/sorting-asc.png diff --git a/SiteServer.Web/SiteServer/images/sorting-desc.png b/net452/SiteServer.Web/SiteServer/images/sorting-desc.png similarity index 100% rename from SiteServer.Web/SiteServer/images/sorting-desc.png rename to net452/SiteServer.Web/SiteServer/images/sorting-desc.png diff --git a/SiteServer.Web/SiteServer/images/sorting.png b/net452/SiteServer.Web/SiteServer/images/sorting.png similarity index 100% rename from SiteServer.Web/SiteServer/images/sorting.png rename to net452/SiteServer.Web/SiteServer/images/sorting.png diff --git a/SiteServer.Web/SiteServer/images/upai_icons.png b/net452/SiteServer.Web/SiteServer/images/upai_icons.png similarity index 100% rename from SiteServer.Web/SiteServer/images/upai_icons.png rename to net452/SiteServer.Web/SiteServer/images/upai_icons.png diff --git a/net452/SiteServer.Web/SiteServer/index.aspx b/net452/SiteServer.Web/SiteServer/index.aspx new file mode 100644 index 000000000..acf3d4687 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/index.aspx @@ -0,0 +1,2 @@ +<%@ Page Language="C#" %> +<%Page.Response.Redirect("main.cshtml", false);%> \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/loading.aspx b/net452/SiteServer.Web/SiteServer/loading.aspx new file mode 100644 index 000000000..a48523e8e --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/loading.aspx @@ -0,0 +1,2 @@ +<%@ Page Language="C#" %> +<% Page.Response.Redirect("loading.cshtml", false); %> \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/loading.cshtml b/net452/SiteServer.Web/SiteServer/loading.cshtml new file mode 100644 index 000000000..105b7f76b --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/loading.cshtml @@ -0,0 +1,6 @@ +@{ Layout = "./Shared/_Layout.cshtml"; } @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/loading.js b/net452/SiteServer.Web/SiteServer/loading.js new file mode 100644 index 000000000..7276b9e22 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/loading.js @@ -0,0 +1,45 @@ +var $url = '/pages/loading'; + +var $data = { + pageLoad: false, + pageAlert: null, + redirectUrl: utils.getQueryString('redirectUrl'), + encryptedUrl: utils.getQueryString('encryptedUrl'), + siteId: utils.getQueryString('siteId'), + channelId: utils.getQueryString('channelId'), + contentId: utils.getQueryString('contentId'), + fileTemplateId: utils.getQueryString('fileTemplateId'), + specialId: utils.getQueryString('specialId') +}; + +var $methods = { + load: function () { + var $this = this; + + $api.post($url, { + redirectUrl: $this.redirectUrl, + encryptedUrl: $this.encryptedUrl, + siteId: $this.siteId, + channelId: $this.channelId, + contentId: $this.contentId, + fileTemplateId: $this.fileTemplateId, + specialId: $this.specialId + }).then(function (response) { + var res = response.data; + + location.href = res.value; + }).catch(function (error) { + $this.pageLoad = true; + $this.pageAlert = utils.getPageAlert(error); + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.load(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/login.aspx b/net452/SiteServer.Web/SiteServer/login.aspx new file mode 100644 index 000000000..c47e7eeb5 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/login.aspx @@ -0,0 +1,2 @@ +<%@ Page Language="C#" %> +<% Page.Response.Redirect("login.cshtml", false); %> \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/login.cshtml b/net452/SiteServer.Web/SiteServer/login.cshtml new file mode 100644 index 000000000..998b4c9b0 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/login.cshtml @@ -0,0 +1,86 @@ +@{ Layout = "./Shared/_Layout.cshtml"; } @section Styles{ } +
          +
          +

          管理员登录

          +
          + +
          +
          +
          +
          + + + +
          + +
          +
          +
          +
          +
          +
          +
          + + + +
          + +
          +
          +
          +
          +
          +
          +
          + + + +
          + +
          +
          +
          +
          +
          +
          + + +
          +
          +
          + + + +
          +
          +
          +
          + +
          +
          +
          + +
          +
          +
          @section Scripts{ + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/login.js b/net452/SiteServer.Web/SiteServer/login.js new file mode 100644 index 000000000..1fece36cf --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/login.js @@ -0,0 +1,107 @@ +if (window.top != self) { + window.top.location = self.location; +} + +var $url = "/pages/login"; +var $urlLogin = '/v1/administrators/actions/login'; +var $urlGetCaptcha = '/v1/captcha/LOGIN-CAPTCHA'; +var $urlCheckCaptcha = '/v1/captcha/LOGIN-CAPTCHA/actions/check'; +var $redirectUrl = utils.getQueryString("redirectUrl"); + +var $data = { + pageLoad: false, + pageSubmit: false, + pageAlert: null, + account: null, + password: null, + isAutoLogin: false, + captcha: null, + captchaUrl: null +}; + +var $methods = { + load: function () { + var $this = this; + + $api.get($url).then(function (response) { + var res = response.data; + + if (res.value) { + $this.reload(); + } else { + location.href = res.redirectUrl; + } + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + reload: function () { + this.pageLoad = true; + this.captcha = ''; + this.pageSubmit = false; + this.captchaUrl = $apiUrl + $urlGetCaptcha + '?r=' + new Date().getTime(); + }, + + checkCaptcha: function () { + var $this = this; + + utils.loading(true); + $api.post($urlCheckCaptcha, { + captcha: $this.captcha + }).then(function (response) { + $this.login(); + }).catch(function (error) { + utils.loading(false); + $this.reload(); + $this.pageAlert = utils.getPageAlert(error); + }); + }, + + login: function () { + var $this = this; + + $api.post($urlLogin, { + account: $this.account, + password: md5($this.password), + isAutoLogin: $this.isAutoLogin + }).then(function (response) { + $this.redirect(); + }).catch(function (error) { + utils.loading(false); + $this.reload(); + $this.pageAlert = utils.getPageAlert(error); + }); + }, + + redirect: function () { + location.href = $redirectUrl || 'main.cshtml'; + }, + + btnLoginClick: function (e) { + e.preventDefault(); + + this.pageSubmit = true; + this.pageAlert = null; + if (!this.account || !this.password || !this.captcha) return; + this.checkCaptcha(); + } +}; + +var $vue = new Vue({ + el: '#main', + data: $data, + directives: { + focus: { + inserted: function (el) { + el.focus() + } + } + }, + methods: $methods, + created: function () { + this.load(); + } +}); diff --git a/net452/SiteServer.Web/SiteServer/logout.aspx b/net452/SiteServer.Web/SiteServer/logout.aspx new file mode 100644 index 000000000..2d17b3828 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/logout.aspx @@ -0,0 +1,2 @@ +<%@ Page Language="C#" %> +<% Page.Response.Redirect("logout.cshtml", false); %> \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/logout.cshtml b/net452/SiteServer.Web/SiteServer/logout.cshtml new file mode 100644 index 000000000..117aa7b6c --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/logout.cshtml @@ -0,0 +1,6 @@ +@{ Layout = "./Shared/_Layout.cshtml"; } @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/logout.js b/net452/SiteServer.Web/SiteServer/logout.js new file mode 100644 index 000000000..62cc9016e --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/logout.js @@ -0,0 +1,30 @@ +var $url = '/v1/administrators/actions/logout'; + +var $data = { + pageLoad: false, + pageAlert: null +}; + +var $methods = { + logout: function () { + var $this = this; + + $api.post($url).then(function (response) { + var res = response.data; + + window.top.location.href = 'login.cshtml'; + }).catch(function (error) { + $this.pageLoad = true; + $this.pageAlert = utils.getPageAlert(error); + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.logout(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/main.cshtml b/net452/SiteServer.Web/SiteServer/main.cshtml new file mode 100644 index 000000000..3596bf60c --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/main.cshtml @@ -0,0 +1,259 @@ + + + + + + SiteServer CMS - 管理后台 + + + + + + + + + + + + +
          + + + +
          + + + + + + + + + + + + + + + + diff --git a/net452/SiteServer.Web/SiteServer/main.js b/net452/SiteServer.Web/SiteServer/main.js new file mode 100644 index 000000000..b489f4170 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/main.js @@ -0,0 +1,299 @@ +if (window.top != self) { + window.top.location = self.location; +} + +function redirect(url) { + $("#right").src = url; +} + +function openPageCreateStatus() { + utils.openLayer({ + title: "生成进度查看", + url: "cms/createStatus.cshtml?siteId=" + $siteId, + full: true + }); + return false; +} + +function reloadPage() { + document.getElementById("frmMain").contentWindow.location.reload(true); +} + +var $url = "/pages/main"; +var $urlCreate = "/pages/main/actions/create"; +var $urlDownload = "/pages/main/actions/download"; +var $packageIdSsCms = "SS.CMS"; +var $siteId = parseInt(utils.getQueryString("siteId") || "0"); +var $pageUrl = utils.getQueryString("pageUrl"); + +var $data = { + pageLoad: false, + pageAlert: null, + defaultPageUrl: null, + isNightlyUpdate: null, + pluginVersion: null, + isSuperAdmin: null, + packageList: null, + packageIds: null, + cmsVersion: null, + apiPrefix: null, + adminDirectory: null, + homeDirectory: null, + topMenus: null, + siteMenus: null, + activeParentMenu: null, + activeChildMenu: null, + pluginMenus: null, + adminInfo: null, + newVersion: null, + updatePackages: [], + status: {}, + pendingCount: 0, + lastExecuteTime: new Date(), + timeoutId: null, + winHeight: 0, + winWidth: 0, + isDesktop: true, + isMobileMenu: false +}; + +var $methods = { + getConfig: function () { + var $this = this; + + $api.post($url, { + siteId: $siteId, + pageUrl: $pageUrl + }).then(function (response) { + var res = response.data; + if (res.value) { + $this.defaultPageUrl = res.defaultPageUrl; + $this.isNightlyUpdate = res.isNightlyUpdate; + $this.pluginVersion = res.pluginVersion; + $this.isSuperAdmin = res.isSuperAdmin; + $this.packageList = res.packageList; + $this.packageIds = res.packageIds; + $this.cmsVersion = res.cmsVersion; + $this.apiPrefix = res.apiPrefix; + $this.adminDirectory = res.adminDirectory; + $this.homeDirectory = res.homeDirectory; + $this.topMenus = res.topMenus; + $this.siteMenus = res.siteMenus; + $this.pluginMenus = res.pluginMenus; + $this.adminInfo = res.adminInfo; + $this.activeParentMenu = $this.siteMenus[0]; + $this.pageLoad = true; + setTimeout($this.ready, 100); + } else { + location.href = res.redirectUrl; + } + }).catch(function (error) { + if (error.response.status === 401) { + location.href = 'login.cshtml'; + } else if (error.response.status === 500) { + $this.pageAlert = utils.getPageAlert(error); + } + }); + }, + + ready: function () { + var $this = this; + + window.onresize = $this.winResize; + window.onresize(); + + $this.create(); + + setInterval(function () { + var dif = new Date().getTime() - $this.lastExecuteTime.getTime(); + var minutes = dif / 1000 / 60; + if (minutes > 2) { + $this.create(); + } + }, 60000); + + $("#sidebar").slimScroll({ + height: "auto", + position: "right", + size: "5px", + color: "#495057", + wheelStep: 5 + }); + + $this.connect(); + }, + + connect: function () { + var $this = this; + $ssApi + .post($ssUrlConnect, { + url: location.href, + apiPrefix: $this.apiPrefix, + isNightlyUpdate: $this.isNightlyUpdate, + pluginVersion: $this.pluginVersion, + packageIds: $this.isSuperAdmin ? $this.packageIds.join(",") : '' + }) + .then(function (response) { + var res = response.data; + + $this.status = res.value; + + if (res.updates && res.updates.length > 0) { + for (var i = 0; i < res.updates.length; i++) { + var releaseInfo = res.updates[i]; + if (!releaseInfo || !releaseInfo.version) continue; + if (releaseInfo.pluginId == $packageIdSsCms) { + $this.downloadSsCms(releaseInfo); + } else { + var installedPackages = _.filter($this.packageList, function (o) { + return o.id == releaseInfo.pluginId; + }); + if (installedPackages.length == 1) { + var installedPackage = installedPackages[0]; + if (installedPackage.version) { + if ( + compareversion( + installedPackage.version, + releaseInfo.version + ) == -1 + ) { + $this.updatePackages.push( + _.assign({}, { + cmsVersion: installedPackage.version + }, + releaseInfo + ) + ); + } + } else { + $this.updatePackages.push( + _.assign({}, { + cmsVersion: installedPackage.version + }, + releaseInfo + ) + ); + } + } + } + } + } + }); + }, + + downloadSsCms: function (releaseInfo) { + var $this = this; + if (compareversion($this.cmsVersion, releaseInfo.version) != -1) return; + + $api + .post($urlDownload, { + packageId: $packageIdSsCms, + version: releaseInfo.version + }) + .then(function (response) { + var res = response.data; + + if (res.value) { + $this.newVersion = { + version: releaseInfo.version, + published: releaseInfo.published, + releaseNotes: releaseInfo.releaseNotes + }; + } + }); + }, + + create: function () { + var $this = this; + clearTimeout($this.timeoutId); + $api + .post($urlCreate) + .then(function (response) { + var res = response.data; + + $this.pendingCount = res.value; + if ($this.pendingCount === 0) { + $this.timeoutId = setTimeout($this.create, 10000); + } else { + $this.timeoutId = setTimeout($this.create, 100); + } + }) + .catch(function (error) { + if (error.response && error.response.status === 401) { + location.href = "login.cshtml"; + } + $this.timeoutId = setTimeout($this.create, 1000); + }) + .then(function () { + $this.lastExecuteTime = new Date(); + }); + }, + + winResize: function () { + this.winHeight = $(window).height(); + this.winWidth = $(window).width(); + this.isDesktop = this.winWidth > 992; + }, + + getHref: function (menu) { + return menu.href && menu.target != "_layer" ? menu.href : "javascript:;"; + }, + + getTarget: function (menu) { + return menu.target ? menu.target : "right"; + }, + + btnCloudLoginClick: function () { + utils.openLayer({ + title: "云服务登录", + url: "cloud/layerLogin.cshtml", + width: 550, + height: 560 + }); + }, + + btnTopMenuClick: function (menu) { + if (menu.target == "_layer") { + utils.openLayer({ + title: menu.text, + url: menu.href, + full: true + }); + } + }, + + btnLeftMenuClick: function (menu) { + if (menu.hasChildren) { + this.activeParentMenu = this.activeParentMenu === menu ? null : menu; + } else { + this.activeChildMenu = menu; + this.isMobileMenu = false; + if (menu.target == "_layer") { + utils.openLayer({ + title: menu.text, + url: menu.href, + full: true + }); + } + } + }, + + btnMobileMenuClick: function () { + this.isMobileMenu = !this.isMobileMenu; + } +}; + +new Vue({ + el: "#wrapper", + data: $data, + methods: $methods, + created: function () { + this.getConfig(); + }, + computed: { + leftMenuWidth: function () { + if (this.isDesktop) return "200px"; + return this.isMobileMenu ? "100%" : "200px"; + } + } +}); diff --git a/SiteServer.Web/SiteServer/pageBlank.html b/net452/SiteServer.Web/SiteServer/pageBlank.html similarity index 100% rename from SiteServer.Web/SiteServer/pageBlank.html rename to net452/SiteServer.Web/SiteServer/pageBlank.html diff --git a/net452/SiteServer.Web/SiteServer/pageLogin.cshtml b/net452/SiteServer.Web/SiteServer/pageLogin.cshtml new file mode 100644 index 000000000..b31225eaf --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/pageLogin.cshtml @@ -0,0 +1 @@ +@{ Response.Redirect("login.cshtml"); } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/pageLogout.cshtml b/net452/SiteServer.Web/SiteServer/pageLogout.cshtml new file mode 100644 index 000000000..0e53a2631 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/pageLogout.cshtml @@ -0,0 +1 @@ +@{ Response.Redirect("logout.cshtml"); } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/pageMain.aspx b/net452/SiteServer.Web/SiteServer/pageMain.aspx new file mode 100644 index 000000000..a5aa070f1 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/pageMain.aspx @@ -0,0 +1,2 @@ +<%@ Page Language="C#" %> +<%Page.Response.Redirect("main.cshtml", false);%> \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/update.cshtml b/net452/SiteServer.Web/SiteServer/update.cshtml new file mode 100644 index 000000000..0665d2d08 --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/update.cshtml @@ -0,0 +1,74 @@ +@{ Layout = "./Shared/_Layout.cshtml"; } +
          +

          SiteServer CMS 数据库升级向导

          +

          欢迎来到SiteServer CMS 数据库升级向导!

          + +
          + +
          +

          欢迎来到SiteServer CMS 数据库升级向导!

          +

          升级向导将逐一检查数据库字段、将数据库结构更新至最新版本。

          +
          +
          +
          + +
          +
          + +
          + +
          + +
          +
          +

          正在升级数据库,请稍后...

          +
          +
          + +
          + + +
          +
          @section Scripts{ } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/update.js b/net452/SiteServer.Web/SiteServer/update.js new file mode 100644 index 000000000..f71b7c5af --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/update.js @@ -0,0 +1,41 @@ +var $url = '/pages/update'; + +var $data = { + pageLoad: false, + pageAlert: null, + step: 1 +}; + +var $methods = { + load: function () { + var $this = this; + + $api.get($url).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + btnUpdateClick: function () { + var $this = this; + + $this.step = 2; + $api.post($url).then(function (response) { + var res = response.data; + + $this.step = 3; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.load(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/upgrade.cshtml b/net452/SiteServer.Web/SiteServer/upgrade.cshtml new file mode 100644 index 000000000..16e3db4fd --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/upgrade.cshtml @@ -0,0 +1,99 @@ +@{ Layout = "./Shared/_Layout.cshtml"; } +
          +

          SiteServer CMS 升级向导

          +

          欢迎来到SiteServer CMS 升级向导!

          + + +
          +
          +
          +

          检查更新

          +

          检查 SiteServer CMS 新版本

          +
          +
          +
          + +
          +
          +

          正在检查系统更新,请稍后...

          +
          +
          +

          当前版本已经是最新版本 进入后台 +

          +
          +
          +
          发现 SiteServer CMS 新版本,请选中复选框后点击下一步开始升级
          + + + + + + + + + + + + + + + + + + + + + +
          选择已安装版本新版本更新说明发布时间
          + + + {{ installedVersion }} {{ package.version }} {{ package.releaseNotes }} {{ package.published }} + 查看发行说明 +
          +
          +
          + +
          +
          +
          +
          +
          + +
          +
          + +
          +
          +

          正在升级系统,可能需要几分钟,请稍后...

          +
          +
          + +
          + +
          +
          @section Scripts{ + + } \ No newline at end of file diff --git a/net452/SiteServer.Web/SiteServer/upgrade.js b/net452/SiteServer.Web/SiteServer/upgrade.js new file mode 100644 index 000000000..901bacfda --- /dev/null +++ b/net452/SiteServer.Web/SiteServer/upgrade.js @@ -0,0 +1,85 @@ +var $url = '/pages/upgrade'; +var $packageId = 'SS.CMS'; + +var $data = { + pageLoad: false, + pageAlert: null, + step: 1, + package: {}, + isCheck: false, + isShouldUpdate: false, + installedVersion: null, + isNightly: null, + version: null, + updatesUrl: '' +}; + +var $methods = { + load: function () { + var $this = this; + + $api.get($url).then(function (response) { + var res = response.data; + + $this.installedVersion = res.installedVersion; + $this.isNightly = res.isNightly; + $this.version = res.version; + $this.getVersion(); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }).then(function () { + $this.pageLoad = true; + }); + }, + + getVersion: function () { + var $this = this; + + $ssApi.get($ssUrlUpdates, { + params: { + isNightly: $this.isNightly, + pluginVersion: $this.version, + packageIds: $packageId + } + }).then(function (response) { + var res = response.data; + $this.package = res.value[0]; + $this.isShouldUpdate = compareversion($this.installedVersion, $this.package.version) == -1; + var major = $this.package.version.split('.')[0]; + var minor = $this.package.version.split('.')[1]; + $this.updatesUrl = ssUtils.getVersionPageUrl(major, minor); + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }); + }, + + check: function () { + this.isCheck = !this.isCheck; + }, + + updateSsCms: function () { + var $this = this; + + if (!$this.package) return; + $this.step = 2; + + $api.post($url, { + version: $this.package.version + }).then(function (response) { + var res = response.data; + + $this.step = 3; + }).catch(function (error) { + $this.pageAlert = utils.getPageAlert(error); + }); + } +}; + +new Vue({ + el: '#main', + data: $data, + methods: $methods, + created: function () { + this.load(); + } +}); \ No newline at end of file diff --git a/net452/SiteServer.Web/Startup.cs b/net452/SiteServer.Web/Startup.cs new file mode 100644 index 000000000..b94ba9136 --- /dev/null +++ b/net452/SiteServer.Web/Startup.cs @@ -0,0 +1,20 @@ +using System.Web.Hosting; +using System.Web.Http; +using Microsoft.Owin; +using Owin; +using SiteServer.API; +using SiteServer.CMS.Plugin; + +[assembly: OwinStartup(typeof(Startup))] + +namespace SiteServer.API +{ + public class Startup + { + public void Configuration(IAppBuilder app) + { + PluginManager.LoadPlugins(HostingEnvironment.ApplicationPhysicalPath); + GlobalConfiguration.Configure(WebApiConfig.Register); + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Utils/Rest.cs b/net452/SiteServer.Web/Utils/Rest.cs new file mode 100644 index 000000000..89eafca82 --- /dev/null +++ b/net452/SiteServer.Web/Utils/Rest.cs @@ -0,0 +1,610 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using SiteServer.CMS.Core; +using SiteServer.CMS.DataCache; +using SiteServer.CMS.Model; +using SiteServer.CMS.Plugin.Impl; +using SiteServer.Plugin; +using SiteServer.Utils; +using SiteServer.Utils.Auth; + +namespace SiteServer.API.Utils +{ + public class Rest : IRequest + { + private const string AuthKeyUserHeader = "X-SS-USER-TOKEN"; + private const string AuthKeyUserCookie = "SS-USER-TOKEN"; + private const string AuthKeyUserQuery = "userToken"; + public const string AuthKeyAdminHeader = "X-SS-ADMIN-TOKEN"; + private const string AuthKeyAdminCookie = "SS-ADMIN-TOKEN"; + private const string AuthKeyAdminQuery = "adminToken"; + private const string AuthKeyApiHeader = "X-SS-API-KEY"; + private const string AuthKeyApiCookie = "SS-API-KEY"; + private const string AuthKeyApiQuery = "apiKey"; + + public const int AccessTokenExpireDays = 7; + + private readonly HttpRequestMessage _request; + + public Rest(HttpRequestMessage request) + { + _request = request; + + try + { + var apiToken = ApiToken; + if (!string.IsNullOrEmpty(apiToken)) + { + var tokenInfo = AccessTokenManager.GetAccessTokenInfo(apiToken); + if (tokenInfo != null) + { + if (!string.IsNullOrEmpty(tokenInfo.AdminName)) + { + var adminInfo = AdminManager.GetAdminInfoByUserName(tokenInfo.AdminName); + if (adminInfo != null && !adminInfo.Locked) + { + AdminInfo = adminInfo; + IsAdminLoggin = true; + } + } + + IsApiAuthenticated = true; + } + } + + var userToken = UserToken; + if (!string.IsNullOrEmpty(userToken)) + { + var tokenImpl = ParseAccessToken(userToken); + if (tokenImpl.UserId > 0 && !string.IsNullOrEmpty(tokenImpl.UserName)) + { + var userInfo = UserManager.GetUserInfoByUserId(tokenImpl.UserId); + if (userInfo != null && !userInfo.IsLockedOut && userInfo.IsChecked && userInfo.UserName == tokenImpl.UserName) + { + UserInfo = userInfo; + IsUserLoggin = true; + } + } + } + + var adminToken = AdminToken; + if (!string.IsNullOrEmpty(adminToken)) + { + var tokenImpl = ParseAccessToken(adminToken); + if (tokenImpl.UserId > 0 && !string.IsNullOrEmpty(tokenImpl.UserName)) + { + var adminInfo = AdminManager.GetAdminInfoByUserId(tokenImpl.UserId); + if (adminInfo != null && !adminInfo.Locked && adminInfo.UserName == tokenImpl.UserName) + { + AdminInfo = adminInfo; + IsAdminLoggin = true; + } + } + } + } + catch (Exception ex) + { + LogUtils.AddErrorLog(ex); + } + } + + #region Request + + /// + /// Returns an individual HTTP Header value + /// + public string GetHeader(string key) + { + return !_request.Headers.TryGetValues(key, out var keys) ? null : keys.First(); + } + + /// + /// Retrieves an individual cookie from the cookies collection + /// + public string GetCookie(string cookieName) + { + var cookie = _request.Headers.GetCookies(cookieName).FirstOrDefault(); + var value = cookie?[cookieName].Value; + return TranslateUtils.DecryptStringBySecretKey(value); + } + + private Dictionary _queryDict; + private Dictionary QueryDict + { + get + { + if (_queryDict != null) return _queryDict; + + _queryDict = _request.GetQueryNameValuePairs() + .ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase); + + return _queryDict; + } + } + + public bool IsQueryExists(string name) + { + return QueryDict.ContainsKey(name); + } + + public string GetQueryString(string name) + { + if (string.IsNullOrEmpty(name)) return null; + return QueryDict.TryGetValue(name, out var value) ? value : null; + } + + public int GetQueryInt(string name, int defaultValue = 0) + { + return TranslateUtils.ToIntWithNegative(GetQueryString(name), defaultValue); + } + + public decimal GetQueryDecimal(string name, decimal defaultValue = 0) + { + return TranslateUtils.ToDecimalWithNegative(GetQueryString(name), defaultValue); + } + + public bool GetQueryBool(string name, bool defaultValue = false) + { + return TranslateUtils.ToBool(GetQueryString(name), false); + } + + private Dictionary _postDict; + private Dictionary PostDict + { + get + { + if (_postDict != null) return _postDict; + + _postDict = new Dictionary(StringComparer.OrdinalIgnoreCase); + + var json = _request.Content.ReadAsStringAsync().Result; + if (string.IsNullOrEmpty(json)) return _postDict; + + var dict = TranslateUtils.JsonDeserialize>(json); + foreach (var key in dict.Keys) + { + _postDict[key] = dict[key]; + } + + return _postDict; + } + } + + public T GetPostObject() + { + var json = _request.Content.ReadAsStringAsync().Result; + return TranslateUtils.JsonDeserialize(json); + } + + public T GetPostObject(string name) + { + var json = GetPostString(name); + return TranslateUtils.JsonDeserialize(json); + } + + public bool IsPostExists(string name) + { + return PostDict.ContainsKey(name); + } + + private object GetPostObject(string name) + { + if (string.IsNullOrEmpty(name)) return null; + return PostDict.TryGetValue(name, out var value) ? value : null; + } + + public string GetPostString(string name) + { + var value = GetPostObject(name); + switch (value) + { + case null: + return null; + case string s: + return s; + default: + return value.ToString(); + } + } + + public int GetPostInt(string name, int defaultValue = 0) + { + var value = GetPostObject(name); + switch (value) + { + case null: + return 0; + case int _: + return (int)value; + default: + return TranslateUtils.ToIntWithNegative(value.ToString(), defaultValue); + } + } + + public decimal GetPostDecimal(string name, decimal defaultValue = 0) + { + var value = GetPostObject(name); + switch (value) + { + case null: + return 0; + case decimal _: + return (decimal)value; + default: + return TranslateUtils.ToDecimalWithNegative(value.ToString(), defaultValue); + } + } + + public bool GetPostBool(string name, bool defaultValue = false) + { + var value = GetPostObject(name); + switch (value) + { + case null: + return false; + case bool _: + return (bool)value; + default: + return TranslateUtils.ToBool(value.ToString(), defaultValue); + } + } + + public DateTime GetPostDateTime(string name) + { + var value = GetPostObject(name); + switch (value) + { + case null: + return DateTime.Now; + case DateTime _: + return (DateTime)value; + default: + return TranslateUtils.ToDateTime(value.ToString()); + } + } + + #endregion + + public bool IsApiAuthenticated { get; } + + public bool IsUserLoggin { get; } + + public bool IsAdminLoggin { get; private set; } + + public string ApiToken + { + get + { + var accessTokenStr = string.Empty; + if (!string.IsNullOrEmpty(GetHeader(AuthKeyApiHeader))) + { + accessTokenStr = GetHeader(AuthKeyApiHeader); + } + else if (IsQueryExists(AuthKeyApiQuery)) + { + accessTokenStr = GetQueryString(AuthKeyApiQuery); + } + else if (!string.IsNullOrEmpty(GetCookie(AuthKeyApiCookie))) + { + accessTokenStr = GetCookie(AuthKeyApiCookie); + } + + if (StringUtils.EndsWith(accessTokenStr, TranslateUtils.EncryptStingIndicator)) + { + accessTokenStr = TranslateUtils.DecryptStringBySecretKey(accessTokenStr); + } + + return accessTokenStr; + } + } + + private string UserToken + { + get + { + var accessTokenStr = string.Empty; + if (!string.IsNullOrEmpty(GetCookie(AuthKeyUserCookie))) + { + accessTokenStr = GetCookie(AuthKeyUserCookie); + } + else if (!string.IsNullOrEmpty(GetHeader(AuthKeyUserHeader))) + { + accessTokenStr = GetHeader(AuthKeyUserHeader); + } + else if (IsQueryExists(AuthKeyUserQuery)) + { + accessTokenStr = GetQueryString(AuthKeyUserQuery); + } + + if (StringUtils.EndsWith(accessTokenStr, TranslateUtils.EncryptStingIndicator)) + { + accessTokenStr = TranslateUtils.DecryptStringBySecretKey(accessTokenStr); + } + + return accessTokenStr; + } + } + + public string AdminToken + { + get + { + var accessTokenStr = string.Empty; + if (!string.IsNullOrEmpty(GetCookie(AuthKeyAdminCookie))) + { + accessTokenStr = GetCookie(AuthKeyAdminCookie); + } + else if (!string.IsNullOrEmpty(GetHeader(AuthKeyAdminHeader))) + { + accessTokenStr = GetHeader(AuthKeyAdminHeader); + } + else if (IsQueryExists(AuthKeyAdminQuery)) + { + accessTokenStr = GetQueryString(AuthKeyAdminQuery); + } + + if (StringUtils.EndsWith(accessTokenStr, TranslateUtils.EncryptStingIndicator)) + { + accessTokenStr = TranslateUtils.DecryptStringBySecretKey(accessTokenStr); + } + + return accessTokenStr; + } + } + + public int SiteId => GetQueryInt("siteId"); + + public int ChannelId => GetQueryInt("channelId"); + + public int ContentId => GetQueryInt("contentId"); + + #region Log + + public void AddSiteLog(int siteId, string action) + { + AddSiteLog(siteId, 0, 0, action, string.Empty); + } + + public void AddSiteLog(int siteId, string action, string summary) + { + AddSiteLog(siteId, 0, 0, action, summary); + } + + public void AddSiteLog(int siteId, int channelId, string action, string summary) + { + LogUtils.AddSiteLog(siteId, channelId, 0, AdminName, action, summary); + } + + public void AddSiteLog(int siteId, int channelId, int contentId, string action, string summary) + { + LogUtils.AddSiteLog(siteId, channelId, contentId, AdminName, action, summary); + } + + public void AddAdminLog(string action, string summary) + { + LogUtils.AddAdminLog(AdminName, action, summary); + } + + public void AddAdminLog(string action) + { + LogUtils.AddAdminLog(AdminName, action); + } + + #endregion + + #region Cookie + + public void SetCookie(string name, string value) + { + CookieUtils.SetCookie(name, value); + } + + public void SetCookie(string name, string value, DateTime expires) + { + CookieUtils.SetCookie(name, value, expires); + } + + public bool IsCookieExists(string name) + { + return CookieUtils.IsExists(name); + } + + #endregion + + private PermissionsImpl _userPermissionsImpl; + + public PermissionsImpl UserPermissionsImpl + { + get + { + if (_userPermissionsImpl != null) return _userPermissionsImpl; + + var adminName = string.Empty; + if (UserInfo != null) + { + var groupInfo = UserGroupManager.GetUserGroupInfo(UserInfo.GroupId); + if (groupInfo != null) + { + adminName = groupInfo.AdminName; + } + } + + _userPermissionsImpl = new PermissionsImpl(adminName); + if (!string.IsNullOrEmpty(adminName)) + { + AdminInfo = AdminManager.GetAdminInfoByUserName(adminName); + } + + return _userPermissionsImpl; + } + } + + public IPermissions UserPermissions => UserPermissionsImpl; + + private PermissionsImpl _adminPermissionsImpl; + + public PermissionsImpl AdminPermissionsImpl + { + get + { + if (_adminPermissionsImpl != null) return _adminPermissionsImpl; + + var adminName = string.Empty; + if (AdminInfo != null) + { + adminName = AdminInfo.UserName; + } + _adminPermissionsImpl = new PermissionsImpl(adminName); + + return _adminPermissionsImpl; + } + } + + public IPermissions AdminPermissions => AdminPermissionsImpl; + + #region Administrator + + public int AdminId => AdminInfo?.Id ?? 0; + + public string AdminName + { + get + { + if (AdminInfo != null) + { + return AdminInfo.UserName; + } + + if (UserInfo != null) + { + var groupInfo = UserGroupManager.GetUserGroupInfo(UserInfo.GroupId); + if (groupInfo != null) + { + return groupInfo.AdminName; + } + } + + return string.Empty; + } + } + + public AdministratorInfo AdminInfo { get; private set; } + + public string AdminLogin(string userName, bool isAutoLogin) + { + if (string.IsNullOrEmpty(userName)) return null; + var adminInfo = AdminManager.GetAdminInfoByUserName(userName); + if (adminInfo == null || adminInfo.Locked) return null; + + AdminInfo = adminInfo; + IsAdminLoggin = true; + + var expiresAt = DateTime.Now.AddDays(AccessTokenExpireDays); + var accessToken = GetAccessToken(adminInfo.Id, adminInfo.UserName, expiresAt); + + LogUtils.AddAdminLog(adminInfo.UserName, "管理员登录"); + + if (isAutoLogin) + { + CookieUtils.SetCookie(AuthKeyAdminCookie, accessToken, expiresAt); + } + else + { + CookieUtils.SetCookie(AuthKeyAdminCookie, accessToken); + } + + return accessToken; + } + + public void AdminLogout() + { + CookieUtils.Erase(AuthKeyAdminCookie); + } + + #endregion + + #region User + + public int UserId => UserInfo?.Id ?? 0; + + public string UserName => UserInfo?.UserName ?? string.Empty; + + public UserInfo UserInfo { get; private set; } + + public string UserLogin(string userName, bool isAutoLogin) + { + if (string.IsNullOrEmpty(userName)) return null; + + var userInfo = UserManager.GetUserInfoByUserName(userName); + if (userInfo == null || userInfo.IsLockedOut || !userInfo.IsChecked) return null; + + UserInfo = userInfo; + + var expiresAt = DateTime.Now.AddDays(AccessTokenExpireDays); + var accessToken = GetAccessToken(UserId, UserName, expiresAt); + + DataProvider.UserDao.UpdateLastActivityDateAndCountOfLogin(UserInfo); + LogUtils.AddUserLoginLog(userName); + + if (isAutoLogin) + { + CookieUtils.SetCookie(AuthKeyUserCookie, accessToken, expiresAt); + } + else + { + CookieUtils.SetCookie(AuthKeyUserCookie, accessToken); + } + + return accessToken; + } + + public void UserLogout() + { + UserInfo = null; + CookieUtils.Erase(AuthKeyUserCookie); + } + + #endregion + + #region Utils + + public static string GetAccessToken(int userId, string userName, DateTime expiresAt) + { + if (userId <= 0 || string.IsNullOrEmpty(userName)) return null; + + var userToken = new AccessTokenImpl + { + UserId = userId, + UserName = userName, + ExpiresAt = expiresAt + }; + + return JsonWebToken.Encode(userToken, WebConfigUtils.SecretKey, JwtHashAlgorithm.HS256); + } + + public static AccessTokenImpl ParseAccessToken(string accessToken) + { + if (string.IsNullOrEmpty(accessToken)) return new AccessTokenImpl(); + + try + { + var tokenObj = JsonWebToken.DecodeToObject(accessToken, WebConfigUtils.SecretKey); + + if (tokenObj?.ExpiresAt.AddDays(AccessTokenExpireDays) > DateTime.Now) + { + return tokenObj; + } + } + catch + { + // ignored + } + + return new AccessTokenImpl(); + } + + #endregion + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/Web.Release.config b/net452/SiteServer.Web/Web.Release.config new file mode 100644 index 000000000..747404ed8 --- /dev/null +++ b/net452/SiteServer.Web/Web.Release.config @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/net452/SiteServer.Web/WebApiConfig.cs b/net452/SiteServer.Web/WebApiConfig.cs new file mode 100644 index 000000000..72a2618bd --- /dev/null +++ b/net452/SiteServer.Web/WebApiConfig.cs @@ -0,0 +1,56 @@ +using System.Linq; +using System.Web.Http; +using System.Web.Http.Cors; +using System.Web.Http.Dispatcher; +using System.Web.Routing; +using SiteServer.CMS.Fx; +using SiteServer.Utils; + +namespace SiteServer.API +{ + // https://docs.microsoft.com/en-us/aspnet/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2 + public static class WebApiConfig + { + public static void Register(HttpConfiguration config) + { + config.MapHttpAttributeRoutes(new CentralizedPrefixProvider(WebConfigUtils.ApiPrefix)); + + config.Services.Replace(typeof(IHttpControllerSelector), + new NamespaceHttpControllerSelector(config)); + + var corsAttr = new EnableCorsAttribute("*", "*", "*") + { + SupportsCredentials = true + }; + config.EnableCors(corsAttr); + + RouteTable.Routes.Ignore(""); //Allow index.html to load + + var jsonFormatter = config.Formatters.JsonFormatter; + //var settings = new JsonSerializerSettings + //{ + // ContractResolver = new CamelCasePropertyNamesContractResolver() + //}; + + //var timeFormat = new IsoDateTimeConverter + //{ + // DateTimeFormat = "yyyy-MM-dd HH:mm:ss" + //}; + //settings.Converters.Add(timeFormat); + //jsonFormatter.SerializerSettings = settings; + jsonFormatter.SerializerSettings = TranslateUtils.JsonSettings; + jsonFormatter.Indent = true; + + var formatters = config.Formatters.Where(formatter => + formatter.SupportedMediaTypes.Any(media => media.MediaType == "application/xml")) + .ToList(); + + foreach (var match in formatters) + { + config.Formatters.Remove(match); + } + + config.EnsureInitialized(); + } + } +} \ No newline at end of file diff --git a/net452/SiteServer.Web/favicon.ico b/net452/SiteServer.Web/favicon.ico new file mode 100644 index 000000000..be4e31226 Binary files /dev/null and b/net452/SiteServer.Web/favicon.ico differ diff --git a/net452/SiteServer.Web/packages.config b/net452/SiteServer.Web/packages.config new file mode 100644 index 000000000..ea98c96a0 --- /dev/null +++ b/net452/SiteServer.Web/packages.config @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/SiteServer.Web/test.aspx b/net452/SiteServer.Web/test.aspx similarity index 100% rename from SiteServer.Web/test.aspx rename to net452/SiteServer.Web/test.aspx diff --git "a/net452/SiteServer.Web/\345\256\211\350\243\205\345\220\221\345\257\274.html" "b/net452/SiteServer.Web/\345\256\211\350\243\205\345\220\221\345\257\274.html" new file mode 100644 index 000000000..a30d782eb --- /dev/null +++ "b/net452/SiteServer.Web/\345\256\211\350\243\205\345\220\221\345\257\274.html" @@ -0,0 +1,10 @@ + + + + + + + + \ No newline at end of file diff --git a/net452/gulpfile.js b/net452/gulpfile.js new file mode 100644 index 000000000..921ac6d29 --- /dev/null +++ b/net452/gulpfile.js @@ -0,0 +1,197 @@ +'use strict'; + +var fs = require("fs"); +var del = require('del'); +var gulp = require("gulp"); +var minifier = require("gulp-minifier"); +var minify = require("gulp-minify"); +var rename = require("gulp-rename"); +var replace = require("gulp-replace"); +var zip = require("gulp-zip"); +var filter = require("gulp-filter"); +var pjson = require('./package.json'); + +var version = process.env.APPVEYOR_BUILD_VERSION || pjson.version; + +function getDependencies() { + var str = ""; + + var dirs = fs.readdirSync("./packages").filter(function (file) { + return fs.statSync("./packages/" + file).isDirectory(); + }); + for (var dir of dirs) { + var items = dir.split("."); + var index = 0; + for (var i = 0; i < items.length; i++) { + var isNumber = !isNaN(parseFloat(items[i])) && isFinite(items[i]); + if (isNumber) { + index = i; + break; + } + } + var id = items.slice(0, index).join("."); + var version = items.slice(index).join("."); + str += ''; + } + str = "" + str + ""; + return str; +} + +gulp.task('build-clean', function () { + console.log("build version: " + version); + return del(['./build']); +}); + +gulp.task("build-nuspec", function () { + var dependencies = getDependencies(); + return gulp + .src("./SS.CMS.nuspec") + .pipe(replace("$version$", version)) + .pipe(replace("", dependencies + "")) + .pipe(gulp.dest("./build")); +}); + +gulp.task("build-bin", function () { + return gulp + .src(["./SiteServer.Web/bin/*.dll"]) + .pipe(gulp.dest("./build/bin")); +}); + +gulp.task("build-sitefiles-all", function () { + return gulp + .src("./SiteServer.Web/SiteFiles/assets/**/*") + .pipe(gulp.dest("./build/SiteFiles/assets")); +}); + +gulp.task("build-sitefiles-min", function () { + return gulp + .src(["./SiteServer.Web/SiteFiles/assets/**/*.js", "./SiteServer.Web/SiteFiles/assets/**/*.css"]) + .pipe( + minifier({ + minify: true, + collapseWhitespace: true, + conservativeCollapse: true, + minifyJS: true, + minifyCSS: true, + minifyHTML: false, + ignoreFiles: ['.min.css', '.min.js'] + }) + ) + .pipe(gulp.dest("./build/SiteFiles/assets")); +}); + +gulp.task("build-siteserver-all", function () { + return gulp.src("./SiteServer.Web/SiteServer/**/*").pipe(gulp.dest("./build/SiteServer")); +}); + +gulp.task("build-siteserver-html", function () { + return gulp + .src(["./SiteServer.Web/SiteServer/**/*.html", "./SiteServer.Web/SiteServer/**/*.aspx", "./SiteServer.Web/SiteServer/**/*.cshtml"]) + .pipe(replace('.css"', ".css?v=" + version + '"')) + .pipe(replace('.js"', ".js?v=" + version + '"')) + .pipe(gulp.dest("./build/SiteServer")); +}); + +gulp.task("build-siteserver-min-css", function () { + return gulp + .src(["./SiteServer.Web/SiteServer/**/*.css"]) + .pipe( + minifier({ + minify: true, + collapseWhitespace: true, + conservativeCollapse: true, + minifyJS: false, + minifyCSS: true, + minifyHTML: false, + ignoreFiles: ['.min.css'] + }) + ) + .pipe(gulp.dest("./build/SiteServer")); +}); + +gulp.task("build-siteserver-min-js", function () { + const f = filter(['**/*-min.js']); + return gulp + .src(["./SiteServer.Web/SiteServer/**/*.js"]) + .pipe(minify()) + .pipe(f) + .pipe(rename(function (path) { + path.basename = path.basename.substring(0, path.basename.length - 4); + })) + .pipe(gulp.dest("./build/SiteServer")); +}); + +gulp.task("build-home-all", function () { + return gulp.src("./SiteServer.Web/Home/**/*").pipe(gulp.dest("./build/Home")); +}); + +gulp.task("build-home-html", function () { + return gulp + .src(["./SiteServer.Web/Home/**/*.html"]) + .pipe(replace('.css"', ".css?v=" + version + '"')) + .pipe(replace('.js"', ".js?v=" + version + '"')) + .pipe(gulp.dest("./build/Home")); +}); + +gulp.task("build-home-min-css", function () { + return gulp + .src(["./SiteServer.Web/Home/**/*.css"]) + .pipe( + minifier({ + minify: true, + collapseWhitespace: true, + conservativeCollapse: true, + minifyJS: false, + minifyCSS: true, + minifyHTML: false, + ignoreFiles: ['.min.css'] + }) + ) + .pipe(gulp.dest("./build/Home")); +}); + +gulp.task("build-home-min-js", function () { + const f = filter(['**/*-min.js']); + return gulp + .src(["./SiteServer.Web/Home/**/*.js"]) + .pipe(minify()) + .pipe(f) + .pipe(rename(function (path) { + path.basename = path.basename.substring(0, path.basename.length - 4); + })) + .pipe(gulp.dest("./build/Home")); +}); + +gulp.task("build-docs", function () { + return gulp.src(["./SiteServer.Web/安装向导.html", "./SiteServer.Web/favicon.ico"]).pipe(gulp.dest("./build")); +}); + +gulp.task("build-webconfig", function () { + return gulp + .src("./SiteServer.Web/Web.Release.config") + .pipe(rename("Web.config")) + .pipe(gulp.dest("./build")); +}); + +gulp.task('build', gulp.series("build-clean", + "build-docs", + "build-webconfig", + "build-nuspec", + "build-bin", + "build-sitefiles-all", + "build-sitefiles-min", + "build-siteserver-all", + "build-siteserver-html", + "build-siteserver-min-css", + "build-siteserver-min-js", + "build-home-all", + "build-home-html", + "build-home-min-css", + "build-home-min-js")); + +gulp.task("zip", function (callback) { + gulp + .src(["./build/**/*", "!./build/SS.CMS.nuspec"]) + .pipe(zip("siteserver_install.zip")) + .pipe(gulp.dest("./")); +}); \ No newline at end of file diff --git a/net452/package.json b/net452/package.json new file mode 100644 index 000000000..6835a635d --- /dev/null +++ b/net452/package.json @@ -0,0 +1,25 @@ +{ + "name": "siteserver", + "version": "6.8.3", + "description": "", + "repository": "https://github.com/siteserver/cms", + "main": "gulpfile.js", + "dependencies": {}, + "devDependencies": { + "del": "^3.0.0", + "gulp": "^4.0.0", + "gulp-filter": "^5.1.0", + "gulp-minifier": "^1.2.2", + "gulp-minify": "^3.1.0", + "gulp-rename": "^1.2.2", + "gulp-replace": "^0.5.4", + "gulp-rev": "^7.1.2", + "gulp-rev-all": "^0.9.7", + "gulp-zip": "^4.0.0" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC" +} \ No newline at end of file diff --git a/ref/WordPlugin.dll b/net452/ref/WordPlugin.dll similarity index 100% rename from ref/WordPlugin.dll rename to net452/ref/WordPlugin.dll diff --git a/package.json b/package.json deleted file mode 100644 index 144e4b7a0..000000000 --- a/package.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "name": "siteserver", - "version": "1.0.0", - "description": "", - "main": "gulpfile.js", - "dependencies": {}, - "devDependencies": { - "gulp": "^3.9.1", - "gulp-filter": "^5.1.0", - "gulp-minifier": "^0.1.4", - "gulp-rename": "^1.2.2", - "gulp-replace": "^0.5.4", - "gulp-rev": "^7.1.2", - "gulp-rev-all": "^0.9.7", - "gulp-zip": "^4.0.0", - "rimraf": "^2.5.4", - "run-sequence": "^2.2.1" - }, - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC" -} diff --git a/siteserver.sln b/siteserver.sln deleted file mode 100644 index 6e64b47f9..000000000 --- a/siteserver.sln +++ /dev/null @@ -1,43 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 15 -VisualStudioVersion = 15.0.27130.2024 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SiteServer.Utils", "SiteServer.Utils\SiteServer.Utils.csproj", "{2176D8BA-5F57-4C56-8E21-A09011517AE2}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SiteServer.CMS", "SiteServer.CMS\SiteServer.CMS.csproj", "{944127C3-915D-4F02-A534-64EC668C46EC}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SiteServer.BackgroundPages", "SiteServer.BackgroundPages\SiteServer.BackgroundPages.csproj", "{6AA1713A-3B77-4B20-B8C7-FCB6DE556F64}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SiteServer.API", "SiteServer.Web\SiteServer.API.csproj", "{69C00F60-F28A-4CBC-B1A4-2DB73BB97471}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2176D8BA-5F57-4C56-8E21-A09011517AE2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {2176D8BA-5F57-4C56-8E21-A09011517AE2}.Debug|Any CPU.Build.0 = Debug|Any CPU - {2176D8BA-5F57-4C56-8E21-A09011517AE2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {2176D8BA-5F57-4C56-8E21-A09011517AE2}.Release|Any CPU.Build.0 = Release|Any CPU - {944127C3-915D-4F02-A534-64EC668C46EC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {944127C3-915D-4F02-A534-64EC668C46EC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {944127C3-915D-4F02-A534-64EC668C46EC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {944127C3-915D-4F02-A534-64EC668C46EC}.Release|Any CPU.Build.0 = Release|Any CPU - {6AA1713A-3B77-4B20-B8C7-FCB6DE556F64}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {6AA1713A-3B77-4B20-B8C7-FCB6DE556F64}.Debug|Any CPU.Build.0 = Debug|Any CPU - {6AA1713A-3B77-4B20-B8C7-FCB6DE556F64}.Release|Any CPU.ActiveCfg = Release|Any CPU - {6AA1713A-3B77-4B20-B8C7-FCB6DE556F64}.Release|Any CPU.Build.0 = Release|Any CPU - {69C00F60-F28A-4CBC-B1A4-2DB73BB97471}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {69C00F60-F28A-4CBC-B1A4-2DB73BB97471}.Debug|Any CPU.Build.0 = Debug|Any CPU - {69C00F60-F28A-4CBC-B1A4-2DB73BB97471}.Release|Any CPU.ActiveCfg = Release|Any CPU - {69C00F60-F28A-4CBC-B1A4-2DB73BB97471}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {16E9F7DE-60E7-4FB3-A3DB-38729FE5A04F} - EndGlobalSection -EndGlobal diff --git a/src/SiteServer.API.Core/.vscode/launch.json b/src/SiteServer.API.Core/.vscode/launch.json new file mode 100644 index 000000000..c305f6ae9 --- /dev/null +++ b/src/SiteServer.API.Core/.vscode/launch.json @@ -0,0 +1,34 @@ +{ + // Use IntelliSense to find out which attributes exist for C# debugging + // Use hover for the description of the existing attributes + // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md + "version": "0.2.0", + "configurations": [ + { + "name": ".NET Core Launch (web)", + "type": "coreclr", + "request": "launch", + "preLaunchTask": "build", + // If you have changed target frameworks, make sure to update the program path. + "program": "${workspaceFolder}/bin/Debug/netcoreapp2.2/SiteServer.APICore.dll", + "args": [], + "cwd": "${workspaceFolder}", + "stopAtEntry": false, + "launchBrowser": { + "enabled": true + }, + "env": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "sourceFileMap": { + "/Views": "${workspaceFolder}/Views" + } + }, + { + "name": ".NET Core Attach", + "type": "coreclr", + "request": "attach", + "processId": "${command:pickProcess}" + } + ] +} \ No newline at end of file diff --git a/src/SiteServer.API.Core/.vscode/tasks.json b/src/SiteServer.API.Core/.vscode/tasks.json new file mode 100644 index 000000000..99271f86b --- /dev/null +++ b/src/SiteServer.API.Core/.vscode/tasks.json @@ -0,0 +1,36 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "build", + "command": "dotnet", + "type": "process", + "args": [ + "build", + "${workspaceFolder}/SiteServer.APICore.csproj" + ], + "problemMatcher": "$tsc" + }, + { + "label": "publish", + "command": "dotnet", + "type": "process", + "args": [ + "publish", + "${workspaceFolder}/SiteServer.APICore.csproj" + ], + "problemMatcher": "$tsc" + }, + { + "label": "watch", + "command": "dotnet", + "type": "process", + "args": [ + "watch", + "run", + "${workspaceFolder}/SiteServer.APICore.csproj" + ], + "problemMatcher": "$tsc" + } + ] +} \ No newline at end of file diff --git a/src/SiteServer.API.Core/Controllers/ValuesController.cs b/src/SiteServer.API.Core/Controllers/ValuesController.cs new file mode 100644 index 000000000..965a2aa53 --- /dev/null +++ b/src/SiteServer.API.Core/Controllers/ValuesController.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using Microsoft.AspNetCore.Mvc; + +namespace SiteServer.API.Core.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class ValuesController : ControllerBase + { + // GET api/values + [HttpGet] + public ActionResult> Get() + { + return new string[] { "value1", "value2" }; + } + + // GET api/values/5 + [HttpGet("{id}")] + public ActionResult Get(int id) + { + return "value"; + } + + // POST api/values + [HttpPost] + public void Post([FromBody] string value) + { + } + + // PUT api/values/5 + [HttpPut("{id}")] + public void Put(int id, [FromBody] string value) + { + } + + // DELETE api/values/5 + [HttpDelete("{id}")] + public void Delete(int id) + { + } + } +} diff --git a/src/SiteServer.API.Core/Program.cs b/src/SiteServer.API.Core/Program.cs new file mode 100644 index 000000000..e7377b635 --- /dev/null +++ b/src/SiteServer.API.Core/Program.cs @@ -0,0 +1,17 @@ +using Microsoft.AspNetCore; +using Microsoft.AspNetCore.Hosting; + +namespace SiteServer.API.Core +{ + public class Program + { + public static void Main(string[] args) + { + CreateWebHostBuilder(args).Build().Run(); + } + + public static IWebHostBuilder CreateWebHostBuilder(string[] args) => + WebHost.CreateDefaultBuilder(args) + .UseStartup(); + } +} diff --git a/src/SiteServer.API.Core/SiteServer.API.Core.csproj b/src/SiteServer.API.Core/SiteServer.API.Core.csproj new file mode 100644 index 000000000..4be6443ba --- /dev/null +++ b/src/SiteServer.API.Core/SiteServer.API.Core.csproj @@ -0,0 +1,14 @@ + + + + netcoreapp2.2 + InProcess + + + + + + + + + diff --git a/src/SiteServer.API.Core/Startup.cs b/src/SiteServer.API.Core/Startup.cs new file mode 100644 index 000000000..d7ac81468 --- /dev/null +++ b/src/SiteServer.API.Core/Startup.cs @@ -0,0 +1,41 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; + +namespace SiteServer.API.Core +{ + public class Startup + { + public Startup(IConfiguration configuration) + { + Configuration = configuration; + } + + public IConfiguration Configuration { get; } + + // This method gets called by the runtime. Use this method to add services to the container. + public void ConfigureServices(IServiceCollection services) + { + services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2); + } + + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IHostingEnvironment env) + { + if (env.IsDevelopment()) + { + app.UseDeveloperExceptionPage(); + } + else + { + // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. + app.UseHsts(); + } + + app.UseHttpsRedirection(); + app.UseMvc(); + } + } +} diff --git a/src/SiteServer.API.Core/appsettings.Development.json b/src/SiteServer.API.Core/appsettings.Development.json new file mode 100644 index 000000000..e203e9407 --- /dev/null +++ b/src/SiteServer.API.Core/appsettings.Development.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Debug", + "System": "Information", + "Microsoft": "Information" + } + } +} diff --git a/src/SiteServer.API.Core/appsettings.json b/src/SiteServer.API.Core/appsettings.json new file mode 100644 index 000000000..def9159a7 --- /dev/null +++ b/src/SiteServer.API.Core/appsettings.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Warning" + } + }, + "AllowedHosts": "*" +} diff --git a/src/SiteServer.Cli.Core/Program.cs b/src/SiteServer.Cli.Core/Program.cs new file mode 100644 index 000000000..3bf5bc0b6 --- /dev/null +++ b/src/SiteServer.Cli.Core/Program.cs @@ -0,0 +1,12 @@ +using System; + +namespace SiteServer.Cli.Core +{ + class Program + { + static void Main(string[] args) + { + Console.WriteLine("Hello World!"); + } + } +} diff --git a/src/SiteServer.Cli.Core/SiteServer.Cli.Core.csproj b/src/SiteServer.Cli.Core/SiteServer.Cli.Core.csproj new file mode 100644 index 000000000..8dc510ad5 --- /dev/null +++ b/src/SiteServer.Cli.Core/SiteServer.Cli.Core.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp2.2 + + + + + + + diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.AdditionalElements/DublinCore/DcElement.cs b/src/SiteServer.Utils/Atom/Atom.AdditionalElements/DublinCore/DcElement.cs similarity index 97% rename from SiteServer.Utils/ThirdParty/Atom/Atom.AdditionalElements/DublinCore/DcElement.cs rename to src/SiteServer.Utils/Atom/Atom.AdditionalElements/DublinCore/DcElement.cs index a5de04945..562374d3a 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.AdditionalElements/DublinCore/DcElement.cs +++ b/src/SiteServer.Utils/Atom/Atom.AdditionalElements/DublinCore/DcElement.cs @@ -31,13 +31,12 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.Xml.XPath; -using Atom.Core; -using Atom.AdditionalElements; -using Atom.Utils; +using SiteServer.Utils.Atom.Atom.Utils; -namespace Atom.AdditionalElements.DublinCore +namespace SiteServer.Utils.Atom.Atom.AdditionalElements.DublinCore { /// /// The class representing any of the Dublin Core elements. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.AdditionalElements/ScopedElement.cs b/src/SiteServer.Utils/Atom/Atom.AdditionalElements/ScopedElement.cs similarity index 97% rename from SiteServer.Utils/ThirdParty/Atom/Atom.AdditionalElements/ScopedElement.cs rename to src/SiteServer.Utils/Atom/Atom.AdditionalElements/ScopedElement.cs index a4125fa9e..362f5f7d7 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.AdditionalElements/ScopedElement.cs +++ b/src/SiteServer.Utils/Atom/Atom.AdditionalElements/ScopedElement.cs @@ -31,11 +31,11 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; -using Atom.Core; -using Atom.Utils; +using SiteServer.Utils.Atom.Atom.Core; -namespace Atom.AdditionalElements +namespace SiteServer.Utils.Atom.Atom.AdditionalElements { /// /// The base class of all non Atom core elements. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.AdditionalElements/ScopedElementCollection.cs b/src/SiteServer.Utils/Atom/Atom.AdditionalElements/ScopedElementCollection.cs similarity index 98% rename from SiteServer.Utils/ThirdParty/Atom/Atom.AdditionalElements/ScopedElementCollection.cs rename to src/SiteServer.Utils/Atom/Atom.AdditionalElements/ScopedElementCollection.cs index e5975bea2..e7b0c3f60 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.AdditionalElements/ScopedElementCollection.cs +++ b/src/SiteServer.Utils/Atom/Atom.AdditionalElements/ScopedElementCollection.cs @@ -31,14 +31,12 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.Collections; using System.Collections.Specialized; -using System.Text; -using Atom.Utils; -using SiteServer.Utils; -namespace Atom.AdditionalElements +namespace SiteServer.Utils.Atom.Atom.AdditionalElements { /// /// A strongly typed collection of objects. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Core.Collections/AtomContentCollection.cs b/src/SiteServer.Utils/Atom/Atom.Core.Collections/AtomContentCollection.cs similarity index 99% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Core.Collections/AtomContentCollection.cs rename to src/SiteServer.Utils/Atom/Atom.Core.Collections/AtomContentCollection.cs index ec2441af2..e3ee94bdc 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Core.Collections/AtomContentCollection.cs +++ b/src/SiteServer.Utils/Atom/Atom.Core.Collections/AtomContentCollection.cs @@ -31,11 +31,11 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.Collections; -using Atom.Utils; -namespace Atom.Core.Collections +namespace SiteServer.Utils.Atom.Atom.Core.Collections { /// /// A strongly typed collection of objects. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Core.Collections/AtomEntryCollection.cs b/src/SiteServer.Utils/Atom/Atom.Core.Collections/AtomEntryCollection.cs similarity index 98% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Core.Collections/AtomEntryCollection.cs rename to src/SiteServer.Utils/Atom/Atom.Core.Collections/AtomEntryCollection.cs index 90c01b96e..422ed68f6 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Core.Collections/AtomEntryCollection.cs +++ b/src/SiteServer.Utils/Atom/Atom.Core.Collections/AtomEntryCollection.cs @@ -31,11 +31,11 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.Collections; -using Atom.Utils; -namespace Atom.Core.Collections +namespace SiteServer.Utils.Atom.Atom.Core.Collections { /// /// A strongly typed collection of objects. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Core.Collections/AtomLinkCollection.cs b/src/SiteServer.Utils/Atom/Atom.Core.Collections/AtomLinkCollection.cs similarity index 99% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Core.Collections/AtomLinkCollection.cs rename to src/SiteServer.Utils/Atom/Atom.Core.Collections/AtomLinkCollection.cs index aa581e439..607650be0 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Core.Collections/AtomLinkCollection.cs +++ b/src/SiteServer.Utils/Atom/Atom.Core.Collections/AtomLinkCollection.cs @@ -31,11 +31,11 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.Collections; -using Atom.Utils; -namespace Atom.Core.Collections +namespace SiteServer.Utils.Atom.Atom.Core.Collections { /// /// A strongly typed collection of objects. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Core.Collections/AtomPersonConstructCollection.cs b/src/SiteServer.Utils/Atom/Atom.Core.Collections/AtomPersonConstructCollection.cs similarity index 99% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Core.Collections/AtomPersonConstructCollection.cs rename to src/SiteServer.Utils/Atom/Atom.Core.Collections/AtomPersonConstructCollection.cs index 4f11a263a..b29501714 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Core.Collections/AtomPersonConstructCollection.cs +++ b/src/SiteServer.Utils/Atom/Atom.Core.Collections/AtomPersonConstructCollection.cs @@ -31,11 +31,11 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.Collections; -using Atom.Utils; -namespace Atom.Core.Collections +namespace SiteServer.Utils.Atom.Atom.Core.Collections { /// /// A strongly typed collection of objects. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomContent.cs b/src/SiteServer.Utils/Atom/Atom.Core/AtomContent.cs similarity index 98% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomContent.cs rename to src/SiteServer.Utils/Atom/Atom.Core/AtomContent.cs index 6b855e5de..4b4c47075 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomContent.cs +++ b/src/SiteServer.Utils/Atom/Atom.Core/AtomContent.cs @@ -31,13 +31,14 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.Text; using System.Xml.XPath; -using Atom.Utils; -using MvpXml; +using SiteServer.Utils.Atom.Atom.Utils; +using SiteServer.Utils.MvpXml; -namespace Atom.Core +namespace SiteServer.Utils.Atom.Atom.Core { /// /// The content of an Atom entry. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomContentConstruct.cs b/src/SiteServer.Utils/Atom/Atom.Core/AtomContentConstruct.cs similarity index 98% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomContentConstruct.cs rename to src/SiteServer.Utils/Atom/Atom.Core/AtomContentConstruct.cs index f6e5fe59c..4ef75c697 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomContentConstruct.cs +++ b/src/SiteServer.Utils/Atom/Atom.Core/AtomContentConstruct.cs @@ -31,13 +31,14 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.Text; using System.Xml.XPath; -using Atom.Utils; -using MvpXml; +using SiteServer.Utils.Atom.Atom.Utils; +using SiteServer.Utils.MvpXml; -namespace Atom.Core +namespace SiteServer.Utils.Atom.Atom.Core { /// /// The class representing all content constructs. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomDateConstruct.cs b/src/SiteServer.Utils/Atom/Atom.Core/AtomDateConstruct.cs similarity index 99% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomDateConstruct.cs rename to src/SiteServer.Utils/Atom/Atom.Core/AtomDateConstruct.cs index e0c40cd97..fdd0834d9 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomDateConstruct.cs +++ b/src/SiteServer.Utils/Atom/Atom.Core/AtomDateConstruct.cs @@ -31,11 +31,12 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.Xml.XPath; -using Atom.Utils; +using SiteServer.Utils.Atom.Atom.Utils; -namespace Atom.Core +namespace SiteServer.Utils.Atom.Atom.Core { /// /// The class representing all date contructs. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomElement.cs b/src/SiteServer.Utils/Atom/Atom.Core/AtomElement.cs similarity index 99% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomElement.cs rename to src/SiteServer.Utils/Atom/Atom.Core/AtomElement.cs index 4cd3f8790..3d179f013 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomElement.cs +++ b/src/SiteServer.Utils/Atom/Atom.Core/AtomElement.cs @@ -31,12 +31,13 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.Text; using System.Xml; -using Atom.Utils; +using SiteServer.Utils.Atom.Atom.Utils; -namespace Atom.Core +namespace SiteServer.Utils.Atom.Atom.Core { /// /// The base class for all elements. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomEntry.cs b/src/SiteServer.Utils/Atom/Atom.Core/AtomEntry.cs similarity index 98% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomEntry.cs rename to src/SiteServer.Utils/Atom/Atom.Core/AtomEntry.cs index c42ff28c2..d62d3dfdf 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomEntry.cs +++ b/src/SiteServer.Utils/Atom/Atom.Core/AtomEntry.cs @@ -31,18 +31,19 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.IO; using System.Net; using System.Text; using System.Xml; using System.Xml.XPath; -using Atom.Core.Collections; -using Atom.AdditionalElements; -using Atom.AdditionalElements.DublinCore; -using Atom.Utils; +using SiteServer.Utils.Atom.Atom.AdditionalElements; +using SiteServer.Utils.Atom.Atom.AdditionalElements.DublinCore; +using SiteServer.Utils.Atom.Atom.Core.Collections; +using SiteServer.Utils.Atom.Atom.Utils; -namespace Atom.Core +namespace SiteServer.Utils.Atom.Atom.Core { /// /// The Atom entry. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomFeed.cs b/src/SiteServer.Utils/Atom/Atom.Core/AtomFeed.cs similarity index 98% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomFeed.cs rename to src/SiteServer.Utils/Atom/Atom.Core/AtomFeed.cs index 6ab3b08d4..ef620d004 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomFeed.cs +++ b/src/SiteServer.Utils/Atom/Atom.Core/AtomFeed.cs @@ -35,19 +35,20 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.IO; -using System.Text; using System.Net; +using System.Text; using System.Xml; using System.Xml.XPath; -using Atom.Core.Collections; -using Atom.AdditionalElements; -using Atom.Utils; -using Atom.AdditionalElements.DublinCore; -using MvpXml; +using SiteServer.Utils.Atom.Atom.AdditionalElements; +using SiteServer.Utils.Atom.Atom.AdditionalElements.DublinCore; +using SiteServer.Utils.Atom.Atom.Core.Collections; +using SiteServer.Utils.Atom.Atom.Utils; +using SiteServer.Utils.MvpXml; -namespace Atom.Core +namespace SiteServer.Utils.Atom.Atom.Core { /// /// The Atom feed. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomGenerator.cs b/src/SiteServer.Utils/Atom/Atom.Core/AtomGenerator.cs similarity index 97% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomGenerator.cs rename to src/SiteServer.Utils/Atom/Atom.Core/AtomGenerator.cs index aa6e4a3bc..26ae2e33c 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomGenerator.cs +++ b/src/SiteServer.Utils/Atom/Atom.Core/AtomGenerator.cs @@ -31,10 +31,11 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; -using Atom.Utils; +using SiteServer.Utils.Atom.Atom.Utils; -namespace Atom.Core +namespace SiteServer.Utils.Atom.Atom.Core { /// /// The generator program of an atom feed. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomLink.cs b/src/SiteServer.Utils/Atom/Atom.Core/AtomLink.cs similarity index 98% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomLink.cs rename to src/SiteServer.Utils/Atom/Atom.Core/AtomLink.cs index 22f27b9ac..bcb60dc4b 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomLink.cs +++ b/src/SiteServer.Utils/Atom/Atom.Core/AtomLink.cs @@ -31,11 +31,12 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.Xml.XPath; -using Atom.Utils; +using SiteServer.Utils.Atom.Atom.Utils; -namespace Atom.Core +namespace SiteServer.Utils.Atom.Atom.Core { /// /// The link of an Atom feed or an entry. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomPersonConstruct.cs b/src/SiteServer.Utils/Atom/Atom.Core/AtomPersonConstruct.cs similarity index 98% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomPersonConstruct.cs rename to src/SiteServer.Utils/Atom/Atom.Core/AtomPersonConstruct.cs index 043006ca9..521b8832a 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/AtomPersonConstruct.cs +++ b/src/SiteServer.Utils/Atom/Atom.Core/AtomPersonConstruct.cs @@ -31,11 +31,12 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.Xml.XPath; -using Atom.Utils; +using SiteServer.Utils.Atom.Atom.Utils; -namespace Atom.Core +namespace SiteServer.Utils.Atom.Atom.Core { /// /// The class representing all person constructs. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/Enums.cs b/src/SiteServer.Utils/Atom/Atom.Core/Enums.cs similarity index 99% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Core/Enums.cs rename to src/SiteServer.Utils/Atom/Atom.Core/Enums.cs index 01c8fb3c5..0141b2fc0 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/Enums.cs +++ b/src/SiteServer.Utils/Atom/Atom.Core/Enums.cs @@ -31,9 +31,8 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using System; -namespace Atom.Core +namespace SiteServer.Utils.Atom.Atom.Core { #region Language diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/Exceptions.cs b/src/SiteServer.Utils/Atom/Atom.Core/Exceptions.cs similarity index 99% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Core/Exceptions.cs rename to src/SiteServer.Utils/Atom/Atom.Core/Exceptions.cs index 189c31e8d..45095de33 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Core/Exceptions.cs +++ b/src/SiteServer.Utils/Atom/Atom.Core/Exceptions.cs @@ -31,9 +31,10 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; -namespace Atom.Core +namespace SiteServer.Utils.Atom.Atom.Core { #region Person constructs exception diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Utils/DefaultValues.cs b/src/SiteServer.Utils/Atom/Atom.Utils/DefaultValues.cs similarity index 98% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Utils/DefaultValues.cs rename to src/SiteServer.Utils/Atom/Atom.Utils/DefaultValues.cs index 651de3d5d..27244f081 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Utils/DefaultValues.cs +++ b/src/SiteServer.Utils/Atom/Atom.Utils/DefaultValues.cs @@ -31,11 +31,12 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.Text; -using Atom.Core; +using SiteServer.Utils.Atom.Atom.Core; -namespace Atom.Utils +namespace SiteServer.Utils.Atom.Atom.Utils { /// /// Contains default values for Atom feeds. diff --git a/SiteServer.Utils/ThirdParty/Atom/Atom.Utils/Utils.cs b/src/SiteServer.Utils/Atom/Atom.Utils/Utils.cs similarity index 99% rename from SiteServer.Utils/ThirdParty/Atom/Atom.Utils/Utils.cs rename to src/SiteServer.Utils/Atom/Atom.Utils/Utils.cs index 1a757cf74..3fbdbb262 100644 --- a/SiteServer.Utils/ThirdParty/Atom/Atom.Utils/Utils.cs +++ b/src/SiteServer.Utils/Atom/Atom.Utils/Utils.cs @@ -31,16 +31,16 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using Atom.Core; + using System; using System.Collections; using System.IO; +using System.Reflection; using System.Text; using System.Text.RegularExpressions; -using System.Reflection; -using System.Web; +using SiteServer.Utils.Atom.Atom.Core; -namespace Atom.Utils +namespace SiteServer.Utils.Atom.Atom.Utils { /// /// A class with some useful methods. @@ -637,7 +637,7 @@ static Utils() /// The escaped . public static string Escape(string buffer) { - return HttpUtility.HtmlEncode(buffer); + return StringUtils.HtmlEncode(buffer); } /// @@ -647,7 +647,7 @@ public static string Escape(string buffer) /// The unescaped . public static string Unescape(string buffer) { - return HttpUtility.HtmlDecode(buffer); + return StringUtils.HtmlDecode(buffer); } /// diff --git a/SiteServer.Utils/ThirdParty/Atom/AtomReader.cs b/src/SiteServer.Utils/Atom/AtomReader.cs similarity index 96% rename from SiteServer.Utils/ThirdParty/Atom/AtomReader.cs rename to src/SiteServer.Utils/Atom/AtomReader.cs index ac39b65ae..71933c2d9 100644 --- a/SiteServer.Utils/ThirdParty/Atom/AtomReader.cs +++ b/src/SiteServer.Utils/Atom/AtomReader.cs @@ -35,15 +35,13 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -using System; + using System.IO; using System.Xml; using System.Xml.XPath; -using Atom.AdditionalElements.DublinCore; -using Atom.Core; -using Atom.Utils; +using SiteServer.Utils.Atom.Atom.Utils; -namespace Atom +namespace SiteServer.Utils.Atom { internal class AtomReader { diff --git a/SiteServer.Utils/ThirdParty/Atom/AtomWriter.cs b/src/SiteServer.Utils/Atom/AtomWriter.cs similarity index 97% rename from SiteServer.Utils/ThirdParty/Atom/AtomWriter.cs rename to src/SiteServer.Utils/Atom/AtomWriter.cs index e80006aa1..b2accc6cd 100644 --- a/SiteServer.Utils/ThirdParty/Atom/AtomWriter.cs +++ b/src/SiteServer.Utils/Atom/AtomWriter.cs @@ -35,14 +35,15 @@ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ + using System; using System.IO; using System.Text; using System.Xml; -using Atom.Core; -using Atom.Utils; +using SiteServer.Utils.Atom.Atom.Core; +using SiteServer.Utils.Atom.Atom.Utils; -namespace Atom +namespace SiteServer.Utils.Atom { internal class AtomWriter { diff --git a/src/SiteServer.Utils/AttackUtils.cs b/src/SiteServer.Utils/AttackUtils.cs new file mode 100644 index 000000000..75f4f2beb --- /dev/null +++ b/src/SiteServer.Utils/AttackUtils.cs @@ -0,0 +1,50 @@ +using System; +using Ganss.XSS; + +namespace SiteServer.Utils +{ + public static class AttackUtils + { + private static readonly HtmlSanitizer Sanitizer = new HtmlSanitizer(); + + public static string FilterSqlAndXss(string objStr) + { + return FilterXss(FilterSql(objStr)); + } + + public static string FilterXss(string html) + { + if (string.IsNullOrEmpty(html)) return string.Empty; + return Sanitizer.Sanitize(html); + } + + public static string FilterSql(string objStr) + { + if (string.IsNullOrEmpty(objStr)) return string.Empty; + + var isSqlExists = false; + const string strSql = "',\\(,\\)"; + var strSqls = strSql.Split(','); + foreach (var sql in strSqls) + { + if (objStr.IndexOf(sql, StringComparison.Ordinal) != -1) + { + isSqlExists = true; + break; + } + } + if (isSqlExists) + { + return objStr.Replace("'", "_sqlquote_").Replace("\\(", "_sqlleftparenthesis_").Replace("\\)", "_sqlrightparenthesis_"); + } + return objStr; + } + + public static string UnFilterSql(string objStr) + { + if (string.IsNullOrEmpty(objStr)) return string.Empty; + + return objStr.Replace("_sqlquote_", "'").Replace("_sqlleftparenthesis_", "\\(").Replace("_sqlrightparenthesis_", "\\)"); + } + } +} diff --git a/src/SiteServer.Utils/Auth/AuthUtils.cs b/src/SiteServer.Utils/Auth/AuthUtils.cs new file mode 100644 index 000000000..e15fa8524 --- /dev/null +++ b/src/SiteServer.Utils/Auth/AuthUtils.cs @@ -0,0 +1,33 @@ +using System; +using System.IO; +using System.Security.Cryptography; +using System.Text; + +namespace SiteServer.Utils.Auth +{ + public static class AuthUtils + { + public static string Md5ByFilePath(string filePath) + { + using (var md5 = MD5.Create()) + { + using (var stream = File.OpenRead(filePath)) + { + var hash = md5.ComputeHash(stream); + return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); + } + } + } + + public static string Md5ByString(string str) + { + if (string.IsNullOrEmpty(str)) return string.Empty; + var bytes = Encoding.UTF8.GetBytes(str); + using (var md5 = MD5.Create()) + { + var hash = md5.ComputeHash(bytes); + return BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant(); + } + } + } +} diff --git a/SiteServer.Utils/Auth/Base64Utils.cs b/src/SiteServer.Utils/Auth/Base64Utils.cs similarity index 100% rename from SiteServer.Utils/Auth/Base64Utils.cs rename to src/SiteServer.Utils/Auth/Base64Utils.cs diff --git a/SiteServer.Utils/Auth/DesEncryptor.cs b/src/SiteServer.Utils/Auth/DesEncryptor.cs similarity index 100% rename from SiteServer.Utils/Auth/DesEncryptor.cs rename to src/SiteServer.Utils/Auth/DesEncryptor.cs diff --git a/SiteServer.Utils/Auth/IJsonSerializer.cs b/src/SiteServer.Utils/Auth/IJsonSerializer.cs similarity index 100% rename from SiteServer.Utils/Auth/IJsonSerializer.cs rename to src/SiteServer.Utils/Auth/IJsonSerializer.cs diff --git a/SiteServer.Utils/Auth/JWT.cs b/src/SiteServer.Utils/Auth/JWT.cs similarity index 95% rename from SiteServer.Utils/Auth/JWT.cs rename to src/SiteServer.Utils/Auth/JWT.cs index 5582625a3..3b20b479d 100644 --- a/SiteServer.Utils/Auth/JWT.cs +++ b/src/SiteServer.Utils/Auth/JWT.cs @@ -20,10 +20,10 @@ public static class JsonWebToken { private static Dictionary> HashAlgorithms; - /// - /// Pluggable JSON Serializer - /// - public static IJsonSerializer JsonSerializer = new DefaultJsonSerializer(); + ///// + ///// Pluggable JSON Serializer + ///// + //public static IJsonSerializer JsonSerializer = new DefaultJsonSerializer(); static JsonWebToken() { @@ -52,8 +52,8 @@ public static string Encode(IDictionary extraHeaders, object pay {"alg", algorithm.ToString()} }; - var headerBytes = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(header)); - var payloadBytes = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(payload)); + var headerBytes = Encoding.UTF8.GetBytes(TranslateUtils.JsonSerialize(header)); + var payloadBytes = Encoding.UTF8.GetBytes(TranslateUtils.JsonSerialize(payload)); segments.Add(Base64UrlEncode(headerBytes)); segments.Add(Base64UrlEncode(payloadBytes)); @@ -127,7 +127,7 @@ public static string Decode(string token, byte[] key, bool verify = true) var headerJson = Encoding.UTF8.GetString(Base64UrlDecode(header)); var payloadJson = Encoding.UTF8.GetString(Base64UrlDecode(payload)); - var headerData = JsonSerializer.Deserialize>(headerJson); + var headerData = TranslateUtils.JsonDeserialize>(headerJson); if (verify) { @@ -145,7 +145,7 @@ public static string Decode(string token, byte[] key, bool verify = true) } // verify exp claim https://tools.ietf.org/html/draft-ietf-oauth-json-web-token-32#section-4.1.4 - var payloadData = JsonSerializer.Deserialize>(payloadJson); + var payloadData = TranslateUtils.JsonDeserialize>(payloadJson); if (payloadData.ContainsKey("exp") && payloadData["exp"] != null) { // safely unpack a boxed int @@ -191,7 +191,7 @@ public static string Decode(string token, string key, bool verify = true) public static object DecodeToObject(string token, byte[] key, bool verify = true) { var payloadJson = Decode(token, key, verify); - var payloadData = JsonSerializer.Deserialize>(payloadJson); + var payloadData = TranslateUtils.JsonDeserialize>(payloadJson); return payloadData; } @@ -220,7 +220,7 @@ public static object DecodeToObject(string token, string key, bool verify = true public static T DecodeToObject(string token, byte[] key, bool verify = true) { var payloadJson = Decode(token, key, verify); - var payloadData = JsonSerializer.Deserialize(payloadJson); + var payloadData = TranslateUtils.JsonDeserialize(payloadJson); return payloadData; } diff --git a/SiteServer.Utils/Base64Decoder.cs b/src/SiteServer.Utils/Base64Decoder.cs similarity index 100% rename from SiteServer.Utils/Base64Decoder.cs rename to src/SiteServer.Utils/Base64Decoder.cs diff --git a/SiteServer.Utils/Base64Encoder.cs b/src/SiteServer.Utils/Base64Encoder.cs similarity index 100% rename from SiteServer.Utils/Base64Encoder.cs rename to src/SiteServer.Utils/Base64Encoder.cs diff --git a/src/SiteServer.Utils/Constants.cs b/src/SiteServer.Utils/Constants.cs new file mode 100644 index 000000000..5fbd1388d --- /dev/null +++ b/src/SiteServer.Utils/Constants.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +namespace SiteServer.Utils +{ + public static class Constants + { + public const string AuthKeyUserHeader = "X-SS-USER-TOKEN"; + public const string AuthKeyUserCookie = "SS-USER-TOKEN"; + public const string AuthKeyUserQuery = "userToken"; + public const string AuthKeyAdminHeader = "X-SS-ADMIN-TOKEN"; + public const string AuthKeyAdminCookie = "SS-ADMIN-TOKEN"; + public const string AuthKeyAdminQuery = "adminToken"; + public const string AuthKeyApiHeader = "X-SS-API-KEY"; + public const string AuthKeyApiCookie = "SS-API-KEY"; + public const string AuthKeyApiQuery = "apiKey"; + public const int AccessTokenExpireDays = 7; + + public const string ReturnAndNewline = "\r\n";//回车换行 + public const string Html5Empty = @""; + + public const string OracleEmptyValue = "_EMPTY_"; + + public const string Ellipsis = "..."; + + public const int PageSize = 25;//后台分页数 + public const string HideElementStyle = "display:none"; + public const string ShowElementStyle = "display:"; + + public const string TitleImageAppendix = "t_"; + public const string SmallImageAppendix = "s_"; + } +} diff --git a/SiteServer.Utils/ConvertHelper.cs b/src/SiteServer.Utils/ConvertHelper.cs similarity index 100% rename from SiteServer.Utils/ConvertHelper.cs rename to src/SiteServer.Utils/ConvertHelper.cs diff --git a/SiteServer.Utils/CsvUtils.cs b/src/SiteServer.Utils/CsvUtils.cs similarity index 100% rename from SiteServer.Utils/CsvUtils.cs rename to src/SiteServer.Utils/CsvUtils.cs diff --git a/src/SiteServer.Utils/DataTypeUtils.cs b/src/SiteServer.Utils/DataTypeUtils.cs new file mode 100644 index 000000000..4b2401385 --- /dev/null +++ b/src/SiteServer.Utils/DataTypeUtils.cs @@ -0,0 +1,86 @@ +using Datory; + +namespace SiteServer.Utils +{ + public class DataTypeUtils + { + public static DataType GetEnumType(string typeStr) + { + var retVal = DataType.VarChar; + + if (Equals(DataType.Boolean, typeStr)) + { + retVal = DataType.Boolean; + } + else if (Equals(DataType.DateTime, typeStr)) + { + retVal = DataType.DateTime; + } + else if (Equals(DataType.Decimal, typeStr)) + { + retVal = DataType.Decimal; + } + else if (Equals(DataType.Integer, typeStr)) + { + retVal = DataType.Integer; + } + else if (Equals(DataType.Text, typeStr)) + { + retVal = DataType.Text; + } + else if (Equals(DataType.VarChar, typeStr)) + { + retVal = DataType.VarChar; + } + + return retVal; + } + + public static bool Equals(DataType type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(type.Value.ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, DataType type) + { + return Equals(type, typeStr); + } + + + + public static string GetText(DataType dataType) + { + var retVal = string.Empty; + if (dataType == DataType.VarChar) + { + retVal = "文本"; + } + else if (dataType == DataType.Text) + { + retVal = "备注"; + } + else if (dataType == DataType.Integer) + { + retVal = "整数"; + } + else if (dataType == DataType.DateTime) + { + retVal = "日期"; + } + else if (dataType == DataType.Decimal) + { + retVal = "小数"; + } + else if (dataType == DataType.Boolean) + { + retVal = "布尔值"; + } + return retVal; + } + } +} diff --git a/src/SiteServer.Utils/DatabaseTypeUtils.cs b/src/SiteServer.Utils/DatabaseTypeUtils.cs new file mode 100644 index 000000000..6f3cfdb7e --- /dev/null +++ b/src/SiteServer.Utils/DatabaseTypeUtils.cs @@ -0,0 +1,48 @@ +using Datory; + +namespace SiteServer.Utils +{ + public class DatabaseTypeUtils + { + public static DatabaseType GetEnumType(string typeStr) + { + var retVal = DatabaseType.SqlServer; + + if (Equals(DatabaseType.MySql, typeStr)) + { + retVal = DatabaseType.MySql; + } + else if (Equals(DatabaseType.SqlServer, typeStr)) + { + retVal = DatabaseType.SqlServer; + } + else if (Equals(DatabaseType.PostgreSql, typeStr)) + { + retVal = DatabaseType.PostgreSql; + } + else if (Equals(DatabaseType.Oracle, typeStr)) + { + retVal = DatabaseType.Oracle; + } + + return retVal; + } + + public static bool Equals(DatabaseType type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(type.Value.ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, DatabaseType type) + { + return Equals(type, typeStr); + } + + + } +} diff --git a/src/SiteServer.Utils/DateUtils.cs b/src/SiteServer.Utils/DateUtils.cs new file mode 100644 index 000000000..592878dbe --- /dev/null +++ b/src/SiteServer.Utils/DateUtils.cs @@ -0,0 +1,313 @@ +using System; +using System.Globalization; +using SiteServer.Utils.Enumerations; + +namespace SiteServer.Utils +{ + public static class DateUtils + { + public const string FormatStringDateTime = "yyyy-MM-dd HH:mm:ss"; + public const string FormatStringDateOnly = "yyyy-MM-dd"; + + public static DateTime GetExpiresAt(TimeSpan expiresAt) + { + return DateTime.UtcNow.Add(expiresAt); + } + + public static string GetRelatedDateTimeString(DateTimeOffset? offset) + { + return offset.HasValue ? GetRelatedDateTimeString(offset.Value.DateTime) : string.Empty; + } + + public static string GetRelatedDateTimeString(DateTime datetime) + { + string retVal; + var interval = DateTime.Now - datetime; + if (interval.Days > 0) + { + if (interval.Days >= 7 && interval.Days < 35) + { + retVal = $"{interval.Days/7}周"; + } + else + { + retVal = $"{interval.Days}天"; + } + } + else if (interval.Hours > 0) + { + retVal = $"{interval.Hours}小时"; + } + else if (interval.Minutes > 0) + { + retVal = $"{interval.Minutes}分钟"; + } + else if (interval.Seconds > 0) + { + retVal = $"{interval.Seconds}秒"; + } + else if (interval.Milliseconds > 0) + { + retVal = $"{interval.Milliseconds}毫秒"; + } + else + { + retVal = "1毫秒"; + } + return retVal; + } + + public static string GetDateAndTimeString(DateTimeOffset? offset, EDateFormatType dateFormat, ETimeFormatType timeFormat) + { + return offset.HasValue ? GetDateAndTimeString(offset.Value.DateTime, dateFormat, timeFormat) : string.Empty; + } + + public static string GetDateAndTimeString(DateTime datetime, EDateFormatType dateFormat, ETimeFormatType timeFormat) + { + return $"{GetDateString(datetime, dateFormat)} {GetTimeString(datetime, timeFormat)}"; + } + + public static string GetDateAndTimeString(DateTimeOffset? offset) + { + return offset.HasValue ? GetDateAndTimeString(offset.Value.DateTime) : string.Empty; + } + + public static string GetDateAndTimeString(DateTime datetime) + { + if (datetime == SqlMinValue || datetime == DateTime.MinValue) return string.Empty; + return GetDateAndTimeString(datetime, EDateFormatType.Day, ETimeFormatType.ShortTime); + } + + public static string GetDateString(DateTimeOffset? offset) + { + return offset.HasValue ? GetDateString(offset.Value.DateTime) : string.Empty; + } + + public static string GetDateString(DateTime datetime) + { + if (datetime == SqlMinValue || datetime == DateTime.MinValue) return string.Empty; + return GetDateString(datetime, EDateFormatType.Day); + } + + public static string GetDateString(DateTimeOffset? offset, EDateFormatType dateFormat) + { + return offset.HasValue ? GetDateString(offset.Value.DateTime, dateFormat) : string.Empty; + } + + public static string GetDateString(DateTime datetime, EDateFormatType dateFormat) + { + var format = string.Empty; + if (dateFormat == EDateFormatType.Year) + { + format = "yyyy年MM月"; + } + else if (dateFormat == EDateFormatType.Month) + { + format = "MM月dd日"; + } + else if (dateFormat == EDateFormatType.Day) + { + format = "yyyy-MM-dd"; + } + else if (dateFormat == EDateFormatType.Chinese) + { + format = "yyyy年M月d日"; + } + return datetime.ToString(format); + } + + public static string GetTimeString(DateTimeOffset? offset) + { + return offset.HasValue ? GetTimeString(offset.Value.DateTime) : string.Empty; + } + + public static string GetTimeString(DateTime datetime) + { + return GetTimeString(datetime, ETimeFormatType.ShortTime); + } + + public static string GetTimeString(DateTimeOffset? offset, ETimeFormatType timeFormat) + { + return offset.HasValue ? GetTimeString(offset.Value.DateTime, timeFormat) : string.Empty; + } + + public static string GetTimeString(DateTime datetime, ETimeFormatType timeFormat) + { + var retVal = string.Empty; + if (timeFormat == ETimeFormatType.LongTime) + { + retVal = datetime.ToLongTimeString(); + } + else if (timeFormat == ETimeFormatType.ShortTime) + { + retVal = datetime.ToShortTimeString(); + } + return retVal; + } + + public static bool IsSince(string val) + { + if (!string.IsNullOrEmpty(val)) + { + val = val.Trim().ToLower(); + if (val.EndsWith("y") || val.EndsWith("m") || val.EndsWith("d") || val.EndsWith("h")) + { + return true; + } + } + return false; + } + + public static int GetSinceHours(string intWithUnitString) + { + var hours = 0; + if (!string.IsNullOrEmpty(intWithUnitString)) + { + intWithUnitString = intWithUnitString.Trim().ToLower(); + if (intWithUnitString.EndsWith("y")) + { + hours = 8760 * TranslateUtils.ToInt(intWithUnitString.TrimEnd('y')); + } + else if (intWithUnitString.EndsWith("m")) + { + hours = 720 * TranslateUtils.ToInt(intWithUnitString.TrimEnd('m')); + } + else if (intWithUnitString.EndsWith("d")) + { + hours = 24 * TranslateUtils.ToInt(intWithUnitString.TrimEnd('d')); + } + else if (intWithUnitString.EndsWith("h")) + { + hours = TranslateUtils.ToInt(intWithUnitString.TrimEnd('h')); + } + else + { + hours = TranslateUtils.ToInt(intWithUnitString); + } + } + return hours; + } + + public static string Format(DateTimeOffset? offset, string formatString) + { + return offset.HasValue ? Format(offset.Value.DateTime, formatString) : string.Empty; + } + + public static string Format(DateTime datetime, string formatString) + { + string retVal; + if (!string.IsNullOrEmpty(formatString)) + { + retVal = formatString.IndexOf("{0:", StringComparison.Ordinal) != -1 ? string.Format(DateTimeFormatInfo.InvariantInfo, formatString, datetime) : datetime.ToString(formatString, DateTimeFormatInfo.InvariantInfo); + } + else + { + retVal = GetDateString(datetime); + } + return retVal; + } + + public static DateTime SqlMinValue => new DateTime(1754, 1, 1, 0, 0, 0, 0); + + public static string ParseThisMoment(DateTime dateTime) + { + if (dateTime <= SqlMinValue) return string.Empty; + + var now = DateTime.Now; + + if (now.Year == dateTime.Year && now.Month == dateTime.Month) + { + if (DateDiff("hour", dateTime, now) <= 10)//如果date和当前时间间隔在10小时内 + { + if (DateDiff("hour", dateTime, now) > 0) + { + return DateDiff("hour", dateTime, now) + "小时前"; + } + + if (DateDiff("minute", dateTime, now) > 0) + { + return DateDiff("minute", dateTime, now) + "分钟前"; + } + + if (DateDiff("second", dateTime, now) >= 0) + { + return DateDiff("second", dateTime, now) + "秒前"; + } + return "刚才"; + } + + if (now.Day - dateTime.Day == 0) + { + return "今天 " + dateTime.ToString("HH") + ":" + dateTime.ToString("mm"); + } + + if (now.Day - dateTime.Day == 1) + { + return "昨天 " + dateTime.ToString("HH") + ":" + dateTime.ToString("mm"); + } + + if (now.Day - dateTime.Day == 2) + { + return "前天 " + dateTime.ToString("HH") + ":" + dateTime.ToString("mm"); + } + } + + return dateTime.ToString("yyyy-MM-dd HH:mm"); + } + + /// + /// 两个时间的差值,可以为秒,小时,天,分钟 + /// + /// + public static long DateDiff(string interval, DateTime startDate, DateTime endDate) + { + long retVal = 0; + var ts = new TimeSpan(endDate.Ticks - startDate.Ticks); + if (interval == "second") + { + retVal = (long)ts.TotalSeconds; + } + else if (interval == "minute") + { + retVal = (long) ts.TotalMinutes; + } + else if (interval == "hour") + { + retVal = (long) ts.TotalHours; + } + else if (interval == "day") + { + retVal = ts.Days; + } + else if (interval == "week") + { + retVal = ts.Days / 7; + } + else if (interval == "month") + { + retVal = ts.Days / 30; + } + else if (interval == "quarter") + { + retVal = ts.Days / 30 / 3; + } + else if (interval == "year") + { + retVal = ts.Days / 365; + } + return retVal; + } + + private static readonly DateTime UnixEpoch = new DateTime(1970, 1, 1); + + public static long ToUnixTime(DateTimeOffset? offset) + { + return offset.HasValue ? ToUnixTime(offset.Value.DateTime) : 0; + } + + public static long ToUnixTime(DateTime dateTime) + { + return (dateTime - UnixEpoch).Ticks / TimeSpan.TicksPerMillisecond; + } + } +} diff --git a/SiteServer.Utils/DirectoryUtils.cs b/src/SiteServer.Utils/DirectoryUtils.cs similarity index 95% rename from SiteServer.Utils/DirectoryUtils.cs rename to src/SiteServer.Utils/DirectoryUtils.cs index 7956582b9..339ed1dd2 100644 --- a/SiteServer.Utils/DirectoryUtils.cs +++ b/src/SiteServer.Utils/DirectoryUtils.cs @@ -7,47 +7,48 @@ namespace SiteServer.Utils /// /// 封装操作文件夹代码的类 /// - public class DirectoryUtils + public static class DirectoryUtils { - public class AspnetClient + public static class AspnetClient { public const string DirectoryName = "aspnet_client"; } - public class Bin + public static class Bin { public const string DirectoryName = "Bin"; } - public class Obj - { - public const string DirectoryName = "obj"; - } - - public class PublishmentSytem + public static class PublishmentSytem { public const string Include = "Include"; public const string Template = "Template"; public const string Content = "Content"; } - public class SiteServer + public static class SiteServer { public const string DirectoryName = "SiteServer"; } - public class SiteFiles + public static class Home + { + public const string DirectoryName = "Home"; + } + + public static class SiteFiles { public const string DirectoryName = "SiteFiles"; - public const string UserFiles = "UserFiles"; public const string BackupFiles = "BackupFiles"; public const string TemporaryFiles = "TemporaryFiles"; public const string Plugins = "Plugins"; public const string Packages = "packages"; + public const string Home = "Home"; + public const string Administrators = "Administrators"; } - public class SiteTemplates + public static class SiteTemplates { public const string DirectoryName = "SiteTemplates"; //文件夹 @@ -137,6 +138,10 @@ public static string GetDirectoryPath(string path) return directoryPath; } + public static string GetParentPath(string path) + { + return Directory.GetParent(path).FullName; + } public static bool IsDirectoryExists(string directoryPath) { diff --git a/src/SiteServer.Utils/Enumerations/EBoolean.cs b/src/SiteServer.Utils/Enumerations/EBoolean.cs new file mode 100644 index 000000000..d29d216cd --- /dev/null +++ b/src/SiteServer.Utils/Enumerations/EBoolean.cs @@ -0,0 +1,73 @@ +using System; + +namespace SiteServer.Utils.Enumerations +{ + public enum EBoolean + { + True, + False + } + + public class EBooleanUtils + { + public static string GetValue(EBoolean type) + { + if (type == EBoolean.True) + { + return "True"; + } + if (type == EBoolean.False) + { + return "False"; + } + throw new Exception(); + } + + public static string GetText(EBoolean type) + { + if (type == EBoolean.True) + { + return "是"; + } + if (type == EBoolean.False) + { + return "否"; + } + throw new Exception(); + } + + public static EBoolean GetEnumType(string typeStr) + { + var retval = EBoolean.False; + + if (Equals(EBoolean.True, typeStr)) + { + retval = EBoolean.True; + } + else if (Equals(EBoolean.False, typeStr)) + { + retval = EBoolean.False; + } + + return retval; + } + + public static bool Equals(EBoolean type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, EBoolean type) + { + return Equals(type, typeStr); + } + + + + } +} diff --git a/SiteServer.Utils/Enumerations/ECharset.cs b/src/SiteServer.Utils/Enumerations/ECharset.cs similarity index 78% rename from SiteServer.Utils/Enumerations/ECharset.cs rename to src/SiteServer.Utils/Enumerations/ECharset.cs index 06d67ebc8..2b1088756 100644 --- a/SiteServer.Utils/Enumerations/ECharset.cs +++ b/src/SiteServer.Utils/Enumerations/ECharset.cs @@ -1,6 +1,5 @@ using System; using System.Text; -using System.Web.UI.WebControls; namespace SiteServer.Utils.Enumerations { @@ -225,38 +224,6 @@ public static bool Equals(string typeStr, ECharset type) return Equals(type, typeStr); } - public static ListItem GetListItem(ECharset type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(ECharset.utf_8, false)); - listControl.Items.Add(GetListItem(ECharset.gb2312, false)); - listControl.Items.Add(GetListItem(ECharset.big5, false)); - listControl.Items.Add(GetListItem(ECharset.iso_8859_1, false)); - listControl.Items.Add(GetListItem(ECharset.euc_kr, false)); - listControl.Items.Add(GetListItem(ECharset.euc_jp, false)); - listControl.Items.Add(GetListItem(ECharset.iso_8859_6, false)); - listControl.Items.Add(GetListItem(ECharset.windows_874, false)); - listControl.Items.Add(GetListItem(ECharset.iso_8859_9, false)); - listControl.Items.Add(GetListItem(ECharset.iso_8859_5, false)); - listControl.Items.Add(GetListItem(ECharset.iso_8859_8, false)); - listControl.Items.Add(GetListItem(ECharset.iso_8859_7, false)); - listControl.Items.Add(GetListItem(ECharset.windows_1258, false)); - listControl.Items.Add(GetListItem(ECharset.iso_8859_2, false)); - } - } - public static Encoding GetEncoding(ECharset type) { if (type == ECharset.utf_8) @@ -275,7 +242,6 @@ public static Encoding GetEncoding(string typeStr) return Encoding.GetEncoding(typeStr); } - private static readonly Encoding gb2312 = Encoding.GetEncoding("gb2312"); - public static Encoding GB2312 => gb2312; + public static Encoding Gb2312 { get; } = Encoding.GetEncoding("gb2312"); } } diff --git a/src/SiteServer.Utils/Enumerations/EDataFormat.cs b/src/SiteServer.Utils/Enumerations/EDataFormat.cs new file mode 100644 index 000000000..9c9de1ae1 --- /dev/null +++ b/src/SiteServer.Utils/Enumerations/EDataFormat.cs @@ -0,0 +1,79 @@ +using System; + +namespace SiteServer.Utils.Enumerations +{ + public enum EDataFormat + { + String, + Json, + Xml + } + + public class EDataFormatUtils + { + public static string GetValue(EDataFormat type) + { + if (type == EDataFormat.String) + { + return "String"; + } + if (type == EDataFormat.Json) + { + return "Json"; + } + if (type == EDataFormat.Xml) + { + return "Xml"; + } + throw new Exception(); + } + + public static string GetText(EDataFormat type) + { + if (type == EDataFormat.String) + { + return "默认"; + } + if (type == EDataFormat.Json) + { + return "Json"; + } + if (type == EDataFormat.Xml) + { + return "Xml"; + } + throw new Exception(); + } + + public static EDataFormat GetEnumType(string typeStr) + { + var retval = EDataFormat.String; + + if (Equals(EDataFormat.Json, typeStr)) + { + retval = EDataFormat.Json; + } + else if (Equals(EDataFormat.Xml, typeStr)) + { + retval = EDataFormat.Xml; + } + + return retval; + } + + public static bool Equals(EDataFormat type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, EDataFormat type) + { + return Equals(type, typeStr); + } + } +} diff --git a/SiteServer.Utils/Enumerations/EDateFormatType.cs b/src/SiteServer.Utils/Enumerations/EDateFormatType.cs similarity index 76% rename from SiteServer.Utils/Enumerations/EDateFormatType.cs rename to src/SiteServer.Utils/Enumerations/EDateFormatType.cs index 9575cce05..fc5e29d66 100644 --- a/SiteServer.Utils/Enumerations/EDateFormatType.cs +++ b/src/SiteServer.Utils/Enumerations/EDateFormatType.cs @@ -1,5 +1,4 @@ using System; -using System.Web.UI.WebControls; namespace SiteServer.Utils.Enumerations { @@ -94,26 +93,7 @@ public static bool Equals(string typeStr, EDateFormatType type) return Equals(type, typeStr); } - public static ListItem GetListItem(EDateFormatType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EDateFormatType.Month, false)); - listControl.Items.Add(GetListItem(EDateFormatType.Day, false)); - listControl.Items.Add(GetListItem(EDateFormatType.Year, false)); - listControl.Items.Add(GetListItem(EDateFormatType.Chinese, false)); - } - } + } } diff --git a/SiteServer.Utils/Enumerations/EFileSystemType.cs b/src/SiteServer.Utils/Enumerations/EFileSystemType.cs similarity index 96% rename from SiteServer.Utils/Enumerations/EFileSystemType.cs rename to src/SiteServer.Utils/Enumerations/EFileSystemType.cs index 45bac5ae8..4f59cae33 100644 --- a/SiteServer.Utils/Enumerations/EFileSystemType.cs +++ b/src/SiteServer.Utils/Enumerations/EFileSystemType.cs @@ -1,5 +1,4 @@ using System; -using System.Web.UI.WebControls; namespace SiteServer.Utils.Enumerations { @@ -18,6 +17,7 @@ public enum EFileSystemType Js, Ascx, Css, + Csv, Jpg, Jpeg, Gif, @@ -113,7 +113,11 @@ public static string GetValue(EFileSystemType type) { return ".css"; } - if (type == EFileSystemType.Jpg) + if (type == EFileSystemType.Csv) + { + return ".csv"; + } + if (type == EFileSystemType.Jpg) { return ".jpg"; } @@ -318,7 +322,11 @@ public static string GetText(EFileSystemType type) { return "Cascading Style Sheet Document"; } - if (type == EFileSystemType.Jpg) + if (type == EFileSystemType.Csv) + { + return "Excel 工作表"; + } + if (type == EFileSystemType.Jpg) { return "JPEG 图像"; } @@ -513,7 +521,11 @@ public static EFileSystemType GetEnumType(string typeStr) { retval = EFileSystemType.Css; } - else if (Equals(EFileSystemType.Jpg, typeStr)) + else if (Equals(EFileSystemType.Csv, typeStr)) + { + retval = EFileSystemType.Csv; + } + else if (Equals(EFileSystemType.Jpg, typeStr)) { retval = EFileSystemType.Jpg; } @@ -661,27 +673,7 @@ public static EFileSystemType GetEnumType(string typeStr) return retval; } - public static ListItem GetListItem(EFileSystemType type, bool selected) - { - var item = new ListItem(GetValue(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddWebPageListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EFileSystemType.Html, false)); - listControl.Items.Add(GetListItem(EFileSystemType.Htm, false)); - listControl.Items.Add(GetListItem(EFileSystemType.SHtml, false)); - listControl.Items.Add(GetListItem(EFileSystemType.Xml, false)); - listControl.Items.Add(GetListItem(EFileSystemType.Json, false)); - } - } + public static string GetResponseContentType(EFileSystemType type) { @@ -737,6 +729,10 @@ public static string GetResponseContentType(EFileSystemType type) { return "text/css"; } + if (type == EFileSystemType.Csv) + { + return "application/vnd.ms-excel"; + } if (type == EFileSystemType.Jpg) { return "image/jpeg"; @@ -970,7 +966,7 @@ public static bool IsImage(string fileExtName) { fileExtName = "." + fileExtName; } - if (fileExtName == ".bmp" || fileExtName == ".gif" || fileExtName == ".jpg" || fileExtName == ".jpeg" || fileExtName == ".png" || fileExtName == ".pneg") + if (fileExtName == ".bmp" || fileExtName == ".gif" || fileExtName == ".jpg" || fileExtName == ".jpeg" || fileExtName == ".png" || fileExtName == ".pneg" || fileExtName == ".webp") { retval = true; } @@ -1029,7 +1025,7 @@ public static bool IsImageOrFlashOrPlayer(string fileExtName) { fileExtName = "." + fileExtName; } - if (fileExtName == ".bmp" || fileExtName == ".gif" || fileExtName == ".jpeg" || fileExtName == ".jpg" || fileExtName == ".png" || fileExtName == ".pneg" || fileExtName == ".swf") + if (fileExtName == ".bmp" || fileExtName == ".gif" || fileExtName == ".jpeg" || fileExtName == ".jpg" || fileExtName == ".png" || fileExtName == ".pneg" || fileExtName == ".webp" || fileExtName == ".swf") { retval = true; } diff --git a/src/SiteServer.Utils/Enumerations/EPasswordFormat.cs b/src/SiteServer.Utils/Enumerations/EPasswordFormat.cs new file mode 100644 index 000000000..0624b63b5 --- /dev/null +++ b/src/SiteServer.Utils/Enumerations/EPasswordFormat.cs @@ -0,0 +1,83 @@ +using System; + +namespace SiteServer.Utils.Enumerations +{ + public enum EPasswordFormat + { + Clear, + Hashed, + Encrypted + } + + public class EPasswordFormatUtils + { + public static string GetValue(EPasswordFormat type) + { + if (type == EPasswordFormat.Clear) + { + return "Clear"; + } + if (type == EPasswordFormat.Hashed) + { + return "Hashed"; + } + if (type == EPasswordFormat.Encrypted) + { + return "Encrypted"; + } + throw new Exception(); + } + + public static string GetText(EPasswordFormat type) + { + if (type == EPasswordFormat.Clear) + { + return "不加密"; + } + if (type == EPasswordFormat.Hashed) + { + return "不可逆方式加密"; + } + if (type == EPasswordFormat.Encrypted) + { + return "可逆方式加密"; + } + throw new Exception(); + } + + public static EPasswordFormat GetEnumType(string typeStr) + { + var retval = EPasswordFormat.Encrypted; + + if (Equals(EPasswordFormat.Clear, typeStr)) + { + retval = EPasswordFormat.Clear; + } + else if (Equals(EPasswordFormat.Hashed, typeStr)) + { + retval = EPasswordFormat.Hashed; + } + else if (Equals(EPasswordFormat.Encrypted, typeStr)) + { + retval = EPasswordFormat.Encrypted; + } + + return retval; + } + + public static bool Equals(EPasswordFormat type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, EPasswordFormat type) + { + return Equals(type, typeStr); + } + } +} diff --git a/src/SiteServer.Utils/Enumerations/EPredefinedRole.cs b/src/SiteServer.Utils/Enumerations/EPredefinedRole.cs new file mode 100644 index 000000000..523d08501 --- /dev/null +++ b/src/SiteServer.Utils/Enumerations/EPredefinedRole.cs @@ -0,0 +1,202 @@ +using System.Collections.Generic; + +namespace SiteServer.Utils.Enumerations +{ + public enum EPredefinedRole + { + ConsoleAdministrator, //超级管理员 + SystemAdministrator, //站点管理员 + Administrator, //管理员 + } + + public class EPredefinedRoleUtils + { + public static string GetValue(EPredefinedRole type) + { + if (type == EPredefinedRole.ConsoleAdministrator) + { + return "ConsoleAdministrator"; + } + if (type == EPredefinedRole.SystemAdministrator) + { + return "SystemAdministrator"; + } + if (type == EPredefinedRole.Administrator) + { + return "Administrator"; + } + return string.Empty; + } + + public static string GetText(EPredefinedRole type) + { + if (type == EPredefinedRole.ConsoleAdministrator) + { + return "超级管理员"; + } + if (type == EPredefinedRole.SystemAdministrator) + { + return "站点管理员"; + } + if (type == EPredefinedRole.Administrator) + { + return "管理员"; + } + return string.Empty; + } + + public static bool IsPredefinedRole(string roleName) + { + var retval = false; + if (Equals(EPredefinedRole.ConsoleAdministrator, roleName)) + { + retval = true; + } + else if (Equals(EPredefinedRole.SystemAdministrator, roleName)) + { + retval = true; + } + else if (Equals(EPredefinedRole.Administrator, roleName)) + { + retval = true; + } + + return retval; + } + + public static EPredefinedRole GetEnumType(string typeStr) + { + var retval = EPredefinedRole.Administrator; + + if (Equals(EPredefinedRole.ConsoleAdministrator, typeStr)) + { + retval = EPredefinedRole.ConsoleAdministrator; + } + else if (Equals(EPredefinedRole.SystemAdministrator, typeStr)) + { + retval = EPredefinedRole.SystemAdministrator; + } + + return retval; + } + + public static EPredefinedRole GetEnumTypeByRoles(IList roles) + { + var isConsoleAdministrator = false; + var isSystemAdministrator = false; + + if (roles != null) + { + foreach (var role in roles) + { + if (Equals(EPredefinedRole.ConsoleAdministrator, role)) + { + isConsoleAdministrator = true; + } + else if (Equals(EPredefinedRole.SystemAdministrator, role)) + { + isSystemAdministrator = true; + } + } + } + if (isConsoleAdministrator) return EPredefinedRole.ConsoleAdministrator; + if (isSystemAdministrator) return EPredefinedRole.SystemAdministrator; + return EPredefinedRole.Administrator; + } + + public static bool Equals(EPredefinedRole type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, EPredefinedRole type) + { + return Equals(type, typeStr); + } + + + + public static bool IsConsoleAdministrator(IList roles) + { + return roles != null && roles.Contains(GetValue(EPredefinedRole.ConsoleAdministrator)); + } + + public static bool IsSystemAdministrator(IList roles) + { + return roles != null && (roles.Contains(GetValue(EPredefinedRole.ConsoleAdministrator)) || roles.Contains(GetValue(EPredefinedRole.SystemAdministrator))); + + // var retval = false; + //if (roles != null && roles.Length > 0) + //{ + // foreach (var role in roles) + // { + // if (Equals(EPredefinedRole.ConsoleAdministrator, role)) + // { + // retval = true; + // break; + // } + // if (Equals(EPredefinedRole.SystemAdministrator, role)) + // { + // retval = true; + // break; + // } + // } + //} + //return retval; + } + + public static bool IsAdministrator(List roles) + { + return roles != null && (roles.Contains(GetValue(EPredefinedRole.ConsoleAdministrator)) || roles.Contains(GetValue(EPredefinedRole.SystemAdministrator)) || roles.Contains(GetValue(EPredefinedRole.Administrator))); + + //var retval = false; + //if (roles != null && roles.Length > 0) + //{ + // foreach (var role in roles) + // { + // if (Equals(EPredefinedRole.ConsoleAdministrator, role)) + // { + // retval = true; + // break; + // } + // if (Equals(EPredefinedRole.SystemAdministrator, role)) + // { + // retval = true; + // break; + // } + // if(Equals(EPredefinedRole.Administrator,role)) + // { + // retval = true; + // break; + // } + // } + //} + //return retval; + } + + public static List GetAllPredefinedRoleName() + { + return new List + { + GetValue(EPredefinedRole.Administrator), + GetValue(EPredefinedRole.SystemAdministrator), + GetValue(EPredefinedRole.ConsoleAdministrator) + }; + } + + public static List GetAllPredefinedRole() + { + return new List + { + EPredefinedRole.Administrator, + EPredefinedRole.SystemAdministrator, + EPredefinedRole.ConsoleAdministrator + }; + } + } +} diff --git a/SiteServer.Utils/Enumerations/EScopeType.cs b/src/SiteServer.Utils/Enumerations/EScopeType.cs similarity index 77% rename from SiteServer.Utils/Enumerations/EScopeType.cs rename to src/SiteServer.Utils/Enumerations/EScopeType.cs index 5e56a90e7..67beb304c 100644 --- a/SiteServer.Utils/Enumerations/EScopeType.cs +++ b/src/SiteServer.Utils/Enumerations/EScopeType.cs @@ -1,5 +1,4 @@ using System; -using System.Web.UI.WebControls; namespace SiteServer.Utils.Enumerations { @@ -107,27 +106,7 @@ public static bool Equals(string typeStr, EScopeType type) return Equals(type, typeStr); } - public static ListItem GetListItem(EScopeType type, bool selected) - { - var item = new ListItem(GetValue(type) + " (" + GetText(type) + ")", GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EScopeType.Self, false)); - listControl.Items.Add(GetListItem(EScopeType.Children, false)); - listControl.Items.Add(GetListItem(EScopeType.SelfAndChildren, false)); - listControl.Items.Add(GetListItem(EScopeType.Descendant, false)); - listControl.Items.Add(GetListItem(EScopeType.All, false)); - } - } + // public static EScopeType GetEnumTypeForChannel(string typeStr) diff --git a/SiteServer.Utils/Enumerations/EStaticXType.cs b/src/SiteServer.Utils/Enumerations/EStaticXType.cs similarity index 77% rename from SiteServer.Utils/Enumerations/EStaticXType.cs rename to src/SiteServer.Utils/Enumerations/EStaticXType.cs index a4d179b5d..b5a9a340f 100644 --- a/SiteServer.Utils/Enumerations/EStaticXType.cs +++ b/src/SiteServer.Utils/Enumerations/EStaticXType.cs @@ -1,5 +1,4 @@ using System; -using System.Web.UI.WebControls; namespace SiteServer.Utils.Enumerations { @@ -95,25 +94,7 @@ public static bool Equals(string typeStr, EStatictisXType type) return Equals(type, typeStr); } - public static ListItem GetListItem(EStatictisXType type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EStatictisXType.Day, false)); - listControl.Items.Add(GetListItem(EStatictisXType.Month, false)); - listControl.Items.Add(GetListItem(EStatictisXType.Year, false)); - } - } + } } diff --git a/src/SiteServer.Utils/Enumerations/ETimeFormatType.cs b/src/SiteServer.Utils/Enumerations/ETimeFormatType.cs new file mode 100644 index 000000000..a6e10ad17 --- /dev/null +++ b/src/SiteServer.Utils/Enumerations/ETimeFormatType.cs @@ -0,0 +1,8 @@ +namespace SiteServer.Utils.Enumerations +{ + public enum ETimeFormatType + { + ShortTime, //8:09 + LongTime //8:09:24 + } +} diff --git a/src/SiteServer.Utils/Enumerations/ETriState.cs b/src/SiteServer.Utils/Enumerations/ETriState.cs new file mode 100644 index 000000000..40eb11214 --- /dev/null +++ b/src/SiteServer.Utils/Enumerations/ETriState.cs @@ -0,0 +1,81 @@ +using System; + +namespace SiteServer.Utils.Enumerations +{ + public enum ETriState + { + All, + True, + False + } + + public class ETriStateUtils + { + public static string GetValue(ETriState type) + { + if (type == ETriState.All) + { + return "All"; + } + if (type == ETriState.True) + { + return "True"; + } + if (type == ETriState.False) + { + return "False"; + } + throw new Exception(); + } + + public static string GetText(ETriState type, string allText, string trueText, string falseText) + { + if (type == ETriState.All) + { + return allText; + } + if (type == ETriState.False) + { + return falseText; + } + return trueText; + } + + public static ETriState GetEnumType(string typeStr) + { + var retval = ETriState.All; + + if (Equals(ETriState.All, typeStr)) + { + retval = ETriState.All; + } + else if (Equals(ETriState.True, typeStr)) + { + retval = ETriState.True; + } + else if (Equals(ETriState.False, typeStr)) + { + retval = ETriState.False; + } + + return retval; + } + + public static bool Equals(ETriState type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(GetValue(type).ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, ETriState type) + { + return Equals(type, typeStr); + } + + + } +} diff --git a/SiteServer.Utils/Enumerations/EUploadType.cs b/src/SiteServer.Utils/Enumerations/EUploadType.cs similarity index 100% rename from SiteServer.Utils/Enumerations/EUploadType.cs rename to src/SiteServer.Utils/Enumerations/EUploadType.cs diff --git a/SiteServer.Utils/Enumerations/EUserBindingType.cs b/src/SiteServer.Utils/Enumerations/EUserBindingType.cs similarity index 100% rename from SiteServer.Utils/Enumerations/EUserBindingType.cs rename to src/SiteServer.Utils/Enumerations/EUserBindingType.cs diff --git a/SiteServer.Utils/Enumerations/EUserLockType.cs b/src/SiteServer.Utils/Enumerations/EUserLockType.cs similarity index 100% rename from SiteServer.Utils/Enumerations/EUserLockType.cs rename to src/SiteServer.Utils/Enumerations/EUserLockType.cs diff --git a/SiteServer.Utils/Enumerations/EUserPasswordRestriction.cs b/src/SiteServer.Utils/Enumerations/EUserPasswordRestriction.cs similarity index 83% rename from SiteServer.Utils/Enumerations/EUserPasswordRestriction.cs rename to src/SiteServer.Utils/Enumerations/EUserPasswordRestriction.cs index 2b0ac6488..393b6420e 100644 --- a/SiteServer.Utils/Enumerations/EUserPasswordRestriction.cs +++ b/src/SiteServer.Utils/Enumerations/EUserPasswordRestriction.cs @@ -1,5 +1,4 @@ using System; -using System.Web.UI.WebControls; namespace SiteServer.Utils.Enumerations { @@ -10,7 +9,7 @@ public enum EUserPasswordRestriction LetterAndDigitAndSymbol } - public class EUserPasswordRestrictionUtils + public static class EUserPasswordRestrictionUtils { public static string GetValue(EUserPasswordRestriction type) { @@ -81,25 +80,7 @@ public static bool Equals(string typeStr, EUserPasswordRestriction type) return Equals(type, typeStr); } - public static ListItem GetListItem(EUserPasswordRestriction type, bool selected) - { - var item = new ListItem(GetText(type), GetValue(type)); - if (selected) - { - item.Selected = true; - } - return item; - } - - public static void AddListItems(ListControl listControl) - { - if (listControl != null) - { - listControl.Items.Add(GetListItem(EUserPasswordRestriction.None, false)); - listControl.Items.Add(GetListItem(EUserPasswordRestriction.LetterAndDigit, false)); - listControl.Items.Add(GetListItem(EUserPasswordRestriction.LetterAndDigitAndSymbol, false)); - } - } + public static bool IsValid(string password, string restrictionStr) { @@ -146,7 +127,7 @@ public static bool IsValid(string password, string restrictionStr) { isDigit = true; } - else if (char.IsSymbol(c)) + else if (char.IsPunctuation(c) || char.IsSymbol(c)) { isSymbol = true; } diff --git a/src/SiteServer.Utils/Extensions.cs b/src/SiteServer.Utils/Extensions.cs new file mode 100644 index 000000000..7d7078bcb --- /dev/null +++ b/src/SiteServer.Utils/Extensions.cs @@ -0,0 +1,309 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using SiteServer.Plugin; + +namespace SiteServer.Utils +{ + public static class Extensions + { + public static bool IsDefault(this T value) where T : struct + { + return value.Equals(default(T)); + } + + public static string ToCamelCase(this string str) + { + if (!string.IsNullOrEmpty(str) && str.Length > 1) + { + return char.ToLowerInvariant(str[0]) + str.Substring(1); + } + return str; + } + + public static void AddRange(this IList list, IEnumerable items) + { + if (list == null || items == null) return; + + if (list is List) + { + ((List)list).AddRange(items); + } + else + { + foreach (var item in items) + { + list.Add(item); + } + } + } + + /// + /// Returns an individual HTTP Header value + /// + public static string GetHeader(this HttpRequestMessage request, string key) + { + if (request == null) + throw new ArgumentNullException(nameof(request)); + return !request.Headers.TryGetValues(key, out var keys) ? null : keys.First(); + } + + /// + /// Retrieves an individual cookie from the cookies collection + /// + public static string GetCookie(this HttpRequestMessage request, string cookieName) + { + if (request == null) + throw new ArgumentNullException(nameof(request)); + + var cookie = request.Headers.GetCookies(cookieName).FirstOrDefault(); + var value = cookie?[cookieName].Value; + return TranslateUtils.DecryptStringBySecretKey(value); + } + + //public static IDictionary GetQueryDirectory(this HttpRequestMessage request) + //{ + // IDictionary dict = null; + // if (request.Properties.ContainsKey("QueryDictionary")) + // { + // dict = TranslateUtils.Get>(request.Properties, "QueryDictionary"); + // } + + // if (dict != null) return dict; + + // dict = request.GetQueryNameValuePairs() + // .ToDictionary(kv => kv.Key, kv => kv.Value, StringComparer.OrdinalIgnoreCase); + + // request.Properties["QueryDictionary"] = dict; + + // return dict; + //} + + //public static bool IsQueryExists(this HttpRequestMessage request, string name) + //{ + // var dict = request.GetQueryDirectory(); + // return dict.ContainsKey(name); + //} + + //public static string GetQueryString(this HttpRequestMessage request, string name) + //{ + // if (string.IsNullOrEmpty(name)) return null; + // var dict = request.GetQueryDirectory(); + // return dict.TryGetValue(name, out var value) ? value : null; + //} + + //public static int GetQueryInt(this HttpRequestMessage request, string name, int defaultValue = 0) + //{ + // return TranslateUtils.ToIntWithNegative(request.GetQueryString(name), defaultValue); + //} + + //public static decimal GetQueryDecimal(this HttpRequestMessage request, string name, decimal defaultValue = 0) + //{ + // return TranslateUtils.ToDecimalWithNegative(request.GetQueryString(name), defaultValue); + //} + + //public static bool GetQueryBool(this HttpRequestMessage request, string name, bool defaultValue = false) + //{ + // return TranslateUtils.ToBool(request.GetQueryString(name), false); + //} + + //public static IDictionary GetPostDictionary(this HttpRequestMessage request) + //{ + // IDictionary dict = null; + // if (request.Properties.ContainsKey("PostDictionary")) + // { + // dict = TranslateUtils.Get>(request.Properties, "PostDictionary"); + // } + + // if (dict != null) return dict; + + // dict = new Dictionary(StringComparer.OrdinalIgnoreCase); + + // var json = request.Content.ReadAsStringAsync().Result; + // if (string.IsNullOrEmpty(json)) return dict; + + // var originalDict = TranslateUtils.JsonDeserialize>(json); + // if (originalDict != null) + // { + // foreach (var key in originalDict.Keys) + // { + // dict[key] = originalDict[key]; + // } + // } + + // request.Properties["PostDictionary"] = dict; + + // return dict; + //} + + //public static T GetPostObject(this HttpRequestMessage request) + //{ + // var json = request.Content.ReadAsStringAsync().Result; + // return TranslateUtils.JsonDeserialize(json); + //} + + //public static T GetPostObject(this HttpRequestMessage request, string name) + //{ + // var json = request.GetPostString(name); + // return TranslateUtils.JsonDeserialize(json); + //} + + //public static bool IsPostExists(this HttpRequestMessage request, string name) + //{ + // var dict = request.GetPostDictionary(); + // return dict.ContainsKey(name); + //} + + //private static object GetPostObject(this HttpRequestMessage request, string name) + //{ + // if (string.IsNullOrEmpty(name)) return null; + + // var dict = request.GetPostDictionary(); + + // return dict.TryGetValue(name, out var value) ? value : null; + //} + + //public static string GetPostString(this HttpRequestMessage request, string name) + //{ + // var value = request.GetPostObject(name); + // switch (value) + // { + // case null: + // return null; + // case string s: + // return s; + // default: + // return value.ToString(); + // } + //} + + //public static int GetPostInt(this HttpRequestMessage request, string name, int defaultValue = 0) + //{ + // var value = request.GetPostObject(name); + // switch (value) + // { + // case null: + // return 0; + // case int _: + // return (int)value; + // default: + // return TranslateUtils.ToIntWithNegative(value.ToString(), defaultValue); + // } + //} + + //public static decimal GetPostDecimal(this HttpRequestMessage request, string name, decimal defaultValue = 0) + //{ + // var value = request.GetPostObject(name); + // switch (value) + // { + // case null: + // return 0; + // case decimal _: + // return (decimal)value; + // default: + // return TranslateUtils.ToDecimalWithNegative(value.ToString(), defaultValue); + // } + //} + + //public static bool GetPostBool(this HttpRequestMessage request, string name, bool defaultValue = false) + //{ + // var value = request.GetPostObject(name); + // switch (value) + // { + // case null: + // return false; + // case bool _: + // return (bool)value; + // default: + // return TranslateUtils.ToBool(value.ToString(), defaultValue); + // } + //} + + //public static DateTime GetPostDateTime(this HttpRequestMessage request, string name, DateTime defaultValue) + //{ + // var value = request.GetPostObject(name); + // switch (value) + // { + // case null: + // return DateTime.Now; + // case DateTime _: + // return (DateTime)value; + // default: + // return TranslateUtils.ToDateTime(value.ToString(), defaultValue); + // } + //} + + public static string GetApiToken(this HttpRequestMessage request) + { + var accessTokenStr = string.Empty; + if (!string.IsNullOrEmpty(request.GetHeader(Constants.AuthKeyApiHeader))) + { + accessTokenStr = request.GetHeader(Constants.AuthKeyApiHeader); + } + else if (request.IsQueryExists(Constants.AuthKeyApiQuery)) + { + accessTokenStr = request.GetQueryString(Constants.AuthKeyApiQuery); + } + else if (!string.IsNullOrEmpty(request.GetCookie(Constants.AuthKeyApiCookie))) + { + accessTokenStr = request.GetCookie(Constants.AuthKeyApiCookie); + } + + if (StringUtils.EndsWith(accessTokenStr, TranslateUtils.EncryptStingIndicator)) + { + accessTokenStr = TranslateUtils.DecryptStringBySecretKey(accessTokenStr); + } + + return accessTokenStr; + } + + public static string GetUserToken(this HttpRequestMessage request) + { + var accessTokenStr = string.Empty; + if (!string.IsNullOrEmpty(request.GetCookie(Constants.AuthKeyUserCookie))) + { + accessTokenStr = request.GetCookie(Constants.AuthKeyUserCookie); + } + else if (!string.IsNullOrEmpty(request.GetHeader(Constants.AuthKeyUserHeader))) + { + accessTokenStr = request.GetHeader(Constants.AuthKeyUserHeader); + } + else if (request.IsQueryExists(Constants.AuthKeyUserQuery)) + { + accessTokenStr = request.GetQueryString(Constants.AuthKeyUserQuery); + } + + if (StringUtils.EndsWith(accessTokenStr, TranslateUtils.EncryptStingIndicator)) + { + accessTokenStr = TranslateUtils.DecryptStringBySecretKey(accessTokenStr); + } + + return accessTokenStr; + } + + public static string GetAdminToken(this HttpRequestMessage request) + { + var accessTokenStr = string.Empty; + if (!string.IsNullOrEmpty(request.GetCookie(Constants.AuthKeyAdminCookie))) + { + accessTokenStr = request.GetCookie(Constants.AuthKeyAdminCookie); + } + else if (!string.IsNullOrEmpty(request.GetHeader(Constants.AuthKeyAdminHeader))) + { + accessTokenStr = request.GetHeader(Constants.AuthKeyAdminHeader); + } + else if (request.IsQueryExists(Constants.AuthKeyAdminQuery)) + { + accessTokenStr = request.GetQueryString(Constants.AuthKeyAdminQuery); + } + + if (StringUtils.EndsWith(accessTokenStr, TranslateUtils.EncryptStingIndicator)) + { + accessTokenStr = TranslateUtils.DecryptStringBySecretKey(accessTokenStr); + } + + return accessTokenStr; + } + } +} diff --git a/SiteServer.Utils/FileUtils.cs b/src/SiteServer.Utils/FileUtils.cs similarity index 82% rename from SiteServer.Utils/FileUtils.cs rename to src/SiteServer.Utils/FileUtils.cs index bc3324745..52300efcb 100644 --- a/SiteServer.Utils/FileUtils.cs +++ b/src/SiteServer.Utils/FileUtils.cs @@ -1,6 +1,6 @@ using System; -using System.IO; using System.Collections.Generic; +using System.IO; using System.Security.Cryptography; using System.Text; using System.Threading.Tasks; @@ -8,8 +8,27 @@ namespace SiteServer.Utils { - public class FileUtils + public static class FileUtils { + public static string TryReadText(string filePath) + { + var text = string.Empty; + + try + { + if (IsFileExists(filePath)) + { + text = ReadText(filePath, Encoding.UTF8); + } + } + catch + { + // ignored + } + + return text; + } + public static string ReadText(string filePath, ECharset charset) { var sr = new StreamReader(filePath, ECharsetUtils.GetEncoding(charset)); @@ -18,6 +37,11 @@ public static string ReadText(string filePath, ECharset charset) return text; } + public static string ReadText(string filePath) + { + return ReadText(filePath, Encoding.UTF8); + } + public static string ReadText(string filePath, Encoding encoding) { var sr = new StreamReader(filePath, encoding); @@ -26,11 +50,19 @@ public static string ReadText(string filePath, Encoding encoding) return text; } - public static async Task WriteTextAsync(string filePath, Encoding encoding, string content) + public static async Task ReadTextAsync(string filePath, Encoding encoding) + { + var sr = new StreamReader(filePath, encoding); + var text = await sr.ReadToEndAsync(); + sr.Close(); + return text; + } + + public static async Task WriteTextAsync(string filePath, string content) { DirectoryUtils.CreateDirectoryIfNotExists(filePath); - byte[] encodedText = encoding.GetBytes(content); + byte[] encodedText = Encoding.UTF8.GetBytes(content); using (FileStream sourceStream = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.None, bufferSize: 4096, useAsync: true)) @@ -44,7 +76,12 @@ public static void WriteText(string filePath, ECharset charset, string content) WriteText(filePath, ECharsetUtils.GetEncoding(charset), content); } - public static void WriteText(string filePath, Encoding encoding, string content) + public static void WriteText(string filePath, string content) + { + WriteText(filePath, Encoding.UTF8, content); + } + + public static void WriteText(string filePath, Encoding encoding, string content) { DirectoryUtils.CreateDirectoryIfNotExists(filePath); @@ -57,26 +94,47 @@ public static void WriteText(string filePath, Encoding encoding, string content) file.Close(); } - - // var sw = new StreamWriter(filePath, false, ECharsetUtils.GetEncoding(charset)); - //sw.Write(content); - //sw.Flush(); - //sw.Close(); } + public static void AppendText(string filePath, string content) + { + AppendText(filePath, Encoding.UTF8, content); + } + public static void AppendText(string filePath, ECharset charset, string content) { - DirectoryUtils.CreateDirectoryIfNotExists(filePath); + AppendText(filePath, ECharsetUtils.GetEncoding(charset), content); + } - using (var fs = new FileStream(filePath, FileMode.Append, FileAccess.Write)) - { - using (var sw = new StreamWriter(fs, ECharsetUtils.GetEncoding(charset))) - { - sw.Write(content); - } - } + public static void AppendText(string filePath, Encoding encoding, string content) + { + DirectoryUtils.CreateDirectoryIfNotExists(filePath); + + var file = new FileStream(filePath, FileMode.Append, FileAccess.Write); + using (var writer = new StreamWriter(file, encoding)) + { + writer.Write(content); + writer.Flush(); + writer.Close(); + + file.Close(); + } } + public static async Task AppendTextAsync(string filePath, string content) + { + DirectoryUtils.CreateDirectoryIfNotExists(filePath); + + var file = new FileStream(filePath, FileMode.Append, FileAccess.Write); + using (var writer = new StreamWriter(file, Encoding.UTF8)) + { + await writer.WriteAsync(content); + writer.Flush(); + writer.Close(); + + file.Close(); + } + } public static void RemoveReadOnlyAndHiddenIfExists(string filePath) { @@ -176,7 +234,6 @@ public static bool CopyFile(string sourceFilePath, string destFilePath, bool isO DirectoryUtils.CreateDirectoryIfNotExists(destFilePath); File.Copy(sourceFilePath, destFilePath, isOverride); - } catch { diff --git a/src/SiteServer.Utils/GlobalSuppressions.cs b/src/SiteServer.Utils/GlobalSuppressions.cs new file mode 100644 index 000000000..a5cc44efc Binary files /dev/null and b/src/SiteServer.Utils/GlobalSuppressions.cs differ diff --git a/SiteServer.Utils/HtmlClearUtils.cs b/src/SiteServer.Utils/HtmlClearUtils.cs similarity index 100% rename from SiteServer.Utils/HtmlClearUtils.cs rename to src/SiteServer.Utils/HtmlClearUtils.cs diff --git a/SiteServer.Utils/IO/EncodedStringWriter.cs b/src/SiteServer.Utils/IO/EncodedStringWriter.cs similarity index 100% rename from SiteServer.Utils/IO/EncodedStringWriter.cs rename to src/SiteServer.Utils/IO/EncodedStringWriter.cs diff --git a/SiteServer.Utils/IO/FTPFileSystemInfo.cs b/src/SiteServer.Utils/IO/FTPFileSystemInfo.cs similarity index 100% rename from SiteServer.Utils/IO/FTPFileSystemInfo.cs rename to src/SiteServer.Utils/IO/FTPFileSystemInfo.cs diff --git a/SiteServer.Utils/IO/FileSystemInfoExtend.cs b/src/SiteServer.Utils/IO/FileSystemInfoExtend.cs similarity index 94% rename from SiteServer.Utils/IO/FileSystemInfoExtend.cs rename to src/SiteServer.Utils/IO/FileSystemInfoExtend.cs index 5fab065e2..3f64357ce 100644 --- a/SiteServer.Utils/IO/FileSystemInfoExtend.cs +++ b/src/SiteServer.Utils/IO/FileSystemInfoExtend.cs @@ -4,7 +4,7 @@ namespace SiteServer.Utils.IO { /// - /// FileSystemInfoExtend ��ժҪ˵���� + /// FileSystemInfoExtend /// public class FileSystemInfoExtend : SimpleFileInfoBase { diff --git a/SiteServer.Utils/IO/FileSystemInfosExtend.cs b/src/SiteServer.Utils/IO/FileSystemInfosExtend.cs similarity index 100% rename from SiteServer.Utils/IO/FileSystemInfosExtend.cs rename to src/SiteServer.Utils/IO/FileSystemInfosExtend.cs diff --git a/SiteServer.Utils/IO/FileWatcherClass.cs b/src/SiteServer.Utils/IO/FileWatcherClass.cs similarity index 90% rename from SiteServer.Utils/IO/FileWatcherClass.cs rename to src/SiteServer.Utils/IO/FileWatcherClass.cs index 97b1e5e89..99917324e 100644 --- a/SiteServer.Utils/IO/FileWatcherClass.cs +++ b/src/SiteServer.Utils/IO/FileWatcherClass.cs @@ -6,9 +6,8 @@ namespace SiteServer.Utils.IO { public class FileWatcherClass { - public const string Node = nameof(Node); public const string Site = nameof(Site); - public const string TableMetadata = nameof(TableMetadata); + public const string Channel = nameof(Channel); public const string TableColumn = nameof(TableColumn); private FileSystemWatcher _fileSystemWatcher; @@ -26,11 +25,6 @@ public void UpdateCacheFile() FileUtils.WriteText(_cacheFilePath, ECharset.utf_8, "cache chaged:" + DateUtils.GetDateAndTimeString(DateTime.Now)); } - public void DeleteCacheFile() - { - FileUtils.DeleteFileIfExists(_cacheFilePath); - } - public delegate void FileChange(object sender, EventArgs e); //The OnFileChange event is fired when the file changes. diff --git a/SiteServer.Utils/IO/SimpleFileInfoBase.cs b/src/SiteServer.Utils/IO/SimpleFileInfoBase.cs similarity index 100% rename from SiteServer.Utils/IO/SimpleFileInfoBase.cs rename to src/SiteServer.Utils/IO/SimpleFileInfoBase.cs diff --git a/SiteServer.Utils/InputParserUtils.cs b/src/SiteServer.Utils/InputParserUtils.cs similarity index 79% rename from SiteServer.Utils/InputParserUtils.cs rename to src/SiteServer.Utils/InputParserUtils.cs index 45bdc1760..b51ff7457 100644 --- a/SiteServer.Utils/InputParserUtils.cs +++ b/src/SiteServer.Utils/InputParserUtils.cs @@ -1,7 +1,4 @@ -using System.Web.UI.WebControls; -using SiteServer.Plugin; - -namespace SiteServer.Utils +namespace SiteServer.Utils { public class InputParserUtils { @@ -19,31 +16,18 @@ private InputParserUtils() // return string.Empty; //} - public static string GetValidateAttributes(bool isValidate, string displayName, bool isRequire, int minNum, int maxNum, ValidateType validateType, string regExp, string errorMessage) + public static string GetValidateAttributes(bool isValidate, string displayName, bool isRequire, int minNum, int maxNum, string validateType, string regExp, string errorMessage) { if (isValidate) { return $@"isValidate=""{true.ToString().ToLower()}"" displayName=""{displayName}"" isRequire=""{isRequire - .ToString().ToLower()}"" minNum=""{minNum}"" maxNum=""{maxNum}"" validateType=""{validateType.Value}"" regExp=""{regExp}"" errorMessage=""{errorMessage}"""; + .ToString().ToLower()}"" minNum=""{minNum}"" maxNum=""{maxNum}"" validateType=""{validateType}"" regExp=""{regExp}"" errorMessage=""{errorMessage}"""; } return string.Empty; } - public static void GetValidateAttributesForListItem(ListControl control, bool isValidate, string displayName, bool isRequire, int minNum, int maxNum, ValidateType validateType, string regExp, string errorMessage) - { - if (!isValidate) return; - - control.Attributes.Add("isValidate", true.ToString().ToLower()); - control.Attributes.Add("displayName", displayName); - control.Attributes.Add("isRequire", isRequire.ToString().ToLower()); - control.Attributes.Add("minNum", minNum.ToString()); - control.Attributes.Add("maxNum", maxNum.ToString()); - control.Attributes.Add("validateType", validateType.Value); - control.Attributes.Add("regExp", regExp); - control.Attributes.Add("errorMessage", errorMessage); - control.Attributes.Add("isListItem", true.ToString().ToLower()); - } + public static string GetValidateSubmitOnClickScript(string formId) { @@ -59,7 +43,11 @@ public static string GetValidateSubmitOnClickScript(string formId) /// public static string GetValidateSubmitOnClickScript(string formId, bool isConfirm, string confirmFunction) { - return !isConfirm ? GetValidateSubmitOnClickScript(formId) : $"return checkFormValueById('{formId}') && {confirmFunction};"; + if (!string.IsNullOrWhiteSpace(confirmFunction)) + { + return !isConfirm ? GetValidateSubmitOnClickScript(formId) : $"return checkFormValueById('{formId}') && {confirmFunction};"; + } + return !isConfirm ? GetValidateSubmitOnClickScript(formId) : $"return checkFormValueById('{formId}');"; } //public static string GetAdditionalAttributes(string whereUsed, InputType inputType) diff --git a/SiteServer.Utils/ThirdParty/MvpXml/XPathNavigatorReader.cs b/src/SiteServer.Utils/MvpXml/XPathNavigatorReader.cs similarity index 99% rename from SiteServer.Utils/ThirdParty/MvpXml/XPathNavigatorReader.cs rename to src/SiteServer.Utils/MvpXml/XPathNavigatorReader.cs index ae60d0d22..ed5ffc637 100644 --- a/SiteServer.Utils/ThirdParty/MvpXml/XPathNavigatorReader.cs +++ b/src/SiteServer.Utils/MvpXml/XPathNavigatorReader.cs @@ -42,7 +42,7 @@ POSSIBILITY OF SUCH DAMAGE. #endregion using -namespace MvpXml +namespace SiteServer.Utils.MvpXml { /// /// Provides an over an diff --git a/SiteServer.Utils/ThirdParty/MvpXml/XmlNamespaces.cs b/src/SiteServer.Utils/MvpXml/XmlNamespaces.cs similarity index 98% rename from SiteServer.Utils/ThirdParty/MvpXml/XmlNamespaces.cs rename to src/SiteServer.Utils/MvpXml/XmlNamespaces.cs index 5fae41966..314788d0a 100644 --- a/SiteServer.Utils/ThirdParty/MvpXml/XmlNamespaces.cs +++ b/src/SiteServer.Utils/MvpXml/XmlNamespaces.cs @@ -37,7 +37,7 @@ POSSIBILITY OF SUCH DAMAGE. #endregion using -namespace MvpXml +namespace SiteServer.Utils.MvpXml { /// /// Provides public constants for wellknown XML namespaces. diff --git a/src/SiteServer.Utils/PageUtils.cs b/src/SiteServer.Utils/PageUtils.cs new file mode 100644 index 000000000..5459a4c73 --- /dev/null +++ b/src/SiteServer.Utils/PageUtils.cs @@ -0,0 +1,551 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Globalization; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; + +namespace SiteServer.Utils +{ + public static class PageUtils + { + public const char SeparatorChar = '/'; + + public const string UnClickedUrl = "javascript:;"; + + + + public static string AddEndSlashToUrl(string url) + { + if (string.IsNullOrEmpty(url) || !url.EndsWith("/")) + { + url += "/"; + } + + return url; + } + + + + + + public static string AddQuestionOrAndToUrl(string pageUrl) + { + var url = pageUrl; + if (string.IsNullOrEmpty(url)) + { + url = "?"; + } + else + { + if (url.IndexOf('?') == -1) + { + url = url + "?"; + } + else if (!url.EndsWith("?")) + { + url = url + "&"; + } + } + return url; + } + + public static string RemoveFileNameFromUrl(string url) + { + if (string.IsNullOrEmpty(url)) return string.Empty; + + url = url.Trim(); + if (url.Contains("/")) + { + var fileName = url.Substring(url.LastIndexOf("/", StringComparison.Ordinal)); + if (fileName.Contains(".")) + { + return url.Substring(0, url.LastIndexOf("/", StringComparison.Ordinal)); + } + } + + return url; + } + + public static string RemoveProtocolFromUrl(string url) + { + if (string.IsNullOrEmpty(url)) return string.Empty; + + url = url.Trim(); + return IsProtocolUrl(url) ? url.Substring(url.IndexOf("://", StringComparison.Ordinal) + 3) : url; + } + + public static bool IsProtocolUrl(string url) + { + if (string.IsNullOrEmpty(url)) return false; + + url = url.Trim(); + return url.IndexOf("://", StringComparison.Ordinal) != -1 || url.StartsWith("javascript:"); + } + + public static bool IsAbsoluteUrl(string url) + { + if (string.IsNullOrEmpty(url)) return false; + + url = url.Trim(); + return url.StartsWith("/") || url.IndexOf("://", StringComparison.Ordinal) != -1 || url.StartsWith("javascript:"); + } + + public static string PathDifference(string path1, string path2, bool compareCase) + { + var num2 = -1; + var num1 = 0; + while ((num1 < path1.Length) && (num1 < path2.Length)) + { + if ((path1[num1] != path2[num1]) && (compareCase || (char.ToLower(path1[num1], CultureInfo.InvariantCulture) != char.ToLower(path2[num1], CultureInfo.InvariantCulture)))) + { + break; + } + if (path1[num1] == '/') + { + num2 = num1; + } + num1++; + } + if (num1 == 0) + { + return path2; + } + if ((num1 == path1.Length) && (num1 == path2.Length)) + { + return string.Empty; + } + var builder1 = new StringBuilder(); + while (num1 < path1.Length) + { + if (path1[num1] == '/') + { + builder1.Append("../"); + } + num1++; + } + return (builder1 + path2.Substring(num2 + 1)); + } + + /// + /// 获取服务器根域名 + /// + /// + public static string GetMainDomain(string url) + { + if (string.IsNullOrEmpty(url)) return url; + + url = RemoveProtocolFromUrl(url.ToLower()); + if (url.IndexOf('/') != -1) + { + url = url.Substring(0, url.IndexOf('/')); + } + + if (url.IndexOf('.') <= 0) return url; + + var strArr = url.Split('.'); + var lastStr = strArr.GetValue(strArr.Length - 1).ToString(); + if (StringUtils.IsNumber(lastStr)) //如果最后一位是数字,那么说明是IP地址 + { + return url; + } + var domainRules = ".com.cn|.net.cn|.org.cn|.gov.cn|.com|.net|.cn|.org|.cc|.me|.tel|.mobi|.asia|.biz|.info|.name|.tv|.hk|.公司|.中国|.网络".Split('|'); + var returnStr = string.Empty; + foreach (var t in domainRules) + { + if (url.EndsWith(t.ToLower())) //如果最后有找到匹配项 + { + var findStr = t; + var replaceStr = url.Replace(findStr, ""); + if (replaceStr.IndexOf('.') > 0) //存在二级域名或者三级,比如:www.px915 + { + var replaceArr = replaceStr.Split('.'); // www px915 + returnStr = replaceArr.GetValue(replaceArr.Length - 1) + findStr; + return returnStr; + } + returnStr = replaceStr + findStr; //连接起来输出为:px915.com + return returnStr; + } + returnStr = url; + } + return returnStr; + } + + + + + + public static NameValueCollection GetQueryString(string url) + { + if (string.IsNullOrEmpty(url) || url.IndexOf("?", StringComparison.Ordinal) == -1) return new NameValueCollection(); + + var querystring = url.Substring(url.IndexOf("?", StringComparison.Ordinal) + 1); + return TranslateUtils.ToNameValueCollection(querystring); + } + + public static NameValueCollection GetQueryStringFilterXss(string url) + { + if (string.IsNullOrEmpty(url) || url.IndexOf("?", StringComparison.Ordinal) == -1) return new NameValueCollection(); + + var attributes = new NameValueCollection(); + + var querystring = url.Substring(url.IndexOf("?", StringComparison.Ordinal) + 1); + var originals = TranslateUtils.ToNameValueCollection(querystring); + foreach (string key in originals.Keys) + { + attributes[key] = AttackUtils.FilterXss(originals[key]); + } + return attributes; + } + + public static string Combine(params string[] urls) + { + if (urls == null || urls.Length <= 0) return string.Empty; + + var retval = urls[0]?.Replace(PathUtils.SeparatorChar, SeparatorChar) ?? string.Empty; + for (var i = 1; i < urls.Length; i++) + { + var url = (urls[i] != null) ? urls[i].Replace(PathUtils.SeparatorChar, SeparatorChar) : string.Empty; + retval = Combine(retval, url); + } + return retval; + } + + private static string Combine(string url1, string url2) + { + if (url1 == null || url2 == null) + { + throw new ArgumentNullException(url1 == null ? "url1" : "url2"); + } + if (url2.Length == 0) + { + return url1; + } + if (url1.Length == 0) + { + return url2; + } + + return url1.TrimEnd(SeparatorChar) + SeparatorChar + url2.TrimStart(SeparatorChar); + } + + public static string AddQueryString(string url, string queryStringKey, string queryStringValue) + { + var queryString = new NameValueCollection + { + {queryStringKey, queryStringValue} + }; + return AddQueryString(url, queryString); + } + + public static string AddQueryString(string url, string queryString) + { + if (queryString == null || url == null) return url; + + queryString = queryString.TrimStart('?', '&'); + + if (url.IndexOf("?", StringComparison.Ordinal) == -1) + { + return string.Concat(url, "?", queryString); + } + return url.EndsWith("?") ? string.Concat(url, queryString) : string.Concat(url, "&", queryString); + } + + public static string AddQueryString(string url, NameValueCollection queryString) + { + if (queryString == null || url == null || queryString.Count == 0) + return url; + + var builder = new StringBuilder(); + foreach (string key in queryString.Keys) + { + builder.Append($"&{key}={UrlEncode(queryString[key])}"); + } + if (url.IndexOf("?", StringComparison.Ordinal) == -1) + { + if (builder.Length > 0) builder.Remove(0, 1); + return string.Concat(url, "?", builder.ToString()); + } + if (url.EndsWith("?")) + { + if (builder.Length > 0) builder.Remove(0, 1); + } + return string.Concat(url, builder.ToString()); + } + + public static string AddQueryStringIfNotExists(string url, NameValueCollection queryString) + { + if (queryString == null || url == null || queryString.Count == 0) + return url; + + var index = url.IndexOf("?", StringComparison.Ordinal); + if (index != -1) + { + var query = TranslateUtils.ToNameValueCollection(url.Substring(index).Trim('?', '&'), '&'); + + foreach (string key in query.Keys) + { + if (queryString[key] != null) + { + queryString.Remove(key); + } + } + } + + return AddQueryString(url, queryString); + } + + public static string RemoveQueryString(string url) + { + if (url == null) return null; + + if (url.IndexOf("?", StringComparison.Ordinal) == -1 || url.EndsWith("?")) + { + return url; + } + + return url.Substring(0, url.IndexOf("?", StringComparison.Ordinal)); + } + + public static string RemoveQueryString(string url, string queryString) + { + if (queryString == null || url == null) return url; + + if (url.IndexOf("?", StringComparison.Ordinal) == -1 || url.EndsWith("?")) + { + return url; + } + var attributes = GetQueryString(url); + attributes.Remove(queryString); + url = url.Substring(0, url.IndexOf("?", StringComparison.Ordinal)); + return AddQueryString(url, attributes); + } + + public static string RemoveQueryString(string url, List queryNames) + { + if (queryNames == null || queryNames.Count == 0 || url == null) return url; + + if (url.IndexOf("?", StringComparison.Ordinal) == -1 || url.EndsWith("?")) + { + return url; + } + var attributes = GetQueryString(url); + foreach (var queryName in queryNames) + { + attributes.Remove(queryName); + } + url = url.Substring(0, url.IndexOf("?", StringComparison.Ordinal)); + return AddQueryString(url, attributes); + } + + + + public static bool IsIpAddress(string ip) + { + return Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$"); + } + + + + + + + + /// + /// 将Url地址的查询字符串去掉 + /// + /// + /// + public static string GetUrlWithoutQueryString(string rawUrl) + { + string urlWithoutQueryString; + if (rawUrl != null && rawUrl.IndexOf("?", StringComparison.Ordinal) != -1) + { + var queryString = rawUrl.Substring(rawUrl.IndexOf("?", StringComparison.Ordinal)); + urlWithoutQueryString = rawUrl.Replace(queryString, ""); + } + else + { + urlWithoutQueryString = rawUrl; + } + return urlWithoutQueryString; + } + + /// + /// 将Url地址域名后的字符去掉 + /// + /// + /// + public static string GetUrlWithoutPathInfo(string rawUrl) + { + var urlWithoutPathInfo = string.Empty; + if (rawUrl != null && rawUrl.Trim().Length > 0) + { + if (rawUrl.ToLower().StartsWith("http://")) + { + urlWithoutPathInfo = rawUrl.Substring("http://".Length); + } + if (urlWithoutPathInfo.IndexOf("/", StringComparison.Ordinal) != -1) + { + urlWithoutPathInfo = urlWithoutPathInfo.Substring(0, urlWithoutPathInfo.IndexOf("/", StringComparison.Ordinal)); + } + if (string.IsNullOrEmpty(urlWithoutPathInfo)) + { + urlWithoutPathInfo = rawUrl; + } + urlWithoutPathInfo = "http://" + urlWithoutPathInfo; + } + return urlWithoutPathInfo; + } + + /// + /// 将Url地址后的文件名称去掉 + /// + /// + /// + public static string GetUrlWithoutFileName(string rawUrl) + { + if (string.IsNullOrEmpty(rawUrl)) return string.Empty; + + var urlWithoutFileName = string.Empty; + if (rawUrl.ToLower().StartsWith("http://")) + { + urlWithoutFileName = rawUrl.Substring("http://".Length); + } + if (urlWithoutFileName.IndexOf("/", StringComparison.Ordinal) != -1 && !urlWithoutFileName.EndsWith("/")) + { + const string regex = "/(?[^/]*\\.[^/]*)[^/]*$"; + const RegexOptions options = RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline | RegexOptions.IgnoreCase; + var reg = new Regex(regex, options); + var match = reg.Match(urlWithoutFileName); + if (match.Success) + { + var fileName = match.Groups["filename"].Value; + urlWithoutFileName = urlWithoutFileName.Substring(0, urlWithoutFileName.LastIndexOf(fileName, StringComparison.Ordinal)); + } + } + urlWithoutFileName = "http://" + urlWithoutFileName; + return urlWithoutFileName; + } + + public static string GetUrlQueryString(string url) + { + var queryString = string.Empty; + if (!string.IsNullOrEmpty(url) && url.IndexOf("?", StringComparison.Ordinal) != -1) + { + queryString = url.Substring(url.IndexOf("?", StringComparison.Ordinal) + 1); + } + return queryString; + } + + public static string GetFileNameFromUrl(string rawUrl) + { + if (string.IsNullOrEmpty(rawUrl)) return string.Empty; + + var fileName = string.Empty; + //if (rawUrl.ToLower().StartsWith("http://")) + //{ + // rawUrl = rawUrl.Substring("http://".Length); + //} + //if (rawUrl.IndexOf("?") != -1) + //{ + // int index = rawUrl.IndexOf("?"); + // rawUrl = rawUrl.Remove(index, rawUrl.Length - index); + //} + rawUrl = RemoveProtocolFromUrl(rawUrl); + rawUrl = GetUrlWithoutQueryString(rawUrl); + if (rawUrl.IndexOf("/", StringComparison.Ordinal) != -1 && !rawUrl.EndsWith("/")) + { + const string regex = "/(?[^/]*\\.[^/]*)[^/]*$"; + const RegexOptions options = RegexOptions.IgnorePatternWhitespace | RegexOptions.Multiline | RegexOptions.IgnoreCase; + var reg = new Regex(regex, options); + var match = reg.Match(rawUrl); + if (match.Success) + { + fileName = match.Groups["filename"].Value; + } + } + else + { + fileName = rawUrl; + } + return fileName; + } + + public static string GetExtensionFromUrl(string rawUrl) + { + var extension = string.Empty; + if (!string.IsNullOrEmpty(rawUrl)) + { + rawUrl = RemoveProtocolFromUrl(rawUrl); + rawUrl = GetUrlWithoutQueryString(rawUrl); + rawUrl = rawUrl.TrimEnd('/'); + if (rawUrl.IndexOf('/') != -1) + { + rawUrl = rawUrl.Substring(rawUrl.LastIndexOf('/')); + if (rawUrl.IndexOf('.') != -1) + { + extension = rawUrl.Substring(rawUrl.LastIndexOf('.')); + } + } + } + return extension; + } + + public static string UrlEncode(string urlString) + { + return WebUtility.UrlEncode(urlString); + } + + public static string UrlDecode(string urlString) + { + return WebUtility.UrlDecode(urlString); + } + + + + + + + + + + + + + + + + + + public static bool IsVirtualUrl(string url) + { + if (!string.IsNullOrEmpty(url)) + { + if (url.StartsWith("~") || url.StartsWith("@")) + { + return true; + } + } + return false; + } + + public static string GetRedirectStringWithCheckBoxValue(string redirectUrl, string checkBoxServerId, string checkBoxClientId, string emptyAlertText) + { + return + $@"if (!_alertCheckBoxCollection(document.getElementsByName('{checkBoxClientId}'), '{emptyAlertText}')){{_goto('{redirectUrl}' + '&{checkBoxServerId}=' + _getCheckBoxCollectionValue(document.getElementsByName('{checkBoxClientId}')));}};return false;"; + } + + public static string GetRedirectStringWithCheckBoxValueAndAlert(string redirectUrl, string checkBoxServerId, string checkBoxClientId, string emptyAlertText, string confirmAlertText) + { + return + $@"_confirmCheckBoxCollection(document.getElementsByName('{checkBoxClientId}'), '{emptyAlertText}', '{confirmAlertText}', '{redirectUrl}' + '&{checkBoxServerId}=' + _getCheckBoxCollectionValue(document.getElementsByName('{checkBoxClientId}')));return false;"; + } + + public static string GetRedirectStringWithConfirm(string redirectUrl, string confirmString) + { + return $@"_confirm('{confirmString}', '{redirectUrl}');return false;"; + } + } +} diff --git a/src/SiteServer.Utils/PathUtils.cs b/src/SiteServer.Utils/PathUtils.cs new file mode 100644 index 000000000..5518148f5 --- /dev/null +++ b/src/SiteServer.Utils/PathUtils.cs @@ -0,0 +1,194 @@ +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; + +namespace SiteServer.Utils +{ + public static class PathUtils + { + public const char SeparatorChar = '\\'; + public static readonly char[] InvalidPathChars = Path.GetInvalidPathChars(); + + public static string Combine(params string[] paths) + { + var retVal = string.Empty; + if (paths != null && paths.Length > 0) + { + retVal = paths[0]?.Replace(PageUtils.SeparatorChar, SeparatorChar).TrimEnd(SeparatorChar) ?? string.Empty; + for (var i = 1; i < paths.Length; i++) + { + var path = paths[i] != null ? paths[i].Replace(PageUtils.SeparatorChar, SeparatorChar).Trim(SeparatorChar) : string.Empty; + retVal = Path.Combine(retVal, path); + } + } + return retVal; + } + + /// + /// 根据路径扩展名判断是否为文件夹路径 + /// + /// + /// + public static bool IsDirectoryPath(string path) + { + var retVal = false; + if (!string.IsNullOrEmpty(path)) + { + var ext = Path.GetExtension(path); + if (string.IsNullOrEmpty(ext)) //path为文件路径 + { + retVal = true; + } + } + return retVal; + } + + public static bool IsFilePath(string val) + { + try + { + return FileUtils.IsFileExists(val); + } + catch + { + return false; + } + } + + public static string GetExtension(string path) + { + var retVal = string.Empty; + if (!string.IsNullOrEmpty(path)) + { + path = PageUtils.RemoveQueryString(path); + path = path.Trim('/', '\\').Trim(); + try + { + retVal = Path.GetExtension(path); + } + catch + { + // ignored + } + } + return retVal; + } + + public static string RemoveExtension(string fileName) + { + var retVal = string.Empty; + if (!string.IsNullOrEmpty(fileName)) + { + var index = fileName.LastIndexOf('.'); + retVal = index != -1 ? fileName.Substring(0, index) : fileName; + } + return retVal; + } + + public static string RemoveParentPath(string path) + { + var retVal = string.Empty; + if (!string.IsNullOrEmpty(path)) + { + retVal = path.Replace("../", string.Empty); + retVal = retVal.Replace("./", string.Empty); + } + return retVal; + } + + public static string GetFileName(string filePath) + { + return Path.GetFileName(filePath); + } + + public static string GetFileNameWithoutExtension(string filePath) + { + return Path.GetFileNameWithoutExtension(filePath); + } + + public static string GetDirectoryName(string path, bool isFile) + { + if (string.IsNullOrWhiteSpace(path)) return string.Empty; + + if (isFile) + { + path = Path.GetDirectoryName(path); + } + if (!string.IsNullOrEmpty(path)) + { + var directoryInfo = new DirectoryInfo(path); + return directoryInfo.Name; + } + return string.Empty; + } + + public static string GetPathDifference(string rootPath, string path) + { + if (!string.IsNullOrEmpty(path) && StringUtils.StartsWithIgnoreCase(path, rootPath)) + { + var retVal = path.Substring(rootPath.Length, path.Length - rootPath.Length); + return retVal.Trim('/', '\\'); + } + return string.Empty; + } + + + + + + public static string GetBinDirectoryPath(string relatedPath) + { + relatedPath = RemoveParentPath(relatedPath); + return Combine(WebConfigUtils.PhysicalApplicationPath, DirectoryUtils.Bin.DirectoryName, relatedPath); + } + + public static string GetAdminDirectoryPath(string relatedPath) + { + relatedPath = RemoveParentPath(relatedPath); + return Combine(WebConfigUtils.PhysicalApplicationPath, WebConfigUtils.AdminDirectory, relatedPath); + } + + public static string GetHomeDirectoryPath(string relatedPath) + { + relatedPath = RemoveParentPath(relatedPath); + return Combine(WebConfigUtils.PhysicalApplicationPath, WebConfigUtils.HomeDirectory, relatedPath); + } + + + + + + public static string RemovePathInvalidChar(string filePath) + { + if (string.IsNullOrEmpty(filePath)) + return filePath; + var invalidChars = new string(Path.GetInvalidPathChars()); + string invalidReStr = $"[{Regex.Escape(invalidChars)}]"; + return Regex.Replace(filePath, invalidReStr, ""); + } + + + + public static bool IsFileExtenstionAllowed(string sAllowedExt, string sExt) + { + if (sExt != null && sExt.StartsWith(".")) + { + sExt = sExt.Substring(1, sExt.Length - 1); + } + sAllowedExt = sAllowedExt.Replace("|", ","); + var aExt = sAllowedExt.Split(','); + return aExt.Any(t => StringUtils.EqualsIgnoreCase(sExt, t)); + } + + public static string GetTemporaryFilesPath(string relatedPath) + { + return Combine(WebConfigUtils.PhysicalApplicationPath, DirectoryUtils.SiteFiles.DirectoryName, DirectoryUtils.SiteFiles.TemporaryFiles, relatedPath); + } + + + + public static string PhysicalSiteServerPath => Combine(WebConfigUtils.PhysicalApplicationPath, WebConfigUtils.AdminDirectory); + + public static string PhysicalSiteFilesPath => Combine(WebConfigUtils.PhysicalApplicationPath, DirectoryUtils.SiteFiles.DirectoryName); + } +} diff --git a/src/SiteServer.Utils/RegexUtils.cs b/src/SiteServer.Utils/RegexUtils.cs new file mode 100644 index 000000000..bdfcdcb70 --- /dev/null +++ b/src/SiteServer.Utils/RegexUtils.cs @@ -0,0 +1,91 @@ +using System; +using System.Collections.Generic; +using System.Text.RegularExpressions; + +namespace SiteServer.Utils +{ + public static class RegexUtils + { + + /* + * 通用:.*? + * 所有链接:[^"]*)"|'(?[^']*)'|(?\S+)).*?> + * */ + + private static RegexOptions Options = ((RegexOptions.Singleline | RegexOptions.IgnoreCase) | RegexOptions.IgnorePatternWhitespace); + + public static List GetOriginalImageSrcs(string html) + { + const string regex = "(img|input)[^><]*\\s+src\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*))"; + return GetContents("url", regex, html); + } + + public static List GetOriginalLinkHrefs(string html) + { + const string regex = "a[^><]*\\s+href\\s*=\\s*(?:\"(?[^\"]*)\"|'(?[^']*)'|(?[^>\\s]*))"; + return GetContents("url", regex, html); + } + + public static List GetTagInnerContents(string tagName, string html) + { + string regex = $"<{tagName}\\s+[^><]*>\\s*(?[\\s\\S]+?)\\s*"; + return GetContents("content", regex, html); + } + + public static string GetInnerContent(string tagName, string html) + { + string regex = $"<{tagName}[^><]*>(?[\\s\\S]+?)"; + return GetContent("content", regex, html); + } + + public static string GetContent(string groupName, string regex, string html) + { + var content = string.Empty; + if (string.IsNullOrEmpty(regex)) return content; + if (regex.IndexOf("<" + groupName + ">", StringComparison.Ordinal) == -1) + { + return regex; + } + + var reg = new Regex(regex, Options); + var match = reg.Match(html); + if (match.Success) + { + content = match.Groups[groupName].Value; + } + + return content; + } + + public static string Replace(string regex, string input, string replacement) + { + if (string.IsNullOrEmpty(input)) return input; + var reg = new Regex(regex, Options); + return reg.Replace(input, replacement); + } + + public static bool IsMatch(string regex, string input) + { + var reg = new Regex(regex, Options); + return reg.IsMatch(input); + } + + public static List GetContents(string groupName, string regex, string html) + { + if (string.IsNullOrEmpty(regex)) return new List(); + + var list = new List(); + var reg = new Regex(regex, Options); + + for (var match = reg.Match(html); match.Success; match = match.NextMatch()) + { + var theValue = match.Groups[groupName].Value; + if (!list.Contains(theValue)) + { + list.Add(theValue); + } + } + return list; + } + } +} diff --git a/SiteServer.Utils/Serializer.cs b/src/SiteServer.Utils/Serializer.cs similarity index 100% rename from SiteServer.Utils/Serializer.cs rename to src/SiteServer.Utils/Serializer.cs diff --git a/src/SiteServer.Utils/SiteServer.Utils.csproj b/src/SiteServer.Utils/SiteServer.Utils.csproj new file mode 100644 index 000000000..27e2654d1 --- /dev/null +++ b/src/SiteServer.Utils/SiteServer.Utils.csproj @@ -0,0 +1,15 @@ + + + + net452;netstandard2.0 + + + + + + + + + + + diff --git a/src/SiteServer.Utils/StringUtils.cs b/src/SiteServer.Utils/StringUtils.cs new file mode 100644 index 000000000..2b16a3278 --- /dev/null +++ b/src/SiteServer.Utils/StringUtils.cs @@ -0,0 +1,700 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net; +using System.Text; +using System.Text.RegularExpressions; + +namespace SiteServer.Utils +{ + public static class StringUtils + { + public static bool IsMobile(string val) + { + return Regex.IsMatch(val, @"^1[3456789]\d{9}$", RegexOptions.IgnoreCase); + } + + public static bool IsEmail(string val) + { + return Regex.IsMatch(val, @"^\w+([-_+.]\w+)*@\w+([-_.]\w+)*\.\w+([-_.]\w+)*$", RegexOptions.IgnoreCase); + } + + public static bool IsNumber(string val) + { + const string formatNumber = "^[0-9]+$"; + return Regex.IsMatch(val, formatNumber); + } + + public static bool IsDateTime(string val) + { + const string formatDate = @"^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$"; + const string formatDateTime = @"^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-)) (20|21|22|23|[0-1]?\d):[0-5]?\d:[0-5]?\d$"; + + return Regex.IsMatch(val, formatDate) || Regex.IsMatch(val, formatDateTime); + } + + public static bool IsGuid(string val) + { + return !string.IsNullOrWhiteSpace(val) && Guid.TryParse(val, out _); + } + + public static bool In(string strCollection, int inInt) + { + return In(strCollection, inInt.ToString()); + } + + public static bool In(string strCollection, string inStr) + { + if (string.IsNullOrEmpty(strCollection)) return false; + return strCollection == inStr || strCollection.StartsWith(inStr + ",") || strCollection.EndsWith("," + inStr) || strCollection.IndexOf("," + inStr + ",", StringComparison.Ordinal) != -1; + } + + public static bool Contains(string text, string inner) + { + return text?.IndexOf(inner, StringComparison.Ordinal) >= 0; + } + + public static bool ContainsIgnoreCase(string text, string inner) + { + if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(inner)) return false; + return text.ToLower().IndexOf(inner.ToLower(), StringComparison.Ordinal) >= 0; + } + + public static bool ContainsIgnoreCase(List list, string target) + { + if (list == null || list.Count == 0) return false; + + return list.Any(element => EqualsIgnoreCase(element, target)); + } + + public static string Trim(string text) + { + return string.IsNullOrEmpty(text) ? string.Empty : text.Trim(); + } + + public static string TrimAndToLower(string text) + { + return string.IsNullOrEmpty(text) ? string.Empty : text.ToLower().Trim(); + } + + public static string TrimAndToUpper(string text) + { + return string.IsNullOrEmpty(text) ? string.Empty : text.ToUpper().Trim(); + } + + public static string Remove(string text, int startIndex) + { + if (string.IsNullOrEmpty(text)) return string.Empty; + if (startIndex < 0) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + if (startIndex >= text.Length) + { + throw new ArgumentOutOfRangeException(nameof(startIndex)); + } + return text.Substring(0, startIndex); + } + + public static string GetGuid() + { + return Guid.NewGuid().ToString(); + } + + public static string GetShortGuid() + { + long i = 1; + foreach (var b in Guid.NewGuid().ToByteArray()) + { + i *= b + 1; + } + return $"{i - DateTime.Now.Ticks:x}"; + } + + public static string GetShortGuid(bool isUppercase) + { + long i = 1; + foreach (var b in Guid.NewGuid().ToByteArray()) + { + i *= b + 1; + } + string retVal = $"{i - DateTime.Now.Ticks:x}"; + return isUppercase ? retVal.ToUpper() : retVal.ToLower(); + } + + public static bool EqualsIgnoreCase(string a, string b) + { + if (a == b) return true; + if (string.IsNullOrEmpty(a) || string.IsNullOrEmpty(b)) return false; + + return a.Equals(b, StringComparison.OrdinalIgnoreCase); + } + + public static bool EqualsIgnoreNull(string a, string b) + { + return string.IsNullOrEmpty(a) ? string.IsNullOrEmpty(b) : string.Equals(a, b); + } + + public static bool StartsWithIgnoreCase(string text, string startString) + { + if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(startString)) return false; + return text.Trim().ToLower().StartsWith(startString.Trim().ToLower()) || string.Equals(text.Trim(), startString.Trim(), StringComparison.OrdinalIgnoreCase); + } + + public static bool EndsWithIgnoreCase(string text, string endString) + { + if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(endString)) return false; + return text.Trim().ToLower().EndsWith(endString.Trim().ToLower()); + } + + public static bool StartsWith(string text, string startString) + { + if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(startString)) return false; + return text.StartsWith(startString); + } + + public static bool EndsWith(string text, string endString) + { + if (string.IsNullOrEmpty(text) || string.IsNullOrEmpty(endString)) return false; + return text.EndsWith(endString); + } + + public static void InsertBefore(string[] insertBeforeArray, StringBuilder contentBuilder, string insertContent) + { + if (contentBuilder == null) return; + foreach (var insertBefore in insertBeforeArray) + { + if (contentBuilder.ToString().IndexOf(insertBefore, StringComparison.Ordinal) != -1) + { + InsertBefore(insertBefore, contentBuilder, insertContent); + return; + } + } + } + + private static void InsertBefore(string insertBefore, StringBuilder contentBuilder, string insertContent) + { + if (string.IsNullOrEmpty(insertBefore) || contentBuilder == null) return; + var startIndex = contentBuilder.ToString().IndexOf(insertBefore, StringComparison.Ordinal); + if (startIndex != -1) + { + contentBuilder.Insert(startIndex, insertContent); + } + } + + public static void InsertAfter(string[] insertAfterArray, StringBuilder contentBuilder, string insertContent) + { + if (contentBuilder != null) + { + foreach (var insertAfter in insertAfterArray) + { + if (contentBuilder.ToString().IndexOf(insertAfter, StringComparison.Ordinal) != -1) + { + InsertAfter(insertAfter, contentBuilder, insertContent); + return; + } + } + } + } + + private static void InsertAfter(string insertAfter, StringBuilder contentBuilder, string insertContent) + { + if (string.IsNullOrEmpty(insertAfter) || contentBuilder == null) return; + var startIndex = contentBuilder.ToString().IndexOf(insertAfter, StringComparison.Ordinal); + if (startIndex == -1) return; + if (startIndex != -1) + { + contentBuilder.Insert(startIndex + insertAfter.Length, insertContent); + } + } + + public static string HtmlDecode(string inputString) + { + if (string.IsNullOrWhiteSpace(inputString)) return string.Empty; + + return WebUtility.HtmlDecode(inputString); + } + + public static string HtmlEncode(string inputString) + { + if (string.IsNullOrWhiteSpace(inputString)) return string.Empty; + + return WebUtility.HtmlEncode(inputString); + } + + public static string ToXmlContent(string inputString) + { + var contentBuilder = new StringBuilder(inputString); + contentBuilder.Replace("", string.Empty); + contentBuilder.Insert(0, ""); + return contentBuilder.ToString(); + } + + public static string StripTags(string inputString) + { + var retVal = RegexUtils.Replace("]*>.*?<\\/script>", inputString, string.Empty); + retVal = RegexUtils.Replace("<[\\/]?[^>]*>|<[\\S]+", retVal, string.Empty); + return retVal; + } + + public static string StripTags(string inputString, params string[] tagNames) + { + var retVal = inputString; + foreach (var tagName in tagNames) + { + retVal = RegexUtils.Replace($"<[\\/]?{tagName}[^>]*>|<{tagName}", retVal, string.Empty); + } + return retVal; + } + + public static string StripEntities(string inputString) + { + var retVal = RegexUtils.Replace("&[^;]*;", inputString, string.Empty); + return retVal; + } + + public static string ReplaceIgnoreCase(string original, string pattern, string replacement) + { + if (original == null) return string.Empty; + if (replacement == null) replacement = string.Empty; + var count = 0; + var position0 = 0; + int position1; + var upperString = original.ToUpper(); + var upperPattern = pattern.ToUpper(); + var inc = (original.Length / pattern.Length) * (replacement.Length - pattern.Length); + var chars = new char[original.Length + Math.Max(0, inc)]; + while ((position1 = upperString.IndexOf(upperPattern, position0, StringComparison.Ordinal)) != -1) + { + for (var i = position0; i < position1; ++i) chars[count++] = original[i]; + foreach (var t in replacement) + { + chars[count++] = t; + } + position0 = position1 + pattern.Length; + } + if (position0 == 0) return original; + for (var i = position0; i < original.Length; ++i) chars[count++] = original[i]; + return new string(chars, 0, count); + } + + public static string Replace(string replace, string input, string to) + { + var retVal = RegexUtils.Replace(replace, input, to); + if (string.IsNullOrEmpty(replace)) return retVal; + if (replace.StartsWith("/") && replace.EndsWith("/")) + { + retVal = RegexUtils.Replace(replace.Trim('/'), input, to); + } + else + { + retVal = input.Replace(replace, to); + } + return retVal; + } + + public static void ReplaceHrefOrSrc(StringBuilder builder, string replace, string to) + { + builder.Replace("href=\"" + replace, "href=\"" + to); + builder.Replace("href='" + replace, "href='" + to); + builder.Replace("href=" + replace, "href=" + to); + builder.Replace("href="" + replace, "href="" + to); + builder.Replace("src=\"" + replace, "src=\"" + to); + builder.Replace("src='" + replace, "src='" + to); + builder.Replace("src=" + replace, "src=" + to); + builder.Replace("src="" + replace, "src="" + to); + } + + public static string ReplaceFirst(string replace, string input, string to) + { + var pos = input.IndexOf(replace, StringComparison.Ordinal); + if (pos > 0) + { + //取位置前部分+替换字符串+位置(加上查找字符长度)后部分 + return input.Substring(0, pos) + to + input.Substring(pos + replace.Length); + } + if (pos == 0) + { + return to + input.Substring(replace.Length); + } + return input; + } + + public static string ReplaceStartsWith(string input, string replace, string to) + { + var retVal = input; + if (!string.IsNullOrEmpty(input) && !string.IsNullOrEmpty(replace) && input.StartsWith(replace)) + { + retVal = to + input.Substring(replace.Length); + } + return retVal; + } + + public static string ReplaceStartsWithIgnoreCase(string input, string replace, string to) + { + var retVal = input; + if (!string.IsNullOrEmpty(input) && !string.IsNullOrEmpty(replace) && input.ToLower().StartsWith(replace.ToLower())) + { + retVal = to + input.Substring(replace.Length); + } + return retVal; + } + + public static string ReplaceEndsWith(string input, string replace, string to) + { + var retVal = input; + if (!string.IsNullOrEmpty(input) && !string.IsNullOrEmpty(replace) && input.EndsWith(replace)) + { + retVal = input.Substring(0, input.Length - replace.Length) + to; + } + return retVal; + } + + public static string ReplaceEndsWithIgnoreCase(string input, string replace, string to) + { + var retVal = input; + if (!string.IsNullOrEmpty(input) && !string.IsNullOrEmpty(replace) && input.ToLower().EndsWith(replace.ToLower())) + { + retVal = input.Substring(0, input.Length - replace.Length) + to; + } + return retVal; + } + + public static string ReplaceNewlineToBr(string inputString) + { + if (string.IsNullOrEmpty(inputString)) return string.Empty; + var retVal = new StringBuilder(); + inputString = inputString.Trim(); + foreach (var t in inputString) + { + switch (t) + { + case '\n': + retVal.Append("
          "); + break; + case '\r': + break; + default: + retVal.Append(t); + break; + } + } + return retVal.ToString(); + } + + public static string ReplaceNewline(string inputString, string replacement) + { + if (string.IsNullOrEmpty(inputString)) return string.Empty; + var retVal = new StringBuilder(); + inputString = inputString.Trim(); + foreach (var t in inputString) + { + switch (t) + { + case '\n': + retVal.Append(replacement); + break; + case '\r': + break; + default: + retVal.Append(t); + break; + } + } + return retVal.ToString(); + } + + public static string MaxLengthText(string inputString, int maxLength, string endString = Constants.Ellipsis) + { + var retVal = inputString; + try + { + if (maxLength > 0) + { + var decodedInputString = HtmlDecode(retVal); + retVal = decodedInputString; + + var totalLength = maxLength * 2; + var length = 0; + var builder = new StringBuilder(); + + var isOneBytesChar = false; + var lastChar = ' '; + + if (!string.IsNullOrEmpty(retVal)) + { + foreach (var singleChar in retVal.ToCharArray()) + { + builder.Append(singleChar); + + if (IsTwoBytesChar(singleChar)) + { + length += 2; + if (length >= totalLength) + { + lastChar = singleChar; + break; + } + } + else + { + length += 1; + if (length == totalLength) + { + isOneBytesChar = true;//已经截取到需要的字数,再多截取一位 + } + else if (length > totalLength) + { + lastChar = singleChar; + break; + } + else + { + isOneBytesChar = !isOneBytesChar; + } + } + } + } + if (isOneBytesChar && length > totalLength) + { + builder.Length--; + var theStr = builder.ToString(); + retVal = builder.ToString(); + if (char.IsLetter(lastChar)) + { + for (var i = theStr.Length - 1; i > 0; i--) + { + var theChar = theStr[i]; + if (!IsTwoBytesChar(theChar) && char.IsLetter(theChar)) + { + retVal = retVal.Substring(0, i - 1); + } + else + { + break; + } + } + //int index = retVal.LastIndexOfAny(new char[] { ' ', '\t', '\n', '\v', '\f', '\r', '\x0085' }); + //if (index != -1) + //{ + // retVal = retVal.Substring(0, index); + //} + } + } + else + { + retVal = builder.ToString(); + } + + var isCut = decodedInputString != retVal; + retVal = HtmlEncode(retVal); + + if (isCut && endString != null) + { + retVal += endString; + } + } + } + catch + { + // ignored + } + + return retVal; + } + + private static Encoding Gb2312 { get; } = Encoding.GetEncoding("gb2312"); + + private static bool IsTwoBytesChar(char chr) + { + // 使用中文支持编码 + return Gb2312.GetByteCount(new[] { chr }) == 2; + } + + /// + /// 得到innerText在content中的数目 + /// + /// + /// + /// + public static int GetCount(string innerText, string content) + { + if (innerText == null || content == null) + { + return 0; + } + var count = 0; + for (var index = content.IndexOf(innerText, StringComparison.Ordinal); index != -1; index = content.IndexOf(innerText, index + innerText.Length, StringComparison.Ordinal)) + { + count++; + } + return count; + } + + public static int GetStartCount(char startChar, string content) + { + if (content == null) + { + return 0; + } + var count = 0; + + foreach (var theChar in content) + { + if (theChar == startChar) + { + count++; + } + else + { + break; + } + } + return count; + } + + public static int GetStartCount(string startString, string content) + { + if (content == null) + { + return 0; + } + var count = 0; + + while (true) + { + if (content.StartsWith(startString)) + { + count++; + content = content.Remove(0, startString.Length); + } + else + { + break; + } + } + + return count; + } + + public static string GetFirstOfStringCollection(string collection, char separator) + { + if (!string.IsNullOrEmpty(collection)) + { + var index = collection.IndexOf(separator); + return index == -1 ? collection : collection.Substring(0, index); + } + return string.Empty; + } + + + private static int _randomSeq; + public static int GetRandomInt(int minValue, int maxValue) + { + var ro = new Random(unchecked((int)DateTime.Now.Ticks)); + var retVal = ro.Next(minValue, maxValue); + retVal += _randomSeq++; + if (retVal >= maxValue) + { + _randomSeq = 0; + retVal = minValue; + } + return retVal; + } + + public static string ValueToUrl(string value) + { + var retVal = string.Empty; + if (!string.IsNullOrEmpty(value)) + { + //替换url中的换行符,update by sessionliang at 20151211 + retVal = value.Replace("=", "_equals_").Replace("&", "_and_").Replace("?", "_question_").Replace("'", "_quote_").Replace("+", "_add_").Replace("\r", "").Replace("\n", ""); + } + return retVal; + } + + public static string ValueFromUrl(string value) + { + var retVal = string.Empty; + if (!string.IsNullOrEmpty(value)) + { + retVal = value.Replace("_equals_", "=").Replace("_and_", "&").Replace("_question_", "?").Replace("_quote_", "'").Replace("_add_", "+"); + } + return retVal; + } + + public static string ToJsString(string value) + { + var retVal = string.Empty; + if (!string.IsNullOrEmpty(value)) + { + retVal = value.Replace("'", @"\'").Replace("\r", "\\r").Replace("\n", "\\n"); + } + return retVal; + } + + public static string ParseReplace(string parsedContent, string replace, string to) + { + if (replace.IndexOf(',') != -1) + { + var replaceList = TranslateUtils.StringCollectionToStringList(replace); + var toList = TranslateUtils.StringCollectionToStringList(to); + + if (replaceList.Count == toList.Count) + { + for (var i = 0; i < replaceList.Count; i++) + { + parsedContent = parsedContent.Replace(replaceList[i], toList[i]); + } + + return parsedContent; + } + + if (toList.Count == 1) + { + foreach (var replaceStr in replaceList) + { + parsedContent = parsedContent.Replace(replaceStr, to); + } + + return parsedContent; + } + } + + string retVal; + if (replace.StartsWith("/") && replace.EndsWith("/")) + { + retVal = RegexUtils.Replace(replace.Trim('/'), parsedContent, to); + } + else + { + retVal = parsedContent.Replace(replace, to); + } + + return retVal; + } + + public static string GetTrueImageHtml(string isDefaultStr) + { + return GetTrueImageHtml(TranslateUtils.ToBool(isDefaultStr)); + } + + private static string GetTrueImageHtml(bool isDefault) + { + var retVal = string.Empty; + if (isDefault) + { + retVal = ""; + } + return retVal; + } + + public static string LowerFirst(string input) + { + if (string.IsNullOrEmpty(input)) return string.Empty; + return input.First().ToString().ToLower() + input.Substring(1); + } + } +} diff --git a/SiteServer.Utils/Tab.cs b/src/SiteServer.Utils/Tab.cs similarity index 100% rename from SiteServer.Utils/Tab.cs rename to src/SiteServer.Utils/Tab.cs diff --git a/src/SiteServer.Utils/TabCollection.cs b/src/SiteServer.Utils/TabCollection.cs new file mode 100644 index 000000000..382a8669e --- /dev/null +++ b/src/SiteServer.Utils/TabCollection.cs @@ -0,0 +1,33 @@ +using System; +using System.Xml.Serialization; + +namespace SiteServer.Utils +{ + /// + /// TabCollection is a container for all of the tabs. + /// + [Serializable] + public class TabCollection + { + private Tab[] _tabs; + /// + /// Property Tabs (Tab[]) + /// + [XmlArray("Tabs")] + public Tab[] Tabs + { + get { return _tabs; } + set { _tabs = value; } + } + + public TabCollection() + { + + } + + public TabCollection(Tab[] tabs) + { + _tabs = tabs; + } + } +} diff --git a/src/SiteServer.Utils/TestEnv.cs b/src/SiteServer.Utils/TestEnv.cs new file mode 100644 index 000000000..64cf377c6 --- /dev/null +++ b/src/SiteServer.Utils/TestEnv.cs @@ -0,0 +1,11 @@ +using System; + +namespace SiteServer.Utils +{ + public static class TestEnv + { + private const string TestMachine = "DESKTOP-7S7SBTS"; + + public static bool IntegrationTestMachine => Environment.MachineName == TestMachine; + } +} diff --git a/src/SiteServer.Utils/TranslateUtils.cs b/src/SiteServer.Utils/TranslateUtils.cs new file mode 100644 index 000000000..8cff48ba5 --- /dev/null +++ b/src/SiteServer.Utils/TranslateUtils.cs @@ -0,0 +1,840 @@ +using System; +using System.Collections; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using Datory; +using Newtonsoft.Json; +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; +using SiteServer.Utils.Auth; + +namespace SiteServer.Utils +{ + public static class TranslateUtils + { + public static T Get(IDictionary dict, string name, T defaultValue = default(T)) + { + return To(Get(dict, name), defaultValue); + } + + public static object Get(IDictionary dict, string name) + { + if (string.IsNullOrEmpty(name)) return null; + + return dict.TryGetValue(name, out var extendValue) ? extendValue : null; + } + + public static T To(object value, T defaultValue = default(T)) + { + switch (value) + { + case null: + return defaultValue; + case T variable: + return variable; + default: + try + { + return (T)Convert.ChangeType(value, typeof(T)); + } + catch (InvalidCastException) + { + return defaultValue; + } + } + } + + public static IDictionary ToDictionary(IDataReader reader) + { + var dict = new Dictionary(StringComparer.OrdinalIgnoreCase); + if (reader == null) return dict; + + for (var i = 0; i < reader.FieldCount; i++) + { + var name = reader.GetName(i); + var value = reader.GetValue(i); + + if (value is string s && WebConfigUtils.DatabaseType == DatabaseType.Oracle && s == Constants.OracleEmptyValue) + { + value = string.Empty; + } + + if (!string.IsNullOrEmpty(name)) + { + dict[name] = value; + } + } + + return dict; + } + + public static IDictionary ToDictionary(DataRowView rowView) + { + if (rowView == null) return new Dictionary(StringComparer.OrdinalIgnoreCase); + + return ToDictionary(rowView.Row); + } + + public static IDictionary ToDictionary(DataRow row) + { + var dict = new Dictionary(StringComparer.OrdinalIgnoreCase); + if (row == null) return dict; + + return row.Table.Columns + .Cast() + .ToDictionary(c => c.ColumnName, c => row[c]); + } + + public static IDictionary ToDictionary(IDataRecord record) + { + var dict = new Dictionary(StringComparer.OrdinalIgnoreCase); + if (record == null) return dict; + + for (var i = 0; i < record.FieldCount; i++) + { + var name = record.GetName(i); + var value = record.GetValue(i); + + if (value is string s && WebConfigUtils.DatabaseType == DatabaseType.Oracle && s == Constants.OracleEmptyValue) + { + value = string.Empty; + } + + if (!string.IsNullOrEmpty(name)) + { + dict[name] = value; + } + } + + return dict; + } + + public static IDictionary ToDictionary(NameValueCollection collection) + { + var dict = new Dictionary(StringComparer.OrdinalIgnoreCase); + if (collection == null) return dict; + + foreach (var key in collection.AllKeys) + { + dict[key] = collection[key]; + } + + return dict; + } + + public static IDictionary ToDictionary(T o) + { + IDictionary res = new Dictionary(); + var props = typeof(T).GetProperties(); + foreach (var prop in props) + { + if (prop.CanRead) + { + res.Add(prop.Name, prop.GetValue(o, null)); + } + } + return res; + } + + public static Dictionary ToDictionary(string json) + { + var dict = new Dictionary(); + + if (string.IsNullOrEmpty(json)) return dict; + + if (json.StartsWith("{") && json.EndsWith("}")) + { + dict = JsonDeserialize>(json); + return dict; + } + + json = json.Replace("/u0026", "&"); + + var pairs = json.Split('&'); + foreach (var pair in pairs) + { + if (pair.IndexOf("=", StringComparison.Ordinal) == -1) continue; + var name = pair.Split('=')[0]; + if (string.IsNullOrEmpty(name)) continue; + + name = name.Replace("_equals_", "=").Replace("_and_", "&").Replace("_question_", "?").Replace("_quote_", "'").Replace("_add_", "+").Replace("_return_", "\r").Replace("_newline_", "\n"); + var value = pair.Split('=')[1]; + if (!string.IsNullOrEmpty(value)) + { + value = value.Replace("_equals_", "=").Replace("_and_", "&").Replace("_question_", "?").Replace("_quote_", "'").Replace("_add_", "+").Replace("_return_", "\r").Replace("_newline_", "\n"); + } + + dict[name] = value; + } + + return dict; + } + + //添加枚举:(fileAttributes | FileAttributes.ReadOnly) 判断枚举:((fileAttributes & FileAttributes.ReadOnly) == FileAttributes.ReadOnly) 去除枚举:(fileAttributes ^ FileAttributes.ReadOnly) + + /// + /// 将字符串类型转换为对应的枚举类型 + /// + public static object ToEnum(Type enumType, string value, object defaultType) + { + object retVal; + try + { + retVal = Enum.Parse(enumType, value, true); + } + catch + { + retVal = defaultType; + } + return retVal; + } + + public static List ToIntList(int intValue) + { + return new List {intValue}; + } + + public static int ToInt(string intStr, int defaultValue = 0) + { + if (!int.TryParse(intStr?.Trim().TrimStart('0'), out var i)) + { + i = defaultValue; + } + if (i < 0) + { + i = defaultValue; + } + return i; + } + + public static int ToIntWithNegative(string intStr, int defaultValue = 0) + { + if (!int.TryParse(intStr?.Trim(), out var i)) + { + i = defaultValue; + } + return i; + } + + public static decimal ToDecimal(string intStr, decimal defaultValue = 0) + { + if (!decimal.TryParse(intStr?.Trim(), out var i)) + { + i = defaultValue; + } + if (i < 0) + { + i = defaultValue; + } + return i; + } + + public static decimal ToDecimalWithNegative(string intStr, decimal defaultValue = 0) + { + if (!decimal.TryParse(intStr?.Trim(), out var i)) + { + i = defaultValue; + } + return i; + } + + public static long ToLong(string intStr, long defaultValue = 0) + { + if (!long.TryParse(intStr?.Trim(), out var l)) + { + l = defaultValue; + } + if (l < 0) + { + l = defaultValue; + } + return l; + } + + public static bool ToBool(string boolStr) + { + if (!bool.TryParse(boolStr?.Trim(), out var boolean)) + { + boolean = false; + } + return boolean; + } + + public static bool ToBool(string boolStr, bool defaultValue) + { + if (!bool.TryParse(boolStr?.Trim(), out var boolean)) + { + boolean = defaultValue; + } + return boolean; + } + + public static DateTime? ToNullableDateTime(string dateTimeStr) + { + if (DateTime.TryParse(dateTimeStr.Trim(), out var datetime)) + { + return datetime; + } + return null; + } + + public static DateTime ToDateTime(string dateTimeStr) + { + var datetime = DateUtils.SqlMinValue; + if (!string.IsNullOrEmpty(dateTimeStr)) + { + if (!DateTime.TryParse(dateTimeStr.Trim(), out datetime)) + { + datetime = DateUtils.SqlMinValue; + } + } + if (datetime < DateUtils.SqlMinValue) + { + datetime = DateUtils.SqlMinValue; + } + return datetime; + } + + public static DateTime ToDateTime(string dateTimeStr, DateTime defaultValue) + { + var datetime = defaultValue; + if (!string.IsNullOrEmpty(dateTimeStr)) + { + if (!DateTime.TryParse(dateTimeStr.Trim(), out datetime)) + { + datetime = defaultValue; + } + return datetime; + } + return datetime; + } + + public static Color ToColor(string colorStr) + { + var color = Color.Empty; + try + { + color = Color.FromName(colorStr.Trim()); + } + catch + { + // ignored + } + return color; + } + + + + public static string ToTwoCharString(int i) + { + return i >= 0 && i <= 9 ? $"0{i}" : i.ToString(); + } + + public static List StringCollectionToIntList(string collection) + { + var list = new List(); + if (!string.IsNullOrEmpty(collection)) + { + var array = collection.Split(','); + foreach (var s in array) + { + int.TryParse(s.Trim(), out var i); + list.Add(i); + } + } + return list; + } + + public static List StringCollectionToStringList(string collection, char split = ',') + { + var list = new List(); + if (string.IsNullOrEmpty(collection)) return list; + + var array = collection.Split(split); + list.AddRange(array); + return list; + } + + public static StringCollection StringCollectionToStringCollection(string collection, char separator = ',') + { + var list = new StringCollection(); + if (string.IsNullOrEmpty(collection)) return list; + + var array = collection.Split(separator); + foreach (var s in array) + { + list.Add(s.Trim()); + } + return list; + } + + public static string ObjectCollectionToString(ICollection collection) + { + var builder = new StringBuilder(); + if (collection == null) return builder.ToString(); + + foreach (var obj in collection) + { + builder.Append(obj.ToString().Trim()).Append(","); + } + if (builder.Length != 0) builder.Remove(builder.Length - 1, 1); + return builder.ToString(); + } + + public static string ObjectCollectionToString(ICollection collection, string separatorStr) + { + var builder = new StringBuilder(); + if (collection == null) return builder.ToString(); + + foreach (var obj in collection) + { + builder.Append(obj.ToString().Trim()).Append(separatorStr); + } + if (builder.Length != 0) builder.Remove(builder.Length - separatorStr.Length, separatorStr.Length); + return builder.ToString(); + } + + /// + /// 将对象集合转化为可供Sql语句查询的In()条件,如将集合{'ss','xx','ww'}转化为字符串"'ss','xx','ww'"。 + /// + /// 非数字的集合 + /// 可供Sql语句查询的In()条件字符串,各元素用单引号包围 + public static string ToSqlInStringWithQuote(ICollection collection) + { + var builder = new StringBuilder(); + if (collection == null) return builder.Length == 0 ? "null" : builder.ToString(); + + foreach (var obj in collection) + { + builder.Append("'").Append(obj).Append("'").Append(","); + } + if (builder.Length != 0) builder.Remove(builder.Length - 1, 1); + return builder.Length == 0 ? "null" : builder.ToString(); + } + + /// + /// 将数字集合转化为可供Sql语句查询的In()条件,如将集合{2,3,4}转化为字符串"2,3,4"。 + /// + /// 非数字的集合 + /// 可供Sql语句查询的In()条件字符串,各元素不使用单引号包围 + public static string ToSqlInStringWithoutQuote(ICollection collection) + { + var builder = new StringBuilder(); + if (collection != null) + { + foreach (var obj in collection) + { + builder.Append(obj).Append(","); + } + if (builder.Length != 0) builder.Remove(builder.Length - 1, 1); + } + return builder.Length == 0 ? "null" : builder.ToString(); + } + + + public static NameValueCollection ToNameValueCollection(string separateString) + { + if (!string.IsNullOrEmpty(separateString)) + { + separateString = separateString.Replace("/u0026", "&"); + } + return ToNameValueCollection(separateString, '&'); + } + + public static NameValueCollection ToNameValueCollection(string separateString, char separator) + { + var attributes = new NameValueCollection(); + if (!string.IsNullOrEmpty(separateString)) + { + var pairs = separateString.Split(separator); + foreach (var pair in pairs) + { + if (pair.IndexOf("=", StringComparison.Ordinal) != -1) + { + var name = StringUtils.ValueFromUrl(pair.Split('=')[0]); + var value = StringUtils.ValueFromUrl(pair.Split('=')[1]); + attributes.Add(name, value); + } + } + } + return attributes; + } + + public static string NameValueCollectionToString(NameValueCollection attributes, char separator = '&') + { + if (attributes == null || attributes.Count <= 0) return string.Empty; + + var builder = new StringBuilder(); + foreach (string key in attributes.Keys) + { + builder.Append( + $@"{StringUtils.ValueToUrl(key)}={StringUtils.ValueToUrl(attributes[key])}{separator}"); + } + builder.Length--; + return builder.ToString(); + } + + public static NameValueCollection DictionaryToNameValueCollection(IDictionary attributes) + { + var nvc = new NameValueCollection(StringComparer.OrdinalIgnoreCase); + if (attributes != null && attributes.Count > 0) + { + foreach (var key in attributes.Keys) + { + var value = attributes[key]; + if (value != null) + { + nvc[key] = attributes[key].ToString(); + } + } + } + return nvc; + } + + public static bool DictGetValue(Dictionary dict, int key) + { + if (dict.TryGetValue(key, out var retVal)) + { + return retVal; + } + + return false; + } + + public static string ToAttributesString(NameValueCollection attributes) + { + var builder = new StringBuilder(); + if (attributes != null && attributes.Count > 0) + { + foreach (string key in attributes.Keys) + { + var value = attributes[key]; + if (!string.IsNullOrEmpty(value)) + { + value = value.Replace("\"", "'"); + } + builder.Append($@"{key}=""{value}"" "); + } + builder.Length--; + } + return builder.ToString(); + } + + public static string ToAttributesString(Dictionary attributes) + { + var builder = new StringBuilder(); + if (attributes != null && attributes.Count > 0) + { + foreach (var key in attributes.Keys) + { + var value = attributes[key]; + + builder.Append(value == null ? $"{key} " : $@"{key}=""{value.Replace("\"", "'")}"" "); + } + builder.Length--; + } + return builder.ToString(); + } + + public static string NameValueCollectionToJsonString(NameValueCollection attributes) + { + var jsonString = new StringBuilder("{"); + if (attributes != null && attributes.Count > 0) + { + foreach (string key in attributes.Keys) + { + var value = attributes[key]; + value = value?.Replace("\\", "\\\\").Replace("\"", "\\\\\\\"").Replace("\r\n", string.Empty); + jsonString.AppendFormat(@"""{0}"": ""{1}"",", key, value); + } + jsonString.Length--; + } + jsonString.Append("}"); + return jsonString.ToString(); + } + + public static long GetKbSize(long byteSize) + { + long fileKbSize = Convert.ToUInt32(Math.Ceiling((double)byteSize / 1024)); + if (fileKbSize == 0) + { + fileKbSize = 1; + } + return fileKbSize; + } + + #region 汉字转拼音 + + private static readonly int[] PyValue = + { + -20319, -20317, -20304, -20295, -20292, -20283, -20265, -20257, -20242, -20230, -20051, -20036, -20032, + -20026, -20002, -19990, -19986, -19982, -19976, -19805, -19784, -19775, -19774, -19763, -19756, -19751, + -19746, -19741, -19739, -19728, + -19725, -19715, -19540, -19531, -19525, -19515, -19500, -19484, -19479, -19467, -19289, -19288, -19281, + -19275, -19270, -19263, + -19261, -19249, -19243, -19242, -19238, -19235, -19227, -19224, -19218, -19212, -19038, -19023, -19018, + -19006, -19003, -18996, + -18977, -18961, -18952, -18783, -18774, -18773, -18763, -18756, -18741, -18735, -18731, -18722, -18710, + -18697, -18696, -18526, + -18518, -18501, -18490, -18478, -18463, -18448, -18447, -18446, -18239, -18237, -18231, -18220, -18211, + -18201, -18184, -18183, + -18181, -18012, -17997, -17988, -17970, -17964, -17961, -17950, -17947, -17931, -17928, -17922, -17759, + -17752, -17733, -17730, + -17721, -17703, -17701, -17697, -17692, -17683, -17676, -17496, -17487, -17482, -17468, -17454, -17433, + -17427, -17417, -17202, + -17185, -16983, -16970, -16942, -16915, -16733, -16708, -16706, -16689, -16664, -16657, -16647, -16474, + -16470, -16465, -16459, + -16452, -16448, -16433, -16429, -16427, -16423, -16419, -16412, -16407, -16403, -16401, -16393, -16220, + -16216, -16212, -16205, + -16202, -16187, -16180, -16171, -16169, -16158, -16155, -15959, -15958, -15944, -15933, -15920, -15915, + -15903, -15889, -15878, + -15707, -15701, -15681, -15667, -15661, -15659, -15652, -15640, -15631, -15625, -15454, -15448, -15436, + -15435, -15419, -15416, + -15408, -15394, -15385, -15377, -15375, -15369, -15363, -15362, -15183, -15180, -15165, -15158, -15153, + -15150, -15149, -15144, + -15143, -15141, -15140, -15139, -15128, -15121, -15119, -15117, -15110, -15109, -14941, -14937, -14933, + -14930, -14929, -14928, + -14926, -14922, -14921, -14914, -14908, -14902, -14894, -14889, -14882, -14873, -14871, -14857, -14678, + -14674, -14670, -14668, + -14663, -14654, -14645, -14630, -14594, -14429, -14407, -14399, -14384, -14379, -14368, -14355, -14353, + -14345, -14170, -14159, + -14151, -14149, -14145, -14140, -14137, -14135, -14125, -14123, -14122, -14112, -14109, -14099, -14097, + -14094, -14092, -14090, + -14087, -14083, -13917, -13914, -13910, -13907, -13906, -13905, -13896, -13894, -13878, -13870, -13859, + -13847, -13831, -13658, + -13611, -13601, -13406, -13404, -13400, -13398, -13395, -13391, -13387, -13383, -13367, -13359, -13356, + -13343, -13340, -13329, + -13326, -13318, -13147, -13138, -13120, -13107, -13096, -13095, -13091, -13076, -13068, -13063, -13060, + -12888, -12875, -12871, + -12860, -12858, -12852, -12849, -12838, -12831, -12829, -12812, -12802, -12607, -12597, -12594, -12585, + -12556, -12359, -12346, + -12320, -12300, -12120, -12099, -12089, -12074, -12067, -12058, -12039, -11867, -11861, -11847, -11831, + -11798, -11781, -11604, + -11589, -11536, -11358, -11340, -11339, -11324, -11303, -11097, -11077, -11067, -11055, -11052, -11045, + -11041, -11038, -11024, + -11020, -11019, -11018, -11014, -10838, -10832, -10815, -10800, -10790, -10780, -10764, -10587, -10544, + -10533, -10519, -10331, + -10329, -10328, -10322, -10315, -10309, -10307, -10296, -10281, -10274, -10270, -10262, -10260, -10256, + -10254 + }; + + private static readonly string[] Pystr = + { + "a", "ai", "an", "ang", "ao", "ba", "bai", "ban", "bang", "bao", "bei", "ben", "beng", "bi", "bian", "biao", + "bie", "bin", "bing", "bo", "bu", "ca", "cai", "can", "cang", "cao", "ce", "ceng", "cha", "chai", "chan", + "chang", "chao", "che", "chen", + "cheng", "chi", "chong", "chou", "chu", "chuai", "chuan", "chuang", "chui", "chun", "chuo", "ci", "cong", + "cou", "cu", "cuan", "cui", + "cun", "cuo", "da", "dai", "dan", "dang", "dao", "de", "deng", "di", "dian", "diao", "die", "ding", "diu", + "dong", "dou", "du", "duan", + "dui", "dun", "duo", "e", "en", "er", "fa", "fan", "fang", "fei", "fen", "feng", "fo", "fou", "fu", "ga", + "gai", "gan", "gang", "gao", + "ge", "gei", "gen", "geng", "gong", "gou", "gu", "gua", "guai", "guan", "guang", "gui", "gun", "guo", "ha", + "hai", "han", "hang", + "hao", "he", "hei", "hen", "heng", "hong", "hou", "hu", "hua", "huai", "huan", "huang", "hui", "hun", "huo", + "ji", "jia", "jian", + "jiang", "jiao", "jie", "jin", "jing", "jiong", "jiu", "ju", "juan", "jue", "jun", "ka", "kai", "kan", + "kang", "kao", "ke", "ken", + "keng", "kong", "kou", "ku", "kua", "kuai", "kuan", "kuang", "kui", "kun", "kuo", "la", "lai", "lan", "lang", + "lao", "le", "lei", + "leng", "li", "lia", "lian", "liang", "liao", "lie", "lin", "ling", "liu", "long", "lou", "lu", "lv", "luan", + "lue", "lun", "luo", + "ma", "mai", "man", "mang", "mao", "me", "mei", "men", "meng", "mi", "mian", "miao", "mie", "min", "ming", + "miu", "mo", "mou", "mu", + "na", "nai", "nan", "nang", "nao", "ne", "nei", "nen", "neng", "ni", "nian", "niang", "niao", "nie", "nin", + "ning", "niu", "nong", + "nu", "nv", "nuan", "nue", "nuo", "o", "ou", "pa", "pai", "pan", "pang", "pao", "pei", "pen", "peng", "pi", + "pian", "piao", "pie", + "pin", "ping", "po", "pu", "qi", "qia", "qian", "qiang", "qiao", "qie", "qin", "qing", "qiong", "qiu", "qu", + "quan", "que", "qun", + "ran", "rang", "rao", "re", "ren", "reng", "ri", "rong", "rou", "ru", "ruan", "rui", "run", "ruo", "sa", + "sai", "san", "sang", + "sao", "se", "sen", "seng", "sha", "shai", "shan", "shang", "shao", "she", "shen", "sheng", "shi", "shou", + "shu", "shua", + "shuai", "shuan", "shuang", "shui", "shun", "shuo", "si", "song", "sou", "su", "suan", "sui", "sun", "suo", + "ta", "tai", + "tan", "tang", "tao", "te", "teng", "ti", "tian", "tiao", "tie", "ting", "tong", "tou", "tu", "tuan", "tui", + "tun", "tuo", + "wa", "wai", "wan", "wang", "wei", "wen", "weng", "wo", "wu", "xi", "xia", "xian", "xiang", "xiao", "xie", + "xin", "xing", + "xiong", "xiu", "xu", "xuan", "xue", "xun", "ya", "yan", "yang", "yao", "ye", "yi", "yin", "ying", "yo", + "yong", "you", + "yu", "yuan", "yue", "yun", "za", "zai", "zan", "zang", "zao", "ze", "zei", "zen", "zeng", "zha", "zhai", + "zhan", "zhang", + "zhao", "zhe", "zhen", "zheng", "zhi", "zhong", "zhou", "zhu", "zhua", "zhuai", "zhuan", "zhuang", "zhui", + "zhun", "zhuo", + "zi", "zong", "zou", "zu", "zuan", "zui", "zun", "zuo" + }; + + public static string ToPinYin(string chrstr) + { + var returnstr = string.Empty; + var nowchar = chrstr.ToCharArray(); + foreach (var t in nowchar) + { + var array = Encoding.Default.GetBytes(t.ToString()); + int i1 = array[0]; + int i2 = array[1]; + var chrasc = i1 * 256 + i2 - 65536; + if (chrasc > 0 && chrasc < 160) + { + returnstr += t; + } + else + { + for (var i = (PyValue.Length - 1); i >= 0; i--) + { + if (PyValue[i] <= chrasc) + { + returnstr += Pystr[i]; + break; + } + } + } + } + return returnstr; + } + + #endregion + + public static readonly JsonSerializerSettings JsonSettings = new JsonSerializerSettings + { + ContractResolver = new CamelCasePropertyNamesContractResolver(), + Converters = new List + { + new IsoDateTimeConverter {DateTimeFormat = "yyyy-MM-dd HH:mm:ss"} + }, + DateTimeZoneHandling = DateTimeZoneHandling.Utc + }; + + public static string JsonSerialize(object obj) + { + try + { + //var settings = new JsonSerializerSettings + //{ + // ContractResolver = new CamelCasePropertyNamesContractResolver() + //}; + //var timeFormat = new IsoDateTimeConverter {DateTimeFormat = "yyyy-MM-dd HH:mm:ss"}; + //settings.Converters.Add(timeFormat); + + return JsonConvert.SerializeObject(obj, JsonSettings); + } + catch + { + return string.Empty; + } + } + + public static T JsonDeserialize(string json, T defaultValue = default(T)) + { + try + { + //var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() }; + //var timeFormat = new IsoDateTimeConverter { DateTimeFormat = "yyyy-MM-dd HH:mm:ss" }; + //settings.Converters.Add(timeFormat); + + return JsonConvert.DeserializeObject(json, JsonSettings); + } + catch + { + return defaultValue; + } + } + + public static Dictionary JsonGetDictionaryIgnoreCase(JObject json) + { + return new Dictionary(json.ToObject>(), StringComparer.OrdinalIgnoreCase); + } + + public const string EncryptStingIndicator = "0secret0"; + + public static string EncryptStringBySecretKey(string inputString) + { + return EncryptStringBySecretKey(inputString, WebConfigUtils.SecretKey); + } + + public static string EncryptStringBySecretKey(string inputString, string secretKey) + { + if (string.IsNullOrEmpty(inputString) || string.IsNullOrEmpty(secretKey)) return string.Empty; + + var encrypt = new DesEncryptor + { + InputString = inputString, + EncryptKey = secretKey + }; + encrypt.DesEncrypt(); + + var retVal = encrypt.OutString; + retVal = retVal.Replace("+", "0add0").Replace("=", "0equals0").Replace("&", "0and0").Replace("?", "0question0").Replace("'", "0quote0").Replace("/", "0slash0"); + + return retVal + EncryptStingIndicator; + } + + public static string DecryptStringBySecretKey(string inputString) + { + return DecryptStringBySecretKey(inputString, WebConfigUtils.SecretKey); + } + + private static string DecryptStringBySecretKey(string inputString, string secretKey) + { + if (string.IsNullOrEmpty(inputString) || string.IsNullOrEmpty(secretKey)) return string.Empty; + + inputString = inputString.Replace(EncryptStingIndicator, string.Empty).Replace("0add0", "+").Replace("0equals0", "=").Replace("0and0", "&").Replace("0question0", "?").Replace("0quote0", "'").Replace("0slash0", "/"); + + var encrypt = new DesEncryptor + { + InputString = inputString, + DecryptKey = secretKey + }; + encrypt.DesDecrypt(); + + return encrypt.OutString; + } + + + + public static List> DataTableToDictionaryList(DataTable dataTable) + { + var rows = new List>(); + + foreach (DataRow dataRow in dataTable.Rows) + { + var row = new Dictionary(); + foreach (DataColumn col in dataTable.Columns) + { + row.Add(col.ColumnName, dataRow[col]); + } + rows.Add(row); + } + + return rows; + } + + public static NameValueCollection NewIgnoreCaseNameValueCollection() + { + var comparer = StringComparer.OrdinalIgnoreCase; + var caseInsensitiveDictionary = new NameValueCollection(comparer); + return caseInsensitiveDictionary; + } + + public static T ToObject(IDictionary dict) + { + var props = typeof(T).GetProperties(); + var res = Activator.CreateInstance(); + foreach (var property in props) + { + if (property.CanWrite && dict.ContainsKey(property.Name)) + { + property.SetValue(res, dict[property.Name], null); + } + } + return res; + } + } +} diff --git a/src/SiteServer.Utils/ValidateTypeUtils.cs b/src/SiteServer.Utils/ValidateTypeUtils.cs new file mode 100644 index 000000000..2b6d746d2 --- /dev/null +++ b/src/SiteServer.Utils/ValidateTypeUtils.cs @@ -0,0 +1,134 @@ +using System; +using SiteServer.Plugin; + +namespace SiteServer.Utils +{ + public static class ValidateTypeUtils + { + public static string GetText(ValidateType type) + { + if (type == ValidateType.None) + { + return "无"; + } + if (type == ValidateType.Chinese) + { + return "中文"; + } + if (type == ValidateType.English) + { + return "英文"; + } + if (type == ValidateType.Email) + { + return "Email格式"; + } + if (type == ValidateType.Url) + { + return "网址格式"; + } + if (type == ValidateType.Phone) + { + return "电话号码"; + } + if (type == ValidateType.Mobile) + { + return "手机号码"; + } + if (type == ValidateType.Integer) + { + return "整数"; + } + if (type == ValidateType.Currency) + { + return "货币格式"; + } + if (type == ValidateType.Zip) + { + return "邮政编码"; + } + if (type == ValidateType.IdCard) + { + return "身份证号码"; + } + if (type == ValidateType.RegExp) + { + return "正则表达式验证"; + } + throw new Exception(); + } + + public static ValidateType GetEnumType(string typeStr) + { + var retval = ValidateType.None; + + if (Equals(ValidateType.None, typeStr)) + { + retval = ValidateType.None; + } + else if (Equals(ValidateType.Chinese, typeStr)) + { + retval = ValidateType.Chinese; + } + else if (Equals(ValidateType.Currency, typeStr)) + { + retval = ValidateType.Currency; + } + else if (Equals(ValidateType.RegExp, typeStr)) + { + retval = ValidateType.RegExp; + } + else if (Equals(ValidateType.Email, typeStr)) + { + retval = ValidateType.Email; + } + else if (Equals(ValidateType.English, typeStr)) + { + retval = ValidateType.English; + } + else if (Equals(ValidateType.IdCard, typeStr)) + { + retval = ValidateType.IdCard; + } + else if (Equals(ValidateType.Integer, typeStr)) + { + retval = ValidateType.Integer; + } + else if (Equals(ValidateType.Mobile, typeStr)) + { + retval = ValidateType.Mobile; + } + else if (Equals(ValidateType.Phone, typeStr)) + { + retval = ValidateType.Phone; + } + else if (Equals(ValidateType.Url, typeStr)) + { + retval = ValidateType.Url; + } + else if (Equals(ValidateType.Zip, typeStr)) + { + retval = ValidateType.Zip; + } + + return retval; + } + + public static bool Equals(ValidateType type, string typeStr) + { + if (string.IsNullOrEmpty(typeStr)) return false; + if (string.Equals(type.Value.ToLower(), typeStr.ToLower())) + { + return true; + } + return false; + } + + public static bool Equals(string typeStr, ValidateType type) + { + return Equals(type, typeStr); + } + + + } +} diff --git a/src/SiteServer.Utils/WebConfigUtils.cs b/src/SiteServer.Utils/WebConfigUtils.cs new file mode 100644 index 000000000..01edd7414 --- /dev/null +++ b/src/SiteServer.Utils/WebConfigUtils.cs @@ -0,0 +1,467 @@ +using System; +using System.Text; +using System.Xml; +using Datory; + +namespace SiteServer.Utils +{ + public static class WebConfigUtils + { + public const string WebConfigFileName = "Web.config"; + /// + /// 获取当前正在执行的服务器应用程序的根目录的物理文件系统路径。 + /// + public static string PhysicalApplicationPath { get; private set; } + + public static bool IsNightlyUpdate { get; private set; } + + public static bool IsProtectData { get; private set; } + public static DatabaseType DatabaseType { get; private set; } + + private static string _connectionString; + + public static string ConnectionStringUserId { get; private set; } + + public static string ConnectionString + { + get => _connectionString; + private set + { + _connectionString = value; + ConnectionStringUserId = GetConnectionStringUserId(_connectionString); + } + } + + public static string ApiPrefix { get; private set; } + public static string AdminDirectory { get; private set; } + public static string HomeDirectory { get; private set; } + public static string SecretKey { get; private set; } + + public static void Load(string physicalApplicationPath, string webConfigPath) + { + PhysicalApplicationPath = physicalApplicationPath; + + var isProtectData = false; + var databaseType = string.Empty; + var connectionString = string.Empty; + try + { + var doc = new XmlDocument(); + + doc.Load(webConfigPath); + + var appSettings = doc.SelectSingleNode("configuration/appSettings"); + if (appSettings != null) + { + foreach (XmlNode setting in appSettings) + { + if (setting.Name == "add") + { + var attrKey = setting.Attributes?["key"]; + if (attrKey != null) + { + if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(IsProtectData))) + { + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + isProtectData = TranslateUtils.ToBool(attrValue.Value); + } + } + else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(DatabaseType))) + { + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + databaseType = attrValue.Value; + } + } + else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(ConnectionString))) + { + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + connectionString = attrValue.Value; + } + } + else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(ApiPrefix))) + { + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + ApiPrefix = attrValue.Value; + } + } + else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(AdminDirectory))) + { + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + AdminDirectory = attrValue.Value; + } + } + else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(HomeDirectory))) + { + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + HomeDirectory = attrValue.Value; + } + } + else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(SecretKey))) + { + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + SecretKey = attrValue.Value; + } + } + else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(IsNightlyUpdate))) + { + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + IsNightlyUpdate = TranslateUtils.ToBool(attrValue.Value); + } + } + } + } + } + + if (isProtectData) + { + databaseType = TranslateUtils.DecryptStringBySecretKey(databaseType); + connectionString = TranslateUtils.DecryptStringBySecretKey(connectionString); + } + } + } + catch + { + // ignored + } + + IsProtectData = isProtectData; + DatabaseType = DatabaseTypeUtils.GetEnumType(databaseType); + ConnectionString = GetConnectionString(DatabaseType, connectionString); + if (ApiPrefix == null) + { + ApiPrefix = "api"; + } + if (AdminDirectory == null) + { + AdminDirectory = "SiteServer"; + } + if (HomeDirectory == null) + { + HomeDirectory = "Home"; + } + if (string.IsNullOrEmpty(SecretKey)) + { + SecretKey = StringUtils.GetShortGuid(); + //SecretKey = "vEnfkn16t8aeaZKG3a4Gl9UUlzf4vgqU9xwh8ZV5"; + } + } + + public static void UpdateWebConfig(bool isProtectData, DatabaseType databaseType, string connectionString, string apiPrefix, string adminDirectory, string homeDirectory, string secretKey, bool isNightlyUpdate) + { + connectionString = GetConnectionString(databaseType, connectionString); + + var configPath = PathUtils.Combine(PhysicalApplicationPath, WebConfigFileName); + UpdateWebConfig(configPath, isProtectData, databaseType, connectionString, apiPrefix, adminDirectory, homeDirectory, secretKey, isNightlyUpdate); + + IsProtectData = isProtectData; + DatabaseType = databaseType; + ConnectionString = connectionString; + } + + public static void UpdateWebConfig(string configPath, bool isProtectData, DatabaseType databaseType, string connectionString, string apiPrefix, string adminDirectory, string homeDirectory, string secretKey, bool isNightlyUpdate) + { + connectionString = GetConnectionString(databaseType, connectionString); + + var doc = new XmlDocument(); + doc.Load(configPath); + var dirty = false; + var appSettings = doc.SelectSingleNode("configuration/appSettings"); + if (appSettings != null) + { + foreach (XmlNode setting in appSettings) + { + if (setting.Name == "add") + { + var attrKey = setting.Attributes?["key"]; + if (attrKey != null) + { + if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(IsProtectData))) + { + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + attrValue.Value = isProtectData.ToString(); + dirty = true; + } + } + else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(DatabaseType))) + { + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + attrValue.Value = databaseType.Value; + if (isProtectData) + { + attrValue.Value = TranslateUtils.EncryptStringBySecretKey(attrValue.Value, secretKey); + } + dirty = true; + } + } + else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(ConnectionString))) + { + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + attrValue.Value = connectionString; + if (isProtectData) + { + attrValue.Value = TranslateUtils.EncryptStringBySecretKey(attrValue.Value, secretKey); + } + dirty = true; + } + } + else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(ApiPrefix))) + { + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + attrValue.Value = apiPrefix; + dirty = true; + } + } + else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(AdminDirectory))) + { + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + attrValue.Value = adminDirectory; + dirty = true; + } + } + else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(HomeDirectory))) + { + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + attrValue.Value = homeDirectory; + dirty = true; + } + } + else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(SecretKey))) + { + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + attrValue.Value = secretKey; + dirty = true; + } + } + else if (StringUtils.EqualsIgnoreCase(attrKey.Value, nameof(IsNightlyUpdate))) + { + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + attrValue.Value = isNightlyUpdate.ToString(); + dirty = true; + } + } + } + } + } + } + + if (dirty) + { + var writer = new XmlTextWriter(configPath, Encoding.UTF8) + { + Formatting = Formatting.Indented + }; + doc.Save(writer); + writer.Flush(); + writer.Close(); + } + } + + public static string GetConnectionStringByName(string name) + { + var connectionString = string.Empty; + try + { + var doc = new XmlDocument(); + + var configFile = PathUtils.Combine(PhysicalApplicationPath, WebConfigFileName); + + doc.Load(configFile); + + var appSettings = doc.SelectSingleNode("configuration/appSettings"); + if (appSettings != null) + { + foreach (XmlNode setting in appSettings) + { + if (setting.Name != "add") continue; + + var attrKey = setting.Attributes?["key"]; + if (attrKey == null) continue; + + if (!StringUtils.EqualsIgnoreCase(attrKey.Value, name)) continue; + + var attrValue = setting.Attributes["value"]; + if (attrValue != null) + { + connectionString = attrValue.Value; + } + break; + } + } + } + catch + { + // ignored + } + + return connectionString; + } + + public static string GetConnectionString(DatabaseType databaseType, string server, bool isDefaultPort, int port, string userName, string password, string database) + { + var connectionString = string.Empty; + + if (databaseType == DatabaseType.MySql) + { + connectionString = $"Server={server};"; + if (!isDefaultPort && port > 0) + { + connectionString += $"Port={port};"; + } + connectionString += $"Uid={userName};Pwd={password};"; + if (!string.IsNullOrEmpty(database)) + { + connectionString += $"Database={database};"; + } + connectionString += "SslMode=Preferred;CharSet=utf8mb4;"; + } + else if (databaseType == DatabaseType.SqlServer) + { + connectionString = $"Server={server};"; + if (!isDefaultPort && port > 0) + { + connectionString += $"Port={port};"; + } + connectionString += $"Uid={userName};Pwd={password};"; + if (!string.IsNullOrEmpty(database)) + { + connectionString += $"Database={database};"; + } + } + else if (databaseType == DatabaseType.PostgreSql) + { + connectionString = $"Host={server};"; + if (!isDefaultPort && port > 0) + { + connectionString += $"Port={port};"; + } + connectionString += $"Username={userName};Password={password};"; + if (!string.IsNullOrEmpty(database)) + { + connectionString += $"Database={database};"; + } + } + else if (databaseType == DatabaseType.Oracle) + { + port = !isDefaultPort && port > 0 ? port : 1521; + database = string.IsNullOrEmpty(database) + ? string.Empty + : $"(CONNECT_DATA=(SERVICE_NAME={database}))"; + connectionString = $"Data Source=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST={server})(PORT={port})){database});User ID={userName};Password={password};pooling=false;"; + } + + return connectionString; + } + + private static string GetConnectionString(DatabaseType databaseType, string connectionString) + { + if (databaseType == DatabaseType.MySql) + { + connectionString = connectionString.TrimEnd(';'); + if (!StringUtils.ContainsIgnoreCase(connectionString, "SslMode=")) + { + connectionString += ";SslMode=Preferred;"; + } + if (!StringUtils.ContainsIgnoreCase(connectionString, "CharSet=")) + { + connectionString += ";CharSet=utf8mb4;"; + } + } + else if (databaseType == DatabaseType.Oracle) + { + connectionString = connectionString.TrimEnd(';'); + if (!StringUtils.ContainsIgnoreCase(connectionString, "pooling=")) + { + connectionString += ";pooling=false;"; + } + } + + return connectionString; + } + + private static string GetConnectionStringUserId(string connectionString) + { + var userId = string.Empty; + + foreach (var pair in TranslateUtils.StringCollectionToStringList(connectionString, ';')) + { + if (!string.IsNullOrEmpty(pair) && pair.IndexOf("=", StringComparison.Ordinal) != -1) + { + var key = pair.Substring(0, pair.IndexOf("=", StringComparison.Ordinal)); + var value = pair.Substring(pair.IndexOf("=", StringComparison.Ordinal) + 1); + if (StringUtils.EqualsIgnoreCase(key, "Uid") || + StringUtils.EqualsIgnoreCase(key, "Username") || + StringUtils.EqualsIgnoreCase(key, "User ID")) + { + return value; + } + } + } + + return userId; + } + + private static string GetValueFromConnectionString(string connectionString, string attribute) + { + var retVal = string.Empty; + if (!string.IsNullOrEmpty(connectionString) && !string.IsNullOrEmpty(attribute)) + { + var pairs = connectionString.Split(';'); + foreach (var pair in pairs) + { + if (pair.IndexOf("=", StringComparison.Ordinal) != -1) + { + if (StringUtils.EqualsIgnoreCase(attribute, pair.Trim().Split('=')[0])) + { + retVal = pair.Trim().Split('=')[1]; + break; + } + } + } + } + return retVal; + } + + public static string GetDatabaseNameFormConnectionString(DatabaseType databaseType, string connectionString) + { + if (databaseType == DatabaseType.Oracle) + { + var index1 = connectionString.IndexOf("SERVICE_NAME=", StringComparison.Ordinal); + var index2 = connectionString.IndexOf(")));", StringComparison.Ordinal); + return connectionString.Substring(index1 + 13, index2 - index1 - 13); + } + return GetValueFromConnectionString(connectionString, "Database"); + } + } +} \ No newline at end of file diff --git a/src/SiteServer.Utils/XmlUtils.cs b/src/SiteServer.Utils/XmlUtils.cs new file mode 100644 index 000000000..a889cfe5b --- /dev/null +++ b/src/SiteServer.Utils/XmlUtils.cs @@ -0,0 +1,37 @@ +using System.Xml; + +namespace SiteServer.Utils +{ + public class XmlUtils + { + + public static XmlDocument GetXmlDocument(string xmlContent) + { + var xmlDocument = new XmlDocument(); + try + { + xmlDocument.LoadXml(xmlContent); + } + catch + { + // ignored + } + + return xmlDocument; + } + + public static XmlNode GetXmlNode(XmlDocument xmlDocument, string xpath) + { + XmlNode node = null; + try + { + node = xmlDocument.SelectSingleNode(xpath); + } + catch + { + // ignored + } + return node; + } + } +} diff --git a/src/SiteServer.Utils/ZipUtils.cs b/src/SiteServer.Utils/ZipUtils.cs new file mode 100644 index 000000000..8cc75dc97 --- /dev/null +++ b/src/SiteServer.Utils/ZipUtils.cs @@ -0,0 +1,193 @@ +using ICSharpCode.SharpZipLib.Zip; + +namespace SiteServer.Utils +{ + public static class ZipUtils + { + public static void CreateZip(string zipFilePath, string directoryPath) + { + var fz = new FastZip {CreateEmptyDirectories = true}; + fz.CreateZip(zipFilePath, directoryPath, true, string.Empty); + } + + public static void ExtractZip(string zipFilePath, string directoryPath) + { + var fz = new FastZip(); + fz.ExtractZip(zipFilePath, directoryPath, null); + } + + //public static void UnpackFilesByExtension(string zipFilePath, string directoryPath, string extension) + //{ + // var fz = new FastZip(); + // fz.ExtractZip(zipFilePath, directoryPath, ".*\\" + extension + "$"); + //} + + //public static bool UnpackFiles(string zipFilePath, string directoryPath) + //{ + // if (!Directory.Exists(directoryPath)) + // Directory.CreateDirectory(directoryPath); + + // ZipInputStream s = new ZipInputStream(File.OpenRead(zipFilePath)); + + // ZipEntry theEntry; + // while ((theEntry = s.GetNextEntry()) != null) + // { + // string directoryName = Path.GetDirectoryName(theEntry.Name); + // string fileName = Path.GetFileName(theEntry.Name); + + // if (directoryName != string.Empty) + // Directory.CreateDirectory(directoryPath + directoryName); + + // if (fileName != string.Empty) + // { + // FileStream streamWriter = File.Create(Path.Combine(directoryPath, theEntry.Name)); + + // int size = 2048; + // byte[] data = new byte[2048]; + // while (true) + // { + // size = s.Read(data, 0, data.Length); + // if (size > 0) + // { + // streamWriter.Write(data, 0, size); + // } + // else + // { + // break; + // } + // } + + // streamWriter.Close(); + // } + // } + // s.Close(); + // return true; + //} + + + // public static void Zip(string directoryPath, string zipFilePath) + //{ + // var filenames = Directory.GetFiles(directoryPath); + + // var crc = new Crc32(); + // var s = new ZipOutputStream(File.Create(zipFilePath)); + + // s.SetLevel(6); // 0 - store only to 9 - means best compression + + // foreach (var file in filenames) + // { + // var fs = File.OpenRead(file); + + // var buffer = new byte[fs.Length]; + // fs.Read(buffer, 0, buffer.Length); + // var entry = new ZipEntry(file) + // { + // DateTime = DateTime.Now, + // Size = fs.Length + // }; + + // // set Size and the crc, because the information + // // about the size and crc should be stored in the header + // // if it is not set it is automatically written in the footer. + // // (in this case size == crc == -1 in the header) + // // Some ZIP programs have problems with zip files that don't store + // // the size and crc in the header. + // fs.Close(); + + // crc.Reset(); + // crc.Update(buffer); + + // entry.Crc = crc.Value; + + // s.PutNextEntry(entry); + + // s.Write(buffer, 0, buffer.Length); + + // } + + // s.Finish(); + // s.Close(); + //} + + + //public static void UnZip(string directoryPath, string zipFilePath) + //{ + // var s = new ZipInputStream(File.OpenRead(zipFilePath)); + + // ZipEntry theEntry; + // while ((theEntry = s.GetNextEntry()) != null) + // { + // var fileInfo = new FileInfo(theEntry.Name); + // var fileName = fileInfo.Name; + + // // create directory + // DirectoryUtils.CreateDirectoryIfNotExists(directoryPath); + + // if (fileName == string.Empty) continue; + + // var filePath = directoryPath + Path.DirectorySeparatorChar + fileName; + // var streamWriter = File.Create(filePath); + + // var data = new byte[2048]; + // while (true) + // { + // var size = s.Read(data, 0, data.Length); + // if (size > 0) + // { + // streamWriter.Write(data, 0, size); + // } + // else + // { + // break; + // } + // } + + // streamWriter.Close(); + // } + // s.Close(); + //} + + + +// public static void UnZip(string zipFilePath) +// { +// ZipInputStream s = new ZipInputStream(File.OpenRead(zipFilePath)); +// +// ZipEntry theEntry; +// while ((theEntry = s.GetNextEntry()) != null) +// { +// +// Console.WriteLine(theEntry.Name); +// +// string directoryName = Path.GetDirectoryName(theEntry.Name); +// string fileName = Path.GetFileName(theEntry.Name); +// +// // create directory +// Directory.CreateDirectory(directoryName); +// +// if (fileName != string.Empty) +// { +// FileStream streamWriter = File.Create(theEntry.Name); +// +// int size = 2048; +// byte[] data = new byte[2048]; +// while (true) +// { +// size = s.Read(data, 0, data.Length); +// if (size > 0) +// { +// streamWriter.Write(data, 0, size); +// } +// else +// { +// break; +// } +// } +// +// streamWriter.Close(); +// } +// } +// s.Close(); +// } + } +} diff --git a/tests/Datory.Tests/Datory.Tests.csproj b/tests/Datory.Tests/Datory.Tests.csproj new file mode 100644 index 000000000..9ebf2a67a --- /dev/null +++ b/tests/Datory.Tests/Datory.Tests.csproj @@ -0,0 +1,23 @@ + + + + netcoreapp2.2 + + false + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + all + runtime; build; native; contentfiles; analyzers + + + + + diff --git a/tests/SiteServer.API.Core.Tests/SiteServer.API.Core.Tests.csproj b/tests/SiteServer.API.Core.Tests/SiteServer.API.Core.Tests.csproj new file mode 100644 index 000000000..b10a13e52 --- /dev/null +++ b/tests/SiteServer.API.Core.Tests/SiteServer.API.Core.Tests.csproj @@ -0,0 +1,16 @@ + + + + netcoreapp2.2 + + false + + + + + + + + + + diff --git a/tests/SiteServer.API.Core.Tests/UnitTest1.cs b/tests/SiteServer.API.Core.Tests/UnitTest1.cs new file mode 100644 index 000000000..da236c233 --- /dev/null +++ b/tests/SiteServer.API.Core.Tests/UnitTest1.cs @@ -0,0 +1,13 @@ +using Xunit; + +namespace SiteServer.API.Core.Tests +{ + public class UnitTest1 + { + [Fact] + public void Test1() + { + + } + } +} diff --git a/tests/SiteServer.Utils.Tests/SiteServer.Utils.Tests.csproj b/tests/SiteServer.Utils.Tests/SiteServer.Utils.Tests.csproj new file mode 100644 index 000000000..34178e1ba --- /dev/null +++ b/tests/SiteServer.Utils.Tests/SiteServer.Utils.Tests.csproj @@ -0,0 +1,23 @@ + + + + netcoreapp2.2 + + false + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + diff --git a/tests/SiteServer.Utils.Tests/TestDirectoryUtils.cs b/tests/SiteServer.Utils.Tests/TestDirectoryUtils.cs new file mode 100644 index 000000000..77439240b --- /dev/null +++ b/tests/SiteServer.Utils.Tests/TestDirectoryUtils.cs @@ -0,0 +1,24 @@ +using System; +using System.IO; +using System.Reflection; +using Xunit; + +namespace SiteServer.Utils.Tests +{ + public class TestDirectoryUtils + { + [Fact] + public void TestGetParentPath() + { + var codeBaseUrl = new Uri(Assembly.GetExecutingAssembly().CodeBase); + var codeBasePath = Uri.UnescapeDataString(codeBaseUrl.AbsolutePath); + var dirPath = Path.GetDirectoryName(codeBasePath); + + dirPath = DirectoryUtils.GetParentPath(dirPath); + Assert.Equal("Bin", PathUtils.GetDirectoryName(dirPath, false), StringComparer.OrdinalIgnoreCase); + + dirPath = DirectoryUtils.GetParentPath(dirPath); + Assert.Equal("SiteServer.Utils.Tests", PathUtils.GetDirectoryName(dirPath, false), StringComparer.OrdinalIgnoreCase); + } + } +} diff --git a/tests/SiteServer.Utils.Tests/TestStringUtils.cs b/tests/SiteServer.Utils.Tests/TestStringUtils.cs new file mode 100644 index 000000000..3a0b643f1 --- /dev/null +++ b/tests/SiteServer.Utils.Tests/TestStringUtils.cs @@ -0,0 +1,22 @@ +using Xunit; +using SiteServer.Utils; + +namespace SiteServer.Utils.Tests +{ + public class TestStringUtils + { + [Fact] + public void TestReplaceEndsWith() + { + var replaced = StringUtils.ReplaceEndsWith("UserName DESC", " DESC", string.Empty); + Assert.Equal("UserName", replaced); + } + + [Fact] + public void TestReplaceEndsWithIgnoreCase() + { + var replaced = StringUtils.ReplaceEndsWithIgnoreCase("UserName desc", " DESC", string.Empty); + Assert.Equal("UserName", replaced); + } + } +} diff --git a/tests/SiteServer.Utils.Tests/UnitTest1.cs b/tests/SiteServer.Utils.Tests/UnitTest1.cs new file mode 100644 index 000000000..d513beb39 --- /dev/null +++ b/tests/SiteServer.Utils.Tests/UnitTest1.cs @@ -0,0 +1,14 @@ +using System; +using Xunit; + +namespace SiteServer.Utils.Tests +{ + public class UnitTest1 + { + [Fact] + public void Test1() + { + + } + } +} diff --git a/web/.babelrc b/web/.babelrc new file mode 100644 index 000000000..c495b7a5c --- /dev/null +++ b/web/.babelrc @@ -0,0 +1,17 @@ +{ + "env": { + "test": { + "presets": [ + [ + "@babel/preset-env", + { + "targets": { + "node": "current" + } + } + ], + "@nuxt/babel-preset-app" + ] + } + } +} diff --git a/web/.editorconfig b/web/.editorconfig new file mode 100644 index 000000000..7c2eb6409 --- /dev/null +++ b/web/.editorconfig @@ -0,0 +1,13 @@ +# editorconfig.org +root = true + +[*] +indent_style = space +indent_size = 2 +end_of_line = crlf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false diff --git a/web/.eslintrc.js b/web/.eslintrc.js new file mode 100644 index 000000000..59556906c --- /dev/null +++ b/web/.eslintrc.js @@ -0,0 +1,19 @@ +module.exports = { + root: true, + env: { + browser: true, + node: true + }, + parserOptions: { + parser: 'babel-eslint' + }, + extends: [ + '@nuxtjs', + 'plugin:vue/strongly-recommended' + ], + plugins: [ + 'prettier' + ], + // add your custom rules here + rules: {} +} diff --git a/web/.gitignore b/web/.gitignore new file mode 100644 index 000000000..f935a370c --- /dev/null +++ b/web/.gitignore @@ -0,0 +1,84 @@ +# Created by .ignore support plugin (hsz.mobi) +### Node template +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (https://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# TypeScript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + +# parcel-bundler cache (https://parceljs.org/) +.cache + +# next.js build output +.next + +# nuxt.js build output +.nuxt + +# Nuxt generate +dist + +# vuepress build output +.vuepress/dist + +# Serverless directories +.serverless + +# IDE +.idea + +# Service worker +sw.* diff --git a/web/.prettierrc b/web/.prettierrc new file mode 100644 index 000000000..b2095be81 --- /dev/null +++ b/web/.prettierrc @@ -0,0 +1,4 @@ +{ + "semi": false, + "singleQuote": true +} diff --git a/web/.vscode/launch.json b/web/.vscode/launch.json new file mode 100644 index 000000000..63352900b --- /dev/null +++ b/web/.vscode/launch.json @@ -0,0 +1,14 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "node", + "request": "attach", + "name": "Attach to Nuxt", + "port": 9229 + } + ] +} diff --git a/web/README.md b/web/README.md new file mode 100644 index 000000000..bf1ce6d32 --- /dev/null +++ b/web/README.md @@ -0,0 +1,18 @@ +## Build Setup + +``` bash +# install dependencies +$ npm install + +# serve with hot reload at localhost:3000 +$ npm run dev + +# build for production and launch server +$ npm run build +$ npm start + +# generate static project +$ npm run generate +``` + +For detailed explanation on how things work, checkout [Nuxt.js docs](https://nuxtjs.org). diff --git a/web/assets/css/menu.css b/web/assets/css/menu.css new file mode 100644 index 000000000..b503f21d1 --- /dev/null +++ b/web/assets/css/menu.css @@ -0,0 +1,1362 @@ +/* +Template Name: Minton Dashboard +Author: CoderThemes +Email: coderthemes@gmail.com +File: Topbar,Left-sidebar,Right-sidebar +*/ +.topbar { + left: 0px; + position: fixed; + right: 0; + top: 0px; + z-index: 999; +} + +.topbar .topbar-left { + background: #282c37; + float: left; + height: 70px; + position: relative; + width: 240px; + z-index: 1; +} + +.navbar-default { + background-color: #323944; + border-radius: 0px; + border: none; + margin-bottom: 0px; +} + +.navbar-default .navbar-nav>.open>a { + background-color: rgba(0, 0, 0, 0.06); +} + +.navbar-default .navbar-nav>.open>a:focus { + background-color: rgba(0, 0, 0, 0.06); +} + +.navbar-default .navbar-nav>.open>a:hover { + background-color: rgba(0, 0, 0, 0.06); +} + +.nav>li>a { + color: #ffffff !important; + line-height: 70px; + padding: 0px 15px; + position: relative; +} + +.nav>li>a i { + font-size: 20px; +} + +.profile img { + border: 2px solid #edf0f0; + height: 36px; + width: 36px; +} + +.dropdown-menu-lg { + width: 300px; +} + +.dropdown-menu-lg .list-group { + margin-bottom: 0px; +} + +.dropdown-menu-lg .list-group-item { + border: none; + padding: 10px 20px; +} + +.dropdown-menu-lg .media-heading { + margin-bottom: 0px; +} + +.dropdown-menu-lg .media-body p { + color: #828282; +} + +.notifi-title { + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + color: #000000; + font-size: 16px; + font-weight: 400; + padding: 5px 0px 10px; +} + +.notification-list em { + width: 30px; + text-align: center; + height: 30px; + line-height: 28px; + border-radius: 50%; + margin-top: 4px; +} + +.notification-list .list-group-item { + padding: 12px 20px; +} + +.notification-list .media-body { + display: inherit; + width: auto; + overflow: hidden; + margin-left: 50px; +} + +.notification-list .media-body h5 { + text-overflow: ellipsis; + white-space: nowrap; + display: block; + width: 100%; + font-weight: normal; + overflow: hidden; +} + +.noti-primary { + color: #00b19d; + border: 2px solid #00b19d; +} + +.noti-success { + color: #00b19d; + border: 2px solid #00b19d; +} + +.noti-info { + color: #3ddcf7; + border: 2px solid #3ddcf7; +} + +.noti-warning { + color: #ffaa00; + border: 2px solid #ffaa00; +} + +.noti-danger { + color: #ef5350; + border: 2px solid #ef5350; +} + +.noti-purple { + color: #7266ba; + border: 2px solid #7266ba; +} + +.noti-pink { + color: #f76397; + border: 2px solid #f76397; +} + +.noti-inverse { + color: #4c5667; + border: 2px solid #4c5667; +} + +.navbar-form { + border: none; + box-shadow: none; + padding: 0px; +} + +.app-search { + position: relative; + margin: 15px 0px 15px 10px; +} + +.app-search a { + position: absolute; + top: 10px; + right: 20px; + color: rgba(255, 255, 255, 0.7); +} + +.app-search a:hover { + color: #ffffff; +} + +.app-search .form-control, +.app-search .form-control:focus { + border: none; + font-size: 13px; + color: #ffffff; + font-weight: 600; + padding-left: 20px; + padding-right: 40px; + margin-top: 3px; + background: rgba(255, 255, 255, 0.2); + box-shadow: none; + border-radius: 30px; + width: 190px; +} + +input.app-search-input::-webkit-input-placeholder { + color: rgba(255, 255, 255, 0.7); + font-weight: normal; +} + +input.app-search-input:-moz-placeholder { + color: rgba(255, 255, 255, 0.7); +} + +input.app-search-input::-moz-placeholder { + color: rgba(255, 255, 255, 0.7); +} + +input.app-search-input:-ms-input-placeholder { + color: rgba(255, 255, 255, 0.7); +} + +.navbar-nav { + margin: 0px; +} + +.side-menu { + bottom: 0; + top: 0; + width: 200px; + z-index: 2; +} + +.side-menu.left { + background: #eeeeee; + box-shadow: -4px 4px 40px rgba(0, 0, 0, 0.15); + position: absolute; + top: 62px; + position: fixed; +} + +body.fixed-left .side-menu.left { + bottom: 50px; + height: 100%; + margin-top: 0; + position: fixed; +} + +.content-page { + margin-left: 200px; + overflow: hidden; + background: #fff; + width: 100%; + height: 100%; + margin-top: 0; + position: fixed; +} + +.content-page>.content { + margin-bottom: 60px; + margin-top: 10px; + padding: 20px 5px 15px 5px; +} + +.button-menu-mobile { + background: transparent; + border: none; + color: #ffffff; + font-size: 21px; + line-height: 70px; + padding: 0px 15px; +} + +.button-menu-mobile:hover { + color: #eeeeee; +} + +.sidebar-inner { + height: 100%; + overflow: auto; +} + +#sidebar-menu, +#sidebar-menu ul, +#sidebar-menu li, +#sidebar-menu a { + border: 0; + font-family: 'Microsoft YaHei', sans-serif; + font-weight: normal; + line-height: 1; + font-size: 14px; + list-style: none; + margin: 0; + padding: 0; + position: relative; + text-decoration: none; +} + +#sidebar-menu { + background-color: #eeeeee; + width: 100%; +} + +#sidebar-menu a { + line-height: 1.3; +} + +#sidebar-menu a.badge { + display: block; + padding: 1px 5px; + font-weight: 600; + font-size: 12px; + float: right; + border-left: 0 !important; +} + +#sidebar-menu a.badge:hover { + background: #ffc107; + border-left: 0 !important; +} + +#sidebar-menu ul li .menu-arrow { + -webkit-transition: -webkit-transform 0.15s; + -o-transition: -o-transform 0.15s; + transition: transform .15s; + position: absolute; + right: 25px; + display: inline-block; + font-family: 'Ionicons'; + text-rendering: auto; + line-height: 25px; + font-size: 18px; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; + -webkit-transform: translate(0, 0); + -ms-transform: translate(0, 0); + -o-transform: translate(0, 0); + transform: translate(0, 0); + color: #98a6ad; +} + +#sidebar-menu ul li .menu-arrow:before { + content: "\f3d3"; +} + +#sidebar-menu ul li a.subdrop .menu-arrow { + -ms-transform: rotate(90deg); + -webkit-transform: rotate(90deg); + -o-transform: rotate(90deg); + transform: rotate(90deg); +} + +#sidebar-menu ul ul li { + border-top: 0; +} + +#sidebar-menu ul ul li.active a { + background: #ddd; + color: #00b19d; +} + +#sidebar-menu ul ul a { + color: #55565d; + display: block; + padding: 10px 10px 10px 45px; +} + +#sidebar-menu ul ul a:hover { + color: #00b19d; +} + +#sidebar-menu ul ul a i { + margin-right: 5px; +} + +#sidebar-menu ul ul ul a { + padding-left: 80px; +} + +#sidebar-menu>ul>li>a { + color: #565b5e; + border-left: 2px solid transparent; + display: block; + padding: 12px 10px; + font-size: 15px; +} + +#sidebar-menu>ul>li>a:hover { + background: #f5f5f5; + border-left: 2px solid #00b19d !important; +} + +#sidebar-menu>ul>li>a:hover i { + color: #00b19d !important; +} + +#sidebar-menu>ul>li>a:hover span { + color: #4c5667; +} + +#sidebar-menu>ul>li>a>span { + vertical-align: middle; +} + +#sidebar-menu>ul>li>a>i { + display: inline-block; + font-size: 18px; + line-height: 17px; + margin-left: 3px; + margin-right: 12px; + color: #565b5e; + text-align: center; + vertical-align: middle; + width: 20px; +} + +#sidebar-menu>ul>li>a>i.i-right { + float: right; + margin: 3px 0 0 0; +} + +#sidebar-menu>ul>li>a.active { + background: #f5f5f5; + border-left: 2px solid #00b19d !important; +} + +#sidebar-menu>ul>li>a.active i { + color: #00b19d !important; +} + +#sidebar-menu>ul>li>a.active span { + color: #4c5667; +} + +.menu-title { + padding: 12px 20px !important; + letter-spacing: .035em; + font-size: 15px !important; + margin-top: 10px !important; + font-weight: 500 !important; + padding-left: 32px !important; +} + +#sidebar-menu>ul>li>a.active.subdrop { + background: #f5f5f5 !important; + border-left: 2px solid #00b19d; +} + +#sidebar-menu>ul>li>a.active.subdrop i { + color: #00b19d; +} + +.subdrop { + background: #f5f5f5; + border-left: 2px solid #00b19d !important; +} + +.subdrop i { + color: #00b19d !important; +} + +.subdrop span { + color: #00b19d !important; +} + +#wrapper.enlarged .menu-title, +#wrapper.enlarged .menu-arrow { + display: none !important; +} + +#wrapper.enlarged #sidebar-menu ul ul { + box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.16), 0 2px 10px 0 rgba(0, 0, 0, 0.12); +} + +#wrapper.enlarged .left.side-menu { + width: 70px; + z-index: 5; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu>ul>li>a { + padding-left: 10px; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu>ul>li>a:hover { + background-color: #f5f5f5 !important; +} + +#wrapper.enlarged .left.side-menu span.pull-right { + display: none !important; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li { + position: relative; + white-space: nowrap; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li:hover>a { + background: #f5f5f5; + position: relative; + width: 260px; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li:hover>ul { + display: block; + left: 70px; + position: absolute; + width: 190px; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li:hover>ul a { + background: #ffffff; + border: none; + box-shadow: none; + padding-left: 15px; + position: relative; + width: 190px; + z-index: 6; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li:hover a span { + display: inline; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li>ul { + display: none; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul ul li:hover>ul { + display: block; + left: 190px; + margin-top: -36px; + position: absolute; + width: 190px; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul ul li>a span.pull-right { + -ms-transform: rotate(270deg); + -webkit-transform: rotate(270deg); + position: absolute; + right: 20px; + top: 12px; + transform: rotate(270deg); +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li>a span { + display: none; + padding-left: 10px; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu>ul>li>a>i { + margin: 0px; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu>ul>li>a { + padding: 15px 20px; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu>ul>li>a i { + margin-right: 20px !important; + font-size: 20px; + color: #a2acae; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li:hover>a { + position: relative; + width: 260px; + background: #f5f5f5; + color: #00b19d; + border-color: #00b19d; +} + +#wrapper.enlarged .left.side-menu #sidebar-menu ul>li:hover>a i { + color: #00b19d; +} + +#wrapper.enlarged .content-page { + margin-left: 70px; +} + +#wrapper.enlarged .topbar .topbar-left { + width: 70px !important; +} + +#wrapper.enlarged .topbar .topbar-left .logo span { + display: none; + opacity: 0; +} + +#wrapper.enlarged .topbar .topbar-left .logo i { + margin-right: 0px; +} + +#wrapper.enlarged #sidebar-menu>ul>li:hover>a.open :after { + display: none; +} + +#wrapper.enlarged #sidebar-menu>ul>li:hover>a.active :after { + display: none; +} + +#wrapper.enlarged .user-detail { + bottom: 0px; + padding: 13px 0px; + width: 70px; + text-align: center; +} + +#wrapper.enlarged .user-detail .dropup { + margin: 0px auto; + margin-left: 17px; +} + +#wrapper.enlarged .user-detail h5 { + display: none; +} + +#wrapper.enlarged .user-detail p { + position: absolute; + right: 12px; + top: 22px; +} + +#wrapper.enlarged .user-detail p span { + display: none; +} + +#wrapper.enlarged #sidebar-menu ul ul li.active a { + color: #00b19d; +} + +#wrapper.enlarged .footer { + left: 70px; +} + +#wrapper.right-bar-enabled .right-bar { + right: 0; +} + +#wrapper.right-bar-enabled .left-layout { + left: 0; +} + +.right-bar-toggle:focus { + background-color: rgba(0, 0, 0, 0.06) !important; +} + +.side-bar.right-bar { + float: right !important; + right: -270px; + bottom: 0px; + top: 70px; +} + +.side-bar { + -moz-transition: all 200ms ease-out; + -webkit-transition: all 200ms ease-out; + background-color: #ffffff; + box-shadow: 0px 0px 8px 1px rgba(0, 0, 0, 0.1); + display: block; + overflow-y: auto; + position: fixed; + transition: all 200ms ease-out; + width: 200px; +} + +.side-bar .nav.nav-tabs+.tab-content { + margin-bottom: 0px; + padding: 20px; +} + +.side-bar .tabs li.tab a { + font-weight: 600; +} + +.right-bar { + background: #ffffff !important; + position: fixed !important; + z-index: 99 !important; +} + +.right-bar h4 { + border-bottom: 1px solid #eeeeee; + padding-bottom: 10px; +} + +.right-bar .nicescroll { + height: 100%; +} + +.navbar-nav { + flex-direction: inherit; +} + +#topnav { + right: 0; + left: 0; + top: 0; + z-index: 1030; + background-color: transparent; + border: 0; + -webkit-transition: all .5s ease; + transition: all .5s ease; + height: 62px; +} + +#topnav .has-submenu.active a { + color: #fff; +} + +#topnav .has-submenu.active a i { + color: #fff; +} + +#topnav .has-submenu.active .submenu li.active a { + color: #00b19d; +} + +#topnav .topbar-main { + font-family: 'Microsoft YaHei', sans-serif; + background-color: #00b19d; + height: 62px; +} + +#topnav .topbar-main .logo { + color: #ffffff !important; + font-size: 18px; + font-weight: 700; + letter-spacing: .05em; + margin-left: 15px; + float: left; +} + +#topnav .topbar-main .toggle { + color: #ffffff !important; + font-size: 18px; + font-weight: 700; + letter-spacing: .05em; + margin-top: 9px; + margin-left: 5px; + float: left; + text-decoration: none; +} + +#topnav .topbar-main .logo h1 { + margin: 0px auto; + text-align: center; +} + +#topnav .topbar-main .logo i { + color: #ffffff; +} + +#topnav .topbar-main .badge { + position: absolute; + top: 12px; + right: -5px; +} + +#topnav .topbar-main .nav>li>a, #topnav .topbar-main .nav>li>a:hover { + color: #ffffff; + line-height: 60px; + padding: 0px 15px; + margin: 0; + width: 50px; + position: relative; + background: transparent; +} + +#topnav .topbar-main .nav>li>a i { + font-size: 24px; +} + +#topnav .topbar-main .nav>li>a { + padding: 0px 15px !important; +} + +#topnav .topbar-main .navbar-nav>.open>a { + background-color: rgba(255, 255, 255, 0.1) !important; +} + +#topnav .topbar-main .profile img { + border: 2px solid #edf0f0; + height: 36px; + width: 36px; +} + +#topnav .topbar-main .dropdown-menu-lg { + width: 300px; +} + +#topnav .topbar-main .dropdown-menu-lg .list-group { + margin-bottom: 0px; +} + +#topnav .topbar-main .dropdown-menu-lg .list-group-item { + border: none; + padding: 10px 20px; +} + +#topnav .topbar-main .dropdown-menu-lg .media-heading { + margin-bottom: 0px; +} + +#topnav .topbar-main .dropdown-menu-lg .media-body p { + color: #828282; +} + +#topnav .topbar-main .notification-list { + max-height: 230px; +} + +#topnav .topbar-main .notification-list em { + width: 34px; + text-align: center; +} + +#topnav .topbar-main .notification-list .media-body { + display: inherit; + width: auto; + overflow: hidden; + margin-left: 50px; +} + +#topnav .topbar-main .notification-list .media-body h5 { + text-overflow: ellipsis; + white-space: nowrap; + display: block; + width: 100%; + font-weight: normal; + overflow: hidden; +} + +#topnav .topbar-main .notifi-title { + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + font-size: 15px; + text-transform: uppercase; + font-weight: 600; + padding: 11px 20px 15px; + color: #4c5667; + font-family: 'Microsoft YaHei', sans-serif; +} + +#topnav .app-search { + position: relative; + margin: 15px 20px 15px 10px; +} + +#topnav .app-search a { + position: absolute; + top: 3px; + color: rgba(255, 255, 255, 0.7); +} + +#topnav .app-search a i { + font-size: 18px; +} + +#topnav .app-search .form-control, +#topnav .app-search .form-control:focus { + border: none; + font-size: 13px; + cursor: initial !important; + color: #ffffff; + padding-left: 20px; + padding-right: 40px; + margin-top: 3px; + background: rgba(255, 255, 255, 0.2); + box-shadow: none; + border-radius: 30px; + height: 30px; + width: 180px; +} + +#topnav .app-search input::-webkit-input-placeholder { + color: rgba(255, 255, 255, 0.7); + font-weight: normal; +} + +#topnav .app-search input:-moz-placeholder { + color: rgba(255, 255, 255, 0.7); +} + +#topnav .app-search input::-moz-placeholder { + color: rgba(255, 255, 255, 0.7); +} + +#topnav .app-search input:-ms-input-placeholder { + color: rgba(255, 255, 255, 0.7); +} + +#topnav .notifi-title { + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + color: #000000; + font-size: 16px; + font-weight: 400; + padding: 5px 0px 10px; +} + +#topnav .notification-list em { + width: 30px; + text-align: center; + height: 30px; + line-height: 28px; + border-radius: 50%; + margin-top: 4px; +} + +#topnav .notification-list .list-group-item { + padding: 12px 20px; +} + +#topnav .notification-list .media-body { + display: inherit; + width: auto; + overflow: hidden; + margin-left: 50px; +} + +#topnav .notification-list .media-body h5 { + text-overflow: ellipsis; + white-space: nowrap; + display: block; + width: 100%; + font-weight: normal; + overflow: hidden; +} + +#topnav .noti-primary { + color: #00b19d; + border: 2px solid #00b19d; +} + +#topnav .noti-success { + color: #3bafda; + border: 2px solid #3bafda; +} + +#topnav .noti-info { + color: #3ddcf7; + border: 2px solid #3ddcf7; +} + +#topnav .noti-warning { + color: #ffaa00; + border: 2px solid #ffaa00; +} + +#topnav .noti-danger { + color: #ef5350; + border: 2px solid #ef5350; +} + +#topnav .noti-purple { + color: #7266ba; + border: 2px solid #7266ba; +} + +#topnav .noti-pink { + color: #f76397; + border: 2px solid #f76397; +} + +#topnav .noti-inverse { + color: #4c5667; + border: 2px solid #4c5667; +} + +#topnav .navbar-custom { + background-color: #ffffff; + box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1); +} + +#topnav .navbar-toggle { + border: 0; + position: relative; + width: 60px; + height: 60px; + padding: 0; + margin: 0; + cursor: pointer; +} + +#topnav .navbar-toggle:hover { + background-color: transparent; +} + +#topnav .navbar-toggle:hover span { + background-color: #ffffff; +} + +#topnav .navbar-toggle:focus { + background-color: transparent; +} + +#topnav .navbar-toggle:focus span { + background-color: #00b19d; +} + +#topnav .navbar-toggle .lines { + width: 25px; + display: block; + position: relative; + margin: 23px auto 17px auto; + height: 18px; +} + +#topnav .navbar-toggle span { + height: 2px; + width: 100%; + background-color: #fff; + display: block; + margin-bottom: 5px; + -webkit-transition: -webkit-transform 0.5s ease; + transition: -webkit-transform 0.5s ease; + transition: transform .5s ease; +} + +#topnav .navbar-toggle.open span { + position: absolute; +} + +#topnav .navbar-toggle.open span:first-child { + top: 6px; + -webkit-transform: rotate(45deg); + transform: rotate(45deg); +} + +#topnav .navbar-toggle.open span:nth-child(2) { + visibility: hidden; +} + +#topnav .navbar-toggle.open span:last-child { + width: 100%; + top: 6px; + -webkit-transform: rotate(-45deg); + transform: rotate(-45deg); +} + +#topnav .navigation-menu { + list-style: none; + margin: 0; + padding: 0; + margin-left: 210px; +} + +#topnav .navigation-menu>li { + float: left; + display: block; + position: relative; +} + +#topnav .navigation-menu>li>a { + display: block; + color: #fff; + font-weight: 500; + font-size: 14px; + -webkit-transition: all .3s ease; + transition: all .3s ease; + line-height: 20px; + padding-left: 15px; + padding-right: 15px; + text-decoration: none; +} + +#topnav .navigation-menu>li.active>a { + font-weight: 800; +} + +#topnav .navigation-menu>li>a:hover { + color: #fff; +} + +#topnav .navigation-menu>li>a:hover i { + color: #fff; +} + +#topnav .navigation-menu>li>a:focus { + color: #fff; +} + +#topnav .navigation-menu>li>a:focus i { + color: #fff; +} + +#topnav .navigation-menu>li>a:active { + color: #fff; +} + +#topnav .navigation-menu>li>a:active i { + color: #fff; +} + +#topnav .navigation-menu>li>a i { + font-size: 18px; + margin-right: 5px; + color: #fff; +} + +#topnav .navigation-menu>li>a:hover, +#topnav .navigation-menu>li>a:focus { + background-color: transparent; +} + +@media (min-width: 992px) { + #topnav .navigation-menu>li>a { + padding-top: 22px; + padding-bottom: 12px; + } +} + +/* + Responsive Menu +*/ +@media (min-width: 992px) { + #topnav .navigation-menu>li.last-elements .submenu { + left: auto; + right: 0; + } + + #topnav .navigation-menu>li.last-elements .submenu>li.has-submenu .submenu { + left: auto; + right: 100%; + margin-left: 0; + margin-right: 10px; + } + + #topnav .navigation-menu>li:hover a { + color: #fff; + } + + #topnav .navigation-menu>li:hover a i { + color: #fff; + } + + #topnav .navigation-menu>li .submenu { + position: absolute; + top: 100%; + left: 0; + z-index: 1000; + border: 1px solid #e7e7e7; + padding: 15px 0; + list-style: none; + min-width: 200px; + visibility: hidden; + opacity: 0; + margin-top: 10px; + -webkit-transition: all .2s ease; + transition: all .2s ease; + background-color: #ffffff; + box-shadow: 0px 1px 1px rgba(0, 0, 0, 0.1); + } + + #topnav .navigation-menu>li .submenu.megamenu { + white-space: nowrap; + width: auto; + } + + #topnav .navigation-menu>li .submenu.megamenu>li { + overflow: hidden; + width: 200px; + display: inline-block; + vertical-align: top; + } + + #topnav .navigation-menu>li .submenu>li.has-submenu>a:after { + content: "\f3d3"; + font-family: 'Ionicons'; + position: absolute; + right: 20px; + font-size: 16px; + top: 8px; + } + + #topnav .navigation-menu>li .submenu>li .submenu { + left: 100%; + top: 0; + margin-left: 10px; + margin-top: -1px; + } + + #topnav .navigation-menu>li .submenu li { + position: relative; + } + + #topnav .navigation-menu>li .submenu li ul { + list-style: none; + padding-left: 0; + margin: 0; + } + + #topnav .navigation-menu>li .submenu li a { + display: block; + padding: 8px 25px; + clear: both; + white-space: nowrap; + font-weight: 500; + font-size: 14px; + text-decoration: none; + color: #494e53; + } + + #topnav .navigation-menu>li .submenu li a:hover { + color: #00b19d; + } + + #topnav .navigation-menu>li .submenu li span { + display: block; + padding: 8px 25px; + clear: both; + line-height: 1.42857143; + white-space: nowrap; + font-size: 10px; + text-transform: uppercase; + letter-spacing: 2px; + font-weight: 500; + color: #949ba1; + } + + #topnav .navbar-toggle { + display: none; + } + + #topnav #navigation { + display: block !important; + } +} + +@media (max-width: 991px) { + .wrapper { + margin-top: 80px; + } + + .container { + width: auto; + } + + #topnav .navigation-menu { + float: none; + max-height: 400px; + } + + #topnav .navigation-menu>li { + float: none; + } + + #topnav .navigation-menu>li>a { + color: #797979; + padding: 15px; + } + + #topnav .navigation-menu>li>a i { + display: inline-block; + margin-right: 10px; + margin-bottom: 0px; + } + + #topnav .navigation-menu>li>a:after { + position: absolute; + right: 15px; + } + + #topnav .navigation-menu>li .submenu { + display: none; + list-style: none; + padding-left: 20px; + margin: 0; + } + + #topnav .navigation-menu>li .submenu li a { + display: block; + position: relative; + padding: 7px 20px; + color: #797979; + } + + #topnav .navigation-menu>li .submenu li a:hover { + color: #00b19d; + } + + #topnav .navigation-menu>li .submenu li.has-submenu>a:after { + content: "\e64b"; + font-family: "themify"; + position: absolute; + right: 30px; + } + + #topnav .navigation-menu>li .submenu.open { + display: block; + } + + #topnav .navigation-menu>li .submenu .submenu { + display: none; + list-style: none; + } + + #topnav .navigation-menu>li .submenu .submenu.open { + display: block; + } + + #topnav .navigation-menu>li .submenu.megamenu>li>ul { + list-style: none; + padding-left: 0; + } + + #topnav .navigation-menu>li .submenu.megamenu>li>ul>li>span { + display: block; + position: relative; + padding: 15px; + text-transform: uppercase; + font-size: 11px; + letter-spacing: 2px; + color: #79818a; + } + + #topnav .navigation-menu>li.has-submenu.open>a { + color: #00b19d; + } + + #topnav .navbar-header { + float: left; + } + + #navigation { + position: absolute; + top: 60px; + left: 0; + width: 100%; + display: none; + height: auto; + padding-bottom: 0; + overflow: auto; + border-top: 1px solid #e7e7e7; + border-bottom: 1px solid #e7e7e7; + background-color: #fff; + } + + #navigation.open { + display: block; + overflow-y: auto; + } +} + +@media (min-width: 768px) { + #topnav .navigation-menu>li.has-submenu:hover>.submenu { + visibility: visible; + opacity: 1; + margin-top: 0; + } + + #topnav .navigation-menu>li.has-submenu:hover>.submenu>li.has-submenu:hover>.submenu, + #topnav .navigation-menu>li.has-submenu:hover>.submenu>li.has-submenu:hover>.submenu>li.has-submenu:hover>.submenu { + visibility: visible; + opacity: 1; + margin-left: 0; + margin-right: 0; + } + + .navbar-toggle { + display: block; + } +} + +/* Footer */ +.footer { + border-top: 1px solid rgba(0, 0, 0, 0.1); + bottom: 0px; + color: #58666e; + text-align: left !important; + padding: 20px 0px; + position: absolute; + right: 0px; + left: 0px; +} diff --git a/web/assets/images/connect.png b/web/assets/images/connect.png new file mode 100644 index 000000000..3b88275dc Binary files /dev/null and b/web/assets/images/connect.png differ diff --git a/web/assets/images/default_avatar.png b/web/assets/images/default_avatar.png new file mode 100644 index 000000000..5caa1fc98 Binary files /dev/null and b/web/assets/images/default_avatar.png differ diff --git a/web/assets/images/favicon.png b/web/assets/images/favicon.png new file mode 100644 index 000000000..df48f0d22 Binary files /dev/null and b/web/assets/images/favicon.png differ diff --git a/web/assets/images/loading.gif b/web/assets/images/loading.gif new file mode 100644 index 000000000..db3a483e4 Binary files /dev/null and b/web/assets/images/loading.gif differ diff --git a/web/assets/images/logo.png b/web/assets/images/logo.png new file mode 100644 index 000000000..f15ef95a5 Binary files /dev/null and b/web/assets/images/logo.png differ diff --git a/web/azure-pipelines.yml b/web/azure-pipelines.yml new file mode 100644 index 000000000..d55a806c1 --- /dev/null +++ b/web/azure-pipelines.yml @@ -0,0 +1,21 @@ +# Node.js with Vue +# Build a Node.js project that uses Vue. +# Add steps that analyze code, save build artifacts, deploy, and more: +# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript + +trigger: +- master + +pool: + vmImage: 'Ubuntu-16.04' + +steps: +- task: NodeTool@0 + inputs: + versionSpec: '8.x' + displayName: 'Install Node.js' + +- script: | + npm install + npm run build + displayName: 'npm install and build' diff --git a/web/components/AppHeader.vue b/web/components/AppHeader.vue new file mode 100644 index 000000000..dc40e70b0 --- /dev/null +++ b/web/components/AppHeader.vue @@ -0,0 +1,104 @@ + + + diff --git a/web/components/AppMeMenus.vue b/web/components/AppMeMenus.vue new file mode 100644 index 000000000..e6d042ea7 --- /dev/null +++ b/web/components/AppMeMenus.vue @@ -0,0 +1,95 @@ + + + diff --git a/web/components/AppNotify.vue b/web/components/AppNotify.vue new file mode 100644 index 000000000..aa13d617f --- /dev/null +++ b/web/components/AppNotify.vue @@ -0,0 +1,101 @@ + + + diff --git a/web/components/AppRepoMenus.vue b/web/components/AppRepoMenus.vue new file mode 100644 index 000000000..2a9aa7746 --- /dev/null +++ b/web/components/AppRepoMenus.vue @@ -0,0 +1,130 @@ + + + diff --git a/web/components/Avatar.vue b/web/components/Avatar.vue new file mode 100644 index 000000000..fedad1c7d --- /dev/null +++ b/web/components/Avatar.vue @@ -0,0 +1,170 @@ + + + + diff --git a/web/jest.config.js b/web/jest.config.js new file mode 100644 index 000000000..4bf92e114 --- /dev/null +++ b/web/jest.config.js @@ -0,0 +1,12 @@ +module.exports = { + moduleNameMapper: { + '^@/(.*)$': '/$1', + '^~/(.*)$': '/$1', + '^vue$': 'vue/dist/vue.common.js' + }, + moduleFileExtensions: ['js', 'vue', 'json'], + transform: { + '^.+\\.js$': 'babel-jest', + '.*\\.(vue)$': 'vue-jest' + } +} diff --git a/web/layouts/default.vue b/web/layouts/default.vue new file mode 100644 index 000000000..9793ce6b6 --- /dev/null +++ b/web/layouts/default.vue @@ -0,0 +1,660 @@ +